diff --git a/config.yml b/config.yml index 56bf6772b..841e96241 100644 --- a/config.yml +++ b/config.yml @@ -1,6 +1,6 @@ repo: https://github.com/openwrt/openwrt.git branch: openwrt-23.05 -revision: cdc8470aecd03e6994714af092f030f209951de4 +revision: 8b385a45a65cb4721e6bb2fbb24ce080417e331f output_dir: ./output patch_folders: diff --git a/patches/0044-netifd-update-to-latest-HEAD.patch b/patches/0044-netifd-update-to-latest-HEAD.patch deleted file mode 100644 index 16a74cce4..000000000 --- a/patches/0044-netifd-update-to-latest-HEAD.patch +++ /dev/null @@ -1,144 +0,0 @@ -From 5287669135980433cbcd1064c950aeca19f6f82c Mon Sep 17 00:00:00 2001 -From: John Crispin -Date: Fri, 28 Jul 2023 16:50:08 +0200 -Subject: [PATCH] netifd: update to latest HEAD - -Signed-off-by: John Crispin ---- - package/network/config/netifd/Makefile | 13 ++-- - .../etc/hotplug.d/net/20-smp-packet-steering | 67 +++++++++++++++++++ - .../netifd/patches/200-psk-radius.patch | 12 ++++ - 3 files changed, 86 insertions(+), 6 deletions(-) - create mode 100644 package/network/config/netifd/files/etc/hotplug.d/net/20-smp-packet-steering - create mode 100644 package/network/config/netifd/patches/200-psk-radius.patch - -diff --git a/package/network/config/netifd/Makefile b/package/network/config/netifd/Makefile -index 31fd0838a4..f749d72eb9 100644 ---- a/package/network/config/netifd/Makefile -+++ b/package/network/config/netifd/Makefile -@@ -5,16 +5,14 @@ PKG_RELEASE:=1 - - PKG_SOURCE_PROTO:=git - PKG_SOURCE_URL=$(PROJECT_GIT)/project/netifd.git --PKG_SOURCE_DATE:=2023-06-04 --PKG_SOURCE_VERSION:=ec9dba72124597b7224bbfe75960386dc320f4bd --PKG_MIRROR_HASH:=baee39a3882a2b03fc83a3a6a8963c340fa8d884c7a8c9e80e7d2dddc50e24bd -+PKG_SOURCE_DATE:=2023-08-31 -+PKG_SOURCE_VERSION:=1a07f1dff32b3af49e39533e33e8964b59535662 -+PKG_MIRROR_HASH:=dc621dd04c3c9631002f929cf10a4620f57af8b0baf614c590bda17957fa6201 - PKG_MAINTAINER:=Felix Fietkau - - PKG_LICENSE:=GPL-2.0 - PKG_LICENSE_FILES:= - --PKG_BUILD_FLAGS:=lto -- - include $(INCLUDE_DIR)/package.mk - include $(INCLUDE_DIR)/cmake.mk - -@@ -32,7 +30,10 @@ endef - - TARGET_CFLAGS += \ - -I$(STAGING_DIR)/usr/include/libnl-tiny \ -- -I$(STAGING_DIR)/usr/include -+ -I$(STAGING_DIR)/usr/include \ -+ -flto -+ -+TARGET_LDFLAGS += -flto -fuse-linker-plugin - - CMAKE_OPTIONS += \ - -DLIBNL_LIBS=-lnl-tiny \ -diff --git a/package/network/config/netifd/files/etc/hotplug.d/net/20-smp-packet-steering b/package/network/config/netifd/files/etc/hotplug.d/net/20-smp-packet-steering -new file mode 100644 -index 0000000000..8a86bf75f6 ---- /dev/null -+++ b/package/network/config/netifd/files/etc/hotplug.d/net/20-smp-packet-steering -@@ -0,0 +1,67 @@ -+#!/bin/sh -+[ "$ACTION" = add ] || exit -+ -+NPROCS="$(grep -c "^processor.*:" /proc/cpuinfo)" -+[ "$NPROCS" -gt 1 ] || exit -+ -+PROC_MASK="$(( (1 << $NPROCS) - 1 ))" -+ -+find_irq_cpu() { -+ local dev="$1" -+ local match="$(grep -m 1 "$dev\$" /proc/interrupts)" -+ local cpu=0 -+ -+ [ -n "$match" ] && { -+ set -- $match -+ shift -+ for cur in $(seq 1 $NPROCS); do -+ [ "$1" -gt 0 ] && { -+ cpu=$(($cur - 1)) -+ break -+ } -+ shift -+ done -+ } -+ -+ echo "$cpu" -+} -+ -+set_hex_val() { -+ local file="$1" -+ local val="$2" -+ val="$(printf %x "$val")" -+ [ -n "$DEBUG" ] && echo "$file = $val" -+ echo "$val" > "$file" -+} -+ -+packet_steering="$(uci get "network.@globals[0].packet_steering")" -+[ "$packet_steering" != 1 ] && exit 0 -+ -+exec 512>/var/lock/smp_tune.lock -+flock 512 || exit 1 -+ -+for dev in /sys/class/net/*; do -+ [ -d "$dev" ] || continue -+ -+ # ignore virtual interfaces -+ [ -n "$(ls "${dev}/" | grep '^lower_')" ] && continue -+ [ -d "${dev}/device" ] || continue -+ -+ device="$(readlink "${dev}/device")" -+ device="$(basename "$device")" -+ irq_cpu="$(find_irq_cpu "$device")" -+ irq_cpu_mask="$((1 << $irq_cpu))" -+ -+ for q in ${dev}/queues/tx-*; do -+ set_hex_val "$q/xps_cpus" "$PROC_MASK" -+ done -+ -+ # ignore dsa slave ports for RPS -+ subsys="$(readlink "${dev}/device/subsystem")" -+ subsys="$(basename "$subsys")" -+ [ "$subsys" = "mdio_bus" ] && continue -+ -+ for q in ${dev}/queues/rx-*; do -+ set_hex_val "$q/rps_cpus" "$PROC_MASK" -+ done -+done -diff --git a/package/network/config/netifd/patches/200-psk-radius.patch b/package/network/config/netifd/patches/200-psk-radius.patch -new file mode 100644 -index 0000000000..cc1e7021c9 ---- /dev/null -+++ b/package/network/config/netifd/patches/200-psk-radius.patch -@@ -0,0 +1,12 @@ -+--- a/scripts/netifd-wireless.sh -++++ b/scripts/netifd-wireless.sh -+@@ -260,6 +260,9 @@ wireless_vif_parse_encryption() { -+ wpa3*) -+ auth_type=eap256 -+ ;; -++ psk2-radius*) -++ auth_type=psk2-radius -++ ;; -+ psk3-mixed*|sae-mixed*) -+ auth_type=psk-sae -+ ;; --- -2.34.1 - diff --git a/patches/0047-ucode-update-to-latest-HEAD.patch b/patches/0047-ucode-update-to-latest-HEAD.patch deleted file mode 100644 index 7961670d2..000000000 --- a/patches/0047-ucode-update-to-latest-HEAD.patch +++ /dev/null @@ -1,30 +0,0 @@ -From 8c587aa5eb6ec68769846cdcc68d44e4c629a981 Mon Sep 17 00:00:00 2001 -From: John Crispin -Date: Fri, 1 Sep 2023 11:01:47 +0200 -Subject: [PATCH] ucode: update to latest HEAD - -Signed-off-by: John Crispin ---- - package/utils/ucode/Makefile | 6 +++--- - 1 file changed, 3 insertions(+), 3 deletions(-) - -diff --git a/package/utils/ucode/Makefile b/package/utils/ucode/Makefile -index e3a33410c2..c77da85349 100644 ---- a/package/utils/ucode/Makefile -+++ b/package/utils/ucode/Makefile -@@ -12,9 +12,9 @@ PKG_RELEASE:=1 - - PKG_SOURCE_PROTO:=git - PKG_SOURCE_URL=https://github.com/jow-/ucode.git --PKG_SOURCE_DATE:=2023-04-03 --PKG_SOURCE_VERSION:=5163867269fc04fa01ec5e9f8df3384c933339f2 --PKG_MIRROR_HASH:=e82922ff59d6f899d9434bf79f2e6e4add0b7b0466355755fc83d4b5a0aeebfb -+PKG_SOURCE_DATE:=2023-06-06 -+PKG_SOURCE_VERSION:=c7d84aae09691a99ae3db427c0b2463732ef84f4 -+PKG_MIRROR_HASH:=38826ae70d886d1d7ada3fc6591ac807169aa28107f60f7f2e617520083525fb - PKG_MAINTAINER:=Jo-Philipp Wich - PKG_LICENSE:=ISC - --- -2.34.1 - diff --git a/patches/0048-hostapd-drop-current-version.patch b/patches/0048-hostapd-drop-current-version.patch index 8c4a3dde1..f6459db7d 100644 --- a/patches/0048-hostapd-drop-current-version.patch +++ b/patches/0048-hostapd-drop-current-version.patch @@ -1,2794 +1,20 @@ -From 9d5081372cce2583789966171b7fea950e50f91e Mon Sep 17 00:00:00 2001 +From afaa1a556743d23ba94510c4966a8fa578a80950 Mon Sep 17 00:00:00 2001 From: John Crispin -Date: Thu, 7 Sep 2023 05:54:07 +0200 -Subject: [PATCH] hostapd: drop upstream version +Date: Tue, 19 Sep 2023 07:05:38 +0200 +Subject: [PATCH] hostapd: drop script Signed-off-by: John Crispin --- - package/network/services/hostapd/Config.in | 113 - - package/network/services/hostapd/Makefile | 824 -- - package/network/services/hostapd/README.md | 419 - - .../services/hostapd/files/dhcp-get-server.sh | 2 - - .../hostapd/files/hostapd-basic.config | 404 - - .../hostapd/files/hostapd-full.config | 404 - - .../hostapd/files/hostapd-mini.config | 404 - - .../network/services/hostapd/files/hostapd.sh | 1616 ---- - .../services/hostapd/files/multicall.c | 28 - - .../hostapd/files/wpa_supplicant-basic.config | 625 -- - .../hostapd/files/wpa_supplicant-full.config | 625 -- - .../hostapd/files/wpa_supplicant-mini.config | 625 -- - .../hostapd/files/wpa_supplicant-p2p.config | 625 -- - .../network/services/hostapd/files/wpad.init | 43 - - .../network/services/hostapd/files/wpad.json | 22 - - .../services/hostapd/files/wpad_acl.json | 10 - - .../services/hostapd/files/wps-hotplug.sh | 69 - - .../001-wolfssl-init-RNG-with-ECC-key.patch | 43 - - ...hannels-to-be-selected-if-dfs-is-ena.patch | 135 - - ...erministic-channel-on-channel-switch.patch | 81 - - ...ix-sta-add-after-previous-connection.patch | 26 - - ...use-of-uninitialized-stack-variables.patch | 25 - - ...-dl_list_del-before-freeing-ipv6-add.patch | 19 - - ...ewrite-neigh-code-to-not-depend-on-l.patch | 275 - - ...ssing-authentication-frames-in-block.patch | 34 - - .../hostapd/patches/050-build_fix.patch | 20 - - .../hostapd/patches/100-daemonize_fix.patch | 97 - - ...edtls-TLS-crypto-option-initial-port.patch | 8051 ----------------- - .../patches/120-mbedtls-fips186_2_prf.patch | 114 - - ...otate-with-TEST_FAIL-for-hwsim-tests.patch | 421 - - ...efile-make-run-tests-with-CONFIG_TLS.patch | 1358 --- - ...hecks-encountered-during-tests-hwsim.patch | 45 - - ...-dpp_pkex-EC-point-mul-w-value-prime.patch | 26 - - ...tapd-update-cfs0-and-cfs1-for-160MHz.patch | 141 - - .../hostapd/patches/200-multicall.patch | 355 - - .../services/hostapd/patches/300-noscan.patch | 58 - - .../hostapd/patches/301-mesh-noscan.patch | 71 - - .../patches/310-rescan_immediately.patch | 11 - - .../hostapd/patches/320-optional_rfkill.patch | 61 - - .../patches/330-nl80211_fix_set_freq.patch | 11 - - .../patches/340-reload_freq_change.patch | 80 - - .../341-mesh-ctrl-iface-channel-switch.patch | 39 - - .../patches/350-nl80211_del_beacon_bss.patch | 35 - - .../patches/360-ctrl_iface_reload.patch | 106 - - .../hostapd/patches/370-ap_sta_support.patch | 392 - - .../patches/380-disable_ctrl_iface_mib.patch | 239 - - .../381-hostapd_cli_UNKNOWN-COMMAND.patch | 11 - - .../patches/390-wpa_ie_cap_workaround.patch | 56 - - .../400-wps_single_auth_enc_type.patch | 23 - - .../patches/410-limit_debug_messages.patch | 210 - - .../patches/420-indicate-features.patch | 63 - - .../patches/430-hostapd_cli_ifdef.patch | 56 - - .../hostapd/patches/431-wpa_cli_ifdef.patch | 18 - - .../hostapd/patches/432-missing-typedef.patch | 10 - - .../hostapd/patches/450-scan_wait.patch | 73 - - ...dd-new-config-params-to-be-used-with.patch | 189 - - .../patches/463-add-mcast_rate-to-11s.patch | 68 - - .../patches/464-fix-mesh-obss-check.patch | 13 - - ...tapd-config-support-random-BSS-color.patch | 24 - - .../patches/470-survey_data_fallback.patch | 30 - - .../patches/500-lto-jobserver-support.patch | 59 - - .../patches/590-rrm-wnm-statistics.patch | 92 - - .../599-wpa_supplicant-fix-warnings.patch | 19 - - .../hostapd/patches/600-ubus_support.patch | 625 -- - .../610-hostapd_cli_ujail_permission.patch | 33 - - .../hostapd/patches/700-wifi-reload.patch | 194 - - .../hostapd/patches/710-vlan_no_bridge.patch | 41 - - .../patches/711-wds_bridge_force.patch | 22 - - .../patches/720-iface_max_num_sta.patch | 82 - - .../hostapd/patches/730-ft_iface.patch | 38 - - .../hostapd/patches/740-snoop_iface.patch | 66 - - ...750-qos_map_set_without_interworking.patch | 97 - - .../751-qos_map_ignore_when_unsupported.patch | 12 - - .../hostapd/patches/760-dynamic_own_ip.patch | 109 - - .../hostapd/patches/761-shared_das_port.patch | 298 - - ..._AP-functions-dependant-on-CONFIG_AP.patch | 33 - - .../patches/991-Fix-OpenWrt-13156.patch | 63 - - .../services/hostapd/src/src/ap/ubus.c | 2101 ----- - .../services/hostapd/src/src/ap/ubus.h | 154 - - .../hostapd/src/src/utils/build_features.h | 65 - - .../hostapd/src/wpa_supplicant/ubus.c | 430 - - .../hostapd/src/wpa_supplicant/ubus.h | 66 - - 82 files changed, 24770 deletions(-) - delete mode 100644 package/network/services/hostapd/Config.in - delete mode 100644 package/network/services/hostapd/Makefile - delete mode 100644 package/network/services/hostapd/README.md - delete mode 100644 package/network/services/hostapd/files/dhcp-get-server.sh - delete mode 100644 package/network/services/hostapd/files/hostapd-basic.config - delete mode 100644 package/network/services/hostapd/files/hostapd-full.config - delete mode 100644 package/network/services/hostapd/files/hostapd-mini.config + .../network/services/hostapd/files/hostapd.sh | 1598 ----------------- + 1 file changed, 1598 deletions(-) delete mode 100644 package/network/services/hostapd/files/hostapd.sh - delete mode 100644 package/network/services/hostapd/files/multicall.c - delete mode 100644 package/network/services/hostapd/files/wpa_supplicant-basic.config - delete mode 100644 package/network/services/hostapd/files/wpa_supplicant-full.config - delete mode 100644 package/network/services/hostapd/files/wpa_supplicant-mini.config - delete mode 100644 package/network/services/hostapd/files/wpa_supplicant-p2p.config - delete mode 100644 package/network/services/hostapd/files/wpad.init - delete mode 100644 package/network/services/hostapd/files/wpad.json - delete mode 100644 package/network/services/hostapd/files/wpad_acl.json - delete mode 100644 package/network/services/hostapd/files/wps-hotplug.sh - delete mode 100644 package/network/services/hostapd/patches/001-wolfssl-init-RNG-with-ECC-key.patch - delete mode 100644 package/network/services/hostapd/patches/010-mesh-Allow-DFS-channels-to-be-selected-if-dfs-is-ena.patch - delete mode 100644 package/network/services/hostapd/patches/011-mesh-use-deterministic-channel-on-channel-switch.patch - delete mode 100644 package/network/services/hostapd/patches/021-fix-sta-add-after-previous-connection.patch - delete mode 100644 package/network/services/hostapd/patches/022-hostapd-fix-use-of-uninitialized-stack-variables.patch - delete mode 100644 package/network/services/hostapd/patches/023-ndisc_snoop-call-dl_list_del-before-freeing-ipv6-add.patch - delete mode 100644 package/network/services/hostapd/patches/030-driver_nl80211-rewrite-neigh-code-to-not-depend-on-l.patch - delete mode 100644 package/network/services/hostapd/patches/040-mesh-allow-processing-authentication-frames-in-block.patch - delete mode 100644 package/network/services/hostapd/patches/050-build_fix.patch - delete mode 100644 package/network/services/hostapd/patches/100-daemonize_fix.patch - delete mode 100644 package/network/services/hostapd/patches/110-mbedtls-TLS-crypto-option-initial-port.patch - delete mode 100644 package/network/services/hostapd/patches/120-mbedtls-fips186_2_prf.patch - delete mode 100644 package/network/services/hostapd/patches/130-mbedtls-annotate-with-TEST_FAIL-for-hwsim-tests.patch - delete mode 100644 package/network/services/hostapd/patches/140-tests-Makefile-make-run-tests-with-CONFIG_TLS.patch - delete mode 100644 package/network/services/hostapd/patches/150-add-NULL-checks-encountered-during-tests-hwsim.patch - delete mode 100644 package/network/services/hostapd/patches/160-dpp_pkex-EC-point-mul-w-value-prime.patch - delete mode 100644 package/network/services/hostapd/patches/170-hostapd-update-cfs0-and-cfs1-for-160MHz.patch - delete mode 100644 package/network/services/hostapd/patches/200-multicall.patch - delete mode 100644 package/network/services/hostapd/patches/300-noscan.patch - delete mode 100644 package/network/services/hostapd/patches/301-mesh-noscan.patch - delete mode 100644 package/network/services/hostapd/patches/310-rescan_immediately.patch - delete mode 100644 package/network/services/hostapd/patches/320-optional_rfkill.patch - delete mode 100644 package/network/services/hostapd/patches/330-nl80211_fix_set_freq.patch - delete mode 100644 package/network/services/hostapd/patches/340-reload_freq_change.patch - delete mode 100644 package/network/services/hostapd/patches/341-mesh-ctrl-iface-channel-switch.patch - delete mode 100644 package/network/services/hostapd/patches/350-nl80211_del_beacon_bss.patch - delete mode 100644 package/network/services/hostapd/patches/360-ctrl_iface_reload.patch - delete mode 100644 package/network/services/hostapd/patches/370-ap_sta_support.patch - delete mode 100644 package/network/services/hostapd/patches/380-disable_ctrl_iface_mib.patch - delete mode 100644 package/network/services/hostapd/patches/381-hostapd_cli_UNKNOWN-COMMAND.patch - delete mode 100644 package/network/services/hostapd/patches/390-wpa_ie_cap_workaround.patch - delete mode 100644 package/network/services/hostapd/patches/400-wps_single_auth_enc_type.patch - delete mode 100644 package/network/services/hostapd/patches/410-limit_debug_messages.patch - delete mode 100644 package/network/services/hostapd/patches/420-indicate-features.patch - delete mode 100644 package/network/services/hostapd/patches/430-hostapd_cli_ifdef.patch - delete mode 100644 package/network/services/hostapd/patches/431-wpa_cli_ifdef.patch - delete mode 100644 package/network/services/hostapd/patches/432-missing-typedef.patch - delete mode 100644 package/network/services/hostapd/patches/450-scan_wait.patch - delete mode 100644 package/network/services/hostapd/patches/460-wpa_supplicant-add-new-config-params-to-be-used-with.patch - delete mode 100644 package/network/services/hostapd/patches/463-add-mcast_rate-to-11s.patch - delete mode 100644 package/network/services/hostapd/patches/464-fix-mesh-obss-check.patch - delete mode 100644 package/network/services/hostapd/patches/465-hostapd-config-support-random-BSS-color.patch - delete mode 100644 package/network/services/hostapd/patches/470-survey_data_fallback.patch - delete mode 100644 package/network/services/hostapd/patches/500-lto-jobserver-support.patch - delete mode 100644 package/network/services/hostapd/patches/590-rrm-wnm-statistics.patch - delete mode 100644 package/network/services/hostapd/patches/599-wpa_supplicant-fix-warnings.patch - delete mode 100644 package/network/services/hostapd/patches/600-ubus_support.patch - delete mode 100644 package/network/services/hostapd/patches/610-hostapd_cli_ujail_permission.patch - delete mode 100644 package/network/services/hostapd/patches/700-wifi-reload.patch - delete mode 100644 package/network/services/hostapd/patches/710-vlan_no_bridge.patch - delete mode 100644 package/network/services/hostapd/patches/711-wds_bridge_force.patch - delete mode 100644 package/network/services/hostapd/patches/720-iface_max_num_sta.patch - delete mode 100644 package/network/services/hostapd/patches/730-ft_iface.patch - delete mode 100644 package/network/services/hostapd/patches/740-snoop_iface.patch - delete mode 100644 package/network/services/hostapd/patches/750-qos_map_set_without_interworking.patch - delete mode 100644 package/network/services/hostapd/patches/751-qos_map_ignore_when_unsupported.patch - delete mode 100644 package/network/services/hostapd/patches/760-dynamic_own_ip.patch - delete mode 100644 package/network/services/hostapd/patches/761-shared_das_port.patch - delete mode 100644 package/network/services/hostapd/patches/990-ctrl-make-WNM_AP-functions-dependant-on-CONFIG_AP.patch - delete mode 100644 package/network/services/hostapd/patches/991-Fix-OpenWrt-13156.patch - delete mode 100644 package/network/services/hostapd/src/src/ap/ubus.c - delete mode 100644 package/network/services/hostapd/src/src/ap/ubus.h - delete mode 100644 package/network/services/hostapd/src/src/utils/build_features.h - delete mode 100644 package/network/services/hostapd/src/wpa_supplicant/ubus.c - delete mode 100644 package/network/services/hostapd/src/wpa_supplicant/ubus.h -diff --git a/package/network/services/hostapd/Config.in b/package/network/services/hostapd/Config.in -deleted file mode 100644 -index 8f28eb2bd4..0000000000 ---- a/package/network/services/hostapd/Config.in -+++ /dev/null -@@ -1,113 +0,0 @@ --# wpa_supplicant config --config WPA_RFKILL_SUPPORT -- bool "Add rfkill support" -- depends on PACKAGE_wpa-supplicant || \ -- PACKAGE_wpa-supplicant-openssl || \ -- PACKAGE_wpa-supplicant-wolfssl || \ -- PACKAGE_wpa-supplicant-mbedtls || \ -- PACKAGE_wpa-supplicant-mesh-openssl || \ -- PACKAGE_wpa-supplicant-mesh-wolfssl || \ -- PACKAGE_wpa-supplicant-mesh-mbedtls || \ -- PACKAGE_wpa-supplicant-basic || \ -- PACKAGE_wpa-supplicant-mini || \ -- PACKAGE_wpa-supplicant-p2p || \ -- PACKAGE_wpad || \ -- PACKAGE_wpad-openssl || \ -- PACKAGE_wpad-wolfssl || \ -- PACKAGE_wpad-mbedtls || \ -- PACKAGE_wpad-basic || \ -- PACKAGE_wpad-basic-openssl || \ -- PACKAGE_wpad-basic-wolfssl || \ -- PACKAGE_wpad-basic-mbedtls || \ -- PACKAGE_wpad-mini || \ -- PACKAGE_wpad-mesh-openssl || \ -- PACKAGE_wpad-mesh-wolfssl || \ -- PACKAGE_wpad-mesh-mbedtls -- default n -- --config WPA_MSG_MIN_PRIORITY -- int "Minimum debug message priority" -- depends on PACKAGE_wpa-supplicant || \ -- PACKAGE_wpa-supplicant-openssl || \ -- PACKAGE_wpa-supplicant-wolfssl || \ -- PACKAGE_wpa-supplicant-mbedtls || \ -- PACKAGE_wpa-supplicant-mesh-openssl || \ -- PACKAGE_wpa-supplicant-mesh-wolfssl || \ -- PACKAGE_wpa-supplicant-mesh-mbedtls || \ -- PACKAGE_wpa-supplicant-basic || \ -- PACKAGE_wpa-supplicant-mini || \ -- PACKAGE_wpa-supplicant-p2p || \ -- PACKAGE_wpad || \ -- PACKAGE_wpad-openssl || \ -- PACKAGE_wpad-wolfssl || \ -- PACKAGE_wpad-mbedtls || \ -- PACKAGE_wpad-basic || \ -- PACKAGE_wpad-basic-openssl || \ -- PACKAGE_wpad-basic-wolfssl || \ -- PACKAGE_wpad-basic-mbedtls || \ -- PACKAGE_wpad-mini || \ -- PACKAGE_wpad-mesh-openssl || \ -- PACKAGE_wpad-mesh-wolfssl || \ -- PACKAGE_wpad-mesh-mbedtls -- default 3 -- help -- Useful values are: -- 0 = all messages -- 1 = raw message dumps -- 2 = most debugging messages -- 3 = info messages -- 4 = warnings -- 5 = errors -- --config WPA_WOLFSSL -- bool -- default PACKAGE_wpa-supplicant-wolfssl ||\ -- PACKAGE_wpad-wolfssl ||\ -- PACKAGE_wpad-basic-wolfssl || \ -- PACKAGE_wpad-mesh-wolfssl ||\ -- PACKAGE_eapol-test-wolfssl -- select WOLFSSL_HAS_AES_CCM -- select WOLFSSL_HAS_ARC4 -- select WOLFSSL_HAS_DH -- select WOLFSSL_HAS_OCSP -- select WOLFSSL_HAS_SESSION_TICKET -- select WOLFSSL_HAS_WPAS -- --config DRIVER_WEXT_SUPPORT -- bool -- select KERNEL_WIRELESS_EXT -- default n -- --config DRIVER_11AC_SUPPORT -- bool -- default n -- --config DRIVER_11AX_SUPPORT -- bool -- default n -- select WPA_MBO_SUPPORT -- --config WPA_ENABLE_WEP -- bool "Enable support for unsecure and obsolete WEP" -- help -- Wired equivalent privacy (WEP) is an obsolete cryptographic data -- confidentiality algorithm that is not considered secure. It should not be used -- for anything anymore. The functionality needed to use WEP is available in the -- current hostapd release under this optional build parameter and completely -- removed in a future release. -- --config WPA_MBO_SUPPORT -- bool "Multi Band Operation (Agile Multiband)" -- default PACKAGE_wpa-supplicant || \ -- PACKAGE_wpa-supplicant-openssl || \ -- PACKAGE_wpa-supplicant-wolfssl || \ -- PACKAGE_wpa-supplicant-mbedtls || \ -- PACKAGE_wpad || \ -- PACKAGE_wpad-openssl || \ -- PACKAGE_wpad-wolfssl || \ -- PACKAGE_wpad-mbedtls -- help -- Multi Band Operation aka (Agile Multiband) enables features -- that facilitate efficient use of multiple frequency bands. -- Enabling MBO on an AP using RSN requires 802.11w to be enabled. -- Hostapd will refuse to start if MBO and RSN are enabled without 11w. -diff --git a/package/network/services/hostapd/Makefile b/package/network/services/hostapd/Makefile -deleted file mode 100644 -index 287a70c80e..0000000000 ---- a/package/network/services/hostapd/Makefile -+++ /dev/null -@@ -1,824 +0,0 @@ --# SPDX-License-Identifier: GPL-2.0-only --# --# Copyright (C) 2006-2021 OpenWrt.org -- --include $(TOPDIR)/rules.mk -- --PKG_NAME:=hostapd --PKG_RELEASE:=1.2 -- --PKG_SOURCE_URL:=http://w1.fi/hostap.git --PKG_SOURCE_PROTO:=git --PKG_SOURCE_DATE:=2023-06-22 --PKG_SOURCE_VERSION:=599d00be9de2846c6ea18c1487d8329522ade22b --PKG_MIRROR_HASH:=828810c558ea181e45ed0c8b940f5c41e55775e2979a15aed8cf0ab17dd7723c -- --PKG_MAINTAINER:=Felix Fietkau --PKG_LICENSE:=BSD-3-Clause --PKG_CPE_ID:=cpe:/a:w1.fi:hostapd -- --PKG_BUILD_PARALLEL:=1 --PKG_ASLR_PIE_REGULAR:=1 -- --PKG_CONFIG_DEPENDS:= \ -- CONFIG_PACKAGE_kmod-ath9k \ -- CONFIG_PACKAGE_kmod-cfg80211 \ -- CONFIG_PACKAGE_hostapd \ -- CONFIG_PACKAGE_hostapd-basic \ -- CONFIG_PACKAGE_hostapd-mini \ -- CONFIG_WPA_RFKILL_SUPPORT \ -- CONFIG_DRIVER_WEXT_SUPPORT \ -- CONFIG_DRIVER_11AC_SUPPORT \ -- CONFIG_DRIVER_11AX_SUPPORT \ -- CONFIG_WPA_ENABLE_WEP -- --PKG_BUILD_FLAGS:=gc-sections lto -- --EAPOL_TEST_PROVIDERS:=eapol-test eapol-test-openssl eapol-test-wolfssl -- --SUPPLICANT_PROVIDERS:= --HOSTAPD_PROVIDERS:= -- --LOCAL_TYPE=$(strip \ -- $(if $(findstring wpad,$(BUILD_VARIANT)),wpad, \ -- $(if $(findstring supplicant,$(BUILD_VARIANT)),supplicant, \ -- hostapd \ -- ))) -- --LOCAL_AND_LIB_VARIANT=$(patsubst hostapd-%,%,\ -- $(patsubst wpad-%,%,\ -- $(patsubst supplicant-%,%,\ -- $(BUILD_VARIANT)\ -- ))) -- --LOCAL_VARIANT=$(patsubst %-internal,%,\ -- $(patsubst %-openssl,%,\ -- $(patsubst %-wolfssl,%,\ -- $(patsubst %-mbedtls,%,\ -- $(LOCAL_AND_LIB_VARIANT)\ -- )))) -- --SSL_VARIANT=$(strip \ -- $(if $(findstring openssl,$(LOCAL_AND_LIB_VARIANT)),openssl,\ -- $(if $(findstring wolfssl,$(LOCAL_AND_LIB_VARIANT)),wolfssl,\ -- $(if $(findstring mbedtls,$(LOCAL_AND_LIB_VARIANT)),mbedtls,\ -- internal\ -- )))) -- --CONFIG_VARIANT:=$(LOCAL_VARIANT) --ifeq ($(LOCAL_VARIANT),mesh) -- CONFIG_VARIANT:=full --endif -- --include $(INCLUDE_DIR)/package.mk -- --STAMP_CONFIGURED:=$(STAMP_CONFIGURED)_$(CONFIG_WPA_MSG_MIN_PRIORITY) -- --ifneq ($(CONFIG_DRIVER_11AC_SUPPORT),) -- HOSTAPD_IEEE80211AC:=y --endif -- --ifneq ($(CONFIG_DRIVER_11AX_SUPPORT),) -- HOSTAPD_IEEE80211AX:=y --endif -- --DRIVER_MAKEOPTS= \ -- CONFIG_ACS=$(CONFIG_PACKAGE_kmod-cfg80211) \ -- CONFIG_DRIVER_NL80211=$(CONFIG_PACKAGE_kmod-cfg80211) \ -- CONFIG_IEEE80211AC=$(HOSTAPD_IEEE80211AC) \ -- CONFIG_IEEE80211AX=$(HOSTAPD_IEEE80211AX) \ -- CONFIG_DRIVER_WEXT=$(CONFIG_DRIVER_WEXT_SUPPORT) \ -- CONFIG_MBO=$(CONFIG_WPA_MBO_SUPPORT) -- --ifeq ($(SSL_VARIANT),openssl) -- DRIVER_MAKEOPTS += CONFIG_TLS=openssl CONFIG_SAE=y -- TARGET_LDFLAGS += -lcrypto -lssl -- -- ifeq ($(LOCAL_VARIANT),basic) -- DRIVER_MAKEOPTS += CONFIG_OWE=y -- endif -- ifeq ($(LOCAL_VARIANT),mesh) -- DRIVER_MAKEOPTS += CONFIG_AP=y CONFIG_MESH=y -- endif -- ifeq ($(LOCAL_VARIANT),full) -- DRIVER_MAKEOPTS += CONFIG_OWE=y CONFIG_SUITEB192=y CONFIG_AP=y CONFIG_MESH=y -- endif --endif -- --ifeq ($(SSL_VARIANT),wolfssl) -- DRIVER_MAKEOPTS += CONFIG_TLS=wolfssl CONFIG_SAE=y -- TARGET_LDFLAGS += -lwolfssl -- -- ifeq ($(LOCAL_VARIANT),basic) -- DRIVER_MAKEOPTS += CONFIG_OWE=y -- endif -- ifeq ($(LOCAL_VARIANT),mesh) -- DRIVER_MAKEOPTS += CONFIG_AP=y CONFIG_MESH=y CONFIG_WPS_NFC=1 -- endif -- ifeq ($(LOCAL_VARIANT),full) -- DRIVER_MAKEOPTS += CONFIG_OWE=y CONFIG_SUITEB192=y CONFIG_AP=y CONFIG_MESH=y CONFIG_WPS_NFC=1 -- endif --endif -- --ifeq ($(SSL_VARIANT),mbedtls) -- DRIVER_MAKEOPTS += CONFIG_TLS=mbedtls CONFIG_SAE=y -- TARGET_LDFLAGS += -lmbedcrypto -lmbedx509 -lmbedtls -- -- ifeq ($(LOCAL_VARIANT),basic) -- DRIVER_MAKEOPTS += CONFIG_OWE=y -- endif -- ifeq ($(LOCAL_VARIANT),mesh) -- DRIVER_MAKEOPTS += CONFIG_AP=y CONFIG_MESH=y CONFIG_WPS_NFC=1 -- endif -- ifeq ($(LOCAL_VARIANT),full) -- DRIVER_MAKEOPTS += CONFIG_OWE=y CONFIG_SUITEB192=y CONFIG_AP=y CONFIG_MESH=y CONFIG_WPS_NFC=1 -- endif --endif -- --ifneq ($(LOCAL_TYPE),hostapd) -- ifdef CONFIG_WPA_RFKILL_SUPPORT -- DRIVER_MAKEOPTS += NEED_RFKILL=y -- endif --endif -- --DRV_DEPENDS:=+PACKAGE_kmod-cfg80211:libnl-tiny -- -- --define Package/hostapd/Default -- SECTION:=net -- CATEGORY:=Network -- SUBMENU:=WirelessAPD -- TITLE:=IEEE 802.1x Authenticator -- URL:=http://hostap.epitest.fi/ -- DEPENDS:=$(DRV_DEPENDS) +hostapd-common +libubus -- EXTRA_DEPENDS:=hostapd-common (=$(PKG_VERSION)-$(PKG_RELEASE)) -- USERID:=network=101:network=101 -- PROVIDES:=hostapd -- CONFLICTS:=$(HOSTAPD_PROVIDERS) -- HOSTAPD_PROVIDERS+=$(1) --endef -- --define Package/hostapd --$(call Package/hostapd/Default,$(1)) -- TITLE+= (built-in full) -- VARIANT:=full-internal --endef -- --define Package/hostapd/description -- This package contains a full featured IEEE 802.1x/WPA/EAP/RADIUS -- Authenticator. --endef -- --define Package/hostapd-openssl --$(call Package/hostapd/Default,$(1)) -- TITLE+= (OpenSSL full) -- VARIANT:=full-openssl -- DEPENDS+=+PACKAGE_hostapd-openssl:libopenssl --endef -- --Package/hostapd-openssl/description = $(Package/hostapd/description) -- --define Package/hostapd-wolfssl --$(call Package/hostapd/Default,$(1)) -- TITLE+= (wolfSSL full) -- VARIANT:=full-wolfssl -- DEPENDS+=+PACKAGE_hostapd-wolfssl:libwolfssl --endef -- --Package/hostapd-wolfssl/description = $(Package/hostapd/description) -- --define Package/hostapd-mbedtls --$(call Package/hostapd/Default,$(1)) -- TITLE+= (mbedTLS full) -- VARIANT:=full-mbedtls -- DEPENDS+=+PACKAGE_hostapd-mbedtls:libmbedtls --endef -- --Package/hostapd-mbedtls/description = $(Package/hostapd/description) -- --define Package/hostapd-basic --$(call Package/hostapd/Default,$(1)) -- TITLE+= (WPA-PSK, 11r, 11w) -- VARIANT:=basic --endef -- --define Package/hostapd-basic/description -- This package contains a basic IEEE 802.1x/WPA Authenticator with WPA-PSK, 802.11r and 802.11w support. --endef -- --define Package/hostapd-basic-openssl --$(call Package/hostapd/Default,$(1)) -- TITLE+= (WPA-PSK, 11r and 11w) -- VARIANT:=basic-openssl -- DEPENDS+=+PACKAGE_hostapd-basic-openssl:libopenssl --endef -- --define Package/hostapd-basic-openssl/description -- This package contains a basic IEEE 802.1x/WPA Authenticator with WPA-PSK, 802.11r and 802.11w support. --endef -- --define Package/hostapd-basic-wolfssl --$(call Package/hostapd/Default,$(1)) -- TITLE+= (WPA-PSK, 11r and 11w) -- VARIANT:=basic-wolfssl -- DEPENDS+=+PACKAGE_hostapd-basic-wolfssl:libwolfssl --endef -- --define Package/hostapd-basic-wolfssl/description -- This package contains a basic IEEE 802.1x/WPA Authenticator with WPA-PSK, 802.11r and 802.11w support. --endef -- --define Package/hostapd-basic-mbedtls --$(call Package/hostapd/Default,$(1)) -- TITLE+= (WPA-PSK, 11r and 11w) -- VARIANT:=basic-mbedtls -- DEPENDS+=+PACKAGE_hostapd-basic-mbedtls:libmbedtls --endef -- --define Package/hostapd-basic-mbedtls/description -- This package contains a basic IEEE 802.1x/WPA Authenticator with WPA-PSK, 802.11r and 802.11w support. --endef -- --define Package/hostapd-mini --$(call Package/hostapd/Default,$(1)) -- TITLE+= (WPA-PSK only) -- VARIANT:=mini --endef -- --define Package/hostapd-mini/description -- This package contains a minimal IEEE 802.1x/WPA Authenticator (WPA-PSK only). --endef -- -- --define Package/wpad/Default -- SECTION:=net -- CATEGORY:=Network -- SUBMENU:=WirelessAPD -- TITLE:=IEEE 802.1x Auth/Supplicant -- DEPENDS:=$(DRV_DEPENDS) +hostapd-common +libubus -- EXTRA_DEPENDS:=hostapd-common (=$(PKG_VERSION)-$(PKG_RELEASE)) -- USERID:=network=101:network=101 -- URL:=http://hostap.epitest.fi/ -- PROVIDES:=hostapd wpa-supplicant -- CONFLICTS:=$(HOSTAPD_PROVIDERS) $(SUPPLICANT_PROVIDERS) -- HOSTAPD_PROVIDERS+=$(1) -- SUPPLICANT_PROVIDERS+=$(1) --endef -- --define Package/wpad --$(call Package/wpad/Default,$(1)) -- TITLE+= (built-in full) -- VARIANT:=wpad-full-internal --endef -- --define Package/wpad/description -- This package contains a full featured IEEE 802.1x/WPA/EAP/RADIUS -- Authenticator and Supplicant --endef -- --define Package/wpad-openssl --$(call Package/wpad/Default,$(1)) -- TITLE+= (OpenSSL full) -- VARIANT:=wpad-full-openssl -- DEPENDS+=+PACKAGE_wpad-openssl:libopenssl --endef -- --Package/wpad-openssl/description = $(Package/wpad/description) -- --define Package/wpad-wolfssl --$(call Package/wpad/Default,$(1)) -- TITLE+= (wolfSSL full) -- VARIANT:=wpad-full-wolfssl -- DEPENDS+=+PACKAGE_wpad-wolfssl:libwolfssl --endef -- --Package/wpad-wolfssl/description = $(Package/wpad/description) -- --define Package/wpad-mbedtls --$(call Package/wpad/Default,$(1)) -- TITLE+= (mbedTLS full) -- VARIANT:=wpad-full-mbedtls -- DEPENDS+=+PACKAGE_wpad-mbedtls:libmbedtls --endef -- --Package/wpad-mbedtls/description = $(Package/wpad/description) -- --define Package/wpad-basic --$(call Package/wpad/Default,$(1)) -- TITLE+= (WPA-PSK, 11r, 11w) -- VARIANT:=wpad-basic --endef -- --define Package/wpad-basic/description -- This package contains a basic IEEE 802.1x/WPA Authenticator and Supplicant with WPA-PSK, 802.11r and 802.11w support. --endef -- --define Package/wpad-basic-openssl --$(call Package/wpad/Default,$(1)) -- TITLE+= (OpenSSL, 11r, 11w) -- VARIANT:=wpad-basic-openssl -- DEPENDS+=+PACKAGE_wpad-basic-openssl:libopenssl --endef -- --define Package/wpad-basic-openssl/description -- This package contains a basic IEEE 802.1x/WPA Authenticator and Supplicant with WPA-PSK, SAE (WPA3-Personal), 802.11r and 802.11w support. --endef -- --define Package/wpad-basic-wolfssl --$(call Package/wpad/Default,$(1)) -- TITLE+= (wolfSSL, 11r, 11w) -- VARIANT:=wpad-basic-wolfssl -- DEPENDS+=+PACKAGE_wpad-basic-wolfssl:libwolfssl --endef -- --define Package/wpad-basic-wolfssl/description -- This package contains a basic IEEE 802.1x/WPA Authenticator and Supplicant with WPA-PSK, SAE (WPA3-Personal), 802.11r and 802.11w support. --endef -- --define Package/wpad-basic-mbedtls --$(call Package/wpad/Default,$(1)) -- TITLE+= (mbedTLS, 11r, 11w) -- VARIANT:=wpad-basic-mbedtls -- DEPENDS+=+PACKAGE_wpad-basic-mbedtls:libmbedtls --endef -- --define Package/wpad-basic-mbedtls/description -- This package contains a basic IEEE 802.1x/WPA Authenticator and Supplicant with WPA-PSK, SAE (WPA3-Personal), 802.11r and 802.11w support. --endef -- --define Package/wpad-mini --$(call Package/wpad/Default,$(1)) -- TITLE+= (WPA-PSK only) -- VARIANT:=wpad-mini --endef -- --define Package/wpad-mini/description -- This package contains a minimal IEEE 802.1x/WPA Authenticator and Supplicant (WPA-PSK only). --endef -- --define Package/wpad-mesh --$(call Package/wpad/Default,$(1)) -- DEPENDS+=@PACKAGE_kmod-cfg80211 @(!TARGET_uml||BROKEN) -- PROVIDES+=wpa-supplicant-mesh wpad-mesh --endef -- --define Package/wpad-mesh/description -- This package contains a minimal IEEE 802.1x/WPA Authenticator and Supplicant (with 802.11s mesh and SAE support). --endef -- --define Package/wpad-mesh-openssl --$(call Package/wpad-mesh,$(1)) -- TITLE+= (OpenSSL, 11s, SAE) -- DEPENDS+=+PACKAGE_wpad-mesh-openssl:libopenssl -- VARIANT:=wpad-mesh-openssl --endef -- --Package/wpad-mesh-openssl/description = $(Package/wpad-mesh/description) -- --define Package/wpad-mesh-wolfssl --$(call Package/wpad-mesh,$(1)) -- TITLE+= (wolfSSL, 11s, SAE) -- DEPENDS+=+PACKAGE_wpad-mesh-wolfssl:libwolfssl -- VARIANT:=wpad-mesh-wolfssl --endef -- --Package/wpad-mesh-wolfssl/description = $(Package/wpad-mesh/description) -- --define Package/wpad-mesh-mbedtls --$(call Package/wpad-mesh,$(1)) -- TITLE+= (mbedTLS, 11s, SAE) -- DEPENDS+=+PACKAGE_wpad-mesh-mbedtls:libmbedtls -- VARIANT:=wpad-mesh-mbedtls --endef -- --Package/wpad-mesh-mbedtls/description = $(Package/wpad-mesh/description) -- -- --define Package/wpa-supplicant/Default -- SECTION:=net -- CATEGORY:=Network -- SUBMENU:=WirelessAPD -- TITLE:=WPA Supplicant -- URL:=http://hostap.epitest.fi/wpa_supplicant/ -- DEPENDS:=$(DRV_DEPENDS) +hostapd-common +libubus -- EXTRA_DEPENDS:=hostapd-common (=$(PKG_VERSION)-$(PKG_RELEASE)) -- USERID:=network=101:network=101 -- PROVIDES:=wpa-supplicant -- CONFLICTS:=$(SUPPLICANT_PROVIDERS) -- SUPPLICANT_PROVIDERS+=$(1) --endef -- --define Package/wpa-supplicant --$(call Package/wpa-supplicant/Default,$(1)) -- TITLE+= (built-in full) -- VARIANT:=supplicant-full-internal --endef -- --define Package/wpa-supplicant-openssl --$(call Package/wpa-supplicant/Default,$(1)) -- TITLE+= (OpenSSL full) -- VARIANT:=supplicant-full-openssl -- DEPENDS+=+PACKAGE_wpa-supplicant-openssl:libopenssl --endef -- --define Package/wpa-supplicant-wolfssl --$(call Package/wpa-supplicant/Default,$(1)) -- TITLE+= (wolfSSL full) -- VARIANT:=supplicant-full-wolfssl -- DEPENDS+=+PACKAGE_wpa-supplicant-wolfssl:libwolfssl --endef -- --define Package/wpa-supplicant-mbedtls --$(call Package/wpa-supplicant/Default,$(1)) -- TITLE+= (mbedTLS full) -- VARIANT:=supplicant-full-mbedtls -- DEPENDS+=+PACKAGE_wpa-supplicant-mbedtls:libmbedtls --endef -- --define Package/wpa-supplicant/config -- source "$(SOURCE)/Config.in" --endef -- --define Package/wpa-supplicant-p2p --$(call Package/wpa-supplicant/Default,$(1)) -- TITLE+= (Wi-Fi P2P support) -- DEPENDS+=@PACKAGE_kmod-cfg80211 -- VARIANT:=supplicant-p2p-internal --endef -- --define Package/wpa-supplicant-mesh/Default --$(call Package/wpa-supplicant/Default,$(1)) -- DEPENDS+=@PACKAGE_kmod-cfg80211 @(!TARGET_uml||BROKEN) -- PROVIDES+=wpa-supplicant-mesh --endef -- --define Package/wpa-supplicant-mesh-openssl --$(call Package/wpa-supplicant-mesh/Default,$(1)) -- TITLE+= (OpenSSL, 11s, SAE) -- VARIANT:=supplicant-mesh-openssl -- DEPENDS+=+PACKAGE_wpa-supplicant-mesh-openssl:libopenssl --endef -- --define Package/wpa-supplicant-mesh-wolfssl --$(call Package/wpa-supplicant-mesh/Default,$(1)) -- TITLE+= (wolfSSL, 11s, SAE) -- VARIANT:=supplicant-mesh-wolfssl -- DEPENDS+=+PACKAGE_wpa-supplicant-mesh-wolfssl:libwolfssl --endef -- --define Package/wpa-supplicant-mesh-mbedtls --$(call Package/wpa-supplicant-mesh/Default,$(1)) -- TITLE+= (mbedTLS, 11s, SAE) -- VARIANT:=supplicant-mesh-mbedtls -- DEPENDS+=+PACKAGE_wpa-supplicant-mesh-mbedtls:libmbedtls --endef -- --define Package/wpa-supplicant-basic --$(call Package/wpa-supplicant/Default,$(1)) -- TITLE+= (11r, 11w) -- VARIANT:=supplicant-basic --endef -- --define Package/wpa-supplicant-mini --$(call Package/wpa-supplicant/Default,$(1)) -- TITLE+= (minimal) -- VARIANT:=supplicant-mini --endef -- -- --define Package/hostapd-common -- TITLE:=hostapd/wpa_supplicant common support files -- SECTION:=net -- CATEGORY:=Network -- SUBMENU:=WirelessAPD --endef -- --define Package/hostapd-utils -- SECTION:=net -- CATEGORY:=Network -- SUBMENU:=WirelessAPD -- TITLE:=IEEE 802.1x Authenticator (utils) -- URL:=http://hostap.epitest.fi/ -- DEPENDS:=@$(subst $(space),||,$(foreach pkg,$(HOSTAPD_PROVIDERS),PACKAGE_$(pkg))) -- VARIANT:=* --endef -- --define Package/hostapd-utils/description -- This package contains a command line utility to control the -- IEEE 802.1x/WPA/EAP/RADIUS Authenticator. --endef -- --define Package/wpa-cli -- SECTION:=net -- CATEGORY:=Network -- SUBMENU:=WirelessAPD -- DEPENDS:=@$(subst $(space),||,$(foreach pkg,$(SUPPLICANT_PROVIDERS),PACKAGE_$(pkg))) -- TITLE:=WPA Supplicant command line control utility -- VARIANT:=* --endef -- --define Package/eapol-test/Default -- TITLE:=802.1x auth test utility -- SECTION:=net -- SUBMENU:=WirelessAPD -- CATEGORY:=Network -- DEPENDS:=$(DRV_DEPENDS) +libubus --endef -- --define Package/eapol-test -- $(call Package/eapol-test/Default,$(1)) -- TITLE+= (built-in full) -- VARIANT:=supplicant-full-internal --endef -- --define Package/eapol-test-openssl -- $(call Package/eapol-test/Default,$(1)) -- TITLE+= (OpenSSL full) -- VARIANT:=supplicant-full-openssl -- CONFLICTS:=$(filter-out eapol-test-openssl ,$(EAPOL_TEST_PROVIDERS)) -- DEPENDS+=+PACKAGE_eapol-test-openssl:libopenssl -- PROVIDES:=eapol-test --endef -- --define Package/eapol-test-wolfssl -- $(call Package/eapol-test/Default,$(1)) -- TITLE+= (wolfSSL full) -- VARIANT:=supplicant-full-wolfssl -- CONFLICTS:=$(filter-out eapol-test-openssl ,$(filter-out eapol-test-wolfssl ,$(EAPOL_TEST_PROVIDERS))) -- DEPENDS+=+PACKAGE_eapol-test-wolfssl:libwolfssl -- PROVIDES:=eapol-test --endef -- --define Package/eapol-test-mbedtls -- $(call Package/eapol-test/Default,$(1)) -- TITLE+= (mbedTLS full) -- VARIANT:=supplicant-full-mbedtls -- CONFLICTS:=$(filter-out eapol-test-openssl ,$(filter-out eapol-test-mbedtls ,$(EAPOL_TEST_PROVIDERS))) -- DEPENDS+=+PACKAGE_eapol-test-mbedtls:libmbedtls -- PROVIDES:=eapol-test --endef -- -- --ifneq ($(wildcard $(PKG_BUILD_DIR)/.config_*),$(subst .configured_,.config_,$(STAMP_CONFIGURED))) -- define Build/Configure/rebuild -- $(FIND) $(PKG_BUILD_DIR) -name \*.o -or -name \*.a | $(XARGS) rm -f -- rm -f $(PKG_BUILD_DIR)/hostapd/hostapd -- rm -f $(PKG_BUILD_DIR)/wpa_supplicant/wpa_supplicant -- rm -f $(PKG_BUILD_DIR)/.config_* -- touch $(subst .configured_,.config_,$(STAMP_CONFIGURED)) -- endef --endif -- --define Build/Configure -- $(Build/Configure/rebuild) -- $(if $(wildcard ./files/hostapd-$(CONFIG_VARIANT).config), \ -- $(CP) ./files/hostapd-$(CONFIG_VARIANT).config $(PKG_BUILD_DIR)/hostapd/.config \ -- ) -- $(if $(wildcard ./files/wpa_supplicant-$(CONFIG_VARIANT).config), \ -- $(CP) ./files/wpa_supplicant-$(CONFIG_VARIANT).config $(PKG_BUILD_DIR)/wpa_supplicant/.config -- ) --endef -- --TARGET_CPPFLAGS := \ -- -I$(STAGING_DIR)/usr/include/libnl-tiny \ -- -I$(PKG_BUILD_DIR)/src/crypto \ -- $(TARGET_CPPFLAGS) \ -- -DCONFIG_LIBNL20 \ -- -D_GNU_SOURCE \ -- $(if $(CONFIG_WPA_MSG_MIN_PRIORITY),-DCONFIG_MSG_MIN_PRIORITY=$(CONFIG_WPA_MSG_MIN_PRIORITY)) -- --TARGET_LDFLAGS += -lubox -lubus -- --ifdef CONFIG_PACKAGE_kmod-cfg80211 -- TARGET_LDFLAGS += -lm -lnl-tiny --endif -- --ifdef CONFIG_WPA_ENABLE_WEP -- DRIVER_MAKEOPTS += CONFIG_WEP=y --endif -- --define Build/RunMake -- CFLAGS="$(TARGET_CPPFLAGS) $(TARGET_CFLAGS)" \ -- $(MAKE) $(PKG_JOBS) -C $(PKG_BUILD_DIR)/$(1) \ -- $(TARGET_CONFIGURE_OPTS) \ -- $(DRIVER_MAKEOPTS) \ -- LIBS="$(TARGET_LDFLAGS)" \ -- LIBS_c="$(TARGET_LDFLAGS_C)" \ -- AR="$(TARGET_CROSS)gcc-ar" \ -- BCHECK= \ -- $(if $(findstring s,$(OPENWRT_VERBOSE)),V=1) \ -- $(2) --endef -- --define Build/Compile/wpad -- echo ` \ -- $(call Build/RunMake,hostapd,-s MULTICALL=1 dump_cflags); \ -- $(call Build/RunMake,wpa_supplicant,-s MULTICALL=1 dump_cflags) | \ -- sed -e 's,-n ,,g' -e 's^$(TARGET_CFLAGS)^^' \ -- ` > $(PKG_BUILD_DIR)/.cflags -- sed -i 's/"/\\"/g' $(PKG_BUILD_DIR)/.cflags -- +$(call Build/RunMake,hostapd, \ -- CFLAGS="$$$$(cat $(PKG_BUILD_DIR)/.cflags)" \ -- MULTICALL=1 \ -- hostapd_cli hostapd_multi.a \ -- ) -- +$(call Build/RunMake,wpa_supplicant, \ -- CFLAGS="$$$$(cat $(PKG_BUILD_DIR)/.cflags)" \ -- MULTICALL=1 \ -- wpa_cli wpa_supplicant_multi.a \ -- ) -- +export MAKEFLAGS="$(MAKE_JOBSERVER)"; $(TARGET_CC) -o $(PKG_BUILD_DIR)/wpad \ -- $(TARGET_CFLAGS) \ -- ./files/multicall.c \ -- $(PKG_BUILD_DIR)/hostapd/hostapd_multi.a \ -- $(PKG_BUILD_DIR)/wpa_supplicant/wpa_supplicant_multi.a \ -- $(TARGET_LDFLAGS) --endef -- --define Build/Compile/hostapd -- +$(call Build/RunMake,hostapd, \ -- hostapd hostapd_cli \ -- ) --endef -- --define Build/Compile/supplicant -- +$(call Build/RunMake,wpa_supplicant, \ -- wpa_cli wpa_supplicant \ -- ) --endef -- --define Build/Compile/supplicant-full-internal -- +$(call Build/RunMake,wpa_supplicant, \ -- eapol_test \ -- ) --endef -- --define Build/Compile/supplicant-full-openssl -- +$(call Build/RunMake,wpa_supplicant, \ -- eapol_test \ -- ) --endef -- --define Build/Compile/supplicant-full-wolfssl -- +$(call Build/RunMake,wpa_supplicant, \ -- eapol_test \ -- ) --endef -- --define Build/Compile/supplicant-full-mbedtls -- +$(call Build/RunMake,wpa_supplicant, \ -- eapol_test \ -- ) --endef -- --define Build/Compile -- $(Build/Compile/$(LOCAL_TYPE)) -- $(Build/Compile/$(BUILD_VARIANT)) --endef -- --define Install/hostapd -- $(INSTALL_DIR) $(1)/usr/sbin --endef -- --define Install/supplicant -- $(INSTALL_DIR) $(1)/usr/sbin --endef -- --define Package/hostapd-common/install -- $(INSTALL_DIR) $(1)/etc/capabilities $(1)/etc/rc.button $(1)/etc/hotplug.d/ieee80211 $(1)/etc/init.d $(1)/lib/netifd $(1)/usr/share/acl.d -- $(INSTALL_BIN) ./files/dhcp-get-server.sh $(1)/lib/netifd/dhcp-get-server.sh -- $(INSTALL_DATA) ./files/hostapd.sh $(1)/lib/netifd/hostapd.sh -- $(INSTALL_BIN) ./files/wpad.init $(1)/etc/init.d/wpad -- $(INSTALL_BIN) ./files/wps-hotplug.sh $(1)/etc/rc.button/wps -- $(INSTALL_DATA) ./files/wpad_acl.json $(1)/usr/share/acl.d -- $(INSTALL_DATA) ./files/wpad.json $(1)/etc/capabilities --endef -- --define Package/hostapd/install -- $(call Install/hostapd,$(1)) -- $(INSTALL_BIN) $(PKG_BUILD_DIR)/hostapd/hostapd $(1)/usr/sbin/ --endef --Package/hostapd-basic/install = $(Package/hostapd/install) --Package/hostapd-basic-openssl/install = $(Package/hostapd/install) --Package/hostapd-basic-wolfssl/install = $(Package/hostapd/install) --Package/hostapd-basic-mbedtls/install = $(Package/hostapd/install) --Package/hostapd-mini/install = $(Package/hostapd/install) --Package/hostapd-openssl/install = $(Package/hostapd/install) --Package/hostapd-wolfssl/install = $(Package/hostapd/install) --Package/hostapd-mbedtls/install = $(Package/hostapd/install) -- --ifneq ($(LOCAL_TYPE),supplicant) -- define Package/hostapd-utils/install -- $(INSTALL_DIR) $(1)/usr/sbin -- $(INSTALL_BIN) $(PKG_BUILD_DIR)/hostapd/hostapd_cli $(1)/usr/sbin/ -- endef --endif -- --define Package/wpad/install -- $(call Install/hostapd,$(1)) -- $(call Install/supplicant,$(1)) -- $(INSTALL_BIN) $(PKG_BUILD_DIR)/wpad $(1)/usr/sbin/ -- $(LN) wpad $(1)/usr/sbin/hostapd -- $(LN) wpad $(1)/usr/sbin/wpa_supplicant --endef --Package/wpad-basic/install = $(Package/wpad/install) --Package/wpad-basic-openssl/install = $(Package/wpad/install) --Package/wpad-basic-wolfssl/install = $(Package/wpad/install) --Package/wpad-basic-mbedtls/install = $(Package/wpad/install) --Package/wpad-mini/install = $(Package/wpad/install) --Package/wpad-openssl/install = $(Package/wpad/install) --Package/wpad-wolfssl/install = $(Package/wpad/install) --Package/wpad-mbedtls/install = $(Package/wpad/install) --Package/wpad-mesh-openssl/install = $(Package/wpad/install) --Package/wpad-mesh-wolfssl/install = $(Package/wpad/install) --Package/wpad-mesh-mbedtls/install = $(Package/wpad/install) -- --define Package/wpa-supplicant/install -- $(call Install/supplicant,$(1)) -- $(INSTALL_BIN) $(PKG_BUILD_DIR)/wpa_supplicant/wpa_supplicant $(1)/usr/sbin/ --endef --Package/wpa-supplicant-basic/install = $(Package/wpa-supplicant/install) --Package/wpa-supplicant-mini/install = $(Package/wpa-supplicant/install) --Package/wpa-supplicant-p2p/install = $(Package/wpa-supplicant/install) --Package/wpa-supplicant-openssl/install = $(Package/wpa-supplicant/install) --Package/wpa-supplicant-wolfssl/install = $(Package/wpa-supplicant/install) --Package/wpa-supplicant-mbedtls/install = $(Package/wpa-supplicant/install) --Package/wpa-supplicant-mesh-openssl/install = $(Package/wpa-supplicant/install) --Package/wpa-supplicant-mesh-wolfssl/install = $(Package/wpa-supplicant/install) --Package/wpa-supplicant-mesh-mbedtls/install = $(Package/wpa-supplicant/install) -- --ifneq ($(LOCAL_TYPE),hostapd) -- define Package/wpa-cli/install -- $(INSTALL_DIR) $(1)/usr/sbin -- $(CP) $(PKG_BUILD_DIR)/wpa_supplicant/wpa_cli $(1)/usr/sbin/ -- endef --endif -- --ifeq ($(BUILD_VARIANT),supplicant-full-internal) -- define Package/eapol-test/install -- $(INSTALL_DIR) $(1)/usr/sbin -- $(CP) $(PKG_BUILD_DIR)/wpa_supplicant/eapol_test $(1)/usr/sbin/ -- endef --endif -- --ifeq ($(BUILD_VARIANT),supplicant-full-openssl) -- define Package/eapol-test-openssl/install -- $(INSTALL_DIR) $(1)/usr/sbin -- $(CP) $(PKG_BUILD_DIR)/wpa_supplicant/eapol_test $(1)/usr/sbin/ -- endef --endif -- --ifeq ($(BUILD_VARIANT),supplicant-full-wolfssl) -- define Package/eapol-test-wolfssl/install -- $(INSTALL_DIR) $(1)/usr/sbin -- $(CP) $(PKG_BUILD_DIR)/wpa_supplicant/eapol_test $(1)/usr/sbin/ -- endef --endif -- --ifeq ($(BUILD_VARIANT),supplicant-full-mbedtls) -- define Package/eapol-test-mbedtls/install -- $(INSTALL_DIR) $(1)/usr/sbin -- $(CP) $(PKG_BUILD_DIR)/wpa_supplicant/eapol_test $(1)/usr/sbin/ -- endef --endif -- --# Build hostapd-common before its dependents, to avoid --# spurious rebuilds when building multiple variants. --$(eval $(call BuildPackage,hostapd-common)) --$(eval $(call BuildPackage,hostapd)) --$(eval $(call BuildPackage,hostapd-basic)) --$(eval $(call BuildPackage,hostapd-basic-openssl)) --$(eval $(call BuildPackage,hostapd-basic-wolfssl)) --$(eval $(call BuildPackage,hostapd-basic-mbedtls)) --$(eval $(call BuildPackage,hostapd-mini)) --$(eval $(call BuildPackage,hostapd-openssl)) --$(eval $(call BuildPackage,hostapd-wolfssl)) --$(eval $(call BuildPackage,hostapd-mbedtls)) --$(eval $(call BuildPackage,wpad)) --$(eval $(call BuildPackage,wpad-mesh-openssl)) --$(eval $(call BuildPackage,wpad-mesh-wolfssl)) --$(eval $(call BuildPackage,wpad-mesh-mbedtls)) --$(eval $(call BuildPackage,wpad-basic)) --$(eval $(call BuildPackage,wpad-basic-openssl)) --$(eval $(call BuildPackage,wpad-basic-wolfssl)) --$(eval $(call BuildPackage,wpad-basic-mbedtls)) --$(eval $(call BuildPackage,wpad-mini)) --$(eval $(call BuildPackage,wpad-openssl)) --$(eval $(call BuildPackage,wpad-wolfssl)) --$(eval $(call BuildPackage,wpad-mbedtls)) --$(eval $(call BuildPackage,wpa-supplicant)) --$(eval $(call BuildPackage,wpa-supplicant-mesh-openssl)) --$(eval $(call BuildPackage,wpa-supplicant-mesh-wolfssl)) --$(eval $(call BuildPackage,wpa-supplicant-mesh-mbedtls)) --$(eval $(call BuildPackage,wpa-supplicant-basic)) --$(eval $(call BuildPackage,wpa-supplicant-mini)) --$(eval $(call BuildPackage,wpa-supplicant-p2p)) --$(eval $(call BuildPackage,wpa-supplicant-openssl)) --$(eval $(call BuildPackage,wpa-supplicant-wolfssl)) --$(eval $(call BuildPackage,wpa-supplicant-mbedtls)) --$(eval $(call BuildPackage,wpa-cli)) --$(eval $(call BuildPackage,hostapd-utils)) --$(eval $(call BuildPackage,eapol-test)) --$(eval $(call BuildPackage,eapol-test-openssl)) --$(eval $(call BuildPackage,eapol-test-wolfssl)) --$(eval $(call BuildPackage,eapol-test-mbedtls)) -diff --git a/package/network/services/hostapd/README.md b/package/network/services/hostapd/README.md -deleted file mode 100644 -index 2150863306..0000000000 ---- a/package/network/services/hostapd/README.md -+++ /dev/null -@@ -1,419 +0,0 @@ --# UBUS methods - hostapd -- --## bss_mgmt_enable --Enable 802.11k/v features. -- --### arguments --| Name | Type | Required | Description | --|---|---|---|---| --| neighbor_report | bool | no | enable 802.11k neighbor reports | --| beacon_report | bool | no | enable 802.11k beacon reports | --| link_measurements | bool | no | enable 802.11k link measurements | --| bss_transition | bool | no | enable 802.11v BSS transition support | -- --### example --`ubus call hostapd.wl5-fb bss_mgmt_enable '{ "neighbor_report": true, "beacon_report": true, "link_measurements": true, "bss_transition": true --}'` -- -- --## bss_transition_request --Initiate an 802.11v transition request. -- --### arguments --| Name | Type | Required | Description | --|---|---|---|---| --| addr | string | yes | client MAC address | --| disassociation_imminent | bool | no | set Disassociation Imminent bit | --| disassociation_timer | int32 | no | disassociate client if it doesn't roam after this time | --| validity_period | int32 | no | validity of the BSS Transition Candiate List | --| neighbors | array | no | BSS Transition Candidate List | --| abridged | bool | no | prefer APs in the BSS Transition Candidate List | --| dialog_token | int32 | no | identifier for the request/report transaction | --| mbo_reason | int32 | no | MBO Transition Reason Code Attribute | --| cell_pref | int32 | no | MBO Cellular Data Connection Preference Attribute | --| reassoc_delay | int32 | no | MBO Re-association retry delay | -- --### example --`ubus call hostapd.wl5-fb bss_transition_request '{ "addr": "68:2F:67:8B:98:ED", "disassociation_imminent": false, "disassociation_timer": 0, "validity_period": 30, "neighbors": ["b6a7b9cbeebabf5900008064090603026a00"], "abridged": 1 }'` -- -- --## config_add --Dynamically load a BSS configuration from a file. This is used by netifd's mac80211 support script to configure BSSes on multiple PHYs in a single hostapd instance. -- --### arguments --| Name | Type | Required | Description | --|---|---|---|---| --| iface | string | yes | WiFi interface name | --| config | string | yes | path to hostapd config file | -- -- --## config_remove --Dynamically remove a BSS configuration. -- --### arguments --| Name | Type | Required | Description | --|---|---|---|---| --| iface | string | yes | WiFi interface name | -- -- --## del_client --Kick a client off the network. -- --### arguments --| Name | Type | Required | Description | --|---|---|---|---| --| addr | string | yes | client MAC address | --| reason | int32 | no | 802.11 reason code | --| deauth | bool | no | deauthenticates client instead of disassociating | --| ban_time | int32 | no | ban client for N milliseconds | -- --### example --`ubus call hostapd.wl5-fb del_client '{ "addr": "68:2f:67:8b:98:ed", "reason": 5, "deauth": true, "ban_time": 10000 }'` -- -- --## get_clients --Show associated clients. -- --### example --`ubus call hostapd.wl5-fb get_clients` -- --### output --```json --{ -- "freq": 5260, -- "clients": { -- "68:2f:67:8b:98:ed": { -- "auth": true, -- "assoc": true, -- "authorized": true, -- "preauth": false, -- "wds": false, -- "wmm": true, -- "ht": true, -- "vht": true, -- "he": false, -- "wps": false, -- "mfp": true, -- "rrm": [ -- 0, -- 0, -- 0, -- 0, -- 0 -- ], -- "extended_capabilities": [ -- 0, -- 0, -- 0, -- 0, -- 0, -- 0, -- 0, -- 64 -- ], -- "aid": 3, -- "signature": "wifi4|probe:0,1,45,127,107,191,221(0017f2,10),221(001018,2),htcap:006f,htagg:1b,htmcs:0000ffff,vhtcap:0f825832,vhtrxmcs:0000ffea,vhttxmcs:0000ffea,extcap:0000008000000040|assoc:0,1,33,36,48,45,127,191,221(0017f2,10),221(001018,2),221(0050f2,2),htcap:006f,htagg:1b,htmcs:0000ffff,vhtcap:0f825832,vhtrxmcs:0000ffea,vhttxmcs:0000ffea,txpow:14f9,extcap:0000000000000040", -- "bytes": { -- "rx": 1933667, -- "tx": 746805 -- }, -- "airtime": { -- "rx": 208863, -- "tx": 9037883 -- }, -- "packets": { -- "rx": 3587, -- "tx": 2185 -- }, -- "rate": { -- "rx": 866700, -- "tx": 866700 -- }, -- "signal": -50, -- "capabilities": { -- "vht": { -- "su_beamformee": true, -- "mu_beamformee": false, -- "mcs_map": { -- "rx": { -- "1ss": 9, -- "2ss": 9, -- "3ss": 9, -- "4ss": -1, -- "5ss": -1, -- "6ss": -1, -- "7ss": -1, -- "8ss": -1 -- }, -- "tx": { -- "1ss": 9, -- "2ss": 9, -- "3ss": 9, -- "4ss": -1, -- "5ss": -1, -- "6ss": -1, -- "7ss": -1, -- "8ss": -1 -- } -- } -- } -- } -- } -- } --} --``` -- -- --## get_features --Show HT/VHT support. -- --### example --`ubus call hostapd.wl5-fb get_features` -- --### output --```json --{ -- "ht_supported": true, -- "vht_supported": true --} --``` -- -- --## get_status --Get BSS status. -- --### example --`ubus call hostapd.wl5-fb get_status` -- --### output --```json --{ -- "status": "ENABLED", -- "bssid": "b6:a7:b9:cb:ee:bc", -- "ssid": "fb", -- "freq": 5260, -- "channel": 52, -- "op_class": 128, -- "beacon_interval": 100, -- "phy": "wl5-lan", -- "rrm": { -- "neighbor_report_tx": 0 -- }, -- "wnm": { -- "bss_transition_query_rx": 0, -- "bss_transition_request_tx": 0, -- "bss_transition_response_rx": 0 -- }, -- "airtime": { -- "time": 259561738, -- "time_busy": 2844249, -- "utilization": 0 -- }, -- "dfs": { -- "cac_seconds": 60, -- "cac_active": false, -- "cac_seconds_left": 0 -- } --} --``` -- -- --## link_measurement_req --Initiate an 802.11k Link Measurement Request. -- --### arguments --| Name | Type | Required | Description | --|---|---|---|---| --| addr | string | yes | client MAC address | --| tx-power-used | int32 | no | transmit power used to transmit the Link Measurement Request frame | --| tx-power-max | int32 | no | upper limit of transmit power to be used by the client | -- -- --## list_bans --List banned clients. -- --### example --`ubus call hostapd.wl5-fb list_bans` -- --### output --```json --{ -- "clients": [ -- "68:2f:67:8b:98:ed" -- ] --} --``` -- -- --## notify_response --When enabled, hostapd will send a ubus notification and wait for a response before responding to various requests. This is used by e.g. usteer to make it possible to ignore probe requests. -- --:warning: enabling this will cause hostapd to stop responding to probe requests unless a ubus subscriber responds to the ubus notifications. -- --### arguments --| Name | Type | Required | Description | --|---|---|---|---| --| notify_response | int32 | yes | disable (0) or enable (!0) | -- --### example --`ubus call hostapd.wl5-fb notify_response '{ "notify_response": 1 }'` -- --## reload --Reload BSS configuration. -- --:warning: this can cause problems for certain configurations: -- --``` --Mon May 16 16:09:08 2022 daemon.warn hostapd: Failed to check if DFS is required; ret=-1 --Mon May 16 16:09:08 2022 daemon.warn hostapd: Failed to check if DFS is required; ret=-1 --Mon May 16 16:09:08 2022 daemon.err hostapd: Wrong coupling between HT and VHT/HE channel setting --``` -- --### example --`ubus call hostapd.wl5-fb reload` -- -- --## rrm_beacon_req --Send a Beacon Measurement Request to a client. -- --### arguments --| Name | Type | Required | Description | --|---|---|---|---| --| addr | string | yes | client MAC address | --| op_class | int32 | yes | the Regulatory Class for which this Measurement Request applies | --| channel | int32 | yes | channel to measure | --| duration | int32 | yes | compile Beacon Measurement Report after N TU | --| mode | int32 | yes | mode to be used for measurement (0: passive, 1: active, 2: beacon table) | --| bssid | string | no | filter BSSes in Beacon Measurement Report by BSSID | --| ssid | string | no | filter BSSes in Beacon Measurement Report by SSID| -- -- --## rrm_nr_get_own --Show Neighbor Report Element for this BSS. -- --### example --`ubus call hostapd.wl5-fb rrm_nr_get_own` -- --### output --```json --{ -- "value": [ -- "b6:a7:b9:cb:ee:bc", -- "fb", -- "b6a7b9cbeebcaf5900008095090603029b00" -- ] --} --``` -- -- --## rrm_nr_list --Show Neighbor Report Elements for other BSSes in this ESS. -- --### example --`ubus call hostapd.wl5-fb rrm_nr_list` -- --### output --```json --{ -- "list": [ -- [ -- "b6:a7:b9:cb:ee:ba", -- "fb", -- "b6a7b9cbeebabf5900008064090603026a00" -- ] -- ] --} --``` -- --## rrm_nr_set --Set the Neighbor Report Elements. An element for the node on which this command is executed will always be added. -- --### arguments --| Name | Type | Required | Description | --|---|---|---|---| --| list | array | yes | array of Neighbor Report Elements in the format of the rrm_nr_list output | -- --### example --`ubus call hostapd.wl5-fb rrm_nr_set '{ "list": [ [ "b6:a7:b9:cb:ee:ba", "fb", "b6a7b9cbeebabf5900008064090603026a00" ] ] }'` -- -- --## set_vendor_elements --Configure Vendor-specific Information Elements for BSS. -- --### arguments --| Name | Type | Required | Description | --|---|---|---|---| --| vendor_elements | string | yes | Vendor-specific Information Elements as hex string | -- --### example --`ubus call hostapd.wl5-fb set_vendor_elements '{ "vendor_elements": "dd054857dd6662" }'` -- -- --## switch_chan --Initiate a channel switch. -- --:warning: trying to switch to the channel that is currently in use will fail: `Command failed: Operation not supported` -- --### arguments --| Name | Type | Required | Description | --|---|---|---|---| --| freq | int32 | yes | frequency in MHz to switch to | --| bcn_count | int32 | no | count in Beacon frames (TBTT) to perform the switch | --| center_freq1 | int32 | no | segment 0 center frequency in MHz (valid for HT and VHT) | --| center_freq2 | int32 | no | segment 1 center frequency in MHz (valid only for 80 MHz channel width and an 80+80 channel) | --| bandwidth | int32 | no | channel width to use | --| sec_channel_offset| int32 | no | secondary channel offset for HT40 (0 = disabled, 1 = HT40+, -1 = HT40-) | --| ht | bool | no | enable 802.11n | --| vht | bool | no | enable 802.11ac | --| he | bool | no | enable 802.11ax | --| block_tx | bool | no | block transmission during CSA period | --| csa_force | bool | no | restart the interface in case the CSA fails | -- --## example --`ubus call hostapd.wl5-fb switch_chan '{ "freq": 5180, "bcn_count": 10, "center_freq1": 5210, "bandwidth": 80, "he": 1, "block_tx": 1, "csa_force": 0 }'` -- -- --## update_airtime --Set dynamic airtime weight for client. -- --### arguments --| Name | Type | Required | Description | --|---|---|---|---| --| sta | string | yes | client MAC address | --| weight | int32 | yes | airtime weight | -- -- --## update_beacon --Force beacon frame content to be updated and to start beaconing on an interface that uses start_disabled=1. -- --### example --`ubus call hostapd.wl5-fb update_beacon` -- -- --## wps_status --Get WPS status for BSS. -- --### example --`ubus call hostapd.wl5-fb wps_status` -- --### output --```json --{ -- "pbc_status": "Disabled", -- "last_wps_result": "None" --} --``` -- -- --## wps_cancel --Cancel WPS Push Button Configuration. -- --### example --`ubus call hostapd.wl5-fb wps_cancel` -- -- --## wps_start --Start WPS Push Button Configuration. -- --### example --`ubus call hostapd.wl5-fb wps_start` -diff --git a/package/network/services/hostapd/files/dhcp-get-server.sh b/package/network/services/hostapd/files/dhcp-get-server.sh -deleted file mode 100644 -index a1509ace2f..0000000000 ---- a/package/network/services/hostapd/files/dhcp-get-server.sh -+++ /dev/null -@@ -1,2 +0,0 @@ --#!/bin/sh --[ "$1" = bound ] && echo "$serverid" -diff --git a/package/network/services/hostapd/files/hostapd-basic.config b/package/network/services/hostapd/files/hostapd-basic.config -deleted file mode 100644 -index 3d19d8f902..0000000000 ---- a/package/network/services/hostapd/files/hostapd-basic.config -+++ /dev/null -@@ -1,404 +0,0 @@ --# Example hostapd build time configuration --# --# This file lists the configuration options that are used when building the --# hostapd binary. All lines starting with # are ignored. Configuration option --# lines must be commented out complete, if they are not to be included, i.e., --# just setting VARIABLE=n is not disabling that variable. --# --# This file is included in Makefile, so variables like CFLAGS and LIBS can also --# be modified from here. In most cass, these lines should use += in order not --# to override previous values of the variables. -- --# Driver interface for Host AP driver --#CONFIG_DRIVER_HOSTAP=y -- --# Driver interface for wired authenticator --CONFIG_DRIVER_WIRED=y -- --# Driver interface for drivers using the nl80211 kernel interface --CONFIG_DRIVER_NL80211=y -- --# QCA vendor extensions to nl80211 --#CONFIG_DRIVER_NL80211_QCA=y -- --# driver_nl80211.c requires libnl. If you are compiling it yourself --# you may need to point hostapd to your version of libnl. --# --#CFLAGS += -I$ --#LIBS += -L$ -- --# Use libnl v2.0 (or 3.0) libraries. --#CONFIG_LIBNL20=y -- --# Use libnl 3.2 libraries (if this is selected, CONFIG_LIBNL20 is ignored) --#CONFIG_LIBNL32=y -- -- --# Driver interface for FreeBSD net80211 layer (e.g., Atheros driver) --#CONFIG_DRIVER_BSD=y --#CFLAGS += -I/usr/local/include --#LIBS += -L/usr/local/lib --#LIBS_p += -L/usr/local/lib --#LIBS_c += -L/usr/local/lib -- --# Driver interface for no driver (e.g., RADIUS server only) --#CONFIG_DRIVER_NONE=y -- --# IEEE 802.11F/IAPP --#CONFIG_IAPP=y -- --# WPA2/IEEE 802.11i RSN pre-authentication --CONFIG_RSN_PREAUTH=y -- --# IEEE 802.11w (management frame protection) --#CONFIG_IEEE80211W=y -- --# Support Operating Channel Validation --CONFIG_OCV=y -- --# Integrated EAP server --#CONFIG_EAP=y -- --# EAP Re-authentication Protocol (ERP) in integrated EAP server --#CONFIG_ERP=y -- --# EAP-MD5 for the integrated EAP server --#CONFIG_EAP_MD5=y -- --# EAP-TLS for the integrated EAP server --#CONFIG_EAP_TLS=y -- --# EAP-MSCHAPv2 for the integrated EAP server --#CONFIG_EAP_MSCHAPV2=y -- --# EAP-PEAP for the integrated EAP server --#CONFIG_EAP_PEAP=y -- --# EAP-GTC for the integrated EAP server --#CONFIG_EAP_GTC=y -- --# EAP-TTLS for the integrated EAP server --#CONFIG_EAP_TTLS=y -- --# EAP-SIM for the integrated EAP server --#CONFIG_EAP_SIM=y -- --# EAP-AKA for the integrated EAP server --#CONFIG_EAP_AKA=y -- --# EAP-AKA' for the integrated EAP server --# This requires CONFIG_EAP_AKA to be enabled, too. --#CONFIG_EAP_AKA_PRIME=y -- --# EAP-PAX for the integrated EAP server --#CONFIG_EAP_PAX=y -- --# EAP-PSK for the integrated EAP server (this is _not_ needed for WPA-PSK) --#CONFIG_EAP_PSK=y -- --# EAP-pwd for the integrated EAP server (secure authentication with a password) --#CONFIG_EAP_PWD=y -- --# EAP-SAKE for the integrated EAP server --#CONFIG_EAP_SAKE=y -- --# EAP-GPSK for the integrated EAP server --#CONFIG_EAP_GPSK=y --# Include support for optional SHA256 cipher suite in EAP-GPSK --#CONFIG_EAP_GPSK_SHA256=y -- --# EAP-FAST for the integrated EAP server --#CONFIG_EAP_FAST=y -- --# EAP-TEAP for the integrated EAP server --# Note: The current EAP-TEAP implementation is experimental and should not be --# enabled for production use. The IETF RFC 7170 that defines EAP-TEAP has number --# of conflicting statements and missing details and the implementation has --# vendor specific workarounds for those and as such, may not interoperate with --# any other implementation. This should not be used for anything else than --# experimentation and interoperability testing until those issues has been --# resolved. --#CONFIG_EAP_TEAP=y -- --# Wi-Fi Protected Setup (WPS) --#CONFIG_WPS=y --# Enable UPnP support for external WPS Registrars --#CONFIG_WPS_UPNP=y --# Enable WPS support with NFC config method --#CONFIG_WPS_NFC=y -- --# EAP-IKEv2 --#CONFIG_EAP_IKEV2=y -- --# Trusted Network Connect (EAP-TNC) --#CONFIG_EAP_TNC=y -- --# EAP-EKE for the integrated EAP server --#CONFIG_EAP_EKE=y -- --# PKCS#12 (PFX) support (used to read private key and certificate file from --# a file that usually has extension .p12 or .pfx) --#CONFIG_PKCS12=y -- --# RADIUS authentication server. This provides access to the integrated EAP --# server from external hosts using RADIUS. --#CONFIG_RADIUS_SERVER=y -- --# Build IPv6 support for RADIUS operations --#CONFIG_IPV6=y -- --# IEEE Std 802.11r-2008 (Fast BSS Transition) --CONFIG_IEEE80211R=y -- --# Use the hostapd's IEEE 802.11 authentication (ACL), but without --# the IEEE 802.11 Management capability (e.g., FreeBSD/net80211) --#CONFIG_DRIVER_RADIUS_ACL=y -- --# IEEE 802.11n (High Throughput) support --CONFIG_IEEE80211N=y -- --# Wireless Network Management (IEEE Std 802.11v-2011) --# Note: This is experimental and not complete implementation. --#CONFIG_WNM=y -- --# IEEE 802.11ac (Very High Throughput) support --CONFIG_IEEE80211AC=y -- --# IEEE 802.11ax HE support --# Note: This is experimental and work in progress. The definitions are still --# subject to change and this should not be expected to interoperate with the --# final IEEE 802.11ax version. --#CONFIG_IEEE80211AX=y -- --# Remove debugging code that is printing out debug messages to stdout. --# This can be used to reduce the size of the hostapd considerably if debugging --# code is not needed. --#CONFIG_NO_STDOUT_DEBUG=y -- --# Add support for writing debug log to a file: -f /tmp/hostapd.log --# Disabled by default. --#CONFIG_DEBUG_FILE=y -- --# Send debug messages to syslog instead of stdout --CONFIG_DEBUG_SYSLOG=y -- --# Add support for sending all debug messages (regardless of debug verbosity) --# to the Linux kernel tracing facility. This helps debug the entire stack by --# making it easy to record everything happening from the driver up into the --# same file, e.g., using trace-cmd. --#CONFIG_DEBUG_LINUX_TRACING=y -- --# Remove support for RADIUS accounting --CONFIG_NO_ACCOUNTING=y -- --# Remove support for RADIUS --CONFIG_NO_RADIUS=y -- --# Remove support for VLANs --#CONFIG_NO_VLAN=y -- --# Enable support for fully dynamic VLANs. This enables hostapd to --# automatically create bridge and VLAN interfaces if necessary. --#CONFIG_FULL_DYNAMIC_VLAN=y -- --# Use netlink-based kernel API for VLAN operations instead of ioctl() --# Note: This requires libnl 3.1 or newer. --#CONFIG_VLAN_NETLINK=y -- --# Remove support for dumping internal state through control interface commands --# This can be used to reduce binary size at the cost of disabling a debugging --# option. --CONFIG_NO_DUMP_STATE=y -- --# Enable tracing code for developer debugging --# This tracks use of memory allocations and other registrations and reports --# incorrect use with a backtrace of call (or allocation) location. --#CONFIG_WPA_TRACE=y --# For BSD, comment out these. --#LIBS += -lexecinfo --#LIBS_p += -lexecinfo --#LIBS_c += -lexecinfo -- --# Use libbfd to get more details for developer debugging --# This enables use of libbfd to get more detailed symbols for the backtraces --# generated by CONFIG_WPA_TRACE=y. --#CONFIG_WPA_TRACE_BFD=y --# For BSD, comment out these. --#LIBS += -lbfd -liberty -lz --#LIBS_p += -lbfd -liberty -lz --#LIBS_c += -lbfd -liberty -lz -- --# hostapd depends on strong random number generation being available from the --# operating system. os_get_random() function is used to fetch random data when --# needed, e.g., for key generation. On Linux and BSD systems, this works by --# reading /dev/urandom. It should be noted that the OS entropy pool needs to be --# properly initialized before hostapd is started. This is important especially --# on embedded devices that do not have a hardware random number generator and --# may by default start up with minimal entropy available for random number --# generation. --# --# As a safety net, hostapd is by default trying to internally collect --# additional entropy for generating random data to mix in with the data --# fetched from the OS. This by itself is not considered to be very strong, but --# it may help in cases where the system pool is not initialized properly. --# However, it is very strongly recommended that the system pool is initialized --# with enough entropy either by using hardware assisted random number --# generator or by storing state over device reboots. --# --# hostapd can be configured to maintain its own entropy store over restarts to --# enhance random number generation. This is not perfect, but it is much more --# secure than using the same sequence of random numbers after every reboot. --# This can be enabled with -e command line option. The specified --# file needs to be readable and writable by hostapd. --# --# If the os_get_random() is known to provide strong random data (e.g., on --# Linux/BSD, the board in question is known to have reliable source of random --# data from /dev/urandom), the internal hostapd random pool can be disabled. --# This will save some in binary size and CPU use. However, this should only be --# considered for builds that are known to be used on devices that meet the --# requirements described above. --CONFIG_NO_RANDOM_POOL=y -- --# Should we attempt to use the getrandom(2) call that provides more reliable --# yet secure randomness source than /dev/random on Linux 3.17 and newer. --# Requires glibc 2.25 to build, falls back to /dev/random if unavailable. --CONFIG_GETRANDOM=y -- --# Should we use poll instead of select? Select is used by default. --#CONFIG_ELOOP_POLL=y -- --# Should we use epoll instead of select? Select is used by default. --CONFIG_ELOOP_EPOLL=y -- --# Should we use kqueue instead of select? Select is used by default. --#CONFIG_ELOOP_KQUEUE=y -- --# Select TLS implementation --# openssl = OpenSSL (default) --# gnutls = GnuTLS --# internal = Internal TLSv1 implementation (experimental) --# linux = Linux kernel AF_ALG and internal TLSv1 implementation (experimental) --# none = Empty template --CONFIG_TLS=internal -- --# TLS-based EAP methods require at least TLS v1.0. Newer version of TLS (v1.1) --# can be enabled to get a stronger construction of messages when block ciphers --# are used. --#CONFIG_TLSV11=y -- --# TLS-based EAP methods require at least TLS v1.0. Newer version of TLS (v1.2) --# can be enabled to enable use of stronger crypto algorithms. --#CONFIG_TLSV12=y -- --# Select which ciphers to use by default with OpenSSL if the user does not --# specify them. --#CONFIG_TLS_DEFAULT_CIPHERS="DEFAULT:!EXP:!LOW" -- --# If CONFIG_TLS=internal is used, additional library and include paths are --# needed for LibTomMath. Alternatively, an integrated, minimal version of --# LibTomMath can be used. See beginning of libtommath.c for details on benefits --# and drawbacks of this option. --#CONFIG_INTERNAL_LIBTOMMATH=y --#ifndef CONFIG_INTERNAL_LIBTOMMATH --#LTM_PATH=/usr/src/libtommath-0.39 --#CFLAGS += -I$(LTM_PATH) --#LIBS += -L$(LTM_PATH) --#LIBS_p += -L$(LTM_PATH) --#endif --# At the cost of about 4 kB of additional binary size, the internal LibTomMath --# can be configured to include faster routines for exptmod, sqr, and div to --# speed up DH and RSA calculation considerably --#CONFIG_INTERNAL_LIBTOMMATH_FAST=y -- --# Interworking (IEEE 802.11u) --# This can be used to enable functionality to improve interworking with --# external networks. --#CONFIG_INTERWORKING=y -- --# Hotspot 2.0 --#CONFIG_HS20=y -- --# Enable SQLite database support in hlr_auc_gw, EAP-SIM DB, and eap_user_file --#CONFIG_SQLITE=y -- --# Enable Fast Session Transfer (FST) --#CONFIG_FST=y -- --# Enable CLI commands for FST testing --#CONFIG_FST_TEST=y -- --# Testing options --# This can be used to enable some testing options (see also the example --# configuration file) that are really useful only for testing clients that --# connect to this hostapd. These options allow, for example, to drop a --# certain percentage of probe requests or auth/(re)assoc frames. --# --#CONFIG_TESTING_OPTIONS=y -- --# Automatic Channel Selection --# This will allow hostapd to pick the channel automatically when channel is set --# to "acs_survey" or "0". Eventually, other ACS algorithms can be added in --# similar way. --# --# Automatic selection is currently only done through initialization, later on --# we hope to do background checks to keep us moving to more ideal channels as --# time goes by. ACS is currently only supported through the nl80211 driver and --# your driver must have survey dump capability that is filled by the driver --# during scanning. --# --# You can customize the ACS survey algorithm with the hostapd.conf variable --# acs_num_scans. --# --# Supported ACS drivers: --# * ath9k --# * ath5k --# * ath10k --# --# For more details refer to: --# http://wireless.kernel.org/en/users/Documentation/acs --# --#CONFIG_ACS=y -- --# Multiband Operation support --# These extentions facilitate efficient use of multiple frequency bands --# available to the AP and the devices that may associate with it. --#CONFIG_MBO=y -- --# Client Taxonomy --# Has the AP retain the Probe Request and (Re)Association Request frames from --# a client, from which a signature can be produced which can identify the model --# of client device like "Nexus 6P" or "iPhone 5s". --#CONFIG_TAXONOMY=y -- --# Fast Initial Link Setup (FILS) (IEEE 802.11ai) --#CONFIG_FILS=y --# FILS shared key authentication with PFS --#CONFIG_FILS_SK_PFS=y -- --# Include internal line edit mode in hostapd_cli. This can be used to provide --# limited command line editing and history support. --#CONFIG_WPA_CLI_EDIT=y -- --# Opportunistic Wireless Encryption (OWE) --# Experimental implementation of draft-harkins-owe-07.txt --#CONFIG_OWE=y -- --# Airtime policy support --CONFIG_AIRTIME_POLICY=y -- --# Proxy ARP support --#CONFIG_PROXYARP=y -- --# Override default value for the wpa_disable_eapol_key_retries configuration --# parameter. See that parameter in hostapd.conf for more details. --#CFLAGS += -DDEFAULT_WPA_DISABLE_EAPOL_KEY_RETRIES=1 -- --# uBus IPC/RPC System --# Services can connect to the bus and provide methods --# that can be called by other services or clients. --CONFIG_UBUS=y -- --# OpenWrt patch 380-disable-ctrl-iface-mib.patch --# leads to the MIB only being compiled in if --# CONFIG_CTRL_IFACE_MIB is enabled. --#CONFIG_CTRL_IFACE_MIB=y -diff --git a/package/network/services/hostapd/files/hostapd-full.config b/package/network/services/hostapd/files/hostapd-full.config -deleted file mode 100644 -index 9076ebc44f..0000000000 ---- a/package/network/services/hostapd/files/hostapd-full.config -+++ /dev/null -@@ -1,404 +0,0 @@ --# Example hostapd build time configuration --# --# This file lists the configuration options that are used when building the --# hostapd binary. All lines starting with # are ignored. Configuration option --# lines must be commented out complete, if they are not to be included, i.e., --# just setting VARIABLE=n is not disabling that variable. --# --# This file is included in Makefile, so variables like CFLAGS and LIBS can also --# be modified from here. In most cass, these lines should use += in order not --# to override previous values of the variables. -- --# Driver interface for Host AP driver --#CONFIG_DRIVER_HOSTAP=y -- --# Driver interface for wired authenticator --CONFIG_DRIVER_WIRED=y -- --# Driver interface for drivers using the nl80211 kernel interface --CONFIG_DRIVER_NL80211=y -- --# QCA vendor extensions to nl80211 --#CONFIG_DRIVER_NL80211_QCA=y -- --# driver_nl80211.c requires libnl. If you are compiling it yourself --# you may need to point hostapd to your version of libnl. --# --#CFLAGS += -I$ --#LIBS += -L$ -- --# Use libnl v2.0 (or 3.0) libraries. --#CONFIG_LIBNL20=y -- --# Use libnl 3.2 libraries (if this is selected, CONFIG_LIBNL20 is ignored) --#CONFIG_LIBNL32=y -- -- --# Driver interface for FreeBSD net80211 layer (e.g., Atheros driver) --#CONFIG_DRIVER_BSD=y --#CFLAGS += -I/usr/local/include --#LIBS += -L/usr/local/lib --#LIBS_p += -L/usr/local/lib --#LIBS_c += -L/usr/local/lib -- --# Driver interface for no driver (e.g., RADIUS server only) --#CONFIG_DRIVER_NONE=y -- --# IEEE 802.11F/IAPP --CONFIG_IAPP=y -- --# WPA2/IEEE 802.11i RSN pre-authentication --CONFIG_RSN_PREAUTH=y -- --# IEEE 802.11w (management frame protection) --#CONFIG_IEEE80211W=y -- --# Support Operating Channel Validation --CONFIG_OCV=y -- --# Integrated EAP server --CONFIG_EAP=y -- --# EAP Re-authentication Protocol (ERP) in integrated EAP server --CONFIG_ERP=y -- --# EAP-MD5 for the integrated EAP server --CONFIG_EAP_MD5=y -- --# EAP-TLS for the integrated EAP server --CONFIG_EAP_TLS=y -- --# EAP-MSCHAPv2 for the integrated EAP server --CONFIG_EAP_MSCHAPV2=y -- --# EAP-PEAP for the integrated EAP server --CONFIG_EAP_PEAP=y -- --# EAP-GTC for the integrated EAP server --CONFIG_EAP_GTC=y -- --# EAP-TTLS for the integrated EAP server --CONFIG_EAP_TTLS=y -- --# EAP-SIM for the integrated EAP server --#CONFIG_EAP_SIM=y -- --# EAP-AKA for the integrated EAP server --#CONFIG_EAP_AKA=y -- --# EAP-AKA' for the integrated EAP server --# This requires CONFIG_EAP_AKA to be enabled, too. --#CONFIG_EAP_AKA_PRIME=y -- --# EAP-PAX for the integrated EAP server --#CONFIG_EAP_PAX=y -- --# EAP-PSK for the integrated EAP server (this is _not_ needed for WPA-PSK) --#CONFIG_EAP_PSK=y -- --# EAP-pwd for the integrated EAP server (secure authentication with a password) --#CONFIG_EAP_PWD=y -- --# EAP-SAKE for the integrated EAP server --#CONFIG_EAP_SAKE=y -- --# EAP-GPSK for the integrated EAP server --#CONFIG_EAP_GPSK=y --# Include support for optional SHA256 cipher suite in EAP-GPSK --#CONFIG_EAP_GPSK_SHA256=y -- --# EAP-FAST for the integrated EAP server --CONFIG_EAP_FAST=y -- --# EAP-TEAP for the integrated EAP server --# Note: The current EAP-TEAP implementation is experimental and should not be --# enabled for production use. The IETF RFC 7170 that defines EAP-TEAP has number --# of conflicting statements and missing details and the implementation has --# vendor specific workarounds for those and as such, may not interoperate with --# any other implementation. This should not be used for anything else than --# experimentation and interoperability testing until those issues has been --# resolved. --#CONFIG_EAP_TEAP=y -- --# Wi-Fi Protected Setup (WPS) --CONFIG_WPS=y --# Enable UPnP support for external WPS Registrars --#CONFIG_WPS_UPNP=y --# Enable WPS support with NFC config method --#CONFIG_WPS_NFC=y -- --# EAP-IKEv2 --#CONFIG_EAP_IKEV2=y -- --# Trusted Network Connect (EAP-TNC) --#CONFIG_EAP_TNC=y -- --# EAP-EKE for the integrated EAP server --#CONFIG_EAP_EKE=y -- --# PKCS#12 (PFX) support (used to read private key and certificate file from --# a file that usually has extension .p12 or .pfx) --CONFIG_PKCS12=y -- --# RADIUS authentication server. This provides access to the integrated EAP --# server from external hosts using RADIUS. --CONFIG_RADIUS_SERVER=y -- --# Build IPv6 support for RADIUS operations --CONFIG_IPV6=y -- --# IEEE Std 802.11r-2008 (Fast BSS Transition) --CONFIG_IEEE80211R=y -- --# Use the hostapd's IEEE 802.11 authentication (ACL), but without --# the IEEE 802.11 Management capability (e.g., FreeBSD/net80211) --#CONFIG_DRIVER_RADIUS_ACL=y -- --# IEEE 802.11n (High Throughput) support --CONFIG_IEEE80211N=y -- --# Wireless Network Management (IEEE Std 802.11v-2011) --# Note: This is experimental and not complete implementation. --CONFIG_WNM=y -- --# IEEE 802.11ac (Very High Throughput) support --CONFIG_IEEE80211AC=y -- --# IEEE 802.11ax HE support --# Note: This is experimental and work in progress. The definitions are still --# subject to change and this should not be expected to interoperate with the --# final IEEE 802.11ax version. --#CONFIG_IEEE80211AX=y -- --# Remove debugging code that is printing out debug messages to stdout. --# This can be used to reduce the size of the hostapd considerably if debugging --# code is not needed. --#CONFIG_NO_STDOUT_DEBUG=y -- --# Add support for writing debug log to a file: -f /tmp/hostapd.log --# Disabled by default. --#CONFIG_DEBUG_FILE=y -- --# Send debug messages to syslog instead of stdout --CONFIG_DEBUG_SYSLOG=y -- --# Add support for sending all debug messages (regardless of debug verbosity) --# to the Linux kernel tracing facility. This helps debug the entire stack by --# making it easy to record everything happening from the driver up into the --# same file, e.g., using trace-cmd. --#CONFIG_DEBUG_LINUX_TRACING=y -- --# Remove support for RADIUS accounting --#CONFIG_NO_ACCOUNTING=y -- --# Remove support for RADIUS --#CONFIG_NO_RADIUS=y -- --# Remove support for VLANs --#CONFIG_NO_VLAN=y -- --# Enable support for fully dynamic VLANs. This enables hostapd to --# automatically create bridge and VLAN interfaces if necessary. --CONFIG_FULL_DYNAMIC_VLAN=y -- --# Use netlink-based kernel API for VLAN operations instead of ioctl() --# Note: This requires libnl 3.1 or newer. --#CONFIG_VLAN_NETLINK=y -- --# Remove support for dumping internal state through control interface commands --# This can be used to reduce binary size at the cost of disabling a debugging --# option. --CONFIG_NO_DUMP_STATE=y -- --# Enable tracing code for developer debugging --# This tracks use of memory allocations and other registrations and reports --# incorrect use with a backtrace of call (or allocation) location. --#CONFIG_WPA_TRACE=y --# For BSD, comment out these. --#LIBS += -lexecinfo --#LIBS_p += -lexecinfo --#LIBS_c += -lexecinfo -- --# Use libbfd to get more details for developer debugging --# This enables use of libbfd to get more detailed symbols for the backtraces --# generated by CONFIG_WPA_TRACE=y. --#CONFIG_WPA_TRACE_BFD=y --# For BSD, comment out these. --#LIBS += -lbfd -liberty -lz --#LIBS_p += -lbfd -liberty -lz --#LIBS_c += -lbfd -liberty -lz -- --# hostapd depends on strong random number generation being available from the --# operating system. os_get_random() function is used to fetch random data when --# needed, e.g., for key generation. On Linux and BSD systems, this works by --# reading /dev/urandom. It should be noted that the OS entropy pool needs to be --# properly initialized before hostapd is started. This is important especially --# on embedded devices that do not have a hardware random number generator and --# may by default start up with minimal entropy available for random number --# generation. --# --# As a safety net, hostapd is by default trying to internally collect --# additional entropy for generating random data to mix in with the data --# fetched from the OS. This by itself is not considered to be very strong, but --# it may help in cases where the system pool is not initialized properly. --# However, it is very strongly recommended that the system pool is initialized --# with enough entropy either by using hardware assisted random number --# generator or by storing state over device reboots. --# --# hostapd can be configured to maintain its own entropy store over restarts to --# enhance random number generation. This is not perfect, but it is much more --# secure than using the same sequence of random numbers after every reboot. --# This can be enabled with -e command line option. The specified --# file needs to be readable and writable by hostapd. --# --# If the os_get_random() is known to provide strong random data (e.g., on --# Linux/BSD, the board in question is known to have reliable source of random --# data from /dev/urandom), the internal hostapd random pool can be disabled. --# This will save some in binary size and CPU use. However, this should only be --# considered for builds that are known to be used on devices that meet the --# requirements described above. --CONFIG_NO_RANDOM_POOL=y -- --# Should we attempt to use the getrandom(2) call that provides more reliable --# yet secure randomness source than /dev/random on Linux 3.17 and newer. --# Requires glibc 2.25 to build, falls back to /dev/random if unavailable. --CONFIG_GETRANDOM=y -- --# Should we use poll instead of select? Select is used by default. --#CONFIG_ELOOP_POLL=y -- --# Should we use epoll instead of select? Select is used by default. --CONFIG_ELOOP_EPOLL=y -- --# Should we use kqueue instead of select? Select is used by default. --#CONFIG_ELOOP_KQUEUE=y -- --# Select TLS implementation --# openssl = OpenSSL (default) --# gnutls = GnuTLS --# internal = Internal TLSv1 implementation (experimental) --# linux = Linux kernel AF_ALG and internal TLSv1 implementation (experimental) --# none = Empty template --CONFIG_TLS=internal -- --# TLS-based EAP methods require at least TLS v1.0. Newer version of TLS (v1.1) --# can be enabled to get a stronger construction of messages when block ciphers --# are used. --#CONFIG_TLSV11=y -- --# TLS-based EAP methods require at least TLS v1.0. Newer version of TLS (v1.2) --# can be enabled to enable use of stronger crypto algorithms. --#CONFIG_TLSV12=y -- --# Select which ciphers to use by default with OpenSSL if the user does not --# specify them. --#CONFIG_TLS_DEFAULT_CIPHERS="DEFAULT:!EXP:!LOW" -- --# If CONFIG_TLS=internal is used, additional library and include paths are --# needed for LibTomMath. Alternatively, an integrated, minimal version of --# LibTomMath can be used. See beginning of libtommath.c for details on benefits --# and drawbacks of this option. --CONFIG_INTERNAL_LIBTOMMATH=y --#ifndef CONFIG_INTERNAL_LIBTOMMATH --#LTM_PATH=/usr/src/libtommath-0.39 --#CFLAGS += -I$(LTM_PATH) --#LIBS += -L$(LTM_PATH) --#LIBS_p += -L$(LTM_PATH) --#endif --# At the cost of about 4 kB of additional binary size, the internal LibTomMath --# can be configured to include faster routines for exptmod, sqr, and div to --# speed up DH and RSA calculation considerably --#CONFIG_INTERNAL_LIBTOMMATH_FAST=y -- --# Interworking (IEEE 802.11u) --# This can be used to enable functionality to improve interworking with --# external networks. --CONFIG_INTERWORKING=y -- --# Hotspot 2.0 --CONFIG_HS20=y -- --# Enable SQLite database support in hlr_auc_gw, EAP-SIM DB, and eap_user_file --#CONFIG_SQLITE=y -- --# Enable Fast Session Transfer (FST) --#CONFIG_FST=y -- --# Enable CLI commands for FST testing --#CONFIG_FST_TEST=y -- --# Testing options --# This can be used to enable some testing options (see also the example --# configuration file) that are really useful only for testing clients that --# connect to this hostapd. These options allow, for example, to drop a --# certain percentage of probe requests or auth/(re)assoc frames. --# --#CONFIG_TESTING_OPTIONS=y -- --# Automatic Channel Selection --# This will allow hostapd to pick the channel automatically when channel is set --# to "acs_survey" or "0". Eventually, other ACS algorithms can be added in --# similar way. --# --# Automatic selection is currently only done through initialization, later on --# we hope to do background checks to keep us moving to more ideal channels as --# time goes by. ACS is currently only supported through the nl80211 driver and --# your driver must have survey dump capability that is filled by the driver --# during scanning. --# --# You can customize the ACS survey algorithm with the hostapd.conf variable --# acs_num_scans. --# --# Supported ACS drivers: --# * ath9k --# * ath5k --# * ath10k --# --# For more details refer to: --# http://wireless.kernel.org/en/users/Documentation/acs --# --#CONFIG_ACS=y -- --# Multiband Operation support --# These extentions facilitate efficient use of multiple frequency bands --# available to the AP and the devices that may associate with it. --#CONFIG_MBO=y -- --# Client Taxonomy --# Has the AP retain the Probe Request and (Re)Association Request frames from --# a client, from which a signature can be produced which can identify the model --# of client device like "Nexus 6P" or "iPhone 5s". --CONFIG_TAXONOMY=y -- --# Fast Initial Link Setup (FILS) (IEEE 802.11ai) --#CONFIG_FILS=y --# FILS shared key authentication with PFS --#CONFIG_FILS_SK_PFS=y -- --# Include internal line edit mode in hostapd_cli. This can be used to provide --# limited command line editing and history support. --#CONFIG_WPA_CLI_EDIT=y -- --# Opportunistic Wireless Encryption (OWE) --# Experimental implementation of draft-harkins-owe-07.txt --#CONFIG_OWE=y -- --# Airtime policy support --CONFIG_AIRTIME_POLICY=y -- --# Proxy ARP support --CONFIG_PROXYARP=y -- --# Override default value for the wpa_disable_eapol_key_retries configuration --# parameter. See that parameter in hostapd.conf for more details. --#CFLAGS += -DDEFAULT_WPA_DISABLE_EAPOL_KEY_RETRIES=1 -- --# uBus IPC/RPC System --# Services can connect to the bus and provide methods --# that can be called by other services or clients. --CONFIG_UBUS=y -- --# OpenWrt patch 380-disable-ctrl-iface-mib.patch --# leads to the MIB only being compiled in if --# CONFIG_CTRL_IFACE_MIB is enabled. --CONFIG_CTRL_IFACE_MIB=y -diff --git a/package/network/services/hostapd/files/hostapd-mini.config b/package/network/services/hostapd/files/hostapd-mini.config -deleted file mode 100644 -index f2ed071ec0..0000000000 ---- a/package/network/services/hostapd/files/hostapd-mini.config -+++ /dev/null -@@ -1,404 +0,0 @@ --# Example hostapd build time configuration --# --# This file lists the configuration options that are used when building the --# hostapd binary. All lines starting with # are ignored. Configuration option --# lines must be commented out complete, if they are not to be included, i.e., --# just setting VARIABLE=n is not disabling that variable. --# --# This file is included in Makefile, so variables like CFLAGS and LIBS can also --# be modified from here. In most cass, these lines should use += in order not --# to override previous values of the variables. -- --# Driver interface for Host AP driver --#CONFIG_DRIVER_HOSTAP=y -- --# Driver interface for wired authenticator --CONFIG_DRIVER_WIRED=y -- --# Driver interface for drivers using the nl80211 kernel interface --CONFIG_DRIVER_NL80211=y -- --# QCA vendor extensions to nl80211 --#CONFIG_DRIVER_NL80211_QCA=y -- --# driver_nl80211.c requires libnl. If you are compiling it yourself --# you may need to point hostapd to your version of libnl. --# --#CFLAGS += -I$ --#LIBS += -L$ -- --# Use libnl v2.0 (or 3.0) libraries. --#CONFIG_LIBNL20=y -- --# Use libnl 3.2 libraries (if this is selected, CONFIG_LIBNL20 is ignored) --#CONFIG_LIBNL32=y -- -- --# Driver interface for FreeBSD net80211 layer (e.g., Atheros driver) --#CONFIG_DRIVER_BSD=y --#CFLAGS += -I/usr/local/include --#LIBS += -L/usr/local/lib --#LIBS_p += -L/usr/local/lib --#LIBS_c += -L/usr/local/lib -- --# Driver interface for no driver (e.g., RADIUS server only) --#CONFIG_DRIVER_NONE=y -- --# IEEE 802.11F/IAPP --#CONFIG_IAPP=y -- --# WPA2/IEEE 802.11i RSN pre-authentication --CONFIG_RSN_PREAUTH=y -- --# IEEE 802.11w (management frame protection) --#CONFIG_IEEE80211W=y -- --# Support Operating Channel Validation --#CONFIG_OCV=y -- --# Integrated EAP server --#CONFIG_EAP=y -- --# EAP Re-authentication Protocol (ERP) in integrated EAP server --#CONFIG_ERP=y -- --# EAP-MD5 for the integrated EAP server --#CONFIG_EAP_MD5=y -- --# EAP-TLS for the integrated EAP server --#CONFIG_EAP_TLS=y -- --# EAP-MSCHAPv2 for the integrated EAP server --#CONFIG_EAP_MSCHAPV2=y -- --# EAP-PEAP for the integrated EAP server --#CONFIG_EAP_PEAP=y -- --# EAP-GTC for the integrated EAP server --#CONFIG_EAP_GTC=y -- --# EAP-TTLS for the integrated EAP server --#CONFIG_EAP_TTLS=y -- --# EAP-SIM for the integrated EAP server --#CONFIG_EAP_SIM=y -- --# EAP-AKA for the integrated EAP server --#CONFIG_EAP_AKA=y -- --# EAP-AKA' for the integrated EAP server --# This requires CONFIG_EAP_AKA to be enabled, too. --#CONFIG_EAP_AKA_PRIME=y -- --# EAP-PAX for the integrated EAP server --#CONFIG_EAP_PAX=y -- --# EAP-PSK for the integrated EAP server (this is _not_ needed for WPA-PSK) --#CONFIG_EAP_PSK=y -- --# EAP-pwd for the integrated EAP server (secure authentication with a password) --#CONFIG_EAP_PWD=y -- --# EAP-SAKE for the integrated EAP server --#CONFIG_EAP_SAKE=y -- --# EAP-GPSK for the integrated EAP server --#CONFIG_EAP_GPSK=y --# Include support for optional SHA256 cipher suite in EAP-GPSK --#CONFIG_EAP_GPSK_SHA256=y -- --# EAP-FAST for the integrated EAP server --#CONFIG_EAP_FAST=y -- --# EAP-TEAP for the integrated EAP server --# Note: The current EAP-TEAP implementation is experimental and should not be --# enabled for production use. The IETF RFC 7170 that defines EAP-TEAP has number --# of conflicting statements and missing details and the implementation has --# vendor specific workarounds for those and as such, may not interoperate with --# any other implementation. This should not be used for anything else than --# experimentation and interoperability testing until those issues has been --# resolved. --#CONFIG_EAP_TEAP=y -- --# Wi-Fi Protected Setup (WPS) --#CONFIG_WPS=y --# Enable UPnP support for external WPS Registrars --#CONFIG_WPS_UPNP=y --# Enable WPS support with NFC config method --#CONFIG_WPS_NFC=y -- --# EAP-IKEv2 --#CONFIG_EAP_IKEV2=y -- --# Trusted Network Connect (EAP-TNC) --#CONFIG_EAP_TNC=y -- --# EAP-EKE for the integrated EAP server --#CONFIG_EAP_EKE=y -- --# PKCS#12 (PFX) support (used to read private key and certificate file from --# a file that usually has extension .p12 or .pfx) --#CONFIG_PKCS12=y -- --# RADIUS authentication server. This provides access to the integrated EAP --# server from external hosts using RADIUS. --#CONFIG_RADIUS_SERVER=y -- --# Build IPv6 support for RADIUS operations --#CONFIG_IPV6=y -- --# IEEE Std 802.11r-2008 (Fast BSS Transition) --#CONFIG_IEEE80211R=y -- --# Use the hostapd's IEEE 802.11 authentication (ACL), but without --# the IEEE 802.11 Management capability (e.g., FreeBSD/net80211) --#CONFIG_DRIVER_RADIUS_ACL=y -- --# IEEE 802.11n (High Throughput) support --CONFIG_IEEE80211N=y -- --# Wireless Network Management (IEEE Std 802.11v-2011) --# Note: This is experimental and not complete implementation. --#CONFIG_WNM=y -- --# IEEE 802.11ac (Very High Throughput) support --CONFIG_IEEE80211AC=y -- --# IEEE 802.11ax HE support --# Note: This is experimental and work in progress. The definitions are still --# subject to change and this should not be expected to interoperate with the --# final IEEE 802.11ax version. --#CONFIG_IEEE80211AX=y -- --# Remove debugging code that is printing out debug messages to stdout. --# This can be used to reduce the size of the hostapd considerably if debugging --# code is not needed. --#CONFIG_NO_STDOUT_DEBUG=y -- --# Add support for writing debug log to a file: -f /tmp/hostapd.log --# Disabled by default. --#CONFIG_DEBUG_FILE=y -- --# Send debug messages to syslog instead of stdout --CONFIG_DEBUG_SYSLOG=y -- --# Add support for sending all debug messages (regardless of debug verbosity) --# to the Linux kernel tracing facility. This helps debug the entire stack by --# making it easy to record everything happening from the driver up into the --# same file, e.g., using trace-cmd. --#CONFIG_DEBUG_LINUX_TRACING=y -- --# Remove support for RADIUS accounting --CONFIG_NO_ACCOUNTING=y -- --# Remove support for RADIUS --CONFIG_NO_RADIUS=y -- --# Remove support for VLANs --#CONFIG_NO_VLAN=y -- --# Enable support for fully dynamic VLANs. This enables hostapd to --# automatically create bridge and VLAN interfaces if necessary. --#CONFIG_FULL_DYNAMIC_VLAN=y -- --# Use netlink-based kernel API for VLAN operations instead of ioctl() --# Note: This requires libnl 3.1 or newer. --#CONFIG_VLAN_NETLINK=y -- --# Remove support for dumping internal state through control interface commands --# This can be used to reduce binary size at the cost of disabling a debugging --# option. --CONFIG_NO_DUMP_STATE=y -- --# Enable tracing code for developer debugging --# This tracks use of memory allocations and other registrations and reports --# incorrect use with a backtrace of call (or allocation) location. --#CONFIG_WPA_TRACE=y --# For BSD, comment out these. --#LIBS += -lexecinfo --#LIBS_p += -lexecinfo --#LIBS_c += -lexecinfo -- --# Use libbfd to get more details for developer debugging --# This enables use of libbfd to get more detailed symbols for the backtraces --# generated by CONFIG_WPA_TRACE=y. --#CONFIG_WPA_TRACE_BFD=y --# For BSD, comment out these. --#LIBS += -lbfd -liberty -lz --#LIBS_p += -lbfd -liberty -lz --#LIBS_c += -lbfd -liberty -lz -- --# hostapd depends on strong random number generation being available from the --# operating system. os_get_random() function is used to fetch random data when --# needed, e.g., for key generation. On Linux and BSD systems, this works by --# reading /dev/urandom. It should be noted that the OS entropy pool needs to be --# properly initialized before hostapd is started. This is important especially --# on embedded devices that do not have a hardware random number generator and --# may by default start up with minimal entropy available for random number --# generation. --# --# As a safety net, hostapd is by default trying to internally collect --# additional entropy for generating random data to mix in with the data --# fetched from the OS. This by itself is not considered to be very strong, but --# it may help in cases where the system pool is not initialized properly. --# However, it is very strongly recommended that the system pool is initialized --# with enough entropy either by using hardware assisted random number --# generator or by storing state over device reboots. --# --# hostapd can be configured to maintain its own entropy store over restarts to --# enhance random number generation. This is not perfect, but it is much more --# secure than using the same sequence of random numbers after every reboot. --# This can be enabled with -e command line option. The specified --# file needs to be readable and writable by hostapd. --# --# If the os_get_random() is known to provide strong random data (e.g., on --# Linux/BSD, the board in question is known to have reliable source of random --# data from /dev/urandom), the internal hostapd random pool can be disabled. --# This will save some in binary size and CPU use. However, this should only be --# considered for builds that are known to be used on devices that meet the --# requirements described above. --CONFIG_NO_RANDOM_POOL=y -- --# Should we attempt to use the getrandom(2) call that provides more reliable --# yet secure randomness source than /dev/random on Linux 3.17 and newer. --# Requires glibc 2.25 to build, falls back to /dev/random if unavailable. --CONFIG_GETRANDOM=y -- --# Should we use poll instead of select? Select is used by default. --#CONFIG_ELOOP_POLL=y -- --# Should we use epoll instead of select? Select is used by default. --CONFIG_ELOOP_EPOLL=y -- --# Should we use kqueue instead of select? Select is used by default. --#CONFIG_ELOOP_KQUEUE=y -- --# Select TLS implementation --# openssl = OpenSSL (default) --# gnutls = GnuTLS --# internal = Internal TLSv1 implementation (experimental) --# linux = Linux kernel AF_ALG and internal TLSv1 implementation (experimental) --# none = Empty template --CONFIG_TLS=internal -- --# TLS-based EAP methods require at least TLS v1.0. Newer version of TLS (v1.1) --# can be enabled to get a stronger construction of messages when block ciphers --# are used. --#CONFIG_TLSV11=y -- --# TLS-based EAP methods require at least TLS v1.0. Newer version of TLS (v1.2) --# can be enabled to enable use of stronger crypto algorithms. --#CONFIG_TLSV12=y -- --# Select which ciphers to use by default with OpenSSL if the user does not --# specify them. --#CONFIG_TLS_DEFAULT_CIPHERS="DEFAULT:!EXP:!LOW" -- --# If CONFIG_TLS=internal is used, additional library and include paths are --# needed for LibTomMath. Alternatively, an integrated, minimal version of --# LibTomMath can be used. See beginning of libtommath.c for details on benefits --# and drawbacks of this option. --#CONFIG_INTERNAL_LIBTOMMATH=y --#ifndef CONFIG_INTERNAL_LIBTOMMATH --#LTM_PATH=/usr/src/libtommath-0.39 --#CFLAGS += -I$(LTM_PATH) --#LIBS += -L$(LTM_PATH) --#LIBS_p += -L$(LTM_PATH) --#endif --# At the cost of about 4 kB of additional binary size, the internal LibTomMath --# can be configured to include faster routines for exptmod, sqr, and div to --# speed up DH and RSA calculation considerably --#CONFIG_INTERNAL_LIBTOMMATH_FAST=y -- --# Interworking (IEEE 802.11u) --# This can be used to enable functionality to improve interworking with --# external networks. --#CONFIG_INTERWORKING=y -- --# Hotspot 2.0 --#CONFIG_HS20=y -- --# Enable SQLite database support in hlr_auc_gw, EAP-SIM DB, and eap_user_file --#CONFIG_SQLITE=y -- --# Enable Fast Session Transfer (FST) --#CONFIG_FST=y -- --# Enable CLI commands for FST testing --#CONFIG_FST_TEST=y -- --# Testing options --# This can be used to enable some testing options (see also the example --# configuration file) that are really useful only for testing clients that --# connect to this hostapd. These options allow, for example, to drop a --# certain percentage of probe requests or auth/(re)assoc frames. --# --#CONFIG_TESTING_OPTIONS=y -- --# Automatic Channel Selection --# This will allow hostapd to pick the channel automatically when channel is set --# to "acs_survey" or "0". Eventually, other ACS algorithms can be added in --# similar way. --# --# Automatic selection is currently only done through initialization, later on --# we hope to do background checks to keep us moving to more ideal channels as --# time goes by. ACS is currently only supported through the nl80211 driver and --# your driver must have survey dump capability that is filled by the driver --# during scanning. --# --# You can customize the ACS survey algorithm with the hostapd.conf variable --# acs_num_scans. --# --# Supported ACS drivers: --# * ath9k --# * ath5k --# * ath10k --# --# For more details refer to: --# http://wireless.kernel.org/en/users/Documentation/acs --# --#CONFIG_ACS=y -- --# Multiband Operation support --# These extentions facilitate efficient use of multiple frequency bands --# available to the AP and the devices that may associate with it. --#CONFIG_MBO=y -- --# Client Taxonomy --# Has the AP retain the Probe Request and (Re)Association Request frames from --# a client, from which a signature can be produced which can identify the model --# of client device like "Nexus 6P" or "iPhone 5s". --#CONFIG_TAXONOMY=y -- --# Fast Initial Link Setup (FILS) (IEEE 802.11ai) --#CONFIG_FILS=y --# FILS shared key authentication with PFS --#CONFIG_FILS_SK_PFS=y -- --# Include internal line edit mode in hostapd_cli. This can be used to provide --# limited command line editing and history support. --#CONFIG_WPA_CLI_EDIT=y -- --# Opportunistic Wireless Encryption (OWE) --# Experimental implementation of draft-harkins-owe-07.txt --#CONFIG_OWE=y -- --# Airtime policy support --#CONFIG_AIRTIME_POLICY=y -- --# Proxy ARP support --#CONFIG_PROXYARP=y -- --# Override default value for the wpa_disable_eapol_key_retries configuration --# parameter. See that parameter in hostapd.conf for more details. --#CFLAGS += -DDEFAULT_WPA_DISABLE_EAPOL_KEY_RETRIES=1 -- --# uBus IPC/RPC System --# Services can connect to the bus and provide methods --# that can be called by other services or clients. --CONFIG_UBUS=y -- --# OpenWrt patch 380-disable-ctrl-iface-mib.patch --# leads to the MIB only being compiled in if --# CONFIG_CTRL_IFACE_MIB is enabled. --#CONFIG_CTRL_IFACE_MIB=y diff --git a/package/network/services/hostapd/files/hostapd.sh b/package/network/services/hostapd/files/hostapd.sh deleted file mode 100644 -index 28bd210623..0000000000 +index 271c1f7bec..0000000000 --- a/package/network/services/hostapd/files/hostapd.sh +++ /dev/null -@@ -1,1616 +0,0 @@ +@@ -1,1598 +0,0 @@ -. /lib/functions/network.sh -. /lib/functions.sh - @@ -2841,14 +67,14 @@ index 28bd210623..0000000000 - append wpa_key_mgmt "WPA-EAP-SUITE-B-192" - [ "${ieee80211r:-0}" -gt 0 ] && append wpa_key_mgmt "FT-EAP-SHA384" - ;; -- eap-eap192) -- append wpa_key_mgmt "WPA-EAP-SUITE-B-192" +- eap-eap2) - append wpa_key_mgmt "WPA-EAP" -- [ "${ieee80211r:-0}" -gt 0 ] && { -- append wpa_key_mgmt "FT-EAP-SHA384" -- append wpa_key_mgmt "FT-EAP" -- } -- [ "${ieee80211w:-0}" -gt 0 ] && append wpa_key_mgmt "WPA-EAP-SHA256" +- append wpa_key_mgmt "WPA-EAP-SHA256" +- [ "${ieee80211r:-0}" -gt 0 ] && append wpa_key_mgmt "FT-EAP" +- ;; +- eap2) +- [ "${ieee80211r:-0}" -gt 0 ] && append wpa_key_mgmt "FT-EAP" +- append wpa_key_mgmt "WPA-EAP-SHA256" - ;; - sae) - append wpa_key_mgmt "SAE" @@ -2868,6 +94,10 @@ index 28bd210623..0000000000 - - [ "$fils" -gt 0 ] && { - case "$auth_type" in +- eap-192) +- append wpa_key_mgmt FILS-SHA384 +- [ "${ieee80211r:-0}" -gt 0 ] && append wpa_key_mgmt FT-FILS-SHA384 +- ;; - eap*) - append wpa_key_mgmt FILS-SHA256 - [ "${ieee80211r:-0}" -gt 0 ] && append wpa_key_mgmt FT-FILS-SHA256 @@ -2912,6 +142,7 @@ index 28bd210623..0000000000 - config_add_array hostapd_options - - config_add_int airtime_mode +- config_add_int mbssid - - hostapd_add_log_config -} @@ -2924,7 +155,8 @@ index 28bd210623..0000000000 - - json_get_vars country country3 country_ie beacon_int:100 doth require_mode legacy_rates \ - acs_chan_bias local_pwr_constraint spectrum_mgmt_required airtime_mode cell_density \ -- rts_threshold beacon_rate rssi_reject_assoc_rssi rssi_ignore_probe_request maxassoc +- rts_threshold beacon_rate rssi_reject_assoc_rssi rssi_ignore_probe_request maxassoc \ +- mbssid:0 - - hostapd_set_log_options base_cfg - @@ -3025,6 +257,7 @@ index 28bd210623..0000000000 - [ -n "$rts_threshold" ] && append base_cfg "rts_threshold=$rts_threshold" "$N" - [ "$airtime_mode" -gt 0 ] && append base_cfg "airtime_mode=$airtime_mode" "$N" - [ -n "$maxassoc" ] && append base_cfg "iface_max_num_sta=$maxassoc" "$N" +- [ "$mbssid" -gt 0 ] && [ "$mbssid" -le 2 ] && append base_cfg "mbssid=$mbssid" "$N" - - json_get_values opts hostapd_options - for val in $opts; do @@ -3416,8 +649,7 @@ index 28bd210623..0000000000 - [ -n "$wpa_strict_rekey" ] && append bss_conf "wpa_strict_rekey=$wpa_strict_rekey" "$N" - } - -- set_default nasid "${macaddr//\:}" -- append bss_conf "nas_identifier=$nasid" "$N" +- [ -n "$nasid" ] && append bss_conf "nas_identifier=$nasid" "$N" - - [ -n "$acct_interval" ] && \ - append bss_conf "radius_acct_interim_interval=$acct_interval" "$N" @@ -3427,12 +659,12 @@ index 28bd210623..0000000000 - [ -n "$ocv" ] && append bss_conf "ocv=$ocv" "$N" - - case "$auth_type" in -- sae|owe|eap192|eap-eap192) +- sae|owe|eap2|eap192) - set_default ieee80211w 2 - set_default sae_require_mfp 1 - set_default sae_pwe 2 - ;; -- psk-sae) +- psk-sae|eap-eap2) - set_default ieee80211w 1 - set_default sae_require_mfp 1 - set_default sae_pwe 2 @@ -3483,7 +715,7 @@ index 28bd210623..0000000000 - vlan_possible=1 - wps_possible=1 - ;; -- eap|eap192|eap-eap192) +- eap|eap2|eap-eap2|eap192) - json_get_vars \ - auth_server auth_secret auth_port \ - dae_client dae_secret dae_port \ @@ -3655,8 +887,9 @@ index 28bd210623..0000000000 - [ "$bss_transition" -eq "1" ] && append bss_conf "bss_transition=1" "$N" - [ "$mbo" -eq 1 ] && append bss_conf "mbo=1" "$N" - -- json_get_vars ieee80211k rrm_neighbor_report rrm_beacon_report +- json_get_vars ieee80211k rrm_neighbor_report rrm_beacon_report rnr - set_default ieee80211k 0 +- set_default rnr 0 - if [ "$ieee80211k" -eq "1" ]; then - set_default rrm_neighbor_report 1 - set_default rrm_beacon_report 1 @@ -3667,6 +900,7 @@ index 28bd210623..0000000000 - - [ "$rrm_neighbor_report" -eq "1" ] && append bss_conf "rrm_neighbor_report=1" "$N" - [ "$rrm_beacon_report" -eq "1" ] && append bss_conf "rrm_beacon_report=1" "$N" +- [ "$rnr" -eq "1" ] && append bss_conf "rnr=1" "$N" - - json_get_vars ftm_responder stationary_ap lci civic - set_default ftm_responder 0 @@ -3947,9 +1181,6 @@ index 28bd210623..0000000000 - append bss_conf "$val" "$N" - done - -- bss_md5sum="$(echo $bss_conf | md5sum | cut -d" " -f1)" -- append bss_conf "config_id=$bss_md5sum" "$N" -- - append "$var" "$bss_conf" "$N" - return 0 -} @@ -4091,7 +1322,7 @@ index 28bd210623..0000000000 - default_disabled - - case "$auth_type" in -- sae|owe|eap192|eap-eap192) +- sae|owe|eap2|eap192) - set_default ieee80211w 2 - ;; - psk-sae) @@ -4174,7 +1405,7 @@ index 28bd210623..0000000000 - fi - append network_data "$passphrase" "$N$T" - ;; -- eap|eap192|eap-eap192) +- eap|eap2|eap192) - hostapd_append_wpa_key_mgmt - key_mgmt="$wpa_key_mgmt" - @@ -4379,21060 +1610,9 @@ index 28bd210623..0000000000 - return 0 -} - --wpa_supplicant_run() { -- local ifname="$1" -- local hostapd_ctrl="$2" -- -- _wpa_supplicant_common "$ifname" -- -- ubus wait_for wpa_supplicant -- local supplicant_res="$(ubus call wpa_supplicant config_add "{ \ -- \"driver\": \"${_w_driver:-wext}\", \"ctrl\": \"$_rpath\", \ -- \"iface\": \"$ifname\", \"config\": \"$_config\" \ -- ${network_bridge:+, \"bridge\": \"$network_bridge\"} \ -- ${hostapd_ctrl:+, \"hostapd_ctrl\": \"$hostapd_ctrl\"} \ -- }")" -- -- ret="$?" -- -- [ "$ret" != 0 -o -z "$supplicant_res" ] && wireless_setup_vif_failed WPA_SUPPLICANT_FAILED -- -- wireless_add_process "$(jsonfilter -s "$supplicant_res" -l 1 -e @.pid)" "/usr/sbin/wpa_supplicant" 1 1 -- -- return $ret --} -- -hostapd_common_cleanup() { - killall meshd-nl80211 -} -diff --git a/package/network/services/hostapd/files/multicall.c b/package/network/services/hostapd/files/multicall.c -deleted file mode 100644 -index c8e814bb5c..0000000000 ---- a/package/network/services/hostapd/files/multicall.c -+++ /dev/null -@@ -1,28 +0,0 @@ --#include --#include --#include -- --extern int hostapd_main(int argc, char **argv); --extern int wpa_supplicant_main(int argc, char **argv); -- --int main(int argc, char **argv) --{ -- bool restart = false; -- const char *prog = argv[0]; -- --restart: -- if (strstr(argv[0], "hostapd")) -- return hostapd_main(argc, argv); -- else if (strstr(argv[0], "wpa_supplicant")) -- return wpa_supplicant_main(argc, argv); -- -- if (!restart && argc > 1) { -- argv++; -- argc--; -- restart = true; -- goto restart; -- } -- -- fprintf(stderr, "Invalid command.\nUsage: %s wpa_supplicant|hostapd []\n", prog); -- return 255; --} -diff --git a/package/network/services/hostapd/files/wpa_supplicant-basic.config b/package/network/services/hostapd/files/wpa_supplicant-basic.config -deleted file mode 100644 -index 6abd8e2331..0000000000 ---- a/package/network/services/hostapd/files/wpa_supplicant-basic.config -+++ /dev/null -@@ -1,625 +0,0 @@ --# Example wpa_supplicant build time configuration --# --# This file lists the configuration options that are used when building the --# wpa_supplicant binary. All lines starting with # are ignored. Configuration --# option lines must be commented out complete, if they are not to be included, --# i.e., just setting VARIABLE=n is not disabling that variable. --# --# This file is included in Makefile, so variables like CFLAGS and LIBS can also --# be modified from here. In most cases, these lines should use += in order not --# to override previous values of the variables. -- -- --# Uncomment following two lines and fix the paths if you have installed OpenSSL --# or GnuTLS in non-default location --#CFLAGS += -I/usr/local/openssl/include --#LIBS += -L/usr/local/openssl/lib -- --# Some Red Hat versions seem to include kerberos header files from OpenSSL, but --# the kerberos files are not in the default include path. Following line can be --# used to fix build issues on such systems (krb5.h not found). --#CFLAGS += -I/usr/include/kerberos -- --# 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 --# replacement for WEXT and its use allows wpa_supplicant to properly control --# the driver to improve existing functionality like roaming and to support new --# functionality. --CONFIG_DRIVER_WEXT=y -- --# Driver interface for Linux drivers using the nl80211 kernel interface --CONFIG_DRIVER_NL80211=y -- --# QCA vendor extensions to nl80211 --#CONFIG_DRIVER_NL80211_QCA=y -- --# driver_nl80211.c requires libnl. If you are compiling it yourself --# you may need to point hostapd to your version of libnl. --# --#CFLAGS += -I$ --#LIBS += -L$ -- --# Use libnl v2.0 (or 3.0) libraries. --#CONFIG_LIBNL20=y -- --# Use libnl 3.2 libraries (if this is selected, CONFIG_LIBNL20 is ignored) --#CONFIG_LIBNL32=y -- -- --# Driver interface for FreeBSD net80211 layer (e.g., Atheros driver) --#CONFIG_DRIVER_BSD=y --#CFLAGS += -I/usr/local/include --#LIBS += -L/usr/local/lib --#LIBS_p += -L/usr/local/lib --#LIBS_c += -L/usr/local/lib -- --# Driver interface for Windows NDIS --#CONFIG_DRIVER_NDIS=y --#CFLAGS += -I/usr/include/w32api/ddk --#LIBS += -L/usr/local/lib --# For native build using mingw --#CONFIG_NATIVE_WINDOWS=y --# Additional directories for cross-compilation on Linux host for mingw target --#CFLAGS += -I/opt/mingw/mingw32/include/ddk --#LIBS += -L/opt/mingw/mingw32/lib --#CC=mingw32-gcc --# By default, driver_ndis uses WinPcap for low-level operations. This can be --# replaced with the following option which replaces WinPcap calls with NDISUIO. --# However, this requires that WZC is disabled (net stop wzcsvc) before starting --# wpa_supplicant. --# CONFIG_USE_NDISUIO=y -- --# Driver interface for wired Ethernet drivers --CONFIG_DRIVER_WIRED=y -- --# Driver interface for MACsec capable Qualcomm Atheros drivers --#CONFIG_DRIVER_MACSEC_QCA=y -- --# Driver interface for Linux MACsec drivers --#CONFIG_DRIVER_MACSEC_LINUX=y -- --# Driver interface for the Broadcom RoboSwitch family --#CONFIG_DRIVER_ROBOSWITCH=y -- --# Driver interface for no driver (e.g., WPS ER only) --#CONFIG_DRIVER_NONE=y -- --# Solaris libraries --#LIBS += -lsocket -ldlpi -lnsl --#LIBS_c += -lsocket -- --# Enable IEEE 802.1X Supplicant (automatically included if any EAP method or --# MACsec is included) --#CONFIG_IEEE8021X_EAPOL=y -- --# EAP-MD5 --#CONFIG_EAP_MD5=y -- --# EAP-MSCHAPv2 --#CONFIG_EAP_MSCHAPV2=y -- --# EAP-TLS --#CONFIG_EAP_TLS=y -- --# EAL-PEAP --#CONFIG_EAP_PEAP=y -- --# EAP-TTLS --#CONFIG_EAP_TTLS=y -- --# EAP-FAST --#CONFIG_EAP_FAST=y -- --# EAP-TEAP --# Note: The current EAP-TEAP implementation is experimental and should not be --# enabled for production use. The IETF RFC 7170 that defines EAP-TEAP has number --# of conflicting statements and missing details and the implementation has --# vendor specific workarounds for those and as such, may not interoperate with --# any other implementation. This should not be used for anything else than --# experimentation and interoperability testing until those issues has been --# resolved. --#CONFIG_EAP_TEAP=y -- --# EAP-GTC --#CONFIG_EAP_GTC=y -- --# EAP-OTP --#CONFIG_EAP_OTP=y -- --# EAP-SIM (enable CONFIG_PCSC, if EAP-SIM is used) --#CONFIG_EAP_SIM=y -- --# Enable SIM simulator (Milenage) for EAP-SIM --#CONFIG_SIM_SIMULATOR=y -- --# EAP-PSK (experimental; this is _not_ needed for WPA-PSK) --#CONFIG_EAP_PSK=y -- --# EAP-pwd (secure authentication using only a password) --#CONFIG_EAP_PWD=y -- --# EAP-PAX --#CONFIG_EAP_PAX=y -- --# LEAP --#CONFIG_EAP_LEAP=y -- --# EAP-AKA (enable CONFIG_PCSC, if EAP-AKA is used) --#CONFIG_EAP_AKA=y -- --# EAP-AKA' (enable CONFIG_PCSC, if EAP-AKA' is used). --# This requires CONFIG_EAP_AKA to be enabled, too. --#CONFIG_EAP_AKA_PRIME=y -- --# Enable USIM simulator (Milenage) for EAP-AKA --#CONFIG_USIM_SIMULATOR=y -- --# EAP-SAKE --#CONFIG_EAP_SAKE=y -- --# EAP-GPSK --#CONFIG_EAP_GPSK=y --# Include support for optional SHA256 cipher suite in EAP-GPSK --#CONFIG_EAP_GPSK_SHA256=y -- --# EAP-TNC and related Trusted Network Connect support (experimental) --#CONFIG_EAP_TNC=y -- --# Wi-Fi Protected Setup (WPS) --#CONFIG_WPS=y --# Enable WPS external registrar functionality --#CONFIG_WPS_ER=y --# Disable credentials for an open network by default when acting as a WPS --# registrar. --#CONFIG_WPS_REG_DISABLE_OPEN=y --# Enable WPS support with NFC config method --#CONFIG_WPS_NFC=y -- --# EAP-IKEv2 --#CONFIG_EAP_IKEV2=y -- --# EAP-EKE --#CONFIG_EAP_EKE=y -- --# MACsec --#CONFIG_MACSEC=y -- --# PKCS#12 (PFX) support (used to read private key and certificate file from --# a file that usually has extension .p12 or .pfx) --#CONFIG_PKCS12=y -- --# Smartcard support (i.e., private key on a smartcard), e.g., with openssl --# engine. --#CONFIG_SMARTCARD=y -- --# PC/SC interface for smartcards (USIM, GSM SIM) --# Enable this if EAP-SIM or EAP-AKA is included --#CONFIG_PCSC=y -- --# Support HT overrides (disable HT/HT40, mask MCS rates, etc.) --CONFIG_HT_OVERRIDES=y -- --# Support VHT overrides (disable VHT, mask MCS rates, etc.) --CONFIG_VHT_OVERRIDES=y -- --# Development testing --#CONFIG_EAPOL_TEST=y -- --# Select control interface backend for external programs, e.g, wpa_cli: --# unix = UNIX domain sockets (default for Linux/*BSD) --# udp = UDP sockets using localhost (127.0.0.1) --# udp6 = UDP IPv6 sockets using localhost (::1) --# named_pipe = Windows Named Pipe (default for Windows) --# udp-remote = UDP sockets with remote access (only for tests systems/purpose) --# udp6-remote = UDP IPv6 sockets with remote access (only for tests purpose) --# y = use default (backwards compatibility) --# If this option is commented out, control interface is not included in the --# build. --CONFIG_CTRL_IFACE=y -- --# Include support for GNU Readline and History Libraries in wpa_cli. --# When building a wpa_cli binary for distribution, please note that these --# libraries are licensed under GPL and as such, BSD license may not apply for --# the resulting binary. --#CONFIG_READLINE=y -- --# Include internal line edit mode in wpa_cli. This can be used as a replacement --# for GNU Readline to provide limited command line editing and history support. --#CONFIG_WPA_CLI_EDIT=y -- --# Remove debugging code that is printing out debug message to stdout. --# This can be used to reduce the size of the wpa_supplicant considerably --# if debugging code is not needed. The size reduction can be around 35% --# (e.g., 90 kB). --#CONFIG_NO_STDOUT_DEBUG=y -- --# Remove WPA support, e.g., for wired-only IEEE 802.1X supplicant, to save --# 35-50 kB in code size. --#CONFIG_NO_WPA=y -- --# Remove IEEE 802.11i/WPA-Personal ASCII passphrase support --# This option can be used to reduce code size by removing support for --# converting ASCII passphrases into PSK. If this functionality is removed, the --# PSK can only be configured as the 64-octet hexstring (e.g., from --# wpa_passphrase). This saves about 0.5 kB in code size. --#CONFIG_NO_WPA_PASSPHRASE=y -- --# Simultaneous Authentication of Equals (SAE), WPA3-Personal --#CONFIG_SAE=y -- --# Disable scan result processing (ap_mode=1) to save code size by about 1 kB. --# This can be used if ap_scan=1 mode is never enabled. --#CONFIG_NO_SCAN_PROCESSING=y -- --# Select configuration backend: --# file = text file (e.g., wpa_supplicant.conf; note: the configuration file --# path is given on command line, not here; this option is just used to --# select the backend that allows configuration files to be used) --# winreg = Windows registry (see win_example.reg for an example) --CONFIG_BACKEND=file -- --# Remove configuration write functionality (i.e., to allow the configuration --# file to be updated based on runtime configuration changes). The runtime --# configuration can still be changed, the changes are just not going to be --# persistent over restarts. This option can be used to reduce code size by --# about 3.5 kB. --CONFIG_NO_CONFIG_WRITE=y -- --# Remove support for configuration blobs to reduce code size by about 1.5 kB. --#CONFIG_NO_CONFIG_BLOBS=y -- --# Select program entry point implementation: --# main = UNIX/POSIX like main() function (default) --# main_winsvc = Windows service (read parameters from registry) --# main_none = Very basic example (development use only) --#CONFIG_MAIN=main -- --# Select wrapper for operating system and C library specific functions --# unix = UNIX/POSIX like systems (default) --# win32 = Windows systems --# none = Empty template --#CONFIG_OS=unix -- --# Select event loop implementation --# eloop = select() loop (default) --# eloop_win = Windows events and WaitForMultipleObject() loop --#CONFIG_ELOOP=eloop -- --# Should we use poll instead of select? Select is used by default. --#CONFIG_ELOOP_POLL=y -- --# Should we use epoll instead of select? Select is used by default. --CONFIG_ELOOP_EPOLL=y -- --# Should we use kqueue instead of select? Select is used by default. --#CONFIG_ELOOP_KQUEUE=y -- --# Select layer 2 packet implementation --# linux = Linux packet socket (default) --# pcap = libpcap/libdnet/WinPcap --# freebsd = FreeBSD libpcap --# winpcap = WinPcap with receive thread --# ndis = Windows NDISUIO (note: requires CONFIG_USE_NDISUIO=y) --# none = Empty template --#CONFIG_L2_PACKET=linux -- --# Disable Linux packet socket workaround applicable for station interface --# in a bridge for EAPOL frames. This should be uncommented only if the kernel --# is known to not have the regression issue in packet socket behavior with --# bridge interfaces (commit 'bridge: respect RFC2863 operational state')'). --CONFIG_NO_LINUX_PACKET_SOCKET_WAR=y -- --# IEEE 802.11w (management frame protection), also known as PMF --# Driver support is also needed for IEEE 802.11w. --#CONFIG_IEEE80211W=y -- --# Support Operating Channel Validation --CONFIG_OCV=y -- --# Select TLS implementation --# openssl = OpenSSL (default) --# gnutls = GnuTLS --# internal = Internal TLSv1 implementation (experimental) --# linux = Linux kernel AF_ALG and internal TLSv1 implementation (experimental) --# none = Empty template --CONFIG_TLS=internal -- --# TLS-based EAP methods require at least TLS v1.0. Newer version of TLS (v1.1) --# can be enabled to get a stronger construction of messages when block ciphers --# are used. It should be noted that some existing TLS v1.0 -based --# implementation may not be compatible with TLS v1.1 message (ClientHello is --# sent prior to negotiating which version will be used) --#CONFIG_TLSV11=y -- --# TLS-based EAP methods require at least TLS v1.0. Newer version of TLS (v1.2) --# can be enabled to enable use of stronger crypto algorithms. It should be --# noted that some existing TLS v1.0 -based implementation may not be compatible --# with TLS v1.2 message (ClientHello is sent prior to negotiating which version --# will be used) --#CONFIG_TLSV12=y -- --# Select which ciphers to use by default with OpenSSL if the user does not --# specify them. --#CONFIG_TLS_DEFAULT_CIPHERS="DEFAULT:!EXP:!LOW" -- --# If CONFIG_TLS=internal is used, additional library and include paths are --# needed for LibTomMath. Alternatively, an integrated, minimal version of --# LibTomMath can be used. See beginning of libtommath.c for details on benefits --# and drawbacks of this option. --#CONFIG_INTERNAL_LIBTOMMATH=y --#ifndef CONFIG_INTERNAL_LIBTOMMATH --#LTM_PATH=/usr/src/libtommath-0.39 --#CFLAGS += -I$(LTM_PATH) --#LIBS += -L$(LTM_PATH) --#LIBS_p += -L$(LTM_PATH) --#endif --# At the cost of about 4 kB of additional binary size, the internal LibTomMath --# can be configured to include faster routines for exptmod, sqr, and div to --# speed up DH and RSA calculation considerably --#CONFIG_INTERNAL_LIBTOMMATH_FAST=y -- --# Include NDIS event processing through WMI into wpa_supplicant/wpasvc. --# This is only for Windows builds and requires WMI-related header files and --# WbemUuid.Lib from Platform SDK even when building with MinGW. --#CONFIG_NDIS_EVENTS_INTEGRATED=y --#PLATFORMSDKLIB="/opt/Program Files/Microsoft Platform SDK/Lib" -- --# Add support for new DBus control interface --# (fi.w1.hostap.wpa_supplicant1) --#CONFIG_CTRL_IFACE_DBUS_NEW=y -- --# Add introspection support for new DBus control interface --#CONFIG_CTRL_IFACE_DBUS_INTRO=y -- --# Add support for loading EAP methods dynamically as shared libraries. --# When this option is enabled, each EAP method can be either included --# statically (CONFIG_EAP_=y) or dynamically (CONFIG_EAP_=dyn). --# Dynamic EAP methods are build as shared objects (eap_*.so) and they need to --# be loaded in the beginning of the wpa_supplicant configuration file --# (see load_dynamic_eap parameter in the example file) before being used in --# the network blocks. --# --# Note that some shared parts of EAP methods are included in the main program --# and in order to be able to use dynamic EAP methods using these parts, the --# main program must have been build with the EAP method enabled (=y or =dyn). --# This means that EAP-TLS/PEAP/TTLS/FAST cannot be added as dynamic libraries --# unless at least one of them was included in the main build to force inclusion --# of the shared code. Similarly, at least one of EAP-SIM/AKA must be included --# in the main build to be able to load these methods dynamically. --# --# Please also note that using dynamic libraries will increase the total binary --# size. Thus, it may not be the best option for targets that have limited --# amount of memory/flash. --#CONFIG_DYNAMIC_EAP_METHODS=y -- --# IEEE Std 802.11r-2008 (Fast BSS Transition) for station mode --CONFIG_IEEE80211R=y -- --# Add support for writing debug log to a file (/tmp/wpa_supplicant-log-#.txt) --#CONFIG_DEBUG_FILE=y -- --# Send debug messages to syslog instead of stdout --CONFIG_DEBUG_SYSLOG=y --# Set syslog facility for debug messages --CONFIG_DEBUG_SYSLOG_FACILITY=LOG_DAEMON -- --# Add support for sending all debug messages (regardless of debug verbosity) --# to the Linux kernel tracing facility. This helps debug the entire stack by --# making it easy to record everything happening from the driver up into the --# same file, e.g., using trace-cmd. --#CONFIG_DEBUG_LINUX_TRACING=y -- --# Add support for writing debug log to Android logcat instead of standard --# output --#CONFIG_ANDROID_LOG=y -- --# Enable privilege separation (see README 'Privilege separation' for details) --#CONFIG_PRIVSEP=y -- --# Enable mitigation against certain attacks against TKIP by delaying Michael --# MIC error reports by a random amount of time between 0 and 60 seconds --#CONFIG_DELAYED_MIC_ERROR_REPORT=y -- --# Enable tracing code for developer debugging --# This tracks use of memory allocations and other registrations and reports --# incorrect use with a backtrace of call (or allocation) location. --#CONFIG_WPA_TRACE=y --# For BSD, uncomment these. --#LIBS += -lexecinfo --#LIBS_p += -lexecinfo --#LIBS_c += -lexecinfo -- --# Use libbfd to get more details for developer debugging --# This enables use of libbfd to get more detailed symbols for the backtraces --# generated by CONFIG_WPA_TRACE=y. --#CONFIG_WPA_TRACE_BFD=y --# For BSD, uncomment these. --#LIBS += -lbfd -liberty -lz --#LIBS_p += -lbfd -liberty -lz --#LIBS_c += -lbfd -liberty -lz -- --# wpa_supplicant depends on strong random number generation being available --# from the operating system. os_get_random() function is used to fetch random --# data when needed, e.g., for key generation. On Linux and BSD systems, this --# works by reading /dev/urandom. It should be noted that the OS entropy pool --# needs to be properly initialized before wpa_supplicant is started. This is --# important especially on embedded devices that do not have a hardware random --# number generator and may by default start up with minimal entropy available --# for random number generation. --# --# As a safety net, wpa_supplicant is by default trying to internally collect --# additional entropy for generating random data to mix in with the data fetched --# from the OS. This by itself is not considered to be very strong, but it may --# help in cases where the system pool is not initialized properly. However, it --# is very strongly recommended that the system pool is initialized with enough --# entropy either by using hardware assisted random number generator or by --# storing state over device reboots. --# --# wpa_supplicant can be configured to maintain its own entropy store over --# restarts to enhance random number generation. This is not perfect, but it is --# much more secure than using the same sequence of random numbers after every --# reboot. This can be enabled with -e command line option. The --# specified file needs to be readable and writable by wpa_supplicant. --# --# If the os_get_random() is known to provide strong random data (e.g., on --# Linux/BSD, the board in question is known to have reliable source of random --# data from /dev/urandom), the internal wpa_supplicant random pool can be --# disabled. This will save some in binary size and CPU use. However, this --# should only be considered for builds that are known to be used on devices --# that meet the requirements described above. --CONFIG_NO_RANDOM_POOL=y -- --# Should we attempt to use the getrandom(2) call that provides more reliable --# yet secure randomness source than /dev/random on Linux 3.17 and newer. --# Requires glibc 2.25 to build, falls back to /dev/random if unavailable. --CONFIG_GETRANDOM=y -- --# IEEE 802.11n (High Throughput) support (mainly for AP mode) --#CONFIG_IEEE80211N=y -- --# IEEE 802.11ac (Very High Throughput) support (mainly for AP mode) --# (depends on CONFIG_IEEE80211N) --#CONFIG_IEEE80211AC=y -- --# Wireless Network Management (IEEE Std 802.11v-2011) --# Note: This is experimental and not complete implementation. --#CONFIG_WNM=y -- --# Interworking (IEEE 802.11u) --# This can be used to enable functionality to improve interworking with --# external networks (GAS/ANQP to learn more about the networks and network --# selection based on available credentials). --#CONFIG_INTERWORKING=y -- --# Hotspot 2.0 --#CONFIG_HS20=y -- --# Enable interface matching in wpa_supplicant --#CONFIG_MATCH_IFACE=y -- --# Disable roaming in wpa_supplicant --#CONFIG_NO_ROAMING=y -- --# AP mode operations with wpa_supplicant --# This can be used for controlling AP mode operations with wpa_supplicant. It --# should be noted that this is mainly aimed at simple cases like --# WPA2-Personal while more complex configurations like WPA2-Enterprise with an --# external RADIUS server can be supported with hostapd. --#CONFIG_AP=y -- --# P2P (Wi-Fi Direct) --# This can be used to enable P2P support in wpa_supplicant. See README-P2P for --# more information on P2P operations. --#CONFIG_P2P=y -- --# Enable TDLS support --#CONFIG_TDLS=y -- --# Wi-Fi Display --# This can be used to enable Wi-Fi Display extensions for P2P using an external --# program to control the additional information exchanges in the messages. --#CONFIG_WIFI_DISPLAY=y -- --# Autoscan --# This can be used to enable automatic scan support in wpa_supplicant. --# See wpa_supplicant.conf for more information on autoscan usage. --# --# Enabling directly a module will enable autoscan support. --# For exponential module: --#CONFIG_AUTOSCAN_EXPONENTIAL=y --# For periodic module: --#CONFIG_AUTOSCAN_PERIODIC=y -- --# Password (and passphrase, etc.) backend for external storage --# These optional mechanisms can be used to add support for storing passwords --# and other secrets in external (to wpa_supplicant) location. This allows, for --# example, operating system specific key storage to be used --# --# External password backend for testing purposes (developer use) --#CONFIG_EXT_PASSWORD_TEST=y -- --# Enable Fast Session Transfer (FST) --#CONFIG_FST=y -- --# Enable CLI commands for FST testing --#CONFIG_FST_TEST=y -- --# OS X builds. This is only for building eapol_test. --#CONFIG_OSX=y -- --# Automatic Channel Selection --# This will allow wpa_supplicant to pick the channel automatically when channel --# is set to "0". --# --# TODO: Extend parser to be able to parse "channel=acs_survey" as an alternative --# to "channel=0". This would enable us to eventually add other ACS algorithms in --# similar way. --# --# Automatic selection is currently only done through initialization, later on --# we hope to do background checks to keep us moving to more ideal channels as --# time goes by. ACS is currently only supported through the nl80211 driver and --# your driver must have survey dump capability that is filled by the driver --# during scanning. --# --# TODO: In analogy to hostapd be able to customize the ACS survey algorithm with --# a newly to create wpa_supplicant.conf variable acs_num_scans. --# --# Supported ACS drivers: --# * ath9k --# * ath5k --# * ath10k --# --# For more details refer to: --# http://wireless.kernel.org/en/users/Documentation/acs --#CONFIG_ACS=y -- --# Support Multi Band Operation --#CONFIG_MBO=y -- --# Fast Initial Link Setup (FILS) (IEEE 802.11ai) --#CONFIG_FILS=y --# FILS shared key authentication with PFS --#CONFIG_FILS_SK_PFS=y -- --# Support RSN on IBSS networks --# This is needed to be able to use mode=1 network profile with proto=RSN and --# key_mgmt=WPA-PSK (i.e., full key management instead of WPA-None). --#CONFIG_IBSS_RSN=y -- --# External PMKSA cache control --# This can be used to enable control interface commands that allow the current --# PMKSA cache entries to be fetched and new entries to be added. --#CONFIG_PMKSA_CACHE_EXTERNAL=y -- --# Mesh Networking (IEEE 802.11s) --#CONFIG_MESH=y -- --# Background scanning modules --# These can be used to request wpa_supplicant to perform background scanning --# operations for roaming within an ESS (same SSID). See the bgscan parameter in --# the wpa_supplicant.conf file for more details. --# Periodic background scans based on signal strength --#CONFIG_BGSCAN_SIMPLE=y --# Learn channels used by the network and try to avoid bgscans on other --# channels (experimental) --#CONFIG_BGSCAN_LEARN=y -- --# Opportunistic Wireless Encryption (OWE) --# Experimental implementation of draft-harkins-owe-07.txt --#CONFIG_OWE=y -- --# Device Provisioning Protocol (DPP) --# This requires CONFIG_IEEE80211W=y to be enabled, too. (see --# wpa_supplicant/README-DPP for details) --#CONFIG_DPP=y -- --# uBus IPC/RPC System --# Services can connect to the bus and provide methods --# that can be called by other services or clients. --CONFIG_UBUS=y -- --# OpenWrt patch 380-disable-ctrl-iface-mib.patch --# leads to the MIB only being compiled in if --# CONFIG_CTRL_IFACE_MIB is enabled. --#CONFIG_CTRL_IFACE_MIB=y -diff --git a/package/network/services/hostapd/files/wpa_supplicant-full.config b/package/network/services/hostapd/files/wpa_supplicant-full.config -deleted file mode 100644 -index d24fbbb01f..0000000000 ---- a/package/network/services/hostapd/files/wpa_supplicant-full.config -+++ /dev/null -@@ -1,625 +0,0 @@ --# Example wpa_supplicant build time configuration --# --# This file lists the configuration options that are used when building the --# wpa_supplicant binary. All lines starting with # are ignored. Configuration --# option lines must be commented out complete, if they are not to be included, --# i.e., just setting VARIABLE=n is not disabling that variable. --# --# This file is included in Makefile, so variables like CFLAGS and LIBS can also --# be modified from here. In most cases, these lines should use += in order not --# to override previous values of the variables. -- -- --# Uncomment following two lines and fix the paths if you have installed OpenSSL --# or GnuTLS in non-default location --#CFLAGS += -I/usr/local/openssl/include --#LIBS += -L/usr/local/openssl/lib -- --# Some Red Hat versions seem to include kerberos header files from OpenSSL, but --# the kerberos files are not in the default include path. Following line can be --# used to fix build issues on such systems (krb5.h not found). --#CFLAGS += -I/usr/include/kerberos -- --# 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 --# replacement for WEXT and its use allows wpa_supplicant to properly control --# the driver to improve existing functionality like roaming and to support new --# functionality. --CONFIG_DRIVER_WEXT=y -- --# Driver interface for Linux drivers using the nl80211 kernel interface --CONFIG_DRIVER_NL80211=y -- --# QCA vendor extensions to nl80211 --#CONFIG_DRIVER_NL80211_QCA=y -- --# driver_nl80211.c requires libnl. If you are compiling it yourself --# you may need to point hostapd to your version of libnl. --# --#CFLAGS += -I$ --#LIBS += -L$ -- --# Use libnl v2.0 (or 3.0) libraries. --#CONFIG_LIBNL20=y -- --# Use libnl 3.2 libraries (if this is selected, CONFIG_LIBNL20 is ignored) --#CONFIG_LIBNL32=y -- -- --# Driver interface for FreeBSD net80211 layer (e.g., Atheros driver) --#CONFIG_DRIVER_BSD=y --#CFLAGS += -I/usr/local/include --#LIBS += -L/usr/local/lib --#LIBS_p += -L/usr/local/lib --#LIBS_c += -L/usr/local/lib -- --# Driver interface for Windows NDIS --#CONFIG_DRIVER_NDIS=y --#CFLAGS += -I/usr/include/w32api/ddk --#LIBS += -L/usr/local/lib --# For native build using mingw --#CONFIG_NATIVE_WINDOWS=y --# Additional directories for cross-compilation on Linux host for mingw target --#CFLAGS += -I/opt/mingw/mingw32/include/ddk --#LIBS += -L/opt/mingw/mingw32/lib --#CC=mingw32-gcc --# By default, driver_ndis uses WinPcap for low-level operations. This can be --# replaced with the following option which replaces WinPcap calls with NDISUIO. --# However, this requires that WZC is disabled (net stop wzcsvc) before starting --# wpa_supplicant. --# CONFIG_USE_NDISUIO=y -- --# Driver interface for wired Ethernet drivers --CONFIG_DRIVER_WIRED=y -- --# Driver interface for MACsec capable Qualcomm Atheros drivers --#CONFIG_DRIVER_MACSEC_QCA=y -- --# Driver interface for Linux MACsec drivers --#CONFIG_DRIVER_MACSEC_LINUX=y -- --# Driver interface for the Broadcom RoboSwitch family --#CONFIG_DRIVER_ROBOSWITCH=y -- --# Driver interface for no driver (e.g., WPS ER only) --#CONFIG_DRIVER_NONE=y -- --# Solaris libraries --#LIBS += -lsocket -ldlpi -lnsl --#LIBS_c += -lsocket -- --# Enable IEEE 802.1X Supplicant (automatically included if any EAP method or --# MACsec is included) --CONFIG_IEEE8021X_EAPOL=y -- --# EAP-MD5 --CONFIG_EAP_MD5=y -- --# EAP-MSCHAPv2 --CONFIG_EAP_MSCHAPV2=y -- --# EAP-TLS --CONFIG_EAP_TLS=y -- --# EAL-PEAP --CONFIG_EAP_PEAP=y -- --# EAP-TTLS --CONFIG_EAP_TTLS=y -- --# EAP-FAST --CONFIG_EAP_FAST=y -- --# EAP-TEAP --# Note: The current EAP-TEAP implementation is experimental and should not be --# enabled for production use. The IETF RFC 7170 that defines EAP-TEAP has number --# of conflicting statements and missing details and the implementation has --# vendor specific workarounds for those and as such, may not interoperate with --# any other implementation. This should not be used for anything else than --# experimentation and interoperability testing until those issues has been --# resolved. --#CONFIG_EAP_TEAP=y -- --# EAP-GTC --CONFIG_EAP_GTC=y -- --# EAP-OTP --CONFIG_EAP_OTP=y -- --# EAP-SIM (enable CONFIG_PCSC, if EAP-SIM is used) --#CONFIG_EAP_SIM=y -- --# Enable SIM simulator (Milenage) for EAP-SIM --#CONFIG_SIM_SIMULATOR=y -- --# EAP-PSK (experimental; this is _not_ needed for WPA-PSK) --#CONFIG_EAP_PSK=y -- --# EAP-pwd (secure authentication using only a password) --#CONFIG_EAP_PWD=y -- --# EAP-PAX --#CONFIG_EAP_PAX=y -- --# LEAP --CONFIG_EAP_LEAP=y -- --# EAP-AKA (enable CONFIG_PCSC, if EAP-AKA is used) --#CONFIG_EAP_AKA=y -- --# EAP-AKA' (enable CONFIG_PCSC, if EAP-AKA' is used). --# This requires CONFIG_EAP_AKA to be enabled, too. --#CONFIG_EAP_AKA_PRIME=y -- --# Enable USIM simulator (Milenage) for EAP-AKA --#CONFIG_USIM_SIMULATOR=y -- --# EAP-SAKE --#CONFIG_EAP_SAKE=y -- --# EAP-GPSK --#CONFIG_EAP_GPSK=y --# Include support for optional SHA256 cipher suite in EAP-GPSK --#CONFIG_EAP_GPSK_SHA256=y -- --# EAP-TNC and related Trusted Network Connect support (experimental) --#CONFIG_EAP_TNC=y -- --# Wi-Fi Protected Setup (WPS) --CONFIG_WPS=y --# Enable WPS external registrar functionality --#CONFIG_WPS_ER=y --# Disable credentials for an open network by default when acting as a WPS --# registrar. --#CONFIG_WPS_REG_DISABLE_OPEN=y --# Enable WPS support with NFC config method --#CONFIG_WPS_NFC=y -- --# EAP-IKEv2 --#CONFIG_EAP_IKEV2=y -- --# EAP-EKE --#CONFIG_EAP_EKE=y -- --# MACsec --#CONFIG_MACSEC=y -- --# PKCS#12 (PFX) support (used to read private key and certificate file from --# a file that usually has extension .p12 or .pfx) --CONFIG_PKCS12=y -- --# Smartcard support (i.e., private key on a smartcard), e.g., with openssl --# engine. --CONFIG_SMARTCARD=y -- --# PC/SC interface for smartcards (USIM, GSM SIM) --# Enable this if EAP-SIM or EAP-AKA is included --#CONFIG_PCSC=y -- --# Support HT overrides (disable HT/HT40, mask MCS rates, etc.) --CONFIG_HT_OVERRIDES=y -- --# Support VHT overrides (disable VHT, mask MCS rates, etc.) --CONFIG_VHT_OVERRIDES=y -- --# Development testing --#CONFIG_EAPOL_TEST=y -- --# Select control interface backend for external programs, e.g, wpa_cli: --# unix = UNIX domain sockets (default for Linux/*BSD) --# udp = UDP sockets using localhost (127.0.0.1) --# udp6 = UDP IPv6 sockets using localhost (::1) --# named_pipe = Windows Named Pipe (default for Windows) --# udp-remote = UDP sockets with remote access (only for tests systems/purpose) --# udp6-remote = UDP IPv6 sockets with remote access (only for tests purpose) --# y = use default (backwards compatibility) --# If this option is commented out, control interface is not included in the --# build. --CONFIG_CTRL_IFACE=y -- --# Include support for GNU Readline and History Libraries in wpa_cli. --# When building a wpa_cli binary for distribution, please note that these --# libraries are licensed under GPL and as such, BSD license may not apply for --# the resulting binary. --#CONFIG_READLINE=y -- --# Include internal line edit mode in wpa_cli. This can be used as a replacement --# for GNU Readline to provide limited command line editing and history support. --#CONFIG_WPA_CLI_EDIT=y -- --# Remove debugging code that is printing out debug message to stdout. --# This can be used to reduce the size of the wpa_supplicant considerably --# if debugging code is not needed. The size reduction can be around 35% --# (e.g., 90 kB). --#CONFIG_NO_STDOUT_DEBUG=y -- --# Remove WPA support, e.g., for wired-only IEEE 802.1X supplicant, to save --# 35-50 kB in code size. --#CONFIG_NO_WPA=y -- --# Remove IEEE 802.11i/WPA-Personal ASCII passphrase support --# This option can be used to reduce code size by removing support for --# converting ASCII passphrases into PSK. If this functionality is removed, the --# PSK can only be configured as the 64-octet hexstring (e.g., from --# wpa_passphrase). This saves about 0.5 kB in code size. --#CONFIG_NO_WPA_PASSPHRASE=y -- --# Simultaneous Authentication of Equals (SAE), WPA3-Personal --#CONFIG_SAE=y -- --# Disable scan result processing (ap_mode=1) to save code size by about 1 kB. --# This can be used if ap_scan=1 mode is never enabled. --#CONFIG_NO_SCAN_PROCESSING=y -- --# Select configuration backend: --# file = text file (e.g., wpa_supplicant.conf; note: the configuration file --# path is given on command line, not here; this option is just used to --# select the backend that allows configuration files to be used) --# winreg = Windows registry (see win_example.reg for an example) --CONFIG_BACKEND=file -- --# Remove configuration write functionality (i.e., to allow the configuration --# file to be updated based on runtime configuration changes). The runtime --# configuration can still be changed, the changes are just not going to be --# persistent over restarts. This option can be used to reduce code size by --# about 3.5 kB. --#CONFIG_NO_CONFIG_WRITE=y -- --# Remove support for configuration blobs to reduce code size by about 1.5 kB. --#CONFIG_NO_CONFIG_BLOBS=y -- --# Select program entry point implementation: --# main = UNIX/POSIX like main() function (default) --# main_winsvc = Windows service (read parameters from registry) --# main_none = Very basic example (development use only) --#CONFIG_MAIN=main -- --# Select wrapper for operating system and C library specific functions --# unix = UNIX/POSIX like systems (default) --# win32 = Windows systems --# none = Empty template --#CONFIG_OS=unix -- --# Select event loop implementation --# eloop = select() loop (default) --# eloop_win = Windows events and WaitForMultipleObject() loop --#CONFIG_ELOOP=eloop -- --# Should we use poll instead of select? Select is used by default. --#CONFIG_ELOOP_POLL=y -- --# Should we use epoll instead of select? Select is used by default. --CONFIG_ELOOP_EPOLL=y -- --# Should we use kqueue instead of select? Select is used by default. --#CONFIG_ELOOP_KQUEUE=y -- --# Select layer 2 packet implementation --# linux = Linux packet socket (default) --# pcap = libpcap/libdnet/WinPcap --# freebsd = FreeBSD libpcap --# winpcap = WinPcap with receive thread --# ndis = Windows NDISUIO (note: requires CONFIG_USE_NDISUIO=y) --# none = Empty template --#CONFIG_L2_PACKET=linux -- --# Disable Linux packet socket workaround applicable for station interface --# in a bridge for EAPOL frames. This should be uncommented only if the kernel --# is known to not have the regression issue in packet socket behavior with --# bridge interfaces (commit 'bridge: respect RFC2863 operational state')'). --CONFIG_NO_LINUX_PACKET_SOCKET_WAR=y -- --# IEEE 802.11w (management frame protection), also known as PMF --# Driver support is also needed for IEEE 802.11w. --#CONFIG_IEEE80211W=y -- --# Support Operating Channel Validation --CONFIG_OCV=y -- --# Select TLS implementation --# openssl = OpenSSL (default) --# gnutls = GnuTLS --# internal = Internal TLSv1 implementation (experimental) --# linux = Linux kernel AF_ALG and internal TLSv1 implementation (experimental) --# none = Empty template --CONFIG_TLS=internal -- --# TLS-based EAP methods require at least TLS v1.0. Newer version of TLS (v1.1) --# can be enabled to get a stronger construction of messages when block ciphers --# are used. It should be noted that some existing TLS v1.0 -based --# implementation may not be compatible with TLS v1.1 message (ClientHello is --# sent prior to negotiating which version will be used) --#CONFIG_TLSV11=y -- --# TLS-based EAP methods require at least TLS v1.0. Newer version of TLS (v1.2) --# can be enabled to enable use of stronger crypto algorithms. It should be --# noted that some existing TLS v1.0 -based implementation may not be compatible --# with TLS v1.2 message (ClientHello is sent prior to negotiating which version --# will be used) --#CONFIG_TLSV12=y -- --# Select which ciphers to use by default with OpenSSL if the user does not --# specify them. --#CONFIG_TLS_DEFAULT_CIPHERS="DEFAULT:!EXP:!LOW" -- --# If CONFIG_TLS=internal is used, additional library and include paths are --# needed for LibTomMath. Alternatively, an integrated, minimal version of --# LibTomMath can be used. See beginning of libtommath.c for details on benefits --# and drawbacks of this option. --CONFIG_INTERNAL_LIBTOMMATH=y --#ifndef CONFIG_INTERNAL_LIBTOMMATH --#LTM_PATH=/usr/src/libtommath-0.39 --#CFLAGS += -I$(LTM_PATH) --#LIBS += -L$(LTM_PATH) --#LIBS_p += -L$(LTM_PATH) --#endif --# At the cost of about 4 kB of additional binary size, the internal LibTomMath --# can be configured to include faster routines for exptmod, sqr, and div to --# speed up DH and RSA calculation considerably --CONFIG_INTERNAL_LIBTOMMATH_FAST=y -- --# Include NDIS event processing through WMI into wpa_supplicant/wpasvc. --# This is only for Windows builds and requires WMI-related header files and --# WbemUuid.Lib from Platform SDK even when building with MinGW. --#CONFIG_NDIS_EVENTS_INTEGRATED=y --#PLATFORMSDKLIB="/opt/Program Files/Microsoft Platform SDK/Lib" -- --# Add support for new DBus control interface --# (fi.w1.hostap.wpa_supplicant1) --#CONFIG_CTRL_IFACE_DBUS_NEW=y -- --# Add introspection support for new DBus control interface --#CONFIG_CTRL_IFACE_DBUS_INTRO=y -- --# Add support for loading EAP methods dynamically as shared libraries. --# When this option is enabled, each EAP method can be either included --# statically (CONFIG_EAP_=y) or dynamically (CONFIG_EAP_=dyn). --# Dynamic EAP methods are build as shared objects (eap_*.so) and they need to --# be loaded in the beginning of the wpa_supplicant configuration file --# (see load_dynamic_eap parameter in the example file) before being used in --# the network blocks. --# --# Note that some shared parts of EAP methods are included in the main program --# and in order to be able to use dynamic EAP methods using these parts, the --# main program must have been build with the EAP method enabled (=y or =dyn). --# This means that EAP-TLS/PEAP/TTLS/FAST cannot be added as dynamic libraries --# unless at least one of them was included in the main build to force inclusion --# of the shared code. Similarly, at least one of EAP-SIM/AKA must be included --# in the main build to be able to load these methods dynamically. --# --# Please also note that using dynamic libraries will increase the total binary --# size. Thus, it may not be the best option for targets that have limited --# amount of memory/flash. --#CONFIG_DYNAMIC_EAP_METHODS=y -- --# IEEE Std 802.11r-2008 (Fast BSS Transition) for station mode --CONFIG_IEEE80211R=y -- --# Add support for writing debug log to a file (/tmp/wpa_supplicant-log-#.txt) --#CONFIG_DEBUG_FILE=y -- --# Send debug messages to syslog instead of stdout --CONFIG_DEBUG_SYSLOG=y --# Set syslog facility for debug messages --CONFIG_DEBUG_SYSLOG_FACILITY=LOG_DAEMON -- --# Add support for sending all debug messages (regardless of debug verbosity) --# to the Linux kernel tracing facility. This helps debug the entire stack by --# making it easy to record everything happening from the driver up into the --# same file, e.g., using trace-cmd. --#CONFIG_DEBUG_LINUX_TRACING=y -- --# Add support for writing debug log to Android logcat instead of standard --# output --#CONFIG_ANDROID_LOG=y -- --# Enable privilege separation (see README 'Privilege separation' for details) --#CONFIG_PRIVSEP=y -- --# Enable mitigation against certain attacks against TKIP by delaying Michael --# MIC error reports by a random amount of time between 0 and 60 seconds --#CONFIG_DELAYED_MIC_ERROR_REPORT=y -- --# Enable tracing code for developer debugging --# This tracks use of memory allocations and other registrations and reports --# incorrect use with a backtrace of call (or allocation) location. --#CONFIG_WPA_TRACE=y --# For BSD, uncomment these. --#LIBS += -lexecinfo --#LIBS_p += -lexecinfo --#LIBS_c += -lexecinfo -- --# Use libbfd to get more details for developer debugging --# This enables use of libbfd to get more detailed symbols for the backtraces --# generated by CONFIG_WPA_TRACE=y. --#CONFIG_WPA_TRACE_BFD=y --# For BSD, uncomment these. --#LIBS += -lbfd -liberty -lz --#LIBS_p += -lbfd -liberty -lz --#LIBS_c += -lbfd -liberty -lz -- --# wpa_supplicant depends on strong random number generation being available --# from the operating system. os_get_random() function is used to fetch random --# data when needed, e.g., for key generation. On Linux and BSD systems, this --# works by reading /dev/urandom. It should be noted that the OS entropy pool --# needs to be properly initialized before wpa_supplicant is started. This is --# important especially on embedded devices that do not have a hardware random --# number generator and may by default start up with minimal entropy available --# for random number generation. --# --# As a safety net, wpa_supplicant is by default trying to internally collect --# additional entropy for generating random data to mix in with the data fetched --# from the OS. This by itself is not considered to be very strong, but it may --# help in cases where the system pool is not initialized properly. However, it --# is very strongly recommended that the system pool is initialized with enough --# entropy either by using hardware assisted random number generator or by --# storing state over device reboots. --# --# wpa_supplicant can be configured to maintain its own entropy store over --# restarts to enhance random number generation. This is not perfect, but it is --# much more secure than using the same sequence of random numbers after every --# reboot. This can be enabled with -e command line option. The --# specified file needs to be readable and writable by wpa_supplicant. --# --# If the os_get_random() is known to provide strong random data (e.g., on --# Linux/BSD, the board in question is known to have reliable source of random --# data from /dev/urandom), the internal wpa_supplicant random pool can be --# disabled. This will save some in binary size and CPU use. However, this --# should only be considered for builds that are known to be used on devices --# that meet the requirements described above. --CONFIG_NO_RANDOM_POOL=y -- --# Should we attempt to use the getrandom(2) call that provides more reliable --# yet secure randomness source than /dev/random on Linux 3.17 and newer. --# Requires glibc 2.25 to build, falls back to /dev/random if unavailable. --CONFIG_GETRANDOM=y -- --# IEEE 802.11n (High Throughput) support (mainly for AP mode) --#CONFIG_IEEE80211N=y -- --# IEEE 802.11ac (Very High Throughput) support (mainly for AP mode) --# (depends on CONFIG_IEEE80211N) --#CONFIG_IEEE80211AC=y -- --# Wireless Network Management (IEEE Std 802.11v-2011) --# Note: This is experimental and not complete implementation. --CONFIG_WNM=y -- --# Interworking (IEEE 802.11u) --# This can be used to enable functionality to improve interworking with --# external networks (GAS/ANQP to learn more about the networks and network --# selection based on available credentials). --CONFIG_INTERWORKING=y -- --# Hotspot 2.0 --CONFIG_HS20=y -- --# Enable interface matching in wpa_supplicant --#CONFIG_MATCH_IFACE=y -- --# Disable roaming in wpa_supplicant --#CONFIG_NO_ROAMING=y -- --# AP mode operations with wpa_supplicant --# This can be used for controlling AP mode operations with wpa_supplicant. It --# should be noted that this is mainly aimed at simple cases like --# WPA2-Personal while more complex configurations like WPA2-Enterprise with an --# external RADIUS server can be supported with hostapd. --#CONFIG_AP=y -- --# P2P (Wi-Fi Direct) --# This can be used to enable P2P support in wpa_supplicant. See README-P2P for --# more information on P2P operations. --#CONFIG_P2P=y -- --# Enable TDLS support --#CONFIG_TDLS=y -- --# Wi-Fi Display --# This can be used to enable Wi-Fi Display extensions for P2P using an external --# program to control the additional information exchanges in the messages. --#CONFIG_WIFI_DISPLAY=y -- --# Autoscan --# This can be used to enable automatic scan support in wpa_supplicant. --# See wpa_supplicant.conf for more information on autoscan usage. --# --# Enabling directly a module will enable autoscan support. --# For exponential module: --#CONFIG_AUTOSCAN_EXPONENTIAL=y --# For periodic module: --#CONFIG_AUTOSCAN_PERIODIC=y -- --# Password (and passphrase, etc.) backend for external storage --# These optional mechanisms can be used to add support for storing passwords --# and other secrets in external (to wpa_supplicant) location. This allows, for --# example, operating system specific key storage to be used --# --# External password backend for testing purposes (developer use) --#CONFIG_EXT_PASSWORD_TEST=y -- --# Enable Fast Session Transfer (FST) --#CONFIG_FST=y -- --# Enable CLI commands for FST testing --#CONFIG_FST_TEST=y -- --# OS X builds. This is only for building eapol_test. --#CONFIG_OSX=y -- --# Automatic Channel Selection --# This will allow wpa_supplicant to pick the channel automatically when channel --# is set to "0". --# --# TODO: Extend parser to be able to parse "channel=acs_survey" as an alternative --# to "channel=0". This would enable us to eventually add other ACS algorithms in --# similar way. --# --# Automatic selection is currently only done through initialization, later on --# we hope to do background checks to keep us moving to more ideal channels as --# time goes by. ACS is currently only supported through the nl80211 driver and --# your driver must have survey dump capability that is filled by the driver --# during scanning. --# --# TODO: In analogy to hostapd be able to customize the ACS survey algorithm with --# a newly to create wpa_supplicant.conf variable acs_num_scans. --# --# Supported ACS drivers: --# * ath9k --# * ath5k --# * ath10k --# --# For more details refer to: --# http://wireless.kernel.org/en/users/Documentation/acs --#CONFIG_ACS=y -- --# Support Multi Band Operation --#CONFIG_MBO=y -- --# Fast Initial Link Setup (FILS) (IEEE 802.11ai) --CONFIG_FILS=y --# FILS shared key authentication with PFS --#CONFIG_FILS_SK_PFS=y -- --# Support RSN on IBSS networks --# This is needed to be able to use mode=1 network profile with proto=RSN and --# key_mgmt=WPA-PSK (i.e., full key management instead of WPA-None). --CONFIG_IBSS_RSN=y -- --# External PMKSA cache control --# This can be used to enable control interface commands that allow the current --# PMKSA cache entries to be fetched and new entries to be added. --#CONFIG_PMKSA_CACHE_EXTERNAL=y -- --# Mesh Networking (IEEE 802.11s) --#CONFIG_MESH=y -- --# Background scanning modules --# These can be used to request wpa_supplicant to perform background scanning --# operations for roaming within an ESS (same SSID). See the bgscan parameter in --# the wpa_supplicant.conf file for more details. --# Periodic background scans based on signal strength --#CONFIG_BGSCAN_SIMPLE=y --# Learn channels used by the network and try to avoid bgscans on other --# channels (experimental) --#CONFIG_BGSCAN_LEARN=y -- --# Opportunistic Wireless Encryption (OWE) --# Experimental implementation of draft-harkins-owe-07.txt --#CONFIG_OWE=y -- --# Device Provisioning Protocol (DPP) --# This requires CONFIG_IEEE80211W=y to be enabled, too. (see --# wpa_supplicant/README-DPP for details) --#CONFIG_DPP=y -- --# uBus IPC/RPC System --# Services can connect to the bus and provide methods --# that can be called by other services or clients. --CONFIG_UBUS=y -- --# OpenWrt patch 380-disable-ctrl-iface-mib.patch --# leads to the MIB only being compiled in if --# CONFIG_CTRL_IFACE_MIB is enabled. --CONFIG_CTRL_IFACE_MIB=y -diff --git a/package/network/services/hostapd/files/wpa_supplicant-mini.config b/package/network/services/hostapd/files/wpa_supplicant-mini.config -deleted file mode 100644 -index 9eb1111e52..0000000000 ---- a/package/network/services/hostapd/files/wpa_supplicant-mini.config -+++ /dev/null -@@ -1,625 +0,0 @@ --# Example wpa_supplicant build time configuration --# --# This file lists the configuration options that are used when building the --# wpa_supplicant binary. All lines starting with # are ignored. Configuration --# option lines must be commented out complete, if they are not to be included, --# i.e., just setting VARIABLE=n is not disabling that variable. --# --# This file is included in Makefile, so variables like CFLAGS and LIBS can also --# be modified from here. In most cases, these lines should use += in order not --# to override previous values of the variables. -- -- --# Uncomment following two lines and fix the paths if you have installed OpenSSL --# or GnuTLS in non-default location --#CFLAGS += -I/usr/local/openssl/include --#LIBS += -L/usr/local/openssl/lib -- --# Some Red Hat versions seem to include kerberos header files from OpenSSL, but --# the kerberos files are not in the default include path. Following line can be --# used to fix build issues on such systems (krb5.h not found). --#CFLAGS += -I/usr/include/kerberos -- --# 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 --# replacement for WEXT and its use allows wpa_supplicant to properly control --# the driver to improve existing functionality like roaming and to support new --# functionality. --CONFIG_DRIVER_WEXT=y -- --# Driver interface for Linux drivers using the nl80211 kernel interface --CONFIG_DRIVER_NL80211=y -- --# QCA vendor extensions to nl80211 --#CONFIG_DRIVER_NL80211_QCA=y -- --# driver_nl80211.c requires libnl. If you are compiling it yourself --# you may need to point hostapd to your version of libnl. --# --#CFLAGS += -I$ --#LIBS += -L$ -- --# Use libnl v2.0 (or 3.0) libraries. --#CONFIG_LIBNL20=y -- --# Use libnl 3.2 libraries (if this is selected, CONFIG_LIBNL20 is ignored) --#CONFIG_LIBNL32=y -- -- --# Driver interface for FreeBSD net80211 layer (e.g., Atheros driver) --#CONFIG_DRIVER_BSD=y --#CFLAGS += -I/usr/local/include --#LIBS += -L/usr/local/lib --#LIBS_p += -L/usr/local/lib --#LIBS_c += -L/usr/local/lib -- --# Driver interface for Windows NDIS --#CONFIG_DRIVER_NDIS=y --#CFLAGS += -I/usr/include/w32api/ddk --#LIBS += -L/usr/local/lib --# For native build using mingw --#CONFIG_NATIVE_WINDOWS=y --# Additional directories for cross-compilation on Linux host for mingw target --#CFLAGS += -I/opt/mingw/mingw32/include/ddk --#LIBS += -L/opt/mingw/mingw32/lib --#CC=mingw32-gcc --# By default, driver_ndis uses WinPcap for low-level operations. This can be --# replaced with the following option which replaces WinPcap calls with NDISUIO. --# However, this requires that WZC is disabled (net stop wzcsvc) before starting --# wpa_supplicant. --# CONFIG_USE_NDISUIO=y -- --# Driver interface for wired Ethernet drivers --CONFIG_DRIVER_WIRED=y -- --# Driver interface for MACsec capable Qualcomm Atheros drivers --#CONFIG_DRIVER_MACSEC_QCA=y -- --# Driver interface for Linux MACsec drivers --#CONFIG_DRIVER_MACSEC_LINUX=y -- --# Driver interface for the Broadcom RoboSwitch family --#CONFIG_DRIVER_ROBOSWITCH=y -- --# Driver interface for no driver (e.g., WPS ER only) --#CONFIG_DRIVER_NONE=y -- --# Solaris libraries --#LIBS += -lsocket -ldlpi -lnsl --#LIBS_c += -lsocket -- --# Enable IEEE 802.1X Supplicant (automatically included if any EAP method or --# MACsec is included) --#CONFIG_IEEE8021X_EAPOL=y -- --# EAP-MD5 --#CONFIG_EAP_MD5=y -- --# EAP-MSCHAPv2 --#CONFIG_EAP_MSCHAPV2=y -- --# EAP-TLS --#CONFIG_EAP_TLS=y -- --# EAL-PEAP --#CONFIG_EAP_PEAP=y -- --# EAP-TTLS --#CONFIG_EAP_TTLS=y -- --# EAP-FAST --#CONFIG_EAP_FAST=y -- --# EAP-TEAP --# Note: The current EAP-TEAP implementation is experimental and should not be --# enabled for production use. The IETF RFC 7170 that defines EAP-TEAP has number --# of conflicting statements and missing details and the implementation has --# vendor specific workarounds for those and as such, may not interoperate with --# any other implementation. This should not be used for anything else than --# experimentation and interoperability testing until those issues has been --# resolved. --#CONFIG_EAP_TEAP=y -- --# EAP-GTC --#CONFIG_EAP_GTC=y -- --# EAP-OTP --#CONFIG_EAP_OTP=y -- --# EAP-SIM (enable CONFIG_PCSC, if EAP-SIM is used) --#CONFIG_EAP_SIM=y -- --# Enable SIM simulator (Milenage) for EAP-SIM --#CONFIG_SIM_SIMULATOR=y -- --# EAP-PSK (experimental; this is _not_ needed for WPA-PSK) --#CONFIG_EAP_PSK=y -- --# EAP-pwd (secure authentication using only a password) --#CONFIG_EAP_PWD=y -- --# EAP-PAX --#CONFIG_EAP_PAX=y -- --# LEAP --#CONFIG_EAP_LEAP=y -- --# EAP-AKA (enable CONFIG_PCSC, if EAP-AKA is used) --#CONFIG_EAP_AKA=y -- --# EAP-AKA' (enable CONFIG_PCSC, if EAP-AKA' is used). --# This requires CONFIG_EAP_AKA to be enabled, too. --#CONFIG_EAP_AKA_PRIME=y -- --# Enable USIM simulator (Milenage) for EAP-AKA --#CONFIG_USIM_SIMULATOR=y -- --# EAP-SAKE --#CONFIG_EAP_SAKE=y -- --# EAP-GPSK --#CONFIG_EAP_GPSK=y --# Include support for optional SHA256 cipher suite in EAP-GPSK --#CONFIG_EAP_GPSK_SHA256=y -- --# EAP-TNC and related Trusted Network Connect support (experimental) --#CONFIG_EAP_TNC=y -- --# Wi-Fi Protected Setup (WPS) --#CONFIG_WPS=y --# Enable WPS external registrar functionality --#CONFIG_WPS_ER=y --# Disable credentials for an open network by default when acting as a WPS --# registrar. --#CONFIG_WPS_REG_DISABLE_OPEN=y --# Enable WPS support with NFC config method --#CONFIG_WPS_NFC=y -- --# EAP-IKEv2 --#CONFIG_EAP_IKEV2=y -- --# EAP-EKE --#CONFIG_EAP_EKE=y -- --# MACsec --#CONFIG_MACSEC=y -- --# PKCS#12 (PFX) support (used to read private key and certificate file from --# a file that usually has extension .p12 or .pfx) --#CONFIG_PKCS12=y -- --# Smartcard support (i.e., private key on a smartcard), e.g., with openssl --# engine. --#CONFIG_SMARTCARD=y -- --# PC/SC interface for smartcards (USIM, GSM SIM) --# Enable this if EAP-SIM or EAP-AKA is included --#CONFIG_PCSC=y -- --# Support HT overrides (disable HT/HT40, mask MCS rates, etc.) --CONFIG_HT_OVERRIDES=y -- --# Support VHT overrides (disable VHT, mask MCS rates, etc.) --CONFIG_VHT_OVERRIDES=y -- --# Development testing --#CONFIG_EAPOL_TEST=y -- --# Select control interface backend for external programs, e.g, wpa_cli: --# unix = UNIX domain sockets (default for Linux/*BSD) --# udp = UDP sockets using localhost (127.0.0.1) --# udp6 = UDP IPv6 sockets using localhost (::1) --# named_pipe = Windows Named Pipe (default for Windows) --# udp-remote = UDP sockets with remote access (only for tests systems/purpose) --# udp6-remote = UDP IPv6 sockets with remote access (only for tests purpose) --# y = use default (backwards compatibility) --# If this option is commented out, control interface is not included in the --# build. --CONFIG_CTRL_IFACE=y -- --# Include support for GNU Readline and History Libraries in wpa_cli. --# When building a wpa_cli binary for distribution, please note that these --# libraries are licensed under GPL and as such, BSD license may not apply for --# the resulting binary. --#CONFIG_READLINE=y -- --# Include internal line edit mode in wpa_cli. This can be used as a replacement --# for GNU Readline to provide limited command line editing and history support. --#CONFIG_WPA_CLI_EDIT=y -- --# Remove debugging code that is printing out debug message to stdout. --# This can be used to reduce the size of the wpa_supplicant considerably --# if debugging code is not needed. The size reduction can be around 35% --# (e.g., 90 kB). --#CONFIG_NO_STDOUT_DEBUG=y -- --# Remove WPA support, e.g., for wired-only IEEE 802.1X supplicant, to save --# 35-50 kB in code size. --#CONFIG_NO_WPA=y -- --# Remove IEEE 802.11i/WPA-Personal ASCII passphrase support --# This option can be used to reduce code size by removing support for --# converting ASCII passphrases into PSK. If this functionality is removed, the --# PSK can only be configured as the 64-octet hexstring (e.g., from --# wpa_passphrase). This saves about 0.5 kB in code size. --#CONFIG_NO_WPA_PASSPHRASE=y -- --# Simultaneous Authentication of Equals (SAE), WPA3-Personal --#CONFIG_SAE=y -- --# Disable scan result processing (ap_mode=1) to save code size by about 1 kB. --# This can be used if ap_scan=1 mode is never enabled. --#CONFIG_NO_SCAN_PROCESSING=y -- --# Select configuration backend: --# file = text file (e.g., wpa_supplicant.conf; note: the configuration file --# path is given on command line, not here; this option is just used to --# select the backend that allows configuration files to be used) --# winreg = Windows registry (see win_example.reg for an example) --CONFIG_BACKEND=file -- --# Remove configuration write functionality (i.e., to allow the configuration --# file to be updated based on runtime configuration changes). The runtime --# configuration can still be changed, the changes are just not going to be --# persistent over restarts. This option can be used to reduce code size by --# about 3.5 kB. --CONFIG_NO_CONFIG_WRITE=y -- --# Remove support for configuration blobs to reduce code size by about 1.5 kB. --#CONFIG_NO_CONFIG_BLOBS=y -- --# Select program entry point implementation: --# main = UNIX/POSIX like main() function (default) --# main_winsvc = Windows service (read parameters from registry) --# main_none = Very basic example (development use only) --#CONFIG_MAIN=main -- --# Select wrapper for operating system and C library specific functions --# unix = UNIX/POSIX like systems (default) --# win32 = Windows systems --# none = Empty template --#CONFIG_OS=unix -- --# Select event loop implementation --# eloop = select() loop (default) --# eloop_win = Windows events and WaitForMultipleObject() loop --#CONFIG_ELOOP=eloop -- --# Should we use poll instead of select? Select is used by default. --#CONFIG_ELOOP_POLL=y -- --# Should we use epoll instead of select? Select is used by default. --CONFIG_ELOOP_EPOLL=y -- --# Should we use kqueue instead of select? Select is used by default. --#CONFIG_ELOOP_KQUEUE=y -- --# Select layer 2 packet implementation --# linux = Linux packet socket (default) --# pcap = libpcap/libdnet/WinPcap --# freebsd = FreeBSD libpcap --# winpcap = WinPcap with receive thread --# ndis = Windows NDISUIO (note: requires CONFIG_USE_NDISUIO=y) --# none = Empty template --#CONFIG_L2_PACKET=linux -- --# Disable Linux packet socket workaround applicable for station interface --# in a bridge for EAPOL frames. This should be uncommented only if the kernel --# is known to not have the regression issue in packet socket behavior with --# bridge interfaces (commit 'bridge: respect RFC2863 operational state')'). --CONFIG_NO_LINUX_PACKET_SOCKET_WAR=y -- --# IEEE 802.11w (management frame protection), also known as PMF --# Driver support is also needed for IEEE 802.11w. --#CONFIG_IEEE80211W=y -- --# Support Operating Channel Validation --#CONFIG_OCV=y -- --# Select TLS implementation --# openssl = OpenSSL (default) --# gnutls = GnuTLS --# internal = Internal TLSv1 implementation (experimental) --# linux = Linux kernel AF_ALG and internal TLSv1 implementation (experimental) --# none = Empty template --CONFIG_TLS=internal -- --# TLS-based EAP methods require at least TLS v1.0. Newer version of TLS (v1.1) --# can be enabled to get a stronger construction of messages when block ciphers --# are used. It should be noted that some existing TLS v1.0 -based --# implementation may not be compatible with TLS v1.1 message (ClientHello is --# sent prior to negotiating which version will be used) --#CONFIG_TLSV11=y -- --# TLS-based EAP methods require at least TLS v1.0. Newer version of TLS (v1.2) --# can be enabled to enable use of stronger crypto algorithms. It should be --# noted that some existing TLS v1.0 -based implementation may not be compatible --# with TLS v1.2 message (ClientHello is sent prior to negotiating which version --# will be used) --#CONFIG_TLSV12=y -- --# Select which ciphers to use by default with OpenSSL if the user does not --# specify them. --#CONFIG_TLS_DEFAULT_CIPHERS="DEFAULT:!EXP:!LOW" -- --# If CONFIG_TLS=internal is used, additional library and include paths are --# needed for LibTomMath. Alternatively, an integrated, minimal version of --# LibTomMath can be used. See beginning of libtommath.c for details on benefits --# and drawbacks of this option. --#CONFIG_INTERNAL_LIBTOMMATH=y --#ifndef CONFIG_INTERNAL_LIBTOMMATH --#LTM_PATH=/usr/src/libtommath-0.39 --#CFLAGS += -I$(LTM_PATH) --#LIBS += -L$(LTM_PATH) --#LIBS_p += -L$(LTM_PATH) --#endif --# At the cost of about 4 kB of additional binary size, the internal LibTomMath --# can be configured to include faster routines for exptmod, sqr, and div to --# speed up DH and RSA calculation considerably --#CONFIG_INTERNAL_LIBTOMMATH_FAST=y -- --# Include NDIS event processing through WMI into wpa_supplicant/wpasvc. --# This is only for Windows builds and requires WMI-related header files and --# WbemUuid.Lib from Platform SDK even when building with MinGW. --#CONFIG_NDIS_EVENTS_INTEGRATED=y --#PLATFORMSDKLIB="/opt/Program Files/Microsoft Platform SDK/Lib" -- --# Add support for new DBus control interface --# (fi.w1.hostap.wpa_supplicant1) --#CONFIG_CTRL_IFACE_DBUS_NEW=y -- --# Add introspection support for new DBus control interface --#CONFIG_CTRL_IFACE_DBUS_INTRO=y -- --# Add support for loading EAP methods dynamically as shared libraries. --# When this option is enabled, each EAP method can be either included --# statically (CONFIG_EAP_=y) or dynamically (CONFIG_EAP_=dyn). --# Dynamic EAP methods are build as shared objects (eap_*.so) and they need to --# be loaded in the beginning of the wpa_supplicant configuration file --# (see load_dynamic_eap parameter in the example file) before being used in --# the network blocks. --# --# Note that some shared parts of EAP methods are included in the main program --# and in order to be able to use dynamic EAP methods using these parts, the --# main program must have been build with the EAP method enabled (=y or =dyn). --# This means that EAP-TLS/PEAP/TTLS/FAST cannot be added as dynamic libraries --# unless at least one of them was included in the main build to force inclusion --# of the shared code. Similarly, at least one of EAP-SIM/AKA must be included --# in the main build to be able to load these methods dynamically. --# --# Please also note that using dynamic libraries will increase the total binary --# size. Thus, it may not be the best option for targets that have limited --# amount of memory/flash. --#CONFIG_DYNAMIC_EAP_METHODS=y -- --# IEEE Std 802.11r-2008 (Fast BSS Transition) for station mode --#CONFIG_IEEE80211R=y -- --# Add support for writing debug log to a file (/tmp/wpa_supplicant-log-#.txt) --#CONFIG_DEBUG_FILE=y -- --# Send debug messages to syslog instead of stdout --CONFIG_DEBUG_SYSLOG=y --# Set syslog facility for debug messages --CONFIG_DEBUG_SYSLOG_FACILITY=LOG_DAEMON -- --# Add support for sending all debug messages (regardless of debug verbosity) --# to the Linux kernel tracing facility. This helps debug the entire stack by --# making it easy to record everything happening from the driver up into the --# same file, e.g., using trace-cmd. --#CONFIG_DEBUG_LINUX_TRACING=y -- --# Add support for writing debug log to Android logcat instead of standard --# output --#CONFIG_ANDROID_LOG=y -- --# Enable privilege separation (see README 'Privilege separation' for details) --#CONFIG_PRIVSEP=y -- --# Enable mitigation against certain attacks against TKIP by delaying Michael --# MIC error reports by a random amount of time between 0 and 60 seconds --#CONFIG_DELAYED_MIC_ERROR_REPORT=y -- --# Enable tracing code for developer debugging --# This tracks use of memory allocations and other registrations and reports --# incorrect use with a backtrace of call (or allocation) location. --#CONFIG_WPA_TRACE=y --# For BSD, uncomment these. --#LIBS += -lexecinfo --#LIBS_p += -lexecinfo --#LIBS_c += -lexecinfo -- --# Use libbfd to get more details for developer debugging --# This enables use of libbfd to get more detailed symbols for the backtraces --# generated by CONFIG_WPA_TRACE=y. --#CONFIG_WPA_TRACE_BFD=y --# For BSD, uncomment these. --#LIBS += -lbfd -liberty -lz --#LIBS_p += -lbfd -liberty -lz --#LIBS_c += -lbfd -liberty -lz -- --# wpa_supplicant depends on strong random number generation being available --# from the operating system. os_get_random() function is used to fetch random --# data when needed, e.g., for key generation. On Linux and BSD systems, this --# works by reading /dev/urandom. It should be noted that the OS entropy pool --# needs to be properly initialized before wpa_supplicant is started. This is --# important especially on embedded devices that do not have a hardware random --# number generator and may by default start up with minimal entropy available --# for random number generation. --# --# As a safety net, wpa_supplicant is by default trying to internally collect --# additional entropy for generating random data to mix in with the data fetched --# from the OS. This by itself is not considered to be very strong, but it may --# help in cases where the system pool is not initialized properly. However, it --# is very strongly recommended that the system pool is initialized with enough --# entropy either by using hardware assisted random number generator or by --# storing state over device reboots. --# --# wpa_supplicant can be configured to maintain its own entropy store over --# restarts to enhance random number generation. This is not perfect, but it is --# much more secure than using the same sequence of random numbers after every --# reboot. This can be enabled with -e command line option. The --# specified file needs to be readable and writable by wpa_supplicant. --# --# If the os_get_random() is known to provide strong random data (e.g., on --# Linux/BSD, the board in question is known to have reliable source of random --# data from /dev/urandom), the internal wpa_supplicant random pool can be --# disabled. This will save some in binary size and CPU use. However, this --# should only be considered for builds that are known to be used on devices --# that meet the requirements described above. --CONFIG_NO_RANDOM_POOL=y -- --# Should we attempt to use the getrandom(2) call that provides more reliable --# yet secure randomness source than /dev/random on Linux 3.17 and newer. --# Requires glibc 2.25 to build, falls back to /dev/random if unavailable. --CONFIG_GETRANDOM=y -- --# IEEE 802.11n (High Throughput) support (mainly for AP mode) --#CONFIG_IEEE80211N=y -- --# IEEE 802.11ac (Very High Throughput) support (mainly for AP mode) --# (depends on CONFIG_IEEE80211N) --#CONFIG_IEEE80211AC=y -- --# Wireless Network Management (IEEE Std 802.11v-2011) --# Note: This is experimental and not complete implementation. --#CONFIG_WNM=y -- --# Interworking (IEEE 802.11u) --# This can be used to enable functionality to improve interworking with --# external networks (GAS/ANQP to learn more about the networks and network --# selection based on available credentials). --#CONFIG_INTERWORKING=y -- --# Hotspot 2.0 --#CONFIG_HS20=y -- --# Enable interface matching in wpa_supplicant --#CONFIG_MATCH_IFACE=y -- --# Disable roaming in wpa_supplicant --#CONFIG_NO_ROAMING=y -- --# AP mode operations with wpa_supplicant --# This can be used for controlling AP mode operations with wpa_supplicant. It --# should be noted that this is mainly aimed at simple cases like --# WPA2-Personal while more complex configurations like WPA2-Enterprise with an --# external RADIUS server can be supported with hostapd. --#CONFIG_AP=y -- --# P2P (Wi-Fi Direct) --# This can be used to enable P2P support in wpa_supplicant. See README-P2P for --# more information on P2P operations. --#CONFIG_P2P=y -- --# Enable TDLS support --#CONFIG_TDLS=y -- --# Wi-Fi Display --# This can be used to enable Wi-Fi Display extensions for P2P using an external --# program to control the additional information exchanges in the messages. --#CONFIG_WIFI_DISPLAY=y -- --# Autoscan --# This can be used to enable automatic scan support in wpa_supplicant. --# See wpa_supplicant.conf for more information on autoscan usage. --# --# Enabling directly a module will enable autoscan support. --# For exponential module: --#CONFIG_AUTOSCAN_EXPONENTIAL=y --# For periodic module: --#CONFIG_AUTOSCAN_PERIODIC=y -- --# Password (and passphrase, etc.) backend for external storage --# These optional mechanisms can be used to add support for storing passwords --# and other secrets in external (to wpa_supplicant) location. This allows, for --# example, operating system specific key storage to be used --# --# External password backend for testing purposes (developer use) --#CONFIG_EXT_PASSWORD_TEST=y -- --# Enable Fast Session Transfer (FST) --#CONFIG_FST=y -- --# Enable CLI commands for FST testing --#CONFIG_FST_TEST=y -- --# OS X builds. This is only for building eapol_test. --#CONFIG_OSX=y -- --# Automatic Channel Selection --# This will allow wpa_supplicant to pick the channel automatically when channel --# is set to "0". --# --# TODO: Extend parser to be able to parse "channel=acs_survey" as an alternative --# to "channel=0". This would enable us to eventually add other ACS algorithms in --# similar way. --# --# Automatic selection is currently only done through initialization, later on --# we hope to do background checks to keep us moving to more ideal channels as --# time goes by. ACS is currently only supported through the nl80211 driver and --# your driver must have survey dump capability that is filled by the driver --# during scanning. --# --# TODO: In analogy to hostapd be able to customize the ACS survey algorithm with --# a newly to create wpa_supplicant.conf variable acs_num_scans. --# --# Supported ACS drivers: --# * ath9k --# * ath5k --# * ath10k --# --# For more details refer to: --# http://wireless.kernel.org/en/users/Documentation/acs --#CONFIG_ACS=y -- --# Support Multi Band Operation --#CONFIG_MBO=y -- --# Fast Initial Link Setup (FILS) (IEEE 802.11ai) --#CONFIG_FILS=y --# FILS shared key authentication with PFS --#CONFIG_FILS_SK_PFS=y -- --# Support RSN on IBSS networks --# This is needed to be able to use mode=1 network profile with proto=RSN and --# key_mgmt=WPA-PSK (i.e., full key management instead of WPA-None). --#CONFIG_IBSS_RSN=y -- --# External PMKSA cache control --# This can be used to enable control interface commands that allow the current --# PMKSA cache entries to be fetched and new entries to be added. --#CONFIG_PMKSA_CACHE_EXTERNAL=y -- --# Mesh Networking (IEEE 802.11s) --#CONFIG_MESH=y -- --# Background scanning modules --# These can be used to request wpa_supplicant to perform background scanning --# operations for roaming within an ESS (same SSID). See the bgscan parameter in --# the wpa_supplicant.conf file for more details. --# Periodic background scans based on signal strength --#CONFIG_BGSCAN_SIMPLE=y --# Learn channels used by the network and try to avoid bgscans on other --# channels (experimental) --#CONFIG_BGSCAN_LEARN=y -- --# Opportunistic Wireless Encryption (OWE) --# Experimental implementation of draft-harkins-owe-07.txt --#CONFIG_OWE=y -- --# Device Provisioning Protocol (DPP) --# This requires CONFIG_IEEE80211W=y to be enabled, too. (see --# wpa_supplicant/README-DPP for details) --#CONFIG_DPP=y -- --# uBus IPC/RPC System --# Services can connect to the bus and provide methods --# that can be called by other services or clients. --CONFIG_UBUS=y -- --# OpenWrt patch 380-disable-ctrl-iface-mib.patch --# leads to the MIB only being compiled in if --# CONFIG_CTRL_IFACE_MIB is enabled. --#CONFIG_CTRL_IFACE_MIB=y -diff --git a/package/network/services/hostapd/files/wpa_supplicant-p2p.config b/package/network/services/hostapd/files/wpa_supplicant-p2p.config -deleted file mode 100644 -index 0dcc88e648..0000000000 ---- a/package/network/services/hostapd/files/wpa_supplicant-p2p.config -+++ /dev/null -@@ -1,625 +0,0 @@ --# Example wpa_supplicant build time configuration --# --# This file lists the configuration options that are used when building the --# wpa_supplicant binary. All lines starting with # are ignored. Configuration --# option lines must be commented out complete, if they are not to be included, --# i.e., just setting VARIABLE=n is not disabling that variable. --# --# This file is included in Makefile, so variables like CFLAGS and LIBS can also --# be modified from here. In most cases, these lines should use += in order not --# to override previous values of the variables. -- -- --# Uncomment following two lines and fix the paths if you have installed OpenSSL --# or GnuTLS in non-default location --#CFLAGS += -I/usr/local/openssl/include --#LIBS += -L/usr/local/openssl/lib -- --# Some Red Hat versions seem to include kerberos header files from OpenSSL, but --# the kerberos files are not in the default include path. Following line can be --# used to fix build issues on such systems (krb5.h not found). --#CFLAGS += -I/usr/include/kerberos -- --# 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 --# replacement for WEXT and its use allows wpa_supplicant to properly control --# the driver to improve existing functionality like roaming and to support new --# functionality. --CONFIG_DRIVER_WEXT=y -- --# Driver interface for Linux drivers using the nl80211 kernel interface --CONFIG_DRIVER_NL80211=y -- --# QCA vendor extensions to nl80211 --#CONFIG_DRIVER_NL80211_QCA=y -- --# driver_nl80211.c requires libnl. If you are compiling it yourself --# you may need to point hostapd to your version of libnl. --# --#CFLAGS += -I$ --#LIBS += -L$ -- --# Use libnl v2.0 (or 3.0) libraries. --#CONFIG_LIBNL20=y -- --# Use libnl 3.2 libraries (if this is selected, CONFIG_LIBNL20 is ignored) --#CONFIG_LIBNL32=y -- -- --# Driver interface for FreeBSD net80211 layer (e.g., Atheros driver) --#CONFIG_DRIVER_BSD=y --#CFLAGS += -I/usr/local/include --#LIBS += -L/usr/local/lib --#LIBS_p += -L/usr/local/lib --#LIBS_c += -L/usr/local/lib -- --# Driver interface for Windows NDIS --#CONFIG_DRIVER_NDIS=y --#CFLAGS += -I/usr/include/w32api/ddk --#LIBS += -L/usr/local/lib --# For native build using mingw --#CONFIG_NATIVE_WINDOWS=y --# Additional directories for cross-compilation on Linux host for mingw target --#CFLAGS += -I/opt/mingw/mingw32/include/ddk --#LIBS += -L/opt/mingw/mingw32/lib --#CC=mingw32-gcc --# By default, driver_ndis uses WinPcap for low-level operations. This can be --# replaced with the following option which replaces WinPcap calls with NDISUIO. --# However, this requires that WZC is disabled (net stop wzcsvc) before starting --# wpa_supplicant. --# CONFIG_USE_NDISUIO=y -- --# Driver interface for wired Ethernet drivers --CONFIG_DRIVER_WIRED=y -- --# Driver interface for MACsec capable Qualcomm Atheros drivers --#CONFIG_DRIVER_MACSEC_QCA=y -- --# Driver interface for Linux MACsec drivers --#CONFIG_DRIVER_MACSEC_LINUX=y -- --# Driver interface for the Broadcom RoboSwitch family --#CONFIG_DRIVER_ROBOSWITCH=y -- --# Driver interface for no driver (e.g., WPS ER only) --#CONFIG_DRIVER_NONE=y -- --# Solaris libraries --#LIBS += -lsocket -ldlpi -lnsl --#LIBS_c += -lsocket -- --# Enable IEEE 802.1X Supplicant (automatically included if any EAP method or --# MACsec is included) --CONFIG_IEEE8021X_EAPOL=y -- --# EAP-MD5 --CONFIG_EAP_MD5=y -- --# EAP-MSCHAPv2 --CONFIG_EAP_MSCHAPV2=y -- --# EAP-TLS --CONFIG_EAP_TLS=y -- --# EAL-PEAP --CONFIG_EAP_PEAP=y -- --# EAP-TTLS --CONFIG_EAP_TTLS=y -- --# EAP-FAST --CONFIG_EAP_FAST=y -- --# EAP-TEAP --# Note: The current EAP-TEAP implementation is experimental and should not be --# enabled for production use. The IETF RFC 7170 that defines EAP-TEAP has number --# of conflicting statements and missing details and the implementation has --# vendor specific workarounds for those and as such, may not interoperate with --# any other implementation. This should not be used for anything else than --# experimentation and interoperability testing until those issues has been --# resolved. --#CONFIG_EAP_TEAP=y -- --# EAP-GTC --CONFIG_EAP_GTC=y -- --# EAP-OTP --CONFIG_EAP_OTP=y -- --# EAP-SIM (enable CONFIG_PCSC, if EAP-SIM is used) --#CONFIG_EAP_SIM=y -- --# Enable SIM simulator (Milenage) for EAP-SIM --#CONFIG_SIM_SIMULATOR=y -- --# EAP-PSK (experimental; this is _not_ needed for WPA-PSK) --#CONFIG_EAP_PSK=y -- --# EAP-pwd (secure authentication using only a password) --#CONFIG_EAP_PWD=y -- --# EAP-PAX --#CONFIG_EAP_PAX=y -- --# LEAP --CONFIG_EAP_LEAP=y -- --# EAP-AKA (enable CONFIG_PCSC, if EAP-AKA is used) --#CONFIG_EAP_AKA=y -- --# EAP-AKA' (enable CONFIG_PCSC, if EAP-AKA' is used). --# This requires CONFIG_EAP_AKA to be enabled, too. --#CONFIG_EAP_AKA_PRIME=y -- --# Enable USIM simulator (Milenage) for EAP-AKA --#CONFIG_USIM_SIMULATOR=y -- --# EAP-SAKE --#CONFIG_EAP_SAKE=y -- --# EAP-GPSK --#CONFIG_EAP_GPSK=y --# Include support for optional SHA256 cipher suite in EAP-GPSK --#CONFIG_EAP_GPSK_SHA256=y -- --# EAP-TNC and related Trusted Network Connect support (experimental) --#CONFIG_EAP_TNC=y -- --# Wi-Fi Protected Setup (WPS) --CONFIG_WPS=y --# Enable WPS external registrar functionality --#CONFIG_WPS_ER=y --# Disable credentials for an open network by default when acting as a WPS --# registrar. --#CONFIG_WPS_REG_DISABLE_OPEN=y --# Enable WPS support with NFC config method --#CONFIG_WPS_NFC=y -- --# EAP-IKEv2 --#CONFIG_EAP_IKEV2=y -- --# EAP-EKE --#CONFIG_EAP_EKE=y -- --# MACsec --#CONFIG_MACSEC=y -- --# PKCS#12 (PFX) support (used to read private key and certificate file from --# a file that usually has extension .p12 or .pfx) --CONFIG_PKCS12=y -- --# Smartcard support (i.e., private key on a smartcard), e.g., with openssl --# engine. --CONFIG_SMARTCARD=y -- --# PC/SC interface for smartcards (USIM, GSM SIM) --# Enable this if EAP-SIM or EAP-AKA is included --#CONFIG_PCSC=y -- --# Support HT overrides (disable HT/HT40, mask MCS rates, etc.) --CONFIG_HT_OVERRIDES=y -- --# Support VHT overrides (disable VHT, mask MCS rates, etc.) --CONFIG_VHT_OVERRIDES=y -- --# Development testing --#CONFIG_EAPOL_TEST=y -- --# Select control interface backend for external programs, e.g, wpa_cli: --# unix = UNIX domain sockets (default for Linux/*BSD) --# udp = UDP sockets using localhost (127.0.0.1) --# udp6 = UDP IPv6 sockets using localhost (::1) --# named_pipe = Windows Named Pipe (default for Windows) --# udp-remote = UDP sockets with remote access (only for tests systems/purpose) --# udp6-remote = UDP IPv6 sockets with remote access (only for tests purpose) --# y = use default (backwards compatibility) --# If this option is commented out, control interface is not included in the --# build. --CONFIG_CTRL_IFACE=y -- --# Include support for GNU Readline and History Libraries in wpa_cli. --# When building a wpa_cli binary for distribution, please note that these --# libraries are licensed under GPL and as such, BSD license may not apply for --# the resulting binary. --#CONFIG_READLINE=y -- --# Include internal line edit mode in wpa_cli. This can be used as a replacement --# for GNU Readline to provide limited command line editing and history support. --#CONFIG_WPA_CLI_EDIT=y -- --# Remove debugging code that is printing out debug message to stdout. --# This can be used to reduce the size of the wpa_supplicant considerably --# if debugging code is not needed. The size reduction can be around 35% --# (e.g., 90 kB). --#CONFIG_NO_STDOUT_DEBUG=y -- --# Remove WPA support, e.g., for wired-only IEEE 802.1X supplicant, to save --# 35-50 kB in code size. --#CONFIG_NO_WPA=y -- --# Remove IEEE 802.11i/WPA-Personal ASCII passphrase support --# This option can be used to reduce code size by removing support for --# converting ASCII passphrases into PSK. If this functionality is removed, the --# PSK can only be configured as the 64-octet hexstring (e.g., from --# wpa_passphrase). This saves about 0.5 kB in code size. --#CONFIG_NO_WPA_PASSPHRASE=y -- --# Simultaneous Authentication of Equals (SAE), WPA3-Personal --#CONFIG_SAE=y -- --# Disable scan result processing (ap_mode=1) to save code size by about 1 kB. --# This can be used if ap_scan=1 mode is never enabled. --#CONFIG_NO_SCAN_PROCESSING=y -- --# Select configuration backend: --# file = text file (e.g., wpa_supplicant.conf; note: the configuration file --# path is given on command line, not here; this option is just used to --# select the backend that allows configuration files to be used) --# winreg = Windows registry (see win_example.reg for an example) --CONFIG_BACKEND=file -- --# Remove configuration write functionality (i.e., to allow the configuration --# file to be updated based on runtime configuration changes). The runtime --# configuration can still be changed, the changes are just not going to be --# persistent over restarts. This option can be used to reduce code size by --# about 3.5 kB. --#CONFIG_NO_CONFIG_WRITE=y -- --# Remove support for configuration blobs to reduce code size by about 1.5 kB. --#CONFIG_NO_CONFIG_BLOBS=y -- --# Select program entry point implementation: --# main = UNIX/POSIX like main() function (default) --# main_winsvc = Windows service (read parameters from registry) --# main_none = Very basic example (development use only) --#CONFIG_MAIN=main -- --# Select wrapper for operating system and C library specific functions --# unix = UNIX/POSIX like systems (default) --# win32 = Windows systems --# none = Empty template --#CONFIG_OS=unix -- --# Select event loop implementation --# eloop = select() loop (default) --# eloop_win = Windows events and WaitForMultipleObject() loop --#CONFIG_ELOOP=eloop -- --# Should we use poll instead of select? Select is used by default. --#CONFIG_ELOOP_POLL=y -- --# Should we use epoll instead of select? Select is used by default. --CONFIG_ELOOP_EPOLL=y -- --# Should we use kqueue instead of select? Select is used by default. --#CONFIG_ELOOP_KQUEUE=y -- --# Select layer 2 packet implementation --# linux = Linux packet socket (default) --# pcap = libpcap/libdnet/WinPcap --# freebsd = FreeBSD libpcap --# winpcap = WinPcap with receive thread --# ndis = Windows NDISUIO (note: requires CONFIG_USE_NDISUIO=y) --# none = Empty template --#CONFIG_L2_PACKET=linux -- --# Disable Linux packet socket workaround applicable for station interface --# in a bridge for EAPOL frames. This should be uncommented only if the kernel --# is known to not have the regression issue in packet socket behavior with --# bridge interfaces (commit 'bridge: respect RFC2863 operational state')'). --CONFIG_NO_LINUX_PACKET_SOCKET_WAR=y -- --# IEEE 802.11w (management frame protection), also known as PMF --# Driver support is also needed for IEEE 802.11w. --CONFIG_IEEE80211W=y -- --# Support Operating Channel Validation --#CONFIG_OCV=y -- --# Select TLS implementation --# openssl = OpenSSL (default) --# gnutls = GnuTLS --# internal = Internal TLSv1 implementation (experimental) --# linux = Linux kernel AF_ALG and internal TLSv1 implementation (experimental) --# none = Empty template --CONFIG_TLS=internal -- --# TLS-based EAP methods require at least TLS v1.0. Newer version of TLS (v1.1) --# can be enabled to get a stronger construction of messages when block ciphers --# are used. It should be noted that some existing TLS v1.0 -based --# implementation may not be compatible with TLS v1.1 message (ClientHello is --# sent prior to negotiating which version will be used) --#CONFIG_TLSV11=y -- --# TLS-based EAP methods require at least TLS v1.0. Newer version of TLS (v1.2) --# can be enabled to enable use of stronger crypto algorithms. It should be --# noted that some existing TLS v1.0 -based implementation may not be compatible --# with TLS v1.2 message (ClientHello is sent prior to negotiating which version --# will be used) --#CONFIG_TLSV12=y -- --# Select which ciphers to use by default with OpenSSL if the user does not --# specify them. --#CONFIG_TLS_DEFAULT_CIPHERS="DEFAULT:!EXP:!LOW" -- --# If CONFIG_TLS=internal is used, additional library and include paths are --# needed for LibTomMath. Alternatively, an integrated, minimal version of --# LibTomMath can be used. See beginning of libtommath.c for details on benefits --# and drawbacks of this option. --CONFIG_INTERNAL_LIBTOMMATH=y --#ifndef CONFIG_INTERNAL_LIBTOMMATH --#LTM_PATH=/usr/src/libtommath-0.39 --#CFLAGS += -I$(LTM_PATH) --#LIBS += -L$(LTM_PATH) --#LIBS_p += -L$(LTM_PATH) --#endif --# At the cost of about 4 kB of additional binary size, the internal LibTomMath --# can be configured to include faster routines for exptmod, sqr, and div to --# speed up DH and RSA calculation considerably --CONFIG_INTERNAL_LIBTOMMATH_FAST=y -- --# Include NDIS event processing through WMI into wpa_supplicant/wpasvc. --# This is only for Windows builds and requires WMI-related header files and --# WbemUuid.Lib from Platform SDK even when building with MinGW. --#CONFIG_NDIS_EVENTS_INTEGRATED=y --#PLATFORMSDKLIB="/opt/Program Files/Microsoft Platform SDK/Lib" -- --# Add support for new DBus control interface --# (fi.w1.hostap.wpa_supplicant1) --#CONFIG_CTRL_IFACE_DBUS_NEW=y -- --# Add introspection support for new DBus control interface --#CONFIG_CTRL_IFACE_DBUS_INTRO=y -- --# Add support for loading EAP methods dynamically as shared libraries. --# When this option is enabled, each EAP method can be either included --# statically (CONFIG_EAP_=y) or dynamically (CONFIG_EAP_=dyn). --# Dynamic EAP methods are build as shared objects (eap_*.so) and they need to --# be loaded in the beginning of the wpa_supplicant configuration file --# (see load_dynamic_eap parameter in the example file) before being used in --# the network blocks. --# --# Note that some shared parts of EAP methods are included in the main program --# and in order to be able to use dynamic EAP methods using these parts, the --# main program must have been build with the EAP method enabled (=y or =dyn). --# This means that EAP-TLS/PEAP/TTLS/FAST cannot be added as dynamic libraries --# unless at least one of them was included in the main build to force inclusion --# of the shared code. Similarly, at least one of EAP-SIM/AKA must be included --# in the main build to be able to load these methods dynamically. --# --# Please also note that using dynamic libraries will increase the total binary --# size. Thus, it may not be the best option for targets that have limited --# amount of memory/flash. --#CONFIG_DYNAMIC_EAP_METHODS=y -- --# IEEE Std 802.11r-2008 (Fast BSS Transition) for station mode --#CONFIG_IEEE80211R=y -- --# Add support for writing debug log to a file (/tmp/wpa_supplicant-log-#.txt) --#CONFIG_DEBUG_FILE=y -- --# Send debug messages to syslog instead of stdout --CONFIG_DEBUG_SYSLOG=y --# Set syslog facility for debug messages --CONFIG_DEBUG_SYSLOG_FACILITY=LOG_DAEMON -- --# Add support for sending all debug messages (regardless of debug verbosity) --# to the Linux kernel tracing facility. This helps debug the entire stack by --# making it easy to record everything happening from the driver up into the --# same file, e.g., using trace-cmd. --#CONFIG_DEBUG_LINUX_TRACING=y -- --# Add support for writing debug log to Android logcat instead of standard --# output --#CONFIG_ANDROID_LOG=y -- --# Enable privilege separation (see README 'Privilege separation' for details) --#CONFIG_PRIVSEP=y -- --# Enable mitigation against certain attacks against TKIP by delaying Michael --# MIC error reports by a random amount of time between 0 and 60 seconds --#CONFIG_DELAYED_MIC_ERROR_REPORT=y -- --# Enable tracing code for developer debugging --# This tracks use of memory allocations and other registrations and reports --# incorrect use with a backtrace of call (or allocation) location. --#CONFIG_WPA_TRACE=y --# For BSD, uncomment these. --#LIBS += -lexecinfo --#LIBS_p += -lexecinfo --#LIBS_c += -lexecinfo -- --# Use libbfd to get more details for developer debugging --# This enables use of libbfd to get more detailed symbols for the backtraces --# generated by CONFIG_WPA_TRACE=y. --#CONFIG_WPA_TRACE_BFD=y --# For BSD, uncomment these. --#LIBS += -lbfd -liberty -lz --#LIBS_p += -lbfd -liberty -lz --#LIBS_c += -lbfd -liberty -lz -- --# wpa_supplicant depends on strong random number generation being available --# from the operating system. os_get_random() function is used to fetch random --# data when needed, e.g., for key generation. On Linux and BSD systems, this --# works by reading /dev/urandom. It should be noted that the OS entropy pool --# needs to be properly initialized before wpa_supplicant is started. This is --# important especially on embedded devices that do not have a hardware random --# number generator and may by default start up with minimal entropy available --# for random number generation. --# --# As a safety net, wpa_supplicant is by default trying to internally collect --# additional entropy for generating random data to mix in with the data fetched --# from the OS. This by itself is not considered to be very strong, but it may --# help in cases where the system pool is not initialized properly. However, it --# is very strongly recommended that the system pool is initialized with enough --# entropy either by using hardware assisted random number generator or by --# storing state over device reboots. --# --# wpa_supplicant can be configured to maintain its own entropy store over --# restarts to enhance random number generation. This is not perfect, but it is --# much more secure than using the same sequence of random numbers after every --# reboot. This can be enabled with -e command line option. The --# specified file needs to be readable and writable by wpa_supplicant. --# --# If the os_get_random() is known to provide strong random data (e.g., on --# Linux/BSD, the board in question is known to have reliable source of random --# data from /dev/urandom), the internal wpa_supplicant random pool can be --# disabled. This will save some in binary size and CPU use. However, this --# should only be considered for builds that are known to be used on devices --# that meet the requirements described above. --CONFIG_NO_RANDOM_POOL=y -- --# Should we attempt to use the getrandom(2) call that provides more reliable --# yet secure randomness source than /dev/random on Linux 3.17 and newer. --# Requires glibc 2.25 to build, falls back to /dev/random if unavailable. --CONFIG_GETRANDOM=y -- --# IEEE 802.11n (High Throughput) support (mainly for AP mode) --#CONFIG_IEEE80211N=y -- --# IEEE 802.11ac (Very High Throughput) support (mainly for AP mode) --# (depends on CONFIG_IEEE80211N) --#CONFIG_IEEE80211AC=y -- --# Wireless Network Management (IEEE Std 802.11v-2011) --# Note: This is experimental and not complete implementation. --#CONFIG_WNM=y -- --# Interworking (IEEE 802.11u) --# This can be used to enable functionality to improve interworking with --# external networks (GAS/ANQP to learn more about the networks and network --# selection based on available credentials). --#CONFIG_INTERWORKING=y -- --# Hotspot 2.0 --#CONFIG_HS20=y -- --# Enable interface matching in wpa_supplicant --#CONFIG_MATCH_IFACE=y -- --# Disable roaming in wpa_supplicant --#CONFIG_NO_ROAMING=y -- --# AP mode operations with wpa_supplicant --# This can be used for controlling AP mode operations with wpa_supplicant. It --# should be noted that this is mainly aimed at simple cases like --# WPA2-Personal while more complex configurations like WPA2-Enterprise with an --# external RADIUS server can be supported with hostapd. --CONFIG_AP=y -- --# P2P (Wi-Fi Direct) --# This can be used to enable P2P support in wpa_supplicant. See README-P2P for --# more information on P2P operations. --CONFIG_P2P=y -- --# Enable TDLS support --#CONFIG_TDLS=y -- --# Wi-Fi Display --# This can be used to enable Wi-Fi Display extensions for P2P using an external --# program to control the additional information exchanges in the messages. --#CONFIG_WIFI_DISPLAY=y -- --# Autoscan --# This can be used to enable automatic scan support in wpa_supplicant. --# See wpa_supplicant.conf for more information on autoscan usage. --# --# Enabling directly a module will enable autoscan support. --# For exponential module: --#CONFIG_AUTOSCAN_EXPONENTIAL=y --# For periodic module: --#CONFIG_AUTOSCAN_PERIODIC=y -- --# Password (and passphrase, etc.) backend for external storage --# These optional mechanisms can be used to add support for storing passwords --# and other secrets in external (to wpa_supplicant) location. This allows, for --# example, operating system specific key storage to be used --# --# External password backend for testing purposes (developer use) --#CONFIG_EXT_PASSWORD_TEST=y -- --# Enable Fast Session Transfer (FST) --#CONFIG_FST=y -- --# Enable CLI commands for FST testing --#CONFIG_FST_TEST=y -- --# OS X builds. This is only for building eapol_test. --#CONFIG_OSX=y -- --# Automatic Channel Selection --# This will allow wpa_supplicant to pick the channel automatically when channel --# is set to "0". --# --# TODO: Extend parser to be able to parse "channel=acs_survey" as an alternative --# to "channel=0". This would enable us to eventually add other ACS algorithms in --# similar way. --# --# Automatic selection is currently only done through initialization, later on --# we hope to do background checks to keep us moving to more ideal channels as --# time goes by. ACS is currently only supported through the nl80211 driver and --# your driver must have survey dump capability that is filled by the driver --# during scanning. --# --# TODO: In analogy to hostapd be able to customize the ACS survey algorithm with --# a newly to create wpa_supplicant.conf variable acs_num_scans. --# --# Supported ACS drivers: --# * ath9k --# * ath5k --# * ath10k --# --# For more details refer to: --# http://wireless.kernel.org/en/users/Documentation/acs --#CONFIG_ACS=y -- --# Support Multi Band Operation --#CONFIG_MBO=y -- --# Fast Initial Link Setup (FILS) (IEEE 802.11ai) --CONFIG_FILS=y --# FILS shared key authentication with PFS --#CONFIG_FILS_SK_PFS=y -- --# Support RSN on IBSS networks --# This is needed to be able to use mode=1 network profile with proto=RSN and --# key_mgmt=WPA-PSK (i.e., full key management instead of WPA-None). --CONFIG_IBSS_RSN=y -- --# External PMKSA cache control --# This can be used to enable control interface commands that allow the current --# PMKSA cache entries to be fetched and new entries to be added. --#CONFIG_PMKSA_CACHE_EXTERNAL=y -- --# Mesh Networking (IEEE 802.11s) --#CONFIG_MESH=y -- --# Background scanning modules --# These can be used to request wpa_supplicant to perform background scanning --# operations for roaming within an ESS (same SSID). See the bgscan parameter in --# the wpa_supplicant.conf file for more details. --# Periodic background scans based on signal strength --#CONFIG_BGSCAN_SIMPLE=y --# Learn channels used by the network and try to avoid bgscans on other --# channels (experimental) --#CONFIG_BGSCAN_LEARN=y -- --# Opportunistic Wireless Encryption (OWE) --# Experimental implementation of draft-harkins-owe-07.txt --#CONFIG_OWE=y -- --# Device Provisioning Protocol (DPP) --# This requires CONFIG_IEEE80211W=y to be enabled, too. (see --# wpa_supplicant/README-DPP for details) --#CONFIG_DPP=y -- --# uBus IPC/RPC System --# Services can connect to the bus and provide methods --# that can be called by other services or clients. --CONFIG_UBUS=y -- --# OpenWrt patch 380-disable-ctrl-iface-mib.patch --# leads to the MIB only being compiled in if --# CONFIG_CTRL_IFACE_MIB is enabled. --CONFIG_CTRL_IFACE_MIB=y -diff --git a/package/network/services/hostapd/files/wpad.init b/package/network/services/hostapd/files/wpad.init -deleted file mode 100644 -index 65d46df982..0000000000 ---- a/package/network/services/hostapd/files/wpad.init -+++ /dev/null -@@ -1,43 +0,0 @@ --#!/bin/sh /etc/rc.common -- --START=19 --STOP=21 -- --USE_PROCD=1 --NAME=wpad -- --start_service() { -- if [ -x "/usr/sbin/hostapd" ]; then -- mkdir -p /var/run/hostapd -- chown network:network /var/run/hostapd -- procd_open_instance hostapd -- procd_set_param command /usr/sbin/hostapd -s -g /var/run/hostapd/global -- procd_set_param respawn 3600 1 0 -- procd_set_param limits core="unlimited" -- [ -x /sbin/ujail -a -e /etc/capabilities/wpad.json ] && { -- procd_add_jail hostapd -- procd_set_param capabilities /etc/capabilities/wpad.json -- procd_set_param user network -- procd_set_param group network -- procd_set_param no_new_privs 1 -- } -- procd_close_instance -- fi -- -- if [ -x "/usr/sbin/wpa_supplicant" ]; then -- mkdir -p /var/run/wpa_supplicant -- chown network:network /var/run/wpa_supplicant -- procd_open_instance supplicant -- procd_set_param command /usr/sbin/wpa_supplicant -n -s -g /var/run/wpa_supplicant/global -- procd_set_param respawn 3600 1 0 -- procd_set_param limits core="unlimited" -- [ -x /sbin/ujail -a -e /etc/capabilities/wpad.json ] && { -- procd_add_jail wpa_supplicant -- procd_set_param capabilities /etc/capabilities/wpad.json -- procd_set_param user network -- procd_set_param group network -- procd_set_param no_new_privs 1 -- } -- procd_close_instance -- fi --} -diff --git a/package/network/services/hostapd/files/wpad.json b/package/network/services/hostapd/files/wpad.json -deleted file mode 100644 -index c73f3d98bd..0000000000 ---- a/package/network/services/hostapd/files/wpad.json -+++ /dev/null -@@ -1,22 +0,0 @@ --{ -- "bounding": [ -- "CAP_NET_ADMIN", -- "CAP_NET_RAW" -- ], -- "effective": [ -- "CAP_NET_ADMIN", -- "CAP_NET_RAW" -- ], -- "ambient": [ -- "CAP_NET_ADMIN", -- "CAP_NET_RAW" -- ], -- "permitted": [ -- "CAP_NET_ADMIN", -- "CAP_NET_RAW" -- ], -- "inheritable": [ -- "CAP_NET_ADMIN", -- "CAP_NET_RAW" -- ] --} -diff --git a/package/network/services/hostapd/files/wpad_acl.json b/package/network/services/hostapd/files/wpad_acl.json -deleted file mode 100644 -index c77ccd8ea0..0000000000 ---- a/package/network/services/hostapd/files/wpad_acl.json -+++ /dev/null -@@ -1,10 +0,0 @@ --{ -- "user": "network", -- "access": { -- "service": { -- "methods": [ "event" ] -- } -- }, -- "publish": [ "hostapd", "hostapd.*", "wpa_supplicant", "wpa_supplicant.*" ], -- "send": [ "bss.*", "wps_credentials" ] --} -diff --git a/package/network/services/hostapd/files/wps-hotplug.sh b/package/network/services/hostapd/files/wps-hotplug.sh -deleted file mode 100644 -index 073bdd1868..0000000000 ---- a/package/network/services/hostapd/files/wps-hotplug.sh -+++ /dev/null -@@ -1,69 +0,0 @@ --#!/bin/sh -- --wps_catch_credentials() { -- local iface ifaces ifc ifname ssid encryption key radio radios -- local found=0 -- -- . /usr/share/libubox/jshn.sh -- ubus -S -t 30 listen wps_credentials | while read creds; do -- json_init -- json_load "$creds" -- json_select wps_credentials || continue -- json_get_vars ifname ssid key encryption -- local ifcname="$ifname" -- json_init -- json_load "$(ubus -S call network.wireless status)" -- json_get_keys radios -- for radio in $radios; do -- json_select $radio -- json_select interfaces -- json_get_keys ifaces -- for ifc in $ifaces; do -- json_select $ifc -- json_get_vars ifname -- [ "$ifname" = "$ifcname" ] && { -- ubus -S call uci set "{\"config\":\"wireless\", \"type\":\"wifi-iface\", \ -- \"match\": { \"device\": \"$radio\", \"encryption\": \"wps\" }, \ -- \"values\": { \"encryption\": \"$encryption\", \ -- \"ssid\": \"$ssid\", \ -- \"key\": \"$key\" } }" -- ubus -S call uci commit '{"config": "wireless"}' -- ubus -S call uci apply -- } -- json_select .. -- done -- json_select .. -- json_select .. -- done -- done --} -- --if [ "$ACTION" = "released" ] && [ "$BUTTON" = "wps" ]; then -- # If the button was pressed for 3 seconds or more, trigger WPS on -- # wpa_supplicant only, no matter if hostapd is running or not. If -- # was pressed for less than 3 seconds, try triggering on -- # hostapd. If there is no hostapd instance to trigger it on or WPS -- # is not enabled on them, trigger it on wpa_supplicant. -- if [ "$SEEN" -lt 3 ] ; then -- wps_done=0 -- ubusobjs="$( ubus -S list hostapd.* )" -- for ubusobj in $ubusobjs; do -- ubus -S call $ubusobj wps_start && wps_done=1 -- done -- [ $wps_done = 0 ] || return 0 -- fi -- wps_done=0 -- ubusobjs="$( ubus -S list wpa_supplicant.* )" -- for ubusobj in $ubusobjs; do -- ifname="$(echo $ubusobj | cut -d'.' -f2 )" -- multi_ap="" -- if [ -e "/var/run/wpa_supplicant-${ifname}.conf.is_multiap" ]; then -- ubus -S call $ubusobj wps_start '{ "multi_ap": true }' && wps_done=1 -- else -- ubus -S call $ubusobj wps_start && wps_done=1 -- fi -- done -- [ $wps_done = 0 ] || wps_catch_credentials & --fi -- --return 0 -diff --git a/package/network/services/hostapd/patches/001-wolfssl-init-RNG-with-ECC-key.patch b/package/network/services/hostapd/patches/001-wolfssl-init-RNG-with-ECC-key.patch -deleted file mode 100644 -index 269dcaac75..0000000000 ---- a/package/network/services/hostapd/patches/001-wolfssl-init-RNG-with-ECC-key.patch -+++ /dev/null -@@ -1,43 +0,0 @@ --From 21ce83b4ae2b9563175fdb4fc4312096cc399cf8 Mon Sep 17 00:00:00 2001 --From: David Bauer --Date: Wed, 5 May 2021 00:44:34 +0200 --Subject: [PATCH] wolfssl: add RNG to EC key -- --Since upstream commit 6467de5a8840 ("Randomize z ordinates in --scalar mult when timing resistant") WolfSSL requires a RNG for --the EC key when built hardened which is the default. -- --Set the RNG for the EC key to fix connections for OWE clients. -- --Signed-off-by: David Bauer ----- -- src/crypto/crypto_wolfssl.c | 4 ++++ -- 1 file changed, 4 insertions(+) -- ----- a/src/crypto/crypto_wolfssl.c --+++ b/src/crypto/crypto_wolfssl.c --@@ -1340,6 +1340,7 @@ int ecc_projective_add_point(ecc_point * -- -- struct crypto_ec { -- ecc_key key; --+ WC_RNG rng; -- mp_int a; -- mp_int prime; -- mp_int order; --@@ -1394,6 +1395,8 @@ struct crypto_ec * crypto_ec_init(int gr -- return NULL; -- -- if (wc_ecc_init(&e->key) != 0 || --+ wc_InitRng(&e->rng) != 0 || --+ wc_ecc_set_rng(&e->key, &e->rng) != 0 || -- wc_ecc_set_curve(&e->key, 0, curve_id) != 0 || -- mp_init(&e->a) != MP_OKAY || -- mp_init(&e->prime) != MP_OKAY || --@@ -1425,6 +1428,7 @@ void crypto_ec_deinit(struct crypto_ec* -- mp_clear(&e->order); -- mp_clear(&e->prime); -- mp_clear(&e->a); --+ wc_FreeRng(&e->rng); -- wc_ecc_free(&e->key); -- os_free(e); -- } -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 -deleted file mode 100644 -index 0a51c84d21..0000000000 ---- a/package/network/services/hostapd/patches/010-mesh-Allow-DFS-channels-to-be-selected-if-dfs-is-ena.patch -+++ /dev/null -@@ -1,135 +0,0 @@ --From 8de8cd8380af0c43d4fde67a668d79ef73b26b26 Mon Sep 17 00:00:00 2001 --From: Peter Oh --Date: Tue, 30 Jun 2020 14:18:58 +0200 --Subject: [PATCH 10/19] mesh: Allow DFS channels to be selected if dfs is -- enabled -- --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(-) -- ----- a/wpa_supplicant/wpa_supplicant.c --+++ b/wpa_supplicant/wpa_supplicant.c --@@ -2638,7 +2638,7 @@ static int drv_supports_vht(struct wpa_s -- } -- -- ---static bool ibss_mesh_is_80mhz_avail(int channel, struct hostapd_hw_modes *mode) --+static bool ibss_mesh_is_80mhz_avail(int channel, struct hostapd_hw_modes *mode, bool dfs_enabled) -- { -- int i; -- --@@ -2647,7 +2647,10 @@ static bool ibss_mesh_is_80mhz_avail(int -- -- chan = hw_get_channel_chan(mode, i, NULL); -- if (!chan || --- chan->flag & (HOSTAPD_CHAN_DISABLED | HOSTAPD_CHAN_NO_IR)) --+ chan->flag & HOSTAPD_CHAN_DISABLED) --+ return false; --+ --+ if (!dfs_enabled && chan->flag & (HOSTAPD_CHAN_RADAR | HOSTAPD_CHAN_NO_IR)) -- return false; -- } -- --@@ -2774,7 +2777,7 @@ static void ibss_mesh_select_40mhz(struc -- const struct wpa_ssid *ssid, -- struct hostapd_hw_modes *mode, -- struct hostapd_freq_params *freq, --- int obss_scan) { --+ int obss_scan, bool dfs_enabled) { -- 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 -- return; -- -- /* Check primary channel flags */ --- if (pri_chan->flag & (HOSTAPD_CHAN_DISABLED | HOSTAPD_CHAN_NO_IR)) --+ if (pri_chan->flag & HOSTAPD_CHAN_DISABLED) -- return; --+ if (pri_chan->flag & (HOSTAPD_CHAN_RADAR | HOSTAPD_CHAN_NO_IR)) --+ if (!dfs_enabled) --+ return; -- -- #ifdef CONFIG_HT_OVERRIDES -- if (ssid->disable_ht40) --@@ -2825,8 +2831,11 @@ static void ibss_mesh_select_40mhz(struc -- return; -- -- /* Check secondary channel flags */ --- if (sec_chan->flag & (HOSTAPD_CHAN_DISABLED | HOSTAPD_CHAN_NO_IR)) --+ if (sec_chan->flag & HOSTAPD_CHAN_DISABLED) -- return; --+ if (sec_chan->flag & (HOSTAPD_CHAN_RADAR | HOSTAPD_CHAN_NO_IR)) --+ if (!dfs_enabled) --+ return; -- -- if (ht40 == -1) { -- if (!(pri_chan->flag & HOSTAPD_CHAN_HT40MINUS)) --@@ -2880,7 +2889,7 @@ static bool ibss_mesh_select_80_160mhz(s -- const struct wpa_ssid *ssid, -- struct hostapd_hw_modes *mode, -- struct hostapd_freq_params *freq, --- int ieee80211_mode, bool is_6ghz) { --+ int ieee80211_mode, bool is_6ghz, bool dfs_enabled) { -- 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 -- goto skip_80mhz; -- -- /* Use 40 MHz if channel not usable */ --- if (!ibss_mesh_is_80mhz_avail(channel, mode)) --+ if (!ibss_mesh_is_80mhz_avail(channel, mode, dfs_enabled)) -- goto skip_80mhz; -- -- chwidth = CONF_OPER_CHWIDTH_80MHZ; --@@ -2939,7 +2948,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 && --- ibss_mesh_is_80mhz_avail(channel + 16, mode)) { --+ ibss_mesh_is_80mhz_avail(channel + 16, mode, dfs_enabled)) { -- 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 -- if (!chan) -- continue; -- --- if (chan->flag & (HOSTAPD_CHAN_DISABLED | --- HOSTAPD_CHAN_NO_IR | --- HOSTAPD_CHAN_RADAR)) --+ if (chan->flag & HOSTAPD_CHAN_DISABLED) -- continue; --+ if (chan->flag & (HOSTAPD_CHAN_RADAR | --+ HOSTAPD_CHAN_NO_IR)) --+ if (!dfs_enabled) --+ continue; -- -- /* 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 -- int i, obss_scan = 1; -- u8 channel; -- bool is_6ghz; --+ 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 -- freq->channel = channel; -- /* Setup higher BW only for 5 GHz */ -- if (mode->mode == HOSTAPD_MODE_IEEE80211A) { --- ibss_mesh_select_40mhz(wpa_s, ssid, mode, freq, obss_scan); --+ ibss_mesh_select_40mhz(wpa_s, ssid, mode, freq, obss_scan, dfs_enabled); -- if (!ibss_mesh_select_80_160mhz(wpa_s, ssid, mode, freq, --- ieee80211_mode, is_6ghz)) --+ ieee80211_mode, is_6ghz, dfs_enabled)) -- freq->he_enabled = freq->vht_enabled = false; -- } -- -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 -deleted file mode 100644 -index 9b11f0e803..0000000000 ---- a/package/network/services/hostapd/patches/011-mesh-use-deterministic-channel-on-channel-switch.patch -+++ /dev/null -@@ -1,81 +0,0 @@ --From fc8ea40f6130ac18d9c66797de2cf1d5af55d496 Mon Sep 17 00:00:00 2001 --From: Markus Theil --Date: Tue, 30 Jun 2020 14:19:07 +0200 --Subject: [PATCH 19/19] mesh: use deterministic channel on channel switch -- --This patch uses a deterministic channel on DFS channel switch --in mesh networks. Otherwise, when switching to a usable but not --available channel, no CSA can be sent and a random channel is choosen --without notification of other nodes. It is then quite likely, that --the mesh network gets disconnected. -- --Fix this by using a deterministic number, based on the sha256 hash --of the mesh ID, in order to use at least a different number in each --mesh network. -- --Signed-off-by: Markus Theil ----- -- src/ap/dfs.c | 20 +++++++++++++++++++- -- src/drivers/driver_nl80211.c | 4 ++++ -- 2 files changed, 23 insertions(+), 1 deletion(-) -- ----- a/src/ap/dfs.c --+++ b/src/ap/dfs.c --@@ -17,6 +17,7 @@ -- #include "ap_drv_ops.h" -- #include "drivers/driver.h" -- #include "dfs.h" --+#include "crypto/crypto.h" -- -- -- enum dfs_channel_type { --@@ -521,9 +522,14 @@ dfs_get_valid_channel(struct hostapd_ifa -- int num_available_chandefs; -- int chan_idx, chan_idx2; -- int sec_chan_idx_80p80 = -1; --+ bool is_mesh = false; -- int i; -- u32 _rand; -- --+#ifdef CONFIG_MESH --+ is_mesh = iface->mconf; --+#endif --+ -- wpa_printf(MSG_DEBUG, "DFS: Selecting random channel"); -- *secondary_channel = 0; -- *oper_centr_freq_seg0_idx = 0; --@@ -543,8 +549,20 @@ dfs_get_valid_channel(struct hostapd_ifa -- if (num_available_chandefs == 0) -- return NULL; -- --- if (os_get_random((u8 *) &_rand, sizeof(_rand)) < 0) --+ /* try to use deterministic channel in mesh, so that both sides --+ * have a chance to switch to the same channel */ --+ if (is_mesh) { --+#ifdef CONFIG_MESH --+ u64 hash[4]; --+ const u8 *meshid[1] = { &iface->mconf->meshid[0] }; --+ const size_t meshid_len = iface->mconf->meshid_len; --+ --+ sha256_vector(1, meshid, &meshid_len, (u8 *)&hash[0]); --+ _rand = hash[0] + hash[1] + hash[2] + hash[3]; --+#endif --+ } else if (os_get_random((u8 *) &_rand, sizeof(_rand)) < 0) -- return NULL; --+ -- chan_idx = _rand % num_available_chandefs; -- dfs_find_channel(iface, &chan, chan_idx, type); -- if (!chan) { ----- a/src/drivers/driver_nl80211.c --+++ b/src/drivers/driver_nl80211.c --@@ -10977,6 +10977,10 @@ static int nl80211_switch_channel(void * -- if (ret) -- goto error; -- --+ if (drv->nlmode == NL80211_IFTYPE_MESH_POINT) { --+ nla_put_flag(msg, NL80211_ATTR_HANDLE_DFS); --+ } --+ -- /* beacon_csa params */ -- beacon_csa = nla_nest_start(msg, NL80211_ATTR_CSA_IES); -- if (!beacon_csa) -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 -deleted file mode 100644 -index 4ee43b5186..0000000000 ---- a/package/network/services/hostapd/patches/021-fix-sta-add-after-previous-connection.patch -+++ /dev/null -@@ -1,26 +0,0 @@ ----- a/src/ap/ieee802_11.c --+++ b/src/ap/ieee802_11.c --@@ -4601,6 +4601,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. --+ * --+ * If the STA was associated and authorized earlier, but came for a new --+ * connection (!added_unassoc + !reassoc), remove the existing STA entry --+ * so that it can be re-added. This case is rarely seen when the AP could --+ * not receive the deauth/disassoc frame from the STA. And the STA comes --+ * back with new connection within a short period or before the inactive --+ * STA entry is removed from the list. -- */ -- 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)", --@@ -4614,7 +4621,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) && --- !wpa_auth_sta_fils_tk_already_set(sta->wpa_sm)))) { --+ !wpa_auth_sta_fils_tk_already_set(sta->wpa_sm)) || --+ (!reassoc && (sta->flags & WLAN_STA_AUTHORIZED)))) { -- hostapd_drv_sta_remove(hapd, sta->addr); -- wpa_auth_sm_event(sta->wpa_sm, WPA_DRV_STA_REMOVED); -- set = 0; -diff --git a/package/network/services/hostapd/patches/022-hostapd-fix-use-of-uninitialized-stack-variables.patch b/package/network/services/hostapd/patches/022-hostapd-fix-use-of-uninitialized-stack-variables.patch -deleted file mode 100644 -index 8dec325c98..0000000000 ---- a/package/network/services/hostapd/patches/022-hostapd-fix-use-of-uninitialized-stack-variables.patch -+++ /dev/null -@@ -1,25 +0,0 @@ --From: Felix Fietkau --Date: Thu, 8 Jul 2021 16:33:03 +0200 --Subject: [PATCH] hostapd: fix use of uninitialized stack variables -- --When a CSA is performed on an 80 MHz channel, hostapd_change_config_freq --unconditionally calls hostapd_set_oper_centr_freq_seg0/1_idx with seg0/1 --filled by ieee80211_freq_to_chan. --However, if ieee80211_freq_to_chan fails (because the freq is 0 or invalid), --seg0/1 remains uninitialized and filled with stack garbage, causing errors --such as "hostapd: 80 MHz: center segment 1 configured" -- --Signed-off-by: Felix Fietkau ----- -- ----- a/src/ap/hostapd.c --+++ b/src/ap/hostapd.c --@@ -3764,7 +3764,7 @@ static int hostapd_change_config_freq(st -- struct hostapd_freq_params *old_params) -- { -- int channel; --- u8 seg0, seg1; --+ u8 seg0 = 0, seg1 = 0; -- struct hostapd_hw_modes *mode; -- -- if (!params->channel) { -diff --git a/package/network/services/hostapd/patches/023-ndisc_snoop-call-dl_list_del-before-freeing-ipv6-add.patch b/package/network/services/hostapd/patches/023-ndisc_snoop-call-dl_list_del-before-freeing-ipv6-add.patch -deleted file mode 100644 -index 9ff9b2398d..0000000000 ---- a/package/network/services/hostapd/patches/023-ndisc_snoop-call-dl_list_del-before-freeing-ipv6-add.patch -+++ /dev/null -@@ -1,19 +0,0 @@ --From: Felix Fietkau --Date: Wed, 28 Jul 2021 05:43:29 +0200 --Subject: [PATCH] ndisc_snoop: call dl_list_del before freeing ipv6 addresses -- --Fixes a segmentation fault on sta disconnect -- --Signed-off-by: Felix Fietkau ----- -- ----- a/src/ap/ndisc_snoop.c --+++ b/src/ap/ndisc_snoop.c --@@ -61,6 +61,7 @@ void sta_ip6addr_del(struct hostapd_data -- dl_list_for_each_safe(ip6addr, prev, &sta->ip6addr, struct ip6addr, -- list) { -- hostapd_drv_br_delete_ip_neigh(hapd, 6, (u8 *) &ip6addr->addr); --+ dl_list_del(&ip6addr->list); -- os_free(ip6addr); -- } -- } -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 -deleted file mode 100644 -index 19248e80d8..0000000000 ---- a/package/network/services/hostapd/patches/030-driver_nl80211-rewrite-neigh-code-to-not-depend-on-l.patch -+++ /dev/null -@@ -1,275 +0,0 @@ --From: Felix Fietkau --Date: Wed, 28 Jul 2021 05:49:46 +0200 --Subject: [PATCH] driver_nl80211: rewrite neigh code to not depend on -- libnl3-route -- --Removes an unnecessary dependency and also makes the code smaller -- --Signed-off-by: Felix Fietkau ----- -- ----- a/src/drivers/driver_nl80211.c --+++ b/src/drivers/driver_nl80211.c --@@ -16,9 +16,6 @@ -- #include -- #include -- #include ---#ifdef CONFIG_LIBNL3_ROUTE ---#include ---#endif /* CONFIG_LIBNL3_ROUTE */ -- #include -- #include -- #include --@@ -5783,26 +5780,29 @@ fail: -- -- static void rtnl_neigh_delete_fdb_entry(struct i802_bss *bss, const u8 *addr) -- { ---#ifdef CONFIG_LIBNL3_ROUTE -- struct wpa_driver_nl80211_data *drv = bss->drv; --- struct rtnl_neigh *rn; --- struct nl_addr *nl_addr; --+ struct ndmsg nhdr = { --+ .ndm_state = NUD_PERMANENT, --+ .ndm_ifindex = bss->ifindex, --+ .ndm_family = AF_BRIDGE, --+ }; --+ struct nl_msg *msg; -- int err; -- --- rn = rtnl_neigh_alloc(); --- if (!rn) --+ msg = nlmsg_alloc_simple(RTM_DELNEIGH, NLM_F_CREATE); --+ if (!msg) -- return; -- --- rtnl_neigh_set_family(rn, AF_BRIDGE); --- rtnl_neigh_set_ifindex(rn, bss->ifindex); --- nl_addr = nl_addr_build(AF_BRIDGE, (void *) addr, ETH_ALEN); --- if (!nl_addr) { --- rtnl_neigh_put(rn); --- return; --- } --- rtnl_neigh_set_lladdr(rn, nl_addr); --+ if (nlmsg_append(msg, &nhdr, sizeof(nhdr), NLMSG_ALIGNTO) < 0) --+ goto errout; --+ --+ if (nla_put(msg, NDA_LLADDR, ETH_ALEN, (void *)addr)) --+ goto errout; --+ --+ if (nl_send_auto_complete(drv->rtnl_sk, msg) < 0) --+ goto errout; -- --- err = rtnl_neigh_delete(drv->rtnl_sk, rn, 0); --+ err = nl_wait_for_ack(drv->rtnl_sk); -- 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( -- MACSTR, MAC2STR(addr)); -- } -- --- nl_addr_put(nl_addr); --- rtnl_neigh_put(rn); ---#endif /* CONFIG_LIBNL3_ROUTE */ --+errout: --+ nlmsg_free(msg); -- } -- -- --@@ -8492,7 +8491,6 @@ static void *i802_init(struct hostapd_da -- (params->num_bridge == 0 || !params->bridge[0])) -- add_ifidx(drv, br_ifindex, drv->ifindex); -- ---#ifdef CONFIG_LIBNL3_ROUTE -- if (bss->added_if_into_bridge || bss->already_in_bridge) { -- int err; -- --@@ -8509,7 +8507,6 @@ static void *i802_init(struct hostapd_da -- goto failed; -- } -- } ---#endif /* CONFIG_LIBNL3_ROUTE */ -- -- if (drv->capa.flags2 & WPA_DRIVER_FLAGS2_CONTROL_PORT_RX) { -- wpa_printf(MSG_DEBUG, --@@ -11843,13 +11840,14 @@ static int wpa_driver_br_add_ip_neigh(vo -- const u8 *ipaddr, int prefixlen, -- const u8 *addr) -- { ---#ifdef CONFIG_LIBNL3_ROUTE -- struct i802_bss *bss = priv; -- struct wpa_driver_nl80211_data *drv = bss->drv; --- struct rtnl_neigh *rn; --- struct nl_addr *nl_ipaddr = NULL; --- struct nl_addr *nl_lladdr = NULL; --- int family, addrsize; --+ struct ndmsg nhdr = { --+ .ndm_state = NUD_PERMANENT, --+ .ndm_ifindex = bss->br_ifindex, --+ }; --+ struct nl_msg *msg; --+ int addrsize; -- int res; -- -- if (!ipaddr || prefixlen == 0 || !addr) --@@ -11868,85 +11866,66 @@ static int wpa_driver_br_add_ip_neigh(vo -- } -- -- if (version == 4) { --- family = AF_INET; --+ nhdr.ndm_family = AF_INET; -- addrsize = 4; -- } else if (version == 6) { --- family = AF_INET6; --+ nhdr.ndm_family = AF_INET6; -- addrsize = 16; -- } else { -- return -EINVAL; -- } -- --- rn = rtnl_neigh_alloc(); --- if (rn == NULL) --+ msg = nlmsg_alloc_simple(RTM_NEWNEIGH, NLM_F_CREATE); --+ if (!msg) -- return -ENOMEM; -- --- /* set the destination ip address for neigh */ --- nl_ipaddr = nl_addr_build(family, (void *) ipaddr, addrsize); --- if (nl_ipaddr == NULL) { --- wpa_printf(MSG_DEBUG, "nl80211: nl_ipaddr build failed"); --- res = -ENOMEM; --+ res = -ENOMEM; --+ if (nlmsg_append(msg, &nhdr, sizeof(nhdr), NLMSG_ALIGNTO) < 0) -- goto errout; --- } --- nl_addr_set_prefixlen(nl_ipaddr, prefixlen); --- res = rtnl_neigh_set_dst(rn, nl_ipaddr); --- if (res) { --- wpa_printf(MSG_DEBUG, --- "nl80211: neigh set destination addr failed"); --+ --+ if (nla_put(msg, NDA_DST, addrsize, (void *)ipaddr)) -- goto errout; --- } -- --- /* set the corresponding lladdr for neigh */ --- nl_lladdr = nl_addr_build(AF_BRIDGE, (u8 *) addr, ETH_ALEN); --- if (nl_lladdr == NULL) { --- wpa_printf(MSG_DEBUG, "nl80211: neigh set lladdr failed"); --- res = -ENOMEM; --+ if (nla_put(msg, NDA_LLADDR, ETH_ALEN, (void *)addr)) -- goto errout; --- } --- rtnl_neigh_set_lladdr(rn, nl_lladdr); -- --- rtnl_neigh_set_ifindex(rn, bss->br_ifindex); --- rtnl_neigh_set_state(rn, NUD_PERMANENT); --+ res = nl_send_auto_complete(drv->rtnl_sk, msg); --+ if (res < 0) --+ goto errout; -- --- res = rtnl_neigh_add(drv->rtnl_sk, rn, NLM_F_CREATE); --+ res = nl_wait_for_ack(drv->rtnl_sk); -- if (res) { -- wpa_printf(MSG_DEBUG, -- "nl80211: Adding bridge ip neigh failed: %s", -- nl_geterror(res)); -- } -- errout: --- if (nl_lladdr) --- nl_addr_put(nl_lladdr); --- if (nl_ipaddr) --- nl_addr_put(nl_ipaddr); --- if (rn) --- rtnl_neigh_put(rn); --+ nlmsg_free(msg); -- return res; ---#else /* CONFIG_LIBNL3_ROUTE */ --- return -1; ---#endif /* CONFIG_LIBNL3_ROUTE */ -- } -- -- -- static int wpa_driver_br_delete_ip_neigh(void *priv, u8 version, -- const u8 *ipaddr) -- { ---#ifdef CONFIG_LIBNL3_ROUTE -- struct i802_bss *bss = priv; -- struct wpa_driver_nl80211_data *drv = bss->drv; --- struct rtnl_neigh *rn; --- struct nl_addr *nl_ipaddr; --- int family, addrsize; --+ struct ndmsg nhdr = { --+ .ndm_state = NUD_PERMANENT, --+ .ndm_ifindex = bss->br_ifindex, --+ }; --+ struct nl_msg *msg; --+ int addrsize; -- int res; -- -- if (!ipaddr) -- return -EINVAL; -- -- if (version == 4) { --- family = AF_INET; --+ nhdr.ndm_family = AF_INET; -- addrsize = 4; -- } else if (version == 6) { --- family = AF_INET6; --+ nhdr.ndm_family = AF_INET6; -- addrsize = 16; -- } else { -- return -EINVAL; --@@ -11964,41 +11943,30 @@ static int wpa_driver_br_delete_ip_neigh -- return -1; -- } -- --- rn = rtnl_neigh_alloc(); --- if (rn == NULL) --+ msg = nlmsg_alloc_simple(RTM_DELNEIGH, NLM_F_CREATE); --+ if (!msg) -- return -ENOMEM; -- --- /* set the destination ip address for neigh */ --- nl_ipaddr = nl_addr_build(family, (void *) ipaddr, addrsize); --- if (nl_ipaddr == NULL) { --- wpa_printf(MSG_DEBUG, "nl80211: nl_ipaddr build failed"); --- res = -ENOMEM; --+ res = -ENOMEM; --+ if (nlmsg_append(msg, &nhdr, sizeof(nhdr), NLMSG_ALIGNTO) < 0) -- goto errout; --- } --- res = rtnl_neigh_set_dst(rn, nl_ipaddr); --- if (res) { --- wpa_printf(MSG_DEBUG, --- "nl80211: neigh set destination addr failed"); --+ --+ if (nla_put(msg, NDA_DST, addrsize, (void *)ipaddr)) -- goto errout; --- } -- --- rtnl_neigh_set_ifindex(rn, bss->br_ifindex); --+ res = nl_send_auto_complete(drv->rtnl_sk, msg); --+ if (res < 0) --+ goto errout; -- --- res = rtnl_neigh_delete(drv->rtnl_sk, rn, 0); --+ res = nl_wait_for_ack(drv->rtnl_sk); -- if (res) { -- wpa_printf(MSG_DEBUG, -- "nl80211: Deleting bridge ip neigh failed: %s", -- nl_geterror(res)); -- } -- errout: --- if (nl_ipaddr) --- nl_addr_put(nl_ipaddr); --- if (rn) --- rtnl_neigh_put(rn); --+ nlmsg_free(msg); -- return res; ---#else /* CONFIG_LIBNL3_ROUTE */ --- return -1; ---#endif /* CONFIG_LIBNL3_ROUTE */ -- } -- -- -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 -deleted file mode 100644 -index f98d3806dc..0000000000 ---- a/package/network/services/hostapd/patches/040-mesh-allow-processing-authentication-frames-in-block.patch -+++ /dev/null -@@ -1,34 +0,0 @@ --From: Felix Fietkau --Date: Mon, 18 Feb 2019 12:57:11 +0100 --Subject: [PATCH] mesh: allow processing authentication frames in blocked state -- --If authentication fails repeatedly e.g. because of a weak signal, the link --can end up in blocked state. If one of the nodes tries to establish a link --again before it is unblocked on the other side, it will block the link to --that other side. The same happens on the other side when it unblocks the --link. In that scenario, the link never recovers on its own. -- --To fix this, allow restarting authentication even if the link is in blocked --state, but don't initiate the attempt until the blocked period is over. -- --Signed-off-by: Felix Fietkau ----- -- ----- a/src/ap/ieee802_11.c --+++ b/src/ap/ieee802_11.c --@@ -3012,15 +3012,6 @@ static void handle_auth(struct hostapd_d -- seq_ctrl); -- return; -- } ---#ifdef CONFIG_MESH --- if ((hapd->conf->mesh & MESH_ENABLED) && --- sta->plink_state == PLINK_BLOCKED) { --- wpa_printf(MSG_DEBUG, "Mesh peer " MACSTR --- " is blocked - drop Authentication frame", --- MAC2STR(sa)); --- return; --- } ---#endif /* CONFIG_MESH */ -- #ifdef CONFIG_PASN -- if (auth_alg == WLAN_AUTH_PASN && -- (sta->flags & WLAN_STA_ASSOC)) { -diff --git a/package/network/services/hostapd/patches/050-build_fix.patch b/package/network/services/hostapd/patches/050-build_fix.patch -deleted file mode 100644 -index 8680b07c66..0000000000 ---- a/package/network/services/hostapd/patches/050-build_fix.patch -+++ /dev/null -@@ -1,20 +0,0 @@ ----- a/hostapd/Makefile --+++ b/hostapd/Makefile --@@ -324,6 +324,7 @@ ifdef CONFIG_FILS -- CFLAGS += -DCONFIG_FILS -- OBJS += ../src/ap/fils_hlp.o -- NEED_SHA384=y --+NEED_HMAC_SHA384_KDF=y -- NEED_AES_SIV=y -- ifdef CONFIG_FILS_SK_PFS -- CFLAGS += -DCONFIG_FILS_SK_PFS ----- a/wpa_supplicant/Makefile --+++ b/wpa_supplicant/Makefile --@@ -331,6 +331,7 @@ endif -- ifdef CONFIG_FILS -- CFLAGS += -DCONFIG_FILS -- NEED_SHA384=y --+NEED_HMAC_SHA384_KDF=y -- NEED_AES_SIV=y -- ifdef CONFIG_FILS_SK_PFS -- CFLAGS += -DCONFIG_FILS_SK_PFS -diff --git a/package/network/services/hostapd/patches/100-daemonize_fix.patch b/package/network/services/hostapd/patches/100-daemonize_fix.patch -deleted file mode 100644 -index 687bd4082d..0000000000 ---- a/package/network/services/hostapd/patches/100-daemonize_fix.patch -+++ /dev/null -@@ -1,97 +0,0 @@ ----- a/src/utils/os_unix.c --+++ b/src/utils/os_unix.c --@@ -10,6 +10,7 @@ -- -- #include -- #include --+#include -- -- #ifdef ANDROID -- #include --@@ -188,59 +189,46 @@ int os_gmtime(os_time_t t, struct os_tm -- return 0; -- } -- --- ---#ifdef __APPLE__ ---#include ---static int os_daemon(int nochdir, int noclose) --+int os_daemonize(const char *pid_file) -- { --- int devnull; --+ int pid = 0, i, devnull; -- --- if (chdir("/") < 0) --- return -1; --+#if defined(__uClinux__) || defined(__sun__) --+ return -1; --+#else /* defined(__uClinux__) || defined(__sun__) */ -- --- devnull = open("/dev/null", O_RDWR); --- if (devnull < 0) --+#ifndef __APPLE__ --+ pid = fork(); --+ if (pid < 0) -- return -1; --+#endif -- --- if (dup2(devnull, STDIN_FILENO) < 0) { --- close(devnull); --- return -1; --+ if (pid > 0) { --+ if (pid_file) { --+ FILE *f = fopen(pid_file, "w"); --+ if (f) { --+ fprintf(f, "%u\n", pid); --+ fclose(f); --+ } --+ } --+ _exit(0); -- } -- --- if (dup2(devnull, STDOUT_FILENO) < 0) { --- close(devnull); --+ if (setsid() < 0) -- return -1; --- } -- --- if (dup2(devnull, STDERR_FILENO) < 0) { --- close(devnull); --+ if (chdir("/") < 0) -- return -1; --- } --- --- return 0; ---} ---#else /* __APPLE__ */ ---#define os_daemon daemon ---#endif /* __APPLE__ */ -- --- ---int os_daemonize(const char *pid_file) ---{ ---#if defined(__uClinux__) || defined(__sun__) --- return -1; ---#else /* defined(__uClinux__) || defined(__sun__) */ --- if (os_daemon(0, 0)) { --- perror("daemon"); --+ devnull = open("/dev/null", O_RDWR); --+ if (devnull < 0) -- return -1; --- } -- --- if (pid_file) { --- FILE *f = fopen(pid_file, "w"); --- if (f) { --- fprintf(f, "%u\n", getpid()); --- fclose(f); --- } --- } --+ for (i = 0; i <= STDERR_FILENO; i++) --+ dup2(devnull, i); --+ --+ if (devnull > 2) --+ close(devnull); -- -- return -0; -- #endif /* defined(__uClinux__) || defined(__sun__) */ -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 -deleted file mode 100644 -index 22107944dc..0000000000 ---- a/package/network/services/hostapd/patches/110-mbedtls-TLS-crypto-option-initial-port.patch -+++ /dev/null -@@ -1,8051 +0,0 @@ --From e16f200dc1d2f69efc78c7c55af0d7b410a981f9 Mon Sep 17 00:00:00 2001 --From: Glenn Strauss --Date: Tue, 5 Jul 2022 02:49:50 -0400 --Subject: [PATCH 1/7] mbedtls: TLS/crypto option (initial port) -- --Signed-off-by: Glenn Strauss ----- -- hostapd/Makefile | 91 + -- hostapd/defconfig | 15 +- -- src/crypto/crypto_mbedtls.c | 4043 +++++++++++++++++ -- src/crypto/tls_mbedtls.c | 3313 ++++++++++++++ -- .../build/build-wpa_supplicant-mbedtls.config | 24 + -- tests/hwsim/example-hostapd.config | 4 + -- tests/hwsim/example-wpa_supplicant.config | 4 + -- wpa_supplicant/Makefile | 74 + -- wpa_supplicant/defconfig | 6 +- -- 9 files changed, 7571 insertions(+), 3 deletions(-) -- create mode 100644 src/crypto/crypto_mbedtls.c -- create mode 100644 src/crypto/tls_mbedtls.c -- create mode 100644 tests/build/build-wpa_supplicant-mbedtls.config -- ----- a/hostapd/Makefile --+++ b/hostapd/Makefile --@@ -745,6 +745,40 @@ endif -- CFLAGS += -DTLS_DEFAULT_CIPHERS=\"$(CONFIG_TLS_DEFAULT_CIPHERS)\" -- endif -- --+ifeq ($(CONFIG_TLS), mbedtls) --+ifndef CONFIG_CRYPTO --+CONFIG_CRYPTO=mbedtls --+endif --+ifdef TLS_FUNCS --+OBJS += ../src/crypto/tls_mbedtls.o --+LIBS += -lmbedtls --+ifndef CONFIG_DPP --+LIBS += -lmbedx509 --+endif --+endif --+OBJS += ../src/crypto/crypto_$(CONFIG_CRYPTO).o --+HOBJS += ../src/crypto/crypto_$(CONFIG_CRYPTO).o --+SOBJS += ../src/crypto/crypto_$(CONFIG_CRYPTO).o --+ifdef NEED_FIPS186_2_PRF --+OBJS += ../src/crypto/fips_prf_internal.o --+SHA1OBJS += ../src/crypto/sha1-internal.o --+endif --+ifeq ($(CONFIG_CRYPTO), mbedtls) --+ifdef CONFIG_DPP --+LIBS += -lmbedx509 --+LIBS_h += -lmbedx509 --+LIBS_n += -lmbedx509 --+LIBS_s += -lmbedx509 --+endif --+LIBS += -lmbedcrypto --+LIBS_h += -lmbedcrypto --+LIBS_n += -lmbedcrypto --+LIBS_s += -lmbedcrypto --+# XXX: create a config option? --+CFLAGS += -DCRYPTO_RSA_OAEP_SHA256 --+endif --+endif --+ -- ifeq ($(CONFIG_TLS), gnutls) -- ifndef CONFIG_CRYPTO -- # default to libgcrypt --@@ -924,9 +958,11 @@ endif -- -- ifneq ($(CONFIG_TLS), openssl) -- ifneq ($(CONFIG_TLS), wolfssl) --+ifneq ($(CONFIG_TLS), mbedtls) -- AESOBJS += ../src/crypto/aes-wrap.o -- endif -- endif --+endif -- ifdef NEED_AES_EAX -- AESOBJS += ../src/crypto/aes-eax.o -- NEED_AES_CTR=y --@@ -936,38 +972,48 @@ AESOBJS += ../src/crypto/aes-siv.o -- NEED_AES_CTR=y -- endif -- ifdef NEED_AES_CTR --+ifneq ($(CONFIG_TLS), mbedtls) -- AESOBJS += ../src/crypto/aes-ctr.o -- endif --+endif -- ifdef NEED_AES_ENCBLOCK --+ifneq ($(CONFIG_TLS), mbedtls) -- AESOBJS += ../src/crypto/aes-encblock.o -- endif --+endif -- ifneq ($(CONFIG_TLS), openssl) -- ifneq ($(CONFIG_TLS), linux) -- ifneq ($(CONFIG_TLS), wolfssl) --+ifneq ($(CONFIG_TLS), mbedtls) -- AESOBJS += ../src/crypto/aes-omac1.o -- endif -- endif -- endif --+endif -- ifdef NEED_AES_UNWRAP -- ifneq ($(CONFIG_TLS), openssl) -- ifneq ($(CONFIG_TLS), linux) -- ifneq ($(CONFIG_TLS), wolfssl) --+ifneq ($(CONFIG_TLS), mbedtls) -- NEED_AES_DEC=y -- AESOBJS += ../src/crypto/aes-unwrap.o -- endif -- endif -- endif -- endif --+endif -- ifdef NEED_AES_CBC -- NEED_AES_DEC=y -- ifneq ($(CONFIG_TLS), openssl) -- ifneq ($(CONFIG_TLS), linux) -- ifneq ($(CONFIG_TLS), wolfssl) --+ifneq ($(CONFIG_TLS), mbedtls) -- AESOBJS += ../src/crypto/aes-cbc.o -- endif -- endif -- endif -- endif --+endif -- ifdef NEED_AES_DEC -- ifdef CONFIG_INTERNAL_AES -- AESOBJS += ../src/crypto/aes-internal-dec.o --@@ -982,12 +1028,16 @@ ifneq ($(CONFIG_TLS), openssl) -- ifneq ($(CONFIG_TLS), linux) -- ifneq ($(CONFIG_TLS), gnutls) -- ifneq ($(CONFIG_TLS), wolfssl) --+ifneq ($(CONFIG_TLS), mbedtls) -- SHA1OBJS += ../src/crypto/sha1.o -- endif -- endif -- endif -- endif --+endif --+ifneq ($(CONFIG_TLS), mbedtls) -- SHA1OBJS += ../src/crypto/sha1-prf.o --+endif -- ifdef CONFIG_INTERNAL_SHA1 -- SHA1OBJS += ../src/crypto/sha1-internal.o -- ifdef NEED_FIPS186_2_PRF --@@ -996,16 +1046,22 @@ endif -- endif -- ifneq ($(CONFIG_TLS), openssl) -- ifneq ($(CONFIG_TLS), wolfssl) --+ifneq ($(CONFIG_TLS), mbedtls) -- SHA1OBJS += ../src/crypto/sha1-pbkdf2.o -- endif -- endif --+endif -- ifdef NEED_T_PRF --+ifneq ($(CONFIG_TLS), mbedtls) -- SHA1OBJS += ../src/crypto/sha1-tprf.o -- endif --+endif -- ifdef NEED_TLS_PRF --+ifneq ($(CONFIG_TLS), mbedtls) -- SHA1OBJS += ../src/crypto/sha1-tlsprf.o -- endif -- endif --+endif -- -- ifdef NEED_SHA1 -- OBJS += $(SHA1OBJS) --@@ -1015,11 +1071,13 @@ ifneq ($(CONFIG_TLS), openssl) -- ifneq ($(CONFIG_TLS), linux) -- ifneq ($(CONFIG_TLS), gnutls) -- ifneq ($(CONFIG_TLS), wolfssl) --+ifneq ($(CONFIG_TLS), mbedtls) -- OBJS += ../src/crypto/md5.o -- endif -- endif -- endif -- endif --+endif -- -- ifdef NEED_MD5 -- ifdef CONFIG_INTERNAL_MD5 --@@ -1058,56 +1116,81 @@ ifneq ($(CONFIG_TLS), openssl) -- ifneq ($(CONFIG_TLS), linux) -- ifneq ($(CONFIG_TLS), gnutls) -- ifneq ($(CONFIG_TLS), wolfssl) --+ifneq ($(CONFIG_TLS), mbedtls) -- OBJS += ../src/crypto/sha256.o -- endif -- endif -- endif -- endif --+endif --+ifneq ($(CONFIG_TLS), mbedtls) -- OBJS += ../src/crypto/sha256-prf.o --+endif -- ifdef CONFIG_INTERNAL_SHA256 -- OBJS += ../src/crypto/sha256-internal.o -- endif -- ifdef NEED_TLS_PRF_SHA256 --+ifneq ($(CONFIG_TLS), mbedtls) -- OBJS += ../src/crypto/sha256-tlsprf.o -- endif --+endif -- ifdef NEED_TLS_PRF_SHA384 --+ifneq ($(CONFIG_TLS), mbedtls) -- OBJS += ../src/crypto/sha384-tlsprf.o -- endif --+endif -- ifdef NEED_HMAC_SHA256_KDF --+CFLAGS += -DCONFIG_HMAC_SHA256_KDF --+ifneq ($(CONFIG_TLS), mbedtls) -- OBJS += ../src/crypto/sha256-kdf.o -- endif --+endif -- ifdef NEED_HMAC_SHA384_KDF --+CFLAGS += -DCONFIG_HMAC_SHA384_KDF --+ifneq ($(CONFIG_TLS), mbedtls) -- OBJS += ../src/crypto/sha384-kdf.o -- endif --+endif -- ifdef NEED_HMAC_SHA512_KDF --+CFLAGS += -DCONFIG_HMAC_SHA512_KDF --+ifneq ($(CONFIG_TLS), mbedtls) -- OBJS += ../src/crypto/sha512-kdf.o -- endif --+endif -- ifdef NEED_SHA384 -- CFLAGS += -DCONFIG_SHA384 -- ifneq ($(CONFIG_TLS), openssl) -- ifneq ($(CONFIG_TLS), linux) -- ifneq ($(CONFIG_TLS), gnutls) -- ifneq ($(CONFIG_TLS), wolfssl) --+ifneq ($(CONFIG_TLS), mbedtls) -- OBJS += ../src/crypto/sha384.o -- endif -- endif -- endif -- endif --+endif --+ifneq ($(CONFIG_TLS), mbedtls) -- OBJS += ../src/crypto/sha384-prf.o -- endif --+endif -- ifdef NEED_SHA512 -- CFLAGS += -DCONFIG_SHA512 -- ifneq ($(CONFIG_TLS), openssl) -- ifneq ($(CONFIG_TLS), linux) -- ifneq ($(CONFIG_TLS), gnutls) -- ifneq ($(CONFIG_TLS), wolfssl) --+ifneq ($(CONFIG_TLS), mbedtls) -- OBJS += ../src/crypto/sha512.o -- endif -- endif -- endif -- endif --+endif --+ifneq ($(CONFIG_TLS), mbedtls) -- OBJS += ../src/crypto/sha512-prf.o -- endif --+endif -- -- ifdef CONFIG_INTERNAL_SHA384 -- CFLAGS += -DCONFIG_INTERNAL_SHA384 --@@ -1152,11 +1235,13 @@ HOBJS += $(SHA1OBJS) -- ifneq ($(CONFIG_TLS), openssl) -- ifneq ($(CONFIG_TLS), linux) -- ifneq ($(CONFIG_TLS), wolfssl) --+ifneq ($(CONFIG_TLS), mbedtls) -- HOBJS += ../src/crypto/md5.o -- endif -- endif -- endif -- endif --+endif -- -- ifdef CONFIG_RADIUS_SERVER -- CFLAGS += -DRADIUS_SERVER --@@ -1329,7 +1414,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 --+ifneq ($(CONFIG_TLS), mbedtls) -- HOBJS += ../src/crypto/aes-encblock.o --+endif -- 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 -- SOBJS += ../src/common/sae_pk.o -- SOBJS += ../src/common/dragonfly.o -- SOBJS += $(AESOBJS) --+ifneq ($(CONFIG_TLS), mbedtls) -- SOBJS += ../src/crypto/sha256-prf.o -- SOBJS += ../src/crypto/sha384-prf.o -- SOBJS += ../src/crypto/sha512-prf.o --+endif -- SOBJS += ../src/crypto/dh_groups.o --+ifneq ($(CONFIG_TLS), mbedtls) -- SOBJS += ../src/crypto/sha256-kdf.o -- SOBJS += ../src/crypto/sha384-kdf.o -- SOBJS += ../src/crypto/sha512-kdf.o --+endif -- -- _OBJS_VAR := NOBJS -- include ../src/objs.mk ----- a/hostapd/defconfig --+++ b/hostapd/defconfig --@@ -6,9 +6,21 @@ -- # just setting VARIABLE=n is not disabling that variable. -- # -- # This file is included in Makefile, so variables like CFLAGS and LIBS can also ---# be modified from here. In most cass, these lines should use += in order not --+# be modified from here. In most cases, these lines should use += in order not -- # to override previous values of the variables. -- --+ --+# Uncomment following two lines and fix the paths if you have installed TLS --+# libraries in a non-default location --+#CFLAGS += -I/usr/local/openssl/include --+#LIBS += -L/usr/local/openssl/lib --+ --+# Some Red Hat versions seem to include kerberos header files from OpenSSL, but --+# the kerberos files are not in the default include path. Following line can be --+# used to fix build issues on such systems (krb5.h not found). --+#CFLAGS += -I/usr/include/kerberos --+ --+ -- # Driver interface for Host AP driver -- CONFIG_DRIVER_HOSTAP=y -- --@@ -278,6 +290,7 @@ CONFIG_IPV6=y -- # openssl = OpenSSL (default) -- # gnutls = GnuTLS -- # internal = Internal TLSv1 implementation (experimental) --+# mbedtls = mbed TLS -- # linux = Linux kernel AF_ALG and internal TLSv1 implementation (experimental) -- # none = Empty template -- #CONFIG_TLS=openssl ----- /dev/null --+++ b/src/crypto/crypto_mbedtls.c --@@ -0,0 +1,4043 @@ --+/* --+ * crypto wrapper functions for mbed TLS --+ * --+ * SPDX-FileCopyrightText: 2022 Glenn Strauss --+ * SPDX-License-Identifier: BSD-3-Clause --+ */ --+ --+#include "utils/includes.h" --+#include "utils/common.h" --+ --+#include --+#include --+#include --+#include /* mbedtls_platform_zeroize() */ --+#include --+#include --+#include --+#include --+#include --+#include --+#include --+#include --+ --+#ifndef MBEDTLS_PRIVATE --+#define MBEDTLS_PRIVATE(x) x --+#endif --+ --+/* hostapd/wpa_supplicant provides forced_memzero(), --+ * but prefer mbedtls_platform_zeroize() */ --+#define forced_memzero(ptr,sz) mbedtls_platform_zeroize(ptr,sz) --+ --+#ifndef __has_attribute --+#define __has_attribute(x) 0 --+#endif --+ --+#ifndef __GNUC_PREREQ --+#define __GNUC_PREREQ(maj,min) 0 --+#endif --+ --+#ifndef __attribute_cold__ --+#if __has_attribute(cold) \ --+ || __GNUC_PREREQ(4,3) --+#define __attribute_cold__ __attribute__((__cold__)) --+#else --+#define __attribute_cold__ --+#endif --+#endif --+ --+#ifndef __attribute_noinline__ --+#if __has_attribute(noinline) \ --+ || __GNUC_PREREQ(3,1) --+#define __attribute_noinline__ __attribute__((__noinline__)) --+#else --+#define __attribute_noinline__ --+#endif --+#endif --+ --+#include "crypto.h" --+#include "aes_wrap.h" --+#include "aes.h" --+#include "md5.h" --+#include "sha1.h" --+#include "sha256.h" --+#include "sha384.h" --+#include "sha512.h" --+ --+ --+/* --+ * selective code inclusion based on preprocessor defines --+ * --+ * future: additional code could be wrapped with preprocessor checks if --+ * wpa_supplicant/Makefile and hostap/Makefile were more consistent with --+ * setting preprocessor defines for named groups of functionality --+ */ --+ --+#if defined(CONFIG_FIPS) --+#undef MBEDTLS_MD4_C /* omit md4_vector() */ --+#undef MBEDTLS_MD5_C /* omit md5_vector() hmac_md5_vector() hmac_md5() */ --+#undef MBEDTLS_DES_C /* omit des_encrypt() */ --+#undef MBEDTLS_NIST_KW_C /* omit aes_wrap() aes_unwrap() */ --+#define CRYPTO_MBEDTLS_CONFIG_FIPS --+#endif --+ --+#if !defined(CONFIG_FIPS) --+#if defined(EAP_PWD) \ --+ || defined(EAP_LEAP) || defined(EAP_LEAP_DYNAMIC) \ --+ || defined(EAP_TTLS) || defined(EAP_TTLS_DYNAMIC) \ --+ || defined(EAP_MSCHAPv2) || defined(EAP_MSCHAPv2_DYNAMIC) \ --+ || defined(EAP_SERVER_MSCHAPV2) --+#ifndef MBEDTLS_MD4_C /* (MD4 not in mbedtls 3.x) */ --+#include "md4-internal.c"/* pull in hostap local implementation */ --+#endif /* md4_vector() */ --+#else --+#undef MBEDTLS_MD4_C /* omit md4_vector() */ --+#endif --+#endif --+ --+#if !defined(CONFIG_NO_RC4) && !defined(CONFIG_NO_WPA) --+#ifndef MBEDTLS_ARC4_C /* (RC4 not in mbedtls 3.x) */ --+#include "rc4.c" /* pull in hostap local implementation */ --+#endif /* rc4_skip() */ --+#else --+#undef MBEDTLS_ARC4_C /* omit rc4_skip() */ --+#endif --+ --+#if defined(CONFIG_MACSEC) \ --+ || defined(CONFIG_NO_RADIUS) \ --+ || defined(CONFIG_IEEE80211R) \ --+ || defined(EAP_SERVER_FAST) \ --+ || defined(EAP_SERVER_TEAP) \ --+ || !defined(CONFIG_NO_WPA) --+ /* aes_wrap() aes_unwrap() */ --+#else --+#undef MBEDTLS_NIST_KW_C /* omit aes_wrap() aes_unwrap() */ --+#endif --+ --+#if !defined(CONFIG_SHA256) --+#undef MBEDTLS_SHA256_C --+#endif --+ --+#if !defined(CONFIG_SHA384) && !defined(CONFIG_SHA512) --+#undef MBEDTLS_SHA512_C --+#endif --+ --+#if defined(CONFIG_HMAC_SHA256_KDF) --+#define CRYPTO_MBEDTLS_HMAC_KDF_SHA256 --+#endif --+#if defined(CONFIG_HMAC_SHA384_KDF) --+#define CRYPTO_MBEDTLS_HMAC_KDF_SHA384 --+#endif --+#if defined(CONFIG_HMAC_SHA512_KDF) --+#define CRYPTO_MBEDTLS_HMAC_KDF_SHA512 --+#endif --+ --+#if defined(EAP_FAST) || defined(EAP_FAST_DYNAMIC) || defined(EAP_SERVER_FAST) \ --+ || defined(EAP_TEAP) || defined(EAP_TEAP_DYNAMIC) || defined(EAP_SERVER_FAST) --+#define CRYPTO_MBEDTLS_SHA1_T_PRF --+#endif --+ --+#if defined(CONFIG_DES) --+#define CRYPTO_MBEDTLS_DES_ENCRYPT --+#endif /* des_encrypt() */ --+ --+#if !defined(CONFIG_NO_PBKDF2) --+#define CRYPTO_MBEDTLS_PBKDF2_SHA1 --+#endif /* pbkdf2_sha1() */ --+ --+#if defined(EAP_IKEV2) \ --+ || defined(EAP_IKEV2_DYNAMIC) \ --+ || defined(EAP_SERVER_IKEV2) /* CONFIG_EAP_IKEV2=y */ --+#define CRYPTO_MBEDTLS_CRYPTO_CIPHER --+#endif /* crypto_cipher_*() */ --+ --+#if defined(EAP_PWD) || defined(EAP_SERVER_PWD) /* CONFIG_EAP_PWD=y */ --+#define CRYPTO_MBEDTLS_CRYPTO_HASH --+#endif /* crypto_hash_*() */ --+ --+#if defined(EAP_PWD) || defined(EAP_SERVER_PWD) /* CONFIG_EAP_PWD=y */ \ --+ || defined(CONFIG_SAE) /* CONFIG_SAE=y */ --+#define CRYPTO_MBEDTLS_CRYPTO_BIGNUM --+#endif /* crypto_bignum_*() */ --+ --+#if defined(EAP_PWD) /* CONFIG_EAP_PWD=y */ \ --+ || defined(EAP_EKE) /* CONFIG_EAP_EKE=y */ \ --+ || defined(EAP_EKE_DYNAMIC) /* CONFIG_EAP_EKE=y */ \ --+ || defined(EAP_SERVER_EKE) /* CONFIG_EAP_EKE=y */ \ --+ || defined(EAP_IKEV2) /* CONFIG_EAP_IKEV2y */ \ --+ || defined(EAP_IKEV2_DYNAMIC)/* CONFIG_EAP_IKEV2=y */ \ --+ || defined(EAP_SERVER_IKEV2) /* CONFIG_EAP_IKEV2=y */ \ --+ || defined(CONFIG_SAE) /* CONFIG_SAE=y */ \ --+ || defined(CONFIG_WPS) /* CONFIG_WPS=y */ --+#define CRYPTO_MBEDTLS_CRYPTO_DH --+#if defined(CONFIG_WPS_NFC) --+#define CRYPTO_MBEDTLS_DH5_INIT_FIXED --+#endif /* dh5_init_fixed() */ --+#endif /* crypto_dh_*() */ --+ --+#if !defined(CONFIG_NO_WPA) /* CONFIG_NO_WPA= */ --+#define CRYPTO_MBEDTLS_CRYPTO_ECDH --+#endif /* crypto_ecdh_*() */ --+ --+#if defined(CONFIG_ECC) --+#define CRYPTO_MBEDTLS_CRYPTO_BIGNUM --+#define CRYPTO_MBEDTLS_CRYPTO_EC --+#endif /* crypto_ec_*() crypto_ec_key_*() */ --+ --+#if defined(CONFIG_DPP) /* CONFIG_DPP=y */ --+#define CRYPTO_MBEDTLS_CRYPTO_EC_DPP /* extra for DPP */ --+#define CRYPTO_MBEDTLS_CRYPTO_CSR --+#endif /* crypto_csr_*() */ --+ --+#if defined(CONFIG_DPP3) /* CONFIG_DPP3=y */ --+#define CRYPTO_MBEDTLS_CRYPTO_HPKE --+#endif --+ --+#if defined(CONFIG_DPP2) /* CONFIG_DPP2=y */ --+#define CRYPTO_MBEDTLS_CRYPTO_PKCS7 --+#endif /* crypto_pkcs7_*() */ --+ --+#if defined(EAP_SIM) || defined(EAP_SIM_DYNAMIC) || defined(EAP_SERVER_SIM) \ --+ || defined(EAP_AKA) || defined(EAP_AKA_DYNAMIC) || defined(EAP_SERVER_AKA) \ --+ || defined(CONFIG_AP) || defined(HOSTAPD) --+/* CONFIG_EAP_SIM=y CONFIG_EAP_AKA=y CONFIG_AP=y HOSTAPD */ --+#if defined(CRYPTO_RSA_OAEP_SHA256) --+#define CRYPTO_MBEDTLS_CRYPTO_RSA --+#endif --+#endif /* crypto_rsa_*() */ --+ --+ --+static int ctr_drbg_init_state; --+static mbedtls_ctr_drbg_context ctr_drbg; --+static mbedtls_entropy_context entropy; --+ --+#ifdef CRYPTO_MBEDTLS_CRYPTO_BIGNUM --+#include --+static mbedtls_mpi mpi_sw_A; --+#endif --+ --+__attribute_cold__ --+__attribute_noinline__ --+static mbedtls_ctr_drbg_context * ctr_drbg_init(void) --+{ --+ mbedtls_ctr_drbg_init(&ctr_drbg); --+ mbedtls_entropy_init(&entropy); --+ if (mbedtls_ctr_drbg_seed(&ctr_drbg, mbedtls_entropy_func, &entropy, --+ NULL, 0)) { --+ wpa_printf(MSG_ERROR, "Init of random number generator failed"); --+ /* XXX: abort? */ --+ } --+ else --+ ctr_drbg_init_state = 1; --+ --+ return &ctr_drbg; --+} --+ --+__attribute_cold__ --+void crypto_unload(void) --+{ --+ if (ctr_drbg_init_state) { --+ mbedtls_ctr_drbg_free(&ctr_drbg); --+ mbedtls_entropy_free(&entropy); --+ #ifdef CRYPTO_MBEDTLS_CRYPTO_BIGNUM --+ mbedtls_mpi_free(&mpi_sw_A); --+ #endif --+ ctr_drbg_init_state = 0; --+ } --+} --+ --+/* init ctr_drbg on first use --+ * crypto_global_init() and crypto_global_deinit() are not available here --+ * (available only when CONFIG_TLS=internal, which is not CONFIG_TLS=mbedtls) */ --+mbedtls_ctr_drbg_context * crypto_mbedtls_ctr_drbg(void); /*(not in header)*/ --+inline --+mbedtls_ctr_drbg_context * crypto_mbedtls_ctr_drbg(void) --+{ --+ return ctr_drbg_init_state ? &ctr_drbg : ctr_drbg_init(); --+} --+ --+#ifdef CRYPTO_MBEDTLS_CONFIG_FIPS --+int crypto_get_random(void *buf, size_t len) --+{ --+ return mbedtls_ctr_drbg_random(crypto_mbedtls_ctr_drbg(),buf,len) ? -1 : 0; --+} --+#endif --+ --+ --+#if 1 --+ --+/* tradeoff: slightly smaller code size here at cost of slight increase --+ * in instructions and function calls at runtime versus the expanded --+ * per-message-digest code that follows in #else (~0.5 kib .text larger) */ --+ --+__attribute_noinline__ --+static int md_vector(size_t num_elem, const u8 *addr[], const size_t *len, --+ u8 *mac, mbedtls_md_type_t md_type) --+{ --+ mbedtls_md_context_t ctx; --+ mbedtls_md_init(&ctx); --+ if (mbedtls_md_setup(&ctx, mbedtls_md_info_from_type(md_type), 0) != 0){ --+ mbedtls_md_free(&ctx); --+ return -1; --+ } --+ mbedtls_md_starts(&ctx); --+ for (size_t i = 0; i < num_elem; ++i) --+ mbedtls_md_update(&ctx, addr[i], len[i]); --+ mbedtls_md_finish(&ctx, mac); --+ mbedtls_md_free(&ctx); --+ return 0; --+} --+ --+#ifdef MBEDTLS_SHA512_C --+int sha512_vector(size_t num_elem, const u8 *addr[], const size_t *len, u8 *mac) --+{ --+ return md_vector(num_elem, addr, len, mac, MBEDTLS_MD_SHA512); --+} --+ --+int sha384_vector(size_t num_elem, const u8 *addr[], const size_t *len, u8 *mac) --+{ --+ return md_vector(num_elem, addr, len, mac, MBEDTLS_MD_SHA384); --+} --+#endif --+ --+#ifdef MBEDTLS_SHA256_C --+int sha256_vector(size_t num_elem, const u8 *addr[], const size_t *len, u8 *mac) --+{ --+ return md_vector(num_elem, addr, len, mac, MBEDTLS_MD_SHA256); --+} --+#endif --+ --+#ifdef MBEDTLS_SHA1_C --+int sha1_vector(size_t num_elem, const u8 *addr[], const size_t *len, u8 *mac) --+{ --+ return md_vector(num_elem, addr, len, mac, MBEDTLS_MD_SHA1); --+} --+#endif --+ --+#ifdef MBEDTLS_MD5_C --+int md5_vector(size_t num_elem, const u8 *addr[], const size_t *len, u8 *mac) --+{ --+ return md_vector(num_elem, addr, len, mac, MBEDTLS_MD_MD5); --+} --+#endif --+ --+#ifdef MBEDTLS_MD4_C --+#include --+int md4_vector(size_t num_elem, const u8 *addr[], const size_t *len, u8 *mac) --+{ --+ return md_vector(num_elem, addr, len, mac, MBEDTLS_MD_MD4); --+} --+#endif --+ --+#else /* expanded per-message-digest functions */ --+ --+#ifdef MBEDTLS_SHA512_C --+#include --+__attribute_noinline__ --+static int sha384_512_vector(size_t num_elem, const u8 *addr[], --+ const size_t *len, u8 *mac, int is384) --+{ --+ struct mbedtls_sha512_context ctx; --+ mbedtls_sha512_init(&ctx); --+ #if MBEDTLS_VERSION_MAJOR >= 3 --+ mbedtls_sha512_starts(&ctx, is384); --+ for (size_t i = 0; i < num_elem; ++i) --+ mbedtls_sha512_update(&ctx, addr[i], len[i]); --+ mbedtls_sha512_finish(&ctx, mac); --+ #else --+ mbedtls_sha512_starts_ret(&ctx, is384); --+ for (size_t i = 0; i < num_elem; ++i) --+ mbedtls_sha512_update_ret(&ctx, addr[i], len[i]); --+ mbedtls_sha512_finish_ret(&ctx, mac); --+ #endif --+ mbedtls_sha512_free(&ctx); --+ return 0; --+} --+ --+int sha512_vector(size_t num_elem, const u8 *addr[], const size_t *len, u8 *mac) --+{ --+ return sha384_512_vector(num_elem, addr, len, mac, 0); --+} --+ --+int sha384_vector(size_t num_elem, const u8 *addr[], const size_t *len, u8 *mac) --+{ --+ return sha384_512_vector(num_elem, addr, len, mac, 1); --+} --+#endif --+ --+#ifdef MBEDTLS_SHA256_C --+#include --+int sha256_vector(size_t num_elem, const u8 *addr[], const size_t *len, u8 *mac) --+{ --+ struct mbedtls_sha256_context ctx; --+ mbedtls_sha256_init(&ctx); --+ #if MBEDTLS_VERSION_MAJOR >= 3 --+ mbedtls_sha256_starts(&ctx, 0); --+ for (size_t i = 0; i < num_elem; ++i) --+ mbedtls_sha256_update(&ctx, addr[i], len[i]); --+ mbedtls_sha256_finish(&ctx, mac); --+ #else --+ mbedtls_sha256_starts_ret(&ctx, 0); --+ for (size_t i = 0; i < num_elem; ++i) --+ mbedtls_sha256_update_ret(&ctx, addr[i], len[i]); --+ mbedtls_sha256_finish_ret(&ctx, mac); --+ #endif --+ mbedtls_sha256_free(&ctx); --+ return 0; --+} --+#endif --+ --+#ifdef MBEDTLS_SHA1_C --+#include --+int sha1_vector(size_t num_elem, const u8 *addr[], const size_t *len, u8 *mac) --+{ --+ struct mbedtls_sha1_context ctx; --+ mbedtls_sha1_init(&ctx); --+ #if MBEDTLS_VERSION_MAJOR >= 3 --+ mbedtls_sha1_starts(&ctx); --+ for (size_t i = 0; i < num_elem; ++i) --+ mbedtls_sha1_update(&ctx, addr[i], len[i]); --+ mbedtls_sha1_finish(&ctx, mac); --+ #else --+ mbedtls_sha1_starts_ret(&ctx); --+ for (size_t i = 0; i < num_elem; ++i) --+ mbedtls_sha1_update_ret(&ctx, addr[i], len[i]); --+ mbedtls_sha1_finish_ret(&ctx, mac); --+ #endif --+ mbedtls_sha1_free(&ctx); --+ return 0; --+} --+#endif --+ --+#ifdef MBEDTLS_MD5_C --+#include --+int md5_vector(size_t num_elem, const u8 *addr[], const size_t *len, u8 *mac) --+{ --+ struct mbedtls_md5_context ctx; --+ mbedtls_md5_init(&ctx); --+ #if MBEDTLS_VERSION_MAJOR >= 3 --+ mbedtls_md5_starts(&ctx); --+ for (size_t i = 0; i < num_elem; ++i) --+ mbedtls_md5_update(&ctx, addr[i], len[i]); --+ mbedtls_md5_finish(&ctx, mac); --+ #else --+ mbedtls_md5_starts_ret(&ctx); --+ for (size_t i = 0; i < num_elem; ++i) --+ mbedtls_md5_update_ret(&ctx, addr[i], len[i]); --+ mbedtls_md5_finish_ret(&ctx, mac); --+ #endif --+ mbedtls_md5_free(&ctx); --+ return 0; --+} --+#endif --+ --+#ifdef MBEDTLS_MD4_C --+#include --+int md4_vector(size_t num_elem, const u8 *addr[], const size_t *len, u8 *mac) --+{ --+ struct mbedtls_md4_context ctx; --+ mbedtls_md4_init(&ctx); --+ mbedtls_md4_starts_ret(&ctx); --+ for (size_t i = 0; i < num_elem; ++i) --+ mbedtls_md4_update_ret(&ctx, addr[i], len[i]); --+ mbedtls_md4_finish_ret(&ctx, mac); --+ mbedtls_md4_free(&ctx); --+ return 0; --+} --+#endif --+ --+#endif /* expanded per-message-digest functions */ --+ --+ --+__attribute_noinline__ --+static int hmac_vector(const u8 *key, size_t key_len, size_t num_elem, --+ const u8 *addr[], const size_t *len, u8 *mac, --+ mbedtls_md_type_t md_type) --+{ --+ mbedtls_md_context_t ctx; --+ mbedtls_md_init(&ctx); --+ if (mbedtls_md_setup(&ctx, mbedtls_md_info_from_type(md_type), 1) != 0){ --+ mbedtls_md_free(&ctx); --+ return -1; --+ } --+ mbedtls_md_hmac_starts(&ctx, key, key_len); --+ for (size_t i = 0; i < num_elem; ++i) --+ mbedtls_md_hmac_update(&ctx, addr[i], len[i]); --+ mbedtls_md_hmac_finish(&ctx, mac); --+ mbedtls_md_free(&ctx); --+ return 0; --+} --+ --+#ifdef MBEDTLS_SHA512_C --+int hmac_sha512_vector(const u8 *key, size_t key_len, size_t num_elem, --+ const u8 *addr[], const size_t *len, u8 *mac) --+{ --+ return hmac_vector(key, key_len, num_elem, addr, len, mac, --+ MBEDTLS_MD_SHA512); --+} --+ --+int hmac_sha512(const u8 *key, size_t key_len, const u8 *data, size_t data_len, --+ u8 *mac) --+{ --+ return hmac_vector(key, key_len, 1, &data, &data_len, mac, --+ MBEDTLS_MD_SHA512); --+} --+ --+int hmac_sha384_vector(const u8 *key, size_t key_len, size_t num_elem, --+ const u8 *addr[], const size_t *len, u8 *mac) --+{ --+ return hmac_vector(key, key_len, num_elem, addr, len, mac, --+ MBEDTLS_MD_SHA384); --+} --+ --+int hmac_sha384(const u8 *key, size_t key_len, const u8 *data, size_t data_len, --+ u8 *mac) --+{ --+ return hmac_vector(key, key_len, 1, &data, &data_len, mac, --+ MBEDTLS_MD_SHA384); --+} --+#endif --+ --+#ifdef MBEDTLS_SHA256_C --+int hmac_sha256_vector(const u8 *key, size_t key_len, size_t num_elem, --+ const u8 *addr[], const size_t *len, u8 *mac) --+{ --+ return hmac_vector(key, key_len, num_elem, addr, len, mac, --+ MBEDTLS_MD_SHA256); --+} --+ --+int hmac_sha256(const u8 *key, size_t key_len, const u8 *data, size_t data_len, --+ u8 *mac) --+{ --+ return hmac_vector(key, key_len, 1, &data, &data_len, mac, --+ MBEDTLS_MD_SHA256); --+} --+#endif --+ --+#ifdef MBEDTLS_SHA1_C --+int hmac_sha1_vector(const u8 *key, size_t key_len, size_t num_elem, --+ const u8 *addr[], const size_t *len, u8 *mac) --+{ --+ return hmac_vector(key, key_len, num_elem, addr, len, mac, --+ MBEDTLS_MD_SHA1); --+} --+ --+int hmac_sha1(const u8 *key, size_t key_len, const u8 *data, size_t data_len, --+ u8 *mac) --+{ --+ return hmac_vector(key, key_len, 1, &data, &data_len, mac, --+ MBEDTLS_MD_SHA1); --+} --+#endif --+ --+#ifdef MBEDTLS_MD5_C --+int hmac_md5_vector(const u8 *key, size_t key_len, size_t num_elem, --+ const u8 *addr[], const size_t *len, u8 *mac) --+{ --+ return hmac_vector(key, key_len, num_elem, addr, len, mac, --+ MBEDTLS_MD_MD5); --+} --+ --+int hmac_md5(const u8 *key, size_t key_len, const u8 *data, size_t data_len, --+ u8 *mac) --+{ --+ return hmac_vector(key, key_len, 1, &data, &data_len, mac, --+ MBEDTLS_MD_MD5); --+} --+#endif --+ --+ --+#if defined(MBEDTLS_SHA256_C) || defined(MBEDTLS_SHA512_C) --+ --+#if defined(CRYPTO_MBEDTLS_HMAC_KDF_SHA256) \ --+ || defined(CRYPTO_MBEDTLS_HMAC_KDF_SHA384) \ --+ || defined(CRYPTO_MBEDTLS_HMAC_KDF_SHA512) --+ --+#include --+ --+/* sha256-kdf.c sha384-kdf.c sha512-kdf.c */ --+ --+/* HMAC-SHA256 KDF (RFC 5295) and HKDF-Expand(SHA256) (RFC 5869) */ --+/* HMAC-SHA384 KDF (RFC 5295) and HKDF-Expand(SHA384) (RFC 5869) */ --+/* HMAC-SHA512 KDF (RFC 5295) and HKDF-Expand(SHA512) (RFC 5869) */ --+__attribute_noinline__ --+static int hmac_kdf_expand(const u8 *prk, size_t prk_len, --+ const char *label, const u8 *info, size_t info_len, --+ u8 *okm, size_t okm_len, mbedtls_md_type_t md_type) --+{ --+ const mbedtls_md_info_t *md_info = mbedtls_md_info_from_type(md_type); --+ #ifdef MBEDTLS_HKDF_C --+ if (label == NULL) /* RFC 5869 HKDF-Expand when (label == NULL) */ --+ return mbedtls_hkdf_expand(md_info, prk, prk_len, info, --+ info_len, okm, okm_len) ? -1 : 0; --+ #endif --+ --+ const size_t mac_len = mbedtls_md_get_size(md_info); --+ /* okm_len must not exceed 255 times hash len (RFC 5869 Section 2.3) */ --+ if (okm_len > ((mac_len << 8) - mac_len)) --+ return -1; --+ --+ mbedtls_md_context_t ctx; --+ mbedtls_md_init(&ctx); --+ if (mbedtls_md_setup(&ctx, md_info, 1) != 0) { --+ mbedtls_md_free(&ctx); --+ return -1; --+ } --+ mbedtls_md_hmac_starts(&ctx, prk, prk_len); --+ --+ u8 iter = 1; --+ const u8 *addr[4] = { okm, (const u8 *)label, info, &iter }; --+ size_t len[4] = { 0, label ? os_strlen(label)+1 : 0, info_len, 1 }; --+ --+ for (; okm_len >= mac_len; okm_len -= mac_len, ++iter) { --+ for (size_t i = 0; i < ARRAY_SIZE(addr); ++i) --+ mbedtls_md_hmac_update(&ctx, addr[i], len[i]); --+ mbedtls_md_hmac_finish(&ctx, okm); --+ mbedtls_md_hmac_reset(&ctx); --+ addr[0] = okm; --+ okm += mac_len; --+ len[0] = mac_len; /*(include digest in subsequent rounds)*/ --+ } --+ --+ if (okm_len) { --+ u8 hash[MBEDTLS_MD_MAX_SIZE]; --+ for (size_t i = 0; i < ARRAY_SIZE(addr); ++i) --+ mbedtls_md_hmac_update(&ctx, addr[i], len[i]); --+ mbedtls_md_hmac_finish(&ctx, hash); --+ os_memcpy(okm, hash, okm_len); --+ forced_memzero(hash, mac_len); --+ } --+ --+ mbedtls_md_free(&ctx); --+ return 0; --+} --+ --+#ifdef MBEDTLS_SHA512_C --+#ifdef CRYPTO_MBEDTLS_HMAC_KDF_SHA512 --+int hmac_sha512_kdf(const u8 *secret, size_t secret_len, --+ const char *label, const u8 *seed, size_t seed_len, --+ u8 *out, size_t outlen) --+{ --+ return hmac_kdf_expand(secret, secret_len, label, seed, seed_len, --+ out, outlen, MBEDTLS_MD_SHA512); --+} --+#endif --+ --+#ifdef CRYPTO_MBEDTLS_HMAC_KDF_SHA384 --+int hmac_sha384_kdf(const u8 *secret, size_t secret_len, --+ const char *label, const u8 *seed, size_t seed_len, --+ u8 *out, size_t outlen) --+{ --+ return hmac_kdf_expand(secret, secret_len, label, seed, seed_len, --+ out, outlen, MBEDTLS_MD_SHA384); --+} --+#endif --+#endif --+ --+#ifdef MBEDTLS_SHA256_C --+#ifdef CRYPTO_MBEDTLS_HMAC_KDF_SHA256 --+int hmac_sha256_kdf(const u8 *secret, size_t secret_len, --+ const char *label, const u8 *seed, size_t seed_len, --+ u8 *out, size_t outlen) --+{ --+ return hmac_kdf_expand(secret, secret_len, label, seed, seed_len, --+ out, outlen, MBEDTLS_MD_SHA256); --+} --+#endif --+#endif --+ --+#endif /* CRYPTO_MBEDTLS_HMAC_KDF_* */ --+ --+ --+/* sha256-prf.c sha384-prf.c sha512-prf.c */ --+ --+/* hmac_prf_bits - IEEE Std 802.11ac-2013, 11.6.1.7.2 Key derivation function */ --+__attribute_noinline__ --+static int hmac_prf_bits(const u8 *key, size_t key_len, const char *label, --+ const u8 *data, size_t data_len, u8 *buf, --+ size_t buf_len_bits, mbedtls_md_type_t md_type) --+{ --+ mbedtls_md_context_t ctx; --+ mbedtls_md_init(&ctx); --+ const mbedtls_md_info_t *md_info = mbedtls_md_info_from_type(md_type); --+ if (mbedtls_md_setup(&ctx, md_info, 1) != 0) { --+ mbedtls_md_free(&ctx); --+ return -1; --+ } --+ mbedtls_md_hmac_starts(&ctx, key, key_len); --+ --+ u16 ctr, n_le = host_to_le16(buf_len_bits); --+ const u8 * const addr[] = { (u8 *)&ctr,(u8 *)label,data,(u8 *)&n_le }; --+ const size_t len[] = { 2, os_strlen(label), data_len, 2 }; --+ const size_t mac_len = mbedtls_md_get_size(md_info); --+ size_t buf_len = (buf_len_bits + 7) / 8; --+ for (ctr = 1; buf_len >= mac_len; buf_len -= mac_len, ++ctr) { --+ #if __BYTE_ORDER == __BIG_ENDIAN --+ ctr = host_to_le16(ctr); --+ #endif --+ for (size_t i = 0; i < ARRAY_SIZE(addr); ++i) --+ mbedtls_md_hmac_update(&ctx, addr[i], len[i]); --+ mbedtls_md_hmac_finish(&ctx, buf); --+ mbedtls_md_hmac_reset(&ctx); --+ buf += mac_len; --+ #if __BYTE_ORDER == __BIG_ENDIAN --+ ctr = le_to_host16(ctr); --+ #endif --+ } --+ --+ if (buf_len) { --+ u8 hash[MBEDTLS_MD_MAX_SIZE]; --+ #if __BYTE_ORDER == __BIG_ENDIAN --+ ctr = host_to_le16(ctr); --+ #endif --+ for (size_t i = 0; i < ARRAY_SIZE(addr); ++i) --+ mbedtls_md_hmac_update(&ctx, addr[i], len[i]); --+ mbedtls_md_hmac_finish(&ctx, hash); --+ os_memcpy(buf, hash, buf_len); --+ buf += buf_len; --+ forced_memzero(hash, mac_len); --+ } --+ --+ /* Mask out unused bits in last octet if it does not use all the bits */ --+ if ((buf_len_bits &= 0x7)) --+ buf[-1] &= (u8)(0xff << (8 - buf_len_bits)); --+ --+ mbedtls_md_free(&ctx); --+ return 0; --+} --+ --+#ifdef MBEDTLS_SHA512_C --+int sha512_prf(const u8 *key, size_t key_len, const char *label, --+ const u8 *data, size_t data_len, u8 *buf, size_t buf_len) --+{ --+ return hmac_prf_bits(key, key_len, label, data, data_len, buf, --+ buf_len * 8, MBEDTLS_MD_SHA512); --+} --+ --+int sha384_prf(const u8 *key, size_t key_len, const char *label, --+ const u8 *data, size_t data_len, u8 *buf, size_t buf_len) --+{ --+ return hmac_prf_bits(key, key_len, label, data, data_len, buf, --+ buf_len * 8, MBEDTLS_MD_SHA384); --+} --+#endif --+ --+#ifdef MBEDTLS_SHA256_C --+int sha256_prf(const u8 *key, size_t key_len, const char *label, --+ const u8 *data, size_t data_len, u8 *buf, size_t buf_len) --+{ --+ return hmac_prf_bits(key, key_len, label, data, data_len, buf, --+ buf_len * 8, MBEDTLS_MD_SHA256); --+} --+ --+int sha256_prf_bits(const u8 *key, size_t key_len, const char *label, --+ const u8 *data, size_t data_len, u8 *buf, --+ size_t buf_len_bits) --+{ --+ return hmac_prf_bits(key, key_len, label, data, data_len, buf, --+ buf_len_bits, MBEDTLS_MD_SHA256); --+} --+#endif --+ --+#endif /* MBEDTLS_SHA256_C || MBEDTLS_SHA512_C */ --+ --+ --+#ifdef MBEDTLS_SHA1_C --+ --+/* sha1-prf.c */ --+ --+/* sha1_prf - SHA1-based Pseudo-Random Function (PRF) (IEEE 802.11i, 8.5.1.1) */ --+ --+int sha1_prf(const u8 *key, size_t key_len, const char *label, --+ const u8 *data, size_t data_len, u8 *buf, size_t buf_len) --+{ --+ /*(note: algorithm differs from hmac_prf_bits() */ --+ /*(note: smaller code size instead of expanding hmac_sha1_vector() --+ * as is done in hmac_prf_bits(); not expecting large num of loops) */ --+ u8 counter = 0; --+ const u8 *addr[] = { (u8 *)label, data, &counter }; --+ const size_t len[] = { os_strlen(label)+1, data_len, 1 }; --+ --+ for (; buf_len >= SHA1_MAC_LEN; buf_len -= SHA1_MAC_LEN, ++counter) { --+ if (hmac_sha1_vector(key, key_len, 3, addr, len, buf)) --+ return -1; --+ buf += SHA1_MAC_LEN; --+ } --+ --+ if (buf_len) { --+ u8 hash[SHA1_MAC_LEN]; --+ if (hmac_sha1_vector(key, key_len, 3, addr, len, hash)) --+ return -1; --+ os_memcpy(buf, hash, buf_len); --+ forced_memzero(hash, sizeof(hash)); --+ } --+ --+ return 0; --+} --+ --+#ifdef CRYPTO_MBEDTLS_SHA1_T_PRF --+ --+/* sha1-tprf.c */ --+ --+/* sha1_t_prf - EAP-FAST Pseudo-Random Function (T-PRF) (RFC 4851,Section 5.5)*/ --+ --+int sha1_t_prf(const u8 *key, size_t key_len, const char *label, --+ const u8 *seed, size_t seed_len, u8 *buf, size_t buf_len) --+{ --+ /*(note: algorithm differs from hmac_prf_bits() and hmac_kdf() above)*/ --+ /*(note: smaller code size instead of expanding hmac_sha1_vector() --+ * as is done in hmac_prf_bits(); not expecting large num of loops) */ --+ u8 ctr; --+ u16 olen = host_to_be16(buf_len); --+ const u8 *addr[] = { buf, (u8 *)label, seed, (u8 *)&olen, &ctr }; --+ size_t len[] = { 0, os_strlen(label)+1, seed_len, 2, 1 }; --+ --+ for (ctr = 1; buf_len >= SHA1_MAC_LEN; buf_len -= SHA1_MAC_LEN, ++ctr) { --+ if (hmac_sha1_vector(key, key_len, 5, addr, len, buf)) --+ return -1; --+ addr[0] = buf; --+ buf += SHA1_MAC_LEN; --+ len[0] = SHA1_MAC_LEN; /*(include digest in subsequent rounds)*/ --+ } --+ --+ if (buf_len) { --+ u8 hash[SHA1_MAC_LEN]; --+ if (hmac_sha1_vector(key, key_len, 5, addr, len, hash)) --+ return -1; --+ os_memcpy(buf, hash, buf_len); --+ forced_memzero(hash, sizeof(hash)); --+ } --+ --+ return 0; --+} --+ --+#endif /* CRYPTO_MBEDTLS_SHA1_T_PRF */ --+ --+#endif /* MBEDTLS_SHA1_C */ --+ --+ --+#ifdef CRYPTO_MBEDTLS_DES_ENCRYPT --+#ifdef MBEDTLS_DES_C --+#include --+int des_encrypt(const u8 *clear, const u8 *key, u8 *cypher) --+{ --+ u8 pkey[8], next, tmp; --+ int i; --+ --+ /* Add parity bits to the key */ --+ next = 0; --+ for (i = 0; i < 7; i++) { --+ tmp = key[i]; --+ pkey[i] = (tmp >> i) | next | 1; --+ next = tmp << (7 - i); --+ } --+ pkey[i] = next | 1; --+ --+ mbedtls_des_context des; --+ mbedtls_des_init(&des); --+ int ret = mbedtls_des_setkey_enc(&des, pkey) --+ || mbedtls_des_crypt_ecb(&des, clear, cypher) ? -1 : 0; --+ mbedtls_des_free(&des); --+ return ret; --+} --+#else --+#include "des-internal.c"/* pull in hostap local implementation */ --+#endif --+#endif --+ --+ --+#ifdef CRYPTO_MBEDTLS_PBKDF2_SHA1 --+/* sha1-pbkdf2.c */ --+#include --+int pbkdf2_sha1(const char *passphrase, const u8 *ssid, size_t ssid_len, --+ int iterations, u8 *buf, size_t buflen) --+{ --+ #if MBEDTLS_VERSION_NUMBER >= 0x03020200 /* mbedtls 3.2.2 */ --+ return mbedtls_pkcs5_pbkdf2_hmac_ext(MBEDTLS_MD_SHA1, --+ (const u8 *)passphrase, os_strlen(passphrase), --+ ssid, ssid_len, iterations, 32, buf) ? -1 : 0; --+ #else --+ const mbedtls_md_info_t *md_info; --+ md_info = mbedtls_md_info_from_type(MBEDTLS_MD_SHA1); --+ if (md_info == NULL) --+ return -1; --+ mbedtls_md_context_t ctx; --+ mbedtls_md_init(&ctx); --+ int ret = mbedtls_md_setup(&ctx, md_info, 1) --+ || mbedtls_pkcs5_pbkdf2_hmac(&ctx, --+ (const u8 *)passphrase, os_strlen(passphrase), --+ ssid, ssid_len, iterations, 32, buf) ? -1 : 0; --+ mbedtls_md_free(&ctx); --+ return ret; --+ #endif --+} --+#endif --+ --+ --+/*#include "aes.h"*/ /* prototypes also included in "crypto.h" */ --+ --+static void *aes_crypt_init_mode(const u8 *key, size_t len, int mode) --+{ --+ mbedtls_aes_context *aes = os_malloc(sizeof(*aes)); --+ if (!aes) --+ return NULL; --+ --+ mbedtls_aes_init(aes); --+ if ((mode == MBEDTLS_AES_ENCRYPT --+ ? mbedtls_aes_setkey_enc(aes, key, len * 8) --+ : mbedtls_aes_setkey_dec(aes, key, len * 8)) == 0) --+ return aes; --+ --+ mbedtls_aes_free(aes); --+ os_free(aes); --+ return NULL; --+} --+ --+void *aes_encrypt_init(const u8 *key, size_t len) --+{ --+ return aes_crypt_init_mode(key, len, MBEDTLS_AES_ENCRYPT); --+} --+ --+int aes_encrypt(void *ctx, const u8 *plain, u8 *crypt) --+{ --+ return mbedtls_aes_crypt_ecb(ctx, MBEDTLS_AES_ENCRYPT, plain, crypt); --+} --+ --+void aes_encrypt_deinit(void *ctx) --+{ --+ mbedtls_aes_free(ctx); --+ os_free(ctx); --+} --+ --+void *aes_decrypt_init(const u8 *key, size_t len) --+{ --+ return aes_crypt_init_mode(key, len, MBEDTLS_AES_DECRYPT); --+} --+ --+int aes_decrypt(void *ctx, const u8 *crypt, u8 *plain) --+{ --+ return mbedtls_aes_crypt_ecb(ctx, MBEDTLS_AES_DECRYPT, crypt, plain); --+} --+ --+void aes_decrypt_deinit(void *ctx) --+{ --+ mbedtls_aes_free(ctx); --+ os_free(ctx); --+} --+ --+ --+#include "aes_wrap.h" --+ --+ --+#ifdef MBEDTLS_NIST_KW_C --+ --+#include --+ --+/* aes-wrap.c */ --+int aes_wrap(const u8 *kek, size_t kek_len, int n, const u8 *plain, u8 *cipher) --+{ --+ mbedtls_nist_kw_context ctx; --+ mbedtls_nist_kw_init(&ctx); --+ size_t olen; --+ int ret = mbedtls_nist_kw_setkey(&ctx, MBEDTLS_CIPHER_ID_AES, --+ kek, kek_len*8, 1) --+ || mbedtls_nist_kw_wrap(&ctx, MBEDTLS_KW_MODE_KW, plain, n*8, --+ cipher, &olen, (n+1)*8) ? -1 : 0; --+ mbedtls_nist_kw_free(&ctx); --+ return ret; --+} --+ --+/* aes-unwrap.c */ --+int aes_unwrap(const u8 *kek, size_t kek_len, int n, const u8 *cipher, u8 *plain) --+{ --+ mbedtls_nist_kw_context ctx; --+ mbedtls_nist_kw_init(&ctx); --+ size_t olen; --+ int ret = mbedtls_nist_kw_setkey(&ctx, MBEDTLS_CIPHER_ID_AES, --+ kek, kek_len*8, 0) --+ || mbedtls_nist_kw_unwrap(&ctx, MBEDTLS_KW_MODE_KW, cipher, --+ (n+1)*8, plain, &olen, n*8) ? -1 : 0; --+ mbedtls_nist_kw_free(&ctx); --+ return ret; --+} --+ --+#else --+ --+#ifndef CRYPTO_MBEDTLS_CONFIG_FIPS --+#include "aes-wrap.c" /* pull in hostap local implementation */ --+#include "aes-unwrap.c" /* pull in hostap local implementation */ --+#endif --+ --+#endif /* MBEDTLS_NIST_KW_C */ --+ --+ --+#ifdef MBEDTLS_CMAC_C --+ --+/* aes-omac1.c */ --+ --+#include --+ --+int omac1_aes_vector( --+ const u8 *key, size_t key_len, size_t num_elem, const u8 *addr[], --+ const size_t *len, u8 *mac) --+{ --+ mbedtls_cipher_type_t cipher_type; --+ switch (key_len) { --+ case 16: cipher_type = MBEDTLS_CIPHER_AES_128_ECB; break; --+ case 24: cipher_type = MBEDTLS_CIPHER_AES_192_ECB; break; --+ case 32: cipher_type = MBEDTLS_CIPHER_AES_256_ECB; break; --+ default: return -1; --+ } --+ const mbedtls_cipher_info_t *cipher_info; --+ cipher_info = mbedtls_cipher_info_from_type(cipher_type); --+ if (cipher_info == NULL) --+ return -1; --+ --+ mbedtls_cipher_context_t ctx; --+ mbedtls_cipher_init(&ctx); --+ int ret = -1; --+ if (mbedtls_cipher_setup(&ctx, cipher_info) == 0 --+ && mbedtls_cipher_cmac_starts(&ctx, key, key_len*8) == 0) { --+ ret = 0; --+ for (size_t i = 0; i < num_elem && ret == 0; ++i) --+ ret = mbedtls_cipher_cmac_update(&ctx, addr[i], len[i]); --+ } --+ if (ret == 0) --+ ret = mbedtls_cipher_cmac_finish(&ctx, mac); --+ mbedtls_cipher_free(&ctx); --+ return ret ? -1 : 0; --+} --+ --+int omac1_aes_128_vector(const u8 *key, size_t num_elem, --+ const u8 *addr[], const size_t *len, --+ u8 *mac) --+{ --+ return omac1_aes_vector(key, 16, num_elem, addr, len, mac); --+} --+ --+int omac1_aes_128(const u8 *key, const u8 *data, size_t data_len, u8 *mac) --+{ --+ return omac1_aes_vector(key, 16, 1, &data, &data_len, mac); --+} --+ --+int omac1_aes_256(const u8 *key, const u8 *data, size_t data_len, u8 *mac) --+{ --+ return omac1_aes_vector(key, 32, 1, &data, &data_len, mac); --+} --+ --+#else --+ --+#include "aes-omac1.c" /* pull in hostap local implementation */ --+ --+#ifndef MBEDTLS_AES_BLOCK_SIZE --+#define MBEDTLS_AES_BLOCK_SIZE 16 --+#endif --+ --+#endif /* MBEDTLS_CMAC_C */ --+ --+ --+/* These interfaces can be inefficient when used in loops, as the overhead of --+ * initialization each call is large for each block input (e.g. 16 bytes) */ --+ --+ --+/* aes-encblock.c */ --+int aes_128_encrypt_block(const u8 *key, const u8 *in, u8 *out) --+{ --+ mbedtls_aes_context aes; --+ mbedtls_aes_init(&aes); --+ int ret = mbedtls_aes_setkey_enc(&aes, key, 128) --+ || mbedtls_aes_crypt_ecb(&aes, MBEDTLS_AES_ENCRYPT, in, out) --+ ? -1 --+ : 0; --+ mbedtls_aes_free(&aes); --+ return ret; --+} --+ --+ --+/* aes-ctr.c */ --+int aes_ctr_encrypt(const u8 *key, size_t key_len, const u8 *nonce, --+ u8 *data, size_t data_len) --+{ --+ unsigned char counter[MBEDTLS_AES_BLOCK_SIZE]; --+ unsigned char stream_block[MBEDTLS_AES_BLOCK_SIZE]; --+ os_memcpy(counter, nonce, MBEDTLS_AES_BLOCK_SIZE);/*(must be writable)*/ --+ --+ mbedtls_aes_context ctx; --+ mbedtls_aes_init(&ctx); --+ size_t nc_off = 0; --+ int ret = mbedtls_aes_setkey_enc(&ctx, key, key_len*8) --+ || mbedtls_aes_crypt_ctr(&ctx, data_len, &nc_off, --+ counter, stream_block, --+ data, data) ? -1 : 0; --+ forced_memzero(stream_block, sizeof(stream_block)); --+ mbedtls_aes_free(&ctx); --+ return ret; --+} --+ --+int aes_128_ctr_encrypt(const u8 *key, const u8 *nonce, --+ u8 *data, size_t data_len) --+{ --+ return aes_ctr_encrypt(key, 16, nonce, data, data_len); --+} --+ --+ --+/* aes-cbc.c */ --+static int aes_128_cbc_oper(const u8 *key, const u8 *iv, --+ u8 *data, size_t data_len, int mode) --+{ --+ unsigned char ivec[MBEDTLS_AES_BLOCK_SIZE]; --+ os_memcpy(ivec, iv, MBEDTLS_AES_BLOCK_SIZE); /*(must be writable)*/ --+ --+ mbedtls_aes_context ctx; --+ mbedtls_aes_init(&ctx); --+ int ret = (mode == MBEDTLS_AES_ENCRYPT --+ ? mbedtls_aes_setkey_enc(&ctx, key, 128) --+ : mbedtls_aes_setkey_dec(&ctx, key, 128)) --+ || mbedtls_aes_crypt_cbc(&ctx, mode, data_len, ivec, data, data); --+ mbedtls_aes_free(&ctx); --+ return ret ? -1 : 0; --+} --+ --+int aes_128_cbc_encrypt(const u8 *key, const u8 *iv, u8 *data, size_t data_len) --+{ --+ return aes_128_cbc_oper(key, iv, data, data_len, MBEDTLS_AES_ENCRYPT); --+} --+ --+int aes_128_cbc_decrypt(const u8 *key, const u8 *iv, u8 *data, size_t data_len) --+{ --+ return aes_128_cbc_oper(key, iv, data, data_len, MBEDTLS_AES_DECRYPT); --+} --+ --+ --+/* --+ * Much of the following is documented in crypto.h as for CONFIG_TLS=internal --+ * but such comments are not accurate: --+ * --+ * "This function is only used with internal TLSv1 implementation --+ * (CONFIG_TLS=internal). If that is not used, the crypto wrapper does not need --+ * to implement this." --+ */ --+ --+ --+#ifdef CRYPTO_MBEDTLS_CRYPTO_CIPHER --+ --+#include --+ --+struct crypto_cipher --+{ --+ mbedtls_cipher_context_t ctx_enc; --+ mbedtls_cipher_context_t ctx_dec; --+}; --+ --+struct crypto_cipher * crypto_cipher_init(enum crypto_cipher_alg alg, --+ const u8 *iv, const u8 *key, --+ size_t key_len) --+{ --+ /* IKEv2 src/eap_common/ikev2_common.c:ikev2_{encr,decr}_encrypt() --+ * uses one of CRYPTO_CIPHER_ALG_AES or CRYPTO_CIPHER_ALG_3DES */ --+ --+ mbedtls_cipher_type_t cipher_type; --+ size_t iv_len; --+ switch (alg) { --+ #ifdef MBEDTLS_ARC4_C --+ #if 0 --+ case CRYPTO_CIPHER_ALG_RC4: --+ cipher_type = MBEDTLS_CIPHER_ARC4_128; --+ iv_len = 0; --+ break; --+ #endif --+ #endif --+ #ifdef MBEDTLS_AES_C --+ case CRYPTO_CIPHER_ALG_AES: --+ if (key_len == 16) cipher_type = MBEDTLS_CIPHER_AES_128_CTR; --+ if (key_len == 24) cipher_type = MBEDTLS_CIPHER_AES_192_CTR; --+ if (key_len == 32) cipher_type = MBEDTLS_CIPHER_AES_256_CTR; --+ iv_len = 16; --+ break; --+ #endif --+ #ifdef MBEDTLS_DES_C --+ case CRYPTO_CIPHER_ALG_3DES: --+ cipher_type = MBEDTLS_CIPHER_DES_EDE3_CBC; --+ iv_len = 8; --+ break; --+ #if 0 --+ case CRYPTO_CIPHER_ALG_DES: --+ cipher_type = MBEDTLS_CIPHER_DES_CBC; --+ iv_len = 8; --+ break; --+ #endif --+ #endif --+ default: --+ return NULL; --+ } --+ --+ const mbedtls_cipher_info_t *cipher_info; --+ cipher_info = mbedtls_cipher_info_from_type(cipher_type); --+ if (cipher_info == NULL) --+ return NULL; --+ --+ key_len *= 8; /* key_bitlen */ --+ #if 0 /*(were key_bitlen not already available)*/ --+ #if MBEDTLS_VERSION_NUMBER >= 0x03010000 /* mbedtls 3.1.0 */ --+ key_len = mbedtls_cipher_info_get_key_bitlen(cipher_info); --+ #else --+ key_len = cipher_info->MBEDTLS_PRIVATE(key_bitlen); --+ #endif --+ #endif --+ --+ #if 0 /*(were iv_len not known above, would need MBEDTLS_PRIVATE(iv_size))*/ --+ iv_len = cipher_info->MBEDTLS_PRIVATE(iv_size); --+ #endif --+ --+ struct crypto_cipher *ctx = os_malloc(sizeof(*ctx)); --+ if (!ctx) --+ return NULL; --+ --+ mbedtls_cipher_init(&ctx->ctx_enc); --+ mbedtls_cipher_init(&ctx->ctx_dec); --+ if ( mbedtls_cipher_setup(&ctx->ctx_enc,cipher_info) == 0 --+ && mbedtls_cipher_setup(&ctx->ctx_dec,cipher_info) == 0 --+ && mbedtls_cipher_setkey(&ctx->ctx_enc,key,key_len,MBEDTLS_ENCRYPT) == 0 --+ && mbedtls_cipher_setkey(&ctx->ctx_dec,key,key_len,MBEDTLS_DECRYPT) == 0 --+ && mbedtls_cipher_set_iv(&ctx->ctx_enc,iv,iv_len) == 0 --+ && mbedtls_cipher_set_iv(&ctx->ctx_dec,iv,iv_len) == 0 --+ && mbedtls_cipher_reset(&ctx->ctx_enc) == 0 --+ && mbedtls_cipher_reset(&ctx->ctx_dec) == 0) { --+ return ctx; --+ } --+ --+ mbedtls_cipher_free(&ctx->ctx_enc); --+ mbedtls_cipher_free(&ctx->ctx_dec); --+ os_free(ctx); --+ return NULL; --+} --+ --+int crypto_cipher_encrypt(struct crypto_cipher *ctx, --+ const u8 *plain, u8 *crypt, size_t len) --+{ --+ size_t olen = 0; /*(poor interface above; unknown size of u8 *crypt)*/ --+ return (mbedtls_cipher_update(&ctx->ctx_enc, plain, len, crypt, &olen) --+ || mbedtls_cipher_finish(&ctx->ctx_enc, crypt + olen, &olen)) ? -1 : 0; --+} --+ --+int crypto_cipher_decrypt(struct crypto_cipher *ctx, --+ const u8 *crypt, u8 *plain, size_t len) --+{ --+ size_t olen = 0; /*(poor interface above; unknown size of u8 *plain)*/ --+ return (mbedtls_cipher_update(&ctx->ctx_dec, crypt, len, plain, &olen) --+ || mbedtls_cipher_finish(&ctx->ctx_dec, plain + olen, &olen)) ? -1 : 0; --+} --+ --+void crypto_cipher_deinit(struct crypto_cipher *ctx) --+{ --+ mbedtls_cipher_free(&ctx->ctx_enc); --+ mbedtls_cipher_free(&ctx->ctx_dec); --+ os_free(ctx); --+} --+ --+#endif /* CRYPTO_MBEDTLS_CRYPTO_CIPHER */ --+ --+ --+#ifdef CRYPTO_MBEDTLS_CRYPTO_HASH --+ --+struct crypto_hash * crypto_hash_init(enum crypto_hash_alg alg, const u8 *key, --+ size_t key_len) --+{ --+ mbedtls_md_type_t md_type; --+ int is_hmac = 0; --+ --+ switch (alg) { --+ #ifdef MBEDTLS_MD5_C --+ case CRYPTO_HASH_ALG_MD5: --+ md_type = MBEDTLS_MD_MD5; --+ break; --+ #endif --+ #ifdef MBEDTLS_SHA1_C --+ case CRYPTO_HASH_ALG_SHA1: --+ md_type = MBEDTLS_MD_SHA1; --+ break; --+ #endif --+ #ifdef MBEDTLS_MD5_C --+ case CRYPTO_HASH_ALG_HMAC_MD5: --+ md_type = MBEDTLS_MD_MD5; --+ is_hmac = 1; --+ break; --+ #endif --+ #ifdef MBEDTLS_SHA1_C --+ case CRYPTO_HASH_ALG_HMAC_SHA1: --+ md_type = MBEDTLS_MD_SHA1; --+ is_hmac = 1; --+ break; --+ #endif --+ #ifdef MBEDTLS_SHA256_C --+ case CRYPTO_HASH_ALG_SHA256: --+ md_type = MBEDTLS_MD_SHA256; --+ break; --+ case CRYPTO_HASH_ALG_HMAC_SHA256: --+ md_type = MBEDTLS_MD_SHA256; --+ is_hmac = 1; --+ break; --+ #endif --+ #ifdef MBEDTLS_SHA512_C --+ case CRYPTO_HASH_ALG_SHA384: --+ md_type = MBEDTLS_MD_SHA384; --+ break; --+ case CRYPTO_HASH_ALG_SHA512: --+ md_type = MBEDTLS_MD_SHA512; --+ break; --+ #endif --+ default: --+ return NULL; --+ } --+ --+ const mbedtls_md_info_t *md_info = mbedtls_md_info_from_type(md_type); --+ if (!md_info) --+ return NULL; --+ --+ mbedtls_md_context_t *mctx = os_malloc(sizeof(*mctx)); --+ if (mctx == NULL) --+ return NULL; --+ --+ mbedtls_md_init(mctx); --+ if (mbedtls_md_setup(mctx, md_info, is_hmac) != 0) { --+ os_free(mctx); --+ return NULL; --+ } --+ --+ if (is_hmac) --+ mbedtls_md_hmac_starts(mctx, key, key_len); --+ else --+ mbedtls_md_starts(mctx); --+ return (struct crypto_hash *)((uintptr_t)mctx | is_hmac); --+} --+ --+void crypto_hash_update(struct crypto_hash *ctx, const u8 *data, size_t len) --+{ --+ mbedtls_md_context_t *mctx = (mbedtls_md_context_t*)((uintptr_t)ctx & ~1uL); --+ #if 0 --+ /*(mbedtls_md_hmac_update() and mbedtls_md_update() --+ * make same modifications under the hood in mbedtls)*/ --+ if ((uintptr_t)ctx & 1uL) --+ mbedtls_md_hmac_update(mctx, data, len); --+ else --+ #endif --+ mbedtls_md_update(mctx, data, len); --+} --+ --+int crypto_hash_finish(struct crypto_hash *ctx, u8 *mac, size_t *len) --+{ --+ mbedtls_md_context_t *mctx = (mbedtls_md_context_t*)((uintptr_t)ctx & ~1uL); --+ if (mac != NULL && len != NULL) { /*(NULL if caller just freeing context)*/ --+ #if MBEDTLS_VERSION_NUMBER >= 0x03020000 /* mbedtls 3.2.0 */ --+ const mbedtls_md_info_t *md_info = mbedtls_md_info_from_ctx(mctx); --+ #else --+ const mbedtls_md_info_t *md_info = mctx->MBEDTLS_PRIVATE(md_info); --+ #endif --+ size_t maclen = mbedtls_md_get_size(md_info); --+ if (*len < maclen) { --+ *len = maclen; --+ /*(note: ctx not freed; can call again with larger *len)*/ --+ return -1; --+ } --+ *len = maclen; --+ if ((uintptr_t)ctx & 1uL) --+ mbedtls_md_hmac_finish(mctx, mac); --+ else --+ mbedtls_md_finish(mctx, mac); --+ } --+ mbedtls_md_free(mctx); --+ os_free(mctx); --+ return 0; --+} --+ --+#endif /* CRYPTO_MBEDTLS_CRYPTO_HASH */ --+ --+ --+#ifdef CRYPTO_MBEDTLS_CRYPTO_BIGNUM --+ --+#include --+ --+/* crypto.h bignum interfaces */ --+ --+struct crypto_bignum *crypto_bignum_init(void) --+{ --+ mbedtls_mpi *bn = os_malloc(sizeof(*bn)); --+ if (bn) --+ mbedtls_mpi_init(bn); --+ return (struct crypto_bignum *)bn; --+} --+ --+struct crypto_bignum *crypto_bignum_init_set(const u8 *buf, size_t len) --+{ --+ mbedtls_mpi *bn = os_malloc(sizeof(*bn)); --+ if (bn) { --+ mbedtls_mpi_init(bn); --+ if (mbedtls_mpi_read_binary(bn, buf, len) == 0) --+ return (struct crypto_bignum *)bn; --+ } --+ --+ os_free(bn); --+ return NULL; --+} --+ --+struct crypto_bignum *crypto_bignum_init_uint(unsigned int val) --+{ --+ #if 0 /*(hostap use of this interface passes int, not uint)*/ --+ val = host_to_be32(val); --+ return crypto_bignum_init_set((const u8 *)&val, sizeof(val)); --+ #else --+ mbedtls_mpi *bn = os_malloc(sizeof(*bn)); --+ if (bn) { --+ mbedtls_mpi_init(bn); --+ if (mbedtls_mpi_lset(bn, (int)val) == 0) --+ return (struct crypto_bignum *)bn; --+ } --+ --+ os_free(bn); --+ return NULL; --+ #endif --+} --+ --+void crypto_bignum_deinit(struct crypto_bignum *n, int clear) --+{ --+ mbedtls_mpi_free((mbedtls_mpi *)n); --+ os_free(n); --+} --+ --+int crypto_bignum_to_bin(const struct crypto_bignum *a, --+ u8 *buf, size_t buflen, size_t padlen) --+{ --+ size_t n = mbedtls_mpi_size((mbedtls_mpi *)a); --+ if (n < padlen) --+ n = padlen; --+ return n > buflen || mbedtls_mpi_write_binary((mbedtls_mpi *)a, buf, n) --+ ? -1 --+ : (int)(n); --+} --+ --+int crypto_bignum_rand(struct crypto_bignum *r, const struct crypto_bignum *m) --+{ --+ /*assert(r != m);*//* r must not be same as m for mbedtls_mpi_random()*/ --+ #if MBEDTLS_VERSION_NUMBER >= 0x021B0000 /* mbedtls 2.27.0 */ --+ return mbedtls_mpi_random((mbedtls_mpi *)r, 0, (mbedtls_mpi *)m, --+ mbedtls_ctr_drbg_random, --+ crypto_mbedtls_ctr_drbg()) ? -1 : 0; --+ #else --+ /* (needed by EAP_PWD, SAE, DPP) */ --+ wpa_printf(MSG_ERROR, --+ "mbedtls 2.27.0 or later required for mbedtls_mpi_random()"); --+ return -1; --+ #endif --+} --+ --+int crypto_bignum_add(const struct crypto_bignum *a, --+ const struct crypto_bignum *b, --+ struct crypto_bignum *c) --+{ --+ return mbedtls_mpi_add_mpi((mbedtls_mpi *)c, --+ (const mbedtls_mpi *)a, --+ (const mbedtls_mpi *)b) ? -1 : 0; --+} --+ --+int crypto_bignum_mod(const struct crypto_bignum *a, --+ const struct crypto_bignum *b, --+ struct crypto_bignum *c) --+{ --+ return mbedtls_mpi_mod_mpi((mbedtls_mpi *)c, --+ (const mbedtls_mpi *)a, --+ (const mbedtls_mpi *)b) ? -1 : 0; --+} --+ --+int crypto_bignum_exptmod(const struct crypto_bignum *a, --+ const struct crypto_bignum *b, --+ const struct crypto_bignum *c, --+ struct crypto_bignum *d) --+{ --+ /* (check if input params match d; d is the result) */ --+ /* (a == d) is ok in current mbedtls implementation */ --+ if (b == d || c == d) { /*(not ok; store result in intermediate)*/ --+ mbedtls_mpi R; --+ mbedtls_mpi_init(&R); --+ int rc = mbedtls_mpi_exp_mod(&R, --+ (const mbedtls_mpi *)a, --+ (const mbedtls_mpi *)b, --+ (const mbedtls_mpi *)c, --+ NULL) --+ || mbedtls_mpi_copy((mbedtls_mpi *)d, &R) ? -1 : 0; --+ mbedtls_mpi_free(&R); --+ return rc; --+ } --+ else { --+ return mbedtls_mpi_exp_mod((mbedtls_mpi *)d, --+ (const mbedtls_mpi *)a, --+ (const mbedtls_mpi *)b, --+ (const mbedtls_mpi *)c, --+ NULL) ? -1 : 0; --+ } --+} --+ --+int crypto_bignum_inverse(const struct crypto_bignum *a, --+ const struct crypto_bignum *b, --+ struct crypto_bignum *c) --+{ --+ return mbedtls_mpi_inv_mod((mbedtls_mpi *)c, --+ (const mbedtls_mpi *)a, --+ (const mbedtls_mpi *)b) ? -1 : 0; --+} --+ --+int crypto_bignum_sub(const struct crypto_bignum *a, --+ const struct crypto_bignum *b, --+ struct crypto_bignum *c) --+{ --+ return mbedtls_mpi_sub_mpi((mbedtls_mpi *)c, --+ (const mbedtls_mpi *)a, --+ (const mbedtls_mpi *)b) ? -1 : 0; --+} --+ --+int crypto_bignum_div(const struct crypto_bignum *a, --+ const struct crypto_bignum *b, --+ struct crypto_bignum *c) --+{ --+ /*(most current use of this crypto.h interface has a == c (result), --+ * so store result in an intermediate to avoid overwritten input)*/ --+ mbedtls_mpi R; --+ mbedtls_mpi_init(&R); --+ int rc = mbedtls_mpi_div_mpi(&R, NULL, --+ (const mbedtls_mpi *)a, --+ (const mbedtls_mpi *)b) --+ || mbedtls_mpi_copy((mbedtls_mpi *)c, &R) ? -1 : 0; --+ mbedtls_mpi_free(&R); --+ return rc; --+} --+ --+int crypto_bignum_addmod(const struct crypto_bignum *a, --+ const struct crypto_bignum *b, --+ const struct crypto_bignum *c, --+ struct crypto_bignum *d) --+{ --+ return mbedtls_mpi_add_mpi((mbedtls_mpi *)d, --+ (const mbedtls_mpi *)a, --+ (const mbedtls_mpi *)b) --+ || mbedtls_mpi_mod_mpi((mbedtls_mpi *)d, --+ (mbedtls_mpi *)d, --+ (const mbedtls_mpi *)c) ? -1 : 0; --+} --+ --+int crypto_bignum_mulmod(const struct crypto_bignum *a, --+ const struct crypto_bignum *b, --+ const struct crypto_bignum *c, --+ struct crypto_bignum *d) --+{ --+ return mbedtls_mpi_mul_mpi((mbedtls_mpi *)d, --+ (const mbedtls_mpi *)a, --+ (const mbedtls_mpi *)b) --+ || mbedtls_mpi_mod_mpi((mbedtls_mpi *)d, --+ (mbedtls_mpi *)d, --+ (const mbedtls_mpi *)c) ? -1 : 0; --+} --+ --+int crypto_bignum_sqrmod(const struct crypto_bignum *a, --+ const struct crypto_bignum *b, --+ struct crypto_bignum *c) --+{ --+ #if 1 --+ return crypto_bignum_mulmod(a, a, b, c); --+ #else --+ mbedtls_mpi bn; --+ mbedtls_mpi_init(&bn); --+ if (mbedtls_mpi_lset(&bn, 2)) /* alt?: mbedtls_mpi_set_bit(&bn, 1) */ --+ return -1; --+ int ret = mbedtls_mpi_exp_mod((mbedtls_mpi *)c, --+ (const mbedtls_mpi *)a, &bn, --+ (const mbedtls_mpi *)b, NULL) ? -1 : 0; --+ mbedtls_mpi_free(&bn); --+ return ret; --+ #endif --+} --+ --+int crypto_bignum_rshift(const struct crypto_bignum *a, int n, --+ struct crypto_bignum *r) --+{ --+ return mbedtls_mpi_copy((mbedtls_mpi *)r, (const mbedtls_mpi *)a) --+ || mbedtls_mpi_shift_r((mbedtls_mpi *)r, n) ? -1 : 0; --+} --+ --+int crypto_bignum_cmp(const struct crypto_bignum *a, --+ const struct crypto_bignum *b) --+{ --+ return mbedtls_mpi_cmp_mpi((const mbedtls_mpi *)a, (const mbedtls_mpi *)b); --+} --+ --+int crypto_bignum_is_zero(const struct crypto_bignum *a) --+{ --+ /* XXX: src/common/sae.c:sswu() contains comment: --+ * "TODO: Make sure crypto_bignum_is_zero() is constant time" --+ * Note: mbedtls_mpi_cmp_int() *is not* constant time */ --+ return (mbedtls_mpi_cmp_int((const mbedtls_mpi *)a, 0) == 0); --+} --+ --+int crypto_bignum_is_one(const struct crypto_bignum *a) --+{ --+ return (mbedtls_mpi_cmp_int((const mbedtls_mpi *)a, 1) == 0); --+} --+ --+int crypto_bignum_is_odd(const struct crypto_bignum *a) --+{ --+ return mbedtls_mpi_get_bit((const mbedtls_mpi *)a, 0); --+} --+ --+#include "utils/const_time.h" --+int crypto_bignum_legendre(const struct crypto_bignum *a, --+ const struct crypto_bignum *p) --+{ --+ /* Security Note: --+ * mbedtls_mpi_exp_mod() is not documented to run in constant time, --+ * though mbedtls/library/bignum.c uses constant_time_internal.h funcs. --+ * Compare to crypto_openssl.c:crypto_bignum_legendre() --+ * which uses openssl BN_mod_exp_mont_consttime() --+ * mbedtls/library/ecp.c has further countermeasures to timing attacks, --+ * (but ecp.c funcs are not used here) */ --+ --+ mbedtls_mpi exp, tmp; --+ mbedtls_mpi_init(&exp); --+ mbedtls_mpi_init(&tmp); --+ --+ /* exp = (p-1) / 2 */ --+ int res; --+ if (mbedtls_mpi_sub_int(&exp, (const mbedtls_mpi *)p, 1) == 0 --+ && mbedtls_mpi_shift_r(&exp, 1) == 0 --+ && mbedtls_mpi_exp_mod(&tmp, (const mbedtls_mpi *)a, &exp, --+ (const mbedtls_mpi *)p, NULL) == 0) { --+ /*(modified from crypto_openssl.c:crypto_bignum_legendre())*/ --+ /* Return 1 if tmp == 1, 0 if tmp == 0, or -1 otherwise. Need --+ * to use constant time selection to avoid branches here. */ --+ unsigned int mask; --+ res = -1; --+ mask = const_time_eq((mbedtls_mpi_cmp_int(&tmp, 1) == 0), 1); --+ res = const_time_select_int(mask, 1, res); --+ mask = const_time_eq((mbedtls_mpi_cmp_int(&tmp, 0) == 0), 1); --+ res = const_time_select_int(mask, 0, res); --+ } else { --+ res = -2; --+ } --+ --+ mbedtls_mpi_free(&tmp); --+ mbedtls_mpi_free(&exp); --+ return res; --+} --+ --+#endif /* CRYPTO_MBEDTLS_CRYPTO_BIGNUM */ --+ --+ --+#ifdef CRYPTO_MBEDTLS_CRYPTO_DH --+ --+/* crypto_internal-modexp.c */ --+ --+#include --+#include --+ --+#if 0 /* crypto_dh_init() and crypto_dh_derive_secret() prefer to use mbedtls */ --+int crypto_mod_exp(const u8 *base, size_t base_len, --+ const u8 *power, size_t power_len, --+ const u8 *modulus, size_t modulus_len, --+ u8 *result, size_t *result_len) --+{ --+ mbedtls_mpi bn_base, bn_exp, bn_modulus, bn_result; --+ mbedtls_mpi_init(&bn_base); --+ mbedtls_mpi_init(&bn_exp); --+ mbedtls_mpi_init(&bn_modulus); --+ mbedtls_mpi_init(&bn_result); --+ --+ size_t len; --+ int ret = mbedtls_mpi_read_binary(&bn_base, base, base_len) --+ || mbedtls_mpi_read_binary(&bn_exp, power, power_len) --+ || mbedtls_mpi_read_binary(&bn_modulus, modulus, modulus_len) --+ || mbedtls_mpi_exp_mod(&bn_result,&bn_base,&bn_exp,&bn_modulus,NULL) --+ || (len = mbedtls_mpi_size(&bn_result)) > *result_len --+ || mbedtls_mpi_write_binary(&bn_result, result, (*result_len = len)) --+ ? -1 --+ : 0; --+ --+ mbedtls_mpi_free(&bn_base); --+ mbedtls_mpi_free(&bn_exp); --+ mbedtls_mpi_free(&bn_modulus); --+ mbedtls_mpi_free(&bn_result); --+ return ret; --+} --+#endif --+ --+static int crypto_mbedtls_dh_set_bin_pg(mbedtls_dhm_context *ctx, u8 generator, --+ const u8 *prime, size_t prime_len) --+{ --+ /*(could set these directly in MBEDTLS_PRIVATE members)*/ --+ mbedtls_mpi P, G; --+ mbedtls_mpi_init(&P); --+ mbedtls_mpi_init(&G); --+ int ret = mbedtls_mpi_lset(&G, generator) --+ || mbedtls_mpi_read_binary(&P, prime, prime_len) --+ || mbedtls_dhm_set_group(ctx, &P, &G); --+ mbedtls_mpi_free(&P); --+ mbedtls_mpi_free(&G); --+ return ret; --+} --+ --+__attribute_noinline__ --+static int crypto_mbedtls_dh_init_public(mbedtls_dhm_context *ctx, u8 generator, --+ const u8 *prime, size_t prime_len, --+ u8 *privkey, u8 *pubkey) --+{ --+ if (crypto_mbedtls_dh_set_bin_pg(ctx, generator, prime, prime_len) --+ || mbedtls_dhm_make_public(ctx, (int)prime_len, pubkey, prime_len, --+ mbedtls_ctr_drbg_random, --+ crypto_mbedtls_ctr_drbg())) --+ return -1; --+ --+ /*(enable later when upstream mbedtls interface changes require)*/ --+ #if 0 && MBEDTLS_VERSION_NUMBER >= 0x03000000 /* mbedtls 3.0.0 */ --+ mbedtls_mpi X; --+ mbedtls_mpi_init(&X); --+ int ret = mbedtls_dhm_get_value(ctx, MBEDTLS_DHM_PARAM_X, &X) --+ || mbedtls_mpi_write_binary(&X, privkey, prime_len) ? -1 : 0; --+ mbedtls_mpi_free(&X); --+ return ret; --+ #else --+ return mbedtls_mpi_write_binary(&ctx->MBEDTLS_PRIVATE(X), --+ privkey, prime_len) ? -1 : 0; --+ #endif --+} --+ --+int crypto_dh_init(u8 generator, const u8 *prime, size_t prime_len, u8 *privkey, --+ u8 *pubkey) --+{ --+ #if 0 /*(crypto_dh_init() duplicated (and identical) in crypto_*.c modules)*/ --+ size_t pubkey_len, pad; --+ --+ if (os_get_random(privkey, prime_len) < 0) --+ return -1; --+ if (os_memcmp(privkey, prime, prime_len) > 0) { --+ /* Make sure private value is smaller than prime */ --+ privkey[0] = 0; --+ } --+ --+ pubkey_len = prime_len; --+ if (crypto_mod_exp(&generator, 1, privkey, prime_len, prime, prime_len, --+ pubkey, &pubkey_len) < 0) --+ return -1; --+ if (pubkey_len < prime_len) { --+ pad = prime_len - pubkey_len; --+ os_memmove(pubkey + pad, pubkey, pubkey_len); --+ os_memset(pubkey, 0, pad); --+ } --+ --+ return 0; --+ #else --+ /* Prefer to use mbedtls to derive our public/private key, as doing so --+ * leverages mbedtls to properly format output and to perform blinding*/ --+ mbedtls_dhm_context ctx; --+ mbedtls_dhm_init(&ctx); --+ int ret = crypto_mbedtls_dh_init_public(&ctx, generator, prime, --+ prime_len, privkey, pubkey); --+ mbedtls_dhm_free(&ctx); --+ return ret; --+ #endif --+} --+ --+/*(crypto_dh_derive_secret() could be implemented using crypto.h APIs --+ * instead of being reimplemented in each crypto_*.c)*/ --+int crypto_dh_derive_secret(u8 generator, const u8 *prime, size_t prime_len, --+ const u8 *order, size_t order_len, --+ const u8 *privkey, size_t privkey_len, --+ const u8 *pubkey, size_t pubkey_len, --+ u8 *secret, size_t *len) --+{ --+ #if 0 --+ if (pubkey_len > prime_len || --+ (pubkey_len == prime_len && --+ os_memcmp(pubkey, prime, prime_len) >= 0)) --+ return -1; --+ --+ int res = 0; --+ mbedtls_mpi pub; --+ mbedtls_mpi_init(&pub); --+ if (mbedtls_mpi_read_binary(&pub, pubkey, pubkey_len) --+ || mbedtls_mpi_cmp_int(&pub, 1) <= 0) { --+ res = -1; --+ } else if (order) { --+ mbedtls_mpi p, q, tmp; --+ mbedtls_mpi_init(&p); --+ mbedtls_mpi_init(&q); --+ mbedtls_mpi_init(&tmp); --+ --+ /* verify: pubkey^q == 1 mod p */ --+ res = (mbedtls_mpi_read_binary(&p, prime, prime_len) --+ || mbedtls_mpi_read_binary(&q, order, order_len) --+ || mbedtls_mpi_exp_mod(&tmp, &pub, &q, &p, NULL) --+ || mbedtls_mpi_cmp_int(&tmp, 1) != 0); --+ --+ mbedtls_mpi_free(&p); --+ mbedtls_mpi_free(&q); --+ mbedtls_mpi_free(&tmp); --+ } --+ mbedtls_mpi_free(&pub); --+ --+ return (res == 0) --+ ? crypto_mod_exp(pubkey, pubkey_len, privkey, privkey_len, --+ prime, prime_len, secret, len) --+ : -1; --+ #else --+ /* Prefer to use mbedtls to derive DH shared secret, as doing so --+ * leverages mbedtls to validate params and to perform blinding. --+ * --+ * Attempt to reconstitute DH context to derive shared secret --+ * (due to limitations of the interface, which ought to pass context). --+ * Force provided G (our private key) into context without validation. --+ * Regenerating GX (our public key) not needed to derive shared secret. --+ */ --+ /*(older compilers might not support VLAs)*/ --+ /*unsigned char buf[2+prime_len+2+1+2+pubkey_len];*/ --+ unsigned char buf[2+MBEDTLS_MPI_MAX_SIZE+2+1+2+MBEDTLS_MPI_MAX_SIZE]; --+ unsigned char *p = buf + 2 + prime_len; --+ if (2+prime_len+2+1+2+pubkey_len > sizeof(buf)) --+ return -1; --+ WPA_PUT_BE16(buf, prime_len); /*(2-byte big-endian size of prime)*/ --+ p[0] = 0; /*(2-byte big-endian size of generator)*/ --+ p[1] = 1; --+ p[2] = generator; --+ WPA_PUT_BE16(p+3, pubkey_len); /*(2-byte big-endian size of pubkey)*/ --+ os_memcpy(p+5, pubkey, pubkey_len); --+ os_memcpy(buf+2, prime, prime_len); --+ --+ mbedtls_dhm_context ctx; --+ mbedtls_dhm_init(&ctx); --+ p = buf; --+ int ret = mbedtls_dhm_read_params(&ctx, &p, p+2+prime_len+5+pubkey_len) --+ || mbedtls_mpi_read_binary(&ctx.MBEDTLS_PRIVATE(X), --+ privkey, privkey_len) --+ || mbedtls_dhm_calc_secret(&ctx, secret, *len, len, --+ mbedtls_ctr_drbg_random, --+ crypto_mbedtls_ctr_drbg()) ? -1 : 0; --+ mbedtls_dhm_free(&ctx); --+ return ret; --+ #endif --+} --+ --+/* dh_group5.c */ --+ --+#include "dh_group5.h" --+ --+/* RFC3526_PRIME_1536[] and RFC3526_GENERATOR_1536[] from crypto_wolfssl.c */ --+ --+static const unsigned char RFC3526_PRIME_1536[] = { --+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xC9, 0x0F, 0xDA, 0xA2, --+ 0x21, 0x68, 0xC2, 0x34, 0xC4, 0xC6, 0x62, 0x8B, 0x80, 0xDC, 0x1C, 0xD1, --+ 0x29, 0x02, 0x4E, 0x08, 0x8A, 0x67, 0xCC, 0x74, 0x02, 0x0B, 0xBE, 0xA6, --+ 0x3B, 0x13, 0x9B, 0x22, 0x51, 0x4A, 0x08, 0x79, 0x8E, 0x34, 0x04, 0xDD, --+ 0xEF, 0x95, 0x19, 0xB3, 0xCD, 0x3A, 0x43, 0x1B, 0x30, 0x2B, 0x0A, 0x6D, --+ 0xF2, 0x5F, 0x14, 0x37, 0x4F, 0xE1, 0x35, 0x6D, 0x6D, 0x51, 0xC2, 0x45, --+ 0xE4, 0x85, 0xB5, 0x76, 0x62, 0x5E, 0x7E, 0xC6, 0xF4, 0x4C, 0x42, 0xE9, --+ 0xA6, 0x37, 0xED, 0x6B, 0x0B, 0xFF, 0x5C, 0xB6, 0xF4, 0x06, 0xB7, 0xED, --+ 0xEE, 0x38, 0x6B, 0xFB, 0x5A, 0x89, 0x9F, 0xA5, 0xAE, 0x9F, 0x24, 0x11, --+ 0x7C, 0x4B, 0x1F, 0xE6, 0x49, 0x28, 0x66, 0x51, 0xEC, 0xE4, 0x5B, 0x3D, --+ 0xC2, 0x00, 0x7C, 0xB8, 0xA1, 0x63, 0xBF, 0x05, 0x98, 0xDA, 0x48, 0x36, --+ 0x1C, 0x55, 0xD3, 0x9A, 0x69, 0x16, 0x3F, 0xA8, 0xFD, 0x24, 0xCF, 0x5F, --+ 0x83, 0x65, 0x5D, 0x23, 0xDC, 0xA3, 0xAD, 0x96, 0x1C, 0x62, 0xF3, 0x56, --+ 0x20, 0x85, 0x52, 0xBB, 0x9E, 0xD5, 0x29, 0x07, 0x70, 0x96, 0x96, 0x6D, --+ 0x67, 0x0C, 0x35, 0x4E, 0x4A, 0xBC, 0x98, 0x04, 0xF1, 0x74, 0x6C, 0x08, --+ 0xCA, 0x23, 0x73, 0x27, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF --+}; --+ --+static const unsigned char RFC3526_GENERATOR_1536[] = { --+ 0x02 --+}; --+ --+void * dh5_init(struct wpabuf **priv, struct wpabuf **publ) --+{ --+ const unsigned char * const prime = RFC3526_PRIME_1536; --+ const size_t prime_len = sizeof(RFC3526_PRIME_1536); --+ const u8 generator = *RFC3526_GENERATOR_1536; --+ struct wpabuf *wpubl = NULL, *wpriv = NULL; --+ --+ mbedtls_dhm_context *ctx = os_malloc(sizeof(*ctx)); --+ if (ctx == NULL) --+ return NULL; --+ mbedtls_dhm_init(ctx); --+ --+ if ( (wpubl = wpabuf_alloc(prime_len)) --+ && (wpriv = wpabuf_alloc(prime_len)) --+ && crypto_mbedtls_dh_init_public(ctx, generator, prime, prime_len, --+ wpabuf_put(wpriv, prime_len), --+ wpabuf_put(wpubl, prime_len))==0) { --+ wpabuf_free(*publ); --+ wpabuf_clear_free(*priv); --+ *publ = wpubl; --+ *priv = wpriv; --+ return ctx; --+ } --+ --+ wpabuf_clear_free(wpriv); --+ wpabuf_free(wpubl); --+ mbedtls_dhm_free(ctx); --+ os_free(ctx); --+ return NULL; --+} --+ --+#ifdef CRYPTO_MBEDTLS_DH5_INIT_FIXED --+void * dh5_init_fixed(const struct wpabuf *priv, const struct wpabuf *publ) --+{ --+ const unsigned char * const prime = RFC3526_PRIME_1536; --+ const size_t prime_len = sizeof(RFC3526_PRIME_1536); --+ const u8 generator = *RFC3526_GENERATOR_1536; --+ --+ mbedtls_dhm_context *ctx = os_malloc(sizeof(*ctx)); --+ if (ctx == NULL) --+ return NULL; --+ mbedtls_dhm_init(ctx); --+ --+ if (crypto_mbedtls_dh_set_bin_pg(ctx, generator, prime, prime_len)==0 --+ #if 0 /*(ignore; not required to derive shared secret)*/ --+ && mbedtls_mpi_read_binary(&ctx->MBEDTLS_PRIVATE(GX), --+ wpabuf_head(publ),wpabuf_len(publ))==0 --+ #endif --+ && mbedtls_mpi_read_binary(&ctx->MBEDTLS_PRIVATE(X), --+ wpabuf_head(priv),wpabuf_len(priv))==0) { --+ return ctx; --+ } --+ --+ mbedtls_dhm_free(ctx); --+ os_free(ctx); --+ return NULL; --+} --+#endif --+ --+struct wpabuf * dh5_derive_shared(void *ctx, const struct wpabuf *peer_public, --+ const struct wpabuf *own_private) --+{ --+ /*((mbedtls_dhm_context *)ctx must already contain own_private)*/ --+ /* mbedtls 2.x: prime_len = ctx->len; */ --+ /* mbedtls 3.x: prime_len = mbedtls_dhm_get_len(ctx); */ --+ size_t olen = sizeof(RFC3526_PRIME_1536); /*(sizeof(); prime known)*/ --+ struct wpabuf *buf = wpabuf_alloc(olen); --+ if (buf == NULL) --+ return NULL; --+ if (mbedtls_dhm_read_public((mbedtls_dhm_context *)ctx, --+ wpabuf_head(peer_public), --+ wpabuf_len(peer_public)) == 0 --+ && mbedtls_dhm_calc_secret(ctx, wpabuf_mhead(buf), olen, &olen, --+ mbedtls_ctr_drbg_random, --+ crypto_mbedtls_ctr_drbg()) == 0) { --+ wpabuf_put(buf, olen); --+ return buf; --+ } --+ --+ wpabuf_free(buf); --+ return NULL; --+} --+ --+void dh5_free(void *ctx) --+{ --+ mbedtls_dhm_free(ctx); --+ os_free(ctx); --+} --+ --+#endif /* CRYPTO_MBEDTLS_CRYPTO_DH */ --+ --+ --+#if defined(CRYPTO_MBEDTLS_CRYPTO_ECDH) || defined(CRYPTO_MBEDTLS_CRYPTO_EC) --+ --+#include --+ --+#define CRYPTO_EC_pbits(e) (((mbedtls_ecp_group *)(e))->pbits) --+#define CRYPTO_EC_plen(e) ((((mbedtls_ecp_group *)(e))->pbits+7)>>3) --+#define CRYPTO_EC_P(e) (&((mbedtls_ecp_group *)(e))->P) --+#define CRYPTO_EC_N(e) (&((mbedtls_ecp_group *)(e))->N) --+#define CRYPTO_EC_A(e) (&((mbedtls_ecp_group *)(e))->A) --+#define CRYPTO_EC_B(e) (&((mbedtls_ecp_group *)(e))->B) --+#define CRYPTO_EC_G(e) (&((mbedtls_ecp_group *)(e))->G) --+ --+static mbedtls_ecp_group_id crypto_mbedtls_ecp_group_id_from_ike_id(int group) --+{ --+ /* https://www.iana.org/assignments/ikev2-parameters/ikev2-parameters.xhtml */ --+ switch (group) { --+ #ifdef MBEDTLS_ECP_DP_SECP256R1_ENABLED --+ case 19: return MBEDTLS_ECP_DP_SECP256R1; --+ #endif --+ #ifdef MBEDTLS_ECP_DP_SECP384R1_ENABLED --+ case 20: return MBEDTLS_ECP_DP_SECP384R1; --+ #endif --+ #ifdef MBEDTLS_ECP_DP_SECP521R1_ENABLED --+ case 21: return MBEDTLS_ECP_DP_SECP521R1; --+ #endif --+ #ifdef MBEDTLS_ECP_DP_SECP192R1_ENABLED --+ case 25: return MBEDTLS_ECP_DP_SECP192R1; --+ #endif --+ #ifdef MBEDTLS_ECP_DP_SECP224R1_ENABLED --+ case 26: return MBEDTLS_ECP_DP_SECP224R1; --+ #endif --+ #ifdef MBEDTLS_ECP_DP_BP256R1_ENABLED --+ case 28: return MBEDTLS_ECP_DP_BP256R1; --+ #endif --+ #ifdef MBEDTLS_ECP_DP_BP384R1_ENABLED --+ case 29: return MBEDTLS_ECP_DP_BP384R1; --+ #endif --+ #ifdef MBEDTLS_ECP_DP_BP512R1_ENABLED --+ case 30: return MBEDTLS_ECP_DP_BP512R1; --+ #endif --+ #ifdef MBEDTLS_ECP_DP_CURVE25519_ENABLED --+ case 31: return MBEDTLS_ECP_DP_CURVE25519; --+ #endif --+ #ifdef MBEDTLS_ECP_DP_CURVE448_ENABLED --+ case 32: return MBEDTLS_ECP_DP_CURVE448; --+ #endif --+ default: return MBEDTLS_ECP_DP_NONE; --+ } --+} --+ --+#ifdef CRYPTO_MBEDTLS_CRYPTO_EC --+static int crypto_mbedtls_ike_id_from_ecp_group_id(mbedtls_ecp_group_id grp_id) --+{ --+ /* https://www.iana.org/assignments/ikev2-parameters/ikev2-parameters.xhtml */ --+ /*(for crypto_ec_key_group())*/ --+ switch (grp_id) { --+ #ifdef MBEDTLS_ECP_DP_SECP256R1_ENABLED --+ case MBEDTLS_ECP_DP_SECP256R1: return 19; --+ #endif --+ #ifdef MBEDTLS_ECP_DP_SECP384R1_ENABLED --+ case MBEDTLS_ECP_DP_SECP384R1: return 20; --+ #endif --+ #ifdef MBEDTLS_ECP_DP_SECP521R1_ENABLED --+ case MBEDTLS_ECP_DP_SECP521R1: return 21; --+ #endif --+ #ifdef MBEDTLS_ECP_DP_SECP192R1_ENABLED --+ case MBEDTLS_ECP_DP_SECP192R1: return 25; --+ #endif --+ #ifdef MBEDTLS_ECP_DP_SECP224R1_ENABLED --+ case MBEDTLS_ECP_DP_SECP224R1: return 26; --+ #endif --+ #ifdef MBEDTLS_ECP_DP_BP256R1_ENABLED --+ case MBEDTLS_ECP_DP_BP256R1: return 28; --+ #endif --+ #ifdef MBEDTLS_ECP_DP_BP384R1_ENABLED --+ case MBEDTLS_ECP_DP_BP384R1: return 29; --+ #endif --+ #ifdef MBEDTLS_ECP_DP_BP512R1_ENABLED --+ case MBEDTLS_ECP_DP_BP512R1: return 30; --+ #endif --+ #ifdef MBEDTLS_ECP_DP_CURVE25519_ENABLED --+ case MBEDTLS_ECP_DP_CURVE25519: return 31; --+ #endif --+ #ifdef MBEDTLS_ECP_DP_CURVE448_ENABLED --+ case MBEDTLS_ECP_DP_CURVE448: return 32; --+ #endif --+ default: return -1; --+ } --+} --+#endif --+ --+#endif /* CRYPTO_MBEDTLS_CRYPTO_ECDH || CRYPTO_MBEDTLS_CRYPTO_EC */ --+ --+ --+#if defined(CRYPTO_MBEDTLS_CRYPTO_ECDH) || defined(CRYPTO_MBEDTLS_CRYPTO_EC_DPP) --+ --+#include --+#include --+ --+static int crypto_mbedtls_keypair_gen(int group, mbedtls_pk_context *pk) --+{ --+ mbedtls_ecp_group_id grp_id = --+ crypto_mbedtls_ecp_group_id_from_ike_id(group); --+ if (grp_id == MBEDTLS_ECP_DP_NONE) --+ return -1; --+ const mbedtls_pk_info_t *pk_info = --+ mbedtls_pk_info_from_type(MBEDTLS_PK_ECKEY); --+ if (pk_info == NULL) --+ return -1; --+ return mbedtls_pk_setup(pk, pk_info) --+ || mbedtls_ecp_gen_key(grp_id, mbedtls_pk_ec(*pk), --+ mbedtls_ctr_drbg_random, --+ crypto_mbedtls_ctr_drbg()) ? -1 : 0; --+} --+ --+#endif --+ --+ --+#ifdef CRYPTO_MBEDTLS_CRYPTO_ECDH --+ --+#include --+#include --+#include --+#include --+ --+/* wrap mbedtls_ecdh_context for more future-proof direct access to components --+ * (mbedtls_ecdh_context internal implementation may change between releases) --+ * --+ * If mbedtls_pk_context -- specifically underlying mbedtls_ecp_keypair -- --+ * lifetime were guaranteed to be longer than that of mbedtls_ecdh_context, --+ * then mbedtls_pk_context or mbedtls_ecp_keypair could be stored in crypto_ecdh --+ * (or crypto_ec_key could be stored in crypto_ecdh, and crypto_ec_key could --+ * wrap mbedtls_ecp_keypair and components, to avoid MBEDTLS_PRIVATE access) */ --+struct crypto_ecdh { --+ mbedtls_ecdh_context ctx; --+ mbedtls_ecp_group grp; --+ mbedtls_ecp_point Q; --+}; --+ --+struct crypto_ecdh * crypto_ecdh_init(int group) --+{ --+ mbedtls_pk_context pk; --+ mbedtls_pk_init(&pk); --+ struct crypto_ecdh *ecdh = crypto_mbedtls_keypair_gen(group, &pk) == 0 --+ ? crypto_ecdh_init2(group, (struct crypto_ec_key *)&pk) --+ : NULL; --+ mbedtls_pk_free(&pk); --+ return ecdh; --+} --+ --+struct crypto_ecdh * crypto_ecdh_init2(int group, --+ struct crypto_ec_key *own_key) --+{ --+ mbedtls_ecp_group_id grp_id = --+ crypto_mbedtls_ecp_group_id_from_ike_id(group); --+ if (grp_id == MBEDTLS_ECP_DP_NONE) --+ return NULL; --+ mbedtls_ecp_keypair *ecp_kp = mbedtls_pk_ec(*(mbedtls_pk_context *)own_key); --+ struct crypto_ecdh *ecdh = os_malloc(sizeof(*ecdh)); --+ if (ecdh == NULL) --+ return NULL; --+ mbedtls_ecdh_init(&ecdh->ctx); --+ mbedtls_ecp_group_init(&ecdh->grp); --+ mbedtls_ecp_point_init(&ecdh->Q); --+ if (mbedtls_ecdh_setup(&ecdh->ctx, grp_id) == 0 --+ && mbedtls_ecdh_get_params(&ecdh->ctx,ecp_kp,MBEDTLS_ECDH_OURS) == 0) { --+ /* copy grp and Q for later use --+ * (retrieving this info later is more convoluted --+ * even if mbedtls_ecdh_make_public() is considered)*/ --+ #if MBEDTLS_VERSION_NUMBER >= 0x03020000 /* mbedtls 3.2.0 */ --+ mbedtls_mpi d; --+ mbedtls_mpi_init(&d); --+ if (mbedtls_ecp_export(ecp_kp, &ecdh->grp, &d, &ecdh->Q) == 0) { --+ mbedtls_mpi_free(&d); --+ return ecdh; --+ } --+ mbedtls_mpi_free(&d); --+ #else --+ if (mbedtls_ecp_group_load(&ecdh->grp, grp_id) == 0 --+ && mbedtls_ecp_copy(&ecdh->Q, &ecp_kp->MBEDTLS_PRIVATE(Q)) == 0) --+ return ecdh; --+ #endif --+ } --+ --+ mbedtls_ecp_point_free(&ecdh->Q); --+ mbedtls_ecp_group_free(&ecdh->grp); --+ mbedtls_ecdh_free(&ecdh->ctx); --+ os_free(ecdh); --+ return NULL; --+} --+ --+struct wpabuf * crypto_ecdh_get_pubkey(struct crypto_ecdh *ecdh, int inc_y) --+{ --+ mbedtls_ecp_group *grp = &ecdh->grp; --+ size_t len = CRYPTO_EC_plen(grp); --+ #ifdef MBEDTLS_ECP_MONTGOMERY_ENABLED --+ /* len */ --+ #endif --+ #ifdef MBEDTLS_ECP_SHORT_WEIERSTRASS_ENABLED --+ if (mbedtls_ecp_get_type(grp) == MBEDTLS_ECP_TYPE_SHORT_WEIERSTRASS) --+ len = inc_y ? len*2+1 : len+1; --+ #endif --+ struct wpabuf *buf = wpabuf_alloc(len); --+ if (buf == NULL) --+ return NULL; --+ inc_y = inc_y ? MBEDTLS_ECP_PF_UNCOMPRESSED : MBEDTLS_ECP_PF_COMPRESSED; --+ if (mbedtls_ecp_point_write_binary(grp, &ecdh->Q, inc_y, &len, --+ wpabuf_mhead_u8(buf), len) == 0) { --+ wpabuf_put(buf, len); --+ return buf; --+ } --+ --+ wpabuf_free(buf); --+ return NULL; --+} --+ --+#if defined(MBEDTLS_ECP_SHORT_WEIERSTRASS_ENABLED) --+static int crypto_mbedtls_short_weierstrass_derive_y(mbedtls_ecp_group *grp, --+ mbedtls_mpi *bn, --+ int parity_bit) --+{ --+ /* y^2 = x^3 + ax + b --+ * sqrt(w) = w^((p+1)/4) mod p (for prime p where p = 3 mod 4) */ --+ mbedtls_mpi *cy2 = (mbedtls_mpi *) --+ crypto_ec_point_compute_y_sqr((struct crypto_ec *)grp, --+ (const struct crypto_bignum *)bn); /*x*/ --+ if (cy2 == NULL) --+ return -1; --+ --+ /*mbedtls_mpi_free(bn);*/ --+ /*(reuse bn to store result (y))*/ --+ --+ mbedtls_mpi exp; --+ mbedtls_mpi_init(&exp); --+ int ret = mbedtls_mpi_get_bit(&grp->P, 0) != 1 /*(p = 3 mod 4)*/ --+ || mbedtls_mpi_get_bit(&grp->P, 1) != 1 /*(p = 3 mod 4)*/ --+ || mbedtls_mpi_add_int(&exp, &grp->P, 1) --+ || mbedtls_mpi_shift_r(&exp, 2) --+ || mbedtls_mpi_exp_mod(bn, cy2, &exp, &grp->P, NULL) --+ || (mbedtls_mpi_get_bit(bn, 0) != parity_bit --+ && mbedtls_mpi_sub_mpi(bn, &grp->P, bn)); --+ mbedtls_mpi_free(&exp); --+ mbedtls_mpi_free(cy2); --+ os_free(cy2); --+ return ret; --+} --+#endif --+ --+struct wpabuf * crypto_ecdh_set_peerkey(struct crypto_ecdh *ecdh, int inc_y, --+ const u8 *key, size_t len) --+{ --+ if (len == 0) /*(invalid peer key)*/ --+ return NULL; --+ --+ mbedtls_ecp_group *grp = &ecdh->grp; --+ --+ #if defined(MBEDTLS_ECP_SHORT_WEIERSTRASS_ENABLED) --+ if (mbedtls_ecp_get_type(grp) == MBEDTLS_ECP_TYPE_SHORT_WEIERSTRASS) { --+ /* add header for mbedtls_ecdh_read_public() */ --+ u8 buf[256]; --+ if (sizeof(buf)-1 < len) --+ return NULL; --+ buf[0] = (u8)(len); --+ os_memcpy(buf+1, key, len); --+ --+ if (inc_y) { --+ if (!(len & 1)) { /*(dpp code/tests does not include tag?!?)*/ --+ if (sizeof(buf)-2 < len) --+ return NULL; --+ buf[0] = (u8)(1+len); --+ buf[1] = 0x04; --+ os_memcpy(buf+2, key, len); --+ } --+ len >>= 1; /*(repurpose len to prime_len)*/ --+ } --+ else if (key[0] == 0x02 || key[0] == 0x03) { /* (inc_y == 0) */ --+ --len; /*(repurpose len to prime_len)*/ --+ --+ /* mbedtls_ecp_point_read_binary() does not currently support --+ * MBEDTLS_ECP_PF_COMPRESSED format (buf[1] = 0x02 or 0x03) --+ * (returns MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE) */ --+ --+ /* derive y, amend buf[] with y for UNCOMPRESSED format */ --+ if (sizeof(buf)-2 < len*2 || len == 0) --+ return NULL; --+ buf[0] = (u8)(1+len*2); --+ buf[1] = 0x04; --+ mbedtls_mpi bn; --+ mbedtls_mpi_init(&bn); --+ int ret = mbedtls_mpi_read_binary(&bn, key+1, len) --+ || crypto_mbedtls_short_weierstrass_derive_y(grp, &bn, --+ key[0] & 1) --+ || mbedtls_mpi_write_binary(&bn, buf+2+len, len); --+ mbedtls_mpi_free(&bn); --+ if (ret != 0) --+ return NULL; --+ } --+ --+ if (key[0] == 0) /*(repurpose len to prime_len)*/ --+ len = CRYPTO_EC_plen(grp); --+ --+ if (mbedtls_ecdh_read_public(&ecdh->ctx, buf, buf[0]+1)) --+ return NULL; --+ } --+ #endif --+ #if defined(MBEDTLS_ECP_MONTGOMERY_ENABLED) --+ if (mbedtls_ecp_get_type(grp) == MBEDTLS_ECP_TYPE_MONTGOMERY) { --+ if (mbedtls_ecdh_read_public(&ecdh->ctx, key, len)) --+ return NULL; --+ } --+ #endif --+ --+ struct wpabuf *buf = wpabuf_alloc(len); --+ if (buf == NULL) --+ return NULL; --+ --+ if (mbedtls_ecdh_calc_secret(&ecdh->ctx, &len, --+ wpabuf_mhead(buf), len, --+ mbedtls_ctr_drbg_random, --+ crypto_mbedtls_ctr_drbg()) == 0) { --+ wpabuf_put(buf, len); --+ return buf; --+ } --+ --+ wpabuf_clear_free(buf); --+ return NULL; --+} --+ --+void crypto_ecdh_deinit(struct crypto_ecdh *ecdh) --+{ --+ if (ecdh == NULL) --+ return; --+ mbedtls_ecp_point_free(&ecdh->Q); --+ mbedtls_ecp_group_free(&ecdh->grp); --+ mbedtls_ecdh_free(&ecdh->ctx); --+ os_free(ecdh); --+} --+ --+size_t crypto_ecdh_prime_len(struct crypto_ecdh *ecdh) --+{ --+ return CRYPTO_EC_plen(&ecdh->grp); --+} --+ --+#endif /* CRYPTO_MBEDTLS_CRYPTO_ECDH */ --+ --+ --+#ifdef CRYPTO_MBEDTLS_CRYPTO_EC --+ --+#include --+ --+struct crypto_ec *crypto_ec_init(int group) --+{ --+ mbedtls_ecp_group_id grp_id = --+ crypto_mbedtls_ecp_group_id_from_ike_id(group); --+ if (grp_id == MBEDTLS_ECP_DP_NONE) --+ return NULL; --+ mbedtls_ecp_group *e = os_malloc(sizeof(*e)); --+ if (e == NULL) --+ return NULL; --+ mbedtls_ecp_group_init(e); --+ if (mbedtls_ecp_group_load(e, grp_id) == 0) --+ return (struct crypto_ec *)e; --+ --+ mbedtls_ecp_group_free(e); --+ os_free(e); --+ return NULL; --+} --+ --+void crypto_ec_deinit(struct crypto_ec *e) --+{ --+ mbedtls_ecp_group_free((mbedtls_ecp_group *)e); --+ os_free(e); --+} --+ --+size_t crypto_ec_prime_len(struct crypto_ec *e) --+{ --+ return CRYPTO_EC_plen(e); --+} --+ --+size_t crypto_ec_prime_len_bits(struct crypto_ec *e) --+{ --+ return CRYPTO_EC_pbits(e); --+} --+ --+size_t crypto_ec_order_len(struct crypto_ec *e) --+{ --+ return (mbedtls_mpi_bitlen(CRYPTO_EC_N(e)) + 7) / 8; --+} --+ --+const struct crypto_bignum *crypto_ec_get_prime(struct crypto_ec *e) --+{ --+ return (const struct crypto_bignum *)CRYPTO_EC_P(e); --+} --+ --+const struct crypto_bignum *crypto_ec_get_order(struct crypto_ec *e) --+{ --+ return (const struct crypto_bignum *)CRYPTO_EC_N(e); --+} --+ --+const struct crypto_bignum *crypto_ec_get_a(struct crypto_ec *e) --+{ --+ static const uint8_t secp256r1_a[] = --+ {0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x01, --+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, --+ 0x00,0x00,0x00,0x00,0xff,0xff,0xff,0xff, --+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfc}; --+ static const uint8_t secp384r1_a[] = --+ {0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, --+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, --+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, --+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfe, --+ 0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x00, --+ 0x00,0x00,0x00,0x00,0xff,0xff,0xff,0xfc}; --+ static const uint8_t secp521r1_a[] = --+ {0x01,0xff,0xff,0xff,0xff,0xff,0xff,0xff, --+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, --+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, --+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, --+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, --+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, --+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, --+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, --+ 0xff,0xfc}; --+ static const uint8_t secp192r1_a[] = --+ {0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, --+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfe, --+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfc}; --+ static const uint8_t secp224r1_a[] = --+ {0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, --+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfe, --+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, --+ 0xff,0xff,0xff,0xfe}; --+ --+ const uint8_t *bin = NULL; --+ size_t len = 0; --+ --+ /* (mbedtls groups matching supported sswu_curve_param() IKE groups) */ --+ switch (((mbedtls_ecp_group *)e)->id) { --+ #ifdef MBEDTLS_ECP_DP_SECP256R1_ENABLED --+ case MBEDTLS_ECP_DP_SECP256R1: --+ bin = secp256r1_a; --+ len = sizeof(secp256r1_a); --+ break; --+ #endif --+ #ifdef MBEDTLS_ECP_DP_SECP384R1_ENABLED --+ case MBEDTLS_ECP_DP_SECP384R1: --+ bin = secp384r1_a; --+ len = sizeof(secp384r1_a); --+ break; --+ #endif --+ #ifdef MBEDTLS_ECP_DP_SECP521R1_ENABLED --+ case MBEDTLS_ECP_DP_SECP521R1: --+ bin = secp521r1_a; --+ len = sizeof(secp521r1_a); --+ break; --+ #endif --+ #ifdef MBEDTLS_ECP_DP_SECP192R1_ENABLED --+ case MBEDTLS_ECP_DP_SECP192R1: --+ bin = secp192r1_a; --+ len = sizeof(secp192r1_a); --+ break; --+ #endif --+ #ifdef MBEDTLS_ECP_DP_SECP224R1_ENABLED --+ case MBEDTLS_ECP_DP_SECP224R1: --+ bin = secp224r1_a; --+ len = sizeof(secp224r1_a); --+ break; --+ #endif --+ #ifdef MBEDTLS_ECP_DP_BP256R1_ENABLED --+ case MBEDTLS_ECP_DP_BP256R1: --+ return (const struct crypto_bignum *)CRYPTO_EC_A(e); --+ #endif --+ #ifdef MBEDTLS_ECP_DP_BP384R1_ENABLED --+ case MBEDTLS_ECP_DP_BP384R1: --+ return (const struct crypto_bignum *)CRYPTO_EC_A(e); --+ #endif --+ #ifdef MBEDTLS_ECP_DP_BP512R1_ENABLED --+ case MBEDTLS_ECP_DP_BP512R1: --+ return (const struct crypto_bignum *)CRYPTO_EC_A(e); --+ #endif --+ #ifdef MBEDTLS_ECP_DP_CURVE25519_ENABLED --+ case MBEDTLS_ECP_DP_CURVE25519: --+ return (const struct crypto_bignum *)CRYPTO_EC_A(e); --+ #endif --+ #ifdef MBEDTLS_ECP_DP_CURVE448_ENABLED --+ case MBEDTLS_ECP_DP_CURVE448: --+ return (const struct crypto_bignum *)CRYPTO_EC_A(e); --+ #endif --+ default: --+ return NULL; --+ } --+ --+ /*(note: not thread-safe; returns file-scoped static storage)*/ --+ if (mbedtls_mpi_read_binary(&mpi_sw_A, bin, len) == 0) --+ return (const struct crypto_bignum *)&mpi_sw_A; --+ return NULL; --+} --+ --+const struct crypto_bignum *crypto_ec_get_b(struct crypto_ec *e) --+{ --+ return (const struct crypto_bignum *)CRYPTO_EC_B(e); --+} --+ --+const struct crypto_ec_point * crypto_ec_get_generator(struct crypto_ec *e) --+{ --+ return (const struct crypto_ec_point *)CRYPTO_EC_G(e); --+} --+ --+struct crypto_ec_point *crypto_ec_point_init(struct crypto_ec *e) --+{ --+ mbedtls_ecp_point *p = os_malloc(sizeof(*p)); --+ if (p != NULL) --+ mbedtls_ecp_point_init(p); --+ return (struct crypto_ec_point *)p; --+} --+ --+void crypto_ec_point_deinit(struct crypto_ec_point *p, int clear) --+{ --+ mbedtls_ecp_point_free((mbedtls_ecp_point *)p); --+ os_free(p); --+} --+ --+int crypto_ec_point_x(struct crypto_ec *e, const struct crypto_ec_point *p, --+ struct crypto_bignum *x) --+{ --+ mbedtls_mpi *px = &((mbedtls_ecp_point *)p)->MBEDTLS_PRIVATE(X); --+ return mbedtls_mpi_copy((mbedtls_mpi *)x, px) --+ ? -1 --+ : 0; --+} --+ --+int crypto_ec_point_to_bin(struct crypto_ec *e, --+ const struct crypto_ec_point *point, u8 *x, u8 *y) --+{ --+ /* crypto.h documents crypto_ec_point_to_bin() output is big-endian */ --+ size_t len = CRYPTO_EC_plen(e); --+ if (x) { --+ mbedtls_mpi *px = &((mbedtls_ecp_point *)point)->MBEDTLS_PRIVATE(X); --+ if (mbedtls_mpi_write_binary(px, x, len)) --+ return -1; --+ } --+ if (y) { --+ #if 0 /*(should not be necessary; py mpi should be in initial state)*/ --+ #ifdef MBEDTLS_ECP_MONTGOMERY_ENABLED --+ if (mbedtls_ecp_get_type((mbedtls_ecp_group *)e) --+ == MBEDTLS_ECP_TYPE_MONTGOMERY) { --+ os_memset(y, 0, len); --+ return 0; --+ } --+ #endif --+ #endif --+ mbedtls_mpi *py = &((mbedtls_ecp_point *)point)->MBEDTLS_PRIVATE(Y); --+ if (mbedtls_mpi_write_binary(py, y, len)) --+ return -1; --+ } --+ return 0; --+} --+ --+struct crypto_ec_point * crypto_ec_point_from_bin(struct crypto_ec *e, --+ const u8 *val) --+{ --+ size_t len = CRYPTO_EC_plen(e); --+ mbedtls_ecp_point *p = os_malloc(sizeof(*p)); --+ u8 buf[1+MBEDTLS_MPI_MAX_SIZE*2]; --+ if (p == NULL) --+ return NULL; --+ mbedtls_ecp_point_init(p); --+ --+ #ifdef MBEDTLS_ECP_SHORT_WEIERSTRASS_ENABLED --+ if (mbedtls_ecp_get_type((mbedtls_ecp_group *)e) --+ == MBEDTLS_ECP_TYPE_SHORT_WEIERSTRASS) { --+ #if 0 /* prefer alternative to MBEDTLS_PRIVATE() access */ --+ mbedtls_mpi *px = &((mbedtls_ecp_point *)p)->MBEDTLS_PRIVATE(X); --+ mbedtls_mpi *py = &((mbedtls_ecp_point *)p)->MBEDTLS_PRIVATE(Y); --+ mbedtls_mpi *pz = &((mbedtls_ecp_point *)p)->MBEDTLS_PRIVATE(Z); --+ --+ if (mbedtls_mpi_read_binary(px, val, len) == 0 --+ && mbedtls_mpi_read_binary(py, val + len, len) == 0 --+ && mbedtls_mpi_lset(pz, 1) == 0) --+ return (struct crypto_ec_point *)p; --+ #else --+ buf[0] = 0x04; --+ os_memcpy(buf+1, val, len*2); --+ if (mbedtls_ecp_point_read_binary((mbedtls_ecp_group *)e, p, --+ buf, 1+len*2) == 0) --+ return (struct crypto_ec_point *)p; --+ #endif --+ } --+ #endif --+ #ifdef MBEDTLS_ECP_MONTGOMERY_ENABLED --+ if (mbedtls_ecp_get_type((mbedtls_ecp_group *)e) --+ == MBEDTLS_ECP_TYPE_MONTGOMERY) { --+ /* crypto.h interface documents crypto_ec_point_from_bin() --+ * val is length: prime_len * 2 and is big-endian --+ * (Short Weierstrass is assumed by hostap) --+ * Reverse to little-endian format for Montgomery */ --+ for (unsigned int i = 0; i < len; ++i) --+ buf[i] = val[len-1-i]; --+ if (mbedtls_ecp_point_read_binary((mbedtls_ecp_group *)e, p, --+ buf, len) == 0) --+ return (struct crypto_ec_point *)p; --+ } --+ #endif --+ --+ mbedtls_ecp_point_free(p); --+ os_free(p); --+ return NULL; --+} --+ --+int crypto_ec_point_add(struct crypto_ec *e, const struct crypto_ec_point *a, --+ const struct crypto_ec_point *b, --+ struct crypto_ec_point *c) --+{ --+ /* mbedtls does not provide an mbedtls_ecp_point add function */ --+ mbedtls_mpi one; --+ mbedtls_mpi_init(&one); --+ int ret = mbedtls_mpi_lset(&one, 1) --+ || mbedtls_ecp_muladd( --+ (mbedtls_ecp_group *)e, (mbedtls_ecp_point *)c, --+ &one, (const mbedtls_ecp_point *)a, --+ &one, (const mbedtls_ecp_point *)b) ? -1 : 0; --+ mbedtls_mpi_free(&one); --+ return ret; --+} --+ --+int crypto_ec_point_mul(struct crypto_ec *e, const struct crypto_ec_point *p, --+ const struct crypto_bignum *b, --+ struct crypto_ec_point *res) --+{ --+ return mbedtls_ecp_mul( --+ (mbedtls_ecp_group *)e, (mbedtls_ecp_point *)res, --+ (const mbedtls_mpi *)b, (const mbedtls_ecp_point *)p, --+ mbedtls_ctr_drbg_random, crypto_mbedtls_ctr_drbg()) ? -1 : 0; --+} --+ --+int crypto_ec_point_invert(struct crypto_ec *e, struct crypto_ec_point *p) --+{ --+ if (mbedtls_ecp_get_type((mbedtls_ecp_group *)e) --+ == MBEDTLS_ECP_TYPE_MONTGOMERY) { --+ /* e.g. MBEDTLS_ECP_DP_CURVE25519 and MBEDTLS_ECP_DP_CURVE448 */ --+ wpa_printf(MSG_ERROR, --+ "%s not implemented for Montgomery curves",__func__); --+ return -1; --+ } --+ --+ /* mbedtls does not provide an mbedtls_ecp_point invert function */ --+ /* below works for Short Weierstrass; incorrect for Montgomery curves */ --+ mbedtls_mpi *py = &((mbedtls_ecp_point *)p)->MBEDTLS_PRIVATE(Y); --+ return mbedtls_ecp_is_zero((mbedtls_ecp_point *)p) /*point at infinity*/ --+ || mbedtls_mpi_cmp_int(py, 0) == 0 /*point is its own inverse*/ --+ || mbedtls_mpi_sub_abs(py, CRYPTO_EC_P(e), py) == 0 ? 0 : -1; --+} --+ --+#ifdef MBEDTLS_ECP_SHORT_WEIERSTRASS_ENABLED --+static int --+crypto_ec_point_y_sqr_weierstrass(mbedtls_ecp_group *e, const mbedtls_mpi *x, --+ mbedtls_mpi *y2) --+{ --+ /* MBEDTLS_ECP_TYPE_SHORT_WEIERSTRASS y^2 = x^3 + a x + b */ --+ --+ /* Short Weierstrass elliptic curve group w/o A set treated as A = -3 */ --+ /* Attempt to match mbedtls/library/ecp.c:ecp_check_pubkey_sw() behavior --+ * and elsewhere in mbedtls/library/ecp.c where if A is not set, it is --+ * treated as if A = -3. */ --+ --+ #if 0 --+ /* y^2 = x^3 + ax + b */ --+ mbedtls_mpi *A = &e->A; --+ mbedtls_mpi t, A_neg3; --+ if (&e->A.p == NULL) { --+ mbedtls_mpi_init(&A_neg3); --+ if (mbedtls_mpi_lset(&A_neg3, -3) != 0) { --+ mbedtls_mpi_free(&A_neg3); --+ return -1; --+ } --+ A = &A_neg3; --+ } --+ mbedtls_mpi_init(&t); --+ int ret = /* x^3 */ --+ mbedtls_mpi_lset(&t, 3) --+ || mbedtls_mpi_exp_mod(y2, x, &t, &e->P, NULL) --+ /* ax */ --+ || mbedtls_mpi_mul_mpi(y2, y2, A) --+ || mbedtls_mpi_mod_mpi(&t, &t, &e->P) --+ /* ax + b */ --+ || mbedtls_mpi_add_mpi(&t, &t, &e->B) --+ || mbedtls_mpi_mod_mpi(&t, &t, &e->P) --+ /* x^3 + ax + b */ --+ || mbedtls_mpi_add_mpi(&t, &t, y2) /* ax + b + x^3 */ --+ || mbedtls_mpi_mod_mpi(y2, &t, &e->P); --+ mbedtls_mpi_free(&t); --+ if (A == &A_neg3) --+ mbedtls_mpi_free(&A_neg3); --+ return ret; /* 0: success, non-zero: failure */ --+ #else --+ /* y^2 = x^3 + ax + b = (x^2 + a)x + b */ --+ return /* x^2 */ --+ mbedtls_mpi_mul_mpi(y2, x, x) --+ || mbedtls_mpi_mod_mpi(y2, y2, &e->P) --+ /* x^2 + a */ --+ || (e->A.MBEDTLS_PRIVATE(p) --+ ? mbedtls_mpi_add_mpi(y2, y2, &e->A) --+ : mbedtls_mpi_sub_int(y2, y2, 3)) --+ || mbedtls_mpi_mod_mpi(y2, y2, &e->P) --+ /* (x^2 + a)x */ --+ || mbedtls_mpi_mul_mpi(y2, y2, x) --+ || mbedtls_mpi_mod_mpi(y2, y2, &e->P) --+ /* (x^2 + a)x + b */ --+ || mbedtls_mpi_add_mpi(y2, y2, &e->B) --+ || mbedtls_mpi_mod_mpi(y2, y2, &e->P); --+ #endif --+} --+#endif /* MBEDTLS_ECP_SHORT_WEIERSTRASS_ENABLED */ --+ --+#if 0 /* not used by hostap */ --+#ifdef MBEDTLS_ECP_MONTGOMERY_ENABLED --+static int --+crypto_ec_point_y_sqr_montgomery(mbedtls_ecp_group *e, const mbedtls_mpi *x, --+ mbedtls_mpi *y2) --+{ --+ /* XXX: !!! must be reviewed and audited for correctness !!! */ --+ --+ /* MBEDTLS_ECP_TYPE_MONTGOMERY y^2 = x^3 + a x^2 + x */ --+ --+ /* y^2 = x^3 + a x^2 + x = (x + a)x^2 + x */ --+ mbedtls_mpi x2; --+ mbedtls_mpi_init(&x2); --+ int ret = /* x^2 */ --+ mbedtls_mpi_mul_mpi(&x2, x, x) --+ || mbedtls_mpi_mod_mpi(&x2, &x2, &e->P) --+ /* x + a */ --+ || mbedtls_mpi_add_mpi(y2, x, &e->A) --+ || mbedtls_mpi_mod_mpi(y2, y2, &e->P) --+ /* (x + a)x^2 */ --+ || mbedtls_mpi_mul_mpi(y2, y2, &x2) --+ || mbedtls_mpi_mod_mpi(y2, y2, &e->P) --+ /* (x + a)x^2 + x */ --+ || mbedtls_mpi_add_mpi(y2, y2, x) --+ || mbedtls_mpi_mod_mpi(y2, y2, &e->P); --+ mbedtls_mpi_free(&x2); --+ return ret; /* 0: success, non-zero: failure */ --+} --+#endif /* MBEDTLS_ECP_MONTGOMERY_ENABLED */ --+#endif --+ --+struct crypto_bignum * --+crypto_ec_point_compute_y_sqr(struct crypto_ec *e, --+ const struct crypto_bignum *x) --+{ --+ mbedtls_mpi *y2 = os_malloc(sizeof(*y2)); --+ if (y2 == NULL) --+ return NULL; --+ mbedtls_mpi_init(y2); --+ --+ #ifdef MBEDTLS_ECP_SHORT_WEIERSTRASS_ENABLED --+ if (mbedtls_ecp_get_type((mbedtls_ecp_group *)e) --+ == MBEDTLS_ECP_TYPE_SHORT_WEIERSTRASS --+ && crypto_ec_point_y_sqr_weierstrass((mbedtls_ecp_group *)e, --+ (const mbedtls_mpi *)x, --+ y2) == 0) --+ return (struct crypto_bignum *)y2; --+ #endif --+ #if 0 /* not used by hostap */ --+ #ifdef MBEDTLS_ECP_MONTGOMERY_ENABLED --+ if (mbedtls_ecp_get_type((mbedtls_ecp_group *)e) --+ == MBEDTLS_ECP_TYPE_MONTGOMERY --+ && crypto_ec_point_y_sqr_montgomery((mbedtls_ecp_group *)e, --+ (const mbedtls_mpi *)x, --+ y2) == 0) --+ return (struct crypto_bignum *)y2; --+ #endif --+ #endif --+ --+ mbedtls_mpi_free(y2); --+ os_free(y2); --+ return NULL; --+} --+ --+int crypto_ec_point_is_at_infinity(struct crypto_ec *e, --+ const struct crypto_ec_point *p) --+{ --+ return mbedtls_ecp_is_zero((mbedtls_ecp_point *)p); --+} --+ --+int crypto_ec_point_is_on_curve(struct crypto_ec *e, --+ const struct crypto_ec_point *p) --+{ --+ #if 1 --+ return mbedtls_ecp_check_pubkey((const mbedtls_ecp_group *)e, --+ (const mbedtls_ecp_point *)p) == 0; --+ #else --+ /* compute y^2 mod P and compare to y^2 mod P */ --+ /*(ref: src/eap_common/eap_pwd_common.c:compute_password_element())*/ --+ const mbedtls_mpi *px = &((const mbedtls_ecp_point *)p)->MBEDTLS_PRIVATE(X); --+ mbedtls_mpi *cy2 = (mbedtls_mpi *) --+ crypto_ec_point_compute_y_sqr(e, (const struct crypto_bignum *)px); --+ if (cy2 == NULL) --+ return 0; --+ --+ mbedtls_mpi y2; --+ mbedtls_mpi_init(&y2); --+ const mbedtls_mpi *py = &((const mbedtls_ecp_point *)p)->MBEDTLS_PRIVATE(Y); --+ int is_on_curve = mbedtls_mpi_mul_mpi(&y2, py, py) /* y^2 mod P */ --+ || mbedtls_mpi_mod_mpi(&y2, &y2, CRYPTO_EC_P(e)) --+ || mbedtls_mpi_cmp_mpi(&y2, cy2) != 0 ? 0 : 1; --+ --+ mbedtls_mpi_free(&y2); --+ mbedtls_mpi_free(cy2); --+ os_free(cy2); --+ return is_on_curve; --+ #endif --+} --+ --+int crypto_ec_point_cmp(const struct crypto_ec *e, --+ const struct crypto_ec_point *a, --+ const struct crypto_ec_point *b) --+{ --+ return mbedtls_ecp_point_cmp((const mbedtls_ecp_point *)a, --+ (const mbedtls_ecp_point *)b); --+} --+ --+#if !defined(CONFIG_NO_STDOUT_DEBUG) --+void crypto_ec_point_debug_print(const struct crypto_ec *e, --+ const struct crypto_ec_point *p, --+ const char *title) --+{ --+ u8 x[MBEDTLS_MPI_MAX_SIZE]; --+ u8 y[MBEDTLS_MPI_MAX_SIZE]; --+ size_t len = CRYPTO_EC_plen(e); --+ /* crypto_ec_point_to_bin ought to take (const struct crypto_ec *e) */ --+ struct crypto_ec *ee; --+ *(const struct crypto_ec **)&ee = e; /*(cast away const)*/ --+ if (crypto_ec_point_to_bin(ee, p, x, y) == 0) { --+ if (title) --+ wpa_printf(MSG_DEBUG, "%s", title); --+ wpa_hexdump(MSG_DEBUG, "x:", x, len); --+ wpa_hexdump(MSG_DEBUG, "y:", y, len); --+ } --+} --+#endif --+ --+ --+struct crypto_ec_key * crypto_ec_key_parse_priv(const u8 *der, size_t der_len) --+{ --+ mbedtls_pk_context *ctx = os_malloc(sizeof(*ctx)); --+ if (ctx == NULL) --+ return NULL; --+ mbedtls_pk_init(ctx); --+ #if MBEDTLS_VERSION_NUMBER < 0x03000000 /* mbedtls 3.0.0 */ --+ if (mbedtls_pk_parse_key(ctx, der, der_len, NULL, 0) == 0) --+ #else --+ if (mbedtls_pk_parse_key(ctx, der, der_len, NULL, 0, --+ mbedtls_ctr_drbg_random, --+ crypto_mbedtls_ctr_drbg()) == 0) --+ #endif --+ return (struct crypto_ec_key *)ctx; --+ --+ mbedtls_pk_free(ctx); --+ os_free(ctx); --+ return NULL; --+} --+ --+#ifdef CRYPTO_MBEDTLS_CRYPTO_HPKE --+#ifdef CONFIG_MODULE_TESTS --+/*(for crypto_module_tests.c)*/ --+struct crypto_ec_key * crypto_ec_key_set_priv(int group, --+ const u8 *raw, size_t raw_len) --+{ --+ mbedtls_ecp_group_id grp_id = --+ crypto_mbedtls_ecp_group_id_from_ike_id(group); --+ if (grp_id == MBEDTLS_ECP_DP_NONE) --+ return NULL; --+ const mbedtls_pk_info_t *pk_info = --+ mbedtls_pk_info_from_type(MBEDTLS_PK_ECKEY); --+ if (pk_info == NULL) --+ return NULL; --+ mbedtls_pk_context *ctx = os_malloc(sizeof(*ctx)); --+ if (ctx == NULL) --+ return NULL; --+ mbedtls_pk_init(ctx); --+ if (mbedtls_pk_setup(ctx, pk_info) == 0 --+ && mbedtls_ecp_read_key(grp_id,mbedtls_pk_ec(*ctx),raw,raw_len) == 0) { --+ return (struct crypto_ec_key *)ctx; --+ } --+ --+ mbedtls_pk_free(ctx); --+ os_free(ctx); --+ return NULL; --+} --+#endif --+#endif --+ --+#include --+#include --+static int crypto_mbedtls_pk_parse_subpubkey_compressed(mbedtls_pk_context *ctx, const u8 *der, size_t der_len) --+{ --+ /* The following is modified from: --+ * mbedtls/library/pkparse.c:mbedtls_pk_parse_subpubkey() --+ * mbedtls/library/pkparse.c:pk_get_pk_alg() --+ * mbedtls/library/pkparse.c:pk_use_ecparams() --+ */ --+ mbedtls_pk_type_t pk_alg = MBEDTLS_PK_NONE; --+ const mbedtls_pk_info_t *pk_info; --+ int ret; --+ size_t len; --+ const unsigned char *end = der+der_len; --+ unsigned char *p; --+ *(const unsigned char **)&p = der; --+ --+ if( ( ret = mbedtls_asn1_get_tag( &p, end, &len, --+ MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 ) --+ { --+ return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT, ret ) ); --+ } --+ --+ end = p + len; --+ --+ /* --+ if( ( ret = pk_get_pk_alg( &p, end, &pk_alg, &alg_params ) ) != 0 ) --+ return( ret ); --+ */ --+ mbedtls_asn1_buf alg_oid, params; --+ memset( ¶ms, 0, sizeof(mbedtls_asn1_buf) ); --+ if( ( ret = mbedtls_asn1_get_alg( &p, end, &alg_oid, ¶ms ) ) != 0 ) --+ return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_PK_INVALID_ALG, ret ) ); --+ if( mbedtls_oid_get_pk_alg( &alg_oid, &pk_alg ) != 0 ) --+ return( MBEDTLS_ERR_PK_UNKNOWN_PK_ALG ); --+ --+ if( ( ret = mbedtls_asn1_get_bitstring_null( &p, end, &len ) ) != 0 ) --+ return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_PK_INVALID_PUBKEY, ret ) ); --+ --+ if( p + len != end ) --+ return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_PK_INVALID_PUBKEY, --+ MBEDTLS_ERR_ASN1_LENGTH_MISMATCH ) ); --+ --+ if( ( pk_info = mbedtls_pk_info_from_type( pk_alg ) ) == NULL ) --+ return( MBEDTLS_ERR_PK_UNKNOWN_PK_ALG ); --+ --+ if( ( ret = mbedtls_pk_setup( ctx, pk_info ) ) != 0 ) --+ return( ret ); --+ --+ /* assume mbedtls_pk_parse_subpubkey(&der, der+der_len, ctx) --+ * has already run with ctx initialized up to pk_get_ecpubkey(), --+ * and pk_get_ecpubkey() has returned MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE --+ * --+ * mbedtls mbedtls_ecp_point_read_binary() --+ * does not handle point in COMPRESSED format --+ * --+ * (validate assumption that algorithm is EC) */ --+ mbedtls_ecp_keypair *ecp_kp = mbedtls_pk_ec(*ctx); --+ if (ecp_kp == NULL) --+ return( MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE ); --+ mbedtls_ecp_group *ecp_kp_grp = &ecp_kp->MBEDTLS_PRIVATE(grp); --+ mbedtls_ecp_point *ecp_kp_Q = &ecp_kp->MBEDTLS_PRIVATE(Q); --+ mbedtls_ecp_group_id grp_id; --+ --+ --+ /* mbedtls/library/pkparse.c:pk_use_ecparams() */ --+ --+ if( params.tag == MBEDTLS_ASN1_OID ) --+ { --+ if( mbedtls_oid_get_ec_grp( ¶ms, &grp_id ) != 0 ) --+ return( MBEDTLS_ERR_PK_UNKNOWN_NAMED_CURVE ); --+ } --+ else --+ { --+#if defined(MBEDTLS_PK_PARSE_EC_EXTENDED) --+ /*(large code block not copied from mbedtls; unsupported)*/ --+ #if 0 --+ if( ( ret = pk_group_id_from_specified( ¶ms, &grp_id ) ) != 0 ) --+ return( ret ); --+ #endif --+#endif --+ return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT ); --+ } --+ --+ /* --+ * grp may already be initialized; if so, make sure IDs match --+ */ --+ if( ecp_kp_grp->id != MBEDTLS_ECP_DP_NONE && ecp_kp_grp->id != grp_id ) --+ return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT ); --+ --+ if( ( ret = mbedtls_ecp_group_load( ecp_kp_grp, grp_id ) ) != 0 ) --+ return( ret ); --+ --+ --+ /* (validate assumption that EC point is in COMPRESSED format) */ --+ len = CRYPTO_EC_plen(ecp_kp_grp); --+ if( mbedtls_ecp_get_type(ecp_kp_grp) != MBEDTLS_ECP_TYPE_SHORT_WEIERSTRASS --+ || (end - p) != 1+len --+ || (*p != 0x02 && *p != 0x03) ) --+ return( MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE ); --+ --+ /* Instead of calling mbedtls/library/pkparse.c:pk_get_ecpubkey() to call --+ * mbedtls_ecp_point_read_binary(), manually parse point into ecp_kp_Q */ --+ mbedtls_mpi *X = &ecp_kp_Q->MBEDTLS_PRIVATE(X); --+ mbedtls_mpi *Y = &ecp_kp_Q->MBEDTLS_PRIVATE(Y); --+ mbedtls_mpi *Z = &ecp_kp_Q->MBEDTLS_PRIVATE(Z); --+ ret = mbedtls_mpi_lset(Z, 1); --+ if (ret != 0) --+ return( ret ); --+ ret = mbedtls_mpi_read_binary(X, p+1, len); --+ if (ret != 0) --+ return( ret ); --+ /* derive Y --+ * (similar derivation of Y in crypto_mbedtls.c:crypto_ecdh_set_peerkey())*/ --+ ret = mbedtls_mpi_copy(Y, X) /*(Y is used as input and output obj below)*/ --+ || crypto_mbedtls_short_weierstrass_derive_y(ecp_kp_grp, Y, (*p & 1)); --+ if (ret != 0) --+ return( ret ); --+ --+ return mbedtls_ecp_check_pubkey( ecp_kp_grp, ecp_kp_Q ); --+} --+ --+struct crypto_ec_key * crypto_ec_key_parse_pub(const u8 *der, size_t der_len) --+{ --+ mbedtls_pk_context *ctx = os_malloc(sizeof(*ctx)); --+ if (ctx == NULL) --+ return NULL; --+ mbedtls_pk_init(ctx); --+ /*int rc = mbedtls_pk_parse_subpubkey(&der, der+der_len, ctx);*/ --+ int rc = mbedtls_pk_parse_public_key(ctx, der, der_len); --+ if (rc == 0) --+ return (struct crypto_ec_key *)ctx; --+ else if (rc == MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE) { --+ /* mbedtls mbedtls_ecp_point_read_binary() --+ * does not handle point in COMPRESSED format; parse internally */ --+ rc = crypto_mbedtls_pk_parse_subpubkey_compressed(ctx,der,der_len); --+ if (rc == 0) --+ return (struct crypto_ec_key *)ctx; --+ } --+ --+ mbedtls_pk_free(ctx); --+ os_free(ctx); --+ return NULL; --+} --+ --+#ifdef CRYPTO_MBEDTLS_CRYPTO_EC_DPP --+ --+static struct crypto_ec_key * --+crypto_ec_key_set_pub_point_for_group(mbedtls_ecp_group_id grp_id, --+ const mbedtls_ecp_point *pub, --+ const u8 *buf, size_t len) --+{ --+ const mbedtls_pk_info_t *pk_info = --+ mbedtls_pk_info_from_type(MBEDTLS_PK_ECKEY); --+ if (pk_info == NULL) --+ return NULL; --+ mbedtls_pk_context *ctx = os_malloc(sizeof(*ctx)); --+ if (ctx == NULL) --+ return NULL; --+ mbedtls_pk_init(ctx); --+ if (mbedtls_pk_setup(ctx, pk_info) == 0) { --+ /* (Is private key generation necessary for callers?) --+ * alt: gen key then overwrite Q --+ * mbedtls_ecp_gen_key(grp_id, ecp_kp, --+ * mbedtls_ctr_drbg_random, --+ * crypto_mbedtls_ctr_drbg()) == 0 --+ */ --+ mbedtls_ecp_keypair *ecp_kp = mbedtls_pk_ec(*ctx); --+ mbedtls_ecp_group *ecp_kp_grp = &ecp_kp->MBEDTLS_PRIVATE(grp); --+ mbedtls_ecp_point *ecp_kp_Q = &ecp_kp->MBEDTLS_PRIVATE(Q); --+ mbedtls_mpi *ecp_kp_d = &ecp_kp->MBEDTLS_PRIVATE(d); --+ if (mbedtls_ecp_group_load(ecp_kp_grp, grp_id) == 0 --+ && (pub --+ ? mbedtls_ecp_copy(ecp_kp_Q, pub) == 0 --+ : mbedtls_ecp_point_read_binary(ecp_kp_grp, ecp_kp_Q, --+ buf, len) == 0) --+ && mbedtls_ecp_gen_privkey(ecp_kp_grp, ecp_kp_d, --+ mbedtls_ctr_drbg_random, --+ crypto_mbedtls_ctr_drbg()) == 0){ --+ return (struct crypto_ec_key *)ctx; --+ } --+ } --+ --+ mbedtls_pk_free(ctx); --+ os_free(ctx); --+ return NULL; --+} --+ --+struct crypto_ec_key * crypto_ec_key_set_pub(int group, const u8 *x, --+ const u8 *y, size_t len) --+{ --+ mbedtls_ecp_group_id grp_id = --+ crypto_mbedtls_ecp_group_id_from_ike_id(group); --+ if (grp_id == MBEDTLS_ECP_DP_NONE) --+ return NULL; --+ if (len > MBEDTLS_MPI_MAX_SIZE) --+ return NULL; --+ u8 buf[1+MBEDTLS_MPI_MAX_SIZE*2]; --+ buf[0] = 0x04; /* assume x,y for Short Weierstrass */ --+ os_memcpy(buf+1, x, len); --+ os_memcpy(buf+1+len, y, len); --+ --+ return crypto_ec_key_set_pub_point_for_group(grp_id,NULL,buf,1+len*2); --+} --+ --+struct crypto_ec_key * --+crypto_ec_key_set_pub_point(struct crypto_ec *e, --+ const struct crypto_ec_point *pub) --+{ --+ mbedtls_ecp_group_id grp_id = ((mbedtls_ecp_group *)e)->id; --+ mbedtls_ecp_point *p = (mbedtls_ecp_point *)pub; --+ return crypto_ec_key_set_pub_point_for_group(grp_id, p, NULL, 0); --+} --+ --+ --+struct crypto_ec_key * crypto_ec_key_gen(int group) --+{ --+ mbedtls_pk_context *ctx = os_malloc(sizeof(*ctx)); --+ if (ctx == NULL) --+ return NULL; --+ mbedtls_pk_init(ctx); --+ if (crypto_mbedtls_keypair_gen(group, ctx) == 0) --+ return (struct crypto_ec_key *)ctx; --+ mbedtls_pk_free(ctx); --+ os_free(ctx); --+ return NULL; --+} --+ --+#endif /* CRYPTO_MBEDTLS_CRYPTO_EC_DPP */ --+ --+void crypto_ec_key_deinit(struct crypto_ec_key *key) --+{ --+ mbedtls_pk_free((mbedtls_pk_context *)key); --+ os_free(key); --+} --+ --+struct wpabuf * crypto_ec_key_get_subject_public_key(struct crypto_ec_key *key) --+{ --+ /* (similar to crypto_ec_key_get_pubkey_point(), --+ * but compressed point format and ASN.1 DER wrapping)*/ --+#ifndef MBEDTLS_PK_ECP_PUB_DER_MAX_BYTES /*(mbedtls/library/pkwrite.h)*/ --+#define MBEDTLS_PK_ECP_PUB_DER_MAX_BYTES ( 30 + 2 * MBEDTLS_ECP_MAX_BYTES ) --+#endif --+ unsigned char buf[MBEDTLS_PK_ECP_PUB_DER_MAX_BYTES]; --+ int len = mbedtls_pk_write_pubkey_der((mbedtls_pk_context *)key, --+ buf, sizeof(buf)); --+ if (len < 0) --+ return NULL; --+ /* Note: data is written at the end of the buffer! Use the --+ * return value to determine where you should start --+ * using the buffer */ --+ unsigned char *p = buf+sizeof(buf)-len; --+ --+ #ifdef MBEDTLS_ECP_SHORT_WEIERSTRASS_ENABLED --+ mbedtls_ecp_keypair *ecp_kp = mbedtls_pk_ec(*(mbedtls_pk_context *)key); --+ if (ecp_kp == NULL) --+ return NULL; --+ mbedtls_ecp_group *grp = &ecp_kp->MBEDTLS_PRIVATE(grp); --+ /* Note: sae_pk.c expects pubkey point in compressed format, --+ * but mbedtls_pk_write_pubkey_der() writes uncompressed format. --+ * Manually translate format and update lengths in DER format */ --+ if (mbedtls_ecp_get_type(grp) == MBEDTLS_ECP_TYPE_SHORT_WEIERSTRASS) { --+ unsigned char *end = buf+sizeof(buf); --+ size_t n; --+ /* SubjectPublicKeyInfo SEQUENCE */ --+ mbedtls_asn1_get_tag(&p, end, &n, --+ MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE); --+ /* algorithm AlgorithmIdentifier */ --+ unsigned char *a = p; --+ size_t alen; --+ mbedtls_asn1_get_tag(&p, end, &alen, --+ MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE); --+ p += alen; --+ alen = (size_t)(p - a); --+ /* subjectPublicKey BIT STRING */ --+ mbedtls_asn1_get_tag(&p, end, &n, MBEDTLS_ASN1_BIT_STRING); --+ /* rewrite into compressed point format and rebuild ASN.1 */ --+ p[1] = (buf[sizeof(buf)-1] & 1) ? 0x03 : 0x02; --+ n = 1 + 1 + (n-2)/2; --+ len = mbedtls_asn1_write_len(&p, buf, n) + (int)n; --+ len += mbedtls_asn1_write_tag(&p, buf, MBEDTLS_ASN1_BIT_STRING); --+ os_memmove(p-alen, a, alen); --+ len += alen; --+ p -= alen; --+ len += mbedtls_asn1_write_len(&p, buf, (size_t)len); --+ len += mbedtls_asn1_write_tag(&p, buf, --+ MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE); --+ } --+ #endif --+ return wpabuf_alloc_copy(p, (size_t)len); --+} --+ --+#ifdef CRYPTO_MBEDTLS_CRYPTO_EC_DPP --+ --+struct wpabuf * crypto_ec_key_get_ecprivate_key(struct crypto_ec_key *key, --+ bool include_pub) --+{ --+#ifndef MBEDTLS_PK_ECP_PRV_DER_MAX_BYTES /*(mbedtls/library/pkwrite.h)*/ --+#define MBEDTLS_PK_ECP_PRV_DER_MAX_BYTES ( 29 + 3 * MBEDTLS_ECP_MAX_BYTES ) --+#endif --+ unsigned char priv[MBEDTLS_PK_ECP_PRV_DER_MAX_BYTES]; --+ int privlen = mbedtls_pk_write_key_der((mbedtls_pk_context *)key, --+ priv, sizeof(priv)); --+ if (privlen < 0) --+ return NULL; --+ --+ struct wpabuf *wbuf; --+ --+ /* Note: data is written at the end of the buffer! Use the --+ * return value to determine where you should start --+ * using the buffer */ --+ /* mbedtls_pk_write_key_der() includes publicKey in DER */ --+ if (include_pub) --+ wbuf = wpabuf_alloc_copy(priv+sizeof(priv)-privlen, privlen); --+ else { --+ /* calculate publicKey offset and skip from end of buffer */ --+ unsigned char *p = priv+sizeof(priv)-privlen; --+ unsigned char *end = priv+sizeof(priv); --+ size_t len; --+ /* ECPrivateKey SEQUENCE */ --+ mbedtls_asn1_get_tag(&p, end, &len, --+ MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE); --+ /* version INTEGER */ --+ unsigned char *v = p; --+ mbedtls_asn1_get_tag(&p, end, &len, MBEDTLS_ASN1_INTEGER); --+ p += len; --+ /* privateKey OCTET STRING */ --+ mbedtls_asn1_get_tag(&p, end, &len, MBEDTLS_ASN1_OCTET_STRING); --+ p += len; --+ /* parameters ECParameters */ --+ mbedtls_asn1_get_tag(&p, end, &len, --+ MBEDTLS_ASN1_CONTEXT_SPECIFIC | MBEDTLS_ASN1_CONSTRUCTED); --+ p += len; --+ --+ /* write new SEQUENCE header (we know that it fits in priv[]) */ --+ len = (size_t)(p - v); --+ p = v; --+ len += mbedtls_asn1_write_len(&p, priv, len); --+ len += mbedtls_asn1_write_tag(&p, priv, --+ MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE); --+ wbuf = wpabuf_alloc_copy(p, len); --+ } --+ --+ forced_memzero(priv, sizeof(priv)); --+ return wbuf; --+} --+ --+struct wpabuf * crypto_ec_key_get_pubkey_point(struct crypto_ec_key *key, --+ int prefix) --+{ --+ /*(similarities to crypto_ecdh_get_pubkey(), but different struct)*/ --+ mbedtls_ecp_keypair *ecp_kp = mbedtls_pk_ec(*(mbedtls_pk_context *)key); --+ if (ecp_kp == NULL) --+ return NULL; --+ mbedtls_ecp_group *grp = &ecp_kp->MBEDTLS_PRIVATE(grp); --+ size_t len = CRYPTO_EC_plen(grp); --+ #ifdef MBEDTLS_ECP_MONTGOMERY_ENABLED --+ /* len */ --+ #endif --+ #ifdef MBEDTLS_ECP_SHORT_WEIERSTRASS_ENABLED --+ if (mbedtls_ecp_get_type(grp) == MBEDTLS_ECP_TYPE_SHORT_WEIERSTRASS) --+ len = len*2+1; --+ #endif --+ struct wpabuf *buf = wpabuf_alloc(len); --+ if (buf == NULL) --+ return NULL; --+ mbedtls_ecp_point *ecp_kp_Q = &ecp_kp->MBEDTLS_PRIVATE(Q); --+ if (mbedtls_ecp_point_write_binary(grp, ecp_kp_Q, --+ MBEDTLS_ECP_PF_UNCOMPRESSED, &len, --+ wpabuf_mhead_u8(buf), len) == 0) { --+ if (!prefix) /* Remove 0x04 prefix if requested */ --+ os_memmove(wpabuf_mhead(buf),wpabuf_mhead(buf)+1,--len); --+ wpabuf_put(buf, len); --+ return buf; --+ } --+ --+ wpabuf_free(buf); --+ return NULL; --+} --+ --+struct crypto_ec_point * --+crypto_ec_key_get_public_key(struct crypto_ec_key *key) --+{ --+ mbedtls_ecp_keypair *ecp_kp = mbedtls_pk_ec(*(mbedtls_pk_context *)key); --+ if (ecp_kp == NULL) --+ return NULL; --+ mbedtls_ecp_point *p = os_malloc(sizeof(*p)); --+ if (p != NULL) { --+ /*(mbedtls_ecp_export() uses &ecp_kp->MBEDTLS_PRIVATE(grp))*/ --+ mbedtls_ecp_point_init(p); --+ mbedtls_ecp_point *ecp_kp_Q = &ecp_kp->MBEDTLS_PRIVATE(Q); --+ if (mbedtls_ecp_copy(p, ecp_kp_Q)) { --+ mbedtls_ecp_point_free(p); --+ os_free(p); --+ p = NULL; --+ } --+ } --+ return (struct crypto_ec_point *)p; --+} --+ --+struct crypto_bignum * --+crypto_ec_key_get_private_key(struct crypto_ec_key *key) --+{ --+ mbedtls_ecp_keypair *ecp_kp = mbedtls_pk_ec(*(mbedtls_pk_context *)key); --+ if (ecp_kp == NULL) --+ return NULL; --+ mbedtls_mpi *bn = os_malloc(sizeof(*bn)); --+ if (bn) { --+ /*(mbedtls_ecp_export() uses &ecp_kp->MBEDTLS_PRIVATE(grp))*/ --+ mbedtls_mpi_init(bn); --+ mbedtls_mpi *ecp_kp_d = &ecp_kp->MBEDTLS_PRIVATE(d); --+ if (mbedtls_mpi_copy(bn, ecp_kp_d)) { --+ mbedtls_mpi_free(bn); --+ os_free(bn); --+ bn = NULL; --+ } --+ } --+ return (struct crypto_bignum *)bn; --+} --+ --+#endif /* CRYPTO_MBEDTLS_CRYPTO_EC_DPP */ --+ --+static mbedtls_md_type_t crypto_ec_key_sign_md(size_t len) --+{ --+ /* get mbedtls_md_type_t from length of hash data to be signed */ --+ switch (len) { --+ case 64: return MBEDTLS_MD_SHA512; --+ case 48: return MBEDTLS_MD_SHA384; --+ case 32: return MBEDTLS_MD_SHA256; --+ case 20: return MBEDTLS_MD_SHA1; --+ case 16: return MBEDTLS_MD_MD5; --+ default: return MBEDTLS_MD_NONE; --+ } --+} --+ --+struct wpabuf * crypto_ec_key_sign(struct crypto_ec_key *key, const u8 *data, --+ size_t len) --+{ --+ #ifndef MBEDTLS_PK_SIGNATURE_MAX_SIZE /*(defined since mbedtls 2.20.0)*/ --+ #if MBEDTLS_ECDSA_MAX_LEN > MBEDTLS_MPI_MAX_SIZE --+ #define MBEDTLS_PK_SIGNATURE_MAX_SIZE MBEDTLS_ECDSA_MAX_LEN --+ #else --+ #define MBEDTLS_PK_SIGNATURE_MAX_SIZE MBEDTLS_MPI_MAX_SIZE --+ #endif --+ #endif --+ size_t sig_len = MBEDTLS_PK_SIGNATURE_MAX_SIZE; --+ struct wpabuf *buf = wpabuf_alloc(sig_len); --+ if (buf == NULL) --+ return NULL; --+ if (mbedtls_pk_sign((mbedtls_pk_context *)key, --+ crypto_ec_key_sign_md(len), data, len, --+ wpabuf_mhead_u8(buf), --+ #if MBEDTLS_VERSION_NUMBER >= 0x03000000 /* mbedtls 3.0.0 */ --+ sig_len, --+ #endif --+ &sig_len, --+ mbedtls_ctr_drbg_random, --+ crypto_mbedtls_ctr_drbg()) == 0) { --+ wpabuf_put(buf, sig_len); --+ return buf; --+ } --+ --+ wpabuf_free(buf); --+ return NULL; --+} --+ --+#ifdef CRYPTO_MBEDTLS_CRYPTO_EC_DPP --+struct wpabuf * crypto_ec_key_sign_r_s(struct crypto_ec_key *key, --+ const u8 *data, size_t len) --+{ --+ mbedtls_ecp_keypair *ecp_kp = mbedtls_pk_ec(*(mbedtls_pk_context *)key); --+ if (ecp_kp == NULL) --+ return NULL; --+ --+ size_t sig_len = MBEDTLS_ECDSA_MAX_LEN; --+ u8 buf[MBEDTLS_ECDSA_MAX_LEN]; --+ if (mbedtls_ecdsa_write_signature(ecp_kp, crypto_ec_key_sign_md(len), --+ data, len, buf, --+ #if MBEDTLS_VERSION_NUMBER >= 0x03000000 /* mbedtls 3.0.0 */ --+ sig_len, --+ #endif --+ &sig_len, --+ mbedtls_ctr_drbg_random, --+ crypto_mbedtls_ctr_drbg())) { --+ return NULL; --+ } --+ --+ /*(mbedtls_ecdsa_write_signature() writes signature in ASN.1)*/ --+ /* parse ASN.1 to get r and s and lengths */ --+ u8 *p = buf, *r, *s; --+ u8 *end = p + sig_len; --+ size_t rlen, slen; --+ mbedtls_asn1_get_tag(&p, end, &rlen, --+ MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE); --+ mbedtls_asn1_get_tag(&p, end, &rlen, MBEDTLS_ASN1_INTEGER); --+ r = p; --+ p += rlen; --+ mbedtls_asn1_get_tag(&p, end, &slen, MBEDTLS_ASN1_INTEGER); --+ s = p; --+ --+ /* write raw r and s into out --+ * (including removal of leading 0 if added for ASN.1 integer) --+ * note: DPP caller expects raw r, s each padded to prime len */ --+ mbedtls_ecp_group *ecp_kp_grp = &ecp_kp->MBEDTLS_PRIVATE(grp); --+ size_t plen = CRYPTO_EC_plen(ecp_kp_grp); --+ if (rlen > plen) { --+ r += (rlen - plen); --+ rlen = plen; --+ } --+ if (slen > plen) { --+ s += (slen - plen); --+ slen = plen; --+ } --+ struct wpabuf *out = wpabuf_alloc(plen*2); --+ if (out) { --+ wpabuf_put(out, plen*2); --+ p = wpabuf_mhead_u8(out); --+ os_memset(p, 0, plen*2); --+ os_memcpy(p+plen*1-rlen, r, rlen); --+ os_memcpy(p+plen*2-slen, s, slen); --+ } --+ return out; --+} --+#endif /* CRYPTO_MBEDTLS_CRYPTO_EC_DPP */ --+ --+int crypto_ec_key_verify_signature(struct crypto_ec_key *key, const u8 *data, --+ size_t len, const u8 *sig, size_t sig_len) --+{ --+ switch (mbedtls_pk_verify((mbedtls_pk_context *)key, --+ crypto_ec_key_sign_md(len), data, len, --+ sig, sig_len)) { --+ case 0: --+ /*case MBEDTLS_ERR_ECP_SIG_LEN_MISMATCH:*//* XXX: allow? */ --+ return 1; --+ case MBEDTLS_ERR_ECP_VERIFY_FAILED: --+ return 0; --+ default: --+ return -1; --+ } --+} --+ --+#ifdef CRYPTO_MBEDTLS_CRYPTO_EC_DPP --+int crypto_ec_key_verify_signature_r_s(struct crypto_ec_key *key, --+ const u8 *data, size_t len, --+ const u8 *r, size_t r_len, --+ const u8 *s, size_t s_len) --+{ --+ /* reimplement mbedtls_ecdsa_read_signature() without encoding r and s --+ * into ASN.1 just for mbedtls_ecdsa_read_signature() to decode ASN.1 */ --+ mbedtls_ecp_keypair *ecp_kp = mbedtls_pk_ec(*(mbedtls_pk_context *)key); --+ if (ecp_kp == NULL) --+ return -1; --+ mbedtls_ecp_group *ecp_kp_grp = &ecp_kp->MBEDTLS_PRIVATE(grp); --+ mbedtls_ecp_point *ecp_kp_Q = &ecp_kp->MBEDTLS_PRIVATE(Q); --+ --+ mbedtls_mpi mpi_r; --+ mbedtls_mpi mpi_s; --+ mbedtls_mpi_init(&mpi_r); --+ mbedtls_mpi_init(&mpi_s); --+ int ret = mbedtls_mpi_read_binary(&mpi_r, r, r_len) --+ || mbedtls_mpi_read_binary(&mpi_s, s, s_len) ? -1 : 0; --+ if (ret == 0) { --+ ret = mbedtls_ecdsa_verify(ecp_kp_grp, data, len, --+ ecp_kp_Q, &mpi_r, &mpi_s); --+ ret = ret ? ret == MBEDTLS_ERR_ECP_BAD_INPUT_DATA ? 0 : -1 : 1; --+ } --+ mbedtls_mpi_free(&mpi_r); --+ mbedtls_mpi_free(&mpi_s); --+ return ret; --+} --+#endif /* CRYPTO_MBEDTLS_CRYPTO_EC_DPP */ --+ --+int crypto_ec_key_group(struct crypto_ec_key *key) --+{ --+ mbedtls_ecp_keypair *ecp_kp = mbedtls_pk_ec(*(mbedtls_pk_context *)key); --+ if (ecp_kp == NULL) --+ return -1; --+ mbedtls_ecp_group *ecp_group = &ecp_kp->MBEDTLS_PRIVATE(grp); --+ return crypto_mbedtls_ike_id_from_ecp_group_id(ecp_group->id); --+} --+ --+#ifdef CRYPTO_MBEDTLS_CRYPTO_EC_DPP --+ --+int crypto_ec_key_cmp(struct crypto_ec_key *key1, struct crypto_ec_key *key2) --+{ --+#if 0 /*(DPP is passing two public keys; unable to use pk_check_pair())*/ --+ #if MBEDTLS_VERSION_NUMBER < 0x03000000 /* mbedtls 3.0.0 */ --+ return mbedtls_pk_check_pair((const mbedtls_pk_context *)key1, --+ (const mbedtls_pk_context *)key2) ? -1 : 0; --+ #else --+ return mbedtls_pk_check_pair((const mbedtls_pk_context *)key1, --+ (const mbedtls_pk_context *)key2, --+ mbedtls_ctr_drbg_random, --+ crypto_mbedtls_ctr_drbg()) ? -1 : 0; --+ #endif --+#else --+ mbedtls_ecp_keypair *ecp_kp1=mbedtls_pk_ec(*(mbedtls_pk_context *)key1); --+ mbedtls_ecp_keypair *ecp_kp2=mbedtls_pk_ec(*(mbedtls_pk_context *)key2); --+ if (ecp_kp1 == NULL || ecp_kp2 == NULL) --+ return -1; --+ mbedtls_ecp_group *ecp_kp1_grp = &ecp_kp1->MBEDTLS_PRIVATE(grp); --+ mbedtls_ecp_group *ecp_kp2_grp = &ecp_kp2->MBEDTLS_PRIVATE(grp); --+ mbedtls_ecp_point *ecp_kp1_Q = &ecp_kp1->MBEDTLS_PRIVATE(Q); --+ mbedtls_ecp_point *ecp_kp2_Q = &ecp_kp2->MBEDTLS_PRIVATE(Q); --+ return ecp_kp1_grp->id != ecp_kp2_grp->id --+ || mbedtls_ecp_point_cmp(ecp_kp1_Q, ecp_kp2_Q) ? -1 : 0; --+#endif --+} --+ --+void crypto_ec_key_debug_print(const struct crypto_ec_key *key, --+ const char *title) --+{ --+ /* TBD: what info is desirable here and in what human readable format?*/ --+ /*(crypto_openssl.c prints a human-readably public key and attributes)*/ --+ #if 0 --+ struct mbedtls_pk_debug_item debug_item; --+ if (mbedtls_pk_debug((const mbedtls_pk_context *)key, &debug_item)) --+ return; --+ /* ... */ --+ #endif --+ wpa_printf(MSG_DEBUG, "%s: %s not implemented", title, __func__); --+} --+ --+#endif /* CRYPTO_MBEDTLS_CRYPTO_EC_DPP */ --+ --+#endif /* CRYPTO_MBEDTLS_CRYPTO_EC */ --+ --+ --+#ifdef CRYPTO_MBEDTLS_CRYPTO_CSR --+ --+#include --+#include --+ --+struct crypto_csr * crypto_csr_init(void) --+{ --+ mbedtls_x509write_csr *csr = os_malloc(sizeof(*csr)); --+ if (csr != NULL) --+ mbedtls_x509write_csr_init(csr); --+ return (struct crypto_csr *)csr; --+} --+ --+struct crypto_csr * crypto_csr_verify(const struct wpabuf *req) --+{ --+ /* future: look for alternatives to MBEDTLS_PRIVATE() access */ --+ --+ /* sole caller src/common/dpp_crypto.c:dpp_validate_csr() --+ * uses (mbedtls_x509_csr *) to obtain CSR_ATTR_CHALLENGE_PASSWORD --+ * so allocate different object (mbedtls_x509_csr *) and special-case --+ * object when used in crypto_csr_get_attribute() and when free()d in --+ * crypto_csr_deinit(). */ --+ --+ mbedtls_x509_csr *csr = os_malloc(sizeof(*csr)); --+ if (csr == NULL) --+ return NULL; --+ mbedtls_x509_csr_init(csr); --+ const mbedtls_md_info_t *md_info; --+ unsigned char digest[MBEDTLS_MD_MAX_SIZE]; --+ if (mbedtls_x509_csr_parse_der(csr,wpabuf_head(req),wpabuf_len(req))==0 --+ && (md_info=mbedtls_md_info_from_type(csr->MBEDTLS_PRIVATE(sig_md))) --+ != NULL --+ && mbedtls_md(md_info, csr->cri.p, csr->cri.len, digest) == 0) { --+ switch (mbedtls_pk_verify(&csr->pk,csr->MBEDTLS_PRIVATE(sig_md), --+ digest, mbedtls_md_get_size(md_info), --+ csr->MBEDTLS_PRIVATE(sig).p, --+ csr->MBEDTLS_PRIVATE(sig).len)) { --+ case 0: --+ /*case MBEDTLS_ERR_ECP_SIG_LEN_MISMATCH:*//* XXX: allow? */ --+ return (struct crypto_csr *)((uintptr_t)csr | 1uL); --+ default: --+ break; --+ } --+ } --+ --+ mbedtls_x509_csr_free(csr); --+ os_free(csr); --+ return NULL; --+} --+ --+void crypto_csr_deinit(struct crypto_csr *csr) --+{ --+ if ((uintptr_t)csr & 1uL) { --+ csr = (struct crypto_csr *)((uintptr_t)csr & ~1uL); --+ mbedtls_x509_csr_free((mbedtls_x509_csr *)csr); --+ } --+ else --+ mbedtls_x509write_csr_free((mbedtls_x509write_csr *)csr); --+ os_free(csr); --+} --+ --+int crypto_csr_set_ec_public_key(struct crypto_csr *csr, --+ struct crypto_ec_key *key) --+{ --+ mbedtls_x509write_csr_set_key((mbedtls_x509write_csr *)csr, --+ (mbedtls_pk_context *)key); --+ return 0; --+} --+ --+int crypto_csr_set_name(struct crypto_csr *csr, enum crypto_csr_name type, --+ const char *name) --+{ --+ /* specialized for src/common/dpp_crypto.c */ --+ --+ /* sole caller src/common/dpp_crypto.c:dpp_build_csr() --+ * calls this function only once, using type == CSR_NAME_CN --+ * (If called more than once, this code would need to append --+ * components to the subject name, which we could do by --+ * appending to (mbedtls_x509write_csr *) private member --+ * mbedtls_asn1_named_data *MBEDTLS_PRIVATE(subject)) */ --+ --+ const char *label; --+ switch (type) { --+ case CSR_NAME_CN: label = "CN="; break; --+ case CSR_NAME_SN: label = "SN="; break; --+ case CSR_NAME_C: label = "C="; break; --+ case CSR_NAME_O: label = "O="; break; --+ case CSR_NAME_OU: label = "OU="; break; --+ default: return -1; --+ } --+ --+ size_t len = strlen(name); --+ struct wpabuf *buf = wpabuf_alloc(3+len+1); --+ if (buf == NULL) --+ return -1; --+ wpabuf_put_data(buf, label, strlen(label)); --+ wpabuf_put_data(buf, name, len+1); /*(include trailing '\0')*/ --+ /* Note: 'name' provided is set as given and should be backslash-escaped --+ * by caller when necessary, e.g. literal ',' which are not separating --+ * components should be backslash-escaped */ --+ --+ int ret = --+ mbedtls_x509write_csr_set_subject_name((mbedtls_x509write_csr *)csr, --+ wpabuf_head(buf)) ? -1 : 0; --+ wpabuf_free(buf); --+ return ret; --+} --+ --+/* OBJ_pkcs9_challengePassword 1 2 840 113549 1 9 7 */ --+static const char OBJ_pkcs9_challengePassword[] = MBEDTLS_OID_PKCS9 "\x07"; --+ --+int crypto_csr_set_attribute(struct crypto_csr *csr, enum crypto_csr_attr attr, --+ int attr_type, const u8 *value, size_t len) --+{ --+ /* specialized for src/common/dpp_crypto.c */ --+ /* sole caller src/common/dpp_crypto.c:dpp_build_csr() passes --+ * attr == CSR_ATTR_CHALLENGE_PASSWORD --+ * attr_type == ASN1_TAG_UTF8STRING */ --+ --+ const char *oid; --+ size_t oid_len; --+ switch (attr) { --+ case CSR_ATTR_CHALLENGE_PASSWORD: --+ oid = OBJ_pkcs9_challengePassword; --+ oid_len = sizeof(OBJ_pkcs9_challengePassword)-1; --+ break; --+ default: --+ return -1; --+ } --+ --+ #if 0 /*(incorrect; sets an extension, not an attribute)*/ --+ return mbedtls_x509write_csr_set_extension((mbedtls_x509write_csr *)csr, --+ oid, oid_len, --+ #if MBEDTLS_VERSION_NUMBER >= 0x03000000 /* mbedtls 3.0.0 */ --+ 0, /*(critical flag)*/ --+ #endif --+ value, len) ? -1 : 0; --+ #else --+ (void)oid; --+ (void)oid_len; --+ #endif --+ --+ /* mbedtls does not currently provide way to set an attribute in a CSR: --+ * https://github.com/Mbed-TLS/mbedtls/issues/4886 */ --+ wpa_printf(MSG_ERROR, --+ "mbedtls does not currently support setting challengePassword " --+ "attribute in CSR"); --+ return -1; --+} --+ --+const u8 * mbedtls_x509_csr_attr_oid_value(mbedtls_x509_csr *csr, --+ const char *oid, size_t oid_len, --+ size_t *vlen, int *vtype) --+{ --+ /* Note: mbedtls_x509_csr_parse_der() has parsed and validated CSR, --+ * so validation checks are not repeated here --+ * --+ * It would be nicer if (mbedtls_x509_csr *) had an mbedtls_x509_buf of --+ * Attributes (or at least a pointer) since mbedtls_x509_csr_parse_der() --+ * already parsed the rest of CertificationRequestInfo, some of which is --+ * repeated here to step to Attributes. Since csr->subject_raw.p points --+ * into csr->cri.p, which points into csr->raw.p, step over version and --+ * subject of CertificationRequestInfo (SEQUENCE) */ --+ unsigned char *p = csr->subject_raw.p + csr->subject_raw.len; --+ unsigned char *end = csr->cri.p + csr->cri.len, *ext; --+ size_t len; --+ --+ /* step over SubjectPublicKeyInfo */ --+ mbedtls_asn1_get_tag(&p, end, &len, --+ MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE); --+ p += len; --+ --+ /* Attributes --+ * { ATTRIBUTE:IOSet } ::= SET OF { SEQUENCE { OID, value } } --+ */ --+ if (mbedtls_asn1_get_tag(&p, end, &len, --+ MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_CONTEXT_SPECIFIC) != 0) { --+ return NULL; --+ } --+ while (p < end) { --+ if (mbedtls_asn1_get_tag(&p, end, &len, --+ MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE) != 0) { --+ return NULL; --+ } --+ ext = p; --+ p += len; --+ --+ if (mbedtls_asn1_get_tag(&ext,end,&len,MBEDTLS_ASN1_OID) != 0) --+ return NULL; --+ if (oid_len != len || 0 != memcmp(ext, oid, oid_len)) --+ continue; --+ --+ /* found oid; return value */ --+ *vtype = *ext++; /* tag */ --+ return (mbedtls_asn1_get_len(&ext,end,vlen) == 0) ? ext : NULL; --+ } --+ --+ return NULL; --+} --+ --+const u8 * crypto_csr_get_attribute(struct crypto_csr *csr, --+ enum crypto_csr_attr attr, --+ size_t *len, int *type) --+{ --+ /* specialized for src/common/dpp_crypto.c */ --+ /* sole caller src/common/dpp_crypto.c:dpp_build_csr() passes --+ * attr == CSR_ATTR_CHALLENGE_PASSWORD */ --+ --+ const char *oid; --+ size_t oid_len; --+ switch (attr) { --+ case CSR_ATTR_CHALLENGE_PASSWORD: --+ oid = OBJ_pkcs9_challengePassword; --+ oid_len = sizeof(OBJ_pkcs9_challengePassword)-1; --+ break; --+ default: --+ return NULL; --+ } --+ --+ /* see crypto_csr_verify(); expecting (mbedtls_x509_csr *) tagged |=1 */ --+ if (!((uintptr_t)csr & 1uL)) --+ return NULL; --+ csr = (struct crypto_csr *)((uintptr_t)csr & ~1uL); --+ --+ return mbedtls_x509_csr_attr_oid_value((mbedtls_x509_csr *)csr, --+ oid, oid_len, len, type); --+} --+ --+struct wpabuf * crypto_csr_sign(struct crypto_csr *csr, --+ struct crypto_ec_key *key, --+ enum crypto_hash_alg algo) --+{ --+ mbedtls_md_type_t sig_md; --+ switch (algo) { --+ #ifdef MBEDTLS_SHA256_C --+ case CRYPTO_HASH_ALG_SHA256: sig_md = MBEDTLS_MD_SHA256; break; --+ #endif --+ #ifdef MBEDTLS_SHA512_C --+ case CRYPTO_HASH_ALG_SHA384: sig_md = MBEDTLS_MD_SHA384; break; --+ case CRYPTO_HASH_ALG_SHA512: sig_md = MBEDTLS_MD_SHA512; break; --+ #endif --+ default: --+ return NULL; --+ } --+ mbedtls_x509write_csr_set_md_alg((mbedtls_x509write_csr *)csr, sig_md); --+ --+ #if 0 --+ unsigned char key_usage = MBEDTLS_X509_KU_DIGITAL_SIGNATURE --+ | MBEDTLS_X509_KU_KEY_CERT_SIGN; --+ if (mbedtls_x509write_csr_set_key_usage((mbedtls_x509write_csr *)csr, --+ key_usage)) --+ return NULL; --+ #endif --+ --+ #if 0 --+ unsigned char ns_cert_type = MBEDTLS_X509_NS_CERT_TYPE_SSL_CLIENT --+ | MBEDTLS_X509_NS_CERT_TYPE_EMAIL; --+ if (mbedtls_x509write_csr_set_ns_cert_type((mbedtls_x509write_csr *)csr, --+ ns_cert_type)) --+ return NULL; --+ #endif --+ --+ #if 0 --+ /* mbedtls does not currently provide way to set an attribute in a CSR: --+ * https://github.com/Mbed-TLS/mbedtls/issues/4886 --+ * XXX: hwsim dpp_enterprise test fails due to this limitation. --+ * --+ * Current usage of this function is solely by dpp_build_csr(), --+ * so as a kludge, might consider custom (struct crypto_csr *) --+ * containing (mbedtls_x509write_csr *) and a list of attributes --+ * (i.e. challengePassword). Might have to totally reimplement --+ * mbedtls_x509write_csr_der(); underlying x509write_csr_der_internal() --+ * handles signing the CSR. (This is more work that appending an --+ * Attributes section to end of CSR and adjusting ASN.1 length of CSR.) --+ */ --+ #endif --+ --+ unsigned char buf[4096]; /* XXX: large enough? too large? */ --+ int len = mbedtls_x509write_csr_der((mbedtls_x509write_csr *)csr, --+ buf, sizeof(buf), --+ mbedtls_ctr_drbg_random, --+ crypto_mbedtls_ctr_drbg()); --+ if (len < 0) --+ return NULL; --+ /* Note: data is written at the end of the buffer! Use the --+ * return value to determine where you should start --+ * using the buffer */ --+ return wpabuf_alloc_copy(buf+sizeof(buf)-len, (size_t)len); --+} --+ --+#endif /* CRYPTO_MBEDTLS_CRYPTO_CSR */ --+ --+ --+#ifdef CRYPTO_MBEDTLS_CRYPTO_PKCS7 --+ --+#if 0 --+#include /* PKCS7 is not currently supported in mbedtls */ --+#include --+#endif --+ --+struct wpabuf * crypto_pkcs7_get_certificates(const struct wpabuf *pkcs7) --+{ --+ /* PKCS7 is not currently supported in mbedtls */ --+ return NULL; --+ --+#if 0 --+ /* https://github.com/naynajain/mbedtls-1 branch: development-pkcs7 --+ * (??? potential future contribution to mbedtls ???) */ --+ --+ /* Note: PKCS7 signature *is not* verified by this function. --+ * The function interface does not provide for passing a certificate */ --+ --+ mbedtls_pkcs7 mpkcs7; --+ mbedtls_pkcs7_init(&mpkcs7); --+ int pkcs7_type = mbedtls_pkcs7_parse_der(wpabuf_head(pkcs7), --+ wpabuf_len(pkcs7), --+ &mpkcs7); --+ wpabuf *buf = NULL; --+ do { --+ if (pkcs7_type < 0) --+ break; --+ --+ /* src/common/dpp.c:dpp_parse_cred_dot1x() interested in certs --+ * for wpa_supplicant/dpp_supplicant.c:wpas_dpp_add_network() --+ * (? are adding certificate headers and footers desired ?) */ --+ --+ /* development-pkcs7 branch does not currently provide --+ * additional interfaces to retrieve the parsed data */ --+ --+ mbedtls_x509_crt *certs = --+ &mpkcs7.MBEDTLS_PRIVATE(signed_data).MBEDTLS_PRIVATE(certs); --+ int ncerts = --+ mpkcs7.MBEDTLS_PRIVATE(signed_data).MBEDTLS_PRIVATE(no_of_certs); --+ --+ /* allocate buffer for PEM (base64-encoded DER) --+ * plus header, footer, newlines, and some extra */ --+ buf = wpabuf_alloc((wpabuf_len(pkcs7)+2)/3*4 + ncerts*64); --+ if (buf == NULL) --+ break; --+ --+ #define PEM_BEGIN_CRT "-----BEGIN CERTIFICATE-----\n" --+ #define PEM_END_CRT "-----END CERTIFICATE-----\n" --+ size_t olen; --+ for (int i = 0; i < ncerts; ++i) { --+ int ret = mbedtls_pem_write_buffer( --+ PEM_BEGIN_CRT, PEM_END_CRT, --+ certs[i].raw.p, certs[i].raw.len, --+ wpabuf_mhead(buf, 0), wpabuf_tailroom(buf), --+ &olen)); --+ if (ret == 0) --+ wpabuf_put(buf, olen); --+ } else { --+ if (ret == MBEDTLS_ERR_BASE64_BUFFER_TOO_SMALL) --+ ret = wpabuf_resize( --+ &buf,olen-wpabuf_tailroom(buf)); --+ if (ret == 0) { --+ --i;/*(adjust loop iterator for retry)*/ --+ continue; --+ } --+ wpabuf_free(buf); --+ buf = NULL; --+ break; --+ } --+ } --+ } while (0); --+ --+ mbedtls_pkcs7_free(&mpkcs7); --+ return buf; --+#endif --+} --+ --+#endif /* CRYPTO_MBEDTLS_CRYPTO_PKCS7 */ --+ --+ --+#ifdef MBEDTLS_ARC4_C --+#include --+int rc4_skip(const u8 *key, size_t keylen, size_t skip, --+ u8 *data, size_t data_len) --+{ --+ mbedtls_arc4_context ctx; --+ mbedtls_arc4_init(&ctx); --+ mbedtls_arc4_setup(&ctx, key, keylen); --+ --+ if (skip) { --+ /*(prefer [16] on ancient hardware with smaller cache lines)*/ --+ unsigned char skip_buf[64]; /*('skip' is generally small)*/ --+ /*os_memset(skip_buf, 0, sizeof(skip_buf));*/ /*(necessary?)*/ --+ size_t len; --+ do { --+ len = skip > sizeof(skip_buf) ? sizeof(skip_buf) : skip; --+ mbedtls_arc4_crypt(&ctx, len, skip_buf, skip_buf); --+ } while ((skip -= len)); --+ } --+ --+ int ret = mbedtls_arc4_crypt(&ctx, data_len, data, data); --+ mbedtls_arc4_free(&ctx); --+ return ret; --+} --+#endif --+ --+ --+/* duplicated in tls_mbedtls.c:tls_mbedtls_readfile()*/ --+__attribute_noinline__ --+static int crypto_mbedtls_readfile(const char *path, u8 **buf, size_t *n) --+{ --+ #if 0 /* #ifdef MBEDTLS_FS_IO */ --+ /*(includes +1 for '\0' needed by mbedtls PEM parsing funcs)*/ --+ if (mbedtls_pk_load_file(path, (unsigned char **)buf, n) != 0) { --+ wpa_printf(MSG_ERROR, "error: mbedtls_pk_load_file %s", path); --+ return -1; --+ } --+ #else --+ /*(use os_readfile() so that we can use os_free() --+ *(if we use mbedtls_pk_load_file() above, macros prevent calling free() --+ * directly #if defined(OS_REJECT_C_LIB_FUNCTIONS) and calling os_free() --+ * on buf aborts in tests if buf not allocated via os_malloc())*/ --+ *buf = (u8 *)os_readfile(path, n); --+ if (!*buf) { --+ wpa_printf(MSG_ERROR, "error: os_readfile %s", path); --+ return -1; --+ } --+ u8 *buf0 = os_realloc(*buf, *n+1); --+ if (!buf0) { --+ bin_clear_free(*buf, *n); --+ *buf = NULL; --+ return -1; --+ } --+ buf0[(*n)++] = '\0'; --+ *buf = buf0; --+ #endif --+ return 0; --+} --+ --+ --+#ifdef CRYPTO_MBEDTLS_CRYPTO_RSA --+#ifdef MBEDTLS_RSA_C --+ --+#include --+#include --+ --+struct crypto_rsa_key * crypto_rsa_key_read(const char *file, bool private_key) --+{ --+ /* mbedtls_pk_parse_keyfile() and mbedtls_pk_parse_public_keyfile() --+ * require #ifdef MBEDTLS_FS_IO in mbedtls library. Prefer to use --+ * crypto_mbedtls_readfile(), which wraps os_readfile() */ --+ u8 *data; --+ size_t len; --+ if (crypto_mbedtls_readfile(file, &data, &len) != 0) --+ return NULL; --+ --+ mbedtls_pk_context *ctx = os_malloc(sizeof(*ctx)); --+ if (ctx == NULL) { --+ bin_clear_free(data, len); --+ return NULL; --+ } --+ mbedtls_pk_init(ctx); --+ --+ int rc; --+ rc = (private_key --+ ? mbedtls_pk_parse_key(ctx, data, len, NULL, 0 --+ #if MBEDTLS_VERSION_NUMBER >= 0x03000000 /* mbedtls 3.0.0 */ --+ ,mbedtls_ctr_drbg_random, --+ crypto_mbedtls_ctr_drbg() --+ #endif --+ ) --+ : mbedtls_pk_parse_public_key(ctx, data, len)) == 0 --+ && mbedtls_pk_can_do(ctx, MBEDTLS_PK_RSA); --+ --+ bin_clear_free(data, len); --+ --+ if (rc) { --+ /* use MBEDTLS_RSA_PKCS_V21 padding for RSAES-OAEP */ --+ /* use MBEDTLS_MD_SHA256 for these hostap interfaces */ --+ #if MBEDTLS_VERSION_NUMBER < 0x03000000 /* mbedtls 3.0.0 */ --+ /*(no return value in mbedtls 2.x)*/ --+ mbedtls_rsa_set_padding(mbedtls_pk_rsa(*ctx), --+ MBEDTLS_RSA_PKCS_V21, --+ MBEDTLS_MD_SHA256); --+ #else --+ if (mbedtls_rsa_set_padding(mbedtls_pk_rsa(*ctx), --+ MBEDTLS_RSA_PKCS_V21, --+ MBEDTLS_MD_SHA256) == 0) --+ #endif --+ return (struct crypto_rsa_key *)ctx; --+ } --+ --+ mbedtls_pk_free(ctx); --+ os_free(ctx); --+ return NULL; --+} --+ --+struct wpabuf * crypto_rsa_oaep_sha256_encrypt(struct crypto_rsa_key *key, --+ const struct wpabuf *in) --+{ --+ mbedtls_rsa_context *pk_rsa = mbedtls_pk_rsa(*(mbedtls_pk_context*)key); --+ size_t olen = mbedtls_rsa_get_len(pk_rsa); --+ struct wpabuf *buf = wpabuf_alloc(olen); --+ if (buf == NULL) --+ return NULL; --+ --+ /* mbedtls_pk_encrypt() takes a few more hops to get to same func */ --+ if (mbedtls_rsa_rsaes_oaep_encrypt(pk_rsa, --+ mbedtls_ctr_drbg_random, --+ crypto_mbedtls_ctr_drbg(), --+ #if MBEDTLS_VERSION_NUMBER < 0x03000000 /* mbedtls 3.0.0 */ --+ MBEDTLS_RSA_PRIVATE, --+ #endif --+ NULL, 0, --+ wpabuf_len(in), wpabuf_head(in), --+ wpabuf_put(buf, olen)) == 0) { --+ return buf; --+ } --+ --+ wpabuf_clear_free(buf); --+ return NULL; --+} --+ --+struct wpabuf * crypto_rsa_oaep_sha256_decrypt(struct crypto_rsa_key *key, --+ const struct wpabuf *in) --+{ --+ mbedtls_rsa_context *pk_rsa = mbedtls_pk_rsa(*(mbedtls_pk_context*)key); --+ size_t olen = mbedtls_rsa_get_len(pk_rsa); --+ struct wpabuf *buf = wpabuf_alloc(olen); --+ if (buf == NULL) --+ return NULL; --+ --+ /* mbedtls_pk_decrypt() takes a few more hops to get to same func */ --+ if (mbedtls_rsa_rsaes_oaep_decrypt(pk_rsa, --+ mbedtls_ctr_drbg_random, --+ crypto_mbedtls_ctr_drbg(), --+ #if MBEDTLS_VERSION_NUMBER < 0x03000000 /* mbedtls 3.0.0 */ --+ MBEDTLS_RSA_PUBLIC, --+ #endif --+ NULL, 0, &olen, wpabuf_head(in), --+ wpabuf_mhead(buf), olen) == 0) { --+ wpabuf_put(buf, olen); --+ return buf; --+ } --+ --+ wpabuf_clear_free(buf); --+ return NULL; --+} --+ --+void crypto_rsa_key_free(struct crypto_rsa_key *key) --+{ --+ mbedtls_pk_free((mbedtls_pk_context *)key); --+ os_free(key); --+} --+ --+#endif /* MBEDTLS_RSA_C */ --+#endif /* CRYPTO_MBEDTLS_CRYPTO_RSA */ --+ --+#ifdef CRYPTO_MBEDTLS_CRYPTO_HPKE --+ --+struct wpabuf * hpke_base_seal(enum hpke_kem_id kem_id, --+ enum hpke_kdf_id kdf_id, --+ enum hpke_aead_id aead_id, --+ struct crypto_ec_key *peer_pub, --+ const u8 *info, size_t info_len, --+ const u8 *aad, size_t aad_len, --+ const u8 *pt, size_t pt_len) --+{ --+ /* not yet implemented */ --+ return NULL; --+} --+ --+struct wpabuf * hpke_base_open(enum hpke_kem_id kem_id, --+ enum hpke_kdf_id kdf_id, --+ enum hpke_aead_id aead_id, --+ struct crypto_ec_key *own_priv, --+ const u8 *info, size_t info_len, --+ const u8 *aad, size_t aad_len, --+ const u8 *enc_ct, size_t enc_ct_len) --+{ --+ /* not yet implemented */ --+ return NULL; --+} --+ --+#endif ----- /dev/null --+++ b/src/crypto/tls_mbedtls.c --@@ -0,0 +1,3313 @@ --+/* --+ * SSL/TLS interface functions for mbed TLS --+ * --+ * SPDX-FileCopyrightText: 2022 Glenn Strauss --+ * SPDX-License-Identifier: BSD-3-Clause --+ * --+ * This software may be distributed under the terms of the BSD license. --+ * See README for more details. --+ * --+ * template: src/crypto/tls_none.c --+ * reference: src/crypto/tls_*.c --+ * --+ * Known Limitations: --+ * - no TLSv1.3 (not available in mbedtls 2.x; experimental in mbedtls 3.x) --+ * - no OCSP (not yet available in mbedtls) --+ * - mbedtls does not support all certificate encodings used by hwsim tests --+ * PCKS#5 v1.5 --+ * PCKS#12 --+ * DH DSA --+ * - EAP-FAST, EAP-TEAP session ticket support not implemented in tls_mbedtls.c --+ * - mbedtls does not currently provide way to set an attribute in a CSR --+ * https://github.com/Mbed-TLS/mbedtls/issues/4886 --+ * so tests/hwsim dpp_enterprise tests fail --+ * - DPP2 not supported --+ * PKCS#7 parsing is not supported in mbedtls --+ * See crypto_mbedtls.c:crypto_pkcs7_get_certificates() comments --+ * - DPP3 not supported --+ * hpke_base_seal() and hpke_base_seal() not implemented in crypto_mbedtls.c --+ * --+ * Status: --+ * - code written to be compatible with mbedtls 2.x and mbedtls 3.x --+ * (currently requires mbedtls >= 2.27.0 for mbedtls_mpi_random()) --+ * (currently requires mbedtls >= 2.18.0 for mbedtls_ssl_tls_prf()) --+ * - builds with tests/build/build-wpa_supplicant-mbedtls.config --+ * - passes all tests/ crypto module tests (incomplete coverage) --+ * ($ cd tests; make clean; make -j 4 run-tests CONFIG_TLS=mbedtls) --+ * - passes almost all tests/hwsim tests --+ * (hwsim tests skipped for missing features) --+ * --+ * RFE: --+ * - EAP-FAST, EAP-TEAP session ticket support not implemented in tls_mbedtls.c --+ * - client/server session resumption, and/or save client session ticket --+ */ --+ --+#include "includes.h" --+#include "common.h" --+ --+#include --+#include --+#include --+#include --+#include --+#include /* mbedtls_calloc() mbedtls_free() */ --+#include /* mbedtls_platform_zeroize() */ --+#include --+#include --+#include --+#include --+ --+#if MBEDTLS_VERSION_NUMBER >= 0x02040000 /* mbedtls 2.4.0 */ --+#include --+#else --+#include --+#endif --+ --+#ifndef MBEDTLS_PRIVATE --+#define MBEDTLS_PRIVATE(x) x --+#endif --+ --+#if MBEDTLS_VERSION_NUMBER < 0x03020000 /* mbedtls 3.2.0 */ --+#define mbedtls_ssl_get_ciphersuite_id_from_ssl(ssl) \ --+ ((ssl)->MBEDTLS_PRIVATE(session) \ --+ ?(ssl)->MBEDTLS_PRIVATE(session)->MBEDTLS_PRIVATE(ciphersuite) \ --+ : 0) --+#define mbedtls_ssl_ciphersuite_get_name(info) \ --+ (info)->MBEDTLS_PRIVATE(name) --+#endif --+ --+#include "crypto.h" /* sha256_vector() */ --+#include "tls.h" --+ --+#ifndef SHA256_DIGEST_LENGTH --+#define SHA256_DIGEST_LENGTH 32 --+#endif --+ --+#ifndef MBEDTLS_EXPKEY_FIXED_SECRET_LEN --+#define MBEDTLS_EXPKEY_FIXED_SECRET_LEN 48 --+#endif --+ --+#ifndef MBEDTLS_EXPKEY_RAND_LEN --+#define MBEDTLS_EXPKEY_RAND_LEN 32 --+#endif --+ --+#if MBEDTLS_VERSION_NUMBER >= 0x03000000 /* mbedtls 3.0.0 */ --+static mbedtls_ssl_export_keys_t tls_connection_export_keys_cb; --+#elif MBEDTLS_VERSION_NUMBER >= 0x02120000 /* mbedtls 2.18.0 */ --+static mbedtls_ssl_export_keys_ext_t tls_connection_export_keys_cb; --+#else /*(not implemented; return error)*/ --+#define mbedtls_ssl_tls_prf(a,b,c,d,e,f,g,h) (-1) --+typedef mbedtls_tls_prf_types int; --+#endif --+ --+ --+/* hostapd/wpa_supplicant provides forced_memzero(), --+ * but prefer mbedtls_platform_zeroize() */ --+#define forced_memzero(ptr,sz) mbedtls_platform_zeroize(ptr,sz) --+ --+ --+#if defined(EAP_FAST) || defined(EAP_FAST_DYNAMIC) || defined(EAP_SERVER_FAST) \ --+ || defined(EAP_TEAP) || defined(EAP_SERVER_TEAP) --+#ifdef MBEDTLS_SSL_SESSION_TICKETS --+#ifdef MBEDTLS_SSL_TICKET_C --+#define TLS_MBEDTLS_SESSION_TICKETS --+#if defined(EAP_TEAP) || defined(EAP_SERVER_TEAP) --+#define TLS_MBEDTLS_EAP_TEAP --+#endif --+#if !defined(CONFIG_FIPS) /* EAP-FAST keys cannot be exported in FIPS mode */ --+#if defined(EAP_FAST) || defined(EAP_FAST_DYNAMIC) || defined(EAP_SERVER_FAST) --+#define TLS_MBEDTLS_EAP_FAST --+#endif --+#endif --+#endif --+#endif --+#endif --+ --+ --+struct tls_conf { --+ mbedtls_ssl_config conf; --+ --+ unsigned int verify_peer:1; --+ unsigned int verify_depth0_only:1; --+ unsigned int check_crl:2; /*(needs :2 bits for 0, 1, 2)*/ --+ unsigned int check_crl_strict:1; /*(needs :1 bit for 0, 1)*/ --+ unsigned int ca_cert_probe:1; --+ unsigned int has_ca_cert:1; --+ unsigned int has_client_cert:1; --+ unsigned int has_private_key:1; --+ unsigned int suiteb128:1; --+ unsigned int suiteb192:1; --+ mbedtls_x509_crl *crl; --+ mbedtls_x509_crt ca_cert; --+ mbedtls_x509_crt client_cert; --+ mbedtls_pk_context private_key; --+ --+ uint32_t refcnt; --+ --+ unsigned int flags; --+ char *subject_match; --+ char *altsubject_match; --+ char *suffix_match; --+ char *domain_match; --+ char *check_cert_subject; --+ u8 ca_cert_hash[SHA256_DIGEST_LENGTH]; --+ --+ int *ciphersuites; /* list of ciphersuite ids for mbedtls_ssl_config */ --+#if MBEDTLS_VERSION_NUMBER < 0x03010000 /* mbedtls 3.1.0 */ --+ mbedtls_ecp_group_id *curves; --+#else --+ uint16_t *curves; /* list of curve ids for mbedtls_ssl_config */ --+#endif --+}; --+ --+ --+struct tls_global { --+ struct tls_conf *tls_conf; --+ char *ocsp_stapling_response; --+ mbedtls_ctr_drbg_context *ctr_drbg; /*(see crypto_mbedtls.c)*/ --+ #ifdef MBEDTLS_SSL_SESSION_TICKETS --+ mbedtls_ssl_ticket_context ticket_ctx; --+ #endif --+ char *ca_cert_file; --+ struct os_reltime crl_reload_previous; --+ unsigned int crl_reload_interval; --+ uint32_t refcnt; --+ struct tls_config init_conf; --+}; --+ --+static struct tls_global tls_ctx_global; --+ --+ --+struct tls_connection { --+ struct tls_conf *tls_conf; --+ struct wpabuf *push_buf; --+ struct wpabuf *pull_buf; --+ size_t pull_buf_offset; --+ --+ unsigned int established:1; --+ unsigned int resumed:1; --+ unsigned int verify_peer:1; --+ unsigned int is_server:1; --+ --+ mbedtls_ssl_context ssl; --+ --+ mbedtls_tls_prf_types tls_prf_type; --+ size_t expkey_keyblock_size; --+ size_t expkey_secret_len; --+ #if MBEDTLS_VERSION_NUMBER < 0x03000000 /* mbedtls 3.0.0 */ --+ unsigned char expkey_secret[MBEDTLS_EXPKEY_FIXED_SECRET_LEN]; --+ #else --+ unsigned char expkey_secret[MBEDTLS_MD_MAX_SIZE]; --+ #endif --+ unsigned char expkey_randbytes[MBEDTLS_EXPKEY_RAND_LEN*2]; --+ --+ int read_alerts, write_alerts, failed; --+ --+ #ifdef TLS_MBEDTLS_SESSION_TICKETS --+ tls_session_ticket_cb session_ticket_cb; --+ void *session_ticket_cb_ctx; --+ unsigned char *clienthello_session_ticket; --+ size_t clienthello_session_ticket_len; --+ #endif --+ char *peer_subject; /* peer subject info for authenticated peer */ --+ struct wpabuf *success_data; --+}; --+ --+ --+#ifndef __has_attribute --+#define __has_attribute(x) 0 --+#endif --+ --+#ifndef __GNUC_PREREQ --+#define __GNUC_PREREQ(maj,min) 0 --+#endif --+ --+#ifndef __attribute_cold__ --+#if __has_attribute(cold) \ --+ || __GNUC_PREREQ(4,3) --+#define __attribute_cold__ __attribute__((__cold__)) --+#else --+#define __attribute_cold__ --+#endif --+#endif --+ --+#ifndef __attribute_noinline__ --+#if __has_attribute(noinline) \ --+ || __GNUC_PREREQ(3,1) --+#define __attribute_noinline__ __attribute__((__noinline__)) --+#else --+#define __attribute_noinline__ --+#endif --+#endif --+ --+ --+__attribute_cold__ --+__attribute_noinline__ --+static void emsg(int level, const char * const msg) --+{ --+ wpa_printf(level, "MTLS: %s", msg); --+} --+ --+ --+__attribute_cold__ --+__attribute_noinline__ --+static void emsgrc(int level, const char * const msg, int rc) --+{ --+ #ifdef MBEDTLS_ERROR_C --+ /* error logging convenience function that decodes mbedtls result codes */ --+ char buf[256]; --+ mbedtls_strerror(rc, buf, sizeof(buf)); --+ wpa_printf(level, "MTLS: %s: %s (-0x%04x)", msg, buf, -rc); --+ #else --+ wpa_printf(level, "MTLS: %s: (-0x%04x)", msg, -rc); --+ #endif --+} --+ --+ --+#define elog(rc, msg) emsgrc(MSG_ERROR, (msg), (rc)) --+#define ilog(rc, msg) emsgrc(MSG_INFO, (msg), (rc)) --+ --+ --+struct tls_conf * tls_conf_init(void *tls_ctx) --+{ --+ struct tls_conf *tls_conf = os_zalloc(sizeof(*tls_conf)); --+ if (tls_conf == NULL) --+ return NULL; --+ tls_conf->refcnt = 1; --+ --+ mbedtls_ssl_config_init(&tls_conf->conf); --+ mbedtls_ssl_conf_rng(&tls_conf->conf, --+ mbedtls_ctr_drbg_random, tls_ctx_global.ctr_drbg); --+ mbedtls_x509_crt_init(&tls_conf->ca_cert); --+ mbedtls_x509_crt_init(&tls_conf->client_cert); --+ mbedtls_pk_init(&tls_conf->private_key); --+ --+ return tls_conf; --+} --+ --+ --+void tls_conf_deinit(struct tls_conf *tls_conf) --+{ --+ if (tls_conf == NULL || --tls_conf->refcnt != 0) --+ return; --+ --+ mbedtls_x509_crt_free(&tls_conf->ca_cert); --+ mbedtls_x509_crt_free(&tls_conf->client_cert); --+ if (tls_conf->crl) { --+ mbedtls_x509_crl_free(tls_conf->crl); --+ os_free(tls_conf->crl); --+ } --+ mbedtls_pk_free(&tls_conf->private_key); --+ mbedtls_ssl_config_free(&tls_conf->conf); --+ os_free(tls_conf->curves); --+ os_free(tls_conf->ciphersuites); --+ os_free(tls_conf->subject_match); --+ os_free(tls_conf->altsubject_match); --+ os_free(tls_conf->suffix_match); --+ os_free(tls_conf->domain_match); --+ os_free(tls_conf->check_cert_subject); --+ os_free(tls_conf); --+} --+ --+ --+mbedtls_ctr_drbg_context * crypto_mbedtls_ctr_drbg(void); /*(not in header)*/ --+ --+__attribute_cold__ --+void * tls_init(const struct tls_config *conf) --+{ --+ /* RFE: review struct tls_config *conf (different from tls_conf) */ --+ --+ if (++tls_ctx_global.refcnt > 1) --+ return &tls_ctx_global; --+ --+ tls_ctx_global.ctr_drbg = crypto_mbedtls_ctr_drbg(); --+ #ifdef MBEDTLS_SSL_SESSION_TICKETS --+ mbedtls_ssl_ticket_init(&tls_ctx_global.ticket_ctx); --+ mbedtls_ssl_ticket_setup(&tls_ctx_global.ticket_ctx, --+ mbedtls_ctr_drbg_random, --+ tls_ctx_global.ctr_drbg, --+ MBEDTLS_CIPHER_AES_256_GCM, --+ 43200); /* ticket timeout: 12 hours */ --+ #endif --+ /* copy struct for future use */ --+ tls_ctx_global.init_conf = *conf; --+ if (conf->openssl_ciphers) --+ tls_ctx_global.init_conf.openssl_ciphers = --+ os_strdup(conf->openssl_ciphers); --+ --+ tls_ctx_global.crl_reload_interval = conf->crl_reload_interval; --+ os_get_reltime(&tls_ctx_global.crl_reload_previous); --+ --+ return &tls_ctx_global; --+} --+ --+ --+__attribute_cold__ --+void tls_deinit(void *tls_ctx) --+{ --+ if (tls_ctx == NULL || --tls_ctx_global.refcnt != 0) --+ return; --+ --+ tls_conf_deinit(tls_ctx_global.tls_conf); --+ os_free(tls_ctx_global.ca_cert_file); --+ os_free(tls_ctx_global.ocsp_stapling_response); --+ char *openssl_ciphers; /*(allocated in tls_init())*/ --+ *(const char **)&openssl_ciphers = --+ tls_ctx_global.init_conf.openssl_ciphers; --+ os_free(openssl_ciphers); --+ #ifdef MBEDTLS_SSL_SESSION_TICKETS --+ mbedtls_ssl_ticket_free(&tls_ctx_global.ticket_ctx); --+ #endif --+ os_memset(&tls_ctx_global, 0, sizeof(tls_ctx_global)); --+} --+ --+ --+int tls_get_errors(void *tls_ctx) --+{ --+ return 0; --+} --+ --+ --+static void tls_connection_deinit_expkey(struct tls_connection *conn) --+{ --+ conn->tls_prf_type = 0; /* MBEDTLS_SSL_TLS_PRF_NONE; */ --+ conn->expkey_keyblock_size = 0; --+ conn->expkey_secret_len = 0; --+ forced_memzero(conn->expkey_secret, sizeof(conn->expkey_secret)); --+ forced_memzero(conn->expkey_randbytes, sizeof(conn->expkey_randbytes)); --+} --+ --+ --+#ifdef TLS_MBEDTLS_SESSION_TICKETS --+void tls_connection_deinit_clienthello_session_ticket(struct tls_connection *conn) --+{ --+ if (conn->clienthello_session_ticket) { --+ mbedtls_platform_zeroize(conn->clienthello_session_ticket, --+ conn->clienthello_session_ticket_len); --+ mbedtls_free(conn->clienthello_session_ticket); --+ conn->clienthello_session_ticket = NULL; --+ conn->clienthello_session_ticket_len = 0; --+ } --+} --+#endif --+ --+ --+void tls_connection_deinit(void *tls_ctx, struct tls_connection *conn) --+{ --+ if (conn == NULL) --+ return; --+ --+ #if 0 /*(good intention, but never sent since we destroy self below)*/ --+ if (conn->established) --+ mbedtls_ssl_close_notify(&conn->ssl); --+ #endif --+ --+ if (conn->tls_prf_type) --+ tls_connection_deinit_expkey(conn); --+ --+ #ifdef TLS_MBEDTLS_SESSION_TICKETS --+ if (conn->clienthello_session_ticket) --+ tls_connection_deinit_clienthello_session_ticket(conn); --+ #endif --+ --+ os_free(conn->peer_subject); --+ wpabuf_free(conn->success_data); --+ wpabuf_free(conn->push_buf); --+ wpabuf_free(conn->pull_buf); --+ mbedtls_ssl_free(&conn->ssl); --+ tls_conf_deinit(conn->tls_conf); --+ os_free(conn); --+} --+ --+ --+static void tls_mbedtls_refresh_crl(void); --+static int tls_mbedtls_ssl_setup(struct tls_connection *conn); --+ --+struct tls_connection * tls_connection_init(void *tls_ctx) --+{ --+ struct tls_connection *conn = os_zalloc(sizeof(*conn)); --+ if (conn == NULL) --+ return NULL; --+ --+ mbedtls_ssl_init(&conn->ssl); --+ --+ conn->tls_conf = tls_ctx_global.tls_conf; /*(inherit global conf, if set)*/ --+ if (conn->tls_conf) { --+ ++conn->tls_conf->refcnt; --+ /* check for CRL refresh if inheriting from global config */ --+ tls_mbedtls_refresh_crl(); --+ --+ conn->verify_peer = conn->tls_conf->verify_peer; --+ if (tls_mbedtls_ssl_setup(conn) != 0) { --+ tls_connection_deinit(&tls_ctx_global, conn); --+ return NULL; --+ } --+ } --+ --+ return conn; --+} --+ --+ --+int tls_connection_established(void *tls_ctx, struct tls_connection *conn) --+{ --+ return conn ? conn->established : 0; --+} --+ --+ --+__attribute_noinline__ --+char * tls_mbedtls_peer_serial_num(const mbedtls_x509_crt *crt, char *serial_num, size_t len) --+{ --+ /* mbedtls_x509_serial_gets() inefficiently formats to hex separated by --+ * colons, so generate the hex serial number here. The func --+ * wpa_snprintf_hex_uppercase() is similarly inefficient. */ --+ size_t i = 0; /* skip leading 0's per Distinguished Encoding Rules (DER) */ --+ while (i < crt->serial.len && crt->serial.p[i] == 0) ++i; --+ if (i == crt->serial.len) --i; --+ --+ const unsigned char *s = crt->serial.p + i; --+ const size_t e = (crt->serial.len - i) * 2; --+ if (e >= len) --+ return NULL; --+ #if 0 --+ wpa_snprintf_hex_uppercase(serial_num, len, s, crt->serial.len-i); --+ #else --+ for (i = 0; i < e; i+=2, ++s) { --+ serial_num[i+0] = "0123456789ABCDEF"[(*s >> 4)]; --+ serial_num[i+1] = "0123456789ABCDEF"[(*s & 0xF)]; --+ } --+ serial_num[e] = '\0'; --+ #endif --+ return serial_num; --+} --+ --+ --+char * tls_connection_peer_serial_num(void *tls_ctx, --+ struct tls_connection *conn) --+{ --+ const mbedtls_x509_crt *crt = mbedtls_ssl_get_peer_cert(&conn->ssl); --+ if (crt == NULL) --+ return NULL; --+ size_t len = crt->serial.len * 2 + 1; --+ char *serial_num = os_malloc(len); --+ if (!serial_num) --+ return NULL; --+ return tls_mbedtls_peer_serial_num(crt, serial_num, len); --+} --+ --+ --+static void tls_pull_buf_reset(struct tls_connection *conn); --+ --+int tls_connection_shutdown(void *tls_ctx, struct tls_connection *conn) --+{ --+ /* Note: this function called from eap_peer_tls_reauth_init() --+ * for session resumption, not for connection shutdown */ --+ --+ if (conn == NULL) --+ return -1; --+ --+ tls_pull_buf_reset(conn); --+ wpabuf_free(conn->push_buf); --+ conn->push_buf = NULL; --+ conn->established = 0; --+ conn->resumed = 0; --+ if (conn->tls_prf_type) --+ tls_connection_deinit_expkey(conn); --+ --+ /* RFE: prepare for session resumption? (see doc in crypto/tls.h) */ --+ --+ return mbedtls_ssl_session_reset(&conn->ssl); --+} --+ --+ --+static int tls_wpabuf_resize_put_data(struct wpabuf **buf, --+ const unsigned char *data, size_t dlen) --+{ --+ if (wpabuf_resize(buf, dlen) < 0) --+ return 0; --+ wpabuf_put_data(*buf, data, dlen); --+ return 1; --+} --+ --+ --+static int tls_pull_buf_append(struct tls_connection *conn, --+ const struct wpabuf *in_data) --+{ --+ /*(interface does not lend itself to move semantics)*/ --+ return tls_wpabuf_resize_put_data(&conn->pull_buf, --+ wpabuf_head(in_data), --+ wpabuf_len(in_data)); --+} --+ --+ --+static void tls_pull_buf_reset(struct tls_connection *conn) --+{ --+ /*(future: might consider reusing conn->pull_buf)*/ --+ wpabuf_free(conn->pull_buf); --+ conn->pull_buf = NULL; --+ conn->pull_buf_offset = 0; --+} --+ --+ --+__attribute_cold__ --+static void tls_pull_buf_discard(struct tls_connection *conn, const char *func) --+{ --+ size_t discard = wpabuf_len(conn->pull_buf) - conn->pull_buf_offset; --+ if (discard) --+ wpa_printf(MSG_DEBUG, --+ "%s - %zu bytes remaining in pull_buf; discarding", --+ func, discard); --+ tls_pull_buf_reset(conn); --+} --+ --+ --+static int tls_pull_func(void *ptr, unsigned char *buf, size_t len) --+{ --+ struct tls_connection *conn = (struct tls_connection *) ptr; --+ if (conn->pull_buf == NULL) --+ return MBEDTLS_ERR_SSL_WANT_READ; --+ const size_t dlen = wpabuf_len(conn->pull_buf) - conn->pull_buf_offset; --+ if (dlen == 0) --+ return MBEDTLS_ERR_SSL_WANT_READ; --+ --+ if (len > dlen) --+ len = dlen; --+ os_memcpy(buf, wpabuf_head(conn->pull_buf)+conn->pull_buf_offset, len); --+ --+ if (len == dlen) { --+ tls_pull_buf_reset(conn); --+ /*wpa_printf(MSG_DEBUG, "%s - emptied pull_buf", __func__);*/ --+ } --+ else { --+ conn->pull_buf_offset += len; --+ /*wpa_printf(MSG_DEBUG, "%s - %zu bytes remaining in pull_buf", --+ __func__, dlen - len);*/ --+ } --+ return (int)len; --+} --+ --+ --+static int tls_push_func(void *ptr, const unsigned char *buf, size_t len) --+{ --+ struct tls_connection *conn = (struct tls_connection *) ptr; --+ return tls_wpabuf_resize_put_data(&conn->push_buf, buf, len) --+ ? (int)len --+ : MBEDTLS_ERR_SSL_ALLOC_FAILED; --+} --+ --+ --+static int --+tls_mbedtls_verify_cb (void *arg, mbedtls_x509_crt *crt, int depth, uint32_t *flags); --+ --+ --+static int tls_mbedtls_ssl_setup(struct tls_connection *conn) --+{ --+ #if 0 --+ /* mbedtls_ssl_setup() must be called only once */ --+ /* If this func might be called multiple times (e.g. via set_params), --+ * then we should set a flag in conn that ssl was initialized */ --+ if (conn->ssl_is_init) { --+ mbedtls_ssl_free(&conn->ssl); --+ mbedtls_ssl_init(&conn->ssl); --+ } --+ #endif --+ --+ int ret = mbedtls_ssl_setup(&conn->ssl, &conn->tls_conf->conf); --+ if (ret != 0) { --+ elog(ret, "mbedtls_ssl_setup"); --+ return -1; --+ } --+ --+ mbedtls_ssl_set_bio(&conn->ssl, conn, tls_push_func, tls_pull_func, NULL); --+ #if MBEDTLS_VERSION_NUMBER >= 0x03000000 /* mbedtls 3.0.0 */ --+ mbedtls_ssl_set_export_keys_cb( --+ &conn->ssl, tls_connection_export_keys_cb, conn); --+ #elif MBEDTLS_VERSION_NUMBER >= 0x02120000 /* mbedtls 2.18.0 */ --+ mbedtls_ssl_conf_export_keys_ext_cb( --+ &conn->tls_conf->conf, tls_connection_export_keys_cb, conn); --+ #endif --+ if (conn->verify_peer) --+ mbedtls_ssl_set_verify(&conn->ssl, tls_mbedtls_verify_cb, conn); --+ --+ return 0; --+} --+ --+ --+static int tls_mbedtls_data_is_pem(const u8 *data) --+{ --+ return (NULL != os_strstr((char *)data, "-----")); --+} --+ --+ --+static void tls_mbedtls_set_allowed_tls_vers(struct tls_conf *tls_conf, --+ mbedtls_ssl_config *conf) --+{ --+ #if !defined(MBEDTLS_SSL_PROTO_TLS1_3) --+ tls_conf->flags |= TLS_CONN_DISABLE_TLSv1_3; --+ #endif --+ --+ /* unconditionally require TLSv1.2+ for TLS_CONN_SUITEB */ --+ if (tls_conf->flags & TLS_CONN_SUITEB) { --+ tls_conf->flags |= TLS_CONN_DISABLE_TLSv1_0; --+ tls_conf->flags |= TLS_CONN_DISABLE_TLSv1_1; --+ } --+ --+ const unsigned int flags = tls_conf->flags; --+ --+ /* attempt to map flags to min and max TLS protocol version */ --+ --+ int min = (flags & TLS_CONN_DISABLE_TLSv1_0) --+ ? (flags & TLS_CONN_DISABLE_TLSv1_1) --+ ? (flags & TLS_CONN_DISABLE_TLSv1_2) --+ ? (flags & TLS_CONN_DISABLE_TLSv1_3) --+ ? 4 --+ : 3 --+ : 2 --+ : 1 --+ : 0; --+ --+ int max = (flags & TLS_CONN_DISABLE_TLSv1_3) --+ ? (flags & TLS_CONN_DISABLE_TLSv1_2) --+ ? (flags & TLS_CONN_DISABLE_TLSv1_1) --+ ? (flags & TLS_CONN_DISABLE_TLSv1_0) --+ ? -1 --+ : 0 --+ : 1 --+ : 2 --+ : 3; --+ --+ if ((flags & TLS_CONN_ENABLE_TLSv1_2) && min > 2) min = 2; --+ if ((flags & TLS_CONN_ENABLE_TLSv1_1) && min > 1) min = 1; --+ if ((flags & TLS_CONN_ENABLE_TLSv1_0) && min > 0) min = 0; --+ if (max < min) { --+ emsg(MSG_ERROR, "invalid tls_disable_tlsv* params; ignoring"); --+ return; --+ } --+ #if MBEDTLS_VERSION_NUMBER >= 0x03000000 /* mbedtls 3.0.0 */ --+ /* mbed TLS 3.0.0 removes support for protocols < TLSv1.2 */ --+ if (min < 2 || max < 2) { --+ emsg(MSG_ERROR, "invalid tls_disable_tlsv* params; ignoring"); --+ if (min < 2) min = 2; --+ if (max < 2) max = 2; --+ } --+ #endif --+ --+ #if MBEDTLS_VERSION_NUMBER >= 0x03020000 /* mbedtls 3.2.0 */ --+ /* MBEDTLS_SSL_VERSION_TLS1_2 = 0x0303 *//*!< (D)TLS 1.2 */ --+ /* MBEDTLS_SSL_VERSION_TLS1_3 = 0x0304 *//*!< (D)TLS 1.3 */ --+ min = (min == 2) ? MBEDTLS_SSL_VERSION_TLS1_2 : MBEDTLS_SSL_VERSION_TLS1_3; --+ max = (max == 2) ? MBEDTLS_SSL_VERSION_TLS1_2 : MBEDTLS_SSL_VERSION_TLS1_3; --+ mbedtls_ssl_conf_min_tls_version(conf, min); --+ mbedtls_ssl_conf_max_tls_version(conf, max); --+ #else --+ #ifndef MBEDTLS_SSL_MINOR_VERSION_4 --+ if (min == 3) min = 2; --+ if (max == 3) max = 2; --+ #endif --+ /* MBEDTLS_SSL_MINOR_VERSION_0 0 *//*!< SSL v3.0 */ --+ /* MBEDTLS_SSL_MINOR_VERSION_1 1 *//*!< TLS v1.0 */ --+ /* MBEDTLS_SSL_MINOR_VERSION_2 2 *//*!< TLS v1.1 */ --+ /* MBEDTLS_SSL_MINOR_VERSION_3 3 *//*!< TLS v1.2 */ --+ /* MBEDTLS_SSL_MINOR_VERSION_4 4 *//*!< TLS v1.3 */ --+ mbedtls_ssl_conf_min_version(conf, MBEDTLS_SSL_MAJOR_VERSION_3, min+1); --+ mbedtls_ssl_conf_max_version(conf, MBEDTLS_SSL_MAJOR_VERSION_3, max+1); --+ #endif --+} --+ --+ --+__attribute_noinline__ --+static int tls_mbedtls_readfile(const char *path, u8 **buf, size_t *n); --+ --+ --+static int --+tls_mbedtls_set_dhparams(struct tls_conf *tls_conf, const char *dh_file) --+{ --+ size_t len; --+ u8 *data; --+ if (tls_mbedtls_readfile(dh_file, &data, &len)) --+ return 0; --+ --+ /* parse only if DH parameters if in PEM format */ --+ if (tls_mbedtls_data_is_pem(data) --+ && NULL == os_strstr((char *)data, "-----BEGIN DH PARAMETERS-----")) { --+ if (os_strstr((char *)data, "-----BEGIN DSA PARAMETERS-----")) --+ wpa_printf(MSG_WARNING, "DSA parameters not handled (%s)", dh_file); --+ else --+ wpa_printf(MSG_WARNING, "unexpected DH param content (%s)",dh_file); --+ forced_memzero(data, len); --+ os_free(data); --+ return 0; --+ } --+ --+ /* mbedtls_dhm_parse_dhm() expects "-----BEGIN DH PARAMETERS-----" if PEM */ --+ mbedtls_dhm_context dhm; --+ mbedtls_dhm_init(&dhm); --+ int rc = mbedtls_dhm_parse_dhm(&dhm, data, len); --+ if (0 == rc) --+ rc = mbedtls_ssl_conf_dh_param_ctx(&tls_conf->conf, &dhm); --+ if (0 != rc) --+ elog(rc, dh_file); --+ mbedtls_dhm_free(&dhm); --+ --+ forced_memzero(data, len); --+ os_free(data); --+ return (0 == rc); --+} --+ --+ --+/* reference: lighttpd src/mod_mbedtls.c:mod_mbedtls_ssl_append_curve() --+ * (same author: gstrauss@gluelogic.com; same license: BSD-3-Clause) */ --+#if MBEDTLS_VERSION_NUMBER < 0x03010000 /* mbedtls 3.1.0 */ --+static int --+tls_mbedtls_append_curve (mbedtls_ecp_group_id *ids, int nids, int idsz, const mbedtls_ecp_group_id id) --+{ --+ if (1 >= idsz - (nids + 1)) { --+ emsg(MSG_ERROR, "error: too many curves during list expand"); --+ return -1; --+ } --+ ids[++nids] = id; --+ return nids; --+} --+ --+ --+static int --+tls_mbedtls_set_curves(struct tls_conf *tls_conf, const char *curvelist) --+{ --+ mbedtls_ecp_group_id ids[512]; --+ int nids = -1; --+ const int idsz = (int)(sizeof(ids)/sizeof(*ids)-1); --+ const mbedtls_ecp_curve_info * const curve_info = mbedtls_ecp_curve_list(); --+ --+ for (const char *e = curvelist-1; e; ) { --+ const char * const n = e+1; --+ e = os_strchr(n, ':'); --+ size_t len = e ? (size_t)(e - n) : os_strlen(n); --+ mbedtls_ecp_group_id grp_id = MBEDTLS_ECP_DP_NONE; --+ switch (len) { --+ case 5: --+ if (0 == os_memcmp("P-521", n, 5)) --+ grp_id = MBEDTLS_ECP_DP_SECP521R1; --+ else if (0 == os_memcmp("P-384", n, 5)) --+ grp_id = MBEDTLS_ECP_DP_SECP384R1; --+ else if (0 == os_memcmp("P-256", n, 5)) --+ grp_id = MBEDTLS_ECP_DP_SECP256R1; --+ break; --+ case 6: --+ if (0 == os_memcmp("BP-521", n, 6)) --+ grp_id = MBEDTLS_ECP_DP_BP512R1; --+ else if (0 == os_memcmp("BP-384", n, 6)) --+ grp_id = MBEDTLS_ECP_DP_BP384R1; --+ else if (0 == os_memcmp("BP-256", n, 6)) --+ grp_id = MBEDTLS_ECP_DP_BP256R1; --+ break; --+ default: --+ break; --+ } --+ if (grp_id != MBEDTLS_ECP_DP_NONE) { --+ nids = tls_mbedtls_append_curve(ids, nids, idsz, grp_id); --+ if (-1 == nids) return 0; --+ continue; --+ } --+ /* similar to mbedtls_ecp_curve_info_from_name() */ --+ const mbedtls_ecp_curve_info *info; --+ for (info = curve_info; info->grp_id != MBEDTLS_ECP_DP_NONE; ++info) { --+ if (0 == os_strncmp(info->name, n, len) && info->name[len] == '\0') --+ break; --+ } --+ if (info->grp_id == MBEDTLS_ECP_DP_NONE) { --+ wpa_printf(MSG_ERROR, "MTLS: unrecognized curve: %.*s",(int)len,n); --+ return 0; --+ } --+ --+ nids = tls_mbedtls_append_curve(ids, nids, idsz, info->grp_id); --+ if (-1 == nids) return 0; --+ } --+ --+ /* mod_openssl configures "prime256v1" if curve list not specified, --+ * but mbedtls provides a list of supported curves if not explicitly set */ --+ if (-1 == nids) return 1; /* empty list; no-op */ --+ --+ ids[++nids] = MBEDTLS_ECP_DP_NONE; /* terminate list */ --+ ++nids; --+ --+ /* curves list must be persistent for lifetime of mbedtls_ssl_config */ --+ tls_conf->curves = os_malloc(nids * sizeof(mbedtls_ecp_group_id)); --+ if (tls_conf->curves == NULL) --+ return 0; --+ os_memcpy(tls_conf->curves, ids, nids * sizeof(mbedtls_ecp_group_id)); --+ --+ mbedtls_ssl_conf_curves(&tls_conf->conf, tls_conf->curves); --+ return 1; --+} --+#else --+static int --+tls_mbedtls_append_curve (uint16_t *ids, int nids, int idsz, const uint16_t id) --+{ --+ if (1 >= idsz - (nids + 1)) { --+ emsg(MSG_ERROR, "error: too many curves during list expand"); --+ return -1; --+ } --+ ids[++nids] = id; --+ return nids; --+} --+ --+ --+static int --+tls_mbedtls_set_curves(struct tls_conf *tls_conf, const char *curvelist) --+{ --+ /* TLS Supported Groups (renamed from "EC Named Curve Registry") --+ * https://www.iana.org/assignments/tls-parameters/tls-parameters.xhtml#tls-parameters-8 --+ */ --+ uint16_t ids[512]; --+ int nids = -1; --+ const int idsz = (int)(sizeof(ids)/sizeof(*ids)-1); --+ const mbedtls_ecp_curve_info * const curve_info = mbedtls_ecp_curve_list(); --+ --+ for (const char *e = curvelist-1; e; ) { --+ const char * const n = e+1; --+ e = os_strchr(n, ':'); --+ size_t len = e ? (size_t)(e - n) : os_strlen(n); --+ uint16_t tls_id = 0; --+ switch (len) { --+ case 5: --+ if (0 == os_memcmp("P-521", n, 5)) --+ tls_id = 25; /* mbedtls_ecp_group_id MBEDTLS_ECP_DP_SECP521R1 */ --+ else if (0 == os_memcmp("P-384", n, 5)) --+ tls_id = 24; /* mbedtls_ecp_group_id MBEDTLS_ECP_DP_SECP384R1 */ --+ else if (0 == os_memcmp("P-256", n, 5)) --+ tls_id = 23; /* mbedtls_ecp_group_id MBEDTLS_ECP_DP_SECP256R1 */ --+ break; --+ case 6: --+ if (0 == os_memcmp("BP-521", n, 6)) --+ tls_id = 28; /* mbedtls_ecp_group_id MBEDTLS_ECP_DP_BP512R1 */ --+ else if (0 == os_memcmp("BP-384", n, 6)) --+ tls_id = 27; /* mbedtls_ecp_group_id MBEDTLS_ECP_DP_BP384R1 */ --+ else if (0 == os_memcmp("BP-256", n, 6)) --+ tls_id = 26; /* mbedtls_ecp_group_id MBEDTLS_ECP_DP_BP256R1 */ --+ break; --+ default: --+ break; --+ } --+ if (tls_id != 0) { --+ nids = tls_mbedtls_append_curve(ids, nids, idsz, tls_id); --+ if (-1 == nids) return 0; --+ continue; --+ } --+ /* similar to mbedtls_ecp_curve_info_from_name() */ --+ const mbedtls_ecp_curve_info *info; --+ for (info = curve_info; info->tls_id != 0; ++info) { --+ if (0 == os_strncmp(info->name, n, len) && info->name[len] == '\0') --+ break; --+ } --+ if (info->tls_id == 0) { --+ wpa_printf(MSG_ERROR, "MTLS: unrecognized curve: %.*s",(int)len,n); --+ return 0; --+ } --+ --+ nids = tls_mbedtls_append_curve(ids, nids, idsz, info->tls_id); --+ if (-1 == nids) return 0; --+ } --+ --+ /* mod_openssl configures "prime256v1" if curve list not specified, --+ * but mbedtls provides a list of supported curves if not explicitly set */ --+ if (-1 == nids) return 1; /* empty list; no-op */ --+ --+ ids[++nids] = 0; /* terminate list */ --+ ++nids; --+ --+ /* curves list must be persistent for lifetime of mbedtls_ssl_config */ --+ tls_conf->curves = os_malloc(nids * sizeof(uint16_t)); --+ if (tls_conf->curves == NULL) --+ return 0; --+ os_memcpy(tls_conf->curves, ids, nids * sizeof(uint16_t)); --+ --+ mbedtls_ssl_conf_groups(&tls_conf->conf, tls_conf->curves); --+ return 1; --+} --+#endif /* MBEDTLS_VERSION_NUMBER >= 0x03010000 */ /* mbedtls 3.1.0 */ --+ --+ --+/* data copied from lighttpd src/mod_mbedtls.c (BSD-3-Clause) */ --+static const int suite_AES_256_ephemeral[] = { --+ /* All AES-256 ephemeral suites */ --+ MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384, --+ MBEDTLS_TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384, --+ MBEDTLS_TLS_DHE_RSA_WITH_AES_256_GCM_SHA384, --+ MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_256_CCM, --+ MBEDTLS_TLS_DHE_RSA_WITH_AES_256_CCM, --+ MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384, --+ MBEDTLS_TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384, --+ MBEDTLS_TLS_DHE_RSA_WITH_AES_256_CBC_SHA256, --+ MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA, --+ MBEDTLS_TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA, --+ MBEDTLS_TLS_DHE_RSA_WITH_AES_256_CBC_SHA, --+ MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_256_CCM_8, --+ MBEDTLS_TLS_DHE_RSA_WITH_AES_256_CCM_8 --+}; --+ --+/* data copied from lighttpd src/mod_mbedtls.c (BSD-3-Clause) */ --+static const int suite_AES_128_ephemeral[] = { --+ /* All AES-128 ephemeral suites */ --+ MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, --+ MBEDTLS_TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, --+ MBEDTLS_TLS_DHE_RSA_WITH_AES_128_GCM_SHA256, --+ MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_CCM, --+ MBEDTLS_TLS_DHE_RSA_WITH_AES_128_CCM, --+ MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256, --+ MBEDTLS_TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256, --+ MBEDTLS_TLS_DHE_RSA_WITH_AES_128_CBC_SHA256, --+ MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA, --+ MBEDTLS_TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA, --+ MBEDTLS_TLS_DHE_RSA_WITH_AES_128_CBC_SHA, --+ MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8, --+ MBEDTLS_TLS_DHE_RSA_WITH_AES_128_CCM_8 --+}; --+ --+/* data copied from lighttpd src/mod_mbedtls.c (BSD-3-Clause) */ --+/* HIGH cipher list (mapped from openssl list to mbedtls) */ --+static const int suite_HIGH[] = { --+ MBEDTLS_TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256, --+ MBEDTLS_TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256, --+ MBEDTLS_TLS_DHE_RSA_WITH_CHACHA20_POLY1305_SHA256, --+ MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384, --+ MBEDTLS_TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384, --+ MBEDTLS_TLS_DHE_RSA_WITH_AES_256_GCM_SHA384, --+ MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_256_CCM, --+ MBEDTLS_TLS_DHE_RSA_WITH_AES_256_CCM, --+ MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384, --+ MBEDTLS_TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384, --+ MBEDTLS_TLS_DHE_RSA_WITH_AES_256_CBC_SHA256, --+ MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA, --+ MBEDTLS_TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA, --+ MBEDTLS_TLS_DHE_RSA_WITH_AES_256_CBC_SHA, --+ MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_256_CCM_8, --+ MBEDTLS_TLS_DHE_RSA_WITH_AES_256_CCM_8, --+ MBEDTLS_TLS_ECDHE_ECDSA_WITH_CAMELLIA_256_CBC_SHA384, --+ MBEDTLS_TLS_ECDHE_RSA_WITH_CAMELLIA_256_CBC_SHA384, --+ MBEDTLS_TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA256, --+ MBEDTLS_TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA, --+ MBEDTLS_TLS_ECDHE_ECDSA_WITH_ARIA_256_GCM_SHA384, --+ MBEDTLS_TLS_ECDHE_RSA_WITH_ARIA_256_GCM_SHA384, --+ MBEDTLS_TLS_DHE_RSA_WITH_ARIA_256_GCM_SHA384, --+ MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, --+ MBEDTLS_TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, --+ MBEDTLS_TLS_DHE_RSA_WITH_AES_128_GCM_SHA256, --+ MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_CCM, --+ MBEDTLS_TLS_DHE_RSA_WITH_AES_128_CCM, --+ MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256, --+ MBEDTLS_TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256, --+ MBEDTLS_TLS_DHE_RSA_WITH_AES_128_CBC_SHA256, --+ MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA, --+ MBEDTLS_TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA, --+ MBEDTLS_TLS_DHE_RSA_WITH_AES_128_CBC_SHA, --+ MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8, --+ MBEDTLS_TLS_DHE_RSA_WITH_AES_128_CCM_8, --+ MBEDTLS_TLS_ECDHE_ECDSA_WITH_CAMELLIA_128_CBC_SHA256, --+ MBEDTLS_TLS_ECDHE_RSA_WITH_CAMELLIA_128_CBC_SHA256, --+ MBEDTLS_TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA256, --+ MBEDTLS_TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA, --+ MBEDTLS_TLS_ECDHE_ECDSA_WITH_ARIA_128_GCM_SHA256, --+ MBEDTLS_TLS_ECDHE_RSA_WITH_ARIA_128_GCM_SHA256, --+ MBEDTLS_TLS_DHE_RSA_WITH_ARIA_128_GCM_SHA256, --+ MBEDTLS_TLS_ECDHE_PSK_WITH_CHACHA20_POLY1305_SHA256, --+ MBEDTLS_TLS_DHE_PSK_WITH_CHACHA20_POLY1305_SHA256, --+ MBEDTLS_TLS_DHE_PSK_WITH_AES_256_GCM_SHA384, --+ MBEDTLS_TLS_DHE_PSK_WITH_AES_256_CCM, --+ MBEDTLS_TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA384, --+ MBEDTLS_TLS_DHE_PSK_WITH_AES_256_CBC_SHA384, --+ MBEDTLS_TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA, --+ MBEDTLS_TLS_DHE_PSK_WITH_AES_256_CBC_SHA, --+ MBEDTLS_TLS_ECDHE_PSK_WITH_CAMELLIA_256_CBC_SHA384, --+ MBEDTLS_TLS_DHE_PSK_WITH_CAMELLIA_256_CBC_SHA384, --+ MBEDTLS_TLS_DHE_PSK_WITH_AES_256_CCM_8, --+ MBEDTLS_TLS_DHE_PSK_WITH_ARIA_256_GCM_SHA384, --+ MBEDTLS_TLS_DHE_PSK_WITH_AES_128_GCM_SHA256, --+ MBEDTLS_TLS_DHE_PSK_WITH_AES_128_CCM, --+ MBEDTLS_TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA256, --+ MBEDTLS_TLS_DHE_PSK_WITH_AES_128_CBC_SHA256, --+ MBEDTLS_TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA, --+ MBEDTLS_TLS_DHE_PSK_WITH_AES_128_CBC_SHA, --+ MBEDTLS_TLS_DHE_PSK_WITH_CAMELLIA_128_CBC_SHA256, --+ MBEDTLS_TLS_ECDHE_PSK_WITH_CAMELLIA_128_CBC_SHA256, --+ MBEDTLS_TLS_DHE_PSK_WITH_AES_128_CCM_8, --+ MBEDTLS_TLS_DHE_PSK_WITH_ARIA_128_GCM_SHA256, --+ MBEDTLS_TLS_RSA_WITH_AES_256_GCM_SHA384, --+ MBEDTLS_TLS_RSA_WITH_AES_256_CCM, --+ MBEDTLS_TLS_RSA_WITH_AES_256_CBC_SHA256, --+ MBEDTLS_TLS_RSA_WITH_AES_256_CBC_SHA, --+ MBEDTLS_TLS_RSA_WITH_AES_256_CCM_8, --+ MBEDTLS_TLS_RSA_WITH_CAMELLIA_256_CBC_SHA256, --+ MBEDTLS_TLS_RSA_WITH_CAMELLIA_256_CBC_SHA, --+ MBEDTLS_TLS_RSA_WITH_ARIA_256_GCM_SHA384, --+ MBEDTLS_TLS_RSA_WITH_AES_128_GCM_SHA256, --+ MBEDTLS_TLS_RSA_WITH_AES_128_CCM, --+ MBEDTLS_TLS_RSA_WITH_AES_128_CBC_SHA256, --+ MBEDTLS_TLS_RSA_WITH_AES_128_CBC_SHA, --+ MBEDTLS_TLS_RSA_WITH_AES_128_CCM_8, --+ MBEDTLS_TLS_RSA_WITH_CAMELLIA_128_CBC_SHA256, --+ MBEDTLS_TLS_RSA_WITH_CAMELLIA_128_CBC_SHA, --+ MBEDTLS_TLS_RSA_WITH_ARIA_128_GCM_SHA256, --+ MBEDTLS_TLS_RSA_PSK_WITH_CHACHA20_POLY1305_SHA256, --+ MBEDTLS_TLS_RSA_PSK_WITH_AES_256_GCM_SHA384, --+ MBEDTLS_TLS_RSA_PSK_WITH_AES_256_CBC_SHA384, --+ MBEDTLS_TLS_RSA_PSK_WITH_AES_256_CBC_SHA, --+ MBEDTLS_TLS_RSA_PSK_WITH_CAMELLIA_256_CBC_SHA384, --+ MBEDTLS_TLS_RSA_PSK_WITH_ARIA_256_GCM_SHA384, --+ MBEDTLS_TLS_RSA_PSK_WITH_AES_128_GCM_SHA256, --+ MBEDTLS_TLS_RSA_PSK_WITH_AES_128_CBC_SHA256, --+ MBEDTLS_TLS_RSA_PSK_WITH_AES_128_CBC_SHA, --+ MBEDTLS_TLS_RSA_PSK_WITH_CAMELLIA_128_CBC_SHA256, --+ MBEDTLS_TLS_RSA_PSK_WITH_ARIA_128_GCM_SHA256, --+ MBEDTLS_TLS_PSK_WITH_CHACHA20_POLY1305_SHA256, --+ MBEDTLS_TLS_PSK_WITH_AES_256_GCM_SHA384, --+ MBEDTLS_TLS_PSK_WITH_AES_256_CCM, --+ MBEDTLS_TLS_PSK_WITH_AES_256_CBC_SHA384, --+ MBEDTLS_TLS_PSK_WITH_AES_256_CBC_SHA, --+ MBEDTLS_TLS_PSK_WITH_CAMELLIA_256_CBC_SHA384, --+ MBEDTLS_TLS_PSK_WITH_AES_256_CCM_8, --+ MBEDTLS_TLS_PSK_WITH_ARIA_256_GCM_SHA384, --+ MBEDTLS_TLS_PSK_WITH_AES_128_GCM_SHA256, --+ MBEDTLS_TLS_PSK_WITH_AES_128_CCM, --+ MBEDTLS_TLS_PSK_WITH_AES_128_CBC_SHA256, --+ MBEDTLS_TLS_PSK_WITH_AES_128_CBC_SHA, --+ MBEDTLS_TLS_PSK_WITH_CAMELLIA_128_CBC_SHA256, --+ MBEDTLS_TLS_PSK_WITH_AES_128_CCM_8, --+ MBEDTLS_TLS_PSK_WITH_ARIA_128_GCM_SHA256 --+}; --+ --+ --+__attribute_noinline__ --+static int --+tls_mbedtls_append_ciphersuite (int *ids, int nids, int idsz, const int *x, int xsz) --+{ --+ if (xsz >= idsz - (nids + 1)) { --+ emsg(MSG_ERROR, "error: too many ciphers during list expand"); --+ return -1; --+ } --+ --+ for (int i = 0; i < xsz; ++i) --+ ids[++nids] = x[i]; --+ --+ return nids; --+} --+ --+ --+static int --+tls_mbedtls_translate_ciphername(int id, char *buf, size_t buflen) --+{ --+ const mbedtls_ssl_ciphersuite_t *info = --+ mbedtls_ssl_ciphersuite_from_id(id); --+ if (info == NULL) --+ return 0; --+ const char *name = mbedtls_ssl_ciphersuite_get_name(info); --+ const size_t len = os_strlen(name); --+ if (len == 7 && 0 == os_memcmp(name, "unknown", 7)) --+ return 0; --+ if (len >= buflen) --+ return 0; --+ os_strlcpy(buf, name, buflen); --+ --+ /* attempt to translate mbedtls string to openssl string --+ * (some heuristics; incomplete) */ --+ size_t i = 0, j = 0; --+ if (buf[0] == 'T') { --+ if (os_strncmp(buf, "TLS1-3-", 7) == 0) { --+ buf[3] = '-'; --+ j = 4; /* remove "1-3" from "TLS1-3-" prefix */ --+ i = 7; --+ } --+ else if (os_strncmp(buf, "TLS-", 4) == 0) --+ i = 4; /* remove "TLS-" prefix */ --+ } --+ for (; buf[i]; ++i) { --+ if (buf[i] == '-') { --+ if (i >= 3) { --+ if (0 == os_memcmp(buf+i-3, "AES", 3)) --+ continue; /* "AES-" -> "AES" */ --+ } --+ if (i >= 4) { --+ if (0 == os_memcmp(buf+i-4, "WITH", 4)) { --+ j -= 4; /* remove "WITH-" */ --+ continue; --+ } --+ } --+ } --+ buf[j++] = buf[i]; --+ } --+ buf[j] = '\0'; --+ --+ return j; --+} --+ --+ --+__attribute_noinline__ --+static int --+tls_mbedtls_set_ciphersuites(struct tls_conf *tls_conf, int *ids, int nids) --+{ --+ /* ciphersuites list must be persistent for lifetime of mbedtls_ssl_config*/ --+ os_free(tls_conf->ciphersuites); --+ tls_conf->ciphersuites = os_malloc(nids * sizeof(int)); --+ if (tls_conf->ciphersuites == NULL) --+ return 0; --+ os_memcpy(tls_conf->ciphersuites, ids, nids * sizeof(int)); --+ mbedtls_ssl_conf_ciphersuites(&tls_conf->conf, tls_conf->ciphersuites); --+ return 1; --+} --+ --+ --+static int --+tls_mbedtls_set_ciphers(struct tls_conf *tls_conf, const char *ciphers) --+{ --+ char buf[64]; --+ int ids[512]; --+ int nids = -1; --+ const int idsz = (int)(sizeof(ids)/sizeof(*ids)-1); --+ const char *next; --+ size_t blen, clen; --+ do { --+ next = os_strchr(ciphers, ':'); --+ clen = next ? (size_t)(next - ciphers) : os_strlen(ciphers); --+ if (!clen) --+ continue; --+ --+ /* special-case a select set of openssl group names for hwsim tests */ --+ /* (review; remove excess code if tests are not run for non-OpenSSL?) */ --+ if (clen == 9 && os_memcmp(ciphers, "SUITEB192", 9) == 0) { --+ static int ssl_preset_suiteb192_ciphersuites[] = { --+ MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384, --+ 0 --+ }; --+ return tls_mbedtls_set_ciphersuites(tls_conf, --+ ssl_preset_suiteb192_ciphersuites, --+ 2); --+ } --+ if (clen == 9 && os_memcmp(ciphers, "SUITEB128", 9) == 0) { --+ static int ssl_preset_suiteb128_ciphersuites[] = { --+ MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, --+ 0 --+ }; --+ return tls_mbedtls_set_ciphersuites(tls_conf, --+ ssl_preset_suiteb128_ciphersuites, --+ 2); --+ } --+ if (clen == 7 && os_memcmp(ciphers, "DEFAULT", 7) == 0) --+ continue; --+ if (clen == 6 && os_memcmp(ciphers, "AES128", 6) == 0) { --+ nids = tls_mbedtls_append_ciphersuite(ids, nids, idsz, --+ suite_AES_128_ephemeral, --+ (int)ARRAY_SIZE(suite_AES_128_ephemeral)); --+ if (nids == -1) --+ return 0; --+ continue; --+ } --+ if (clen == 6 && os_memcmp(ciphers, "AES256", 6) == 0) { --+ nids = tls_mbedtls_append_ciphersuite(ids, nids, idsz, --+ suite_AES_256_ephemeral, --+ (int)ARRAY_SIZE(suite_AES_256_ephemeral)); --+ if (nids == -1) --+ return 0; --+ continue; --+ } --+ if (clen == 4 && os_memcmp(ciphers, "HIGH", 4) == 0) { --+ nids = tls_mbedtls_append_ciphersuite(ids, nids, idsz, suite_HIGH, --+ (int)ARRAY_SIZE(suite_HIGH)); --+ if (nids == -1) --+ return 0; --+ continue; --+ } --+ /* ignore anonymous cipher group names (?not supported by mbedtls?) */ --+ if (clen == 4 && os_memcmp(ciphers, "!ADH", 4) == 0) --+ continue; --+ if (clen == 6 && os_memcmp(ciphers, "-aECDH", 6) == 0) --+ continue; --+ if (clen == 7 && os_memcmp(ciphers, "-aECDSA", 7) == 0) --+ continue; --+ --+ /* attempt to match mbedtls cipher names --+ * nb: does not support openssl group names or list manipulation syntax --+ * (alt: could copy almost 1200 lines (!!!) of lighttpd mod_mbedtls.c --+ * mod_mbedtls_ssl_conf_ciphersuites() to translate strings) --+ * note: not efficient to rewrite list for each ciphers entry, --+ * but this code is expected to run only at startup --+ */ --+ const int *list = mbedtls_ssl_list_ciphersuites(); --+ for (; *list; ++list) { --+ blen = tls_mbedtls_translate_ciphername(*list,buf,sizeof(buf)); --+ if (!blen) --+ continue; --+ --+ /* matching heuristics additional to translate_ciphername above */ --+ if (blen == clen+4) { --+ char *cbc = os_strstr(buf, "CBC-"); --+ if (cbc) { --+ os_memmove(cbc, cbc+4, blen-(cbc+4-buf)+1); /*(w/ '\0')*/ --+ blen -= 4; --+ } --+ } --+ if (blen >= clen && os_memcmp(ciphers, buf, clen) == 0 --+ && (blen == clen --+ || (blen == clen+7 && os_memcmp(buf+clen, "-SHA256", 7)))) { --+ if (1 >= idsz - (nids + 1)) { --+ emsg(MSG_ERROR, --+ "error: too many ciphers during list expand"); --+ return 0; --+ } --+ ids[++nids] = *list; --+ break; --+ } --+ } --+ if (*list == 0) { --+ wpa_printf(MSG_ERROR, --+ "MTLS: unrecognized cipher: %.*s", (int)clen, ciphers); --+ return 0; --+ } --+ } while ((ciphers = next ? next+1 : NULL)); --+ --+ if (-1 == nids) return 1; /* empty list; no-op */ --+ --+ ids[++nids] = 0; /* terminate list */ --+ ++nids; --+ --+ return tls_mbedtls_set_ciphersuites(tls_conf, ids, nids); --+} --+ --+ --+__attribute_noinline__ --+static int tls_mbedtls_set_item(char **config_item, const char *item) --+{ --+ os_free(*config_item); --+ *config_item = NULL; --+ return item ? (*config_item = os_strdup(item)) != NULL : 1; --+} --+ --+ --+static int tls_connection_set_subject_match(struct tls_conf *tls_conf, --+ const struct tls_connection_params *params) --+{ --+ int rc = 1; --+ rc &= tls_mbedtls_set_item(&tls_conf->subject_match, --+ params->subject_match); --+ rc &= tls_mbedtls_set_item(&tls_conf->altsubject_match, --+ params->altsubject_match); --+ rc &= tls_mbedtls_set_item(&tls_conf->suffix_match, --+ params->suffix_match); --+ rc &= tls_mbedtls_set_item(&tls_conf->domain_match, --+ params->domain_match); --+ rc &= tls_mbedtls_set_item(&tls_conf->check_cert_subject, --+ params->check_cert_subject); --+ return rc; --+} --+ --+ --+/* duplicated in crypto_mbedtls.c:crypto_mbedtls_readfile()*/ --+__attribute_noinline__ --+static int tls_mbedtls_readfile(const char *path, u8 **buf, size_t *n) --+{ --+ #if 0 /* #ifdef MBEDTLS_FS_IO */ --+ /*(includes +1 for '\0' needed by mbedtls PEM parsing funcs)*/ --+ if (mbedtls_pk_load_file(path, (unsigned char **)buf, n) != 0) { --+ wpa_printf(MSG_ERROR, "error: mbedtls_pk_load_file %s", path); --+ return -1; --+ } --+ #else --+ /*(use os_readfile() so that we can use os_free() --+ *(if we use mbedtls_pk_load_file() above, macros prevent calling free() --+ * directly #if defined(OS_REJECT_C_LIB_FUNCTIONS) and calling os_free() --+ * on buf aborts in tests if buf not allocated via os_malloc())*/ --+ *buf = (u8 *)os_readfile(path, n); --+ if (!*buf) { --+ wpa_printf(MSG_ERROR, "error: os_readfile %s", path); --+ return -1; --+ } --+ u8 *buf0 = os_realloc(*buf, *n+1); --+ if (!buf0) { --+ bin_clear_free(*buf, *n); --+ *buf = NULL; --+ return -1; --+ } --+ buf0[(*n)++] = '\0'; --+ *buf = buf0; --+ #endif --+ return 0; --+} --+ --+ --+static int tls_mbedtls_set_crl(struct tls_conf *tls_conf, const u8 *data, size_t len) --+{ --+ /* do not use mbedtls_x509_crl_parse() on PEM unless it contains CRL */ --+ if (len && data[len-1] == '\0' --+ && NULL == os_strstr((const char *)data,"-----BEGIN X509 CRL-----") --+ && tls_mbedtls_data_is_pem(data)) --+ return 0; --+ --+ mbedtls_x509_crl crl; --+ mbedtls_x509_crl_init(&crl); --+ int rc = mbedtls_x509_crl_parse(&crl, data, len); --+ if (rc < 0) { --+ mbedtls_x509_crl_free(&crl); --+ return rc == MBEDTLS_ERR_PEM_NO_HEADER_FOOTER_PRESENT ? 0 : rc; --+ } --+ --+ mbedtls_x509_crl *crl_new = os_malloc(sizeof(crl)); --+ if (crl_new == NULL) { --+ mbedtls_x509_crl_free(&crl); --+ return MBEDTLS_ERR_X509_ALLOC_FAILED; --+ } --+ os_memcpy(crl_new, &crl, sizeof(crl)); --+ --+ mbedtls_x509_crl *crl_old = tls_conf->crl; --+ tls_conf->crl = crl_new; --+ if (crl_old) { --+ mbedtls_x509_crl_free(crl_old); --+ os_free(crl_old); --+ } --+ return 0; --+} --+ --+ --+static int tls_mbedtls_set_ca(struct tls_conf *tls_conf, u8 *data, size_t len) --+{ --+ /* load crt struct onto stack and then copy into tls_conf in --+ * order to preserve existing tls_conf value if error occurs --+ * --+ * hostapd is not threaded, or else should allocate memory and swap in --+ * pointer reduce race condition. (If threaded, would also need to --+ * keep reference count of use to avoid freeing while still in use.) */ --+ --+ mbedtls_x509_crt crt; --+ mbedtls_x509_crt_init(&crt); --+ int rc = mbedtls_x509_crt_parse(&crt, data, len); --+ if (rc < 0) { --+ mbedtls_x509_crt_free(&crt); --+ return rc; --+ } --+ --+ mbedtls_x509_crt_free(&tls_conf->ca_cert); --+ os_memcpy(&tls_conf->ca_cert, &crt, sizeof(crt)); --+ return 0; --+} --+ --+ --+static int tls_mbedtls_set_ca_and_crl(struct tls_conf *tls_conf, const char *ca_cert_file) --+{ --+ size_t len; --+ u8 *data; --+ if (tls_mbedtls_readfile(ca_cert_file, &data, &len)) --+ return -1; --+ --+ int rc; --+ if (0 == (rc = tls_mbedtls_set_ca(tls_conf, data, len)) --+ && (!tls_mbedtls_data_is_pem(data) /*skip parse for CRL if not PEM*/ --+ || 0 == (rc = tls_mbedtls_set_crl(tls_conf, data, len)))) { --+ mbedtls_ssl_conf_ca_chain(&tls_conf->conf, --+ &tls_conf->ca_cert, --+ tls_conf->crl); --+ } --+ else { --+ elog(rc, __func__); --+ emsg(MSG_ERROR, ca_cert_file); --+ } --+ --+ forced_memzero(data, len); --+ os_free(data); --+ return rc; --+} --+ --+ --+static void tls_mbedtls_refresh_crl(void) --+{ --+ /* check for CRL refresh --+ * continue even if error occurs; continue with previous cert, CRL */ --+ unsigned int crl_reload_interval = tls_ctx_global.crl_reload_interval; --+ const char *ca_cert_file = tls_ctx_global.ca_cert_file; --+ if (!crl_reload_interval || !ca_cert_file) --+ return; --+ --+ struct os_reltime *previous = &tls_ctx_global.crl_reload_previous; --+ struct os_reltime now; --+ if (os_get_reltime(&now) != 0 --+ || !os_reltime_expired(&now, previous, crl_reload_interval)) --+ return; --+ --+ /* Note: modifying global state is not thread-safe --+ * if in use by existing connections --+ * --+ * src/utils/os.h does not provide a portable stat() --+ * or else it would be a good idea to check mtime and size, --+ * and avoid reloading if file has not changed */ --+ --+ if (tls_mbedtls_set_ca_and_crl(tls_ctx_global.tls_conf, ca_cert_file) == 0) --+ *previous = now; --+} --+ --+ --+static int tls_mbedtls_set_ca_cert(struct tls_conf *tls_conf, --+ const struct tls_connection_params *params) --+{ --+ if (params->ca_cert) { --+ if (os_strncmp(params->ca_cert, "probe://", 8) == 0) { --+ tls_conf->ca_cert_probe = 1; --+ tls_conf->has_ca_cert = 1; --+ return 0; --+ } --+ --+ if (os_strncmp(params->ca_cert, "hash://", 7) == 0) { --+ const char *pos = params->ca_cert + 7; --+ if (os_strncmp(pos, "server/sha256/", 14) != 0) { --+ emsg(MSG_ERROR, "unsupported ca_cert hash value"); --+ return -1; --+ } --+ pos += 14; --+ if (os_strlen(pos) != SHA256_DIGEST_LENGTH*2) { --+ emsg(MSG_ERROR, "unexpected ca_cert hash length"); --+ return -1; --+ } --+ if (hexstr2bin(pos, tls_conf->ca_cert_hash, --+ SHA256_DIGEST_LENGTH) < 0) { --+ emsg(MSG_ERROR, "invalid ca_cert hash value"); --+ return -1; --+ } --+ emsg(MSG_DEBUG, "checking only server certificate match"); --+ tls_conf->verify_depth0_only = 1; --+ tls_conf->has_ca_cert = 1; --+ return 0; --+ } --+ --+ if (tls_mbedtls_set_ca_and_crl(tls_conf, params->ca_cert) != 0) --+ return -1; --+ } --+ if (params->ca_cert_blob) { --+ size_t len = params->ca_cert_blob_len; --+ int is_pem = tls_mbedtls_data_is_pem(params->ca_cert_blob); --+ if (len && params->ca_cert_blob[len-1] != '\0' && is_pem) --+ ++len; /*(include '\0' in len for PEM)*/ --+ int ret = mbedtls_x509_crt_parse(&tls_conf->ca_cert, --+ params->ca_cert_blob, len); --+ if (ret != 0) { --+ elog(ret, "mbedtls_x509_crt_parse"); --+ return -1; --+ } --+ if (is_pem) { /*(ca_cert_blob in DER format contains ca cert only)*/ --+ ret = tls_mbedtls_set_crl(tls_conf, params->ca_cert_blob, len); --+ if (ret != 0) { --+ elog(ret, "mbedtls_x509_crl_parse"); --+ return -1; --+ } --+ } --+ } --+ --+ if (mbedtls_x509_time_is_future(&tls_conf->ca_cert.valid_from) --+ || mbedtls_x509_time_is_past(&tls_conf->ca_cert.valid_to)) { --+ emsg(MSG_WARNING, "ca_cert expired or not yet valid"); --+ if (params->ca_cert) --+ emsg(MSG_WARNING, params->ca_cert); --+ } --+ --+ tls_conf->has_ca_cert = 1; --+ return 0; --+} --+ --+ --+static int tls_mbedtls_set_certs(struct tls_conf *tls_conf, --+ const struct tls_connection_params *params) --+{ --+ int ret; --+ --+ if (params->ca_cert || params->ca_cert_blob) { --+ if (tls_mbedtls_set_ca_cert(tls_conf, params) != 0) --+ return -1; --+ } --+ else if (params->ca_path) { --+ emsg(MSG_INFO, "ca_path support not implemented"); --+ return -1; --+ } --+ --+ if (!tls_conf->has_ca_cert) --+ mbedtls_ssl_conf_authmode(&tls_conf->conf, MBEDTLS_SSL_VERIFY_NONE); --+ else { --+ /* Initial setting: REQUIRED for client, OPTIONAL for server --+ * (see also tls_connection_set_verify()) */ --+ tls_conf->verify_peer = (tls_ctx_global.tls_conf == NULL); --+ int authmode = tls_conf->verify_peer --+ ? MBEDTLS_SSL_VERIFY_REQUIRED --+ : MBEDTLS_SSL_VERIFY_OPTIONAL; --+ mbedtls_ssl_conf_authmode(&tls_conf->conf, authmode); --+ mbedtls_ssl_conf_ca_chain(&tls_conf->conf, --+ &tls_conf->ca_cert, --+ tls_conf->crl); --+ --+ if (!tls_connection_set_subject_match(tls_conf, params)) --+ return -1; --+ } --+ --+ if (params->client_cert2) /*(yes, server_cert2 in msg below)*/ --+ emsg(MSG_INFO, "server_cert2 support not implemented"); --+ --+ if (params->client_cert) { --+ size_t len; --+ u8 *data; --+ if (tls_mbedtls_readfile(params->client_cert, &data, &len)) --+ return -1; --+ ret = mbedtls_x509_crt_parse(&tls_conf->client_cert, data, len); --+ forced_memzero(data, len); --+ os_free(data); --+ } --+ if (params->client_cert_blob) { --+ size_t len = params->client_cert_blob_len; --+ if (len && params->client_cert_blob[len-1] != '\0' --+ && tls_mbedtls_data_is_pem(params->client_cert_blob)) --+ ++len; /*(include '\0' in len for PEM)*/ --+ ret = mbedtls_x509_crt_parse(&tls_conf->client_cert, --+ params->client_cert_blob, len); --+ } --+ if (params->client_cert || params->client_cert_blob) { --+ if (ret < 0) { --+ elog(ret, "mbedtls_x509_crt_parse"); --+ if (params->client_cert) --+ emsg(MSG_ERROR, params->client_cert); --+ return -1; --+ } --+ if (mbedtls_x509_time_is_future(&tls_conf->client_cert.valid_from) --+ || mbedtls_x509_time_is_past(&tls_conf->client_cert.valid_to)) { --+ emsg(MSG_WARNING, "cert expired or not yet valid"); --+ if (params->client_cert) --+ emsg(MSG_WARNING, params->client_cert); --+ } --+ tls_conf->has_client_cert = 1; --+ } --+ --+ if (params->private_key || params->private_key_blob) { --+ size_t len = params->private_key_blob_len; --+ u8 *data; --+ *(const u8 **)&data = params->private_key_blob; --+ if (len && data[len-1] != '\0' && tls_mbedtls_data_is_pem(data)) --+ ++len; /*(include '\0' in len for PEM)*/ --+ if (params->private_key --+ && tls_mbedtls_readfile(params->private_key, &data, &len)) { --+ return -1; --+ } --+ const char *pwd = params->private_key_passwd; --+ #if MBEDTLS_VERSION_NUMBER >= 0x03000000 /* mbedtls 3.0.0 */ --+ ret = mbedtls_pk_parse_key(&tls_conf->private_key, --+ data, len, --+ (const unsigned char *)pwd, --+ pwd ? os_strlen(pwd) : 0, --+ mbedtls_ctr_drbg_random, --+ tls_ctx_global.ctr_drbg); --+ #else --+ ret = mbedtls_pk_parse_key(&tls_conf->private_key, --+ data, len, --+ (const unsigned char *)pwd, --+ pwd ? os_strlen(pwd) : 0); --+ #endif --+ if (params->private_key) { --+ forced_memzero(data, len); --+ os_free(data); --+ } --+ if (ret < 0) { --+ elog(ret, "mbedtls_pk_parse_key"); --+ return -1; --+ } --+ tls_conf->has_private_key = 1; --+ } --+ --+ if (tls_conf->has_client_cert && tls_conf->has_private_key) { --+ ret = mbedtls_ssl_conf_own_cert( --+ &tls_conf->conf, &tls_conf->client_cert, &tls_conf->private_key); --+ if (ret < 0) { --+ elog(ret, "mbedtls_ssl_conf_own_cert"); --+ return -1; --+ } --+ } --+ --+ return 0; --+} --+ --+ --+/* mbedtls_x509_crt_profile_suiteb plus rsa_min_bitlen 2048 */ --+/* (reference: see also mbedtls_x509_crt_profile_next) */ --+/* ??? should permit SHA-512, too, and additional curves ??? */ --+static const mbedtls_x509_crt_profile tls_mbedtls_crt_profile_suiteb128 = --+{ --+ /* Only SHA-256 and 384 */ --+ MBEDTLS_X509_ID_FLAG( MBEDTLS_MD_SHA256 ) | --+ MBEDTLS_X509_ID_FLAG( MBEDTLS_MD_SHA384 ), --+ /* Only ECDSA */ --+ MBEDTLS_X509_ID_FLAG( MBEDTLS_PK_ECDSA ) | --+ MBEDTLS_X509_ID_FLAG( MBEDTLS_PK_ECKEY ), --+#if defined(MBEDTLS_ECP_C) --+ /* Only NIST P-256 and P-384 */ --+ MBEDTLS_X509_ID_FLAG( MBEDTLS_ECP_DP_SECP256R1 ) | --+ MBEDTLS_X509_ID_FLAG( MBEDTLS_ECP_DP_SECP384R1 ), --+#else --+ 0, --+#endif --+ 2048, --+}; --+ --+ --+/* stricter than mbedtls_x509_crt_profile_suiteb */ --+/* (reference: see also mbedtls_x509_crt_profile_next) */ --+/* ??? should permit SHA-512, too, and additional curves ??? */ --+static const mbedtls_x509_crt_profile tls_mbedtls_crt_profile_suiteb192 = --+{ --+ /* Only SHA-384 */ --+ MBEDTLS_X509_ID_FLAG( MBEDTLS_MD_SHA384 ), --+ /* Only ECDSA */ --+ MBEDTLS_X509_ID_FLAG( MBEDTLS_PK_ECDSA ) | --+ MBEDTLS_X509_ID_FLAG( MBEDTLS_PK_ECKEY ), --+#if defined(MBEDTLS_ECP_C) --+ /* Only NIST P-384 */ --+ MBEDTLS_X509_ID_FLAG( MBEDTLS_ECP_DP_SECP384R1 ), --+#else --+ 0, --+#endif --+ 3072, --+}; --+ --+ --+/* stricter than mbedtls_x509_crt_profile_suiteb except allow any PK alg */ --+/* (reference: see also mbedtls_x509_crt_profile_next) */ --+/* ??? should permit SHA-512, too, and additional curves ??? */ --+static const mbedtls_x509_crt_profile tls_mbedtls_crt_profile_suiteb192_anypk = --+{ --+ /* Only SHA-384 */ --+ MBEDTLS_X509_ID_FLAG( MBEDTLS_MD_SHA384 ), --+ 0xFFFFFFF, /* Any PK alg */ --+#if defined(MBEDTLS_ECP_C) --+ /* Only NIST P-384 */ --+ MBEDTLS_X509_ID_FLAG( MBEDTLS_ECP_DP_SECP384R1 ), --+#else --+ 0, --+#endif --+ 3072, --+}; --+ --+ --+static int tls_mbedtls_set_params(struct tls_conf *tls_conf, --+ const struct tls_connection_params *params) --+{ --+ tls_conf->flags = params->flags; --+ --+ if (tls_conf->flags & TLS_CONN_REQUIRE_OCSP_ALL) { --+ emsg(MSG_INFO, "ocsp=3 not supported"); --+ return -1; --+ } --+ --+ if (tls_conf->flags & TLS_CONN_REQUIRE_OCSP) { --+ emsg(MSG_INFO, "ocsp not supported"); --+ return -1; --+ } --+ --+ int suiteb128 = 0; --+ int suiteb192 = 0; --+ if (params->openssl_ciphers) { --+ if (os_strcmp(params->openssl_ciphers, "SUITEB192") == 0) { --+ suiteb192 = 1; --+ tls_conf->flags |= TLS_CONN_SUITEB; --+ } --+ if (os_strcmp(params->openssl_ciphers, "SUITEB128") == 0) { --+ suiteb128 = 1; --+ tls_conf->flags |= TLS_CONN_SUITEB; --+ } --+ } --+ --+ int ret = mbedtls_ssl_config_defaults( --+ &tls_conf->conf, tls_ctx_global.tls_conf ? MBEDTLS_SSL_IS_SERVER --+ : MBEDTLS_SSL_IS_CLIENT, --+ MBEDTLS_SSL_TRANSPORT_STREAM, --+ (tls_conf->flags & TLS_CONN_SUITEB) ? MBEDTLS_SSL_PRESET_SUITEB --+ : MBEDTLS_SSL_PRESET_DEFAULT); --+ if (ret != 0) { --+ elog(ret, "mbedtls_ssl_config_defaults"); --+ return -1; --+ } --+ --+ if (suiteb128) { --+ mbedtls_ssl_conf_cert_profile(&tls_conf->conf, --+ &tls_mbedtls_crt_profile_suiteb128); --+ mbedtls_ssl_conf_dhm_min_bitlen(&tls_conf->conf, 2048); --+ } --+ else if (suiteb192) { --+ mbedtls_ssl_conf_cert_profile(&tls_conf->conf, --+ &tls_mbedtls_crt_profile_suiteb192); --+ mbedtls_ssl_conf_dhm_min_bitlen(&tls_conf->conf, 3072); --+ } --+ else if (tls_conf->flags & TLS_CONN_SUITEB) { --+ /* treat as suiteb192 while allowing any PK algorithm */ --+ mbedtls_ssl_conf_cert_profile(&tls_conf->conf, --+ &tls_mbedtls_crt_profile_suiteb192_anypk); --+ mbedtls_ssl_conf_dhm_min_bitlen(&tls_conf->conf, 3072); --+ } --+ --+ tls_mbedtls_set_allowed_tls_vers(tls_conf, &tls_conf->conf); --+ ret = tls_mbedtls_set_certs(tls_conf, params); --+ if (ret != 0) --+ return -1; --+ --+ if (params->dh_file --+ && !tls_mbedtls_set_dhparams(tls_conf, params->dh_file)) { --+ return -1; --+ } --+ --+ if (params->openssl_ecdh_curves --+ && !tls_mbedtls_set_curves(tls_conf, params->openssl_ecdh_curves)) { --+ return -1; --+ } --+ --+ if (params->openssl_ciphers) { --+ if (!tls_mbedtls_set_ciphers(tls_conf, params->openssl_ciphers)) --+ return -1; --+ } --+ else if (tls_conf->flags & TLS_CONN_SUITEB) { --+ /* special-case a select set of ciphers for hwsim tests */ --+ if (!tls_mbedtls_set_ciphers(tls_conf, --+ (tls_conf->flags & TLS_CONN_SUITEB_NO_ECDH) --+ ? "DHE-RSA-AES256-GCM-SHA384" --+ : "ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES256-GCM-SHA384")) --+ return -1; --+ } --+ --+ return 0; --+} --+ --+ --+int tls_connection_set_params(void *tls_ctx, struct tls_connection *conn, --+ const struct tls_connection_params *params) --+{ --+ if (conn == NULL || params == NULL) --+ return -1; --+ --+ tls_conf_deinit(conn->tls_conf); --+ struct tls_conf *tls_conf = conn->tls_conf = tls_conf_init(tls_ctx); --+ if (tls_conf == NULL) --+ return -1; --+ --+ if (tls_ctx_global.tls_conf) { --+ tls_conf->check_crl = tls_ctx_global.tls_conf->check_crl; --+ tls_conf->check_crl_strict = tls_ctx_global.tls_conf->check_crl_strict; --+ /*(tls_openssl.c inherits check_cert_subject from global conf)*/ --+ if (tls_ctx_global.tls_conf->check_cert_subject) { --+ tls_conf->check_cert_subject = --+ os_strdup(tls_ctx_global.tls_conf->check_cert_subject); --+ if (tls_conf->check_cert_subject == NULL) --+ return -1; --+ } --+ } --+ --+ if (tls_mbedtls_set_params(tls_conf, params) != 0) --+ return -1; --+ conn->verify_peer = tls_conf->verify_peer; --+ --+ return tls_mbedtls_ssl_setup(conn); --+} --+ --+ --+#ifdef TLS_MBEDTLS_SESSION_TICKETS --+ --+static int tls_mbedtls_clienthello_session_ticket_prep (struct tls_connection *conn, --+ const u8 *data, size_t len) --+{ --+ if (conn->tls_conf->flags & TLS_CONN_DISABLE_SESSION_TICKET) --+ return -1; --+ if (conn->clienthello_session_ticket) --+ tls_connection_deinit_clienthello_session_ticket(conn); --+ if (len) { --+ conn->clienthello_session_ticket = mbedtls_calloc(1, len); --+ if (conn->clienthello_session_ticket == NULL) --+ return -1; --+ conn->clienthello_session_ticket_len = len; --+ os_memcpy(conn->clienthello_session_ticket, data, len); --+ } --+ return 0; --+} --+ --+ --+static void tls_mbedtls_clienthello_session_ticket_set (struct tls_connection *conn) --+{ --+ mbedtls_ssl_session *sess = conn->ssl.MBEDTLS_PRIVATE(session_negotiate); --+ if (sess->MBEDTLS_PRIVATE(ticket)) { --+ mbedtls_platform_zeroize(sess->MBEDTLS_PRIVATE(ticket), --+ sess->MBEDTLS_PRIVATE(ticket_len)); --+ mbedtls_free(sess->MBEDTLS_PRIVATE(ticket)); --+ } --+ sess->MBEDTLS_PRIVATE(ticket) = conn->clienthello_session_ticket; --+ sess->MBEDTLS_PRIVATE(ticket_len) = conn->clienthello_session_ticket_len; --+ sess->MBEDTLS_PRIVATE(ticket_lifetime) = 86400;/* XXX: can hint be 0? */ --+ --+ conn->clienthello_session_ticket = NULL; --+ conn->clienthello_session_ticket_len = 0; --+} --+ --+ --+static int tls_mbedtls_ssl_ticket_write(void *p_ticket, --+ const mbedtls_ssl_session *session, --+ unsigned char *start, --+ const unsigned char *end, --+ size_t *tlen, --+ uint32_t *lifetime) --+{ --+ struct tls_connection *conn = p_ticket; --+ if (conn && conn->session_ticket_cb) { --+ /* see tls_mbedtls_clienthello_session_ticket_prep() */ --+ /* see tls_mbedtls_clienthello_session_ticket_set() */ --+ return 0; --+ } --+ --+ return mbedtls_ssl_ticket_write(&tls_ctx_global.ticket_ctx, --+ session, start, end, tlen, lifetime); --+} --+ --+ --+static int tls_mbedtls_ssl_ticket_parse(void *p_ticket, --+ mbedtls_ssl_session *session, --+ unsigned char *buf, --+ size_t len) --+{ --+ /* XXX: TODO: not implemented in client; --+ * mbedtls_ssl_conf_session_tickets_cb() callbacks only for TLS server*/ --+ --+ if (len == 0) --+ return MBEDTLS_ERR_SSL_BAD_INPUT_DATA; --+ --+ struct tls_connection *conn = p_ticket; --+ if (conn && conn->session_ticket_cb) { --+ /* XXX: have random and secret been initialized yet? --+ * or must keys first be exported? --+ * EAP-FAST uses all args, EAP-TEAP only uses secret */ --+ struct tls_random data; --+ if (tls_connection_get_random(NULL, conn, &data) != 0) --+ return MBEDTLS_ERR_SSL_INTERNAL_ERROR; --+ int ret = --+ conn->session_ticket_cb(conn->session_ticket_cb_ctx, --+ buf, len, --+ data.client_random, --+ data.server_random, --+ conn->expkey_secret); --+ if (ret == 1) { --+ conn->resumed = 1; --+ return 0; --+ } --+ emsg(MSG_ERROR, "EAP session ticket ext not implemented"); --+ return MBEDTLS_ERR_SSL_INVALID_MAC; --+ /*(non-zero return used for mbedtls debug logging)*/ --+ } --+ --+ /* XXX: TODO always use tls_mbedtls_ssl_ticket_parse() for callback? */ --+ int rc = mbedtls_ssl_ticket_parse(&tls_ctx_global.ticket_ctx, --+ session, buf, len); --+ if (conn) --+ conn->resumed = (rc == 0); --+ return rc; --+} --+ --+#endif /* TLS_MBEDTLS_SESSION_TICKETS */ --+ --+ --+__attribute_cold__ --+int tls_global_set_params(void *tls_ctx, --+ const struct tls_connection_params *params) --+{ --+ /* XXX: why might global_set_params be called more than once? */ --+ if (tls_ctx_global.tls_conf) --+ tls_conf_deinit(tls_ctx_global.tls_conf); --+ tls_ctx_global.tls_conf = tls_conf_init(tls_ctx); --+ if (tls_ctx_global.tls_conf == NULL) --+ return -1; --+ --+ #ifdef MBEDTLS_SSL_SESSION_TICKETS --+ #ifdef MBEDTLS_SSL_TICKET_C --+ if (!(params->flags & TLS_CONN_DISABLE_SESSION_TICKET)) --+ #ifdef TLS_MBEDTLS_SESSION_TICKETS --+ mbedtls_ssl_conf_session_tickets_cb(&tls_ctx_global.tls_conf->conf, --+ tls_mbedtls_ssl_ticket_write, --+ tls_mbedtls_ssl_ticket_parse, --+ NULL); --+ #else --+ mbedtls_ssl_conf_session_tickets_cb(&tls_ctx_global.tls_conf->conf, --+ mbedtls_ssl_ticket_write, --+ mbedtls_ssl_ticket_parse, --+ &tls_ctx_global.ticket_ctx); --+ #endif --+ #endif --+ #endif --+ --+ os_free(tls_ctx_global.ocsp_stapling_response); --+ tls_ctx_global.ocsp_stapling_response = NULL; --+ if (params->ocsp_stapling_response) --+ tls_ctx_global.ocsp_stapling_response = --+ os_strdup(params->ocsp_stapling_response); --+ --+ os_free(tls_ctx_global.ca_cert_file); --+ tls_ctx_global.ca_cert_file = NULL; --+ if (params->ca_cert) --+ tls_ctx_global.ca_cert_file = os_strdup(params->ca_cert); --+ return tls_mbedtls_set_params(tls_ctx_global.tls_conf, params); --+} --+ --+ --+int tls_global_set_verify(void *tls_ctx, int check_crl, int strict) --+{ --+ tls_ctx_global.tls_conf->check_crl = check_crl; --+ tls_ctx_global.tls_conf->check_crl_strict = strict; /*(time checks)*/ --+ return 0; --+} --+ --+ --+int tls_connection_set_verify(void *tls_ctx, struct tls_connection *conn, --+ int verify_peer, unsigned int flags, --+ const u8 *session_ctx, size_t session_ctx_len) --+{ --+ /*(EAP server-side calls this from eap_server_tls_ssl_init())*/ --+ if (conn == NULL) --+ return -1; --+ --+ conn->tls_conf->flags |= flags;/* TODO: reprocess flags, if necessary */ --+ --+ int authmode; --+ switch (verify_peer) { --+ case 2: authmode = MBEDTLS_SSL_VERIFY_OPTIONAL; break;/*(eap_teap_init())*/ --+ case 1: authmode = MBEDTLS_SSL_VERIFY_REQUIRED; break; --+ default: authmode = MBEDTLS_SSL_VERIFY_NONE; break; --+ } --+ mbedtls_ssl_set_hs_authmode(&conn->ssl, authmode); --+ --+ if ((conn->verify_peer = (authmode != MBEDTLS_SSL_VERIFY_NONE))) --+ mbedtls_ssl_set_verify(&conn->ssl, tls_mbedtls_verify_cb, conn); --+ else --+ mbedtls_ssl_set_verify(&conn->ssl, NULL, NULL); --+ --+ return 0; --+} --+ --+ --+#if MBEDTLS_VERSION_NUMBER >= 0x03000000 /* mbedtls 3.0.0 */ --+static void tls_connection_export_keys_cb( --+ void *p_expkey, mbedtls_ssl_key_export_type secret_type, --+ const unsigned char *secret, size_t secret_len, --+ const unsigned char client_random[MBEDTLS_EXPKEY_RAND_LEN], --+ const unsigned char server_random[MBEDTLS_EXPKEY_RAND_LEN], --+ mbedtls_tls_prf_types tls_prf_type) --+{ --+ struct tls_connection *conn = p_expkey; --+ conn->tls_prf_type = tls_prf_type; --+ if (!tls_prf_type) --+ return; --+ if (secret_len > sizeof(conn->expkey_secret)) { --+ emsg(MSG_ERROR, "tls_connection_export_keys_cb secret too long"); --+ conn->tls_prf_type = MBEDTLS_SSL_TLS_PRF_NONE; /* 0 */ --+ return; --+ } --+ conn->expkey_secret_len = secret_len; --+ os_memcpy(conn->expkey_secret, secret, secret_len); --+ os_memcpy(conn->expkey_randbytes, --+ client_random, MBEDTLS_EXPKEY_RAND_LEN); --+ os_memcpy(conn->expkey_randbytes + MBEDTLS_EXPKEY_RAND_LEN, --+ server_random, MBEDTLS_EXPKEY_RAND_LEN); --+} --+#elif MBEDTLS_VERSION_NUMBER >= 0x02120000 /* mbedtls 2.18.0 */ --+static int tls_connection_export_keys_cb( --+ void *p_expkey, --+ const unsigned char *ms, --+ const unsigned char *kb, --+ size_t maclen, --+ size_t keylen, --+ size_t ivlen, --+ const unsigned char client_random[MBEDTLS_EXPKEY_RAND_LEN], --+ const unsigned char server_random[MBEDTLS_EXPKEY_RAND_LEN], --+ mbedtls_tls_prf_types tls_prf_type ) --+{ --+ struct tls_connection *conn = p_expkey; --+ conn->tls_prf_type = tls_prf_type; --+ if (!tls_prf_type) --+ return -1; /*(return value ignored by mbedtls)*/ --+ conn->expkey_keyblock_size = maclen + keylen + ivlen; --+ conn->expkey_secret_len = MBEDTLS_EXPKEY_FIXED_SECRET_LEN; --+ os_memcpy(conn->expkey_secret, ms, MBEDTLS_EXPKEY_FIXED_SECRET_LEN); --+ os_memcpy(conn->expkey_randbytes, --+ client_random, MBEDTLS_EXPKEY_RAND_LEN); --+ os_memcpy(conn->expkey_randbytes + MBEDTLS_EXPKEY_RAND_LEN, --+ server_random, MBEDTLS_EXPKEY_RAND_LEN); --+ return 0; --+} --+#endif --+ --+ --+int tls_connection_get_random(void *tls_ctx, struct tls_connection *conn, --+ struct tls_random *data) --+{ --+ if (!conn || !conn->tls_prf_type) --+ return -1; --+ data->client_random = conn->expkey_randbytes; --+ data->client_random_len = MBEDTLS_EXPKEY_RAND_LEN; --+ data->server_random = conn->expkey_randbytes + MBEDTLS_EXPKEY_RAND_LEN; --+ data->server_random_len = MBEDTLS_EXPKEY_RAND_LEN; --+ return 0; --+} --+ --+ --+int tls_connection_export_key(void *tls_ctx, struct tls_connection *conn, --+ const char *label, const u8 *context, --+ size_t context_len, u8 *out, size_t out_len) --+{ --+ /* (EAP-PEAP EAP-TLS EAP-TTLS) */ --+ #if MBEDTLS_VERSION_NUMBER >= 0x02120000 /* mbedtls 2.18.0 */ --+ return (conn && conn->established && conn->tls_prf_type) --+ ? mbedtls_ssl_tls_prf(conn->tls_prf_type, --+ conn->expkey_secret, conn->expkey_secret_len, label, --+ conn->expkey_randbytes, --+ sizeof(conn->expkey_randbytes), out, out_len) --+ : -1; --+ #else --+ /* not implemented here for mbedtls < 2.18.0 */ --+ return -1; --+ #endif --+} --+ --+ --+#ifdef TLS_MBEDTLS_EAP_FAST --+ --+#if MBEDTLS_VERSION_NUMBER >= 0x03000000 /* mbedtls 3.0.0 */ --+/* keyblock size info is not exposed in mbed TLS 3.0.0 */ --+/* extracted from mbedtls library/ssl_tls.c:ssl_tls12_populate_transform() */ --+#include --+#include --+static size_t tls_mbedtls_ssl_keyblock_size (mbedtls_ssl_context *ssl) --+{ --+ #if !defined(MBEDTLS_USE_PSA_CRYPTO) /* XXX: (not extracted for PSA crypto) */ --+ #if defined(MBEDTLS_SSL_PROTO_TLS1_3) --+ if (tls_version == MBEDTLS_SSL_VERSION_TLS1_3) --+ return 0; /* (calculation not extracted) */ --+ #endif /* MBEDTLS_SSL_PROTO_TLS1_3 */ --+ --+ int ciphersuite = mbedtls_ssl_get_ciphersuite_id_from_ssl(ssl); --+ const mbedtls_ssl_ciphersuite_t *ciphersuite_info = --+ mbedtls_ssl_ciphersuite_from_id(ciphersuite); --+ if (ciphersuite_info == NULL) --+ return 0; --+ --+ const mbedtls_cipher_info_t *cipher_info = --+ mbedtls_cipher_info_from_type(ciphersuite_info->MBEDTLS_PRIVATE(cipher)); --+ if (cipher_info == NULL) --+ return 0; --+ --+ #if MBEDTLS_VERSION_NUMBER >= 0x03010000 /* mbedtls 3.1.0 */ --+ size_t keylen = mbedtls_cipher_info_get_key_bitlen(cipher_info) / 8; --+ mbedtls_cipher_mode_t mode = mbedtls_cipher_info_get_mode(cipher_info); --+ #else --+ size_t keylen = cipher_info->MBEDTLS_PRIVATE(key_bitlen) / 8; --+ mbedtls_cipher_mode_t mode = cipher_info->MBEDTLS_PRIVATE(mode); --+ #endif --+ #if defined(MBEDTLS_GCM_C) || \ --+ defined(MBEDTLS_CCM_C) || \ --+ defined(MBEDTLS_CHACHAPOLY_C) --+ if (mode == MBEDTLS_MODE_GCM || mode == MBEDTLS_MODE_CCM) --+ return keylen + 4; --+ else if (mode == MBEDTLS_MODE_CHACHAPOLY) --+ return keylen + 12; --+ else --+ #endif /* MBEDTLS_GCM_C || MBEDTLS_CCM_C || MBEDTLS_CHACHAPOLY_C */ --+ #if defined(MBEDTLS_SSL_SOME_SUITES_USE_MAC) --+ { --+ const mbedtls_md_info_t *md_info = --+ mbedtls_md_info_from_type(ciphersuite_info->MBEDTLS_PRIVATE(mac)); --+ if (md_info == NULL) --+ return 0; --+ size_t mac_key_len = mbedtls_md_get_size(md_info); --+ size_t ivlen = mbedtls_cipher_info_get_iv_size(cipher_info); --+ return keylen + mac_key_len + ivlen; --+ } --+ #endif /* MBEDTLS_SSL_SOME_SUITES_USE_MAC */ --+ #endif /* !MBEDTLS_USE_PSA_CRYPTO *//* (not extracted for PSA crypto) */ --+ return 0; --+} --+#endif /* MBEDTLS_VERSION_NUMBER >= 0x03000000 *//* mbedtls 3.0.0 */ --+ --+ --+int tls_connection_get_eap_fast_key(void *tls_ctx, struct tls_connection *conn, --+ u8 *out, size_t out_len) --+{ --+ /* XXX: has export keys callback been run? */ --+ if (!conn || !conn->tls_prf_type) --+ return -1; --+ --+ #if MBEDTLS_VERSION_NUMBER >= 0x03000000 /* mbedtls 3.0.0 */ --+ conn->expkey_keyblock_size = tls_mbedtls_ssl_keyblock_size(&conn->ssl); --+ if (conn->expkey_keyblock_size == 0) --+ return -1; --+ #endif --+ size_t skip = conn->expkey_keyblock_size * 2; --+ unsigned char *tmp_out = os_malloc(skip + out_len); --+ if (!tmp_out) --+ return -1; --+ --+ /* server_random and then client_random */ --+ unsigned char seed[MBEDTLS_EXPKEY_RAND_LEN*2]; --+ os_memcpy(seed, conn->expkey_randbytes + MBEDTLS_EXPKEY_RAND_LEN, --+ MBEDTLS_EXPKEY_RAND_LEN); --+ os_memcpy(seed + MBEDTLS_EXPKEY_RAND_LEN, conn->expkey_randbytes, --+ MBEDTLS_EXPKEY_RAND_LEN); --+ --+ #if MBEDTLS_VERSION_NUMBER >= 0x02120000 /* mbedtls 2.18.0 */ --+ int ret = mbedtls_ssl_tls_prf(conn->tls_prf_type, --+ conn->expkey_secret, conn->expkey_secret_len, --+ "key expansion", seed, sizeof(seed), --+ tmp_out, skip + out_len); --+ if (ret == 0) --+ os_memcpy(out, tmp_out + skip, out_len); --+ #else --+ int ret = -1; /*(not reached if not impl; return -1 at top of func)*/ --+ #endif --+ --+ bin_clear_free(tmp_out, skip + out_len); --+ forced_memzero(seed, sizeof(seed)); --+ return ret; --+} --+ --+#endif /* TLS_MBEDTLS_EAP_FAST */ --+ --+ --+__attribute_cold__ --+static void tls_mbedtls_suiteb_handshake_alert (struct tls_connection *conn) --+{ --+ /* tests/hwsim/test_suite_b.py test_suite_b_192_rsa_insufficient_dh */ --+ if (!(conn->tls_conf->flags & TLS_CONN_SUITEB)) --+ return; --+ if (tls_ctx_global.tls_conf) /*(is server; want issue event on client)*/ --+ return; --+ #if 0 --+ /*(info not available on client; --+ * mbed TLS library enforces dhm min bitlen in ServerKeyExchange)*/ --+ if (MBEDTLS_TLS_DHE_RSA_WITH_AES_256_GCM_SHA384 == --+ #if MBEDTLS_VERSION_NUMBER < 0x03020000 /* mbedtls 3.2.0 */ --+ mbedtls_ssl_get_ciphersuite_id_from_ssl(&conn->ssl) --+ #else --+ mbedtls_ssl_get_ciphersuite_id( --+ mbedtls_ssl_get_ciphersuite(&conn->ssl)) --+ #endif --+ && mbedtls_mpi_size(&conn->tls_conf->conf.MBEDTLS_PRIVATE(dhm_P)) --+ < 384 /*(3072/8)*/) --+ #endif --+ { --+ struct tls_config *init_conf = &tls_ctx_global.init_conf; --+ if (init_conf->event_cb) { --+ union tls_event_data ev; --+ os_memset(&ev, 0, sizeof(ev)); --+ ev.alert.is_local = 1; --+ ev.alert.type = "fatal"; --+ /*"internal error" string for tests/hwsim/test_suiteb.py */ --+ ev.alert.description = "internal error: handshake failure"; --+ /*ev.alert.description = "insufficient security";*/ --+ init_conf->event_cb(init_conf->cb_ctx, TLS_ALERT, &ev); --+ } --+ } --+} --+ --+ --+struct wpabuf * tls_connection_handshake(void *tls_ctx, --+ struct tls_connection *conn, --+ const struct wpabuf *in_data, --+ struct wpabuf **appl_data) --+{ --+ if (appl_data) --+ *appl_data = NULL; --+ --+ if (in_data && wpabuf_len(in_data)) { --+ /*(unsure why tls_gnutls.c discards buffer contents; skip here)*/ --+ if (conn->pull_buf && 0) /* disable; appears unwise */ --+ tls_pull_buf_discard(conn, __func__); --+ if (!tls_pull_buf_append(conn, in_data)) --+ return NULL; --+ } --+ --+ if (conn->tls_conf == NULL) { --+ struct tls_connection_params params; --+ os_memset(¶ms, 0, sizeof(params)); --+ params.openssl_ciphers = --+ tls_ctx_global.init_conf.openssl_ciphers; --+ params.flags = tls_ctx_global.tls_conf->flags; --+ if (tls_connection_set_params(tls_ctx, conn, ¶ms) != 0) --+ return NULL; --+ } --+ --+ if (conn->verify_peer) /*(call here might be redundant; nbd)*/ --+ mbedtls_ssl_set_verify(&conn->ssl, tls_mbedtls_verify_cb, conn); --+ --+ #ifdef TLS_MBEDTLS_SESSION_TICKETS --+ if (conn->clienthello_session_ticket) --+ /*(starting handshake for EAP-FAST and EAP-TEAP)*/ --+ tls_mbedtls_clienthello_session_ticket_set(conn); --+ --+ /* (not thread-safe due to need to set userdata 'conn' for callback) */ --+ /* (unable to use mbedtls_ssl_set_user_data_p() with mbedtls 3.2.0+ --+ * since ticket write and parse callbacks take (mbedtls_ssl_session *) --+ * param instead of (mbedtls_ssl_context *) param) */ --+ if (conn->tls_conf->flags & TLS_CONN_DISABLE_SESSION_TICKET) --+ mbedtls_ssl_conf_session_tickets_cb(&conn->tls_conf->conf, --+ NULL, NULL, NULL); --+ else --+ mbedtls_ssl_conf_session_tickets_cb(&conn->tls_conf->conf, --+ tls_mbedtls_ssl_ticket_write, --+ tls_mbedtls_ssl_ticket_parse, --+ conn); --+ #endif --+ --+ #if MBEDTLS_VERSION_NUMBER >= 0x03020000 /* mbedtls 3.2.0 */ --+ int ret = mbedtls_ssl_handshake(&conn->ssl); --+ #else --+ int ret = 0; --+ while (conn->ssl.MBEDTLS_PRIVATE(state) != MBEDTLS_SSL_HANDSHAKE_OVER) { --+ ret = mbedtls_ssl_handshake_step(&conn->ssl); --+ if (ret != 0) --+ break; --+ } --+ #endif --+ --+ #ifdef TLS_MBEDTLS_SESSION_TICKETS --+ mbedtls_ssl_conf_session_tickets_cb(&conn->tls_conf->conf, --+ tls_mbedtls_ssl_ticket_write, --+ tls_mbedtls_ssl_ticket_parse, --+ NULL); --+ #endif --+ --+ switch (ret) { --+ case 0: --+ conn->established = 1; --+ if (conn->push_buf == NULL) --+ /* Need to return something to get final TLS ACK. */ --+ conn->push_buf = wpabuf_alloc(0); --+ --+ if (appl_data /*&& conn->pull_buf && wpabuf_len(conn->pull_buf)*/) --+ *appl_data = NULL; /* RFE: check for application data */ --+ break; --+ case MBEDTLS_ERR_SSL_WANT_WRITE: --+ case MBEDTLS_ERR_SSL_WANT_READ: --+ case MBEDTLS_ERR_SSL_CRYPTO_IN_PROGRESS: --+ case MBEDTLS_ERR_SSL_ASYNC_IN_PROGRESS: --+ if (tls_ctx_global.tls_conf /*(is server)*/ --+ && conn->established && conn->push_buf == NULL) --+ /* Need to return something to trigger completion of EAP-TLS. */ --+ conn->push_buf = wpabuf_alloc(0); --+ break; --+ default: --+ ++conn->failed; --+ switch (ret) { --+ case MBEDTLS_ERR_SSL_CLIENT_RECONNECT: --+ case MBEDTLS_ERR_NET_CONN_RESET: --+ case MBEDTLS_ERR_NET_SEND_FAILED: --+ ++conn->write_alerts; --+ break; --+ #if MBEDTLS_VERSION_NUMBER >= 0x03000000 /* mbedtls 3.0.0 */ --+ case MBEDTLS_ERR_SSL_HANDSHAKE_FAILURE: --+ #else --+ case MBEDTLS_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE: --+ #endif --+ tls_mbedtls_suiteb_handshake_alert(conn); --+ /* fall through */ --+ case MBEDTLS_ERR_NET_RECV_FAILED: --+ case MBEDTLS_ERR_SSL_CONN_EOF: --+ case MBEDTLS_ERR_SSL_PEER_CLOSE_NOTIFY: --+ case MBEDTLS_ERR_SSL_FATAL_ALERT_MESSAGE: --+ ++conn->read_alerts; --+ break; --+ default: --+ break; --+ } --+ --+ ilog(ret, "mbedtls_ssl_handshake"); --+ break; --+ } --+ --+ struct wpabuf *out_data = conn->push_buf; --+ conn->push_buf = NULL; --+ return out_data; --+} --+ --+ --+struct wpabuf * tls_connection_server_handshake(void *tls_ctx, --+ struct tls_connection *conn, --+ const struct wpabuf *in_data, --+ struct wpabuf **appl_data) --+{ --+ conn->is_server = 1; --+ return tls_connection_handshake(tls_ctx, conn, in_data, appl_data); --+} --+ --+ --+struct wpabuf * tls_connection_encrypt(void *tls_ctx, --+ struct tls_connection *conn, --+ const struct wpabuf *in_data) --+{ --+ int res = mbedtls_ssl_write(&conn->ssl, --+ wpabuf_head_u8(in_data), wpabuf_len(in_data)); --+ if (res < 0) { --+ elog(res, "mbedtls_ssl_write"); --+ return NULL; --+ } --+ --+ struct wpabuf *buf = conn->push_buf; --+ conn->push_buf = NULL; --+ return buf; --+} --+ --+ --+struct wpabuf * tls_connection_decrypt(void *tls_ctx, --+ struct tls_connection *conn, --+ const struct wpabuf *in_data) --+{ --+ int res; --+ struct wpabuf *out; --+ --+ /*assert(in_data != NULL);*/ --+ if (!tls_pull_buf_append(conn, in_data)) --+ return NULL; --+ --+ #if defined(MBEDTLS_ZLIB_SUPPORT) /* removed in mbedtls 3.x */ --+ /* Add extra buffer space to handle the possibility of decrypted --+ * data being longer than input data due to TLS compression. */ --+ out = wpabuf_alloc((wpabuf_len(in_data) + 500) * 3); --+ #else /* TLS compression is disabled in mbedtls 3.x */ --+ out = wpabuf_alloc(wpabuf_len(in_data)); --+ #endif --+ if (out == NULL) --+ return NULL; --+ --+ res = mbedtls_ssl_read(&conn->ssl, wpabuf_mhead(out), wpabuf_size(out)); --+ if (res < 0) { --+ #if 1 /*(seems like a different error if wpabuf_len(in_data) == 0)*/ --+ if (res == MBEDTLS_ERR_SSL_WANT_READ) --+ return out; --+ #endif --+ elog(res, "mbedtls_ssl_read"); --+ wpabuf_free(out); --+ return NULL; --+ } --+ wpabuf_put(out, res); --+ --+ return out; --+} --+ --+ --+int tls_connection_resumed(void *tls_ctx, struct tls_connection *conn) --+{ --+ /* XXX: might need to detect if session resumed from TLS session ticket --+ * even if not special session ticket handling for EAP-FAST, EAP-TEAP */ --+ /* (?ssl->handshake->resume during session ticket validation?) */ --+ return conn && conn->resumed; --+} --+ --+ --+#ifdef TLS_MBEDTLS_EAP_FAST --+int tls_connection_set_cipher_list(void *tls_ctx, struct tls_connection *conn, --+ u8 *ciphers) --+{ --+ /* ciphers is list of TLS_CIPHER_* from hostap/src/crypto/tls.h */ --+ int ids[7]; --+ const int idsz = (int)sizeof(ids); --+ int nids = -1, id; --+ for ( ; *ciphers != TLS_CIPHER_NONE; ++ciphers) { --+ switch (*ciphers) { --+ case TLS_CIPHER_RC4_SHA: --+ #ifdef MBEDTLS_TLS_RSA_WITH_RC4_128_SHA --+ id = MBEDTLS_TLS_RSA_WITH_RC4_128_SHA; --+ break; --+ #else --+ continue; /*(not supported in mbedtls 3.x; ignore)*/ --+ #endif --+ case TLS_CIPHER_AES128_SHA: --+ id = MBEDTLS_TLS_RSA_WITH_AES_128_CBC_SHA; --+ break; --+ case TLS_CIPHER_RSA_DHE_AES128_SHA: --+ id = MBEDTLS_TLS_DHE_RSA_WITH_AES_128_CBC_SHA; --+ break; --+ case TLS_CIPHER_ANON_DH_AES128_SHA: --+ continue; /*(not supported in mbedtls; ignore)*/ --+ case TLS_CIPHER_RSA_DHE_AES256_SHA: --+ id = MBEDTLS_TLS_DHE_RSA_WITH_AES_256_CBC_SHA; --+ break; --+ case TLS_CIPHER_AES256_SHA: --+ id = MBEDTLS_TLS_RSA_WITH_AES_256_CBC_SHA; --+ break; --+ default: --+ return -1; /* should not happen */ --+ } --+ if (++nids == idsz) --+ return -1; /* should not happen */ --+ ids[nids] = id; --+ } --+ if (nids < 0) --+ return 0; /* nothing to do */ --+ if (++nids == idsz) --+ return -1; /* should not happen */ --+ ids[nids] = 0; /* terminate list */ --+ ++nids; --+ --+ return tls_mbedtls_set_ciphersuites(conn->tls_conf, ids, nids) ? 0 : -1; --+} --+#endif --+ --+ --+int tls_get_version(void *ssl_ctx, struct tls_connection *conn, --+ char *buf, size_t buflen) --+{ --+ if (conn == NULL) --+ return -1; --+ os_strlcpy(buf, mbedtls_ssl_get_version(&conn->ssl), buflen); --+ return buf[0] != 'u' ? 0 : -1; /*(-1 if "unknown")*/ --+} --+ --+ --+#ifdef TLS_MBEDTLS_EAP_TEAP --+u16 tls_connection_get_cipher_suite(struct tls_connection *conn) --+{ --+ if (conn == NULL) --+ return 0; --+ return (u16)mbedtls_ssl_get_ciphersuite_id_from_ssl(&conn->ssl); --+} --+#endif --+ --+ --+int tls_get_cipher(void *tls_ctx, struct tls_connection *conn, --+ char *buf, size_t buflen) --+{ --+ if (conn == NULL) --+ return -1; --+ const int id = mbedtls_ssl_get_ciphersuite_id_from_ssl(&conn->ssl); --+ return tls_mbedtls_translate_ciphername(id, buf, buflen) ? 0 : -1; --+} --+ --+ --+#ifdef TLS_MBEDTLS_SESSION_TICKETS --+ --+int tls_connection_enable_workaround(void *tls_ctx, --+ struct tls_connection *conn) --+{ --+ /* (see comment in src/eap_peer/eap_fast.c:eap_fast_init()) */ --+ /* XXX: is there a relevant setting for this in mbed TLS? */ --+ /* (do we even care that much about older CBC ciphers?) */ --+ return 0; --+} --+ --+ --+int tls_connection_client_hello_ext(void *tls_ctx, struct tls_connection *conn, --+ int ext_type, const u8 *data, --+ size_t data_len) --+{ --+ /* (EAP-FAST and EAP-TEAP) */ --+ if (ext_type == MBEDTLS_TLS_EXT_SESSION_TICKET) /*(ext_type == 35)*/ --+ return tls_mbedtls_clienthello_session_ticket_prep(conn, data, --+ data_len); --+ --+ return -1; --+} --+ --+#endif /* TLS_MBEDTLS_SESSION_TICKETS */ --+ --+ --+int tls_connection_get_failed(void *tls_ctx, struct tls_connection *conn) --+{ --+ return conn ? conn->failed : -1; --+} --+ --+ --+int tls_connection_get_read_alerts(void *tls_ctx, struct tls_connection *conn) --+{ --+ return conn ? conn->read_alerts : -1; --+} --+ --+ --+int tls_connection_get_write_alerts(void *tls_ctx, --+ struct tls_connection *conn) --+{ --+ return conn ? conn->write_alerts : -1; --+} --+ --+ --+#ifdef TLS_MBEDTLS_SESSION_TICKETS --+int tls_connection_set_session_ticket_cb( --+ void *tls_ctx, struct tls_connection *conn, --+ tls_session_ticket_cb cb, void *ctx) --+{ --+ if (!(conn->tls_conf->flags & TLS_CONN_DISABLE_SESSION_TICKET)) { --+ /* (EAP-FAST and EAP-TEAP) */ --+ conn->session_ticket_cb = cb; --+ conn->session_ticket_cb_ctx = ctx; --+ return 0; --+ } --+ return -1; --+} --+#endif --+ --+ --+int tls_get_library_version(char *buf, size_t buf_len) --+{ --+ #ifndef MBEDTLS_VERSION_C --+ const char * const ver = "n/a"; --+ #else --+ char ver[9]; --+ mbedtls_version_get_string(ver); --+ #endif --+ return os_snprintf(buf, buf_len, --+ "mbed TLS build=" MBEDTLS_VERSION_STRING " run=%s", ver); --+} --+ --+ --+void tls_connection_set_success_data(struct tls_connection *conn, --+ struct wpabuf *data) --+{ --+ wpabuf_free(conn->success_data); --+ conn->success_data = data; --+} --+ --+ --+void tls_connection_set_success_data_resumed(struct tls_connection *conn) --+{ --+} --+ --+ --+const struct wpabuf * --+tls_connection_get_success_data(struct tls_connection *conn) --+{ --+ return conn->success_data; --+} --+ --+ --+void tls_connection_remove_session(struct tls_connection *conn) --+{ --+} --+ --+ --+#ifdef TLS_MBEDTLS_EAP_TEAP --+int tls_get_tls_unique(struct tls_connection *conn, u8 *buf, size_t max_len) --+{ --+ #if defined(MBEDTLS_SSL_RENEGOTIATION) /* XXX: renegotiation or resumption? */ --+ /* data from TLS handshake Finished message */ --+ size_t verify_len = conn->ssl.MBEDTLS_PRIVATE(verify_data_len); --+ char *verify_data = (conn->is_server ^ conn->resumed) --+ ? conn->ssl.MBEDTLS_PRIVATE(peer_verify_data) --+ : conn->ssl.MBEDTLS_PRIVATE(own_verify_data); --+ if (verify_len && verify_len <= max_len) { --+ os_memcpy(buf, verify_data, verify_len); --+ return (int)verify_len; --+ } --+ #endif --+ return -1; --+} --+#endif --+ --+ --+__attribute_noinline__ --+static void tls_mbedtls_set_peer_subject(struct tls_connection *conn, const mbedtls_x509_crt *crt) --+{ --+ if (conn->peer_subject) --+ return; --+ char buf[MBEDTLS_X509_MAX_DN_NAME_SIZE*2]; --+ int buflen = mbedtls_x509_dn_gets(buf, sizeof(buf), &crt->subject); --+ if (buflen >= 0 && (conn->peer_subject = os_malloc((size_t)buflen+1))) --+ os_memcpy(conn->peer_subject, buf, (size_t)buflen+1); --+} --+ --+ --+#ifdef TLS_MBEDTLS_EAP_TEAP --+const char * tls_connection_get_peer_subject(struct tls_connection *conn) --+{ --+ if (!conn) --+ return NULL; --+ if (!conn->peer_subject) { /*(if not set during cert verify)*/ --+ const mbedtls_x509_crt *peer_cert = --+ mbedtls_ssl_get_peer_cert(&conn->ssl); --+ if (peer_cert) --+ tls_mbedtls_set_peer_subject(conn, peer_cert); --+ } --+ return conn->peer_subject; --+} --+#endif --+ --+ --+#ifdef TLS_MBEDTLS_EAP_TEAP --+bool tls_connection_get_own_cert_used(struct tls_connection *conn) --+{ --+ /* XXX: availability of cert does not necessary mean that client --+ * received certificate request from server and then sent cert. --+ * ? step handshake in tls_connection_handshake() looking for --+ * MBEDTLS_SSL_CERTIFICATE_REQUEST ? */ --+ const struct tls_conf * const tls_conf = conn->tls_conf; --+ return (tls_conf->has_client_cert && tls_conf->has_private_key); --+} --+#endif --+ --+ --+#if defined(CONFIG_FIPS) --+#define TLS_MBEDTLS_CONFIG_FIPS --+#endif --+ --+#if defined(CONFIG_SHA256) --+#define TLS_MBEDTLS_TLS_PRF_SHA256 --+#endif --+ --+#if defined(CONFIG_SHA384) --+#define TLS_MBEDTLS_TLS_PRF_SHA384 --+#endif --+ --+ --+#ifndef TLS_MBEDTLS_CONFIG_FIPS --+#if defined(CONFIG_MODULE_TESTS) --+/* unused with CONFIG_TLS=mbedtls except in crypto_module_tests.c */ --+#if MBEDTLS_VERSION_NUMBER >= 0x02120000 /* mbedtls 2.18.0 */ \ --+ && MBEDTLS_VERSION_NUMBER < 0x03000000 /* mbedtls 3.0.0 */ --+/* sha1-tlsprf.c */ --+#include "sha1.h" --+int tls_prf_sha1_md5(const u8 *secret, size_t secret_len, const char *label, --+ const u8 *seed, size_t seed_len, u8 *out, size_t outlen) --+{ --+ return mbedtls_ssl_tls_prf(MBEDTLS_SSL_TLS_PRF_TLS1, --+ secret, secret_len, label, --+ seed, seed_len, out, outlen) ? -1 : 0; --+} --+#else --+#include "sha1-tlsprf.c" /* pull in hostap local implementation */ --+#endif --+#endif --+#endif --+ --+#ifdef TLS_MBEDTLS_TLS_PRF_SHA256 --+/* sha256-tlsprf.c */ --+#if MBEDTLS_VERSION_NUMBER >= 0x02120000 /* mbedtls 2.18.0 */ --+#include "sha256.h" --+int tls_prf_sha256(const u8 *secret, size_t secret_len, const char *label, --+ const u8 *seed, size_t seed_len, u8 *out, size_t outlen) --+{ --+ return mbedtls_ssl_tls_prf(MBEDTLS_SSL_TLS_PRF_SHA256, --+ secret, secret_len, label, --+ seed, seed_len, out, outlen) ? -1 : 0; --+} --+#else --+#include "sha256-tlsprf.c" /* pull in hostap local implementation */ --+#endif --+#endif --+ --+#ifdef TLS_MBEDTLS_TLS_PRF_SHA384 --+/* sha384-tlsprf.c */ --+#if MBEDTLS_VERSION_NUMBER >= 0x02120000 /* mbedtls 2.18.0 */ --+#include "sha384.h" --+int tls_prf_sha384(const u8 *secret, size_t secret_len, const char *label, --+ const u8 *seed, size_t seed_len, u8 *out, size_t outlen) --+{ --+ return mbedtls_ssl_tls_prf(MBEDTLS_SSL_TLS_PRF_SHA384, --+ secret, secret_len, label, --+ seed, seed_len, out, outlen) ? -1 : 0; --+} --+#else --+#include "sha384-tlsprf.c" /* pull in hostap local implementation */ --+#endif --+#endif --+ --+ --+#if MBEDTLS_VERSION_NUMBER < 0x03020000 /* mbedtls 3.2.0 */ --+#define mbedtls_x509_crt_has_ext_type(crt, ext_type) \ --+ ((crt)->MBEDTLS_PRIVATE(ext_types) & (ext_type)) --+#endif --+ --+struct mlist { const char *p; size_t n; }; --+ --+ --+static int --+tls_mbedtls_match_altsubject(mbedtls_x509_crt *crt, const char *match) --+{ --+ /* RFE: this could be pre-parsed into structured data at config time */ --+ struct mlist list[256]; /*(much larger than expected)*/ --+ int nlist = 0; --+ if ( os_strncmp(match, "EMAIL:", 6) != 0 --+ && os_strncmp(match, "DNS:", 4) != 0 --+ && os_strncmp(match, "URI:", 4) != 0 ) { --+ wpa_printf(MSG_INFO, "MTLS: Invalid altSubjectName match '%s'", match); --+ return 0; --+ } --+ for (const char *s = match, *tok; *s; s = tok ? tok+1 : "") { --+ do { } while ((tok = os_strchr(s, ';')) --+ && os_strncmp(tok+1, "EMAIL:", 6) != 0 --+ && os_strncmp(tok+1, "DNS:", 4) != 0 --+ && os_strncmp(tok+1, "URI:", 4) != 0); --+ list[nlist].p = s; --+ list[nlist].n = tok ? (size_t)(tok - s) : os_strlen(s); --+ if (list[nlist].n && ++nlist == sizeof(list)/sizeof(*list)) { --+ wpa_printf(MSG_INFO, "MTLS: excessive altSubjectName match '%s'", --+ match); --+ break; /* truncate huge list and continue */ --+ } --+ } --+ --+ if (!mbedtls_x509_crt_has_ext_type(crt, MBEDTLS_X509_EXT_SUBJECT_ALT_NAME)) --+ return 0; --+ --+ const mbedtls_x509_sequence *cur = &crt->subject_alt_names; --+ for (; cur != NULL; cur = cur->next) { --+ const unsigned char san_type = (unsigned char)cur->buf.tag --+ & MBEDTLS_ASN1_TAG_VALUE_MASK; --+ char t; --+ size_t step = 4; --+ switch (san_type) { /* "EMAIL:" or "DNS:" or "URI:" */ --+ case MBEDTLS_X509_SAN_RFC822_NAME: step = 6; t = 'E'; break; --+ case MBEDTLS_X509_SAN_DNS_NAME: t = 'D'; break; --+ case MBEDTLS_X509_SAN_UNIFORM_RESOURCE_IDENTIFIER: t = 'U'; break; --+ default: continue; --+ } --+ --+ for (int i = 0; i < nlist; ++i) { --+ /* step over "EMAIL:" or "DNS:" or "URI:" in list[i].p */ --+ /* Note: v is not '\0'-terminated, but is a known length vlen, --+ * so okay to pass to os_strncasecmp() even though not z-string */ --+ if (cur->buf.len == list[i].n - step && t == *list[i].p --+ && 0 == os_strncasecmp((char *)cur->buf.p, --+ list[i].p+step, cur->buf.len)) { --+ return 1; /* match */ --+ } --+ } --+ } --+ return 0; /* no match */ --+} --+ --+ --+static int --+tls_mbedtls_match_suffix(const char *v, size_t vlen, --+ const struct mlist *list, int nlist, int full) --+{ --+ /* Note: v is not '\0'-terminated, but is a known length vlen, --+ * so okay to pass to os_strncasecmp() even though not z-string */ --+ for (int i = 0; i < nlist; ++i) { --+ size_t n = list[i].n; --+ if ((n == vlen || (n < vlen && v[vlen-n-1] == '.' && !full)) --+ && 0 == os_strncasecmp(v+vlen-n, list[i].p, n)) --+ return 1; /* match */ --+ } --+ return 0; /* no match */ --+} --+ --+ --+static int --+tls_mbedtls_match_suffixes(mbedtls_x509_crt *crt, const char *match, int full) --+{ --+ /* RFE: this could be pre-parsed into structured data at config time */ --+ struct mlist list[256]; /*(much larger than expected)*/ --+ int nlist = 0; --+ for (const char *s = match, *tok; *s; s = tok ? tok+1 : "") { --+ tok = os_strchr(s, ';'); --+ list[nlist].p = s; --+ list[nlist].n = tok ? (size_t)(tok - s) : os_strlen(s); --+ if (list[nlist].n && ++nlist == sizeof(list)/sizeof(*list)) { --+ wpa_printf(MSG_INFO, "MTLS: excessive suffix match '%s'", match); --+ break; /* truncate huge list and continue */ --+ } --+ } --+ --+ /* check subjectAltNames */ --+ if (mbedtls_x509_crt_has_ext_type(crt, MBEDTLS_X509_EXT_SUBJECT_ALT_NAME)) { --+ const mbedtls_x509_sequence *cur = &crt->subject_alt_names; --+ for (; cur != NULL; cur = cur->next) { --+ const unsigned char san_type = (unsigned char)cur->buf.tag --+ & MBEDTLS_ASN1_TAG_VALUE_MASK; --+ if (san_type == MBEDTLS_X509_SAN_DNS_NAME --+ && tls_mbedtls_match_suffix((char *)cur->buf.p, --+ cur->buf.len, --+ list, nlist, full)) { --+ return 1; /* match */ --+ } --+ } --+ } --+ --+ /* check subject CN */ --+ const mbedtls_x509_name *name = &crt->subject; --+ for (; name != NULL; name = name->next) { --+ if (name->oid.p && MBEDTLS_OID_CMP(MBEDTLS_OID_AT_CN, &name->oid) == 0) --+ break; --+ } --+ if (name && tls_mbedtls_match_suffix((char *)name->val.p, name->val.len, --+ list, nlist, full)) { --+ return 1; /* match */ --+ } --+ --+ return 0; /* no match */ --+} --+ --+ --+static int --+tls_mbedtls_match_dn_field(mbedtls_x509_crt *crt, const char *match) --+{ --+ /* RFE: this could be pre-parsed into structured data at config time */ --+ struct mlistoid { const char *p; size_t n; --+ const char *oid; size_t olen; --+ int prefix; }; --+ struct mlistoid list[32]; /*(much larger than expected)*/ --+ int nlist = 0; --+ for (const char *s = match, *tok, *e; *s; s = tok ? tok+1 : "") { --+ tok = os_strchr(s, '/'); --+ list[nlist].oid = NULL; --+ list[nlist].olen = 0; --+ list[nlist].n = tok ? (size_t)(tok - s) : os_strlen(s); --+ e = memchr(s, '=', list[nlist].n); --+ if (e == NULL) { --+ if (list[nlist].n == 0) --+ continue; /* skip consecutive, repeated '/' */ --+ if (list[nlist].n == 1 && *s == '*') { --+ /* special-case "*" to match any OID and value */ --+ s = e = "=*"; --+ list[nlist].n = 2; --+ list[nlist].oid = ""; --+ } --+ else { --+ wpa_printf(MSG_INFO, --+ "MTLS: invalid check_cert_subject '%s' missing '='", --+ match); --+ return 0; --+ } --+ } --+ switch (e - s) { --+ case 1: --+ if (*s == 'C') { --+ list[nlist].oid = MBEDTLS_OID_AT_COUNTRY; --+ list[nlist].olen = sizeof(MBEDTLS_OID_AT_COUNTRY)-1; --+ } --+ else if (*s == 'L') { --+ list[nlist].oid = MBEDTLS_OID_AT_LOCALITY; --+ list[nlist].olen = sizeof(MBEDTLS_OID_AT_LOCALITY)-1; --+ } --+ else if (*s == 'O') { --+ list[nlist].oid = MBEDTLS_OID_AT_ORGANIZATION; --+ list[nlist].olen = sizeof(MBEDTLS_OID_AT_ORGANIZATION)-1; --+ } --+ break; --+ case 2: --+ if (s[0] == 'C' && s[1] == 'N') { --+ list[nlist].oid = MBEDTLS_OID_AT_CN; --+ list[nlist].olen = sizeof(MBEDTLS_OID_AT_CN)-1; --+ } --+ else if (s[0] == 'S' && s[1] == 'T') { --+ list[nlist].oid = MBEDTLS_OID_AT_STATE; --+ list[nlist].olen = sizeof(MBEDTLS_OID_AT_STATE)-1; --+ } --+ else if (s[0] == 'O' && s[1] == 'U') { --+ list[nlist].oid = MBEDTLS_OID_AT_ORG_UNIT; --+ list[nlist].olen = sizeof(MBEDTLS_OID_AT_ORG_UNIT)-1; --+ } --+ break; --+ case 12: --+ if (os_memcmp(s, "emailAddress", 12) == 0) { --+ list[nlist].oid = MBEDTLS_OID_PKCS9_EMAIL; --+ list[nlist].olen = sizeof(MBEDTLS_OID_PKCS9_EMAIL)-1; --+ } --+ break; --+ default: --+ break; --+ } --+ if (list[nlist].oid == NULL) { --+ wpa_printf(MSG_INFO, --+ "MTLS: Unknown field in check_cert_subject '%s'", --+ match); --+ return 0; --+ } --+ list[nlist].n -= (size_t)(++e - s); --+ list[nlist].p = e; --+ if (list[nlist].n && e[list[nlist].n-1] == '*') { --+ --list[nlist].n; --+ list[nlist].prefix = 1; --+ } --+ /*(could easily add support for suffix matches if value begins with '*', --+ * but suffix match is not currently supported by other TLS modules)*/ --+ --+ if (list[nlist].n && ++nlist == sizeof(list)/sizeof(*list)) { --+ wpa_printf(MSG_INFO, --+ "MTLS: excessive check_cert_subject match '%s'", --+ match); --+ break; /* truncate huge list and continue */ --+ } --+ } --+ --+ /* each component in match string must match cert Subject in order listed --+ * The behavior below preserves ordering but is slightly different than --+ * the grossly inefficient contortions implemented in tls_openssl.c */ --+ const mbedtls_x509_name *name = &crt->subject; --+ for (int i = 0; i < nlist; ++i) { --+ int found = 0; --+ for (; name != NULL && !found; name = name->next) { --+ if (!name->oid.p) --+ continue; --+ /* special-case "*" to match any OID and value */ --+ if (list[i].olen == 0) { --+ found = 1; --+ continue; --+ } --+ /* perform equalent of !MBEDTLS_OID_CMP() with oid ptr and len */ --+ if (list[i].olen != name->oid.len --+ || os_memcmp(list[i].oid, name->oid.p, name->oid.len) != 0) --+ continue; --+ /* Note: v is not '\0'-terminated, but is a known length vlen, --+ * so okay to pass to os_strncasecmp() even though not z-string */ --+ if ((list[i].prefix --+ ? list[i].n <= name->val.len /* prefix match */ --+ : list[i].n == name->val.len) /* full match */ --+ && 0 == os_strncasecmp((char *)name->val.p, --+ list[i].p, list[i].n)) { --+ found = 1; --+ continue; --+ } --+ } --+ if (!found) --+ return 0; /* no match */ --+ } --+ return 1; /* match */ --+} --+ --+ --+__attribute_cold__ --+static void --+tls_mbedtls_verify_fail_event (mbedtls_x509_crt *crt, int depth, --+ const char *errmsg, enum tls_fail_reason reason) --+{ --+ struct tls_config *init_conf = &tls_ctx_global.init_conf; --+ if (init_conf->event_cb == NULL) --+ return; --+ --+ struct wpabuf *certbuf = wpabuf_alloc_copy(crt->raw.p, crt->raw.len); --+ char subject[MBEDTLS_X509_MAX_DN_NAME_SIZE*2]; --+ if (mbedtls_x509_dn_gets(subject, sizeof(subject), &crt->subject) < 0) --+ subject[0] = '\0'; --+ union tls_event_data ev; --+ os_memset(&ev, 0, sizeof(ev)); --+ ev.cert_fail.reason = reason; --+ ev.cert_fail.depth = depth; --+ ev.cert_fail.subject = subject; --+ ev.cert_fail.reason_txt = errmsg; --+ ev.cert_fail.cert = certbuf; --+ --+ init_conf->event_cb(init_conf->cb_ctx, TLS_CERT_CHAIN_FAILURE, &ev); --+ --+ wpabuf_free(certbuf); --+} --+ --+ --+__attribute_noinline__ --+static void --+tls_mbedtls_verify_cert_event (struct tls_connection *conn, --+ mbedtls_x509_crt *crt, int depth) --+{ --+ struct tls_config *init_conf = &tls_ctx_global.init_conf; --+ if (init_conf->event_cb == NULL) --+ return; --+ --+ struct wpabuf *certbuf = NULL; --+ union tls_event_data ev; --+ os_memset(&ev, 0, sizeof(ev)); --+ --+ #ifdef MBEDTLS_SHA256_C --+ u8 hash[SHA256_DIGEST_LENGTH]; --+ const u8 *addr[] = { (u8 *)crt->raw.p }; --+ if (sha256_vector(1, addr, &crt->raw.len, hash) == 0) { --+ ev.peer_cert.hash = hash; --+ ev.peer_cert.hash_len = sizeof(hash); --+ } --+ #endif --+ ev.peer_cert.depth = depth; --+ char subject[MBEDTLS_X509_MAX_DN_NAME_SIZE*2]; --+ if (depth == 0) --+ ev.peer_cert.subject = conn->peer_subject; --+ if (ev.peer_cert.subject == NULL) { --+ ev.peer_cert.subject = subject; --+ if (mbedtls_x509_dn_gets(subject, sizeof(subject), &crt->subject) < 0) --+ subject[0] = '\0'; --+ } --+ --+ char serial_num[128+1]; --+ ev.peer_cert.serial_num = --+ tls_mbedtls_peer_serial_num(crt, serial_num, sizeof(serial_num)); --+ --+ const mbedtls_x509_sequence *cur; --+ --+ cur = NULL; --+ if (mbedtls_x509_crt_has_ext_type(crt, MBEDTLS_X509_EXT_SUBJECT_ALT_NAME)) --+ cur = &crt->subject_alt_names; --+ for (; cur != NULL; cur = cur->next) { --+ const unsigned char san_type = (unsigned char)cur->buf.tag --+ & MBEDTLS_ASN1_TAG_VALUE_MASK; --+ size_t prelen = 4; --+ const char *pre; --+ switch (san_type) { --+ case MBEDTLS_X509_SAN_RFC822_NAME: prelen = 6; pre = "EMAIL:";break; --+ case MBEDTLS_X509_SAN_DNS_NAME: pre = "DNS:"; break; --+ case MBEDTLS_X509_SAN_UNIFORM_RESOURCE_IDENTIFIER: pre = "URI:"; break; --+ default: continue; --+ } --+ --+ char *pos = os_malloc(prelen + cur->buf.len + 1); --+ if (pos == NULL) --+ break; --+ ev.peer_cert.altsubject[ev.peer_cert.num_altsubject] = pos; --+ os_memcpy(pos, pre, prelen); --+ /* data should be properly backslash-escaped if needed, --+ * so code below does not re-escape, but does replace CTLs */ --+ /*os_memcpy(pos+prelen, cur->buf.p, cur->buf.len);*/ --+ /*pos[prelen+cur->buf.len] = '\0';*/ --+ pos += prelen; --+ for (size_t i = 0; i < cur->buf.len; ++i) { --+ unsigned char c = cur->buf.p[i]; --+ *pos++ = (c >= 32 && c != 127) ? c : '?'; --+ } --+ *pos = '\0'; --+ --+ if (++ev.peer_cert.num_altsubject == TLS_MAX_ALT_SUBJECT) --+ break; --+ } --+ --+ cur = NULL; --+ if (mbedtls_x509_crt_has_ext_type(crt, MBEDTLS_X509_EXT_CERTIFICATE_POLICIES)) --+ cur = &crt->certificate_policies; --+ for (; cur != NULL; cur = cur->next) { --+ if (cur->buf.len != 11) /* len of OID_TOD_STRICT or OID_TOD_TOFU */ --+ continue; --+ /* TOD-STRICT "1.3.6.1.4.1.40808.1.3.1" */ --+ /* TOD-TOFU "1.3.6.1.4.1.40808.1.3.2" */ --+ #define OID_TOD_STRICT "\x2b\x06\x01\x04\x01\x82\xbe\x68\x01\x03\x01" --+ #define OID_TOD_TOFU "\x2b\x06\x01\x04\x01\x82\xbe\x68\x01\x03\x02" --+ if (os_memcmp(cur->buf.p, --+ OID_TOD_STRICT, sizeof(OID_TOD_STRICT)-1) == 0) { --+ ev.peer_cert.tod = 1; /* TOD-STRICT */ --+ break; --+ } --+ if (os_memcmp(cur->buf.p, --+ OID_TOD_TOFU, sizeof(OID_TOD_TOFU)-1) == 0) { --+ ev.peer_cert.tod = 2; /* TOD-TOFU */ --+ break; --+ } --+ } --+ --+ struct tls_conf *tls_conf = conn->tls_conf; --+ if (tls_conf->ca_cert_probe || (tls_conf->flags & TLS_CONN_EXT_CERT_CHECK) --+ || init_conf->cert_in_cb) { --+ certbuf = wpabuf_alloc_copy(crt->raw.p, crt->raw.len); --+ ev.peer_cert.cert = certbuf; --+ } --+ --+ init_conf->event_cb(init_conf->cb_ctx, TLS_PEER_CERTIFICATE, &ev); --+ --+ wpabuf_free(certbuf); --+ char **altsubject; --+ *(const char ***)&altsubject = ev.peer_cert.altsubject; --+ for (size_t i = 0; i < ev.peer_cert.num_altsubject; ++i) --+ os_free(altsubject[i]); --+} --+ --+ --+static int --+tls_mbedtls_verify_cb (void *arg, mbedtls_x509_crt *crt, int depth, uint32_t *flags) --+{ --+ /* XXX: N.B. verify code not carefully tested besides hwsim tests --+ * --+ * RFE: mbedtls_x509_crt_verify_info() and enhance log trace messages --+ * RFE: review and add support for additional TLS_CONN_* flags --+ * not handling OCSP (not available in mbedtls) --+ * ... */ --+ --+ struct tls_connection *conn = (struct tls_connection *)arg; --+ struct tls_conf *tls_conf = conn->tls_conf; --+ uint32_t flags_in = *flags; --+ --+ if (depth > 8) { /*(depth 8 picked as arbitrary limit)*/ --+ emsg(MSG_WARNING, "client cert chain too long"); --+ *flags |= MBEDTLS_X509_BADCERT_OTHER; /* cert chain too long */ --+ tls_mbedtls_verify_fail_event(crt, depth, --+ "client cert chain too long", --+ TLS_FAIL_BAD_CERTIFICATE); --+ } --+ else if (tls_conf->verify_depth0_only) { --+ if (depth > 0) --+ *flags = 0; --+ else { --+ #ifdef MBEDTLS_SHA256_C --+ u8 hash[SHA256_DIGEST_LENGTH]; --+ const u8 *addr[] = { (u8 *)crt->raw.p }; --+ if (sha256_vector(1, addr, &crt->raw.len, hash) < 0 --+ || os_memcmp(tls_conf->ca_cert_hash, hash, sizeof(hash)) != 0) { --+ *flags |= MBEDTLS_X509_BADCERT_NOT_TRUSTED; --+ tls_mbedtls_verify_fail_event(crt, depth, --+ "cert hash mismatch", --+ TLS_FAIL_UNTRUSTED); --+ } --+ else /* hash matches; ignore other issues *except* if revoked)*/ --+ *flags &= MBEDTLS_X509_BADCERT_REVOKED; --+ #endif --+ } --+ } --+ else if (depth == 0) { --+ if (!conn->peer_subject) --+ tls_mbedtls_set_peer_subject(conn, crt); --+ /*(use same labels to tls_mbedtls_verify_fail_event() as used in --+ * other TLS modules so that hwsim tests find exact string match)*/ --+ if (!conn->peer_subject) { /* error copying subject string */ --+ *flags |= MBEDTLS_X509_BADCERT_OTHER; --+ tls_mbedtls_verify_fail_event(crt, depth, --+ "internal error", --+ TLS_FAIL_UNSPECIFIED); --+ } --+ /*(use os_strstr() for subject match as is done in tls_mbedtls.c --+ * to follow the same behavior, even though a suffix match would --+ * make more sense. Also, note that strstr match does not --+ * normalize whitespace (between components) for comparison)*/ --+ else if (tls_conf->subject_match --+ && os_strstr(conn->peer_subject, --+ tls_conf->subject_match) == NULL) { --+ wpa_printf(MSG_WARNING, --+ "MTLS: Subject '%s' did not match with '%s'", --+ conn->peer_subject, tls_conf->subject_match); --+ *flags |= MBEDTLS_X509_BADCERT_CN_MISMATCH; --+ tls_mbedtls_verify_fail_event(crt, depth, --+ "Subject mismatch", --+ TLS_FAIL_SUBJECT_MISMATCH); --+ } --+ if (tls_conf->altsubject_match --+ && !tls_mbedtls_match_altsubject(crt, tls_conf->altsubject_match)) { --+ wpa_printf(MSG_WARNING, --+ "MTLS: altSubjectName match '%s' not found", --+ tls_conf->altsubject_match); --+ *flags |= MBEDTLS_X509_BADCERT_CN_MISMATCH; --+ tls_mbedtls_verify_fail_event(crt, depth, --+ "AltSubject mismatch", --+ TLS_FAIL_ALTSUBJECT_MISMATCH); --+ } --+ if (tls_conf->suffix_match --+ && !tls_mbedtls_match_suffixes(crt, tls_conf->suffix_match, 0)) { --+ wpa_printf(MSG_WARNING, --+ "MTLS: Domain suffix match '%s' not found", --+ tls_conf->suffix_match); --+ *flags |= MBEDTLS_X509_BADCERT_CN_MISMATCH; --+ tls_mbedtls_verify_fail_event(crt, depth, --+ "Domain suffix mismatch", --+ TLS_FAIL_DOMAIN_SUFFIX_MISMATCH); --+ } --+ if (tls_conf->domain_match --+ && !tls_mbedtls_match_suffixes(crt, tls_conf->domain_match, 1)) { --+ wpa_printf(MSG_WARNING, --+ "MTLS: Domain match '%s' not found", --+ tls_conf->domain_match); --+ *flags |= MBEDTLS_X509_BADCERT_CN_MISMATCH; --+ tls_mbedtls_verify_fail_event(crt, depth, --+ "Domain mismatch", --+ TLS_FAIL_DOMAIN_MISMATCH); --+ } --+ if (tls_conf->check_cert_subject --+ && !tls_mbedtls_match_dn_field(crt, tls_conf->check_cert_subject)) { --+ *flags |= MBEDTLS_X509_BADCERT_CN_MISMATCH; --+ tls_mbedtls_verify_fail_event(crt, depth, --+ "Distinguished Name", --+ TLS_FAIL_DN_MISMATCH); --+ } --+ if (tls_conf->flags & TLS_CONN_SUITEB) { --+ /* check RSA modulus size (public key bitlen) */ --+ const mbedtls_pk_type_t pk_alg = mbedtls_pk_get_type(&crt->pk); --+ if ((pk_alg == MBEDTLS_PK_RSA || pk_alg == MBEDTLS_PK_RSASSA_PSS) --+ && mbedtls_pk_get_bitlen(&crt->pk) < 3072) { --+ /* hwsim suite_b RSA tests expect 3072 --+ * suite_b_192_rsa_ecdhe_radius_rsa2048_client --+ * suite_b_192_rsa_dhe_radius_rsa2048_client */ --+ *flags |= MBEDTLS_X509_BADCERT_BAD_KEY; --+ tls_mbedtls_verify_fail_event(crt, depth, --+ "Insufficient RSA modulus size", --+ TLS_FAIL_INSUFFICIENT_KEY_LEN); --+ } --+ } --+ if (tls_conf->check_crl && tls_conf->crl == NULL) { --+ /* see tests/hwsim test_ap_eap.py ap_wpa2_eap_tls_check_crl */ --+ emsg(MSG_WARNING, "check_crl set but no CRL loaded; reject all?"); --+ *flags |= MBEDTLS_X509_BADCERT_OTHER; --+ tls_mbedtls_verify_fail_event(crt, depth, --+ "check_crl set but no CRL loaded; " --+ "reject all?", --+ TLS_FAIL_BAD_CERTIFICATE); --+ } --+ } --+ else { --+ if (tls_conf->check_crl != 2) /* 2 == verify CRLs for all certs */ --+ *flags &= ~MBEDTLS_X509_BADCERT_REVOKED; --+ } --+ --+ if (!tls_conf->check_crl_strict) { --+ *flags &= ~MBEDTLS_X509_BADCRL_EXPIRED; --+ *flags &= ~MBEDTLS_X509_BADCRL_FUTURE; --+ } --+ --+ if (tls_conf->flags & TLS_CONN_DISABLE_TIME_CHECKS) { --+ *flags &= ~MBEDTLS_X509_BADCERT_EXPIRED; --+ *flags &= ~MBEDTLS_X509_BADCERT_FUTURE; --+ } --+ --+ tls_mbedtls_verify_cert_event(conn, crt, depth); --+ --+ if (*flags) { --+ if (*flags & (MBEDTLS_X509_BADCERT_NOT_TRUSTED --+ |MBEDTLS_X509_BADCERT_CN_MISMATCH --+ |MBEDTLS_X509_BADCERT_REVOKED)) { --+ emsg(MSG_WARNING, "client cert not trusted"); --+ } --+ /* report event if flags set but no additional flags set above */ --+ /* (could translate flags to more detailed TLS_FAIL_* if needed) */ --+ if (!(*flags & ~flags_in)) { --+ enum tls_fail_reason reason = TLS_FAIL_UNSPECIFIED; --+ const char *errmsg = "cert verify fail unspecified"; --+ if (*flags & MBEDTLS_X509_BADCERT_NOT_TRUSTED) { --+ reason = TLS_FAIL_UNTRUSTED; --+ errmsg = "certificate not trusted"; --+ } --+ if (*flags & MBEDTLS_X509_BADCERT_REVOKED) { --+ reason = TLS_FAIL_REVOKED; --+ errmsg = "certificate has been revoked"; --+ } --+ if (*flags & MBEDTLS_X509_BADCERT_FUTURE) { --+ reason = TLS_FAIL_NOT_YET_VALID; --+ errmsg = "certificate not yet valid"; --+ } --+ if (*flags & MBEDTLS_X509_BADCERT_EXPIRED) { --+ reason = TLS_FAIL_EXPIRED; --+ errmsg = "certificate has expired"; --+ } --+ if (*flags & MBEDTLS_X509_BADCERT_BAD_MD) { --+ reason = TLS_FAIL_BAD_CERTIFICATE; --+ errmsg = "certificate uses insecure algorithm"; --+ } --+ tls_mbedtls_verify_fail_event(crt, depth, errmsg, reason); --+ } --+ #if 0 --+ /* ??? send (again) cert events for all certs in chain ??? --+ * (should already have been called for greater depths) */ --+ /* tls_openssl.c:tls_verify_cb() sends cert events for all certs --+ * in chain if certificate validation fails, but sends all events --+ * with depth set to 0 (might be a bug) */ --+ if (depth > 0) { --+ int pdepth = depth + 1; --+ for (mbedtls_x509_crt *pcrt; (pcrt = crt->next); ++pdepth) { --+ tls_mbedtls_verify_cert_event(conn, pcrt, pdepth); --+ } --+ } --+ #endif --+ /*(do not preserve subject if verification failed but was optional)*/ --+ if (depth == 0 && conn->peer_subject) { --+ os_free(conn->peer_subject); --+ conn->peer_subject = NULL; --+ } --+ } --+ else if (depth == 0) { --+ struct tls_config *init_conf = &tls_ctx_global.init_conf; --+ if (tls_conf->ca_cert_probe) { --+ /* reject server certificate on probe-only run */ --+ *flags |= MBEDTLS_X509_BADCERT_OTHER; --+ tls_mbedtls_verify_fail_event(crt, depth, --+ "server chain probe", --+ TLS_FAIL_SERVER_CHAIN_PROBE); --+ } --+ else if (init_conf->event_cb) { --+ /* ??? send event as soon as depth == 0 is verified ??? --+ * What about rest of chain? --+ * Follows tls_mbedtls.c behavior: */ --+ init_conf->event_cb(init_conf->cb_ctx, --+ TLS_CERT_CHAIN_SUCCESS, NULL); --+ } --+ } --+ --+ return 0; --+} ----- /dev/null --+++ b/tests/build/build-wpa_supplicant-mbedtls.config --@@ -0,0 +1,24 @@ --+CONFIG_TLS=mbedtls --+ --+CONFIG_WPS=y --+CONFIG_EAP_TLS=y --+CONFIG_EAP_MSCHAPV2=y --+ --+CONFIG_EAP_PSK=y --+CONFIG_EAP_GPSK=y --+CONFIG_EAP_AKA=y --+CONFIG_EAP_SIM=y --+CONFIG_EAP_SAKE=y --+CONFIG_EAP_PAX=y --+CONFIG_EAP_FAST=y --+CONFIG_EAP_IKEV2=y --+ --+CONFIG_SAE=y --+CONFIG_FILS=y --+CONFIG_FILS_SK_PFS=y --+CONFIG_OWE=y --+CONFIG_DPP=y --+CONFIG_SUITEB=y --+CONFIG_SUITEB192=y --+ --+CFLAGS += -Werror ----- a/tests/hwsim/example-hostapd.config --+++ b/tests/hwsim/example-hostapd.config --@@ -4,6 +4,7 @@ CONFIG_DRIVER_NONE=y -- CONFIG_DRIVER_NL80211=y -- CONFIG_RSN_PREAUTH=y -- --+#CONFIG_TLS=mbedtls -- #CONFIG_TLS=internal -- #CONFIG_INTERNAL_LIBTOMMATH=y -- #CONFIG_INTERNAL_LIBTOMMATH_FAST=y --@@ -39,6 +40,9 @@ endif -- ifeq ($(CONFIG_TLS), wolfssl) -- CONFIG_EAP_PWD=y -- endif --+ifeq ($(CONFIG_TLS), mbedtls) --+CONFIG_EAP_PWD=y --+endif -- CONFIG_EAP_EKE=y -- CONFIG_PKCS12=y -- CONFIG_RADIUS_SERVER=y ----- a/tests/hwsim/example-wpa_supplicant.config --+++ b/tests/hwsim/example-wpa_supplicant.config --@@ -2,6 +2,7 @@ -- -- CONFIG_TLS=openssl -- #CONFIG_TLS=wolfssl --+#CONFIG_TLS=mbedtls -- #CONFIG_TLS=internal -- #CONFIG_INTERNAL_LIBTOMMATH=y -- #CONFIG_INTERNAL_LIBTOMMATH_FAST=y --@@ -41,6 +42,9 @@ endif -- ifeq ($(CONFIG_TLS), wolfssl) -- CONFIG_EAP_PWD=y -- endif --+ifeq ($(CONFIG_TLS), mbedtls) --+CONFIG_EAP_PWD=y --+endif -- -- CONFIG_USIM_SIMULATOR=y -- CONFIG_SIM_SIMULATOR=y ----- a/wpa_supplicant/Makefile --+++ b/wpa_supplicant/Makefile --@@ -1163,6 +1163,29 @@ endif -- CFLAGS += -DTLS_DEFAULT_CIPHERS=\"$(CONFIG_TLS_DEFAULT_CIPHERS)\" -- endif -- --+ifeq ($(CONFIG_TLS), mbedtls) --+ifndef CONFIG_CRYPTO --+CONFIG_CRYPTO=mbedtls --+endif --+ifdef TLS_FUNCS --+OBJS += ../src/crypto/tls_mbedtls.o --+LIBS += -lmbedtls -lmbedx509 --+endif --+OBJS += ../src/crypto/crypto_$(CONFIG_CRYPTO).o --+OBJS_p += ../src/crypto/crypto_$(CONFIG_CRYPTO).o --+OBJS_priv += ../src/crypto/crypto_$(CONFIG_CRYPTO).o --+ifdef NEED_FIPS186_2_PRF --+OBJS += ../src/crypto/fips_prf_internal.o --+SHA1OBJS += ../src/crypto/sha1-internal.o --+endif --+ifeq ($(CONFIG_CRYPTO), mbedtls) --+LIBS += -lmbedcrypto --+LIBS_p += -lmbedcrypto --+# XXX: create a config option? --+CFLAGS += -DCRYPTO_RSA_OAEP_SHA256 --+endif --+endif --+ -- ifeq ($(CONFIG_TLS), gnutls) -- ifndef CONFIG_CRYPTO -- # default to libgcrypt --@@ -1355,9 +1378,11 @@ endif -- -- ifneq ($(CONFIG_TLS), openssl) -- ifneq ($(CONFIG_TLS), wolfssl) --+ifneq ($(CONFIG_TLS), mbedtls) -- NEED_INTERNAL_AES_WRAP=y -- endif -- endif --+endif -- ifdef CONFIG_OPENSSL_INTERNAL_AES_WRAP -- # Seems to be needed at least with BoringSSL -- NEED_INTERNAL_AES_WRAP=y --@@ -1371,9 +1396,11 @@ endif -- -- ifdef NEED_INTERNAL_AES_WRAP -- ifneq ($(CONFIG_TLS), linux) --+ifneq ($(CONFIG_TLS), mbedtls) -- AESOBJS += ../src/crypto/aes-unwrap.o -- endif -- endif --+endif -- ifdef NEED_AES_EAX -- AESOBJS += ../src/crypto/aes-eax.o -- NEED_AES_CTR=y --@@ -1383,35 +1410,45 @@ AESOBJS += ../src/crypto/aes-siv.o -- NEED_AES_CTR=y -- endif -- ifdef NEED_AES_CTR --+ifneq ($(CONFIG_TLS), mbedtls) -- AESOBJS += ../src/crypto/aes-ctr.o -- endif --+endif -- ifdef NEED_AES_ENCBLOCK --+ifneq ($(CONFIG_TLS), mbedtls) -- AESOBJS += ../src/crypto/aes-encblock.o -- endif --+endif -- NEED_AES_ENC=y -- ifneq ($(CONFIG_TLS), openssl) -- ifneq ($(CONFIG_TLS), linux) -- ifneq ($(CONFIG_TLS), wolfssl) --+ifneq ($(CONFIG_TLS), mbedtls) -- AESOBJS += ../src/crypto/aes-omac1.o -- endif -- endif -- endif --+endif -- ifdef NEED_AES_WRAP -- NEED_AES_ENC=y -- ifdef NEED_INTERNAL_AES_WRAP --+ifneq ($(CONFIG_TLS), mbedtls) -- AESOBJS += ../src/crypto/aes-wrap.o -- endif -- endif --+endif -- ifdef NEED_AES_CBC -- NEED_AES_ENC=y -- ifneq ($(CONFIG_TLS), openssl) -- ifneq ($(CONFIG_TLS), linux) -- ifneq ($(CONFIG_TLS), wolfssl) --+ifneq ($(CONFIG_TLS), mbedtls) -- AESOBJS += ../src/crypto/aes-cbc.o -- endif -- endif -- endif -- endif --+endif -- ifdef NEED_AES_ENC -- ifdef CONFIG_INTERNAL_AES -- AESOBJS += ../src/crypto/aes-internal-enc.o --@@ -1426,12 +1463,16 @@ ifneq ($(CONFIG_TLS), openssl) -- ifneq ($(CONFIG_TLS), linux) -- ifneq ($(CONFIG_TLS), gnutls) -- ifneq ($(CONFIG_TLS), wolfssl) --+ifneq ($(CONFIG_TLS), mbedtls) -- SHA1OBJS += ../src/crypto/sha1.o -- endif -- endif -- endif -- endif --+endif --+ifneq ($(CONFIG_TLS), mbedtls) -- SHA1OBJS += ../src/crypto/sha1-prf.o --+endif -- ifdef CONFIG_INTERNAL_SHA1 -- SHA1OBJS += ../src/crypto/sha1-internal.o -- ifdef NEED_FIPS186_2_PRF --@@ -1443,29 +1484,37 @@ CFLAGS += -DCONFIG_NO_PBKDF2 -- else -- ifneq ($(CONFIG_TLS), openssl) -- ifneq ($(CONFIG_TLS), wolfssl) --+ifneq ($(CONFIG_TLS), mbedtls) -- SHA1OBJS += ../src/crypto/sha1-pbkdf2.o -- endif -- endif -- endif --+endif -- ifdef NEED_T_PRF --+ifneq ($(CONFIG_TLS), mbedtls) -- SHA1OBJS += ../src/crypto/sha1-tprf.o -- endif --+endif -- ifdef NEED_TLS_PRF --+ifneq ($(CONFIG_TLS), mbedtls) -- SHA1OBJS += ../src/crypto/sha1-tlsprf.o -- endif -- endif --+endif -- -- ifndef CONFIG_FIPS -- ifneq ($(CONFIG_TLS), openssl) -- ifneq ($(CONFIG_TLS), linux) -- ifneq ($(CONFIG_TLS), gnutls) -- ifneq ($(CONFIG_TLS), wolfssl) --+ifneq ($(CONFIG_TLS), mbedtls) -- MD5OBJS += ../src/crypto/md5.o -- endif -- endif -- endif -- endif -- endif --+endif -- ifdef NEED_MD5 -- ifdef CONFIG_INTERNAL_MD5 -- MD5OBJS += ../src/crypto/md5-internal.o --@@ -1520,12 +1569,17 @@ ifneq ($(CONFIG_TLS), openssl) -- ifneq ($(CONFIG_TLS), linux) -- ifneq ($(CONFIG_TLS), gnutls) -- ifneq ($(CONFIG_TLS), wolfssl) --+ifneq ($(CONFIG_TLS), mbedtls) -- SHA256OBJS += ../src/crypto/sha256.o -- endif -- endif -- endif -- endif --+endif --+ --+ifneq ($(CONFIG_TLS), mbedtls) -- SHA256OBJS += ../src/crypto/sha256-prf.o --+endif -- ifdef CONFIG_INTERNAL_SHA256 -- SHA256OBJS += ../src/crypto/sha256-internal.o -- endif --@@ -1538,50 +1592,68 @@ CFLAGS += -DCONFIG_INTERNAL_SHA512 -- SHA256OBJS += ../src/crypto/sha512-internal.o -- endif -- ifdef NEED_TLS_PRF_SHA256 --+ifneq ($(CONFIG_TLS), mbedtls) -- SHA256OBJS += ../src/crypto/sha256-tlsprf.o -- endif --+endif -- ifdef NEED_TLS_PRF_SHA384 --+ifneq ($(CONFIG_TLS), mbedtls) -- SHA256OBJS += ../src/crypto/sha384-tlsprf.o -- endif --+endif -- ifdef NEED_HMAC_SHA256_KDF -- CFLAGS += -DCONFIG_HMAC_SHA256_KDF --+ifneq ($(CONFIG_TLS), mbedtls) -- OBJS += ../src/crypto/sha256-kdf.o -- endif --+endif -- ifdef NEED_HMAC_SHA384_KDF -- CFLAGS += -DCONFIG_HMAC_SHA384_KDF --+ifneq ($(CONFIG_TLS), mbedtls) -- OBJS += ../src/crypto/sha384-kdf.o -- endif --+endif -- ifdef NEED_HMAC_SHA512_KDF -- CFLAGS += -DCONFIG_HMAC_SHA512_KDF --+ifneq ($(CONFIG_TLS), mbedtls) -- OBJS += ../src/crypto/sha512-kdf.o -- endif --+endif -- OBJS += $(SHA256OBJS) -- ifdef NEED_SHA384 -- ifneq ($(CONFIG_TLS), openssl) -- ifneq ($(CONFIG_TLS), linux) -- ifneq ($(CONFIG_TLS), gnutls) -- ifneq ($(CONFIG_TLS), wolfssl) --+ifneq ($(CONFIG_TLS), mbedtls) -- OBJS += ../src/crypto/sha384.o -- endif -- endif -- endif -- endif --+endif -- CFLAGS += -DCONFIG_SHA384 --+ifneq ($(CONFIG_TLS), mbedtls) -- OBJS += ../src/crypto/sha384-prf.o -- endif --+endif -- ifdef NEED_SHA512 -- ifneq ($(CONFIG_TLS), openssl) -- ifneq ($(CONFIG_TLS), linux) -- ifneq ($(CONFIG_TLS), gnutls) -- ifneq ($(CONFIG_TLS), wolfssl) --+ifneq ($(CONFIG_TLS), mbedtls) -- OBJS += ../src/crypto/sha512.o -- endif -- endif -- endif -- endif --+endif -- CFLAGS += -DCONFIG_SHA512 --+ifneq ($(CONFIG_TLS), mbedtls) -- OBJS += ../src/crypto/sha512-prf.o -- endif --+endif -- -- ifdef NEED_ASN1 -- OBJS += ../src/tls/asn1.o --@@ -1756,10 +1828,12 @@ ifdef CONFIG_FIPS -- CFLAGS += -DCONFIG_FIPS -- ifneq ($(CONFIG_TLS), openssl) -- ifneq ($(CONFIG_TLS), wolfssl) --+ifneq ($(CONFIG_TLS), mbedtls) -- $(error CONFIG_FIPS=y requires CONFIG_TLS=openssl) -- endif -- endif -- endif --+endif -- -- OBJS += $(SHA1OBJS) $(DESOBJS) -- ----- a/wpa_supplicant/defconfig --+++ b/wpa_supplicant/defconfig --@@ -10,8 +10,8 @@ -- # to override previous values of the variables. -- -- ---# Uncomment following two lines and fix the paths if you have installed OpenSSL ---# or GnuTLS in non-default location --+# Uncomment following two lines and fix the paths if you have installed TLS --+# libraries in a non-default location -- #CFLAGS += -I/usr/local/openssl/include -- #LIBS += -L/usr/local/openssl/lib -- --@@ -20,6 +20,7 @@ -- # used to fix build issues on such systems (krb5.h not found). -- #CFLAGS += -I/usr/include/kerberos -- --+ -- # 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 -- # openssl = OpenSSL (default) -- # gnutls = GnuTLS -- # internal = Internal TLSv1 implementation (experimental) --+# mbedtls = mbed TLS -- # linux = Linux kernel AF_ALG and internal TLSv1 implementation (experimental) -- # none = Empty template -- #CONFIG_TLS=openssl -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 -deleted file mode 100644 -index a48725264f..0000000000 ---- a/package/network/services/hostapd/patches/120-mbedtls-fips186_2_prf.patch -+++ /dev/null -@@ -1,114 +0,0 @@ --From c8dba4bd750269bcc80fed3d546e2077cb4cdf0e Mon Sep 17 00:00:00 2001 --From: Glenn Strauss --Date: Tue, 19 Jul 2022 20:02:21 -0400 --Subject: [PATCH 2/7] mbedtls: fips186_2_prf() -- --Signed-off-by: Glenn Strauss ----- -- hostapd/Makefile | 4 --- -- src/crypto/crypto_mbedtls.c | 60 +++++++++++++++++++++++++++++++++++++ -- wpa_supplicant/Makefile | 4 --- -- 3 files changed, 60 insertions(+), 8 deletions(-) -- ----- a/hostapd/Makefile --+++ b/hostapd/Makefile --@@ -759,10 +759,6 @@ endif -- OBJS += ../src/crypto/crypto_$(CONFIG_CRYPTO).o -- HOBJS += ../src/crypto/crypto_$(CONFIG_CRYPTO).o -- SOBJS += ../src/crypto/crypto_$(CONFIG_CRYPTO).o ---ifdef NEED_FIPS186_2_PRF ---OBJS += ../src/crypto/fips_prf_internal.o ---SHA1OBJS += ../src/crypto/sha1-internal.o ---endif -- ifeq ($(CONFIG_CRYPTO), mbedtls) -- ifdef CONFIG_DPP -- LIBS += -lmbedx509 ----- a/src/crypto/crypto_mbedtls.c --+++ b/src/crypto/crypto_mbedtls.c --@@ -132,6 +132,12 @@ -- #define CRYPTO_MBEDTLS_HMAC_KDF_SHA512 -- #endif -- --+#if defined(EAP_SIM) || defined(EAP_SIM_DYNAMIC) || defined(EAP_SERVER_SIM) \ --+ || defined(EAP_AKA) || defined(EAP_AKA_DYNAMIC) || defined(EAP_SERVER_AKA) --+/* EAP_SIM=y EAP_AKA=y */ --+#define CRYPTO_MBEDTLS_FIPS186_2_PRF --+#endif --+ -- #if defined(EAP_FAST) || defined(EAP_FAST_DYNAMIC) || defined(EAP_SERVER_FAST) \ -- || defined(EAP_TEAP) || defined(EAP_TEAP_DYNAMIC) || defined(EAP_SERVER_FAST) -- #define CRYPTO_MBEDTLS_SHA1_T_PRF --@@ -813,6 +819,60 @@ int sha1_t_prf(const u8 *key, size_t key -- -- #endif /* CRYPTO_MBEDTLS_SHA1_T_PRF */ -- --+#ifdef CRYPTO_MBEDTLS_FIPS186_2_PRF --+ --+/* fips_prf_internal.c sha1-internal.c */ --+ --+/* used only by src/eap_common/eap_sim_common.c:eap_sim_prf() --+ * for eap_sim_derive_keys() and eap_sim_derive_keys_reauth() --+ * where xlen is 160 */ --+ --+int fips186_2_prf(const u8 *seed, size_t seed_len, u8 *x, size_t xlen) --+{ --+ /* FIPS 186-2 + change notice 1 */ --+ --+ mbedtls_sha1_context ctx; --+ u8 * const xkey = ctx.MBEDTLS_PRIVATE(buffer); --+ u32 * const xstate = ctx.MBEDTLS_PRIVATE(state); --+ const u32 xstate_init[] = --+ { 0x67452301, 0xEFCDAB89, 0x98BADCFE, 0x10325476, 0xC3D2E1F0 }; --+ --+ mbedtls_sha1_init(&ctx); --+ os_memcpy(xkey, seed, seed_len < 64 ? seed_len : 64); --+ --+ /* note: does not fill extra bytes if (xlen % 20) (SHA1_MAC_LEN) */ --+ for (; xlen >= 20; xlen -= 20) { --+ /* XSEED_j = 0 */ --+ /* XVAL = (XKEY + XSEED_j) mod 2^b */ --+ --+ /* w_i = G(t, XVAL) */ --+ os_memcpy(xstate, xstate_init, sizeof(xstate_init)); --+ mbedtls_internal_sha1_process(&ctx, xkey); --+ --+ #if __BYTE_ORDER == __LITTLE_ENDIAN --+ xstate[0] = host_to_be32(xstate[0]); --+ xstate[1] = host_to_be32(xstate[1]); --+ xstate[2] = host_to_be32(xstate[2]); --+ xstate[3] = host_to_be32(xstate[3]); --+ xstate[4] = host_to_be32(xstate[4]); --+ #endif --+ os_memcpy(x, xstate, 20); --+ if (xlen == 20) /*(done; skip prep for next loop)*/ --+ break; --+ --+ /* XKEY = (1 + XKEY + w_i) mod 2^b */ --+ for (u32 carry = 1, k = 20; k-- > 0; carry >>= 8) --+ xkey[k] = (carry += xkey[k] + x[k]) & 0xff; --+ x += 20; --+ /* x_j = w_0|w_1 (each pair of iterations through loop)*/ --+ } --+ --+ mbedtls_sha1_free(&ctx); --+ return 0; --+} --+ --+#endif /* CRYPTO_MBEDTLS_FIPS186_2_PRF */ --+ -- #endif /* MBEDTLS_SHA1_C */ -- -- ----- a/wpa_supplicant/Makefile --+++ b/wpa_supplicant/Makefile --@@ -1174,10 +1174,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 ---ifdef NEED_FIPS186_2_PRF ---OBJS += ../src/crypto/fips_prf_internal.o ---SHA1OBJS += ../src/crypto/sha1-internal.o ---endif -- ifeq ($(CONFIG_CRYPTO), mbedtls) -- LIBS += -lmbedcrypto -- LIBS_p += -lmbedcrypto -diff --git a/package/network/services/hostapd/patches/130-mbedtls-annotate-with-TEST_FAIL-for-hwsim-tests.patch b/package/network/services/hostapd/patches/130-mbedtls-annotate-with-TEST_FAIL-for-hwsim-tests.patch -deleted file mode 100644 -index ae7620b90c..0000000000 ---- a/package/network/services/hostapd/patches/130-mbedtls-annotate-with-TEST_FAIL-for-hwsim-tests.patch -+++ /dev/null -@@ -1,421 +0,0 @@ --From 31bd19e0e0254b910cccfd3ddc6a6a9222bbcfc0 Mon Sep 17 00:00:00 2001 --From: Glenn Strauss --Date: Sun, 9 Oct 2022 05:12:17 -0400 --Subject: [PATCH 3/7] mbedtls: annotate with TEST_FAIL() for hwsim tests -- --Signed-off-by: Glenn Strauss ----- -- src/crypto/crypto_mbedtls.c | 124 ++++++++++++++++++++++++++++++++++++ -- 1 file changed, 124 insertions(+) -- ----- a/src/crypto/crypto_mbedtls.c --+++ b/src/crypto/crypto_mbedtls.c --@@ -280,6 +280,9 @@ __attribute_noinline__ -- static int md_vector(size_t num_elem, const u8 *addr[], const size_t *len, -- u8 *mac, mbedtls_md_type_t md_type) -- { --+ if (TEST_FAIL()) --+ return -1; --+ -- mbedtls_md_context_t ctx; -- mbedtls_md_init(&ctx); -- if (mbedtls_md_setup(&ctx, mbedtls_md_info_from_type(md_type), 0) != 0){ --@@ -343,6 +346,9 @@ __attribute_noinline__ -- static int sha384_512_vector(size_t num_elem, const u8 *addr[], -- const size_t *len, u8 *mac, int is384) -- { --+ if (TEST_FAIL()) --+ return -1; --+ -- struct mbedtls_sha512_context ctx; -- mbedtls_sha512_init(&ctx); -- #if MBEDTLS_VERSION_MAJOR >= 3 --@@ -375,6 +381,9 @@ int sha384_vector(size_t num_elem, const -- #include -- int sha256_vector(size_t num_elem, const u8 *addr[], const size_t *len, u8 *mac) -- { --+ if (TEST_FAIL()) --+ return -1; --+ -- struct mbedtls_sha256_context ctx; -- mbedtls_sha256_init(&ctx); -- #if MBEDTLS_VERSION_MAJOR >= 3 --@@ -397,6 +406,9 @@ int sha256_vector(size_t num_elem, const -- #include -- int sha1_vector(size_t num_elem, const u8 *addr[], const size_t *len, u8 *mac) -- { --+ if (TEST_FAIL()) --+ return -1; --+ -- struct mbedtls_sha1_context ctx; -- mbedtls_sha1_init(&ctx); -- #if MBEDTLS_VERSION_MAJOR >= 3 --@@ -419,6 +431,9 @@ int sha1_vector(size_t num_elem, const u -- #include -- int md5_vector(size_t num_elem, const u8 *addr[], const size_t *len, u8 *mac) -- { --+ if (TEST_FAIL()) --+ return -1; --+ -- struct mbedtls_md5_context ctx; -- mbedtls_md5_init(&ctx); -- #if MBEDTLS_VERSION_MAJOR >= 3 --@@ -441,6 +456,9 @@ int md5_vector(size_t num_elem, const u8 -- #include -- int md4_vector(size_t num_elem, const u8 *addr[], const size_t *len, u8 *mac) -- { --+ if (TEST_FAIL()) --+ return -1; --+ -- struct mbedtls_md4_context ctx; -- mbedtls_md4_init(&ctx); -- mbedtls_md4_starts_ret(&ctx); --@@ -460,6 +478,9 @@ static int hmac_vector(const u8 *key, si -- const u8 *addr[], const size_t *len, u8 *mac, -- mbedtls_md_type_t md_type) -- { --+ if (TEST_FAIL()) --+ return -1; --+ -- mbedtls_md_context_t ctx; -- mbedtls_md_init(&ctx); -- if (mbedtls_md_setup(&ctx, mbedtls_md_info_from_type(md_type), 1) != 0){ --@@ -571,6 +592,9 @@ static int hmac_kdf_expand(const u8 *prk -- const char *label, const u8 *info, size_t info_len, -- u8 *okm, size_t okm_len, mbedtls_md_type_t md_type) -- { --+ if (TEST_FAIL()) --+ return -1; --+ -- const mbedtls_md_info_t *md_info = mbedtls_md_info_from_type(md_type); -- #ifdef MBEDTLS_HKDF_C -- if (label == NULL) /* RFC 5869 HKDF-Expand when (label == NULL) */ --@@ -663,6 +687,9 @@ static int hmac_prf_bits(const u8 *key, -- const u8 *data, size_t data_len, u8 *buf, -- size_t buf_len_bits, mbedtls_md_type_t md_type) -- { --+ if (TEST_FAIL()) --+ return -1; --+ -- mbedtls_md_context_t ctx; -- mbedtls_md_init(&ctx); -- const mbedtls_md_info_t *md_info = mbedtls_md_info_from_type(md_type); --@@ -938,6 +965,9 @@ int pbkdf2_sha1(const char *passphrase, -- -- static void *aes_crypt_init_mode(const u8 *key, size_t len, int mode) -- { --+ if (TEST_FAIL()) --+ return NULL; --+ -- mbedtls_aes_context *aes = os_malloc(sizeof(*aes)); -- if (!aes) -- return NULL; --@@ -996,6 +1026,9 @@ void aes_decrypt_deinit(void *ctx) -- /* aes-wrap.c */ -- int aes_wrap(const u8 *kek, size_t kek_len, int n, const u8 *plain, u8 *cipher) -- { --+ if (TEST_FAIL()) --+ return -1; --+ -- mbedtls_nist_kw_context ctx; -- mbedtls_nist_kw_init(&ctx); -- size_t olen; --@@ -1010,6 +1043,9 @@ int aes_wrap(const u8 *kek, size_t kek_l -- /* aes-unwrap.c */ -- int aes_unwrap(const u8 *kek, size_t kek_len, int n, const u8 *cipher, u8 *plain) -- { --+ if (TEST_FAIL()) --+ return -1; --+ -- mbedtls_nist_kw_context ctx; -- mbedtls_nist_kw_init(&ctx); -- size_t olen; --@@ -1041,6 +1077,9 @@ int omac1_aes_vector( -- const u8 *key, size_t key_len, size_t num_elem, const u8 *addr[], -- const size_t *len, u8 *mac) -- { --+ if (TEST_FAIL()) --+ return -1; --+ -- mbedtls_cipher_type_t cipher_type; -- switch (key_len) { -- case 16: cipher_type = MBEDTLS_CIPHER_AES_128_ECB; break; --@@ -1103,6 +1142,9 @@ int omac1_aes_256(const u8 *key, const u -- /* aes-encblock.c */ -- int aes_128_encrypt_block(const u8 *key, const u8 *in, u8 *out) -- { --+ if (TEST_FAIL()) --+ return -1; --+ -- mbedtls_aes_context aes; -- mbedtls_aes_init(&aes); -- int ret = mbedtls_aes_setkey_enc(&aes, key, 128) --@@ -1118,6 +1160,9 @@ int aes_128_encrypt_block(const u8 *key, -- int aes_ctr_encrypt(const u8 *key, size_t key_len, const u8 *nonce, -- u8 *data, size_t data_len) -- { --+ if (TEST_FAIL()) --+ return -1; --+ -- unsigned char counter[MBEDTLS_AES_BLOCK_SIZE]; -- unsigned char stream_block[MBEDTLS_AES_BLOCK_SIZE]; -- os_memcpy(counter, nonce, MBEDTLS_AES_BLOCK_SIZE);/*(must be writable)*/ --@@ -1160,11 +1205,17 @@ static int aes_128_cbc_oper(const u8 *ke -- -- int aes_128_cbc_encrypt(const u8 *key, const u8 *iv, u8 *data, size_t data_len) -- { --+ if (TEST_FAIL()) --+ return -1; --+ -- return aes_128_cbc_oper(key, iv, data, data_len, MBEDTLS_AES_ENCRYPT); -- } -- -- int aes_128_cbc_decrypt(const u8 *key, const u8 *iv, u8 *data, size_t data_len) -- { --+ if (TEST_FAIL()) --+ return -1; --+ -- return aes_128_cbc_oper(key, iv, data, data_len, MBEDTLS_AES_DECRYPT); -- } -- --@@ -1407,6 +1458,10 @@ int crypto_hash_finish(struct crypto_has -- } -- mbedtls_md_free(mctx); -- os_free(mctx); --+ --+ if (TEST_FAIL()) --+ return -1; --+ -- return 0; -- } -- --@@ -1421,6 +1476,9 @@ int crypto_hash_finish(struct crypto_has -- -- struct crypto_bignum *crypto_bignum_init(void) -- { --+ if (TEST_FAIL()) --+ return NULL; --+ -- mbedtls_mpi *bn = os_malloc(sizeof(*bn)); -- if (bn) -- mbedtls_mpi_init(bn); --@@ -1429,6 +1487,9 @@ struct crypto_bignum *crypto_bignum_init -- -- struct crypto_bignum *crypto_bignum_init_set(const u8 *buf, size_t len) -- { --+ if (TEST_FAIL()) --+ return NULL; --+ -- mbedtls_mpi *bn = os_malloc(sizeof(*bn)); -- if (bn) { -- mbedtls_mpi_init(bn); --@@ -1442,6 +1503,9 @@ struct crypto_bignum *crypto_bignum_init -- -- struct crypto_bignum *crypto_bignum_init_uint(unsigned int val) -- { --+ if (TEST_FAIL()) --+ return NULL; --+ -- #if 0 /*(hostap use of this interface passes int, not uint)*/ -- val = host_to_be32(val); -- return crypto_bignum_init_set((const u8 *)&val, sizeof(val)); --@@ -1467,6 +1531,9 @@ void crypto_bignum_deinit(struct crypto_ -- int crypto_bignum_to_bin(const struct crypto_bignum *a, -- u8 *buf, size_t buflen, size_t padlen) -- { --+ if (TEST_FAIL()) --+ return -1; --+ -- size_t n = mbedtls_mpi_size((mbedtls_mpi *)a); -- if (n < padlen) -- n = padlen; --@@ -1477,6 +1544,9 @@ int crypto_bignum_to_bin(const struct cr -- -- int crypto_bignum_rand(struct crypto_bignum *r, const struct crypto_bignum *m) -- { --+ if (TEST_FAIL()) --+ return -1; --+ -- /*assert(r != m);*//* r must not be same as m for mbedtls_mpi_random()*/ -- #if MBEDTLS_VERSION_NUMBER >= 0x021B0000 /* mbedtls 2.27.0 */ -- return mbedtls_mpi_random((mbedtls_mpi *)r, 0, (mbedtls_mpi *)m, --@@ -1513,6 +1583,9 @@ int crypto_bignum_exptmod(const struct c -- const struct crypto_bignum *c, -- struct crypto_bignum *d) -- { --+ if (TEST_FAIL()) --+ return -1; --+ -- /* (check if input params match d; d is the result) */ -- /* (a == d) is ok in current mbedtls implementation */ -- if (b == d || c == d) { /*(not ok; store result in intermediate)*/ --@@ -1540,6 +1613,9 @@ int crypto_bignum_inverse(const struct c -- const struct crypto_bignum *b, -- struct crypto_bignum *c) -- { --+ if (TEST_FAIL()) --+ return -1; --+ -- return mbedtls_mpi_inv_mod((mbedtls_mpi *)c, -- (const mbedtls_mpi *)a, -- (const mbedtls_mpi *)b) ? -1 : 0; --@@ -1549,6 +1625,9 @@ int crypto_bignum_sub(const struct crypt -- const struct crypto_bignum *b, -- struct crypto_bignum *c) -- { --+ if (TEST_FAIL()) --+ return -1; --+ -- return mbedtls_mpi_sub_mpi((mbedtls_mpi *)c, -- (const mbedtls_mpi *)a, -- (const mbedtls_mpi *)b) ? -1 : 0; --@@ -1558,6 +1637,9 @@ int crypto_bignum_div(const struct crypt -- const struct crypto_bignum *b, -- struct crypto_bignum *c) -- { --+ if (TEST_FAIL()) --+ return -1; --+ -- /*(most current use of this crypto.h interface has a == c (result), -- * so store result in an intermediate to avoid overwritten input)*/ -- mbedtls_mpi R; --@@ -1575,6 +1657,9 @@ int crypto_bignum_addmod(const struct cr -- const struct crypto_bignum *c, -- struct crypto_bignum *d) -- { --+ if (TEST_FAIL()) --+ return -1; --+ -- return mbedtls_mpi_add_mpi((mbedtls_mpi *)d, -- (const mbedtls_mpi *)a, -- (const mbedtls_mpi *)b) --@@ -1588,6 +1673,9 @@ int crypto_bignum_mulmod(const struct cr -- const struct crypto_bignum *c, -- struct crypto_bignum *d) -- { --+ if (TEST_FAIL()) --+ return -1; --+ -- return mbedtls_mpi_mul_mpi((mbedtls_mpi *)d, -- (const mbedtls_mpi *)a, -- (const mbedtls_mpi *)b) --@@ -1600,6 +1688,9 @@ int crypto_bignum_sqrmod(const struct cr -- const struct crypto_bignum *b, -- struct crypto_bignum *c) -- { --+ if (TEST_FAIL()) --+ return -1; --+ -- #if 1 -- return crypto_bignum_mulmod(a, a, b, c); -- #else --@@ -1650,6 +1741,9 @@ int crypto_bignum_is_odd(const struct cr -- int crypto_bignum_legendre(const struct crypto_bignum *a, -- const struct crypto_bignum *p) -- { --+ if (TEST_FAIL()) --+ return -2; --+ -- /* Security Note: -- * mbedtls_mpi_exp_mod() is not documented to run in constant time, -- * though mbedtls/library/bignum.c uses constant_time_internal.h funcs. --@@ -1702,6 +1796,9 @@ int crypto_mod_exp(const u8 *base, size_ -- const u8 *modulus, size_t modulus_len, -- u8 *result, size_t *result_len) -- { --+ if (TEST_FAIL()) --+ return -1; --+ -- mbedtls_mpi bn_base, bn_exp, bn_modulus, bn_result; -- mbedtls_mpi_init(&bn_base); -- mbedtls_mpi_init(&bn_exp); --@@ -1769,6 +1866,9 @@ static int crypto_mbedtls_dh_init_public -- int crypto_dh_init(u8 generator, const u8 *prime, size_t prime_len, u8 *privkey, -- u8 *pubkey) -- { --+ if (TEST_FAIL()) --+ return -1; --+ -- #if 0 /*(crypto_dh_init() duplicated (and identical) in crypto_*.c modules)*/ -- size_t pubkey_len, pad; -- --@@ -1810,6 +1910,9 @@ int crypto_dh_derive_secret(u8 generator -- const u8 *pubkey, size_t pubkey_len, -- u8 *secret, size_t *len) -- { --+ if (TEST_FAIL()) --+ return -1; --+ -- #if 0 -- if (pubkey_len > prime_len || -- (pubkey_len == prime_len && --@@ -2512,6 +2615,9 @@ const struct crypto_ec_point * crypto_ec -- -- struct crypto_ec_point *crypto_ec_point_init(struct crypto_ec *e) -- { --+ if (TEST_FAIL()) --+ return NULL; --+ -- mbedtls_ecp_point *p = os_malloc(sizeof(*p)); -- if (p != NULL) -- mbedtls_ecp_point_init(p); --@@ -2536,6 +2642,9 @@ int crypto_ec_point_x(struct crypto_ec * -- int crypto_ec_point_to_bin(struct crypto_ec *e, -- const struct crypto_ec_point *point, u8 *x, u8 *y) -- { --+ if (TEST_FAIL()) --+ return -1; --+ -- /* crypto.h documents crypto_ec_point_to_bin() output is big-endian */ -- size_t len = CRYPTO_EC_plen(e); -- if (x) { --@@ -2563,6 +2672,9 @@ int crypto_ec_point_to_bin(struct crypto -- struct crypto_ec_point * crypto_ec_point_from_bin(struct crypto_ec *e, -- const u8 *val) -- { --+ if (TEST_FAIL()) --+ return NULL; --+ -- size_t len = CRYPTO_EC_plen(e); -- mbedtls_ecp_point *p = os_malloc(sizeof(*p)); -- u8 buf[1+MBEDTLS_MPI_MAX_SIZE*2]; --@@ -2615,6 +2727,9 @@ int crypto_ec_point_add(struct crypto_ec -- const struct crypto_ec_point *b, -- struct crypto_ec_point *c) -- { --+ if (TEST_FAIL()) --+ return -1; --+ -- /* mbedtls does not provide an mbedtls_ecp_point add function */ -- mbedtls_mpi one; -- mbedtls_mpi_init(&one); --@@ -2631,6 +2746,9 @@ int crypto_ec_point_mul(struct crypto_ec -- const struct crypto_bignum *b, -- struct crypto_ec_point *res) -- { --+ if (TEST_FAIL()) --+ return -1; --+ -- return mbedtls_ecp_mul( -- (mbedtls_ecp_group *)e, (mbedtls_ecp_point *)res, -- (const mbedtls_mpi *)b, (const mbedtls_ecp_point *)p, --@@ -2639,6 +2757,9 @@ int crypto_ec_point_mul(struct crypto_ec -- -- int crypto_ec_point_invert(struct crypto_ec *e, struct crypto_ec_point *p) -- { --+ if (TEST_FAIL()) --+ return -1; --+ -- if (mbedtls_ecp_get_type((mbedtls_ecp_group *)e) -- == MBEDTLS_ECP_TYPE_MONTGOMERY) { -- /* e.g. MBEDTLS_ECP_DP_CURVE25519 and MBEDTLS_ECP_DP_CURVE448 */ --@@ -2751,6 +2872,9 @@ struct crypto_bignum * -- crypto_ec_point_compute_y_sqr(struct crypto_ec *e, -- const struct crypto_bignum *x) -- { --+ if (TEST_FAIL()) --+ return NULL; --+ -- mbedtls_mpi *y2 = os_malloc(sizeof(*y2)); -- if (y2 == NULL) -- return NULL; -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 -deleted file mode 100644 -index 148c268f9c..0000000000 ---- a/package/network/services/hostapd/patches/140-tests-Makefile-make-run-tests-with-CONFIG_TLS.patch -+++ /dev/null -@@ -1,1358 +0,0 @@ --From f24933dc175e0faf44a3cce3330c256a59649ca6 Mon Sep 17 00:00:00 2001 --From: Glenn Strauss --Date: Tue, 19 Jul 2022 23:01:17 -0400 --Subject: [PATCH 4/7] tests/Makefile make run-tests with CONFIG_TLS=... -- --add test-crypto_module.c to run crypto_module_tests() -- --adjust some tests/hwsim/*.py for mbed TLS (work in progress) -- --option to build and run-tests with CONFIG_TLS=internal # (default) --$ cd tests; make clean --$ make run-tests -- --option to build and run-tests with CONFIG_TLS=gnutls --$ cd tests; make clean CONFIG_TLS=gnutls --$ make run-tests CONFIG_TLS=gnutls -- --option to build and run-tests with CONFIG_TLS=mbedtls --$ cd tests; make clean CONFIG_TLS=mbedtls --$ make run-tests CONFIG_TLS=mbedtls -- --option to build and run-tests with CONFIG_TLS=openssl --$ cd tests; make clean CONFIG_TLS=openssl --$ make run-tests CONFIG_TLS=openssl -- --option to build and run-tests with CONFIG_TLS=wolfssl --$ cd tests; make clean CONFIG_TLS=wolfssl --$ make run-tests CONFIG_TLS=wolfssl -- --RFE: Makefile logic for crypto objects should be centralized -- instead of being duplicated in hostapd/Makefile, -- wpa_supplicant/Makefile, src/crypto/Makefile, -- tests/Makefile, ... -- --Signed-off-by: Glenn Strauss ----- -- hostapd/Makefile | 6 + -- 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/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_pmksa_cache.py | 4 +- -- tests/hwsim/test_sae.py | 7 ++ -- tests/hwsim/test_suite_b.py | 3 + -- tests/hwsim/test_wpas_ctrl.py | 2 +- -- tests/hwsim/utils.py | 8 +- -- tests/test-crypto_module.c | 16 +++ -- tests/test-https.c | 12 +- -- tests/test-https_server.c | 12 +- -- wpa_supplicant/Makefile | 6 + -- 22 files changed, 524 insertions(+), 91 deletions(-) -- create mode 100644 tests/test-crypto_module.c -- ----- a/hostapd/Makefile --+++ b/hostapd/Makefile --@@ -696,6 +696,7 @@ CFLAGS += -DCONFIG_TLSV12 -- endif -- -- ifeq ($(CONFIG_TLS), wolfssl) --+CFLAGS += -DCONFIG_TLS_WOLFSSL -- CONFIG_CRYPTO=wolfssl -- ifdef TLS_FUNCS -- OBJS += ../src/crypto/tls_wolfssl.o --@@ -716,6 +717,7 @@ endif -- endif -- -- ifeq ($(CONFIG_TLS), openssl) --+CFLAGS += -DCONFIG_TLS_OPENSSL -- CFLAGS += -DCRYPTO_RSA_OAEP_SHA256 -- CONFIG_CRYPTO=openssl -- ifdef TLS_FUNCS --@@ -746,6 +748,7 @@ CFLAGS += -DTLS_DEFAULT_CIPHERS=\"$(CONF -- endif -- -- ifeq ($(CONFIG_TLS), mbedtls) --+CFLAGS += -DCONFIG_TLS_MBEDTLS -- ifndef CONFIG_CRYPTO -- CONFIG_CRYPTO=mbedtls -- endif --@@ -776,6 +779,7 @@ endif -- endif -- -- ifeq ($(CONFIG_TLS), gnutls) --+CFLAGS += -DCONFIG_TLS_GNUTLS -- ifndef CONFIG_CRYPTO -- # default to libgcrypt -- CONFIG_CRYPTO=gnutls --@@ -806,6 +810,7 @@ endif -- endif -- -- ifeq ($(CONFIG_TLS), internal) --+CFLAGS += -DCONFIG_TLS_INTERNAL -- ifndef CONFIG_CRYPTO -- CONFIG_CRYPTO=internal -- endif --@@ -884,6 +889,7 @@ endif -- endif -- -- ifeq ($(CONFIG_TLS), linux) --+CFLAGS += -DCONFIG_TLS_INTERNAL -- OBJS += ../src/crypto/crypto_linux.o -- ifdef TLS_FUNCS -- OBJS += ../src/crypto/crypto_internal-rsa.o ----- a/src/crypto/Makefile --+++ b/src/crypto/Makefile --@@ -1,10 +1,121 @@ ---CFLAGS += -DCONFIG_CRYPTO_INTERNAL ---CFLAGS += -DCONFIG_TLS_INTERNAL_CLIENT ---CFLAGS += -DCONFIG_TLS_INTERNAL_SERVER -- #CFLAGS += -DALL_DH_GROUPS -- CFLAGS += -DCONFIG_SHA256 -- CFLAGS += -DCONFIG_SHA384 --+CFLAGS += -DCONFIG_HMAC_SHA256_KDF -- CFLAGS += -DCONFIG_HMAC_SHA384_KDF --+ --+# crypto_module_tests.c --+CFLAGS += -DCONFIG_MODULE_TESTS --+CFLAGS += -DCONFIG_DPP --+#CFLAGS += -DCONFIG_DPP2 --+#CFLAGS += -DCONFIG_DPP3 --+CFLAGS += -DCONFIG_ECC --+CFLAGS += -DCONFIG_MESH --+CFLAGS += -DEAP_PSK --+CFLAGS += -DEAP_FAST --+ --+ifeq ($(CONFIG_TLS),mbedtls) --+ --+# (enable features for 'cd tests; make run-tests CONFIG_TLS=mbedtls') --+CFLAGS += -DCRYPTO_RSA_OAEP_SHA256 --+CFLAGS += -DCONFIG_DES --+CFLAGS += -DEAP_IKEV2 --+CFLAGS += -DEAP_MSCHAPv2 --+CFLAGS += -DEAP_SIM --+ --+LIB_OBJS = tls_mbedtls.o crypto_mbedtls.o --+LIB_OBJS+= \ --+ aes-eax.o \ --+ aes-siv.o \ --+ dh_groups.o \ --+ milenage.o \ --+ ms_funcs.o --+ --+else --+ifeq ($(CONFIG_TLS),openssl) --+ --+# (enable features for 'cd tests; make run-tests CONFIG_TLS=openssl') --+ifndef CONFIG_TLS_DEFAULT_CIPHERS --+CONFIG_TLS_DEFAULT_CIPHERS = "DEFAULT:!EXP:!LOW" --+endif --+CFLAGS += -DTLS_DEFAULT_CIPHERS=\"$(CONFIG_TLS_DEFAULT_CIPHERS)\" --+CFLAGS += -DCRYPTO_RSA_OAEP_SHA256 --+CFLAGS += -DEAP_TLS_OPENSSL --+ --+LIB_OBJS = tls_openssl.o fips_prf_openssl.o crypto_openssl.o --+LIB_OBJS+= \ --+ aes-ctr.o \ --+ aes-eax.o \ --+ aes-encblock.o \ --+ aes-siv.o \ --+ dh_groups.o \ --+ milenage.o \ --+ ms_funcs.o \ --+ sha1-prf.o \ --+ sha1-tlsprf.o \ --+ sha1-tprf.o \ --+ sha256-kdf.o \ --+ sha256-prf.o \ --+ sha256-tlsprf.o --+ --+else --+ifeq ($(CONFIG_TLS),wolfssl) --+ --+# (wolfssl libraries must be built with ./configure --enable-wpas) --+# (enable features for 'cd tests; make run-tests CONFIG_TLS=wolfssl') --+CFLAGS += -DWOLFSSL_DER_LOAD --+CFLAGS += -DCONFIG_DES --+ --+LIB_OBJS = tls_wolfssl.o fips_prf_wolfssl.o crypto_wolfssl.o --+LIB_OBJS+= \ --+ aes-ctr.o \ --+ aes-eax.o \ --+ aes-encblock.o \ --+ aes-siv.o \ --+ dh_groups.o \ --+ milenage.o \ --+ ms_funcs.o \ --+ sha1-prf.o \ --+ sha1-tlsprf.o \ --+ sha1-tprf.o \ --+ sha256-kdf.o \ --+ sha256-prf.o \ --+ sha256-tlsprf.o --+ --+else --+ifeq ($(CONFIG_TLS),gnutls) --+ --+# (enable features for 'cd tests; make run-tests CONFIG_TLS=gnutls') --+LIB_OBJS = tls_gnutls.o crypto_gnutls.o --+LIB_OBJS+= \ --+ aes-cbc.o \ --+ aes-ctr.o \ --+ aes-eax.o \ --+ aes-encblock.o \ --+ aes-omac1.o \ --+ aes-siv.o \ --+ aes-unwrap.o \ --+ aes-wrap.o \ --+ dh_group5.o \ --+ dh_groups.o \ --+ milenage.o \ --+ ms_funcs.o \ --+ rc4.o \ --+ sha1-pbkdf2.o \ --+ sha1-prf.o \ --+ fips_prf_internal.o \ --+ sha1-internal.o \ --+ sha1-tlsprf.o \ --+ sha1-tprf.o \ --+ sha256-kdf.o \ --+ sha256-prf.o \ --+ sha256-tlsprf.o --+ --+else --+ --+CFLAGS += -DCONFIG_CRYPTO_INTERNAL --+CFLAGS += -DCONFIG_TLS_INTERNAL_CLIENT --+CFLAGS += -DCONFIG_TLS_INTERNAL_SERVER -- CFLAGS += -DCONFIG_INTERNAL_SHA384 -- -- LIB_OBJS= \ --@@ -13,7 +124,6 @@ LIB_OBJS= \ -- aes-ctr.o \ -- aes-eax.o \ -- aes-encblock.o \ --- aes-gcm.o \ -- aes-internal.o \ -- aes-internal-dec.o \ -- aes-internal-enc.o \ --@@ -37,6 +147,7 @@ LIB_OBJS= \ -- sha1-tlsprf.o \ -- sha1-tprf.o \ -- sha256.o \ --+ sha256-kdf.o \ -- sha256-prf.o \ -- sha256-tlsprf.o \ -- sha256-internal.o \ --@@ -53,6 +164,16 @@ LIB_OBJS += crypto_internal-modexp.o -- LIB_OBJS += crypto_internal-rsa.o -- LIB_OBJS += tls_internal.o -- LIB_OBJS += fips_prf_internal.o --+ --+endif --+endif --+endif --+endif --+ --+ --+# (used by wlantest/{bip,gcmp,rx_mgmt}.c and tests/test-aes.c) --+LIB_OBJS += aes-gcm.o --+ -- ifndef TEST_FUZZ -- LIB_OBJS += random.o -- endif ----- a/src/crypto/crypto_module_tests.c --+++ b/src/crypto/crypto_module_tests.c --@@ -2469,6 +2469,139 @@ static int test_hpke(void) -- } -- -- --+static int test_ecc(void) --+{ --+#ifdef CONFIG_ECC --+#ifndef CONFIG_TLS_INTERNAL --+#ifndef CONFIG_TLS_GNUTLS --+#if defined(CONFIG_TLS_MBEDTLS) \ --+ || defined(CONFIG_TLS_OPENSSL) \ --+ || defined(CONFIG_TLS_WOLFSSL) --+ wpa_printf(MSG_INFO, "Testing ECC"); --+ /* Note: some tests below are valid on supported Short Weierstrass --+ * curves, but not on Montgomery curves (e.g. IKE groups 31 and 32) --+ * (e.g. deriving and comparing y^2 test below not valid on Montgomery) --+ */ --+#ifdef CONFIG_TLS_MBEDTLS --+ const int grps[] = {19, 20, 21, 25, 26, 28}; --+#endif --+#ifdef CONFIG_TLS_OPENSSL --+ const int grps[] = {19, 20, 21, 26}; --+#endif --+#ifdef CONFIG_TLS_WOLFSSL --+ const int grps[] = {19, 20, 21, 26}; --+#endif --+ uint32_t i; --+ struct crypto_ec *e = NULL; --+ struct crypto_ec_point *p = NULL, *q = NULL; --+ struct crypto_bignum *x = NULL, *y = NULL; --+#ifdef CONFIG_DPP --+ u8 bin[4096]; --+#endif --+ for (i = 0; i < ARRAY_SIZE(grps); ++i) { --+ e = crypto_ec_init(grps[i]); --+ if (e == NULL --+ || crypto_ec_prime_len(e) == 0 --+ || crypto_ec_prime_len_bits(e) == 0 --+ || crypto_ec_order_len(e) == 0 --+ || crypto_ec_get_prime(e) == NULL --+ || crypto_ec_get_order(e) == NULL --+ || crypto_ec_get_a(e) == NULL --+ || crypto_ec_get_b(e) == NULL --+ || crypto_ec_get_generator(e) == NULL) { --+ break; --+ } --+#ifdef CONFIG_DPP --+ struct crypto_ec_key *key = crypto_ec_key_gen(grps[i]); --+ if (key == NULL) --+ break; --+ p = crypto_ec_key_get_public_key(key); --+ q = crypto_ec_key_get_public_key(key); --+ crypto_ec_key_deinit(key); --+ if (p == NULL || q == NULL) --+ break; --+ if (!crypto_ec_point_is_on_curve(e, p)) --+ break; --+ --+ /* inverted point should not match original; --+ * double-invert should match */ --+ if (crypto_ec_point_invert(e, q) != 0 --+ || crypto_ec_point_cmp(e, p, q) == 0 --+ || crypto_ec_point_invert(e, q) != 0 --+ || crypto_ec_point_cmp(e, p, q) != 0) { --+ break; --+ } --+ --+ /* crypto_ec_point_to_bin() and crypto_ec_point_from_bin() --+ * imbalanced interfaces? */ --+ size_t prime_len = crypto_ec_prime_len(e); --+ if (prime_len * 2 > sizeof(bin)) --+ break; --+ if (crypto_ec_point_to_bin(e, p, bin, bin+prime_len) != 0) --+ break; --+ struct crypto_ec_point *tmp = crypto_ec_point_from_bin(e, bin); --+ if (tmp == NULL) --+ break; --+ if (crypto_ec_point_cmp(e, p, tmp) != 0) { --+ crypto_ec_point_deinit(tmp, 0); --+ break; --+ } --+ crypto_ec_point_deinit(tmp, 0); --+ --+ x = crypto_bignum_init(); --+ y = crypto_bignum_init_set(bin+prime_len, prime_len); --+ if (x == NULL || y == NULL || crypto_ec_point_x(e, p, x) != 0) --+ break; --+ struct crypto_bignum *y2 = crypto_ec_point_compute_y_sqr(e, x); --+ if (y2 == NULL) --+ break; --+ if (crypto_bignum_sqrmod(y, crypto_ec_get_prime(e), y) != 0 --+ || crypto_bignum_cmp(y, y2) != 0) { --+ crypto_bignum_deinit(y2, 0); --+ break; --+ } --+ crypto_bignum_deinit(y2, 0); --+ crypto_bignum_deinit(x, 0); --+ crypto_bignum_deinit(y, 0); --+ x = NULL; --+ y = NULL; --+ --+ x = crypto_bignum_init(); --+ if (x == NULL) --+ break; --+ if (crypto_bignum_rand(x, crypto_ec_get_prime(e)) != 0) --+ break; --+ crypto_bignum_deinit(x, 0); --+ x = NULL; --+ --+ crypto_ec_point_deinit(p, 0); --+ p = NULL; --+ crypto_ec_point_deinit(q, 0); --+ q = NULL; --+#endif /* CONFIG_DPP */ --+ crypto_ec_deinit(e); --+ e = NULL; --+ } --+ if (i != ARRAY_SIZE(grps)) { --+ crypto_bignum_deinit(x, 0); --+ crypto_bignum_deinit(y, 0); --+ crypto_ec_point_deinit(p, 0); --+ crypto_ec_point_deinit(q, 0); --+ crypto_ec_deinit(e); --+ wpa_printf(MSG_INFO, --+ "ECC test case failed tls_id:%d", grps[i]); --+ return -1; --+ } --+ --+ wpa_printf(MSG_INFO, "ECC test cases passed"); --+#endif --+#endif /* !CONFIG_TLS_GNUTLS */ --+#endif /* !CONFIG_TLS_INTERNAL */ --+#endif /* CONFIG_ECC */ --+ return 0; --+} --+ --+ -- static int test_ms_funcs(void) -- { -- #ifndef CONFIG_FIPS --@@ -2590,6 +2723,7 @@ int crypto_module_tests(void) -- test_fips186_2_prf() || -- test_extract_expand_hkdf() || -- test_hpke() || --+ test_ecc() || -- test_ms_funcs()) -- ret = -1; -- ----- a/src/tls/Makefile --+++ b/src/tls/Makefile --@@ -1,3 +1,10 @@ --+LIB_OBJS= asn1.o --+ --+ifneq ($(CONFIG_TLS),gnutls) --+ifneq ($(CONFIG_TLS),mbedtls) --+ifneq ($(CONFIG_TLS),openssl) --+ifneq ($(CONFIG_TLS),wolfssl) --+ -- CFLAGS += -DCONFIG_INTERNAL_LIBTOMMATH -- CFLAGS += -DCONFIG_CRYPTO_INTERNAL -- CFLAGS += -DCONFIG_TLSV11 --@@ -21,5 +28,9 @@ LIB_OBJS= \ -- tlsv1_server_read.o \ -- tlsv1_server_write.o \ -- x509v3.o --+endif --+endif --+endif --+endif -- -- include ../lib.rules ----- a/tests/Makefile --+++ b/tests/Makefile --@@ -1,8 +1,10 @@ ---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 --+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 -- -- include ../src/build.rules -- --@@ -24,13 +26,27 @@ CFLAGS += -DCONFIG_IEEE80211R_AP -- CFLAGS += -DCONFIG_IEEE80211R -- CFLAGS += -DCONFIG_TDLS -- --+# test-crypto_module --+CFLAGS += -DCONFIG_MODULE_TESTS --+CFLAGS += -DCONFIG_DPP --+#CFLAGS += -DCONFIG_DPP2 --+#CFLAGS += -DCONFIG_DPP3 --+CFLAGS += -DCONFIG_ECC --+CFLAGS += -DCONFIG_HMAC_SHA256_KDF --+CFLAGS += -DCONFIG_HMAC_SHA384_KDF --+CFLAGS += -DCONFIG_MESH --+CFLAGS += -DCONFIG_SHA256 --+CFLAGS += -DCONFIG_SHA384 --+CFLAGS += -DEAP_PSK --+CFLAGS += -DEAP_FAST --+ -- CFLAGS += -I../src -- CFLAGS += -I../src/utils -- -- SLIBS = ../src/utils/libutils.a -- ---DLIBS = ../src/crypto/libcrypto.a \ --- ../src/tls/libtls.a --+DLIBS = ../src/tls/libtls.a \ --+ ../src/crypto/libcrypto.a -- -- _OBJS_VAR := LLIBS -- include ../src/objs.mk --@@ -42,12 +58,43 @@ include ../src/objs.mk -- LIBS = $(SLIBS) $(DLIBS) -- LLIBS = -Wl,--start-group $(DLIBS) -Wl,--end-group $(SLIBS) -- --+ifeq ($(CONFIG_TLS),mbedtls) --+CFLAGS += -DCONFIG_TLS_MBEDTLS --+LLIBS += -lmbedtls -lmbedx509 -lmbedcrypto --+else --+ifeq ($(CONFIG_TLS),openssl) --+CFLAGS += -DCONFIG_TLS_OPENSSL --+LLIBS += -lssl -lcrypto --+else --+ifeq ($(CONFIG_TLS),gnutls) --+CFLAGS += -DCONFIG_TLS_GNUTLS --+LLIBS += -lgnutls -lgpg-error -lgcrypt --+else --+ifeq ($(CONFIG_TLS),wolfssl) --+CFLAGS += -DCONFIG_TLS_WOLFSSL --+LLIBS += -lwolfssl -lm --+else --+CFLAGS += -DCONFIG_TLS_INTERNAL --+CFLAGS += -DCONFIG_TLS_INTERNAL_SERVER --+ALL += test-rsa-sig-ver --+ALL += test-x509v3 --+clean-config_tls_internal: --+ rm -f test_x509v3_nist.out.* --+ rm -f test_x509v3_nist2.out.* --+endif --+endif --+endif --+endif --+ -- # glibc < 2.17 needs -lrt for clock_gettime() -- LLIBS += -lrt -- -- test-aes: $(call BUILDOBJ,test-aes.o) $(LIBS) -- $(LDO) $(LDFLAGS) -o $@ $^ $(LLIBS) -- --+test-crypto_module: $(call BUILDOBJ,test-crypto_module.o) $(LIBS) --+ $(LDO) $(LDFLAGS) -o $@ $< $(LLIBS) --+ -- test-base64: $(call BUILDOBJ,test-base64.o) $(LIBS) -- $(LDO) $(LDFLAGS) -o $@ $^ $(LLIBS) -- --@@ -83,17 +130,11 @@ test-x509v3: $(call BUILDOBJ,test-x509v3 -- -- -- run-tests: $(ALL) --- ./test-aes --- ./test-list --- ./test-md4 --- ./test-milenage --- ./test-rsa-sig-ver --- ./test-sha1 --- ./test-sha256 --+ @set -ex; for i in $(RUN_TESTS); do ./$$i; done -- @echo -- @echo All tests completed successfully. -- ---clean: common-clean --+clean: common-clean clean-config_tls_internal -- rm -f *~ --- rm -f test_x509v3_nist.out.* --- rm -f test_x509v3_nist2.out.* --+ --+.PHONY: run-tests clean-config_tls_internal ----- a/tests/hwsim/example-hostapd.config --+++ b/tests/hwsim/example-hostapd.config --@@ -34,15 +34,7 @@ CONFIG_EAP_TNC=y -- CFLAGS += -DTNC_CONFIG_FILE=\"tnc/tnc_config\" -- LIBS += -rdynamic -- CONFIG_EAP_UNAUTH_TLS=y ---ifeq ($(CONFIG_TLS), openssl) ---CONFIG_EAP_PWD=y ---endif ---ifeq ($(CONFIG_TLS), wolfssl) ---CONFIG_EAP_PWD=y ---endif ---ifeq ($(CONFIG_TLS), mbedtls) ---CONFIG_EAP_PWD=y ---endif --+CONFIG_EAP_PWD=$(if $(filter openssl wolfssl mbedtls,$(CONFIG_TLS)),y,) -- 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 -- CONFIG_EAP_FAST=y -- CONFIG_EAP_TEAP=y -- CONFIG_EAP_IKEV2=y --- ---ifeq ($(CONFIG_TLS), openssl) ---CONFIG_EAP_PWD=y ---endif ---ifeq ($(CONFIG_TLS), wolfssl) ---CONFIG_EAP_PWD=y ---endif ---ifeq ($(CONFIG_TLS), mbedtls) ---CONFIG_EAP_PWD=y ---endif --+CONFIG_EAP_PWD=$(if $(filter openssl wolfssl mbedtls,$(CONFIG_TLS)),y,) -- -- 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): -- res = dev.get_capability("eap") -- if method not in res: -- raise HwsimSkip("EAP method %s not supported in the build" % method) --+ if method == "FAST" or method == "TEAP": --+ tls = dev.request("GET tls_library") --+ if tls.startswith("mbed TLS"): --+ raise HwsimSkip("EAP-%s not supported with this TLS library: " % method + tls) -- -- def check_subject_match_support(dev): -- tls = dev.request("GET tls_library") --- if not tls.startswith("OpenSSL") and not tls.startswith("wolfSSL"): --+ if tls.startswith("OpenSSL"): --+ return --+ elif tls.startswith("wolfSSL"): --+ return --+ elif tls.startswith("mbed TLS"): --+ return --+ else: -- raise HwsimSkip("subject_match not supported with this TLS library: " + tls) -- -- def check_check_cert_subject_support(dev): -- tls = dev.request("GET tls_library") --- if not tls.startswith("OpenSSL") and not tls.startswith("wolfSSL"): --+ if tls.startswith("OpenSSL"): --+ return --+ elif tls.startswith("wolfSSL"): --+ return --+ elif tls.startswith("mbed TLS"): --+ return --+ else: -- raise HwsimSkip("check_cert_subject not supported with this TLS library: " + tls) -- -- def check_altsubject_match_support(dev): -- tls = dev.request("GET tls_library") --- if not tls.startswith("OpenSSL") and not tls.startswith("wolfSSL"): --+ if tls.startswith("OpenSSL"): --+ return --+ elif tls.startswith("wolfSSL"): --+ return --+ elif tls.startswith("mbed TLS"): --+ return --+ else: -- raise HwsimSkip("altsubject_match not supported with this TLS library: " + tls) -- -- def check_domain_match(dev): --@@ -70,7 +92,13 @@ def check_domain_suffix_match(dev): -- -- def check_domain_match_full(dev): -- tls = dev.request("GET tls_library") --- if not tls.startswith("OpenSSL") and not tls.startswith("wolfSSL"): --+ if tls.startswith("OpenSSL"): --+ return --+ elif tls.startswith("wolfSSL"): --+ return --+ elif tls.startswith("mbed TLS"): --+ return --+ else: -- raise HwsimSkip("domain_suffix_match requires full match with this TLS library: " + tls) -- -- def check_cert_probe_support(dev): --@@ -79,8 +107,15 @@ def check_cert_probe_support(dev): -- raise HwsimSkip("Certificate probing not supported with this TLS library: " + tls) -- -- def check_ext_cert_check_support(dev): --+ if not openssl_imported: --+ raise HwsimSkip("OpenSSL python method not available") --+ -- tls = dev.request("GET tls_library") --- if not tls.startswith("OpenSSL"): --+ if tls.startswith("OpenSSL"): --+ return --+ elif tls.startswith("mbed TLS"): --+ return --+ else: -- raise HwsimSkip("ext_cert_check not supported with this TLS library: " + tls) -- -- def check_ocsp_support(dev): --@@ -91,14 +126,18 @@ def check_ocsp_support(dev): -- # raise HwsimSkip("OCSP not supported with this TLS library: " + tls) -- #if tls.startswith("wolfSSL"): -- # raise HwsimSkip("OCSP not supported with this TLS library: " + tls) --+ if tls.startswith("mbed TLS"): --+ raise HwsimSkip("OCSP not supported with this TLS library: " + tls) -- -- def check_pkcs5_v15_support(dev): -- tls = dev.request("GET tls_library") --- if "BoringSSL" in tls or "GnuTLS" in tls: --+ if "BoringSSL" in tls or "GnuTLS" in tls or "mbed TLS" in tls: -- raise HwsimSkip("PKCS#5 v1.5 not supported with this TLS library: " + tls) -- -- def check_tls13_support(dev): -- 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): -- # 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) --+ if tls.startswith("mbed TLS"): --+ raise HwsimSkip("PKCS#12 not supported with this TLS library: " + tls) -- -- def check_dh_dsa_support(dev): -- tls = dev.request("GET tls_library") -- if tls.startswith("internal"): -- raise HwsimSkip("DH DSA not supported with this TLS library: " + tls) --+ if tls.startswith("mbed TLS"): --+ raise HwsimSkip("DH DSA not supported with this TLS library: " + tls) -- -- def check_ec_support(dev): -- tls = dev.request("GET tls_library") --@@ -1595,7 +1638,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", --- subject_match="/C=FI/O=w1.fi/CN=server.w1.fi", --+ check_cert_subject="/C=FI/O=w1.fi/CN=server.w1.fi", -- 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 -- -- def test_ap_wpa2_eap_tls_neg_subject_match(dev, apdev): -- """WPA2-Enterprise negative test - subject mismatch""" --+ check_subject_match_support(dev[0]) -- 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 -- -- def test_ap_wpa2_eap_tls_neg_altsubject_match(dev, apdev): -- """WPA2-Enterprise negative test - altsubject mismatch""" --+ check_altsubject_match_support(dev[0]) -- 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 -- dev[0].request("REMOVE_NETWORK all") -- -- tls = dev[0].request("GET tls_library") --- if not tls.startswith("wolfSSL"): --+ if not tls.startswith("wolfSSL") and not tls.startswith("mbed TLS"): -- 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 -- params["private_key"] = "auth_serv/iCA-server/server.key" -- hostapd.add_ap(apdev[0], params) -- tls = dev[0].request("GET tls_library") --- if "GnuTLS" in tls or "wolfSSL" in tls: --+ if "GnuTLS" in tls or "wolfSSL" in tls or "mbed TLS" in tls: -- 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 -- 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): --+ check_ocsp_support(dev[0]) -- 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_ -- try: -- hostapd.add_ap(apdev[0], params) -- tls = dev[0].request("GET tls_library") --- if "GnuTLS" in tls or "wolfSSL" in tls: --+ if "GnuTLS" in tls or "wolfSSL" in tls or "mbed TLS" in tls: -- 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_ -- try: -- hostapd.add_ap(apdev[0], params) -- tls = dev[0].request("GET tls_library") --- if "GnuTLS" in tls or "wolfSSL" in tls: --+ if "GnuTLS" in tls or "wolfSSL" in tls or "mbed TLS" in tls: -- 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 -- try: -- hostapd.add_ap(apdev[0], params) -- tls = dev[0].request("GET tls_library") --- if "GnuTLS" in tls or "wolfSSL" in tls: --+ if "GnuTLS" in tls or "wolfSSL" in tls or "mbed TLS" in tls: -- 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 -- -- hostapd.add_ap(apdev[0], params) -- tls = dev[0].request("GET tls_library") --- if "GnuTLS" in tls or "wolfSSL" in tls: --+ if "GnuTLS" in tls or "wolfSSL" in tls or "mbed TLS" in tls: -- 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 -- -- def test_ap_wpa2_eap_ttls_server_pkcs12(dev, apdev): -- """WPA2-Enterprise using EAP-TTLS and server PKCS#12 file""" --+ check_pkcs12_support(dev[0]) -- 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( -- -- def test_ap_wpa2_eap_ttls_server_pkcs12_extra(dev, apdev): -- """EAP-TTLS and server PKCS#12 file with extra certs""" --+ check_pkcs12_support(dev[0]) -- 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 -- -- def test_ap_wpa2_eap_ttls_dh_params_dsa_server(dev, apdev): -- """WPA2-Enterprise using EAP-TTLS and alternative server dhparams (DSA)""" --+ check_dh_dsa_support(dev[0]) -- 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 -- def test_openssl_cipher_suite_config_wpas(dev, apdev): -- """OpenSSL cipher suite configuration on wpa_supplicant""" -- tls = dev[0].request("GET tls_library") --- if not tls.startswith("OpenSSL"): --- raise HwsimSkip("TLS library is not OpenSSL: " + tls) --+ if not tls.startswith("OpenSSL") and not tls.startswith("mbed TLS"): --+ raise HwsimSkip("TLS library is not OpenSSL or mbed TLS: " + tls) -- 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 -- def test_openssl_cipher_suite_config_hapd(dev, apdev): -- """OpenSSL cipher suite configuration on hostapd""" -- tls = dev[0].request("GET tls_library") --- if not tls.startswith("OpenSSL"): --- raise HwsimSkip("wpa_supplicant TLS library is not OpenSSL: " + tls) --+ if not tls.startswith("OpenSSL") and not tls.startswith("mbed TLS"): --+ raise HwsimSkip("wpa_supplicant TLS library is not OpenSSL or mbed TLS: " + tls) -- params = int_eap_server_params() -- params['openssl_ciphers'] = "AES256" -- hapd = hostapd.add_ap(apdev[0], params) -- tls = hapd.request("GET tls_library") --- if not tls.startswith("OpenSSL"): --- raise HwsimSkip("hostapd TLS library is not OpenSSL: " + tls) --+ if not tls.startswith("OpenSSL") and not tls.startswith("mbed TLS"): --+ raise HwsimSkip("hostapd TLS library is not OpenSSL or mbed TLS: " + tls) -- 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 -- check_tls_ver(dev[0], hapd, -- "tls_disable_tlsv1_0=1 tls_disable_tlsv1_1=1", -- "TLSv1.2") --- elif tls.startswith("internal"): --+ elif tls.startswith("internal") or tls.startswith("mbed TLS"): -- check_tls_ver(dev[0], hapd, -- "tls_disable_tlsv1_0=1 tls_disable_tlsv1_1=1", "TLSv1.2") --- check_tls_ver(dev[1], hapd, --- "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 tls.startswith("mbed TLS"): --+ check_tls_ver(dev[2], hapd, --+ "tls_disable_tlsv1_0=0 tls_disable_tlsv1_1=1 tls_disable_tlsv1_2=1", "TLSv1.0") --+ else: --+ check_tls_ver(dev[1], hapd, --+ "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: -- 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 -- 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]")] --+ tls = dev[0].request("GET tls_library") --+ if tls.startswith("mbed TLS"): --+ tests = [#("TLSv1.0", "[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]")] -- for exp, flags in tests: -- hapd.disable() -- hapd.set("tls_flags", flags) --@@ -7115,6 +7173,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 --+ check_ext_cert_check_support(dev[0]) -- id = dev[0].connect("test-wpa2-eap", key_mgmt="WPA-EAP", eap="TLS", -- identity="tls user", -- ca_cert="auth_serv/ca.pem", --@@ -7127,6 +7186,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 --+ check_ext_cert_check_support(dev[0]) -- id = dev[0].connect("test-wpa2-eap", key_mgmt="WPA-EAP", eap="TTLS", -- identity="pap user", anonymous_identity="ttls", -- password="password", phase2="auth=PAP", --@@ -7137,6 +7197,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 --+ check_ext_cert_check_support(dev[0]) -- id = dev[0].connect("test-wpa2-eap", key_mgmt="WPA-EAP", eap="PEAP", -- identity="user", anonymous_identity="peap", -- ca_cert="auth_serv/ca.pem", --@@ -7147,6 +7208,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""" --+ check_ext_cert_check_support(dev[0]) -- check_eap_capa(dev[0], "FAST") -- # With internal server certificate chain validation -- dev[0].request("SET blob fast_pac_auth_ext ") --@@ -7161,10 +7223,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): --- check_ext_cert_check_support(dev[0]) --- if not openssl_imported: --- raise HwsimSkip("OpenSSL python method not available") --- -- params = hostapd.wpa2_eap_params(ssid="test-wpa2-eap") -- hapd = hostapd.add_ap(apdev[0], params) -- ----- a/tests/hwsim/test_ap_ft.py --+++ b/tests/hwsim/test_ap_ft.py --@@ -2471,11 +2471,11 @@ def test_ap_ft_ap_oom5(dev, apdev): -- # This will fail to roam -- dev[0].roam(bssid1, check_bssid=False) -- --- with fail_test(hapd1, 1, "sha256_prf_bits;wpa_pmk_r1_to_ptk;wpa_ft_process_auth_req"): --+ with fail_test(hapd1, 1, "sha256_prf;wpa_pmk_r1_to_ptk;wpa_ft_process_auth_req"): -- # This will fail to roam -- dev[0].roam(bssid1, check_bssid=False) -- --- with fail_test(hapd1, 3, "wpa_pmk_r1_to_ptk;wpa_ft_process_auth_req"): --+ with fail_test(hapd1, 2, "wpa_pmk_r1_to_ptk;wpa_ft_process_auth_req"): -- # This will fail to roam -- dev[0].roam(bssid1, check_bssid=False) -- ----- a/tests/hwsim/test_authsrv.py --+++ b/tests/hwsim/test_authsrv.py --@@ -156,9 +156,12 @@ def test_authsrv_oom(dev, apdev): -- if "FAIL" not in authsrv.request("ENABLE"): -- raise Exception("ENABLE succeeded during OOM") -- --- with alloc_fail(authsrv, 1, "tls_init;authsrv_init"): --- if "FAIL" not in authsrv.request("ENABLE"): --- raise Exception("ENABLE succeeded during OOM") --+ # tls_mbedtls.c:tls_init() does not alloc memory (no alloc fail trigger) --+ tls = dev[0].request("GET tls_library") --+ if not tls.startswith("mbed TLS"): --+ with alloc_fail(authsrv, 1, "tls_init;authsrv_init"): --+ if "FAIL" not in authsrv.request("ENABLE"): --+ raise Exception("ENABLE succeeded during OOM") -- -- for count in range(1, 3): -- with alloc_fail(authsrv, count, "eap_sim_db_init;authsrv_init"): ----- a/tests/hwsim/test_dpp.py --+++ b/tests/hwsim/test_dpp.py --@@ -39,7 +39,8 @@ def check_dpp_capab(dev, brainpool=False -- raise HwsimSkip("DPP not supported") -- if brainpool: -- tls = dev.request("GET tls_library") --- if (not tls.startswith("OpenSSL") or "run=BoringSSL" in tls) and not tls.startswith("wolfSSL"): --+ if (not tls.startswith("OpenSSL") or "run=BoringSSL" in tls) and not tls.startswith("wolfSSL") \ --+ and not tls.startswith("mbed TLS"): -- 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 -- -- def test_dpp_proto_auth_req_invalid_i_proto_key(dev, apdev): -- """DPP protocol testing - invalid I-proto key in Auth Req""" --+ tls = dev[0].request("GET tls_library") --+ if tls.startswith("mbed TLS"): --+ raise HwsimSkip("mbed TLS crypto_ecdh_set_peerkey() properly detects invalid key; no response") -- 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_ -- -- def test_dpp_proto_auth_resp_invalid_r_proto_key(dev, apdev): -- """DPP protocol testing - invalid R-Proto Key in Auth Resp""" --- run_dpp_proto_auth_resp_missing(dev, 67, "Invalid Responder Protocol Key") --+ tls = dev[0].request("GET tls_library") --+ if tls.startswith("mbed TLS"): --+ # mbed TLS crypto_ecdh_set_peerkey() properly detects invalid key --+ run_dpp_proto_auth_resp_missing(dev, 67, "Failed to derive ECDH shared secret") --+ else: --+ run_dpp_proto_auth_resp_missing(dev, 67, "Invalid Responder Protocol Key") -- -- 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 -- -- def test_dpp_proto_pkex_cr_req_invalid_bootstrap_key(dev, apdev): -- """DPP protocol testing - invalid Bootstrap Key in PKEX Commit-Reveal Request""" --+ tls = dev[0].request("GET tls_library") --+ if tls.startswith("mbed TLS"): --+ raise HwsimSkip("mbed TLS crypto_ecdh_set_peerkey() properly detects invalid key; no response") -- run_dpp_proto_pkex_req_missing(dev, 47, -- "Peer bootstrapping key is invalid") -- -- def test_dpp_proto_pkex_cr_resp_invalid_bootstrap_key(dev, apdev): -- """DPP protocol testing - invalid Bootstrap Key in PKEX Commit-Reveal Response""" --+ tls = dev[0].request("GET tls_library") --+ if tls.startswith("mbed TLS"): --+ raise HwsimSkip("mbed TLS crypto_ecdh_set_peerkey() properly detects invalid key; no response") -- run_dpp_proto_pkex_resp_missing(dev, 48, -- "Peer bootstrapping key is invalid") -- ----- a/tests/hwsim/test_erp.py --+++ b/tests/hwsim/test_erp.py --@@ -12,7 +12,7 @@ import time -- -- import hostapd -- from utils import * ---from test_ap_eap import int_eap_server_params, check_tls13_support --+from test_ap_eap import int_eap_server_params, check_tls13_support, check_eap_capa -- from test_ap_psk import find_wpas_process, read_process_memory, verify_not_present, get_key_locations -- -- def test_erp_initiate_reauth_start(dev, apdev): --@@ -276,6 +276,7 @@ def test_erp_radius_eap_methods(dev, apd -- params['erp_domain'] = 'example.com' -- params['disable_pmksa_caching'] = '1' -- hapd = hostapd.add_ap(apdev[0], params) --+ tls = dev[0].request("GET tls_library") -- -- erp_test(dev[0], hapd, eap="AKA", identity="0232010000000000@example.com", -- password="90dca4eda45b53cf0f12d7c9c3bc6a89:cb9cccc4b9258e6dca4760379fb82581:000000000123") --@@ -289,7 +290,7 @@ def test_erp_radius_eap_methods(dev, apd -- password="5122250214c33e723a5dd523fc145fc0:981d464c7c52eb6e5036234984ad0bcf:000000000123") -- erp_test(dev[0], hapd, eap="EKE", identity="erp-eke@example.com", -- password="hello") --- if "FAST" in eap_methods: --+ if "FAST" in eap_methods and check_eap_capa(dev[0], "FAST"): -- erp_test(dev[0], hapd, eap="FAST", identity="erp-fast@example.com", -- password="password", ca_cert="auth_serv/ca.pem", -- phase2="auth=GTC", --@@ -301,13 +302,14 @@ def test_erp_radius_eap_methods(dev, apd -- password="password") -- erp_test(dev[0], hapd, eap="PAX", identity="erp-pax@example.com", -- password_hex="0123456789abcdef0123456789abcdef") --- if "MSCHAPV2" in eap_methods: --+ if "MSCHAPV2" in eap_methods and check_eap_capa(dev[0], "MSCHAPV2"): -- erp_test(dev[0], hapd, eap="PEAP", identity="erp-peap@example.com", -- password="password", ca_cert="auth_serv/ca.pem", -- phase2="auth=MSCHAPV2") --- erp_test(dev[0], hapd, eap="TEAP", identity="erp-teap@example.com", --- password="password", ca_cert="auth_serv/ca.pem", --- phase2="auth=MSCHAPV2", pac_file="blob://teap_pac") --+ if check_eap_capa(dev[0], "TEAP"): --+ erp_test(dev[0], hapd, eap="TEAP", identity="erp-teap@example.com", --+ password="password", ca_cert="auth_serv/ca.pem", --+ phase2="auth=MSCHAPV2", pac_file="blob://teap_pac") -- erp_test(dev[0], hapd, eap="PSK", identity="erp-psk@example.com", -- password_hex="0123456789abcdef0123456789abcdef") -- if "PWD" in eap_methods: --@@ -640,7 +642,7 @@ def test_erp_local_errors(dev, apdev): -- dev[0].request("REMOVE_NETWORK all") -- dev[0].wait_disconnected() -- --- for count in range(1, 6): --+ for count in range(1, 4): -- dev[0].request("ERP_FLUSH") -- with fail_test(dev[0], count, "hmac_sha256_kdf;eap_peer_erp_init"): -- 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"): --+ 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") ----- 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 -- eap_connect(dev[0], hapd, "PAX", "pax.user@example.com", -- password_hex="0123456789abcdef0123456789abcdef", -- bssid=apdev[0]['bssid']) --- for i in range(1, 11): --+ for i in range(1, 10): -- 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 -- state = dev[0].request('GET_ALLOC_FAIL') -- if state.startswith('0:'): -- break --- time.sleep(0.05) --+ time.sleep(0.10) -- -- def test_pmksa_cache_ctrl(dev, apdev): -- """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): -- 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] --+ if tls.startswith("mbed TLS"): --+ # secp224k1 and secp224r1 (26) have prime p = 1 mod 4, and mbedtls --+ # does not have code to derive y from compressed format for those curves --+ sae_groups = [19, 25, 20, 21, 1, 2, 5, 14, 15, 16, 22, 23, 24] --+ sae_groups += [27, 28, 29, 30] -- heavy_groups = [14, 15, 16] -- suitable_groups = [15, 16, 17, 18, 19, 20, 21] -- groups = [str(g) for g in sae_groups] --@@ -2188,6 +2193,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") --+ elif tls.startswith("mbed TLS"): --+ logger.info("Make sure Brainpool EC groups were enabled when compiling mbed TLS") -- else: -- raise HwsimSkip("Brainpool curve not supported") -- start_sae_pwe_ap(apdev[0], group, 2) ----- a/tests/hwsim/test_suite_b.py --+++ b/tests/hwsim/test_suite_b.py --@@ -27,6 +27,8 @@ def check_suite_b_tls_lib(dev, dhe=False -- return -- if tls.startswith("wolfSSL"): -- return --+ if tls.startswith("mbed TLS"): --+ return -- if not tls.startswith("OpenSSL"): -- raise HwsimSkip("TLS library not supported for Suite B: " + tls) -- supported = False --@@ -520,6 +522,7 @@ def test_suite_b_192_rsa_insufficient_dh -- -- dev[0].connect("test-suite-b", key_mgmt="WPA-EAP-SUITE-B-192", -- ieee80211w="2", --+ openssl_ciphers="DHE-RSA-AES256-GCM-SHA384", -- phase1="tls_suiteb=1", -- eap="TLS", identity="tls user", -- ca_cert="auth_serv/rsa3072-ca.pem", ----- a/tests/hwsim/test_wpas_ctrl.py --+++ b/tests/hwsim/test_wpas_ctrl.py --@@ -1842,7 +1842,7 @@ def _test_wpas_ctrl_oom(dev): -- tls = dev[0].request("GET tls_library") -- if not tls.startswith("internal"): -- tests.append(('NFC_GET_HANDOVER_SEL NDEF P2P-CR-TAG', 'FAIL', --- 4, 'wpas_ctrl_nfc_get_handover_sel_p2p')) --+ 3, 'wpas_ctrl_nfc_get_handover_sel_p2p')) -- for cmd, exp, count, func in tests: -- with alloc_fail(dev[0], count, func): -- 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): -- -- def check_tls_tod(dev): -- tls = dev.request("GET tls_library") --- if not tls.startswith("OpenSSL") and not tls.startswith("internal"): --+ if tls.startswith("OpenSSL"): --+ return --+ elif tls.startswith("internal"): --+ return --+ elif tls.startswith("mbed TLS"): --+ return --+ else: -- raise HwsimSkip("TLS TOD-TOFU/STRICT not supported with this TLS library: " + tls) -- -- def vht_supported(): ----- /dev/null --+++ b/tests/test-crypto_module.c --@@ -0,0 +1,16 @@ --+/* --+ * crypto module tests - test program --+ * Copyright (c) 2022, Glenn Strauss --+ * --+ * This software may be distributed under the terms of the BSD license. --+ * See README for more details. --+ */ --+ --+#include "utils/includes.h" --+#include "utils/module_tests.h" --+#include "crypto/crypto_module_tests.c" --+ --+int main(int argc, char *argv[]) --+{ --+ return crypto_module_tests(); --+} ----- a/tests/test-https.c --+++ b/tests/test-https.c --@@ -75,7 +75,7 @@ static int https_client(int s, const cha -- struct tls_connection *conn; -- struct wpabuf *in, *out, *appl; -- int res = -1; --- int need_more_data; --+ int need_more_data = 0; -- -- os_memset(&conf, 0, sizeof(conf)); -- conf.event_cb = https_tls_event_cb; --@@ -93,8 +93,12 @@ static int https_client(int s, const cha -- -- for (;;) { -- appl = NULL; --+#ifdef CONFIG_TLS_INTERNAL_SERVER -- out = tls_connection_handshake2(tls, conn, in, &appl, -- &need_more_data); --+#else --+ out = tls_connection_handshake(tls, conn, in, &appl); --+#endif -- wpabuf_free(in); -- in = NULL; -- if (out == NULL) { --@@ -152,11 +156,15 @@ static int https_client(int s, const cha -- -- wpa_printf(MSG_INFO, "Reading HTTP response"); -- for (;;) { --- int need_more_data; --+ int need_more_data = 0; -- in = https_recv(s); -- if (in == NULL) -- goto done; --+#ifdef CONFIG_TLS_INTERNAL_SERVER -- out = tls_connection_decrypt2(tls, conn, in, &need_more_data); --+#else --+ out = tls_connection_decrypt(tls, conn, in); --+#endif -- if (need_more_data) -- wpa_printf(MSG_DEBUG, "HTTP: Need more data"); -- wpabuf_free(in); ----- a/tests/test-https_server.c --+++ b/tests/test-https_server.c --@@ -67,10 +67,12 @@ static struct wpabuf * https_recv(int s, -- } -- -- --+#ifdef CONFIG_TLS_INTERNAL_SERVER -- static void https_tls_log_cb(void *ctx, const char *msg) -- { -- wpa_printf(MSG_DEBUG, "TLS: %s", msg); -- } --+#endif -- -- -- static int https_server(int s) --@@ -79,7 +81,7 @@ static int https_server(int s) -- void *tls; -- struct tls_connection_params params; -- struct tls_connection *conn; --- struct wpabuf *in, *out, *appl; --+ struct wpabuf *in = NULL, *out = NULL, *appl = NULL; -- int res = -1; -- -- os_memset(&conf, 0, sizeof(conf)); --@@ -106,7 +108,9 @@ static int https_server(int s) -- return -1; -- } -- --+#ifdef CONFIG_TLS_INTERNAL_SERVER -- tls_connection_set_log_cb(conn, https_tls_log_cb, NULL); --+#endif -- -- for (;;) { -- in = https_recv(s, 5000); --@@ -147,12 +151,16 @@ static int https_server(int s) -- -- wpa_printf(MSG_INFO, "Reading HTTP request"); -- for (;;) { --- int need_more_data; --+ int need_more_data = 0; -- -- in = https_recv(s, 5000); -- if (!in) -- goto done; --+#ifdef CONFIG_TLS_INTERNAL_SERVER -- out = tls_connection_decrypt2(tls, conn, in, &need_more_data); --+#else --+ out = tls_connection_decrypt(tls, conn, in); --+#endif -- wpabuf_free(in); -- in = NULL; -- if (need_more_data) { ----- a/wpa_supplicant/Makefile --+++ b/wpa_supplicant/Makefile --@@ -1122,6 +1122,7 @@ CFLAGS += -DCONFIG_TLSV12 -- endif -- -- ifeq ($(CONFIG_TLS), wolfssl) --+CFLAGS += -DCONFIG_TLS_WOLFSSL -- ifdef TLS_FUNCS -- CFLAGS += -DWOLFSSL_DER_LOAD -- OBJS += ../src/crypto/tls_wolfssl.o --@@ -1137,6 +1138,7 @@ LIBS_p += -lwolfssl -lm -- endif -- -- ifeq ($(CONFIG_TLS), openssl) --+CFLAGS += -DCONFIG_TLS_OPENSSL -- CFLAGS += -DCRYPTO_RSA_OAEP_SHA256 -- ifdef TLS_FUNCS -- CFLAGS += -DEAP_TLS_OPENSSL --@@ -1164,6 +1166,7 @@ CFLAGS += -DTLS_DEFAULT_CIPHERS=\"$(CONF -- endif -- -- ifeq ($(CONFIG_TLS), mbedtls) --+CFLAGS += -DCONFIG_TLS_MBEDTLS -- ifndef CONFIG_CRYPTO -- CONFIG_CRYPTO=mbedtls -- endif --@@ -1183,6 +1186,7 @@ endif -- endif -- -- ifeq ($(CONFIG_TLS), gnutls) --+CFLAGS += -DCONFIG_TLS_GNUTLS -- ifndef CONFIG_CRYPTO -- # default to libgcrypt -- CONFIG_CRYPTO=gnutls --@@ -1213,6 +1217,7 @@ endif -- endif -- -- ifeq ($(CONFIG_TLS), internal) --+CFLAGS += -DCONFIG_TLS_INTERNAL -- ifndef CONFIG_CRYPTO -- CONFIG_CRYPTO=internal -- endif --@@ -1293,6 +1298,7 @@ endif -- endif -- -- ifeq ($(CONFIG_TLS), linux) --+CFLAGS += -DCONFIG_TLS_INTERNAL -- OBJS += ../src/crypto/crypto_linux.o -- OBJS_p += ../src/crypto/crypto_linux.o -- ifdef TLS_FUNCS -diff --git a/package/network/services/hostapd/patches/150-add-NULL-checks-encountered-during-tests-hwsim.patch b/package/network/services/hostapd/patches/150-add-NULL-checks-encountered-during-tests-hwsim.patch -deleted file mode 100644 -index c8c3ff33f4..0000000000 ---- a/package/network/services/hostapd/patches/150-add-NULL-checks-encountered-during-tests-hwsim.patch -+++ /dev/null -@@ -1,45 +0,0 @@ --From 33afce36c54b0cad38643629ded10ff5d727f077 Mon Sep 17 00:00:00 2001 --From: Glenn Strauss --Date: Fri, 12 Aug 2022 05:34:47 -0400 --Subject: [PATCH 5/7] add NULL checks (encountered during tests/hwsim) -- --sae_derive_commit_element_ecc NULL pwe_ecc check --dpp_gen_keypair() NULL curve check -- --Signed-off-by: Glenn Strauss ----- -- src/common/dpp_crypto.c | 6 ++++++ -- src/common/sae.c | 7 +++++++ -- 2 files changed, 13 insertions(+) -- ----- a/src/common/dpp_crypto.c --+++ b/src/common/dpp_crypto.c --@@ -269,6 +269,12 @@ int dpp_get_pubkey_hash(struct crypto_ec -- -- struct crypto_ec_key * dpp_gen_keypair(const struct dpp_curve_params *curve) -- { --+ if (curve == NULL) { --+ wpa_printf(MSG_DEBUG, --+ "DPP: %s curve must be initialized", __func__); --+ return NULL; --+ } --+ -- struct crypto_ec_key *key; -- -- wpa_printf(MSG_DEBUG, "DPP: Generating a keypair"); ----- a/src/common/sae.c --+++ b/src/common/sae.c --@@ -1278,6 +1278,13 @@ void sae_deinit_pt(struct sae_pt *pt) -- static int sae_derive_commit_element_ecc(struct sae_data *sae, -- struct crypto_bignum *mask) -- { --+ if (sae->tmp->pwe_ecc == NULL) { --+ wpa_printf(MSG_DEBUG, --+ "SAE: %s sae->tmp->pwe_ecc must be initialized", --+ __func__); --+ return -1; --+ } --+ -- /* COMMIT-ELEMENT = inverse(scalar-op(mask, PWE)) */ -- if (!sae->tmp->own_commit_element_ecc) { -- sae->tmp->own_commit_element_ecc = -diff --git a/package/network/services/hostapd/patches/160-dpp_pkex-EC-point-mul-w-value-prime.patch b/package/network/services/hostapd/patches/160-dpp_pkex-EC-point-mul-w-value-prime.patch -deleted file mode 100644 -index db4fcfe235..0000000000 ---- a/package/network/services/hostapd/patches/160-dpp_pkex-EC-point-mul-w-value-prime.patch -+++ /dev/null -@@ -1,26 +0,0 @@ --From 54211caa2e0e5163aefef390daf88a971367a702 Mon Sep 17 00:00:00 2001 --From: Glenn Strauss --Date: Tue, 4 Oct 2022 17:09:24 -0400 --Subject: [PATCH 6/7] dpp_pkex: EC point mul w/ value < prime -- --crypto_ec_point_mul() with mbedtls requires point --be multiplied by a multiplicand with value < prime -- --Signed-off-by: Glenn Strauss ----- -- src/common/dpp_crypto.c | 4 +++- -- 1 file changed, 3 insertions(+), 1 deletion(-) -- ----- a/src/common/dpp_crypto.c --+++ b/src/common/dpp_crypto.c --@@ -1588,7 +1588,9 @@ dpp_pkex_derive_Qr(const struct dpp_curv -- Pr = crypto_ec_key_get_public_key(Pr_key); -- Qr = crypto_ec_point_init(ec); -- hash_bn = crypto_bignum_init_set(hash, curve->hash_len); --- if (!Pr || !Qr || !hash_bn || crypto_ec_point_mul(ec, Pr, hash_bn, Qr)) --+ if (!Pr || !Qr || !hash_bn || --+ crypto_bignum_mod(hash_bn, crypto_ec_get_prime(ec), hash_bn) || --+ crypto_ec_point_mul(ec, Pr, hash_bn, Qr)) -- goto fail; -- -- if (crypto_ec_point_is_at_infinity(ec, Qr)) { -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 -deleted file mode 100644 -index 710a3c851e..0000000000 ---- a/package/network/services/hostapd/patches/170-hostapd-update-cfs0-and-cfs1-for-160MHz.patch -+++ /dev/null -@@ -1,141 +0,0 @@ --From d4c4ef302f98fd6bce173b8636e7e350d8b44981 Mon Sep 17 00:00:00 2001 --From: P Praneesh --Date: Fri, 19 Mar 2021 12:17:27 +0530 --Subject: [PATCH] hostapd: update cfs0 and cfs1 for 160MHz -- --As per standard Draft P802.11ax_D8.0,( Table 26-9—Setting --of the VHT Channel Width and VHT NSS at an HE STA --transmitting the OM Control subfield ), center frequency of --160MHz should be published in HT information subset 2 of --HT information when EXT NSS BW field is enabled. -- --If the supported number of NSS in 160MHz is at least max NSS --support, then center_freq_seg0 indicates the center frequency of 80MHz and --center_freq_seg1 indicates the center frequency of 160MHz. -- --If the supported number of NSS in 160MHz is less than max NSS --support, then center_freq_seg0 indicates the center frequency of 80MHz and --center_freq_seg1 is 0. The center frequency of 160MHz is published in HT --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/common/hw_features_common.c | 1 + -- src/common/ieee802_11_defs.h | 1 + -- 5 files changed, 27 insertions(+) -- ----- a/hostapd/config_file.c --+++ b/hostapd/config_file.c --@@ -1153,6 +1153,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; --+ if (os_strstr(capab, "[EXT-NSS-BW-SUPP]")) --+ conf->vht_capab |= VHT_CAP_EXTENDED_NSS_BW_SUPPORT; -- return 0; -- } -- #endif /* CONFIG_IEEE80211AC */ ----- a/src/ap/ieee802_11_ht.c --+++ b/src/ap/ieee802_11_ht.c --@@ -82,7 +82,9 @@ u8 * hostapd_eid_ht_capabilities(struct -- u8 * hostapd_eid_ht_operation(struct hostapd_data *hapd, u8 *eid) -- { -- struct ieee80211_ht_operation *oper; --+ le32 vht_capabilities_info; -- u8 *pos = eid; --+ u8 chwidth; -- -- if (!hapd->iconf->ieee80211n || hapd->conf->disable_11n || -- is_6ghz_op_class(hapd->iconf->op_class)) --@@ -103,6 +105,13 @@ u8 * hostapd_eid_ht_operation(struct hos -- oper->ht_param |= HT_INFO_HT_PARAM_SECONDARY_CHNL_BELOW | -- HT_INFO_HT_PARAM_STA_CHNL_WIDTH; -- --+ vht_capabilities_info = host_to_le32(hapd->iface->current_mode->vht_capab); --+ chwidth = hostapd_get_oper_chwidth(hapd->iconf); --+ if (vht_capabilities_info & VHT_CAP_EXTENDED_NSS_BW_SUPPORT --+ && ((chwidth == CHANWIDTH_160MHZ) || (chwidth == CHANWIDTH_80P80MHZ))) { --+ oper->operation_mode = host_to_le16(hapd->iconf->vht_oper_centr_freq_seg0_idx << 5); --+ } --+ -- pos += sizeof(*oper); -- -- 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 -- struct ieee80211_vht_capabilities *cap; -- struct hostapd_hw_modes *mode = hapd->iface->current_mode; -- u8 *pos = eid; --+ u8 chwidth; -- -- if (!mode || is_6ghz_op_class(hapd->iconf->op_class)) -- return eid; --@@ -62,6 +63,17 @@ u8 * hostapd_eid_vht_capabilities(struct -- host_to_le32(nsts << VHT_CAP_BEAMFORMEE_STS_OFFSET); -- } -- --+ chwidth = hostapd_get_oper_chwidth(hapd->iconf); --+ if (((host_to_le32(mode->vht_capab)) & VHT_CAP_EXTENDED_NSS_BW_SUPPORT) --+ && ((chwidth == CHANWIDTH_160MHZ) || (chwidth == CHANWIDTH_80P80MHZ))) { --+ cap->vht_capabilities_info |= VHT_CAP_EXTENDED_NSS_BW_SUPPORT; --+ cap->vht_capabilities_info &= ~(host_to_le32(VHT_CAP_SUPP_CHAN_WIDTH_160_80PLUS80MHZ)); --+ cap->vht_capabilities_info &= ~(host_to_le32(VHT_CAP_SUPP_CHAN_WIDTH_160MHZ)); --+ cap->vht_capabilities_info &= ~(host_to_le32(VHT_CAP_SUPP_CHAN_WIDTH_MASK)); --+ } else { --+ cap->vht_capabilities_info &= ~VHT_CAP_EXTENDED_NSS_BW_SUPPORT_MASK; --+ } --+ -- /* 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 -- u8 * hostapd_eid_vht_operation(struct hostapd_data *hapd, u8 *eid) -- { -- struct ieee80211_vht_operation *oper; --+ le32 vht_capabilities_info; -- 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 -- oper->vht_op_info_chan_center_freq_seg1_idx = seg1; -- -- oper->vht_op_info_chwidth = oper_chwidth; --+ vht_capabilities_info = host_to_le32(hapd->iface->current_mode->vht_capab); -- 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 -- oper->vht_op_info_chan_center_freq_seg0_idx -= 8; -- else -- oper->vht_op_info_chan_center_freq_seg0_idx += 8; --+ --+ if (vht_capabilities_info & VHT_CAP_EXTENDED_NSS_BW_SUPPORT) --+ oper->vht_op_info_chan_center_freq_seg1_idx = 0; -- } else if (oper_chwidth == CONF_OPER_CHWIDTH_80P80MHZ) { -- /* -- * 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 --@@ -808,6 +808,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); --+ VHT_CAP_CHECK(VHT_CAP_EXTENDED_NSS_BW_SUPPORT); -- -- #undef VHT_CAP_CHECK -- #undef VHT_CAP_CHECK_MAX ----- a/src/common/ieee802_11_defs.h --+++ b/src/common/ieee802_11_defs.h --@@ -1348,6 +1348,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)) --+#define VHT_CAP_EXTENDED_NSS_BW_SUPPORT ((u32) BIT(30)) --+#define VHT_CAP_EXTENDED_NSS_BW_SUPPORT_MASK ((u32) BIT(30) | BIT(31)) -- -- #define VHT_OPMODE_CHANNEL_WIDTH_MASK ((u8) BIT(0) | BIT(1)) -- #define VHT_OPMODE_CHANNEL_RxNSS_MASK ((u8) BIT(4) | BIT(5) | \ -diff --git a/package/network/services/hostapd/patches/200-multicall.patch b/package/network/services/hostapd/patches/200-multicall.patch -deleted file mode 100644 -index f7e797a9c8..0000000000 ---- a/package/network/services/hostapd/patches/200-multicall.patch -+++ /dev/null -@@ -1,355 +0,0 @@ ----- a/hostapd/Makefile --+++ b/hostapd/Makefile --@@ -1,6 +1,7 @@ -- ALL=hostapd hostapd_cli -- CONFIG_FILE = .config -- --+-include $(if $(MULTICALL), ../wpa_supplicant/.config) -- include ../src/build.rules -- -- ifdef LIBS --@@ -199,7 +200,8 @@ endif -- -- ifdef CONFIG_NO_VLAN -- CFLAGS += -DCONFIG_NO_VLAN ---else --+endif --+ifneq ($(findstring CONFIG_NO_VLAN,$(CFLAGS)), CONFIG_NO_VLAN) -- OBJS += ../src/ap/vlan_init.o -- OBJS += ../src/ap/vlan_ifconfig.o -- OBJS += ../src/ap/vlan.o --@@ -357,10 +359,14 @@ CFLAGS += -DCONFIG_MBO -- OBJS += ../src/ap/mbo_ap.o -- endif -- --+ifndef MULTICALL --+CFLAGS += -DNO_SUPPLICANT --+endif --+ -- include ../src/drivers/drivers.mak ---OBJS += $(DRV_AP_OBJS) ---CFLAGS += $(DRV_AP_CFLAGS) ---LDFLAGS += $(DRV_AP_LDFLAGS) --+OBJS += $(sort $(DRV_AP_OBJS) $(if $(MULTICALL),$(DRV_WPA_OBJS))) --+CFLAGS += $(DRV_AP_CFLAGS) $(if $(MULTICALL),$(DRV_WPA_CFLAGS)) --+LDFLAGS += $(DRV_AP_LDFLAGS) $(if $(MULTICALL),$(DRV_WPA_LDFLAGS)) -- LIBS += $(DRV_AP_LIBS) -- -- ifdef CONFIG_L2_PACKET --@@ -1380,6 +1386,12 @@ install: $(addprefix $(DESTDIR)$(BINDIR) -- _OBJS_VAR := OBJS -- include ../src/objs.mk -- --+hostapd_multi.a: $(BCHECK) $(OBJS) --+ $(Q)$(CC) -c -o hostapd_multi.o -Dmain=hostapd_main $(CFLAGS) main.c --+ @$(E) " CC " $< --+ @rm -f $@ --+ @$(AR) cr $@ hostapd_multi.o $(OBJS) --+ -- hostapd: $(OBJS) -- $(Q)$(CC) $(LDFLAGS) -o hostapd $(OBJS) $(LIBS) -- @$(E) " LD " $@ --@@ -1460,6 +1472,12 @@ include ../src/objs.mk -- _OBJS_VAR := SOBJS -- include ../src/objs.mk -- --+dump_cflags: --+ @printf "%s " "$(CFLAGS)" --+ --+dump_ldflags: --+ @printf "%s " "$(LDFLAGS) $(LIBS) $(EXTRALIBS)" --+ -- nt_password_hash: $(NOBJS) -- $(Q)$(CC) $(LDFLAGS) -o nt_password_hash $(NOBJS) $(LIBS_n) -- @$(E) " LD " $@ ----- a/wpa_supplicant/Makefile --+++ b/wpa_supplicant/Makefile --@@ -10,6 +10,7 @@ ALL += dbus/fi.w1.wpa_supplicant1.servic -- EXTRA_TARGETS=dynamic_eap_methods -- -- CONFIG_FILE=.config --+-include $(if $(MULTICALL),../hostapd/.config) -- include ../src/build.rules -- -- ifdef CONFIG_BUILD_PASN_SO --@@ -382,7 +383,9 @@ endif -- ifdef CONFIG_IBSS_RSN -- NEED_RSN_AUTHENTICATOR=y -- CFLAGS += -DCONFIG_IBSS_RSN --+ifndef MULTICALL -- CFLAGS += -DCONFIG_NO_VLAN --+endif -- OBJS += ibss_rsn.o -- endif -- --@@ -924,6 +927,10 @@ ifdef CONFIG_DYNAMIC_EAP_METHODS -- CFLAGS += -DCONFIG_DYNAMIC_EAP_METHODS -- LIBS += -ldl -rdynamic -- endif --+else --+ ifdef MULTICALL --+ OBJS += ../src/eap_common/eap_common.o --+ endif -- endif -- -- ifdef CONFIG_AP --@@ -931,9 +938,11 @@ NEED_EAP_COMMON=y -- NEED_RSN_AUTHENTICATOR=y -- CFLAGS += -DCONFIG_AP -- OBJS += ap.o --+ifndef MULTICALL -- CFLAGS += -DCONFIG_NO_RADIUS -- CFLAGS += -DCONFIG_NO_ACCOUNTING -- CFLAGS += -DCONFIG_NO_VLAN --+endif -- OBJS += ../src/ap/hostapd.o -- OBJS += ../src/ap/wpa_auth_glue.o -- OBJS += ../src/ap/utils.o --@@ -1022,6 +1031,12 @@ endif -- ifdef CONFIG_HS20 -- OBJS += ../src/ap/hs20.o -- endif --+else --+ ifdef MULTICALL --+ OBJS += ../src/eap_server/eap_server.o --+ OBJS += ../src/eap_server/eap_server_identity.o --+ OBJS += ../src/eap_server/eap_server_methods.o --+ endif -- endif -- -- ifdef CONFIG_MBO --@@ -1030,7 +1045,9 @@ CFLAGS += -DCONFIG_MBO -- endif -- -- ifdef NEED_RSN_AUTHENTICATOR --+ifndef MULTICALL -- CFLAGS += -DCONFIG_NO_RADIUS --+endif -- 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) -- -- _OBJS_VAR := OBJS -- include ../src/objs.mk --+wpa_supplicant_multi.a: .config $(BCHECK) $(OBJS) $(EXTRA_progs) --+ $(Q)$(CC) -c -o wpa_supplicant_multi.o -Dmain=wpa_supplicant_main $(CFLAGS) main.c --+ @$(E) " CC " $< --+ @rm -f $@ --+ @$(AR) cr $@ wpa_supplicant_multi.o $(OBJS) --+ -- 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) -- $(Q)sed -e 's|\@BINDIR\@|$(BINDIR)|g' $< >$@ -- @$(E) " sed" $< -- --+dump_cflags: --+ @printf "%s " "$(CFLAGS)" --+ --+dump_ldflags: --+ @printf "%s " "$(LDFLAGS) $(LIBS) $(EXTRALIBS)" --+ -- wpa_supplicant.exe: wpa_supplicant -- mv -f $< $@ -- wpa_cli.exe: wpa_cli ----- a/src/drivers/driver.h --+++ b/src/drivers/driver.h --@@ -6651,8 +6651,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 --@@ -6664,7 +6664,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/ap/drv_callbacks.c --+++ b/src/ap/drv_callbacks.c --@@ -1994,8 +1994,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; -- #ifndef CONFIG_NO_STDOUT_DEBUG --@@ -2271,7 +2271,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/wpa_supplicant/wpa_priv.c --+++ b/wpa_supplicant/wpa_priv.c --@@ -1039,8 +1039,8 @@ static void wpa_priv_send_ft_response(st -- } -- -- ---void wpa_supplicant_event(void *ctx, enum wpa_event_type event, --- union wpa_event_data *data) --+static void supplicant_event(void *ctx, enum wpa_event_type event, --+ union wpa_event_data *data) -- { -- struct wpa_priv_interface *iface = ctx; -- --@@ -1103,7 +1103,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_priv_global *global = ctx; --@@ -1217,6 +1217,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; -- wpa_priv_fd_workaround(); -- -- os_memset(&global, 0, sizeof(global)); ----- a/wpa_supplicant/events.c --+++ b/wpa_supplicant/events.c --@@ -5345,8 +5345,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; --@@ -6264,7 +6264,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 --@@ -7435,7 +7435,6 @@ struct wpa_interface * wpa_supplicant_ma -- return NULL; -- } -- --- -- /** -- * wpa_supplicant_match_existing - Match existing interfaces -- * @global: Pointer to global data from wpa_supplicant_init() --@@ -7470,6 +7469,11 @@ static int wpa_supplicant_match_existing -- -- #endif /* CONFIG_MATCH_IFACE */ -- --+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); -- -- /** -- * wpa_supplicant_add_iface - Add a new network interface --@@ -7726,6 +7730,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 */ --+ wpa_supplicant_event = supplicant_event; --+ wpa_supplicant_event_global = supplicant_event_global; -- -- if (params->wpa_debug_file_path) -- wpa_debug_open_file(params->wpa_debug_file_path); ----- a/hostapd/main.c --+++ b/hostapd/main.c --@@ -685,6 +685,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) --@@ -778,6 +783,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/300-noscan.patch b/package/network/services/hostapd/patches/300-noscan.patch -deleted file mode 100644 -index 1ea89043e8..0000000000 ---- a/package/network/services/hostapd/patches/300-noscan.patch -+++ /dev/null -@@ -1,58 +0,0 @@ ----- a/hostapd/config_file.c --+++ b/hostapd/config_file.c --@@ -3448,6 +3448,10 @@ static int hostapd_config_fill(struct ho -- if (bss->ocv && !bss->ieee80211w) -- bss->ieee80211w = 1; -- #endif /* CONFIG_OCV */ --+ } else if (os_strcmp(buf, "noscan") == 0) { --+ conf->noscan = atoi(pos); --+ } else if (os_strcmp(buf, "ht_coex") == 0) { --+ conf->no_ht_coex = !atoi(pos); -- } else if (os_strcmp(buf, "ieee80211n") == 0) { -- conf->ieee80211n = atoi(pos); -- } else if (os_strcmp(buf, "ht_capab") == 0) { ----- a/src/ap/ap_config.h --+++ b/src/ap/ap_config.h --@@ -1072,6 +1072,8 @@ struct hostapd_config { -- -- int ht_op_mode_fixed; -- u16 ht_capab; --+ int noscan; --+ int no_ht_coex; -- int ieee80211n; -- int secondary_channel; -- int no_pri_sec_switch; ----- a/src/ap/hw_features.c --+++ b/src/ap/hw_features.c --@@ -517,7 +517,8 @@ static int ieee80211n_check_40mhz(struct -- int ret; -- -- /* Check that HT40 is used and PRI / SEC switch is allowed */ --- if (!iface->conf->secondary_channel || iface->conf->no_pri_sec_switch) --+ if (!iface->conf->secondary_channel || iface->conf->no_pri_sec_switch || --+ iface->conf->noscan) -- return 0; -- -- hostapd_set_state(iface, HAPD_IFACE_HT_SCAN); ----- a/src/ap/ieee802_11_ht.c --+++ b/src/ap/ieee802_11_ht.c --@@ -239,6 +239,9 @@ void hostapd_2040_coex_action(struct hos -- return; -- } -- --+ if (iface->conf->noscan || iface->conf->no_ht_coex) --+ return; --+ -- if (len < IEEE80211_HDRLEN + 2 + sizeof(*bc_ie)) { -- wpa_printf(MSG_DEBUG, -- "Ignore too short 20/40 BSS Coexistence Management frame"); --@@ -399,6 +402,9 @@ void ht40_intolerant_add(struct hostapd_ -- if (iface->current_mode->mode != HOSTAPD_MODE_IEEE80211G) -- return; -- --+ if (iface->conf->noscan || iface->conf->no_ht_coex) --+ return; --+ -- wpa_printf(MSG_INFO, "HT: Forty MHz Intolerant is set by STA " MACSTR -- " in Association Request", MAC2STR(sta->addr)); -- -diff --git a/package/network/services/hostapd/patches/301-mesh-noscan.patch b/package/network/services/hostapd/patches/301-mesh-noscan.patch -deleted file mode 100644 -index 6b5416f0ea..0000000000 ---- a/package/network/services/hostapd/patches/301-mesh-noscan.patch -+++ /dev/null -@@ -1,71 +0,0 @@ ----- a/wpa_supplicant/config.c --+++ b/wpa_supplicant/config.c --@@ -2600,6 +2600,7 @@ static const struct parse_data ssid_fiel -- #else /* CONFIG_MESH */ -- { INT_RANGE(mode, 0, 4) }, -- #endif /* CONFIG_MESH */ --+ { INT_RANGE(noscan, 0, 1) }, -- { INT_RANGE(proactive_key_caching, 0, 1) }, -- { INT_RANGE(disabled, 0, 2) }, -- { STR(id_str) }, ----- a/wpa_supplicant/config_file.c --+++ b/wpa_supplicant/config_file.c --@@ -775,6 +775,7 @@ static void wpa_config_write_network(FIL -- #endif /* IEEE8021X_EAPOL */ -- INT(mode); -- INT(no_auto_peer); --+ INT(noscan); -- INT(mesh_fwding); -- INT(frequency); -- INT(enable_edmg); ----- a/wpa_supplicant/mesh.c --+++ b/wpa_supplicant/mesh.c --@@ -506,6 +506,8 @@ static int wpa_supplicant_mesh_init(stru -- frequency); -- goto out_free; -- } --+ if (ssid->noscan) --+ conf->noscan = 1; -- -- if (ssid->mesh_basic_rates == NULL) { -- /* ----- a/wpa_supplicant/wpa_supplicant.c --+++ b/wpa_supplicant/wpa_supplicant.c --@@ -2710,7 +2710,7 @@ static bool ibss_mesh_can_use_vht(struct -- const struct wpa_ssid *ssid, -- struct hostapd_hw_modes *mode) -- { --- if (mode->mode != HOSTAPD_MODE_IEEE80211A) --+ if (mode->mode != HOSTAPD_MODE_IEEE80211A && !(ssid->noscan)) -- return false; -- -- if (!drv_supports_vht(wpa_s, ssid)) --@@ -2783,7 +2783,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, 36, 44, 52, 60, 100, 108, 116, 124, 132, 149, 157, 165, 173, -- 184, 192 -- }; -- int ht40 = -1; --@@ -3033,7 +3033,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 dfs_enabled = wpa_s->conf->country[0] && (wpa_s->drv_flags & WPA_DRIVER_FLAGS_RADAR); ----- 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 -deleted file mode 100644 -index a47546d38f..0000000000 ---- a/package/network/services/hostapd/patches/310-rescan_immediately.patch -+++ /dev/null -@@ -1,11 +0,0 @@ ----- a/wpa_supplicant/wpa_supplicant.c --+++ b/wpa_supplicant/wpa_supplicant.c --@@ -5740,7 +5740,7 @@ wpa_supplicant_alloc(struct wpa_supplica -- if (wpa_s == NULL) -- return NULL; -- wpa_s->scan_req = INITIAL_SCAN_REQ; --- wpa_s->scan_interval = 5; --+ wpa_s->scan_interval = 1; -- wpa_s->new_connection = 1; -- wpa_s->parent = parent ? parent : wpa_s; -- wpa_s->p2pdev = wpa_s->parent; -diff --git a/package/network/services/hostapd/patches/320-optional_rfkill.patch b/package/network/services/hostapd/patches/320-optional_rfkill.patch -deleted file mode 100644 -index 01537790e0..0000000000 ---- a/package/network/services/hostapd/patches/320-optional_rfkill.patch -+++ /dev/null -@@ -1,61 +0,0 @@ ----- a/src/drivers/drivers.mak --+++ b/src/drivers/drivers.mak --@@ -54,7 +54,6 @@ NEED_SME=y -- NEED_AP_MLME=y -- NEED_NETLINK=y -- NEED_LINUX_IOCTL=y ---NEED_RFKILL=y -- NEED_RADIOTAP=y -- NEED_LIBNL=y -- endif --@@ -111,7 +110,6 @@ DRV_WPA_CFLAGS += -DCONFIG_DRIVER_WEXT -- CONFIG_WIRELESS_EXTENSION=y -- NEED_NETLINK=y -- NEED_LINUX_IOCTL=y ---NEED_RFKILL=y -- endif -- -- ifdef CONFIG_DRIVER_NDIS --@@ -137,7 +135,6 @@ endif -- ifdef CONFIG_WIRELESS_EXTENSION -- DRV_WPA_CFLAGS += -DCONFIG_WIRELESS_EXTENSION -- DRV_WPA_OBJS += ../src/drivers/driver_wext.o ---NEED_RFKILL=y -- endif -- -- ifdef NEED_NETLINK --@@ -146,6 +143,7 @@ endif -- -- ifdef NEED_RFKILL -- DRV_OBJS += ../src/drivers/rfkill.o --+DRV_WPA_CFLAGS += -DCONFIG_RFKILL -- endif -- -- ifdef NEED_RADIOTAP ----- a/src/drivers/rfkill.h --+++ b/src/drivers/rfkill.h --@@ -18,8 +18,24 @@ struct rfkill_config { -- void (*unblocked_cb)(void *ctx); -- }; -- --+#ifdef CONFIG_RFKILL -- struct rfkill_data * rfkill_init(struct rfkill_config *cfg); -- void rfkill_deinit(struct rfkill_data *rfkill); -- int rfkill_is_blocked(struct rfkill_data *rfkill); --+#else --+static inline struct rfkill_data * rfkill_init(struct rfkill_config *cfg) --+{ --+ return (void *) 1; --+} --+ --+static inline void rfkill_deinit(struct rfkill_data *rfkill) --+{ --+} --+ --+static inline int rfkill_is_blocked(struct rfkill_data *rfkill) --+{ --+ return 0; --+} --+#endif -- -- #endif /* RFKILL_H */ -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 -deleted file mode 100644 -index c11c957216..0000000000 ---- a/package/network/services/hostapd/patches/330-nl80211_fix_set_freq.patch -+++ /dev/null -@@ -1,11 +0,0 @@ ----- a/src/drivers/driver_nl80211.c --+++ b/src/drivers/driver_nl80211.c --@@ -5407,7 +5407,7 @@ static int nl80211_set_channel(struct i8 -- freq->he_enabled, freq->eht_enabled, freq->bandwidth, -- freq->center_freq1, freq->center_freq2); -- --- msg = nl80211_drv_msg(drv, 0, set_chan ? NL80211_CMD_SET_CHANNEL : --+ msg = nl80211_bss_msg(bss, 0, set_chan ? NL80211_CMD_SET_CHANNEL : -- NL80211_CMD_SET_WIPHY); -- if (!msg || nl80211_put_freq_params(msg, freq) < 0) { -- nlmsg_free(msg); -diff --git a/package/network/services/hostapd/patches/340-reload_freq_change.patch b/package/network/services/hostapd/patches/340-reload_freq_change.patch -deleted file mode 100644 -index ae6cd81ea4..0000000000 ---- a/package/network/services/hostapd/patches/340-reload_freq_change.patch -+++ /dev/null -@@ -1,80 +0,0 @@ ----- a/src/ap/hostapd.c --+++ b/src/ap/hostapd.c --@@ -143,6 +143,29 @@ static void hostapd_reload_bss(struct ho -- #endif /* CONFIG_NO_RADIUS */ -- -- ssid = &hapd->conf->ssid; --+ --+ hostapd_set_freq(hapd, hapd->iconf->hw_mode, hapd->iface->freq, --+ hapd->iconf->channel, --+ hapd->iconf->enable_edmg, --+ hapd->iconf->edmg_channel, --+ hapd->iconf->ieee80211n, --+ hapd->iconf->ieee80211ac, --+ hapd->iconf->ieee80211ax, --+ hapd->iconf->ieee80211be, --+ hapd->iconf->secondary_channel, --+ hostapd_get_oper_chwidth(hapd->iconf), --+ hostapd_get_oper_centr_freq_seg0_idx(hapd->iconf), --+ hostapd_get_oper_centr_freq_seg1_idx(hapd->iconf)); --+ --+ if (hapd->iface->current_mode) { --+ if (hostapd_prepare_rates(hapd->iface, hapd->iface->current_mode)) { --+ wpa_printf(MSG_ERROR, "Failed to prepare rates table."); --+ hostapd_logger(hapd, NULL, HOSTAPD_MODULE_IEEE80211, --+ HOSTAPD_LEVEL_WARNING, --+ "Failed to prepare rates table."); --+ } --+ } --+ -- if (!ssid->wpa_psk_set && ssid->wpa_psk && !ssid->wpa_psk->next && -- ssid->wpa_passphrase_set && ssid->wpa_passphrase) { -- /* --@@ -251,6 +274,7 @@ int hostapd_reload_config(struct hostapd -- struct hostapd_data *hapd = iface->bss[0]; -- struct hostapd_config *newconf, *oldconf; -- size_t j; --+ int i; -- -- if (iface->config_fname == NULL) { -- /* Only in-memory config in use - assume it has been updated */ --@@ -301,6 +325,17 @@ int hostapd_reload_config(struct hostapd -- } -- iface->conf = newconf; -- --+ for (i = 0; i < iface->num_hw_features; i++) { --+ struct hostapd_hw_modes *mode = &iface->hw_features[i]; --+ if (mode->mode == iface->conf->hw_mode) { --+ iface->current_mode = mode; --+ break; --+ } --+ } --+ --+ if (iface->conf->channel) --+ iface->freq = hostapd_hw_get_freq(hapd, iface->conf->channel); --+ -- for (j = 0; j < iface->num_bss; j++) { -- hapd = iface->bss[j]; -- if (!hapd->conf->config_id || !newconf->bss[j]->config_id || --@@ -308,21 +343,6 @@ int hostapd_reload_config(struct hostapd -- newconf->bss[j]->config_id) != 0) -- hostapd_clear_old_bss(hapd); -- hapd->iconf = newconf; --- hapd->iconf->channel = oldconf->channel; --- hapd->iconf->acs = oldconf->acs; --- hapd->iconf->secondary_channel = oldconf->secondary_channel; --- hapd->iconf->ieee80211n = oldconf->ieee80211n; --- hapd->iconf->ieee80211ac = oldconf->ieee80211ac; --- hapd->iconf->ht_capab = oldconf->ht_capab; --- hapd->iconf->vht_capab = oldconf->vht_capab; --- hostapd_set_oper_chwidth(hapd->iconf, --- hostapd_get_oper_chwidth(oldconf)); --- hostapd_set_oper_centr_freq_seg0_idx( --- hapd->iconf, --- hostapd_get_oper_centr_freq_seg0_idx(oldconf)); --- hostapd_set_oper_centr_freq_seg1_idx( --- hapd->iconf, --- hostapd_get_oper_centr_freq_seg1_idx(oldconf)); -- hapd->conf = newconf->bss[j]; -- hostapd_reload_bss(hapd); -- } -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 -deleted file mode 100644 -index 8784452876..0000000000 ---- a/package/network/services/hostapd/patches/341-mesh-ctrl-iface-channel-switch.patch -+++ /dev/null -@@ -1,39 +0,0 @@ ----- a/wpa_supplicant/ap.c --+++ b/wpa_supplicant/ap.c --@@ -1825,15 +1825,35 @@ int ap_switch_channel(struct wpa_supplic -- -- -- #ifdef CONFIG_CTRL_IFACE --+ --+static int __ap_ctrl_iface_chanswitch(struct hostapd_iface *iface, --+ struct csa_settings *settings) --+{ --+#ifdef NEED_AP_MLME --+ if (!iface || !iface->bss[0]) --+ return 0; --+ --+ return hostapd_switch_channel(iface->bss[0], settings); --+#else --+ return -1; --+#endif --+} --+ --+ -- int ap_ctrl_iface_chanswitch(struct wpa_supplicant *wpa_s, const char *pos) -- { -- struct csa_settings settings; -- int ret = hostapd_parse_csa_settings(pos, &settings); -- --+ 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; -- --- return ap_switch_channel(wpa_s, &settings); --+ 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 -deleted file mode 100644 -index 647ca2cbf9..0000000000 ---- a/package/network/services/hostapd/patches/350-nl80211_del_beacon_bss.patch -+++ /dev/null -@@ -1,35 +0,0 @@ ----- a/src/drivers/driver_nl80211.c --+++ b/src/drivers/driver_nl80211.c --@@ -3008,12 +3008,12 @@ static int wpa_driver_nl80211_del_beacon -- return 0; -- -- wpa_printf(MSG_DEBUG, "nl80211: Remove beacon (ifindex=%d)", --- drv->ifindex); --+ bss->ifindex); -- link->beacon_set = 0; -- link->freq = 0; -- -- nl80211_put_wiphy_data_ap(bss); --- msg = nl80211_drv_msg(drv, 0, NL80211_CMD_DEL_BEACON); --+ msg = nl80211_bss_msg(bss, 0, NL80211_CMD_DEL_BEACON); -- if (!msg) -- return -ENOBUFS; -- --@@ -6100,7 +6100,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; --+ wpa_driver_nl80211_del_beacon_all(bss); -- } -- -- --@@ -8859,8 +8859,6 @@ static int wpa_driver_nl80211_if_remove( -- } else { -- wpa_printf(MSG_DEBUG, "nl80211: First BSS - reassign context"); -- nl80211_teardown_ap(bss); --- if (!bss->added_if && !drv->first_bss->next) --- wpa_driver_nl80211_del_beacon_all(bss); -- nl80211_destroy_bss(bss); -- if (!bss->added_if) -- i802_set_iface_flags(bss, 0); -diff --git a/package/network/services/hostapd/patches/360-ctrl_iface_reload.patch b/package/network/services/hostapd/patches/360-ctrl_iface_reload.patch -deleted file mode 100644 -index 4d85ea11f9..0000000000 ---- a/package/network/services/hostapd/patches/360-ctrl_iface_reload.patch -+++ /dev/null -@@ -1,106 +0,0 @@ ----- a/hostapd/ctrl_iface.c --+++ b/hostapd/ctrl_iface.c --@@ -68,6 +68,7 @@ -- #include "fst/fst_ctrl_iface.h" -- #include "config_file.h" -- #include "ctrl_iface.h" --+#include "config_file.h" -- -- -- #define HOSTAPD_CLI_DUP_VALUE_MAX_LEN 256 --@@ -83,6 +84,7 @@ static void hostapd_ctrl_iface_send(stru -- enum wpa_msg_type type, -- const char *buf, size_t len); -- --+static char *reload_opts = NULL; -- -- static int hostapd_ctrl_iface_attach(struct hostapd_data *hapd, -- struct sockaddr_storage *from, --@@ -134,6 +136,61 @@ static int hostapd_ctrl_iface_new_sta(st -- return 0; -- } -- --+static char *get_option(char *opt, char *str) --+{ --+ int len = strlen(str); --+ --+ if (!strncmp(opt, str, len)) --+ return opt + len; --+ else --+ return NULL; --+} --+ --+static struct hostapd_config *hostapd_ctrl_iface_config_read(const char *fname) --+{ --+ struct hostapd_config *conf; --+ char *opt, *val; --+ --+ conf = hostapd_config_read(fname); --+ if (!conf) --+ return NULL; --+ --+ for (opt = strtok(reload_opts, " "); --+ opt; --+ opt = strtok(NULL, " ")) { --+ --+ if ((val = get_option(opt, "channel="))) --+ conf->channel = atoi(val); --+ else if ((val = get_option(opt, "ht_capab="))) --+ conf->ht_capab = atoi(val); --+ else if ((val = get_option(opt, "ht_capab_mask="))) --+ conf->ht_capab &= atoi(val); --+ else if ((val = get_option(opt, "sec_chan="))) --+ conf->secondary_channel = atoi(val); --+ else if ((val = get_option(opt, "hw_mode="))) --+ conf->hw_mode = atoi(val); --+ else if ((val = get_option(opt, "ieee80211n="))) --+ conf->ieee80211n = atoi(val); --+ else --+ break; --+ } --+ --+ return conf; --+} --+ --+static int hostapd_ctrl_iface_update(struct hostapd_data *hapd, char *txt) --+{ --+ struct hostapd_config * (*config_read_cb)(const char *config_fname); --+ struct hostapd_iface *iface = hapd->iface; --+ --+ config_read_cb = iface->interfaces->config_read_cb; --+ iface->interfaces->config_read_cb = hostapd_ctrl_iface_config_read; --+ reload_opts = txt; --+ --+ hostapd_reload_config(iface); --+ --+ iface->interfaces->config_read_cb = config_read_cb; --+} -- -- #ifdef NEED_AP_MLME -- static int hostapd_ctrl_iface_sa_query(struct hostapd_data *hapd, --@@ -3564,6 +3621,8 @@ static int hostapd_ctrl_iface_receive_pr -- } else if (os_strncmp(buf, "VENDOR ", 7) == 0) { -- reply_len = hostapd_ctrl_iface_vendor(hapd, buf + 7, reply, -- reply_size); --+ } else if (os_strncmp(buf, "UPDATE ", 7) == 0) { --+ hostapd_ctrl_iface_update(hapd, buf + 7); -- } else if (os_strcmp(buf, "ERP_FLUSH") == 0) { -- ieee802_1x_erp_flush(hapd); -- #ifdef RADIUS_SERVER ----- a/src/ap/ctrl_iface_ap.c --+++ b/src/ap/ctrl_iface_ap.c --@@ -1023,7 +1023,13 @@ int hostapd_parse_csa_settings(const cha -- -- int hostapd_ctrl_iface_stop_ap(struct hostapd_data *hapd) -- { --- return hostapd_drv_stop_ap(hapd); --+ struct hostapd_iface *iface = hapd->iface; --+ int i; --+ --+ for (i = 0; i < iface->num_bss; i++) --+ hostapd_drv_stop_ap(iface->bss[i]); --+ --+ return 0; -- } -- -- -diff --git a/package/network/services/hostapd/patches/370-ap_sta_support.patch b/package/network/services/hostapd/patches/370-ap_sta_support.patch -deleted file mode 100644 -index 3baad2a52e..0000000000 ---- a/package/network/services/hostapd/patches/370-ap_sta_support.patch -+++ /dev/null -@@ -1,392 +0,0 @@ ----- a/wpa_supplicant/Makefile --+++ b/wpa_supplicant/Makefile --@@ -126,6 +126,8 @@ OBJS_c += ../src/utils/common.o -- OBJS_c += ../src/common/cli.o -- OBJS += wmm_ac.o -- --+OBJS += ../src/common/wpa_ctrl.o --+ -- ifndef CONFIG_OS -- ifdef CONFIG_NATIVE_WINDOWS -- CONFIG_OS=win32 ----- a/wpa_supplicant/bss.c --+++ b/wpa_supplicant/bss.c --@@ -11,6 +11,7 @@ -- #include "utils/common.h" -- #include "utils/eloop.h" -- #include "common/ieee802_11_defs.h" --+#include "common/ieee802_11_common.h" -- #include "drivers/driver.h" -- #include "eap_peer/eap.h" -- #include "wpa_supplicant_i.h" --@@ -283,6 +284,10 @@ void calculate_update_time(const struct -- static void wpa_bss_copy_res(struct wpa_bss *dst, struct wpa_scan_res *src, -- struct os_reltime *fetch_time) -- { --+ struct ieee80211_ht_capabilities *capab; --+ struct ieee80211_ht_operation *oper; --+ struct ieee802_11_elems elems; --+ -- dst->flags = src->flags; -- os_memcpy(dst->bssid, src->bssid, ETH_ALEN); -- dst->freq = src->freq; --@@ -296,6 +301,15 @@ static void wpa_bss_copy_res(struct wpa_ -- dst->est_throughput = src->est_throughput; -- dst->snr = src->snr; -- --+ memset(&elems, 0, sizeof(elems)); --+ ieee802_11_parse_elems((u8 *) (src + 1), src->ie_len, &elems, 0); --+ capab = (struct ieee80211_ht_capabilities *) elems.ht_capabilities; --+ oper = (struct ieee80211_ht_operation *) elems.ht_operation; --+ if (capab) --+ dst->ht_capab = le_to_host16(capab->ht_capabilities_info); --+ if (oper) --+ dst->ht_param = oper->ht_param; --+ -- calculate_update_time(fetch_time, src->age, &dst->last_update); -- } -- ----- a/wpa_supplicant/bss.h --+++ b/wpa_supplicant/bss.h --@@ -94,6 +94,10 @@ struct wpa_bss { -- u8 ssid[SSID_MAX_LEN]; -- /** Length of SSID */ -- size_t ssid_len; --+ /** HT capabilities */ --+ u16 ht_capab; --+ /* Five octets of HT Operation Information */ --+ u8 ht_param; -- /** Frequency of the channel in MHz (e.g., 2412 = channel 1) */ -- int freq; -- /** Beacon interval in TUs (host byte order) */ ----- a/wpa_supplicant/main.c --+++ b/wpa_supplicant/main.c --@@ -35,7 +35,7 @@ static void usage(void) -- "vW] [-P] " -- "[-g] \\\n" -- " [-G] \\\n" --- " -i -c [-C] [-D] " --+ " -i -c [-C] [-D] [-H] " -- "[-p] \\\n" -- " [-b] [-e]" -- #ifdef CONFIG_DEBUG_FILE --@@ -75,6 +75,7 @@ static void usage(void) -- " -g = global ctrl_interface\n" -- " -G = global ctrl_interface group\n" -- " -h = show this help text\n" --+ " -H = connect to a hostapd instance to manage state changes\n" -- " -i = interface name\n" -- " -I = additional configuration file\n" -- " -K = include keys (passwords, etc.) in debug output\n" --@@ -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:hH:i:I:KLMm:No:O:p:P:qsTtuvW"); -- if (c < 0) -- break; -- switch (c) { --@@ -249,6 +250,9 @@ int main(int argc, char *argv[]) -- usage(); -- exitcode = 0; -- goto out; --+ case 'H': --+ iface->hostapd_ctrl = optarg; --+ break; -- case 'i': -- iface->ifname = optarg; -- break; ----- a/wpa_supplicant/wpa_supplicant.c --+++ b/wpa_supplicant/wpa_supplicant.c --@@ -131,6 +131,54 @@ static void wpas_update_fils_connect_par -- static void wpas_update_owe_connect_params(struct wpa_supplicant *wpa_s); -- #endif /* CONFIG_OWE */ -- --+static int hostapd_stop(struct wpa_supplicant *wpa_s) --+{ --+ const char *cmd = "STOP_AP"; --+ char buf[256]; --+ size_t len = sizeof(buf); --+ --+ if (wpa_ctrl_request(wpa_s->hostapd, cmd, os_strlen(cmd), buf, &len, NULL) < 0) { --+ wpa_printf(MSG_ERROR, "\nFailed to stop hostapd AP interfaces\n"); --+ return -1; --+ } --+ return 0; --+} --+ --+static int hostapd_reload(struct wpa_supplicant *wpa_s, struct wpa_bss *bss) --+{ --+ char *cmd = NULL; --+ char buf[256]; --+ size_t len = sizeof(buf); --+ enum hostapd_hw_mode hw_mode; --+ u8 channel; --+ int sec_chan = 0; --+ int ret; --+ --+ if (!bss) --+ return -1; --+ --+ if (bss->ht_param & HT_INFO_HT_PARAM_STA_CHNL_WIDTH) { --+ int sec = bss->ht_param & HT_INFO_HT_PARAM_SECONDARY_CHNL_OFF_MASK; --+ if (sec == HT_INFO_HT_PARAM_SECONDARY_CHNL_ABOVE) --+ sec_chan = 1; --+ else if (sec == HT_INFO_HT_PARAM_SECONDARY_CHNL_BELOW) --+ sec_chan = -1; --+ } --+ --+ hw_mode = ieee80211_freq_to_chan(bss->freq, &channel); --+ if (asprintf(&cmd, "UPDATE channel=%d sec_chan=%d hw_mode=%d", --+ channel, sec_chan, hw_mode) < 0) --+ return -1; --+ --+ ret = wpa_ctrl_request(wpa_s->hostapd, cmd, os_strlen(cmd), buf, &len, NULL); --+ free(cmd); --+ --+ if (ret < 0) { --+ wpa_printf(MSG_ERROR, "\nFailed to reload hostapd AP interfaces\n"); --+ return -1; --+ } --+ return 0; --+} -- -- #ifdef CONFIG_WEP -- /* Configure default/group WEP keys for static WEP */ --@@ -1026,6 +1074,8 @@ void wpa_supplicant_set_state(struct wpa -- -- sme_sched_obss_scan(wpa_s, 1); -- --+ if (wpa_s->hostapd) --+ hostapd_reload(wpa_s, wpa_s->current_bss); -- #if defined(CONFIG_FILS) && defined(IEEE8021X_EAPOL) -- if (!fils_hlp_sent && ssid && ssid->eap.erp) -- update_fils_connect_params = true; --@@ -1036,6 +1086,8 @@ void wpa_supplicant_set_state(struct wpa -- #endif /* CONFIG_OWE */ -- } else if (state == WPA_DISCONNECTED || state == WPA_ASSOCIATING || -- state == WPA_ASSOCIATED) { --+ if (wpa_s->hostapd) --+ hostapd_stop(wpa_s); -- wpa_s->new_connection = 1; -- wpa_drv_set_operstate(wpa_s, 0); -- #ifndef IEEE8021X_EAPOL --@@ -2537,6 +2589,8 @@ void wpa_supplicant_associate(struct wpa -- return; -- } -- wpa_s->current_bss = bss; --+ if (wpa_s->hostapd) --+ hostapd_reload(wpa_s, wpa_s->current_bss); -- #else /* CONFIG_MESH */ -- wpa_msg(wpa_s, MSG_ERROR, -- "mesh mode support not included in the build"); --@@ -7037,6 +7091,16 @@ static int wpa_supplicant_init_iface(str -- sizeof(wpa_s->bridge_ifname)); -- } -- --+ if (iface->hostapd_ctrl) { --+ wpa_s->hostapd = wpa_ctrl_open(iface->hostapd_ctrl); --+ if (!wpa_s->hostapd) { --+ wpa_printf(MSG_ERROR, "\nFailed to connect to hostapd\n"); --+ return -1; --+ } --+ if (hostapd_stop(wpa_s) < 0) --+ return -1; --+ } --+ -- /* RSNA Supplicant Key Management - INITIALIZE */ -- eapol_sm_notify_portEnabled(wpa_s->eapol, false); -- eapol_sm_notify_portValid(wpa_s->eapol, false); --@@ -7379,6 +7443,11 @@ static void wpa_supplicant_deinit_iface( -- if (terminate) -- wpa_msg(wpa_s, MSG_INFO, WPA_EVENT_TERMINATING); -- --+ if (wpa_s->hostapd) { --+ wpa_ctrl_close(wpa_s->hostapd); --+ wpa_s->hostapd = NULL; --+ } --+ -- wpa_supplicant_ctrl_iface_deinit(wpa_s, wpa_s->ctrl_iface); -- wpa_s->ctrl_iface = NULL; -- ----- a/wpa_supplicant/wpa_supplicant_i.h --+++ b/wpa_supplicant/wpa_supplicant_i.h --@@ -106,6 +106,11 @@ struct wpa_interface { -- const char *ifname; -- -- /** --+ * hostapd_ctrl - path to hostapd control socket for notification --+ */ --+ const char *hostapd_ctrl; --+ --+ /** -- * bridge_ifname - Optional bridge interface name -- * -- * If the driver interface (ifname) is included in a Linux bridge --@@ -665,6 +670,8 @@ struct wpa_supplicant { -- #endif /* CONFIG_CTRL_IFACE_BINDER */ -- char bridge_ifname[16]; -- --+ struct wpa_ctrl *hostapd; --+ -- char *confname; -- char *confanother; -- ----- a/hostapd/ctrl_iface.c --+++ b/hostapd/ctrl_iface.c --@@ -2751,6 +2751,12 @@ static int hostapd_ctrl_iface_chan_switc -- return 0; -- } -- --+ if (os_strstr(pos, " auto-ht")) { --+ settings.freq_params.ht_enabled = iface->conf->ieee80211n; --+ settings.freq_params.vht_enabled = iface->conf->ieee80211ac; --+ settings.freq_params.he_enabled = iface->conf->ieee80211ax; --+ } --+ -- for (i = 0; i < iface->num_bss; i++) { -- -- /* Save CHAN_SWITCH VHT, HE, and EHT config */ ----- a/src/ap/beacon.c --+++ b/src/ap/beacon.c --@@ -2108,11 +2108,6 @@ static int __ieee802_11_set_beacon(struc -- return -1; -- } -- --- if (hapd->csa_in_progress) { --- wpa_printf(MSG_ERROR, "Cannot set beacons during CSA period"); --- return -1; --- } --- -- hapd->beacon_set_done = 1; -- -- if (ieee802_11_build_ap_params(hapd, ¶ms) < 0) ----- a/wpa_supplicant/events.c --+++ b/wpa_supplicant/events.c --@@ -5345,6 +5345,60 @@ static void wpas_link_reconfig(struct wp -- } -- -- --+static void --+supplicant_ch_switch_started(struct wpa_supplicant *wpa_s, --+ union wpa_event_data *data) --+{ --+ char buf[256]; --+ size_t len = sizeof(buf); --+ char *cmd = NULL; --+ int width = 20; --+ int ret; --+ --+ if (!wpa_s->hostapd) --+ return; --+ --+ wpa_msg(wpa_s, MSG_INFO, WPA_EVENT_CHANNEL_SWITCH --+ "count=%d freq=%d ht_enabled=%d ch_offset=%d ch_width=%s cf1=%d cf2=%d", --+ data->ch_switch.count, --+ data->ch_switch.freq, --+ data->ch_switch.ht_enabled, --+ data->ch_switch.ch_offset, --+ channel_width_to_string(data->ch_switch.ch_width), --+ data->ch_switch.cf1, --+ data->ch_switch.cf2); --+ --+ switch (data->ch_switch.ch_width) { --+ case CHAN_WIDTH_20_NOHT: --+ case CHAN_WIDTH_20: --+ width = 20; --+ break; --+ case CHAN_WIDTH_40: --+ width = 40; --+ break; --+ case CHAN_WIDTH_80: --+ width = 80; --+ break; --+ case CHAN_WIDTH_160: --+ case CHAN_WIDTH_80P80: --+ width = 160; --+ break; --+ } --+ --+ asprintf(&cmd, "CHAN_SWITCH %d %d sec_channel_offset=%d center_freq1=%d center_freq2=%d, bandwidth=%d auto-ht\n", --+ data->ch_switch.count - 1, --+ data->ch_switch.freq, --+ data->ch_switch.ch_offset, --+ data->ch_switch.cf1, --+ data->ch_switch.cf2, --+ width); --+ ret = wpa_ctrl_request(wpa_s->hostapd, cmd, os_strlen(cmd), buf, &len, NULL); --+ free(cmd); --+ --+ if (ret < 0) --+ wpa_printf(MSG_ERROR, "\nFailed to reload hostapd AP interfaces\n"); --+} --+ -- void supplicant_event(void *ctx, enum wpa_event_type event, -- union wpa_event_data *data) -- { --@@ -5697,8 +5751,10 @@ void supplicant_event(void *ctx, enum wp -- channel_width_to_string(data->ch_switch.ch_width), -- data->ch_switch.cf1, -- data->ch_switch.cf2); --- if (event == EVENT_CH_SWITCH_STARTED) --+ if (event == EVENT_CH_SWITCH_STARTED) { --+ supplicant_ch_switch_started(wpa_s, data); -- break; --+ } -- -- wpa_s->assoc_freq = data->ch_switch.freq; -- wpa_s->current_ssid->frequency = data->ch_switch.freq; ----- a/src/drivers/driver.h --+++ b/src/drivers/driver.h --@@ -6421,6 +6421,7 @@ union wpa_event_data { -- -- /** -- * struct ch_switch --+ * @count: Count until channel switch activates -- * @freq: Frequency of new channel in MHz -- * @ht_enabled: Whether this is an HT channel -- * @ch_offset: Secondary channel offset --@@ -6431,6 +6432,7 @@ union wpa_event_data { -- * @punct_bitmap: Puncturing bitmap -- */ -- struct ch_switch { --+ int count; -- int freq; -- int ht_enabled; -- 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 -- struct nlattr *bw, struct nlattr *cf1, -- struct nlattr *cf2, -- struct nlattr *punct_bitmap, --+ struct nlattr *count, -- int finished) -- { -- struct i802_bss *bss; --@@ -1265,6 +1266,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; --@@ -3848,6 +3851,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: --@@ -3860,6 +3864,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: -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 -deleted file mode 100644 -index 456599db09..0000000000 ---- a/package/network/services/hostapd/patches/380-disable_ctrl_iface_mib.patch -+++ /dev/null -@@ -1,239 +0,0 @@ ----- 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 --@@ -3377,6 +3377,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) { --@@ -3418,6 +3419,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/wpa_supplicant/Makefile --+++ b/wpa_supplicant/Makefile --@@ -985,6 +985,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/ctrl_iface.c --+++ b/wpa_supplicant/ctrl_iface.c --@@ -2326,7 +2326,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, --@@ -11964,6 +11964,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) { --@@ -11976,6 +11977,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); --@@ -12464,6 +12466,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) { --@@ -12472,12 +12475,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; ----- 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) --@@ -493,6 +493,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, --@@ -884,12 +885,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 --@@ -2834,6 +2834,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) -- { --@@ -3020,6 +3021,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 --@@ -5328,6 +5328,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) \ --@@ -5480,7 +5481,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 --@@ -3834,6 +3834,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 --@@ -3915,6 +3917,7 @@ int wpa_sm_get_mib(struct wpa_sm *sm, ch -- -- return (int) len; -- } --+#endif -- #endif /* CONFIG_CTRL_IFACE */ -- -- ----- a/wpa_supplicant/ap.c --+++ b/wpa_supplicant/ap.c --@@ -1499,7 +1499,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) -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 -deleted file mode 100644 -index e9083f6ecc..0000000000 ---- a/package/network/services/hostapd/patches/381-hostapd_cli_UNKNOWN-COMMAND.patch -+++ /dev/null -@@ -1,11 +0,0 @@ ----- a/hostapd/hostapd_cli.c --+++ b/hostapd/hostapd_cli.c --@@ -757,7 +757,7 @@ static int wpa_ctrl_command_sta(struct w -- } -- -- buf[len] = '\0'; --- if (memcmp(buf, "FAIL", 4) == 0) --+ if (memcmp(buf, "FAIL", 4) == 0 || memcmp(buf, "UNKNOWN COMMAND", 15) == 0) -- return -1; -- if (print) -- printf("%s", buf); -diff --git a/package/network/services/hostapd/patches/390-wpa_ie_cap_workaround.patch b/package/network/services/hostapd/patches/390-wpa_ie_cap_workaround.patch -deleted file mode 100644 -index 40c39ff29c..0000000000 ---- a/package/network/services/hostapd/patches/390-wpa_ie_cap_workaround.patch -+++ /dev/null -@@ -1,56 +0,0 @@ ----- a/src/common/wpa_common.c --+++ b/src/common/wpa_common.c --@@ -2719,6 +2719,31 @@ u32 wpa_akm_to_suite(int akm) -- } -- -- --+static void wpa_fixup_wpa_ie_rsn(u8 *assoc_ie, const u8 *wpa_msg_ie, --+ size_t rsn_ie_len) --+{ --+ int pos, count; --+ --+ pos = sizeof(struct rsn_ie_hdr) + RSN_SELECTOR_LEN; --+ if (rsn_ie_len < pos + 2) --+ return; --+ --+ count = WPA_GET_LE16(wpa_msg_ie + pos); --+ pos += 2 + count * RSN_SELECTOR_LEN; --+ if (rsn_ie_len < pos + 2) --+ return; --+ --+ count = WPA_GET_LE16(wpa_msg_ie + pos); --+ pos += 2 + count * RSN_SELECTOR_LEN; --+ if (rsn_ie_len < pos + 2) --+ return; --+ --+ if (!assoc_ie[pos] && !assoc_ie[pos + 1] && --+ (wpa_msg_ie[pos] || wpa_msg_ie[pos + 1])) --+ memcpy(&assoc_ie[pos], &wpa_msg_ie[pos], 2); --+} --+ --+ -- int wpa_compare_rsn_ie(int ft_initial_assoc, -- const u8 *ie1, size_t ie1len, -- const u8 *ie2, size_t ie2len) --@@ -2726,8 +2751,19 @@ int wpa_compare_rsn_ie(int ft_initial_as -- if (ie1 == NULL || ie2 == NULL) -- return -1; -- --- if (ie1len == ie2len && os_memcmp(ie1, ie2, ie1len) == 0) --- return 0; /* identical IEs */ --+ if (ie1len == ie2len) { --+ u8 *ie_tmp; --+ --+ if (os_memcmp(ie1, ie2, ie1len) == 0) --+ return 0; /* identical IEs */ --+ --+ ie_tmp = alloca(ie1len); --+ memcpy(ie_tmp, ie1, ie1len); --+ wpa_fixup_wpa_ie_rsn(ie_tmp, ie2, ie1len); --+ --+ if (os_memcmp(ie_tmp, ie2, ie1len) == 0) --+ return 0; /* only mismatch in RSN capabilties */ --+ } -- -- #ifdef CONFIG_IEEE80211R -- if (ft_initial_assoc) { -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 -deleted file mode 100644 -index edcd985257..0000000000 ---- a/package/network/services/hostapd/patches/400-wps_single_auth_enc_type.patch -+++ /dev/null -@@ -1,23 +0,0 @@ ----- a/src/ap/wps_hostapd.c --+++ b/src/ap/wps_hostapd.c --@@ -394,9 +394,8 @@ static int hapd_wps_reconfig_in_memory(s -- bss->wpa_pairwise |= WPA_CIPHER_GCMP; -- else -- bss->wpa_pairwise |= WPA_CIPHER_CCMP; --- } -- #ifndef CONFIG_NO_TKIP --- if (cred->encr_type & WPS_ENCR_TKIP) --+ } else if (cred->encr_type & WPS_ENCR_TKIP) -- bss->wpa_pairwise |= WPA_CIPHER_TKIP; -- #endif /* CONFIG_NO_TKIP */ -- bss->rsn_pairwise = bss->wpa_pairwise; --@@ -1181,8 +1180,7 @@ int hostapd_init_wps(struct hostapd_data -- WPA_CIPHER_GCMP_256)) { -- wps->encr_types |= WPS_ENCR_AES; -- wps->encr_types_rsn |= WPS_ENCR_AES; --- } --- if (conf->rsn_pairwise & WPA_CIPHER_TKIP) { --+ } else if (conf->rsn_pairwise & WPA_CIPHER_TKIP) { -- #ifdef CONFIG_NO_TKIP -- wpa_printf(MSG_INFO, "WPS: TKIP not supported"); -- goto fail; -diff --git a/package/network/services/hostapd/patches/410-limit_debug_messages.patch b/package/network/services/hostapd/patches/410-limit_debug_messages.patch -deleted file mode 100644 -index 48a5589200..0000000000 ---- a/package/network/services/hostapd/patches/410-limit_debug_messages.patch -+++ /dev/null -@@ -1,210 +0,0 @@ ----- a/src/utils/wpa_debug.c --+++ b/src/utils/wpa_debug.c --@@ -206,7 +206,7 @@ void wpa_debug_close_linux_tracing(void) -- * -- * Note: New line '\n' is added to the end of the text when printing to stdout. -- */ ---void wpa_printf(int level, const char *fmt, ...) --+void _wpa_printf(int level, const char *fmt, ...) -- { -- va_list ap; -- --@@ -255,7 +255,7 @@ void wpa_printf(int level, const char *f -- } -- -- ---static void _wpa_hexdump(int level, const char *title, const u8 *buf, --+void _wpa_hexdump(int level, const char *title, const u8 *buf, -- size_t len, int show, int only_syslog) -- { -- size_t i; --@@ -382,19 +382,7 @@ static void _wpa_hexdump(int level, cons -- #endif /* CONFIG_ANDROID_LOG */ -- } -- ---void wpa_hexdump(int level, const char *title, const void *buf, size_t len) ---{ --- _wpa_hexdump(level, title, buf, len, 1, 0); ---} --- --- ---void wpa_hexdump_key(int level, const char *title, const void *buf, size_t len) ---{ --- _wpa_hexdump(level, title, buf, len, wpa_debug_show_keys, 0); ---} --- --- ---static void _wpa_hexdump_ascii(int level, const char *title, const void *buf, --+void _wpa_hexdump_ascii(int level, const char *title, const void *buf, -- size_t len, int show) -- { -- size_t i, llen; --@@ -507,20 +495,6 @@ file_done: -- } -- -- ---void wpa_hexdump_ascii(int level, const char *title, const void *buf, --- size_t len) ---{ --- _wpa_hexdump_ascii(level, title, buf, len, 1); ---} --- --- ---void wpa_hexdump_ascii_key(int level, const char *title, const void *buf, --- size_t len) ---{ --- _wpa_hexdump_ascii(level, title, buf, len, wpa_debug_show_keys); ---} --- --- -- #ifdef CONFIG_DEBUG_FILE -- static char *last_path = NULL; -- #endif /* CONFIG_DEBUG_FILE */ --@@ -644,7 +618,7 @@ void wpa_msg_register_ifname_cb(wpa_msg_ -- } -- -- ---void wpa_msg(void *ctx, int level, const char *fmt, ...) --+void _wpa_msg(void *ctx, int level, const char *fmt, ...) -- { -- va_list ap; -- char *buf; --@@ -682,7 +656,7 @@ void wpa_msg(void *ctx, int level, const -- } -- -- ---void wpa_msg_ctrl(void *ctx, int level, const char *fmt, ...) --+void _wpa_msg_ctrl(void *ctx, int level, const char *fmt, ...) -- { -- va_list ap; -- char *buf; ----- a/src/utils/wpa_debug.h --+++ b/src/utils/wpa_debug.h --@@ -51,6 +51,17 @@ void wpa_debug_close_file(void); -- void wpa_debug_setup_stdout(void); -- void wpa_debug_stop_log(void); -- --+/* internal */ --+void _wpa_hexdump(int level, const char *title, const u8 *buf, --+ size_t len, int show, int only_syslog); --+void _wpa_hexdump_ascii(int level, const char *title, const void *buf, --+ size_t len, int show); --+extern int wpa_debug_show_keys; --+ --+#ifndef CONFIG_MSG_MIN_PRIORITY --+#define CONFIG_MSG_MIN_PRIORITY 0 --+#endif --+ -- /** -- * wpa_debug_printf_timestamp - Print timestamp for debug output -- * --@@ -71,9 +82,15 @@ void wpa_debug_print_timestamp(void); -- * -- * Note: New line '\n' is added to the end of the text when printing to stdout. -- */ ---void wpa_printf(int level, const char *fmt, ...) --+void _wpa_printf(int level, const char *fmt, ...) -- PRINTF_FORMAT(2, 3); -- --+#define wpa_printf(level, ...) \ --+ do { \ --+ if (level >= CONFIG_MSG_MIN_PRIORITY) \ --+ _wpa_printf(level, __VA_ARGS__); \ --+ } while(0) --+ -- /** -- * wpa_hexdump - conditional hex dump -- * @level: priority level (MSG_*) of the message --@@ -85,7 +102,13 @@ PRINTF_FORMAT(2, 3); -- * output may be directed to stdout, stderr, and/or syslog based on -- * configuration. The contents of buf is printed out has hex dump. -- */ ---void wpa_hexdump(int level, const char *title, const void *buf, size_t len); --+static inline void wpa_hexdump(int level, const char *title, const void *buf, size_t len) --+{ --+ if (level < CONFIG_MSG_MIN_PRIORITY) --+ return; --+ --+ _wpa_hexdump(level, title, buf, len, 1, 1); --+} -- -- static inline void wpa_hexdump_buf(int level, const char *title, -- const struct wpabuf *buf) --@@ -107,7 +130,13 @@ static inline void wpa_hexdump_buf(int l -- * like wpa_hexdump(), but by default, does not include secret keys (passwords, -- * etc.) in debug output. -- */ ---void wpa_hexdump_key(int level, const char *title, const void *buf, size_t len); --+static inline void wpa_hexdump_key(int level, const char *title, const u8 *buf, size_t len) --+{ --+ if (level < CONFIG_MSG_MIN_PRIORITY) --+ return; --+ --+ _wpa_hexdump(level, title, buf, len, wpa_debug_show_keys, 1); --+} -- -- static inline void wpa_hexdump_buf_key(int level, const char *title, -- const struct wpabuf *buf) --@@ -129,8 +158,14 @@ static inline void wpa_hexdump_buf_key(i -- * the hex numbers and ASCII characters (for printable range) are shown. 16 -- * bytes per line will be shown. -- */ ---void wpa_hexdump_ascii(int level, const char *title, const void *buf, --- size_t len); --+static inline void wpa_hexdump_ascii(int level, const char *title, --+ const u8 *buf, size_t len) --+{ --+ if (level < CONFIG_MSG_MIN_PRIORITY) --+ return; --+ --+ _wpa_hexdump_ascii(level, title, buf, len, 1); --+} -- -- /** -- * wpa_hexdump_ascii_key - conditional hex dump, hide keys --@@ -146,8 +181,14 @@ void wpa_hexdump_ascii(int level, const -- * bytes per line will be shown. This works like wpa_hexdump_ascii(), but by -- * default, does not include secret keys (passwords, etc.) in debug output. -- */ ---void wpa_hexdump_ascii_key(int level, const char *title, const void *buf, --- size_t len); --+static inline void wpa_hexdump_ascii_key(int level, const char *title, --+ const u8 *buf, size_t len) --+{ --+ if (level < CONFIG_MSG_MIN_PRIORITY) --+ return; --+ --+ _wpa_hexdump_ascii(level, title, buf, len, wpa_debug_show_keys); --+} -- -- /* -- * wpa_dbg() behaves like wpa_msg(), but it can be removed from build to reduce --@@ -184,7 +225,12 @@ void wpa_hexdump_ascii_key(int level, co -- * -- * Note: New line '\n' is added to the end of the text when printing to stdout. -- */ ---void wpa_msg(void *ctx, int level, const char *fmt, ...) PRINTF_FORMAT(3, 4); --+void _wpa_msg(void *ctx, int level, const char *fmt, ...) PRINTF_FORMAT(3, 4); --+#define wpa_msg(ctx, level, ...) \ --+ do { \ --+ if (level >= CONFIG_MSG_MIN_PRIORITY) \ --+ _wpa_msg(ctx, level, __VA_ARGS__); \ --+ } while(0) -- -- /** -- * wpa_msg_ctrl - Conditional printf for ctrl_iface monitors --@@ -198,8 +244,13 @@ void wpa_msg(void *ctx, int level, const -- * attached ctrl_iface monitors. In other words, it can be used for frequent -- * events that do not need to be sent to syslog. -- */ ---void wpa_msg_ctrl(void *ctx, int level, const char *fmt, ...) --+void _wpa_msg_ctrl(void *ctx, int level, const char *fmt, ...) -- PRINTF_FORMAT(3, 4); --+#define wpa_msg_ctrl(ctx, level, ...) \ --+ do { \ --+ if (level >= CONFIG_MSG_MIN_PRIORITY) \ --+ _wpa_msg_ctrl(ctx, level, __VA_ARGS__); \ --+ } while(0) -- -- /** -- * wpa_msg_global - Global printf for ctrl_iface monitors -diff --git a/package/network/services/hostapd/patches/420-indicate-features.patch b/package/network/services/hostapd/patches/420-indicate-features.patch -deleted file mode 100644 -index 786b83d315..0000000000 ---- a/package/network/services/hostapd/patches/420-indicate-features.patch -+++ /dev/null -@@ -1,63 +0,0 @@ ----- 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; --@@ -786,7 +786,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) { --@@ -823,6 +823,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" --@@ -203,7 +204,7 @@ int main(int argc, char *argv[]) -- -- for (;;) { -- c = getopt(argc, argv, --- "b:Bc:C:D:de:f:g:G:hH:i:I:KLMm:No:O:p:P:qsTtuvW"); --+ "b:Bc:C:D:de:f:g:G:hH:i:I:KLMm:No:O:p:P:qsTtuv::W"); -- if (c < 0) -- break; -- switch (c) { --@@ -306,8 +307,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/430-hostapd_cli_ifdef.patch b/package/network/services/hostapd/patches/430-hostapd_cli_ifdef.patch -deleted file mode 100644 -index a21f0bf7ce..0000000000 ---- a/package/network/services/hostapd/patches/430-hostapd_cli_ifdef.patch -+++ /dev/null -@@ -1,56 +0,0 @@ ----- 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, --@@ -1610,13 +1606,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, --@@ -1641,7 +1634,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/431-wpa_cli_ifdef.patch b/package/network/services/hostapd/patches/431-wpa_cli_ifdef.patch -deleted file mode 100644 -index 65c31c567f..0000000000 ---- a/package/network/services/hostapd/patches/431-wpa_cli_ifdef.patch -+++ /dev/null -@@ -1,18 +0,0 @@ ----- 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/432-missing-typedef.patch b/package/network/services/hostapd/patches/432-missing-typedef.patch -deleted file mode 100644 -index 7a100f1a0d..0000000000 ---- a/package/network/services/hostapd/patches/432-missing-typedef.patch -+++ /dev/null -@@ -1,10 +0,0 @@ ----- a/src/drivers/linux_wext.h --+++ b/src/drivers/linux_wext.h --@@ -26,6 +26,7 @@ typedef int32_t __s32; -- typedef uint16_t __u16; -- typedef int16_t __s16; -- typedef uint8_t __u8; --+typedef int8_t __s8; -- #ifndef __user -- #define __user -- #endif /* __user */ -diff --git a/package/network/services/hostapd/patches/450-scan_wait.patch b/package/network/services/hostapd/patches/450-scan_wait.patch -deleted file mode 100644 -index 45886896ee..0000000000 ---- a/package/network/services/hostapd/patches/450-scan_wait.patch -+++ /dev/null -@@ -1,73 +0,0 @@ ----- a/hostapd/main.c --+++ b/hostapd/main.c --@@ -39,6 +39,8 @@ struct hapd_global { -- }; -- -- static struct hapd_global global; --+static int daemonize = 0; --+static char *pid_file = NULL; -- -- -- #ifndef CONFIG_NO_HOSTAPD_LOGGER --@@ -146,6 +148,14 @@ static void hostapd_logger_cb(void *ctx, -- } -- #endif /* CONFIG_NO_HOSTAPD_LOGGER */ -- --+static void hostapd_setup_complete_cb(void *ctx) --+{ --+ if (daemonize && os_daemonize(pid_file)) { --+ perror("daemon"); --+ return; --+ } --+ daemonize = 0; --+} -- -- /** -- * hostapd_driver_init - Preparate driver interface --@@ -217,6 +227,8 @@ static int hostapd_driver_init(struct ho -- } -- #endif /* CONFIG_IEEE80211BE */ -- --+ hapd->setup_complete_cb = hostapd_setup_complete_cb; --+ -- /* Initialize the driver interface */ -- if (!(b[0] | b[1] | b[2] | b[3] | b[4] | b[5])) -- b = NULL; --@@ -497,8 +509,6 @@ static void hostapd_global_deinit(const -- #endif /* CONFIG_NATIVE_WINDOWS */ -- -- eap_server_unregister_methods(); --- --- os_daemonize_terminate(pid_file); -- } -- -- --@@ -524,18 +534,6 @@ static int hostapd_global_run(struct hap -- } -- #endif /* EAP_SERVER_TNC */ -- --- if (daemonize) { --- if (os_daemonize(pid_file)) { --- wpa_printf(MSG_ERROR, "daemon: %s", strerror(errno)); --- return -1; --- } --- if (eloop_sock_requeue()) { --- wpa_printf(MSG_ERROR, "eloop_sock_requeue: %s", --- strerror(errno)); --- return -1; --- } --- } --- -- eloop_run(); -- -- return 0; --@@ -739,8 +737,7 @@ int main(int argc, char *argv[]) -- struct hapd_interfaces interfaces; -- int ret = 1; -- size_t i, j; --- int c, debug = 0, daemonize = 0; --- char *pid_file = NULL; --+ int c, debug = 0; -- const char *log_file = NULL; -- const char *entropy_file = NULL; -- char **bss_config = NULL, **tmp_bss; -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 -deleted file mode 100644 -index 4c72868139..0000000000 ---- a/package/network/services/hostapd/patches/460-wpa_supplicant-add-new-config-params-to-be-used-with.patch -+++ /dev/null -@@ -1,189 +0,0 @@ --From 4bb69d15477e0f2b00e166845341dc933de47c58 Mon Sep 17 00:00:00 2001 --From: Antonio Quartulli --Date: Sun, 3 Jun 2012 18:22:56 +0200 --Subject: [PATCHv2 601/602] wpa_supplicant: add new config params to be used -- with the ibss join command -- --Signed-hostap: Antonio Quartulli ----- -- src/drivers/driver.h | 6 +++ -- wpa_supplicant/config.c | 96 +++++++++++++++++++++++++++++++++++++++ -- wpa_supplicant/config_ssid.h | 6 +++ -- wpa_supplicant/wpa_supplicant.c | 23 +++++++--- -- 4 files changed, 124 insertions(+), 7 deletions(-) -- ----- 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" --@@ -953,6 +954,9 @@ struct wpa_driver_associate_params { -- * responsible for selecting with which BSS to associate. */ -- const u8 *bssid; -- --+ unsigned char rates[WLAN_SUPP_RATES_MAX]; --+ int mcast_rate; --+ -- /** -- * bssid_hint - BSSID of a proposed AP -- * ----- a/wpa_supplicant/config.c --+++ b/wpa_supplicant/config.c --@@ -18,6 +18,7 @@ -- #include "eap_peer/eap.h" -- #include "p2p/p2p.h" -- #include "fst/fst.h" --+#include "ap/sta_info.h" -- #include "config.h" -- -- --@@ -2389,6 +2390,97 @@ static char * wpa_config_write_mac_value -- #endif /* NO_CONFIG_WRITE */ -- -- --+static int wpa_config_parse_mcast_rate(const struct parse_data *data, --+ struct wpa_ssid *ssid, int line, --+ const char *value) --+{ --+ ssid->mcast_rate = (int)(strtod(value, NULL) * 10); --+ --+ return 0; --+} --+ --+#ifndef NO_CONFIG_WRITE --+static char * wpa_config_write_mcast_rate(const struct parse_data *data, --+ struct wpa_ssid *ssid) --+{ --+ char *value; --+ int res; --+ --+ if (!ssid->mcast_rate == 0) --+ return NULL; --+ --+ value = os_malloc(6); /* longest: 300.0 */ --+ if (value == NULL) --+ return NULL; --+ res = os_snprintf(value, 5, "%.1f", (double)ssid->mcast_rate / 10); --+ if (res < 0) { --+ os_free(value); --+ return NULL; --+ } --+ return value; --+} --+#endif /* NO_CONFIG_WRITE */ --+ --+static int wpa_config_parse_rates(const struct parse_data *data, --+ struct wpa_ssid *ssid, int line, --+ const char *value) --+{ --+ int i; --+ char *pos, *r, *sptr, *end; --+ double rate; --+ --+ pos = (char *)value; --+ r = strtok_r(pos, ",", &sptr); --+ i = 0; --+ while (pos && i < WLAN_SUPP_RATES_MAX) { --+ rate = 0.0; --+ if (r) --+ rate = strtod(r, &end); --+ ssid->rates[i] = rate * 2; --+ if (*end != '\0' || rate * 2 != ssid->rates[i]) --+ return 1; --+ --+ i++; --+ r = strtok_r(NULL, ",", &sptr); --+ } --+ --+ return 0; --+} --+ --+#ifndef NO_CONFIG_WRITE --+static char * wpa_config_write_rates(const struct parse_data *data, --+ struct wpa_ssid *ssid) --+{ --+ char *value, *pos; --+ int res, i; --+ --+ if (ssid->rates[0] <= 0) --+ return NULL; --+ --+ value = os_malloc(6 * WLAN_SUPP_RATES_MAX + 1); --+ if (value == NULL) --+ return NULL; --+ pos = value; --+ for (i = 0; i < WLAN_SUPP_RATES_MAX - 1; i++) { --+ res = os_snprintf(pos, 6, "%.1f,", (double)ssid->rates[i] / 2); --+ if (res < 0) { --+ os_free(value); --+ return NULL; --+ } --+ pos += res; --+ } --+ res = os_snprintf(pos, 6, "%.1f", --+ (double)ssid->rates[WLAN_SUPP_RATES_MAX - 1] / 2); --+ if (res < 0) { --+ os_free(value); --+ return NULL; --+ } --+ --+ value[6 * WLAN_SUPP_RATES_MAX] = '\0'; --+ return value; --+} --+#endif /* NO_CONFIG_WRITE */ --+ -- /* Helper macros for network block parser */ -- -- #ifdef OFFSET --@@ -2674,6 +2766,8 @@ static const struct parse_data ssid_fiel -- { INT(ap_max_inactivity) }, -- { INT(dtim_period) }, -- { INT(beacon_int) }, --+ { FUNC(rates) }, --+ { FUNC(mcast_rate) }, -- #ifdef CONFIG_MACSEC -- { INT_RANGE(macsec_policy, 0, 1) }, -- { 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 { -- */ -- void *parent_cred; -- --+ unsigned char rates[WLAN_SUPP_RATES_MAX]; --+ double mcast_rate; --+ -- #ifdef CONFIG_MACSEC -- /** -- * macsec_policy - Determines the policy for MACsec secure session ----- a/wpa_supplicant/wpa_supplicant.c --+++ b/wpa_supplicant/wpa_supplicant.c --@@ -4203,6 +4203,12 @@ static void wpas_start_assoc_cb(struct w -- params.beacon_int = ssid->beacon_int; -- else -- params.beacon_int = wpa_s->conf->beacon_int; --+ int i = 0; --+ while (i < WLAN_SUPP_RATES_MAX) { --+ params.rates[i] = ssid->rates[i]; --+ i++; --+ } --+ params.mcast_rate = ssid->mcast_rate; -- } -- -- if (bss && ssid->enable_edmg) -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 -deleted file mode 100644 -index be9e0507d6..0000000000 ---- a/package/network/services/hostapd/patches/463-add-mcast_rate-to-11s.patch -+++ /dev/null -@@ -1,68 +0,0 @@ --From: Sven Eckelmann --Date: Thu, 11 May 2017 08:21:45 +0200 --Subject: [PATCH] set mcast_rate in mesh mode -- --The wpa_supplicant code for IBSS allows to set the mcast rate. It is --recommended to increase this value from 1 or 6 Mbit/s to something higher --when using a mesh protocol on top which uses the multicast packet loss as --indicator for the link quality. -- --This setting was unfortunately not applied for mesh mode. But it would be --beneficial when wpa_supplicant would behave similar to IBSS mode and set --this argument during mesh join like authsae already does. At least it is --helpful for companies/projects which are currently switching to 802.11s --(without mesh_fwding and with mesh_ttl set to 1) as replacement for IBSS --because newer drivers seem to support 802.11s but not IBSS anymore. -- --Signed-off-by: Sven Eckelmann --Tested-by: Simon Wunderlich -- ----- a/src/drivers/driver.h --+++ b/src/drivers/driver.h --@@ -1827,6 +1827,7 @@ struct wpa_driver_mesh_join_params { -- #define WPA_DRIVER_MESH_FLAG_AMPE 0x00000008 -- unsigned int flags; -- bool handle_dfs; --+ int mcast_rate; -- }; -- -- struct wpa_driver_set_key_params { ----- a/src/drivers/driver_nl80211.c --+++ b/src/drivers/driver_nl80211.c --@@ -11626,6 +11626,18 @@ static int nl80211_put_mesh_id(struct nl -- } -- -- --+static int nl80211_put_mcast_rate(struct nl_msg *msg, int mcast_rate) --+{ --+ if (mcast_rate > 0) { --+ wpa_printf(MSG_DEBUG, " * mcast_rate=%.1f", --+ (double)mcast_rate / 10); --+ return nla_put_u32(msg, NL80211_ATTR_MCAST_RATE, mcast_rate); --+ } --+ --+ return 0; --+} --+ --+ -- static int nl80211_put_mesh_config(struct nl_msg *msg, -- struct wpa_driver_mesh_bss_params *params) -- { --@@ -11687,6 +11699,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) || --+ nl80211_put_mcast_rate(msg, params->mcast_rate) || -- nl80211_put_dtim_period(msg, params->dtim_period)) -- goto fail; -- ----- a/wpa_supplicant/mesh.c --+++ b/wpa_supplicant/mesh.c --@@ -632,6 +632,7 @@ int wpa_supplicant_join_mesh(struct wpa_ -- -- params->meshid = ssid->ssid; -- params->meshid_len = ssid->ssid_len; --+ params->mcast_rate = ssid->mcast_rate; -- ibss_mesh_setup_freq(wpa_s, ssid, ¶ms->freq); -- wpa_s->mesh_ht_enabled = !!params->freq.ht_enabled; -- wpa_s->mesh_vht_enabled = !!params->freq.vht_enabled; -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 -deleted file mode 100644 -index c7e8cf25ce..0000000000 ---- a/package/network/services/hostapd/patches/464-fix-mesh-obss-check.patch -+++ /dev/null -@@ -1,13 +0,0 @@ ----- a/wpa_supplicant/wpa_supplicant.c --+++ b/wpa_supplicant/wpa_supplicant.c --@@ -3094,6 +3094,10 @@ void ibss_mesh_setup_freq(struct wpa_sup -- -- freq->freq = ssid->frequency; -- --+ if (ssid->fixed_freq) { --+ obss_scan = 0; --+ } --+ -- if (ssid->mode == WPAS_MODE_IBSS && !ssid->fixed_freq) { -- struct wpa_bss *bss = ibss_find_existing_bss(wpa_s, ssid); -- -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 -deleted file mode 100644 -index 7d3d94648e..0000000000 ---- a/package/network/services/hostapd/patches/465-hostapd-config-support-random-BSS-color.patch -+++ /dev/null -@@ -1,24 +0,0 @@ --From c9304d3303d563ad6d2619f4e07864ed12f96889 Mon Sep 17 00:00:00 2001 --From: David Bauer --Date: Sat, 14 May 2022 21:41:03 +0200 --Subject: [PATCH] hostapd: config: support random BSS color -- --Configure the HE BSS color to a random value in case the config defines --a BSS color which exceeds the max BSS color (63). -- --Signed-off-by: David Bauer ----- -- hostapd/config_file.c | 2 ++ -- 1 file changed, 2 insertions(+) -- ----- a/hostapd/config_file.c --+++ b/hostapd/config_file.c --@@ -3500,6 +3500,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; --+ if (atoi(pos) > 63) --+ conf->he_op.he_bss_color = os_random() % 63 + 1; -- } else if (os_strcmp(buf, "he_bss_color_partial") == 0) { -- conf->he_op.he_bss_color_partial = atoi(pos); -- } else if (os_strcmp(buf, "he_default_pe_duration") == 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 -deleted file mode 100644 -index 79ab48c5c2..0000000000 ---- a/package/network/services/hostapd/patches/470-survey_data_fallback.patch -+++ /dev/null -@@ -1,30 +0,0 @@ ----- a/src/ap/acs.c --+++ b/src/ap/acs.c --@@ -455,17 +455,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)) { --+ survey->nf = -95; -- wpa_printf(MSG_INFO, -- "ACS: Survey for freq %d is missing noise floor", -- survey->freq); --- return 0; -- } -- -- if (!(survey->filled & SURVEY_HAS_CHAN_TIME)) { --+ survey->channel_time = 0; -- wpa_printf(MSG_INFO, -- "ACS: Survey for freq %d is missing channel time", -- survey->freq); --- return 0; -- } -- -- if (!(survey->filled & SURVEY_HAS_CHAN_TIME_BUSY) && --@@ -473,7 +473,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); --- return 0; -- } -- -- return 1; -diff --git a/package/network/services/hostapd/patches/500-lto-jobserver-support.patch b/package/network/services/hostapd/patches/500-lto-jobserver-support.patch -deleted file mode 100644 -index 046da42ab8..0000000000 ---- a/package/network/services/hostapd/patches/500-lto-jobserver-support.patch -+++ /dev/null -@@ -1,59 +0,0 @@ ----- a/hostapd/Makefile --+++ b/hostapd/Makefile --@@ -1396,7 +1396,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 --@@ -1407,7 +1407,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 --@@ -2039,31 +2039,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/590-rrm-wnm-statistics.patch b/package/network/services/hostapd/patches/590-rrm-wnm-statistics.patch -deleted file mode 100644 -index 0efa6db908..0000000000 ---- a/package/network/services/hostapd/patches/590-rrm-wnm-statistics.patch -+++ /dev/null -@@ -1,92 +0,0 @@ ----- a/src/ap/hostapd.h --+++ b/src/ap/hostapd.h --@@ -163,6 +163,21 @@ struct hostapd_sae_commit_queue { -- }; -- -- /** --+ * struct hostapd_openwrt_stats - OpenWrt custom STA/AP statistics --+ */ --+struct hostapd_openwrt_stats { --+ struct { --+ u64 neighbor_report_tx; --+ } rrm; --+ --+ struct { --+ u64 bss_transition_query_rx; --+ u64 bss_transition_request_tx; --+ u64 bss_transition_response_rx; --+ } wnm; --+}; --+ --+/** -- * struct hostapd_data - hostapd per-BSS data structure -- */ -- struct hostapd_data { --@@ -182,6 +197,9 @@ struct hostapd_data { -- -- struct hostapd_data *mld_first_bss; -- --+ /* OpenWrt specific statistics */ --+ struct hostapd_openwrt_stats openwrt_stats; --+ -- 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/wnm_ap.c --+++ b/src/ap/wnm_ap.c --@@ -386,6 +386,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; -- --+ hapd->openwrt_stats.wnm.bss_transition_request_tx++; -- 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 -- plen); -- return 0; -- case WNM_BSS_TRANS_MGMT_QUERY: --+ hapd->openwrt_stats.wnm.bss_transition_query_rx++; -- ieee802_11_rx_bss_trans_mgmt_query(hapd, mgmt->sa, payload, -- plen); -- return 0; -- case WNM_BSS_TRANS_MGMT_RESP: --+ hapd->openwrt_stats.wnm.bss_transition_response_rx++; -- 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 -- -- pos = mgmt->u.action.u.bss_tm_req.variable; -- --+ hapd->openwrt_stats.wnm.bss_transition_request_tx++; -- 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 -- return -1; -- } -- --+ hapd->openwrt_stats.wnm.bss_transition_request_tx++; -- 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 -- } -- 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); -diff --git a/package/network/services/hostapd/patches/599-wpa_supplicant-fix-warnings.patch b/package/network/services/hostapd/patches/599-wpa_supplicant-fix-warnings.patch -deleted file mode 100644 -index e70dc61419..0000000000 ---- a/package/network/services/hostapd/patches/599-wpa_supplicant-fix-warnings.patch -+++ /dev/null -@@ -1,19 +0,0 @@ ----- 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/600-ubus_support.patch b/package/network/services/hostapd/patches/600-ubus_support.patch -deleted file mode 100644 -index f3936342a5..0000000000 ---- a/package/network/services/hostapd/patches/600-ubus_support.patch -+++ /dev/null -@@ -1,625 +0,0 @@ ----- a/hostapd/Makefile --+++ b/hostapd/Makefile --@@ -166,6 +166,11 @@ OBJS += ../src/common/hw_features_common -- -- OBJS += ../src/eapol_auth/eapol_auth_sm.o -- --+ifdef CONFIG_UBUS --+CFLAGS += -DUBUS_SUPPORT --+OBJS += ../src/ap/ubus.o --+LIBS += -lubox -lubus --+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" -- -- #define OCE_STA_CFON_ENABLED(hapd) \ -- ((hapd->conf->oce & OCE_STA_CFON) && \ --@@ -92,7 +93,7 @@ struct hapd_interfaces { -- #ifdef CONFIG_CTRL_IFACE_UDP -- unsigned char ctrl_iface_cookie[CTRL_IFACE_COOKIE_LEN]; -- #endif /* CONFIG_CTRL_IFACE_UDP */ --- --+ struct ubus_object ubus; -- }; -- -- enum hostapd_chan_status { --@@ -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); ----- a/src/ap/hostapd.c --+++ b/src/ap/hostapd.c --@@ -455,6 +455,7 @@ void hostapd_free_hapd_data(struct hosta -- hapd->beacon_set_done = 0; -- -- wpa_printf(MSG_DEBUG, "%s(%s)", __func__, hapd->conf->iface); --+ hostapd_ubus_free_bss(hapd); -- accounting_deinit(hapd); -- hostapd_deinit_wpa(hapd); -- vlan_deinit(hapd); --@@ -1207,6 +1208,8 @@ static int hostapd_start_beacon(struct h -- if (hapd->driver && hapd->driver->set_operstate) -- hapd->driver->set_operstate(hapd->drv_priv, 1); -- --+ hostapd_ubus_add_bss(hapd); --+ -- return 0; -- } -- --@@ -2295,6 +2298,7 @@ static int hostapd_setup_interface_compl -- if (err) -- goto fail; -- --+ hostapd_ubus_add_iface(iface); -- wpa_printf(MSG_DEBUG, "Completing interface initialization"); -- if (iface->freq) { -- #ifdef NEED_AP_MLME --@@ -2514,6 +2518,7 @@ dfs_offload: -- -- fail: -- wpa_printf(MSG_ERROR, "Interface initialization failed"); --+ hostapd_ubus_free_iface(iface); -- -- if (iface->is_no_ir) { -- hostapd_set_state(iface, HAPD_IFACE_NO_IR); --@@ -3004,6 +3009,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; --+ hostapd_ubus_free_iface(iface); -- hostapd_interface_deinit(iface); -- wpa_printf(MSG_DEBUG, "%s: driver=%p drv_priv=%p -> hapd_deinit", -- __func__, driver, drv_priv); ----- a/src/ap/ieee802_11.c --+++ b/src/ap/ieee802_11.c --@@ -2778,7 +2778,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; --- int res, reply_res; --+ int res, reply_res, ubus_resp; -- u16 fc; -- const u8 *challenge = NULL; -- u8 resp_ies[2 + WLAN_AUTH_CHALLENGE_LEN]; --@@ -2787,6 +2787,11 @@ static void handle_auth(struct hostapd_d -- struct radius_sta rad_info; -- const u8 *dst, *sa, *bssid; -- bool mld_sta = false; --+ struct hostapd_ubus_request req = { --+ .type = HOSTAPD_UBUS_AUTH_REQ, --+ .mgmt_frame = mgmt, --+ .ssi_signal = rssi, --+ }; -- -- if (len < IEEE80211_HDRLEN + sizeof(mgmt->u.auth)) { -- wpa_printf(MSG_INFO, "handle_auth - too short payload (len=%lu)", --@@ -2978,6 +2983,13 @@ static void handle_auth(struct hostapd_d -- resp = WLAN_STATUS_UNSPECIFIED_FAILURE; -- goto fail; -- } --+ ubus_resp = hostapd_ubus_handle_event(hapd, &req); --+ if (ubus_resp) { --+ wpa_printf(MSG_DEBUG, "Station " MACSTR " rejected by ubus handler.\n", --+ MAC2STR(mgmt->sa)); --+ resp = ubus_resp > 0 ? (u16) ubus_resp : WLAN_STATUS_UNSPECIFIED_FAILURE; --+ goto fail; --+ } -- if (res == HOSTAPD_ACL_PENDING) -- return; -- --@@ -5141,7 +5153,7 @@ static void handle_assoc(struct hostapd_ -- int resp = WLAN_STATUS_SUCCESS; -- u16 reply_res = WLAN_STATUS_UNSPECIFIED_FAILURE; -- const u8 *pos; --- int left, i; --+ int left, i, ubus_resp; -- struct sta_info *sta; -- u8 *tmp = NULL; -- #ifdef CONFIG_FILS --@@ -5354,6 +5366,11 @@ static void handle_assoc(struct hostapd_ -- left = res; -- } -- #endif /* CONFIG_FILS */ --+ struct hostapd_ubus_request req = { --+ .type = HOSTAPD_UBUS_ASSOC_REQ, --+ .mgmt_frame = mgmt, --+ .ssi_signal = rssi, --+ }; -- -- /* followed by SSID and Supported rates; and HT capabilities if 802.11n -- * is used */ --@@ -5452,6 +5469,13 @@ static void handle_assoc(struct hostapd_ -- } -- #endif /* CONFIG_FILS */ -- --+ ubus_resp = hostapd_ubus_handle_event(hapd, &req); --+ if (ubus_resp) { --+ wpa_printf(MSG_DEBUG, "Station " MACSTR " assoc rejected by ubus handler.\n", --+ MAC2STR(mgmt->sa)); --+ resp = ubus_resp > 0 ? (u16) ubus_resp : WLAN_STATUS_UNSPECIFIED_FAILURE; --+ goto fail; --+ } -- fail: -- -- /* --@@ -5733,6 +5757,7 @@ static void handle_disassoc(struct hosta -- (unsigned long) len); -- return; -- } --+ hostapd_ubus_notify(hapd, "disassoc", mgmt->sa); -- -- sta = ap_get_sta(hapd, mgmt->sa); -- if (!sta) { --@@ -5764,6 +5789,8 @@ static void handle_deauth(struct hostapd -- /* Clear the PTKSA cache entries for PASN */ -- ptksa_cache_flush(hapd->ptksa, mgmt->sa, WPA_CIPHER_NONE); -- --+ hostapd_ubus_notify(hapd, "deauth", mgmt->sa); --+ -- 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 --@@ -1036,6 +1036,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) --@@ -1222,6 +1228,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/drv_callbacks.c --+++ b/src/ap/drv_callbacks.c --@@ -145,6 +145,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) { -- /* --@@ -237,6 +241,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/sta_info.c --+++ b/src/ap/sta_info.c --@@ -471,6 +471,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"); --+ hostapd_ubus_notify(hapd, "local-deauth", sta->addr); -- ap_free_sta(hapd, sta); -- return; -- } --@@ -626,6 +627,7 @@ skip_poll: -- mlme_deauthenticate_indication( -- hapd, sta, -- WLAN_REASON_PREV_AUTH_NOT_VALID); --+ hostapd_ubus_notify(hapd, "inactive-deauth", sta->addr); -- ap_free_sta(hapd, sta); -- break; -- } --@@ -1344,15 +1346,28 @@ void ap_sta_set_authorized(struct hostap -- sta->addr, authorized, dev_addr); -- -- if (authorized) { --+ static const char * const auth_algs[] = { --+ [WLAN_AUTH_OPEN] = "open", --+ [WLAN_AUTH_SHARED_KEY] = "shared", --+ [WLAN_AUTH_FT] = "ft", --+ [WLAN_AUTH_SAE] = "sae", --+ [WLAN_AUTH_FILS_SK] = "fils-sk", --+ [WLAN_AUTH_FILS_SK_PFS] = "fils-sk-pfs", --+ [WLAN_AUTH_FILS_PK] = "fils-pk", --+ [WLAN_AUTH_PASN] = "pasn", --+ }; --+ const char *auth_alg = NULL; -- const u8 *dpp_pkhash; -- const char *keyid; -- char dpp_pkhash_buf[100]; -- char keyid_buf[100]; -- char ip_addr[100]; --+ char alg_buf[100]; -- -- dpp_pkhash_buf[0] = '\0'; -- keyid_buf[0] = '\0'; -- ip_addr[0] = '\0'; --+ alg_buf[0] = '\0'; -- #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 --@@ -194,6 +194,12 @@ ifdef CONFIG_EAPOL_TEST -- CFLAGS += -Werror -DEAPOL_TEST -- endif -- --+ifdef CONFIG_UBUS --+CFLAGS += -DUBUS_SUPPORT --+OBJS += ubus.o --+LIBS += -lubox -lubus --+endif --+ -- ifdef CONFIG_CODE_COVERAGE -- CFLAGS += -O0 -fprofile-arcs -ftest-coverage -- LIBS += -lgcov --@@ -989,6 +995,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 --@@ -7635,6 +7635,8 @@ struct wpa_supplicant * wpa_supplicant_a -- } -- #endif /* CONFIG_P2P */ -- --+ wpas_ubus_add_bss(wpa_s); --+ -- return wpa_s; -- } -- --@@ -7661,6 +7663,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) { --@@ -8007,8 +8011,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; --@@ -324,6 +325,8 @@ struct wpa_global { -- #endif /* CONFIG_WIFI_DISPLAY */ -- -- struct psk_list_entry *add_psk; /* From group formation */ --+ --+ struct ubus_object ubus_global; -- }; -- -- --@@ -655,6 +658,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; -- ----- a/hostapd/main.c --+++ b/hostapd/main.c --@@ -991,6 +991,7 @@ int main(int argc, char *argv[]) -- } -- -- hostapd_global_ctrl_iface_init(&interfaces); --+ hostapd_ubus_add(&interfaces); -- -- if (hostapd_global_run(&interfaces, daemonize, pid_file)) { -- wpa_printf(MSG_ERROR, "Failed to start eloop"); --@@ -1000,6 +1001,7 @@ int main(int argc, char *argv[]) -- ret = 0; -- -- out: --+ hostapd_ubus_free(&interfaces); -- hostapd_global_ctrl_iface_deinit(&interfaces); -- /* Deinitialize all interfaces */ -- for (i = 0; i < interfaces.count; i++) { ----- a/wpa_supplicant/main.c --+++ b/wpa_supplicant/main.c --@@ -204,7 +204,7 @@ int main(int argc, char *argv[]) -- -- for (;;) { -- c = getopt(argc, argv, --- "b:Bc:C:D:de:f:g:G:hH:i:I:KLMm:No:O:p:P:qsTtuv::W"); --+ "b:Bc:C:D:de:f:g:G:hH:i:I:KLMm:nNo:O:p:P:qsTtuv::W"); -- if (c < 0) -- break; -- switch (c) { --@@ -272,6 +272,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); -- } -- -- --@@ -352,6 +355,9 @@ void hostapd_handle_radio_measurement(st -- mgmt->u.action.u.rrm.action, MAC2STR(mgmt->sa)); -- -- 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 @@ -- static int vlan_if_add(struct hostapd_data *hapd, struct hostapd_vlan *vlan, -- int existsok) -- { --+ bool vlan_exists = iface_exists(vlan->ifname); -- int ret; -- #ifdef CONFIG_WEP -- int i; --@@ -36,7 +37,7 @@ static int vlan_if_add(struct hostapd_da -- } -- #endif /* CONFIG_WEP */ -- --- if (!iface_exists(vlan->ifname)) --+ if (!vlan_exists) -- ret = hostapd_vlan_if_add(hapd, vlan->ifname); -- else if (!existsok) -- return -1; --@@ -51,6 +52,9 @@ static int vlan_if_add(struct hostapd_da -- if (hapd->wpa_auth) -- ret = wpa_auth_ensure_group(hapd->wpa_auth, vlan->vlan_id); -- --+ if (!ret && !vlan_exists) --+ hostapd_ubus_add_vlan(hapd, vlan); --+ -- if (ret == 0) -- return ret; -- --@@ -77,6 +81,8 @@ int vlan_if_remove(struct hostapd_data * -- "WPA deinitialization for VLAN %d failed (%d)", -- vlan->vlan_id, ret); -- --+ hostapd_ubus_remove_vlan(hapd, vlan); --+ -- return hostapd_vlan_if_remove(hapd, vlan->ifname); -- } -- ----- a/src/ap/dfs.c --+++ b/src/ap/dfs.c --@@ -1211,6 +1211,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 -- MAC2STR(addr), reason, hex ? " neighbor=" : "", hex); -- os_free(hex); -- --- ieee802_11_send_bss_trans_mgmt_request(hapd, addr, dialog_token); --+ if (!hostapd_ubus_notify_bss_transition_query(hapd, addr, dialog_token, reason, pos, end - pos)) --+ ieee802_11_send_bss_trans_mgmt_request(hapd, addr, dialog_token); -- } -- -- --@@ -477,7 +478,7 @@ static void ieee802_11_rx_bss_trans_mgmt -- size_t len) -- { -- u8 dialog_token, status_code, bss_termination_delay; --- const u8 *pos, *end; --+ const u8 *pos, *end, *target_bssid = NULL; -- int enabled = hapd->conf->bss_transition; -- struct sta_info *sta; -- --@@ -524,6 +525,7 @@ static void ieee802_11_rx_bss_trans_mgmt -- wpa_printf(MSG_DEBUG, "WNM: not enough room for Target BSSID field"); -- return; -- } --+ target_bssid = pos; -- 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 -- MAC2STR(addr), status_code, bss_termination_delay); -- } -- --+ hostapd_ubus_notify_bss_transition_response(hapd, sta->addr, dialog_token, --+ status_code, bss_termination_delay, --+ target_bssid, pos, end - pos); --+ -- wpa_hexdump(MSG_DEBUG, "WNM: BSS Transition Candidate List Entries", -- pos, end - pos); -- } -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 -deleted file mode 100644 -index a03fcc9f92..0000000000 ---- a/package/network/services/hostapd/patches/610-hostapd_cli_ujail_permission.patch -+++ /dev/null -@@ -1,33 +0,0 @@ ----- a/src/common/wpa_ctrl.c --+++ b/src/common/wpa_ctrl.c --@@ -135,7 +135,7 @@ try_again: -- return NULL; -- } -- tries++; ---#ifdef ANDROID --+ -- /* Set client socket file permissions so that bind() creates the client -- * socket with these permissions and there is no need to try to change -- * them with chmod() after bind() which would have potential issues with --@@ -147,7 +147,7 @@ try_again: -- * operations to allow the response to go through. Those are using the -- * no-deference-symlinks version to avoid races. */ -- fchmod(ctrl->s, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP); ---#endif /* ANDROID */ --+ -- if (bind(ctrl->s, (struct sockaddr *) &ctrl->local, -- sizeof(ctrl->local)) < 0) { -- if (errno == EADDRINUSE && tries < 2) { --@@ -165,7 +165,11 @@ try_again: -- return NULL; -- } -- ---#ifdef ANDROID --+#ifndef ANDROID --+ /* Set group even if we do not have privileges to change owner */ --+ lchown(ctrl->local.sun_path, -1, 101); --+ lchown(ctrl->local.sun_path, 101, 101); --+#else -- /* Set group even if we do not have privileges to change owner */ -- lchown(ctrl->local.sun_path, -1, AID_WIFI); -- lchown(ctrl->local.sun_path, AID_SYSTEM, AID_WIFI); -diff --git a/package/network/services/hostapd/patches/700-wifi-reload.patch b/package/network/services/hostapd/patches/700-wifi-reload.patch -deleted file mode 100644 -index 0c7627645f..0000000000 ---- a/package/network/services/hostapd/patches/700-wifi-reload.patch -+++ /dev/null -@@ -1,194 +0,0 @@ ----- a/hostapd/config_file.c --+++ b/hostapd/config_file.c --@@ -2420,6 +2420,8 @@ static int hostapd_config_fill(struct ho -- bss->isolate = atoi(pos); -- } else if (os_strcmp(buf, "ap_max_inactivity") == 0) { -- bss->ap_max_inactivity = atoi(pos); --+ } else if (os_strcmp(buf, "config_id") == 0) { --+ bss->config_id = os_strdup(pos); -- } else if (os_strcmp(buf, "skip_inactivity_poll") == 0) { -- bss->skip_inactivity_poll = atoi(pos); -- } else if (os_strcmp(buf, "config_id") == 0) { --@@ -3130,6 +3132,8 @@ static int hostapd_config_fill(struct ho -- } -- } else if (os_strcmp(buf, "acs_exclude_dfs") == 0) { -- conf->acs_exclude_dfs = atoi(pos); --+ } else if (os_strcmp(buf, "radio_config_id") == 0) { --+ conf->config_id = os_strdup(pos); -- } else if (os_strcmp(buf, "op_class") == 0) { -- conf->op_class = atoi(pos); -- } else if (os_strcmp(buf, "channel") == 0) { ----- a/src/ap/ap_config.c --+++ b/src/ap/ap_config.c --@@ -998,6 +998,7 @@ void hostapd_config_free(struct hostapd_ -- -- for (i = 0; i < conf->num_bss; i++) -- hostapd_config_free_bss(conf->bss[i]); --+ os_free(conf->config_id); -- os_free(conf->bss); -- os_free(conf->supported_rates); -- os_free(conf->basic_rates); ----- a/src/ap/ap_config.h --+++ b/src/ap/ap_config.h --@@ -998,6 +998,7 @@ struct eht_phy_capabilities_info { -- struct hostapd_config { -- struct hostapd_bss_config **bss, *last_bss; -- size_t num_bss; --+ char *config_id; -- -- u16 beacon_int; -- int rts_threshold; ----- a/src/ap/hostapd.c --+++ b/src/ap/hostapd.c --@@ -255,6 +255,10 @@ static int hostapd_iface_conf_changed(st -- { -- size_t i; -- --+ if (newconf->config_id != oldconf->config_id) --+ if (strcmp(newconf->config_id, oldconf->config_id)) --+ return 1; --+ -- if (newconf->num_bss != oldconf->num_bss) -- return 1; -- --@@ -268,7 +272,7 @@ static int hostapd_iface_conf_changed(st -- } -- -- ---int hostapd_reload_config(struct hostapd_iface *iface) --+int hostapd_reload_config(struct hostapd_iface *iface, int reconf) -- { -- struct hapd_interfaces *interfaces = iface->interfaces; -- struct hostapd_data *hapd = iface->bss[0]; --@@ -296,6 +300,9 @@ int hostapd_reload_config(struct hostapd -- char *fname; -- int res; -- --+ if (reconf) --+ return -1; --+ -- hostapd_clear_old(iface); -- -- wpa_printf(MSG_DEBUG, --@@ -322,6 +329,24 @@ int hostapd_reload_config(struct hostapd -- wpa_printf(MSG_ERROR, -- "Failed to enable interface on config reload"); -- return res; --+ } else { --+ for (j = 0; j < iface->num_bss; j++) { --+ hapd = iface->bss[j]; --+ if (!hapd->config_id || strcmp(hapd->config_id, newconf->bss[j]->config_id)) { --+ hostapd_flush_old_stations(iface->bss[j], --+ WLAN_REASON_PREV_AUTH_NOT_VALID); --+#ifdef CONFIG_WEP --+ hostapd_broadcast_wep_clear(iface->bss[j]); --+#endif --+ --+#ifndef CONFIG_NO_RADIUS --+ /* TODO: update dynamic data based on changed configuration --+ * items (e.g., open/close sockets, etc.) */ --+ radius_client_flush(iface->bss[j]->radius, 0); --+#endif /* CONFIG_NO_RADIUS */ --+ wpa_printf(MSG_INFO, "bss %zu changed", j); --+ } --+ } -- } -- iface->conf = newconf; -- --@@ -338,6 +363,12 @@ int hostapd_reload_config(struct hostapd -- -- for (j = 0; j < iface->num_bss; j++) { -- hapd = iface->bss[j]; --+ if (hapd->config_id) { --+ os_free(hapd->config_id); --+ hapd->config_id = NULL; --+ } --+ if (newconf->bss[j]->config_id) --+ hapd->config_id = strdup(newconf->bss[j]->config_id); -- if (!hapd->conf->config_id || !newconf->bss[j]->config_id || -- os_strcmp(hapd->conf->config_id, -- newconf->bss[j]->config_id) != 0) --@@ -2700,6 +2731,10 @@ hostapd_alloc_bss_data(struct hostapd_if -- hapd->iconf = conf; -- hapd->conf = bss; -- hapd->iface = hapd_iface; --+ if (bss && bss->config_id) --+ hapd->config_id = strdup(bss->config_id); --+ else --+ hapd->config_id = NULL; -- if (conf) -- hapd->driver = conf->driver; -- hapd->ctrl_sock = -1; ----- a/src/ap/hostapd.h --+++ b/src/ap/hostapd.h --@@ -47,7 +47,7 @@ struct mesh_conf; -- struct hostapd_iface; -- -- struct hapd_interfaces { --- int (*reload_config)(struct hostapd_iface *iface); --+ int (*reload_config)(struct hostapd_iface *iface, int reconf); -- 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); --@@ -186,6 +186,7 @@ struct hostapd_data { -- struct hostapd_config *iconf; -- struct hostapd_bss_config *conf; -- struct hostapd_ubus_bss ubus; --+ char *config_id; -- int interface_added; /* virtual interface added for this BSS */ -- unsigned int started:1; -- unsigned int disabled:1; --@@ -689,7 +690,7 @@ struct hostapd_iface { -- int hostapd_for_each_interface(struct hapd_interfaces *interfaces, -- int (*cb)(struct hostapd_iface *iface, -- void *ctx), void *ctx); ---int hostapd_reload_config(struct hostapd_iface *iface); --+int hostapd_reload_config(struct hostapd_iface *iface, int reconf); -- void hostapd_reconfig_encryption(struct hostapd_data *hapd); -- struct hostapd_data * -- hostapd_alloc_bss_data(struct hostapd_iface *hapd_iface, ----- a/src/drivers/driver_nl80211.c --+++ b/src/drivers/driver_nl80211.c --@@ -5322,6 +5322,9 @@ static int wpa_driver_nl80211_set_ap(voi -- if (ret) { -- wpa_printf(MSG_DEBUG, "nl80211: Beacon set failed: %d (%s)", -- ret, strerror(-ret)); --+ if (!bss->flink->beacon_set) --+ ret = 0; --+ bss->flink->beacon_set = 0; -- } else { -- link->beacon_set = 1; -- nl80211_set_bss(bss, params->cts_protect, params->preamble, ----- a/hostapd/ctrl_iface.c --+++ b/hostapd/ctrl_iface.c --@@ -187,7 +187,7 @@ static int hostapd_ctrl_iface_update(str -- iface->interfaces->config_read_cb = hostapd_ctrl_iface_config_read; -- reload_opts = txt; -- --- hostapd_reload_config(iface); --+ hostapd_reload_config(iface, 0); -- -- iface->interfaces->config_read_cb = config_read_cb; -- } ----- a/hostapd/main.c --+++ b/hostapd/main.c --@@ -410,7 +410,7 @@ static void handle_term(int sig, void *s -- -- static int handle_reload_iface(struct hostapd_iface *iface, void *ctx) -- { --- if (hostapd_reload_config(iface) < 0) { --+ if (hostapd_reload_config(iface, 0) < 0) { -- wpa_printf(MSG_WARNING, "Failed to read new configuration " -- "file - continuing with old."); -- } ----- a/src/ap/wps_hostapd.c --+++ b/src/ap/wps_hostapd.c --@@ -315,7 +315,7 @@ static void wps_reload_config(void *eloo -- -- wpa_printf(MSG_DEBUG, "WPS: Reload configuration data"); -- if (iface->interfaces == NULL || --- iface->interfaces->reload_config(iface) < 0) { --+ iface->interfaces->reload_config(iface, 1) < 0) { -- wpa_printf(MSG_WARNING, "WPS: Failed to reload the updated " -- "configuration"); -- } -diff --git a/package/network/services/hostapd/patches/710-vlan_no_bridge.patch b/package/network/services/hostapd/patches/710-vlan_no_bridge.patch -deleted file mode 100644 -index 61f33acb6e..0000000000 ---- a/package/network/services/hostapd/patches/710-vlan_no_bridge.patch -+++ /dev/null -@@ -1,41 +0,0 @@ ----- a/src/ap/ap_config.h --+++ b/src/ap/ap_config.h --@@ -121,6 +121,7 @@ struct hostapd_ssid { -- #define DYNAMIC_VLAN_OPTIONAL 1 -- #define DYNAMIC_VLAN_REQUIRED 2 -- int dynamic_vlan; --+ int vlan_no_bridge; -- #define DYNAMIC_VLAN_NAMING_WITHOUT_DEVICE 0 -- #define DYNAMIC_VLAN_NAMING_WITH_DEVICE 1 -- #define DYNAMIC_VLAN_NAMING_END 2 ----- a/src/ap/vlan_full.c --+++ b/src/ap/vlan_full.c --@@ -475,6 +475,9 @@ void vlan_newlink(const char *ifname, st -- if (!vlan) -- return; -- --+ if (hapd->conf->ssid.vlan_no_bridge) --+ goto out; --+ -- vlan->configured = 1; -- -- notempty = vlan->vlan_desc.notempty; --@@ -506,6 +509,7 @@ void vlan_newlink(const char *ifname, st -- ifname, br_name, tagged[i], hapd); -- } -- --+out: -- ifconfig_up(ifname); -- } -- ----- a/hostapd/config_file.c --+++ b/hostapd/config_file.c --@@ -3355,6 +3355,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 -deleted file mode 100644 -index c0f2c31c44..0000000000 ---- a/package/network/services/hostapd/patches/711-wds_bridge_force.patch -+++ /dev/null -@@ -1,22 +0,0 @@ ----- a/hostapd/config_file.c --+++ b/hostapd/config_file.c --@@ -2318,6 +2318,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)); --+ if (!bss->wds_bridge[0]) --+ 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, "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 -- return -1; -- if (hapd->conf->wds_bridge[0]) -- bridge = hapd->conf->wds_bridge; --- else if (hapd->conf->bridge[0]) --- bridge = hapd->conf->bridge; -- return hapd->driver->set_wds_sta(hapd->drv_priv, addr, aid, val, -- bridge, ifname_wds); -- } -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 -deleted file mode 100644 -index 0bb00f9555..0000000000 ---- a/package/network/services/hostapd/patches/720-iface_max_num_sta.patch -+++ /dev/null -@@ -1,82 +0,0 @@ ----- a/hostapd/config_file.c --+++ b/hostapd/config_file.c --@@ -2850,6 +2850,14 @@ static int hostapd_config_fill(struct ho -- line, bss->max_num_sta, MAX_STA_COUNT); -- return 1; -- } --+ } else if (os_strcmp(buf, "iface_max_num_sta") == 0) { --+ conf->max_num_sta = atoi(pos); --+ if (conf->max_num_sta < 0 || --+ conf->max_num_sta > MAX_STA_COUNT) { --+ wpa_printf(MSG_ERROR, "Line %d: Invalid max_num_sta=%d; allowed range 0..%d", --+ line, conf->max_num_sta, MAX_STA_COUNT); --+ return 1; --+ } -- } 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 --@@ -734,6 +734,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); -- -- void hostapd_switch_color(struct hostapd_data *hapd, u64 bitmap); -- void hostapd_cleanup_cca_params(struct hostapd_data *hapd); ----- a/src/ap/hostapd.c --+++ b/src/ap/hostapd.c --@@ -272,6 +272,30 @@ static int hostapd_iface_conf_changed(st -- } -- -- --+static inline int hostapd_iface_num_sta(struct hostapd_iface *iface) --+{ --+ int num_sta = 0; --+ int i; --+ --+ for (i = 0; i < iface->num_bss; i++) --+ num_sta += iface->bss[i]->num_sta; --+ --+ return num_sta; --+} --+ --+ --+int hostapd_check_max_sta(struct hostapd_data *hapd) --+{ --+ if (hapd->num_sta >= hapd->conf->max_num_sta) --+ return 1; --+ --+ if (hapd->iconf->max_num_sta && --+ hostapd_iface_num_sta(hapd->iface) >= hapd->iconf->max_num_sta) --+ return 1; --+ --+ return 0; --+} --+ -- int hostapd_reload_config(struct hostapd_iface *iface, int reconf) -- { -- struct hapd_interfaces *interfaces = iface->interfaces; ----- a/src/ap/beacon.c --+++ b/src/ap/beacon.c --@@ -1252,7 +1252,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 --@@ -1037,6 +1037,8 @@ struct hostapd_config { -- unsigned int track_sta_max_num; -- unsigned int track_sta_max_age; -- --+ 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 -diff --git a/package/network/services/hostapd/patches/730-ft_iface.patch b/package/network/services/hostapd/patches/730-ft_iface.patch -deleted file mode 100644 -index 563fe5b5fb..0000000000 ---- a/package/network/services/hostapd/patches/730-ft_iface.patch -+++ /dev/null -@@ -1,38 +0,0 @@ ----- a/hostapd/config_file.c --+++ b/hostapd/config_file.c --@@ -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 --+ } else if (os_strcmp(buf, "ft_iface") == 0) { --+ os_strlcpy(bss->ft_iface, pos, sizeof(bss->ft_iface)); -- } else if (os_strcmp(buf, "mobility_domain") == 0) { -- if (os_strlen(pos) != 2 * MOBILITY_DOMAIN_ID_LEN || -- hexstr2bin(pos, bss->mobility_domain, ----- a/src/ap/ap_config.h --+++ b/src/ap/ap_config.h --@@ -283,6 +283,7 @@ struct airtime_sta_weight { -- struct hostapd_bss_config { -- char iface[IFNAMSIZ + 1]; -- char bridge[IFNAMSIZ + 1]; --+ char ft_iface[IFNAMSIZ + 1]; -- char vlan_bridge[IFNAMSIZ + 1]; -- char wds_bridge[IFNAMSIZ + 1]; -- 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 -- wpa_key_mgmt_ft(hapd->conf->wpa_key_mgmt)) { -- const char *ft_iface; -- --- ft_iface = hapd->conf->bridge[0] ? hapd->conf->bridge : --- hapd->conf->iface; --+ if (hapd->conf->ft_iface[0]) --+ ft_iface = hapd->conf->ft_iface; --+ else if (hapd->conf->bridge[0]) --+ ft_iface = hapd->conf->bridge; --+ else --+ ft_iface = hapd->conf->iface; -- hapd->l2 = l2_packet_init(ft_iface, NULL, ETH_P_RRB, -- hostapd_rrb_receive, hapd, 1); -- if (!hapd->l2) { -diff --git a/package/network/services/hostapd/patches/740-snoop_iface.patch b/package/network/services/hostapd/patches/740-snoop_iface.patch -deleted file mode 100644 -index 6b6cc0fad7..0000000000 ---- a/package/network/services/hostapd/patches/740-snoop_iface.patch -+++ /dev/null -@@ -1,66 +0,0 @@ ----- a/src/ap/ap_config.h --+++ b/src/ap/ap_config.h --@@ -284,6 +284,7 @@ struct hostapd_bss_config { -- char iface[IFNAMSIZ + 1]; -- char bridge[IFNAMSIZ + 1]; -- char ft_iface[IFNAMSIZ + 1]; --+ char snoop_iface[IFNAMSIZ + 1]; -- char vlan_bridge[IFNAMSIZ + 1]; -- char wds_bridge[IFNAMSIZ + 1]; -- int bridge_hairpin; /* hairpin_mode on bridge members */ ----- a/src/ap/x_snoop.c --+++ b/src/ap/x_snoop.c --@@ -33,14 +33,16 @@ int x_snoop_init(struct hostapd_data *ha -- -- hapd->x_snoop_initialized = true; -- --- if (hostapd_drv_br_port_set_attr(hapd, DRV_BR_PORT_ATTR_HAIRPIN_MODE, --+ if (!conf->snoop_iface[0] && --+ hostapd_drv_br_port_set_attr(hapd, DRV_BR_PORT_ATTR_HAIRPIN_MODE, -- 1)) { -- wpa_printf(MSG_DEBUG, -- "x_snoop: Failed to enable hairpin_mode on the bridge port"); -- return -1; -- } -- --- if (hostapd_drv_br_port_set_attr(hapd, DRV_BR_PORT_ATTR_PROXYARP, 1)) { --+ if (!conf->snoop_iface[0] && --+ hostapd_drv_br_port_set_attr(hapd, DRV_BR_PORT_ATTR_PROXYARP, 1)) { -- wpa_printf(MSG_DEBUG, -- "x_snoop: Failed to enable proxyarp on the bridge port"); -- return -1; --@@ -54,7 +56,8 @@ int x_snoop_init(struct hostapd_data *ha -- } -- -- #ifdef CONFIG_IPV6 --- if (hostapd_drv_br_set_net_param(hapd, DRV_BR_MULTICAST_SNOOPING, 1)) { --+ if (!conf->snoop_iface[0] && --+ hostapd_drv_br_set_net_param(hapd, DRV_BR_MULTICAST_SNOOPING, 1)) { -- wpa_printf(MSG_DEBUG, -- "x_snoop: Failed to enable multicast snooping on the bridge"); -- return -1; --@@ -73,8 +76,12 @@ x_snoop_get_l2_packet(struct hostapd_dat -- { -- struct hostapd_bss_config *conf = hapd->conf; -- struct l2_packet_data *l2; --+ const char *ifname = conf->bridge; -- --- l2 = l2_packet_init(conf->bridge, NULL, ETH_P_ALL, handler, hapd, 1); --+ if (conf->snoop_iface[0]) --+ ifname = conf->snoop_iface; --+ --+ l2 = l2_packet_init(ifname, NULL, ETH_P_ALL, handler, hapd, 1); -- if (l2 == NULL) { -- wpa_printf(MSG_DEBUG, -- "x_snoop: Failed to initialize L2 packet processing %s", ----- 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) { -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 -deleted file mode 100644 -index 124f5ea6ba..0000000000 ---- a/package/network/services/hostapd/patches/750-qos_map_set_without_interworking.patch -+++ /dev/null -@@ -1,97 +0,0 @@ ----- a/hostapd/config_file.c --+++ b/hostapd/config_file.c --@@ -1604,6 +1604,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) --@@ -1645,8 +1647,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, --@@ -4066,10 +4066,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 --@@ -1534,6 +1534,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, --@@ -1541,7 +1542,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/wpa_supplicant/events.c --+++ b/wpa_supplicant/events.c --@@ -2683,8 +2683,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) -- { --@@ -2717,8 +2715,6 @@ static void interworking_process_assoc_r -- } -- } -- ---#endif /* CONFIG_INTERWORKING */ --- -- -- static void wpa_supplicant_set_4addr_mode(struct wpa_supplicant *wpa_s) -- { --@@ -3098,10 +3094,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)) ----- a/src/ap/ieee802_11_shared.c --+++ b/src/ap/ieee802_11_shared.c --@@ -1116,13 +1116,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)); -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 -deleted file mode 100644 -index f5ebab70d1..0000000000 ---- a/package/network/services/hostapd/patches/751-qos_map_ignore_when_unsupported.patch -+++ /dev/null -@@ -1,12 +0,0 @@ ----- 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 -- int hostapd_drv_set_qos_map(struct hostapd_data *hapd, -- const u8 *qos_map_set, u8 qos_map_set_len) -- { --- if (!hapd->driver || !hapd->driver->set_qos_map || !hapd->drv_priv) --+ if (!hapd->driver || !hapd->driver->set_qos_map || !hapd->drv_priv || --+ !(hapd->iface->drv_flags & WPA_DRIVER_FLAGS_QOS_MAPPING)) -- return 0; -- return hapd->driver->set_qos_map(hapd->drv_priv, qos_map_set, -- 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 -deleted file mode 100644 -index 946b4533bf..0000000000 ---- a/package/network/services/hostapd/patches/760-dynamic_own_ip.patch -+++ /dev/null -@@ -1,109 +0,0 @@ ----- a/src/ap/ap_config.h --+++ b/src/ap/ap_config.h --@@ -310,6 +310,7 @@ struct hostapd_bss_config { -- unsigned int eap_sim_db_timeout; -- int eap_server_erp; /* Whether ERP is enabled on internal EAP server */ -- struct hostapd_ip_addr own_ip_addr; --+ int dynamic_own_ip_addr; -- char *nas_identifier; -- struct hostapd_radius_servers *radius; -- int acct_interim_interval; ----- a/src/radius/radius_client.c --+++ b/src/radius/radius_client.c --@@ -163,6 +163,8 @@ struct radius_client_data { -- */ -- void *ctx; -- --+ struct hostapd_ip_addr local_ip; --+ -- /** -- * conf - RADIUS client configuration (list of RADIUS servers to use) -- */ --@@ -720,6 +722,30 @@ static void radius_client_list_add(struc -- -- -- /** --+ * radius_client_send - Get local address for the RADIUS auth socket --+ * @radius: RADIUS client context from radius_client_init() --+ * @addr: pointer to store the address --+ * --+ * This function returns the local address for the connection to the RADIUS --+ * auth server. It also opens the socket if it's not available yet. --+ */ --+int radius_client_get_local_addr(struct radius_client_data *radius, --+ struct hostapd_ip_addr *addr) --+{ --+ struct hostapd_radius_servers *conf = radius->conf; --+ --+ if (conf->auth_server && radius->auth_sock < 0) --+ radius_client_init_auth(radius); --+ --+ if (radius->auth_sock < 0) --+ return -1; --+ --+ memcpy(addr, &radius->local_ip, sizeof(*addr)); --+ --+ return 0; --+} --+ --+/** -- * 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 -- wpa_printf(MSG_DEBUG, "RADIUS local address: %s:%u", -- inet_ntoa(claddr.sin_addr), -- ntohs(claddr.sin_port)); --+ if (auth) { --+ radius->local_ip.af = AF_INET; --+ radius->local_ip.u.v4 = claddr.sin_addr; --+ } -- } -- break; -- #ifdef CONFIG_IPV6 --@@ -1249,6 +1279,10 @@ radius_change_server(struct radius_clien -- inet_ntop(AF_INET6, &claddr6.sin6_addr, -- abuf, sizeof(abuf)), -- ntohs(claddr6.sin6_port)); --+ if (auth) { --+ radius->local_ip.af = AF_INET6; --+ radius->local_ip.u.v6 = claddr6.sin6_addr; --+ } -- } -- break; -- } ----- a/src/radius/radius_client.h --+++ b/src/radius/radius_client.h --@@ -249,6 +249,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); --+int radius_client_get_local_addr(struct radius_client_data *radius, --+ struct hostapd_ip_addr * addr); -- 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 -deleted file mode 100644 -index dad7afddf1..0000000000 ---- a/package/network/services/hostapd/patches/761-shared_das_port.patch -+++ /dev/null -@@ -1,298 +0,0 @@ ----- 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; ----- a/src/ap/hostapd.c --+++ b/src/ap/hostapd.c --@@ -1471,6 +1471,7 @@ static int hostapd_setup_bss(struct host -- -- os_memset(&das_conf, 0, sizeof(das_conf)); -- das_conf.port = conf->radius_das_port; --+ das_conf.nas_identifier = conf->nas_identifier; -- das_conf.shared_secret = conf->radius_das_shared_secret; -- das_conf.shared_secret_len = -- conf->radius_das_shared_secret_len; ----- a/src/radius/radius_das.c --+++ b/src/radius/radius_das.c --@@ -12,13 +12,26 @@ -- #include "utils/common.h" -- #include "utils/eloop.h" -- #include "utils/ip_addr.h" --+#include "utils/list.h" -- #include "radius.h" -- #include "radius_das.h" -- -- ---struct radius_das_data { --+static struct dl_list das_ports = DL_LIST_HEAD_INIT(das_ports); --+ --+struct radius_das_port { --+ struct dl_list list; --+ struct dl_list das_data; --+ --+ int port; -- int sock; --+}; --+ --+struct radius_das_data { --+ struct dl_list list; --+ struct radius_das_port *port; -- u8 *shared_secret; --+ u8 *nas_identifier; -- size_t shared_secret_len; -- struct hostapd_ip_addr client_addr; -- unsigned int time_window; --@@ -378,56 +391,17 @@ fail: -- } -- -- ---static void radius_das_receive(int sock, void *eloop_ctx, void *sock_ctx) --+static void --+radius_das_receive_msg(struct radius_das_data *das, struct radius_msg *msg, --+ struct sockaddr *from, socklen_t fromlen, --+ char *abuf, int from_port) -- { --- struct radius_das_data *das = eloop_ctx; --- u8 buf[1500]; --- union { --- struct sockaddr_storage ss; --- struct sockaddr_in sin; ---#ifdef CONFIG_IPV6 --- struct sockaddr_in6 sin6; ---#endif /* CONFIG_IPV6 */ --- } from; --- char abuf[50]; --- int from_port = 0; --- socklen_t fromlen; --- int len; --- struct radius_msg *msg, *reply = NULL; --+ struct radius_msg *reply = NULL; -- struct radius_hdr *hdr; -- struct wpabuf *rbuf; --+ struct os_time now; -- u32 val; -- int res; --- struct os_time now; --- --- fromlen = sizeof(from); --- len = recvfrom(sock, buf, sizeof(buf), 0, --- (struct sockaddr *) &from.ss, &fromlen); --- if (len < 0) { --- wpa_printf(MSG_ERROR, "DAS: recvfrom: %s", strerror(errno)); --- return; --- } --- --- os_strlcpy(abuf, inet_ntoa(from.sin.sin_addr), sizeof(abuf)); --- from_port = ntohs(from.sin.sin_port); --- --- wpa_printf(MSG_DEBUG, "DAS: Received %d bytes from %s:%d", --- len, abuf, from_port); --- if (das->client_addr.u.v4.s_addr && --- das->client_addr.u.v4.s_addr != from.sin.sin_addr.s_addr) { --- wpa_printf(MSG_DEBUG, "DAS: Drop message from unknown client"); --- return; --- } --- --- msg = radius_msg_parse(buf, len); --- if (msg == NULL) { --- wpa_printf(MSG_DEBUG, "DAS: Parsing incoming RADIUS packet " --- "from %s:%d failed", abuf, from_port); --- return; --- } --- --- if (wpa_debug_level <= MSG_MSGDUMP) --- radius_msg_dump(msg); -- -- if (radius_msg_verify_das_req(msg, das->shared_secret, -- das->shared_secret_len, --@@ -494,9 +468,8 @@ static void radius_das_receive(int sock, -- radius_msg_dump(reply); -- -- rbuf = radius_msg_get_buf(reply); --- res = sendto(das->sock, wpabuf_head(rbuf), --- wpabuf_len(rbuf), 0, --- (struct sockaddr *) &from.ss, fromlen); --+ res = sendto(das->port->sock, wpabuf_head(rbuf), --+ wpabuf_len(rbuf), 0, from, fromlen); -- if (res < 0) { -- wpa_printf(MSG_ERROR, "DAS: sendto(to %s:%d): %s", -- abuf, from_port, strerror(errno)); --@@ -508,6 +481,72 @@ fail: -- radius_msg_free(reply); -- } -- --+static void radius_das_receive(int sock, void *eloop_ctx, void *sock_ctx) --+{ --+ struct radius_das_port *p = eloop_ctx; --+ struct radius_das_data *das; --+ u8 buf[1500]; --+ union { --+ struct sockaddr_storage ss; --+ struct sockaddr_in sin; --+#ifdef CONFIG_IPV6 --+ struct sockaddr_in6 sin6; --+#endif /* CONFIG_IPV6 */ --+ } from; --+ struct radius_msg *msg; --+ size_t nasid_len = 0; --+ u8 *nasid_buf = NULL; --+ char abuf[50]; --+ int from_port = 0; --+ socklen_t fromlen; --+ int found = 0; --+ int len; --+ --+ fromlen = sizeof(from); --+ len = recvfrom(sock, buf, sizeof(buf), 0, --+ (struct sockaddr *) &from.ss, &fromlen); --+ if (len < 0) { --+ wpa_printf(MSG_ERROR, "DAS: recvfrom: %s", strerror(errno)); --+ return; --+ } --+ --+ os_strlcpy(abuf, inet_ntoa(from.sin.sin_addr), sizeof(abuf)); --+ from_port = ntohs(from.sin.sin_port); --+ --+ msg = radius_msg_parse(buf, len); --+ if (msg == NULL) { --+ wpa_printf(MSG_DEBUG, "DAS: Parsing incoming RADIUS packet " --+ "from %s:%d failed", abuf, from_port); --+ return; --+ } --+ --+ wpa_printf(MSG_DEBUG, "DAS: Received %d bytes from %s:%d", --+ len, abuf, from_port); --+ --+ if (wpa_debug_level <= MSG_MSGDUMP) --+ radius_msg_dump(msg); --+ --+ radius_msg_get_attr_ptr(msg, RADIUS_ATTR_NAS_IDENTIFIER, --+ &nasid_buf, &nasid_len, NULL); --+ dl_list_for_each(das, &p->das_data, struct radius_das_data, list) { --+ if (das->client_addr.u.v4.s_addr && --+ das->client_addr.u.v4.s_addr != from.sin.sin_addr.s_addr) --+ continue; --+ --+ if (das->nas_identifier && nasid_buf && --+ (nasid_len != os_strlen(das->nas_identifier) || --+ os_memcmp(das->nas_identifier, nasid_buf, nasid_len) != 0)) --+ continue; --+ --+ found = 1; --+ radius_das_receive_msg(das, msg, (struct sockaddr *)&from.ss, --+ fromlen, abuf, from_port); --+ } --+ --+ if (!found) --+ wpa_printf(MSG_DEBUG, "DAS: Drop message from unknown client"); --+} --+ -- -- static int radius_das_open_socket(int port) -- { --@@ -533,6 +572,49 @@ static int radius_das_open_socket(int po -- } -- -- --+static struct radius_das_port * --+radius_das_open_port(int port) --+{ --+ struct radius_das_port *p; --+ --+ dl_list_for_each(p, &das_ports, struct radius_das_port, list) { --+ if (p->port == port) --+ return p; --+ } --+ --+ p = os_zalloc(sizeof(*p)); --+ if (p == NULL) --+ return NULL; --+ --+ dl_list_init(&p->das_data); --+ p->port = port; --+ p->sock = radius_das_open_socket(port); --+ if (p->sock < 0) --+ goto free_port; --+ --+ if (eloop_register_read_sock(p->sock, radius_das_receive, p, NULL)) --+ goto close_port; --+ --+ dl_list_add(&das_ports, &p->list); --+ --+ return p; --+ --+close_port: --+ close(p->sock); --+free_port: --+ os_free(p); --+ --+ return NULL; --+} --+ --+static void radius_das_close_port(struct radius_das_port *p) --+{ --+ dl_list_del(&p->list); --+ eloop_unregister_read_sock(p->sock); --+ close(p->sock); --+ free(p); --+} --+ -- struct radius_das_data * -- radius_das_init(struct radius_das_conf *conf) -- { --@@ -553,6 +635,8 @@ radius_das_init(struct radius_das_conf * -- das->ctx = conf->ctx; -- das->disconnect = conf->disconnect; -- das->coa = conf->coa; --+ if (conf->nas_identifier) --+ das->nas_identifier = os_strdup(conf->nas_identifier); -- -- os_memcpy(&das->client_addr, conf->client_addr, -- sizeof(das->client_addr)); --@@ -565,19 +649,15 @@ radius_das_init(struct radius_das_conf * -- } -- das->shared_secret_len = conf->shared_secret_len; -- --- das->sock = radius_das_open_socket(conf->port); --- if (das->sock < 0) { --+ das->port = radius_das_open_port(conf->port); --+ if (!das->port) { -- wpa_printf(MSG_ERROR, "Failed to open UDP socket for RADIUS " -- "DAS"); -- radius_das_deinit(das); -- return NULL; -- } -- --- if (eloop_register_read_sock(das->sock, radius_das_receive, das, NULL)) --- { --- radius_das_deinit(das); --- return NULL; --- } --+ dl_list_add(&das->port->das_data, &das->list); -- -- return das; -- } --@@ -588,11 +668,14 @@ void radius_das_deinit(struct radius_das -- if (das == NULL) -- return; -- --- if (das->sock >= 0) { --- eloop_unregister_read_sock(das->sock); --- close(das->sock); --+ if (das->port) { --+ dl_list_del(&das->list); --+ --+ if (dl_list_empty(&das->port->das_data)) --+ radius_das_close_port(das->port); -- } -- --+ os_free(das->nas_identifier); -- os_free(das->shared_secret); -- os_free(das); -- } -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 -deleted file mode 100644 -index 51690def09..0000000000 ---- a/package/network/services/hostapd/patches/990-ctrl-make-WNM_AP-functions-dependant-on-CONFIG_AP.patch -+++ /dev/null -@@ -1,33 +0,0 @@ --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 --@@ -12640,7 +12640,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; --@@ -12650,7 +12650,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/991-Fix-OpenWrt-13156.patch b/package/network/services/hostapd/patches/991-Fix-OpenWrt-13156.patch -deleted file mode 100644 -index 99d800858f..0000000000 ---- a/package/network/services/hostapd/patches/991-Fix-OpenWrt-13156.patch -+++ /dev/null -@@ -1,63 +0,0 @@ --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 --@@ -3615,6 +3615,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); --@@ -3622,10 +3624,16 @@ void hostapd_new_assoc_sta(struct hostap -- } -- -- #ifdef CONFIG_IEEE80211BE --- if (hapd->conf->mld_ap && sta->mld_info.mld_sta && --- sta->mld_assoc_link_id != hapd->mld_link_id) --- return; --+ if (hapd->conf->mld_ap && sta->mld_info.mld_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 --@@ -1318,9 +1318,6 @@ void ap_sta_set_authorized(struct hostap -- 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/src/src/ap/ubus.c b/package/network/services/hostapd/src/src/ap/ubus.c -deleted file mode 100644 -index ddd86447eb..0000000000 ---- a/package/network/services/hostapd/src/src/ap/ubus.c -+++ /dev/null -@@ -1,2101 +0,0 @@ --/* -- * hostapd / ubus support -- * Copyright (c) 2013, Felix Fietkau -- * -- * This software may be distributed under the terms of the BSD license. -- * See README for more details. -- */ -- --#include "utils/includes.h" --#include "utils/common.h" --#include "utils/eloop.h" --#include "utils/wpabuf.h" --#include "common/ieee802_11_defs.h" --#include "common/hw_features_common.h" --#include "hostapd.h" --#include "neighbor_db.h" --#include "wps_hostapd.h" --#include "sta_info.h" --#include "ubus.h" --#include "ap_drv_ops.h" --#include "beacon.h" --#include "rrm.h" --#include "wnm_ap.h" --#include "taxonomy.h" --#include "airtime_policy.h" --#include "hw_features.h" -- --static struct ubus_context *ctx; --static struct blob_buf b; --static int ctx_ref; -- --static inline struct hapd_interfaces *get_hapd_interfaces_from_object(struct ubus_object *obj) --{ -- return container_of(obj, struct hapd_interfaces, ubus); --} -- --static inline struct hostapd_data *get_hapd_from_object(struct ubus_object *obj) --{ -- return container_of(obj, struct hostapd_data, ubus.obj); --} -- --struct ubus_banned_client { -- struct avl_node avl; -- u8 addr[ETH_ALEN]; --}; -- --static void ubus_receive(int sock, void *eloop_ctx, void *sock_ctx) --{ -- struct ubus_context *ctx = eloop_ctx; -- ubus_handle_event(ctx); --} -- --static void ubus_reconnect_timeout(void *eloop_data, void *user_ctx) --{ -- if (ubus_reconnect(ctx, NULL)) { -- eloop_register_timeout(1, 0, ubus_reconnect_timeout, ctx, NULL); -- return; -- } -- -- eloop_register_read_sock(ctx->sock.fd, ubus_receive, ctx, NULL); --} -- --static void hostapd_ubus_connection_lost(struct ubus_context *ctx) --{ -- eloop_unregister_read_sock(ctx->sock.fd); -- eloop_register_timeout(1, 0, ubus_reconnect_timeout, ctx, NULL); --} -- --static bool hostapd_ubus_init(void) --{ -- if (ctx) -- return true; -- -- ctx = ubus_connect(NULL); -- if (!ctx) -- return false; -- -- ctx->connection_lost = hostapd_ubus_connection_lost; -- eloop_register_read_sock(ctx->sock.fd, ubus_receive, ctx, NULL); -- return true; --} -- --static void hostapd_ubus_ref_inc(void) --{ -- ctx_ref++; --} -- --static void hostapd_ubus_ref_dec(void) --{ -- ctx_ref--; -- if (!ctx) -- return; -- -- if (ctx_ref) -- return; -- -- eloop_unregister_read_sock(ctx->sock.fd); -- ubus_free(ctx); -- ctx = NULL; --} -- --void hostapd_ubus_add_iface(struct hostapd_iface *iface) --{ -- if (!hostapd_ubus_init()) -- return; --} -- --void hostapd_ubus_free_iface(struct hostapd_iface *iface) --{ -- if (!ctx) -- return; --} -- --static void hostapd_notify_ubus(struct ubus_object *obj, char *bssname, char *event) --{ -- char *event_type; -- -- if (!ctx || !obj) -- return; -- -- if (asprintf(&event_type, "bss.%s", event) < 0) -- return; -- -- blob_buf_init(&b, 0); -- blobmsg_add_string(&b, "name", bssname); -- ubus_notify(ctx, obj, event_type, b.head, -1); -- free(event_type); --} -- --static void hostapd_send_procd_event(char *bssname, char *event) --{ -- char *name, *s; -- uint32_t id; -- void *v; -- -- if (!ctx || ubus_lookup_id(ctx, "service", &id)) -- return; -- -- if (asprintf(&name, "hostapd.%s.%s", bssname, event) < 0) -- return; -- -- blob_buf_init(&b, 0); -- -- s = blobmsg_alloc_string_buffer(&b, "type", strlen(name) + 1); -- sprintf(s, "%s", name); -- blobmsg_add_string_buffer(&b); -- -- v = blobmsg_open_table(&b, "data"); -- blobmsg_close_table(&b, v); -- -- ubus_invoke(ctx, id, "event", b.head, NULL, NULL, 1000); -- -- free(name); --} -- --static void hostapd_send_shared_event(struct ubus_object *obj, char *bssname, char *event) --{ -- hostapd_send_procd_event(bssname, event); -- hostapd_notify_ubus(obj, bssname, event); --} -- --static void --hostapd_bss_del_ban(void *eloop_data, void *user_ctx) --{ -- struct ubus_banned_client *ban = eloop_data; -- struct hostapd_data *hapd = user_ctx; -- -- avl_delete(&hapd->ubus.banned, &ban->avl); -- free(ban); --} -- --static void --hostapd_bss_ban_client(struct hostapd_data *hapd, u8 *addr, int time) --{ -- struct ubus_banned_client *ban; -- -- if (time < 0) -- time = 0; -- -- ban = avl_find_element(&hapd->ubus.banned, addr, ban, avl); -- if (!ban) { -- if (!time) -- return; -- -- ban = os_zalloc(sizeof(*ban)); -- memcpy(ban->addr, addr, sizeof(ban->addr)); -- ban->avl.key = ban->addr; -- avl_insert(&hapd->ubus.banned, &ban->avl); -- } else { -- eloop_cancel_timeout(hostapd_bss_del_ban, ban, hapd); -- if (!time) { -- hostapd_bss_del_ban(ban, hapd); -- return; -- } -- } -- -- eloop_register_timeout(0, time * 1000, hostapd_bss_del_ban, ban, hapd); --} -- --static int --hostapd_bss_reload(struct ubus_context *ctx, struct ubus_object *obj, -- struct ubus_request_data *req, const char *method, -- struct blob_attr *msg) --{ -- struct hostapd_data *hapd = container_of(obj, struct hostapd_data, ubus.obj); -- int ret = hostapd_reload_config(hapd->iface, 1); -- -- hostapd_send_shared_event(&hapd->iface->interfaces->ubus, hapd->conf->iface, "reload"); -- return ret; --} -- -- --static void --hostapd_parse_vht_map_blobmsg(uint16_t map) --{ -- char label[4]; -- int16_t val; -- int i; -- -- for (i = 0; i < 8; i++) { -- snprintf(label, 4, "%dss", i + 1); -- -- val = (map & (BIT(1) | BIT(0))) + 7; -- blobmsg_add_u16(&b, label, val == 10 ? -1 : val); -- map = map >> 2; -- } --} -- --static void --hostapd_parse_vht_capab_blobmsg(struct ieee80211_vht_capabilities *vhtc) --{ -- void *supported_mcs; -- void *map; -- int i; -- -- static const struct { -- const char *name; -- uint32_t flag; -- } vht_capas[] = { -- { "su_beamformee", VHT_CAP_SU_BEAMFORMEE_CAPABLE }, -- { "mu_beamformee", VHT_CAP_MU_BEAMFORMEE_CAPABLE }, -- }; -- -- for (i = 0; i < ARRAY_SIZE(vht_capas); i++) -- blobmsg_add_u8(&b, vht_capas[i].name, -- !!(vhtc->vht_capabilities_info & vht_capas[i].flag)); -- -- supported_mcs = blobmsg_open_table(&b, "mcs_map"); -- -- /* RX map */ -- map = blobmsg_open_table(&b, "rx"); -- hostapd_parse_vht_map_blobmsg(le_to_host16(vhtc->vht_supported_mcs_set.rx_map)); -- blobmsg_close_table(&b, map); -- -- /* TX map */ -- map = blobmsg_open_table(&b, "tx"); -- hostapd_parse_vht_map_blobmsg(le_to_host16(vhtc->vht_supported_mcs_set.tx_map)); -- blobmsg_close_table(&b, map); -- -- blobmsg_close_table(&b, supported_mcs); --} -- --static void --hostapd_parse_capab_blobmsg(struct sta_info *sta) --{ -- void *r, *v; -- -- v = blobmsg_open_table(&b, "capabilities"); -- -- if (sta->vht_capabilities) { -- r = blobmsg_open_table(&b, "vht"); -- hostapd_parse_vht_capab_blobmsg(sta->vht_capabilities); -- blobmsg_close_table(&b, r); -- } -- -- /* ToDo: Add HT / HE capability parsing */ -- -- blobmsg_close_table(&b, v); --} -- --static int --hostapd_bss_get_clients(struct ubus_context *ctx, struct ubus_object *obj, -- struct ubus_request_data *req, const char *method, -- struct blob_attr *msg) --{ -- struct hostapd_data *hapd = container_of(obj, struct hostapd_data, ubus.obj); -- struct hostap_sta_driver_data sta_driver_data; -- struct sta_info *sta; -- void *list, *c; -- char mac_buf[20]; -- static const struct { -- const char *name; -- uint32_t flag; -- } sta_flags[] = { -- { "auth", WLAN_STA_AUTH }, -- { "assoc", WLAN_STA_ASSOC }, -- { "authorized", WLAN_STA_AUTHORIZED }, -- { "preauth", WLAN_STA_PREAUTH }, -- { "wds", WLAN_STA_WDS }, -- { "wmm", WLAN_STA_WMM }, -- { "ht", WLAN_STA_HT }, -- { "vht", WLAN_STA_VHT }, -- { "he", WLAN_STA_HE }, -- { "wps", WLAN_STA_WPS }, -- { "mfp", WLAN_STA_MFP }, -- }; -- -- blob_buf_init(&b, 0); -- blobmsg_add_u32(&b, "freq", hapd->iface->freq); -- list = blobmsg_open_table(&b, "clients"); -- for (sta = hapd->sta_list; sta; sta = sta->next) { -- void *r; -- int i; -- -- sprintf(mac_buf, MACSTR, MAC2STR(sta->addr)); -- c = blobmsg_open_table(&b, mac_buf); -- for (i = 0; i < ARRAY_SIZE(sta_flags); i++) -- blobmsg_add_u8(&b, sta_flags[i].name, -- !!(sta->flags & sta_flags[i].flag)); -- --#ifdef CONFIG_MBO -- blobmsg_add_u8(&b, "mbo", !!(sta->cell_capa)); --#endif -- -- r = blobmsg_open_array(&b, "rrm"); -- for (i = 0; i < ARRAY_SIZE(sta->rrm_enabled_capa); i++) -- blobmsg_add_u32(&b, "", sta->rrm_enabled_capa[i]); -- blobmsg_close_array(&b, r); -- -- r = blobmsg_open_array(&b, "extended_capabilities"); -- /* Check if client advertises extended capabilities */ -- if (sta->ext_capability && sta->ext_capability[0] > 0) { -- for (i = 0; i < sta->ext_capability[0]; i++) { -- blobmsg_add_u32(&b, "", sta->ext_capability[1 + i]); -- } -- } -- blobmsg_close_array(&b, r); -- -- blobmsg_add_u32(&b, "aid", sta->aid); --#ifdef CONFIG_TAXONOMY -- r = blobmsg_alloc_string_buffer(&b, "signature", 1024); -- if (retrieve_sta_taxonomy(hapd, sta, r, 1024) > 0) -- blobmsg_add_string_buffer(&b); --#endif -- -- /* Driver information */ -- if (hostapd_drv_read_sta_data(hapd, &sta_driver_data, sta->addr) >= 0) { -- r = blobmsg_open_table(&b, "bytes"); -- blobmsg_add_u64(&b, "rx", sta_driver_data.rx_bytes); -- blobmsg_add_u64(&b, "tx", sta_driver_data.tx_bytes); -- blobmsg_close_table(&b, r); -- r = blobmsg_open_table(&b, "airtime"); -- blobmsg_add_u64(&b, "rx", sta_driver_data.rx_airtime); -- blobmsg_add_u64(&b, "tx", sta_driver_data.tx_airtime); -- blobmsg_close_table(&b, r); -- r = blobmsg_open_table(&b, "packets"); -- blobmsg_add_u32(&b, "rx", sta_driver_data.rx_packets); -- blobmsg_add_u32(&b, "tx", sta_driver_data.tx_packets); -- blobmsg_close_table(&b, r); -- r = blobmsg_open_table(&b, "rate"); -- /* Rate in kbits */ -- blobmsg_add_u32(&b, "rx", sta_driver_data.current_rx_rate * 100); -- blobmsg_add_u32(&b, "tx", sta_driver_data.current_tx_rate * 100); -- blobmsg_close_table(&b, r); -- blobmsg_add_u32(&b, "signal", sta_driver_data.signal); -- } -- -- hostapd_parse_capab_blobmsg(sta); -- -- blobmsg_close_table(&b, c); -- } -- blobmsg_close_array(&b, list); -- ubus_send_reply(ctx, req, b.head); -- -- return 0; --} -- --static int --hostapd_bss_get_features(struct ubus_context *ctx, struct ubus_object *obj, -- struct ubus_request_data *req, const char *method, -- struct blob_attr *msg) --{ -- struct hostapd_data *hapd = container_of(obj, struct hostapd_data, ubus.obj); -- -- blob_buf_init(&b, 0); -- blobmsg_add_u8(&b, "ht_supported", ht_supported(hapd->iface->hw_features)); -- blobmsg_add_u8(&b, "vht_supported", vht_supported(hapd->iface->hw_features)); -- ubus_send_reply(ctx, req, b.head); -- -- return 0; --} -- --static int --hostapd_bss_get_status(struct ubus_context *ctx, struct ubus_object *obj, -- struct ubus_request_data *req, const char *method, -- struct blob_attr *msg) --{ -- struct hostapd_data *hapd = container_of(obj, struct hostapd_data, ubus.obj); -- void *airtime_table, *dfs_table, *rrm_table, *wnm_table; -- struct os_reltime now; -- char ssid[SSID_MAX_LEN + 1]; -- char phy_name[17]; -- size_t ssid_len = SSID_MAX_LEN; -- u8 channel = 0, op_class = 0; -- -- if (hapd->conf->ssid.ssid_len < SSID_MAX_LEN) -- ssid_len = hapd->conf->ssid.ssid_len; -- -- ieee80211_freq_to_channel_ext(hapd->iface->freq, -- hapd->iconf->secondary_channel, -- hostapd_get_oper_chwidth(hapd->iconf), -- &op_class, &channel); -- -- blob_buf_init(&b, 0); -- blobmsg_add_string(&b, "status", hostapd_state_text(hapd->iface->state)); -- blobmsg_printf(&b, "bssid", MACSTR, MAC2STR(hapd->conf->bssid)); -- -- memset(ssid, 0, SSID_MAX_LEN + 1); -- memcpy(ssid, hapd->conf->ssid.ssid, ssid_len); -- blobmsg_add_string(&b, "ssid", ssid); -- -- blobmsg_add_u32(&b, "freq", hapd->iface->freq); -- blobmsg_add_u32(&b, "channel", channel); -- blobmsg_add_u32(&b, "op_class", op_class); -- blobmsg_add_u32(&b, "beacon_interval", hapd->iconf->beacon_int); --#ifdef CONFIG_IEEE80211AX -- blobmsg_add_u32(&b, "bss_color", hapd->iface->conf->he_op.he_bss_color_disabled ? -1 : -- hapd->iface->conf->he_op.he_bss_color); --#else -- blobmsg_add_u32(&b, "bss_color", -1); --#endif -- -- snprintf(phy_name, 17, "%s", hapd->iface->phy); -- blobmsg_add_string(&b, "phy", phy_name); -- -- /* RRM */ -- rrm_table = blobmsg_open_table(&b, "rrm"); -- blobmsg_add_u64(&b, "neighbor_report_tx", hapd->openwrt_stats.rrm.neighbor_report_tx); -- blobmsg_close_table(&b, rrm_table); -- -- /* WNM */ -- wnm_table = blobmsg_open_table(&b, "wnm"); -- blobmsg_add_u64(&b, "bss_transition_query_rx", hapd->openwrt_stats.wnm.bss_transition_query_rx); -- blobmsg_add_u64(&b, "bss_transition_request_tx", hapd->openwrt_stats.wnm.bss_transition_request_tx); -- blobmsg_add_u64(&b, "bss_transition_response_rx", hapd->openwrt_stats.wnm.bss_transition_response_rx); -- blobmsg_close_table(&b, wnm_table); -- -- /* Airtime */ -- airtime_table = blobmsg_open_table(&b, "airtime"); -- blobmsg_add_u64(&b, "time", hapd->iface->last_channel_time); -- blobmsg_add_u64(&b, "time_busy", hapd->iface->last_channel_time_busy); -- blobmsg_add_u16(&b, "utilization", hapd->iface->channel_utilization); -- blobmsg_close_table(&b, airtime_table); -- -- /* DFS */ -- dfs_table = blobmsg_open_table(&b, "dfs"); -- blobmsg_add_u32(&b, "cac_seconds", hapd->iface->dfs_cac_ms / 1000); -- blobmsg_add_u8(&b, "cac_active", !!(hapd->iface->cac_started)); -- os_reltime_age(&hapd->iface->dfs_cac_start, &now); -- blobmsg_add_u32(&b, "cac_seconds_left", -- hapd->iface->cac_started ? hapd->iface->dfs_cac_ms / 1000 - now.sec : 0); -- blobmsg_close_table(&b, dfs_table); -- -- ubus_send_reply(ctx, req, b.head); -- -- return 0; --} -- --enum { -- NOTIFY_RESPONSE, -- __NOTIFY_MAX --}; -- --static const struct blobmsg_policy notify_policy[__NOTIFY_MAX] = { -- [NOTIFY_RESPONSE] = { "notify_response", BLOBMSG_TYPE_INT32 }, --}; -- --static int --hostapd_notify_response(struct ubus_context *ctx, struct ubus_object *obj, -- struct ubus_request_data *req, const char *method, -- struct blob_attr *msg) --{ -- struct blob_attr *tb[__NOTIFY_MAX]; -- struct hostapd_data *hapd = get_hapd_from_object(obj); -- struct wpabuf *elems; -- const char *pos; -- size_t len; -- -- blobmsg_parse(notify_policy, __NOTIFY_MAX, tb, -- blob_data(msg), blob_len(msg)); -- -- if (!tb[NOTIFY_RESPONSE]) -- return UBUS_STATUS_INVALID_ARGUMENT; -- -- hapd->ubus.notify_response = blobmsg_get_u32(tb[NOTIFY_RESPONSE]); -- -- return UBUS_STATUS_OK; --} -- --enum { -- DEL_CLIENT_ADDR, -- DEL_CLIENT_REASON, -- DEL_CLIENT_DEAUTH, -- DEL_CLIENT_BAN_TIME, -- __DEL_CLIENT_MAX --}; -- --static const struct blobmsg_policy del_policy[__DEL_CLIENT_MAX] = { -- [DEL_CLIENT_ADDR] = { "addr", BLOBMSG_TYPE_STRING }, -- [DEL_CLIENT_REASON] = { "reason", BLOBMSG_TYPE_INT32 }, -- [DEL_CLIENT_DEAUTH] = { "deauth", BLOBMSG_TYPE_INT8 }, -- [DEL_CLIENT_BAN_TIME] = { "ban_time", BLOBMSG_TYPE_INT32 }, --}; -- --static int --hostapd_bss_del_client(struct ubus_context *ctx, struct ubus_object *obj, -- struct ubus_request_data *req, const char *method, -- struct blob_attr *msg) --{ -- struct blob_attr *tb[__DEL_CLIENT_MAX]; -- struct hostapd_data *hapd = container_of(obj, struct hostapd_data, ubus.obj); -- struct sta_info *sta; -- bool deauth = false; -- int reason; -- u8 addr[ETH_ALEN]; -- -- blobmsg_parse(del_policy, __DEL_CLIENT_MAX, tb, blob_data(msg), blob_len(msg)); -- -- if (!tb[DEL_CLIENT_ADDR]) -- return UBUS_STATUS_INVALID_ARGUMENT; -- -- if (hwaddr_aton(blobmsg_data(tb[DEL_CLIENT_ADDR]), addr)) -- return UBUS_STATUS_INVALID_ARGUMENT; -- -- if (tb[DEL_CLIENT_REASON]) -- reason = blobmsg_get_u32(tb[DEL_CLIENT_REASON]); -- -- if (tb[DEL_CLIENT_DEAUTH]) -- deauth = blobmsg_get_bool(tb[DEL_CLIENT_DEAUTH]); -- -- sta = ap_get_sta(hapd, addr); -- if (sta) { -- if (deauth) { -- hostapd_drv_sta_deauth(hapd, addr, reason); -- ap_sta_deauthenticate(hapd, sta, reason); -- } else { -- hostapd_drv_sta_disassoc(hapd, addr, reason); -- ap_sta_disassociate(hapd, sta, reason); -- } -- } -- -- if (tb[DEL_CLIENT_BAN_TIME]) -- hostapd_bss_ban_client(hapd, addr, blobmsg_get_u32(tb[DEL_CLIENT_BAN_TIME])); -- -- return 0; --} -- --static void --blobmsg_add_macaddr(struct blob_buf *buf, const char *name, const u8 *addr) --{ -- char *s; -- -- s = blobmsg_alloc_string_buffer(buf, name, 20); -- sprintf(s, MACSTR, MAC2STR(addr)); -- blobmsg_add_string_buffer(buf); --} -- --static int --hostapd_bss_list_bans(struct ubus_context *ctx, struct ubus_object *obj, -- struct ubus_request_data *req, const char *method, -- struct blob_attr *msg) --{ -- struct hostapd_data *hapd = container_of(obj, struct hostapd_data, ubus.obj); -- struct ubus_banned_client *ban; -- void *c; -- -- blob_buf_init(&b, 0); -- c = blobmsg_open_array(&b, "clients"); -- avl_for_each_element(&hapd->ubus.banned, ban, avl) -- blobmsg_add_macaddr(&b, NULL, ban->addr); -- blobmsg_close_array(&b, c); -- ubus_send_reply(ctx, req, b.head); -- -- return 0; --} -- --#ifdef CONFIG_WPS --static int --hostapd_bss_wps_start(struct ubus_context *ctx, struct ubus_object *obj, -- struct ubus_request_data *req, const char *method, -- struct blob_attr *msg) --{ -- int rc; -- struct hostapd_data *hapd = container_of(obj, struct hostapd_data, ubus.obj); -- -- rc = hostapd_wps_button_pushed(hapd, NULL); -- -- if (rc != 0) -- return UBUS_STATUS_NOT_SUPPORTED; -- -- return 0; --} -- -- --static const char * pbc_status_enum_str(enum pbc_status status) --{ -- switch (status) { -- case WPS_PBC_STATUS_DISABLE: -- return "Disabled"; -- case WPS_PBC_STATUS_ACTIVE: -- return "Active"; -- case WPS_PBC_STATUS_TIMEOUT: -- return "Timed-out"; -- case WPS_PBC_STATUS_OVERLAP: -- return "Overlap"; -- default: -- return "Unknown"; -- } --} -- --static int --hostapd_bss_wps_status(struct ubus_context *ctx, struct ubus_object *obj, -- struct ubus_request_data *req, const char *method, -- struct blob_attr *msg) --{ -- int rc; -- struct hostapd_data *hapd = container_of(obj, struct hostapd_data, ubus.obj); -- -- blob_buf_init(&b, 0); -- -- blobmsg_add_string(&b, "pbc_status", pbc_status_enum_str(hapd->wps_stats.pbc_status)); -- blobmsg_add_string(&b, "last_wps_result", -- (hapd->wps_stats.status == WPS_STATUS_SUCCESS ? -- "Success": -- (hapd->wps_stats.status == WPS_STATUS_FAILURE ? -- "Failed" : "None"))); -- -- /* If status == Failure - Add possible Reasons */ -- if(hapd->wps_stats.status == WPS_STATUS_FAILURE && -- hapd->wps_stats.failure_reason > 0) -- blobmsg_add_string(&b, "reason", wps_ei_str(hapd->wps_stats.failure_reason)); -- -- if (hapd->wps_stats.status) -- blobmsg_printf(&b, "peer_address", MACSTR, MAC2STR(hapd->wps_stats.peer_addr)); -- -- ubus_send_reply(ctx, req, b.head); -- -- return 0; --} -- --static int --hostapd_bss_wps_cancel(struct ubus_context *ctx, struct ubus_object *obj, -- struct ubus_request_data *req, const char *method, -- struct blob_attr *msg) --{ -- int rc; -- struct hostapd_data *hapd = container_of(obj, struct hostapd_data, ubus.obj); -- -- rc = hostapd_wps_cancel(hapd); -- -- if (rc != 0) -- return UBUS_STATUS_NOT_SUPPORTED; -- -- return 0; --} --#endif /* CONFIG_WPS */ -- --static int --hostapd_bss_update_beacon(struct ubus_context *ctx, struct ubus_object *obj, -- struct ubus_request_data *req, const char *method, -- struct blob_attr *msg) --{ -- int rc; -- struct hostapd_data *hapd = container_of(obj, struct hostapd_data, ubus.obj); -- -- rc = ieee802_11_set_beacon(hapd); -- -- if (rc != 0) -- return UBUS_STATUS_NOT_SUPPORTED; -- -- return 0; --} -- --enum { -- CONFIG_IFACE, -- CONFIG_FILE, -- __CONFIG_MAX --}; -- --static const struct blobmsg_policy config_add_policy[__CONFIG_MAX] = { -- [CONFIG_IFACE] = { "iface", BLOBMSG_TYPE_STRING }, -- [CONFIG_FILE] = { "config", BLOBMSG_TYPE_STRING }, --}; -- --static int --hostapd_config_add(struct ubus_context *ctx, struct ubus_object *obj, -- struct ubus_request_data *req, const char *method, -- struct blob_attr *msg) --{ -- struct blob_attr *tb[__CONFIG_MAX]; -- struct hapd_interfaces *interfaces = get_hapd_interfaces_from_object(obj); -- char buf[128]; -- -- blobmsg_parse(config_add_policy, __CONFIG_MAX, tb, blob_data(msg), blob_len(msg)); -- -- if (!tb[CONFIG_FILE] || !tb[CONFIG_IFACE]) -- return UBUS_STATUS_INVALID_ARGUMENT; -- -- snprintf(buf, sizeof(buf), "bss_config=%s:%s", -- blobmsg_get_string(tb[CONFIG_IFACE]), -- blobmsg_get_string(tb[CONFIG_FILE])); -- -- if (hostapd_add_iface(interfaces, buf)) -- return UBUS_STATUS_INVALID_ARGUMENT; -- -- blob_buf_init(&b, 0); -- blobmsg_add_u32(&b, "pid", getpid()); -- ubus_send_reply(ctx, req, b.head); -- -- return UBUS_STATUS_OK; --} -- --enum { -- CONFIG_REM_IFACE, -- __CONFIG_REM_MAX --}; -- --static const struct blobmsg_policy config_remove_policy[__CONFIG_REM_MAX] = { -- [CONFIG_REM_IFACE] = { "iface", BLOBMSG_TYPE_STRING }, --}; -- --static int --hostapd_config_remove(struct ubus_context *ctx, struct ubus_object *obj, -- struct ubus_request_data *req, const char *method, -- struct blob_attr *msg) --{ -- struct blob_attr *tb[__CONFIG_REM_MAX]; -- struct hapd_interfaces *interfaces = get_hapd_interfaces_from_object(obj); -- char buf[128]; -- -- blobmsg_parse(config_remove_policy, __CONFIG_REM_MAX, tb, blob_data(msg), blob_len(msg)); -- -- if (!tb[CONFIG_REM_IFACE]) -- return UBUS_STATUS_INVALID_ARGUMENT; -- -- if (hostapd_remove_iface(interfaces, blobmsg_get_string(tb[CONFIG_REM_IFACE]))) -- return UBUS_STATUS_INVALID_ARGUMENT; -- -- return UBUS_STATUS_OK; --} -- --enum { -- CSA_FREQ, -- CSA_BCN_COUNT, -- CSA_CENTER_FREQ1, -- CSA_CENTER_FREQ2, -- CSA_BANDWIDTH, -- CSA_SEC_CHANNEL_OFFSET, -- CSA_HT, -- CSA_VHT, -- CSA_HE, -- CSA_BLOCK_TX, -- CSA_FORCE, -- __CSA_MAX --}; -- --static const struct blobmsg_policy csa_policy[__CSA_MAX] = { -- [CSA_FREQ] = { "freq", BLOBMSG_TYPE_INT32 }, -- [CSA_BCN_COUNT] = { "bcn_count", BLOBMSG_TYPE_INT32 }, -- [CSA_CENTER_FREQ1] = { "center_freq1", BLOBMSG_TYPE_INT32 }, -- [CSA_CENTER_FREQ2] = { "center_freq2", BLOBMSG_TYPE_INT32 }, -- [CSA_BANDWIDTH] = { "bandwidth", BLOBMSG_TYPE_INT32 }, -- [CSA_SEC_CHANNEL_OFFSET] = { "sec_channel_offset", BLOBMSG_TYPE_INT32 }, -- [CSA_HT] = { "ht", BLOBMSG_TYPE_BOOL }, -- [CSA_VHT] = { "vht", BLOBMSG_TYPE_BOOL }, -- [CSA_HE] = { "he", BLOBMSG_TYPE_BOOL }, -- [CSA_BLOCK_TX] = { "block_tx", BLOBMSG_TYPE_BOOL }, -- [CSA_FORCE] = { "force", BLOBMSG_TYPE_BOOL }, --}; -- -- --static void switch_chan_fallback_cb(void *eloop_data, void *user_ctx) --{ -- struct hostapd_iface *iface = eloop_data; -- struct hostapd_freq_params *freq_params = user_ctx; -- -- hostapd_switch_channel_fallback(iface, freq_params); --} -- --#ifdef NEED_AP_MLME --static int --hostapd_switch_chan(struct ubus_context *ctx, struct ubus_object *obj, -- struct ubus_request_data *req, const char *method, -- struct blob_attr *msg) --{ -- struct blob_attr *tb[__CSA_MAX]; -- struct hostapd_data *hapd = get_hapd_from_object(obj); -- struct hostapd_config *iconf = hapd->iface->conf; -- struct hostapd_freq_params *freq_params; -- struct hostapd_hw_modes *mode = hapd->iface->current_mode; -- struct csa_settings css = { -- .freq_params = { -- .ht_enabled = iconf->ieee80211n, -- .vht_enabled = iconf->ieee80211ac, -- .he_enabled = iconf->ieee80211ax, -- .sec_channel_offset = iconf->secondary_channel, -- } -- }; -- u8 chwidth = hostapd_get_oper_chwidth(iconf); -- u8 seg0 = 0, seg1 = 0; -- int ret = UBUS_STATUS_OK; -- int i; -- -- blobmsg_parse(csa_policy, __CSA_MAX, tb, blob_data(msg), blob_len(msg)); -- -- if (!tb[CSA_FREQ]) -- return UBUS_STATUS_INVALID_ARGUMENT; -- -- switch (iconf->vht_oper_chwidth) { -- case CHANWIDTH_USE_HT: -- if (iconf->secondary_channel) -- css.freq_params.bandwidth = 40; -- else -- css.freq_params.bandwidth = 20; -- break; -- case CHANWIDTH_160MHZ: -- css.freq_params.bandwidth = 160; -- break; -- default: -- css.freq_params.bandwidth = 80; -- break; -- } -- -- css.freq_params.freq = blobmsg_get_u32(tb[CSA_FREQ]); -- --#define SET_CSA_SETTING(name, field, type) \ -- do { \ -- if (tb[name]) \ -- css.field = blobmsg_get_ ## type(tb[name]); \ -- } while(0) -- -- SET_CSA_SETTING(CSA_BCN_COUNT, cs_count, u32); -- SET_CSA_SETTING(CSA_CENTER_FREQ1, freq_params.center_freq1, u32); -- SET_CSA_SETTING(CSA_CENTER_FREQ2, freq_params.center_freq2, u32); -- SET_CSA_SETTING(CSA_BANDWIDTH, freq_params.bandwidth, u32); -- SET_CSA_SETTING(CSA_SEC_CHANNEL_OFFSET, freq_params.sec_channel_offset, u32); -- SET_CSA_SETTING(CSA_HT, freq_params.ht_enabled, bool); -- SET_CSA_SETTING(CSA_VHT, freq_params.vht_enabled, bool); -- SET_CSA_SETTING(CSA_HE, freq_params.he_enabled, bool); -- SET_CSA_SETTING(CSA_BLOCK_TX, block_tx, bool); -- -- css.freq_params.channel = hostapd_hw_get_channel(hapd, css.freq_params.freq); -- if (!css.freq_params.channel) -- return UBUS_STATUS_NOT_SUPPORTED; -- -- switch (css.freq_params.bandwidth) { -- case 160: -- chwidth = CHANWIDTH_160MHZ; -- break; -- case 80: -- chwidth = css.freq_params.center_freq2 ? CHANWIDTH_80P80MHZ : CHANWIDTH_80MHZ; -- break; -- default: -- chwidth = CHANWIDTH_USE_HT; -- break; -- } -- -- hostapd_set_freq_params(&css.freq_params, iconf->hw_mode, -- css.freq_params.freq, -- css.freq_params.channel, iconf->enable_edmg, -- iconf->edmg_channel, -- css.freq_params.ht_enabled, -- css.freq_params.vht_enabled, -- css.freq_params.he_enabled, -- css.freq_params.eht_enabled, -- css.freq_params.sec_channel_offset, -- chwidth, seg0, seg1, -- iconf->vht_capab, -- mode ? &mode->he_capab[IEEE80211_MODE_AP] : -- NULL, -- mode ? &mode->eht_capab[IEEE80211_MODE_AP] : -- NULL); -- -- for (i = 0; i < hapd->iface->num_bss; i++) { -- struct hostapd_data *bss = hapd->iface->bss[i]; -- -- if (hostapd_switch_channel(bss, &css) != 0) -- ret = UBUS_STATUS_NOT_SUPPORTED; -- } -- -- if (!ret || !tb[CSA_FORCE] || !blobmsg_get_bool(tb[CSA_FORCE])) -- return ret; -- -- freq_params = malloc(sizeof(*freq_params)); -- memcpy(freq_params, &css.freq_params, sizeof(*freq_params)); -- eloop_register_timeout(0, 1, switch_chan_fallback_cb, -- hapd->iface, freq_params); -- -- return 0; --#undef SET_CSA_SETTING --} --#endif -- --enum { -- VENDOR_ELEMENTS, -- __VENDOR_ELEMENTS_MAX --}; -- --static const struct blobmsg_policy ve_policy[__VENDOR_ELEMENTS_MAX] = { -- /* vendor elements are provided as hex-string */ -- [VENDOR_ELEMENTS] = { "vendor_elements", BLOBMSG_TYPE_STRING }, --}; -- --static int --hostapd_vendor_elements(struct ubus_context *ctx, struct ubus_object *obj, -- struct ubus_request_data *req, const char *method, -- struct blob_attr *msg) --{ -- struct blob_attr *tb[__VENDOR_ELEMENTS_MAX]; -- struct hostapd_data *hapd = get_hapd_from_object(obj); -- struct hostapd_bss_config *bss = hapd->conf; -- struct wpabuf *elems; -- const char *pos; -- size_t len; -- -- blobmsg_parse(ve_policy, __VENDOR_ELEMENTS_MAX, tb, -- blob_data(msg), blob_len(msg)); -- -- if (!tb[VENDOR_ELEMENTS]) -- return UBUS_STATUS_INVALID_ARGUMENT; -- -- pos = blobmsg_data(tb[VENDOR_ELEMENTS]); -- len = os_strlen(pos); -- if (len & 0x01) -- return UBUS_STATUS_INVALID_ARGUMENT; -- -- len /= 2; -- if (len == 0) { -- wpabuf_free(bss->vendor_elements); -- bss->vendor_elements = NULL; -- return 0; -- } -- -- elems = wpabuf_alloc(len); -- if (elems == NULL) -- return 1; -- -- if (hexstr2bin(pos, wpabuf_put(elems, len), len)) { -- wpabuf_free(elems); -- return UBUS_STATUS_INVALID_ARGUMENT; -- } -- -- wpabuf_free(bss->vendor_elements); -- bss->vendor_elements = elems; -- -- /* update beacons if vendor elements were set successfully */ -- if (ieee802_11_update_beacons(hapd->iface) != 0) -- return UBUS_STATUS_NOT_SUPPORTED; -- return UBUS_STATUS_OK; --} -- --static void --hostapd_rrm_print_nr(struct hostapd_neighbor_entry *nr) --{ -- const u8 *data; -- char *str; -- int len; -- -- blobmsg_printf(&b, "", MACSTR, MAC2STR(nr->bssid)); -- -- str = blobmsg_alloc_string_buffer(&b, "", nr->ssid.ssid_len + 1); -- memcpy(str, nr->ssid.ssid, nr->ssid.ssid_len); -- str[nr->ssid.ssid_len] = 0; -- blobmsg_add_string_buffer(&b); -- -- len = wpabuf_len(nr->nr); -- str = blobmsg_alloc_string_buffer(&b, "", 2 * len + 1); -- wpa_snprintf_hex(str, 2 * len + 1, wpabuf_head_u8(nr->nr), len); -- blobmsg_add_string_buffer(&b); --} -- --enum { -- BSS_MGMT_EN_NEIGHBOR, -- BSS_MGMT_EN_BEACON, -- BSS_MGMT_EN_LINK_MEASUREMENT, --#ifdef CONFIG_WNM_AP -- BSS_MGMT_EN_BSS_TRANSITION, --#endif -- __BSS_MGMT_EN_MAX --}; -- --static bool --__hostapd_bss_mgmt_enable_f(struct hostapd_data *hapd, int flag) --{ -- struct hostapd_bss_config *bss = hapd->conf; -- uint32_t flags; -- -- switch (flag) { -- case BSS_MGMT_EN_NEIGHBOR: -- if (bss->radio_measurements[0] & -- WLAN_RRM_CAPS_NEIGHBOR_REPORT) -- return false; -- -- bss->radio_measurements[0] |= -- WLAN_RRM_CAPS_NEIGHBOR_REPORT; -- hostapd_neighbor_set_own_report(hapd); -- return true; -- case BSS_MGMT_EN_BEACON: -- flags = WLAN_RRM_CAPS_BEACON_REPORT_PASSIVE | -- WLAN_RRM_CAPS_BEACON_REPORT_ACTIVE | -- WLAN_RRM_CAPS_BEACON_REPORT_TABLE; -- -- if (bss->radio_measurements[0] & flags == flags) -- return false; -- -- bss->radio_measurements[0] |= (u8) flags; -- return true; -- case BSS_MGMT_EN_LINK_MEASUREMENT: -- flags = WLAN_RRM_CAPS_LINK_MEASUREMENT; -- -- if (bss->radio_measurements[0] & flags == flags) -- return false; -- -- bss->radio_measurements[0] |= (u8) flags; -- return true; --#ifdef CONFIG_WNM_AP -- case BSS_MGMT_EN_BSS_TRANSITION: -- if (bss->bss_transition) -- return false; -- -- bss->bss_transition = 1; -- return true; --#endif -- } --} -- --static void --__hostapd_bss_mgmt_enable(struct hostapd_data *hapd, uint32_t flags) --{ -- bool update = false; -- int i; -- -- for (i = 0; i < __BSS_MGMT_EN_MAX; i++) { -- if (!(flags & (1 << i))) -- continue; -- -- update |= __hostapd_bss_mgmt_enable_f(hapd, i); -- } -- -- if (update) -- ieee802_11_update_beacons(hapd->iface); --} -- -- --static const struct blobmsg_policy bss_mgmt_enable_policy[__BSS_MGMT_EN_MAX] = { -- [BSS_MGMT_EN_NEIGHBOR] = { "neighbor_report", BLOBMSG_TYPE_BOOL }, -- [BSS_MGMT_EN_BEACON] = { "beacon_report", BLOBMSG_TYPE_BOOL }, -- [BSS_MGMT_EN_LINK_MEASUREMENT] = { "link_measurement", BLOBMSG_TYPE_BOOL }, --#ifdef CONFIG_WNM_AP -- [BSS_MGMT_EN_BSS_TRANSITION] = { "bss_transition", BLOBMSG_TYPE_BOOL }, --#endif --}; -- --static int --hostapd_bss_mgmt_enable(struct ubus_context *ctx, struct ubus_object *obj, -- struct ubus_request_data *req, const char *method, -- struct blob_attr *msg) -- --{ -- struct hostapd_data *hapd = get_hapd_from_object(obj); -- struct blob_attr *tb[__BSS_MGMT_EN_MAX]; -- struct blob_attr *cur; -- uint32_t flags = 0; -- int i; -- bool neigh = false, beacon = false; -- -- blobmsg_parse(bss_mgmt_enable_policy, __BSS_MGMT_EN_MAX, tb, blob_data(msg), blob_len(msg)); -- -- for (i = 0; i < ARRAY_SIZE(tb); i++) { -- if (!tb[i] || !blobmsg_get_bool(tb[i])) -- continue; -- -- flags |= (1 << i); -- } -- -- __hostapd_bss_mgmt_enable(hapd, flags); -- -- return 0; --} -- -- --static void --hostapd_rrm_nr_enable(struct hostapd_data *hapd) --{ -- __hostapd_bss_mgmt_enable(hapd, 1 << BSS_MGMT_EN_NEIGHBOR); --} -- --static int --hostapd_rrm_nr_get_own(struct ubus_context *ctx, struct ubus_object *obj, -- struct ubus_request_data *req, const char *method, -- struct blob_attr *msg) --{ -- struct hostapd_data *hapd = get_hapd_from_object(obj); -- struct hostapd_neighbor_entry *nr; -- void *c; -- -- hostapd_rrm_nr_enable(hapd); -- -- nr = hostapd_neighbor_get(hapd, hapd->own_addr, NULL); -- if (!nr) -- return UBUS_STATUS_NOT_FOUND; -- -- blob_buf_init(&b, 0); -- -- c = blobmsg_open_array(&b, "value"); -- hostapd_rrm_print_nr(nr); -- blobmsg_close_array(&b, c); -- -- ubus_send_reply(ctx, req, b.head); -- -- return 0; --} -- --static int --hostapd_rrm_nr_list(struct ubus_context *ctx, struct ubus_object *obj, -- struct ubus_request_data *req, const char *method, -- struct blob_attr *msg) --{ -- struct hostapd_data *hapd = get_hapd_from_object(obj); -- struct hostapd_neighbor_entry *nr; -- void *c; -- -- hostapd_rrm_nr_enable(hapd); -- blob_buf_init(&b, 0); -- -- c = blobmsg_open_array(&b, "list"); -- dl_list_for_each(nr, &hapd->nr_db, struct hostapd_neighbor_entry, list) { -- void *cur; -- -- if (!memcmp(nr->bssid, hapd->own_addr, ETH_ALEN)) -- continue; -- -- cur = blobmsg_open_array(&b, NULL); -- hostapd_rrm_print_nr(nr); -- blobmsg_close_array(&b, cur); -- } -- blobmsg_close_array(&b, c); -- -- ubus_send_reply(ctx, req, b.head); -- -- return 0; --} -- --enum { -- NR_SET_LIST, -- __NR_SET_LIST_MAX --}; -- --static const struct blobmsg_policy nr_set_policy[__NR_SET_LIST_MAX] = { -- [NR_SET_LIST] = { "list", BLOBMSG_TYPE_ARRAY }, --}; -- -- --static void --hostapd_rrm_nr_clear(struct hostapd_data *hapd) --{ -- struct hostapd_neighbor_entry *nr; -- --restart: -- dl_list_for_each(nr, &hapd->nr_db, struct hostapd_neighbor_entry, list) { -- if (!memcmp(nr->bssid, hapd->own_addr, ETH_ALEN)) -- continue; -- -- hostapd_neighbor_remove(hapd, nr->bssid, &nr->ssid); -- goto restart; -- } --} -- --static int --hostapd_rrm_nr_set(struct ubus_context *ctx, struct ubus_object *obj, -- struct ubus_request_data *req, const char *method, -- struct blob_attr *msg) --{ -- static const struct blobmsg_policy nr_e_policy[] = { -- { .type = BLOBMSG_TYPE_STRING }, -- { .type = BLOBMSG_TYPE_STRING }, -- { .type = BLOBMSG_TYPE_STRING }, -- }; -- struct hostapd_data *hapd = get_hapd_from_object(obj); -- struct blob_attr *tb_l[__NR_SET_LIST_MAX]; -- struct blob_attr *tb[ARRAY_SIZE(nr_e_policy)]; -- struct blob_attr *cur; -- int rem; -- -- hostapd_rrm_nr_enable(hapd); -- -- blobmsg_parse(nr_set_policy, __NR_SET_LIST_MAX, tb_l, blob_data(msg), blob_len(msg)); -- if (!tb_l[NR_SET_LIST]) -- return UBUS_STATUS_INVALID_ARGUMENT; -- -- hostapd_rrm_nr_clear(hapd); -- blobmsg_for_each_attr(cur, tb_l[NR_SET_LIST], rem) { -- struct wpa_ssid_value ssid; -- struct wpabuf *data; -- u8 bssid[ETH_ALEN]; -- char *s, *nr_s; -- -- blobmsg_parse_array(nr_e_policy, ARRAY_SIZE(nr_e_policy), tb, blobmsg_data(cur), blobmsg_data_len(cur)); -- if (!tb[0] || !tb[1] || !tb[2]) -- goto invalid; -- -- /* Neighbor Report binary */ -- nr_s = blobmsg_get_string(tb[2]); -- data = wpabuf_parse_bin(nr_s); -- if (!data) -- goto invalid; -- -- /* BSSID */ -- s = blobmsg_get_string(tb[0]); -- if (strlen(s) == 0) { -- /* Copy BSSID from neighbor report */ -- if (hwaddr_compact_aton(nr_s, bssid)) -- goto invalid; -- } else if (hwaddr_aton(s, bssid)) { -- goto invalid; -- } -- -- /* SSID */ -- s = blobmsg_get_string(tb[1]); -- if (strlen(s) == 0) { -- /* Copy SSID from hostapd BSS conf */ -- memcpy(&ssid, &hapd->conf->ssid, sizeof(ssid)); -- } else { -- ssid.ssid_len = strlen(s); -- if (ssid.ssid_len > sizeof(ssid.ssid)) -- goto invalid; -- -- memcpy(&ssid, s, ssid.ssid_len); -- } -- -- hostapd_neighbor_set(hapd, bssid, &ssid, data, NULL, NULL, 0, 0); -- wpabuf_free(data); -- continue; -- --invalid: -- return UBUS_STATUS_INVALID_ARGUMENT; -- } -- -- return 0; --} -- --enum { -- BEACON_REQ_ADDR, -- BEACON_REQ_MODE, -- BEACON_REQ_OP_CLASS, -- BEACON_REQ_CHANNEL, -- BEACON_REQ_DURATION, -- BEACON_REQ_BSSID, -- BEACON_REQ_SSID, -- __BEACON_REQ_MAX, --}; -- --static const struct blobmsg_policy beacon_req_policy[__BEACON_REQ_MAX] = { -- [BEACON_REQ_ADDR] = { "addr", BLOBMSG_TYPE_STRING }, -- [BEACON_REQ_OP_CLASS] { "op_class", BLOBMSG_TYPE_INT32 }, -- [BEACON_REQ_CHANNEL] { "channel", BLOBMSG_TYPE_INT32 }, -- [BEACON_REQ_DURATION] { "duration", BLOBMSG_TYPE_INT32 }, -- [BEACON_REQ_MODE] { "mode", BLOBMSG_TYPE_INT32 }, -- [BEACON_REQ_BSSID] { "bssid", BLOBMSG_TYPE_STRING }, -- [BEACON_REQ_SSID] { "ssid", BLOBMSG_TYPE_STRING }, --}; -- --static int --hostapd_rrm_beacon_req(struct ubus_context *ctx, struct ubus_object *obj, -- struct ubus_request_data *ureq, const char *method, -- struct blob_attr *msg) --{ -- struct hostapd_data *hapd = container_of(obj, struct hostapd_data, ubus.obj); -- struct blob_attr *tb[__BEACON_REQ_MAX]; -- struct blob_attr *cur; -- struct wpabuf *req; -- u8 bssid[ETH_ALEN] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }; -- u8 addr[ETH_ALEN]; -- int mode, rem, ret; -- int buf_len = 13; -- -- blobmsg_parse(beacon_req_policy, __BEACON_REQ_MAX, tb, blob_data(msg), blob_len(msg)); -- -- if (!tb[BEACON_REQ_ADDR] || !tb[BEACON_REQ_MODE] || !tb[BEACON_REQ_DURATION] || -- !tb[BEACON_REQ_OP_CLASS] || !tb[BEACON_REQ_CHANNEL]) -- return UBUS_STATUS_INVALID_ARGUMENT; -- -- if (tb[BEACON_REQ_SSID]) -- buf_len += blobmsg_data_len(tb[BEACON_REQ_SSID]) + 2 - 1; -- -- mode = blobmsg_get_u32(tb[BEACON_REQ_MODE]); -- if (hwaddr_aton(blobmsg_data(tb[BEACON_REQ_ADDR]), addr)) -- return UBUS_STATUS_INVALID_ARGUMENT; -- -- if (tb[BEACON_REQ_BSSID] && -- hwaddr_aton(blobmsg_data(tb[BEACON_REQ_BSSID]), bssid)) -- return UBUS_STATUS_INVALID_ARGUMENT; -- -- req = wpabuf_alloc(buf_len); -- if (!req) -- return UBUS_STATUS_UNKNOWN_ERROR; -- -- /* 1: regulatory class */ -- wpabuf_put_u8(req, blobmsg_get_u32(tb[BEACON_REQ_OP_CLASS])); -- -- /* 2: channel number */ -- wpabuf_put_u8(req, blobmsg_get_u32(tb[BEACON_REQ_CHANNEL])); -- -- /* 3-4: randomization interval */ -- wpabuf_put_le16(req, 0); -- -- /* 5-6: duration */ -- wpabuf_put_le16(req, blobmsg_get_u32(tb[BEACON_REQ_DURATION])); -- -- /* 7: mode */ -- wpabuf_put_u8(req, blobmsg_get_u32(tb[BEACON_REQ_MODE])); -- -- /* 8-13: BSSID */ -- wpabuf_put_data(req, bssid, ETH_ALEN); -- -- if ((cur = tb[BEACON_REQ_SSID]) != NULL) { -- wpabuf_put_u8(req, WLAN_EID_SSID); -- wpabuf_put_u8(req, blobmsg_data_len(cur) - 1); -- wpabuf_put_data(req, blobmsg_data(cur), blobmsg_data_len(cur) - 1); -- } -- -- ret = hostapd_send_beacon_req(hapd, addr, 0, req); -- if (ret < 0) -- return -ret; -- -- return 0; --} -- --enum { -- LM_REQ_ADDR, -- LM_REQ_TX_POWER_USED, -- LM_REQ_TX_POWER_MAX, -- __LM_REQ_MAX, --}; -- --static const struct blobmsg_policy lm_req_policy[__LM_REQ_MAX] = { -- [LM_REQ_ADDR] = { "addr", BLOBMSG_TYPE_STRING }, -- [LM_REQ_TX_POWER_USED] = { "tx-power-used", BLOBMSG_TYPE_INT32 }, -- [LM_REQ_TX_POWER_MAX] = { "tx-power-max", BLOBMSG_TYPE_INT32 }, --}; -- --static int --hostapd_rrm_lm_req(struct ubus_context *ctx, struct ubus_object *obj, -- struct ubus_request_data *ureq, const char *method, -- struct blob_attr *msg) --{ -- struct hostapd_data *hapd = container_of(obj, struct hostapd_data, ubus.obj); -- struct blob_attr *tb[__LM_REQ_MAX]; -- struct wpabuf *buf; -- u8 addr[ETH_ALEN]; -- int ret; -- int8_t txp_used, txp_max; -- -- txp_used = 0; -- txp_max = 0; -- -- blobmsg_parse(lm_req_policy, __LM_REQ_MAX, tb, blob_data(msg), blob_len(msg)); -- -- if (!tb[LM_REQ_ADDR]) -- return UBUS_STATUS_INVALID_ARGUMENT; -- -- if (tb[LM_REQ_TX_POWER_USED]) -- txp_used = (int8_t) blobmsg_get_u32(tb[LM_REQ_TX_POWER_USED]); -- -- if (tb[LM_REQ_TX_POWER_MAX]) -- txp_max = (int8_t) blobmsg_get_u32(tb[LM_REQ_TX_POWER_MAX]); -- -- if (hwaddr_aton(blobmsg_data(tb[LM_REQ_ADDR]), addr)) -- return UBUS_STATUS_INVALID_ARGUMENT; -- -- buf = wpabuf_alloc(5); -- if (!buf) -- return UBUS_STATUS_UNKNOWN_ERROR; -- -- wpabuf_put_u8(buf, WLAN_ACTION_RADIO_MEASUREMENT); -- wpabuf_put_u8(buf, WLAN_RRM_LINK_MEASUREMENT_REQUEST); -- wpabuf_put_u8(buf, 1); -- /* TX-Power used */ -- wpabuf_put_u8(buf, txp_used); -- /* Max TX Power */ -- wpabuf_put_u8(buf, txp_max); -- -- ret = hostapd_drv_send_action(hapd, hapd->iface->freq, 0, addr, -- wpabuf_head(buf), wpabuf_len(buf)); -- -- wpabuf_free(buf); -- if (ret < 0) -- return -ret; -- -- return 0; --} -- -- --void hostapd_ubus_handle_link_measurement(struct hostapd_data *hapd, const u8 *data, size_t len) --{ -- const struct ieee80211_mgmt *mgmt = (const struct ieee80211_mgmt *) data; -- const u8 *pos, *end; -- u8 token; -- -- end = data + len; -- token = mgmt->u.action.u.rrm.dialog_token; -- pos = mgmt->u.action.u.rrm.variable; -- -- if (end - pos < 8) -- return; -- -- if (!hapd->ubus.obj.has_subscribers) -- return; -- -- blob_buf_init(&b, 0); -- blobmsg_add_macaddr(&b, "address", mgmt->sa); -- blobmsg_add_u16(&b, "dialog-token", token); -- blobmsg_add_u16(&b, "rx-antenna-id", pos[4]); -- blobmsg_add_u16(&b, "tx-antenna-id", pos[5]); -- blobmsg_add_u16(&b, "rcpi", pos[6]); -- blobmsg_add_u16(&b, "rsni", pos[7]); -- -- ubus_notify(ctx, &hapd->ubus.obj, "link-measurement-report", b.head, -1); --} -- -- --#ifdef CONFIG_WNM_AP -- --static int --hostapd_bss_tr_send(struct hostapd_data *hapd, u8 *addr, bool disassoc_imminent, bool abridged, -- u16 disassoc_timer, u8 validity_period, u8 dialog_token, -- struct blob_attr *neighbors, u8 mbo_reason, u8 cell_pref, u8 reassoc_delay) --{ -- struct blob_attr *cur; -- struct sta_info *sta; -- int nr_len = 0; -- int rem; -- u8 *nr = NULL; -- u8 req_mode = 0; -- u8 mbo[10]; -- size_t mbo_len = 0; -- -- sta = ap_get_sta(hapd, addr); -- if (!sta) -- return UBUS_STATUS_NOT_FOUND; -- -- if (neighbors) { -- u8 *nr_cur; -- -- if (blobmsg_check_array(neighbors, -- BLOBMSG_TYPE_STRING) < 0) -- return UBUS_STATUS_INVALID_ARGUMENT; -- -- blobmsg_for_each_attr(cur, neighbors, rem) { -- int len = strlen(blobmsg_get_string(cur)); -- -- if (len % 2) -- return UBUS_STATUS_INVALID_ARGUMENT; -- -- nr_len += (len / 2) + 2; -- } -- -- if (nr_len) { -- nr = os_zalloc(nr_len); -- if (!nr) -- return UBUS_STATUS_UNKNOWN_ERROR; -- } -- -- nr_cur = nr; -- blobmsg_for_each_attr(cur, neighbors, rem) { -- int len = strlen(blobmsg_get_string(cur)) / 2; -- -- *nr_cur++ = WLAN_EID_NEIGHBOR_REPORT; -- *nr_cur++ = (u8) len; -- if (hexstr2bin(blobmsg_data(cur), nr_cur, len)) { -- free(nr); -- return UBUS_STATUS_INVALID_ARGUMENT; -- } -- -- nr_cur += len; -- } -- } -- -- if (nr) -- req_mode |= WNM_BSS_TM_REQ_PREF_CAND_LIST_INCLUDED; -- -- if (abridged) -- req_mode |= WNM_BSS_TM_REQ_ABRIDGED; -- -- if (disassoc_imminent) -- req_mode |= WNM_BSS_TM_REQ_DISASSOC_IMMINENT; -- --#ifdef CONFIG_MBO -- u8 *mbo_pos = mbo; -- -- if (mbo_reason > MBO_TRANSITION_REASON_PREMIUM_AP) -- return UBUS_STATUS_INVALID_ARGUMENT; -- -- if (cell_pref != 0 && cell_pref != 1 && cell_pref != 255) -- return UBUS_STATUS_INVALID_ARGUMENT; -- -- if (reassoc_delay > 65535 || (reassoc_delay && !disassoc_imminent)) -- return UBUS_STATUS_INVALID_ARGUMENT; -- -- *mbo_pos++ = MBO_ATTR_ID_TRANSITION_REASON; -- *mbo_pos++ = 1; -- *mbo_pos++ = mbo_reason; -- *mbo_pos++ = MBO_ATTR_ID_CELL_DATA_PREF; -- *mbo_pos++ = 1; -- *mbo_pos++ = cell_pref; -- -- if (reassoc_delay) { -- *mbo_pos++ = MBO_ATTR_ID_ASSOC_RETRY_DELAY; -- *mbo_pos++ = 2; -- WPA_PUT_LE16(mbo_pos, reassoc_delay); -- mbo_pos += 2; -- } -- -- mbo_len = mbo_pos - mbo; --#endif -- -- if (wnm_send_bss_tm_req(hapd, sta, req_mode, disassoc_timer, validity_period, NULL, -- dialog_token, NULL, nr, nr_len, mbo_len ? mbo : NULL, mbo_len)) -- return UBUS_STATUS_UNKNOWN_ERROR; -- -- return 0; --} -- --enum { -- BSS_TR_ADDR, -- BSS_TR_DA_IMMINENT, -- BSS_TR_DA_TIMER, -- BSS_TR_VALID_PERIOD, -- BSS_TR_NEIGHBORS, -- BSS_TR_ABRIDGED, -- BSS_TR_DIALOG_TOKEN, --#ifdef CONFIG_MBO -- BSS_TR_MBO_REASON, -- BSS_TR_CELL_PREF, -- BSS_TR_REASSOC_DELAY, --#endif -- __BSS_TR_DISASSOC_MAX --}; -- --static const struct blobmsg_policy bss_tr_policy[__BSS_TR_DISASSOC_MAX] = { -- [BSS_TR_ADDR] = { "addr", BLOBMSG_TYPE_STRING }, -- [BSS_TR_DA_IMMINENT] = { "disassociation_imminent", BLOBMSG_TYPE_BOOL }, -- [BSS_TR_DA_TIMER] = { "disassociation_timer", BLOBMSG_TYPE_INT32 }, -- [BSS_TR_VALID_PERIOD] = { "validity_period", BLOBMSG_TYPE_INT32 }, -- [BSS_TR_NEIGHBORS] = { "neighbors", BLOBMSG_TYPE_ARRAY }, -- [BSS_TR_ABRIDGED] = { "abridged", BLOBMSG_TYPE_BOOL }, -- [BSS_TR_DIALOG_TOKEN] = { "dialog_token", BLOBMSG_TYPE_INT32 }, --#ifdef CONFIG_MBO -- [BSS_TR_MBO_REASON] = { "mbo_reason", BLOBMSG_TYPE_INT32 }, -- [BSS_TR_CELL_PREF] = { "cell_pref", BLOBMSG_TYPE_INT32 }, -- [BSS_TR_REASSOC_DELAY] = { "reassoc_delay", BLOBMSG_TYPE_INT32 }, --#endif --}; -- --static int --hostapd_bss_transition_request(struct ubus_context *ctx, struct ubus_object *obj, -- struct ubus_request_data *ureq, const char *method, -- struct blob_attr *msg) --{ -- struct hostapd_data *hapd = container_of(obj, struct hostapd_data, ubus.obj); -- struct blob_attr *tb[__BSS_TR_DISASSOC_MAX]; -- struct sta_info *sta; -- u32 da_timer = 0; -- u32 valid_period = 0; -- u8 addr[ETH_ALEN]; -- u32 dialog_token = 1; -- bool abridged; -- bool da_imminent; -- u8 mbo_reason; -- u8 cell_pref; -- u8 reassoc_delay; -- -- blobmsg_parse(bss_tr_policy, __BSS_TR_DISASSOC_MAX, tb, blob_data(msg), blob_len(msg)); -- -- if (!tb[BSS_TR_ADDR]) -- return UBUS_STATUS_INVALID_ARGUMENT; -- -- if (hwaddr_aton(blobmsg_data(tb[BSS_TR_ADDR]), addr)) -- return UBUS_STATUS_INVALID_ARGUMENT; -- -- if (tb[BSS_TR_DA_TIMER]) -- da_timer = blobmsg_get_u32(tb[BSS_TR_DA_TIMER]); -- -- if (tb[BSS_TR_VALID_PERIOD]) -- valid_period = blobmsg_get_u32(tb[BSS_TR_VALID_PERIOD]); -- -- if (tb[BSS_TR_DIALOG_TOKEN]) -- dialog_token = blobmsg_get_u32(tb[BSS_TR_DIALOG_TOKEN]); -- -- da_imminent = !!(tb[BSS_TR_DA_IMMINENT] && blobmsg_get_bool(tb[BSS_TR_DA_IMMINENT])); -- abridged = !!(tb[BSS_TR_ABRIDGED] && blobmsg_get_bool(tb[BSS_TR_ABRIDGED])); -- --#ifdef CONFIG_MBO -- if (tb[BSS_TR_MBO_REASON]) -- mbo_reason = blobmsg_get_u32(tb[BSS_TR_MBO_REASON]); -- -- if (tb[BSS_TR_CELL_PREF]) -- cell_pref = blobmsg_get_u32(tb[BSS_TR_CELL_PREF]); -- -- if (tb[BSS_TR_REASSOC_DELAY]) -- reassoc_delay = blobmsg_get_u32(tb[BSS_TR_REASSOC_DELAY]); --#endif -- -- return hostapd_bss_tr_send(hapd, addr, da_imminent, abridged, da_timer, valid_period, -- dialog_token, tb[BSS_TR_NEIGHBORS], mbo_reason, cell_pref, reassoc_delay); --} --#endif -- --#ifdef CONFIG_AIRTIME_POLICY --enum { -- UPDATE_AIRTIME_STA, -- UPDATE_AIRTIME_WEIGHT, -- __UPDATE_AIRTIME_MAX, --}; -- -- --static const struct blobmsg_policy airtime_policy[__UPDATE_AIRTIME_MAX] = { -- [UPDATE_AIRTIME_STA] = { "sta", BLOBMSG_TYPE_STRING }, -- [UPDATE_AIRTIME_WEIGHT] = { "weight", BLOBMSG_TYPE_INT32 }, --}; -- --static int --hostapd_bss_update_airtime(struct ubus_context *ctx, struct ubus_object *obj, -- struct ubus_request_data *ureq, const char *method, -- struct blob_attr *msg) --{ -- struct hostapd_data *hapd = container_of(obj, struct hostapd_data, ubus.obj); -- struct blob_attr *tb[__UPDATE_AIRTIME_MAX]; -- struct sta_info *sta = NULL; -- u8 addr[ETH_ALEN]; -- int weight; -- -- blobmsg_parse(airtime_policy, __UPDATE_AIRTIME_MAX, tb, blob_data(msg), blob_len(msg)); -- -- if (!tb[UPDATE_AIRTIME_WEIGHT]) -- return UBUS_STATUS_INVALID_ARGUMENT; -- -- weight = blobmsg_get_u32(tb[UPDATE_AIRTIME_WEIGHT]); -- -- if (!tb[UPDATE_AIRTIME_STA]) { -- if (!weight) -- return UBUS_STATUS_INVALID_ARGUMENT; -- -- hapd->conf->airtime_weight = weight; -- return 0; -- } -- -- if (hwaddr_aton(blobmsg_data(tb[UPDATE_AIRTIME_STA]), addr)) -- return UBUS_STATUS_INVALID_ARGUMENT; -- -- sta = ap_get_sta(hapd, addr); -- if (!sta) -- return UBUS_STATUS_NOT_FOUND; -- -- sta->dyn_airtime_weight = weight; -- airtime_policy_new_sta(hapd, sta); -- -- return 0; --} --#endif -- -- --static const struct ubus_method bss_methods[] = { -- UBUS_METHOD_NOARG("reload", hostapd_bss_reload), -- UBUS_METHOD_NOARG("get_clients", hostapd_bss_get_clients), -- UBUS_METHOD_NOARG("get_status", hostapd_bss_get_status), -- UBUS_METHOD("del_client", hostapd_bss_del_client, del_policy), --#ifdef CONFIG_AIRTIME_POLICY -- UBUS_METHOD("update_airtime", hostapd_bss_update_airtime, airtime_policy), --#endif -- UBUS_METHOD_NOARG("list_bans", hostapd_bss_list_bans), --#ifdef CONFIG_WPS -- UBUS_METHOD_NOARG("wps_start", hostapd_bss_wps_start), -- UBUS_METHOD_NOARG("wps_status", hostapd_bss_wps_status), -- UBUS_METHOD_NOARG("wps_cancel", hostapd_bss_wps_cancel), --#endif -- UBUS_METHOD_NOARG("update_beacon", hostapd_bss_update_beacon), -- UBUS_METHOD_NOARG("get_features", hostapd_bss_get_features), --#ifdef NEED_AP_MLME -- UBUS_METHOD("switch_chan", hostapd_switch_chan, csa_policy), --#endif -- UBUS_METHOD("set_vendor_elements", hostapd_vendor_elements, ve_policy), -- UBUS_METHOD("notify_response", hostapd_notify_response, notify_policy), -- UBUS_METHOD("bss_mgmt_enable", hostapd_bss_mgmt_enable, bss_mgmt_enable_policy), -- UBUS_METHOD_NOARG("rrm_nr_get_own", hostapd_rrm_nr_get_own), -- UBUS_METHOD_NOARG("rrm_nr_list", hostapd_rrm_nr_list), -- UBUS_METHOD("rrm_nr_set", hostapd_rrm_nr_set, nr_set_policy), -- UBUS_METHOD("rrm_beacon_req", hostapd_rrm_beacon_req, beacon_req_policy), -- UBUS_METHOD("link_measurement_req", hostapd_rrm_lm_req, lm_req_policy), --#ifdef CONFIG_WNM_AP -- UBUS_METHOD("bss_transition_request", hostapd_bss_transition_request, bss_tr_policy), --#endif --}; -- --static struct ubus_object_type bss_object_type = -- UBUS_OBJECT_TYPE("hostapd_bss", bss_methods); -- --static int avl_compare_macaddr(const void *k1, const void *k2, void *ptr) --{ -- return memcmp(k1, k2, ETH_ALEN); --} -- --void hostapd_ubus_add_bss(struct hostapd_data *hapd) --{ -- struct ubus_object *obj = &hapd->ubus.obj; -- char *name; -- int ret; -- --#ifdef CONFIG_MESH -- if (hapd->conf->mesh & MESH_ENABLED) -- return; --#endif -- -- if (!hostapd_ubus_init()) -- return; -- -- if (asprintf(&name, "hostapd.%s", hapd->conf->iface) < 0) -- return; -- -- avl_init(&hapd->ubus.banned, avl_compare_macaddr, false, NULL); -- obj->name = name; -- obj->type = &bss_object_type; -- obj->methods = bss_object_type.methods; -- obj->n_methods = bss_object_type.n_methods; -- ret = ubus_add_object(ctx, obj); -- hostapd_ubus_ref_inc(); -- -- hostapd_send_shared_event(&hapd->iface->interfaces->ubus, hapd->conf->iface, "add"); --} -- --void hostapd_ubus_free_bss(struct hostapd_data *hapd) --{ -- struct ubus_object *obj = &hapd->ubus.obj; -- char *name = (char *) obj->name; -- --#ifdef CONFIG_MESH -- if (hapd->conf->mesh & MESH_ENABLED) -- return; --#endif -- -- if (!ctx) -- return; -- -- hostapd_send_shared_event(&hapd->iface->interfaces->ubus, hapd->conf->iface, "remove"); -- -- if (obj->id) { -- ubus_remove_object(ctx, obj); -- hostapd_ubus_ref_dec(); -- } -- -- free(name); --} -- --static void --hostapd_ubus_vlan_action(struct hostapd_data *hapd, struct hostapd_vlan *vlan, -- const char *action) --{ -- struct vlan_description *desc = &vlan->vlan_desc; -- void *c; -- int i; -- -- if (!hapd->ubus.obj.has_subscribers) -- return; -- -- blob_buf_init(&b, 0); -- blobmsg_add_string(&b, "ifname", vlan->ifname); -- blobmsg_add_string(&b, "bridge", vlan->bridge); -- blobmsg_add_u32(&b, "vlan_id", vlan->vlan_id); -- -- if (desc->notempty) { -- blobmsg_add_u32(&b, "untagged", desc->untagged); -- c = blobmsg_open_array(&b, "tagged"); -- for (i = 0; i < ARRAY_SIZE(desc->tagged) && desc->tagged[i]; i++) -- blobmsg_add_u32(&b, "", desc->tagged[i]); -- blobmsg_close_array(&b, c); -- } -- -- ubus_notify(ctx, &hapd->ubus.obj, action, b.head, -1); --} -- --void hostapd_ubus_add_vlan(struct hostapd_data *hapd, struct hostapd_vlan *vlan) --{ -- hostapd_ubus_vlan_action(hapd, vlan, "vlan_add"); --} -- --void hostapd_ubus_remove_vlan(struct hostapd_data *hapd, struct hostapd_vlan *vlan) --{ -- hostapd_ubus_vlan_action(hapd, vlan, "vlan_remove"); --} -- --static const struct ubus_method daemon_methods[] = { -- UBUS_METHOD("config_add", hostapd_config_add, config_add_policy), -- UBUS_METHOD("config_remove", hostapd_config_remove, config_remove_policy), --}; -- --static struct ubus_object_type daemon_object_type = -- UBUS_OBJECT_TYPE("hostapd", daemon_methods); -- --void hostapd_ubus_add(struct hapd_interfaces *interfaces) --{ -- struct ubus_object *obj = &interfaces->ubus; -- int ret; -- -- if (!hostapd_ubus_init()) -- return; -- -- obj->name = strdup("hostapd"); -- -- obj->type = &daemon_object_type; -- obj->methods = daemon_object_type.methods; -- obj->n_methods = daemon_object_type.n_methods; -- ret = ubus_add_object(ctx, obj); -- hostapd_ubus_ref_inc(); --} -- --void hostapd_ubus_free(struct hapd_interfaces *interfaces) --{ -- struct ubus_object *obj = &interfaces->ubus; -- char *name = (char *) obj->name; -- -- if (!ctx) -- return; -- -- if (obj->id) { -- ubus_remove_object(ctx, obj); -- hostapd_ubus_ref_dec(); -- } -- -- free(name); --} -- --struct ubus_event_req { -- struct ubus_notify_request nreq; -- int resp; --}; -- --static void --ubus_event_cb(struct ubus_notify_request *req, int idx, int ret) --{ -- struct ubus_event_req *ureq = container_of(req, struct ubus_event_req, nreq); -- -- ureq->resp = ret; --} -- --int hostapd_ubus_handle_event(struct hostapd_data *hapd, struct hostapd_ubus_request *req) --{ -- struct ubus_banned_client *ban; -- const char *types[HOSTAPD_UBUS_TYPE_MAX] = { -- [HOSTAPD_UBUS_PROBE_REQ] = "probe", -- [HOSTAPD_UBUS_AUTH_REQ] = "auth", -- [HOSTAPD_UBUS_ASSOC_REQ] = "assoc", -- }; -- const char *type = "mgmt"; -- struct ubus_event_req ureq = {}; -- const u8 *addr; -- -- if (req->mgmt_frame) -- addr = req->mgmt_frame->sa; -- else -- addr = req->addr; -- -- ban = avl_find_element(&hapd->ubus.banned, addr, ban, avl); -- if (ban) -- return WLAN_STATUS_AP_UNABLE_TO_HANDLE_NEW_STA; -- -- if (!hapd->ubus.obj.has_subscribers) -- return WLAN_STATUS_SUCCESS; -- -- if (req->type < ARRAY_SIZE(types)) -- type = types[req->type]; -- -- blob_buf_init(&b, 0); -- blobmsg_add_macaddr(&b, "address", addr); -- if (req->mgmt_frame) -- blobmsg_add_macaddr(&b, "target", req->mgmt_frame->da); -- if (req->ssi_signal) -- blobmsg_add_u32(&b, "signal", req->ssi_signal); -- blobmsg_add_u32(&b, "freq", hapd->iface->freq); -- -- if (req->elems) { -- if(req->elems->ht_capabilities) -- { -- struct ieee80211_ht_capabilities *ht_capabilities; -- void *ht_cap, *ht_cap_mcs_set, *mcs_set; -- -- -- ht_capabilities = (struct ieee80211_ht_capabilities*) req->elems->ht_capabilities; -- ht_cap = blobmsg_open_table(&b, "ht_capabilities"); -- blobmsg_add_u16(&b, "ht_capabilities_info", ht_capabilities->ht_capabilities_info); -- ht_cap_mcs_set = blobmsg_open_table(&b, "supported_mcs_set"); -- blobmsg_add_u16(&b, "a_mpdu_params", ht_capabilities->a_mpdu_params); -- blobmsg_add_u16(&b, "ht_extended_capabilities", ht_capabilities->ht_extended_capabilities); -- blobmsg_add_u32(&b, "tx_bf_capability_info", ht_capabilities->tx_bf_capability_info); -- blobmsg_add_u16(&b, "asel_capabilities", ht_capabilities->asel_capabilities); -- mcs_set = blobmsg_open_array(&b, "supported_mcs_set"); -- for (int i = 0; i < 16; i++) { -- blobmsg_add_u16(&b, NULL, (u16) ht_capabilities->supported_mcs_set[i]); -- } -- blobmsg_close_array(&b, mcs_set); -- blobmsg_close_table(&b, ht_cap_mcs_set); -- blobmsg_close_table(&b, ht_cap); -- } -- if(req->elems->vht_capabilities) -- { -- struct ieee80211_vht_capabilities *vht_capabilities; -- void *vht_cap, *vht_cap_mcs_set; -- -- vht_capabilities = (struct ieee80211_vht_capabilities*) req->elems->vht_capabilities; -- vht_cap = blobmsg_open_table(&b, "vht_capabilities"); -- blobmsg_add_u32(&b, "vht_capabilities_info", vht_capabilities->vht_capabilities_info); -- vht_cap_mcs_set = blobmsg_open_table(&b, "vht_supported_mcs_set"); -- blobmsg_add_u16(&b, "rx_map", vht_capabilities->vht_supported_mcs_set.rx_map); -- blobmsg_add_u16(&b, "rx_highest", vht_capabilities->vht_supported_mcs_set.rx_highest); -- blobmsg_add_u16(&b, "tx_map", vht_capabilities->vht_supported_mcs_set.tx_map); -- blobmsg_add_u16(&b, "tx_highest", vht_capabilities->vht_supported_mcs_set.tx_highest); -- blobmsg_close_table(&b, vht_cap_mcs_set); -- blobmsg_close_table(&b, vht_cap); -- } -- } -- -- if (!hapd->ubus.notify_response) { -- ubus_notify(ctx, &hapd->ubus.obj, type, b.head, -1); -- return WLAN_STATUS_SUCCESS; -- } -- -- if (ubus_notify_async(ctx, &hapd->ubus.obj, type, b.head, &ureq.nreq)) -- return WLAN_STATUS_SUCCESS; -- -- ureq.nreq.status_cb = ubus_event_cb; -- ubus_complete_request(ctx, &ureq.nreq.req, 100); -- -- if (ureq.resp) -- return ureq.resp; -- -- return WLAN_STATUS_SUCCESS; --} -- --void hostapd_ubus_notify(struct hostapd_data *hapd, const char *type, const u8 *addr) --{ -- if (!hapd->ubus.obj.has_subscribers) -- return; -- -- if (!addr) -- return; -- -- blob_buf_init(&b, 0); -- blobmsg_add_macaddr(&b, "address", addr); -- -- ubus_notify(ctx, &hapd->ubus.obj, type, b.head, -1); --} -- --void hostapd_ubus_notify_authorized(struct hostapd_data *hapd, struct sta_info *sta, -- const char *auth_alg) --{ -- if (!hapd->ubus.obj.has_subscribers) -- return; -- -- blob_buf_init(&b, 0); -- blobmsg_add_macaddr(&b, "address", sta->addr); -- if (auth_alg) -- blobmsg_add_string(&b, "auth-alg", auth_alg); -- -- ubus_notify(ctx, &hapd->ubus.obj, "sta-authorized", b.head, -1); --} -- --void hostapd_ubus_notify_beacon_report( -- struct hostapd_data *hapd, const u8 *addr, u8 token, u8 rep_mode, -- struct rrm_measurement_beacon_report *rep, size_t len) --{ -- if (!hapd->ubus.obj.has_subscribers) -- return; -- -- if (!addr || !rep) -- return; -- -- blob_buf_init(&b, 0); -- blobmsg_add_macaddr(&b, "address", addr); -- blobmsg_add_u16(&b, "op-class", rep->op_class); -- blobmsg_add_u16(&b, "channel", rep->channel); -- blobmsg_add_u64(&b, "start-time", rep->start_time); -- blobmsg_add_u16(&b, "duration", rep->duration); -- blobmsg_add_u16(&b, "report-info", rep->report_info); -- blobmsg_add_u16(&b, "rcpi", rep->rcpi); -- blobmsg_add_u16(&b, "rsni", rep->rsni); -- blobmsg_add_macaddr(&b, "bssid", rep->bssid); -- blobmsg_add_u16(&b, "antenna-id", rep->antenna_id); -- blobmsg_add_u16(&b, "parent-tsf", rep->parent_tsf); -- blobmsg_add_u16(&b, "rep-mode", rep_mode); -- -- ubus_notify(ctx, &hapd->ubus.obj, "beacon-report", b.head, -1); --} -- --void hostapd_ubus_notify_radar_detected(struct hostapd_iface *iface, int frequency, -- int chan_width, int cf1, int cf2) --{ -- struct hostapd_data *hapd; -- int i; -- -- blob_buf_init(&b, 0); -- blobmsg_add_u16(&b, "frequency", frequency); -- blobmsg_add_u16(&b, "width", chan_width); -- blobmsg_add_u16(&b, "center1", cf1); -- blobmsg_add_u16(&b, "center2", cf2); -- -- for (i = 0; i < iface->num_bss; i++) { -- hapd = iface->bss[i]; -- ubus_notify(ctx, &hapd->ubus.obj, "radar-detected", b.head, -1); -- } --} -- --#ifdef CONFIG_WNM_AP --static void hostapd_ubus_notify_bss_transition_add_candidate_list( -- const u8 *candidate_list, u16 candidate_list_len) --{ -- char *cl_str; -- int i; -- -- if (candidate_list_len == 0) -- return; -- -- cl_str = blobmsg_alloc_string_buffer(&b, "candidate-list", candidate_list_len * 2 + 1); -- for (i = 0; i < candidate_list_len; i++) -- snprintf(&cl_str[i*2], 3, "%02X", candidate_list[i]); -- blobmsg_add_string_buffer(&b); -- --} --#endif -- --void hostapd_ubus_notify_bss_transition_response( -- struct hostapd_data *hapd, const u8 *addr, u8 dialog_token, u8 status_code, -- u8 bss_termination_delay, const u8 *target_bssid, -- const u8 *candidate_list, u16 candidate_list_len) --{ --#ifdef CONFIG_WNM_AP -- u16 i; -- -- if (!hapd->ubus.obj.has_subscribers) -- return; -- -- if (!addr) -- return; -- -- blob_buf_init(&b, 0); -- blobmsg_add_macaddr(&b, "address", addr); -- blobmsg_add_u8(&b, "dialog-token", dialog_token); -- blobmsg_add_u8(&b, "status-code", status_code); -- blobmsg_add_u8(&b, "bss-termination-delay", bss_termination_delay); -- if (target_bssid) -- blobmsg_add_macaddr(&b, "target-bssid", target_bssid); -- -- hostapd_ubus_notify_bss_transition_add_candidate_list(candidate_list, candidate_list_len); -- -- ubus_notify(ctx, &hapd->ubus.obj, "bss-transition-response", b.head, -1); --#endif --} -- --int hostapd_ubus_notify_bss_transition_query( -- struct hostapd_data *hapd, const u8 *addr, u8 dialog_token, u8 reason, -- const u8 *candidate_list, u16 candidate_list_len) --{ --#ifdef CONFIG_WNM_AP -- struct ubus_event_req ureq = {}; -- char *cl_str; -- u16 i; -- -- if (!hapd->ubus.obj.has_subscribers) -- return 0; -- -- if (!addr) -- return 0; -- -- blob_buf_init(&b, 0); -- blobmsg_add_macaddr(&b, "address", addr); -- blobmsg_add_u8(&b, "dialog-token", dialog_token); -- blobmsg_add_u8(&b, "reason", reason); -- hostapd_ubus_notify_bss_transition_add_candidate_list(candidate_list, candidate_list_len); -- -- if (!hapd->ubus.notify_response) { -- ubus_notify(ctx, &hapd->ubus.obj, "bss-transition-query", b.head, -1); -- return 0; -- } -- -- if (ubus_notify_async(ctx, &hapd->ubus.obj, "bss-transition-query", b.head, &ureq.nreq)) -- return 0; -- -- ureq.nreq.status_cb = ubus_event_cb; -- ubus_complete_request(ctx, &ureq.nreq.req, 100); -- -- return ureq.resp; --#endif --} -diff --git a/package/network/services/hostapd/src/src/ap/ubus.h b/package/network/services/hostapd/src/src/ap/ubus.h -deleted file mode 100644 -index b0f7c44ab5..0000000000 ---- a/package/network/services/hostapd/src/src/ap/ubus.h -+++ /dev/null -@@ -1,154 +0,0 @@ --/* -- * hostapd / ubus support -- * Copyright (c) 2013, Felix Fietkau -- * -- * This software may be distributed under the terms of the BSD license. -- * See README for more details. -- */ --#ifndef __HOSTAPD_UBUS_H --#define __HOSTAPD_UBUS_H -- --enum hostapd_ubus_event_type { -- HOSTAPD_UBUS_PROBE_REQ, -- HOSTAPD_UBUS_AUTH_REQ, -- HOSTAPD_UBUS_ASSOC_REQ, -- HOSTAPD_UBUS_TYPE_MAX --}; -- --struct hostapd_ubus_request { -- enum hostapd_ubus_event_type type; -- const struct ieee80211_mgmt *mgmt_frame; -- const struct ieee802_11_elems *elems; -- int ssi_signal; /* dBm */ -- const u8 *addr; --}; -- --struct hostapd_iface; --struct hostapd_data; --struct hapd_interfaces; --struct rrm_measurement_beacon_report; -- --#ifdef UBUS_SUPPORT -- --#include --#include -- --struct hostapd_ubus_bss { -- struct ubus_object obj; -- struct avl_tree banned; -- int notify_response; --}; -- --void hostapd_ubus_add_iface(struct hostapd_iface *iface); --void hostapd_ubus_free_iface(struct hostapd_iface *iface); --void hostapd_ubus_add_bss(struct hostapd_data *hapd); --void hostapd_ubus_free_bss(struct hostapd_data *hapd); --void hostapd_ubus_add_vlan(struct hostapd_data *hapd, struct hostapd_vlan *vlan); --void hostapd_ubus_remove_vlan(struct hostapd_data *hapd, struct hostapd_vlan *vlan); -- --int hostapd_ubus_handle_event(struct hostapd_data *hapd, struct hostapd_ubus_request *req); --void hostapd_ubus_handle_link_measurement(struct hostapd_data *hapd, const u8 *data, size_t len); --void hostapd_ubus_notify(struct hostapd_data *hapd, const char *type, const u8 *mac); --void hostapd_ubus_notify_beacon_report(struct hostapd_data *hapd, -- const u8 *addr, u8 token, u8 rep_mode, -- struct rrm_measurement_beacon_report *rep, -- size_t len); --void hostapd_ubus_notify_radar_detected(struct hostapd_iface *iface, int frequency, -- int chan_width, int cf1, int cf2); -- --void hostapd_ubus_notify_bss_transition_response( -- struct hostapd_data *hapd, const u8 *addr, u8 dialog_token, u8 status_code, -- u8 bss_termination_delay, const u8 *target_bssid, -- const u8 *candidate_list, u16 candidate_list_len); --void hostapd_ubus_add(struct hapd_interfaces *interfaces); --void hostapd_ubus_free(struct hapd_interfaces *interfaces); --int hostapd_ubus_notify_bss_transition_query( -- struct hostapd_data *hapd, const u8 *addr, u8 dialog_token, u8 reason, -- const u8 *candidate_list, u16 candidate_list_len); --void hostapd_ubus_notify_authorized(struct hostapd_data *hapd, struct sta_info *sta, -- const char *auth_alg); -- --#else -- --struct hostapd_ubus_bss {}; -- --static inline void hostapd_ubus_add_iface(struct hostapd_iface *iface) --{ --} -- --static inline void hostapd_ubus_free_iface(struct hostapd_iface *iface) --{ --} -- --static inline void hostapd_ubus_add_bss(struct hostapd_data *hapd) --{ --} -- --static inline void hostapd_ubus_free_bss(struct hostapd_data *hapd) --{ --} -- --static inline void hostapd_ubus_add_vlan(struct hostapd_data *hapd, struct hostapd_vlan *vlan) --{ --} -- --static inline void hostapd_ubus_remove_vlan(struct hostapd_data *hapd, struct hostapd_vlan *vlan) --{ --} -- --static inline int hostapd_ubus_handle_event(struct hostapd_data *hapd, struct hostapd_ubus_request *req) --{ -- return 0; --} -- --static inline void hostapd_ubus_handle_link_measurement(struct hostapd_data *hapd, const u8 *data, size_t len) --{ --} -- --static inline void hostapd_ubus_notify(struct hostapd_data *hapd, const char *type, const u8 *mac) --{ --} -- --static inline void hostapd_ubus_notify_beacon_report(struct hostapd_data *hapd, -- const u8 *addr, u8 token, -- u8 rep_mode, -- struct rrm_measurement_beacon_report *rep, -- size_t len) --{ --} --static inline void hostapd_ubus_notify_radar_detected(struct hostapd_iface *iface, int frequency, -- int chan_width, int cf1, int cf2) --{ --} -- --static inline void hostapd_ubus_notify_bss_transition_response( -- struct hostapd_data *hapd, const u8 *addr, u8 dialog_token, u8 status_code, -- u8 bss_termination_delay, const u8 *target_bssid, -- const u8 *candidate_list, u16 candidate_list_len) --{ --} -- --static inline void hostapd_ubus_add(struct hapd_interfaces *interfaces) --{ --} -- --static inline void hostapd_ubus_free(struct hapd_interfaces *interfaces) --{ --} -- --static inline int hostapd_ubus_notify_bss_transition_query( -- struct hostapd_data *hapd, const u8 *addr, u8 dialog_token, u8 reason, -- const u8 *candidate_list, u16 candidate_list_len) --{ -- return 0; --} -- --static inline void --hostapd_ubus_notify_authorized(struct hostapd_data *hapd, struct sta_info *sta, -- const char *auth_alg) --{ --} -- --#endif -- --#endif -diff --git a/package/network/services/hostapd/src/src/utils/build_features.h b/package/network/services/hostapd/src/src/utils/build_features.h -deleted file mode 100644 -index 553769eceb..0000000000 ---- a/package/network/services/hostapd/src/src/utils/build_features.h -+++ /dev/null -@@ -1,65 +0,0 @@ --#ifndef BUILD_FEATURES_H --#define BUILD_FEATURES_H -- --static inline int has_feature(const char *feat) --{ --#if defined(IEEE8021X_EAPOL) || (defined(HOSTAPD) && !defined(CONFIG_NO_RADIUS)) -- if (!strcmp(feat, "eap")) -- return 1; --#endif --#ifdef CONFIG_IEEE80211AC -- if (!strcmp(feat, "11ac")) -- return 1; --#endif --#ifdef CONFIG_IEEE80211AX -- if (!strcmp(feat, "11ax")) -- return 1; --#endif --#ifdef CONFIG_IEEE80211R -- if (!strcmp(feat, "11r")) -- return 1; --#endif --#ifdef CONFIG_ACS -- if (!strcmp(feat, "acs")) -- return 1; --#endif --#ifdef CONFIG_SAE -- if (!strcmp(feat, "sae")) -- return 1; --#endif --#ifdef CONFIG_OWE -- if (!strcmp(feat, "owe")) -- return 1; --#endif --#ifdef CONFIG_SUITEB192 -- if (!strcmp(feat, "suiteb192")) -- return 1; --#endif --#ifdef CONFIG_WEP -- if (!strcmp(feat, "wep")) -- return 1; --#endif --#ifdef CONFIG_HS20 -- if (!strcmp(feat, "hs20")) -- return 1; --#endif --#ifdef CONFIG_WPS -- if (!strcmp(feat, "wps")) -- return 1; --#endif --#ifdef CONFIG_FILS -- if (!strcmp(feat, "fils")) -- return 1; --#endif --#ifdef CONFIG_OCV -- if (!strcmp(feat, "ocv")) -- return 1; --#endif --#ifdef CONFIG_MESH -- if (!strcmp(feat, "mesh")) -- return 1; --#endif -- return 0; --} -- --#endif /* BUILD_FEATURES_H */ -diff --git a/package/network/services/hostapd/src/wpa_supplicant/ubus.c b/package/network/services/hostapd/src/wpa_supplicant/ubus.c -deleted file mode 100644 -index 16a68c5073..0000000000 ---- a/package/network/services/hostapd/src/wpa_supplicant/ubus.c -+++ /dev/null -@@ -1,430 +0,0 @@ --/* -- * wpa_supplicant / ubus support -- * Copyright (c) 2018, Daniel Golle -- * Copyright (c) 2013, Felix Fietkau -- * -- * This software may be distributed under the terms of the BSD license. -- * See README for more details. -- */ -- --#include "utils/includes.h" --#include "utils/common.h" --#include "utils/eloop.h" --#include "utils/wpabuf.h" --#include "common/ieee802_11_defs.h" --#include "wpa_supplicant_i.h" --#include "wps_supplicant.h" --#include "ubus.h" -- --static struct ubus_context *ctx; --static struct blob_buf b; --static int ctx_ref; -- --static inline struct wpa_global *get_wpa_global_from_object(struct ubus_object *obj) --{ -- return container_of(obj, struct wpa_global, ubus_global); --} -- --static inline struct wpa_supplicant *get_wpas_from_object(struct ubus_object *obj) --{ -- return container_of(obj, struct wpa_supplicant, ubus.obj); --} -- --static void ubus_receive(int sock, void *eloop_ctx, void *sock_ctx) --{ -- struct ubus_context *ctx = eloop_ctx; -- ubus_handle_event(ctx); --} -- --static void ubus_reconnect_timeout(void *eloop_data, void *user_ctx) --{ -- if (ubus_reconnect(ctx, NULL)) { -- eloop_register_timeout(1, 0, ubus_reconnect_timeout, ctx, NULL); -- return; -- } -- -- eloop_register_read_sock(ctx->sock.fd, ubus_receive, ctx, NULL); --} -- --static void wpas_ubus_connection_lost(struct ubus_context *ctx) --{ -- eloop_unregister_read_sock(ctx->sock.fd); -- eloop_register_timeout(1, 0, ubus_reconnect_timeout, ctx, NULL); --} -- --static bool wpas_ubus_init(void) --{ -- if (ctx) -- return true; -- -- ctx = ubus_connect(NULL); -- if (!ctx) -- return false; -- -- ctx->connection_lost = wpas_ubus_connection_lost; -- eloop_register_read_sock(ctx->sock.fd, ubus_receive, ctx, NULL); -- return true; --} -- --static void wpas_ubus_ref_inc(void) --{ -- ctx_ref++; --} -- --static void wpas_ubus_ref_dec(void) --{ -- ctx_ref--; -- if (!ctx) -- return; -- -- if (ctx_ref) -- return; -- -- eloop_unregister_read_sock(ctx->sock.fd); -- ubus_free(ctx); -- ctx = NULL; --} -- --static int --wpas_bss_get_features(struct ubus_context *ctx, struct ubus_object *obj, -- struct ubus_request_data *req, const char *method, -- struct blob_attr *msg) --{ -- struct wpa_supplicant *wpa_s = get_wpas_from_object(obj); -- -- blob_buf_init(&b, 0); -- blobmsg_add_u8(&b, "ht_supported", ht_supported(wpa_s->hw.modes)); -- blobmsg_add_u8(&b, "vht_supported", vht_supported(wpa_s->hw.modes)); -- ubus_send_reply(ctx, req, b.head); -- -- return 0; --} -- --static int --wpas_bss_reload(struct ubus_context *ctx, struct ubus_object *obj, -- struct ubus_request_data *req, const char *method, -- struct blob_attr *msg) --{ -- struct wpa_supplicant *wpa_s = get_wpas_from_object(obj); -- -- if (wpa_supplicant_reload_configuration(wpa_s)) -- return UBUS_STATUS_UNKNOWN_ERROR; -- else -- return 0; --} -- --#ifdef CONFIG_WPS --enum { -- WPS_START_MULTI_AP, -- __WPS_START_MAX --}; -- --static const struct blobmsg_policy wps_start_policy[] = { -- [WPS_START_MULTI_AP] = { "multi_ap", BLOBMSG_TYPE_BOOL }, --}; -- --static int --wpas_bss_wps_start(struct ubus_context *ctx, struct ubus_object *obj, -- struct ubus_request_data *req, const char *method, -- struct blob_attr *msg) --{ -- int rc; -- struct wpa_supplicant *wpa_s = get_wpas_from_object(obj); -- struct blob_attr *tb[__WPS_START_MAX], *cur; -- int multi_ap = 0; -- -- blobmsg_parse(wps_start_policy, __WPS_START_MAX, tb, blobmsg_data(msg), blobmsg_data_len(msg)); -- -- if (tb[WPS_START_MULTI_AP]) -- multi_ap = blobmsg_get_bool(tb[WPS_START_MULTI_AP]); -- -- rc = wpas_wps_start_pbc(wpa_s, NULL, 0, multi_ap); -- -- if (rc != 0) -- return UBUS_STATUS_NOT_SUPPORTED; -- -- return 0; --} -- --static int --wpas_bss_wps_cancel(struct ubus_context *ctx, struct ubus_object *obj, -- struct ubus_request_data *req, const char *method, -- struct blob_attr *msg) --{ -- int rc; -- struct wpa_supplicant *wpa_s = get_wpas_from_object(obj); -- -- rc = wpas_wps_cancel(wpa_s); -- -- if (rc != 0) -- return UBUS_STATUS_NOT_SUPPORTED; -- -- return 0; --} --#endif -- --static const struct ubus_method bss_methods[] = { -- UBUS_METHOD_NOARG("reload", wpas_bss_reload), -- UBUS_METHOD_NOARG("get_features", wpas_bss_get_features), --#ifdef CONFIG_WPS -- UBUS_METHOD_NOARG("wps_start", wpas_bss_wps_start), -- UBUS_METHOD_NOARG("wps_cancel", wpas_bss_wps_cancel), --#endif --}; -- --static struct ubus_object_type bss_object_type = -- UBUS_OBJECT_TYPE("wpas_bss", bss_methods); -- --void wpas_ubus_add_bss(struct wpa_supplicant *wpa_s) --{ -- struct ubus_object *obj = &wpa_s->ubus.obj; -- char *name; -- int ret; -- -- if (!wpas_ubus_init()) -- return; -- -- if (asprintf(&name, "wpa_supplicant.%s", wpa_s->ifname) < 0) -- return; -- -- obj->name = name; -- obj->type = &bss_object_type; -- obj->methods = bss_object_type.methods; -- obj->n_methods = bss_object_type.n_methods; -- ret = ubus_add_object(ctx, obj); -- wpas_ubus_ref_inc(); --} -- --void wpas_ubus_free_bss(struct wpa_supplicant *wpa_s) --{ -- struct ubus_object *obj = &wpa_s->ubus.obj; -- char *name = (char *) obj->name; -- -- if (!ctx) -- return; -- -- if (obj->id) { -- ubus_remove_object(ctx, obj); -- wpas_ubus_ref_dec(); -- } -- -- free(name); --} -- --enum { -- WPAS_CONFIG_DRIVER, -- WPAS_CONFIG_IFACE, -- WPAS_CONFIG_BRIDGE, -- WPAS_CONFIG_HOSTAPD_CTRL, -- WPAS_CONFIG_CTRL, -- WPAS_CONFIG_FILE, -- __WPAS_CONFIG_MAX --}; -- --static const struct blobmsg_policy wpas_config_add_policy[__WPAS_CONFIG_MAX] = { -- [WPAS_CONFIG_DRIVER] = { "driver", BLOBMSG_TYPE_STRING }, -- [WPAS_CONFIG_IFACE] = { "iface", BLOBMSG_TYPE_STRING }, -- [WPAS_CONFIG_BRIDGE] = { "bridge", BLOBMSG_TYPE_STRING }, -- [WPAS_CONFIG_HOSTAPD_CTRL] = { "hostapd_ctrl", BLOBMSG_TYPE_STRING }, -- [WPAS_CONFIG_CTRL] = { "ctrl", BLOBMSG_TYPE_STRING }, -- [WPAS_CONFIG_FILE] = { "config", BLOBMSG_TYPE_STRING }, --}; -- --static int --wpas_config_add(struct ubus_context *ctx, struct ubus_object *obj, -- struct ubus_request_data *req, const char *method, -- struct blob_attr *msg) --{ -- struct blob_attr *tb[__WPAS_CONFIG_MAX]; -- struct wpa_global *global = get_wpa_global_from_object(obj); -- struct wpa_interface *iface; -- -- blobmsg_parse(wpas_config_add_policy, __WPAS_CONFIG_MAX, tb, blob_data(msg), blob_len(msg)); -- -- if (!tb[WPAS_CONFIG_FILE] || !tb[WPAS_CONFIG_IFACE] || !tb[WPAS_CONFIG_DRIVER]) -- return UBUS_STATUS_INVALID_ARGUMENT; -- -- iface = os_zalloc(sizeof(struct wpa_interface)); -- if (iface == NULL) -- return UBUS_STATUS_UNKNOWN_ERROR; -- -- iface->driver = blobmsg_get_string(tb[WPAS_CONFIG_DRIVER]); -- iface->ifname = blobmsg_get_string(tb[WPAS_CONFIG_IFACE]); -- iface->confname = blobmsg_get_string(tb[WPAS_CONFIG_FILE]); -- -- if (tb[WPAS_CONFIG_BRIDGE]) -- iface->bridge_ifname = blobmsg_get_string(tb[WPAS_CONFIG_BRIDGE]); -- -- if (tb[WPAS_CONFIG_CTRL]) -- iface->ctrl_interface = blobmsg_get_string(tb[WPAS_CONFIG_CTRL]); -- -- if (tb[WPAS_CONFIG_HOSTAPD_CTRL]) -- iface->hostapd_ctrl = blobmsg_get_string(tb[WPAS_CONFIG_HOSTAPD_CTRL]); -- -- if (!wpa_supplicant_add_iface(global, iface, NULL)) -- return UBUS_STATUS_INVALID_ARGUMENT; -- -- blob_buf_init(&b, 0); -- blobmsg_add_u32(&b, "pid", getpid()); -- ubus_send_reply(ctx, req, b.head); -- -- return UBUS_STATUS_OK; --} -- --enum { -- WPAS_CONFIG_REM_IFACE, -- __WPAS_CONFIG_REM_MAX --}; -- --static const struct blobmsg_policy wpas_config_remove_policy[__WPAS_CONFIG_REM_MAX] = { -- [WPAS_CONFIG_REM_IFACE] = { "iface", BLOBMSG_TYPE_STRING }, --}; -- --static int --wpas_config_remove(struct ubus_context *ctx, struct ubus_object *obj, -- struct ubus_request_data *req, const char *method, -- struct blob_attr *msg) --{ -- struct blob_attr *tb[__WPAS_CONFIG_REM_MAX]; -- struct wpa_global *global = get_wpa_global_from_object(obj); -- struct wpa_supplicant *wpa_s = NULL; -- unsigned int found = 0; -- -- blobmsg_parse(wpas_config_remove_policy, __WPAS_CONFIG_REM_MAX, tb, blob_data(msg), blob_len(msg)); -- -- if (!tb[WPAS_CONFIG_REM_IFACE]) -- return UBUS_STATUS_INVALID_ARGUMENT; -- -- /* find wpa_s object for to-be-removed interface */ -- for (wpa_s = global->ifaces; wpa_s; wpa_s = wpa_s->next) { -- if (!strncmp(wpa_s->ifname, -- blobmsg_get_string(tb[WPAS_CONFIG_REM_IFACE]), -- sizeof(wpa_s->ifname))) -- { -- found = 1; -- break; -- } -- } -- -- if (!found) -- return UBUS_STATUS_INVALID_ARGUMENT; -- -- if (wpa_supplicant_remove_iface(global, wpa_s, 0)) -- return UBUS_STATUS_INVALID_ARGUMENT; -- -- return UBUS_STATUS_OK; --} -- --static const struct ubus_method wpas_daemon_methods[] = { -- UBUS_METHOD("config_add", wpas_config_add, wpas_config_add_policy), -- UBUS_METHOD("config_remove", wpas_config_remove, wpas_config_remove_policy), --}; -- --static struct ubus_object_type wpas_daemon_object_type = -- UBUS_OBJECT_TYPE("wpa_supplicant", wpas_daemon_methods); -- --void wpas_ubus_add(struct wpa_global *global) --{ -- struct ubus_object *obj = &global->ubus_global; -- int ret; -- -- if (!wpas_ubus_init()) -- return; -- -- obj->name = strdup("wpa_supplicant"); -- -- obj->type = &wpas_daemon_object_type; -- obj->methods = wpas_daemon_object_type.methods; -- obj->n_methods = wpas_daemon_object_type.n_methods; -- ret = ubus_add_object(ctx, obj); -- wpas_ubus_ref_inc(); --} -- --void wpas_ubus_free(struct wpa_global *global) --{ -- struct ubus_object *obj = &global->ubus_global; -- char *name = (char *) obj->name; -- -- if (!ctx) -- return; -- -- if (obj->id) { -- ubus_remove_object(ctx, obj); -- wpas_ubus_ref_dec(); -- } -- -- free(name); --} -- -- --#ifdef CONFIG_WPS --void wpas_ubus_notify(struct wpa_supplicant *wpa_s, const struct wps_credential *cred) --{ -- u16 auth_type; -- char *ifname, *encryption, *ssid, *key; -- size_t ifname_len; -- -- if (!cred) -- return; -- -- auth_type = cred->auth_type; -- -- if (auth_type == (WPS_AUTH_WPAPSK | WPS_AUTH_WPA2PSK)) -- auth_type = WPS_AUTH_WPA2PSK; -- -- if (auth_type != WPS_AUTH_OPEN && -- auth_type != WPS_AUTH_WPAPSK && -- auth_type != WPS_AUTH_WPA2PSK) { -- wpa_printf(MSG_DEBUG, "WPS: Ignored credentials for " -- "unsupported authentication type 0x%x", -- auth_type); -- return; -- } -- -- if (auth_type == WPS_AUTH_WPAPSK || auth_type == WPS_AUTH_WPA2PSK) { -- if (cred->key_len < 8 || cred->key_len > 2 * PMK_LEN) { -- wpa_printf(MSG_ERROR, "WPS: Reject PSK credential with " -- "invalid Network Key length %lu", -- (unsigned long) cred->key_len); -- return; -- } -- } -- -- blob_buf_init(&b, 0); -- -- ifname_len = strlen(wpa_s->ifname); -- ifname = blobmsg_alloc_string_buffer(&b, "ifname", ifname_len + 1); -- memcpy(ifname, wpa_s->ifname, ifname_len + 1); -- ifname[ifname_len] = '\0'; -- blobmsg_add_string_buffer(&b); -- -- switch (auth_type) { -- case WPS_AUTH_WPA2PSK: -- encryption = "psk2"; -- break; -- case WPS_AUTH_WPAPSK: -- encryption = "psk"; -- break; -- default: -- encryption = "none"; -- break; -- } -- -- blobmsg_add_string(&b, "encryption", encryption); -- -- ssid = blobmsg_alloc_string_buffer(&b, "ssid", cred->ssid_len + 1); -- memcpy(ssid, cred->ssid, cred->ssid_len); -- ssid[cred->ssid_len] = '\0'; -- blobmsg_add_string_buffer(&b); -- -- if (cred->key_len > 0) { -- key = blobmsg_alloc_string_buffer(&b, "key", cred->key_len + 1); -- memcpy(key, cred->key, cred->key_len); -- key[cred->key_len] = '\0'; -- blobmsg_add_string_buffer(&b); -- } -- --// ubus_notify(ctx, &wpa_s->ubus.obj, "wps_credentials", b.head, -1); -- ubus_send_event(ctx, "wps_credentials", b.head); --} --#endif /* CONFIG_WPS */ -diff --git a/package/network/services/hostapd/src/wpa_supplicant/ubus.h b/package/network/services/hostapd/src/wpa_supplicant/ubus.h -deleted file mode 100644 -index bf92b98c01..0000000000 ---- a/package/network/services/hostapd/src/wpa_supplicant/ubus.h -+++ /dev/null -@@ -1,66 +0,0 @@ --/* -- * wpa_supplicant / ubus support -- * Copyright (c) 2018, Daniel Golle -- * Copyright (c) 2013, Felix Fietkau -- * -- * This software may be distributed under the terms of the BSD license. -- * See README for more details. -- */ --#ifndef __WPAS_UBUS_H --#define __WPAS_UBUS_H -- --struct wpa_supplicant; --struct wpa_global; -- --#include "wps_supplicant.h" -- --#ifdef UBUS_SUPPORT --#include -- --struct wpas_ubus_bss { -- struct ubus_object obj; --}; -- --void wpas_ubus_add_bss(struct wpa_supplicant *wpa_s); --void wpas_ubus_free_bss(struct wpa_supplicant *wpa_s); -- --void wpas_ubus_add(struct wpa_global *global); --void wpas_ubus_free(struct wpa_global *global); -- --#ifdef CONFIG_WPS --void wpas_ubus_notify(struct wpa_supplicant *wpa_s, const struct wps_credential *cred); --#endif -- --#else --struct wpas_ubus_bss {}; -- --static inline void wpas_ubus_add_iface(struct wpa_supplicant *wpa_s) --{ --} -- --static inline void wpas_ubus_free_iface(struct wpa_supplicant *wpa_s) --{ --} -- --static inline void wpas_ubus_add_bss(struct wpa_supplicant *wpa_s) --{ --} -- --static inline void wpas_ubus_free_bss(struct wpa_supplicant *wpa_s) --{ --} -- --static inline void wpas_ubus_notify(struct wpa_supplicant *wpa_s, struct wps_credential *cred) --{ --} -- --static inline void wpas_ubus_add(struct wpa_global *global) --{ --} -- --static inline void wpas_ubus_free(struct wpa_global *global) --{ --} --#endif -- --#endif -- 2.34.1 diff --git a/patches/0049-hostapd-add-upstream-version.patch b/patches/0049-hostapd-add-upstream-version.patch deleted file mode 100644 index d3f162b9d..000000000 --- a/patches/0049-hostapd-add-upstream-version.patch +++ /dev/null @@ -1,26625 +0,0 @@ -From 8a37e576b5f0a3171e6f17b3df395cad33a0be07 Mon Sep 17 00:00:00 2001 -From: John Crispin -Date: Thu, 17 Aug 2023 15:54:00 +0200 -Subject: [PATCH 49/52] hostapd: add upstream version - -Signed-off-by: John Crispin ---- - package/network/services/hostapd/Config.in | 108 + - package/network/services/hostapd/Makefile | 858 ++ - package/network/services/hostapd/README.md | 419 + - .../network/services/hostapd/files/common.uc | 168 + - .../services/hostapd/files/dhcp-get-server.sh | 2 + - .../hostapd/files/hostapd-basic.config | 404 + - .../hostapd/files/hostapd-full.config | 404 + - .../hostapd/files/hostapd-mini.config | 404 + - .../network/services/hostapd/files/hostapd.sh | 1593 ++++ - .../network/services/hostapd/files/hostapd.uc | 486 + - .../services/hostapd/files/multicall.c | 28 + - .../services/hostapd/files/radius.clients | 1 + - .../services/hostapd/files/radius.config | 9 + - .../services/hostapd/files/radius.init | 42 + - .../services/hostapd/files/radius.users | 14 + - .../network/services/hostapd/files/wdev.uc | 156 + - .../hostapd/files/wpa_supplicant-basic.config | 625 ++ - .../hostapd/files/wpa_supplicant-full.config | 625 ++ - .../hostapd/files/wpa_supplicant-mini.config | 625 ++ - .../hostapd/files/wpa_supplicant-p2p.config | 625 ++ - .../services/hostapd/files/wpa_supplicant.uc | 253 + - .../network/services/hostapd/files/wpad.init | 43 + - .../network/services/hostapd/files/wpad.json | 22 + - .../services/hostapd/files/wpad_acl.json | 10 + - .../services/hostapd/files/wps-hotplug.sh | 69 + - .../001-wolfssl-init-RNG-with-ECC-key.patch | 43 + - ...hannels-to-be-selected-if-dfs-is-ena.patch | 135 + - ...erministic-channel-on-channel-switch.patch | 81 + - ...ix-sta-add-after-previous-connection.patch | 26 + - ...use-of-uninitialized-stack-variables.patch | 25 + - ...-dl_list_del-before-freeing-ipv6-add.patch | 19 + - ...ewrite-neigh-code-to-not-depend-on-l.patch | 275 + - ...ssing-authentication-frames-in-block.patch | 34 + - .../hostapd/patches/050-build_fix.patch | 20 + - .../hostapd/patches/100-daemonize_fix.patch | 97 + - ...edtls-TLS-crypto-option-initial-port.patch | 8051 +++++++++++++++++ - .../patches/120-mbedtls-fips186_2_prf.patch | 114 + - ...otate-with-TEST_FAIL-for-hwsim-tests.patch | 421 + - ...efile-make-run-tests-with-CONFIG_TLS.patch | 1358 +++ - ...hecks-encountered-during-tests-hwsim.patch | 45 + - ...-dpp_pkex-EC-point-mul-w-value-prime.patch | 26 + - ...tapd-update-cfs0-and-cfs1-for-160MHz.patch | 141 + - ...S-coloring-fix-CCA-with-multiple-BSS.patch | 103 + - .../hostapd/patches/200-multicall.patch | 355 + - .../services/hostapd/patches/300-noscan.patch | 58 + - .../hostapd/patches/301-mesh-noscan.patch | 71 + - .../patches/310-rescan_immediately.patch | 11 + - .../hostapd/patches/320-optional_rfkill.patch | 61 + - .../patches/330-nl80211_fix_set_freq.patch | 11 + - .../341-mesh-ctrl-iface-channel-switch.patch | 39 + - .../patches/350-nl80211_del_beacon_bss.patch | 35 + - .../patches/380-disable_ctrl_iface_mib.patch | 239 + - .../381-hostapd_cli_UNKNOWN-COMMAND.patch | 11 + - .../patches/390-wpa_ie_cap_workaround.patch | 56 + - .../400-wps_single_auth_enc_type.patch | 23 + - .../patches/410-limit_debug_messages.patch | 210 + - .../patches/420-indicate-features.patch | 63 + - .../patches/430-hostapd_cli_ifdef.patch | 56 + - .../hostapd/patches/431-wpa_cli_ifdef.patch | 18 + - ...dd-new-config-params-to-be-used-with.patch | 189 + - .../patches/463-add-mcast_rate-to-11s.patch | 68 + - .../patches/464-fix-mesh-obss-check.patch | 13 + - ...tapd-config-support-random-BSS-color.patch | 24 + - .../patches/470-survey_data_fallback.patch | 30 + - .../patches/500-lto-jobserver-support.patch | 59 + - .../patches/590-rrm-wnm-statistics.patch | 92 + - .../599-wpa_supplicant-fix-warnings.patch | 19 + - .../hostapd/patches/600-ubus_support.patch | 748 ++ - .../hostapd/patches/601-ucode_support.patch | 333 + - .../610-hostapd_cli_ujail_permission.patch | 33 + - .../patches/701-reload_config_inline.patch | 33 + - .../hostapd/patches/710-vlan_no_bridge.patch | 41 + - .../patches/711-wds_bridge_force.patch | 22 + - .../patches/720-iface_max_num_sta.patch | 81 + - .../hostapd/patches/730-ft_iface.patch | 38 + - .../hostapd/patches/740-snoop_iface.patch | 66 + - ...750-qos_map_set_without_interworking.patch | 97 + - .../751-qos_map_ignore_when_unsupported.patch | 12 + - .../hostapd/patches/760-dynamic_own_ip.patch | 109 + - .../hostapd/patches/761-shared_das_port.patch | 298 + - .../hostapd/patches/770-radius_server.patch | 154 + - ..._AP-functions-dependant-on-CONFIG_AP.patch | 33 + - .../services/hostapd/src/hostapd/radius.c | 715 ++ - .../services/hostapd/src/src/ap/ubus.c | 2002 ++++ - .../services/hostapd/src/src/ap/ubus.h | 154 + - .../services/hostapd/src/src/ap/ucode.c | 545 ++ - .../services/hostapd/src/src/ap/ucode.h | 54 + - .../hostapd/src/src/utils/build_features.h | 65 + - .../services/hostapd/src/src/utils/ucode.c | 326 + - .../services/hostapd/src/src/utils/ucode.h | 29 + - .../hostapd/src/wpa_supplicant/ubus.c | 280 + - .../hostapd/src/wpa_supplicant/ubus.h | 55 + - .../hostapd/src/wpa_supplicant/ucode.c | 270 + - .../hostapd/src/wpa_supplicant/ucode.h | 49 + - 94 files changed, 27460 insertions(+) - create mode 100644 package/network/services/hostapd/Config.in - create mode 100644 package/network/services/hostapd/Makefile - create mode 100644 package/network/services/hostapd/README.md - create mode 100644 package/network/services/hostapd/files/common.uc - create mode 100644 package/network/services/hostapd/files/dhcp-get-server.sh - create mode 100644 package/network/services/hostapd/files/hostapd-basic.config - create mode 100644 package/network/services/hostapd/files/hostapd-full.config - create mode 100644 package/network/services/hostapd/files/hostapd-mini.config - create mode 100644 package/network/services/hostapd/files/hostapd.sh - create mode 100644 package/network/services/hostapd/files/hostapd.uc - create mode 100644 package/network/services/hostapd/files/multicall.c - create mode 100644 package/network/services/hostapd/files/radius.clients - create mode 100644 package/network/services/hostapd/files/radius.config - create mode 100644 package/network/services/hostapd/files/radius.init - create mode 100644 package/network/services/hostapd/files/radius.users - create mode 100644 package/network/services/hostapd/files/wdev.uc - create mode 100644 package/network/services/hostapd/files/wpa_supplicant-basic.config - create mode 100644 package/network/services/hostapd/files/wpa_supplicant-full.config - create mode 100644 package/network/services/hostapd/files/wpa_supplicant-mini.config - create mode 100644 package/network/services/hostapd/files/wpa_supplicant-p2p.config - create mode 100644 package/network/services/hostapd/files/wpa_supplicant.uc - create mode 100644 package/network/services/hostapd/files/wpad.init - create mode 100644 package/network/services/hostapd/files/wpad.json - create mode 100644 package/network/services/hostapd/files/wpad_acl.json - create mode 100644 package/network/services/hostapd/files/wps-hotplug.sh - create mode 100644 package/network/services/hostapd/patches/001-wolfssl-init-RNG-with-ECC-key.patch - create mode 100644 package/network/services/hostapd/patches/010-mesh-Allow-DFS-channels-to-be-selected-if-dfs-is-ena.patch - create mode 100644 package/network/services/hostapd/patches/011-mesh-use-deterministic-channel-on-channel-switch.patch - create mode 100644 package/network/services/hostapd/patches/021-fix-sta-add-after-previous-connection.patch - create mode 100644 package/network/services/hostapd/patches/022-hostapd-fix-use-of-uninitialized-stack-variables.patch - create mode 100644 package/network/services/hostapd/patches/023-ndisc_snoop-call-dl_list_del-before-freeing-ipv6-add.patch - create mode 100644 package/network/services/hostapd/patches/030-driver_nl80211-rewrite-neigh-code-to-not-depend-on-l.patch - create mode 100644 package/network/services/hostapd/patches/040-mesh-allow-processing-authentication-frames-in-block.patch - create mode 100644 package/network/services/hostapd/patches/050-build_fix.patch - create mode 100644 package/network/services/hostapd/patches/100-daemonize_fix.patch - create mode 100644 package/network/services/hostapd/patches/110-mbedtls-TLS-crypto-option-initial-port.patch - create mode 100644 package/network/services/hostapd/patches/120-mbedtls-fips186_2_prf.patch - create mode 100644 package/network/services/hostapd/patches/130-mbedtls-annotate-with-TEST_FAIL-for-hwsim-tests.patch - create mode 100644 package/network/services/hostapd/patches/140-tests-Makefile-make-run-tests-with-CONFIG_TLS.patch - create mode 100644 package/network/services/hostapd/patches/150-add-NULL-checks-encountered-during-tests-hwsim.patch - create mode 100644 package/network/services/hostapd/patches/160-dpp_pkex-EC-point-mul-w-value-prime.patch - create mode 100644 package/network/services/hostapd/patches/170-hostapd-update-cfs0-and-cfs1-for-160MHz.patch - create mode 100644 package/network/services/hostapd/patches/180-BSS-coloring-fix-CCA-with-multiple-BSS.patch - create mode 100644 package/network/services/hostapd/patches/200-multicall.patch - create mode 100644 package/network/services/hostapd/patches/300-noscan.patch - create mode 100644 package/network/services/hostapd/patches/301-mesh-noscan.patch - create mode 100644 package/network/services/hostapd/patches/310-rescan_immediately.patch - create mode 100644 package/network/services/hostapd/patches/320-optional_rfkill.patch - create mode 100644 package/network/services/hostapd/patches/330-nl80211_fix_set_freq.patch - create mode 100644 package/network/services/hostapd/patches/341-mesh-ctrl-iface-channel-switch.patch - create mode 100644 package/network/services/hostapd/patches/350-nl80211_del_beacon_bss.patch - create mode 100644 package/network/services/hostapd/patches/380-disable_ctrl_iface_mib.patch - create mode 100644 package/network/services/hostapd/patches/381-hostapd_cli_UNKNOWN-COMMAND.patch - create mode 100644 package/network/services/hostapd/patches/390-wpa_ie_cap_workaround.patch - create mode 100644 package/network/services/hostapd/patches/400-wps_single_auth_enc_type.patch - create mode 100644 package/network/services/hostapd/patches/410-limit_debug_messages.patch - create mode 100644 package/network/services/hostapd/patches/420-indicate-features.patch - create mode 100644 package/network/services/hostapd/patches/430-hostapd_cli_ifdef.patch - create mode 100644 package/network/services/hostapd/patches/431-wpa_cli_ifdef.patch - create mode 100644 package/network/services/hostapd/patches/460-wpa_supplicant-add-new-config-params-to-be-used-with.patch - create mode 100644 package/network/services/hostapd/patches/463-add-mcast_rate-to-11s.patch - create mode 100644 package/network/services/hostapd/patches/464-fix-mesh-obss-check.patch - create mode 100644 package/network/services/hostapd/patches/465-hostapd-config-support-random-BSS-color.patch - create mode 100644 package/network/services/hostapd/patches/470-survey_data_fallback.patch - create mode 100644 package/network/services/hostapd/patches/500-lto-jobserver-support.patch - create mode 100644 package/network/services/hostapd/patches/590-rrm-wnm-statistics.patch - create mode 100644 package/network/services/hostapd/patches/599-wpa_supplicant-fix-warnings.patch - create mode 100644 package/network/services/hostapd/patches/600-ubus_support.patch - create mode 100644 package/network/services/hostapd/patches/601-ucode_support.patch - create mode 100644 package/network/services/hostapd/patches/610-hostapd_cli_ujail_permission.patch - create mode 100644 package/network/services/hostapd/patches/701-reload_config_inline.patch - create mode 100644 package/network/services/hostapd/patches/710-vlan_no_bridge.patch - create mode 100644 package/network/services/hostapd/patches/711-wds_bridge_force.patch - create mode 100644 package/network/services/hostapd/patches/720-iface_max_num_sta.patch - create mode 100644 package/network/services/hostapd/patches/730-ft_iface.patch - create mode 100644 package/network/services/hostapd/patches/740-snoop_iface.patch - create mode 100644 package/network/services/hostapd/patches/750-qos_map_set_without_interworking.patch - create mode 100644 package/network/services/hostapd/patches/751-qos_map_ignore_when_unsupported.patch - create mode 100644 package/network/services/hostapd/patches/760-dynamic_own_ip.patch - create mode 100644 package/network/services/hostapd/patches/761-shared_das_port.patch - create mode 100644 package/network/services/hostapd/patches/770-radius_server.patch - create mode 100644 package/network/services/hostapd/patches/990-ctrl-make-WNM_AP-functions-dependant-on-CONFIG_AP.patch - create mode 100644 package/network/services/hostapd/src/hostapd/radius.c - create mode 100644 package/network/services/hostapd/src/src/ap/ubus.c - create mode 100644 package/network/services/hostapd/src/src/ap/ubus.h - create mode 100644 package/network/services/hostapd/src/src/ap/ucode.c - create mode 100644 package/network/services/hostapd/src/src/ap/ucode.h - create mode 100644 package/network/services/hostapd/src/src/utils/build_features.h - create mode 100644 package/network/services/hostapd/src/src/utils/ucode.c - create mode 100644 package/network/services/hostapd/src/src/utils/ucode.h - create mode 100644 package/network/services/hostapd/src/wpa_supplicant/ubus.c - create mode 100644 package/network/services/hostapd/src/wpa_supplicant/ubus.h - create mode 100644 package/network/services/hostapd/src/wpa_supplicant/ucode.c - create mode 100644 package/network/services/hostapd/src/wpa_supplicant/ucode.h - -diff --git a/package/network/services/hostapd/Config.in b/package/network/services/hostapd/Config.in -new file mode 100644 -index 0000000000..87ad7e093e ---- /dev/null -+++ b/package/network/services/hostapd/Config.in -@@ -0,0 +1,108 @@ -+# wpa_supplicant config -+config WPA_RFKILL_SUPPORT -+ bool "Add rfkill support" -+ depends on PACKAGE_wpa-supplicant || \ -+ PACKAGE_wpa-supplicant-openssl || \ -+ PACKAGE_wpa-supplicant-wolfssl || \ -+ PACKAGE_wpa-supplicant-mbedtls || \ -+ PACKAGE_wpa-supplicant-mesh-openssl || \ -+ PACKAGE_wpa-supplicant-mesh-wolfssl || \ -+ PACKAGE_wpa-supplicant-mesh-mbedtls || \ -+ PACKAGE_wpa-supplicant-basic || \ -+ PACKAGE_wpa-supplicant-mini || \ -+ PACKAGE_wpa-supplicant-p2p || \ -+ PACKAGE_wpad || \ -+ PACKAGE_wpad-openssl || \ -+ PACKAGE_wpad-wolfssl || \ -+ PACKAGE_wpad-mbedtls || \ -+ PACKAGE_wpad-basic || \ -+ PACKAGE_wpad-basic-openssl || \ -+ PACKAGE_wpad-basic-wolfssl || \ -+ PACKAGE_wpad-basic-mbedtls || \ -+ PACKAGE_wpad-mini || \ -+ PACKAGE_wpad-mesh-openssl || \ -+ PACKAGE_wpad-mesh-wolfssl || \ -+ PACKAGE_wpad-mesh-mbedtls -+ default n -+ -+config WPA_MSG_MIN_PRIORITY -+ int "Minimum debug message priority" -+ depends on PACKAGE_wpa-supplicant || \ -+ PACKAGE_wpa-supplicant-openssl || \ -+ PACKAGE_wpa-supplicant-wolfssl || \ -+ PACKAGE_wpa-supplicant-mbedtls || \ -+ PACKAGE_wpa-supplicant-mesh-openssl || \ -+ PACKAGE_wpa-supplicant-mesh-wolfssl || \ -+ PACKAGE_wpa-supplicant-mesh-mbedtls || \ -+ PACKAGE_wpa-supplicant-basic || \ -+ PACKAGE_wpa-supplicant-mini || \ -+ PACKAGE_wpa-supplicant-p2p || \ -+ PACKAGE_wpad || \ -+ PACKAGE_wpad-openssl || \ -+ PACKAGE_wpad-wolfssl || \ -+ PACKAGE_wpad-mbedtls || \ -+ PACKAGE_wpad-basic || \ -+ PACKAGE_wpad-basic-openssl || \ -+ PACKAGE_wpad-basic-wolfssl || \ -+ PACKAGE_wpad-basic-mbedtls || \ -+ PACKAGE_wpad-mini || \ -+ PACKAGE_wpad-mesh-openssl || \ -+ PACKAGE_wpad-mesh-wolfssl || \ -+ PACKAGE_wpad-mesh-mbedtls -+ default 3 -+ help -+ Useful values are: -+ 0 = all messages -+ 1 = raw message dumps -+ 2 = most debugging messages -+ 3 = info messages -+ 4 = warnings -+ 5 = errors -+ -+config WPA_WOLFSSL -+ bool -+ default PACKAGE_wpa-supplicant-wolfssl ||\ -+ PACKAGE_wpad-wolfssl ||\ -+ PACKAGE_wpad-basic-wolfssl || \ -+ PACKAGE_wpad-mesh-wolfssl ||\ -+ PACKAGE_eapol-test-wolfssl -+ select WOLFSSL_HAS_AES_CCM -+ select WOLFSSL_HAS_ARC4 -+ select WOLFSSL_HAS_DH -+ select WOLFSSL_HAS_OCSP -+ select WOLFSSL_HAS_SESSION_TICKET -+ select WOLFSSL_HAS_WPAS -+ -+config DRIVER_11AC_SUPPORT -+ bool -+ default n -+ -+config DRIVER_11AX_SUPPORT -+ bool -+ default n -+ select WPA_MBO_SUPPORT -+ -+config WPA_ENABLE_WEP -+ bool "Enable support for unsecure and obsolete WEP" -+ help -+ Wired equivalent privacy (WEP) is an obsolete cryptographic data -+ confidentiality algorithm that is not considered secure. It should not be used -+ for anything anymore. The functionality needed to use WEP is available in the -+ current hostapd release under this optional build parameter and completely -+ removed in a future release. -+ -+config WPA_MBO_SUPPORT -+ bool "Multi Band Operation (Agile Multiband)" -+ default PACKAGE_wpa-supplicant || \ -+ PACKAGE_wpa-supplicant-openssl || \ -+ PACKAGE_wpa-supplicant-wolfssl || \ -+ PACKAGE_wpa-supplicant-mbedtls || \ -+ PACKAGE_wpad || \ -+ PACKAGE_wpad-openssl || \ -+ PACKAGE_wpad-wolfssl || \ -+ PACKAGE_wpad-mbedtls -+ help -+ Multi Band Operation aka (Agile Multiband) enables features -+ that facilitate efficient use of multiple frequency bands. -+ Enabling MBO on an AP using RSN requires 802.11w to be enabled. -+ Hostapd will refuse to start if MBO and RSN are enabled without 11w. -diff --git a/package/network/services/hostapd/Makefile b/package/network/services/hostapd/Makefile -new file mode 100644 -index 0000000000..178dd20fcd ---- /dev/null -+++ b/package/network/services/hostapd/Makefile -@@ -0,0 +1,858 @@ -+# SPDX-License-Identifier: GPL-2.0-only -+# -+# Copyright (C) 2006-2021 OpenWrt.org -+ -+include $(TOPDIR)/rules.mk -+ -+PKG_NAME:=hostapd -+PKG_RELEASE:=2 -+ -+PKG_SOURCE_URL:=http://w1.fi/hostap.git -+PKG_SOURCE_PROTO:=git -+PKG_SOURCE_DATE:=2023-06-22 -+PKG_SOURCE_VERSION:=599d00be9de2846c6ea18c1487d8329522ade22b -+PKG_MIRROR_HASH:=828810c558ea181e45ed0c8b940f5c41e55775e2979a15aed8cf0ab17dd7723c -+ -+PKG_MAINTAINER:=Felix Fietkau -+PKG_LICENSE:=BSD-3-Clause -+PKG_CPE_ID:=cpe:/a:w1.fi:hostapd -+ -+PKG_BUILD_PARALLEL:=1 -+PKG_ASLR_PIE_REGULAR:=1 -+ -+PKG_CONFIG_DEPENDS:= \ -+ CONFIG_PACKAGE_kmod-ath9k \ -+ CONFIG_PACKAGE_kmod-cfg80211 \ -+ CONFIG_PACKAGE_hostapd \ -+ CONFIG_PACKAGE_hostapd-basic \ -+ CONFIG_PACKAGE_hostapd-mini \ -+ CONFIG_WPA_RFKILL_SUPPORT \ -+ CONFIG_DRIVER_11AC_SUPPORT \ -+ CONFIG_DRIVER_11AX_SUPPORT \ -+ CONFIG_WPA_ENABLE_WEP -+ -+PKG_BUILD_FLAGS:=gc-sections lto -+ -+EAPOL_TEST_PROVIDERS:=eapol-test eapol-test-openssl eapol-test-wolfssl -+ -+SUPPLICANT_PROVIDERS:= -+HOSTAPD_PROVIDERS:= -+ -+LOCAL_TYPE=$(strip \ -+ $(if $(findstring wpad,$(BUILD_VARIANT)),wpad, \ -+ $(if $(findstring supplicant,$(BUILD_VARIANT)),supplicant, \ -+ hostapd \ -+ ))) -+ -+LOCAL_AND_LIB_VARIANT=$(patsubst hostapd-%,%,\ -+ $(patsubst wpad-%,%,\ -+ $(patsubst supplicant-%,%,\ -+ $(BUILD_VARIANT)\ -+ ))) -+ -+LOCAL_VARIANT=$(patsubst %-internal,%,\ -+ $(patsubst %-openssl,%,\ -+ $(patsubst %-wolfssl,%,\ -+ $(patsubst %-mbedtls,%,\ -+ $(LOCAL_AND_LIB_VARIANT)\ -+ )))) -+ -+SSL_VARIANT=$(strip \ -+ $(if $(findstring openssl,$(LOCAL_AND_LIB_VARIANT)),openssl,\ -+ $(if $(findstring wolfssl,$(LOCAL_AND_LIB_VARIANT)),wolfssl,\ -+ $(if $(findstring mbedtls,$(LOCAL_AND_LIB_VARIANT)),mbedtls,\ -+ internal\ -+ )))) -+ -+CONFIG_VARIANT:=$(LOCAL_VARIANT) -+ifeq ($(LOCAL_VARIANT),mesh) -+ CONFIG_VARIANT:=full -+endif -+ -+include $(INCLUDE_DIR)/package.mk -+ -+STAMP_CONFIGURED:=$(STAMP_CONFIGURED)_$(CONFIG_WPA_MSG_MIN_PRIORITY) -+ -+ifneq ($(CONFIG_DRIVER_11AC_SUPPORT),) -+ HOSTAPD_IEEE80211AC:=y -+endif -+ -+ifneq ($(CONFIG_DRIVER_11AX_SUPPORT),) -+ HOSTAPD_IEEE80211AX:=y -+endif -+ -+CORE_DEPENDS = +ucode +libubus +libucode +ucode-mod-fs +ucode-mod-nl80211 +ucode-mod-rtnl +ucode-mod-ubus +ucode-mod-uloop +libblobmsg-json -+ -+DRIVER_MAKEOPTS= \ -+ CONFIG_ACS=$(CONFIG_PACKAGE_kmod-cfg80211) \ -+ CONFIG_DRIVER_NL80211=$(CONFIG_PACKAGE_kmod-cfg80211) \ -+ CONFIG_IEEE80211AC=$(HOSTAPD_IEEE80211AC) \ -+ CONFIG_IEEE80211AX=$(HOSTAPD_IEEE80211AX) \ -+ CONFIG_MBO=$(CONFIG_WPA_MBO_SUPPORT) \ -+ CONFIG_UCODE=y -+ -+ifeq ($(SSL_VARIANT),openssl) -+ DRIVER_MAKEOPTS += CONFIG_TLS=openssl CONFIG_SAE=y -+ TARGET_LDFLAGS += -lcrypto -lssl -+ -+ ifeq ($(LOCAL_VARIANT),basic) -+ DRIVER_MAKEOPTS += CONFIG_OWE=y -+ endif -+ ifeq ($(LOCAL_VARIANT),mesh) -+ DRIVER_MAKEOPTS += CONFIG_AP=y CONFIG_MESH=y -+ endif -+ ifeq ($(LOCAL_VARIANT),full) -+ DRIVER_MAKEOPTS += CONFIG_OWE=y CONFIG_SUITEB192=y CONFIG_AP=y CONFIG_MESH=y -+ endif -+endif -+ -+ifeq ($(SSL_VARIANT),wolfssl) -+ DRIVER_MAKEOPTS += CONFIG_TLS=wolfssl CONFIG_SAE=y -+ TARGET_LDFLAGS += -lwolfssl -+ -+ ifeq ($(LOCAL_VARIANT),basic) -+ DRIVER_MAKEOPTS += CONFIG_OWE=y -+ endif -+ ifeq ($(LOCAL_VARIANT),mesh) -+ DRIVER_MAKEOPTS += CONFIG_AP=y CONFIG_MESH=y CONFIG_WPS_NFC=1 -+ endif -+ ifeq ($(LOCAL_VARIANT),full) -+ DRIVER_MAKEOPTS += CONFIG_OWE=y CONFIG_SUITEB192=y CONFIG_AP=y CONFIG_MESH=y CONFIG_WPS_NFC=1 -+ endif -+endif -+ -+ifeq ($(SSL_VARIANT),mbedtls) -+ DRIVER_MAKEOPTS += CONFIG_TLS=mbedtls CONFIG_SAE=y -+ TARGET_LDFLAGS += -lmbedcrypto -lmbedx509 -lmbedtls -+ -+ ifeq ($(LOCAL_VARIANT),basic) -+ DRIVER_MAKEOPTS += CONFIG_OWE=y -+ endif -+ ifeq ($(LOCAL_VARIANT),mesh) -+ DRIVER_MAKEOPTS += CONFIG_AP=y CONFIG_MESH=y CONFIG_WPS_NFC=1 -+ endif -+ ifeq ($(LOCAL_VARIANT),full) -+ DRIVER_MAKEOPTS += CONFIG_OWE=y CONFIG_SUITEB192=y CONFIG_AP=y CONFIG_MESH=y CONFIG_WPS_NFC=1 -+ endif -+endif -+ -+ifneq ($(LOCAL_TYPE),hostapd) -+ ifdef CONFIG_WPA_RFKILL_SUPPORT -+ DRIVER_MAKEOPTS += NEED_RFKILL=y -+ endif -+endif -+ -+DRV_DEPENDS:=+PACKAGE_kmod-cfg80211:libnl-tiny -+ -+ -+define Package/hostapd/Default -+ SECTION:=net -+ CATEGORY:=Network -+ SUBMENU:=WirelessAPD -+ TITLE:=IEEE 802.1x Authenticator -+ URL:=http://hostap.epitest.fi/ -+ DEPENDS:=$(DRV_DEPENDS) +hostapd-common $(CORE_DEPENDS) -+ EXTRA_DEPENDS:=hostapd-common (=$(PKG_VERSION)-$(PKG_RELEASE)) -+ USERID:=network=101:network=101 -+ PROVIDES:=hostapd -+ CONFLICTS:=$(HOSTAPD_PROVIDERS) -+ HOSTAPD_PROVIDERS+=$(1) -+endef -+ -+define Package/hostapd -+$(call Package/hostapd/Default,$(1)) -+ TITLE+= (built-in full) -+ VARIANT:=full-internal -+endef -+ -+define Package/hostapd/description -+ This package contains a full featured IEEE 802.1x/WPA/EAP/RADIUS -+ Authenticator. -+endef -+ -+define Package/hostapd-openssl -+$(call Package/hostapd/Default,$(1)) -+ TITLE+= (OpenSSL full) -+ VARIANT:=full-openssl -+ DEPENDS+=+PACKAGE_hostapd-openssl:libopenssl -+endef -+ -+Package/hostapd-openssl/description = $(Package/hostapd/description) -+ -+define Package/hostapd-wolfssl -+$(call Package/hostapd/Default,$(1)) -+ TITLE+= (wolfSSL full) -+ VARIANT:=full-wolfssl -+ DEPENDS+=+PACKAGE_hostapd-wolfssl:libwolfssl -+endef -+ -+Package/hostapd-wolfssl/description = $(Package/hostapd/description) -+ -+define Package/hostapd-mbedtls -+$(call Package/hostapd/Default,$(1)) -+ TITLE+= (mbedTLS full) -+ VARIANT:=full-mbedtls -+ DEPENDS+=+PACKAGE_hostapd-mbedtls:libmbedtls -+endef -+ -+Package/hostapd-mbedtls/description = $(Package/hostapd/description) -+ -+define Package/hostapd-basic -+$(call Package/hostapd/Default,$(1)) -+ TITLE+= (WPA-PSK, 11r, 11w) -+ VARIANT:=basic -+endef -+ -+define Package/hostapd-basic/description -+ This package contains a basic IEEE 802.1x/WPA Authenticator with WPA-PSK, 802.11r and 802.11w support. -+endef -+ -+define Package/hostapd-basic-openssl -+$(call Package/hostapd/Default,$(1)) -+ TITLE+= (WPA-PSK, 11r and 11w) -+ VARIANT:=basic-openssl -+ DEPENDS+=+PACKAGE_hostapd-basic-openssl:libopenssl -+endef -+ -+define Package/hostapd-basic-openssl/description -+ This package contains a basic IEEE 802.1x/WPA Authenticator with WPA-PSK, 802.11r and 802.11w support. -+endef -+ -+define Package/hostapd-basic-wolfssl -+$(call Package/hostapd/Default,$(1)) -+ TITLE+= (WPA-PSK, 11r and 11w) -+ VARIANT:=basic-wolfssl -+ DEPENDS+=+PACKAGE_hostapd-basic-wolfssl:libwolfssl -+endef -+ -+define Package/hostapd-basic-wolfssl/description -+ This package contains a basic IEEE 802.1x/WPA Authenticator with WPA-PSK, 802.11r and 802.11w support. -+endef -+ -+define Package/hostapd-basic-mbedtls -+$(call Package/hostapd/Default,$(1)) -+ TITLE+= (WPA-PSK, 11r and 11w) -+ VARIANT:=basic-mbedtls -+ DEPENDS+=+PACKAGE_hostapd-basic-mbedtls:libmbedtls -+endef -+ -+define Package/hostapd-basic-mbedtls/description -+ This package contains a basic IEEE 802.1x/WPA Authenticator with WPA-PSK, 802.11r and 802.11w support. -+endef -+ -+define Package/hostapd-mini -+$(call Package/hostapd/Default,$(1)) -+ TITLE+= (WPA-PSK only) -+ VARIANT:=mini -+endef -+ -+define Package/hostapd-mini/description -+ This package contains a minimal IEEE 802.1x/WPA Authenticator (WPA-PSK only). -+endef -+ -+ -+define Package/wpad/Default -+ SECTION:=net -+ CATEGORY:=Network -+ SUBMENU:=WirelessAPD -+ TITLE:=IEEE 802.1x Auth/Supplicant -+ DEPENDS:=$(DRV_DEPENDS) +hostapd-common $(CORE_DEPENDS) -+ EXTRA_DEPENDS:=hostapd-common (=$(PKG_VERSION)-$(PKG_RELEASE)) -+ USERID:=network=101:network=101 -+ URL:=http://hostap.epitest.fi/ -+ PROVIDES:=hostapd wpa-supplicant -+ CONFLICTS:=$(HOSTAPD_PROVIDERS) $(SUPPLICANT_PROVIDERS) -+ HOSTAPD_PROVIDERS+=$(1) -+ SUPPLICANT_PROVIDERS+=$(1) -+endef -+ -+define Package/wpad -+$(call Package/wpad/Default,$(1)) -+ TITLE+= (built-in full) -+ VARIANT:=wpad-full-internal -+endef -+ -+define Package/wpad/description -+ This package contains a full featured IEEE 802.1x/WPA/EAP/RADIUS -+ Authenticator and Supplicant -+endef -+ -+define Package/wpad-openssl -+$(call Package/wpad/Default,$(1)) -+ TITLE+= (OpenSSL full) -+ VARIANT:=wpad-full-openssl -+ DEPENDS+=+PACKAGE_wpad-openssl:libopenssl -+endef -+ -+Package/wpad-openssl/description = $(Package/wpad/description) -+ -+define Package/wpad-wolfssl -+$(call Package/wpad/Default,$(1)) -+ TITLE+= (wolfSSL full) -+ VARIANT:=wpad-full-wolfssl -+ DEPENDS+=+PACKAGE_wpad-wolfssl:libwolfssl -+endef -+ -+Package/wpad-wolfssl/description = $(Package/wpad/description) -+ -+define Package/wpad-mbedtls -+$(call Package/wpad/Default,$(1)) -+ TITLE+= (mbedTLS full) -+ VARIANT:=wpad-full-mbedtls -+ DEPENDS+=+PACKAGE_wpad-mbedtls:libmbedtls -+endef -+ -+Package/wpad-mbedtls/description = $(Package/wpad/description) -+ -+define Package/wpad-basic -+$(call Package/wpad/Default,$(1)) -+ TITLE+= (WPA-PSK, 11r, 11w) -+ VARIANT:=wpad-basic -+endef -+ -+define Package/wpad-basic/description -+ This package contains a basic IEEE 802.1x/WPA Authenticator and Supplicant with WPA-PSK, 802.11r and 802.11w support. -+endef -+ -+define Package/wpad-basic-openssl -+$(call Package/wpad/Default,$(1)) -+ TITLE+= (OpenSSL, 11r, 11w) -+ VARIANT:=wpad-basic-openssl -+ DEPENDS+=+PACKAGE_wpad-basic-openssl:libopenssl -+endef -+ -+define Package/wpad-basic-openssl/description -+ This package contains a basic IEEE 802.1x/WPA Authenticator and Supplicant with WPA-PSK, SAE (WPA3-Personal), 802.11r and 802.11w support. -+endef -+ -+define Package/wpad-basic-wolfssl -+$(call Package/wpad/Default,$(1)) -+ TITLE+= (wolfSSL, 11r, 11w) -+ VARIANT:=wpad-basic-wolfssl -+ DEPENDS+=+PACKAGE_wpad-basic-wolfssl:libwolfssl -+endef -+ -+define Package/wpad-basic-wolfssl/description -+ This package contains a basic IEEE 802.1x/WPA Authenticator and Supplicant with WPA-PSK, SAE (WPA3-Personal), 802.11r and 802.11w support. -+endef -+ -+define Package/wpad-basic-mbedtls -+$(call Package/wpad/Default,$(1)) -+ TITLE+= (mbedTLS, 11r, 11w) -+ VARIANT:=wpad-basic-mbedtls -+ DEPENDS+=+PACKAGE_wpad-basic-mbedtls:libmbedtls -+endef -+ -+define Package/wpad-basic-mbedtls/description -+ This package contains a basic IEEE 802.1x/WPA Authenticator and Supplicant with WPA-PSK, SAE (WPA3-Personal), 802.11r and 802.11w support. -+endef -+ -+define Package/wpad-mini -+$(call Package/wpad/Default,$(1)) -+ TITLE+= (WPA-PSK only) -+ VARIANT:=wpad-mini -+endef -+ -+define Package/wpad-mini/description -+ This package contains a minimal IEEE 802.1x/WPA Authenticator and Supplicant (WPA-PSK only). -+endef -+ -+define Package/wpad-mesh -+$(call Package/wpad/Default,$(1)) -+ DEPENDS+=@PACKAGE_kmod-cfg80211 @(!TARGET_uml||BROKEN) -+ PROVIDES+=wpa-supplicant-mesh wpad-mesh -+endef -+ -+define Package/wpad-mesh/description -+ This package contains a minimal IEEE 802.1x/WPA Authenticator and Supplicant (with 802.11s mesh and SAE support). -+endef -+ -+define Package/wpad-mesh-openssl -+$(call Package/wpad-mesh,$(1)) -+ TITLE+= (OpenSSL, 11s, SAE) -+ DEPENDS+=+PACKAGE_wpad-mesh-openssl:libopenssl -+ VARIANT:=wpad-mesh-openssl -+endef -+ -+Package/wpad-mesh-openssl/description = $(Package/wpad-mesh/description) -+ -+define Package/wpad-mesh-wolfssl -+$(call Package/wpad-mesh,$(1)) -+ TITLE+= (wolfSSL, 11s, SAE) -+ DEPENDS+=+PACKAGE_wpad-mesh-wolfssl:libwolfssl -+ VARIANT:=wpad-mesh-wolfssl -+endef -+ -+Package/wpad-mesh-wolfssl/description = $(Package/wpad-mesh/description) -+ -+define Package/wpad-mesh-mbedtls -+$(call Package/wpad-mesh,$(1)) -+ TITLE+= (mbedTLS, 11s, SAE) -+ DEPENDS+=+PACKAGE_wpad-mesh-mbedtls:libmbedtls -+ VARIANT:=wpad-mesh-mbedtls -+endef -+ -+Package/wpad-mesh-mbedtls/description = $(Package/wpad-mesh/description) -+ -+ -+define Package/wpa-supplicant/Default -+ SECTION:=net -+ CATEGORY:=Network -+ SUBMENU:=WirelessAPD -+ TITLE:=WPA Supplicant -+ URL:=http://hostap.epitest.fi/wpa_supplicant/ -+ DEPENDS:=$(DRV_DEPENDS) +hostapd-common $(CORE_DEPENDS) -+ EXTRA_DEPENDS:=hostapd-common (=$(PKG_VERSION)-$(PKG_RELEASE)) -+ USERID:=network=101:network=101 -+ PROVIDES:=wpa-supplicant -+ CONFLICTS:=$(SUPPLICANT_PROVIDERS) -+ SUPPLICANT_PROVIDERS+=$(1) -+endef -+ -+define Package/wpa-supplicant -+$(call Package/wpa-supplicant/Default,$(1)) -+ TITLE+= (built-in full) -+ VARIANT:=supplicant-full-internal -+endef -+ -+define Package/wpa-supplicant-openssl -+$(call Package/wpa-supplicant/Default,$(1)) -+ TITLE+= (OpenSSL full) -+ VARIANT:=supplicant-full-openssl -+ DEPENDS+=+PACKAGE_wpa-supplicant-openssl:libopenssl -+endef -+ -+define Package/wpa-supplicant-wolfssl -+$(call Package/wpa-supplicant/Default,$(1)) -+ TITLE+= (wolfSSL full) -+ VARIANT:=supplicant-full-wolfssl -+ DEPENDS+=+PACKAGE_wpa-supplicant-wolfssl:libwolfssl -+endef -+ -+define Package/wpa-supplicant-mbedtls -+$(call Package/wpa-supplicant/Default,$(1)) -+ TITLE+= (mbedTLS full) -+ VARIANT:=supplicant-full-mbedtls -+ DEPENDS+=+PACKAGE_wpa-supplicant-mbedtls:libmbedtls -+endef -+ -+define Package/wpa-supplicant/config -+ source "$(SOURCE)/Config.in" -+endef -+ -+define Package/wpa-supplicant-p2p -+$(call Package/wpa-supplicant/Default,$(1)) -+ TITLE+= (Wi-Fi P2P support) -+ DEPENDS+=@PACKAGE_kmod-cfg80211 -+ VARIANT:=supplicant-p2p-internal -+endef -+ -+define Package/wpa-supplicant-mesh/Default -+$(call Package/wpa-supplicant/Default,$(1)) -+ DEPENDS+=@PACKAGE_kmod-cfg80211 @(!TARGET_uml||BROKEN) -+ PROVIDES+=wpa-supplicant-mesh -+endef -+ -+define Package/wpa-supplicant-mesh-openssl -+$(call Package/wpa-supplicant-mesh/Default,$(1)) -+ TITLE+= (OpenSSL, 11s, SAE) -+ VARIANT:=supplicant-mesh-openssl -+ DEPENDS+=+PACKAGE_wpa-supplicant-mesh-openssl:libopenssl -+endef -+ -+define Package/wpa-supplicant-mesh-wolfssl -+$(call Package/wpa-supplicant-mesh/Default,$(1)) -+ TITLE+= (wolfSSL, 11s, SAE) -+ VARIANT:=supplicant-mesh-wolfssl -+ DEPENDS+=+PACKAGE_wpa-supplicant-mesh-wolfssl:libwolfssl -+endef -+ -+define Package/wpa-supplicant-mesh-mbedtls -+$(call Package/wpa-supplicant-mesh/Default,$(1)) -+ TITLE+= (mbedTLS, 11s, SAE) -+ VARIANT:=supplicant-mesh-mbedtls -+ DEPENDS+=+PACKAGE_wpa-supplicant-mesh-mbedtls:libmbedtls -+endef -+ -+define Package/wpa-supplicant-basic -+$(call Package/wpa-supplicant/Default,$(1)) -+ TITLE+= (11r, 11w) -+ VARIANT:=supplicant-basic -+endef -+ -+define Package/wpa-supplicant-mini -+$(call Package/wpa-supplicant/Default,$(1)) -+ TITLE+= (minimal) -+ VARIANT:=supplicant-mini -+endef -+ -+ -+define Package/hostapd-common -+ TITLE:=hostapd/wpa_supplicant common support files -+ SECTION:=net -+ CATEGORY:=Network -+ SUBMENU:=WirelessAPD -+endef -+ -+define Package/hostapd-utils -+ SECTION:=net -+ CATEGORY:=Network -+ SUBMENU:=WirelessAPD -+ TITLE:=IEEE 802.1x Authenticator (utils) -+ URL:=http://hostap.epitest.fi/ -+ DEPENDS:=@$(subst $(space),||,$(foreach pkg,$(HOSTAPD_PROVIDERS),PACKAGE_$(pkg))) -+ VARIANT:=* -+endef -+ -+define Package/hostapd-utils/description -+ This package contains a command line utility to control the -+ IEEE 802.1x/WPA/EAP/RADIUS Authenticator. -+endef -+ -+define Package/wpa-cli -+ SECTION:=net -+ CATEGORY:=Network -+ SUBMENU:=WirelessAPD -+ DEPENDS:=@$(subst $(space),||,$(foreach pkg,$(SUPPLICANT_PROVIDERS),PACKAGE_$(pkg))) -+ TITLE:=WPA Supplicant command line control utility -+ VARIANT:=* -+endef -+ -+define Package/eapol-test/Default -+ TITLE:=802.1x auth test utility -+ SECTION:=net -+ SUBMENU:=WirelessAPD -+ CATEGORY:=Network -+ DEPENDS:=$(DRV_DEPENDS) $(CORE_DEPENDS) -+endef -+ -+define Package/eapol-test -+ $(call Package/eapol-test/Default,$(1)) -+ TITLE+= (built-in full) -+ VARIANT:=supplicant-full-internal -+endef -+ -+define Package/eapol-test-openssl -+ $(call Package/eapol-test/Default,$(1)) -+ TITLE+= (OpenSSL full) -+ VARIANT:=supplicant-full-openssl -+ CONFLICTS:=$(filter-out eapol-test-openssl ,$(EAPOL_TEST_PROVIDERS)) -+ DEPENDS+=+PACKAGE_eapol-test-openssl:libopenssl -+ PROVIDES:=eapol-test -+endef -+ -+define Package/eapol-test-wolfssl -+ $(call Package/eapol-test/Default,$(1)) -+ TITLE+= (wolfSSL full) -+ VARIANT:=supplicant-full-wolfssl -+ CONFLICTS:=$(filter-out eapol-test-openssl ,$(filter-out eapol-test-wolfssl ,$(EAPOL_TEST_PROVIDERS))) -+ DEPENDS+=+PACKAGE_eapol-test-wolfssl:libwolfssl -+ PROVIDES:=eapol-test -+endef -+ -+define Package/eapol-test-mbedtls -+ $(call Package/eapol-test/Default,$(1)) -+ TITLE+= (mbedTLS full) -+ VARIANT:=supplicant-full-mbedtls -+ CONFLICTS:=$(filter-out eapol-test-openssl ,$(filter-out eapol-test-mbedtls ,$(EAPOL_TEST_PROVIDERS))) -+ DEPENDS+=+PACKAGE_eapol-test-mbedtls:libmbedtls -+ PROVIDES:=eapol-test -+endef -+ -+ -+ifneq ($(wildcard $(PKG_BUILD_DIR)/.config_*),$(subst .configured_,.config_,$(STAMP_CONFIGURED))) -+ define Build/Configure/rebuild -+ $(FIND) $(PKG_BUILD_DIR) -name \*.o -or -name \*.a | $(XARGS) rm -f -+ rm -f $(PKG_BUILD_DIR)/hostapd/hostapd -+ rm -f $(PKG_BUILD_DIR)/wpa_supplicant/wpa_supplicant -+ rm -f $(PKG_BUILD_DIR)/.config_* -+ touch $(subst .configured_,.config_,$(STAMP_CONFIGURED)) -+ endef -+endif -+ -+define Build/Configure -+ $(Build/Configure/rebuild) -+ $(if $(wildcard ./files/hostapd-$(CONFIG_VARIANT).config), \ -+ $(CP) ./files/hostapd-$(CONFIG_VARIANT).config $(PKG_BUILD_DIR)/hostapd/.config \ -+ ) -+ $(if $(wildcard ./files/wpa_supplicant-$(CONFIG_VARIANT).config), \ -+ $(CP) ./files/wpa_supplicant-$(CONFIG_VARIANT).config $(PKG_BUILD_DIR)/wpa_supplicant/.config -+ ) -+endef -+ -+TARGET_CPPFLAGS := \ -+ -I$(STAGING_DIR)/usr/include/libnl-tiny \ -+ -I$(PKG_BUILD_DIR)/src/crypto \ -+ $(TARGET_CPPFLAGS) \ -+ -DCONFIG_LIBNL20 \ -+ -D_GNU_SOURCE \ -+ $(if $(CONFIG_WPA_MSG_MIN_PRIORITY),-DCONFIG_MSG_MIN_PRIORITY=$(CONFIG_WPA_MSG_MIN_PRIORITY)) -+ -+TARGET_LDFLAGS += -lubox -lubus -lblobmsg_json -lucode -+ -+ifdef CONFIG_PACKAGE_kmod-cfg80211 -+ TARGET_LDFLAGS += -lm -lnl-tiny -+endif -+ -+ifdef CONFIG_WPA_ENABLE_WEP -+ DRIVER_MAKEOPTS += CONFIG_WEP=y -+endif -+ -+define Build/RunMake -+ CFLAGS="$(TARGET_CPPFLAGS) $(TARGET_CFLAGS)" \ -+ $(MAKE) $(PKG_JOBS) -C $(PKG_BUILD_DIR)/$(1) \ -+ $(TARGET_CONFIGURE_OPTS) \ -+ $(DRIVER_MAKEOPTS) \ -+ LIBS="$(TARGET_LDFLAGS)" \ -+ LIBS_c="$(TARGET_LDFLAGS_C)" \ -+ AR="$(TARGET_CROSS)gcc-ar" \ -+ BCHECK= \ -+ $(if $(findstring s,$(OPENWRT_VERBOSE)),V=1) \ -+ $(2) -+endef -+ -+define Build/Compile/wpad -+ echo ` \ -+ $(call Build/RunMake,hostapd,-s MULTICALL=1 dump_cflags); \ -+ $(call Build/RunMake,wpa_supplicant,-s MULTICALL=1 dump_cflags) | \ -+ sed -e 's,-n ,,g' -e 's^$(TARGET_CFLAGS)^^' \ -+ ` > $(PKG_BUILD_DIR)/.cflags -+ sed -i 's/"/\\"/g' $(PKG_BUILD_DIR)/.cflags -+ +$(call Build/RunMake,hostapd, \ -+ CFLAGS="$$$$(cat $(PKG_BUILD_DIR)/.cflags)" \ -+ MULTICALL=1 \ -+ hostapd_cli hostapd_multi.a \ -+ ) -+ +$(call Build/RunMake,wpa_supplicant, \ -+ CFLAGS="$$$$(cat $(PKG_BUILD_DIR)/.cflags)" \ -+ MULTICALL=1 \ -+ wpa_cli wpa_supplicant_multi.a \ -+ ) -+ +export MAKEFLAGS="$(MAKE_JOBSERVER)"; $(TARGET_CC) -o $(PKG_BUILD_DIR)/wpad \ -+ $(TARGET_CFLAGS) \ -+ ./files/multicall.c \ -+ $(PKG_BUILD_DIR)/hostapd/hostapd_multi.a \ -+ $(PKG_BUILD_DIR)/wpa_supplicant/wpa_supplicant_multi.a \ -+ $(TARGET_LDFLAGS) -+endef -+ -+define Build/Compile/hostapd -+ +$(call Build/RunMake,hostapd, \ -+ hostapd hostapd_cli \ -+ ) -+endef -+ -+define Build/Compile/supplicant -+ +$(call Build/RunMake,wpa_supplicant, \ -+ wpa_cli wpa_supplicant \ -+ ) -+endef -+ -+define Build/Compile/supplicant-full-internal -+ +$(call Build/RunMake,wpa_supplicant, \ -+ eapol_test \ -+ ) -+endef -+ -+define Build/Compile/supplicant-full-openssl -+ +$(call Build/RunMake,wpa_supplicant, \ -+ eapol_test \ -+ ) -+endef -+ -+define Build/Compile/supplicant-full-wolfssl -+ +$(call Build/RunMake,wpa_supplicant, \ -+ eapol_test \ -+ ) -+endef -+ -+define Build/Compile/supplicant-full-mbedtls -+ +$(call Build/RunMake,wpa_supplicant, \ -+ eapol_test \ -+ ) -+endef -+ -+define Build/Compile -+ $(Build/Compile/$(LOCAL_TYPE)) -+ $(Build/Compile/$(BUILD_VARIANT)) -+endef -+ -+define Install/hostapd/full -+ $(INSTALL_DIR) $(1)/etc/init.d $(1)/etc/config $(1)/etc/radius -+ ln -sf hostapd $(1)/usr/sbin/hostapd-radius -+ $(INSTALL_BIN) ./files/radius.init $(1)/etc/init.d/radius -+ $(INSTALL_DATA) ./files/radius.config $(1)/etc/config/radius -+ $(INSTALL_DATA) ./files/radius.clients $(1)/etc/radius/clients -+ $(INSTALL_DATA) ./files/radius.users $(1)/etc/radius/users -+endef -+ -+define Package/hostapd-full/conffiles -+/etc/config/radius -+/etc/radius -+endef -+ -+ifeq ($(CONFIG_VARIANT),full) -+Package/wpad-mesh-openssl/conffiles = $(Package/hostapd-full/conffiles) -+Package/wpad-mesh-wolfssl/conffiles = $(Package/hostapd-full/conffiles) -+Package/wpad-mesh-mbedtls/conffiles = $(Package/hostapd-full/conffiles) -+Package/wpad/conffiles = $(Package/hostapd-full/conffiles) -+Package/wpad-openssl/conffiles = $(Package/hostapd-full/conffiles) -+Package/wpad-wolfssl/conffiles = $(Package/hostapd-full/conffiles) -+Package/wpad-mbedtls/conffiles = $(Package/hostapd-full/conffiles) -+Package/hostapd/conffiles = $(Package/hostapd-full/conffiles) -+Package/hostapd-openssl/conffiles = $(Package/hostapd-full/conffiles) -+Package/hostapd-wolfssl/conffiles = $(Package/hostapd-full/conffiles) -+Package/hostapd-mbedtls/conffiles = $(Package/hostapd-full/conffiles) -+endif -+ -+define Install/hostapd -+ $(INSTALL_DIR) $(1)/usr/sbin $(1)/usr/share/hostap -+ $(INSTALL_DATA) ./files/hostapd.uc $(1)/usr/share/hostap/ -+ $(if $(findstring full,$(CONFIG_VARIANT)),$(Install/hostapd/full)) -+endef -+ -+define Install/supplicant -+ $(INSTALL_DIR) $(1)/usr/sbin $(1)/usr/share/hostap -+ $(INSTALL_DATA) ./files/wpa_supplicant.uc $(1)/usr/share/hostap/ -+endef -+ -+define Package/hostapd-common/install -+ $(INSTALL_DIR) $(1)/etc/capabilities $(1)/etc/rc.button $(1)/etc/hotplug.d/ieee80211 $(1)/etc/init.d $(1)/lib/netifd $(1)/usr/share/acl.d $(1)/usr/share/hostap -+ $(INSTALL_BIN) ./files/dhcp-get-server.sh $(1)/lib/netifd/dhcp-get-server.sh -+ $(INSTALL_DATA) ./files/hostapd.sh $(1)/lib/netifd/hostapd.sh -+ $(INSTALL_BIN) ./files/wpad.init $(1)/etc/init.d/wpad -+ $(INSTALL_BIN) ./files/wps-hotplug.sh $(1)/etc/rc.button/wps -+ $(INSTALL_DATA) ./files/wpad_acl.json $(1)/usr/share/acl.d -+ $(INSTALL_DATA) ./files/wpad.json $(1)/etc/capabilities -+ $(INSTALL_DATA) ./files/common.uc $(1)/usr/share/hostap/ -+ $(INSTALL_DATA) ./files/wdev.uc $(1)/usr/share/hostap/ -+endef -+ -+define Package/hostapd/install -+ $(call Install/hostapd,$(1)) -+ $(INSTALL_BIN) $(PKG_BUILD_DIR)/hostapd/hostapd $(1)/usr/sbin/ -+endef -+Package/hostapd-basic/install = $(Package/hostapd/install) -+Package/hostapd-basic-openssl/install = $(Package/hostapd/install) -+Package/hostapd-basic-wolfssl/install = $(Package/hostapd/install) -+Package/hostapd-basic-mbedtls/install = $(Package/hostapd/install) -+Package/hostapd-mini/install = $(Package/hostapd/install) -+Package/hostapd-openssl/install = $(Package/hostapd/install) -+Package/hostapd-wolfssl/install = $(Package/hostapd/install) -+Package/hostapd-mbedtls/install = $(Package/hostapd/install) -+ -+ifneq ($(LOCAL_TYPE),supplicant) -+ define Package/hostapd-utils/install -+ $(INSTALL_DIR) $(1)/usr/sbin -+ $(INSTALL_BIN) $(PKG_BUILD_DIR)/hostapd/hostapd_cli $(1)/usr/sbin/ -+ endef -+endif -+ -+define Package/wpad/install -+ $(call Install/hostapd,$(1)) -+ $(call Install/supplicant,$(1)) -+ $(INSTALL_BIN) $(PKG_BUILD_DIR)/wpad $(1)/usr/sbin/ -+ $(LN) wpad $(1)/usr/sbin/hostapd -+ $(LN) wpad $(1)/usr/sbin/wpa_supplicant -+endef -+Package/wpad-basic/install = $(Package/wpad/install) -+Package/wpad-basic-openssl/install = $(Package/wpad/install) -+Package/wpad-basic-wolfssl/install = $(Package/wpad/install) -+Package/wpad-basic-mbedtls/install = $(Package/wpad/install) -+Package/wpad-mini/install = $(Package/wpad/install) -+Package/wpad-openssl/install = $(Package/wpad/install) -+Package/wpad-wolfssl/install = $(Package/wpad/install) -+Package/wpad-mbedtls/install = $(Package/wpad/install) -+Package/wpad-mesh-openssl/install = $(Package/wpad/install) -+Package/wpad-mesh-wolfssl/install = $(Package/wpad/install) -+Package/wpad-mesh-mbedtls/install = $(Package/wpad/install) -+ -+define Package/wpa-supplicant/install -+ $(call Install/supplicant,$(1)) -+ $(INSTALL_BIN) $(PKG_BUILD_DIR)/wpa_supplicant/wpa_supplicant $(1)/usr/sbin/ -+endef -+Package/wpa-supplicant-basic/install = $(Package/wpa-supplicant/install) -+Package/wpa-supplicant-mini/install = $(Package/wpa-supplicant/install) -+Package/wpa-supplicant-p2p/install = $(Package/wpa-supplicant/install) -+Package/wpa-supplicant-openssl/install = $(Package/wpa-supplicant/install) -+Package/wpa-supplicant-wolfssl/install = $(Package/wpa-supplicant/install) -+Package/wpa-supplicant-mbedtls/install = $(Package/wpa-supplicant/install) -+Package/wpa-supplicant-mesh-openssl/install = $(Package/wpa-supplicant/install) -+Package/wpa-supplicant-mesh-wolfssl/install = $(Package/wpa-supplicant/install) -+Package/wpa-supplicant-mesh-mbedtls/install = $(Package/wpa-supplicant/install) -+ -+ifneq ($(LOCAL_TYPE),hostapd) -+ define Package/wpa-cli/install -+ $(INSTALL_DIR) $(1)/usr/sbin -+ $(CP) $(PKG_BUILD_DIR)/wpa_supplicant/wpa_cli $(1)/usr/sbin/ -+ endef -+endif -+ -+ifeq ($(BUILD_VARIANT),supplicant-full-internal) -+ define Package/eapol-test/install -+ $(INSTALL_DIR) $(1)/usr/sbin -+ $(CP) $(PKG_BUILD_DIR)/wpa_supplicant/eapol_test $(1)/usr/sbin/ -+ endef -+endif -+ -+ifeq ($(BUILD_VARIANT),supplicant-full-openssl) -+ define Package/eapol-test-openssl/install -+ $(INSTALL_DIR) $(1)/usr/sbin -+ $(CP) $(PKG_BUILD_DIR)/wpa_supplicant/eapol_test $(1)/usr/sbin/ -+ endef -+endif -+ -+ifeq ($(BUILD_VARIANT),supplicant-full-wolfssl) -+ define Package/eapol-test-wolfssl/install -+ $(INSTALL_DIR) $(1)/usr/sbin -+ $(CP) $(PKG_BUILD_DIR)/wpa_supplicant/eapol_test $(1)/usr/sbin/ -+ endef -+endif -+ -+ifeq ($(BUILD_VARIANT),supplicant-full-mbedtls) -+ define Package/eapol-test-mbedtls/install -+ $(INSTALL_DIR) $(1)/usr/sbin -+ $(CP) $(PKG_BUILD_DIR)/wpa_supplicant/eapol_test $(1)/usr/sbin/ -+ endef -+endif -+ -+# Build hostapd-common before its dependents, to avoid -+# spurious rebuilds when building multiple variants. -+$(eval $(call BuildPackage,hostapd-common)) -+$(eval $(call BuildPackage,hostapd)) -+$(eval $(call BuildPackage,hostapd-basic)) -+$(eval $(call BuildPackage,hostapd-basic-openssl)) -+$(eval $(call BuildPackage,hostapd-basic-wolfssl)) -+$(eval $(call BuildPackage,hostapd-basic-mbedtls)) -+$(eval $(call BuildPackage,hostapd-mini)) -+$(eval $(call BuildPackage,hostapd-openssl)) -+$(eval $(call BuildPackage,hostapd-wolfssl)) -+$(eval $(call BuildPackage,hostapd-mbedtls)) -+$(eval $(call BuildPackage,wpad)) -+$(eval $(call BuildPackage,wpad-mesh-openssl)) -+$(eval $(call BuildPackage,wpad-mesh-wolfssl)) -+$(eval $(call BuildPackage,wpad-mesh-mbedtls)) -+$(eval $(call BuildPackage,wpad-basic)) -+$(eval $(call BuildPackage,wpad-basic-openssl)) -+$(eval $(call BuildPackage,wpad-basic-wolfssl)) -+$(eval $(call BuildPackage,wpad-basic-mbedtls)) -+$(eval $(call BuildPackage,wpad-mini)) -+$(eval $(call BuildPackage,wpad-openssl)) -+$(eval $(call BuildPackage,wpad-wolfssl)) -+$(eval $(call BuildPackage,wpad-mbedtls)) -+$(eval $(call BuildPackage,wpa-supplicant)) -+$(eval $(call BuildPackage,wpa-supplicant-mesh-openssl)) -+$(eval $(call BuildPackage,wpa-supplicant-mesh-wolfssl)) -+$(eval $(call BuildPackage,wpa-supplicant-mesh-mbedtls)) -+$(eval $(call BuildPackage,wpa-supplicant-basic)) -+$(eval $(call BuildPackage,wpa-supplicant-mini)) -+$(eval $(call BuildPackage,wpa-supplicant-p2p)) -+$(eval $(call BuildPackage,wpa-supplicant-openssl)) -+$(eval $(call BuildPackage,wpa-supplicant-wolfssl)) -+$(eval $(call BuildPackage,wpa-supplicant-mbedtls)) -+$(eval $(call BuildPackage,wpa-cli)) -+$(eval $(call BuildPackage,hostapd-utils)) -+$(eval $(call BuildPackage,eapol-test)) -+$(eval $(call BuildPackage,eapol-test-openssl)) -+$(eval $(call BuildPackage,eapol-test-wolfssl)) -+$(eval $(call BuildPackage,eapol-test-mbedtls)) -diff --git a/package/network/services/hostapd/README.md b/package/network/services/hostapd/README.md -new file mode 100644 -index 0000000000..2150863306 ---- /dev/null -+++ b/package/network/services/hostapd/README.md -@@ -0,0 +1,419 @@ -+# UBUS methods - hostapd -+ -+## bss_mgmt_enable -+Enable 802.11k/v features. -+ -+### arguments -+| Name | Type | Required | Description | -+|---|---|---|---| -+| neighbor_report | bool | no | enable 802.11k neighbor reports | -+| beacon_report | bool | no | enable 802.11k beacon reports | -+| link_measurements | bool | no | enable 802.11k link measurements | -+| bss_transition | bool | no | enable 802.11v BSS transition support | -+ -+### example -+`ubus call hostapd.wl5-fb bss_mgmt_enable '{ "neighbor_report": true, "beacon_report": true, "link_measurements": true, "bss_transition": true -+}'` -+ -+ -+## bss_transition_request -+Initiate an 802.11v transition request. -+ -+### arguments -+| Name | Type | Required | Description | -+|---|---|---|---| -+| addr | string | yes | client MAC address | -+| disassociation_imminent | bool | no | set Disassociation Imminent bit | -+| disassociation_timer | int32 | no | disassociate client if it doesn't roam after this time | -+| validity_period | int32 | no | validity of the BSS Transition Candiate List | -+| neighbors | array | no | BSS Transition Candidate List | -+| abridged | bool | no | prefer APs in the BSS Transition Candidate List | -+| dialog_token | int32 | no | identifier for the request/report transaction | -+| mbo_reason | int32 | no | MBO Transition Reason Code Attribute | -+| cell_pref | int32 | no | MBO Cellular Data Connection Preference Attribute | -+| reassoc_delay | int32 | no | MBO Re-association retry delay | -+ -+### example -+`ubus call hostapd.wl5-fb bss_transition_request '{ "addr": "68:2F:67:8B:98:ED", "disassociation_imminent": false, "disassociation_timer": 0, "validity_period": 30, "neighbors": ["b6a7b9cbeebabf5900008064090603026a00"], "abridged": 1 }'` -+ -+ -+## config_add -+Dynamically load a BSS configuration from a file. This is used by netifd's mac80211 support script to configure BSSes on multiple PHYs in a single hostapd instance. -+ -+### arguments -+| Name | Type | Required | Description | -+|---|---|---|---| -+| iface | string | yes | WiFi interface name | -+| config | string | yes | path to hostapd config file | -+ -+ -+## config_remove -+Dynamically remove a BSS configuration. -+ -+### arguments -+| Name | Type | Required | Description | -+|---|---|---|---| -+| iface | string | yes | WiFi interface name | -+ -+ -+## del_client -+Kick a client off the network. -+ -+### arguments -+| Name | Type | Required | Description | -+|---|---|---|---| -+| addr | string | yes | client MAC address | -+| reason | int32 | no | 802.11 reason code | -+| deauth | bool | no | deauthenticates client instead of disassociating | -+| ban_time | int32 | no | ban client for N milliseconds | -+ -+### example -+`ubus call hostapd.wl5-fb del_client '{ "addr": "68:2f:67:8b:98:ed", "reason": 5, "deauth": true, "ban_time": 10000 }'` -+ -+ -+## get_clients -+Show associated clients. -+ -+### example -+`ubus call hostapd.wl5-fb get_clients` -+ -+### output -+```json -+{ -+ "freq": 5260, -+ "clients": { -+ "68:2f:67:8b:98:ed": { -+ "auth": true, -+ "assoc": true, -+ "authorized": true, -+ "preauth": false, -+ "wds": false, -+ "wmm": true, -+ "ht": true, -+ "vht": true, -+ "he": false, -+ "wps": false, -+ "mfp": true, -+ "rrm": [ -+ 0, -+ 0, -+ 0, -+ 0, -+ 0 -+ ], -+ "extended_capabilities": [ -+ 0, -+ 0, -+ 0, -+ 0, -+ 0, -+ 0, -+ 0, -+ 64 -+ ], -+ "aid": 3, -+ "signature": "wifi4|probe:0,1,45,127,107,191,221(0017f2,10),221(001018,2),htcap:006f,htagg:1b,htmcs:0000ffff,vhtcap:0f825832,vhtrxmcs:0000ffea,vhttxmcs:0000ffea,extcap:0000008000000040|assoc:0,1,33,36,48,45,127,191,221(0017f2,10),221(001018,2),221(0050f2,2),htcap:006f,htagg:1b,htmcs:0000ffff,vhtcap:0f825832,vhtrxmcs:0000ffea,vhttxmcs:0000ffea,txpow:14f9,extcap:0000000000000040", -+ "bytes": { -+ "rx": 1933667, -+ "tx": 746805 -+ }, -+ "airtime": { -+ "rx": 208863, -+ "tx": 9037883 -+ }, -+ "packets": { -+ "rx": 3587, -+ "tx": 2185 -+ }, -+ "rate": { -+ "rx": 866700, -+ "tx": 866700 -+ }, -+ "signal": -50, -+ "capabilities": { -+ "vht": { -+ "su_beamformee": true, -+ "mu_beamformee": false, -+ "mcs_map": { -+ "rx": { -+ "1ss": 9, -+ "2ss": 9, -+ "3ss": 9, -+ "4ss": -1, -+ "5ss": -1, -+ "6ss": -1, -+ "7ss": -1, -+ "8ss": -1 -+ }, -+ "tx": { -+ "1ss": 9, -+ "2ss": 9, -+ "3ss": 9, -+ "4ss": -1, -+ "5ss": -1, -+ "6ss": -1, -+ "7ss": -1, -+ "8ss": -1 -+ } -+ } -+ } -+ } -+ } -+ } -+} -+``` -+ -+ -+## get_features -+Show HT/VHT support. -+ -+### example -+`ubus call hostapd.wl5-fb get_features` -+ -+### output -+```json -+{ -+ "ht_supported": true, -+ "vht_supported": true -+} -+``` -+ -+ -+## get_status -+Get BSS status. -+ -+### example -+`ubus call hostapd.wl5-fb get_status` -+ -+### output -+```json -+{ -+ "status": "ENABLED", -+ "bssid": "b6:a7:b9:cb:ee:bc", -+ "ssid": "fb", -+ "freq": 5260, -+ "channel": 52, -+ "op_class": 128, -+ "beacon_interval": 100, -+ "phy": "wl5-lan", -+ "rrm": { -+ "neighbor_report_tx": 0 -+ }, -+ "wnm": { -+ "bss_transition_query_rx": 0, -+ "bss_transition_request_tx": 0, -+ "bss_transition_response_rx": 0 -+ }, -+ "airtime": { -+ "time": 259561738, -+ "time_busy": 2844249, -+ "utilization": 0 -+ }, -+ "dfs": { -+ "cac_seconds": 60, -+ "cac_active": false, -+ "cac_seconds_left": 0 -+ } -+} -+``` -+ -+ -+## link_measurement_req -+Initiate an 802.11k Link Measurement Request. -+ -+### arguments -+| Name | Type | Required | Description | -+|---|---|---|---| -+| addr | string | yes | client MAC address | -+| tx-power-used | int32 | no | transmit power used to transmit the Link Measurement Request frame | -+| tx-power-max | int32 | no | upper limit of transmit power to be used by the client | -+ -+ -+## list_bans -+List banned clients. -+ -+### example -+`ubus call hostapd.wl5-fb list_bans` -+ -+### output -+```json -+{ -+ "clients": [ -+ "68:2f:67:8b:98:ed" -+ ] -+} -+``` -+ -+ -+## notify_response -+When enabled, hostapd will send a ubus notification and wait for a response before responding to various requests. This is used by e.g. usteer to make it possible to ignore probe requests. -+ -+:warning: enabling this will cause hostapd to stop responding to probe requests unless a ubus subscriber responds to the ubus notifications. -+ -+### arguments -+| Name | Type | Required | Description | -+|---|---|---|---| -+| notify_response | int32 | yes | disable (0) or enable (!0) | -+ -+### example -+`ubus call hostapd.wl5-fb notify_response '{ "notify_response": 1 }'` -+ -+## reload -+Reload BSS configuration. -+ -+:warning: this can cause problems for certain configurations: -+ -+``` -+Mon May 16 16:09:08 2022 daemon.warn hostapd: Failed to check if DFS is required; ret=-1 -+Mon May 16 16:09:08 2022 daemon.warn hostapd: Failed to check if DFS is required; ret=-1 -+Mon May 16 16:09:08 2022 daemon.err hostapd: Wrong coupling between HT and VHT/HE channel setting -+``` -+ -+### example -+`ubus call hostapd.wl5-fb reload` -+ -+ -+## rrm_beacon_req -+Send a Beacon Measurement Request to a client. -+ -+### arguments -+| Name | Type | Required | Description | -+|---|---|---|---| -+| addr | string | yes | client MAC address | -+| op_class | int32 | yes | the Regulatory Class for which this Measurement Request applies | -+| channel | int32 | yes | channel to measure | -+| duration | int32 | yes | compile Beacon Measurement Report after N TU | -+| mode | int32 | yes | mode to be used for measurement (0: passive, 1: active, 2: beacon table) | -+| bssid | string | no | filter BSSes in Beacon Measurement Report by BSSID | -+| ssid | string | no | filter BSSes in Beacon Measurement Report by SSID| -+ -+ -+## rrm_nr_get_own -+Show Neighbor Report Element for this BSS. -+ -+### example -+`ubus call hostapd.wl5-fb rrm_nr_get_own` -+ -+### output -+```json -+{ -+ "value": [ -+ "b6:a7:b9:cb:ee:bc", -+ "fb", -+ "b6a7b9cbeebcaf5900008095090603029b00" -+ ] -+} -+``` -+ -+ -+## rrm_nr_list -+Show Neighbor Report Elements for other BSSes in this ESS. -+ -+### example -+`ubus call hostapd.wl5-fb rrm_nr_list` -+ -+### output -+```json -+{ -+ "list": [ -+ [ -+ "b6:a7:b9:cb:ee:ba", -+ "fb", -+ "b6a7b9cbeebabf5900008064090603026a00" -+ ] -+ ] -+} -+``` -+ -+## rrm_nr_set -+Set the Neighbor Report Elements. An element for the node on which this command is executed will always be added. -+ -+### arguments -+| Name | Type | Required | Description | -+|---|---|---|---| -+| list | array | yes | array of Neighbor Report Elements in the format of the rrm_nr_list output | -+ -+### example -+`ubus call hostapd.wl5-fb rrm_nr_set '{ "list": [ [ "b6:a7:b9:cb:ee:ba", "fb", "b6a7b9cbeebabf5900008064090603026a00" ] ] }'` -+ -+ -+## set_vendor_elements -+Configure Vendor-specific Information Elements for BSS. -+ -+### arguments -+| Name | Type | Required | Description | -+|---|---|---|---| -+| vendor_elements | string | yes | Vendor-specific Information Elements as hex string | -+ -+### example -+`ubus call hostapd.wl5-fb set_vendor_elements '{ "vendor_elements": "dd054857dd6662" }'` -+ -+ -+## switch_chan -+Initiate a channel switch. -+ -+:warning: trying to switch to the channel that is currently in use will fail: `Command failed: Operation not supported` -+ -+### arguments -+| Name | Type | Required | Description | -+|---|---|---|---| -+| freq | int32 | yes | frequency in MHz to switch to | -+| bcn_count | int32 | no | count in Beacon frames (TBTT) to perform the switch | -+| center_freq1 | int32 | no | segment 0 center frequency in MHz (valid for HT and VHT) | -+| center_freq2 | int32 | no | segment 1 center frequency in MHz (valid only for 80 MHz channel width and an 80+80 channel) | -+| bandwidth | int32 | no | channel width to use | -+| sec_channel_offset| int32 | no | secondary channel offset for HT40 (0 = disabled, 1 = HT40+, -1 = HT40-) | -+| ht | bool | no | enable 802.11n | -+| vht | bool | no | enable 802.11ac | -+| he | bool | no | enable 802.11ax | -+| block_tx | bool | no | block transmission during CSA period | -+| csa_force | bool | no | restart the interface in case the CSA fails | -+ -+## example -+`ubus call hostapd.wl5-fb switch_chan '{ "freq": 5180, "bcn_count": 10, "center_freq1": 5210, "bandwidth": 80, "he": 1, "block_tx": 1, "csa_force": 0 }'` -+ -+ -+## update_airtime -+Set dynamic airtime weight for client. -+ -+### arguments -+| Name | Type | Required | Description | -+|---|---|---|---| -+| sta | string | yes | client MAC address | -+| weight | int32 | yes | airtime weight | -+ -+ -+## update_beacon -+Force beacon frame content to be updated and to start beaconing on an interface that uses start_disabled=1. -+ -+### example -+`ubus call hostapd.wl5-fb update_beacon` -+ -+ -+## wps_status -+Get WPS status for BSS. -+ -+### example -+`ubus call hostapd.wl5-fb wps_status` -+ -+### output -+```json -+{ -+ "pbc_status": "Disabled", -+ "last_wps_result": "None" -+} -+``` -+ -+ -+## wps_cancel -+Cancel WPS Push Button Configuration. -+ -+### example -+`ubus call hostapd.wl5-fb wps_cancel` -+ -+ -+## wps_start -+Start WPS Push Button Configuration. -+ -+### example -+`ubus call hostapd.wl5-fb wps_start` -diff --git a/package/network/services/hostapd/files/common.uc b/package/network/services/hostapd/files/common.uc -new file mode 100644 -index 0000000000..9ece3b1af2 ---- /dev/null -+++ b/package/network/services/hostapd/files/common.uc -@@ -0,0 +1,168 @@ -+import * as nl80211 from "nl80211"; -+import * as rtnl from "rtnl"; -+import { readfile } from "fs"; -+ -+const iftypes = { -+ ap: nl80211.const.NL80211_IFTYPE_AP, -+ mesh: nl80211.const.NL80211_IFTYPE_MESH_POINT, -+ sta: nl80211.const.NL80211_IFTYPE_STATION, -+ adhoc: nl80211.const.NL80211_IFTYPE_ADHOC, -+ monitor: nl80211.const.NL80211_IFTYPE_MONITOR, -+}; -+ -+function wdev_remove(name) -+{ -+ nl80211.request(nl80211.const.NL80211_CMD_DEL_INTERFACE, 0, { dev: name }); -+} -+ -+function __phy_is_fullmac(phyidx) -+{ -+ let data = nl80211.request(nl80211.const.NL80211_CMD_GET_WIPHY, 0, { wiphy: phyidx }); -+ -+ return !data.software_iftypes.ap_vlan; -+} -+ -+function phy_is_fullmac(phy) -+{ -+ let phyidx = int(trim(readfile(`/sys/class/ieee80211/${phy}/index`))); -+ -+ return __phy_is_fullmac(phyidx); -+} -+ -+function find_reusable_wdev(phyidx) -+{ -+ if (!__phy_is_fullmac(phyidx)) -+ return null; -+ -+ let data = nl80211.request( -+ nl80211.const.NL80211_CMD_GET_INTERFACE, -+ nl80211.const.NLM_F_DUMP, -+ { wiphy: phyidx }); -+ for (let res in data) -+ if (trim(readfile(`/sys/class/net/${res.ifname}/operstate`)) == "down") -+ return res.ifname; -+ return null; -+} -+ -+function wdev_create(phy, name, data) -+{ -+ let phyidx = int(readfile(`/sys/class/ieee80211/${phy}/index`)); -+ -+ wdev_remove(name); -+ -+ if (!iftypes[data.mode]) -+ return `Invalid mode: ${data.mode}`; -+ -+ let req = { -+ wiphy: phyidx, -+ ifname: name, -+ iftype: iftypes[data.mode], -+ }; -+ -+ if (data["4addr"]) -+ req["4addr"] = data["4addr"]; -+ if (data.macaddr) -+ req.mac = data.macaddr; -+ -+ nl80211.error(); -+ -+ let reuse_ifname = find_reusable_wdev(phyidx); -+ if (reuse_ifname && -+ (reuse_ifname == name || -+ rtnl.request(rtnl.const.RTM_SETLINK, 0, { dev: reuse_ifname, ifname: name}) != false)) -+ nl80211.request( -+ nl80211.const.NL80211_CMD_SET_INTERFACE, 0, { -+ wiphy: phyidx, -+ dev: name, -+ iftype: iftypes[data.mode], -+ }); -+ else -+ nl80211.request( -+ nl80211.const.NL80211_CMD_NEW_INTERFACE, -+ nl80211.const.NLM_F_CREATE, -+ req); -+ -+ let error = nl80211.error(); -+ if (error) -+ return error; -+ -+ if (data.powersave != null) { -+ nl80211.request(nl80211.const.NL80211_CMD_SET_POWER_SAVE, 0, -+ { dev: name, ps_state: data.powersave ? 1 : 0}); -+ } -+ -+ return null; -+} -+ -+const vlist_proto = { -+ update: function(values, arg) { -+ let data = this.data; -+ let cb = this.cb; -+ let seq = { }; -+ let new_data = {}; -+ let old_data = {}; -+ -+ this.data = new_data; -+ -+ if (type(values) == "object") { -+ for (let key in values) { -+ old_data[key] = data[key]; -+ new_data[key] = values[key]; -+ delete data[key]; -+ } -+ } else { -+ for (let val in values) { -+ let cur_key = val[0]; -+ let cur_obj = val[1]; -+ -+ old_data[cur_key] = data[cur_key]; -+ new_data[cur_key] = val[1]; -+ delete data[cur_key]; -+ } -+ } -+ -+ for (let key in data) { -+ cb(null, data[key], arg); -+ delete data[key]; -+ } -+ for (let key in new_data) -+ cb(new_data[key], old_data[key], arg); -+ } -+}; -+ -+function is_equal(val1, val2) { -+ let t1 = type(val1); -+ -+ if (t1 != type(val2)) -+ return false; -+ -+ if (t1 == "array") { -+ if (length(val1) != length(val2)) -+ return false; -+ -+ for (let i = 0; i < length(val1); i++) -+ if (!is_equal(val1[i], val2[i])) -+ return false; -+ -+ return true; -+ } else if (t1 == "object") { -+ for (let key in val1) -+ if (!is_equal(val1[key], val2[key])) -+ return false; -+ for (let key in val2) -+ if (!val1[key]) -+ return false; -+ return true; -+ } else { -+ return val1 == val2; -+ } -+} -+ -+function vlist_new(cb) { -+ return proto({ -+ cb: cb, -+ data: {} -+ }, vlist_proto); -+} -+ -+export { wdev_remove, wdev_create, is_equal, vlist_new, phy_is_fullmac }; -diff --git a/package/network/services/hostapd/files/dhcp-get-server.sh b/package/network/services/hostapd/files/dhcp-get-server.sh -new file mode 100644 -index 0000000000..a1509ace2f ---- /dev/null -+++ b/package/network/services/hostapd/files/dhcp-get-server.sh -@@ -0,0 +1,2 @@ -+#!/bin/sh -+[ "$1" = bound ] && echo "$serverid" -diff --git a/package/network/services/hostapd/files/hostapd-basic.config b/package/network/services/hostapd/files/hostapd-basic.config -new file mode 100644 -index 0000000000..3d19d8f902 ---- /dev/null -+++ b/package/network/services/hostapd/files/hostapd-basic.config -@@ -0,0 +1,404 @@ -+# Example hostapd build time configuration -+# -+# This file lists the configuration options that are used when building the -+# hostapd binary. All lines starting with # are ignored. Configuration option -+# lines must be commented out complete, if they are not to be included, i.e., -+# just setting VARIABLE=n is not disabling that variable. -+# -+# This file is included in Makefile, so variables like CFLAGS and LIBS can also -+# be modified from here. In most cass, these lines should use += in order not -+# to override previous values of the variables. -+ -+# Driver interface for Host AP driver -+#CONFIG_DRIVER_HOSTAP=y -+ -+# Driver interface for wired authenticator -+CONFIG_DRIVER_WIRED=y -+ -+# Driver interface for drivers using the nl80211 kernel interface -+CONFIG_DRIVER_NL80211=y -+ -+# QCA vendor extensions to nl80211 -+#CONFIG_DRIVER_NL80211_QCA=y -+ -+# driver_nl80211.c requires libnl. If you are compiling it yourself -+# you may need to point hostapd to your version of libnl. -+# -+#CFLAGS += -I$ -+#LIBS += -L$ -+ -+# Use libnl v2.0 (or 3.0) libraries. -+#CONFIG_LIBNL20=y -+ -+# Use libnl 3.2 libraries (if this is selected, CONFIG_LIBNL20 is ignored) -+#CONFIG_LIBNL32=y -+ -+ -+# Driver interface for FreeBSD net80211 layer (e.g., Atheros driver) -+#CONFIG_DRIVER_BSD=y -+#CFLAGS += -I/usr/local/include -+#LIBS += -L/usr/local/lib -+#LIBS_p += -L/usr/local/lib -+#LIBS_c += -L/usr/local/lib -+ -+# Driver interface for no driver (e.g., RADIUS server only) -+#CONFIG_DRIVER_NONE=y -+ -+# IEEE 802.11F/IAPP -+#CONFIG_IAPP=y -+ -+# WPA2/IEEE 802.11i RSN pre-authentication -+CONFIG_RSN_PREAUTH=y -+ -+# IEEE 802.11w (management frame protection) -+#CONFIG_IEEE80211W=y -+ -+# Support Operating Channel Validation -+CONFIG_OCV=y -+ -+# Integrated EAP server -+#CONFIG_EAP=y -+ -+# EAP Re-authentication Protocol (ERP) in integrated EAP server -+#CONFIG_ERP=y -+ -+# EAP-MD5 for the integrated EAP server -+#CONFIG_EAP_MD5=y -+ -+# EAP-TLS for the integrated EAP server -+#CONFIG_EAP_TLS=y -+ -+# EAP-MSCHAPv2 for the integrated EAP server -+#CONFIG_EAP_MSCHAPV2=y -+ -+# EAP-PEAP for the integrated EAP server -+#CONFIG_EAP_PEAP=y -+ -+# EAP-GTC for the integrated EAP server -+#CONFIG_EAP_GTC=y -+ -+# EAP-TTLS for the integrated EAP server -+#CONFIG_EAP_TTLS=y -+ -+# EAP-SIM for the integrated EAP server -+#CONFIG_EAP_SIM=y -+ -+# EAP-AKA for the integrated EAP server -+#CONFIG_EAP_AKA=y -+ -+# EAP-AKA' for the integrated EAP server -+# This requires CONFIG_EAP_AKA to be enabled, too. -+#CONFIG_EAP_AKA_PRIME=y -+ -+# EAP-PAX for the integrated EAP server -+#CONFIG_EAP_PAX=y -+ -+# EAP-PSK for the integrated EAP server (this is _not_ needed for WPA-PSK) -+#CONFIG_EAP_PSK=y -+ -+# EAP-pwd for the integrated EAP server (secure authentication with a password) -+#CONFIG_EAP_PWD=y -+ -+# EAP-SAKE for the integrated EAP server -+#CONFIG_EAP_SAKE=y -+ -+# EAP-GPSK for the integrated EAP server -+#CONFIG_EAP_GPSK=y -+# Include support for optional SHA256 cipher suite in EAP-GPSK -+#CONFIG_EAP_GPSK_SHA256=y -+ -+# EAP-FAST for the integrated EAP server -+#CONFIG_EAP_FAST=y -+ -+# EAP-TEAP for the integrated EAP server -+# Note: The current EAP-TEAP implementation is experimental and should not be -+# enabled for production use. The IETF RFC 7170 that defines EAP-TEAP has number -+# of conflicting statements and missing details and the implementation has -+# vendor specific workarounds for those and as such, may not interoperate with -+# any other implementation. This should not be used for anything else than -+# experimentation and interoperability testing until those issues has been -+# resolved. -+#CONFIG_EAP_TEAP=y -+ -+# Wi-Fi Protected Setup (WPS) -+#CONFIG_WPS=y -+# Enable UPnP support for external WPS Registrars -+#CONFIG_WPS_UPNP=y -+# Enable WPS support with NFC config method -+#CONFIG_WPS_NFC=y -+ -+# EAP-IKEv2 -+#CONFIG_EAP_IKEV2=y -+ -+# Trusted Network Connect (EAP-TNC) -+#CONFIG_EAP_TNC=y -+ -+# EAP-EKE for the integrated EAP server -+#CONFIG_EAP_EKE=y -+ -+# PKCS#12 (PFX) support (used to read private key and certificate file from -+# a file that usually has extension .p12 or .pfx) -+#CONFIG_PKCS12=y -+ -+# RADIUS authentication server. This provides access to the integrated EAP -+# server from external hosts using RADIUS. -+#CONFIG_RADIUS_SERVER=y -+ -+# Build IPv6 support for RADIUS operations -+#CONFIG_IPV6=y -+ -+# IEEE Std 802.11r-2008 (Fast BSS Transition) -+CONFIG_IEEE80211R=y -+ -+# Use the hostapd's IEEE 802.11 authentication (ACL), but without -+# the IEEE 802.11 Management capability (e.g., FreeBSD/net80211) -+#CONFIG_DRIVER_RADIUS_ACL=y -+ -+# IEEE 802.11n (High Throughput) support -+CONFIG_IEEE80211N=y -+ -+# Wireless Network Management (IEEE Std 802.11v-2011) -+# Note: This is experimental and not complete implementation. -+#CONFIG_WNM=y -+ -+# IEEE 802.11ac (Very High Throughput) support -+CONFIG_IEEE80211AC=y -+ -+# IEEE 802.11ax HE support -+# Note: This is experimental and work in progress. The definitions are still -+# subject to change and this should not be expected to interoperate with the -+# final IEEE 802.11ax version. -+#CONFIG_IEEE80211AX=y -+ -+# Remove debugging code that is printing out debug messages to stdout. -+# This can be used to reduce the size of the hostapd considerably if debugging -+# code is not needed. -+#CONFIG_NO_STDOUT_DEBUG=y -+ -+# Add support for writing debug log to a file: -f /tmp/hostapd.log -+# Disabled by default. -+#CONFIG_DEBUG_FILE=y -+ -+# Send debug messages to syslog instead of stdout -+CONFIG_DEBUG_SYSLOG=y -+ -+# Add support for sending all debug messages (regardless of debug verbosity) -+# to the Linux kernel tracing facility. This helps debug the entire stack by -+# making it easy to record everything happening from the driver up into the -+# same file, e.g., using trace-cmd. -+#CONFIG_DEBUG_LINUX_TRACING=y -+ -+# Remove support for RADIUS accounting -+CONFIG_NO_ACCOUNTING=y -+ -+# Remove support for RADIUS -+CONFIG_NO_RADIUS=y -+ -+# Remove support for VLANs -+#CONFIG_NO_VLAN=y -+ -+# Enable support for fully dynamic VLANs. This enables hostapd to -+# automatically create bridge and VLAN interfaces if necessary. -+#CONFIG_FULL_DYNAMIC_VLAN=y -+ -+# Use netlink-based kernel API for VLAN operations instead of ioctl() -+# Note: This requires libnl 3.1 or newer. -+#CONFIG_VLAN_NETLINK=y -+ -+# Remove support for dumping internal state through control interface commands -+# This can be used to reduce binary size at the cost of disabling a debugging -+# option. -+CONFIG_NO_DUMP_STATE=y -+ -+# Enable tracing code for developer debugging -+# This tracks use of memory allocations and other registrations and reports -+# incorrect use with a backtrace of call (or allocation) location. -+#CONFIG_WPA_TRACE=y -+# For BSD, comment out these. -+#LIBS += -lexecinfo -+#LIBS_p += -lexecinfo -+#LIBS_c += -lexecinfo -+ -+# Use libbfd to get more details for developer debugging -+# This enables use of libbfd to get more detailed symbols for the backtraces -+# generated by CONFIG_WPA_TRACE=y. -+#CONFIG_WPA_TRACE_BFD=y -+# For BSD, comment out these. -+#LIBS += -lbfd -liberty -lz -+#LIBS_p += -lbfd -liberty -lz -+#LIBS_c += -lbfd -liberty -lz -+ -+# hostapd depends on strong random number generation being available from the -+# operating system. os_get_random() function is used to fetch random data when -+# needed, e.g., for key generation. On Linux and BSD systems, this works by -+# reading /dev/urandom. It should be noted that the OS entropy pool needs to be -+# properly initialized before hostapd is started. This is important especially -+# on embedded devices that do not have a hardware random number generator and -+# may by default start up with minimal entropy available for random number -+# generation. -+# -+# As a safety net, hostapd is by default trying to internally collect -+# additional entropy for generating random data to mix in with the data -+# fetched from the OS. This by itself is not considered to be very strong, but -+# it may help in cases where the system pool is not initialized properly. -+# However, it is very strongly recommended that the system pool is initialized -+# with enough entropy either by using hardware assisted random number -+# generator or by storing state over device reboots. -+# -+# hostapd can be configured to maintain its own entropy store over restarts to -+# enhance random number generation. This is not perfect, but it is much more -+# secure than using the same sequence of random numbers after every reboot. -+# This can be enabled with -e command line option. The specified -+# file needs to be readable and writable by hostapd. -+# -+# If the os_get_random() is known to provide strong random data (e.g., on -+# Linux/BSD, the board in question is known to have reliable source of random -+# data from /dev/urandom), the internal hostapd random pool can be disabled. -+# This will save some in binary size and CPU use. However, this should only be -+# considered for builds that are known to be used on devices that meet the -+# requirements described above. -+CONFIG_NO_RANDOM_POOL=y -+ -+# Should we attempt to use the getrandom(2) call that provides more reliable -+# yet secure randomness source than /dev/random on Linux 3.17 and newer. -+# Requires glibc 2.25 to build, falls back to /dev/random if unavailable. -+CONFIG_GETRANDOM=y -+ -+# Should we use poll instead of select? Select is used by default. -+#CONFIG_ELOOP_POLL=y -+ -+# Should we use epoll instead of select? Select is used by default. -+CONFIG_ELOOP_EPOLL=y -+ -+# Should we use kqueue instead of select? Select is used by default. -+#CONFIG_ELOOP_KQUEUE=y -+ -+# Select TLS implementation -+# openssl = OpenSSL (default) -+# gnutls = GnuTLS -+# internal = Internal TLSv1 implementation (experimental) -+# linux = Linux kernel AF_ALG and internal TLSv1 implementation (experimental) -+# none = Empty template -+CONFIG_TLS=internal -+ -+# TLS-based EAP methods require at least TLS v1.0. Newer version of TLS (v1.1) -+# can be enabled to get a stronger construction of messages when block ciphers -+# are used. -+#CONFIG_TLSV11=y -+ -+# TLS-based EAP methods require at least TLS v1.0. Newer version of TLS (v1.2) -+# can be enabled to enable use of stronger crypto algorithms. -+#CONFIG_TLSV12=y -+ -+# Select which ciphers to use by default with OpenSSL if the user does not -+# specify them. -+#CONFIG_TLS_DEFAULT_CIPHERS="DEFAULT:!EXP:!LOW" -+ -+# If CONFIG_TLS=internal is used, additional library and include paths are -+# needed for LibTomMath. Alternatively, an integrated, minimal version of -+# LibTomMath can be used. See beginning of libtommath.c for details on benefits -+# and drawbacks of this option. -+#CONFIG_INTERNAL_LIBTOMMATH=y -+#ifndef CONFIG_INTERNAL_LIBTOMMATH -+#LTM_PATH=/usr/src/libtommath-0.39 -+#CFLAGS += -I$(LTM_PATH) -+#LIBS += -L$(LTM_PATH) -+#LIBS_p += -L$(LTM_PATH) -+#endif -+# At the cost of about 4 kB of additional binary size, the internal LibTomMath -+# can be configured to include faster routines for exptmod, sqr, and div to -+# speed up DH and RSA calculation considerably -+#CONFIG_INTERNAL_LIBTOMMATH_FAST=y -+ -+# Interworking (IEEE 802.11u) -+# This can be used to enable functionality to improve interworking with -+# external networks. -+#CONFIG_INTERWORKING=y -+ -+# Hotspot 2.0 -+#CONFIG_HS20=y -+ -+# Enable SQLite database support in hlr_auc_gw, EAP-SIM DB, and eap_user_file -+#CONFIG_SQLITE=y -+ -+# Enable Fast Session Transfer (FST) -+#CONFIG_FST=y -+ -+# Enable CLI commands for FST testing -+#CONFIG_FST_TEST=y -+ -+# Testing options -+# This can be used to enable some testing options (see also the example -+# configuration file) that are really useful only for testing clients that -+# connect to this hostapd. These options allow, for example, to drop a -+# certain percentage of probe requests or auth/(re)assoc frames. -+# -+#CONFIG_TESTING_OPTIONS=y -+ -+# Automatic Channel Selection -+# This will allow hostapd to pick the channel automatically when channel is set -+# to "acs_survey" or "0". Eventually, other ACS algorithms can be added in -+# similar way. -+# -+# Automatic selection is currently only done through initialization, later on -+# we hope to do background checks to keep us moving to more ideal channels as -+# time goes by. ACS is currently only supported through the nl80211 driver and -+# your driver must have survey dump capability that is filled by the driver -+# during scanning. -+# -+# You can customize the ACS survey algorithm with the hostapd.conf variable -+# acs_num_scans. -+# -+# Supported ACS drivers: -+# * ath9k -+# * ath5k -+# * ath10k -+# -+# For more details refer to: -+# http://wireless.kernel.org/en/users/Documentation/acs -+# -+#CONFIG_ACS=y -+ -+# Multiband Operation support -+# These extentions facilitate efficient use of multiple frequency bands -+# available to the AP and the devices that may associate with it. -+#CONFIG_MBO=y -+ -+# Client Taxonomy -+# Has the AP retain the Probe Request and (Re)Association Request frames from -+# a client, from which a signature can be produced which can identify the model -+# of client device like "Nexus 6P" or "iPhone 5s". -+#CONFIG_TAXONOMY=y -+ -+# Fast Initial Link Setup (FILS) (IEEE 802.11ai) -+#CONFIG_FILS=y -+# FILS shared key authentication with PFS -+#CONFIG_FILS_SK_PFS=y -+ -+# Include internal line edit mode in hostapd_cli. This can be used to provide -+# limited command line editing and history support. -+#CONFIG_WPA_CLI_EDIT=y -+ -+# Opportunistic Wireless Encryption (OWE) -+# Experimental implementation of draft-harkins-owe-07.txt -+#CONFIG_OWE=y -+ -+# Airtime policy support -+CONFIG_AIRTIME_POLICY=y -+ -+# Proxy ARP support -+#CONFIG_PROXYARP=y -+ -+# Override default value for the wpa_disable_eapol_key_retries configuration -+# parameter. See that parameter in hostapd.conf for more details. -+#CFLAGS += -DDEFAULT_WPA_DISABLE_EAPOL_KEY_RETRIES=1 -+ -+# uBus IPC/RPC System -+# Services can connect to the bus and provide methods -+# that can be called by other services or clients. -+CONFIG_UBUS=y -+ -+# OpenWrt patch 380-disable-ctrl-iface-mib.patch -+# leads to the MIB only being compiled in if -+# CONFIG_CTRL_IFACE_MIB is enabled. -+#CONFIG_CTRL_IFACE_MIB=y -diff --git a/package/network/services/hostapd/files/hostapd-full.config b/package/network/services/hostapd/files/hostapd-full.config -new file mode 100644 -index 0000000000..9076ebc44f ---- /dev/null -+++ b/package/network/services/hostapd/files/hostapd-full.config -@@ -0,0 +1,404 @@ -+# Example hostapd build time configuration -+# -+# This file lists the configuration options that are used when building the -+# hostapd binary. All lines starting with # are ignored. Configuration option -+# lines must be commented out complete, if they are not to be included, i.e., -+# just setting VARIABLE=n is not disabling that variable. -+# -+# This file is included in Makefile, so variables like CFLAGS and LIBS can also -+# be modified from here. In most cass, these lines should use += in order not -+# to override previous values of the variables. -+ -+# Driver interface for Host AP driver -+#CONFIG_DRIVER_HOSTAP=y -+ -+# Driver interface for wired authenticator -+CONFIG_DRIVER_WIRED=y -+ -+# Driver interface for drivers using the nl80211 kernel interface -+CONFIG_DRIVER_NL80211=y -+ -+# QCA vendor extensions to nl80211 -+#CONFIG_DRIVER_NL80211_QCA=y -+ -+# driver_nl80211.c requires libnl. If you are compiling it yourself -+# you may need to point hostapd to your version of libnl. -+# -+#CFLAGS += -I$ -+#LIBS += -L$ -+ -+# Use libnl v2.0 (or 3.0) libraries. -+#CONFIG_LIBNL20=y -+ -+# Use libnl 3.2 libraries (if this is selected, CONFIG_LIBNL20 is ignored) -+#CONFIG_LIBNL32=y -+ -+ -+# Driver interface for FreeBSD net80211 layer (e.g., Atheros driver) -+#CONFIG_DRIVER_BSD=y -+#CFLAGS += -I/usr/local/include -+#LIBS += -L/usr/local/lib -+#LIBS_p += -L/usr/local/lib -+#LIBS_c += -L/usr/local/lib -+ -+# Driver interface for no driver (e.g., RADIUS server only) -+#CONFIG_DRIVER_NONE=y -+ -+# IEEE 802.11F/IAPP -+CONFIG_IAPP=y -+ -+# WPA2/IEEE 802.11i RSN pre-authentication -+CONFIG_RSN_PREAUTH=y -+ -+# IEEE 802.11w (management frame protection) -+#CONFIG_IEEE80211W=y -+ -+# Support Operating Channel Validation -+CONFIG_OCV=y -+ -+# Integrated EAP server -+CONFIG_EAP=y -+ -+# EAP Re-authentication Protocol (ERP) in integrated EAP server -+CONFIG_ERP=y -+ -+# EAP-MD5 for the integrated EAP server -+CONFIG_EAP_MD5=y -+ -+# EAP-TLS for the integrated EAP server -+CONFIG_EAP_TLS=y -+ -+# EAP-MSCHAPv2 for the integrated EAP server -+CONFIG_EAP_MSCHAPV2=y -+ -+# EAP-PEAP for the integrated EAP server -+CONFIG_EAP_PEAP=y -+ -+# EAP-GTC for the integrated EAP server -+CONFIG_EAP_GTC=y -+ -+# EAP-TTLS for the integrated EAP server -+CONFIG_EAP_TTLS=y -+ -+# EAP-SIM for the integrated EAP server -+#CONFIG_EAP_SIM=y -+ -+# EAP-AKA for the integrated EAP server -+#CONFIG_EAP_AKA=y -+ -+# EAP-AKA' for the integrated EAP server -+# This requires CONFIG_EAP_AKA to be enabled, too. -+#CONFIG_EAP_AKA_PRIME=y -+ -+# EAP-PAX for the integrated EAP server -+#CONFIG_EAP_PAX=y -+ -+# EAP-PSK for the integrated EAP server (this is _not_ needed for WPA-PSK) -+#CONFIG_EAP_PSK=y -+ -+# EAP-pwd for the integrated EAP server (secure authentication with a password) -+#CONFIG_EAP_PWD=y -+ -+# EAP-SAKE for the integrated EAP server -+#CONFIG_EAP_SAKE=y -+ -+# EAP-GPSK for the integrated EAP server -+#CONFIG_EAP_GPSK=y -+# Include support for optional SHA256 cipher suite in EAP-GPSK -+#CONFIG_EAP_GPSK_SHA256=y -+ -+# EAP-FAST for the integrated EAP server -+CONFIG_EAP_FAST=y -+ -+# EAP-TEAP for the integrated EAP server -+# Note: The current EAP-TEAP implementation is experimental and should not be -+# enabled for production use. The IETF RFC 7170 that defines EAP-TEAP has number -+# of conflicting statements and missing details and the implementation has -+# vendor specific workarounds for those and as such, may not interoperate with -+# any other implementation. This should not be used for anything else than -+# experimentation and interoperability testing until those issues has been -+# resolved. -+#CONFIG_EAP_TEAP=y -+ -+# Wi-Fi Protected Setup (WPS) -+CONFIG_WPS=y -+# Enable UPnP support for external WPS Registrars -+#CONFIG_WPS_UPNP=y -+# Enable WPS support with NFC config method -+#CONFIG_WPS_NFC=y -+ -+# EAP-IKEv2 -+#CONFIG_EAP_IKEV2=y -+ -+# Trusted Network Connect (EAP-TNC) -+#CONFIG_EAP_TNC=y -+ -+# EAP-EKE for the integrated EAP server -+#CONFIG_EAP_EKE=y -+ -+# PKCS#12 (PFX) support (used to read private key and certificate file from -+# a file that usually has extension .p12 or .pfx) -+CONFIG_PKCS12=y -+ -+# RADIUS authentication server. This provides access to the integrated EAP -+# server from external hosts using RADIUS. -+CONFIG_RADIUS_SERVER=y -+ -+# Build IPv6 support for RADIUS operations -+CONFIG_IPV6=y -+ -+# IEEE Std 802.11r-2008 (Fast BSS Transition) -+CONFIG_IEEE80211R=y -+ -+# Use the hostapd's IEEE 802.11 authentication (ACL), but without -+# the IEEE 802.11 Management capability (e.g., FreeBSD/net80211) -+#CONFIG_DRIVER_RADIUS_ACL=y -+ -+# IEEE 802.11n (High Throughput) support -+CONFIG_IEEE80211N=y -+ -+# Wireless Network Management (IEEE Std 802.11v-2011) -+# Note: This is experimental and not complete implementation. -+CONFIG_WNM=y -+ -+# IEEE 802.11ac (Very High Throughput) support -+CONFIG_IEEE80211AC=y -+ -+# IEEE 802.11ax HE support -+# Note: This is experimental and work in progress. The definitions are still -+# subject to change and this should not be expected to interoperate with the -+# final IEEE 802.11ax version. -+#CONFIG_IEEE80211AX=y -+ -+# Remove debugging code that is printing out debug messages to stdout. -+# This can be used to reduce the size of the hostapd considerably if debugging -+# code is not needed. -+#CONFIG_NO_STDOUT_DEBUG=y -+ -+# Add support for writing debug log to a file: -f /tmp/hostapd.log -+# Disabled by default. -+#CONFIG_DEBUG_FILE=y -+ -+# Send debug messages to syslog instead of stdout -+CONFIG_DEBUG_SYSLOG=y -+ -+# Add support for sending all debug messages (regardless of debug verbosity) -+# to the Linux kernel tracing facility. This helps debug the entire stack by -+# making it easy to record everything happening from the driver up into the -+# same file, e.g., using trace-cmd. -+#CONFIG_DEBUG_LINUX_TRACING=y -+ -+# Remove support for RADIUS accounting -+#CONFIG_NO_ACCOUNTING=y -+ -+# Remove support for RADIUS -+#CONFIG_NO_RADIUS=y -+ -+# Remove support for VLANs -+#CONFIG_NO_VLAN=y -+ -+# Enable support for fully dynamic VLANs. This enables hostapd to -+# automatically create bridge and VLAN interfaces if necessary. -+CONFIG_FULL_DYNAMIC_VLAN=y -+ -+# Use netlink-based kernel API for VLAN operations instead of ioctl() -+# Note: This requires libnl 3.1 or newer. -+#CONFIG_VLAN_NETLINK=y -+ -+# Remove support for dumping internal state through control interface commands -+# This can be used to reduce binary size at the cost of disabling a debugging -+# option. -+CONFIG_NO_DUMP_STATE=y -+ -+# Enable tracing code for developer debugging -+# This tracks use of memory allocations and other registrations and reports -+# incorrect use with a backtrace of call (or allocation) location. -+#CONFIG_WPA_TRACE=y -+# For BSD, comment out these. -+#LIBS += -lexecinfo -+#LIBS_p += -lexecinfo -+#LIBS_c += -lexecinfo -+ -+# Use libbfd to get more details for developer debugging -+# This enables use of libbfd to get more detailed symbols for the backtraces -+# generated by CONFIG_WPA_TRACE=y. -+#CONFIG_WPA_TRACE_BFD=y -+# For BSD, comment out these. -+#LIBS += -lbfd -liberty -lz -+#LIBS_p += -lbfd -liberty -lz -+#LIBS_c += -lbfd -liberty -lz -+ -+# hostapd depends on strong random number generation being available from the -+# operating system. os_get_random() function is used to fetch random data when -+# needed, e.g., for key generation. On Linux and BSD systems, this works by -+# reading /dev/urandom. It should be noted that the OS entropy pool needs to be -+# properly initialized before hostapd is started. This is important especially -+# on embedded devices that do not have a hardware random number generator and -+# may by default start up with minimal entropy available for random number -+# generation. -+# -+# As a safety net, hostapd is by default trying to internally collect -+# additional entropy for generating random data to mix in with the data -+# fetched from the OS. This by itself is not considered to be very strong, but -+# it may help in cases where the system pool is not initialized properly. -+# However, it is very strongly recommended that the system pool is initialized -+# with enough entropy either by using hardware assisted random number -+# generator or by storing state over device reboots. -+# -+# hostapd can be configured to maintain its own entropy store over restarts to -+# enhance random number generation. This is not perfect, but it is much more -+# secure than using the same sequence of random numbers after every reboot. -+# This can be enabled with -e command line option. The specified -+# file needs to be readable and writable by hostapd. -+# -+# If the os_get_random() is known to provide strong random data (e.g., on -+# Linux/BSD, the board in question is known to have reliable source of random -+# data from /dev/urandom), the internal hostapd random pool can be disabled. -+# This will save some in binary size and CPU use. However, this should only be -+# considered for builds that are known to be used on devices that meet the -+# requirements described above. -+CONFIG_NO_RANDOM_POOL=y -+ -+# Should we attempt to use the getrandom(2) call that provides more reliable -+# yet secure randomness source than /dev/random on Linux 3.17 and newer. -+# Requires glibc 2.25 to build, falls back to /dev/random if unavailable. -+CONFIG_GETRANDOM=y -+ -+# Should we use poll instead of select? Select is used by default. -+#CONFIG_ELOOP_POLL=y -+ -+# Should we use epoll instead of select? Select is used by default. -+CONFIG_ELOOP_EPOLL=y -+ -+# Should we use kqueue instead of select? Select is used by default. -+#CONFIG_ELOOP_KQUEUE=y -+ -+# Select TLS implementation -+# openssl = OpenSSL (default) -+# gnutls = GnuTLS -+# internal = Internal TLSv1 implementation (experimental) -+# linux = Linux kernel AF_ALG and internal TLSv1 implementation (experimental) -+# none = Empty template -+CONFIG_TLS=internal -+ -+# TLS-based EAP methods require at least TLS v1.0. Newer version of TLS (v1.1) -+# can be enabled to get a stronger construction of messages when block ciphers -+# are used. -+#CONFIG_TLSV11=y -+ -+# TLS-based EAP methods require at least TLS v1.0. Newer version of TLS (v1.2) -+# can be enabled to enable use of stronger crypto algorithms. -+#CONFIG_TLSV12=y -+ -+# Select which ciphers to use by default with OpenSSL if the user does not -+# specify them. -+#CONFIG_TLS_DEFAULT_CIPHERS="DEFAULT:!EXP:!LOW" -+ -+# If CONFIG_TLS=internal is used, additional library and include paths are -+# needed for LibTomMath. Alternatively, an integrated, minimal version of -+# LibTomMath can be used. See beginning of libtommath.c for details on benefits -+# and drawbacks of this option. -+CONFIG_INTERNAL_LIBTOMMATH=y -+#ifndef CONFIG_INTERNAL_LIBTOMMATH -+#LTM_PATH=/usr/src/libtommath-0.39 -+#CFLAGS += -I$(LTM_PATH) -+#LIBS += -L$(LTM_PATH) -+#LIBS_p += -L$(LTM_PATH) -+#endif -+# At the cost of about 4 kB of additional binary size, the internal LibTomMath -+# can be configured to include faster routines for exptmod, sqr, and div to -+# speed up DH and RSA calculation considerably -+#CONFIG_INTERNAL_LIBTOMMATH_FAST=y -+ -+# Interworking (IEEE 802.11u) -+# This can be used to enable functionality to improve interworking with -+# external networks. -+CONFIG_INTERWORKING=y -+ -+# Hotspot 2.0 -+CONFIG_HS20=y -+ -+# Enable SQLite database support in hlr_auc_gw, EAP-SIM DB, and eap_user_file -+#CONFIG_SQLITE=y -+ -+# Enable Fast Session Transfer (FST) -+#CONFIG_FST=y -+ -+# Enable CLI commands for FST testing -+#CONFIG_FST_TEST=y -+ -+# Testing options -+# This can be used to enable some testing options (see also the example -+# configuration file) that are really useful only for testing clients that -+# connect to this hostapd. These options allow, for example, to drop a -+# certain percentage of probe requests or auth/(re)assoc frames. -+# -+#CONFIG_TESTING_OPTIONS=y -+ -+# Automatic Channel Selection -+# This will allow hostapd to pick the channel automatically when channel is set -+# to "acs_survey" or "0". Eventually, other ACS algorithms can be added in -+# similar way. -+# -+# Automatic selection is currently only done through initialization, later on -+# we hope to do background checks to keep us moving to more ideal channels as -+# time goes by. ACS is currently only supported through the nl80211 driver and -+# your driver must have survey dump capability that is filled by the driver -+# during scanning. -+# -+# You can customize the ACS survey algorithm with the hostapd.conf variable -+# acs_num_scans. -+# -+# Supported ACS drivers: -+# * ath9k -+# * ath5k -+# * ath10k -+# -+# For more details refer to: -+# http://wireless.kernel.org/en/users/Documentation/acs -+# -+#CONFIG_ACS=y -+ -+# Multiband Operation support -+# These extentions facilitate efficient use of multiple frequency bands -+# available to the AP and the devices that may associate with it. -+#CONFIG_MBO=y -+ -+# Client Taxonomy -+# Has the AP retain the Probe Request and (Re)Association Request frames from -+# a client, from which a signature can be produced which can identify the model -+# of client device like "Nexus 6P" or "iPhone 5s". -+CONFIG_TAXONOMY=y -+ -+# Fast Initial Link Setup (FILS) (IEEE 802.11ai) -+#CONFIG_FILS=y -+# FILS shared key authentication with PFS -+#CONFIG_FILS_SK_PFS=y -+ -+# Include internal line edit mode in hostapd_cli. This can be used to provide -+# limited command line editing and history support. -+#CONFIG_WPA_CLI_EDIT=y -+ -+# Opportunistic Wireless Encryption (OWE) -+# Experimental implementation of draft-harkins-owe-07.txt -+#CONFIG_OWE=y -+ -+# Airtime policy support -+CONFIG_AIRTIME_POLICY=y -+ -+# Proxy ARP support -+CONFIG_PROXYARP=y -+ -+# Override default value for the wpa_disable_eapol_key_retries configuration -+# parameter. See that parameter in hostapd.conf for more details. -+#CFLAGS += -DDEFAULT_WPA_DISABLE_EAPOL_KEY_RETRIES=1 -+ -+# uBus IPC/RPC System -+# Services can connect to the bus and provide methods -+# that can be called by other services or clients. -+CONFIG_UBUS=y -+ -+# OpenWrt patch 380-disable-ctrl-iface-mib.patch -+# leads to the MIB only being compiled in if -+# CONFIG_CTRL_IFACE_MIB is enabled. -+CONFIG_CTRL_IFACE_MIB=y -diff --git a/package/network/services/hostapd/files/hostapd-mini.config b/package/network/services/hostapd/files/hostapd-mini.config -new file mode 100644 -index 0000000000..f2ed071ec0 ---- /dev/null -+++ b/package/network/services/hostapd/files/hostapd-mini.config -@@ -0,0 +1,404 @@ -+# Example hostapd build time configuration -+# -+# This file lists the configuration options that are used when building the -+# hostapd binary. All lines starting with # are ignored. Configuration option -+# lines must be commented out complete, if they are not to be included, i.e., -+# just setting VARIABLE=n is not disabling that variable. -+# -+# This file is included in Makefile, so variables like CFLAGS and LIBS can also -+# be modified from here. In most cass, these lines should use += in order not -+# to override previous values of the variables. -+ -+# Driver interface for Host AP driver -+#CONFIG_DRIVER_HOSTAP=y -+ -+# Driver interface for wired authenticator -+CONFIG_DRIVER_WIRED=y -+ -+# Driver interface for drivers using the nl80211 kernel interface -+CONFIG_DRIVER_NL80211=y -+ -+# QCA vendor extensions to nl80211 -+#CONFIG_DRIVER_NL80211_QCA=y -+ -+# driver_nl80211.c requires libnl. If you are compiling it yourself -+# you may need to point hostapd to your version of libnl. -+# -+#CFLAGS += -I$ -+#LIBS += -L$ -+ -+# Use libnl v2.0 (or 3.0) libraries. -+#CONFIG_LIBNL20=y -+ -+# Use libnl 3.2 libraries (if this is selected, CONFIG_LIBNL20 is ignored) -+#CONFIG_LIBNL32=y -+ -+ -+# Driver interface for FreeBSD net80211 layer (e.g., Atheros driver) -+#CONFIG_DRIVER_BSD=y -+#CFLAGS += -I/usr/local/include -+#LIBS += -L/usr/local/lib -+#LIBS_p += -L/usr/local/lib -+#LIBS_c += -L/usr/local/lib -+ -+# Driver interface for no driver (e.g., RADIUS server only) -+#CONFIG_DRIVER_NONE=y -+ -+# IEEE 802.11F/IAPP -+#CONFIG_IAPP=y -+ -+# WPA2/IEEE 802.11i RSN pre-authentication -+CONFIG_RSN_PREAUTH=y -+ -+# IEEE 802.11w (management frame protection) -+#CONFIG_IEEE80211W=y -+ -+# Support Operating Channel Validation -+#CONFIG_OCV=y -+ -+# Integrated EAP server -+#CONFIG_EAP=y -+ -+# EAP Re-authentication Protocol (ERP) in integrated EAP server -+#CONFIG_ERP=y -+ -+# EAP-MD5 for the integrated EAP server -+#CONFIG_EAP_MD5=y -+ -+# EAP-TLS for the integrated EAP server -+#CONFIG_EAP_TLS=y -+ -+# EAP-MSCHAPv2 for the integrated EAP server -+#CONFIG_EAP_MSCHAPV2=y -+ -+# EAP-PEAP for the integrated EAP server -+#CONFIG_EAP_PEAP=y -+ -+# EAP-GTC for the integrated EAP server -+#CONFIG_EAP_GTC=y -+ -+# EAP-TTLS for the integrated EAP server -+#CONFIG_EAP_TTLS=y -+ -+# EAP-SIM for the integrated EAP server -+#CONFIG_EAP_SIM=y -+ -+# EAP-AKA for the integrated EAP server -+#CONFIG_EAP_AKA=y -+ -+# EAP-AKA' for the integrated EAP server -+# This requires CONFIG_EAP_AKA to be enabled, too. -+#CONFIG_EAP_AKA_PRIME=y -+ -+# EAP-PAX for the integrated EAP server -+#CONFIG_EAP_PAX=y -+ -+# EAP-PSK for the integrated EAP server (this is _not_ needed for WPA-PSK) -+#CONFIG_EAP_PSK=y -+ -+# EAP-pwd for the integrated EAP server (secure authentication with a password) -+#CONFIG_EAP_PWD=y -+ -+# EAP-SAKE for the integrated EAP server -+#CONFIG_EAP_SAKE=y -+ -+# EAP-GPSK for the integrated EAP server -+#CONFIG_EAP_GPSK=y -+# Include support for optional SHA256 cipher suite in EAP-GPSK -+#CONFIG_EAP_GPSK_SHA256=y -+ -+# EAP-FAST for the integrated EAP server -+#CONFIG_EAP_FAST=y -+ -+# EAP-TEAP for the integrated EAP server -+# Note: The current EAP-TEAP implementation is experimental and should not be -+# enabled for production use. The IETF RFC 7170 that defines EAP-TEAP has number -+# of conflicting statements and missing details and the implementation has -+# vendor specific workarounds for those and as such, may not interoperate with -+# any other implementation. This should not be used for anything else than -+# experimentation and interoperability testing until those issues has been -+# resolved. -+#CONFIG_EAP_TEAP=y -+ -+# Wi-Fi Protected Setup (WPS) -+#CONFIG_WPS=y -+# Enable UPnP support for external WPS Registrars -+#CONFIG_WPS_UPNP=y -+# Enable WPS support with NFC config method -+#CONFIG_WPS_NFC=y -+ -+# EAP-IKEv2 -+#CONFIG_EAP_IKEV2=y -+ -+# Trusted Network Connect (EAP-TNC) -+#CONFIG_EAP_TNC=y -+ -+# EAP-EKE for the integrated EAP server -+#CONFIG_EAP_EKE=y -+ -+# PKCS#12 (PFX) support (used to read private key and certificate file from -+# a file that usually has extension .p12 or .pfx) -+#CONFIG_PKCS12=y -+ -+# RADIUS authentication server. This provides access to the integrated EAP -+# server from external hosts using RADIUS. -+#CONFIG_RADIUS_SERVER=y -+ -+# Build IPv6 support for RADIUS operations -+#CONFIG_IPV6=y -+ -+# IEEE Std 802.11r-2008 (Fast BSS Transition) -+#CONFIG_IEEE80211R=y -+ -+# Use the hostapd's IEEE 802.11 authentication (ACL), but without -+# the IEEE 802.11 Management capability (e.g., FreeBSD/net80211) -+#CONFIG_DRIVER_RADIUS_ACL=y -+ -+# IEEE 802.11n (High Throughput) support -+CONFIG_IEEE80211N=y -+ -+# Wireless Network Management (IEEE Std 802.11v-2011) -+# Note: This is experimental and not complete implementation. -+#CONFIG_WNM=y -+ -+# IEEE 802.11ac (Very High Throughput) support -+CONFIG_IEEE80211AC=y -+ -+# IEEE 802.11ax HE support -+# Note: This is experimental and work in progress. The definitions are still -+# subject to change and this should not be expected to interoperate with the -+# final IEEE 802.11ax version. -+#CONFIG_IEEE80211AX=y -+ -+# Remove debugging code that is printing out debug messages to stdout. -+# This can be used to reduce the size of the hostapd considerably if debugging -+# code is not needed. -+#CONFIG_NO_STDOUT_DEBUG=y -+ -+# Add support for writing debug log to a file: -f /tmp/hostapd.log -+# Disabled by default. -+#CONFIG_DEBUG_FILE=y -+ -+# Send debug messages to syslog instead of stdout -+CONFIG_DEBUG_SYSLOG=y -+ -+# Add support for sending all debug messages (regardless of debug verbosity) -+# to the Linux kernel tracing facility. This helps debug the entire stack by -+# making it easy to record everything happening from the driver up into the -+# same file, e.g., using trace-cmd. -+#CONFIG_DEBUG_LINUX_TRACING=y -+ -+# Remove support for RADIUS accounting -+CONFIG_NO_ACCOUNTING=y -+ -+# Remove support for RADIUS -+CONFIG_NO_RADIUS=y -+ -+# Remove support for VLANs -+#CONFIG_NO_VLAN=y -+ -+# Enable support for fully dynamic VLANs. This enables hostapd to -+# automatically create bridge and VLAN interfaces if necessary. -+#CONFIG_FULL_DYNAMIC_VLAN=y -+ -+# Use netlink-based kernel API for VLAN operations instead of ioctl() -+# Note: This requires libnl 3.1 or newer. -+#CONFIG_VLAN_NETLINK=y -+ -+# Remove support for dumping internal state through control interface commands -+# This can be used to reduce binary size at the cost of disabling a debugging -+# option. -+CONFIG_NO_DUMP_STATE=y -+ -+# Enable tracing code for developer debugging -+# This tracks use of memory allocations and other registrations and reports -+# incorrect use with a backtrace of call (or allocation) location. -+#CONFIG_WPA_TRACE=y -+# For BSD, comment out these. -+#LIBS += -lexecinfo -+#LIBS_p += -lexecinfo -+#LIBS_c += -lexecinfo -+ -+# Use libbfd to get more details for developer debugging -+# This enables use of libbfd to get more detailed symbols for the backtraces -+# generated by CONFIG_WPA_TRACE=y. -+#CONFIG_WPA_TRACE_BFD=y -+# For BSD, comment out these. -+#LIBS += -lbfd -liberty -lz -+#LIBS_p += -lbfd -liberty -lz -+#LIBS_c += -lbfd -liberty -lz -+ -+# hostapd depends on strong random number generation being available from the -+# operating system. os_get_random() function is used to fetch random data when -+# needed, e.g., for key generation. On Linux and BSD systems, this works by -+# reading /dev/urandom. It should be noted that the OS entropy pool needs to be -+# properly initialized before hostapd is started. This is important especially -+# on embedded devices that do not have a hardware random number generator and -+# may by default start up with minimal entropy available for random number -+# generation. -+# -+# As a safety net, hostapd is by default trying to internally collect -+# additional entropy for generating random data to mix in with the data -+# fetched from the OS. This by itself is not considered to be very strong, but -+# it may help in cases where the system pool is not initialized properly. -+# However, it is very strongly recommended that the system pool is initialized -+# with enough entropy either by using hardware assisted random number -+# generator or by storing state over device reboots. -+# -+# hostapd can be configured to maintain its own entropy store over restarts to -+# enhance random number generation. This is not perfect, but it is much more -+# secure than using the same sequence of random numbers after every reboot. -+# This can be enabled with -e command line option. The specified -+# file needs to be readable and writable by hostapd. -+# -+# If the os_get_random() is known to provide strong random data (e.g., on -+# Linux/BSD, the board in question is known to have reliable source of random -+# data from /dev/urandom), the internal hostapd random pool can be disabled. -+# This will save some in binary size and CPU use. However, this should only be -+# considered for builds that are known to be used on devices that meet the -+# requirements described above. -+CONFIG_NO_RANDOM_POOL=y -+ -+# Should we attempt to use the getrandom(2) call that provides more reliable -+# yet secure randomness source than /dev/random on Linux 3.17 and newer. -+# Requires glibc 2.25 to build, falls back to /dev/random if unavailable. -+CONFIG_GETRANDOM=y -+ -+# Should we use poll instead of select? Select is used by default. -+#CONFIG_ELOOP_POLL=y -+ -+# Should we use epoll instead of select? Select is used by default. -+CONFIG_ELOOP_EPOLL=y -+ -+# Should we use kqueue instead of select? Select is used by default. -+#CONFIG_ELOOP_KQUEUE=y -+ -+# Select TLS implementation -+# openssl = OpenSSL (default) -+# gnutls = GnuTLS -+# internal = Internal TLSv1 implementation (experimental) -+# linux = Linux kernel AF_ALG and internal TLSv1 implementation (experimental) -+# none = Empty template -+CONFIG_TLS=internal -+ -+# TLS-based EAP methods require at least TLS v1.0. Newer version of TLS (v1.1) -+# can be enabled to get a stronger construction of messages when block ciphers -+# are used. -+#CONFIG_TLSV11=y -+ -+# TLS-based EAP methods require at least TLS v1.0. Newer version of TLS (v1.2) -+# can be enabled to enable use of stronger crypto algorithms. -+#CONFIG_TLSV12=y -+ -+# Select which ciphers to use by default with OpenSSL if the user does not -+# specify them. -+#CONFIG_TLS_DEFAULT_CIPHERS="DEFAULT:!EXP:!LOW" -+ -+# If CONFIG_TLS=internal is used, additional library and include paths are -+# needed for LibTomMath. Alternatively, an integrated, minimal version of -+# LibTomMath can be used. See beginning of libtommath.c for details on benefits -+# and drawbacks of this option. -+#CONFIG_INTERNAL_LIBTOMMATH=y -+#ifndef CONFIG_INTERNAL_LIBTOMMATH -+#LTM_PATH=/usr/src/libtommath-0.39 -+#CFLAGS += -I$(LTM_PATH) -+#LIBS += -L$(LTM_PATH) -+#LIBS_p += -L$(LTM_PATH) -+#endif -+# At the cost of about 4 kB of additional binary size, the internal LibTomMath -+# can be configured to include faster routines for exptmod, sqr, and div to -+# speed up DH and RSA calculation considerably -+#CONFIG_INTERNAL_LIBTOMMATH_FAST=y -+ -+# Interworking (IEEE 802.11u) -+# This can be used to enable functionality to improve interworking with -+# external networks. -+#CONFIG_INTERWORKING=y -+ -+# Hotspot 2.0 -+#CONFIG_HS20=y -+ -+# Enable SQLite database support in hlr_auc_gw, EAP-SIM DB, and eap_user_file -+#CONFIG_SQLITE=y -+ -+# Enable Fast Session Transfer (FST) -+#CONFIG_FST=y -+ -+# Enable CLI commands for FST testing -+#CONFIG_FST_TEST=y -+ -+# Testing options -+# This can be used to enable some testing options (see also the example -+# configuration file) that are really useful only for testing clients that -+# connect to this hostapd. These options allow, for example, to drop a -+# certain percentage of probe requests or auth/(re)assoc frames. -+# -+#CONFIG_TESTING_OPTIONS=y -+ -+# Automatic Channel Selection -+# This will allow hostapd to pick the channel automatically when channel is set -+# to "acs_survey" or "0". Eventually, other ACS algorithms can be added in -+# similar way. -+# -+# Automatic selection is currently only done through initialization, later on -+# we hope to do background checks to keep us moving to more ideal channels as -+# time goes by. ACS is currently only supported through the nl80211 driver and -+# your driver must have survey dump capability that is filled by the driver -+# during scanning. -+# -+# You can customize the ACS survey algorithm with the hostapd.conf variable -+# acs_num_scans. -+# -+# Supported ACS drivers: -+# * ath9k -+# * ath5k -+# * ath10k -+# -+# For more details refer to: -+# http://wireless.kernel.org/en/users/Documentation/acs -+# -+#CONFIG_ACS=y -+ -+# Multiband Operation support -+# These extentions facilitate efficient use of multiple frequency bands -+# available to the AP and the devices that may associate with it. -+#CONFIG_MBO=y -+ -+# Client Taxonomy -+# Has the AP retain the Probe Request and (Re)Association Request frames from -+# a client, from which a signature can be produced which can identify the model -+# of client device like "Nexus 6P" or "iPhone 5s". -+#CONFIG_TAXONOMY=y -+ -+# Fast Initial Link Setup (FILS) (IEEE 802.11ai) -+#CONFIG_FILS=y -+# FILS shared key authentication with PFS -+#CONFIG_FILS_SK_PFS=y -+ -+# Include internal line edit mode in hostapd_cli. This can be used to provide -+# limited command line editing and history support. -+#CONFIG_WPA_CLI_EDIT=y -+ -+# Opportunistic Wireless Encryption (OWE) -+# Experimental implementation of draft-harkins-owe-07.txt -+#CONFIG_OWE=y -+ -+# Airtime policy support -+#CONFIG_AIRTIME_POLICY=y -+ -+# Proxy ARP support -+#CONFIG_PROXYARP=y -+ -+# Override default value for the wpa_disable_eapol_key_retries configuration -+# parameter. See that parameter in hostapd.conf for more details. -+#CFLAGS += -DDEFAULT_WPA_DISABLE_EAPOL_KEY_RETRIES=1 -+ -+# uBus IPC/RPC System -+# Services can connect to the bus and provide methods -+# that can be called by other services or clients. -+CONFIG_UBUS=y -+ -+# OpenWrt patch 380-disable-ctrl-iface-mib.patch -+# leads to the MIB only being compiled in if -+# CONFIG_CTRL_IFACE_MIB is enabled. -+#CONFIG_CTRL_IFACE_MIB=y -diff --git a/package/network/services/hostapd/files/hostapd.uc b/package/network/services/hostapd/files/hostapd.uc -new file mode 100644 -index 0000000000..f9f0c31bab ---- /dev/null -+++ b/package/network/services/hostapd/files/hostapd.uc -@@ -0,0 +1,486 @@ -+let libubus = require("ubus"); -+import { open, readfile } from "fs"; -+import { wdev_create, wdev_remove, is_equal, vlist_new, phy_is_fullmac } from "common"; -+ -+let ubus = libubus.connect(); -+ -+hostapd.data.config = {}; -+ -+hostapd.data.file_fields = { -+ vlan_file: true, -+ wpa_psk_file: true, -+ accept_mac_file: true, -+ deny_mac_file: true, -+ eap_user_file: true, -+ ca_cert: true, -+ server_cert: true, -+ server_cert2: true, -+ private_key: true, -+ private_key2: true, -+ dh_file: true, -+ eap_sim_db: true, -+}; -+ -+function iface_remove(cfg) -+{ -+ if (!cfg || !cfg.bss || !cfg.bss[0] || !cfg.bss[0].ifname) -+ return; -+ -+ hostapd.remove_iface(cfg.bss[0].ifname); -+ for (let bss in cfg.bss) -+ wdev_remove(bss.ifname); -+} -+ -+function iface_gen_config(phy, config) -+{ -+ let str = `data: -+${join("\n", config.radio.data)} -+channel=${config.radio.channel} -+`; -+ -+ for (let i = 0; i < length(config.bss); i++) { -+ let bss = config.bss[i]; -+ let type = i > 0 ? "bss" : "interface"; -+ -+ str += ` -+${type}=${bss.ifname} -+${join("\n", bss.data)} -+`; -+ } -+ -+ return str; -+} -+ -+function iface_restart(phy, config, old_config) -+{ -+ iface_remove(old_config); -+ iface_remove(config); -+ -+ if (!config.bss || !config.bss[0]) { -+ hostapd.printf(`No bss for phy ${phy}`); -+ return; -+ } -+ -+ let bss = config.bss[0]; -+ let err = wdev_create(phy, bss.ifname, { mode: "ap" }); -+ if (err) -+ hostapd.printf(`Failed to create ${bss.ifname} on phy ${phy}: ${err}`); -+ let config_inline = iface_gen_config(phy, config); -+ -+ let ubus = hostapd.data.ubus; -+ ubus.call("wpa_supplicant", "phy_set_state", { phy: phy, stop: true }); -+ if (hostapd.add_iface(`bss_config=${bss.ifname}:${config_inline}`) < 0) -+ hostapd.printf(`hostapd.add_iface failed for phy ${phy} ifname=${bss.ifname}`); -+ ubus.call("wpa_supplicant", "phy_set_state", { phy: phy, stop: false }); -+} -+ -+function array_to_obj(arr, key, start) -+{ -+ let obj = {}; -+ -+ start ??= 0; -+ for (let i = start; i < length(arr); i++) { -+ let cur = arr[i]; -+ obj[cur[key]] = cur; -+ } -+ -+ return obj; -+} -+ -+function find_array_idx(arr, key, val) -+{ -+ for (let i = 0; i < length(arr); i++) -+ if (arr[i][key] == val) -+ return i; -+ -+ return -1; -+} -+ -+function bss_reload_psk(bss, config, old_config) -+{ -+ if (is_equal(old_config.hash.wpa_psk_file, config.hash.wpa_psk_file)) -+ return; -+ -+ old_config.hash.wpa_psk_file = config.hash.wpa_psk_file; -+ if (!is_equal(old_config, config)) -+ return; -+ -+ let ret = bss.ctrl("RELOAD_WPA_PSK"); -+ ret ??= "failed"; -+ -+ hostapd.printf(`Reload WPA PSK file for bss ${config.ifname}: ${ret}`); -+} -+ -+function iface_reload_config(phy, config, old_config) -+{ -+ if (!old_config || !is_equal(old_config.radio, config.radio)) -+ return false; -+ -+ if (is_equal(old_config.bss, config.bss)) -+ return true; -+ -+ if (!old_config.bss || !old_config.bss[0]) -+ return false; -+ -+ if (config.bss[0].ifname != old_config.bss[0].ifname) -+ return false; -+ -+ let iface_name = config.bss[0].ifname; -+ let iface = hostapd.interfaces[iface_name]; -+ if (!iface) -+ return false; -+ -+ let first_bss = hostapd.bss[iface_name]; -+ if (!first_bss) -+ return false; -+ -+ let config_inline = iface_gen_config(phy, config); -+ -+ bss_reload_psk(first_bss, config.bss[0], old_config.bss[0]); -+ if (!is_equal(config.bss[0], old_config.bss[0])) { -+ if (phy_is_fullmac(phy)) -+ return false; -+ -+ if (config.bss[0].bssid != old_config.bss[0].bssid) -+ return false; -+ -+ hostapd.printf(`Reload config for bss '${config.bss[0].ifname}' on phy '${phy}'`); -+ if (first_bss.set_config(config_inline, 0) < 0) { -+ hostapd.printf(`Failed to set config`); -+ return false; -+ } -+ } -+ -+ let new_cfg = array_to_obj(config.bss, "ifname", 1); -+ let old_cfg = array_to_obj(old_config.bss, "ifname", 1); -+ -+ for (let name in old_cfg) { -+ let bss = hostapd.bss[name]; -+ if (!bss) { -+ hostapd.printf(`bss '${name}' not found`); -+ return false; -+ } -+ -+ if (!new_cfg[name]) { -+ hostapd.printf(`Remove bss '${name}' on phy '${phy}'`); -+ bss.delete(); -+ wdev_remove(name); -+ continue; -+ } -+ -+ let new_cfg_data = new_cfg[name]; -+ delete new_cfg[name]; -+ -+ if (is_equal(old_cfg[name], new_cfg_data)) -+ continue; -+ -+ hostapd.printf(`Reload config for bss '${name}' on phy '${phy}'`); -+ let idx = find_array_idx(config.bss, "ifname", name); -+ if (idx < 0) { -+ hostapd.printf(`bss index not found`); -+ return false; -+ } -+ -+ if (bss.set_config(config_inline, idx) < 0) { -+ hostapd.printf(`Failed to set config`); -+ return false; -+ } -+ } -+ -+ for (let name in new_cfg) { -+ hostapd.printf(`Add bss '${name}' on phy '${phy}'`); -+ -+ let idx = find_array_idx(config.bss, "ifname", name); -+ if (idx < 0) { -+ hostapd.printf(`bss index not found`); -+ return false; -+ } -+ -+ if (iface.add_bss(config_inline, idx) < 0) { -+ hostapd.printf(`Failed to add bss`); -+ return false; -+ } -+ } -+ -+ return true; -+} -+ -+function iface_set_config(phy, config) -+{ -+ let old_config = hostapd.data.config[phy]; -+ -+ hostapd.data.config[phy] = config; -+ -+ if (!config) -+ return iface_remove(old_config); -+ -+ let ret = iface_reload_config(phy, config, old_config); -+ if (ret) { -+ hostapd.printf(`Reloaded settings for phy ${phy}`); -+ return 0; -+ } -+ -+ hostapd.printf(`Restart interface for phy ${phy}`); -+ return iface_restart(phy, config, old_config); -+} -+ -+function config_add_bss(config, name) -+{ -+ let bss = { -+ ifname: name, -+ data: [], -+ hash: {} -+ }; -+ -+ push(config.bss, bss); -+ -+ return bss; -+} -+ -+function iface_load_config(filename) -+{ -+ let f = open(filename, "r"); -+ if (!f) -+ return null; -+ -+ let config = { -+ radio: { -+ data: [] -+ }, -+ bss: [], -+ orig_file: filename, -+ }; -+ -+ let bss; -+ let line; -+ while ((line = trim(f.read("line"))) != null) { -+ let val = split(line, "=", 2); -+ if (!val[0]) -+ continue; -+ -+ if (val[0] == "interface") { -+ bss = config_add_bss(config, val[1]); -+ break; -+ } -+ -+ if (val[0] == "channel") { -+ config.radio.channel = val[1]; -+ continue; -+ } -+ -+ push(config.radio.data, line); -+ } -+ -+ while ((line = trim(f.read("line"))) != null) { -+ let val = split(line, "=", 2); -+ if (!val[0]) -+ continue; -+ -+ if (val[0] == "bssid") -+ bss.bssid = val[1]; -+ -+ if (val[0] == "bss") { -+ bss = config_add_bss(config, val[1]); -+ continue; -+ } -+ -+ if (hostapd.data.file_fields[val[0]]) -+ bss.hash[val[0]] = hostapd.sha1(readfile(val[1])); -+ -+ push(bss.data, line); -+ } -+ f.close(); -+ -+ return config; -+} -+ -+ -+ -+let main_obj = { -+ reload: { -+ args: { -+ phy: "", -+ }, -+ call: function(req) { -+ try { -+ let phy_list = req.args.phy ? [ req.args.phy ] : keys(hostapd.data.config); -+ for (let phy_name in phy_list) { -+ let phy = hostapd.data.config[phy_name]; -+ let config = iface_load_config(phy.orig_file); -+ iface_set_config(phy_name, config); -+ } -+ } catch(e) { -+ hostapd.printf(`Error reloading config: ${e}\n${e.stacktrace[0].context}`); -+ return libubus.STATUS_INVALID_ARGUMENT; -+ } -+ -+ return 0; -+ } -+ }, -+ apsta_state: { -+ args: { -+ phy: "", -+ up: true, -+ frequency: 0, -+ sec_chan_offset: 0, -+ csa: true, -+ csa_count: 0, -+ }, -+ call: function(req) { -+ if (req.args.up == null || !req.args.phy) -+ return libubus.STATUS_INVALID_ARGUMENT; -+ -+ let phy = req.args.phy; -+ let config = hostapd.data.config[phy]; -+ if (!config || !config.bss || !config.bss[0] || !config.bss[0].ifname) -+ return 0; -+ -+ let iface = hostapd.interfaces[config.bss[0].ifname]; -+ if (!iface) -+ return 0; -+ -+ if (!req.args.up) { -+ iface.stop(); -+ return 0; -+ } -+ -+ let freq = req.args.frequency; -+ if (!freq) -+ return libubus.STATUS_INVALID_ARGUMENT; -+ -+ let sec_offset = req.args.sec_chan_offset; -+ if (sec_offset != -1 && sec_offset != 1) -+ sec_offset = 0; -+ -+ let width = 0; -+ for (let line in config.radio.data) { -+ if (!sec_offset && match(line, /^ht_capab=.*HT40/)) { -+ sec_offset = null; // auto-detect -+ continue; -+ } -+ -+ let val = match(line, /^(vht_oper_chwidth|he_oper_chwidth)=(\d+)/); -+ if (!val) -+ continue; -+ -+ val = int(val[2]); -+ if (val > width) -+ width = val; -+ } -+ -+ if (freq < 4000) -+ width = 0; -+ -+ let freq_info = hostapd.freq_info(freq, sec_offset, width); -+ if (!freq_info) -+ return libubus.STATUS_UNKNOWN_ERROR; -+ -+ let ret; -+ if (req.args.csa) { -+ freq_info.csa_count = req.args.csa_count ?? 10; -+ ret = iface.switch_channel(freq_info); -+ } else { -+ iface.stop(); -+ ret = iface.start(freq_info); -+ } -+ if (!ret) -+ return libubus.STATUS_UNKNOWN_ERROR; -+ -+ return 0; -+ } -+ }, -+ config_set: { -+ args: { -+ phy: "", -+ config: "", -+ prev_config: "", -+ }, -+ call: function(req) { -+ let phy = req.args.phy; -+ let file = req.args.config; -+ let prev_file = req.args.prev_config; -+ -+ if (!phy) -+ return libubus.STATUS_INVALID_ARGUMENT; -+ -+ try { -+ if (prev_file && !hostapd.data.config[phy]) { -+ let config = iface_load_config(prev_file); -+ if (config) -+ config.radio.data = []; -+ hostapd.data.config[phy] = config; -+ } -+ -+ let config = iface_load_config(file); -+ -+ hostapd.printf(`Set new config for phy ${phy}: ${file}`); -+ iface_set_config(phy, config); -+ } catch(e) { -+ hostapd.printf(`Error loading config: ${e}\n${e.stacktrace[0].context}`); -+ return libubus.STATUS_INVALID_ARGUMENT; -+ } -+ -+ return { -+ pid: hostapd.getpid() -+ }; -+ } -+ }, -+ config_add: { -+ args: { -+ iface: "", -+ config: "", -+ }, -+ call: function(req) { -+ if (!req.args.iface || !req.args.config) -+ return libubus.STATUS_INVALID_ARGUMENT; -+ -+ if (hostapd.add_iface(`bss_config=${req.args.iface}:${req.args.config}`) < 0) -+ return libubus.STATUS_INVALID_ARGUMENT; -+ -+ return { -+ pid: hostapd.getpid() -+ }; -+ } -+ }, -+ config_remove: { -+ args: { -+ iface: "" -+ }, -+ call: function(req) { -+ if (!req.args.iface) -+ return libubus.STATUS_INVALID_ARGUMENT; -+ -+ hostapd.remove_iface(req.args.iface); -+ return 0; -+ } -+ }, -+}; -+ -+hostapd.data.ubus = ubus; -+hostapd.data.obj = ubus.publish("hostapd", main_obj); -+ -+function bss_event(type, name, data) { -+ let ubus = hostapd.data.ubus; -+ -+ data ??= {}; -+ data.name = name; -+ hostapd.data.obj.notify(`bss.${type}`, data, null, null, null, -1); -+ ubus.call("service", "event", { type: `hostapd.${name}.${type}`, data: {} }); -+} -+ -+return { -+ shutdown: function() { -+ for (let phy in hostapd.data.config) -+ iface_set_config(phy, null); -+ hostapd.ubus.disconnect(); -+ }, -+ bss_add: function(name, obj) { -+ bss_event("add", name); -+ }, -+ bss_reload: function(name, obj, reconf) { -+ bss_event("reload", name, { reconf: reconf != 0 }); -+ }, -+ bss_remove: function(name, obj) { -+ bss_event("remove", name); -+ } -+}; -diff --git a/package/network/services/hostapd/files/multicall.c b/package/network/services/hostapd/files/multicall.c -new file mode 100644 -index 0000000000..c8e814bb5c ---- /dev/null -+++ b/package/network/services/hostapd/files/multicall.c -@@ -0,0 +1,28 @@ -+#include -+#include -+#include -+ -+extern int hostapd_main(int argc, char **argv); -+extern int wpa_supplicant_main(int argc, char **argv); -+ -+int main(int argc, char **argv) -+{ -+ bool restart = false; -+ const char *prog = argv[0]; -+ -+restart: -+ if (strstr(argv[0], "hostapd")) -+ return hostapd_main(argc, argv); -+ else if (strstr(argv[0], "wpa_supplicant")) -+ return wpa_supplicant_main(argc, argv); -+ -+ if (!restart && argc > 1) { -+ argv++; -+ argc--; -+ restart = true; -+ goto restart; -+ } -+ -+ fprintf(stderr, "Invalid command.\nUsage: %s wpa_supplicant|hostapd []\n", prog); -+ return 255; -+} -diff --git a/package/network/services/hostapd/files/radius.clients b/package/network/services/hostapd/files/radius.clients -new file mode 100644 -index 0000000000..3175dcfd04 ---- /dev/null -+++ b/package/network/services/hostapd/files/radius.clients -@@ -0,0 +1 @@ -+0.0.0.0/0 radius -diff --git a/package/network/services/hostapd/files/radius.config b/package/network/services/hostapd/files/radius.config -new file mode 100644 -index 0000000000..ad8730748b ---- /dev/null -+++ b/package/network/services/hostapd/files/radius.config -@@ -0,0 +1,9 @@ -+config radius -+ option disabled '1' -+ option ca_cert '/etc/radius/ca.pem' -+ option cert '/etc/radius/cert.pem' -+ option key '/etc/radius/key.pem' -+ option users '/etc/radius/users' -+ option clients '/etc/radius/clients' -+ option auth_port '1812' -+ option acct_port '1813' -diff --git a/package/network/services/hostapd/files/radius.init b/package/network/services/hostapd/files/radius.init -new file mode 100644 -index 0000000000..4c562c2473 ---- /dev/null -+++ b/package/network/services/hostapd/files/radius.init -@@ -0,0 +1,42 @@ -+#!/bin/sh /etc/rc.common -+ -+START=30 -+ -+USE_PROCD=1 -+NAME=radius -+ -+radius_start() { -+ local cfg="$1" -+ -+ config_get_bool disabled "$cfg" disabled 0 -+ -+ [ "$disabled" -gt 0 ] && return -+ -+ config_get ca "$cfg" ca_cert -+ config_get key "$cfg" key -+ config_get cert "$cfg" cert -+ config_get users "$cfg" users -+ config_get clients "$cfg" clients -+ config_get auth_port "$cfg" auth_port 1812 -+ config_get acct_port "$cfg" acct_port 1813 -+ config_get identity "$cfg" identity "$(cat /proc/sys/kernel/hostname)" -+ -+ procd_open_instance $cfg -+ procd_set_param command /usr/sbin/hostapd-radius \ -+ -C "$ca" \ -+ -c "$cert" -k "$key" \ -+ -s "$clients" -u "$users" \ -+ -p "$auth_port" -P "$acct_port" \ -+ -i "$identity" -+ procd_close_instance -+} -+ -+start_service() { -+ config_load radius -+ config_foreach radius_start radius -+} -+ -+service_triggers() -+{ -+ procd_add_reload_trigger "radius" -+} -diff --git a/package/network/services/hostapd/files/radius.users b/package/network/services/hostapd/files/radius.users -new file mode 100644 -index 0000000000..03e2fc8fae ---- /dev/null -+++ b/package/network/services/hostapd/files/radius.users -@@ -0,0 +1,14 @@ -+{ -+ "phase1": { -+ "wildcard": [ -+ { -+ "name": "*", -+ "methods": [ "PEAP" ] -+ } -+ ] -+ }, -+ "phase2": { -+ "users": { -+ } -+ } -+} -diff --git a/package/network/services/hostapd/files/wdev.uc b/package/network/services/hostapd/files/wdev.uc -new file mode 100644 -index 0000000000..5b321423eb ---- /dev/null -+++ b/package/network/services/hostapd/files/wdev.uc -@@ -0,0 +1,156 @@ -+#!/usr/bin/env ucode -+'use strict'; -+import { vlist_new, is_equal, wdev_create, wdev_remove } from "/usr/share/hostap/common.uc"; -+import { readfile, writefile, basename, readlink, glob } from "fs"; -+ -+let keep_devices = {}; -+let phy = shift(ARGV); -+let new_config = shift(ARGV); -+const mesh_params = [ -+ "mesh_retry_timeout", "mesh_confirm_timeout", "mesh_holding_timeout", "mesh_max_peer_links", -+ "mesh_max_retries", "mesh_ttl", "mesh_element_ttl", "mesh_hwmp_max_preq_retries", -+ "mesh_path_refresh_time", "mesh_min_discovery_timeout", "mesh_hwmp_active_path_timeout", -+ "mesh_hwmp_preq_min_interval", "mesh_hwmp_net_diameter_traversal_time", "mesh_hwmp_rootmode", -+ "mesh_hwmp_rann_interval", "mesh_gate_announcements", "mesh_sync_offset_max_neighor", -+ "mesh_rssi_threshold", "mesh_hwmp_active_path_to_root_timeout", "mesh_hwmp_root_interval", -+ "mesh_hwmp_confirmation_interval", "mesh_awake_window", "mesh_plink_timeout", -+ "mesh_auto_open_plinks", "mesh_fwding", "mesh_power_mode" -+]; -+ -+function iface_stop(wdev) -+{ -+ if (keep_devices[wdev.ifname]) -+ return; -+ -+ wdev_remove(wdev.ifname); -+} -+ -+function iface_start(wdev) -+{ -+ let ifname = wdev.ifname; -+ -+ if (readfile(`/sys/class/net/${ifname}/ifindex`)) { -+ system([ "ip", "link", "set", "dev", ifname, "down" ]); -+ wdev_remove(ifname); -+ } -+ wdev_create(phy, ifname, wdev); -+ system([ "ip", "link", "set", "dev", ifname, "up" ]); -+ if (wdev.freq) -+ system(`iw dev ${ifname} set freq ${wdev.freq} ${wdev.htmode}`); -+ if (wdev.mode == "adhoc") { -+ let cmd = ["iw", "dev", ifname, "ibss", "join", wdev.ssid, wdev.freq, wdev.htmode, "fixed-freq" ]; -+ if (wdev.bssid) -+ push(cmd, wdev.bssid); -+ for (let key in [ "beacon-interval", "basic-rates", "mcast-rate", "keys" ]) -+ if (wdev[key]) -+ push(cmd, key, wdev[key]); -+ system(cmd); -+ } else if (wdev.mode == "mesh") { -+ let cmd = [ "iw", "dev", ifname, "mesh", "join", wdev.ssid, "freq", wdev.freq, wdev.htmode ]; -+ for (let key in [ "beacon-interval", "mcast-rate" ]) -+ if (wdev[key]) -+ push(cmd, key, wdev[key]); -+ system(cmd); -+ -+ cmd = ["iw", "dev", ifname, "set", "mesh_param" ]; -+ let len = length(cmd); -+ -+ for (let param in mesh_params) -+ if (wdev[param]) -+ push(cmd, param, wdev[param]); -+ -+ if (len == length(cmd)) -+ return; -+ -+ system(cmd); -+ } -+ -+} -+ -+function iface_cb(new_if, old_if) -+{ -+ if (old_if && new_if && is_equal(old_if, new_if)) -+ return; -+ -+ if (old_if) -+ iface_stop(old_if); -+ if (new_if) -+ iface_start(new_if); -+} -+ -+function drop_inactive(config) -+{ -+ for (let key in config) { -+ if (!readfile(`/sys/class/net/${key}/ifindex`)) -+ delete config[key]; -+ } -+} -+ -+function add_ifname(config) -+{ -+ for (let key in config) -+ config[key].ifname = key; -+} -+ -+function delete_ifname(config) -+{ -+ for (let key in config) -+ delete config[key].ifname; -+} -+ -+function add_existing(phy, config) -+{ -+ let wdevs = glob(`/sys/class/ieee80211/${phy}/device/net/*`); -+ wdevs = map(wdevs, (arg) => basename(arg)); -+ for (let wdev in wdevs) { -+ if (config[wdev]) -+ continue; -+ -+ if (basename(readlink(`/sys/class/net/${wdev}/phy80211`)) != phy) -+ continue; -+ -+ if (trim(readfile(`/sys/class/net/${wdev}/operstate`)) == "down") -+ config[wdev] = {}; -+ } -+} -+ -+ -+let statefile = `/var/run/wdev-${phy}.json`; -+ -+for (let dev in ARGV) -+ keep_devices[dev] = true; -+ -+if (!phy || !new_config) { -+ warn(`Usage: ${basename(sourcepath())} [ -+#LIBS += -L$ -+ -+# Use libnl v2.0 (or 3.0) libraries. -+#CONFIG_LIBNL20=y -+ -+# Use libnl 3.2 libraries (if this is selected, CONFIG_LIBNL20 is ignored) -+#CONFIG_LIBNL32=y -+ -+ -+# Driver interface for FreeBSD net80211 layer (e.g., Atheros driver) -+#CONFIG_DRIVER_BSD=y -+#CFLAGS += -I/usr/local/include -+#LIBS += -L/usr/local/lib -+#LIBS_p += -L/usr/local/lib -+#LIBS_c += -L/usr/local/lib -+ -+# Driver interface for Windows NDIS -+#CONFIG_DRIVER_NDIS=y -+#CFLAGS += -I/usr/include/w32api/ddk -+#LIBS += -L/usr/local/lib -+# For native build using mingw -+#CONFIG_NATIVE_WINDOWS=y -+# Additional directories for cross-compilation on Linux host for mingw target -+#CFLAGS += -I/opt/mingw/mingw32/include/ddk -+#LIBS += -L/opt/mingw/mingw32/lib -+#CC=mingw32-gcc -+# By default, driver_ndis uses WinPcap for low-level operations. This can be -+# replaced with the following option which replaces WinPcap calls with NDISUIO. -+# However, this requires that WZC is disabled (net stop wzcsvc) before starting -+# wpa_supplicant. -+# CONFIG_USE_NDISUIO=y -+ -+# Driver interface for wired Ethernet drivers -+CONFIG_DRIVER_WIRED=y -+ -+# Driver interface for MACsec capable Qualcomm Atheros drivers -+#CONFIG_DRIVER_MACSEC_QCA=y -+ -+# Driver interface for Linux MACsec drivers -+#CONFIG_DRIVER_MACSEC_LINUX=y -+ -+# Driver interface for the Broadcom RoboSwitch family -+#CONFIG_DRIVER_ROBOSWITCH=y -+ -+# Driver interface for no driver (e.g., WPS ER only) -+#CONFIG_DRIVER_NONE=y -+ -+# Solaris libraries -+#LIBS += -lsocket -ldlpi -lnsl -+#LIBS_c += -lsocket -+ -+# Enable IEEE 802.1X Supplicant (automatically included if any EAP method or -+# MACsec is included) -+#CONFIG_IEEE8021X_EAPOL=y -+ -+# EAP-MD5 -+#CONFIG_EAP_MD5=y -+ -+# EAP-MSCHAPv2 -+#CONFIG_EAP_MSCHAPV2=y -+ -+# EAP-TLS -+#CONFIG_EAP_TLS=y -+ -+# EAL-PEAP -+#CONFIG_EAP_PEAP=y -+ -+# EAP-TTLS -+#CONFIG_EAP_TTLS=y -+ -+# EAP-FAST -+#CONFIG_EAP_FAST=y -+ -+# EAP-TEAP -+# Note: The current EAP-TEAP implementation is experimental and should not be -+# enabled for production use. The IETF RFC 7170 that defines EAP-TEAP has number -+# of conflicting statements and missing details and the implementation has -+# vendor specific workarounds for those and as such, may not interoperate with -+# any other implementation. This should not be used for anything else than -+# experimentation and interoperability testing until those issues has been -+# resolved. -+#CONFIG_EAP_TEAP=y -+ -+# EAP-GTC -+#CONFIG_EAP_GTC=y -+ -+# EAP-OTP -+#CONFIG_EAP_OTP=y -+ -+# EAP-SIM (enable CONFIG_PCSC, if EAP-SIM is used) -+#CONFIG_EAP_SIM=y -+ -+# Enable SIM simulator (Milenage) for EAP-SIM -+#CONFIG_SIM_SIMULATOR=y -+ -+# EAP-PSK (experimental; this is _not_ needed for WPA-PSK) -+#CONFIG_EAP_PSK=y -+ -+# EAP-pwd (secure authentication using only a password) -+#CONFIG_EAP_PWD=y -+ -+# EAP-PAX -+#CONFIG_EAP_PAX=y -+ -+# LEAP -+#CONFIG_EAP_LEAP=y -+ -+# EAP-AKA (enable CONFIG_PCSC, if EAP-AKA is used) -+#CONFIG_EAP_AKA=y -+ -+# EAP-AKA' (enable CONFIG_PCSC, if EAP-AKA' is used). -+# This requires CONFIG_EAP_AKA to be enabled, too. -+#CONFIG_EAP_AKA_PRIME=y -+ -+# Enable USIM simulator (Milenage) for EAP-AKA -+#CONFIG_USIM_SIMULATOR=y -+ -+# EAP-SAKE -+#CONFIG_EAP_SAKE=y -+ -+# EAP-GPSK -+#CONFIG_EAP_GPSK=y -+# Include support for optional SHA256 cipher suite in EAP-GPSK -+#CONFIG_EAP_GPSK_SHA256=y -+ -+# EAP-TNC and related Trusted Network Connect support (experimental) -+#CONFIG_EAP_TNC=y -+ -+# Wi-Fi Protected Setup (WPS) -+#CONFIG_WPS=y -+# Enable WPS external registrar functionality -+#CONFIG_WPS_ER=y -+# Disable credentials for an open network by default when acting as a WPS -+# registrar. -+#CONFIG_WPS_REG_DISABLE_OPEN=y -+# Enable WPS support with NFC config method -+#CONFIG_WPS_NFC=y -+ -+# EAP-IKEv2 -+#CONFIG_EAP_IKEV2=y -+ -+# EAP-EKE -+#CONFIG_EAP_EKE=y -+ -+# MACsec -+#CONFIG_MACSEC=y -+ -+# PKCS#12 (PFX) support (used to read private key and certificate file from -+# a file that usually has extension .p12 or .pfx) -+#CONFIG_PKCS12=y -+ -+# Smartcard support (i.e., private key on a smartcard), e.g., with openssl -+# engine. -+#CONFIG_SMARTCARD=y -+ -+# PC/SC interface for smartcards (USIM, GSM SIM) -+# Enable this if EAP-SIM or EAP-AKA is included -+#CONFIG_PCSC=y -+ -+# Support HT overrides (disable HT/HT40, mask MCS rates, etc.) -+CONFIG_HT_OVERRIDES=y -+ -+# Support VHT overrides (disable VHT, mask MCS rates, etc.) -+CONFIG_VHT_OVERRIDES=y -+ -+# Development testing -+#CONFIG_EAPOL_TEST=y -+ -+# Select control interface backend for external programs, e.g, wpa_cli: -+# unix = UNIX domain sockets (default for Linux/*BSD) -+# udp = UDP sockets using localhost (127.0.0.1) -+# udp6 = UDP IPv6 sockets using localhost (::1) -+# named_pipe = Windows Named Pipe (default for Windows) -+# udp-remote = UDP sockets with remote access (only for tests systems/purpose) -+# udp6-remote = UDP IPv6 sockets with remote access (only for tests purpose) -+# y = use default (backwards compatibility) -+# If this option is commented out, control interface is not included in the -+# build. -+CONFIG_CTRL_IFACE=y -+ -+# Include support for GNU Readline and History Libraries in wpa_cli. -+# When building a wpa_cli binary for distribution, please note that these -+# libraries are licensed under GPL and as such, BSD license may not apply for -+# the resulting binary. -+#CONFIG_READLINE=y -+ -+# Include internal line edit mode in wpa_cli. This can be used as a replacement -+# for GNU Readline to provide limited command line editing and history support. -+#CONFIG_WPA_CLI_EDIT=y -+ -+# Remove debugging code that is printing out debug message to stdout. -+# This can be used to reduce the size of the wpa_supplicant considerably -+# if debugging code is not needed. The size reduction can be around 35% -+# (e.g., 90 kB). -+#CONFIG_NO_STDOUT_DEBUG=y -+ -+# Remove WPA support, e.g., for wired-only IEEE 802.1X supplicant, to save -+# 35-50 kB in code size. -+#CONFIG_NO_WPA=y -+ -+# Remove IEEE 802.11i/WPA-Personal ASCII passphrase support -+# This option can be used to reduce code size by removing support for -+# converting ASCII passphrases into PSK. If this functionality is removed, the -+# PSK can only be configured as the 64-octet hexstring (e.g., from -+# wpa_passphrase). This saves about 0.5 kB in code size. -+#CONFIG_NO_WPA_PASSPHRASE=y -+ -+# Simultaneous Authentication of Equals (SAE), WPA3-Personal -+#CONFIG_SAE=y -+ -+# Disable scan result processing (ap_mode=1) to save code size by about 1 kB. -+# This can be used if ap_scan=1 mode is never enabled. -+#CONFIG_NO_SCAN_PROCESSING=y -+ -+# Select configuration backend: -+# file = text file (e.g., wpa_supplicant.conf; note: the configuration file -+# path is given on command line, not here; this option is just used to -+# select the backend that allows configuration files to be used) -+# winreg = Windows registry (see win_example.reg for an example) -+CONFIG_BACKEND=file -+ -+# Remove configuration write functionality (i.e., to allow the configuration -+# file to be updated based on runtime configuration changes). The runtime -+# configuration can still be changed, the changes are just not going to be -+# persistent over restarts. This option can be used to reduce code size by -+# about 3.5 kB. -+CONFIG_NO_CONFIG_WRITE=y -+ -+# Remove support for configuration blobs to reduce code size by about 1.5 kB. -+#CONFIG_NO_CONFIG_BLOBS=y -+ -+# Select program entry point implementation: -+# main = UNIX/POSIX like main() function (default) -+# main_winsvc = Windows service (read parameters from registry) -+# main_none = Very basic example (development use only) -+#CONFIG_MAIN=main -+ -+# Select wrapper for operating system and C library specific functions -+# unix = UNIX/POSIX like systems (default) -+# win32 = Windows systems -+# none = Empty template -+#CONFIG_OS=unix -+ -+# Select event loop implementation -+# eloop = select() loop (default) -+# eloop_win = Windows events and WaitForMultipleObject() loop -+#CONFIG_ELOOP=eloop -+ -+# Should we use poll instead of select? Select is used by default. -+#CONFIG_ELOOP_POLL=y -+ -+# Should we use epoll instead of select? Select is used by default. -+CONFIG_ELOOP_EPOLL=y -+ -+# Should we use kqueue instead of select? Select is used by default. -+#CONFIG_ELOOP_KQUEUE=y -+ -+# Select layer 2 packet implementation -+# linux = Linux packet socket (default) -+# pcap = libpcap/libdnet/WinPcap -+# freebsd = FreeBSD libpcap -+# winpcap = WinPcap with receive thread -+# ndis = Windows NDISUIO (note: requires CONFIG_USE_NDISUIO=y) -+# none = Empty template -+#CONFIG_L2_PACKET=linux -+ -+# Disable Linux packet socket workaround applicable for station interface -+# in a bridge for EAPOL frames. This should be uncommented only if the kernel -+# is known to not have the regression issue in packet socket behavior with -+# bridge interfaces (commit 'bridge: respect RFC2863 operational state')'). -+CONFIG_NO_LINUX_PACKET_SOCKET_WAR=y -+ -+# IEEE 802.11w (management frame protection), also known as PMF -+# Driver support is also needed for IEEE 802.11w. -+#CONFIG_IEEE80211W=y -+ -+# Support Operating Channel Validation -+CONFIG_OCV=y -+ -+# Select TLS implementation -+# openssl = OpenSSL (default) -+# gnutls = GnuTLS -+# internal = Internal TLSv1 implementation (experimental) -+# linux = Linux kernel AF_ALG and internal TLSv1 implementation (experimental) -+# none = Empty template -+CONFIG_TLS=internal -+ -+# TLS-based EAP methods require at least TLS v1.0. Newer version of TLS (v1.1) -+# can be enabled to get a stronger construction of messages when block ciphers -+# are used. It should be noted that some existing TLS v1.0 -based -+# implementation may not be compatible with TLS v1.1 message (ClientHello is -+# sent prior to negotiating which version will be used) -+#CONFIG_TLSV11=y -+ -+# TLS-based EAP methods require at least TLS v1.0. Newer version of TLS (v1.2) -+# can be enabled to enable use of stronger crypto algorithms. It should be -+# noted that some existing TLS v1.0 -based implementation may not be compatible -+# with TLS v1.2 message (ClientHello is sent prior to negotiating which version -+# will be used) -+#CONFIG_TLSV12=y -+ -+# Select which ciphers to use by default with OpenSSL if the user does not -+# specify them. -+#CONFIG_TLS_DEFAULT_CIPHERS="DEFAULT:!EXP:!LOW" -+ -+# If CONFIG_TLS=internal is used, additional library and include paths are -+# needed for LibTomMath. Alternatively, an integrated, minimal version of -+# LibTomMath can be used. See beginning of libtommath.c for details on benefits -+# and drawbacks of this option. -+#CONFIG_INTERNAL_LIBTOMMATH=y -+#ifndef CONFIG_INTERNAL_LIBTOMMATH -+#LTM_PATH=/usr/src/libtommath-0.39 -+#CFLAGS += -I$(LTM_PATH) -+#LIBS += -L$(LTM_PATH) -+#LIBS_p += -L$(LTM_PATH) -+#endif -+# At the cost of about 4 kB of additional binary size, the internal LibTomMath -+# can be configured to include faster routines for exptmod, sqr, and div to -+# speed up DH and RSA calculation considerably -+#CONFIG_INTERNAL_LIBTOMMATH_FAST=y -+ -+# Include NDIS event processing through WMI into wpa_supplicant/wpasvc. -+# This is only for Windows builds and requires WMI-related header files and -+# WbemUuid.Lib from Platform SDK even when building with MinGW. -+#CONFIG_NDIS_EVENTS_INTEGRATED=y -+#PLATFORMSDKLIB="/opt/Program Files/Microsoft Platform SDK/Lib" -+ -+# Add support for new DBus control interface -+# (fi.w1.hostap.wpa_supplicant1) -+#CONFIG_CTRL_IFACE_DBUS_NEW=y -+ -+# Add introspection support for new DBus control interface -+#CONFIG_CTRL_IFACE_DBUS_INTRO=y -+ -+# Add support for loading EAP methods dynamically as shared libraries. -+# When this option is enabled, each EAP method can be either included -+# statically (CONFIG_EAP_=y) or dynamically (CONFIG_EAP_=dyn). -+# Dynamic EAP methods are build as shared objects (eap_*.so) and they need to -+# be loaded in the beginning of the wpa_supplicant configuration file -+# (see load_dynamic_eap parameter in the example file) before being used in -+# the network blocks. -+# -+# Note that some shared parts of EAP methods are included in the main program -+# and in order to be able to use dynamic EAP methods using these parts, the -+# main program must have been build with the EAP method enabled (=y or =dyn). -+# This means that EAP-TLS/PEAP/TTLS/FAST cannot be added as dynamic libraries -+# unless at least one of them was included in the main build to force inclusion -+# of the shared code. Similarly, at least one of EAP-SIM/AKA must be included -+# in the main build to be able to load these methods dynamically. -+# -+# Please also note that using dynamic libraries will increase the total binary -+# size. Thus, it may not be the best option for targets that have limited -+# amount of memory/flash. -+#CONFIG_DYNAMIC_EAP_METHODS=y -+ -+# IEEE Std 802.11r-2008 (Fast BSS Transition) for station mode -+CONFIG_IEEE80211R=y -+ -+# Add support for writing debug log to a file (/tmp/wpa_supplicant-log-#.txt) -+#CONFIG_DEBUG_FILE=y -+ -+# Send debug messages to syslog instead of stdout -+CONFIG_DEBUG_SYSLOG=y -+# Set syslog facility for debug messages -+CONFIG_DEBUG_SYSLOG_FACILITY=LOG_DAEMON -+ -+# Add support for sending all debug messages (regardless of debug verbosity) -+# to the Linux kernel tracing facility. This helps debug the entire stack by -+# making it easy to record everything happening from the driver up into the -+# same file, e.g., using trace-cmd. -+#CONFIG_DEBUG_LINUX_TRACING=y -+ -+# Add support for writing debug log to Android logcat instead of standard -+# output -+#CONFIG_ANDROID_LOG=y -+ -+# Enable privilege separation (see README 'Privilege separation' for details) -+#CONFIG_PRIVSEP=y -+ -+# Enable mitigation against certain attacks against TKIP by delaying Michael -+# MIC error reports by a random amount of time between 0 and 60 seconds -+#CONFIG_DELAYED_MIC_ERROR_REPORT=y -+ -+# Enable tracing code for developer debugging -+# This tracks use of memory allocations and other registrations and reports -+# incorrect use with a backtrace of call (or allocation) location. -+#CONFIG_WPA_TRACE=y -+# For BSD, uncomment these. -+#LIBS += -lexecinfo -+#LIBS_p += -lexecinfo -+#LIBS_c += -lexecinfo -+ -+# Use libbfd to get more details for developer debugging -+# This enables use of libbfd to get more detailed symbols for the backtraces -+# generated by CONFIG_WPA_TRACE=y. -+#CONFIG_WPA_TRACE_BFD=y -+# For BSD, uncomment these. -+#LIBS += -lbfd -liberty -lz -+#LIBS_p += -lbfd -liberty -lz -+#LIBS_c += -lbfd -liberty -lz -+ -+# wpa_supplicant depends on strong random number generation being available -+# from the operating system. os_get_random() function is used to fetch random -+# data when needed, e.g., for key generation. On Linux and BSD systems, this -+# works by reading /dev/urandom. It should be noted that the OS entropy pool -+# needs to be properly initialized before wpa_supplicant is started. This is -+# important especially on embedded devices that do not have a hardware random -+# number generator and may by default start up with minimal entropy available -+# for random number generation. -+# -+# As a safety net, wpa_supplicant is by default trying to internally collect -+# additional entropy for generating random data to mix in with the data fetched -+# from the OS. This by itself is not considered to be very strong, but it may -+# help in cases where the system pool is not initialized properly. However, it -+# is very strongly recommended that the system pool is initialized with enough -+# entropy either by using hardware assisted random number generator or by -+# storing state over device reboots. -+# -+# wpa_supplicant can be configured to maintain its own entropy store over -+# restarts to enhance random number generation. This is not perfect, but it is -+# much more secure than using the same sequence of random numbers after every -+# reboot. This can be enabled with -e command line option. The -+# specified file needs to be readable and writable by wpa_supplicant. -+# -+# If the os_get_random() is known to provide strong random data (e.g., on -+# Linux/BSD, the board in question is known to have reliable source of random -+# data from /dev/urandom), the internal wpa_supplicant random pool can be -+# disabled. This will save some in binary size and CPU use. However, this -+# should only be considered for builds that are known to be used on devices -+# that meet the requirements described above. -+CONFIG_NO_RANDOM_POOL=y -+ -+# Should we attempt to use the getrandom(2) call that provides more reliable -+# yet secure randomness source than /dev/random on Linux 3.17 and newer. -+# Requires glibc 2.25 to build, falls back to /dev/random if unavailable. -+CONFIG_GETRANDOM=y -+ -+# IEEE 802.11n (High Throughput) support (mainly for AP mode) -+#CONFIG_IEEE80211N=y -+ -+# IEEE 802.11ac (Very High Throughput) support (mainly for AP mode) -+# (depends on CONFIG_IEEE80211N) -+#CONFIG_IEEE80211AC=y -+ -+# Wireless Network Management (IEEE Std 802.11v-2011) -+# Note: This is experimental and not complete implementation. -+#CONFIG_WNM=y -+ -+# Interworking (IEEE 802.11u) -+# This can be used to enable functionality to improve interworking with -+# external networks (GAS/ANQP to learn more about the networks and network -+# selection based on available credentials). -+#CONFIG_INTERWORKING=y -+ -+# Hotspot 2.0 -+#CONFIG_HS20=y -+ -+# Enable interface matching in wpa_supplicant -+#CONFIG_MATCH_IFACE=y -+ -+# Disable roaming in wpa_supplicant -+#CONFIG_NO_ROAMING=y -+ -+# AP mode operations with wpa_supplicant -+# This can be used for controlling AP mode operations with wpa_supplicant. It -+# should be noted that this is mainly aimed at simple cases like -+# WPA2-Personal while more complex configurations like WPA2-Enterprise with an -+# external RADIUS server can be supported with hostapd. -+#CONFIG_AP=y -+ -+# P2P (Wi-Fi Direct) -+# This can be used to enable P2P support in wpa_supplicant. See README-P2P for -+# more information on P2P operations. -+#CONFIG_P2P=y -+ -+# Enable TDLS support -+#CONFIG_TDLS=y -+ -+# Wi-Fi Display -+# This can be used to enable Wi-Fi Display extensions for P2P using an external -+# program to control the additional information exchanges in the messages. -+#CONFIG_WIFI_DISPLAY=y -+ -+# Autoscan -+# This can be used to enable automatic scan support in wpa_supplicant. -+# See wpa_supplicant.conf for more information on autoscan usage. -+# -+# Enabling directly a module will enable autoscan support. -+# For exponential module: -+#CONFIG_AUTOSCAN_EXPONENTIAL=y -+# For periodic module: -+#CONFIG_AUTOSCAN_PERIODIC=y -+ -+# Password (and passphrase, etc.) backend for external storage -+# These optional mechanisms can be used to add support for storing passwords -+# and other secrets in external (to wpa_supplicant) location. This allows, for -+# example, operating system specific key storage to be used -+# -+# External password backend for testing purposes (developer use) -+#CONFIG_EXT_PASSWORD_TEST=y -+ -+# Enable Fast Session Transfer (FST) -+#CONFIG_FST=y -+ -+# Enable CLI commands for FST testing -+#CONFIG_FST_TEST=y -+ -+# OS X builds. This is only for building eapol_test. -+#CONFIG_OSX=y -+ -+# Automatic Channel Selection -+# This will allow wpa_supplicant to pick the channel automatically when channel -+# is set to "0". -+# -+# TODO: Extend parser to be able to parse "channel=acs_survey" as an alternative -+# to "channel=0". This would enable us to eventually add other ACS algorithms in -+# similar way. -+# -+# Automatic selection is currently only done through initialization, later on -+# we hope to do background checks to keep us moving to more ideal channels as -+# time goes by. ACS is currently only supported through the nl80211 driver and -+# your driver must have survey dump capability that is filled by the driver -+# during scanning. -+# -+# TODO: In analogy to hostapd be able to customize the ACS survey algorithm with -+# a newly to create wpa_supplicant.conf variable acs_num_scans. -+# -+# Supported ACS drivers: -+# * ath9k -+# * ath5k -+# * ath10k -+# -+# For more details refer to: -+# http://wireless.kernel.org/en/users/Documentation/acs -+#CONFIG_ACS=y -+ -+# Support Multi Band Operation -+#CONFIG_MBO=y -+ -+# Fast Initial Link Setup (FILS) (IEEE 802.11ai) -+#CONFIG_FILS=y -+# FILS shared key authentication with PFS -+#CONFIG_FILS_SK_PFS=y -+ -+# Support RSN on IBSS networks -+# This is needed to be able to use mode=1 network profile with proto=RSN and -+# key_mgmt=WPA-PSK (i.e., full key management instead of WPA-None). -+#CONFIG_IBSS_RSN=y -+ -+# External PMKSA cache control -+# This can be used to enable control interface commands that allow the current -+# PMKSA cache entries to be fetched and new entries to be added. -+#CONFIG_PMKSA_CACHE_EXTERNAL=y -+ -+# Mesh Networking (IEEE 802.11s) -+#CONFIG_MESH=y -+ -+# Background scanning modules -+# These can be used to request wpa_supplicant to perform background scanning -+# operations for roaming within an ESS (same SSID). See the bgscan parameter in -+# the wpa_supplicant.conf file for more details. -+# Periodic background scans based on signal strength -+#CONFIG_BGSCAN_SIMPLE=y -+# Learn channels used by the network and try to avoid bgscans on other -+# channels (experimental) -+#CONFIG_BGSCAN_LEARN=y -+ -+# Opportunistic Wireless Encryption (OWE) -+# Experimental implementation of draft-harkins-owe-07.txt -+#CONFIG_OWE=y -+ -+# Device Provisioning Protocol (DPP) -+# This requires CONFIG_IEEE80211W=y to be enabled, too. (see -+# wpa_supplicant/README-DPP for details) -+#CONFIG_DPP=y -+ -+# uBus IPC/RPC System -+# Services can connect to the bus and provide methods -+# that can be called by other services or clients. -+CONFIG_UBUS=y -+ -+# OpenWrt patch 380-disable-ctrl-iface-mib.patch -+# leads to the MIB only being compiled in if -+# CONFIG_CTRL_IFACE_MIB is enabled. -+#CONFIG_CTRL_IFACE_MIB=y -diff --git a/package/network/services/hostapd/files/wpa_supplicant-full.config b/package/network/services/hostapd/files/wpa_supplicant-full.config -new file mode 100644 -index 0000000000..b39dabca06 ---- /dev/null -+++ b/package/network/services/hostapd/files/wpa_supplicant-full.config -@@ -0,0 +1,625 @@ -+# Example wpa_supplicant build time configuration -+# -+# This file lists the configuration options that are used when building the -+# wpa_supplicant binary. All lines starting with # are ignored. Configuration -+# option lines must be commented out complete, if they are not to be included, -+# i.e., just setting VARIABLE=n is not disabling that variable. -+# -+# This file is included in Makefile, so variables like CFLAGS and LIBS can also -+# be modified from here. In most cases, these lines should use += in order not -+# to override previous values of the variables. -+ -+ -+# Uncomment following two lines and fix the paths if you have installed OpenSSL -+# or GnuTLS in non-default location -+#CFLAGS += -I/usr/local/openssl/include -+#LIBS += -L/usr/local/openssl/lib -+ -+# Some Red Hat versions seem to include kerberos header files from OpenSSL, but -+# the kerberos files are not in the default include path. Following line can be -+# used to fix build issues on such systems (krb5.h not found). -+#CFLAGS += -I/usr/include/kerberos -+ -+# 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 -+# replacement for WEXT and its use allows wpa_supplicant to properly control -+# the driver to improve existing functionality like roaming and to support new -+# functionality. -+#CONFIG_DRIVER_WEXT=y -+ -+# Driver interface for Linux drivers using the nl80211 kernel interface -+CONFIG_DRIVER_NL80211=y -+ -+# QCA vendor extensions to nl80211 -+#CONFIG_DRIVER_NL80211_QCA=y -+ -+# driver_nl80211.c requires libnl. If you are compiling it yourself -+# you may need to point hostapd to your version of libnl. -+# -+#CFLAGS += -I$ -+#LIBS += -L$ -+ -+# Use libnl v2.0 (or 3.0) libraries. -+#CONFIG_LIBNL20=y -+ -+# Use libnl 3.2 libraries (if this is selected, CONFIG_LIBNL20 is ignored) -+#CONFIG_LIBNL32=y -+ -+ -+# Driver interface for FreeBSD net80211 layer (e.g., Atheros driver) -+#CONFIG_DRIVER_BSD=y -+#CFLAGS += -I/usr/local/include -+#LIBS += -L/usr/local/lib -+#LIBS_p += -L/usr/local/lib -+#LIBS_c += -L/usr/local/lib -+ -+# Driver interface for Windows NDIS -+#CONFIG_DRIVER_NDIS=y -+#CFLAGS += -I/usr/include/w32api/ddk -+#LIBS += -L/usr/local/lib -+# For native build using mingw -+#CONFIG_NATIVE_WINDOWS=y -+# Additional directories for cross-compilation on Linux host for mingw target -+#CFLAGS += -I/opt/mingw/mingw32/include/ddk -+#LIBS += -L/opt/mingw/mingw32/lib -+#CC=mingw32-gcc -+# By default, driver_ndis uses WinPcap for low-level operations. This can be -+# replaced with the following option which replaces WinPcap calls with NDISUIO. -+# However, this requires that WZC is disabled (net stop wzcsvc) before starting -+# wpa_supplicant. -+# CONFIG_USE_NDISUIO=y -+ -+# Driver interface for wired Ethernet drivers -+CONFIG_DRIVER_WIRED=y -+ -+# Driver interface for MACsec capable Qualcomm Atheros drivers -+#CONFIG_DRIVER_MACSEC_QCA=y -+ -+# Driver interface for Linux MACsec drivers -+#CONFIG_DRIVER_MACSEC_LINUX=y -+ -+# Driver interface for the Broadcom RoboSwitch family -+#CONFIG_DRIVER_ROBOSWITCH=y -+ -+# Driver interface for no driver (e.g., WPS ER only) -+#CONFIG_DRIVER_NONE=y -+ -+# Solaris libraries -+#LIBS += -lsocket -ldlpi -lnsl -+#LIBS_c += -lsocket -+ -+# Enable IEEE 802.1X Supplicant (automatically included if any EAP method or -+# MACsec is included) -+CONFIG_IEEE8021X_EAPOL=y -+ -+# EAP-MD5 -+CONFIG_EAP_MD5=y -+ -+# EAP-MSCHAPv2 -+CONFIG_EAP_MSCHAPV2=y -+ -+# EAP-TLS -+CONFIG_EAP_TLS=y -+ -+# EAL-PEAP -+CONFIG_EAP_PEAP=y -+ -+# EAP-TTLS -+CONFIG_EAP_TTLS=y -+ -+# EAP-FAST -+CONFIG_EAP_FAST=y -+ -+# EAP-TEAP -+# Note: The current EAP-TEAP implementation is experimental and should not be -+# enabled for production use. The IETF RFC 7170 that defines EAP-TEAP has number -+# of conflicting statements and missing details and the implementation has -+# vendor specific workarounds for those and as such, may not interoperate with -+# any other implementation. This should not be used for anything else than -+# experimentation and interoperability testing until those issues has been -+# resolved. -+#CONFIG_EAP_TEAP=y -+ -+# EAP-GTC -+CONFIG_EAP_GTC=y -+ -+# EAP-OTP -+CONFIG_EAP_OTP=y -+ -+# EAP-SIM (enable CONFIG_PCSC, if EAP-SIM is used) -+#CONFIG_EAP_SIM=y -+ -+# Enable SIM simulator (Milenage) for EAP-SIM -+#CONFIG_SIM_SIMULATOR=y -+ -+# EAP-PSK (experimental; this is _not_ needed for WPA-PSK) -+#CONFIG_EAP_PSK=y -+ -+# EAP-pwd (secure authentication using only a password) -+#CONFIG_EAP_PWD=y -+ -+# EAP-PAX -+#CONFIG_EAP_PAX=y -+ -+# LEAP -+CONFIG_EAP_LEAP=y -+ -+# EAP-AKA (enable CONFIG_PCSC, if EAP-AKA is used) -+#CONFIG_EAP_AKA=y -+ -+# EAP-AKA' (enable CONFIG_PCSC, if EAP-AKA' is used). -+# This requires CONFIG_EAP_AKA to be enabled, too. -+#CONFIG_EAP_AKA_PRIME=y -+ -+# Enable USIM simulator (Milenage) for EAP-AKA -+#CONFIG_USIM_SIMULATOR=y -+ -+# EAP-SAKE -+#CONFIG_EAP_SAKE=y -+ -+# EAP-GPSK -+#CONFIG_EAP_GPSK=y -+# Include support for optional SHA256 cipher suite in EAP-GPSK -+#CONFIG_EAP_GPSK_SHA256=y -+ -+# EAP-TNC and related Trusted Network Connect support (experimental) -+#CONFIG_EAP_TNC=y -+ -+# Wi-Fi Protected Setup (WPS) -+CONFIG_WPS=y -+# Enable WPS external registrar functionality -+#CONFIG_WPS_ER=y -+# Disable credentials for an open network by default when acting as a WPS -+# registrar. -+#CONFIG_WPS_REG_DISABLE_OPEN=y -+# Enable WPS support with NFC config method -+#CONFIG_WPS_NFC=y -+ -+# EAP-IKEv2 -+#CONFIG_EAP_IKEV2=y -+ -+# EAP-EKE -+#CONFIG_EAP_EKE=y -+ -+# MACsec -+#CONFIG_MACSEC=y -+ -+# PKCS#12 (PFX) support (used to read private key and certificate file from -+# a file that usually has extension .p12 or .pfx) -+CONFIG_PKCS12=y -+ -+# Smartcard support (i.e., private key on a smartcard), e.g., with openssl -+# engine. -+CONFIG_SMARTCARD=y -+ -+# PC/SC interface for smartcards (USIM, GSM SIM) -+# Enable this if EAP-SIM or EAP-AKA is included -+#CONFIG_PCSC=y -+ -+# Support HT overrides (disable HT/HT40, mask MCS rates, etc.) -+CONFIG_HT_OVERRIDES=y -+ -+# Support VHT overrides (disable VHT, mask MCS rates, etc.) -+CONFIG_VHT_OVERRIDES=y -+ -+# Development testing -+#CONFIG_EAPOL_TEST=y -+ -+# Select control interface backend for external programs, e.g, wpa_cli: -+# unix = UNIX domain sockets (default for Linux/*BSD) -+# udp = UDP sockets using localhost (127.0.0.1) -+# udp6 = UDP IPv6 sockets using localhost (::1) -+# named_pipe = Windows Named Pipe (default for Windows) -+# udp-remote = UDP sockets with remote access (only for tests systems/purpose) -+# udp6-remote = UDP IPv6 sockets with remote access (only for tests purpose) -+# y = use default (backwards compatibility) -+# If this option is commented out, control interface is not included in the -+# build. -+CONFIG_CTRL_IFACE=y -+ -+# Include support for GNU Readline and History Libraries in wpa_cli. -+# When building a wpa_cli binary for distribution, please note that these -+# libraries are licensed under GPL and as such, BSD license may not apply for -+# the resulting binary. -+#CONFIG_READLINE=y -+ -+# Include internal line edit mode in wpa_cli. This can be used as a replacement -+# for GNU Readline to provide limited command line editing and history support. -+#CONFIG_WPA_CLI_EDIT=y -+ -+# Remove debugging code that is printing out debug message to stdout. -+# This can be used to reduce the size of the wpa_supplicant considerably -+# if debugging code is not needed. The size reduction can be around 35% -+# (e.g., 90 kB). -+#CONFIG_NO_STDOUT_DEBUG=y -+ -+# Remove WPA support, e.g., for wired-only IEEE 802.1X supplicant, to save -+# 35-50 kB in code size. -+#CONFIG_NO_WPA=y -+ -+# Remove IEEE 802.11i/WPA-Personal ASCII passphrase support -+# This option can be used to reduce code size by removing support for -+# converting ASCII passphrases into PSK. If this functionality is removed, the -+# PSK can only be configured as the 64-octet hexstring (e.g., from -+# wpa_passphrase). This saves about 0.5 kB in code size. -+#CONFIG_NO_WPA_PASSPHRASE=y -+ -+# Simultaneous Authentication of Equals (SAE), WPA3-Personal -+#CONFIG_SAE=y -+ -+# Disable scan result processing (ap_mode=1) to save code size by about 1 kB. -+# This can be used if ap_scan=1 mode is never enabled. -+#CONFIG_NO_SCAN_PROCESSING=y -+ -+# Select configuration backend: -+# file = text file (e.g., wpa_supplicant.conf; note: the configuration file -+# path is given on command line, not here; this option is just used to -+# select the backend that allows configuration files to be used) -+# winreg = Windows registry (see win_example.reg for an example) -+CONFIG_BACKEND=file -+ -+# Remove configuration write functionality (i.e., to allow the configuration -+# file to be updated based on runtime configuration changes). The runtime -+# configuration can still be changed, the changes are just not going to be -+# persistent over restarts. This option can be used to reduce code size by -+# about 3.5 kB. -+#CONFIG_NO_CONFIG_WRITE=y -+ -+# Remove support for configuration blobs to reduce code size by about 1.5 kB. -+#CONFIG_NO_CONFIG_BLOBS=y -+ -+# Select program entry point implementation: -+# main = UNIX/POSIX like main() function (default) -+# main_winsvc = Windows service (read parameters from registry) -+# main_none = Very basic example (development use only) -+#CONFIG_MAIN=main -+ -+# Select wrapper for operating system and C library specific functions -+# unix = UNIX/POSIX like systems (default) -+# win32 = Windows systems -+# none = Empty template -+#CONFIG_OS=unix -+ -+# Select event loop implementation -+# eloop = select() loop (default) -+# eloop_win = Windows events and WaitForMultipleObject() loop -+#CONFIG_ELOOP=eloop -+ -+# Should we use poll instead of select? Select is used by default. -+#CONFIG_ELOOP_POLL=y -+ -+# Should we use epoll instead of select? Select is used by default. -+CONFIG_ELOOP_EPOLL=y -+ -+# Should we use kqueue instead of select? Select is used by default. -+#CONFIG_ELOOP_KQUEUE=y -+ -+# Select layer 2 packet implementation -+# linux = Linux packet socket (default) -+# pcap = libpcap/libdnet/WinPcap -+# freebsd = FreeBSD libpcap -+# winpcap = WinPcap with receive thread -+# ndis = Windows NDISUIO (note: requires CONFIG_USE_NDISUIO=y) -+# none = Empty template -+#CONFIG_L2_PACKET=linux -+ -+# Disable Linux packet socket workaround applicable for station interface -+# in a bridge for EAPOL frames. This should be uncommented only if the kernel -+# is known to not have the regression issue in packet socket behavior with -+# bridge interfaces (commit 'bridge: respect RFC2863 operational state')'). -+CONFIG_NO_LINUX_PACKET_SOCKET_WAR=y -+ -+# IEEE 802.11w (management frame protection), also known as PMF -+# Driver support is also needed for IEEE 802.11w. -+#CONFIG_IEEE80211W=y -+ -+# Support Operating Channel Validation -+CONFIG_OCV=y -+ -+# Select TLS implementation -+# openssl = OpenSSL (default) -+# gnutls = GnuTLS -+# internal = Internal TLSv1 implementation (experimental) -+# linux = Linux kernel AF_ALG and internal TLSv1 implementation (experimental) -+# none = Empty template -+CONFIG_TLS=internal -+ -+# TLS-based EAP methods require at least TLS v1.0. Newer version of TLS (v1.1) -+# can be enabled to get a stronger construction of messages when block ciphers -+# are used. It should be noted that some existing TLS v1.0 -based -+# implementation may not be compatible with TLS v1.1 message (ClientHello is -+# sent prior to negotiating which version will be used) -+#CONFIG_TLSV11=y -+ -+# TLS-based EAP methods require at least TLS v1.0. Newer version of TLS (v1.2) -+# can be enabled to enable use of stronger crypto algorithms. It should be -+# noted that some existing TLS v1.0 -based implementation may not be compatible -+# with TLS v1.2 message (ClientHello is sent prior to negotiating which version -+# will be used) -+#CONFIG_TLSV12=y -+ -+# Select which ciphers to use by default with OpenSSL if the user does not -+# specify them. -+#CONFIG_TLS_DEFAULT_CIPHERS="DEFAULT:!EXP:!LOW" -+ -+# If CONFIG_TLS=internal is used, additional library and include paths are -+# needed for LibTomMath. Alternatively, an integrated, minimal version of -+# LibTomMath can be used. See beginning of libtommath.c for details on benefits -+# and drawbacks of this option. -+CONFIG_INTERNAL_LIBTOMMATH=y -+#ifndef CONFIG_INTERNAL_LIBTOMMATH -+#LTM_PATH=/usr/src/libtommath-0.39 -+#CFLAGS += -I$(LTM_PATH) -+#LIBS += -L$(LTM_PATH) -+#LIBS_p += -L$(LTM_PATH) -+#endif -+# At the cost of about 4 kB of additional binary size, the internal LibTomMath -+# can be configured to include faster routines for exptmod, sqr, and div to -+# speed up DH and RSA calculation considerably -+CONFIG_INTERNAL_LIBTOMMATH_FAST=y -+ -+# Include NDIS event processing through WMI into wpa_supplicant/wpasvc. -+# This is only for Windows builds and requires WMI-related header files and -+# WbemUuid.Lib from Platform SDK even when building with MinGW. -+#CONFIG_NDIS_EVENTS_INTEGRATED=y -+#PLATFORMSDKLIB="/opt/Program Files/Microsoft Platform SDK/Lib" -+ -+# Add support for new DBus control interface -+# (fi.w1.hostap.wpa_supplicant1) -+#CONFIG_CTRL_IFACE_DBUS_NEW=y -+ -+# Add introspection support for new DBus control interface -+#CONFIG_CTRL_IFACE_DBUS_INTRO=y -+ -+# Add support for loading EAP methods dynamically as shared libraries. -+# When this option is enabled, each EAP method can be either included -+# statically (CONFIG_EAP_=y) or dynamically (CONFIG_EAP_=dyn). -+# Dynamic EAP methods are build as shared objects (eap_*.so) and they need to -+# be loaded in the beginning of the wpa_supplicant configuration file -+# (see load_dynamic_eap parameter in the example file) before being used in -+# the network blocks. -+# -+# Note that some shared parts of EAP methods are included in the main program -+# and in order to be able to use dynamic EAP methods using these parts, the -+# main program must have been build with the EAP method enabled (=y or =dyn). -+# This means that EAP-TLS/PEAP/TTLS/FAST cannot be added as dynamic libraries -+# unless at least one of them was included in the main build to force inclusion -+# of the shared code. Similarly, at least one of EAP-SIM/AKA must be included -+# in the main build to be able to load these methods dynamically. -+# -+# Please also note that using dynamic libraries will increase the total binary -+# size. Thus, it may not be the best option for targets that have limited -+# amount of memory/flash. -+#CONFIG_DYNAMIC_EAP_METHODS=y -+ -+# IEEE Std 802.11r-2008 (Fast BSS Transition) for station mode -+CONFIG_IEEE80211R=y -+ -+# Add support for writing debug log to a file (/tmp/wpa_supplicant-log-#.txt) -+#CONFIG_DEBUG_FILE=y -+ -+# Send debug messages to syslog instead of stdout -+CONFIG_DEBUG_SYSLOG=y -+# Set syslog facility for debug messages -+CONFIG_DEBUG_SYSLOG_FACILITY=LOG_DAEMON -+ -+# Add support for sending all debug messages (regardless of debug verbosity) -+# to the Linux kernel tracing facility. This helps debug the entire stack by -+# making it easy to record everything happening from the driver up into the -+# same file, e.g., using trace-cmd. -+#CONFIG_DEBUG_LINUX_TRACING=y -+ -+# Add support for writing debug log to Android logcat instead of standard -+# output -+#CONFIG_ANDROID_LOG=y -+ -+# Enable privilege separation (see README 'Privilege separation' for details) -+#CONFIG_PRIVSEP=y -+ -+# Enable mitigation against certain attacks against TKIP by delaying Michael -+# MIC error reports by a random amount of time between 0 and 60 seconds -+#CONFIG_DELAYED_MIC_ERROR_REPORT=y -+ -+# Enable tracing code for developer debugging -+# This tracks use of memory allocations and other registrations and reports -+# incorrect use with a backtrace of call (or allocation) location. -+#CONFIG_WPA_TRACE=y -+# For BSD, uncomment these. -+#LIBS += -lexecinfo -+#LIBS_p += -lexecinfo -+#LIBS_c += -lexecinfo -+ -+# Use libbfd to get more details for developer debugging -+# This enables use of libbfd to get more detailed symbols for the backtraces -+# generated by CONFIG_WPA_TRACE=y. -+#CONFIG_WPA_TRACE_BFD=y -+# For BSD, uncomment these. -+#LIBS += -lbfd -liberty -lz -+#LIBS_p += -lbfd -liberty -lz -+#LIBS_c += -lbfd -liberty -lz -+ -+# wpa_supplicant depends on strong random number generation being available -+# from the operating system. os_get_random() function is used to fetch random -+# data when needed, e.g., for key generation. On Linux and BSD systems, this -+# works by reading /dev/urandom. It should be noted that the OS entropy pool -+# needs to be properly initialized before wpa_supplicant is started. This is -+# important especially on embedded devices that do not have a hardware random -+# number generator and may by default start up with minimal entropy available -+# for random number generation. -+# -+# As a safety net, wpa_supplicant is by default trying to internally collect -+# additional entropy for generating random data to mix in with the data fetched -+# from the OS. This by itself is not considered to be very strong, but it may -+# help in cases where the system pool is not initialized properly. However, it -+# is very strongly recommended that the system pool is initialized with enough -+# entropy either by using hardware assisted random number generator or by -+# storing state over device reboots. -+# -+# wpa_supplicant can be configured to maintain its own entropy store over -+# restarts to enhance random number generation. This is not perfect, but it is -+# much more secure than using the same sequence of random numbers after every -+# reboot. This can be enabled with -e command line option. The -+# specified file needs to be readable and writable by wpa_supplicant. -+# -+# If the os_get_random() is known to provide strong random data (e.g., on -+# Linux/BSD, the board in question is known to have reliable source of random -+# data from /dev/urandom), the internal wpa_supplicant random pool can be -+# disabled. This will save some in binary size and CPU use. However, this -+# should only be considered for builds that are known to be used on devices -+# that meet the requirements described above. -+CONFIG_NO_RANDOM_POOL=y -+ -+# Should we attempt to use the getrandom(2) call that provides more reliable -+# yet secure randomness source than /dev/random on Linux 3.17 and newer. -+# Requires glibc 2.25 to build, falls back to /dev/random if unavailable. -+CONFIG_GETRANDOM=y -+ -+# IEEE 802.11n (High Throughput) support (mainly for AP mode) -+#CONFIG_IEEE80211N=y -+ -+# IEEE 802.11ac (Very High Throughput) support (mainly for AP mode) -+# (depends on CONFIG_IEEE80211N) -+#CONFIG_IEEE80211AC=y -+ -+# Wireless Network Management (IEEE Std 802.11v-2011) -+# Note: This is experimental and not complete implementation. -+CONFIG_WNM=y -+ -+# Interworking (IEEE 802.11u) -+# This can be used to enable functionality to improve interworking with -+# external networks (GAS/ANQP to learn more about the networks and network -+# selection based on available credentials). -+CONFIG_INTERWORKING=y -+ -+# Hotspot 2.0 -+CONFIG_HS20=y -+ -+# Enable interface matching in wpa_supplicant -+#CONFIG_MATCH_IFACE=y -+ -+# Disable roaming in wpa_supplicant -+#CONFIG_NO_ROAMING=y -+ -+# AP mode operations with wpa_supplicant -+# This can be used for controlling AP mode operations with wpa_supplicant. It -+# should be noted that this is mainly aimed at simple cases like -+# WPA2-Personal while more complex configurations like WPA2-Enterprise with an -+# external RADIUS server can be supported with hostapd. -+#CONFIG_AP=y -+ -+# P2P (Wi-Fi Direct) -+# This can be used to enable P2P support in wpa_supplicant. See README-P2P for -+# more information on P2P operations. -+#CONFIG_P2P=y -+ -+# Enable TDLS support -+#CONFIG_TDLS=y -+ -+# Wi-Fi Display -+# This can be used to enable Wi-Fi Display extensions for P2P using an external -+# program to control the additional information exchanges in the messages. -+#CONFIG_WIFI_DISPLAY=y -+ -+# Autoscan -+# This can be used to enable automatic scan support in wpa_supplicant. -+# See wpa_supplicant.conf for more information on autoscan usage. -+# -+# Enabling directly a module will enable autoscan support. -+# For exponential module: -+#CONFIG_AUTOSCAN_EXPONENTIAL=y -+# For periodic module: -+#CONFIG_AUTOSCAN_PERIODIC=y -+ -+# Password (and passphrase, etc.) backend for external storage -+# These optional mechanisms can be used to add support for storing passwords -+# and other secrets in external (to wpa_supplicant) location. This allows, for -+# example, operating system specific key storage to be used -+# -+# External password backend for testing purposes (developer use) -+#CONFIG_EXT_PASSWORD_TEST=y -+ -+# Enable Fast Session Transfer (FST) -+#CONFIG_FST=y -+ -+# Enable CLI commands for FST testing -+#CONFIG_FST_TEST=y -+ -+# OS X builds. This is only for building eapol_test. -+#CONFIG_OSX=y -+ -+# Automatic Channel Selection -+# This will allow wpa_supplicant to pick the channel automatically when channel -+# is set to "0". -+# -+# TODO: Extend parser to be able to parse "channel=acs_survey" as an alternative -+# to "channel=0". This would enable us to eventually add other ACS algorithms in -+# similar way. -+# -+# Automatic selection is currently only done through initialization, later on -+# we hope to do background checks to keep us moving to more ideal channels as -+# time goes by. ACS is currently only supported through the nl80211 driver and -+# your driver must have survey dump capability that is filled by the driver -+# during scanning. -+# -+# TODO: In analogy to hostapd be able to customize the ACS survey algorithm with -+# a newly to create wpa_supplicant.conf variable acs_num_scans. -+# -+# Supported ACS drivers: -+# * ath9k -+# * ath5k -+# * ath10k -+# -+# For more details refer to: -+# http://wireless.kernel.org/en/users/Documentation/acs -+#CONFIG_ACS=y -+ -+# Support Multi Band Operation -+#CONFIG_MBO=y -+ -+# Fast Initial Link Setup (FILS) (IEEE 802.11ai) -+CONFIG_FILS=y -+# FILS shared key authentication with PFS -+#CONFIG_FILS_SK_PFS=y -+ -+# Support RSN on IBSS networks -+# This is needed to be able to use mode=1 network profile with proto=RSN and -+# key_mgmt=WPA-PSK (i.e., full key management instead of WPA-None). -+CONFIG_IBSS_RSN=y -+ -+# External PMKSA cache control -+# This can be used to enable control interface commands that allow the current -+# PMKSA cache entries to be fetched and new entries to be added. -+#CONFIG_PMKSA_CACHE_EXTERNAL=y -+ -+# Mesh Networking (IEEE 802.11s) -+#CONFIG_MESH=y -+ -+# Background scanning modules -+# These can be used to request wpa_supplicant to perform background scanning -+# operations for roaming within an ESS (same SSID). See the bgscan parameter in -+# the wpa_supplicant.conf file for more details. -+# Periodic background scans based on signal strength -+#CONFIG_BGSCAN_SIMPLE=y -+# Learn channels used by the network and try to avoid bgscans on other -+# channels (experimental) -+#CONFIG_BGSCAN_LEARN=y -+ -+# Opportunistic Wireless Encryption (OWE) -+# Experimental implementation of draft-harkins-owe-07.txt -+#CONFIG_OWE=y -+ -+# Device Provisioning Protocol (DPP) -+# This requires CONFIG_IEEE80211W=y to be enabled, too. (see -+# wpa_supplicant/README-DPP for details) -+#CONFIG_DPP=y -+ -+# uBus IPC/RPC System -+# Services can connect to the bus and provide methods -+# that can be called by other services or clients. -+CONFIG_UBUS=y -+ -+# OpenWrt patch 380-disable-ctrl-iface-mib.patch -+# leads to the MIB only being compiled in if -+# CONFIG_CTRL_IFACE_MIB is enabled. -+CONFIG_CTRL_IFACE_MIB=y -diff --git a/package/network/services/hostapd/files/wpa_supplicant-mini.config b/package/network/services/hostapd/files/wpa_supplicant-mini.config -new file mode 100644 -index 0000000000..2a3f8fb69d ---- /dev/null -+++ b/package/network/services/hostapd/files/wpa_supplicant-mini.config -@@ -0,0 +1,625 @@ -+# Example wpa_supplicant build time configuration -+# -+# This file lists the configuration options that are used when building the -+# wpa_supplicant binary. All lines starting with # are ignored. Configuration -+# option lines must be commented out complete, if they are not to be included, -+# i.e., just setting VARIABLE=n is not disabling that variable. -+# -+# This file is included in Makefile, so variables like CFLAGS and LIBS can also -+# be modified from here. In most cases, these lines should use += in order not -+# to override previous values of the variables. -+ -+ -+# Uncomment following two lines and fix the paths if you have installed OpenSSL -+# or GnuTLS in non-default location -+#CFLAGS += -I/usr/local/openssl/include -+#LIBS += -L/usr/local/openssl/lib -+ -+# Some Red Hat versions seem to include kerberos header files from OpenSSL, but -+# the kerberos files are not in the default include path. Following line can be -+# used to fix build issues on such systems (krb5.h not found). -+#CFLAGS += -I/usr/include/kerberos -+ -+# 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 -+# replacement for WEXT and its use allows wpa_supplicant to properly control -+# the driver to improve existing functionality like roaming and to support new -+# functionality. -+#CONFIG_DRIVER_WEXT=y -+ -+# Driver interface for Linux drivers using the nl80211 kernel interface -+CONFIG_DRIVER_NL80211=y -+ -+# QCA vendor extensions to nl80211 -+#CONFIG_DRIVER_NL80211_QCA=y -+ -+# driver_nl80211.c requires libnl. If you are compiling it yourself -+# you may need to point hostapd to your version of libnl. -+# -+#CFLAGS += -I$ -+#LIBS += -L$ -+ -+# Use libnl v2.0 (or 3.0) libraries. -+#CONFIG_LIBNL20=y -+ -+# Use libnl 3.2 libraries (if this is selected, CONFIG_LIBNL20 is ignored) -+#CONFIG_LIBNL32=y -+ -+ -+# Driver interface for FreeBSD net80211 layer (e.g., Atheros driver) -+#CONFIG_DRIVER_BSD=y -+#CFLAGS += -I/usr/local/include -+#LIBS += -L/usr/local/lib -+#LIBS_p += -L/usr/local/lib -+#LIBS_c += -L/usr/local/lib -+ -+# Driver interface for Windows NDIS -+#CONFIG_DRIVER_NDIS=y -+#CFLAGS += -I/usr/include/w32api/ddk -+#LIBS += -L/usr/local/lib -+# For native build using mingw -+#CONFIG_NATIVE_WINDOWS=y -+# Additional directories for cross-compilation on Linux host for mingw target -+#CFLAGS += -I/opt/mingw/mingw32/include/ddk -+#LIBS += -L/opt/mingw/mingw32/lib -+#CC=mingw32-gcc -+# By default, driver_ndis uses WinPcap for low-level operations. This can be -+# replaced with the following option which replaces WinPcap calls with NDISUIO. -+# However, this requires that WZC is disabled (net stop wzcsvc) before starting -+# wpa_supplicant. -+# CONFIG_USE_NDISUIO=y -+ -+# Driver interface for wired Ethernet drivers -+CONFIG_DRIVER_WIRED=y -+ -+# Driver interface for MACsec capable Qualcomm Atheros drivers -+#CONFIG_DRIVER_MACSEC_QCA=y -+ -+# Driver interface for Linux MACsec drivers -+#CONFIG_DRIVER_MACSEC_LINUX=y -+ -+# Driver interface for the Broadcom RoboSwitch family -+#CONFIG_DRIVER_ROBOSWITCH=y -+ -+# Driver interface for no driver (e.g., WPS ER only) -+#CONFIG_DRIVER_NONE=y -+ -+# Solaris libraries -+#LIBS += -lsocket -ldlpi -lnsl -+#LIBS_c += -lsocket -+ -+# Enable IEEE 802.1X Supplicant (automatically included if any EAP method or -+# MACsec is included) -+#CONFIG_IEEE8021X_EAPOL=y -+ -+# EAP-MD5 -+#CONFIG_EAP_MD5=y -+ -+# EAP-MSCHAPv2 -+#CONFIG_EAP_MSCHAPV2=y -+ -+# EAP-TLS -+#CONFIG_EAP_TLS=y -+ -+# EAL-PEAP -+#CONFIG_EAP_PEAP=y -+ -+# EAP-TTLS -+#CONFIG_EAP_TTLS=y -+ -+# EAP-FAST -+#CONFIG_EAP_FAST=y -+ -+# EAP-TEAP -+# Note: The current EAP-TEAP implementation is experimental and should not be -+# enabled for production use. The IETF RFC 7170 that defines EAP-TEAP has number -+# of conflicting statements and missing details and the implementation has -+# vendor specific workarounds for those and as such, may not interoperate with -+# any other implementation. This should not be used for anything else than -+# experimentation and interoperability testing until those issues has been -+# resolved. -+#CONFIG_EAP_TEAP=y -+ -+# EAP-GTC -+#CONFIG_EAP_GTC=y -+ -+# EAP-OTP -+#CONFIG_EAP_OTP=y -+ -+# EAP-SIM (enable CONFIG_PCSC, if EAP-SIM is used) -+#CONFIG_EAP_SIM=y -+ -+# Enable SIM simulator (Milenage) for EAP-SIM -+#CONFIG_SIM_SIMULATOR=y -+ -+# EAP-PSK (experimental; this is _not_ needed for WPA-PSK) -+#CONFIG_EAP_PSK=y -+ -+# EAP-pwd (secure authentication using only a password) -+#CONFIG_EAP_PWD=y -+ -+# EAP-PAX -+#CONFIG_EAP_PAX=y -+ -+# LEAP -+#CONFIG_EAP_LEAP=y -+ -+# EAP-AKA (enable CONFIG_PCSC, if EAP-AKA is used) -+#CONFIG_EAP_AKA=y -+ -+# EAP-AKA' (enable CONFIG_PCSC, if EAP-AKA' is used). -+# This requires CONFIG_EAP_AKA to be enabled, too. -+#CONFIG_EAP_AKA_PRIME=y -+ -+# Enable USIM simulator (Milenage) for EAP-AKA -+#CONFIG_USIM_SIMULATOR=y -+ -+# EAP-SAKE -+#CONFIG_EAP_SAKE=y -+ -+# EAP-GPSK -+#CONFIG_EAP_GPSK=y -+# Include support for optional SHA256 cipher suite in EAP-GPSK -+#CONFIG_EAP_GPSK_SHA256=y -+ -+# EAP-TNC and related Trusted Network Connect support (experimental) -+#CONFIG_EAP_TNC=y -+ -+# Wi-Fi Protected Setup (WPS) -+#CONFIG_WPS=y -+# Enable WPS external registrar functionality -+#CONFIG_WPS_ER=y -+# Disable credentials for an open network by default when acting as a WPS -+# registrar. -+#CONFIG_WPS_REG_DISABLE_OPEN=y -+# Enable WPS support with NFC config method -+#CONFIG_WPS_NFC=y -+ -+# EAP-IKEv2 -+#CONFIG_EAP_IKEV2=y -+ -+# EAP-EKE -+#CONFIG_EAP_EKE=y -+ -+# MACsec -+#CONFIG_MACSEC=y -+ -+# PKCS#12 (PFX) support (used to read private key and certificate file from -+# a file that usually has extension .p12 or .pfx) -+#CONFIG_PKCS12=y -+ -+# Smartcard support (i.e., private key on a smartcard), e.g., with openssl -+# engine. -+#CONFIG_SMARTCARD=y -+ -+# PC/SC interface for smartcards (USIM, GSM SIM) -+# Enable this if EAP-SIM or EAP-AKA is included -+#CONFIG_PCSC=y -+ -+# Support HT overrides (disable HT/HT40, mask MCS rates, etc.) -+CONFIG_HT_OVERRIDES=y -+ -+# Support VHT overrides (disable VHT, mask MCS rates, etc.) -+CONFIG_VHT_OVERRIDES=y -+ -+# Development testing -+#CONFIG_EAPOL_TEST=y -+ -+# Select control interface backend for external programs, e.g, wpa_cli: -+# unix = UNIX domain sockets (default for Linux/*BSD) -+# udp = UDP sockets using localhost (127.0.0.1) -+# udp6 = UDP IPv6 sockets using localhost (::1) -+# named_pipe = Windows Named Pipe (default for Windows) -+# udp-remote = UDP sockets with remote access (only for tests systems/purpose) -+# udp6-remote = UDP IPv6 sockets with remote access (only for tests purpose) -+# y = use default (backwards compatibility) -+# If this option is commented out, control interface is not included in the -+# build. -+CONFIG_CTRL_IFACE=y -+ -+# Include support for GNU Readline and History Libraries in wpa_cli. -+# When building a wpa_cli binary for distribution, please note that these -+# libraries are licensed under GPL and as such, BSD license may not apply for -+# the resulting binary. -+#CONFIG_READLINE=y -+ -+# Include internal line edit mode in wpa_cli. This can be used as a replacement -+# for GNU Readline to provide limited command line editing and history support. -+#CONFIG_WPA_CLI_EDIT=y -+ -+# Remove debugging code that is printing out debug message to stdout. -+# This can be used to reduce the size of the wpa_supplicant considerably -+# if debugging code is not needed. The size reduction can be around 35% -+# (e.g., 90 kB). -+#CONFIG_NO_STDOUT_DEBUG=y -+ -+# Remove WPA support, e.g., for wired-only IEEE 802.1X supplicant, to save -+# 35-50 kB in code size. -+#CONFIG_NO_WPA=y -+ -+# Remove IEEE 802.11i/WPA-Personal ASCII passphrase support -+# This option can be used to reduce code size by removing support for -+# converting ASCII passphrases into PSK. If this functionality is removed, the -+# PSK can only be configured as the 64-octet hexstring (e.g., from -+# wpa_passphrase). This saves about 0.5 kB in code size. -+#CONFIG_NO_WPA_PASSPHRASE=y -+ -+# Simultaneous Authentication of Equals (SAE), WPA3-Personal -+#CONFIG_SAE=y -+ -+# Disable scan result processing (ap_mode=1) to save code size by about 1 kB. -+# This can be used if ap_scan=1 mode is never enabled. -+#CONFIG_NO_SCAN_PROCESSING=y -+ -+# Select configuration backend: -+# file = text file (e.g., wpa_supplicant.conf; note: the configuration file -+# path is given on command line, not here; this option is just used to -+# select the backend that allows configuration files to be used) -+# winreg = Windows registry (see win_example.reg for an example) -+CONFIG_BACKEND=file -+ -+# Remove configuration write functionality (i.e., to allow the configuration -+# file to be updated based on runtime configuration changes). The runtime -+# configuration can still be changed, the changes are just not going to be -+# persistent over restarts. This option can be used to reduce code size by -+# about 3.5 kB. -+CONFIG_NO_CONFIG_WRITE=y -+ -+# Remove support for configuration blobs to reduce code size by about 1.5 kB. -+#CONFIG_NO_CONFIG_BLOBS=y -+ -+# Select program entry point implementation: -+# main = UNIX/POSIX like main() function (default) -+# main_winsvc = Windows service (read parameters from registry) -+# main_none = Very basic example (development use only) -+#CONFIG_MAIN=main -+ -+# Select wrapper for operating system and C library specific functions -+# unix = UNIX/POSIX like systems (default) -+# win32 = Windows systems -+# none = Empty template -+#CONFIG_OS=unix -+ -+# Select event loop implementation -+# eloop = select() loop (default) -+# eloop_win = Windows events and WaitForMultipleObject() loop -+#CONFIG_ELOOP=eloop -+ -+# Should we use poll instead of select? Select is used by default. -+#CONFIG_ELOOP_POLL=y -+ -+# Should we use epoll instead of select? Select is used by default. -+CONFIG_ELOOP_EPOLL=y -+ -+# Should we use kqueue instead of select? Select is used by default. -+#CONFIG_ELOOP_KQUEUE=y -+ -+# Select layer 2 packet implementation -+# linux = Linux packet socket (default) -+# pcap = libpcap/libdnet/WinPcap -+# freebsd = FreeBSD libpcap -+# winpcap = WinPcap with receive thread -+# ndis = Windows NDISUIO (note: requires CONFIG_USE_NDISUIO=y) -+# none = Empty template -+#CONFIG_L2_PACKET=linux -+ -+# Disable Linux packet socket workaround applicable for station interface -+# in a bridge for EAPOL frames. This should be uncommented only if the kernel -+# is known to not have the regression issue in packet socket behavior with -+# bridge interfaces (commit 'bridge: respect RFC2863 operational state')'). -+CONFIG_NO_LINUX_PACKET_SOCKET_WAR=y -+ -+# IEEE 802.11w (management frame protection), also known as PMF -+# Driver support is also needed for IEEE 802.11w. -+#CONFIG_IEEE80211W=y -+ -+# Support Operating Channel Validation -+#CONFIG_OCV=y -+ -+# Select TLS implementation -+# openssl = OpenSSL (default) -+# gnutls = GnuTLS -+# internal = Internal TLSv1 implementation (experimental) -+# linux = Linux kernel AF_ALG and internal TLSv1 implementation (experimental) -+# none = Empty template -+CONFIG_TLS=internal -+ -+# TLS-based EAP methods require at least TLS v1.0. Newer version of TLS (v1.1) -+# can be enabled to get a stronger construction of messages when block ciphers -+# are used. It should be noted that some existing TLS v1.0 -based -+# implementation may not be compatible with TLS v1.1 message (ClientHello is -+# sent prior to negotiating which version will be used) -+#CONFIG_TLSV11=y -+ -+# TLS-based EAP methods require at least TLS v1.0. Newer version of TLS (v1.2) -+# can be enabled to enable use of stronger crypto algorithms. It should be -+# noted that some existing TLS v1.0 -based implementation may not be compatible -+# with TLS v1.2 message (ClientHello is sent prior to negotiating which version -+# will be used) -+#CONFIG_TLSV12=y -+ -+# Select which ciphers to use by default with OpenSSL if the user does not -+# specify them. -+#CONFIG_TLS_DEFAULT_CIPHERS="DEFAULT:!EXP:!LOW" -+ -+# If CONFIG_TLS=internal is used, additional library and include paths are -+# needed for LibTomMath. Alternatively, an integrated, minimal version of -+# LibTomMath can be used. See beginning of libtommath.c for details on benefits -+# and drawbacks of this option. -+#CONFIG_INTERNAL_LIBTOMMATH=y -+#ifndef CONFIG_INTERNAL_LIBTOMMATH -+#LTM_PATH=/usr/src/libtommath-0.39 -+#CFLAGS += -I$(LTM_PATH) -+#LIBS += -L$(LTM_PATH) -+#LIBS_p += -L$(LTM_PATH) -+#endif -+# At the cost of about 4 kB of additional binary size, the internal LibTomMath -+# can be configured to include faster routines for exptmod, sqr, and div to -+# speed up DH and RSA calculation considerably -+#CONFIG_INTERNAL_LIBTOMMATH_FAST=y -+ -+# Include NDIS event processing through WMI into wpa_supplicant/wpasvc. -+# This is only for Windows builds and requires WMI-related header files and -+# WbemUuid.Lib from Platform SDK even when building with MinGW. -+#CONFIG_NDIS_EVENTS_INTEGRATED=y -+#PLATFORMSDKLIB="/opt/Program Files/Microsoft Platform SDK/Lib" -+ -+# Add support for new DBus control interface -+# (fi.w1.hostap.wpa_supplicant1) -+#CONFIG_CTRL_IFACE_DBUS_NEW=y -+ -+# Add introspection support for new DBus control interface -+#CONFIG_CTRL_IFACE_DBUS_INTRO=y -+ -+# Add support for loading EAP methods dynamically as shared libraries. -+# When this option is enabled, each EAP method can be either included -+# statically (CONFIG_EAP_=y) or dynamically (CONFIG_EAP_=dyn). -+# Dynamic EAP methods are build as shared objects (eap_*.so) and they need to -+# be loaded in the beginning of the wpa_supplicant configuration file -+# (see load_dynamic_eap parameter in the example file) before being used in -+# the network blocks. -+# -+# Note that some shared parts of EAP methods are included in the main program -+# and in order to be able to use dynamic EAP methods using these parts, the -+# main program must have been build with the EAP method enabled (=y or =dyn). -+# This means that EAP-TLS/PEAP/TTLS/FAST cannot be added as dynamic libraries -+# unless at least one of them was included in the main build to force inclusion -+# of the shared code. Similarly, at least one of EAP-SIM/AKA must be included -+# in the main build to be able to load these methods dynamically. -+# -+# Please also note that using dynamic libraries will increase the total binary -+# size. Thus, it may not be the best option for targets that have limited -+# amount of memory/flash. -+#CONFIG_DYNAMIC_EAP_METHODS=y -+ -+# IEEE Std 802.11r-2008 (Fast BSS Transition) for station mode -+#CONFIG_IEEE80211R=y -+ -+# Add support for writing debug log to a file (/tmp/wpa_supplicant-log-#.txt) -+#CONFIG_DEBUG_FILE=y -+ -+# Send debug messages to syslog instead of stdout -+CONFIG_DEBUG_SYSLOG=y -+# Set syslog facility for debug messages -+CONFIG_DEBUG_SYSLOG_FACILITY=LOG_DAEMON -+ -+# Add support for sending all debug messages (regardless of debug verbosity) -+# to the Linux kernel tracing facility. This helps debug the entire stack by -+# making it easy to record everything happening from the driver up into the -+# same file, e.g., using trace-cmd. -+#CONFIG_DEBUG_LINUX_TRACING=y -+ -+# Add support for writing debug log to Android logcat instead of standard -+# output -+#CONFIG_ANDROID_LOG=y -+ -+# Enable privilege separation (see README 'Privilege separation' for details) -+#CONFIG_PRIVSEP=y -+ -+# Enable mitigation against certain attacks against TKIP by delaying Michael -+# MIC error reports by a random amount of time between 0 and 60 seconds -+#CONFIG_DELAYED_MIC_ERROR_REPORT=y -+ -+# Enable tracing code for developer debugging -+# This tracks use of memory allocations and other registrations and reports -+# incorrect use with a backtrace of call (or allocation) location. -+#CONFIG_WPA_TRACE=y -+# For BSD, uncomment these. -+#LIBS += -lexecinfo -+#LIBS_p += -lexecinfo -+#LIBS_c += -lexecinfo -+ -+# Use libbfd to get more details for developer debugging -+# This enables use of libbfd to get more detailed symbols for the backtraces -+# generated by CONFIG_WPA_TRACE=y. -+#CONFIG_WPA_TRACE_BFD=y -+# For BSD, uncomment these. -+#LIBS += -lbfd -liberty -lz -+#LIBS_p += -lbfd -liberty -lz -+#LIBS_c += -lbfd -liberty -lz -+ -+# wpa_supplicant depends on strong random number generation being available -+# from the operating system. os_get_random() function is used to fetch random -+# data when needed, e.g., for key generation. On Linux and BSD systems, this -+# works by reading /dev/urandom. It should be noted that the OS entropy pool -+# needs to be properly initialized before wpa_supplicant is started. This is -+# important especially on embedded devices that do not have a hardware random -+# number generator and may by default start up with minimal entropy available -+# for random number generation. -+# -+# As a safety net, wpa_supplicant is by default trying to internally collect -+# additional entropy for generating random data to mix in with the data fetched -+# from the OS. This by itself is not considered to be very strong, but it may -+# help in cases where the system pool is not initialized properly. However, it -+# is very strongly recommended that the system pool is initialized with enough -+# entropy either by using hardware assisted random number generator or by -+# storing state over device reboots. -+# -+# wpa_supplicant can be configured to maintain its own entropy store over -+# restarts to enhance random number generation. This is not perfect, but it is -+# much more secure than using the same sequence of random numbers after every -+# reboot. This can be enabled with -e command line option. The -+# specified file needs to be readable and writable by wpa_supplicant. -+# -+# If the os_get_random() is known to provide strong random data (e.g., on -+# Linux/BSD, the board in question is known to have reliable source of random -+# data from /dev/urandom), the internal wpa_supplicant random pool can be -+# disabled. This will save some in binary size and CPU use. However, this -+# should only be considered for builds that are known to be used on devices -+# that meet the requirements described above. -+CONFIG_NO_RANDOM_POOL=y -+ -+# Should we attempt to use the getrandom(2) call that provides more reliable -+# yet secure randomness source than /dev/random on Linux 3.17 and newer. -+# Requires glibc 2.25 to build, falls back to /dev/random if unavailable. -+CONFIG_GETRANDOM=y -+ -+# IEEE 802.11n (High Throughput) support (mainly for AP mode) -+#CONFIG_IEEE80211N=y -+ -+# IEEE 802.11ac (Very High Throughput) support (mainly for AP mode) -+# (depends on CONFIG_IEEE80211N) -+#CONFIG_IEEE80211AC=y -+ -+# Wireless Network Management (IEEE Std 802.11v-2011) -+# Note: This is experimental and not complete implementation. -+#CONFIG_WNM=y -+ -+# Interworking (IEEE 802.11u) -+# This can be used to enable functionality to improve interworking with -+# external networks (GAS/ANQP to learn more about the networks and network -+# selection based on available credentials). -+#CONFIG_INTERWORKING=y -+ -+# Hotspot 2.0 -+#CONFIG_HS20=y -+ -+# Enable interface matching in wpa_supplicant -+#CONFIG_MATCH_IFACE=y -+ -+# Disable roaming in wpa_supplicant -+#CONFIG_NO_ROAMING=y -+ -+# AP mode operations with wpa_supplicant -+# This can be used for controlling AP mode operations with wpa_supplicant. It -+# should be noted that this is mainly aimed at simple cases like -+# WPA2-Personal while more complex configurations like WPA2-Enterprise with an -+# external RADIUS server can be supported with hostapd. -+#CONFIG_AP=y -+ -+# P2P (Wi-Fi Direct) -+# This can be used to enable P2P support in wpa_supplicant. See README-P2P for -+# more information on P2P operations. -+#CONFIG_P2P=y -+ -+# Enable TDLS support -+#CONFIG_TDLS=y -+ -+# Wi-Fi Display -+# This can be used to enable Wi-Fi Display extensions for P2P using an external -+# program to control the additional information exchanges in the messages. -+#CONFIG_WIFI_DISPLAY=y -+ -+# Autoscan -+# This can be used to enable automatic scan support in wpa_supplicant. -+# See wpa_supplicant.conf for more information on autoscan usage. -+# -+# Enabling directly a module will enable autoscan support. -+# For exponential module: -+#CONFIG_AUTOSCAN_EXPONENTIAL=y -+# For periodic module: -+#CONFIG_AUTOSCAN_PERIODIC=y -+ -+# Password (and passphrase, etc.) backend for external storage -+# These optional mechanisms can be used to add support for storing passwords -+# and other secrets in external (to wpa_supplicant) location. This allows, for -+# example, operating system specific key storage to be used -+# -+# External password backend for testing purposes (developer use) -+#CONFIG_EXT_PASSWORD_TEST=y -+ -+# Enable Fast Session Transfer (FST) -+#CONFIG_FST=y -+ -+# Enable CLI commands for FST testing -+#CONFIG_FST_TEST=y -+ -+# OS X builds. This is only for building eapol_test. -+#CONFIG_OSX=y -+ -+# Automatic Channel Selection -+# This will allow wpa_supplicant to pick the channel automatically when channel -+# is set to "0". -+# -+# TODO: Extend parser to be able to parse "channel=acs_survey" as an alternative -+# to "channel=0". This would enable us to eventually add other ACS algorithms in -+# similar way. -+# -+# Automatic selection is currently only done through initialization, later on -+# we hope to do background checks to keep us moving to more ideal channels as -+# time goes by. ACS is currently only supported through the nl80211 driver and -+# your driver must have survey dump capability that is filled by the driver -+# during scanning. -+# -+# TODO: In analogy to hostapd be able to customize the ACS survey algorithm with -+# a newly to create wpa_supplicant.conf variable acs_num_scans. -+# -+# Supported ACS drivers: -+# * ath9k -+# * ath5k -+# * ath10k -+# -+# For more details refer to: -+# http://wireless.kernel.org/en/users/Documentation/acs -+#CONFIG_ACS=y -+ -+# Support Multi Band Operation -+#CONFIG_MBO=y -+ -+# Fast Initial Link Setup (FILS) (IEEE 802.11ai) -+#CONFIG_FILS=y -+# FILS shared key authentication with PFS -+#CONFIG_FILS_SK_PFS=y -+ -+# Support RSN on IBSS networks -+# This is needed to be able to use mode=1 network profile with proto=RSN and -+# key_mgmt=WPA-PSK (i.e., full key management instead of WPA-None). -+#CONFIG_IBSS_RSN=y -+ -+# External PMKSA cache control -+# This can be used to enable control interface commands that allow the current -+# PMKSA cache entries to be fetched and new entries to be added. -+#CONFIG_PMKSA_CACHE_EXTERNAL=y -+ -+# Mesh Networking (IEEE 802.11s) -+#CONFIG_MESH=y -+ -+# Background scanning modules -+# These can be used to request wpa_supplicant to perform background scanning -+# operations for roaming within an ESS (same SSID). See the bgscan parameter in -+# the wpa_supplicant.conf file for more details. -+# Periodic background scans based on signal strength -+#CONFIG_BGSCAN_SIMPLE=y -+# Learn channels used by the network and try to avoid bgscans on other -+# channels (experimental) -+#CONFIG_BGSCAN_LEARN=y -+ -+# Opportunistic Wireless Encryption (OWE) -+# Experimental implementation of draft-harkins-owe-07.txt -+#CONFIG_OWE=y -+ -+# Device Provisioning Protocol (DPP) -+# This requires CONFIG_IEEE80211W=y to be enabled, too. (see -+# wpa_supplicant/README-DPP for details) -+#CONFIG_DPP=y -+ -+# uBus IPC/RPC System -+# Services can connect to the bus and provide methods -+# that can be called by other services or clients. -+CONFIG_UBUS=y -+ -+# OpenWrt patch 380-disable-ctrl-iface-mib.patch -+# leads to the MIB only being compiled in if -+# CONFIG_CTRL_IFACE_MIB is enabled. -+#CONFIG_CTRL_IFACE_MIB=y -diff --git a/package/network/services/hostapd/files/wpa_supplicant-p2p.config b/package/network/services/hostapd/files/wpa_supplicant-p2p.config -new file mode 100644 -index 0000000000..7f5140622c ---- /dev/null -+++ b/package/network/services/hostapd/files/wpa_supplicant-p2p.config -@@ -0,0 +1,625 @@ -+# Example wpa_supplicant build time configuration -+# -+# This file lists the configuration options that are used when building the -+# wpa_supplicant binary. All lines starting with # are ignored. Configuration -+# option lines must be commented out complete, if they are not to be included, -+# i.e., just setting VARIABLE=n is not disabling that variable. -+# -+# This file is included in Makefile, so variables like CFLAGS and LIBS can also -+# be modified from here. In most cases, these lines should use += in order not -+# to override previous values of the variables. -+ -+ -+# Uncomment following two lines and fix the paths if you have installed OpenSSL -+# or GnuTLS in non-default location -+#CFLAGS += -I/usr/local/openssl/include -+#LIBS += -L/usr/local/openssl/lib -+ -+# Some Red Hat versions seem to include kerberos header files from OpenSSL, but -+# the kerberos files are not in the default include path. Following line can be -+# used to fix build issues on such systems (krb5.h not found). -+#CFLAGS += -I/usr/include/kerberos -+ -+# 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 -+# replacement for WEXT and its use allows wpa_supplicant to properly control -+# the driver to improve existing functionality like roaming and to support new -+# functionality. -+#CONFIG_DRIVER_WEXT=y -+ -+# Driver interface for Linux drivers using the nl80211 kernel interface -+CONFIG_DRIVER_NL80211=y -+ -+# QCA vendor extensions to nl80211 -+#CONFIG_DRIVER_NL80211_QCA=y -+ -+# driver_nl80211.c requires libnl. If you are compiling it yourself -+# you may need to point hostapd to your version of libnl. -+# -+#CFLAGS += -I$ -+#LIBS += -L$ -+ -+# Use libnl v2.0 (or 3.0) libraries. -+#CONFIG_LIBNL20=y -+ -+# Use libnl 3.2 libraries (if this is selected, CONFIG_LIBNL20 is ignored) -+#CONFIG_LIBNL32=y -+ -+ -+# Driver interface for FreeBSD net80211 layer (e.g., Atheros driver) -+#CONFIG_DRIVER_BSD=y -+#CFLAGS += -I/usr/local/include -+#LIBS += -L/usr/local/lib -+#LIBS_p += -L/usr/local/lib -+#LIBS_c += -L/usr/local/lib -+ -+# Driver interface for Windows NDIS -+#CONFIG_DRIVER_NDIS=y -+#CFLAGS += -I/usr/include/w32api/ddk -+#LIBS += -L/usr/local/lib -+# For native build using mingw -+#CONFIG_NATIVE_WINDOWS=y -+# Additional directories for cross-compilation on Linux host for mingw target -+#CFLAGS += -I/opt/mingw/mingw32/include/ddk -+#LIBS += -L/opt/mingw/mingw32/lib -+#CC=mingw32-gcc -+# By default, driver_ndis uses WinPcap for low-level operations. This can be -+# replaced with the following option which replaces WinPcap calls with NDISUIO. -+# However, this requires that WZC is disabled (net stop wzcsvc) before starting -+# wpa_supplicant. -+# CONFIG_USE_NDISUIO=y -+ -+# Driver interface for wired Ethernet drivers -+CONFIG_DRIVER_WIRED=y -+ -+# Driver interface for MACsec capable Qualcomm Atheros drivers -+#CONFIG_DRIVER_MACSEC_QCA=y -+ -+# Driver interface for Linux MACsec drivers -+#CONFIG_DRIVER_MACSEC_LINUX=y -+ -+# Driver interface for the Broadcom RoboSwitch family -+#CONFIG_DRIVER_ROBOSWITCH=y -+ -+# Driver interface for no driver (e.g., WPS ER only) -+#CONFIG_DRIVER_NONE=y -+ -+# Solaris libraries -+#LIBS += -lsocket -ldlpi -lnsl -+#LIBS_c += -lsocket -+ -+# Enable IEEE 802.1X Supplicant (automatically included if any EAP method or -+# MACsec is included) -+CONFIG_IEEE8021X_EAPOL=y -+ -+# EAP-MD5 -+CONFIG_EAP_MD5=y -+ -+# EAP-MSCHAPv2 -+CONFIG_EAP_MSCHAPV2=y -+ -+# EAP-TLS -+CONFIG_EAP_TLS=y -+ -+# EAL-PEAP -+CONFIG_EAP_PEAP=y -+ -+# EAP-TTLS -+CONFIG_EAP_TTLS=y -+ -+# EAP-FAST -+CONFIG_EAP_FAST=y -+ -+# EAP-TEAP -+# Note: The current EAP-TEAP implementation is experimental and should not be -+# enabled for production use. The IETF RFC 7170 that defines EAP-TEAP has number -+# of conflicting statements and missing details and the implementation has -+# vendor specific workarounds for those and as such, may not interoperate with -+# any other implementation. This should not be used for anything else than -+# experimentation and interoperability testing until those issues has been -+# resolved. -+#CONFIG_EAP_TEAP=y -+ -+# EAP-GTC -+CONFIG_EAP_GTC=y -+ -+# EAP-OTP -+CONFIG_EAP_OTP=y -+ -+# EAP-SIM (enable CONFIG_PCSC, if EAP-SIM is used) -+#CONFIG_EAP_SIM=y -+ -+# Enable SIM simulator (Milenage) for EAP-SIM -+#CONFIG_SIM_SIMULATOR=y -+ -+# EAP-PSK (experimental; this is _not_ needed for WPA-PSK) -+#CONFIG_EAP_PSK=y -+ -+# EAP-pwd (secure authentication using only a password) -+#CONFIG_EAP_PWD=y -+ -+# EAP-PAX -+#CONFIG_EAP_PAX=y -+ -+# LEAP -+CONFIG_EAP_LEAP=y -+ -+# EAP-AKA (enable CONFIG_PCSC, if EAP-AKA is used) -+#CONFIG_EAP_AKA=y -+ -+# EAP-AKA' (enable CONFIG_PCSC, if EAP-AKA' is used). -+# This requires CONFIG_EAP_AKA to be enabled, too. -+#CONFIG_EAP_AKA_PRIME=y -+ -+# Enable USIM simulator (Milenage) for EAP-AKA -+#CONFIG_USIM_SIMULATOR=y -+ -+# EAP-SAKE -+#CONFIG_EAP_SAKE=y -+ -+# EAP-GPSK -+#CONFIG_EAP_GPSK=y -+# Include support for optional SHA256 cipher suite in EAP-GPSK -+#CONFIG_EAP_GPSK_SHA256=y -+ -+# EAP-TNC and related Trusted Network Connect support (experimental) -+#CONFIG_EAP_TNC=y -+ -+# Wi-Fi Protected Setup (WPS) -+CONFIG_WPS=y -+# Enable WPS external registrar functionality -+#CONFIG_WPS_ER=y -+# Disable credentials for an open network by default when acting as a WPS -+# registrar. -+#CONFIG_WPS_REG_DISABLE_OPEN=y -+# Enable WPS support with NFC config method -+#CONFIG_WPS_NFC=y -+ -+# EAP-IKEv2 -+#CONFIG_EAP_IKEV2=y -+ -+# EAP-EKE -+#CONFIG_EAP_EKE=y -+ -+# MACsec -+#CONFIG_MACSEC=y -+ -+# PKCS#12 (PFX) support (used to read private key and certificate file from -+# a file that usually has extension .p12 or .pfx) -+CONFIG_PKCS12=y -+ -+# Smartcard support (i.e., private key on a smartcard), e.g., with openssl -+# engine. -+CONFIG_SMARTCARD=y -+ -+# PC/SC interface for smartcards (USIM, GSM SIM) -+# Enable this if EAP-SIM or EAP-AKA is included -+#CONFIG_PCSC=y -+ -+# Support HT overrides (disable HT/HT40, mask MCS rates, etc.) -+CONFIG_HT_OVERRIDES=y -+ -+# Support VHT overrides (disable VHT, mask MCS rates, etc.) -+CONFIG_VHT_OVERRIDES=y -+ -+# Development testing -+#CONFIG_EAPOL_TEST=y -+ -+# Select control interface backend for external programs, e.g, wpa_cli: -+# unix = UNIX domain sockets (default for Linux/*BSD) -+# udp = UDP sockets using localhost (127.0.0.1) -+# udp6 = UDP IPv6 sockets using localhost (::1) -+# named_pipe = Windows Named Pipe (default for Windows) -+# udp-remote = UDP sockets with remote access (only for tests systems/purpose) -+# udp6-remote = UDP IPv6 sockets with remote access (only for tests purpose) -+# y = use default (backwards compatibility) -+# If this option is commented out, control interface is not included in the -+# build. -+CONFIG_CTRL_IFACE=y -+ -+# Include support for GNU Readline and History Libraries in wpa_cli. -+# When building a wpa_cli binary for distribution, please note that these -+# libraries are licensed under GPL and as such, BSD license may not apply for -+# the resulting binary. -+#CONFIG_READLINE=y -+ -+# Include internal line edit mode in wpa_cli. This can be used as a replacement -+# for GNU Readline to provide limited command line editing and history support. -+#CONFIG_WPA_CLI_EDIT=y -+ -+# Remove debugging code that is printing out debug message to stdout. -+# This can be used to reduce the size of the wpa_supplicant considerably -+# if debugging code is not needed. The size reduction can be around 35% -+# (e.g., 90 kB). -+#CONFIG_NO_STDOUT_DEBUG=y -+ -+# Remove WPA support, e.g., for wired-only IEEE 802.1X supplicant, to save -+# 35-50 kB in code size. -+#CONFIG_NO_WPA=y -+ -+# Remove IEEE 802.11i/WPA-Personal ASCII passphrase support -+# This option can be used to reduce code size by removing support for -+# converting ASCII passphrases into PSK. If this functionality is removed, the -+# PSK can only be configured as the 64-octet hexstring (e.g., from -+# wpa_passphrase). This saves about 0.5 kB in code size. -+#CONFIG_NO_WPA_PASSPHRASE=y -+ -+# Simultaneous Authentication of Equals (SAE), WPA3-Personal -+#CONFIG_SAE=y -+ -+# Disable scan result processing (ap_mode=1) to save code size by about 1 kB. -+# This can be used if ap_scan=1 mode is never enabled. -+#CONFIG_NO_SCAN_PROCESSING=y -+ -+# Select configuration backend: -+# file = text file (e.g., wpa_supplicant.conf; note: the configuration file -+# path is given on command line, not here; this option is just used to -+# select the backend that allows configuration files to be used) -+# winreg = Windows registry (see win_example.reg for an example) -+CONFIG_BACKEND=file -+ -+# Remove configuration write functionality (i.e., to allow the configuration -+# file to be updated based on runtime configuration changes). The runtime -+# configuration can still be changed, the changes are just not going to be -+# persistent over restarts. This option can be used to reduce code size by -+# about 3.5 kB. -+#CONFIG_NO_CONFIG_WRITE=y -+ -+# Remove support for configuration blobs to reduce code size by about 1.5 kB. -+#CONFIG_NO_CONFIG_BLOBS=y -+ -+# Select program entry point implementation: -+# main = UNIX/POSIX like main() function (default) -+# main_winsvc = Windows service (read parameters from registry) -+# main_none = Very basic example (development use only) -+#CONFIG_MAIN=main -+ -+# Select wrapper for operating system and C library specific functions -+# unix = UNIX/POSIX like systems (default) -+# win32 = Windows systems -+# none = Empty template -+#CONFIG_OS=unix -+ -+# Select event loop implementation -+# eloop = select() loop (default) -+# eloop_win = Windows events and WaitForMultipleObject() loop -+#CONFIG_ELOOP=eloop -+ -+# Should we use poll instead of select? Select is used by default. -+#CONFIG_ELOOP_POLL=y -+ -+# Should we use epoll instead of select? Select is used by default. -+CONFIG_ELOOP_EPOLL=y -+ -+# Should we use kqueue instead of select? Select is used by default. -+#CONFIG_ELOOP_KQUEUE=y -+ -+# Select layer 2 packet implementation -+# linux = Linux packet socket (default) -+# pcap = libpcap/libdnet/WinPcap -+# freebsd = FreeBSD libpcap -+# winpcap = WinPcap with receive thread -+# ndis = Windows NDISUIO (note: requires CONFIG_USE_NDISUIO=y) -+# none = Empty template -+#CONFIG_L2_PACKET=linux -+ -+# Disable Linux packet socket workaround applicable for station interface -+# in a bridge for EAPOL frames. This should be uncommented only if the kernel -+# is known to not have the regression issue in packet socket behavior with -+# bridge interfaces (commit 'bridge: respect RFC2863 operational state')'). -+CONFIG_NO_LINUX_PACKET_SOCKET_WAR=y -+ -+# IEEE 802.11w (management frame protection), also known as PMF -+# Driver support is also needed for IEEE 802.11w. -+CONFIG_IEEE80211W=y -+ -+# Support Operating Channel Validation -+#CONFIG_OCV=y -+ -+# Select TLS implementation -+# openssl = OpenSSL (default) -+# gnutls = GnuTLS -+# internal = Internal TLSv1 implementation (experimental) -+# linux = Linux kernel AF_ALG and internal TLSv1 implementation (experimental) -+# none = Empty template -+CONFIG_TLS=internal -+ -+# TLS-based EAP methods require at least TLS v1.0. Newer version of TLS (v1.1) -+# can be enabled to get a stronger construction of messages when block ciphers -+# are used. It should be noted that some existing TLS v1.0 -based -+# implementation may not be compatible with TLS v1.1 message (ClientHello is -+# sent prior to negotiating which version will be used) -+#CONFIG_TLSV11=y -+ -+# TLS-based EAP methods require at least TLS v1.0. Newer version of TLS (v1.2) -+# can be enabled to enable use of stronger crypto algorithms. It should be -+# noted that some existing TLS v1.0 -based implementation may not be compatible -+# with TLS v1.2 message (ClientHello is sent prior to negotiating which version -+# will be used) -+#CONFIG_TLSV12=y -+ -+# Select which ciphers to use by default with OpenSSL if the user does not -+# specify them. -+#CONFIG_TLS_DEFAULT_CIPHERS="DEFAULT:!EXP:!LOW" -+ -+# If CONFIG_TLS=internal is used, additional library and include paths are -+# needed for LibTomMath. Alternatively, an integrated, minimal version of -+# LibTomMath can be used. See beginning of libtommath.c for details on benefits -+# and drawbacks of this option. -+CONFIG_INTERNAL_LIBTOMMATH=y -+#ifndef CONFIG_INTERNAL_LIBTOMMATH -+#LTM_PATH=/usr/src/libtommath-0.39 -+#CFLAGS += -I$(LTM_PATH) -+#LIBS += -L$(LTM_PATH) -+#LIBS_p += -L$(LTM_PATH) -+#endif -+# At the cost of about 4 kB of additional binary size, the internal LibTomMath -+# can be configured to include faster routines for exptmod, sqr, and div to -+# speed up DH and RSA calculation considerably -+CONFIG_INTERNAL_LIBTOMMATH_FAST=y -+ -+# Include NDIS event processing through WMI into wpa_supplicant/wpasvc. -+# This is only for Windows builds and requires WMI-related header files and -+# WbemUuid.Lib from Platform SDK even when building with MinGW. -+#CONFIG_NDIS_EVENTS_INTEGRATED=y -+#PLATFORMSDKLIB="/opt/Program Files/Microsoft Platform SDK/Lib" -+ -+# Add support for new DBus control interface -+# (fi.w1.hostap.wpa_supplicant1) -+#CONFIG_CTRL_IFACE_DBUS_NEW=y -+ -+# Add introspection support for new DBus control interface -+#CONFIG_CTRL_IFACE_DBUS_INTRO=y -+ -+# Add support for loading EAP methods dynamically as shared libraries. -+# When this option is enabled, each EAP method can be either included -+# statically (CONFIG_EAP_=y) or dynamically (CONFIG_EAP_=dyn). -+# Dynamic EAP methods are build as shared objects (eap_*.so) and they need to -+# be loaded in the beginning of the wpa_supplicant configuration file -+# (see load_dynamic_eap parameter in the example file) before being used in -+# the network blocks. -+# -+# Note that some shared parts of EAP methods are included in the main program -+# and in order to be able to use dynamic EAP methods using these parts, the -+# main program must have been build with the EAP method enabled (=y or =dyn). -+# This means that EAP-TLS/PEAP/TTLS/FAST cannot be added as dynamic libraries -+# unless at least one of them was included in the main build to force inclusion -+# of the shared code. Similarly, at least one of EAP-SIM/AKA must be included -+# in the main build to be able to load these methods dynamically. -+# -+# Please also note that using dynamic libraries will increase the total binary -+# size. Thus, it may not be the best option for targets that have limited -+# amount of memory/flash. -+#CONFIG_DYNAMIC_EAP_METHODS=y -+ -+# IEEE Std 802.11r-2008 (Fast BSS Transition) for station mode -+#CONFIG_IEEE80211R=y -+ -+# Add support for writing debug log to a file (/tmp/wpa_supplicant-log-#.txt) -+#CONFIG_DEBUG_FILE=y -+ -+# Send debug messages to syslog instead of stdout -+CONFIG_DEBUG_SYSLOG=y -+# Set syslog facility for debug messages -+CONFIG_DEBUG_SYSLOG_FACILITY=LOG_DAEMON -+ -+# Add support for sending all debug messages (regardless of debug verbosity) -+# to the Linux kernel tracing facility. This helps debug the entire stack by -+# making it easy to record everything happening from the driver up into the -+# same file, e.g., using trace-cmd. -+#CONFIG_DEBUG_LINUX_TRACING=y -+ -+# Add support for writing debug log to Android logcat instead of standard -+# output -+#CONFIG_ANDROID_LOG=y -+ -+# Enable privilege separation (see README 'Privilege separation' for details) -+#CONFIG_PRIVSEP=y -+ -+# Enable mitigation against certain attacks against TKIP by delaying Michael -+# MIC error reports by a random amount of time between 0 and 60 seconds -+#CONFIG_DELAYED_MIC_ERROR_REPORT=y -+ -+# Enable tracing code for developer debugging -+# This tracks use of memory allocations and other registrations and reports -+# incorrect use with a backtrace of call (or allocation) location. -+#CONFIG_WPA_TRACE=y -+# For BSD, uncomment these. -+#LIBS += -lexecinfo -+#LIBS_p += -lexecinfo -+#LIBS_c += -lexecinfo -+ -+# Use libbfd to get more details for developer debugging -+# This enables use of libbfd to get more detailed symbols for the backtraces -+# generated by CONFIG_WPA_TRACE=y. -+#CONFIG_WPA_TRACE_BFD=y -+# For BSD, uncomment these. -+#LIBS += -lbfd -liberty -lz -+#LIBS_p += -lbfd -liberty -lz -+#LIBS_c += -lbfd -liberty -lz -+ -+# wpa_supplicant depends on strong random number generation being available -+# from the operating system. os_get_random() function is used to fetch random -+# data when needed, e.g., for key generation. On Linux and BSD systems, this -+# works by reading /dev/urandom. It should be noted that the OS entropy pool -+# needs to be properly initialized before wpa_supplicant is started. This is -+# important especially on embedded devices that do not have a hardware random -+# number generator and may by default start up with minimal entropy available -+# for random number generation. -+# -+# As a safety net, wpa_supplicant is by default trying to internally collect -+# additional entropy for generating random data to mix in with the data fetched -+# from the OS. This by itself is not considered to be very strong, but it may -+# help in cases where the system pool is not initialized properly. However, it -+# is very strongly recommended that the system pool is initialized with enough -+# entropy either by using hardware assisted random number generator or by -+# storing state over device reboots. -+# -+# wpa_supplicant can be configured to maintain its own entropy store over -+# restarts to enhance random number generation. This is not perfect, but it is -+# much more secure than using the same sequence of random numbers after every -+# reboot. This can be enabled with -e command line option. The -+# specified file needs to be readable and writable by wpa_supplicant. -+# -+# If the os_get_random() is known to provide strong random data (e.g., on -+# Linux/BSD, the board in question is known to have reliable source of random -+# data from /dev/urandom), the internal wpa_supplicant random pool can be -+# disabled. This will save some in binary size and CPU use. However, this -+# should only be considered for builds that are known to be used on devices -+# that meet the requirements described above. -+CONFIG_NO_RANDOM_POOL=y -+ -+# Should we attempt to use the getrandom(2) call that provides more reliable -+# yet secure randomness source than /dev/random on Linux 3.17 and newer. -+# Requires glibc 2.25 to build, falls back to /dev/random if unavailable. -+CONFIG_GETRANDOM=y -+ -+# IEEE 802.11n (High Throughput) support (mainly for AP mode) -+#CONFIG_IEEE80211N=y -+ -+# IEEE 802.11ac (Very High Throughput) support (mainly for AP mode) -+# (depends on CONFIG_IEEE80211N) -+#CONFIG_IEEE80211AC=y -+ -+# Wireless Network Management (IEEE Std 802.11v-2011) -+# Note: This is experimental and not complete implementation. -+#CONFIG_WNM=y -+ -+# Interworking (IEEE 802.11u) -+# This can be used to enable functionality to improve interworking with -+# external networks (GAS/ANQP to learn more about the networks and network -+# selection based on available credentials). -+#CONFIG_INTERWORKING=y -+ -+# Hotspot 2.0 -+#CONFIG_HS20=y -+ -+# Enable interface matching in wpa_supplicant -+#CONFIG_MATCH_IFACE=y -+ -+# Disable roaming in wpa_supplicant -+#CONFIG_NO_ROAMING=y -+ -+# AP mode operations with wpa_supplicant -+# This can be used for controlling AP mode operations with wpa_supplicant. It -+# should be noted that this is mainly aimed at simple cases like -+# WPA2-Personal while more complex configurations like WPA2-Enterprise with an -+# external RADIUS server can be supported with hostapd. -+CONFIG_AP=y -+ -+# P2P (Wi-Fi Direct) -+# This can be used to enable P2P support in wpa_supplicant. See README-P2P for -+# more information on P2P operations. -+CONFIG_P2P=y -+ -+# Enable TDLS support -+#CONFIG_TDLS=y -+ -+# Wi-Fi Display -+# This can be used to enable Wi-Fi Display extensions for P2P using an external -+# program to control the additional information exchanges in the messages. -+#CONFIG_WIFI_DISPLAY=y -+ -+# Autoscan -+# This can be used to enable automatic scan support in wpa_supplicant. -+# See wpa_supplicant.conf for more information on autoscan usage. -+# -+# Enabling directly a module will enable autoscan support. -+# For exponential module: -+#CONFIG_AUTOSCAN_EXPONENTIAL=y -+# For periodic module: -+#CONFIG_AUTOSCAN_PERIODIC=y -+ -+# Password (and passphrase, etc.) backend for external storage -+# These optional mechanisms can be used to add support for storing passwords -+# and other secrets in external (to wpa_supplicant) location. This allows, for -+# example, operating system specific key storage to be used -+# -+# External password backend for testing purposes (developer use) -+#CONFIG_EXT_PASSWORD_TEST=y -+ -+# Enable Fast Session Transfer (FST) -+#CONFIG_FST=y -+ -+# Enable CLI commands for FST testing -+#CONFIG_FST_TEST=y -+ -+# OS X builds. This is only for building eapol_test. -+#CONFIG_OSX=y -+ -+# Automatic Channel Selection -+# This will allow wpa_supplicant to pick the channel automatically when channel -+# is set to "0". -+# -+# TODO: Extend parser to be able to parse "channel=acs_survey" as an alternative -+# to "channel=0". This would enable us to eventually add other ACS algorithms in -+# similar way. -+# -+# Automatic selection is currently only done through initialization, later on -+# we hope to do background checks to keep us moving to more ideal channels as -+# time goes by. ACS is currently only supported through the nl80211 driver and -+# your driver must have survey dump capability that is filled by the driver -+# during scanning. -+# -+# TODO: In analogy to hostapd be able to customize the ACS survey algorithm with -+# a newly to create wpa_supplicant.conf variable acs_num_scans. -+# -+# Supported ACS drivers: -+# * ath9k -+# * ath5k -+# * ath10k -+# -+# For more details refer to: -+# http://wireless.kernel.org/en/users/Documentation/acs -+#CONFIG_ACS=y -+ -+# Support Multi Band Operation -+#CONFIG_MBO=y -+ -+# Fast Initial Link Setup (FILS) (IEEE 802.11ai) -+CONFIG_FILS=y -+# FILS shared key authentication with PFS -+#CONFIG_FILS_SK_PFS=y -+ -+# Support RSN on IBSS networks -+# This is needed to be able to use mode=1 network profile with proto=RSN and -+# key_mgmt=WPA-PSK (i.e., full key management instead of WPA-None). -+CONFIG_IBSS_RSN=y -+ -+# External PMKSA cache control -+# This can be used to enable control interface commands that allow the current -+# PMKSA cache entries to be fetched and new entries to be added. -+#CONFIG_PMKSA_CACHE_EXTERNAL=y -+ -+# Mesh Networking (IEEE 802.11s) -+#CONFIG_MESH=y -+ -+# Background scanning modules -+# These can be used to request wpa_supplicant to perform background scanning -+# operations for roaming within an ESS (same SSID). See the bgscan parameter in -+# the wpa_supplicant.conf file for more details. -+# Periodic background scans based on signal strength -+#CONFIG_BGSCAN_SIMPLE=y -+# Learn channels used by the network and try to avoid bgscans on other -+# channels (experimental) -+#CONFIG_BGSCAN_LEARN=y -+ -+# Opportunistic Wireless Encryption (OWE) -+# Experimental implementation of draft-harkins-owe-07.txt -+#CONFIG_OWE=y -+ -+# Device Provisioning Protocol (DPP) -+# This requires CONFIG_IEEE80211W=y to be enabled, too. (see -+# wpa_supplicant/README-DPP for details) -+#CONFIG_DPP=y -+ -+# uBus IPC/RPC System -+# Services can connect to the bus and provide methods -+# that can be called by other services or clients. -+CONFIG_UBUS=y -+ -+# OpenWrt patch 380-disable-ctrl-iface-mib.patch -+# leads to the MIB only being compiled in if -+# CONFIG_CTRL_IFACE_MIB is enabled. -+CONFIG_CTRL_IFACE_MIB=y -diff --git a/package/network/services/hostapd/files/wpa_supplicant.uc b/package/network/services/hostapd/files/wpa_supplicant.uc -new file mode 100644 -index 0000000000..e3a3afcff2 ---- /dev/null -+++ b/package/network/services/hostapd/files/wpa_supplicant.uc -@@ -0,0 +1,253 @@ -+let libubus = require("ubus"); -+import { open, readfile } from "fs"; -+import { wdev_create, wdev_remove, is_equal, vlist_new } from "common"; -+ -+let ubus = libubus.connect(); -+ -+wpas.data.config = {}; -+wpas.data.iface_phy = {}; -+ -+function iface_stop(iface) -+{ -+ let ifname = iface.config.iface; -+ -+ if (!iface.running) -+ return; -+ -+ delete wpas.data.iface_phy[ifname]; -+ wpas.remove_iface(ifname); -+ wdev_remove(ifname); -+ iface.running = false; -+} -+ -+function iface_start(phy, iface) -+{ -+ if (iface.running) -+ return; -+ -+ let ifname = iface.config.iface; -+ -+ wpas.data.iface_phy[ifname] = phy; -+ wdev_remove(ifname); -+ let ret = wdev_create(phy, ifname, iface.config); -+ if (ret) -+ wpas.printf(`Failed to create device ${ifname}: ${ret}`); -+ wpas.add_iface(iface.config); -+ iface.running = true; -+} -+ -+function iface_cb(new_if, old_if) -+{ -+ if (old_if && new_if && is_equal(old_if.config, new_if.config)) { -+ new_if.running = old_if.running; -+ return; -+ } -+ -+ if (old_if) -+ iface_stop(old_if); -+} -+ -+function prepare_config(config) -+{ -+ config.config_data = readfile(config.config); -+ -+ return { config: config }; -+} -+ -+function set_config(phy_name, config_list) -+{ -+ let phy = wpas.data.config[phy_name]; -+ -+ if (!phy) { -+ phy = vlist_new(iface_cb, false); -+ wpas.data.config[phy_name] = phy; -+ } -+ -+ let values = []; -+ for (let config in config_list) -+ push(values, [ config.iface, prepare_config(config) ]); -+ -+ phy.update(values); -+} -+ -+function start_pending(phy_name) -+{ -+ let phy = wpas.data.config[phy_name]; -+ -+ for (let ifname in phy.data) -+ iface_start(phy_name, phy.data[ifname]); -+} -+ -+let main_obj = { -+ phy_set_state: { -+ args: { -+ phy: "", -+ stop: true, -+ }, -+ call: function(req) { -+ if (!req.args.phy || req.args.stop == null) -+ return libubus.STATUS_INVALID_ARGUMENT; -+ -+ let phy = wpas.data.config[req.args.phy]; -+ if (!phy) -+ return libubus.STATUS_NOT_FOUND; -+ -+ try { -+ if (req.args.stop) { -+ for (let ifname in phy.data) -+ iface_stop(phy.data[ifname]); -+ } else { -+ start_pending(req.args.phy); -+ } -+ } catch (e) { -+ wpas.printf(`Error chaging state: ${e}\n${e.stacktrace[0].context}`); -+ return libubus.STATUS_INVALID_ARGUMENT; -+ } -+ return 0; -+ } -+ }, -+ config_set: { -+ args: { -+ phy: "", -+ config: [], -+ defer: true, -+ }, -+ call: function(req) { -+ if (!req.args.phy) -+ return libubus.STATUS_INVALID_ARGUMENT; -+ -+ try { -+ if (req.args.config) -+ set_config(req.args.phy, req.args.config); -+ -+ if (!req.args.defer) -+ start_pending(req.args.phy); -+ } catch (e) { -+ wpas.printf(`Error loading config: ${e}\n${e.stacktrace[0].context}`); -+ return libubus.STATUS_INVALID_ARGUMENT; -+ } -+ -+ return { -+ pid: wpas.getpid() -+ }; -+ } -+ }, -+ config_add: { -+ args: { -+ driver: "", -+ iface: "", -+ bridge: "", -+ hostapd_ctrl: "", -+ ctrl: "", -+ config: "", -+ }, -+ call: function(req) { -+ if (!req.args.iface || !req.args.config) -+ return libubus.STATUS_INVALID_ARGUMENT; -+ -+ if (wpas.add_iface(req.args) < 0) -+ return libubus.STATUS_INVALID_ARGUMENT; -+ -+ return { -+ pid: wpas.getpid() -+ }; -+ } -+ }, -+ config_remove: { -+ args: { -+ iface: "" -+ }, -+ call: function(req) { -+ if (!req.args.iface) -+ return libubus.STATUS_INVALID_ARGUMENT; -+ -+ wpas.remove_iface(req.args.iface); -+ return 0; -+ } -+ }, -+}; -+ -+wpas.data.ubus = ubus; -+wpas.data.obj = ubus.publish("wpa_supplicant", main_obj); -+ -+function iface_event(type, name, data) { -+ let ubus = wpas.data.ubus; -+ -+ data ??= {}; -+ data.name = name; -+ wpas.data.obj.notify(`iface.${type}`, data, null, null, null, -1); -+ ubus.call("service", "event", { type: `wpa_supplicant.${name}.${type}`, data: {} }); -+} -+ -+function iface_hostapd_notify(phy, ifname, iface, state) -+{ -+ let ubus = wpas.data.ubus; -+ let status = iface.status(); -+ let msg = { phy: phy }; -+ -+ switch (state) { -+ case "DISCONNECTED": -+ case "AUTHENTICATING": -+ msg.up = false; -+ break; -+ case "INTERFACE_DISABLED": -+ case "INACTIVE": -+ msg.up = true; -+ break; -+ case "COMPLETED": -+ msg.up = true; -+ msg.frequency = status.frequency; -+ msg.sec_chan_offset = status.sec_chan_offset; -+ break; -+ default: -+ return; -+ } -+ -+ ubus.call("hostapd", "apsta_state", msg); -+} -+ -+function iface_channel_switch(phy, ifname, iface, info) -+{ -+ let msg = { -+ phy: phy, -+ up: true, -+ csa: true, -+ csa_count: info.csa_count ? info.csa_count - 1 : 0, -+ frequency: info.frequency, -+ sec_chan_offset: info.sec_chan_offset, -+ }; -+ ubus.call("hostapd", "apsta_state", msg); -+} -+ -+return { -+ shutdown: function() { -+ for (let phy in wpas.data.config) -+ set_config(phy, []); -+ wpas.ubus.disconnect(); -+ }, -+ iface_add: function(name, obj) { -+ iface_event("add", name); -+ }, -+ iface_remove: function(name, obj) { -+ iface_event("remove", name); -+ }, -+ state: function(ifname, iface, state) { -+ let phy = wpas.data.iface_phy[ifname]; -+ if (!phy) { -+ wpas.printf(`no PHY for ifname ${ifname}`); -+ return; -+ } -+ -+ iface_hostapd_notify(phy, ifname, iface, state); -+ }, -+ event: function(ifname, iface, ev, info) { -+ let phy = wpas.data.iface_phy[ifname]; -+ if (!phy) { -+ wpas.printf(`no PHY for ifname ${ifname}`); -+ return; -+ } -+ -+ if (ev == "CH_SWITCH_STARTED") -+ iface_channel_switch(phy, ifname, iface, info); -+ } -+}; -diff --git a/package/network/services/hostapd/files/wpad.init b/package/network/services/hostapd/files/wpad.init -new file mode 100644 -index 0000000000..65d46df982 ---- /dev/null -+++ b/package/network/services/hostapd/files/wpad.init -@@ -0,0 +1,43 @@ -+#!/bin/sh /etc/rc.common -+ -+START=19 -+STOP=21 -+ -+USE_PROCD=1 -+NAME=wpad -+ -+start_service() { -+ if [ -x "/usr/sbin/hostapd" ]; then -+ mkdir -p /var/run/hostapd -+ chown network:network /var/run/hostapd -+ procd_open_instance hostapd -+ procd_set_param command /usr/sbin/hostapd -s -g /var/run/hostapd/global -+ procd_set_param respawn 3600 1 0 -+ procd_set_param limits core="unlimited" -+ [ -x /sbin/ujail -a -e /etc/capabilities/wpad.json ] && { -+ procd_add_jail hostapd -+ procd_set_param capabilities /etc/capabilities/wpad.json -+ procd_set_param user network -+ procd_set_param group network -+ procd_set_param no_new_privs 1 -+ } -+ procd_close_instance -+ fi -+ -+ if [ -x "/usr/sbin/wpa_supplicant" ]; then -+ mkdir -p /var/run/wpa_supplicant -+ chown network:network /var/run/wpa_supplicant -+ procd_open_instance supplicant -+ procd_set_param command /usr/sbin/wpa_supplicant -n -s -g /var/run/wpa_supplicant/global -+ procd_set_param respawn 3600 1 0 -+ procd_set_param limits core="unlimited" -+ [ -x /sbin/ujail -a -e /etc/capabilities/wpad.json ] && { -+ procd_add_jail wpa_supplicant -+ procd_set_param capabilities /etc/capabilities/wpad.json -+ procd_set_param user network -+ procd_set_param group network -+ procd_set_param no_new_privs 1 -+ } -+ procd_close_instance -+ fi -+} -diff --git a/package/network/services/hostapd/files/wpad.json b/package/network/services/hostapd/files/wpad.json -new file mode 100644 -index 0000000000..c73f3d98bd ---- /dev/null -+++ b/package/network/services/hostapd/files/wpad.json -@@ -0,0 +1,22 @@ -+{ -+ "bounding": [ -+ "CAP_NET_ADMIN", -+ "CAP_NET_RAW" -+ ], -+ "effective": [ -+ "CAP_NET_ADMIN", -+ "CAP_NET_RAW" -+ ], -+ "ambient": [ -+ "CAP_NET_ADMIN", -+ "CAP_NET_RAW" -+ ], -+ "permitted": [ -+ "CAP_NET_ADMIN", -+ "CAP_NET_RAW" -+ ], -+ "inheritable": [ -+ "CAP_NET_ADMIN", -+ "CAP_NET_RAW" -+ ] -+} -diff --git a/package/network/services/hostapd/files/wpad_acl.json b/package/network/services/hostapd/files/wpad_acl.json -new file mode 100644 -index 0000000000..c77ccd8ea0 ---- /dev/null -+++ b/package/network/services/hostapd/files/wpad_acl.json -@@ -0,0 +1,10 @@ -+{ -+ "user": "network", -+ "access": { -+ "service": { -+ "methods": [ "event" ] -+ } -+ }, -+ "publish": [ "hostapd", "hostapd.*", "wpa_supplicant", "wpa_supplicant.*" ], -+ "send": [ "bss.*", "wps_credentials" ] -+} -diff --git a/package/network/services/hostapd/files/wps-hotplug.sh b/package/network/services/hostapd/files/wps-hotplug.sh -new file mode 100644 -index 0000000000..073bdd1868 ---- /dev/null -+++ b/package/network/services/hostapd/files/wps-hotplug.sh -@@ -0,0 +1,69 @@ -+#!/bin/sh -+ -+wps_catch_credentials() { -+ local iface ifaces ifc ifname ssid encryption key radio radios -+ local found=0 -+ -+ . /usr/share/libubox/jshn.sh -+ ubus -S -t 30 listen wps_credentials | while read creds; do -+ json_init -+ json_load "$creds" -+ json_select wps_credentials || continue -+ json_get_vars ifname ssid key encryption -+ local ifcname="$ifname" -+ json_init -+ json_load "$(ubus -S call network.wireless status)" -+ json_get_keys radios -+ for radio in $radios; do -+ json_select $radio -+ json_select interfaces -+ json_get_keys ifaces -+ for ifc in $ifaces; do -+ json_select $ifc -+ json_get_vars ifname -+ [ "$ifname" = "$ifcname" ] && { -+ ubus -S call uci set "{\"config\":\"wireless\", \"type\":\"wifi-iface\", \ -+ \"match\": { \"device\": \"$radio\", \"encryption\": \"wps\" }, \ -+ \"values\": { \"encryption\": \"$encryption\", \ -+ \"ssid\": \"$ssid\", \ -+ \"key\": \"$key\" } }" -+ ubus -S call uci commit '{"config": "wireless"}' -+ ubus -S call uci apply -+ } -+ json_select .. -+ done -+ json_select .. -+ json_select .. -+ done -+ done -+} -+ -+if [ "$ACTION" = "released" ] && [ "$BUTTON" = "wps" ]; then -+ # If the button was pressed for 3 seconds or more, trigger WPS on -+ # wpa_supplicant only, no matter if hostapd is running or not. If -+ # was pressed for less than 3 seconds, try triggering on -+ # hostapd. If there is no hostapd instance to trigger it on or WPS -+ # is not enabled on them, trigger it on wpa_supplicant. -+ if [ "$SEEN" -lt 3 ] ; then -+ wps_done=0 -+ ubusobjs="$( ubus -S list hostapd.* )" -+ for ubusobj in $ubusobjs; do -+ ubus -S call $ubusobj wps_start && wps_done=1 -+ done -+ [ $wps_done = 0 ] || return 0 -+ fi -+ wps_done=0 -+ ubusobjs="$( ubus -S list wpa_supplicant.* )" -+ for ubusobj in $ubusobjs; do -+ ifname="$(echo $ubusobj | cut -d'.' -f2 )" -+ multi_ap="" -+ if [ -e "/var/run/wpa_supplicant-${ifname}.conf.is_multiap" ]; then -+ ubus -S call $ubusobj wps_start '{ "multi_ap": true }' && wps_done=1 -+ else -+ ubus -S call $ubusobj wps_start && wps_done=1 -+ fi -+ done -+ [ $wps_done = 0 ] || wps_catch_credentials & -+fi -+ -+return 0 -diff --git a/package/network/services/hostapd/patches/001-wolfssl-init-RNG-with-ECC-key.patch b/package/network/services/hostapd/patches/001-wolfssl-init-RNG-with-ECC-key.patch -new file mode 100644 -index 0000000000..269dcaac75 ---- /dev/null -+++ b/package/network/services/hostapd/patches/001-wolfssl-init-RNG-with-ECC-key.patch -@@ -0,0 +1,43 @@ -+From 21ce83b4ae2b9563175fdb4fc4312096cc399cf8 Mon Sep 17 00:00:00 2001 -+From: David Bauer -+Date: Wed, 5 May 2021 00:44:34 +0200 -+Subject: [PATCH] wolfssl: add RNG to EC key -+ -+Since upstream commit 6467de5a8840 ("Randomize z ordinates in -+scalar mult when timing resistant") WolfSSL requires a RNG for -+the EC key when built hardened which is the default. -+ -+Set the RNG for the EC key to fix connections for OWE clients. -+ -+Signed-off-by: David Bauer -+--- -+ src/crypto/crypto_wolfssl.c | 4 ++++ -+ 1 file changed, 4 insertions(+) -+ -+--- a/src/crypto/crypto_wolfssl.c -++++ b/src/crypto/crypto_wolfssl.c -+@@ -1340,6 +1340,7 @@ int ecc_projective_add_point(ecc_point * -+ -+ struct crypto_ec { -+ ecc_key key; -++ WC_RNG rng; -+ mp_int a; -+ mp_int prime; -+ mp_int order; -+@@ -1394,6 +1395,8 @@ struct crypto_ec * crypto_ec_init(int gr -+ return NULL; -+ -+ if (wc_ecc_init(&e->key) != 0 || -++ wc_InitRng(&e->rng) != 0 || -++ wc_ecc_set_rng(&e->key, &e->rng) != 0 || -+ wc_ecc_set_curve(&e->key, 0, curve_id) != 0 || -+ mp_init(&e->a) != MP_OKAY || -+ mp_init(&e->prime) != MP_OKAY || -+@@ -1425,6 +1428,7 @@ void crypto_ec_deinit(struct crypto_ec* -+ mp_clear(&e->order); -+ mp_clear(&e->prime); -+ mp_clear(&e->a); -++ wc_FreeRng(&e->rng); -+ wc_ecc_free(&e->key); -+ os_free(e); -+ } -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 -new file mode 100644 -index 0000000000..0a51c84d21 ---- /dev/null -+++ b/package/network/services/hostapd/patches/010-mesh-Allow-DFS-channels-to-be-selected-if-dfs-is-ena.patch -@@ -0,0 +1,135 @@ -+From 8de8cd8380af0c43d4fde67a668d79ef73b26b26 Mon Sep 17 00:00:00 2001 -+From: Peter Oh -+Date: Tue, 30 Jun 2020 14:18:58 +0200 -+Subject: [PATCH 10/19] mesh: Allow DFS channels to be selected if dfs is -+ enabled -+ -+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(-) -+ -+--- a/wpa_supplicant/wpa_supplicant.c -++++ b/wpa_supplicant/wpa_supplicant.c -+@@ -2638,7 +2638,7 @@ static int drv_supports_vht(struct wpa_s -+ } -+ -+ -+-static bool ibss_mesh_is_80mhz_avail(int channel, struct hostapd_hw_modes *mode) -++static bool ibss_mesh_is_80mhz_avail(int channel, struct hostapd_hw_modes *mode, bool dfs_enabled) -+ { -+ int i; -+ -+@@ -2647,7 +2647,10 @@ static bool ibss_mesh_is_80mhz_avail(int -+ -+ chan = hw_get_channel_chan(mode, i, NULL); -+ if (!chan || -+- chan->flag & (HOSTAPD_CHAN_DISABLED | HOSTAPD_CHAN_NO_IR)) -++ chan->flag & HOSTAPD_CHAN_DISABLED) -++ return false; -++ -++ if (!dfs_enabled && chan->flag & (HOSTAPD_CHAN_RADAR | HOSTAPD_CHAN_NO_IR)) -+ return false; -+ } -+ -+@@ -2774,7 +2777,7 @@ static void ibss_mesh_select_40mhz(struc -+ const struct wpa_ssid *ssid, -+ struct hostapd_hw_modes *mode, -+ struct hostapd_freq_params *freq, -+- int obss_scan) { -++ int obss_scan, bool dfs_enabled) { -+ 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 -+ return; -+ -+ /* Check primary channel flags */ -+- if (pri_chan->flag & (HOSTAPD_CHAN_DISABLED | HOSTAPD_CHAN_NO_IR)) -++ if (pri_chan->flag & HOSTAPD_CHAN_DISABLED) -+ return; -++ if (pri_chan->flag & (HOSTAPD_CHAN_RADAR | HOSTAPD_CHAN_NO_IR)) -++ if (!dfs_enabled) -++ return; -+ -+ #ifdef CONFIG_HT_OVERRIDES -+ if (ssid->disable_ht40) -+@@ -2825,8 +2831,11 @@ static void ibss_mesh_select_40mhz(struc -+ return; -+ -+ /* Check secondary channel flags */ -+- if (sec_chan->flag & (HOSTAPD_CHAN_DISABLED | HOSTAPD_CHAN_NO_IR)) -++ if (sec_chan->flag & HOSTAPD_CHAN_DISABLED) -+ return; -++ if (sec_chan->flag & (HOSTAPD_CHAN_RADAR | HOSTAPD_CHAN_NO_IR)) -++ if (!dfs_enabled) -++ return; -+ -+ if (ht40 == -1) { -+ if (!(pri_chan->flag & HOSTAPD_CHAN_HT40MINUS)) -+@@ -2880,7 +2889,7 @@ static bool ibss_mesh_select_80_160mhz(s -+ const struct wpa_ssid *ssid, -+ struct hostapd_hw_modes *mode, -+ struct hostapd_freq_params *freq, -+- int ieee80211_mode, bool is_6ghz) { -++ int ieee80211_mode, bool is_6ghz, bool dfs_enabled) { -+ 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 -+ goto skip_80mhz; -+ -+ /* Use 40 MHz if channel not usable */ -+- if (!ibss_mesh_is_80mhz_avail(channel, mode)) -++ if (!ibss_mesh_is_80mhz_avail(channel, mode, dfs_enabled)) -+ goto skip_80mhz; -+ -+ chwidth = CONF_OPER_CHWIDTH_80MHZ; -+@@ -2939,7 +2948,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 && -+- ibss_mesh_is_80mhz_avail(channel + 16, mode)) { -++ ibss_mesh_is_80mhz_avail(channel + 16, mode, dfs_enabled)) { -+ 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 -+ if (!chan) -+ continue; -+ -+- if (chan->flag & (HOSTAPD_CHAN_DISABLED | -+- HOSTAPD_CHAN_NO_IR | -+- HOSTAPD_CHAN_RADAR)) -++ if (chan->flag & HOSTAPD_CHAN_DISABLED) -+ continue; -++ if (chan->flag & (HOSTAPD_CHAN_RADAR | -++ HOSTAPD_CHAN_NO_IR)) -++ if (!dfs_enabled) -++ continue; -+ -+ /* 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 -+ int i, obss_scan = 1; -+ u8 channel; -+ bool is_6ghz; -++ 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 -+ freq->channel = channel; -+ /* Setup higher BW only for 5 GHz */ -+ if (mode->mode == HOSTAPD_MODE_IEEE80211A) { -+- ibss_mesh_select_40mhz(wpa_s, ssid, mode, freq, obss_scan); -++ ibss_mesh_select_40mhz(wpa_s, ssid, mode, freq, obss_scan, dfs_enabled); -+ if (!ibss_mesh_select_80_160mhz(wpa_s, ssid, mode, freq, -+- ieee80211_mode, is_6ghz)) -++ ieee80211_mode, is_6ghz, dfs_enabled)) -+ freq->he_enabled = freq->vht_enabled = false; -+ } -+ -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 -new file mode 100644 -index 0000000000..9b11f0e803 ---- /dev/null -+++ b/package/network/services/hostapd/patches/011-mesh-use-deterministic-channel-on-channel-switch.patch -@@ -0,0 +1,81 @@ -+From fc8ea40f6130ac18d9c66797de2cf1d5af55d496 Mon Sep 17 00:00:00 2001 -+From: Markus Theil -+Date: Tue, 30 Jun 2020 14:19:07 +0200 -+Subject: [PATCH 19/19] mesh: use deterministic channel on channel switch -+ -+This patch uses a deterministic channel on DFS channel switch -+in mesh networks. Otherwise, when switching to a usable but not -+available channel, no CSA can be sent and a random channel is choosen -+without notification of other nodes. It is then quite likely, that -+the mesh network gets disconnected. -+ -+Fix this by using a deterministic number, based on the sha256 hash -+of the mesh ID, in order to use at least a different number in each -+mesh network. -+ -+Signed-off-by: Markus Theil -+--- -+ src/ap/dfs.c | 20 +++++++++++++++++++- -+ src/drivers/driver_nl80211.c | 4 ++++ -+ 2 files changed, 23 insertions(+), 1 deletion(-) -+ -+--- a/src/ap/dfs.c -++++ b/src/ap/dfs.c -+@@ -17,6 +17,7 @@ -+ #include "ap_drv_ops.h" -+ #include "drivers/driver.h" -+ #include "dfs.h" -++#include "crypto/crypto.h" -+ -+ -+ enum dfs_channel_type { -+@@ -521,9 +522,14 @@ dfs_get_valid_channel(struct hostapd_ifa -+ int num_available_chandefs; -+ int chan_idx, chan_idx2; -+ int sec_chan_idx_80p80 = -1; -++ bool is_mesh = false; -+ int i; -+ u32 _rand; -+ -++#ifdef CONFIG_MESH -++ is_mesh = iface->mconf; -++#endif -++ -+ wpa_printf(MSG_DEBUG, "DFS: Selecting random channel"); -+ *secondary_channel = 0; -+ *oper_centr_freq_seg0_idx = 0; -+@@ -543,8 +549,20 @@ dfs_get_valid_channel(struct hostapd_ifa -+ if (num_available_chandefs == 0) -+ return NULL; -+ -+- if (os_get_random((u8 *) &_rand, sizeof(_rand)) < 0) -++ /* try to use deterministic channel in mesh, so that both sides -++ * have a chance to switch to the same channel */ -++ if (is_mesh) { -++#ifdef CONFIG_MESH -++ u64 hash[4]; -++ const u8 *meshid[1] = { &iface->mconf->meshid[0] }; -++ const size_t meshid_len = iface->mconf->meshid_len; -++ -++ sha256_vector(1, meshid, &meshid_len, (u8 *)&hash[0]); -++ _rand = hash[0] + hash[1] + hash[2] + hash[3]; -++#endif -++ } else if (os_get_random((u8 *) &_rand, sizeof(_rand)) < 0) -+ return NULL; -++ -+ chan_idx = _rand % num_available_chandefs; -+ dfs_find_channel(iface, &chan, chan_idx, type); -+ if (!chan) { -+--- a/src/drivers/driver_nl80211.c -++++ b/src/drivers/driver_nl80211.c -+@@ -10977,6 +10977,10 @@ static int nl80211_switch_channel(void * -+ if (ret) -+ goto error; -+ -++ if (drv->nlmode == NL80211_IFTYPE_MESH_POINT) { -++ nla_put_flag(msg, NL80211_ATTR_HANDLE_DFS); -++ } -++ -+ /* beacon_csa params */ -+ beacon_csa = nla_nest_start(msg, NL80211_ATTR_CSA_IES); -+ if (!beacon_csa) -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 -new file mode 100644 -index 0000000000..4ee43b5186 ---- /dev/null -+++ b/package/network/services/hostapd/patches/021-fix-sta-add-after-previous-connection.patch -@@ -0,0 +1,26 @@ -+--- a/src/ap/ieee802_11.c -++++ b/src/ap/ieee802_11.c -+@@ -4601,6 +4601,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. -++ * -++ * If the STA was associated and authorized earlier, but came for a new -++ * connection (!added_unassoc + !reassoc), remove the existing STA entry -++ * so that it can be re-added. This case is rarely seen when the AP could -++ * not receive the deauth/disassoc frame from the STA. And the STA comes -++ * back with new connection within a short period or before the inactive -++ * STA entry is removed from the list. -+ */ -+ 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)", -+@@ -4614,7 +4621,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) && -+- !wpa_auth_sta_fils_tk_already_set(sta->wpa_sm)))) { -++ !wpa_auth_sta_fils_tk_already_set(sta->wpa_sm)) || -++ (!reassoc && (sta->flags & WLAN_STA_AUTHORIZED)))) { -+ hostapd_drv_sta_remove(hapd, sta->addr); -+ wpa_auth_sm_event(sta->wpa_sm, WPA_DRV_STA_REMOVED); -+ set = 0; -diff --git a/package/network/services/hostapd/patches/022-hostapd-fix-use-of-uninitialized-stack-variables.patch b/package/network/services/hostapd/patches/022-hostapd-fix-use-of-uninitialized-stack-variables.patch -new file mode 100644 -index 0000000000..8dec325c98 ---- /dev/null -+++ b/package/network/services/hostapd/patches/022-hostapd-fix-use-of-uninitialized-stack-variables.patch -@@ -0,0 +1,25 @@ -+From: Felix Fietkau -+Date: Thu, 8 Jul 2021 16:33:03 +0200 -+Subject: [PATCH] hostapd: fix use of uninitialized stack variables -+ -+When a CSA is performed on an 80 MHz channel, hostapd_change_config_freq -+unconditionally calls hostapd_set_oper_centr_freq_seg0/1_idx with seg0/1 -+filled by ieee80211_freq_to_chan. -+However, if ieee80211_freq_to_chan fails (because the freq is 0 or invalid), -+seg0/1 remains uninitialized and filled with stack garbage, causing errors -+such as "hostapd: 80 MHz: center segment 1 configured" -+ -+Signed-off-by: Felix Fietkau -+--- -+ -+--- a/src/ap/hostapd.c -++++ b/src/ap/hostapd.c -+@@ -3764,7 +3764,7 @@ static int hostapd_change_config_freq(st -+ struct hostapd_freq_params *old_params) -+ { -+ int channel; -+- u8 seg0, seg1; -++ u8 seg0 = 0, seg1 = 0; -+ struct hostapd_hw_modes *mode; -+ -+ if (!params->channel) { -diff --git a/package/network/services/hostapd/patches/023-ndisc_snoop-call-dl_list_del-before-freeing-ipv6-add.patch b/package/network/services/hostapd/patches/023-ndisc_snoop-call-dl_list_del-before-freeing-ipv6-add.patch -new file mode 100644 -index 0000000000..9ff9b2398d ---- /dev/null -+++ b/package/network/services/hostapd/patches/023-ndisc_snoop-call-dl_list_del-before-freeing-ipv6-add.patch -@@ -0,0 +1,19 @@ -+From: Felix Fietkau -+Date: Wed, 28 Jul 2021 05:43:29 +0200 -+Subject: [PATCH] ndisc_snoop: call dl_list_del before freeing ipv6 addresses -+ -+Fixes a segmentation fault on sta disconnect -+ -+Signed-off-by: Felix Fietkau -+--- -+ -+--- a/src/ap/ndisc_snoop.c -++++ b/src/ap/ndisc_snoop.c -+@@ -61,6 +61,7 @@ void sta_ip6addr_del(struct hostapd_data -+ dl_list_for_each_safe(ip6addr, prev, &sta->ip6addr, struct ip6addr, -+ list) { -+ hostapd_drv_br_delete_ip_neigh(hapd, 6, (u8 *) &ip6addr->addr); -++ dl_list_del(&ip6addr->list); -+ os_free(ip6addr); -+ } -+ } -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 -new file mode 100644 -index 0000000000..19248e80d8 ---- /dev/null -+++ b/package/network/services/hostapd/patches/030-driver_nl80211-rewrite-neigh-code-to-not-depend-on-l.patch -@@ -0,0 +1,275 @@ -+From: Felix Fietkau -+Date: Wed, 28 Jul 2021 05:49:46 +0200 -+Subject: [PATCH] driver_nl80211: rewrite neigh code to not depend on -+ libnl3-route -+ -+Removes an unnecessary dependency and also makes the code smaller -+ -+Signed-off-by: Felix Fietkau -+--- -+ -+--- a/src/drivers/driver_nl80211.c -++++ b/src/drivers/driver_nl80211.c -+@@ -16,9 +16,6 @@ -+ #include -+ #include -+ #include -+-#ifdef CONFIG_LIBNL3_ROUTE -+-#include -+-#endif /* CONFIG_LIBNL3_ROUTE */ -+ #include -+ #include -+ #include -+@@ -5783,26 +5780,29 @@ fail: -+ -+ static void rtnl_neigh_delete_fdb_entry(struct i802_bss *bss, const u8 *addr) -+ { -+-#ifdef CONFIG_LIBNL3_ROUTE -+ struct wpa_driver_nl80211_data *drv = bss->drv; -+- struct rtnl_neigh *rn; -+- struct nl_addr *nl_addr; -++ struct ndmsg nhdr = { -++ .ndm_state = NUD_PERMANENT, -++ .ndm_ifindex = bss->ifindex, -++ .ndm_family = AF_BRIDGE, -++ }; -++ struct nl_msg *msg; -+ int err; -+ -+- rn = rtnl_neigh_alloc(); -+- if (!rn) -++ msg = nlmsg_alloc_simple(RTM_DELNEIGH, NLM_F_CREATE); -++ if (!msg) -+ return; -+ -+- rtnl_neigh_set_family(rn, AF_BRIDGE); -+- rtnl_neigh_set_ifindex(rn, bss->ifindex); -+- nl_addr = nl_addr_build(AF_BRIDGE, (void *) addr, ETH_ALEN); -+- if (!nl_addr) { -+- rtnl_neigh_put(rn); -+- return; -+- } -+- rtnl_neigh_set_lladdr(rn, nl_addr); -++ if (nlmsg_append(msg, &nhdr, sizeof(nhdr), NLMSG_ALIGNTO) < 0) -++ goto errout; -++ -++ if (nla_put(msg, NDA_LLADDR, ETH_ALEN, (void *)addr)) -++ goto errout; -++ -++ if (nl_send_auto_complete(drv->rtnl_sk, msg) < 0) -++ goto errout; -+ -+- err = rtnl_neigh_delete(drv->rtnl_sk, rn, 0); -++ err = nl_wait_for_ack(drv->rtnl_sk); -+ 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( -+ MACSTR, MAC2STR(addr)); -+ } -+ -+- nl_addr_put(nl_addr); -+- rtnl_neigh_put(rn); -+-#endif /* CONFIG_LIBNL3_ROUTE */ -++errout: -++ nlmsg_free(msg); -+ } -+ -+ -+@@ -8492,7 +8491,6 @@ static void *i802_init(struct hostapd_da -+ (params->num_bridge == 0 || !params->bridge[0])) -+ add_ifidx(drv, br_ifindex, drv->ifindex); -+ -+-#ifdef CONFIG_LIBNL3_ROUTE -+ if (bss->added_if_into_bridge || bss->already_in_bridge) { -+ int err; -+ -+@@ -8509,7 +8507,6 @@ static void *i802_init(struct hostapd_da -+ goto failed; -+ } -+ } -+-#endif /* CONFIG_LIBNL3_ROUTE */ -+ -+ if (drv->capa.flags2 & WPA_DRIVER_FLAGS2_CONTROL_PORT_RX) { -+ wpa_printf(MSG_DEBUG, -+@@ -11843,13 +11840,14 @@ static int wpa_driver_br_add_ip_neigh(vo -+ const u8 *ipaddr, int prefixlen, -+ const u8 *addr) -+ { -+-#ifdef CONFIG_LIBNL3_ROUTE -+ struct i802_bss *bss = priv; -+ struct wpa_driver_nl80211_data *drv = bss->drv; -+- struct rtnl_neigh *rn; -+- struct nl_addr *nl_ipaddr = NULL; -+- struct nl_addr *nl_lladdr = NULL; -+- int family, addrsize; -++ struct ndmsg nhdr = { -++ .ndm_state = NUD_PERMANENT, -++ .ndm_ifindex = bss->br_ifindex, -++ }; -++ struct nl_msg *msg; -++ int addrsize; -+ int res; -+ -+ if (!ipaddr || prefixlen == 0 || !addr) -+@@ -11868,85 +11866,66 @@ static int wpa_driver_br_add_ip_neigh(vo -+ } -+ -+ if (version == 4) { -+- family = AF_INET; -++ nhdr.ndm_family = AF_INET; -+ addrsize = 4; -+ } else if (version == 6) { -+- family = AF_INET6; -++ nhdr.ndm_family = AF_INET6; -+ addrsize = 16; -+ } else { -+ return -EINVAL; -+ } -+ -+- rn = rtnl_neigh_alloc(); -+- if (rn == NULL) -++ msg = nlmsg_alloc_simple(RTM_NEWNEIGH, NLM_F_CREATE); -++ if (!msg) -+ return -ENOMEM; -+ -+- /* set the destination ip address for neigh */ -+- nl_ipaddr = nl_addr_build(family, (void *) ipaddr, addrsize); -+- if (nl_ipaddr == NULL) { -+- wpa_printf(MSG_DEBUG, "nl80211: nl_ipaddr build failed"); -+- res = -ENOMEM; -++ res = -ENOMEM; -++ if (nlmsg_append(msg, &nhdr, sizeof(nhdr), NLMSG_ALIGNTO) < 0) -+ goto errout; -+- } -+- nl_addr_set_prefixlen(nl_ipaddr, prefixlen); -+- res = rtnl_neigh_set_dst(rn, nl_ipaddr); -+- if (res) { -+- wpa_printf(MSG_DEBUG, -+- "nl80211: neigh set destination addr failed"); -++ -++ if (nla_put(msg, NDA_DST, addrsize, (void *)ipaddr)) -+ goto errout; -+- } -+ -+- /* set the corresponding lladdr for neigh */ -+- nl_lladdr = nl_addr_build(AF_BRIDGE, (u8 *) addr, ETH_ALEN); -+- if (nl_lladdr == NULL) { -+- wpa_printf(MSG_DEBUG, "nl80211: neigh set lladdr failed"); -+- res = -ENOMEM; -++ if (nla_put(msg, NDA_LLADDR, ETH_ALEN, (void *)addr)) -+ goto errout; -+- } -+- rtnl_neigh_set_lladdr(rn, nl_lladdr); -+ -+- rtnl_neigh_set_ifindex(rn, bss->br_ifindex); -+- rtnl_neigh_set_state(rn, NUD_PERMANENT); -++ res = nl_send_auto_complete(drv->rtnl_sk, msg); -++ if (res < 0) -++ goto errout; -+ -+- res = rtnl_neigh_add(drv->rtnl_sk, rn, NLM_F_CREATE); -++ res = nl_wait_for_ack(drv->rtnl_sk); -+ if (res) { -+ wpa_printf(MSG_DEBUG, -+ "nl80211: Adding bridge ip neigh failed: %s", -+ nl_geterror(res)); -+ } -+ errout: -+- if (nl_lladdr) -+- nl_addr_put(nl_lladdr); -+- if (nl_ipaddr) -+- nl_addr_put(nl_ipaddr); -+- if (rn) -+- rtnl_neigh_put(rn); -++ nlmsg_free(msg); -+ return res; -+-#else /* CONFIG_LIBNL3_ROUTE */ -+- return -1; -+-#endif /* CONFIG_LIBNL3_ROUTE */ -+ } -+ -+ -+ static int wpa_driver_br_delete_ip_neigh(void *priv, u8 version, -+ const u8 *ipaddr) -+ { -+-#ifdef CONFIG_LIBNL3_ROUTE -+ struct i802_bss *bss = priv; -+ struct wpa_driver_nl80211_data *drv = bss->drv; -+- struct rtnl_neigh *rn; -+- struct nl_addr *nl_ipaddr; -+- int family, addrsize; -++ struct ndmsg nhdr = { -++ .ndm_state = NUD_PERMANENT, -++ .ndm_ifindex = bss->br_ifindex, -++ }; -++ struct nl_msg *msg; -++ int addrsize; -+ int res; -+ -+ if (!ipaddr) -+ return -EINVAL; -+ -+ if (version == 4) { -+- family = AF_INET; -++ nhdr.ndm_family = AF_INET; -+ addrsize = 4; -+ } else if (version == 6) { -+- family = AF_INET6; -++ nhdr.ndm_family = AF_INET6; -+ addrsize = 16; -+ } else { -+ return -EINVAL; -+@@ -11964,41 +11943,30 @@ static int wpa_driver_br_delete_ip_neigh -+ return -1; -+ } -+ -+- rn = rtnl_neigh_alloc(); -+- if (rn == NULL) -++ msg = nlmsg_alloc_simple(RTM_DELNEIGH, NLM_F_CREATE); -++ if (!msg) -+ return -ENOMEM; -+ -+- /* set the destination ip address for neigh */ -+- nl_ipaddr = nl_addr_build(family, (void *) ipaddr, addrsize); -+- if (nl_ipaddr == NULL) { -+- wpa_printf(MSG_DEBUG, "nl80211: nl_ipaddr build failed"); -+- res = -ENOMEM; -++ res = -ENOMEM; -++ if (nlmsg_append(msg, &nhdr, sizeof(nhdr), NLMSG_ALIGNTO) < 0) -+ goto errout; -+- } -+- res = rtnl_neigh_set_dst(rn, nl_ipaddr); -+- if (res) { -+- wpa_printf(MSG_DEBUG, -+- "nl80211: neigh set destination addr failed"); -++ -++ if (nla_put(msg, NDA_DST, addrsize, (void *)ipaddr)) -+ goto errout; -+- } -+ -+- rtnl_neigh_set_ifindex(rn, bss->br_ifindex); -++ res = nl_send_auto_complete(drv->rtnl_sk, msg); -++ if (res < 0) -++ goto errout; -+ -+- res = rtnl_neigh_delete(drv->rtnl_sk, rn, 0); -++ res = nl_wait_for_ack(drv->rtnl_sk); -+ if (res) { -+ wpa_printf(MSG_DEBUG, -+ "nl80211: Deleting bridge ip neigh failed: %s", -+ nl_geterror(res)); -+ } -+ errout: -+- if (nl_ipaddr) -+- nl_addr_put(nl_ipaddr); -+- if (rn) -+- rtnl_neigh_put(rn); -++ nlmsg_free(msg); -+ return res; -+-#else /* CONFIG_LIBNL3_ROUTE */ -+- return -1; -+-#endif /* CONFIG_LIBNL3_ROUTE */ -+ } -+ -+ -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 -new file mode 100644 -index 0000000000..f98d3806dc ---- /dev/null -+++ b/package/network/services/hostapd/patches/040-mesh-allow-processing-authentication-frames-in-block.patch -@@ -0,0 +1,34 @@ -+From: Felix Fietkau -+Date: Mon, 18 Feb 2019 12:57:11 +0100 -+Subject: [PATCH] mesh: allow processing authentication frames in blocked state -+ -+If authentication fails repeatedly e.g. because of a weak signal, the link -+can end up in blocked state. If one of the nodes tries to establish a link -+again before it is unblocked on the other side, it will block the link to -+that other side. The same happens on the other side when it unblocks the -+link. In that scenario, the link never recovers on its own. -+ -+To fix this, allow restarting authentication even if the link is in blocked -+state, but don't initiate the attempt until the blocked period is over. -+ -+Signed-off-by: Felix Fietkau -+--- -+ -+--- a/src/ap/ieee802_11.c -++++ b/src/ap/ieee802_11.c -+@@ -3012,15 +3012,6 @@ static void handle_auth(struct hostapd_d -+ seq_ctrl); -+ return; -+ } -+-#ifdef CONFIG_MESH -+- if ((hapd->conf->mesh & MESH_ENABLED) && -+- sta->plink_state == PLINK_BLOCKED) { -+- wpa_printf(MSG_DEBUG, "Mesh peer " MACSTR -+- " is blocked - drop Authentication frame", -+- MAC2STR(sa)); -+- return; -+- } -+-#endif /* CONFIG_MESH */ -+ #ifdef CONFIG_PASN -+ if (auth_alg == WLAN_AUTH_PASN && -+ (sta->flags & WLAN_STA_ASSOC)) { -diff --git a/package/network/services/hostapd/patches/050-build_fix.patch b/package/network/services/hostapd/patches/050-build_fix.patch -new file mode 100644 -index 0000000000..8680b07c66 ---- /dev/null -+++ b/package/network/services/hostapd/patches/050-build_fix.patch -@@ -0,0 +1,20 @@ -+--- a/hostapd/Makefile -++++ b/hostapd/Makefile -+@@ -324,6 +324,7 @@ ifdef CONFIG_FILS -+ CFLAGS += -DCONFIG_FILS -+ OBJS += ../src/ap/fils_hlp.o -+ NEED_SHA384=y -++NEED_HMAC_SHA384_KDF=y -+ NEED_AES_SIV=y -+ ifdef CONFIG_FILS_SK_PFS -+ CFLAGS += -DCONFIG_FILS_SK_PFS -+--- a/wpa_supplicant/Makefile -++++ b/wpa_supplicant/Makefile -+@@ -331,6 +331,7 @@ endif -+ ifdef CONFIG_FILS -+ CFLAGS += -DCONFIG_FILS -+ NEED_SHA384=y -++NEED_HMAC_SHA384_KDF=y -+ NEED_AES_SIV=y -+ ifdef CONFIG_FILS_SK_PFS -+ CFLAGS += -DCONFIG_FILS_SK_PFS -diff --git a/package/network/services/hostapd/patches/100-daemonize_fix.patch b/package/network/services/hostapd/patches/100-daemonize_fix.patch -new file mode 100644 -index 0000000000..687bd4082d ---- /dev/null -+++ b/package/network/services/hostapd/patches/100-daemonize_fix.patch -@@ -0,0 +1,97 @@ -+--- a/src/utils/os_unix.c -++++ b/src/utils/os_unix.c -+@@ -10,6 +10,7 @@ -+ -+ #include -+ #include -++#include -+ -+ #ifdef ANDROID -+ #include -+@@ -188,59 +189,46 @@ int os_gmtime(os_time_t t, struct os_tm -+ return 0; -+ } -+ -+- -+-#ifdef __APPLE__ -+-#include -+-static int os_daemon(int nochdir, int noclose) -++int os_daemonize(const char *pid_file) -+ { -+- int devnull; -++ int pid = 0, i, devnull; -+ -+- if (chdir("/") < 0) -+- return -1; -++#if defined(__uClinux__) || defined(__sun__) -++ return -1; -++#else /* defined(__uClinux__) || defined(__sun__) */ -+ -+- devnull = open("/dev/null", O_RDWR); -+- if (devnull < 0) -++#ifndef __APPLE__ -++ pid = fork(); -++ if (pid < 0) -+ return -1; -++#endif -+ -+- if (dup2(devnull, STDIN_FILENO) < 0) { -+- close(devnull); -+- return -1; -++ if (pid > 0) { -++ if (pid_file) { -++ FILE *f = fopen(pid_file, "w"); -++ if (f) { -++ fprintf(f, "%u\n", pid); -++ fclose(f); -++ } -++ } -++ _exit(0); -+ } -+ -+- if (dup2(devnull, STDOUT_FILENO) < 0) { -+- close(devnull); -++ if (setsid() < 0) -+ return -1; -+- } -+ -+- if (dup2(devnull, STDERR_FILENO) < 0) { -+- close(devnull); -++ if (chdir("/") < 0) -+ return -1; -+- } -+- -+- return 0; -+-} -+-#else /* __APPLE__ */ -+-#define os_daemon daemon -+-#endif /* __APPLE__ */ -+ -+- -+-int os_daemonize(const char *pid_file) -+-{ -+-#if defined(__uClinux__) || defined(__sun__) -+- return -1; -+-#else /* defined(__uClinux__) || defined(__sun__) */ -+- if (os_daemon(0, 0)) { -+- perror("daemon"); -++ devnull = open("/dev/null", O_RDWR); -++ if (devnull < 0) -+ return -1; -+- } -+ -+- if (pid_file) { -+- FILE *f = fopen(pid_file, "w"); -+- if (f) { -+- fprintf(f, "%u\n", getpid()); -+- fclose(f); -+- } -+- } -++ for (i = 0; i <= STDERR_FILENO; i++) -++ dup2(devnull, i); -++ -++ if (devnull > 2) -++ close(devnull); -+ -+ return -0; -+ #endif /* defined(__uClinux__) || defined(__sun__) */ -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 -new file mode 100644 -index 0000000000..22107944dc ---- /dev/null -+++ b/package/network/services/hostapd/patches/110-mbedtls-TLS-crypto-option-initial-port.patch -@@ -0,0 +1,8051 @@ -+From e16f200dc1d2f69efc78c7c55af0d7b410a981f9 Mon Sep 17 00:00:00 2001 -+From: Glenn Strauss -+Date: Tue, 5 Jul 2022 02:49:50 -0400 -+Subject: [PATCH 1/7] mbedtls: TLS/crypto option (initial port) -+ -+Signed-off-by: Glenn Strauss -+--- -+ hostapd/Makefile | 91 + -+ hostapd/defconfig | 15 +- -+ src/crypto/crypto_mbedtls.c | 4043 +++++++++++++++++ -+ src/crypto/tls_mbedtls.c | 3313 ++++++++++++++ -+ .../build/build-wpa_supplicant-mbedtls.config | 24 + -+ tests/hwsim/example-hostapd.config | 4 + -+ tests/hwsim/example-wpa_supplicant.config | 4 + -+ wpa_supplicant/Makefile | 74 + -+ wpa_supplicant/defconfig | 6 +- -+ 9 files changed, 7571 insertions(+), 3 deletions(-) -+ create mode 100644 src/crypto/crypto_mbedtls.c -+ create mode 100644 src/crypto/tls_mbedtls.c -+ create mode 100644 tests/build/build-wpa_supplicant-mbedtls.config -+ -+--- a/hostapd/Makefile -++++ b/hostapd/Makefile -+@@ -745,6 +745,40 @@ endif -+ CFLAGS += -DTLS_DEFAULT_CIPHERS=\"$(CONFIG_TLS_DEFAULT_CIPHERS)\" -+ endif -+ -++ifeq ($(CONFIG_TLS), mbedtls) -++ifndef CONFIG_CRYPTO -++CONFIG_CRYPTO=mbedtls -++endif -++ifdef TLS_FUNCS -++OBJS += ../src/crypto/tls_mbedtls.o -++LIBS += -lmbedtls -++ifndef CONFIG_DPP -++LIBS += -lmbedx509 -++endif -++endif -++OBJS += ../src/crypto/crypto_$(CONFIG_CRYPTO).o -++HOBJS += ../src/crypto/crypto_$(CONFIG_CRYPTO).o -++SOBJS += ../src/crypto/crypto_$(CONFIG_CRYPTO).o -++ifdef NEED_FIPS186_2_PRF -++OBJS += ../src/crypto/fips_prf_internal.o -++SHA1OBJS += ../src/crypto/sha1-internal.o -++endif -++ifeq ($(CONFIG_CRYPTO), mbedtls) -++ifdef CONFIG_DPP -++LIBS += -lmbedx509 -++LIBS_h += -lmbedx509 -++LIBS_n += -lmbedx509 -++LIBS_s += -lmbedx509 -++endif -++LIBS += -lmbedcrypto -++LIBS_h += -lmbedcrypto -++LIBS_n += -lmbedcrypto -++LIBS_s += -lmbedcrypto -++# XXX: create a config option? -++CFLAGS += -DCRYPTO_RSA_OAEP_SHA256 -++endif -++endif -++ -+ ifeq ($(CONFIG_TLS), gnutls) -+ ifndef CONFIG_CRYPTO -+ # default to libgcrypt -+@@ -924,9 +958,11 @@ endif -+ -+ ifneq ($(CONFIG_TLS), openssl) -+ ifneq ($(CONFIG_TLS), wolfssl) -++ifneq ($(CONFIG_TLS), mbedtls) -+ AESOBJS += ../src/crypto/aes-wrap.o -+ endif -+ endif -++endif -+ ifdef NEED_AES_EAX -+ AESOBJS += ../src/crypto/aes-eax.o -+ NEED_AES_CTR=y -+@@ -936,38 +972,48 @@ AESOBJS += ../src/crypto/aes-siv.o -+ NEED_AES_CTR=y -+ endif -+ ifdef NEED_AES_CTR -++ifneq ($(CONFIG_TLS), mbedtls) -+ AESOBJS += ../src/crypto/aes-ctr.o -+ endif -++endif -+ ifdef NEED_AES_ENCBLOCK -++ifneq ($(CONFIG_TLS), mbedtls) -+ AESOBJS += ../src/crypto/aes-encblock.o -+ endif -++endif -+ ifneq ($(CONFIG_TLS), openssl) -+ ifneq ($(CONFIG_TLS), linux) -+ ifneq ($(CONFIG_TLS), wolfssl) -++ifneq ($(CONFIG_TLS), mbedtls) -+ AESOBJS += ../src/crypto/aes-omac1.o -+ endif -+ endif -+ endif -++endif -+ ifdef NEED_AES_UNWRAP -+ ifneq ($(CONFIG_TLS), openssl) -+ ifneq ($(CONFIG_TLS), linux) -+ ifneq ($(CONFIG_TLS), wolfssl) -++ifneq ($(CONFIG_TLS), mbedtls) -+ NEED_AES_DEC=y -+ AESOBJS += ../src/crypto/aes-unwrap.o -+ endif -+ endif -+ endif -+ endif -++endif -+ ifdef NEED_AES_CBC -+ NEED_AES_DEC=y -+ ifneq ($(CONFIG_TLS), openssl) -+ ifneq ($(CONFIG_TLS), linux) -+ ifneq ($(CONFIG_TLS), wolfssl) -++ifneq ($(CONFIG_TLS), mbedtls) -+ AESOBJS += ../src/crypto/aes-cbc.o -+ endif -+ endif -+ endif -+ endif -++endif -+ ifdef NEED_AES_DEC -+ ifdef CONFIG_INTERNAL_AES -+ AESOBJS += ../src/crypto/aes-internal-dec.o -+@@ -982,12 +1028,16 @@ ifneq ($(CONFIG_TLS), openssl) -+ ifneq ($(CONFIG_TLS), linux) -+ ifneq ($(CONFIG_TLS), gnutls) -+ ifneq ($(CONFIG_TLS), wolfssl) -++ifneq ($(CONFIG_TLS), mbedtls) -+ SHA1OBJS += ../src/crypto/sha1.o -+ endif -+ endif -+ endif -+ endif -++endif -++ifneq ($(CONFIG_TLS), mbedtls) -+ SHA1OBJS += ../src/crypto/sha1-prf.o -++endif -+ ifdef CONFIG_INTERNAL_SHA1 -+ SHA1OBJS += ../src/crypto/sha1-internal.o -+ ifdef NEED_FIPS186_2_PRF -+@@ -996,16 +1046,22 @@ endif -+ endif -+ ifneq ($(CONFIG_TLS), openssl) -+ ifneq ($(CONFIG_TLS), wolfssl) -++ifneq ($(CONFIG_TLS), mbedtls) -+ SHA1OBJS += ../src/crypto/sha1-pbkdf2.o -+ endif -+ endif -++endif -+ ifdef NEED_T_PRF -++ifneq ($(CONFIG_TLS), mbedtls) -+ SHA1OBJS += ../src/crypto/sha1-tprf.o -+ endif -++endif -+ ifdef NEED_TLS_PRF -++ifneq ($(CONFIG_TLS), mbedtls) -+ SHA1OBJS += ../src/crypto/sha1-tlsprf.o -+ endif -+ endif -++endif -+ -+ ifdef NEED_SHA1 -+ OBJS += $(SHA1OBJS) -+@@ -1015,11 +1071,13 @@ ifneq ($(CONFIG_TLS), openssl) -+ ifneq ($(CONFIG_TLS), linux) -+ ifneq ($(CONFIG_TLS), gnutls) -+ ifneq ($(CONFIG_TLS), wolfssl) -++ifneq ($(CONFIG_TLS), mbedtls) -+ OBJS += ../src/crypto/md5.o -+ endif -+ endif -+ endif -+ endif -++endif -+ -+ ifdef NEED_MD5 -+ ifdef CONFIG_INTERNAL_MD5 -+@@ -1058,56 +1116,81 @@ ifneq ($(CONFIG_TLS), openssl) -+ ifneq ($(CONFIG_TLS), linux) -+ ifneq ($(CONFIG_TLS), gnutls) -+ ifneq ($(CONFIG_TLS), wolfssl) -++ifneq ($(CONFIG_TLS), mbedtls) -+ OBJS += ../src/crypto/sha256.o -+ endif -+ endif -+ endif -+ endif -++endif -++ifneq ($(CONFIG_TLS), mbedtls) -+ OBJS += ../src/crypto/sha256-prf.o -++endif -+ ifdef CONFIG_INTERNAL_SHA256 -+ OBJS += ../src/crypto/sha256-internal.o -+ endif -+ ifdef NEED_TLS_PRF_SHA256 -++ifneq ($(CONFIG_TLS), mbedtls) -+ OBJS += ../src/crypto/sha256-tlsprf.o -+ endif -++endif -+ ifdef NEED_TLS_PRF_SHA384 -++ifneq ($(CONFIG_TLS), mbedtls) -+ OBJS += ../src/crypto/sha384-tlsprf.o -+ endif -++endif -+ ifdef NEED_HMAC_SHA256_KDF -++CFLAGS += -DCONFIG_HMAC_SHA256_KDF -++ifneq ($(CONFIG_TLS), mbedtls) -+ OBJS += ../src/crypto/sha256-kdf.o -+ endif -++endif -+ ifdef NEED_HMAC_SHA384_KDF -++CFLAGS += -DCONFIG_HMAC_SHA384_KDF -++ifneq ($(CONFIG_TLS), mbedtls) -+ OBJS += ../src/crypto/sha384-kdf.o -+ endif -++endif -+ ifdef NEED_HMAC_SHA512_KDF -++CFLAGS += -DCONFIG_HMAC_SHA512_KDF -++ifneq ($(CONFIG_TLS), mbedtls) -+ OBJS += ../src/crypto/sha512-kdf.o -+ endif -++endif -+ ifdef NEED_SHA384 -+ CFLAGS += -DCONFIG_SHA384 -+ ifneq ($(CONFIG_TLS), openssl) -+ ifneq ($(CONFIG_TLS), linux) -+ ifneq ($(CONFIG_TLS), gnutls) -+ ifneq ($(CONFIG_TLS), wolfssl) -++ifneq ($(CONFIG_TLS), mbedtls) -+ OBJS += ../src/crypto/sha384.o -+ endif -+ endif -+ endif -+ endif -++endif -++ifneq ($(CONFIG_TLS), mbedtls) -+ OBJS += ../src/crypto/sha384-prf.o -+ endif -++endif -+ ifdef NEED_SHA512 -+ CFLAGS += -DCONFIG_SHA512 -+ ifneq ($(CONFIG_TLS), openssl) -+ ifneq ($(CONFIG_TLS), linux) -+ ifneq ($(CONFIG_TLS), gnutls) -+ ifneq ($(CONFIG_TLS), wolfssl) -++ifneq ($(CONFIG_TLS), mbedtls) -+ OBJS += ../src/crypto/sha512.o -+ endif -+ endif -+ endif -+ endif -++endif -++ifneq ($(CONFIG_TLS), mbedtls) -+ OBJS += ../src/crypto/sha512-prf.o -+ endif -++endif -+ -+ ifdef CONFIG_INTERNAL_SHA384 -+ CFLAGS += -DCONFIG_INTERNAL_SHA384 -+@@ -1152,11 +1235,13 @@ HOBJS += $(SHA1OBJS) -+ ifneq ($(CONFIG_TLS), openssl) -+ ifneq ($(CONFIG_TLS), linux) -+ ifneq ($(CONFIG_TLS), wolfssl) -++ifneq ($(CONFIG_TLS), mbedtls) -+ HOBJS += ../src/crypto/md5.o -+ endif -+ endif -+ endif -+ endif -++endif -+ -+ ifdef CONFIG_RADIUS_SERVER -+ CFLAGS += -DRADIUS_SERVER -+@@ -1329,7 +1414,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 -++ifneq ($(CONFIG_TLS), mbedtls) -+ HOBJS += ../src/crypto/aes-encblock.o -++endif -+ 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 -+ SOBJS += ../src/common/sae_pk.o -+ SOBJS += ../src/common/dragonfly.o -+ SOBJS += $(AESOBJS) -++ifneq ($(CONFIG_TLS), mbedtls) -+ SOBJS += ../src/crypto/sha256-prf.o -+ SOBJS += ../src/crypto/sha384-prf.o -+ SOBJS += ../src/crypto/sha512-prf.o -++endif -+ SOBJS += ../src/crypto/dh_groups.o -++ifneq ($(CONFIG_TLS), mbedtls) -+ SOBJS += ../src/crypto/sha256-kdf.o -+ SOBJS += ../src/crypto/sha384-kdf.o -+ SOBJS += ../src/crypto/sha512-kdf.o -++endif -+ -+ _OBJS_VAR := NOBJS -+ include ../src/objs.mk -+--- a/hostapd/defconfig -++++ b/hostapd/defconfig -+@@ -6,9 +6,21 @@ -+ # just setting VARIABLE=n is not disabling that variable. -+ # -+ # This file is included in Makefile, so variables like CFLAGS and LIBS can also -+-# be modified from here. In most cass, these lines should use += in order not -++# be modified from here. In most cases, these lines should use += in order not -+ # to override previous values of the variables. -+ -++ -++# Uncomment following two lines and fix the paths if you have installed TLS -++# libraries in a non-default location -++#CFLAGS += -I/usr/local/openssl/include -++#LIBS += -L/usr/local/openssl/lib -++ -++# Some Red Hat versions seem to include kerberos header files from OpenSSL, but -++# the kerberos files are not in the default include path. Following line can be -++# used to fix build issues on such systems (krb5.h not found). -++#CFLAGS += -I/usr/include/kerberos -++ -++ -+ # Driver interface for Host AP driver -+ CONFIG_DRIVER_HOSTAP=y -+ -+@@ -278,6 +290,7 @@ CONFIG_IPV6=y -+ # openssl = OpenSSL (default) -+ # gnutls = GnuTLS -+ # internal = Internal TLSv1 implementation (experimental) -++# mbedtls = mbed TLS -+ # linux = Linux kernel AF_ALG and internal TLSv1 implementation (experimental) -+ # none = Empty template -+ #CONFIG_TLS=openssl -+--- /dev/null -++++ b/src/crypto/crypto_mbedtls.c -+@@ -0,0 +1,4043 @@ -++/* -++ * crypto wrapper functions for mbed TLS -++ * -++ * SPDX-FileCopyrightText: 2022 Glenn Strauss -++ * SPDX-License-Identifier: BSD-3-Clause -++ */ -++ -++#include "utils/includes.h" -++#include "utils/common.h" -++ -++#include -++#include -++#include -++#include /* mbedtls_platform_zeroize() */ -++#include -++#include -++#include -++#include -++#include -++#include -++#include -++#include -++ -++#ifndef MBEDTLS_PRIVATE -++#define MBEDTLS_PRIVATE(x) x -++#endif -++ -++/* hostapd/wpa_supplicant provides forced_memzero(), -++ * but prefer mbedtls_platform_zeroize() */ -++#define forced_memzero(ptr,sz) mbedtls_platform_zeroize(ptr,sz) -++ -++#ifndef __has_attribute -++#define __has_attribute(x) 0 -++#endif -++ -++#ifndef __GNUC_PREREQ -++#define __GNUC_PREREQ(maj,min) 0 -++#endif -++ -++#ifndef __attribute_cold__ -++#if __has_attribute(cold) \ -++ || __GNUC_PREREQ(4,3) -++#define __attribute_cold__ __attribute__((__cold__)) -++#else -++#define __attribute_cold__ -++#endif -++#endif -++ -++#ifndef __attribute_noinline__ -++#if __has_attribute(noinline) \ -++ || __GNUC_PREREQ(3,1) -++#define __attribute_noinline__ __attribute__((__noinline__)) -++#else -++#define __attribute_noinline__ -++#endif -++#endif -++ -++#include "crypto.h" -++#include "aes_wrap.h" -++#include "aes.h" -++#include "md5.h" -++#include "sha1.h" -++#include "sha256.h" -++#include "sha384.h" -++#include "sha512.h" -++ -++ -++/* -++ * selective code inclusion based on preprocessor defines -++ * -++ * future: additional code could be wrapped with preprocessor checks if -++ * wpa_supplicant/Makefile and hostap/Makefile were more consistent with -++ * setting preprocessor defines for named groups of functionality -++ */ -++ -++#if defined(CONFIG_FIPS) -++#undef MBEDTLS_MD4_C /* omit md4_vector() */ -++#undef MBEDTLS_MD5_C /* omit md5_vector() hmac_md5_vector() hmac_md5() */ -++#undef MBEDTLS_DES_C /* omit des_encrypt() */ -++#undef MBEDTLS_NIST_KW_C /* omit aes_wrap() aes_unwrap() */ -++#define CRYPTO_MBEDTLS_CONFIG_FIPS -++#endif -++ -++#if !defined(CONFIG_FIPS) -++#if defined(EAP_PWD) \ -++ || defined(EAP_LEAP) || defined(EAP_LEAP_DYNAMIC) \ -++ || defined(EAP_TTLS) || defined(EAP_TTLS_DYNAMIC) \ -++ || defined(EAP_MSCHAPv2) || defined(EAP_MSCHAPv2_DYNAMIC) \ -++ || defined(EAP_SERVER_MSCHAPV2) -++#ifndef MBEDTLS_MD4_C /* (MD4 not in mbedtls 3.x) */ -++#include "md4-internal.c"/* pull in hostap local implementation */ -++#endif /* md4_vector() */ -++#else -++#undef MBEDTLS_MD4_C /* omit md4_vector() */ -++#endif -++#endif -++ -++#if !defined(CONFIG_NO_RC4) && !defined(CONFIG_NO_WPA) -++#ifndef MBEDTLS_ARC4_C /* (RC4 not in mbedtls 3.x) */ -++#include "rc4.c" /* pull in hostap local implementation */ -++#endif /* rc4_skip() */ -++#else -++#undef MBEDTLS_ARC4_C /* omit rc4_skip() */ -++#endif -++ -++#if defined(CONFIG_MACSEC) \ -++ || defined(CONFIG_NO_RADIUS) \ -++ || defined(CONFIG_IEEE80211R) \ -++ || defined(EAP_SERVER_FAST) \ -++ || defined(EAP_SERVER_TEAP) \ -++ || !defined(CONFIG_NO_WPA) -++ /* aes_wrap() aes_unwrap() */ -++#else -++#undef MBEDTLS_NIST_KW_C /* omit aes_wrap() aes_unwrap() */ -++#endif -++ -++#if !defined(CONFIG_SHA256) -++#undef MBEDTLS_SHA256_C -++#endif -++ -++#if !defined(CONFIG_SHA384) && !defined(CONFIG_SHA512) -++#undef MBEDTLS_SHA512_C -++#endif -++ -++#if defined(CONFIG_HMAC_SHA256_KDF) -++#define CRYPTO_MBEDTLS_HMAC_KDF_SHA256 -++#endif -++#if defined(CONFIG_HMAC_SHA384_KDF) -++#define CRYPTO_MBEDTLS_HMAC_KDF_SHA384 -++#endif -++#if defined(CONFIG_HMAC_SHA512_KDF) -++#define CRYPTO_MBEDTLS_HMAC_KDF_SHA512 -++#endif -++ -++#if defined(EAP_FAST) || defined(EAP_FAST_DYNAMIC) || defined(EAP_SERVER_FAST) \ -++ || defined(EAP_TEAP) || defined(EAP_TEAP_DYNAMIC) || defined(EAP_SERVER_FAST) -++#define CRYPTO_MBEDTLS_SHA1_T_PRF -++#endif -++ -++#if defined(CONFIG_DES) -++#define CRYPTO_MBEDTLS_DES_ENCRYPT -++#endif /* des_encrypt() */ -++ -++#if !defined(CONFIG_NO_PBKDF2) -++#define CRYPTO_MBEDTLS_PBKDF2_SHA1 -++#endif /* pbkdf2_sha1() */ -++ -++#if defined(EAP_IKEV2) \ -++ || defined(EAP_IKEV2_DYNAMIC) \ -++ || defined(EAP_SERVER_IKEV2) /* CONFIG_EAP_IKEV2=y */ -++#define CRYPTO_MBEDTLS_CRYPTO_CIPHER -++#endif /* crypto_cipher_*() */ -++ -++#if defined(EAP_PWD) || defined(EAP_SERVER_PWD) /* CONFIG_EAP_PWD=y */ -++#define CRYPTO_MBEDTLS_CRYPTO_HASH -++#endif /* crypto_hash_*() */ -++ -++#if defined(EAP_PWD) || defined(EAP_SERVER_PWD) /* CONFIG_EAP_PWD=y */ \ -++ || defined(CONFIG_SAE) /* CONFIG_SAE=y */ -++#define CRYPTO_MBEDTLS_CRYPTO_BIGNUM -++#endif /* crypto_bignum_*() */ -++ -++#if defined(EAP_PWD) /* CONFIG_EAP_PWD=y */ \ -++ || defined(EAP_EKE) /* CONFIG_EAP_EKE=y */ \ -++ || defined(EAP_EKE_DYNAMIC) /* CONFIG_EAP_EKE=y */ \ -++ || defined(EAP_SERVER_EKE) /* CONFIG_EAP_EKE=y */ \ -++ || defined(EAP_IKEV2) /* CONFIG_EAP_IKEV2y */ \ -++ || defined(EAP_IKEV2_DYNAMIC)/* CONFIG_EAP_IKEV2=y */ \ -++ || defined(EAP_SERVER_IKEV2) /* CONFIG_EAP_IKEV2=y */ \ -++ || defined(CONFIG_SAE) /* CONFIG_SAE=y */ \ -++ || defined(CONFIG_WPS) /* CONFIG_WPS=y */ -++#define CRYPTO_MBEDTLS_CRYPTO_DH -++#if defined(CONFIG_WPS_NFC) -++#define CRYPTO_MBEDTLS_DH5_INIT_FIXED -++#endif /* dh5_init_fixed() */ -++#endif /* crypto_dh_*() */ -++ -++#if !defined(CONFIG_NO_WPA) /* CONFIG_NO_WPA= */ -++#define CRYPTO_MBEDTLS_CRYPTO_ECDH -++#endif /* crypto_ecdh_*() */ -++ -++#if defined(CONFIG_ECC) -++#define CRYPTO_MBEDTLS_CRYPTO_BIGNUM -++#define CRYPTO_MBEDTLS_CRYPTO_EC -++#endif /* crypto_ec_*() crypto_ec_key_*() */ -++ -++#if defined(CONFIG_DPP) /* CONFIG_DPP=y */ -++#define CRYPTO_MBEDTLS_CRYPTO_EC_DPP /* extra for DPP */ -++#define CRYPTO_MBEDTLS_CRYPTO_CSR -++#endif /* crypto_csr_*() */ -++ -++#if defined(CONFIG_DPP3) /* CONFIG_DPP3=y */ -++#define CRYPTO_MBEDTLS_CRYPTO_HPKE -++#endif -++ -++#if defined(CONFIG_DPP2) /* CONFIG_DPP2=y */ -++#define CRYPTO_MBEDTLS_CRYPTO_PKCS7 -++#endif /* crypto_pkcs7_*() */ -++ -++#if defined(EAP_SIM) || defined(EAP_SIM_DYNAMIC) || defined(EAP_SERVER_SIM) \ -++ || defined(EAP_AKA) || defined(EAP_AKA_DYNAMIC) || defined(EAP_SERVER_AKA) \ -++ || defined(CONFIG_AP) || defined(HOSTAPD) -++/* CONFIG_EAP_SIM=y CONFIG_EAP_AKA=y CONFIG_AP=y HOSTAPD */ -++#if defined(CRYPTO_RSA_OAEP_SHA256) -++#define CRYPTO_MBEDTLS_CRYPTO_RSA -++#endif -++#endif /* crypto_rsa_*() */ -++ -++ -++static int ctr_drbg_init_state; -++static mbedtls_ctr_drbg_context ctr_drbg; -++static mbedtls_entropy_context entropy; -++ -++#ifdef CRYPTO_MBEDTLS_CRYPTO_BIGNUM -++#include -++static mbedtls_mpi mpi_sw_A; -++#endif -++ -++__attribute_cold__ -++__attribute_noinline__ -++static mbedtls_ctr_drbg_context * ctr_drbg_init(void) -++{ -++ mbedtls_ctr_drbg_init(&ctr_drbg); -++ mbedtls_entropy_init(&entropy); -++ if (mbedtls_ctr_drbg_seed(&ctr_drbg, mbedtls_entropy_func, &entropy, -++ NULL, 0)) { -++ wpa_printf(MSG_ERROR, "Init of random number generator failed"); -++ /* XXX: abort? */ -++ } -++ else -++ ctr_drbg_init_state = 1; -++ -++ return &ctr_drbg; -++} -++ -++__attribute_cold__ -++void crypto_unload(void) -++{ -++ if (ctr_drbg_init_state) { -++ mbedtls_ctr_drbg_free(&ctr_drbg); -++ mbedtls_entropy_free(&entropy); -++ #ifdef CRYPTO_MBEDTLS_CRYPTO_BIGNUM -++ mbedtls_mpi_free(&mpi_sw_A); -++ #endif -++ ctr_drbg_init_state = 0; -++ } -++} -++ -++/* init ctr_drbg on first use -++ * crypto_global_init() and crypto_global_deinit() are not available here -++ * (available only when CONFIG_TLS=internal, which is not CONFIG_TLS=mbedtls) */ -++mbedtls_ctr_drbg_context * crypto_mbedtls_ctr_drbg(void); /*(not in header)*/ -++inline -++mbedtls_ctr_drbg_context * crypto_mbedtls_ctr_drbg(void) -++{ -++ return ctr_drbg_init_state ? &ctr_drbg : ctr_drbg_init(); -++} -++ -++#ifdef CRYPTO_MBEDTLS_CONFIG_FIPS -++int crypto_get_random(void *buf, size_t len) -++{ -++ return mbedtls_ctr_drbg_random(crypto_mbedtls_ctr_drbg(),buf,len) ? -1 : 0; -++} -++#endif -++ -++ -++#if 1 -++ -++/* tradeoff: slightly smaller code size here at cost of slight increase -++ * in instructions and function calls at runtime versus the expanded -++ * per-message-digest code that follows in #else (~0.5 kib .text larger) */ -++ -++__attribute_noinline__ -++static int md_vector(size_t num_elem, const u8 *addr[], const size_t *len, -++ u8 *mac, mbedtls_md_type_t md_type) -++{ -++ mbedtls_md_context_t ctx; -++ mbedtls_md_init(&ctx); -++ if (mbedtls_md_setup(&ctx, mbedtls_md_info_from_type(md_type), 0) != 0){ -++ mbedtls_md_free(&ctx); -++ return -1; -++ } -++ mbedtls_md_starts(&ctx); -++ for (size_t i = 0; i < num_elem; ++i) -++ mbedtls_md_update(&ctx, addr[i], len[i]); -++ mbedtls_md_finish(&ctx, mac); -++ mbedtls_md_free(&ctx); -++ return 0; -++} -++ -++#ifdef MBEDTLS_SHA512_C -++int sha512_vector(size_t num_elem, const u8 *addr[], const size_t *len, u8 *mac) -++{ -++ return md_vector(num_elem, addr, len, mac, MBEDTLS_MD_SHA512); -++} -++ -++int sha384_vector(size_t num_elem, const u8 *addr[], const size_t *len, u8 *mac) -++{ -++ return md_vector(num_elem, addr, len, mac, MBEDTLS_MD_SHA384); -++} -++#endif -++ -++#ifdef MBEDTLS_SHA256_C -++int sha256_vector(size_t num_elem, const u8 *addr[], const size_t *len, u8 *mac) -++{ -++ return md_vector(num_elem, addr, len, mac, MBEDTLS_MD_SHA256); -++} -++#endif -++ -++#ifdef MBEDTLS_SHA1_C -++int sha1_vector(size_t num_elem, const u8 *addr[], const size_t *len, u8 *mac) -++{ -++ return md_vector(num_elem, addr, len, mac, MBEDTLS_MD_SHA1); -++} -++#endif -++ -++#ifdef MBEDTLS_MD5_C -++int md5_vector(size_t num_elem, const u8 *addr[], const size_t *len, u8 *mac) -++{ -++ return md_vector(num_elem, addr, len, mac, MBEDTLS_MD_MD5); -++} -++#endif -++ -++#ifdef MBEDTLS_MD4_C -++#include -++int md4_vector(size_t num_elem, const u8 *addr[], const size_t *len, u8 *mac) -++{ -++ return md_vector(num_elem, addr, len, mac, MBEDTLS_MD_MD4); -++} -++#endif -++ -++#else /* expanded per-message-digest functions */ -++ -++#ifdef MBEDTLS_SHA512_C -++#include -++__attribute_noinline__ -++static int sha384_512_vector(size_t num_elem, const u8 *addr[], -++ const size_t *len, u8 *mac, int is384) -++{ -++ struct mbedtls_sha512_context ctx; -++ mbedtls_sha512_init(&ctx); -++ #if MBEDTLS_VERSION_MAJOR >= 3 -++ mbedtls_sha512_starts(&ctx, is384); -++ for (size_t i = 0; i < num_elem; ++i) -++ mbedtls_sha512_update(&ctx, addr[i], len[i]); -++ mbedtls_sha512_finish(&ctx, mac); -++ #else -++ mbedtls_sha512_starts_ret(&ctx, is384); -++ for (size_t i = 0; i < num_elem; ++i) -++ mbedtls_sha512_update_ret(&ctx, addr[i], len[i]); -++ mbedtls_sha512_finish_ret(&ctx, mac); -++ #endif -++ mbedtls_sha512_free(&ctx); -++ return 0; -++} -++ -++int sha512_vector(size_t num_elem, const u8 *addr[], const size_t *len, u8 *mac) -++{ -++ return sha384_512_vector(num_elem, addr, len, mac, 0); -++} -++ -++int sha384_vector(size_t num_elem, const u8 *addr[], const size_t *len, u8 *mac) -++{ -++ return sha384_512_vector(num_elem, addr, len, mac, 1); -++} -++#endif -++ -++#ifdef MBEDTLS_SHA256_C -++#include -++int sha256_vector(size_t num_elem, const u8 *addr[], const size_t *len, u8 *mac) -++{ -++ struct mbedtls_sha256_context ctx; -++ mbedtls_sha256_init(&ctx); -++ #if MBEDTLS_VERSION_MAJOR >= 3 -++ mbedtls_sha256_starts(&ctx, 0); -++ for (size_t i = 0; i < num_elem; ++i) -++ mbedtls_sha256_update(&ctx, addr[i], len[i]); -++ mbedtls_sha256_finish(&ctx, mac); -++ #else -++ mbedtls_sha256_starts_ret(&ctx, 0); -++ for (size_t i = 0; i < num_elem; ++i) -++ mbedtls_sha256_update_ret(&ctx, addr[i], len[i]); -++ mbedtls_sha256_finish_ret(&ctx, mac); -++ #endif -++ mbedtls_sha256_free(&ctx); -++ return 0; -++} -++#endif -++ -++#ifdef MBEDTLS_SHA1_C -++#include -++int sha1_vector(size_t num_elem, const u8 *addr[], const size_t *len, u8 *mac) -++{ -++ struct mbedtls_sha1_context ctx; -++ mbedtls_sha1_init(&ctx); -++ #if MBEDTLS_VERSION_MAJOR >= 3 -++ mbedtls_sha1_starts(&ctx); -++ for (size_t i = 0; i < num_elem; ++i) -++ mbedtls_sha1_update(&ctx, addr[i], len[i]); -++ mbedtls_sha1_finish(&ctx, mac); -++ #else -++ mbedtls_sha1_starts_ret(&ctx); -++ for (size_t i = 0; i < num_elem; ++i) -++ mbedtls_sha1_update_ret(&ctx, addr[i], len[i]); -++ mbedtls_sha1_finish_ret(&ctx, mac); -++ #endif -++ mbedtls_sha1_free(&ctx); -++ return 0; -++} -++#endif -++ -++#ifdef MBEDTLS_MD5_C -++#include -++int md5_vector(size_t num_elem, const u8 *addr[], const size_t *len, u8 *mac) -++{ -++ struct mbedtls_md5_context ctx; -++ mbedtls_md5_init(&ctx); -++ #if MBEDTLS_VERSION_MAJOR >= 3 -++ mbedtls_md5_starts(&ctx); -++ for (size_t i = 0; i < num_elem; ++i) -++ mbedtls_md5_update(&ctx, addr[i], len[i]); -++ mbedtls_md5_finish(&ctx, mac); -++ #else -++ mbedtls_md5_starts_ret(&ctx); -++ for (size_t i = 0; i < num_elem; ++i) -++ mbedtls_md5_update_ret(&ctx, addr[i], len[i]); -++ mbedtls_md5_finish_ret(&ctx, mac); -++ #endif -++ mbedtls_md5_free(&ctx); -++ return 0; -++} -++#endif -++ -++#ifdef MBEDTLS_MD4_C -++#include -++int md4_vector(size_t num_elem, const u8 *addr[], const size_t *len, u8 *mac) -++{ -++ struct mbedtls_md4_context ctx; -++ mbedtls_md4_init(&ctx); -++ mbedtls_md4_starts_ret(&ctx); -++ for (size_t i = 0; i < num_elem; ++i) -++ mbedtls_md4_update_ret(&ctx, addr[i], len[i]); -++ mbedtls_md4_finish_ret(&ctx, mac); -++ mbedtls_md4_free(&ctx); -++ return 0; -++} -++#endif -++ -++#endif /* expanded per-message-digest functions */ -++ -++ -++__attribute_noinline__ -++static int hmac_vector(const u8 *key, size_t key_len, size_t num_elem, -++ const u8 *addr[], const size_t *len, u8 *mac, -++ mbedtls_md_type_t md_type) -++{ -++ mbedtls_md_context_t ctx; -++ mbedtls_md_init(&ctx); -++ if (mbedtls_md_setup(&ctx, mbedtls_md_info_from_type(md_type), 1) != 0){ -++ mbedtls_md_free(&ctx); -++ return -1; -++ } -++ mbedtls_md_hmac_starts(&ctx, key, key_len); -++ for (size_t i = 0; i < num_elem; ++i) -++ mbedtls_md_hmac_update(&ctx, addr[i], len[i]); -++ mbedtls_md_hmac_finish(&ctx, mac); -++ mbedtls_md_free(&ctx); -++ return 0; -++} -++ -++#ifdef MBEDTLS_SHA512_C -++int hmac_sha512_vector(const u8 *key, size_t key_len, size_t num_elem, -++ const u8 *addr[], const size_t *len, u8 *mac) -++{ -++ return hmac_vector(key, key_len, num_elem, addr, len, mac, -++ MBEDTLS_MD_SHA512); -++} -++ -++int hmac_sha512(const u8 *key, size_t key_len, const u8 *data, size_t data_len, -++ u8 *mac) -++{ -++ return hmac_vector(key, key_len, 1, &data, &data_len, mac, -++ MBEDTLS_MD_SHA512); -++} -++ -++int hmac_sha384_vector(const u8 *key, size_t key_len, size_t num_elem, -++ const u8 *addr[], const size_t *len, u8 *mac) -++{ -++ return hmac_vector(key, key_len, num_elem, addr, len, mac, -++ MBEDTLS_MD_SHA384); -++} -++ -++int hmac_sha384(const u8 *key, size_t key_len, const u8 *data, size_t data_len, -++ u8 *mac) -++{ -++ return hmac_vector(key, key_len, 1, &data, &data_len, mac, -++ MBEDTLS_MD_SHA384); -++} -++#endif -++ -++#ifdef MBEDTLS_SHA256_C -++int hmac_sha256_vector(const u8 *key, size_t key_len, size_t num_elem, -++ const u8 *addr[], const size_t *len, u8 *mac) -++{ -++ return hmac_vector(key, key_len, num_elem, addr, len, mac, -++ MBEDTLS_MD_SHA256); -++} -++ -++int hmac_sha256(const u8 *key, size_t key_len, const u8 *data, size_t data_len, -++ u8 *mac) -++{ -++ return hmac_vector(key, key_len, 1, &data, &data_len, mac, -++ MBEDTLS_MD_SHA256); -++} -++#endif -++ -++#ifdef MBEDTLS_SHA1_C -++int hmac_sha1_vector(const u8 *key, size_t key_len, size_t num_elem, -++ const u8 *addr[], const size_t *len, u8 *mac) -++{ -++ return hmac_vector(key, key_len, num_elem, addr, len, mac, -++ MBEDTLS_MD_SHA1); -++} -++ -++int hmac_sha1(const u8 *key, size_t key_len, const u8 *data, size_t data_len, -++ u8 *mac) -++{ -++ return hmac_vector(key, key_len, 1, &data, &data_len, mac, -++ MBEDTLS_MD_SHA1); -++} -++#endif -++ -++#ifdef MBEDTLS_MD5_C -++int hmac_md5_vector(const u8 *key, size_t key_len, size_t num_elem, -++ const u8 *addr[], const size_t *len, u8 *mac) -++{ -++ return hmac_vector(key, key_len, num_elem, addr, len, mac, -++ MBEDTLS_MD_MD5); -++} -++ -++int hmac_md5(const u8 *key, size_t key_len, const u8 *data, size_t data_len, -++ u8 *mac) -++{ -++ return hmac_vector(key, key_len, 1, &data, &data_len, mac, -++ MBEDTLS_MD_MD5); -++} -++#endif -++ -++ -++#if defined(MBEDTLS_SHA256_C) || defined(MBEDTLS_SHA512_C) -++ -++#if defined(CRYPTO_MBEDTLS_HMAC_KDF_SHA256) \ -++ || defined(CRYPTO_MBEDTLS_HMAC_KDF_SHA384) \ -++ || defined(CRYPTO_MBEDTLS_HMAC_KDF_SHA512) -++ -++#include -++ -++/* sha256-kdf.c sha384-kdf.c sha512-kdf.c */ -++ -++/* HMAC-SHA256 KDF (RFC 5295) and HKDF-Expand(SHA256) (RFC 5869) */ -++/* HMAC-SHA384 KDF (RFC 5295) and HKDF-Expand(SHA384) (RFC 5869) */ -++/* HMAC-SHA512 KDF (RFC 5295) and HKDF-Expand(SHA512) (RFC 5869) */ -++__attribute_noinline__ -++static int hmac_kdf_expand(const u8 *prk, size_t prk_len, -++ const char *label, const u8 *info, size_t info_len, -++ u8 *okm, size_t okm_len, mbedtls_md_type_t md_type) -++{ -++ const mbedtls_md_info_t *md_info = mbedtls_md_info_from_type(md_type); -++ #ifdef MBEDTLS_HKDF_C -++ if (label == NULL) /* RFC 5869 HKDF-Expand when (label == NULL) */ -++ return mbedtls_hkdf_expand(md_info, prk, prk_len, info, -++ info_len, okm, okm_len) ? -1 : 0; -++ #endif -++ -++ const size_t mac_len = mbedtls_md_get_size(md_info); -++ /* okm_len must not exceed 255 times hash len (RFC 5869 Section 2.3) */ -++ if (okm_len > ((mac_len << 8) - mac_len)) -++ return -1; -++ -++ mbedtls_md_context_t ctx; -++ mbedtls_md_init(&ctx); -++ if (mbedtls_md_setup(&ctx, md_info, 1) != 0) { -++ mbedtls_md_free(&ctx); -++ return -1; -++ } -++ mbedtls_md_hmac_starts(&ctx, prk, prk_len); -++ -++ u8 iter = 1; -++ const u8 *addr[4] = { okm, (const u8 *)label, info, &iter }; -++ size_t len[4] = { 0, label ? os_strlen(label)+1 : 0, info_len, 1 }; -++ -++ for (; okm_len >= mac_len; okm_len -= mac_len, ++iter) { -++ for (size_t i = 0; i < ARRAY_SIZE(addr); ++i) -++ mbedtls_md_hmac_update(&ctx, addr[i], len[i]); -++ mbedtls_md_hmac_finish(&ctx, okm); -++ mbedtls_md_hmac_reset(&ctx); -++ addr[0] = okm; -++ okm += mac_len; -++ len[0] = mac_len; /*(include digest in subsequent rounds)*/ -++ } -++ -++ if (okm_len) { -++ u8 hash[MBEDTLS_MD_MAX_SIZE]; -++ for (size_t i = 0; i < ARRAY_SIZE(addr); ++i) -++ mbedtls_md_hmac_update(&ctx, addr[i], len[i]); -++ mbedtls_md_hmac_finish(&ctx, hash); -++ os_memcpy(okm, hash, okm_len); -++ forced_memzero(hash, mac_len); -++ } -++ -++ mbedtls_md_free(&ctx); -++ return 0; -++} -++ -++#ifdef MBEDTLS_SHA512_C -++#ifdef CRYPTO_MBEDTLS_HMAC_KDF_SHA512 -++int hmac_sha512_kdf(const u8 *secret, size_t secret_len, -++ const char *label, const u8 *seed, size_t seed_len, -++ u8 *out, size_t outlen) -++{ -++ return hmac_kdf_expand(secret, secret_len, label, seed, seed_len, -++ out, outlen, MBEDTLS_MD_SHA512); -++} -++#endif -++ -++#ifdef CRYPTO_MBEDTLS_HMAC_KDF_SHA384 -++int hmac_sha384_kdf(const u8 *secret, size_t secret_len, -++ const char *label, const u8 *seed, size_t seed_len, -++ u8 *out, size_t outlen) -++{ -++ return hmac_kdf_expand(secret, secret_len, label, seed, seed_len, -++ out, outlen, MBEDTLS_MD_SHA384); -++} -++#endif -++#endif -++ -++#ifdef MBEDTLS_SHA256_C -++#ifdef CRYPTO_MBEDTLS_HMAC_KDF_SHA256 -++int hmac_sha256_kdf(const u8 *secret, size_t secret_len, -++ const char *label, const u8 *seed, size_t seed_len, -++ u8 *out, size_t outlen) -++{ -++ return hmac_kdf_expand(secret, secret_len, label, seed, seed_len, -++ out, outlen, MBEDTLS_MD_SHA256); -++} -++#endif -++#endif -++ -++#endif /* CRYPTO_MBEDTLS_HMAC_KDF_* */ -++ -++ -++/* sha256-prf.c sha384-prf.c sha512-prf.c */ -++ -++/* hmac_prf_bits - IEEE Std 802.11ac-2013, 11.6.1.7.2 Key derivation function */ -++__attribute_noinline__ -++static int hmac_prf_bits(const u8 *key, size_t key_len, const char *label, -++ const u8 *data, size_t data_len, u8 *buf, -++ size_t buf_len_bits, mbedtls_md_type_t md_type) -++{ -++ mbedtls_md_context_t ctx; -++ mbedtls_md_init(&ctx); -++ const mbedtls_md_info_t *md_info = mbedtls_md_info_from_type(md_type); -++ if (mbedtls_md_setup(&ctx, md_info, 1) != 0) { -++ mbedtls_md_free(&ctx); -++ return -1; -++ } -++ mbedtls_md_hmac_starts(&ctx, key, key_len); -++ -++ u16 ctr, n_le = host_to_le16(buf_len_bits); -++ const u8 * const addr[] = { (u8 *)&ctr,(u8 *)label,data,(u8 *)&n_le }; -++ const size_t len[] = { 2, os_strlen(label), data_len, 2 }; -++ const size_t mac_len = mbedtls_md_get_size(md_info); -++ size_t buf_len = (buf_len_bits + 7) / 8; -++ for (ctr = 1; buf_len >= mac_len; buf_len -= mac_len, ++ctr) { -++ #if __BYTE_ORDER == __BIG_ENDIAN -++ ctr = host_to_le16(ctr); -++ #endif -++ for (size_t i = 0; i < ARRAY_SIZE(addr); ++i) -++ mbedtls_md_hmac_update(&ctx, addr[i], len[i]); -++ mbedtls_md_hmac_finish(&ctx, buf); -++ mbedtls_md_hmac_reset(&ctx); -++ buf += mac_len; -++ #if __BYTE_ORDER == __BIG_ENDIAN -++ ctr = le_to_host16(ctr); -++ #endif -++ } -++ -++ if (buf_len) { -++ u8 hash[MBEDTLS_MD_MAX_SIZE]; -++ #if __BYTE_ORDER == __BIG_ENDIAN -++ ctr = host_to_le16(ctr); -++ #endif -++ for (size_t i = 0; i < ARRAY_SIZE(addr); ++i) -++ mbedtls_md_hmac_update(&ctx, addr[i], len[i]); -++ mbedtls_md_hmac_finish(&ctx, hash); -++ os_memcpy(buf, hash, buf_len); -++ buf += buf_len; -++ forced_memzero(hash, mac_len); -++ } -++ -++ /* Mask out unused bits in last octet if it does not use all the bits */ -++ if ((buf_len_bits &= 0x7)) -++ buf[-1] &= (u8)(0xff << (8 - buf_len_bits)); -++ -++ mbedtls_md_free(&ctx); -++ return 0; -++} -++ -++#ifdef MBEDTLS_SHA512_C -++int sha512_prf(const u8 *key, size_t key_len, const char *label, -++ const u8 *data, size_t data_len, u8 *buf, size_t buf_len) -++{ -++ return hmac_prf_bits(key, key_len, label, data, data_len, buf, -++ buf_len * 8, MBEDTLS_MD_SHA512); -++} -++ -++int sha384_prf(const u8 *key, size_t key_len, const char *label, -++ const u8 *data, size_t data_len, u8 *buf, size_t buf_len) -++{ -++ return hmac_prf_bits(key, key_len, label, data, data_len, buf, -++ buf_len * 8, MBEDTLS_MD_SHA384); -++} -++#endif -++ -++#ifdef MBEDTLS_SHA256_C -++int sha256_prf(const u8 *key, size_t key_len, const char *label, -++ const u8 *data, size_t data_len, u8 *buf, size_t buf_len) -++{ -++ return hmac_prf_bits(key, key_len, label, data, data_len, buf, -++ buf_len * 8, MBEDTLS_MD_SHA256); -++} -++ -++int sha256_prf_bits(const u8 *key, size_t key_len, const char *label, -++ const u8 *data, size_t data_len, u8 *buf, -++ size_t buf_len_bits) -++{ -++ return hmac_prf_bits(key, key_len, label, data, data_len, buf, -++ buf_len_bits, MBEDTLS_MD_SHA256); -++} -++#endif -++ -++#endif /* MBEDTLS_SHA256_C || MBEDTLS_SHA512_C */ -++ -++ -++#ifdef MBEDTLS_SHA1_C -++ -++/* sha1-prf.c */ -++ -++/* sha1_prf - SHA1-based Pseudo-Random Function (PRF) (IEEE 802.11i, 8.5.1.1) */ -++ -++int sha1_prf(const u8 *key, size_t key_len, const char *label, -++ const u8 *data, size_t data_len, u8 *buf, size_t buf_len) -++{ -++ /*(note: algorithm differs from hmac_prf_bits() */ -++ /*(note: smaller code size instead of expanding hmac_sha1_vector() -++ * as is done in hmac_prf_bits(); not expecting large num of loops) */ -++ u8 counter = 0; -++ const u8 *addr[] = { (u8 *)label, data, &counter }; -++ const size_t len[] = { os_strlen(label)+1, data_len, 1 }; -++ -++ for (; buf_len >= SHA1_MAC_LEN; buf_len -= SHA1_MAC_LEN, ++counter) { -++ if (hmac_sha1_vector(key, key_len, 3, addr, len, buf)) -++ return -1; -++ buf += SHA1_MAC_LEN; -++ } -++ -++ if (buf_len) { -++ u8 hash[SHA1_MAC_LEN]; -++ if (hmac_sha1_vector(key, key_len, 3, addr, len, hash)) -++ return -1; -++ os_memcpy(buf, hash, buf_len); -++ forced_memzero(hash, sizeof(hash)); -++ } -++ -++ return 0; -++} -++ -++#ifdef CRYPTO_MBEDTLS_SHA1_T_PRF -++ -++/* sha1-tprf.c */ -++ -++/* sha1_t_prf - EAP-FAST Pseudo-Random Function (T-PRF) (RFC 4851,Section 5.5)*/ -++ -++int sha1_t_prf(const u8 *key, size_t key_len, const char *label, -++ const u8 *seed, size_t seed_len, u8 *buf, size_t buf_len) -++{ -++ /*(note: algorithm differs from hmac_prf_bits() and hmac_kdf() above)*/ -++ /*(note: smaller code size instead of expanding hmac_sha1_vector() -++ * as is done in hmac_prf_bits(); not expecting large num of loops) */ -++ u8 ctr; -++ u16 olen = host_to_be16(buf_len); -++ const u8 *addr[] = { buf, (u8 *)label, seed, (u8 *)&olen, &ctr }; -++ size_t len[] = { 0, os_strlen(label)+1, seed_len, 2, 1 }; -++ -++ for (ctr = 1; buf_len >= SHA1_MAC_LEN; buf_len -= SHA1_MAC_LEN, ++ctr) { -++ if (hmac_sha1_vector(key, key_len, 5, addr, len, buf)) -++ return -1; -++ addr[0] = buf; -++ buf += SHA1_MAC_LEN; -++ len[0] = SHA1_MAC_LEN; /*(include digest in subsequent rounds)*/ -++ } -++ -++ if (buf_len) { -++ u8 hash[SHA1_MAC_LEN]; -++ if (hmac_sha1_vector(key, key_len, 5, addr, len, hash)) -++ return -1; -++ os_memcpy(buf, hash, buf_len); -++ forced_memzero(hash, sizeof(hash)); -++ } -++ -++ return 0; -++} -++ -++#endif /* CRYPTO_MBEDTLS_SHA1_T_PRF */ -++ -++#endif /* MBEDTLS_SHA1_C */ -++ -++ -++#ifdef CRYPTO_MBEDTLS_DES_ENCRYPT -++#ifdef MBEDTLS_DES_C -++#include -++int des_encrypt(const u8 *clear, const u8 *key, u8 *cypher) -++{ -++ u8 pkey[8], next, tmp; -++ int i; -++ -++ /* Add parity bits to the key */ -++ next = 0; -++ for (i = 0; i < 7; i++) { -++ tmp = key[i]; -++ pkey[i] = (tmp >> i) | next | 1; -++ next = tmp << (7 - i); -++ } -++ pkey[i] = next | 1; -++ -++ mbedtls_des_context des; -++ mbedtls_des_init(&des); -++ int ret = mbedtls_des_setkey_enc(&des, pkey) -++ || mbedtls_des_crypt_ecb(&des, clear, cypher) ? -1 : 0; -++ mbedtls_des_free(&des); -++ return ret; -++} -++#else -++#include "des-internal.c"/* pull in hostap local implementation */ -++#endif -++#endif -++ -++ -++#ifdef CRYPTO_MBEDTLS_PBKDF2_SHA1 -++/* sha1-pbkdf2.c */ -++#include -++int pbkdf2_sha1(const char *passphrase, const u8 *ssid, size_t ssid_len, -++ int iterations, u8 *buf, size_t buflen) -++{ -++ #if MBEDTLS_VERSION_NUMBER >= 0x03020200 /* mbedtls 3.2.2 */ -++ return mbedtls_pkcs5_pbkdf2_hmac_ext(MBEDTLS_MD_SHA1, -++ (const u8 *)passphrase, os_strlen(passphrase), -++ ssid, ssid_len, iterations, 32, buf) ? -1 : 0; -++ #else -++ const mbedtls_md_info_t *md_info; -++ md_info = mbedtls_md_info_from_type(MBEDTLS_MD_SHA1); -++ if (md_info == NULL) -++ return -1; -++ mbedtls_md_context_t ctx; -++ mbedtls_md_init(&ctx); -++ int ret = mbedtls_md_setup(&ctx, md_info, 1) -++ || mbedtls_pkcs5_pbkdf2_hmac(&ctx, -++ (const u8 *)passphrase, os_strlen(passphrase), -++ ssid, ssid_len, iterations, 32, buf) ? -1 : 0; -++ mbedtls_md_free(&ctx); -++ return ret; -++ #endif -++} -++#endif -++ -++ -++/*#include "aes.h"*/ /* prototypes also included in "crypto.h" */ -++ -++static void *aes_crypt_init_mode(const u8 *key, size_t len, int mode) -++{ -++ mbedtls_aes_context *aes = os_malloc(sizeof(*aes)); -++ if (!aes) -++ return NULL; -++ -++ mbedtls_aes_init(aes); -++ if ((mode == MBEDTLS_AES_ENCRYPT -++ ? mbedtls_aes_setkey_enc(aes, key, len * 8) -++ : mbedtls_aes_setkey_dec(aes, key, len * 8)) == 0) -++ return aes; -++ -++ mbedtls_aes_free(aes); -++ os_free(aes); -++ return NULL; -++} -++ -++void *aes_encrypt_init(const u8 *key, size_t len) -++{ -++ return aes_crypt_init_mode(key, len, MBEDTLS_AES_ENCRYPT); -++} -++ -++int aes_encrypt(void *ctx, const u8 *plain, u8 *crypt) -++{ -++ return mbedtls_aes_crypt_ecb(ctx, MBEDTLS_AES_ENCRYPT, plain, crypt); -++} -++ -++void aes_encrypt_deinit(void *ctx) -++{ -++ mbedtls_aes_free(ctx); -++ os_free(ctx); -++} -++ -++void *aes_decrypt_init(const u8 *key, size_t len) -++{ -++ return aes_crypt_init_mode(key, len, MBEDTLS_AES_DECRYPT); -++} -++ -++int aes_decrypt(void *ctx, const u8 *crypt, u8 *plain) -++{ -++ return mbedtls_aes_crypt_ecb(ctx, MBEDTLS_AES_DECRYPT, crypt, plain); -++} -++ -++void aes_decrypt_deinit(void *ctx) -++{ -++ mbedtls_aes_free(ctx); -++ os_free(ctx); -++} -++ -++ -++#include "aes_wrap.h" -++ -++ -++#ifdef MBEDTLS_NIST_KW_C -++ -++#include -++ -++/* aes-wrap.c */ -++int aes_wrap(const u8 *kek, size_t kek_len, int n, const u8 *plain, u8 *cipher) -++{ -++ mbedtls_nist_kw_context ctx; -++ mbedtls_nist_kw_init(&ctx); -++ size_t olen; -++ int ret = mbedtls_nist_kw_setkey(&ctx, MBEDTLS_CIPHER_ID_AES, -++ kek, kek_len*8, 1) -++ || mbedtls_nist_kw_wrap(&ctx, MBEDTLS_KW_MODE_KW, plain, n*8, -++ cipher, &olen, (n+1)*8) ? -1 : 0; -++ mbedtls_nist_kw_free(&ctx); -++ return ret; -++} -++ -++/* aes-unwrap.c */ -++int aes_unwrap(const u8 *kek, size_t kek_len, int n, const u8 *cipher, u8 *plain) -++{ -++ mbedtls_nist_kw_context ctx; -++ mbedtls_nist_kw_init(&ctx); -++ size_t olen; -++ int ret = mbedtls_nist_kw_setkey(&ctx, MBEDTLS_CIPHER_ID_AES, -++ kek, kek_len*8, 0) -++ || mbedtls_nist_kw_unwrap(&ctx, MBEDTLS_KW_MODE_KW, cipher, -++ (n+1)*8, plain, &olen, n*8) ? -1 : 0; -++ mbedtls_nist_kw_free(&ctx); -++ return ret; -++} -++ -++#else -++ -++#ifndef CRYPTO_MBEDTLS_CONFIG_FIPS -++#include "aes-wrap.c" /* pull in hostap local implementation */ -++#include "aes-unwrap.c" /* pull in hostap local implementation */ -++#endif -++ -++#endif /* MBEDTLS_NIST_KW_C */ -++ -++ -++#ifdef MBEDTLS_CMAC_C -++ -++/* aes-omac1.c */ -++ -++#include -++ -++int omac1_aes_vector( -++ const u8 *key, size_t key_len, size_t num_elem, const u8 *addr[], -++ const size_t *len, u8 *mac) -++{ -++ mbedtls_cipher_type_t cipher_type; -++ switch (key_len) { -++ case 16: cipher_type = MBEDTLS_CIPHER_AES_128_ECB; break; -++ case 24: cipher_type = MBEDTLS_CIPHER_AES_192_ECB; break; -++ case 32: cipher_type = MBEDTLS_CIPHER_AES_256_ECB; break; -++ default: return -1; -++ } -++ const mbedtls_cipher_info_t *cipher_info; -++ cipher_info = mbedtls_cipher_info_from_type(cipher_type); -++ if (cipher_info == NULL) -++ return -1; -++ -++ mbedtls_cipher_context_t ctx; -++ mbedtls_cipher_init(&ctx); -++ int ret = -1; -++ if (mbedtls_cipher_setup(&ctx, cipher_info) == 0 -++ && mbedtls_cipher_cmac_starts(&ctx, key, key_len*8) == 0) { -++ ret = 0; -++ for (size_t i = 0; i < num_elem && ret == 0; ++i) -++ ret = mbedtls_cipher_cmac_update(&ctx, addr[i], len[i]); -++ } -++ if (ret == 0) -++ ret = mbedtls_cipher_cmac_finish(&ctx, mac); -++ mbedtls_cipher_free(&ctx); -++ return ret ? -1 : 0; -++} -++ -++int omac1_aes_128_vector(const u8 *key, size_t num_elem, -++ const u8 *addr[], const size_t *len, -++ u8 *mac) -++{ -++ return omac1_aes_vector(key, 16, num_elem, addr, len, mac); -++} -++ -++int omac1_aes_128(const u8 *key, const u8 *data, size_t data_len, u8 *mac) -++{ -++ return omac1_aes_vector(key, 16, 1, &data, &data_len, mac); -++} -++ -++int omac1_aes_256(const u8 *key, const u8 *data, size_t data_len, u8 *mac) -++{ -++ return omac1_aes_vector(key, 32, 1, &data, &data_len, mac); -++} -++ -++#else -++ -++#include "aes-omac1.c" /* pull in hostap local implementation */ -++ -++#ifndef MBEDTLS_AES_BLOCK_SIZE -++#define MBEDTLS_AES_BLOCK_SIZE 16 -++#endif -++ -++#endif /* MBEDTLS_CMAC_C */ -++ -++ -++/* These interfaces can be inefficient when used in loops, as the overhead of -++ * initialization each call is large for each block input (e.g. 16 bytes) */ -++ -++ -++/* aes-encblock.c */ -++int aes_128_encrypt_block(const u8 *key, const u8 *in, u8 *out) -++{ -++ mbedtls_aes_context aes; -++ mbedtls_aes_init(&aes); -++ int ret = mbedtls_aes_setkey_enc(&aes, key, 128) -++ || mbedtls_aes_crypt_ecb(&aes, MBEDTLS_AES_ENCRYPT, in, out) -++ ? -1 -++ : 0; -++ mbedtls_aes_free(&aes); -++ return ret; -++} -++ -++ -++/* aes-ctr.c */ -++int aes_ctr_encrypt(const u8 *key, size_t key_len, const u8 *nonce, -++ u8 *data, size_t data_len) -++{ -++ unsigned char counter[MBEDTLS_AES_BLOCK_SIZE]; -++ unsigned char stream_block[MBEDTLS_AES_BLOCK_SIZE]; -++ os_memcpy(counter, nonce, MBEDTLS_AES_BLOCK_SIZE);/*(must be writable)*/ -++ -++ mbedtls_aes_context ctx; -++ mbedtls_aes_init(&ctx); -++ size_t nc_off = 0; -++ int ret = mbedtls_aes_setkey_enc(&ctx, key, key_len*8) -++ || mbedtls_aes_crypt_ctr(&ctx, data_len, &nc_off, -++ counter, stream_block, -++ data, data) ? -1 : 0; -++ forced_memzero(stream_block, sizeof(stream_block)); -++ mbedtls_aes_free(&ctx); -++ return ret; -++} -++ -++int aes_128_ctr_encrypt(const u8 *key, const u8 *nonce, -++ u8 *data, size_t data_len) -++{ -++ return aes_ctr_encrypt(key, 16, nonce, data, data_len); -++} -++ -++ -++/* aes-cbc.c */ -++static int aes_128_cbc_oper(const u8 *key, const u8 *iv, -++ u8 *data, size_t data_len, int mode) -++{ -++ unsigned char ivec[MBEDTLS_AES_BLOCK_SIZE]; -++ os_memcpy(ivec, iv, MBEDTLS_AES_BLOCK_SIZE); /*(must be writable)*/ -++ -++ mbedtls_aes_context ctx; -++ mbedtls_aes_init(&ctx); -++ int ret = (mode == MBEDTLS_AES_ENCRYPT -++ ? mbedtls_aes_setkey_enc(&ctx, key, 128) -++ : mbedtls_aes_setkey_dec(&ctx, key, 128)) -++ || mbedtls_aes_crypt_cbc(&ctx, mode, data_len, ivec, data, data); -++ mbedtls_aes_free(&ctx); -++ return ret ? -1 : 0; -++} -++ -++int aes_128_cbc_encrypt(const u8 *key, const u8 *iv, u8 *data, size_t data_len) -++{ -++ return aes_128_cbc_oper(key, iv, data, data_len, MBEDTLS_AES_ENCRYPT); -++} -++ -++int aes_128_cbc_decrypt(const u8 *key, const u8 *iv, u8 *data, size_t data_len) -++{ -++ return aes_128_cbc_oper(key, iv, data, data_len, MBEDTLS_AES_DECRYPT); -++} -++ -++ -++/* -++ * Much of the following is documented in crypto.h as for CONFIG_TLS=internal -++ * but such comments are not accurate: -++ * -++ * "This function is only used with internal TLSv1 implementation -++ * (CONFIG_TLS=internal). If that is not used, the crypto wrapper does not need -++ * to implement this." -++ */ -++ -++ -++#ifdef CRYPTO_MBEDTLS_CRYPTO_CIPHER -++ -++#include -++ -++struct crypto_cipher -++{ -++ mbedtls_cipher_context_t ctx_enc; -++ mbedtls_cipher_context_t ctx_dec; -++}; -++ -++struct crypto_cipher * crypto_cipher_init(enum crypto_cipher_alg alg, -++ const u8 *iv, const u8 *key, -++ size_t key_len) -++{ -++ /* IKEv2 src/eap_common/ikev2_common.c:ikev2_{encr,decr}_encrypt() -++ * uses one of CRYPTO_CIPHER_ALG_AES or CRYPTO_CIPHER_ALG_3DES */ -++ -++ mbedtls_cipher_type_t cipher_type; -++ size_t iv_len; -++ switch (alg) { -++ #ifdef MBEDTLS_ARC4_C -++ #if 0 -++ case CRYPTO_CIPHER_ALG_RC4: -++ cipher_type = MBEDTLS_CIPHER_ARC4_128; -++ iv_len = 0; -++ break; -++ #endif -++ #endif -++ #ifdef MBEDTLS_AES_C -++ case CRYPTO_CIPHER_ALG_AES: -++ if (key_len == 16) cipher_type = MBEDTLS_CIPHER_AES_128_CTR; -++ if (key_len == 24) cipher_type = MBEDTLS_CIPHER_AES_192_CTR; -++ if (key_len == 32) cipher_type = MBEDTLS_CIPHER_AES_256_CTR; -++ iv_len = 16; -++ break; -++ #endif -++ #ifdef MBEDTLS_DES_C -++ case CRYPTO_CIPHER_ALG_3DES: -++ cipher_type = MBEDTLS_CIPHER_DES_EDE3_CBC; -++ iv_len = 8; -++ break; -++ #if 0 -++ case CRYPTO_CIPHER_ALG_DES: -++ cipher_type = MBEDTLS_CIPHER_DES_CBC; -++ iv_len = 8; -++ break; -++ #endif -++ #endif -++ default: -++ return NULL; -++ } -++ -++ const mbedtls_cipher_info_t *cipher_info; -++ cipher_info = mbedtls_cipher_info_from_type(cipher_type); -++ if (cipher_info == NULL) -++ return NULL; -++ -++ key_len *= 8; /* key_bitlen */ -++ #if 0 /*(were key_bitlen not already available)*/ -++ #if MBEDTLS_VERSION_NUMBER >= 0x03010000 /* mbedtls 3.1.0 */ -++ key_len = mbedtls_cipher_info_get_key_bitlen(cipher_info); -++ #else -++ key_len = cipher_info->MBEDTLS_PRIVATE(key_bitlen); -++ #endif -++ #endif -++ -++ #if 0 /*(were iv_len not known above, would need MBEDTLS_PRIVATE(iv_size))*/ -++ iv_len = cipher_info->MBEDTLS_PRIVATE(iv_size); -++ #endif -++ -++ struct crypto_cipher *ctx = os_malloc(sizeof(*ctx)); -++ if (!ctx) -++ return NULL; -++ -++ mbedtls_cipher_init(&ctx->ctx_enc); -++ mbedtls_cipher_init(&ctx->ctx_dec); -++ if ( mbedtls_cipher_setup(&ctx->ctx_enc,cipher_info) == 0 -++ && mbedtls_cipher_setup(&ctx->ctx_dec,cipher_info) == 0 -++ && mbedtls_cipher_setkey(&ctx->ctx_enc,key,key_len,MBEDTLS_ENCRYPT) == 0 -++ && mbedtls_cipher_setkey(&ctx->ctx_dec,key,key_len,MBEDTLS_DECRYPT) == 0 -++ && mbedtls_cipher_set_iv(&ctx->ctx_enc,iv,iv_len) == 0 -++ && mbedtls_cipher_set_iv(&ctx->ctx_dec,iv,iv_len) == 0 -++ && mbedtls_cipher_reset(&ctx->ctx_enc) == 0 -++ && mbedtls_cipher_reset(&ctx->ctx_dec) == 0) { -++ return ctx; -++ } -++ -++ mbedtls_cipher_free(&ctx->ctx_enc); -++ mbedtls_cipher_free(&ctx->ctx_dec); -++ os_free(ctx); -++ return NULL; -++} -++ -++int crypto_cipher_encrypt(struct crypto_cipher *ctx, -++ const u8 *plain, u8 *crypt, size_t len) -++{ -++ size_t olen = 0; /*(poor interface above; unknown size of u8 *crypt)*/ -++ return (mbedtls_cipher_update(&ctx->ctx_enc, plain, len, crypt, &olen) -++ || mbedtls_cipher_finish(&ctx->ctx_enc, crypt + olen, &olen)) ? -1 : 0; -++} -++ -++int crypto_cipher_decrypt(struct crypto_cipher *ctx, -++ const u8 *crypt, u8 *plain, size_t len) -++{ -++ size_t olen = 0; /*(poor interface above; unknown size of u8 *plain)*/ -++ return (mbedtls_cipher_update(&ctx->ctx_dec, crypt, len, plain, &olen) -++ || mbedtls_cipher_finish(&ctx->ctx_dec, plain + olen, &olen)) ? -1 : 0; -++} -++ -++void crypto_cipher_deinit(struct crypto_cipher *ctx) -++{ -++ mbedtls_cipher_free(&ctx->ctx_enc); -++ mbedtls_cipher_free(&ctx->ctx_dec); -++ os_free(ctx); -++} -++ -++#endif /* CRYPTO_MBEDTLS_CRYPTO_CIPHER */ -++ -++ -++#ifdef CRYPTO_MBEDTLS_CRYPTO_HASH -++ -++struct crypto_hash * crypto_hash_init(enum crypto_hash_alg alg, const u8 *key, -++ size_t key_len) -++{ -++ mbedtls_md_type_t md_type; -++ int is_hmac = 0; -++ -++ switch (alg) { -++ #ifdef MBEDTLS_MD5_C -++ case CRYPTO_HASH_ALG_MD5: -++ md_type = MBEDTLS_MD_MD5; -++ break; -++ #endif -++ #ifdef MBEDTLS_SHA1_C -++ case CRYPTO_HASH_ALG_SHA1: -++ md_type = MBEDTLS_MD_SHA1; -++ break; -++ #endif -++ #ifdef MBEDTLS_MD5_C -++ case CRYPTO_HASH_ALG_HMAC_MD5: -++ md_type = MBEDTLS_MD_MD5; -++ is_hmac = 1; -++ break; -++ #endif -++ #ifdef MBEDTLS_SHA1_C -++ case CRYPTO_HASH_ALG_HMAC_SHA1: -++ md_type = MBEDTLS_MD_SHA1; -++ is_hmac = 1; -++ break; -++ #endif -++ #ifdef MBEDTLS_SHA256_C -++ case CRYPTO_HASH_ALG_SHA256: -++ md_type = MBEDTLS_MD_SHA256; -++ break; -++ case CRYPTO_HASH_ALG_HMAC_SHA256: -++ md_type = MBEDTLS_MD_SHA256; -++ is_hmac = 1; -++ break; -++ #endif -++ #ifdef MBEDTLS_SHA512_C -++ case CRYPTO_HASH_ALG_SHA384: -++ md_type = MBEDTLS_MD_SHA384; -++ break; -++ case CRYPTO_HASH_ALG_SHA512: -++ md_type = MBEDTLS_MD_SHA512; -++ break; -++ #endif -++ default: -++ return NULL; -++ } -++ -++ const mbedtls_md_info_t *md_info = mbedtls_md_info_from_type(md_type); -++ if (!md_info) -++ return NULL; -++ -++ mbedtls_md_context_t *mctx = os_malloc(sizeof(*mctx)); -++ if (mctx == NULL) -++ return NULL; -++ -++ mbedtls_md_init(mctx); -++ if (mbedtls_md_setup(mctx, md_info, is_hmac) != 0) { -++ os_free(mctx); -++ return NULL; -++ } -++ -++ if (is_hmac) -++ mbedtls_md_hmac_starts(mctx, key, key_len); -++ else -++ mbedtls_md_starts(mctx); -++ return (struct crypto_hash *)((uintptr_t)mctx | is_hmac); -++} -++ -++void crypto_hash_update(struct crypto_hash *ctx, const u8 *data, size_t len) -++{ -++ mbedtls_md_context_t *mctx = (mbedtls_md_context_t*)((uintptr_t)ctx & ~1uL); -++ #if 0 -++ /*(mbedtls_md_hmac_update() and mbedtls_md_update() -++ * make same modifications under the hood in mbedtls)*/ -++ if ((uintptr_t)ctx & 1uL) -++ mbedtls_md_hmac_update(mctx, data, len); -++ else -++ #endif -++ mbedtls_md_update(mctx, data, len); -++} -++ -++int crypto_hash_finish(struct crypto_hash *ctx, u8 *mac, size_t *len) -++{ -++ mbedtls_md_context_t *mctx = (mbedtls_md_context_t*)((uintptr_t)ctx & ~1uL); -++ if (mac != NULL && len != NULL) { /*(NULL if caller just freeing context)*/ -++ #if MBEDTLS_VERSION_NUMBER >= 0x03020000 /* mbedtls 3.2.0 */ -++ const mbedtls_md_info_t *md_info = mbedtls_md_info_from_ctx(mctx); -++ #else -++ const mbedtls_md_info_t *md_info = mctx->MBEDTLS_PRIVATE(md_info); -++ #endif -++ size_t maclen = mbedtls_md_get_size(md_info); -++ if (*len < maclen) { -++ *len = maclen; -++ /*(note: ctx not freed; can call again with larger *len)*/ -++ return -1; -++ } -++ *len = maclen; -++ if ((uintptr_t)ctx & 1uL) -++ mbedtls_md_hmac_finish(mctx, mac); -++ else -++ mbedtls_md_finish(mctx, mac); -++ } -++ mbedtls_md_free(mctx); -++ os_free(mctx); -++ return 0; -++} -++ -++#endif /* CRYPTO_MBEDTLS_CRYPTO_HASH */ -++ -++ -++#ifdef CRYPTO_MBEDTLS_CRYPTO_BIGNUM -++ -++#include -++ -++/* crypto.h bignum interfaces */ -++ -++struct crypto_bignum *crypto_bignum_init(void) -++{ -++ mbedtls_mpi *bn = os_malloc(sizeof(*bn)); -++ if (bn) -++ mbedtls_mpi_init(bn); -++ return (struct crypto_bignum *)bn; -++} -++ -++struct crypto_bignum *crypto_bignum_init_set(const u8 *buf, size_t len) -++{ -++ mbedtls_mpi *bn = os_malloc(sizeof(*bn)); -++ if (bn) { -++ mbedtls_mpi_init(bn); -++ if (mbedtls_mpi_read_binary(bn, buf, len) == 0) -++ return (struct crypto_bignum *)bn; -++ } -++ -++ os_free(bn); -++ return NULL; -++} -++ -++struct crypto_bignum *crypto_bignum_init_uint(unsigned int val) -++{ -++ #if 0 /*(hostap use of this interface passes int, not uint)*/ -++ val = host_to_be32(val); -++ return crypto_bignum_init_set((const u8 *)&val, sizeof(val)); -++ #else -++ mbedtls_mpi *bn = os_malloc(sizeof(*bn)); -++ if (bn) { -++ mbedtls_mpi_init(bn); -++ if (mbedtls_mpi_lset(bn, (int)val) == 0) -++ return (struct crypto_bignum *)bn; -++ } -++ -++ os_free(bn); -++ return NULL; -++ #endif -++} -++ -++void crypto_bignum_deinit(struct crypto_bignum *n, int clear) -++{ -++ mbedtls_mpi_free((mbedtls_mpi *)n); -++ os_free(n); -++} -++ -++int crypto_bignum_to_bin(const struct crypto_bignum *a, -++ u8 *buf, size_t buflen, size_t padlen) -++{ -++ size_t n = mbedtls_mpi_size((mbedtls_mpi *)a); -++ if (n < padlen) -++ n = padlen; -++ return n > buflen || mbedtls_mpi_write_binary((mbedtls_mpi *)a, buf, n) -++ ? -1 -++ : (int)(n); -++} -++ -++int crypto_bignum_rand(struct crypto_bignum *r, const struct crypto_bignum *m) -++{ -++ /*assert(r != m);*//* r must not be same as m for mbedtls_mpi_random()*/ -++ #if MBEDTLS_VERSION_NUMBER >= 0x021B0000 /* mbedtls 2.27.0 */ -++ return mbedtls_mpi_random((mbedtls_mpi *)r, 0, (mbedtls_mpi *)m, -++ mbedtls_ctr_drbg_random, -++ crypto_mbedtls_ctr_drbg()) ? -1 : 0; -++ #else -++ /* (needed by EAP_PWD, SAE, DPP) */ -++ wpa_printf(MSG_ERROR, -++ "mbedtls 2.27.0 or later required for mbedtls_mpi_random()"); -++ return -1; -++ #endif -++} -++ -++int crypto_bignum_add(const struct crypto_bignum *a, -++ const struct crypto_bignum *b, -++ struct crypto_bignum *c) -++{ -++ return mbedtls_mpi_add_mpi((mbedtls_mpi *)c, -++ (const mbedtls_mpi *)a, -++ (const mbedtls_mpi *)b) ? -1 : 0; -++} -++ -++int crypto_bignum_mod(const struct crypto_bignum *a, -++ const struct crypto_bignum *b, -++ struct crypto_bignum *c) -++{ -++ return mbedtls_mpi_mod_mpi((mbedtls_mpi *)c, -++ (const mbedtls_mpi *)a, -++ (const mbedtls_mpi *)b) ? -1 : 0; -++} -++ -++int crypto_bignum_exptmod(const struct crypto_bignum *a, -++ const struct crypto_bignum *b, -++ const struct crypto_bignum *c, -++ struct crypto_bignum *d) -++{ -++ /* (check if input params match d; d is the result) */ -++ /* (a == d) is ok in current mbedtls implementation */ -++ if (b == d || c == d) { /*(not ok; store result in intermediate)*/ -++ mbedtls_mpi R; -++ mbedtls_mpi_init(&R); -++ int rc = mbedtls_mpi_exp_mod(&R, -++ (const mbedtls_mpi *)a, -++ (const mbedtls_mpi *)b, -++ (const mbedtls_mpi *)c, -++ NULL) -++ || mbedtls_mpi_copy((mbedtls_mpi *)d, &R) ? -1 : 0; -++ mbedtls_mpi_free(&R); -++ return rc; -++ } -++ else { -++ return mbedtls_mpi_exp_mod((mbedtls_mpi *)d, -++ (const mbedtls_mpi *)a, -++ (const mbedtls_mpi *)b, -++ (const mbedtls_mpi *)c, -++ NULL) ? -1 : 0; -++ } -++} -++ -++int crypto_bignum_inverse(const struct crypto_bignum *a, -++ const struct crypto_bignum *b, -++ struct crypto_bignum *c) -++{ -++ return mbedtls_mpi_inv_mod((mbedtls_mpi *)c, -++ (const mbedtls_mpi *)a, -++ (const mbedtls_mpi *)b) ? -1 : 0; -++} -++ -++int crypto_bignum_sub(const struct crypto_bignum *a, -++ const struct crypto_bignum *b, -++ struct crypto_bignum *c) -++{ -++ return mbedtls_mpi_sub_mpi((mbedtls_mpi *)c, -++ (const mbedtls_mpi *)a, -++ (const mbedtls_mpi *)b) ? -1 : 0; -++} -++ -++int crypto_bignum_div(const struct crypto_bignum *a, -++ const struct crypto_bignum *b, -++ struct crypto_bignum *c) -++{ -++ /*(most current use of this crypto.h interface has a == c (result), -++ * so store result in an intermediate to avoid overwritten input)*/ -++ mbedtls_mpi R; -++ mbedtls_mpi_init(&R); -++ int rc = mbedtls_mpi_div_mpi(&R, NULL, -++ (const mbedtls_mpi *)a, -++ (const mbedtls_mpi *)b) -++ || mbedtls_mpi_copy((mbedtls_mpi *)c, &R) ? -1 : 0; -++ mbedtls_mpi_free(&R); -++ return rc; -++} -++ -++int crypto_bignum_addmod(const struct crypto_bignum *a, -++ const struct crypto_bignum *b, -++ const struct crypto_bignum *c, -++ struct crypto_bignum *d) -++{ -++ return mbedtls_mpi_add_mpi((mbedtls_mpi *)d, -++ (const mbedtls_mpi *)a, -++ (const mbedtls_mpi *)b) -++ || mbedtls_mpi_mod_mpi((mbedtls_mpi *)d, -++ (mbedtls_mpi *)d, -++ (const mbedtls_mpi *)c) ? -1 : 0; -++} -++ -++int crypto_bignum_mulmod(const struct crypto_bignum *a, -++ const struct crypto_bignum *b, -++ const struct crypto_bignum *c, -++ struct crypto_bignum *d) -++{ -++ return mbedtls_mpi_mul_mpi((mbedtls_mpi *)d, -++ (const mbedtls_mpi *)a, -++ (const mbedtls_mpi *)b) -++ || mbedtls_mpi_mod_mpi((mbedtls_mpi *)d, -++ (mbedtls_mpi *)d, -++ (const mbedtls_mpi *)c) ? -1 : 0; -++} -++ -++int crypto_bignum_sqrmod(const struct crypto_bignum *a, -++ const struct crypto_bignum *b, -++ struct crypto_bignum *c) -++{ -++ #if 1 -++ return crypto_bignum_mulmod(a, a, b, c); -++ #else -++ mbedtls_mpi bn; -++ mbedtls_mpi_init(&bn); -++ if (mbedtls_mpi_lset(&bn, 2)) /* alt?: mbedtls_mpi_set_bit(&bn, 1) */ -++ return -1; -++ int ret = mbedtls_mpi_exp_mod((mbedtls_mpi *)c, -++ (const mbedtls_mpi *)a, &bn, -++ (const mbedtls_mpi *)b, NULL) ? -1 : 0; -++ mbedtls_mpi_free(&bn); -++ return ret; -++ #endif -++} -++ -++int crypto_bignum_rshift(const struct crypto_bignum *a, int n, -++ struct crypto_bignum *r) -++{ -++ return mbedtls_mpi_copy((mbedtls_mpi *)r, (const mbedtls_mpi *)a) -++ || mbedtls_mpi_shift_r((mbedtls_mpi *)r, n) ? -1 : 0; -++} -++ -++int crypto_bignum_cmp(const struct crypto_bignum *a, -++ const struct crypto_bignum *b) -++{ -++ return mbedtls_mpi_cmp_mpi((const mbedtls_mpi *)a, (const mbedtls_mpi *)b); -++} -++ -++int crypto_bignum_is_zero(const struct crypto_bignum *a) -++{ -++ /* XXX: src/common/sae.c:sswu() contains comment: -++ * "TODO: Make sure crypto_bignum_is_zero() is constant time" -++ * Note: mbedtls_mpi_cmp_int() *is not* constant time */ -++ return (mbedtls_mpi_cmp_int((const mbedtls_mpi *)a, 0) == 0); -++} -++ -++int crypto_bignum_is_one(const struct crypto_bignum *a) -++{ -++ return (mbedtls_mpi_cmp_int((const mbedtls_mpi *)a, 1) == 0); -++} -++ -++int crypto_bignum_is_odd(const struct crypto_bignum *a) -++{ -++ return mbedtls_mpi_get_bit((const mbedtls_mpi *)a, 0); -++} -++ -++#include "utils/const_time.h" -++int crypto_bignum_legendre(const struct crypto_bignum *a, -++ const struct crypto_bignum *p) -++{ -++ /* Security Note: -++ * mbedtls_mpi_exp_mod() is not documented to run in constant time, -++ * though mbedtls/library/bignum.c uses constant_time_internal.h funcs. -++ * Compare to crypto_openssl.c:crypto_bignum_legendre() -++ * which uses openssl BN_mod_exp_mont_consttime() -++ * mbedtls/library/ecp.c has further countermeasures to timing attacks, -++ * (but ecp.c funcs are not used here) */ -++ -++ mbedtls_mpi exp, tmp; -++ mbedtls_mpi_init(&exp); -++ mbedtls_mpi_init(&tmp); -++ -++ /* exp = (p-1) / 2 */ -++ int res; -++ if (mbedtls_mpi_sub_int(&exp, (const mbedtls_mpi *)p, 1) == 0 -++ && mbedtls_mpi_shift_r(&exp, 1) == 0 -++ && mbedtls_mpi_exp_mod(&tmp, (const mbedtls_mpi *)a, &exp, -++ (const mbedtls_mpi *)p, NULL) == 0) { -++ /*(modified from crypto_openssl.c:crypto_bignum_legendre())*/ -++ /* Return 1 if tmp == 1, 0 if tmp == 0, or -1 otherwise. Need -++ * to use constant time selection to avoid branches here. */ -++ unsigned int mask; -++ res = -1; -++ mask = const_time_eq((mbedtls_mpi_cmp_int(&tmp, 1) == 0), 1); -++ res = const_time_select_int(mask, 1, res); -++ mask = const_time_eq((mbedtls_mpi_cmp_int(&tmp, 0) == 0), 1); -++ res = const_time_select_int(mask, 0, res); -++ } else { -++ res = -2; -++ } -++ -++ mbedtls_mpi_free(&tmp); -++ mbedtls_mpi_free(&exp); -++ return res; -++} -++ -++#endif /* CRYPTO_MBEDTLS_CRYPTO_BIGNUM */ -++ -++ -++#ifdef CRYPTO_MBEDTLS_CRYPTO_DH -++ -++/* crypto_internal-modexp.c */ -++ -++#include -++#include -++ -++#if 0 /* crypto_dh_init() and crypto_dh_derive_secret() prefer to use mbedtls */ -++int crypto_mod_exp(const u8 *base, size_t base_len, -++ const u8 *power, size_t power_len, -++ const u8 *modulus, size_t modulus_len, -++ u8 *result, size_t *result_len) -++{ -++ mbedtls_mpi bn_base, bn_exp, bn_modulus, bn_result; -++ mbedtls_mpi_init(&bn_base); -++ mbedtls_mpi_init(&bn_exp); -++ mbedtls_mpi_init(&bn_modulus); -++ mbedtls_mpi_init(&bn_result); -++ -++ size_t len; -++ int ret = mbedtls_mpi_read_binary(&bn_base, base, base_len) -++ || mbedtls_mpi_read_binary(&bn_exp, power, power_len) -++ || mbedtls_mpi_read_binary(&bn_modulus, modulus, modulus_len) -++ || mbedtls_mpi_exp_mod(&bn_result,&bn_base,&bn_exp,&bn_modulus,NULL) -++ || (len = mbedtls_mpi_size(&bn_result)) > *result_len -++ || mbedtls_mpi_write_binary(&bn_result, result, (*result_len = len)) -++ ? -1 -++ : 0; -++ -++ mbedtls_mpi_free(&bn_base); -++ mbedtls_mpi_free(&bn_exp); -++ mbedtls_mpi_free(&bn_modulus); -++ mbedtls_mpi_free(&bn_result); -++ return ret; -++} -++#endif -++ -++static int crypto_mbedtls_dh_set_bin_pg(mbedtls_dhm_context *ctx, u8 generator, -++ const u8 *prime, size_t prime_len) -++{ -++ /*(could set these directly in MBEDTLS_PRIVATE members)*/ -++ mbedtls_mpi P, G; -++ mbedtls_mpi_init(&P); -++ mbedtls_mpi_init(&G); -++ int ret = mbedtls_mpi_lset(&G, generator) -++ || mbedtls_mpi_read_binary(&P, prime, prime_len) -++ || mbedtls_dhm_set_group(ctx, &P, &G); -++ mbedtls_mpi_free(&P); -++ mbedtls_mpi_free(&G); -++ return ret; -++} -++ -++__attribute_noinline__ -++static int crypto_mbedtls_dh_init_public(mbedtls_dhm_context *ctx, u8 generator, -++ const u8 *prime, size_t prime_len, -++ u8 *privkey, u8 *pubkey) -++{ -++ if (crypto_mbedtls_dh_set_bin_pg(ctx, generator, prime, prime_len) -++ || mbedtls_dhm_make_public(ctx, (int)prime_len, pubkey, prime_len, -++ mbedtls_ctr_drbg_random, -++ crypto_mbedtls_ctr_drbg())) -++ return -1; -++ -++ /*(enable later when upstream mbedtls interface changes require)*/ -++ #if 0 && MBEDTLS_VERSION_NUMBER >= 0x03000000 /* mbedtls 3.0.0 */ -++ mbedtls_mpi X; -++ mbedtls_mpi_init(&X); -++ int ret = mbedtls_dhm_get_value(ctx, MBEDTLS_DHM_PARAM_X, &X) -++ || mbedtls_mpi_write_binary(&X, privkey, prime_len) ? -1 : 0; -++ mbedtls_mpi_free(&X); -++ return ret; -++ #else -++ return mbedtls_mpi_write_binary(&ctx->MBEDTLS_PRIVATE(X), -++ privkey, prime_len) ? -1 : 0; -++ #endif -++} -++ -++int crypto_dh_init(u8 generator, const u8 *prime, size_t prime_len, u8 *privkey, -++ u8 *pubkey) -++{ -++ #if 0 /*(crypto_dh_init() duplicated (and identical) in crypto_*.c modules)*/ -++ size_t pubkey_len, pad; -++ -++ if (os_get_random(privkey, prime_len) < 0) -++ return -1; -++ if (os_memcmp(privkey, prime, prime_len) > 0) { -++ /* Make sure private value is smaller than prime */ -++ privkey[0] = 0; -++ } -++ -++ pubkey_len = prime_len; -++ if (crypto_mod_exp(&generator, 1, privkey, prime_len, prime, prime_len, -++ pubkey, &pubkey_len) < 0) -++ return -1; -++ if (pubkey_len < prime_len) { -++ pad = prime_len - pubkey_len; -++ os_memmove(pubkey + pad, pubkey, pubkey_len); -++ os_memset(pubkey, 0, pad); -++ } -++ -++ return 0; -++ #else -++ /* Prefer to use mbedtls to derive our public/private key, as doing so -++ * leverages mbedtls to properly format output and to perform blinding*/ -++ mbedtls_dhm_context ctx; -++ mbedtls_dhm_init(&ctx); -++ int ret = crypto_mbedtls_dh_init_public(&ctx, generator, prime, -++ prime_len, privkey, pubkey); -++ mbedtls_dhm_free(&ctx); -++ return ret; -++ #endif -++} -++ -++/*(crypto_dh_derive_secret() could be implemented using crypto.h APIs -++ * instead of being reimplemented in each crypto_*.c)*/ -++int crypto_dh_derive_secret(u8 generator, const u8 *prime, size_t prime_len, -++ const u8 *order, size_t order_len, -++ const u8 *privkey, size_t privkey_len, -++ const u8 *pubkey, size_t pubkey_len, -++ u8 *secret, size_t *len) -++{ -++ #if 0 -++ if (pubkey_len > prime_len || -++ (pubkey_len == prime_len && -++ os_memcmp(pubkey, prime, prime_len) >= 0)) -++ return -1; -++ -++ int res = 0; -++ mbedtls_mpi pub; -++ mbedtls_mpi_init(&pub); -++ if (mbedtls_mpi_read_binary(&pub, pubkey, pubkey_len) -++ || mbedtls_mpi_cmp_int(&pub, 1) <= 0) { -++ res = -1; -++ } else if (order) { -++ mbedtls_mpi p, q, tmp; -++ mbedtls_mpi_init(&p); -++ mbedtls_mpi_init(&q); -++ mbedtls_mpi_init(&tmp); -++ -++ /* verify: pubkey^q == 1 mod p */ -++ res = (mbedtls_mpi_read_binary(&p, prime, prime_len) -++ || mbedtls_mpi_read_binary(&q, order, order_len) -++ || mbedtls_mpi_exp_mod(&tmp, &pub, &q, &p, NULL) -++ || mbedtls_mpi_cmp_int(&tmp, 1) != 0); -++ -++ mbedtls_mpi_free(&p); -++ mbedtls_mpi_free(&q); -++ mbedtls_mpi_free(&tmp); -++ } -++ mbedtls_mpi_free(&pub); -++ -++ return (res == 0) -++ ? crypto_mod_exp(pubkey, pubkey_len, privkey, privkey_len, -++ prime, prime_len, secret, len) -++ : -1; -++ #else -++ /* Prefer to use mbedtls to derive DH shared secret, as doing so -++ * leverages mbedtls to validate params and to perform blinding. -++ * -++ * Attempt to reconstitute DH context to derive shared secret -++ * (due to limitations of the interface, which ought to pass context). -++ * Force provided G (our private key) into context without validation. -++ * Regenerating GX (our public key) not needed to derive shared secret. -++ */ -++ /*(older compilers might not support VLAs)*/ -++ /*unsigned char buf[2+prime_len+2+1+2+pubkey_len];*/ -++ unsigned char buf[2+MBEDTLS_MPI_MAX_SIZE+2+1+2+MBEDTLS_MPI_MAX_SIZE]; -++ unsigned char *p = buf + 2 + prime_len; -++ if (2+prime_len+2+1+2+pubkey_len > sizeof(buf)) -++ return -1; -++ WPA_PUT_BE16(buf, prime_len); /*(2-byte big-endian size of prime)*/ -++ p[0] = 0; /*(2-byte big-endian size of generator)*/ -++ p[1] = 1; -++ p[2] = generator; -++ WPA_PUT_BE16(p+3, pubkey_len); /*(2-byte big-endian size of pubkey)*/ -++ os_memcpy(p+5, pubkey, pubkey_len); -++ os_memcpy(buf+2, prime, prime_len); -++ -++ mbedtls_dhm_context ctx; -++ mbedtls_dhm_init(&ctx); -++ p = buf; -++ int ret = mbedtls_dhm_read_params(&ctx, &p, p+2+prime_len+5+pubkey_len) -++ || mbedtls_mpi_read_binary(&ctx.MBEDTLS_PRIVATE(X), -++ privkey, privkey_len) -++ || mbedtls_dhm_calc_secret(&ctx, secret, *len, len, -++ mbedtls_ctr_drbg_random, -++ crypto_mbedtls_ctr_drbg()) ? -1 : 0; -++ mbedtls_dhm_free(&ctx); -++ return ret; -++ #endif -++} -++ -++/* dh_group5.c */ -++ -++#include "dh_group5.h" -++ -++/* RFC3526_PRIME_1536[] and RFC3526_GENERATOR_1536[] from crypto_wolfssl.c */ -++ -++static const unsigned char RFC3526_PRIME_1536[] = { -++ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xC9, 0x0F, 0xDA, 0xA2, -++ 0x21, 0x68, 0xC2, 0x34, 0xC4, 0xC6, 0x62, 0x8B, 0x80, 0xDC, 0x1C, 0xD1, -++ 0x29, 0x02, 0x4E, 0x08, 0x8A, 0x67, 0xCC, 0x74, 0x02, 0x0B, 0xBE, 0xA6, -++ 0x3B, 0x13, 0x9B, 0x22, 0x51, 0x4A, 0x08, 0x79, 0x8E, 0x34, 0x04, 0xDD, -++ 0xEF, 0x95, 0x19, 0xB3, 0xCD, 0x3A, 0x43, 0x1B, 0x30, 0x2B, 0x0A, 0x6D, -++ 0xF2, 0x5F, 0x14, 0x37, 0x4F, 0xE1, 0x35, 0x6D, 0x6D, 0x51, 0xC2, 0x45, -++ 0xE4, 0x85, 0xB5, 0x76, 0x62, 0x5E, 0x7E, 0xC6, 0xF4, 0x4C, 0x42, 0xE9, -++ 0xA6, 0x37, 0xED, 0x6B, 0x0B, 0xFF, 0x5C, 0xB6, 0xF4, 0x06, 0xB7, 0xED, -++ 0xEE, 0x38, 0x6B, 0xFB, 0x5A, 0x89, 0x9F, 0xA5, 0xAE, 0x9F, 0x24, 0x11, -++ 0x7C, 0x4B, 0x1F, 0xE6, 0x49, 0x28, 0x66, 0x51, 0xEC, 0xE4, 0x5B, 0x3D, -++ 0xC2, 0x00, 0x7C, 0xB8, 0xA1, 0x63, 0xBF, 0x05, 0x98, 0xDA, 0x48, 0x36, -++ 0x1C, 0x55, 0xD3, 0x9A, 0x69, 0x16, 0x3F, 0xA8, 0xFD, 0x24, 0xCF, 0x5F, -++ 0x83, 0x65, 0x5D, 0x23, 0xDC, 0xA3, 0xAD, 0x96, 0x1C, 0x62, 0xF3, 0x56, -++ 0x20, 0x85, 0x52, 0xBB, 0x9E, 0xD5, 0x29, 0x07, 0x70, 0x96, 0x96, 0x6D, -++ 0x67, 0x0C, 0x35, 0x4E, 0x4A, 0xBC, 0x98, 0x04, 0xF1, 0x74, 0x6C, 0x08, -++ 0xCA, 0x23, 0x73, 0x27, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF -++}; -++ -++static const unsigned char RFC3526_GENERATOR_1536[] = { -++ 0x02 -++}; -++ -++void * dh5_init(struct wpabuf **priv, struct wpabuf **publ) -++{ -++ const unsigned char * const prime = RFC3526_PRIME_1536; -++ const size_t prime_len = sizeof(RFC3526_PRIME_1536); -++ const u8 generator = *RFC3526_GENERATOR_1536; -++ struct wpabuf *wpubl = NULL, *wpriv = NULL; -++ -++ mbedtls_dhm_context *ctx = os_malloc(sizeof(*ctx)); -++ if (ctx == NULL) -++ return NULL; -++ mbedtls_dhm_init(ctx); -++ -++ if ( (wpubl = wpabuf_alloc(prime_len)) -++ && (wpriv = wpabuf_alloc(prime_len)) -++ && crypto_mbedtls_dh_init_public(ctx, generator, prime, prime_len, -++ wpabuf_put(wpriv, prime_len), -++ wpabuf_put(wpubl, prime_len))==0) { -++ wpabuf_free(*publ); -++ wpabuf_clear_free(*priv); -++ *publ = wpubl; -++ *priv = wpriv; -++ return ctx; -++ } -++ -++ wpabuf_clear_free(wpriv); -++ wpabuf_free(wpubl); -++ mbedtls_dhm_free(ctx); -++ os_free(ctx); -++ return NULL; -++} -++ -++#ifdef CRYPTO_MBEDTLS_DH5_INIT_FIXED -++void * dh5_init_fixed(const struct wpabuf *priv, const struct wpabuf *publ) -++{ -++ const unsigned char * const prime = RFC3526_PRIME_1536; -++ const size_t prime_len = sizeof(RFC3526_PRIME_1536); -++ const u8 generator = *RFC3526_GENERATOR_1536; -++ -++ mbedtls_dhm_context *ctx = os_malloc(sizeof(*ctx)); -++ if (ctx == NULL) -++ return NULL; -++ mbedtls_dhm_init(ctx); -++ -++ if (crypto_mbedtls_dh_set_bin_pg(ctx, generator, prime, prime_len)==0 -++ #if 0 /*(ignore; not required to derive shared secret)*/ -++ && mbedtls_mpi_read_binary(&ctx->MBEDTLS_PRIVATE(GX), -++ wpabuf_head(publ),wpabuf_len(publ))==0 -++ #endif -++ && mbedtls_mpi_read_binary(&ctx->MBEDTLS_PRIVATE(X), -++ wpabuf_head(priv),wpabuf_len(priv))==0) { -++ return ctx; -++ } -++ -++ mbedtls_dhm_free(ctx); -++ os_free(ctx); -++ return NULL; -++} -++#endif -++ -++struct wpabuf * dh5_derive_shared(void *ctx, const struct wpabuf *peer_public, -++ const struct wpabuf *own_private) -++{ -++ /*((mbedtls_dhm_context *)ctx must already contain own_private)*/ -++ /* mbedtls 2.x: prime_len = ctx->len; */ -++ /* mbedtls 3.x: prime_len = mbedtls_dhm_get_len(ctx); */ -++ size_t olen = sizeof(RFC3526_PRIME_1536); /*(sizeof(); prime known)*/ -++ struct wpabuf *buf = wpabuf_alloc(olen); -++ if (buf == NULL) -++ return NULL; -++ if (mbedtls_dhm_read_public((mbedtls_dhm_context *)ctx, -++ wpabuf_head(peer_public), -++ wpabuf_len(peer_public)) == 0 -++ && mbedtls_dhm_calc_secret(ctx, wpabuf_mhead(buf), olen, &olen, -++ mbedtls_ctr_drbg_random, -++ crypto_mbedtls_ctr_drbg()) == 0) { -++ wpabuf_put(buf, olen); -++ return buf; -++ } -++ -++ wpabuf_free(buf); -++ return NULL; -++} -++ -++void dh5_free(void *ctx) -++{ -++ mbedtls_dhm_free(ctx); -++ os_free(ctx); -++} -++ -++#endif /* CRYPTO_MBEDTLS_CRYPTO_DH */ -++ -++ -++#if defined(CRYPTO_MBEDTLS_CRYPTO_ECDH) || defined(CRYPTO_MBEDTLS_CRYPTO_EC) -++ -++#include -++ -++#define CRYPTO_EC_pbits(e) (((mbedtls_ecp_group *)(e))->pbits) -++#define CRYPTO_EC_plen(e) ((((mbedtls_ecp_group *)(e))->pbits+7)>>3) -++#define CRYPTO_EC_P(e) (&((mbedtls_ecp_group *)(e))->P) -++#define CRYPTO_EC_N(e) (&((mbedtls_ecp_group *)(e))->N) -++#define CRYPTO_EC_A(e) (&((mbedtls_ecp_group *)(e))->A) -++#define CRYPTO_EC_B(e) (&((mbedtls_ecp_group *)(e))->B) -++#define CRYPTO_EC_G(e) (&((mbedtls_ecp_group *)(e))->G) -++ -++static mbedtls_ecp_group_id crypto_mbedtls_ecp_group_id_from_ike_id(int group) -++{ -++ /* https://www.iana.org/assignments/ikev2-parameters/ikev2-parameters.xhtml */ -++ switch (group) { -++ #ifdef MBEDTLS_ECP_DP_SECP256R1_ENABLED -++ case 19: return MBEDTLS_ECP_DP_SECP256R1; -++ #endif -++ #ifdef MBEDTLS_ECP_DP_SECP384R1_ENABLED -++ case 20: return MBEDTLS_ECP_DP_SECP384R1; -++ #endif -++ #ifdef MBEDTLS_ECP_DP_SECP521R1_ENABLED -++ case 21: return MBEDTLS_ECP_DP_SECP521R1; -++ #endif -++ #ifdef MBEDTLS_ECP_DP_SECP192R1_ENABLED -++ case 25: return MBEDTLS_ECP_DP_SECP192R1; -++ #endif -++ #ifdef MBEDTLS_ECP_DP_SECP224R1_ENABLED -++ case 26: return MBEDTLS_ECP_DP_SECP224R1; -++ #endif -++ #ifdef MBEDTLS_ECP_DP_BP256R1_ENABLED -++ case 28: return MBEDTLS_ECP_DP_BP256R1; -++ #endif -++ #ifdef MBEDTLS_ECP_DP_BP384R1_ENABLED -++ case 29: return MBEDTLS_ECP_DP_BP384R1; -++ #endif -++ #ifdef MBEDTLS_ECP_DP_BP512R1_ENABLED -++ case 30: return MBEDTLS_ECP_DP_BP512R1; -++ #endif -++ #ifdef MBEDTLS_ECP_DP_CURVE25519_ENABLED -++ case 31: return MBEDTLS_ECP_DP_CURVE25519; -++ #endif -++ #ifdef MBEDTLS_ECP_DP_CURVE448_ENABLED -++ case 32: return MBEDTLS_ECP_DP_CURVE448; -++ #endif -++ default: return MBEDTLS_ECP_DP_NONE; -++ } -++} -++ -++#ifdef CRYPTO_MBEDTLS_CRYPTO_EC -++static int crypto_mbedtls_ike_id_from_ecp_group_id(mbedtls_ecp_group_id grp_id) -++{ -++ /* https://www.iana.org/assignments/ikev2-parameters/ikev2-parameters.xhtml */ -++ /*(for crypto_ec_key_group())*/ -++ switch (grp_id) { -++ #ifdef MBEDTLS_ECP_DP_SECP256R1_ENABLED -++ case MBEDTLS_ECP_DP_SECP256R1: return 19; -++ #endif -++ #ifdef MBEDTLS_ECP_DP_SECP384R1_ENABLED -++ case MBEDTLS_ECP_DP_SECP384R1: return 20; -++ #endif -++ #ifdef MBEDTLS_ECP_DP_SECP521R1_ENABLED -++ case MBEDTLS_ECP_DP_SECP521R1: return 21; -++ #endif -++ #ifdef MBEDTLS_ECP_DP_SECP192R1_ENABLED -++ case MBEDTLS_ECP_DP_SECP192R1: return 25; -++ #endif -++ #ifdef MBEDTLS_ECP_DP_SECP224R1_ENABLED -++ case MBEDTLS_ECP_DP_SECP224R1: return 26; -++ #endif -++ #ifdef MBEDTLS_ECP_DP_BP256R1_ENABLED -++ case MBEDTLS_ECP_DP_BP256R1: return 28; -++ #endif -++ #ifdef MBEDTLS_ECP_DP_BP384R1_ENABLED -++ case MBEDTLS_ECP_DP_BP384R1: return 29; -++ #endif -++ #ifdef MBEDTLS_ECP_DP_BP512R1_ENABLED -++ case MBEDTLS_ECP_DP_BP512R1: return 30; -++ #endif -++ #ifdef MBEDTLS_ECP_DP_CURVE25519_ENABLED -++ case MBEDTLS_ECP_DP_CURVE25519: return 31; -++ #endif -++ #ifdef MBEDTLS_ECP_DP_CURVE448_ENABLED -++ case MBEDTLS_ECP_DP_CURVE448: return 32; -++ #endif -++ default: return -1; -++ } -++} -++#endif -++ -++#endif /* CRYPTO_MBEDTLS_CRYPTO_ECDH || CRYPTO_MBEDTLS_CRYPTO_EC */ -++ -++ -++#if defined(CRYPTO_MBEDTLS_CRYPTO_ECDH) || defined(CRYPTO_MBEDTLS_CRYPTO_EC_DPP) -++ -++#include -++#include -++ -++static int crypto_mbedtls_keypair_gen(int group, mbedtls_pk_context *pk) -++{ -++ mbedtls_ecp_group_id grp_id = -++ crypto_mbedtls_ecp_group_id_from_ike_id(group); -++ if (grp_id == MBEDTLS_ECP_DP_NONE) -++ return -1; -++ const mbedtls_pk_info_t *pk_info = -++ mbedtls_pk_info_from_type(MBEDTLS_PK_ECKEY); -++ if (pk_info == NULL) -++ return -1; -++ return mbedtls_pk_setup(pk, pk_info) -++ || mbedtls_ecp_gen_key(grp_id, mbedtls_pk_ec(*pk), -++ mbedtls_ctr_drbg_random, -++ crypto_mbedtls_ctr_drbg()) ? -1 : 0; -++} -++ -++#endif -++ -++ -++#ifdef CRYPTO_MBEDTLS_CRYPTO_ECDH -++ -++#include -++#include -++#include -++#include -++ -++/* wrap mbedtls_ecdh_context for more future-proof direct access to components -++ * (mbedtls_ecdh_context internal implementation may change between releases) -++ * -++ * If mbedtls_pk_context -- specifically underlying mbedtls_ecp_keypair -- -++ * lifetime were guaranteed to be longer than that of mbedtls_ecdh_context, -++ * then mbedtls_pk_context or mbedtls_ecp_keypair could be stored in crypto_ecdh -++ * (or crypto_ec_key could be stored in crypto_ecdh, and crypto_ec_key could -++ * wrap mbedtls_ecp_keypair and components, to avoid MBEDTLS_PRIVATE access) */ -++struct crypto_ecdh { -++ mbedtls_ecdh_context ctx; -++ mbedtls_ecp_group grp; -++ mbedtls_ecp_point Q; -++}; -++ -++struct crypto_ecdh * crypto_ecdh_init(int group) -++{ -++ mbedtls_pk_context pk; -++ mbedtls_pk_init(&pk); -++ struct crypto_ecdh *ecdh = crypto_mbedtls_keypair_gen(group, &pk) == 0 -++ ? crypto_ecdh_init2(group, (struct crypto_ec_key *)&pk) -++ : NULL; -++ mbedtls_pk_free(&pk); -++ return ecdh; -++} -++ -++struct crypto_ecdh * crypto_ecdh_init2(int group, -++ struct crypto_ec_key *own_key) -++{ -++ mbedtls_ecp_group_id grp_id = -++ crypto_mbedtls_ecp_group_id_from_ike_id(group); -++ if (grp_id == MBEDTLS_ECP_DP_NONE) -++ return NULL; -++ mbedtls_ecp_keypair *ecp_kp = mbedtls_pk_ec(*(mbedtls_pk_context *)own_key); -++ struct crypto_ecdh *ecdh = os_malloc(sizeof(*ecdh)); -++ if (ecdh == NULL) -++ return NULL; -++ mbedtls_ecdh_init(&ecdh->ctx); -++ mbedtls_ecp_group_init(&ecdh->grp); -++ mbedtls_ecp_point_init(&ecdh->Q); -++ if (mbedtls_ecdh_setup(&ecdh->ctx, grp_id) == 0 -++ && mbedtls_ecdh_get_params(&ecdh->ctx,ecp_kp,MBEDTLS_ECDH_OURS) == 0) { -++ /* copy grp and Q for later use -++ * (retrieving this info later is more convoluted -++ * even if mbedtls_ecdh_make_public() is considered)*/ -++ #if MBEDTLS_VERSION_NUMBER >= 0x03020000 /* mbedtls 3.2.0 */ -++ mbedtls_mpi d; -++ mbedtls_mpi_init(&d); -++ if (mbedtls_ecp_export(ecp_kp, &ecdh->grp, &d, &ecdh->Q) == 0) { -++ mbedtls_mpi_free(&d); -++ return ecdh; -++ } -++ mbedtls_mpi_free(&d); -++ #else -++ if (mbedtls_ecp_group_load(&ecdh->grp, grp_id) == 0 -++ && mbedtls_ecp_copy(&ecdh->Q, &ecp_kp->MBEDTLS_PRIVATE(Q)) == 0) -++ return ecdh; -++ #endif -++ } -++ -++ mbedtls_ecp_point_free(&ecdh->Q); -++ mbedtls_ecp_group_free(&ecdh->grp); -++ mbedtls_ecdh_free(&ecdh->ctx); -++ os_free(ecdh); -++ return NULL; -++} -++ -++struct wpabuf * crypto_ecdh_get_pubkey(struct crypto_ecdh *ecdh, int inc_y) -++{ -++ mbedtls_ecp_group *grp = &ecdh->grp; -++ size_t len = CRYPTO_EC_plen(grp); -++ #ifdef MBEDTLS_ECP_MONTGOMERY_ENABLED -++ /* len */ -++ #endif -++ #ifdef MBEDTLS_ECP_SHORT_WEIERSTRASS_ENABLED -++ if (mbedtls_ecp_get_type(grp) == MBEDTLS_ECP_TYPE_SHORT_WEIERSTRASS) -++ len = inc_y ? len*2+1 : len+1; -++ #endif -++ struct wpabuf *buf = wpabuf_alloc(len); -++ if (buf == NULL) -++ return NULL; -++ inc_y = inc_y ? MBEDTLS_ECP_PF_UNCOMPRESSED : MBEDTLS_ECP_PF_COMPRESSED; -++ if (mbedtls_ecp_point_write_binary(grp, &ecdh->Q, inc_y, &len, -++ wpabuf_mhead_u8(buf), len) == 0) { -++ wpabuf_put(buf, len); -++ return buf; -++ } -++ -++ wpabuf_free(buf); -++ return NULL; -++} -++ -++#if defined(MBEDTLS_ECP_SHORT_WEIERSTRASS_ENABLED) -++static int crypto_mbedtls_short_weierstrass_derive_y(mbedtls_ecp_group *grp, -++ mbedtls_mpi *bn, -++ int parity_bit) -++{ -++ /* y^2 = x^3 + ax + b -++ * sqrt(w) = w^((p+1)/4) mod p (for prime p where p = 3 mod 4) */ -++ mbedtls_mpi *cy2 = (mbedtls_mpi *) -++ crypto_ec_point_compute_y_sqr((struct crypto_ec *)grp, -++ (const struct crypto_bignum *)bn); /*x*/ -++ if (cy2 == NULL) -++ return -1; -++ -++ /*mbedtls_mpi_free(bn);*/ -++ /*(reuse bn to store result (y))*/ -++ -++ mbedtls_mpi exp; -++ mbedtls_mpi_init(&exp); -++ int ret = mbedtls_mpi_get_bit(&grp->P, 0) != 1 /*(p = 3 mod 4)*/ -++ || mbedtls_mpi_get_bit(&grp->P, 1) != 1 /*(p = 3 mod 4)*/ -++ || mbedtls_mpi_add_int(&exp, &grp->P, 1) -++ || mbedtls_mpi_shift_r(&exp, 2) -++ || mbedtls_mpi_exp_mod(bn, cy2, &exp, &grp->P, NULL) -++ || (mbedtls_mpi_get_bit(bn, 0) != parity_bit -++ && mbedtls_mpi_sub_mpi(bn, &grp->P, bn)); -++ mbedtls_mpi_free(&exp); -++ mbedtls_mpi_free(cy2); -++ os_free(cy2); -++ return ret; -++} -++#endif -++ -++struct wpabuf * crypto_ecdh_set_peerkey(struct crypto_ecdh *ecdh, int inc_y, -++ const u8 *key, size_t len) -++{ -++ if (len == 0) /*(invalid peer key)*/ -++ return NULL; -++ -++ mbedtls_ecp_group *grp = &ecdh->grp; -++ -++ #if defined(MBEDTLS_ECP_SHORT_WEIERSTRASS_ENABLED) -++ if (mbedtls_ecp_get_type(grp) == MBEDTLS_ECP_TYPE_SHORT_WEIERSTRASS) { -++ /* add header for mbedtls_ecdh_read_public() */ -++ u8 buf[256]; -++ if (sizeof(buf)-1 < len) -++ return NULL; -++ buf[0] = (u8)(len); -++ os_memcpy(buf+1, key, len); -++ -++ if (inc_y) { -++ if (!(len & 1)) { /*(dpp code/tests does not include tag?!?)*/ -++ if (sizeof(buf)-2 < len) -++ return NULL; -++ buf[0] = (u8)(1+len); -++ buf[1] = 0x04; -++ os_memcpy(buf+2, key, len); -++ } -++ len >>= 1; /*(repurpose len to prime_len)*/ -++ } -++ else if (key[0] == 0x02 || key[0] == 0x03) { /* (inc_y == 0) */ -++ --len; /*(repurpose len to prime_len)*/ -++ -++ /* mbedtls_ecp_point_read_binary() does not currently support -++ * MBEDTLS_ECP_PF_COMPRESSED format (buf[1] = 0x02 or 0x03) -++ * (returns MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE) */ -++ -++ /* derive y, amend buf[] with y for UNCOMPRESSED format */ -++ if (sizeof(buf)-2 < len*2 || len == 0) -++ return NULL; -++ buf[0] = (u8)(1+len*2); -++ buf[1] = 0x04; -++ mbedtls_mpi bn; -++ mbedtls_mpi_init(&bn); -++ int ret = mbedtls_mpi_read_binary(&bn, key+1, len) -++ || crypto_mbedtls_short_weierstrass_derive_y(grp, &bn, -++ key[0] & 1) -++ || mbedtls_mpi_write_binary(&bn, buf+2+len, len); -++ mbedtls_mpi_free(&bn); -++ if (ret != 0) -++ return NULL; -++ } -++ -++ if (key[0] == 0) /*(repurpose len to prime_len)*/ -++ len = CRYPTO_EC_plen(grp); -++ -++ if (mbedtls_ecdh_read_public(&ecdh->ctx, buf, buf[0]+1)) -++ return NULL; -++ } -++ #endif -++ #if defined(MBEDTLS_ECP_MONTGOMERY_ENABLED) -++ if (mbedtls_ecp_get_type(grp) == MBEDTLS_ECP_TYPE_MONTGOMERY) { -++ if (mbedtls_ecdh_read_public(&ecdh->ctx, key, len)) -++ return NULL; -++ } -++ #endif -++ -++ struct wpabuf *buf = wpabuf_alloc(len); -++ if (buf == NULL) -++ return NULL; -++ -++ if (mbedtls_ecdh_calc_secret(&ecdh->ctx, &len, -++ wpabuf_mhead(buf), len, -++ mbedtls_ctr_drbg_random, -++ crypto_mbedtls_ctr_drbg()) == 0) { -++ wpabuf_put(buf, len); -++ return buf; -++ } -++ -++ wpabuf_clear_free(buf); -++ return NULL; -++} -++ -++void crypto_ecdh_deinit(struct crypto_ecdh *ecdh) -++{ -++ if (ecdh == NULL) -++ return; -++ mbedtls_ecp_point_free(&ecdh->Q); -++ mbedtls_ecp_group_free(&ecdh->grp); -++ mbedtls_ecdh_free(&ecdh->ctx); -++ os_free(ecdh); -++} -++ -++size_t crypto_ecdh_prime_len(struct crypto_ecdh *ecdh) -++{ -++ return CRYPTO_EC_plen(&ecdh->grp); -++} -++ -++#endif /* CRYPTO_MBEDTLS_CRYPTO_ECDH */ -++ -++ -++#ifdef CRYPTO_MBEDTLS_CRYPTO_EC -++ -++#include -++ -++struct crypto_ec *crypto_ec_init(int group) -++{ -++ mbedtls_ecp_group_id grp_id = -++ crypto_mbedtls_ecp_group_id_from_ike_id(group); -++ if (grp_id == MBEDTLS_ECP_DP_NONE) -++ return NULL; -++ mbedtls_ecp_group *e = os_malloc(sizeof(*e)); -++ if (e == NULL) -++ return NULL; -++ mbedtls_ecp_group_init(e); -++ if (mbedtls_ecp_group_load(e, grp_id) == 0) -++ return (struct crypto_ec *)e; -++ -++ mbedtls_ecp_group_free(e); -++ os_free(e); -++ return NULL; -++} -++ -++void crypto_ec_deinit(struct crypto_ec *e) -++{ -++ mbedtls_ecp_group_free((mbedtls_ecp_group *)e); -++ os_free(e); -++} -++ -++size_t crypto_ec_prime_len(struct crypto_ec *e) -++{ -++ return CRYPTO_EC_plen(e); -++} -++ -++size_t crypto_ec_prime_len_bits(struct crypto_ec *e) -++{ -++ return CRYPTO_EC_pbits(e); -++} -++ -++size_t crypto_ec_order_len(struct crypto_ec *e) -++{ -++ return (mbedtls_mpi_bitlen(CRYPTO_EC_N(e)) + 7) / 8; -++} -++ -++const struct crypto_bignum *crypto_ec_get_prime(struct crypto_ec *e) -++{ -++ return (const struct crypto_bignum *)CRYPTO_EC_P(e); -++} -++ -++const struct crypto_bignum *crypto_ec_get_order(struct crypto_ec *e) -++{ -++ return (const struct crypto_bignum *)CRYPTO_EC_N(e); -++} -++ -++const struct crypto_bignum *crypto_ec_get_a(struct crypto_ec *e) -++{ -++ static const uint8_t secp256r1_a[] = -++ {0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x01, -++ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -++ 0x00,0x00,0x00,0x00,0xff,0xff,0xff,0xff, -++ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfc}; -++ static const uint8_t secp384r1_a[] = -++ {0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, -++ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, -++ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, -++ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfe, -++ 0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x00, -++ 0x00,0x00,0x00,0x00,0xff,0xff,0xff,0xfc}; -++ static const uint8_t secp521r1_a[] = -++ {0x01,0xff,0xff,0xff,0xff,0xff,0xff,0xff, -++ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, -++ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, -++ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, -++ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, -++ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, -++ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, -++ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, -++ 0xff,0xfc}; -++ static const uint8_t secp192r1_a[] = -++ {0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, -++ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfe, -++ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfc}; -++ static const uint8_t secp224r1_a[] = -++ {0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, -++ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfe, -++ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, -++ 0xff,0xff,0xff,0xfe}; -++ -++ const uint8_t *bin = NULL; -++ size_t len = 0; -++ -++ /* (mbedtls groups matching supported sswu_curve_param() IKE groups) */ -++ switch (((mbedtls_ecp_group *)e)->id) { -++ #ifdef MBEDTLS_ECP_DP_SECP256R1_ENABLED -++ case MBEDTLS_ECP_DP_SECP256R1: -++ bin = secp256r1_a; -++ len = sizeof(secp256r1_a); -++ break; -++ #endif -++ #ifdef MBEDTLS_ECP_DP_SECP384R1_ENABLED -++ case MBEDTLS_ECP_DP_SECP384R1: -++ bin = secp384r1_a; -++ len = sizeof(secp384r1_a); -++ break; -++ #endif -++ #ifdef MBEDTLS_ECP_DP_SECP521R1_ENABLED -++ case MBEDTLS_ECP_DP_SECP521R1: -++ bin = secp521r1_a; -++ len = sizeof(secp521r1_a); -++ break; -++ #endif -++ #ifdef MBEDTLS_ECP_DP_SECP192R1_ENABLED -++ case MBEDTLS_ECP_DP_SECP192R1: -++ bin = secp192r1_a; -++ len = sizeof(secp192r1_a); -++ break; -++ #endif -++ #ifdef MBEDTLS_ECP_DP_SECP224R1_ENABLED -++ case MBEDTLS_ECP_DP_SECP224R1: -++ bin = secp224r1_a; -++ len = sizeof(secp224r1_a); -++ break; -++ #endif -++ #ifdef MBEDTLS_ECP_DP_BP256R1_ENABLED -++ case MBEDTLS_ECP_DP_BP256R1: -++ return (const struct crypto_bignum *)CRYPTO_EC_A(e); -++ #endif -++ #ifdef MBEDTLS_ECP_DP_BP384R1_ENABLED -++ case MBEDTLS_ECP_DP_BP384R1: -++ return (const struct crypto_bignum *)CRYPTO_EC_A(e); -++ #endif -++ #ifdef MBEDTLS_ECP_DP_BP512R1_ENABLED -++ case MBEDTLS_ECP_DP_BP512R1: -++ return (const struct crypto_bignum *)CRYPTO_EC_A(e); -++ #endif -++ #ifdef MBEDTLS_ECP_DP_CURVE25519_ENABLED -++ case MBEDTLS_ECP_DP_CURVE25519: -++ return (const struct crypto_bignum *)CRYPTO_EC_A(e); -++ #endif -++ #ifdef MBEDTLS_ECP_DP_CURVE448_ENABLED -++ case MBEDTLS_ECP_DP_CURVE448: -++ return (const struct crypto_bignum *)CRYPTO_EC_A(e); -++ #endif -++ default: -++ return NULL; -++ } -++ -++ /*(note: not thread-safe; returns file-scoped static storage)*/ -++ if (mbedtls_mpi_read_binary(&mpi_sw_A, bin, len) == 0) -++ return (const struct crypto_bignum *)&mpi_sw_A; -++ return NULL; -++} -++ -++const struct crypto_bignum *crypto_ec_get_b(struct crypto_ec *e) -++{ -++ return (const struct crypto_bignum *)CRYPTO_EC_B(e); -++} -++ -++const struct crypto_ec_point * crypto_ec_get_generator(struct crypto_ec *e) -++{ -++ return (const struct crypto_ec_point *)CRYPTO_EC_G(e); -++} -++ -++struct crypto_ec_point *crypto_ec_point_init(struct crypto_ec *e) -++{ -++ mbedtls_ecp_point *p = os_malloc(sizeof(*p)); -++ if (p != NULL) -++ mbedtls_ecp_point_init(p); -++ return (struct crypto_ec_point *)p; -++} -++ -++void crypto_ec_point_deinit(struct crypto_ec_point *p, int clear) -++{ -++ mbedtls_ecp_point_free((mbedtls_ecp_point *)p); -++ os_free(p); -++} -++ -++int crypto_ec_point_x(struct crypto_ec *e, const struct crypto_ec_point *p, -++ struct crypto_bignum *x) -++{ -++ mbedtls_mpi *px = &((mbedtls_ecp_point *)p)->MBEDTLS_PRIVATE(X); -++ return mbedtls_mpi_copy((mbedtls_mpi *)x, px) -++ ? -1 -++ : 0; -++} -++ -++int crypto_ec_point_to_bin(struct crypto_ec *e, -++ const struct crypto_ec_point *point, u8 *x, u8 *y) -++{ -++ /* crypto.h documents crypto_ec_point_to_bin() output is big-endian */ -++ size_t len = CRYPTO_EC_plen(e); -++ if (x) { -++ mbedtls_mpi *px = &((mbedtls_ecp_point *)point)->MBEDTLS_PRIVATE(X); -++ if (mbedtls_mpi_write_binary(px, x, len)) -++ return -1; -++ } -++ if (y) { -++ #if 0 /*(should not be necessary; py mpi should be in initial state)*/ -++ #ifdef MBEDTLS_ECP_MONTGOMERY_ENABLED -++ if (mbedtls_ecp_get_type((mbedtls_ecp_group *)e) -++ == MBEDTLS_ECP_TYPE_MONTGOMERY) { -++ os_memset(y, 0, len); -++ return 0; -++ } -++ #endif -++ #endif -++ mbedtls_mpi *py = &((mbedtls_ecp_point *)point)->MBEDTLS_PRIVATE(Y); -++ if (mbedtls_mpi_write_binary(py, y, len)) -++ return -1; -++ } -++ return 0; -++} -++ -++struct crypto_ec_point * crypto_ec_point_from_bin(struct crypto_ec *e, -++ const u8 *val) -++{ -++ size_t len = CRYPTO_EC_plen(e); -++ mbedtls_ecp_point *p = os_malloc(sizeof(*p)); -++ u8 buf[1+MBEDTLS_MPI_MAX_SIZE*2]; -++ if (p == NULL) -++ return NULL; -++ mbedtls_ecp_point_init(p); -++ -++ #ifdef MBEDTLS_ECP_SHORT_WEIERSTRASS_ENABLED -++ if (mbedtls_ecp_get_type((mbedtls_ecp_group *)e) -++ == MBEDTLS_ECP_TYPE_SHORT_WEIERSTRASS) { -++ #if 0 /* prefer alternative to MBEDTLS_PRIVATE() access */ -++ mbedtls_mpi *px = &((mbedtls_ecp_point *)p)->MBEDTLS_PRIVATE(X); -++ mbedtls_mpi *py = &((mbedtls_ecp_point *)p)->MBEDTLS_PRIVATE(Y); -++ mbedtls_mpi *pz = &((mbedtls_ecp_point *)p)->MBEDTLS_PRIVATE(Z); -++ -++ if (mbedtls_mpi_read_binary(px, val, len) == 0 -++ && mbedtls_mpi_read_binary(py, val + len, len) == 0 -++ && mbedtls_mpi_lset(pz, 1) == 0) -++ return (struct crypto_ec_point *)p; -++ #else -++ buf[0] = 0x04; -++ os_memcpy(buf+1, val, len*2); -++ if (mbedtls_ecp_point_read_binary((mbedtls_ecp_group *)e, p, -++ buf, 1+len*2) == 0) -++ return (struct crypto_ec_point *)p; -++ #endif -++ } -++ #endif -++ #ifdef MBEDTLS_ECP_MONTGOMERY_ENABLED -++ if (mbedtls_ecp_get_type((mbedtls_ecp_group *)e) -++ == MBEDTLS_ECP_TYPE_MONTGOMERY) { -++ /* crypto.h interface documents crypto_ec_point_from_bin() -++ * val is length: prime_len * 2 and is big-endian -++ * (Short Weierstrass is assumed by hostap) -++ * Reverse to little-endian format for Montgomery */ -++ for (unsigned int i = 0; i < len; ++i) -++ buf[i] = val[len-1-i]; -++ if (mbedtls_ecp_point_read_binary((mbedtls_ecp_group *)e, p, -++ buf, len) == 0) -++ return (struct crypto_ec_point *)p; -++ } -++ #endif -++ -++ mbedtls_ecp_point_free(p); -++ os_free(p); -++ return NULL; -++} -++ -++int crypto_ec_point_add(struct crypto_ec *e, const struct crypto_ec_point *a, -++ const struct crypto_ec_point *b, -++ struct crypto_ec_point *c) -++{ -++ /* mbedtls does not provide an mbedtls_ecp_point add function */ -++ mbedtls_mpi one; -++ mbedtls_mpi_init(&one); -++ int ret = mbedtls_mpi_lset(&one, 1) -++ || mbedtls_ecp_muladd( -++ (mbedtls_ecp_group *)e, (mbedtls_ecp_point *)c, -++ &one, (const mbedtls_ecp_point *)a, -++ &one, (const mbedtls_ecp_point *)b) ? -1 : 0; -++ mbedtls_mpi_free(&one); -++ return ret; -++} -++ -++int crypto_ec_point_mul(struct crypto_ec *e, const struct crypto_ec_point *p, -++ const struct crypto_bignum *b, -++ struct crypto_ec_point *res) -++{ -++ return mbedtls_ecp_mul( -++ (mbedtls_ecp_group *)e, (mbedtls_ecp_point *)res, -++ (const mbedtls_mpi *)b, (const mbedtls_ecp_point *)p, -++ mbedtls_ctr_drbg_random, crypto_mbedtls_ctr_drbg()) ? -1 : 0; -++} -++ -++int crypto_ec_point_invert(struct crypto_ec *e, struct crypto_ec_point *p) -++{ -++ if (mbedtls_ecp_get_type((mbedtls_ecp_group *)e) -++ == MBEDTLS_ECP_TYPE_MONTGOMERY) { -++ /* e.g. MBEDTLS_ECP_DP_CURVE25519 and MBEDTLS_ECP_DP_CURVE448 */ -++ wpa_printf(MSG_ERROR, -++ "%s not implemented for Montgomery curves",__func__); -++ return -1; -++ } -++ -++ /* mbedtls does not provide an mbedtls_ecp_point invert function */ -++ /* below works for Short Weierstrass; incorrect for Montgomery curves */ -++ mbedtls_mpi *py = &((mbedtls_ecp_point *)p)->MBEDTLS_PRIVATE(Y); -++ return mbedtls_ecp_is_zero((mbedtls_ecp_point *)p) /*point at infinity*/ -++ || mbedtls_mpi_cmp_int(py, 0) == 0 /*point is its own inverse*/ -++ || mbedtls_mpi_sub_abs(py, CRYPTO_EC_P(e), py) == 0 ? 0 : -1; -++} -++ -++#ifdef MBEDTLS_ECP_SHORT_WEIERSTRASS_ENABLED -++static int -++crypto_ec_point_y_sqr_weierstrass(mbedtls_ecp_group *e, const mbedtls_mpi *x, -++ mbedtls_mpi *y2) -++{ -++ /* MBEDTLS_ECP_TYPE_SHORT_WEIERSTRASS y^2 = x^3 + a x + b */ -++ -++ /* Short Weierstrass elliptic curve group w/o A set treated as A = -3 */ -++ /* Attempt to match mbedtls/library/ecp.c:ecp_check_pubkey_sw() behavior -++ * and elsewhere in mbedtls/library/ecp.c where if A is not set, it is -++ * treated as if A = -3. */ -++ -++ #if 0 -++ /* y^2 = x^3 + ax + b */ -++ mbedtls_mpi *A = &e->A; -++ mbedtls_mpi t, A_neg3; -++ if (&e->A.p == NULL) { -++ mbedtls_mpi_init(&A_neg3); -++ if (mbedtls_mpi_lset(&A_neg3, -3) != 0) { -++ mbedtls_mpi_free(&A_neg3); -++ return -1; -++ } -++ A = &A_neg3; -++ } -++ mbedtls_mpi_init(&t); -++ int ret = /* x^3 */ -++ mbedtls_mpi_lset(&t, 3) -++ || mbedtls_mpi_exp_mod(y2, x, &t, &e->P, NULL) -++ /* ax */ -++ || mbedtls_mpi_mul_mpi(y2, y2, A) -++ || mbedtls_mpi_mod_mpi(&t, &t, &e->P) -++ /* ax + b */ -++ || mbedtls_mpi_add_mpi(&t, &t, &e->B) -++ || mbedtls_mpi_mod_mpi(&t, &t, &e->P) -++ /* x^3 + ax + b */ -++ || mbedtls_mpi_add_mpi(&t, &t, y2) /* ax + b + x^3 */ -++ || mbedtls_mpi_mod_mpi(y2, &t, &e->P); -++ mbedtls_mpi_free(&t); -++ if (A == &A_neg3) -++ mbedtls_mpi_free(&A_neg3); -++ return ret; /* 0: success, non-zero: failure */ -++ #else -++ /* y^2 = x^3 + ax + b = (x^2 + a)x + b */ -++ return /* x^2 */ -++ mbedtls_mpi_mul_mpi(y2, x, x) -++ || mbedtls_mpi_mod_mpi(y2, y2, &e->P) -++ /* x^2 + a */ -++ || (e->A.MBEDTLS_PRIVATE(p) -++ ? mbedtls_mpi_add_mpi(y2, y2, &e->A) -++ : mbedtls_mpi_sub_int(y2, y2, 3)) -++ || mbedtls_mpi_mod_mpi(y2, y2, &e->P) -++ /* (x^2 + a)x */ -++ || mbedtls_mpi_mul_mpi(y2, y2, x) -++ || mbedtls_mpi_mod_mpi(y2, y2, &e->P) -++ /* (x^2 + a)x + b */ -++ || mbedtls_mpi_add_mpi(y2, y2, &e->B) -++ || mbedtls_mpi_mod_mpi(y2, y2, &e->P); -++ #endif -++} -++#endif /* MBEDTLS_ECP_SHORT_WEIERSTRASS_ENABLED */ -++ -++#if 0 /* not used by hostap */ -++#ifdef MBEDTLS_ECP_MONTGOMERY_ENABLED -++static int -++crypto_ec_point_y_sqr_montgomery(mbedtls_ecp_group *e, const mbedtls_mpi *x, -++ mbedtls_mpi *y2) -++{ -++ /* XXX: !!! must be reviewed and audited for correctness !!! */ -++ -++ /* MBEDTLS_ECP_TYPE_MONTGOMERY y^2 = x^3 + a x^2 + x */ -++ -++ /* y^2 = x^3 + a x^2 + x = (x + a)x^2 + x */ -++ mbedtls_mpi x2; -++ mbedtls_mpi_init(&x2); -++ int ret = /* x^2 */ -++ mbedtls_mpi_mul_mpi(&x2, x, x) -++ || mbedtls_mpi_mod_mpi(&x2, &x2, &e->P) -++ /* x + a */ -++ || mbedtls_mpi_add_mpi(y2, x, &e->A) -++ || mbedtls_mpi_mod_mpi(y2, y2, &e->P) -++ /* (x + a)x^2 */ -++ || mbedtls_mpi_mul_mpi(y2, y2, &x2) -++ || mbedtls_mpi_mod_mpi(y2, y2, &e->P) -++ /* (x + a)x^2 + x */ -++ || mbedtls_mpi_add_mpi(y2, y2, x) -++ || mbedtls_mpi_mod_mpi(y2, y2, &e->P); -++ mbedtls_mpi_free(&x2); -++ return ret; /* 0: success, non-zero: failure */ -++} -++#endif /* MBEDTLS_ECP_MONTGOMERY_ENABLED */ -++#endif -++ -++struct crypto_bignum * -++crypto_ec_point_compute_y_sqr(struct crypto_ec *e, -++ const struct crypto_bignum *x) -++{ -++ mbedtls_mpi *y2 = os_malloc(sizeof(*y2)); -++ if (y2 == NULL) -++ return NULL; -++ mbedtls_mpi_init(y2); -++ -++ #ifdef MBEDTLS_ECP_SHORT_WEIERSTRASS_ENABLED -++ if (mbedtls_ecp_get_type((mbedtls_ecp_group *)e) -++ == MBEDTLS_ECP_TYPE_SHORT_WEIERSTRASS -++ && crypto_ec_point_y_sqr_weierstrass((mbedtls_ecp_group *)e, -++ (const mbedtls_mpi *)x, -++ y2) == 0) -++ return (struct crypto_bignum *)y2; -++ #endif -++ #if 0 /* not used by hostap */ -++ #ifdef MBEDTLS_ECP_MONTGOMERY_ENABLED -++ if (mbedtls_ecp_get_type((mbedtls_ecp_group *)e) -++ == MBEDTLS_ECP_TYPE_MONTGOMERY -++ && crypto_ec_point_y_sqr_montgomery((mbedtls_ecp_group *)e, -++ (const mbedtls_mpi *)x, -++ y2) == 0) -++ return (struct crypto_bignum *)y2; -++ #endif -++ #endif -++ -++ mbedtls_mpi_free(y2); -++ os_free(y2); -++ return NULL; -++} -++ -++int crypto_ec_point_is_at_infinity(struct crypto_ec *e, -++ const struct crypto_ec_point *p) -++{ -++ return mbedtls_ecp_is_zero((mbedtls_ecp_point *)p); -++} -++ -++int crypto_ec_point_is_on_curve(struct crypto_ec *e, -++ const struct crypto_ec_point *p) -++{ -++ #if 1 -++ return mbedtls_ecp_check_pubkey((const mbedtls_ecp_group *)e, -++ (const mbedtls_ecp_point *)p) == 0; -++ #else -++ /* compute y^2 mod P and compare to y^2 mod P */ -++ /*(ref: src/eap_common/eap_pwd_common.c:compute_password_element())*/ -++ const mbedtls_mpi *px = &((const mbedtls_ecp_point *)p)->MBEDTLS_PRIVATE(X); -++ mbedtls_mpi *cy2 = (mbedtls_mpi *) -++ crypto_ec_point_compute_y_sqr(e, (const struct crypto_bignum *)px); -++ if (cy2 == NULL) -++ return 0; -++ -++ mbedtls_mpi y2; -++ mbedtls_mpi_init(&y2); -++ const mbedtls_mpi *py = &((const mbedtls_ecp_point *)p)->MBEDTLS_PRIVATE(Y); -++ int is_on_curve = mbedtls_mpi_mul_mpi(&y2, py, py) /* y^2 mod P */ -++ || mbedtls_mpi_mod_mpi(&y2, &y2, CRYPTO_EC_P(e)) -++ || mbedtls_mpi_cmp_mpi(&y2, cy2) != 0 ? 0 : 1; -++ -++ mbedtls_mpi_free(&y2); -++ mbedtls_mpi_free(cy2); -++ os_free(cy2); -++ return is_on_curve; -++ #endif -++} -++ -++int crypto_ec_point_cmp(const struct crypto_ec *e, -++ const struct crypto_ec_point *a, -++ const struct crypto_ec_point *b) -++{ -++ return mbedtls_ecp_point_cmp((const mbedtls_ecp_point *)a, -++ (const mbedtls_ecp_point *)b); -++} -++ -++#if !defined(CONFIG_NO_STDOUT_DEBUG) -++void crypto_ec_point_debug_print(const struct crypto_ec *e, -++ const struct crypto_ec_point *p, -++ const char *title) -++{ -++ u8 x[MBEDTLS_MPI_MAX_SIZE]; -++ u8 y[MBEDTLS_MPI_MAX_SIZE]; -++ size_t len = CRYPTO_EC_plen(e); -++ /* crypto_ec_point_to_bin ought to take (const struct crypto_ec *e) */ -++ struct crypto_ec *ee; -++ *(const struct crypto_ec **)&ee = e; /*(cast away const)*/ -++ if (crypto_ec_point_to_bin(ee, p, x, y) == 0) { -++ if (title) -++ wpa_printf(MSG_DEBUG, "%s", title); -++ wpa_hexdump(MSG_DEBUG, "x:", x, len); -++ wpa_hexdump(MSG_DEBUG, "y:", y, len); -++ } -++} -++#endif -++ -++ -++struct crypto_ec_key * crypto_ec_key_parse_priv(const u8 *der, size_t der_len) -++{ -++ mbedtls_pk_context *ctx = os_malloc(sizeof(*ctx)); -++ if (ctx == NULL) -++ return NULL; -++ mbedtls_pk_init(ctx); -++ #if MBEDTLS_VERSION_NUMBER < 0x03000000 /* mbedtls 3.0.0 */ -++ if (mbedtls_pk_parse_key(ctx, der, der_len, NULL, 0) == 0) -++ #else -++ if (mbedtls_pk_parse_key(ctx, der, der_len, NULL, 0, -++ mbedtls_ctr_drbg_random, -++ crypto_mbedtls_ctr_drbg()) == 0) -++ #endif -++ return (struct crypto_ec_key *)ctx; -++ -++ mbedtls_pk_free(ctx); -++ os_free(ctx); -++ return NULL; -++} -++ -++#ifdef CRYPTO_MBEDTLS_CRYPTO_HPKE -++#ifdef CONFIG_MODULE_TESTS -++/*(for crypto_module_tests.c)*/ -++struct crypto_ec_key * crypto_ec_key_set_priv(int group, -++ const u8 *raw, size_t raw_len) -++{ -++ mbedtls_ecp_group_id grp_id = -++ crypto_mbedtls_ecp_group_id_from_ike_id(group); -++ if (grp_id == MBEDTLS_ECP_DP_NONE) -++ return NULL; -++ const mbedtls_pk_info_t *pk_info = -++ mbedtls_pk_info_from_type(MBEDTLS_PK_ECKEY); -++ if (pk_info == NULL) -++ return NULL; -++ mbedtls_pk_context *ctx = os_malloc(sizeof(*ctx)); -++ if (ctx == NULL) -++ return NULL; -++ mbedtls_pk_init(ctx); -++ if (mbedtls_pk_setup(ctx, pk_info) == 0 -++ && mbedtls_ecp_read_key(grp_id,mbedtls_pk_ec(*ctx),raw,raw_len) == 0) { -++ return (struct crypto_ec_key *)ctx; -++ } -++ -++ mbedtls_pk_free(ctx); -++ os_free(ctx); -++ return NULL; -++} -++#endif -++#endif -++ -++#include -++#include -++static int crypto_mbedtls_pk_parse_subpubkey_compressed(mbedtls_pk_context *ctx, const u8 *der, size_t der_len) -++{ -++ /* The following is modified from: -++ * mbedtls/library/pkparse.c:mbedtls_pk_parse_subpubkey() -++ * mbedtls/library/pkparse.c:pk_get_pk_alg() -++ * mbedtls/library/pkparse.c:pk_use_ecparams() -++ */ -++ mbedtls_pk_type_t pk_alg = MBEDTLS_PK_NONE; -++ const mbedtls_pk_info_t *pk_info; -++ int ret; -++ size_t len; -++ const unsigned char *end = der+der_len; -++ unsigned char *p; -++ *(const unsigned char **)&p = der; -++ -++ if( ( ret = mbedtls_asn1_get_tag( &p, end, &len, -++ MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 ) -++ { -++ return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT, ret ) ); -++ } -++ -++ end = p + len; -++ -++ /* -++ if( ( ret = pk_get_pk_alg( &p, end, &pk_alg, &alg_params ) ) != 0 ) -++ return( ret ); -++ */ -++ mbedtls_asn1_buf alg_oid, params; -++ memset( ¶ms, 0, sizeof(mbedtls_asn1_buf) ); -++ if( ( ret = mbedtls_asn1_get_alg( &p, end, &alg_oid, ¶ms ) ) != 0 ) -++ return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_PK_INVALID_ALG, ret ) ); -++ if( mbedtls_oid_get_pk_alg( &alg_oid, &pk_alg ) != 0 ) -++ return( MBEDTLS_ERR_PK_UNKNOWN_PK_ALG ); -++ -++ if( ( ret = mbedtls_asn1_get_bitstring_null( &p, end, &len ) ) != 0 ) -++ return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_PK_INVALID_PUBKEY, ret ) ); -++ -++ if( p + len != end ) -++ return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_PK_INVALID_PUBKEY, -++ MBEDTLS_ERR_ASN1_LENGTH_MISMATCH ) ); -++ -++ if( ( pk_info = mbedtls_pk_info_from_type( pk_alg ) ) == NULL ) -++ return( MBEDTLS_ERR_PK_UNKNOWN_PK_ALG ); -++ -++ if( ( ret = mbedtls_pk_setup( ctx, pk_info ) ) != 0 ) -++ return( ret ); -++ -++ /* assume mbedtls_pk_parse_subpubkey(&der, der+der_len, ctx) -++ * has already run with ctx initialized up to pk_get_ecpubkey(), -++ * and pk_get_ecpubkey() has returned MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE -++ * -++ * mbedtls mbedtls_ecp_point_read_binary() -++ * does not handle point in COMPRESSED format -++ * -++ * (validate assumption that algorithm is EC) */ -++ mbedtls_ecp_keypair *ecp_kp = mbedtls_pk_ec(*ctx); -++ if (ecp_kp == NULL) -++ return( MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE ); -++ mbedtls_ecp_group *ecp_kp_grp = &ecp_kp->MBEDTLS_PRIVATE(grp); -++ mbedtls_ecp_point *ecp_kp_Q = &ecp_kp->MBEDTLS_PRIVATE(Q); -++ mbedtls_ecp_group_id grp_id; -++ -++ -++ /* mbedtls/library/pkparse.c:pk_use_ecparams() */ -++ -++ if( params.tag == MBEDTLS_ASN1_OID ) -++ { -++ if( mbedtls_oid_get_ec_grp( ¶ms, &grp_id ) != 0 ) -++ return( MBEDTLS_ERR_PK_UNKNOWN_NAMED_CURVE ); -++ } -++ else -++ { -++#if defined(MBEDTLS_PK_PARSE_EC_EXTENDED) -++ /*(large code block not copied from mbedtls; unsupported)*/ -++ #if 0 -++ if( ( ret = pk_group_id_from_specified( ¶ms, &grp_id ) ) != 0 ) -++ return( ret ); -++ #endif -++#endif -++ return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT ); -++ } -++ -++ /* -++ * grp may already be initialized; if so, make sure IDs match -++ */ -++ if( ecp_kp_grp->id != MBEDTLS_ECP_DP_NONE && ecp_kp_grp->id != grp_id ) -++ return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT ); -++ -++ if( ( ret = mbedtls_ecp_group_load( ecp_kp_grp, grp_id ) ) != 0 ) -++ return( ret ); -++ -++ -++ /* (validate assumption that EC point is in COMPRESSED format) */ -++ len = CRYPTO_EC_plen(ecp_kp_grp); -++ if( mbedtls_ecp_get_type(ecp_kp_grp) != MBEDTLS_ECP_TYPE_SHORT_WEIERSTRASS -++ || (end - p) != 1+len -++ || (*p != 0x02 && *p != 0x03) ) -++ return( MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE ); -++ -++ /* Instead of calling mbedtls/library/pkparse.c:pk_get_ecpubkey() to call -++ * mbedtls_ecp_point_read_binary(), manually parse point into ecp_kp_Q */ -++ mbedtls_mpi *X = &ecp_kp_Q->MBEDTLS_PRIVATE(X); -++ mbedtls_mpi *Y = &ecp_kp_Q->MBEDTLS_PRIVATE(Y); -++ mbedtls_mpi *Z = &ecp_kp_Q->MBEDTLS_PRIVATE(Z); -++ ret = mbedtls_mpi_lset(Z, 1); -++ if (ret != 0) -++ return( ret ); -++ ret = mbedtls_mpi_read_binary(X, p+1, len); -++ if (ret != 0) -++ return( ret ); -++ /* derive Y -++ * (similar derivation of Y in crypto_mbedtls.c:crypto_ecdh_set_peerkey())*/ -++ ret = mbedtls_mpi_copy(Y, X) /*(Y is used as input and output obj below)*/ -++ || crypto_mbedtls_short_weierstrass_derive_y(ecp_kp_grp, Y, (*p & 1)); -++ if (ret != 0) -++ return( ret ); -++ -++ return mbedtls_ecp_check_pubkey( ecp_kp_grp, ecp_kp_Q ); -++} -++ -++struct crypto_ec_key * crypto_ec_key_parse_pub(const u8 *der, size_t der_len) -++{ -++ mbedtls_pk_context *ctx = os_malloc(sizeof(*ctx)); -++ if (ctx == NULL) -++ return NULL; -++ mbedtls_pk_init(ctx); -++ /*int rc = mbedtls_pk_parse_subpubkey(&der, der+der_len, ctx);*/ -++ int rc = mbedtls_pk_parse_public_key(ctx, der, der_len); -++ if (rc == 0) -++ return (struct crypto_ec_key *)ctx; -++ else if (rc == MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE) { -++ /* mbedtls mbedtls_ecp_point_read_binary() -++ * does not handle point in COMPRESSED format; parse internally */ -++ rc = crypto_mbedtls_pk_parse_subpubkey_compressed(ctx,der,der_len); -++ if (rc == 0) -++ return (struct crypto_ec_key *)ctx; -++ } -++ -++ mbedtls_pk_free(ctx); -++ os_free(ctx); -++ return NULL; -++} -++ -++#ifdef CRYPTO_MBEDTLS_CRYPTO_EC_DPP -++ -++static struct crypto_ec_key * -++crypto_ec_key_set_pub_point_for_group(mbedtls_ecp_group_id grp_id, -++ const mbedtls_ecp_point *pub, -++ const u8 *buf, size_t len) -++{ -++ const mbedtls_pk_info_t *pk_info = -++ mbedtls_pk_info_from_type(MBEDTLS_PK_ECKEY); -++ if (pk_info == NULL) -++ return NULL; -++ mbedtls_pk_context *ctx = os_malloc(sizeof(*ctx)); -++ if (ctx == NULL) -++ return NULL; -++ mbedtls_pk_init(ctx); -++ if (mbedtls_pk_setup(ctx, pk_info) == 0) { -++ /* (Is private key generation necessary for callers?) -++ * alt: gen key then overwrite Q -++ * mbedtls_ecp_gen_key(grp_id, ecp_kp, -++ * mbedtls_ctr_drbg_random, -++ * crypto_mbedtls_ctr_drbg()) == 0 -++ */ -++ mbedtls_ecp_keypair *ecp_kp = mbedtls_pk_ec(*ctx); -++ mbedtls_ecp_group *ecp_kp_grp = &ecp_kp->MBEDTLS_PRIVATE(grp); -++ mbedtls_ecp_point *ecp_kp_Q = &ecp_kp->MBEDTLS_PRIVATE(Q); -++ mbedtls_mpi *ecp_kp_d = &ecp_kp->MBEDTLS_PRIVATE(d); -++ if (mbedtls_ecp_group_load(ecp_kp_grp, grp_id) == 0 -++ && (pub -++ ? mbedtls_ecp_copy(ecp_kp_Q, pub) == 0 -++ : mbedtls_ecp_point_read_binary(ecp_kp_grp, ecp_kp_Q, -++ buf, len) == 0) -++ && mbedtls_ecp_gen_privkey(ecp_kp_grp, ecp_kp_d, -++ mbedtls_ctr_drbg_random, -++ crypto_mbedtls_ctr_drbg()) == 0){ -++ return (struct crypto_ec_key *)ctx; -++ } -++ } -++ -++ mbedtls_pk_free(ctx); -++ os_free(ctx); -++ return NULL; -++} -++ -++struct crypto_ec_key * crypto_ec_key_set_pub(int group, const u8 *x, -++ const u8 *y, size_t len) -++{ -++ mbedtls_ecp_group_id grp_id = -++ crypto_mbedtls_ecp_group_id_from_ike_id(group); -++ if (grp_id == MBEDTLS_ECP_DP_NONE) -++ return NULL; -++ if (len > MBEDTLS_MPI_MAX_SIZE) -++ return NULL; -++ u8 buf[1+MBEDTLS_MPI_MAX_SIZE*2]; -++ buf[0] = 0x04; /* assume x,y for Short Weierstrass */ -++ os_memcpy(buf+1, x, len); -++ os_memcpy(buf+1+len, y, len); -++ -++ return crypto_ec_key_set_pub_point_for_group(grp_id,NULL,buf,1+len*2); -++} -++ -++struct crypto_ec_key * -++crypto_ec_key_set_pub_point(struct crypto_ec *e, -++ const struct crypto_ec_point *pub) -++{ -++ mbedtls_ecp_group_id grp_id = ((mbedtls_ecp_group *)e)->id; -++ mbedtls_ecp_point *p = (mbedtls_ecp_point *)pub; -++ return crypto_ec_key_set_pub_point_for_group(grp_id, p, NULL, 0); -++} -++ -++ -++struct crypto_ec_key * crypto_ec_key_gen(int group) -++{ -++ mbedtls_pk_context *ctx = os_malloc(sizeof(*ctx)); -++ if (ctx == NULL) -++ return NULL; -++ mbedtls_pk_init(ctx); -++ if (crypto_mbedtls_keypair_gen(group, ctx) == 0) -++ return (struct crypto_ec_key *)ctx; -++ mbedtls_pk_free(ctx); -++ os_free(ctx); -++ return NULL; -++} -++ -++#endif /* CRYPTO_MBEDTLS_CRYPTO_EC_DPP */ -++ -++void crypto_ec_key_deinit(struct crypto_ec_key *key) -++{ -++ mbedtls_pk_free((mbedtls_pk_context *)key); -++ os_free(key); -++} -++ -++struct wpabuf * crypto_ec_key_get_subject_public_key(struct crypto_ec_key *key) -++{ -++ /* (similar to crypto_ec_key_get_pubkey_point(), -++ * but compressed point format and ASN.1 DER wrapping)*/ -++#ifndef MBEDTLS_PK_ECP_PUB_DER_MAX_BYTES /*(mbedtls/library/pkwrite.h)*/ -++#define MBEDTLS_PK_ECP_PUB_DER_MAX_BYTES ( 30 + 2 * MBEDTLS_ECP_MAX_BYTES ) -++#endif -++ unsigned char buf[MBEDTLS_PK_ECP_PUB_DER_MAX_BYTES]; -++ int len = mbedtls_pk_write_pubkey_der((mbedtls_pk_context *)key, -++ buf, sizeof(buf)); -++ if (len < 0) -++ return NULL; -++ /* Note: data is written at the end of the buffer! Use the -++ * return value to determine where you should start -++ * using the buffer */ -++ unsigned char *p = buf+sizeof(buf)-len; -++ -++ #ifdef MBEDTLS_ECP_SHORT_WEIERSTRASS_ENABLED -++ mbedtls_ecp_keypair *ecp_kp = mbedtls_pk_ec(*(mbedtls_pk_context *)key); -++ if (ecp_kp == NULL) -++ return NULL; -++ mbedtls_ecp_group *grp = &ecp_kp->MBEDTLS_PRIVATE(grp); -++ /* Note: sae_pk.c expects pubkey point in compressed format, -++ * but mbedtls_pk_write_pubkey_der() writes uncompressed format. -++ * Manually translate format and update lengths in DER format */ -++ if (mbedtls_ecp_get_type(grp) == MBEDTLS_ECP_TYPE_SHORT_WEIERSTRASS) { -++ unsigned char *end = buf+sizeof(buf); -++ size_t n; -++ /* SubjectPublicKeyInfo SEQUENCE */ -++ mbedtls_asn1_get_tag(&p, end, &n, -++ MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE); -++ /* algorithm AlgorithmIdentifier */ -++ unsigned char *a = p; -++ size_t alen; -++ mbedtls_asn1_get_tag(&p, end, &alen, -++ MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE); -++ p += alen; -++ alen = (size_t)(p - a); -++ /* subjectPublicKey BIT STRING */ -++ mbedtls_asn1_get_tag(&p, end, &n, MBEDTLS_ASN1_BIT_STRING); -++ /* rewrite into compressed point format and rebuild ASN.1 */ -++ p[1] = (buf[sizeof(buf)-1] & 1) ? 0x03 : 0x02; -++ n = 1 + 1 + (n-2)/2; -++ len = mbedtls_asn1_write_len(&p, buf, n) + (int)n; -++ len += mbedtls_asn1_write_tag(&p, buf, MBEDTLS_ASN1_BIT_STRING); -++ os_memmove(p-alen, a, alen); -++ len += alen; -++ p -= alen; -++ len += mbedtls_asn1_write_len(&p, buf, (size_t)len); -++ len += mbedtls_asn1_write_tag(&p, buf, -++ MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE); -++ } -++ #endif -++ return wpabuf_alloc_copy(p, (size_t)len); -++} -++ -++#ifdef CRYPTO_MBEDTLS_CRYPTO_EC_DPP -++ -++struct wpabuf * crypto_ec_key_get_ecprivate_key(struct crypto_ec_key *key, -++ bool include_pub) -++{ -++#ifndef MBEDTLS_PK_ECP_PRV_DER_MAX_BYTES /*(mbedtls/library/pkwrite.h)*/ -++#define MBEDTLS_PK_ECP_PRV_DER_MAX_BYTES ( 29 + 3 * MBEDTLS_ECP_MAX_BYTES ) -++#endif -++ unsigned char priv[MBEDTLS_PK_ECP_PRV_DER_MAX_BYTES]; -++ int privlen = mbedtls_pk_write_key_der((mbedtls_pk_context *)key, -++ priv, sizeof(priv)); -++ if (privlen < 0) -++ return NULL; -++ -++ struct wpabuf *wbuf; -++ -++ /* Note: data is written at the end of the buffer! Use the -++ * return value to determine where you should start -++ * using the buffer */ -++ /* mbedtls_pk_write_key_der() includes publicKey in DER */ -++ if (include_pub) -++ wbuf = wpabuf_alloc_copy(priv+sizeof(priv)-privlen, privlen); -++ else { -++ /* calculate publicKey offset and skip from end of buffer */ -++ unsigned char *p = priv+sizeof(priv)-privlen; -++ unsigned char *end = priv+sizeof(priv); -++ size_t len; -++ /* ECPrivateKey SEQUENCE */ -++ mbedtls_asn1_get_tag(&p, end, &len, -++ MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE); -++ /* version INTEGER */ -++ unsigned char *v = p; -++ mbedtls_asn1_get_tag(&p, end, &len, MBEDTLS_ASN1_INTEGER); -++ p += len; -++ /* privateKey OCTET STRING */ -++ mbedtls_asn1_get_tag(&p, end, &len, MBEDTLS_ASN1_OCTET_STRING); -++ p += len; -++ /* parameters ECParameters */ -++ mbedtls_asn1_get_tag(&p, end, &len, -++ MBEDTLS_ASN1_CONTEXT_SPECIFIC | MBEDTLS_ASN1_CONSTRUCTED); -++ p += len; -++ -++ /* write new SEQUENCE header (we know that it fits in priv[]) */ -++ len = (size_t)(p - v); -++ p = v; -++ len += mbedtls_asn1_write_len(&p, priv, len); -++ len += mbedtls_asn1_write_tag(&p, priv, -++ MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE); -++ wbuf = wpabuf_alloc_copy(p, len); -++ } -++ -++ forced_memzero(priv, sizeof(priv)); -++ return wbuf; -++} -++ -++struct wpabuf * crypto_ec_key_get_pubkey_point(struct crypto_ec_key *key, -++ int prefix) -++{ -++ /*(similarities to crypto_ecdh_get_pubkey(), but different struct)*/ -++ mbedtls_ecp_keypair *ecp_kp = mbedtls_pk_ec(*(mbedtls_pk_context *)key); -++ if (ecp_kp == NULL) -++ return NULL; -++ mbedtls_ecp_group *grp = &ecp_kp->MBEDTLS_PRIVATE(grp); -++ size_t len = CRYPTO_EC_plen(grp); -++ #ifdef MBEDTLS_ECP_MONTGOMERY_ENABLED -++ /* len */ -++ #endif -++ #ifdef MBEDTLS_ECP_SHORT_WEIERSTRASS_ENABLED -++ if (mbedtls_ecp_get_type(grp) == MBEDTLS_ECP_TYPE_SHORT_WEIERSTRASS) -++ len = len*2+1; -++ #endif -++ struct wpabuf *buf = wpabuf_alloc(len); -++ if (buf == NULL) -++ return NULL; -++ mbedtls_ecp_point *ecp_kp_Q = &ecp_kp->MBEDTLS_PRIVATE(Q); -++ if (mbedtls_ecp_point_write_binary(grp, ecp_kp_Q, -++ MBEDTLS_ECP_PF_UNCOMPRESSED, &len, -++ wpabuf_mhead_u8(buf), len) == 0) { -++ if (!prefix) /* Remove 0x04 prefix if requested */ -++ os_memmove(wpabuf_mhead(buf),wpabuf_mhead(buf)+1,--len); -++ wpabuf_put(buf, len); -++ return buf; -++ } -++ -++ wpabuf_free(buf); -++ return NULL; -++} -++ -++struct crypto_ec_point * -++crypto_ec_key_get_public_key(struct crypto_ec_key *key) -++{ -++ mbedtls_ecp_keypair *ecp_kp = mbedtls_pk_ec(*(mbedtls_pk_context *)key); -++ if (ecp_kp == NULL) -++ return NULL; -++ mbedtls_ecp_point *p = os_malloc(sizeof(*p)); -++ if (p != NULL) { -++ /*(mbedtls_ecp_export() uses &ecp_kp->MBEDTLS_PRIVATE(grp))*/ -++ mbedtls_ecp_point_init(p); -++ mbedtls_ecp_point *ecp_kp_Q = &ecp_kp->MBEDTLS_PRIVATE(Q); -++ if (mbedtls_ecp_copy(p, ecp_kp_Q)) { -++ mbedtls_ecp_point_free(p); -++ os_free(p); -++ p = NULL; -++ } -++ } -++ return (struct crypto_ec_point *)p; -++} -++ -++struct crypto_bignum * -++crypto_ec_key_get_private_key(struct crypto_ec_key *key) -++{ -++ mbedtls_ecp_keypair *ecp_kp = mbedtls_pk_ec(*(mbedtls_pk_context *)key); -++ if (ecp_kp == NULL) -++ return NULL; -++ mbedtls_mpi *bn = os_malloc(sizeof(*bn)); -++ if (bn) { -++ /*(mbedtls_ecp_export() uses &ecp_kp->MBEDTLS_PRIVATE(grp))*/ -++ mbedtls_mpi_init(bn); -++ mbedtls_mpi *ecp_kp_d = &ecp_kp->MBEDTLS_PRIVATE(d); -++ if (mbedtls_mpi_copy(bn, ecp_kp_d)) { -++ mbedtls_mpi_free(bn); -++ os_free(bn); -++ bn = NULL; -++ } -++ } -++ return (struct crypto_bignum *)bn; -++} -++ -++#endif /* CRYPTO_MBEDTLS_CRYPTO_EC_DPP */ -++ -++static mbedtls_md_type_t crypto_ec_key_sign_md(size_t len) -++{ -++ /* get mbedtls_md_type_t from length of hash data to be signed */ -++ switch (len) { -++ case 64: return MBEDTLS_MD_SHA512; -++ case 48: return MBEDTLS_MD_SHA384; -++ case 32: return MBEDTLS_MD_SHA256; -++ case 20: return MBEDTLS_MD_SHA1; -++ case 16: return MBEDTLS_MD_MD5; -++ default: return MBEDTLS_MD_NONE; -++ } -++} -++ -++struct wpabuf * crypto_ec_key_sign(struct crypto_ec_key *key, const u8 *data, -++ size_t len) -++{ -++ #ifndef MBEDTLS_PK_SIGNATURE_MAX_SIZE /*(defined since mbedtls 2.20.0)*/ -++ #if MBEDTLS_ECDSA_MAX_LEN > MBEDTLS_MPI_MAX_SIZE -++ #define MBEDTLS_PK_SIGNATURE_MAX_SIZE MBEDTLS_ECDSA_MAX_LEN -++ #else -++ #define MBEDTLS_PK_SIGNATURE_MAX_SIZE MBEDTLS_MPI_MAX_SIZE -++ #endif -++ #endif -++ size_t sig_len = MBEDTLS_PK_SIGNATURE_MAX_SIZE; -++ struct wpabuf *buf = wpabuf_alloc(sig_len); -++ if (buf == NULL) -++ return NULL; -++ if (mbedtls_pk_sign((mbedtls_pk_context *)key, -++ crypto_ec_key_sign_md(len), data, len, -++ wpabuf_mhead_u8(buf), -++ #if MBEDTLS_VERSION_NUMBER >= 0x03000000 /* mbedtls 3.0.0 */ -++ sig_len, -++ #endif -++ &sig_len, -++ mbedtls_ctr_drbg_random, -++ crypto_mbedtls_ctr_drbg()) == 0) { -++ wpabuf_put(buf, sig_len); -++ return buf; -++ } -++ -++ wpabuf_free(buf); -++ return NULL; -++} -++ -++#ifdef CRYPTO_MBEDTLS_CRYPTO_EC_DPP -++struct wpabuf * crypto_ec_key_sign_r_s(struct crypto_ec_key *key, -++ const u8 *data, size_t len) -++{ -++ mbedtls_ecp_keypair *ecp_kp = mbedtls_pk_ec(*(mbedtls_pk_context *)key); -++ if (ecp_kp == NULL) -++ return NULL; -++ -++ size_t sig_len = MBEDTLS_ECDSA_MAX_LEN; -++ u8 buf[MBEDTLS_ECDSA_MAX_LEN]; -++ if (mbedtls_ecdsa_write_signature(ecp_kp, crypto_ec_key_sign_md(len), -++ data, len, buf, -++ #if MBEDTLS_VERSION_NUMBER >= 0x03000000 /* mbedtls 3.0.0 */ -++ sig_len, -++ #endif -++ &sig_len, -++ mbedtls_ctr_drbg_random, -++ crypto_mbedtls_ctr_drbg())) { -++ return NULL; -++ } -++ -++ /*(mbedtls_ecdsa_write_signature() writes signature in ASN.1)*/ -++ /* parse ASN.1 to get r and s and lengths */ -++ u8 *p = buf, *r, *s; -++ u8 *end = p + sig_len; -++ size_t rlen, slen; -++ mbedtls_asn1_get_tag(&p, end, &rlen, -++ MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE); -++ mbedtls_asn1_get_tag(&p, end, &rlen, MBEDTLS_ASN1_INTEGER); -++ r = p; -++ p += rlen; -++ mbedtls_asn1_get_tag(&p, end, &slen, MBEDTLS_ASN1_INTEGER); -++ s = p; -++ -++ /* write raw r and s into out -++ * (including removal of leading 0 if added for ASN.1 integer) -++ * note: DPP caller expects raw r, s each padded to prime len */ -++ mbedtls_ecp_group *ecp_kp_grp = &ecp_kp->MBEDTLS_PRIVATE(grp); -++ size_t plen = CRYPTO_EC_plen(ecp_kp_grp); -++ if (rlen > plen) { -++ r += (rlen - plen); -++ rlen = plen; -++ } -++ if (slen > plen) { -++ s += (slen - plen); -++ slen = plen; -++ } -++ struct wpabuf *out = wpabuf_alloc(plen*2); -++ if (out) { -++ wpabuf_put(out, plen*2); -++ p = wpabuf_mhead_u8(out); -++ os_memset(p, 0, plen*2); -++ os_memcpy(p+plen*1-rlen, r, rlen); -++ os_memcpy(p+plen*2-slen, s, slen); -++ } -++ return out; -++} -++#endif /* CRYPTO_MBEDTLS_CRYPTO_EC_DPP */ -++ -++int crypto_ec_key_verify_signature(struct crypto_ec_key *key, const u8 *data, -++ size_t len, const u8 *sig, size_t sig_len) -++{ -++ switch (mbedtls_pk_verify((mbedtls_pk_context *)key, -++ crypto_ec_key_sign_md(len), data, len, -++ sig, sig_len)) { -++ case 0: -++ /*case MBEDTLS_ERR_ECP_SIG_LEN_MISMATCH:*//* XXX: allow? */ -++ return 1; -++ case MBEDTLS_ERR_ECP_VERIFY_FAILED: -++ return 0; -++ default: -++ return -1; -++ } -++} -++ -++#ifdef CRYPTO_MBEDTLS_CRYPTO_EC_DPP -++int crypto_ec_key_verify_signature_r_s(struct crypto_ec_key *key, -++ const u8 *data, size_t len, -++ const u8 *r, size_t r_len, -++ const u8 *s, size_t s_len) -++{ -++ /* reimplement mbedtls_ecdsa_read_signature() without encoding r and s -++ * into ASN.1 just for mbedtls_ecdsa_read_signature() to decode ASN.1 */ -++ mbedtls_ecp_keypair *ecp_kp = mbedtls_pk_ec(*(mbedtls_pk_context *)key); -++ if (ecp_kp == NULL) -++ return -1; -++ mbedtls_ecp_group *ecp_kp_grp = &ecp_kp->MBEDTLS_PRIVATE(grp); -++ mbedtls_ecp_point *ecp_kp_Q = &ecp_kp->MBEDTLS_PRIVATE(Q); -++ -++ mbedtls_mpi mpi_r; -++ mbedtls_mpi mpi_s; -++ mbedtls_mpi_init(&mpi_r); -++ mbedtls_mpi_init(&mpi_s); -++ int ret = mbedtls_mpi_read_binary(&mpi_r, r, r_len) -++ || mbedtls_mpi_read_binary(&mpi_s, s, s_len) ? -1 : 0; -++ if (ret == 0) { -++ ret = mbedtls_ecdsa_verify(ecp_kp_grp, data, len, -++ ecp_kp_Q, &mpi_r, &mpi_s); -++ ret = ret ? ret == MBEDTLS_ERR_ECP_BAD_INPUT_DATA ? 0 : -1 : 1; -++ } -++ mbedtls_mpi_free(&mpi_r); -++ mbedtls_mpi_free(&mpi_s); -++ return ret; -++} -++#endif /* CRYPTO_MBEDTLS_CRYPTO_EC_DPP */ -++ -++int crypto_ec_key_group(struct crypto_ec_key *key) -++{ -++ mbedtls_ecp_keypair *ecp_kp = mbedtls_pk_ec(*(mbedtls_pk_context *)key); -++ if (ecp_kp == NULL) -++ return -1; -++ mbedtls_ecp_group *ecp_group = &ecp_kp->MBEDTLS_PRIVATE(grp); -++ return crypto_mbedtls_ike_id_from_ecp_group_id(ecp_group->id); -++} -++ -++#ifdef CRYPTO_MBEDTLS_CRYPTO_EC_DPP -++ -++int crypto_ec_key_cmp(struct crypto_ec_key *key1, struct crypto_ec_key *key2) -++{ -++#if 0 /*(DPP is passing two public keys; unable to use pk_check_pair())*/ -++ #if MBEDTLS_VERSION_NUMBER < 0x03000000 /* mbedtls 3.0.0 */ -++ return mbedtls_pk_check_pair((const mbedtls_pk_context *)key1, -++ (const mbedtls_pk_context *)key2) ? -1 : 0; -++ #else -++ return mbedtls_pk_check_pair((const mbedtls_pk_context *)key1, -++ (const mbedtls_pk_context *)key2, -++ mbedtls_ctr_drbg_random, -++ crypto_mbedtls_ctr_drbg()) ? -1 : 0; -++ #endif -++#else -++ mbedtls_ecp_keypair *ecp_kp1=mbedtls_pk_ec(*(mbedtls_pk_context *)key1); -++ mbedtls_ecp_keypair *ecp_kp2=mbedtls_pk_ec(*(mbedtls_pk_context *)key2); -++ if (ecp_kp1 == NULL || ecp_kp2 == NULL) -++ return -1; -++ mbedtls_ecp_group *ecp_kp1_grp = &ecp_kp1->MBEDTLS_PRIVATE(grp); -++ mbedtls_ecp_group *ecp_kp2_grp = &ecp_kp2->MBEDTLS_PRIVATE(grp); -++ mbedtls_ecp_point *ecp_kp1_Q = &ecp_kp1->MBEDTLS_PRIVATE(Q); -++ mbedtls_ecp_point *ecp_kp2_Q = &ecp_kp2->MBEDTLS_PRIVATE(Q); -++ return ecp_kp1_grp->id != ecp_kp2_grp->id -++ || mbedtls_ecp_point_cmp(ecp_kp1_Q, ecp_kp2_Q) ? -1 : 0; -++#endif -++} -++ -++void crypto_ec_key_debug_print(const struct crypto_ec_key *key, -++ const char *title) -++{ -++ /* TBD: what info is desirable here and in what human readable format?*/ -++ /*(crypto_openssl.c prints a human-readably public key and attributes)*/ -++ #if 0 -++ struct mbedtls_pk_debug_item debug_item; -++ if (mbedtls_pk_debug((const mbedtls_pk_context *)key, &debug_item)) -++ return; -++ /* ... */ -++ #endif -++ wpa_printf(MSG_DEBUG, "%s: %s not implemented", title, __func__); -++} -++ -++#endif /* CRYPTO_MBEDTLS_CRYPTO_EC_DPP */ -++ -++#endif /* CRYPTO_MBEDTLS_CRYPTO_EC */ -++ -++ -++#ifdef CRYPTO_MBEDTLS_CRYPTO_CSR -++ -++#include -++#include -++ -++struct crypto_csr * crypto_csr_init(void) -++{ -++ mbedtls_x509write_csr *csr = os_malloc(sizeof(*csr)); -++ if (csr != NULL) -++ mbedtls_x509write_csr_init(csr); -++ return (struct crypto_csr *)csr; -++} -++ -++struct crypto_csr * crypto_csr_verify(const struct wpabuf *req) -++{ -++ /* future: look for alternatives to MBEDTLS_PRIVATE() access */ -++ -++ /* sole caller src/common/dpp_crypto.c:dpp_validate_csr() -++ * uses (mbedtls_x509_csr *) to obtain CSR_ATTR_CHALLENGE_PASSWORD -++ * so allocate different object (mbedtls_x509_csr *) and special-case -++ * object when used in crypto_csr_get_attribute() and when free()d in -++ * crypto_csr_deinit(). */ -++ -++ mbedtls_x509_csr *csr = os_malloc(sizeof(*csr)); -++ if (csr == NULL) -++ return NULL; -++ mbedtls_x509_csr_init(csr); -++ const mbedtls_md_info_t *md_info; -++ unsigned char digest[MBEDTLS_MD_MAX_SIZE]; -++ if (mbedtls_x509_csr_parse_der(csr,wpabuf_head(req),wpabuf_len(req))==0 -++ && (md_info=mbedtls_md_info_from_type(csr->MBEDTLS_PRIVATE(sig_md))) -++ != NULL -++ && mbedtls_md(md_info, csr->cri.p, csr->cri.len, digest) == 0) { -++ switch (mbedtls_pk_verify(&csr->pk,csr->MBEDTLS_PRIVATE(sig_md), -++ digest, mbedtls_md_get_size(md_info), -++ csr->MBEDTLS_PRIVATE(sig).p, -++ csr->MBEDTLS_PRIVATE(sig).len)) { -++ case 0: -++ /*case MBEDTLS_ERR_ECP_SIG_LEN_MISMATCH:*//* XXX: allow? */ -++ return (struct crypto_csr *)((uintptr_t)csr | 1uL); -++ default: -++ break; -++ } -++ } -++ -++ mbedtls_x509_csr_free(csr); -++ os_free(csr); -++ return NULL; -++} -++ -++void crypto_csr_deinit(struct crypto_csr *csr) -++{ -++ if ((uintptr_t)csr & 1uL) { -++ csr = (struct crypto_csr *)((uintptr_t)csr & ~1uL); -++ mbedtls_x509_csr_free((mbedtls_x509_csr *)csr); -++ } -++ else -++ mbedtls_x509write_csr_free((mbedtls_x509write_csr *)csr); -++ os_free(csr); -++} -++ -++int crypto_csr_set_ec_public_key(struct crypto_csr *csr, -++ struct crypto_ec_key *key) -++{ -++ mbedtls_x509write_csr_set_key((mbedtls_x509write_csr *)csr, -++ (mbedtls_pk_context *)key); -++ return 0; -++} -++ -++int crypto_csr_set_name(struct crypto_csr *csr, enum crypto_csr_name type, -++ const char *name) -++{ -++ /* specialized for src/common/dpp_crypto.c */ -++ -++ /* sole caller src/common/dpp_crypto.c:dpp_build_csr() -++ * calls this function only once, using type == CSR_NAME_CN -++ * (If called more than once, this code would need to append -++ * components to the subject name, which we could do by -++ * appending to (mbedtls_x509write_csr *) private member -++ * mbedtls_asn1_named_data *MBEDTLS_PRIVATE(subject)) */ -++ -++ const char *label; -++ switch (type) { -++ case CSR_NAME_CN: label = "CN="; break; -++ case CSR_NAME_SN: label = "SN="; break; -++ case CSR_NAME_C: label = "C="; break; -++ case CSR_NAME_O: label = "O="; break; -++ case CSR_NAME_OU: label = "OU="; break; -++ default: return -1; -++ } -++ -++ size_t len = strlen(name); -++ struct wpabuf *buf = wpabuf_alloc(3+len+1); -++ if (buf == NULL) -++ return -1; -++ wpabuf_put_data(buf, label, strlen(label)); -++ wpabuf_put_data(buf, name, len+1); /*(include trailing '\0')*/ -++ /* Note: 'name' provided is set as given and should be backslash-escaped -++ * by caller when necessary, e.g. literal ',' which are not separating -++ * components should be backslash-escaped */ -++ -++ int ret = -++ mbedtls_x509write_csr_set_subject_name((mbedtls_x509write_csr *)csr, -++ wpabuf_head(buf)) ? -1 : 0; -++ wpabuf_free(buf); -++ return ret; -++} -++ -++/* OBJ_pkcs9_challengePassword 1 2 840 113549 1 9 7 */ -++static const char OBJ_pkcs9_challengePassword[] = MBEDTLS_OID_PKCS9 "\x07"; -++ -++int crypto_csr_set_attribute(struct crypto_csr *csr, enum crypto_csr_attr attr, -++ int attr_type, const u8 *value, size_t len) -++{ -++ /* specialized for src/common/dpp_crypto.c */ -++ /* sole caller src/common/dpp_crypto.c:dpp_build_csr() passes -++ * attr == CSR_ATTR_CHALLENGE_PASSWORD -++ * attr_type == ASN1_TAG_UTF8STRING */ -++ -++ const char *oid; -++ size_t oid_len; -++ switch (attr) { -++ case CSR_ATTR_CHALLENGE_PASSWORD: -++ oid = OBJ_pkcs9_challengePassword; -++ oid_len = sizeof(OBJ_pkcs9_challengePassword)-1; -++ break; -++ default: -++ return -1; -++ } -++ -++ #if 0 /*(incorrect; sets an extension, not an attribute)*/ -++ return mbedtls_x509write_csr_set_extension((mbedtls_x509write_csr *)csr, -++ oid, oid_len, -++ #if MBEDTLS_VERSION_NUMBER >= 0x03000000 /* mbedtls 3.0.0 */ -++ 0, /*(critical flag)*/ -++ #endif -++ value, len) ? -1 : 0; -++ #else -++ (void)oid; -++ (void)oid_len; -++ #endif -++ -++ /* mbedtls does not currently provide way to set an attribute in a CSR: -++ * https://github.com/Mbed-TLS/mbedtls/issues/4886 */ -++ wpa_printf(MSG_ERROR, -++ "mbedtls does not currently support setting challengePassword " -++ "attribute in CSR"); -++ return -1; -++} -++ -++const u8 * mbedtls_x509_csr_attr_oid_value(mbedtls_x509_csr *csr, -++ const char *oid, size_t oid_len, -++ size_t *vlen, int *vtype) -++{ -++ /* Note: mbedtls_x509_csr_parse_der() has parsed and validated CSR, -++ * so validation checks are not repeated here -++ * -++ * It would be nicer if (mbedtls_x509_csr *) had an mbedtls_x509_buf of -++ * Attributes (or at least a pointer) since mbedtls_x509_csr_parse_der() -++ * already parsed the rest of CertificationRequestInfo, some of which is -++ * repeated here to step to Attributes. Since csr->subject_raw.p points -++ * into csr->cri.p, which points into csr->raw.p, step over version and -++ * subject of CertificationRequestInfo (SEQUENCE) */ -++ unsigned char *p = csr->subject_raw.p + csr->subject_raw.len; -++ unsigned char *end = csr->cri.p + csr->cri.len, *ext; -++ size_t len; -++ -++ /* step over SubjectPublicKeyInfo */ -++ mbedtls_asn1_get_tag(&p, end, &len, -++ MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE); -++ p += len; -++ -++ /* Attributes -++ * { ATTRIBUTE:IOSet } ::= SET OF { SEQUENCE { OID, value } } -++ */ -++ if (mbedtls_asn1_get_tag(&p, end, &len, -++ MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_CONTEXT_SPECIFIC) != 0) { -++ return NULL; -++ } -++ while (p < end) { -++ if (mbedtls_asn1_get_tag(&p, end, &len, -++ MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE) != 0) { -++ return NULL; -++ } -++ ext = p; -++ p += len; -++ -++ if (mbedtls_asn1_get_tag(&ext,end,&len,MBEDTLS_ASN1_OID) != 0) -++ return NULL; -++ if (oid_len != len || 0 != memcmp(ext, oid, oid_len)) -++ continue; -++ -++ /* found oid; return value */ -++ *vtype = *ext++; /* tag */ -++ return (mbedtls_asn1_get_len(&ext,end,vlen) == 0) ? ext : NULL; -++ } -++ -++ return NULL; -++} -++ -++const u8 * crypto_csr_get_attribute(struct crypto_csr *csr, -++ enum crypto_csr_attr attr, -++ size_t *len, int *type) -++{ -++ /* specialized for src/common/dpp_crypto.c */ -++ /* sole caller src/common/dpp_crypto.c:dpp_build_csr() passes -++ * attr == CSR_ATTR_CHALLENGE_PASSWORD */ -++ -++ const char *oid; -++ size_t oid_len; -++ switch (attr) { -++ case CSR_ATTR_CHALLENGE_PASSWORD: -++ oid = OBJ_pkcs9_challengePassword; -++ oid_len = sizeof(OBJ_pkcs9_challengePassword)-1; -++ break; -++ default: -++ return NULL; -++ } -++ -++ /* see crypto_csr_verify(); expecting (mbedtls_x509_csr *) tagged |=1 */ -++ if (!((uintptr_t)csr & 1uL)) -++ return NULL; -++ csr = (struct crypto_csr *)((uintptr_t)csr & ~1uL); -++ -++ return mbedtls_x509_csr_attr_oid_value((mbedtls_x509_csr *)csr, -++ oid, oid_len, len, type); -++} -++ -++struct wpabuf * crypto_csr_sign(struct crypto_csr *csr, -++ struct crypto_ec_key *key, -++ enum crypto_hash_alg algo) -++{ -++ mbedtls_md_type_t sig_md; -++ switch (algo) { -++ #ifdef MBEDTLS_SHA256_C -++ case CRYPTO_HASH_ALG_SHA256: sig_md = MBEDTLS_MD_SHA256; break; -++ #endif -++ #ifdef MBEDTLS_SHA512_C -++ case CRYPTO_HASH_ALG_SHA384: sig_md = MBEDTLS_MD_SHA384; break; -++ case CRYPTO_HASH_ALG_SHA512: sig_md = MBEDTLS_MD_SHA512; break; -++ #endif -++ default: -++ return NULL; -++ } -++ mbedtls_x509write_csr_set_md_alg((mbedtls_x509write_csr *)csr, sig_md); -++ -++ #if 0 -++ unsigned char key_usage = MBEDTLS_X509_KU_DIGITAL_SIGNATURE -++ | MBEDTLS_X509_KU_KEY_CERT_SIGN; -++ if (mbedtls_x509write_csr_set_key_usage((mbedtls_x509write_csr *)csr, -++ key_usage)) -++ return NULL; -++ #endif -++ -++ #if 0 -++ unsigned char ns_cert_type = MBEDTLS_X509_NS_CERT_TYPE_SSL_CLIENT -++ | MBEDTLS_X509_NS_CERT_TYPE_EMAIL; -++ if (mbedtls_x509write_csr_set_ns_cert_type((mbedtls_x509write_csr *)csr, -++ ns_cert_type)) -++ return NULL; -++ #endif -++ -++ #if 0 -++ /* mbedtls does not currently provide way to set an attribute in a CSR: -++ * https://github.com/Mbed-TLS/mbedtls/issues/4886 -++ * XXX: hwsim dpp_enterprise test fails due to this limitation. -++ * -++ * Current usage of this function is solely by dpp_build_csr(), -++ * so as a kludge, might consider custom (struct crypto_csr *) -++ * containing (mbedtls_x509write_csr *) and a list of attributes -++ * (i.e. challengePassword). Might have to totally reimplement -++ * mbedtls_x509write_csr_der(); underlying x509write_csr_der_internal() -++ * handles signing the CSR. (This is more work that appending an -++ * Attributes section to end of CSR and adjusting ASN.1 length of CSR.) -++ */ -++ #endif -++ -++ unsigned char buf[4096]; /* XXX: large enough? too large? */ -++ int len = mbedtls_x509write_csr_der((mbedtls_x509write_csr *)csr, -++ buf, sizeof(buf), -++ mbedtls_ctr_drbg_random, -++ crypto_mbedtls_ctr_drbg()); -++ if (len < 0) -++ return NULL; -++ /* Note: data is written at the end of the buffer! Use the -++ * return value to determine where you should start -++ * using the buffer */ -++ return wpabuf_alloc_copy(buf+sizeof(buf)-len, (size_t)len); -++} -++ -++#endif /* CRYPTO_MBEDTLS_CRYPTO_CSR */ -++ -++ -++#ifdef CRYPTO_MBEDTLS_CRYPTO_PKCS7 -++ -++#if 0 -++#include /* PKCS7 is not currently supported in mbedtls */ -++#include -++#endif -++ -++struct wpabuf * crypto_pkcs7_get_certificates(const struct wpabuf *pkcs7) -++{ -++ /* PKCS7 is not currently supported in mbedtls */ -++ return NULL; -++ -++#if 0 -++ /* https://github.com/naynajain/mbedtls-1 branch: development-pkcs7 -++ * (??? potential future contribution to mbedtls ???) */ -++ -++ /* Note: PKCS7 signature *is not* verified by this function. -++ * The function interface does not provide for passing a certificate */ -++ -++ mbedtls_pkcs7 mpkcs7; -++ mbedtls_pkcs7_init(&mpkcs7); -++ int pkcs7_type = mbedtls_pkcs7_parse_der(wpabuf_head(pkcs7), -++ wpabuf_len(pkcs7), -++ &mpkcs7); -++ wpabuf *buf = NULL; -++ do { -++ if (pkcs7_type < 0) -++ break; -++ -++ /* src/common/dpp.c:dpp_parse_cred_dot1x() interested in certs -++ * for wpa_supplicant/dpp_supplicant.c:wpas_dpp_add_network() -++ * (? are adding certificate headers and footers desired ?) */ -++ -++ /* development-pkcs7 branch does not currently provide -++ * additional interfaces to retrieve the parsed data */ -++ -++ mbedtls_x509_crt *certs = -++ &mpkcs7.MBEDTLS_PRIVATE(signed_data).MBEDTLS_PRIVATE(certs); -++ int ncerts = -++ mpkcs7.MBEDTLS_PRIVATE(signed_data).MBEDTLS_PRIVATE(no_of_certs); -++ -++ /* allocate buffer for PEM (base64-encoded DER) -++ * plus header, footer, newlines, and some extra */ -++ buf = wpabuf_alloc((wpabuf_len(pkcs7)+2)/3*4 + ncerts*64); -++ if (buf == NULL) -++ break; -++ -++ #define PEM_BEGIN_CRT "-----BEGIN CERTIFICATE-----\n" -++ #define PEM_END_CRT "-----END CERTIFICATE-----\n" -++ size_t olen; -++ for (int i = 0; i < ncerts; ++i) { -++ int ret = mbedtls_pem_write_buffer( -++ PEM_BEGIN_CRT, PEM_END_CRT, -++ certs[i].raw.p, certs[i].raw.len, -++ wpabuf_mhead(buf, 0), wpabuf_tailroom(buf), -++ &olen)); -++ if (ret == 0) -++ wpabuf_put(buf, olen); -++ } else { -++ if (ret == MBEDTLS_ERR_BASE64_BUFFER_TOO_SMALL) -++ ret = wpabuf_resize( -++ &buf,olen-wpabuf_tailroom(buf)); -++ if (ret == 0) { -++ --i;/*(adjust loop iterator for retry)*/ -++ continue; -++ } -++ wpabuf_free(buf); -++ buf = NULL; -++ break; -++ } -++ } -++ } while (0); -++ -++ mbedtls_pkcs7_free(&mpkcs7); -++ return buf; -++#endif -++} -++ -++#endif /* CRYPTO_MBEDTLS_CRYPTO_PKCS7 */ -++ -++ -++#ifdef MBEDTLS_ARC4_C -++#include -++int rc4_skip(const u8 *key, size_t keylen, size_t skip, -++ u8 *data, size_t data_len) -++{ -++ mbedtls_arc4_context ctx; -++ mbedtls_arc4_init(&ctx); -++ mbedtls_arc4_setup(&ctx, key, keylen); -++ -++ if (skip) { -++ /*(prefer [16] on ancient hardware with smaller cache lines)*/ -++ unsigned char skip_buf[64]; /*('skip' is generally small)*/ -++ /*os_memset(skip_buf, 0, sizeof(skip_buf));*/ /*(necessary?)*/ -++ size_t len; -++ do { -++ len = skip > sizeof(skip_buf) ? sizeof(skip_buf) : skip; -++ mbedtls_arc4_crypt(&ctx, len, skip_buf, skip_buf); -++ } while ((skip -= len)); -++ } -++ -++ int ret = mbedtls_arc4_crypt(&ctx, data_len, data, data); -++ mbedtls_arc4_free(&ctx); -++ return ret; -++} -++#endif -++ -++ -++/* duplicated in tls_mbedtls.c:tls_mbedtls_readfile()*/ -++__attribute_noinline__ -++static int crypto_mbedtls_readfile(const char *path, u8 **buf, size_t *n) -++{ -++ #if 0 /* #ifdef MBEDTLS_FS_IO */ -++ /*(includes +1 for '\0' needed by mbedtls PEM parsing funcs)*/ -++ if (mbedtls_pk_load_file(path, (unsigned char **)buf, n) != 0) { -++ wpa_printf(MSG_ERROR, "error: mbedtls_pk_load_file %s", path); -++ return -1; -++ } -++ #else -++ /*(use os_readfile() so that we can use os_free() -++ *(if we use mbedtls_pk_load_file() above, macros prevent calling free() -++ * directly #if defined(OS_REJECT_C_LIB_FUNCTIONS) and calling os_free() -++ * on buf aborts in tests if buf not allocated via os_malloc())*/ -++ *buf = (u8 *)os_readfile(path, n); -++ if (!*buf) { -++ wpa_printf(MSG_ERROR, "error: os_readfile %s", path); -++ return -1; -++ } -++ u8 *buf0 = os_realloc(*buf, *n+1); -++ if (!buf0) { -++ bin_clear_free(*buf, *n); -++ *buf = NULL; -++ return -1; -++ } -++ buf0[(*n)++] = '\0'; -++ *buf = buf0; -++ #endif -++ return 0; -++} -++ -++ -++#ifdef CRYPTO_MBEDTLS_CRYPTO_RSA -++#ifdef MBEDTLS_RSA_C -++ -++#include -++#include -++ -++struct crypto_rsa_key * crypto_rsa_key_read(const char *file, bool private_key) -++{ -++ /* mbedtls_pk_parse_keyfile() and mbedtls_pk_parse_public_keyfile() -++ * require #ifdef MBEDTLS_FS_IO in mbedtls library. Prefer to use -++ * crypto_mbedtls_readfile(), which wraps os_readfile() */ -++ u8 *data; -++ size_t len; -++ if (crypto_mbedtls_readfile(file, &data, &len) != 0) -++ return NULL; -++ -++ mbedtls_pk_context *ctx = os_malloc(sizeof(*ctx)); -++ if (ctx == NULL) { -++ bin_clear_free(data, len); -++ return NULL; -++ } -++ mbedtls_pk_init(ctx); -++ -++ int rc; -++ rc = (private_key -++ ? mbedtls_pk_parse_key(ctx, data, len, NULL, 0 -++ #if MBEDTLS_VERSION_NUMBER >= 0x03000000 /* mbedtls 3.0.0 */ -++ ,mbedtls_ctr_drbg_random, -++ crypto_mbedtls_ctr_drbg() -++ #endif -++ ) -++ : mbedtls_pk_parse_public_key(ctx, data, len)) == 0 -++ && mbedtls_pk_can_do(ctx, MBEDTLS_PK_RSA); -++ -++ bin_clear_free(data, len); -++ -++ if (rc) { -++ /* use MBEDTLS_RSA_PKCS_V21 padding for RSAES-OAEP */ -++ /* use MBEDTLS_MD_SHA256 for these hostap interfaces */ -++ #if MBEDTLS_VERSION_NUMBER < 0x03000000 /* mbedtls 3.0.0 */ -++ /*(no return value in mbedtls 2.x)*/ -++ mbedtls_rsa_set_padding(mbedtls_pk_rsa(*ctx), -++ MBEDTLS_RSA_PKCS_V21, -++ MBEDTLS_MD_SHA256); -++ #else -++ if (mbedtls_rsa_set_padding(mbedtls_pk_rsa(*ctx), -++ MBEDTLS_RSA_PKCS_V21, -++ MBEDTLS_MD_SHA256) == 0) -++ #endif -++ return (struct crypto_rsa_key *)ctx; -++ } -++ -++ mbedtls_pk_free(ctx); -++ os_free(ctx); -++ return NULL; -++} -++ -++struct wpabuf * crypto_rsa_oaep_sha256_encrypt(struct crypto_rsa_key *key, -++ const struct wpabuf *in) -++{ -++ mbedtls_rsa_context *pk_rsa = mbedtls_pk_rsa(*(mbedtls_pk_context*)key); -++ size_t olen = mbedtls_rsa_get_len(pk_rsa); -++ struct wpabuf *buf = wpabuf_alloc(olen); -++ if (buf == NULL) -++ return NULL; -++ -++ /* mbedtls_pk_encrypt() takes a few more hops to get to same func */ -++ if (mbedtls_rsa_rsaes_oaep_encrypt(pk_rsa, -++ mbedtls_ctr_drbg_random, -++ crypto_mbedtls_ctr_drbg(), -++ #if MBEDTLS_VERSION_NUMBER < 0x03000000 /* mbedtls 3.0.0 */ -++ MBEDTLS_RSA_PRIVATE, -++ #endif -++ NULL, 0, -++ wpabuf_len(in), wpabuf_head(in), -++ wpabuf_put(buf, olen)) == 0) { -++ return buf; -++ } -++ -++ wpabuf_clear_free(buf); -++ return NULL; -++} -++ -++struct wpabuf * crypto_rsa_oaep_sha256_decrypt(struct crypto_rsa_key *key, -++ const struct wpabuf *in) -++{ -++ mbedtls_rsa_context *pk_rsa = mbedtls_pk_rsa(*(mbedtls_pk_context*)key); -++ size_t olen = mbedtls_rsa_get_len(pk_rsa); -++ struct wpabuf *buf = wpabuf_alloc(olen); -++ if (buf == NULL) -++ return NULL; -++ -++ /* mbedtls_pk_decrypt() takes a few more hops to get to same func */ -++ if (mbedtls_rsa_rsaes_oaep_decrypt(pk_rsa, -++ mbedtls_ctr_drbg_random, -++ crypto_mbedtls_ctr_drbg(), -++ #if MBEDTLS_VERSION_NUMBER < 0x03000000 /* mbedtls 3.0.0 */ -++ MBEDTLS_RSA_PUBLIC, -++ #endif -++ NULL, 0, &olen, wpabuf_head(in), -++ wpabuf_mhead(buf), olen) == 0) { -++ wpabuf_put(buf, olen); -++ return buf; -++ } -++ -++ wpabuf_clear_free(buf); -++ return NULL; -++} -++ -++void crypto_rsa_key_free(struct crypto_rsa_key *key) -++{ -++ mbedtls_pk_free((mbedtls_pk_context *)key); -++ os_free(key); -++} -++ -++#endif /* MBEDTLS_RSA_C */ -++#endif /* CRYPTO_MBEDTLS_CRYPTO_RSA */ -++ -++#ifdef CRYPTO_MBEDTLS_CRYPTO_HPKE -++ -++struct wpabuf * hpke_base_seal(enum hpke_kem_id kem_id, -++ enum hpke_kdf_id kdf_id, -++ enum hpke_aead_id aead_id, -++ struct crypto_ec_key *peer_pub, -++ const u8 *info, size_t info_len, -++ const u8 *aad, size_t aad_len, -++ const u8 *pt, size_t pt_len) -++{ -++ /* not yet implemented */ -++ return NULL; -++} -++ -++struct wpabuf * hpke_base_open(enum hpke_kem_id kem_id, -++ enum hpke_kdf_id kdf_id, -++ enum hpke_aead_id aead_id, -++ struct crypto_ec_key *own_priv, -++ const u8 *info, size_t info_len, -++ const u8 *aad, size_t aad_len, -++ const u8 *enc_ct, size_t enc_ct_len) -++{ -++ /* not yet implemented */ -++ return NULL; -++} -++ -++#endif -+--- /dev/null -++++ b/src/crypto/tls_mbedtls.c -+@@ -0,0 +1,3313 @@ -++/* -++ * SSL/TLS interface functions for mbed TLS -++ * -++ * SPDX-FileCopyrightText: 2022 Glenn Strauss -++ * SPDX-License-Identifier: BSD-3-Clause -++ * -++ * This software may be distributed under the terms of the BSD license. -++ * See README for more details. -++ * -++ * template: src/crypto/tls_none.c -++ * reference: src/crypto/tls_*.c -++ * -++ * Known Limitations: -++ * - no TLSv1.3 (not available in mbedtls 2.x; experimental in mbedtls 3.x) -++ * - no OCSP (not yet available in mbedtls) -++ * - mbedtls does not support all certificate encodings used by hwsim tests -++ * PCKS#5 v1.5 -++ * PCKS#12 -++ * DH DSA -++ * - EAP-FAST, EAP-TEAP session ticket support not implemented in tls_mbedtls.c -++ * - mbedtls does not currently provide way to set an attribute in a CSR -++ * https://github.com/Mbed-TLS/mbedtls/issues/4886 -++ * so tests/hwsim dpp_enterprise tests fail -++ * - DPP2 not supported -++ * PKCS#7 parsing is not supported in mbedtls -++ * See crypto_mbedtls.c:crypto_pkcs7_get_certificates() comments -++ * - DPP3 not supported -++ * hpke_base_seal() and hpke_base_seal() not implemented in crypto_mbedtls.c -++ * -++ * Status: -++ * - code written to be compatible with mbedtls 2.x and mbedtls 3.x -++ * (currently requires mbedtls >= 2.27.0 for mbedtls_mpi_random()) -++ * (currently requires mbedtls >= 2.18.0 for mbedtls_ssl_tls_prf()) -++ * - builds with tests/build/build-wpa_supplicant-mbedtls.config -++ * - passes all tests/ crypto module tests (incomplete coverage) -++ * ($ cd tests; make clean; make -j 4 run-tests CONFIG_TLS=mbedtls) -++ * - passes almost all tests/hwsim tests -++ * (hwsim tests skipped for missing features) -++ * -++ * RFE: -++ * - EAP-FAST, EAP-TEAP session ticket support not implemented in tls_mbedtls.c -++ * - client/server session resumption, and/or save client session ticket -++ */ -++ -++#include "includes.h" -++#include "common.h" -++ -++#include -++#include -++#include -++#include -++#include -++#include /* mbedtls_calloc() mbedtls_free() */ -++#include /* mbedtls_platform_zeroize() */ -++#include -++#include -++#include -++#include -++ -++#if MBEDTLS_VERSION_NUMBER >= 0x02040000 /* mbedtls 2.4.0 */ -++#include -++#else -++#include -++#endif -++ -++#ifndef MBEDTLS_PRIVATE -++#define MBEDTLS_PRIVATE(x) x -++#endif -++ -++#if MBEDTLS_VERSION_NUMBER < 0x03020000 /* mbedtls 3.2.0 */ -++#define mbedtls_ssl_get_ciphersuite_id_from_ssl(ssl) \ -++ ((ssl)->MBEDTLS_PRIVATE(session) \ -++ ?(ssl)->MBEDTLS_PRIVATE(session)->MBEDTLS_PRIVATE(ciphersuite) \ -++ : 0) -++#define mbedtls_ssl_ciphersuite_get_name(info) \ -++ (info)->MBEDTLS_PRIVATE(name) -++#endif -++ -++#include "crypto.h" /* sha256_vector() */ -++#include "tls.h" -++ -++#ifndef SHA256_DIGEST_LENGTH -++#define SHA256_DIGEST_LENGTH 32 -++#endif -++ -++#ifndef MBEDTLS_EXPKEY_FIXED_SECRET_LEN -++#define MBEDTLS_EXPKEY_FIXED_SECRET_LEN 48 -++#endif -++ -++#ifndef MBEDTLS_EXPKEY_RAND_LEN -++#define MBEDTLS_EXPKEY_RAND_LEN 32 -++#endif -++ -++#if MBEDTLS_VERSION_NUMBER >= 0x03000000 /* mbedtls 3.0.0 */ -++static mbedtls_ssl_export_keys_t tls_connection_export_keys_cb; -++#elif MBEDTLS_VERSION_NUMBER >= 0x02120000 /* mbedtls 2.18.0 */ -++static mbedtls_ssl_export_keys_ext_t tls_connection_export_keys_cb; -++#else /*(not implemented; return error)*/ -++#define mbedtls_ssl_tls_prf(a,b,c,d,e,f,g,h) (-1) -++typedef mbedtls_tls_prf_types int; -++#endif -++ -++ -++/* hostapd/wpa_supplicant provides forced_memzero(), -++ * but prefer mbedtls_platform_zeroize() */ -++#define forced_memzero(ptr,sz) mbedtls_platform_zeroize(ptr,sz) -++ -++ -++#if defined(EAP_FAST) || defined(EAP_FAST_DYNAMIC) || defined(EAP_SERVER_FAST) \ -++ || defined(EAP_TEAP) || defined(EAP_SERVER_TEAP) -++#ifdef MBEDTLS_SSL_SESSION_TICKETS -++#ifdef MBEDTLS_SSL_TICKET_C -++#define TLS_MBEDTLS_SESSION_TICKETS -++#if defined(EAP_TEAP) || defined(EAP_SERVER_TEAP) -++#define TLS_MBEDTLS_EAP_TEAP -++#endif -++#if !defined(CONFIG_FIPS) /* EAP-FAST keys cannot be exported in FIPS mode */ -++#if defined(EAP_FAST) || defined(EAP_FAST_DYNAMIC) || defined(EAP_SERVER_FAST) -++#define TLS_MBEDTLS_EAP_FAST -++#endif -++#endif -++#endif -++#endif -++#endif -++ -++ -++struct tls_conf { -++ mbedtls_ssl_config conf; -++ -++ unsigned int verify_peer:1; -++ unsigned int verify_depth0_only:1; -++ unsigned int check_crl:2; /*(needs :2 bits for 0, 1, 2)*/ -++ unsigned int check_crl_strict:1; /*(needs :1 bit for 0, 1)*/ -++ unsigned int ca_cert_probe:1; -++ unsigned int has_ca_cert:1; -++ unsigned int has_client_cert:1; -++ unsigned int has_private_key:1; -++ unsigned int suiteb128:1; -++ unsigned int suiteb192:1; -++ mbedtls_x509_crl *crl; -++ mbedtls_x509_crt ca_cert; -++ mbedtls_x509_crt client_cert; -++ mbedtls_pk_context private_key; -++ -++ uint32_t refcnt; -++ -++ unsigned int flags; -++ char *subject_match; -++ char *altsubject_match; -++ char *suffix_match; -++ char *domain_match; -++ char *check_cert_subject; -++ u8 ca_cert_hash[SHA256_DIGEST_LENGTH]; -++ -++ int *ciphersuites; /* list of ciphersuite ids for mbedtls_ssl_config */ -++#if MBEDTLS_VERSION_NUMBER < 0x03010000 /* mbedtls 3.1.0 */ -++ mbedtls_ecp_group_id *curves; -++#else -++ uint16_t *curves; /* list of curve ids for mbedtls_ssl_config */ -++#endif -++}; -++ -++ -++struct tls_global { -++ struct tls_conf *tls_conf; -++ char *ocsp_stapling_response; -++ mbedtls_ctr_drbg_context *ctr_drbg; /*(see crypto_mbedtls.c)*/ -++ #ifdef MBEDTLS_SSL_SESSION_TICKETS -++ mbedtls_ssl_ticket_context ticket_ctx; -++ #endif -++ char *ca_cert_file; -++ struct os_reltime crl_reload_previous; -++ unsigned int crl_reload_interval; -++ uint32_t refcnt; -++ struct tls_config init_conf; -++}; -++ -++static struct tls_global tls_ctx_global; -++ -++ -++struct tls_connection { -++ struct tls_conf *tls_conf; -++ struct wpabuf *push_buf; -++ struct wpabuf *pull_buf; -++ size_t pull_buf_offset; -++ -++ unsigned int established:1; -++ unsigned int resumed:1; -++ unsigned int verify_peer:1; -++ unsigned int is_server:1; -++ -++ mbedtls_ssl_context ssl; -++ -++ mbedtls_tls_prf_types tls_prf_type; -++ size_t expkey_keyblock_size; -++ size_t expkey_secret_len; -++ #if MBEDTLS_VERSION_NUMBER < 0x03000000 /* mbedtls 3.0.0 */ -++ unsigned char expkey_secret[MBEDTLS_EXPKEY_FIXED_SECRET_LEN]; -++ #else -++ unsigned char expkey_secret[MBEDTLS_MD_MAX_SIZE]; -++ #endif -++ unsigned char expkey_randbytes[MBEDTLS_EXPKEY_RAND_LEN*2]; -++ -++ int read_alerts, write_alerts, failed; -++ -++ #ifdef TLS_MBEDTLS_SESSION_TICKETS -++ tls_session_ticket_cb session_ticket_cb; -++ void *session_ticket_cb_ctx; -++ unsigned char *clienthello_session_ticket; -++ size_t clienthello_session_ticket_len; -++ #endif -++ char *peer_subject; /* peer subject info for authenticated peer */ -++ struct wpabuf *success_data; -++}; -++ -++ -++#ifndef __has_attribute -++#define __has_attribute(x) 0 -++#endif -++ -++#ifndef __GNUC_PREREQ -++#define __GNUC_PREREQ(maj,min) 0 -++#endif -++ -++#ifndef __attribute_cold__ -++#if __has_attribute(cold) \ -++ || __GNUC_PREREQ(4,3) -++#define __attribute_cold__ __attribute__((__cold__)) -++#else -++#define __attribute_cold__ -++#endif -++#endif -++ -++#ifndef __attribute_noinline__ -++#if __has_attribute(noinline) \ -++ || __GNUC_PREREQ(3,1) -++#define __attribute_noinline__ __attribute__((__noinline__)) -++#else -++#define __attribute_noinline__ -++#endif -++#endif -++ -++ -++__attribute_cold__ -++__attribute_noinline__ -++static void emsg(int level, const char * const msg) -++{ -++ wpa_printf(level, "MTLS: %s", msg); -++} -++ -++ -++__attribute_cold__ -++__attribute_noinline__ -++static void emsgrc(int level, const char * const msg, int rc) -++{ -++ #ifdef MBEDTLS_ERROR_C -++ /* error logging convenience function that decodes mbedtls result codes */ -++ char buf[256]; -++ mbedtls_strerror(rc, buf, sizeof(buf)); -++ wpa_printf(level, "MTLS: %s: %s (-0x%04x)", msg, buf, -rc); -++ #else -++ wpa_printf(level, "MTLS: %s: (-0x%04x)", msg, -rc); -++ #endif -++} -++ -++ -++#define elog(rc, msg) emsgrc(MSG_ERROR, (msg), (rc)) -++#define ilog(rc, msg) emsgrc(MSG_INFO, (msg), (rc)) -++ -++ -++struct tls_conf * tls_conf_init(void *tls_ctx) -++{ -++ struct tls_conf *tls_conf = os_zalloc(sizeof(*tls_conf)); -++ if (tls_conf == NULL) -++ return NULL; -++ tls_conf->refcnt = 1; -++ -++ mbedtls_ssl_config_init(&tls_conf->conf); -++ mbedtls_ssl_conf_rng(&tls_conf->conf, -++ mbedtls_ctr_drbg_random, tls_ctx_global.ctr_drbg); -++ mbedtls_x509_crt_init(&tls_conf->ca_cert); -++ mbedtls_x509_crt_init(&tls_conf->client_cert); -++ mbedtls_pk_init(&tls_conf->private_key); -++ -++ return tls_conf; -++} -++ -++ -++void tls_conf_deinit(struct tls_conf *tls_conf) -++{ -++ if (tls_conf == NULL || --tls_conf->refcnt != 0) -++ return; -++ -++ mbedtls_x509_crt_free(&tls_conf->ca_cert); -++ mbedtls_x509_crt_free(&tls_conf->client_cert); -++ if (tls_conf->crl) { -++ mbedtls_x509_crl_free(tls_conf->crl); -++ os_free(tls_conf->crl); -++ } -++ mbedtls_pk_free(&tls_conf->private_key); -++ mbedtls_ssl_config_free(&tls_conf->conf); -++ os_free(tls_conf->curves); -++ os_free(tls_conf->ciphersuites); -++ os_free(tls_conf->subject_match); -++ os_free(tls_conf->altsubject_match); -++ os_free(tls_conf->suffix_match); -++ os_free(tls_conf->domain_match); -++ os_free(tls_conf->check_cert_subject); -++ os_free(tls_conf); -++} -++ -++ -++mbedtls_ctr_drbg_context * crypto_mbedtls_ctr_drbg(void); /*(not in header)*/ -++ -++__attribute_cold__ -++void * tls_init(const struct tls_config *conf) -++{ -++ /* RFE: review struct tls_config *conf (different from tls_conf) */ -++ -++ if (++tls_ctx_global.refcnt > 1) -++ return &tls_ctx_global; -++ -++ tls_ctx_global.ctr_drbg = crypto_mbedtls_ctr_drbg(); -++ #ifdef MBEDTLS_SSL_SESSION_TICKETS -++ mbedtls_ssl_ticket_init(&tls_ctx_global.ticket_ctx); -++ mbedtls_ssl_ticket_setup(&tls_ctx_global.ticket_ctx, -++ mbedtls_ctr_drbg_random, -++ tls_ctx_global.ctr_drbg, -++ MBEDTLS_CIPHER_AES_256_GCM, -++ 43200); /* ticket timeout: 12 hours */ -++ #endif -++ /* copy struct for future use */ -++ tls_ctx_global.init_conf = *conf; -++ if (conf->openssl_ciphers) -++ tls_ctx_global.init_conf.openssl_ciphers = -++ os_strdup(conf->openssl_ciphers); -++ -++ tls_ctx_global.crl_reload_interval = conf->crl_reload_interval; -++ os_get_reltime(&tls_ctx_global.crl_reload_previous); -++ -++ return &tls_ctx_global; -++} -++ -++ -++__attribute_cold__ -++void tls_deinit(void *tls_ctx) -++{ -++ if (tls_ctx == NULL || --tls_ctx_global.refcnt != 0) -++ return; -++ -++ tls_conf_deinit(tls_ctx_global.tls_conf); -++ os_free(tls_ctx_global.ca_cert_file); -++ os_free(tls_ctx_global.ocsp_stapling_response); -++ char *openssl_ciphers; /*(allocated in tls_init())*/ -++ *(const char **)&openssl_ciphers = -++ tls_ctx_global.init_conf.openssl_ciphers; -++ os_free(openssl_ciphers); -++ #ifdef MBEDTLS_SSL_SESSION_TICKETS -++ mbedtls_ssl_ticket_free(&tls_ctx_global.ticket_ctx); -++ #endif -++ os_memset(&tls_ctx_global, 0, sizeof(tls_ctx_global)); -++} -++ -++ -++int tls_get_errors(void *tls_ctx) -++{ -++ return 0; -++} -++ -++ -++static void tls_connection_deinit_expkey(struct tls_connection *conn) -++{ -++ conn->tls_prf_type = 0; /* MBEDTLS_SSL_TLS_PRF_NONE; */ -++ conn->expkey_keyblock_size = 0; -++ conn->expkey_secret_len = 0; -++ forced_memzero(conn->expkey_secret, sizeof(conn->expkey_secret)); -++ forced_memzero(conn->expkey_randbytes, sizeof(conn->expkey_randbytes)); -++} -++ -++ -++#ifdef TLS_MBEDTLS_SESSION_TICKETS -++void tls_connection_deinit_clienthello_session_ticket(struct tls_connection *conn) -++{ -++ if (conn->clienthello_session_ticket) { -++ mbedtls_platform_zeroize(conn->clienthello_session_ticket, -++ conn->clienthello_session_ticket_len); -++ mbedtls_free(conn->clienthello_session_ticket); -++ conn->clienthello_session_ticket = NULL; -++ conn->clienthello_session_ticket_len = 0; -++ } -++} -++#endif -++ -++ -++void tls_connection_deinit(void *tls_ctx, struct tls_connection *conn) -++{ -++ if (conn == NULL) -++ return; -++ -++ #if 0 /*(good intention, but never sent since we destroy self below)*/ -++ if (conn->established) -++ mbedtls_ssl_close_notify(&conn->ssl); -++ #endif -++ -++ if (conn->tls_prf_type) -++ tls_connection_deinit_expkey(conn); -++ -++ #ifdef TLS_MBEDTLS_SESSION_TICKETS -++ if (conn->clienthello_session_ticket) -++ tls_connection_deinit_clienthello_session_ticket(conn); -++ #endif -++ -++ os_free(conn->peer_subject); -++ wpabuf_free(conn->success_data); -++ wpabuf_free(conn->push_buf); -++ wpabuf_free(conn->pull_buf); -++ mbedtls_ssl_free(&conn->ssl); -++ tls_conf_deinit(conn->tls_conf); -++ os_free(conn); -++} -++ -++ -++static void tls_mbedtls_refresh_crl(void); -++static int tls_mbedtls_ssl_setup(struct tls_connection *conn); -++ -++struct tls_connection * tls_connection_init(void *tls_ctx) -++{ -++ struct tls_connection *conn = os_zalloc(sizeof(*conn)); -++ if (conn == NULL) -++ return NULL; -++ -++ mbedtls_ssl_init(&conn->ssl); -++ -++ conn->tls_conf = tls_ctx_global.tls_conf; /*(inherit global conf, if set)*/ -++ if (conn->tls_conf) { -++ ++conn->tls_conf->refcnt; -++ /* check for CRL refresh if inheriting from global config */ -++ tls_mbedtls_refresh_crl(); -++ -++ conn->verify_peer = conn->tls_conf->verify_peer; -++ if (tls_mbedtls_ssl_setup(conn) != 0) { -++ tls_connection_deinit(&tls_ctx_global, conn); -++ return NULL; -++ } -++ } -++ -++ return conn; -++} -++ -++ -++int tls_connection_established(void *tls_ctx, struct tls_connection *conn) -++{ -++ return conn ? conn->established : 0; -++} -++ -++ -++__attribute_noinline__ -++char * tls_mbedtls_peer_serial_num(const mbedtls_x509_crt *crt, char *serial_num, size_t len) -++{ -++ /* mbedtls_x509_serial_gets() inefficiently formats to hex separated by -++ * colons, so generate the hex serial number here. The func -++ * wpa_snprintf_hex_uppercase() is similarly inefficient. */ -++ size_t i = 0; /* skip leading 0's per Distinguished Encoding Rules (DER) */ -++ while (i < crt->serial.len && crt->serial.p[i] == 0) ++i; -++ if (i == crt->serial.len) --i; -++ -++ const unsigned char *s = crt->serial.p + i; -++ const size_t e = (crt->serial.len - i) * 2; -++ if (e >= len) -++ return NULL; -++ #if 0 -++ wpa_snprintf_hex_uppercase(serial_num, len, s, crt->serial.len-i); -++ #else -++ for (i = 0; i < e; i+=2, ++s) { -++ serial_num[i+0] = "0123456789ABCDEF"[(*s >> 4)]; -++ serial_num[i+1] = "0123456789ABCDEF"[(*s & 0xF)]; -++ } -++ serial_num[e] = '\0'; -++ #endif -++ return serial_num; -++} -++ -++ -++char * tls_connection_peer_serial_num(void *tls_ctx, -++ struct tls_connection *conn) -++{ -++ const mbedtls_x509_crt *crt = mbedtls_ssl_get_peer_cert(&conn->ssl); -++ if (crt == NULL) -++ return NULL; -++ size_t len = crt->serial.len * 2 + 1; -++ char *serial_num = os_malloc(len); -++ if (!serial_num) -++ return NULL; -++ return tls_mbedtls_peer_serial_num(crt, serial_num, len); -++} -++ -++ -++static void tls_pull_buf_reset(struct tls_connection *conn); -++ -++int tls_connection_shutdown(void *tls_ctx, struct tls_connection *conn) -++{ -++ /* Note: this function called from eap_peer_tls_reauth_init() -++ * for session resumption, not for connection shutdown */ -++ -++ if (conn == NULL) -++ return -1; -++ -++ tls_pull_buf_reset(conn); -++ wpabuf_free(conn->push_buf); -++ conn->push_buf = NULL; -++ conn->established = 0; -++ conn->resumed = 0; -++ if (conn->tls_prf_type) -++ tls_connection_deinit_expkey(conn); -++ -++ /* RFE: prepare for session resumption? (see doc in crypto/tls.h) */ -++ -++ return mbedtls_ssl_session_reset(&conn->ssl); -++} -++ -++ -++static int tls_wpabuf_resize_put_data(struct wpabuf **buf, -++ const unsigned char *data, size_t dlen) -++{ -++ if (wpabuf_resize(buf, dlen) < 0) -++ return 0; -++ wpabuf_put_data(*buf, data, dlen); -++ return 1; -++} -++ -++ -++static int tls_pull_buf_append(struct tls_connection *conn, -++ const struct wpabuf *in_data) -++{ -++ /*(interface does not lend itself to move semantics)*/ -++ return tls_wpabuf_resize_put_data(&conn->pull_buf, -++ wpabuf_head(in_data), -++ wpabuf_len(in_data)); -++} -++ -++ -++static void tls_pull_buf_reset(struct tls_connection *conn) -++{ -++ /*(future: might consider reusing conn->pull_buf)*/ -++ wpabuf_free(conn->pull_buf); -++ conn->pull_buf = NULL; -++ conn->pull_buf_offset = 0; -++} -++ -++ -++__attribute_cold__ -++static void tls_pull_buf_discard(struct tls_connection *conn, const char *func) -++{ -++ size_t discard = wpabuf_len(conn->pull_buf) - conn->pull_buf_offset; -++ if (discard) -++ wpa_printf(MSG_DEBUG, -++ "%s - %zu bytes remaining in pull_buf; discarding", -++ func, discard); -++ tls_pull_buf_reset(conn); -++} -++ -++ -++static int tls_pull_func(void *ptr, unsigned char *buf, size_t len) -++{ -++ struct tls_connection *conn = (struct tls_connection *) ptr; -++ if (conn->pull_buf == NULL) -++ return MBEDTLS_ERR_SSL_WANT_READ; -++ const size_t dlen = wpabuf_len(conn->pull_buf) - conn->pull_buf_offset; -++ if (dlen == 0) -++ return MBEDTLS_ERR_SSL_WANT_READ; -++ -++ if (len > dlen) -++ len = dlen; -++ os_memcpy(buf, wpabuf_head(conn->pull_buf)+conn->pull_buf_offset, len); -++ -++ if (len == dlen) { -++ tls_pull_buf_reset(conn); -++ /*wpa_printf(MSG_DEBUG, "%s - emptied pull_buf", __func__);*/ -++ } -++ else { -++ conn->pull_buf_offset += len; -++ /*wpa_printf(MSG_DEBUG, "%s - %zu bytes remaining in pull_buf", -++ __func__, dlen - len);*/ -++ } -++ return (int)len; -++} -++ -++ -++static int tls_push_func(void *ptr, const unsigned char *buf, size_t len) -++{ -++ struct tls_connection *conn = (struct tls_connection *) ptr; -++ return tls_wpabuf_resize_put_data(&conn->push_buf, buf, len) -++ ? (int)len -++ : MBEDTLS_ERR_SSL_ALLOC_FAILED; -++} -++ -++ -++static int -++tls_mbedtls_verify_cb (void *arg, mbedtls_x509_crt *crt, int depth, uint32_t *flags); -++ -++ -++static int tls_mbedtls_ssl_setup(struct tls_connection *conn) -++{ -++ #if 0 -++ /* mbedtls_ssl_setup() must be called only once */ -++ /* If this func might be called multiple times (e.g. via set_params), -++ * then we should set a flag in conn that ssl was initialized */ -++ if (conn->ssl_is_init) { -++ mbedtls_ssl_free(&conn->ssl); -++ mbedtls_ssl_init(&conn->ssl); -++ } -++ #endif -++ -++ int ret = mbedtls_ssl_setup(&conn->ssl, &conn->tls_conf->conf); -++ if (ret != 0) { -++ elog(ret, "mbedtls_ssl_setup"); -++ return -1; -++ } -++ -++ mbedtls_ssl_set_bio(&conn->ssl, conn, tls_push_func, tls_pull_func, NULL); -++ #if MBEDTLS_VERSION_NUMBER >= 0x03000000 /* mbedtls 3.0.0 */ -++ mbedtls_ssl_set_export_keys_cb( -++ &conn->ssl, tls_connection_export_keys_cb, conn); -++ #elif MBEDTLS_VERSION_NUMBER >= 0x02120000 /* mbedtls 2.18.0 */ -++ mbedtls_ssl_conf_export_keys_ext_cb( -++ &conn->tls_conf->conf, tls_connection_export_keys_cb, conn); -++ #endif -++ if (conn->verify_peer) -++ mbedtls_ssl_set_verify(&conn->ssl, tls_mbedtls_verify_cb, conn); -++ -++ return 0; -++} -++ -++ -++static int tls_mbedtls_data_is_pem(const u8 *data) -++{ -++ return (NULL != os_strstr((char *)data, "-----")); -++} -++ -++ -++static void tls_mbedtls_set_allowed_tls_vers(struct tls_conf *tls_conf, -++ mbedtls_ssl_config *conf) -++{ -++ #if !defined(MBEDTLS_SSL_PROTO_TLS1_3) -++ tls_conf->flags |= TLS_CONN_DISABLE_TLSv1_3; -++ #endif -++ -++ /* unconditionally require TLSv1.2+ for TLS_CONN_SUITEB */ -++ if (tls_conf->flags & TLS_CONN_SUITEB) { -++ tls_conf->flags |= TLS_CONN_DISABLE_TLSv1_0; -++ tls_conf->flags |= TLS_CONN_DISABLE_TLSv1_1; -++ } -++ -++ const unsigned int flags = tls_conf->flags; -++ -++ /* attempt to map flags to min and max TLS protocol version */ -++ -++ int min = (flags & TLS_CONN_DISABLE_TLSv1_0) -++ ? (flags & TLS_CONN_DISABLE_TLSv1_1) -++ ? (flags & TLS_CONN_DISABLE_TLSv1_2) -++ ? (flags & TLS_CONN_DISABLE_TLSv1_3) -++ ? 4 -++ : 3 -++ : 2 -++ : 1 -++ : 0; -++ -++ int max = (flags & TLS_CONN_DISABLE_TLSv1_3) -++ ? (flags & TLS_CONN_DISABLE_TLSv1_2) -++ ? (flags & TLS_CONN_DISABLE_TLSv1_1) -++ ? (flags & TLS_CONN_DISABLE_TLSv1_0) -++ ? -1 -++ : 0 -++ : 1 -++ : 2 -++ : 3; -++ -++ if ((flags & TLS_CONN_ENABLE_TLSv1_2) && min > 2) min = 2; -++ if ((flags & TLS_CONN_ENABLE_TLSv1_1) && min > 1) min = 1; -++ if ((flags & TLS_CONN_ENABLE_TLSv1_0) && min > 0) min = 0; -++ if (max < min) { -++ emsg(MSG_ERROR, "invalid tls_disable_tlsv* params; ignoring"); -++ return; -++ } -++ #if MBEDTLS_VERSION_NUMBER >= 0x03000000 /* mbedtls 3.0.0 */ -++ /* mbed TLS 3.0.0 removes support for protocols < TLSv1.2 */ -++ if (min < 2 || max < 2) { -++ emsg(MSG_ERROR, "invalid tls_disable_tlsv* params; ignoring"); -++ if (min < 2) min = 2; -++ if (max < 2) max = 2; -++ } -++ #endif -++ -++ #if MBEDTLS_VERSION_NUMBER >= 0x03020000 /* mbedtls 3.2.0 */ -++ /* MBEDTLS_SSL_VERSION_TLS1_2 = 0x0303 *//*!< (D)TLS 1.2 */ -++ /* MBEDTLS_SSL_VERSION_TLS1_3 = 0x0304 *//*!< (D)TLS 1.3 */ -++ min = (min == 2) ? MBEDTLS_SSL_VERSION_TLS1_2 : MBEDTLS_SSL_VERSION_TLS1_3; -++ max = (max == 2) ? MBEDTLS_SSL_VERSION_TLS1_2 : MBEDTLS_SSL_VERSION_TLS1_3; -++ mbedtls_ssl_conf_min_tls_version(conf, min); -++ mbedtls_ssl_conf_max_tls_version(conf, max); -++ #else -++ #ifndef MBEDTLS_SSL_MINOR_VERSION_4 -++ if (min == 3) min = 2; -++ if (max == 3) max = 2; -++ #endif -++ /* MBEDTLS_SSL_MINOR_VERSION_0 0 *//*!< SSL v3.0 */ -++ /* MBEDTLS_SSL_MINOR_VERSION_1 1 *//*!< TLS v1.0 */ -++ /* MBEDTLS_SSL_MINOR_VERSION_2 2 *//*!< TLS v1.1 */ -++ /* MBEDTLS_SSL_MINOR_VERSION_3 3 *//*!< TLS v1.2 */ -++ /* MBEDTLS_SSL_MINOR_VERSION_4 4 *//*!< TLS v1.3 */ -++ mbedtls_ssl_conf_min_version(conf, MBEDTLS_SSL_MAJOR_VERSION_3, min+1); -++ mbedtls_ssl_conf_max_version(conf, MBEDTLS_SSL_MAJOR_VERSION_3, max+1); -++ #endif -++} -++ -++ -++__attribute_noinline__ -++static int tls_mbedtls_readfile(const char *path, u8 **buf, size_t *n); -++ -++ -++static int -++tls_mbedtls_set_dhparams(struct tls_conf *tls_conf, const char *dh_file) -++{ -++ size_t len; -++ u8 *data; -++ if (tls_mbedtls_readfile(dh_file, &data, &len)) -++ return 0; -++ -++ /* parse only if DH parameters if in PEM format */ -++ if (tls_mbedtls_data_is_pem(data) -++ && NULL == os_strstr((char *)data, "-----BEGIN DH PARAMETERS-----")) { -++ if (os_strstr((char *)data, "-----BEGIN DSA PARAMETERS-----")) -++ wpa_printf(MSG_WARNING, "DSA parameters not handled (%s)", dh_file); -++ else -++ wpa_printf(MSG_WARNING, "unexpected DH param content (%s)",dh_file); -++ forced_memzero(data, len); -++ os_free(data); -++ return 0; -++ } -++ -++ /* mbedtls_dhm_parse_dhm() expects "-----BEGIN DH PARAMETERS-----" if PEM */ -++ mbedtls_dhm_context dhm; -++ mbedtls_dhm_init(&dhm); -++ int rc = mbedtls_dhm_parse_dhm(&dhm, data, len); -++ if (0 == rc) -++ rc = mbedtls_ssl_conf_dh_param_ctx(&tls_conf->conf, &dhm); -++ if (0 != rc) -++ elog(rc, dh_file); -++ mbedtls_dhm_free(&dhm); -++ -++ forced_memzero(data, len); -++ os_free(data); -++ return (0 == rc); -++} -++ -++ -++/* reference: lighttpd src/mod_mbedtls.c:mod_mbedtls_ssl_append_curve() -++ * (same author: gstrauss@gluelogic.com; same license: BSD-3-Clause) */ -++#if MBEDTLS_VERSION_NUMBER < 0x03010000 /* mbedtls 3.1.0 */ -++static int -++tls_mbedtls_append_curve (mbedtls_ecp_group_id *ids, int nids, int idsz, const mbedtls_ecp_group_id id) -++{ -++ if (1 >= idsz - (nids + 1)) { -++ emsg(MSG_ERROR, "error: too many curves during list expand"); -++ return -1; -++ } -++ ids[++nids] = id; -++ return nids; -++} -++ -++ -++static int -++tls_mbedtls_set_curves(struct tls_conf *tls_conf, const char *curvelist) -++{ -++ mbedtls_ecp_group_id ids[512]; -++ int nids = -1; -++ const int idsz = (int)(sizeof(ids)/sizeof(*ids)-1); -++ const mbedtls_ecp_curve_info * const curve_info = mbedtls_ecp_curve_list(); -++ -++ for (const char *e = curvelist-1; e; ) { -++ const char * const n = e+1; -++ e = os_strchr(n, ':'); -++ size_t len = e ? (size_t)(e - n) : os_strlen(n); -++ mbedtls_ecp_group_id grp_id = MBEDTLS_ECP_DP_NONE; -++ switch (len) { -++ case 5: -++ if (0 == os_memcmp("P-521", n, 5)) -++ grp_id = MBEDTLS_ECP_DP_SECP521R1; -++ else if (0 == os_memcmp("P-384", n, 5)) -++ grp_id = MBEDTLS_ECP_DP_SECP384R1; -++ else if (0 == os_memcmp("P-256", n, 5)) -++ grp_id = MBEDTLS_ECP_DP_SECP256R1; -++ break; -++ case 6: -++ if (0 == os_memcmp("BP-521", n, 6)) -++ grp_id = MBEDTLS_ECP_DP_BP512R1; -++ else if (0 == os_memcmp("BP-384", n, 6)) -++ grp_id = MBEDTLS_ECP_DP_BP384R1; -++ else if (0 == os_memcmp("BP-256", n, 6)) -++ grp_id = MBEDTLS_ECP_DP_BP256R1; -++ break; -++ default: -++ break; -++ } -++ if (grp_id != MBEDTLS_ECP_DP_NONE) { -++ nids = tls_mbedtls_append_curve(ids, nids, idsz, grp_id); -++ if (-1 == nids) return 0; -++ continue; -++ } -++ /* similar to mbedtls_ecp_curve_info_from_name() */ -++ const mbedtls_ecp_curve_info *info; -++ for (info = curve_info; info->grp_id != MBEDTLS_ECP_DP_NONE; ++info) { -++ if (0 == os_strncmp(info->name, n, len) && info->name[len] == '\0') -++ break; -++ } -++ if (info->grp_id == MBEDTLS_ECP_DP_NONE) { -++ wpa_printf(MSG_ERROR, "MTLS: unrecognized curve: %.*s",(int)len,n); -++ return 0; -++ } -++ -++ nids = tls_mbedtls_append_curve(ids, nids, idsz, info->grp_id); -++ if (-1 == nids) return 0; -++ } -++ -++ /* mod_openssl configures "prime256v1" if curve list not specified, -++ * but mbedtls provides a list of supported curves if not explicitly set */ -++ if (-1 == nids) return 1; /* empty list; no-op */ -++ -++ ids[++nids] = MBEDTLS_ECP_DP_NONE; /* terminate list */ -++ ++nids; -++ -++ /* curves list must be persistent for lifetime of mbedtls_ssl_config */ -++ tls_conf->curves = os_malloc(nids * sizeof(mbedtls_ecp_group_id)); -++ if (tls_conf->curves == NULL) -++ return 0; -++ os_memcpy(tls_conf->curves, ids, nids * sizeof(mbedtls_ecp_group_id)); -++ -++ mbedtls_ssl_conf_curves(&tls_conf->conf, tls_conf->curves); -++ return 1; -++} -++#else -++static int -++tls_mbedtls_append_curve (uint16_t *ids, int nids, int idsz, const uint16_t id) -++{ -++ if (1 >= idsz - (nids + 1)) { -++ emsg(MSG_ERROR, "error: too many curves during list expand"); -++ return -1; -++ } -++ ids[++nids] = id; -++ return nids; -++} -++ -++ -++static int -++tls_mbedtls_set_curves(struct tls_conf *tls_conf, const char *curvelist) -++{ -++ /* TLS Supported Groups (renamed from "EC Named Curve Registry") -++ * https://www.iana.org/assignments/tls-parameters/tls-parameters.xhtml#tls-parameters-8 -++ */ -++ uint16_t ids[512]; -++ int nids = -1; -++ const int idsz = (int)(sizeof(ids)/sizeof(*ids)-1); -++ const mbedtls_ecp_curve_info * const curve_info = mbedtls_ecp_curve_list(); -++ -++ for (const char *e = curvelist-1; e; ) { -++ const char * const n = e+1; -++ e = os_strchr(n, ':'); -++ size_t len = e ? (size_t)(e - n) : os_strlen(n); -++ uint16_t tls_id = 0; -++ switch (len) { -++ case 5: -++ if (0 == os_memcmp("P-521", n, 5)) -++ tls_id = 25; /* mbedtls_ecp_group_id MBEDTLS_ECP_DP_SECP521R1 */ -++ else if (0 == os_memcmp("P-384", n, 5)) -++ tls_id = 24; /* mbedtls_ecp_group_id MBEDTLS_ECP_DP_SECP384R1 */ -++ else if (0 == os_memcmp("P-256", n, 5)) -++ tls_id = 23; /* mbedtls_ecp_group_id MBEDTLS_ECP_DP_SECP256R1 */ -++ break; -++ case 6: -++ if (0 == os_memcmp("BP-521", n, 6)) -++ tls_id = 28; /* mbedtls_ecp_group_id MBEDTLS_ECP_DP_BP512R1 */ -++ else if (0 == os_memcmp("BP-384", n, 6)) -++ tls_id = 27; /* mbedtls_ecp_group_id MBEDTLS_ECP_DP_BP384R1 */ -++ else if (0 == os_memcmp("BP-256", n, 6)) -++ tls_id = 26; /* mbedtls_ecp_group_id MBEDTLS_ECP_DP_BP256R1 */ -++ break; -++ default: -++ break; -++ } -++ if (tls_id != 0) { -++ nids = tls_mbedtls_append_curve(ids, nids, idsz, tls_id); -++ if (-1 == nids) return 0; -++ continue; -++ } -++ /* similar to mbedtls_ecp_curve_info_from_name() */ -++ const mbedtls_ecp_curve_info *info; -++ for (info = curve_info; info->tls_id != 0; ++info) { -++ if (0 == os_strncmp(info->name, n, len) && info->name[len] == '\0') -++ break; -++ } -++ if (info->tls_id == 0) { -++ wpa_printf(MSG_ERROR, "MTLS: unrecognized curve: %.*s",(int)len,n); -++ return 0; -++ } -++ -++ nids = tls_mbedtls_append_curve(ids, nids, idsz, info->tls_id); -++ if (-1 == nids) return 0; -++ } -++ -++ /* mod_openssl configures "prime256v1" if curve list not specified, -++ * but mbedtls provides a list of supported curves if not explicitly set */ -++ if (-1 == nids) return 1; /* empty list; no-op */ -++ -++ ids[++nids] = 0; /* terminate list */ -++ ++nids; -++ -++ /* curves list must be persistent for lifetime of mbedtls_ssl_config */ -++ tls_conf->curves = os_malloc(nids * sizeof(uint16_t)); -++ if (tls_conf->curves == NULL) -++ return 0; -++ os_memcpy(tls_conf->curves, ids, nids * sizeof(uint16_t)); -++ -++ mbedtls_ssl_conf_groups(&tls_conf->conf, tls_conf->curves); -++ return 1; -++} -++#endif /* MBEDTLS_VERSION_NUMBER >= 0x03010000 */ /* mbedtls 3.1.0 */ -++ -++ -++/* data copied from lighttpd src/mod_mbedtls.c (BSD-3-Clause) */ -++static const int suite_AES_256_ephemeral[] = { -++ /* All AES-256 ephemeral suites */ -++ MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384, -++ MBEDTLS_TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384, -++ MBEDTLS_TLS_DHE_RSA_WITH_AES_256_GCM_SHA384, -++ MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_256_CCM, -++ MBEDTLS_TLS_DHE_RSA_WITH_AES_256_CCM, -++ MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384, -++ MBEDTLS_TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384, -++ MBEDTLS_TLS_DHE_RSA_WITH_AES_256_CBC_SHA256, -++ MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA, -++ MBEDTLS_TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA, -++ MBEDTLS_TLS_DHE_RSA_WITH_AES_256_CBC_SHA, -++ MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_256_CCM_8, -++ MBEDTLS_TLS_DHE_RSA_WITH_AES_256_CCM_8 -++}; -++ -++/* data copied from lighttpd src/mod_mbedtls.c (BSD-3-Clause) */ -++static const int suite_AES_128_ephemeral[] = { -++ /* All AES-128 ephemeral suites */ -++ MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, -++ MBEDTLS_TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, -++ MBEDTLS_TLS_DHE_RSA_WITH_AES_128_GCM_SHA256, -++ MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_CCM, -++ MBEDTLS_TLS_DHE_RSA_WITH_AES_128_CCM, -++ MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256, -++ MBEDTLS_TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256, -++ MBEDTLS_TLS_DHE_RSA_WITH_AES_128_CBC_SHA256, -++ MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA, -++ MBEDTLS_TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA, -++ MBEDTLS_TLS_DHE_RSA_WITH_AES_128_CBC_SHA, -++ MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8, -++ MBEDTLS_TLS_DHE_RSA_WITH_AES_128_CCM_8 -++}; -++ -++/* data copied from lighttpd src/mod_mbedtls.c (BSD-3-Clause) */ -++/* HIGH cipher list (mapped from openssl list to mbedtls) */ -++static const int suite_HIGH[] = { -++ MBEDTLS_TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256, -++ MBEDTLS_TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256, -++ MBEDTLS_TLS_DHE_RSA_WITH_CHACHA20_POLY1305_SHA256, -++ MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384, -++ MBEDTLS_TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384, -++ MBEDTLS_TLS_DHE_RSA_WITH_AES_256_GCM_SHA384, -++ MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_256_CCM, -++ MBEDTLS_TLS_DHE_RSA_WITH_AES_256_CCM, -++ MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384, -++ MBEDTLS_TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384, -++ MBEDTLS_TLS_DHE_RSA_WITH_AES_256_CBC_SHA256, -++ MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA, -++ MBEDTLS_TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA, -++ MBEDTLS_TLS_DHE_RSA_WITH_AES_256_CBC_SHA, -++ MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_256_CCM_8, -++ MBEDTLS_TLS_DHE_RSA_WITH_AES_256_CCM_8, -++ MBEDTLS_TLS_ECDHE_ECDSA_WITH_CAMELLIA_256_CBC_SHA384, -++ MBEDTLS_TLS_ECDHE_RSA_WITH_CAMELLIA_256_CBC_SHA384, -++ MBEDTLS_TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA256, -++ MBEDTLS_TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA, -++ MBEDTLS_TLS_ECDHE_ECDSA_WITH_ARIA_256_GCM_SHA384, -++ MBEDTLS_TLS_ECDHE_RSA_WITH_ARIA_256_GCM_SHA384, -++ MBEDTLS_TLS_DHE_RSA_WITH_ARIA_256_GCM_SHA384, -++ MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, -++ MBEDTLS_TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, -++ MBEDTLS_TLS_DHE_RSA_WITH_AES_128_GCM_SHA256, -++ MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_CCM, -++ MBEDTLS_TLS_DHE_RSA_WITH_AES_128_CCM, -++ MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256, -++ MBEDTLS_TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256, -++ MBEDTLS_TLS_DHE_RSA_WITH_AES_128_CBC_SHA256, -++ MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA, -++ MBEDTLS_TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA, -++ MBEDTLS_TLS_DHE_RSA_WITH_AES_128_CBC_SHA, -++ MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8, -++ MBEDTLS_TLS_DHE_RSA_WITH_AES_128_CCM_8, -++ MBEDTLS_TLS_ECDHE_ECDSA_WITH_CAMELLIA_128_CBC_SHA256, -++ MBEDTLS_TLS_ECDHE_RSA_WITH_CAMELLIA_128_CBC_SHA256, -++ MBEDTLS_TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA256, -++ MBEDTLS_TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA, -++ MBEDTLS_TLS_ECDHE_ECDSA_WITH_ARIA_128_GCM_SHA256, -++ MBEDTLS_TLS_ECDHE_RSA_WITH_ARIA_128_GCM_SHA256, -++ MBEDTLS_TLS_DHE_RSA_WITH_ARIA_128_GCM_SHA256, -++ MBEDTLS_TLS_ECDHE_PSK_WITH_CHACHA20_POLY1305_SHA256, -++ MBEDTLS_TLS_DHE_PSK_WITH_CHACHA20_POLY1305_SHA256, -++ MBEDTLS_TLS_DHE_PSK_WITH_AES_256_GCM_SHA384, -++ MBEDTLS_TLS_DHE_PSK_WITH_AES_256_CCM, -++ MBEDTLS_TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA384, -++ MBEDTLS_TLS_DHE_PSK_WITH_AES_256_CBC_SHA384, -++ MBEDTLS_TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA, -++ MBEDTLS_TLS_DHE_PSK_WITH_AES_256_CBC_SHA, -++ MBEDTLS_TLS_ECDHE_PSK_WITH_CAMELLIA_256_CBC_SHA384, -++ MBEDTLS_TLS_DHE_PSK_WITH_CAMELLIA_256_CBC_SHA384, -++ MBEDTLS_TLS_DHE_PSK_WITH_AES_256_CCM_8, -++ MBEDTLS_TLS_DHE_PSK_WITH_ARIA_256_GCM_SHA384, -++ MBEDTLS_TLS_DHE_PSK_WITH_AES_128_GCM_SHA256, -++ MBEDTLS_TLS_DHE_PSK_WITH_AES_128_CCM, -++ MBEDTLS_TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA256, -++ MBEDTLS_TLS_DHE_PSK_WITH_AES_128_CBC_SHA256, -++ MBEDTLS_TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA, -++ MBEDTLS_TLS_DHE_PSK_WITH_AES_128_CBC_SHA, -++ MBEDTLS_TLS_DHE_PSK_WITH_CAMELLIA_128_CBC_SHA256, -++ MBEDTLS_TLS_ECDHE_PSK_WITH_CAMELLIA_128_CBC_SHA256, -++ MBEDTLS_TLS_DHE_PSK_WITH_AES_128_CCM_8, -++ MBEDTLS_TLS_DHE_PSK_WITH_ARIA_128_GCM_SHA256, -++ MBEDTLS_TLS_RSA_WITH_AES_256_GCM_SHA384, -++ MBEDTLS_TLS_RSA_WITH_AES_256_CCM, -++ MBEDTLS_TLS_RSA_WITH_AES_256_CBC_SHA256, -++ MBEDTLS_TLS_RSA_WITH_AES_256_CBC_SHA, -++ MBEDTLS_TLS_RSA_WITH_AES_256_CCM_8, -++ MBEDTLS_TLS_RSA_WITH_CAMELLIA_256_CBC_SHA256, -++ MBEDTLS_TLS_RSA_WITH_CAMELLIA_256_CBC_SHA, -++ MBEDTLS_TLS_RSA_WITH_ARIA_256_GCM_SHA384, -++ MBEDTLS_TLS_RSA_WITH_AES_128_GCM_SHA256, -++ MBEDTLS_TLS_RSA_WITH_AES_128_CCM, -++ MBEDTLS_TLS_RSA_WITH_AES_128_CBC_SHA256, -++ MBEDTLS_TLS_RSA_WITH_AES_128_CBC_SHA, -++ MBEDTLS_TLS_RSA_WITH_AES_128_CCM_8, -++ MBEDTLS_TLS_RSA_WITH_CAMELLIA_128_CBC_SHA256, -++ MBEDTLS_TLS_RSA_WITH_CAMELLIA_128_CBC_SHA, -++ MBEDTLS_TLS_RSA_WITH_ARIA_128_GCM_SHA256, -++ MBEDTLS_TLS_RSA_PSK_WITH_CHACHA20_POLY1305_SHA256, -++ MBEDTLS_TLS_RSA_PSK_WITH_AES_256_GCM_SHA384, -++ MBEDTLS_TLS_RSA_PSK_WITH_AES_256_CBC_SHA384, -++ MBEDTLS_TLS_RSA_PSK_WITH_AES_256_CBC_SHA, -++ MBEDTLS_TLS_RSA_PSK_WITH_CAMELLIA_256_CBC_SHA384, -++ MBEDTLS_TLS_RSA_PSK_WITH_ARIA_256_GCM_SHA384, -++ MBEDTLS_TLS_RSA_PSK_WITH_AES_128_GCM_SHA256, -++ MBEDTLS_TLS_RSA_PSK_WITH_AES_128_CBC_SHA256, -++ MBEDTLS_TLS_RSA_PSK_WITH_AES_128_CBC_SHA, -++ MBEDTLS_TLS_RSA_PSK_WITH_CAMELLIA_128_CBC_SHA256, -++ MBEDTLS_TLS_RSA_PSK_WITH_ARIA_128_GCM_SHA256, -++ MBEDTLS_TLS_PSK_WITH_CHACHA20_POLY1305_SHA256, -++ MBEDTLS_TLS_PSK_WITH_AES_256_GCM_SHA384, -++ MBEDTLS_TLS_PSK_WITH_AES_256_CCM, -++ MBEDTLS_TLS_PSK_WITH_AES_256_CBC_SHA384, -++ MBEDTLS_TLS_PSK_WITH_AES_256_CBC_SHA, -++ MBEDTLS_TLS_PSK_WITH_CAMELLIA_256_CBC_SHA384, -++ MBEDTLS_TLS_PSK_WITH_AES_256_CCM_8, -++ MBEDTLS_TLS_PSK_WITH_ARIA_256_GCM_SHA384, -++ MBEDTLS_TLS_PSK_WITH_AES_128_GCM_SHA256, -++ MBEDTLS_TLS_PSK_WITH_AES_128_CCM, -++ MBEDTLS_TLS_PSK_WITH_AES_128_CBC_SHA256, -++ MBEDTLS_TLS_PSK_WITH_AES_128_CBC_SHA, -++ MBEDTLS_TLS_PSK_WITH_CAMELLIA_128_CBC_SHA256, -++ MBEDTLS_TLS_PSK_WITH_AES_128_CCM_8, -++ MBEDTLS_TLS_PSK_WITH_ARIA_128_GCM_SHA256 -++}; -++ -++ -++__attribute_noinline__ -++static int -++tls_mbedtls_append_ciphersuite (int *ids, int nids, int idsz, const int *x, int xsz) -++{ -++ if (xsz >= idsz - (nids + 1)) { -++ emsg(MSG_ERROR, "error: too many ciphers during list expand"); -++ return -1; -++ } -++ -++ for (int i = 0; i < xsz; ++i) -++ ids[++nids] = x[i]; -++ -++ return nids; -++} -++ -++ -++static int -++tls_mbedtls_translate_ciphername(int id, char *buf, size_t buflen) -++{ -++ const mbedtls_ssl_ciphersuite_t *info = -++ mbedtls_ssl_ciphersuite_from_id(id); -++ if (info == NULL) -++ return 0; -++ const char *name = mbedtls_ssl_ciphersuite_get_name(info); -++ const size_t len = os_strlen(name); -++ if (len == 7 && 0 == os_memcmp(name, "unknown", 7)) -++ return 0; -++ if (len >= buflen) -++ return 0; -++ os_strlcpy(buf, name, buflen); -++ -++ /* attempt to translate mbedtls string to openssl string -++ * (some heuristics; incomplete) */ -++ size_t i = 0, j = 0; -++ if (buf[0] == 'T') { -++ if (os_strncmp(buf, "TLS1-3-", 7) == 0) { -++ buf[3] = '-'; -++ j = 4; /* remove "1-3" from "TLS1-3-" prefix */ -++ i = 7; -++ } -++ else if (os_strncmp(buf, "TLS-", 4) == 0) -++ i = 4; /* remove "TLS-" prefix */ -++ } -++ for (; buf[i]; ++i) { -++ if (buf[i] == '-') { -++ if (i >= 3) { -++ if (0 == os_memcmp(buf+i-3, "AES", 3)) -++ continue; /* "AES-" -> "AES" */ -++ } -++ if (i >= 4) { -++ if (0 == os_memcmp(buf+i-4, "WITH", 4)) { -++ j -= 4; /* remove "WITH-" */ -++ continue; -++ } -++ } -++ } -++ buf[j++] = buf[i]; -++ } -++ buf[j] = '\0'; -++ -++ return j; -++} -++ -++ -++__attribute_noinline__ -++static int -++tls_mbedtls_set_ciphersuites(struct tls_conf *tls_conf, int *ids, int nids) -++{ -++ /* ciphersuites list must be persistent for lifetime of mbedtls_ssl_config*/ -++ os_free(tls_conf->ciphersuites); -++ tls_conf->ciphersuites = os_malloc(nids * sizeof(int)); -++ if (tls_conf->ciphersuites == NULL) -++ return 0; -++ os_memcpy(tls_conf->ciphersuites, ids, nids * sizeof(int)); -++ mbedtls_ssl_conf_ciphersuites(&tls_conf->conf, tls_conf->ciphersuites); -++ return 1; -++} -++ -++ -++static int -++tls_mbedtls_set_ciphers(struct tls_conf *tls_conf, const char *ciphers) -++{ -++ char buf[64]; -++ int ids[512]; -++ int nids = -1; -++ const int idsz = (int)(sizeof(ids)/sizeof(*ids)-1); -++ const char *next; -++ size_t blen, clen; -++ do { -++ next = os_strchr(ciphers, ':'); -++ clen = next ? (size_t)(next - ciphers) : os_strlen(ciphers); -++ if (!clen) -++ continue; -++ -++ /* special-case a select set of openssl group names for hwsim tests */ -++ /* (review; remove excess code if tests are not run for non-OpenSSL?) */ -++ if (clen == 9 && os_memcmp(ciphers, "SUITEB192", 9) == 0) { -++ static int ssl_preset_suiteb192_ciphersuites[] = { -++ MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384, -++ 0 -++ }; -++ return tls_mbedtls_set_ciphersuites(tls_conf, -++ ssl_preset_suiteb192_ciphersuites, -++ 2); -++ } -++ if (clen == 9 && os_memcmp(ciphers, "SUITEB128", 9) == 0) { -++ static int ssl_preset_suiteb128_ciphersuites[] = { -++ MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, -++ 0 -++ }; -++ return tls_mbedtls_set_ciphersuites(tls_conf, -++ ssl_preset_suiteb128_ciphersuites, -++ 2); -++ } -++ if (clen == 7 && os_memcmp(ciphers, "DEFAULT", 7) == 0) -++ continue; -++ if (clen == 6 && os_memcmp(ciphers, "AES128", 6) == 0) { -++ nids = tls_mbedtls_append_ciphersuite(ids, nids, idsz, -++ suite_AES_128_ephemeral, -++ (int)ARRAY_SIZE(suite_AES_128_ephemeral)); -++ if (nids == -1) -++ return 0; -++ continue; -++ } -++ if (clen == 6 && os_memcmp(ciphers, "AES256", 6) == 0) { -++ nids = tls_mbedtls_append_ciphersuite(ids, nids, idsz, -++ suite_AES_256_ephemeral, -++ (int)ARRAY_SIZE(suite_AES_256_ephemeral)); -++ if (nids == -1) -++ return 0; -++ continue; -++ } -++ if (clen == 4 && os_memcmp(ciphers, "HIGH", 4) == 0) { -++ nids = tls_mbedtls_append_ciphersuite(ids, nids, idsz, suite_HIGH, -++ (int)ARRAY_SIZE(suite_HIGH)); -++ if (nids == -1) -++ return 0; -++ continue; -++ } -++ /* ignore anonymous cipher group names (?not supported by mbedtls?) */ -++ if (clen == 4 && os_memcmp(ciphers, "!ADH", 4) == 0) -++ continue; -++ if (clen == 6 && os_memcmp(ciphers, "-aECDH", 6) == 0) -++ continue; -++ if (clen == 7 && os_memcmp(ciphers, "-aECDSA", 7) == 0) -++ continue; -++ -++ /* attempt to match mbedtls cipher names -++ * nb: does not support openssl group names or list manipulation syntax -++ * (alt: could copy almost 1200 lines (!!!) of lighttpd mod_mbedtls.c -++ * mod_mbedtls_ssl_conf_ciphersuites() to translate strings) -++ * note: not efficient to rewrite list for each ciphers entry, -++ * but this code is expected to run only at startup -++ */ -++ const int *list = mbedtls_ssl_list_ciphersuites(); -++ for (; *list; ++list) { -++ blen = tls_mbedtls_translate_ciphername(*list,buf,sizeof(buf)); -++ if (!blen) -++ continue; -++ -++ /* matching heuristics additional to translate_ciphername above */ -++ if (blen == clen+4) { -++ char *cbc = os_strstr(buf, "CBC-"); -++ if (cbc) { -++ os_memmove(cbc, cbc+4, blen-(cbc+4-buf)+1); /*(w/ '\0')*/ -++ blen -= 4; -++ } -++ } -++ if (blen >= clen && os_memcmp(ciphers, buf, clen) == 0 -++ && (blen == clen -++ || (blen == clen+7 && os_memcmp(buf+clen, "-SHA256", 7)))) { -++ if (1 >= idsz - (nids + 1)) { -++ emsg(MSG_ERROR, -++ "error: too many ciphers during list expand"); -++ return 0; -++ } -++ ids[++nids] = *list; -++ break; -++ } -++ } -++ if (*list == 0) { -++ wpa_printf(MSG_ERROR, -++ "MTLS: unrecognized cipher: %.*s", (int)clen, ciphers); -++ return 0; -++ } -++ } while ((ciphers = next ? next+1 : NULL)); -++ -++ if (-1 == nids) return 1; /* empty list; no-op */ -++ -++ ids[++nids] = 0; /* terminate list */ -++ ++nids; -++ -++ return tls_mbedtls_set_ciphersuites(tls_conf, ids, nids); -++} -++ -++ -++__attribute_noinline__ -++static int tls_mbedtls_set_item(char **config_item, const char *item) -++{ -++ os_free(*config_item); -++ *config_item = NULL; -++ return item ? (*config_item = os_strdup(item)) != NULL : 1; -++} -++ -++ -++static int tls_connection_set_subject_match(struct tls_conf *tls_conf, -++ const struct tls_connection_params *params) -++{ -++ int rc = 1; -++ rc &= tls_mbedtls_set_item(&tls_conf->subject_match, -++ params->subject_match); -++ rc &= tls_mbedtls_set_item(&tls_conf->altsubject_match, -++ params->altsubject_match); -++ rc &= tls_mbedtls_set_item(&tls_conf->suffix_match, -++ params->suffix_match); -++ rc &= tls_mbedtls_set_item(&tls_conf->domain_match, -++ params->domain_match); -++ rc &= tls_mbedtls_set_item(&tls_conf->check_cert_subject, -++ params->check_cert_subject); -++ return rc; -++} -++ -++ -++/* duplicated in crypto_mbedtls.c:crypto_mbedtls_readfile()*/ -++__attribute_noinline__ -++static int tls_mbedtls_readfile(const char *path, u8 **buf, size_t *n) -++{ -++ #if 0 /* #ifdef MBEDTLS_FS_IO */ -++ /*(includes +1 for '\0' needed by mbedtls PEM parsing funcs)*/ -++ if (mbedtls_pk_load_file(path, (unsigned char **)buf, n) != 0) { -++ wpa_printf(MSG_ERROR, "error: mbedtls_pk_load_file %s", path); -++ return -1; -++ } -++ #else -++ /*(use os_readfile() so that we can use os_free() -++ *(if we use mbedtls_pk_load_file() above, macros prevent calling free() -++ * directly #if defined(OS_REJECT_C_LIB_FUNCTIONS) and calling os_free() -++ * on buf aborts in tests if buf not allocated via os_malloc())*/ -++ *buf = (u8 *)os_readfile(path, n); -++ if (!*buf) { -++ wpa_printf(MSG_ERROR, "error: os_readfile %s", path); -++ return -1; -++ } -++ u8 *buf0 = os_realloc(*buf, *n+1); -++ if (!buf0) { -++ bin_clear_free(*buf, *n); -++ *buf = NULL; -++ return -1; -++ } -++ buf0[(*n)++] = '\0'; -++ *buf = buf0; -++ #endif -++ return 0; -++} -++ -++ -++static int tls_mbedtls_set_crl(struct tls_conf *tls_conf, const u8 *data, size_t len) -++{ -++ /* do not use mbedtls_x509_crl_parse() on PEM unless it contains CRL */ -++ if (len && data[len-1] == '\0' -++ && NULL == os_strstr((const char *)data,"-----BEGIN X509 CRL-----") -++ && tls_mbedtls_data_is_pem(data)) -++ return 0; -++ -++ mbedtls_x509_crl crl; -++ mbedtls_x509_crl_init(&crl); -++ int rc = mbedtls_x509_crl_parse(&crl, data, len); -++ if (rc < 0) { -++ mbedtls_x509_crl_free(&crl); -++ return rc == MBEDTLS_ERR_PEM_NO_HEADER_FOOTER_PRESENT ? 0 : rc; -++ } -++ -++ mbedtls_x509_crl *crl_new = os_malloc(sizeof(crl)); -++ if (crl_new == NULL) { -++ mbedtls_x509_crl_free(&crl); -++ return MBEDTLS_ERR_X509_ALLOC_FAILED; -++ } -++ os_memcpy(crl_new, &crl, sizeof(crl)); -++ -++ mbedtls_x509_crl *crl_old = tls_conf->crl; -++ tls_conf->crl = crl_new; -++ if (crl_old) { -++ mbedtls_x509_crl_free(crl_old); -++ os_free(crl_old); -++ } -++ return 0; -++} -++ -++ -++static int tls_mbedtls_set_ca(struct tls_conf *tls_conf, u8 *data, size_t len) -++{ -++ /* load crt struct onto stack and then copy into tls_conf in -++ * order to preserve existing tls_conf value if error occurs -++ * -++ * hostapd is not threaded, or else should allocate memory and swap in -++ * pointer reduce race condition. (If threaded, would also need to -++ * keep reference count of use to avoid freeing while still in use.) */ -++ -++ mbedtls_x509_crt crt; -++ mbedtls_x509_crt_init(&crt); -++ int rc = mbedtls_x509_crt_parse(&crt, data, len); -++ if (rc < 0) { -++ mbedtls_x509_crt_free(&crt); -++ return rc; -++ } -++ -++ mbedtls_x509_crt_free(&tls_conf->ca_cert); -++ os_memcpy(&tls_conf->ca_cert, &crt, sizeof(crt)); -++ return 0; -++} -++ -++ -++static int tls_mbedtls_set_ca_and_crl(struct tls_conf *tls_conf, const char *ca_cert_file) -++{ -++ size_t len; -++ u8 *data; -++ if (tls_mbedtls_readfile(ca_cert_file, &data, &len)) -++ return -1; -++ -++ int rc; -++ if (0 == (rc = tls_mbedtls_set_ca(tls_conf, data, len)) -++ && (!tls_mbedtls_data_is_pem(data) /*skip parse for CRL if not PEM*/ -++ || 0 == (rc = tls_mbedtls_set_crl(tls_conf, data, len)))) { -++ mbedtls_ssl_conf_ca_chain(&tls_conf->conf, -++ &tls_conf->ca_cert, -++ tls_conf->crl); -++ } -++ else { -++ elog(rc, __func__); -++ emsg(MSG_ERROR, ca_cert_file); -++ } -++ -++ forced_memzero(data, len); -++ os_free(data); -++ return rc; -++} -++ -++ -++static void tls_mbedtls_refresh_crl(void) -++{ -++ /* check for CRL refresh -++ * continue even if error occurs; continue with previous cert, CRL */ -++ unsigned int crl_reload_interval = tls_ctx_global.crl_reload_interval; -++ const char *ca_cert_file = tls_ctx_global.ca_cert_file; -++ if (!crl_reload_interval || !ca_cert_file) -++ return; -++ -++ struct os_reltime *previous = &tls_ctx_global.crl_reload_previous; -++ struct os_reltime now; -++ if (os_get_reltime(&now) != 0 -++ || !os_reltime_expired(&now, previous, crl_reload_interval)) -++ return; -++ -++ /* Note: modifying global state is not thread-safe -++ * if in use by existing connections -++ * -++ * src/utils/os.h does not provide a portable stat() -++ * or else it would be a good idea to check mtime and size, -++ * and avoid reloading if file has not changed */ -++ -++ if (tls_mbedtls_set_ca_and_crl(tls_ctx_global.tls_conf, ca_cert_file) == 0) -++ *previous = now; -++} -++ -++ -++static int tls_mbedtls_set_ca_cert(struct tls_conf *tls_conf, -++ const struct tls_connection_params *params) -++{ -++ if (params->ca_cert) { -++ if (os_strncmp(params->ca_cert, "probe://", 8) == 0) { -++ tls_conf->ca_cert_probe = 1; -++ tls_conf->has_ca_cert = 1; -++ return 0; -++ } -++ -++ if (os_strncmp(params->ca_cert, "hash://", 7) == 0) { -++ const char *pos = params->ca_cert + 7; -++ if (os_strncmp(pos, "server/sha256/", 14) != 0) { -++ emsg(MSG_ERROR, "unsupported ca_cert hash value"); -++ return -1; -++ } -++ pos += 14; -++ if (os_strlen(pos) != SHA256_DIGEST_LENGTH*2) { -++ emsg(MSG_ERROR, "unexpected ca_cert hash length"); -++ return -1; -++ } -++ if (hexstr2bin(pos, tls_conf->ca_cert_hash, -++ SHA256_DIGEST_LENGTH) < 0) { -++ emsg(MSG_ERROR, "invalid ca_cert hash value"); -++ return -1; -++ } -++ emsg(MSG_DEBUG, "checking only server certificate match"); -++ tls_conf->verify_depth0_only = 1; -++ tls_conf->has_ca_cert = 1; -++ return 0; -++ } -++ -++ if (tls_mbedtls_set_ca_and_crl(tls_conf, params->ca_cert) != 0) -++ return -1; -++ } -++ if (params->ca_cert_blob) { -++ size_t len = params->ca_cert_blob_len; -++ int is_pem = tls_mbedtls_data_is_pem(params->ca_cert_blob); -++ if (len && params->ca_cert_blob[len-1] != '\0' && is_pem) -++ ++len; /*(include '\0' in len for PEM)*/ -++ int ret = mbedtls_x509_crt_parse(&tls_conf->ca_cert, -++ params->ca_cert_blob, len); -++ if (ret != 0) { -++ elog(ret, "mbedtls_x509_crt_parse"); -++ return -1; -++ } -++ if (is_pem) { /*(ca_cert_blob in DER format contains ca cert only)*/ -++ ret = tls_mbedtls_set_crl(tls_conf, params->ca_cert_blob, len); -++ if (ret != 0) { -++ elog(ret, "mbedtls_x509_crl_parse"); -++ return -1; -++ } -++ } -++ } -++ -++ if (mbedtls_x509_time_is_future(&tls_conf->ca_cert.valid_from) -++ || mbedtls_x509_time_is_past(&tls_conf->ca_cert.valid_to)) { -++ emsg(MSG_WARNING, "ca_cert expired or not yet valid"); -++ if (params->ca_cert) -++ emsg(MSG_WARNING, params->ca_cert); -++ } -++ -++ tls_conf->has_ca_cert = 1; -++ return 0; -++} -++ -++ -++static int tls_mbedtls_set_certs(struct tls_conf *tls_conf, -++ const struct tls_connection_params *params) -++{ -++ int ret; -++ -++ if (params->ca_cert || params->ca_cert_blob) { -++ if (tls_mbedtls_set_ca_cert(tls_conf, params) != 0) -++ return -1; -++ } -++ else if (params->ca_path) { -++ emsg(MSG_INFO, "ca_path support not implemented"); -++ return -1; -++ } -++ -++ if (!tls_conf->has_ca_cert) -++ mbedtls_ssl_conf_authmode(&tls_conf->conf, MBEDTLS_SSL_VERIFY_NONE); -++ else { -++ /* Initial setting: REQUIRED for client, OPTIONAL for server -++ * (see also tls_connection_set_verify()) */ -++ tls_conf->verify_peer = (tls_ctx_global.tls_conf == NULL); -++ int authmode = tls_conf->verify_peer -++ ? MBEDTLS_SSL_VERIFY_REQUIRED -++ : MBEDTLS_SSL_VERIFY_OPTIONAL; -++ mbedtls_ssl_conf_authmode(&tls_conf->conf, authmode); -++ mbedtls_ssl_conf_ca_chain(&tls_conf->conf, -++ &tls_conf->ca_cert, -++ tls_conf->crl); -++ -++ if (!tls_connection_set_subject_match(tls_conf, params)) -++ return -1; -++ } -++ -++ if (params->client_cert2) /*(yes, server_cert2 in msg below)*/ -++ emsg(MSG_INFO, "server_cert2 support not implemented"); -++ -++ if (params->client_cert) { -++ size_t len; -++ u8 *data; -++ if (tls_mbedtls_readfile(params->client_cert, &data, &len)) -++ return -1; -++ ret = mbedtls_x509_crt_parse(&tls_conf->client_cert, data, len); -++ forced_memzero(data, len); -++ os_free(data); -++ } -++ if (params->client_cert_blob) { -++ size_t len = params->client_cert_blob_len; -++ if (len && params->client_cert_blob[len-1] != '\0' -++ && tls_mbedtls_data_is_pem(params->client_cert_blob)) -++ ++len; /*(include '\0' in len for PEM)*/ -++ ret = mbedtls_x509_crt_parse(&tls_conf->client_cert, -++ params->client_cert_blob, len); -++ } -++ if (params->client_cert || params->client_cert_blob) { -++ if (ret < 0) { -++ elog(ret, "mbedtls_x509_crt_parse"); -++ if (params->client_cert) -++ emsg(MSG_ERROR, params->client_cert); -++ return -1; -++ } -++ if (mbedtls_x509_time_is_future(&tls_conf->client_cert.valid_from) -++ || mbedtls_x509_time_is_past(&tls_conf->client_cert.valid_to)) { -++ emsg(MSG_WARNING, "cert expired or not yet valid"); -++ if (params->client_cert) -++ emsg(MSG_WARNING, params->client_cert); -++ } -++ tls_conf->has_client_cert = 1; -++ } -++ -++ if (params->private_key || params->private_key_blob) { -++ size_t len = params->private_key_blob_len; -++ u8 *data; -++ *(const u8 **)&data = params->private_key_blob; -++ if (len && data[len-1] != '\0' && tls_mbedtls_data_is_pem(data)) -++ ++len; /*(include '\0' in len for PEM)*/ -++ if (params->private_key -++ && tls_mbedtls_readfile(params->private_key, &data, &len)) { -++ return -1; -++ } -++ const char *pwd = params->private_key_passwd; -++ #if MBEDTLS_VERSION_NUMBER >= 0x03000000 /* mbedtls 3.0.0 */ -++ ret = mbedtls_pk_parse_key(&tls_conf->private_key, -++ data, len, -++ (const unsigned char *)pwd, -++ pwd ? os_strlen(pwd) : 0, -++ mbedtls_ctr_drbg_random, -++ tls_ctx_global.ctr_drbg); -++ #else -++ ret = mbedtls_pk_parse_key(&tls_conf->private_key, -++ data, len, -++ (const unsigned char *)pwd, -++ pwd ? os_strlen(pwd) : 0); -++ #endif -++ if (params->private_key) { -++ forced_memzero(data, len); -++ os_free(data); -++ } -++ if (ret < 0) { -++ elog(ret, "mbedtls_pk_parse_key"); -++ return -1; -++ } -++ tls_conf->has_private_key = 1; -++ } -++ -++ if (tls_conf->has_client_cert && tls_conf->has_private_key) { -++ ret = mbedtls_ssl_conf_own_cert( -++ &tls_conf->conf, &tls_conf->client_cert, &tls_conf->private_key); -++ if (ret < 0) { -++ elog(ret, "mbedtls_ssl_conf_own_cert"); -++ return -1; -++ } -++ } -++ -++ return 0; -++} -++ -++ -++/* mbedtls_x509_crt_profile_suiteb plus rsa_min_bitlen 2048 */ -++/* (reference: see also mbedtls_x509_crt_profile_next) */ -++/* ??? should permit SHA-512, too, and additional curves ??? */ -++static const mbedtls_x509_crt_profile tls_mbedtls_crt_profile_suiteb128 = -++{ -++ /* Only SHA-256 and 384 */ -++ MBEDTLS_X509_ID_FLAG( MBEDTLS_MD_SHA256 ) | -++ MBEDTLS_X509_ID_FLAG( MBEDTLS_MD_SHA384 ), -++ /* Only ECDSA */ -++ MBEDTLS_X509_ID_FLAG( MBEDTLS_PK_ECDSA ) | -++ MBEDTLS_X509_ID_FLAG( MBEDTLS_PK_ECKEY ), -++#if defined(MBEDTLS_ECP_C) -++ /* Only NIST P-256 and P-384 */ -++ MBEDTLS_X509_ID_FLAG( MBEDTLS_ECP_DP_SECP256R1 ) | -++ MBEDTLS_X509_ID_FLAG( MBEDTLS_ECP_DP_SECP384R1 ), -++#else -++ 0, -++#endif -++ 2048, -++}; -++ -++ -++/* stricter than mbedtls_x509_crt_profile_suiteb */ -++/* (reference: see also mbedtls_x509_crt_profile_next) */ -++/* ??? should permit SHA-512, too, and additional curves ??? */ -++static const mbedtls_x509_crt_profile tls_mbedtls_crt_profile_suiteb192 = -++{ -++ /* Only SHA-384 */ -++ MBEDTLS_X509_ID_FLAG( MBEDTLS_MD_SHA384 ), -++ /* Only ECDSA */ -++ MBEDTLS_X509_ID_FLAG( MBEDTLS_PK_ECDSA ) | -++ MBEDTLS_X509_ID_FLAG( MBEDTLS_PK_ECKEY ), -++#if defined(MBEDTLS_ECP_C) -++ /* Only NIST P-384 */ -++ MBEDTLS_X509_ID_FLAG( MBEDTLS_ECP_DP_SECP384R1 ), -++#else -++ 0, -++#endif -++ 3072, -++}; -++ -++ -++/* stricter than mbedtls_x509_crt_profile_suiteb except allow any PK alg */ -++/* (reference: see also mbedtls_x509_crt_profile_next) */ -++/* ??? should permit SHA-512, too, and additional curves ??? */ -++static const mbedtls_x509_crt_profile tls_mbedtls_crt_profile_suiteb192_anypk = -++{ -++ /* Only SHA-384 */ -++ MBEDTLS_X509_ID_FLAG( MBEDTLS_MD_SHA384 ), -++ 0xFFFFFFF, /* Any PK alg */ -++#if defined(MBEDTLS_ECP_C) -++ /* Only NIST P-384 */ -++ MBEDTLS_X509_ID_FLAG( MBEDTLS_ECP_DP_SECP384R1 ), -++#else -++ 0, -++#endif -++ 3072, -++}; -++ -++ -++static int tls_mbedtls_set_params(struct tls_conf *tls_conf, -++ const struct tls_connection_params *params) -++{ -++ tls_conf->flags = params->flags; -++ -++ if (tls_conf->flags & TLS_CONN_REQUIRE_OCSP_ALL) { -++ emsg(MSG_INFO, "ocsp=3 not supported"); -++ return -1; -++ } -++ -++ if (tls_conf->flags & TLS_CONN_REQUIRE_OCSP) { -++ emsg(MSG_INFO, "ocsp not supported"); -++ return -1; -++ } -++ -++ int suiteb128 = 0; -++ int suiteb192 = 0; -++ if (params->openssl_ciphers) { -++ if (os_strcmp(params->openssl_ciphers, "SUITEB192") == 0) { -++ suiteb192 = 1; -++ tls_conf->flags |= TLS_CONN_SUITEB; -++ } -++ if (os_strcmp(params->openssl_ciphers, "SUITEB128") == 0) { -++ suiteb128 = 1; -++ tls_conf->flags |= TLS_CONN_SUITEB; -++ } -++ } -++ -++ int ret = mbedtls_ssl_config_defaults( -++ &tls_conf->conf, tls_ctx_global.tls_conf ? MBEDTLS_SSL_IS_SERVER -++ : MBEDTLS_SSL_IS_CLIENT, -++ MBEDTLS_SSL_TRANSPORT_STREAM, -++ (tls_conf->flags & TLS_CONN_SUITEB) ? MBEDTLS_SSL_PRESET_SUITEB -++ : MBEDTLS_SSL_PRESET_DEFAULT); -++ if (ret != 0) { -++ elog(ret, "mbedtls_ssl_config_defaults"); -++ return -1; -++ } -++ -++ if (suiteb128) { -++ mbedtls_ssl_conf_cert_profile(&tls_conf->conf, -++ &tls_mbedtls_crt_profile_suiteb128); -++ mbedtls_ssl_conf_dhm_min_bitlen(&tls_conf->conf, 2048); -++ } -++ else if (suiteb192) { -++ mbedtls_ssl_conf_cert_profile(&tls_conf->conf, -++ &tls_mbedtls_crt_profile_suiteb192); -++ mbedtls_ssl_conf_dhm_min_bitlen(&tls_conf->conf, 3072); -++ } -++ else if (tls_conf->flags & TLS_CONN_SUITEB) { -++ /* treat as suiteb192 while allowing any PK algorithm */ -++ mbedtls_ssl_conf_cert_profile(&tls_conf->conf, -++ &tls_mbedtls_crt_profile_suiteb192_anypk); -++ mbedtls_ssl_conf_dhm_min_bitlen(&tls_conf->conf, 3072); -++ } -++ -++ tls_mbedtls_set_allowed_tls_vers(tls_conf, &tls_conf->conf); -++ ret = tls_mbedtls_set_certs(tls_conf, params); -++ if (ret != 0) -++ return -1; -++ -++ if (params->dh_file -++ && !tls_mbedtls_set_dhparams(tls_conf, params->dh_file)) { -++ return -1; -++ } -++ -++ if (params->openssl_ecdh_curves -++ && !tls_mbedtls_set_curves(tls_conf, params->openssl_ecdh_curves)) { -++ return -1; -++ } -++ -++ if (params->openssl_ciphers) { -++ if (!tls_mbedtls_set_ciphers(tls_conf, params->openssl_ciphers)) -++ return -1; -++ } -++ else if (tls_conf->flags & TLS_CONN_SUITEB) { -++ /* special-case a select set of ciphers for hwsim tests */ -++ if (!tls_mbedtls_set_ciphers(tls_conf, -++ (tls_conf->flags & TLS_CONN_SUITEB_NO_ECDH) -++ ? "DHE-RSA-AES256-GCM-SHA384" -++ : "ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES256-GCM-SHA384")) -++ return -1; -++ } -++ -++ return 0; -++} -++ -++ -++int tls_connection_set_params(void *tls_ctx, struct tls_connection *conn, -++ const struct tls_connection_params *params) -++{ -++ if (conn == NULL || params == NULL) -++ return -1; -++ -++ tls_conf_deinit(conn->tls_conf); -++ struct tls_conf *tls_conf = conn->tls_conf = tls_conf_init(tls_ctx); -++ if (tls_conf == NULL) -++ return -1; -++ -++ if (tls_ctx_global.tls_conf) { -++ tls_conf->check_crl = tls_ctx_global.tls_conf->check_crl; -++ tls_conf->check_crl_strict = tls_ctx_global.tls_conf->check_crl_strict; -++ /*(tls_openssl.c inherits check_cert_subject from global conf)*/ -++ if (tls_ctx_global.tls_conf->check_cert_subject) { -++ tls_conf->check_cert_subject = -++ os_strdup(tls_ctx_global.tls_conf->check_cert_subject); -++ if (tls_conf->check_cert_subject == NULL) -++ return -1; -++ } -++ } -++ -++ if (tls_mbedtls_set_params(tls_conf, params) != 0) -++ return -1; -++ conn->verify_peer = tls_conf->verify_peer; -++ -++ return tls_mbedtls_ssl_setup(conn); -++} -++ -++ -++#ifdef TLS_MBEDTLS_SESSION_TICKETS -++ -++static int tls_mbedtls_clienthello_session_ticket_prep (struct tls_connection *conn, -++ const u8 *data, size_t len) -++{ -++ if (conn->tls_conf->flags & TLS_CONN_DISABLE_SESSION_TICKET) -++ return -1; -++ if (conn->clienthello_session_ticket) -++ tls_connection_deinit_clienthello_session_ticket(conn); -++ if (len) { -++ conn->clienthello_session_ticket = mbedtls_calloc(1, len); -++ if (conn->clienthello_session_ticket == NULL) -++ return -1; -++ conn->clienthello_session_ticket_len = len; -++ os_memcpy(conn->clienthello_session_ticket, data, len); -++ } -++ return 0; -++} -++ -++ -++static void tls_mbedtls_clienthello_session_ticket_set (struct tls_connection *conn) -++{ -++ mbedtls_ssl_session *sess = conn->ssl.MBEDTLS_PRIVATE(session_negotiate); -++ if (sess->MBEDTLS_PRIVATE(ticket)) { -++ mbedtls_platform_zeroize(sess->MBEDTLS_PRIVATE(ticket), -++ sess->MBEDTLS_PRIVATE(ticket_len)); -++ mbedtls_free(sess->MBEDTLS_PRIVATE(ticket)); -++ } -++ sess->MBEDTLS_PRIVATE(ticket) = conn->clienthello_session_ticket; -++ sess->MBEDTLS_PRIVATE(ticket_len) = conn->clienthello_session_ticket_len; -++ sess->MBEDTLS_PRIVATE(ticket_lifetime) = 86400;/* XXX: can hint be 0? */ -++ -++ conn->clienthello_session_ticket = NULL; -++ conn->clienthello_session_ticket_len = 0; -++} -++ -++ -++static int tls_mbedtls_ssl_ticket_write(void *p_ticket, -++ const mbedtls_ssl_session *session, -++ unsigned char *start, -++ const unsigned char *end, -++ size_t *tlen, -++ uint32_t *lifetime) -++{ -++ struct tls_connection *conn = p_ticket; -++ if (conn && conn->session_ticket_cb) { -++ /* see tls_mbedtls_clienthello_session_ticket_prep() */ -++ /* see tls_mbedtls_clienthello_session_ticket_set() */ -++ return 0; -++ } -++ -++ return mbedtls_ssl_ticket_write(&tls_ctx_global.ticket_ctx, -++ session, start, end, tlen, lifetime); -++} -++ -++ -++static int tls_mbedtls_ssl_ticket_parse(void *p_ticket, -++ mbedtls_ssl_session *session, -++ unsigned char *buf, -++ size_t len) -++{ -++ /* XXX: TODO: not implemented in client; -++ * mbedtls_ssl_conf_session_tickets_cb() callbacks only for TLS server*/ -++ -++ if (len == 0) -++ return MBEDTLS_ERR_SSL_BAD_INPUT_DATA; -++ -++ struct tls_connection *conn = p_ticket; -++ if (conn && conn->session_ticket_cb) { -++ /* XXX: have random and secret been initialized yet? -++ * or must keys first be exported? -++ * EAP-FAST uses all args, EAP-TEAP only uses secret */ -++ struct tls_random data; -++ if (tls_connection_get_random(NULL, conn, &data) != 0) -++ return MBEDTLS_ERR_SSL_INTERNAL_ERROR; -++ int ret = -++ conn->session_ticket_cb(conn->session_ticket_cb_ctx, -++ buf, len, -++ data.client_random, -++ data.server_random, -++ conn->expkey_secret); -++ if (ret == 1) { -++ conn->resumed = 1; -++ return 0; -++ } -++ emsg(MSG_ERROR, "EAP session ticket ext not implemented"); -++ return MBEDTLS_ERR_SSL_INVALID_MAC; -++ /*(non-zero return used for mbedtls debug logging)*/ -++ } -++ -++ /* XXX: TODO always use tls_mbedtls_ssl_ticket_parse() for callback? */ -++ int rc = mbedtls_ssl_ticket_parse(&tls_ctx_global.ticket_ctx, -++ session, buf, len); -++ if (conn) -++ conn->resumed = (rc == 0); -++ return rc; -++} -++ -++#endif /* TLS_MBEDTLS_SESSION_TICKETS */ -++ -++ -++__attribute_cold__ -++int tls_global_set_params(void *tls_ctx, -++ const struct tls_connection_params *params) -++{ -++ /* XXX: why might global_set_params be called more than once? */ -++ if (tls_ctx_global.tls_conf) -++ tls_conf_deinit(tls_ctx_global.tls_conf); -++ tls_ctx_global.tls_conf = tls_conf_init(tls_ctx); -++ if (tls_ctx_global.tls_conf == NULL) -++ return -1; -++ -++ #ifdef MBEDTLS_SSL_SESSION_TICKETS -++ #ifdef MBEDTLS_SSL_TICKET_C -++ if (!(params->flags & TLS_CONN_DISABLE_SESSION_TICKET)) -++ #ifdef TLS_MBEDTLS_SESSION_TICKETS -++ mbedtls_ssl_conf_session_tickets_cb(&tls_ctx_global.tls_conf->conf, -++ tls_mbedtls_ssl_ticket_write, -++ tls_mbedtls_ssl_ticket_parse, -++ NULL); -++ #else -++ mbedtls_ssl_conf_session_tickets_cb(&tls_ctx_global.tls_conf->conf, -++ mbedtls_ssl_ticket_write, -++ mbedtls_ssl_ticket_parse, -++ &tls_ctx_global.ticket_ctx); -++ #endif -++ #endif -++ #endif -++ -++ os_free(tls_ctx_global.ocsp_stapling_response); -++ tls_ctx_global.ocsp_stapling_response = NULL; -++ if (params->ocsp_stapling_response) -++ tls_ctx_global.ocsp_stapling_response = -++ os_strdup(params->ocsp_stapling_response); -++ -++ os_free(tls_ctx_global.ca_cert_file); -++ tls_ctx_global.ca_cert_file = NULL; -++ if (params->ca_cert) -++ tls_ctx_global.ca_cert_file = os_strdup(params->ca_cert); -++ return tls_mbedtls_set_params(tls_ctx_global.tls_conf, params); -++} -++ -++ -++int tls_global_set_verify(void *tls_ctx, int check_crl, int strict) -++{ -++ tls_ctx_global.tls_conf->check_crl = check_crl; -++ tls_ctx_global.tls_conf->check_crl_strict = strict; /*(time checks)*/ -++ return 0; -++} -++ -++ -++int tls_connection_set_verify(void *tls_ctx, struct tls_connection *conn, -++ int verify_peer, unsigned int flags, -++ const u8 *session_ctx, size_t session_ctx_len) -++{ -++ /*(EAP server-side calls this from eap_server_tls_ssl_init())*/ -++ if (conn == NULL) -++ return -1; -++ -++ conn->tls_conf->flags |= flags;/* TODO: reprocess flags, if necessary */ -++ -++ int authmode; -++ switch (verify_peer) { -++ case 2: authmode = MBEDTLS_SSL_VERIFY_OPTIONAL; break;/*(eap_teap_init())*/ -++ case 1: authmode = MBEDTLS_SSL_VERIFY_REQUIRED; break; -++ default: authmode = MBEDTLS_SSL_VERIFY_NONE; break; -++ } -++ mbedtls_ssl_set_hs_authmode(&conn->ssl, authmode); -++ -++ if ((conn->verify_peer = (authmode != MBEDTLS_SSL_VERIFY_NONE))) -++ mbedtls_ssl_set_verify(&conn->ssl, tls_mbedtls_verify_cb, conn); -++ else -++ mbedtls_ssl_set_verify(&conn->ssl, NULL, NULL); -++ -++ return 0; -++} -++ -++ -++#if MBEDTLS_VERSION_NUMBER >= 0x03000000 /* mbedtls 3.0.0 */ -++static void tls_connection_export_keys_cb( -++ void *p_expkey, mbedtls_ssl_key_export_type secret_type, -++ const unsigned char *secret, size_t secret_len, -++ const unsigned char client_random[MBEDTLS_EXPKEY_RAND_LEN], -++ const unsigned char server_random[MBEDTLS_EXPKEY_RAND_LEN], -++ mbedtls_tls_prf_types tls_prf_type) -++{ -++ struct tls_connection *conn = p_expkey; -++ conn->tls_prf_type = tls_prf_type; -++ if (!tls_prf_type) -++ return; -++ if (secret_len > sizeof(conn->expkey_secret)) { -++ emsg(MSG_ERROR, "tls_connection_export_keys_cb secret too long"); -++ conn->tls_prf_type = MBEDTLS_SSL_TLS_PRF_NONE; /* 0 */ -++ return; -++ } -++ conn->expkey_secret_len = secret_len; -++ os_memcpy(conn->expkey_secret, secret, secret_len); -++ os_memcpy(conn->expkey_randbytes, -++ client_random, MBEDTLS_EXPKEY_RAND_LEN); -++ os_memcpy(conn->expkey_randbytes + MBEDTLS_EXPKEY_RAND_LEN, -++ server_random, MBEDTLS_EXPKEY_RAND_LEN); -++} -++#elif MBEDTLS_VERSION_NUMBER >= 0x02120000 /* mbedtls 2.18.0 */ -++static int tls_connection_export_keys_cb( -++ void *p_expkey, -++ const unsigned char *ms, -++ const unsigned char *kb, -++ size_t maclen, -++ size_t keylen, -++ size_t ivlen, -++ const unsigned char client_random[MBEDTLS_EXPKEY_RAND_LEN], -++ const unsigned char server_random[MBEDTLS_EXPKEY_RAND_LEN], -++ mbedtls_tls_prf_types tls_prf_type ) -++{ -++ struct tls_connection *conn = p_expkey; -++ conn->tls_prf_type = tls_prf_type; -++ if (!tls_prf_type) -++ return -1; /*(return value ignored by mbedtls)*/ -++ conn->expkey_keyblock_size = maclen + keylen + ivlen; -++ conn->expkey_secret_len = MBEDTLS_EXPKEY_FIXED_SECRET_LEN; -++ os_memcpy(conn->expkey_secret, ms, MBEDTLS_EXPKEY_FIXED_SECRET_LEN); -++ os_memcpy(conn->expkey_randbytes, -++ client_random, MBEDTLS_EXPKEY_RAND_LEN); -++ os_memcpy(conn->expkey_randbytes + MBEDTLS_EXPKEY_RAND_LEN, -++ server_random, MBEDTLS_EXPKEY_RAND_LEN); -++ return 0; -++} -++#endif -++ -++ -++int tls_connection_get_random(void *tls_ctx, struct tls_connection *conn, -++ struct tls_random *data) -++{ -++ if (!conn || !conn->tls_prf_type) -++ return -1; -++ data->client_random = conn->expkey_randbytes; -++ data->client_random_len = MBEDTLS_EXPKEY_RAND_LEN; -++ data->server_random = conn->expkey_randbytes + MBEDTLS_EXPKEY_RAND_LEN; -++ data->server_random_len = MBEDTLS_EXPKEY_RAND_LEN; -++ return 0; -++} -++ -++ -++int tls_connection_export_key(void *tls_ctx, struct tls_connection *conn, -++ const char *label, const u8 *context, -++ size_t context_len, u8 *out, size_t out_len) -++{ -++ /* (EAP-PEAP EAP-TLS EAP-TTLS) */ -++ #if MBEDTLS_VERSION_NUMBER >= 0x02120000 /* mbedtls 2.18.0 */ -++ return (conn && conn->established && conn->tls_prf_type) -++ ? mbedtls_ssl_tls_prf(conn->tls_prf_type, -++ conn->expkey_secret, conn->expkey_secret_len, label, -++ conn->expkey_randbytes, -++ sizeof(conn->expkey_randbytes), out, out_len) -++ : -1; -++ #else -++ /* not implemented here for mbedtls < 2.18.0 */ -++ return -1; -++ #endif -++} -++ -++ -++#ifdef TLS_MBEDTLS_EAP_FAST -++ -++#if MBEDTLS_VERSION_NUMBER >= 0x03000000 /* mbedtls 3.0.0 */ -++/* keyblock size info is not exposed in mbed TLS 3.0.0 */ -++/* extracted from mbedtls library/ssl_tls.c:ssl_tls12_populate_transform() */ -++#include -++#include -++static size_t tls_mbedtls_ssl_keyblock_size (mbedtls_ssl_context *ssl) -++{ -++ #if !defined(MBEDTLS_USE_PSA_CRYPTO) /* XXX: (not extracted for PSA crypto) */ -++ #if defined(MBEDTLS_SSL_PROTO_TLS1_3) -++ if (tls_version == MBEDTLS_SSL_VERSION_TLS1_3) -++ return 0; /* (calculation not extracted) */ -++ #endif /* MBEDTLS_SSL_PROTO_TLS1_3 */ -++ -++ int ciphersuite = mbedtls_ssl_get_ciphersuite_id_from_ssl(ssl); -++ const mbedtls_ssl_ciphersuite_t *ciphersuite_info = -++ mbedtls_ssl_ciphersuite_from_id(ciphersuite); -++ if (ciphersuite_info == NULL) -++ return 0; -++ -++ const mbedtls_cipher_info_t *cipher_info = -++ mbedtls_cipher_info_from_type(ciphersuite_info->MBEDTLS_PRIVATE(cipher)); -++ if (cipher_info == NULL) -++ return 0; -++ -++ #if MBEDTLS_VERSION_NUMBER >= 0x03010000 /* mbedtls 3.1.0 */ -++ size_t keylen = mbedtls_cipher_info_get_key_bitlen(cipher_info) / 8; -++ mbedtls_cipher_mode_t mode = mbedtls_cipher_info_get_mode(cipher_info); -++ #else -++ size_t keylen = cipher_info->MBEDTLS_PRIVATE(key_bitlen) / 8; -++ mbedtls_cipher_mode_t mode = cipher_info->MBEDTLS_PRIVATE(mode); -++ #endif -++ #if defined(MBEDTLS_GCM_C) || \ -++ defined(MBEDTLS_CCM_C) || \ -++ defined(MBEDTLS_CHACHAPOLY_C) -++ if (mode == MBEDTLS_MODE_GCM || mode == MBEDTLS_MODE_CCM) -++ return keylen + 4; -++ else if (mode == MBEDTLS_MODE_CHACHAPOLY) -++ return keylen + 12; -++ else -++ #endif /* MBEDTLS_GCM_C || MBEDTLS_CCM_C || MBEDTLS_CHACHAPOLY_C */ -++ #if defined(MBEDTLS_SSL_SOME_SUITES_USE_MAC) -++ { -++ const mbedtls_md_info_t *md_info = -++ mbedtls_md_info_from_type(ciphersuite_info->MBEDTLS_PRIVATE(mac)); -++ if (md_info == NULL) -++ return 0; -++ size_t mac_key_len = mbedtls_md_get_size(md_info); -++ size_t ivlen = mbedtls_cipher_info_get_iv_size(cipher_info); -++ return keylen + mac_key_len + ivlen; -++ } -++ #endif /* MBEDTLS_SSL_SOME_SUITES_USE_MAC */ -++ #endif /* !MBEDTLS_USE_PSA_CRYPTO *//* (not extracted for PSA crypto) */ -++ return 0; -++} -++#endif /* MBEDTLS_VERSION_NUMBER >= 0x03000000 *//* mbedtls 3.0.0 */ -++ -++ -++int tls_connection_get_eap_fast_key(void *tls_ctx, struct tls_connection *conn, -++ u8 *out, size_t out_len) -++{ -++ /* XXX: has export keys callback been run? */ -++ if (!conn || !conn->tls_prf_type) -++ return -1; -++ -++ #if MBEDTLS_VERSION_NUMBER >= 0x03000000 /* mbedtls 3.0.0 */ -++ conn->expkey_keyblock_size = tls_mbedtls_ssl_keyblock_size(&conn->ssl); -++ if (conn->expkey_keyblock_size == 0) -++ return -1; -++ #endif -++ size_t skip = conn->expkey_keyblock_size * 2; -++ unsigned char *tmp_out = os_malloc(skip + out_len); -++ if (!tmp_out) -++ return -1; -++ -++ /* server_random and then client_random */ -++ unsigned char seed[MBEDTLS_EXPKEY_RAND_LEN*2]; -++ os_memcpy(seed, conn->expkey_randbytes + MBEDTLS_EXPKEY_RAND_LEN, -++ MBEDTLS_EXPKEY_RAND_LEN); -++ os_memcpy(seed + MBEDTLS_EXPKEY_RAND_LEN, conn->expkey_randbytes, -++ MBEDTLS_EXPKEY_RAND_LEN); -++ -++ #if MBEDTLS_VERSION_NUMBER >= 0x02120000 /* mbedtls 2.18.0 */ -++ int ret = mbedtls_ssl_tls_prf(conn->tls_prf_type, -++ conn->expkey_secret, conn->expkey_secret_len, -++ "key expansion", seed, sizeof(seed), -++ tmp_out, skip + out_len); -++ if (ret == 0) -++ os_memcpy(out, tmp_out + skip, out_len); -++ #else -++ int ret = -1; /*(not reached if not impl; return -1 at top of func)*/ -++ #endif -++ -++ bin_clear_free(tmp_out, skip + out_len); -++ forced_memzero(seed, sizeof(seed)); -++ return ret; -++} -++ -++#endif /* TLS_MBEDTLS_EAP_FAST */ -++ -++ -++__attribute_cold__ -++static void tls_mbedtls_suiteb_handshake_alert (struct tls_connection *conn) -++{ -++ /* tests/hwsim/test_suite_b.py test_suite_b_192_rsa_insufficient_dh */ -++ if (!(conn->tls_conf->flags & TLS_CONN_SUITEB)) -++ return; -++ if (tls_ctx_global.tls_conf) /*(is server; want issue event on client)*/ -++ return; -++ #if 0 -++ /*(info not available on client; -++ * mbed TLS library enforces dhm min bitlen in ServerKeyExchange)*/ -++ if (MBEDTLS_TLS_DHE_RSA_WITH_AES_256_GCM_SHA384 == -++ #if MBEDTLS_VERSION_NUMBER < 0x03020000 /* mbedtls 3.2.0 */ -++ mbedtls_ssl_get_ciphersuite_id_from_ssl(&conn->ssl) -++ #else -++ mbedtls_ssl_get_ciphersuite_id( -++ mbedtls_ssl_get_ciphersuite(&conn->ssl)) -++ #endif -++ && mbedtls_mpi_size(&conn->tls_conf->conf.MBEDTLS_PRIVATE(dhm_P)) -++ < 384 /*(3072/8)*/) -++ #endif -++ { -++ struct tls_config *init_conf = &tls_ctx_global.init_conf; -++ if (init_conf->event_cb) { -++ union tls_event_data ev; -++ os_memset(&ev, 0, sizeof(ev)); -++ ev.alert.is_local = 1; -++ ev.alert.type = "fatal"; -++ /*"internal error" string for tests/hwsim/test_suiteb.py */ -++ ev.alert.description = "internal error: handshake failure"; -++ /*ev.alert.description = "insufficient security";*/ -++ init_conf->event_cb(init_conf->cb_ctx, TLS_ALERT, &ev); -++ } -++ } -++} -++ -++ -++struct wpabuf * tls_connection_handshake(void *tls_ctx, -++ struct tls_connection *conn, -++ const struct wpabuf *in_data, -++ struct wpabuf **appl_data) -++{ -++ if (appl_data) -++ *appl_data = NULL; -++ -++ if (in_data && wpabuf_len(in_data)) { -++ /*(unsure why tls_gnutls.c discards buffer contents; skip here)*/ -++ if (conn->pull_buf && 0) /* disable; appears unwise */ -++ tls_pull_buf_discard(conn, __func__); -++ if (!tls_pull_buf_append(conn, in_data)) -++ return NULL; -++ } -++ -++ if (conn->tls_conf == NULL) { -++ struct tls_connection_params params; -++ os_memset(¶ms, 0, sizeof(params)); -++ params.openssl_ciphers = -++ tls_ctx_global.init_conf.openssl_ciphers; -++ params.flags = tls_ctx_global.tls_conf->flags; -++ if (tls_connection_set_params(tls_ctx, conn, ¶ms) != 0) -++ return NULL; -++ } -++ -++ if (conn->verify_peer) /*(call here might be redundant; nbd)*/ -++ mbedtls_ssl_set_verify(&conn->ssl, tls_mbedtls_verify_cb, conn); -++ -++ #ifdef TLS_MBEDTLS_SESSION_TICKETS -++ if (conn->clienthello_session_ticket) -++ /*(starting handshake for EAP-FAST and EAP-TEAP)*/ -++ tls_mbedtls_clienthello_session_ticket_set(conn); -++ -++ /* (not thread-safe due to need to set userdata 'conn' for callback) */ -++ /* (unable to use mbedtls_ssl_set_user_data_p() with mbedtls 3.2.0+ -++ * since ticket write and parse callbacks take (mbedtls_ssl_session *) -++ * param instead of (mbedtls_ssl_context *) param) */ -++ if (conn->tls_conf->flags & TLS_CONN_DISABLE_SESSION_TICKET) -++ mbedtls_ssl_conf_session_tickets_cb(&conn->tls_conf->conf, -++ NULL, NULL, NULL); -++ else -++ mbedtls_ssl_conf_session_tickets_cb(&conn->tls_conf->conf, -++ tls_mbedtls_ssl_ticket_write, -++ tls_mbedtls_ssl_ticket_parse, -++ conn); -++ #endif -++ -++ #if MBEDTLS_VERSION_NUMBER >= 0x03020000 /* mbedtls 3.2.0 */ -++ int ret = mbedtls_ssl_handshake(&conn->ssl); -++ #else -++ int ret = 0; -++ while (conn->ssl.MBEDTLS_PRIVATE(state) != MBEDTLS_SSL_HANDSHAKE_OVER) { -++ ret = mbedtls_ssl_handshake_step(&conn->ssl); -++ if (ret != 0) -++ break; -++ } -++ #endif -++ -++ #ifdef TLS_MBEDTLS_SESSION_TICKETS -++ mbedtls_ssl_conf_session_tickets_cb(&conn->tls_conf->conf, -++ tls_mbedtls_ssl_ticket_write, -++ tls_mbedtls_ssl_ticket_parse, -++ NULL); -++ #endif -++ -++ switch (ret) { -++ case 0: -++ conn->established = 1; -++ if (conn->push_buf == NULL) -++ /* Need to return something to get final TLS ACK. */ -++ conn->push_buf = wpabuf_alloc(0); -++ -++ if (appl_data /*&& conn->pull_buf && wpabuf_len(conn->pull_buf)*/) -++ *appl_data = NULL; /* RFE: check for application data */ -++ break; -++ case MBEDTLS_ERR_SSL_WANT_WRITE: -++ case MBEDTLS_ERR_SSL_WANT_READ: -++ case MBEDTLS_ERR_SSL_CRYPTO_IN_PROGRESS: -++ case MBEDTLS_ERR_SSL_ASYNC_IN_PROGRESS: -++ if (tls_ctx_global.tls_conf /*(is server)*/ -++ && conn->established && conn->push_buf == NULL) -++ /* Need to return something to trigger completion of EAP-TLS. */ -++ conn->push_buf = wpabuf_alloc(0); -++ break; -++ default: -++ ++conn->failed; -++ switch (ret) { -++ case MBEDTLS_ERR_SSL_CLIENT_RECONNECT: -++ case MBEDTLS_ERR_NET_CONN_RESET: -++ case MBEDTLS_ERR_NET_SEND_FAILED: -++ ++conn->write_alerts; -++ break; -++ #if MBEDTLS_VERSION_NUMBER >= 0x03000000 /* mbedtls 3.0.0 */ -++ case MBEDTLS_ERR_SSL_HANDSHAKE_FAILURE: -++ #else -++ case MBEDTLS_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE: -++ #endif -++ tls_mbedtls_suiteb_handshake_alert(conn); -++ /* fall through */ -++ case MBEDTLS_ERR_NET_RECV_FAILED: -++ case MBEDTLS_ERR_SSL_CONN_EOF: -++ case MBEDTLS_ERR_SSL_PEER_CLOSE_NOTIFY: -++ case MBEDTLS_ERR_SSL_FATAL_ALERT_MESSAGE: -++ ++conn->read_alerts; -++ break; -++ default: -++ break; -++ } -++ -++ ilog(ret, "mbedtls_ssl_handshake"); -++ break; -++ } -++ -++ struct wpabuf *out_data = conn->push_buf; -++ conn->push_buf = NULL; -++ return out_data; -++} -++ -++ -++struct wpabuf * tls_connection_server_handshake(void *tls_ctx, -++ struct tls_connection *conn, -++ const struct wpabuf *in_data, -++ struct wpabuf **appl_data) -++{ -++ conn->is_server = 1; -++ return tls_connection_handshake(tls_ctx, conn, in_data, appl_data); -++} -++ -++ -++struct wpabuf * tls_connection_encrypt(void *tls_ctx, -++ struct tls_connection *conn, -++ const struct wpabuf *in_data) -++{ -++ int res = mbedtls_ssl_write(&conn->ssl, -++ wpabuf_head_u8(in_data), wpabuf_len(in_data)); -++ if (res < 0) { -++ elog(res, "mbedtls_ssl_write"); -++ return NULL; -++ } -++ -++ struct wpabuf *buf = conn->push_buf; -++ conn->push_buf = NULL; -++ return buf; -++} -++ -++ -++struct wpabuf * tls_connection_decrypt(void *tls_ctx, -++ struct tls_connection *conn, -++ const struct wpabuf *in_data) -++{ -++ int res; -++ struct wpabuf *out; -++ -++ /*assert(in_data != NULL);*/ -++ if (!tls_pull_buf_append(conn, in_data)) -++ return NULL; -++ -++ #if defined(MBEDTLS_ZLIB_SUPPORT) /* removed in mbedtls 3.x */ -++ /* Add extra buffer space to handle the possibility of decrypted -++ * data being longer than input data due to TLS compression. */ -++ out = wpabuf_alloc((wpabuf_len(in_data) + 500) * 3); -++ #else /* TLS compression is disabled in mbedtls 3.x */ -++ out = wpabuf_alloc(wpabuf_len(in_data)); -++ #endif -++ if (out == NULL) -++ return NULL; -++ -++ res = mbedtls_ssl_read(&conn->ssl, wpabuf_mhead(out), wpabuf_size(out)); -++ if (res < 0) { -++ #if 1 /*(seems like a different error if wpabuf_len(in_data) == 0)*/ -++ if (res == MBEDTLS_ERR_SSL_WANT_READ) -++ return out; -++ #endif -++ elog(res, "mbedtls_ssl_read"); -++ wpabuf_free(out); -++ return NULL; -++ } -++ wpabuf_put(out, res); -++ -++ return out; -++} -++ -++ -++int tls_connection_resumed(void *tls_ctx, struct tls_connection *conn) -++{ -++ /* XXX: might need to detect if session resumed from TLS session ticket -++ * even if not special session ticket handling for EAP-FAST, EAP-TEAP */ -++ /* (?ssl->handshake->resume during session ticket validation?) */ -++ return conn && conn->resumed; -++} -++ -++ -++#ifdef TLS_MBEDTLS_EAP_FAST -++int tls_connection_set_cipher_list(void *tls_ctx, struct tls_connection *conn, -++ u8 *ciphers) -++{ -++ /* ciphers is list of TLS_CIPHER_* from hostap/src/crypto/tls.h */ -++ int ids[7]; -++ const int idsz = (int)sizeof(ids); -++ int nids = -1, id; -++ for ( ; *ciphers != TLS_CIPHER_NONE; ++ciphers) { -++ switch (*ciphers) { -++ case TLS_CIPHER_RC4_SHA: -++ #ifdef MBEDTLS_TLS_RSA_WITH_RC4_128_SHA -++ id = MBEDTLS_TLS_RSA_WITH_RC4_128_SHA; -++ break; -++ #else -++ continue; /*(not supported in mbedtls 3.x; ignore)*/ -++ #endif -++ case TLS_CIPHER_AES128_SHA: -++ id = MBEDTLS_TLS_RSA_WITH_AES_128_CBC_SHA; -++ break; -++ case TLS_CIPHER_RSA_DHE_AES128_SHA: -++ id = MBEDTLS_TLS_DHE_RSA_WITH_AES_128_CBC_SHA; -++ break; -++ case TLS_CIPHER_ANON_DH_AES128_SHA: -++ continue; /*(not supported in mbedtls; ignore)*/ -++ case TLS_CIPHER_RSA_DHE_AES256_SHA: -++ id = MBEDTLS_TLS_DHE_RSA_WITH_AES_256_CBC_SHA; -++ break; -++ case TLS_CIPHER_AES256_SHA: -++ id = MBEDTLS_TLS_RSA_WITH_AES_256_CBC_SHA; -++ break; -++ default: -++ return -1; /* should not happen */ -++ } -++ if (++nids == idsz) -++ return -1; /* should not happen */ -++ ids[nids] = id; -++ } -++ if (nids < 0) -++ return 0; /* nothing to do */ -++ if (++nids == idsz) -++ return -1; /* should not happen */ -++ ids[nids] = 0; /* terminate list */ -++ ++nids; -++ -++ return tls_mbedtls_set_ciphersuites(conn->tls_conf, ids, nids) ? 0 : -1; -++} -++#endif -++ -++ -++int tls_get_version(void *ssl_ctx, struct tls_connection *conn, -++ char *buf, size_t buflen) -++{ -++ if (conn == NULL) -++ return -1; -++ os_strlcpy(buf, mbedtls_ssl_get_version(&conn->ssl), buflen); -++ return buf[0] != 'u' ? 0 : -1; /*(-1 if "unknown")*/ -++} -++ -++ -++#ifdef TLS_MBEDTLS_EAP_TEAP -++u16 tls_connection_get_cipher_suite(struct tls_connection *conn) -++{ -++ if (conn == NULL) -++ return 0; -++ return (u16)mbedtls_ssl_get_ciphersuite_id_from_ssl(&conn->ssl); -++} -++#endif -++ -++ -++int tls_get_cipher(void *tls_ctx, struct tls_connection *conn, -++ char *buf, size_t buflen) -++{ -++ if (conn == NULL) -++ return -1; -++ const int id = mbedtls_ssl_get_ciphersuite_id_from_ssl(&conn->ssl); -++ return tls_mbedtls_translate_ciphername(id, buf, buflen) ? 0 : -1; -++} -++ -++ -++#ifdef TLS_MBEDTLS_SESSION_TICKETS -++ -++int tls_connection_enable_workaround(void *tls_ctx, -++ struct tls_connection *conn) -++{ -++ /* (see comment in src/eap_peer/eap_fast.c:eap_fast_init()) */ -++ /* XXX: is there a relevant setting for this in mbed TLS? */ -++ /* (do we even care that much about older CBC ciphers?) */ -++ return 0; -++} -++ -++ -++int tls_connection_client_hello_ext(void *tls_ctx, struct tls_connection *conn, -++ int ext_type, const u8 *data, -++ size_t data_len) -++{ -++ /* (EAP-FAST and EAP-TEAP) */ -++ if (ext_type == MBEDTLS_TLS_EXT_SESSION_TICKET) /*(ext_type == 35)*/ -++ return tls_mbedtls_clienthello_session_ticket_prep(conn, data, -++ data_len); -++ -++ return -1; -++} -++ -++#endif /* TLS_MBEDTLS_SESSION_TICKETS */ -++ -++ -++int tls_connection_get_failed(void *tls_ctx, struct tls_connection *conn) -++{ -++ return conn ? conn->failed : -1; -++} -++ -++ -++int tls_connection_get_read_alerts(void *tls_ctx, struct tls_connection *conn) -++{ -++ return conn ? conn->read_alerts : -1; -++} -++ -++ -++int tls_connection_get_write_alerts(void *tls_ctx, -++ struct tls_connection *conn) -++{ -++ return conn ? conn->write_alerts : -1; -++} -++ -++ -++#ifdef TLS_MBEDTLS_SESSION_TICKETS -++int tls_connection_set_session_ticket_cb( -++ void *tls_ctx, struct tls_connection *conn, -++ tls_session_ticket_cb cb, void *ctx) -++{ -++ if (!(conn->tls_conf->flags & TLS_CONN_DISABLE_SESSION_TICKET)) { -++ /* (EAP-FAST and EAP-TEAP) */ -++ conn->session_ticket_cb = cb; -++ conn->session_ticket_cb_ctx = ctx; -++ return 0; -++ } -++ return -1; -++} -++#endif -++ -++ -++int tls_get_library_version(char *buf, size_t buf_len) -++{ -++ #ifndef MBEDTLS_VERSION_C -++ const char * const ver = "n/a"; -++ #else -++ char ver[9]; -++ mbedtls_version_get_string(ver); -++ #endif -++ return os_snprintf(buf, buf_len, -++ "mbed TLS build=" MBEDTLS_VERSION_STRING " run=%s", ver); -++} -++ -++ -++void tls_connection_set_success_data(struct tls_connection *conn, -++ struct wpabuf *data) -++{ -++ wpabuf_free(conn->success_data); -++ conn->success_data = data; -++} -++ -++ -++void tls_connection_set_success_data_resumed(struct tls_connection *conn) -++{ -++} -++ -++ -++const struct wpabuf * -++tls_connection_get_success_data(struct tls_connection *conn) -++{ -++ return conn->success_data; -++} -++ -++ -++void tls_connection_remove_session(struct tls_connection *conn) -++{ -++} -++ -++ -++#ifdef TLS_MBEDTLS_EAP_TEAP -++int tls_get_tls_unique(struct tls_connection *conn, u8 *buf, size_t max_len) -++{ -++ #if defined(MBEDTLS_SSL_RENEGOTIATION) /* XXX: renegotiation or resumption? */ -++ /* data from TLS handshake Finished message */ -++ size_t verify_len = conn->ssl.MBEDTLS_PRIVATE(verify_data_len); -++ char *verify_data = (conn->is_server ^ conn->resumed) -++ ? conn->ssl.MBEDTLS_PRIVATE(peer_verify_data) -++ : conn->ssl.MBEDTLS_PRIVATE(own_verify_data); -++ if (verify_len && verify_len <= max_len) { -++ os_memcpy(buf, verify_data, verify_len); -++ return (int)verify_len; -++ } -++ #endif -++ return -1; -++} -++#endif -++ -++ -++__attribute_noinline__ -++static void tls_mbedtls_set_peer_subject(struct tls_connection *conn, const mbedtls_x509_crt *crt) -++{ -++ if (conn->peer_subject) -++ return; -++ char buf[MBEDTLS_X509_MAX_DN_NAME_SIZE*2]; -++ int buflen = mbedtls_x509_dn_gets(buf, sizeof(buf), &crt->subject); -++ if (buflen >= 0 && (conn->peer_subject = os_malloc((size_t)buflen+1))) -++ os_memcpy(conn->peer_subject, buf, (size_t)buflen+1); -++} -++ -++ -++#ifdef TLS_MBEDTLS_EAP_TEAP -++const char * tls_connection_get_peer_subject(struct tls_connection *conn) -++{ -++ if (!conn) -++ return NULL; -++ if (!conn->peer_subject) { /*(if not set during cert verify)*/ -++ const mbedtls_x509_crt *peer_cert = -++ mbedtls_ssl_get_peer_cert(&conn->ssl); -++ if (peer_cert) -++ tls_mbedtls_set_peer_subject(conn, peer_cert); -++ } -++ return conn->peer_subject; -++} -++#endif -++ -++ -++#ifdef TLS_MBEDTLS_EAP_TEAP -++bool tls_connection_get_own_cert_used(struct tls_connection *conn) -++{ -++ /* XXX: availability of cert does not necessary mean that client -++ * received certificate request from server and then sent cert. -++ * ? step handshake in tls_connection_handshake() looking for -++ * MBEDTLS_SSL_CERTIFICATE_REQUEST ? */ -++ const struct tls_conf * const tls_conf = conn->tls_conf; -++ return (tls_conf->has_client_cert && tls_conf->has_private_key); -++} -++#endif -++ -++ -++#if defined(CONFIG_FIPS) -++#define TLS_MBEDTLS_CONFIG_FIPS -++#endif -++ -++#if defined(CONFIG_SHA256) -++#define TLS_MBEDTLS_TLS_PRF_SHA256 -++#endif -++ -++#if defined(CONFIG_SHA384) -++#define TLS_MBEDTLS_TLS_PRF_SHA384 -++#endif -++ -++ -++#ifndef TLS_MBEDTLS_CONFIG_FIPS -++#if defined(CONFIG_MODULE_TESTS) -++/* unused with CONFIG_TLS=mbedtls except in crypto_module_tests.c */ -++#if MBEDTLS_VERSION_NUMBER >= 0x02120000 /* mbedtls 2.18.0 */ \ -++ && MBEDTLS_VERSION_NUMBER < 0x03000000 /* mbedtls 3.0.0 */ -++/* sha1-tlsprf.c */ -++#include "sha1.h" -++int tls_prf_sha1_md5(const u8 *secret, size_t secret_len, const char *label, -++ const u8 *seed, size_t seed_len, u8 *out, size_t outlen) -++{ -++ return mbedtls_ssl_tls_prf(MBEDTLS_SSL_TLS_PRF_TLS1, -++ secret, secret_len, label, -++ seed, seed_len, out, outlen) ? -1 : 0; -++} -++#else -++#include "sha1-tlsprf.c" /* pull in hostap local implementation */ -++#endif -++#endif -++#endif -++ -++#ifdef TLS_MBEDTLS_TLS_PRF_SHA256 -++/* sha256-tlsprf.c */ -++#if MBEDTLS_VERSION_NUMBER >= 0x02120000 /* mbedtls 2.18.0 */ -++#include "sha256.h" -++int tls_prf_sha256(const u8 *secret, size_t secret_len, const char *label, -++ const u8 *seed, size_t seed_len, u8 *out, size_t outlen) -++{ -++ return mbedtls_ssl_tls_prf(MBEDTLS_SSL_TLS_PRF_SHA256, -++ secret, secret_len, label, -++ seed, seed_len, out, outlen) ? -1 : 0; -++} -++#else -++#include "sha256-tlsprf.c" /* pull in hostap local implementation */ -++#endif -++#endif -++ -++#ifdef TLS_MBEDTLS_TLS_PRF_SHA384 -++/* sha384-tlsprf.c */ -++#if MBEDTLS_VERSION_NUMBER >= 0x02120000 /* mbedtls 2.18.0 */ -++#include "sha384.h" -++int tls_prf_sha384(const u8 *secret, size_t secret_len, const char *label, -++ const u8 *seed, size_t seed_len, u8 *out, size_t outlen) -++{ -++ return mbedtls_ssl_tls_prf(MBEDTLS_SSL_TLS_PRF_SHA384, -++ secret, secret_len, label, -++ seed, seed_len, out, outlen) ? -1 : 0; -++} -++#else -++#include "sha384-tlsprf.c" /* pull in hostap local implementation */ -++#endif -++#endif -++ -++ -++#if MBEDTLS_VERSION_NUMBER < 0x03020000 /* mbedtls 3.2.0 */ -++#define mbedtls_x509_crt_has_ext_type(crt, ext_type) \ -++ ((crt)->MBEDTLS_PRIVATE(ext_types) & (ext_type)) -++#endif -++ -++struct mlist { const char *p; size_t n; }; -++ -++ -++static int -++tls_mbedtls_match_altsubject(mbedtls_x509_crt *crt, const char *match) -++{ -++ /* RFE: this could be pre-parsed into structured data at config time */ -++ struct mlist list[256]; /*(much larger than expected)*/ -++ int nlist = 0; -++ if ( os_strncmp(match, "EMAIL:", 6) != 0 -++ && os_strncmp(match, "DNS:", 4) != 0 -++ && os_strncmp(match, "URI:", 4) != 0 ) { -++ wpa_printf(MSG_INFO, "MTLS: Invalid altSubjectName match '%s'", match); -++ return 0; -++ } -++ for (const char *s = match, *tok; *s; s = tok ? tok+1 : "") { -++ do { } while ((tok = os_strchr(s, ';')) -++ && os_strncmp(tok+1, "EMAIL:", 6) != 0 -++ && os_strncmp(tok+1, "DNS:", 4) != 0 -++ && os_strncmp(tok+1, "URI:", 4) != 0); -++ list[nlist].p = s; -++ list[nlist].n = tok ? (size_t)(tok - s) : os_strlen(s); -++ if (list[nlist].n && ++nlist == sizeof(list)/sizeof(*list)) { -++ wpa_printf(MSG_INFO, "MTLS: excessive altSubjectName match '%s'", -++ match); -++ break; /* truncate huge list and continue */ -++ } -++ } -++ -++ if (!mbedtls_x509_crt_has_ext_type(crt, MBEDTLS_X509_EXT_SUBJECT_ALT_NAME)) -++ return 0; -++ -++ const mbedtls_x509_sequence *cur = &crt->subject_alt_names; -++ for (; cur != NULL; cur = cur->next) { -++ const unsigned char san_type = (unsigned char)cur->buf.tag -++ & MBEDTLS_ASN1_TAG_VALUE_MASK; -++ char t; -++ size_t step = 4; -++ switch (san_type) { /* "EMAIL:" or "DNS:" or "URI:" */ -++ case MBEDTLS_X509_SAN_RFC822_NAME: step = 6; t = 'E'; break; -++ case MBEDTLS_X509_SAN_DNS_NAME: t = 'D'; break; -++ case MBEDTLS_X509_SAN_UNIFORM_RESOURCE_IDENTIFIER: t = 'U'; break; -++ default: continue; -++ } -++ -++ for (int i = 0; i < nlist; ++i) { -++ /* step over "EMAIL:" or "DNS:" or "URI:" in list[i].p */ -++ /* Note: v is not '\0'-terminated, but is a known length vlen, -++ * so okay to pass to os_strncasecmp() even though not z-string */ -++ if (cur->buf.len == list[i].n - step && t == *list[i].p -++ && 0 == os_strncasecmp((char *)cur->buf.p, -++ list[i].p+step, cur->buf.len)) { -++ return 1; /* match */ -++ } -++ } -++ } -++ return 0; /* no match */ -++} -++ -++ -++static int -++tls_mbedtls_match_suffix(const char *v, size_t vlen, -++ const struct mlist *list, int nlist, int full) -++{ -++ /* Note: v is not '\0'-terminated, but is a known length vlen, -++ * so okay to pass to os_strncasecmp() even though not z-string */ -++ for (int i = 0; i < nlist; ++i) { -++ size_t n = list[i].n; -++ if ((n == vlen || (n < vlen && v[vlen-n-1] == '.' && !full)) -++ && 0 == os_strncasecmp(v+vlen-n, list[i].p, n)) -++ return 1; /* match */ -++ } -++ return 0; /* no match */ -++} -++ -++ -++static int -++tls_mbedtls_match_suffixes(mbedtls_x509_crt *crt, const char *match, int full) -++{ -++ /* RFE: this could be pre-parsed into structured data at config time */ -++ struct mlist list[256]; /*(much larger than expected)*/ -++ int nlist = 0; -++ for (const char *s = match, *tok; *s; s = tok ? tok+1 : "") { -++ tok = os_strchr(s, ';'); -++ list[nlist].p = s; -++ list[nlist].n = tok ? (size_t)(tok - s) : os_strlen(s); -++ if (list[nlist].n && ++nlist == sizeof(list)/sizeof(*list)) { -++ wpa_printf(MSG_INFO, "MTLS: excessive suffix match '%s'", match); -++ break; /* truncate huge list and continue */ -++ } -++ } -++ -++ /* check subjectAltNames */ -++ if (mbedtls_x509_crt_has_ext_type(crt, MBEDTLS_X509_EXT_SUBJECT_ALT_NAME)) { -++ const mbedtls_x509_sequence *cur = &crt->subject_alt_names; -++ for (; cur != NULL; cur = cur->next) { -++ const unsigned char san_type = (unsigned char)cur->buf.tag -++ & MBEDTLS_ASN1_TAG_VALUE_MASK; -++ if (san_type == MBEDTLS_X509_SAN_DNS_NAME -++ && tls_mbedtls_match_suffix((char *)cur->buf.p, -++ cur->buf.len, -++ list, nlist, full)) { -++ return 1; /* match */ -++ } -++ } -++ } -++ -++ /* check subject CN */ -++ const mbedtls_x509_name *name = &crt->subject; -++ for (; name != NULL; name = name->next) { -++ if (name->oid.p && MBEDTLS_OID_CMP(MBEDTLS_OID_AT_CN, &name->oid) == 0) -++ break; -++ } -++ if (name && tls_mbedtls_match_suffix((char *)name->val.p, name->val.len, -++ list, nlist, full)) { -++ return 1; /* match */ -++ } -++ -++ return 0; /* no match */ -++} -++ -++ -++static int -++tls_mbedtls_match_dn_field(mbedtls_x509_crt *crt, const char *match) -++{ -++ /* RFE: this could be pre-parsed into structured data at config time */ -++ struct mlistoid { const char *p; size_t n; -++ const char *oid; size_t olen; -++ int prefix; }; -++ struct mlistoid list[32]; /*(much larger than expected)*/ -++ int nlist = 0; -++ for (const char *s = match, *tok, *e; *s; s = tok ? tok+1 : "") { -++ tok = os_strchr(s, '/'); -++ list[nlist].oid = NULL; -++ list[nlist].olen = 0; -++ list[nlist].n = tok ? (size_t)(tok - s) : os_strlen(s); -++ e = memchr(s, '=', list[nlist].n); -++ if (e == NULL) { -++ if (list[nlist].n == 0) -++ continue; /* skip consecutive, repeated '/' */ -++ if (list[nlist].n == 1 && *s == '*') { -++ /* special-case "*" to match any OID and value */ -++ s = e = "=*"; -++ list[nlist].n = 2; -++ list[nlist].oid = ""; -++ } -++ else { -++ wpa_printf(MSG_INFO, -++ "MTLS: invalid check_cert_subject '%s' missing '='", -++ match); -++ return 0; -++ } -++ } -++ switch (e - s) { -++ case 1: -++ if (*s == 'C') { -++ list[nlist].oid = MBEDTLS_OID_AT_COUNTRY; -++ list[nlist].olen = sizeof(MBEDTLS_OID_AT_COUNTRY)-1; -++ } -++ else if (*s == 'L') { -++ list[nlist].oid = MBEDTLS_OID_AT_LOCALITY; -++ list[nlist].olen = sizeof(MBEDTLS_OID_AT_LOCALITY)-1; -++ } -++ else if (*s == 'O') { -++ list[nlist].oid = MBEDTLS_OID_AT_ORGANIZATION; -++ list[nlist].olen = sizeof(MBEDTLS_OID_AT_ORGANIZATION)-1; -++ } -++ break; -++ case 2: -++ if (s[0] == 'C' && s[1] == 'N') { -++ list[nlist].oid = MBEDTLS_OID_AT_CN; -++ list[nlist].olen = sizeof(MBEDTLS_OID_AT_CN)-1; -++ } -++ else if (s[0] == 'S' && s[1] == 'T') { -++ list[nlist].oid = MBEDTLS_OID_AT_STATE; -++ list[nlist].olen = sizeof(MBEDTLS_OID_AT_STATE)-1; -++ } -++ else if (s[0] == 'O' && s[1] == 'U') { -++ list[nlist].oid = MBEDTLS_OID_AT_ORG_UNIT; -++ list[nlist].olen = sizeof(MBEDTLS_OID_AT_ORG_UNIT)-1; -++ } -++ break; -++ case 12: -++ if (os_memcmp(s, "emailAddress", 12) == 0) { -++ list[nlist].oid = MBEDTLS_OID_PKCS9_EMAIL; -++ list[nlist].olen = sizeof(MBEDTLS_OID_PKCS9_EMAIL)-1; -++ } -++ break; -++ default: -++ break; -++ } -++ if (list[nlist].oid == NULL) { -++ wpa_printf(MSG_INFO, -++ "MTLS: Unknown field in check_cert_subject '%s'", -++ match); -++ return 0; -++ } -++ list[nlist].n -= (size_t)(++e - s); -++ list[nlist].p = e; -++ if (list[nlist].n && e[list[nlist].n-1] == '*') { -++ --list[nlist].n; -++ list[nlist].prefix = 1; -++ } -++ /*(could easily add support for suffix matches if value begins with '*', -++ * but suffix match is not currently supported by other TLS modules)*/ -++ -++ if (list[nlist].n && ++nlist == sizeof(list)/sizeof(*list)) { -++ wpa_printf(MSG_INFO, -++ "MTLS: excessive check_cert_subject match '%s'", -++ match); -++ break; /* truncate huge list and continue */ -++ } -++ } -++ -++ /* each component in match string must match cert Subject in order listed -++ * The behavior below preserves ordering but is slightly different than -++ * the grossly inefficient contortions implemented in tls_openssl.c */ -++ const mbedtls_x509_name *name = &crt->subject; -++ for (int i = 0; i < nlist; ++i) { -++ int found = 0; -++ for (; name != NULL && !found; name = name->next) { -++ if (!name->oid.p) -++ continue; -++ /* special-case "*" to match any OID and value */ -++ if (list[i].olen == 0) { -++ found = 1; -++ continue; -++ } -++ /* perform equalent of !MBEDTLS_OID_CMP() with oid ptr and len */ -++ if (list[i].olen != name->oid.len -++ || os_memcmp(list[i].oid, name->oid.p, name->oid.len) != 0) -++ continue; -++ /* Note: v is not '\0'-terminated, but is a known length vlen, -++ * so okay to pass to os_strncasecmp() even though not z-string */ -++ if ((list[i].prefix -++ ? list[i].n <= name->val.len /* prefix match */ -++ : list[i].n == name->val.len) /* full match */ -++ && 0 == os_strncasecmp((char *)name->val.p, -++ list[i].p, list[i].n)) { -++ found = 1; -++ continue; -++ } -++ } -++ if (!found) -++ return 0; /* no match */ -++ } -++ return 1; /* match */ -++} -++ -++ -++__attribute_cold__ -++static void -++tls_mbedtls_verify_fail_event (mbedtls_x509_crt *crt, int depth, -++ const char *errmsg, enum tls_fail_reason reason) -++{ -++ struct tls_config *init_conf = &tls_ctx_global.init_conf; -++ if (init_conf->event_cb == NULL) -++ return; -++ -++ struct wpabuf *certbuf = wpabuf_alloc_copy(crt->raw.p, crt->raw.len); -++ char subject[MBEDTLS_X509_MAX_DN_NAME_SIZE*2]; -++ if (mbedtls_x509_dn_gets(subject, sizeof(subject), &crt->subject) < 0) -++ subject[0] = '\0'; -++ union tls_event_data ev; -++ os_memset(&ev, 0, sizeof(ev)); -++ ev.cert_fail.reason = reason; -++ ev.cert_fail.depth = depth; -++ ev.cert_fail.subject = subject; -++ ev.cert_fail.reason_txt = errmsg; -++ ev.cert_fail.cert = certbuf; -++ -++ init_conf->event_cb(init_conf->cb_ctx, TLS_CERT_CHAIN_FAILURE, &ev); -++ -++ wpabuf_free(certbuf); -++} -++ -++ -++__attribute_noinline__ -++static void -++tls_mbedtls_verify_cert_event (struct tls_connection *conn, -++ mbedtls_x509_crt *crt, int depth) -++{ -++ struct tls_config *init_conf = &tls_ctx_global.init_conf; -++ if (init_conf->event_cb == NULL) -++ return; -++ -++ struct wpabuf *certbuf = NULL; -++ union tls_event_data ev; -++ os_memset(&ev, 0, sizeof(ev)); -++ -++ #ifdef MBEDTLS_SHA256_C -++ u8 hash[SHA256_DIGEST_LENGTH]; -++ const u8 *addr[] = { (u8 *)crt->raw.p }; -++ if (sha256_vector(1, addr, &crt->raw.len, hash) == 0) { -++ ev.peer_cert.hash = hash; -++ ev.peer_cert.hash_len = sizeof(hash); -++ } -++ #endif -++ ev.peer_cert.depth = depth; -++ char subject[MBEDTLS_X509_MAX_DN_NAME_SIZE*2]; -++ if (depth == 0) -++ ev.peer_cert.subject = conn->peer_subject; -++ if (ev.peer_cert.subject == NULL) { -++ ev.peer_cert.subject = subject; -++ if (mbedtls_x509_dn_gets(subject, sizeof(subject), &crt->subject) < 0) -++ subject[0] = '\0'; -++ } -++ -++ char serial_num[128+1]; -++ ev.peer_cert.serial_num = -++ tls_mbedtls_peer_serial_num(crt, serial_num, sizeof(serial_num)); -++ -++ const mbedtls_x509_sequence *cur; -++ -++ cur = NULL; -++ if (mbedtls_x509_crt_has_ext_type(crt, MBEDTLS_X509_EXT_SUBJECT_ALT_NAME)) -++ cur = &crt->subject_alt_names; -++ for (; cur != NULL; cur = cur->next) { -++ const unsigned char san_type = (unsigned char)cur->buf.tag -++ & MBEDTLS_ASN1_TAG_VALUE_MASK; -++ size_t prelen = 4; -++ const char *pre; -++ switch (san_type) { -++ case MBEDTLS_X509_SAN_RFC822_NAME: prelen = 6; pre = "EMAIL:";break; -++ case MBEDTLS_X509_SAN_DNS_NAME: pre = "DNS:"; break; -++ case MBEDTLS_X509_SAN_UNIFORM_RESOURCE_IDENTIFIER: pre = "URI:"; break; -++ default: continue; -++ } -++ -++ char *pos = os_malloc(prelen + cur->buf.len + 1); -++ if (pos == NULL) -++ break; -++ ev.peer_cert.altsubject[ev.peer_cert.num_altsubject] = pos; -++ os_memcpy(pos, pre, prelen); -++ /* data should be properly backslash-escaped if needed, -++ * so code below does not re-escape, but does replace CTLs */ -++ /*os_memcpy(pos+prelen, cur->buf.p, cur->buf.len);*/ -++ /*pos[prelen+cur->buf.len] = '\0';*/ -++ pos += prelen; -++ for (size_t i = 0; i < cur->buf.len; ++i) { -++ unsigned char c = cur->buf.p[i]; -++ *pos++ = (c >= 32 && c != 127) ? c : '?'; -++ } -++ *pos = '\0'; -++ -++ if (++ev.peer_cert.num_altsubject == TLS_MAX_ALT_SUBJECT) -++ break; -++ } -++ -++ cur = NULL; -++ if (mbedtls_x509_crt_has_ext_type(crt, MBEDTLS_X509_EXT_CERTIFICATE_POLICIES)) -++ cur = &crt->certificate_policies; -++ for (; cur != NULL; cur = cur->next) { -++ if (cur->buf.len != 11) /* len of OID_TOD_STRICT or OID_TOD_TOFU */ -++ continue; -++ /* TOD-STRICT "1.3.6.1.4.1.40808.1.3.1" */ -++ /* TOD-TOFU "1.3.6.1.4.1.40808.1.3.2" */ -++ #define OID_TOD_STRICT "\x2b\x06\x01\x04\x01\x82\xbe\x68\x01\x03\x01" -++ #define OID_TOD_TOFU "\x2b\x06\x01\x04\x01\x82\xbe\x68\x01\x03\x02" -++ if (os_memcmp(cur->buf.p, -++ OID_TOD_STRICT, sizeof(OID_TOD_STRICT)-1) == 0) { -++ ev.peer_cert.tod = 1; /* TOD-STRICT */ -++ break; -++ } -++ if (os_memcmp(cur->buf.p, -++ OID_TOD_TOFU, sizeof(OID_TOD_TOFU)-1) == 0) { -++ ev.peer_cert.tod = 2; /* TOD-TOFU */ -++ break; -++ } -++ } -++ -++ struct tls_conf *tls_conf = conn->tls_conf; -++ if (tls_conf->ca_cert_probe || (tls_conf->flags & TLS_CONN_EXT_CERT_CHECK) -++ || init_conf->cert_in_cb) { -++ certbuf = wpabuf_alloc_copy(crt->raw.p, crt->raw.len); -++ ev.peer_cert.cert = certbuf; -++ } -++ -++ init_conf->event_cb(init_conf->cb_ctx, TLS_PEER_CERTIFICATE, &ev); -++ -++ wpabuf_free(certbuf); -++ char **altsubject; -++ *(const char ***)&altsubject = ev.peer_cert.altsubject; -++ for (size_t i = 0; i < ev.peer_cert.num_altsubject; ++i) -++ os_free(altsubject[i]); -++} -++ -++ -++static int -++tls_mbedtls_verify_cb (void *arg, mbedtls_x509_crt *crt, int depth, uint32_t *flags) -++{ -++ /* XXX: N.B. verify code not carefully tested besides hwsim tests -++ * -++ * RFE: mbedtls_x509_crt_verify_info() and enhance log trace messages -++ * RFE: review and add support for additional TLS_CONN_* flags -++ * not handling OCSP (not available in mbedtls) -++ * ... */ -++ -++ struct tls_connection *conn = (struct tls_connection *)arg; -++ struct tls_conf *tls_conf = conn->tls_conf; -++ uint32_t flags_in = *flags; -++ -++ if (depth > 8) { /*(depth 8 picked as arbitrary limit)*/ -++ emsg(MSG_WARNING, "client cert chain too long"); -++ *flags |= MBEDTLS_X509_BADCERT_OTHER; /* cert chain too long */ -++ tls_mbedtls_verify_fail_event(crt, depth, -++ "client cert chain too long", -++ TLS_FAIL_BAD_CERTIFICATE); -++ } -++ else if (tls_conf->verify_depth0_only) { -++ if (depth > 0) -++ *flags = 0; -++ else { -++ #ifdef MBEDTLS_SHA256_C -++ u8 hash[SHA256_DIGEST_LENGTH]; -++ const u8 *addr[] = { (u8 *)crt->raw.p }; -++ if (sha256_vector(1, addr, &crt->raw.len, hash) < 0 -++ || os_memcmp(tls_conf->ca_cert_hash, hash, sizeof(hash)) != 0) { -++ *flags |= MBEDTLS_X509_BADCERT_NOT_TRUSTED; -++ tls_mbedtls_verify_fail_event(crt, depth, -++ "cert hash mismatch", -++ TLS_FAIL_UNTRUSTED); -++ } -++ else /* hash matches; ignore other issues *except* if revoked)*/ -++ *flags &= MBEDTLS_X509_BADCERT_REVOKED; -++ #endif -++ } -++ } -++ else if (depth == 0) { -++ if (!conn->peer_subject) -++ tls_mbedtls_set_peer_subject(conn, crt); -++ /*(use same labels to tls_mbedtls_verify_fail_event() as used in -++ * other TLS modules so that hwsim tests find exact string match)*/ -++ if (!conn->peer_subject) { /* error copying subject string */ -++ *flags |= MBEDTLS_X509_BADCERT_OTHER; -++ tls_mbedtls_verify_fail_event(crt, depth, -++ "internal error", -++ TLS_FAIL_UNSPECIFIED); -++ } -++ /*(use os_strstr() for subject match as is done in tls_mbedtls.c -++ * to follow the same behavior, even though a suffix match would -++ * make more sense. Also, note that strstr match does not -++ * normalize whitespace (between components) for comparison)*/ -++ else if (tls_conf->subject_match -++ && os_strstr(conn->peer_subject, -++ tls_conf->subject_match) == NULL) { -++ wpa_printf(MSG_WARNING, -++ "MTLS: Subject '%s' did not match with '%s'", -++ conn->peer_subject, tls_conf->subject_match); -++ *flags |= MBEDTLS_X509_BADCERT_CN_MISMATCH; -++ tls_mbedtls_verify_fail_event(crt, depth, -++ "Subject mismatch", -++ TLS_FAIL_SUBJECT_MISMATCH); -++ } -++ if (tls_conf->altsubject_match -++ && !tls_mbedtls_match_altsubject(crt, tls_conf->altsubject_match)) { -++ wpa_printf(MSG_WARNING, -++ "MTLS: altSubjectName match '%s' not found", -++ tls_conf->altsubject_match); -++ *flags |= MBEDTLS_X509_BADCERT_CN_MISMATCH; -++ tls_mbedtls_verify_fail_event(crt, depth, -++ "AltSubject mismatch", -++ TLS_FAIL_ALTSUBJECT_MISMATCH); -++ } -++ if (tls_conf->suffix_match -++ && !tls_mbedtls_match_suffixes(crt, tls_conf->suffix_match, 0)) { -++ wpa_printf(MSG_WARNING, -++ "MTLS: Domain suffix match '%s' not found", -++ tls_conf->suffix_match); -++ *flags |= MBEDTLS_X509_BADCERT_CN_MISMATCH; -++ tls_mbedtls_verify_fail_event(crt, depth, -++ "Domain suffix mismatch", -++ TLS_FAIL_DOMAIN_SUFFIX_MISMATCH); -++ } -++ if (tls_conf->domain_match -++ && !tls_mbedtls_match_suffixes(crt, tls_conf->domain_match, 1)) { -++ wpa_printf(MSG_WARNING, -++ "MTLS: Domain match '%s' not found", -++ tls_conf->domain_match); -++ *flags |= MBEDTLS_X509_BADCERT_CN_MISMATCH; -++ tls_mbedtls_verify_fail_event(crt, depth, -++ "Domain mismatch", -++ TLS_FAIL_DOMAIN_MISMATCH); -++ } -++ if (tls_conf->check_cert_subject -++ && !tls_mbedtls_match_dn_field(crt, tls_conf->check_cert_subject)) { -++ *flags |= MBEDTLS_X509_BADCERT_CN_MISMATCH; -++ tls_mbedtls_verify_fail_event(crt, depth, -++ "Distinguished Name", -++ TLS_FAIL_DN_MISMATCH); -++ } -++ if (tls_conf->flags & TLS_CONN_SUITEB) { -++ /* check RSA modulus size (public key bitlen) */ -++ const mbedtls_pk_type_t pk_alg = mbedtls_pk_get_type(&crt->pk); -++ if ((pk_alg == MBEDTLS_PK_RSA || pk_alg == MBEDTLS_PK_RSASSA_PSS) -++ && mbedtls_pk_get_bitlen(&crt->pk) < 3072) { -++ /* hwsim suite_b RSA tests expect 3072 -++ * suite_b_192_rsa_ecdhe_radius_rsa2048_client -++ * suite_b_192_rsa_dhe_radius_rsa2048_client */ -++ *flags |= MBEDTLS_X509_BADCERT_BAD_KEY; -++ tls_mbedtls_verify_fail_event(crt, depth, -++ "Insufficient RSA modulus size", -++ TLS_FAIL_INSUFFICIENT_KEY_LEN); -++ } -++ } -++ if (tls_conf->check_crl && tls_conf->crl == NULL) { -++ /* see tests/hwsim test_ap_eap.py ap_wpa2_eap_tls_check_crl */ -++ emsg(MSG_WARNING, "check_crl set but no CRL loaded; reject all?"); -++ *flags |= MBEDTLS_X509_BADCERT_OTHER; -++ tls_mbedtls_verify_fail_event(crt, depth, -++ "check_crl set but no CRL loaded; " -++ "reject all?", -++ TLS_FAIL_BAD_CERTIFICATE); -++ } -++ } -++ else { -++ if (tls_conf->check_crl != 2) /* 2 == verify CRLs for all certs */ -++ *flags &= ~MBEDTLS_X509_BADCERT_REVOKED; -++ } -++ -++ if (!tls_conf->check_crl_strict) { -++ *flags &= ~MBEDTLS_X509_BADCRL_EXPIRED; -++ *flags &= ~MBEDTLS_X509_BADCRL_FUTURE; -++ } -++ -++ if (tls_conf->flags & TLS_CONN_DISABLE_TIME_CHECKS) { -++ *flags &= ~MBEDTLS_X509_BADCERT_EXPIRED; -++ *flags &= ~MBEDTLS_X509_BADCERT_FUTURE; -++ } -++ -++ tls_mbedtls_verify_cert_event(conn, crt, depth); -++ -++ if (*flags) { -++ if (*flags & (MBEDTLS_X509_BADCERT_NOT_TRUSTED -++ |MBEDTLS_X509_BADCERT_CN_MISMATCH -++ |MBEDTLS_X509_BADCERT_REVOKED)) { -++ emsg(MSG_WARNING, "client cert not trusted"); -++ } -++ /* report event if flags set but no additional flags set above */ -++ /* (could translate flags to more detailed TLS_FAIL_* if needed) */ -++ if (!(*flags & ~flags_in)) { -++ enum tls_fail_reason reason = TLS_FAIL_UNSPECIFIED; -++ const char *errmsg = "cert verify fail unspecified"; -++ if (*flags & MBEDTLS_X509_BADCERT_NOT_TRUSTED) { -++ reason = TLS_FAIL_UNTRUSTED; -++ errmsg = "certificate not trusted"; -++ } -++ if (*flags & MBEDTLS_X509_BADCERT_REVOKED) { -++ reason = TLS_FAIL_REVOKED; -++ errmsg = "certificate has been revoked"; -++ } -++ if (*flags & MBEDTLS_X509_BADCERT_FUTURE) { -++ reason = TLS_FAIL_NOT_YET_VALID; -++ errmsg = "certificate not yet valid"; -++ } -++ if (*flags & MBEDTLS_X509_BADCERT_EXPIRED) { -++ reason = TLS_FAIL_EXPIRED; -++ errmsg = "certificate has expired"; -++ } -++ if (*flags & MBEDTLS_X509_BADCERT_BAD_MD) { -++ reason = TLS_FAIL_BAD_CERTIFICATE; -++ errmsg = "certificate uses insecure algorithm"; -++ } -++ tls_mbedtls_verify_fail_event(crt, depth, errmsg, reason); -++ } -++ #if 0 -++ /* ??? send (again) cert events for all certs in chain ??? -++ * (should already have been called for greater depths) */ -++ /* tls_openssl.c:tls_verify_cb() sends cert events for all certs -++ * in chain if certificate validation fails, but sends all events -++ * with depth set to 0 (might be a bug) */ -++ if (depth > 0) { -++ int pdepth = depth + 1; -++ for (mbedtls_x509_crt *pcrt; (pcrt = crt->next); ++pdepth) { -++ tls_mbedtls_verify_cert_event(conn, pcrt, pdepth); -++ } -++ } -++ #endif -++ /*(do not preserve subject if verification failed but was optional)*/ -++ if (depth == 0 && conn->peer_subject) { -++ os_free(conn->peer_subject); -++ conn->peer_subject = NULL; -++ } -++ } -++ else if (depth == 0) { -++ struct tls_config *init_conf = &tls_ctx_global.init_conf; -++ if (tls_conf->ca_cert_probe) { -++ /* reject server certificate on probe-only run */ -++ *flags |= MBEDTLS_X509_BADCERT_OTHER; -++ tls_mbedtls_verify_fail_event(crt, depth, -++ "server chain probe", -++ TLS_FAIL_SERVER_CHAIN_PROBE); -++ } -++ else if (init_conf->event_cb) { -++ /* ??? send event as soon as depth == 0 is verified ??? -++ * What about rest of chain? -++ * Follows tls_mbedtls.c behavior: */ -++ init_conf->event_cb(init_conf->cb_ctx, -++ TLS_CERT_CHAIN_SUCCESS, NULL); -++ } -++ } -++ -++ return 0; -++} -+--- /dev/null -++++ b/tests/build/build-wpa_supplicant-mbedtls.config -+@@ -0,0 +1,24 @@ -++CONFIG_TLS=mbedtls -++ -++CONFIG_WPS=y -++CONFIG_EAP_TLS=y -++CONFIG_EAP_MSCHAPV2=y -++ -++CONFIG_EAP_PSK=y -++CONFIG_EAP_GPSK=y -++CONFIG_EAP_AKA=y -++CONFIG_EAP_SIM=y -++CONFIG_EAP_SAKE=y -++CONFIG_EAP_PAX=y -++CONFIG_EAP_FAST=y -++CONFIG_EAP_IKEV2=y -++ -++CONFIG_SAE=y -++CONFIG_FILS=y -++CONFIG_FILS_SK_PFS=y -++CONFIG_OWE=y -++CONFIG_DPP=y -++CONFIG_SUITEB=y -++CONFIG_SUITEB192=y -++ -++CFLAGS += -Werror -+--- a/tests/hwsim/example-hostapd.config -++++ b/tests/hwsim/example-hostapd.config -+@@ -4,6 +4,7 @@ CONFIG_DRIVER_NONE=y -+ CONFIG_DRIVER_NL80211=y -+ CONFIG_RSN_PREAUTH=y -+ -++#CONFIG_TLS=mbedtls -+ #CONFIG_TLS=internal -+ #CONFIG_INTERNAL_LIBTOMMATH=y -+ #CONFIG_INTERNAL_LIBTOMMATH_FAST=y -+@@ -39,6 +40,9 @@ endif -+ ifeq ($(CONFIG_TLS), wolfssl) -+ CONFIG_EAP_PWD=y -+ endif -++ifeq ($(CONFIG_TLS), mbedtls) -++CONFIG_EAP_PWD=y -++endif -+ CONFIG_EAP_EKE=y -+ CONFIG_PKCS12=y -+ CONFIG_RADIUS_SERVER=y -+--- a/tests/hwsim/example-wpa_supplicant.config -++++ b/tests/hwsim/example-wpa_supplicant.config -+@@ -2,6 +2,7 @@ -+ -+ CONFIG_TLS=openssl -+ #CONFIG_TLS=wolfssl -++#CONFIG_TLS=mbedtls -+ #CONFIG_TLS=internal -+ #CONFIG_INTERNAL_LIBTOMMATH=y -+ #CONFIG_INTERNAL_LIBTOMMATH_FAST=y -+@@ -41,6 +42,9 @@ endif -+ ifeq ($(CONFIG_TLS), wolfssl) -+ CONFIG_EAP_PWD=y -+ endif -++ifeq ($(CONFIG_TLS), mbedtls) -++CONFIG_EAP_PWD=y -++endif -+ -+ CONFIG_USIM_SIMULATOR=y -+ CONFIG_SIM_SIMULATOR=y -+--- a/wpa_supplicant/Makefile -++++ b/wpa_supplicant/Makefile -+@@ -1163,6 +1163,29 @@ endif -+ CFLAGS += -DTLS_DEFAULT_CIPHERS=\"$(CONFIG_TLS_DEFAULT_CIPHERS)\" -+ endif -+ -++ifeq ($(CONFIG_TLS), mbedtls) -++ifndef CONFIG_CRYPTO -++CONFIG_CRYPTO=mbedtls -++endif -++ifdef TLS_FUNCS -++OBJS += ../src/crypto/tls_mbedtls.o -++LIBS += -lmbedtls -lmbedx509 -++endif -++OBJS += ../src/crypto/crypto_$(CONFIG_CRYPTO).o -++OBJS_p += ../src/crypto/crypto_$(CONFIG_CRYPTO).o -++OBJS_priv += ../src/crypto/crypto_$(CONFIG_CRYPTO).o -++ifdef NEED_FIPS186_2_PRF -++OBJS += ../src/crypto/fips_prf_internal.o -++SHA1OBJS += ../src/crypto/sha1-internal.o -++endif -++ifeq ($(CONFIG_CRYPTO), mbedtls) -++LIBS += -lmbedcrypto -++LIBS_p += -lmbedcrypto -++# XXX: create a config option? -++CFLAGS += -DCRYPTO_RSA_OAEP_SHA256 -++endif -++endif -++ -+ ifeq ($(CONFIG_TLS), gnutls) -+ ifndef CONFIG_CRYPTO -+ # default to libgcrypt -+@@ -1355,9 +1378,11 @@ endif -+ -+ ifneq ($(CONFIG_TLS), openssl) -+ ifneq ($(CONFIG_TLS), wolfssl) -++ifneq ($(CONFIG_TLS), mbedtls) -+ NEED_INTERNAL_AES_WRAP=y -+ endif -+ endif -++endif -+ ifdef CONFIG_OPENSSL_INTERNAL_AES_WRAP -+ # Seems to be needed at least with BoringSSL -+ NEED_INTERNAL_AES_WRAP=y -+@@ -1371,9 +1396,11 @@ endif -+ -+ ifdef NEED_INTERNAL_AES_WRAP -+ ifneq ($(CONFIG_TLS), linux) -++ifneq ($(CONFIG_TLS), mbedtls) -+ AESOBJS += ../src/crypto/aes-unwrap.o -+ endif -+ endif -++endif -+ ifdef NEED_AES_EAX -+ AESOBJS += ../src/crypto/aes-eax.o -+ NEED_AES_CTR=y -+@@ -1383,35 +1410,45 @@ AESOBJS += ../src/crypto/aes-siv.o -+ NEED_AES_CTR=y -+ endif -+ ifdef NEED_AES_CTR -++ifneq ($(CONFIG_TLS), mbedtls) -+ AESOBJS += ../src/crypto/aes-ctr.o -+ endif -++endif -+ ifdef NEED_AES_ENCBLOCK -++ifneq ($(CONFIG_TLS), mbedtls) -+ AESOBJS += ../src/crypto/aes-encblock.o -+ endif -++endif -+ NEED_AES_ENC=y -+ ifneq ($(CONFIG_TLS), openssl) -+ ifneq ($(CONFIG_TLS), linux) -+ ifneq ($(CONFIG_TLS), wolfssl) -++ifneq ($(CONFIG_TLS), mbedtls) -+ AESOBJS += ../src/crypto/aes-omac1.o -+ endif -+ endif -+ endif -++endif -+ ifdef NEED_AES_WRAP -+ NEED_AES_ENC=y -+ ifdef NEED_INTERNAL_AES_WRAP -++ifneq ($(CONFIG_TLS), mbedtls) -+ AESOBJS += ../src/crypto/aes-wrap.o -+ endif -+ endif -++endif -+ ifdef NEED_AES_CBC -+ NEED_AES_ENC=y -+ ifneq ($(CONFIG_TLS), openssl) -+ ifneq ($(CONFIG_TLS), linux) -+ ifneq ($(CONFIG_TLS), wolfssl) -++ifneq ($(CONFIG_TLS), mbedtls) -+ AESOBJS += ../src/crypto/aes-cbc.o -+ endif -+ endif -+ endif -+ endif -++endif -+ ifdef NEED_AES_ENC -+ ifdef CONFIG_INTERNAL_AES -+ AESOBJS += ../src/crypto/aes-internal-enc.o -+@@ -1426,12 +1463,16 @@ ifneq ($(CONFIG_TLS), openssl) -+ ifneq ($(CONFIG_TLS), linux) -+ ifneq ($(CONFIG_TLS), gnutls) -+ ifneq ($(CONFIG_TLS), wolfssl) -++ifneq ($(CONFIG_TLS), mbedtls) -+ SHA1OBJS += ../src/crypto/sha1.o -+ endif -+ endif -+ endif -+ endif -++endif -++ifneq ($(CONFIG_TLS), mbedtls) -+ SHA1OBJS += ../src/crypto/sha1-prf.o -++endif -+ ifdef CONFIG_INTERNAL_SHA1 -+ SHA1OBJS += ../src/crypto/sha1-internal.o -+ ifdef NEED_FIPS186_2_PRF -+@@ -1443,29 +1484,37 @@ CFLAGS += -DCONFIG_NO_PBKDF2 -+ else -+ ifneq ($(CONFIG_TLS), openssl) -+ ifneq ($(CONFIG_TLS), wolfssl) -++ifneq ($(CONFIG_TLS), mbedtls) -+ SHA1OBJS += ../src/crypto/sha1-pbkdf2.o -+ endif -+ endif -+ endif -++endif -+ ifdef NEED_T_PRF -++ifneq ($(CONFIG_TLS), mbedtls) -+ SHA1OBJS += ../src/crypto/sha1-tprf.o -+ endif -++endif -+ ifdef NEED_TLS_PRF -++ifneq ($(CONFIG_TLS), mbedtls) -+ SHA1OBJS += ../src/crypto/sha1-tlsprf.o -+ endif -+ endif -++endif -+ -+ ifndef CONFIG_FIPS -+ ifneq ($(CONFIG_TLS), openssl) -+ ifneq ($(CONFIG_TLS), linux) -+ ifneq ($(CONFIG_TLS), gnutls) -+ ifneq ($(CONFIG_TLS), wolfssl) -++ifneq ($(CONFIG_TLS), mbedtls) -+ MD5OBJS += ../src/crypto/md5.o -+ endif -+ endif -+ endif -+ endif -+ endif -++endif -+ ifdef NEED_MD5 -+ ifdef CONFIG_INTERNAL_MD5 -+ MD5OBJS += ../src/crypto/md5-internal.o -+@@ -1520,12 +1569,17 @@ ifneq ($(CONFIG_TLS), openssl) -+ ifneq ($(CONFIG_TLS), linux) -+ ifneq ($(CONFIG_TLS), gnutls) -+ ifneq ($(CONFIG_TLS), wolfssl) -++ifneq ($(CONFIG_TLS), mbedtls) -+ SHA256OBJS += ../src/crypto/sha256.o -+ endif -+ endif -+ endif -+ endif -++endif -++ -++ifneq ($(CONFIG_TLS), mbedtls) -+ SHA256OBJS += ../src/crypto/sha256-prf.o -++endif -+ ifdef CONFIG_INTERNAL_SHA256 -+ SHA256OBJS += ../src/crypto/sha256-internal.o -+ endif -+@@ -1538,50 +1592,68 @@ CFLAGS += -DCONFIG_INTERNAL_SHA512 -+ SHA256OBJS += ../src/crypto/sha512-internal.o -+ endif -+ ifdef NEED_TLS_PRF_SHA256 -++ifneq ($(CONFIG_TLS), mbedtls) -+ SHA256OBJS += ../src/crypto/sha256-tlsprf.o -+ endif -++endif -+ ifdef NEED_TLS_PRF_SHA384 -++ifneq ($(CONFIG_TLS), mbedtls) -+ SHA256OBJS += ../src/crypto/sha384-tlsprf.o -+ endif -++endif -+ ifdef NEED_HMAC_SHA256_KDF -+ CFLAGS += -DCONFIG_HMAC_SHA256_KDF -++ifneq ($(CONFIG_TLS), mbedtls) -+ OBJS += ../src/crypto/sha256-kdf.o -+ endif -++endif -+ ifdef NEED_HMAC_SHA384_KDF -+ CFLAGS += -DCONFIG_HMAC_SHA384_KDF -++ifneq ($(CONFIG_TLS), mbedtls) -+ OBJS += ../src/crypto/sha384-kdf.o -+ endif -++endif -+ ifdef NEED_HMAC_SHA512_KDF -+ CFLAGS += -DCONFIG_HMAC_SHA512_KDF -++ifneq ($(CONFIG_TLS), mbedtls) -+ OBJS += ../src/crypto/sha512-kdf.o -+ endif -++endif -+ OBJS += $(SHA256OBJS) -+ ifdef NEED_SHA384 -+ ifneq ($(CONFIG_TLS), openssl) -+ ifneq ($(CONFIG_TLS), linux) -+ ifneq ($(CONFIG_TLS), gnutls) -+ ifneq ($(CONFIG_TLS), wolfssl) -++ifneq ($(CONFIG_TLS), mbedtls) -+ OBJS += ../src/crypto/sha384.o -+ endif -+ endif -+ endif -+ endif -++endif -+ CFLAGS += -DCONFIG_SHA384 -++ifneq ($(CONFIG_TLS), mbedtls) -+ OBJS += ../src/crypto/sha384-prf.o -+ endif -++endif -+ ifdef NEED_SHA512 -+ ifneq ($(CONFIG_TLS), openssl) -+ ifneq ($(CONFIG_TLS), linux) -+ ifneq ($(CONFIG_TLS), gnutls) -+ ifneq ($(CONFIG_TLS), wolfssl) -++ifneq ($(CONFIG_TLS), mbedtls) -+ OBJS += ../src/crypto/sha512.o -+ endif -+ endif -+ endif -+ endif -++endif -+ CFLAGS += -DCONFIG_SHA512 -++ifneq ($(CONFIG_TLS), mbedtls) -+ OBJS += ../src/crypto/sha512-prf.o -+ endif -++endif -+ -+ ifdef NEED_ASN1 -+ OBJS += ../src/tls/asn1.o -+@@ -1756,10 +1828,12 @@ ifdef CONFIG_FIPS -+ CFLAGS += -DCONFIG_FIPS -+ ifneq ($(CONFIG_TLS), openssl) -+ ifneq ($(CONFIG_TLS), wolfssl) -++ifneq ($(CONFIG_TLS), mbedtls) -+ $(error CONFIG_FIPS=y requires CONFIG_TLS=openssl) -+ endif -+ endif -+ endif -++endif -+ -+ OBJS += $(SHA1OBJS) $(DESOBJS) -+ -+--- a/wpa_supplicant/defconfig -++++ b/wpa_supplicant/defconfig -+@@ -10,8 +10,8 @@ -+ # to override previous values of the variables. -+ -+ -+-# Uncomment following two lines and fix the paths if you have installed OpenSSL -+-# or GnuTLS in non-default location -++# Uncomment following two lines and fix the paths if you have installed TLS -++# libraries in a non-default location -+ #CFLAGS += -I/usr/local/openssl/include -+ #LIBS += -L/usr/local/openssl/lib -+ -+@@ -20,6 +20,7 @@ -+ # used to fix build issues on such systems (krb5.h not found). -+ #CFLAGS += -I/usr/include/kerberos -+ -++ -+ # 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 -+ # openssl = OpenSSL (default) -+ # gnutls = GnuTLS -+ # internal = Internal TLSv1 implementation (experimental) -++# mbedtls = mbed TLS -+ # linux = Linux kernel AF_ALG and internal TLSv1 implementation (experimental) -+ # none = Empty template -+ #CONFIG_TLS=openssl -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 -new file mode 100644 -index 0000000000..a48725264f ---- /dev/null -+++ b/package/network/services/hostapd/patches/120-mbedtls-fips186_2_prf.patch -@@ -0,0 +1,114 @@ -+From c8dba4bd750269bcc80fed3d546e2077cb4cdf0e Mon Sep 17 00:00:00 2001 -+From: Glenn Strauss -+Date: Tue, 19 Jul 2022 20:02:21 -0400 -+Subject: [PATCH 2/7] mbedtls: fips186_2_prf() -+ -+Signed-off-by: Glenn Strauss -+--- -+ hostapd/Makefile | 4 --- -+ src/crypto/crypto_mbedtls.c | 60 +++++++++++++++++++++++++++++++++++++ -+ wpa_supplicant/Makefile | 4 --- -+ 3 files changed, 60 insertions(+), 8 deletions(-) -+ -+--- a/hostapd/Makefile -++++ b/hostapd/Makefile -+@@ -759,10 +759,6 @@ endif -+ OBJS += ../src/crypto/crypto_$(CONFIG_CRYPTO).o -+ HOBJS += ../src/crypto/crypto_$(CONFIG_CRYPTO).o -+ SOBJS += ../src/crypto/crypto_$(CONFIG_CRYPTO).o -+-ifdef NEED_FIPS186_2_PRF -+-OBJS += ../src/crypto/fips_prf_internal.o -+-SHA1OBJS += ../src/crypto/sha1-internal.o -+-endif -+ ifeq ($(CONFIG_CRYPTO), mbedtls) -+ ifdef CONFIG_DPP -+ LIBS += -lmbedx509 -+--- a/src/crypto/crypto_mbedtls.c -++++ b/src/crypto/crypto_mbedtls.c -+@@ -132,6 +132,12 @@ -+ #define CRYPTO_MBEDTLS_HMAC_KDF_SHA512 -+ #endif -+ -++#if defined(EAP_SIM) || defined(EAP_SIM_DYNAMIC) || defined(EAP_SERVER_SIM) \ -++ || defined(EAP_AKA) || defined(EAP_AKA_DYNAMIC) || defined(EAP_SERVER_AKA) -++/* EAP_SIM=y EAP_AKA=y */ -++#define CRYPTO_MBEDTLS_FIPS186_2_PRF -++#endif -++ -+ #if defined(EAP_FAST) || defined(EAP_FAST_DYNAMIC) || defined(EAP_SERVER_FAST) \ -+ || defined(EAP_TEAP) || defined(EAP_TEAP_DYNAMIC) || defined(EAP_SERVER_FAST) -+ #define CRYPTO_MBEDTLS_SHA1_T_PRF -+@@ -813,6 +819,60 @@ int sha1_t_prf(const u8 *key, size_t key -+ -+ #endif /* CRYPTO_MBEDTLS_SHA1_T_PRF */ -+ -++#ifdef CRYPTO_MBEDTLS_FIPS186_2_PRF -++ -++/* fips_prf_internal.c sha1-internal.c */ -++ -++/* used only by src/eap_common/eap_sim_common.c:eap_sim_prf() -++ * for eap_sim_derive_keys() and eap_sim_derive_keys_reauth() -++ * where xlen is 160 */ -++ -++int fips186_2_prf(const u8 *seed, size_t seed_len, u8 *x, size_t xlen) -++{ -++ /* FIPS 186-2 + change notice 1 */ -++ -++ mbedtls_sha1_context ctx; -++ u8 * const xkey = ctx.MBEDTLS_PRIVATE(buffer); -++ u32 * const xstate = ctx.MBEDTLS_PRIVATE(state); -++ const u32 xstate_init[] = -++ { 0x67452301, 0xEFCDAB89, 0x98BADCFE, 0x10325476, 0xC3D2E1F0 }; -++ -++ mbedtls_sha1_init(&ctx); -++ os_memcpy(xkey, seed, seed_len < 64 ? seed_len : 64); -++ -++ /* note: does not fill extra bytes if (xlen % 20) (SHA1_MAC_LEN) */ -++ for (; xlen >= 20; xlen -= 20) { -++ /* XSEED_j = 0 */ -++ /* XVAL = (XKEY + XSEED_j) mod 2^b */ -++ -++ /* w_i = G(t, XVAL) */ -++ os_memcpy(xstate, xstate_init, sizeof(xstate_init)); -++ mbedtls_internal_sha1_process(&ctx, xkey); -++ -++ #if __BYTE_ORDER == __LITTLE_ENDIAN -++ xstate[0] = host_to_be32(xstate[0]); -++ xstate[1] = host_to_be32(xstate[1]); -++ xstate[2] = host_to_be32(xstate[2]); -++ xstate[3] = host_to_be32(xstate[3]); -++ xstate[4] = host_to_be32(xstate[4]); -++ #endif -++ os_memcpy(x, xstate, 20); -++ if (xlen == 20) /*(done; skip prep for next loop)*/ -++ break; -++ -++ /* XKEY = (1 + XKEY + w_i) mod 2^b */ -++ for (u32 carry = 1, k = 20; k-- > 0; carry >>= 8) -++ xkey[k] = (carry += xkey[k] + x[k]) & 0xff; -++ x += 20; -++ /* x_j = w_0|w_1 (each pair of iterations through loop)*/ -++ } -++ -++ mbedtls_sha1_free(&ctx); -++ return 0; -++} -++ -++#endif /* CRYPTO_MBEDTLS_FIPS186_2_PRF */ -++ -+ #endif /* MBEDTLS_SHA1_C */ -+ -+ -+--- a/wpa_supplicant/Makefile -++++ b/wpa_supplicant/Makefile -+@@ -1174,10 +1174,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 -+-ifdef NEED_FIPS186_2_PRF -+-OBJS += ../src/crypto/fips_prf_internal.o -+-SHA1OBJS += ../src/crypto/sha1-internal.o -+-endif -+ ifeq ($(CONFIG_CRYPTO), mbedtls) -+ LIBS += -lmbedcrypto -+ LIBS_p += -lmbedcrypto -diff --git a/package/network/services/hostapd/patches/130-mbedtls-annotate-with-TEST_FAIL-for-hwsim-tests.patch b/package/network/services/hostapd/patches/130-mbedtls-annotate-with-TEST_FAIL-for-hwsim-tests.patch -new file mode 100644 -index 0000000000..ae7620b90c ---- /dev/null -+++ b/package/network/services/hostapd/patches/130-mbedtls-annotate-with-TEST_FAIL-for-hwsim-tests.patch -@@ -0,0 +1,421 @@ -+From 31bd19e0e0254b910cccfd3ddc6a6a9222bbcfc0 Mon Sep 17 00:00:00 2001 -+From: Glenn Strauss -+Date: Sun, 9 Oct 2022 05:12:17 -0400 -+Subject: [PATCH 3/7] mbedtls: annotate with TEST_FAIL() for hwsim tests -+ -+Signed-off-by: Glenn Strauss -+--- -+ src/crypto/crypto_mbedtls.c | 124 ++++++++++++++++++++++++++++++++++++ -+ 1 file changed, 124 insertions(+) -+ -+--- a/src/crypto/crypto_mbedtls.c -++++ b/src/crypto/crypto_mbedtls.c -+@@ -280,6 +280,9 @@ __attribute_noinline__ -+ static int md_vector(size_t num_elem, const u8 *addr[], const size_t *len, -+ u8 *mac, mbedtls_md_type_t md_type) -+ { -++ if (TEST_FAIL()) -++ return -1; -++ -+ mbedtls_md_context_t ctx; -+ mbedtls_md_init(&ctx); -+ if (mbedtls_md_setup(&ctx, mbedtls_md_info_from_type(md_type), 0) != 0){ -+@@ -343,6 +346,9 @@ __attribute_noinline__ -+ static int sha384_512_vector(size_t num_elem, const u8 *addr[], -+ const size_t *len, u8 *mac, int is384) -+ { -++ if (TEST_FAIL()) -++ return -1; -++ -+ struct mbedtls_sha512_context ctx; -+ mbedtls_sha512_init(&ctx); -+ #if MBEDTLS_VERSION_MAJOR >= 3 -+@@ -375,6 +381,9 @@ int sha384_vector(size_t num_elem, const -+ #include -+ int sha256_vector(size_t num_elem, const u8 *addr[], const size_t *len, u8 *mac) -+ { -++ if (TEST_FAIL()) -++ return -1; -++ -+ struct mbedtls_sha256_context ctx; -+ mbedtls_sha256_init(&ctx); -+ #if MBEDTLS_VERSION_MAJOR >= 3 -+@@ -397,6 +406,9 @@ int sha256_vector(size_t num_elem, const -+ #include -+ int sha1_vector(size_t num_elem, const u8 *addr[], const size_t *len, u8 *mac) -+ { -++ if (TEST_FAIL()) -++ return -1; -++ -+ struct mbedtls_sha1_context ctx; -+ mbedtls_sha1_init(&ctx); -+ #if MBEDTLS_VERSION_MAJOR >= 3 -+@@ -419,6 +431,9 @@ int sha1_vector(size_t num_elem, const u -+ #include -+ int md5_vector(size_t num_elem, const u8 *addr[], const size_t *len, u8 *mac) -+ { -++ if (TEST_FAIL()) -++ return -1; -++ -+ struct mbedtls_md5_context ctx; -+ mbedtls_md5_init(&ctx); -+ #if MBEDTLS_VERSION_MAJOR >= 3 -+@@ -441,6 +456,9 @@ int md5_vector(size_t num_elem, const u8 -+ #include -+ int md4_vector(size_t num_elem, const u8 *addr[], const size_t *len, u8 *mac) -+ { -++ if (TEST_FAIL()) -++ return -1; -++ -+ struct mbedtls_md4_context ctx; -+ mbedtls_md4_init(&ctx); -+ mbedtls_md4_starts_ret(&ctx); -+@@ -460,6 +478,9 @@ static int hmac_vector(const u8 *key, si -+ const u8 *addr[], const size_t *len, u8 *mac, -+ mbedtls_md_type_t md_type) -+ { -++ if (TEST_FAIL()) -++ return -1; -++ -+ mbedtls_md_context_t ctx; -+ mbedtls_md_init(&ctx); -+ if (mbedtls_md_setup(&ctx, mbedtls_md_info_from_type(md_type), 1) != 0){ -+@@ -571,6 +592,9 @@ static int hmac_kdf_expand(const u8 *prk -+ const char *label, const u8 *info, size_t info_len, -+ u8 *okm, size_t okm_len, mbedtls_md_type_t md_type) -+ { -++ if (TEST_FAIL()) -++ return -1; -++ -+ const mbedtls_md_info_t *md_info = mbedtls_md_info_from_type(md_type); -+ #ifdef MBEDTLS_HKDF_C -+ if (label == NULL) /* RFC 5869 HKDF-Expand when (label == NULL) */ -+@@ -663,6 +687,9 @@ static int hmac_prf_bits(const u8 *key, -+ const u8 *data, size_t data_len, u8 *buf, -+ size_t buf_len_bits, mbedtls_md_type_t md_type) -+ { -++ if (TEST_FAIL()) -++ return -1; -++ -+ mbedtls_md_context_t ctx; -+ mbedtls_md_init(&ctx); -+ const mbedtls_md_info_t *md_info = mbedtls_md_info_from_type(md_type); -+@@ -938,6 +965,9 @@ int pbkdf2_sha1(const char *passphrase, -+ -+ static void *aes_crypt_init_mode(const u8 *key, size_t len, int mode) -+ { -++ if (TEST_FAIL()) -++ return NULL; -++ -+ mbedtls_aes_context *aes = os_malloc(sizeof(*aes)); -+ if (!aes) -+ return NULL; -+@@ -996,6 +1026,9 @@ void aes_decrypt_deinit(void *ctx) -+ /* aes-wrap.c */ -+ int aes_wrap(const u8 *kek, size_t kek_len, int n, const u8 *plain, u8 *cipher) -+ { -++ if (TEST_FAIL()) -++ return -1; -++ -+ mbedtls_nist_kw_context ctx; -+ mbedtls_nist_kw_init(&ctx); -+ size_t olen; -+@@ -1010,6 +1043,9 @@ int aes_wrap(const u8 *kek, size_t kek_l -+ /* aes-unwrap.c */ -+ int aes_unwrap(const u8 *kek, size_t kek_len, int n, const u8 *cipher, u8 *plain) -+ { -++ if (TEST_FAIL()) -++ return -1; -++ -+ mbedtls_nist_kw_context ctx; -+ mbedtls_nist_kw_init(&ctx); -+ size_t olen; -+@@ -1041,6 +1077,9 @@ int omac1_aes_vector( -+ const u8 *key, size_t key_len, size_t num_elem, const u8 *addr[], -+ const size_t *len, u8 *mac) -+ { -++ if (TEST_FAIL()) -++ return -1; -++ -+ mbedtls_cipher_type_t cipher_type; -+ switch (key_len) { -+ case 16: cipher_type = MBEDTLS_CIPHER_AES_128_ECB; break; -+@@ -1103,6 +1142,9 @@ int omac1_aes_256(const u8 *key, const u -+ /* aes-encblock.c */ -+ int aes_128_encrypt_block(const u8 *key, const u8 *in, u8 *out) -+ { -++ if (TEST_FAIL()) -++ return -1; -++ -+ mbedtls_aes_context aes; -+ mbedtls_aes_init(&aes); -+ int ret = mbedtls_aes_setkey_enc(&aes, key, 128) -+@@ -1118,6 +1160,9 @@ int aes_128_encrypt_block(const u8 *key, -+ int aes_ctr_encrypt(const u8 *key, size_t key_len, const u8 *nonce, -+ u8 *data, size_t data_len) -+ { -++ if (TEST_FAIL()) -++ return -1; -++ -+ unsigned char counter[MBEDTLS_AES_BLOCK_SIZE]; -+ unsigned char stream_block[MBEDTLS_AES_BLOCK_SIZE]; -+ os_memcpy(counter, nonce, MBEDTLS_AES_BLOCK_SIZE);/*(must be writable)*/ -+@@ -1160,11 +1205,17 @@ static int aes_128_cbc_oper(const u8 *ke -+ -+ int aes_128_cbc_encrypt(const u8 *key, const u8 *iv, u8 *data, size_t data_len) -+ { -++ if (TEST_FAIL()) -++ return -1; -++ -+ return aes_128_cbc_oper(key, iv, data, data_len, MBEDTLS_AES_ENCRYPT); -+ } -+ -+ int aes_128_cbc_decrypt(const u8 *key, const u8 *iv, u8 *data, size_t data_len) -+ { -++ if (TEST_FAIL()) -++ return -1; -++ -+ return aes_128_cbc_oper(key, iv, data, data_len, MBEDTLS_AES_DECRYPT); -+ } -+ -+@@ -1407,6 +1458,10 @@ int crypto_hash_finish(struct crypto_has -+ } -+ mbedtls_md_free(mctx); -+ os_free(mctx); -++ -++ if (TEST_FAIL()) -++ return -1; -++ -+ return 0; -+ } -+ -+@@ -1421,6 +1476,9 @@ int crypto_hash_finish(struct crypto_has -+ -+ struct crypto_bignum *crypto_bignum_init(void) -+ { -++ if (TEST_FAIL()) -++ return NULL; -++ -+ mbedtls_mpi *bn = os_malloc(sizeof(*bn)); -+ if (bn) -+ mbedtls_mpi_init(bn); -+@@ -1429,6 +1487,9 @@ struct crypto_bignum *crypto_bignum_init -+ -+ struct crypto_bignum *crypto_bignum_init_set(const u8 *buf, size_t len) -+ { -++ if (TEST_FAIL()) -++ return NULL; -++ -+ mbedtls_mpi *bn = os_malloc(sizeof(*bn)); -+ if (bn) { -+ mbedtls_mpi_init(bn); -+@@ -1442,6 +1503,9 @@ struct crypto_bignum *crypto_bignum_init -+ -+ struct crypto_bignum *crypto_bignum_init_uint(unsigned int val) -+ { -++ if (TEST_FAIL()) -++ return NULL; -++ -+ #if 0 /*(hostap use of this interface passes int, not uint)*/ -+ val = host_to_be32(val); -+ return crypto_bignum_init_set((const u8 *)&val, sizeof(val)); -+@@ -1467,6 +1531,9 @@ void crypto_bignum_deinit(struct crypto_ -+ int crypto_bignum_to_bin(const struct crypto_bignum *a, -+ u8 *buf, size_t buflen, size_t padlen) -+ { -++ if (TEST_FAIL()) -++ return -1; -++ -+ size_t n = mbedtls_mpi_size((mbedtls_mpi *)a); -+ if (n < padlen) -+ n = padlen; -+@@ -1477,6 +1544,9 @@ int crypto_bignum_to_bin(const struct cr -+ -+ int crypto_bignum_rand(struct crypto_bignum *r, const struct crypto_bignum *m) -+ { -++ if (TEST_FAIL()) -++ return -1; -++ -+ /*assert(r != m);*//* r must not be same as m for mbedtls_mpi_random()*/ -+ #if MBEDTLS_VERSION_NUMBER >= 0x021B0000 /* mbedtls 2.27.0 */ -+ return mbedtls_mpi_random((mbedtls_mpi *)r, 0, (mbedtls_mpi *)m, -+@@ -1513,6 +1583,9 @@ int crypto_bignum_exptmod(const struct c -+ const struct crypto_bignum *c, -+ struct crypto_bignum *d) -+ { -++ if (TEST_FAIL()) -++ return -1; -++ -+ /* (check if input params match d; d is the result) */ -+ /* (a == d) is ok in current mbedtls implementation */ -+ if (b == d || c == d) { /*(not ok; store result in intermediate)*/ -+@@ -1540,6 +1613,9 @@ int crypto_bignum_inverse(const struct c -+ const struct crypto_bignum *b, -+ struct crypto_bignum *c) -+ { -++ if (TEST_FAIL()) -++ return -1; -++ -+ return mbedtls_mpi_inv_mod((mbedtls_mpi *)c, -+ (const mbedtls_mpi *)a, -+ (const mbedtls_mpi *)b) ? -1 : 0; -+@@ -1549,6 +1625,9 @@ int crypto_bignum_sub(const struct crypt -+ const struct crypto_bignum *b, -+ struct crypto_bignum *c) -+ { -++ if (TEST_FAIL()) -++ return -1; -++ -+ return mbedtls_mpi_sub_mpi((mbedtls_mpi *)c, -+ (const mbedtls_mpi *)a, -+ (const mbedtls_mpi *)b) ? -1 : 0; -+@@ -1558,6 +1637,9 @@ int crypto_bignum_div(const struct crypt -+ const struct crypto_bignum *b, -+ struct crypto_bignum *c) -+ { -++ if (TEST_FAIL()) -++ return -1; -++ -+ /*(most current use of this crypto.h interface has a == c (result), -+ * so store result in an intermediate to avoid overwritten input)*/ -+ mbedtls_mpi R; -+@@ -1575,6 +1657,9 @@ int crypto_bignum_addmod(const struct cr -+ const struct crypto_bignum *c, -+ struct crypto_bignum *d) -+ { -++ if (TEST_FAIL()) -++ return -1; -++ -+ return mbedtls_mpi_add_mpi((mbedtls_mpi *)d, -+ (const mbedtls_mpi *)a, -+ (const mbedtls_mpi *)b) -+@@ -1588,6 +1673,9 @@ int crypto_bignum_mulmod(const struct cr -+ const struct crypto_bignum *c, -+ struct crypto_bignum *d) -+ { -++ if (TEST_FAIL()) -++ return -1; -++ -+ return mbedtls_mpi_mul_mpi((mbedtls_mpi *)d, -+ (const mbedtls_mpi *)a, -+ (const mbedtls_mpi *)b) -+@@ -1600,6 +1688,9 @@ int crypto_bignum_sqrmod(const struct cr -+ const struct crypto_bignum *b, -+ struct crypto_bignum *c) -+ { -++ if (TEST_FAIL()) -++ return -1; -++ -+ #if 1 -+ return crypto_bignum_mulmod(a, a, b, c); -+ #else -+@@ -1650,6 +1741,9 @@ int crypto_bignum_is_odd(const struct cr -+ int crypto_bignum_legendre(const struct crypto_bignum *a, -+ const struct crypto_bignum *p) -+ { -++ if (TEST_FAIL()) -++ return -2; -++ -+ /* Security Note: -+ * mbedtls_mpi_exp_mod() is not documented to run in constant time, -+ * though mbedtls/library/bignum.c uses constant_time_internal.h funcs. -+@@ -1702,6 +1796,9 @@ int crypto_mod_exp(const u8 *base, size_ -+ const u8 *modulus, size_t modulus_len, -+ u8 *result, size_t *result_len) -+ { -++ if (TEST_FAIL()) -++ return -1; -++ -+ mbedtls_mpi bn_base, bn_exp, bn_modulus, bn_result; -+ mbedtls_mpi_init(&bn_base); -+ mbedtls_mpi_init(&bn_exp); -+@@ -1769,6 +1866,9 @@ static int crypto_mbedtls_dh_init_public -+ int crypto_dh_init(u8 generator, const u8 *prime, size_t prime_len, u8 *privkey, -+ u8 *pubkey) -+ { -++ if (TEST_FAIL()) -++ return -1; -++ -+ #if 0 /*(crypto_dh_init() duplicated (and identical) in crypto_*.c modules)*/ -+ size_t pubkey_len, pad; -+ -+@@ -1810,6 +1910,9 @@ int crypto_dh_derive_secret(u8 generator -+ const u8 *pubkey, size_t pubkey_len, -+ u8 *secret, size_t *len) -+ { -++ if (TEST_FAIL()) -++ return -1; -++ -+ #if 0 -+ if (pubkey_len > prime_len || -+ (pubkey_len == prime_len && -+@@ -2512,6 +2615,9 @@ const struct crypto_ec_point * crypto_ec -+ -+ struct crypto_ec_point *crypto_ec_point_init(struct crypto_ec *e) -+ { -++ if (TEST_FAIL()) -++ return NULL; -++ -+ mbedtls_ecp_point *p = os_malloc(sizeof(*p)); -+ if (p != NULL) -+ mbedtls_ecp_point_init(p); -+@@ -2536,6 +2642,9 @@ int crypto_ec_point_x(struct crypto_ec * -+ int crypto_ec_point_to_bin(struct crypto_ec *e, -+ const struct crypto_ec_point *point, u8 *x, u8 *y) -+ { -++ if (TEST_FAIL()) -++ return -1; -++ -+ /* crypto.h documents crypto_ec_point_to_bin() output is big-endian */ -+ size_t len = CRYPTO_EC_plen(e); -+ if (x) { -+@@ -2563,6 +2672,9 @@ int crypto_ec_point_to_bin(struct crypto -+ struct crypto_ec_point * crypto_ec_point_from_bin(struct crypto_ec *e, -+ const u8 *val) -+ { -++ if (TEST_FAIL()) -++ return NULL; -++ -+ size_t len = CRYPTO_EC_plen(e); -+ mbedtls_ecp_point *p = os_malloc(sizeof(*p)); -+ u8 buf[1+MBEDTLS_MPI_MAX_SIZE*2]; -+@@ -2615,6 +2727,9 @@ int crypto_ec_point_add(struct crypto_ec -+ const struct crypto_ec_point *b, -+ struct crypto_ec_point *c) -+ { -++ if (TEST_FAIL()) -++ return -1; -++ -+ /* mbedtls does not provide an mbedtls_ecp_point add function */ -+ mbedtls_mpi one; -+ mbedtls_mpi_init(&one); -+@@ -2631,6 +2746,9 @@ int crypto_ec_point_mul(struct crypto_ec -+ const struct crypto_bignum *b, -+ struct crypto_ec_point *res) -+ { -++ if (TEST_FAIL()) -++ return -1; -++ -+ return mbedtls_ecp_mul( -+ (mbedtls_ecp_group *)e, (mbedtls_ecp_point *)res, -+ (const mbedtls_mpi *)b, (const mbedtls_ecp_point *)p, -+@@ -2639,6 +2757,9 @@ int crypto_ec_point_mul(struct crypto_ec -+ -+ int crypto_ec_point_invert(struct crypto_ec *e, struct crypto_ec_point *p) -+ { -++ if (TEST_FAIL()) -++ return -1; -++ -+ if (mbedtls_ecp_get_type((mbedtls_ecp_group *)e) -+ == MBEDTLS_ECP_TYPE_MONTGOMERY) { -+ /* e.g. MBEDTLS_ECP_DP_CURVE25519 and MBEDTLS_ECP_DP_CURVE448 */ -+@@ -2751,6 +2872,9 @@ struct crypto_bignum * -+ crypto_ec_point_compute_y_sqr(struct crypto_ec *e, -+ const struct crypto_bignum *x) -+ { -++ if (TEST_FAIL()) -++ return NULL; -++ -+ mbedtls_mpi *y2 = os_malloc(sizeof(*y2)); -+ if (y2 == NULL) -+ return NULL; -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 -new file mode 100644 -index 0000000000..148c268f9c ---- /dev/null -+++ b/package/network/services/hostapd/patches/140-tests-Makefile-make-run-tests-with-CONFIG_TLS.patch -@@ -0,0 +1,1358 @@ -+From f24933dc175e0faf44a3cce3330c256a59649ca6 Mon Sep 17 00:00:00 2001 -+From: Glenn Strauss -+Date: Tue, 19 Jul 2022 23:01:17 -0400 -+Subject: [PATCH 4/7] tests/Makefile make run-tests with CONFIG_TLS=... -+ -+add test-crypto_module.c to run crypto_module_tests() -+ -+adjust some tests/hwsim/*.py for mbed TLS (work in progress) -+ -+option to build and run-tests with CONFIG_TLS=internal # (default) -+$ cd tests; make clean -+$ make run-tests -+ -+option to build and run-tests with CONFIG_TLS=gnutls -+$ cd tests; make clean CONFIG_TLS=gnutls -+$ make run-tests CONFIG_TLS=gnutls -+ -+option to build and run-tests with CONFIG_TLS=mbedtls -+$ cd tests; make clean CONFIG_TLS=mbedtls -+$ make run-tests CONFIG_TLS=mbedtls -+ -+option to build and run-tests with CONFIG_TLS=openssl -+$ cd tests; make clean CONFIG_TLS=openssl -+$ make run-tests CONFIG_TLS=openssl -+ -+option to build and run-tests with CONFIG_TLS=wolfssl -+$ cd tests; make clean CONFIG_TLS=wolfssl -+$ make run-tests CONFIG_TLS=wolfssl -+ -+RFE: Makefile logic for crypto objects should be centralized -+ instead of being duplicated in hostapd/Makefile, -+ wpa_supplicant/Makefile, src/crypto/Makefile, -+ tests/Makefile, ... -+ -+Signed-off-by: Glenn Strauss -+--- -+ hostapd/Makefile | 6 + -+ 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/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_pmksa_cache.py | 4 +- -+ tests/hwsim/test_sae.py | 7 ++ -+ tests/hwsim/test_suite_b.py | 3 + -+ tests/hwsim/test_wpas_ctrl.py | 2 +- -+ tests/hwsim/utils.py | 8 +- -+ tests/test-crypto_module.c | 16 +++ -+ tests/test-https.c | 12 +- -+ tests/test-https_server.c | 12 +- -+ wpa_supplicant/Makefile | 6 + -+ 22 files changed, 524 insertions(+), 91 deletions(-) -+ create mode 100644 tests/test-crypto_module.c -+ -+--- a/hostapd/Makefile -++++ b/hostapd/Makefile -+@@ -696,6 +696,7 @@ CFLAGS += -DCONFIG_TLSV12 -+ endif -+ -+ ifeq ($(CONFIG_TLS), wolfssl) -++CFLAGS += -DCONFIG_TLS_WOLFSSL -+ CONFIG_CRYPTO=wolfssl -+ ifdef TLS_FUNCS -+ OBJS += ../src/crypto/tls_wolfssl.o -+@@ -716,6 +717,7 @@ endif -+ endif -+ -+ ifeq ($(CONFIG_TLS), openssl) -++CFLAGS += -DCONFIG_TLS_OPENSSL -+ CFLAGS += -DCRYPTO_RSA_OAEP_SHA256 -+ CONFIG_CRYPTO=openssl -+ ifdef TLS_FUNCS -+@@ -746,6 +748,7 @@ CFLAGS += -DTLS_DEFAULT_CIPHERS=\"$(CONF -+ endif -+ -+ ifeq ($(CONFIG_TLS), mbedtls) -++CFLAGS += -DCONFIG_TLS_MBEDTLS -+ ifndef CONFIG_CRYPTO -+ CONFIG_CRYPTO=mbedtls -+ endif -+@@ -776,6 +779,7 @@ endif -+ endif -+ -+ ifeq ($(CONFIG_TLS), gnutls) -++CFLAGS += -DCONFIG_TLS_GNUTLS -+ ifndef CONFIG_CRYPTO -+ # default to libgcrypt -+ CONFIG_CRYPTO=gnutls -+@@ -806,6 +810,7 @@ endif -+ endif -+ -+ ifeq ($(CONFIG_TLS), internal) -++CFLAGS += -DCONFIG_TLS_INTERNAL -+ ifndef CONFIG_CRYPTO -+ CONFIG_CRYPTO=internal -+ endif -+@@ -884,6 +889,7 @@ endif -+ endif -+ -+ ifeq ($(CONFIG_TLS), linux) -++CFLAGS += -DCONFIG_TLS_INTERNAL -+ OBJS += ../src/crypto/crypto_linux.o -+ ifdef TLS_FUNCS -+ OBJS += ../src/crypto/crypto_internal-rsa.o -+--- a/src/crypto/Makefile -++++ b/src/crypto/Makefile -+@@ -1,10 +1,121 @@ -+-CFLAGS += -DCONFIG_CRYPTO_INTERNAL -+-CFLAGS += -DCONFIG_TLS_INTERNAL_CLIENT -+-CFLAGS += -DCONFIG_TLS_INTERNAL_SERVER -+ #CFLAGS += -DALL_DH_GROUPS -+ CFLAGS += -DCONFIG_SHA256 -+ CFLAGS += -DCONFIG_SHA384 -++CFLAGS += -DCONFIG_HMAC_SHA256_KDF -+ CFLAGS += -DCONFIG_HMAC_SHA384_KDF -++ -++# crypto_module_tests.c -++CFLAGS += -DCONFIG_MODULE_TESTS -++CFLAGS += -DCONFIG_DPP -++#CFLAGS += -DCONFIG_DPP2 -++#CFLAGS += -DCONFIG_DPP3 -++CFLAGS += -DCONFIG_ECC -++CFLAGS += -DCONFIG_MESH -++CFLAGS += -DEAP_PSK -++CFLAGS += -DEAP_FAST -++ -++ifeq ($(CONFIG_TLS),mbedtls) -++ -++# (enable features for 'cd tests; make run-tests CONFIG_TLS=mbedtls') -++CFLAGS += -DCRYPTO_RSA_OAEP_SHA256 -++CFLAGS += -DCONFIG_DES -++CFLAGS += -DEAP_IKEV2 -++CFLAGS += -DEAP_MSCHAPv2 -++CFLAGS += -DEAP_SIM -++ -++LIB_OBJS = tls_mbedtls.o crypto_mbedtls.o -++LIB_OBJS+= \ -++ aes-eax.o \ -++ aes-siv.o \ -++ dh_groups.o \ -++ milenage.o \ -++ ms_funcs.o -++ -++else -++ifeq ($(CONFIG_TLS),openssl) -++ -++# (enable features for 'cd tests; make run-tests CONFIG_TLS=openssl') -++ifndef CONFIG_TLS_DEFAULT_CIPHERS -++CONFIG_TLS_DEFAULT_CIPHERS = "DEFAULT:!EXP:!LOW" -++endif -++CFLAGS += -DTLS_DEFAULT_CIPHERS=\"$(CONFIG_TLS_DEFAULT_CIPHERS)\" -++CFLAGS += -DCRYPTO_RSA_OAEP_SHA256 -++CFLAGS += -DEAP_TLS_OPENSSL -++ -++LIB_OBJS = tls_openssl.o fips_prf_openssl.o crypto_openssl.o -++LIB_OBJS+= \ -++ aes-ctr.o \ -++ aes-eax.o \ -++ aes-encblock.o \ -++ aes-siv.o \ -++ dh_groups.o \ -++ milenage.o \ -++ ms_funcs.o \ -++ sha1-prf.o \ -++ sha1-tlsprf.o \ -++ sha1-tprf.o \ -++ sha256-kdf.o \ -++ sha256-prf.o \ -++ sha256-tlsprf.o -++ -++else -++ifeq ($(CONFIG_TLS),wolfssl) -++ -++# (wolfssl libraries must be built with ./configure --enable-wpas) -++# (enable features for 'cd tests; make run-tests CONFIG_TLS=wolfssl') -++CFLAGS += -DWOLFSSL_DER_LOAD -++CFLAGS += -DCONFIG_DES -++ -++LIB_OBJS = tls_wolfssl.o fips_prf_wolfssl.o crypto_wolfssl.o -++LIB_OBJS+= \ -++ aes-ctr.o \ -++ aes-eax.o \ -++ aes-encblock.o \ -++ aes-siv.o \ -++ dh_groups.o \ -++ milenage.o \ -++ ms_funcs.o \ -++ sha1-prf.o \ -++ sha1-tlsprf.o \ -++ sha1-tprf.o \ -++ sha256-kdf.o \ -++ sha256-prf.o \ -++ sha256-tlsprf.o -++ -++else -++ifeq ($(CONFIG_TLS),gnutls) -++ -++# (enable features for 'cd tests; make run-tests CONFIG_TLS=gnutls') -++LIB_OBJS = tls_gnutls.o crypto_gnutls.o -++LIB_OBJS+= \ -++ aes-cbc.o \ -++ aes-ctr.o \ -++ aes-eax.o \ -++ aes-encblock.o \ -++ aes-omac1.o \ -++ aes-siv.o \ -++ aes-unwrap.o \ -++ aes-wrap.o \ -++ dh_group5.o \ -++ dh_groups.o \ -++ milenage.o \ -++ ms_funcs.o \ -++ rc4.o \ -++ sha1-pbkdf2.o \ -++ sha1-prf.o \ -++ fips_prf_internal.o \ -++ sha1-internal.o \ -++ sha1-tlsprf.o \ -++ sha1-tprf.o \ -++ sha256-kdf.o \ -++ sha256-prf.o \ -++ sha256-tlsprf.o -++ -++else -++ -++CFLAGS += -DCONFIG_CRYPTO_INTERNAL -++CFLAGS += -DCONFIG_TLS_INTERNAL_CLIENT -++CFLAGS += -DCONFIG_TLS_INTERNAL_SERVER -+ CFLAGS += -DCONFIG_INTERNAL_SHA384 -+ -+ LIB_OBJS= \ -+@@ -13,7 +124,6 @@ LIB_OBJS= \ -+ aes-ctr.o \ -+ aes-eax.o \ -+ aes-encblock.o \ -+- aes-gcm.o \ -+ aes-internal.o \ -+ aes-internal-dec.o \ -+ aes-internal-enc.o \ -+@@ -37,6 +147,7 @@ LIB_OBJS= \ -+ sha1-tlsprf.o \ -+ sha1-tprf.o \ -+ sha256.o \ -++ sha256-kdf.o \ -+ sha256-prf.o \ -+ sha256-tlsprf.o \ -+ sha256-internal.o \ -+@@ -53,6 +164,16 @@ LIB_OBJS += crypto_internal-modexp.o -+ LIB_OBJS += crypto_internal-rsa.o -+ LIB_OBJS += tls_internal.o -+ LIB_OBJS += fips_prf_internal.o -++ -++endif -++endif -++endif -++endif -++ -++ -++# (used by wlantest/{bip,gcmp,rx_mgmt}.c and tests/test-aes.c) -++LIB_OBJS += aes-gcm.o -++ -+ ifndef TEST_FUZZ -+ LIB_OBJS += random.o -+ endif -+--- a/src/crypto/crypto_module_tests.c -++++ b/src/crypto/crypto_module_tests.c -+@@ -2469,6 +2469,139 @@ static int test_hpke(void) -+ } -+ -+ -++static int test_ecc(void) -++{ -++#ifdef CONFIG_ECC -++#ifndef CONFIG_TLS_INTERNAL -++#ifndef CONFIG_TLS_GNUTLS -++#if defined(CONFIG_TLS_MBEDTLS) \ -++ || defined(CONFIG_TLS_OPENSSL) \ -++ || defined(CONFIG_TLS_WOLFSSL) -++ wpa_printf(MSG_INFO, "Testing ECC"); -++ /* Note: some tests below are valid on supported Short Weierstrass -++ * curves, but not on Montgomery curves (e.g. IKE groups 31 and 32) -++ * (e.g. deriving and comparing y^2 test below not valid on Montgomery) -++ */ -++#ifdef CONFIG_TLS_MBEDTLS -++ const int grps[] = {19, 20, 21, 25, 26, 28}; -++#endif -++#ifdef CONFIG_TLS_OPENSSL -++ const int grps[] = {19, 20, 21, 26}; -++#endif -++#ifdef CONFIG_TLS_WOLFSSL -++ const int grps[] = {19, 20, 21, 26}; -++#endif -++ uint32_t i; -++ struct crypto_ec *e = NULL; -++ struct crypto_ec_point *p = NULL, *q = NULL; -++ struct crypto_bignum *x = NULL, *y = NULL; -++#ifdef CONFIG_DPP -++ u8 bin[4096]; -++#endif -++ for (i = 0; i < ARRAY_SIZE(grps); ++i) { -++ e = crypto_ec_init(grps[i]); -++ if (e == NULL -++ || crypto_ec_prime_len(e) == 0 -++ || crypto_ec_prime_len_bits(e) == 0 -++ || crypto_ec_order_len(e) == 0 -++ || crypto_ec_get_prime(e) == NULL -++ || crypto_ec_get_order(e) == NULL -++ || crypto_ec_get_a(e) == NULL -++ || crypto_ec_get_b(e) == NULL -++ || crypto_ec_get_generator(e) == NULL) { -++ break; -++ } -++#ifdef CONFIG_DPP -++ struct crypto_ec_key *key = crypto_ec_key_gen(grps[i]); -++ if (key == NULL) -++ break; -++ p = crypto_ec_key_get_public_key(key); -++ q = crypto_ec_key_get_public_key(key); -++ crypto_ec_key_deinit(key); -++ if (p == NULL || q == NULL) -++ break; -++ if (!crypto_ec_point_is_on_curve(e, p)) -++ break; -++ -++ /* inverted point should not match original; -++ * double-invert should match */ -++ if (crypto_ec_point_invert(e, q) != 0 -++ || crypto_ec_point_cmp(e, p, q) == 0 -++ || crypto_ec_point_invert(e, q) != 0 -++ || crypto_ec_point_cmp(e, p, q) != 0) { -++ break; -++ } -++ -++ /* crypto_ec_point_to_bin() and crypto_ec_point_from_bin() -++ * imbalanced interfaces? */ -++ size_t prime_len = crypto_ec_prime_len(e); -++ if (prime_len * 2 > sizeof(bin)) -++ break; -++ if (crypto_ec_point_to_bin(e, p, bin, bin+prime_len) != 0) -++ break; -++ struct crypto_ec_point *tmp = crypto_ec_point_from_bin(e, bin); -++ if (tmp == NULL) -++ break; -++ if (crypto_ec_point_cmp(e, p, tmp) != 0) { -++ crypto_ec_point_deinit(tmp, 0); -++ break; -++ } -++ crypto_ec_point_deinit(tmp, 0); -++ -++ x = crypto_bignum_init(); -++ y = crypto_bignum_init_set(bin+prime_len, prime_len); -++ if (x == NULL || y == NULL || crypto_ec_point_x(e, p, x) != 0) -++ break; -++ struct crypto_bignum *y2 = crypto_ec_point_compute_y_sqr(e, x); -++ if (y2 == NULL) -++ break; -++ if (crypto_bignum_sqrmod(y, crypto_ec_get_prime(e), y) != 0 -++ || crypto_bignum_cmp(y, y2) != 0) { -++ crypto_bignum_deinit(y2, 0); -++ break; -++ } -++ crypto_bignum_deinit(y2, 0); -++ crypto_bignum_deinit(x, 0); -++ crypto_bignum_deinit(y, 0); -++ x = NULL; -++ y = NULL; -++ -++ x = crypto_bignum_init(); -++ if (x == NULL) -++ break; -++ if (crypto_bignum_rand(x, crypto_ec_get_prime(e)) != 0) -++ break; -++ crypto_bignum_deinit(x, 0); -++ x = NULL; -++ -++ crypto_ec_point_deinit(p, 0); -++ p = NULL; -++ crypto_ec_point_deinit(q, 0); -++ q = NULL; -++#endif /* CONFIG_DPP */ -++ crypto_ec_deinit(e); -++ e = NULL; -++ } -++ if (i != ARRAY_SIZE(grps)) { -++ crypto_bignum_deinit(x, 0); -++ crypto_bignum_deinit(y, 0); -++ crypto_ec_point_deinit(p, 0); -++ crypto_ec_point_deinit(q, 0); -++ crypto_ec_deinit(e); -++ wpa_printf(MSG_INFO, -++ "ECC test case failed tls_id:%d", grps[i]); -++ return -1; -++ } -++ -++ wpa_printf(MSG_INFO, "ECC test cases passed"); -++#endif -++#endif /* !CONFIG_TLS_GNUTLS */ -++#endif /* !CONFIG_TLS_INTERNAL */ -++#endif /* CONFIG_ECC */ -++ return 0; -++} -++ -++ -+ static int test_ms_funcs(void) -+ { -+ #ifndef CONFIG_FIPS -+@@ -2590,6 +2723,7 @@ int crypto_module_tests(void) -+ test_fips186_2_prf() || -+ test_extract_expand_hkdf() || -+ test_hpke() || -++ test_ecc() || -+ test_ms_funcs()) -+ ret = -1; -+ -+--- a/src/tls/Makefile -++++ b/src/tls/Makefile -+@@ -1,3 +1,10 @@ -++LIB_OBJS= asn1.o -++ -++ifneq ($(CONFIG_TLS),gnutls) -++ifneq ($(CONFIG_TLS),mbedtls) -++ifneq ($(CONFIG_TLS),openssl) -++ifneq ($(CONFIG_TLS),wolfssl) -++ -+ CFLAGS += -DCONFIG_INTERNAL_LIBTOMMATH -+ CFLAGS += -DCONFIG_CRYPTO_INTERNAL -+ CFLAGS += -DCONFIG_TLSV11 -+@@ -21,5 +28,9 @@ LIB_OBJS= \ -+ tlsv1_server_read.o \ -+ tlsv1_server_write.o \ -+ x509v3.o -++endif -++endif -++endif -++endif -+ -+ include ../lib.rules -+--- a/tests/Makefile -++++ b/tests/Makefile -+@@ -1,8 +1,10 @@ -+-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 -++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 -+ -+ include ../src/build.rules -+ -+@@ -24,13 +26,27 @@ CFLAGS += -DCONFIG_IEEE80211R_AP -+ CFLAGS += -DCONFIG_IEEE80211R -+ CFLAGS += -DCONFIG_TDLS -+ -++# test-crypto_module -++CFLAGS += -DCONFIG_MODULE_TESTS -++CFLAGS += -DCONFIG_DPP -++#CFLAGS += -DCONFIG_DPP2 -++#CFLAGS += -DCONFIG_DPP3 -++CFLAGS += -DCONFIG_ECC -++CFLAGS += -DCONFIG_HMAC_SHA256_KDF -++CFLAGS += -DCONFIG_HMAC_SHA384_KDF -++CFLAGS += -DCONFIG_MESH -++CFLAGS += -DCONFIG_SHA256 -++CFLAGS += -DCONFIG_SHA384 -++CFLAGS += -DEAP_PSK -++CFLAGS += -DEAP_FAST -++ -+ CFLAGS += -I../src -+ CFLAGS += -I../src/utils -+ -+ SLIBS = ../src/utils/libutils.a -+ -+-DLIBS = ../src/crypto/libcrypto.a \ -+- ../src/tls/libtls.a -++DLIBS = ../src/tls/libtls.a \ -++ ../src/crypto/libcrypto.a -+ -+ _OBJS_VAR := LLIBS -+ include ../src/objs.mk -+@@ -42,12 +58,43 @@ include ../src/objs.mk -+ LIBS = $(SLIBS) $(DLIBS) -+ LLIBS = -Wl,--start-group $(DLIBS) -Wl,--end-group $(SLIBS) -+ -++ifeq ($(CONFIG_TLS),mbedtls) -++CFLAGS += -DCONFIG_TLS_MBEDTLS -++LLIBS += -lmbedtls -lmbedx509 -lmbedcrypto -++else -++ifeq ($(CONFIG_TLS),openssl) -++CFLAGS += -DCONFIG_TLS_OPENSSL -++LLIBS += -lssl -lcrypto -++else -++ifeq ($(CONFIG_TLS),gnutls) -++CFLAGS += -DCONFIG_TLS_GNUTLS -++LLIBS += -lgnutls -lgpg-error -lgcrypt -++else -++ifeq ($(CONFIG_TLS),wolfssl) -++CFLAGS += -DCONFIG_TLS_WOLFSSL -++LLIBS += -lwolfssl -lm -++else -++CFLAGS += -DCONFIG_TLS_INTERNAL -++CFLAGS += -DCONFIG_TLS_INTERNAL_SERVER -++ALL += test-rsa-sig-ver -++ALL += test-x509v3 -++clean-config_tls_internal: -++ rm -f test_x509v3_nist.out.* -++ rm -f test_x509v3_nist2.out.* -++endif -++endif -++endif -++endif -++ -+ # glibc < 2.17 needs -lrt for clock_gettime() -+ LLIBS += -lrt -+ -+ test-aes: $(call BUILDOBJ,test-aes.o) $(LIBS) -+ $(LDO) $(LDFLAGS) -o $@ $^ $(LLIBS) -+ -++test-crypto_module: $(call BUILDOBJ,test-crypto_module.o) $(LIBS) -++ $(LDO) $(LDFLAGS) -o $@ $< $(LLIBS) -++ -+ test-base64: $(call BUILDOBJ,test-base64.o) $(LIBS) -+ $(LDO) $(LDFLAGS) -o $@ $^ $(LLIBS) -+ -+@@ -83,17 +130,11 @@ test-x509v3: $(call BUILDOBJ,test-x509v3 -+ -+ -+ run-tests: $(ALL) -+- ./test-aes -+- ./test-list -+- ./test-md4 -+- ./test-milenage -+- ./test-rsa-sig-ver -+- ./test-sha1 -+- ./test-sha256 -++ @set -ex; for i in $(RUN_TESTS); do ./$$i; done -+ @echo -+ @echo All tests completed successfully. -+ -+-clean: common-clean -++clean: common-clean clean-config_tls_internal -+ rm -f *~ -+- rm -f test_x509v3_nist.out.* -+- rm -f test_x509v3_nist2.out.* -++ -++.PHONY: run-tests clean-config_tls_internal -+--- a/tests/hwsim/example-hostapd.config -++++ b/tests/hwsim/example-hostapd.config -+@@ -34,15 +34,7 @@ CONFIG_EAP_TNC=y -+ CFLAGS += -DTNC_CONFIG_FILE=\"tnc/tnc_config\" -+ LIBS += -rdynamic -+ CONFIG_EAP_UNAUTH_TLS=y -+-ifeq ($(CONFIG_TLS), openssl) -+-CONFIG_EAP_PWD=y -+-endif -+-ifeq ($(CONFIG_TLS), wolfssl) -+-CONFIG_EAP_PWD=y -+-endif -+-ifeq ($(CONFIG_TLS), mbedtls) -+-CONFIG_EAP_PWD=y -+-endif -++CONFIG_EAP_PWD=$(if $(filter openssl wolfssl mbedtls,$(CONFIG_TLS)),y,) -+ 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 -+ CONFIG_EAP_FAST=y -+ CONFIG_EAP_TEAP=y -+ CONFIG_EAP_IKEV2=y -+- -+-ifeq ($(CONFIG_TLS), openssl) -+-CONFIG_EAP_PWD=y -+-endif -+-ifeq ($(CONFIG_TLS), wolfssl) -+-CONFIG_EAP_PWD=y -+-endif -+-ifeq ($(CONFIG_TLS), mbedtls) -+-CONFIG_EAP_PWD=y -+-endif -++CONFIG_EAP_PWD=$(if $(filter openssl wolfssl mbedtls,$(CONFIG_TLS)),y,) -+ -+ 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): -+ res = dev.get_capability("eap") -+ if method not in res: -+ raise HwsimSkip("EAP method %s not supported in the build" % method) -++ if method == "FAST" or method == "TEAP": -++ tls = dev.request("GET tls_library") -++ if tls.startswith("mbed TLS"): -++ raise HwsimSkip("EAP-%s not supported with this TLS library: " % method + tls) -+ -+ def check_subject_match_support(dev): -+ tls = dev.request("GET tls_library") -+- if not tls.startswith("OpenSSL") and not tls.startswith("wolfSSL"): -++ if tls.startswith("OpenSSL"): -++ return -++ elif tls.startswith("wolfSSL"): -++ return -++ elif tls.startswith("mbed TLS"): -++ return -++ else: -+ raise HwsimSkip("subject_match not supported with this TLS library: " + tls) -+ -+ def check_check_cert_subject_support(dev): -+ tls = dev.request("GET tls_library") -+- if not tls.startswith("OpenSSL") and not tls.startswith("wolfSSL"): -++ if tls.startswith("OpenSSL"): -++ return -++ elif tls.startswith("wolfSSL"): -++ return -++ elif tls.startswith("mbed TLS"): -++ return -++ else: -+ raise HwsimSkip("check_cert_subject not supported with this TLS library: " + tls) -+ -+ def check_altsubject_match_support(dev): -+ tls = dev.request("GET tls_library") -+- if not tls.startswith("OpenSSL") and not tls.startswith("wolfSSL"): -++ if tls.startswith("OpenSSL"): -++ return -++ elif tls.startswith("wolfSSL"): -++ return -++ elif tls.startswith("mbed TLS"): -++ return -++ else: -+ raise HwsimSkip("altsubject_match not supported with this TLS library: " + tls) -+ -+ def check_domain_match(dev): -+@@ -70,7 +92,13 @@ def check_domain_suffix_match(dev): -+ -+ def check_domain_match_full(dev): -+ tls = dev.request("GET tls_library") -+- if not tls.startswith("OpenSSL") and not tls.startswith("wolfSSL"): -++ if tls.startswith("OpenSSL"): -++ return -++ elif tls.startswith("wolfSSL"): -++ return -++ elif tls.startswith("mbed TLS"): -++ return -++ else: -+ raise HwsimSkip("domain_suffix_match requires full match with this TLS library: " + tls) -+ -+ def check_cert_probe_support(dev): -+@@ -79,8 +107,15 @@ def check_cert_probe_support(dev): -+ raise HwsimSkip("Certificate probing not supported with this TLS library: " + tls) -+ -+ def check_ext_cert_check_support(dev): -++ if not openssl_imported: -++ raise HwsimSkip("OpenSSL python method not available") -++ -+ tls = dev.request("GET tls_library") -+- if not tls.startswith("OpenSSL"): -++ if tls.startswith("OpenSSL"): -++ return -++ elif tls.startswith("mbed TLS"): -++ return -++ else: -+ raise HwsimSkip("ext_cert_check not supported with this TLS library: " + tls) -+ -+ def check_ocsp_support(dev): -+@@ -91,14 +126,18 @@ def check_ocsp_support(dev): -+ # raise HwsimSkip("OCSP not supported with this TLS library: " + tls) -+ #if tls.startswith("wolfSSL"): -+ # raise HwsimSkip("OCSP not supported with this TLS library: " + tls) -++ if tls.startswith("mbed TLS"): -++ raise HwsimSkip("OCSP not supported with this TLS library: " + tls) -+ -+ def check_pkcs5_v15_support(dev): -+ tls = dev.request("GET tls_library") -+- if "BoringSSL" in tls or "GnuTLS" in tls: -++ if "BoringSSL" in tls or "GnuTLS" in tls or "mbed TLS" in tls: -+ raise HwsimSkip("PKCS#5 v1.5 not supported with this TLS library: " + tls) -+ -+ def check_tls13_support(dev): -+ 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): -+ # 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) -++ if tls.startswith("mbed TLS"): -++ raise HwsimSkip("PKCS#12 not supported with this TLS library: " + tls) -+ -+ def check_dh_dsa_support(dev): -+ tls = dev.request("GET tls_library") -+ if tls.startswith("internal"): -+ raise HwsimSkip("DH DSA not supported with this TLS library: " + tls) -++ if tls.startswith("mbed TLS"): -++ raise HwsimSkip("DH DSA not supported with this TLS library: " + tls) -+ -+ def check_ec_support(dev): -+ tls = dev.request("GET tls_library") -+@@ -1595,7 +1638,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", -+- subject_match="/C=FI/O=w1.fi/CN=server.w1.fi", -++ check_cert_subject="/C=FI/O=w1.fi/CN=server.w1.fi", -+ 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 -+ -+ def test_ap_wpa2_eap_tls_neg_subject_match(dev, apdev): -+ """WPA2-Enterprise negative test - subject mismatch""" -++ check_subject_match_support(dev[0]) -+ 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 -+ -+ def test_ap_wpa2_eap_tls_neg_altsubject_match(dev, apdev): -+ """WPA2-Enterprise negative test - altsubject mismatch""" -++ check_altsubject_match_support(dev[0]) -+ 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 -+ dev[0].request("REMOVE_NETWORK all") -+ -+ tls = dev[0].request("GET tls_library") -+- if not tls.startswith("wolfSSL"): -++ if not tls.startswith("wolfSSL") and not tls.startswith("mbed TLS"): -+ 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 -+ params["private_key"] = "auth_serv/iCA-server/server.key" -+ hostapd.add_ap(apdev[0], params) -+ tls = dev[0].request("GET tls_library") -+- if "GnuTLS" in tls or "wolfSSL" in tls: -++ if "GnuTLS" in tls or "wolfSSL" in tls or "mbed TLS" in tls: -+ 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 -+ 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): -++ check_ocsp_support(dev[0]) -+ 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_ -+ try: -+ hostapd.add_ap(apdev[0], params) -+ tls = dev[0].request("GET tls_library") -+- if "GnuTLS" in tls or "wolfSSL" in tls: -++ if "GnuTLS" in tls or "wolfSSL" in tls or "mbed TLS" in tls: -+ 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_ -+ try: -+ hostapd.add_ap(apdev[0], params) -+ tls = dev[0].request("GET tls_library") -+- if "GnuTLS" in tls or "wolfSSL" in tls: -++ if "GnuTLS" in tls or "wolfSSL" in tls or "mbed TLS" in tls: -+ 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 -+ try: -+ hostapd.add_ap(apdev[0], params) -+ tls = dev[0].request("GET tls_library") -+- if "GnuTLS" in tls or "wolfSSL" in tls: -++ if "GnuTLS" in tls or "wolfSSL" in tls or "mbed TLS" in tls: -+ 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 -+ -+ hostapd.add_ap(apdev[0], params) -+ tls = dev[0].request("GET tls_library") -+- if "GnuTLS" in tls or "wolfSSL" in tls: -++ if "GnuTLS" in tls or "wolfSSL" in tls or "mbed TLS" in tls: -+ 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 -+ -+ def test_ap_wpa2_eap_ttls_server_pkcs12(dev, apdev): -+ """WPA2-Enterprise using EAP-TTLS and server PKCS#12 file""" -++ check_pkcs12_support(dev[0]) -+ 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( -+ -+ def test_ap_wpa2_eap_ttls_server_pkcs12_extra(dev, apdev): -+ """EAP-TTLS and server PKCS#12 file with extra certs""" -++ check_pkcs12_support(dev[0]) -+ 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 -+ -+ def test_ap_wpa2_eap_ttls_dh_params_dsa_server(dev, apdev): -+ """WPA2-Enterprise using EAP-TTLS and alternative server dhparams (DSA)""" -++ check_dh_dsa_support(dev[0]) -+ 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 -+ def test_openssl_cipher_suite_config_wpas(dev, apdev): -+ """OpenSSL cipher suite configuration on wpa_supplicant""" -+ tls = dev[0].request("GET tls_library") -+- if not tls.startswith("OpenSSL"): -+- raise HwsimSkip("TLS library is not OpenSSL: " + tls) -++ if not tls.startswith("OpenSSL") and not tls.startswith("mbed TLS"): -++ raise HwsimSkip("TLS library is not OpenSSL or mbed TLS: " + tls) -+ 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 -+ def test_openssl_cipher_suite_config_hapd(dev, apdev): -+ """OpenSSL cipher suite configuration on hostapd""" -+ tls = dev[0].request("GET tls_library") -+- if not tls.startswith("OpenSSL"): -+- raise HwsimSkip("wpa_supplicant TLS library is not OpenSSL: " + tls) -++ if not tls.startswith("OpenSSL") and not tls.startswith("mbed TLS"): -++ raise HwsimSkip("wpa_supplicant TLS library is not OpenSSL or mbed TLS: " + tls) -+ params = int_eap_server_params() -+ params['openssl_ciphers'] = "AES256" -+ hapd = hostapd.add_ap(apdev[0], params) -+ tls = hapd.request("GET tls_library") -+- if not tls.startswith("OpenSSL"): -+- raise HwsimSkip("hostapd TLS library is not OpenSSL: " + tls) -++ if not tls.startswith("OpenSSL") and not tls.startswith("mbed TLS"): -++ raise HwsimSkip("hostapd TLS library is not OpenSSL or mbed TLS: " + tls) -+ 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 -+ check_tls_ver(dev[0], hapd, -+ "tls_disable_tlsv1_0=1 tls_disable_tlsv1_1=1", -+ "TLSv1.2") -+- elif tls.startswith("internal"): -++ elif tls.startswith("internal") or tls.startswith("mbed TLS"): -+ check_tls_ver(dev[0], hapd, -+ "tls_disable_tlsv1_0=1 tls_disable_tlsv1_1=1", "TLSv1.2") -+- check_tls_ver(dev[1], hapd, -+- "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 tls.startswith("mbed TLS"): -++ check_tls_ver(dev[2], hapd, -++ "tls_disable_tlsv1_0=0 tls_disable_tlsv1_1=1 tls_disable_tlsv1_2=1", "TLSv1.0") -++ else: -++ check_tls_ver(dev[1], hapd, -++ "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: -+ 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 -+ 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]")] -++ tls = dev[0].request("GET tls_library") -++ if tls.startswith("mbed TLS"): -++ tests = [#("TLSv1.0", "[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]")] -+ for exp, flags in tests: -+ hapd.disable() -+ hapd.set("tls_flags", flags) -+@@ -7115,6 +7173,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 -++ check_ext_cert_check_support(dev[0]) -+ id = dev[0].connect("test-wpa2-eap", key_mgmt="WPA-EAP", eap="TLS", -+ identity="tls user", -+ ca_cert="auth_serv/ca.pem", -+@@ -7127,6 +7186,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 -++ check_ext_cert_check_support(dev[0]) -+ id = dev[0].connect("test-wpa2-eap", key_mgmt="WPA-EAP", eap="TTLS", -+ identity="pap user", anonymous_identity="ttls", -+ password="password", phase2="auth=PAP", -+@@ -7137,6 +7197,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 -++ check_ext_cert_check_support(dev[0]) -+ id = dev[0].connect("test-wpa2-eap", key_mgmt="WPA-EAP", eap="PEAP", -+ identity="user", anonymous_identity="peap", -+ ca_cert="auth_serv/ca.pem", -+@@ -7147,6 +7208,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""" -++ check_ext_cert_check_support(dev[0]) -+ check_eap_capa(dev[0], "FAST") -+ # With internal server certificate chain validation -+ dev[0].request("SET blob fast_pac_auth_ext ") -+@@ -7161,10 +7223,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): -+- check_ext_cert_check_support(dev[0]) -+- if not openssl_imported: -+- raise HwsimSkip("OpenSSL python method not available") -+- -+ params = hostapd.wpa2_eap_params(ssid="test-wpa2-eap") -+ hapd = hostapd.add_ap(apdev[0], params) -+ -+--- a/tests/hwsim/test_ap_ft.py -++++ b/tests/hwsim/test_ap_ft.py -+@@ -2471,11 +2471,11 @@ def test_ap_ft_ap_oom5(dev, apdev): -+ # This will fail to roam -+ dev[0].roam(bssid1, check_bssid=False) -+ -+- with fail_test(hapd1, 1, "sha256_prf_bits;wpa_pmk_r1_to_ptk;wpa_ft_process_auth_req"): -++ with fail_test(hapd1, 1, "sha256_prf;wpa_pmk_r1_to_ptk;wpa_ft_process_auth_req"): -+ # This will fail to roam -+ dev[0].roam(bssid1, check_bssid=False) -+ -+- with fail_test(hapd1, 3, "wpa_pmk_r1_to_ptk;wpa_ft_process_auth_req"): -++ with fail_test(hapd1, 2, "wpa_pmk_r1_to_ptk;wpa_ft_process_auth_req"): -+ # This will fail to roam -+ dev[0].roam(bssid1, check_bssid=False) -+ -+--- a/tests/hwsim/test_authsrv.py -++++ b/tests/hwsim/test_authsrv.py -+@@ -156,9 +156,12 @@ def test_authsrv_oom(dev, apdev): -+ if "FAIL" not in authsrv.request("ENABLE"): -+ raise Exception("ENABLE succeeded during OOM") -+ -+- with alloc_fail(authsrv, 1, "tls_init;authsrv_init"): -+- if "FAIL" not in authsrv.request("ENABLE"): -+- raise Exception("ENABLE succeeded during OOM") -++ # tls_mbedtls.c:tls_init() does not alloc memory (no alloc fail trigger) -++ tls = dev[0].request("GET tls_library") -++ if not tls.startswith("mbed TLS"): -++ with alloc_fail(authsrv, 1, "tls_init;authsrv_init"): -++ if "FAIL" not in authsrv.request("ENABLE"): -++ raise Exception("ENABLE succeeded during OOM") -+ -+ for count in range(1, 3): -+ with alloc_fail(authsrv, count, "eap_sim_db_init;authsrv_init"): -+--- a/tests/hwsim/test_dpp.py -++++ b/tests/hwsim/test_dpp.py -+@@ -39,7 +39,8 @@ def check_dpp_capab(dev, brainpool=False -+ raise HwsimSkip("DPP not supported") -+ if brainpool: -+ tls = dev.request("GET tls_library") -+- if (not tls.startswith("OpenSSL") or "run=BoringSSL" in tls) and not tls.startswith("wolfSSL"): -++ if (not tls.startswith("OpenSSL") or "run=BoringSSL" in tls) and not tls.startswith("wolfSSL") \ -++ and not tls.startswith("mbed TLS"): -+ 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 -+ -+ def test_dpp_proto_auth_req_invalid_i_proto_key(dev, apdev): -+ """DPP protocol testing - invalid I-proto key in Auth Req""" -++ tls = dev[0].request("GET tls_library") -++ if tls.startswith("mbed TLS"): -++ raise HwsimSkip("mbed TLS crypto_ecdh_set_peerkey() properly detects invalid key; no response") -+ 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_ -+ -+ def test_dpp_proto_auth_resp_invalid_r_proto_key(dev, apdev): -+ """DPP protocol testing - invalid R-Proto Key in Auth Resp""" -+- run_dpp_proto_auth_resp_missing(dev, 67, "Invalid Responder Protocol Key") -++ tls = dev[0].request("GET tls_library") -++ if tls.startswith("mbed TLS"): -++ # mbed TLS crypto_ecdh_set_peerkey() properly detects invalid key -++ run_dpp_proto_auth_resp_missing(dev, 67, "Failed to derive ECDH shared secret") -++ else: -++ run_dpp_proto_auth_resp_missing(dev, 67, "Invalid Responder Protocol Key") -+ -+ 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 -+ -+ def test_dpp_proto_pkex_cr_req_invalid_bootstrap_key(dev, apdev): -+ """DPP protocol testing - invalid Bootstrap Key in PKEX Commit-Reveal Request""" -++ tls = dev[0].request("GET tls_library") -++ if tls.startswith("mbed TLS"): -++ raise HwsimSkip("mbed TLS crypto_ecdh_set_peerkey() properly detects invalid key; no response") -+ run_dpp_proto_pkex_req_missing(dev, 47, -+ "Peer bootstrapping key is invalid") -+ -+ def test_dpp_proto_pkex_cr_resp_invalid_bootstrap_key(dev, apdev): -+ """DPP protocol testing - invalid Bootstrap Key in PKEX Commit-Reveal Response""" -++ tls = dev[0].request("GET tls_library") -++ if tls.startswith("mbed TLS"): -++ raise HwsimSkip("mbed TLS crypto_ecdh_set_peerkey() properly detects invalid key; no response") -+ run_dpp_proto_pkex_resp_missing(dev, 48, -+ "Peer bootstrapping key is invalid") -+ -+--- a/tests/hwsim/test_erp.py -++++ b/tests/hwsim/test_erp.py -+@@ -12,7 +12,7 @@ import time -+ -+ import hostapd -+ from utils import * -+-from test_ap_eap import int_eap_server_params, check_tls13_support -++from test_ap_eap import int_eap_server_params, check_tls13_support, check_eap_capa -+ from test_ap_psk import find_wpas_process, read_process_memory, verify_not_present, get_key_locations -+ -+ def test_erp_initiate_reauth_start(dev, apdev): -+@@ -276,6 +276,7 @@ def test_erp_radius_eap_methods(dev, apd -+ params['erp_domain'] = 'example.com' -+ params['disable_pmksa_caching'] = '1' -+ hapd = hostapd.add_ap(apdev[0], params) -++ tls = dev[0].request("GET tls_library") -+ -+ erp_test(dev[0], hapd, eap="AKA", identity="0232010000000000@example.com", -+ password="90dca4eda45b53cf0f12d7c9c3bc6a89:cb9cccc4b9258e6dca4760379fb82581:000000000123") -+@@ -289,7 +290,7 @@ def test_erp_radius_eap_methods(dev, apd -+ password="5122250214c33e723a5dd523fc145fc0:981d464c7c52eb6e5036234984ad0bcf:000000000123") -+ erp_test(dev[0], hapd, eap="EKE", identity="erp-eke@example.com", -+ password="hello") -+- if "FAST" in eap_methods: -++ if "FAST" in eap_methods and check_eap_capa(dev[0], "FAST"): -+ erp_test(dev[0], hapd, eap="FAST", identity="erp-fast@example.com", -+ password="password", ca_cert="auth_serv/ca.pem", -+ phase2="auth=GTC", -+@@ -301,13 +302,14 @@ def test_erp_radius_eap_methods(dev, apd -+ password="password") -+ erp_test(dev[0], hapd, eap="PAX", identity="erp-pax@example.com", -+ password_hex="0123456789abcdef0123456789abcdef") -+- if "MSCHAPV2" in eap_methods: -++ if "MSCHAPV2" in eap_methods and check_eap_capa(dev[0], "MSCHAPV2"): -+ erp_test(dev[0], hapd, eap="PEAP", identity="erp-peap@example.com", -+ password="password", ca_cert="auth_serv/ca.pem", -+ phase2="auth=MSCHAPV2") -+- erp_test(dev[0], hapd, eap="TEAP", identity="erp-teap@example.com", -+- password="password", ca_cert="auth_serv/ca.pem", -+- phase2="auth=MSCHAPV2", pac_file="blob://teap_pac") -++ if check_eap_capa(dev[0], "TEAP"): -++ erp_test(dev[0], hapd, eap="TEAP", identity="erp-teap@example.com", -++ password="password", ca_cert="auth_serv/ca.pem", -++ phase2="auth=MSCHAPV2", pac_file="blob://teap_pac") -+ erp_test(dev[0], hapd, eap="PSK", identity="erp-psk@example.com", -+ password_hex="0123456789abcdef0123456789abcdef") -+ if "PWD" in eap_methods: -+@@ -640,7 +642,7 @@ def test_erp_local_errors(dev, apdev): -+ dev[0].request("REMOVE_NETWORK all") -+ dev[0].wait_disconnected() -+ -+- for count in range(1, 6): -++ for count in range(1, 4): -+ dev[0].request("ERP_FLUSH") -+ with fail_test(dev[0], count, "hmac_sha256_kdf;eap_peer_erp_init"): -+ 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"): -++ 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") -+--- 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 -+ eap_connect(dev[0], hapd, "PAX", "pax.user@example.com", -+ password_hex="0123456789abcdef0123456789abcdef", -+ bssid=apdev[0]['bssid']) -+- for i in range(1, 11): -++ for i in range(1, 10): -+ 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 -+ state = dev[0].request('GET_ALLOC_FAIL') -+ if state.startswith('0:'): -+ break -+- time.sleep(0.05) -++ time.sleep(0.10) -+ -+ def test_pmksa_cache_ctrl(dev, apdev): -+ """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): -+ 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] -++ if tls.startswith("mbed TLS"): -++ # secp224k1 and secp224r1 (26) have prime p = 1 mod 4, and mbedtls -++ # does not have code to derive y from compressed format for those curves -++ sae_groups = [19, 25, 20, 21, 1, 2, 5, 14, 15, 16, 22, 23, 24] -++ sae_groups += [27, 28, 29, 30] -+ heavy_groups = [14, 15, 16] -+ suitable_groups = [15, 16, 17, 18, 19, 20, 21] -+ groups = [str(g) for g in sae_groups] -+@@ -2188,6 +2193,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") -++ elif tls.startswith("mbed TLS"): -++ logger.info("Make sure Brainpool EC groups were enabled when compiling mbed TLS") -+ else: -+ raise HwsimSkip("Brainpool curve not supported") -+ start_sae_pwe_ap(apdev[0], group, 2) -+--- a/tests/hwsim/test_suite_b.py -++++ b/tests/hwsim/test_suite_b.py -+@@ -27,6 +27,8 @@ def check_suite_b_tls_lib(dev, dhe=False -+ return -+ if tls.startswith("wolfSSL"): -+ return -++ if tls.startswith("mbed TLS"): -++ return -+ if not tls.startswith("OpenSSL"): -+ raise HwsimSkip("TLS library not supported for Suite B: " + tls) -+ supported = False -+@@ -520,6 +522,7 @@ def test_suite_b_192_rsa_insufficient_dh -+ -+ dev[0].connect("test-suite-b", key_mgmt="WPA-EAP-SUITE-B-192", -+ ieee80211w="2", -++ openssl_ciphers="DHE-RSA-AES256-GCM-SHA384", -+ phase1="tls_suiteb=1", -+ eap="TLS", identity="tls user", -+ ca_cert="auth_serv/rsa3072-ca.pem", -+--- a/tests/hwsim/test_wpas_ctrl.py -++++ b/tests/hwsim/test_wpas_ctrl.py -+@@ -1842,7 +1842,7 @@ def _test_wpas_ctrl_oom(dev): -+ tls = dev[0].request("GET tls_library") -+ if not tls.startswith("internal"): -+ tests.append(('NFC_GET_HANDOVER_SEL NDEF P2P-CR-TAG', 'FAIL', -+- 4, 'wpas_ctrl_nfc_get_handover_sel_p2p')) -++ 3, 'wpas_ctrl_nfc_get_handover_sel_p2p')) -+ for cmd, exp, count, func in tests: -+ with alloc_fail(dev[0], count, func): -+ 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): -+ -+ def check_tls_tod(dev): -+ tls = dev.request("GET tls_library") -+- if not tls.startswith("OpenSSL") and not tls.startswith("internal"): -++ if tls.startswith("OpenSSL"): -++ return -++ elif tls.startswith("internal"): -++ return -++ elif tls.startswith("mbed TLS"): -++ return -++ else: -+ raise HwsimSkip("TLS TOD-TOFU/STRICT not supported with this TLS library: " + tls) -+ -+ def vht_supported(): -+--- /dev/null -++++ b/tests/test-crypto_module.c -+@@ -0,0 +1,16 @@ -++/* -++ * crypto module tests - test program -++ * Copyright (c) 2022, Glenn Strauss -++ * -++ * This software may be distributed under the terms of the BSD license. -++ * See README for more details. -++ */ -++ -++#include "utils/includes.h" -++#include "utils/module_tests.h" -++#include "crypto/crypto_module_tests.c" -++ -++int main(int argc, char *argv[]) -++{ -++ return crypto_module_tests(); -++} -+--- a/tests/test-https.c -++++ b/tests/test-https.c -+@@ -75,7 +75,7 @@ static int https_client(int s, const cha -+ struct tls_connection *conn; -+ struct wpabuf *in, *out, *appl; -+ int res = -1; -+- int need_more_data; -++ int need_more_data = 0; -+ -+ os_memset(&conf, 0, sizeof(conf)); -+ conf.event_cb = https_tls_event_cb; -+@@ -93,8 +93,12 @@ static int https_client(int s, const cha -+ -+ for (;;) { -+ appl = NULL; -++#ifdef CONFIG_TLS_INTERNAL_SERVER -+ out = tls_connection_handshake2(tls, conn, in, &appl, -+ &need_more_data); -++#else -++ out = tls_connection_handshake(tls, conn, in, &appl); -++#endif -+ wpabuf_free(in); -+ in = NULL; -+ if (out == NULL) { -+@@ -152,11 +156,15 @@ static int https_client(int s, const cha -+ -+ wpa_printf(MSG_INFO, "Reading HTTP response"); -+ for (;;) { -+- int need_more_data; -++ int need_more_data = 0; -+ in = https_recv(s); -+ if (in == NULL) -+ goto done; -++#ifdef CONFIG_TLS_INTERNAL_SERVER -+ out = tls_connection_decrypt2(tls, conn, in, &need_more_data); -++#else -++ out = tls_connection_decrypt(tls, conn, in); -++#endif -+ if (need_more_data) -+ wpa_printf(MSG_DEBUG, "HTTP: Need more data"); -+ wpabuf_free(in); -+--- a/tests/test-https_server.c -++++ b/tests/test-https_server.c -+@@ -67,10 +67,12 @@ static struct wpabuf * https_recv(int s, -+ } -+ -+ -++#ifdef CONFIG_TLS_INTERNAL_SERVER -+ static void https_tls_log_cb(void *ctx, const char *msg) -+ { -+ wpa_printf(MSG_DEBUG, "TLS: %s", msg); -+ } -++#endif -+ -+ -+ static int https_server(int s) -+@@ -79,7 +81,7 @@ static int https_server(int s) -+ void *tls; -+ struct tls_connection_params params; -+ struct tls_connection *conn; -+- struct wpabuf *in, *out, *appl; -++ struct wpabuf *in = NULL, *out = NULL, *appl = NULL; -+ int res = -1; -+ -+ os_memset(&conf, 0, sizeof(conf)); -+@@ -106,7 +108,9 @@ static int https_server(int s) -+ return -1; -+ } -+ -++#ifdef CONFIG_TLS_INTERNAL_SERVER -+ tls_connection_set_log_cb(conn, https_tls_log_cb, NULL); -++#endif -+ -+ for (;;) { -+ in = https_recv(s, 5000); -+@@ -147,12 +151,16 @@ static int https_server(int s) -+ -+ wpa_printf(MSG_INFO, "Reading HTTP request"); -+ for (;;) { -+- int need_more_data; -++ int need_more_data = 0; -+ -+ in = https_recv(s, 5000); -+ if (!in) -+ goto done; -++#ifdef CONFIG_TLS_INTERNAL_SERVER -+ out = tls_connection_decrypt2(tls, conn, in, &need_more_data); -++#else -++ out = tls_connection_decrypt(tls, conn, in); -++#endif -+ wpabuf_free(in); -+ in = NULL; -+ if (need_more_data) { -+--- a/wpa_supplicant/Makefile -++++ b/wpa_supplicant/Makefile -+@@ -1122,6 +1122,7 @@ CFLAGS += -DCONFIG_TLSV12 -+ endif -+ -+ ifeq ($(CONFIG_TLS), wolfssl) -++CFLAGS += -DCONFIG_TLS_WOLFSSL -+ ifdef TLS_FUNCS -+ CFLAGS += -DWOLFSSL_DER_LOAD -+ OBJS += ../src/crypto/tls_wolfssl.o -+@@ -1137,6 +1138,7 @@ LIBS_p += -lwolfssl -lm -+ endif -+ -+ ifeq ($(CONFIG_TLS), openssl) -++CFLAGS += -DCONFIG_TLS_OPENSSL -+ CFLAGS += -DCRYPTO_RSA_OAEP_SHA256 -+ ifdef TLS_FUNCS -+ CFLAGS += -DEAP_TLS_OPENSSL -+@@ -1164,6 +1166,7 @@ CFLAGS += -DTLS_DEFAULT_CIPHERS=\"$(CONF -+ endif -+ -+ ifeq ($(CONFIG_TLS), mbedtls) -++CFLAGS += -DCONFIG_TLS_MBEDTLS -+ ifndef CONFIG_CRYPTO -+ CONFIG_CRYPTO=mbedtls -+ endif -+@@ -1183,6 +1186,7 @@ endif -+ endif -+ -+ ifeq ($(CONFIG_TLS), gnutls) -++CFLAGS += -DCONFIG_TLS_GNUTLS -+ ifndef CONFIG_CRYPTO -+ # default to libgcrypt -+ CONFIG_CRYPTO=gnutls -+@@ -1213,6 +1217,7 @@ endif -+ endif -+ -+ ifeq ($(CONFIG_TLS), internal) -++CFLAGS += -DCONFIG_TLS_INTERNAL -+ ifndef CONFIG_CRYPTO -+ CONFIG_CRYPTO=internal -+ endif -+@@ -1293,6 +1298,7 @@ endif -+ endif -+ -+ ifeq ($(CONFIG_TLS), linux) -++CFLAGS += -DCONFIG_TLS_INTERNAL -+ OBJS += ../src/crypto/crypto_linux.o -+ OBJS_p += ../src/crypto/crypto_linux.o -+ ifdef TLS_FUNCS -diff --git a/package/network/services/hostapd/patches/150-add-NULL-checks-encountered-during-tests-hwsim.patch b/package/network/services/hostapd/patches/150-add-NULL-checks-encountered-during-tests-hwsim.patch -new file mode 100644 -index 0000000000..c8c3ff33f4 ---- /dev/null -+++ b/package/network/services/hostapd/patches/150-add-NULL-checks-encountered-during-tests-hwsim.patch -@@ -0,0 +1,45 @@ -+From 33afce36c54b0cad38643629ded10ff5d727f077 Mon Sep 17 00:00:00 2001 -+From: Glenn Strauss -+Date: Fri, 12 Aug 2022 05:34:47 -0400 -+Subject: [PATCH 5/7] add NULL checks (encountered during tests/hwsim) -+ -+sae_derive_commit_element_ecc NULL pwe_ecc check -+dpp_gen_keypair() NULL curve check -+ -+Signed-off-by: Glenn Strauss -+--- -+ src/common/dpp_crypto.c | 6 ++++++ -+ src/common/sae.c | 7 +++++++ -+ 2 files changed, 13 insertions(+) -+ -+--- a/src/common/dpp_crypto.c -++++ b/src/common/dpp_crypto.c -+@@ -269,6 +269,12 @@ int dpp_get_pubkey_hash(struct crypto_ec -+ -+ struct crypto_ec_key * dpp_gen_keypair(const struct dpp_curve_params *curve) -+ { -++ if (curve == NULL) { -++ wpa_printf(MSG_DEBUG, -++ "DPP: %s curve must be initialized", __func__); -++ return NULL; -++ } -++ -+ struct crypto_ec_key *key; -+ -+ wpa_printf(MSG_DEBUG, "DPP: Generating a keypair"); -+--- a/src/common/sae.c -++++ b/src/common/sae.c -+@@ -1278,6 +1278,13 @@ void sae_deinit_pt(struct sae_pt *pt) -+ static int sae_derive_commit_element_ecc(struct sae_data *sae, -+ struct crypto_bignum *mask) -+ { -++ if (sae->tmp->pwe_ecc == NULL) { -++ wpa_printf(MSG_DEBUG, -++ "SAE: %s sae->tmp->pwe_ecc must be initialized", -++ __func__); -++ return -1; -++ } -++ -+ /* COMMIT-ELEMENT = inverse(scalar-op(mask, PWE)) */ -+ if (!sae->tmp->own_commit_element_ecc) { -+ sae->tmp->own_commit_element_ecc = -diff --git a/package/network/services/hostapd/patches/160-dpp_pkex-EC-point-mul-w-value-prime.patch b/package/network/services/hostapd/patches/160-dpp_pkex-EC-point-mul-w-value-prime.patch -new file mode 100644 -index 0000000000..db4fcfe235 ---- /dev/null -+++ b/package/network/services/hostapd/patches/160-dpp_pkex-EC-point-mul-w-value-prime.patch -@@ -0,0 +1,26 @@ -+From 54211caa2e0e5163aefef390daf88a971367a702 Mon Sep 17 00:00:00 2001 -+From: Glenn Strauss -+Date: Tue, 4 Oct 2022 17:09:24 -0400 -+Subject: [PATCH 6/7] dpp_pkex: EC point mul w/ value < prime -+ -+crypto_ec_point_mul() with mbedtls requires point -+be multiplied by a multiplicand with value < prime -+ -+Signed-off-by: Glenn Strauss -+--- -+ src/common/dpp_crypto.c | 4 +++- -+ 1 file changed, 3 insertions(+), 1 deletion(-) -+ -+--- a/src/common/dpp_crypto.c -++++ b/src/common/dpp_crypto.c -+@@ -1588,7 +1588,9 @@ dpp_pkex_derive_Qr(const struct dpp_curv -+ Pr = crypto_ec_key_get_public_key(Pr_key); -+ Qr = crypto_ec_point_init(ec); -+ hash_bn = crypto_bignum_init_set(hash, curve->hash_len); -+- if (!Pr || !Qr || !hash_bn || crypto_ec_point_mul(ec, Pr, hash_bn, Qr)) -++ if (!Pr || !Qr || !hash_bn || -++ crypto_bignum_mod(hash_bn, crypto_ec_get_prime(ec), hash_bn) || -++ crypto_ec_point_mul(ec, Pr, hash_bn, Qr)) -+ goto fail; -+ -+ if (crypto_ec_point_is_at_infinity(ec, Qr)) { -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 -new file mode 100644 -index 0000000000..710a3c851e ---- /dev/null -+++ b/package/network/services/hostapd/patches/170-hostapd-update-cfs0-and-cfs1-for-160MHz.patch -@@ -0,0 +1,141 @@ -+From d4c4ef302f98fd6bce173b8636e7e350d8b44981 Mon Sep 17 00:00:00 2001 -+From: P Praneesh -+Date: Fri, 19 Mar 2021 12:17:27 +0530 -+Subject: [PATCH] hostapd: update cfs0 and cfs1 for 160MHz -+ -+As per standard Draft P802.11ax_D8.0,( Table 26-9—Setting -+of the VHT Channel Width and VHT NSS at an HE STA -+transmitting the OM Control subfield ), center frequency of -+160MHz should be published in HT information subset 2 of -+HT information when EXT NSS BW field is enabled. -+ -+If the supported number of NSS in 160MHz is at least max NSS -+support, then center_freq_seg0 indicates the center frequency of 80MHz and -+center_freq_seg1 indicates the center frequency of 160MHz. -+ -+If the supported number of NSS in 160MHz is less than max NSS -+support, then center_freq_seg0 indicates the center frequency of 80MHz and -+center_freq_seg1 is 0. The center frequency of 160MHz is published in HT -+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/common/hw_features_common.c | 1 + -+ src/common/ieee802_11_defs.h | 1 + -+ 5 files changed, 27 insertions(+) -+ -+--- a/hostapd/config_file.c -++++ b/hostapd/config_file.c -+@@ -1153,6 +1153,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; -++ if (os_strstr(capab, "[EXT-NSS-BW-SUPP]")) -++ conf->vht_capab |= VHT_CAP_EXTENDED_NSS_BW_SUPPORT; -+ return 0; -+ } -+ #endif /* CONFIG_IEEE80211AC */ -+--- a/src/ap/ieee802_11_ht.c -++++ b/src/ap/ieee802_11_ht.c -+@@ -82,7 +82,9 @@ u8 * hostapd_eid_ht_capabilities(struct -+ u8 * hostapd_eid_ht_operation(struct hostapd_data *hapd, u8 *eid) -+ { -+ struct ieee80211_ht_operation *oper; -++ le32 vht_capabilities_info; -+ u8 *pos = eid; -++ u8 chwidth; -+ -+ if (!hapd->iconf->ieee80211n || hapd->conf->disable_11n || -+ is_6ghz_op_class(hapd->iconf->op_class)) -+@@ -103,6 +105,13 @@ u8 * hostapd_eid_ht_operation(struct hos -+ oper->ht_param |= HT_INFO_HT_PARAM_SECONDARY_CHNL_BELOW | -+ HT_INFO_HT_PARAM_STA_CHNL_WIDTH; -+ -++ vht_capabilities_info = host_to_le32(hapd->iface->current_mode->vht_capab); -++ chwidth = hostapd_get_oper_chwidth(hapd->iconf); -++ if (vht_capabilities_info & VHT_CAP_EXTENDED_NSS_BW_SUPPORT -++ && ((chwidth == CHANWIDTH_160MHZ) || (chwidth == CHANWIDTH_80P80MHZ))) { -++ oper->operation_mode = host_to_le16(hapd->iconf->vht_oper_centr_freq_seg0_idx << 5); -++ } -++ -+ pos += sizeof(*oper); -+ -+ 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 -+ struct ieee80211_vht_capabilities *cap; -+ struct hostapd_hw_modes *mode = hapd->iface->current_mode; -+ u8 *pos = eid; -++ u8 chwidth; -+ -+ if (!mode || is_6ghz_op_class(hapd->iconf->op_class)) -+ return eid; -+@@ -62,6 +63,17 @@ u8 * hostapd_eid_vht_capabilities(struct -+ host_to_le32(nsts << VHT_CAP_BEAMFORMEE_STS_OFFSET); -+ } -+ -++ chwidth = hostapd_get_oper_chwidth(hapd->iconf); -++ if (((host_to_le32(mode->vht_capab)) & VHT_CAP_EXTENDED_NSS_BW_SUPPORT) -++ && ((chwidth == CHANWIDTH_160MHZ) || (chwidth == CHANWIDTH_80P80MHZ))) { -++ cap->vht_capabilities_info |= VHT_CAP_EXTENDED_NSS_BW_SUPPORT; -++ cap->vht_capabilities_info &= ~(host_to_le32(VHT_CAP_SUPP_CHAN_WIDTH_160_80PLUS80MHZ)); -++ cap->vht_capabilities_info &= ~(host_to_le32(VHT_CAP_SUPP_CHAN_WIDTH_160MHZ)); -++ cap->vht_capabilities_info &= ~(host_to_le32(VHT_CAP_SUPP_CHAN_WIDTH_MASK)); -++ } else { -++ cap->vht_capabilities_info &= ~VHT_CAP_EXTENDED_NSS_BW_SUPPORT_MASK; -++ } -++ -+ /* 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 -+ u8 * hostapd_eid_vht_operation(struct hostapd_data *hapd, u8 *eid) -+ { -+ struct ieee80211_vht_operation *oper; -++ le32 vht_capabilities_info; -+ 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 -+ oper->vht_op_info_chan_center_freq_seg1_idx = seg1; -+ -+ oper->vht_op_info_chwidth = oper_chwidth; -++ vht_capabilities_info = host_to_le32(hapd->iface->current_mode->vht_capab); -+ 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 -+ oper->vht_op_info_chan_center_freq_seg0_idx -= 8; -+ else -+ oper->vht_op_info_chan_center_freq_seg0_idx += 8; -++ -++ if (vht_capabilities_info & VHT_CAP_EXTENDED_NSS_BW_SUPPORT) -++ oper->vht_op_info_chan_center_freq_seg1_idx = 0; -+ } else if (oper_chwidth == CONF_OPER_CHWIDTH_80P80MHZ) { -+ /* -+ * 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 -+@@ -808,6 +808,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); -++ VHT_CAP_CHECK(VHT_CAP_EXTENDED_NSS_BW_SUPPORT); -+ -+ #undef VHT_CAP_CHECK -+ #undef VHT_CAP_CHECK_MAX -+--- a/src/common/ieee802_11_defs.h -++++ b/src/common/ieee802_11_defs.h -+@@ -1348,6 +1348,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)) -++#define VHT_CAP_EXTENDED_NSS_BW_SUPPORT ((u32) BIT(30)) -++#define VHT_CAP_EXTENDED_NSS_BW_SUPPORT_MASK ((u32) BIT(30) | BIT(31)) -+ -+ #define VHT_OPMODE_CHANNEL_WIDTH_MASK ((u8) BIT(0) | BIT(1)) -+ #define VHT_OPMODE_CHANNEL_RxNSS_MASK ((u8) BIT(4) | BIT(5) | \ -diff --git a/package/network/services/hostapd/patches/180-BSS-coloring-fix-CCA-with-multiple-BSS.patch b/package/network/services/hostapd/patches/180-BSS-coloring-fix-CCA-with-multiple-BSS.patch -new file mode 100644 -index 0000000000..7b0435a453 ---- /dev/null -+++ b/package/network/services/hostapd/patches/180-BSS-coloring-fix-CCA-with-multiple-BSS.patch -@@ -0,0 +1,103 @@ -+From: Felix Fietkau -+Date: Mon, 7 Aug 2023 21:55:57 +0200 -+Subject: [PATCH] BSS coloring: fix CCA with multiple BSS -+ -+Pass bss->ctx instead of drv->ctx in order to avoid multiple reports for -+the first bss. The first report would otherwise clear hapd->cca_color and -+subsequent reports would cause the iface bss color to be set to 0. -+In order to avoid any issues with cancellations, only overwrite the color -+based on hapd->cca_color if it was actually set. -+ -+Fixes: 33c4dd26cd11 ("BSS coloring: Handle the collision and CCA events coming from the kernel") -+Signed-off-by: Felix Fietkau -+--- -+ -+--- a/src/ap/drv_callbacks.c -++++ b/src/ap/drv_callbacks.c -+@@ -2260,7 +2260,8 @@ void wpa_supplicant_event(void *ctx, enu -+ case EVENT_CCA_NOTIFY: -+ wpa_printf(MSG_DEBUG, "CCA finished on on %s", -+ hapd->conf->iface); -+- hapd->iface->conf->he_op.he_bss_color = hapd->cca_color; -++ if (hapd->cca_color) -++ hapd->iface->conf->he_op.he_bss_color = hapd->cca_color; -+ hostapd_cleanup_cca_params(hapd); -+ break; -+ #endif /* CONFIG_IEEE80211AX */ -+--- a/src/drivers/driver_nl80211_event.c -++++ b/src/drivers/driver_nl80211_event.c -+@@ -3653,7 +3653,7 @@ static void nl80211_assoc_comeback(struc -+ -+ #ifdef CONFIG_IEEE80211AX -+ -+-static void nl80211_obss_color_collision(struct wpa_driver_nl80211_data *drv, -++static void nl80211_obss_color_collision(struct i802_bss *bss, -+ struct nlattr *tb[]) -+ { -+ union wpa_event_data data; -+@@ -3667,37 +3667,37 @@ static void nl80211_obss_color_collision -+ -+ wpa_printf(MSG_DEBUG, "nl80211: BSS color collision - bitmap %08llx", -+ (long long unsigned int) data.bss_color_collision.bitmap); -+- wpa_supplicant_event(drv->ctx, EVENT_BSS_COLOR_COLLISION, &data); -++ wpa_supplicant_event(bss->ctx, EVENT_BSS_COLOR_COLLISION, &data); -+ } -+ -+ -+ static void -+-nl80211_color_change_announcement_started(struct wpa_driver_nl80211_data *drv) -++nl80211_color_change_announcement_started(struct i802_bss *bss) -+ { -+ union wpa_event_data data = {}; -+ -+ wpa_printf(MSG_DEBUG, "nl80211: CCA started"); -+- wpa_supplicant_event(drv->ctx, EVENT_CCA_STARTED_NOTIFY, &data); -++ wpa_supplicant_event(bss->ctx, EVENT_CCA_STARTED_NOTIFY, &data); -+ } -+ -+ -+ static void -+-nl80211_color_change_announcement_aborted(struct wpa_driver_nl80211_data *drv) -++nl80211_color_change_announcement_aborted(struct i802_bss *bss) -+ { -+ union wpa_event_data data = {}; -+ -+ wpa_printf(MSG_DEBUG, "nl80211: CCA aborted"); -+- wpa_supplicant_event(drv->ctx, EVENT_CCA_ABORTED_NOTIFY, &data); -++ wpa_supplicant_event(bss->ctx, EVENT_CCA_ABORTED_NOTIFY, &data); -+ } -+ -+ -+ static void -+-nl80211_color_change_announcement_completed(struct wpa_driver_nl80211_data *drv) -++nl80211_color_change_announcement_completed(struct i802_bss *bss) -+ { -+ union wpa_event_data data = {}; -+ -+ wpa_printf(MSG_DEBUG, "nl80211: CCA completed"); -+- wpa_supplicant_event(drv->ctx, EVENT_CCA_NOTIFY, &data); -++ wpa_supplicant_event(bss->ctx, EVENT_CCA_NOTIFY, &data); -+ } -+ -+ #endif /* CONFIG_IEEE80211AX */ -+@@ -3957,16 +3957,16 @@ static void do_process_drv_event(struct -+ break; -+ #ifdef CONFIG_IEEE80211AX -+ case NL80211_CMD_OBSS_COLOR_COLLISION: -+- nl80211_obss_color_collision(drv, tb); -++ nl80211_obss_color_collision(bss, tb); -+ break; -+ case NL80211_CMD_COLOR_CHANGE_STARTED: -+- nl80211_color_change_announcement_started(drv); -++ nl80211_color_change_announcement_started(bss); -+ break; -+ case NL80211_CMD_COLOR_CHANGE_ABORTED: -+- nl80211_color_change_announcement_aborted(drv); -++ nl80211_color_change_announcement_aborted(bss); -+ break; -+ case NL80211_CMD_COLOR_CHANGE_COMPLETED: -+- nl80211_color_change_announcement_completed(drv); -++ nl80211_color_change_announcement_completed(bss); -+ break; -+ #endif /* CONFIG_IEEE80211AX */ -+ default: -diff --git a/package/network/services/hostapd/patches/200-multicall.patch b/package/network/services/hostapd/patches/200-multicall.patch -new file mode 100644 -index 0000000000..8ebbed0c32 ---- /dev/null -+++ b/package/network/services/hostapd/patches/200-multicall.patch -@@ -0,0 +1,355 @@ -+--- a/hostapd/Makefile -++++ b/hostapd/Makefile -+@@ -1,6 +1,7 @@ -+ ALL=hostapd hostapd_cli -+ CONFIG_FILE = .config -+ -++-include $(if $(MULTICALL), ../wpa_supplicant/.config) -+ include ../src/build.rules -+ -+ ifdef LIBS -+@@ -199,7 +200,8 @@ endif -+ -+ ifdef CONFIG_NO_VLAN -+ CFLAGS += -DCONFIG_NO_VLAN -+-else -++endif -++ifneq ($(findstring CONFIG_NO_VLAN,$(CFLAGS)), CONFIG_NO_VLAN) -+ OBJS += ../src/ap/vlan_init.o -+ OBJS += ../src/ap/vlan_ifconfig.o -+ OBJS += ../src/ap/vlan.o -+@@ -357,10 +359,14 @@ CFLAGS += -DCONFIG_MBO -+ OBJS += ../src/ap/mbo_ap.o -+ endif -+ -++ifndef MULTICALL -++CFLAGS += -DNO_SUPPLICANT -++endif -++ -+ include ../src/drivers/drivers.mak -+-OBJS += $(DRV_AP_OBJS) -+-CFLAGS += $(DRV_AP_CFLAGS) -+-LDFLAGS += $(DRV_AP_LDFLAGS) -++OBJS += $(sort $(DRV_AP_OBJS) $(if $(MULTICALL),$(DRV_WPA_OBJS))) -++CFLAGS += $(DRV_AP_CFLAGS) $(if $(MULTICALL),$(DRV_WPA_CFLAGS)) -++LDFLAGS += $(DRV_AP_LDFLAGS) $(if $(MULTICALL),$(DRV_WPA_LDFLAGS)) -+ LIBS += $(DRV_AP_LIBS) -+ -+ ifdef CONFIG_L2_PACKET -+@@ -1380,6 +1386,12 @@ install: $(addprefix $(DESTDIR)$(BINDIR) -+ _OBJS_VAR := OBJS -+ include ../src/objs.mk -+ -++hostapd_multi.a: $(BCHECK) $(OBJS) -++ $(Q)$(CC) -c -o hostapd_multi.o -Dmain=hostapd_main $(CFLAGS) main.c -++ @$(E) " CC " $< -++ @rm -f $@ -++ @$(AR) cr $@ hostapd_multi.o $(OBJS) -++ -+ hostapd: $(OBJS) -+ $(Q)$(CC) $(LDFLAGS) -o hostapd $(OBJS) $(LIBS) -+ @$(E) " LD " $@ -+@@ -1460,6 +1472,12 @@ include ../src/objs.mk -+ _OBJS_VAR := SOBJS -+ include ../src/objs.mk -+ -++dump_cflags: -++ @printf "%s " "$(CFLAGS)" -++ -++dump_ldflags: -++ @printf "%s " "$(LDFLAGS) $(LIBS) $(EXTRALIBS)" -++ -+ nt_password_hash: $(NOBJS) -+ $(Q)$(CC) $(LDFLAGS) -o nt_password_hash $(NOBJS) $(LIBS_n) -+ @$(E) " LD " $@ -+--- a/wpa_supplicant/Makefile -++++ b/wpa_supplicant/Makefile -+@@ -10,6 +10,7 @@ ALL += dbus/fi.w1.wpa_supplicant1.servic -+ EXTRA_TARGETS=dynamic_eap_methods -+ -+ CONFIG_FILE=.config -++-include $(if $(MULTICALL),../hostapd/.config) -+ include ../src/build.rules -+ -+ ifdef CONFIG_BUILD_PASN_SO -+@@ -382,7 +383,9 @@ endif -+ ifdef CONFIG_IBSS_RSN -+ NEED_RSN_AUTHENTICATOR=y -+ CFLAGS += -DCONFIG_IBSS_RSN -++ifndef MULTICALL -+ CFLAGS += -DCONFIG_NO_VLAN -++endif -+ OBJS += ibss_rsn.o -+ endif -+ -+@@ -924,6 +927,10 @@ ifdef CONFIG_DYNAMIC_EAP_METHODS -+ CFLAGS += -DCONFIG_DYNAMIC_EAP_METHODS -+ LIBS += -ldl -rdynamic -+ endif -++else -++ ifdef MULTICALL -++ OBJS += ../src/eap_common/eap_common.o -++ endif -+ endif -+ -+ ifdef CONFIG_AP -+@@ -931,9 +938,11 @@ NEED_EAP_COMMON=y -+ NEED_RSN_AUTHENTICATOR=y -+ CFLAGS += -DCONFIG_AP -+ OBJS += ap.o -++ifndef MULTICALL -+ CFLAGS += -DCONFIG_NO_RADIUS -+ CFLAGS += -DCONFIG_NO_ACCOUNTING -+ CFLAGS += -DCONFIG_NO_VLAN -++endif -+ OBJS += ../src/ap/hostapd.o -+ OBJS += ../src/ap/wpa_auth_glue.o -+ OBJS += ../src/ap/utils.o -+@@ -1022,6 +1031,12 @@ endif -+ ifdef CONFIG_HS20 -+ OBJS += ../src/ap/hs20.o -+ endif -++else -++ ifdef MULTICALL -++ OBJS += ../src/eap_server/eap_server.o -++ OBJS += ../src/eap_server/eap_server_identity.o -++ OBJS += ../src/eap_server/eap_server_methods.o -++ endif -+ endif -+ -+ ifdef CONFIG_MBO -+@@ -1030,7 +1045,9 @@ CFLAGS += -DCONFIG_MBO -+ endif -+ -+ ifdef NEED_RSN_AUTHENTICATOR -++ifndef MULTICALL -+ CFLAGS += -DCONFIG_NO_RADIUS -++endif -+ 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) -+ -+ _OBJS_VAR := OBJS -+ include ../src/objs.mk -++wpa_supplicant_multi.a: .config $(BCHECK) $(OBJS) $(EXTRA_progs) -++ $(Q)$(CC) -c -o wpa_supplicant_multi.o -Dmain=wpa_supplicant_main $(CFLAGS) main.c -++ @$(E) " CC " $< -++ @rm -f $@ -++ @$(AR) cr $@ wpa_supplicant_multi.o $(OBJS) -++ -+ 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) -+ $(Q)sed -e 's|\@BINDIR\@|$(BINDIR)|g' $< >$@ -+ @$(E) " sed" $< -+ -++dump_cflags: -++ @printf "%s " "$(CFLAGS)" -++ -++dump_ldflags: -++ @printf "%s " "$(LDFLAGS) $(LIBS) $(EXTRALIBS)" -++ -+ wpa_supplicant.exe: wpa_supplicant -+ mv -f $< $@ -+ wpa_cli.exe: wpa_cli -+--- a/src/drivers/driver.h -++++ b/src/drivers/driver.h -+@@ -6651,8 +6651,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 -+@@ -6664,7 +6664,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/ap/drv_callbacks.c -++++ b/src/ap/drv_callbacks.c -+@@ -1994,8 +1994,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; -+ #ifndef CONFIG_NO_STDOUT_DEBUG -+@@ -2272,7 +2272,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/wpa_supplicant/wpa_priv.c -++++ b/wpa_supplicant/wpa_priv.c -+@@ -1039,8 +1039,8 @@ static void wpa_priv_send_ft_response(st -+ } -+ -+ -+-void wpa_supplicant_event(void *ctx, enum wpa_event_type event, -+- union wpa_event_data *data) -++static void supplicant_event(void *ctx, enum wpa_event_type event, -++ union wpa_event_data *data) -+ { -+ struct wpa_priv_interface *iface = ctx; -+ -+@@ -1103,7 +1103,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_priv_global *global = ctx; -+@@ -1217,6 +1217,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; -+ wpa_priv_fd_workaround(); -+ -+ os_memset(&global, 0, sizeof(global)); -+--- a/wpa_supplicant/events.c -++++ b/wpa_supplicant/events.c -+@@ -5345,8 +5345,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; -+@@ -6264,7 +6264,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 -+@@ -7435,7 +7435,6 @@ struct wpa_interface * wpa_supplicant_ma -+ return NULL; -+ } -+ -+- -+ /** -+ * wpa_supplicant_match_existing - Match existing interfaces -+ * @global: Pointer to global data from wpa_supplicant_init() -+@@ -7470,6 +7469,11 @@ static int wpa_supplicant_match_existing -+ -+ #endif /* CONFIG_MATCH_IFACE */ -+ -++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); -+ -+ /** -+ * wpa_supplicant_add_iface - Add a new network interface -+@@ -7726,6 +7730,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 */ -++ wpa_supplicant_event = supplicant_event; -++ wpa_supplicant_event_global = supplicant_event_global; -+ -+ if (params->wpa_debug_file_path) -+ wpa_debug_open_file(params->wpa_debug_file_path); -+--- a/hostapd/main.c -++++ b/hostapd/main.c -+@@ -685,6 +685,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) -+@@ -778,6 +783,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/300-noscan.patch b/package/network/services/hostapd/patches/300-noscan.patch -new file mode 100644 -index 0000000000..1ea89043e8 ---- /dev/null -+++ b/package/network/services/hostapd/patches/300-noscan.patch -@@ -0,0 +1,58 @@ -+--- a/hostapd/config_file.c -++++ b/hostapd/config_file.c -+@@ -3448,6 +3448,10 @@ static int hostapd_config_fill(struct ho -+ if (bss->ocv && !bss->ieee80211w) -+ bss->ieee80211w = 1; -+ #endif /* CONFIG_OCV */ -++ } else if (os_strcmp(buf, "noscan") == 0) { -++ conf->noscan = atoi(pos); -++ } else if (os_strcmp(buf, "ht_coex") == 0) { -++ conf->no_ht_coex = !atoi(pos); -+ } else if (os_strcmp(buf, "ieee80211n") == 0) { -+ conf->ieee80211n = atoi(pos); -+ } else if (os_strcmp(buf, "ht_capab") == 0) { -+--- a/src/ap/ap_config.h -++++ b/src/ap/ap_config.h -+@@ -1072,6 +1072,8 @@ struct hostapd_config { -+ -+ int ht_op_mode_fixed; -+ u16 ht_capab; -++ int noscan; -++ int no_ht_coex; -+ int ieee80211n; -+ int secondary_channel; -+ int no_pri_sec_switch; -+--- a/src/ap/hw_features.c -++++ b/src/ap/hw_features.c -+@@ -517,7 +517,8 @@ static int ieee80211n_check_40mhz(struct -+ int ret; -+ -+ /* Check that HT40 is used and PRI / SEC switch is allowed */ -+- if (!iface->conf->secondary_channel || iface->conf->no_pri_sec_switch) -++ if (!iface->conf->secondary_channel || iface->conf->no_pri_sec_switch || -++ iface->conf->noscan) -+ return 0; -+ -+ hostapd_set_state(iface, HAPD_IFACE_HT_SCAN); -+--- a/src/ap/ieee802_11_ht.c -++++ b/src/ap/ieee802_11_ht.c -+@@ -239,6 +239,9 @@ void hostapd_2040_coex_action(struct hos -+ return; -+ } -+ -++ if (iface->conf->noscan || iface->conf->no_ht_coex) -++ return; -++ -+ if (len < IEEE80211_HDRLEN + 2 + sizeof(*bc_ie)) { -+ wpa_printf(MSG_DEBUG, -+ "Ignore too short 20/40 BSS Coexistence Management frame"); -+@@ -399,6 +402,9 @@ void ht40_intolerant_add(struct hostapd_ -+ if (iface->current_mode->mode != HOSTAPD_MODE_IEEE80211G) -+ return; -+ -++ if (iface->conf->noscan || iface->conf->no_ht_coex) -++ return; -++ -+ wpa_printf(MSG_INFO, "HT: Forty MHz Intolerant is set by STA " MACSTR -+ " in Association Request", MAC2STR(sta->addr)); -+ -diff --git a/package/network/services/hostapd/patches/301-mesh-noscan.patch b/package/network/services/hostapd/patches/301-mesh-noscan.patch -new file mode 100644 -index 0000000000..6b5416f0ea ---- /dev/null -+++ b/package/network/services/hostapd/patches/301-mesh-noscan.patch -@@ -0,0 +1,71 @@ -+--- a/wpa_supplicant/config.c -++++ b/wpa_supplicant/config.c -+@@ -2600,6 +2600,7 @@ static const struct parse_data ssid_fiel -+ #else /* CONFIG_MESH */ -+ { INT_RANGE(mode, 0, 4) }, -+ #endif /* CONFIG_MESH */ -++ { INT_RANGE(noscan, 0, 1) }, -+ { INT_RANGE(proactive_key_caching, 0, 1) }, -+ { INT_RANGE(disabled, 0, 2) }, -+ { STR(id_str) }, -+--- a/wpa_supplicant/config_file.c -++++ b/wpa_supplicant/config_file.c -+@@ -775,6 +775,7 @@ static void wpa_config_write_network(FIL -+ #endif /* IEEE8021X_EAPOL */ -+ INT(mode); -+ INT(no_auto_peer); -++ INT(noscan); -+ INT(mesh_fwding); -+ INT(frequency); -+ INT(enable_edmg); -+--- a/wpa_supplicant/mesh.c -++++ b/wpa_supplicant/mesh.c -+@@ -506,6 +506,8 @@ static int wpa_supplicant_mesh_init(stru -+ frequency); -+ goto out_free; -+ } -++ if (ssid->noscan) -++ conf->noscan = 1; -+ -+ if (ssid->mesh_basic_rates == NULL) { -+ /* -+--- a/wpa_supplicant/wpa_supplicant.c -++++ b/wpa_supplicant/wpa_supplicant.c -+@@ -2710,7 +2710,7 @@ static bool ibss_mesh_can_use_vht(struct -+ const struct wpa_ssid *ssid, -+ struct hostapd_hw_modes *mode) -+ { -+- if (mode->mode != HOSTAPD_MODE_IEEE80211A) -++ if (mode->mode != HOSTAPD_MODE_IEEE80211A && !(ssid->noscan)) -+ return false; -+ -+ if (!drv_supports_vht(wpa_s, ssid)) -+@@ -2783,7 +2783,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, 36, 44, 52, 60, 100, 108, 116, 124, 132, 149, 157, 165, 173, -+ 184, 192 -+ }; -+ int ht40 = -1; -+@@ -3033,7 +3033,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 dfs_enabled = wpa_s->conf->country[0] && (wpa_s->drv_flags & WPA_DRIVER_FLAGS_RADAR); -+--- 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 -new file mode 100644 -index 0000000000..a47546d38f ---- /dev/null -+++ b/package/network/services/hostapd/patches/310-rescan_immediately.patch -@@ -0,0 +1,11 @@ -+--- a/wpa_supplicant/wpa_supplicant.c -++++ b/wpa_supplicant/wpa_supplicant.c -+@@ -5740,7 +5740,7 @@ wpa_supplicant_alloc(struct wpa_supplica -+ if (wpa_s == NULL) -+ return NULL; -+ wpa_s->scan_req = INITIAL_SCAN_REQ; -+- wpa_s->scan_interval = 5; -++ wpa_s->scan_interval = 1; -+ wpa_s->new_connection = 1; -+ wpa_s->parent = parent ? parent : wpa_s; -+ wpa_s->p2pdev = wpa_s->parent; -diff --git a/package/network/services/hostapd/patches/320-optional_rfkill.patch b/package/network/services/hostapd/patches/320-optional_rfkill.patch -new file mode 100644 -index 0000000000..01537790e0 ---- /dev/null -+++ b/package/network/services/hostapd/patches/320-optional_rfkill.patch -@@ -0,0 +1,61 @@ -+--- a/src/drivers/drivers.mak -++++ b/src/drivers/drivers.mak -+@@ -54,7 +54,6 @@ NEED_SME=y -+ NEED_AP_MLME=y -+ NEED_NETLINK=y -+ NEED_LINUX_IOCTL=y -+-NEED_RFKILL=y -+ NEED_RADIOTAP=y -+ NEED_LIBNL=y -+ endif -+@@ -111,7 +110,6 @@ DRV_WPA_CFLAGS += -DCONFIG_DRIVER_WEXT -+ CONFIG_WIRELESS_EXTENSION=y -+ NEED_NETLINK=y -+ NEED_LINUX_IOCTL=y -+-NEED_RFKILL=y -+ endif -+ -+ ifdef CONFIG_DRIVER_NDIS -+@@ -137,7 +135,6 @@ endif -+ ifdef CONFIG_WIRELESS_EXTENSION -+ DRV_WPA_CFLAGS += -DCONFIG_WIRELESS_EXTENSION -+ DRV_WPA_OBJS += ../src/drivers/driver_wext.o -+-NEED_RFKILL=y -+ endif -+ -+ ifdef NEED_NETLINK -+@@ -146,6 +143,7 @@ endif -+ -+ ifdef NEED_RFKILL -+ DRV_OBJS += ../src/drivers/rfkill.o -++DRV_WPA_CFLAGS += -DCONFIG_RFKILL -+ endif -+ -+ ifdef NEED_RADIOTAP -+--- a/src/drivers/rfkill.h -++++ b/src/drivers/rfkill.h -+@@ -18,8 +18,24 @@ struct rfkill_config { -+ void (*unblocked_cb)(void *ctx); -+ }; -+ -++#ifdef CONFIG_RFKILL -+ struct rfkill_data * rfkill_init(struct rfkill_config *cfg); -+ void rfkill_deinit(struct rfkill_data *rfkill); -+ int rfkill_is_blocked(struct rfkill_data *rfkill); -++#else -++static inline struct rfkill_data * rfkill_init(struct rfkill_config *cfg) -++{ -++ return (void *) 1; -++} -++ -++static inline void rfkill_deinit(struct rfkill_data *rfkill) -++{ -++} -++ -++static inline int rfkill_is_blocked(struct rfkill_data *rfkill) -++{ -++ return 0; -++} -++#endif -+ -+ #endif /* RFKILL_H */ -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 -new file mode 100644 -index 0000000000..c11c957216 ---- /dev/null -+++ b/package/network/services/hostapd/patches/330-nl80211_fix_set_freq.patch -@@ -0,0 +1,11 @@ -+--- a/src/drivers/driver_nl80211.c -++++ b/src/drivers/driver_nl80211.c -+@@ -5407,7 +5407,7 @@ static int nl80211_set_channel(struct i8 -+ freq->he_enabled, freq->eht_enabled, freq->bandwidth, -+ freq->center_freq1, freq->center_freq2); -+ -+- msg = nl80211_drv_msg(drv, 0, set_chan ? NL80211_CMD_SET_CHANNEL : -++ msg = nl80211_bss_msg(bss, 0, set_chan ? NL80211_CMD_SET_CHANNEL : -+ NL80211_CMD_SET_WIPHY); -+ if (!msg || nl80211_put_freq_params(msg, freq) < 0) { -+ nlmsg_free(msg); -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 -new file mode 100644 -index 0000000000..8784452876 ---- /dev/null -+++ b/package/network/services/hostapd/patches/341-mesh-ctrl-iface-channel-switch.patch -@@ -0,0 +1,39 @@ -+--- a/wpa_supplicant/ap.c -++++ b/wpa_supplicant/ap.c -+@@ -1825,15 +1825,35 @@ int ap_switch_channel(struct wpa_supplic -+ -+ -+ #ifdef CONFIG_CTRL_IFACE -++ -++static int __ap_ctrl_iface_chanswitch(struct hostapd_iface *iface, -++ struct csa_settings *settings) -++{ -++#ifdef NEED_AP_MLME -++ if (!iface || !iface->bss[0]) -++ return 0; -++ -++ return hostapd_switch_channel(iface->bss[0], settings); -++#else -++ return -1; -++#endif -++} -++ -++ -+ int ap_ctrl_iface_chanswitch(struct wpa_supplicant *wpa_s, const char *pos) -+ { -+ struct csa_settings settings; -+ int ret = hostapd_parse_csa_settings(pos, &settings); -+ -++ 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; -+ -+- return ap_switch_channel(wpa_s, &settings); -++ 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 -new file mode 100644 -index 0000000000..647ca2cbf9 ---- /dev/null -+++ b/package/network/services/hostapd/patches/350-nl80211_del_beacon_bss.patch -@@ -0,0 +1,35 @@ -+--- a/src/drivers/driver_nl80211.c -++++ b/src/drivers/driver_nl80211.c -+@@ -3008,12 +3008,12 @@ static int wpa_driver_nl80211_del_beacon -+ return 0; -+ -+ wpa_printf(MSG_DEBUG, "nl80211: Remove beacon (ifindex=%d)", -+- drv->ifindex); -++ bss->ifindex); -+ link->beacon_set = 0; -+ link->freq = 0; -+ -+ nl80211_put_wiphy_data_ap(bss); -+- msg = nl80211_drv_msg(drv, 0, NL80211_CMD_DEL_BEACON); -++ msg = nl80211_bss_msg(bss, 0, NL80211_CMD_DEL_BEACON); -+ if (!msg) -+ return -ENOBUFS; -+ -+@@ -6100,7 +6100,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; -++ wpa_driver_nl80211_del_beacon_all(bss); -+ } -+ -+ -+@@ -8859,8 +8859,6 @@ static int wpa_driver_nl80211_if_remove( -+ } else { -+ wpa_printf(MSG_DEBUG, "nl80211: First BSS - reassign context"); -+ nl80211_teardown_ap(bss); -+- if (!bss->added_if && !drv->first_bss->next) -+- wpa_driver_nl80211_del_beacon_all(bss); -+ nl80211_destroy_bss(bss); -+ if (!bss->added_if) -+ i802_set_iface_flags(bss, 0); -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 -new file mode 100644 -index 0000000000..54a736fe91 ---- /dev/null -+++ b/package/network/services/hostapd/patches/380-disable_ctrl_iface_mib.patch -@@ -0,0 +1,239 @@ -+--- 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 -+@@ -3314,6 +3314,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) { -+@@ -3355,6 +3356,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/wpa_supplicant/Makefile -++++ b/wpa_supplicant/Makefile -+@@ -983,6 +983,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/ctrl_iface.c -++++ b/wpa_supplicant/ctrl_iface.c -+@@ -2326,7 +2326,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, -+@@ -11964,6 +11964,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) { -+@@ -11976,6 +11977,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); -+@@ -12464,6 +12466,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) { -+@@ -12472,12 +12475,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; -+--- 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) -+@@ -493,6 +493,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, -+@@ -884,12 +885,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 -+@@ -2834,6 +2834,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) -+ { -+@@ -3020,6 +3021,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 -+@@ -5328,6 +5328,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) \ -+@@ -5480,7 +5481,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 -+@@ -3834,6 +3834,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 -+@@ -3915,6 +3917,7 @@ int wpa_sm_get_mib(struct wpa_sm *sm, ch -+ -+ return (int) len; -+ } -++#endif -+ #endif /* CONFIG_CTRL_IFACE */ -+ -+ -+--- a/wpa_supplicant/ap.c -++++ b/wpa_supplicant/ap.c -+@@ -1499,7 +1499,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) -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 -new file mode 100644 -index 0000000000..e9083f6ecc ---- /dev/null -+++ b/package/network/services/hostapd/patches/381-hostapd_cli_UNKNOWN-COMMAND.patch -@@ -0,0 +1,11 @@ -+--- a/hostapd/hostapd_cli.c -++++ b/hostapd/hostapd_cli.c -+@@ -757,7 +757,7 @@ static int wpa_ctrl_command_sta(struct w -+ } -+ -+ buf[len] = '\0'; -+- if (memcmp(buf, "FAIL", 4) == 0) -++ if (memcmp(buf, "FAIL", 4) == 0 || memcmp(buf, "UNKNOWN COMMAND", 15) == 0) -+ return -1; -+ if (print) -+ printf("%s", buf); -diff --git a/package/network/services/hostapd/patches/390-wpa_ie_cap_workaround.patch b/package/network/services/hostapd/patches/390-wpa_ie_cap_workaround.patch -new file mode 100644 -index 0000000000..40c39ff29c ---- /dev/null -+++ b/package/network/services/hostapd/patches/390-wpa_ie_cap_workaround.patch -@@ -0,0 +1,56 @@ -+--- a/src/common/wpa_common.c -++++ b/src/common/wpa_common.c -+@@ -2719,6 +2719,31 @@ u32 wpa_akm_to_suite(int akm) -+ } -+ -+ -++static void wpa_fixup_wpa_ie_rsn(u8 *assoc_ie, const u8 *wpa_msg_ie, -++ size_t rsn_ie_len) -++{ -++ int pos, count; -++ -++ pos = sizeof(struct rsn_ie_hdr) + RSN_SELECTOR_LEN; -++ if (rsn_ie_len < pos + 2) -++ return; -++ -++ count = WPA_GET_LE16(wpa_msg_ie + pos); -++ pos += 2 + count * RSN_SELECTOR_LEN; -++ if (rsn_ie_len < pos + 2) -++ return; -++ -++ count = WPA_GET_LE16(wpa_msg_ie + pos); -++ pos += 2 + count * RSN_SELECTOR_LEN; -++ if (rsn_ie_len < pos + 2) -++ return; -++ -++ if (!assoc_ie[pos] && !assoc_ie[pos + 1] && -++ (wpa_msg_ie[pos] || wpa_msg_ie[pos + 1])) -++ memcpy(&assoc_ie[pos], &wpa_msg_ie[pos], 2); -++} -++ -++ -+ int wpa_compare_rsn_ie(int ft_initial_assoc, -+ const u8 *ie1, size_t ie1len, -+ const u8 *ie2, size_t ie2len) -+@@ -2726,8 +2751,19 @@ int wpa_compare_rsn_ie(int ft_initial_as -+ if (ie1 == NULL || ie2 == NULL) -+ return -1; -+ -+- if (ie1len == ie2len && os_memcmp(ie1, ie2, ie1len) == 0) -+- return 0; /* identical IEs */ -++ if (ie1len == ie2len) { -++ u8 *ie_tmp; -++ -++ if (os_memcmp(ie1, ie2, ie1len) == 0) -++ return 0; /* identical IEs */ -++ -++ ie_tmp = alloca(ie1len); -++ memcpy(ie_tmp, ie1, ie1len); -++ wpa_fixup_wpa_ie_rsn(ie_tmp, ie2, ie1len); -++ -++ if (os_memcmp(ie_tmp, ie2, ie1len) == 0) -++ return 0; /* only mismatch in RSN capabilties */ -++ } -+ -+ #ifdef CONFIG_IEEE80211R -+ if (ft_initial_assoc) { -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 -new file mode 100644 -index 0000000000..edcd985257 ---- /dev/null -+++ b/package/network/services/hostapd/patches/400-wps_single_auth_enc_type.patch -@@ -0,0 +1,23 @@ -+--- a/src/ap/wps_hostapd.c -++++ b/src/ap/wps_hostapd.c -+@@ -394,9 +394,8 @@ static int hapd_wps_reconfig_in_memory(s -+ bss->wpa_pairwise |= WPA_CIPHER_GCMP; -+ else -+ bss->wpa_pairwise |= WPA_CIPHER_CCMP; -+- } -+ #ifndef CONFIG_NO_TKIP -+- if (cred->encr_type & WPS_ENCR_TKIP) -++ } else if (cred->encr_type & WPS_ENCR_TKIP) -+ bss->wpa_pairwise |= WPA_CIPHER_TKIP; -+ #endif /* CONFIG_NO_TKIP */ -+ bss->rsn_pairwise = bss->wpa_pairwise; -+@@ -1181,8 +1180,7 @@ int hostapd_init_wps(struct hostapd_data -+ WPA_CIPHER_GCMP_256)) { -+ wps->encr_types |= WPS_ENCR_AES; -+ wps->encr_types_rsn |= WPS_ENCR_AES; -+- } -+- if (conf->rsn_pairwise & WPA_CIPHER_TKIP) { -++ } else if (conf->rsn_pairwise & WPA_CIPHER_TKIP) { -+ #ifdef CONFIG_NO_TKIP -+ wpa_printf(MSG_INFO, "WPS: TKIP not supported"); -+ goto fail; -diff --git a/package/network/services/hostapd/patches/410-limit_debug_messages.patch b/package/network/services/hostapd/patches/410-limit_debug_messages.patch -new file mode 100644 -index 0000000000..48a5589200 ---- /dev/null -+++ b/package/network/services/hostapd/patches/410-limit_debug_messages.patch -@@ -0,0 +1,210 @@ -+--- a/src/utils/wpa_debug.c -++++ b/src/utils/wpa_debug.c -+@@ -206,7 +206,7 @@ void wpa_debug_close_linux_tracing(void) -+ * -+ * Note: New line '\n' is added to the end of the text when printing to stdout. -+ */ -+-void wpa_printf(int level, const char *fmt, ...) -++void _wpa_printf(int level, const char *fmt, ...) -+ { -+ va_list ap; -+ -+@@ -255,7 +255,7 @@ void wpa_printf(int level, const char *f -+ } -+ -+ -+-static void _wpa_hexdump(int level, const char *title, const u8 *buf, -++void _wpa_hexdump(int level, const char *title, const u8 *buf, -+ size_t len, int show, int only_syslog) -+ { -+ size_t i; -+@@ -382,19 +382,7 @@ static void _wpa_hexdump(int level, cons -+ #endif /* CONFIG_ANDROID_LOG */ -+ } -+ -+-void wpa_hexdump(int level, const char *title, const void *buf, size_t len) -+-{ -+- _wpa_hexdump(level, title, buf, len, 1, 0); -+-} -+- -+- -+-void wpa_hexdump_key(int level, const char *title, const void *buf, size_t len) -+-{ -+- _wpa_hexdump(level, title, buf, len, wpa_debug_show_keys, 0); -+-} -+- -+- -+-static void _wpa_hexdump_ascii(int level, const char *title, const void *buf, -++void _wpa_hexdump_ascii(int level, const char *title, const void *buf, -+ size_t len, int show) -+ { -+ size_t i, llen; -+@@ -507,20 +495,6 @@ file_done: -+ } -+ -+ -+-void wpa_hexdump_ascii(int level, const char *title, const void *buf, -+- size_t len) -+-{ -+- _wpa_hexdump_ascii(level, title, buf, len, 1); -+-} -+- -+- -+-void wpa_hexdump_ascii_key(int level, const char *title, const void *buf, -+- size_t len) -+-{ -+- _wpa_hexdump_ascii(level, title, buf, len, wpa_debug_show_keys); -+-} -+- -+- -+ #ifdef CONFIG_DEBUG_FILE -+ static char *last_path = NULL; -+ #endif /* CONFIG_DEBUG_FILE */ -+@@ -644,7 +618,7 @@ void wpa_msg_register_ifname_cb(wpa_msg_ -+ } -+ -+ -+-void wpa_msg(void *ctx, int level, const char *fmt, ...) -++void _wpa_msg(void *ctx, int level, const char *fmt, ...) -+ { -+ va_list ap; -+ char *buf; -+@@ -682,7 +656,7 @@ void wpa_msg(void *ctx, int level, const -+ } -+ -+ -+-void wpa_msg_ctrl(void *ctx, int level, const char *fmt, ...) -++void _wpa_msg_ctrl(void *ctx, int level, const char *fmt, ...) -+ { -+ va_list ap; -+ char *buf; -+--- a/src/utils/wpa_debug.h -++++ b/src/utils/wpa_debug.h -+@@ -51,6 +51,17 @@ void wpa_debug_close_file(void); -+ void wpa_debug_setup_stdout(void); -+ void wpa_debug_stop_log(void); -+ -++/* internal */ -++void _wpa_hexdump(int level, const char *title, const u8 *buf, -++ size_t len, int show, int only_syslog); -++void _wpa_hexdump_ascii(int level, const char *title, const void *buf, -++ size_t len, int show); -++extern int wpa_debug_show_keys; -++ -++#ifndef CONFIG_MSG_MIN_PRIORITY -++#define CONFIG_MSG_MIN_PRIORITY 0 -++#endif -++ -+ /** -+ * wpa_debug_printf_timestamp - Print timestamp for debug output -+ * -+@@ -71,9 +82,15 @@ void wpa_debug_print_timestamp(void); -+ * -+ * Note: New line '\n' is added to the end of the text when printing to stdout. -+ */ -+-void wpa_printf(int level, const char *fmt, ...) -++void _wpa_printf(int level, const char *fmt, ...) -+ PRINTF_FORMAT(2, 3); -+ -++#define wpa_printf(level, ...) \ -++ do { \ -++ if (level >= CONFIG_MSG_MIN_PRIORITY) \ -++ _wpa_printf(level, __VA_ARGS__); \ -++ } while(0) -++ -+ /** -+ * wpa_hexdump - conditional hex dump -+ * @level: priority level (MSG_*) of the message -+@@ -85,7 +102,13 @@ PRINTF_FORMAT(2, 3); -+ * output may be directed to stdout, stderr, and/or syslog based on -+ * configuration. The contents of buf is printed out has hex dump. -+ */ -+-void wpa_hexdump(int level, const char *title, const void *buf, size_t len); -++static inline void wpa_hexdump(int level, const char *title, const void *buf, size_t len) -++{ -++ if (level < CONFIG_MSG_MIN_PRIORITY) -++ return; -++ -++ _wpa_hexdump(level, title, buf, len, 1, 1); -++} -+ -+ static inline void wpa_hexdump_buf(int level, const char *title, -+ const struct wpabuf *buf) -+@@ -107,7 +130,13 @@ static inline void wpa_hexdump_buf(int l -+ * like wpa_hexdump(), but by default, does not include secret keys (passwords, -+ * etc.) in debug output. -+ */ -+-void wpa_hexdump_key(int level, const char *title, const void *buf, size_t len); -++static inline void wpa_hexdump_key(int level, const char *title, const u8 *buf, size_t len) -++{ -++ if (level < CONFIG_MSG_MIN_PRIORITY) -++ return; -++ -++ _wpa_hexdump(level, title, buf, len, wpa_debug_show_keys, 1); -++} -+ -+ static inline void wpa_hexdump_buf_key(int level, const char *title, -+ const struct wpabuf *buf) -+@@ -129,8 +158,14 @@ static inline void wpa_hexdump_buf_key(i -+ * the hex numbers and ASCII characters (for printable range) are shown. 16 -+ * bytes per line will be shown. -+ */ -+-void wpa_hexdump_ascii(int level, const char *title, const void *buf, -+- size_t len); -++static inline void wpa_hexdump_ascii(int level, const char *title, -++ const u8 *buf, size_t len) -++{ -++ if (level < CONFIG_MSG_MIN_PRIORITY) -++ return; -++ -++ _wpa_hexdump_ascii(level, title, buf, len, 1); -++} -+ -+ /** -+ * wpa_hexdump_ascii_key - conditional hex dump, hide keys -+@@ -146,8 +181,14 @@ void wpa_hexdump_ascii(int level, const -+ * bytes per line will be shown. This works like wpa_hexdump_ascii(), but by -+ * default, does not include secret keys (passwords, etc.) in debug output. -+ */ -+-void wpa_hexdump_ascii_key(int level, const char *title, const void *buf, -+- size_t len); -++static inline void wpa_hexdump_ascii_key(int level, const char *title, -++ const u8 *buf, size_t len) -++{ -++ if (level < CONFIG_MSG_MIN_PRIORITY) -++ return; -++ -++ _wpa_hexdump_ascii(level, title, buf, len, wpa_debug_show_keys); -++} -+ -+ /* -+ * wpa_dbg() behaves like wpa_msg(), but it can be removed from build to reduce -+@@ -184,7 +225,12 @@ void wpa_hexdump_ascii_key(int level, co -+ * -+ * Note: New line '\n' is added to the end of the text when printing to stdout. -+ */ -+-void wpa_msg(void *ctx, int level, const char *fmt, ...) PRINTF_FORMAT(3, 4); -++void _wpa_msg(void *ctx, int level, const char *fmt, ...) PRINTF_FORMAT(3, 4); -++#define wpa_msg(ctx, level, ...) \ -++ do { \ -++ if (level >= CONFIG_MSG_MIN_PRIORITY) \ -++ _wpa_msg(ctx, level, __VA_ARGS__); \ -++ } while(0) -+ -+ /** -+ * wpa_msg_ctrl - Conditional printf for ctrl_iface monitors -+@@ -198,8 +244,13 @@ void wpa_msg(void *ctx, int level, const -+ * attached ctrl_iface monitors. In other words, it can be used for frequent -+ * events that do not need to be sent to syslog. -+ */ -+-void wpa_msg_ctrl(void *ctx, int level, const char *fmt, ...) -++void _wpa_msg_ctrl(void *ctx, int level, const char *fmt, ...) -+ PRINTF_FORMAT(3, 4); -++#define wpa_msg_ctrl(ctx, level, ...) \ -++ do { \ -++ if (level >= CONFIG_MSG_MIN_PRIORITY) \ -++ _wpa_msg_ctrl(ctx, level, __VA_ARGS__); \ -++ } while(0) -+ -+ /** -+ * wpa_msg_global - Global printf for ctrl_iface monitors -diff --git a/package/network/services/hostapd/patches/420-indicate-features.patch b/package/network/services/hostapd/patches/420-indicate-features.patch -new file mode 100644 -index 0000000000..3b28b6e752 ---- /dev/null -+++ b/package/network/services/hostapd/patches/420-indicate-features.patch -@@ -0,0 +1,63 @@ -+--- 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; -+@@ -786,7 +786,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) { -+@@ -823,6 +823,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/430-hostapd_cli_ifdef.patch b/package/network/services/hostapd/patches/430-hostapd_cli_ifdef.patch -new file mode 100644 -index 0000000000..a21f0bf7ce ---- /dev/null -+++ b/package/network/services/hostapd/patches/430-hostapd_cli_ifdef.patch -@@ -0,0 +1,56 @@ -+--- 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, -+@@ -1610,13 +1606,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, -+@@ -1641,7 +1634,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/431-wpa_cli_ifdef.patch b/package/network/services/hostapd/patches/431-wpa_cli_ifdef.patch -new file mode 100644 -index 0000000000..65c31c567f ---- /dev/null -+++ b/package/network/services/hostapd/patches/431-wpa_cli_ifdef.patch -@@ -0,0 +1,18 @@ -+--- 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/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 -new file mode 100644 -index 0000000000..e50c609d97 ---- /dev/null -+++ b/package/network/services/hostapd/patches/460-wpa_supplicant-add-new-config-params-to-be-used-with.patch -@@ -0,0 +1,189 @@ -+From 4bb69d15477e0f2b00e166845341dc933de47c58 Mon Sep 17 00:00:00 2001 -+From: Antonio Quartulli -+Date: Sun, 3 Jun 2012 18:22:56 +0200 -+Subject: [PATCHv2 601/602] wpa_supplicant: add new config params to be used -+ with the ibss join command -+ -+Signed-hostap: Antonio Quartulli -+--- -+ src/drivers/driver.h | 6 +++ -+ wpa_supplicant/config.c | 96 +++++++++++++++++++++++++++++++++++++++ -+ wpa_supplicant/config_ssid.h | 6 +++ -+ wpa_supplicant/wpa_supplicant.c | 23 +++++++--- -+ 4 files changed, 124 insertions(+), 7 deletions(-) -+ -+--- 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" -+@@ -953,6 +954,9 @@ struct wpa_driver_associate_params { -+ * responsible for selecting with which BSS to associate. */ -+ const u8 *bssid; -+ -++ unsigned char rates[WLAN_SUPP_RATES_MAX]; -++ int mcast_rate; -++ -+ /** -+ * bssid_hint - BSSID of a proposed AP -+ * -+--- a/wpa_supplicant/config.c -++++ b/wpa_supplicant/config.c -+@@ -18,6 +18,7 @@ -+ #include "eap_peer/eap.h" -+ #include "p2p/p2p.h" -+ #include "fst/fst.h" -++#include "ap/sta_info.h" -+ #include "config.h" -+ -+ -+@@ -2389,6 +2390,97 @@ static char * wpa_config_write_mac_value -+ #endif /* NO_CONFIG_WRITE */ -+ -+ -++static int wpa_config_parse_mcast_rate(const struct parse_data *data, -++ struct wpa_ssid *ssid, int line, -++ const char *value) -++{ -++ ssid->mcast_rate = (int)(strtod(value, NULL) * 10); -++ -++ return 0; -++} -++ -++#ifndef NO_CONFIG_WRITE -++static char * wpa_config_write_mcast_rate(const struct parse_data *data, -++ struct wpa_ssid *ssid) -++{ -++ char *value; -++ int res; -++ -++ if (!ssid->mcast_rate == 0) -++ return NULL; -++ -++ value = os_malloc(6); /* longest: 300.0 */ -++ if (value == NULL) -++ return NULL; -++ res = os_snprintf(value, 5, "%.1f", (double)ssid->mcast_rate / 10); -++ if (res < 0) { -++ os_free(value); -++ return NULL; -++ } -++ return value; -++} -++#endif /* NO_CONFIG_WRITE */ -++ -++static int wpa_config_parse_rates(const struct parse_data *data, -++ struct wpa_ssid *ssid, int line, -++ const char *value) -++{ -++ int i; -++ char *pos, *r, *sptr, *end; -++ double rate; -++ -++ pos = (char *)value; -++ r = strtok_r(pos, ",", &sptr); -++ i = 0; -++ while (pos && i < WLAN_SUPP_RATES_MAX) { -++ rate = 0.0; -++ if (r) -++ rate = strtod(r, &end); -++ ssid->rates[i] = rate * 2; -++ if (*end != '\0' || rate * 2 != ssid->rates[i]) -++ return 1; -++ -++ i++; -++ r = strtok_r(NULL, ",", &sptr); -++ } -++ -++ return 0; -++} -++ -++#ifndef NO_CONFIG_WRITE -++static char * wpa_config_write_rates(const struct parse_data *data, -++ struct wpa_ssid *ssid) -++{ -++ char *value, *pos; -++ int res, i; -++ -++ if (ssid->rates[0] <= 0) -++ return NULL; -++ -++ value = os_malloc(6 * WLAN_SUPP_RATES_MAX + 1); -++ if (value == NULL) -++ return NULL; -++ pos = value; -++ for (i = 0; i < WLAN_SUPP_RATES_MAX - 1; i++) { -++ res = os_snprintf(pos, 6, "%.1f,", (double)ssid->rates[i] / 2); -++ if (res < 0) { -++ os_free(value); -++ return NULL; -++ } -++ pos += res; -++ } -++ res = os_snprintf(pos, 6, "%.1f", -++ (double)ssid->rates[WLAN_SUPP_RATES_MAX - 1] / 2); -++ if (res < 0) { -++ os_free(value); -++ return NULL; -++ } -++ -++ value[6 * WLAN_SUPP_RATES_MAX] = '\0'; -++ return value; -++} -++#endif /* NO_CONFIG_WRITE */ -++ -+ /* Helper macros for network block parser */ -+ -+ #ifdef OFFSET -+@@ -2674,6 +2766,8 @@ static const struct parse_data ssid_fiel -+ { INT(ap_max_inactivity) }, -+ { INT(dtim_period) }, -+ { INT(beacon_int) }, -++ { FUNC(rates) }, -++ { FUNC(mcast_rate) }, -+ #ifdef CONFIG_MACSEC -+ { INT_RANGE(macsec_policy, 0, 1) }, -+ { 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 { -+ */ -+ void *parent_cred; -+ -++ unsigned char rates[WLAN_SUPP_RATES_MAX]; -++ double mcast_rate; -++ -+ #ifdef CONFIG_MACSEC -+ /** -+ * macsec_policy - Determines the policy for MACsec secure session -+--- a/wpa_supplicant/wpa_supplicant.c -++++ b/wpa_supplicant/wpa_supplicant.c -+@@ -4149,6 +4149,12 @@ static void wpas_start_assoc_cb(struct w -+ params.beacon_int = ssid->beacon_int; -+ else -+ params.beacon_int = wpa_s->conf->beacon_int; -++ int i = 0; -++ while (i < WLAN_SUPP_RATES_MAX) { -++ params.rates[i] = ssid->rates[i]; -++ i++; -++ } -++ params.mcast_rate = ssid->mcast_rate; -+ } -+ -+ if (bss && ssid->enable_edmg) -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 -new file mode 100644 -index 0000000000..be9e0507d6 ---- /dev/null -+++ b/package/network/services/hostapd/patches/463-add-mcast_rate-to-11s.patch -@@ -0,0 +1,68 @@ -+From: Sven Eckelmann -+Date: Thu, 11 May 2017 08:21:45 +0200 -+Subject: [PATCH] set mcast_rate in mesh mode -+ -+The wpa_supplicant code for IBSS allows to set the mcast rate. It is -+recommended to increase this value from 1 or 6 Mbit/s to something higher -+when using a mesh protocol on top which uses the multicast packet loss as -+indicator for the link quality. -+ -+This setting was unfortunately not applied for mesh mode. But it would be -+beneficial when wpa_supplicant would behave similar to IBSS mode and set -+this argument during mesh join like authsae already does. At least it is -+helpful for companies/projects which are currently switching to 802.11s -+(without mesh_fwding and with mesh_ttl set to 1) as replacement for IBSS -+because newer drivers seem to support 802.11s but not IBSS anymore. -+ -+Signed-off-by: Sven Eckelmann -+Tested-by: Simon Wunderlich -+ -+--- a/src/drivers/driver.h -++++ b/src/drivers/driver.h -+@@ -1827,6 +1827,7 @@ struct wpa_driver_mesh_join_params { -+ #define WPA_DRIVER_MESH_FLAG_AMPE 0x00000008 -+ unsigned int flags; -+ bool handle_dfs; -++ int mcast_rate; -+ }; -+ -+ struct wpa_driver_set_key_params { -+--- a/src/drivers/driver_nl80211.c -++++ b/src/drivers/driver_nl80211.c -+@@ -11626,6 +11626,18 @@ static int nl80211_put_mesh_id(struct nl -+ } -+ -+ -++static int nl80211_put_mcast_rate(struct nl_msg *msg, int mcast_rate) -++{ -++ if (mcast_rate > 0) { -++ wpa_printf(MSG_DEBUG, " * mcast_rate=%.1f", -++ (double)mcast_rate / 10); -++ return nla_put_u32(msg, NL80211_ATTR_MCAST_RATE, mcast_rate); -++ } -++ -++ return 0; -++} -++ -++ -+ static int nl80211_put_mesh_config(struct nl_msg *msg, -+ struct wpa_driver_mesh_bss_params *params) -+ { -+@@ -11687,6 +11699,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) || -++ nl80211_put_mcast_rate(msg, params->mcast_rate) || -+ nl80211_put_dtim_period(msg, params->dtim_period)) -+ goto fail; -+ -+--- a/wpa_supplicant/mesh.c -++++ b/wpa_supplicant/mesh.c -+@@ -632,6 +632,7 @@ int wpa_supplicant_join_mesh(struct wpa_ -+ -+ params->meshid = ssid->ssid; -+ params->meshid_len = ssid->ssid_len; -++ params->mcast_rate = ssid->mcast_rate; -+ ibss_mesh_setup_freq(wpa_s, ssid, ¶ms->freq); -+ wpa_s->mesh_ht_enabled = !!params->freq.ht_enabled; -+ wpa_s->mesh_vht_enabled = !!params->freq.vht_enabled; -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 -new file mode 100644 -index 0000000000..4d7d85f4ab ---- /dev/null -+++ b/package/network/services/hostapd/patches/464-fix-mesh-obss-check.patch -@@ -0,0 +1,13 @@ -+--- a/wpa_supplicant/wpa_supplicant.c -++++ b/wpa_supplicant/wpa_supplicant.c -+@@ -3040,6 +3040,10 @@ void ibss_mesh_setup_freq(struct wpa_sup -+ -+ freq->freq = ssid->frequency; -+ -++ if (ssid->fixed_freq) { -++ obss_scan = 0; -++ } -++ -+ if (ssid->mode == WPAS_MODE_IBSS && !ssid->fixed_freq) { -+ struct wpa_bss *bss = ibss_find_existing_bss(wpa_s, ssid); -+ -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 -new file mode 100644 -index 0000000000..7d3d94648e ---- /dev/null -+++ b/package/network/services/hostapd/patches/465-hostapd-config-support-random-BSS-color.patch -@@ -0,0 +1,24 @@ -+From c9304d3303d563ad6d2619f4e07864ed12f96889 Mon Sep 17 00:00:00 2001 -+From: David Bauer -+Date: Sat, 14 May 2022 21:41:03 +0200 -+Subject: [PATCH] hostapd: config: support random BSS color -+ -+Configure the HE BSS color to a random value in case the config defines -+a BSS color which exceeds the max BSS color (63). -+ -+Signed-off-by: David Bauer -+--- -+ hostapd/config_file.c | 2 ++ -+ 1 file changed, 2 insertions(+) -+ -+--- a/hostapd/config_file.c -++++ b/hostapd/config_file.c -+@@ -3500,6 +3500,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; -++ if (atoi(pos) > 63) -++ conf->he_op.he_bss_color = os_random() % 63 + 1; -+ } else if (os_strcmp(buf, "he_bss_color_partial") == 0) { -+ conf->he_op.he_bss_color_partial = atoi(pos); -+ } else if (os_strcmp(buf, "he_default_pe_duration") == 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 -new file mode 100644 -index 0000000000..79ab48c5c2 ---- /dev/null -+++ b/package/network/services/hostapd/patches/470-survey_data_fallback.patch -@@ -0,0 +1,30 @@ -+--- a/src/ap/acs.c -++++ b/src/ap/acs.c -+@@ -455,17 +455,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)) { -++ survey->nf = -95; -+ wpa_printf(MSG_INFO, -+ "ACS: Survey for freq %d is missing noise floor", -+ survey->freq); -+- return 0; -+ } -+ -+ if (!(survey->filled & SURVEY_HAS_CHAN_TIME)) { -++ survey->channel_time = 0; -+ wpa_printf(MSG_INFO, -+ "ACS: Survey for freq %d is missing channel time", -+ survey->freq); -+- return 0; -+ } -+ -+ if (!(survey->filled & SURVEY_HAS_CHAN_TIME_BUSY) && -+@@ -473,7 +473,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); -+- return 0; -+ } -+ -+ return 1; -diff --git a/package/network/services/hostapd/patches/500-lto-jobserver-support.patch b/package/network/services/hostapd/patches/500-lto-jobserver-support.patch -new file mode 100644 -index 0000000000..67312c5004 ---- /dev/null -+++ b/package/network/services/hostapd/patches/500-lto-jobserver-support.patch -@@ -0,0 +1,59 @@ -+--- a/hostapd/Makefile -++++ b/hostapd/Makefile -+@@ -1396,7 +1396,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 -+@@ -1407,7 +1407,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 -+@@ -2037,31 +2037,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/590-rrm-wnm-statistics.patch b/package/network/services/hostapd/patches/590-rrm-wnm-statistics.patch -new file mode 100644 -index 0000000000..0efa6db908 ---- /dev/null -+++ b/package/network/services/hostapd/patches/590-rrm-wnm-statistics.patch -@@ -0,0 +1,92 @@ -+--- a/src/ap/hostapd.h -++++ b/src/ap/hostapd.h -+@@ -163,6 +163,21 @@ struct hostapd_sae_commit_queue { -+ }; -+ -+ /** -++ * struct hostapd_openwrt_stats - OpenWrt custom STA/AP statistics -++ */ -++struct hostapd_openwrt_stats { -++ struct { -++ u64 neighbor_report_tx; -++ } rrm; -++ -++ struct { -++ u64 bss_transition_query_rx; -++ u64 bss_transition_request_tx; -++ u64 bss_transition_response_rx; -++ } wnm; -++}; -++ -++/** -+ * struct hostapd_data - hostapd per-BSS data structure -+ */ -+ struct hostapd_data { -+@@ -182,6 +197,9 @@ struct hostapd_data { -+ -+ struct hostapd_data *mld_first_bss; -+ -++ /* OpenWrt specific statistics */ -++ struct hostapd_openwrt_stats openwrt_stats; -++ -+ 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/wnm_ap.c -++++ b/src/ap/wnm_ap.c -+@@ -386,6 +386,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; -+ -++ hapd->openwrt_stats.wnm.bss_transition_request_tx++; -+ 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 -+ plen); -+ return 0; -+ case WNM_BSS_TRANS_MGMT_QUERY: -++ hapd->openwrt_stats.wnm.bss_transition_query_rx++; -+ ieee802_11_rx_bss_trans_mgmt_query(hapd, mgmt->sa, payload, -+ plen); -+ return 0; -+ case WNM_BSS_TRANS_MGMT_RESP: -++ hapd->openwrt_stats.wnm.bss_transition_response_rx++; -+ 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 -+ -+ pos = mgmt->u.action.u.bss_tm_req.variable; -+ -++ hapd->openwrt_stats.wnm.bss_transition_request_tx++; -+ 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 -+ return -1; -+ } -+ -++ hapd->openwrt_stats.wnm.bss_transition_request_tx++; -+ 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 -+ } -+ 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); -diff --git a/package/network/services/hostapd/patches/599-wpa_supplicant-fix-warnings.patch b/package/network/services/hostapd/patches/599-wpa_supplicant-fix-warnings.patch -new file mode 100644 -index 0000000000..e70dc61419 ---- /dev/null -+++ b/package/network/services/hostapd/patches/599-wpa_supplicant-fix-warnings.patch -@@ -0,0 +1,19 @@ -+--- 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/600-ubus_support.patch b/package/network/services/hostapd/patches/600-ubus_support.patch -new file mode 100644 -index 0000000000..5b2745a3be ---- /dev/null -+++ b/package/network/services/hostapd/patches/600-ubus_support.patch -@@ -0,0 +1,748 @@ -+--- a/hostapd/Makefile -++++ b/hostapd/Makefile -+@@ -166,6 +166,12 @@ OBJS += ../src/common/hw_features_common -+ -+ OBJS += ../src/eapol_auth/eapol_auth_sm.o -+ -++ifdef CONFIG_UBUS -++CFLAGS += -DUBUS_SUPPORT -++OBJS += ../src/utils/uloop.o -++OBJS += ../src/ap/ubus.o -++LIBS += -lubox -lubus -++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" -+ -+ #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); -+--- a/src/ap/hostapd.c -++++ b/src/ap/hostapd.c -+@@ -435,6 +435,7 @@ void hostapd_free_hapd_data(struct hosta -+ hapd->beacon_set_done = 0; -+ -+ wpa_printf(MSG_DEBUG, "%s(%s)", __func__, hapd->conf->iface); -++ hostapd_ubus_free_bss(hapd); -+ accounting_deinit(hapd); -+ hostapd_deinit_wpa(hapd); -+ vlan_deinit(hapd); -+@@ -1187,6 +1188,8 @@ static int hostapd_start_beacon(struct h -+ if (hapd->driver && hapd->driver->set_operstate) -+ hapd->driver->set_operstate(hapd->drv_priv, 1); -+ -++ hostapd_ubus_add_bss(hapd); -++ -+ return 0; -+ } -+ -+@@ -2275,6 +2278,7 @@ static int hostapd_setup_interface_compl -+ if (err) -+ goto fail; -+ -++ hostapd_ubus_add_iface(iface); -+ wpa_printf(MSG_DEBUG, "Completing interface initialization"); -+ if (iface->freq) { -+ #ifdef NEED_AP_MLME -+@@ -2494,6 +2498,7 @@ dfs_offload: -+ -+ fail: -+ wpa_printf(MSG_ERROR, "Interface initialization failed"); -++ hostapd_ubus_free_iface(iface); -+ -+ if (iface->is_no_ir) { -+ hostapd_set_state(iface, HAPD_IFACE_NO_IR); -+@@ -2984,6 +2989,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; -++ hostapd_ubus_free_iface(iface); -+ hostapd_interface_deinit(iface); -+ wpa_printf(MSG_DEBUG, "%s: driver=%p drv_priv=%p -> hapd_deinit", -+ __func__, driver, drv_priv); -+--- a/src/ap/ieee802_11.c -++++ b/src/ap/ieee802_11.c -+@@ -2778,7 +2778,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; -+- int res, reply_res; -++ int res, reply_res, ubus_resp; -+ u16 fc; -+ const u8 *challenge = NULL; -+ u8 resp_ies[2 + WLAN_AUTH_CHALLENGE_LEN]; -+@@ -2787,6 +2787,11 @@ static void handle_auth(struct hostapd_d -+ struct radius_sta rad_info; -+ const u8 *dst, *sa, *bssid; -+ bool mld_sta = false; -++ struct hostapd_ubus_request req = { -++ .type = HOSTAPD_UBUS_AUTH_REQ, -++ .mgmt_frame = mgmt, -++ .ssi_signal = rssi, -++ }; -+ -+ if (len < IEEE80211_HDRLEN + sizeof(mgmt->u.auth)) { -+ wpa_printf(MSG_INFO, "handle_auth - too short payload (len=%lu)", -+@@ -2978,6 +2983,13 @@ static void handle_auth(struct hostapd_d -+ resp = WLAN_STATUS_UNSPECIFIED_FAILURE; -+ goto fail; -+ } -++ ubus_resp = hostapd_ubus_handle_event(hapd, &req); -++ if (ubus_resp) { -++ wpa_printf(MSG_DEBUG, "Station " MACSTR " rejected by ubus handler.\n", -++ MAC2STR(mgmt->sa)); -++ resp = ubus_resp > 0 ? (u16) ubus_resp : WLAN_STATUS_UNSPECIFIED_FAILURE; -++ goto fail; -++ } -+ if (res == HOSTAPD_ACL_PENDING) -+ return; -+ -+@@ -5141,7 +5153,7 @@ static void handle_assoc(struct hostapd_ -+ int resp = WLAN_STATUS_SUCCESS; -+ u16 reply_res = WLAN_STATUS_UNSPECIFIED_FAILURE; -+ const u8 *pos; -+- int left, i; -++ int left, i, ubus_resp; -+ struct sta_info *sta; -+ u8 *tmp = NULL; -+ #ifdef CONFIG_FILS -+@@ -5354,6 +5366,11 @@ static void handle_assoc(struct hostapd_ -+ left = res; -+ } -+ #endif /* CONFIG_FILS */ -++ struct hostapd_ubus_request req = { -++ .type = HOSTAPD_UBUS_ASSOC_REQ, -++ .mgmt_frame = mgmt, -++ .ssi_signal = rssi, -++ }; -+ -+ /* followed by SSID and Supported rates; and HT capabilities if 802.11n -+ * is used */ -+@@ -5452,6 +5469,13 @@ static void handle_assoc(struct hostapd_ -+ } -+ #endif /* CONFIG_FILS */ -+ -++ ubus_resp = hostapd_ubus_handle_event(hapd, &req); -++ if (ubus_resp) { -++ wpa_printf(MSG_DEBUG, "Station " MACSTR " assoc rejected by ubus handler.\n", -++ MAC2STR(mgmt->sa)); -++ resp = ubus_resp > 0 ? (u16) ubus_resp : WLAN_STATUS_UNSPECIFIED_FAILURE; -++ goto fail; -++ } -+ fail: -+ -+ /* -+@@ -5733,6 +5757,7 @@ static void handle_disassoc(struct hosta -+ (unsigned long) len); -+ return; -+ } -++ hostapd_ubus_notify(hapd, "disassoc", mgmt->sa); -+ -+ sta = ap_get_sta(hapd, mgmt->sa); -+ if (!sta) { -+@@ -5764,6 +5789,8 @@ static void handle_deauth(struct hostapd -+ /* Clear the PTKSA cache entries for PASN */ -+ ptksa_cache_flush(hapd->ptksa, mgmt->sa, WPA_CIPHER_NONE); -+ -++ hostapd_ubus_notify(hapd, "deauth", mgmt->sa); -++ -+ 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 -+@@ -1036,6 +1036,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) -+@@ -1222,6 +1228,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/drv_callbacks.c -++++ b/src/ap/drv_callbacks.c -+@@ -145,6 +145,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) { -+ /* -+@@ -237,6 +241,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/sta_info.c -++++ b/src/ap/sta_info.c -+@@ -471,6 +471,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"); -++ hostapd_ubus_notify(hapd, "local-deauth", sta->addr); -+ ap_free_sta(hapd, sta); -+ return; -+ } -+@@ -626,6 +627,7 @@ skip_poll: -+ mlme_deauthenticate_indication( -+ hapd, sta, -+ WLAN_REASON_PREV_AUTH_NOT_VALID); -++ hostapd_ubus_notify(hapd, "inactive-deauth", sta->addr); -+ ap_free_sta(hapd, sta); -+ break; -+ } -+@@ -1344,15 +1346,28 @@ void ap_sta_set_authorized(struct hostap -+ sta->addr, authorized, dev_addr); -+ -+ if (authorized) { -++ static const char * const auth_algs[] = { -++ [WLAN_AUTH_OPEN] = "open", -++ [WLAN_AUTH_SHARED_KEY] = "shared", -++ [WLAN_AUTH_FT] = "ft", -++ [WLAN_AUTH_SAE] = "sae", -++ [WLAN_AUTH_FILS_SK] = "fils-sk", -++ [WLAN_AUTH_FILS_SK_PFS] = "fils-sk-pfs", -++ [WLAN_AUTH_FILS_PK] = "fils-pk", -++ [WLAN_AUTH_PASN] = "pasn", -++ }; -++ const char *auth_alg = NULL; -+ const u8 *dpp_pkhash; -+ const char *keyid; -+ char dpp_pkhash_buf[100]; -+ char keyid_buf[100]; -+ char ip_addr[100]; -++ char alg_buf[100]; -+ -+ dpp_pkhash_buf[0] = '\0'; -+ keyid_buf[0] = '\0'; -+ ip_addr[0] = '\0'; -++ alg_buf[0] = '\0'; -+ #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 -+@@ -7566,6 +7566,8 @@ struct wpa_supplicant * wpa_supplicant_a -+ } -+ #endif /* CONFIG_P2P */ -+ -++ wpas_ubus_add_bss(wpa_s); -++ -+ return wpa_s; -+ } -+ -+@@ -7592,6 +7594,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) { -+@@ -7938,8 +7942,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; -+ }; -+ -+ -+@@ -650,6 +653,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; -+ -+--- 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/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); -+ } -+ -+ -+@@ -352,6 +355,9 @@ void hostapd_handle_radio_measurement(st -+ mgmt->u.action.u.rrm.action, MAC2STR(mgmt->sa)); -+ -+ 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 @@ -+ static int vlan_if_add(struct hostapd_data *hapd, struct hostapd_vlan *vlan, -+ int existsok) -+ { -++ bool vlan_exists = iface_exists(vlan->ifname); -+ int ret; -+ #ifdef CONFIG_WEP -+ int i; -+@@ -36,7 +37,7 @@ static int vlan_if_add(struct hostapd_da -+ } -+ #endif /* CONFIG_WEP */ -+ -+- if (!iface_exists(vlan->ifname)) -++ if (!vlan_exists) -+ ret = hostapd_vlan_if_add(hapd, vlan->ifname); -+ else if (!existsok) -+ return -1; -+@@ -51,6 +52,9 @@ static int vlan_if_add(struct hostapd_da -+ if (hapd->wpa_auth) -+ ret = wpa_auth_ensure_group(hapd->wpa_auth, vlan->vlan_id); -+ -++ if (!ret && !vlan_exists) -++ hostapd_ubus_add_vlan(hapd, vlan); -++ -+ if (ret == 0) -+ return ret; -+ -+@@ -77,6 +81,8 @@ int vlan_if_remove(struct hostapd_data * -+ "WPA deinitialization for VLAN %d failed (%d)", -+ vlan->vlan_id, ret); -+ -++ hostapd_ubus_remove_vlan(hapd, vlan); -++ -+ return hostapd_vlan_if_remove(hapd, vlan->ifname); -+ } -+ -+--- a/src/ap/dfs.c -++++ b/src/ap/dfs.c -+@@ -1211,6 +1211,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 -+ MAC2STR(addr), reason, hex ? " neighbor=" : "", hex); -+ os_free(hex); -+ -+- ieee802_11_send_bss_trans_mgmt_request(hapd, addr, dialog_token); -++ if (!hostapd_ubus_notify_bss_transition_query(hapd, addr, dialog_token, reason, pos, end - pos)) -++ ieee802_11_send_bss_trans_mgmt_request(hapd, addr, dialog_token); -+ } -+ -+ -+@@ -477,7 +478,7 @@ static void ieee802_11_rx_bss_trans_mgmt -+ size_t len) -+ { -+ u8 dialog_token, status_code, bss_termination_delay; -+- const u8 *pos, *end; -++ const u8 *pos, *end, *target_bssid = NULL; -+ int enabled = hapd->conf->bss_transition; -+ struct sta_info *sta; -+ -+@@ -524,6 +525,7 @@ static void ieee802_11_rx_bss_trans_mgmt -+ wpa_printf(MSG_DEBUG, "WNM: not enough room for Target BSSID field"); -+ return; -+ } -++ target_bssid = pos; -+ 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 -+ MAC2STR(addr), status_code, bss_termination_delay); -+ } -+ -++ hostapd_ubus_notify_bss_transition_response(hapd, sta->addr, dialog_token, -++ status_code, bss_termination_delay, -++ target_bssid, pos, end - pos); -++ -+ wpa_hexdump(MSG_DEBUG, "WNM: BSS Transition Candidate List Entries", -+ pos, end - pos); -+ } -+--- a/src/utils/eloop.c -++++ b/src/utils/eloop.c -+@@ -77,6 +77,9 @@ struct eloop_sock_table { -+ struct eloop_data { -+ int max_sock; -+ -++ eloop_timeout_poll_handler timeout_poll_cb; -++ eloop_poll_handler poll_cb; -++ -+ size_t count; /* sum of all table counts */ -+ #ifdef CONFIG_ELOOP_POLL -+ size_t max_pollfd_map; /* number of pollfds_map currently allocated */ -+@@ -1121,6 +1124,12 @@ void eloop_run(void) -+ os_reltime_sub(&timeout->time, &now, &tv); -+ else -+ tv.sec = tv.usec = 0; -++ } -++ -++ if (eloop.timeout_poll_cb && eloop.timeout_poll_cb(&tv, !!timeout)) -++ timeout = (void *)1; -++ -++ if (timeout) { -+ #if defined(CONFIG_ELOOP_POLL) || defined(CONFIG_ELOOP_EPOLL) -+ timeout_ms = tv.sec * 1000 + tv.usec / 1000; -+ #endif /* defined(CONFIG_ELOOP_POLL) || defined(CONFIG_ELOOP_EPOLL) */ -+@@ -1190,7 +1199,8 @@ void eloop_run(void) -+ eloop.exceptions.changed = 0; -+ -+ eloop_process_pending_signals(); -+- -++ if (eloop.poll_cb) -++ eloop.poll_cb(); -+ -+ /* check if some registered timeouts have occurred */ -+ timeout = dl_list_first(&eloop.timeout, struct eloop_timeout, -+@@ -1252,6 +1262,14 @@ out: -+ return; -+ } -+ -++int eloop_register_cb(eloop_poll_handler poll_cb, -++ eloop_timeout_poll_handler timeout_cb) -++{ -++ eloop.poll_cb = poll_cb; -++ eloop.timeout_poll_cb = timeout_cb; -++ -++ return 0; -++} -+ -+ void eloop_terminate(void) -+ { -+--- a/src/utils/eloop.h -++++ b/src/utils/eloop.h -+@@ -65,6 +65,9 @@ typedef void (*eloop_timeout_handler)(vo -+ */ -+ typedef void (*eloop_signal_handler)(int sig, void *signal_ctx); -+ -++typedef bool (*eloop_timeout_poll_handler)(struct os_reltime *tv, bool tv_set); -++typedef void (*eloop_poll_handler)(void); -++ -+ /** -+ * eloop_init() - Initialize global event loop data -+ * Returns: 0 on success, -1 on failure -+@@ -73,6 +76,9 @@ typedef void (*eloop_signal_handler)(int -+ */ -+ int eloop_init(void); -+ -++int eloop_register_cb(eloop_poll_handler poll_cb, -++ eloop_timeout_poll_handler timeout_cb); -++ -+ /** -+ * eloop_register_read_sock - Register handler for read events -+ * @sock: File descriptor number for the socket -+@@ -320,6 +326,8 @@ int eloop_register_signal_reconfig(eloop -+ */ -+ int eloop_sock_requeue(void); -+ -++void eloop_add_uloop(void); -++ -+ /** -+ * eloop_run - Start the event loop -+ * -+--- /dev/null -++++ b/src/utils/uloop.c -+@@ -0,0 +1,64 @@ -++#include -++#include "includes.h" -++#include "common.h" -++#include "eloop.h" -++ -++static void eloop_uloop_event_cb(int sock, void *eloop_ctx, void *sock_ctx) -++{ -++} -++ -++static void eloop_uloop_fd_cb(struct uloop_fd *fd, unsigned int events) -++{ -++ unsigned int changed = events ^ fd->flags; -++ -++ if (changed & ULOOP_READ) { -++ if (events & ULOOP_READ) -++ eloop_register_sock(fd->fd, EVENT_TYPE_READ, eloop_uloop_event_cb, fd, fd); -++ else -++ eloop_unregister_sock(fd->fd, EVENT_TYPE_READ); -++ } -++ -++ if (changed & ULOOP_WRITE) { -++ if (events & ULOOP_WRITE) -++ eloop_register_sock(fd->fd, EVENT_TYPE_WRITE, eloop_uloop_event_cb, fd, fd); -++ else -++ eloop_unregister_sock(fd->fd, EVENT_TYPE_WRITE); -++ } -++} -++ -++static bool uloop_timeout_poll_handler(struct os_reltime *tv, bool tv_set) -++{ -++ struct os_reltime tv_uloop; -++ int timeout_ms = uloop_get_next_timeout(); -++ -++ if (timeout_ms < 0) -++ return false; -++ -++ tv_uloop.sec = timeout_ms / 1000; -++ tv_uloop.usec = (timeout_ms % 1000) * 1000; -++ -++ if (!tv_set || os_reltime_before(&tv_uloop, tv)) { -++ *tv = tv_uloop; -++ return true; -++ } -++ -++ return false; -++} -++ -++static void uloop_poll_handler(void) -++{ -++ uloop_run_timeout(0); -++} -++ -++void eloop_add_uloop(void) -++{ -++ static bool init_done = false; -++ -++ if (!init_done) { -++ uloop_init(); -++ uloop_fd_set_cb = eloop_uloop_fd_cb; -++ init_done = true; -++ } -++ -++ eloop_register_cb(uloop_poll_handler, uloop_timeout_poll_handler); -++} -diff --git a/package/network/services/hostapd/patches/601-ucode_support.patch b/package/network/services/hostapd/patches/601-ucode_support.patch -new file mode 100644 -index 0000000000..e0bbf1337d ---- /dev/null -+++ b/package/network/services/hostapd/patches/601-ucode_support.patch -@@ -0,0 +1,333 @@ -+--- a/hostapd/Makefile -++++ b/hostapd/Makefile -+@@ -168,9 +168,21 @@ OBJS += ../src/eapol_auth/eapol_auth_sm. -+ -+ ifdef CONFIG_UBUS -+ CFLAGS += -DUBUS_SUPPORT -+-OBJS += ../src/utils/uloop.o -+ OBJS += ../src/ap/ubus.o -+-LIBS += -lubox -lubus -++LIBS += -lubus -++NEED_ULOOP:=y -++endif -++ -++ifdef CONFIG_UCODE -++CFLAGS += -DUCODE_SUPPORT -++OBJS += ../src/utils/ucode.o -++OBJS += ../src/ap/ucode.o -++NEED_ULOOP:=y -++endif -++ -++ifdef NEED_ULOOP -++OBJS += ../src/utils/uloop.o -++LIBS += -lubox -+ endif -+ -+ ifdef CONFIG_CODE_COVERAGE -+--- a/hostapd/main.c -++++ b/hostapd/main.c -+@@ -994,6 +994,7 @@ int main(int argc, char *argv[]) -+ } -+ -+ hostapd_global_ctrl_iface_init(&interfaces); -++ hostapd_ucode_init(&interfaces); -+ -+ if (hostapd_global_run(&interfaces, daemonize, pid_file)) { -+ wpa_printf(MSG_ERROR, "Failed to start eloop"); -+@@ -1003,6 +1004,7 @@ int main(int argc, char *argv[]) -+ ret = 0; -+ -+ out: -++ hostapd_ucode_free(); -+ 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" -+ -+ #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); -+--- a/src/ap/hostapd.c -++++ b/src/ap/hostapd.c -+@@ -252,6 +252,8 @@ int hostapd_reload_config(struct hostapd -+ struct hostapd_config *newconf, *oldconf; -+ size_t j; -+ -++ hostapd_ucode_reload_bss(hapd); -++ -+ 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 -+ hapd->beacon_set_done = 0; -+ -+ wpa_printf(MSG_DEBUG, "%s(%s)", __func__, hapd->conf->iface); -++ hostapd_ucode_free_bss(hapd); -+ hostapd_ubus_free_bss(hapd); -+ accounting_deinit(hapd); -+ hostapd_deinit_wpa(hapd); -+@@ -599,6 +602,7 @@ void hostapd_cleanup_iface_partial(struc -+ static void hostapd_cleanup_iface(struct hostapd_iface *iface) -+ { -+ wpa_printf(MSG_DEBUG, "%s(%p)", __func__, iface); -++ hostapd_ucode_free_iface(iface); -+ eloop_cancel_timeout(channel_list_update_timeout, iface, NULL); -+ eloop_cancel_timeout(hostapd_interface_setup_failure_handler, iface, -+ NULL); -+@@ -1189,6 +1193,7 @@ static int hostapd_start_beacon(struct h -+ hapd->driver->set_operstate(hapd->drv_priv, 1); -+ -+ hostapd_ubus_add_bss(hapd); -++ hostapd_ucode_add_bss(hapd); -+ -+ return 0; -+ } -+@@ -1211,8 +1216,7 @@ static int hostapd_start_beacon(struct h -+ * initialized. Most of the modules that are initialized here will be -+ * deinitialized in hostapd_cleanup(). -+ */ -+-static int hostapd_setup_bss(struct hostapd_data *hapd, int first, -+- bool start_beacon) -++int hostapd_setup_bss(struct hostapd_data *hapd, int first, bool start_beacon) -+ { -+ struct hostapd_bss_config *conf = hapd->conf; -+ u8 ssid[SSID_MAX_LEN + 1]; -+@@ -2698,7 +2702,7 @@ hostapd_alloc_bss_data(struct hostapd_if -+ } -+ -+ -+-static void hostapd_bss_deinit(struct hostapd_data *hapd) -++void hostapd_bss_deinit(struct hostapd_data *hapd) -+ { -+ if (!hapd) -+ return; -+--- 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) -+@@ -7567,6 +7568,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; -+ } -+@@ -7594,6 +7596,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 */ -+@@ -7904,6 +7907,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; -+ } -+@@ -7942,12 +7946,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; -+ } -+ -+@@ -7980,6 +7980,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; -+@@ -654,6 +655,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); -+ -+--- a/src/drivers/driver.h -++++ b/src/drivers/driver.h -+@@ -6426,6 +6426,7 @@ union wpa_event_data { -+ -+ /** -+ * struct ch_switch -++ * @count: Count until channel switch activates -+ * @freq: Frequency of new channel in MHz -+ * @ht_enabled: Whether this is an HT channel -+ * @ch_offset: Secondary channel offset -+@@ -6436,6 +6437,7 @@ union wpa_event_data { -+ * @punct_bitmap: Puncturing bitmap -+ */ -+ struct ch_switch { -++ int count; -+ int freq; -+ int ht_enabled; -+ 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 -+ struct nlattr *bw, struct nlattr *cf1, -+ struct nlattr *cf2, -+ struct nlattr *punct_bitmap, -++ struct nlattr *count, -+ int finished) -+ { -+ struct i802_bss *bss; -+@@ -1265,6 +1266,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; -+@@ -3848,6 +3851,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: -+@@ -3860,6 +3864,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 -+@@ -5381,6 +5381,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 -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 -new file mode 100644 -index 0000000000..a03fcc9f92 ---- /dev/null -+++ b/package/network/services/hostapd/patches/610-hostapd_cli_ujail_permission.patch -@@ -0,0 +1,33 @@ -+--- a/src/common/wpa_ctrl.c -++++ b/src/common/wpa_ctrl.c -+@@ -135,7 +135,7 @@ try_again: -+ return NULL; -+ } -+ tries++; -+-#ifdef ANDROID -++ -+ /* Set client socket file permissions so that bind() creates the client -+ * socket with these permissions and there is no need to try to change -+ * them with chmod() after bind() which would have potential issues with -+@@ -147,7 +147,7 @@ try_again: -+ * operations to allow the response to go through. Those are using the -+ * no-deference-symlinks version to avoid races. */ -+ fchmod(ctrl->s, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP); -+-#endif /* ANDROID */ -++ -+ if (bind(ctrl->s, (struct sockaddr *) &ctrl->local, -+ sizeof(ctrl->local)) < 0) { -+ if (errno == EADDRINUSE && tries < 2) { -+@@ -165,7 +165,11 @@ try_again: -+ return NULL; -+ } -+ -+-#ifdef ANDROID -++#ifndef ANDROID -++ /* Set group even if we do not have privileges to change owner */ -++ lchown(ctrl->local.sun_path, -1, 101); -++ lchown(ctrl->local.sun_path, 101, 101); -++#else -+ /* Set group even if we do not have privileges to change owner */ -+ lchown(ctrl->local.sun_path, -1, AID_WIFI); -+ lchown(ctrl->local.sun_path, AID_SYSTEM, AID_WIFI); -diff --git a/package/network/services/hostapd/patches/701-reload_config_inline.patch b/package/network/services/hostapd/patches/701-reload_config_inline.patch -new file mode 100644 -index 0000000000..44c8892bae ---- /dev/null -+++ b/package/network/services/hostapd/patches/701-reload_config_inline.patch -@@ -0,0 +1,33 @@ -+--- a/hostapd/config_file.c -++++ b/hostapd/config_file.c -+@@ -4810,7 +4810,12 @@ struct hostapd_config * hostapd_config_r -+ int errors = 0; -+ size_t i; -+ -+- f = fopen(fname, "r"); -++ if (!strncmp(fname, "data:", 5)) { -++ f = fmemopen((void *)(fname + 5), strlen(fname + 5), "r"); -++ fname = ""; -++ } else { -++ f = fopen(fname, "r"); -++ } -+ if (f == NULL) { -+ wpa_printf(MSG_ERROR, "Could not open configuration file '%s' " -+ "for reading.", fname); -+--- a/wpa_supplicant/config_file.c -++++ b/wpa_supplicant/config_file.c -+@@ -326,8 +326,13 @@ struct wpa_config * wpa_config_read(cons -+ while (cred_tail && cred_tail->next) -+ cred_tail = cred_tail->next; -+ -++ if (!strncmp(name, "data:", 5)) { -++ f = fmemopen((void *)(name + 5), strlen(name + 5), "r"); -++ name = ""; -++ } else { -++ f = fopen(name, "r"); -++ } -+ wpa_printf(MSG_DEBUG, "Reading configuration file '%s'", name); -+- f = fopen(name, "r"); -+ if (f == NULL) { -+ wpa_printf(MSG_ERROR, "Failed to open config file '%s', " -+ "error: %s", name, strerror(errno)); -diff --git a/package/network/services/hostapd/patches/710-vlan_no_bridge.patch b/package/network/services/hostapd/patches/710-vlan_no_bridge.patch -new file mode 100644 -index 0000000000..63d1b8a3b8 ---- /dev/null -+++ b/package/network/services/hostapd/patches/710-vlan_no_bridge.patch -@@ -0,0 +1,41 @@ -+--- a/src/ap/ap_config.h -++++ b/src/ap/ap_config.h -+@@ -121,6 +121,7 @@ struct hostapd_ssid { -+ #define DYNAMIC_VLAN_OPTIONAL 1 -+ #define DYNAMIC_VLAN_REQUIRED 2 -+ int dynamic_vlan; -++ int vlan_no_bridge; -+ #define DYNAMIC_VLAN_NAMING_WITHOUT_DEVICE 0 -+ #define DYNAMIC_VLAN_NAMING_WITH_DEVICE 1 -+ #define DYNAMIC_VLAN_NAMING_END 2 -+--- a/src/ap/vlan_full.c -++++ b/src/ap/vlan_full.c -+@@ -475,6 +475,9 @@ void vlan_newlink(const char *ifname, st -+ if (!vlan) -+ return; -+ -++ if (hapd->conf->ssid.vlan_no_bridge) -++ goto out; -++ -+ vlan->configured = 1; -+ -+ notempty = vlan->vlan_desc.notempty; -+@@ -506,6 +509,7 @@ void vlan_newlink(const char *ifname, st -+ ifname, br_name, tagged[i], hapd); -+ } -+ -++out: -+ ifconfig_up(ifname); -+ } -+ -+--- a/hostapd/config_file.c -++++ b/hostapd/config_file.c -+@@ -3351,6 +3351,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 -new file mode 100644 -index 0000000000..c0f2c31c44 ---- /dev/null -+++ b/package/network/services/hostapd/patches/711-wds_bridge_force.patch -@@ -0,0 +1,22 @@ -+--- a/hostapd/config_file.c -++++ b/hostapd/config_file.c -+@@ -2318,6 +2318,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)); -++ if (!bss->wds_bridge[0]) -++ 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, "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 -+ return -1; -+ if (hapd->conf->wds_bridge[0]) -+ bridge = hapd->conf->wds_bridge; -+- else if (hapd->conf->bridge[0]) -+- bridge = hapd->conf->bridge; -+ return hapd->driver->set_wds_sta(hapd->drv_priv, addr, aid, val, -+ bridge, ifname_wds); -+ } -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 -new file mode 100644 -index 0000000000..1aa4456a5f ---- /dev/null -+++ b/package/network/services/hostapd/patches/720-iface_max_num_sta.patch -@@ -0,0 +1,81 @@ -+--- a/hostapd/config_file.c -++++ b/hostapd/config_file.c -+@@ -2848,6 +2848,14 @@ static int hostapd_config_fill(struct ho -+ line, bss->max_num_sta, MAX_STA_COUNT); -+ return 1; -+ } -++ } else if (os_strcmp(buf, "iface_max_num_sta") == 0) { -++ conf->max_num_sta = atoi(pos); -++ if (conf->max_num_sta < 0 || -++ conf->max_num_sta > MAX_STA_COUNT) { -++ wpa_printf(MSG_ERROR, "Line %d: Invalid max_num_sta=%d; allowed range 0..%d", -++ line, conf->max_num_sta, MAX_STA_COUNT); -++ return 1; -++ } -+ } 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); -+ -+ void hostapd_switch_color(struct hostapd_data *hapd, u64 bitmap); -+ void hostapd_cleanup_cca_params(struct hostapd_data *hapd); -+--- a/src/ap/hostapd.c -++++ b/src/ap/hostapd.c -+@@ -244,6 +244,29 @@ static int hostapd_iface_conf_changed(st -+ return 0; -+ } -+ -++static inline int hostapd_iface_num_sta(struct hostapd_iface *iface) -++{ -++ int num_sta = 0; -++ int i; -++ -++ for (i = 0; i < iface->num_bss; i++) -++ num_sta += iface->bss[i]->num_sta; -++ -++ return num_sta; -++} -++ -++ -++int hostapd_check_max_sta(struct hostapd_data *hapd) -++{ -++ if (hapd->num_sta >= hapd->conf->max_num_sta) -++ return 1; -++ -++ if (hapd->iconf->max_num_sta && -++ hostapd_iface_num_sta(hapd->iface) >= hapd->iconf->max_num_sta) -++ return 1; -++ -++ return 0; -++} -+ -+ int hostapd_reload_config(struct hostapd_iface *iface) -+ { -+--- a/src/ap/beacon.c -++++ b/src/ap/beacon.c -+@@ -1252,7 +1252,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 -+@@ -1036,6 +1036,8 @@ struct hostapd_config { -+ unsigned int track_sta_max_num; -+ unsigned int track_sta_max_age; -+ -++ 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 -diff --git a/package/network/services/hostapd/patches/730-ft_iface.patch b/package/network/services/hostapd/patches/730-ft_iface.patch -new file mode 100644 -index 0000000000..0795ed15a1 ---- /dev/null -+++ b/package/network/services/hostapd/patches/730-ft_iface.patch -@@ -0,0 +1,38 @@ -+--- a/hostapd/config_file.c -++++ b/hostapd/config_file.c -+@@ -3007,6 +3007,8 @@ static int hostapd_config_fill(struct ho -+ wpa_printf(MSG_INFO, -+ "Line %d: Obsolete peerkey parameter ignored", line); -+ #ifdef CONFIG_IEEE80211R_AP -++ } else if (os_strcmp(buf, "ft_iface") == 0) { -++ os_strlcpy(bss->ft_iface, pos, sizeof(bss->ft_iface)); -+ } else if (os_strcmp(buf, "mobility_domain") == 0) { -+ if (os_strlen(pos) != 2 * MOBILITY_DOMAIN_ID_LEN || -+ hexstr2bin(pos, bss->mobility_domain, -+--- a/src/ap/ap_config.h -++++ b/src/ap/ap_config.h -+@@ -283,6 +283,7 @@ struct airtime_sta_weight { -+ struct hostapd_bss_config { -+ char iface[IFNAMSIZ + 1]; -+ char bridge[IFNAMSIZ + 1]; -++ char ft_iface[IFNAMSIZ + 1]; -+ char vlan_bridge[IFNAMSIZ + 1]; -+ char wds_bridge[IFNAMSIZ + 1]; -+ 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 -+ wpa_key_mgmt_ft(hapd->conf->wpa_key_mgmt)) { -+ const char *ft_iface; -+ -+- ft_iface = hapd->conf->bridge[0] ? hapd->conf->bridge : -+- hapd->conf->iface; -++ if (hapd->conf->ft_iface[0]) -++ ft_iface = hapd->conf->ft_iface; -++ else if (hapd->conf->bridge[0]) -++ ft_iface = hapd->conf->bridge; -++ else -++ ft_iface = hapd->conf->iface; -+ hapd->l2 = l2_packet_init(ft_iface, NULL, ETH_P_RRB, -+ hostapd_rrb_receive, hapd, 1); -+ if (!hapd->l2) { -diff --git a/package/network/services/hostapd/patches/740-snoop_iface.patch b/package/network/services/hostapd/patches/740-snoop_iface.patch -new file mode 100644 -index 0000000000..6b6cc0fad7 ---- /dev/null -+++ b/package/network/services/hostapd/patches/740-snoop_iface.patch -@@ -0,0 +1,66 @@ -+--- a/src/ap/ap_config.h -++++ b/src/ap/ap_config.h -+@@ -284,6 +284,7 @@ struct hostapd_bss_config { -+ char iface[IFNAMSIZ + 1]; -+ char bridge[IFNAMSIZ + 1]; -+ char ft_iface[IFNAMSIZ + 1]; -++ char snoop_iface[IFNAMSIZ + 1]; -+ char vlan_bridge[IFNAMSIZ + 1]; -+ char wds_bridge[IFNAMSIZ + 1]; -+ int bridge_hairpin; /* hairpin_mode on bridge members */ -+--- a/src/ap/x_snoop.c -++++ b/src/ap/x_snoop.c -+@@ -33,14 +33,16 @@ int x_snoop_init(struct hostapd_data *ha -+ -+ hapd->x_snoop_initialized = true; -+ -+- if (hostapd_drv_br_port_set_attr(hapd, DRV_BR_PORT_ATTR_HAIRPIN_MODE, -++ if (!conf->snoop_iface[0] && -++ hostapd_drv_br_port_set_attr(hapd, DRV_BR_PORT_ATTR_HAIRPIN_MODE, -+ 1)) { -+ wpa_printf(MSG_DEBUG, -+ "x_snoop: Failed to enable hairpin_mode on the bridge port"); -+ return -1; -+ } -+ -+- if (hostapd_drv_br_port_set_attr(hapd, DRV_BR_PORT_ATTR_PROXYARP, 1)) { -++ if (!conf->snoop_iface[0] && -++ hostapd_drv_br_port_set_attr(hapd, DRV_BR_PORT_ATTR_PROXYARP, 1)) { -+ wpa_printf(MSG_DEBUG, -+ "x_snoop: Failed to enable proxyarp on the bridge port"); -+ return -1; -+@@ -54,7 +56,8 @@ int x_snoop_init(struct hostapd_data *ha -+ } -+ -+ #ifdef CONFIG_IPV6 -+- if (hostapd_drv_br_set_net_param(hapd, DRV_BR_MULTICAST_SNOOPING, 1)) { -++ if (!conf->snoop_iface[0] && -++ hostapd_drv_br_set_net_param(hapd, DRV_BR_MULTICAST_SNOOPING, 1)) { -+ wpa_printf(MSG_DEBUG, -+ "x_snoop: Failed to enable multicast snooping on the bridge"); -+ return -1; -+@@ -73,8 +76,12 @@ x_snoop_get_l2_packet(struct hostapd_dat -+ { -+ struct hostapd_bss_config *conf = hapd->conf; -+ struct l2_packet_data *l2; -++ const char *ifname = conf->bridge; -+ -+- l2 = l2_packet_init(conf->bridge, NULL, ETH_P_ALL, handler, hapd, 1); -++ if (conf->snoop_iface[0]) -++ ifname = conf->snoop_iface; -++ -++ l2 = l2_packet_init(ifname, NULL, ETH_P_ALL, handler, hapd, 1); -+ if (l2 == NULL) { -+ wpa_printf(MSG_DEBUG, -+ "x_snoop: Failed to initialize L2 packet processing %s", -+--- 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) { -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 -new file mode 100644 -index 0000000000..97c32df704 ---- /dev/null -+++ b/package/network/services/hostapd/patches/750-qos_map_set_without_interworking.patch -@@ -0,0 +1,97 @@ -+--- a/hostapd/config_file.c -++++ b/hostapd/config_file.c -+@@ -1604,6 +1604,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) -+@@ -1645,8 +1647,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, -+@@ -4062,10 +4062,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 -+@@ -1486,6 +1486,7 @@ int hostapd_setup_bss(struct hostapd_dat -+ 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, -+@@ -1493,7 +1494,6 @@ int hostapd_setup_bss(struct hostapd_dat -+ 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/wpa_supplicant/events.c -++++ b/wpa_supplicant/events.c -+@@ -2683,8 +2683,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) -+ { -+@@ -2717,8 +2715,6 @@ static void interworking_process_assoc_r -+ } -+ } -+ -+-#endif /* CONFIG_INTERWORKING */ -+- -+ -+ static void wpa_supplicant_set_4addr_mode(struct wpa_supplicant *wpa_s) -+ { -+@@ -3098,10 +3094,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)) -+--- a/src/ap/ieee802_11_shared.c -++++ b/src/ap/ieee802_11_shared.c -+@@ -1116,13 +1116,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)); -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 -new file mode 100644 -index 0000000000..f5ebab70d1 ---- /dev/null -+++ b/package/network/services/hostapd/patches/751-qos_map_ignore_when_unsupported.patch -@@ -0,0 +1,12 @@ -+--- 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 -+ int hostapd_drv_set_qos_map(struct hostapd_data *hapd, -+ const u8 *qos_map_set, u8 qos_map_set_len) -+ { -+- if (!hapd->driver || !hapd->driver->set_qos_map || !hapd->drv_priv) -++ if (!hapd->driver || !hapd->driver->set_qos_map || !hapd->drv_priv || -++ !(hapd->iface->drv_flags & WPA_DRIVER_FLAGS_QOS_MAPPING)) -+ return 0; -+ return hapd->driver->set_qos_map(hapd->drv_priv, qos_map_set, -+ 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 -new file mode 100644 -index 0000000000..2c705a68cf ---- /dev/null -+++ b/package/network/services/hostapd/patches/760-dynamic_own_ip.patch -@@ -0,0 +1,109 @@ -+--- a/src/ap/ap_config.h -++++ b/src/ap/ap_config.h -+@@ -310,6 +310,7 @@ struct hostapd_bss_config { -+ unsigned int eap_sim_db_timeout; -+ int eap_server_erp; /* Whether ERP is enabled on internal EAP server */ -+ struct hostapd_ip_addr own_ip_addr; -++ int dynamic_own_ip_addr; -+ char *nas_identifier; -+ struct hostapd_radius_servers *radius; -+ int acct_interim_interval; -+--- a/src/radius/radius_client.c -++++ b/src/radius/radius_client.c -+@@ -163,6 +163,8 @@ struct radius_client_data { -+ */ -+ void *ctx; -+ -++ struct hostapd_ip_addr local_ip; -++ -+ /** -+ * conf - RADIUS client configuration (list of RADIUS servers to use) -+ */ -+@@ -720,6 +722,30 @@ static void radius_client_list_add(struc -+ -+ -+ /** -++ * radius_client_send - Get local address for the RADIUS auth socket -++ * @radius: RADIUS client context from radius_client_init() -++ * @addr: pointer to store the address -++ * -++ * This function returns the local address for the connection to the RADIUS -++ * auth server. It also opens the socket if it's not available yet. -++ */ -++int radius_client_get_local_addr(struct radius_client_data *radius, -++ struct hostapd_ip_addr *addr) -++{ -++ struct hostapd_radius_servers *conf = radius->conf; -++ -++ if (conf->auth_server && radius->auth_sock < 0) -++ radius_client_init_auth(radius); -++ -++ if (radius->auth_sock < 0) -++ return -1; -++ -++ memcpy(addr, &radius->local_ip, sizeof(*addr)); -++ -++ return 0; -++} -++ -++/** -+ * 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 -+ wpa_printf(MSG_DEBUG, "RADIUS local address: %s:%u", -+ inet_ntoa(claddr.sin_addr), -+ ntohs(claddr.sin_port)); -++ if (auth) { -++ radius->local_ip.af = AF_INET; -++ radius->local_ip.u.v4 = claddr.sin_addr; -++ } -+ } -+ break; -+ #ifdef CONFIG_IPV6 -+@@ -1249,6 +1279,10 @@ radius_change_server(struct radius_clien -+ inet_ntop(AF_INET6, &claddr6.sin6_addr, -+ abuf, sizeof(abuf)), -+ ntohs(claddr6.sin6_port)); -++ if (auth) { -++ radius->local_ip.af = AF_INET6; -++ radius->local_ip.u.v6 = claddr6.sin6_addr; -++ } -+ } -+ break; -+ } -+--- a/src/radius/radius_client.h -++++ b/src/radius/radius_client.h -+@@ -249,6 +249,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); -++int radius_client_get_local_addr(struct radius_client_data *radius, -++ struct hostapd_ip_addr * addr); -+ 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 -+@@ -2688,6 +2688,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 -new file mode 100644 -index 0000000000..cbb2a1be3c ---- /dev/null -+++ b/package/network/services/hostapd/patches/761-shared_das_port.patch -@@ -0,0 +1,298 @@ -+--- 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; -+--- a/src/ap/hostapd.c -++++ b/src/ap/hostapd.c -+@@ -1423,6 +1423,7 @@ int hostapd_setup_bss(struct hostapd_dat -+ -+ os_memset(&das_conf, 0, sizeof(das_conf)); -+ das_conf.port = conf->radius_das_port; -++ das_conf.nas_identifier = conf->nas_identifier; -+ das_conf.shared_secret = conf->radius_das_shared_secret; -+ das_conf.shared_secret_len = -+ conf->radius_das_shared_secret_len; -+--- a/src/radius/radius_das.c -++++ b/src/radius/radius_das.c -+@@ -12,13 +12,26 @@ -+ #include "utils/common.h" -+ #include "utils/eloop.h" -+ #include "utils/ip_addr.h" -++#include "utils/list.h" -+ #include "radius.h" -+ #include "radius_das.h" -+ -+ -+-struct radius_das_data { -++static struct dl_list das_ports = DL_LIST_HEAD_INIT(das_ports); -++ -++struct radius_das_port { -++ struct dl_list list; -++ struct dl_list das_data; -++ -++ int port; -+ int sock; -++}; -++ -++struct radius_das_data { -++ struct dl_list list; -++ struct radius_das_port *port; -+ u8 *shared_secret; -++ u8 *nas_identifier; -+ size_t shared_secret_len; -+ struct hostapd_ip_addr client_addr; -+ unsigned int time_window; -+@@ -378,56 +391,17 @@ fail: -+ } -+ -+ -+-static void radius_das_receive(int sock, void *eloop_ctx, void *sock_ctx) -++static void -++radius_das_receive_msg(struct radius_das_data *das, struct radius_msg *msg, -++ struct sockaddr *from, socklen_t fromlen, -++ char *abuf, int from_port) -+ { -+- struct radius_das_data *das = eloop_ctx; -+- u8 buf[1500]; -+- union { -+- struct sockaddr_storage ss; -+- struct sockaddr_in sin; -+-#ifdef CONFIG_IPV6 -+- struct sockaddr_in6 sin6; -+-#endif /* CONFIG_IPV6 */ -+- } from; -+- char abuf[50]; -+- int from_port = 0; -+- socklen_t fromlen; -+- int len; -+- struct radius_msg *msg, *reply = NULL; -++ struct radius_msg *reply = NULL; -+ struct radius_hdr *hdr; -+ struct wpabuf *rbuf; -++ struct os_time now; -+ u32 val; -+ int res; -+- struct os_time now; -+- -+- fromlen = sizeof(from); -+- len = recvfrom(sock, buf, sizeof(buf), 0, -+- (struct sockaddr *) &from.ss, &fromlen); -+- if (len < 0) { -+- wpa_printf(MSG_ERROR, "DAS: recvfrom: %s", strerror(errno)); -+- return; -+- } -+- -+- os_strlcpy(abuf, inet_ntoa(from.sin.sin_addr), sizeof(abuf)); -+- from_port = ntohs(from.sin.sin_port); -+- -+- wpa_printf(MSG_DEBUG, "DAS: Received %d bytes from %s:%d", -+- len, abuf, from_port); -+- if (das->client_addr.u.v4.s_addr && -+- das->client_addr.u.v4.s_addr != from.sin.sin_addr.s_addr) { -+- wpa_printf(MSG_DEBUG, "DAS: Drop message from unknown client"); -+- return; -+- } -+- -+- msg = radius_msg_parse(buf, len); -+- if (msg == NULL) { -+- wpa_printf(MSG_DEBUG, "DAS: Parsing incoming RADIUS packet " -+- "from %s:%d failed", abuf, from_port); -+- return; -+- } -+- -+- if (wpa_debug_level <= MSG_MSGDUMP) -+- radius_msg_dump(msg); -+ -+ if (radius_msg_verify_das_req(msg, das->shared_secret, -+ das->shared_secret_len, -+@@ -494,9 +468,8 @@ static void radius_das_receive(int sock, -+ radius_msg_dump(reply); -+ -+ rbuf = radius_msg_get_buf(reply); -+- res = sendto(das->sock, wpabuf_head(rbuf), -+- wpabuf_len(rbuf), 0, -+- (struct sockaddr *) &from.ss, fromlen); -++ res = sendto(das->port->sock, wpabuf_head(rbuf), -++ wpabuf_len(rbuf), 0, from, fromlen); -+ if (res < 0) { -+ wpa_printf(MSG_ERROR, "DAS: sendto(to %s:%d): %s", -+ abuf, from_port, strerror(errno)); -+@@ -508,6 +481,72 @@ fail: -+ radius_msg_free(reply); -+ } -+ -++static void radius_das_receive(int sock, void *eloop_ctx, void *sock_ctx) -++{ -++ struct radius_das_port *p = eloop_ctx; -++ struct radius_das_data *das; -++ u8 buf[1500]; -++ union { -++ struct sockaddr_storage ss; -++ struct sockaddr_in sin; -++#ifdef CONFIG_IPV6 -++ struct sockaddr_in6 sin6; -++#endif /* CONFIG_IPV6 */ -++ } from; -++ struct radius_msg *msg; -++ size_t nasid_len = 0; -++ u8 *nasid_buf = NULL; -++ char abuf[50]; -++ int from_port = 0; -++ socklen_t fromlen; -++ int found = 0; -++ int len; -++ -++ fromlen = sizeof(from); -++ len = recvfrom(sock, buf, sizeof(buf), 0, -++ (struct sockaddr *) &from.ss, &fromlen); -++ if (len < 0) { -++ wpa_printf(MSG_ERROR, "DAS: recvfrom: %s", strerror(errno)); -++ return; -++ } -++ -++ os_strlcpy(abuf, inet_ntoa(from.sin.sin_addr), sizeof(abuf)); -++ from_port = ntohs(from.sin.sin_port); -++ -++ msg = radius_msg_parse(buf, len); -++ if (msg == NULL) { -++ wpa_printf(MSG_DEBUG, "DAS: Parsing incoming RADIUS packet " -++ "from %s:%d failed", abuf, from_port); -++ return; -++ } -++ -++ wpa_printf(MSG_DEBUG, "DAS: Received %d bytes from %s:%d", -++ len, abuf, from_port); -++ -++ if (wpa_debug_level <= MSG_MSGDUMP) -++ radius_msg_dump(msg); -++ -++ radius_msg_get_attr_ptr(msg, RADIUS_ATTR_NAS_IDENTIFIER, -++ &nasid_buf, &nasid_len, NULL); -++ dl_list_for_each(das, &p->das_data, struct radius_das_data, list) { -++ if (das->client_addr.u.v4.s_addr && -++ das->client_addr.u.v4.s_addr != from.sin.sin_addr.s_addr) -++ continue; -++ -++ if (das->nas_identifier && nasid_buf && -++ (nasid_len != os_strlen(das->nas_identifier) || -++ os_memcmp(das->nas_identifier, nasid_buf, nasid_len) != 0)) -++ continue; -++ -++ found = 1; -++ radius_das_receive_msg(das, msg, (struct sockaddr *)&from.ss, -++ fromlen, abuf, from_port); -++ } -++ -++ if (!found) -++ wpa_printf(MSG_DEBUG, "DAS: Drop message from unknown client"); -++} -++ -+ -+ static int radius_das_open_socket(int port) -+ { -+@@ -533,6 +572,49 @@ static int radius_das_open_socket(int po -+ } -+ -+ -++static struct radius_das_port * -++radius_das_open_port(int port) -++{ -++ struct radius_das_port *p; -++ -++ dl_list_for_each(p, &das_ports, struct radius_das_port, list) { -++ if (p->port == port) -++ return p; -++ } -++ -++ p = os_zalloc(sizeof(*p)); -++ if (p == NULL) -++ return NULL; -++ -++ dl_list_init(&p->das_data); -++ p->port = port; -++ p->sock = radius_das_open_socket(port); -++ if (p->sock < 0) -++ goto free_port; -++ -++ if (eloop_register_read_sock(p->sock, radius_das_receive, p, NULL)) -++ goto close_port; -++ -++ dl_list_add(&das_ports, &p->list); -++ -++ return p; -++ -++close_port: -++ close(p->sock); -++free_port: -++ os_free(p); -++ -++ return NULL; -++} -++ -++static void radius_das_close_port(struct radius_das_port *p) -++{ -++ dl_list_del(&p->list); -++ eloop_unregister_read_sock(p->sock); -++ close(p->sock); -++ free(p); -++} -++ -+ struct radius_das_data * -+ radius_das_init(struct radius_das_conf *conf) -+ { -+@@ -553,6 +635,8 @@ radius_das_init(struct radius_das_conf * -+ das->ctx = conf->ctx; -+ das->disconnect = conf->disconnect; -+ das->coa = conf->coa; -++ if (conf->nas_identifier) -++ das->nas_identifier = os_strdup(conf->nas_identifier); -+ -+ os_memcpy(&das->client_addr, conf->client_addr, -+ sizeof(das->client_addr)); -+@@ -565,19 +649,15 @@ radius_das_init(struct radius_das_conf * -+ } -+ das->shared_secret_len = conf->shared_secret_len; -+ -+- das->sock = radius_das_open_socket(conf->port); -+- if (das->sock < 0) { -++ das->port = radius_das_open_port(conf->port); -++ if (!das->port) { -+ wpa_printf(MSG_ERROR, "Failed to open UDP socket for RADIUS " -+ "DAS"); -+ radius_das_deinit(das); -+ return NULL; -+ } -+ -+- if (eloop_register_read_sock(das->sock, radius_das_receive, das, NULL)) -+- { -+- radius_das_deinit(das); -+- return NULL; -+- } -++ dl_list_add(&das->port->das_data, &das->list); -+ -+ return das; -+ } -+@@ -588,11 +668,14 @@ void radius_das_deinit(struct radius_das -+ if (das == NULL) -+ return; -+ -+- if (das->sock >= 0) { -+- eloop_unregister_read_sock(das->sock); -+- close(das->sock); -++ if (das->port) { -++ dl_list_del(&das->list); -++ -++ if (dl_list_empty(&das->port->das_data)) -++ radius_das_close_port(das->port); -+ } -+ -++ os_free(das->nas_identifier); -+ os_free(das->shared_secret); -+ os_free(das); -+ } -diff --git a/package/network/services/hostapd/patches/770-radius_server.patch b/package/network/services/hostapd/patches/770-radius_server.patch -new file mode 100644 -index 0000000000..e4690c76b8 ---- /dev/null -+++ b/package/network/services/hostapd/patches/770-radius_server.patch -@@ -0,0 +1,154 @@ -+--- a/hostapd/Makefile -++++ b/hostapd/Makefile -+@@ -63,6 +63,10 @@ endif -+ OBJS += main.o -+ OBJS += config_file.o -+ -++ifdef CONFIG_RADIUS_SERVER -++OBJS += radius.o -++endif -++ -+ OBJS += ../src/ap/hostapd.o -+ OBJS += ../src/ap/wpa_auth_glue.o -+ OBJS += ../src/ap/drv_callbacks.o -+--- a/hostapd/main.c -++++ b/hostapd/main.c -+@@ -40,6 +40,7 @@ struct hapd_global { -+ -+ static struct hapd_global global; -+ -++extern int radius_main(int argc, char **argv); -+ -+ #ifndef CONFIG_NO_HOSTAPD_LOGGER -+ static void hostapd_logger_cb(void *ctx, const u8 *addr, unsigned int module, -+@@ -758,6 +759,11 @@ int main(int argc, char *argv[]) -+ if (os_program_init()) -+ return -1; -+ -++#ifdef RADIUS_SERVER -++ if (strstr(argv[0], "radius")) -++ return radius_main(argc, argv); -++#endif -++ -+ os_memset(&interfaces, 0, sizeof(interfaces)); -+ interfaces.reload_config = hostapd_reload_config; -+ interfaces.config_read_cb = hostapd_config_read; -+--- a/src/radius/radius_server.c -++++ b/src/radius/radius_server.c -+@@ -63,6 +63,12 @@ struct radius_server_counters { -+ u32 unknown_acct_types; -+ }; -+ -++struct radius_accept_attr { -++ u8 type; -++ u16 len; -++ void *data; -++}; -++ -+ /** -+ * struct radius_session - Internal RADIUS server data for a session -+ */ -+@@ -90,7 +96,7 @@ struct radius_session { -+ unsigned int macacl:1; -+ unsigned int t_c_filtering:1; -+ -+- struct hostapd_radius_attr *accept_attr; -++ struct radius_accept_attr *accept_attr; -+ -+ u32 t_c_timestamp; /* Last read T&C timestamp from user DB */ -+ }; -+@@ -394,6 +400,7 @@ static void radius_server_session_free(s -+ radius_msg_free(sess->last_reply); -+ os_free(sess->username); -+ os_free(sess->nas_ip); -++ os_free(sess->accept_attr); -+ os_free(sess); -+ data->num_sess--; -+ } -+@@ -554,6 +561,36 @@ radius_server_erp_find_key(struct radius -+ } -+ #endif /* CONFIG_ERP */ -+ -++static struct radius_accept_attr * -++radius_server_copy_attr(const struct hostapd_radius_attr *data) -++{ -++ const struct hostapd_radius_attr *attr; -++ struct radius_accept_attr *attr_new; -++ size_t data_size = 0; -++ void *data_buf; -++ int n_attr = 1; -++ -++ for (attr = data; attr; attr = attr->next) { -++ n_attr++; -++ data_size += wpabuf_len(attr->val); -++ } -++ -++ attr_new = os_zalloc(n_attr * sizeof(*attr) + data_size); -++ if (!attr_new) -++ return NULL; -++ -++ data_buf = &attr_new[n_attr]; -++ for (n_attr = 0, attr = data; attr; attr = attr->next) { -++ struct radius_accept_attr *cur = &attr_new[n_attr++]; -++ -++ cur->type = attr->type; -++ cur->len = wpabuf_len(attr->val); -++ cur->data = memcpy(data_buf, wpabuf_head(attr->val), cur->len); -++ data_buf += cur->len; -++ } -++ -++ return attr_new; -++} -+ -+ static struct radius_session * -+ radius_server_get_new_session(struct radius_server_data *data, -+@@ -607,7 +644,7 @@ radius_server_get_new_session(struct rad -+ eap_user_free(tmp); -+ return NULL; -+ } -+- sess->accept_attr = tmp->accept_attr; -++ sess->accept_attr = radius_server_copy_attr(tmp->accept_attr); -+ sess->macacl = tmp->macacl; -+ eap_user_free(tmp); -+ -+@@ -1118,11 +1155,10 @@ radius_server_encapsulate_eap(struct rad -+ } -+ -+ if (code == RADIUS_CODE_ACCESS_ACCEPT) { -+- struct hostapd_radius_attr *attr; -+- for (attr = sess->accept_attr; attr; attr = attr->next) { -+- if (!radius_msg_add_attr(msg, attr->type, -+- wpabuf_head(attr->val), -+- wpabuf_len(attr->val))) { -++ struct radius_accept_attr *attr; -++ for (attr = sess->accept_attr; attr->data; attr++) { -++ if (!radius_msg_add_attr(msg, attr->type, attr->data, -++ attr->len)) { -+ wpa_printf(MSG_ERROR, "Could not add RADIUS attribute"); -+ radius_msg_free(msg); -+ return NULL; -+@@ -1211,11 +1247,10 @@ radius_server_macacl(struct radius_serve -+ } -+ -+ if (code == RADIUS_CODE_ACCESS_ACCEPT) { -+- struct hostapd_radius_attr *attr; -+- for (attr = sess->accept_attr; attr; attr = attr->next) { -+- if (!radius_msg_add_attr(msg, attr->type, -+- wpabuf_head(attr->val), -+- wpabuf_len(attr->val))) { -++ struct radius_accept_attr *attr; -++ for (attr = sess->accept_attr; attr->data; attr++) { -++ if (!radius_msg_add_attr(msg, attr->type, attr->data, -++ attr->len)) { -+ wpa_printf(MSG_ERROR, "Could not add RADIUS attribute"); -+ radius_msg_free(msg); -+ return NULL; -+@@ -2512,7 +2547,7 @@ static int radius_server_get_eap_user(vo -+ ret = data->get_eap_user(data->conf_ctx, identity, identity_len, -+ phase2, user); -+ if (ret == 0 && user) { -+- sess->accept_attr = user->accept_attr; -++ sess->accept_attr = radius_server_copy_attr(user->accept_attr); -+ sess->remediation = user->remediation; -+ sess->macacl = user->macacl; -+ sess->t_c_timestamp = user->t_c_timestamp; -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 -new file mode 100644 -index 0000000000..51690def09 ---- /dev/null -+++ b/package/network/services/hostapd/patches/990-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 -+@@ -12640,7 +12640,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; -+@@ -12650,7 +12650,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/src/hostapd/radius.c b/package/network/services/hostapd/src/hostapd/radius.c -new file mode 100644 -index 0000000000..362a22c276 ---- /dev/null -+++ b/package/network/services/hostapd/src/hostapd/radius.c -@@ -0,0 +1,715 @@ -+#include "utils/includes.h" -+#include "utils/common.h" -+#include "utils/eloop.h" -+#include "crypto/crypto.h" -+#include "crypto/tls.h" -+ -+#include "ap/ap_config.h" -+#include "eap_server/eap.h" -+#include "radius/radius.h" -+#include "radius/radius_server.h" -+#include "eap_register.h" -+ -+#include -+#include -+#include -+#include -+#include -+ -+#include -+#include -+ -+#define VENDOR_ID_WISPR 14122 -+#define VENDOR_ATTR_SIZE 6 -+ -+struct radius_parse_attr_data { -+ unsigned int vendor; -+ u8 type; -+ int size; -+ char format; -+ const char *data; -+}; -+ -+struct radius_parse_attr_state { -+ struct hostapd_radius_attr *prev; -+ struct hostapd_radius_attr *attr; -+ struct wpabuf *buf; -+ void *attrdata; -+}; -+ -+struct radius_user_state { -+ struct avl_node node; -+ struct eap_user data; -+}; -+ -+struct radius_user_data { -+ struct kvlist users; -+ struct avl_tree user_state; -+ struct blob_attr *wildcard; -+}; -+ -+struct radius_state { -+ struct radius_server_data *radius; -+ struct eap_config eap; -+ -+ struct radius_user_data phase1, phase2; -+ const char *user_file; -+ time_t user_file_ts; -+ -+ int n_attrs; -+ struct hostapd_radius_attr *attrs; -+}; -+ -+struct radius_config { -+ struct tls_connection_params tls; -+ struct radius_server_conf radius; -+}; -+ -+enum { -+ USER_ATTR_PASSWORD, -+ USER_ATTR_HASH, -+ USER_ATTR_SALT, -+ USER_ATTR_METHODS, -+ USER_ATTR_RADIUS, -+ USER_ATTR_VLAN, -+ USER_ATTR_MAX_RATE_UP, -+ USER_ATTR_MAX_RATE_DOWN, -+ __USER_ATTR_MAX -+}; -+ -+static void radius_tls_event(void *ctx, enum tls_event ev, -+ union tls_event_data *data) -+{ -+ switch (ev) { -+ case TLS_CERT_CHAIN_SUCCESS: -+ wpa_printf(MSG_DEBUG, "radius: remote certificate verification success"); -+ break; -+ case TLS_CERT_CHAIN_FAILURE: -+ wpa_printf(MSG_INFO, "radius: certificate chain failure: reason=%d depth=%d subject='%s' err='%s'", -+ data->cert_fail.reason, -+ data->cert_fail.depth, -+ data->cert_fail.subject, -+ data->cert_fail.reason_txt); -+ break; -+ case TLS_PEER_CERTIFICATE: -+ wpa_printf(MSG_DEBUG, "radius: peer certificate: depth=%d serial_num=%s subject=%s", -+ data->peer_cert.depth, -+ data->peer_cert.serial_num ? data->peer_cert.serial_num : "N/A", -+ data->peer_cert.subject); -+ break; -+ case TLS_ALERT: -+ if (data->alert.is_local) -+ wpa_printf(MSG_DEBUG, "radius: local TLS alert: %s", -+ data->alert.description); -+ else -+ wpa_printf(MSG_DEBUG, "radius: remote TLS alert: %s", -+ data->alert.description); -+ break; -+ case TLS_UNSAFE_RENEGOTIATION_DISABLED: -+ /* Not applicable to TLS server */ -+ break; -+ } -+} -+ -+static void radius_userdata_init(struct radius_user_data *u) -+{ -+ kvlist_init(&u->users, kvlist_blob_len); -+ avl_init(&u->user_state, avl_strcmp, false, NULL); -+} -+ -+static void radius_userdata_free(struct radius_user_data *u) -+{ -+ struct radius_user_state *s, *tmp; -+ -+ kvlist_free(&u->users); -+ free(u->wildcard); -+ u->wildcard = NULL; -+ avl_remove_all_elements(&u->user_state, s, node, tmp) -+ free(s); -+} -+ -+static void -+radius_userdata_load(struct radius_user_data *u, struct blob_attr *data) -+{ -+ enum { -+ USERSTATE_USERS, -+ USERSTATE_WILDCARD, -+ __USERSTATE_MAX, -+ }; -+ static const struct blobmsg_policy policy[__USERSTATE_MAX] = { -+ [USERSTATE_USERS] = { "users", BLOBMSG_TYPE_TABLE }, -+ [USERSTATE_WILDCARD] = { "wildcard", BLOBMSG_TYPE_ARRAY }, -+ }; -+ struct blob_attr *tb[__USERSTATE_MAX], *cur; -+ int rem; -+ -+ if (!data) -+ return; -+ -+ blobmsg_parse(policy, __USERSTATE_MAX, tb, blobmsg_data(data), blobmsg_len(data)); -+ -+ blobmsg_for_each_attr(cur, tb[USERSTATE_USERS], rem) -+ kvlist_set(&u->users, blobmsg_name(cur), cur); -+ -+ if (tb[USERSTATE_WILDCARD]) -+ u->wildcard = blob_memdup(tb[USERSTATE_WILDCARD]); -+} -+ -+static void -+load_userfile(struct radius_state *s) -+{ -+ enum { -+ USERDATA_PHASE1, -+ USERDATA_PHASE2, -+ __USERDATA_MAX -+ }; -+ static const struct blobmsg_policy policy[__USERDATA_MAX] = { -+ [USERDATA_PHASE1] = { "phase1", BLOBMSG_TYPE_TABLE }, -+ [USERDATA_PHASE2] = { "phase2", BLOBMSG_TYPE_TABLE }, -+ }; -+ struct blob_attr *tb[__USERDATA_MAX], *cur; -+ static struct blob_buf b; -+ struct stat st; -+ int rem; -+ -+ if (stat(s->user_file, &st)) -+ return; -+ -+ if (s->user_file_ts == st.st_mtime) -+ return; -+ -+ s->user_file_ts = st.st_mtime; -+ radius_userdata_free(&s->phase1); -+ radius_userdata_free(&s->phase2); -+ -+ blob_buf_init(&b, 0); -+ blobmsg_add_json_from_file(&b, s->user_file); -+ blobmsg_parse(policy, __USERDATA_MAX, tb, blob_data(b.head), blob_len(b.head)); -+ radius_userdata_load(&s->phase1, tb[USERDATA_PHASE1]); -+ radius_userdata_load(&s->phase2, tb[USERDATA_PHASE2]); -+ -+ blob_buf_free(&b); -+} -+ -+static struct blob_attr * -+radius_user_get(struct radius_user_data *s, const char *name) -+{ -+ struct blob_attr *cur; -+ int rem; -+ -+ cur = kvlist_get(&s->users, name); -+ if (cur) -+ return cur; -+ -+ blobmsg_for_each_attr(cur, s->wildcard, rem) { -+ static const struct blobmsg_policy policy = { -+ "name", BLOBMSG_TYPE_STRING -+ }; -+ struct blob_attr *pattern; -+ -+ if (blobmsg_type(cur) != BLOBMSG_TYPE_TABLE) -+ continue; -+ -+ blobmsg_parse(&policy, 1, &pattern, blobmsg_data(cur), blobmsg_len(cur)); -+ if (!name) -+ continue; -+ -+ if (!fnmatch(blobmsg_get_string(pattern), name, 0)) -+ return cur; -+ } -+ -+ return NULL; -+} -+ -+static struct radius_parse_attr_data * -+radius_parse_attr(struct blob_attr *attr) -+{ -+ static const struct blobmsg_policy policy[4] = { -+ { .type = BLOBMSG_TYPE_INT32 }, -+ { .type = BLOBMSG_TYPE_INT32 }, -+ { .type = BLOBMSG_TYPE_STRING }, -+ { .type = BLOBMSG_TYPE_STRING }, -+ }; -+ static struct radius_parse_attr_data data; -+ struct blob_attr *tb[4]; -+ const char *format; -+ -+ blobmsg_parse_array(policy, ARRAY_SIZE(policy), tb, blobmsg_data(attr), blobmsg_len(attr)); -+ -+ if (!tb[0] || !tb[1] || !tb[2] || !tb[3]) -+ return NULL; -+ -+ format = blobmsg_get_string(tb[2]); -+ if (strlen(format) != 1) -+ return NULL; -+ -+ data.vendor = blobmsg_get_u32(tb[0]); -+ data.type = blobmsg_get_u32(tb[1]); -+ data.format = format[0]; -+ data.data = blobmsg_get_string(tb[3]); -+ data.size = strlen(data.data); -+ -+ switch (data.format) { -+ case 's': -+ break; -+ case 'x': -+ if (data.size & 1) -+ return NULL; -+ data.size /= 2; -+ break; -+ case 'd': -+ data.size = 4; -+ break; -+ default: -+ return NULL; -+ } -+ -+ return &data; -+} -+ -+static void -+radius_count_attrs(struct blob_attr **tb, int *n_attr, size_t *attr_size) -+{ -+ struct blob_attr *data = tb[USER_ATTR_RADIUS]; -+ struct blob_attr *cur; -+ int rem; -+ -+ blobmsg_for_each_attr(cur, data, rem) { -+ struct radius_parse_attr_data *data; -+ size_t prev = *attr_size; -+ -+ data = radius_parse_attr(cur); -+ if (!data) -+ continue; -+ -+ *attr_size += data->size; -+ if (data->vendor) -+ *attr_size += VENDOR_ATTR_SIZE; -+ -+ (*n_attr)++; -+ } -+ -+ *n_attr += !!tb[USER_ATTR_VLAN] * 3 + -+ !!tb[USER_ATTR_MAX_RATE_UP] + -+ !!tb[USER_ATTR_MAX_RATE_DOWN]; -+ *attr_size += !!tb[USER_ATTR_VLAN] * (4 + 4 + 5) + -+ !!tb[USER_ATTR_MAX_RATE_UP] * (4 + VENDOR_ATTR_SIZE) + -+ !!tb[USER_ATTR_MAX_RATE_DOWN] * (4 + VENDOR_ATTR_SIZE); -+} -+ -+static void * -+radius_add_attr(struct radius_parse_attr_state *state, -+ u32 vendor, u8 type, u8 len) -+{ -+ struct hostapd_radius_attr *attr; -+ struct wpabuf *buf; -+ void *val; -+ -+ val = state->attrdata; -+ -+ buf = state->buf++; -+ buf->buf = val; -+ -+ attr = state->attr++; -+ attr->val = buf; -+ attr->type = type; -+ -+ if (state->prev) -+ state->prev->next = attr; -+ state->prev = attr; -+ -+ if (vendor) { -+ u8 *vendor_hdr = val + 4; -+ -+ WPA_PUT_BE32(val, vendor); -+ vendor_hdr[0] = type; -+ vendor_hdr[1] = len + 2; -+ -+ len += VENDOR_ATTR_SIZE; -+ val += VENDOR_ATTR_SIZE; -+ attr->type = RADIUS_ATTR_VENDOR_SPECIFIC; -+ } -+ -+ buf->size = buf->used = len; -+ state->attrdata += len; -+ -+ return val; -+} -+ -+static void -+radius_parse_attrs(struct blob_attr **tb, struct radius_parse_attr_state *state) -+{ -+ struct blob_attr *data = tb[USER_ATTR_RADIUS]; -+ struct hostapd_radius_attr *prev = NULL; -+ struct blob_attr *cur; -+ int len, rem; -+ void *val; -+ -+ if ((cur = tb[USER_ATTR_VLAN]) != NULL && blobmsg_get_u32(cur) < 4096) { -+ char buf[5]; -+ -+ val = radius_add_attr(state, 0, RADIUS_ATTR_TUNNEL_TYPE, 4); -+ WPA_PUT_BE32(val, RADIUS_TUNNEL_TYPE_VLAN); -+ -+ val = radius_add_attr(state, 0, RADIUS_ATTR_TUNNEL_MEDIUM_TYPE, 4); -+ WPA_PUT_BE32(val, RADIUS_TUNNEL_MEDIUM_TYPE_802); -+ -+ len = snprintf(buf, sizeof(buf), "%d", blobmsg_get_u32(cur)); -+ val = radius_add_attr(state, 0, RADIUS_ATTR_TUNNEL_PRIVATE_GROUP_ID, len); -+ memcpy(val, buf, len); -+ } -+ -+ if ((cur = tb[USER_ATTR_MAX_RATE_UP]) != NULL) { -+ val = radius_add_attr(state, VENDOR_ID_WISPR, 7, 4); -+ WPA_PUT_BE32(val, blobmsg_get_u32(cur)); -+ } -+ -+ if ((cur = tb[USER_ATTR_MAX_RATE_DOWN]) != NULL) { -+ val = radius_add_attr(state, VENDOR_ID_WISPR, 8, 4); -+ WPA_PUT_BE32(val, blobmsg_get_u32(cur)); -+ } -+ -+ blobmsg_for_each_attr(cur, data, rem) { -+ struct radius_parse_attr_data *data; -+ void *val; -+ int size; -+ -+ data = radius_parse_attr(cur); -+ if (!data) -+ continue; -+ -+ val = radius_add_attr(state, data->vendor, data->type, data->size); -+ switch (data->format) { -+ case 's': -+ memcpy(val, data->data, data->size); -+ break; -+ case 'x': -+ hexstr2bin(data->data, val, data->size); -+ break; -+ case 'd': -+ WPA_PUT_BE32(val, atoi(data->data)); -+ break; -+ } -+ } -+} -+ -+static void -+radius_user_parse_methods(struct eap_user *eap, struct blob_attr *data) -+{ -+ struct blob_attr *cur; -+ int rem, n = 0; -+ -+ if (!data) -+ return; -+ -+ blobmsg_for_each_attr(cur, data, rem) { -+ const char *method; -+ -+ if (blobmsg_type(cur) != BLOBMSG_TYPE_STRING) -+ continue; -+ -+ if (n == EAP_MAX_METHODS) -+ break; -+ -+ method = blobmsg_get_string(cur); -+ eap->methods[n].method = eap_server_get_type(method, &eap->methods[n].vendor); -+ if (eap->methods[n].vendor == EAP_VENDOR_IETF && -+ eap->methods[n].method == EAP_TYPE_NONE) { -+ if (!strcmp(method, "TTLS-PAP")) { -+ eap->ttls_auth |= EAP_TTLS_AUTH_PAP; -+ continue; -+ } -+ if (!strcmp(method, "TTLS-CHAP")) { -+ eap->ttls_auth |= EAP_TTLS_AUTH_CHAP; -+ continue; -+ } -+ if (!strcmp(method, "TTLS-MSCHAP")) { -+ eap->ttls_auth |= EAP_TTLS_AUTH_MSCHAP; -+ continue; -+ } -+ if (!strcmp(method, "TTLS-MSCHAPV2")) { -+ eap->ttls_auth |= EAP_TTLS_AUTH_MSCHAPV2; -+ continue; -+ } -+ } -+ n++; -+ } -+} -+ -+static struct eap_user * -+radius_user_get_state(struct radius_user_data *u, struct blob_attr *data, -+ const char *id) -+{ -+ static const struct blobmsg_policy policy[__USER_ATTR_MAX] = { -+ [USER_ATTR_PASSWORD] = { "password", BLOBMSG_TYPE_STRING }, -+ [USER_ATTR_HASH] = { "hash", BLOBMSG_TYPE_STRING }, -+ [USER_ATTR_SALT] = { "salt", BLOBMSG_TYPE_STRING }, -+ [USER_ATTR_METHODS] = { "methods", BLOBMSG_TYPE_ARRAY }, -+ [USER_ATTR_RADIUS] = { "radius", BLOBMSG_TYPE_ARRAY }, -+ [USER_ATTR_VLAN] = { "vlan-id", BLOBMSG_TYPE_INT32 }, -+ [USER_ATTR_MAX_RATE_UP] = { "max-rate-up", BLOBMSG_TYPE_INT32 }, -+ [USER_ATTR_MAX_RATE_DOWN] = { "max-rate-down", BLOBMSG_TYPE_INT32 }, -+ }; -+ struct blob_attr *tb[__USER_ATTR_MAX], *cur; -+ char *password_buf, *salt_buf, *name_buf; -+ struct radius_parse_attr_state astate = {}; -+ struct hostapd_radius_attr *attr; -+ struct radius_user_state *state; -+ int pw_len = 0, salt_len = 0; -+ struct eap_user *eap; -+ struct wpabuf *val; -+ size_t attrsize = 0; -+ void *attrdata; -+ int n_attr = 0; -+ -+ state = avl_find_element(&u->user_state, id, state, node); -+ if (state) -+ return &state->data; -+ -+ blobmsg_parse(policy, __USER_ATTR_MAX, tb, blobmsg_data(data), blobmsg_len(data)); -+ -+ if ((cur = tb[USER_ATTR_SALT]) != NULL) -+ salt_len = strlen(blobmsg_get_string(cur)) / 2; -+ if ((cur = tb[USER_ATTR_HASH]) != NULL) -+ pw_len = strlen(blobmsg_get_string(cur)) / 2; -+ else if ((cur = tb[USER_ATTR_PASSWORD]) != NULL) -+ pw_len = blobmsg_len(cur) - 1; -+ radius_count_attrs(tb, &n_attr, &attrsize); -+ -+ state = calloc_a(sizeof(*state), &name_buf, strlen(id) + 1, -+ &password_buf, pw_len, -+ &salt_buf, salt_len, -+ &astate.attr, n_attr * sizeof(*astate.attr), -+ &astate.buf, n_attr * sizeof(*astate.buf), -+ &astate.attrdata, attrsize); -+ eap = &state->data; -+ eap->salt = salt_len ? salt_buf : NULL; -+ eap->salt_len = salt_len; -+ eap->password = pw_len ? password_buf : NULL; -+ eap->password_len = pw_len; -+ eap->force_version = -1; -+ -+ if ((cur = tb[USER_ATTR_SALT]) != NULL) -+ hexstr2bin(blobmsg_get_string(cur), salt_buf, salt_len); -+ if ((cur = tb[USER_ATTR_PASSWORD]) != NULL) -+ memcpy(password_buf, blobmsg_get_string(cur), pw_len); -+ else if ((cur = tb[USER_ATTR_HASH]) != NULL) { -+ hexstr2bin(blobmsg_get_string(cur), password_buf, pw_len); -+ eap->password_hash = 1; -+ } -+ radius_user_parse_methods(eap, tb[USER_ATTR_METHODS]); -+ -+ if (n_attr > 0) { -+ cur = tb[USER_ATTR_RADIUS]; -+ eap->accept_attr = astate.attr; -+ radius_parse_attrs(tb, &astate); -+ } -+ -+ state->node.key = strcpy(name_buf, id); -+ avl_insert(&u->user_state, &state->node); -+ -+ return &state->data; -+ -+free: -+ free(state); -+ return NULL; -+} -+ -+static int radius_get_eap_user(void *ctx, const u8 *identity, -+ size_t identity_len, int phase2, -+ struct eap_user *user) -+{ -+ struct radius_state *s = ctx; -+ struct radius_user_data *u = phase2 ? &s->phase2 : &s->phase1; -+ struct blob_attr *entry; -+ struct eap_user *data; -+ char *id; -+ -+ if (identity_len > 512) -+ return -1; -+ -+ load_userfile(s); -+ -+ id = alloca(identity_len + 1); -+ memcpy(id, identity, identity_len); -+ id[identity_len] = 0; -+ -+ entry = radius_user_get(u, id); -+ if (!entry) -+ return -1; -+ -+ if (!user) -+ return 0; -+ -+ data = radius_user_get_state(u, entry, id); -+ if (!data) -+ return -1; -+ -+ *user = *data; -+ if (user->password_len > 0) -+ user->password = os_memdup(user->password, user->password_len); -+ if (user->salt_len > 0) -+ user->salt = os_memdup(user->salt, user->salt_len); -+ user->phase2 = phase2; -+ -+ return 0; -+} -+ -+static int radius_setup(struct radius_state *s, struct radius_config *c) -+{ -+ struct eap_config *eap = &s->eap; -+ struct tls_config conf = { -+ .event_cb = radius_tls_event, -+ .tls_flags = TLS_CONN_DISABLE_TLSv1_3, -+ .cb_ctx = s, -+ }; -+ -+ eap->eap_server = 1; -+ eap->max_auth_rounds = 100; -+ eap->max_auth_rounds_short = 50; -+ eap->ssl_ctx = tls_init(&conf); -+ if (!eap->ssl_ctx) { -+ wpa_printf(MSG_INFO, "TLS init failed\n"); -+ return 1; -+ } -+ -+ if (tls_global_set_params(eap->ssl_ctx, &c->tls)) { -+ wpa_printf(MSG_INFO, "failed to set TLS parameters\n"); -+ return 1; -+ } -+ -+ c->radius.eap_cfg = eap; -+ c->radius.conf_ctx = s; -+ c->radius.get_eap_user = radius_get_eap_user; -+ s->radius = radius_server_init(&c->radius); -+ if (!s->radius) { -+ wpa_printf(MSG_INFO, "failed to initialize radius server\n"); -+ return 1; -+ } -+ -+ return 0; -+} -+ -+static int radius_init(struct radius_state *s) -+{ -+ memset(s, 0, sizeof(*s)); -+ radius_userdata_init(&s->phase1); -+ radius_userdata_init(&s->phase2); -+} -+ -+static void radius_deinit(struct radius_state *s) -+{ -+ if (s->radius) -+ radius_server_deinit(s->radius); -+ -+ if (s->eap.ssl_ctx) -+ tls_deinit(s->eap.ssl_ctx); -+ -+ radius_userdata_free(&s->phase1); -+ radius_userdata_free(&s->phase2); -+} -+ -+static int usage(const char *progname) -+{ -+ fprintf(stderr, "Usage: %s \n", -+ progname); -+} -+ -+int radius_main(int argc, char **argv) -+{ -+ static struct radius_state state = {}; -+ static struct radius_config config = {}; -+ const char *progname = argv[0]; -+ int ret = 0; -+ int ch; -+ -+ wpa_debug_setup_stdout(); -+ wpa_debug_level = 0; -+ -+ if (eloop_init()) { -+ wpa_printf(MSG_ERROR, "Failed to initialize event loop"); -+ return 1; -+ } -+ -+ eap_server_register_methods(); -+ radius_init(&state); -+ -+ while ((ch = getopt(argc, argv, "6C:c:d:i:k:K:p:P:s:u:")) != -1) { -+ switch (ch) { -+ case '6': -+ config.radius.ipv6 = 1; -+ break; -+ case 'C': -+ config.tls.ca_cert = optarg; -+ break; -+ case 'c': -+ if (config.tls.client_cert2) -+ return usage(progname); -+ -+ if (config.tls.client_cert) -+ config.tls.client_cert2 = optarg; -+ else -+ config.tls.client_cert = optarg; -+ break; -+ case 'd': -+ config.tls.dh_file = optarg; -+ break; -+ case 'i': -+ state.eap.server_id = optarg; -+ state.eap.server_id_len = strlen(optarg); -+ break; -+ case 'k': -+ if (config.tls.private_key2) -+ return usage(progname); -+ -+ if (config.tls.private_key) -+ config.tls.private_key2 = optarg; -+ else -+ config.tls.private_key = optarg; -+ break; -+ case 'K': -+ if (config.tls.private_key_passwd2) -+ return usage(progname); -+ -+ if (config.tls.private_key_passwd) -+ config.tls.private_key_passwd2 = optarg; -+ else -+ config.tls.private_key_passwd = optarg; -+ break; -+ case 'p': -+ config.radius.auth_port = atoi(optarg); -+ break; -+ case 'P': -+ config.radius.acct_port = atoi(optarg); -+ break; -+ case 's': -+ config.radius.client_file = optarg; -+ break; -+ case 'u': -+ state.user_file = optarg; -+ break; -+ default: -+ return usage(progname); -+ } -+ } -+ -+ if (!config.tls.client_cert || !config.tls.private_key || -+ !config.radius.client_file || !state.eap.server_id || -+ !state.user_file) { -+ wpa_printf(MSG_INFO, "missing options\n"); -+ goto out; -+ } -+ -+ ret = radius_setup(&state, &config); -+ if (ret) -+ goto out; -+ -+ load_userfile(&state); -+ eloop_run(); -+ -+out: -+ radius_deinit(&state); -+ os_program_deinit(); -+ -+ return ret; -+} -diff --git a/package/network/services/hostapd/src/src/ap/ubus.c b/package/network/services/hostapd/src/src/ap/ubus.c -new file mode 100644 -index 0000000000..6ff2257c32 ---- /dev/null -+++ b/package/network/services/hostapd/src/src/ap/ubus.c -@@ -0,0 +1,2002 @@ -+/* -+ * hostapd / ubus support -+ * Copyright (c) 2013, Felix Fietkau -+ * -+ * This software may be distributed under the terms of the BSD license. -+ * See README for more details. -+ */ -+ -+#include "utils/includes.h" -+#include "utils/common.h" -+#include "utils/eloop.h" -+#include "utils/wpabuf.h" -+#include "common/ieee802_11_defs.h" -+#include "common/hw_features_common.h" -+#include "hostapd.h" -+#include "neighbor_db.h" -+#include "wps_hostapd.h" -+#include "sta_info.h" -+#include "ubus.h" -+#include "ap_drv_ops.h" -+#include "beacon.h" -+#include "rrm.h" -+#include "wnm_ap.h" -+#include "taxonomy.h" -+#include "airtime_policy.h" -+#include "hw_features.h" -+ -+static struct ubus_context *ctx; -+static struct blob_buf b; -+static int ctx_ref; -+ -+static inline struct hostapd_data *get_hapd_from_object(struct ubus_object *obj) -+{ -+ return container_of(obj, struct hostapd_data, ubus.obj); -+} -+ -+struct ubus_banned_client { -+ struct avl_node avl; -+ u8 addr[ETH_ALEN]; -+}; -+ -+static void ubus_reconnect_timeout(void *eloop_data, void *user_ctx) -+{ -+ if (ubus_reconnect(ctx, NULL)) { -+ eloop_register_timeout(1, 0, ubus_reconnect_timeout, ctx, NULL); -+ return; -+ } -+ -+ ubus_add_uloop(ctx); -+} -+ -+static void hostapd_ubus_connection_lost(struct ubus_context *ctx) -+{ -+ uloop_fd_delete(&ctx->sock); -+ eloop_register_timeout(1, 0, ubus_reconnect_timeout, ctx, NULL); -+} -+ -+static bool hostapd_ubus_init(void) -+{ -+ if (ctx) -+ return true; -+ -+ eloop_add_uloop(); -+ ctx = ubus_connect(NULL); -+ if (!ctx) -+ return false; -+ -+ ctx->connection_lost = hostapd_ubus_connection_lost; -+ ubus_add_uloop(ctx); -+ -+ return true; -+} -+ -+static void hostapd_ubus_ref_inc(void) -+{ -+ ctx_ref++; -+} -+ -+static void hostapd_ubus_ref_dec(void) -+{ -+ ctx_ref--; -+ if (!ctx) -+ return; -+ -+ if (ctx_ref) -+ return; -+ -+ uloop_fd_delete(&ctx->sock); -+ ubus_free(ctx); -+ ctx = NULL; -+} -+ -+void hostapd_ubus_add_iface(struct hostapd_iface *iface) -+{ -+ if (!hostapd_ubus_init()) -+ return; -+} -+ -+void hostapd_ubus_free_iface(struct hostapd_iface *iface) -+{ -+ if (!ctx) -+ return; -+} -+ -+static void hostapd_notify_ubus(struct ubus_object *obj, char *bssname, char *event) -+{ -+ char *event_type; -+ -+ if (!ctx || !obj) -+ return; -+ -+ if (asprintf(&event_type, "bss.%s", event) < 0) -+ return; -+ -+ blob_buf_init(&b, 0); -+ blobmsg_add_string(&b, "name", bssname); -+ ubus_notify(ctx, obj, event_type, b.head, -1); -+ free(event_type); -+} -+ -+static void -+hostapd_bss_del_ban(void *eloop_data, void *user_ctx) -+{ -+ struct ubus_banned_client *ban = eloop_data; -+ struct hostapd_data *hapd = user_ctx; -+ -+ avl_delete(&hapd->ubus.banned, &ban->avl); -+ free(ban); -+} -+ -+static void -+hostapd_bss_ban_client(struct hostapd_data *hapd, u8 *addr, int time) -+{ -+ struct ubus_banned_client *ban; -+ -+ if (time < 0) -+ time = 0; -+ -+ ban = avl_find_element(&hapd->ubus.banned, addr, ban, avl); -+ if (!ban) { -+ if (!time) -+ return; -+ -+ ban = os_zalloc(sizeof(*ban)); -+ memcpy(ban->addr, addr, sizeof(ban->addr)); -+ ban->avl.key = ban->addr; -+ avl_insert(&hapd->ubus.banned, &ban->avl); -+ } else { -+ eloop_cancel_timeout(hostapd_bss_del_ban, ban, hapd); -+ if (!time) { -+ hostapd_bss_del_ban(ban, hapd); -+ return; -+ } -+ } -+ -+ eloop_register_timeout(0, time * 1000, hostapd_bss_del_ban, ban, hapd); -+} -+ -+static int -+hostapd_bss_reload(struct ubus_context *ctx, struct ubus_object *obj, -+ struct ubus_request_data *req, const char *method, -+ struct blob_attr *msg) -+{ -+ struct hostapd_data *hapd = container_of(obj, struct hostapd_data, ubus.obj); -+ -+ return hostapd_reload_config(hapd->iface); -+} -+ -+ -+static void -+hostapd_parse_vht_map_blobmsg(uint16_t map) -+{ -+ char label[4]; -+ int16_t val; -+ int i; -+ -+ for (i = 0; i < 8; i++) { -+ snprintf(label, 4, "%dss", i + 1); -+ -+ val = (map & (BIT(1) | BIT(0))) + 7; -+ blobmsg_add_u16(&b, label, val == 10 ? -1 : val); -+ map = map >> 2; -+ } -+} -+ -+static void -+hostapd_parse_vht_capab_blobmsg(struct ieee80211_vht_capabilities *vhtc) -+{ -+ void *supported_mcs; -+ void *map; -+ int i; -+ -+ static const struct { -+ const char *name; -+ uint32_t flag; -+ } vht_capas[] = { -+ { "su_beamformee", VHT_CAP_SU_BEAMFORMEE_CAPABLE }, -+ { "mu_beamformee", VHT_CAP_MU_BEAMFORMEE_CAPABLE }, -+ }; -+ -+ for (i = 0; i < ARRAY_SIZE(vht_capas); i++) -+ blobmsg_add_u8(&b, vht_capas[i].name, -+ !!(vhtc->vht_capabilities_info & vht_capas[i].flag)); -+ -+ supported_mcs = blobmsg_open_table(&b, "mcs_map"); -+ -+ /* RX map */ -+ map = blobmsg_open_table(&b, "rx"); -+ hostapd_parse_vht_map_blobmsg(le_to_host16(vhtc->vht_supported_mcs_set.rx_map)); -+ blobmsg_close_table(&b, map); -+ -+ /* TX map */ -+ map = blobmsg_open_table(&b, "tx"); -+ hostapd_parse_vht_map_blobmsg(le_to_host16(vhtc->vht_supported_mcs_set.tx_map)); -+ blobmsg_close_table(&b, map); -+ -+ blobmsg_close_table(&b, supported_mcs); -+} -+ -+static void -+hostapd_parse_capab_blobmsg(struct sta_info *sta) -+{ -+ void *r, *v; -+ -+ v = blobmsg_open_table(&b, "capabilities"); -+ -+ if (sta->vht_capabilities) { -+ r = blobmsg_open_table(&b, "vht"); -+ hostapd_parse_vht_capab_blobmsg(sta->vht_capabilities); -+ blobmsg_close_table(&b, r); -+ } -+ -+ /* ToDo: Add HT / HE capability parsing */ -+ -+ blobmsg_close_table(&b, v); -+} -+ -+static int -+hostapd_bss_get_clients(struct ubus_context *ctx, struct ubus_object *obj, -+ struct ubus_request_data *req, const char *method, -+ struct blob_attr *msg) -+{ -+ struct hostapd_data *hapd = container_of(obj, struct hostapd_data, ubus.obj); -+ struct hostap_sta_driver_data sta_driver_data; -+ struct sta_info *sta; -+ void *list, *c; -+ char mac_buf[20]; -+ static const struct { -+ const char *name; -+ uint32_t flag; -+ } sta_flags[] = { -+ { "auth", WLAN_STA_AUTH }, -+ { "assoc", WLAN_STA_ASSOC }, -+ { "authorized", WLAN_STA_AUTHORIZED }, -+ { "preauth", WLAN_STA_PREAUTH }, -+ { "wds", WLAN_STA_WDS }, -+ { "wmm", WLAN_STA_WMM }, -+ { "ht", WLAN_STA_HT }, -+ { "vht", WLAN_STA_VHT }, -+ { "he", WLAN_STA_HE }, -+ { "wps", WLAN_STA_WPS }, -+ { "mfp", WLAN_STA_MFP }, -+ }; -+ -+ blob_buf_init(&b, 0); -+ blobmsg_add_u32(&b, "freq", hapd->iface->freq); -+ list = blobmsg_open_table(&b, "clients"); -+ for (sta = hapd->sta_list; sta; sta = sta->next) { -+ void *r; -+ int i; -+ -+ sprintf(mac_buf, MACSTR, MAC2STR(sta->addr)); -+ c = blobmsg_open_table(&b, mac_buf); -+ for (i = 0; i < ARRAY_SIZE(sta_flags); i++) -+ blobmsg_add_u8(&b, sta_flags[i].name, -+ !!(sta->flags & sta_flags[i].flag)); -+ -+#ifdef CONFIG_MBO -+ blobmsg_add_u8(&b, "mbo", !!(sta->cell_capa)); -+#endif -+ -+ r = blobmsg_open_array(&b, "rrm"); -+ for (i = 0; i < ARRAY_SIZE(sta->rrm_enabled_capa); i++) -+ blobmsg_add_u32(&b, "", sta->rrm_enabled_capa[i]); -+ blobmsg_close_array(&b, r); -+ -+ r = blobmsg_open_array(&b, "extended_capabilities"); -+ /* Check if client advertises extended capabilities */ -+ if (sta->ext_capability && sta->ext_capability[0] > 0) { -+ for (i = 0; i < sta->ext_capability[0]; i++) { -+ blobmsg_add_u32(&b, "", sta->ext_capability[1 + i]); -+ } -+ } -+ blobmsg_close_array(&b, r); -+ -+ blobmsg_add_u32(&b, "aid", sta->aid); -+#ifdef CONFIG_TAXONOMY -+ r = blobmsg_alloc_string_buffer(&b, "signature", 1024); -+ if (retrieve_sta_taxonomy(hapd, sta, r, 1024) > 0) -+ blobmsg_add_string_buffer(&b); -+#endif -+ -+ /* Driver information */ -+ if (hostapd_drv_read_sta_data(hapd, &sta_driver_data, sta->addr) >= 0) { -+ r = blobmsg_open_table(&b, "bytes"); -+ blobmsg_add_u64(&b, "rx", sta_driver_data.rx_bytes); -+ blobmsg_add_u64(&b, "tx", sta_driver_data.tx_bytes); -+ blobmsg_close_table(&b, r); -+ r = blobmsg_open_table(&b, "airtime"); -+ blobmsg_add_u64(&b, "rx", sta_driver_data.rx_airtime); -+ blobmsg_add_u64(&b, "tx", sta_driver_data.tx_airtime); -+ blobmsg_close_table(&b, r); -+ r = blobmsg_open_table(&b, "packets"); -+ blobmsg_add_u32(&b, "rx", sta_driver_data.rx_packets); -+ blobmsg_add_u32(&b, "tx", sta_driver_data.tx_packets); -+ blobmsg_close_table(&b, r); -+ r = blobmsg_open_table(&b, "rate"); -+ /* Rate in kbits */ -+ blobmsg_add_u32(&b, "rx", sta_driver_data.current_rx_rate * 100); -+ blobmsg_add_u32(&b, "tx", sta_driver_data.current_tx_rate * 100); -+ blobmsg_close_table(&b, r); -+ blobmsg_add_u32(&b, "signal", sta_driver_data.signal); -+ } -+ -+ hostapd_parse_capab_blobmsg(sta); -+ -+ blobmsg_close_table(&b, c); -+ } -+ blobmsg_close_array(&b, list); -+ ubus_send_reply(ctx, req, b.head); -+ -+ return 0; -+} -+ -+static int -+hostapd_bss_get_features(struct ubus_context *ctx, struct ubus_object *obj, -+ struct ubus_request_data *req, const char *method, -+ struct blob_attr *msg) -+{ -+ struct hostapd_data *hapd = container_of(obj, struct hostapd_data, ubus.obj); -+ -+ blob_buf_init(&b, 0); -+ blobmsg_add_u8(&b, "ht_supported", ht_supported(hapd->iface->hw_features)); -+ blobmsg_add_u8(&b, "vht_supported", vht_supported(hapd->iface->hw_features)); -+ ubus_send_reply(ctx, req, b.head); -+ -+ return 0; -+} -+ -+static int -+hostapd_bss_get_status(struct ubus_context *ctx, struct ubus_object *obj, -+ struct ubus_request_data *req, const char *method, -+ struct blob_attr *msg) -+{ -+ struct hostapd_data *hapd = container_of(obj, struct hostapd_data, ubus.obj); -+ void *airtime_table, *dfs_table, *rrm_table, *wnm_table; -+ struct os_reltime now; -+ char ssid[SSID_MAX_LEN + 1]; -+ char phy_name[17]; -+ size_t ssid_len = SSID_MAX_LEN; -+ u8 channel = 0, op_class = 0; -+ -+ if (hapd->conf->ssid.ssid_len < SSID_MAX_LEN) -+ ssid_len = hapd->conf->ssid.ssid_len; -+ -+ ieee80211_freq_to_channel_ext(hapd->iface->freq, -+ hapd->iconf->secondary_channel, -+ hostapd_get_oper_chwidth(hapd->iconf), -+ &op_class, &channel); -+ -+ blob_buf_init(&b, 0); -+ blobmsg_add_string(&b, "status", hostapd_state_text(hapd->iface->state)); -+ blobmsg_printf(&b, "bssid", MACSTR, MAC2STR(hapd->conf->bssid)); -+ -+ memset(ssid, 0, SSID_MAX_LEN + 1); -+ memcpy(ssid, hapd->conf->ssid.ssid, ssid_len); -+ blobmsg_add_string(&b, "ssid", ssid); -+ -+ blobmsg_add_u32(&b, "freq", hapd->iface->freq); -+ blobmsg_add_u32(&b, "channel", channel); -+ blobmsg_add_u32(&b, "op_class", op_class); -+ blobmsg_add_u32(&b, "beacon_interval", hapd->iconf->beacon_int); -+#ifdef CONFIG_IEEE80211AX -+ blobmsg_add_u32(&b, "bss_color", hapd->iface->conf->he_op.he_bss_color_disabled ? -1 : -+ hapd->iface->conf->he_op.he_bss_color); -+#else -+ blobmsg_add_u32(&b, "bss_color", -1); -+#endif -+ -+ snprintf(phy_name, 17, "%s", hapd->iface->phy); -+ blobmsg_add_string(&b, "phy", phy_name); -+ -+ /* RRM */ -+ rrm_table = blobmsg_open_table(&b, "rrm"); -+ blobmsg_add_u64(&b, "neighbor_report_tx", hapd->openwrt_stats.rrm.neighbor_report_tx); -+ blobmsg_close_table(&b, rrm_table); -+ -+ /* WNM */ -+ wnm_table = blobmsg_open_table(&b, "wnm"); -+ blobmsg_add_u64(&b, "bss_transition_query_rx", hapd->openwrt_stats.wnm.bss_transition_query_rx); -+ blobmsg_add_u64(&b, "bss_transition_request_tx", hapd->openwrt_stats.wnm.bss_transition_request_tx); -+ blobmsg_add_u64(&b, "bss_transition_response_rx", hapd->openwrt_stats.wnm.bss_transition_response_rx); -+ blobmsg_close_table(&b, wnm_table); -+ -+ /* Airtime */ -+ airtime_table = blobmsg_open_table(&b, "airtime"); -+ blobmsg_add_u64(&b, "time", hapd->iface->last_channel_time); -+ blobmsg_add_u64(&b, "time_busy", hapd->iface->last_channel_time_busy); -+ blobmsg_add_u16(&b, "utilization", hapd->iface->channel_utilization); -+ blobmsg_close_table(&b, airtime_table); -+ -+ /* DFS */ -+ dfs_table = blobmsg_open_table(&b, "dfs"); -+ blobmsg_add_u32(&b, "cac_seconds", hapd->iface->dfs_cac_ms / 1000); -+ blobmsg_add_u8(&b, "cac_active", !!(hapd->iface->cac_started)); -+ os_reltime_age(&hapd->iface->dfs_cac_start, &now); -+ blobmsg_add_u32(&b, "cac_seconds_left", -+ hapd->iface->cac_started ? hapd->iface->dfs_cac_ms / 1000 - now.sec : 0); -+ blobmsg_close_table(&b, dfs_table); -+ -+ ubus_send_reply(ctx, req, b.head); -+ -+ return 0; -+} -+ -+enum { -+ NOTIFY_RESPONSE, -+ __NOTIFY_MAX -+}; -+ -+static const struct blobmsg_policy notify_policy[__NOTIFY_MAX] = { -+ [NOTIFY_RESPONSE] = { "notify_response", BLOBMSG_TYPE_INT32 }, -+}; -+ -+static int -+hostapd_notify_response(struct ubus_context *ctx, struct ubus_object *obj, -+ struct ubus_request_data *req, const char *method, -+ struct blob_attr *msg) -+{ -+ struct blob_attr *tb[__NOTIFY_MAX]; -+ struct hostapd_data *hapd = get_hapd_from_object(obj); -+ struct wpabuf *elems; -+ const char *pos; -+ size_t len; -+ -+ blobmsg_parse(notify_policy, __NOTIFY_MAX, tb, -+ blob_data(msg), blob_len(msg)); -+ -+ if (!tb[NOTIFY_RESPONSE]) -+ return UBUS_STATUS_INVALID_ARGUMENT; -+ -+ hapd->ubus.notify_response = blobmsg_get_u32(tb[NOTIFY_RESPONSE]); -+ -+ return UBUS_STATUS_OK; -+} -+ -+enum { -+ DEL_CLIENT_ADDR, -+ DEL_CLIENT_REASON, -+ DEL_CLIENT_DEAUTH, -+ DEL_CLIENT_BAN_TIME, -+ __DEL_CLIENT_MAX -+}; -+ -+static const struct blobmsg_policy del_policy[__DEL_CLIENT_MAX] = { -+ [DEL_CLIENT_ADDR] = { "addr", BLOBMSG_TYPE_STRING }, -+ [DEL_CLIENT_REASON] = { "reason", BLOBMSG_TYPE_INT32 }, -+ [DEL_CLIENT_DEAUTH] = { "deauth", BLOBMSG_TYPE_INT8 }, -+ [DEL_CLIENT_BAN_TIME] = { "ban_time", BLOBMSG_TYPE_INT32 }, -+}; -+ -+static int -+hostapd_bss_del_client(struct ubus_context *ctx, struct ubus_object *obj, -+ struct ubus_request_data *req, const char *method, -+ struct blob_attr *msg) -+{ -+ struct blob_attr *tb[__DEL_CLIENT_MAX]; -+ struct hostapd_data *hapd = container_of(obj, struct hostapd_data, ubus.obj); -+ struct sta_info *sta; -+ bool deauth = false; -+ int reason; -+ u8 addr[ETH_ALEN]; -+ -+ blobmsg_parse(del_policy, __DEL_CLIENT_MAX, tb, blob_data(msg), blob_len(msg)); -+ -+ if (!tb[DEL_CLIENT_ADDR]) -+ return UBUS_STATUS_INVALID_ARGUMENT; -+ -+ if (hwaddr_aton(blobmsg_data(tb[DEL_CLIENT_ADDR]), addr)) -+ return UBUS_STATUS_INVALID_ARGUMENT; -+ -+ if (tb[DEL_CLIENT_REASON]) -+ reason = blobmsg_get_u32(tb[DEL_CLIENT_REASON]); -+ -+ if (tb[DEL_CLIENT_DEAUTH]) -+ deauth = blobmsg_get_bool(tb[DEL_CLIENT_DEAUTH]); -+ -+ sta = ap_get_sta(hapd, addr); -+ if (sta) { -+ if (deauth) { -+ hostapd_drv_sta_deauth(hapd, addr, reason); -+ ap_sta_deauthenticate(hapd, sta, reason); -+ } else { -+ hostapd_drv_sta_disassoc(hapd, addr, reason); -+ ap_sta_disassociate(hapd, sta, reason); -+ } -+ } -+ -+ if (tb[DEL_CLIENT_BAN_TIME]) -+ hostapd_bss_ban_client(hapd, addr, blobmsg_get_u32(tb[DEL_CLIENT_BAN_TIME])); -+ -+ return 0; -+} -+ -+static void -+blobmsg_add_macaddr(struct blob_buf *buf, const char *name, const u8 *addr) -+{ -+ char *s; -+ -+ s = blobmsg_alloc_string_buffer(buf, name, 20); -+ sprintf(s, MACSTR, MAC2STR(addr)); -+ blobmsg_add_string_buffer(buf); -+} -+ -+static int -+hostapd_bss_list_bans(struct ubus_context *ctx, struct ubus_object *obj, -+ struct ubus_request_data *req, const char *method, -+ struct blob_attr *msg) -+{ -+ struct hostapd_data *hapd = container_of(obj, struct hostapd_data, ubus.obj); -+ struct ubus_banned_client *ban; -+ void *c; -+ -+ blob_buf_init(&b, 0); -+ c = blobmsg_open_array(&b, "clients"); -+ avl_for_each_element(&hapd->ubus.banned, ban, avl) -+ blobmsg_add_macaddr(&b, NULL, ban->addr); -+ blobmsg_close_array(&b, c); -+ ubus_send_reply(ctx, req, b.head); -+ -+ return 0; -+} -+ -+#ifdef CONFIG_WPS -+static int -+hostapd_bss_wps_start(struct ubus_context *ctx, struct ubus_object *obj, -+ struct ubus_request_data *req, const char *method, -+ struct blob_attr *msg) -+{ -+ int rc; -+ struct hostapd_data *hapd = container_of(obj, struct hostapd_data, ubus.obj); -+ -+ rc = hostapd_wps_button_pushed(hapd, NULL); -+ -+ if (rc != 0) -+ return UBUS_STATUS_NOT_SUPPORTED; -+ -+ return 0; -+} -+ -+ -+static const char * pbc_status_enum_str(enum pbc_status status) -+{ -+ switch (status) { -+ case WPS_PBC_STATUS_DISABLE: -+ return "Disabled"; -+ case WPS_PBC_STATUS_ACTIVE: -+ return "Active"; -+ case WPS_PBC_STATUS_TIMEOUT: -+ return "Timed-out"; -+ case WPS_PBC_STATUS_OVERLAP: -+ return "Overlap"; -+ default: -+ return "Unknown"; -+ } -+} -+ -+static int -+hostapd_bss_wps_status(struct ubus_context *ctx, struct ubus_object *obj, -+ struct ubus_request_data *req, const char *method, -+ struct blob_attr *msg) -+{ -+ int rc; -+ struct hostapd_data *hapd = container_of(obj, struct hostapd_data, ubus.obj); -+ -+ blob_buf_init(&b, 0); -+ -+ blobmsg_add_string(&b, "pbc_status", pbc_status_enum_str(hapd->wps_stats.pbc_status)); -+ blobmsg_add_string(&b, "last_wps_result", -+ (hapd->wps_stats.status == WPS_STATUS_SUCCESS ? -+ "Success": -+ (hapd->wps_stats.status == WPS_STATUS_FAILURE ? -+ "Failed" : "None"))); -+ -+ /* If status == Failure - Add possible Reasons */ -+ if(hapd->wps_stats.status == WPS_STATUS_FAILURE && -+ hapd->wps_stats.failure_reason > 0) -+ blobmsg_add_string(&b, "reason", wps_ei_str(hapd->wps_stats.failure_reason)); -+ -+ if (hapd->wps_stats.status) -+ blobmsg_printf(&b, "peer_address", MACSTR, MAC2STR(hapd->wps_stats.peer_addr)); -+ -+ ubus_send_reply(ctx, req, b.head); -+ -+ return 0; -+} -+ -+static int -+hostapd_bss_wps_cancel(struct ubus_context *ctx, struct ubus_object *obj, -+ struct ubus_request_data *req, const char *method, -+ struct blob_attr *msg) -+{ -+ int rc; -+ struct hostapd_data *hapd = container_of(obj, struct hostapd_data, ubus.obj); -+ -+ rc = hostapd_wps_cancel(hapd); -+ -+ if (rc != 0) -+ return UBUS_STATUS_NOT_SUPPORTED; -+ -+ return 0; -+} -+#endif /* CONFIG_WPS */ -+ -+static int -+hostapd_bss_update_beacon(struct ubus_context *ctx, struct ubus_object *obj, -+ struct ubus_request_data *req, const char *method, -+ struct blob_attr *msg) -+{ -+ int rc; -+ struct hostapd_data *hapd = container_of(obj, struct hostapd_data, ubus.obj); -+ -+ rc = ieee802_11_set_beacon(hapd); -+ -+ if (rc != 0) -+ return UBUS_STATUS_NOT_SUPPORTED; -+ -+ return 0; -+} -+ -+enum { -+ CONFIG_IFACE, -+ CONFIG_FILE, -+ __CONFIG_MAX -+}; -+ -+enum { -+ CSA_FREQ, -+ CSA_BCN_COUNT, -+ CSA_CENTER_FREQ1, -+ CSA_CENTER_FREQ2, -+ CSA_BANDWIDTH, -+ CSA_SEC_CHANNEL_OFFSET, -+ CSA_HT, -+ CSA_VHT, -+ CSA_HE, -+ CSA_BLOCK_TX, -+ CSA_FORCE, -+ __CSA_MAX -+}; -+ -+static const struct blobmsg_policy csa_policy[__CSA_MAX] = { -+ [CSA_FREQ] = { "freq", BLOBMSG_TYPE_INT32 }, -+ [CSA_BCN_COUNT] = { "bcn_count", BLOBMSG_TYPE_INT32 }, -+ [CSA_CENTER_FREQ1] = { "center_freq1", BLOBMSG_TYPE_INT32 }, -+ [CSA_CENTER_FREQ2] = { "center_freq2", BLOBMSG_TYPE_INT32 }, -+ [CSA_BANDWIDTH] = { "bandwidth", BLOBMSG_TYPE_INT32 }, -+ [CSA_SEC_CHANNEL_OFFSET] = { "sec_channel_offset", BLOBMSG_TYPE_INT32 }, -+ [CSA_HT] = { "ht", BLOBMSG_TYPE_BOOL }, -+ [CSA_VHT] = { "vht", BLOBMSG_TYPE_BOOL }, -+ [CSA_HE] = { "he", BLOBMSG_TYPE_BOOL }, -+ [CSA_BLOCK_TX] = { "block_tx", BLOBMSG_TYPE_BOOL }, -+ [CSA_FORCE] = { "force", BLOBMSG_TYPE_BOOL }, -+}; -+ -+ -+static void switch_chan_fallback_cb(void *eloop_data, void *user_ctx) -+{ -+ struct hostapd_iface *iface = eloop_data; -+ struct hostapd_freq_params *freq_params = user_ctx; -+ -+ hostapd_switch_channel_fallback(iface, freq_params); -+} -+ -+#ifdef NEED_AP_MLME -+static int -+hostapd_switch_chan(struct ubus_context *ctx, struct ubus_object *obj, -+ struct ubus_request_data *req, const char *method, -+ struct blob_attr *msg) -+{ -+ struct blob_attr *tb[__CSA_MAX]; -+ struct hostapd_data *hapd = get_hapd_from_object(obj); -+ struct hostapd_config *iconf = hapd->iface->conf; -+ struct hostapd_freq_params *freq_params; -+ struct hostapd_hw_modes *mode = hapd->iface->current_mode; -+ struct csa_settings css = { -+ .freq_params = { -+ .ht_enabled = iconf->ieee80211n, -+ .vht_enabled = iconf->ieee80211ac, -+ .he_enabled = iconf->ieee80211ax, -+ .sec_channel_offset = iconf->secondary_channel, -+ } -+ }; -+ u8 chwidth = hostapd_get_oper_chwidth(iconf); -+ u8 seg0 = 0, seg1 = 0; -+ int ret = UBUS_STATUS_OK; -+ int i; -+ -+ blobmsg_parse(csa_policy, __CSA_MAX, tb, blob_data(msg), blob_len(msg)); -+ -+ if (!tb[CSA_FREQ]) -+ return UBUS_STATUS_INVALID_ARGUMENT; -+ -+ switch (iconf->vht_oper_chwidth) { -+ case CHANWIDTH_USE_HT: -+ if (iconf->secondary_channel) -+ css.freq_params.bandwidth = 40; -+ else -+ css.freq_params.bandwidth = 20; -+ break; -+ case CHANWIDTH_160MHZ: -+ css.freq_params.bandwidth = 160; -+ break; -+ default: -+ css.freq_params.bandwidth = 80; -+ break; -+ } -+ -+ css.freq_params.freq = blobmsg_get_u32(tb[CSA_FREQ]); -+ -+#define SET_CSA_SETTING(name, field, type) \ -+ do { \ -+ if (tb[name]) \ -+ css.field = blobmsg_get_ ## type(tb[name]); \ -+ } while(0) -+ -+ SET_CSA_SETTING(CSA_BCN_COUNT, cs_count, u32); -+ SET_CSA_SETTING(CSA_CENTER_FREQ1, freq_params.center_freq1, u32); -+ SET_CSA_SETTING(CSA_CENTER_FREQ2, freq_params.center_freq2, u32); -+ SET_CSA_SETTING(CSA_BANDWIDTH, freq_params.bandwidth, u32); -+ SET_CSA_SETTING(CSA_SEC_CHANNEL_OFFSET, freq_params.sec_channel_offset, u32); -+ SET_CSA_SETTING(CSA_HT, freq_params.ht_enabled, bool); -+ SET_CSA_SETTING(CSA_VHT, freq_params.vht_enabled, bool); -+ SET_CSA_SETTING(CSA_HE, freq_params.he_enabled, bool); -+ SET_CSA_SETTING(CSA_BLOCK_TX, block_tx, bool); -+ -+ css.freq_params.channel = hostapd_hw_get_channel(hapd, css.freq_params.freq); -+ if (!css.freq_params.channel) -+ return UBUS_STATUS_NOT_SUPPORTED; -+ -+ switch (css.freq_params.bandwidth) { -+ case 160: -+ chwidth = CHANWIDTH_160MHZ; -+ break; -+ case 80: -+ chwidth = css.freq_params.center_freq2 ? CHANWIDTH_80P80MHZ : CHANWIDTH_80MHZ; -+ break; -+ default: -+ chwidth = CHANWIDTH_USE_HT; -+ break; -+ } -+ -+ hostapd_set_freq_params(&css.freq_params, iconf->hw_mode, -+ css.freq_params.freq, -+ css.freq_params.channel, iconf->enable_edmg, -+ iconf->edmg_channel, -+ css.freq_params.ht_enabled, -+ css.freq_params.vht_enabled, -+ css.freq_params.he_enabled, -+ css.freq_params.eht_enabled, -+ css.freq_params.sec_channel_offset, -+ chwidth, seg0, seg1, -+ iconf->vht_capab, -+ mode ? &mode->he_capab[IEEE80211_MODE_AP] : -+ NULL, -+ mode ? &mode->eht_capab[IEEE80211_MODE_AP] : -+ NULL); -+ -+ for (i = 0; i < hapd->iface->num_bss; i++) { -+ struct hostapd_data *bss = hapd->iface->bss[i]; -+ -+ if (hostapd_switch_channel(bss, &css) != 0) -+ ret = UBUS_STATUS_NOT_SUPPORTED; -+ } -+ -+ if (!ret || !tb[CSA_FORCE] || !blobmsg_get_bool(tb[CSA_FORCE])) -+ return ret; -+ -+ freq_params = malloc(sizeof(*freq_params)); -+ memcpy(freq_params, &css.freq_params, sizeof(*freq_params)); -+ eloop_register_timeout(0, 1, switch_chan_fallback_cb, -+ hapd->iface, freq_params); -+ -+ return 0; -+#undef SET_CSA_SETTING -+} -+#endif -+ -+enum { -+ VENDOR_ELEMENTS, -+ __VENDOR_ELEMENTS_MAX -+}; -+ -+static const struct blobmsg_policy ve_policy[__VENDOR_ELEMENTS_MAX] = { -+ /* vendor elements are provided as hex-string */ -+ [VENDOR_ELEMENTS] = { "vendor_elements", BLOBMSG_TYPE_STRING }, -+}; -+ -+static int -+hostapd_vendor_elements(struct ubus_context *ctx, struct ubus_object *obj, -+ struct ubus_request_data *req, const char *method, -+ struct blob_attr *msg) -+{ -+ struct blob_attr *tb[__VENDOR_ELEMENTS_MAX]; -+ struct hostapd_data *hapd = get_hapd_from_object(obj); -+ struct hostapd_bss_config *bss = hapd->conf; -+ struct wpabuf *elems; -+ const char *pos; -+ size_t len; -+ -+ blobmsg_parse(ve_policy, __VENDOR_ELEMENTS_MAX, tb, -+ blob_data(msg), blob_len(msg)); -+ -+ if (!tb[VENDOR_ELEMENTS]) -+ return UBUS_STATUS_INVALID_ARGUMENT; -+ -+ pos = blobmsg_data(tb[VENDOR_ELEMENTS]); -+ len = os_strlen(pos); -+ if (len & 0x01) -+ return UBUS_STATUS_INVALID_ARGUMENT; -+ -+ len /= 2; -+ if (len == 0) { -+ wpabuf_free(bss->vendor_elements); -+ bss->vendor_elements = NULL; -+ return 0; -+ } -+ -+ elems = wpabuf_alloc(len); -+ if (elems == NULL) -+ return 1; -+ -+ if (hexstr2bin(pos, wpabuf_put(elems, len), len)) { -+ wpabuf_free(elems); -+ return UBUS_STATUS_INVALID_ARGUMENT; -+ } -+ -+ wpabuf_free(bss->vendor_elements); -+ bss->vendor_elements = elems; -+ -+ /* update beacons if vendor elements were set successfully */ -+ if (ieee802_11_update_beacons(hapd->iface) != 0) -+ return UBUS_STATUS_NOT_SUPPORTED; -+ return UBUS_STATUS_OK; -+} -+ -+static void -+hostapd_rrm_print_nr(struct hostapd_neighbor_entry *nr) -+{ -+ const u8 *data; -+ char *str; -+ int len; -+ -+ blobmsg_printf(&b, "", MACSTR, MAC2STR(nr->bssid)); -+ -+ str = blobmsg_alloc_string_buffer(&b, "", nr->ssid.ssid_len + 1); -+ memcpy(str, nr->ssid.ssid, nr->ssid.ssid_len); -+ str[nr->ssid.ssid_len] = 0; -+ blobmsg_add_string_buffer(&b); -+ -+ len = wpabuf_len(nr->nr); -+ str = blobmsg_alloc_string_buffer(&b, "", 2 * len + 1); -+ wpa_snprintf_hex(str, 2 * len + 1, wpabuf_head_u8(nr->nr), len); -+ blobmsg_add_string_buffer(&b); -+} -+ -+enum { -+ BSS_MGMT_EN_NEIGHBOR, -+ BSS_MGMT_EN_BEACON, -+ BSS_MGMT_EN_LINK_MEASUREMENT, -+#ifdef CONFIG_WNM_AP -+ BSS_MGMT_EN_BSS_TRANSITION, -+#endif -+ __BSS_MGMT_EN_MAX -+}; -+ -+static bool -+__hostapd_bss_mgmt_enable_f(struct hostapd_data *hapd, int flag) -+{ -+ struct hostapd_bss_config *bss = hapd->conf; -+ uint32_t flags; -+ -+ switch (flag) { -+ case BSS_MGMT_EN_NEIGHBOR: -+ if (bss->radio_measurements[0] & -+ WLAN_RRM_CAPS_NEIGHBOR_REPORT) -+ return false; -+ -+ bss->radio_measurements[0] |= -+ WLAN_RRM_CAPS_NEIGHBOR_REPORT; -+ hostapd_neighbor_set_own_report(hapd); -+ return true; -+ case BSS_MGMT_EN_BEACON: -+ flags = WLAN_RRM_CAPS_BEACON_REPORT_PASSIVE | -+ WLAN_RRM_CAPS_BEACON_REPORT_ACTIVE | -+ WLAN_RRM_CAPS_BEACON_REPORT_TABLE; -+ -+ if (bss->radio_measurements[0] & flags == flags) -+ return false; -+ -+ bss->radio_measurements[0] |= (u8) flags; -+ return true; -+ case BSS_MGMT_EN_LINK_MEASUREMENT: -+ flags = WLAN_RRM_CAPS_LINK_MEASUREMENT; -+ -+ if (bss->radio_measurements[0] & flags == flags) -+ return false; -+ -+ bss->radio_measurements[0] |= (u8) flags; -+ return true; -+#ifdef CONFIG_WNM_AP -+ case BSS_MGMT_EN_BSS_TRANSITION: -+ if (bss->bss_transition) -+ return false; -+ -+ bss->bss_transition = 1; -+ return true; -+#endif -+ } -+} -+ -+static void -+__hostapd_bss_mgmt_enable(struct hostapd_data *hapd, uint32_t flags) -+{ -+ bool update = false; -+ int i; -+ -+ for (i = 0; i < __BSS_MGMT_EN_MAX; i++) { -+ if (!(flags & (1 << i))) -+ continue; -+ -+ update |= __hostapd_bss_mgmt_enable_f(hapd, i); -+ } -+ -+ if (update) -+ ieee802_11_update_beacons(hapd->iface); -+} -+ -+ -+static const struct blobmsg_policy bss_mgmt_enable_policy[__BSS_MGMT_EN_MAX] = { -+ [BSS_MGMT_EN_NEIGHBOR] = { "neighbor_report", BLOBMSG_TYPE_BOOL }, -+ [BSS_MGMT_EN_BEACON] = { "beacon_report", BLOBMSG_TYPE_BOOL }, -+ [BSS_MGMT_EN_LINK_MEASUREMENT] = { "link_measurement", BLOBMSG_TYPE_BOOL }, -+#ifdef CONFIG_WNM_AP -+ [BSS_MGMT_EN_BSS_TRANSITION] = { "bss_transition", BLOBMSG_TYPE_BOOL }, -+#endif -+}; -+ -+static int -+hostapd_bss_mgmt_enable(struct ubus_context *ctx, struct ubus_object *obj, -+ struct ubus_request_data *req, const char *method, -+ struct blob_attr *msg) -+ -+{ -+ struct hostapd_data *hapd = get_hapd_from_object(obj); -+ struct blob_attr *tb[__BSS_MGMT_EN_MAX]; -+ struct blob_attr *cur; -+ uint32_t flags = 0; -+ int i; -+ bool neigh = false, beacon = false; -+ -+ blobmsg_parse(bss_mgmt_enable_policy, __BSS_MGMT_EN_MAX, tb, blob_data(msg), blob_len(msg)); -+ -+ for (i = 0; i < ARRAY_SIZE(tb); i++) { -+ if (!tb[i] || !blobmsg_get_bool(tb[i])) -+ continue; -+ -+ flags |= (1 << i); -+ } -+ -+ __hostapd_bss_mgmt_enable(hapd, flags); -+ -+ return 0; -+} -+ -+ -+static void -+hostapd_rrm_nr_enable(struct hostapd_data *hapd) -+{ -+ __hostapd_bss_mgmt_enable(hapd, 1 << BSS_MGMT_EN_NEIGHBOR); -+} -+ -+static int -+hostapd_rrm_nr_get_own(struct ubus_context *ctx, struct ubus_object *obj, -+ struct ubus_request_data *req, const char *method, -+ struct blob_attr *msg) -+{ -+ struct hostapd_data *hapd = get_hapd_from_object(obj); -+ struct hostapd_neighbor_entry *nr; -+ void *c; -+ -+ hostapd_rrm_nr_enable(hapd); -+ -+ nr = hostapd_neighbor_get(hapd, hapd->own_addr, NULL); -+ if (!nr) -+ return UBUS_STATUS_NOT_FOUND; -+ -+ blob_buf_init(&b, 0); -+ -+ c = blobmsg_open_array(&b, "value"); -+ hostapd_rrm_print_nr(nr); -+ blobmsg_close_array(&b, c); -+ -+ ubus_send_reply(ctx, req, b.head); -+ -+ return 0; -+} -+ -+static int -+hostapd_rrm_nr_list(struct ubus_context *ctx, struct ubus_object *obj, -+ struct ubus_request_data *req, const char *method, -+ struct blob_attr *msg) -+{ -+ struct hostapd_data *hapd = get_hapd_from_object(obj); -+ struct hostapd_neighbor_entry *nr; -+ void *c; -+ -+ hostapd_rrm_nr_enable(hapd); -+ blob_buf_init(&b, 0); -+ -+ c = blobmsg_open_array(&b, "list"); -+ dl_list_for_each(nr, &hapd->nr_db, struct hostapd_neighbor_entry, list) { -+ void *cur; -+ -+ if (!memcmp(nr->bssid, hapd->own_addr, ETH_ALEN)) -+ continue; -+ -+ cur = blobmsg_open_array(&b, NULL); -+ hostapd_rrm_print_nr(nr); -+ blobmsg_close_array(&b, cur); -+ } -+ blobmsg_close_array(&b, c); -+ -+ ubus_send_reply(ctx, req, b.head); -+ -+ return 0; -+} -+ -+enum { -+ NR_SET_LIST, -+ __NR_SET_LIST_MAX -+}; -+ -+static const struct blobmsg_policy nr_set_policy[__NR_SET_LIST_MAX] = { -+ [NR_SET_LIST] = { "list", BLOBMSG_TYPE_ARRAY }, -+}; -+ -+ -+static void -+hostapd_rrm_nr_clear(struct hostapd_data *hapd) -+{ -+ struct hostapd_neighbor_entry *nr; -+ -+restart: -+ dl_list_for_each(nr, &hapd->nr_db, struct hostapd_neighbor_entry, list) { -+ if (!memcmp(nr->bssid, hapd->own_addr, ETH_ALEN)) -+ continue; -+ -+ hostapd_neighbor_remove(hapd, nr->bssid, &nr->ssid); -+ goto restart; -+ } -+} -+ -+static int -+hostapd_rrm_nr_set(struct ubus_context *ctx, struct ubus_object *obj, -+ struct ubus_request_data *req, const char *method, -+ struct blob_attr *msg) -+{ -+ static const struct blobmsg_policy nr_e_policy[] = { -+ { .type = BLOBMSG_TYPE_STRING }, -+ { .type = BLOBMSG_TYPE_STRING }, -+ { .type = BLOBMSG_TYPE_STRING }, -+ }; -+ struct hostapd_data *hapd = get_hapd_from_object(obj); -+ struct blob_attr *tb_l[__NR_SET_LIST_MAX]; -+ struct blob_attr *tb[ARRAY_SIZE(nr_e_policy)]; -+ struct blob_attr *cur; -+ int rem; -+ -+ hostapd_rrm_nr_enable(hapd); -+ -+ blobmsg_parse(nr_set_policy, __NR_SET_LIST_MAX, tb_l, blob_data(msg), blob_len(msg)); -+ if (!tb_l[NR_SET_LIST]) -+ return UBUS_STATUS_INVALID_ARGUMENT; -+ -+ hostapd_rrm_nr_clear(hapd); -+ blobmsg_for_each_attr(cur, tb_l[NR_SET_LIST], rem) { -+ struct wpa_ssid_value ssid; -+ struct wpabuf *data; -+ u8 bssid[ETH_ALEN]; -+ char *s, *nr_s; -+ -+ blobmsg_parse_array(nr_e_policy, ARRAY_SIZE(nr_e_policy), tb, blobmsg_data(cur), blobmsg_data_len(cur)); -+ if (!tb[0] || !tb[1] || !tb[2]) -+ goto invalid; -+ -+ /* Neighbor Report binary */ -+ nr_s = blobmsg_get_string(tb[2]); -+ data = wpabuf_parse_bin(nr_s); -+ if (!data) -+ goto invalid; -+ -+ /* BSSID */ -+ s = blobmsg_get_string(tb[0]); -+ if (strlen(s) == 0) { -+ /* Copy BSSID from neighbor report */ -+ if (hwaddr_compact_aton(nr_s, bssid)) -+ goto invalid; -+ } else if (hwaddr_aton(s, bssid)) { -+ goto invalid; -+ } -+ -+ /* SSID */ -+ s = blobmsg_get_string(tb[1]); -+ if (strlen(s) == 0) { -+ /* Copy SSID from hostapd BSS conf */ -+ memcpy(&ssid, &hapd->conf->ssid, sizeof(ssid)); -+ } else { -+ ssid.ssid_len = strlen(s); -+ if (ssid.ssid_len > sizeof(ssid.ssid)) -+ goto invalid; -+ -+ memcpy(&ssid, s, ssid.ssid_len); -+ } -+ -+ hostapd_neighbor_set(hapd, bssid, &ssid, data, NULL, NULL, 0, 0); -+ wpabuf_free(data); -+ continue; -+ -+invalid: -+ return UBUS_STATUS_INVALID_ARGUMENT; -+ } -+ -+ return 0; -+} -+ -+enum { -+ BEACON_REQ_ADDR, -+ BEACON_REQ_MODE, -+ BEACON_REQ_OP_CLASS, -+ BEACON_REQ_CHANNEL, -+ BEACON_REQ_DURATION, -+ BEACON_REQ_BSSID, -+ BEACON_REQ_SSID, -+ __BEACON_REQ_MAX, -+}; -+ -+static const struct blobmsg_policy beacon_req_policy[__BEACON_REQ_MAX] = { -+ [BEACON_REQ_ADDR] = { "addr", BLOBMSG_TYPE_STRING }, -+ [BEACON_REQ_OP_CLASS] { "op_class", BLOBMSG_TYPE_INT32 }, -+ [BEACON_REQ_CHANNEL] { "channel", BLOBMSG_TYPE_INT32 }, -+ [BEACON_REQ_DURATION] { "duration", BLOBMSG_TYPE_INT32 }, -+ [BEACON_REQ_MODE] { "mode", BLOBMSG_TYPE_INT32 }, -+ [BEACON_REQ_BSSID] { "bssid", BLOBMSG_TYPE_STRING }, -+ [BEACON_REQ_SSID] { "ssid", BLOBMSG_TYPE_STRING }, -+}; -+ -+static int -+hostapd_rrm_beacon_req(struct ubus_context *ctx, struct ubus_object *obj, -+ struct ubus_request_data *ureq, const char *method, -+ struct blob_attr *msg) -+{ -+ struct hostapd_data *hapd = container_of(obj, struct hostapd_data, ubus.obj); -+ struct blob_attr *tb[__BEACON_REQ_MAX]; -+ struct blob_attr *cur; -+ struct wpabuf *req; -+ u8 bssid[ETH_ALEN] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }; -+ u8 addr[ETH_ALEN]; -+ int mode, rem, ret; -+ int buf_len = 13; -+ -+ blobmsg_parse(beacon_req_policy, __BEACON_REQ_MAX, tb, blob_data(msg), blob_len(msg)); -+ -+ if (!tb[BEACON_REQ_ADDR] || !tb[BEACON_REQ_MODE] || !tb[BEACON_REQ_DURATION] || -+ !tb[BEACON_REQ_OP_CLASS] || !tb[BEACON_REQ_CHANNEL]) -+ return UBUS_STATUS_INVALID_ARGUMENT; -+ -+ if (tb[BEACON_REQ_SSID]) -+ buf_len += blobmsg_data_len(tb[BEACON_REQ_SSID]) + 2 - 1; -+ -+ mode = blobmsg_get_u32(tb[BEACON_REQ_MODE]); -+ if (hwaddr_aton(blobmsg_data(tb[BEACON_REQ_ADDR]), addr)) -+ return UBUS_STATUS_INVALID_ARGUMENT; -+ -+ if (tb[BEACON_REQ_BSSID] && -+ hwaddr_aton(blobmsg_data(tb[BEACON_REQ_BSSID]), bssid)) -+ return UBUS_STATUS_INVALID_ARGUMENT; -+ -+ req = wpabuf_alloc(buf_len); -+ if (!req) -+ return UBUS_STATUS_UNKNOWN_ERROR; -+ -+ /* 1: regulatory class */ -+ wpabuf_put_u8(req, blobmsg_get_u32(tb[BEACON_REQ_OP_CLASS])); -+ -+ /* 2: channel number */ -+ wpabuf_put_u8(req, blobmsg_get_u32(tb[BEACON_REQ_CHANNEL])); -+ -+ /* 3-4: randomization interval */ -+ wpabuf_put_le16(req, 0); -+ -+ /* 5-6: duration */ -+ wpabuf_put_le16(req, blobmsg_get_u32(tb[BEACON_REQ_DURATION])); -+ -+ /* 7: mode */ -+ wpabuf_put_u8(req, blobmsg_get_u32(tb[BEACON_REQ_MODE])); -+ -+ /* 8-13: BSSID */ -+ wpabuf_put_data(req, bssid, ETH_ALEN); -+ -+ if ((cur = tb[BEACON_REQ_SSID]) != NULL) { -+ wpabuf_put_u8(req, WLAN_EID_SSID); -+ wpabuf_put_u8(req, blobmsg_data_len(cur) - 1); -+ wpabuf_put_data(req, blobmsg_data(cur), blobmsg_data_len(cur) - 1); -+ } -+ -+ ret = hostapd_send_beacon_req(hapd, addr, 0, req); -+ if (ret < 0) -+ return -ret; -+ -+ return 0; -+} -+ -+enum { -+ LM_REQ_ADDR, -+ LM_REQ_TX_POWER_USED, -+ LM_REQ_TX_POWER_MAX, -+ __LM_REQ_MAX, -+}; -+ -+static const struct blobmsg_policy lm_req_policy[__LM_REQ_MAX] = { -+ [LM_REQ_ADDR] = { "addr", BLOBMSG_TYPE_STRING }, -+ [LM_REQ_TX_POWER_USED] = { "tx-power-used", BLOBMSG_TYPE_INT32 }, -+ [LM_REQ_TX_POWER_MAX] = { "tx-power-max", BLOBMSG_TYPE_INT32 }, -+}; -+ -+static int -+hostapd_rrm_lm_req(struct ubus_context *ctx, struct ubus_object *obj, -+ struct ubus_request_data *ureq, const char *method, -+ struct blob_attr *msg) -+{ -+ struct hostapd_data *hapd = container_of(obj, struct hostapd_data, ubus.obj); -+ struct blob_attr *tb[__LM_REQ_MAX]; -+ struct wpabuf *buf; -+ u8 addr[ETH_ALEN]; -+ int ret; -+ int8_t txp_used, txp_max; -+ -+ txp_used = 0; -+ txp_max = 0; -+ -+ blobmsg_parse(lm_req_policy, __LM_REQ_MAX, tb, blob_data(msg), blob_len(msg)); -+ -+ if (!tb[LM_REQ_ADDR]) -+ return UBUS_STATUS_INVALID_ARGUMENT; -+ -+ if (tb[LM_REQ_TX_POWER_USED]) -+ txp_used = (int8_t) blobmsg_get_u32(tb[LM_REQ_TX_POWER_USED]); -+ -+ if (tb[LM_REQ_TX_POWER_MAX]) -+ txp_max = (int8_t) blobmsg_get_u32(tb[LM_REQ_TX_POWER_MAX]); -+ -+ if (hwaddr_aton(blobmsg_data(tb[LM_REQ_ADDR]), addr)) -+ return UBUS_STATUS_INVALID_ARGUMENT; -+ -+ buf = wpabuf_alloc(5); -+ if (!buf) -+ return UBUS_STATUS_UNKNOWN_ERROR; -+ -+ wpabuf_put_u8(buf, WLAN_ACTION_RADIO_MEASUREMENT); -+ wpabuf_put_u8(buf, WLAN_RRM_LINK_MEASUREMENT_REQUEST); -+ wpabuf_put_u8(buf, 1); -+ /* TX-Power used */ -+ wpabuf_put_u8(buf, txp_used); -+ /* Max TX Power */ -+ wpabuf_put_u8(buf, txp_max); -+ -+ ret = hostapd_drv_send_action(hapd, hapd->iface->freq, 0, addr, -+ wpabuf_head(buf), wpabuf_len(buf)); -+ -+ wpabuf_free(buf); -+ if (ret < 0) -+ return -ret; -+ -+ return 0; -+} -+ -+ -+void hostapd_ubus_handle_link_measurement(struct hostapd_data *hapd, const u8 *data, size_t len) -+{ -+ const struct ieee80211_mgmt *mgmt = (const struct ieee80211_mgmt *) data; -+ const u8 *pos, *end; -+ u8 token; -+ -+ end = data + len; -+ token = mgmt->u.action.u.rrm.dialog_token; -+ pos = mgmt->u.action.u.rrm.variable; -+ -+ if (end - pos < 8) -+ return; -+ -+ if (!hapd->ubus.obj.has_subscribers) -+ return; -+ -+ blob_buf_init(&b, 0); -+ blobmsg_add_macaddr(&b, "address", mgmt->sa); -+ blobmsg_add_u16(&b, "dialog-token", token); -+ blobmsg_add_u16(&b, "rx-antenna-id", pos[4]); -+ blobmsg_add_u16(&b, "tx-antenna-id", pos[5]); -+ blobmsg_add_u16(&b, "rcpi", pos[6]); -+ blobmsg_add_u16(&b, "rsni", pos[7]); -+ -+ ubus_notify(ctx, &hapd->ubus.obj, "link-measurement-report", b.head, -1); -+} -+ -+ -+#ifdef CONFIG_WNM_AP -+ -+static int -+hostapd_bss_tr_send(struct hostapd_data *hapd, u8 *addr, bool disassoc_imminent, bool abridged, -+ u16 disassoc_timer, u8 validity_period, u8 dialog_token, -+ struct blob_attr *neighbors, u8 mbo_reason, u8 cell_pref, u8 reassoc_delay) -+{ -+ struct blob_attr *cur; -+ struct sta_info *sta; -+ int nr_len = 0; -+ int rem; -+ u8 *nr = NULL; -+ u8 req_mode = 0; -+ u8 mbo[10]; -+ size_t mbo_len = 0; -+ -+ sta = ap_get_sta(hapd, addr); -+ if (!sta) -+ return UBUS_STATUS_NOT_FOUND; -+ -+ if (neighbors) { -+ u8 *nr_cur; -+ -+ if (blobmsg_check_array(neighbors, -+ BLOBMSG_TYPE_STRING) < 0) -+ return UBUS_STATUS_INVALID_ARGUMENT; -+ -+ blobmsg_for_each_attr(cur, neighbors, rem) { -+ int len = strlen(blobmsg_get_string(cur)); -+ -+ if (len % 2) -+ return UBUS_STATUS_INVALID_ARGUMENT; -+ -+ nr_len += (len / 2) + 2; -+ } -+ -+ if (nr_len) { -+ nr = os_zalloc(nr_len); -+ if (!nr) -+ return UBUS_STATUS_UNKNOWN_ERROR; -+ } -+ -+ nr_cur = nr; -+ blobmsg_for_each_attr(cur, neighbors, rem) { -+ int len = strlen(blobmsg_get_string(cur)) / 2; -+ -+ *nr_cur++ = WLAN_EID_NEIGHBOR_REPORT; -+ *nr_cur++ = (u8) len; -+ if (hexstr2bin(blobmsg_data(cur), nr_cur, len)) { -+ free(nr); -+ return UBUS_STATUS_INVALID_ARGUMENT; -+ } -+ -+ nr_cur += len; -+ } -+ } -+ -+ if (nr) -+ req_mode |= WNM_BSS_TM_REQ_PREF_CAND_LIST_INCLUDED; -+ -+ if (abridged) -+ req_mode |= WNM_BSS_TM_REQ_ABRIDGED; -+ -+ if (disassoc_imminent) -+ req_mode |= WNM_BSS_TM_REQ_DISASSOC_IMMINENT; -+ -+#ifdef CONFIG_MBO -+ u8 *mbo_pos = mbo; -+ -+ if (mbo_reason > MBO_TRANSITION_REASON_PREMIUM_AP) -+ return UBUS_STATUS_INVALID_ARGUMENT; -+ -+ if (cell_pref != 0 && cell_pref != 1 && cell_pref != 255) -+ return UBUS_STATUS_INVALID_ARGUMENT; -+ -+ if (reassoc_delay > 65535 || (reassoc_delay && !disassoc_imminent)) -+ return UBUS_STATUS_INVALID_ARGUMENT; -+ -+ *mbo_pos++ = MBO_ATTR_ID_TRANSITION_REASON; -+ *mbo_pos++ = 1; -+ *mbo_pos++ = mbo_reason; -+ *mbo_pos++ = MBO_ATTR_ID_CELL_DATA_PREF; -+ *mbo_pos++ = 1; -+ *mbo_pos++ = cell_pref; -+ -+ if (reassoc_delay) { -+ *mbo_pos++ = MBO_ATTR_ID_ASSOC_RETRY_DELAY; -+ *mbo_pos++ = 2; -+ WPA_PUT_LE16(mbo_pos, reassoc_delay); -+ mbo_pos += 2; -+ } -+ -+ mbo_len = mbo_pos - mbo; -+#endif -+ -+ if (wnm_send_bss_tm_req(hapd, sta, req_mode, disassoc_timer, validity_period, NULL, -+ dialog_token, NULL, nr, nr_len, mbo_len ? mbo : NULL, mbo_len)) -+ return UBUS_STATUS_UNKNOWN_ERROR; -+ -+ return 0; -+} -+ -+enum { -+ BSS_TR_ADDR, -+ BSS_TR_DA_IMMINENT, -+ BSS_TR_DA_TIMER, -+ BSS_TR_VALID_PERIOD, -+ BSS_TR_NEIGHBORS, -+ BSS_TR_ABRIDGED, -+ BSS_TR_DIALOG_TOKEN, -+#ifdef CONFIG_MBO -+ BSS_TR_MBO_REASON, -+ BSS_TR_CELL_PREF, -+ BSS_TR_REASSOC_DELAY, -+#endif -+ __BSS_TR_DISASSOC_MAX -+}; -+ -+static const struct blobmsg_policy bss_tr_policy[__BSS_TR_DISASSOC_MAX] = { -+ [BSS_TR_ADDR] = { "addr", BLOBMSG_TYPE_STRING }, -+ [BSS_TR_DA_IMMINENT] = { "disassociation_imminent", BLOBMSG_TYPE_BOOL }, -+ [BSS_TR_DA_TIMER] = { "disassociation_timer", BLOBMSG_TYPE_INT32 }, -+ [BSS_TR_VALID_PERIOD] = { "validity_period", BLOBMSG_TYPE_INT32 }, -+ [BSS_TR_NEIGHBORS] = { "neighbors", BLOBMSG_TYPE_ARRAY }, -+ [BSS_TR_ABRIDGED] = { "abridged", BLOBMSG_TYPE_BOOL }, -+ [BSS_TR_DIALOG_TOKEN] = { "dialog_token", BLOBMSG_TYPE_INT32 }, -+#ifdef CONFIG_MBO -+ [BSS_TR_MBO_REASON] = { "mbo_reason", BLOBMSG_TYPE_INT32 }, -+ [BSS_TR_CELL_PREF] = { "cell_pref", BLOBMSG_TYPE_INT32 }, -+ [BSS_TR_REASSOC_DELAY] = { "reassoc_delay", BLOBMSG_TYPE_INT32 }, -+#endif -+}; -+ -+static int -+hostapd_bss_transition_request(struct ubus_context *ctx, struct ubus_object *obj, -+ struct ubus_request_data *ureq, const char *method, -+ struct blob_attr *msg) -+{ -+ struct hostapd_data *hapd = container_of(obj, struct hostapd_data, ubus.obj); -+ struct blob_attr *tb[__BSS_TR_DISASSOC_MAX]; -+ struct sta_info *sta; -+ u32 da_timer = 0; -+ u32 valid_period = 0; -+ u8 addr[ETH_ALEN]; -+ u32 dialog_token = 1; -+ bool abridged; -+ bool da_imminent; -+ u8 mbo_reason; -+ u8 cell_pref; -+ u8 reassoc_delay; -+ -+ blobmsg_parse(bss_tr_policy, __BSS_TR_DISASSOC_MAX, tb, blob_data(msg), blob_len(msg)); -+ -+ if (!tb[BSS_TR_ADDR]) -+ return UBUS_STATUS_INVALID_ARGUMENT; -+ -+ if (hwaddr_aton(blobmsg_data(tb[BSS_TR_ADDR]), addr)) -+ return UBUS_STATUS_INVALID_ARGUMENT; -+ -+ if (tb[BSS_TR_DA_TIMER]) -+ da_timer = blobmsg_get_u32(tb[BSS_TR_DA_TIMER]); -+ -+ if (tb[BSS_TR_VALID_PERIOD]) -+ valid_period = blobmsg_get_u32(tb[BSS_TR_VALID_PERIOD]); -+ -+ if (tb[BSS_TR_DIALOG_TOKEN]) -+ dialog_token = blobmsg_get_u32(tb[BSS_TR_DIALOG_TOKEN]); -+ -+ da_imminent = !!(tb[BSS_TR_DA_IMMINENT] && blobmsg_get_bool(tb[BSS_TR_DA_IMMINENT])); -+ abridged = !!(tb[BSS_TR_ABRIDGED] && blobmsg_get_bool(tb[BSS_TR_ABRIDGED])); -+ -+#ifdef CONFIG_MBO -+ if (tb[BSS_TR_MBO_REASON]) -+ mbo_reason = blobmsg_get_u32(tb[BSS_TR_MBO_REASON]); -+ -+ if (tb[BSS_TR_CELL_PREF]) -+ cell_pref = blobmsg_get_u32(tb[BSS_TR_CELL_PREF]); -+ -+ if (tb[BSS_TR_REASSOC_DELAY]) -+ reassoc_delay = blobmsg_get_u32(tb[BSS_TR_REASSOC_DELAY]); -+#endif -+ -+ return hostapd_bss_tr_send(hapd, addr, da_imminent, abridged, da_timer, valid_period, -+ dialog_token, tb[BSS_TR_NEIGHBORS], mbo_reason, cell_pref, reassoc_delay); -+} -+#endif -+ -+#ifdef CONFIG_AIRTIME_POLICY -+enum { -+ UPDATE_AIRTIME_STA, -+ UPDATE_AIRTIME_WEIGHT, -+ __UPDATE_AIRTIME_MAX, -+}; -+ -+ -+static const struct blobmsg_policy airtime_policy[__UPDATE_AIRTIME_MAX] = { -+ [UPDATE_AIRTIME_STA] = { "sta", BLOBMSG_TYPE_STRING }, -+ [UPDATE_AIRTIME_WEIGHT] = { "weight", BLOBMSG_TYPE_INT32 }, -+}; -+ -+static int -+hostapd_bss_update_airtime(struct ubus_context *ctx, struct ubus_object *obj, -+ struct ubus_request_data *ureq, const char *method, -+ struct blob_attr *msg) -+{ -+ struct hostapd_data *hapd = container_of(obj, struct hostapd_data, ubus.obj); -+ struct blob_attr *tb[__UPDATE_AIRTIME_MAX]; -+ struct sta_info *sta = NULL; -+ u8 addr[ETH_ALEN]; -+ int weight; -+ -+ blobmsg_parse(airtime_policy, __UPDATE_AIRTIME_MAX, tb, blob_data(msg), blob_len(msg)); -+ -+ if (!tb[UPDATE_AIRTIME_WEIGHT]) -+ return UBUS_STATUS_INVALID_ARGUMENT; -+ -+ weight = blobmsg_get_u32(tb[UPDATE_AIRTIME_WEIGHT]); -+ -+ if (!tb[UPDATE_AIRTIME_STA]) { -+ if (!weight) -+ return UBUS_STATUS_INVALID_ARGUMENT; -+ -+ hapd->conf->airtime_weight = weight; -+ return 0; -+ } -+ -+ if (hwaddr_aton(blobmsg_data(tb[UPDATE_AIRTIME_STA]), addr)) -+ return UBUS_STATUS_INVALID_ARGUMENT; -+ -+ sta = ap_get_sta(hapd, addr); -+ if (!sta) -+ return UBUS_STATUS_NOT_FOUND; -+ -+ sta->dyn_airtime_weight = weight; -+ airtime_policy_new_sta(hapd, sta); -+ -+ return 0; -+} -+#endif -+ -+#ifdef CONFIG_TAXONOMY -+static const struct blobmsg_policy addr_policy[] = { -+ { "address", BLOBMSG_TYPE_STRING } -+}; -+ -+static bool -+hostapd_add_b64_data(const char *name, const struct wpabuf *buf) -+{ -+ char *str; -+ -+ if (!buf) -+ return false; -+ -+ str = blobmsg_alloc_string_buffer(&b, name, B64_ENCODE_LEN(wpabuf_len(buf))); -+ b64_encode(wpabuf_head(buf), wpabuf_len(buf), str, B64_ENCODE_LEN(wpabuf_len(buf))); -+ blobmsg_add_string_buffer(&b); -+ -+ return true; -+} -+ -+static int -+hostapd_bss_get_sta_ies(struct ubus_context *ctx, struct ubus_object *obj, -+ struct ubus_request_data *req, const char *method, -+ struct blob_attr *msg) -+{ -+ struct hostapd_data *hapd = container_of(obj, struct hostapd_data, ubus.obj); -+ struct blob_attr *tb; -+ struct sta_info *sta; -+ u8 addr[ETH_ALEN]; -+ -+ blobmsg_parse(addr_policy, 1, &tb, blobmsg_data(msg), blobmsg_len(msg)); -+ -+ if (!tb || hwaddr_aton(blobmsg_data(tb), addr)) -+ return UBUS_STATUS_INVALID_ARGUMENT; -+ -+ sta = ap_get_sta(hapd, addr); -+ if (!sta || (!sta->probe_ie_taxonomy && !sta->assoc_ie_taxonomy)) -+ return UBUS_STATUS_NOT_FOUND; -+ -+ blob_buf_init(&b, 0); -+ hostapd_add_b64_data("probe_ie", sta->probe_ie_taxonomy); -+ hostapd_add_b64_data("assoc_ie", sta->assoc_ie_taxonomy); -+ ubus_send_reply(ctx, req, b.head); -+ -+ return 0; -+} -+#endif -+ -+ -+static const struct ubus_method bss_methods[] = { -+ UBUS_METHOD_NOARG("reload", hostapd_bss_reload), -+ UBUS_METHOD_NOARG("get_clients", hostapd_bss_get_clients), -+#ifdef CONFIG_TAXONOMY -+ UBUS_METHOD("get_sta_ies", hostapd_bss_get_sta_ies, addr_policy), -+#endif -+ UBUS_METHOD_NOARG("get_status", hostapd_bss_get_status), -+ UBUS_METHOD("del_client", hostapd_bss_del_client, del_policy), -+#ifdef CONFIG_AIRTIME_POLICY -+ UBUS_METHOD("update_airtime", hostapd_bss_update_airtime, airtime_policy), -+#endif -+ UBUS_METHOD_NOARG("list_bans", hostapd_bss_list_bans), -+#ifdef CONFIG_WPS -+ UBUS_METHOD_NOARG("wps_start", hostapd_bss_wps_start), -+ UBUS_METHOD_NOARG("wps_status", hostapd_bss_wps_status), -+ UBUS_METHOD_NOARG("wps_cancel", hostapd_bss_wps_cancel), -+#endif -+ UBUS_METHOD_NOARG("update_beacon", hostapd_bss_update_beacon), -+ UBUS_METHOD_NOARG("get_features", hostapd_bss_get_features), -+#ifdef NEED_AP_MLME -+ UBUS_METHOD("switch_chan", hostapd_switch_chan, csa_policy), -+#endif -+ UBUS_METHOD("set_vendor_elements", hostapd_vendor_elements, ve_policy), -+ UBUS_METHOD("notify_response", hostapd_notify_response, notify_policy), -+ UBUS_METHOD("bss_mgmt_enable", hostapd_bss_mgmt_enable, bss_mgmt_enable_policy), -+ UBUS_METHOD_NOARG("rrm_nr_get_own", hostapd_rrm_nr_get_own), -+ UBUS_METHOD_NOARG("rrm_nr_list", hostapd_rrm_nr_list), -+ UBUS_METHOD("rrm_nr_set", hostapd_rrm_nr_set, nr_set_policy), -+ UBUS_METHOD("rrm_beacon_req", hostapd_rrm_beacon_req, beacon_req_policy), -+ UBUS_METHOD("link_measurement_req", hostapd_rrm_lm_req, lm_req_policy), -+#ifdef CONFIG_WNM_AP -+ UBUS_METHOD("bss_transition_request", hostapd_bss_transition_request, bss_tr_policy), -+#endif -+}; -+ -+static struct ubus_object_type bss_object_type = -+ UBUS_OBJECT_TYPE("hostapd_bss", bss_methods); -+ -+static int avl_compare_macaddr(const void *k1, const void *k2, void *ptr) -+{ -+ return memcmp(k1, k2, ETH_ALEN); -+} -+ -+void hostapd_ubus_add_bss(struct hostapd_data *hapd) -+{ -+ struct ubus_object *obj = &hapd->ubus.obj; -+ char *name; -+ int ret; -+ -+#ifdef CONFIG_MESH -+ if (hapd->conf->mesh & MESH_ENABLED) -+ return; -+#endif -+ -+ if (!hostapd_ubus_init()) -+ return; -+ -+ if (asprintf(&name, "hostapd.%s", hapd->conf->iface) < 0) -+ return; -+ -+ avl_init(&hapd->ubus.banned, avl_compare_macaddr, false, NULL); -+ obj->name = name; -+ obj->type = &bss_object_type; -+ obj->methods = bss_object_type.methods; -+ obj->n_methods = bss_object_type.n_methods; -+ ret = ubus_add_object(ctx, obj); -+ hostapd_ubus_ref_inc(); -+} -+ -+void hostapd_ubus_free_bss(struct hostapd_data *hapd) -+{ -+ struct ubus_object *obj = &hapd->ubus.obj; -+ char *name = (char *) obj->name; -+ -+#ifdef CONFIG_MESH -+ if (hapd->conf->mesh & MESH_ENABLED) -+ return; -+#endif -+ -+ if (!ctx) -+ return; -+ -+ if (obj->id) { -+ ubus_remove_object(ctx, obj); -+ hostapd_ubus_ref_dec(); -+ } -+ -+ free(name); -+} -+ -+static void -+hostapd_ubus_vlan_action(struct hostapd_data *hapd, struct hostapd_vlan *vlan, -+ const char *action) -+{ -+ struct vlan_description *desc = &vlan->vlan_desc; -+ void *c; -+ int i; -+ -+ if (!hapd->ubus.obj.has_subscribers) -+ return; -+ -+ blob_buf_init(&b, 0); -+ blobmsg_add_string(&b, "ifname", vlan->ifname); -+ blobmsg_add_string(&b, "bridge", vlan->bridge); -+ blobmsg_add_u32(&b, "vlan_id", vlan->vlan_id); -+ -+ if (desc->notempty) { -+ blobmsg_add_u32(&b, "untagged", desc->untagged); -+ c = blobmsg_open_array(&b, "tagged"); -+ for (i = 0; i < ARRAY_SIZE(desc->tagged) && desc->tagged[i]; i++) -+ blobmsg_add_u32(&b, "", desc->tagged[i]); -+ blobmsg_close_array(&b, c); -+ } -+ -+ ubus_notify(ctx, &hapd->ubus.obj, action, b.head, -1); -+} -+ -+void hostapd_ubus_add_vlan(struct hostapd_data *hapd, struct hostapd_vlan *vlan) -+{ -+ hostapd_ubus_vlan_action(hapd, vlan, "vlan_add"); -+} -+ -+void hostapd_ubus_remove_vlan(struct hostapd_data *hapd, struct hostapd_vlan *vlan) -+{ -+ hostapd_ubus_vlan_action(hapd, vlan, "vlan_remove"); -+} -+ -+struct ubus_event_req { -+ struct ubus_notify_request nreq; -+ int resp; -+}; -+ -+static void -+ubus_event_cb(struct ubus_notify_request *req, int idx, int ret) -+{ -+ struct ubus_event_req *ureq = container_of(req, struct ubus_event_req, nreq); -+ -+ ureq->resp = ret; -+} -+ -+int hostapd_ubus_handle_event(struct hostapd_data *hapd, struct hostapd_ubus_request *req) -+{ -+ struct ubus_banned_client *ban; -+ const char *types[HOSTAPD_UBUS_TYPE_MAX] = { -+ [HOSTAPD_UBUS_PROBE_REQ] = "probe", -+ [HOSTAPD_UBUS_AUTH_REQ] = "auth", -+ [HOSTAPD_UBUS_ASSOC_REQ] = "assoc", -+ }; -+ const char *type = "mgmt"; -+ struct ubus_event_req ureq = {}; -+ const u8 *addr; -+ -+ if (req->mgmt_frame) -+ addr = req->mgmt_frame->sa; -+ else -+ addr = req->addr; -+ -+ ban = avl_find_element(&hapd->ubus.banned, addr, ban, avl); -+ if (ban) -+ return WLAN_STATUS_AP_UNABLE_TO_HANDLE_NEW_STA; -+ -+ if (!hapd->ubus.obj.has_subscribers) -+ return WLAN_STATUS_SUCCESS; -+ -+ if (req->type < ARRAY_SIZE(types)) -+ type = types[req->type]; -+ -+ blob_buf_init(&b, 0); -+ blobmsg_add_macaddr(&b, "address", addr); -+ if (req->mgmt_frame) -+ blobmsg_add_macaddr(&b, "target", req->mgmt_frame->da); -+ if (req->ssi_signal) -+ blobmsg_add_u32(&b, "signal", req->ssi_signal); -+ blobmsg_add_u32(&b, "freq", hapd->iface->freq); -+ -+ if (req->elems) { -+ if(req->elems->ht_capabilities) -+ { -+ struct ieee80211_ht_capabilities *ht_capabilities; -+ void *ht_cap, *ht_cap_mcs_set, *mcs_set; -+ -+ -+ ht_capabilities = (struct ieee80211_ht_capabilities*) req->elems->ht_capabilities; -+ ht_cap = blobmsg_open_table(&b, "ht_capabilities"); -+ blobmsg_add_u16(&b, "ht_capabilities_info", ht_capabilities->ht_capabilities_info); -+ ht_cap_mcs_set = blobmsg_open_table(&b, "supported_mcs_set"); -+ blobmsg_add_u16(&b, "a_mpdu_params", ht_capabilities->a_mpdu_params); -+ blobmsg_add_u16(&b, "ht_extended_capabilities", ht_capabilities->ht_extended_capabilities); -+ blobmsg_add_u32(&b, "tx_bf_capability_info", ht_capabilities->tx_bf_capability_info); -+ blobmsg_add_u16(&b, "asel_capabilities", ht_capabilities->asel_capabilities); -+ mcs_set = blobmsg_open_array(&b, "supported_mcs_set"); -+ for (int i = 0; i < 16; i++) { -+ blobmsg_add_u16(&b, NULL, (u16) ht_capabilities->supported_mcs_set[i]); -+ } -+ blobmsg_close_array(&b, mcs_set); -+ blobmsg_close_table(&b, ht_cap_mcs_set); -+ blobmsg_close_table(&b, ht_cap); -+ } -+ if(req->elems->vht_capabilities) -+ { -+ struct ieee80211_vht_capabilities *vht_capabilities; -+ void *vht_cap, *vht_cap_mcs_set; -+ -+ vht_capabilities = (struct ieee80211_vht_capabilities*) req->elems->vht_capabilities; -+ vht_cap = blobmsg_open_table(&b, "vht_capabilities"); -+ blobmsg_add_u32(&b, "vht_capabilities_info", vht_capabilities->vht_capabilities_info); -+ vht_cap_mcs_set = blobmsg_open_table(&b, "vht_supported_mcs_set"); -+ blobmsg_add_u16(&b, "rx_map", vht_capabilities->vht_supported_mcs_set.rx_map); -+ blobmsg_add_u16(&b, "rx_highest", vht_capabilities->vht_supported_mcs_set.rx_highest); -+ blobmsg_add_u16(&b, "tx_map", vht_capabilities->vht_supported_mcs_set.tx_map); -+ blobmsg_add_u16(&b, "tx_highest", vht_capabilities->vht_supported_mcs_set.tx_highest); -+ blobmsg_close_table(&b, vht_cap_mcs_set); -+ blobmsg_close_table(&b, vht_cap); -+ } -+ } -+ -+ if (!hapd->ubus.notify_response) { -+ ubus_notify(ctx, &hapd->ubus.obj, type, b.head, -1); -+ return WLAN_STATUS_SUCCESS; -+ } -+ -+ if (ubus_notify_async(ctx, &hapd->ubus.obj, type, b.head, &ureq.nreq)) -+ return WLAN_STATUS_SUCCESS; -+ -+ ureq.nreq.status_cb = ubus_event_cb; -+ ubus_complete_request(ctx, &ureq.nreq.req, 100); -+ -+ if (ureq.resp) -+ return ureq.resp; -+ -+ return WLAN_STATUS_SUCCESS; -+} -+ -+void hostapd_ubus_notify(struct hostapd_data *hapd, const char *type, const u8 *addr) -+{ -+ if (!hapd->ubus.obj.has_subscribers) -+ return; -+ -+ if (!addr) -+ return; -+ -+ blob_buf_init(&b, 0); -+ blobmsg_add_macaddr(&b, "address", addr); -+ -+ ubus_notify(ctx, &hapd->ubus.obj, type, b.head, -1); -+} -+ -+void hostapd_ubus_notify_authorized(struct hostapd_data *hapd, struct sta_info *sta, -+ const char *auth_alg) -+{ -+ if (!hapd->ubus.obj.has_subscribers) -+ return; -+ -+ blob_buf_init(&b, 0); -+ blobmsg_add_macaddr(&b, "address", sta->addr); -+ if (auth_alg) -+ blobmsg_add_string(&b, "auth-alg", auth_alg); -+ -+ ubus_notify(ctx, &hapd->ubus.obj, "sta-authorized", b.head, -1); -+} -+ -+void hostapd_ubus_notify_beacon_report( -+ struct hostapd_data *hapd, const u8 *addr, u8 token, u8 rep_mode, -+ struct rrm_measurement_beacon_report *rep, size_t len) -+{ -+ if (!hapd->ubus.obj.has_subscribers) -+ return; -+ -+ if (!addr || !rep) -+ return; -+ -+ blob_buf_init(&b, 0); -+ blobmsg_add_macaddr(&b, "address", addr); -+ blobmsg_add_u16(&b, "op-class", rep->op_class); -+ blobmsg_add_u16(&b, "channel", rep->channel); -+ blobmsg_add_u64(&b, "start-time", rep->start_time); -+ blobmsg_add_u16(&b, "duration", rep->duration); -+ blobmsg_add_u16(&b, "report-info", rep->report_info); -+ blobmsg_add_u16(&b, "rcpi", rep->rcpi); -+ blobmsg_add_u16(&b, "rsni", rep->rsni); -+ blobmsg_add_macaddr(&b, "bssid", rep->bssid); -+ blobmsg_add_u16(&b, "antenna-id", rep->antenna_id); -+ blobmsg_add_u16(&b, "parent-tsf", rep->parent_tsf); -+ blobmsg_add_u16(&b, "rep-mode", rep_mode); -+ -+ ubus_notify(ctx, &hapd->ubus.obj, "beacon-report", b.head, -1); -+} -+ -+void hostapd_ubus_notify_radar_detected(struct hostapd_iface *iface, int frequency, -+ int chan_width, int cf1, int cf2) -+{ -+ struct hostapd_data *hapd; -+ int i; -+ -+ blob_buf_init(&b, 0); -+ blobmsg_add_u16(&b, "frequency", frequency); -+ blobmsg_add_u16(&b, "width", chan_width); -+ blobmsg_add_u16(&b, "center1", cf1); -+ blobmsg_add_u16(&b, "center2", cf2); -+ -+ for (i = 0; i < iface->num_bss; i++) { -+ hapd = iface->bss[i]; -+ ubus_notify(ctx, &hapd->ubus.obj, "radar-detected", b.head, -1); -+ } -+} -+ -+#ifdef CONFIG_WNM_AP -+static void hostapd_ubus_notify_bss_transition_add_candidate_list( -+ const u8 *candidate_list, u16 candidate_list_len) -+{ -+ char *cl_str; -+ int i; -+ -+ if (candidate_list_len == 0) -+ return; -+ -+ cl_str = blobmsg_alloc_string_buffer(&b, "candidate-list", candidate_list_len * 2 + 1); -+ for (i = 0; i < candidate_list_len; i++) -+ snprintf(&cl_str[i*2], 3, "%02X", candidate_list[i]); -+ blobmsg_add_string_buffer(&b); -+ -+} -+#endif -+ -+void hostapd_ubus_notify_bss_transition_response( -+ struct hostapd_data *hapd, const u8 *addr, u8 dialog_token, u8 status_code, -+ u8 bss_termination_delay, const u8 *target_bssid, -+ const u8 *candidate_list, u16 candidate_list_len) -+{ -+#ifdef CONFIG_WNM_AP -+ u16 i; -+ -+ if (!hapd->ubus.obj.has_subscribers) -+ return; -+ -+ if (!addr) -+ return; -+ -+ blob_buf_init(&b, 0); -+ blobmsg_add_macaddr(&b, "address", addr); -+ blobmsg_add_u8(&b, "dialog-token", dialog_token); -+ blobmsg_add_u8(&b, "status-code", status_code); -+ blobmsg_add_u8(&b, "bss-termination-delay", bss_termination_delay); -+ if (target_bssid) -+ blobmsg_add_macaddr(&b, "target-bssid", target_bssid); -+ -+ hostapd_ubus_notify_bss_transition_add_candidate_list(candidate_list, candidate_list_len); -+ -+ ubus_notify(ctx, &hapd->ubus.obj, "bss-transition-response", b.head, -1); -+#endif -+} -+ -+int hostapd_ubus_notify_bss_transition_query( -+ struct hostapd_data *hapd, const u8 *addr, u8 dialog_token, u8 reason, -+ const u8 *candidate_list, u16 candidate_list_len) -+{ -+#ifdef CONFIG_WNM_AP -+ struct ubus_event_req ureq = {}; -+ char *cl_str; -+ u16 i; -+ -+ if (!hapd->ubus.obj.has_subscribers) -+ return 0; -+ -+ if (!addr) -+ return 0; -+ -+ blob_buf_init(&b, 0); -+ blobmsg_add_macaddr(&b, "address", addr); -+ blobmsg_add_u8(&b, "dialog-token", dialog_token); -+ blobmsg_add_u8(&b, "reason", reason); -+ hostapd_ubus_notify_bss_transition_add_candidate_list(candidate_list, candidate_list_len); -+ -+ if (!hapd->ubus.notify_response) { -+ ubus_notify(ctx, &hapd->ubus.obj, "bss-transition-query", b.head, -1); -+ return 0; -+ } -+ -+ if (ubus_notify_async(ctx, &hapd->ubus.obj, "bss-transition-query", b.head, &ureq.nreq)) -+ return 0; -+ -+ ureq.nreq.status_cb = ubus_event_cb; -+ ubus_complete_request(ctx, &ureq.nreq.req, 100); -+ -+ return ureq.resp; -+#endif -+} -diff --git a/package/network/services/hostapd/src/src/ap/ubus.h b/package/network/services/hostapd/src/src/ap/ubus.h -new file mode 100644 -index 0000000000..b0f7c44ab5 ---- /dev/null -+++ b/package/network/services/hostapd/src/src/ap/ubus.h -@@ -0,0 +1,154 @@ -+/* -+ * hostapd / ubus support -+ * Copyright (c) 2013, Felix Fietkau -+ * -+ * This software may be distributed under the terms of the BSD license. -+ * See README for more details. -+ */ -+#ifndef __HOSTAPD_UBUS_H -+#define __HOSTAPD_UBUS_H -+ -+enum hostapd_ubus_event_type { -+ HOSTAPD_UBUS_PROBE_REQ, -+ HOSTAPD_UBUS_AUTH_REQ, -+ HOSTAPD_UBUS_ASSOC_REQ, -+ HOSTAPD_UBUS_TYPE_MAX -+}; -+ -+struct hostapd_ubus_request { -+ enum hostapd_ubus_event_type type; -+ const struct ieee80211_mgmt *mgmt_frame; -+ const struct ieee802_11_elems *elems; -+ int ssi_signal; /* dBm */ -+ const u8 *addr; -+}; -+ -+struct hostapd_iface; -+struct hostapd_data; -+struct hapd_interfaces; -+struct rrm_measurement_beacon_report; -+ -+#ifdef UBUS_SUPPORT -+ -+#include -+#include -+ -+struct hostapd_ubus_bss { -+ struct ubus_object obj; -+ struct avl_tree banned; -+ int notify_response; -+}; -+ -+void hostapd_ubus_add_iface(struct hostapd_iface *iface); -+void hostapd_ubus_free_iface(struct hostapd_iface *iface); -+void hostapd_ubus_add_bss(struct hostapd_data *hapd); -+void hostapd_ubus_free_bss(struct hostapd_data *hapd); -+void hostapd_ubus_add_vlan(struct hostapd_data *hapd, struct hostapd_vlan *vlan); -+void hostapd_ubus_remove_vlan(struct hostapd_data *hapd, struct hostapd_vlan *vlan); -+ -+int hostapd_ubus_handle_event(struct hostapd_data *hapd, struct hostapd_ubus_request *req); -+void hostapd_ubus_handle_link_measurement(struct hostapd_data *hapd, const u8 *data, size_t len); -+void hostapd_ubus_notify(struct hostapd_data *hapd, const char *type, const u8 *mac); -+void hostapd_ubus_notify_beacon_report(struct hostapd_data *hapd, -+ const u8 *addr, u8 token, u8 rep_mode, -+ struct rrm_measurement_beacon_report *rep, -+ size_t len); -+void hostapd_ubus_notify_radar_detected(struct hostapd_iface *iface, int frequency, -+ int chan_width, int cf1, int cf2); -+ -+void hostapd_ubus_notify_bss_transition_response( -+ struct hostapd_data *hapd, const u8 *addr, u8 dialog_token, u8 status_code, -+ u8 bss_termination_delay, const u8 *target_bssid, -+ const u8 *candidate_list, u16 candidate_list_len); -+void hostapd_ubus_add(struct hapd_interfaces *interfaces); -+void hostapd_ubus_free(struct hapd_interfaces *interfaces); -+int hostapd_ubus_notify_bss_transition_query( -+ struct hostapd_data *hapd, const u8 *addr, u8 dialog_token, u8 reason, -+ const u8 *candidate_list, u16 candidate_list_len); -+void hostapd_ubus_notify_authorized(struct hostapd_data *hapd, struct sta_info *sta, -+ const char *auth_alg); -+ -+#else -+ -+struct hostapd_ubus_bss {}; -+ -+static inline void hostapd_ubus_add_iface(struct hostapd_iface *iface) -+{ -+} -+ -+static inline void hostapd_ubus_free_iface(struct hostapd_iface *iface) -+{ -+} -+ -+static inline void hostapd_ubus_add_bss(struct hostapd_data *hapd) -+{ -+} -+ -+static inline void hostapd_ubus_free_bss(struct hostapd_data *hapd) -+{ -+} -+ -+static inline void hostapd_ubus_add_vlan(struct hostapd_data *hapd, struct hostapd_vlan *vlan) -+{ -+} -+ -+static inline void hostapd_ubus_remove_vlan(struct hostapd_data *hapd, struct hostapd_vlan *vlan) -+{ -+} -+ -+static inline int hostapd_ubus_handle_event(struct hostapd_data *hapd, struct hostapd_ubus_request *req) -+{ -+ return 0; -+} -+ -+static inline void hostapd_ubus_handle_link_measurement(struct hostapd_data *hapd, const u8 *data, size_t len) -+{ -+} -+ -+static inline void hostapd_ubus_notify(struct hostapd_data *hapd, const char *type, const u8 *mac) -+{ -+} -+ -+static inline void hostapd_ubus_notify_beacon_report(struct hostapd_data *hapd, -+ const u8 *addr, u8 token, -+ u8 rep_mode, -+ struct rrm_measurement_beacon_report *rep, -+ size_t len) -+{ -+} -+static inline void hostapd_ubus_notify_radar_detected(struct hostapd_iface *iface, int frequency, -+ int chan_width, int cf1, int cf2) -+{ -+} -+ -+static inline void hostapd_ubus_notify_bss_transition_response( -+ struct hostapd_data *hapd, const u8 *addr, u8 dialog_token, u8 status_code, -+ u8 bss_termination_delay, const u8 *target_bssid, -+ const u8 *candidate_list, u16 candidate_list_len) -+{ -+} -+ -+static inline void hostapd_ubus_add(struct hapd_interfaces *interfaces) -+{ -+} -+ -+static inline void hostapd_ubus_free(struct hapd_interfaces *interfaces) -+{ -+} -+ -+static inline int hostapd_ubus_notify_bss_transition_query( -+ struct hostapd_data *hapd, const u8 *addr, u8 dialog_token, u8 reason, -+ const u8 *candidate_list, u16 candidate_list_len) -+{ -+ return 0; -+} -+ -+static inline void -+hostapd_ubus_notify_authorized(struct hostapd_data *hapd, struct sta_info *sta, -+ const char *auth_alg) -+{ -+} -+ -+#endif -+ -+#endif -diff --git a/package/network/services/hostapd/src/src/ap/ucode.c b/package/network/services/hostapd/src/src/ap/ucode.c -new file mode 100644 -index 0000000000..053171b142 ---- /dev/null -+++ b/package/network/services/hostapd/src/src/ap/ucode.c -@@ -0,0 +1,545 @@ -+#include -+ -+#include "utils/includes.h" -+#include "utils/common.h" -+#include "utils/ucode.h" -+#include "hostapd.h" -+#include "beacon.h" -+#include "hw_features.h" -+#include "ap_drv_ops.h" -+#include -+ -+static uc_resource_type_t *global_type, *bss_type, *iface_type; -+static struct hapd_interfaces *interfaces; -+static uc_value_t *global, *bss_registry, *iface_registry; -+static uc_vm_t *vm; -+ -+static uc_value_t * -+hostapd_ucode_bss_get_uval(struct hostapd_data *hapd) -+{ -+ uc_value_t *val; -+ -+ if (hapd->ucode.idx) -+ return wpa_ucode_registry_get(bss_registry, hapd->ucode.idx); -+ -+ val = uc_resource_new(bss_type, hapd); -+ hapd->ucode.idx = wpa_ucode_registry_add(bss_registry, val); -+ -+ return val; -+} -+ -+static uc_value_t * -+hostapd_ucode_iface_get_uval(struct hostapd_iface *hapd) -+{ -+ uc_value_t *val; -+ -+ if (hapd->ucode.idx) -+ return wpa_ucode_registry_get(iface_registry, hapd->ucode.idx); -+ -+ val = uc_resource_new(iface_type, hapd); -+ hapd->ucode.idx = wpa_ucode_registry_add(iface_registry, val); -+ -+ return val; -+} -+ -+static void -+hostapd_ucode_update_bss_list(struct hostapd_iface *iface, uc_value_t *if_bss, uc_value_t *bss) -+{ -+ uc_value_t *list; -+ int i; -+ -+ list = ucv_array_new(vm); -+ for (i = 0; i < iface->num_bss; i++) { -+ struct hostapd_data *hapd = iface->bss[i]; -+ uc_value_t *val = hostapd_ucode_bss_get_uval(hapd); -+ -+ ucv_array_set(list, i, ucv_get(ucv_string_new(hapd->conf->iface))); -+ ucv_object_add(bss, hapd->conf->iface, ucv_get(val)); -+ } -+ ucv_object_add(if_bss, iface->phy, ucv_get(list)); -+} -+ -+static void -+hostapd_ucode_update_interfaces(void) -+{ -+ uc_value_t *ifs = ucv_object_new(vm); -+ uc_value_t *if_bss = ucv_array_new(vm); -+ uc_value_t *bss = ucv_object_new(vm); -+ int i; -+ -+ for (i = 0; i < interfaces->count; i++) { -+ struct hostapd_iface *iface = interfaces->iface[i]; -+ -+ ucv_object_add(ifs, iface->phy, ucv_get(hostapd_ucode_iface_get_uval(iface))); -+ hostapd_ucode_update_bss_list(iface, if_bss, bss); -+ } -+ -+ ucv_object_add(ucv_prototype_get(global), "interfaces", ucv_get(ifs)); -+ ucv_object_add(ucv_prototype_get(global), "interface_bss", ucv_get(if_bss)); -+ ucv_object_add(ucv_prototype_get(global), "bss", ucv_get(bss)); -+ ucv_gc(vm); -+} -+ -+static uc_value_t * -+uc_hostapd_add_iface(uc_vm_t *vm, size_t nargs) -+{ -+ uc_value_t *iface = uc_fn_arg(0); -+ int ret; -+ -+ if (ucv_type(iface) != UC_STRING) -+ return ucv_int64_new(-1); -+ -+ ret = hostapd_add_iface(interfaces, ucv_string_get(iface)); -+ hostapd_ucode_update_interfaces(); -+ -+ return ucv_int64_new(ret); -+} -+ -+static uc_value_t * -+uc_hostapd_remove_iface(uc_vm_t *vm, size_t nargs) -+{ -+ uc_value_t *iface = uc_fn_arg(0); -+ -+ if (ucv_type(iface) != UC_STRING) -+ return NULL; -+ -+ hostapd_remove_iface(interfaces, ucv_string_get(iface)); -+ hostapd_ucode_update_interfaces(); -+ -+ return NULL; -+} -+ -+static uc_value_t * -+uc_hostapd_bss_set_config(uc_vm_t *vm, size_t nargs) -+{ -+ struct hostapd_data *hapd = uc_fn_thisval("hostapd.bss"); -+ struct hostapd_bss_config *old_bss; -+ struct hostapd_iface *iface; -+ struct hostapd_config *conf; -+ uc_value_t *file = uc_fn_arg(0); -+ uc_value_t *index = uc_fn_arg(1); -+ unsigned int i, idx = 0; -+ int ret = -1; -+ -+ if (!hapd || ucv_type(file) != UC_STRING) -+ goto out; -+ -+ if (ucv_type(index) == UC_INTEGER) -+ idx = ucv_int64_get(index); -+ -+ iface = hapd->iface; -+ conf = interfaces->config_read_cb(ucv_string_get(file)); -+ if (!conf || idx > conf->num_bss || !conf->bss[idx]) -+ goto out; -+ -+ hostapd_bss_deinit_no_free(hapd); -+ hostapd_drv_stop_ap(hapd); -+ hostapd_free_hapd_data(hapd); -+ -+ old_bss = hapd->conf; -+ for (i = 0; i < iface->conf->num_bss; i++) -+ if (iface->conf->bss[i] == hapd->conf) -+ iface->conf->bss[i] = conf->bss[idx]; -+ hapd->conf = conf->bss[idx]; -+ conf->bss[idx] = old_bss; -+ hostapd_config_free(conf); -+ -+ hostapd_setup_bss(hapd, hapd == iface->bss[0], !iface->conf->mbssid); -+ -+ ret = 0; -+ -+out: -+ return ucv_int64_new(ret); -+} -+ -+static void -+hostapd_remove_iface_bss_conf(struct hostapd_config *iconf, -+ struct hostapd_bss_config *conf) -+{ -+ int i; -+ -+ for (i = 0; i < iconf->num_bss; i++) -+ if (iconf->bss[i] == conf) -+ break; -+ -+ if (i == iconf->num_bss) -+ return; -+ -+ for (i++; i < iconf->num_bss; i++) -+ iconf->bss[i - 1] = iconf->bss[i]; -+ iconf->num_bss--; -+} -+ -+ -+static uc_value_t * -+uc_hostapd_bss_delete(uc_vm_t *vm, size_t nargs) -+{ -+ struct hostapd_data *hapd = uc_fn_thisval("hostapd.bss"); -+ struct hostapd_iface *iface; -+ int i, idx; -+ -+ if (!hapd || hapd == hapd->iface->bss[0]) -+ return NULL; -+ -+ iface = hapd->iface; -+ for (idx = 0; idx < iface->num_bss; idx++) -+ if (iface->bss[idx] == hapd) -+ break; -+ -+ if (idx == iface->num_bss) -+ return NULL; -+ -+ for (i = idx + 1; i < iface->num_bss; i++) -+ iface->bss[i - 1] = iface->bss[i]; -+ iface->num_bss--; -+ -+ hostapd_drv_stop_ap(hapd); -+ hostapd_bss_deinit(hapd); -+ hostapd_remove_iface_bss_conf(iface->conf, hapd->conf); -+ hostapd_config_free_bss(hapd->conf); -+ os_free(hapd); -+ -+ hostapd_ucode_update_interfaces(); -+ ucv_gc(vm); -+ -+ return NULL; -+} -+ -+static uc_value_t * -+uc_hostapd_iface_add_bss(uc_vm_t *vm, size_t nargs) -+{ -+ struct hostapd_iface *iface = uc_fn_thisval("hostapd.iface"); -+ struct hostapd_bss_config *bss; -+ struct hostapd_config *conf; -+ struct hostapd_data *hapd; -+ uc_value_t *file = uc_fn_arg(0); -+ uc_value_t *index = uc_fn_arg(1); -+ unsigned int idx = 0; -+ uc_value_t *ret = NULL; -+ -+ if (!iface || ucv_type(file) != UC_STRING) -+ goto out; -+ -+ if (ucv_type(index) == UC_INTEGER) -+ idx = ucv_int64_get(index); -+ -+ conf = interfaces->config_read_cb(ucv_string_get(file)); -+ if (!conf || idx > conf->num_bss || !conf->bss[idx]) -+ goto out; -+ -+ bss = conf->bss[idx]; -+ hapd = hostapd_alloc_bss_data(iface, iface->conf, bss); -+ if (!hapd) -+ goto out; -+ -+ hapd->driver = iface->bss[0]->driver; -+ hapd->drv_priv = iface->bss[0]->drv_priv; -+ if (interfaces->ctrl_iface_init && -+ interfaces->ctrl_iface_init(hapd) < 0) -+ goto free_hapd; -+ -+ if (iface->state == HAPD_IFACE_ENABLED && -+ hostapd_setup_bss(hapd, -1, true)) -+ goto deinit_ctrl; -+ -+ iface->bss = os_realloc_array(iface->bss, iface->num_bss + 1, -+ sizeof(*iface->bss)); -+ iface->bss[iface->num_bss++] = hapd; -+ -+ iface->conf->bss = os_realloc_array(iface->conf->bss, -+ iface->conf->num_bss + 1, -+ sizeof(*iface->conf->bss)); -+ iface->conf->bss[iface->conf->num_bss] = bss; -+ conf->bss[idx] = NULL; -+ ret = hostapd_ucode_bss_get_uval(hapd); -+ hostapd_ucode_update_interfaces(); -+ goto out; -+ -+deinit_ctrl: -+ if (interfaces->ctrl_iface_deinit) -+ interfaces->ctrl_iface_deinit(hapd); -+free_hapd: -+ hostapd_free_hapd_data(hapd); -+ os_free(hapd); -+out: -+ hostapd_config_free(conf); -+ return ret; -+} -+ -+static uc_value_t * -+uc_hostapd_bss_ctrl(uc_vm_t *vm, size_t nargs) -+{ -+ struct hostapd_data *hapd = uc_fn_thisval("hostapd.bss"); -+ uc_value_t *arg = uc_fn_arg(0); -+ struct sockaddr_storage from = {}; -+ static char reply[4096]; -+ int reply_len; -+ -+ if (!hapd || !interfaces->ctrl_iface_recv || -+ ucv_type(arg) != UC_STRING) -+ return NULL; -+ -+ reply_len = interfaces->ctrl_iface_recv(hapd, ucv_string_get(arg), -+ reply, sizeof(reply), -+ &from, sizeof(from)); -+ if (reply_len < 0) -+ return NULL; -+ -+ if (reply_len && reply[reply_len - 1] == '\n') -+ reply_len--; -+ -+ return ucv_string_new_length(reply, reply_len); -+} -+ -+static uc_value_t * -+uc_hostapd_iface_stop(uc_vm_t *vm, size_t nargs) -+{ -+ struct hostapd_iface *iface = uc_fn_thisval("hostapd.iface"); -+ int i; -+ -+ for (i = 0; i < iface->num_bss; i++) { -+ struct hostapd_data *hapd = iface->bss[i]; -+ -+ hostapd_drv_stop_ap(hapd); -+ hapd->started = 0; -+ } -+} -+ -+static uc_value_t * -+uc_hostapd_iface_start(uc_vm_t *vm, size_t nargs) -+{ -+ struct hostapd_iface *iface = uc_fn_thisval("hostapd.iface"); -+ uc_value_t *info = uc_fn_arg(0); -+ struct hostapd_config *conf; -+ uint64_t intval; -+ int i; -+ -+ if (!iface) -+ return NULL; -+ -+ if (!info) -+ goto out; -+ -+ if (ucv_type(info) != UC_OBJECT) -+ return NULL; -+ -+ conf = iface->conf; -+ if ((intval = ucv_int64_get(ucv_object_get(info, "op_class", NULL))) && !errno) -+ conf->op_class = intval; -+ if ((intval = ucv_int64_get(ucv_object_get(info, "hw_mode", NULL))) && !errno) -+ conf->hw_mode = intval; -+ if ((intval = ucv_int64_get(ucv_object_get(info, "channel", NULL))) && !errno) -+ conf->channel = intval; -+ if ((intval = ucv_int64_get(ucv_object_get(info, "sec_channel", NULL))) && !errno) -+ conf->secondary_channel = intval; -+#ifdef CONFIG_IEEE80211AC -+ if ((intval = ucv_int64_get(ucv_object_get(info, "center_seg0_idx", NULL))) && !errno) { -+ conf->vht_oper_centr_freq_seg0_idx = intval; -+#ifdef CONFIG_IEEE80211AX -+ conf->he_oper_centr_freq_seg0_idx = intval; -+#endif -+#ifdef CONFIG_IEEE80211BE -+ conf->eht_oper_centr_freq_seg0_idx = intval; -+#endif -+ } -+ if ((intval = ucv_int64_get(ucv_object_get(info, "center_seg1_idx", NULL))) && !errno) { -+ conf->vht_oper_centr_freq_seg1_idx = intval; -+#ifdef CONFIG_IEEE80211AX -+ conf->he_oper_centr_freq_seg1_idx = intval; -+#endif -+#ifdef CONFIG_IEEE80211BE -+ conf->eht_oper_centr_freq_seg1_idx = intval; -+#endif -+ } -+ intval = ucv_int64_get(ucv_object_get(info, "oper_chwidth", NULL)); -+ if (!errno) { -+ conf->vht_oper_chwidth = intval; -+#ifdef CONFIG_IEEE80211AX -+ conf->he_oper_chwidth = intval; -+#endif -+#ifdef CONFIG_IEEE80211BE -+ conf->eht_oper_chwidth = intval; -+#endif -+ } -+#endif -+ -+out: -+ if (conf->channel) -+ iface->freq = hostapd_hw_get_freq(iface->bss[0], conf->channel); -+ -+ for (i = 0; i < iface->num_bss; i++) { -+ struct hostapd_data *hapd = iface->bss[i]; -+ int ret; -+ -+ hapd->started = 1; -+ hostapd_set_freq(hapd, conf->hw_mode, iface->freq, -+ conf->channel, -+ conf->enable_edmg, -+ conf->edmg_channel, -+ conf->ieee80211n, -+ conf->ieee80211ac, -+ conf->ieee80211ax, -+ conf->ieee80211be, -+ conf->secondary_channel, -+ hostapd_get_oper_chwidth(conf), -+ hostapd_get_oper_centr_freq_seg0_idx(conf), -+ hostapd_get_oper_centr_freq_seg1_idx(conf)); -+ -+ ieee802_11_set_beacon(hapd); -+ } -+ -+ return ucv_boolean_new(true); -+} -+ -+static uc_value_t * -+uc_hostapd_iface_switch_channel(uc_vm_t *vm, size_t nargs) -+{ -+ struct hostapd_iface *iface = uc_fn_thisval("hostapd.iface"); -+ uc_value_t *info = uc_fn_arg(0); -+ struct hostapd_config *conf; -+ struct csa_settings csa = {}; -+ uint64_t intval; -+ int i, ret = 0; -+ -+ if (!iface || ucv_type(info) != UC_OBJECT) -+ return NULL; -+ -+ conf = iface->conf; -+ if ((intval = ucv_int64_get(ucv_object_get(info, "csa_count", NULL))) && !errno) -+ csa.cs_count = intval; -+ if ((intval = ucv_int64_get(ucv_object_get(info, "sec_channel", NULL))) && !errno) -+ csa.freq_params.sec_channel_offset = intval; -+ -+ csa.freq_params.ht_enabled = conf->ieee80211n; -+ csa.freq_params.vht_enabled = conf->ieee80211ac; -+ csa.freq_params.he_enabled = conf->ieee80211ax; -+#ifdef CONFIG_IEEE80211BE -+ csa.freq_params.eht_enabled = conf->ieee80211be; -+#endif -+ intval = ucv_int64_get(ucv_object_get(info, "oper_chwidth", NULL)); -+ if (errno) -+ intval = hostapd_get_oper_chwidth(conf); -+ if (intval) -+ csa.freq_params.bandwidth = 40 << intval; -+ else -+ csa.freq_params.bandwidth = csa.freq_params.sec_channel_offset ? 40 : 20; -+ -+ if ((intval = ucv_int64_get(ucv_object_get(info, "frequency", NULL))) && !errno) -+ csa.freq_params.freq = intval; -+ if ((intval = ucv_int64_get(ucv_object_get(info, "center_freq1", NULL))) && !errno) -+ csa.freq_params.center_freq1 = intval; -+ if ((intval = ucv_int64_get(ucv_object_get(info, "center_freq2", NULL))) && !errno) -+ csa.freq_params.center_freq2 = intval; -+ -+ for (i = 0; i < iface->num_bss; i++) -+ ret = hostapd_switch_channel(iface->bss[i], &csa); -+ -+ return ucv_boolean_new(!ret); -+} -+ -+int hostapd_ucode_init(struct hapd_interfaces *ifaces) -+{ -+ static const uc_function_list_t global_fns[] = { -+ { "printf", uc_wpa_printf }, -+ { "getpid", uc_wpa_getpid }, -+ { "sha1", uc_wpa_sha1 }, -+ { "freq_info", uc_wpa_freq_info }, -+ { "add_iface", uc_hostapd_add_iface }, -+ { "remove_iface", uc_hostapd_remove_iface }, -+ }; -+ static const uc_function_list_t bss_fns[] = { -+ { "ctrl", uc_hostapd_bss_ctrl }, -+ { "set_config", uc_hostapd_bss_set_config }, -+ { "delete", uc_hostapd_bss_delete }, -+ }; -+ static const uc_function_list_t iface_fns[] = { -+ { "add_bss", uc_hostapd_iface_add_bss }, -+ { "stop", uc_hostapd_iface_stop }, -+ { "start", uc_hostapd_iface_start }, -+ { "switch_channel", uc_hostapd_iface_switch_channel }, -+ }; -+ uc_value_t *data, *proto; -+ -+ interfaces = ifaces; -+ vm = wpa_ucode_create_vm(); -+ -+ global_type = uc_type_declare(vm, "hostapd.global", global_fns, NULL); -+ bss_type = uc_type_declare(vm, "hostapd.bss", bss_fns, NULL); -+ iface_type = uc_type_declare(vm, "hostapd.iface", iface_fns, NULL); -+ -+ bss_registry = ucv_array_new(vm); -+ uc_vm_registry_set(vm, "hostap.bss_registry", bss_registry); -+ -+ iface_registry = ucv_array_new(vm); -+ uc_vm_registry_set(vm, "hostap.iface_registry", iface_registry); -+ -+ global = wpa_ucode_global_init("hostapd", global_type); -+ -+ if (wpa_ucode_run(HOSTAPD_UC_PATH "hostapd.uc")) -+ goto free_vm; -+ ucv_gc(vm); -+ -+ return 0; -+ -+free_vm: -+ wpa_ucode_free_vm(); -+ return -1; -+} -+ -+void hostapd_ucode_free(void) -+{ -+ if (wpa_ucode_call_prepare("shutdown") == 0) -+ ucv_put(wpa_ucode_call(0)); -+ wpa_ucode_free_vm(); -+} -+ -+void hostapd_ucode_free_iface(struct hostapd_iface *iface) -+{ -+ wpa_ucode_registry_remove(iface_registry, iface->ucode.idx); -+} -+ -+void hostapd_ucode_add_bss(struct hostapd_data *hapd) -+{ -+ uc_value_t *val; -+ -+ if (wpa_ucode_call_prepare("bss_add")) -+ return; -+ -+ val = hostapd_ucode_bss_get_uval(hapd); -+ uc_value_push(ucv_get(ucv_string_new(hapd->conf->iface))); -+ uc_value_push(ucv_get(val)); -+ ucv_put(wpa_ucode_call(2)); -+ ucv_gc(vm); -+} -+ -+void hostapd_ucode_reload_bss(struct hostapd_data *hapd) -+{ -+ uc_value_t *val; -+ -+ if (wpa_ucode_call_prepare("bss_reload")) -+ return; -+ -+ val = hostapd_ucode_bss_get_uval(hapd); -+ uc_value_push(ucv_get(ucv_string_new(hapd->conf->iface))); -+ uc_value_push(ucv_get(val)); -+ ucv_put(wpa_ucode_call(2)); -+ ucv_gc(vm); -+} -+ -+void hostapd_ucode_free_bss(struct hostapd_data *hapd) -+{ -+ uc_value_t *val; -+ -+ val = wpa_ucode_registry_remove(bss_registry, hapd->ucode.idx); -+ if (!val) -+ return; -+ -+ hapd->ucode.idx = 0; -+ if (wpa_ucode_call_prepare("bss_remove")) -+ return; -+ -+ uc_value_push(ucv_string_new(hapd->conf->iface)); -+ uc_value_push(ucv_get(val)); -+ ucv_put(wpa_ucode_call(2)); -+ ucv_gc(vm); -+} -diff --git a/package/network/services/hostapd/src/src/ap/ucode.h b/package/network/services/hostapd/src/src/ap/ucode.h -new file mode 100644 -index 0000000000..d00b787169 ---- /dev/null -+++ b/package/network/services/hostapd/src/src/ap/ucode.h -@@ -0,0 +1,54 @@ -+#ifndef __HOSTAPD_AP_UCODE_H -+#define __HOSTAPD_AP_UCODE_H -+ -+#include "utils/ucode.h" -+ -+struct hostapd_data; -+ -+struct hostapd_ucode_bss { -+#ifdef UCODE_SUPPORT -+ int idx; -+#endif -+}; -+ -+struct hostapd_ucode_iface { -+#ifdef UCODE_SUPPORT -+ int idx; -+#endif -+}; -+ -+#ifdef UCODE_SUPPORT -+ -+int hostapd_ucode_init(struct hapd_interfaces *ifaces); -+ -+void hostapd_ucode_free(void); -+void hostapd_ucode_free_iface(struct hostapd_iface *iface); -+void hostapd_ucode_add_bss(struct hostapd_data *hapd); -+void hostapd_ucode_free_bss(struct hostapd_data *hapd); -+void hostapd_ucode_reload_bss(struct hostapd_data *hapd); -+ -+#else -+ -+static inline int hostapd_ucode_init(struct hapd_interfaces *ifaces) -+{ -+ return -EINVAL; -+} -+static inline void hostapd_ucode_free(void) -+{ -+} -+static inline void hostapd_ucode_free_iface(struct hostapd_iface *iface) -+{ -+} -+static inline void hostapd_ucode_reload_bss(struct hostapd_data *hapd) -+{ -+} -+static inline void hostapd_ucode_add_bss(struct hostapd_data *hapd) -+{ -+} -+static inline void hostapd_ucode_free_bss(struct hostapd_data *hapd) -+{ -+} -+ -+#endif -+ -+#endif -diff --git a/package/network/services/hostapd/src/src/utils/build_features.h b/package/network/services/hostapd/src/src/utils/build_features.h -new file mode 100644 -index 0000000000..553769eceb ---- /dev/null -+++ b/package/network/services/hostapd/src/src/utils/build_features.h -@@ -0,0 +1,65 @@ -+#ifndef BUILD_FEATURES_H -+#define BUILD_FEATURES_H -+ -+static inline int has_feature(const char *feat) -+{ -+#if defined(IEEE8021X_EAPOL) || (defined(HOSTAPD) && !defined(CONFIG_NO_RADIUS)) -+ if (!strcmp(feat, "eap")) -+ return 1; -+#endif -+#ifdef CONFIG_IEEE80211AC -+ if (!strcmp(feat, "11ac")) -+ return 1; -+#endif -+#ifdef CONFIG_IEEE80211AX -+ if (!strcmp(feat, "11ax")) -+ return 1; -+#endif -+#ifdef CONFIG_IEEE80211R -+ if (!strcmp(feat, "11r")) -+ return 1; -+#endif -+#ifdef CONFIG_ACS -+ if (!strcmp(feat, "acs")) -+ return 1; -+#endif -+#ifdef CONFIG_SAE -+ if (!strcmp(feat, "sae")) -+ return 1; -+#endif -+#ifdef CONFIG_OWE -+ if (!strcmp(feat, "owe")) -+ return 1; -+#endif -+#ifdef CONFIG_SUITEB192 -+ if (!strcmp(feat, "suiteb192")) -+ return 1; -+#endif -+#ifdef CONFIG_WEP -+ if (!strcmp(feat, "wep")) -+ return 1; -+#endif -+#ifdef CONFIG_HS20 -+ if (!strcmp(feat, "hs20")) -+ return 1; -+#endif -+#ifdef CONFIG_WPS -+ if (!strcmp(feat, "wps")) -+ return 1; -+#endif -+#ifdef CONFIG_FILS -+ if (!strcmp(feat, "fils")) -+ return 1; -+#endif -+#ifdef CONFIG_OCV -+ if (!strcmp(feat, "ocv")) -+ return 1; -+#endif -+#ifdef CONFIG_MESH -+ if (!strcmp(feat, "mesh")) -+ return 1; -+#endif -+ return 0; -+} -+ -+#endif /* BUILD_FEATURES_H */ -diff --git a/package/network/services/hostapd/src/src/utils/ucode.c b/package/network/services/hostapd/src/src/utils/ucode.c -new file mode 100644 -index 0000000000..44169f0bf0 ---- /dev/null -+++ b/package/network/services/hostapd/src/src/utils/ucode.c -@@ -0,0 +1,326 @@ -+#include -+#include "ucode.h" -+#include "utils/eloop.h" -+#include "crypto/crypto.h" -+#include "crypto/sha1.h" -+#include "common/ieee802_11_common.h" -+#include -+#include -+ -+static uc_value_t *registry; -+static uc_vm_t vm; -+static struct uloop_timeout gc_timer; -+ -+static void uc_gc_timer(struct uloop_timeout *timeout) -+{ -+ ucv_gc(&vm); -+} -+ -+uc_value_t *uc_wpa_printf(uc_vm_t *vm, size_t nargs) -+{ -+ uc_value_t *level = uc_fn_arg(0); -+ uc_value_t *ret, **args; -+ uc_cfn_ptr_t _sprintf; -+ int l = MSG_INFO; -+ int i, start = 0; -+ -+ _sprintf = uc_stdlib_function("sprintf"); -+ if (!sprintf) -+ return NULL; -+ -+ if (ucv_type(level) == UC_INTEGER) { -+ l = ucv_int64_get(level); -+ start++; -+ } -+ -+ if (nargs <= start) -+ return NULL; -+ -+ ret = _sprintf(vm, nargs - start); -+ if (ucv_type(ret) != UC_STRING) -+ return NULL; -+ -+ wpa_printf(l, "%s", ucv_string_get(ret)); -+ ucv_put(ret); -+ -+ return NULL; -+} -+ -+uc_value_t *uc_wpa_freq_info(uc_vm_t *vm, size_t nargs) -+{ -+ uc_value_t *freq = uc_fn_arg(0); -+ uc_value_t *sec = uc_fn_arg(1); -+ int width = ucv_uint64_get(uc_fn_arg(2)); -+ int freq_val, center_idx, center_ofs; -+ enum oper_chan_width chanwidth; -+ enum hostapd_hw_mode hw_mode; -+ u8 op_class, channel, tmp_channel; -+ const char *modestr; -+ int sec_channel = 0; -+ uc_value_t *ret; -+ -+ if (ucv_type(freq) != UC_INTEGER) -+ return NULL; -+ -+ freq_val = ucv_int64_get(freq); -+ if (ucv_type(sec) == UC_INTEGER) -+ sec_channel = ucv_int64_get(sec); -+ else if (sec) -+ return NULL; -+ else if (freq_val > 4000) -+ sec_channel = (freq_val / 20) & 1 ? 1 : -1; -+ else -+ sec_channel = freq_val < 2442 ? 1 : -1; -+ -+ if (sec_channel != -1 && sec_channel != 1 && sec_channel != 0) -+ return NULL; -+ -+ switch (width) { -+ case 0: -+ chanwidth = CONF_OPER_CHWIDTH_USE_HT; -+ break; -+ case 1: -+ chanwidth = CONF_OPER_CHWIDTH_80MHZ; -+ break; -+ case 2: -+ chanwidth = CONF_OPER_CHWIDTH_160MHZ; -+ break; -+ default: -+ return NULL; -+ } -+ -+ hw_mode = ieee80211_freq_to_channel_ext(freq_val, sec_channel, -+ chanwidth, &op_class, &channel); -+ switch (hw_mode) { -+ case HOSTAPD_MODE_IEEE80211B: -+ modestr = "b"; -+ break; -+ case HOSTAPD_MODE_IEEE80211G: -+ modestr = "g"; -+ break; -+ case HOSTAPD_MODE_IEEE80211A: -+ modestr = "a"; -+ break; -+ case HOSTAPD_MODE_IEEE80211AD: -+ modestr = "ad"; -+ break; -+ default: -+ return NULL; -+ } -+ -+ ret = ucv_object_new(vm); -+ ucv_object_add(ret, "op_class", ucv_int64_new(op_class)); -+ ucv_object_add(ret, "channel", ucv_int64_new(channel)); -+ ucv_object_add(ret, "hw_mode", ucv_int64_new(hw_mode)); -+ ucv_object_add(ret, "hw_mode_str", ucv_get(ucv_string_new(modestr))); -+ ucv_object_add(ret, "sec_channel", ucv_int64_new(sec_channel)); -+ ucv_object_add(ret, "frequency", ucv_int64_new(freq_val)); -+ -+ if (!sec_channel) -+ return ret; -+ -+ if (freq_val >= 5900) -+ center_ofs = 0; -+ else if (freq_val >= 5745) -+ center_ofs = 20; -+ else -+ center_ofs = 35; -+ tmp_channel = channel - center_ofs; -+ tmp_channel &= ~((8 << width) - 1); -+ center_idx = tmp_channel + center_ofs + (4 << width) - 1; -+ -+ ucv_object_add(ret, "center_seg0_idx", ucv_int64_new(center_idx)); -+ center_idx = (center_idx - channel) * 5 + freq_val; -+ ucv_object_add(ret, "center_freq1", ucv_int64_new(center_idx)); -+ -+out: -+ return ret; -+} -+ -+uc_value_t *uc_wpa_getpid(uc_vm_t *vm, size_t nargs) -+{ -+ return ucv_int64_new(getpid()); -+} -+ -+uc_value_t *uc_wpa_sha1(uc_vm_t *vm, size_t nargs) -+{ -+ u8 hash[SHA1_MAC_LEN]; -+ char hash_hex[2 * ARRAY_SIZE(hash) + 1]; -+ uc_value_t *val; -+ size_t *lens; -+ const u8 **args; -+ int i; -+ -+ if (!nargs) -+ return NULL; -+ -+ args = alloca(nargs * sizeof(*args)); -+ lens = alloca(nargs * sizeof(*lens)); -+ for (i = 0; i < nargs; i++) { -+ val = uc_fn_arg(i); -+ if (ucv_type(val) != UC_STRING) -+ return NULL; -+ -+ args[i] = ucv_string_get(val); -+ lens[i] = ucv_string_length(val); -+ } -+ -+ if (sha1_vector(nargs, args, lens, hash)) -+ return NULL; -+ -+ for (i = 0; i < ARRAY_SIZE(hash); i++) -+ sprintf(hash_hex + 2 * i, "%02x", hash[i]); -+ -+ return ucv_string_new_length(hash_hex, 2 * ARRAY_SIZE(hash)); -+} -+ -+uc_vm_t *wpa_ucode_create_vm(void) -+{ -+ static uc_parse_config_t config = { -+ .strict_declarations = true, -+ .lstrip_blocks = true, -+ .trim_blocks = true, -+ .raw_mode = true -+ }; -+ -+ uc_search_path_init(&config.module_search_path); -+ uc_search_path_add(&config.module_search_path, HOSTAPD_UC_PATH "*.so"); -+ uc_search_path_add(&config.module_search_path, HOSTAPD_UC_PATH "*.uc"); -+ -+ uc_vm_init(&vm, &config); -+ -+ uc_stdlib_load(uc_vm_scope_get(&vm)); -+ eloop_add_uloop(); -+ gc_timer.cb = uc_gc_timer; -+ -+ return &vm; -+} -+ -+int wpa_ucode_run(const char *script) -+{ -+ uc_source_t *source; -+ uc_program_t *prog; -+ uc_value_t *ops; -+ char *err; -+ int ret; -+ -+ source = uc_source_new_file(script); -+ if (!source) -+ return -1; -+ -+ prog = uc_compile(vm.config, source, &err); -+ uc_source_put(source); -+ if (!prog) { -+ wpa_printf(MSG_ERROR, "Error loading ucode: %s\n", err); -+ return -1; -+ } -+ -+ ret = uc_vm_execute(&vm, prog, &ops); -+ uc_program_put(prog); -+ if (ret || !ops) -+ return -1; -+ -+ registry = ucv_array_new(&vm); -+ uc_vm_registry_set(&vm, "hostap.registry", registry); -+ ucv_array_set(registry, 0, ucv_get(ops)); -+ -+ return 0; -+} -+ -+int wpa_ucode_call_prepare(const char *fname) -+{ -+ uc_value_t *obj, *func; -+ -+ if (!registry) -+ return -1; -+ -+ obj = ucv_array_get(registry, 0); -+ if (!obj) -+ return -1; -+ -+ func = ucv_object_get(obj, fname, NULL); -+ if (!ucv_is_callable(func)) -+ return -1; -+ -+ uc_vm_stack_push(&vm, ucv_get(obj)); -+ uc_vm_stack_push(&vm, ucv_get(func)); -+ -+ return 0; -+} -+ -+uc_value_t *wpa_ucode_global_init(const char *name, uc_resource_type_t *global_type) -+{ -+ uc_value_t *global = uc_resource_new(global_type, NULL); -+ uc_value_t *proto; -+ -+ uc_vm_registry_set(&vm, "hostap.global", global); -+ proto = ucv_prototype_get(global); -+ ucv_object_add(proto, "data", ucv_get(ucv_object_new(&vm))); -+ -+#define ADD_CONST(x) ucv_object_add(proto, #x, ucv_int64_new(x)) -+ ADD_CONST(MSG_EXCESSIVE); -+ ADD_CONST(MSG_MSGDUMP); -+ ADD_CONST(MSG_DEBUG); -+ ADD_CONST(MSG_INFO); -+ ADD_CONST(MSG_WARNING); -+ ADD_CONST(MSG_ERROR); -+#undef ADD_CONST -+ -+ ucv_object_add(uc_vm_scope_get(&vm), name, ucv_get(global)); -+ -+ return global; -+} -+ -+int wpa_ucode_registry_add(uc_value_t *reg, uc_value_t *val) -+{ -+ uc_value_t *data; -+ int i = 0; -+ -+ while (ucv_array_get(reg, i)) -+ i++; -+ -+ ucv_array_set(reg, i, ucv_get(val)); -+ -+ return i + 1; -+} -+ -+uc_value_t *wpa_ucode_registry_get(uc_value_t *reg, int idx) -+{ -+ if (!idx) -+ return NULL; -+ -+ return ucv_array_get(reg, idx - 1); -+} -+ -+uc_value_t *wpa_ucode_registry_remove(uc_value_t *reg, int idx) -+{ -+ uc_value_t *val = wpa_ucode_registry_get(reg, idx); -+ -+ if (val) -+ ucv_array_set(reg, idx - 1, NULL); -+ -+ return val; -+} -+ -+ -+uc_value_t *wpa_ucode_call(size_t nargs) -+{ -+ if (uc_vm_call(&vm, true, nargs) != EXCEPTION_NONE) -+ return NULL; -+ -+ if (!gc_timer.pending) -+ uloop_timeout_set(&gc_timer, 10); -+ -+ return uc_vm_stack_pop(&vm); -+} -+ -+void wpa_ucode_free_vm(void) -+{ -+ if (!vm.config) -+ return; -+ -+ uc_search_path_free(&vm.config->module_search_path); -+ uc_vm_free(&vm); -+ registry = NULL; -+ vm = (uc_vm_t){}; -+} -diff --git a/package/network/services/hostapd/src/src/utils/ucode.h b/package/network/services/hostapd/src/src/utils/ucode.h -new file mode 100644 -index 0000000000..2c1886976e ---- /dev/null -+++ b/package/network/services/hostapd/src/src/utils/ucode.h -@@ -0,0 +1,29 @@ -+#ifndef __HOSTAPD_UTILS_UCODE_H -+#define __HOSTAPD_UTILS_UCODE_H -+ -+#include "utils/includes.h" -+#include "utils/common.h" -+#include -+#include -+ -+#define HOSTAPD_UC_PATH "/usr/share/hostap/" -+ -+extern uc_value_t *uc_registry; -+uc_vm_t *wpa_ucode_create_vm(void); -+int wpa_ucode_run(const char *script); -+int wpa_ucode_call_prepare(const char *fname); -+uc_value_t *wpa_ucode_call(size_t nargs); -+void wpa_ucode_free_vm(void); -+ -+uc_value_t *wpa_ucode_global_init(const char *name, uc_resource_type_t *global_type); -+ -+int wpa_ucode_registry_add(uc_value_t *reg, uc_value_t *val); -+uc_value_t *wpa_ucode_registry_get(uc_value_t *reg, int idx); -+uc_value_t *wpa_ucode_registry_remove(uc_value_t *reg, int idx); -+ -+uc_value_t *uc_wpa_printf(uc_vm_t *vm, size_t nargs); -+uc_value_t *uc_wpa_getpid(uc_vm_t *vm, size_t nargs); -+uc_value_t *uc_wpa_sha1(uc_vm_t *vm, size_t nargs); -+uc_value_t *uc_wpa_freq_info(uc_vm_t *vm, size_t nargs); -+ -+#endif -diff --git a/package/network/services/hostapd/src/wpa_supplicant/ubus.c b/package/network/services/hostapd/src/wpa_supplicant/ubus.c -new file mode 100644 -index 0000000000..1c477f0c0c ---- /dev/null -+++ b/package/network/services/hostapd/src/wpa_supplicant/ubus.c -@@ -0,0 +1,280 @@ -+/* -+ * wpa_supplicant / ubus support -+ * Copyright (c) 2018, Daniel Golle -+ * Copyright (c) 2013, Felix Fietkau -+ * -+ * This software may be distributed under the terms of the BSD license. -+ * See README for more details. -+ */ -+ -+#include "utils/includes.h" -+#include "utils/common.h" -+#include "utils/eloop.h" -+#include "utils/wpabuf.h" -+#include "common/ieee802_11_defs.h" -+#include "wpa_supplicant_i.h" -+#include "wps_supplicant.h" -+#include "ubus.h" -+ -+static struct ubus_context *ctx; -+static struct blob_buf b; -+static int ctx_ref; -+ -+static inline struct wpa_global *get_wpa_global_from_object(struct ubus_object *obj) -+{ -+ return container_of(obj, struct wpa_global, ubus_global); -+} -+ -+static inline struct wpa_supplicant *get_wpas_from_object(struct ubus_object *obj) -+{ -+ return container_of(obj, struct wpa_supplicant, ubus.obj); -+} -+ -+static void ubus_reconnect_timeout(void *eloop_data, void *user_ctx) -+{ -+ if (ubus_reconnect(ctx, NULL)) { -+ eloop_register_timeout(1, 0, ubus_reconnect_timeout, ctx, NULL); -+ return; -+ } -+ -+ ubus_add_uloop(ctx); -+} -+ -+static void wpas_ubus_connection_lost(struct ubus_context *ctx) -+{ -+ uloop_fd_delete(&ctx->sock); -+ eloop_register_timeout(1, 0, ubus_reconnect_timeout, ctx, NULL); -+} -+ -+static bool wpas_ubus_init(void) -+{ -+ if (ctx) -+ return true; -+ -+ eloop_add_uloop(); -+ ctx = ubus_connect(NULL); -+ if (!ctx) -+ return false; -+ -+ ctx->connection_lost = wpas_ubus_connection_lost; -+ ubus_add_uloop(ctx); -+ -+ return true; -+} -+ -+static void wpas_ubus_ref_inc(void) -+{ -+ ctx_ref++; -+} -+ -+static void wpas_ubus_ref_dec(void) -+{ -+ ctx_ref--; -+ if (!ctx) -+ return; -+ -+ if (ctx_ref) -+ return; -+ -+ uloop_fd_delete(&ctx->sock); -+ ubus_free(ctx); -+ ctx = NULL; -+} -+ -+static int -+wpas_bss_get_features(struct ubus_context *ctx, struct ubus_object *obj, -+ struct ubus_request_data *req, const char *method, -+ struct blob_attr *msg) -+{ -+ struct wpa_supplicant *wpa_s = get_wpas_from_object(obj); -+ -+ blob_buf_init(&b, 0); -+ blobmsg_add_u8(&b, "ht_supported", ht_supported(wpa_s->hw.modes)); -+ blobmsg_add_u8(&b, "vht_supported", vht_supported(wpa_s->hw.modes)); -+ ubus_send_reply(ctx, req, b.head); -+ -+ return 0; -+} -+ -+static int -+wpas_bss_reload(struct ubus_context *ctx, struct ubus_object *obj, -+ struct ubus_request_data *req, const char *method, -+ struct blob_attr *msg) -+{ -+ struct wpa_supplicant *wpa_s = get_wpas_from_object(obj); -+ -+ if (wpa_supplicant_reload_configuration(wpa_s)) -+ return UBUS_STATUS_UNKNOWN_ERROR; -+ else -+ return 0; -+} -+ -+#ifdef CONFIG_WPS -+enum { -+ WPS_START_MULTI_AP, -+ __WPS_START_MAX -+}; -+ -+static const struct blobmsg_policy wps_start_policy[] = { -+ [WPS_START_MULTI_AP] = { "multi_ap", BLOBMSG_TYPE_BOOL }, -+}; -+ -+static int -+wpas_bss_wps_start(struct ubus_context *ctx, struct ubus_object *obj, -+ struct ubus_request_data *req, const char *method, -+ struct blob_attr *msg) -+{ -+ int rc; -+ struct wpa_supplicant *wpa_s = get_wpas_from_object(obj); -+ struct blob_attr *tb[__WPS_START_MAX], *cur; -+ int multi_ap = 0; -+ -+ blobmsg_parse(wps_start_policy, __WPS_START_MAX, tb, blobmsg_data(msg), blobmsg_data_len(msg)); -+ -+ if (tb[WPS_START_MULTI_AP]) -+ multi_ap = blobmsg_get_bool(tb[WPS_START_MULTI_AP]); -+ -+ rc = wpas_wps_start_pbc(wpa_s, NULL, 0, multi_ap); -+ -+ if (rc != 0) -+ return UBUS_STATUS_NOT_SUPPORTED; -+ -+ return 0; -+} -+ -+static int -+wpas_bss_wps_cancel(struct ubus_context *ctx, struct ubus_object *obj, -+ struct ubus_request_data *req, const char *method, -+ struct blob_attr *msg) -+{ -+ int rc; -+ struct wpa_supplicant *wpa_s = get_wpas_from_object(obj); -+ -+ rc = wpas_wps_cancel(wpa_s); -+ -+ if (rc != 0) -+ return UBUS_STATUS_NOT_SUPPORTED; -+ -+ return 0; -+} -+#endif -+ -+static const struct ubus_method bss_methods[] = { -+ UBUS_METHOD_NOARG("reload", wpas_bss_reload), -+ UBUS_METHOD_NOARG("get_features", wpas_bss_get_features), -+#ifdef CONFIG_WPS -+ UBUS_METHOD_NOARG("wps_start", wpas_bss_wps_start), -+ UBUS_METHOD_NOARG("wps_cancel", wpas_bss_wps_cancel), -+#endif -+}; -+ -+static struct ubus_object_type bss_object_type = -+ UBUS_OBJECT_TYPE("wpas_bss", bss_methods); -+ -+void wpas_ubus_add_bss(struct wpa_supplicant *wpa_s) -+{ -+ struct ubus_object *obj = &wpa_s->ubus.obj; -+ char *name; -+ int ret; -+ -+ if (!wpas_ubus_init()) -+ return; -+ -+ if (asprintf(&name, "wpa_supplicant.%s", wpa_s->ifname) < 0) -+ return; -+ -+ obj->name = name; -+ obj->type = &bss_object_type; -+ obj->methods = bss_object_type.methods; -+ obj->n_methods = bss_object_type.n_methods; -+ ret = ubus_add_object(ctx, obj); -+ wpas_ubus_ref_inc(); -+} -+ -+void wpas_ubus_free_bss(struct wpa_supplicant *wpa_s) -+{ -+ struct ubus_object *obj = &wpa_s->ubus.obj; -+ char *name = (char *) obj->name; -+ -+ if (!ctx) -+ return; -+ -+ if (obj->id) { -+ ubus_remove_object(ctx, obj); -+ wpas_ubus_ref_dec(); -+ } -+ -+ free(name); -+} -+ -+#ifdef CONFIG_WPS -+void wpas_ubus_notify(struct wpa_supplicant *wpa_s, const struct wps_credential *cred) -+{ -+ u16 auth_type; -+ char *ifname, *encryption, *ssid, *key; -+ size_t ifname_len; -+ -+ if (!cred) -+ return; -+ -+ auth_type = cred->auth_type; -+ -+ if (auth_type == (WPS_AUTH_WPAPSK | WPS_AUTH_WPA2PSK)) -+ auth_type = WPS_AUTH_WPA2PSK; -+ -+ if (auth_type != WPS_AUTH_OPEN && -+ auth_type != WPS_AUTH_WPAPSK && -+ auth_type != WPS_AUTH_WPA2PSK) { -+ wpa_printf(MSG_DEBUG, "WPS: Ignored credentials for " -+ "unsupported authentication type 0x%x", -+ auth_type); -+ return; -+ } -+ -+ if (auth_type == WPS_AUTH_WPAPSK || auth_type == WPS_AUTH_WPA2PSK) { -+ if (cred->key_len < 8 || cred->key_len > 2 * PMK_LEN) { -+ wpa_printf(MSG_ERROR, "WPS: Reject PSK credential with " -+ "invalid Network Key length %lu", -+ (unsigned long) cred->key_len); -+ return; -+ } -+ } -+ -+ blob_buf_init(&b, 0); -+ -+ ifname_len = strlen(wpa_s->ifname); -+ ifname = blobmsg_alloc_string_buffer(&b, "ifname", ifname_len + 1); -+ memcpy(ifname, wpa_s->ifname, ifname_len + 1); -+ ifname[ifname_len] = '\0'; -+ blobmsg_add_string_buffer(&b); -+ -+ switch (auth_type) { -+ case WPS_AUTH_WPA2PSK: -+ encryption = "psk2"; -+ break; -+ case WPS_AUTH_WPAPSK: -+ encryption = "psk"; -+ break; -+ default: -+ encryption = "none"; -+ break; -+ } -+ -+ blobmsg_add_string(&b, "encryption", encryption); -+ -+ ssid = blobmsg_alloc_string_buffer(&b, "ssid", cred->ssid_len + 1); -+ memcpy(ssid, cred->ssid, cred->ssid_len); -+ ssid[cred->ssid_len] = '\0'; -+ blobmsg_add_string_buffer(&b); -+ -+ if (cred->key_len > 0) { -+ key = blobmsg_alloc_string_buffer(&b, "key", cred->key_len + 1); -+ memcpy(key, cred->key, cred->key_len); -+ key[cred->key_len] = '\0'; -+ blobmsg_add_string_buffer(&b); -+ } -+ -+// ubus_notify(ctx, &wpa_s->ubus.obj, "wps_credentials", b.head, -1); -+ ubus_send_event(ctx, "wps_credentials", b.head); -+} -+#endif /* CONFIG_WPS */ -diff --git a/package/network/services/hostapd/src/wpa_supplicant/ubus.h b/package/network/services/hostapd/src/wpa_supplicant/ubus.h -new file mode 100644 -index 0000000000..f6681cb26d ---- /dev/null -+++ b/package/network/services/hostapd/src/wpa_supplicant/ubus.h -@@ -0,0 +1,55 @@ -+/* -+ * wpa_supplicant / ubus support -+ * Copyright (c) 2018, Daniel Golle -+ * Copyright (c) 2013, Felix Fietkau -+ * -+ * This software may be distributed under the terms of the BSD license. -+ * See README for more details. -+ */ -+#ifndef __WPAS_UBUS_H -+#define __WPAS_UBUS_H -+ -+struct wpa_supplicant; -+struct wpa_global; -+ -+#include "wps_supplicant.h" -+ -+#ifdef UBUS_SUPPORT -+#include -+ -+struct wpas_ubus_bss { -+ struct ubus_object obj; -+}; -+ -+void wpas_ubus_add_bss(struct wpa_supplicant *wpa_s); -+void wpas_ubus_free_bss(struct wpa_supplicant *wpa_s); -+ -+#ifdef CONFIG_WPS -+void wpas_ubus_notify(struct wpa_supplicant *wpa_s, const struct wps_credential *cred); -+#endif -+ -+#else -+struct wpas_ubus_bss {}; -+ -+static inline void wpas_ubus_add_bss(struct wpa_supplicant *wpa_s) -+{ -+} -+ -+static inline void wpas_ubus_free_bss(struct wpa_supplicant *wpa_s) -+{ -+} -+ -+static inline void wpas_ubus_notify(struct wpa_supplicant *wpa_s, struct wps_credential *cred) -+{ -+} -+ -+static inline void wpas_ubus_add(struct wpa_global *global) -+{ -+} -+ -+static inline void wpas_ubus_free(struct wpa_global *global) -+{ -+} -+#endif -+ -+#endif -diff --git a/package/network/services/hostapd/src/wpa_supplicant/ucode.c b/package/network/services/hostapd/src/wpa_supplicant/ucode.c -new file mode 100644 -index 0000000000..d0a78d1625 ---- /dev/null -+++ b/package/network/services/hostapd/src/wpa_supplicant/ucode.c -@@ -0,0 +1,270 @@ -+#include "utils/includes.h" -+#include "utils/common.h" -+#include "utils/ucode.h" -+#include "drivers/driver.h" -+#include "wpa_supplicant_i.h" -+#include "wps_supplicant.h" -+#include "bss.h" -+#include "ucode.h" -+ -+static struct wpa_global *wpa_global; -+static uc_resource_type_t *global_type, *iface_type; -+static uc_value_t *global, *iface_registry; -+static uc_vm_t *vm; -+ -+static uc_value_t * -+wpas_ucode_iface_get_uval(struct wpa_supplicant *wpa_s) -+{ -+ uc_value_t *val; -+ -+ if (wpa_s->ucode.idx) -+ return wpa_ucode_registry_get(iface_registry, wpa_s->ucode.idx); -+ -+ val = uc_resource_new(iface_type, wpa_s); -+ wpa_s->ucode.idx = wpa_ucode_registry_add(iface_registry, val); -+ -+ return val; -+} -+ -+static void -+wpas_ucode_update_interfaces(void) -+{ -+ uc_value_t *ifs = ucv_object_new(vm); -+ struct wpa_supplicant *wpa_s; -+ int i; -+ -+ for (wpa_s = wpa_global->ifaces; wpa_s; wpa_s = wpa_s->next) -+ ucv_object_add(ifs, wpa_s->ifname, ucv_get(wpas_ucode_iface_get_uval(wpa_s))); -+ -+ ucv_object_add(ucv_prototype_get(global), "interfaces", ucv_get(ifs)); -+ ucv_gc(vm); -+} -+ -+void wpas_ucode_add_bss(struct wpa_supplicant *wpa_s) -+{ -+ uc_value_t *val; -+ -+ if (wpa_ucode_call_prepare("iface_add")) -+ return; -+ -+ uc_value_push(ucv_get(ucv_string_new(wpa_s->ifname))); -+ uc_value_push(ucv_get(wpas_ucode_iface_get_uval(wpa_s))); -+ ucv_put(wpa_ucode_call(2)); -+ ucv_gc(vm); -+} -+ -+void wpas_ucode_free_bss(struct wpa_supplicant *wpa_s) -+{ -+ uc_value_t *val; -+ -+ val = wpa_ucode_registry_remove(iface_registry, wpa_s->ucode.idx); -+ if (!val) -+ return; -+ -+ wpa_s->ucode.idx = 0; -+ if (wpa_ucode_call_prepare("iface_remove")) -+ return; -+ -+ uc_value_push(ucv_get(ucv_string_new(wpa_s->ifname))); -+ uc_value_push(ucv_get(val)); -+ ucv_put(wpa_ucode_call(2)); -+ ucv_gc(vm); -+} -+ -+void wpas_ucode_update_state(struct wpa_supplicant *wpa_s) -+{ -+ const char *state; -+ uc_value_t *val; -+ -+ val = wpa_ucode_registry_get(iface_registry, wpa_s->ucode.idx); -+ if (!val) -+ return; -+ -+ if (wpa_ucode_call_prepare("state")) -+ return; -+ -+ state = wpa_supplicant_state_txt(wpa_s->wpa_state); -+ uc_value_push(ucv_get(ucv_string_new(wpa_s->ifname))); -+ uc_value_push(ucv_get(val)); -+ uc_value_push(ucv_get(ucv_string_new(state))); -+ ucv_put(wpa_ucode_call(3)); -+ ucv_gc(vm); -+} -+ -+void wpas_ucode_event(struct wpa_supplicant *wpa_s, int event, union wpa_event_data *data) -+{ -+ const char *state; -+ uc_value_t *val; -+ -+ if (event != EVENT_CH_SWITCH_STARTED) -+ return; -+ -+ val = wpa_ucode_registry_get(iface_registry, wpa_s->ucode.idx); -+ if (!val) -+ return; -+ -+ if (wpa_ucode_call_prepare("event")) -+ return; -+ -+ uc_value_push(ucv_get(ucv_string_new(wpa_s->ifname))); -+ uc_value_push(ucv_get(val)); -+ uc_value_push(ucv_get(ucv_string_new(event_to_string(event)))); -+ val = ucv_object_new(vm); -+ uc_value_push(ucv_get(val)); -+ -+ if (event == EVENT_CH_SWITCH_STARTED) { -+ ucv_object_add(val, "csa_count", ucv_int64_new(data->ch_switch.count)); -+ ucv_object_add(val, "frequency", ucv_int64_new(data->ch_switch.freq)); -+ ucv_object_add(val, "sec_chan_offset", ucv_int64_new(data->ch_switch.ch_offset)); -+ ucv_object_add(val, "center_freq1", ucv_int64_new(data->ch_switch.cf1)); -+ ucv_object_add(val, "center_freq2", ucv_int64_new(data->ch_switch.cf2)); -+ } -+ -+ ucv_put(wpa_ucode_call(4)); -+ ucv_gc(vm); -+} -+ -+static const char *obj_stringval(uc_value_t *obj, const char *name) -+{ -+ uc_value_t *val = ucv_object_get(obj, name, NULL); -+ -+ return ucv_string_get(val); -+} -+ -+static uc_value_t * -+uc_wpas_add_iface(uc_vm_t *vm, size_t nargs) -+{ -+ uc_value_t *info = uc_fn_arg(0); -+ uc_value_t *ifname = ucv_object_get(info, "iface", NULL); -+ uc_value_t *bridge = ucv_object_get(info, "bridge", NULL); -+ uc_value_t *config = ucv_object_get(info, "config", NULL); -+ uc_value_t *ctrl = ucv_object_get(info, "ctrl", NULL); -+ struct wpa_interface iface; -+ int ret = -1; -+ -+ if (ucv_type(info) != UC_OBJECT) -+ goto out; -+ -+ iface = (struct wpa_interface){ -+ .driver = "nl80211", -+ .ifname = ucv_string_get(ifname), -+ .bridge_ifname = ucv_string_get(bridge), -+ .confname = ucv_string_get(config), -+ .ctrl_interface = ucv_string_get(ctrl), -+ }; -+ -+ if (!iface.ifname || !iface.confname) -+ goto out; -+ -+ ret = wpa_supplicant_add_iface(wpa_global, &iface, 0) ? 0 : -1; -+ wpas_ucode_update_interfaces(); -+ -+out: -+ return ucv_int64_new(ret); -+} -+ -+static uc_value_t * -+uc_wpas_remove_iface(uc_vm_t *vm, size_t nargs) -+{ -+ struct wpa_supplicant *wpa_s = NULL; -+ uc_value_t *ifname_arg = uc_fn_arg(0); -+ const char *ifname = ucv_string_get(ifname_arg); -+ int ret = -1; -+ -+ if (!ifname) -+ goto out; -+ -+ for (wpa_s = wpa_global->ifaces; wpa_s; wpa_s = wpa_s->next) -+ if (!strcmp(wpa_s->ifname, ifname)) -+ break; -+ -+ if (!wpa_s) -+ goto out; -+ -+ ret = wpa_supplicant_remove_iface(wpa_global, wpa_s, 0); -+ wpas_ucode_update_interfaces(); -+ -+out: -+ return ucv_int64_new(ret); -+} -+ -+static uc_value_t * -+uc_wpas_iface_status(uc_vm_t *vm, size_t nargs) -+{ -+ struct wpa_supplicant *wpa_s = uc_fn_thisval("wpas.iface"); -+ struct wpa_bss *bss; -+ uc_value_t *ret, *val; -+ -+ if (!wpa_s) -+ return NULL; -+ -+ ret = ucv_object_new(vm); -+ -+ val = ucv_string_new(wpa_supplicant_state_txt(wpa_s->wpa_state)); -+ ucv_object_add(ret, "state", ucv_get(val)); -+ -+ bss = wpa_s->current_bss; -+ if (bss) { -+ int sec_chan = 0; -+ const u8 *ie; -+ -+ ie = wpa_bss_get_ie(bss, WLAN_EID_HT_OPERATION); -+ if (ie && ie[1] >= 2) { -+ const struct ieee80211_ht_operation *ht_oper; -+ -+ ht_oper = (const void *) (ie + 2); -+ if (ht_oper->ht_param & HT_INFO_HT_PARAM_SECONDARY_CHNL_ABOVE) -+ sec_chan = 1; -+ else if (ht_oper->ht_param & -+ HT_INFO_HT_PARAM_SECONDARY_CHNL_BELOW) -+ sec_chan = -1; -+ } -+ -+ ucv_object_add(ret, "sec_chan_offset", ucv_int64_new(sec_chan)); -+ ucv_object_add(ret, "frequency", ucv_int64_new(bss->freq)); -+ } -+ -+ return ret; -+} -+ -+int wpas_ucode_init(struct wpa_global *gl) -+{ -+ static const uc_function_list_t global_fns[] = { -+ { "printf", uc_wpa_printf }, -+ { "getpid", uc_wpa_getpid }, -+ { "add_iface", uc_wpas_add_iface }, -+ { "remove_iface", uc_wpas_remove_iface }, -+ }; -+ static const uc_function_list_t iface_fns[] = { -+ { "status", uc_wpas_iface_status }, -+ }; -+ uc_value_t *data, *proto; -+ -+ wpa_global = gl; -+ vm = wpa_ucode_create_vm(); -+ -+ global_type = uc_type_declare(vm, "wpas.global", global_fns, NULL); -+ iface_type = uc_type_declare(vm, "wpas.iface", iface_fns, NULL); -+ -+ iface_registry = ucv_array_new(vm); -+ uc_vm_registry_set(vm, "wpas.iface_registry", iface_registry); -+ -+ global = wpa_ucode_global_init("wpas", global_type); -+ -+ if (wpa_ucode_run(HOSTAPD_UC_PATH "wpa_supplicant.uc")) -+ goto free_vm; -+ -+ ucv_gc(vm); -+ return 0; -+ -+free_vm: -+ wpa_ucode_free_vm(); -+ return -1; -+} -+ -+void wpas_ucode_free(void) -+{ -+ if (wpa_ucode_call_prepare("shutdown") == 0) -+ ucv_put(wpa_ucode_call(0)); -+ wpa_ucode_free_vm(); -+} -diff --git a/package/network/services/hostapd/src/wpa_supplicant/ucode.h b/package/network/services/hostapd/src/wpa_supplicant/ucode.h -new file mode 100644 -index 0000000000..a429a0ed87 ---- /dev/null -+++ b/package/network/services/hostapd/src/wpa_supplicant/ucode.h -@@ -0,0 +1,49 @@ -+#ifndef __WPAS_UCODE_H -+#define __WPAS_UCODE_H -+ -+#include "utils/ucode.h" -+ -+struct wpa_global; -+union wpa_event_data; -+struct wpa_supplicant; -+ -+struct wpas_ucode_bss { -+#ifdef UCODE_SUPPORT -+ unsigned int idx; -+#endif -+}; -+ -+#ifdef UCODE_SUPPORT -+int wpas_ucode_init(struct wpa_global *gl); -+void wpas_ucode_free(void); -+void wpas_ucode_add_bss(struct wpa_supplicant *wpa_s); -+void wpas_ucode_free_bss(struct wpa_supplicant *wpa_s); -+void wpas_ucode_update_state(struct wpa_supplicant *wpa_s); -+void wpas_ucode_event(struct wpa_supplicant *wpa_s, int event, union wpa_event_data *data); -+#else -+static inline int wpas_ucode_init(struct wpa_global *gl) -+{ -+ return -EINVAL; -+} -+static inline void wpas_ucode_free(void) -+{ -+} -+static inline void wpas_ucode_add_bss(struct wpa_supplicant *wpa_s) -+{ -+} -+ -+static inline void wpas_ucode_free_bss(struct wpa_supplicant *wpa_s) -+{ -+} -+ -+static inline void wpas_ucode_update_state(struct wpa_supplicant *wpa_s) -+{ -+} -+ -+static inline void wpas_ucode_event(struct wpa_supplicant *wpa_s, int event, union wpa_event_data *data) -+{ -+} -+ -+#endif -+ -+#endif --- -2.34.1 - diff --git a/patches/0052-mac80211-drop-23.05-version.patch b/patches/0052-mac80211-drop-23.05-version.patch deleted file mode 100644 index cee2a978b..000000000 --- a/patches/0052-mac80211-drop-23.05-version.patch +++ /dev/null @@ -1,29225 +0,0 @@ -From 7858898ed5f8ce1bde570c9a5970f975fb03990f Mon Sep 17 00:00:00 2001 -From: John Crispin -Date: Mon, 4 Sep 2023 09:07:33 +0200 -Subject: [PATCH 52/55] mac80211: drop 23.05 version - -Signed-off-by: John Crispin ---- - package/kernel/mac80211/Makefile | 397 ----- - package/kernel/mac80211/ath.mk | 391 ----- - package/kernel/mac80211/broadcom.mk | 491 ------ - .../files/lib/netifd/wireless/mac80211.sh | 1321 ----------------- - .../mac80211/files/lib/wifi/mac80211.sh | 217 --- - .../kernel/mac80211/files/mac80211.hotplug | 5 - - package/kernel/mac80211/intel.mk | 77 - - package/kernel/mac80211/marvell.mk | 51 - - .../patches/ath/070-ath_common_config.patch | 10 - - .../patches/ath/400-ath_move_debug_code.patch | 31 - - .../patches/ath/402-ath_regd_optional.patch | 92 -- - .../patches/ath/403-world_regd_fixup.patch | 84 -- - .../patches/ath/404-regd_no_assoc_hints.patch | 19 - - .../patches/ath/405-ath_regd_us.patch | 26 - - .../ath/406-ath_relax_default_regd.patch | 51 - - ...add_platform_eeprom_support_to_ath5k.patch | 56 - - .../ath10k/080-ath10k_thermal_config.patch | 47 - - ...21-ath10k_init_devices_synchronously.patch | 33 - - .../930-ath10k_add_tpt_led_trigger.patch | 37 - - ...rolling-support-for-various-chipsets.patch | 609 -------- - ...75-ath10k-use-tpt-trigger-by-default.patch | 53 - - ...-power-reduction-for-US-regulatory-d.patch | 101 -- - ...h10k-Try-to-get-mac-address-from-dts.patch | 37 - - .../ath10k/990-ath10k-small-buffers.patch | 64 - - ...-tx-queues-immediately-upon-firmware.patch | 78 - - ...-ath11k-Don-t-exit-on-wakeup-failure.patch | 45 - - ...-Fix-spelling-mistake-chnange-change.patch | 25 - - ...-ath11k-suppress-add-interface-error.patch | 52 - - ...support-to-configure-channel-dwell-t.patch | 102 -- - ...firmware-crash-on-vdev-delete-race-c.patch | 116 -- - ...monitor-vdev-creation-with-firmware-.patch | 40 - - ...qmi_msg_handler-data-structure-initi.patch | 33 - - ...hronize-ath11k_mac_he_gi_to_nl80211_.patch | 42 - - ...-ath11k-Make-QMI-message-rules-const.patch | 341 ----- - ...ger-sta-disconnect-on-hardware-resta.patch | 119 -- - ...race-condition-with-struct-htt_ppdu_.patch | 103 -- - ...-ath11k-update-hw-params-for-IPQ5018.patch | 125 -- - ...update-ce-configurations-for-IPQ5018.patch | 246 --- - ...-remap-ce-register-space-for-IPQ5018.patch | 351 ----- - ...11k-update-hal-srng-regs-for-IPQ5018.patch | 130 -- - ...ath11k-initialize-hw_ops-for-IPQ5018.patch | 90 -- - ...new-hw-ops-for-IPQ5018-to-get-rx-des.patch | 84 -- - ...fi-ath11k-add-ipq5018-device-support.patch | 31 - - ...scan-request-param-frame-size-warnin.patch | 161 -- - ...support-to-configure-FTM-responder-r.patch | 169 --- - ...-channel-177-into-5-GHz-channel-list.patch | 41 - - ...ix-ce-memory-mapping-for-ahb-devices.patch | 114 -- - ...ext-passive-scan-flag-to-adjust-pass.patch | 73 - - ...return-value-check-in-ath11k_ahb_pro.patch | 27 - - ...platform_get_irq-to-get-the-interrup.patch | 50 - - ...SAC-bug-on-peer-addition-with-sta-ba.patch | 53 - - ...low-system-suspend-to-survive-ath11k.patch | 43 - - ...fy-accessor-macros-to-match-index-si.patch | 61 - - ...-MU-MIMO-params-from-hostapd-to-hard.patch | 300 ---- - ...-HE-MCS-mapper-to-a-separate-functio.patch | 67 - - ...rate-rx-and-tx-mcs-maps-for-supporte.patch | 64 - - ...tx-ack-signal-support-for-management.patch | 150 -- - ...proper-regulatory-reference-for-band.patch | 216 --- - ...support-to-parse-new-WMI-event-for-6.patch | 844 ----------- - ...debug-prints-in-regulatory-WMI-event.patch | 567 ------- - ...ace-fake-flex-array-with-flexible-ar.patch | 246 --- - ...deinitialization-of-firmware-resourc.patch | 79 - - ...BUFFER_DONE-read-on-monitor-ring-rx-.patch | 130 -- - ...wifi-ath11k-Optimize-6-GHz-scan-time.patch | 101 -- - ...igure-the-FTM-responder-role-using-f.patch | 117 -- - ...rssi-station-dump-not-updated-in-QCN.patch | 158 -- - ...invalid-management-rx-frame-length-i.patch | 115 -- - ...-writing-to-unintended-memory-region.patch | 43 - - ...-11d-scan-start-before-WMI_START_SCA.patch | 61 - - ...1k-Remove-redundant-pci_clear_master.patch | 58 - - ...ble-Spectral-scan-upon-removing-inte.patch | 36 - - ...ath11k-enable-SAR-support-on-WCN6750.patch | 29 - - ...pci-Add-more-MODULE_FIRMWARE-entries.patch | 36 - - ...t-a-warning-when-crypto_alloc_shash-.patch | 34 - - ...re-frags-from-uninitialized-peer-in-.patch | 104 -- - ...-undefined-behavior-with-__fls-in-dp.patch | 29 - - ...double-free-of-peer-rx_tid-during-re.patch | 144 -- - ...wifi-ath11k-Prevent-REO-cmd-failures.patch | 43 - - ...peer-mac-information-in-failure-case.patch | 74 - - ...tx-status-reporting-in-encap-offload.patch | 119 -- - ...-incorrect-update-of-radiotap-fields.patch | 49 - - ...SKB-corruption-in-REO-destination-ri.patch | 70 - - ...emove-disabling-of-80-80-and-160-MHz.patch | 49 - - ...registration-of-6Ghz-only-phy-withou.patch | 61 - - ...ound-false-positive-stringop-overrea.patch | 84 -- - ...k-driver-settings-for-MBSSID-and-EMA.patch | 133 -- - ...ID-configuration-during-vdev-create-.patch | 215 --- - ...ame-MBSSID-fields-in-wmi_vdev_up_cmd.patch | 52 - - ...ID-parameter-configuration-in-AP-mod.patch | 138 -- - ...efactor-vif-parameter-configurations.patch | 86 -- - ...76-wifi-ath11k-MBSSID-beacon-support.patch | 190 --- - .../0077-wifi-ath11k-EMA-beacon-support.patch | 156 -- - ...cate-the-func-ath11k_mac_bitrate_mas.patch | 75 - - ...-HT-fixed-rate-in-WMI-peer-fixed-par.patch | 141 -- - ...support-default-regdb-while-searchin.patch | 127 -- - ...ve-unused-function-ath11k_tm_event_w.patch | 128 -- - ...ifi-ath11k-factory-test-mode-support.patch | 850 ----------- - ...w-ath11k-to-boot-without-caldata-in-.patch | 47 - - ...11k-Add-HTT-stats-for-PHY-reset-case.patch | 261 ---- - ...i-ath11k-use-unique-QRTR-instance-ID.patch | 162 -- - ...k-control-thermal-support-via-symbol.patch | 66 - - ...ci-fix-compilation-in-5.16-and-older.patch | 29 - - ...ble-coldboot-calibration-for-IPQ8074.patch | 24 - - ...upport-setting-FW-memory-mode-via-DT.patch | 74 - - ...tersection-support-for-regulatory-ru.patch | 317 ---- - .../201-ath5k-WAR-for-AR71xx-PCI-bug.patch | 38 - - .../ath5k/411-ath5k_allow_adhoc_and_ap.patch | 46 - - .../ath5k/420-ath5k_disable_fast_cc.patch | 18 - - .../ath5k/430-add_ath5k_platform.patch | 33 - - .../patches/ath5k/432-ath5k_add_pciids.patch | 11 - - .../ath5k/440-ath5k_channel_bw_debugfs.patch | 142 -- - ...w-reset-AHB-WMAC-interface-on-AR91xx.patch | 25 - - ..._hw-issue-external-reset-for-QCA955x.patch | 129 -- - ...h9k-force-rx_clear-when-disabling-rx.patch | 35 - - ...erpret-requested-txpower-in-EIRP-dom.patch | 36 - - ...power-reduction-for-US-regulatory-do.patch | 24 - - .../ath9k/401-ath9k_blink_default.patch | 11 - - .../ath9k/410-ath9k_allow_adhoc_and_ap.patch | 10 - - ...abled-MFP-capability-unconditionally.patch | 34 - - .../ath9k/500-ath9k_eeprom_debugfs.patch | 66 - - .../patches/ath9k/501-ath9k_ahb_init.patch | 34 - - .../510-ath9k_intr_mitigation_tweak.patch | 18 - - .../ath9k/511-ath9k_reduce_rxbuf.patch | 11 - - .../ath9k/512-ath9k_channelbw_debugfs.patch | 125 -- - .../patches/ath9k/513-ath9k_add_pci_ids.patch | 30 - - .../patches/ath9k/530-ath9k_extra_leds.patch | 267 ---- - .../ath9k/531-ath9k_extra_platform_leds.patch | 76 - - .../ath9k/540-ath9k_reduce_ani_interval.patch | 11 - - .../ath9k/542-ath9k_debugfs_diag.patch | 139 -- - .../ath9k/543-ath9k_entropy_from_adc.patch | 186 --- - ...544-ath9k-ar933x-usb-hang-workaround.patch | 79 - - .../ath9k/545-ath9k_ani_ws_detect.patch | 155 -- - .../ath9k/547-ath9k_led_defstate_fix.patch | 29 - - .../ath9k/548-ath9k_enable_gpio_chip.patch | 251 ---- - .../ath9k/549-ath9k_enable_gpio_buttons.patch | 143 -- - .../ath9k/551-ath9k_ubnt_uap_plus_hsr.patch | 403 ----- - .../patches/ath9k/552-ath9k-ahb_of.patch | 331 ----- - .../ath9k/553-ath9k_of_gpio_mask.patch | 25 - - .../patches/brcm/040-brcmutil_option.patch | 10 - - .../810-b43-gpio-mask-module-option.patch | 37 - - .../patches/brcm/811-b43_no_pio.patch | 86 -- - .../brcm/812-b43-add-antenna-control.patch | 131 -- - .../813-b43-reduce-number-of-RX-slots.patch | 11 - - .../814-b43-only-use-gpio-0-1-for-led.patch | 17 - - ...815-b43-always-take-overlapping-devs.patch | 11 - - ...-remove-extra-regulation-restriction.patch | 27 - - ...und-bug-with-some-inconsistent-BSSes.patch | 49 - - ...62-brcmfmac-Disable-power-management.patch | 27 - - ...-in-driver-tables-with-country-codes.patch | 60 - - ...e-internal-roaming-engine-by-default.patch | 23 - - ...d-alternative-firmware-names-from-DT.patch | 191 --- - .../patches/build/000-fix_kconfig.patch | 14 - - .../patches/build/001-fix_build.patch | 169 --- - .../patches/build/002-change_allconfig.patch | 64 - - .../build/003-remove_bogus_modparams.patch | 34 - - .../build/012-kernel_build_check.patch | 11 - - .../patches/build/050-lib80211_option.patch | 34 - - .../patches/build/060-no_local_ssb_bcma.patch | 314 ---- - .../build/070-remove-broken-wext-select.patch | 10 - - .../patches/build/080-resv_start_op.patch | 24 - - .../mac80211/patches/build/090-bcma-otp.patch | 13 - - .../100-backports-drop-QRTR-and-MHI.patch | 76 - - .../build/110-backport_napi_build_skb.patch | 11 - - ...01-wifi-mt7601u-update-firmware-path.patch | 55 - - ...700-mwl8k-missing-pci-id-for-WNR854T.patch | 10 - - .../801-libertas-configure-sysfs-links.patch | 21 - - .../802-libertas-set-wireless-macaddr.patch | 11 - - ...crease-the-global-limit-up-to-4-SSID.patch | 41 - - ...940-mwl8k_init_devices_synchronously.patch | 20 - - ...ringified-name-of-command-in-error-l.patch | 189 --- - .../patches/rt2x00/100-rt2x00_options.patch | 47 - - ...to-build-rt2800soc-module-for-RT3883.patch | 30 - - ...1-rt2x00-introduce-rt2x00_platform_h.patch | 32 - - .../602-rt2x00-introduce-rt2x00eeprom.patch | 296 ---- - .../603-rt2x00-of_load_eeprom_filename.patch | 31 - - ...om-on-SoC-from-a-mtd-device-defines-.patch | 113 -- - ...isabling_bands_through_platform_data.patch | 47 - - ...07-rt2x00-add_platform_data_mac_addr.patch | 25 - - ...00-allow_disabling_bands_through_dts.patch | 19 - - ...c-loadable-via-OF-on-rt288x-305x-SoC.patch | 33 - - ...0-rt2x00-change-led-polarity-from-OF.patch | 40 - - .../611-rt2x00-add-AP+STA-support.patch | 11 - - ...t-support-for-external-LNA-on-MT7620.patch | 161 -- - ...duce-accessors-for-CHIP_VER-register.patch | 139 -- - ...-differentiate-based-on-SoC-CHIP_VER.patch | 408 ----- - .../110-mac80211_keep_keys_on_stop_ap.patch | 19 - - .../120-cfg80211_allow_perm_addr_change.patch | 52 - - .../mac80211/patches/subsys/210-ap_scan.patch | 19 - - ...domize-BA-session-dialog-token-alloc.patch | 38 - - ...-minstrel_ht-fix-MINSTREL_FRAC-macro.patch | 21 - - ...l_ht-reduce-fluctuations-in-rate-pro.patch | 30 - - ...l_ht-rework-rate-downgrade-code-and-.patch | 151 -- - ...crease-quantum-for-airtime-scheduler.patch | 53 - - ...d-internal-handler-for-wake_tx_queue.patch | 183 --- - ...dd-wake_tx_queue-callback-to-drivers.patch | 396 ----- - ...c80211-Drop-support-for-TX-push-path.patch | 683 --------- - ...ltek-remove-duplicated-wake_tx_queue.patch | 32 - - ...port-for-restricting-netdev-features.patch | 506 ------- - ...x-and-simplify-unencrypted-drop-chec.patch | 87 -- - ...ve-A-MSDU-check-in-ieee80211_data_to.patch | 25 - - ...ctor-out-bridge-tunnel-RFC1042-heade.patch | 76 - - ...move-mesh-forwarding-congestion-chec.patch | 54 - - ...x-receiving-A-MSDU-frames-on-mesh-in.patch | 753 ---------- - ...d-a-workaround-for-receiving-non-sta.patch | 145 -- - ...x-race-in-mesh-sequence-number-assig.patch | 37 - - ...wifi-mac80211-mesh-fast-xmit-support.patch | 850 ----------- - ...e-mesh-header-cache-to-speed-up-mesh.patch | 132 -- - .../321-mac80211-fix-mesh-forwarding.patch | 32 - - ...x-mesh-path-discovery-based-on-unica.patch | 52 - - ...d-VHT-MU-MIMO-related-flags-in-ieee8.patch | 68 - - ...d-HE-MU-MIMO-related-flags-in-ieee80.patch | 68 - - ...troduce-ieee80211_refresh_tx_agg_ses.patch | 60 - - ...fi-mac80211-add-mesh-fast-rx-support.patch | 77 - - ...d-support-for-letting-drivers-regist.patch | 149 -- - ...x-receiving-mesh-packets-in-forwardi.patch | 50 - - ...orrectly-mark-FTM-frames-non-buffera.patch | 134 -- - ...mac80211-flush-queues-on-STA-removal.patch | 36 - - ...i-mvm-support-flush-on-AP-interfaces.patch | 34 - - ...3-wifi-mac80211-add-flush_sta-method.patch | 91 -- - ...ifi-mvm-support-new-flush_sta-method.patch | 53 - - ...d-LDPC-related-flags-in-ieee80211_bs.patch | 62 - - ...0211-generate-EMA-beacons-in-AP-mode.patch | 372 ----- - ...1-always-use-mac80211-loss-detection.patch | 36 - - .../patches/subsys/400-allow-ibss-mixed.patch | 40 - - .../500-mac80211_configure_antenna_gain.patch | 162 -- - ...the-dst-buffer-to-of_get_mac_address.patch | 29 - - package/kernel/mac80211/ralink.mk | 131 -- - package/kernel/mac80211/realtek.mk | 197 --- - .../mac80211/scripts/import-backports.sh | 109 -- - 229 files changed, 27381 deletions(-) - delete mode 100644 package/kernel/mac80211/Makefile - delete mode 100644 package/kernel/mac80211/ath.mk - delete mode 100644 package/kernel/mac80211/broadcom.mk - delete mode 100644 package/kernel/mac80211/files/lib/netifd/wireless/mac80211.sh - delete mode 100644 package/kernel/mac80211/files/lib/wifi/mac80211.sh - delete mode 100644 package/kernel/mac80211/files/mac80211.hotplug - delete mode 100644 package/kernel/mac80211/intel.mk - delete mode 100644 package/kernel/mac80211/marvell.mk - delete mode 100644 package/kernel/mac80211/patches/ath/070-ath_common_config.patch - delete mode 100644 package/kernel/mac80211/patches/ath/400-ath_move_debug_code.patch - delete mode 100644 package/kernel/mac80211/patches/ath/402-ath_regd_optional.patch - delete mode 100644 package/kernel/mac80211/patches/ath/403-world_regd_fixup.patch - delete mode 100644 package/kernel/mac80211/patches/ath/404-regd_no_assoc_hints.patch - delete mode 100644 package/kernel/mac80211/patches/ath/405-ath_regd_us.patch - delete mode 100644 package/kernel/mac80211/patches/ath/406-ath_relax_default_regd.patch - delete mode 100644 package/kernel/mac80211/patches/ath/431-add_platform_eeprom_support_to_ath5k.patch - delete mode 100644 package/kernel/mac80211/patches/ath10k/080-ath10k_thermal_config.patch - delete mode 100644 package/kernel/mac80211/patches/ath10k/921-ath10k_init_devices_synchronously.patch - delete mode 100644 package/kernel/mac80211/patches/ath10k/930-ath10k_add_tpt_led_trigger.patch - delete mode 100644 package/kernel/mac80211/patches/ath10k/974-ath10k_add-LED-and-GPIO-controlling-support-for-various-chipsets.patch - delete mode 100644 package/kernel/mac80211/patches/ath10k/975-ath10k-use-tpt-trigger-by-default.patch - delete mode 100644 package/kernel/mac80211/patches/ath10k/981-ath10k-adjust-tx-power-reduction-for-US-regulatory-d.patch - delete mode 100644 package/kernel/mac80211/patches/ath10k/984-ath10k-Try-to-get-mac-address-from-dts.patch - delete mode 100644 package/kernel/mac80211/patches/ath10k/990-ath10k-small-buffers.patch - delete mode 100644 package/kernel/mac80211/patches/ath11k/0001-wifi-ath11k-stop-tx-queues-immediately-upon-firmware.patch - delete mode 100644 package/kernel/mac80211/patches/ath11k/0002-wifi-ath11k-Don-t-exit-on-wakeup-failure.patch - delete mode 100644 package/kernel/mac80211/patches/ath11k/0005-wifi-ath11k-Fix-spelling-mistake-chnange-change.patch - delete mode 100644 package/kernel/mac80211/patches/ath11k/0007-wifi-ath11k-suppress-add-interface-error.patch - delete mode 100644 package/kernel/mac80211/patches/ath11k/0008-wifi-ath11k-add-support-to-configure-channel-dwell-t.patch - delete mode 100644 package/kernel/mac80211/patches/ath11k/0010-wifi-ath11k-Fix-firmware-crash-on-vdev-delete-race-c.patch - delete mode 100644 package/kernel/mac80211/patches/ath11k/0011-wifi-ath11k-fix-monitor-vdev-creation-with-firmware-.patch - delete mode 100644 package/kernel/mac80211/patches/ath11k/0012-wifi-ath11k-Fix-qmi_msg_handler-data-structure-initi.patch - delete mode 100644 package/kernel/mac80211/patches/ath11k/0013-wifi-ath11k-synchronize-ath11k_mac_he_gi_to_nl80211_.patch - delete mode 100644 package/kernel/mac80211/patches/ath11k/0016-wifi-ath11k-Make-QMI-message-rules-const.patch - delete mode 100644 package/kernel/mac80211/patches/ath11k/0017-wifi-ath11k-Trigger-sta-disconnect-on-hardware-resta.patch - delete mode 100644 package/kernel/mac80211/patches/ath11k/0018-wifi-ath11k-Fix-race-condition-with-struct-htt_ppdu_.patch - delete mode 100644 package/kernel/mac80211/patches/ath11k/0019-wifi-ath11k-update-hw-params-for-IPQ5018.patch - delete mode 100644 package/kernel/mac80211/patches/ath11k/0020-wifi-ath11k-update-ce-configurations-for-IPQ5018.patch - delete mode 100644 package/kernel/mac80211/patches/ath11k/0021-wifi-ath11k-remap-ce-register-space-for-IPQ5018.patch - delete mode 100644 package/kernel/mac80211/patches/ath11k/0022-wifi-ath11k-update-hal-srng-regs-for-IPQ5018.patch - delete mode 100644 package/kernel/mac80211/patches/ath11k/0023-wifi-ath11k-initialize-hw_ops-for-IPQ5018.patch - delete mode 100644 package/kernel/mac80211/patches/ath11k/0024-wifi-ath11k-add-new-hw-ops-for-IPQ5018-to-get-rx-des.patch - delete mode 100644 package/kernel/mac80211/patches/ath11k/0025-wifi-ath11k-add-ipq5018-device-support.patch - delete mode 100644 package/kernel/mac80211/patches/ath11k/0026-wifi-ath11k-Fix-scan-request-param-frame-size-warnin.patch - delete mode 100644 package/kernel/mac80211/patches/ath11k/0029-wifi-ath11k-Add-support-to-configure-FTM-responder-r.patch - delete mode 100644 package/kernel/mac80211/patches/ath11k/0030-wifi-ath11k-add-channel-177-into-5-GHz-channel-list.patch - delete mode 100644 package/kernel/mac80211/patches/ath11k/0031-wifi-ath11k-fix-ce-memory-mapping-for-ahb-devices.patch - delete mode 100644 package/kernel/mac80211/patches/ath11k/0033-wifi-ath11k-Set-ext-passive-scan-flag-to-adjust-pass.patch - delete mode 100644 package/kernel/mac80211/patches/ath11k/0034-wifi-ath11k-fix-return-value-check-in-ath11k_ahb_pro.patch - delete mode 100644 package/kernel/mac80211/patches/ath11k/0035-wifi-ath11k-Use-platform_get_irq-to-get-the-interrup.patch - delete mode 100644 package/kernel/mac80211/patches/ath11k/0036-wifi-ath11k-fix-SAC-bug-on-peer-addition-with-sta-ba.patch - delete mode 100644 package/kernel/mac80211/patches/ath11k/0037-wifi-ath11k-allow-system-suspend-to-survive-ath11k.patch - delete mode 100644 package/kernel/mac80211/patches/ath11k/0038-wifi-ath11k-modify-accessor-macros-to-match-index-si.patch - delete mode 100644 package/kernel/mac80211/patches/ath11k/0039-wifi-ath11k-push-MU-MIMO-params-from-hostapd-to-hard.patch - delete mode 100644 package/kernel/mac80211/patches/ath11k/0040-wifi-ath11k-move-HE-MCS-mapper-to-a-separate-functio.patch - delete mode 100644 package/kernel/mac80211/patches/ath11k/0041-wifi-ath11k-generate-rx-and-tx-mcs-maps-for-supporte.patch - delete mode 100644 package/kernel/mac80211/patches/ath11k/0042-wifi-ath11k-Add-tx-ack-signal-support-for-management.patch - delete mode 100644 package/kernel/mac80211/patches/ath11k/0043-wifi-ath11k-use-proper-regulatory-reference-for-band.patch - delete mode 100644 package/kernel/mac80211/patches/ath11k/0044-wifi-ath11k-add-support-to-parse-new-WMI-event-for-6.patch - delete mode 100644 package/kernel/mac80211/patches/ath11k/0045-wifi-ath11k-add-debug-prints-in-regulatory-WMI-event.patch - delete mode 100644 package/kernel/mac80211/patches/ath11k/0046-wifi-ath11k-Replace-fake-flex-array-with-flexible-ar.patch - delete mode 100644 package/kernel/mac80211/patches/ath11k/0047-wifi-ath11k-fix-deinitialization-of-firmware-resourc.patch - delete mode 100644 package/kernel/mac80211/patches/ath11k/0048-wifi-ath11k-fix-BUFFER_DONE-read-on-monitor-ring-rx-.patch - delete mode 100644 package/kernel/mac80211/patches/ath11k/0049-wifi-ath11k-Optimize-6-GHz-scan-time.patch - delete mode 100644 package/kernel/mac80211/patches/ath11k/0050-wifi-ath11k-Configure-the-FTM-responder-role-using-f.patch - delete mode 100644 package/kernel/mac80211/patches/ath11k/0051-wifi-ath11k-fix-rssi-station-dump-not-updated-in-QCN.patch - delete mode 100644 package/kernel/mac80211/patches/ath11k/0052-wifi-ath11k-Fix-invalid-management-rx-frame-length-i.patch - delete mode 100644 package/kernel/mac80211/patches/ath11k/0053-wifi-ath11k-fix-writing-to-unintended-memory-region.patch - delete mode 100644 package/kernel/mac80211/patches/ath11k/0054-wifi-ath11k-Send-11d-scan-start-before-WMI_START_SCA.patch - delete mode 100644 package/kernel/mac80211/patches/ath11k/0055-wifi-ath11k-Remove-redundant-pci_clear_master.patch - delete mode 100644 package/kernel/mac80211/patches/ath11k/0056-wifi-ath11k-Disable-Spectral-scan-upon-removing-inte.patch - delete mode 100644 package/kernel/mac80211/patches/ath11k/0057-wifi-ath11k-enable-SAR-support-on-WCN6750.patch - delete mode 100644 package/kernel/mac80211/patches/ath11k/0058-wifi-ath11k-pci-Add-more-MODULE_FIRMWARE-entries.patch - delete mode 100644 package/kernel/mac80211/patches/ath11k/0059-wifi-ath11k-print-a-warning-when-crypto_alloc_shash-.patch - delete mode 100644 package/kernel/mac80211/patches/ath11k/0060-wifi-ath11k-Ignore-frags-from-uninitialized-peer-in-.patch - delete mode 100644 package/kernel/mac80211/patches/ath11k/0061-wifi-ath11k-fix-undefined-behavior-with-__fls-in-dp.patch - delete mode 100644 package/kernel/mac80211/patches/ath11k/0062-wifi-ath11k-fix-double-free-of-peer-rx_tid-during-re.patch - delete mode 100644 package/kernel/mac80211/patches/ath11k/0063-wifi-ath11k-Prevent-REO-cmd-failures.patch - delete mode 100644 package/kernel/mac80211/patches/ath11k/0064-wifi-ath11k-add-peer-mac-information-in-failure-case.patch - delete mode 100644 package/kernel/mac80211/patches/ath11k/0065-wifi-ath11k-fix-tx-status-reporting-in-encap-offload.patch - delete mode 100644 package/kernel/mac80211/patches/ath11k/0066-wifi-ath11k-Fix-incorrect-update-of-radiotap-fields.patch - delete mode 100644 package/kernel/mac80211/patches/ath11k/0067-wifi-ath11k-Fix-SKB-corruption-in-REO-destination-ri.patch - delete mode 100644 package/kernel/mac80211/patches/ath11k/0068-wifi-ath11k-Remove-disabling-of-80-80-and-160-MHz.patch - delete mode 100644 package/kernel/mac80211/patches/ath11k/0069-wifi-ath11k-fix-registration-of-6Ghz-only-phy-withou.patch - delete mode 100644 package/kernel/mac80211/patches/ath11k/0070-wifi-ath-work-around-false-positive-stringop-overrea.patch - delete mode 100644 package/kernel/mac80211/patches/ath11k/0071-wifi-ath11k-driver-settings-for-MBSSID-and-EMA.patch - delete mode 100644 package/kernel/mac80211/patches/ath11k/0072-wifi-ath11k-MBSSID-configuration-during-vdev-create-.patch - delete mode 100644 package/kernel/mac80211/patches/ath11k/0073-wifi-ath11k-rename-MBSSID-fields-in-wmi_vdev_up_cmd.patch - delete mode 100644 package/kernel/mac80211/patches/ath11k/0074-wifi-ath11k-MBSSID-parameter-configuration-in-AP-mod.patch - delete mode 100644 package/kernel/mac80211/patches/ath11k/0075-wifi-ath11k-refactor-vif-parameter-configurations.patch - delete mode 100644 package/kernel/mac80211/patches/ath11k/0076-wifi-ath11k-MBSSID-beacon-support.patch - delete mode 100644 package/kernel/mac80211/patches/ath11k/0077-wifi-ath11k-EMA-beacon-support.patch - delete mode 100644 package/kernel/mac80211/patches/ath11k/0078-wifi-ath11k-Relocate-the-func-ath11k_mac_bitrate_mas.patch - delete mode 100644 package/kernel/mac80211/patches/ath11k/0079-wifi-ath11k-Send-HT-fixed-rate-in-WMI-peer-fixed-par.patch - delete mode 100644 package/kernel/mac80211/patches/ath11k/0080-wifi-ath11k-add-support-default-regdb-while-searchin.patch - delete mode 100644 package/kernel/mac80211/patches/ath11k/0081-wifi-ath11k-remove-unused-function-ath11k_tm_event_w.patch - delete mode 100644 package/kernel/mac80211/patches/ath11k/0082-wifi-ath11k-factory-test-mode-support.patch - delete mode 100644 package/kernel/mac80211/patches/ath11k/0083-wifi-ath11k-Allow-ath11k-to-boot-without-caldata-in-.patch - delete mode 100644 package/kernel/mac80211/patches/ath11k/0084-wifi-ath11k-Add-HTT-stats-for-PHY-reset-case.patch - delete mode 100644 package/kernel/mac80211/patches/ath11k/100-wifi-ath11k-use-unique-QRTR-instance-ID.patch - delete mode 100644 package/kernel/mac80211/patches/ath11k/900-ath11k-control-thermal-support-via-symbol.patch - delete mode 100644 package/kernel/mac80211/patches/ath11k/901-wifi-ath11k-pci-fix-compilation-in-5.16-and-older.patch - delete mode 100644 package/kernel/mac80211/patches/ath11k/902-ath11k-Disable-coldboot-calibration-for-IPQ8074.patch - delete mode 100644 package/kernel/mac80211/patches/ath11k/903-ath11k-support-setting-FW-memory-mode-via-DT.patch - delete mode 100644 package/kernel/mac80211/patches/ath11k/905-ath11k-remove-intersection-support-for-regulatory-ru.patch - delete mode 100644 package/kernel/mac80211/patches/ath5k/201-ath5k-WAR-for-AR71xx-PCI-bug.patch - delete mode 100644 package/kernel/mac80211/patches/ath5k/411-ath5k_allow_adhoc_and_ap.patch - delete mode 100644 package/kernel/mac80211/patches/ath5k/420-ath5k_disable_fast_cc.patch - delete mode 100644 package/kernel/mac80211/patches/ath5k/430-add_ath5k_platform.patch - delete mode 100644 package/kernel/mac80211/patches/ath5k/432-ath5k_add_pciids.patch - delete mode 100644 package/kernel/mac80211/patches/ath5k/440-ath5k_channel_bw_debugfs.patch - delete mode 100644 package/kernel/mac80211/patches/ath9k/350-ath9k_hw-reset-AHB-WMAC-interface-on-AR91xx.patch - delete mode 100644 package/kernel/mac80211/patches/ath9k/351-ath9k_hw-issue-external-reset-for-QCA955x.patch - delete mode 100644 package/kernel/mac80211/patches/ath9k/354-ath9k-force-rx_clear-when-disabling-rx.patch - delete mode 100644 package/kernel/mac80211/patches/ath9k/356-Revert-ath9k-interpret-requested-txpower-in-EIRP-dom.patch - delete mode 100644 package/kernel/mac80211/patches/ath9k/365-ath9k-adjust-tx-power-reduction-for-US-regulatory-do.patch - delete mode 100644 package/kernel/mac80211/patches/ath9k/401-ath9k_blink_default.patch - delete mode 100644 package/kernel/mac80211/patches/ath9k/410-ath9k_allow_adhoc_and_ap.patch - delete mode 100644 package/kernel/mac80211/patches/ath9k/450-ath9k-enabled-MFP-capability-unconditionally.patch - delete mode 100644 package/kernel/mac80211/patches/ath9k/500-ath9k_eeprom_debugfs.patch - delete mode 100644 package/kernel/mac80211/patches/ath9k/501-ath9k_ahb_init.patch - delete mode 100644 package/kernel/mac80211/patches/ath9k/510-ath9k_intr_mitigation_tweak.patch - delete mode 100644 package/kernel/mac80211/patches/ath9k/511-ath9k_reduce_rxbuf.patch - delete mode 100644 package/kernel/mac80211/patches/ath9k/512-ath9k_channelbw_debugfs.patch - delete mode 100644 package/kernel/mac80211/patches/ath9k/513-ath9k_add_pci_ids.patch - delete mode 100644 package/kernel/mac80211/patches/ath9k/530-ath9k_extra_leds.patch - delete mode 100644 package/kernel/mac80211/patches/ath9k/531-ath9k_extra_platform_leds.patch - delete mode 100644 package/kernel/mac80211/patches/ath9k/540-ath9k_reduce_ani_interval.patch - delete mode 100644 package/kernel/mac80211/patches/ath9k/542-ath9k_debugfs_diag.patch - delete mode 100644 package/kernel/mac80211/patches/ath9k/543-ath9k_entropy_from_adc.patch - delete mode 100644 package/kernel/mac80211/patches/ath9k/544-ath9k-ar933x-usb-hang-workaround.patch - delete mode 100644 package/kernel/mac80211/patches/ath9k/545-ath9k_ani_ws_detect.patch - delete mode 100644 package/kernel/mac80211/patches/ath9k/547-ath9k_led_defstate_fix.patch - delete mode 100644 package/kernel/mac80211/patches/ath9k/548-ath9k_enable_gpio_chip.patch - delete mode 100644 package/kernel/mac80211/patches/ath9k/549-ath9k_enable_gpio_buttons.patch - delete mode 100644 package/kernel/mac80211/patches/ath9k/551-ath9k_ubnt_uap_plus_hsr.patch - delete mode 100644 package/kernel/mac80211/patches/ath9k/552-ath9k-ahb_of.patch - delete mode 100644 package/kernel/mac80211/patches/ath9k/553-ath9k_of_gpio_mask.patch - delete mode 100644 package/kernel/mac80211/patches/brcm/040-brcmutil_option.patch - delete mode 100644 package/kernel/mac80211/patches/brcm/810-b43-gpio-mask-module-option.patch - delete mode 100644 package/kernel/mac80211/patches/brcm/811-b43_no_pio.patch - delete mode 100644 package/kernel/mac80211/patches/brcm/812-b43-add-antenna-control.patch - delete mode 100644 package/kernel/mac80211/patches/brcm/813-b43-reduce-number-of-RX-slots.patch - delete mode 100644 package/kernel/mac80211/patches/brcm/814-b43-only-use-gpio-0-1-for-led.patch - delete mode 100644 package/kernel/mac80211/patches/brcm/815-b43-always-take-overlapping-devs.patch - delete mode 100644 package/kernel/mac80211/patches/brcm/850-brcmsmac-remove-extra-regulation-restriction.patch - delete mode 100644 package/kernel/mac80211/patches/brcm/861-brcmfmac-workaround-bug-with-some-inconsistent-BSSes.patch - delete mode 100644 package/kernel/mac80211/patches/brcm/862-brcmfmac-Disable-power-management.patch - delete mode 100644 package/kernel/mac80211/patches/brcm/863-brcmfmac-add-in-driver-tables-with-country-codes.patch - delete mode 100644 package/kernel/mac80211/patches/brcm/864-brcmfmac-do-not-use-internal-roaming-engine-by-default.patch - delete mode 100644 package/kernel/mac80211/patches/brcm/865-brcmfmac-Read-alternative-firmware-names-from-DT.patch - delete mode 100644 package/kernel/mac80211/patches/build/000-fix_kconfig.patch - delete mode 100644 package/kernel/mac80211/patches/build/001-fix_build.patch - delete mode 100644 package/kernel/mac80211/patches/build/002-change_allconfig.patch - delete mode 100644 package/kernel/mac80211/patches/build/003-remove_bogus_modparams.patch - delete mode 100644 package/kernel/mac80211/patches/build/012-kernel_build_check.patch - delete mode 100644 package/kernel/mac80211/patches/build/050-lib80211_option.patch - delete mode 100644 package/kernel/mac80211/patches/build/060-no_local_ssb_bcma.patch - delete mode 100644 package/kernel/mac80211/patches/build/070-remove-broken-wext-select.patch - delete mode 100644 package/kernel/mac80211/patches/build/080-resv_start_op.patch - delete mode 100644 package/kernel/mac80211/patches/build/090-bcma-otp.patch - delete mode 100644 package/kernel/mac80211/patches/build/100-backports-drop-QRTR-and-MHI.patch - delete mode 100644 package/kernel/mac80211/patches/build/110-backport_napi_build_skb.patch - delete mode 100644 package/kernel/mac80211/patches/mt7601u/001-wifi-mt7601u-update-firmware-path.patch - delete mode 100644 package/kernel/mac80211/patches/mwl/700-mwl8k-missing-pci-id-for-WNR854T.patch - delete mode 100644 package/kernel/mac80211/patches/mwl/801-libertas-configure-sysfs-links.patch - delete mode 100644 package/kernel/mac80211/patches/mwl/802-libertas-set-wireless-macaddr.patch - delete mode 100644 package/kernel/mac80211/patches/mwl/900-mwifiex-increase-the-global-limit-up-to-4-SSID.patch - delete mode 100644 package/kernel/mac80211/patches/mwl/940-mwl8k_init_devices_synchronously.patch - delete mode 100644 package/kernel/mac80211/patches/mwl/950-mwifiex-Print-stringified-name-of-command-in-error-l.patch - delete mode 100644 package/kernel/mac80211/patches/rt2x00/100-rt2x00_options.patch - delete mode 100644 package/kernel/mac80211/patches/rt2x00/501-rt2x00-allow-to-build-rt2800soc-module-for-RT3883.patch - delete mode 100644 package/kernel/mac80211/patches/rt2x00/601-rt2x00-introduce-rt2x00_platform_h.patch - delete mode 100644 package/kernel/mac80211/patches/rt2x00/602-rt2x00-introduce-rt2x00eeprom.patch - delete mode 100644 package/kernel/mac80211/patches/rt2x00/603-rt2x00-of_load_eeprom_filename.patch - delete mode 100644 package/kernel/mac80211/patches/rt2x00/604-rt2x00-load-eeprom-on-SoC-from-a-mtd-device-defines-.patch - delete mode 100644 package/kernel/mac80211/patches/rt2x00/606-rt2x00-allow_disabling_bands_through_platform_data.patch - delete mode 100644 package/kernel/mac80211/patches/rt2x00/607-rt2x00-add_platform_data_mac_addr.patch - delete mode 100644 package/kernel/mac80211/patches/rt2x00/608-rt2x00-allow_disabling_bands_through_dts.patch - delete mode 100644 package/kernel/mac80211/patches/rt2x00/609-rt2x00-make-wmac-loadable-via-OF-on-rt288x-305x-SoC.patch - delete mode 100644 package/kernel/mac80211/patches/rt2x00/610-rt2x00-change-led-polarity-from-OF.patch - delete mode 100644 package/kernel/mac80211/patches/rt2x00/611-rt2x00-add-AP+STA-support.patch - delete mode 100644 package/kernel/mac80211/patches/rt2x00/994-rt2x00-import-support-for-external-LNA-on-MT7620.patch - delete mode 100644 package/kernel/mac80211/patches/rt2x00/995-rt2x00-mt7620-introduce-accessors-for-CHIP_VER-register.patch - delete mode 100644 package/kernel/mac80211/patches/rt2x00/996-rt2x00-mt7620-differentiate-based-on-SoC-CHIP_VER.patch - delete mode 100644 package/kernel/mac80211/patches/subsys/110-mac80211_keep_keys_on_stop_ap.patch - delete mode 100644 package/kernel/mac80211/patches/subsys/120-cfg80211_allow_perm_addr_change.patch - delete mode 100644 package/kernel/mac80211/patches/subsys/210-ap_scan.patch - delete mode 100644 package/kernel/mac80211/patches/subsys/301-mac80211-sta-randomize-BA-session-dialog-token-alloc.patch - delete mode 100644 package/kernel/mac80211/patches/subsys/302-mac80211-minstrel_ht-fix-MINSTREL_FRAC-macro.patch - delete mode 100644 package/kernel/mac80211/patches/subsys/303-mac80211-minstrel_ht-reduce-fluctuations-in-rate-pro.patch - delete mode 100644 package/kernel/mac80211/patches/subsys/304-mac80211-minstrel_ht-rework-rate-downgrade-code-and-.patch - delete mode 100644 package/kernel/mac80211/patches/subsys/305-mac80211-increase-quantum-for-airtime-scheduler.patch - delete mode 100644 package/kernel/mac80211/patches/subsys/306-01-v6.2-wifi-mac80211-add-internal-handler-for-wake_tx_queue.patch - delete mode 100644 package/kernel/mac80211/patches/subsys/306-02-v6.2-wifi-mac80211-add-wake_tx_queue-callback-to-drivers.patch - delete mode 100644 package/kernel/mac80211/patches/subsys/306-03-v6.2-wifi-mac80211-Drop-support-for-TX-push-path.patch - delete mode 100644 package/kernel/mac80211/patches/subsys/306-04-v6.2-wifi-realtek-remove-duplicated-wake_tx_queue.patch - delete mode 100644 package/kernel/mac80211/patches/subsys/310-v6.2-mac80211-add-support-for-restricting-netdev-features.patch - delete mode 100644 package/kernel/mac80211/patches/subsys/311-v6.2-wifi-mac80211-fix-and-simplify-unencrypted-drop-chec.patch - delete mode 100644 package/kernel/mac80211/patches/subsys/312-v6.3-wifi-cfg80211-move-A-MSDU-check-in-ieee80211_data_to.patch - delete mode 100644 package/kernel/mac80211/patches/subsys/313-v6.3-wifi-cfg80211-factor-out-bridge-tunnel-RFC1042-heade.patch - delete mode 100644 package/kernel/mac80211/patches/subsys/314-v6.3-wifi-mac80211-remove-mesh-forwarding-congestion-chec.patch - delete mode 100644 package/kernel/mac80211/patches/subsys/315-v6.3-wifi-mac80211-fix-receiving-A-MSDU-frames-on-mesh-in.patch - delete mode 100644 package/kernel/mac80211/patches/subsys/316-v6.3-wifi-mac80211-add-a-workaround-for-receiving-non-sta.patch - delete mode 100644 package/kernel/mac80211/patches/subsys/318-wifi-mac80211-fix-race-in-mesh-sequence-number-assig.patch - delete mode 100644 package/kernel/mac80211/patches/subsys/319-wifi-mac80211-mesh-fast-xmit-support.patch - delete mode 100644 package/kernel/mac80211/patches/subsys/320-wifi-mac80211-use-mesh-header-cache-to-speed-up-mesh.patch - delete mode 100644 package/kernel/mac80211/patches/subsys/321-mac80211-fix-mesh-forwarding.patch - delete mode 100644 package/kernel/mac80211/patches/subsys/322-wifi-mac80211-fix-mesh-path-discovery-based-on-unica.patch - delete mode 100644 package/kernel/mac80211/patches/subsys/323-v6.3-wifi-mac80211-Add-VHT-MU-MIMO-related-flags-in-ieee8.patch - delete mode 100644 package/kernel/mac80211/patches/subsys/324-v6.3-wifi-mac80211-Add-HE-MU-MIMO-related-flags-in-ieee80.patch - delete mode 100644 package/kernel/mac80211/patches/subsys/325-wifi-mac80211-introduce-ieee80211_refresh_tx_agg_ses.patch - delete mode 100644 package/kernel/mac80211/patches/subsys/326-wifi-mac80211-add-mesh-fast-rx-support.patch - delete mode 100644 package/kernel/mac80211/patches/subsys/327-wifi-mac80211-add-support-for-letting-drivers-regist.patch - delete mode 100644 package/kernel/mac80211/patches/subsys/329-wifi-mac80211-fix-receiving-mesh-packets-in-forwardi.patch - delete mode 100644 package/kernel/mac80211/patches/subsys/330-wifi-ieee80211-correctly-mark-FTM-frames-non-buffera.patch - delete mode 100644 package/kernel/mac80211/patches/subsys/331-wifi-mac80211-flush-queues-on-STA-removal.patch - delete mode 100644 package/kernel/mac80211/patches/subsys/332-wifi-iwlwifi-mvm-support-flush-on-AP-interfaces.patch - delete mode 100644 package/kernel/mac80211/patches/subsys/333-wifi-mac80211-add-flush_sta-method.patch - delete mode 100644 package/kernel/mac80211/patches/subsys/334-wifi-iwlwifi-mvm-support-new-flush_sta-method.patch - delete mode 100644 package/kernel/mac80211/patches/subsys/335-wifi-mac80211-add-LDPC-related-flags-in-ieee80211_bs.patch - delete mode 100644 package/kernel/mac80211/patches/subsys/336-v6.4-wifi-mac80211-generate-EMA-beacons-in-AP-mode.patch - delete mode 100644 package/kernel/mac80211/patches/subsys/340-mac80211-always-use-mac80211-loss-detection.patch - delete mode 100644 package/kernel/mac80211/patches/subsys/400-allow-ibss-mixed.patch - delete mode 100644 package/kernel/mac80211/patches/subsys/500-mac80211_configure_antenna_gain.patch - delete mode 100644 package/kernel/mac80211/patches/subsys/782-net-next-1-of-net-pass-the-dst-buffer-to-of_get_mac_address.patch - delete mode 100644 package/kernel/mac80211/ralink.mk - delete mode 100644 package/kernel/mac80211/realtek.mk - delete mode 100755 package/kernel/mac80211/scripts/import-backports.sh - -diff --git a/package/kernel/mac80211/Makefile b/package/kernel/mac80211/Makefile -deleted file mode 100644 -index 248b48c3c1..0000000000 ---- a/package/kernel/mac80211/Makefile -+++ /dev/null -@@ -1,397 +0,0 @@ --# --# Copyright (C) 2007-2015 OpenWrt.org --# --# 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:=mac80211 -- --PKG_VERSION:=6.1.24 --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:=5d39aca7e34c33cb9b3e366117b2e86841b7bdd37933679d6b1e61be6b150648 -- --PKG_SOURCE:=backports-$(PKG_VERSION).tar.xz --PKG_BUILD_DIR:=$(KERNEL_BUILD_DIR)/backports-$(PKG_VERSION) --PKG_BUILD_PARALLEL:=1 -- --PKG_MAINTAINER:=Felix Fietkau -- --PKG_DRIVERS = \ -- mac80211-hwsim \ -- mt7601u \ -- rsi91x rsi91x-usb rsi91x-sdio\ -- wlcore wl12xx wl18xx -- --PKG_CONFIG_DEPENDS:= \ -- CONFIG_PACKAGE_kmod-mac80211 \ -- CONFIG_PACKAGE_CFG80211_TESTMODE \ -- CONFIG_PACKAGE_MAC80211_DEBUGFS \ -- CONFIG_PACKAGE_MAC80211_MESH \ -- CONFIG_PACKAGE_MAC80211_TRACING \ -- CONFIG_PACKAGE_IWLWIFI_DEBUG \ -- CONFIG_PACKAGE_IWLWIFI_DEBUGFS \ -- CONFIG_PACKAGE_RTLWIFI_DEBUG \ -- --include $(INCLUDE_DIR)/package.mk -- --WMENU:=Wireless Drivers -- --define KernelPackage/mac80211/Default -- SUBMENU:=$(WMENU) -- URL:=https://wireless.wiki.kernel.org/ -- MAINTAINER:=Felix Fietkau --endef -- --config_package=$(if $(CONFIG_PACKAGE_kmod-$(1)),m) -- --config-y:= \ -- WLAN \ -- CFG80211_CERTIFICATION_ONUS \ -- MAC80211_RC_MINSTREL \ -- MAC80211_RC_MINSTREL_HT \ -- MAC80211_RC_MINSTREL_VHT \ -- MAC80211_RC_DEFAULT_MINSTREL \ -- WLAN_VENDOR_ADMTEK \ -- WLAN_VENDOR_ATH \ -- WLAN_VENDOR_ATMEL \ -- WLAN_VENDOR_BROADCOM \ -- WLAN_VENDOR_CISCO \ -- WLAN_VENDOR_INTEL \ -- WLAN_VENDOR_INTERSIL \ -- WLAN_VENDOR_MARVELL \ -- WLAN_VENDOR_MEDIATEK \ -- WLAN_VENDOR_RALINK \ -- WLAN_VENDOR_REALTEK \ -- WLAN_VENDOR_RSI \ -- WLAN_VENDOR_ST \ -- WLAN_VENDOR_TI \ -- WLAN_VENDOR_ZYDAS \ -- --config-$(call config_package,cfg80211) += CFG80211 --config-$(CONFIG_PACKAGE_CFG80211_TESTMODE) += NL80211_TESTMODE -- --config-$(call config_package,mac80211) += MAC80211 --config-$(CONFIG_PACKAGE_MAC80211_MESH) += MAC80211_MESH -- --include ath.mk --include broadcom.mk --include intel.mk --include marvell.mk --include ralink.mk --include realtek.mk -- --PKG_CONFIG_DEPENDS += \ -- $(patsubst %,CONFIG_PACKAGE_kmod-%,$(PKG_DRIVERS)) -- --define KernelPackage/cfg80211 -- $(call KernelPackage/mac80211/Default) -- TITLE:=cfg80211 - wireless configuration API -- DEPENDS+= +iw +iwinfo +wireless-regdb +USE_RFKILL:kmod-rfkill -- ABI_VERSION:=$(PKG_VERSION)-$(PKG_RELEASE) -- FILES:= \ -- $(PKG_BUILD_DIR)/compat/compat.ko \ -- $(PKG_BUILD_DIR)/net/wireless/cfg80211.ko --endef -- --define KernelPackage/cfg80211/description --cfg80211 is the Linux wireless LAN (802.11) configuration API. --endef -- --define KernelPackage/cfg80211/config -- if PACKAGE_kmod-cfg80211 -- -- config PACKAGE_CFG80211_TESTMODE -- bool "Enable testmode command support" -- default n -- help -- This is typically used for tests and calibration during -- manufacturing, or vendor specific debugging features -- -- endif --endef -- -- --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 -- KCONFIG:=\ -- CONFIG_AVERAGE=y -- FILES:= $(PKG_BUILD_DIR)/net/mac80211/mac80211.ko -- ABI_VERSION:=$(PKG_VERSION)-$(PKG_RELEASE) -- MENU:=1 --endef -- --define KernelPackage/mac80211/config -- if PACKAGE_kmod-mac80211 -- -- config PACKAGE_MAC80211_DEBUGFS -- bool "Export mac80211 internals in DebugFS" -- select KERNEL_DEBUG_FS -- default y -- help -- Select this to see extensive information about -- the internal state of mac80211 in debugfs. -- -- config PACKAGE_MAC80211_TRACING -- bool "Enable tracing (mac80211 and supported drivers)" -- select KERNEL_FTRACE -- select KERNEL_ENABLE_DEFAULT_TRACERS -- default n -- help -- Select this to enable tracing of mac80211 and -- related wifi drivers (using trace-cmd). -- -- config PACKAGE_MAC80211_MESH -- bool "Enable 802.11s mesh support" -- default y -- -- endif --endef -- --define KernelPackage/mac80211/description --Generic IEEE 802.11 Networking Stack (mac80211) --endef -- --define KernelPackage/mac80211-hwsim -- $(call KernelPackage/mac80211/Default) -- TITLE:=mac80211 HW simulation device -- DEPENDS+= +kmod-mac80211 +@DRIVER_11AX_SUPPORT +@DRIVER_11AC_SUPPORT -- FILES:=$(PKG_BUILD_DIR)/drivers/net/wireless/mac80211_hwsim.ko -- AUTOLOAD:=$(call AutoProbe,mac80211_hwsim) --endef -- -- --define KernelPackage/mt7601u -- $(call KernelPackage/mac80211/Default) -- TITLE:=MT7601U-based USB dongles Wireless Driver -- DEPENDS+= +kmod-mac80211 @USB_SUPPORT +kmod-usb-core +mt7601u-firmware -- FILES:=$(PKG_BUILD_DIR)/drivers/net/wireless/mediatek/mt7601u/mt7601u.ko -- AUTOLOAD:=$(call AutoProbe,mt7601u) --endef -- --define KernelPackage/rsi91x -- $(call KernelPackage/mac80211/Default) -- TITLE:=Redpine Signals Inc 91x WLAN driver support -- DEPENDS+= +kmod-mac80211 +rs9113-firmware -- FILES:=$(PKG_BUILD_DIR)/drivers/net/wireless/rsi/rsi_91x.ko --endef -- --define KernelPackage/rsi91x-usb -- $(call KernelPackage/mac80211/Default) -- TITLE:=Redpine Signals USB bus support -- DEPENDS+=@USB_SUPPORT +kmod-usb-core +kmod-mac80211 +kmod-rsi91x +rs9113-firmware -- FILES:=$(PKG_BUILD_DIR)/drivers/net/wireless/rsi/rsi_usb.ko -- AUTOLOAD:=$(call AutoProbe,rsi_usb) --endef -- --define KernelPackage/rsi91x-sdio -- $(call KernelPackage/mac80211/Default) -- TITLE:=Redpine Signals SDIO bus support -- DEPENDS+= +kmod-mac80211 +kmod-mmc +kmod-rsi91x +rs9113-firmware -- FILES:=$(PKG_BUILD_DIR)/drivers/net/wireless/rsi/rsi_sdio.ko -- AUTOLOAD:=$(call AutoProbe,rsi_sdio) --endef -- -- --define KernelPackage/wlcore -- $(call KernelPackage/mac80211/Default) -- TITLE:=TI common driver part -- DEPENDS+= +kmod-mmc +kmod-mac80211 -- FILES:= \ -- $(PKG_BUILD_DIR)/drivers/net/wireless/ti/wlcore/wlcore.ko \ -- $(PKG_BUILD_DIR)/drivers/net/wireless/ti/wlcore/wlcore_sdio.ko -- AUTOLOAD:=$(call AutoProbe,wlcore wlcore_sdio) --endef -- --define KernelPackage/wlcore/description -- This module contains some common parts needed by TI Wireless drivers. --endef -- --define KernelPackage/wl12xx -- $(call KernelPackage/mac80211/Default) -- TITLE:=Driver for TI WL12xx -- URL:=https://wireless.wiki.kernel.org/en/users/drivers/wl12xx -- DEPENDS+= +kmod-wlcore +wl12xx-firmware -- FILES:=$(PKG_BUILD_DIR)/drivers/net/wireless/ti/wl12xx/wl12xx.ko -- AUTOLOAD:=$(call AutoProbe,wl12xx) --endef -- --define KernelPackage/wl12xx/description -- Kernel modules for TI WL12xx --endef -- --define KernelPackage/wl18xx -- $(call KernelPackage/mac80211/Default) -- TITLE:=Driver for TI WL18xx -- URL:=https://wireless.wiki.kernel.org/en/users/drivers/wl18xx -- DEPENDS+= +kmod-wlcore +wl18xx-firmware -- FILES:=$(PKG_BUILD_DIR)/drivers/net/wireless/ti/wl18xx/wl18xx.ko -- AUTOLOAD:=$(call AutoProbe,wl18xx) --endef -- --define KernelPackage/wl18xx/description -- Kernel modules for TI WL18xx --endef -- -- --ifdef CONFIG_PACKAGE_MAC80211_DEBUGFS -- config-y += \ -- CFG80211_DEBUGFS \ -- MAC80211_DEBUGFS --endif -- --ifdef CONFIG_PACKAGE_MAC80211_TRACING -- config-y += \ -- IWLWIFI_DEVICE_TRACING --endif -- --config-$(call config_package,mac80211-hwsim) += MAC80211_HWSIM --config-$(call config_package,mt7601u) += MT7601U --config-y += WL_MEDIATEK -- --config-$(call config_package,wlcore) += WLCORE WLCORE_SDIO --config-$(call config_package,wl12xx) += WL12XX --config-$(call config_package,wl18xx) += WL18XX --config-y += WL_TI WILINK_PLATFORM_DATA --config-$(call config_package,rsi91x) += RSI_91X --config-$(call config_package,rsi91x-usb) += RSI_USB --config-$(call config_package,rsi91x-sdio) += RSI_SDIO -- --config-$(CONFIG_LEDS_TRIGGERS) += MAC80211_LEDS -- --C_DEFINES= -- --ifeq ($(BUILD_VARIANT),smallbuffers) -- C_DEFINES+= -DCONFIG_ATH10K_SMALLBUFFERS --endif -- --MAKE_OPTS:= \ -- $(subst -C $(LINUX_DIR),-C "$(PKG_BUILD_DIR)",$(KERNEL_MAKEOPTS)) \ -- EXTRA_CFLAGS="-I$(PKG_BUILD_DIR)/include $(IREMAP_CFLAGS) $(C_DEFINES)" \ -- KLIB_BUILD="$(LINUX_DIR)" \ -- MODPROBE=true \ -- KLIB=$(TARGET_MODULES_DIR) \ -- KERNEL_SUBLEVEL=$(lastword $(subst ., ,$(KERNEL_PATCHVER))) \ -- KBUILD_LDFLAGS_MODULE_PREREQ= -- --define ConfigVars --$(subst $(space),,$(foreach opt,$(config-$(1)),CPTCFG_$(opt)=$(1) --)) --endef -- --define mac80211_config --$(call ConfigVars,m)$(call ConfigVars,y) --endef --$(eval $(call shexport,mac80211_config)) -- --define Build/Prepare -- rm -rf $(PKG_BUILD_DIR) -- mkdir -p $(PKG_BUILD_DIR) -- $(PKG_UNPACK) -- $(Build/Patch) -- rm -rf \ -- $(PKG_BUILD_DIR)/include/linux/ssb \ -- $(PKG_BUILD_DIR)/include/linux/bcma \ -- $(PKG_BUILD_DIR)/include/net/bluetooth -- -- rm -f \ -- $(PKG_BUILD_DIR)/include/linux/cordic.h \ -- $(PKG_BUILD_DIR)/include/linux/crc8.h \ -- $(PKG_BUILD_DIR)/include/linux/eeprom_93cx6.h \ -- $(PKG_BUILD_DIR)/include/linux/wl12xx.h \ -- $(PKG_BUILD_DIR)/include/linux/mhi.h \ -- $(PKG_BUILD_DIR)/include/net/ieee80211.h \ -- $(PKG_BUILD_DIR)/backport-include/linux/bcm47xx_nvram.h -- -- echo 'compat-wireless-$(PKG_VERSION)-$(PKG_RELEASE)-$(REVISION)' > $(PKG_BUILD_DIR)/compat_version --endef -- --ifneq ($(CONFIG_PACKAGE_kmod-cfg80211),) -- define Build/Compile/kmod -- rm -rf $(PKG_BUILD_DIR)/modules -- +$(MAKE) $(PKG_JOBS) $(MAKE_OPTS) modules -- endef --endif -- --#do not Build/Configure for EXTERNAL KERNEL --ifeq ($(strip $(CONFIG_EXTERNAL_KERNEL_TREE)),"") -- ifeq ($(strip $(CONFIG_KERNEL_GIT_CLONE_URI)),"") -- define Build/Configure -- cmp $(PKG_BUILD_DIR)/include/linux/ath9k_platform.h $(LINUX_DIR)/include/linux/ath9k_platform.h -- cmp $(PKG_BUILD_DIR)/include/linux/ath5k_platform.h $(LINUX_DIR)/include/linux/ath5k_platform.h -- cmp $(PKG_BUILD_DIR)/include/linux/rt2x00_platform.h $(LINUX_DIR)/include/linux/rt2x00_platform.h -- endef -- endif --endif -- --define Build/Patch -- $(if $(QUILT),rm -rf $(PKG_BUILD_DIR)/patches; mkdir -p $(PKG_BUILD_DIR)/patches) -- $(call PatchDir,$(PKG_BUILD_DIR),$(PATCH_DIR)/build,build/) -- $(call PatchDir,$(PKG_BUILD_DIR),$(PATCH_DIR)/subsys,subsys/) -- $(call PatchDir,$(PKG_BUILD_DIR),$(PATCH_DIR)/ath,ath/) -- $(call PatchDir,$(PKG_BUILD_DIR),$(PATCH_DIR)/ath5k,ath5k/) -- $(call PatchDir,$(PKG_BUILD_DIR),$(PATCH_DIR)/ath9k,ath9k/) -- $(call PatchDir,$(PKG_BUILD_DIR),$(PATCH_DIR)/ath10k,ath10k/) -- $(call PatchDir,$(PKG_BUILD_DIR),$(PATCH_DIR)/ath11k,ath11k/) -- $(call PatchDir,$(PKG_BUILD_DIR),$(PATCH_DIR)/rt2x00,rt2x00/) -- $(call PatchDir,$(PKG_BUILD_DIR),$(PATCH_DIR)/mt7601u,mt7601u/) -- $(call PatchDir,$(PKG_BUILD_DIR),$(PATCH_DIR)/mwl,mwl/) -- $(call PatchDir,$(PKG_BUILD_DIR),$(PATCH_DIR)/brcm,brcm/) -- $(call PatchDir,$(PKG_BUILD_DIR),$(PATCH_DIR)/rtl,rtl/) -- $(if $(QUILT),touch $(PKG_BUILD_DIR)/.quilt_used) --endef -- --define Quilt/Refresh/Package -- $(call Quilt/RefreshDir,$(PKG_BUILD_DIR),$(PATCH_DIR)/build,build/) -- $(call Quilt/RefreshDir,$(PKG_BUILD_DIR),$(PATCH_DIR)/subsys,subsys/) -- $(call Quilt/RefreshDir,$(PKG_BUILD_DIR),$(PATCH_DIR)/ath,ath/) -- $(call Quilt/RefreshDir,$(PKG_BUILD_DIR),$(PATCH_DIR)/ath5k,ath5k/) -- $(call Quilt/RefreshDir,$(PKG_BUILD_DIR),$(PATCH_DIR)/ath9k,ath9k/) -- $(call Quilt/RefreshDir,$(PKG_BUILD_DIR),$(PATCH_DIR)/ath10k,ath10k/) -- $(call Quilt/RefreshDir,$(PKG_BUILD_DIR),$(PATCH_DIR)/ath11k,ath11k/) -- $(call Quilt/RefreshDir,$(PKG_BUILD_DIR),$(PATCH_DIR)/rt2x00,rt2x00/) -- $(call Quilt/RefreshDir,$(PKG_BUILD_DIR),$(PATCH_DIR)/mt7601u,mt7601u/) -- $(call Quilt/RefreshDir,$(PKG_BUILD_DIR),$(PATCH_DIR)/mwl,mwl/) -- $(call Quilt/RefreshDir,$(PKG_BUILD_DIR),$(PATCH_DIR)/brcm,brcm/) -- $(call Quilt/RefreshDir,$(PKG_BUILD_DIR),$(PATCH_DIR)/rtl,rtl/) --endef -- --define Build/Compile -- $(SH_FUNC) var2file "$(call shvar,mac80211_config)" $(PKG_BUILD_DIR)/.config -- $(MAKE) $(MAKE_OPTS) allnoconfig -- $(call Build/Compile/kmod) --endef -- --define Build/InstallDev -- mkdir -p \ -- $(1)/usr/include/mac80211 \ -- $(1)/usr/include/mac80211-backport \ -- $(1)/usr/include/mac80211/ath \ -- $(1)/usr/include/net/mac80211 -- $(CP) $(PKG_BUILD_DIR)/net/mac80211/*.h $(PKG_BUILD_DIR)/include/* $(1)/usr/include/mac80211/ -- $(CP) $(PKG_BUILD_DIR)/backport-include/* $(1)/usr/include/mac80211-backport/ -- $(CP) $(PKG_BUILD_DIR)/net/mac80211/rate.h $(1)/usr/include/net/mac80211/ -- $(CP) $(PKG_BUILD_DIR)/drivers/net/wireless/ath/*.h $(1)/usr/include/mac80211/ath/ -- rm -f $(1)/usr/include/mac80211-backport/linux/module.h --endef -- -- --define KernelPackage/cfg80211/install -- $(INSTALL_DIR) $(1)/lib/wifi $(1)/lib/netifd/wireless -- $(INSTALL_DATA) ./files/lib/wifi/mac80211.sh $(1)/lib/wifi -- $(INSTALL_BIN) ./files/lib/netifd/wireless/mac80211.sh $(1)/lib/netifd/wireless -- $(INSTALL_DIR) $(1)/etc/hotplug.d/ieee80211 -- $(INSTALL_DATA) ./files/mac80211.hotplug $(1)/etc/hotplug.d/ieee80211/10-wifi-detect --endef -- --$(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 -deleted file mode 100644 -index dc08df4f6f..0000000000 ---- a/package/kernel/mac80211/ath.mk -+++ /dev/null -@@ -1,391 +0,0 @@ --PKG_DRIVERS += \ -- ath ath5k ath6kl ath6kl-sdio ath6kl-usb ath9k ath9k-common ath9k-htc ath10k ath10k-smallbuffers \ -- ath11k ath11k-ahb ath11k-pci carl9170 owl-loader ar5523 wil6210 -- --PKG_CONFIG_DEPENDS += \ -- CONFIG_PACKAGE_ATH_DEBUG \ -- CONFIG_PACKAGE_ATH_DFS \ -- CONFIG_PACKAGE_ATH_SPECTRAL \ -- CONFIG_PACKAGE_ATH_DYNACK \ -- CONFIG_ATH9K_HWRNG \ -- CONFIG_ATH9K_SUPPORT_PCOEM \ -- CONFIG_ATH9K_TX99 \ -- CONFIG_ATH10K_LEDS \ -- CONFIG_ATH10K_THERMAL \ -- CONFIG_ATH11K_THERMAL \ -- CONFIG_ATH_USER_REGD -- --ifdef CONFIG_PACKAGE_MAC80211_DEBUGFS -- config-y += \ -- ATH9K_DEBUGFS \ -- ATH9K_HTC_DEBUGFS \ -- ATH10K_DEBUGFS \ -- ATH11K_DEBUGFS \ -- CARL9170_DEBUGFS \ -- ATH5K_DEBUG \ -- ATH6KL_DEBUG \ -- WIL6210_DEBUGFS --endif -- --ifdef CONFIG_PACKAGE_MAC80211_TRACING -- config-y += \ -- ATH10K_TRACING \ -- ATH11K_TRACING \ -- ATH6KL_TRACING \ -- ATH_TRACEPOINTS \ -- ATH5K_TRACER \ -- WIL6210_TRACING --endif -- --config-$(call config_package,ath) += ATH_CARDS ATH_COMMON --config-$(CONFIG_PACKAGE_ATH_DEBUG) += ATH_DEBUG ATH10K_DEBUG ATH11K_DEBUG ATH9K_STATION_STATISTICS --config-$(CONFIG_PACKAGE_ATH_DFS) += ATH9K_DFS_CERTIFIED ATH10K_DFS_CERTIFIED --config-$(CONFIG_PACKAGE_ATH_SPECTRAL) += ATH9K_COMMON_SPECTRAL ATH10K_SPECTRAL ATH11K_SPECTRAL --config-$(CONFIG_PACKAGE_ATH_DYNACK) += ATH9K_DYNACK --config-$(call config_package,ath9k) += ATH9K --config-$(call config_package,ath9k-common) += ATH9K_COMMON --config-$(call config_package,owl-loader) += ATH9K_PCI_NO_EEPROM --config-$(CONFIG_TARGET_ath79) += ATH9K_AHB --config-$(CONFIG_TARGET_ipq40xx) += ATH10K_AHB --config-$(CONFIG_PCI) += ATH9K_PCI --config-$(CONFIG_ATH_USER_REGD) += ATH_USER_REGD ATH_REG_DYNAMIC_USER_REG_HINTS --config-$(CONFIG_ATH9K_HWRNG) += ATH9K_HWRNG --config-$(CONFIG_ATH9K_SUPPORT_PCOEM) += ATH9K_PCOEM --config-$(CONFIG_ATH9K_TX99) += ATH9K_TX99 --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-$(call config_package,ath9k-htc) += ATH9K_HTC --config-$(call config_package,ath10k) += ATH10K ATH10K_PCI --config-$(call config_package,ath10k-smallbuffers) += ATH10K ATH10K_PCI ATH10K_SMALLBUFFERS --config-$(call config_package,ath11k) += ATH11K --config-$(call config_package,ath11k-ahb) += ATH11K_AHB --config-$(call config_package,ath11k-pci) += ATH11K_PCI -- --config-$(call config_package,ath5k) += ATH5K --ifdef CONFIG_TARGET_ath25 -- config-y += ATH5K_AHB --else -- config-y += ATH5K_PCI --endif -- --config-$(call config_package,ath6kl) += ATH6KL --config-$(call config_package,ath6kl-sdio) += ATH6KL_SDIO --config-$(call config_package,ath6kl-usb) += ATH6KL_USB -- --config-$(call config_package,carl9170) += CARL9170 --config-$(call config_package,ar5523) += AR5523 -- --config-$(call config_package,wil6210) += WIL6210 -- --define KernelPackage/ath/config -- if PACKAGE_kmod-ath -- config ATH_USER_REGD -- bool "Force Atheros drivers to respect the user's regdomain settings" -- default y -- help -- Atheros' idea of regulatory handling is that the EEPROM of the card defines -- the regulatory limits and the user is only allowed to restrict the settings -- even further, even if the country allows frequencies or power levels that -- are forbidden by the EEPROM settings. -- -- Select this option if you want the driver to respect the user's decision about -- regulatory settings. -- -- config PACKAGE_ATH_DEBUG -- bool "Atheros wireless debugging" -- help -- Say Y, if you want to debug atheros wireless drivers. -- Only ath9k & ath10k make use of this. -- -- config PACKAGE_ATH_DFS -- bool "Enable DFS support" -- default y -- help -- Dynamic frequency selection (DFS) is required for most of the 5 GHz band -- channels in Europe, US, and Japan. -- -- Select this option if you want to use such channels. -- -- config PACKAGE_ATH_SPECTRAL -- bool "Atheros spectral scan support" -- depends on PACKAGE_ATH_DEBUG -- select KERNEL_RELAY -- help -- Say Y to enable access to the FFT/spectral data via debugfs. -- -- config PACKAGE_ATH_DYNACK -- bool "Enable Dynack support" -- depends on PACKAGE_kmod-ath9k-common -- help -- Enables support for Dynamic ACK estimation, which allows the fastest possible speed -- at any distance automatically by increasing/decreasing the max frame ACK time for -- the most remote station detected. It can be enabled by using iw (iw phy0 set distance auto), -- or by sending the NL80211_ATTR_WIPHY_DYN_ACK flag to mac80211 driver using netlink. -- -- Select this option if you want to enable this feature -- -- endif --endef -- --define KernelPackage/ath -- $(call KernelPackage/mac80211/Default) -- TITLE:=Atheros common driver part -- DEPENDS+= @PCI_SUPPORT||USB_SUPPORT||TARGET_ath79||TARGET_ath25 +kmod-mac80211 -- FILES:=$(PKG_BUILD_DIR)/drivers/net/wireless/ath/ath.ko -- MENU:=1 --endef -- --define KernelPackage/ath/description -- This module contains some common parts needed by Atheros Wireless drivers. --endef -- --define KernelPackage/ath5k -- $(call KernelPackage/mac80211/Default) -- TITLE:=Atheros 5xxx wireless cards support -- URL:=https://wireless.wiki.kernel.org/en/users/drivers/ath5k -- DEPENDS+= @(PCI_SUPPORT||TARGET_ath25) +kmod-ath -- FILES:=$(PKG_BUILD_DIR)/drivers/net/wireless/ath/ath5k/ath5k.ko -- AUTOLOAD:=$(call AutoProbe,ath5k) --endef -- --define KernelPackage/ath5k/description -- This module adds support for wireless adapters based on -- Atheros 5xxx chipset. --endef -- --define KernelPackage/ath6kl -- $(call KernelPackage/mac80211/Default) -- TITLE:=Atheros FullMAC wireless devices (common code for ath6kl_sdio and ath6kl_usb) -- URL:=https://wireless.wiki.kernel.org/en/users/drivers/ath6kl -- HIDDEN:=1 -- DEPENDS+= +kmod-ath -- FILES:= $(PKG_BUILD_DIR)/drivers/net/wireless/ath/ath6kl/ath6kl_core.ko --endef -- --define KernelPackage/ath6kl-sdio -- $(call KernelPackage/mac80211/Default) -- TITLE:=Atheros 802.11n SDIO wireless cards support -- URL:=https://wireless.wiki.kernel.org/en/users/drivers/ath6kl -- DEPENDS+= +kmod-mmc +kmod-ath6kl -- FILES:= $(PKG_BUILD_DIR)/drivers/net/wireless/ath/ath6kl/ath6kl_sdio.ko -- AUTOLOAD:=$(call AutoProbe,ath6kl_sdio) --endef -- --define KernelPackage/ath6kl-sdio/description --This module adds support for wireless adapters based on --Atheros IEEE 802.11n AR6003 and AR6004 family of chipsets. --endef -- --define KernelPackage/ath6kl-usb -- $(call KernelPackage/mac80211/Default) -- TITLE:=Atheros 802.11n USB wireless cards support -- URL:=https://wireless.wiki.kernel.org/en/users/drivers/ath6kl -- DEPENDS+= @USB_SUPPORT +kmod-usb-core +kmod-ath6kl -- FILES:= $(PKG_BUILD_DIR)/drivers/net/wireless/ath/ath6kl/ath6kl_usb.ko -- AUTOLOAD:=$(call AutoProbe,ath6kl_usb) --endef -- --define KernelPackage/ath6kl-usb/description --This module adds support for wireless adapters based on the --Atheros IEEE 802.11n AR6004 chipset. --endef -- --define KernelPackage/ath9k-common -- $(call KernelPackage/mac80211/Default) -- TITLE:=Atheros 802.11n wireless devices (common code for ath9k and ath9k_htc) -- URL:=https://wireless.wiki.kernel.org/en/users/drivers/ath9k -- HIDDEN:=1 -- DEPENDS+= @PCI_SUPPORT||USB_SUPPORT||TARGET_ath79 +kmod-ath +kmod-random-core -- FILES:= \ -- $(PKG_BUILD_DIR)/drivers/net/wireless/ath/ath9k/ath9k_common.ko \ -- $(PKG_BUILD_DIR)/drivers/net/wireless/ath/ath9k/ath9k_hw.ko --endef -- --define KernelPackage/ath9k -- $(call KernelPackage/mac80211/Default) -- TITLE:=Atheros 802.11n PCI wireless cards support -- URL:=https://wireless.wiki.kernel.org/en/users/drivers/ath9k -- DEPENDS+= @PCI_SUPPORT||TARGET_ath79 +kmod-ath9k-common -- FILES:= \ -- $(PKG_BUILD_DIR)/drivers/net/wireless/ath/ath9k/ath9k.ko -- AUTOLOAD:=$(call AutoProbe,ath9k) --endef -- --define KernelPackage/ath9k/description --This module adds support for wireless adapters based on --Atheros IEEE 802.11n AR5008 and AR9001 family of chipsets. --endef -- --define KernelPackage/ath9k/config -- -- config ATH9K_HWRNG -- bool "Add wireless noise as source of randomness to kernel entropy pool" -- depends on PACKAGE_kmod-ath9k -- select PACKAGE_kmod-random-core -- default y -- -- config ATH9K_SUPPORT_PCOEM -- bool "Support chips used in PC OEM cards" -- depends on PACKAGE_kmod-ath9k -- default y if (x86_64 || i386) -- -- config ATH9K_TX99 -- bool "Enable TX99 support (WARNING: testing only, breaks normal operation!)" -- depends on PACKAGE_kmod-ath9k -- -- config ATH9K_UBNTHSR -- bool "Support for Ubiquiti UniFi Outdoor+ access point" -- depends on PACKAGE_kmod-ath9k && TARGET_ath79 -- default y -- --endef -- --define KernelPackage/ath9k-htc -- $(call KernelPackage/mac80211/Default) -- TITLE:=Atheros 802.11n USB device support -- URL:=https://wireless.wiki.kernel.org/en/users/drivers/ath9k -- DEPENDS+= @USB_SUPPORT +kmod-ath9k-common +kmod-usb-core +ath9k-htc-firmware -- FILES:= \ -- $(PKG_BUILD_DIR)/drivers/net/wireless/ath/ath9k/ath9k_htc.ko -- AUTOLOAD:=$(call AutoProbe,ath9k_htc) --endef -- --define KernelPackage/ath9k-htc/description --This module adds support for wireless adapters based on --Atheros USB AR9271 and AR7010 family of chipsets. --endef -- --define KernelPackage/ath10k -- $(call KernelPackage/mac80211/Default) -- TITLE:=Atheros 802.11ac wireless cards support -- URL:=https://wireless.wiki.kernel.org/en/users/drivers/ath10k -- DEPENDS+= @PCI_SUPPORT +kmod-ath +@DRIVER_11AC_SUPPORT \ -- +ATH10K_THERMAL:kmod-hwmon-core +ATH10K_THERMAL:kmod-thermal -- FILES:= \ -- $(PKG_BUILD_DIR)/drivers/net/wireless/ath/ath10k/ath10k_core.ko \ -- $(PKG_BUILD_DIR)/drivers/net/wireless/ath/ath10k/ath10k_pci.ko -- AUTOLOAD:=$(call AutoProbe,ath10k_core ath10k_pci) -- MODPARAMS.ath10k_core:=frame_mode=2 -- VARIANT:=regular --endef -- --define KernelPackage/ath10k/description --This module adds support for wireless adapters based on --Atheros IEEE 802.11ac family of chipsets. For now only --PCI is supported. --endef -- --define KernelPackage/ath10k/config -- -- config ATH10K_LEDS -- bool "Enable LED support" -- default y -- depends on PACKAGE_kmod-ath10k || PACKAGE_kmod-ath10k-smallbuffers -- -- config ATH10K_THERMAL -- bool "Enable thermal sensors and throttling support" -- depends on PACKAGE_kmod-ath10k || PACKAGE_kmod-ath10k-smallbuffers -- --endef -- --define KernelPackage/ath10k-smallbuffers -- $(call KernelPackage/ath10k) -- TITLE+= (small buffers for low-RAM devices) -- VARIANT:=smallbuffers --endef -- --define KernelPackage/ath11k -- $(call KernelPackage/mac80211/Default) -- 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 -- FILES:=$(PKG_BUILD_DIR)/drivers/soc/qcom/qmi_helpers.ko \ -- $(PKG_BUILD_DIR)/drivers/net/wireless/ath/ath11k/ath11k.ko --endef -- --define KernelPackage/ath11k/description --This module adds support for Qualcomm Technologies 802.11ax family of --chipsets. --endef -- --define KernelPackage/ath11k/config -- -- config ATH11K_THERMAL -- bool "Enable thermal sensors and throttling support" -- depends on PACKAGE_kmod-ath11k -- default y if TARGET_ipq807x -- --endef -- --define KernelPackage/ath11k-ahb -- $(call KernelPackage/mac80211/Default) -- TITLE:=Qualcomm 802.11ax AHB wireless chipset support -- URL:=https://wireless.wiki.kernel.org/en/users/drivers/ath11k -- DEPENDS+= @TARGET_ipq807x +kmod-ath11k +kmod-qrtr-smd -- FILES:=$(PKG_BUILD_DIR)/drivers/net/wireless/ath/ath11k/ath11k_ahb.ko -- AUTOLOAD:=$(call AutoProbe,ath11k_ahb) --endef -- --define KernelPackage/ath11k-ahb/description --This module adds support for Qualcomm Technologies 802.11ax family of --chipsets with AHB bus. --endef -- --define KernelPackage/ath11k-pci -- $(call KernelPackage/mac80211/Default) -- TITLE:=Qualcomm 802.11ax PCI wireless chipset support -- URL:=https://wireless.wiki.kernel.org/en/users/drivers/ath11k -- DEPENDS+= @PCI_SUPPORT +kmod-qrtr-mhi +kmod-ath11k -- FILES:=$(PKG_BUILD_DIR)/drivers/net/wireless/ath/ath11k/ath11k_pci.ko -- AUTOLOAD:=$(call AutoProbe,ath11k_pci) --endef -- --define KernelPackage/ath11k-pci/description --This module adds support for Qualcomm Technologies 802.11ax family of --chipsets with PCI bus. --endef -- --define KernelPackage/carl9170 -- $(call KernelPackage/mac80211/Default) -- TITLE:=Driver for Atheros AR9170 USB sticks -- DEPENDS:=@USB_SUPPORT +kmod-mac80211 +kmod-ath +kmod-usb-core +kmod-input-core +carl9170-firmware -- FILES:=$(PKG_BUILD_DIR)/drivers/net/wireless/ath/carl9170/carl9170.ko -- AUTOLOAD:=$(call AutoProbe,carl9170) --endef -- --define KernelPackage/owl-loader -- $(call KernelPackage/mac80211/Default) -- TITLE:=Owl loader for initializing Atheros PCI(e) Wifi chips -- DEPENDS:=@PCI_SUPPORT +kmod-ath9k -- FILES:=$(PKG_BUILD_DIR)/drivers/net/wireless/ath/ath9k/ath9k_pci_owl_loader.ko -- AUTOLOAD:=$(call AutoProbe,ath9k_pci_owl_loader) --endef -- --define KernelPackage/owl-loader/description -- Kernel module that helps to initialize certain Qualcomm -- Atheros' PCI(e) Wifi chips, which have the init data -- (which contains the PCI device ID for example) stored -- together with the calibration data in the file system. -- -- This is necessary for devices like the Cisco Meraki Z1. --endef -- --define KernelPackage/ar5523 -- $(call KernelPackage/mac80211/Default) -- TITLE:=Driver for Atheros AR5523 USB sticks -- DEPENDS:=@USB_SUPPORT +kmod-mac80211 +kmod-ath +kmod-usb-core +kmod-input-core -- FILES:=$(PKG_BUILD_DIR)/drivers/net/wireless/ath/ar5523/ar5523.ko -- AUTOLOAD:=$(call AutoProbe,ar5523) --endef -- --define KernelPackage/wil6210 -- $(call KernelPackage/mac80211/Default) -- TITLE:=QCA/Wilocity 60g WiFi card wil6210 support -- DEPENDS+= @PCI_SUPPORT +kmod-mac80211 +wil6210-firmware -- FILES:=$(PKG_BUILD_DIR)/drivers/net/wireless/ath/wil6210/wil6210.ko -- AUTOLOAD:=$(call AutoProbe,wil6210) --endef -diff --git a/package/kernel/mac80211/broadcom.mk b/package/kernel/mac80211/broadcom.mk -deleted file mode 100644 -index cf80ad2d32..0000000000 ---- a/package/kernel/mac80211/broadcom.mk -+++ /dev/null -@@ -1,491 +0,0 @@ --PKG_DRIVERS += \ -- b43 brcmsmac brcmfmac brcmutil -- --PKG_CONFIG_DEPENDS += \ -- CONFIG_PACKAGE_B43_DEBUG \ -- CONFIG_PACKAGE_B43_PIO \ -- CONFIG_PACKAGE_B43_PHY_G \ -- CONFIG_PACKAGE_B43_PHY_N \ -- CONFIG_PACKAGE_B43_PHY_LP \ -- CONFIG_PACKAGE_B43_PHY_HT \ -- CONFIG_PACKAGE_B43_BUSES_BCMA_AND_SSB \ -- CONFIG_PACKAGE_B43_BUSES_BCMA \ -- CONFIG_PACKAGE_B43_BUSES_SSB \ -- CONFIG_PACKAGE_BRCM80211_DEBUG -- --config-$(call config_package,b43) += B43 --config-$(CONFIG_PACKAGE_B43_BUSES_BCMA_AND_SSB) += B43_BUSES_BCMA_AND_SSB --config-$(CONFIG_PACKAGE_B43_BUSES_BCMA) += B43_BUSES_BCMA --config-$(CONFIG_PACKAGE_B43_BUSES_SSB) += B43_BUSES_SSB --config-$(CONFIG_PACKAGE_B43_PHY_G) += B43_PHY_G --config-$(CONFIG_PACKAGE_B43_PHY_N) += B43_PHY_N --config-$(CONFIG_PACKAGE_B43_PHY_LP) += B43_PHY_LP --config-$(CONFIG_PACKAGE_B43_PHY_HT) += B43_PHY_HT --config-$(CONFIG_PACKAGE_B43_PIO) += B43_PIO --config-$(CONFIG_PACKAGE_B43_DEBUG) += B43_DEBUG -- --config-$(call config_package,brcmutil) += BRCMUTIL --config-$(call config_package,brcmsmac) += BRCMSMAC --config-$(call config_package,brcmfmac) += BRCMFMAC --config-$(CONFIG_BRCMFMAC_SDIO) += BRCMFMAC_SDIO --config-$(CONFIG_BRCMFMAC_USB) += BRCMFMAC_USB --config-$(CONFIG_BRCMFMAC_PCIE) += BRCMFMAC_PCIE --config-$(CONFIG_PACKAGE_BRCM80211_DEBUG) += BRCMDBG -- --config-$(CONFIG_LEDS_TRIGGERS) += B43_LEDS B43LEGACY_LEDS -- --#Broadcom firmware --ifneq ($(CONFIG_B43_FW_6_30),) -- PKG_B43_FWV4_NAME:=broadcom-wl -- PKG_B43_FWV4_VERSION:=6.30.163.46 -- PKG_B43_FWV4_OBJECT:=$(PKG_B43_FWV4_NAME)-$(PKG_B43_FWV4_VERSION).wl_apsta.o -- PKG_B43_FWV4_SOURCE:=$(PKG_B43_FWV4_NAME)-$(PKG_B43_FWV4_VERSION).tar.bz2 -- PKG_B43_FWV4_SOURCE_URL:=http://www.lwfinger.com/b43-firmware/ -- PKG_B43_FWV4_HASH:=a07c3b6b277833c7dbe61daa511f908cd66c5e2763eb7a0859abc36cd9335c2d --else --ifneq ($(CONFIG_B43_FW_5_10),) -- PKG_B43_FWV4_NAME:=broadcom-wl -- PKG_B43_FWV4_VERSION:=5.10.56.27.3 -- PKG_B43_FWV4_OBJECT:=$(PKG_B43_FWV4_NAME)-$(PKG_B43_FWV4_VERSION)/driver/wl_apsta/wl_prebuilt.o -- PKG_B43_FWV4_SOURCE:=$(PKG_B43_FWV4_NAME)-$(PKG_B43_FWV4_VERSION)_mipsel.tar.bz2 -- PKG_B43_FWV4_SOURCE_URL:=@OPENWRT -- PKG_B43_FWV4_HASH:=26a8c370f48fc129d0731cfd751c36cae1419b0bc8ca35781126744e60eae009 --else --ifneq ($(CONFIG_B43_FW_4_178),) -- PKG_B43_FWV4_NAME:=broadcom-wl -- PKG_B43_FWV4_VERSION:=4.178.10.4 -- PKG_B43_FWV4_OBJECT:=$(PKG_B43_FWV4_NAME)-$(PKG_B43_FWV4_VERSION)/linux/wl_apsta.o -- PKG_B43_FWV4_SOURCE:=$(PKG_B43_FWV4_NAME)-$(PKG_B43_FWV4_VERSION).tar.bz2 -- PKG_B43_FWV4_SOURCE_URL:=@OPENWRT -- PKG_B43_FWV4_HASH:=32f6ad98facbb9045646fdc8b54bb03086d204153253f9c65d0234a5d90ae53f --else --ifneq ($(CONFIG_B43_FW_5_100_138),) -- PKG_B43_FWV4_NAME:=broadcom-wl -- PKG_B43_FWV4_VERSION:=5.100.138 -- PKG_B43_FWV4_OBJECT:=$(PKG_B43_FWV4_NAME)-$(PKG_B43_FWV4_VERSION)/linux/wl_apsta.o -- PKG_B43_FWV4_SOURCE:=$(PKG_B43_FWV4_NAME)-$(PKG_B43_FWV4_VERSION).tar.bz2 -- PKG_B43_FWV4_SOURCE_URL:=http://www.lwfinger.com/b43-firmware/ -- PKG_B43_FWV4_HASH:=f1e7067aac5b62b67b8b6e4c517990277804339ac16065eb13c731ff909ae46f --else -- PKG_B43_FWV4_NAME:=broadcom-wl -- PKG_B43_FWV4_VERSION:=4.150.10.5 -- PKG_B43_FWV4_OBJECT:=$(PKG_B43_FWV4_NAME)-$(PKG_B43_FWV4_VERSION)/driver/wl_apsta_mimo.o -- PKG_B43_FWV4_SOURCE:=$(PKG_B43_FWV4_NAME)-$(PKG_B43_FWV4_VERSION).tar.bz2 -- PKG_B43_FWV4_SOURCE_URL:=@OPENWRT -- PKG_B43_FWV4_HASH:=a9f4e276a4d8d3a1cd0f2eb87080ae89b77f0a7140f06d4e9e2135fc44fdd533 --endif --endif --endif --endif --ifneq ($(CONFIG_B43_OPENFIRMWARE),) -- PKG_B43_FWV4_NAME:=broadcom-wl -- PKG_B43_FWV4_VERSION:=5.2 -- PKG_B43_FWV4_OBJECT:=openfwwf-$(PKG_B43_FWV4_VERSION) -- PKG_B43_FWV4_SOURCE:=openfwwf-$(PKG_B43_FWV4_VERSION).tar.gz -- PKG_B43_FWV4_SOURCE_URL:=http://netweb.ing.unibs.it/~openfwwf/firmware -- PKG_B43_FWV4_HASH:=9de03320083201080b2e94b81637ac07a159cf4e6f3481383e1a217e627bc0dc --endif -- -- --define Download/b43 -- FILE:=$(PKG_B43_FWV4_SOURCE) -- URL:=$(PKG_B43_FWV4_SOURCE_URL) -- HASH:=$(PKG_B43_FWV4_HASH) --endef --$(eval $(call Download,b43)) -- --define KernelPackage/b43 -- $(call KernelPackage/mac80211/Default) -- TITLE:=Broadcom 43xx wireless support -- URL:=https://wireless.wiki.kernel.org/en/users/drivers/b43 -- KCONFIG:= \ -- CONFIG_HW_RANDOM=y -- # Depend on PCI_SUPPORT to make sure we can select kmod-bcma or kmod-ssb -- DEPENDS += \ -- @PCI_SUPPORT +kmod-mac80211 +kmod-lib-cordic \ -- $(if $(CONFIG_PACKAGE_B43_USE_SSB),+kmod-ssb) \ -- $(if $(CONFIG_PACKAGE_B43_USE_BCMA),+kmod-bcma) -- FILES:=$(PKG_BUILD_DIR)/drivers/net/wireless/broadcom/b43/b43.ko -- AUTOLOAD:=$(call AutoProbe,b43) -- MENU:=1 --endef -- --define KernelPackage/b43/config -- --config PACKAGE_B43_USE_SSB -- select PACKAGE_kmod-ssb -- tristate -- depends on !TARGET_bcm47xx && !TARGET_bcm63xx -- default PACKAGE_kmod-b43 if PACKAGE_B43_BUSES_BCMA_AND_SSB -- default PACKAGE_kmod-b43 if PACKAGE_B43_BUSES_SSB -- --config PACKAGE_B43_USE_BCMA -- select PACKAGE_kmod-bcma -- tristate -- depends on !TARGET_bcm47xx && !TARGET_bcm53xx -- default PACKAGE_kmod-b43 if PACKAGE_B43_BUSES_BCMA_AND_SSB -- default PACKAGE_kmod-b43 if PACKAGE_B43_BUSES_BCMA -- -- if PACKAGE_kmod-b43 -- -- choice -- prompt "b43 firmware version" -- default B43_FW_5_100_138 -- help -- This option allows you to select the version of the b43 firmware. -- -- config B43_FW_4_150 -- bool "Firmware 410.2160 from driver 4.150.10.5 (old stable)" -- help -- Old stable firmware for BCM43xx devices. -- -- If unsure, select this. -- -- config B43_FW_4_178 -- bool "Firmware 478.104 from driver 4.178.10.4" -- help -- Older firmware for BCM43xx devices. -- -- If unsure, select the "stable" firmware. -- -- config B43_FW_5_10 -- bool "Firmware 508.1084 from driver 5.10.56.27" -- help -- Older firmware for BCM43xx devices. -- -- If unsure, select the "stable" firmware. -- -- config B43_FW_5_100_138 -- bool "Firmware 666.2 from driver 5.100.138 (stable)" -- help -- The currently default firmware for BCM43xx devices. -- -- This firmware currently gets most of the testing and is needed for some N-PHY devices. -- -- If unsure, select the this firmware. -- -- config B43_FW_6_30 -- bool "Firmware 784.2 from driver 6.30.163.46 (experimental)" -- help -- Newer experimental firmware for BCM43xx devices. -- -- This firmware is mostly untested. -- -- If unsure, select the "stable" firmware. -- -- config B43_OPENFIRMWARE -- bool "Open FirmWare for WiFi networks" -- help -- Opensource firmware for BCM43xx devices. -- -- Do _not_ select this, unless you know what you are doing. -- The Opensource firmware is not suitable for embedded devices, yet. -- It does not support QoS, which is bad for AccessPoints. -- It does not support hardware crypto acceleration, which is a showstopper -- for embedded devices with low CPU resources. -- -- If unsure, select the "stable" firmware. -- -- endchoice -- -- config B43_FW_SQUASH -- bool "Remove unnecessary firmware files" -- depends on !B43_OPENFIRMWARE -- default y -- help -- This options allows you to remove unnecessary b43 firmware files -- from the final rootfs image. This can reduce the rootfs size by -- up to 200k. -- -- If unsure, say Y. -- -- config B43_FW_SQUASH_COREREVS -- string "Core revisions to include" -- depends on B43_FW_SQUASH -- default "5,6,7,8,9,10,11,13,15" if TARGET_bcm47xx_legacy -- default "16,28,29,30" if TARGET_bcm47xx_mips74k -- default "5,6,7,8,9,10,11,13,15,16,28,29,30" -- help -- This is a comma separated list of core revision numbers. -- -- Example (keep files for rev5 only): -- 5 -- -- Example (keep files for rev5 and rev11): -- 5,11 -- -- config B43_FW_SQUASH_PHYTYPES -- string "PHY types to include" -- depends on B43_FW_SQUASH -- default "G,N,LP" if TARGET_bcm47xx_legacy -- default "N,HT" if TARGET_bcm47xx_mips74k -- default "G,N,LP,HT" -- help -- This is a comma separated list of PHY types: -- A => A-PHY -- AG => Dual A-PHY G-PHY -- G => G-PHY -- LP => LP-PHY -- N => N-PHY -- HT => HT-PHY -- LCN => LCN-PHY -- LCN40 => LCN40-PHY -- AC => AC-PHY -- -- Example (keep files for G-PHY only): -- G -- -- Example (keep files for G-PHY and N-PHY): -- G,N -- -- choice -- prompt "Supported buses" -- default PACKAGE_B43_BUSES_BCMA_AND_SSB -- help -- This allows choosing buses that b43 should support. -- -- config PACKAGE_B43_BUSES_BCMA_AND_SSB -- depends on !TARGET_bcm47xx_legacy && !TARGET_bcm47xx_mips74k && !TARGET_bcm53xx && !TARGET_bmips -- bool "BCMA and SSB" -- -- config PACKAGE_B43_BUSES_BCMA -- depends on !TARGET_bcm47xx_legacy && !TARGET_bmips_bcm6358 && !TARGET_bmips_bcm6368 -- bool "BCMA only" -- -- config PACKAGE_B43_BUSES_SSB -- depends on !TARGET_bcm47xx_mips74k && !TARGET_bcm53xx -- bool "SSB only" -- -- endchoice -- -- config PACKAGE_B43_DEBUG -- bool "Enable debug output and debugfs for b43" -- default n -- help -- Enable additional debug output and runtime sanity checks for b43 -- and enables the debugfs interface. -- -- If unsure, say N. -- -- config PACKAGE_B43_PIO -- bool "Enable support for PIO transfer mode" -- default n -- help -- Enable support for using PIO instead of DMA. Unless you have DMA -- transfer problems you don't need this. -- -- If unsure, say N. -- -- config PACKAGE_B43_PHY_G -- bool "Enable support for G-PHYs" -- default n if TARGET_bcm47xx_mips74k -- default y -- help -- Enable support for G-PHY. This includes support for the following devices: -- PCI: BCM4306, BCM4311, BCM4318 -- SoC: BCM5352E, BCM4712 -- -- If unsure, say Y. -- -- config PACKAGE_B43_PHY_N -- bool "Enable support for N-PHYs" -- default y -- help -- Enable support for N-PHY. This includes support for the following devices: -- PCI: BCM4321, BCM4322, BCM43222, BCM43224, BCM43225 -- SoC: BCM4716, BCM4717, BCM4718 -- -- Currently only 11g speed is available. -- -- If unsure, say Y. -- -- config PACKAGE_B43_PHY_LP -- bool "Enable support for LP-PHYs" -- default n if TARGET_bcm47xx_mips74k -- default y -- help -- Enable support for LP-PHY. This includes support for the following devices: -- PCI: BCM4312 -- SoC: BCM5354 -- -- If unsure, say Y. -- -- config PACKAGE_B43_PHY_HT -- bool "Enable support for HT-PHYs" -- default n if TARGET_bcm47xx_legacy -- default y -- help -- Enable support for HT-PHY. This includes support for the following devices: -- PCI: BCM4331 -- -- Currently only 11g speed is available. -- -- If unsure, say Y. -- -- config PACKAGE_B43_PHY_LCN -- bool "Enable support for LCN-PHYs" -- depends on BROKEN -- default n -- help -- Currently broken. -- -- If unsure, say N. -- -- endif --endef -- --define KernelPackage/b43/description --Kernel module for Broadcom 43xx wireless support (mac80211 stack) new --endef -- --define KernelPackage/brcmutil -- $(call KernelPackage/mac80211/Default) -- TITLE:=Broadcom IEEE802.11n common driver parts -- URL:=https://wireless.wiki.kernel.org/en/users/drivers/brcm80211 -- DEPENDS+=@PCI_SUPPORT||USB_SUPPORT -- FILES:=$(PKG_BUILD_DIR)/drivers/net/wireless/broadcom/brcm80211/brcmutil/brcmutil.ko -- AUTOLOAD:=$(call AutoProbe,brcmutil) -- MENU:=1 --endef -- --define KernelPackage/brcmutil/description -- This module contains some common parts needed by Broadcom Wireless drivers brcmsmac and brcmfmac. --endef -- --define KernelPackage/brcmutil/config -- if PACKAGE_kmod-brcmutil -- -- config PACKAGE_BRCM80211_DEBUG -- bool "Broadcom wireless driver debugging" -- help -- Say Y, if you want to debug brcmsmac and brcmfmac wireless driver. -- -- endif --endef -- --PKG_BRCMSMAC_FW_NAME:=broadcom-wl --PKG_BRCMSMAC_FW_VERSION:=5.100.138 --PKG_BRCMSMAC_FW_OBJECT:=$(PKG_BRCMSMAC_FW_NAME)-$(PKG_BRCMSMAC_FW_VERSION)/linux/wl_apsta.o --PKG_BRCMSMAC_FW_SOURCE:=$(PKG_BRCMSMAC_FW_NAME)-$(PKG_BRCMSMAC_FW_VERSION).tar.bz2 --PKG_BRCMSMAC_FW_SOURCE_URL:=http://www.lwfinger.com/b43-firmware/ --PKG_BRCMSMAC_FW_HASH:=f1e7067aac5b62b67b8b6e4c517990277804339ac16065eb13c731ff909ae46f -- --define Download/brcmsmac -- FILE:=$(PKG_BRCMSMAC_FW_SOURCE) -- URL:=$(PKG_BRCMSMAC_FW_SOURCE_URL) -- HASH:=$(PKG_BRCMSMAC_FW_HASH) --endef --$(eval $(call Download,brcmsmac)) -- --define KernelPackage/brcmsmac -- $(call KernelPackage/mac80211/Default) -- TITLE:=Broadcom IEEE802.11n PCIe SoftMAC WLAN driver -- URL:=https://wireless.wiki.kernel.org/en/users/drivers/brcm80211 -- DEPENDS+=@!TARGET_bcm47xx_legacy +kmod-mac80211 +!TARGET_bcm47xx:kmod-bcma +kmod-lib-cordic +kmod-lib-crc8 +kmod-brcmutil +!BRCMSMAC_USE_FW_FROM_WL:brcmsmac-firmware -- FILES:=$(PKG_BUILD_DIR)/drivers/net/wireless/broadcom/brcm80211/brcmsmac/brcmsmac.ko -- AUTOLOAD:=$(call AutoProbe,brcmsmac) -- MENU:=1 --endef -- --define KernelPackage/brcmsmac/description -- Kernel module for Broadcom IEEE802.11n PCIe Wireless cards --endef -- --define KernelPackage/brcmsmac/config -- if PACKAGE_kmod-brcmsmac -- -- config BRCMSMAC_USE_FW_FROM_WL -- bool "Use firmware extracted from broadcom proprietary driver" -- default y -- help -- Instead of using the official brcmsmac firmware a firmware -- version 666.2 extracted from the proprietary Broadcom driver -- is used. This is needed to get core rev 17 used in bcm4716 -- to work. -- -- If unsure, say Y. -- -- endif --endef -- -- --define KernelPackage/brcmfmac -- $(call KernelPackage/mac80211/Default) -- TITLE:=Broadcom IEEE802.11n USB FullMAC WLAN driver -- URL:=https://wireless.wiki.kernel.org/en/users/drivers/brcm80211 -- DEPENDS+= @USB_SUPPORT +kmod-cfg80211 +@DRIVER_11AC_SUPPORT \ -- +kmod-brcmutil +BRCMFMAC_SDIO:kmod-mmc @!TARGET_uml \ -- +BRCMFMAC_USB:kmod-usb-core +BRCMFMAC_USB:brcmfmac-firmware-usb -- FILES:=$(PKG_BUILD_DIR)/drivers/net/wireless/broadcom/brcm80211/brcmfmac/brcmfmac.ko -- AUTOLOAD:=$(call AutoProbe,brcmfmac) --endef -- --define KernelPackage/brcmfmac/description -- Kernel module for Broadcom IEEE802.11n USB Wireless cards --endef -- --define KernelPackage/brcmfmac/config -- if PACKAGE_kmod-brcmfmac -- -- config BRCMFMAC_SDIO -- bool "Enable SDIO bus interface support" -- default y if TARGET_bcm27xx -- default y if TARGET_imx_cortexa7 -- default y if TARGET_sunxi -- default n -- help -- Enable support for cards attached to an SDIO bus. -- Select this option only if you are sure that your -- board has a Broadcom wireless chip atacched to -- that bus. -- -- config BRCMFMAC_USB -- bool "Enable USB bus interface support" -- depends on USB_SUPPORT -- default y -- help -- Supported USB connected chipsets: -- BCM43235, BCM43236, BCM43238 (all in revision 3 only) -- BCM43143, BCM43242, BCM43566, BCM43569 -- -- config BRCMFMAC_PCIE -- bool "Enable PCIE bus interface support" -- depends on PCI_SUPPORT -- default y -- help -- Supported PCIe connected chipsets: -- BCM4354, BCM4356, BCM43567, BCM43570, BCM43602 -- -- endif --endef -- -- --define KernelPackage/b43/install -- rm -rf $(1)/lib/firmware/ --ifeq ($(CONFIG_B43_OPENFIRMWARE),y) -- tar xzf "$(DL_DIR)/$(PKG_B43_FWV4_SOURCE)" -C "$(PKG_BUILD_DIR)" --else -- tar xjf "$(DL_DIR)/$(PKG_B43_FWV4_SOURCE)" -C "$(PKG_BUILD_DIR)" --endif -- $(INSTALL_DIR) $(1)/lib/firmware/ --ifeq ($(CONFIG_B43_OPENFIRMWARE),y) -- $(MAKE) -C "$(PKG_BUILD_DIR)/$(PKG_B43_FWV4_OBJECT)/" -- $(INSTALL_DIR) $(1)/lib/firmware/b43-open/ -- $(INSTALL_DATA) $(PKG_BUILD_DIR)/$(PKG_B43_FWV4_OBJECT)/ucode5.fw $(1)/lib/firmware/b43-open/ucode5.fw -- $(INSTALL_DATA) $(PKG_BUILD_DIR)/$(PKG_B43_FWV4_OBJECT)/b0g0bsinitvals5.fw $(1)/lib/firmware/b43-open/b0g0bsinitvals5.fw -- $(INSTALL_DATA) $(PKG_BUILD_DIR)/$(PKG_B43_FWV4_OBJECT)/b0g0initvals5.fw $(1)/lib/firmware/b43-open/b0g0initvals5.fw --else -- b43-fwcutter -w $(1)/lib/firmware/ $(PKG_BUILD_DIR)/$(PKG_B43_FWV4_OBJECT) --endif --ifneq ($(CONFIG_B43_FW_SQUASH),) -- b43-fwsquash.py "$(CONFIG_B43_FW_SQUASH_PHYTYPES)" "$(CONFIG_B43_FW_SQUASH_COREREVS)" "$(1)/lib/firmware/b43" --endif --endef -- --define KernelPackage/brcmsmac/install -- $(INSTALL_DIR) $(1)/lib/firmware/brcm --ifeq ($(CONFIG_BRCMSMAC_USE_FW_FROM_WL),y) -- tar xjf "$(DL_DIR)/$(PKG_BRCMSMAC_FW_SOURCE)" -C "$(PKG_BUILD_DIR)" -- b43-fwcutter --brcmsmac -w $(1)/lib/firmware/ $(PKG_BUILD_DIR)/$(PKG_BRCMSMAC_FW_OBJECT) --endif --endef -diff --git a/package/kernel/mac80211/files/lib/netifd/wireless/mac80211.sh b/package/kernel/mac80211/files/lib/netifd/wireless/mac80211.sh -deleted file mode 100644 -index 5aaba9af26..0000000000 ---- a/package/kernel/mac80211/files/lib/netifd/wireless/mac80211.sh -+++ /dev/null -@@ -1,1321 +0,0 @@ --#!/bin/sh --. /lib/netifd/netifd-wireless.sh --. /lib/netifd/hostapd.sh --. /lib/functions/system.sh -- --init_wireless_driver "$@" -- --MP_CONFIG_INT="mesh_retry_timeout mesh_confirm_timeout mesh_holding_timeout mesh_max_peer_links -- mesh_max_retries mesh_ttl mesh_element_ttl mesh_hwmp_max_preq_retries -- mesh_path_refresh_time mesh_min_discovery_timeout mesh_hwmp_active_path_timeout -- mesh_hwmp_preq_min_interval mesh_hwmp_net_diameter_traversal_time mesh_hwmp_rootmode -- mesh_hwmp_rann_interval mesh_gate_announcements mesh_sync_offset_max_neighor -- mesh_rssi_threshold mesh_hwmp_active_path_to_root_timeout mesh_hwmp_root_interval -- mesh_hwmp_confirmation_interval mesh_awake_window mesh_plink_timeout" --MP_CONFIG_BOOL="mesh_auto_open_plinks mesh_fwding" --MP_CONFIG_STRING="mesh_power_mode" -- --NEWAPLIST= --OLDAPLIST= --NEWSPLIST= --OLDSPLIST= --NEWUMLIST= --OLDUMLIST= -- --drv_mac80211_init_device_config() { -- hostapd_common_add_device_config -- -- config_add_string path phy 'macaddr:macaddr' -- config_add_string tx_burst -- config_add_string distance -- config_add_int beacon_int chanbw frag rts -- config_add_int rxantenna txantenna antenna_gain txpower min_tx_power -- config_add_boolean noscan ht_coex acs_exclude_dfs background_radar -- config_add_array ht_capab -- config_add_array channels -- config_add_array scan_list -- config_add_boolean \ -- rxldpc \ -- short_gi_80 \ -- short_gi_160 \ -- tx_stbc_2by1 \ -- su_beamformer \ -- su_beamformee \ -- mu_beamformer \ -- mu_beamformee \ -- he_su_beamformer \ -- he_su_beamformee \ -- he_mu_beamformer \ -- vht_txop_ps \ -- htc_vht \ -- rx_antenna_pattern \ -- tx_antenna_pattern \ -- he_spr_sr_control \ -- he_spr_psr_enabled \ -- he_bss_color_enabled \ -- he_twt_required -- config_add_int \ -- beamformer_antennas \ -- beamformee_antennas \ -- vht_max_a_mpdu_len_exp \ -- vht_max_mpdu \ -- vht_link_adapt \ -- vht160 \ -- rx_stbc \ -- tx_stbc \ -- he_bss_color \ -- he_spr_non_srg_obss_pd_max_offset -- config_add_boolean \ -- ldpc \ -- greenfield \ -- short_gi_20 \ -- short_gi_40 \ -- max_amsdu \ -- dsss_cck_40 --} -- --drv_mac80211_init_iface_config() { -- hostapd_common_add_bss_config -- -- config_add_string 'macaddr:macaddr' ifname -- -- config_add_boolean wds powersave enable -- config_add_string wds_bridge -- config_add_int maxassoc -- config_add_int max_listen_int -- config_add_int dtim_period -- config_add_int start_disabled -- -- # mesh -- config_add_string mesh_id -- config_add_int $MP_CONFIG_INT -- config_add_boolean $MP_CONFIG_BOOL -- config_add_string $MP_CONFIG_STRING --} -- --mac80211_add_capabilities() { -- local __var="$1"; shift -- local __mask="$1"; shift -- local __out= oifs -- -- oifs="$IFS" -- IFS=: -- for capab in "$@"; do -- set -- $capab -- -- [ "$(($4))" -gt 0 ] || continue -- [ "$(($__mask & $2))" -eq "$((${3:-$2}))" ] || continue -- __out="$__out[$1]" -- done -- IFS="$oifs" -- -- export -n -- "$__var=$__out" --} -- --mac80211_add_he_capabilities() { -- local __out= oifs -- -- oifs="$IFS" -- IFS=: -- for capab in "$@"; do -- set -- $capab -- [ "$(($4))" -gt 0 ] || continue -- [ "$(((0x$2) & $3))" -gt 0 ] || { -- eval "$1=0" -- continue -- } -- append base_cfg "$1=1" "$N" -- done -- IFS="$oifs" --} -- --mac80211_hostapd_setup_base() { -- local phy="$1" -- -- json_select config -- -- [ "$auto_channel" -gt 0 ] && channel=acs_survey -- -- [ "$auto_channel" -gt 0 ] && json_get_vars acs_exclude_dfs -- [ -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_values ht_capab_list ht_capab -- json_get_values channel_list channels -- -- [ "$auto_channel" = 0 ] && [ -z "$channel_list" ] && \ -- channel_list="$channel" -- -- [ "$min_tx_power" -gt 0 ] && append base_cfg "min_tx_power=$min_tx_power" -- -- set_default noscan 0 -- -- [ "$noscan" -gt 0 ] && hostapd_noscan=1 -- [ "$tx_burst" = 0 ] && tx_burst= -- -- chan_ofs=0 -- [ "$band" = "6g" ] && chan_ofs=1 -- -- ieee80211n=1 -- ht_capab= -- case "$htmode" in -- VHT20|HT20|HE20) ;; -- HT40*|VHT40|VHT80|VHT160|HE40|HE80|HE160) -- case "$hwmode" in -- a) -- case "$(( (($channel / 4) + $chan_ofs) % 2 ))" in -- 1) ht_capab="[HT40+]";; -- 0) ht_capab="[HT40-]";; -- esac -- ;; -- *) -- case "$htmode" in -- HT40+) ht_capab="[HT40+]";; -- HT40-) ht_capab="[HT40-]";; -- *) -- if [ "$channel" -lt 7 ]; then -- ht_capab="[HT40+]" -- else -- ht_capab="[HT40-]" -- fi -- ;; -- esac -- ;; -- esac -- [ "$auto_channel" -gt 0 ] && ht_capab="[HT40+]" -- ;; -- *) ieee80211n= ;; -- esac -- -- [ -n "$ieee80211n" ] && { -- append base_cfg "ieee80211n=1" "$N" -- -- set_default ht_coex 0 -- append base_cfg "ht_coex=$ht_coex" "$N" -- -- json_get_vars \ -- ldpc:1 \ -- greenfield:0 \ -- short_gi_20:1 \ -- short_gi_40:1 \ -- tx_stbc:1 \ -- rx_stbc:3 \ -- max_amsdu:1 \ -- dsss_cck_40:1 -- -- ht_cap_mask=0 -- for cap in $(iw phy "$phy" info | grep 'Capabilities:' | cut -d: -f2); do -- ht_cap_mask="$(($ht_cap_mask | $cap))" -- done -- -- cap_rx_stbc=$((($ht_cap_mask >> 8) & 3)) -- [ "$rx_stbc" -lt "$cap_rx_stbc" ] && cap_rx_stbc="$rx_stbc" -- ht_cap_mask="$(( ($ht_cap_mask & ~(0x300)) | ($cap_rx_stbc << 8) ))" -- -- mac80211_add_capabilities ht_capab_flags $ht_cap_mask \ -- LDPC:0x1::$ldpc \ -- GF:0x10::$greenfield \ -- SHORT-GI-20:0x20::$short_gi_20 \ -- SHORT-GI-40:0x40::$short_gi_40 \ -- TX-STBC:0x80::$tx_stbc \ -- RX-STBC1:0x300:0x100:1 \ -- RX-STBC12:0x300:0x200:1 \ -- RX-STBC123:0x300:0x300:1 \ -- MAX-AMSDU-7935:0x800::$max_amsdu \ -- DSSS_CCK-40:0x1000::$dsss_cck_40 -- -- ht_capab="$ht_capab$ht_capab_flags" -- [ -n "$ht_capab" ] && append base_cfg "ht_capab=$ht_capab" "$N" -- } -- -- # 802.11ac -- enable_ac=0 -- vht_oper_chwidth=0 -- vht_center_seg0= -- -- idx="$channel" -- case "$htmode" in -- VHT20|HE20) enable_ac=1;; -- VHT40|HE40) -- case "$(( (($channel / 4) + $chan_ofs) % 2 ))" in -- 1) idx=$(($channel + 2));; -- 0) idx=$(($channel - 2));; -- esac -- enable_ac=1 -- vht_center_seg0=$idx -- ;; -- VHT80|HE80) -- case "$(( (($channel / 4) + $chan_ofs) % 4 ))" in -- 1) idx=$(($channel + 6));; -- 2) idx=$(($channel + 2));; -- 3) idx=$(($channel - 2));; -- 0) idx=$(($channel - 6));; -- esac -- enable_ac=1 -- vht_oper_chwidth=1 -- vht_center_seg0=$idx -- ;; -- VHT160|HE160) -- if [ "$band" = "6g" ]; then -- case "$channel" in -- 1|5|9|13|17|21|25|29) idx=15;; -- 33|37|41|45|49|53|57|61) idx=47;; -- 65|69|73|77|81|85|89|93) idx=79;; -- 97|101|105|109|113|117|121|125) idx=111;; -- 129|133|137|141|145|149|153|157) idx=143;; -- 161|165|169|173|177|181|185|189) idx=175;; -- 193|197|201|205|209|213|217|221) idx=207;; -- esac -- else -- case "$channel" in -- 36|40|44|48|52|56|60|64) idx=50;; -- 100|104|108|112|116|120|124|128) idx=114;; -- esac -- fi -- enable_ac=1 -- vht_oper_chwidth=2 -- vht_center_seg0=$idx -- ;; -- esac -- [ "$band" = "5g" ] && { -- json_get_vars background_radar:0 -- -- [ "$background_radar" -eq 1 ] && append base_cfg "enable_background_radar=1" "$N" -- } -- [ "$band" = "6g" ] && { -- op_class= -- case "$htmode" in -- HE20) op_class=131;; -- HE*) op_class=$((132 + $vht_oper_chwidth)) -- esac -- [ -n "$op_class" ] && append base_cfg "op_class=$op_class" "$N" -- } -- [ "$hwmode" = "a" ] || enable_ac=0 -- -- if [ "$enable_ac" != "0" ]; then -- json_get_vars \ -- rxldpc:1 \ -- short_gi_80:1 \ -- short_gi_160:1 \ -- tx_stbc_2by1:1 \ -- su_beamformer:1 \ -- su_beamformee:1 \ -- mu_beamformer:1 \ -- mu_beamformee:1 \ -- vht_txop_ps:1 \ -- htc_vht:1 \ -- beamformee_antennas:4 \ -- beamformer_antennas:4 \ -- rx_antenna_pattern:1 \ -- tx_antenna_pattern:1 \ -- vht_max_a_mpdu_len_exp:7 \ -- vht_max_mpdu:11454 \ -- rx_stbc:4 \ -- vht_link_adapt:3 \ -- vht160:2 -- -- set_default tx_burst 2.0 -- append base_cfg "ieee80211ac=1" "$N" -- vht_cap=0 -- for cap in $(iw phy "$phy" info | awk -F "[()]" '/VHT Capabilities/ { print $2 }'); do -- vht_cap="$(($vht_cap | $cap))" -- done -- -- append base_cfg "vht_oper_chwidth=$vht_oper_chwidth" "$N" -- append base_cfg "vht_oper_centr_freq_seg0_idx=$vht_center_seg0" "$N" -- -- cap_rx_stbc=$((($vht_cap >> 8) & 7)) -- [ "$rx_stbc" -lt "$cap_rx_stbc" ] && cap_rx_stbc="$rx_stbc" -- vht_cap="$(( ($vht_cap & ~(0x700)) | ($cap_rx_stbc << 8) ))" -- -- mac80211_add_capabilities vht_capab $vht_cap \ -- RXLDPC:0x10::$rxldpc \ -- SHORT-GI-80:0x20::$short_gi_80 \ -- SHORT-GI-160:0x40::$short_gi_160 \ -- TX-STBC-2BY1:0x80::$tx_stbc_2by1 \ -- SU-BEAMFORMER:0x800::$su_beamformer \ -- SU-BEAMFORMEE:0x1000::$su_beamformee \ -- MU-BEAMFORMER:0x80000::$mu_beamformer \ -- MU-BEAMFORMEE:0x100000::$mu_beamformee \ -- VHT-TXOP-PS:0x200000::$vht_txop_ps \ -- HTC-VHT:0x400000::$htc_vht \ -- RX-ANTENNA-PATTERN:0x10000000::$rx_antenna_pattern \ -- TX-ANTENNA-PATTERN:0x20000000::$tx_antenna_pattern \ -- RX-STBC-1:0x700:0x100:1 \ -- RX-STBC-12:0x700:0x200:1 \ -- RX-STBC-123:0x700:0x300:1 \ -- RX-STBC-1234:0x700:0x400:1 \ -- -- [ "$(($vht_cap & 0x800))" -gt 0 -a "$su_beamformer" -gt 0 ] && { -- cap_ant="$(( ( ($vht_cap >> 16) & 3 ) + 1 ))" -- [ "$cap_ant" -gt "$beamformer_antennas" ] && cap_ant="$beamformer_antennas" -- [ "$cap_ant" -gt 1 ] && vht_capab="$vht_capab[SOUNDING-DIMENSION-$cap_ant]" -- } -- -- [ "$(($vht_cap & 0x1000))" -gt 0 -a "$su_beamformee" -gt 0 ] && { -- cap_ant="$(( ( ($vht_cap >> 13) & 3 ) + 1 ))" -- [ "$cap_ant" -gt "$beamformee_antennas" ] && cap_ant="$beamformee_antennas" -- [ "$cap_ant" -gt 1 ] && vht_capab="$vht_capab[BF-ANTENNA-$cap_ant]" -- } -- -- # supported Channel widths -- vht160_hw=0 -- [ "$(($vht_cap & 12))" -eq 4 -a 1 -le "$vht160" ] && \ -- vht160_hw=1 -- [ "$(($vht_cap & 12))" -eq 8 -a 2 -le "$vht160" ] && \ -- vht160_hw=2 -- [ "$vht160_hw" = 1 ] && vht_capab="$vht_capab[VHT160]" -- [ "$vht160_hw" = 2 ] && vht_capab="$vht_capab[VHT160-80PLUS80]" -- -- # maximum MPDU length -- vht_max_mpdu_hw=3895 -- [ "$(($vht_cap & 3))" -ge 1 -a 7991 -le "$vht_max_mpdu" ] && \ -- vht_max_mpdu_hw=7991 -- [ "$(($vht_cap & 3))" -ge 2 -a 11454 -le "$vht_max_mpdu" ] && \ -- vht_max_mpdu_hw=11454 -- [ "$vht_max_mpdu_hw" != 3895 ] && \ -- vht_capab="$vht_capab[MAX-MPDU-$vht_max_mpdu_hw]" -- -- # maximum A-MPDU length exponent -- vht_max_a_mpdu_len_exp_hw=0 -- [ "$(($vht_cap & 58720256))" -ge 8388608 -a 1 -le "$vht_max_a_mpdu_len_exp" ] && \ -- vht_max_a_mpdu_len_exp_hw=1 -- [ "$(($vht_cap & 58720256))" -ge 16777216 -a 2 -le "$vht_max_a_mpdu_len_exp" ] && \ -- vht_max_a_mpdu_len_exp_hw=2 -- [ "$(($vht_cap & 58720256))" -ge 25165824 -a 3 -le "$vht_max_a_mpdu_len_exp" ] && \ -- vht_max_a_mpdu_len_exp_hw=3 -- [ "$(($vht_cap & 58720256))" -ge 33554432 -a 4 -le "$vht_max_a_mpdu_len_exp" ] && \ -- vht_max_a_mpdu_len_exp_hw=4 -- [ "$(($vht_cap & 58720256))" -ge 41943040 -a 5 -le "$vht_max_a_mpdu_len_exp" ] && \ -- vht_max_a_mpdu_len_exp_hw=5 -- [ "$(($vht_cap & 58720256))" -ge 50331648 -a 6 -le "$vht_max_a_mpdu_len_exp" ] && \ -- vht_max_a_mpdu_len_exp_hw=6 -- [ "$(($vht_cap & 58720256))" -ge 58720256 -a 7 -le "$vht_max_a_mpdu_len_exp" ] && \ -- vht_max_a_mpdu_len_exp_hw=7 -- vht_capab="$vht_capab[MAX-A-MPDU-LEN-EXP$vht_max_a_mpdu_len_exp_hw]" -- -- # whether or not the STA supports link adaptation using VHT variant -- vht_link_adapt_hw=0 -- [ "$(($vht_cap & 201326592))" -ge 134217728 -a 2 -le "$vht_link_adapt" ] && \ -- vht_link_adapt_hw=2 -- [ "$(($vht_cap & 201326592))" -ge 201326592 -a 3 -le "$vht_link_adapt" ] && \ -- vht_link_adapt_hw=3 -- [ "$vht_link_adapt_hw" != 0 ] && \ -- vht_capab="$vht_capab[VHT-LINK-ADAPT-$vht_link_adapt_hw]" -- -- [ -n "$vht_capab" ] && append base_cfg "vht_capab=$vht_capab" "$N" -- fi -- -- # 802.11ax -- enable_ax=0 -- case "$htmode" in -- HE*) enable_ax=1 ;; -- esac -- -- if [ "$enable_ax" != "0" ]; then -- json_get_vars \ -- he_su_beamformer:1 \ -- he_su_beamformee:1 \ -- he_mu_beamformer:1 \ -- he_twt_required:0 \ -- he_spr_sr_control:3 \ -- he_spr_psr_enabled:0 \ -- he_spr_non_srg_obss_pd_max_offset:0 \ -- he_bss_color:128 \ -- he_bss_color_enabled:1 -- -- he_phy_cap=$(iw phy "$phy" info | sed -n '/HE Iftypes: AP/,$p' | awk -F "[()]" '/HE PHY Capabilities/ { print $2 }' | head -1) -- he_phy_cap=${he_phy_cap:2} -- he_mac_cap=$(iw phy "$phy" info | sed -n '/HE Iftypes: AP/,$p' | awk -F "[()]" '/HE MAC Capabilities/ { print $2 }' | head -1) -- he_mac_cap=${he_mac_cap:2} -- -- append base_cfg "ieee80211ax=1" "$N" -- [ "$hwmode" = "a" ] && { -- append base_cfg "he_oper_chwidth=$vht_oper_chwidth" "$N" -- append base_cfg "he_oper_centr_freq_seg0_idx=$vht_center_seg0" "$N" -- } -- -- mac80211_add_he_capabilities \ -- he_su_beamformer:${he_phy_cap:6:2}:0x80:$he_su_beamformer \ -- he_su_beamformee:${he_phy_cap:8:2}:0x1:$he_su_beamformee \ -- he_mu_beamformer:${he_phy_cap:8:2}:0x2:$he_mu_beamformer \ -- he_spr_psr_enabled:${he_phy_cap:14:2}:0x1:$he_spr_psr_enabled \ -- he_twt_required:${he_mac_cap:0:2}:0x6:$he_twt_required -- -- if [ "$he_bss_color_enabled" -gt 0 ]; then -- append base_cfg "he_bss_color=$he_bss_color" "$N" -- [ "$he_spr_non_srg_obss_pd_max_offset" -gt 0 ] && { \ -- append base_cfg "he_spr_non_srg_obss_pd_max_offset=$he_spr_non_srg_obss_pd_max_offset" "$N" -- he_spr_sr_control=$((he_spr_sr_control | (1 << 2))) -- } -- [ "$he_spr_psr_enabled" -gt 0 ] || he_spr_sr_control=$((he_spr_sr_control | (1 << 0))) -- append base_cfg "he_spr_sr_control=$he_spr_sr_control" "$N" -- else -- append base_cfg "he_bss_color_disabled=1" "$N" -- fi -- -- -- append base_cfg "he_default_pe_duration=4" "$N" -- append base_cfg "he_rts_threshold=1023" "$N" -- append base_cfg "he_mu_edca_qos_info_param_count=0" "$N" -- append base_cfg "he_mu_edca_qos_info_q_ack=0" "$N" -- append base_cfg "he_mu_edca_qos_info_queue_request=0" "$N" -- append base_cfg "he_mu_edca_qos_info_txop_request=0" "$N" -- append base_cfg "he_mu_edca_ac_be_aifsn=8" "$N" -- append base_cfg "he_mu_edca_ac_be_aci=0" "$N" -- append base_cfg "he_mu_edca_ac_be_ecwmin=9" "$N" -- append base_cfg "he_mu_edca_ac_be_ecwmax=10" "$N" -- append base_cfg "he_mu_edca_ac_be_timer=255" "$N" -- append base_cfg "he_mu_edca_ac_bk_aifsn=15" "$N" -- append base_cfg "he_mu_edca_ac_bk_aci=1" "$N" -- append base_cfg "he_mu_edca_ac_bk_ecwmin=9" "$N" -- append base_cfg "he_mu_edca_ac_bk_ecwmax=10" "$N" -- append base_cfg "he_mu_edca_ac_bk_timer=255" "$N" -- append base_cfg "he_mu_edca_ac_vi_ecwmin=5" "$N" -- append base_cfg "he_mu_edca_ac_vi_ecwmax=7" "$N" -- append base_cfg "he_mu_edca_ac_vi_aifsn=5" "$N" -- append base_cfg "he_mu_edca_ac_vi_aci=2" "$N" -- append base_cfg "he_mu_edca_ac_vi_timer=255" "$N" -- append base_cfg "he_mu_edca_ac_vo_aifsn=5" "$N" -- append base_cfg "he_mu_edca_ac_vo_aci=3" "$N" -- append base_cfg "he_mu_edca_ac_vo_ecwmin=5" "$N" -- append base_cfg "he_mu_edca_ac_vo_ecwmax=7" "$N" -- append base_cfg "he_mu_edca_ac_vo_timer=255" "$N" -- fi -- -- hostapd_prepare_device_config "$hostapd_conf_file" nl80211 -- cat >> "$hostapd_conf_file" <> $hostapd_conf_file --} -- --mac80211_hostapd_setup_bss() { -- local phy="$1" -- local ifname="$2" -- local macaddr="$3" -- local type="$4" -- -- hostapd_cfg= -- append hostapd_cfg "$type=$ifname" "$N" -- -- hostapd_set_bss_options hostapd_cfg "$phy" "$vif" || return 1 -- json_get_vars wds wds_bridge dtim_period max_listen_int start_disabled -- -- set_default wds 0 -- set_default start_disabled 0 -- -- [ "$wds" -gt 0 ] && { -- append hostapd_cfg "wds_sta=1" "$N" -- [ -n "$wds_bridge" ] && append hostapd_cfg "wds_bridge=$wds_bridge" "$N" -- } -- [ "$staidx" -gt 0 -o "$start_disabled" -eq 1 ] && append hostapd_cfg "start_disabled=1" "$N" -- -- cat >> /var/run/hostapd-$phy.conf </dev/null); do -- grep -i -q "$macaddr" "/sys/class/ieee80211/${phy}/macaddress" && { -- path="$(iwinfo nl80211 path "$phy")" -- rename_board_phy_by_path "$path" -- return 0 -- } -- done -- } -- return 1 --} -- --mac80211_check_ap() { -- has_ap=1 --} -- --mac80211_iw_interface_add() { -- local phy="$1" -- local ifname="$2" -- local type="$3" -- local wdsflag="$4" -- local rc -- local oldifname -- -- iw phy "$phy" interface add "$ifname" type "$type" $wdsflag >/dev/null 2>&1 -- rc="$?" -- -- [ "$rc" = 233 ] && { -- # Device might have just been deleted, give the kernel some time to finish cleaning it up -- sleep 1 -- -- iw phy "$phy" interface add "$ifname" type "$type" $wdsflag >/dev/null 2>&1 -- rc="$?" -- } -- -- [ "$rc" = 233 ] && { -- # Keep matching pre-existing interface -- [ -d "/sys/class/ieee80211/${phy}/device/net/${ifname}" ] && \ -- case "$(iw dev $ifname info | grep "^\ttype" | cut -d' ' -f2- 2>/dev/null)" in -- "AP") -- [ "$type" = "__ap" ] && rc=0 -- ;; -- "IBSS") -- [ "$type" = "adhoc" ] && rc=0 -- ;; -- "managed") -- [ "$type" = "managed" ] && rc=0 -- ;; -- "mesh point") -- [ "$type" = "mp" ] && rc=0 -- ;; -- "monitor") -- [ "$type" = "monitor" ] && rc=0 -- ;; -- esac -- } -- -- [ "$rc" = 233 ] && { -- iw dev "$ifname" del >/dev/null 2>&1 -- [ "$?" = 0 ] && { -- sleep 1 -- -- iw phy "$phy" interface add "$ifname" type "$type" $wdsflag >/dev/null 2>&1 -- rc="$?" -- } -- } -- -- [ "$rc" != 0 ] && { -- # Device might not support virtual interfaces, so the interface never got deleted in the first place. -- # Check if the interface already exists, and avoid failing in this case. -- [ -d "/sys/class/ieee80211/${phy}/device/net/${ifname}" ] && rc=0 -- } -- -- [ "$rc" != 0 ] && { -- # Device doesn't support virtual interfaces and may have existing interface other than ifname. -- oldifname="$(basename "/sys/class/ieee80211/${phy}/device/net"/* 2>/dev/null)" -- [ "$oldifname" ] && ip link set "$oldifname" name "$ifname" 1>/dev/null 2>&1 -- rc="$?" -- } -- -- [ "$rc" != 0 ] && echo "Failed to create interface $ifname" -- return $rc --} -- --mac80211_set_ifname() { -- local phy="$1" -- local prefix="$2" -- eval "ifname=\"$phy-$prefix\${idx_$prefix:-0}\"; idx_$prefix=\$((\${idx_$prefix:-0 } + 1))" --} -- --mac80211_prepare_vif() { -- json_select config -- -- json_get_vars ifname mode ssid wds powersave macaddr enable wpa_psk_file vlan_file -- -- [ -n "$ifname" ] || { -- local prefix; -- -- case "$mode" in -- ap|sta|mesh) prefix=$mode;; -- adhoc) prefix=ibss;; -- monitor) prefix=mon;; -- esac -- -- mac80211_set_ifname "$phy" "$prefix" -- } -- -- set_default wds 0 -- set_default powersave 0 -- -- json_select .. -- -- if [ -z "$macaddr" ]; then -- macaddr="$(mac80211_generate_mac $phy)" -- macidx="$(($macidx + 1))" -- elif [ "$macaddr" = 'random' ]; then -- macaddr="$(macaddr_random)" -- fi -- -- json_add_object data -- json_add_string ifname "$ifname" -- json_close_object -- -- [ "$mode" == "ap" ] && { -- [ -z "$wpa_psk_file" ] && hostapd_set_psk "$ifname" -- [ -z "$vlan_file" ] && hostapd_set_vlan "$ifname" -- } -- -- json_select config -- -- # It is far easier to delete and create the desired interface -- case "$mode" in -- adhoc) -- mac80211_iw_interface_add "$phy" "$ifname" adhoc || return -- ;; -- ap) -- # Hostapd will handle recreating the interface and -- # subsequent virtual APs belonging to the same PHY -- if [ -n "$hostapd_ctrl" ]; then -- type=bss -- else -- type=interface -- fi -- -- mac80211_hostapd_setup_bss "$phy" "$ifname" "$macaddr" "$type" || return -- -- NEWAPLIST="${NEWAPLIST}$ifname " -- [ -n "$hostapd_ctrl" ] || { -- ap_ifname="${ifname}" -- hostapd_ctrl="${hostapd_ctrl:-/var/run/hostapd/$ifname}" -- } -- ;; -- mesh) -- mac80211_iw_interface_add "$phy" "$ifname" mp || return -- ;; -- monitor) -- mac80211_iw_interface_add "$phy" "$ifname" monitor || return -- ;; -- sta) -- local wdsflag= -- [ "$enable" = 0 ] || staidx="$(($staidx + 1))" -- [ "$wds" -gt 0 ] && wdsflag="4addr on" -- mac80211_iw_interface_add "$phy" "$ifname" managed "$wdsflag" || return -- if [ "$wds" -gt 0 ]; then -- iw "$ifname" set 4addr on -- else -- iw "$ifname" set 4addr off -- fi -- [ "$powersave" -gt 0 ] && powersave="on" || powersave="off" -- iw "$ifname" set power_save "$powersave" -- ;; -- esac -- -- case "$mode" in -- monitor|mesh) -- [ "$auto_channel" -gt 0 ] || iw dev "$ifname" set channel "$channel" $iw_htmode -- ;; -- esac -- -- if [ "$mode" != "ap" ]; then -- # ALL ap functionality will be passed to hostapd -- # All interfaces must have unique mac addresses -- # which can either be explicitly set in the device -- # section, or automatically generated -- ip link set dev "$ifname" address "$macaddr" -- fi -- -- json_select .. --} -- --mac80211_setup_supplicant() { -- local enable=$1 -- local add_sp=0 -- local spobj="$(ubus -S list | grep wpa_supplicant.${ifname})" -- -- [ "$enable" = 0 ] && { -- ubus call wpa_supplicant.${phy} config_remove "{\"iface\":\"$ifname\"}" -- ip link set dev "$ifname" down -- iw dev "$ifname" del -- return 0 -- } -- -- wpa_supplicant_prepare_interface "$ifname" nl80211 || { -- iw dev "$ifname" del -- return 1 -- } -- if [ "$mode" = "sta" ]; then -- wpa_supplicant_add_network "$ifname" -- else -- wpa_supplicant_add_network "$ifname" "$freq" "$htmode" "$noscan" -- fi -- -- NEWSPLIST="${NEWSPLIST}$ifname " -- -- if [ "${NEWAPLIST%% *}" != "${OLDAPLIST%% *}" ]; then -- [ "$spobj" ] && ubus call wpa_supplicant config_remove "{\"iface\":\"$ifname\"}" -- add_sp=1 -- fi -- [ -z "$spobj" ] && add_sp=1 -- -- NEW_MD5_SP=$(test -e "${_config}" && md5sum ${_config}) -- OLD_MD5_SP=$(uci -q -P /var/state get wireless._${phy}.md5_${ifname}) -- if [ "$add_sp" = "1" ]; then -- wpa_supplicant_run "$ifname" "$hostapd_ctrl" -- else -- [ "${NEW_MD5_SP}" == "${OLD_MD5_SP}" ] || ubus call $spobj reload -- fi -- uci -q -P /var/state set wireless._${phy}.md5_${ifname}="${NEW_MD5_SP}" -- return 0 --} -- --mac80211_setup_supplicant_noctl() { -- local enable=$1 -- local spobj="$(ubus -S list | grep wpa_supplicant.${ifname})" -- wpa_supplicant_prepare_interface "$ifname" nl80211 || { -- iw dev "$ifname" del -- return 1 -- } -- -- wpa_supplicant_add_network "$ifname" "$freq" "$htmode" "$noscan" -- -- NEWSPLIST="${NEWSPLIST}$ifname " -- [ "$enable" = 0 ] && { -- ubus call wpa_supplicant config_remove "{\"iface\":\"$ifname\"}" -- ip link set dev "$ifname" down -- return 0 -- } -- if [ -z "$spobj" ]; then -- wpa_supplicant_run "$ifname" -- else -- ubus call $spobj reload -- fi --} -- --mac80211_prepare_iw_htmode() { -- case "$htmode" in -- VHT20|HT20|HE20) iw_htmode=HT20;; -- HT40*|VHT40|VHT160|HE40) -- case "$band" in -- 2g) -- case "$htmode" in -- HT40+) iw_htmode="HT40+";; -- HT40-) iw_htmode="HT40-";; -- *) -- if [ "$channel" -lt 7 ]; then -- iw_htmode="HT40+" -- else -- iw_htmode="HT40-" -- fi -- ;; -- esac -- ;; -- *) -- case "$(( ($channel / 4) % 2 ))" in -- 1) iw_htmode="HT40+" ;; -- 0) iw_htmode="HT40-";; -- esac -- ;; -- esac -- [ "$auto_channel" -gt 0 ] && iw_htmode="HT40+" -- ;; -- VHT80|HE80) -- iw_htmode="80MHZ" -- ;; -- NONE|NOHT) -- iw_htmode="NOHT" -- ;; -- *) iw_htmode="" ;; -- esac --} -- --mac80211_setup_adhoc() { -- local enable=$1 -- json_get_vars bssid ssid key mcast_rate -- -- NEWUMLIST="${NEWUMLIST}$ifname " -- -- [ "$enable" = 0 ] && { -- ip link set dev "$ifname" down -- return 0 -- } -- -- keyspec= -- [ "$auth_type" = "wep" ] && { -- set_default key 1 -- case "$key" in -- [1234]) -- local idx -- for idx in 1 2 3 4; do -- json_get_var ikey "key$idx" -- -- [ -n "$ikey" ] && { -- ikey="$(($idx - 1)):$(prepare_key_wep "$ikey")" -- [ $idx -eq $key ] && ikey="d:$ikey" -- append keyspec "$ikey" -- } -- done -- ;; -- *) -- append keyspec "d:0:$(prepare_key_wep "$key")" -- ;; -- esac -- } -- -- brstr= -- for br in $basic_rate_list; do -- wpa_supplicant_add_rate brstr "$br" -- done -- -- mcval= -- [ -n "$mcast_rate" ] && wpa_supplicant_add_rate mcval "$mcast_rate" -- -- iw dev "$ifname" set type ibss -- iw dev "$ifname" ibss join "$ssid" $freq $iw_htmode fixed-freq $bssid \ -- beacon-interval $beacon_int \ -- ${brstr:+basic-rates $brstr} \ -- ${mcval:+mcast-rate $mcval} \ -- ${keyspec:+keys $keyspec} --} -- --mac80211_setup_mesh() { -- local enable=$1 -- json_get_vars ssid mesh_id mcast_rate -- -- NEWUMLIST="${NEWUMLIST}$ifname " -- -- [ "$enable" = 0 ] && { -- ip link set dev "$ifname" down -- return 0 -- } -- -- mcval= -- [ -n "$mcast_rate" ] && wpa_supplicant_add_rate mcval "$mcast_rate" -- [ -n "$mesh_id" ] && ssid="$mesh_id" -- -- iw dev "$ifname" mesh join "$ssid" freq $freq $iw_htmode \ -- ${mcval:+mcast-rate $mcval} \ -- beacon-interval $beacon_int --} -- --mac80211_setup_vif() { -- local name="$1" -- local failed -- local action=up -- -- json_select data -- json_get_vars ifname -- json_select .. -- -- json_select config -- json_get_vars mode -- json_get_var vif_txpower -- json_get_var vif_enable enable 1 -- -- [ "$vif_enable" = 1 ] || action=down -- if [ "$mode" != "ap" ] || [ "$ifname" = "$ap_ifname" ]; then -- ip link set dev "$ifname" "$action" || { -- wireless_setup_vif_failed IFUP_ERROR -- json_select .. -- return -- } -- [ -z "$vif_txpower" ] || iw dev "$ifname" set txpower fixed "${vif_txpower%%.*}00" -- fi -- -- case "$mode" in -- mesh) -- wireless_vif_parse_encryption -- [ -z "$htmode" ] && htmode="NOHT"; -- if wpa_supplicant -vmesh || [ "$wpa" -gt 0 -o "$auto_channel" -gt 0 ] || chan_is_dfs "$phy" "$channel"; then -- mac80211_setup_supplicant $vif_enable || failed=1 -- else -- mac80211_setup_mesh $vif_enable -- fi -- for var in $MP_CONFIG_INT $MP_CONFIG_BOOL $MP_CONFIG_STRING; do -- json_get_var mp_val "$var" -- [ -n "$mp_val" ] && iw dev "$ifname" set mesh_param "$var" "$mp_val" -- done -- ;; -- adhoc) -- wireless_vif_parse_encryption -- if [ "$wpa" -gt 0 -o "$auto_channel" -gt 0 ]; then -- mac80211_setup_supplicant_noctl $vif_enable || failed=1 -- else -- mac80211_setup_adhoc $vif_enable -- fi -- ;; -- sta) -- mac80211_setup_supplicant $vif_enable || failed=1 -- ;; -- esac -- -- json_select .. -- [ -n "$failed" ] || wireless_add_vif "$name" "$ifname" --} -- --get_freq() { -- local phy="$1" -- local channel="$2" -- local band="$3" -- -- case "$band" in -- 2g) band="1:";; -- 5g) band="2:";; -- 60g) band="3:";; -- 6g) band="4:";; -- esac -- -- iw "$phy" info | awk -v band="$band" -v channel="[$channel]" ' -- --$1 ~ /Band/ { -- band_match = band == $2 --} -- --band_match && $3 == "MHz" && $4 == channel { -- print $2 -- exit --} --' --} -- -- --chan_is_dfs() { -- local phy="$1" -- local chan="$2" -- iw "$phy" info | grep -E -m1 "(\* ${chan:-....} MHz${chan:+|\\[$chan\\]})" | grep -q "MHz.*radar detection" -- return $! --} -- --mac80211_vap_cleanup() { -- local service="$1" -- local vaps="$2" -- -- for wdev in $vaps; do -- [ "$service" != "none" ] && ubus call ${service} config_remove "{\"iface\":\"$wdev\"}" -- ip link set dev "$wdev" down 2>/dev/null -- iw dev "$wdev" del -- done --} -- --mac80211_interface_cleanup() { -- local phy="$1" -- local primary_ap=$(uci -q -P /var/state get wireless._${phy}.aplist) -- primary_ap=${primary_ap%% *} -- -- mac80211_vap_cleanup hostapd "${primary_ap}" -- mac80211_vap_cleanup wpa_supplicant "$(uci -q -P /var/state get wireless._${phy}.splist)" -- mac80211_vap_cleanup none "$(uci -q -P /var/state get wireless._${phy}.umlist)" --} -- --mac80211_set_noscan() { -- hostapd_noscan=1 --} -- --drv_mac80211_cleanup() { -- hostapd_common_cleanup --} -- --drv_mac80211_setup() { -- json_select config -- json_get_vars \ -- phy macaddr path \ -- country chanbw distance \ -- txpower antenna_gain \ -- rxantenna txantenna \ -- frag rts beacon_int:100 htmode -- json_get_values basic_rate_list basic_rate -- json_get_values scan_list scan_list -- json_select .. -- -- find_phy || { -- echo "Could not find PHY for device '$1'" -- wireless_set_retry 0 -- return 1 -- } -- -- wireless_set_data phy="$phy" -- [ -z "$(uci -q -P /var/state show wireless._${phy})" ] && uci -q -P /var/state set wireless._${phy}=phy -- -- OLDAPLIST=$(uci -q -P /var/state get wireless._${phy}.aplist) -- OLDSPLIST=$(uci -q -P /var/state get wireless._${phy}.splist) -- OLDUMLIST=$(uci -q -P /var/state get wireless._${phy}.umlist) -- -- local wdev -- local cwdev -- local found -- -- for wdev in $(list_phy_interfaces "$phy"); do -- found=0 -- for cwdev in $OLDAPLIST $OLDSPLIST $OLDUMLIST; do -- if [ "$wdev" = "$cwdev" ]; then -- found=1 -- break -- fi -- done -- if [ "$found" = "0" ]; then -- ip link set dev "$wdev" down -- iw dev "$wdev" del -- fi -- done -- -- # convert channel to frequency -- [ "$auto_channel" -gt 0 ] || freq="$(get_freq "$phy" "$channel" "$band")" -- -- [ -n "$country" ] && { -- iw reg get | grep -q "^country $country:" || { -- iw reg set "$country" -- sleep 1 -- } -- } -- -- hostapd_conf_file="/var/run/hostapd-$phy.conf" -- -- no_ap=1 -- macidx=0 -- staidx=0 -- -- [ -n "$chanbw" ] && { -- for file in /sys/kernel/debug/ieee80211/$phy/ath9k*/chanbw /sys/kernel/debug/ieee80211/$phy/ath5k/bwmode; do -- [ -f "$file" ] && echo "$chanbw" > "$file" -- done -- } -- -- set_default rxantenna 0xffffffff -- set_default txantenna 0xffffffff -- set_default distance 0 -- set_default antenna_gain 0 -- -- [ "$txantenna" = "all" ] && txantenna=0xffffffff -- [ "$rxantenna" = "all" ] && rxantenna=0xffffffff -- -- iw phy "$phy" set antenna $txantenna $rxantenna >/dev/null 2>&1 -- iw phy "$phy" set antenna_gain $antenna_gain >/dev/null 2>&1 -- iw phy "$phy" set distance "$distance" >/dev/null 2>&1 -- -- if [ -n "$txpower" ]; then -- iw phy "$phy" set txpower fixed "${txpower%%.*}00" -- else -- iw phy "$phy" set txpower auto -- fi -- -- [ -n "$frag" ] && iw phy "$phy" set frag "${frag%%.*}" -- [ -n "$rts" ] && iw phy "$phy" set rts "${rts%%.*}" -- -- has_ap= -- hostapd_ctrl= -- ap_ifname= -- hostapd_noscan= -- for_each_interface "ap" mac80211_check_ap -- -- rm -f "$hostapd_conf_file" -- -- for_each_interface "sta adhoc mesh" mac80211_set_noscan -- [ -n "$has_ap" ] && mac80211_hostapd_setup_base "$phy" -- -- mac80211_prepare_iw_htmode -- for_each_interface "sta adhoc mesh monitor" mac80211_prepare_vif -- NEWAPLIST= -- for_each_interface "ap" mac80211_prepare_vif -- NEW_MD5=$(test -e "${hostapd_conf_file}" && md5sum ${hostapd_conf_file}) -- OLD_MD5=$(uci -q -P /var/state get wireless._${phy}.md5) -- if [ "${NEWAPLIST}" != "${OLDAPLIST}" ]; then -- mac80211_vap_cleanup hostapd "${OLDAPLIST}" -- fi -- [ -n "${NEWAPLIST}" ] && mac80211_iw_interface_add "$phy" "${NEWAPLIST%% *}" __ap -- local add_ap=0 -- local primary_ap=${NEWAPLIST%% *} -- [ -n "$hostapd_ctrl" ] && { -- local no_reload=1 -- if [ -n "$(ubus list | grep hostapd.$primary_ap)" ]; then -- no_reload=0 -- [ "${NEW_MD5}" = "${OLD_MD5}" ] || { -- ubus call hostapd.$primary_ap reload -- no_reload=$? -- if [ "$no_reload" != "0" ]; then -- mac80211_vap_cleanup hostapd "${OLDAPLIST}" -- mac80211_vap_cleanup wpa_supplicant "$(uci -q -P /var/state get wireless._${phy}.splist)" -- mac80211_vap_cleanup none "$(uci -q -P /var/state get wireless._${phy}.umlist)" -- sleep 2 -- mac80211_iw_interface_add "$phy" "${NEWAPLIST%% *}" __ap -- for_each_interface "sta adhoc mesh monitor" mac80211_prepare_vif -- fi -- } -- fi -- if [ "$no_reload" != "0" ]; then -- add_ap=1 -- ubus wait_for hostapd -- local hostapd_res="$(ubus call hostapd config_add "{\"iface\":\"$primary_ap\", \"config\":\"${hostapd_conf_file}\"}")" -- ret="$?" -- [ "$ret" != 0 -o -z "$hostapd_res" ] && { -- wireless_setup_failed HOSTAPD_START_FAILED -- return -- } -- wireless_add_process "$(jsonfilter -s "$hostapd_res" -l 1 -e @.pid)" "/usr/sbin/hostapd" 1 1 -- fi -- } -- uci -q -P /var/state set wireless._${phy}.aplist="${NEWAPLIST}" -- uci -q -P /var/state set wireless._${phy}.md5="${NEW_MD5}" -- -- [ "${add_ap}" = 1 ] && sleep 1 -- for_each_interface "ap" mac80211_setup_vif -- -- NEWSPLIST= -- NEWUMLIST= -- -- for_each_interface "sta adhoc mesh monitor" mac80211_setup_vif -- -- uci -q -P /var/state set wireless._${phy}.splist="${NEWSPLIST}" -- uci -q -P /var/state set wireless._${phy}.umlist="${NEWUMLIST}" -- -- local foundvap -- local dropvap="" -- for oldvap in $OLDSPLIST; do -- foundvap=0 -- for newvap in $NEWSPLIST; do -- [ "$oldvap" = "$newvap" ] && foundvap=1 -- done -- [ "$foundvap" = "0" ] && dropvap="$dropvap $oldvap" -- done -- [ -n "$dropvap" ] && mac80211_vap_cleanup wpa_supplicant "$dropvap" -- wireless_set_up --} -- --_list_phy_interfaces() { -- local phy="$1" -- if [ -d "/sys/class/ieee80211/${phy}/device/net" ]; then -- ls "/sys/class/ieee80211/${phy}/device/net" 2>/dev/null; -- else -- ls "/sys/class/ieee80211/${phy}/device" 2>/dev/null | grep net: | sed -e 's,net:,,g' -- fi --} -- --list_phy_interfaces() { -- local phy="$1" -- -- for dev in $(_list_phy_interfaces "$phy"); do -- readlink "/sys/class/net/${dev}/phy80211" | grep -q "/${phy}\$" || continue -- echo "$dev" -- done --} -- --drv_mac80211_teardown() { -- json_select data -- json_get_vars phy -- json_select .. -- [ -n "$phy" ] || { -- echo "Bug: PHY is undefined for device '$1'" -- return 1 -- } -- -- mac80211_interface_cleanup "$phy" -- uci -q -P /var/state revert wireless._${phy} --} -- --add_driver mac80211 -diff --git a/package/kernel/mac80211/files/lib/wifi/mac80211.sh b/package/kernel/mac80211/files/lib/wifi/mac80211.sh -deleted file mode 100644 -index e24a2a634e..0000000000 ---- a/package/kernel/mac80211/files/lib/wifi/mac80211.sh -+++ /dev/null -@@ -1,217 +0,0 @@ --#!/bin/sh -- --append DRIVERS "mac80211" -- --check_mac80211_device() { -- local device="$1" -- local path="$2" -- local macaddr="$3" -- -- [ -n "$found" ] && return 0 -- -- phy_path= -- config_get phy "$device" phy -- json_select wlan -- [ -n "$phy" ] && case "$phy" in -- phy*) -- [ -d /sys/class/ieee80211/$phy ] && \ -- phy_path="$(iwinfo nl80211 path "$dev")" -- ;; -- *) -- if json_is_a "$phy" object; then -- json_select "$phy" -- json_get_var phy_path path -- json_select .. -- elif json_is_a "${phy%.*}" object; then -- json_select "${phy%.*}" -- json_get_var phy_path path -- json_select .. -- phy_path="$phy_path+${phy##*.}" -- fi -- ;; -- esac -- json_select .. -- [ -n "$phy_path" ] || config_get phy_path "$device" path -- [ -n "$path" -a "$phy_path" = "$path" ] && { -- found=1 -- return 0 -- } -- -- config_get dev_macaddr "$device" macaddr -- -- [ -n "$macaddr" -a "$dev_macaddr" = "$macaddr" ] && found=1 -- -- return 0 --} -- -- --__get_band_defaults() { -- local phy="$1" -- -- ( iw phy "$phy" info; echo ) | awk ' --BEGIN { -- bands = "" --} -- --($1 == "Band" || $1 == "") && band { -- if (channel) { -- mode="NOHT" -- if (ht) mode="HT20" -- if (vht && band != "1:") mode="VHT80" -- if (he) mode="HE80" -- if (he && band == "1:") mode="HE20" -- sub("\\[", "", channel) -- sub("\\]", "", channel) -- bands = bands band channel ":" mode " " -- } -- band="" --} -- --$1 == "Band" { -- band = $2 -- channel = "" -- vht = "" -- ht = "" -- he = "" --} -- --$0 ~ "Capabilities:" { -- ht=1 --} -- --$0 ~ "VHT Capabilities" { -- vht=1 --} -- --$0 ~ "HE Iftypes" { -- he=1 --} -- --$1 == "*" && $3 == "MHz" && $0 !~ /disabled/ && band && !channel { -- channel = $4 --} -- --END { -- print bands --}' --} -- --get_band_defaults() { -- local phy="$1" -- -- for c in $(__get_band_defaults "$phy"); do -- local band="${c%%:*}" -- c="${c#*:}" -- local chan="${c%%:*}" -- c="${c#*:}" -- local mode="${c%%:*}" -- -- case "$band" in -- 1) band=2g;; -- 2) band=5g;; -- 3) band=60g;; -- 4) band=6g;; -- *) band="";; -- esac -- -- [ -n "$band" ] || continue -- [ -n "$mode_band" -a "$band" = "6g" ] && return -- -- mode_band="$band" -- channel="$chan" -- htmode="$mode" -- done --} -- --check_devidx() { -- case "$1" in -- radio[0-9]*) -- local idx="${1#radio}" -- [ "$devidx" -ge "${1#radio}" ] && devidx=$((idx + 1)) -- ;; -- esac --} -- --check_board_phy() { -- local name="$2" -- -- json_select "$name" -- json_get_var phy_path path -- json_select .. -- -- if [ "$path" = "$phy_path" ]; then -- board_dev="$name" -- elif [ "${path%+*}" = "$phy_path" ]; then -- fallback_board_dev="$name.${path#*+}" -- fi --} -- --detect_mac80211() { -- devidx=0 -- config_load wireless -- config_foreach check_devidx wifi-device -- -- json_load_file /etc/board.json -- -- for _dev in /sys/class/ieee80211/*; do -- [ -e "$_dev" ] || continue -- -- dev="${_dev##*/}" -- -- mode_band="" -- channel="" -- htmode="" -- ht_capab="" -- -- get_band_defaults "$dev" -- -- path="$(iwinfo nl80211 path "$dev")" -- macaddr="$(cat /sys/class/ieee80211/${dev}/macaddress)" -- -- # work around phy rename related race condition -- [ -n "$path" -o -n "$macaddr" ] || continue -- -- board_dev= -- fallback_board_dev= -- json_for_each_item check_board_phy wlan -- [ -n "$board_dev" ] || board_dev="$fallback_board_dev" -- [ -n "$board_dev" ] && dev="$board_dev" -- -- found= -- config_foreach check_mac80211_device wifi-device "$path" "$macaddr" -- [ -n "$found" ] && continue -- -- name="radio${devidx}" -- devidx=$(($devidx + 1)) -- case "$dev" in -- phy*) -- if [ -n "$path" ]; then -- dev_id="set wireless.${name}.path='$path'" -- else -- dev_id="set wireless.${name}.macaddr='$macaddr'" -- fi -- ;; -- *) -- dev_id="set wireless.${name}.phy='$dev'" -- ;; -- esac -- -- uci -q batch <<-EOF -- set wireless.${name}=wifi-device -- set wireless.${name}.type=mac80211 -- ${dev_id} -- set wireless.${name}.channel=${channel} -- set wireless.${name}.band=${mode_band} -- set wireless.${name}.htmode=$htmode -- set wireless.${name}.disabled=1 -- -- set wireless.default_${name}=wifi-iface -- set wireless.default_${name}.device=${name} -- set wireless.default_${name}.network=lan -- set wireless.default_${name}.mode=ap -- set wireless.default_${name}.ssid=OpenWrt -- set wireless.default_${name}.encryption=none --EOF -- uci -q commit wireless -- done --} -diff --git a/package/kernel/mac80211/files/mac80211.hotplug b/package/kernel/mac80211/files/mac80211.hotplug -deleted file mode 100644 -index b865552661..0000000000 ---- a/package/kernel/mac80211/files/mac80211.hotplug -+++ /dev/null -@@ -1,5 +0,0 @@ --#!/bin/sh -- --[ "${ACTION}" = "add" ] && { -- /sbin/wifi config --} -diff --git a/package/kernel/mac80211/intel.mk b/package/kernel/mac80211/intel.mk -deleted file mode 100644 -index 8d374d73e7..0000000000 ---- a/package/kernel/mac80211/intel.mk -+++ /dev/null -@@ -1,77 +0,0 @@ --PKG_DRIVERS += iwlwifi -- --config-$(call config_package,iwlwifi) += IWLWIFI IWLDVM IWLMVM --config-$(CONFIG_PACKAGE_IWLWIFI_DEBUG)+= IWLWIFI_DEBUG --config-$(CONFIG_PACKAGE_IWLWIFI_DEBUGFS)+= IWLWIFI_DEBUGFS -- --define KernelPackage/iwlwifi -- $(call KernelPackage/mac80211/Default) -- DEPENDS:= +kmod-mac80211 @PCI_SUPPORT +@DRIVER_11AC_SUPPORT +@DRIVER_11AX_SUPPORT -- TITLE:=Intel AGN Wireless support -- FILES:= \ -- $(PKG_BUILD_DIR)/drivers/net/wireless/intel/iwlwifi/iwlwifi.ko \ -- $(PKG_BUILD_DIR)/drivers/net/wireless/intel/iwlwifi/dvm/iwldvm.ko \ -- $(PKG_BUILD_DIR)/drivers/net/wireless/intel/iwlwifi/mvm/iwlmvm.ko -- AUTOLOAD:=$(call AutoProbe,iwlwifi iwldvm iwlmvm) -- MENU:=1 --endef -- --define KernelPackage/iwlwifi/description -- iwlwifi kernel module for -- Intel Wireless WiFi Link 6250AGN Adapter -- Intel 6000 Series Wi-Fi Adapters (6200AGN and 6300AGN) -- Intel WiFi Link 1000BGN -- Intel Wireless WiFi 5150AGN -- Intel Wireless WiFi 5100AGN, 5300AGN, and 5350AGN -- Intel 6005 Series Wi-Fi Adapters -- Intel 6030 Series Wi-Fi Adapters -- Intel Wireless WiFi Link 6150BGN 2 Adapter -- Intel 100 Series Wi-Fi Adapters (100BGN and 130BGN) -- Intel 2000 Series Wi-Fi Adapters -- Intel 7260 Wi-Fi Adapter -- Intel 3160 Wi-Fi Adapter -- Intel 7265 Wi-Fi Adapter -- Intel 8260 Wi-Fi Adapter -- Intel 3165 Wi-Fi Adapter --endef -- --define KernelPackage/iwlwifi/config -- if PACKAGE_kmod-iwlwifi -- -- config PACKAGE_IWLWIFI_DEBUG -- bool "Enable full debugging output in the iwlwifi driver" -- default n -- help -- This option will enable debug tracing output for the iwlwifi drivers -- -- This will result in the kernel module being ~100k larger. You can -- control which debug output is sent to the kernel log by setting the -- value in -- -- /sys/module/iwlwifi/parameters/debug -- -- This entry will only exist if this option is enabled. -- -- To set a value, simply echo an 8-byte hex value to the same file: -- -- % echo 0x43fff > /sys/module/iwlwifi/parameters/debug -- -- You can find the list of debug mask values in: -- drivers/net/wireless/intel/iwlwifi/iwl-debug.h -- -- If this is your first time using this driver, you should say Y here -- as the debug information can assist others in helping you resolve -- any problems you may encounter. -- -- config PACKAGE_IWLWIFI_DEBUGFS -- bool "iwlwifi debugfs support" -- depends on PACKAGE_MAC80211_DEBUGFS -- default n -- help -- Enable creation of debugfs files for the iwlwifi drivers. This -- is a low-impact option that allows getting insight into the -- driver's state at runtime. -- -- endif --endef -- -diff --git a/package/kernel/mac80211/marvell.mk b/package/kernel/mac80211/marvell.mk -deleted file mode 100644 -index dbd07a80da..0000000000 ---- a/package/kernel/mac80211/marvell.mk -+++ /dev/null -@@ -1,51 +0,0 @@ --PKG_DRIVERS += \ -- mwl8k mwifiex-pcie mwifiex-sdio -- --config-$(call config_package,mwl8k) += MWL8K --config-$(call config_package,mwifiex-pcie) += MWIFIEX MWIFIEX_PCIE --config-$(call config_package,mwifiex-sdio) += MWIFIEX MWIFIEX_SDIO -- --define KernelPackage/mwl8k -- $(call KernelPackage/mac80211/Default) -- TITLE:=Driver for Marvell TOPDOG 802.11 Wireless cards -- URL:=https://wireless.wiki.kernel.org/en/users/drivers/mwl8k -- DEPENDS+= @PCI_SUPPORT +kmod-mac80211 +mwl8k-firmware -- FILES:=$(PKG_BUILD_DIR)/drivers/net/wireless/marvell/mwl8k.ko -- AUTOLOAD:=$(call AutoProbe,mwl8k) --endef -- --define KernelPackage/mwl8k/description -- Kernel modules for Marvell TOPDOG 802.11 Wireless cards --endef -- -- --define KernelPackage/mwifiex-pcie -- $(call KernelPackage/mac80211/Default) -- TITLE:=Driver for Marvell 802.11n/802.11ac PCIe Wireless cards -- URL:=https://wireless.wiki.kernel.org/en/users/drivers/mwifiex -- DEPENDS+= @PCI_SUPPORT +kmod-mac80211 +@DRIVER_11AC_SUPPORT +mwifiex-pcie-firmware -- FILES:= \ -- $(PKG_BUILD_DIR)/drivers/net/wireless/marvell/mwifiex/mwifiex.ko \ -- $(PKG_BUILD_DIR)/drivers/net/wireless/marvell/mwifiex/mwifiex_pcie.ko -- AUTOLOAD:=$(call AutoProbe,mwifiex_pcie) --endef -- --define KernelPackage/mwifiex-pcie/description -- Kernel modules for Marvell 802.11n/802.11ac PCIe Wireless cards --endef -- --define KernelPackage/mwifiex-sdio -- $(call KernelPackage/mac80211/Default) -- TITLE:=Driver for Marvell 802.11n/802.11ac SDIO Wireless cards -- URL:=https://wireless.wiki.kernel.org/en/users/drivers/mwifiex -- DEPENDS+= +kmod-mmc +kmod-mac80211 +@DRIVER_11AC_SUPPORT +mwifiex-sdio-firmware -- FILES:= \ -- $(PKG_BUILD_DIR)/drivers/net/wireless/marvell/mwifiex/mwifiex.ko \ -- $(PKG_BUILD_DIR)/drivers/net/wireless/marvell/mwifiex/mwifiex_sdio.ko -- AUTOLOAD:=$(call AutoProbe,mwifiex_sdio) --endef -- --define KernelPackage/mwifiex-sdio/description -- Kernel modules for Marvell 802.11n/802.11ac SDIO Wireless cards --endef -- -diff --git a/package/kernel/mac80211/patches/ath/070-ath_common_config.patch b/package/kernel/mac80211/patches/ath/070-ath_common_config.patch -deleted file mode 100644 -index 3d0b4d6b1a..0000000000 ---- a/package/kernel/mac80211/patches/ath/070-ath_common_config.patch -+++ /dev/null -@@ -1,10 +0,0 @@ ----- a/drivers/net/wireless/ath/Kconfig --+++ b/drivers/net/wireless/ath/Kconfig --@@ -1,6 +1,6 @@ -- # SPDX-License-Identifier: ISC -- config ATH_COMMON --- tristate --+ tristate "ath.ko" -- depends on m -- -- config WLAN_VENDOR_ATH -diff --git a/package/kernel/mac80211/patches/ath/400-ath_move_debug_code.patch b/package/kernel/mac80211/patches/ath/400-ath_move_debug_code.patch -deleted file mode 100644 -index eacc72776e..0000000000 ---- a/package/kernel/mac80211/patches/ath/400-ath_move_debug_code.patch -+++ /dev/null -@@ -1,31 +0,0 @@ ----- a/drivers/net/wireless/ath/Makefile --+++ b/drivers/net/wireless/ath/Makefile --@@ -15,10 +15,10 @@ ath-objs := main.o \ -- regd.o \ -- hw.o \ -- key.o \ --+ debug.o \ -- dfs_pattern_detector.o \ -- dfs_pri_detector.o -- ---ath-$(CPTCFG_ATH_DEBUG) += debug.o -- ath-$(CPTCFG_ATH_TRACEPOINTS) += trace.o -- -- CFLAGS_trace.o := -I$(src) ----- a/drivers/net/wireless/ath/ath.h --+++ b/drivers/net/wireless/ath/ath.h --@@ -317,14 +317,7 @@ void _ath_dbg(struct ath_common *common, -- #endif /* CPTCFG_ATH_DEBUG */ -- -- /** Returns string describing opmode, or NULL if unknown mode. */ ---#ifdef CPTCFG_ATH_DEBUG -- const char *ath_opmode_to_string(enum nl80211_iftype opmode); ---#else ---static inline const char *ath_opmode_to_string(enum nl80211_iftype opmode) ---{ --- return "UNKNOWN"; ---} ---#endif -- -- extern const char *ath_bus_type_strings[]; -- static inline const char *ath_bus_type_to_string(enum ath_bus_type bustype) -diff --git a/package/kernel/mac80211/patches/ath/402-ath_regd_optional.patch b/package/kernel/mac80211/patches/ath/402-ath_regd_optional.patch -deleted file mode 100644 -index fd5493de71..0000000000 ---- a/package/kernel/mac80211/patches/ath/402-ath_regd_optional.patch -+++ /dev/null -@@ -1,92 +0,0 @@ ----- a/drivers/net/wireless/ath/regd.c --+++ b/drivers/net/wireless/ath/regd.c --@@ -24,6 +24,7 @@ -- #include "regd_common.h" -- -- static int __ath_regd_init(struct ath_regulatory *reg); --+static struct reg_dmn_pair_mapping *ath_get_regpair(int regdmn); -- -- /* -- * This is a set of common rules used by our world regulatory domains. --@@ -116,6 +117,9 @@ static const struct ieee80211_regdomain -- -- static bool dynamic_country_user_possible(struct ath_regulatory *reg) -- { --+ if (IS_ENABLED(CPTCFG_ATH_USER_REGD)) --+ return true; --+ -- if (IS_ENABLED(CPTCFG_ATH_REG_DYNAMIC_USER_CERT_TESTING)) -- return true; -- --@@ -188,6 +192,8 @@ static bool dynamic_country_user_possibl -- -- static bool ath_reg_dyn_country_user_allow(struct ath_regulatory *reg) -- { --+ if (IS_ENABLED(CPTCFG_ATH_USER_REGD)) --+ return true; -- if (!IS_ENABLED(CPTCFG_ATH_REG_DYNAMIC_USER_REG_HINTS)) -- return false; -- if (!dynamic_country_user_possible(reg)) --@@ -345,6 +351,9 @@ ath_reg_apply_beaconing_flags(struct wip -- struct ieee80211_channel *ch; -- unsigned int i; -- --+ if (IS_ENABLED(CPTCFG_ATH_USER_REGD)) --+ return; --+ -- for (band = 0; band < NUM_NL80211_BANDS; band++) { -- if (!wiphy->bands[band]) -- continue; --@@ -379,6 +388,9 @@ ath_reg_apply_ir_flags(struct wiphy *wip -- { -- struct ieee80211_supported_band *sband; -- --+ if (IS_ENABLED(CPTCFG_ATH_USER_REGD)) --+ return; --+ -- sband = wiphy->bands[NL80211_BAND_2GHZ]; -- if (!sband) -- return; --@@ -408,6 +420,9 @@ static void ath_reg_apply_radar_flags(st -- struct ieee80211_channel *ch; -- unsigned int i; -- --+ if (IS_ENABLED(CPTCFG_ATH_USER_REGD)) --+ return; --+ -- if (!wiphy->bands[NL80211_BAND_5GHZ]) -- return; -- --@@ -640,6 +655,10 @@ ath_regd_init_wiphy(struct ath_regulator -- const struct ieee80211_regdomain *regd; -- -- wiphy->reg_notifier = reg_notifier; --+ --+ if (IS_ENABLED(CPTCFG_ATH_USER_REGD)) --+ return 0; --+ -- wiphy->regulatory_flags |= REGULATORY_STRICT_REG | -- REGULATORY_CUSTOM_REG; -- ----- a/drivers/net/wireless/ath/Kconfig --+++ b/drivers/net/wireless/ath/Kconfig --@@ -24,6 +24,9 @@ config WLAN_VENDOR_ATH -- -- if WLAN_VENDOR_ATH -- --+config ATH_USER_REGD --+ bool "Do not enforce EEPROM regulatory restrictions" --+ -- config ATH_DEBUG -- bool "Atheros wireless debugging" -- help ----- a/local-symbols --+++ b/local-symbols --@@ -102,6 +102,7 @@ ADM8211= -- ATH_COMMON= -- WLAN_VENDOR_ATH= -- ATH_DEBUG= --+ATH_USER_REGD= -- ATH_TRACEPOINTS= -- ATH_REG_DYNAMIC_USER_REG_HINTS= -- ATH_REG_DYNAMIC_USER_CERT_TESTING= -diff --git a/package/kernel/mac80211/patches/ath/403-world_regd_fixup.patch b/package/kernel/mac80211/patches/ath/403-world_regd_fixup.patch -deleted file mode 100644 -index ed616b7532..0000000000 ---- a/package/kernel/mac80211/patches/ath/403-world_regd_fixup.patch -+++ /dev/null -@@ -1,84 +0,0 @@ ----- a/drivers/net/wireless/ath/regd.c --+++ b/drivers/net/wireless/ath/regd.c --@@ -44,7 +44,8 @@ static struct reg_dmn_pair_mapping *ath_ -- NL80211_RRF_NO_OFDM) -- -- /* We allow IBSS on these on a case by case basis by regulatory domain */ ---#define ATH_5GHZ_5150_5350 REG_RULE(5150-10, 5350+10, 80, 0, 30,\ --+#define ATH_5GHZ_5150_5350 REG_RULE(5150-10, 5240+10, 80, 0, 30, 0),\ --+ REG_RULE(5260-10, 5350+10, 80, 0, 30,\ -- NL80211_RRF_NO_IR) -- #define ATH_5GHZ_5470_5850 REG_RULE(5470-10, 5850+10, 80, 0, 30,\ -- NL80211_RRF_NO_IR) --@@ -62,57 +63,56 @@ static struct reg_dmn_pair_mapping *ath_ -- #define ATH_5GHZ_NO_MIDBAND ATH_5GHZ_5150_5350, \ -- ATH_5GHZ_5725_5850 -- --+#define REGD_RULES(...) \ --+ .reg_rules = { __VA_ARGS__ }, \ --+ .n_reg_rules = ARRAY_SIZE(((struct ieee80211_reg_rule[]) { __VA_ARGS__ })) --+ -- /* Can be used for: -- * 0x60, 0x61, 0x62 */ -- static const struct ieee80211_regdomain ath_world_regdom_60_61_62 = { --- .n_reg_rules = 5, -- .alpha2 = "99", --- .reg_rules = { --+ REGD_RULES( -- ATH_2GHZ_ALL, -- ATH_5GHZ_ALL, --- } --+ ) -- }; -- -- /* Can be used by 0x63 and 0x65 */ -- static const struct ieee80211_regdomain ath_world_regdom_63_65 = { --- .n_reg_rules = 4, -- .alpha2 = "99", --- .reg_rules = { --+ REGD_RULES( -- ATH_2GHZ_CH01_11, -- ATH_2GHZ_CH12_13, -- ATH_5GHZ_NO_MIDBAND, --- } --+ ) -- }; -- -- /* Can be used by 0x64 only */ -- static const struct ieee80211_regdomain ath_world_regdom_64 = { --- .n_reg_rules = 3, -- .alpha2 = "99", --- .reg_rules = { --+ REGD_RULES( -- ATH_2GHZ_CH01_11, -- ATH_5GHZ_NO_MIDBAND, --- } --+ ) -- }; -- -- /* Can be used by 0x66 and 0x69 */ -- static const struct ieee80211_regdomain ath_world_regdom_66_69 = { --- .n_reg_rules = 3, -- .alpha2 = "99", --- .reg_rules = { --+ REGD_RULES( -- ATH_2GHZ_CH01_11, -- ATH_5GHZ_ALL, --- } --+ ) -- }; -- -- /* Can be used by 0x67, 0x68, 0x6A and 0x6C */ -- static const struct ieee80211_regdomain ath_world_regdom_67_68_6A_6C = { --- .n_reg_rules = 4, -- .alpha2 = "99", --- .reg_rules = { --+ REGD_RULES( -- ATH_2GHZ_CH01_11, -- ATH_2GHZ_CH12_13, -- ATH_5GHZ_ALL, --- } --+ ) -- }; -- -- static bool dynamic_country_user_possible(struct ath_regulatory *reg) -diff --git a/package/kernel/mac80211/patches/ath/404-regd_no_assoc_hints.patch b/package/kernel/mac80211/patches/ath/404-regd_no_assoc_hints.patch -deleted file mode 100644 -index 8d83921a3b..0000000000 ---- a/package/kernel/mac80211/patches/ath/404-regd_no_assoc_hints.patch -+++ /dev/null -@@ -1,19 +0,0 @@ ----- a/net/wireless/reg.c --+++ b/net/wireless/reg.c --@@ -3370,6 +3370,8 @@ void regulatory_hint_country_ie(struct w -- enum environment_cap env = ENVIRON_ANY; -- struct regulatory_request *request = NULL, *lr; -- --+ return; --+ -- /* IE len must be evenly divisible by 2 */ -- if (country_ie_len & 0x01) -- return; --@@ -3621,6 +3623,7 @@ static bool is_wiphy_all_set_reg_flag(en -- -- void regulatory_hint_disconnect(void) -- { --+ return; -- /* Restore of regulatory settings is not required when wiphy(s) -- * ignore IE from connected access point but clearance of beacon hints -- * is required when wiphy(s) supports beacon hints. -diff --git a/package/kernel/mac80211/patches/ath/405-ath_regd_us.patch b/package/kernel/mac80211/patches/ath/405-ath_regd_us.patch -deleted file mode 100644 -index 6723721a47..0000000000 ---- a/package/kernel/mac80211/patches/ath/405-ath_regd_us.patch -+++ /dev/null -@@ -1,26 +0,0 @@ ----- a/drivers/net/wireless/ath/regd_common.h --+++ b/drivers/net/wireless/ath/regd_common.h --@@ -32,6 +32,7 @@ enum EnumRd { -- FCC2_WORLD = 0x21, -- FCC2_ETSIC = 0x22, -- FCC6_WORLD = 0x23, --+ FCC3_FCCA_2 = 0x2A, -- FRANCE_RES = 0x31, -- FCC3_FCCA = 0x3A, -- FCC3_WORLD = 0x3B, --@@ -173,6 +174,7 @@ static struct reg_dmn_pair_mapping regDo -- {FCC2_WORLD, CTL_FCC, CTL_ETSI}, -- {FCC2_ETSIC, CTL_FCC, CTL_ETSI}, -- {FCC3_FCCA, CTL_FCC, CTL_FCC}, --+ {FCC3_FCCA_2, CTL_FCC, CTL_FCC}, -- {FCC3_WORLD, CTL_FCC, CTL_ETSI}, -- {FCC3_ETSIC, CTL_FCC, CTL_ETSI}, -- {FCC4_FCCA, CTL_FCC, CTL_FCC}, --@@ -486,6 +488,7 @@ static struct country_code_to_enum_rd al -- {CTRY_UAE, NULL1_WORLD, "AE"}, -- {CTRY_UNITED_KINGDOM, ETSI1_WORLD, "GB"}, -- {CTRY_UNITED_STATES, FCC3_FCCA, "US"}, --+ {CTRY_UNITED_STATES, FCC3_FCCA_2, "US"}, -- {CTRY_UNITED_STATES2, FCC3_FCCA, "US"}, -- {CTRY_UNITED_STATES3, FCC3_FCCA, "US"}, -- /* This "PS" is for US public safety actually... to support this we -diff --git a/package/kernel/mac80211/patches/ath/406-ath_relax_default_regd.patch b/package/kernel/mac80211/patches/ath/406-ath_relax_default_regd.patch -deleted file mode 100644 -index ee4e461342..0000000000 ---- a/package/kernel/mac80211/patches/ath/406-ath_relax_default_regd.patch -+++ /dev/null -@@ -1,51 +0,0 @@ ----- a/drivers/net/wireless/ath/regd.c --+++ b/drivers/net/wireless/ath/regd.c --@@ -115,6 +115,16 @@ static const struct ieee80211_regdomain -- ) -- }; -- --+static u16 ath_regd_get_eepromRD(struct ath_regulatory *reg) --+{ --+ return reg->current_rd & ~WORLDWIDE_ROAMING_FLAG; --+} --+ --+static bool is_default_regd(struct ath_regulatory *reg) --+{ --+ return ath_regd_get_eepromRD(reg) == CTRY_DEFAULT; --+} --+ -- static bool dynamic_country_user_possible(struct ath_regulatory *reg) -- { -- if (IS_ENABLED(CPTCFG_ATH_USER_REGD)) --@@ -123,6 +133,9 @@ static bool dynamic_country_user_possibl -- if (IS_ENABLED(CPTCFG_ATH_REG_DYNAMIC_USER_CERT_TESTING)) -- return true; -- --+ if (is_default_regd(reg)) --+ return true; --+ -- switch (reg->country_code) { -- case CTRY_UNITED_STATES: -- case CTRY_JAPAN1: --@@ -208,11 +221,6 @@ static inline bool is_wwr_sku(u16 regd) -- (regd == WORLD)); -- } -- ---static u16 ath_regd_get_eepromRD(struct ath_regulatory *reg) ---{ --- return reg->current_rd & ~WORLDWIDE_ROAMING_FLAG; ---} --- -- bool ath_is_world_regd(struct ath_regulatory *reg) -- { -- return is_wwr_sku(ath_regd_get_eepromRD(reg)); --@@ -659,6 +667,9 @@ ath_regd_init_wiphy(struct ath_regulator -- if (IS_ENABLED(CPTCFG_ATH_USER_REGD)) -- return 0; -- --+ if (is_default_regd(reg)) --+ return 0; --+ -- wiphy->regulatory_flags |= REGULATORY_STRICT_REG | -- REGULATORY_CUSTOM_REG; -- -diff --git a/package/kernel/mac80211/patches/ath/431-add_platform_eeprom_support_to_ath5k.patch b/package/kernel/mac80211/patches/ath/431-add_platform_eeprom_support_to_ath5k.patch -deleted file mode 100644 -index 136be19894..0000000000 ---- a/package/kernel/mac80211/patches/ath/431-add_platform_eeprom_support_to_ath5k.patch -+++ /dev/null -@@ -1,56 +0,0 @@ ----- a/drivers/net/wireless/ath/ath5k/pci.c --+++ b/drivers/net/wireless/ath/ath5k/pci.c --@@ -20,6 +20,7 @@ -- #include -- #include -- #include --+#include -- #include "../ath.h" -- #include "ath5k.h" -- #include "debug.h" --@@ -71,7 +72,7 @@ static void ath5k_pci_read_cachesize(str -- } -- -- /* --- * Read from eeprom --+ * Read from eeprom or platform_data -- */ -- static bool -- ath5k_pci_eeprom_read(struct ath_common *common, u32 offset, u16 *data) --@@ -79,6 +80,19 @@ ath5k_pci_eeprom_read(struct ath_common -- struct ath5k_hw *ah = (struct ath5k_hw *) common->ah; -- u32 status, timeout; -- --+ struct ath5k_platform_data *pdata = NULL; --+ --+ if (ah->pdev) --+ pdata = ah->pdev->dev.platform_data; --+ --+ if (pdata && pdata->eeprom_data && pdata->eeprom_data[61] == AR5K_EEPROM_MAGIC_VALUE) { --+ if (offset >= ATH5K_PLAT_EEP_MAX_WORDS) --+ return false; --+ --+ *data = pdata->eeprom_data[offset]; --+ return true; --+ } --+ -- /* -- * Initialize EEPROM access -- */ --@@ -122,6 +136,16 @@ static int ath5k_pci_eeprom_read_mac(str -- u16 data; -- int octet; -- --+ struct ath5k_platform_data *pdata = NULL; --+ --+ if (ah->pdev) --+ pdata = ah->pdev->dev.platform_data; --+ --+ if (pdata && pdata->macaddr) { --+ memcpy(mac, pdata->macaddr, ETH_ALEN); --+ return 0; --+ } --+ -- AR5K_EEPROM_READ(0x20, data); -- -- for (offset = 0x1f, octet = 0, total = 0; offset >= 0x1d; offset--) { -diff --git a/package/kernel/mac80211/patches/ath10k/080-ath10k_thermal_config.patch b/package/kernel/mac80211/patches/ath10k/080-ath10k_thermal_config.patch -deleted file mode 100644 -index 41ad6006b5..0000000000 ---- a/package/kernel/mac80211/patches/ath10k/080-ath10k_thermal_config.patch -+++ /dev/null -@@ -1,47 +0,0 @@ ----- a/drivers/net/wireless/ath/ath10k/Kconfig --+++ b/drivers/net/wireless/ath/ath10k/Kconfig --@@ -86,6 +86,12 @@ config ATH10K_TRACING -- help -- Select this to ath10k use tracing infrastructure. -- --+config ATH10K_THERMAL --+ bool "Atheros ath10k thermal monitoring support" --+ depends on THERMAL --+ ---help--- --+ Select this to ath10k use hwmon for thermal measurement. --+ -- config ATH10K_DFS_CERTIFIED -- bool "Atheros DFS support for certified platforms" -- depends on ATH10K && CFG80211_CERTIFICATION_ONUS ----- a/drivers/net/wireless/ath/ath10k/Makefile --+++ b/drivers/net/wireless/ath/ath10k/Makefile --@@ -18,7 +18,7 @@ ath10k_core-y += mac.o \ -- ath10k_core-$(CPTCFG_ATH10K_SPECTRAL) += spectral.o -- ath10k_core-$(CPTCFG_NL80211_TESTMODE) += testmode.o -- ath10k_core-$(CPTCFG_ATH10K_TRACING) += trace.o ---ath10k_core-$(CONFIG_THERMAL) += thermal.o --+ath10k_core-$(CPTCFG_ATH10K_THERMAL) += thermal.o -- ath10k_core-$(CPTCFG_MAC80211_DEBUGFS) += debugfs_sta.o -- ath10k_core-$(CONFIG_PM) += wow.o -- ath10k_core-$(CONFIG_DEV_COREDUMP) += coredump.o ----- a/drivers/net/wireless/ath/ath10k/thermal.h --+++ b/drivers/net/wireless/ath/ath10k/thermal.h --@@ -25,7 +25,7 @@ struct ath10k_thermal { -- int temperature; -- }; -- ---#if IS_REACHABLE(CONFIG_THERMAL) --+#if IS_REACHABLE(CPTCFG_ATH10K_THERMAL) -- int ath10k_thermal_register(struct ath10k *ar); -- void ath10k_thermal_unregister(struct ath10k *ar); -- void ath10k_thermal_event_temperature(struct ath10k *ar, int temperature); ----- a/local-symbols --+++ b/local-symbols --@@ -161,6 +161,7 @@ ATH10K_SNOC= -- ATH10K_DEBUG= -- ATH10K_DEBUGFS= -- ATH10K_SPECTRAL= --+ATH10K_THERMAL= -- ATH10K_TRACING= -- ATH10K_DFS_CERTIFIED= -- WCN36XX= -diff --git a/package/kernel/mac80211/patches/ath10k/921-ath10k_init_devices_synchronously.patch b/package/kernel/mac80211/patches/ath10k/921-ath10k_init_devices_synchronously.patch -deleted file mode 100644 -index 7a38cf3e4e..0000000000 ---- a/package/kernel/mac80211/patches/ath10k/921-ath10k_init_devices_synchronously.patch -+++ /dev/null -@@ -1,33 +0,0 @@ --From: Sven Eckelmann --Date: Tue, 18 Nov 2014 12:29:28 +0100 --Subject: [PATCH] ath10k: Don't initialize devices asynchronously -- --OpenWrt requires all PHYs to be initialized to create the configuration files --during bootup. ath10k violates this because it delays the creation of the PHY --to a not well defined point in the future. -- --Forcing the work to be done immediately works around this problem but may also --delay the boot when firmware images cannot be found. -- --Signed-off-by: Sven Eckelmann ----- -- ----- a/drivers/net/wireless/ath/ath10k/core.c --+++ b/drivers/net/wireless/ath/ath10k/core.c --@@ -3516,6 +3516,16 @@ int ath10k_core_register(struct ath10k * -- -- queue_work(ar->workqueue, &ar->register_work); -- --+ /* OpenWrt requires all PHYs to be initialized to create the --+ * configuration files during bootup. ath10k violates this --+ * because it delays the creation of the PHY to a not well defined --+ * point in the future. --+ * --+ * Forcing the work to be done immediately works around this problem --+ * but may also delay the boot when firmware images cannot be found. --+ */ --+ flush_workqueue(ar->workqueue); --+ -- return 0; -- } -- EXPORT_SYMBOL(ath10k_core_register); -diff --git a/package/kernel/mac80211/patches/ath10k/930-ath10k_add_tpt_led_trigger.patch b/package/kernel/mac80211/patches/ath10k/930-ath10k_add_tpt_led_trigger.patch -deleted file mode 100644 -index e8beed17e8..0000000000 ---- a/package/kernel/mac80211/patches/ath10k/930-ath10k_add_tpt_led_trigger.patch -+++ /dev/null -@@ -1,37 +0,0 @@ ----- a/drivers/net/wireless/ath/ath10k/mac.c --+++ b/drivers/net/wireless/ath/ath10k/mac.c --@@ -9909,6 +9909,21 @@ static int ath10k_mac_init_rd(struct ath -- return 0; -- } -- --+#ifdef CPTCFG_MAC80211_LEDS --+static const struct ieee80211_tpt_blink ath10k_tpt_blink[] = { --+ { .throughput = 0 * 1024, .blink_time = 334 }, --+ { .throughput = 1 * 1024, .blink_time = 260 }, --+ { .throughput = 2 * 1024, .blink_time = 220 }, --+ { .throughput = 5 * 1024, .blink_time = 190 }, --+ { .throughput = 10 * 1024, .blink_time = 170 }, --+ { .throughput = 25 * 1024, .blink_time = 150 }, --+ { .throughput = 54 * 1024, .blink_time = 130 }, --+ { .throughput = 120 * 1024, .blink_time = 110 }, --+ { .throughput = 265 * 1024, .blink_time = 80 }, --+ { .throughput = 586 * 1024, .blink_time = 50 }, --+}; --+#endif --+ -- int ath10k_mac_register(struct ath10k *ar) -- { -- static const u32 cipher_suites[] = { --@@ -10267,6 +10282,12 @@ int ath10k_mac_register(struct ath10k *a -- -- ar->hw->weight_multiplier = ATH10K_AIRTIME_WEIGHT_MULTIPLIER; -- --+#ifdef CPTCFG_MAC80211_LEDS --+ ieee80211_create_tpt_led_trigger(ar->hw, --+ IEEE80211_TPT_LEDTRIG_FL_RADIO, ath10k_tpt_blink, --+ ARRAY_SIZE(ath10k_tpt_blink)); --+#endif --+ -- ret = ieee80211_register_hw(ar->hw); -- if (ret) { -- ath10k_err(ar, "failed to register ieee80211: %d\n", ret); -diff --git a/package/kernel/mac80211/patches/ath10k/974-ath10k_add-LED-and-GPIO-controlling-support-for-various-chipsets.patch b/package/kernel/mac80211/patches/ath10k/974-ath10k_add-LED-and-GPIO-controlling-support-for-various-chipsets.patch -deleted file mode 100644 -index 1c1630c051..0000000000 ---- a/package/kernel/mac80211/patches/ath10k/974-ath10k_add-LED-and-GPIO-controlling-support-for-various-chipsets.patch -+++ /dev/null -@@ -1,609 +0,0 @@ --From: Sebastian Gottschall -- --Adds LED and GPIO Control support for 988x, 9887, 9888, 99x0, 9984 based --chipsets with on chipset connected led's using WMI Firmware API. The LED --device will get available named as "ath10k-phyX" at sysfs and can be controlled --with various triggers. adds also debugfs interface for gpio control. -- --This patch is specific for OpenWRt base, as is use old backported package --with old wireless source. Support for QCA9984 is removed and a simbol --is added to local-simbol file to export the actually compile the code --with the ATH10K_LEDS simbol. -- -- --Signed-off-by: Sebastian Gottschall --Reviewed-by: Steve deRosier --[kvalo: major reorg and cleanup] --Signed-off-by: Kalle Valo --Signed-off-by: Ansuel Smith ----- -- --v13: -- --* only compile tested! -- --* fix all checkpatch warnings -- --* fix commit log -- --* sizeof(struct ath10k_gpiocontrol) -> sizeof(*gpio) -- --* unsigned -> unsigned int -- --* remove GPIOLIB code, that should be added in a separate patch -- --* rename gpio.c to leds.c -- --* add leds.h -- --* rename some functions: -- -- ath10k_attach_led() -> ath10k_leds_register() -- ath10k_unregister_led() -> ath10k_leds_unregister() -- ath10k_reset_led_pin() -> ath10k_leds_start() -- --* call ath10k_leds_unregister() before ath10k_thermal_unregister() to preserve ordering -- --* call ath10k_leds_start() only from ath10k_core_start() and not from mac.c -- --* rename struct ath10k_gpiocontrol as anonymous function under struct -- ath10k::leds, no need for memory allocation -- --* merge ath10k_add_led() to ath10k_attach_led(), which is it's only caller -- --* remove #if IS_ENABLED() checks from most of places, memory savings from those were not worth it -- --* Kconfig help text improvement and move it lower in the menu, also don't enable it by default -- --* switch to set_brightness_blocking() so that the callback can sleep, -- then no need to use ath10k_wmi_cmd_send_nowait() and can take mutex -- to access ar->state -- --* don't touch ath10k_wmi_pdev_get_temperature() -- --* as QCA6174/QCA9377 are not (yet) supported don't add the command to WMI-TLV interface -- --* remove debugfs interface, that should be added in another patch -- --* cleanup includes -- -- -- drivers/net/wireless/ath/ath10k/Kconfig | 10 +++ -- drivers/net/wireless/ath/ath10k/Makefile | 1 + -- drivers/net/wireless/ath/ath10k/core.c | 22 +++++++ -- drivers/net/wireless/ath/ath10k/core.h | 9 ++- -- drivers/net/wireless/ath/ath10k/hw.h | 1 + -- drivers/net/wireless/ath/ath10k/leds.c | 103 ++++++++++++++++++++++++++++++ -- drivers/net/wireless/ath/ath10k/leds.h | 45 +++++++++++++ -- drivers/net/wireless/ath/ath10k/mac.c | 1 + -- drivers/net/wireless/ath/ath10k/wmi-ops.h | 32 ++++++++++ -- drivers/net/wireless/ath/ath10k/wmi-tlv.c | 2 + -- drivers/net/wireless/ath/ath10k/wmi.c | 54 ++++++++++++++++ -- drivers/net/wireless/ath/ath10k/wmi.h | 35 ++++++++++ -- 12 files changed, 314 insertions(+), 1 deletion(-) -- create mode 100644 drivers/net/wireless/ath/ath10k/leds.c -- create mode 100644 drivers/net/wireless/ath/ath10k/leds.h ----- a/drivers/net/wireless/ath/ath10k/Kconfig --+++ b/drivers/net/wireless/ath/ath10k/Kconfig --@@ -71,6 +71,16 @@ config ATH10K_DEBUGFS -- -- If unsure, say Y to make it easier to debug problems. -- --+config ATH10K_LEDS --+ bool "Atheros ath10k LED support" --+ depends on ATH10K --+ select MAC80211_LEDS --+ select LEDS_CLASS --+ select NEW_LEDS --+ default y --+ ---help--- --+ This option is necessary, if you want LED support for chipset connected led pins. If unsure, say N. --+ -- config ATH10K_SPECTRAL -- bool "Atheros ath10k spectral scan support" -- depends on ATH10K_DEBUGFS ----- a/drivers/net/wireless/ath/ath10k/Makefile --+++ b/drivers/net/wireless/ath/ath10k/Makefile --@@ -19,6 +19,7 @@ ath10k_core-$(CPTCFG_ATH10K_SPECTRAL) += -- ath10k_core-$(CPTCFG_NL80211_TESTMODE) += testmode.o -- ath10k_core-$(CPTCFG_ATH10K_TRACING) += trace.o -- ath10k_core-$(CPTCFG_ATH10K_THERMAL) += thermal.o --+ath10k_core-$(CPTCFG_ATH10K_LEDS) += leds.o -- ath10k_core-$(CPTCFG_MAC80211_DEBUGFS) += debugfs_sta.o -- ath10k_core-$(CONFIG_PM) += wow.o -- ath10k_core-$(CONFIG_DEV_COREDUMP) += coredump.o ----- a/local-symbols --+++ b/local-symbols --@@ -162,6 +162,7 @@ ATH10K_DEBUG= -- ATH10K_DEBUGFS= -- ATH10K_SPECTRAL= -- ATH10K_THERMAL= --+ATH10K_LEDS= -- ATH10K_TRACING= -- ATH10K_DFS_CERTIFIED= -- WCN36XX= ----- a/drivers/net/wireless/ath/ath10k/core.c --+++ b/drivers/net/wireless/ath/ath10k/core.c --@@ -26,6 +26,7 @@ -- #include "testmode.h" -- #include "wmi-ops.h" -- #include "coredump.h" --+#include "leds.h" -- -- unsigned int ath10k_debug_mask; -- EXPORT_SYMBOL(ath10k_debug_mask); --@@ -65,6 +66,7 @@ static const struct ath10k_hw_params ath -- .dev_id = QCA988X_2_0_DEVICE_ID, -- .bus = ATH10K_BUS_PCI, -- .name = "qca988x hw2.0", --+ .led_pin = 1, -- .patch_load_addr = QCA988X_HW_2_0_PATCH_LOAD_ADDR, -- .uart_pin = 7, -- .cc_wraparound_type = ATH10K_HW_CC_WRAP_SHIFTED_ALL, --@@ -146,6 +148,7 @@ static const struct ath10k_hw_params ath -- .dev_id = QCA9887_1_0_DEVICE_ID, -- .bus = ATH10K_BUS_PCI, -- .name = "qca9887 hw1.0", --+ .led_pin = 1, -- .patch_load_addr = QCA9887_HW_1_0_PATCH_LOAD_ADDR, -- .uart_pin = 7, -- .cc_wraparound_type = ATH10K_HW_CC_WRAP_SHIFTED_ALL, --@@ -387,6 +390,7 @@ static const struct ath10k_hw_params ath -- .dev_id = QCA99X0_2_0_DEVICE_ID, -- .bus = ATH10K_BUS_PCI, -- .name = "qca99x0 hw2.0", --+ .led_pin = 17, -- .patch_load_addr = QCA99X0_HW_2_0_PATCH_LOAD_ADDR, -- .uart_pin = 7, -- .otp_exe_param = 0x00000700, --@@ -433,6 +437,7 @@ static const struct ath10k_hw_params ath -- .dev_id = QCA9984_1_0_DEVICE_ID, -- .bus = ATH10K_BUS_PCI, -- .name = "qca9984/qca9994 hw1.0", --+ .led_pin = 17, -- .patch_load_addr = QCA9984_HW_1_0_PATCH_LOAD_ADDR, -- .uart_pin = 7, -- .cc_wraparound_type = ATH10K_HW_CC_WRAP_SHIFTED_EACH, --@@ -486,6 +491,7 @@ static const struct ath10k_hw_params ath -- .dev_id = QCA9888_2_0_DEVICE_ID, -- .bus = ATH10K_BUS_PCI, -- .name = "qca9888 hw2.0", --+ .led_pin = 17, -- .patch_load_addr = QCA9888_HW_2_0_PATCH_LOAD_ADDR, -- .uart_pin = 7, -- .cc_wraparound_type = ATH10K_HW_CC_WRAP_SHIFTED_EACH, --@@ -3231,6 +3237,10 @@ int ath10k_core_start(struct ath10k *ar, -- goto err_hif_stop; -- } -- --+ status = ath10k_leds_start(ar); --+ if (status) --+ goto err_hif_stop; --+ -- return 0; -- -- err_hif_stop: --@@ -3489,9 +3499,18 @@ static void ath10k_core_register_work(st -- goto err_spectral_destroy; -- } -- --+ status = ath10k_leds_register(ar); --+ if (status) { --+ ath10k_err(ar, "could not register leds: %d\n", --+ status); --+ goto err_thermal_unregister; --+ } --+ -- set_bit(ATH10K_FLAG_CORE_REGISTERED, &ar->dev_flags); -- return; -- --+err_thermal_unregister: --+ ath10k_thermal_unregister(ar); -- err_spectral_destroy: -- ath10k_spectral_destroy(ar); -- err_debug_destroy: --@@ -3537,6 +3556,8 @@ void ath10k_core_unregister(struct ath10 -- if (!test_bit(ATH10K_FLAG_CORE_REGISTERED, &ar->dev_flags)) -- return; -- --+ ath10k_leds_unregister(ar); --+ -- ath10k_thermal_unregister(ar); -- /* Stop spectral before unregistering from mac80211 to remove the -- * relayfs debugfs file cleanly. Otherwise the parent debugfs tree ----- a/drivers/net/wireless/ath/ath10k/core.h --+++ b/drivers/net/wireless/ath/ath10k/core.h --@@ -14,6 +14,7 @@ -- #include -- #include -- #include --+#include -- -- #include "htt.h" -- #include "htc.h" --@@ -1253,6 +1254,13 @@ struct ath10k { -- } testmode; -- -- struct { --+ struct gpio_led wifi_led; --+ struct led_classdev cdev; --+ char label[48]; --+ u32 gpio_state_pin; --+ } leds; --+ --+ struct { -- /* protected by data_lock */ -- u32 rx_crc_err_drop; -- u32 fw_crash_counter; ----- a/drivers/net/wireless/ath/ath10k/hw.h --+++ b/drivers/net/wireless/ath/ath10k/hw.h --@@ -519,6 +519,7 @@ struct ath10k_hw_params { -- const char *name; -- u32 patch_load_addr; -- int uart_pin; --+ int led_pin; -- u32 otp_exe_param; -- -- /* Type of hw cycle counter wraparound logic, for more info ----- /dev/null --+++ b/drivers/net/wireless/ath/ath10k/leds.c --@@ -0,0 +1,103 @@ --+/* --+ * Copyright (c) 2005-2011 Atheros Communications Inc. --+ * Copyright (c) 2011-2017 Qualcomm Atheros, Inc. --+ * Copyright (c) 2018 Sebastian Gottschall --+ * Copyright (c) 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 "core.h" --+#include "wmi.h" --+#include "wmi-ops.h" --+ --+#include "leds.h" --+ --+static int ath10k_leds_set_brightness_blocking(struct led_classdev *led_cdev, --+ enum led_brightness brightness) --+{ --+ struct ath10k *ar = container_of(led_cdev, struct ath10k, --+ leds.cdev); --+ struct gpio_led *led = &ar->leds.wifi_led; --+ --+ mutex_lock(&ar->conf_mutex); --+ --+ if (ar->state != ATH10K_STATE_ON) --+ goto out; --+ --+ ar->leds.gpio_state_pin = (brightness != LED_OFF) ^ led->active_low; --+ ath10k_wmi_gpio_output(ar, led->gpio, ar->leds.gpio_state_pin); --+ --+out: --+ mutex_unlock(&ar->conf_mutex); --+ --+ return 0; --+} --+ --+int ath10k_leds_start(struct ath10k *ar) --+{ --+ if (ar->hw_params.led_pin == 0) --+ /* leds not supported */ --+ return 0; --+ --+ /* under some circumstances, the gpio pin gets reconfigured --+ * to default state by the firmware, so we need to --+ * reconfigure it this behaviour has only ben seen on --+ * QCA9984 and QCA99XX devices so far --+ */ --+ ath10k_wmi_gpio_config(ar, ar->hw_params.led_pin, 0, --+ WMI_GPIO_PULL_NONE, WMI_GPIO_INTTYPE_DISABLE); --+ ath10k_wmi_gpio_output(ar, ar->hw_params.led_pin, 1); --+ --+ return 0; --+} --+ --+int ath10k_leds_register(struct ath10k *ar) --+{ --+ int ret; --+ --+ if (ar->hw_params.led_pin == 0) --+ /* leds not supported */ --+ return 0; --+ --+ snprintf(ar->leds.label, sizeof(ar->leds.label), "ath10k-%s", --+ wiphy_name(ar->hw->wiphy)); --+ ar->leds.wifi_led.active_low = 1; --+ ar->leds.wifi_led.gpio = ar->hw_params.led_pin; --+ ar->leds.wifi_led.name = ar->leds.label; --+ ar->leds.wifi_led.default_state = LEDS_GPIO_DEFSTATE_KEEP; --+ --+ ar->leds.cdev.name = ar->leds.label; --+ ar->leds.cdev.brightness_set_blocking = ath10k_leds_set_brightness_blocking; --+ --+ /* FIXME: this assignment doesn't make sense as it's NULL, remove it? */ --+ ar->leds.cdev.default_trigger = ar->leds.wifi_led.default_trigger; --+ --+ ret = led_classdev_register(wiphy_dev(ar->hw->wiphy), &ar->leds.cdev); --+ if (ret) --+ return ret; --+ --+ return 0; --+} --+ --+void ath10k_leds_unregister(struct ath10k *ar) --+{ --+ if (ar->hw_params.led_pin == 0) --+ /* leds not supported */ --+ return; --+ --+ led_classdev_unregister(&ar->leds.cdev); --+} --+ ----- /dev/null --+++ b/drivers/net/wireless/ath/ath10k/leds.h --@@ -0,0 +1,41 @@ --+/* --+ * Copyright (c) 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. --+ */ --+#ifndef _LEDS_H_ --+#define _LEDS_H_ --+ --+#include "core.h" --+ --+#ifdef CPTCFG_ATH10K_LEDS --+void ath10k_leds_unregister(struct ath10k *ar); --+int ath10k_leds_start(struct ath10k *ar); --+int ath10k_leds_register(struct ath10k *ar); --+#else --+static inline void ath10k_leds_unregister(struct ath10k *ar) --+{ --+} --+ --+static inline int ath10k_leds_start(struct ath10k *ar) --+{ --+ return 0; --+} --+ --+static inline int ath10k_leds_register(struct ath10k *ar) --+{ --+ return 0; --+} --+ --+#endif --+#endif /* _LEDS_H_ */ ----- a/drivers/net/wireless/ath/ath10k/mac.c --+++ b/drivers/net/wireless/ath/ath10k/mac.c --@@ -24,6 +24,7 @@ -- #include "wmi-tlv.h" -- #include "wmi-ops.h" -- #include "wow.h" --+#include "leds.h" -- -- /*********/ -- /* Rates */ ----- a/drivers/net/wireless/ath/ath10k/wmi-ops.h --+++ b/drivers/net/wireless/ath/ath10k/wmi-ops.h --@@ -226,7 +226,10 @@ struct wmi_ops { -- const struct wmi_bb_timing_cfg_arg *arg); -- struct sk_buff *(*gen_per_peer_per_tid_cfg)(struct ath10k *ar, -- const struct wmi_per_peer_per_tid_cfg_arg *arg); --+ struct sk_buff *(*gen_gpio_config)(struct ath10k *ar, u32 gpio_num, --+ u32 input, u32 pull_type, u32 intr_mode); -- --+ struct sk_buff *(*gen_gpio_output)(struct ath10k *ar, u32 gpio_num, u32 set); -- }; -- -- int ath10k_wmi_cmd_send(struct ath10k *ar, struct sk_buff *skb, u32 cmd_id); --@@ -1122,6 +1125,35 @@ ath10k_wmi_force_fw_hang(struct ath10k * -- return ath10k_wmi_cmd_send(ar, skb, ar->wmi.cmd->force_fw_hang_cmdid); -- } -- --+static inline int ath10k_wmi_gpio_config(struct ath10k *ar, u32 gpio_num, --+ u32 input, u32 pull_type, u32 intr_mode) --+{ --+ struct sk_buff *skb; --+ --+ if (!ar->wmi.ops->gen_gpio_config) --+ return -EOPNOTSUPP; --+ --+ skb = ar->wmi.ops->gen_gpio_config(ar, gpio_num, input, pull_type, intr_mode); --+ if (IS_ERR(skb)) --+ return PTR_ERR(skb); --+ --+ return ath10k_wmi_cmd_send(ar, skb, ar->wmi.cmd->gpio_config_cmdid); --+} --+ --+static inline int ath10k_wmi_gpio_output(struct ath10k *ar, u32 gpio_num, u32 set) --+{ --+ struct sk_buff *skb; --+ --+ if (!ar->wmi.ops->gen_gpio_config) --+ return -EOPNOTSUPP; --+ --+ skb = ar->wmi.ops->gen_gpio_output(ar, gpio_num, set); --+ if (IS_ERR(skb)) --+ return PTR_ERR(skb); --+ --+ return ath10k_wmi_cmd_send(ar, skb, ar->wmi.cmd->gpio_output_cmdid); --+} --+ -- static inline int -- ath10k_wmi_dbglog_cfg(struct ath10k *ar, u64 module_enable, u32 log_level) -- { ----- a/drivers/net/wireless/ath/ath10k/wmi-tlv.c --+++ b/drivers/net/wireless/ath/ath10k/wmi-tlv.c --@@ -4594,6 +4594,8 @@ static const struct wmi_ops wmi_tlv_ops -- .gen_echo = ath10k_wmi_tlv_op_gen_echo, -- .gen_vdev_spectral_conf = ath10k_wmi_tlv_op_gen_vdev_spectral_conf, -- .gen_vdev_spectral_enable = ath10k_wmi_tlv_op_gen_vdev_spectral_enable, --+ /* .gen_gpio_config not implemented */ --+ /* .gen_gpio_output not implemented */ -- }; -- -- static const struct wmi_peer_flags_map wmi_tlv_peer_flags_map = { ----- a/drivers/net/wireless/ath/ath10k/wmi.c --+++ b/drivers/net/wireless/ath/ath10k/wmi.c --@@ -7472,6 +7472,49 @@ ath10k_wmi_op_gen_peer_set_param(struct -- return skb; -- } -- --+static struct sk_buff *ath10k_wmi_op_gen_gpio_config(struct ath10k *ar, --+ u32 gpio_num, u32 input, --+ u32 pull_type, u32 intr_mode) --+{ --+ struct wmi_gpio_config_cmd *cmd; --+ struct sk_buff *skb; --+ --+ skb = ath10k_wmi_alloc_skb(ar, sizeof(*cmd)); --+ if (!skb) --+ return ERR_PTR(-ENOMEM); --+ --+ cmd = (struct wmi_gpio_config_cmd *)skb->data; --+ cmd->pull_type = __cpu_to_le32(pull_type); --+ cmd->gpio_num = __cpu_to_le32(gpio_num); --+ cmd->input = __cpu_to_le32(input); --+ cmd->intr_mode = __cpu_to_le32(intr_mode); --+ --+ ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi gpio_config gpio_num 0x%08x input 0x%08x pull_type 0x%08x intr_mode 0x%08x\n", --+ gpio_num, input, pull_type, intr_mode); --+ --+ return skb; --+} --+ --+static struct sk_buff *ath10k_wmi_op_gen_gpio_output(struct ath10k *ar, --+ u32 gpio_num, u32 set) --+{ --+ struct wmi_gpio_output_cmd *cmd; --+ struct sk_buff *skb; --+ --+ skb = ath10k_wmi_alloc_skb(ar, sizeof(*cmd)); --+ if (!skb) --+ return ERR_PTR(-ENOMEM); --+ --+ cmd = (struct wmi_gpio_output_cmd *)skb->data; --+ cmd->gpio_num = __cpu_to_le32(gpio_num); --+ cmd->set = __cpu_to_le32(set); --+ --+ ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi gpio_output gpio_num 0x%08x set 0x%08x\n", --+ gpio_num, set); --+ --+ return skb; --+} --+ -- static struct sk_buff * -- ath10k_wmi_op_gen_set_psmode(struct ath10k *ar, u32 vdev_id, -- enum wmi_sta_ps_mode psmode) --@@ -9160,6 +9203,9 @@ static const struct wmi_ops wmi_ops = { -- .fw_stats_fill = ath10k_wmi_main_op_fw_stats_fill, -- .get_vdev_subtype = ath10k_wmi_op_get_vdev_subtype, -- .gen_echo = ath10k_wmi_op_gen_echo, --+ .gen_gpio_config = ath10k_wmi_op_gen_gpio_config, --+ .gen_gpio_output = ath10k_wmi_op_gen_gpio_output, --+ -- /* .gen_bcn_tmpl not implemented */ -- /* .gen_prb_tmpl not implemented */ -- /* .gen_p2p_go_bcn_ie not implemented */ --@@ -9230,6 +9276,8 @@ static const struct wmi_ops wmi_10_1_ops -- .fw_stats_fill = ath10k_wmi_10x_op_fw_stats_fill, -- .get_vdev_subtype = ath10k_wmi_op_get_vdev_subtype, -- .gen_echo = ath10k_wmi_op_gen_echo, --+ .gen_gpio_config = ath10k_wmi_op_gen_gpio_config, --+ .gen_gpio_output = ath10k_wmi_op_gen_gpio_output, -- /* .gen_bcn_tmpl not implemented */ -- /* .gen_prb_tmpl not implemented */ -- /* .gen_p2p_go_bcn_ie not implemented */ --@@ -9302,6 +9350,8 @@ static const struct wmi_ops wmi_10_2_ops -- .gen_delba_send = ath10k_wmi_op_gen_delba_send, -- .fw_stats_fill = ath10k_wmi_10x_op_fw_stats_fill, -- .get_vdev_subtype = ath10k_wmi_op_get_vdev_subtype, --+ .gen_gpio_config = ath10k_wmi_op_gen_gpio_config, --+ .gen_gpio_output = ath10k_wmi_op_gen_gpio_output, -- /* .gen_pdev_enable_adaptive_cca not implemented */ -- }; -- --@@ -9373,6 +9423,8 @@ static const struct wmi_ops wmi_10_2_4_o -- ath10k_wmi_op_gen_pdev_enable_adaptive_cca, -- .get_vdev_subtype = ath10k_wmi_10_2_4_op_get_vdev_subtype, -- .gen_bb_timing = ath10k_wmi_10_2_4_op_gen_bb_timing, --+ .gen_gpio_config = ath10k_wmi_op_gen_gpio_config, --+ .gen_gpio_output = ath10k_wmi_op_gen_gpio_output, -- /* .gen_bcn_tmpl not implemented */ -- /* .gen_prb_tmpl not implemented */ -- /* .gen_p2p_go_bcn_ie not implemented */ --@@ -9454,6 +9506,8 @@ static const struct wmi_ops wmi_10_4_ops -- .gen_pdev_bss_chan_info_req = ath10k_wmi_10_2_op_gen_pdev_bss_chan_info, -- .gen_echo = ath10k_wmi_op_gen_echo, -- .gen_pdev_get_tpc_config = ath10k_wmi_10_2_4_op_gen_pdev_get_tpc_config, --+ .gen_gpio_config = ath10k_wmi_op_gen_gpio_config, --+ .gen_gpio_output = ath10k_wmi_op_gen_gpio_output, -- }; -- -- int ath10k_wmi_attach(struct ath10k *ar) ----- a/drivers/net/wireless/ath/ath10k/wmi.h --+++ b/drivers/net/wireless/ath/ath10k/wmi.h --@@ -3030,6 +3030,41 @@ enum wmi_10_4_feature_mask { -- -- }; -- --+/* WMI_GPIO_CONFIG_CMDID */ --+enum { --+ WMI_GPIO_PULL_NONE, --+ WMI_GPIO_PULL_UP, --+ WMI_GPIO_PULL_DOWN, --+}; --+ --+enum { --+ WMI_GPIO_INTTYPE_DISABLE, --+ WMI_GPIO_INTTYPE_RISING_EDGE, --+ WMI_GPIO_INTTYPE_FALLING_EDGE, --+ WMI_GPIO_INTTYPE_BOTH_EDGE, --+ WMI_GPIO_INTTYPE_LEVEL_LOW, --+ WMI_GPIO_INTTYPE_LEVEL_HIGH --+}; --+ --+/* WMI_GPIO_CONFIG_CMDID */ --+struct wmi_gpio_config_cmd { --+ __le32 gpio_num; /* GPIO number to be setup */ --+ __le32 input; /* 0 - Output/ 1 - Input */ --+ __le32 pull_type; /* Pull type defined above */ --+ __le32 intr_mode; /* Interrupt mode defined above (Input) */ --+} __packed; --+ --+/* WMI_GPIO_OUTPUT_CMDID */ --+struct wmi_gpio_output_cmd { --+ __le32 gpio_num; /* GPIO number to be setup */ --+ __le32 set; /* Set the GPIO pin*/ --+} __packed; --+ --+/* WMI_GPIO_INPUT_EVENTID */ --+struct wmi_gpio_input_event { --+ __le32 gpio_num; /* GPIO number which changed state */ --+} __packed; --+ -- struct wmi_ext_resource_config_10_4_cmd { -- /* contains enum wmi_host_platform_type */ -- __le32 host_platform_config; -diff --git a/package/kernel/mac80211/patches/ath10k/975-ath10k-use-tpt-trigger-by-default.patch b/package/kernel/mac80211/patches/ath10k/975-ath10k-use-tpt-trigger-by-default.patch -deleted file mode 100644 -index 4c1f9aa815..0000000000 ---- a/package/kernel/mac80211/patches/ath10k/975-ath10k-use-tpt-trigger-by-default.patch -+++ /dev/null -@@ -1,53 +0,0 @@ --From 79c9d7aabae1d1da9eea97d83b61e1517a8a2221 Mon Sep 17 00:00:00 2001 --From: Mathias Kresin --Date: Fri, 22 Jun 2018 18:59:44 +0200 --Subject: [PATCH] ath10k: use tpt LED trigger by default -- --Use the tpt LED trigger for each created phy led. Ths way LEDs attached --to the ath10k GPIO pins are indicating the phy status and blink on --traffic. -- --Signed-off-by: Mathias Kresin ----- -- drivers/net/wireless/ath/ath10k/core.h | 4 ++++ -- drivers/net/wireless/ath/ath10k/leds.c | 4 +--- -- drivers/net/wireless/ath/ath10k/mac.c | 2 +- -- 3 files changed, 6 insertions(+), 4 deletions(-) -- ----- a/drivers/net/wireless/ath/ath10k/core.h --+++ b/drivers/net/wireless/ath/ath10k/core.h --@@ -1309,6 +1309,10 @@ struct ath10k { -- s32 tx_power_2g_limit; -- s32 tx_power_5g_limit; -- --+#ifdef CPTCFG_MAC80211_LEDS --+ const char *led_default_trigger; --+#endif --+ -- /* must be last */ -- u8 drv_priv[] __aligned(sizeof(void *)); -- }; ----- a/drivers/net/wireless/ath/ath10k/leds.c --+++ b/drivers/net/wireless/ath/ath10k/leds.c --@@ -81,9 +81,7 @@ int ath10k_leds_register(struct ath10k * -- -- ar->leds.cdev.name = ar->leds.label; -- ar->leds.cdev.brightness_set_blocking = ath10k_leds_set_brightness_blocking; --- --- /* FIXME: this assignment doesn't make sense as it's NULL, remove it? */ --- ar->leds.cdev.default_trigger = ar->leds.wifi_led.default_trigger; --+ ar->leds.cdev.default_trigger = ar->led_default_trigger; -- -- ret = led_classdev_register(wiphy_dev(ar->hw->wiphy), &ar->leds.cdev); -- if (ret) ----- a/drivers/net/wireless/ath/ath10k/mac.c --+++ b/drivers/net/wireless/ath/ath10k/mac.c --@@ -10284,7 +10284,7 @@ int ath10k_mac_register(struct ath10k *a -- ar->hw->weight_multiplier = ATH10K_AIRTIME_WEIGHT_MULTIPLIER; -- -- #ifdef CPTCFG_MAC80211_LEDS --- ieee80211_create_tpt_led_trigger(ar->hw, --+ ar->led_default_trigger = ieee80211_create_tpt_led_trigger(ar->hw, -- IEEE80211_TPT_LEDTRIG_FL_RADIO, ath10k_tpt_blink, -- ARRAY_SIZE(ath10k_tpt_blink)); -- #endif -diff --git a/package/kernel/mac80211/patches/ath10k/981-ath10k-adjust-tx-power-reduction-for-US-regulatory-d.patch b/package/kernel/mac80211/patches/ath10k/981-ath10k-adjust-tx-power-reduction-for-US-regulatory-d.patch -deleted file mode 100644 -index 3626debf19..0000000000 ---- a/package/kernel/mac80211/patches/ath10k/981-ath10k-adjust-tx-power-reduction-for-US-regulatory-d.patch -+++ /dev/null -@@ -1,101 +0,0 @@ --From: Sven Eckelmann --Date: Wed, 28 Nov 2018 16:16:27 +0100 --Subject: ath10k: adjust tx power reduction for US regulatory domain -- --FCC allows maximum antenna gain of 6 dBi. 15.247(b)(4): -- --> (4) The conducted output power limit --> specified in paragraph (b) of this section --> is based on the use of antennas --> with directional gains that do not exceed --> 6 dBi. Except as shown in paragraph --> (c) of this section, if transmitting --> antennas of directional gain greater --> than 6 dBi are used, the conducted --> output power from the intentional radiator --> shall be reduced below the stated --> values in paragraphs (b)(1), (b)(2), --> and (b)(3) of this section, as appropriate, --> by the amount in dB that the --> directional gain of the antenna exceeds --> 6 dBi. -- --https://www.gpo.gov/fdsys/pkg/CFR-2013-title47-vol1/pdf/CFR-2013-title47-vol1-sec15-247.pdf -- --Signed-off-by: Sven Eckelmann -- --Forwarded: no -- ----- a/drivers/net/wireless/ath/ath10k/mac.c --+++ b/drivers/net/wireless/ath/ath10k/mac.c --@@ -1028,6 +1028,40 @@ static inline int ath10k_vdev_setup_sync -- return ar->last_wmi_vdev_start_status; -- } -- --+static u32 ath10k_get_max_antenna_gain(struct ath10k *ar, --+ u32 ch_max_antenna_gain) --+{ --+ u32 max_antenna_gain; --+ --+ if (ar->dfs_detector && ar->dfs_detector->region == NL80211_DFS_FCC) { --+ /* FCC allows maximum antenna gain of 6 dBi. 15.247(b)(4): --+ * --+ * > (4) The conducted output power limit --+ * > specified in paragraph (b) of this section --+ * > is based on the use of antennas --+ * > with directional gains that do not exceed --+ * > 6 dBi. Except as shown in paragraph --+ * > (c) of this section, if transmitting --+ * > antennas of directional gain greater --+ * > than 6 dBi are used, the conducted --+ * > output power from the intentional radiator --+ * > shall be reduced below the stated --+ * > values in paragraphs (b)(1), (b)(2), --+ * > and (b)(3) of this section, as appropriate, --+ * > by the amount in dB that the --+ * > directional gain of the antenna exceeds --+ * > 6 dBi. --+ * --+ * https://www.gpo.gov/fdsys/pkg/CFR-2013-title47-vol1/pdf/CFR-2013-title47-vol1-sec15-247.pdf --+ */ --+ max_antenna_gain = 6; --+ } else { --+ max_antenna_gain = 0; --+ } --+ --+ return max(ch_max_antenna_gain, max_antenna_gain); --+} --+ -- static int ath10k_monitor_vdev_start(struct ath10k *ar, int vdev_id) -- { -- struct cfg80211_chan_def *chandef = NULL; --@@ -1060,7 +1094,8 @@ static int ath10k_monitor_vdev_start(str -- arg.channel.min_power = 0; -- arg.channel.max_power = channel->max_power * 2; -- arg.channel.max_reg_power = channel->max_reg_power * 2; --- arg.channel.max_antenna_gain = channel->max_antenna_gain; --+ arg.channel.max_antenna_gain = ath10k_get_max_antenna_gain(ar, --+ channel->max_antenna_gain); -- -- reinit_completion(&ar->vdev_setup_done); -- reinit_completion(&ar->vdev_delete_done); --@@ -1506,7 +1541,8 @@ static int ath10k_vdev_start_restart(str -- arg.channel.min_power = 0; -- arg.channel.max_power = chandef->chan->max_power * 2; -- arg.channel.max_reg_power = chandef->chan->max_reg_power * 2; --- arg.channel.max_antenna_gain = chandef->chan->max_antenna_gain; --+ arg.channel.max_antenna_gain = ath10k_get_max_antenna_gain(ar, --+ chandef->chan->max_antenna_gain); -- -- if (arvif->vdev_type == WMI_VDEV_TYPE_AP) { -- arg.ssid = arvif->u.ap.ssid; --@@ -3437,7 +3473,8 @@ static int ath10k_update_channel_list(st -- ch->min_power = 0; -- ch->max_power = channel->max_power * 2; -- ch->max_reg_power = channel->max_reg_power * 2; --- ch->max_antenna_gain = channel->max_antenna_gain; --+ ch->max_antenna_gain = ath10k_get_max_antenna_gain(ar, --+ channel->max_antenna_gain); -- ch->reg_class_id = 0; /* FIXME */ -- -- /* FIXME: why use only legacy modes, why not any -diff --git a/package/kernel/mac80211/patches/ath10k/984-ath10k-Try-to-get-mac-address-from-dts.patch b/package/kernel/mac80211/patches/ath10k/984-ath10k-Try-to-get-mac-address-from-dts.patch -deleted file mode 100644 -index 084e28a2d9..0000000000 ---- a/package/kernel/mac80211/patches/ath10k/984-ath10k-Try-to-get-mac-address-from-dts.patch -+++ /dev/null -@@ -1,37 +0,0 @@ --From 22fb5991a44c78ff18ec0082dc90c809356eb893 Mon Sep 17 00:00:00 2001 --From: Ansuel Smith --Date: Sun, 27 Sep 2020 19:23:35 +0200 --Subject: [PATCH 1/2] ath10k: Try to get mac-address from dts -- --Most of embedded device that have the ath10k wifi integrated store the --mac-address in nvmem partitions. Try to fetch the mac-address using the --standard 'of_get_mac_address' than in all the check also try to fetch the --address using the nvmem api searching for a defined 'mac-address' cell. --Mac-address defined in the dts have priority than any other address found. -- --Tested-on: QCA9984 hw1.0 PCI 10.4 -- --Signed-off-by: Ansuel Smith ----- -- drivers/net/wireless/ath/ath10k/core.c | 10 ++++++++++ -- 1 file changed, 10 insertions(+) -- ----- a/drivers/net/wireless/ath/ath10k/core.c --+++ b/drivers/net/wireless/ath/ath10k/core.c --@@ -8,6 +8,7 @@ -- #include -- #include -- #include --+#include -- #include -- #include -- #include --@@ -3407,6 +3408,8 @@ static int ath10k_core_probe_fw(struct a -- -- device_get_mac_address(ar->dev, ar->mac_addr); -- --+ of_get_mac_address(ar->dev->of_node, ar->mac_addr); --+ -- ret = ath10k_core_init_firmware_features(ar); -- if (ret) { -- ath10k_err(ar, "fatal problem with firmware features: %d\n", -diff --git a/package/kernel/mac80211/patches/ath10k/990-ath10k-small-buffers.patch b/package/kernel/mac80211/patches/ath10k/990-ath10k-small-buffers.patch -deleted file mode 100644 -index 2f560c70a0..0000000000 ---- a/package/kernel/mac80211/patches/ath10k/990-ath10k-small-buffers.patch -+++ /dev/null -@@ -1,64 +0,0 @@ ----- a/drivers/net/wireless/ath/ath10k/htt.h --+++ b/drivers/net/wireless/ath/ath10k/htt.h --@@ -235,7 +235,11 @@ enum htt_rx_ring_flags { -- }; -- -- #define HTT_RX_RING_SIZE_MIN 128 --+#ifndef CONFIG_ATH10K_SMALLBUFFERS -- #define HTT_RX_RING_SIZE_MAX 2048 --+#else --+#define HTT_RX_RING_SIZE_MAX 512 --+#endif -- #define HTT_RX_RING_SIZE HTT_RX_RING_SIZE_MAX -- #define HTT_RX_RING_FILL_LEVEL (((HTT_RX_RING_SIZE) / 2) - 1) -- #define HTT_RX_RING_FILL_LEVEL_DUAL_MAC (HTT_RX_RING_SIZE - 1) ----- a/drivers/net/wireless/ath/ath10k/pci.c --+++ b/drivers/net/wireless/ath/ath10k/pci.c --@@ -131,7 +131,11 @@ static const struct ce_attr pci_host_ce_ -- .flags = CE_ATTR_FLAGS, -- .src_nentries = 0, -- .src_sz_max = 2048, --+#ifndef CONFIG_ATH10K_SMALLBUFFERS -- .dest_nentries = 512, --+#else --+ .dest_nentries = 128, --+#endif -- .recv_cb = ath10k_pci_htt_htc_rx_cb, -- }, -- --@@ -140,7 +144,11 @@ static const struct ce_attr pci_host_ce_ -- .flags = CE_ATTR_FLAGS, -- .src_nentries = 0, -- .src_sz_max = 2048, --+#ifndef CONFIG_ATH10K_SMALLBUFFERS -- .dest_nentries = 128, --+#else --+ .dest_nentries = 64, --+#endif -- .recv_cb = ath10k_pci_htc_rx_cb, -- }, -- --@@ -167,7 +175,11 @@ static const struct ce_attr pci_host_ce_ -- .flags = CE_ATTR_FLAGS, -- .src_nentries = 0, -- .src_sz_max = 512, --+#ifndef CONFIG_ATH10K_SMALLBUFFERS -- .dest_nentries = 512, --+#else --+ .dest_nentries = 128, --+#endif -- .recv_cb = ath10k_pci_htt_rx_cb, -- }, -- --@@ -192,7 +204,11 @@ static const struct ce_attr pci_host_ce_ -- .flags = CE_ATTR_FLAGS, -- .src_nentries = 0, -- .src_sz_max = 2048, --+#ifndef CONFIG_ATH10K_SMALLBUFFERS -- .dest_nentries = 128, --+#else --+ .dest_nentries = 96, --+#endif -- .recv_cb = ath10k_pci_pktlog_rx_cb, -- }, -- -diff --git a/package/kernel/mac80211/patches/ath11k/0001-wifi-ath11k-stop-tx-queues-immediately-upon-firmware.patch b/package/kernel/mac80211/patches/ath11k/0001-wifi-ath11k-stop-tx-queues-immediately-upon-firmware.patch -deleted file mode 100644 -index d0dc04febf..0000000000 ---- a/package/kernel/mac80211/patches/ath11k/0001-wifi-ath11k-stop-tx-queues-immediately-upon-firmware.patch -+++ /dev/null -@@ -1,78 +0,0 @@ --From 81e60b2dfb2744ab6642c4aa62534b4f711fdc5d Mon Sep 17 00:00:00 2001 --From: Aditya Kumar Singh --Date: Tue, 27 Sep 2022 09:18:54 +0300 --Subject: [PATCH] wifi: ath11k: stop tx queues immediately upon firmware exit -- --Currently, recovery flag is set immediately upon firmware --exit but tx queues are stopped once firmware arrives back --and is ready which is during ath11k_core_restart. Once --ieee80211 hw restart is completed, tx queues are resumed. --If during the time delta between firmware exit and firmware --ready, mac80211 send packets, currently ath11k will drop it --since recovery flag will be set. But warning prints will --come - -- "ath11k c000000.wifi: failed to transmit frame -108" -- --If more tx packets are there, this could lead to flooding --of above print. -- --However, actually tx queues should be stopped immediately --when firmware leaves. This will prevent packets to get --dropped when firmware is recovering. -- --Add fix to stop tx queues immediately after firmware exit. -- --Tested-on: IPQ8074 hw2.0 AHB WLAN.HK.2.5.0.1-01100-QCAHKSWPL_SILICONZ-1 -- --Signed-off-by: Aditya Kumar Singh --Signed-off-by: Kalle Valo --Link: https://lore.kernel.org/r/20220923170235.18873-1-quic_adisi@quicinc.com ----- -- drivers/net/wireless/ath/ath11k/core.c | 5 +---- -- drivers/net/wireless/ath/ath11k/core.h | 1 + -- drivers/net/wireless/ath/ath11k/qmi.c | 3 +++ -- 3 files changed, 5 insertions(+), 4 deletions(-) -- ----- a/drivers/net/wireless/ath/ath11k/core.c --+++ b/drivers/net/wireless/ath/ath11k/core.c --@@ -1641,7 +1641,7 @@ static void ath11k_update_11d(struct wor -- } -- } -- ---static void ath11k_core_pre_reconfigure_recovery(struct ath11k_base *ab) --+void ath11k_core_pre_reconfigure_recovery(struct ath11k_base *ab) -- { -- struct ath11k *ar; -- struct ath11k_pdev *pdev; --@@ -1730,9 +1730,6 @@ static void ath11k_core_restart(struct w -- struct ath11k_base *ab = container_of(work, struct ath11k_base, restart_work); -- int ret; -- --- if (!ab->is_reset) --- ath11k_core_pre_reconfigure_recovery(ab); --- -- ret = ath11k_core_reconfigure_on_crash(ab); -- if (ret) { -- ath11k_err(ab, "failed to reconfigure driver on crash recovery\n"); ----- a/drivers/net/wireless/ath/ath11k/core.h --+++ b/drivers/net/wireless/ath/ath11k/core.h --@@ -1158,6 +1158,7 @@ int ath11k_core_check_smbios(struct ath1 -- void ath11k_core_halt(struct ath11k *ar); -- int ath11k_core_resume(struct ath11k_base *ab); -- int ath11k_core_suspend(struct ath11k_base *ab); --+void ath11k_core_pre_reconfigure_recovery(struct ath11k_base *ab); -- -- const struct firmware *ath11k_core_firmware_request(struct ath11k_base *ab, -- const char *filename); ----- a/drivers/net/wireless/ath/ath11k/qmi.c --+++ b/drivers/net/wireless/ath/ath11k/qmi.c --@@ -3164,6 +3164,9 @@ static void ath11k_qmi_driver_event_work -- case ATH11K_QMI_EVENT_SERVER_EXIT: -- set_bit(ATH11K_FLAG_CRASH_FLUSH, &ab->dev_flags); -- set_bit(ATH11K_FLAG_RECOVERY, &ab->dev_flags); --+ --+ if (!ab->is_reset) --+ ath11k_core_pre_reconfigure_recovery(ab); -- break; -- case ATH11K_QMI_EVENT_REQUEST_MEM: -- ret = ath11k_qmi_event_mem_request(qmi); -diff --git a/package/kernel/mac80211/patches/ath11k/0002-wifi-ath11k-Don-t-exit-on-wakeup-failure.patch b/package/kernel/mac80211/patches/ath11k/0002-wifi-ath11k-Don-t-exit-on-wakeup-failure.patch -deleted file mode 100644 -index 47385e0458..0000000000 ---- a/package/kernel/mac80211/patches/ath11k/0002-wifi-ath11k-Don-t-exit-on-wakeup-failure.patch -+++ /dev/null -@@ -1,45 +0,0 @@ --From 45d2e268369b0c768d5a644f319758bcfd370521 Mon Sep 17 00:00:00 2001 --From: Baochen Qiang --Date: Wed, 28 Sep 2022 09:51:40 +0800 --Subject: [PATCH] wifi: ath11k: Don't exit on wakeup failure -- --Currently, ath11k_pcic_read() returns an error if wakeup() --fails, this makes firmware crash debug quite hard because we can --get nothing. -- --Change to go ahead on wakeup failure, in that case we still may --get something valid to check. There should be no mislead due --to incorrect content because we are aware of the failure with the --log printed. -- --Tested-on: WCN6855 hw2.0 PCI WLAN.HSP.1.1-01720.1-QCAHSPSWPL_V1_V2_SILICONZ_LITE-1 -- --Signed-off-by: Baochen Qiang --Signed-off-by: Kalle Valo --Link: https://lore.kernel.org/r/20220928015140.5431-1-quic_bqiang@quicinc.com ----- -- drivers/net/wireless/ath/ath11k/pcic.c | 13 ++++++++++--- -- 1 file changed, 10 insertions(+), 3 deletions(-) -- ----- a/drivers/net/wireless/ath/ath11k/pcic.c --+++ b/drivers/net/wireless/ath/ath11k/pcic.c --@@ -218,9 +218,16 @@ int ath11k_pcic_read(struct ath11k_base -- if (wakeup_required && ab->pci.ops->wakeup) { -- ret = ab->pci.ops->wakeup(ab); -- if (ret) { --- ath11k_warn(ab, "failed to wakeup for read from 0x%x: %d\n", --- start, ret); --- return ret; --+ ath11k_warn(ab, --+ "wakeup failed, data may be invalid: %d", --+ ret); --+ /* Even though wakeup() failed, continue processing rather --+ * than returning because some parts of the data may still --+ * be valid and useful in some cases, e.g. could give us --+ * some clues on firmware crash. --+ * Mislead due to invalid data could be avoided because we --+ * are aware of the wakeup failure. --+ */ -- } -- } -- -diff --git a/package/kernel/mac80211/patches/ath11k/0005-wifi-ath11k-Fix-spelling-mistake-chnange-change.patch b/package/kernel/mac80211/patches/ath11k/0005-wifi-ath11k-Fix-spelling-mistake-chnange-change.patch -deleted file mode 100644 -index 4b52252ef3..0000000000 ---- a/package/kernel/mac80211/patches/ath11k/0005-wifi-ath11k-Fix-spelling-mistake-chnange-change.patch -+++ /dev/null -@@ -1,25 +0,0 @@ --From a797f479bf3e02c6d179c2e6aeace7f9b22b0acd Mon Sep 17 00:00:00 2001 --From: Colin Ian King --Date: Wed, 28 Sep 2022 15:38:34 +0100 --Subject: [PATCH] wifi: ath11k: Fix spelling mistake "chnange" -> "change" -- --There is a spelling mistake in an ath11k_dbg debug message. Fix it. -- --Signed-off-by: Colin Ian King --Signed-off-by: Kalle Valo --Link: https://lore.kernel.org/r/20220928143834.35189-1-colin.i.king@gmail.com ----- -- drivers/net/wireless/ath/ath11k/wmi.c | 2 +- -- 1 file changed, 1 insertion(+), 1 deletion(-) -- ----- a/drivers/net/wireless/ath/ath11k/wmi.c --+++ b/drivers/net/wireless/ath/ath11k/wmi.c --@@ -6829,7 +6829,7 @@ static void ath11k_wmi_event_peer_sta_ps -- } -- -- ath11k_dbg(ab, ATH11K_DBG_WMI, --- "peer sta ps chnange ev addr %pM state %u sup_bitmap %x ps_valid %u ts %u\n", --+ "peer sta ps change ev addr %pM state %u sup_bitmap %x ps_valid %u ts %u\n", -- ev->peer_macaddr.addr, ev->peer_ps_state, -- ev->ps_supported_bitmap, ev->peer_ps_valid, -- ev->peer_ps_timestamp); -diff --git a/package/kernel/mac80211/patches/ath11k/0007-wifi-ath11k-suppress-add-interface-error.patch b/package/kernel/mac80211/patches/ath11k/0007-wifi-ath11k-suppress-add-interface-error.patch -deleted file mode 100644 -index fbef0abb8d..0000000000 ---- a/package/kernel/mac80211/patches/ath11k/0007-wifi-ath11k-suppress-add-interface-error.patch -+++ /dev/null -@@ -1,52 +0,0 @@ --From 638b26652b0438563a76ec90014c8cba34db982b Mon Sep 17 00:00:00 2001 --From: Karthikeyan Periyasamy --Date: Thu, 6 Oct 2022 06:28:42 +0530 --Subject: [PATCH 7/9] wifi: ath11k: suppress add interface error -- --In the VIF (other than monitor type) creation request, we should not --throw the error code when the monitor VIF creation fails, since the --actual VIF creation succeeds. If we throw the error code from driver --then the actual VIF creation get fail. So suppress the monitor VIF --creation error by throwing warning message instead of error code. -- --Tested-on: QCN9074 hw1.0 PCI WLAN.HK.2.6.0.1-00760-QCAHKSWPL_SILICONZ-1 -- --Signed-off-by: Karthikeyan Periyasamy --Signed-off-by: Kalle Valo --Link: https://lore.kernel.org/r/20221006005842.8599-1-quic_periyasa@quicinc.com ----- -- drivers/net/wireless/ath/ath11k/mac.c | 9 +++------ -- 1 file changed, 3 insertions(+), 6 deletions(-) -- ----- a/drivers/net/wireless/ath/ath11k/mac.c --+++ b/drivers/net/wireless/ath/ath11k/mac.c --@@ -6421,18 +6421,16 @@ static int ath11k_mac_op_add_interface(s -- -- ath11k_dp_vdev_tx_attach(ar, arvif); -- --+ ath11k_debugfs_add_interface(arvif); --+ -- if (vif->type != NL80211_IFTYPE_MONITOR && -- test_bit(ATH11K_FLAG_MONITOR_CONF_ENABLED, &ar->monitor_flags)) { -- ret = ath11k_mac_monitor_vdev_create(ar); --- if (ret) { --+ if (ret) -- ath11k_warn(ar->ab, "failed to create monitor vdev during add interface: %d", -- ret); --- goto err_peer_del; --- } -- } -- --- ath11k_debugfs_add_interface(arvif); --- -- mutex_unlock(&ar->conf_mutex); -- -- return 0; --@@ -6457,7 +6455,6 @@ err_vdev_del: -- spin_unlock_bh(&ar->data_lock); -- -- err: --- ath11k_debugfs_remove_interface(arvif); -- mutex_unlock(&ar->conf_mutex); -- -- return ret; -diff --git a/package/kernel/mac80211/patches/ath11k/0008-wifi-ath11k-add-support-to-configure-channel-dwell-t.patch b/package/kernel/mac80211/patches/ath11k/0008-wifi-ath11k-add-support-to-configure-channel-dwell-t.patch -deleted file mode 100644 -index d0b19fe59f..0000000000 ---- a/package/kernel/mac80211/patches/ath11k/0008-wifi-ath11k-add-support-to-configure-channel-dwell-t.patch -+++ /dev/null -@@ -1,102 +0,0 @@ --From c362daa213cdeb0a9e7c2ed84849544c24505720 Mon Sep 17 00:00:00 2001 --From: Manikanta Pubbisetty --Date: Fri, 7 Oct 2022 10:41:30 +0530 --Subject: [PATCH 8/9] wifi: ath11k: add support to configure channel dwell time -- --Add support to configure channel dwell time during scan. --Dwell time help to stay on the channel for a specified duration --during scan and aid userspace in finding WiFi networks. Very --useful in passive scans where longer dwell times are needed --to find the WiFi networks. -- --Configure channel dwell time from duration of the scan request --received from mac80211 when the duration is non-zero. When the --scan request does not have duration value, use the default ones, --the current implementation. -- --Advertise corresponding feature flag NL80211_EXT_FEATURE_SET_SCAN_DWELL --to enable the feature. -- --Change is applicable for all ath11k hardware. -- --Tested-on: WCN6750 hw1.0 AHB WLAN.MSL.1.0.1-00887-QCAMSLSWPLZ-1 -- --Signed-off-by: Manikanta Pubbisetty --Reviewed-by: Jeff Johnson --Signed-off-by: Kalle Valo --Link: https://lore.kernel.org/r/20221007051130.6067-1-quic_mpubbise@quicinc.com ----- -- drivers/net/wireless/ath/ath11k/mac.c | 33 +++++++++++++++++++++++---- -- 1 file changed, 29 insertions(+), 4 deletions(-) -- ----- a/drivers/net/wireless/ath/ath11k/mac.c --+++ b/drivers/net/wireless/ath/ath11k/mac.c --@@ -241,7 +241,10 @@ const struct htt_rx_ring_tlv_filter ath1 -- #define ath11k_a_rates (ath11k_legacy_rates + 4) -- #define ath11k_a_rates_size (ARRAY_SIZE(ath11k_legacy_rates) - 4) -- ---#define ATH11K_MAC_SCAN_TIMEOUT_MSECS 200 /* in msecs */ --+#define ATH11K_MAC_SCAN_CMD_EVT_OVERHEAD 200 /* in msecs */ --+ --+/* Overhead due to the processing of channel switch events from FW */ --+#define ATH11K_SCAN_CHANNEL_SWITCH_WMI_EVT_OVERHEAD 10 /* in msecs */ -- -- static const u32 ath11k_smps_map[] = { -- [WLAN_HT_CAP_SM_PS_STATIC] = WMI_PEER_SMPS_STATIC, --@@ -3612,6 +3615,7 @@ static int ath11k_mac_op_hw_scan(struct -- struct scan_req_params arg; -- int ret = 0; -- int i; --+ u32 scan_timeout; -- -- mutex_lock(&ar->conf_mutex); -- --@@ -3681,6 +3685,26 @@ static int ath11k_mac_op_hw_scan(struct -- ether_addr_copy(arg.mac_mask.addr, req->mac_addr_mask); -- } -- --+ /* if duration is set, default dwell times will be overwritten */ --+ if (req->duration) { --+ arg.dwell_time_active = req->duration; --+ arg.dwell_time_active_2g = req->duration; --+ arg.dwell_time_active_6g = req->duration; --+ arg.dwell_time_passive = req->duration; --+ arg.dwell_time_passive_6g = req->duration; --+ arg.burst_duration = req->duration; --+ --+ scan_timeout = min_t(u32, arg.max_rest_time * --+ (arg.num_chan - 1) + (req->duration + --+ ATH11K_SCAN_CHANNEL_SWITCH_WMI_EVT_OVERHEAD) * --+ arg.num_chan, arg.max_scan_time); --+ } else { --+ scan_timeout = arg.max_scan_time; --+ } --+ --+ /* Add a margin to account for event/command processing */ --+ scan_timeout += ATH11K_MAC_SCAN_CMD_EVT_OVERHEAD; --+ -- ret = ath11k_start_scan(ar, &arg); -- if (ret) { -- ath11k_warn(ar->ab, "failed to start hw scan: %d\n", ret); --@@ -3689,10 +3713,8 @@ static int ath11k_mac_op_hw_scan(struct -- spin_unlock_bh(&ar->data_lock); -- } -- --- /* Add a 200ms margin to account for event/command processing */ -- ieee80211_queue_delayed_work(ar->hw, &ar->scan.timeout, --- msecs_to_jiffies(arg.max_scan_time + --- ATH11K_MAC_SCAN_TIMEOUT_MSECS)); --+ msecs_to_jiffies(scan_timeout)); -- -- exit: -- kfree(arg.chan_list); --@@ -9060,6 +9082,9 @@ static int __ath11k_mac_register(struct -- NL80211_EXT_FEATURE_UNSOL_BCAST_PROBE_RESP); -- } -- --+ wiphy_ext_feature_set(ar->hw->wiphy, --+ NL80211_EXT_FEATURE_SET_SCAN_DWELL); --+ -- ath11k_reg_init(ar); -- -- if (!test_bit(ATH11K_FLAG_RAW_MODE, &ab->dev_flags)) { -diff --git a/package/kernel/mac80211/patches/ath11k/0010-wifi-ath11k-Fix-firmware-crash-on-vdev-delete-race-c.patch b/package/kernel/mac80211/patches/ath11k/0010-wifi-ath11k-Fix-firmware-crash-on-vdev-delete-race-c.patch -deleted file mode 100644 -index 7275af06ea..0000000000 ---- a/package/kernel/mac80211/patches/ath11k/0010-wifi-ath11k-Fix-firmware-crash-on-vdev-delete-race-c.patch -+++ /dev/null -@@ -1,116 +0,0 @@ --From 3811fa1f231f1a3e29759efef4992116604aab8b Mon Sep 17 00:00:00 2001 --From: Sowmiya Sree Elavalagan --Date: Tue, 11 Oct 2022 15:23:46 +0530 --Subject: [PATCH] wifi: ath11k: Fix firmware crash on vdev delete race -- condition -- --Current code does not wait for vdev delete completion on vdev create --failures and tries to send another vdev create followed by vdev set --param to firmware with same vdev id. This causes firmware crash. --Fix this crash by waiting for vdev delete completion on vdev --create failures. -- --Tested-on: IPQ8074 hw2.0 AHB WLAN.HK.2.6.0.1-00905-QCAHKSWPL_SILICONZ-1 -- --Signed-off-by: Sowmiya Sree Elavalagan --Signed-off-by: Kalle Valo --Link: https://lore.kernel.org/r/20221011095346.3901-1-quic_ssreeela@quicinc.com ----- -- drivers/net/wireless/ath/ath11k/mac.c | 60 +++++++++++++++++---------- -- 1 file changed, 37 insertions(+), 23 deletions(-) -- ----- a/drivers/net/wireless/ath/ath11k/mac.c --+++ b/drivers/net/wireless/ath/ath11k/mac.c --@@ -6233,6 +6233,40 @@ void ath11k_mac_11d_scan_stop_all(struct -- } -- } -- --+static int ath11k_mac_vdev_delete(struct ath11k *ar, struct ath11k_vif *arvif) --+{ --+ unsigned long time_left; --+ struct ieee80211_vif *vif = arvif->vif; --+ int ret = 0; --+ --+ lockdep_assert_held(&ar->conf_mutex); --+ --+ reinit_completion(&ar->vdev_delete_done); --+ --+ ret = ath11k_wmi_vdev_delete(ar, arvif->vdev_id); --+ if (ret) { --+ ath11k_warn(ar->ab, "failed to delete WMI vdev %d: %d\n", --+ arvif->vdev_id, ret); --+ return ret; --+ } --+ --+ time_left = wait_for_completion_timeout(&ar->vdev_delete_done, --+ ATH11K_VDEV_DELETE_TIMEOUT_HZ); --+ if (time_left == 0) { --+ ath11k_warn(ar->ab, "Timeout in receiving vdev delete response\n"); --+ return -ETIMEDOUT; --+ } --+ --+ ar->ab->free_vdev_map |= 1LL << (arvif->vdev_id); --+ ar->allocated_vdev_map &= ~(1LL << arvif->vdev_id); --+ ar->num_created_vdevs--; --+ --+ ath11k_dbg(ar->ab, ATH11K_DBG_MAC, "vdev %pM deleted, vdev_id %d\n", --+ vif->addr, arvif->vdev_id); --+ --+ return ret; --+} --+ -- static int ath11k_mac_op_add_interface(struct ieee80211_hw *hw, -- struct ieee80211_vif *vif) -- { --@@ -6468,10 +6502,7 @@ err_peer_del: -- } -- -- err_vdev_del: --- ath11k_wmi_vdev_delete(ar, arvif->vdev_id); --- ar->num_created_vdevs--; --- ar->allocated_vdev_map &= ~(1LL << arvif->vdev_id); --- ab->free_vdev_map |= 1LL << arvif->vdev_id; --+ ath11k_mac_vdev_delete(ar, arvif); -- spin_lock_bh(&ar->data_lock); -- list_del(&arvif->list); -- spin_unlock_bh(&ar->data_lock); --@@ -6499,7 +6530,6 @@ 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; --- unsigned long time_left; -- int ret; -- int i; -- --@@ -6520,29 +6550,13 @@ static void ath11k_mac_op_remove_interfa -- arvif->vdev_id, ret); -- } -- --- reinit_completion(&ar->vdev_delete_done); --- --- ret = ath11k_wmi_vdev_delete(ar, arvif->vdev_id); --+ ret = ath11k_mac_vdev_delete(ar, arvif); -- if (ret) { --- ath11k_warn(ab, "failed to delete WMI vdev %d: %d\n", --+ ath11k_warn(ab, "failed to delete vdev %d: %d\n", -- arvif->vdev_id, ret); -- goto err_vdev_del; -- } -- --- time_left = wait_for_completion_timeout(&ar->vdev_delete_done, --- ATH11K_VDEV_DELETE_TIMEOUT_HZ); --- if (time_left == 0) { --- ath11k_warn(ab, "Timeout in receiving vdev delete response\n"); --- goto err_vdev_del; --- } --- --- ab->free_vdev_map |= 1LL << (arvif->vdev_id); --- ar->allocated_vdev_map &= ~(1LL << arvif->vdev_id); --- ar->num_created_vdevs--; --- --- ath11k_dbg(ab, ATH11K_DBG_MAC, "vdev %pM deleted, vdev_id %d\n", --- vif->addr, arvif->vdev_id); --- -- if (arvif->vdev_type == WMI_VDEV_TYPE_MONITOR) { -- clear_bit(ATH11K_FLAG_MONITOR_VDEV_CREATED, &ar->monitor_flags); -- ar->monitor_vdev_id = -1; -diff --git a/package/kernel/mac80211/patches/ath11k/0011-wifi-ath11k-fix-monitor-vdev-creation-with-firmware-.patch b/package/kernel/mac80211/patches/ath11k/0011-wifi-ath11k-fix-monitor-vdev-creation-with-firmware-.patch -deleted file mode 100644 -index 2f066d0a56..0000000000 ---- a/package/kernel/mac80211/patches/ath11k/0011-wifi-ath11k-fix-monitor-vdev-creation-with-firmware-.patch -+++ /dev/null -@@ -1,40 +0,0 @@ --From f3ca72b0327101a074a871539e61775d43908ca4 Mon Sep 17 00:00:00 2001 --From: Nagarajan Maran --Date: Fri, 14 Oct 2022 21:20:54 +0530 --Subject: [PATCH] wifi: ath11k: fix monitor vdev creation with firmware -- recovery -- --During firmware recovery, the monitor interface is not --getting created in the driver and firmware since --the respective flags are not updated properly. -- --So after firmware recovery is successful, when monitor --interface is brought down manually, firmware assertion --is observed, since we are trying to bring down the --interface which is not yet created in the firmware. -- --Fix this by updating the monitor flags properly per --phy#, during firmware recovery. -- --Tested-on: IPQ8074 hw2.0 AHB WLAN.HK.2.7.0.1-01744-QCAHKSWPL_SILICONZ-1 -- --Signed-off-by: Nagarajan Maran --Signed-off-by: Kalle Valo --Link: https://lore.kernel.org/r/20221014155054.11471-1-quic_nmaran@quicinc.com ----- -- drivers/net/wireless/ath/ath11k/core.c | 4 ++++ -- 1 file changed, 4 insertions(+) -- ----- a/drivers/net/wireless/ath/ath11k/core.c --+++ b/drivers/net/wireless/ath/ath11k/core.c --@@ -1677,6 +1677,10 @@ void ath11k_core_pre_reconfigure_recover -- ath11k_mac_tx_mgmt_pending_free, ar); -- idr_destroy(&ar->txmgmt_idr); -- wake_up(&ar->txmgmt_empty_waitq); --+ --+ ar->monitor_vdev_id = -1; --+ clear_bit(ATH11K_FLAG_MONITOR_STARTED, &ar->monitor_flags); --+ clear_bit(ATH11K_FLAG_MONITOR_VDEV_CREATED, &ar->monitor_flags); -- } -- -- wake_up(&ab->wmi_ab.tx_credits_wq); -diff --git a/package/kernel/mac80211/patches/ath11k/0012-wifi-ath11k-Fix-qmi_msg_handler-data-structure-initi.patch b/package/kernel/mac80211/patches/ath11k/0012-wifi-ath11k-Fix-qmi_msg_handler-data-structure-initi.patch -deleted file mode 100644 -index fccfa4385a..0000000000 ---- a/package/kernel/mac80211/patches/ath11k/0012-wifi-ath11k-Fix-qmi_msg_handler-data-structure-initi.patch -+++ /dev/null -@@ -1,33 +0,0 @@ --From ed3725e15a154ebebf44e0c34806c57525483f92 Mon Sep 17 00:00:00 2001 --From: Rahul Bhattacharjee --Date: Fri, 21 Oct 2022 14:31:26 +0530 --Subject: [PATCH] wifi: ath11k: Fix qmi_msg_handler data structure -- initialization -- --qmi_msg_handler is required to be null terminated by QMI module. --There might be a case where a handler for a msg id is not present in the --handlers array which can lead to infinite loop while searching the handler --and therefore out of bound access in qmi_invoke_handler(). --Hence update the initialization in qmi_msg_handler data structure. -- --Tested-on: IPQ8074 hw2.0 AHB WLAN.HK.2.5.0.1-01100-QCAHKSWPL_SILICONZ-1 -- --Signed-off-by: Rahul Bhattacharjee --Signed-off-by: Kalle Valo --Link: https://lore.kernel.org/r/20221021090126.28626-1-quic_rbhattac@quicinc.com ----- -- drivers/net/wireless/ath/ath11k/qmi.c | 3 +++ -- 1 file changed, 3 insertions(+) -- ----- a/drivers/net/wireless/ath/ath11k/qmi.c --+++ b/drivers/net/wireless/ath/ath11k/qmi.c --@@ -1702,6 +1702,9 @@ static struct qmi_elem_info qmi_wlfw_fw_ -- .data_type = QMI_EOTI, -- .array_type = NO_ARRAY, -- }, --+ --+ /* end of list */ --+ {}, -- }; -- -- static int ath11k_qmi_host_cap_send(struct ath11k_base *ab) -diff --git a/package/kernel/mac80211/patches/ath11k/0013-wifi-ath11k-synchronize-ath11k_mac_he_gi_to_nl80211_.patch b/package/kernel/mac80211/patches/ath11k/0013-wifi-ath11k-synchronize-ath11k_mac_he_gi_to_nl80211_.patch -deleted file mode 100644 -index 1e89b4d4f2..0000000000 ---- a/package/kernel/mac80211/patches/ath11k/0013-wifi-ath11k-synchronize-ath11k_mac_he_gi_to_nl80211_.patch -+++ /dev/null -@@ -1,42 +0,0 @@ --From dd1c2322694522f674c874f5fa02ac5ae39135dd Mon Sep 17 00:00:00 2001 --From: "Jiri Slaby (SUSE)" --Date: Mon, 31 Oct 2022 12:43:41 +0100 --Subject: [PATCH] wifi: ath11k: synchronize -- ath11k_mac_he_gi_to_nl80211_he_gi()'s return type -- --ath11k_mac_he_gi_to_nl80211_he_gi() generates a valid warning with gcc-13: -- drivers/net/wireless/ath/ath11k/mac.c:321:20: error: conflicting types for 'ath11k_mac_he_gi_to_nl80211_he_gi' due to enum/integer mismatch; have 'enum nl80211_he_gi(u8)' -- drivers/net/wireless/ath/ath11k/mac.h:166:5: note: previous declaration of 'ath11k_mac_he_gi_to_nl80211_he_gi' with type 'u32(u8)' -- --I.e. the type of the return value ath11k_mac_he_gi_to_nl80211_he_gi() in --the declaration is u32, while the definition spells enum nl80211_he_gi. --Synchronize them to the latter. -- --Cc: Martin Liska --Cc: Kalle Valo --Cc: "David S. Miller" --Cc: Eric Dumazet --Cc: Jakub Kicinski --Cc: Paolo Abeni --Cc: ath11k@lists.infradead.org --Cc: linux-wireless@vger.kernel.org --Cc: netdev@vger.kernel.org --Signed-off-by: Jiri Slaby (SUSE) --Reviewed-by: Jeff Johnson --Signed-off-by: Kalle Valo --Link: https://lore.kernel.org/r/20221031114341.10377-1-jirislaby@kernel.org ----- -- drivers/net/wireless/ath/ath11k/mac.h | 2 +- -- 1 file changed, 1 insertion(+), 1 deletion(-) -- ----- a/drivers/net/wireless/ath/ath11k/mac.h --+++ b/drivers/net/wireless/ath/ath11k/mac.h --@@ -163,7 +163,7 @@ void ath11k_mac_drain_tx(struct ath11k * -- void ath11k_mac_peer_cleanup_all(struct ath11k *ar); -- int ath11k_mac_tx_mgmt_pending_free(int buf_id, void *skb, void *ctx); -- u8 ath11k_mac_bw_to_mac80211_bw(u8 bw); ---u32 ath11k_mac_he_gi_to_nl80211_he_gi(u8 sgi); --+enum nl80211_he_gi ath11k_mac_he_gi_to_nl80211_he_gi(u8 sgi); -- enum nl80211_he_ru_alloc ath11k_mac_phy_he_ru_to_nl80211_he_ru_alloc(u16 ru_phy); -- enum nl80211_he_ru_alloc ath11k_mac_he_ru_tones_to_nl80211_he_ru_alloc(u16 ru_tones); -- enum ath11k_supported_bw ath11k_mac_mac80211_bw_to_ath11k_bw(enum rate_info_bw bw); -diff --git a/package/kernel/mac80211/patches/ath11k/0016-wifi-ath11k-Make-QMI-message-rules-const.patch b/package/kernel/mac80211/patches/ath11k/0016-wifi-ath11k-Make-QMI-message-rules-const.patch -deleted file mode 100644 -index 1f48df73f7..0000000000 ---- a/package/kernel/mac80211/patches/ath11k/0016-wifi-ath11k-Make-QMI-message-rules-const.patch -+++ /dev/null -@@ -1,341 +0,0 @@ --From 93c1592889fca46d09d833455628bab05516cdbf Mon Sep 17 00:00:00 2001 --From: Jeff Johnson --Date: Wed, 14 Sep 2022 17:23:03 -0700 --Subject: [PATCH] wifi: ath11k: Make QMI message rules const -- --Commit ff6d365898d4 ("soc: qcom: qmi: use const for struct --qmi_elem_info") allows QMI message encoding/decoding rules to be --const, so do that for ath11k. -- --Compile tested only. -- --Signed-off-by: Jeff Johnson --Signed-off-by: Kalle Valo --Link: https://lore.kernel.org/r/20220915002303.12206-1-quic_jjohnson@quicinc.com ----- -- drivers/net/wireless/ath/ath11k/qmi.c | 72 +++++++++++++-------------- -- 1 file changed, 36 insertions(+), 36 deletions(-) -- ----- a/drivers/net/wireless/ath/ath11k/qmi.c --+++ b/drivers/net/wireless/ath/ath11k/qmi.c --@@ -29,7 +29,7 @@ module_param_named(cold_boot_cal, ath11k -- MODULE_PARM_DESC(cold_boot_cal, -- "Decrease the channel switch time but increase the driver load time (Default: true)"); -- ---static struct qmi_elem_info qmi_wlanfw_host_cap_req_msg_v01_ei[] = { --+static const struct qmi_elem_info qmi_wlanfw_host_cap_req_msg_v01_ei[] = { -- { -- .data_type = QMI_OPT_FLAG, -- .elem_len = 1, --@@ -280,7 +280,7 @@ static struct qmi_elem_info qmi_wlanfw_h -- }, -- }; -- ---static struct qmi_elem_info qmi_wlanfw_host_cap_resp_msg_v01_ei[] = { --+static const struct qmi_elem_info qmi_wlanfw_host_cap_resp_msg_v01_ei[] = { -- { -- .data_type = QMI_STRUCT, -- .elem_len = 1, --@@ -297,7 +297,7 @@ static struct qmi_elem_info qmi_wlanfw_h -- }, -- }; -- ---static struct qmi_elem_info qmi_wlanfw_ind_register_req_msg_v01_ei[] = { --+static const struct qmi_elem_info qmi_wlanfw_ind_register_req_msg_v01_ei[] = { -- { -- .data_type = QMI_OPT_FLAG, -- .elem_len = 1, --@@ -522,7 +522,7 @@ static struct qmi_elem_info qmi_wlanfw_i -- }, -- }; -- ---static struct qmi_elem_info qmi_wlanfw_ind_register_resp_msg_v01_ei[] = { --+static const struct qmi_elem_info qmi_wlanfw_ind_register_resp_msg_v01_ei[] = { -- { -- .data_type = QMI_STRUCT, -- .elem_len = 1, --@@ -558,7 +558,7 @@ static struct qmi_elem_info qmi_wlanfw_i -- }, -- }; -- ---static struct qmi_elem_info qmi_wlanfw_mem_cfg_s_v01_ei[] = { --+static const struct qmi_elem_info qmi_wlanfw_mem_cfg_s_v01_ei[] = { -- { -- .data_type = QMI_UNSIGNED_8_BYTE, -- .elem_len = 1, --@@ -590,7 +590,7 @@ static struct qmi_elem_info qmi_wlanfw_m -- }, -- }; -- ---static struct qmi_elem_info qmi_wlanfw_mem_seg_s_v01_ei[] = { --+static const struct qmi_elem_info qmi_wlanfw_mem_seg_s_v01_ei[] = { -- { -- .data_type = QMI_UNSIGNED_4_BYTE, -- .elem_len = 1, --@@ -632,7 +632,7 @@ static struct qmi_elem_info qmi_wlanfw_m -- }, -- }; -- ---static struct qmi_elem_info qmi_wlanfw_request_mem_ind_msg_v01_ei[] = { --+static const struct qmi_elem_info qmi_wlanfw_request_mem_ind_msg_v01_ei[] = { -- { -- .data_type = QMI_DATA_LEN, -- .elem_len = 1, --@@ -659,7 +659,7 @@ static struct qmi_elem_info qmi_wlanfw_r -- }, -- }; -- ---static struct qmi_elem_info qmi_wlanfw_mem_seg_resp_s_v01_ei[] = { --+static const struct qmi_elem_info qmi_wlanfw_mem_seg_resp_s_v01_ei[] = { -- { -- .data_type = QMI_UNSIGNED_8_BYTE, -- .elem_len = 1, --@@ -699,7 +699,7 @@ static struct qmi_elem_info qmi_wlanfw_m -- }, -- }; -- ---static struct qmi_elem_info qmi_wlanfw_respond_mem_req_msg_v01_ei[] = { --+static const struct qmi_elem_info qmi_wlanfw_respond_mem_req_msg_v01_ei[] = { -- { -- .data_type = QMI_DATA_LEN, -- .elem_len = 1, --@@ -726,7 +726,7 @@ static struct qmi_elem_info qmi_wlanfw_r -- }, -- }; -- ---static struct qmi_elem_info qmi_wlanfw_respond_mem_resp_msg_v01_ei[] = { --+static const struct qmi_elem_info qmi_wlanfw_respond_mem_resp_msg_v01_ei[] = { -- { -- .data_type = QMI_STRUCT, -- .elem_len = 1, --@@ -744,7 +744,7 @@ static struct qmi_elem_info qmi_wlanfw_r -- }, -- }; -- ---static struct qmi_elem_info qmi_wlanfw_cap_req_msg_v01_ei[] = { --+static const struct qmi_elem_info qmi_wlanfw_cap_req_msg_v01_ei[] = { -- { -- .data_type = QMI_EOTI, -- .array_type = NO_ARRAY, --@@ -752,7 +752,7 @@ static struct qmi_elem_info qmi_wlanfw_c -- }, -- }; -- ---static struct qmi_elem_info qmi_wlanfw_device_info_req_msg_v01_ei[] = { --+static const struct qmi_elem_info qmi_wlanfw_device_info_req_msg_v01_ei[] = { -- { -- .data_type = QMI_EOTI, -- .array_type = NO_ARRAY, --@@ -760,7 +760,7 @@ static struct qmi_elem_info qmi_wlanfw_d -- }, -- }; -- ---static struct qmi_elem_info qmi_wlfw_device_info_resp_msg_v01_ei[] = { --+static const struct qmi_elem_info qmi_wlfw_device_info_resp_msg_v01_ei[] = { -- { -- .data_type = QMI_STRUCT, -- .elem_len = 1, --@@ -814,7 +814,7 @@ static struct qmi_elem_info qmi_wlfw_dev -- }, -- }; -- ---static struct qmi_elem_info qmi_wlanfw_rf_chip_info_s_v01_ei[] = { --+static const struct qmi_elem_info qmi_wlanfw_rf_chip_info_s_v01_ei[] = { -- { -- .data_type = QMI_UNSIGNED_4_BYTE, -- .elem_len = 1, --@@ -840,7 +840,7 @@ static struct qmi_elem_info qmi_wlanfw_r -- }, -- }; -- ---static struct qmi_elem_info qmi_wlanfw_rf_board_info_s_v01_ei[] = { --+static const struct qmi_elem_info qmi_wlanfw_rf_board_info_s_v01_ei[] = { -- { -- .data_type = QMI_UNSIGNED_4_BYTE, -- .elem_len = 1, --@@ -857,7 +857,7 @@ static struct qmi_elem_info qmi_wlanfw_r -- }, -- }; -- ---static struct qmi_elem_info qmi_wlanfw_soc_info_s_v01_ei[] = { --+static const struct qmi_elem_info qmi_wlanfw_soc_info_s_v01_ei[] = { -- { -- .data_type = QMI_UNSIGNED_4_BYTE, -- .elem_len = 1, --@@ -873,7 +873,7 @@ static struct qmi_elem_info qmi_wlanfw_s -- }, -- }; -- ---static struct qmi_elem_info qmi_wlanfw_fw_version_info_s_v01_ei[] = { --+static const struct qmi_elem_info qmi_wlanfw_fw_version_info_s_v01_ei[] = { -- { -- .data_type = QMI_UNSIGNED_4_BYTE, -- .elem_len = 1, --@@ -899,7 +899,7 @@ static struct qmi_elem_info qmi_wlanfw_f -- }, -- }; -- ---static struct qmi_elem_info qmi_wlanfw_cap_resp_msg_v01_ei[] = { --+static const struct qmi_elem_info qmi_wlanfw_cap_resp_msg_v01_ei[] = { -- { -- .data_type = QMI_STRUCT, -- .elem_len = 1, --@@ -1100,7 +1100,7 @@ static struct qmi_elem_info qmi_wlanfw_c -- }, -- }; -- ---static struct qmi_elem_info qmi_wlanfw_bdf_download_req_msg_v01_ei[] = { --+static const struct qmi_elem_info qmi_wlanfw_bdf_download_req_msg_v01_ei[] = { -- { -- .data_type = QMI_UNSIGNED_1_BYTE, -- .elem_len = 1, --@@ -1235,7 +1235,7 @@ static struct qmi_elem_info qmi_wlanfw_b -- }, -- }; -- ---static struct qmi_elem_info qmi_wlanfw_bdf_download_resp_msg_v01_ei[] = { --+static const struct qmi_elem_info qmi_wlanfw_bdf_download_resp_msg_v01_ei[] = { -- { -- .data_type = QMI_STRUCT, -- .elem_len = 1, --@@ -1253,7 +1253,7 @@ static struct qmi_elem_info qmi_wlanfw_b -- }, -- }; -- ---static struct qmi_elem_info qmi_wlanfw_m3_info_req_msg_v01_ei[] = { --+static const struct qmi_elem_info qmi_wlanfw_m3_info_req_msg_v01_ei[] = { -- { -- .data_type = QMI_UNSIGNED_8_BYTE, -- .elem_len = 1, --@@ -1277,7 +1277,7 @@ static struct qmi_elem_info qmi_wlanfw_m -- }, -- }; -- ---static struct qmi_elem_info qmi_wlanfw_m3_info_resp_msg_v01_ei[] = { --+static const struct qmi_elem_info qmi_wlanfw_m3_info_resp_msg_v01_ei[] = { -- { -- .data_type = QMI_STRUCT, -- .elem_len = 1, --@@ -1294,7 +1294,7 @@ static struct qmi_elem_info qmi_wlanfw_m -- }, -- }; -- ---static struct qmi_elem_info qmi_wlanfw_ce_tgt_pipe_cfg_s_v01_ei[] = { --+static const struct qmi_elem_info qmi_wlanfw_ce_tgt_pipe_cfg_s_v01_ei[] = { -- { -- .data_type = QMI_UNSIGNED_4_BYTE, -- .elem_len = 1, --@@ -1347,7 +1347,7 @@ static struct qmi_elem_info qmi_wlanfw_c -- }, -- }; -- ---static struct qmi_elem_info qmi_wlanfw_ce_svc_pipe_cfg_s_v01_ei[] = { --+static const struct qmi_elem_info qmi_wlanfw_ce_svc_pipe_cfg_s_v01_ei[] = { -- { -- .data_type = QMI_UNSIGNED_4_BYTE, -- .elem_len = 1, --@@ -1382,7 +1382,7 @@ static struct qmi_elem_info qmi_wlanfw_c -- }, -- }; -- ---static struct qmi_elem_info qmi_wlanfw_shadow_reg_cfg_s_v01_ei[] = { --+static const struct qmi_elem_info qmi_wlanfw_shadow_reg_cfg_s_v01_ei[] = { -- { -- .data_type = QMI_UNSIGNED_2_BYTE, -- .elem_len = 1, --@@ -1406,7 +1406,7 @@ static struct qmi_elem_info qmi_wlanfw_s -- }, -- }; -- ---static struct qmi_elem_info qmi_wlanfw_shadow_reg_v2_cfg_s_v01_ei[] = { --+static const struct qmi_elem_info qmi_wlanfw_shadow_reg_v2_cfg_s_v01_ei[] = { -- { -- .data_type = QMI_UNSIGNED_4_BYTE, -- .elem_len = 1, --@@ -1423,7 +1423,7 @@ static struct qmi_elem_info qmi_wlanfw_s -- }, -- }; -- ---static struct qmi_elem_info qmi_wlanfw_wlan_mode_req_msg_v01_ei[] = { --+static const struct qmi_elem_info qmi_wlanfw_wlan_mode_req_msg_v01_ei[] = { -- { -- .data_type = QMI_UNSIGNED_4_BYTE, -- .elem_len = 1, --@@ -1458,7 +1458,7 @@ static struct qmi_elem_info qmi_wlanfw_w -- }, -- }; -- ---static struct qmi_elem_info qmi_wlanfw_wlan_mode_resp_msg_v01_ei[] = { --+static const struct qmi_elem_info qmi_wlanfw_wlan_mode_resp_msg_v01_ei[] = { -- { -- .data_type = QMI_STRUCT, -- .elem_len = 1, --@@ -1476,7 +1476,7 @@ static struct qmi_elem_info qmi_wlanfw_w -- }, -- }; -- ---static struct qmi_elem_info qmi_wlanfw_wlan_cfg_req_msg_v01_ei[] = { --+static const struct qmi_elem_info qmi_wlanfw_wlan_cfg_req_msg_v01_ei[] = { -- { -- .data_type = QMI_OPT_FLAG, -- .elem_len = 1, --@@ -1615,7 +1615,7 @@ static struct qmi_elem_info qmi_wlanfw_w -- }, -- }; -- ---static struct qmi_elem_info qmi_wlanfw_wlan_cfg_resp_msg_v01_ei[] = { --+static const struct qmi_elem_info qmi_wlanfw_wlan_cfg_resp_msg_v01_ei[] = { -- { -- .data_type = QMI_STRUCT, -- .elem_len = 1, --@@ -1632,28 +1632,28 @@ static struct qmi_elem_info qmi_wlanfw_w -- }, -- }; -- ---static struct qmi_elem_info qmi_wlanfw_mem_ready_ind_msg_v01_ei[] = { --+static const struct qmi_elem_info qmi_wlanfw_mem_ready_ind_msg_v01_ei[] = { -- { -- .data_type = QMI_EOTI, -- .array_type = NO_ARRAY, -- }, -- }; -- ---static struct qmi_elem_info qmi_wlanfw_fw_ready_ind_msg_v01_ei[] = { --+static const struct qmi_elem_info qmi_wlanfw_fw_ready_ind_msg_v01_ei[] = { -- { -- .data_type = QMI_EOTI, -- .array_type = NO_ARRAY, -- }, -- }; -- ---static struct qmi_elem_info qmi_wlanfw_cold_boot_cal_done_ind_msg_v01_ei[] = { --+static const struct qmi_elem_info qmi_wlanfw_cold_boot_cal_done_ind_msg_v01_ei[] = { -- { -- .data_type = QMI_EOTI, -- .array_type = NO_ARRAY, -- }, -- }; -- ---static struct qmi_elem_info qmi_wlanfw_wlan_ini_req_msg_v01_ei[] = { --+static const struct qmi_elem_info qmi_wlanfw_wlan_ini_req_msg_v01_ei[] = { -- { -- .data_type = QMI_OPT_FLAG, -- .elem_len = 1, --@@ -1679,7 +1679,7 @@ static struct qmi_elem_info qmi_wlanfw_w -- }, -- }; -- ---static struct qmi_elem_info qmi_wlanfw_wlan_ini_resp_msg_v01_ei[] = { --+static const struct qmi_elem_info qmi_wlanfw_wlan_ini_resp_msg_v01_ei[] = { -- { -- .data_type = QMI_STRUCT, -- .elem_len = 1, --@@ -1697,7 +1697,7 @@ static struct qmi_elem_info qmi_wlanfw_w -- }, -- }; -- ---static struct qmi_elem_info qmi_wlfw_fw_init_done_ind_msg_v01_ei[] = { --+static const struct qmi_elem_info qmi_wlfw_fw_init_done_ind_msg_v01_ei[] = { -- { -- .data_type = QMI_EOTI, -- .array_type = NO_ARRAY, -diff --git a/package/kernel/mac80211/patches/ath11k/0017-wifi-ath11k-Trigger-sta-disconnect-on-hardware-resta.patch b/package/kernel/mac80211/patches/ath11k/0017-wifi-ath11k-Trigger-sta-disconnect-on-hardware-resta.patch -deleted file mode 100644 -index f95e5027b2..0000000000 ---- a/package/kernel/mac80211/patches/ath11k/0017-wifi-ath11k-Trigger-sta-disconnect-on-hardware-resta.patch -+++ /dev/null -@@ -1,119 +0,0 @@ --From a018750a2cceaf4427c4ee3d9ce3e83a171d5bd6 Mon Sep 17 00:00:00 2001 --From: Youghandhar Chintala --Date: Fri, 4 Nov 2022 14:24:03 +0530 --Subject: [PATCH] wifi: ath11k: Trigger sta disconnect on hardware restart -- --Currently after the hardware restart triggered from the driver, the --station interface connection remains intact, since a disconnect trigger --is not sent to userspace. This can lead to a problem in targets where --the wifi mac sequence is added by the firmware. -- --After the target restart, its wifi mac sequence number gets reset to --zero. Hence AP to which our device is connected will receive frames with --a wifi mac sequence number jump to the past, thereby resulting in the --AP dropping all these frames, until the frame arrives with a wifi mac --sequence number which AP was expecting. -- --To avoid such frame drops, its better to trigger a station disconnect --upon target hardware restart which can be done with API --ieee80211_reconfig_disconnect exposed to mac80211. -- --The other targets are not affected by this change, since the hardware --params flag is not set. -- --Reported-by: kernel test robot -- --Tested-on: WCN6750 hw1.0 AHB WLAN.MSL.1.0.1-00887-QCAMSLSWPLZ-1 -- --Signed-off-by: Youghandhar Chintala --Signed-off-by: Kalle Valo --Link: https://lore.kernel.org/r/20221104085403.11025-1-quic_youghand@quicinc.com ----- -- drivers/net/wireless/ath/ath11k/core.c | 6 ++++++ -- drivers/net/wireless/ath/ath11k/hw.h | 1 + -- drivers/net/wireless/ath/ath11k/mac.c | 7 +++++++ -- 3 files changed, 14 insertions(+) -- ----- a/drivers/net/wireless/ath/ath11k/core.c --+++ b/drivers/net/wireless/ath/ath11k/core.c --@@ -195,6 +195,7 @@ static const struct ath11k_hw_params ath -- .tcl_ring_retry = true, -- .tx_ring_size = DP_TCL_DATA_RING_SIZE, -- .smp2p_wow_exit = false, --+ .support_fw_mac_sequence = false, -- }, -- { -- .name = "qca6390 hw2.0", --@@ -277,6 +278,7 @@ static const struct ath11k_hw_params ath -- .tcl_ring_retry = true, -- .tx_ring_size = DP_TCL_DATA_RING_SIZE, -- .smp2p_wow_exit = false, --+ .support_fw_mac_sequence = true, -- }, -- { -- .name = "qcn9074 hw1.0", --@@ -356,6 +358,7 @@ static const struct ath11k_hw_params ath -- .tcl_ring_retry = true, -- .tx_ring_size = DP_TCL_DATA_RING_SIZE, -- .smp2p_wow_exit = false, --+ .support_fw_mac_sequence = false, -- }, -- { -- .name = "wcn6855 hw2.0", --@@ -438,6 +441,7 @@ static const struct ath11k_hw_params ath -- .tcl_ring_retry = true, -- .tx_ring_size = DP_TCL_DATA_RING_SIZE, -- .smp2p_wow_exit = false, --+ .support_fw_mac_sequence = true, -- }, -- { -- .name = "wcn6855 hw2.1", --@@ -519,6 +523,7 @@ static const struct ath11k_hw_params ath -- .tcl_ring_retry = true, -- .tx_ring_size = DP_TCL_DATA_RING_SIZE, -- .smp2p_wow_exit = false, --+ .support_fw_mac_sequence = true, -- }, -- { -- .name = "wcn6750 hw1.0", --@@ -597,6 +602,7 @@ static const struct ath11k_hw_params ath -- .tcl_ring_retry = false, -- .tx_ring_size = DP_TCL_DATA_RING_SIZE_WCN6750, -- .smp2p_wow_exit = true, --+ .support_fw_mac_sequence = true, -- }, -- }; -- ----- a/drivers/net/wireless/ath/ath11k/hw.h --+++ b/drivers/net/wireless/ath/ath11k/hw.h --@@ -219,6 +219,7 @@ struct ath11k_hw_params { -- bool tcl_ring_retry; -- u32 tx_ring_size; -- bool smp2p_wow_exit; --+ bool support_fw_mac_sequence; -- }; -- -- struct ath11k_hw_ops { ----- a/drivers/net/wireless/ath/ath11k/mac.c --+++ b/drivers/net/wireless/ath/ath11k/mac.c --@@ -8010,6 +8010,7 @@ ath11k_mac_op_reconfig_complete(struct i -- struct ath11k *ar = hw->priv; -- struct ath11k_base *ab = ar->ab; -- int recovery_count; --+ struct ath11k_vif *arvif; -- -- if (reconfig_type != IEEE80211_RECONFIG_TYPE_RESTART) -- return; --@@ -8045,6 +8046,12 @@ ath11k_mac_op_reconfig_complete(struct i -- ath11k_dbg(ab, ATH11K_DBG_BOOT, "reset success\n"); -- } -- } --+ if (ar->ab->hw_params.support_fw_mac_sequence) { --+ list_for_each_entry(arvif, &ar->arvifs, list) { --+ if (arvif->is_up && arvif->vdev_type == WMI_VDEV_TYPE_STA) --+ ieee80211_hw_restart_disconnect(arvif->vif); --+ } --+ } -- } -- -- mutex_unlock(&ar->conf_mutex); -diff --git a/package/kernel/mac80211/patches/ath11k/0018-wifi-ath11k-Fix-race-condition-with-struct-htt_ppdu_.patch b/package/kernel/mac80211/patches/ath11k/0018-wifi-ath11k-Fix-race-condition-with-struct-htt_ppdu_.patch -deleted file mode 100644 -index cef61ee344..0000000000 ---- a/package/kernel/mac80211/patches/ath11k/0018-wifi-ath11k-Fix-race-condition-with-struct-htt_ppdu_.patch -+++ /dev/null -@@ -1,103 +0,0 @@ --From e44de90453bb2b46a523df78c39eb896bab35dcd Mon Sep 17 00:00:00 2001 --From: Govindaraj Saminathan --Date: Tue, 29 Nov 2022 13:04:02 +0200 --Subject: [PATCH] wifi: ath11k: Fix race condition with struct -- htt_ppdu_stats_info -- --A crash happens when running the traffic with multiple clients: -- --Crash Signature : Unable to handle kernel paging request at --virtual address ffffffd700970918 During the crash, PC points to --"ieee80211_tx_rate_update+0x30/0x68 [mac80211]" --LR points to "ath11k_dp_htt_htc_t2h_msg_handler+0x5a8/0x8a0 [ath11k]". -- --Struct ppdu_stats_info is allocated and accessed from event callback via copy --engine tasklet, this has a problem when freeing it from ath11k_mac_op_stop(). -- --Use data_lock during entire ath11k_dp_htt_get_ppdu_desc() call to protect --struct htt_ppdu_stats_info access and to avoid race condition when accessing it --from ath11k_mac_op_stop(). -- --Tested-on: IPQ8074 hw2.0 AHB WLAN.HK.2.7.0.1-01744-QCAHKSWPL_SILICONZ-1 -- --Signed-off-by: Govindaraj Saminathan --Co-developed-by: Karthikeyan Kathirvel --Signed-off-by: Karthikeyan Kathirvel --Signed-off-by: Kalle Valo --Link: https://lore.kernel.org/r/20221124071104.22506-1-quic_kathirve@quicinc.com ----- -- drivers/net/wireless/ath/ath11k/dp_rx.c | 22 +++++++++++----------- -- 1 file changed, 11 insertions(+), 11 deletions(-) -- ----- a/drivers/net/wireless/ath/ath11k/dp_rx.c --+++ b/drivers/net/wireless/ath/ath11k/dp_rx.c --@@ -1535,13 +1535,12 @@ struct htt_ppdu_stats_info *ath11k_dp_ht -- { -- struct htt_ppdu_stats_info *ppdu_info; -- --- spin_lock_bh(&ar->data_lock); --+ lockdep_assert_held(&ar->data_lock); --+ -- if (!list_empty(&ar->ppdu_stats_info)) { -- list_for_each_entry(ppdu_info, &ar->ppdu_stats_info, list) { --- if (ppdu_info->ppdu_id == ppdu_id) { --- spin_unlock_bh(&ar->data_lock); --+ if (ppdu_info->ppdu_id == ppdu_id) -- return ppdu_info; --- } -- } -- -- if (ar->ppdu_stat_list_depth > HTT_PPDU_DESC_MAX_DEPTH) { --@@ -1553,16 +1552,13 @@ struct htt_ppdu_stats_info *ath11k_dp_ht -- kfree(ppdu_info); -- } -- } --- spin_unlock_bh(&ar->data_lock); -- -- ppdu_info = kzalloc(sizeof(*ppdu_info), GFP_ATOMIC); -- if (!ppdu_info) -- return NULL; -- --- spin_lock_bh(&ar->data_lock); -- list_add_tail(&ppdu_info->list, &ar->ppdu_stats_info); -- ar->ppdu_stat_list_depth++; --- spin_unlock_bh(&ar->data_lock); -- -- return ppdu_info; -- } --@@ -1586,16 +1582,17 @@ static int ath11k_htt_pull_ppdu_stats(st -- ar = ath11k_mac_get_ar_by_pdev_id(ab, pdev_id); -- if (!ar) { -- ret = -EINVAL; --- goto exit; --+ goto out; -- } -- -- if (ath11k_debugfs_is_pktlog_lite_mode_enabled(ar)) -- trace_ath11k_htt_ppdu_stats(ar, skb->data, len); -- --+ spin_lock_bh(&ar->data_lock); -- ppdu_info = ath11k_dp_htt_get_ppdu_desc(ar, ppdu_id); -- if (!ppdu_info) { -- ret = -EINVAL; --- goto exit; --+ goto out_unlock_data; -- } -- -- ppdu_info->ppdu_id = ppdu_id; --@@ -1604,10 +1601,13 @@ static int ath11k_htt_pull_ppdu_stats(st -- (void *)ppdu_info); -- if (ret) { -- ath11k_warn(ab, "Failed to parse tlv %d\n", ret); --- goto exit; --+ goto out_unlock_data; -- } -- ---exit: --+out_unlock_data: --+ spin_unlock_bh(&ar->data_lock); --+ --+out: -- rcu_read_unlock(); -- -- return ret; -diff --git a/package/kernel/mac80211/patches/ath11k/0019-wifi-ath11k-update-hw-params-for-IPQ5018.patch b/package/kernel/mac80211/patches/ath11k/0019-wifi-ath11k-update-hw-params-for-IPQ5018.patch -deleted file mode 100644 -index 25d39ddb0d..0000000000 ---- a/package/kernel/mac80211/patches/ath11k/0019-wifi-ath11k-update-hw-params-for-IPQ5018.patch -+++ /dev/null -@@ -1,125 +0,0 @@ --From 8dfe875aa24aec68baf6702018633c84c2c1feca Mon Sep 17 00:00:00 2001 --From: Sriram R --Date: Fri, 2 Dec 2022 23:37:13 +0200 --Subject: [PATCH] wifi: ath11k: update hw params for IPQ5018 -- --Add new compatible string for IPQ5018 and add --required hw params for IPQ5018. The hw descriptors size and --datapath ops are similar to QCN9074, hence reuse the same. -- --Tested-on: IPQ5018 hw1.0 AHB WLAN.HK.2.6.0.1-00861-QCAHKSWPL_SILICONZ-1 -- --Signed-off-by: Sriram R --Co-developed-by: Karthikeyan Kathirvel --Signed-off-by: Karthikeyan Kathirvel --Signed-off-by: Kalle Valo --Link: https://lore.kernel.org/r/20221122132152.17771-3-quic_kathirve@quicinc.com ----- -- drivers/net/wireless/ath/ath11k/core.c | 71 ++++++++++++++++++++++++++ -- drivers/net/wireless/ath/ath11k/core.h | 8 +++ -- 2 files changed, 79 insertions(+) -- ----- a/drivers/net/wireless/ath/ath11k/core.c --+++ b/drivers/net/wireless/ath/ath11k/core.c --@@ -604,6 +604,77 @@ static const struct ath11k_hw_params ath -- .smp2p_wow_exit = true, -- .support_fw_mac_sequence = true, -- }, --+ { --+ .hw_rev = ATH11K_HW_IPQ5018_HW10, --+ .name = "ipq5018 hw1.0", --+ .fw = { --+ .dir = "IPQ5018/hw1.0", --+ .board_size = 256 * 1024, --+ .cal_offset = 128 * 1024, --+ }, --+ .max_radios = MAX_RADIOS_5018, --+ .bdf_addr = 0x4BA00000, --+ /* hal_desc_sz and hw ops are similar to qcn9074 */ --+ .hal_desc_sz = sizeof(struct hal_rx_desc_qcn9074), --+ .qmi_service_ins_id = ATH11K_QMI_WLFW_SERVICE_INS_ID_V01_IPQ8074, --+ .ring_mask = &ath11k_hw_ring_mask_ipq8074, --+ .credit_flow = false, --+ .max_tx_ring = 1, --+ .spectral = { --+ .fft_sz = 2, --+ .fft_pad_sz = 0, --+ .summary_pad_sz = 16, --+ .fft_hdr_len = 24, --+ .max_fft_bins = 1024, --+ }, --+ .internal_sleep_clock = false, --+ .host_ce_config = ath11k_host_ce_config_qcn9074, --+ .ce_count = CE_CNT_5018, --+ .rxdma1_enable = true, --+ .num_rxmda_per_pdev = RXDMA_PER_PDEV_5018, --+ .rx_mac_buf_ring = false, --+ .vdev_start_delay = false, --+ .htt_peer_map_v2 = true, --+ .interface_modes = BIT(NL80211_IFTYPE_STATION) | --+ BIT(NL80211_IFTYPE_AP) | --+ BIT(NL80211_IFTYPE_MESH_POINT), --+ .supports_monitor = false, --+ .supports_sta_ps = false, --+ .supports_shadow_regs = false, --+ .fw_mem_mode = 0, --+ .num_vdevs = 16 + 1, --+ .num_peers = 512, --+ .supports_regdb = false, --+ .idle_ps = false, --+ .supports_suspend = false, --+ .hal_params = &ath11k_hw_hal_params_ipq8074, --+ .single_pdev_only = false, --+ .cold_boot_calib = true, --+ .fix_l1ss = true, --+ .supports_dynamic_smps_6ghz = false, --+ .alloc_cacheable_memory = true, --+ .supports_rssi_stats = false, --+ .fw_wmi_diag_event = false, --+ .current_cc_support = false, --+ .dbr_debug_support = true, --+ .global_reset = false, --+ .bios_sar_capa = NULL, --+ .m3_fw_support = false, --+ .fixed_bdf_addr = true, --+ .fixed_mem_region = true, --+ .static_window_map = false, --+ .hybrid_bus_type = false, --+ .fixed_fw_mem = false, --+ .support_off_channel_tx = false, --+ .supports_multi_bssid = false, --+ --+ .sram_dump = {}, --+ --+ .tcl_ring_retry = true, --+ .tx_ring_size = DP_TCL_DATA_RING_SIZE, --+ .smp2p_wow_exit = false, --+ .support_fw_mac_sequence = false, --+ }, -- }; -- -- static inline struct ath11k_pdev *ath11k_core_get_single_pdev(struct ath11k_base *ab) ----- a/drivers/net/wireless/ath/ath11k/core.h --+++ b/drivers/net/wireless/ath/ath11k/core.h --@@ -142,6 +142,7 @@ enum ath11k_hw_rev { -- ATH11K_HW_WCN6855_HW20, -- ATH11K_HW_WCN6855_HW21, -- ATH11K_HW_WCN6750_HW10, --+ ATH11K_HW_IPQ5018_HW10, -- }; -- -- enum ath11k_firmware_mode { --@@ -230,6 +231,13 @@ struct ath11k_he { -- -- #define MAX_RADIOS 3 -- --+/* ipq5018 hw param macros */ --+#define MAX_RADIOS_5018 1 --+#define CE_CNT_5018 6 --+#define TARGET_CE_CNT_5018 9 --+#define SVC_CE_MAP_LEN_5018 17 --+#define RXDMA_PER_PDEV_5018 1 --+ -- enum { -- WMI_HOST_TP_SCALE_MAX = 0, -- WMI_HOST_TP_SCALE_50 = 1, -diff --git a/package/kernel/mac80211/patches/ath11k/0020-wifi-ath11k-update-ce-configurations-for-IPQ5018.patch b/package/kernel/mac80211/patches/ath11k/0020-wifi-ath11k-update-ce-configurations-for-IPQ5018.patch -deleted file mode 100644 -index 95643a95fe..0000000000 ---- a/package/kernel/mac80211/patches/ath11k/0020-wifi-ath11k-update-ce-configurations-for-IPQ5018.patch -+++ /dev/null -@@ -1,246 +0,0 @@ --From 26af7aabd2d8225c6b2056234626ba5099610871 Mon Sep 17 00:00:00 2001 --From: Sriram R --Date: Fri, 2 Dec 2022 23:37:14 +0200 --Subject: [PATCH] wifi: ath11k: update ce configurations for IPQ5018 -- --IPQ5018 is a single pdev device. Update host --and target CE configurations accordingly. -- --Tested-on: IPQ5018 hw1.0 AHB WLAN.HK.2.6.0.1-00861-QCAHKSWPL_SILICONZ-1 -- --Signed-off-by: Sriram R --Co-developed-by: Karthikeyan Kathirvel --Signed-off-by: Karthikeyan Kathirvel --Signed-off-by: Kalle Valo --Link: https://lore.kernel.org/r/20221122132152.17771-4-quic_kathirve@quicinc.com ----- -- drivers/net/wireless/ath/ath11k/core.c | 4 + -- drivers/net/wireless/ath/ath11k/core.h | 3 + -- drivers/net/wireless/ath/ath11k/hw.c | 191 +++++++++++++++++++++++++ -- 3 files changed, 198 insertions(+) -- ----- a/drivers/net/wireless/ath/ath11k/core.c --+++ b/drivers/net/wireless/ath/ath11k/core.c --@@ -630,6 +630,10 @@ static const struct ath11k_hw_params ath -- .internal_sleep_clock = false, -- .host_ce_config = ath11k_host_ce_config_qcn9074, -- .ce_count = CE_CNT_5018, --+ .target_ce_config = ath11k_target_ce_config_wlan_ipq5018, --+ .target_ce_count = TARGET_CE_CNT_5018, --+ .svc_to_ce_map = ath11k_target_service_to_ce_map_wlan_ipq5018, --+ .svc_to_ce_map_len = SVC_CE_MAP_LEN_5018, -- .rxdma1_enable = true, -- .num_rxmda_per_pdev = RXDMA_PER_PDEV_5018, -- .rx_mac_buf_ring = false, ----- a/drivers/net/wireless/ath/ath11k/core.h --+++ b/drivers/net/wireless/ath/ath11k/core.h --@@ -1145,6 +1145,9 @@ extern const struct service_to_pipe ath1 -- extern const struct ce_pipe_config ath11k_target_ce_config_wlan_qca6390[]; -- extern const struct service_to_pipe ath11k_target_service_to_ce_map_wlan_qca6390[]; -- --+extern const struct ce_pipe_config ath11k_target_ce_config_wlan_ipq5018[]; --+extern const struct service_to_pipe ath11k_target_service_to_ce_map_wlan_ipq5018[]; --+ -- extern const struct ce_pipe_config ath11k_target_ce_config_wlan_qcn9074[]; -- extern const struct service_to_pipe ath11k_target_service_to_ce_map_wlan_qcn9074[]; -- int ath11k_core_qmi_firmware_ready(struct ath11k_base *ab); ----- a/drivers/net/wireless/ath/ath11k/hw.c --+++ b/drivers/net/wireless/ath/ath11k/hw.c --@@ -1972,6 +1972,197 @@ const struct ath11k_hw_ring_mask ath11k_ -- }, -- }; -- --+/* Target firmware's Copy Engine configuration for IPQ5018 */ --+const struct ce_pipe_config ath11k_target_ce_config_wlan_ipq5018[] = { --+ /* CE0: host->target HTC control and raw streams */ --+ { --+ .pipenum = __cpu_to_le32(0), --+ .pipedir = __cpu_to_le32(PIPEDIR_OUT), --+ .nentries = __cpu_to_le32(32), --+ .nbytes_max = __cpu_to_le32(2048), --+ .flags = __cpu_to_le32(CE_ATTR_FLAGS), --+ .reserved = __cpu_to_le32(0), --+ }, --+ --+ /* CE1: target->host HTT + HTC control */ --+ { --+ .pipenum = __cpu_to_le32(1), --+ .pipedir = __cpu_to_le32(PIPEDIR_IN), --+ .nentries = __cpu_to_le32(32), --+ .nbytes_max = __cpu_to_le32(2048), --+ .flags = __cpu_to_le32(CE_ATTR_FLAGS), --+ .reserved = __cpu_to_le32(0), --+ }, --+ --+ /* CE2: target->host WMI */ --+ { --+ .pipenum = __cpu_to_le32(2), --+ .pipedir = __cpu_to_le32(PIPEDIR_IN), --+ .nentries = __cpu_to_le32(32), --+ .nbytes_max = __cpu_to_le32(2048), --+ .flags = __cpu_to_le32(CE_ATTR_FLAGS), --+ .reserved = __cpu_to_le32(0), --+ }, --+ --+ /* CE3: host->target WMI */ --+ { --+ .pipenum = __cpu_to_le32(3), --+ .pipedir = __cpu_to_le32(PIPEDIR_OUT), --+ .nentries = __cpu_to_le32(32), --+ .nbytes_max = __cpu_to_le32(2048), --+ .flags = __cpu_to_le32(CE_ATTR_FLAGS), --+ .reserved = __cpu_to_le32(0), --+ }, --+ --+ /* CE4: host->target HTT */ --+ { --+ .pipenum = __cpu_to_le32(4), --+ .pipedir = __cpu_to_le32(PIPEDIR_OUT), --+ .nentries = __cpu_to_le32(256), --+ .nbytes_max = __cpu_to_le32(256), --+ .flags = __cpu_to_le32(CE_ATTR_FLAGS | CE_ATTR_DIS_INTR), --+ .reserved = __cpu_to_le32(0), --+ }, --+ --+ /* CE5: target->host Pktlog */ --+ { --+ .pipenum = __cpu_to_le32(5), --+ .pipedir = __cpu_to_le32(PIPEDIR_IN), --+ .nentries = __cpu_to_le32(32), --+ .nbytes_max = __cpu_to_le32(2048), --+ .flags = __cpu_to_le32(CE_ATTR_FLAGS), --+ .reserved = __cpu_to_le32(0), --+ }, --+ --+ /* CE6: Reserved for target autonomous hif_memcpy */ --+ { --+ .pipenum = __cpu_to_le32(6), --+ .pipedir = __cpu_to_le32(PIPEDIR_INOUT), --+ .nentries = __cpu_to_le32(32), --+ .nbytes_max = __cpu_to_le32(16384), --+ .flags = __cpu_to_le32(CE_ATTR_FLAGS), --+ .reserved = __cpu_to_le32(0), --+ }, --+ --+ /* CE7 used only by Host */ --+ { --+ .pipenum = __cpu_to_le32(7), --+ .pipedir = __cpu_to_le32(PIPEDIR_OUT), --+ .nentries = __cpu_to_le32(32), --+ .nbytes_max = __cpu_to_le32(2048), --+ .flags = __cpu_to_le32(0x2000), --+ .reserved = __cpu_to_le32(0), --+ }, --+ --+ /* CE8 target->host used only by IPA */ --+ { --+ .pipenum = __cpu_to_le32(8), --+ .pipedir = __cpu_to_le32(PIPEDIR_INOUT), --+ .nentries = __cpu_to_le32(32), --+ .nbytes_max = __cpu_to_le32(16384), --+ .flags = __cpu_to_le32(CE_ATTR_FLAGS), --+ .reserved = __cpu_to_le32(0), --+ }, --+}; --+ --+/* Map from service/endpoint to Copy Engine for IPQ5018. --+ * This table is derived from the CE TABLE, above. --+ * It is passed to the Target at startup for use by firmware. --+ */ --+const struct service_to_pipe ath11k_target_service_to_ce_map_wlan_ipq5018[] = { --+ { --+ .service_id = __cpu_to_le32(ATH11K_HTC_SVC_ID_WMI_DATA_VO), --+ .pipedir = __cpu_to_le32(PIPEDIR_OUT), /* out = UL = host -> target */ --+ .pipenum = __cpu_to_le32(3), --+ }, --+ { --+ .service_id = __cpu_to_le32(ATH11K_HTC_SVC_ID_WMI_DATA_VO), --+ .pipedir = __cpu_to_le32(PIPEDIR_IN), /* in = DL = target -> host */ --+ .pipenum = __cpu_to_le32(2), --+ }, --+ { --+ .service_id = __cpu_to_le32(ATH11K_HTC_SVC_ID_WMI_DATA_BK), --+ .pipedir = __cpu_to_le32(PIPEDIR_OUT), /* out = UL = host -> target */ --+ .pipenum = __cpu_to_le32(3), --+ }, --+ { --+ .service_id = __cpu_to_le32(ATH11K_HTC_SVC_ID_WMI_DATA_BK), --+ .pipedir = __cpu_to_le32(PIPEDIR_IN), /* in = DL = target -> host */ --+ .pipenum = __cpu_to_le32(2), --+ }, --+ { --+ .service_id = __cpu_to_le32(ATH11K_HTC_SVC_ID_WMI_DATA_BE), --+ .pipedir = __cpu_to_le32(PIPEDIR_OUT), /* out = UL = host -> target */ --+ .pipenum = __cpu_to_le32(3), --+ }, --+ { --+ .service_id = __cpu_to_le32(ATH11K_HTC_SVC_ID_WMI_DATA_BE), --+ .pipedir = __cpu_to_le32(PIPEDIR_IN), /* in = DL = target -> host */ --+ .pipenum = __cpu_to_le32(2), --+ }, --+ { --+ .service_id = __cpu_to_le32(ATH11K_HTC_SVC_ID_WMI_DATA_VI), --+ .pipedir = __cpu_to_le32(PIPEDIR_OUT), /* out = UL = host -> target */ --+ .pipenum = __cpu_to_le32(3), --+ }, --+ { --+ .service_id = __cpu_to_le32(ATH11K_HTC_SVC_ID_WMI_DATA_VI), --+ .pipedir = __cpu_to_le32(PIPEDIR_IN), /* in = DL = target -> host */ --+ .pipenum = __cpu_to_le32(2), --+ }, --+ { --+ .service_id = __cpu_to_le32(ATH11K_HTC_SVC_ID_WMI_CONTROL), --+ .pipedir = __cpu_to_le32(PIPEDIR_OUT), /* out = UL = host -> target */ --+ .pipenum = __cpu_to_le32(3), --+ }, --+ { --+ .service_id = __cpu_to_le32(ATH11K_HTC_SVC_ID_WMI_CONTROL), --+ .pipedir = __cpu_to_le32(PIPEDIR_IN), /* in = DL = target -> host */ --+ .pipenum = __cpu_to_le32(2), --+ }, --+ --+ { --+ .service_id = __cpu_to_le32(ATH11K_HTC_SVC_ID_RSVD_CTRL), --+ .pipedir = __cpu_to_le32(PIPEDIR_OUT), /* out = UL = host -> target */ --+ .pipenum = __cpu_to_le32(0), --+ }, --+ { --+ .service_id = __cpu_to_le32(ATH11K_HTC_SVC_ID_RSVD_CTRL), --+ .pipedir = __cpu_to_le32(PIPEDIR_IN), /* in = DL = target -> host */ --+ .pipenum = __cpu_to_le32(1), --+ }, --+ --+ { --+ .service_id = __cpu_to_le32(ATH11K_HTC_SVC_ID_TEST_RAW_STREAMS), --+ .pipedir = __cpu_to_le32(PIPEDIR_OUT), /* out = UL = host -> target */ --+ .pipenum = __cpu_to_le32(0), --+ }, --+ { --+ .service_id = __cpu_to_le32(ATH11K_HTC_SVC_ID_TEST_RAW_STREAMS), --+ .pipedir = __cpu_to_le32(PIPEDIR_IN), /* in = DL = target -> host */ --+ .pipenum = __cpu_to_le32(1), --+ }, --+ { --+ .service_id = __cpu_to_le32(ATH11K_HTC_SVC_ID_HTT_DATA_MSG), --+ .pipedir = __cpu_to_le32(PIPEDIR_OUT), /* out = UL = host -> target */ --+ .pipenum = __cpu_to_le32(4), --+ }, --+ { --+ .service_id = __cpu_to_le32(ATH11K_HTC_SVC_ID_HTT_DATA_MSG), --+ .pipedir = __cpu_to_le32(PIPEDIR_IN), /* in = DL = target -> host */ --+ .pipenum = __cpu_to_le32(1), --+ }, --+ { --+ .service_id = __cpu_to_le32(ATH11K_HTC_SVC_ID_PKT_LOG), --+ .pipedir = __cpu_to_le32(PIPEDIR_IN), /* in = DL = target -> host */ --+ .pipenum = __cpu_to_le32(5), --+ }, --+ --+ /* (Additions here) */ --+ --+ { /* terminator entry */ } --+}; --+ -- const struct ath11k_hw_regs ipq8074_regs = { -- /* SW2TCL(x) R0 ring configuration address */ -- .hal_tcl1_ring_base_lsb = 0x00000510, -diff --git a/package/kernel/mac80211/patches/ath11k/0021-wifi-ath11k-remap-ce-register-space-for-IPQ5018.patch b/package/kernel/mac80211/patches/ath11k/0021-wifi-ath11k-remap-ce-register-space-for-IPQ5018.patch -deleted file mode 100644 -index d07a258ac2..0000000000 ---- a/package/kernel/mac80211/patches/ath11k/0021-wifi-ath11k-remap-ce-register-space-for-IPQ5018.patch -+++ /dev/null -@@ -1,351 +0,0 @@ --From b42b3678c91f3ca6e0888bf5a15c1e8678fd5f2d Mon Sep 17 00:00:00 2001 --From: Sriram R --Date: Fri, 2 Dec 2022 23:37:14 +0200 --Subject: [PATCH] wifi: ath11k: remap ce register space for IPQ5018 -- --In IPQ5018 ce register space is moved out of wcss unlike --ipq8074 or ipq6018 and the space is not contiguous, --hence remap the CE registers to a new space to access them. -- --Register read/write is modified to check if the register to be written --falls in the CE register space and corresponding register is written. --Also adjust the interrupt register address to ce irq enable/disable. -- --Tested-on: IPQ5018 hw1.0 AHB WLAN.HK.2.6.0.1-00861-QCAHKSWPL_SILICONZ-1 -- --Signed-off-by: Sriram R --Co-developed-by: Karthikeyan Kathirvel --Signed-off-by: Karthikeyan Kathirvel --Signed-off-by: Kalle Valo --Link: https://lore.kernel.org/r/20221122132152.17771-5-quic_kathirve@quicinc.com ----- -- drivers/net/wireless/ath/ath11k/ahb.c | 44 ++++++++++++++++++++++---- -- drivers/net/wireless/ath/ath11k/ce.h | 16 ++++++++++ -- drivers/net/wireless/ath/ath11k/core.c | 8 +++++ -- drivers/net/wireless/ath/ath11k/core.h | 1 + -- drivers/net/wireless/ath/ath11k/hal.c | 17 ++++++---- -- drivers/net/wireless/ath/ath11k/hal.h | 5 +++ -- drivers/net/wireless/ath/ath11k/hw.c | 17 ++++++++++ -- drivers/net/wireless/ath/ath11k/hw.h | 9 ++++++ -- drivers/net/wireless/ath/ath11k/pci.c | 2 ++ -- 9 files changed, 107 insertions(+), 12 deletions(-) -- ----- a/drivers/net/wireless/ath/ath11k/ahb.c --+++ b/drivers/net/wireless/ath/ath11k/ahb.c --@@ -267,30 +267,42 @@ static void ath11k_ahb_clearbit32(struct -- static void ath11k_ahb_ce_irq_enable(struct ath11k_base *ab, u16 ce_id) -- { -- const struct ce_attr *ce_attr; --+ const struct ce_ie_addr *ce_ie_addr = ab->hw_params.ce_ie_addr; --+ u32 ie1_reg_addr, ie2_reg_addr, ie3_reg_addr; --+ --+ ie1_reg_addr = ce_ie_addr->ie1_reg_addr + ATH11K_CE_OFFSET(ab); --+ ie2_reg_addr = ce_ie_addr->ie2_reg_addr + ATH11K_CE_OFFSET(ab); --+ ie3_reg_addr = ce_ie_addr->ie3_reg_addr + ATH11K_CE_OFFSET(ab); -- -- ce_attr = &ab->hw_params.host_ce_config[ce_id]; -- if (ce_attr->src_nentries) --- ath11k_ahb_setbit32(ab, ce_id, CE_HOST_IE_ADDRESS); --+ ath11k_ahb_setbit32(ab, ce_id, ie1_reg_addr); -- -- if (ce_attr->dest_nentries) { --- ath11k_ahb_setbit32(ab, ce_id, CE_HOST_IE_2_ADDRESS); --+ ath11k_ahb_setbit32(ab, ce_id, ie2_reg_addr); -- ath11k_ahb_setbit32(ab, ce_id + CE_HOST_IE_3_SHIFT, --- CE_HOST_IE_3_ADDRESS); --+ ie3_reg_addr); -- } -- } -- -- static void ath11k_ahb_ce_irq_disable(struct ath11k_base *ab, u16 ce_id) -- { -- const struct ce_attr *ce_attr; --+ const struct ce_ie_addr *ce_ie_addr = ab->hw_params.ce_ie_addr; --+ u32 ie1_reg_addr, ie2_reg_addr, ie3_reg_addr; --+ --+ ie1_reg_addr = ce_ie_addr->ie1_reg_addr + ATH11K_CE_OFFSET(ab); --+ ie2_reg_addr = ce_ie_addr->ie2_reg_addr + ATH11K_CE_OFFSET(ab); --+ ie3_reg_addr = ce_ie_addr->ie3_reg_addr + ATH11K_CE_OFFSET(ab); -- -- ce_attr = &ab->hw_params.host_ce_config[ce_id]; -- if (ce_attr->src_nentries) --- ath11k_ahb_clearbit32(ab, ce_id, CE_HOST_IE_ADDRESS); --+ ath11k_ahb_clearbit32(ab, ce_id, ie1_reg_addr); -- -- if (ce_attr->dest_nentries) { --- ath11k_ahb_clearbit32(ab, ce_id, CE_HOST_IE_2_ADDRESS); --+ ath11k_ahb_clearbit32(ab, ce_id, ie2_reg_addr); -- ath11k_ahb_clearbit32(ab, ce_id + CE_HOST_IE_3_SHIFT, --- CE_HOST_IE_3_ADDRESS); --+ ie3_reg_addr); -- } -- } -- --@@ -1142,10 +1154,26 @@ static int ath11k_ahb_probe(struct platf -- goto err_core_free; -- } -- --+ ab->mem_ce = ab->mem; --+ -- ret = ath11k_core_pre_init(ab); -- if (ret) -- goto err_core_free; -- --+ if (ab->hw_params.ce_remap) { --+ const struct ce_remap *ce_remap = ab->hw_params.ce_remap; --+ /* ce register space is moved out of wcss unlike ipq8074 or ipq6018 --+ * and the space is not contiguous, hence remapping the CE registers --+ * to a new space for accessing them. --+ */ --+ ab->mem_ce = ioremap(ce_remap->base, ce_remap->size); --+ if (IS_ERR(ab->mem_ce)) { --+ dev_err(&pdev->dev, "ce ioremap error\n"); --+ ret = -ENOMEM; --+ goto err_core_free; --+ } --+ } --+ -- ret = ath11k_ahb_setup_resources(ab); -- if (ret) -- goto err_core_free; --@@ -1236,6 +1264,10 @@ static void ath11k_ahb_free_resources(st -- ath11k_ahb_release_smp2p_handle(ab); -- ath11k_ahb_fw_resource_deinit(ab); -- ath11k_ce_free_pipes(ab); --+ --+ if (ab->hw_params.ce_remap) --+ iounmap(ab->mem_ce); --+ -- ath11k_core_free(ab); -- platform_set_drvdata(pdev, NULL); -- } ----- a/drivers/net/wireless/ath/ath11k/ce.h --+++ b/drivers/net/wireless/ath/ath11k/ce.h --@@ -49,6 +49,11 @@ void ath11k_ce_byte_swap(void *mem, u32 -- #define CE_HOST_IE_2_ADDRESS 0x00A18040 -- #define CE_HOST_IE_3_ADDRESS CE_HOST_IE_ADDRESS -- --+/* CE IE registers are different for IPQ5018 */ --+#define CE_HOST_IPQ5018_IE_ADDRESS 0x0841804C --+#define CE_HOST_IPQ5018_IE_2_ADDRESS 0x08418050 --+#define CE_HOST_IPQ5018_IE_3_ADDRESS CE_HOST_IPQ5018_IE_ADDRESS --+ -- #define CE_HOST_IE_3_SHIFT 0xC -- -- #define CE_RING_IDX_INCR(nentries_mask, idx) (((idx) + 1) & (nentries_mask)) --@@ -84,6 +89,17 @@ struct ce_pipe_config { -- __le32 reserved; -- }; -- --+struct ce_ie_addr { --+ u32 ie1_reg_addr; --+ u32 ie2_reg_addr; --+ u32 ie3_reg_addr; --+}; --+ --+struct ce_remap { --+ u32 base; --+ u32 size; --+}; --+ -- struct ce_attr { -- /* CE_ATTR_* values */ -- unsigned int flags; ----- a/drivers/net/wireless/ath/ath11k/core.c --+++ b/drivers/net/wireless/ath/ath11k/core.c --@@ -54,6 +54,7 @@ static const struct ath11k_hw_params ath -- .target_ce_count = 11, -- .svc_to_ce_map = ath11k_target_service_to_ce_map_wlan_ipq8074, -- .svc_to_ce_map_len = 21, --+ .ce_ie_addr = &ath11k_ce_ie_addr_ipq8074, -- .single_pdev_only = false, -- .rxdma1_enable = true, -- .num_rxmda_per_pdev = 1, --@@ -137,6 +138,7 @@ static const struct ath11k_hw_params ath -- .target_ce_count = 11, -- .svc_to_ce_map = ath11k_target_service_to_ce_map_wlan_ipq6018, -- .svc_to_ce_map_len = 19, --+ .ce_ie_addr = &ath11k_ce_ie_addr_ipq8074, -- .single_pdev_only = false, -- .rxdma1_enable = true, -- .num_rxmda_per_pdev = 1, --@@ -218,6 +220,7 @@ static const struct ath11k_hw_params ath -- .target_ce_count = 9, -- .svc_to_ce_map = ath11k_target_service_to_ce_map_wlan_qca6390, -- .svc_to_ce_map_len = 14, --+ .ce_ie_addr = &ath11k_ce_ie_addr_ipq8074, -- .single_pdev_only = true, -- .rxdma1_enable = false, -- .num_rxmda_per_pdev = 2, --@@ -301,6 +304,7 @@ static const struct ath11k_hw_params ath -- .target_ce_count = 9, -- .svc_to_ce_map = ath11k_target_service_to_ce_map_wlan_qcn9074, -- .svc_to_ce_map_len = 18, --+ .ce_ie_addr = &ath11k_ce_ie_addr_ipq8074, -- .rxdma1_enable = true, -- .num_rxmda_per_pdev = 1, -- .rx_mac_buf_ring = false, --@@ -381,6 +385,7 @@ static const struct ath11k_hw_params ath -- .target_ce_count = 9, -- .svc_to_ce_map = ath11k_target_service_to_ce_map_wlan_qca6390, -- .svc_to_ce_map_len = 14, --+ .ce_ie_addr = &ath11k_ce_ie_addr_ipq8074, -- .single_pdev_only = true, -- .rxdma1_enable = false, -- .num_rxmda_per_pdev = 2, --@@ -546,6 +551,7 @@ static const struct ath11k_hw_params ath -- .target_ce_count = 9, -- .svc_to_ce_map = ath11k_target_service_to_ce_map_wlan_qca6390, -- .svc_to_ce_map_len = 14, --+ .ce_ie_addr = &ath11k_ce_ie_addr_ipq8074, -- .single_pdev_only = true, -- .rxdma1_enable = false, -- .num_rxmda_per_pdev = 1, --@@ -634,6 +640,8 @@ static const struct ath11k_hw_params ath -- .target_ce_count = TARGET_CE_CNT_5018, -- .svc_to_ce_map = ath11k_target_service_to_ce_map_wlan_ipq5018, -- .svc_to_ce_map_len = SVC_CE_MAP_LEN_5018, --+ .ce_ie_addr = &ath11k_ce_ie_addr_ipq5018, --+ .ce_remap = &ath11k_ce_remap_ipq5018, -- .rxdma1_enable = true, -- .num_rxmda_per_pdev = RXDMA_PER_PDEV_5018, -- .rx_mac_buf_ring = false, ----- a/drivers/net/wireless/ath/ath11k/core.h --+++ b/drivers/net/wireless/ath/ath11k/core.h --@@ -851,6 +851,7 @@ struct ath11k_base { -- struct ath11k_dp dp; -- -- void __iomem *mem; --+ void __iomem *mem_ce; -- unsigned long mem_len; -- -- struct { ----- a/drivers/net/wireless/ath/ath11k/hal.c --+++ b/drivers/net/wireless/ath/ath11k/hal.c --@@ -1220,16 +1220,20 @@ static int ath11k_hal_srng_create_config -- s->reg_start[1] = HAL_SEQ_WCSS_UMAC_TCL_REG + HAL_TCL_STATUS_RING_HP; -- -- s = &hal->srng_config[HAL_CE_SRC]; --- s->reg_start[0] = HAL_SEQ_WCSS_UMAC_CE0_SRC_REG(ab) + HAL_CE_DST_RING_BASE_LSB; --- s->reg_start[1] = HAL_SEQ_WCSS_UMAC_CE0_SRC_REG(ab) + HAL_CE_DST_RING_HP; --+ s->reg_start[0] = HAL_SEQ_WCSS_UMAC_CE0_SRC_REG(ab) + HAL_CE_DST_RING_BASE_LSB + --+ ATH11K_CE_OFFSET(ab); --+ s->reg_start[1] = HAL_SEQ_WCSS_UMAC_CE0_SRC_REG(ab) + HAL_CE_DST_RING_HP + --+ ATH11K_CE_OFFSET(ab); -- s->reg_size[0] = HAL_SEQ_WCSS_UMAC_CE1_SRC_REG(ab) - -- HAL_SEQ_WCSS_UMAC_CE0_SRC_REG(ab); -- s->reg_size[1] = HAL_SEQ_WCSS_UMAC_CE1_SRC_REG(ab) - -- HAL_SEQ_WCSS_UMAC_CE0_SRC_REG(ab); -- -- s = &hal->srng_config[HAL_CE_DST]; --- s->reg_start[0] = HAL_SEQ_WCSS_UMAC_CE0_DST_REG(ab) + HAL_CE_DST_RING_BASE_LSB; --- s->reg_start[1] = HAL_SEQ_WCSS_UMAC_CE0_DST_REG(ab) + HAL_CE_DST_RING_HP; --+ s->reg_start[0] = HAL_SEQ_WCSS_UMAC_CE0_DST_REG(ab) + HAL_CE_DST_RING_BASE_LSB + --+ ATH11K_CE_OFFSET(ab); --+ s->reg_start[1] = HAL_SEQ_WCSS_UMAC_CE0_DST_REG(ab) + HAL_CE_DST_RING_HP + --+ ATH11K_CE_OFFSET(ab); -- s->reg_size[0] = HAL_SEQ_WCSS_UMAC_CE1_DST_REG(ab) - -- HAL_SEQ_WCSS_UMAC_CE0_DST_REG(ab); -- s->reg_size[1] = HAL_SEQ_WCSS_UMAC_CE1_DST_REG(ab) - --@@ -1237,8 +1241,9 @@ static int ath11k_hal_srng_create_config -- -- s = &hal->srng_config[HAL_CE_DST_STATUS]; -- s->reg_start[0] = HAL_SEQ_WCSS_UMAC_CE0_DST_REG(ab) + --- HAL_CE_DST_STATUS_RING_BASE_LSB; --- s->reg_start[1] = HAL_SEQ_WCSS_UMAC_CE0_DST_REG(ab) + HAL_CE_DST_STATUS_RING_HP; --+ HAL_CE_DST_STATUS_RING_BASE_LSB + ATH11K_CE_OFFSET(ab); --+ s->reg_start[1] = HAL_SEQ_WCSS_UMAC_CE0_DST_REG(ab) + HAL_CE_DST_STATUS_RING_HP + --+ ATH11K_CE_OFFSET(ab); -- s->reg_size[0] = HAL_SEQ_WCSS_UMAC_CE1_DST_REG(ab) - -- HAL_SEQ_WCSS_UMAC_CE0_DST_REG(ab); -- s->reg_size[1] = HAL_SEQ_WCSS_UMAC_CE1_DST_REG(ab) - ----- a/drivers/net/wireless/ath/ath11k/hal.h --+++ b/drivers/net/wireless/ath/ath11k/hal.h --@@ -321,6 +321,10 @@ struct ath11k_base; -- #define HAL_WBM2SW_RELEASE_RING_BASE_MSB_RING_SIZE 0x000fffff -- #define HAL_RXDMA_RING_MAX_SIZE 0x0000ffff -- --+/* IPQ5018 ce registers */ --+#define HAL_IPQ5018_CE_WFSS_REG_BASE 0x08400000 --+#define HAL_IPQ5018_CE_SIZE 0x200000 --+ -- /* Add any other errors here and return them in -- * ath11k_hal_rx_desc_get_err(). -- */ --@@ -519,6 +523,7 @@ enum hal_srng_dir { -- #define HAL_SRNG_FLAGS_MSI_INTR 0x00020000 -- #define HAL_SRNG_FLAGS_CACHED 0x20000000 -- #define HAL_SRNG_FLAGS_LMAC_RING 0x80000000 --+#define HAL_SRNG_FLAGS_REMAP_CE_RING 0x10000000 -- -- #define HAL_SRNG_TLV_HDR_TAG GENMASK(9, 1) -- #define HAL_SRNG_TLV_HDR_LEN GENMASK(25, 10) ----- a/drivers/net/wireless/ath/ath11k/hw.c --+++ b/drivers/net/wireless/ath/ath11k/hw.c --@@ -2163,6 +2163,23 @@ const struct service_to_pipe ath11k_targ -- { /* terminator entry */ } -- }; -- --+const struct ce_ie_addr ath11k_ce_ie_addr_ipq8074 = { --+ .ie1_reg_addr = CE_HOST_IE_ADDRESS, --+ .ie2_reg_addr = CE_HOST_IE_2_ADDRESS, --+ .ie3_reg_addr = CE_HOST_IE_3_ADDRESS, --+}; --+ --+const struct ce_ie_addr ath11k_ce_ie_addr_ipq5018 = { --+ .ie1_reg_addr = CE_HOST_IPQ5018_IE_ADDRESS - HAL_IPQ5018_CE_WFSS_REG_BASE, --+ .ie2_reg_addr = CE_HOST_IPQ5018_IE_2_ADDRESS - HAL_IPQ5018_CE_WFSS_REG_BASE, --+ .ie3_reg_addr = CE_HOST_IPQ5018_IE_3_ADDRESS - HAL_IPQ5018_CE_WFSS_REG_BASE, --+}; --+ --+const struct ce_remap ath11k_ce_remap_ipq5018 = { --+ .base = HAL_IPQ5018_CE_WFSS_REG_BASE, --+ .size = HAL_IPQ5018_CE_SIZE, --+}; --+ -- const struct ath11k_hw_regs ipq8074_regs = { -- /* SW2TCL(x) R0 ring configuration address */ -- .hal_tcl1_ring_base_lsb = 0x00000510, ----- a/drivers/net/wireless/ath/ath11k/hw.h --+++ b/drivers/net/wireless/ath/ath11k/hw.h --@@ -80,6 +80,8 @@ -- #define ATH11K_M3_FILE "m3.bin" -- #define ATH11K_REGDB_FILE_NAME "regdb.bin" -- --+#define ATH11K_CE_OFFSET(ab) (ab->mem_ce - ab->mem) --+ -- enum ath11k_hw_rate_cck { -- ATH11K_HW_RATE_CCK_LP_11M = 0, -- ATH11K_HW_RATE_CCK_LP_5_5M, --@@ -158,6 +160,8 @@ struct ath11k_hw_params { -- u32 target_ce_count; -- const struct service_to_pipe *svc_to_ce_map; -- u32 svc_to_ce_map_len; --+ const struct ce_ie_addr *ce_ie_addr; --+ const struct ce_remap *ce_remap; -- -- bool single_pdev_only; -- --@@ -277,6 +281,11 @@ extern const struct ath11k_hw_ring_mask -- extern const struct ath11k_hw_ring_mask ath11k_hw_ring_mask_qcn9074; -- extern const struct ath11k_hw_ring_mask ath11k_hw_ring_mask_wcn6750; -- --+extern const struct ce_ie_addr ath11k_ce_ie_addr_ipq8074; --+extern const struct ce_ie_addr ath11k_ce_ie_addr_ipq5018; --+ --+extern const struct ce_remap ath11k_ce_remap_ipq5018; --+ -- extern const struct ath11k_hw_hal_params ath11k_hw_hal_params_ipq8074; -- extern const struct ath11k_hw_hal_params ath11k_hw_hal_params_qca6390; -- extern const struct ath11k_hw_hal_params ath11k_hw_hal_params_wcn6750; ----- a/drivers/net/wireless/ath/ath11k/pci.c --+++ b/drivers/net/wireless/ath/ath11k/pci.c --@@ -543,6 +543,8 @@ static int ath11k_pci_claim(struct ath11 -- goto clear_master; -- } -- --+ ab->mem_ce = ab->mem; --+ -- ath11k_dbg(ab, ATH11K_DBG_BOOT, "boot pci_mem 0x%pK\n", ab->mem); -- return 0; -- -diff --git a/package/kernel/mac80211/patches/ath11k/0022-wifi-ath11k-update-hal-srng-regs-for-IPQ5018.patch b/package/kernel/mac80211/patches/ath11k/0022-wifi-ath11k-update-hal-srng-regs-for-IPQ5018.patch -deleted file mode 100644 -index 35ea20a3c4..0000000000 ---- a/package/kernel/mac80211/patches/ath11k/0022-wifi-ath11k-update-hal-srng-regs-for-IPQ5018.patch -+++ /dev/null -@@ -1,130 +0,0 @@ --From 711b80acbdfb9667a9cf8374e13320a6e624ce73 Mon Sep 17 00:00:00 2001 --From: Sriram R --Date: Fri, 2 Dec 2022 23:37:14 +0200 --Subject: [PATCH] wifi: ath11k: update hal srng regs for IPQ5018 -- --IPQ5018 hal srng register address & offsets are not --similar to IPQ8074/IPQ6018/QCN9074, hence define a --new set of srng register group data for IPQ5018. -- --Tested-on: IPQ5018 hw1.0 AHB WLAN.HK.2.6.0.1-00861-QCAHKSWPL_SILICONZ-1 -- --Signed-off-by: Sriram R --Co-developed-by: Karthikeyan Kathirvel --Signed-off-by: Karthikeyan Kathirvel --Signed-off-by: Kalle Valo --Link: https://lore.kernel.org/r/20221122132152.17771-6-quic_kathirve@quicinc.com ----- -- drivers/net/wireless/ath/ath11k/core.c | 1 + -- drivers/net/wireless/ath/ath11k/hw.c | 79 ++++++++++++++++++++++++++ -- drivers/net/wireless/ath/ath11k/hw.h | 1 + -- 3 files changed, 81 insertions(+) -- ----- a/drivers/net/wireless/ath/ath11k/core.c --+++ b/drivers/net/wireless/ath/ath11k/core.c --@@ -634,6 +634,7 @@ static const struct ath11k_hw_params ath -- .max_fft_bins = 1024, -- }, -- .internal_sleep_clock = false, --+ .regs = &ipq5018_regs, -- .host_ce_config = ath11k_host_ce_config_qcn9074, -- .ce_count = CE_CNT_5018, -- .target_ce_config = ath11k_target_ce_config_wlan_ipq5018, ----- a/drivers/net/wireless/ath/ath11k/hw.c --+++ b/drivers/net/wireless/ath/ath11k/hw.c --@@ -2645,6 +2645,85 @@ static const struct ath11k_hw_tcl2wbm_rb -- }, -- }; -- --+const struct ath11k_hw_regs ipq5018_regs = { --+ /* SW2TCL(x) R0 ring configuration address */ --+ .hal_tcl1_ring_base_lsb = 0x00000694, --+ .hal_tcl1_ring_base_msb = 0x00000698, --+ .hal_tcl1_ring_id = 0x0000069c, --+ .hal_tcl1_ring_misc = 0x000006a4, --+ .hal_tcl1_ring_tp_addr_lsb = 0x000006b0, --+ .hal_tcl1_ring_tp_addr_msb = 0x000006b4, --+ .hal_tcl1_ring_consumer_int_setup_ix0 = 0x000006c4, --+ .hal_tcl1_ring_consumer_int_setup_ix1 = 0x000006c8, --+ .hal_tcl1_ring_msi1_base_lsb = 0x000006dc, --+ .hal_tcl1_ring_msi1_base_msb = 0x000006e0, --+ .hal_tcl1_ring_msi1_data = 0x000006e4, --+ .hal_tcl2_ring_base_lsb = 0x000006ec, --+ .hal_tcl_ring_base_lsb = 0x0000079c, --+ --+ /* TCL STATUS ring address */ --+ .hal_tcl_status_ring_base_lsb = 0x000008a4, --+ --+ /* REO2SW(x) R0 ring configuration address */ --+ .hal_reo1_ring_base_lsb = 0x000001ec, --+ .hal_reo1_ring_base_msb = 0x000001f0, --+ .hal_reo1_ring_id = 0x000001f4, --+ .hal_reo1_ring_misc = 0x000001fc, --+ .hal_reo1_ring_hp_addr_lsb = 0x00000200, --+ .hal_reo1_ring_hp_addr_msb = 0x00000204, --+ .hal_reo1_ring_producer_int_setup = 0x00000210, --+ .hal_reo1_ring_msi1_base_lsb = 0x00000234, --+ .hal_reo1_ring_msi1_base_msb = 0x00000238, --+ .hal_reo1_ring_msi1_data = 0x0000023c, --+ .hal_reo2_ring_base_lsb = 0x00000244, --+ .hal_reo1_aging_thresh_ix_0 = 0x00000564, --+ .hal_reo1_aging_thresh_ix_1 = 0x00000568, --+ .hal_reo1_aging_thresh_ix_2 = 0x0000056c, --+ .hal_reo1_aging_thresh_ix_3 = 0x00000570, --+ --+ /* REO2SW(x) R2 ring pointers (head/tail) address */ --+ .hal_reo1_ring_hp = 0x00003028, --+ .hal_reo1_ring_tp = 0x0000302c, --+ .hal_reo2_ring_hp = 0x00003030, --+ --+ /* REO2TCL R0 ring configuration address */ --+ .hal_reo_tcl_ring_base_lsb = 0x000003fc, --+ .hal_reo_tcl_ring_hp = 0x00003058, --+ --+ /* SW2REO ring address */ --+ .hal_sw2reo_ring_base_lsb = 0x0000013c, --+ .hal_sw2reo_ring_hp = 0x00003018, --+ --+ /* REO CMD ring address */ --+ .hal_reo_cmd_ring_base_lsb = 0x000000e4, --+ .hal_reo_cmd_ring_hp = 0x00003010, --+ --+ /* REO status address */ --+ .hal_reo_status_ring_base_lsb = 0x00000504, --+ .hal_reo_status_hp = 0x00003070, --+ --+ /* WCSS relative address */ --+ .hal_seq_wcss_umac_ce0_src_reg = 0x08400000 --+ - HAL_IPQ5018_CE_WFSS_REG_BASE, --+ .hal_seq_wcss_umac_ce0_dst_reg = 0x08401000 --+ - HAL_IPQ5018_CE_WFSS_REG_BASE, --+ .hal_seq_wcss_umac_ce1_src_reg = 0x08402000 --+ - HAL_IPQ5018_CE_WFSS_REG_BASE, --+ .hal_seq_wcss_umac_ce1_dst_reg = 0x08403000 --+ - HAL_IPQ5018_CE_WFSS_REG_BASE, --+ --+ /* WBM Idle address */ --+ .hal_wbm_idle_link_ring_base_lsb = 0x00000874, --+ .hal_wbm_idle_link_ring_misc = 0x00000884, --+ --+ /* SW2WBM release address */ --+ .hal_wbm_release_ring_base_lsb = 0x000001ec, --+ --+ /* WBM2SW release address */ --+ .hal_wbm0_release_ring_base_lsb = 0x00000924, --+ .hal_wbm1_release_ring_base_lsb = 0x0000097c, --+}; --+ -- const struct ath11k_hw_hal_params ath11k_hw_hal_params_ipq8074 = { -- .rx_buf_rbm = HAL_RX_BUF_RBM_SW3_BM, -- .tcl2wbm_rbm_map = ath11k_hw_tcl2wbm_rbm_map_ipq8074, ----- a/drivers/net/wireless/ath/ath11k/hw.h --+++ b/drivers/net/wireless/ath/ath11k/hw.h --@@ -415,6 +415,7 @@ extern const struct ath11k_hw_regs qca63 -- extern const struct ath11k_hw_regs qcn9074_regs; -- extern const struct ath11k_hw_regs wcn6855_regs; -- extern const struct ath11k_hw_regs wcn6750_regs; --+extern const struct ath11k_hw_regs ipq5018_regs; -- -- static inline const char *ath11k_bd_ie_type_str(enum ath11k_bd_ie_type type) -- { -diff --git a/package/kernel/mac80211/patches/ath11k/0023-wifi-ath11k-initialize-hw_ops-for-IPQ5018.patch b/package/kernel/mac80211/patches/ath11k/0023-wifi-ath11k-initialize-hw_ops-for-IPQ5018.patch -deleted file mode 100644 -index 5ef701a445..0000000000 ---- a/package/kernel/mac80211/patches/ath11k/0023-wifi-ath11k-initialize-hw_ops-for-IPQ5018.patch -+++ /dev/null -@@ -1,90 +0,0 @@ --From ba60f2793d3a37a00da14bb56a26558a902d2831 Mon Sep 17 00:00:00 2001 --From: Sriram R --Date: Fri, 2 Dec 2022 23:37:14 +0200 --Subject: [PATCH] wifi: ath11k: initialize hw_ops for IPQ5018 -- --The ipq5018_ops is initialized for IPQ5018. This is different from --other platforms. -- --Tested-on: IPQ5018 hw1.0 AHB WLAN.HK.2.6.0.1-00861-QCAHKSWPL_SILICONZ-1 -- --Signed-off-by: Sriram R --Co-developed-by: Karthikeyan Kathirvel --Signed-off-by: Karthikeyan Kathirvel --Signed-off-by: Kalle Valo --Link: https://lore.kernel.org/r/20221122132152.17771-7-quic_kathirve@quicinc.com ----- -- drivers/net/wireless/ath/ath11k/core.c | 1 + -- drivers/net/wireless/ath/ath11k/hw.c | 40 ++++++++++++++++++++++++++ -- drivers/net/wireless/ath/ath11k/hw.h | 1 + -- 3 files changed, 42 insertions(+) -- ----- a/drivers/net/wireless/ath/ath11k/core.c --+++ b/drivers/net/wireless/ath/ath11k/core.c --@@ -635,6 +635,7 @@ static const struct ath11k_hw_params ath -- }, -- .internal_sleep_clock = false, -- .regs = &ipq5018_regs, --+ .hw_ops = &ipq5018_ops, -- .host_ce_config = ath11k_host_ce_config_qcn9074, -- .ce_count = CE_CNT_5018, -- .target_ce_config = ath11k_target_ce_config_wlan_ipq5018, ----- a/drivers/net/wireless/ath/ath11k/hw.c --+++ b/drivers/net/wireless/ath/ath11k/hw.c --@@ -1084,6 +1084,46 @@ const struct ath11k_hw_ops wcn6750_ops = -- .get_ring_selector = ath11k_hw_wcn6750_get_tcl_ring_selector, -- }; -- --+/* IPQ5018 hw ops is similar to QCN9074 except for the dest ring remap */ --+const struct ath11k_hw_ops ipq5018_ops = { --+ .get_hw_mac_from_pdev_id = ath11k_hw_ipq6018_mac_from_pdev_id, --+ .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, --+ .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, --+ .rx_desc_get_l3_pad_bytes = ath11k_hw_qcn9074_rx_desc_get_l3_pad_bytes, --+ .rx_desc_get_hdr_status = ath11k_hw_qcn9074_rx_desc_get_hdr_status, --+ .rx_desc_encrypt_valid = ath11k_hw_qcn9074_rx_desc_encrypt_valid, --+ .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_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, --+ .rx_desc_get_mpdu_start_seq_no = ath11k_hw_qcn9074_rx_desc_get_mpdu_start_seq_no, --+ .rx_desc_get_msdu_len = ath11k_hw_qcn9074_rx_desc_get_msdu_len, --+ .rx_desc_get_msdu_sgi = ath11k_hw_qcn9074_rx_desc_get_msdu_sgi, --+ .rx_desc_get_msdu_rate_mcs = ath11k_hw_qcn9074_rx_desc_get_msdu_rate_mcs, --+ .rx_desc_get_msdu_rx_bw = ath11k_hw_qcn9074_rx_desc_get_msdu_rx_bw, --+ .rx_desc_get_msdu_freq = ath11k_hw_qcn9074_rx_desc_get_msdu_freq, --+ .rx_desc_get_msdu_pkt_type = ath11k_hw_qcn9074_rx_desc_get_msdu_pkt_type, --+ .rx_desc_get_msdu_nss = ath11k_hw_qcn9074_rx_desc_get_msdu_nss, --+ .rx_desc_get_mpdu_tid = ath11k_hw_qcn9074_rx_desc_get_mpdu_tid, --+ .rx_desc_get_mpdu_peer_id = ath11k_hw_qcn9074_rx_desc_get_mpdu_peer_id, --+ .rx_desc_copy_attn_end_tlv = ath11k_hw_qcn9074_rx_desc_copy_attn_end, --+ .rx_desc_get_mpdu_start_tag = ath11k_hw_qcn9074_rx_desc_get_mpdu_start_tag, --+ .rx_desc_get_mpdu_ppdu_id = ath11k_hw_qcn9074_rx_desc_get_mpdu_ppdu_id, --+ .rx_desc_set_msdu_len = ath11k_hw_qcn9074_rx_desc_set_msdu_len, --+ .rx_desc_get_attention = ath11k_hw_qcn9074_rx_desc_get_attention, --+ .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, --+ --+}; --+ -- #define ATH11K_TX_RING_MASK_0 BIT(0) -- #define ATH11K_TX_RING_MASK_1 BIT(1) -- #define ATH11K_TX_RING_MASK_2 BIT(2) ----- a/drivers/net/wireless/ath/ath11k/hw.h --+++ b/drivers/net/wireless/ath/ath11k/hw.h --@@ -275,6 +275,7 @@ extern const struct ath11k_hw_ops qca639 -- extern const struct ath11k_hw_ops qcn9074_ops; -- extern const struct ath11k_hw_ops wcn6855_ops; -- extern const struct ath11k_hw_ops wcn6750_ops; --+extern const struct ath11k_hw_ops ipq5018_ops; -- -- extern const struct ath11k_hw_ring_mask ath11k_hw_ring_mask_ipq8074; -- extern const struct ath11k_hw_ring_mask ath11k_hw_ring_mask_qca6390; -diff --git a/package/kernel/mac80211/patches/ath11k/0024-wifi-ath11k-add-new-hw-ops-for-IPQ5018-to-get-rx-des.patch b/package/kernel/mac80211/patches/ath11k/0024-wifi-ath11k-add-new-hw-ops-for-IPQ5018-to-get-rx-des.patch -deleted file mode 100644 -index 64531f13f8..0000000000 ---- a/package/kernel/mac80211/patches/ath11k/0024-wifi-ath11k-add-new-hw-ops-for-IPQ5018-to-get-rx-des.patch -+++ /dev/null -@@ -1,84 +0,0 @@ --From 69968f88f1770d61cae0febef805fd00d66cf6a1 Mon Sep 17 00:00:00 2001 --From: Sriram R --Date: Fri, 2 Dec 2022 23:37:15 +0200 --Subject: [PATCH] wifi: ath11k: add new hw ops for IPQ5018 to get rx dest ring -- hashmap -- --The Destination ring control register is different --for IPQ5018 when compared to IPQ8074/IPQ6018/QCN9074. --Hence create a new hw ops to fetch the hash ring map --for different device variants. ipq5018 hw ops --is similar to qcn9074 except for this change, so reuse --all the qcn9074 ops for ipq5018. -- --Tested-on: IPQ5018 hw1.0 AHB WLAN.HK.2.6.0.1-00861-QCAHKSWPL_SILICONZ-1 -- --Signed-off-by: Sriram R --Co-developed-by: Karthikeyan Kathirvel --Signed-off-by: Karthikeyan Kathirvel --Signed-off-by: Kalle Valo --Link: https://lore.kernel.org/r/20221122132152.17771-8-quic_kathirve@quicinc.com ----- -- drivers/net/wireless/ath/ath11k/hw.c | 44 ++++++++++++++++++++++++++++ -- 1 file changed, 44 insertions(+) -- ----- a/drivers/net/wireless/ath/ath11k/hw.c --+++ b/drivers/net/wireless/ath/ath11k/hw.c --@@ -791,6 +791,49 @@ static void ath11k_hw_wcn6855_reo_setup( -- ring_hash_map); -- } -- --+static void ath11k_hw_ipq5018_reo_setup(struct ath11k_base *ab) --+{ --+ 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 << 4 | --+ HAL_HASH_ROUTING_RING_SW3 << 8 | --+ HAL_HASH_ROUTING_RING_SW4 << 12 | --+ HAL_HASH_ROUTING_RING_SW1 << 16 | --+ HAL_HASH_ROUTING_RING_SW2 << 20 | --+ HAL_HASH_ROUTING_RING_SW3 << 24 | --+ HAL_HASH_ROUTING_RING_SW4 << 28; --+ --+ 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) | --+ 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); --+ --+ ath11k_hif_write32(ab, reo_base + HAL_REO1_AGING_THRESH_IX_0(ab), --+ HAL_DEFAULT_REO_TIMEOUT_USEC); --+ ath11k_hif_write32(ab, reo_base + HAL_REO1_AGING_THRESH_IX_1(ab), --+ HAL_DEFAULT_REO_TIMEOUT_USEC); --+ ath11k_hif_write32(ab, reo_base + HAL_REO1_AGING_THRESH_IX_2(ab), --+ 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); --+} --+ -- static u16 ath11k_hw_ipq8074_mpdu_info_get_peerid(u8 *tlv_data) -- { -- u16 peer_id = 0; --@@ -1117,6 +1160,7 @@ const struct ath11k_hw_ops ipq5018_ops = -- .rx_desc_get_mpdu_ppdu_id = ath11k_hw_qcn9074_rx_desc_get_mpdu_ppdu_id, -- .rx_desc_set_msdu_len = ath11k_hw_qcn9074_rx_desc_set_msdu_len, -- .rx_desc_get_attention = ath11k_hw_qcn9074_rx_desc_get_attention, --+ .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, -diff --git a/package/kernel/mac80211/patches/ath11k/0025-wifi-ath11k-add-ipq5018-device-support.patch b/package/kernel/mac80211/patches/ath11k/0025-wifi-ath11k-add-ipq5018-device-support.patch -deleted file mode 100644 -index 5b930e8d4f..0000000000 ---- a/package/kernel/mac80211/patches/ath11k/0025-wifi-ath11k-add-ipq5018-device-support.patch -+++ /dev/null -@@ -1,31 +0,0 @@ --From 25edca7bb18a2a40cc7e54c6f522e9b3c917e2c5 Mon Sep 17 00:00:00 2001 --From: Sriram R --Date: Fri, 2 Dec 2022 23:37:15 +0200 --Subject: [PATCH] wifi: ath11k: add ipq5018 device support -- --ipq5018 is a ahb 2ghz device, enable the compatible support for --ipq5018 in ahb. -- --Tested-on: IPQ5018 hw1.0 AHB WLAN.HK.2.6.0.1-00861-QCAHKSWPL_SILICONZ-1 -- --Signed-off-by: Sriram R --Co-developed-by: Karthikeyan Kathirvel --Signed-off-by: Karthikeyan Kathirvel --Signed-off-by: Kalle Valo --Link: https://lore.kernel.org/r/20221122132152.17771-9-quic_kathirve@quicinc.com ----- -- drivers/net/wireless/ath/ath11k/ahb.c | 3 +++ -- 1 file changed, 3 insertions(+) -- ----- a/drivers/net/wireless/ath/ath11k/ahb.c --+++ b/drivers/net/wireless/ath/ath11k/ahb.c --@@ -32,6 +32,9 @@ static const struct of_device_id ath11k_ -- { .compatible = "qcom,wcn6750-wifi", -- .data = (void *)ATH11K_HW_WCN6750_HW10, -- }, --+ { .compatible = "qcom,ipq5018-wifi", --+ .data = (void *)ATH11K_HW_IPQ5018_HW10, --+ }, -- { } -- }; -- -diff --git a/package/kernel/mac80211/patches/ath11k/0026-wifi-ath11k-Fix-scan-request-param-frame-size-warnin.patch b/package/kernel/mac80211/patches/ath11k/0026-wifi-ath11k-Fix-scan-request-param-frame-size-warnin.patch -deleted file mode 100644 -index 50c14e7b98..0000000000 ---- a/package/kernel/mac80211/patches/ath11k/0026-wifi-ath11k-Fix-scan-request-param-frame-size-warnin.patch -+++ /dev/null -@@ -1,161 +0,0 @@ --From d45daa6d1a8da080f1b516c570a8428a7b9225e4 Mon Sep 17 00:00:00 2001 --From: Karthikeyan Kathirvel --Date: Tue, 6 Dec 2022 00:51:25 +0530 --Subject: [PATCH] wifi: ath11k: Fix scan request param frame size warning -- --Following warning was observed -- --drivers/net/wireless/ath/ath11k/mac.c:2351:1: warning: the frame --size of 1184 bytes is larger than 1024 bytes [-Wframe-larger-than=] -- --A local variable is declared with a size larger than 1024 bytes --this causing a compilation warning. Change the local variable to --heap memory to fix the warning. -- --Tested-on: IPQ8074 AHB WLAN.HK.2.7.0.1-01701-QCAHKSWPL_SILICONZ-1 v2 -- --Signed-off-by: Karthikeyan Kathirvel --Signed-off-by: Kalle Valo --Link: https://lore.kernel.org/r/20221205192125.13533-1-quic_kathirve@quicinc.com ----- -- drivers/net/wireless/ath/ath11k/mac.c | 83 +++++++++++++++------------ -- 1 file changed, 45 insertions(+), 38 deletions(-) -- ----- a/drivers/net/wireless/ath/ath11k/mac.c --+++ b/drivers/net/wireless/ath/ath11k/mac.c --@@ -3612,7 +3612,7 @@ static int ath11k_mac_op_hw_scan(struct -- struct ath11k *ar = hw->priv; -- struct ath11k_vif *arvif = ath11k_vif_to_arvif(vif); -- struct cfg80211_scan_request *req = &hw_req->req; --- struct scan_req_params arg; --+ struct scan_req_params *arg = NULL; -- int ret = 0; -- int i; -- u32 scan_timeout; --@@ -3640,72 +3640,78 @@ static int ath11k_mac_op_hw_scan(struct -- if (ret) -- goto exit; -- --- memset(&arg, 0, sizeof(arg)); --- ath11k_wmi_start_scan_init(ar, &arg); --- arg.vdev_id = arvif->vdev_id; --- arg.scan_id = ATH11K_SCAN_ID; --+ arg = kzalloc(sizeof(*arg), GFP_KERNEL); --+ --+ if (!arg) { --+ ret = -ENOMEM; --+ goto exit; --+ } --+ --+ ath11k_wmi_start_scan_init(ar, arg); --+ arg->vdev_id = arvif->vdev_id; --+ arg->scan_id = ATH11K_SCAN_ID; -- -- if (req->ie_len) { --- arg.extraie.ptr = kmemdup(req->ie, req->ie_len, GFP_KERNEL); --- if (!arg.extraie.ptr) { --+ arg->extraie.ptr = kmemdup(req->ie, req->ie_len, GFP_KERNEL); --+ if (!arg->extraie.ptr) { -- ret = -ENOMEM; -- goto exit; -- } --- arg.extraie.len = req->ie_len; --+ arg->extraie.len = req->ie_len; -- } -- -- if (req->n_ssids) { --- arg.num_ssids = req->n_ssids; --- for (i = 0; i < arg.num_ssids; i++) { --- arg.ssid[i].length = req->ssids[i].ssid_len; --- memcpy(&arg.ssid[i].ssid, req->ssids[i].ssid, --+ arg->num_ssids = req->n_ssids; --+ for (i = 0; i < arg->num_ssids; i++) { --+ arg->ssid[i].length = req->ssids[i].ssid_len; --+ memcpy(&arg->ssid[i].ssid, req->ssids[i].ssid, -- req->ssids[i].ssid_len); -- } -- } else { --- arg.scan_flags |= WMI_SCAN_FLAG_PASSIVE; --+ arg->scan_flags |= WMI_SCAN_FLAG_PASSIVE; -- } -- -- if (req->n_channels) { --- arg.num_chan = req->n_channels; --- arg.chan_list = kcalloc(arg.num_chan, sizeof(*arg.chan_list), --- GFP_KERNEL); --+ arg->num_chan = req->n_channels; --+ arg->chan_list = kcalloc(arg->num_chan, sizeof(*arg->chan_list), --+ GFP_KERNEL); -- --- if (!arg.chan_list) { --+ if (!arg->chan_list) { -- ret = -ENOMEM; -- goto exit; -- } -- --- for (i = 0; i < arg.num_chan; i++) --- arg.chan_list[i] = req->channels[i]->center_freq; --+ for (i = 0; i < arg->num_chan; i++) --+ arg->chan_list[i] = req->channels[i]->center_freq; -- } -- -- if (req->flags & NL80211_SCAN_FLAG_RANDOM_ADDR) { --- arg.scan_f_add_spoofed_mac_in_probe = 1; --- ether_addr_copy(arg.mac_addr.addr, req->mac_addr); --- ether_addr_copy(arg.mac_mask.addr, req->mac_addr_mask); --+ arg->scan_f_add_spoofed_mac_in_probe = 1; --+ ether_addr_copy(arg->mac_addr.addr, req->mac_addr); --+ ether_addr_copy(arg->mac_mask.addr, req->mac_addr_mask); -- } -- -- /* if duration is set, default dwell times will be overwritten */ -- if (req->duration) { --- arg.dwell_time_active = req->duration; --- arg.dwell_time_active_2g = req->duration; --- arg.dwell_time_active_6g = req->duration; --- arg.dwell_time_passive = req->duration; --- arg.dwell_time_passive_6g = req->duration; --- arg.burst_duration = req->duration; --+ arg->dwell_time_active = req->duration; --+ arg->dwell_time_active_2g = req->duration; --+ arg->dwell_time_active_6g = req->duration; --+ arg->dwell_time_passive = req->duration; --+ arg->dwell_time_passive_6g = req->duration; --+ arg->burst_duration = req->duration; -- --- scan_timeout = min_t(u32, arg.max_rest_time * --- (arg.num_chan - 1) + (req->duration + --+ scan_timeout = min_t(u32, arg->max_rest_time * --+ (arg->num_chan - 1) + (req->duration + -- ATH11K_SCAN_CHANNEL_SWITCH_WMI_EVT_OVERHEAD) * --- arg.num_chan, arg.max_scan_time); --+ arg->num_chan, arg->max_scan_time); -- } else { --- scan_timeout = arg.max_scan_time; --+ scan_timeout = arg->max_scan_time; -- } -- -- /* Add a margin to account for event/command processing */ -- scan_timeout += ATH11K_MAC_SCAN_CMD_EVT_OVERHEAD; -- --- ret = ath11k_start_scan(ar, &arg); --+ ret = ath11k_start_scan(ar, arg); -- if (ret) { -- ath11k_warn(ar->ab, "failed to start hw scan: %d\n", ret); -- spin_lock_bh(&ar->data_lock); --@@ -3717,10 +3723,11 @@ static int ath11k_mac_op_hw_scan(struct -- msecs_to_jiffies(scan_timeout)); -- -- exit: --- kfree(arg.chan_list); --- --- if (req->ie_len) --- kfree(arg.extraie.ptr); --+ if (arg) { --+ kfree(arg->chan_list); --+ kfree(arg->extraie.ptr); --+ kfree(arg); --+ } -- -- mutex_unlock(&ar->conf_mutex); -- -diff --git a/package/kernel/mac80211/patches/ath11k/0029-wifi-ath11k-Add-support-to-configure-FTM-responder-r.patch b/package/kernel/mac80211/patches/ath11k/0029-wifi-ath11k-Add-support-to-configure-FTM-responder-r.patch -deleted file mode 100644 -index f652d689b5..0000000000 ---- a/package/kernel/mac80211/patches/ath11k/0029-wifi-ath11k-Add-support-to-configure-FTM-responder-r.patch -+++ /dev/null -@@ -1,169 +0,0 @@ --From a27c6a5853eb9d4f293b99be73a6891fe88263c7 Mon Sep 17 00:00:00 2001 --From: Sowmiya Sree Elavalagan --Date: Tue, 10 Jan 2023 15:30:57 +0200 --Subject: [PATCH] wifi: ath11k: Add support to configure FTM responder role -- --Fine Timing Measurement(FTM) support is used to measure round trip --time between two nodes. -- --Enable FTM responder feature using hw_params on supported device. --Since FTM functionality is offloaded to firmware, adding the --interface allows user space to enable or disable FTM responder. --Also add support for advertising the same in extended capabilities. -- --QCA6390, WCN6855 and WCN6750 do not support this feature. -- --Tested-on: IPQ8074 hw2.0 AHB WLAN.HK.2.7.0.1-01744-QCAHKSWPL_SILICONZ-1 --Tested-on: QCN9074 hw1.0 PCI WLAN.HK.2.7.0.1-01744-QCAHKSWPL_SILICONZ-1 -- --Signed-off-by: Sowmiya Sree Elavalagan --Signed-off-by: Raj Kumar Bhagat --Signed-off-by: Kalle Valo --Link: https://lore.kernel.org/r/20221220044435.10506-1-quic_rajkbhag@quicinc.com ----- -- drivers/net/wireless/ath/ath11k/core.c | 8 ++++++++ -- drivers/net/wireless/ath/ath11k/core.h | 1 + -- drivers/net/wireless/ath/ath11k/hw.h | 1 + -- drivers/net/wireless/ath/ath11k/mac.c | 20 +++++++++++++++++++- -- drivers/net/wireless/ath/ath11k/wmi.h | 1 + -- 5 files changed, 30 insertions(+), 1 deletion(-) -- ----- a/drivers/net/wireless/ath/ath11k/core.c --+++ b/drivers/net/wireless/ath/ath11k/core.c --@@ -116,6 +116,7 @@ static const struct ath11k_hw_params ath -- .tcl_ring_retry = true, -- .tx_ring_size = DP_TCL_DATA_RING_SIZE, -- .smp2p_wow_exit = false, --+ .ftm_responder = true, -- }, -- { -- .hw_rev = ATH11K_HW_IPQ6018_HW10, --@@ -198,6 +199,7 @@ static const struct ath11k_hw_params ath -- .tx_ring_size = DP_TCL_DATA_RING_SIZE, -- .smp2p_wow_exit = false, -- .support_fw_mac_sequence = false, --+ .ftm_responder = true, -- }, -- { -- .name = "qca6390 hw2.0", --@@ -282,6 +284,7 @@ static const struct ath11k_hw_params ath -- .tx_ring_size = DP_TCL_DATA_RING_SIZE, -- .smp2p_wow_exit = false, -- .support_fw_mac_sequence = true, --+ .ftm_responder = false, -- }, -- { -- .name = "qcn9074 hw1.0", --@@ -363,6 +366,7 @@ static const struct ath11k_hw_params ath -- .tx_ring_size = DP_TCL_DATA_RING_SIZE, -- .smp2p_wow_exit = false, -- .support_fw_mac_sequence = false, --+ .ftm_responder = true, -- }, -- { -- .name = "wcn6855 hw2.0", --@@ -447,6 +451,7 @@ static const struct ath11k_hw_params ath -- .tx_ring_size = DP_TCL_DATA_RING_SIZE, -- .smp2p_wow_exit = false, -- .support_fw_mac_sequence = true, --+ .ftm_responder = false, -- }, -- { -- .name = "wcn6855 hw2.1", --@@ -529,6 +534,7 @@ static const struct ath11k_hw_params ath -- .tx_ring_size = DP_TCL_DATA_RING_SIZE, -- .smp2p_wow_exit = false, -- .support_fw_mac_sequence = true, --+ .ftm_responder = false, -- }, -- { -- .name = "wcn6750 hw1.0", --@@ -609,6 +615,7 @@ static const struct ath11k_hw_params ath -- .tx_ring_size = DP_TCL_DATA_RING_SIZE_WCN6750, -- .smp2p_wow_exit = true, -- .support_fw_mac_sequence = true, --+ .ftm_responder = false, -- }, -- { -- .hw_rev = ATH11K_HW_IPQ5018_HW10, --@@ -688,6 +695,7 @@ static const struct ath11k_hw_params ath -- .tx_ring_size = DP_TCL_DATA_RING_SIZE, -- .smp2p_wow_exit = false, -- .support_fw_mac_sequence = false, --+ .ftm_responder = true, -- }, -- }; -- ----- a/drivers/net/wireless/ath/ath11k/core.h --+++ b/drivers/net/wireless/ath/ath11k/core.h --@@ -346,6 +346,7 @@ struct ath11k_vif { -- -- bool is_started; -- bool is_up; --+ bool ftm_responder; -- bool spectral_enabled; -- bool ps; -- u32 aid; ----- a/drivers/net/wireless/ath/ath11k/hw.h --+++ b/drivers/net/wireless/ath/ath11k/hw.h --@@ -224,6 +224,7 @@ struct ath11k_hw_params { -- u32 tx_ring_size; -- bool smp2p_wow_exit; -- bool support_fw_mac_sequence; --+ bool ftm_responder; -- }; -- -- struct ath11k_hw_ops { ----- a/drivers/net/wireless/ath/ath11k/mac.c --+++ b/drivers/net/wireless/ath/ath11k/mac.c --@@ -3110,7 +3110,7 @@ static void ath11k_mac_op_bss_info_chang -- u16 bitrate; -- int ret = 0; -- u8 rateidx; --- u32 rate; --+ u32 rate, param; -- u32 ipv4_cnt; -- -- mutex_lock(&ar->conf_mutex); --@@ -3412,6 +3412,20 @@ static void ath11k_mac_op_bss_info_chang -- } -- } -- --+ if (changed & BSS_CHANGED_FTM_RESPONDER && --+ arvif->ftm_responder != info->ftm_responder && --+ ar->ab->hw_params.ftm_responder && --+ (vif->type == NL80211_IFTYPE_AP || --+ vif->type == NL80211_IFTYPE_MESH_POINT)) { --+ arvif->ftm_responder = info->ftm_responder; --+ param = WMI_VDEV_PARAM_ENABLE_DISABLE_RTT_RESPONDER_ROLE; --+ ret = ath11k_wmi_vdev_set_param_cmd(ar, arvif->vdev_id, param, --+ arvif->ftm_responder); --+ if (ret) --+ ath11k_warn(ar->ab, "Failed to set ftm responder %i: %d\n", --+ arvif->vdev_id, ret); --+ } --+ -- if (changed & BSS_CHANGED_FILS_DISCOVERY || -- changed & BSS_CHANGED_UNSOL_BCAST_PROBE_RESP) -- ath11k_mac_fils_discovery(arvif, info); --@@ -9113,6 +9127,10 @@ static int __ath11k_mac_register(struct -- wiphy_ext_feature_set(ar->hw->wiphy, -- NL80211_EXT_FEATURE_SET_SCAN_DWELL); -- --+ if (ab->hw_params.ftm_responder) --+ wiphy_ext_feature_set(ar->hw->wiphy, --+ NL80211_EXT_FEATURE_ENABLE_FTM_RESPONDER); --+ -- ath11k_reg_init(ar); -- -- if (!test_bit(ATH11K_FLAG_RAW_MODE, &ab->dev_flags)) { ----- a/drivers/net/wireless/ath/ath11k/wmi.h --+++ b/drivers/net/wireless/ath/ath11k/wmi.h --@@ -1073,6 +1073,7 @@ enum wmi_tlv_vdev_param { -- WMI_VDEV_PARAM_ENABLE_BCAST_PROBE_RESPONSE, -- WMI_VDEV_PARAM_FILS_MAX_CHANNEL_GUARD_TIME, -- WMI_VDEV_PARAM_HE_LTF = 0x74, --+ WMI_VDEV_PARAM_ENABLE_DISABLE_RTT_RESPONDER_ROLE = 0x7d, -- WMI_VDEV_PARAM_BA_MODE = 0x7e, -- WMI_VDEV_PARAM_AUTORATE_MISC_CFG = 0x80, -- WMI_VDEV_PARAM_SET_HE_SOUNDING_MODE = 0x87, -diff --git a/package/kernel/mac80211/patches/ath11k/0030-wifi-ath11k-add-channel-177-into-5-GHz-channel-list.patch b/package/kernel/mac80211/patches/ath11k/0030-wifi-ath11k-add-channel-177-into-5-GHz-channel-list.patch -deleted file mode 100644 -index d0ed9c54b8..0000000000 ---- a/package/kernel/mac80211/patches/ath11k/0030-wifi-ath11k-add-channel-177-into-5-GHz-channel-list.patch -+++ /dev/null -@@ -1,41 +0,0 @@ --From e5e94d10c85653609a2893c8d0ef24a27471b68f Mon Sep 17 00:00:00 2001 --From: Wen Gong --Date: Tue, 10 Jan 2023 15:30:58 +0200 --Subject: [PATCH] wifi: ath11k: add channel 177 into 5 GHz channel list -- --Add support for the 5 GHz channel 177 with center frequency 5885 MHz and --operating class 125 per IEEE Std 802.11ax-2021, Table E-4. -- --Tested-on: WCN6855 hw2.0 PCI WLAN.HSP.1.1-03125-QCAHSPSWPL_V1_V2_SILICONZ_LITE-3 -- --Signed-off-by: Wen Gong --Signed-off-by: Kalle Valo --Link: https://lore.kernel.org/r/20221220101912.30816-1-quic_wgong@quicinc.com ----- -- drivers/net/wireless/ath/ath11k/core.h | 4 ++-- -- drivers/net/wireless/ath/ath11k/mac.c | 1 + -- 2 files changed, 3 insertions(+), 2 deletions(-) -- ----- a/drivers/net/wireless/ath/ath11k/core.h --+++ b/drivers/net/wireless/ath/ath11k/core.h --@@ -521,8 +521,8 @@ struct ath11k_sta { -- #define ATH11K_MIN_5G_FREQ 4150 -- #define ATH11K_MIN_6G_FREQ 5925 -- #define ATH11K_MAX_6G_FREQ 7115 ---#define ATH11K_NUM_CHANS 101 ---#define ATH11K_MAX_5G_CHAN 173 --+#define ATH11K_NUM_CHANS 102 --+#define ATH11K_MAX_5G_CHAN 177 -- -- enum ath11k_state { -- ATH11K_STATE_OFF, ----- a/drivers/net/wireless/ath/ath11k/mac.c --+++ b/drivers/net/wireless/ath/ath11k/mac.c --@@ -96,6 +96,7 @@ static const struct ieee80211_channel at -- CHAN5G(165, 5825, 0), -- CHAN5G(169, 5845, 0), -- CHAN5G(173, 5865, 0), --+ CHAN5G(177, 5885, 0), -- }; -- -- static const struct ieee80211_channel ath11k_6ghz_channels[] = { -diff --git a/package/kernel/mac80211/patches/ath11k/0031-wifi-ath11k-fix-ce-memory-mapping-for-ahb-devices.patch b/package/kernel/mac80211/patches/ath11k/0031-wifi-ath11k-fix-ce-memory-mapping-for-ahb-devices.patch -deleted file mode 100644 -index 2786799972..0000000000 ---- a/package/kernel/mac80211/patches/ath11k/0031-wifi-ath11k-fix-ce-memory-mapping-for-ahb-devices.patch -+++ /dev/null -@@ -1,114 +0,0 @@ --From 53a998c4d7284debd77734d01e1466e59a1d03b2 Mon Sep 17 00:00:00 2001 --From: Raj Kumar Bhagat --Date: Fri, 13 Jan 2023 12:02:09 +0530 --Subject: [PATCH] wifi: ath11k: fix ce memory mapping for ahb devices -- --Currently ath11k_ahb module is not loaded successfully and the wifi --interface is not created. Kernel trace is seen while loading the --ath11k_ahb module. The issue is seen in all ath11k AHB devices except --in IPQ5018. -- --This happens because in ath11k_ahb_probe(), ab->mem_ce is initialized --with the value of ab->mem. However, at this instant ab->mem is not --yet set. -- --Later, during write to a particular memory via ath11k_ahb_write32() --this ab->mem_ce is used with particular offset. Since ab->mem_ce is --not set properly this possibly leads to memory conflict to handle --kernel paging request and the below trace is seen. -- --[ 93.035047] Unable to handle kernel paging request at virtual address ffff800100a00000 --[ 93.035083] Mem abort info: --[ 93.041869] ESR = 0x0000000096000045 --[ 93.044561] EC = 0x25: DABT (current EL), IL = 32 bits --[ 93.048377] SET = 0, FnV = 0 --[ 93.053840] EA = 0, S1PTW = 0 --[ 93.056704] FSC = 0x05: level 1 translation fault --[ 93.059745] Data abort info: --[ 93.064603] ISV = 0, ISS = 0x00000045 --[ 93.067729] CM = 0, WnR = 1 --[ 93.071287] swapper pgtable: 4k pages, 48-bit VAs, pgdp=0000000042219000 --[ 93.074409] [ffff800100a00000] pgd=100000007ffff003, p4d=100000007ffff003, pud=0000000000000000 --[ 93.081195] Internal error: Oops: 0000000096000045 [#1] PREEMPT SMP --[ 93.089598] Modules linked in: ath11k_ahb ath11k_pci ath11k qmi_helpers --[ 93.095851] CPU: 2 PID: 66 Comm: kworker/u8:3 Not tainted 6.1.0-rc8-wt-ath-658126-g58e4b9df840c-dirty #2 --[ 93.102454] Hardware name: Qualcomm Technologies, Inc. IPQ8074/AP-HK14 (DT) --[ 93.112171] Workqueue: ath11k_qmi_driver_event ath11k_qmi_driver_event_work [ath11k] --[ 93.118856] pstate: 40000005 (nZcv daif -PAN -UAO -TCO -DIT -SSBS BTYPE=--) --[ 93.126838] pc : ath11k_ahb_write32+0xc/0x18 [ath11k_ahb] --[ 93.133520] lr : ath11k_hal_srng_setup+0x860/0x8f0 [ath11k] --[ 93.139075] sp : ffff80000aaebb70 --[ 93.144452] x29: ffff80000aaebb70 x28: 0000000000000020 x27: ffff80000aaebc50 --[ 93.147934] x26: ffff000004923750 x25: ffff000004921200 x24: ffff000004928000 --[ 93.155051] x23: 0000000000000020 x22: ffff000004930000 x21: ffff000004923200 --[ 93.162170] x20: ffff000004920000 x19: 00000000eea00000 x18: ffff0000049200f0 --[ 93.169288] x17: 0000000000000000 x16: 0000000000000000 x15: 000000000000025e --[ 93.176405] x14: ffff000003c414f0 x13: 0000000000000000 x12: 0000000000000008 --[ 93.183524] x11: ffff000003c41488 x10: 0000000000000040 x9 : 0000000000000000 --[ 93.190641] x8 : ffff80000a9dd100 x7 : 0000000000000000 x6 : 000000000000003f --[ 93.197759] x5 : ffff800100a00400 x4 : ffff8000031f4018 x3 : 0000000000000004 --[ 93.204877] x2 : 0000000047b62000 x1 : ffff800100a00000 x0 : ffff800012000000 --[ 93.211996] Call trace: --[ 93.219104] ath11k_ahb_write32+0xc/0x18 [ath11k_ahb] --[ 93.221366] ath11k_ce_init_ring+0x184/0x278 [ath11k] --[ 93.226576] ath11k_ce_init_pipes+0x4c/0x1a0 [ath11k] --[ 93.231610] ath11k_core_qmi_firmware_ready+0x3c/0x568 [ath11k] --[ 93.236646] ath11k_qmi_driver_event_work+0x168/0x4f8 [ath11k] --[ 93.242376] process_one_work+0x144/0x350 --[ 93.248275] worker_thread+0x120/0x430 --[ 93.252352] kthread+0xf4/0x110 --[ 93.255997] ret_from_fork+0x10/0x20 --[ 93.259043] Code: d503201f f94e1c00 8b214001 d50332bf (b9000022) --[ 93.262863] ---[ end trace 0000000000000000 ]--- -- --However, for the device IPQ5018 ath11k_hw_params .ce_remap is --defined. This parameter is used to recalculate ab->mem_ce and hence, --this issue is not seen in IPQ5018. -- --Hence, fix this by initializing ab->mem_ce after ab->mem is set. --ab->mem is set inside the ath11k_ahb_setup_resources() therefore --initialize ab->mem_ce after ath11k_ahb_setup_resources(). -- --Tested-on: IPQ8074 hw2.0 AHB WLAN.HK.2.7.0.1-01744-QCAHKSWPL_SILICONZ-1 -- --Fixes: b42b3678c91f ("wifi: ath11k: remap ce register space for IPQ5018") -- --Signed-off-by: Raj Kumar Bhagat --Signed-off-by: Kalle Valo --Link: https://lore.kernel.org/r/20230113063209.7256-1-quic_rajkbhag@quicinc.com ----- -- drivers/net/wireless/ath/ath11k/ahb.c | 12 ++++++------ -- 1 file changed, 6 insertions(+), 6 deletions(-) -- ----- a/drivers/net/wireless/ath/ath11k/ahb.c --+++ b/drivers/net/wireless/ath/ath11k/ahb.c --@@ -1157,12 +1157,16 @@ static int ath11k_ahb_probe(struct platf -- goto err_core_free; -- } -- --- ab->mem_ce = ab->mem; --- -- ret = ath11k_core_pre_init(ab); -- if (ret) -- goto err_core_free; -- --+ ret = ath11k_ahb_setup_resources(ab); --+ if (ret) --+ goto err_core_free; --+ --+ ab->mem_ce = ab->mem; --+ -- if (ab->hw_params.ce_remap) { -- const struct ce_remap *ce_remap = ab->hw_params.ce_remap; -- /* ce register space is moved out of wcss unlike ipq8074 or ipq6018 --@@ -1177,10 +1181,6 @@ static int ath11k_ahb_probe(struct platf -- } -- } -- --- ret = ath11k_ahb_setup_resources(ab); --- if (ret) --- goto err_core_free; --- -- ret = ath11k_ahb_fw_resources_init(ab); -- if (ret) -- goto err_core_free; -diff --git a/package/kernel/mac80211/patches/ath11k/0033-wifi-ath11k-Set-ext-passive-scan-flag-to-adjust-pass.patch b/package/kernel/mac80211/patches/ath11k/0033-wifi-ath11k-Set-ext-passive-scan-flag-to-adjust-pass.patch -deleted file mode 100644 -index 79b79e1053..0000000000 ---- a/package/kernel/mac80211/patches/ath11k/0033-wifi-ath11k-Set-ext-passive-scan-flag-to-adjust-pass.patch -+++ /dev/null -@@ -1,73 +0,0 @@ --From cf8f3d4deb02a8fdc806c46d4112b69868544697 Mon Sep 17 00:00:00 2001 --From: Tamizh Chelvam Raja --Date: Wed, 15 Feb 2023 20:31:36 +0200 --Subject: [PATCH] wifi: ath11k: Set ext passive scan flag to adjust passive -- scan start time -- --Set the WMI_SCAN_FLAG_EXT_PASSIVE_SCAN_START_TIME_ENHANCE flag --while sending the scan command. If this flag is enabled when the --incoming scan request comes with a strict start time and its duration --overlaps with next TBTT, then target adjust the start time accordingly --for passive scan. Target supporting this feature will advertise --WMI_TLV_SERVICE_PASSIVE_SCAN_START_TIME_ENHANCE. -- --Tested-on: IPQ8074 hw2.0 AHB WLAN.HK.2.4.0.1-01467-QCAHKSWPL_SILICONZ-1 -- --Signed-off-by: Tamizh Chelvam Raja --Signed-off-by: Kalle Valo --Link: https://lore.kernel.org/r/20221222131720.11368-1-quic_tamizhr@quicinc.com ----- -- drivers/net/wireless/ath/ath11k/wmi.c | 8 ++++++++ -- drivers/net/wireless/ath/ath11k/wmi.h | 3 +++ -- 2 files changed, 11 insertions(+) -- ----- a/drivers/net/wireless/ath/ath11k/wmi.c --+++ b/drivers/net/wireless/ath/ath11k/wmi.c --@@ -2068,6 +2068,12 @@ void ath11k_wmi_start_scan_init(struct a -- WMI_SCAN_EVENT_FOREIGN_CHAN | -- WMI_SCAN_EVENT_DEQUEUED; -- arg->scan_flags |= WMI_SCAN_CHAN_STAT_EVENT; --+ --+ if (test_bit(WMI_TLV_SERVICE_PASSIVE_SCAN_START_TIME_ENHANCE, --+ ar->ab->wmi_ab.svc_map)) --+ arg->scan_ctrl_flags_ext |= --+ WMI_SCAN_FLAG_EXT_PASSIVE_SCAN_START_TIME_ENHANCE; --+ -- arg->num_bssid = 1; -- -- /* fill bssid_list[0] with 0xff, otherwise bssid and RA will be --@@ -2149,6 +2155,8 @@ ath11k_wmi_copy_scan_event_cntrl_flags(s -- /* for adaptive scan mode using 3 bits (21 - 23 bits) */ -- WMI_SCAN_SET_DWELL_MODE(cmd->scan_ctrl_flags, -- param->adaptive_dwell_time_mode); --+ --+ cmd->scan_ctrl_flags_ext = param->scan_ctrl_flags_ext; -- } -- -- int ath11k_wmi_send_scan_start_cmd(struct ath11k *ar, ----- a/drivers/net/wireless/ath/ath11k/wmi.h --+++ b/drivers/net/wireless/ath/ath11k/wmi.h --@@ -2093,6 +2093,7 @@ enum wmi_tlv_service { -- WMI_TLV_SERVICE_EXT2_MSG = 220, -- WMI_TLV_SERVICE_PEER_POWER_SAVE_DURATION_SUPPORT = 246, -- WMI_TLV_SERVICE_SRG_SRP_SPATIAL_REUSE_SUPPORT = 249, --+ WMI_TLV_SERVICE_PASSIVE_SCAN_START_TIME_ENHANCE = 263, -- -- /* The second 128 bits */ -- WMI_MAX_EXT_SERVICE = 256, --@@ -3223,6 +3224,7 @@ struct wmi_start_scan_cmd { -- -- #define WMI_SCAN_DWELL_MODE_MASK 0x00E00000 -- #define WMI_SCAN_DWELL_MODE_SHIFT 21 --+#define WMI_SCAN_FLAG_EXT_PASSIVE_SCAN_START_TIME_ENHANCE 0x00000800 -- -- enum { -- WMI_SCAN_DWELL_MODE_DEFAULT = 0, --@@ -3270,6 +3272,7 @@ struct scan_req_params { -- }; -- u32 scan_events; -- }; --+ u32 scan_ctrl_flags_ext; -- u32 dwell_time_active; -- u32 dwell_time_active_2g; -- u32 dwell_time_passive; -diff --git a/package/kernel/mac80211/patches/ath11k/0034-wifi-ath11k-fix-return-value-check-in-ath11k_ahb_pro.patch b/package/kernel/mac80211/patches/ath11k/0034-wifi-ath11k-fix-return-value-check-in-ath11k_ahb_pro.patch -deleted file mode 100644 -index 59132913bd..0000000000 ---- a/package/kernel/mac80211/patches/ath11k/0034-wifi-ath11k-fix-return-value-check-in-ath11k_ahb_pro.patch -+++ /dev/null -@@ -1,27 +0,0 @@ --From 342fcde9d91460f01f65707e16368a1571271a3a Mon Sep 17 00:00:00 2001 --From: Yang Yingliang --Date: Fri, 17 Feb 2023 11:00:31 +0800 --Subject: [PATCH] wifi: ath11k: fix return value check in ath11k_ahb_probe() -- --ioremap() returns NULL pointer not PTR_ERR() when it fails, --so replace the IS_ERR() check with NULL pointer check. -- --Fixes: b42b3678c91f ("wifi: ath11k: remap ce register space for IPQ5018") --Signed-off-by: Yang Yingliang --Signed-off-by: Kalle Valo --Link: https://lore.kernel.org/r/20230217030031.4021289-1-yangyingliang@huawei.com ----- -- drivers/net/wireless/ath/ath11k/ahb.c | 2 +- -- 1 file changed, 1 insertion(+), 1 deletion(-) -- ----- a/drivers/net/wireless/ath/ath11k/ahb.c --+++ b/drivers/net/wireless/ath/ath11k/ahb.c --@@ -1174,7 +1174,7 @@ static int ath11k_ahb_probe(struct platf -- * to a new space for accessing them. -- */ -- ab->mem_ce = ioremap(ce_remap->base, ce_remap->size); --- if (IS_ERR(ab->mem_ce)) { --+ if (!ab->mem_ce) { -- dev_err(&pdev->dev, "ce ioremap error\n"); -- ret = -ENOMEM; -- goto err_core_free; -diff --git a/package/kernel/mac80211/patches/ath11k/0035-wifi-ath11k-Use-platform_get_irq-to-get-the-interrup.patch b/package/kernel/mac80211/patches/ath11k/0035-wifi-ath11k-Use-platform_get_irq-to-get-the-interrup.patch -deleted file mode 100644 -index 93a9da8fc2..0000000000 ---- a/package/kernel/mac80211/patches/ath11k/0035-wifi-ath11k-Use-platform_get_irq-to-get-the-interrup.patch -+++ /dev/null -@@ -1,50 +0,0 @@ --From f117276638b7600b981b3fe28550823cfbe1ef23 Mon Sep 17 00:00:00 2001 --From: Douglas Anderson --Date: Wed, 1 Feb 2023 08:54:42 -0800 --Subject: [PATCH] wifi: ath11k: Use platform_get_irq() to get the interrupt -- --As of commit a1a2b7125e10 ("of/platform: Drop static setup of IRQ --resource from DT core"), we need to use platform_get_irq() instead of --platform_get_resource() to get our IRQs because --platform_get_resource() simply won't get them anymore. -- --This was already fixed in several other Atheros WiFi drivers, --apparently in response to Zeal Robot reports. An example of another --fix is commit 9503a1fc123d ("ath9k: Use platform_get_irq() to get the --interrupt"). ath11k seems to have been missed in this effort, though. -- --Without this change, WiFi wasn't coming up on my Qualcomm sc7280-based --hardware. Specifically, "platform_get_resource(pdev, IORESOURCE_IRQ, --i)" was failing even for i=0. -- --Tested-on: WCN6750 hw1.0 AHB WLAN.MSL.1.0.1-00887-QCAMSLSWPLZ-1 -- --Fixes: a1a2b7125e10 ("of/platform: Drop static setup of IRQ resource from DT core") --Fixes: 00402f49d26f ("ath11k: Add support for WCN6750 device") --Signed-off-by: Douglas Anderson --Tested-by: Jun Yu --Reviewed-by: Lad Prabhakar --Signed-off-by: Kalle Valo --Link: https://lore.kernel.org/r/20230201084131.v2.1.I69cf3d56c97098287fe3a70084ee515098390b70@changeid ----- -- drivers/net/wireless/ath/ath11k/ahb.c | 8 ++++---- -- 1 file changed, 4 insertions(+), 4 deletions(-) -- ----- a/drivers/net/wireless/ath/ath11k/ahb.c --+++ b/drivers/net/wireless/ath/ath11k/ahb.c --@@ -874,11 +874,11 @@ static int ath11k_ahb_setup_msi_resource -- ab->pci.msi.ep_base_data = int_prop + 32; -- -- for (i = 0; i < ab->pci.msi.config->total_vectors; i++) { --- res = platform_get_resource(pdev, IORESOURCE_IRQ, i); --- if (!res) --- return -ENODEV; --+ ret = platform_get_irq(pdev, i); --+ if (ret < 0) --+ return ret; -- --- ab->pci.msi.irqs[i] = res->start; --+ ab->pci.msi.irqs[i] = ret; -- } -- -- set_bit(ATH11K_FLAG_MULTI_MSI_VECTORS, &ab->dev_flags); -diff --git a/package/kernel/mac80211/patches/ath11k/0036-wifi-ath11k-fix-SAC-bug-on-peer-addition-with-sta-ba.patch b/package/kernel/mac80211/patches/ath11k/0036-wifi-ath11k-fix-SAC-bug-on-peer-addition-with-sta-ba.patch -deleted file mode 100644 -index b37f070ba6..0000000000 ---- a/package/kernel/mac80211/patches/ath11k/0036-wifi-ath11k-fix-SAC-bug-on-peer-addition-with-sta-ba.patch -+++ /dev/null -@@ -1,53 +0,0 @@ --From 60b7d62ba8cdbd073997bff0f1cdae8d844002c0 Mon Sep 17 00:00:00 2001 --From: Christian Marangi --Date: Thu, 9 Feb 2023 23:26:22 +0100 --Subject: [PATCH] wifi: ath11k: fix SAC bug on peer addition with sta band -- migration -- --Fix sleep in atomic context warning detected by Smatch static checker --analyzer. -- --Following the locking pattern for peer_rhash_add lock tbl_mtx_lock mutex --always even if sta is not transitioning to another band. --This is peer_add function and a more secure locking should not cause --performance regression. -- --Tested-on: IPQ8074 hw2.0 AHB WLAN.HK.2.5.0.1-01208-QCAHKSWPL_SILICONZ-1 -- --Fixes: d673cb6fe6c0 ("wifi: ath11k: fix peer addition/deletion error on sta band migration") --Reported-by: Dan Carpenter --Signed-off-by: Christian Marangi --Signed-off-by: Kalle Valo --Link: https://lore.kernel.org/r/20230209222622.1751-1-ansuelsmth@gmail.com ----- -- drivers/net/wireless/ath/ath11k/peer.c | 5 +++-- -- 1 file changed, 3 insertions(+), 2 deletions(-) -- ----- a/drivers/net/wireless/ath/ath11k/peer.c --+++ b/drivers/net/wireless/ath/ath11k/peer.c --@@ -382,22 +382,23 @@ int ath11k_peer_create(struct ath11k *ar -- return -ENOBUFS; -- } -- --+ mutex_lock(&ar->ab->tbl_mtx_lock); -- spin_lock_bh(&ar->ab->base_lock); -- peer = ath11k_peer_find_by_addr(ar->ab, param->peer_addr); -- if (peer) { -- if (peer->vdev_id == param->vdev_id) { -- spin_unlock_bh(&ar->ab->base_lock); --+ mutex_unlock(&ar->ab->tbl_mtx_lock); -- return -EINVAL; -- } -- -- /* Assume sta is transitioning to another band. -- * Remove here the peer from rhash. -- */ --- mutex_lock(&ar->ab->tbl_mtx_lock); -- ath11k_peer_rhash_delete(ar->ab, peer); --- mutex_unlock(&ar->ab->tbl_mtx_lock); -- } -- spin_unlock_bh(&ar->ab->base_lock); --+ mutex_unlock(&ar->ab->tbl_mtx_lock); -- -- ret = ath11k_wmi_send_peer_create_cmd(ar, param); -- if (ret) { -diff --git a/package/kernel/mac80211/patches/ath11k/0037-wifi-ath11k-allow-system-suspend-to-survive-ath11k.patch b/package/kernel/mac80211/patches/ath11k/0037-wifi-ath11k-allow-system-suspend-to-survive-ath11k.patch -deleted file mode 100644 -index fa680954e6..0000000000 ---- a/package/kernel/mac80211/patches/ath11k/0037-wifi-ath11k-allow-system-suspend-to-survive-ath11k.patch -+++ /dev/null -@@ -1,43 +0,0 @@ --From 7c15430822e71e90203d87e6d0cfe83fa058b0dc Mon Sep 17 00:00:00 2001 --From: Len Brown --Date: Wed, 1 Feb 2023 12:32:01 -0600 --Subject: [PATCH] wifi: ath11k: allow system suspend to survive ath11k -- --When ath11k runs into internal errors upon suspend, --it returns an error code to pci_pm_suspend, which --aborts the entire system suspend. -- --The driver should not abort system suspend, but should --keep its internal errors to itself, and allow the system --to suspend. Otherwise, a user can suspend a laptop --by closing the lid and sealing it into a case, assuming --that is will suspend, rather than heating up and draining --the battery when in transit. -- --In practice, the ath11k device seems to have plenty of transient --errors, and subsequent suspend cycles after this failure --often succeed. -- --https://bugzilla.kernel.org/show_bug.cgi?id=216968 -- --Fixes: d1b0c33850d29 ("ath11k: implement suspend for QCA6390 PCI devices") -- --Signed-off-by: Len Brown --Cc: stable@vger.kernel.org --Signed-off-by: Kalle Valo --Link: https://lore.kernel.org/r/20230201183201.14431-1-len.brown@intel.com ----- -- drivers/net/wireless/ath/ath11k/pci.c | 2 +- -- 1 file changed, 1 insertion(+), 1 deletion(-) -- ----- a/drivers/net/wireless/ath/ath11k/pci.c --+++ b/drivers/net/wireless/ath/ath11k/pci.c --@@ -998,7 +998,7 @@ static __maybe_unused int ath11k_pci_pm_ -- if (ret) -- ath11k_warn(ab, "failed to resume core: %d\n", ret); -- --- return ret; --+ return 0; -- } -- -- static SIMPLE_DEV_PM_OPS(ath11k_pci_pm_ops, -diff --git a/package/kernel/mac80211/patches/ath11k/0038-wifi-ath11k-modify-accessor-macros-to-match-index-si.patch b/package/kernel/mac80211/patches/ath11k/0038-wifi-ath11k-modify-accessor-macros-to-match-index-si.patch -deleted file mode 100644 -index 42bf170a03..0000000000 ---- a/package/kernel/mac80211/patches/ath11k/0038-wifi-ath11k-modify-accessor-macros-to-match-index-si.patch -+++ /dev/null -@@ -1,61 +0,0 @@ --From a96f10422e74cde27c100b321b127ec32ae75747 Mon Sep 17 00:00:00 2001 --From: Muna Sinada --Date: Fri, 24 Feb 2023 12:28:03 +0200 --Subject: [PATCH] wifi: ath11k: modify accessor macros to match index size -- --HE PHY is only 11 bytes, therefore it should be using byte indexes --instead of dword. Change corresponding macros to reflect this. -- --Signed-off-by: Muna Sinada --Signed-off-by: Kalle Valo --Link: https://lore.kernel.org/r/1666128501-12364-2-git-send-email-quic_msinada@quicinc.com ----- -- drivers/net/wireless/ath/ath11k/wmi.h | 24 +++++++++++++----------- -- 1 file changed, 13 insertions(+), 11 deletions(-) -- ----- a/drivers/net/wireless/ath/ath11k/wmi.h --+++ b/drivers/net/wireless/ath/ath11k/wmi.h --@@ -2859,30 +2859,32 @@ struct rx_reorder_queue_remove_params { -- #define WMI_VDEV_PARAM_TXBF_SU_TX_BFER BIT(2) -- #define WMI_VDEV_PARAM_TXBF_MU_TX_BFER BIT(3) -- ---#define HECAP_PHYDWORD_0 0 ---#define HECAP_PHYDWORD_1 1 ---#define HECAP_PHYDWORD_2 2 --+#define HE_PHYCAP_BYTE_0 0 --+#define HE_PHYCAP_BYTE_1 1 --+#define HE_PHYCAP_BYTE_2 2 --+#define HE_PHYCAP_BYTE_3 3 --+#define HE_PHYCAP_BYTE_4 4 -- ---#define HECAP_PHY_SU_BFER BIT(31) --+#define HECAP_PHY_SU_BFER BIT(7) -- #define HECAP_PHY_SU_BFEE BIT(0) -- #define HECAP_PHY_MU_BFER BIT(1) ---#define HECAP_PHY_UL_MUMIMO BIT(22) ---#define HECAP_PHY_UL_MUOFDMA BIT(23) --+#define HECAP_PHY_UL_MUMIMO BIT(6) --+#define HECAP_PHY_UL_MUOFDMA BIT(7) -- -- #define HECAP_PHY_SUBFMR_GET(hecap_phy) \ --- FIELD_GET(HECAP_PHY_SU_BFER, hecap_phy[HECAP_PHYDWORD_0]) --+ FIELD_GET(HECAP_PHY_SU_BFER, hecap_phy[HE_PHYCAP_BYTE_3]) -- -- #define HECAP_PHY_SUBFME_GET(hecap_phy) \ --- FIELD_GET(HECAP_PHY_SU_BFEE, hecap_phy[HECAP_PHYDWORD_1]) --+ FIELD_GET(HECAP_PHY_SU_BFEE, hecap_phy[HE_PHYCAP_BYTE_4]) -- -- #define HECAP_PHY_MUBFMR_GET(hecap_phy) \ --- FIELD_GET(HECAP_PHY_MU_BFER, hecap_phy[HECAP_PHYDWORD_1]) --+ FIELD_GET(HECAP_PHY_MU_BFER, hecap_phy[HE_PHYCAP_BYTE_4]) -- -- #define HECAP_PHY_ULMUMIMO_GET(hecap_phy) \ --- FIELD_GET(HECAP_PHY_UL_MUMIMO, hecap_phy[HECAP_PHYDWORD_0]) --+ FIELD_GET(HECAP_PHY_UL_MUMIMO, hecap_phy[HE_PHYCAP_BYTE_2]) -- -- #define HECAP_PHY_ULOFDMA_GET(hecap_phy) \ --- FIELD_GET(HECAP_PHY_UL_MUOFDMA, hecap_phy[HECAP_PHYDWORD_0]) --+ FIELD_GET(HECAP_PHY_UL_MUOFDMA, hecap_phy[HE_PHYCAP_BYTE_2]) -- -- #define HE_MODE_SU_TX_BFEE BIT(0) -- #define HE_MODE_SU_TX_BFER BIT(1) -diff --git a/package/kernel/mac80211/patches/ath11k/0039-wifi-ath11k-push-MU-MIMO-params-from-hostapd-to-hard.patch b/package/kernel/mac80211/patches/ath11k/0039-wifi-ath11k-push-MU-MIMO-params-from-hostapd-to-hard.patch -deleted file mode 100644 -index 298ce1a612..0000000000 ---- a/package/kernel/mac80211/patches/ath11k/0039-wifi-ath11k-push-MU-MIMO-params-from-hostapd-to-hard.patch -+++ /dev/null -@@ -1,300 +0,0 @@ --From 38dfe775d0abf511341f37c1cb77b919a3ad410b Mon Sep 17 00:00:00 2001 --From: Muna Sinada --Date: Fri, 24 Feb 2023 12:28:04 +0200 --Subject: [PATCH] wifi: ath11k: push MU-MIMO params from hostapd to hardware -- --In the previous behaviour only HE IE in management frames are changed --regarding MU-MIMO configurations and not in hardware. Adding push of --MU-MIMO configurations to the hardware as well. -- --Tested-on: IPQ8074 hw2.0 AHB WLAN.HK.2.4.0.1-00356-QCAHKSWPL_SILICONZ-1 -- --Co-developed-by: Anilkumar Kolli --Signed-off-by: Anilkumar Kolli --Signed-off-by: Muna Sinada --Signed-off-by: Kalle Valo --Link: https://lore.kernel.org/r/1666128501-12364-3-git-send-email-quic_msinada@quicinc.com ----- -- drivers/net/wireless/ath/ath11k/mac.c | 200 ++++++++++++++++---------- -- drivers/net/wireless/ath/ath11k/wmi.h | 3 + -- 2 files changed, 130 insertions(+), 73 deletions(-) -- ----- a/drivers/net/wireless/ath/ath11k/mac.c --+++ b/drivers/net/wireless/ath/ath11k/mac.c --@@ -2699,6 +2699,117 @@ static int ath11k_setup_peer_smps(struct -- ath11k_smps_map[smps]); -- } -- --+static bool ath11k_mac_set_he_txbf_conf(struct ath11k_vif *arvif) --+{ --+ struct ath11k *ar = arvif->ar; --+ u32 param, value; --+ int ret; --+ --+ if (!arvif->vif->bss_conf.he_support) --+ return true; --+ --+ param = WMI_VDEV_PARAM_SET_HEMU_MODE; --+ value = 0; --+ if (arvif->vif->bss_conf.he_su_beamformer) { --+ value |= FIELD_PREP(HE_MODE_SU_TX_BFER, HE_SU_BFER_ENABLE); --+ if (arvif->vif->bss_conf.he_mu_beamformer && --+ arvif->vdev_type == WMI_VDEV_TYPE_AP) --+ value |= FIELD_PREP(HE_MODE_MU_TX_BFER, HE_MU_BFER_ENABLE); --+ } --+ --+ if (arvif->vif->type != NL80211_IFTYPE_MESH_POINT) { --+ value |= FIELD_PREP(HE_MODE_DL_OFDMA, HE_DL_MUOFDMA_ENABLE) | --+ FIELD_PREP(HE_MODE_UL_OFDMA, HE_UL_MUOFDMA_ENABLE); --+ --+ if (arvif->vif->bss_conf.he_full_ul_mumimo) --+ value |= FIELD_PREP(HE_MODE_UL_MUMIMO, HE_UL_MUMIMO_ENABLE); --+ --+ if (arvif->vif->bss_conf.he_su_beamformee) --+ value |= FIELD_PREP(HE_MODE_SU_TX_BFEE, HE_SU_BFEE_ENABLE); --+ } --+ --+ ret = ath11k_wmi_vdev_set_param_cmd(ar, arvif->vdev_id, param, value); --+ if (ret) { --+ ath11k_warn(ar->ab, "failed to set vdev %d HE MU mode: %d\n", --+ arvif->vdev_id, ret); --+ return false; --+ } --+ --+ param = WMI_VDEV_PARAM_SET_HE_SOUNDING_MODE; --+ value = FIELD_PREP(HE_VHT_SOUNDING_MODE, HE_VHT_SOUNDING_MODE_ENABLE) | --+ FIELD_PREP(HE_TRIG_NONTRIG_SOUNDING_MODE, --+ HE_TRIG_NONTRIG_SOUNDING_MODE_ENABLE); --+ ret = ath11k_wmi_vdev_set_param_cmd(ar, arvif->vdev_id, --+ param, value); --+ if (ret) { --+ ath11k_warn(ar->ab, "failed to set vdev %d sounding mode: %d\n", --+ arvif->vdev_id, ret); --+ return false; --+ } --+ return true; --+} --+ --+static bool ath11k_mac_vif_recalc_sta_he_txbf(struct ath11k *ar, --+ struct ieee80211_vif *vif, --+ struct ieee80211_sta_he_cap *he_cap) --+{ --+ struct ath11k_vif *arvif = (void *)vif->drv_priv; --+ struct ieee80211_he_cap_elem he_cap_elem = {0}; --+ struct ieee80211_sta_he_cap *cap_band = NULL; --+ struct cfg80211_chan_def def; --+ u32 param = WMI_VDEV_PARAM_SET_HEMU_MODE; --+ u32 hemode = 0; --+ int ret; --+ --+ if (!vif->bss_conf.he_support) --+ return true; --+ --+ if (vif->type != NL80211_IFTYPE_STATION) --+ return false; --+ --+ if (WARN_ON(ath11k_mac_vif_chan(vif, &def))) --+ return false; --+ --+ if (def.chan->band == NL80211_BAND_2GHZ) --+ cap_band = &ar->mac.iftype[NL80211_BAND_2GHZ][vif->type].he_cap; --+ else --+ cap_band = &ar->mac.iftype[NL80211_BAND_5GHZ][vif->type].he_cap; --+ --+ memcpy(&he_cap_elem, &cap_band->he_cap_elem, sizeof(he_cap_elem)); --+ --+ if (HECAP_PHY_SUBFME_GET(he_cap_elem.phy_cap_info)) { --+ if (HECAP_PHY_SUBFMR_GET(he_cap->he_cap_elem.phy_cap_info)) --+ hemode |= FIELD_PREP(HE_MODE_SU_TX_BFEE, HE_SU_BFEE_ENABLE); --+ if (HECAP_PHY_MUBFMR_GET(he_cap->he_cap_elem.phy_cap_info)) --+ hemode |= FIELD_PREP(HE_MODE_MU_TX_BFEE, HE_MU_BFEE_ENABLE); --+ } --+ --+ if (vif->type != NL80211_IFTYPE_MESH_POINT) { --+ hemode |= FIELD_PREP(HE_MODE_DL_OFDMA, HE_DL_MUOFDMA_ENABLE) | --+ FIELD_PREP(HE_MODE_UL_OFDMA, HE_UL_MUOFDMA_ENABLE); --+ --+ if (HECAP_PHY_ULMUMIMO_GET(he_cap_elem.phy_cap_info)) --+ if (HECAP_PHY_ULMUMIMO_GET(he_cap->he_cap_elem.phy_cap_info)) --+ hemode |= FIELD_PREP(HE_MODE_UL_MUMIMO, --+ HE_UL_MUMIMO_ENABLE); --+ --+ if (FIELD_GET(HE_MODE_MU_TX_BFEE, hemode)) --+ hemode |= FIELD_PREP(HE_MODE_SU_TX_BFEE, HE_SU_BFEE_ENABLE); --+ --+ if (FIELD_GET(HE_MODE_MU_TX_BFER, hemode)) --+ hemode |= FIELD_PREP(HE_MODE_SU_TX_BFER, HE_SU_BFER_ENABLE); --+ } --+ --+ ret = ath11k_wmi_vdev_set_param_cmd(ar, arvif->vdev_id, param, hemode); --+ if (ret) { --+ ath11k_warn(ar->ab, "failed to submit vdev param txbf 0x%x: %d\n", --+ hemode, ret); --+ return false; --+ } --+ --+ return true; --+} --+ -- static void ath11k_bss_assoc(struct ieee80211_hw *hw, -- struct ieee80211_vif *vif, -- struct ieee80211_bss_conf *bss_conf) --@@ -2709,6 +2820,7 @@ static void ath11k_bss_assoc(struct ieee -- struct ieee80211_sta *ap_sta; -- struct ath11k_peer *peer; -- bool is_auth = false; --+ struct ieee80211_sta_he_cap he_cap; -- int ret; -- -- lockdep_assert_held(&ar->conf_mutex); --@@ -2726,6 +2838,9 @@ static void ath11k_bss_assoc(struct ieee -- return; -- } -- --+ /* he_cap here is updated at assoc success for sta mode only */ --+ he_cap = ap_sta->deflink.he_cap; --+ -- ath11k_peer_assoc_prepare(ar, vif, ap_sta, &peer_arg, false); -- -- rcu_read_unlock(); --@@ -2753,6 +2868,12 @@ static void ath11k_bss_assoc(struct ieee -- return; -- } -- --+ if (!ath11k_mac_vif_recalc_sta_he_txbf(ar, vif, &he_cap)) { --+ ath11k_warn(ar->ab, "failed to recalc he txbf for vdev %i on bss %pM\n", --+ arvif->vdev_id, bss_conf->bssid); --+ return; --+ } --+ -- WARN_ON(arvif->is_up); -- -- arvif->aid = vif->cfg.aid; --@@ -3202,6 +3323,8 @@ static void ath11k_mac_op_bss_info_chang -- ether_addr_copy(arvif->bssid, info->bssid); -- -- if (changed & BSS_CHANGED_BEACON_ENABLED) { --+ if (info->enable_beacon) --+ ath11k_mac_set_he_txbf_conf(arvif); -- ath11k_control_beaconing(arvif, info); -- -- if (arvif->is_up && vif->bss_conf.he_support && --@@ -5392,6 +5515,10 @@ static int ath11k_mac_copy_he_cap(struct -- -- he_cap_elem->mac_cap_info[1] &= -- IEEE80211_HE_MAC_CAP1_TF_MAC_PAD_DUR_MASK; --+ he_cap_elem->phy_cap_info[0] &= --+ ~IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_160MHZ_IN_5G; --+ he_cap_elem->phy_cap_info[0] &= --+ ~IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_80PLUS80_MHZ_IN_5G; -- -- he_cap_elem->phy_cap_info[5] &= -- ~IEEE80211_HE_PHY_CAP5_BEAMFORMEE_NUM_SND_DIM_UNDER_80MHZ_MASK; --@@ -6026,69 +6153,6 @@ ath11k_mac_setup_vdev_create_params(stru -- } -- } -- ---static u32 ---ath11k_mac_prepare_he_mode(struct ath11k_pdev *pdev, u32 viftype) ---{ --- struct ath11k_pdev_cap *pdev_cap = &pdev->cap; --- struct ath11k_band_cap *cap_band = NULL; --- u32 *hecap_phy_ptr = NULL; --- u32 hemode = 0; --- --- if (pdev->cap.supported_bands & WMI_HOST_WLAN_2G_CAP) --- cap_band = &pdev_cap->band[NL80211_BAND_2GHZ]; --- else --- cap_band = &pdev_cap->band[NL80211_BAND_5GHZ]; --- --- hecap_phy_ptr = &cap_band->he_cap_phy_info[0]; --- --- hemode = FIELD_PREP(HE_MODE_SU_TX_BFEE, HE_SU_BFEE_ENABLE) | --- FIELD_PREP(HE_MODE_SU_TX_BFER, HECAP_PHY_SUBFMR_GET(hecap_phy_ptr)) | --- FIELD_PREP(HE_MODE_UL_MUMIMO, HECAP_PHY_ULMUMIMO_GET(hecap_phy_ptr)); --- --- /* TODO WDS and other modes */ --- if (viftype == NL80211_IFTYPE_AP) { --- hemode |= FIELD_PREP(HE_MODE_MU_TX_BFER, --- HECAP_PHY_MUBFMR_GET(hecap_phy_ptr)) | --- FIELD_PREP(HE_MODE_DL_OFDMA, HE_DL_MUOFDMA_ENABLE) | --- FIELD_PREP(HE_MODE_UL_OFDMA, HE_UL_MUOFDMA_ENABLE); --- } else { --- hemode |= FIELD_PREP(HE_MODE_MU_TX_BFEE, HE_MU_BFEE_ENABLE); --- } --- --- return hemode; ---} --- ---static int ath11k_set_he_mu_sounding_mode(struct ath11k *ar, --- struct ath11k_vif *arvif) ---{ --- u32 param_id, param_value; --- struct ath11k_base *ab = ar->ab; --- int ret = 0; --- --- param_id = WMI_VDEV_PARAM_SET_HEMU_MODE; --- param_value = ath11k_mac_prepare_he_mode(ar->pdev, arvif->vif->type); --- ret = ath11k_wmi_vdev_set_param_cmd(ar, arvif->vdev_id, --- param_id, param_value); --- if (ret) { --- ath11k_warn(ab, "failed to set vdev %d HE MU mode: %d param_value %x\n", --- arvif->vdev_id, ret, param_value); --- return ret; --- } --- param_id = WMI_VDEV_PARAM_SET_HE_SOUNDING_MODE; --- param_value = --- FIELD_PREP(HE_VHT_SOUNDING_MODE, HE_VHT_SOUNDING_MODE_ENABLE) | --- FIELD_PREP(HE_TRIG_NONTRIG_SOUNDING_MODE, --- HE_TRIG_NONTRIG_SOUNDING_MODE_ENABLE); --- ret = ath11k_wmi_vdev_set_param_cmd(ar, arvif->vdev_id, --- param_id, param_value); --- if (ret) { --- ath11k_warn(ab, "failed to set vdev %d HE MU mode: %d\n", --- arvif->vdev_id, ret); --- return ret; --- } --- return ret; ---} --- -- static void ath11k_mac_op_update_vif_offload(struct ieee80211_hw *hw, -- struct ieee80211_vif *vif) -- { --@@ -6757,7 +6821,6 @@ ath11k_mac_vdev_start_restart(struct ath -- struct ath11k_base *ab = ar->ab; -- struct wmi_vdev_start_req_arg arg = {}; -- const struct cfg80211_chan_def *chandef = &ctx->def; --- int he_support = arvif->vif->bss_conf.he_support; -- int ret = 0; -- -- lockdep_assert_held(&ar->conf_mutex); --@@ -6798,15 +6861,6 @@ ath11k_mac_vdev_start_restart(struct ath -- spin_lock_bh(&ab->base_lock); -- arg.regdomain = ar->ab->dfs_region; -- spin_unlock_bh(&ab->base_lock); --- --- if (he_support) { --- ret = ath11k_set_he_mu_sounding_mode(ar, arvif); --- if (ret) { --- ath11k_warn(ar->ab, "failed to set he mode vdev %i\n", --- arg.vdev_id); --- return ret; --- } --- } -- } -- -- arg.channel.passive |= !!(chandef->chan->flags & IEEE80211_CHAN_NO_IR); ----- a/drivers/net/wireless/ath/ath11k/wmi.h --+++ b/drivers/net/wireless/ath/ath11k/wmi.h --@@ -2897,8 +2897,11 @@ struct rx_reorder_queue_remove_params { -- #define HE_DL_MUOFDMA_ENABLE 1 -- #define HE_UL_MUOFDMA_ENABLE 1 -- #define HE_DL_MUMIMO_ENABLE 1 --+#define HE_UL_MUMIMO_ENABLE 1 -- #define HE_MU_BFEE_ENABLE 1 -- #define HE_SU_BFEE_ENABLE 1 --+#define HE_MU_BFER_ENABLE 1 --+#define HE_SU_BFER_ENABLE 1 -- -- #define HE_VHT_SOUNDING_MODE_ENABLE 1 -- #define HE_SU_MU_SOUNDING_MODE_ENABLE 1 -diff --git a/package/kernel/mac80211/patches/ath11k/0040-wifi-ath11k-move-HE-MCS-mapper-to-a-separate-functio.patch b/package/kernel/mac80211/patches/ath11k/0040-wifi-ath11k-move-HE-MCS-mapper-to-a-separate-functio.patch -deleted file mode 100644 -index 6bc9880e10..0000000000 ---- a/package/kernel/mac80211/patches/ath11k/0040-wifi-ath11k-move-HE-MCS-mapper-to-a-separate-functio.patch -+++ /dev/null -@@ -1,67 +0,0 @@ --From 8077c1bbbc28e527fb29143c46f32c6a9d6cadf0 Mon Sep 17 00:00:00 2001 --From: Muna Sinada --Date: Fri, 24 Feb 2023 12:28:04 +0200 --Subject: [PATCH] wifi: ath11k: move HE MCS mapper to a separate function -- --Move HE MCS mapper to a separate function and call new function --in ath11k_mac_copy_he_cap(). -- --Tested-on: IPQ8074 hw2.0 AHB WLAN.HK.2.4.0.1-00356-QCAHKSWPL_SILICONZ-1 -- --Signed-off-by: Muna Sinada --Signed-off-by: Kalle Valo --Link: https://lore.kernel.org/r/1666128501-12364-4-git-send-email-quic_msinada@quicinc.com ----- -- drivers/net/wireless/ath/ath11k/mac.c | 34 +++++++++++++++++---------- -- 1 file changed, 22 insertions(+), 12 deletions(-) -- ----- a/drivers/net/wireless/ath/ath11k/mac.c --+++ b/drivers/net/wireless/ath/ath11k/mac.c --@@ -5483,6 +5483,27 @@ static __le16 ath11k_mac_setup_he_6ghz_c -- return cpu_to_le16(bcap->he_6ghz_capa); -- } -- --+static void ath11k_mac_set_hemcsmap(struct ath11k *ar, --+ struct ath11k_pdev_cap *cap, --+ struct ieee80211_sta_he_cap *he_cap, --+ int band) --+{ --+ struct ath11k_band_cap *band_cap = &cap->band[band]; --+ --+ he_cap->he_mcs_nss_supp.rx_mcs_80 = --+ cpu_to_le16(band_cap->he_mcs & 0xffff); --+ he_cap->he_mcs_nss_supp.tx_mcs_80 = --+ cpu_to_le16(band_cap->he_mcs & 0xffff); --+ he_cap->he_mcs_nss_supp.rx_mcs_160 = --+ cpu_to_le16((band_cap->he_mcs >> 16) & 0xffff); --+ he_cap->he_mcs_nss_supp.tx_mcs_160 = --+ cpu_to_le16((band_cap->he_mcs >> 16) & 0xffff); --+ he_cap->he_mcs_nss_supp.rx_mcs_80p80 = --+ cpu_to_le16((band_cap->he_mcs >> 16) & 0xffff); --+ he_cap->he_mcs_nss_supp.tx_mcs_80p80 = --+ cpu_to_le16((band_cap->he_mcs >> 16) & 0xffff); --+} --+ -- static int ath11k_mac_copy_he_cap(struct ath11k *ar, -- struct ath11k_pdev_cap *cap, -- struct ieee80211_sband_iftype_data *data, --@@ -5544,18 +5565,7 @@ static int ath11k_mac_copy_he_cap(struct -- break; -- } -- --- he_cap->he_mcs_nss_supp.rx_mcs_80 = --- cpu_to_le16(band_cap->he_mcs & 0xffff); --- he_cap->he_mcs_nss_supp.tx_mcs_80 = --- cpu_to_le16(band_cap->he_mcs & 0xffff); --- he_cap->he_mcs_nss_supp.rx_mcs_160 = --- cpu_to_le16((band_cap->he_mcs >> 16) & 0xffff); --- he_cap->he_mcs_nss_supp.tx_mcs_160 = --- cpu_to_le16((band_cap->he_mcs >> 16) & 0xffff); --- he_cap->he_mcs_nss_supp.rx_mcs_80p80 = --- cpu_to_le16((band_cap->he_mcs >> 16) & 0xffff); --- he_cap->he_mcs_nss_supp.tx_mcs_80p80 = --- cpu_to_le16((band_cap->he_mcs >> 16) & 0xffff); --+ ath11k_mac_set_hemcsmap(ar, cap, he_cap, band); -- -- memset(he_cap->ppe_thres, 0, sizeof(he_cap->ppe_thres)); -- if (he_cap_elem->phy_cap_info[6] & -diff --git a/package/kernel/mac80211/patches/ath11k/0041-wifi-ath11k-generate-rx-and-tx-mcs-maps-for-supporte.patch b/package/kernel/mac80211/patches/ath11k/0041-wifi-ath11k-generate-rx-and-tx-mcs-maps-for-supporte.patch -deleted file mode 100644 -index 5cb7801b29..0000000000 ---- a/package/kernel/mac80211/patches/ath11k/0041-wifi-ath11k-generate-rx-and-tx-mcs-maps-for-supporte.patch -+++ /dev/null -@@ -1,64 +0,0 @@ --From ebf82988f844dd98e6b007cffcc5e95986056995 Mon Sep 17 00:00:00 2001 --From: Muna Sinada --Date: Fri, 24 Feb 2023 12:28:04 +0200 --Subject: [PATCH] wifi: ath11k: generate rx and tx mcs maps for supported HE -- mcs -- --Generate rx and tx mcs maps in ath11k_mac_set_hemcsmap() and set them --in supported mcs/nss for HE capabilities. -- --Tested-on: IPQ8074 hw2.0 AHB WLAN.HK.2.4.0.1-00356-QCAHKSWPL_SILICONZ-1 -- --Signed-off-by: Muna Sinada --Signed-off-by: Kalle Valo --Link: https://lore.kernel.org/r/1666128501-12364-5-git-send-email-quic_msinada@quicinc.com ----- -- drivers/net/wireless/ath/ath11k/mac.c | 30 ++++++++++++++++++++------- -- 1 file changed, 23 insertions(+), 7 deletions(-) -- ----- a/drivers/net/wireless/ath/ath11k/mac.c --+++ b/drivers/net/wireless/ath/ath11k/mac.c --@@ -5488,20 +5488,36 @@ static void ath11k_mac_set_hemcsmap(stru -- struct ieee80211_sta_he_cap *he_cap, -- int band) -- { --- struct ath11k_band_cap *band_cap = &cap->band[band]; --+ u16 txmcs_map, rxmcs_map; --+ u32 i; -- --+ rxmcs_map = 0; --+ txmcs_map = 0; --+ for (i = 0; i < 8; i++) { --+ if (i < ar->num_tx_chains && --+ (ar->cfg_tx_chainmask >> cap->tx_chain_mask_shift) & BIT(i)) --+ txmcs_map |= IEEE80211_HE_MCS_SUPPORT_0_11 << (i * 2); --+ else --+ txmcs_map |= IEEE80211_HE_MCS_NOT_SUPPORTED << (i * 2); --+ --+ if (i < ar->num_rx_chains && --+ (ar->cfg_rx_chainmask >> cap->tx_chain_mask_shift) & BIT(i)) --+ rxmcs_map |= IEEE80211_HE_MCS_SUPPORT_0_11 << (i * 2); --+ else --+ rxmcs_map |= IEEE80211_HE_MCS_NOT_SUPPORTED << (i * 2); --+ } -- he_cap->he_mcs_nss_supp.rx_mcs_80 = --- cpu_to_le16(band_cap->he_mcs & 0xffff); --+ cpu_to_le16(rxmcs_map & 0xffff); -- he_cap->he_mcs_nss_supp.tx_mcs_80 = --- cpu_to_le16(band_cap->he_mcs & 0xffff); --+ cpu_to_le16(txmcs_map & 0xffff); -- he_cap->he_mcs_nss_supp.rx_mcs_160 = --- cpu_to_le16((band_cap->he_mcs >> 16) & 0xffff); --+ cpu_to_le16(rxmcs_map & 0xffff); -- he_cap->he_mcs_nss_supp.tx_mcs_160 = --- cpu_to_le16((band_cap->he_mcs >> 16) & 0xffff); --+ cpu_to_le16(txmcs_map & 0xffff); -- he_cap->he_mcs_nss_supp.rx_mcs_80p80 = --- cpu_to_le16((band_cap->he_mcs >> 16) & 0xffff); --+ cpu_to_le16(rxmcs_map & 0xffff); -- he_cap->he_mcs_nss_supp.tx_mcs_80p80 = --- cpu_to_le16((band_cap->he_mcs >> 16) & 0xffff); --+ cpu_to_le16(txmcs_map & 0xffff); -- } -- -- static int ath11k_mac_copy_he_cap(struct ath11k *ar, -diff --git a/package/kernel/mac80211/patches/ath11k/0042-wifi-ath11k-Add-tx-ack-signal-support-for-management.patch b/package/kernel/mac80211/patches/ath11k/0042-wifi-ath11k-Add-tx-ack-signal-support-for-management.patch -deleted file mode 100644 -index 8d41657311..0000000000 ---- a/package/kernel/mac80211/patches/ath11k/0042-wifi-ath11k-Add-tx-ack-signal-support-for-management.patch -+++ /dev/null -@@ -1,150 +0,0 @@ --From 01c6c9fccbd51c1d9eab0f5794b0271b026178df Mon Sep 17 00:00:00 2001 --From: Abinaya Kalaiselvan --Date: Mon, 19 Dec 2022 11:08:44 +0530 --Subject: [PATCH] wifi: ath11k: Add tx ack signal support for management -- packets -- --Add support to notify tx ack signal values for management --packets to userspace through nl80211 interface. -- --Advertise NL80211_EXT_FEATURE_ACK_SIGNAL_SUPPORT flag --to enable this feature and it will be used for data --packets as well. -- --Tested-on: IPQ8074 hw2.0 AHB WLAN.HK.2.7.0.1-01744-QCAHKSWPL_SILICONZ-1 -- --Signed-off-by: Abinaya Kalaiselvan --Signed-off-by: Maharaja Kennadyrajan --Signed-off-by: Kalle Valo --Link: https://lore.kernel.org/r/20221219053844.4084486-1-quic_mkenna@quicinc.com ----- -- drivers/net/wireless/ath/ath11k/hw.c | 1 + -- drivers/net/wireless/ath/ath11k/mac.c | 5 +++++ -- drivers/net/wireless/ath/ath11k/wmi.c | 27 ++++++++++++++++----------- -- drivers/net/wireless/ath/ath11k/wmi.h | 3 +++ -- 4 files changed, 25 insertions(+), 11 deletions(-) -- ----- a/drivers/net/wireless/ath/ath11k/hw.c --+++ b/drivers/net/wireless/ath/ath11k/hw.c --@@ -201,6 +201,7 @@ static void ath11k_init_wmi_config_ipq80 -- config->twt_ap_pdev_count = ab->num_radios; -- config->twt_ap_sta_count = 1000; -- config->flag1 |= WMI_RSRC_CFG_FLAG1_BSS_CHANNEL_INFO_64; --+ config->flag1 |= WMI_RSRC_CFG_FLAG1_ACK_RSSI; -- } -- -- static int ath11k_hw_mac_id_to_pdev_id_ipq8074(struct ath11k_hw_params *hw, ----- a/drivers/net/wireless/ath/ath11k/mac.c --+++ b/drivers/net/wireless/ath/ath11k/mac.c --@@ -9174,6 +9174,11 @@ static int __ath11k_mac_register(struct -- goto err_free_if_combs; -- } -- --+ if (test_bit(WMI_TLV_SERVICE_TX_DATA_MGMT_ACK_RSSI, --+ ar->ab->wmi_ab.svc_map)) --+ 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 --@@ -5229,8 +5229,8 @@ static int ath11k_pull_mgmt_rx_params_tl -- return 0; -- } -- ---static int wmi_process_mgmt_tx_comp(struct ath11k *ar, u32 desc_id, --- u32 status) --+static int wmi_process_mgmt_tx_comp(struct ath11k *ar, --+ struct wmi_mgmt_tx_compl_event *tx_compl_param) -- { -- struct sk_buff *msdu; -- struct ieee80211_tx_info *info; --@@ -5238,24 +5238,29 @@ static int wmi_process_mgmt_tx_comp(stru -- int num_mgmt; -- -- spin_lock_bh(&ar->txmgmt_idr_lock); --- msdu = idr_find(&ar->txmgmt_idr, desc_id); --+ msdu = idr_find(&ar->txmgmt_idr, tx_compl_param->desc_id); -- -- if (!msdu) { -- ath11k_warn(ar->ab, "received mgmt tx compl for invalid msdu_id: %d\n", --- desc_id); --+ tx_compl_param->desc_id); -- spin_unlock_bh(&ar->txmgmt_idr_lock); -- return -ENOENT; -- } -- --- idr_remove(&ar->txmgmt_idr, desc_id); --+ idr_remove(&ar->txmgmt_idr, tx_compl_param->desc_id); -- spin_unlock_bh(&ar->txmgmt_idr_lock); -- -- skb_cb = ATH11K_SKB_CB(msdu); -- dma_unmap_single(ar->ab->dev, skb_cb->paddr, msdu->len, DMA_TO_DEVICE); -- -- info = IEEE80211_SKB_CB(msdu); --- if ((!(info->flags & IEEE80211_TX_CTL_NO_ACK)) && !status) --+ if ((!(info->flags & IEEE80211_TX_CTL_NO_ACK)) && --+ !tx_compl_param->status) { -- info->flags |= IEEE80211_TX_STAT_ACK; --+ if (test_bit(WMI_TLV_SERVICE_TX_DATA_MGMT_ACK_RSSI, --+ ar->ab->wmi_ab.svc_map)) --+ info->status.ack_signal = tx_compl_param->ack_rssi; --+ } -- -- ieee80211_tx_status_irqsafe(ar->hw, msdu); -- --@@ -5267,7 +5272,7 @@ static int wmi_process_mgmt_tx_comp(stru -- -- ath11k_dbg(ar->ab, ATH11K_DBG_WMI, -- "wmi mgmt tx comp pending %d desc id %d\n", --- num_mgmt, desc_id); --+ num_mgmt, tx_compl_param->desc_id); -- -- if (!num_mgmt) -- wake_up(&ar->txmgmt_empty_waitq); --@@ -5300,6 +5305,7 @@ static int ath11k_pull_mgmt_tx_compl_par -- param->pdev_id = ev->pdev_id; -- param->desc_id = ev->desc_id; -- param->status = ev->status; --+ param->ack_rssi = ev->ack_rssi; -- -- kfree(tb); -- return 0; --@@ -7070,13 +7076,12 @@ static void ath11k_mgmt_tx_compl_event(s -- goto exit; -- } -- --- wmi_process_mgmt_tx_comp(ar, tx_compl_param.desc_id, --- tx_compl_param.status); --+ wmi_process_mgmt_tx_comp(ar, &tx_compl_param); -- -- ath11k_dbg(ab, ATH11K_DBG_MGMT, --- "mgmt tx compl ev pdev_id %d, desc_id %d, status %d", --+ "mgmt tx compl ev pdev_id %d, desc_id %d, status %d ack_rssi %d", -- tx_compl_param.pdev_id, tx_compl_param.desc_id, --- tx_compl_param.status); --+ tx_compl_param.status, tx_compl_param.ack_rssi); -- -- exit: -- rcu_read_unlock(); ----- a/drivers/net/wireless/ath/ath11k/wmi.h --+++ b/drivers/net/wireless/ath/ath11k/wmi.h --@@ -2311,6 +2311,7 @@ struct wmi_init_cmd { -- } __packed; -- -- #define WMI_RSRC_CFG_FLAG1_BSS_CHANNEL_INFO_64 BIT(5) --+#define WMI_RSRC_CFG_FLAG1_ACK_RSSI BIT(18) -- -- struct wmi_resource_config { -- u32 tlv_header; --@@ -4550,6 +4551,8 @@ struct wmi_mgmt_tx_compl_event { -- u32 desc_id; -- u32 status; -- u32 pdev_id; --+ u32 ppdu_id; --+ u32 ack_rssi; -- } __packed; -- -- struct wmi_scan_event { -diff --git a/package/kernel/mac80211/patches/ath11k/0043-wifi-ath11k-use-proper-regulatory-reference-for-band.patch b/package/kernel/mac80211/patches/ath11k/0043-wifi-ath11k-use-proper-regulatory-reference-for-band.patch -deleted file mode 100644 -index 5bc195528e..0000000000 ---- a/package/kernel/mac80211/patches/ath11k/0043-wifi-ath11k-use-proper-regulatory-reference-for-band.patch -+++ /dev/null -@@ -1,216 +0,0 @@ --From 25e289e1f52e1f4fb1d07622c6a24f8d8a8e420d Mon Sep 17 00:00:00 2001 --From: Aditya Kumar Singh --Date: Wed, 1 Mar 2023 16:20:58 +0200 --Subject: [PATCH] wifi: ath11k: use proper regulatory reference for bands -- --Currently, during regulatory event, 2 GHz/5 GHz is referred --to as 2G/5G including variable names. However, there is no --such entity as 2G or 5G. -- --Re-name such occurences to its proper name. No functional changes. -- --Tested-on: IPQ8074 hw2.0 AHB WLAN.HK.2.7.0.1-01744-QCAHKSWPL_SILICONZ-1 --Tested-on: QCN9074 hw1.0 PCI WLAN.HK.2.7.0.1-01744-QCAHKSWPL_SILICONZ-1 --Tested-on: QCN9074 hw1.0 PCI WLAN.HK.2.5.0.1-01100-QCAHKSWPL_SILICONZ-1 -- --Signed-off-by: Aditya Kumar Singh --Signed-off-by: Kalle Valo --Link: https://lore.kernel.org/r/20230110121024.14051-2-quic_adisi@quicinc.com ----- -- drivers/net/wireless/ath/ath11k/reg.c | 20 ++++----- -- drivers/net/wireless/ath/ath11k/wmi.c | 58 ++++++++++++++------------- -- drivers/net/wireless/ath/ath11k/wmi.h | 28 ++++++------- -- 3 files changed, 54 insertions(+), 52 deletions(-) -- ----- a/drivers/net/wireless/ath/ath11k/reg.c --+++ b/drivers/net/wireless/ath/ath11k/reg.c --@@ -619,7 +619,7 @@ ath11k_reg_build_regd(struct ath11k_base -- u32 flags; -- char alpha2[3]; -- --- num_rules = reg_info->num_5g_reg_rules + reg_info->num_2g_reg_rules; --+ num_rules = reg_info->num_5ghz_reg_rules + reg_info->num_2ghz_reg_rules; -- -- if (!num_rules) -- goto ret; --@@ -644,20 +644,20 @@ ath11k_reg_build_regd(struct ath11k_base -- alpha2, ath11k_reg_get_regdom_str(tmp_regd->dfs_region), -- reg_info->dfs_region, num_rules); -- /* Update reg_rules[] below. Firmware is expected to --- * send these rules in order(2G rules first and then 5G) --+ * send these rules in order(2 GHz rules first and then 5 GHz) -- */ -- for (; i < num_rules; i++) { --- if (reg_info->num_2g_reg_rules && --- (i < reg_info->num_2g_reg_rules)) { --- reg_rule = reg_info->reg_rules_2g_ptr + i; --+ if (reg_info->num_2ghz_reg_rules && --+ (i < reg_info->num_2ghz_reg_rules)) { --+ reg_rule = reg_info->reg_rules_2ghz_ptr + i; -- max_bw = min_t(u16, reg_rule->max_bw, --- reg_info->max_bw_2g); --+ reg_info->max_bw_2ghz); -- flags = 0; --- } else if (reg_info->num_5g_reg_rules && --- (j < reg_info->num_5g_reg_rules)) { --- reg_rule = reg_info->reg_rules_5g_ptr + j++; --+ } else if (reg_info->num_5ghz_reg_rules && --+ (j < reg_info->num_5ghz_reg_rules)) { --+ reg_rule = reg_info->reg_rules_5ghz_ptr + j++; -- max_bw = min_t(u16, reg_rule->max_bw, --- reg_info->max_bw_5g); --+ reg_info->max_bw_5ghz); -- -- /* FW doesn't pass NL80211_RRF_AUTO_BW flag for -- * BW Auto correction, we can enable this by default ----- a/drivers/net/wireless/ath/ath11k/wmi.c --+++ b/drivers/net/wireless/ath/ath11k/wmi.c --@@ -4959,7 +4959,7 @@ static int ath11k_pull_reg_chan_list_upd -- const void **tb; -- const struct wmi_reg_chan_list_cc_event *chan_list_event_hdr; -- struct wmi_regulatory_rule_struct *wmi_reg_rule; --- u32 num_2g_reg_rules, num_5g_reg_rules; --+ u32 num_2ghz_reg_rules, num_5ghz_reg_rules; -- int ret; -- -- ath11k_dbg(ab, ATH11K_DBG_WMI, "processing regulatory channel list\n"); --@@ -4978,10 +4978,10 @@ static int ath11k_pull_reg_chan_list_upd -- return -EPROTO; -- } -- --- reg_info->num_2g_reg_rules = chan_list_event_hdr->num_2g_reg_rules; --- reg_info->num_5g_reg_rules = chan_list_event_hdr->num_5g_reg_rules; --+ reg_info->num_2ghz_reg_rules = chan_list_event_hdr->num_2ghz_reg_rules; --+ reg_info->num_5ghz_reg_rules = chan_list_event_hdr->num_5ghz_reg_rules; -- --- if (!(reg_info->num_2g_reg_rules + reg_info->num_5g_reg_rules)) { --+ if (!(reg_info->num_2ghz_reg_rules + reg_info->num_5ghz_reg_rules)) { -- ath11k_warn(ab, "No regulatory rules available in the event info\n"); -- kfree(tb); -- return -EINVAL; --@@ -5008,46 +5008,48 @@ static int ath11k_pull_reg_chan_list_upd -- else if (chan_list_event_hdr->status_code == WMI_REG_SET_CC_STATUS_FAIL) -- reg_info->status_code = REG_SET_CC_STATUS_FAIL; -- --- reg_info->min_bw_2g = chan_list_event_hdr->min_bw_2g; --- reg_info->max_bw_2g = chan_list_event_hdr->max_bw_2g; --- reg_info->min_bw_5g = chan_list_event_hdr->min_bw_5g; --- reg_info->max_bw_5g = chan_list_event_hdr->max_bw_5g; --+ reg_info->min_bw_2ghz = chan_list_event_hdr->min_bw_2ghz; --+ reg_info->max_bw_2ghz = chan_list_event_hdr->max_bw_2ghz; --+ reg_info->min_bw_5ghz = chan_list_event_hdr->min_bw_5ghz; --+ reg_info->max_bw_5ghz = chan_list_event_hdr->max_bw_5ghz; -- --- num_2g_reg_rules = reg_info->num_2g_reg_rules; --- num_5g_reg_rules = reg_info->num_5g_reg_rules; --+ num_2ghz_reg_rules = reg_info->num_2ghz_reg_rules; --+ num_5ghz_reg_rules = reg_info->num_5ghz_reg_rules; -- -- ath11k_dbg(ab, ATH11K_DBG_WMI, --- "%s:cc %s dsf %d BW: min_2g %d max_2g %d min_5g %d max_5g %d", --+ "%s:cc %s dsf %d BW: min_2ghz %d max_2ghz %d min_5ghz %d max_5ghz %d", -- __func__, reg_info->alpha2, reg_info->dfs_region, --- reg_info->min_bw_2g, reg_info->max_bw_2g, --- reg_info->min_bw_5g, reg_info->max_bw_5g); --+ reg_info->min_bw_2ghz, reg_info->max_bw_2ghz, --+ reg_info->min_bw_5ghz, reg_info->max_bw_5ghz); -- -- ath11k_dbg(ab, ATH11K_DBG_WMI, --- "%s: num_2g_reg_rules %d num_5g_reg_rules %d", __func__, --- num_2g_reg_rules, num_5g_reg_rules); --+ "%s: num_2ghz_reg_rules %d num_5ghz_reg_rules %d", __func__, --+ num_2ghz_reg_rules, num_5ghz_reg_rules); -- -- wmi_reg_rule = -- (struct wmi_regulatory_rule_struct *)((u8 *)chan_list_event_hdr -- + sizeof(*chan_list_event_hdr) -- + sizeof(struct wmi_tlv)); -- --- if (num_2g_reg_rules) { --- reg_info->reg_rules_2g_ptr = create_reg_rules_from_wmi(num_2g_reg_rules, --- wmi_reg_rule); --- if (!reg_info->reg_rules_2g_ptr) { --+ if (num_2ghz_reg_rules) { --+ reg_info->reg_rules_2ghz_ptr = --+ create_reg_rules_from_wmi(num_2ghz_reg_rules, --+ wmi_reg_rule); --+ if (!reg_info->reg_rules_2ghz_ptr) { -- kfree(tb); --- ath11k_warn(ab, "Unable to Allocate memory for 2g rules\n"); --+ ath11k_warn(ab, "Unable to Allocate memory for 2 GHz rules\n"); -- return -ENOMEM; -- } -- } -- --- if (num_5g_reg_rules) { --- wmi_reg_rule += num_2g_reg_rules; --- reg_info->reg_rules_5g_ptr = create_reg_rules_from_wmi(num_5g_reg_rules, --- wmi_reg_rule); --- if (!reg_info->reg_rules_5g_ptr) { --+ if (num_5ghz_reg_rules) { --+ wmi_reg_rule += num_2ghz_reg_rules; --+ reg_info->reg_rules_5ghz_ptr = --+ create_reg_rules_from_wmi(num_5ghz_reg_rules, --+ wmi_reg_rule); --+ if (!reg_info->reg_rules_5ghz_ptr) { -- kfree(tb); --- ath11k_warn(ab, "Unable to Allocate memory for 5g rules\n"); --+ ath11k_warn(ab, "Unable to Allocate memory for 5 GHz rules\n"); -- return -ENOMEM; -- } -- } --@@ -6619,8 +6621,8 @@ fallback: -- WARN_ON(1); -- mem_free: -- if (reg_info) { --- kfree(reg_info->reg_rules_2g_ptr); --- kfree(reg_info->reg_rules_5g_ptr); --+ kfree(reg_info->reg_rules_2ghz_ptr); --+ kfree(reg_info->reg_rules_5ghz_ptr); -- kfree(reg_info); -- } -- return ret; ----- a/drivers/net/wireless/ath/ath11k/wmi.h --+++ b/drivers/net/wireless/ath/ath11k/wmi.h --@@ -4129,14 +4129,14 @@ struct cur_regulatory_info { -- u8 alpha2[REG_ALPHA2_LEN + 1]; -- u32 dfs_region; -- u32 phybitmap; --- u32 min_bw_2g; --- u32 max_bw_2g; --- u32 min_bw_5g; --- u32 max_bw_5g; --- u32 num_2g_reg_rules; --- u32 num_5g_reg_rules; --- struct cur_reg_rule *reg_rules_2g_ptr; --- struct cur_reg_rule *reg_rules_5g_ptr; --+ u32 min_bw_2ghz; --+ u32 max_bw_2ghz; --+ u32 min_bw_5ghz; --+ u32 max_bw_5ghz; --+ u32 num_2ghz_reg_rules; --+ u32 num_5ghz_reg_rules; --+ struct cur_reg_rule *reg_rules_2ghz_ptr; --+ struct cur_reg_rule *reg_rules_5ghz_ptr; -- }; -- -- struct wmi_reg_chan_list_cc_event { --@@ -4148,12 +4148,12 @@ struct wmi_reg_chan_list_cc_event { -- u32 domain_code; -- u32 dfs_region; -- u32 phybitmap; --- u32 min_bw_2g; --- u32 max_bw_2g; --- u32 min_bw_5g; --- u32 max_bw_5g; --- u32 num_2g_reg_rules; --- u32 num_5g_reg_rules; --+ u32 min_bw_2ghz; --+ u32 max_bw_2ghz; --+ u32 min_bw_5ghz; --+ u32 max_bw_5ghz; --+ u32 num_2ghz_reg_rules; --+ u32 num_5ghz_reg_rules; -- } __packed; -- -- struct wmi_regulatory_rule_struct { -diff --git a/package/kernel/mac80211/patches/ath11k/0044-wifi-ath11k-add-support-to-parse-new-WMI-event-for-6.patch b/package/kernel/mac80211/patches/ath11k/0044-wifi-ath11k-add-support-to-parse-new-WMI-event-for-6.patch -deleted file mode 100644 -index e165c09dc4..0000000000 ---- a/package/kernel/mac80211/patches/ath11k/0044-wifi-ath11k-add-support-to-parse-new-WMI-event-for-6.patch -+++ /dev/null -@@ -1,844 +0,0 @@ --From 91fa00fa69224aae5afb720c5e68b22e4c4f7333 Mon Sep 17 00:00:00 2001 --From: Aditya Kumar Singh --Date: Wed, 1 Mar 2023 16:20:59 +0200 --Subject: [PATCH] wifi: ath11k: add support to parse new WMI event for 6 GHz -- --In order to support different power levels of 6 GHz AP and client, --new WMI event for regulatory - WMI_REG_CHAN_LIST_CC_EXT_EVENTID is --added in firmware. This event provides new parameters required for --6 GHz regulatory rules. -- --Add support for parsing 2.4 GHz, 5 GHz and 6 GHz reg rules and other --parameters from WMI_REG_CHAN_LIST_CC_EXT_EVENTID. -- --Tested-on: IPQ8074 hw2.0 AHB WLAN.HK.2.7.0.1-01744-QCAHKSWPL_SILICONZ-1 --Tested-on: QCN9074 hw1.0 PCI WLAN.HK.2.7.0.1-01744-QCAHKSWPL_SILICONZ-1 --Tested-on: QCN9074 hw1.0 PCI WLAN.HK.2.5.0.1-01100-QCAHKSWPL_SILICONZ-1 -- --Signed-off-by: Lavanya Suresh --Signed-off-by: Wen Gong --Signed-off-by: Aditya Kumar Singh --Signed-off-by: Kalle Valo --Link: https://lore.kernel.org/r/20230110121024.14051-3-quic_adisi@quicinc.com ----- -- drivers/net/wireless/ath/ath11k/reg.c | 37 ++- -- drivers/net/wireless/ath/ath11k/wmi.c | 418 +++++++++++++++++++++++++- -- drivers/net/wireless/ath/ath11k/wmi.h | 163 +++++++++- -- 3 files changed, 584 insertions(+), 34 deletions(-) -- ----- a/drivers/net/wireless/ath/ath11k/reg.c --+++ b/drivers/net/wireless/ath/ath11k/reg.c --@@ -613,7 +613,7 @@ ath11k_reg_build_regd(struct ath11k_base -- { -- struct ieee80211_regdomain *tmp_regd, *default_regd, *new_regd = NULL; -- struct cur_reg_rule *reg_rule; --- u8 i = 0, j = 0; --+ u8 i = 0, j = 0, k = 0; -- u8 num_rules; -- u16 max_bw; -- u32 flags; --@@ -621,6 +621,12 @@ ath11k_reg_build_regd(struct ath11k_base -- -- num_rules = reg_info->num_5ghz_reg_rules + reg_info->num_2ghz_reg_rules; -- --+ /* FIXME: Currently taking reg rules for 6 GHz only from Indoor AP mode list. --+ * This can be updated after complete 6 GHz regulatory support is added. --+ */ --+ if (reg_info->is_ext_reg_event) --+ num_rules += reg_info->num_6ghz_rules_ap[WMI_REG_INDOOR_AP]; --+ -- if (!num_rules) -- goto ret; -- --@@ -666,6 +672,14 @@ ath11k_reg_build_regd(struct ath11k_base -- * per other BW rule flags we pass from here -- */ -- flags = NL80211_RRF_AUTO_BW; --+ } else if (reg_info->is_ext_reg_event && --+ reg_info->num_6ghz_rules_ap[WMI_REG_INDOOR_AP] && --+ (k < reg_info->num_6ghz_rules_ap[WMI_REG_INDOOR_AP])) { --+ reg_rule = reg_info->reg_rules_6ghz_ap_ptr[WMI_REG_INDOOR_AP] + --+ k++; --+ max_bw = min_t(u16, reg_rule->max_bw, --+ reg_info->max_bw_6ghz_ap[WMI_REG_INDOOR_AP]); --+ flags = NL80211_RRF_AUTO_BW; -- } else { -- break; -- } --@@ -693,12 +707,21 @@ ath11k_reg_build_regd(struct ath11k_base -- continue; -- } -- --- ath11k_dbg(ab, ATH11K_DBG_REG, --- "\t%d. (%d - %d @ %d) (%d, %d) (%d ms) (FLAGS %d)\n", --- i + 1, reg_rule->start_freq, reg_rule->end_freq, --- max_bw, reg_rule->ant_gain, reg_rule->reg_power, --- tmp_regd->reg_rules[i].dfs_cac_ms, --- flags); --+ if (reg_info->is_ext_reg_event) { --+ ath11k_dbg(ab, ATH11K_DBG_REG, --+ "\t%d. (%d - %d @ %d) (%d, %d) (%d ms) (FLAGS %d) (%d, %d)\n", --+ i + 1, reg_rule->start_freq, reg_rule->end_freq, --+ max_bw, reg_rule->ant_gain, reg_rule->reg_power, --+ tmp_regd->reg_rules[i].dfs_cac_ms, flags, --+ reg_rule->psd_flag, reg_rule->psd_eirp); --+ } else { --+ ath11k_dbg(ab, ATH11K_DBG_REG, --+ "\t%d. (%d - %d @ %d) (%d, %d) (%d ms) (FLAGS %d)\n", --+ i + 1, reg_rule->start_freq, reg_rule->end_freq, --+ max_bw, reg_rule->ant_gain, reg_rule->reg_power, --+ tmp_regd->reg_rules[i].dfs_cac_ms, --+ flags); --+ } -- } -- -- tmp_regd->n_reg_rules = i; ----- a/drivers/net/wireless/ath/ath11k/wmi.c --+++ b/drivers/net/wireless/ath/ath11k/wmi.c --@@ -105,6 +105,8 @@ static const struct wmi_tlv_policy wmi_t -- = { .min_len = sizeof(struct wmi_vdev_stopped_event) }, -- [WMI_TAG_REG_CHAN_LIST_CC_EVENT] -- = { .min_len = sizeof(struct 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) }, -- [WMI_TAG_MGMT_RX_HDR] -- = { .min_len = sizeof(struct wmi_mgmt_rx_hdr) }, -- [WMI_TAG_MGMT_TX_COMPL_EVENT] --@@ -3974,6 +3976,10 @@ ath11k_wmi_copy_resource_config(struct w -- wmi_cfg->sched_params = tg_cfg->sched_params; -- wmi_cfg->twt_ap_pdev_count = tg_cfg->twt_ap_pdev_count; -- wmi_cfg->twt_ap_sta_count = tg_cfg->twt_ap_sta_count; --+ wmi_cfg->host_service_flags &= --+ ~(1 << WMI_CFG_HOST_SERVICE_FLAG_REG_CC_EXT); --+ wmi_cfg->host_service_flags |= (tg_cfg->is_reg_cc_ext_event_supported << --+ WMI_CFG_HOST_SERVICE_FLAG_REG_CC_EXT); -- } -- -- static int ath11k_init_cmd_send(struct ath11k_pdev_wmi *wmi, --@@ -4192,6 +4198,10 @@ int ath11k_wmi_cmd_init(struct ath11k_ba -- -- ab->hw_params.hw_ops->wmi_init_config(ab, &config); -- --+ if (test_bit(WMI_TLV_SERVICE_REG_CC_EXT_EVENT_SUPPORT, --+ ab->wmi_ab.svc_map)) --+ config.is_reg_cc_ext_event_supported = 1; --+ -- memcpy(&wmi_sc->wlan_resource_config, &config, sizeof(config)); -- -- init_param.res_cfg = &wmi_sc->wlan_resource_config; --@@ -4995,18 +5005,11 @@ static int ath11k_pull_reg_chan_list_upd -- reg_info->phy_id = chan_list_event_hdr->phy_id; -- reg_info->ctry_code = chan_list_event_hdr->country_id; -- reg_info->reg_dmn_pair = chan_list_event_hdr->domain_code; --- if (chan_list_event_hdr->status_code == WMI_REG_SET_CC_STATUS_PASS) --- reg_info->status_code = REG_SET_CC_STATUS_PASS; --- else if (chan_list_event_hdr->status_code == WMI_REG_CURRENT_ALPHA2_NOT_FOUND) --- reg_info->status_code = REG_CURRENT_ALPHA2_NOT_FOUND; --- else if (chan_list_event_hdr->status_code == WMI_REG_INIT_ALPHA2_NOT_FOUND) --- reg_info->status_code = REG_INIT_ALPHA2_NOT_FOUND; --- else if (chan_list_event_hdr->status_code == WMI_REG_SET_CC_CHANGE_NOT_ALLOWED) --- reg_info->status_code = REG_SET_CC_CHANGE_NOT_ALLOWED; --- else if (chan_list_event_hdr->status_code == WMI_REG_SET_CC_STATUS_NO_MEMORY) --- reg_info->status_code = REG_SET_CC_STATUS_NO_MEMORY; --- else if (chan_list_event_hdr->status_code == WMI_REG_SET_CC_STATUS_FAIL) --- reg_info->status_code = REG_SET_CC_STATUS_FAIL; --+ --+ reg_info->status_code = --+ ath11k_wmi_cc_setting_code_to_reg(chan_list_event_hdr->status_code); --+ --+ reg_info->is_ext_reg_event = false; -- -- reg_info->min_bw_2ghz = chan_list_event_hdr->min_bw_2ghz; -- reg_info->max_bw_2ghz = chan_list_event_hdr->max_bw_2ghz; --@@ -5060,6 +5063,372 @@ static int ath11k_pull_reg_chan_list_upd -- return 0; -- } -- --+static struct cur_reg_rule --+*create_ext_reg_rules_from_wmi(u32 num_reg_rules, --+ struct wmi_regulatory_ext_rule *wmi_reg_rule) --+{ --+ struct cur_reg_rule *reg_rule_ptr; --+ u32 count; --+ --+ reg_rule_ptr = kcalloc(num_reg_rules, sizeof(*reg_rule_ptr), GFP_ATOMIC); --+ --+ if (!reg_rule_ptr) --+ return NULL; --+ --+ for (count = 0; count < num_reg_rules; count++) { --+ reg_rule_ptr[count].start_freq = --+ u32_get_bits(wmi_reg_rule[count].freq_info, --+ REG_RULE_START_FREQ); --+ reg_rule_ptr[count].end_freq = --+ u32_get_bits(wmi_reg_rule[count].freq_info, --+ REG_RULE_END_FREQ); --+ reg_rule_ptr[count].max_bw = --+ u32_get_bits(wmi_reg_rule[count].bw_pwr_info, --+ REG_RULE_MAX_BW); --+ reg_rule_ptr[count].reg_power = --+ u32_get_bits(wmi_reg_rule[count].bw_pwr_info, --+ REG_RULE_REG_PWR); --+ reg_rule_ptr[count].ant_gain = --+ u32_get_bits(wmi_reg_rule[count].bw_pwr_info, --+ REG_RULE_ANT_GAIN); --+ reg_rule_ptr[count].flags = --+ u32_get_bits(wmi_reg_rule[count].flag_info, --+ REG_RULE_FLAGS); --+ reg_rule_ptr[count].psd_flag = --+ u32_get_bits(wmi_reg_rule[count].psd_power_info, --+ REG_RULE_PSD_INFO); --+ reg_rule_ptr[count].psd_eirp = --+ u32_get_bits(wmi_reg_rule[count].psd_power_info, --+ REG_RULE_PSD_EIRP); --+ } --+ --+ return reg_rule_ptr; --+} --+ --+static u8 --+ath11k_invalid_5ghz_reg_ext_rules_from_wmi(u32 num_reg_rules, --+ const struct wmi_regulatory_ext_rule *rule) --+{ --+ u8 num_invalid_5ghz_rules = 0; --+ u32 count, start_freq; --+ --+ for (count = 0; count < num_reg_rules; count++) { --+ start_freq = u32_get_bits(rule[count].freq_info, --+ REG_RULE_START_FREQ); --+ --+ if (start_freq >= ATH11K_MIN_6G_FREQ) --+ num_invalid_5ghz_rules++; --+ } --+ --+ return num_invalid_5ghz_rules; --+} --+ --+static int ath11k_pull_reg_chan_list_ext_update_ev(struct ath11k_base *ab, --+ struct sk_buff *skb, --+ struct cur_regulatory_info *reg_info) --+{ --+ const void **tb; --+ const struct wmi_reg_chan_list_cc_ext_event *ext_chan_list_event_hdr; --+ struct wmi_regulatory_ext_rule *ext_wmi_reg_rule; --+ u32 num_2ghz_reg_rules, num_5ghz_reg_rules; --+ u32 num_6ghz_reg_rules_ap[WMI_REG_CURRENT_MAX_AP_TYPE]; --+ u32 num_6ghz_client[WMI_REG_CURRENT_MAX_AP_TYPE][WMI_REG_MAX_CLIENT_TYPE]; --+ u32 total_reg_rules = 0; --+ int ret, i, j, num_invalid_5ghz_ext_rules = 0; --+ --+ ath11k_dbg(ab, ATH11K_DBG_WMI, "processing regulatory ext channel list\n"); --+ --+ 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; --+ } --+ --+ ext_chan_list_event_hdr = tb[WMI_TAG_REG_CHAN_LIST_CC_EXT_EVENT]; --+ if (!ext_chan_list_event_hdr) { --+ ath11k_warn(ab, "failed to fetch reg chan list ext update ev\n"); --+ kfree(tb); --+ return -EPROTO; --+ } --+ --+ reg_info->num_2ghz_reg_rules = --+ ext_chan_list_event_hdr->num_2ghz_reg_rules; --+ reg_info->num_5ghz_reg_rules = --+ ext_chan_list_event_hdr->num_5ghz_reg_rules; --+ reg_info->num_6ghz_rules_ap[WMI_REG_INDOOR_AP] = --+ ext_chan_list_event_hdr->num_6ghz_reg_rules_ap_lpi; --+ reg_info->num_6ghz_rules_ap[WMI_REG_STANDARD_POWER_AP] = --+ ext_chan_list_event_hdr->num_6ghz_reg_rules_ap_sp; --+ reg_info->num_6ghz_rules_ap[WMI_REG_VERY_LOW_POWER_AP] = --+ ext_chan_list_event_hdr->num_6ghz_reg_rules_ap_vlp; --+ --+ for (i = 0; i < WMI_REG_MAX_CLIENT_TYPE; i++) { --+ reg_info->num_6ghz_rules_client[WMI_REG_INDOOR_AP][i] = --+ ext_chan_list_event_hdr->num_6ghz_reg_rules_client_lpi[i]; --+ reg_info->num_6ghz_rules_client[WMI_REG_STANDARD_POWER_AP][i] = --+ ext_chan_list_event_hdr->num_6ghz_reg_rules_client_sp[i]; --+ reg_info->num_6ghz_rules_client[WMI_REG_VERY_LOW_POWER_AP][i] = --+ ext_chan_list_event_hdr->num_6ghz_reg_rules_client_vlp[i]; --+ } --+ --+ num_2ghz_reg_rules = reg_info->num_2ghz_reg_rules; --+ num_5ghz_reg_rules = reg_info->num_5ghz_reg_rules; --+ --+ total_reg_rules += num_2ghz_reg_rules; --+ total_reg_rules += num_5ghz_reg_rules; --+ --+ if ((num_2ghz_reg_rules > MAX_REG_RULES) || --+ (num_5ghz_reg_rules > MAX_REG_RULES)) { --+ ath11k_warn(ab, "Num reg rules for 2.4 GHz/5 GHz exceeds max limit (num_2ghz_reg_rules: %d num_5ghz_reg_rules: %d max_rules: %d)\n", --+ num_2ghz_reg_rules, num_5ghz_reg_rules, MAX_REG_RULES); --+ kfree(tb); --+ return -EINVAL; --+ } --+ --+ for (i = 0; i < WMI_REG_CURRENT_MAX_AP_TYPE; i++) { --+ num_6ghz_reg_rules_ap[i] = reg_info->num_6ghz_rules_ap[i]; --+ --+ if (num_6ghz_reg_rules_ap[i] > MAX_6GHZ_REG_RULES) { --+ ath11k_warn(ab, "Num 6 GHz reg rules for AP mode(%d) exceeds max limit (num_6ghz_reg_rules_ap: %d, max_rules: %d)\n", --+ i, num_6ghz_reg_rules_ap[i], MAX_6GHZ_REG_RULES); --+ kfree(tb); --+ return -EINVAL; --+ } --+ --+ total_reg_rules += num_6ghz_reg_rules_ap[i]; --+ } --+ --+ for (i = 0; i < WMI_REG_MAX_CLIENT_TYPE; i++) { --+ num_6ghz_client[WMI_REG_INDOOR_AP][i] = --+ reg_info->num_6ghz_rules_client[WMI_REG_INDOOR_AP][i]; --+ total_reg_rules += num_6ghz_client[WMI_REG_INDOOR_AP][i]; --+ --+ num_6ghz_client[WMI_REG_STANDARD_POWER_AP][i] = --+ reg_info->num_6ghz_rules_client[WMI_REG_STANDARD_POWER_AP][i]; --+ total_reg_rules += num_6ghz_client[WMI_REG_STANDARD_POWER_AP][i]; --+ --+ num_6ghz_client[WMI_REG_VERY_LOW_POWER_AP][i] = --+ reg_info->num_6ghz_rules_client[WMI_REG_VERY_LOW_POWER_AP][i]; --+ total_reg_rules += num_6ghz_client[WMI_REG_VERY_LOW_POWER_AP][i]; --+ --+ if ((num_6ghz_client[WMI_REG_INDOOR_AP][i] > MAX_6GHZ_REG_RULES) || --+ (num_6ghz_client[WMI_REG_STANDARD_POWER_AP][i] > --+ MAX_6GHZ_REG_RULES) || --+ (num_6ghz_client[WMI_REG_VERY_LOW_POWER_AP][i] > --+ MAX_6GHZ_REG_RULES)) { --+ ath11k_warn(ab, --+ "Num 6 GHz client reg rules exceeds max limit, for client(type: %d)\n", --+ i); --+ kfree(tb); --+ return -EINVAL; --+ } --+ } --+ --+ if (!total_reg_rules) { --+ ath11k_warn(ab, "No reg rules available\n"); --+ kfree(tb); --+ return -EINVAL; --+ } --+ --+ memcpy(reg_info->alpha2, &ext_chan_list_event_hdr->alpha2, --+ REG_ALPHA2_LEN); --+ --+ reg_info->dfs_region = ext_chan_list_event_hdr->dfs_region; --+ reg_info->phybitmap = ext_chan_list_event_hdr->phybitmap; --+ reg_info->num_phy = ext_chan_list_event_hdr->num_phy; --+ reg_info->phy_id = ext_chan_list_event_hdr->phy_id; --+ reg_info->ctry_code = ext_chan_list_event_hdr->country_id; --+ reg_info->reg_dmn_pair = ext_chan_list_event_hdr->domain_code; --+ --+ reg_info->status_code = --+ ath11k_wmi_cc_setting_code_to_reg(ext_chan_list_event_hdr->status_code); --+ --+ reg_info->is_ext_reg_event = true; --+ --+ reg_info->min_bw_2ghz = ext_chan_list_event_hdr->min_bw_2ghz; --+ reg_info->max_bw_2ghz = ext_chan_list_event_hdr->max_bw_2ghz; --+ reg_info->min_bw_5ghz = ext_chan_list_event_hdr->min_bw_5ghz; --+ reg_info->max_bw_5ghz = ext_chan_list_event_hdr->max_bw_5ghz; --+ --+ reg_info->min_bw_6ghz_ap[WMI_REG_INDOOR_AP] = --+ ext_chan_list_event_hdr->min_bw_6ghz_ap_lpi; --+ reg_info->max_bw_6ghz_ap[WMI_REG_INDOOR_AP] = --+ ext_chan_list_event_hdr->max_bw_6ghz_ap_lpi; --+ reg_info->min_bw_6ghz_ap[WMI_REG_STANDARD_POWER_AP] = --+ ext_chan_list_event_hdr->min_bw_6ghz_ap_sp; --+ reg_info->max_bw_6ghz_ap[WMI_REG_STANDARD_POWER_AP] = --+ ext_chan_list_event_hdr->max_bw_6ghz_ap_sp; --+ reg_info->min_bw_6ghz_ap[WMI_REG_VERY_LOW_POWER_AP] = --+ ext_chan_list_event_hdr->min_bw_6ghz_ap_vlp; --+ reg_info->max_bw_6ghz_ap[WMI_REG_VERY_LOW_POWER_AP] = --+ ext_chan_list_event_hdr->max_bw_6ghz_ap_vlp; --+ --+ for (i = 0; i < WMI_REG_MAX_CLIENT_TYPE; i++) { --+ reg_info->min_bw_6ghz_client[WMI_REG_INDOOR_AP][i] = --+ ext_chan_list_event_hdr->min_bw_6ghz_client_lpi[i]; --+ reg_info->max_bw_6ghz_client[WMI_REG_INDOOR_AP][i] = --+ ext_chan_list_event_hdr->max_bw_6ghz_client_lpi[i]; --+ reg_info->min_bw_6ghz_client[WMI_REG_STANDARD_POWER_AP][i] = --+ ext_chan_list_event_hdr->min_bw_6ghz_client_sp[i]; --+ reg_info->max_bw_6ghz_client[WMI_REG_STANDARD_POWER_AP][i] = --+ ext_chan_list_event_hdr->max_bw_6ghz_client_sp[i]; --+ reg_info->min_bw_6ghz_client[WMI_REG_VERY_LOW_POWER_AP][i] = --+ ext_chan_list_event_hdr->min_bw_6ghz_client_vlp[i]; --+ reg_info->max_bw_6ghz_client[WMI_REG_VERY_LOW_POWER_AP][i] = --+ ext_chan_list_event_hdr->max_bw_6ghz_client_vlp[i]; --+ } --+ --+ ath11k_dbg(ab, ATH11K_DBG_WMI, --+ "%s:cc_ext %s dsf %d BW: min_2ghz %d max_2ghz %d min_5ghz %d max_5ghz %d", --+ __func__, reg_info->alpha2, reg_info->dfs_region, --+ reg_info->min_bw_2ghz, reg_info->max_bw_2ghz, --+ reg_info->min_bw_5ghz, reg_info->max_bw_5ghz); --+ --+ ath11k_dbg(ab, ATH11K_DBG_WMI, --+ "num_2ghz_reg_rules %d num_5ghz_reg_rules %d", --+ num_2ghz_reg_rules, num_5ghz_reg_rules); --+ --+ ath11k_dbg(ab, ATH11K_DBG_WMI, --+ "num_6ghz_reg_rules_ap_lpi: %d num_6ghz_reg_rules_ap_sp: %d num_6ghz_reg_rules_ap_vlp: %d", --+ num_6ghz_reg_rules_ap[WMI_REG_INDOOR_AP], --+ num_6ghz_reg_rules_ap[WMI_REG_STANDARD_POWER_AP], --+ num_6ghz_reg_rules_ap[WMI_REG_VERY_LOW_POWER_AP]); --+ --+ j = WMI_REG_DEFAULT_CLIENT; --+ ath11k_dbg(ab, ATH11K_DBG_WMI, --+ "6 GHz Regular client: num_6ghz_reg_rules_lpi: %d num_6ghz_reg_rules_sp: %d num_6ghz_reg_rules_vlp: %d", --+ num_6ghz_client[WMI_REG_INDOOR_AP][j], --+ num_6ghz_client[WMI_REG_STANDARD_POWER_AP][j], --+ num_6ghz_client[WMI_REG_VERY_LOW_POWER_AP][j]); --+ --+ j = WMI_REG_SUBORDINATE_CLIENT; --+ ath11k_dbg(ab, ATH11K_DBG_WMI, --+ "6 GHz Subordinate client: num_6ghz_reg_rules_lpi: %d num_6ghz_reg_rules_sp: %d num_6ghz_reg_rules_vlp: %d", --+ num_6ghz_client[WMI_REG_INDOOR_AP][j], --+ num_6ghz_client[WMI_REG_STANDARD_POWER_AP][j], --+ num_6ghz_client[WMI_REG_VERY_LOW_POWER_AP][j]); --+ --+ ext_wmi_reg_rule = --+ (struct wmi_regulatory_ext_rule *)((u8 *)ext_chan_list_event_hdr --+ + sizeof(*ext_chan_list_event_hdr) --+ + sizeof(struct wmi_tlv)); --+ if (num_2ghz_reg_rules) { --+ reg_info->reg_rules_2ghz_ptr = --+ create_ext_reg_rules_from_wmi(num_2ghz_reg_rules, --+ ext_wmi_reg_rule); --+ --+ if (!reg_info->reg_rules_2ghz_ptr) { --+ kfree(tb); --+ ath11k_warn(ab, "Unable to Allocate memory for 2 GHz rules\n"); --+ return -ENOMEM; --+ } --+ } --+ --+ ext_wmi_reg_rule += num_2ghz_reg_rules; --+ --+ /* Firmware might include 6 GHz reg rule in 5 GHz rule list --+ * for few countries along with separate 6 GHz rule. --+ * Having same 6 GHz reg rule in 5 GHz and 6 GHz rules list --+ * causes intersect check to be true, and same rules will be --+ * shown multiple times in iw cmd. --+ * Hence, avoid parsing 6 GHz rule from 5 GHz reg rule list --+ */ --+ num_invalid_5ghz_ext_rules = --+ ath11k_invalid_5ghz_reg_ext_rules_from_wmi(num_5ghz_reg_rules, --+ ext_wmi_reg_rule); --+ --+ if (num_invalid_5ghz_ext_rules) { --+ ath11k_dbg(ab, ATH11K_DBG_WMI, --+ "CC: %s 5 GHz reg rules number %d from fw, %d number of invalid 5 GHz rules", --+ reg_info->alpha2, reg_info->num_5ghz_reg_rules, --+ num_invalid_5ghz_ext_rules); --+ --+ num_5ghz_reg_rules = num_5ghz_reg_rules - num_invalid_5ghz_ext_rules; --+ reg_info->num_5ghz_reg_rules = num_5ghz_reg_rules; --+ } --+ --+ if (num_5ghz_reg_rules) { --+ reg_info->reg_rules_5ghz_ptr = --+ create_ext_reg_rules_from_wmi(num_5ghz_reg_rules, --+ ext_wmi_reg_rule); --+ --+ if (!reg_info->reg_rules_5ghz_ptr) { --+ kfree(tb); --+ ath11k_warn(ab, "Unable to Allocate memory for 5 GHz rules\n"); --+ return -ENOMEM; --+ } --+ } --+ --+ /* We have adjusted the number of 5 GHz reg rules above. But still those --+ * many rules needs to be adjusted in ext_wmi_reg_rule. --+ * --+ * NOTE: num_invalid_5ghz_ext_rules will be 0 for rest other cases. --+ */ --+ ext_wmi_reg_rule += (num_5ghz_reg_rules + num_invalid_5ghz_ext_rules); --+ --+ for (i = 0; i < WMI_REG_CURRENT_MAX_AP_TYPE; i++) { --+ reg_info->reg_rules_6ghz_ap_ptr[i] = --+ create_ext_reg_rules_from_wmi(num_6ghz_reg_rules_ap[i], --+ ext_wmi_reg_rule); --+ --+ if (!reg_info->reg_rules_6ghz_ap_ptr[i]) { --+ kfree(tb); --+ ath11k_warn(ab, "Unable to Allocate memory for 6 GHz AP rules\n"); --+ return -ENOMEM; --+ } --+ --+ ext_wmi_reg_rule += num_6ghz_reg_rules_ap[i]; --+ } --+ --+ for (j = 0; j < WMI_REG_CURRENT_MAX_AP_TYPE; j++) { --+ for (i = 0; i < WMI_REG_MAX_CLIENT_TYPE; i++) { --+ reg_info->reg_rules_6ghz_client_ptr[j][i] = --+ create_ext_reg_rules_from_wmi(num_6ghz_client[j][i], --+ ext_wmi_reg_rule); --+ --+ if (!reg_info->reg_rules_6ghz_client_ptr[j][i]) { --+ kfree(tb); --+ ath11k_warn(ab, "Unable to Allocate memory for 6 GHz client rules\n"); --+ return -ENOMEM; --+ } --+ --+ ext_wmi_reg_rule += num_6ghz_client[j][i]; --+ } --+ } --+ --+ reg_info->client_type = ext_chan_list_event_hdr->client_type; --+ reg_info->rnr_tpe_usable = ext_chan_list_event_hdr->rnr_tpe_usable; --+ reg_info->unspecified_ap_usable = --+ ext_chan_list_event_hdr->unspecified_ap_usable; --+ reg_info->domain_code_6ghz_ap[WMI_REG_INDOOR_AP] = --+ ext_chan_list_event_hdr->domain_code_6ghz_ap_lpi; --+ reg_info->domain_code_6ghz_ap[WMI_REG_STANDARD_POWER_AP] = --+ ext_chan_list_event_hdr->domain_code_6ghz_ap_sp; --+ reg_info->domain_code_6ghz_ap[WMI_REG_VERY_LOW_POWER_AP] = --+ ext_chan_list_event_hdr->domain_code_6ghz_ap_vlp; --+ --+ for (i = 0; i < WMI_REG_MAX_CLIENT_TYPE; i++) { --+ reg_info->domain_code_6ghz_client[WMI_REG_INDOOR_AP][i] = --+ ext_chan_list_event_hdr->domain_code_6ghz_client_lpi[i]; --+ reg_info->domain_code_6ghz_client[WMI_REG_STANDARD_POWER_AP][i] = --+ ext_chan_list_event_hdr->domain_code_6ghz_client_sp[i]; --+ reg_info->domain_code_6ghz_client[WMI_REG_VERY_LOW_POWER_AP][i] = --+ ext_chan_list_event_hdr->domain_code_6ghz_client_vlp[i]; --+ } --+ --+ reg_info->domain_code_6ghz_super_id = --+ ext_chan_list_event_hdr->domain_code_6ghz_super_id; --+ --+ ath11k_dbg(ab, ATH11K_DBG_WMI, "6 GHz client_type: %d domain_code_6ghz_super_id: %d", --+ reg_info->client_type, reg_info->domain_code_6ghz_super_id); --+ --+ ath11k_dbg(ab, ATH11K_DBG_WMI, "processed regulatory ext channel list\n"); --+ --+ kfree(tb); --+ return 0; --+} --+ -- static int ath11k_pull_peer_del_resp_ev(struct ath11k_base *ab, struct sk_buff *skb, -- struct wmi_peer_delete_resp_event *peer_del_resp) -- { --@@ -6507,12 +6876,14 @@ static bool ath11k_reg_is_world_alpha(ch -- return false; -- } -- ---static int ath11k_reg_chan_list_event(struct ath11k_base *ab, struct sk_buff *skb) --+static int ath11k_reg_chan_list_event(struct ath11k_base *ab, --+ struct sk_buff *skb, --+ enum wmi_reg_chan_list_cmd_type id) -- { -- struct cur_regulatory_info *reg_info = NULL; -- struct ieee80211_regdomain *regd = NULL; -- bool intersect = false; --- int ret = 0, pdev_idx; --+ int ret = 0, pdev_idx, i, j; -- struct ath11k *ar; -- -- reg_info = kzalloc(sizeof(*reg_info), GFP_ATOMIC); --@@ -6521,7 +6892,11 @@ static int ath11k_reg_chan_list_event(st -- goto fallback; -- } -- --- ret = ath11k_pull_reg_chan_list_update_ev(ab, skb, reg_info); --+ if (id == WMI_REG_CHAN_LIST_CC_ID) --+ ret = ath11k_pull_reg_chan_list_update_ev(ab, skb, reg_info); --+ else --+ ret = ath11k_pull_reg_chan_list_ext_update_ev(ab, skb, reg_info); --+ -- if (ret) { -- ath11k_warn(ab, "failed to extract regulatory info from received event\n"); -- goto fallback; --@@ -6623,6 +6998,14 @@ mem_free: -- if (reg_info) { -- kfree(reg_info->reg_rules_2ghz_ptr); -- kfree(reg_info->reg_rules_5ghz_ptr); --+ if (reg_info->is_ext_reg_event) { --+ for (i = 0; i < WMI_REG_CURRENT_MAX_AP_TYPE; i++) --+ kfree(reg_info->reg_rules_6ghz_ap_ptr[i]); --+ --+ for (j = 0; j < WMI_REG_CURRENT_MAX_AP_TYPE; j++) --+ for (i = 0; i < WMI_REG_MAX_CLIENT_TYPE; i++) --+ kfree(reg_info->reg_rules_6ghz_client_ptr[j][i]); --+ } -- kfree(reg_info); -- } -- return ret; --@@ -8054,7 +8437,10 @@ static void ath11k_wmi_tlv_op_rx(struct -- ath11k_service_ready_ext2_event(ab, skb); -- break; -- case WMI_REG_CHAN_LIST_CC_EVENTID: --- ath11k_reg_chan_list_event(ab, skb); --+ ath11k_reg_chan_list_event(ab, skb, WMI_REG_CHAN_LIST_CC_ID); --+ break; --+ case WMI_REG_CHAN_LIST_CC_EXT_EVENTID: --+ ath11k_reg_chan_list_event(ab, skb, WMI_REG_CHAN_LIST_CC_EXT_ID); -- break; -- case WMI_READY_EVENTID: -- ath11k_ready_event(ab, skb); ----- a/drivers/net/wireless/ath/ath11k/wmi.h --+++ b/drivers/net/wireless/ath/ath11k/wmi.h --@@ -797,6 +797,7 @@ enum wmi_tlv_event_id { -- WMI_RMC_NEW_LEADER_EVENTID = WMI_TLV_CMD(WMI_GRP_RMC), -- WMI_REG_CHAN_LIST_CC_EVENTID = WMI_TLV_CMD(WMI_GRP_REGULATORY), -- WMI_11D_NEW_COUNTRY_EVENTID, --+ WMI_REG_CHAN_LIST_CC_EXT_EVENTID, -- WMI_NDI_CAP_RSP_EVENTID = WMI_TLV_CMD(WMI_GRP_PROTOTYPE), -- WMI_NDP_INITIATOR_RSP_EVENTID, -- WMI_NDP_RESPONDER_RSP_EVENTID, --@@ -1865,6 +1866,8 @@ enum wmi_tlv_tag { -- WMI_TAG_PDEV_SRG_OBSS_BSSID_ENABLE_BITMAP_CMD, -- WMI_TAG_PDEV_NON_SRG_OBSS_COLOR_ENABLE_BITMAP_CMD, -- 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, -- WMI_TAG_MAX --@@ -2097,6 +2100,7 @@ enum wmi_tlv_service { -- -- /* The second 128 bits */ -- WMI_MAX_EXT_SERVICE = 256, --+ WMI_TLV_SERVICE_REG_CC_EXT_EVENT_SUPPORT = 281, -- WMI_TLV_SERVICE_BIOS_SAR_SUPPORT = 326, -- -- /* The third 128 bits */ --@@ -2313,6 +2317,8 @@ struct wmi_init_cmd { -- #define WMI_RSRC_CFG_FLAG1_BSS_CHANNEL_INFO_64 BIT(5) -- #define WMI_RSRC_CFG_FLAG1_ACK_RSSI BIT(18) -- --+#define WMI_CFG_HOST_SERVICE_FLAG_REG_CC_EXT 4 --+ -- struct wmi_resource_config { -- u32 tlv_header; -- u32 num_vdevs; --@@ -2372,6 +2378,15 @@ struct wmi_resource_config { -- u32 sched_params; -- u32 twt_ap_pdev_count; -- u32 twt_ap_sta_count; --+ u32 max_nlo_ssids; --+ u32 num_pkt_filters; --+ u32 num_max_sta_vdevs; --+ u32 max_bssid_indicator; --+ u32 ul_resp_config; --+ u32 msdu_flow_override_config0; --+ u32 msdu_flow_override_config1; --+ u32 flags2; --+ u32 host_service_flags; -- } __packed; -- -- struct wmi_service_ready_event { --@@ -2854,6 +2869,8 @@ struct rx_reorder_queue_remove_params { -- #define REG_RULE_MAX_BW 0x0000ffff -- #define REG_RULE_REG_PWR 0x00ff0000 -- #define REG_RULE_ANT_GAIN 0xff000000 --+#define REG_RULE_PSD_INFO BIT(0) --+#define REG_RULE_PSD_EIRP 0xff0000 -- -- #define WMI_VDEV_PARAM_TXBF_SU_TX_BFEE BIT(0) -- #define WMI_VDEV_PARAM_TXBF_MU_TX_BFEE BIT(1) --@@ -4049,6 +4066,7 @@ struct wmi_he_rate_set { -- -- #define MAX_REG_RULES 10 -- #define REG_ALPHA2_LEN 2 --+#define MAX_6GHZ_REG_RULES 5 -- -- enum wmi_start_event_param { -- WMI_VDEV_START_RESP_EVENT = 0, --@@ -4079,16 +4097,6 @@ enum wmi_vdev_start_resp_status_code { -- WMI_VDEV_START_RESPONSE_INVALID_REGDOMAIN = 4, -- }; -- ---; ---enum cc_setting_code { --- REG_SET_CC_STATUS_PASS = 0, --- REG_CURRENT_ALPHA2_NOT_FOUND = 1, --- REG_INIT_ALPHA2_NOT_FOUND = 2, --- REG_SET_CC_CHANGE_NOT_ALLOWED = 3, --- REG_SET_CC_STATUS_NO_MEMORY = 4, --- REG_SET_CC_STATUS_FAIL = 5, ---}; --- -- /* Regaulatory Rule Flags Passed by FW */ -- #define REGULATORY_CHAN_DISABLED BIT(0) -- #define REGULATORY_CHAN_NO_IR BIT(1) --@@ -4102,13 +4110,72 @@ enum cc_setting_code { -- #define REGULATORY_CHAN_NO_20MHZ BIT(11) -- #define REGULATORY_CHAN_NO_10MHZ BIT(12) -- ---enum { --+enum wmi_reg_chan_list_cmd_type { --+ WMI_REG_CHAN_LIST_CC_ID = 0, --+ WMI_REG_CHAN_LIST_CC_EXT_ID = 1, --+}; --+ --+enum wmi_reg_cc_setting_code { -- WMI_REG_SET_CC_STATUS_PASS = 0, -- WMI_REG_CURRENT_ALPHA2_NOT_FOUND = 1, -- WMI_REG_INIT_ALPHA2_NOT_FOUND = 2, -- WMI_REG_SET_CC_CHANGE_NOT_ALLOWED = 3, -- WMI_REG_SET_CC_STATUS_NO_MEMORY = 4, -- WMI_REG_SET_CC_STATUS_FAIL = 5, --+ --+ /* add new setting code above, update in --+ * @enum cc_setting_code as well. --+ * Also handle it in ath11k_wmi_cc_setting_code_to_reg() --+ */ --+}; --+ --+enum cc_setting_code { --+ REG_SET_CC_STATUS_PASS = 0, --+ REG_CURRENT_ALPHA2_NOT_FOUND = 1, --+ REG_INIT_ALPHA2_NOT_FOUND = 2, --+ REG_SET_CC_CHANGE_NOT_ALLOWED = 3, --+ REG_SET_CC_STATUS_NO_MEMORY = 4, --+ REG_SET_CC_STATUS_FAIL = 5, --+ --+ /* add new setting code above, update in --+ * @enum wmi_reg_cc_setting_code as well. --+ */ --+}; --+ --+static inline enum cc_setting_code --+ath11k_wmi_cc_setting_code_to_reg(enum wmi_reg_cc_setting_code status_code) --+{ --+ switch (status_code) { --+ case WMI_REG_SET_CC_STATUS_PASS: --+ return REG_SET_CC_STATUS_PASS; --+ case WMI_REG_CURRENT_ALPHA2_NOT_FOUND: --+ return REG_CURRENT_ALPHA2_NOT_FOUND; --+ case WMI_REG_INIT_ALPHA2_NOT_FOUND: --+ return REG_INIT_ALPHA2_NOT_FOUND; --+ case WMI_REG_SET_CC_CHANGE_NOT_ALLOWED: --+ return REG_SET_CC_CHANGE_NOT_ALLOWED; --+ case WMI_REG_SET_CC_STATUS_NO_MEMORY: --+ return REG_SET_CC_STATUS_NO_MEMORY; --+ case WMI_REG_SET_CC_STATUS_FAIL: --+ return REG_SET_CC_STATUS_FAIL; --+ } --+ --+ return REG_SET_CC_STATUS_FAIL; --+} --+ --+enum wmi_reg_6ghz_ap_type { --+ WMI_REG_INDOOR_AP = 0, --+ WMI_REG_STANDARD_POWER_AP = 1, --+ WMI_REG_VERY_LOW_POWER_AP = 2, --+ --+ WMI_REG_CURRENT_MAX_AP_TYPE, --+ WMI_REG_MAX_AP_TYPE = 7, --+}; --+ --+enum wmi_reg_6ghz_client_type { --+ WMI_REG_DEFAULT_CLIENT = 0, --+ WMI_REG_SUBORDINATE_CLIENT = 1, --+ WMI_REG_MAX_CLIENT_TYPE = 2, -- }; -- -- struct cur_reg_rule { --@@ -4118,6 +4185,8 @@ struct cur_reg_rule { -- u8 reg_power; -- u8 ant_gain; -- u16 flags; --+ bool psd_flag; --+ s8 psd_eirp; -- }; -- -- struct cur_regulatory_info { --@@ -4137,6 +4206,22 @@ struct cur_regulatory_info { -- u32 num_5ghz_reg_rules; -- struct cur_reg_rule *reg_rules_2ghz_ptr; -- struct cur_reg_rule *reg_rules_5ghz_ptr; --+ bool is_ext_reg_event; --+ enum wmi_reg_6ghz_client_type client_type; --+ bool rnr_tpe_usable; --+ bool unspecified_ap_usable; --+ u8 domain_code_6ghz_ap[WMI_REG_CURRENT_MAX_AP_TYPE]; --+ u8 domain_code_6ghz_client[WMI_REG_CURRENT_MAX_AP_TYPE][WMI_REG_MAX_CLIENT_TYPE]; --+ u32 domain_code_6ghz_super_id; --+ u32 min_bw_6ghz_ap[WMI_REG_CURRENT_MAX_AP_TYPE]; --+ u32 max_bw_6ghz_ap[WMI_REG_CURRENT_MAX_AP_TYPE]; --+ u32 min_bw_6ghz_client[WMI_REG_CURRENT_MAX_AP_TYPE][WMI_REG_MAX_CLIENT_TYPE]; --+ u32 max_bw_6ghz_client[WMI_REG_CURRENT_MAX_AP_TYPE][WMI_REG_MAX_CLIENT_TYPE]; --+ u32 num_6ghz_rules_ap[WMI_REG_CURRENT_MAX_AP_TYPE]; --+ u32 num_6ghz_rules_client[WMI_REG_CURRENT_MAX_AP_TYPE][WMI_REG_MAX_CLIENT_TYPE]; --+ struct cur_reg_rule *reg_rules_6ghz_ap_ptr[WMI_REG_CURRENT_MAX_AP_TYPE]; --+ struct cur_reg_rule *reg_rules_6ghz_client_ptr --+ [WMI_REG_CURRENT_MAX_AP_TYPE][WMI_REG_MAX_CLIENT_TYPE]; -- }; -- -- struct wmi_reg_chan_list_cc_event { --@@ -4163,6 +4248,61 @@ struct wmi_regulatory_rule_struct { -- u32 flag_info; -- }; -- --+#define WMI_REG_CLIENT_MAX 4 --+ --+struct wmi_reg_chan_list_cc_ext_event { --+ u32 status_code; --+ u32 phy_id; --+ u32 alpha2; --+ u32 num_phy; --+ u32 country_id; --+ u32 domain_code; --+ u32 dfs_region; --+ u32 phybitmap; --+ u32 min_bw_2ghz; --+ u32 max_bw_2ghz; --+ u32 min_bw_5ghz; --+ u32 max_bw_5ghz; --+ u32 num_2ghz_reg_rules; --+ u32 num_5ghz_reg_rules; --+ u32 client_type; --+ u32 rnr_tpe_usable; --+ u32 unspecified_ap_usable; --+ u32 domain_code_6ghz_ap_lpi; --+ u32 domain_code_6ghz_ap_sp; --+ u32 domain_code_6ghz_ap_vlp; --+ u32 domain_code_6ghz_client_lpi[WMI_REG_CLIENT_MAX]; --+ u32 domain_code_6ghz_client_sp[WMI_REG_CLIENT_MAX]; --+ u32 domain_code_6ghz_client_vlp[WMI_REG_CLIENT_MAX]; --+ u32 domain_code_6ghz_super_id; --+ u32 min_bw_6ghz_ap_sp; --+ u32 max_bw_6ghz_ap_sp; --+ u32 min_bw_6ghz_ap_lpi; --+ u32 max_bw_6ghz_ap_lpi; --+ u32 min_bw_6ghz_ap_vlp; --+ u32 max_bw_6ghz_ap_vlp; --+ u32 min_bw_6ghz_client_sp[WMI_REG_CLIENT_MAX]; --+ u32 max_bw_6ghz_client_sp[WMI_REG_CLIENT_MAX]; --+ u32 min_bw_6ghz_client_lpi[WMI_REG_CLIENT_MAX]; --+ u32 max_bw_6ghz_client_lpi[WMI_REG_CLIENT_MAX]; --+ u32 min_bw_6ghz_client_vlp[WMI_REG_CLIENT_MAX]; --+ u32 max_bw_6ghz_client_vlp[WMI_REG_CLIENT_MAX]; --+ u32 num_6ghz_reg_rules_ap_sp; --+ u32 num_6ghz_reg_rules_ap_lpi; --+ u32 num_6ghz_reg_rules_ap_vlp; --+ u32 num_6ghz_reg_rules_client_sp[WMI_REG_CLIENT_MAX]; --+ u32 num_6ghz_reg_rules_client_lpi[WMI_REG_CLIENT_MAX]; --+ u32 num_6ghz_reg_rules_client_vlp[WMI_REG_CLIENT_MAX]; --+} __packed; --+ --+struct wmi_regulatory_ext_rule { --+ u32 tlv_header; --+ u32 freq_info; --+ u32 bw_pwr_info; --+ u32 flag_info; --+ u32 psd_power_info; --+} __packed; --+ -- struct wmi_vdev_delete_resp_event { -- u32 vdev_id; -- } __packed; --@@ -5358,6 +5498,7 @@ struct target_resource_config { -- u32 sched_params; -- u32 twt_ap_pdev_count; -- u32 twt_ap_sta_count; --+ u8 is_reg_cc_ext_event_supported; -- }; -- -- enum wmi_debug_log_param { -diff --git a/package/kernel/mac80211/patches/ath11k/0045-wifi-ath11k-add-debug-prints-in-regulatory-WMI-event.patch b/package/kernel/mac80211/patches/ath11k/0045-wifi-ath11k-add-debug-prints-in-regulatory-WMI-event.patch -deleted file mode 100644 -index b88e51928f..0000000000 ---- a/package/kernel/mac80211/patches/ath11k/0045-wifi-ath11k-add-debug-prints-in-regulatory-WMI-event.patch -+++ /dev/null -@@ -1,567 +0,0 @@ --From e238e62ba8868a784e485eb94451c87cd1b85cee Mon Sep 17 00:00:00 2001 --From: Aditya Kumar Singh --Date: Wed, 1 Mar 2023 16:20:59 +0200 --Subject: [PATCH] wifi: ath11k: add debug prints in regulatory WMI event -- processing -- --Add some more debug prints in processing regulatory WMI event in order to --increase more debuggability. -- --Tested-on: IPQ8074 hw2.0 AHB WLAN.HK.2.7.0.1-01744-QCAHKSWPL_SILICONZ-1 --Tested-on: QCN9074 hw1.0 PCI WLAN.HK.2.7.0.1-01744-QCAHKSWPL_SILICONZ-1 --Tested-on: QCN9074 hw1.0 PCI WLAN.HK.2.5.0.1-01100-QCAHKSWPL_SILICONZ-1 -- --Signed-off-by: Aditya Kumar Singh --Signed-off-by: Kalle Valo --Link: https://lore.kernel.org/r/20230110121024.14051-4-quic_adisi@quicinc.com ----- -- drivers/net/wireless/ath/ath11k/reg.c | 2 +- -- drivers/net/wireless/ath/ath11k/wmi.c | 207 ++++++++++++++++++-------- -- drivers/net/wireless/ath/ath11k/wmi.h | 142 ++++++++++++++++++ -- 3 files changed, 291 insertions(+), 60 deletions(-) -- ----- a/drivers/net/wireless/ath/ath11k/reg.c --+++ b/drivers/net/wireless/ath/ath11k/reg.c --@@ -646,7 +646,7 @@ ath11k_reg_build_regd(struct ath11k_base -- tmp_regd->dfs_region = ath11k_map_fw_dfs_region(reg_info->dfs_region); -- -- ath11k_dbg(ab, ATH11K_DBG_REG, --- "\r\nCountry %s, CFG Regdomain %s FW Regdomain %d, num_reg_rules %d\n", --+ "Country %s, CFG Regdomain %s FW Regdomain %d, num_reg_rules %d\n", -- alpha2, ath11k_reg_get_regdom_str(tmp_regd->dfs_region), -- reg_info->dfs_region, num_rules); -- /* Update reg_rules[] below. Firmware is expected to ----- a/drivers/net/wireless/ath/ath11k/wmi.c --+++ b/drivers/net/wireless/ath/ath11k/wmi.c --@@ -4925,6 +4925,26 @@ static int ath11k_pull_vdev_start_resp_t -- return 0; -- } -- --+static void ath11k_print_reg_rule(struct ath11k_base *ab, const char *band, --+ u32 num_reg_rules, --+ struct cur_reg_rule *reg_rule_ptr) --+{ --+ struct cur_reg_rule *reg_rule = reg_rule_ptr; --+ u32 count; --+ --+ ath11k_dbg(ab, ATH11K_DBG_WMI, "number of reg rules in %s band: %d\n", --+ band, num_reg_rules); --+ --+ for (count = 0; count < num_reg_rules; count++) { --+ ath11k_dbg(ab, ATH11K_DBG_WMI, --+ "reg rule %d: (%d - %d @ %d) (%d, %d) (FLAGS %d)\n", --+ count + 1, reg_rule->start_freq, reg_rule->end_freq, --+ reg_rule->max_bw, reg_rule->ant_gain, --+ reg_rule->reg_power, reg_rule->flags); --+ reg_rule++; --+ } --+} --+ -- static struct cur_reg_rule -- *create_reg_rules_from_wmi(u32 num_reg_rules, -- struct wmi_regulatory_rule_struct *wmi_reg_rule) --@@ -5006,6 +5026,10 @@ static int ath11k_pull_reg_chan_list_upd -- reg_info->ctry_code = chan_list_event_hdr->country_id; -- reg_info->reg_dmn_pair = chan_list_event_hdr->domain_code; -- --+ ath11k_dbg(ab, ATH11K_DBG_WMI, --+ "status_code %s", --+ ath11k_cc_status_to_str(reg_info->status_code)); --+ -- reg_info->status_code = -- ath11k_wmi_cc_setting_code_to_reg(chan_list_event_hdr->status_code); -- --@@ -5020,13 +5044,13 @@ static int ath11k_pull_reg_chan_list_upd -- num_5ghz_reg_rules = reg_info->num_5ghz_reg_rules; -- -- ath11k_dbg(ab, ATH11K_DBG_WMI, --- "%s:cc %s dsf %d BW: min_2ghz %d max_2ghz %d min_5ghz %d max_5ghz %d", --- __func__, reg_info->alpha2, reg_info->dfs_region, --+ "cc %s dsf %d BW: min_2ghz %d max_2ghz %d min_5ghz %d max_5ghz %d", --+ reg_info->alpha2, reg_info->dfs_region, -- reg_info->min_bw_2ghz, reg_info->max_bw_2ghz, -- reg_info->min_bw_5ghz, reg_info->max_bw_5ghz); -- -- ath11k_dbg(ab, ATH11K_DBG_WMI, --- "%s: num_2ghz_reg_rules %d num_5ghz_reg_rules %d", __func__, --+ "num_2ghz_reg_rules %d num_5ghz_reg_rules %d", -- num_2ghz_reg_rules, num_5ghz_reg_rules); -- -- wmi_reg_rule = --@@ -5043,6 +5067,10 @@ static int ath11k_pull_reg_chan_list_upd -- ath11k_warn(ab, "Unable to Allocate memory for 2 GHz rules\n"); -- return -ENOMEM; -- } --+ --+ ath11k_print_reg_rule(ab, "2 GHz", --+ num_2ghz_reg_rules, --+ reg_info->reg_rules_2ghz_ptr); -- } -- -- if (num_5ghz_reg_rules) { --@@ -5055,6 +5083,10 @@ static int ath11k_pull_reg_chan_list_upd -- ath11k_warn(ab, "Unable to Allocate memory for 5 GHz rules\n"); -- return -ENOMEM; -- } --+ --+ ath11k_print_reg_rule(ab, "5 GHz", --+ num_5ghz_reg_rules, --+ reg_info->reg_rules_5ghz_ptr); -- } -- -- ath11k_dbg(ab, ATH11K_DBG_WMI, "processed regulatory channel list\n"); --@@ -5128,7 +5160,7 @@ static int ath11k_pull_reg_chan_list_ext -- struct cur_regulatory_info *reg_info) -- { -- const void **tb; --- const struct wmi_reg_chan_list_cc_ext_event *ext_chan_list_event_hdr; --+ const struct wmi_reg_chan_list_cc_ext_event *ev; -- struct wmi_regulatory_ext_rule *ext_wmi_reg_rule; -- u32 num_2ghz_reg_rules, num_5ghz_reg_rules; -- u32 num_6ghz_reg_rules_ap[WMI_REG_CURRENT_MAX_AP_TYPE]; --@@ -5145,31 +5177,29 @@ static int ath11k_pull_reg_chan_list_ext -- return ret; -- } -- --- ext_chan_list_event_hdr = tb[WMI_TAG_REG_CHAN_LIST_CC_EXT_EVENT]; --- if (!ext_chan_list_event_hdr) { --+ ev = tb[WMI_TAG_REG_CHAN_LIST_CC_EXT_EVENT]; --+ if (!ev) { -- ath11k_warn(ab, "failed to fetch reg chan list ext update ev\n"); -- kfree(tb); -- return -EPROTO; -- } -- --- reg_info->num_2ghz_reg_rules = --- ext_chan_list_event_hdr->num_2ghz_reg_rules; --- reg_info->num_5ghz_reg_rules = --- ext_chan_list_event_hdr->num_5ghz_reg_rules; --+ reg_info->num_2ghz_reg_rules = ev->num_2ghz_reg_rules; --+ reg_info->num_5ghz_reg_rules = ev->num_5ghz_reg_rules; -- reg_info->num_6ghz_rules_ap[WMI_REG_INDOOR_AP] = --- ext_chan_list_event_hdr->num_6ghz_reg_rules_ap_lpi; --+ ev->num_6ghz_reg_rules_ap_lpi; -- reg_info->num_6ghz_rules_ap[WMI_REG_STANDARD_POWER_AP] = --- ext_chan_list_event_hdr->num_6ghz_reg_rules_ap_sp; --+ ev->num_6ghz_reg_rules_ap_sp; -- reg_info->num_6ghz_rules_ap[WMI_REG_VERY_LOW_POWER_AP] = --- ext_chan_list_event_hdr->num_6ghz_reg_rules_ap_vlp; --+ ev->num_6ghz_reg_rules_ap_vlp; -- -- for (i = 0; i < WMI_REG_MAX_CLIENT_TYPE; i++) { -- reg_info->num_6ghz_rules_client[WMI_REG_INDOOR_AP][i] = --- ext_chan_list_event_hdr->num_6ghz_reg_rules_client_lpi[i]; --+ ev->num_6ghz_reg_rules_client_lpi[i]; -- reg_info->num_6ghz_rules_client[WMI_REG_STANDARD_POWER_AP][i] = --- ext_chan_list_event_hdr->num_6ghz_reg_rules_client_sp[i]; --+ ev->num_6ghz_reg_rules_client_sp[i]; -- reg_info->num_6ghz_rules_client[WMI_REG_VERY_LOW_POWER_AP][i] = --- ext_chan_list_event_hdr->num_6ghz_reg_rules_client_vlp[i]; --+ ev->num_6ghz_reg_rules_client_vlp[i]; -- } -- -- num_2ghz_reg_rules = reg_info->num_2ghz_reg_rules; --@@ -5231,57 +5261,79 @@ static int ath11k_pull_reg_chan_list_ext -- return -EINVAL; -- } -- --- memcpy(reg_info->alpha2, &ext_chan_list_event_hdr->alpha2, --- REG_ALPHA2_LEN); --+ memcpy(reg_info->alpha2, &ev->alpha2, REG_ALPHA2_LEN); --+ --+ reg_info->dfs_region = ev->dfs_region; --+ reg_info->phybitmap = ev->phybitmap; --+ reg_info->num_phy = ev->num_phy; --+ reg_info->phy_id = ev->phy_id; --+ reg_info->ctry_code = ev->country_id; --+ reg_info->reg_dmn_pair = ev->domain_code; -- --- reg_info->dfs_region = ext_chan_list_event_hdr->dfs_region; --- reg_info->phybitmap = ext_chan_list_event_hdr->phybitmap; --- reg_info->num_phy = ext_chan_list_event_hdr->num_phy; --- reg_info->phy_id = ext_chan_list_event_hdr->phy_id; --- reg_info->ctry_code = ext_chan_list_event_hdr->country_id; --- reg_info->reg_dmn_pair = ext_chan_list_event_hdr->domain_code; --+ ath11k_dbg(ab, ATH11K_DBG_WMI, --+ "status_code %s", --+ ath11k_cc_status_to_str(reg_info->status_code)); -- -- reg_info->status_code = --- ath11k_wmi_cc_setting_code_to_reg(ext_chan_list_event_hdr->status_code); --+ ath11k_wmi_cc_setting_code_to_reg(ev->status_code); -- -- reg_info->is_ext_reg_event = true; -- --- reg_info->min_bw_2ghz = ext_chan_list_event_hdr->min_bw_2ghz; --- reg_info->max_bw_2ghz = ext_chan_list_event_hdr->max_bw_2ghz; --- reg_info->min_bw_5ghz = ext_chan_list_event_hdr->min_bw_5ghz; --- reg_info->max_bw_5ghz = ext_chan_list_event_hdr->max_bw_5ghz; --+ reg_info->min_bw_2ghz = ev->min_bw_2ghz; --+ reg_info->max_bw_2ghz = ev->max_bw_2ghz; --+ reg_info->min_bw_5ghz = ev->min_bw_5ghz; --+ reg_info->max_bw_5ghz = ev->max_bw_5ghz; -- -- reg_info->min_bw_6ghz_ap[WMI_REG_INDOOR_AP] = --- ext_chan_list_event_hdr->min_bw_6ghz_ap_lpi; --+ ev->min_bw_6ghz_ap_lpi; -- reg_info->max_bw_6ghz_ap[WMI_REG_INDOOR_AP] = --- ext_chan_list_event_hdr->max_bw_6ghz_ap_lpi; --+ ev->max_bw_6ghz_ap_lpi; -- reg_info->min_bw_6ghz_ap[WMI_REG_STANDARD_POWER_AP] = --- ext_chan_list_event_hdr->min_bw_6ghz_ap_sp; --+ ev->min_bw_6ghz_ap_sp; -- reg_info->max_bw_6ghz_ap[WMI_REG_STANDARD_POWER_AP] = --- ext_chan_list_event_hdr->max_bw_6ghz_ap_sp; --+ ev->max_bw_6ghz_ap_sp; -- reg_info->min_bw_6ghz_ap[WMI_REG_VERY_LOW_POWER_AP] = --- ext_chan_list_event_hdr->min_bw_6ghz_ap_vlp; --+ ev->min_bw_6ghz_ap_vlp; -- reg_info->max_bw_6ghz_ap[WMI_REG_VERY_LOW_POWER_AP] = --- ext_chan_list_event_hdr->max_bw_6ghz_ap_vlp; --+ ev->max_bw_6ghz_ap_vlp; --+ --+ ath11k_dbg(ab, ATH11K_DBG_WMI, --+ "6 GHz AP BW: LPI (%d - %d), SP (%d - %d), VLP (%d - %d)\n", --+ reg_info->min_bw_6ghz_ap[WMI_REG_INDOOR_AP], --+ reg_info->max_bw_6ghz_ap[WMI_REG_INDOOR_AP], --+ reg_info->min_bw_6ghz_ap[WMI_REG_STANDARD_POWER_AP], --+ reg_info->max_bw_6ghz_ap[WMI_REG_STANDARD_POWER_AP], --+ reg_info->min_bw_6ghz_ap[WMI_REG_VERY_LOW_POWER_AP], --+ reg_info->max_bw_6ghz_ap[WMI_REG_VERY_LOW_POWER_AP]); -- -- for (i = 0; i < WMI_REG_MAX_CLIENT_TYPE; i++) { -- reg_info->min_bw_6ghz_client[WMI_REG_INDOOR_AP][i] = --- ext_chan_list_event_hdr->min_bw_6ghz_client_lpi[i]; --+ ev->min_bw_6ghz_client_lpi[i]; -- reg_info->max_bw_6ghz_client[WMI_REG_INDOOR_AP][i] = --- ext_chan_list_event_hdr->max_bw_6ghz_client_lpi[i]; --+ ev->max_bw_6ghz_client_lpi[i]; -- reg_info->min_bw_6ghz_client[WMI_REG_STANDARD_POWER_AP][i] = --- ext_chan_list_event_hdr->min_bw_6ghz_client_sp[i]; --+ ev->min_bw_6ghz_client_sp[i]; -- reg_info->max_bw_6ghz_client[WMI_REG_STANDARD_POWER_AP][i] = --- ext_chan_list_event_hdr->max_bw_6ghz_client_sp[i]; --+ ev->max_bw_6ghz_client_sp[i]; -- reg_info->min_bw_6ghz_client[WMI_REG_VERY_LOW_POWER_AP][i] = --- ext_chan_list_event_hdr->min_bw_6ghz_client_vlp[i]; --+ ev->min_bw_6ghz_client_vlp[i]; -- reg_info->max_bw_6ghz_client[WMI_REG_VERY_LOW_POWER_AP][i] = --- ext_chan_list_event_hdr->max_bw_6ghz_client_vlp[i]; --+ ev->max_bw_6ghz_client_vlp[i]; --+ --+ ath11k_dbg(ab, ATH11K_DBG_WMI, --+ "6 GHz %s BW: LPI (%d - %d), SP (%d - %d), VLP (%d - %d)\n", --+ ath11k_6ghz_client_type_to_str(i), --+ reg_info->min_bw_6ghz_client[WMI_REG_INDOOR_AP][i], --+ reg_info->max_bw_6ghz_client[WMI_REG_INDOOR_AP][i], --+ reg_info->min_bw_6ghz_client[WMI_REG_STANDARD_POWER_AP][i], --+ reg_info->max_bw_6ghz_client[WMI_REG_STANDARD_POWER_AP][i], --+ reg_info->min_bw_6ghz_client[WMI_REG_VERY_LOW_POWER_AP][i], --+ reg_info->max_bw_6ghz_client[WMI_REG_VERY_LOW_POWER_AP][i]); -- } -- -- ath11k_dbg(ab, ATH11K_DBG_WMI, --- "%s:cc_ext %s dsf %d BW: min_2ghz %d max_2ghz %d min_5ghz %d max_5ghz %d", --- __func__, reg_info->alpha2, reg_info->dfs_region, --+ "cc_ext %s dsf %d BW: min_2ghz %d max_2ghz %d min_5ghz %d max_5ghz %d", --+ reg_info->alpha2, reg_info->dfs_region, -- reg_info->min_bw_2ghz, reg_info->max_bw_2ghz, -- reg_info->min_bw_5ghz, reg_info->max_bw_5ghz); -- --@@ -5310,9 +5362,8 @@ static int ath11k_pull_reg_chan_list_ext -- num_6ghz_client[WMI_REG_VERY_LOW_POWER_AP][j]); -- -- ext_wmi_reg_rule = --- (struct wmi_regulatory_ext_rule *)((u8 *)ext_chan_list_event_hdr --- + sizeof(*ext_chan_list_event_hdr) --- + sizeof(struct wmi_tlv)); --+ (struct wmi_regulatory_ext_rule *)((u8 *)ev + sizeof(*ev) + --+ sizeof(struct wmi_tlv)); -- if (num_2ghz_reg_rules) { -- reg_info->reg_rules_2ghz_ptr = -- create_ext_reg_rules_from_wmi(num_2ghz_reg_rules, --@@ -5323,6 +5374,10 @@ static int ath11k_pull_reg_chan_list_ext -- ath11k_warn(ab, "Unable to Allocate memory for 2 GHz rules\n"); -- return -ENOMEM; -- } --+ --+ ath11k_print_reg_rule(ab, "2 GHz", --+ num_2ghz_reg_rules, --+ reg_info->reg_rules_2ghz_ptr); -- } -- -- ext_wmi_reg_rule += num_2ghz_reg_rules; --@@ -5358,6 +5413,10 @@ static int ath11k_pull_reg_chan_list_ext -- ath11k_warn(ab, "Unable to Allocate memory for 5 GHz rules\n"); -- return -ENOMEM; -- } --+ --+ ath11k_print_reg_rule(ab, "5 GHz", --+ num_5ghz_reg_rules, --+ reg_info->reg_rules_5ghz_ptr); -- } -- -- /* We have adjusted the number of 5 GHz reg rules above. But still those --@@ -5378,10 +5437,17 @@ static int ath11k_pull_reg_chan_list_ext -- return -ENOMEM; -- } -- --+ ath11k_print_reg_rule(ab, ath11k_6ghz_ap_type_to_str(i), --+ num_6ghz_reg_rules_ap[i], --+ reg_info->reg_rules_6ghz_ap_ptr[i]); --+ -- ext_wmi_reg_rule += num_6ghz_reg_rules_ap[i]; -- } -- -- for (j = 0; j < WMI_REG_CURRENT_MAX_AP_TYPE; j++) { --+ ath11k_dbg(ab, ATH11K_DBG_WMI, --+ "6 GHz AP type %s", ath11k_6ghz_ap_type_to_str(j)); --+ -- for (i = 0; i < WMI_REG_MAX_CLIENT_TYPE; i++) { -- reg_info->reg_rules_6ghz_client_ptr[j][i] = -- create_ext_reg_rules_from_wmi(num_6ghz_client[j][i], --@@ -5393,35 +5459,58 @@ static int ath11k_pull_reg_chan_list_ext -- return -ENOMEM; -- } -- --+ ath11k_print_reg_rule(ab, --+ ath11k_6ghz_client_type_to_str(i), --+ num_6ghz_client[j][i], --+ reg_info->reg_rules_6ghz_client_ptr[j][i]); --+ -- ext_wmi_reg_rule += num_6ghz_client[j][i]; -- } -- } -- --- reg_info->client_type = ext_chan_list_event_hdr->client_type; --- reg_info->rnr_tpe_usable = ext_chan_list_event_hdr->rnr_tpe_usable; --+ reg_info->client_type = ev->client_type; --+ reg_info->rnr_tpe_usable = ev->rnr_tpe_usable; -- reg_info->unspecified_ap_usable = --- ext_chan_list_event_hdr->unspecified_ap_usable; --+ ev->unspecified_ap_usable; -- reg_info->domain_code_6ghz_ap[WMI_REG_INDOOR_AP] = --- ext_chan_list_event_hdr->domain_code_6ghz_ap_lpi; --+ ev->domain_code_6ghz_ap_lpi; -- reg_info->domain_code_6ghz_ap[WMI_REG_STANDARD_POWER_AP] = --- ext_chan_list_event_hdr->domain_code_6ghz_ap_sp; --+ ev->domain_code_6ghz_ap_sp; -- reg_info->domain_code_6ghz_ap[WMI_REG_VERY_LOW_POWER_AP] = --- ext_chan_list_event_hdr->domain_code_6ghz_ap_vlp; --+ ev->domain_code_6ghz_ap_vlp; --+ --+ ath11k_dbg(ab, ATH11K_DBG_WMI, --+ "6 GHz reg info client type %s rnr_tpe_usable %d unspecified_ap_usable %d AP sub domain: lpi %s, sp %s, vlp %s\n", --+ ath11k_6ghz_client_type_to_str(reg_info->client_type), --+ reg_info->rnr_tpe_usable, --+ reg_info->unspecified_ap_usable, --+ ath11k_sub_reg_6ghz_to_str(ev->domain_code_6ghz_ap_lpi), --+ ath11k_sub_reg_6ghz_to_str(ev->domain_code_6ghz_ap_sp), --+ ath11k_sub_reg_6ghz_to_str(ev->domain_code_6ghz_ap_vlp)); -- -- for (i = 0; i < WMI_REG_MAX_CLIENT_TYPE; i++) { -- reg_info->domain_code_6ghz_client[WMI_REG_INDOOR_AP][i] = --- ext_chan_list_event_hdr->domain_code_6ghz_client_lpi[i]; --+ ev->domain_code_6ghz_client_lpi[i]; -- reg_info->domain_code_6ghz_client[WMI_REG_STANDARD_POWER_AP][i] = --- ext_chan_list_event_hdr->domain_code_6ghz_client_sp[i]; --+ ev->domain_code_6ghz_client_sp[i]; -- reg_info->domain_code_6ghz_client[WMI_REG_VERY_LOW_POWER_AP][i] = --- ext_chan_list_event_hdr->domain_code_6ghz_client_vlp[i]; --+ ev->domain_code_6ghz_client_vlp[i]; --+ --+ ath11k_dbg(ab, ATH11K_DBG_WMI, --+ "6 GHz client type %s client sub domain: lpi %s, sp %s, vlp %s\n", --+ ath11k_6ghz_client_type_to_str(i), --+ ath11k_sub_reg_6ghz_to_str(ev->domain_code_6ghz_client_lpi[i]), --+ ath11k_sub_reg_6ghz_to_str(ev->domain_code_6ghz_client_sp[i]), --+ ath11k_sub_reg_6ghz_to_str(ev->domain_code_6ghz_client_vlp[i]) --+ ); -- } -- --- reg_info->domain_code_6ghz_super_id = --- ext_chan_list_event_hdr->domain_code_6ghz_super_id; --+ reg_info->domain_code_6ghz_super_id = ev->domain_code_6ghz_super_id; -- --- ath11k_dbg(ab, ATH11K_DBG_WMI, "6 GHz client_type: %d domain_code_6ghz_super_id: %d", --- reg_info->client_type, reg_info->domain_code_6ghz_super_id); --+ ath11k_dbg(ab, ATH11K_DBG_WMI, --+ "6 GHz client_type %s 6 GHz super domain %s", --+ ath11k_6ghz_client_type_to_str(reg_info->client_type), --+ ath11k_super_reg_6ghz_to_str(reg_info->domain_code_6ghz_super_id)); -- -- ath11k_dbg(ab, ATH11K_DBG_WMI, "processed regulatory ext channel list\n"); -- ----- a/drivers/net/wireless/ath/ath11k/wmi.h --+++ b/drivers/net/wireless/ath/ath11k/wmi.h --@@ -4139,6 +4139,7 @@ enum cc_setting_code { -- -- /* add new setting code above, update in -- * @enum wmi_reg_cc_setting_code as well. --+ * Also handle it in ath11k_cc_status_to_str() -- */ -- }; -- --@@ -4163,21 +4164,162 @@ ath11k_wmi_cc_setting_code_to_reg(enum w -- return REG_SET_CC_STATUS_FAIL; -- } -- --+static inline const char *ath11k_cc_status_to_str(enum cc_setting_code code) --+{ --+ switch (code) { --+ case REG_SET_CC_STATUS_PASS: --+ return "REG_SET_CC_STATUS_PASS"; --+ case REG_CURRENT_ALPHA2_NOT_FOUND: --+ return "REG_CURRENT_ALPHA2_NOT_FOUND"; --+ case REG_INIT_ALPHA2_NOT_FOUND: --+ return "REG_INIT_ALPHA2_NOT_FOUND"; --+ case REG_SET_CC_CHANGE_NOT_ALLOWED: --+ return "REG_SET_CC_CHANGE_NOT_ALLOWED"; --+ case REG_SET_CC_STATUS_NO_MEMORY: --+ return "REG_SET_CC_STATUS_NO_MEMORY"; --+ case REG_SET_CC_STATUS_FAIL: --+ return "REG_SET_CC_STATUS_FAIL"; --+ } --+ --+ return "Unknown CC status"; --+} --+ -- enum wmi_reg_6ghz_ap_type { -- WMI_REG_INDOOR_AP = 0, -- WMI_REG_STANDARD_POWER_AP = 1, -- WMI_REG_VERY_LOW_POWER_AP = 2, -- --+ /* add AP type above, handle in ath11k_6ghz_ap_type_to_str() --+ */ -- WMI_REG_CURRENT_MAX_AP_TYPE, -- WMI_REG_MAX_AP_TYPE = 7, -- }; -- --+static inline const char * --+ath11k_6ghz_ap_type_to_str(enum wmi_reg_6ghz_ap_type type) --+{ --+ switch (type) { --+ case WMI_REG_INDOOR_AP: --+ return "INDOOR AP"; --+ case WMI_REG_STANDARD_POWER_AP: --+ return "STANDARD POWER AP"; --+ case WMI_REG_VERY_LOW_POWER_AP: --+ return "VERY LOW POWER AP"; --+ case WMI_REG_CURRENT_MAX_AP_TYPE: --+ return "CURRENT_MAX_AP_TYPE"; --+ case WMI_REG_MAX_AP_TYPE: --+ return "MAX_AP_TYPE"; --+ } --+ --+ return "unknown 6 GHz AP type"; --+} --+ -- enum wmi_reg_6ghz_client_type { -- WMI_REG_DEFAULT_CLIENT = 0, -- WMI_REG_SUBORDINATE_CLIENT = 1, -- WMI_REG_MAX_CLIENT_TYPE = 2, --+ --+ /* add client type above, handle it in --+ * ath11k_6ghz_client_type_to_str() --+ */ --+}; --+ --+static inline const char * --+ath11k_6ghz_client_type_to_str(enum wmi_reg_6ghz_client_type type) --+{ --+ switch (type) { --+ case WMI_REG_DEFAULT_CLIENT: --+ return "DEFAULT CLIENT"; --+ case WMI_REG_SUBORDINATE_CLIENT: --+ return "SUBORDINATE CLIENT"; --+ case WMI_REG_MAX_CLIENT_TYPE: --+ return "MAX_CLIENT_TYPE"; --+ } --+ --+ return "unknown 6 GHz client type"; --+} --+ --+enum reg_subdomains_6ghz { --+ EMPTY_6GHZ = 0x0, --+ FCC1_CLIENT_LPI_REGULAR_6GHZ = 0x01, --+ FCC1_CLIENT_SP_6GHZ = 0x02, --+ FCC1_AP_LPI_6GHZ = 0x03, --+ FCC1_CLIENT_LPI_SUBORDINATE = FCC1_AP_LPI_6GHZ, --+ FCC1_AP_SP_6GHZ = 0x04, --+ ETSI1_LPI_6GHZ = 0x10, --+ ETSI1_VLP_6GHZ = 0x11, --+ ETSI2_LPI_6GHZ = 0x12, --+ ETSI2_VLP_6GHZ = 0x13, --+ APL1_LPI_6GHZ = 0x20, --+ APL1_VLP_6GHZ = 0x21, --+ --+ /* add sub-domain above, handle it in --+ * ath11k_sub_reg_6ghz_to_str() --+ */ --+}; --+ --+static inline const char * --+ath11k_sub_reg_6ghz_to_str(enum reg_subdomains_6ghz sub_id) --+{ --+ switch (sub_id) { --+ case EMPTY_6GHZ: --+ return "N/A"; --+ case FCC1_CLIENT_LPI_REGULAR_6GHZ: --+ return "FCC1_CLIENT_LPI_REGULAR_6GHZ"; --+ case FCC1_CLIENT_SP_6GHZ: --+ return "FCC1_CLIENT_SP_6GHZ"; --+ case FCC1_AP_LPI_6GHZ: --+ return "FCC1_AP_LPI_6GHZ/FCC1_CLIENT_LPI_SUBORDINATE"; --+ case FCC1_AP_SP_6GHZ: --+ return "FCC1_AP_SP_6GHZ"; --+ case ETSI1_LPI_6GHZ: --+ return "ETSI1_LPI_6GHZ"; --+ case ETSI1_VLP_6GHZ: --+ return "ETSI1_VLP_6GHZ"; --+ case ETSI2_LPI_6GHZ: --+ return "ETSI2_LPI_6GHZ"; --+ case ETSI2_VLP_6GHZ: --+ return "ETSI2_VLP_6GHZ"; --+ case APL1_LPI_6GHZ: --+ return "APL1_LPI_6GHZ"; --+ case APL1_VLP_6GHZ: --+ return "APL1_VLP_6GHZ"; --+ } --+ --+ return "unknown sub reg id"; --+} --+ --+enum reg_super_domain_6ghz { --+ FCC1_6GHZ = 0x01, --+ ETSI1_6GHZ = 0x02, --+ ETSI2_6GHZ = 0x03, --+ APL1_6GHZ = 0x04, --+ FCC1_6GHZ_CL = 0x05, --+ --+ /* add super domain above, handle it in --+ * ath11k_super_reg_6ghz_to_str() --+ */ -- }; -- --+static inline const char * --+ath11k_super_reg_6ghz_to_str(enum reg_super_domain_6ghz domain_id) --+{ --+ switch (domain_id) { --+ case FCC1_6GHZ: --+ return "FCC1_6GHZ"; --+ case ETSI1_6GHZ: --+ return "ETSI1_6GHZ"; --+ case ETSI2_6GHZ: --+ return "ETSI2_6GHZ"; --+ case APL1_6GHZ: --+ return "APL1_6GHZ"; --+ case FCC1_6GHZ_CL: --+ return "FCC1_6GHZ_CL"; --+ } --+ --+ return "unknown domain id"; --+} --+ -- struct cur_reg_rule { -- u16 start_freq; -- u16 end_freq; -diff --git a/package/kernel/mac80211/patches/ath11k/0046-wifi-ath11k-Replace-fake-flex-array-with-flexible-ar.patch b/package/kernel/mac80211/patches/ath11k/0046-wifi-ath11k-Replace-fake-flex-array-with-flexible-ar.patch -deleted file mode 100644 -index bd16178564..0000000000 ---- a/package/kernel/mac80211/patches/ath11k/0046-wifi-ath11k-Replace-fake-flex-array-with-flexible-ar.patch -+++ /dev/null -@@ -1,246 +0,0 @@ --From 3b1088a09ec9438523c251d8435e78988824bc0d Mon Sep 17 00:00:00 2001 --From: "Gustavo A. R. Silva" --Date: Tue, 7 Mar 2023 16:22:39 -0600 --Subject: [PATCH] wifi: ath11k: Replace fake flex-array with flexible-array -- member --MIME-Version: 1.0 --Content-Type: text/plain; charset=UTF-8 --Content-Transfer-Encoding: 8bit -- --Zero-length arrays as fake flexible arrays are deprecated and we are --moving towards adopting C99 flexible-array members instead. -- --Address 25 of the following warnings found with GCC-13 and ---fstrict-flex-arrays=3 enabled: --drivers/net/wireless/ath/ath11k/debugfs_htt_stats.c:30:51: warning: array subscript is outside array bounds of ‘const u32[0]’ {aka ‘const unsigned int[]’} [-Warray-bounds=] -- --This helps with the ongoing efforts to tighten the FORTIFY_SOURCE --routines on memcpy() and help us make progress towards globally --enabling -fstrict-flex-arrays=3 [1]. -- --Link: https://github.com/KSPP/linux/issues/21 --Link: https://github.com/KSPP/linux/issues/266 --Link: https://gcc.gnu.org/pipermail/gcc-patches/2022-October/602902.html [1] --Signed-off-by: Gustavo A. R. Silva --Reviewed-by: Simon Horman --Signed-off-by: Kalle Valo --Link: https://lore.kernel.org/r/ZAe5L5DtmsQxzqRH@work ----- -- .../wireless/ath/ath11k/debugfs_htt_stats.h | 73 +++++++++++-------- -- 1 file changed, 43 insertions(+), 30 deletions(-) -- ----- a/drivers/net/wireless/ath/ath11k/debugfs_htt_stats.h --+++ b/drivers/net/wireless/ath/ath11k/debugfs_htt_stats.h --@@ -143,7 +143,8 @@ enum htt_tx_pdev_underrun_enum { -- /* Bytes stored in little endian order */ -- /* Length should be multiple of DWORD */ -- struct htt_stats_string_tlv { --- u32 data[0]; /* Can be variable length */ --+ /* Can be variable length */ --+ DECLARE_FLEX_ARRAY(u32, data); -- } __packed; -- -- #define HTT_STATS_MAC_ID GENMASK(7, 0) --@@ -205,27 +206,32 @@ struct htt_tx_pdev_stats_cmn_tlv { -- -- /* NOTE: Variable length TLV, use length spec to infer array size */ -- struct htt_tx_pdev_stats_urrn_tlv_v { --- u32 urrn_stats[0]; /* HTT_TX_PDEV_MAX_URRN_STATS */ --+ /* HTT_TX_PDEV_MAX_URRN_STATS */ --+ DECLARE_FLEX_ARRAY(u32, urrn_stats); -- }; -- -- /* NOTE: Variable length TLV, use length spec to infer array size */ -- struct htt_tx_pdev_stats_flush_tlv_v { --- u32 flush_errs[0]; /* HTT_TX_PDEV_MAX_FLUSH_REASON_STATS */ --+ /* HTT_TX_PDEV_MAX_FLUSH_REASON_STATS */ --+ DECLARE_FLEX_ARRAY(u32, flush_errs); -- }; -- -- /* NOTE: Variable length TLV, use length spec to infer array size */ -- struct htt_tx_pdev_stats_sifs_tlv_v { --- u32 sifs_status[0]; /* HTT_TX_PDEV_MAX_SIFS_BURST_STATS */ --+ /* HTT_TX_PDEV_MAX_SIFS_BURST_STATS */ --+ DECLARE_FLEX_ARRAY(u32, sifs_status); -- }; -- -- /* NOTE: Variable length TLV, use length spec to infer array size */ -- struct htt_tx_pdev_stats_phy_err_tlv_v { --- u32 phy_errs[0]; /* HTT_TX_PDEV_MAX_PHY_ERR_STATS */ --+ /* HTT_TX_PDEV_MAX_PHY_ERR_STATS */ --+ DECLARE_FLEX_ARRAY(u32, phy_errs); -- }; -- -- /* NOTE: Variable length TLV, use length spec to infer array size */ -- struct htt_tx_pdev_stats_sifs_hist_tlv_v { --- u32 sifs_hist_status[0]; /* HTT_TX_PDEV_SIFS_BURST_HIST_STATS */ --+ /* HTT_TX_PDEV_SIFS_BURST_HIST_STATS */ --+ DECLARE_FLEX_ARRAY(u32, sifs_hist_status); -- }; -- -- struct htt_tx_pdev_stats_tx_ppdu_stats_tlv_v { --@@ -590,20 +596,20 @@ struct htt_tx_hwq_difs_latency_stats_tlv -- -- /* NOTE: Variable length TLV, use length spec to infer array size */ -- struct htt_tx_hwq_cmd_result_stats_tlv_v { --- /* Histogram of sched cmd result */ --- u32 cmd_result[0]; /* HTT_TX_HWQ_MAX_CMD_RESULT_STATS */ --+ /* Histogram of sched cmd result, HTT_TX_HWQ_MAX_CMD_RESULT_STATS */ --+ DECLARE_FLEX_ARRAY(u32, cmd_result); -- }; -- -- /* NOTE: Variable length TLV, use length spec to infer array size */ -- struct htt_tx_hwq_cmd_stall_stats_tlv_v { --- /* Histogram of various pause conitions */ --- u32 cmd_stall_status[0]; /* HTT_TX_HWQ_MAX_CMD_STALL_STATS */ --+ /* Histogram of various pause conitions, HTT_TX_HWQ_MAX_CMD_STALL_STATS */ --+ DECLARE_FLEX_ARRAY(u32, cmd_stall_status); -- }; -- -- /* NOTE: Variable length TLV, use length spec to infer array size */ -- struct htt_tx_hwq_fes_result_stats_tlv_v { --- /* Histogram of number of user fes result */ --- u32 fes_result[0]; /* HTT_TX_HWQ_MAX_FES_RESULT_STATS */ --+ /* Histogram of number of user fes result, HTT_TX_HWQ_MAX_FES_RESULT_STATS */ --+ DECLARE_FLEX_ARRAY(u32, fes_result); -- }; -- -- /* NOTE: Variable length TLV, use length spec to infer array size --@@ -635,8 +641,8 @@ struct htt_tx_hwq_tried_mpdu_cnt_hist_tl -- * #define WAL_TXOP_USED_HISTOGRAM_INTERVAL 1000 ( 1 ms ) -- */ -- struct htt_tx_hwq_txop_used_cnt_hist_tlv_v { --- /* Histogram of txop used cnt */ --- u32 txop_used_cnt_hist[0]; /* HTT_TX_HWQ_TXOP_USED_CNT_HIST */ --+ /* Histogram of txop used cnt, HTT_TX_HWQ_TXOP_USED_CNT_HIST */ --+ DECLARE_FLEX_ARRAY(u32, txop_used_cnt_hist); -- }; -- -- /* == TX SELFGEN STATS == */ --@@ -804,17 +810,20 @@ struct htt_tx_pdev_mpdu_stats_tlv { -- /* == TX SCHED STATS == */ -- /* NOTE: Variable length TLV, use length spec to infer array size */ -- struct htt_sched_txq_cmd_posted_tlv_v { --- u32 sched_cmd_posted[0]; /* HTT_TX_PDEV_SCHED_TX_MODE_MAX */ --+ /* HTT_TX_PDEV_SCHED_TX_MODE_MAX */ --+ DECLARE_FLEX_ARRAY(u32, sched_cmd_posted); -- }; -- -- /* NOTE: Variable length TLV, use length spec to infer array size */ -- struct htt_sched_txq_cmd_reaped_tlv_v { --- u32 sched_cmd_reaped[0]; /* HTT_TX_PDEV_SCHED_TX_MODE_MAX */ --+ /* HTT_TX_PDEV_SCHED_TX_MODE_MAX */ --+ DECLARE_FLEX_ARRAY(u32, sched_cmd_reaped); -- }; -- -- /* NOTE: Variable length TLV, use length spec to infer array size */ -- struct htt_sched_txq_sched_order_su_tlv_v { --- u32 sched_order_su[0]; /* HTT_TX_PDEV_NUM_SCHED_ORDER_LOG */ --+ /* HTT_TX_PDEV_NUM_SCHED_ORDER_LOG */ --+ DECLARE_FLEX_ARRAY(u32, sched_order_su); -- }; -- -- enum htt_sched_txq_sched_ineligibility_tlv_enum { --@@ -842,7 +851,7 @@ enum htt_sched_txq_sched_ineligibility_t -- /* NOTE: Variable length TLV, use length spec to infer array size */ -- struct htt_sched_txq_sched_ineligibility_tlv_v { -- /* indexed by htt_sched_txq_sched_ineligibility_tlv_enum */ --- u32 sched_ineligibility[0]; --+ DECLARE_FLEX_ARRAY(u32, sched_ineligibility); -- }; -- -- #define HTT_TX_PDEV_STATS_SCHED_PER_TXQ_MAC_ID GENMASK(7, 0) --@@ -888,18 +897,20 @@ struct htt_stats_tx_sched_cmn_tlv { -- -- /* NOTE: Variable length TLV, use length spec to infer array size */ -- struct htt_tx_tqm_gen_mpdu_stats_tlv_v { --- u32 gen_mpdu_end_reason[0]; /* HTT_TX_TQM_MAX_GEN_MPDU_END_REASON */ --+ /* HTT_TX_TQM_MAX_GEN_MPDU_END_REASON */ --+ DECLARE_FLEX_ARRAY(u32, gen_mpdu_end_reason); -- }; -- -- /* NOTE: Variable length TLV, use length spec to infer array size */ -- struct htt_tx_tqm_list_mpdu_stats_tlv_v { --- u32 list_mpdu_end_reason[0]; /* HTT_TX_TQM_MAX_LIST_MPDU_END_REASON */ --+ /* HTT_TX_TQM_MAX_LIST_MPDU_END_REASON */ --+ DECLARE_FLEX_ARRAY(u32, list_mpdu_end_reason); -- }; -- -- /* NOTE: Variable length TLV, use length spec to infer array size */ -- struct htt_tx_tqm_list_mpdu_cnt_tlv_v { --- u32 list_mpdu_cnt_hist[0]; --- /* HTT_TX_TQM_MAX_LIST_MPDU_CNT_HISTOGRAM_BINS */ --+ /* HTT_TX_TQM_MAX_LIST_MPDU_CNT_HISTOGRAM_BINS */ --+ DECLARE_FLEX_ARRAY(u32, list_mpdu_cnt_hist); -- }; -- -- struct htt_tx_tqm_pdev_stats_tlv_v { --@@ -1098,7 +1109,7 @@ struct htt_tx_de_compl_stats_tlv { -- * ENTRIES_PER_BIN_COUNT) -- */ -- struct htt_tx_de_fw2wbm_ring_full_hist_tlv { --- u32 fw2wbm_ring_full_hist[0]; --+ DECLARE_FLEX_ARRAY(u32, fw2wbm_ring_full_hist); -- }; -- -- struct htt_tx_de_cmn_stats_tlv { --@@ -1151,7 +1162,7 @@ struct htt_ring_if_cmn_tlv { -- /* NOTE: Variable length TLV, use length spec to infer array size */ -- struct htt_sfm_client_user_tlv_v { -- /* Number of DWORDS used per user and per client */ --- u32 dwords_used_by_user_n[0]; --+ DECLARE_FLEX_ARRAY(u32, dwords_used_by_user_n); -- }; -- -- struct htt_sfm_client_tlv { --@@ -1436,12 +1447,14 @@ struct htt_rx_soc_fw_stats_tlv { -- -- /* NOTE: Variable length TLV, use length spec to infer array size */ -- struct htt_rx_soc_fw_refill_ring_empty_tlv_v { --- u32 refill_ring_empty_cnt[0]; /* HTT_RX_STATS_REFILL_MAX_RING */ --+ /* HTT_RX_STATS_REFILL_MAX_RING */ --+ DECLARE_FLEX_ARRAY(u32, refill_ring_empty_cnt); -- }; -- -- /* NOTE: Variable length TLV, use length spec to infer array size */ -- struct htt_rx_soc_fw_refill_ring_num_refill_tlv_v { --- u32 refill_ring_num_refill[0]; /* HTT_RX_STATS_REFILL_MAX_RING */ --+ /* HTT_RX_STATS_REFILL_MAX_RING */ --+ DECLARE_FLEX_ARRAY(u32, refill_ring_num_refill); -- }; -- -- /* RXDMA error code from WBM released packets */ --@@ -1473,7 +1486,7 @@ enum htt_rx_rxdma_error_code_enum { -- -- /* NOTE: Variable length TLV, use length spec to infer array size */ -- struct htt_rx_soc_fw_refill_ring_num_rxdma_err_tlv_v { --- u32 rxdma_err[0]; /* HTT_RX_RXDMA_MAX_ERR_CODE */ --+ DECLARE_FLEX_ARRAY(u32, rxdma_err); /* HTT_RX_RXDMA_MAX_ERR_CODE */ -- }; -- -- /* REO error code from WBM released packets */ --@@ -1505,7 +1518,7 @@ enum htt_rx_reo_error_code_enum { -- -- /* NOTE: Variable length TLV, use length spec to infer array size */ -- struct htt_rx_soc_fw_refill_ring_num_reo_err_tlv_v { --- u32 reo_err[0]; /* HTT_RX_REO_MAX_ERR_CODE */ --+ DECLARE_FLEX_ARRAY(u32, reo_err); /* HTT_RX_REO_MAX_ERR_CODE */ -- }; -- -- /* == RX PDEV STATS == */ --@@ -1622,13 +1635,13 @@ struct htt_rx_pdev_fw_stats_phy_err_tlv -- /* NOTE: Variable length TLV, use length spec to infer array size */ -- struct htt_rx_pdev_fw_ring_mpdu_err_tlv_v { -- /* Num error MPDU for each RxDMA error type */ --- u32 fw_ring_mpdu_err[0]; /* HTT_RX_STATS_RXDMA_MAX_ERR */ --+ DECLARE_FLEX_ARRAY(u32, fw_ring_mpdu_err); /* HTT_RX_STATS_RXDMA_MAX_ERR */ -- }; -- -- /* NOTE: Variable length TLV, use length spec to infer array size */ -- struct htt_rx_pdev_fw_mpdu_drop_tlv_v { -- /* Num MPDU dropped */ --- u32 fw_mpdu_drop[0]; /* HTT_RX_STATS_FW_DROP_REASON_MAX */ --+ DECLARE_FLEX_ARRAY(u32, fw_mpdu_drop); /* HTT_RX_STATS_FW_DROP_REASON_MAX */ -- }; -- -- #define HTT_PDEV_CCA_STATS_TX_FRAME_INFO_PRESENT (0x1) -diff --git a/package/kernel/mac80211/patches/ath11k/0047-wifi-ath11k-fix-deinitialization-of-firmware-resourc.patch b/package/kernel/mac80211/patches/ath11k/0047-wifi-ath11k-fix-deinitialization-of-firmware-resourc.patch -deleted file mode 100644 -index eec11f50e3..0000000000 ---- a/package/kernel/mac80211/patches/ath11k/0047-wifi-ath11k-fix-deinitialization-of-firmware-resourc.patch -+++ /dev/null -@@ -1,79 +0,0 @@ --From 5a78ac33e3cb8822da64dd1af196e83664b332b0 Mon Sep 17 00:00:00 2001 --From: Aditya Kumar Singh --Date: Thu, 9 Mar 2023 15:23:08 +0530 --Subject: [PATCH] wifi: ath11k: fix deinitialization of firmware resources -- --Currently, in ath11k_ahb_fw_resources_init(), iommu domain --mapping is done only for the chipsets having fixed firmware --memory. Also, for such chipsets, mapping is done only if it --does not have TrustZone support. -- --During deinitialization, only if TrustZone support is not there, --iommu is unmapped back. However, for non fixed firmware memory --chipsets, TrustZone support is not there and this makes the --condition check to true and it tries to unmap the memory which --was not mapped during initialization. -- --This leads to the following trace - -- --[ 83.198790] Unable to handle kernel NULL pointer dereference at virtual address 0000000000000008 --[ 83.259537] Modules linked in: ath11k_ahb ath11k qmi_helpers --.. snip .. --[ 83.280286] pstate: 20000005 (nzCv daif -PAN -UAO -TCO -DIT -SSBS BTYPE=--) --[ 83.287228] pc : __iommu_unmap+0x30/0x140 --[ 83.293907] lr : iommu_unmap+0x5c/0xa4 --[ 83.298072] sp : ffff80000b3abad0 --.. snip .. --[ 83.369175] Call trace: --[ 83.376282] __iommu_unmap+0x30/0x140 --[ 83.378541] iommu_unmap+0x5c/0xa4 --[ 83.382360] ath11k_ahb_fw_resource_deinit.part.12+0x2c/0xac [ath11k_ahb] --[ 83.385666] ath11k_ahb_free_resources+0x140/0x17c [ath11k_ahb] --[ 83.392521] ath11k_ahb_shutdown+0x34/0x40 [ath11k_ahb] --[ 83.398248] platform_shutdown+0x20/0x2c --[ 83.403455] device_shutdown+0x16c/0x1c4 --[ 83.407621] kernel_restart_prepare+0x34/0x3c --[ 83.411529] kernel_restart+0x14/0x74 --[ 83.415781] __do_sys_reboot+0x1c4/0x22c --[ 83.419427] __arm64_sys_reboot+0x1c/0x24 --[ 83.423420] invoke_syscall+0x44/0xfc --[ 83.427326] el0_svc_common.constprop.3+0xac/0xe8 --[ 83.430974] do_el0_svc+0xa0/0xa8 --[ 83.435659] el0_svc+0x1c/0x44 --[ 83.438957] el0t_64_sync_handler+0x60/0x144 --[ 83.441910] el0t_64_sync+0x15c/0x160 --[ 83.446343] Code: aa0103f4 f9400001 f90027a1 d2800001 (f94006a0) --[ 83.449903] ---[ end trace 0000000000000000 ]--- -- --This can be reproduced by probing an AHB chipset which is not --having a fixed memory region. During reboot (or rmmod) trace --can be seen. -- --Fix this issue by adding a condition check on firmware fixed memory --hw_param as done in the counter initialization function. -- --Tested-on: IPQ8074 hw2.0 AHB WLAN.HK.2.7.0.1-01744-QCAHKSWPL_SILICONZ-1 -- --Fixes: f9eec4947add ("ath11k: Add support for targets without trustzone") --Signed-off-by: Aditya Kumar Singh --Signed-off-by: Kalle Valo --Link: https://lore.kernel.org/r/20230309095308.24937-1-quic_adisi@quicinc.com ----- -- drivers/net/wireless/ath/ath11k/ahb.c | 6 ++++++ -- 1 file changed, 6 insertions(+) -- ----- a/drivers/net/wireless/ath/ath11k/ahb.c --+++ b/drivers/net/wireless/ath/ath11k/ahb.c --@@ -1078,6 +1078,12 @@ static int ath11k_ahb_fw_resource_deinit -- struct iommu_domain *iommu; -- size_t unmapped_size; -- --+ /* Chipsets not requiring MSA would have not initialized --+ * MSA resources, return success in such cases. --+ */ --+ if (!ab->hw_params.fixed_fw_mem) --+ return 0; --+ -- if (ab_ahb->fw.use_tz) -- return 0; -- -diff --git a/package/kernel/mac80211/patches/ath11k/0048-wifi-ath11k-fix-BUFFER_DONE-read-on-monitor-ring-rx-.patch b/package/kernel/mac80211/patches/ath11k/0048-wifi-ath11k-fix-BUFFER_DONE-read-on-monitor-ring-rx-.patch -deleted file mode 100644 -index 3e22645331..0000000000 ---- a/package/kernel/mac80211/patches/ath11k/0048-wifi-ath11k-fix-BUFFER_DONE-read-on-monitor-ring-rx-.patch -+++ /dev/null -@@ -1,130 +0,0 @@ --From 68e93ac5a31d4975b25f819b2dfe914c72abc3bb Mon Sep 17 00:00:00 2001 --From: Harshitha Prem --Date: Wed, 15 Mar 2023 12:24:43 +0200 --Subject: [PATCH] wifi: ath11k: fix BUFFER_DONE read on monitor ring rx buffer -- --Perform dma_sync_single_for_cpu() on monitor ring rx buffer before --reading BUFFER_DONE tag and do dma_unmap_single() only after device --had set BUFFER_DONE tag to the buffer. -- --Also when BUFFER_DONE tag is not set, allow the buffer to get read --next time without freeing skb. -- --This helps to fix AP+Monitor VAP with flood traffic scenario to see --monitor ring rx buffer overrun missing BUFFER_DONE tag to be set. -- --Also remove redundant rx dma buf free performed on DP --rx_mon_status_refill_ring. -- --Tested-on: IPQ8074 hw2.0 AHB WLAN.HK.2.7.0.1-01744-QCAHKSWPL_SILICONZ-1 -- --Signed-off-by: Sathishkumar Muruganandam --Signed-off-by: Harshitha Prem --Signed-off-by: Kalle Valo --Link: https://lore.kernel.org/r/20230309164434.32660-1-quic_hprem@quicinc.com ----- -- drivers/net/wireless/ath/ath11k/dp_rx.c | 57 ++++++++++--------------- -- 1 file changed, 23 insertions(+), 34 deletions(-) -- ----- a/drivers/net/wireless/ath/ath11k/dp_rx.c --+++ b/drivers/net/wireless/ath/ath11k/dp_rx.c --@@ -435,7 +435,6 @@ fail_free_skb: -- static int ath11k_dp_rxdma_buf_ring_free(struct ath11k *ar, -- struct dp_rxdma_ring *rx_ring) -- { --- struct ath11k_pdev_dp *dp = &ar->dp; -- struct sk_buff *skb; -- int buf_id; -- --@@ -453,28 +452,6 @@ static int ath11k_dp_rxdma_buf_ring_free -- idr_destroy(&rx_ring->bufs_idr); -- spin_unlock_bh(&rx_ring->idr_lock); -- --- /* if rxdma1_enable is false, mon_status_refill_ring --- * isn't setup, so don't clean. --- */ --- if (!ar->ab->hw_params.rxdma1_enable) --- return 0; --- --- rx_ring = &dp->rx_mon_status_refill_ring[0]; --- --- spin_lock_bh(&rx_ring->idr_lock); --- idr_for_each_entry(&rx_ring->bufs_idr, skb, buf_id) { --- idr_remove(&rx_ring->bufs_idr, buf_id); --- /* XXX: Understand where internal driver does this dma_unmap --- * of rxdma_buffer. --- */ --- dma_unmap_single(ar->ab->dev, ATH11K_SKB_RXCB(skb)->paddr, --- skb->len + skb_tailroom(skb), DMA_BIDIRECTIONAL); --- dev_kfree_skb_any(skb); --- } --- --- idr_destroy(&rx_ring->bufs_idr); --- spin_unlock_bh(&rx_ring->idr_lock); --- -- return 0; -- } -- --@@ -3029,39 +3006,51 @@ static int ath11k_dp_rx_reap_mon_status_ -- -- 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) { -- ath11k_warn(ab, "rx monitor status with invalid buf_id %d\n", -- buf_id); --- spin_unlock_bh(&rx_ring->idr_lock); -- pmon->buf_state = DP_MON_STATUS_REPLINISH; -- goto move_next; -- } -- --- 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, --- skb->len + skb_tailroom(skb), --- DMA_FROM_DEVICE); --+ 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) { --- ath11k_warn(ab, "mon status DONE not set %lx\n", --+ ath11k_warn(ab, "mon status DONE not set %lx, buf_id %d\n", -- FIELD_GET(HAL_TLV_HDR_TAG, --- tlv->tl)); --- dev_kfree_skb_any(skb); --+ 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 --+ */ -- pmon->buf_state = DP_MON_STATUS_NO_DMA; --- goto move_next; --+ break; -- } -- --+ spin_lock_bh(&rx_ring->idr_lock); --+ idr_remove(&rx_ring->bufs_idr, buf_id); --+ spin_unlock_bh(&rx_ring->idr_lock); -- if (ab->hw_params.full_monitor_mode) { -- ath11k_dp_rx_mon_update_status_buf_state(pmon, tlv); -- if (paddr == pmon->mon_status_paddr) -- pmon->buf_state = DP_MON_STATUS_MATCH; -- } --+ --+ dma_unmap_single(ab->dev, rxcb->paddr, --+ skb->len + skb_tailroom(skb), --+ DMA_FROM_DEVICE); --+ -- __skb_queue_tail(skb_list, skb); -- } else { -- pmon->buf_state = DP_MON_STATUS_REPLINISH; -diff --git a/package/kernel/mac80211/patches/ath11k/0049-wifi-ath11k-Optimize-6-GHz-scan-time.patch b/package/kernel/mac80211/patches/ath11k/0049-wifi-ath11k-Optimize-6-GHz-scan-time.patch -deleted file mode 100644 -index f468990feb..0000000000 ---- a/package/kernel/mac80211/patches/ath11k/0049-wifi-ath11k-Optimize-6-GHz-scan-time.patch -+++ /dev/null -@@ -1,101 +0,0 @@ --From 8b4d2f080afbd4280ecca0f4b3ceea943a7a86d0 Mon Sep 17 00:00:00 2001 --From: Manikanta Pubbisetty --Date: Thu, 23 Mar 2023 11:39:13 +0530 --Subject: [PATCH] wifi: ath11k: Optimize 6 GHz scan time -- --Currently, time taken to scan all supported channels on WCN6750 --is ~8 seconds and connection time is almost 10 seconds. WCN6750 --supports three Wi-Fi bands (i.e., 2.4/5/6 GHz) and the numbers of --channels for scan come around ~100 channels (default case). --Since the chip doesn't have support for DBS (Dual Band Simultaneous), --scans cannot be parallelized resulting in longer scan times. -- --Among the 100 odd channels, ~60 channels are in 6 GHz band. Therefore, --optimizing the scan for 6 GHz channels will bring down the overall --scan time. -- --WCN6750 firmware has support to scan a 6 GHz channel based on co-located --AP information i.e., RNR IE which is found in the legacy 2.4/5 GHz scan --results. When a scan request with all supported channel list is enqueued --to the firmware, then based on WMI_SCAN_CHAN_FLAG_SCAN_ONLY_IF_RNR_FOUND --scan channel flag, firmware will scan only those 6 GHz channels for which --RNR IEs are found in the legacy scan results. -- --In the proposed design, based on NL80211_SCAN_FLAG_COLOCATED_6GHZ scan --flag, driver will set the WMI_SCAN_CHAN_FLAG_SCAN_ONLY_IF_RNR_FOUND flag --for non-PSC channels. Since there is high probability to find 6 GHz APs --on PSC channels, these channels are always scanned. Only non-PSC channels --are selectively scanned based on cached RNR information from the legacy --scan results. -- --If NL80211_SCAN_FLAG_COLOCATED_6GHZ is not set in the scan flags, --then scan will happen on all supported channels (default behavior). -- --With these optimizations, scan time is improved by 1.5-1.8 seconds on --WCN6750. Similar savings have been observed on WCN6855. -- --Tested-on: WCN6750 hw1.0 AHB WLAN.MSL.1.0.1-00887-QCAMSLSWPLZ-1 --Tested-on: WCN6855 hw2.1 PCI WLAN.HSP.1.1-03125-QCAHSPSWPL_V1_V2_SILICONZ_LITE-3.6510.16 -- --Signed-off-by: Manikanta Pubbisetty --Signed-off-by: Kalle Valo --Link: https://lore.kernel.org/r/20230323060913.10097-1-quic_mpubbise@quicinc.com ----- -- drivers/net/wireless/ath/ath11k/mac.c | 25 +++++++++++++++++++++++-- -- drivers/net/wireless/ath/ath11k/wmi.h | 4 ++++ -- 2 files changed, 27 insertions(+), 2 deletions(-) -- ----- a/drivers/net/wireless/ath/ath11k/mac.c --+++ b/drivers/net/wireless/ath/ath11k/mac.c --@@ -3819,8 +3819,29 @@ static int ath11k_mac_op_hw_scan(struct -- goto exit; -- } -- --- for (i = 0; i < arg->num_chan; i++) --- arg->chan_list[i] = req->channels[i]->center_freq; --+ for (i = 0; i < arg->num_chan; i++) { --+ if (test_bit(WMI_TLV_SERVICE_SCAN_CONFIG_PER_CHANNEL, --+ ar->ab->wmi_ab.svc_map)) { --+ arg->chan_list[i] = --+ u32_encode_bits(req->channels[i]->center_freq, --+ WMI_SCAN_CONFIG_PER_CHANNEL_MASK); --+ --+ /* If NL80211_SCAN_FLAG_COLOCATED_6GHZ is set in scan --+ * flags, then scan all PSC channels in 6 GHz band and --+ * those non-PSC channels where RNR IE is found during --+ * the legacy 2.4/5 GHz scan. --+ * If NL80211_SCAN_FLAG_COLOCATED_6GHZ is not set, --+ * then all channels in 6 GHz will be scanned. --+ */ --+ if (req->channels[i]->band == NL80211_BAND_6GHZ && --+ req->flags & NL80211_SCAN_FLAG_COLOCATED_6GHZ && --+ !cfg80211_channel_is_psc(req->channels[i])) --+ arg->chan_list[i] |= --+ WMI_SCAN_CH_FLAG_SCAN_ONLY_IF_RNR_FOUND; --+ } else { --+ arg->chan_list[i] = req->channels[i]->center_freq; --+ } --+ } -- } -- -- if (req->flags & NL80211_SCAN_FLAG_RANDOM_ADDR) { ----- a/drivers/net/wireless/ath/ath11k/wmi.h --+++ b/drivers/net/wireless/ath/ath11k/wmi.h --@@ -2100,6 +2100,7 @@ enum wmi_tlv_service { -- -- /* The second 128 bits */ -- WMI_MAX_EXT_SERVICE = 256, --+ WMI_TLV_SERVICE_SCAN_CONFIG_PER_CHANNEL = 265, -- WMI_TLV_SERVICE_REG_CC_EXT_EVENT_SUPPORT = 281, -- WMI_TLV_SERVICE_BIOS_SAR_SUPPORT = 326, -- --@@ -3249,6 +3250,9 @@ struct wmi_start_scan_cmd { -- #define WMI_SCAN_DWELL_MODE_SHIFT 21 -- #define WMI_SCAN_FLAG_EXT_PASSIVE_SCAN_START_TIME_ENHANCE 0x00000800 -- --+#define WMI_SCAN_CONFIG_PER_CHANNEL_MASK GENMASK(19, 0) --+#define WMI_SCAN_CH_FLAG_SCAN_ONLY_IF_RNR_FOUND BIT(20) --+ -- enum { -- WMI_SCAN_DWELL_MODE_DEFAULT = 0, -- WMI_SCAN_DWELL_MODE_CONSERVATIVE = 1, -diff --git a/package/kernel/mac80211/patches/ath11k/0050-wifi-ath11k-Configure-the-FTM-responder-role-using-f.patch b/package/kernel/mac80211/patches/ath11k/0050-wifi-ath11k-Configure-the-FTM-responder-role-using-f.patch -deleted file mode 100644 -index bca08b177f..0000000000 ---- a/package/kernel/mac80211/patches/ath11k/0050-wifi-ath11k-Configure-the-FTM-responder-role-using-f.patch -+++ /dev/null -@@ -1,117 +0,0 @@ --From 813968c24126cc5c8320cd5db0e262069a535063 Mon Sep 17 00:00:00 2001 --From: Ganesh Babu Jothiram --Date: Fri, 24 Mar 2023 16:57:00 +0200 --Subject: [PATCH] wifi: ath11k: Configure the FTM responder role using firmware -- capability flag -- --Fine Time Measurement(FTM) is offloaded feature to firmware. --Hence, the configuration of FTM responder role is done using --firmware capability flag instead of hw param. -- --Tested-on: QCN9074 hw1.0 PCI WLAN.HK.2.7.0.1-01744-QCAHKSWPL_SILICONZ-1 -- --Signed-off-by: Ganesh Babu Jothiram --Signed-off-by: Kalle Valo --Link: https://lore.kernel.org/r/20230317072034.8217-1-quic_gjothira@quicinc.com ----- -- drivers/net/wireless/ath/ath11k/core.c | 8 -------- -- drivers/net/wireless/ath/ath11k/hw.h | 1 - -- drivers/net/wireless/ath/ath11k/mac.c | 4 ++-- -- 3 files changed, 2 insertions(+), 11 deletions(-) -- ----- a/drivers/net/wireless/ath/ath11k/core.c --+++ b/drivers/net/wireless/ath/ath11k/core.c --@@ -116,7 +116,6 @@ static const struct ath11k_hw_params ath -- .tcl_ring_retry = true, -- .tx_ring_size = DP_TCL_DATA_RING_SIZE, -- .smp2p_wow_exit = false, --- .ftm_responder = true, -- }, -- { -- .hw_rev = ATH11K_HW_IPQ6018_HW10, --@@ -199,7 +198,6 @@ static const struct ath11k_hw_params ath -- .tx_ring_size = DP_TCL_DATA_RING_SIZE, -- .smp2p_wow_exit = false, -- .support_fw_mac_sequence = false, --- .ftm_responder = true, -- }, -- { -- .name = "qca6390 hw2.0", --@@ -284,7 +282,6 @@ static const struct ath11k_hw_params ath -- .tx_ring_size = DP_TCL_DATA_RING_SIZE, -- .smp2p_wow_exit = false, -- .support_fw_mac_sequence = true, --- .ftm_responder = false, -- }, -- { -- .name = "qcn9074 hw1.0", --@@ -366,7 +363,6 @@ static const struct ath11k_hw_params ath -- .tx_ring_size = DP_TCL_DATA_RING_SIZE, -- .smp2p_wow_exit = false, -- .support_fw_mac_sequence = false, --- .ftm_responder = true, -- }, -- { -- .name = "wcn6855 hw2.0", --@@ -451,7 +447,6 @@ static const struct ath11k_hw_params ath -- .tx_ring_size = DP_TCL_DATA_RING_SIZE, -- .smp2p_wow_exit = false, -- .support_fw_mac_sequence = true, --- .ftm_responder = false, -- }, -- { -- .name = "wcn6855 hw2.1", --@@ -534,7 +529,6 @@ static const struct ath11k_hw_params ath -- .tx_ring_size = DP_TCL_DATA_RING_SIZE, -- .smp2p_wow_exit = false, -- .support_fw_mac_sequence = true, --- .ftm_responder = false, -- }, -- { -- .name = "wcn6750 hw1.0", --@@ -615,7 +609,6 @@ static const struct ath11k_hw_params ath -- .tx_ring_size = DP_TCL_DATA_RING_SIZE_WCN6750, -- .smp2p_wow_exit = true, -- .support_fw_mac_sequence = true, --- .ftm_responder = false, -- }, -- { -- .hw_rev = ATH11K_HW_IPQ5018_HW10, --@@ -695,7 +688,6 @@ static const struct ath11k_hw_params ath -- .tx_ring_size = DP_TCL_DATA_RING_SIZE, -- .smp2p_wow_exit = false, -- .support_fw_mac_sequence = false, --- .ftm_responder = true, -- }, -- }; -- ----- a/drivers/net/wireless/ath/ath11k/hw.h --+++ b/drivers/net/wireless/ath/ath11k/hw.h --@@ -224,7 +224,6 @@ struct ath11k_hw_params { -- u32 tx_ring_size; -- bool smp2p_wow_exit; -- bool support_fw_mac_sequence; --- bool ftm_responder; -- }; -- -- struct ath11k_hw_ops { ----- a/drivers/net/wireless/ath/ath11k/mac.c --+++ b/drivers/net/wireless/ath/ath11k/mac.c --@@ -3538,7 +3538,7 @@ static void ath11k_mac_op_bss_info_chang -- -- if (changed & BSS_CHANGED_FTM_RESPONDER && -- arvif->ftm_responder != info->ftm_responder && --- ar->ab->hw_params.ftm_responder && --+ test_bit(WMI_TLV_SERVICE_RTT, ar->ab->wmi_ab.svc_map) && -- (vif->type == NL80211_IFTYPE_AP || -- vif->type == NL80211_IFTYPE_MESH_POINT)) { -- arvif->ftm_responder = info->ftm_responder; --@@ -9234,7 +9234,7 @@ static int __ath11k_mac_register(struct -- wiphy_ext_feature_set(ar->hw->wiphy, -- NL80211_EXT_FEATURE_SET_SCAN_DWELL); -- --- if (ab->hw_params.ftm_responder) --+ if (test_bit(WMI_TLV_SERVICE_RTT, ar->ab->wmi_ab.svc_map)) -- wiphy_ext_feature_set(ar->hw->wiphy, -- NL80211_EXT_FEATURE_ENABLE_FTM_RESPONDER); -- -diff --git a/package/kernel/mac80211/patches/ath11k/0051-wifi-ath11k-fix-rssi-station-dump-not-updated-in-QCN.patch b/package/kernel/mac80211/patches/ath11k/0051-wifi-ath11k-fix-rssi-station-dump-not-updated-in-QCN.patch -deleted file mode 100644 -index 835dece1fe..0000000000 ---- a/package/kernel/mac80211/patches/ath11k/0051-wifi-ath11k-fix-rssi-station-dump-not-updated-in-QCN.patch -+++ /dev/null -@@ -1,158 +0,0 @@ --From 031ffa6c2cd305a57ccc6d610f2decd956b2e7f6 Mon Sep 17 00:00:00 2001 --From: P Praneesh --Date: Fri, 24 Mar 2023 16:57:00 +0200 --Subject: [PATCH] wifi: ath11k: fix rssi station dump not updated in QCN9074 -- --In QCN9074, station dump signal values display default value which --is -95 dbm, since there is firmware header change for HAL_RX_MPDU_START --between QCN9074 and IPQ8074 which cause wrong peer_id fetch from msdu. --Fix this by updating hal_rx_mpdu_info with corresponding QCN9074 tlv --format. -- --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.4.0.1-01695-QCAHKSWPL_SILICONZ-1 -- --Signed-off-by: P Praneesh --Signed-off-by: Kalle Valo --Link: https://lore.kernel.org/r/20230320110312.20639-1-quic_ppranees@quicinc.com ----- -- drivers/net/wireless/ath/ath11k/hal_rx.c | 10 ++++++++- -- drivers/net/wireless/ath/ath11k/hal_rx.h | 18 +++++++++++++++- -- drivers/net/wireless/ath/ath11k/hw.c | 27 ++++++++++++++++-------- -- drivers/net/wireless/ath/ath11k/hw.h | 2 +- -- 4 files changed, 45 insertions(+), 12 deletions(-) -- ----- a/drivers/net/wireless/ath/ath11k/hal_rx.c --+++ b/drivers/net/wireless/ath/ath11k/hal_rx.c --@@ -865,6 +865,12 @@ ath11k_hal_rx_populate_mu_user_info(void -- ath11k_hal_rx_populate_byte_count(rx_tlv, ppdu_info, rx_user_status); -- } -- --+static u16 ath11k_hal_rx_mpduinfo_get_peerid(struct ath11k_base *ab, --+ struct hal_rx_mpdu_info *mpdu_info) --+{ --+ return ab->hw_params.hw_ops->mpdu_info_get_peerid(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, --@@ -1459,9 +1465,11 @@ ath11k_hal_rx_parse_mon_status_tlv(struc -- break; -- } -- case HAL_RX_MPDU_START: { --+ struct hal_rx_mpdu_info *mpdu_info = --+ (struct hal_rx_mpdu_info *)tlv_data; -- u16 peer_id; -- --- peer_id = ab->hw_params.hw_ops->mpdu_info_get_peerid(tlv_data); --+ peer_id = ath11k_hal_rx_mpduinfo_get_peerid(ab, mpdu_info); -- if (peer_id) -- ppdu_info->peer_id = peer_id; -- break; ----- a/drivers/net/wireless/ath/ath11k/hal_rx.h --+++ b/drivers/net/wireless/ath/ath11k/hal_rx.h --@@ -405,7 +405,7 @@ struct hal_rx_phyrx_rssi_legacy_info { -- #define HAL_RX_MPDU_INFO_INFO0_PEERID_WCN6855 GENMASK(15, 0) -- #define HAL_RX_MPDU_INFO_INFO1_MPDU_LEN GENMASK(13, 0) -- ---struct hal_rx_mpdu_info { --+struct hal_rx_mpdu_info_ipq8074 { -- __le32 rsvd0; -- __le32 info0; -- __le32 rsvd1[11]; --@@ -413,12 +413,28 @@ struct hal_rx_mpdu_info { -- __le32 rsvd2[9]; -- } __packed; -- --+struct hal_rx_mpdu_info_qcn9074 { --+ __le32 rsvd0[10]; --+ __le32 info0; --+ __le32 rsvd1[2]; --+ __le32 info1; --+ __le32 rsvd2[9]; --+} __packed; --+ -- struct hal_rx_mpdu_info_wcn6855 { -- __le32 rsvd0[8]; -- __le32 info0; -- __le32 rsvd1[14]; -- } __packed; -- --+struct hal_rx_mpdu_info { --+ union { --+ struct hal_rx_mpdu_info_ipq8074 ipq8074; --+ struct hal_rx_mpdu_info_qcn9074 qcn9074; --+ struct hal_rx_mpdu_info_wcn6855 wcn6855; --+ } u; --+} __packed; --+ -- #define HAL_RX_PPDU_END_DURATION GENMASK(23, 0) -- struct hal_rx_ppdu_end_duration { -- __le32 rsvd0[9]; ----- a/drivers/net/wireless/ath/ath11k/hw.c --+++ b/drivers/net/wireless/ath/ath11k/hw.c --@@ -835,26 +835,35 @@ static void ath11k_hw_ipq5018_reo_setup( -- ring_hash_map); -- } -- ---static u16 ath11k_hw_ipq8074_mpdu_info_get_peerid(u8 *tlv_data) --+static u16 --+ath11k_hw_ipq8074_mpdu_info_get_peerid(struct hal_rx_mpdu_info *mpdu_info) -- { -- u16 peer_id = 0; --- struct hal_rx_mpdu_info *mpdu_info = --- (struct hal_rx_mpdu_info *)tlv_data; -- -- peer_id = FIELD_GET(HAL_RX_MPDU_INFO_INFO0_PEERID, --- __le32_to_cpu(mpdu_info->info0)); --+ __le32_to_cpu(mpdu_info->u.ipq8074.info0)); -- -- return peer_id; -- } -- ---static u16 ath11k_hw_wcn6855_mpdu_info_get_peerid(u8 *tlv_data) --+static u16 --+ath11k_hw_qcn9074_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.qcn9074.info0)); --+ --+ return peer_id; --+} --+ --+static u16 --+ath11k_hw_wcn6855_mpdu_info_get_peerid(struct hal_rx_mpdu_info *mpdu_info) -- { -- u16 peer_id = 0; --- struct hal_rx_mpdu_info_wcn6855 *mpdu_info = --- (struct hal_rx_mpdu_info_wcn6855 *)tlv_data; -- -- peer_id = FIELD_GET(HAL_RX_MPDU_INFO_INFO0_PEERID_WCN6855, --- __le32_to_cpu(mpdu_info->info0)); --+ __le32_to_cpu(mpdu_info->u.wcn6855.info0)); -- return peer_id; -- } -- --@@ -1042,7 +1051,7 @@ const struct ath11k_hw_ops qcn9074_ops = -- .rx_desc_get_attention = ath11k_hw_qcn9074_rx_desc_get_attention, -- .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_ipq8074_mpdu_info_get_peerid, --+ .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 --@@ -263,7 +263,7 @@ struct ath11k_hw_ops { -- struct rx_attention *(*rx_desc_get_attention)(struct hal_rx_desc *desc); -- u8 *(*rx_desc_get_msdu_payload)(struct hal_rx_desc *desc); -- void (*reo_setup)(struct ath11k_base *ab); --- u16 (*mpdu_info_get_peerid)(u8 *tlv_data); --+ u16 (*mpdu_info_get_peerid)(struct hal_rx_mpdu_info *mpdu_info); -- 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/0052-wifi-ath11k-Fix-invalid-management-rx-frame-length-i.patch b/package/kernel/mac80211/patches/ath11k/0052-wifi-ath11k-Fix-invalid-management-rx-frame-length-i.patch -deleted file mode 100644 -index 0c1637fb04..0000000000 ---- a/package/kernel/mac80211/patches/ath11k/0052-wifi-ath11k-Fix-invalid-management-rx-frame-length-i.patch -+++ /dev/null -@@ -1,115 +0,0 @@ --From 447b0398a9cd41ca343dfd43e555af92d6214487 Mon Sep 17 00:00:00 2001 --From: Bhagavathi Perumal S --Date: Fri, 24 Mar 2023 16:57:00 +0200 --Subject: [PATCH] wifi: ath11k: Fix invalid management rx frame length issue -- --The WMI management rx event has multiple arrays of TLVs, however the common --WMI TLV parser won't handle multiple TLV tags of same type. --So the multiple array tags of WMI management rx TLV is parsed incorrectly --and the length calculated becomes wrong when the target sends multiple --array tags. -- --Add separate TLV parser to handle multiple arrays for WMI management rx --TLV. This fixes invalid length issue when the target sends multiple array --tags. -- --Tested-on: QCN9074 hw1.0 PCI WLAN.HK.2.7.0.1-01744-QCAHKSWPL_SILICONZ-1 -- --Signed-off-by: Bhagavathi Perumal S --Co-developed-by: Nagarajan Maran --Signed-off-by: Nagarajan Maran --Signed-off-by: Kalle Valo --Link: https://lore.kernel.org/r/20230320133840.30162-1-quic_nmaran@quicinc.com ----- -- drivers/net/wireless/ath/ath11k/wmi.c | 45 +++++++++++++++++++++------ -- 1 file changed, 35 insertions(+), 10 deletions(-) -- ----- a/drivers/net/wireless/ath/ath11k/wmi.c --+++ b/drivers/net/wireless/ath/ath11k/wmi.c --@@ -82,6 +82,12 @@ struct wmi_tlv_fw_stats_parse { -- bool chain_rssi_done; -- }; -- --+struct wmi_tlv_mgmt_rx_parse { --+ const struct wmi_mgmt_rx_hdr *fixed; --+ const u8 *frame_buf; --+ bool frame_buf_done; --+}; --+ -- static const struct wmi_tlv_policy wmi_tlv_policies[] = { -- [WMI_TAG_ARRAY_BYTE] -- = { .min_len = 0 }, --@@ -5633,28 +5639,49 @@ static int ath11k_pull_vdev_stopped_para -- return 0; -- } -- --+static int ath11k_wmi_tlv_mgmt_rx_parse(struct ath11k_base *ab, --+ u16 tag, u16 len, --+ const void *ptr, void *data) --+{ --+ struct wmi_tlv_mgmt_rx_parse *parse = data; --+ --+ switch (tag) { --+ case WMI_TAG_MGMT_RX_HDR: --+ parse->fixed = ptr; --+ break; --+ case WMI_TAG_ARRAY_BYTE: --+ if (!parse->frame_buf_done) { --+ parse->frame_buf = ptr; --+ parse->frame_buf_done = true; --+ } --+ break; --+ } --+ return 0; --+} --+ -- static int ath11k_pull_mgmt_rx_params_tlv(struct ath11k_base *ab, -- struct sk_buff *skb, -- struct mgmt_rx_event_params *hdr) -- { --- const void **tb; --+ struct wmi_tlv_mgmt_rx_parse parse = { }; -- const struct wmi_mgmt_rx_hdr *ev; -- const u8 *frame; -- 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); --+ ret = ath11k_wmi_tlv_iter(ab, skb->data, skb->len, --+ ath11k_wmi_tlv_mgmt_rx_parse, --+ &parse); --+ if (ret) { --+ ath11k_warn(ab, "failed to parse mgmt rx tlv %d\n", --+ ret); -- return ret; -- } -- --- ev = tb[WMI_TAG_MGMT_RX_HDR]; --- frame = tb[WMI_TAG_ARRAY_BYTE]; --+ ev = parse.fixed; --+ frame = parse.frame_buf; -- -- if (!ev || !frame) { -- ath11k_warn(ab, "failed to fetch mgmt rx hdr"); --- kfree(tb); -- return -EPROTO; -- } -- --@@ -5673,7 +5700,6 @@ static int ath11k_pull_mgmt_rx_params_tl -- -- if (skb->len < (frame - skb->data) + hdr->buf_len) { -- ath11k_warn(ab, "invalid length in mgmt rx hdr ev"); --- kfree(tb); -- return -EPROTO; -- } -- --@@ -5685,7 +5711,6 @@ static int ath11k_pull_mgmt_rx_params_tl -- -- ath11k_ce_byte_swap(skb->data, hdr->buf_len); -- --- kfree(tb); -- return 0; -- } -- -diff --git a/package/kernel/mac80211/patches/ath11k/0053-wifi-ath11k-fix-writing-to-unintended-memory-region.patch b/package/kernel/mac80211/patches/ath11k/0053-wifi-ath11k-fix-writing-to-unintended-memory-region.patch -deleted file mode 100644 -index 7b8a7d4543..0000000000 ---- a/package/kernel/mac80211/patches/ath11k/0053-wifi-ath11k-fix-writing-to-unintended-memory-region.patch -+++ /dev/null -@@ -1,43 +0,0 @@ --From 756a7f90878f0866fd2fe167ef37e90b47326b96 Mon Sep 17 00:00:00 2001 --From: P Praneesh --Date: Fri, 24 Mar 2023 16:57:01 +0200 --Subject: [PATCH] wifi: ath11k: fix writing to unintended memory region -- --While initializing spectral, the magic value is getting written to the --invalid memory address leading to random boot-up crash. This occurs --due to the incorrect index increment in ath11k_dbring_fill_magic_value --function. Fix it by replacing the existing logic with memset32 to ensure --there is no invalid memory access. -- --Tested-on: QCN9074 hw1.0 PCI WLAN.HK.2.4.0.1-01838-QCAHKSWPL_SILICONZ-1 -- --Fixes: d3d358efc553 ("ath11k: add spectral/CFR buffer validation support") --Signed-off-by: P Praneesh --Signed-off-by: Kalle Valo --Link: https://lore.kernel.org/r/20230321052900.16895-1-quic_ppranees@quicinc.com ----- -- drivers/net/wireless/ath/ath11k/dbring.c | 12 ++++++------ -- 1 file changed, 6 insertions(+), 6 deletions(-) -- ----- a/drivers/net/wireless/ath/ath11k/dbring.c --+++ b/drivers/net/wireless/ath/ath11k/dbring.c --@@ -26,13 +26,13 @@ int ath11k_dbring_validate_buffer(struct -- static void ath11k_dbring_fill_magic_value(struct ath11k *ar, -- void *buffer, u32 size) -- { --- u32 *temp; --- int idx; --+ /* memset32 function fills buffer payload with the ATH11K_DB_MAGIC_VALUE --+ * and the variable size is expected to be the number of u32 values --+ * to be stored, not the number of bytes. --+ */ --+ size = size / sizeof(u32); -- --- size = size >> 2; --- --- for (idx = 0, temp = buffer; idx < size; idx++, temp++) --- *temp++ = ATH11K_DB_MAGIC_VALUE; --+ memset32(buffer, ATH11K_DB_MAGIC_VALUE, size); -- } -- -- static int ath11k_dbring_bufs_replenish(struct ath11k *ar, -diff --git a/package/kernel/mac80211/patches/ath11k/0054-wifi-ath11k-Send-11d-scan-start-before-WMI_START_SCA.patch b/package/kernel/mac80211/patches/ath11k/0054-wifi-ath11k-Send-11d-scan-start-before-WMI_START_SCA.patch -deleted file mode 100644 -index 0f8e637592..0000000000 ---- a/package/kernel/mac80211/patches/ath11k/0054-wifi-ath11k-Send-11d-scan-start-before-WMI_START_SCA.patch -+++ /dev/null -@@ -1,61 +0,0 @@ --From e89a51aedf380bc60219dc9afa96c36507060fb3 Mon Sep 17 00:00:00 2001 --From: Manikanta Pubbisetty --Date: Wed, 15 Mar 2023 21:48:17 +0530 --Subject: [PATCH] wifi: ath11k: Send 11d scan start before WMI_START_SCAN_CMDID -- --Firmwares advertising the support of triggering 11d algorithm on the --scan results of a regular scan expects driver to send --WMI_11D_SCAN_START_CMDID before sending WMI_START_SCAN_CMDID. --Triggering 11d algorithm on the scan results of a normal scan helps --in completely avoiding a separate 11d scan for determining regdomain. --This indirectly helps in speeding up connections on station --interfaces on the chipsets supporting 11D scan. -- --To enable this feature, send WMI_11D_SCAN_START_CMDID just before --sending WMI_START_SCAN_CMDID if the firmware advertises --WMI_TLV_SERVICE_SUPPORT_11D_FOR_HOST_SCAN service flag. -- --WCN6750 & WCN6855 supports this feature. -- --Tested-on: WCN6750 hw1.0 AHB WLAN.MSL.1.0.1-01160-QCAMSLSWPLZ-1 --Tested-on: WCN6855 hw2.1 PCI WLAN.HSP.1.1-03125-QCAHSPSWPL_V1_V2_SILICONZ_LITE-3.6510.23 -- --Signed-off-by: Manikanta Pubbisetty --Signed-off-by: Kalle Valo --Link: https://lore.kernel.org/r/20230315161817.29627-1-quic_mpubbise@quicinc.com ----- -- drivers/net/wireless/ath/ath11k/mac.c | 12 ++++++++++++ -- drivers/net/wireless/ath/ath11k/wmi.h | 1 + -- 2 files changed, 13 insertions(+) -- ----- a/drivers/net/wireless/ath/ath11k/mac.c --+++ b/drivers/net/wireless/ath/ath11k/mac.c --@@ -3755,6 +3755,18 @@ static int ath11k_mac_op_hw_scan(struct -- int i; -- u32 scan_timeout; -- --+ /* Firmwares advertising the support of triggering 11D algorithm --+ * on the scan results of a regular scan expects driver to send --+ * WMI_11D_SCAN_START_CMDID before sending WMI_START_SCAN_CMDID. --+ * With this feature, separate 11D scan can be avoided since --+ * regdomain can be determined with the scan results of the --+ * regular scan. --+ */ --+ if (ar->state_11d == ATH11K_11D_PREPARING && --+ test_bit(WMI_TLV_SERVICE_SUPPORT_11D_FOR_HOST_SCAN, --+ ar->ab->wmi_ab.svc_map)) --+ ath11k_mac_11d_scan_start(ar, arvif->vdev_id); --+ -- mutex_lock(&ar->conf_mutex); -- -- spin_lock_bh(&ar->data_lock); ----- a/drivers/net/wireless/ath/ath11k/wmi.h --+++ b/drivers/net/wireless/ath/ath11k/wmi.h --@@ -2103,6 +2103,7 @@ enum wmi_tlv_service { -- WMI_TLV_SERVICE_SCAN_CONFIG_PER_CHANNEL = 265, -- WMI_TLV_SERVICE_REG_CC_EXT_EVENT_SUPPORT = 281, -- WMI_TLV_SERVICE_BIOS_SAR_SUPPORT = 326, --+ WMI_TLV_SERVICE_SUPPORT_11D_FOR_HOST_SCAN = 357, -- -- /* The third 128 bits */ -- WMI_MAX_EXT2_SERVICE = 384 -diff --git a/package/kernel/mac80211/patches/ath11k/0055-wifi-ath11k-Remove-redundant-pci_clear_master.patch b/package/kernel/mac80211/patches/ath11k/0055-wifi-ath11k-Remove-redundant-pci_clear_master.patch -deleted file mode 100644 -index 0439727e72..0000000000 ---- a/package/kernel/mac80211/patches/ath11k/0055-wifi-ath11k-Remove-redundant-pci_clear_master.patch -+++ /dev/null -@@ -1,58 +0,0 @@ --From f812e2a9f85d6bea78957ccb5197e4491316848b Mon Sep 17 00:00:00 2001 --From: Cai Huoqing --Date: Thu, 23 Mar 2023 19:26:09 +0800 --Subject: [PATCH] wifi: ath11k: Remove redundant pci_clear_master -- --Remove pci_clear_master to simplify the code, --the bus-mastering is also cleared in do_pci_disable_device, --like this: --./drivers/pci/pci.c:2197 --static void do_pci_disable_device(struct pci_dev *dev) --{ -- u16 pci_command; -- -- pci_read_config_word(dev, PCI_COMMAND, &pci_command); -- if (pci_command & PCI_COMMAND_MASTER) { -- pci_command &= ~PCI_COMMAND_MASTER; -- pci_write_config_word(dev, PCI_COMMAND, pci_command); -- } -- -- pcibios_disable_device(dev); --}. --And dev->is_busmaster is set to 0 in pci_disable_device. -- --Signed-off-by: Cai Huoqing --Signed-off-by: Kalle Valo --Link: https://lore.kernel.org/r/20230323112613.7550-1-cai.huoqing@linux.dev ----- -- drivers/net/wireless/ath/ath11k/pci.c | 5 +---- -- 1 file changed, 1 insertion(+), 4 deletions(-) -- ----- a/drivers/net/wireless/ath/ath11k/pci.c --+++ b/drivers/net/wireless/ath/ath11k/pci.c --@@ -540,7 +540,7 @@ static int ath11k_pci_claim(struct ath11 -- if (!ab->mem) { -- ath11k_err(ab, "failed to map pci bar %d\n", ATH11K_PCI_BAR_NUM); -- ret = -EIO; --- goto clear_master; --+ goto release_region; -- } -- -- ab->mem_ce = ab->mem; --@@ -548,8 +548,6 @@ static int ath11k_pci_claim(struct ath11 -- ath11k_dbg(ab, ATH11K_DBG_BOOT, "boot pci_mem 0x%pK\n", ab->mem); -- return 0; -- ---clear_master: --- pci_clear_master(pdev); -- release_region: -- pci_release_region(pdev, ATH11K_PCI_BAR_NUM); -- disable_device: --@@ -565,7 +563,6 @@ static void ath11k_pci_free_region(struc -- -- pci_iounmap(pci_dev, ab->mem); -- ab->mem = NULL; --- pci_clear_master(pci_dev); -- pci_release_region(pci_dev, ATH11K_PCI_BAR_NUM); -- if (pci_is_enabled(pci_dev)) -- pci_disable_device(pci_dev); -diff --git a/package/kernel/mac80211/patches/ath11k/0056-wifi-ath11k-Disable-Spectral-scan-upon-removing-inte.patch b/package/kernel/mac80211/patches/ath11k/0056-wifi-ath11k-Disable-Spectral-scan-upon-removing-inte.patch -deleted file mode 100644 -index 44532a4d72..0000000000 ---- a/package/kernel/mac80211/patches/ath11k/0056-wifi-ath11k-Disable-Spectral-scan-upon-removing-inte.patch -+++ /dev/null -@@ -1,36 +0,0 @@ --From 5c690db63b45c6c4c4932b13173af71df369dba5 Mon Sep 17 00:00:00 2001 --From: Tamizh Chelvam Raja --Date: Tue, 28 Mar 2023 12:41:50 +0530 --Subject: [PATCH] wifi: ath11k: Disable Spectral scan upon removing interface -- --Host might receive spectral events during interface --down sequence and this might create below errors. -- --failed to handle dma buf release event -22 --failed to handle dma buf release event -22 -- --Fix this by disabling spectral config during remove interface. -- --Tested-on: IPQ5018 hw1.0 AHB WLAN.HK.2.6.0.1-00861-QCAHKSWPL_SILICONZ-1 -- --Signed-off-by: Tamizh Chelvam Raja --Signed-off-by: Kalle Valo --Link: https://lore.kernel.org/r/20230328071150.29645-1-quic_tamizhr@quicinc.com ----- -- drivers/net/wireless/ath/ath11k/mac.c | 5 +++++ -- 1 file changed, 5 insertions(+) -- ----- a/drivers/net/wireless/ath/ath11k/mac.c --+++ b/drivers/net/wireless/ath/ath11k/mac.c --@@ -6685,6 +6685,11 @@ static void ath11k_mac_op_remove_interfa -- ath11k_dbg(ab, ATH11K_DBG_MAC, "mac remove interface (vdev %d)\n", -- arvif->vdev_id); -- --+ ret = ath11k_spectral_vif_stop(arvif); --+ if (ret) --+ ath11k_warn(ab, "failed to stop spectral for vdev %i: %d\n", --+ arvif->vdev_id, ret); --+ -- if (arvif->vdev_type == WMI_VDEV_TYPE_STA) -- ath11k_mac_11d_scan_stop(ar); -- -diff --git a/package/kernel/mac80211/patches/ath11k/0057-wifi-ath11k-enable-SAR-support-on-WCN6750.patch b/package/kernel/mac80211/patches/ath11k/0057-wifi-ath11k-enable-SAR-support-on-WCN6750.patch -deleted file mode 100644 -index 5e64e552c1..0000000000 ---- a/package/kernel/mac80211/patches/ath11k/0057-wifi-ath11k-enable-SAR-support-on-WCN6750.patch -+++ /dev/null -@@ -1,29 +0,0 @@ --From abf57d84973ce1abcb67504ac0df8aea1fe09a76 Mon Sep 17 00:00:00 2001 --From: Youghandhar Chintala --Date: Tue, 28 Mar 2023 17:04:55 +0530 --Subject: [PATCH] wifi: ath11k: enable SAR support on WCN6750 -- --Currently, SAR is enabled only on WCN6855, enable this for WCN6750 too. This --functionality gets triggered, when the user space application calls --NL80211_CMD_SET_SAR_SPECS. -- --Tested-on: WCN6750 hw1.0 AHB WLAN.MSL.1.0.1-00887-QCAMSLSWPLZ-1 -- --Signed-off-by: Youghandhar Chintala --Signed-off-by: Kalle Valo --Link: https://lore.kernel.org/r/20230328113455.11252-1-quic_youghand@quicinc.com ----- -- drivers/net/wireless/ath/ath11k/core.c | 2 +- -- 1 file changed, 1 insertion(+), 1 deletion(-) -- ----- a/drivers/net/wireless/ath/ath11k/core.c --+++ b/drivers/net/wireless/ath/ath11k/core.c --@@ -593,7 +593,7 @@ static const struct ath11k_hw_params ath -- .current_cc_support = true, -- .dbr_debug_support = false, -- .global_reset = false, --- .bios_sar_capa = NULL, --+ .bios_sar_capa = &ath11k_hw_sar_capa_wcn6855, -- .m3_fw_support = false, -- .fixed_bdf_addr = false, -- .fixed_mem_region = false, -diff --git a/package/kernel/mac80211/patches/ath11k/0058-wifi-ath11k-pci-Add-more-MODULE_FIRMWARE-entries.patch b/package/kernel/mac80211/patches/ath11k/0058-wifi-ath11k-pci-Add-more-MODULE_FIRMWARE-entries.patch -deleted file mode 100644 -index 585864eff2..0000000000 ---- a/package/kernel/mac80211/patches/ath11k/0058-wifi-ath11k-pci-Add-more-MODULE_FIRMWARE-entries.patch -+++ /dev/null -@@ -1,36 +0,0 @@ --From 06c58473969239e00d76b683edd511952060ca56 Mon Sep 17 00:00:00 2001 --From: Takashi Iwai --Date: Thu, 30 Mar 2023 16:37:18 +0200 --Subject: [PATCH] wifi: ath11k: pci: Add more MODULE_FIRMWARE() entries -- --As there are a few more models supported by the driver, let's add the --missing MODULE_FIRMWARE() entries for them. The lack of them resulted --in the missing device enablement on some systems, such as the --installation image of openSUSE. -- --While we are at it, use the wildcard instead of listing each firmware --files individually for each. -- --Signed-off-by: Takashi Iwai --Reviewed-by: Simon Horman --Signed-off-by: Kalle Valo --Link: https://lore.kernel.org/r/20230330143718.19511-1-tiwai@suse.de ----- -- drivers/net/wireless/ath/ath11k/pci.c | 9 +++++---- -- 1 file changed, 5 insertions(+), 4 deletions(-) -- ----- a/drivers/net/wireless/ath/ath11k/pci.c --+++ b/drivers/net/wireless/ath/ath11k/pci.c --@@ -1036,7 +1036,8 @@ module_exit(ath11k_pci_exit); -- MODULE_DESCRIPTION("Driver support for Qualcomm Technologies 802.11ax WLAN PCIe devices"); -- MODULE_LICENSE("Dual BSD/GPL"); -- ---/* QCA639x 2.0 firmware files */ ---MODULE_FIRMWARE(ATH11K_FW_DIR "/QCA6390/hw2.0/" ATH11K_BOARD_API2_FILE); ---MODULE_FIRMWARE(ATH11K_FW_DIR "/QCA6390/hw2.0/" ATH11K_AMSS_FILE); ---MODULE_FIRMWARE(ATH11K_FW_DIR "/QCA6390/hw2.0/" ATH11K_M3_FILE); --+/* firmware files */ --+MODULE_FIRMWARE(ATH11K_FW_DIR "/QCA6390/hw2.0/*"); --+MODULE_FIRMWARE(ATH11K_FW_DIR "/QCN9074/hw1.0/*"); --+MODULE_FIRMWARE(ATH11K_FW_DIR "/WCN6855/hw2.0/*"); --+MODULE_FIRMWARE(ATH11K_FW_DIR "/WCN6855/hw2.1/*"); -diff --git a/package/kernel/mac80211/patches/ath11k/0059-wifi-ath11k-print-a-warning-when-crypto_alloc_shash-.patch b/package/kernel/mac80211/patches/ath11k/0059-wifi-ath11k-print-a-warning-when-crypto_alloc_shash-.patch -deleted file mode 100644 -index fab52a0fa7..0000000000 ---- a/package/kernel/mac80211/patches/ath11k/0059-wifi-ath11k-print-a-warning-when-crypto_alloc_shash-.patch -+++ /dev/null -@@ -1,34 +0,0 @@ --From a87a9110ac0dcbfd9458b6665c141fa1c16a669d Mon Sep 17 00:00:00 2001 --From: Kalle Valo --Date: Wed, 5 Apr 2023 12:04:25 +0300 --Subject: [PATCH] wifi: ath11k: print a warning when crypto_alloc_shash() fails -- --Christoph reported that ath11k failed to initialise when michael_mic.ko --module was not installed. To make it easier to notice that case print a --warning when crypto_alloc_shash() fails. -- --Compile tested only. -- --Reported-by: Christoph Hellwig --Link: https://lore.kernel.org/all/20221130133016.GC3055@lst.de/ --Signed-off-by: Kalle Valo --Link: https://lore.kernel.org/r/20230405090425.1351-1-kvalo@kernel.org ----- -- drivers/net/wireless/ath/ath11k/dp_rx.c | 5 ++++- -- 1 file changed, 4 insertions(+), 1 deletion(-) -- ----- a/drivers/net/wireless/ath/ath11k/dp_rx.c --+++ b/drivers/net/wireless/ath/ath11k/dp_rx.c --@@ -3106,8 +3106,11 @@ int ath11k_peer_rx_frag_setup(struct ath -- int i; -- -- tfm = crypto_alloc_shash("michael_mic", 0, 0); --- if (IS_ERR(tfm)) --+ if (IS_ERR(tfm)) { --+ ath11k_warn(ab, "failed to allocate michael_mic shash: %ld\n", --+ PTR_ERR(tfm)); -- return PTR_ERR(tfm); --+ } -- -- spin_lock_bh(&ab->base_lock); -- -diff --git a/package/kernel/mac80211/patches/ath11k/0060-wifi-ath11k-Ignore-frags-from-uninitialized-peer-in-.patch b/package/kernel/mac80211/patches/ath11k/0060-wifi-ath11k-Ignore-frags-from-uninitialized-peer-in-.patch -deleted file mode 100644 -index 5bbf9e04a4..0000000000 ---- a/package/kernel/mac80211/patches/ath11k/0060-wifi-ath11k-Ignore-frags-from-uninitialized-peer-in-.patch -+++ /dev/null -@@ -1,104 +0,0 @@ --From a06bfb3c9f69f303692cdae87bc0899d2ae8b2a6 Mon Sep 17 00:00:00 2001 --From: Harshitha Prem --Date: Tue, 4 Apr 2023 00:11:54 +0530 --Subject: [PATCH] wifi: ath11k: Ignore frags from uninitialized peer in dp. -- --When max virtual ap interfaces are configured in all the bands with --ACS and hostapd restart is done every 60s, a crash is observed at --random times. --In this certain scenario, a 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. -- --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) -- --Tested-on: IPQ8074 hw2.0 AHB WLAN.HK.2.7.0.1-01744-QCAHKSWPL_SILICONZ-1 -- --Signed-off-by: Harshitha Prem --Signed-off-by: Nagarajan Maran --Signed-off-by: Kalle Valo --Link: https://lore.kernel.org/r/20230403184155.8670-2-quic_nmaran@quicinc.com ----- -- drivers/net/wireless/ath/ath11k/dp.c | 4 +++- -- drivers/net/wireless/ath/ath11k/dp_rx.c | 8 ++++++++ -- drivers/net/wireless/ath/ath11k/peer.h | 1 + -- 3 files changed, 12 insertions(+), 1 deletion(-) -- ----- a/drivers/net/wireless/ath/ath11k/dp.c --+++ b/drivers/net/wireless/ath/ath11k/dp.c --@@ -36,6 +36,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); -- spin_unlock_bh(&ab->base_lock); -- } --@@ -72,7 +73,8 @@ int ath11k_dp_peer_setup(struct ath11k * -- ret = ath11k_peer_rx_frag_setup(ar, addr, vdev_id); -- if (ret) { -- ath11k_warn(ab, "failed to setup rx defrag context\n"); --- return ret; --+ tid--; --+ goto peer_clean; -- } -- -- /* TODO: Setup other peer specific resource used in data path */ ----- a/drivers/net/wireless/ath/ath11k/dp_rx.c --+++ b/drivers/net/wireless/ath/ath11k/dp_rx.c --@@ -3130,6 +3130,7 @@ int ath11k_peer_rx_frag_setup(struct ath -- } -- -- peer->tfm_mmic = tfm; --+ peer->dp_setup_done = true; -- spin_unlock_bh(&ab->base_lock); -- -- return 0; --@@ -3575,6 +3576,13 @@ static int ath11k_dp_rx_frag_h_mpdu(stru -- ret = -ENOENT; -- goto out_unlock; -- } --+ if (!peer->dp_setup_done) { --+ ath11k_warn(ab, "The peer %pM [%d] has uninitialized datapath\n", --+ peer->addr, peer_id); --+ ret = -ENOENT; --+ goto out_unlock; --+ } --+ -- rx_tid = &peer->rx_tid[tid]; -- -- if ((!skb_queue_empty(&rx_tid->rx_frags) && seqno != rx_tid->cur_sn) || ----- a/drivers/net/wireless/ath/ath11k/peer.h --+++ b/drivers/net/wireless/ath/ath11k/peer.h --@@ -35,6 +35,7 @@ struct ath11k_peer { -- u16 sec_type; -- u16 sec_type_grp; -- bool is_authorized; --+ bool dp_setup_done; -- }; -- -- void ath11k_peer_unmap_event(struct ath11k_base *ab, u16 peer_id); -diff --git a/package/kernel/mac80211/patches/ath11k/0061-wifi-ath11k-fix-undefined-behavior-with-__fls-in-dp.patch b/package/kernel/mac80211/patches/ath11k/0061-wifi-ath11k-fix-undefined-behavior-with-__fls-in-dp.patch -deleted file mode 100644 -index d68c19f160..0000000000 ---- a/package/kernel/mac80211/patches/ath11k/0061-wifi-ath11k-fix-undefined-behavior-with-__fls-in-dp.patch -+++ /dev/null -@@ -1,29 +0,0 @@ --From 41e02bf4ae32cf2ac47b08b4caaa9c1a032e4ce7 Mon Sep 17 00:00:00 2001 --From: Harshitha Prem --Date: Tue, 4 Apr 2023 00:11:55 +0530 --Subject: [PATCH] wifi: ath11k: fix undefined behavior with __fls in dp -- --"__fls" would have an undefined behavior if the argument is passed --as "0". Hence, added changes to handle the same. -- --Tested-on: IPQ8074 hw2.0 AHB WLAN.HK.2.7.0.1-01744-QCAHKSWPL_SILICONZ-1 -- --Signed-off-by: Harshitha Prem --Signed-off-by: Nagarajan Maran --Signed-off-by: Kalle Valo --Link: https://lore.kernel.org/r/20230403184155.8670-3-quic_nmaran@quicinc.com ----- -- drivers/net/wireless/ath/ath11k/dp_rx.c | 2 +- -- 1 file changed, 1 insertion(+), 1 deletion(-) -- ----- a/drivers/net/wireless/ath/ath11k/dp_rx.c --+++ b/drivers/net/wireless/ath/ath11k/dp_rx.c --@@ -3598,7 +3598,7 @@ static int ath11k_dp_rx_frag_h_mpdu(stru -- goto out_unlock; -- } -- --- if (frag_no > __fls(rx_tid->rx_frag_bitmap)) --+ if (!rx_tid->rx_frag_bitmap || (frag_no > __fls(rx_tid->rx_frag_bitmap))) -- __skb_queue_tail(&rx_tid->rx_frags, msdu); -- else -- ath11k_dp_rx_h_sort_frags(ar, &rx_tid->rx_frags, msdu); -diff --git a/package/kernel/mac80211/patches/ath11k/0062-wifi-ath11k-fix-double-free-of-peer-rx_tid-during-re.patch b/package/kernel/mac80211/patches/ath11k/0062-wifi-ath11k-fix-double-free-of-peer-rx_tid-during-re.patch -deleted file mode 100644 -index dd37b1e4fa..0000000000 ---- a/package/kernel/mac80211/patches/ath11k/0062-wifi-ath11k-fix-double-free-of-peer-rx_tid-during-re.patch -+++ /dev/null -@@ -1,144 +0,0 @@ --From 93a91f40c25c3d0e61f8540a7accf105090f9995 Mon Sep 17 00:00:00 2001 --From: Harshitha Prem --Date: Mon, 17 Apr 2023 13:35:00 +0300 --Subject: [PATCH] wifi: 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. -- --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: Sathishkumar Muruganandam --Signed-off-by: Harshitha Prem --Signed-off-by: Kalle Valo --Link: https://lore.kernel.org/r/20230403182420.23375-2-quic_hprem@quicinc.com ----- -- drivers/net/wireless/ath/ath11k/dp_rx.c | 43 ++++++++++++++++++------- -- 1 file changed, 31 insertions(+), 12 deletions(-) -- ----- a/drivers/net/wireless/ath/ath11k/dp_rx.c --+++ b/drivers/net/wireless/ath/ath11k/dp_rx.c --@@ -668,13 +668,18 @@ void ath11k_dp_reo_cmd_list_cleanup(stru -- struct ath11k_dp *dp = &ab->dp; -- struct dp_reo_cmd *cmd, *tmp; -- struct dp_reo_cache_flush_elem *cmd_cache, *tmp_cache; --+ struct dp_rx_tid *rx_tid; -- -- spin_lock_bh(&dp->reo_cmd_lock); -- list_for_each_entry_safe(cmd, tmp, &dp->reo_cmd_list, list) { -- list_del(&cmd->list); --- dma_unmap_single(ab->dev, cmd->data.paddr, --- cmd->data.size, DMA_BIDIRECTIONAL); --- kfree(cmd->data.vaddr); --+ rx_tid = &cmd->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); -- } -- --@@ -682,9 +687,13 @@ void ath11k_dp_reo_cmd_list_cleanup(stru -- &dp->reo_cmd_cache_flush_list, list) { -- list_del(&cmd_cache->list); -- dp->reo_cmd_cache_flush_count--; --- dma_unmap_single(ab->dev, cmd_cache->data.paddr, --- cmd_cache->data.size, DMA_BIDIRECTIONAL); --- kfree(cmd_cache->data.vaddr); --+ rx_tid = &cmd_cache->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_cache); -- } -- spin_unlock_bh(&dp->reo_cmd_lock); --@@ -698,10 +707,12 @@ static void ath11k_dp_reo_cmd_free(struc -- if (status != HAL_REO_CMD_SUCCESS) -- ath11k_warn(dp->ab, "failed to flush rx tid hw desc, tid %d status %d\n", -- rx_tid->tid, status); --- --- dma_unmap_single(dp->ab->dev, rx_tid->paddr, rx_tid->size, --- DMA_BIDIRECTIONAL); --- kfree(rx_tid->vaddr); --+ if (rx_tid->vaddr) { --+ dma_unmap_single(dp->ab->dev, rx_tid->paddr, rx_tid->size, --+ DMA_BIDIRECTIONAL); --+ kfree(rx_tid->vaddr); --+ rx_tid->vaddr = NULL; --+ } -- } -- -- static void ath11k_dp_reo_cache_flush(struct ath11k_base *ab, --@@ -740,6 +751,7 @@ static void ath11k_dp_reo_cache_flush(st -- dma_unmap_single(ab->dev, rx_tid->paddr, rx_tid->size, -- DMA_BIDIRECTIONAL); -- kfree(rx_tid->vaddr); --+ rx_tid->vaddr = NULL; -- } -- } -- --@@ -792,6 +804,7 @@ free_desc: -- dma_unmap_single(ab->dev, rx_tid->paddr, rx_tid->size, -- DMA_BIDIRECTIONAL); -- kfree(rx_tid->vaddr); --+ rx_tid->vaddr = NULL; -- } -- -- void ath11k_peer_rx_tid_delete(struct ath11k *ar, --@@ -804,6 +817,8 @@ void ath11k_peer_rx_tid_delete(struct at -- if (!rx_tid->active) -- return; -- --+ 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); --@@ -818,9 +833,11 @@ void ath11k_peer_rx_tid_delete(struct at -- dma_unmap_single(ar->ab->dev, rx_tid->paddr, rx_tid->size, -- DMA_BIDIRECTIONAL); -- kfree(rx_tid->vaddr); --+ rx_tid->vaddr = NULL; -- } -- --- rx_tid->active = false; --+ rx_tid->paddr = 0; --+ rx_tid->size = 0; -- } -- -- static int ath11k_dp_rx_link_desc_return(struct ath11k_base *ab, --@@ -967,6 +984,7 @@ static void ath11k_dp_rx_tid_mem_free(st -- dma_unmap_single(ab->dev, rx_tid->paddr, rx_tid->size, -- DMA_BIDIRECTIONAL); -- kfree(rx_tid->vaddr); --+ rx_tid->vaddr = NULL; -- -- rx_tid->active = false; -- --@@ -1067,7 +1085,8 @@ int ath11k_peer_rx_tid_setup(struct ath1 -- return ret; -- -- err_mem_free: --- kfree(vaddr); --+ kfree(rx_tid->vaddr); --+ rx_tid->vaddr = NULL; -- -- return ret; -- } -diff --git a/package/kernel/mac80211/patches/ath11k/0063-wifi-ath11k-Prevent-REO-cmd-failures.patch b/package/kernel/mac80211/patches/ath11k/0063-wifi-ath11k-Prevent-REO-cmd-failures.patch -deleted file mode 100644 -index 4b9af18062..0000000000 ---- a/package/kernel/mac80211/patches/ath11k/0063-wifi-ath11k-Prevent-REO-cmd-failures.patch -+++ /dev/null -@@ -1,43 +0,0 @@ --From a8ae833657a45746debde85c38bb7f070d344026 Mon Sep 17 00:00:00 2001 --From: Harshitha Prem --Date: Mon, 17 Apr 2023 13:35:01 +0300 --Subject: [PATCH] wifi: ath11k: Prevent REO cmd failures -- --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. -- --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: Sathishkumar Muruganandam --Signed-off-by: Harshitha Prem --Signed-off-by: Kalle Valo --Link: https://lore.kernel.org/r/20230403182420.23375-3-quic_hprem@quicinc.com ----- -- drivers/net/wireless/ath/ath11k/dp.h | 2 +- -- drivers/net/wireless/ath/ath11k/hw.c | 1 + -- 2 files changed, 2 insertions(+), 1 deletion(-) -- ----- a/drivers/net/wireless/ath/ath11k/dp.h --+++ b/drivers/net/wireless/ath/ath11k/dp.h --@@ -214,7 +214,7 @@ struct ath11k_pdev_dp { -- #define DP_REO_REINJECT_RING_SIZE 32 -- #define DP_RX_RELEASE_RING_SIZE 1024 -- #define DP_REO_EXCEPTION_RING_SIZE 128 ---#define DP_REO_CMD_RING_SIZE 128 --+#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 ----- a/drivers/net/wireless/ath/ath11k/hw.c --+++ b/drivers/net/wireless/ath/ath11k/hw.c --@@ -1233,6 +1233,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/0064-wifi-ath11k-add-peer-mac-information-in-failure-case.patch b/package/kernel/mac80211/patches/ath11k/0064-wifi-ath11k-add-peer-mac-information-in-failure-case.patch -deleted file mode 100644 -index fbcbdfff71..0000000000 ---- a/package/kernel/mac80211/patches/ath11k/0064-wifi-ath11k-add-peer-mac-information-in-failure-case.patch -+++ /dev/null -@@ -1,74 +0,0 @@ --From 20487cc3ff36bbfa9505f0a078ba98f09abfc717 Mon Sep 17 00:00:00 2001 --From: Harshitha Prem --Date: Mon, 17 Apr 2023 13:35:01 +0300 --Subject: [PATCH] wifi: ath11k: add peer mac information in failure cases -- --During reo command failure, the peer mac detail for which the reo --command was not successful is unknown. Hence, to improve the --debuggability, add the peer mac information in the failure cases --which would be useful during multi client cases. -- --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: Sathishkumar Muruganandam --Signed-off-by: Harshitha Prem --Signed-off-by: Kalle Valo --Link: https://lore.kernel.org/r/20230403182420.23375-4-quic_hprem@quicinc.com ----- -- drivers/net/wireless/ath/ath11k/dp_rx.c | 16 ++++++++++------ -- 1 file changed, 10 insertions(+), 6 deletions(-) -- ----- a/drivers/net/wireless/ath/ath11k/dp_rx.c --+++ b/drivers/net/wireless/ath/ath11k/dp_rx.c --@@ -1009,7 +1009,8 @@ int ath11k_peer_rx_tid_setup(struct ath1 -- -- peer = ath11k_peer_find(ab, vdev_id, peer_mac); -- if (!peer) { --- ath11k_warn(ab, "failed to find the peer to set up rx tid\n"); --+ ath11k_warn(ab, "failed to find the peer %pM to set up rx tid\n", --+ peer_mac); -- spin_unlock_bh(&ab->base_lock); -- return -ENOENT; -- } --@@ -1022,7 +1023,8 @@ int ath11k_peer_rx_tid_setup(struct ath1 -- ba_win_sz, ssn, true); -- spin_unlock_bh(&ab->base_lock); -- if (ret) { --- ath11k_warn(ab, "failed to update reo for rx tid %d\n", tid); --+ ath11k_warn(ab, "failed to update reo for peer %pM rx tid %d\n: %d", --+ peer_mac, tid, ret); -- return ret; -- } -- --@@ -1030,8 +1032,8 @@ int ath11k_peer_rx_tid_setup(struct ath1 -- peer_mac, paddr, -- tid, 1, ba_win_sz); -- if (ret) --- ath11k_warn(ab, "failed to send wmi command to update rx reorder queue, tid :%d (%d)\n", --- tid, ret); --+ ath11k_warn(ab, "failed to send wmi rx reorder queue for peer %pM tid %d: %d\n", --+ peer_mac, tid, ret); -- return ret; -- } -- --@@ -1064,6 +1066,8 @@ int ath11k_peer_rx_tid_setup(struct ath1 -- ret = dma_mapping_error(ab->dev, paddr); -- if (ret) { -- spin_unlock_bh(&ab->base_lock); --+ ath11k_warn(ab, "failed to setup dma map for peer %pM rx tid %d: %d\n", --+ peer_mac, tid, ret); -- goto err_mem_free; -- } -- --@@ -1077,8 +1081,8 @@ int ath11k_peer_rx_tid_setup(struct ath1 -- ret = ath11k_wmi_peer_rx_reorder_queue_setup(ar, vdev_id, peer_mac, -- paddr, tid, 1, ba_win_sz); -- if (ret) { --- ath11k_warn(ar->ab, "failed to setup rx reorder queue, tid :%d (%d)\n", --- tid, ret); --+ ath11k_warn(ar->ab, "failed to setup rx reorder queue for peer %pM tid %d: %d\n", --+ peer_mac, tid, ret); -- ath11k_dp_rx_tid_mem_free(ab, peer_mac, vdev_id, tid); -- } -- -diff --git a/package/kernel/mac80211/patches/ath11k/0065-wifi-ath11k-fix-tx-status-reporting-in-encap-offload.patch b/package/kernel/mac80211/patches/ath11k/0065-wifi-ath11k-fix-tx-status-reporting-in-encap-offload.patch -deleted file mode 100644 -index e2fe419158..0000000000 ---- a/package/kernel/mac80211/patches/ath11k/0065-wifi-ath11k-fix-tx-status-reporting-in-encap-offload.patch -+++ /dev/null -@@ -1,119 +0,0 @@ --From 6257c702264c44d74c6b71f0c62a7665da2dc356 Mon Sep 17 00:00:00 2001 --From: Pradeep Kumar Chitrapu --Date: Mon, 17 Apr 2023 13:35:02 +0300 --Subject: [PATCH] wifi: ath11k: fix tx status reporting in encap offload mode -- --ieee80211_tx_status() treats packets in 802.11 frame format and --tries to extract sta address from packet header. When tx encap --offload is enabled, this becomes invalid operation. Hence, switch --to using ieee80211_tx_status_ext() after filling in station --address for handling both 802.11 and 802.3 frames. -- --Tested-on: QCN9074 hw1.0 PCI WLAN.HK.2.7.0.1-01744-QCAHKSWPL_SILICONZ-1 -- --Signed-off-by: Pradeep Kumar Chitrapu --Signed-off-by: Kalle Valo --Link: https://lore.kernel.org/r/20230403195738.25367-2-quic_pradeepc@quicinc.com ----- -- drivers/net/wireless/ath/ath11k/dp.h | 4 +++ -- drivers/net/wireless/ath/ath11k/dp_tx.c | 33 ++++++++++++++++++++++++- -- drivers/net/wireless/ath/ath11k/dp_tx.h | 1 + -- 3 files changed, 37 insertions(+), 1 deletion(-) -- ----- a/drivers/net/wireless/ath/ath11k/dp.h --+++ b/drivers/net/wireless/ath/ath11k/dp.h --@@ -303,12 +303,16 @@ struct ath11k_dp { -- -- #define HTT_TX_WBM_COMP_STATUS_OFFSET 8 -- --+#define HTT_INVALID_PEER_ID 0xffff --+ -- /* HTT tx completion is overlaid in wbm_release_ring */ -- #define HTT_TX_WBM_COMP_INFO0_STATUS GENMASK(12, 9) -- #define HTT_TX_WBM_COMP_INFO0_REINJECT_REASON GENMASK(16, 13) -- #define HTT_TX_WBM_COMP_INFO0_REINJECT_REASON GENMASK(16, 13) -- -- #define HTT_TX_WBM_COMP_INFO1_ACK_RSSI GENMASK(31, 24) --+#define HTT_TX_WBM_COMP_INFO2_SW_PEER_ID GENMASK(15, 0) --+#define HTT_TX_WBM_COMP_INFO2_VALID BIT(21) -- -- struct htt_tx_wbm_completion { -- u32 info0; ----- a/drivers/net/wireless/ath/ath11k/dp_tx.c --+++ b/drivers/net/wireless/ath/ath11k/dp_tx.c --@@ -316,10 +316,12 @@ ath11k_dp_tx_htt_tx_complete_buf(struct -- struct dp_tx_ring *tx_ring, -- struct ath11k_dp_htt_wbm_tx_status *ts) -- { --+ struct ieee80211_tx_status status = { 0 }; -- struct sk_buff *msdu; -- struct ieee80211_tx_info *info; -- struct ath11k_skb_cb *skb_cb; -- struct ath11k *ar; --+ struct ath11k_peer *peer; -- -- spin_lock(&tx_ring->tx_idr_lock); -- msdu = idr_remove(&tx_ring->txbuf_idr, ts->msdu_id); --@@ -341,6 +343,11 @@ ath11k_dp_tx_htt_tx_complete_buf(struct -- -- dma_unmap_single(ab->dev, skb_cb->paddr, msdu->len, DMA_TO_DEVICE); -- --+ if (!skb_cb->vif) { --+ dev_kfree_skb_any(msdu); --+ return; --+ } --+ -- memset(&info->status, 0, sizeof(info->status)); -- -- if (ts->acked) { --@@ -355,7 +362,23 @@ ath11k_dp_tx_htt_tx_complete_buf(struct -- } -- } -- --- ieee80211_tx_status(ar->hw, msdu); --+ spin_lock_bh(&ab->base_lock); --+ peer = ath11k_peer_find_by_id(ab, ts->peer_id); --+ if (!peer || !peer->sta) { --+ ath11k_dbg(ab, ATH11K_DBG_DATA, --+ "dp_tx: failed to find the peer with peer_id %d\n", --+ ts->peer_id); --+ spin_unlock_bh(&ab->base_lock); --+ dev_kfree_skb_any(msdu); --+ return; --+ } --+ spin_unlock_bh(&ab->base_lock); --+ --+ status.sta = peer->sta; --+ status.info = info; --+ status.skb = msdu; --+ --+ ieee80211_tx_status_ext(ar->hw, &status); -- } -- -- static void --@@ -379,7 +402,15 @@ ath11k_dp_tx_process_htt_tx_complete(str -- ts.msdu_id = msdu_id; -- ts.ack_rssi = FIELD_GET(HTT_TX_WBM_COMP_INFO1_ACK_RSSI, -- status_desc->info1); --+ --+ if (FIELD_GET(HTT_TX_WBM_COMP_INFO2_VALID, status_desc->info2)) --+ ts.peer_id = FIELD_GET(HTT_TX_WBM_COMP_INFO2_SW_PEER_ID, --+ status_desc->info2); --+ else --+ ts.peer_id = HTT_INVALID_PEER_ID; --+ -- ath11k_dp_tx_htt_tx_complete_buf(ab, tx_ring, &ts); --+ -- break; -- case HAL_WBM_REL_HTT_TX_COMP_STATUS_REINJ: -- case HAL_WBM_REL_HTT_TX_COMP_STATUS_INSPECT: ----- a/drivers/net/wireless/ath/ath11k/dp_tx.h --+++ b/drivers/net/wireless/ath/ath11k/dp_tx.h --@@ -13,6 +13,7 @@ struct ath11k_dp_htt_wbm_tx_status { -- u32 msdu_id; -- bool acked; -- int ack_rssi; --+ u16 peer_id; -- }; -- -- void ath11k_dp_tx_update_txcompl(struct ath11k *ar, struct hal_tx_status *ts); -diff --git a/package/kernel/mac80211/patches/ath11k/0066-wifi-ath11k-Fix-incorrect-update-of-radiotap-fields.patch b/package/kernel/mac80211/patches/ath11k/0066-wifi-ath11k-Fix-incorrect-update-of-radiotap-fields.patch -deleted file mode 100644 -index 4f94580100..0000000000 ---- a/package/kernel/mac80211/patches/ath11k/0066-wifi-ath11k-Fix-incorrect-update-of-radiotap-fields.patch -+++ /dev/null -@@ -1,49 +0,0 @@ --From 2f0c9ac8362da09c80f1cd422ef7fd6fa9b252b9 Mon Sep 17 00:00:00 2001 --From: Pradeep Kumar Chitrapu --Date: Mon, 17 Apr 2023 13:35:02 +0300 --Subject: [PATCH] wifi: ath11k: Fix incorrect update of radiotap fields -- --Fix incorrect update of ppdu stats causing incorrect radiotap --fields. -- --Tested-on: QCN9074 hw1.0 PCI WLAN.HK.2.7.0.1-01744-QCAHKSWPL_SILICONZ-1 -- --Signed-off-by: Pradeep Kumar Chitrapu --Signed-off-by: Kalle Valo --Link: https://lore.kernel.org/r/20230403195738.25367-3-quic_pradeepc@quicinc.com ----- -- drivers/net/wireless/ath/ath11k/hal_rx.c | 4 ++-- -- drivers/net/wireless/ath/ath11k/hal_rx.h | 2 +- -- 2 files changed, 3 insertions(+), 3 deletions(-) -- ----- a/drivers/net/wireless/ath/ath11k/hal_rx.c --+++ b/drivers/net/wireless/ath/ath11k/hal_rx.c --@@ -1029,7 +1029,7 @@ ath11k_hal_rx_parse_mon_status_tlv(struc -- info1 = __le32_to_cpu(vht_sig->info1); -- -- ppdu_info->ldpc = FIELD_GET(HAL_RX_VHT_SIG_A_INFO_INFO1_SU_MU_CODING, --- info0); --+ info1); -- ppdu_info->mcs = FIELD_GET(HAL_RX_VHT_SIG_A_INFO_INFO1_MCS, -- info1); -- gi_setting = FIELD_GET(HAL_RX_VHT_SIG_A_INFO_INFO1_GI_SETTING, --@@ -1452,7 +1452,7 @@ ath11k_hal_rx_parse_mon_status_tlv(struc -- * PHYRX_OTHER_RECEIVE_INFO TLV. -- */ -- ppdu_info->rssi_comb = --- FIELD_GET(HAL_RX_PHYRX_RSSI_LEGACY_INFO_INFO1_RSSI_COMB, --+ FIELD_GET(HAL_RX_PHYRX_RSSI_LEGACY_INFO_INFO0_RSSI_COMB, -- __le32_to_cpu(rssi->info0)); -- -- if (db2dbm) { ----- a/drivers/net/wireless/ath/ath11k/hal_rx.h --+++ b/drivers/net/wireless/ath/ath11k/hal_rx.h --@@ -385,7 +385,7 @@ struct hal_rx_he_sig_b2_ofdma_info { -- __le32 info0; -- } __packed; -- ---#define HAL_RX_PHYRX_RSSI_LEGACY_INFO_INFO1_RSSI_COMB GENMASK(15, 8) --+#define HAL_RX_PHYRX_RSSI_LEGACY_INFO_INFO0_RSSI_COMB GENMASK(15, 8) -- -- #define HAL_RX_PHYRX_RSSI_PREAMBLE_PRI20 GENMASK(7, 0) -- -diff --git a/package/kernel/mac80211/patches/ath11k/0067-wifi-ath11k-Fix-SKB-corruption-in-REO-destination-ri.patch b/package/kernel/mac80211/patches/ath11k/0067-wifi-ath11k-Fix-SKB-corruption-in-REO-destination-ri.patch -deleted file mode 100644 -index 8b300f3a79..0000000000 ---- a/package/kernel/mac80211/patches/ath11k/0067-wifi-ath11k-Fix-SKB-corruption-in-REO-destination-ri.patch -+++ /dev/null -@@ -1,70 +0,0 @@ --From f9fff67d2d7ca6fa8066132003a3deef654c55b1 Mon Sep 17 00:00:00 2001 --From: Nagarajan Maran --Date: Mon, 17 Apr 2023 13:35:02 +0300 --Subject: [PATCH] wifi: ath11k: Fix SKB corruption in REO destination ring -- --While running traffics for a long time, randomly an RX descriptor --filled with value "0" from REO destination ring is received. --This descriptor which is invalid causes the wrong SKB (SKB stored in --the IDR lookup with buffer id "0") to be fetched which in turn --causes SKB memory corruption issue and the same leads to crash --after some time. -- --Changed the start id for idr allocation to "1" and the buffer id "0" --is reserved for error validation. Introduced Sanity check to validate --the descriptor, before processing the SKB. -- --Crash Signature : -- --Unable to handle kernel paging request at virtual address 3f004900 --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) -- --Tested-on: IPQ8074 hw2.0 AHB WLAN.HK.2.7.0.1-01744-QCAHKSWPL_SILICONZ-1 -- --Signed-off-by: Nagarajan Maran --Signed-off-by: Kalle Valo --Link: https://lore.kernel.org/r/20230403191533.28114-1-quic_nmaran@quicinc.com ----- -- drivers/net/wireless/ath/ath11k/dp_rx.c | 9 ++++++--- -- 1 file changed, 6 insertions(+), 3 deletions(-) -- ----- a/drivers/net/wireless/ath/ath11k/dp_rx.c --+++ b/drivers/net/wireless/ath/ath11k/dp_rx.c --@@ -389,10 +389,10 @@ 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, 0, --- rx_ring->bufs_max * 3, 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) --+ if (buf_id <= 0) -- goto fail_dma_unmap; -- -- desc = ath11k_hal_srng_src_get_next_entry(ab, srng); --@@ -2665,6 +2665,9 @@ try_again: -- cookie); -- mac_id = FIELD_GET(DP_RXDMA_BUF_COOKIE_PDEV_ID, cookie); -- --+ if (unlikely(buf_id == 0)) --+ continue; --+ -- ar = ab->pdevs[mac_id].ar; -- rx_ring = &ar->dp.rx_refill_buf_ring; -- spin_lock_bh(&rx_ring->idr_lock); -diff --git a/package/kernel/mac80211/patches/ath11k/0068-wifi-ath11k-Remove-disabling-of-80-80-and-160-MHz.patch b/package/kernel/mac80211/patches/ath11k/0068-wifi-ath11k-Remove-disabling-of-80-80-and-160-MHz.patch -deleted file mode 100644 -index ce5ffd273b..0000000000 ---- a/package/kernel/mac80211/patches/ath11k/0068-wifi-ath11k-Remove-disabling-of-80-80-and-160-MHz.patch -+++ /dev/null -@@ -1,49 +0,0 @@ --From b100722a777f6455d913666a376f81342b2cb995 Mon Sep 17 00:00:00 2001 --From: Muna Sinada --Date: Mon, 17 Apr 2023 13:22:27 -0700 --Subject: [PATCH] wifi: ath11k: Remove disabling of 80+80 and 160 MHz -- --This is a regression fix for 80+80 and 160 MHz support bits being --cleared, therefore not adverised. Remove disable of 80+80 and 160 MHz --capability flags and assign valid center frequency 2 similar to --VHT80_80. -- --Fixes: 38dfe775d0ab ("wifi: ath11k: push MU-MIMO params from hostapd to hardware") --Reported-by: Robert Marko --Tested-by: Robert Marko # IPQ8074 WLAN.HK.2.9.0.1-01385-QCAHKSWPL_SILICONZ-1 --Link: https://bugzilla.kernel.org/show_bug.cgi?id=217299 --Co-developed-by: P Praneesh --Signed-off-by: P Praneesh --Signed-off-by: Muna Sinada --Signed-off-by: Kalle Valo --Link: https://lore.kernel.org/r/1681762947-13882-1-git-send-email-quic_msinada@quicinc.com ----- -- drivers/net/wireless/ath/ath11k/mac.c | 4 ---- -- drivers/net/wireless/ath/ath11k/wmi.c | 3 ++- -- 2 files changed, 2 insertions(+), 5 deletions(-) -- ----- a/drivers/net/wireless/ath/ath11k/mac.c --+++ b/drivers/net/wireless/ath/ath11k/mac.c --@@ -5585,10 +5585,6 @@ static int ath11k_mac_copy_he_cap(struct -- -- he_cap_elem->mac_cap_info[1] &= -- IEEE80211_HE_MAC_CAP1_TF_MAC_PAD_DUR_MASK; --- he_cap_elem->phy_cap_info[0] &= --- ~IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_160MHZ_IN_5G; --- he_cap_elem->phy_cap_info[0] &= --- ~IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_80PLUS80_MHZ_IN_5G; -- -- he_cap_elem->phy_cap_info[5] &= -- ~IEEE80211_HE_PHY_CAP5_BEAMFORMEE_NUM_SND_DIM_UNDER_80MHZ_MASK; ----- a/drivers/net/wireless/ath/ath11k/wmi.c --+++ b/drivers/net/wireless/ath/ath11k/wmi.c --@@ -871,7 +871,8 @@ static void ath11k_wmi_put_wmi_channel(s -- -- chan->band_center_freq2 = arg->channel.band_center_freq1; -- --- } else if (arg->channel.mode == MODE_11AC_VHT80_80) { --+ } else if ((arg->channel.mode == MODE_11AC_VHT80_80) || --+ (arg->channel.mode == MODE_11AX_HE80_80)) { -- chan->band_center_freq2 = arg->channel.band_center_freq2; -- } else { -- chan->band_center_freq2 = 0; -diff --git a/package/kernel/mac80211/patches/ath11k/0069-wifi-ath11k-fix-registration-of-6Ghz-only-phy-withou.patch b/package/kernel/mac80211/patches/ath11k/0069-wifi-ath11k-fix-registration-of-6Ghz-only-phy-withou.patch -deleted file mode 100644 -index 32468dbc4c..0000000000 ---- a/package/kernel/mac80211/patches/ath11k/0069-wifi-ath11k-fix-registration-of-6Ghz-only-phy-withou.patch -+++ /dev/null -@@ -1,61 +0,0 @@ --From e2ceb1de2f83aafd8003f0b72dfd4b7441e97d14 Mon Sep 17 00:00:00 2001 --From: Maxime Bizon --Date: Fri, 21 Apr 2023 16:54:45 +0200 --Subject: [PATCH] wifi: ath11k: fix registration of 6Ghz-only phy without the -- full channel range -- --Because of what seems to be a typo, a 6Ghz-only phy for which the BDF --does not allow the 7115Mhz channel will fail to register: -- -- WARNING: CPU: 2 PID: 106 at net/wireless/core.c:907 wiphy_register+0x914/0x954 -- Modules linked in: ath11k_pci sbsa_gwdt -- CPU: 2 PID: 106 Comm: kworker/u8:5 Not tainted 6.3.0-rc7-next-20230418-00549-g1e096a17625a-dirty #9 -- Hardware name: Freebox V7R Board (DT) -- Workqueue: ath11k_qmi_driver_event ath11k_qmi_driver_event_work -- pstate: 60000005 (nZCv daif -PAN -UAO -TCO -DIT -SSBS BTYPE=--) -- pc : wiphy_register+0x914/0x954 -- lr : ieee80211_register_hw+0x67c/0xc10 -- sp : ffffff800b123aa0 -- x29: ffffff800b123aa0 x28: 0000000000000000 x27: 0000000000000000 -- x26: 0000000000000000 x25: 0000000000000006 x24: ffffffc008d51418 -- x23: ffffffc008cb0838 x22: ffffff80176c2460 x21: 0000000000000168 -- x20: ffffff80176c0000 x19: ffffff80176c03e0 x18: 0000000000000014 -- x17: 00000000cbef338c x16: 00000000d2a26f21 x15: 00000000ad6bb85f -- x14: 0000000000000020 x13: 0000000000000020 x12: 00000000ffffffbd -- x11: 0000000000000208 x10: 00000000fffffdf7 x9 : ffffffc009394718 -- x8 : ffffff80176c0528 x7 : 000000007fffffff x6 : 0000000000000006 -- x5 : 0000000000000005 x4 : ffffff800b304284 x3 : ffffff800b304284 -- x2 : ffffff800b304d98 x1 : 0000000000000000 x0 : 0000000000000000 -- Call trace: -- wiphy_register+0x914/0x954 -- ieee80211_register_hw+0x67c/0xc10 -- ath11k_mac_register+0x7c4/0xe10 -- ath11k_core_qmi_firmware_ready+0x1f4/0x570 -- ath11k_qmi_driver_event_work+0x198/0x590 -- process_one_work+0x1b8/0x328 -- worker_thread+0x6c/0x414 -- kthread+0x100/0x104 -- ret_from_fork+0x10/0x20 -- ---[ end trace 0000000000000000 ]--- -- ath11k_pci 0002:01:00.0: ieee80211 registration failed: -22 -- ath11k_pci 0002:01:00.0: failed register the radio with mac80211: -22 -- ath11k_pci 0002:01:00.0: failed to create pdev core: -22 -- --Signed-off-by: Maxime Bizon --Signed-off-by: Kalle Valo --Link: https://lore.kernel.org/r/20230421145445.2612280-1-mbizon@freebox.fr ----- -- drivers/net/wireless/ath/ath11k/mac.c | 2 +- -- 1 file changed, 1 insertion(+), 1 deletion(-) -- ----- a/drivers/net/wireless/ath/ath11k/mac.c --+++ b/drivers/net/wireless/ath/ath11k/mac.c --@@ -8892,7 +8892,7 @@ static int ath11k_mac_setup_channels_rat -- } -- -- if (supported_bands & WMI_HOST_WLAN_5G_CAP) { --- if (reg_cap->high_5ghz_chan >= ATH11K_MAX_6G_FREQ) { --+ if (reg_cap->high_5ghz_chan >= ATH11K_MIN_6G_FREQ) { -- channels = kmemdup(ath11k_6ghz_channels, -- sizeof(ath11k_6ghz_channels), GFP_KERNEL); -- if (!channels) { -diff --git a/package/kernel/mac80211/patches/ath11k/0070-wifi-ath-work-around-false-positive-stringop-overrea.patch b/package/kernel/mac80211/patches/ath11k/0070-wifi-ath-work-around-false-positive-stringop-overrea.patch -deleted file mode 100644 -index aa4df16a90..0000000000 ---- a/package/kernel/mac80211/patches/ath11k/0070-wifi-ath-work-around-false-positive-stringop-overrea.patch -+++ /dev/null -@@ -1,84 +0,0 @@ --From 695df2f417d25202bdac9cde3c82d2acb6492b4d Mon Sep 17 00:00:00 2001 --From: Arnd Bergmann --Date: Fri, 5 May 2023 16:11:25 +0300 --Subject: [PATCH] wifi: ath: work around false-positive stringop-overread -- warning -- --In a rare arm64 randconfig build, I got multiple warnings for ath11k --and ath12k: -- --In function 'ath11k_peer_assoc_h_ht', -- inlined from 'ath11k_peer_assoc_prepare' at drivers/net/wireless/ath/ath11k/mac.c:2665:2: --drivers/net/wireless/ath/ath11k/mac.c:1709:13: error: 'ath11k_peer_assoc_h_ht_masked' reading 10 bytes from a region of size 0 [-Werror=stringop-overread] -- 1709 | if (ath11k_peer_assoc_h_ht_masked(ht_mcs_mask)) -- | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -- --This happens whenever gcc-13 fails to inline one of the functions --that take a fixed-length array argument but gets passed a pointer. -- --Change these functions to all take a regular pointer argument --instead. -- --Signed-off-by: Arnd Bergmann --Signed-off-by: Kalle Valo --Link: https://lore.kernel.org/r/20230417205447.1800912-1-arnd@kernel.org ----- -- drivers/net/wireless/ath/ath11k/mac.c | 12 ++++++------ -- 1 file changed, 6 insertions(+), 6 deletions(-) -- ----- a/drivers/net/wireless/ath/ath11k/mac.c --+++ b/drivers/net/wireless/ath/ath11k/mac.c --@@ -433,7 +433,7 @@ u8 ath11k_mac_bitrate_to_idx(const struc -- } -- -- static u32 ---ath11k_mac_max_ht_nss(const u8 ht_mcs_mask[IEEE80211_HT_MCS_MASK_LEN]) --+ath11k_mac_max_ht_nss(const u8 *ht_mcs_mask) -- { -- int nss; -- --@@ -445,7 +445,7 @@ ath11k_mac_max_ht_nss(const u8 ht_mcs_ma -- } -- -- static u32 ---ath11k_mac_max_vht_nss(const u16 vht_mcs_mask[NL80211_VHT_NSS_MAX]) --+ath11k_mac_max_vht_nss(const u16 *vht_mcs_mask) -- { -- int nss; -- --@@ -457,7 +457,7 @@ ath11k_mac_max_vht_nss(const u16 vht_mcs -- } -- -- static u32 ---ath11k_mac_max_he_nss(const u16 he_mcs_mask[NL80211_HE_NSS_MAX]) --+ath11k_mac_max_he_nss(const u16 *he_mcs_mask) -- { -- int nss; -- --@@ -1658,7 +1658,7 @@ static void ath11k_peer_assoc_h_rates(st -- } -- -- static bool ---ath11k_peer_assoc_h_ht_masked(const u8 ht_mcs_mask[IEEE80211_HT_MCS_MASK_LEN]) --+ath11k_peer_assoc_h_ht_masked(const u8 *ht_mcs_mask) -- { -- int nss; -- --@@ -1670,7 +1670,7 @@ ath11k_peer_assoc_h_ht_masked(const u8 h -- } -- -- static bool ---ath11k_peer_assoc_h_vht_masked(const u16 vht_mcs_mask[]) --+ath11k_peer_assoc_h_vht_masked(const u16 *vht_mcs_mask) -- { -- int nss; -- --@@ -2065,7 +2065,7 @@ static u16 ath11k_peer_assoc_h_he_limit( -- } -- -- static bool ---ath11k_peer_assoc_h_he_masked(const u16 he_mcs_mask[NL80211_HE_NSS_MAX]) --+ath11k_peer_assoc_h_he_masked(const u16 *he_mcs_mask) -- { -- int nss; -- -diff --git a/package/kernel/mac80211/patches/ath11k/0071-wifi-ath11k-driver-settings-for-MBSSID-and-EMA.patch b/package/kernel/mac80211/patches/ath11k/0071-wifi-ath11k-driver-settings-for-MBSSID-and-EMA.patch -deleted file mode 100644 -index bede4819ca..0000000000 ---- a/package/kernel/mac80211/patches/ath11k/0071-wifi-ath11k-driver-settings-for-MBSSID-and-EMA.patch -+++ /dev/null -@@ -1,133 +0,0 @@ --From a08dbb04d7365a04d52882143cf196005bfc88c3 Mon Sep 17 00:00:00 2001 --From: Aloka Dixit --Date: Fri, 5 May 2023 16:11:27 +0300 --Subject: [PATCH 71/77] wifi: ath11k: driver settings for MBSSID and EMA -- --Advertise the driver support for multiple BSSID (MBSSID) and --enhanced multi-BSSID advertisements (EMA) by setting extended --capabilities. -- --Configure mbssid_max_interfaces and ema_max_profile_periodicity --fields in structure wiphy which are used to advertise maximum number --of interfaces and profile periodicity supported by the driver. -- --Add new WMI fields to configure maximum vdev count supported for --MBSSID and profile periodicity in case of EMA. --Setting WMI_RSRC_CFG_FLAG2_CALC_NEXT_DTIM_COUNT_SET flag --indicates that the firmware should track and update the DTIM counts --for each non-transmitted profile. -- --Tested-on: IPQ8074 hw2.0 AHB WLAN.HK.2.7.0.1-01744-QCAHKSWPL_SILICONZ-1 -- --Signed-off-by: Aloka Dixit --Co-developed-by: John Crispin --Signed-off-by: John Crispin --Signed-off-by: Kalle Valo --Link: https://lore.kernel.org/r/20230405221648.17950-2-quic_alokad@quicinc.com ----- -- drivers/net/wireless/ath/ath11k/hw.c | 3 +++ -- drivers/net/wireless/ath/ath11k/hw.h | 1 + -- drivers/net/wireless/ath/ath11k/mac.c | 7 +++++++ -- drivers/net/wireless/ath/ath11k/wmi.c | 3 +++ -- drivers/net/wireless/ath/ath11k/wmi.h | 6 ++++++ -- 5 files changed, 20 insertions(+) -- ----- a/drivers/net/wireless/ath/ath11k/hw.c --+++ b/drivers/net/wireless/ath/ath11k/hw.c --@@ -202,6 +202,9 @@ static void ath11k_init_wmi_config_ipq80 -- config->twt_ap_sta_count = 1000; -- config->flag1 |= WMI_RSRC_CFG_FLAG1_BSS_CHANNEL_INFO_64; -- config->flag1 |= WMI_RSRC_CFG_FLAG1_ACK_RSSI; --+ config->ema_max_vap_cnt = ab->num_radios; --+ config->ema_max_profile_period = TARGET_EMA_MAX_PROFILE_PERIOD; --+ config->beacon_tx_offload_max_vdev += config->ema_max_vap_cnt; -- } -- -- static int ath11k_hw_mac_id_to_pdev_id_ipq8074(struct ath11k_hw_params *hw, ----- a/drivers/net/wireless/ath/ath11k/hw.h --+++ b/drivers/net/wireless/ath/ath11k/hw.h --@@ -64,6 +64,7 @@ -- #define TARGET_NUM_WDS_ENTRIES 32 -- #define TARGET_DMA_BURST_SIZE 1 -- #define TARGET_RX_BATCHMODE 1 --+#define TARGET_EMA_MAX_PROFILE_PERIOD 8 -- -- #define ATH11K_HW_MAX_QUEUES 4 -- #define ATH11K_QUEUE_LEN 4096 ----- a/drivers/net/wireless/ath/ath11k/mac.c --+++ b/drivers/net/wireless/ath/ath11k/mac.c --@@ -9001,19 +9001,23 @@ static int ath11k_mac_setup_iface_combin -- -- static const u8 ath11k_if_types_ext_capa[] = { -- [0] = WLAN_EXT_CAPA1_EXT_CHANNEL_SWITCHING, --+ [2] = WLAN_EXT_CAPA3_MULTI_BSSID_SUPPORT, -- [7] = WLAN_EXT_CAPA8_OPMODE_NOTIF, -- }; -- -- static const u8 ath11k_if_types_ext_capa_sta[] = { -- [0] = WLAN_EXT_CAPA1_EXT_CHANNEL_SWITCHING, --+ [2] = WLAN_EXT_CAPA3_MULTI_BSSID_SUPPORT, -- [7] = WLAN_EXT_CAPA8_OPMODE_NOTIF, -- [9] = WLAN_EXT_CAPA10_TWT_REQUESTER_SUPPORT, -- }; -- -- static const u8 ath11k_if_types_ext_capa_ap[] = { -- [0] = WLAN_EXT_CAPA1_EXT_CHANNEL_SWITCHING, --+ [2] = WLAN_EXT_CAPA3_MULTI_BSSID_SUPPORT, -- [7] = WLAN_EXT_CAPA8_OPMODE_NOTIF, -- [9] = WLAN_EXT_CAPA10_TWT_RESPONDER_SUPPORT, --+ [10] = WLAN_EXT_CAPA11_EMA_SUPPORT, -- }; -- -- static const struct wiphy_iftype_ext_capab ath11k_iftypes_ext_capa[] = { --@@ -9251,6 +9255,9 @@ static int __ath11k_mac_register(struct -- wiphy_ext_feature_set(ar->hw->wiphy, -- NL80211_EXT_FEATURE_ENABLE_FTM_RESPONDER); -- --+ ar->hw->wiphy->mbssid_max_interfaces = TARGET_NUM_VDEVS(ab); --+ ar->hw->wiphy->ema_max_profile_periodicity = TARGET_EMA_MAX_PROFILE_PERIOD; --+ -- ath11k_reg_init(ar); -- -- if (!test_bit(ATH11K_FLAG_RAW_MODE, &ab->dev_flags)) { ----- a/drivers/net/wireless/ath/ath11k/wmi.c --+++ b/drivers/net/wireless/ath/ath11k/wmi.c --@@ -3987,6 +3987,9 @@ ath11k_wmi_copy_resource_config(struct w -- ~(1 << WMI_CFG_HOST_SERVICE_FLAG_REG_CC_EXT); -- wmi_cfg->host_service_flags |= (tg_cfg->is_reg_cc_ext_event_supported << -- WMI_CFG_HOST_SERVICE_FLAG_REG_CC_EXT); --+ 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; -- } -- -- static int ath11k_init_cmd_send(struct ath11k_pdev_wmi *wmi, ----- a/drivers/net/wireless/ath/ath11k/wmi.h --+++ b/drivers/net/wireless/ath/ath11k/wmi.h --@@ -2317,6 +2317,7 @@ struct wmi_init_cmd { -- } __packed; -- -- #define WMI_RSRC_CFG_FLAG1_BSS_CHANNEL_INFO_64 BIT(5) --+#define WMI_RSRC_CFG_FLAG2_CALC_NEXT_DTIM_COUNT_SET BIT(9) -- #define WMI_RSRC_CFG_FLAG1_ACK_RSSI BIT(18) -- -- #define WMI_CFG_HOST_SERVICE_FLAG_REG_CC_EXT 4 --@@ -2389,6 +2390,9 @@ struct wmi_resource_config { -- u32 msdu_flow_override_config1; -- u32 flags2; -- u32 host_service_flags; --+ u32 max_rnr_neighbours; --+ u32 ema_max_vap_cnt; --+ u32 ema_max_profile_period; -- } __packed; -- -- struct wmi_service_ready_event { --@@ -5646,6 +5650,8 @@ struct target_resource_config { -- u32 twt_ap_pdev_count; -- u32 twt_ap_sta_count; -- u8 is_reg_cc_ext_event_supported; --+ u32 ema_max_vap_cnt; --+ u32 ema_max_profile_period; -- }; -- -- enum wmi_debug_log_param { -diff --git a/package/kernel/mac80211/patches/ath11k/0072-wifi-ath11k-MBSSID-configuration-during-vdev-create-.patch b/package/kernel/mac80211/patches/ath11k/0072-wifi-ath11k-MBSSID-configuration-during-vdev-create-.patch -deleted file mode 100644 -index 4ba0717319..0000000000 ---- a/package/kernel/mac80211/patches/ath11k/0072-wifi-ath11k-MBSSID-configuration-during-vdev-create-.patch -+++ /dev/null -@@ -1,215 +0,0 @@ --From 5a81610acf66c4ad6e1a1fbd09f3f555fca863b1 Mon Sep 17 00:00:00 2001 --From: Aloka Dixit --Date: Fri, 5 May 2023 16:11:27 +0300 --Subject: [PATCH 72/77] wifi: ath11k: MBSSID configuration during vdev -- create/start -- --Configure multiple BSSID flags and index of the transmitting interface --in vdev create/start commands depending on the service bit --WMI_TLV_SERVICE_MBSS_PARAM_IN_VDEV_START_SUPPORT. -- --Tested-on: IPQ8074 hw2.0 AHB WLAN.HK.2.7.0.1-01744-QCAHKSWPL_SILICONZ-1 -- --Signed-off-by: Aloka Dixit --Co-developed-by: John Crispin --Signed-off-by: John Crispin --Signed-off-by: Kalle Valo --Link: https://lore.kernel.org/r/20230405221648.17950-3-quic_alokad@quicinc.com ----- -- drivers/net/wireless/ath/ath11k/mac.c | 70 +++++++++++++++++++++++++-- -- drivers/net/wireless/ath/ath11k/wmi.c | 5 ++ -- drivers/net/wireless/ath/ath11k/wmi.h | 19 ++++++++ -- 3 files changed, 90 insertions(+), 4 deletions(-) -- ----- a/drivers/net/wireless/ath/ath11k/mac.c --+++ b/drivers/net/wireless/ath/ath11k/mac.c --@@ -6181,17 +6181,62 @@ static void ath11k_mac_op_stop(struct ie -- atomic_set(&ar->num_pending_mgmt_tx, 0); -- } -- ---static void ---ath11k_mac_setup_vdev_create_params(struct ath11k_vif *arvif, --- struct vdev_create_params *params) --+static int ath11k_mac_setup_vdev_params_mbssid(struct ath11k_vif *arvif, --+ u32 *flags, u32 *tx_vdev_id) --+{ --+ struct ath11k *ar = arvif->ar; --+ struct ath11k_vif *tx_arvif; --+ struct ieee80211_vif *tx_vif; --+ --+ *tx_vdev_id = 0; --+ tx_vif = arvif->vif->mbssid_tx_vif; --+ if (!tx_vif) { --+ *flags = WMI_HOST_VDEV_FLAGS_NON_MBSSID_AP; --+ return 0; --+ } --+ --+ tx_arvif = (void *)tx_vif->drv_priv; --+ --+ if (arvif->vif->bss_conf.nontransmitted) { --+ if (ar->hw->wiphy != ieee80211_vif_to_wdev(tx_vif)->wiphy) --+ return -EINVAL; --+ --+ *flags = WMI_HOST_VDEV_FLAGS_NON_TRANSMIT_AP; --+ *tx_vdev_id = ath11k_vif_to_arvif(tx_vif)->vdev_id; --+ } else if (tx_arvif == arvif) { --+ *flags = WMI_HOST_VDEV_FLAGS_TRANSMIT_AP; --+ } else { --+ return -EINVAL; --+ } --+ --+ if (arvif->vif->bss_conf.ema_ap) --+ *flags |= WMI_HOST_VDEV_FLAGS_EMA_MODE; --+ --+ return 0; --+} --+ --+static int ath11k_mac_setup_vdev_create_params(struct ath11k_vif *arvif, --+ struct vdev_create_params *params) -- { -- struct ath11k *ar = arvif->ar; -- struct ath11k_pdev *pdev = ar->pdev; --+ int ret; -- -- params->if_id = arvif->vdev_id; -- params->type = arvif->vdev_type; -- params->subtype = arvif->vdev_subtype; -- params->pdev_id = pdev->pdev_id; --+ params->mbssid_flags = 0; --+ params->mbssid_tx_vdev_id = 0; --+ --+ if (!test_bit(WMI_TLV_SERVICE_MBSS_PARAM_IN_VDEV_START_SUPPORT, --+ ar->ab->wmi_ab.svc_map)) { --+ ret = ath11k_mac_setup_vdev_params_mbssid(arvif, --+ ¶ms->mbssid_flags, --+ ¶ms->mbssid_tx_vdev_id); --+ if (ret) --+ return ret; --+ } -- -- if (pdev->cap.supported_bands & WMI_HOST_WLAN_2G_CAP) { -- params->chains[NL80211_BAND_2GHZ].tx = ar->num_tx_chains; --@@ -6206,6 +6251,7 @@ ath11k_mac_setup_vdev_create_params(stru -- params->chains[NL80211_BAND_6GHZ].tx = ar->num_tx_chains; -- params->chains[NL80211_BAND_6GHZ].rx = ar->num_rx_chains; -- } --+ return 0; -- } -- -- static void ath11k_mac_op_update_vif_offload(struct ieee80211_hw *hw, --@@ -6500,7 +6546,12 @@ static int ath11k_mac_op_add_interface(s -- for (i = 0; i < ARRAY_SIZE(vif->hw_queue); i++) -- vif->hw_queue[i] = i % (ATH11K_HW_MAX_QUEUES - 1); -- --- ath11k_mac_setup_vdev_create_params(arvif, &vdev_param); --+ ret = ath11k_mac_setup_vdev_create_params(arvif, &vdev_param); --+ if (ret) { --+ ath11k_warn(ab, "failed to create vdev parameters %d: %d\n", --+ arvif->vdev_id, ret); --+ goto err; --+ } -- -- ret = ath11k_wmi_vdev_create(ar, vif->addr, &vdev_param); -- if (ret) { --@@ -6905,6 +6956,17 @@ ath11k_mac_vdev_start_restart(struct ath -- arg.pref_tx_streams = ar->num_tx_chains; -- arg.pref_rx_streams = ar->num_rx_chains; -- --+ arg.mbssid_flags = 0; --+ arg.mbssid_tx_vdev_id = 0; --+ if (test_bit(WMI_TLV_SERVICE_MBSS_PARAM_IN_VDEV_START_SUPPORT, --+ ar->ab->wmi_ab.svc_map)) { --+ ret = ath11k_mac_setup_vdev_params_mbssid(arvif, --+ &arg.mbssid_flags, --+ &arg.mbssid_tx_vdev_id); --+ if (ret) --+ return ret; --+ } --+ -- if (arvif->vdev_type == WMI_VDEV_TYPE_AP) { -- arg.ssid = arvif->u.ap.ssid; -- arg.ssid_len = arvif->u.ap.ssid_len; ----- a/drivers/net/wireless/ath/ath11k/wmi.c --+++ b/drivers/net/wireless/ath/ath11k/wmi.c --@@ -724,6 +724,9 @@ int ath11k_wmi_vdev_create(struct ath11k -- cmd->vdev_subtype = param->subtype; -- cmd->num_cfg_txrx_streams = WMI_NUM_SUPPORTED_BAND_MAX; -- cmd->pdev_id = param->pdev_id; --+ cmd->mbssid_flags = param->mbssid_flags; --+ cmd->mbssid_tx_vdev_id = param->mbssid_tx_vdev_id; --+ -- ether_addr_copy(cmd->vdev_macaddr.addr, macaddr); -- -- ptr = skb->data + sizeof(*cmd); --@@ -941,6 +944,8 @@ int ath11k_wmi_vdev_start(struct ath11k -- cmd->cac_duration_ms = arg->cac_duration_ms; -- cmd->regdomain = arg->regdomain; -- cmd->he_ops = arg->he_ops; --+ cmd->mbssid_flags = arg->mbssid_flags; --+ cmd->mbssid_tx_vdev_id = arg->mbssid_tx_vdev_id; -- -- if (!restart) { -- if (arg->ssid) { ----- a/drivers/net/wireless/ath/ath11k/wmi.h --+++ b/drivers/net/wireless/ath/ath11k/wmi.h --@@ -137,6 +137,14 @@ enum { -- WMI_AUTORATE_3200NS_GI = BIT(11), -- }; -- --+enum { --+ WMI_HOST_VDEV_FLAGS_NON_MBSSID_AP = 0x00000001, --+ WMI_HOST_VDEV_FLAGS_TRANSMIT_AP = 0x00000002, --+ WMI_HOST_VDEV_FLAGS_NON_TRANSMIT_AP = 0x00000004, --+ WMI_HOST_VDEV_FLAGS_EMA_MODE = 0x00000008, --+ WMI_HOST_VDEV_FLAGS_SCAN_MODE_VAP = 0x00000010, --+}; --+ -- /* -- * wmi command groups. -- */ --@@ -2096,6 +2104,7 @@ enum wmi_tlv_service { -- WMI_TLV_SERVICE_EXT2_MSG = 220, -- 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_PASSIVE_SCAN_START_TIME_ENHANCE = 263, -- -- /* The second 128 bits */ --@@ -2583,6 +2592,8 @@ struct vdev_create_params { -- u8 rx; -- } chains[NUM_NL80211_BANDS]; -- u32 pdev_id; --+ u32 mbssid_flags; --+ u32 mbssid_tx_vdev_id; -- }; -- -- struct wmi_vdev_create_cmd { --@@ -2593,6 +2604,8 @@ struct wmi_vdev_create_cmd { -- struct wmi_mac_addr vdev_macaddr; -- u32 num_cfg_txrx_streams; -- u32 pdev_id; --+ u32 mbssid_flags; --+ u32 mbssid_tx_vdev_id; -- } __packed; -- -- struct wmi_vdev_txrx_streams { --@@ -2656,6 +2669,9 @@ struct wmi_vdev_start_request_cmd { -- u32 he_ops; -- u32 cac_duration_ms; -- u32 regdomain; --+ u32 min_data_rate; --+ u32 mbssid_flags; --+ u32 mbssid_tx_vdev_id; -- } __packed; -- -- #define MGMT_TX_DL_FRM_LEN 64 --@@ -2825,6 +2841,9 @@ struct wmi_vdev_start_req_arg { -- u32 pref_rx_streams; -- u32 pref_tx_streams; -- u32 num_noa_descriptors; --+ u32 min_data_rate; --+ u32 mbssid_flags; --+ u32 mbssid_tx_vdev_id; -- }; -- -- struct peer_create_params { -diff --git a/package/kernel/mac80211/patches/ath11k/0073-wifi-ath11k-rename-MBSSID-fields-in-wmi_vdev_up_cmd.patch b/package/kernel/mac80211/patches/ath11k/0073-wifi-ath11k-rename-MBSSID-fields-in-wmi_vdev_up_cmd.patch -deleted file mode 100644 -index 023a1dbb9f..0000000000 ---- a/package/kernel/mac80211/patches/ath11k/0073-wifi-ath11k-rename-MBSSID-fields-in-wmi_vdev_up_cmd.patch -+++ /dev/null -@@ -1,52 +0,0 @@ --From cf604e72bc6e6db68c7fcaa8779b03ec14b8d2fa Mon Sep 17 00:00:00 2001 --From: Aloka Dixit --Date: Fri, 5 May 2023 16:11:27 +0300 --Subject: [PATCH 73/77] wifi: ath11k: rename MBSSID fields in wmi_vdev_up_cmd -- --Rename trans_bssid to tx_vdev_bssid to make it similar to vdev_bssid. -- --Rename profile_num to nontx_profile_cnt, and profile_idx to --nontx_profile_idx which makes it clear that these store configurations --related to MBSSID non-transmitting profiles. -- --Tested-on: IPQ8074 hw2.0 AHB WLAN.HK.2.7.0.1-01744-QCAHKSWPL_SILICONZ-1 -- --Signed-off-by: Aloka Dixit --Signed-off-by: Kalle Valo --Link: https://lore.kernel.org/r/20230405221648.17950-4-quic_alokad@quicinc.com ----- -- drivers/net/wireless/ath/ath11k/wmi.c | 6 +++--- -- drivers/net/wireless/ath/ath11k/wmi.h | 6 +++--- -- 2 files changed, 6 insertions(+), 6 deletions(-) -- ----- a/drivers/net/wireless/ath/ath11k/wmi.c --+++ b/drivers/net/wireless/ath/ath11k/wmi.c --@@ -1029,10 +1029,10 @@ int ath11k_wmi_vdev_up(struct ath11k *ar -- bss_conf = &arvif->vif->bss_conf; -- -- if (bss_conf->nontransmitted) { --- ether_addr_copy(cmd->trans_bssid.addr, --+ ether_addr_copy(cmd->tx_vdev_bssid.addr, -- bss_conf->transmitter_bssid); --- cmd->profile_idx = bss_conf->bssid_index; --- cmd->profile_num = bss_conf->bssid_indicator; --+ cmd->nontx_profile_idx = bss_conf->bssid_index; --+ cmd->nontx_profile_cnt = bss_conf->bssid_indicator; -- } -- } -- ----- a/drivers/net/wireless/ath/ath11k/wmi.h --+++ b/drivers/net/wireless/ath/ath11k/wmi.h --@@ -2625,9 +2625,9 @@ struct wmi_vdev_up_cmd { -- u32 vdev_id; -- u32 vdev_assoc_id; -- struct wmi_mac_addr vdev_bssid; --- struct wmi_mac_addr trans_bssid; --- u32 profile_idx; --- u32 profile_num; --+ struct wmi_mac_addr tx_vdev_bssid; --+ u32 nontx_profile_idx; --+ u32 nontx_profile_cnt; -- } __packed; -- -- struct wmi_vdev_stop_cmd { -diff --git a/package/kernel/mac80211/patches/ath11k/0074-wifi-ath11k-MBSSID-parameter-configuration-in-AP-mod.patch b/package/kernel/mac80211/patches/ath11k/0074-wifi-ath11k-MBSSID-parameter-configuration-in-AP-mod.patch -deleted file mode 100644 -index d93e27dd42..0000000000 ---- a/package/kernel/mac80211/patches/ath11k/0074-wifi-ath11k-MBSSID-parameter-configuration-in-AP-mod.patch -+++ /dev/null -@@ -1,138 +0,0 @@ --From c82dc33f252fd8883be66f2d0230af0fd734c683 Mon Sep 17 00:00:00 2001 --From: Aloka Dixit --Date: Fri, 5 May 2023 16:11:27 +0300 --Subject: [PATCH 74/77] wifi: ath11k: MBSSID parameter configuration in AP mode -- --Include MBSSID parameters in WMI vdev up operation. -- --Tested-on: IPQ8074 hw2.0 AHB WLAN.HK.2.7.0.1-01744-QCAHKSWPL_SILICONZ-1 -- --Signed-off-by: Aloka Dixit --Co-developed-by: John Crispin --Signed-off-by: John Crispin --Signed-off-by: Kalle Valo --Link: https://lore.kernel.org/r/20230405221648.17950-5-quic_alokad@quicinc.com ----- -- drivers/net/wireless/ath/ath11k/mac.c | 29 +++++++++++++++++++++------ -- drivers/net/wireless/ath/ath11k/wmi.c | 8 +++++++- -- drivers/net/wireless/ath/ath11k/wmi.h | 3 ++- -- 3 files changed, 32 insertions(+), 8 deletions(-) -- ----- a/drivers/net/wireless/ath/ath11k/mac.c --+++ b/drivers/net/wireless/ath/ath11k/mac.c --@@ -964,7 +964,7 @@ static int ath11k_mac_monitor_vdev_start -- return ret; -- } -- --- ret = ath11k_wmi_vdev_up(ar, vdev_id, 0, ar->mac_addr); --+ ret = ath11k_wmi_vdev_up(ar, vdev_id, 0, ar->mac_addr, NULL, 0, 0); -- if (ret) { -- ath11k_warn(ar->ab, "failed to put up monitor vdev %i: %d\n", -- vdev_id, ret); --@@ -1423,6 +1423,7 @@ static void ath11k_control_beaconing(str -- struct ieee80211_bss_conf *info) -- { -- struct ath11k *ar = arvif->ar; --+ struct ath11k_vif *tx_arvif = NULL; -- int ret = 0; -- -- lockdep_assert_held(&arvif->ar->conf_mutex); --@@ -1451,8 +1452,14 @@ static void ath11k_control_beaconing(str -- -- ether_addr_copy(arvif->bssid, info->bssid); -- --+ if (arvif->vif->mbssid_tx_vif) --+ tx_arvif = (struct ath11k_vif *)arvif->vif->mbssid_tx_vif->drv_priv; --+ -- ret = ath11k_wmi_vdev_up(arvif->ar, arvif->vdev_id, arvif->aid, --- arvif->bssid); --+ arvif->bssid, --+ tx_arvif ? tx_arvif->bssid : NULL, --+ info->bssid_index, --+ 1 << info->bssid_indicator); -- if (ret) { -- ath11k_warn(ar->ab, "failed to bring up vdev %d: %i\n", -- arvif->vdev_id, ret); --@@ -2879,7 +2886,8 @@ static void ath11k_bss_assoc(struct ieee -- arvif->aid = vif->cfg.aid; -- ether_addr_copy(arvif->bssid, bss_conf->bssid); -- --- ret = ath11k_wmi_vdev_up(ar, arvif->vdev_id, arvif->aid, arvif->bssid); --+ ret = ath11k_wmi_vdev_up(ar, arvif->vdev_id, arvif->aid, arvif->bssid, --+ NULL, 0, 0); -- if (ret) { -- ath11k_warn(ar->ab, "failed to set vdev %d up: %d\n", -- arvif->vdev_id, ret); --@@ -7133,7 +7141,8 @@ ath11k_mac_update_vif_chan(struct ath11k -- int n_vifs) -- { -- struct ath11k_base *ab = ar->ab; --- struct ath11k_vif *arvif; --+ struct ath11k_vif *arvif, *tx_arvif = NULL; --+ struct ieee80211_vif *mbssid_tx_vif; -- int ret; -- int i; -- bool monitor_vif = false; --@@ -7187,8 +7196,15 @@ ath11k_mac_update_vif_chan(struct ath11k -- ath11k_warn(ab, "failed to update bcn tmpl during csa: %d\n", -- ret); -- --+ mbssid_tx_vif = arvif->vif->mbssid_tx_vif; --+ if (mbssid_tx_vif) --+ tx_arvif = (struct ath11k_vif *)mbssid_tx_vif->drv_priv; --+ -- ret = ath11k_wmi_vdev_up(arvif->ar, arvif->vdev_id, arvif->aid, --- arvif->bssid); --+ arvif->bssid, --+ tx_arvif ? tx_arvif->bssid : NULL, --+ arvif->vif->bss_conf.bssid_index, --+ 1 << arvif->vif->bss_conf.bssid_indicator); -- if (ret) { -- ath11k_warn(ab, "failed to bring vdev up %d: %d\n", -- arvif->vdev_id, ret); --@@ -7306,7 +7322,8 @@ static int ath11k_start_vdev_delay(struc -- } -- -- if (arvif->vdev_type == WMI_VDEV_TYPE_MONITOR) { --- ret = ath11k_wmi_vdev_up(ar, arvif->vdev_id, 0, ar->mac_addr); --+ ret = ath11k_wmi_vdev_up(ar, arvif->vdev_id, 0, ar->mac_addr, --+ NULL, 0, 0); -- if (ret) { -- ath11k_warn(ab, "failed put monitor up: %d\n", ret); -- return ret; ----- a/drivers/net/wireless/ath/ath11k/wmi.c --+++ b/drivers/net/wireless/ath/ath11k/wmi.c --@@ -1001,7 +1001,8 @@ int ath11k_wmi_vdev_start(struct ath11k -- return ret; -- } -- ---int ath11k_wmi_vdev_up(struct ath11k *ar, u32 vdev_id, u32 aid, const u8 *bssid) --+int ath11k_wmi_vdev_up(struct ath11k *ar, u32 vdev_id, u32 aid, const u8 *bssid, --+ u8 *tx_bssid, u32 nontx_profile_idx, u32 nontx_profile_cnt) -- { -- struct ath11k_pdev_wmi *wmi = ar->wmi; -- struct wmi_vdev_up_cmd *cmd; --@@ -1025,6 +1026,11 @@ int ath11k_wmi_vdev_up(struct ath11k *ar -- -- ether_addr_copy(cmd->vdev_bssid.addr, bssid); -- --+ cmd->nontx_profile_idx = nontx_profile_idx; --+ cmd->nontx_profile_cnt = nontx_profile_cnt; --+ if (tx_bssid) --+ ether_addr_copy(cmd->tx_vdev_bssid.addr, tx_bssid); --+ -- if (arvif && arvif->vif->type == NL80211_IFTYPE_STATION) { -- bss_conf = &arvif->vif->bss_conf; -- ----- a/drivers/net/wireless/ath/ath11k/wmi.h --+++ b/drivers/net/wireless/ath/ath11k/wmi.h --@@ -6301,7 +6301,8 @@ int ath11k_wmi_bcn_tmpl(struct ath11k *a -- struct sk_buff *bcn); -- int ath11k_wmi_vdev_down(struct ath11k *ar, u8 vdev_id); -- int ath11k_wmi_vdev_up(struct ath11k *ar, u32 vdev_id, u32 aid, --- const u8 *bssid); --+ const u8 *bssid, u8 *tx_bssid, u32 nontx_profile_idx, --+ u32 nontx_profile_cnt); -- int ath11k_wmi_vdev_stop(struct ath11k *ar, u8 vdev_id); -- int ath11k_wmi_vdev_start(struct ath11k *ar, struct wmi_vdev_start_req_arg *arg, -- bool restart); -diff --git a/package/kernel/mac80211/patches/ath11k/0075-wifi-ath11k-refactor-vif-parameter-configurations.patch b/package/kernel/mac80211/patches/ath11k/0075-wifi-ath11k-refactor-vif-parameter-configurations.patch -deleted file mode 100644 -index 8509e55978..0000000000 ---- a/package/kernel/mac80211/patches/ath11k/0075-wifi-ath11k-refactor-vif-parameter-configurations.patch -+++ /dev/null -@@ -1,86 +0,0 @@ --From cb9bea773c85e372931cd7a177db4165adf29d95 Mon Sep 17 00:00:00 2001 --From: Aloka Dixit --Date: Fri, 5 May 2023 16:11:28 +0300 --Subject: [PATCH 75/77] wifi: ath11k: refactor vif parameter configurations -- --Security parameters for each non-transmitting profile can be --different when MBSSID is enabled and this information is included --in the MBSSID element in the Beacon frame. Current implementation --to set rsnie_present and wpaie_present does not parse this element --hence it applies only to the transmitting interface. -- --Move the code to a separate function to make additions for --non-transmitting interfaces cleaner. -- --Tested-on: IPQ8074 hw2.0 AHB WLAN.HK.2.7.0.1-01744-QCAHKSWPL_SILICONZ-1 -- --Signed-off-by: Aloka Dixit --Signed-off-by: Kalle Valo --Link: https://lore.kernel.org/r/20230405221648.17950-6-quic_alokad@quicinc.com ----- -- drivers/net/wireless/ath/ath11k/mac.c | 41 ++++++++++++++++----------- -- 1 file changed, 24 insertions(+), 17 deletions(-) -- ----- a/drivers/net/wireless/ath/ath11k/mac.c --+++ b/drivers/net/wireless/ath/ath11k/mac.c --@@ -1351,28 +1351,14 @@ err_mon_del: -- return ret; -- } -- ---static int ath11k_mac_setup_bcn_tmpl(struct ath11k_vif *arvif) --+static void ath11k_mac_set_vif_params(struct ath11k_vif *arvif, --+ struct sk_buff *bcn) -- { --- struct ath11k *ar = arvif->ar; --- struct ath11k_base *ab = ar->ab; --- struct ieee80211_hw *hw = ar->hw; --- struct ieee80211_vif *vif = arvif->vif; --- struct ieee80211_mutable_offsets offs = {}; --- struct sk_buff *bcn; -- struct ieee80211_mgmt *mgmt; -- u8 *ies; --- int ret; --- --- if (arvif->vdev_type != WMI_VDEV_TYPE_AP) --- return 0; --- --- bcn = ieee80211_beacon_get_template(hw, vif, &offs, 0); --- if (!bcn) { --- ath11k_warn(ab, "failed to get beacon template from mac80211\n"); --- return -EPERM; --- } -- -- ies = bcn->data + ieee80211_get_hdrlen_from_skb(bcn); --+ mgmt = (struct ieee80211_mgmt *)bcn->data; -- ies += sizeof(mgmt->u.beacon); -- -- if (cfg80211_find_ie(WLAN_EID_RSN, ies, (skb_tail_pointer(bcn) - ies))) --@@ -1386,7 +1372,28 @@ static int ath11k_mac_setup_bcn_tmpl(str -- arvif->wpaie_present = true; -- else -- arvif->wpaie_present = false; --+} --+ --+static int ath11k_mac_setup_bcn_tmpl(struct ath11k_vif *arvif) --+{ --+ struct ath11k *ar = arvif->ar; --+ struct ath11k_base *ab = ar->ab; --+ struct ieee80211_hw *hw = ar->hw; --+ struct ieee80211_vif *vif = arvif->vif; --+ struct ieee80211_mutable_offsets offs = {}; --+ struct sk_buff *bcn; --+ int ret; --+ --+ if (arvif->vdev_type != WMI_VDEV_TYPE_AP) --+ return 0; --+ --+ bcn = ieee80211_beacon_get_template(hw, vif, &offs, 0); --+ if (!bcn) { --+ ath11k_warn(ab, "failed to get beacon template from mac80211\n"); --+ return -EPERM; --+ } -- --+ ath11k_mac_set_vif_params(arvif, bcn); -- ret = ath11k_wmi_bcn_tmpl(ar, arvif->vdev_id, &offs, bcn); -- -- kfree_skb(bcn); -diff --git a/package/kernel/mac80211/patches/ath11k/0076-wifi-ath11k-MBSSID-beacon-support.patch b/package/kernel/mac80211/patches/ath11k/0076-wifi-ath11k-MBSSID-beacon-support.patch -deleted file mode 100644 -index d23ea8deea..0000000000 ---- a/package/kernel/mac80211/patches/ath11k/0076-wifi-ath11k-MBSSID-beacon-support.patch -+++ /dev/null -@@ -1,190 +0,0 @@ --From 335a92765d308dfe22826f5562cd4b4389b45e71 Mon Sep 17 00:00:00 2001 --From: Aloka Dixit --Date: Fri, 5 May 2023 16:11:28 +0300 --Subject: [PATCH 76/77] wifi: ath11k: MBSSID beacon support -- --- Split ath11k_mac_setup_bcn_tmpl() to move the beacon retrieval and -- WMI command to a new function, ath11k_mac_setup_bcn_tmpl_legacy(). -- In the original function add checks to use the transmitting interface -- when MBSSID is enabled. --- Set rsnie_present and wpaie_present fields for the non-transmitting -- interfaces when MBSSID is enabled. -- --Tested-on: IPQ8074 hw2.0 AHB WLAN.HK.2.7.0.1-01744-QCAHKSWPL_SILICONZ-1 -- --Signed-off-by: Aloka Dixit --Co-developed-by: John Crispin --Signed-off-by: John Crispin --Signed-off-by: Kalle Valo --Link: https://lore.kernel.org/r/20230405221648.17950-7-quic_alokad@quicinc.com ----- -- drivers/net/wireless/ath/ath11k/mac.c | 116 ++++++++++++++++++++++++-- -- drivers/net/wireless/ath/ath11k/wmi.c | 1 + -- 2 files changed, 112 insertions(+), 5 deletions(-) -- ----- a/drivers/net/wireless/ath/ath11k/mac.c --+++ b/drivers/net/wireless/ath/ath11k/mac.c --@@ -1351,6 +1351,84 @@ err_mon_del: -- return ret; -- } -- --+static void ath11k_mac_setup_nontx_vif_rsnie(struct ath11k_vif *arvif, --+ bool tx_arvif_rsnie_present, --+ const u8 *profile, u8 profile_len) --+{ --+ if (cfg80211_find_ie(WLAN_EID_RSN, profile, profile_len)) { --+ arvif->rsnie_present = true; --+ } else if (tx_arvif_rsnie_present) { --+ int i; --+ u8 nie_len; --+ const u8 *nie = cfg80211_find_ext_ie(WLAN_EID_EXT_NON_INHERITANCE, --+ profile, profile_len); --+ if (!nie) --+ return; --+ --+ nie_len = nie[1]; --+ nie += 2; --+ for (i = 0; i < nie_len; i++) { --+ if (nie[i] == WLAN_EID_RSN) { --+ arvif->rsnie_present = false; --+ break; --+ } --+ } --+ } --+} --+ --+static bool ath11k_mac_set_nontx_vif_params(struct ath11k_vif *tx_arvif, --+ struct ath11k_vif *arvif, --+ struct sk_buff *bcn) --+{ --+ struct ieee80211_mgmt *mgmt; --+ const u8 *ies, *profile, *next_profile; --+ int ies_len; --+ --+ ies = bcn->data + ieee80211_get_hdrlen_from_skb(bcn); --+ mgmt = (struct ieee80211_mgmt *)bcn->data; --+ ies += sizeof(mgmt->u.beacon); --+ ies_len = skb_tail_pointer(bcn) - ies; --+ --+ ies = cfg80211_find_ie(WLAN_EID_MULTIPLE_BSSID, ies, ies_len); --+ arvif->rsnie_present = tx_arvif->rsnie_present; --+ --+ while (ies) { --+ u8 mbssid_len; --+ --+ ies_len -= (2 + ies[1]); --+ mbssid_len = ies[1] - 1; --+ profile = &ies[3]; --+ --+ while (mbssid_len) { --+ u8 profile_len; --+ --+ profile_len = profile[1]; --+ next_profile = profile + (2 + profile_len); --+ mbssid_len -= (2 + profile_len); --+ --+ profile += 2; --+ profile_len -= (2 + profile[1]); --+ profile += (2 + profile[1]); /* nontx capabilities */ --+ profile_len -= (2 + profile[1]); --+ profile += (2 + profile[1]); /* SSID */ --+ if (profile[2] == arvif->vif->bss_conf.bssid_index) { --+ profile_len -= 5; --+ profile = profile + 5; --+ ath11k_mac_setup_nontx_vif_rsnie(arvif, --+ tx_arvif->rsnie_present, --+ profile, --+ profile_len); --+ return true; --+ } --+ profile = next_profile; --+ } --+ ies = cfg80211_find_ie(WLAN_EID_MULTIPLE_BSSID, profile, --+ ies_len); --+ } --+ --+ return false; --+} --+ -- static void ath11k_mac_set_vif_params(struct ath11k_vif *arvif, -- struct sk_buff *bcn) -- { --@@ -1374,18 +1452,26 @@ static void ath11k_mac_set_vif_params(st -- arvif->wpaie_present = false; -- } -- ---static int ath11k_mac_setup_bcn_tmpl(struct ath11k_vif *arvif) --+static int ath11k_mac_setup_bcn_tmpl_mbssid(struct ath11k_vif *arvif) -- { -- struct ath11k *ar = arvif->ar; -- struct ath11k_base *ab = ar->ab; --+ struct ath11k_vif *tx_arvif = arvif; -- struct ieee80211_hw *hw = ar->hw; -- struct ieee80211_vif *vif = arvif->vif; -- struct ieee80211_mutable_offsets offs = {}; -- struct sk_buff *bcn; -- int ret; -- --- if (arvif->vdev_type != WMI_VDEV_TYPE_AP) --- return 0; --+ if (arvif->vif->mbssid_tx_vif) { --+ tx_arvif = (void *)arvif->vif->mbssid_tx_vif->drv_priv; --+ if (tx_arvif != arvif) { --+ ar = tx_arvif->ar; --+ ab = ar->ab; --+ hw = ar->hw; --+ vif = tx_arvif->vif; --+ } --+ } -- -- bcn = ieee80211_beacon_get_template(hw, vif, &offs, 0); -- if (!bcn) { --@@ -1393,9 +1479,12 @@ static int ath11k_mac_setup_bcn_tmpl(str -- return -EPERM; -- } -- --- ath11k_mac_set_vif_params(arvif, bcn); --- ret = ath11k_wmi_bcn_tmpl(ar, arvif->vdev_id, &offs, bcn); --+ if (tx_arvif == arvif) --+ ath11k_mac_set_vif_params(tx_arvif, bcn); --+ else if (!ath11k_mac_set_nontx_vif_params(tx_arvif, arvif, bcn)) --+ return -EINVAL; -- --+ ret = ath11k_wmi_bcn_tmpl(ar, arvif->vdev_id, &offs, bcn); -- kfree_skb(bcn); -- -- if (ret) --@@ -1405,6 +1494,23 @@ static int ath11k_mac_setup_bcn_tmpl(str -- return ret; -- } -- --+static int ath11k_mac_setup_bcn_tmpl(struct ath11k_vif *arvif) --+{ --+ struct ieee80211_vif *vif = arvif->vif; --+ --+ if (arvif->vdev_type != WMI_VDEV_TYPE_AP) --+ return 0; --+ --+ /* Target does not expect beacon templates for the already up --+ * non-transmitting interfaces, and results in a crash if sent. --+ */ --+ if (vif->mbssid_tx_vif && --+ arvif != (void *)vif->mbssid_tx_vif->drv_priv && arvif->is_up) --+ return 0; --+ --+ return ath11k_mac_setup_bcn_tmpl_mbssid(arvif); --+} --+ -- void ath11k_mac_bcn_tx_event(struct ath11k_vif *arvif) -- { -- struct ieee80211_vif *vif = arvif->vif; ----- a/drivers/net/wireless/ath/ath11k/wmi.c --+++ b/drivers/net/wireless/ath/ath11k/wmi.c --@@ -1737,6 +1737,7 @@ int ath11k_wmi_bcn_tmpl(struct ath11k *a -- } -- -- cmd->buf_len = bcn->len; --+ cmd->mbssid_ie_offset = offs->mbssid_off; -- -- ptr = skb->data + sizeof(*cmd); -- -diff --git a/package/kernel/mac80211/patches/ath11k/0077-wifi-ath11k-EMA-beacon-support.patch b/package/kernel/mac80211/patches/ath11k/0077-wifi-ath11k-EMA-beacon-support.patch -deleted file mode 100644 -index 51353fa3e4..0000000000 ---- a/package/kernel/mac80211/patches/ath11k/0077-wifi-ath11k-EMA-beacon-support.patch -+++ /dev/null -@@ -1,156 +0,0 @@ --From 87bd401138161008fdb82fbca6e213af117bfeb9 Mon Sep 17 00:00:00 2001 --From: Aloka Dixit --Date: Fri, 5 May 2023 16:11:28 +0300 --Subject: [PATCH 77/77] wifi: ath11k: EMA beacon support -- --Add new function ath11k_mac_setup_bcn_tmpl_ema() which invokes the new --API provided by MAC80211 to retrieve EMA beacons. -- --Tested-on: IPQ8074 hw2.0 AHB WLAN.HK.2.7.0.1-01744-QCAHKSWPL_SILICONZ-1 -- --Signed-off-by: Aloka Dixit --Co-developed-by: John Crispin --Signed-off-by: John Crispin --Signed-off-by: Kalle Valo --Link: https://lore.kernel.org/r/20230405221648.17950-8-quic_alokad@quicinc.com ----- -- drivers/net/wireless/ath/ath11k/mac.c | 59 ++++++++++++++++++++++++++- -- drivers/net/wireless/ath/ath11k/wmi.c | 3 +- -- drivers/net/wireless/ath/ath11k/wmi.h | 11 ++++- -- 3 files changed, 70 insertions(+), 3 deletions(-) -- ----- a/drivers/net/wireless/ath/ath11k/mac.c --+++ b/drivers/net/wireless/ath/ath11k/mac.c --@@ -1452,6 +1452,60 @@ static void ath11k_mac_set_vif_params(st -- arvif->wpaie_present = false; -- } -- --+static int ath11k_mac_setup_bcn_tmpl_ema(struct ath11k_vif *arvif) --+{ --+ struct ath11k_vif *tx_arvif; --+ struct ieee80211_ema_beacons *beacons; --+ int ret = 0; --+ bool nontx_vif_params_set = false; --+ u32 params = 0; --+ u8 i = 0; --+ --+ tx_arvif = (void *)arvif->vif->mbssid_tx_vif->drv_priv; --+ --+ beacons = ieee80211_beacon_get_template_ema_list(tx_arvif->ar->hw, --+ tx_arvif->vif, 0); --+ if (!beacons || !beacons->cnt) { --+ ath11k_warn(arvif->ar->ab, --+ "failed to get ema beacon templates from mac80211\n"); --+ return -EPERM; --+ } --+ --+ if (tx_arvif == arvif) --+ ath11k_mac_set_vif_params(tx_arvif, beacons->bcn[0].skb); --+ else --+ arvif->wpaie_present = tx_arvif->wpaie_present; --+ --+ for (i = 0; i < beacons->cnt; i++) { --+ if (tx_arvif != arvif && !nontx_vif_params_set) --+ nontx_vif_params_set = --+ ath11k_mac_set_nontx_vif_params(tx_arvif, arvif, --+ beacons->bcn[i].skb); --+ --+ params = beacons->cnt; --+ params |= (i << WMI_EMA_TMPL_IDX_SHIFT); --+ params |= ((!i ? 1 : 0) << WMI_EMA_FIRST_TMPL_SHIFT); --+ params |= ((i + 1 == beacons->cnt ? 1 : 0) << WMI_EMA_LAST_TMPL_SHIFT); --+ --+ ret = ath11k_wmi_bcn_tmpl(tx_arvif->ar, tx_arvif->vdev_id, --+ &beacons->bcn[i].offs, --+ beacons->bcn[i].skb, params); --+ if (ret) { --+ ath11k_warn(tx_arvif->ar->ab, --+ "failed to set ema beacon template id %i error %d\n", --+ i, ret); --+ break; --+ } --+ } --+ --+ ieee80211_beacon_free_ema_list(beacons); --+ --+ if (tx_arvif != arvif && !nontx_vif_params_set) --+ return -EINVAL; /* Profile not found in the beacons */ --+ --+ return ret; --+} --+ -- static int ath11k_mac_setup_bcn_tmpl_mbssid(struct ath11k_vif *arvif) -- { -- struct ath11k *ar = arvif->ar; --@@ -1484,7 +1538,7 @@ static int ath11k_mac_setup_bcn_tmpl_mbs -- else if (!ath11k_mac_set_nontx_vif_params(tx_arvif, arvif, bcn)) -- return -EINVAL; -- --- ret = ath11k_wmi_bcn_tmpl(ar, arvif->vdev_id, &offs, bcn); --+ ret = ath11k_wmi_bcn_tmpl(ar, arvif->vdev_id, &offs, bcn, 0); -- kfree_skb(bcn); -- -- if (ret) --@@ -1508,6 +1562,9 @@ static int ath11k_mac_setup_bcn_tmpl(str -- arvif != (void *)vif->mbssid_tx_vif->drv_priv && arvif->is_up) -- return 0; -- --+ if (vif->bss_conf.ema_ap && vif->mbssid_tx_vif) --+ return ath11k_mac_setup_bcn_tmpl_ema(arvif); --+ -- return ath11k_mac_setup_bcn_tmpl_mbssid(arvif); -- } -- ----- a/drivers/net/wireless/ath/ath11k/wmi.c --+++ b/drivers/net/wireless/ath/ath11k/wmi.c --@@ -1699,7 +1699,7 @@ int ath11k_wmi_send_bcn_offload_control_ -- -- int ath11k_wmi_bcn_tmpl(struct ath11k *ar, u32 vdev_id, -- struct ieee80211_mutable_offsets *offs, --- struct sk_buff *bcn) --+ struct sk_buff *bcn, u32 ema_params) -- { -- struct ath11k_pdev_wmi *wmi = ar->wmi; -- struct wmi_bcn_tmpl_cmd *cmd; --@@ -1738,6 +1738,7 @@ int ath11k_wmi_bcn_tmpl(struct ath11k *a -- -- cmd->buf_len = bcn->len; -- cmd->mbssid_ie_offset = offs->mbssid_off; --+ cmd->ema_params = ema_params; -- -- ptr = skb->data + sizeof(*cmd); -- ----- a/drivers/net/wireless/ath/ath11k/wmi.h --+++ b/drivers/net/wireless/ath/ath11k/wmi.h --@@ -3566,6 +3566,10 @@ struct wmi_get_pdev_temperature_cmd { -- -- #define WMI_BEACON_TX_BUFFER_SIZE 512 -- --+#define WMI_EMA_TMPL_IDX_SHIFT 8 --+#define WMI_EMA_FIRST_TMPL_SHIFT 16 --+#define WMI_EMA_LAST_TMPL_SHIFT 24 --+ -- struct wmi_bcn_tmpl_cmd { -- u32 tlv_header; -- u32 vdev_id; --@@ -3576,6 +3580,11 @@ struct wmi_bcn_tmpl_cmd { -- u32 csa_event_bitmap; -- u32 mbssid_ie_offset; -- u32 esp_ie_offset; --+ u32 csc_switch_count_offset; --+ u32 csc_event_bitmap; --+ u32 mu_edca_ie_offset; --+ u32 feature_enable_bitmap; --+ u32 ema_params; -- } __packed; -- -- struct wmi_key_seq_counter { --@@ -6298,7 +6307,7 @@ int ath11k_wmi_mgmt_send(struct ath11k * -- struct sk_buff *frame); -- int ath11k_wmi_bcn_tmpl(struct ath11k *ar, u32 vdev_id, -- struct ieee80211_mutable_offsets *offs, --- struct sk_buff *bcn); --+ struct sk_buff *bcn, u32 ema_param); -- int ath11k_wmi_vdev_down(struct ath11k *ar, u8 vdev_id); -- int ath11k_wmi_vdev_up(struct ath11k *ar, u32 vdev_id, u32 aid, -- const u8 *bssid, u8 *tx_bssid, u32 nontx_profile_idx, -diff --git a/package/kernel/mac80211/patches/ath11k/0078-wifi-ath11k-Relocate-the-func-ath11k_mac_bitrate_mas.patch b/package/kernel/mac80211/patches/ath11k/0078-wifi-ath11k-Relocate-the-func-ath11k_mac_bitrate_mas.patch -deleted file mode 100644 -index 610bf72514..0000000000 ---- a/package/kernel/mac80211/patches/ath11k/0078-wifi-ath11k-Relocate-the-func-ath11k_mac_bitrate_mas.patch -+++ /dev/null -@@ -1,75 +0,0 @@ --From 570eec3d40505c30babbe3b8f85a38496c975ab2 Mon Sep 17 00:00:00 2001 --From: Maharaja Kennadyrajan --Date: Tue, 9 May 2023 20:07:23 +0300 --Subject: [PATCH] wifi: ath11k: Relocate the func -- ath11k_mac_bitrate_mask_num_ht_rates() and change hweight16 to hweight8 -- --Relocate the function ath11k_mac_bitrate_mask_num_ht_rates() definition --to call this function from other functions which helps to avoid the --compilation error (function not defined). -- --ht_mcs[] is 1 byte array and it is enough to use hweight8() instead --of hweight16(). Hence, fixed the same. -- --Tested on: Compile tested only. -- --Signed-off-by: Maharaja Kennadyrajan --Signed-off-by: Kalle Valo --Link: https://lore.kernel.org/r/20230504092033.3542456-2-quic_mkenna@quicinc.com ----- -- drivers/net/wireless/ath/ath11k/mac.c | 30 +++++++++++++-------------- -- 1 file changed, 15 insertions(+), 15 deletions(-) -- ----- a/drivers/net/wireless/ath/ath11k/mac.c --+++ b/drivers/net/wireless/ath/ath11k/mac.c --@@ -1,7 +1,7 @@ -- // SPDX-License-Identifier: BSD-3-Clause-Clear -- /* -- * Copyright (c) 2018-2019 The Linux Foundation. All rights reserved. --- * Copyright (c) 2021-2022 Qualcomm Innovation Center, Inc. All rights reserved. --+ * Copyright (c) 2021-2023 Qualcomm Innovation Center, Inc. All rights reserved. -- */ -- -- #include --@@ -4338,6 +4338,20 @@ exit: -- } -- -- static int --+ath11k_mac_bitrate_mask_num_ht_rates(struct ath11k *ar, --+ enum nl80211_band band, --+ const struct cfg80211_bitrate_mask *mask) --+{ --+ int num_rates = 0; --+ int i; --+ --+ for (i = 0; i < ARRAY_SIZE(mask->control[band].ht_mcs); i++) --+ num_rates += hweight8(mask->control[band].ht_mcs[i]); --+ --+ return num_rates; --+} --+ --+static int -- ath11k_mac_bitrate_mask_num_vht_rates(struct ath11k *ar, -- enum nl80211_band band, -- const struct cfg80211_bitrate_mask *mask) --@@ -7791,20 +7805,6 @@ static void ath11k_mac_op_flush(struct i -- ath11k_mac_flush_tx_complete(ar); -- } -- ---static int ---ath11k_mac_bitrate_mask_num_ht_rates(struct ath11k *ar, --- enum nl80211_band band, --- const struct cfg80211_bitrate_mask *mask) ---{ --- int num_rates = 0; --- int i; --- --- for (i = 0; i < ARRAY_SIZE(mask->control[band].ht_mcs); i++) --- num_rates += hweight16(mask->control[band].ht_mcs[i]); --- --- return num_rates; ---} --- -- static bool -- ath11k_mac_has_single_legacy_rate(struct ath11k *ar, -- enum nl80211_band band, -diff --git a/package/kernel/mac80211/patches/ath11k/0079-wifi-ath11k-Send-HT-fixed-rate-in-WMI-peer-fixed-par.patch b/package/kernel/mac80211/patches/ath11k/0079-wifi-ath11k-Send-HT-fixed-rate-in-WMI-peer-fixed-par.patch -deleted file mode 100644 -index 6282f4462e..0000000000 ---- a/package/kernel/mac80211/patches/ath11k/0079-wifi-ath11k-Send-HT-fixed-rate-in-WMI-peer-fixed-par.patch -+++ /dev/null -@@ -1,141 +0,0 @@ --From df8e3729ffc0aa645839693f74ee7b6d999cdf64 Mon Sep 17 00:00:00 2001 --From: Maharaja Kennadyrajan --Date: Tue, 9 May 2023 20:07:24 +0300 --Subject: [PATCH] wifi: ath11k: Send HT fixed rate in WMI peer fixed param -- --Due to the firmware behavior with HT fixed rate setting, --HT fixed rate MCS with NSS > 1 are treated as NSS = 1 --HT rates in the firmware and enables the HT fixed rate of --NSS = 1. -- --This leads to HT fixed rate is always configured for NSS = 1 --even though the user sets NSS = 2 or > 1 HT fixed MCS in the --set bitrate command. -- --Currently HT fixed MCS is sent via WMI peer assoc command. --Fix this issue, by sending the HT fixed rate MCS in WMI peer --fixed param instead of sending in peer assoc command. -- --Tested-on: QCN9074 hw1.0 PCI WLAN.HK.2.7.0.1-01744-QCAHKSWPL_SILICONZ-1 -- --Signed-off-by: Maharaja Kennadyrajan --Signed-off-by: Kalle Valo --Link: https://lore.kernel.org/r/20230504092033.3542456-3-quic_mkenna@quicinc.com ----- -- drivers/net/wireless/ath/ath11k/mac.c | 63 ++++++++++++++++++++++++++- -- 1 file changed, 61 insertions(+), 2 deletions(-) -- ----- a/drivers/net/wireless/ath/ath11k/mac.c --+++ b/drivers/net/wireless/ath/ath11k/mac.c --@@ -4480,6 +4480,54 @@ ath11k_mac_set_peer_he_fixed_rate(struct -- return ret; -- } -- --+static int --+ath11k_mac_set_peer_ht_fixed_rate(struct ath11k_vif *arvif, --+ struct ieee80211_sta *sta, --+ const struct cfg80211_bitrate_mask *mask, --+ enum nl80211_band band) --+{ --+ struct ath11k *ar = arvif->ar; --+ u8 ht_rate, nss = 0; --+ u32 rate_code; --+ int ret, i; --+ --+ lockdep_assert_held(&ar->conf_mutex); --+ --+ for (i = 0; i < ARRAY_SIZE(mask->control[band].ht_mcs); i++) { --+ if (hweight8(mask->control[band].ht_mcs[i]) == 1) { --+ nss = i + 1; --+ ht_rate = ffs(mask->control[band].ht_mcs[i]) - 1; --+ } --+ } --+ --+ if (!nss) { --+ ath11k_warn(ar->ab, "No single HT Fixed rate found to set for %pM", --+ sta->addr); --+ return -EINVAL; --+ } --+ --+ /* Avoid updating invalid nss as fixed rate*/ --+ if (nss > sta->deflink.rx_nss) --+ return -EINVAL; --+ --+ ath11k_dbg(ar->ab, ATH11K_DBG_MAC, --+ "Setting Fixed HT Rate for peer %pM. Device will not switch to any other selected rates", --+ sta->addr); --+ --+ rate_code = ATH11K_HW_RATE_CODE(ht_rate, nss - 1, --+ WMI_RATE_PREAMBLE_HT); --+ ret = ath11k_wmi_set_peer_param(ar, sta->addr, --+ arvif->vdev_id, --+ WMI_PEER_PARAM_FIXED_RATE, --+ rate_code); --+ if (ret) --+ ath11k_warn(ar->ab, --+ "failed to update STA %pM HT Fixed Rate %d: %d\n", --+ sta->addr, rate_code, ret); --+ --+ return ret; --+} --+ -- static int ath11k_station_assoc(struct ath11k *ar, -- struct ieee80211_vif *vif, -- struct ieee80211_sta *sta, --@@ -4491,7 +4539,7 @@ static int ath11k_station_assoc(struct a -- struct cfg80211_chan_def def; -- enum nl80211_band band; -- struct cfg80211_bitrate_mask *mask; --- u8 num_vht_rates, num_he_rates; --+ u8 num_ht_rates, num_vht_rates, num_he_rates; -- -- lockdep_assert_held(&ar->conf_mutex); -- --@@ -4519,6 +4567,7 @@ static int ath11k_station_assoc(struct a -- -- num_vht_rates = ath11k_mac_bitrate_mask_num_vht_rates(ar, band, mask); -- num_he_rates = ath11k_mac_bitrate_mask_num_he_rates(ar, band, mask); --+ num_ht_rates = ath11k_mac_bitrate_mask_num_ht_rates(ar, band, mask); -- -- /* If single VHT/HE rate is configured (by set_bitrate_mask()), -- * peer_assoc will disable VHT/HE. This is now enabled by a peer specific --@@ -4535,6 +4584,11 @@ static int ath11k_station_assoc(struct a -- band); -- if (ret) -- return ret; --+ } else if (sta->deflink.ht_cap.ht_supported && num_ht_rates == 1) { --+ ret = ath11k_mac_set_peer_ht_fixed_rate(arvif, sta, mask, --+ band); --+ if (ret) --+ return ret; -- } -- -- /* Re-assoc is run only to update supported rates for given station. It --@@ -4608,7 +4662,7 @@ static void ath11k_sta_rc_update_wk(stru -- const u16 *vht_mcs_mask; -- const u16 *he_mcs_mask; -- u32 changed, bw, nss, smps, bw_prev; --- int err, num_vht_rates, num_he_rates; --+ int err, num_ht_rates, num_vht_rates, num_he_rates; -- const struct cfg80211_bitrate_mask *mask; -- struct peer_assoc_params peer_arg; -- enum wmi_phy_mode peer_phymode; --@@ -4724,6 +4778,8 @@ static void ath11k_sta_rc_update_wk(stru -- -- if (changed & IEEE80211_RC_SUPP_RATES_CHANGED) { -- mask = &arvif->bitrate_mask; --+ num_ht_rates = ath11k_mac_bitrate_mask_num_ht_rates(ar, band, --+ mask); -- num_vht_rates = ath11k_mac_bitrate_mask_num_vht_rates(ar, band, -- mask); -- num_he_rates = ath11k_mac_bitrate_mask_num_he_rates(ar, band, --@@ -4746,6 +4802,9 @@ static void ath11k_sta_rc_update_wk(stru -- } else if (sta->deflink.he_cap.has_he && num_he_rates == 1) { -- ath11k_mac_set_peer_he_fixed_rate(arvif, sta, mask, -- band); --+ } else if (sta->deflink.ht_cap.ht_supported && num_ht_rates == 1) { --+ ath11k_mac_set_peer_ht_fixed_rate(arvif, sta, mask, --+ band); -- } else { -- /* If the peer is non-VHT/HE or no fixed VHT/HE rate -- * is provided in the new bitrate mask we set the -diff --git a/package/kernel/mac80211/patches/ath11k/0080-wifi-ath11k-add-support-default-regdb-while-searchin.patch b/package/kernel/mac80211/patches/ath11k/0080-wifi-ath11k-add-support-default-regdb-while-searchin.patch -deleted file mode 100644 -index 5ff40aac7a..0000000000 ---- a/package/kernel/mac80211/patches/ath11k/0080-wifi-ath11k-add-support-default-regdb-while-searchin.patch -+++ /dev/null -@@ -1,127 +0,0 @@ --From 88ca89202f8e8afb5225eb5244d79cd67c15d744 Mon Sep 17 00:00:00 2001 --From: Wen Gong --Date: Fri, 26 May 2023 12:41:06 +0300 --Subject: [PATCH] wifi: ath11k: add support default regdb while searching -- board-2.bin for WCN6855 -- --Sometimes board-2.bin does not have the regdb data which matched the --parameters such as vendor, device, subsystem-vendor, subsystem-device --and etc. Add default regdb data with 'bus=%s' into board-2.bin for --WCN6855, then ath11k use 'bus=pci' to search regdb data in board-2.bin --for WCN6855. -- --kernel: [ 122.515808] ath11k_pci 0000:03:00.0: boot using board name 'bus=pci,vendor=17cb,device=1103,subsystem-vendor=17cb,subsystem-device=3374,qmi-chip-id=2,qmi-board-id=262' --kernel: [ 122.517240] ath11k_pci 0000:03:00.0: boot firmware request ath11k/WCN6855/hw2.0/board-2.bin size 6179564 --kernel: [ 122.517280] ath11k_pci 0000:03:00.0: failed to fetch regdb data for bus=pci,vendor=17cb,device=1103,subsystem-vendor=17cb,subsystem-device=3374,qmi-chip-id=2,qmi-board-id=262 from ath11k/WCN6855/hw2.0/board-2.bin --kernel: [ 122.517464] ath11k_pci 0000:03:00.0: boot using board name 'bus=pci' --kernel: [ 122.518901] ath11k_pci 0000:03:00.0: boot firmware request ath11k/WCN6855/hw2.0/board-2.bin size 6179564 --kernel: [ 122.518915] ath11k_pci 0000:03:00.0: board name --kernel: [ 122.518917] ath11k_pci 0000:03:00.0: 00000000: 62 75 73 3d 70 63 69 bus=pci --kernel: [ 122.518918] ath11k_pci 0000:03:00.0: boot found match regdb data for name 'bus=pci' --kernel: [ 122.518920] ath11k_pci 0000:03:00.0: boot found regdb data for 'bus=pci' --kernel: [ 122.518921] ath11k_pci 0000:03:00.0: fetched regdb -- --Tested-on: WCN6855 hw2.0 PCI WLAN.HSP.1.1-03125-QCAHSPSWPL_V1_V2_SILICONZ_LITE-3 -- --Signed-off-by: Wen Gong --Signed-off-by: Kalle Valo --Link: https://lore.kernel.org/r/20230517133959.8224-1-quic_wgong@quicinc.com ----- -- drivers/net/wireless/ath/ath11k/core.c | 53 +++++++++++++++++++------- -- 1 file changed, 40 insertions(+), 13 deletions(-) -- ----- a/drivers/net/wireless/ath/ath11k/core.c --+++ b/drivers/net/wireless/ath/ath11k/core.c --@@ -961,7 +961,8 @@ int ath11k_core_check_dt(struct ath11k_b -- } -- -- static int __ath11k_core_create_board_name(struct ath11k_base *ab, char *name, --- size_t name_len, bool with_variant) --+ size_t name_len, bool with_variant, --+ bool bus_type_mode) -- { -- /* strlen(',variant=') + strlen(ab->qmi.target.bdf_ext) */ -- char variant[9 + ATH11K_QMI_BDF_EXT_STR_LENGTH] = { 0 }; --@@ -972,15 +973,20 @@ static int __ath11k_core_create_board_na -- -- switch (ab->id.bdf_search) { -- case ATH11K_BDF_SEARCH_BUS_AND_BOARD: --- 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); --+ if (bus_type_mode) --+ scnprintf(name, name_len, --+ "bus=%s", --+ ath11k_bus_str(ab->hif.bus)); --+ else --+ 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; -- default: -- scnprintf(name, name_len, --@@ -999,13 +1005,19 @@ static int __ath11k_core_create_board_na -- static int ath11k_core_create_board_name(struct ath11k_base *ab, char *name, -- size_t name_len) -- { --- return __ath11k_core_create_board_name(ab, name, name_len, true); --+ return __ath11k_core_create_board_name(ab, name, name_len, true, false); -- } -- -- 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); --+ return __ath11k_core_create_board_name(ab, name, name_len, false, false); --+} --+ --+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, true); -- } -- -- const struct firmware *ath11k_core_firmware_request(struct ath11k_base *ab, --@@ -1309,7 +1321,7 @@ success: -- -- int ath11k_core_fetch_regdb(struct ath11k_base *ab, struct ath11k_board_data *bd) -- { --- char boardname[BOARD_NAME_SIZE]; --+ char boardname[BOARD_NAME_SIZE], default_boardname[BOARD_NAME_SIZE]; -- int ret; -- -- ret = ath11k_core_create_board_name(ab, boardname, BOARD_NAME_SIZE); --@@ -1323,6 +1335,21 @@ int ath11k_core_fetch_regdb(struct ath11 -- ATH11K_BD_IE_REGDB, -- ATH11K_BD_IE_REGDB_NAME, -- ATH11K_BD_IE_REGDB_DATA); --+ if (!ret) --+ goto exit; --+ --+ ret = ath11k_core_create_bus_type_board_name(ab, default_boardname, --+ BOARD_NAME_SIZE); --+ if (ret) { --+ ath11k_dbg(ab, ATH11K_DBG_BOOT, --+ "failed to create default board name for regdb: %d", ret); --+ goto exit; --+ } --+ --+ ret = ath11k_core_fetch_board_data_api_n(ab, bd, default_boardname, --+ ATH11K_BD_IE_REGDB, --+ ATH11K_BD_IE_REGDB_NAME, --+ ATH11K_BD_IE_REGDB_DATA); -- if (!ret) -- goto exit; -- -diff --git a/package/kernel/mac80211/patches/ath11k/0081-wifi-ath11k-remove-unused-function-ath11k_tm_event_w.patch b/package/kernel/mac80211/patches/ath11k/0081-wifi-ath11k-remove-unused-function-ath11k_tm_event_w.patch -deleted file mode 100644 -index b5dc83f007..0000000000 ---- a/package/kernel/mac80211/patches/ath11k/0081-wifi-ath11k-remove-unused-function-ath11k_tm_event_w.patch -+++ /dev/null -@@ -1,128 +0,0 @@ --From 86f85575a3f6a20cef1c8bb98e78585fe3a53ccc Mon Sep 17 00:00:00 2001 --From: Govindaraj Saminathan --Date: Fri, 26 May 2023 12:41:06 +0300 --Subject: [PATCH 82/84] wifi: ath11k: remove unused function -- ath11k_tm_event_wmi() -- --The function ath11k_tm_event_wmi() is only defined and it is not used --anywhere. Hence remove the unused. -- --Tested-on: IPQ8074 hw2.0 AHB WLAN.HK.2.7.0.1-01744-QCAHKSWPL_SILICONZ-1 -- --Signed-off-by: Govindaraj Saminathan --Signed-off-by: Raj Kumar Bhagat --Signed-off-by: Kalle Valo --Link: https://lore.kernel.org/r/20230517135934.16408-2-quic_rajkbhag@quicinc.com ----- -- drivers/net/wireless/ath/ath11k/testmode.c | 64 +--------------------- -- drivers/net/wireless/ath/ath11k/testmode.h | 8 +-- -- 2 files changed, 2 insertions(+), 70 deletions(-) -- ----- a/drivers/net/wireless/ath/ath11k/testmode.c --+++ b/drivers/net/wireless/ath/ath11k/testmode.c --@@ -1,6 +1,7 @@ -- // SPDX-License-Identifier: BSD-3-Clause-Clear -- /* -- * Copyright (c) 2018-2019 The Linux Foundation. All rights reserved. --+ * Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights reserved. -- */ -- -- #include "testmode.h" --@@ -20,69 +21,6 @@ static const struct nla_policy ath11k_tm -- [ATH11K_TM_ATTR_VERSION_MINOR] = { .type = NLA_U32 }, -- }; -- ---/* Returns true if callee consumes the skb and the skb should be discarded. --- * Returns false if skb is not used. Does not sleep. --- */ ---bool ath11k_tm_event_wmi(struct ath11k *ar, u32 cmd_id, struct sk_buff *skb) ---{ --- struct sk_buff *nl_skb; --- bool consumed; --- int ret; --- --- ath11k_dbg(ar->ab, ATH11K_DBG_TESTMODE, --- "testmode event wmi cmd_id %d skb %pK skb->len %d\n", --- cmd_id, skb, skb->len); --- --- ath11k_dbg_dump(ar->ab, ATH11K_DBG_TESTMODE, NULL, "", skb->data, skb->len); --- --- spin_lock_bh(&ar->data_lock); --- --- consumed = true; --- --- nl_skb = cfg80211_testmode_alloc_event_skb(ar->hw->wiphy, --- 2 * sizeof(u32) + skb->len, --- GFP_ATOMIC); --- if (!nl_skb) { --- ath11k_warn(ar->ab, --- "failed to allocate skb for testmode wmi event\n"); --- goto out; --- } --- --- ret = nla_put_u32(nl_skb, ATH11K_TM_ATTR_CMD, ATH11K_TM_CMD_WMI); --- if (ret) { --- ath11k_warn(ar->ab, --- "failed to put testmode wmi event cmd attribute: %d\n", --- ret); --- kfree_skb(nl_skb); --- goto out; --- } --- --- ret = nla_put_u32(nl_skb, ATH11K_TM_ATTR_WMI_CMDID, cmd_id); --- if (ret) { --- ath11k_warn(ar->ab, --- "failed to put testmode wmi even cmd_id: %d\n", --- ret); --- kfree_skb(nl_skb); --- goto out; --- } --- --- ret = nla_put(nl_skb, ATH11K_TM_ATTR_DATA, skb->len, skb->data); --- if (ret) { --- ath11k_warn(ar->ab, --- "failed to copy skb to testmode wmi event: %d\n", --- ret); --- kfree_skb(nl_skb); --- goto out; --- } --- --- cfg80211_testmode_event(nl_skb, GFP_ATOMIC); --- ---out: --- spin_unlock_bh(&ar->data_lock); --- --- return consumed; ---} --- -- static int ath11k_tm_cmd_get_version(struct ath11k *ar, struct nlattr *tb[]) -- { -- struct sk_buff *skb; ----- a/drivers/net/wireless/ath/ath11k/testmode.h --+++ b/drivers/net/wireless/ath/ath11k/testmode.h --@@ -1,24 +1,18 @@ -- /* SPDX-License-Identifier: BSD-3-Clause-Clear */ -- /* -- * Copyright (c) 2018-2019 The Linux Foundation. All rights reserved. --+ * Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights reserved. -- */ -- -- #include "core.h" -- -- #ifdef CPTCFG_NL80211_TESTMODE -- ---bool ath11k_tm_event_wmi(struct ath11k *ar, u32 cmd_id, struct sk_buff *skb); -- int ath11k_tm_cmd(struct ieee80211_hw *hw, struct ieee80211_vif *vif, -- void *data, int len); -- -- #else -- ---static inline bool ath11k_tm_event_wmi(struct ath11k *ar, u32 cmd_id, --- struct sk_buff *skb) ---{ --- return false; ---} --- -- static inline int ath11k_tm_cmd(struct ieee80211_hw *hw, -- struct ieee80211_vif *vif, -- void *data, int len) -diff --git a/package/kernel/mac80211/patches/ath11k/0082-wifi-ath11k-factory-test-mode-support.patch b/package/kernel/mac80211/patches/ath11k/0082-wifi-ath11k-factory-test-mode-support.patch -deleted file mode 100644 -index f1b262724f..0000000000 ---- a/package/kernel/mac80211/patches/ath11k/0082-wifi-ath11k-factory-test-mode-support.patch -+++ /dev/null -@@ -1,850 +0,0 @@ --From b43310e44edc823a7f02af1e1e2b4e8a9abc7d91 Mon Sep 17 00:00:00 2001 --From: Govindaraj Saminathan --Date: Fri, 26 May 2023 12:41:07 +0300 --Subject: [PATCH 83/84] wifi: ath11k: factory test mode support -- --Add support to process factory test mode commands (FTM) for calibration. --By default firmware start with NORMAL mode and to process the FTM commands --firmware needs to be restarted in FTM mode using module parameter ftm_mode. --The pre-request is all the radios should be down before starting the test. -- --When start command ATH11K_TM_CMD_TESTMODE_START is received, ar->state --is set to Test Mode. If the FTM command or event length is greater --than 256 bytes, it will be broken down into multiple segments and --encoded with TLV header if it is segmented commands, else it is sent --to firmware as it is. -- --On receiving UTF event from firmware, if it is segmented event, the driver --will wait until it receives all the segments and notify the complete --data to user application. In case the segmented sequence are missed or --lost from the firmware, driver will skip the already received partial data. -- --In case of unsegmented UTF event from firmware, driver notifies the --data to the user application as it comes. Applications handles --the data further. -- --Command to boot in ftm mode: -- --insmod ath11k ftm_mode=1 -- --Tested-on: IPQ8074 hw2.0 AHB WLAN.HK.2.7.0.1-01744-QCAHKSWPL_SILICONZ-1 -- --Signed-off-by: Govindaraj Saminathan --Co-developed-by: Sowmiya Sree Elavalagan --Signed-off-by: Sowmiya Sree Elavalagan --Signed-off-by: Raj Kumar Bhagat --Signed-off-by: Kalle Valo --Link: https://lore.kernel.org/r/20230517135934.16408-4-quic_rajkbhag@quicinc.com ----- -- drivers/net/wireless/ath/ath11k/ahb.c | 3 +- -- drivers/net/wireless/ath/ath11k/core.c | 21 +- -- drivers/net/wireless/ath/ath11k/core.h | 16 +- -- drivers/net/wireless/ath/ath11k/debug.h | 1 + -- drivers/net/wireless/ath/ath11k/mac.c | 11 +- -- drivers/net/wireless/ath/ath11k/pci.c | 3 +- -- drivers/net/wireless/ath/ath11k/testmode.c | 350 ++++++++++++++++++- -- drivers/net/wireless/ath/ath11k/testmode.h | 6 + -- drivers/net/wireless/ath/ath11k/testmode_i.h | 18 +- -- drivers/net/wireless/ath/ath11k/wmi.c | 11 +- -- drivers/net/wireless/ath/ath11k/wmi.h | 22 ++ -- drivers/net/wireless/ath/ath11k/wow.c | 3 +- -- 12 files changed, 444 insertions(+), 21 deletions(-) -- ----- a/drivers/net/wireless/ath/ath11k/ahb.c --+++ b/drivers/net/wireless/ath/ath11k/ahb.c --@@ -1,7 +1,7 @@ -- // SPDX-License-Identifier: BSD-3-Clause-Clear -- /* -- * Copyright (c) 2018-2019 The Linux Foundation. All rights reserved. --- * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved. --+ * Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved. -- */ -- -- #include --@@ -1155,6 +1155,7 @@ static int ath11k_ahb_probe(struct platf -- ab->hif.ops = hif_ops; -- ab->pdev = pdev; -- ab->hw_rev = hw_rev; --+ ab->fw_mode = ATH11K_FIRMWARE_MODE_NORMAL; -- platform_set_drvdata(pdev, ab); -- -- ret = ath11k_pcic_register_pci_ops(ab, pci_ops); ----- a/drivers/net/wireless/ath/ath11k/core.c --+++ b/drivers/net/wireless/ath/ath11k/core.c --@@ -1,7 +1,7 @@ -- // SPDX-License-Identifier: BSD-3-Clause-Clear -- /* -- * Copyright (c) 2018-2019 The Linux Foundation. All rights reserved. --- * Copyright (c) 2021-2022 Qualcomm Innovation Center, Inc. All rights reserved. --+ * Copyright (c) 2021-2023 Qualcomm Innovation Center, Inc. All rights reserved. -- */ -- -- #include --@@ -32,6 +32,10 @@ module_param_named(frame_mode, ath11k_fr -- 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_hw_params ath11k_hw_params[] = { -- { -- .hw_rev = ATH11K_HW_IPQ8074, --@@ -1381,6 +1385,11 @@ static int ath11k_core_soc_create(struct -- { -- int ret; -- --+ if (ath11k_ftm_mode) { --+ ab->fw_mode = ATH11K_FIRMWARE_MODE_FTM; --+ ath11k_info(ab, "Booting in factory test mode\n"); --+ } --+ -- ret = ath11k_qmi_init_service(ab); -- if (ret) { -- ath11k_err(ab, "failed to initialize qmi :%d\n", ret); --@@ -1607,7 +1616,7 @@ int ath11k_core_qmi_firmware_ready(struc -- { -- int ret; -- --- ret = ath11k_core_start_firmware(ab, ATH11K_FIRMWARE_MODE_NORMAL); --+ ret = ath11k_core_start_firmware(ab, ab->fw_mode); -- if (ret) { -- ath11k_err(ab, "failed to start firmware: %d\n", ret); -- return ret; --@@ -1772,7 +1781,8 @@ void ath11k_core_pre_reconfigure_recover -- for (i = 0; i < ab->num_radios; i++) { -- pdev = &ab->pdevs[i]; -- ar = pdev->ar; --- if (!ar || ar->state == ATH11K_STATE_OFF) --+ if (!ar || ar->state == ATH11K_STATE_OFF || --+ ar->state == ATH11K_STATE_FTM) -- continue; -- -- ieee80211_stop_queues(ar->hw); --@@ -1841,7 +1851,12 @@ static void ath11k_core_post_reconfigure -- ath11k_warn(ab, -- "device is wedged, will not restart radio %d\n", i); -- break; --+ case ATH11K_STATE_FTM: --+ ath11k_dbg(ab, ATH11K_DBG_TESTMODE, --+ "fw mode reset done radio %d\n", i); --+ break; -- } --+ -- mutex_unlock(&ar->conf_mutex); -- } -- complete(&ab->driver_recovery); ----- a/drivers/net/wireless/ath/ath11k/core.h --+++ b/drivers/net/wireless/ath/ath11k/core.h --@@ -1,7 +1,7 @@ -- /* SPDX-License-Identifier: BSD-3-Clause-Clear */ -- /* -- * Copyright (c) 2018-2019 The Linux Foundation. All rights reserved. --- * Copyright (c) 2021-2022 Qualcomm Innovation Center, Inc. All rights reserved. --+ * Copyright (c) 2021-2023 Qualcomm Innovation Center, Inc. All rights reserved. -- */ -- -- #ifndef ATH11K_CORE_H --@@ -52,6 +52,7 @@ -- #define ATH11K_SMBIOS_BDF_EXT_MAGIC "BDF_" -- -- extern unsigned int ath11k_frame_mode; --+extern bool ath11k_ftm_mode; -- -- #define ATH11K_SCAN_TIMEOUT_HZ (20 * HZ) -- --@@ -277,6 +278,7 @@ enum ath11k_dev_flags { -- ATH11K_FLAG_FIXED_MEM_RGN, -- ATH11K_FLAG_DEVICE_INIT_DONE, -- ATH11K_FLAG_MULTI_MSI_VECTORS, --+ ATH11K_FLAG_FTM_SEGMENTED, -- }; -- -- enum ath11k_monitor_flags { --@@ -530,6 +532,7 @@ enum ath11k_state { -- ATH11K_STATE_RESTARTING, -- ATH11K_STATE_RESTARTED, -- ATH11K_STATE_WEDGED, --+ ATH11K_STATE_FTM, -- /* Add other states as required */ -- }; -- --@@ -709,6 +712,8 @@ struct ath11k { -- u32 last_ppdu_id; -- u32 cached_ppdu_id; -- int monitor_vdev_id; --+ struct completion fw_mode_reset; --+ u8 ftm_msgref; -- #ifdef CPTCFG_ATH11K_DEBUGFS -- struct ath11k_debug debug; -- #endif --@@ -838,6 +843,7 @@ struct ath11k_msi_config { -- /* Master structure to hold the hw data which may be used in core module */ -- struct ath11k_base { -- enum ath11k_hw_rev hw_rev; --+ enum ath11k_firmware_mode fw_mode; -- struct platform_device *pdev; -- struct device *dev; -- struct ath11k_qmi qmi; --@@ -978,6 +984,14 @@ struct ath11k_base { -- const struct ath11k_pci_ops *ops; -- } pci; -- --+#ifdef CPTCFG_NL80211_TESTMODE --+ struct { --+ u32 data_pos; --+ u32 expected_seq; --+ u8 *eventdata; --+ } testmode; --+#endif --+ -- /* must be last */ -- u8 drv_priv[] __aligned(sizeof(void *)); -- }; ----- a/drivers/net/wireless/ath/ath11k/debug.h --+++ b/drivers/net/wireless/ath/ath11k/debug.h --@@ -1,6 +1,7 @@ -- /* SPDX-License-Identifier: BSD-3-Clause-Clear */ -- /* -- * Copyright (c) 2018-2019 The Linux Foundation. All rights reserved. --+ * Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights reserved. -- */ -- -- #ifndef _ATH11K_DEBUG_H_ ----- a/drivers/net/wireless/ath/ath11k/mac.c --+++ b/drivers/net/wireless/ath/ath11k/mac.c --@@ -643,7 +643,10 @@ struct ath11k *ath11k_mac_get_ar_by_pdev -- return NULL; -- -- for (i = 0; i < ab->num_radios; i++) { --- pdev = rcu_dereference(ab->pdevs_active[i]); --+ if (ab->fw_mode == ATH11K_FIRMWARE_MODE_FTM) --+ pdev = &ab->pdevs[i]; --+ else --+ pdev = rcu_dereference(ab->pdevs_active[i]); -- -- if (pdev && pdev->pdev_id == pdev_id) -- return (pdev->ar ? pdev->ar : NULL); --@@ -6271,6 +6274,11 @@ static int ath11k_mac_op_start(struct ie -- struct ath11k_pdev *pdev = ar->pdev; -- int ret; -- --+ if (ath11k_ftm_mode) { --+ ath11k_warn(ab, "mac operations not supported in factory test mode\n"); --+ return -EOPNOTSUPP; --+ } --+ -- ath11k_mac_drain_tx(ar); -- mutex_lock(&ar->conf_mutex); -- --@@ -6285,6 +6293,7 @@ static int ath11k_mac_op_start(struct ie -- case ATH11K_STATE_RESTARTED: -- case ATH11K_STATE_WEDGED: -- case ATH11K_STATE_ON: --+ case ATH11K_STATE_FTM: -- WARN_ON(1); -- ret = -EINVAL; -- goto err; ----- a/drivers/net/wireless/ath/ath11k/pci.c --+++ b/drivers/net/wireless/ath/ath11k/pci.c --@@ -1,7 +1,7 @@ -- // SPDX-License-Identifier: BSD-3-Clause-Clear -- /* -- * Copyright (c) 2019-2020 The Linux Foundation. All rights reserved. --- * Copyright (c) 2021-2022, Qualcomm Innovation Center, Inc. All rights reserved. --+ * Copyright (c) 2021-2023 Qualcomm Innovation Center, Inc. All rights reserved. -- */ -- -- #include --@@ -745,6 +745,7 @@ static int ath11k_pci_probe(struct pci_d -- ab_pci->ab = ab; -- ab_pci->pdev = pdev; -- ab->hif.ops = &ath11k_pci_hif_ops; --+ ab->fw_mode = ATH11K_FIRMWARE_MODE_NORMAL; -- pci_set_drvdata(pdev, ab); -- spin_lock_init(&ab_pci->window_lock); -- ----- a/drivers/net/wireless/ath/ath11k/testmode.c --+++ b/drivers/net/wireless/ath/ath11k/testmode.c --@@ -12,6 +12,9 @@ -- #include "core.h" -- #include "testmode_i.h" -- --+#define ATH11K_FTM_SEGHDR_CURRENT_SEQ GENMASK(3, 0) --+#define ATH11K_FTM_SEGHDR_TOTAL_SEGMENTS GENMASK(7, 4) --+ -- static const struct nla_policy ath11k_tm_policy[ATH11K_TM_ATTR_MAX + 1] = { -- [ATH11K_TM_ATTR_CMD] = { .type = NLA_U32 }, -- [ATH11K_TM_ATTR_DATA] = { .type = NLA_BINARY, --@@ -21,13 +24,217 @@ static const struct nla_policy ath11k_tm -- [ATH11K_TM_ATTR_VERSION_MINOR] = { .type = NLA_U32 }, -- }; -- --+static struct ath11k *ath11k_tm_get_ar(struct ath11k_base *ab) --+{ --+ struct ath11k_pdev *pdev; --+ struct ath11k *ar = NULL; --+ int i; --+ --+ for (i = 0; i < ab->num_radios; i++) { --+ pdev = &ab->pdevs[i]; --+ ar = pdev->ar; --+ --+ if (ar && ar->state == ATH11K_STATE_FTM) --+ break; --+ } --+ --+ return ar; --+} --+ --+/* This function handles unsegmented events. Data in various events are aggregated --+ * in application layer, this event is unsegmented from host perspective. --+ */ --+static void ath11k_tm_wmi_event_unsegmented(struct ath11k_base *ab, u32 cmd_id, --+ struct sk_buff *skb) --+{ --+ struct sk_buff *nl_skb; --+ struct ath11k *ar; --+ --+ ath11k_dbg(ab, ATH11K_DBG_TESTMODE, --+ "event wmi cmd_id %d skb length %d\n", --+ cmd_id, skb->len); --+ ath11k_dbg_dump(ab, ATH11K_DBG_TESTMODE, NULL, "", skb->data, skb->len); --+ --+ ar = ath11k_tm_get_ar(ab); --+ if (!ar) { --+ ath11k_warn(ab, "testmode event not handled due to invalid pdev\n"); --+ return; --+ } --+ --+ spin_lock_bh(&ar->data_lock); --+ --+ nl_skb = cfg80211_testmode_alloc_event_skb(ar->hw->wiphy, --+ 2 * nla_total_size(sizeof(u32)) + --+ nla_total_size(skb->len), --+ GFP_ATOMIC); --+ if (!nl_skb) { --+ ath11k_warn(ab, --+ "failed to allocate skb for unsegmented testmode wmi event\n"); --+ goto out; --+ } --+ --+ if (nla_put_u32(nl_skb, ATH11K_TM_ATTR_CMD, ATH11K_TM_CMD_WMI) || --+ nla_put_u32(nl_skb, ATH11K_TM_ATTR_WMI_CMDID, cmd_id) || --+ nla_put(nl_skb, ATH11K_TM_ATTR_DATA, skb->len, skb->data)) { --+ ath11k_warn(ab, "failed to populate testmode unsegmented event\n"); --+ kfree_skb(nl_skb); --+ goto out; --+ } --+ --+ cfg80211_testmode_event(nl_skb, GFP_ATOMIC); --+ spin_unlock_bh(&ar->data_lock); --+ return; --+ --+out: --+ spin_unlock_bh(&ar->data_lock); --+ ath11k_warn(ab, "Failed to send testmode event to higher layers\n"); --+} --+ --+/* This function handles segmented events. Data of various events received --+ * from firmware is aggregated and sent to application layer --+ */ --+static int ath11k_tm_process_event(struct ath11k_base *ab, u32 cmd_id, --+ const struct wmi_ftm_event_msg *ftm_msg, --+ u16 length) --+{ --+ struct sk_buff *nl_skb; --+ int ret = 0; --+ struct ath11k *ar; --+ u8 const *buf_pos; --+ u16 datalen; --+ u8 total_segments, current_seq; --+ u32 data_pos; --+ u32 pdev_id; --+ --+ ath11k_dbg(ab, ATH11K_DBG_TESTMODE, --+ "event wmi cmd_id %d ftm event msg %pK datalen %d\n", --+ cmd_id, ftm_msg, length); --+ ath11k_dbg_dump(ab, ATH11K_DBG_TESTMODE, NULL, "", ftm_msg, length); --+ pdev_id = DP_HW2SW_MACID(ftm_msg->seg_hdr.pdev_id); --+ --+ if (pdev_id >= ab->num_radios) { --+ ath11k_warn(ab, "testmode event not handled due to invalid pdev id: %d\n", --+ pdev_id); --+ return -EINVAL; --+ } --+ --+ ar = ab->pdevs[pdev_id].ar; --+ if (!ar) { --+ ath11k_warn(ab, "testmode event not handled due to absence of pdev\n"); --+ return -ENODEV; --+ } --+ --+ current_seq = FIELD_GET(ATH11K_FTM_SEGHDR_CURRENT_SEQ, --+ ftm_msg->seg_hdr.segmentinfo); --+ total_segments = FIELD_GET(ATH11K_FTM_SEGHDR_TOTAL_SEGMENTS, --+ ftm_msg->seg_hdr.segmentinfo); --+ datalen = length - (sizeof(struct wmi_ftm_seg_hdr)); --+ buf_pos = ftm_msg->data; --+ --+ spin_lock_bh(&ar->data_lock); --+ --+ if (current_seq == 0) { --+ ab->testmode.expected_seq = 0; --+ ab->testmode.data_pos = 0; --+ } --+ --+ data_pos = ab->testmode.data_pos; --+ --+ if ((data_pos + datalen) > ATH11K_FTM_EVENT_MAX_BUF_LENGTH) { --+ ath11k_warn(ab, "Invalid ftm event length at %d: %d\n", --+ data_pos, datalen); --+ ret = -EINVAL; --+ goto out; --+ } --+ --+ memcpy(&ab->testmode.eventdata[data_pos], buf_pos, datalen); --+ data_pos += datalen; --+ --+ if (++ab->testmode.expected_seq != total_segments) { --+ ab->testmode.data_pos = data_pos; --+ ath11k_dbg(ab, ATH11K_DBG_TESTMODE, --+ "partial data received current_seq %d total_seg %d\n", --+ current_seq, total_segments); --+ goto out; --+ } --+ --+ ath11k_dbg(ab, ATH11K_DBG_TESTMODE, --+ "total data length pos %d len %d\n", --+ data_pos, ftm_msg->seg_hdr.len); --+ nl_skb = cfg80211_testmode_alloc_event_skb(ar->hw->wiphy, --+ 2 * nla_total_size(sizeof(u32)) + --+ nla_total_size(data_pos), --+ GFP_ATOMIC); --+ if (!nl_skb) { --+ ath11k_warn(ab, --+ "failed to allocate skb for segmented testmode wmi event\n"); --+ ret = -ENOMEM; --+ goto out; --+ } --+ --+ if (nla_put_u32(nl_skb, ATH11K_TM_ATTR_CMD, --+ ATH11K_TM_CMD_WMI_FTM) || --+ nla_put_u32(nl_skb, ATH11K_TM_ATTR_WMI_CMDID, cmd_id) || --+ nla_put(nl_skb, ATH11K_TM_ATTR_DATA, data_pos, --+ &ab->testmode.eventdata[0])) { --+ ath11k_warn(ab, "failed to populate segmented testmode event"); --+ kfree_skb(nl_skb); --+ ret = -ENOBUFS; --+ goto out; --+ } --+ --+ cfg80211_testmode_event(nl_skb, GFP_ATOMIC); --+ --+out: --+ spin_unlock_bh(&ar->data_lock); --+ return ret; --+} --+ --+static void ath11k_tm_wmi_event_segmented(struct ath11k_base *ab, u32 cmd_id, --+ struct sk_buff *skb) --+{ --+ const void **tb; --+ const struct wmi_ftm_event_msg *ev; --+ u16 length; --+ 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 ftm event tlv: %d\n", ret); --+ return; --+ } --+ --+ ev = tb[WMI_TAG_ARRAY_BYTE]; --+ if (!ev) { --+ ath11k_warn(ab, "failed to fetch ftm msg\n"); --+ kfree(tb); --+ return; --+ } --+ --+ length = skb->len - TLV_HDR_SIZE; --+ ret = ath11k_tm_process_event(ab, cmd_id, ev, length); --+ if (ret) --+ ath11k_warn(ab, "Failed to process ftm event\n"); --+ --+ kfree(tb); --+} --+ --+void ath11k_tm_wmi_event(struct ath11k_base *ab, u32 cmd_id, struct sk_buff *skb) --+{ --+ if (test_bit(ATH11K_FLAG_FTM_SEGMENTED, &ab->dev_flags)) --+ ath11k_tm_wmi_event_segmented(ab, cmd_id, skb); --+ else --+ ath11k_tm_wmi_event_unsegmented(ab, cmd_id, skb); --+} --+ -- static int ath11k_tm_cmd_get_version(struct ath11k *ar, struct nlattr *tb[]) -- { -- struct sk_buff *skb; -- int ret; -- -- ath11k_dbg(ar->ab, ATH11K_DBG_TESTMODE, --- "testmode cmd get version_major %d version_minor %d\n", --+ "cmd get version_major %d version_minor %d\n", -- ATH11K_TESTMODE_VERSION_MAJOR, -- ATH11K_TESTMODE_VERSION_MINOR); -- --@@ -53,6 +260,43 @@ static int ath11k_tm_cmd_get_version(str -- return cfg80211_testmode_reply(skb); -- } -- --+static int ath11k_tm_cmd_testmode_start(struct ath11k *ar, struct nlattr *tb[]) --+{ --+ int ret; --+ --+ mutex_lock(&ar->conf_mutex); --+ --+ if (ar->state == ATH11K_STATE_FTM) { --+ ret = -EALREADY; --+ goto err; --+ } --+ --+ /* start utf only when the driver is not in use */ --+ if (ar->state != ATH11K_STATE_OFF) { --+ ret = -EBUSY; --+ goto err; --+ } --+ --+ ar->ab->testmode.eventdata = kzalloc(ATH11K_FTM_EVENT_MAX_BUF_LENGTH, --+ GFP_KERNEL); --+ if (!ar->ab->testmode.eventdata) { --+ ret = -ENOMEM; --+ goto err; --+ } --+ --+ ar->state = ATH11K_STATE_FTM; --+ ar->ftm_msgref = 0; --+ --+ mutex_unlock(&ar->conf_mutex); --+ --+ ath11k_dbg(ar->ab, ATH11K_DBG_TESTMODE, "cmd start\n"); --+ return 0; --+ --+err: --+ mutex_unlock(&ar->conf_mutex); --+ return ret; --+} --+ -- static int ath11k_tm_cmd_wmi(struct ath11k *ar, struct nlattr *tb[]) -- { -- struct ath11k_pdev_wmi *wmi = ar->wmi; --@@ -63,11 +307,6 @@ static int ath11k_tm_cmd_wmi(struct ath1 -- -- mutex_lock(&ar->conf_mutex); -- --- if (ar->state != ATH11K_STATE_ON) { --- ret = -ENETDOWN; --- goto out; --- } --- -- if (!tb[ATH11K_TM_ATTR_DATA]) { -- ret = -EINVAL; -- goto out; --@@ -80,11 +319,17 @@ static int ath11k_tm_cmd_wmi(struct ath1 -- -- buf = nla_data(tb[ATH11K_TM_ATTR_DATA]); -- buf_len = nla_len(tb[ATH11K_TM_ATTR_DATA]); --+ if (!buf_len) { --+ ath11k_warn(ar->ab, "No data present in testmode wmi command\n"); --+ ret = -EINVAL; --+ goto out; --+ } --+ -- cmd_id = nla_get_u32(tb[ATH11K_TM_ATTR_WMI_CMDID]); -- -- ath11k_dbg(ar->ab, ATH11K_DBG_TESTMODE, --- "testmode cmd wmi cmd_id %d buf %pK buf_len %d\n", --- cmd_id, buf, buf_len); --+ "cmd wmi cmd_id %d buf length %d\n", --+ cmd_id, buf_len); -- -- ath11k_dbg_dump(ar->ab, ATH11K_DBG_TESTMODE, NULL, "", buf, buf_len); -- --@@ -111,6 +356,91 @@ out: -- return ret; -- } -- --+static int ath11k_tm_cmd_wmi_ftm(struct ath11k *ar, struct nlattr *tb[]) --+{ --+ struct ath11k_pdev_wmi *wmi = ar->wmi; --+ struct ath11k_base *ab = ar->ab; --+ struct sk_buff *skb; --+ u32 cmd_id, buf_len, hdr_info; --+ int ret; --+ void *buf; --+ u8 segnumber = 0, seginfo; --+ u16 chunk_len, total_bytes, num_segments; --+ u8 *bufpos; --+ struct wmi_ftm_cmd *ftm_cmd; --+ --+ set_bit(ATH11K_FLAG_FTM_SEGMENTED, &ab->dev_flags); --+ --+ mutex_lock(&ar->conf_mutex); --+ --+ if (ar->state != ATH11K_STATE_FTM) { --+ ret = -ENETDOWN; --+ goto out; --+ } --+ --+ if (!tb[ATH11K_TM_ATTR_DATA]) { --+ ret = -EINVAL; --+ goto out; --+ } --+ --+ buf = nla_data(tb[ATH11K_TM_ATTR_DATA]); --+ buf_len = nla_len(tb[ATH11K_TM_ATTR_DATA]); --+ cmd_id = WMI_PDEV_UTF_CMDID; --+ --+ ath11k_dbg(ar->ab, ATH11K_DBG_TESTMODE, --+ "cmd wmi ftm cmd_id %d buffer length %d\n", --+ cmd_id, buf_len); --+ ath11k_dbg_dump(ar->ab, ATH11K_DBG_TESTMODE, NULL, "", buf, buf_len); --+ --+ bufpos = buf; --+ total_bytes = buf_len; --+ num_segments = total_bytes / MAX_WMI_UTF_LEN; --+ --+ if (buf_len - (num_segments * MAX_WMI_UTF_LEN)) --+ num_segments++; --+ --+ while (buf_len) { --+ chunk_len = min_t(u16, buf_len, MAX_WMI_UTF_LEN); --+ --+ skb = ath11k_wmi_alloc_skb(wmi->wmi_ab, (chunk_len + --+ sizeof(struct wmi_ftm_cmd))); --+ if (!skb) { --+ ret = -ENOMEM; --+ goto out; --+ } --+ --+ ftm_cmd = (struct wmi_ftm_cmd *)skb->data; --+ hdr_info = FIELD_PREP(WMI_TLV_TAG, WMI_TAG_ARRAY_BYTE) | --+ FIELD_PREP(WMI_TLV_LEN, (chunk_len + --+ sizeof(struct wmi_ftm_seg_hdr))); --+ ftm_cmd->tlv_header = hdr_info; --+ ftm_cmd->seg_hdr.len = total_bytes; --+ ftm_cmd->seg_hdr.msgref = ar->ftm_msgref; --+ seginfo = FIELD_PREP(ATH11K_FTM_SEGHDR_TOTAL_SEGMENTS, num_segments) | --+ FIELD_PREP(ATH11K_FTM_SEGHDR_CURRENT_SEQ, segnumber); --+ ftm_cmd->seg_hdr.segmentinfo = seginfo; --+ segnumber++; --+ --+ memcpy(&ftm_cmd->data, bufpos, chunk_len); --+ --+ ret = ath11k_wmi_cmd_send(wmi, skb, cmd_id); --+ if (ret) { --+ ath11k_warn(ar->ab, "failed to send wmi ftm command: %d\n", ret); --+ goto out; --+ } --+ --+ buf_len -= chunk_len; --+ bufpos += chunk_len; --+ } --+ --+ ar->ftm_msgref++; --+ ret = 0; --+ --+out: --+ mutex_unlock(&ar->conf_mutex); --+ return ret; --+} --+ -- int ath11k_tm_cmd(struct ieee80211_hw *hw, struct ieee80211_vif *vif, -- void *data, int len) -- { --@@ -131,6 +461,10 @@ int ath11k_tm_cmd(struct ieee80211_hw *h -- return ath11k_tm_cmd_get_version(ar, tb); -- case ATH11K_TM_CMD_WMI: -- return ath11k_tm_cmd_wmi(ar, tb); --+ case ATH11K_TM_CMD_TESTMODE_START: --+ return ath11k_tm_cmd_testmode_start(ar, tb); --+ case ATH11K_TM_CMD_WMI_FTM: --+ return ath11k_tm_cmd_wmi_ftm(ar, tb); -- default: -- return -EOPNOTSUPP; -- } ----- a/drivers/net/wireless/ath/ath11k/testmode.h --+++ b/drivers/net/wireless/ath/ath11k/testmode.h --@@ -8,11 +8,17 @@ -- -- #ifdef CPTCFG_NL80211_TESTMODE -- --+void ath11k_tm_wmi_event(struct ath11k_base *ab, u32 cmd_id, struct sk_buff *skb); -- int ath11k_tm_cmd(struct ieee80211_hw *hw, struct ieee80211_vif *vif, -- void *data, int len); -- -- #else -- --+static inline void ath11k_tm_wmi_event(struct ath11k_base *ab, u32 cmd_id, --+ struct sk_buff *skb) --+{ --+} --+ -- static inline int ath11k_tm_cmd(struct ieee80211_hw *hw, -- struct ieee80211_vif *vif, -- void *data, int len) ----- a/drivers/net/wireless/ath/ath11k/testmode_i.h --+++ b/drivers/net/wireless/ath/ath11k/testmode_i.h --@@ -1,6 +1,7 @@ -- /* SPDX-License-Identifier: BSD-3-Clause-Clear */ -- /* -- * Copyright (c) 2018-2019 The Linux Foundation. All rights reserved. --+ * Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights reserved. -- */ -- -- /* "API" level of the ath11k testmode interface. Bump it after every --@@ -11,9 +12,10 @@ -- /* Bump this after every _compatible_ interface change, for example -- * addition of a new command or an attribute. -- */ ---#define ATH11K_TESTMODE_VERSION_MINOR 0 --+#define ATH11K_TESTMODE_VERSION_MINOR 1 -- -- #define ATH11K_TM_DATA_MAX_LEN 5000 --+#define ATH11K_FTM_EVENT_MAX_BUF_LENGTH 2048 -- -- enum ath11k_tm_attr { -- __ATH11K_TM_ATTR_INVALID = 0, --@@ -47,4 +49,18 @@ enum ath11k_tm_cmd { -- * ATH11K_TM_ATTR_DATA. -- */ -- ATH11K_TM_CMD_WMI = 1, --+ --+ /* Boots the UTF firmware, the netdev interface must be down at the --+ * time. --+ */ --+ ATH11K_TM_CMD_TESTMODE_START = 2, --+ --+ /* The command used to transmit a FTM WMI command to the firmware --+ * and the event to receive WMI events from the firmware. The data --+ * received only contain the payload, need to add the tlv header --+ * and send the cmd to firmware with command id WMI_PDEV_UTF_CMDID. --+ * The data payload size could be large and the driver needs to --+ * send segmented data to firmware. --+ */ --+ ATH11K_TM_CMD_WMI_FTM = 3, -- }; ----- a/drivers/net/wireless/ath/ath11k/wmi.c --+++ b/drivers/net/wireless/ath/ath11k/wmi.c --@@ -1,7 +1,7 @@ -- // SPDX-License-Identifier: BSD-3-Clause-Clear -- /* -- * Copyright (c) 2018-2019 The Linux Foundation. All rights reserved. --- * Copyright (c) 2021, Qualcomm Innovation Center, Inc. All rights reserved. --+ * Copyright (c) 2021, 2023 Qualcomm Innovation Center, Inc. All rights reserved. -- */ -- #include -- #include --@@ -19,6 +19,7 @@ -- #include "mac.h" -- #include "hw.h" -- #include "peer.h" --+#include "testmode.h" -- -- struct wmi_tlv_policy { -- size_t min_len; --@@ -237,9 +238,8 @@ static int ath11k_wmi_tlv_parse(struct a -- (void *)tb); -- } -- ---static const void ** ---ath11k_wmi_tlv_parse_alloc(struct ath11k_base *ab, const void *ptr, --- size_t len, gfp_t gfp) --+const void **ath11k_wmi_tlv_parse_alloc(struct ath11k_base *ab, const void *ptr, --+ size_t len, gfp_t gfp) -- { -- const void **tb; -- int ret; --@@ -8628,6 +8628,9 @@ static void ath11k_wmi_tlv_op_rx(struct -- case WMI_PDEV_CSA_SWITCH_COUNT_STATUS_EVENTID: -- ath11k_wmi_pdev_csa_switch_count_status_event(ab, skb); -- break; --+ case WMI_PDEV_UTF_EVENTID: --+ ath11k_tm_wmi_event(ab, id, skb); --+ break; -- case WMI_PDEV_TEMPERATURE_EVENTID: -- ath11k_wmi_pdev_temperature_event(ab, skb); -- break; ----- a/drivers/net/wireless/ath/ath11k/wmi.h --+++ b/drivers/net/wireless/ath/ath11k/wmi.h --@@ -1,6 +1,7 @@ -- /* SPDX-License-Identifier: BSD-3-Clause-Clear */ -- /* -- * Copyright (c) 2018-2019 The Linux Foundation. All rights reserved. --+ * Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights reserved. -- */ -- -- #ifndef ATH11K_WMI_H --@@ -68,6 +69,7 @@ struct wmi_tlv { -- -- #define WMI_APPEND_TO_EXISTING_CHAN_LIST_FLAG 1 -- --+#define MAX_WMI_UTF_LEN 252 -- #define WMI_BA_MODE_BUFFER_SIZE_256 3 -- /* -- * HW mode config type replicated from FW header --@@ -3564,6 +3566,24 @@ struct wmi_get_pdev_temperature_cmd { -- u32 pdev_id; -- } __packed; -- --+struct wmi_ftm_seg_hdr { --+ u32 len; --+ u32 msgref; --+ u32 segmentinfo; --+ u32 pdev_id; --+} __packed; --+ --+struct wmi_ftm_cmd { --+ u32 tlv_header; --+ struct wmi_ftm_seg_hdr seg_hdr; --+ u8 data[]; --+} __packed; --+ --+struct wmi_ftm_event_msg { --+ struct wmi_ftm_seg_hdr seg_hdr; --+ u8 data[]; --+} __packed; --+ -- #define WMI_BEACON_TX_BUFFER_SIZE 512 -- -- #define WMI_EMA_TMPL_IDX_SHIFT 8 --@@ -6300,6 +6320,8 @@ enum wmi_sta_keepalive_method { -- #define WMI_STA_KEEPALIVE_INTERVAL_DEFAULT 30 -- #define WMI_STA_KEEPALIVE_INTERVAL_DISABLE 0 -- --+const void **ath11k_wmi_tlv_parse_alloc(struct ath11k_base *ab, const void *ptr, --+ size_t len, gfp_t gfp); -- int ath11k_wmi_cmd_send(struct ath11k_pdev_wmi *wmi, struct sk_buff *skb, -- u32 cmd_id); -- struct sk_buff *ath11k_wmi_alloc_skb(struct ath11k_wmi_base *wmi_sc, u32 len); ----- a/drivers/net/wireless/ath/ath11k/wow.c --+++ b/drivers/net/wireless/ath/ath11k/wow.c --@@ -1,7 +1,7 @@ -- // SPDX-License-Identifier: BSD-3-Clause-Clear -- /* -- * Copyright (c) 2020 The Linux Foundation. All rights reserved. --- * Copyright (c) 2022, Qualcomm Innovation Center, Inc. All rights reserved. --+ * Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved. -- */ -- -- #include --@@ -838,6 +838,7 @@ exit: -- case ATH11K_STATE_RESTARTING: -- case ATH11K_STATE_RESTARTED: -- case ATH11K_STATE_WEDGED: --+ case ATH11K_STATE_FTM: -- ath11k_warn(ar->ab, "encountered unexpected device state %d on resume, cannot recover\n", -- ar->state); -- ret = -EIO; -diff --git a/package/kernel/mac80211/patches/ath11k/0083-wifi-ath11k-Allow-ath11k-to-boot-without-caldata-in-.patch b/package/kernel/mac80211/patches/ath11k/0083-wifi-ath11k-Allow-ath11k-to-boot-without-caldata-in-.patch -deleted file mode 100644 -index 5a1fa88294..0000000000 ---- a/package/kernel/mac80211/patches/ath11k/0083-wifi-ath11k-Allow-ath11k-to-boot-without-caldata-in-.patch -+++ /dev/null -@@ -1,47 +0,0 @@ --From 8aeba427296bff6a6051686f1d139c89a0b00e4c Mon Sep 17 00:00:00 2001 --From: Sowmiya Sree Elavalagan --Date: Fri, 26 May 2023 12:41:07 +0300 --Subject: [PATCH 84/84] wifi: ath11k: Allow ath11k to boot without caldata in -- ftm mode -- --Currently, if ath11k is unable to load the calibration data file it will --always exit. However the calibration data may not be present in factory --test mode, so update the logic to allow the driver to execute in FTM mode --even if downloading the calibration data fails. -- --Tested-on : IPQ8074 hw2.0 AHB WLAN.HK.2.7.0.1-01744-QCAHKSWPL_SILICONZ-1 -- --Signed-off-by: Sowmiya Sree Elavalagan --Signed-off-by: Raj Kumar Bhagat --Signed-off-by: Kalle Valo --Link: https://lore.kernel.org/r/20230517135934.16408-5-quic_rajkbhag@quicinc.com ----- -- drivers/net/wireless/ath/ath11k/qmi.c | 10 +++++++++- -- 1 file changed, 9 insertions(+), 1 deletion(-) -- ----- a/drivers/net/wireless/ath/ath11k/qmi.c --+++ b/drivers/net/wireless/ath/ath11k/qmi.c --@@ -1,7 +1,7 @@ -- // SPDX-License-Identifier: BSD-3-Clause-Clear -- /* -- * Copyright (c) 2018-2019 The Linux Foundation. All rights reserved. --- * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved. --+ * Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved. -- */ -- -- #include --@@ -2460,6 +2460,14 @@ static int ath11k_qmi_load_bdf_qmi(struc -- -- fw_entry = ath11k_core_firmware_request(ab, ATH11K_DEFAULT_CAL_FILE); -- if (IS_ERR(fw_entry)) { --+ /* Caldata may not be present during first time calibration in --+ * factory hence allow to boot without loading caldata in ftm mode --+ */ --+ if (ath11k_ftm_mode) { --+ ath11k_info(ab, --+ "Booting without cal data file in factory test mode\n"); --+ return 0; --+ } -- ret = PTR_ERR(fw_entry); -- ath11k_warn(ab, -- "qmi failed to load CAL data file:%s\n", -diff --git a/package/kernel/mac80211/patches/ath11k/0084-wifi-ath11k-Add-HTT-stats-for-PHY-reset-case.patch b/package/kernel/mac80211/patches/ath11k/0084-wifi-ath11k-Add-HTT-stats-for-PHY-reset-case.patch -deleted file mode 100644 -index 946f5f7b57..0000000000 ---- a/package/kernel/mac80211/patches/ath11k/0084-wifi-ath11k-Add-HTT-stats-for-PHY-reset-case.patch -+++ /dev/null -@@ -1,261 +0,0 @@ --From 2d4f9093e2d8531ad0a2bb98fe5b36dc8addf2a2 Mon Sep 17 00:00:00 2001 --From: Nidhi Jain --Date: Fri, 26 May 2023 12:41:07 +0300 --Subject: [PATCH] wifi: ath11k: Add HTT stats for PHY reset case -- --New HTT stats are added with stats type 37 to --provide PHY reset stats and PHY reset counter stats. -- --PHY reset stats are used to display the current --PHY-related operation information such as band, CCA --threshold, current operating channel etc., -- --PHY reset counter stats are used to display the --PHY reset counter values like calibration counts, --temperature based recalibration counts etc., -- --Usage: --echo 37 > /sys/kernel/debug/ieee80211/phyX/ath11k/htt_stats_type --cat /sys/kernel/debug/ieee80211/phyx/ath11k/htt_stats -- --Output: -- --HTT_PHY_RESET_STATS_TLV: --pdev_id = 0 --chan_mhz = 5180 --chan_band_center_freq1 = 5210 --chan_band_center_freq2 = 0 --chan_phy_mode = 18 --chan_flags = 0x8 --chan_num = 36 --reset_cause = 0x50000 --prev_reset_cause = 0x50000 --phy_warm_reset_src = 0x0 --rx_gain_tbl_mode = 0 --xbar_val = 0xfac688 --force_calibration = 0 --phyrf_mode = 0 --phy_homechan = 0 --phy_tx_ch_mask = 0x3 --phy_rx_ch_mask = 0x3 --phybb_ini_mask = 0x5 --phyrf_ini_mask = 0x0 --phy_dfs_en_mask = 0x0 --phy_sscan_en_mask = 0x0 --phy_synth_sel_mask = 0x0 --phy_adfs_freq = 0 --cck_fir_settings = 0x0 --phy_dyn_pri_chan = 6 --cca_thresh = 0x26232020 --dyn_cca_status = 0 --rxdesense_thresh_hw = 0xcfe0afe --rxdesense_thresh_sw = 0xcfe0afe -- --HTT_PHY_RESET_COUNTERS_TLV: --pdev_id = 0 --cf_active_low_fail_cnt = 0 --cf_active_low_pass_cnt = 0 --phy_off_through_vreg_cnt = 0 --force_calibration_cnt = 0 --rf_mode_switch_phy_off_cnt = 0 -- --Tested-on: IPQ8074 hw2.0 AHB WLAN.HK.2.7.0.1-01744-QCAHKSWPL_SILICONZ-1 -- --Signed-off-by: Nidhi Jain --Signed-off-by: Maharaja Kennadyrajan --Signed-off-by: Kalle Valo --Link: https://lore.kernel.org/r/20230517141242.2754293-1-quic_mkenna@quicinc.com ----- -- .../wireless/ath/ath11k/debugfs_htt_stats.c | 114 ++++++++++++++++++ -- .../wireless/ath/ath11k/debugfs_htt_stats.h | 43 +++++++ -- 2 files changed, 157 insertions(+) -- ----- a/drivers/net/wireless/ath/ath11k/debugfs_htt_stats.c --+++ b/drivers/net/wireless/ath/ath11k/debugfs_htt_stats.c --@@ -4011,6 +4011,114 @@ void htt_print_phy_stats_tlv(const void -- stats_req->buf_len = len; -- } -- --+static inline void --+htt_print_phy_reset_counters_tlv(const void *tag_buf, --+ u16 tag_len, --+ struct debug_htt_stats_req *stats_req) --+{ --+ const struct htt_phy_reset_counters_tlv *htt_stats_buf = tag_buf; --+ u8 *buf = stats_req->buf; --+ u32 len = stats_req->buf_len; --+ u32 buf_len = ATH11K_HTT_STATS_BUF_SIZE; --+ --+ if (tag_len < sizeof(*htt_stats_buf)) --+ return; --+ --+ len += scnprintf(buf + len, buf_len - len, "HTT_PHY_RESET_COUNTERS_TLV:\n"); --+ --+ len += scnprintf(buf + len, buf_len - len, "pdev_id = %u\n", --+ htt_stats_buf->pdev_id); --+ len += scnprintf(buf + len, buf_len - len, "cf_active_low_fail_cnt = %u\n", --+ htt_stats_buf->cf_active_low_fail_cnt); --+ len += scnprintf(buf + len, buf_len - len, "cf_active_low_pass_cnt = %u\n", --+ htt_stats_buf->cf_active_low_pass_cnt); --+ len += scnprintf(buf + len, buf_len - len, "phy_off_through_vreg_cnt = %u\n", --+ htt_stats_buf->phy_off_through_vreg_cnt); --+ len += scnprintf(buf + len, buf_len - len, "force_calibration_cnt = %u\n", --+ htt_stats_buf->force_calibration_cnt); --+ len += scnprintf(buf + len, buf_len - len, "rf_mode_switch_phy_off_cnt = %u\n", --+ htt_stats_buf->rf_mode_switch_phy_off_cnt); --+ --+ stats_req->buf_len = len; --+} --+ --+static inline void --+htt_print_phy_reset_stats_tlv(const void *tag_buf, --+ u16 tag_len, --+ struct debug_htt_stats_req *stats_req) --+{ --+ const struct htt_phy_reset_stats_tlv *htt_stats_buf = tag_buf; --+ u8 *buf = stats_req->buf; --+ u32 len = stats_req->buf_len; --+ u32 buf_len = ATH11K_HTT_STATS_BUF_SIZE; --+ --+ if (tag_len < sizeof(*htt_stats_buf)) --+ return; --+ --+ len += scnprintf(buf + len, buf_len - len, "HTT_PHY_RESET_STATS_TLV:\n"); --+ --+ len += scnprintf(buf + len, buf_len - len, "pdev_id = %u\n", --+ htt_stats_buf->pdev_id); --+ len += scnprintf(buf + len, buf_len - len, "chan_mhz = %u\n", --+ htt_stats_buf->chan_mhz); --+ len += scnprintf(buf + len, buf_len - len, "chan_band_center_freq1 = %u\n", --+ htt_stats_buf->chan_band_center_freq1); --+ len += scnprintf(buf + len, buf_len - len, "chan_band_center_freq2 = %u\n", --+ htt_stats_buf->chan_band_center_freq2); --+ len += scnprintf(buf + len, buf_len - len, "chan_phy_mode = %u\n", --+ htt_stats_buf->chan_phy_mode); --+ len += scnprintf(buf + len, buf_len - len, "chan_flags = 0x%0x\n", --+ htt_stats_buf->chan_flags); --+ len += scnprintf(buf + len, buf_len - len, "chan_num = %u\n", --+ htt_stats_buf->chan_num); --+ len += scnprintf(buf + len, buf_len - len, "reset_cause = 0x%0x\n", --+ htt_stats_buf->reset_cause); --+ len += scnprintf(buf + len, buf_len - len, "prev_reset_cause = 0x%0x\n", --+ htt_stats_buf->prev_reset_cause); --+ len += scnprintf(buf + len, buf_len - len, "phy_warm_reset_src = 0x%0x\n", --+ htt_stats_buf->phy_warm_reset_src); --+ len += scnprintf(buf + len, buf_len - len, "rx_gain_tbl_mode = %d\n", --+ htt_stats_buf->rx_gain_tbl_mode); --+ len += scnprintf(buf + len, buf_len - len, "xbar_val = 0x%0x\n", --+ htt_stats_buf->xbar_val); --+ len += scnprintf(buf + len, buf_len - len, "force_calibration = %u\n", --+ htt_stats_buf->force_calibration); --+ len += scnprintf(buf + len, buf_len - len, "phyrf_mode = %u\n", --+ htt_stats_buf->phyrf_mode); --+ len += scnprintf(buf + len, buf_len - len, "phy_homechan = %u\n", --+ htt_stats_buf->phy_homechan); --+ len += scnprintf(buf + len, buf_len - len, "phy_tx_ch_mask = 0x%0x\n", --+ htt_stats_buf->phy_tx_ch_mask); --+ len += scnprintf(buf + len, buf_len - len, "phy_rx_ch_mask = 0x%0x\n", --+ htt_stats_buf->phy_rx_ch_mask); --+ len += scnprintf(buf + len, buf_len - len, "phybb_ini_mask = 0x%0x\n", --+ htt_stats_buf->phybb_ini_mask); --+ len += scnprintf(buf + len, buf_len - len, "phyrf_ini_mask = 0x%0x\n", --+ htt_stats_buf->phyrf_ini_mask); --+ len += scnprintf(buf + len, buf_len - len, "phy_dfs_en_mask = 0x%0x\n", --+ htt_stats_buf->phy_dfs_en_mask); --+ len += scnprintf(buf + len, buf_len - len, "phy_sscan_en_mask = 0x%0x\n", --+ htt_stats_buf->phy_sscan_en_mask); --+ len += scnprintf(buf + len, buf_len - len, "phy_synth_sel_mask = 0x%0x\n", --+ htt_stats_buf->phy_synth_sel_mask); --+ len += scnprintf(buf + len, buf_len - len, "phy_adfs_freq = %u\n", --+ htt_stats_buf->phy_adfs_freq); --+ len += scnprintf(buf + len, buf_len - len, "cck_fir_settings = 0x%0x\n", --+ htt_stats_buf->cck_fir_settings); --+ len += scnprintf(buf + len, buf_len - len, "phy_dyn_pri_chan = %u\n", --+ htt_stats_buf->phy_dyn_pri_chan); --+ len += scnprintf(buf + len, buf_len - len, "cca_thresh = 0x%0x\n", --+ htt_stats_buf->cca_thresh); --+ len += scnprintf(buf + len, buf_len - len, "dyn_cca_status = %u\n", --+ htt_stats_buf->dyn_cca_status); --+ len += scnprintf(buf + len, buf_len - len, "rxdesense_thresh_hw = 0x%x\n", --+ htt_stats_buf->rxdesense_thresh_hw); --+ len += scnprintf(buf + len, buf_len - len, "rxdesense_thresh_sw = 0x%x\n", --+ htt_stats_buf->rxdesense_thresh_sw); --+ --+ stats_req->buf_len = len; --+} --+ -- static inline -- void htt_print_peer_ctrl_path_txrx_stats_tlv(const void *tag_buf, -- struct debug_htt_stats_req *stats_req) --@@ -4425,6 +4533,12 @@ static int ath11k_dbg_htt_ext_stats_pars -- case HTT_STATS_PHY_STATS_TAG: -- htt_print_phy_stats_tlv(tag_buf, stats_req); -- break; --+ case HTT_STATS_PHY_RESET_COUNTERS_TAG: --+ htt_print_phy_reset_counters_tlv(tag_buf, len, stats_req); --+ break; --+ case HTT_STATS_PHY_RESET_STATS_TAG: --+ htt_print_phy_reset_stats_tlv(tag_buf, len, stats_req); --+ break; -- case HTT_STATS_PEER_CTRL_PATH_TXRX_STATS_TAG: -- htt_print_peer_ctrl_path_txrx_stats_tlv(tag_buf, stats_req); -- break; ----- a/drivers/net/wireless/ath/ath11k/debugfs_htt_stats.h --+++ b/drivers/net/wireless/ath/ath11k/debugfs_htt_stats.h --@@ -111,6 +111,8 @@ enum htt_tlv_tag_t { -- HTT_STATS_TXBF_OFDMA_STEER_STATS_TAG = 116, -- HTT_STATS_PHY_COUNTERS_TAG = 121, -- HTT_STATS_PHY_STATS_TAG = 122, --+ HTT_STATS_PHY_RESET_COUNTERS_TAG = 123, --+ HTT_STATS_PHY_RESET_STATS_TAG = 124, -- -- HTT_STATS_MAX_TAG, -- }; --@@ -1964,6 +1966,47 @@ struct htt_phy_stats_tlv { -- u32 fw_run_time; -- }; -- --+struct htt_phy_reset_counters_tlv { --+ u32 pdev_id; --+ u32 cf_active_low_fail_cnt; --+ u32 cf_active_low_pass_cnt; --+ u32 phy_off_through_vreg_cnt; --+ u32 force_calibration_cnt; --+ u32 rf_mode_switch_phy_off_cnt; --+}; --+ --+struct htt_phy_reset_stats_tlv { --+ u32 pdev_id; --+ u32 chan_mhz; --+ u32 chan_band_center_freq1; --+ u32 chan_band_center_freq2; --+ u32 chan_phy_mode; --+ u32 chan_flags; --+ u32 chan_num; --+ u32 reset_cause; --+ u32 prev_reset_cause; --+ u32 phy_warm_reset_src; --+ u32 rx_gain_tbl_mode; --+ u32 xbar_val; --+ u32 force_calibration; --+ u32 phyrf_mode; --+ u32 phy_homechan; --+ u32 phy_tx_ch_mask; --+ u32 phy_rx_ch_mask; --+ u32 phybb_ini_mask; --+ u32 phyrf_ini_mask; --+ u32 phy_dfs_en_mask; --+ u32 phy_sscan_en_mask; --+ u32 phy_synth_sel_mask; --+ u32 phy_adfs_freq; --+ u32 cck_fir_settings; --+ u32 phy_dyn_pri_chan; --+ u32 cca_thresh; --+ u32 dyn_cca_status; --+ u32 rxdesense_thresh_hw; --+ u32 rxdesense_thresh_sw; --+}; --+ -- struct htt_peer_ctrl_path_txrx_stats_tlv { -- /* peer mac address */ -- u8 peer_mac_addr[ETH_ALEN]; -diff --git a/package/kernel/mac80211/patches/ath11k/100-wifi-ath11k-use-unique-QRTR-instance-ID.patch b/package/kernel/mac80211/patches/ath11k/100-wifi-ath11k-use-unique-QRTR-instance-ID.patch -deleted file mode 100644 -index 39d5a61d5a..0000000000 ---- a/package/kernel/mac80211/patches/ath11k/100-wifi-ath11k-use-unique-QRTR-instance-ID.patch -+++ /dev/null -@@ -1,162 +0,0 @@ --From 534a5f99d589cfa6b244b4433c192b6a278a67ff Mon Sep 17 00:00:00 2001 --From: Robert Marko --Date: Sat, 5 Nov 2022 20:15:40 +0100 --Subject: [PATCH] wifi: ath11k: use unique QRTR instance ID -- --Currently, trying to use AHB + PCI/MHI cards or multiple PCI/MHI cards --will cause a clash in the QRTR instance node ID and prevent the driver --from talking via QMI to the card and thus initializing it with: --[ 9.836329] ath11k c000000.wifi: host capability request failed: 1 90 --[ 9.842047] ath11k c000000.wifi: failed to send qmi host cap: -22 -- --So, in order to allow for this combination of cards, especially AHB + PCI --cards like IPQ8074 + QCN9074 (Used by me and tested on) set the desired --QRTR instance ID offset by calculating a unique one based on PCI domain --and bus ID-s and writing it to bits 7-0 of BHI_ERRDBG2 MHI register by --using the SBL state callback that is added as part of the series. --We also have to make sure that new QRTR offset is added on top of the --default QRTR instance ID-s that are currently used in the driver. -- --This finally allows using AHB + PCI or multiple PCI cards on the same --system. -- --Since this is not supported on QCA6390 and like, its limited to QCN9074 --which is known to support changing QRTR instance ID. -- --Before: --root@OpenWrt:/# qrtr-lookup -- Service Version Instance Node Port -- 1054 1 0 7 1 -- 69 1 2 7 3 ATH10k WLAN firmware service -- --After: --root@OpenWrt:/# qrtr-lookup -- Service Version Instance Node Port -- 1054 1 0 7 1 -- 69 1 2 7 3 ATH10k WLAN firmware service -- 15 1 0 8 1 Test service -- 69 1 8 8 2 ATH10k WLAN firmware service -- --Tested-on: IPQ8074 hw2.0 AHB WLAN.HK.2.5.0.1-01208-QCAHKSWPL_SILICONZ-1 --Tested-on: QCN9074 hw1.0 PCI WLAN.HK.2.5.0.1-01208-QCAHKSWPL_SILICONZ-1 -- --Signed-off-by: Robert Marko ----- -- drivers/net/wireless/ath/ath11k/mhi.c | 49 ++++++++++++++++++--------- -- drivers/net/wireless/ath/ath11k/mhi.h | 3 ++ -- drivers/net/wireless/ath/ath11k/pci.c | 9 ++++- -- 3 files changed, 44 insertions(+), 17 deletions(-) -- ----- a/drivers/net/wireless/ath/ath11k/mhi.c --+++ b/drivers/net/wireless/ath/ath11k/mhi.c --@@ -294,6 +294,34 @@ static void ath11k_mhi_op_runtime_put(st -- { -- } -- --+static int ath11k_mhi_op_read_reg(struct mhi_controller *mhi_cntrl, --+ void __iomem *addr, --+ u32 *out) --+{ --+ *out = readl(addr); --+ --+ return 0; --+} --+ --+static void ath11k_mhi_op_write_reg(struct mhi_controller *mhi_cntrl, --+ void __iomem *addr, --+ u32 val) --+{ --+ writel(val, addr); --+} --+ --+static void ath11k_mhi_qrtr_instance_set(struct mhi_controller *mhi_cntrl) --+{ --+ struct ath11k_base *ab = dev_get_drvdata(mhi_cntrl->cntrl_dev); --+ --+ if (ab->hw_rev == ATH11K_HW_QCN9074_HW10) { --+ ath11k_mhi_op_write_reg(mhi_cntrl, --+ mhi_cntrl->bhi + BHI_ERRDBG2, --+ FIELD_PREP(QRTR_INSTANCE_MASK, --+ ab->qmi.service_ins_id - ab->hw_params.qmi_service_ins_id)); --+ } --+} --+ -- static char *ath11k_mhi_op_callback_to_str(enum mhi_callback reason) -- { -- switch (reason) { --@@ -315,6 +343,8 @@ static char *ath11k_mhi_op_callback_to_s -- return "MHI_CB_FATAL_ERROR"; -- case MHI_CB_BW_REQ: -- return "MHI_CB_BW_REQ"; --+ case MHI_CB_EE_SBL_MODE: --+ return "MHI_CB_EE_SBL_MODE"; -- default: -- return "UNKNOWN"; -- } --@@ -336,27 +366,14 @@ static void ath11k_mhi_op_status_cb(stru -- if (!(test_bit(ATH11K_FLAG_UNREGISTERING, &ab->dev_flags))) -- queue_work(ab->workqueue_aux, &ab->reset_work); -- break; --+ case MHI_CB_EE_SBL_MODE: --+ ath11k_mhi_qrtr_instance_set(mhi_cntrl); --+ break; -- default: -- break; -- } -- } -- ---static int ath11k_mhi_op_read_reg(struct mhi_controller *mhi_cntrl, --- void __iomem *addr, --- u32 *out) ---{ --- *out = readl(addr); --- --- return 0; ---} --- ---static void ath11k_mhi_op_write_reg(struct mhi_controller *mhi_cntrl, --- void __iomem *addr, --- u32 val) ---{ --- writel(val, addr); ---} --- -- static int ath11k_mhi_read_addr_from_dt(struct mhi_controller *mhi_ctrl) -- { -- struct device_node *np; ----- a/drivers/net/wireless/ath/ath11k/mhi.h --+++ b/drivers/net/wireless/ath/ath11k/mhi.h --@@ -16,6 +16,9 @@ -- #define MHICTRL 0x38 -- #define MHICTRL_RESET_MASK 0x2 -- --+#define BHI_ERRDBG2 0x38 --+#define QRTR_INSTANCE_MASK GENMASK(7, 0) --+ -- int ath11k_mhi_start(struct ath11k_pci *ar_pci); -- void ath11k_mhi_stop(struct ath11k_pci *ar_pci); -- int ath11k_mhi_register(struct ath11k_pci *ar_pci); ----- a/drivers/net/wireless/ath/ath11k/pci.c --+++ b/drivers/net/wireless/ath/ath11k/pci.c --@@ -370,13 +370,20 @@ static void ath11k_pci_sw_reset(struct a -- static void ath11k_pci_init_qmi_ce_config(struct ath11k_base *ab) -- { -- struct ath11k_qmi_ce_cfg *cfg = &ab->qmi.ce_cfg; --+ struct ath11k_pci *ab_pci = ath11k_pci_priv(ab); --+ struct pci_bus *bus = ab_pci->pdev->bus; -- -- cfg->tgt_ce = ab->hw_params.target_ce_config; -- cfg->tgt_ce_len = ab->hw_params.target_ce_count; -- -- cfg->svc_to_ce_map = ab->hw_params.svc_to_ce_map; -- cfg->svc_to_ce_map_len = ab->hw_params.svc_to_ce_map_len; --- ab->qmi.service_ins_id = ab->hw_params.qmi_service_ins_id; --+ --+ if (ab->hw_rev == ATH11K_HW_QCN9074_HW10) { --+ ab->qmi.service_ins_id = ab->hw_params.qmi_service_ins_id + --+ (((pci_domain_nr(bus) & 0xF) << 4) | (bus->number & 0xF)); --+ } else --+ ab->qmi.service_ins_id = ab->hw_params.qmi_service_ins_id; -- -- ath11k_ce_get_shadow_config(ab, &cfg->shadow_reg_v2, -- &cfg->shadow_reg_v2_len); -diff --git a/package/kernel/mac80211/patches/ath11k/900-ath11k-control-thermal-support-via-symbol.patch b/package/kernel/mac80211/patches/ath11k/900-ath11k-control-thermal-support-via-symbol.patch -deleted file mode 100644 -index 60720a721e..0000000000 ---- a/package/kernel/mac80211/patches/ath11k/900-ath11k-control-thermal-support-via-symbol.patch -+++ /dev/null -@@ -1,66 +0,0 @@ --From 703d6551f71e7290619d6effe2a25a64e10538b7 Mon Sep 17 00:00:00 2001 --From: Robert Marko --Date: Thu, 15 Dec 2022 12:20:52 +0100 --Subject: [PATCH] ath11k: control thermal support via symbol -- --Currently, thermal support will get built if CONFIG_THERMAL is reachable, --however this is not suitable for OpenWrt as with ALL_KMODS being set to y --ATH11K_THERMAL wont get selected and so hwmon and thermal kmods wont get --pulled in resulting in a build-failure. -- --So, to avoid that, lets do what is already done for ath10k and add a --config symbol into backports for enabling thermal support. -- --Signed-off-by: Robert Marko ----- -- drivers/net/wireless/ath/ath11k/Kconfig | 7 +++++++ -- drivers/net/wireless/ath/ath11k/Makefile | 2 +- -- drivers/net/wireless/ath/ath11k/thermal.h | 2 +- -- local-symbols | 1 + -- 4 files changed, 10 insertions(+), 2 deletions(-) -- ----- a/drivers/net/wireless/ath/ath11k/Kconfig --+++ b/drivers/net/wireless/ath/ath11k/Kconfig --@@ -61,3 +61,10 @@ config ATH11K_SPECTRAL -- Enable ath11k spectral scan support -- -- Say Y to enable access to the FFT/spectral data via debugfs. --+ --+config ATH11K_THERMAL --+ bool "ath11k thermal sensors and throttling support" --+ depends on ATH11K --+ depends on THERMAL --+ help --+ Enable ath11k thermal sensors and throttling support. ----- a/drivers/net/wireless/ath/ath11k/Makefile --+++ b/drivers/net/wireless/ath/ath11k/Makefile --@@ -22,7 +22,7 @@ ath11k-y += core.o \ -- ath11k-$(CPTCFG_ATH11K_DEBUGFS) += debugfs.o debugfs_htt_stats.o debugfs_sta.o -- ath11k-$(CPTCFG_NL80211_TESTMODE) += testmode.o -- ath11k-$(CPTCFG_ATH11K_TRACING) += trace.o ---ath11k-$(CONFIG_THERMAL) += thermal.o --+ath11k-$(CPTCFG_ATH11K_THERMAL) += thermal.o -- ath11k-$(CPTCFG_ATH11K_SPECTRAL) += spectral.o -- ath11k-$(CONFIG_PM) += wow.o -- ----- a/drivers/net/wireless/ath/ath11k/thermal.h --+++ b/drivers/net/wireless/ath/ath11k/thermal.h --@@ -25,7 +25,7 @@ struct ath11k_thermal { -- int temperature; -- }; -- ---#if IS_REACHABLE(CONFIG_THERMAL) --+#if IS_REACHABLE(CPTCFG_ATH11K_THERMAL) -- int ath11k_thermal_register(struct ath11k_base *sc); -- void ath11k_thermal_unregister(struct ath11k_base *sc); -- int ath11k_thermal_set_throttling(struct ath11k *ar, u32 throttle_state); ----- a/local-symbols --+++ b/local-symbols --@@ -174,6 +174,7 @@ ATH11K_DEBUG= -- ATH11K_DEBUGFS= -- ATH11K_TRACING= -- ATH11K_SPECTRAL= --+ATH11K_THERMAL= -- WLAN_VENDOR_ATMEL= -- ATMEL= -- PCI_ATMEL= -diff --git a/package/kernel/mac80211/patches/ath11k/901-wifi-ath11k-pci-fix-compilation-in-5.16-and-older.patch b/package/kernel/mac80211/patches/ath11k/901-wifi-ath11k-pci-fix-compilation-in-5.16-and-older.patch -deleted file mode 100644 -index 7215656389..0000000000 ---- a/package/kernel/mac80211/patches/ath11k/901-wifi-ath11k-pci-fix-compilation-in-5.16-and-older.patch -+++ /dev/null -@@ -1,29 +0,0 @@ --From 04178918e7f6b5f34dde81ec79ee8a1ccace3be3 Mon Sep 17 00:00:00 2001 --From: Robert Marko --Date: Mon, 17 Oct 2022 11:45:03 +0200 --Subject: [PATCH] wifi: ath11k: pci: fix compilation in 5.16 and older -- --Commit ("genirq/msi, treewide: Use a named struct for PCI/MSI attributes") --changed the msi_desc structure a bit, however that is only available in --kernels 5.17 and newer, so check for kernel version to allow compilation --in 5.16 and older. -- --Signed-off-by: Robert Marko ----- -- drivers/net/wireless/ath/ath11k/pci.c | 4 ++++ -- 1 file changed, 4 insertions(+) -- ----- a/drivers/net/wireless/ath/ath11k/pci.c --+++ b/drivers/net/wireless/ath/ath11k/pci.c --@@ -458,7 +458,11 @@ static int ath11k_pci_alloc_msi(struct a -- pci_read_config_dword(pci_dev, pci_dev->msi_cap + PCI_MSI_ADDRESS_LO, -- &ab->pci.msi.addr_lo); -- --+#if (LINUX_VERSION_CODE > KERNEL_VERSION(5, 17, 0)) -- if (msi_desc->pci.msi_attrib.is_64) { --+#else --+ if (msi_desc->msi_attrib.is_64) { --+#endif -- pci_read_config_dword(pci_dev, pci_dev->msi_cap + PCI_MSI_ADDRESS_HI, -- &ab->pci.msi.addr_hi); -- } else { -diff --git a/package/kernel/mac80211/patches/ath11k/902-ath11k-Disable-coldboot-calibration-for-IPQ8074.patch b/package/kernel/mac80211/patches/ath11k/902-ath11k-Disable-coldboot-calibration-for-IPQ8074.patch -deleted file mode 100644 -index 5454fa75e4..0000000000 ---- a/package/kernel/mac80211/patches/ath11k/902-ath11k-Disable-coldboot-calibration-for-IPQ8074.patch -+++ /dev/null -@@ -1,24 +0,0 @@ --From dd3b9c59cfa1e9e0b73a575f4646be905691eaef Mon Sep 17 00:00:00 2001 --From: Robert Marko --Date: Sat, 16 Oct 2021 19:34:10 +0200 --Subject: [PATCH 241/241] ath11k: Disable coldboot calibration for IPQ8074 -- --There is a bug with the remoteproc reset after coldboot calibration, --so until that is resolved disabled it to allow using the radio. -- --Signed-off-by: Robert Marko ----- -- drivers/net/wireless/ath/ath11k/core.c | 2 +- -- 1 file changed, 1 insertion(+), 1 deletion(-) -- ----- a/drivers/net/wireless/ath/ath11k/core.c --+++ b/drivers/net/wireless/ath/ath11k/core.c --@@ -86,7 +86,7 @@ static const struct ath11k_hw_params ath -- .supports_shadow_regs = false, -- .idle_ps = false, -- .supports_sta_ps = false, --- .cold_boot_calib = true, --+ .cold_boot_calib = false, -- .cbcal_restart_fw = true, -- .fw_mem_mode = 0, -- .num_vdevs = 16 + 1, -diff --git a/package/kernel/mac80211/patches/ath11k/903-ath11k-support-setting-FW-memory-mode-via-DT.patch b/package/kernel/mac80211/patches/ath11k/903-ath11k-support-setting-FW-memory-mode-via-DT.patch -deleted file mode 100644 -index 22c2493ca9..0000000000 ---- a/package/kernel/mac80211/patches/ath11k/903-ath11k-support-setting-FW-memory-mode-via-DT.patch -+++ /dev/null -@@ -1,74 +0,0 @@ --From fb1c40c225cbc413d82c872dd8c8af3469b2b921 Mon Sep 17 00:00:00 2001 --From: Robert Marko --Date: Fri, 16 Dec 2022 17:17:52 +0100 --Subject: [PATCH] ath11k: support setting FW memory mode via DT -- --ath11k is really memory intensive for devices with less that 1GB of RAM, --so lets allow saving a significant amount of memory by setting the FW to --Mode-1 via DTS for devices that need it. -- --However the drawback is reduced number of VDEV-s and peers which is a --reasonable tradeoff. -- --Mode-2 allows for further reduction, but it has further restrictions. -- --While we are here, lets add a print to be able to easily determine what --FW memory mode is being used. -- --Signed-off-by: Robert Marko ----- -- drivers/net/wireless/ath/ath11k/core.c | 28 ++++++++++++++++++++++++-- -- 1 file changed, 26 insertions(+), 2 deletions(-) -- ----- a/drivers/net/wireless/ath/ath11k/core.c --+++ b/drivers/net/wireless/ath/ath11k/core.c --@@ -36,7 +36,7 @@ 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_hw_params ath11k_hw_params[] = { --+static struct ath11k_hw_params ath11k_hw_params[] = { -- { -- .hw_rev = ATH11K_HW_IPQ8074, -- .name = "ipq8074 hw2.0", --@@ -1953,7 +1953,8 @@ static void ath11k_core_reset(struct wor -- static int ath11k_init_hw_params(struct ath11k_base *ab) -- { -- const struct ath11k_hw_params *hw_params = NULL; --- int i; --+ u32 fw_mem_mode; --+ int i, ret; -- -- for (i = 0; i < ARRAY_SIZE(ath11k_hw_params); i++) { -- hw_params = &ath11k_hw_params[i]; --@@ -1969,7 +1970,30 @@ static int ath11k_init_hw_params(struct -- -- ab->hw_params = *hw_params; -- --+ ret = of_property_read_u32(ab->dev->of_node, --+ "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) { --+ ab->hw_params.fw_mem_mode = 1; --+ ab->hw_params.num_vdevs = 8; --+ ab->hw_params.num_peers = 128; --+ } else if (fw_mem_mode == 2) { --+ ab->hw_params.fw_mem_mode = 2; --+ ab->hw_params.num_vdevs = 8; --+ ab->hw_params.num_peers = 128; --+ ab->hw_params.cold_boot_calib = false; --+ } else --+ ath11k_info(ab, "Unsupported FW memory mode: %u\n", fw_mem_mode); --+ } --+ -- ath11k_info(ab, "%s\n", ab->hw_params.name); --+ ath11k_info(ab, "FW memory mode: %d\n", ab->hw_params.fw_mem_mode); -- -- return 0; -- } -diff --git a/package/kernel/mac80211/patches/ath11k/905-ath11k-remove-intersection-support-for-regulatory-ru.patch b/package/kernel/mac80211/patches/ath11k/905-ath11k-remove-intersection-support-for-regulatory-ru.patch -deleted file mode 100644 -index b0ceb00ba0..0000000000 ---- a/package/kernel/mac80211/patches/ath11k/905-ath11k-remove-intersection-support-for-regulatory-ru.patch -+++ /dev/null -@@ -1,317 +0,0 @@ --From abdd0985a36189ef2cc0e393b027276e86137ace Mon Sep 17 00:00:00 2001 --From: Aditya Kumar Singh --Date: Tue, 11 Apr 2023 20:08:49 +0200 --Subject: [PATCH] ath11k: remove intersection support for regulatory rules -- --Currently, regulatory rules from new country settings is intersected with --rules from default country settings(during initialisation) in order to prevent --users to bypass their default country settings such as power limits, channel --flags, etc. -- --However, the country setting in the BDF will take higher higher precendence --and FW will protect it. Therefore, there is no need to handle intersection --on the driver side now. -- --Remove regulatory rules intersection logic support. -- --Signed-off-by: Aditya Kumar Singh ----- -- drivers/net/wireless/ath/ath11k/reg.c | 168 +++----------------------- -- drivers/net/wireless/ath/ath11k/reg.h | 2 +- -- drivers/net/wireless/ath/ath11k/wmi.c | 24 +--- -- 3 files changed, 16 insertions(+), 178 deletions(-) -- ----- a/drivers/net/wireless/ath/ath11k/reg.c --+++ b/drivers/net/wireless/ath/ath11k/reg.c --@@ -352,129 +352,6 @@ static u32 ath11k_map_fw_reg_flags(u16 r -- return flags; -- } -- ---static bool ---ath11k_reg_can_intersect(struct ieee80211_reg_rule *rule1, --- struct ieee80211_reg_rule *rule2) ---{ --- u32 start_freq1, end_freq1; --- u32 start_freq2, end_freq2; --- --- start_freq1 = rule1->freq_range.start_freq_khz; --- start_freq2 = rule2->freq_range.start_freq_khz; --- --- end_freq1 = rule1->freq_range.end_freq_khz; --- end_freq2 = rule2->freq_range.end_freq_khz; --- --- if ((start_freq1 >= start_freq2 && --- start_freq1 < end_freq2) || --- (start_freq2 > start_freq1 && --- start_freq2 < end_freq1)) --- return true; --- --- /* TODO: Should we restrict intersection feasibility --- * based on min bandwidth of the intersected region also, --- * say the intersected rule should have a min bandwidth --- * of 20MHz? --- */ --- --- return false; ---} --- ---static void ath11k_reg_intersect_rules(struct ieee80211_reg_rule *rule1, --- struct ieee80211_reg_rule *rule2, --- struct ieee80211_reg_rule *new_rule) ---{ --- u32 start_freq1, end_freq1; --- u32 start_freq2, end_freq2; --- u32 freq_diff, max_bw; --- --- start_freq1 = rule1->freq_range.start_freq_khz; --- start_freq2 = rule2->freq_range.start_freq_khz; --- --- end_freq1 = rule1->freq_range.end_freq_khz; --- end_freq2 = rule2->freq_range.end_freq_khz; --- --- new_rule->freq_range.start_freq_khz = max_t(u32, start_freq1, --- start_freq2); --- new_rule->freq_range.end_freq_khz = min_t(u32, end_freq1, end_freq2); --- --- freq_diff = new_rule->freq_range.end_freq_khz - --- new_rule->freq_range.start_freq_khz; --- max_bw = min_t(u32, rule1->freq_range.max_bandwidth_khz, --- rule2->freq_range.max_bandwidth_khz); --- new_rule->freq_range.max_bandwidth_khz = min_t(u32, max_bw, freq_diff); --- --- new_rule->power_rule.max_antenna_gain = --- min_t(u32, rule1->power_rule.max_antenna_gain, --- rule2->power_rule.max_antenna_gain); --- --- new_rule->power_rule.max_eirp = min_t(u32, rule1->power_rule.max_eirp, --- rule2->power_rule.max_eirp); --- --- /* Use the flags of both the rules */ --- new_rule->flags = rule1->flags | rule2->flags; --- --- /* To be safe, lts use the max cac timeout of both rules */ --- new_rule->dfs_cac_ms = max_t(u32, rule1->dfs_cac_ms, --- rule2->dfs_cac_ms); ---} --- ---static struct ieee80211_regdomain * ---ath11k_regd_intersect(struct ieee80211_regdomain *default_regd, --- struct ieee80211_regdomain *curr_regd) ---{ --- u8 num_old_regd_rules, num_curr_regd_rules, num_new_regd_rules; --- struct ieee80211_reg_rule *old_rule, *curr_rule, *new_rule; --- struct ieee80211_regdomain *new_regd = NULL; --- u8 i, j, k; --- --- num_old_regd_rules = default_regd->n_reg_rules; --- num_curr_regd_rules = curr_regd->n_reg_rules; --- num_new_regd_rules = 0; --- --- /* Find the number of intersecting rules to allocate new regd memory */ --- for (i = 0; i < num_old_regd_rules; i++) { --- old_rule = default_regd->reg_rules + i; --- for (j = 0; j < num_curr_regd_rules; j++) { --- curr_rule = curr_regd->reg_rules + j; --- --- if (ath11k_reg_can_intersect(old_rule, curr_rule)) --- num_new_regd_rules++; --- } --- } --- --- if (!num_new_regd_rules) --- return NULL; --- --- new_regd = kzalloc(sizeof(*new_regd) + (num_new_regd_rules * --- sizeof(struct ieee80211_reg_rule)), --- GFP_ATOMIC); --- --- if (!new_regd) --- return NULL; --- --- /* We set the new country and dfs region directly and only trim --- * the freq, power, antenna gain by intersecting with the --- * default regdomain. Also MAX of the dfs cac timeout is selected. --- */ --- new_regd->n_reg_rules = num_new_regd_rules; --- memcpy(new_regd->alpha2, curr_regd->alpha2, sizeof(new_regd->alpha2)); --- new_regd->dfs_region = curr_regd->dfs_region; --- new_rule = new_regd->reg_rules; --- --- for (i = 0, k = 0; i < num_old_regd_rules; i++) { --- old_rule = default_regd->reg_rules + i; --- for (j = 0; j < num_curr_regd_rules; j++) { --- curr_rule = curr_regd->reg_rules + j; --- --- if (ath11k_reg_can_intersect(old_rule, curr_rule)) --- ath11k_reg_intersect_rules(old_rule, curr_rule, --- (new_rule + k++)); --- } --- } --- return new_regd; ---} --- -- static const char * -- ath11k_reg_get_regdom_str(enum nl80211_dfs_regions dfs_region) -- { --@@ -609,9 +486,9 @@ ath11k_reg_update_weather_radar_band(str -- -- struct ieee80211_regdomain * -- ath11k_reg_build_regd(struct ath11k_base *ab, --- struct cur_regulatory_info *reg_info, bool intersect) --+ struct cur_regulatory_info *reg_info) -- { --- struct ieee80211_regdomain *tmp_regd, *default_regd, *new_regd = NULL; --+ struct ieee80211_regdomain *new_regd = NULL; -- struct cur_reg_rule *reg_rule; -- u8 i = 0, j = 0, k = 0; -- u8 num_rules; --@@ -628,26 +505,26 @@ ath11k_reg_build_regd(struct ath11k_base -- num_rules += reg_info->num_6ghz_rules_ap[WMI_REG_INDOOR_AP]; -- -- if (!num_rules) --- goto ret; --+ return new_regd; -- -- /* Add max additional rules to accommodate weather radar band */ -- if (reg_info->dfs_region == ATH11K_DFS_REG_ETSI) -- num_rules += 2; -- --- tmp_regd = kzalloc(sizeof(*tmp_regd) + --+ new_regd = kzalloc(sizeof(*new_regd) + -- (num_rules * sizeof(struct ieee80211_reg_rule)), -- GFP_ATOMIC); --- if (!tmp_regd) --- goto ret; --+ if (!new_regd) --+ return new_regd; -- --- memcpy(tmp_regd->alpha2, reg_info->alpha2, REG_ALPHA2_LEN + 1); --+ memcpy(new_regd->alpha2, reg_info->alpha2, REG_ALPHA2_LEN + 1); -- memcpy(alpha2, reg_info->alpha2, REG_ALPHA2_LEN + 1); -- alpha2[2] = '\0'; --- tmp_regd->dfs_region = ath11k_map_fw_dfs_region(reg_info->dfs_region); --+ new_regd->dfs_region = ath11k_map_fw_dfs_region(reg_info->dfs_region); -- -- ath11k_dbg(ab, ATH11K_DBG_REG, -- "Country %s, CFG Regdomain %s FW Regdomain %d, num_reg_rules %d\n", --- alpha2, ath11k_reg_get_regdom_str(tmp_regd->dfs_region), --+ alpha2, ath11k_reg_get_regdom_str(new_regd->dfs_region), -- reg_info->dfs_region, num_rules); -- /* Update reg_rules[] below. Firmware is expected to -- * send these rules in order(2 GHz rules first and then 5 GHz) --@@ -686,7 +563,7 @@ ath11k_reg_build_regd(struct ath11k_base -- -- flags |= ath11k_map_fw_reg_flags(reg_rule->flags); -- --- ath11k_reg_update_rule(tmp_regd->reg_rules + i, --+ ath11k_reg_update_rule(new_regd->reg_rules + i, -- reg_rule->start_freq, -- reg_rule->end_freq, max_bw, -- reg_rule->ant_gain, reg_rule->reg_power, --@@ -701,7 +578,7 @@ ath11k_reg_build_regd(struct ath11k_base -- reg_info->dfs_region == ATH11K_DFS_REG_ETSI && -- (reg_rule->end_freq > ETSI_WEATHER_RADAR_BAND_LOW && -- reg_rule->start_freq < ETSI_WEATHER_RADAR_BAND_HIGH)){ --- ath11k_reg_update_weather_radar_band(ab, tmp_regd, --+ ath11k_reg_update_weather_radar_band(ab, new_regd, -- reg_rule, &i, -- flags, max_bw); -- continue; --@@ -712,37 +589,20 @@ ath11k_reg_build_regd(struct ath11k_base -- "\t%d. (%d - %d @ %d) (%d, %d) (%d ms) (FLAGS %d) (%d, %d)\n", -- i + 1, reg_rule->start_freq, reg_rule->end_freq, -- max_bw, reg_rule->ant_gain, reg_rule->reg_power, --- tmp_regd->reg_rules[i].dfs_cac_ms, flags, --+ new_regd->reg_rules[i].dfs_cac_ms, flags, -- reg_rule->psd_flag, reg_rule->psd_eirp); -- } else { -- ath11k_dbg(ab, ATH11K_DBG_REG, -- "\t%d. (%d - %d @ %d) (%d, %d) (%d ms) (FLAGS %d)\n", -- i + 1, reg_rule->start_freq, reg_rule->end_freq, -- max_bw, reg_rule->ant_gain, reg_rule->reg_power, --- tmp_regd->reg_rules[i].dfs_cac_ms, --+ new_regd->reg_rules[i].dfs_cac_ms, -- flags); -- } -- } -- --- tmp_regd->n_reg_rules = i; --- --- if (intersect) { --- default_regd = ab->default_regd[reg_info->phy_id]; --- --- /* Get a new regd by intersecting the received regd with --- * our default regd. --- */ --- new_regd = ath11k_regd_intersect(default_regd, tmp_regd); --- kfree(tmp_regd); --- if (!new_regd) { --- ath11k_warn(ab, "Unable to create intersected regdomain\n"); --- goto ret; --- } --- } else { --- new_regd = tmp_regd; --- } --+ new_regd->n_reg_rules = i; -- ---ret: -- return new_regd; -- } -- ----- a/drivers/net/wireless/ath/ath11k/reg.h --+++ b/drivers/net/wireless/ath/ath11k/reg.h --@@ -30,7 +30,7 @@ void ath11k_reg_free(struct ath11k_base -- void ath11k_regd_update_work(struct work_struct *work); -- struct ieee80211_regdomain * -- ath11k_reg_build_regd(struct ath11k_base *ab, --- struct cur_regulatory_info *reg_info, bool intersect); --+ struct cur_regulatory_info *reg_info); -- int ath11k_regd_update(struct ath11k *ar); -- int ath11k_reg_update_chan_list(struct ath11k *ar, bool wait); -- #endif ----- a/drivers/net/wireless/ath/ath11k/wmi.c --+++ b/drivers/net/wireless/ath/ath11k/wmi.c --@@ -6996,24 +6996,12 @@ static void ath11k_wmi_htc_tx_complete(s -- wake_up(&wmi->tx_ce_desc_wq); -- } -- ---static bool ath11k_reg_is_world_alpha(char *alpha) ---{ --- if (alpha[0] == '0' && alpha[1] == '0') --- return true; --- --- if (alpha[0] == 'n' && alpha[1] == 'a') --- return true; --- --- return false; ---} --- -- static int ath11k_reg_chan_list_event(struct ath11k_base *ab, -- struct sk_buff *skb, -- enum wmi_reg_chan_list_cmd_type id) -- { -- struct cur_regulatory_info *reg_info = NULL; -- struct ieee80211_regdomain *regd = NULL; --- bool intersect = false; -- int ret = 0, pdev_idx, i, j; -- struct ath11k *ar; -- --@@ -7075,17 +7063,7 @@ static int ath11k_reg_chan_list_event(st -- (char *)reg_info->alpha2, 2)) -- goto mem_free; -- --- /* Intersect new rules with default regd if a new country setting was --- * requested, i.e a default regd was already set during initialization --- * and the regd coming from this event has a valid country info. --- */ --- if (ab->default_regd[pdev_idx] && --- !ath11k_reg_is_world_alpha((char *) --- ab->default_regd[pdev_idx]->alpha2) && --- !ath11k_reg_is_world_alpha((char *)reg_info->alpha2)) --- intersect = true; --- --- regd = ath11k_reg_build_regd(ab, reg_info, intersect); --+ regd = ath11k_reg_build_regd(ab, reg_info); -- if (!regd) { -- ath11k_warn(ab, "failed to build regd from reg_info\n"); -- goto fallback; -diff --git a/package/kernel/mac80211/patches/ath5k/201-ath5k-WAR-for-AR71xx-PCI-bug.patch b/package/kernel/mac80211/patches/ath5k/201-ath5k-WAR-for-AR71xx-PCI-bug.patch -deleted file mode 100644 -index 4fc97dfaec..0000000000 ---- a/package/kernel/mac80211/patches/ath5k/201-ath5k-WAR-for-AR71xx-PCI-bug.patch -+++ /dev/null -@@ -1,38 +0,0 @@ ----- a/drivers/net/wireless/ath/ath5k/initvals.c --+++ b/drivers/net/wireless/ath/ath5k/initvals.c --@@ -62,8 +62,14 @@ static const struct ath5k_ini ar5210_ini -- { AR5K_IMR, 0 }, -- { AR5K_IER, AR5K_IER_DISABLE }, -- { AR5K_BSR, 0, AR5K_INI_READ }, --+#if !defined(CONFIG_ATHEROS_AR71XX) && !defined(CONFIG_ATH79) -- { AR5K_TXCFG, AR5K_DMASIZE_128B }, -- { AR5K_RXCFG, AR5K_DMASIZE_128B }, --+#else --+ /* WAR for AR71xx PCI bug */ --+ { AR5K_TXCFG, AR5K_DMASIZE_128B }, --+ { AR5K_RXCFG, AR5K_DMASIZE_4B }, --+#endif -- { AR5K_CFG, AR5K_INIT_CFG }, -- { AR5K_TOPS, 8 }, -- { AR5K_RXNOFRM, 8 }, ----- a/drivers/net/wireless/ath/ath5k/dma.c --+++ b/drivers/net/wireless/ath/ath5k/dma.c --@@ -854,10 +854,18 @@ ath5k_hw_dma_init(struct ath5k_hw *ah) -- * guess we can tweak it and see how it goes ;-) -- */ -- if (ah->ah_version != AR5K_AR5210) { --+#if !defined(CONFIG_ATHEROS_AR71XX) && !defined(CONFIG_ATH79) -- AR5K_REG_WRITE_BITS(ah, AR5K_TXCFG, -- AR5K_TXCFG_SDMAMR, AR5K_DMASIZE_128B); -- AR5K_REG_WRITE_BITS(ah, AR5K_RXCFG, -- AR5K_RXCFG_SDMAMW, AR5K_DMASIZE_128B); --+#else --+ /* WAR for AR71xx PCI bug */ --+ AR5K_REG_WRITE_BITS(ah, AR5K_TXCFG, --+ AR5K_TXCFG_SDMAMR, AR5K_DMASIZE_128B); --+ AR5K_REG_WRITE_BITS(ah, AR5K_RXCFG, --+ AR5K_RXCFG_SDMAMW, AR5K_DMASIZE_4B); --+#endif -- } -- -- /* Pre-enable interrupts on 5211/5212*/ -diff --git a/package/kernel/mac80211/patches/ath5k/411-ath5k_allow_adhoc_and_ap.patch b/package/kernel/mac80211/patches/ath5k/411-ath5k_allow_adhoc_and_ap.patch -deleted file mode 100644 -index 1df4aab57e..0000000000 ---- a/package/kernel/mac80211/patches/ath5k/411-ath5k_allow_adhoc_and_ap.patch -+++ /dev/null -@@ -1,46 +0,0 @@ ----- a/drivers/net/wireless/ath/ath5k/mac80211-ops.c --+++ b/drivers/net/wireless/ath/ath5k/mac80211-ops.c --@@ -86,13 +86,8 @@ ath5k_add_interface(struct ieee80211_hw -- goto end; -- } -- --- /* Don't allow other interfaces if one ad-hoc is configured. --- * TODO: Fix the problems with ad-hoc and multiple other interfaces. --- * We would need to operate the HW in ad-hoc mode to allow TSF updates --- * for the IBSS, but this breaks with additional AP or STA interfaces --- * at the moment. */ --- if (ah->num_adhoc_vifs || --- (ah->nvifs && vif->type == NL80211_IFTYPE_ADHOC)) { --+ /* Don't allow more than one ad-hoc interface */ --+ if (ah->num_adhoc_vifs && vif->type == NL80211_IFTYPE_ADHOC) { -- ATH5K_ERR(ah, "Only one single ad-hoc interface is allowed.\n"); -- ret = -ELNRNG; -- goto end; ----- a/drivers/net/wireless/ath/ath5k/base.c --+++ b/drivers/net/wireless/ath/ath5k/base.c --@@ -2009,7 +2009,7 @@ ath5k_beacon_send(struct ath5k_hw *ah) -- } -- -- if ((ah->opmode == NL80211_IFTYPE_AP && ah->num_ap_vifs + --- ah->num_mesh_vifs > 1) || --+ ah->num_adhoc_vifs + ah->num_mesh_vifs > 1) || -- ah->opmode == NL80211_IFTYPE_MESH_POINT) { -- u64 tsf = ath5k_hw_get_tsf64(ah); -- u32 tsftu = TSF_TO_TU(tsf); --@@ -2095,7 +2095,7 @@ ath5k_beacon_update_timers(struct ath5k_ -- -- intval = ah->bintval & AR5K_BEACON_PERIOD; -- if (ah->opmode == NL80211_IFTYPE_AP && ah->num_ap_vifs --- + ah->num_mesh_vifs > 1) { --+ + ah->num_adhoc_vifs + ah->num_mesh_vifs > 1) { -- intval /= ATH_BCBUF; /* staggered multi-bss beacons */ -- if (intval < 15) -- ATH5K_WARN(ah, "intval %u is too low, min 15\n", --@@ -2561,6 +2561,7 @@ static const struct ieee80211_iface_limi -- BIT(NL80211_IFTYPE_MESH_POINT) | -- #endif -- BIT(NL80211_IFTYPE_AP) }, --+ { .max = 1, .types = BIT(NL80211_IFTYPE_ADHOC) }, -- }; -- -- static const struct ieee80211_iface_combination if_comb = { -diff --git a/package/kernel/mac80211/patches/ath5k/420-ath5k_disable_fast_cc.patch b/package/kernel/mac80211/patches/ath5k/420-ath5k_disable_fast_cc.patch -deleted file mode 100644 -index 414f49508f..0000000000 ---- a/package/kernel/mac80211/patches/ath5k/420-ath5k_disable_fast_cc.patch -+++ /dev/null -@@ -1,18 +0,0 @@ ----- a/drivers/net/wireless/ath/ath5k/reset.c --+++ b/drivers/net/wireless/ath/ath5k/reset.c --@@ -1154,6 +1154,7 @@ ath5k_hw_reset(struct ath5k_hw *ah, enum -- tsf_lo = 0; -- mode = 0; -- --+#if 0 -- /* -- * Sanity check for fast flag -- * Fast channel change only available --@@ -1161,6 +1162,7 @@ ath5k_hw_reset(struct ath5k_hw *ah, enum -- */ -- if (fast && (ah->ah_radio != AR5K_RF2413) && -- (ah->ah_radio != AR5K_RF5413)) --+#endif -- fast = false; -- -- /* Disable sleep clock operation -diff --git a/package/kernel/mac80211/patches/ath5k/430-add_ath5k_platform.patch b/package/kernel/mac80211/patches/ath5k/430-add_ath5k_platform.patch -deleted file mode 100644 -index b213e2a819..0000000000 ---- a/package/kernel/mac80211/patches/ath5k/430-add_ath5k_platform.patch -+++ /dev/null -@@ -1,33 +0,0 @@ ----- /dev/null --+++ b/include/linux/ath5k_platform.h --@@ -0,0 +1,30 @@ --+/* --+ * Copyright (c) 2008 Atheros Communications Inc. --+ * Copyright (c) 2009 Gabor Juhos --+ * Copyright (c) 2009 Imre Kaloz --+ * Copyright (c) 2010 Daniel Golle --+ * --+ * 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_ATH5K_PLATFORM_H --+#define _LINUX_ATH5K_PLATFORM_H --+ --+#define ATH5K_PLAT_EEP_MAX_WORDS 2048 --+ --+struct ath5k_platform_data { --+ u16 *eeprom_data; --+ u8 *macaddr; --+}; --+ --+#endif /* _LINUX_ATH5K_PLATFORM_H */ -diff --git a/package/kernel/mac80211/patches/ath5k/432-ath5k_add_pciids.patch b/package/kernel/mac80211/patches/ath5k/432-ath5k_add_pciids.patch -deleted file mode 100644 -index bd0e6707a5..0000000000 ---- a/package/kernel/mac80211/patches/ath5k/432-ath5k_add_pciids.patch -+++ /dev/null -@@ -1,11 +0,0 @@ ----- a/drivers/net/wireless/ath/ath5k/pci.c --+++ b/drivers/net/wireless/ath/ath5k/pci.c --@@ -47,6 +47,8 @@ static const struct pci_device_id ath5k_ -- { PCI_VDEVICE(ATHEROS, 0x001b) }, /* 5413 Eagle */ -- { PCI_VDEVICE(ATHEROS, 0x001c) }, /* PCI-E cards */ -- { PCI_VDEVICE(ATHEROS, 0x001d) }, /* 2417 Nala */ --+ { PCI_VDEVICE(ATHEROS, 0xff16) }, /* 2413,2414 sx76x on lantiq_danube */ --+ { PCI_VDEVICE(ATHEROS, 0xff1a) }, /* 2417 arv45xx on lantiq_danube */ -- { PCI_VDEVICE(ATHEROS, 0xff1b) }, /* AR5BXB63 */ -- { 0 } -- }; -diff --git a/package/kernel/mac80211/patches/ath5k/440-ath5k_channel_bw_debugfs.patch b/package/kernel/mac80211/patches/ath5k/440-ath5k_channel_bw_debugfs.patch -deleted file mode 100644 -index a63f0c881b..0000000000 ---- a/package/kernel/mac80211/patches/ath5k/440-ath5k_channel_bw_debugfs.patch -+++ /dev/null -@@ -1,142 +0,0 @@ --This adds a bwmode debugfs file which can be used to set alternate --channel operating bandwidths. Only tested with AR5413 and only at --5 and 20 mhz channels. -- --Signed-off-by: Pat Erley ----- --Other devices will need to be added to the switch in write_file_bwmode -- --drivers/net/wireless/ath/ath5k/debug.c | 86 ++++++++++++++++++++++++++++++++ -- 1 files changed, 86 insertions(+), 0 deletions(-) -- ----- a/drivers/net/wireless/ath/ath5k/debug.c --+++ b/drivers/net/wireless/ath/ath5k/debug.c --@@ -803,6 +803,97 @@ static const struct file_operations fops -- .llseek = default_llseek, -- }; -- --+/* debugfs: bwmode */ --+ --+static ssize_t read_file_bwmode(struct file *file, char __user *user_buf, --+ size_t count, loff_t *ppos) --+{ --+ struct ath5k_hw *ah = file->private_data; --+ char buf[15]; --+ unsigned int len = 0; --+ --+ int cur_ah_bwmode = ah->ah_bwmode_debug; --+ --+#define print_selected(MODE, LABEL) \ --+ if (cur_ah_bwmode == MODE) \ --+ len += snprintf(buf+len, sizeof(buf)-len, "[%s]", LABEL); \ --+ else \ --+ len += snprintf(buf+len, sizeof(buf)-len, "%s", LABEL); \ --+ len += snprintf(buf+len, sizeof(buf)-len, " "); --+ --+ print_selected(AR5K_BWMODE_5MHZ, "5"); --+ print_selected(AR5K_BWMODE_10MHZ, "10"); --+ print_selected(AR5K_BWMODE_DEFAULT, "20"); --+ print_selected(AR5K_BWMODE_40MHZ, "40"); --+#undef print_selected --+ --+ len += snprintf(buf+len, sizeof(buf)-len, "\n"); --+ --+ return simple_read_from_buffer(user_buf, count, ppos, buf, len); --+} --+ --+static ssize_t write_file_bwmode(struct file *file, --+ const char __user *userbuf, --+ size_t count, loff_t *ppos) --+{ --+ struct ath5k_hw *ah = file->private_data; --+ char buf[3]; --+ int bw = 20; --+ int tobwmode = AR5K_BWMODE_DEFAULT; --+ --+ if (copy_from_user(buf, userbuf, min(count, sizeof(buf)))) --+ return -EFAULT; --+ --+ /* TODO: Add check for active interface */ --+ --+ if(strncmp(buf, "5", 1) == 0 ) { --+ tobwmode = AR5K_BWMODE_5MHZ; --+ bw = 5; --+ } else if ( strncmp(buf, "10", 2) == 0 ) { --+ tobwmode = AR5K_BWMODE_10MHZ; --+ bw = 10; --+ } else if ( strncmp(buf, "20", 2) == 0 ) { --+ tobwmode = AR5K_BWMODE_DEFAULT; --+ bw = 20; --+ } else if ( strncmp(buf, "40", 2) == 0 ) { --+ tobwmode = AR5K_BWMODE_40MHZ; --+ bw = 40; --+ } else --+ return -EINVAL; --+ --+ ATH5K_INFO(ah, "Changing to %imhz channel width[%i]\n", --+ bw, tobwmode); --+ --+ switch (ah->ah_radio) { --+ /* TODO: only define radios that actually support 5/10mhz channels */ --+ case AR5K_RF5413: --+ case AR5K_RF5110: --+ case AR5K_RF5111: --+ case AR5K_RF5112: --+ case AR5K_RF2413: --+ case AR5K_RF2316: --+ case AR5K_RF2317: --+ case AR5K_RF2425: --+ if(ah->ah_bwmode_debug != tobwmode) { --+ mutex_lock(&ah->lock); --+ ah->ah_bwmode = tobwmode; --+ ah->ah_bwmode_debug = tobwmode; --+ mutex_unlock(&ah->lock); --+ } --+ break; --+ default: --+ return -EOPNOTSUPP; --+ } --+ return count; --+} --+ --+static const struct file_operations fops_bwmode = { --+ .read = read_file_bwmode, --+ .write = write_file_bwmode, --+ .open = simple_open, --+ .owner = THIS_MODULE, --+ .llseek = default_llseek, --+}; -- -- /* debugfs: queues etc */ -- --@@ -997,6 +1088,8 @@ ath5k_debug_init_device(struct ath5k_hw -- debugfs_create_file("queue", 0600, phydir, ah, &fops_queue); -- debugfs_create_bool("32khz_clock", 0600, phydir, -- &ah->ah_use_32khz_clock); --+ debugfs_create_file("bwmode", S_IWUSR | S_IRUSR, phydir, ah, --+ &fops_bwmode); -- } -- -- /* functions used in other places */ ----- a/drivers/net/wireless/ath/ath5k/ath5k.h --+++ b/drivers/net/wireless/ath/ath5k/ath5k.h --@@ -1372,6 +1372,7 @@ struct ath5k_hw { -- u8 ah_coverage_class; -- bool ah_ack_bitrate_high; -- u8 ah_bwmode; --+ u8 ah_bwmode_debug; -- bool ah_short_slot; -- -- /* Antenna Control */ ----- a/drivers/net/wireless/ath/ath5k/base.c --+++ b/drivers/net/wireless/ath/ath5k/base.c --@@ -465,6 +465,9 @@ ath5k_chan_set(struct ath5k_hw *ah, stru -- return -EINVAL; -- } -- --+ if (ah->ah_bwmode_debug != AR5K_BWMODE_DEFAULT) --+ ah->ah_bwmode = ah->ah_bwmode_debug; --+ -- /* -- * To switch channels clear any pending DMA operations; -- * wait long enough for the RX fifo to drain, reset the -diff --git a/package/kernel/mac80211/patches/ath9k/350-ath9k_hw-reset-AHB-WMAC-interface-on-AR91xx.patch b/package/kernel/mac80211/patches/ath9k/350-ath9k_hw-reset-AHB-WMAC-interface-on-AR91xx.patch -deleted file mode 100644 -index 3a0171d4a2..0000000000 ---- a/package/kernel/mac80211/patches/ath9k/350-ath9k_hw-reset-AHB-WMAC-interface-on-AR91xx.patch -+++ /dev/null -@@ -1,25 +0,0 @@ --From: Felix Fietkau --Date: Sat, 9 Jul 2016 15:25:24 +0200 --Subject: [PATCH] ath9k_hw: reset AHB-WMAC interface on AR91xx -- --Should fix a few stability issues -- --Signed-off-by: Felix Fietkau ----- -- ----- a/drivers/net/wireless/ath/ath9k/hw.c --+++ b/drivers/net/wireless/ath/ath9k/hw.c --@@ -1434,8 +1434,12 @@ static bool ath9k_hw_set_reset(struct at -- if (!AR_SREV_9100(ah)) -- REG_WRITE(ah, AR_RC, 0); -- --- if (AR_SREV_9100(ah)) --+ if (AR_SREV_9100(ah)) { --+ /* Reset the AHB-WMAC interface */ --+ if (ah->external_reset) --+ ah->external_reset(); -- udelay(50); --+ } -- -- return true; -- } -diff --git a/package/kernel/mac80211/patches/ath9k/351-ath9k_hw-issue-external-reset-for-QCA955x.patch b/package/kernel/mac80211/patches/ath9k/351-ath9k_hw-issue-external-reset-for-QCA955x.patch -deleted file mode 100644 -index 53b7ba08bc..0000000000 ---- a/package/kernel/mac80211/patches/ath9k/351-ath9k_hw-issue-external-reset-for-QCA955x.patch -+++ /dev/null -@@ -1,129 +0,0 @@ --From: Felix Fietkau --Date: Sat, 9 Jul 2016 15:26:44 +0200 --Subject: [PATCH] ath9k_hw: issue external reset for QCA955x -- --The RTC interface on the SoC needs to be reset along with the rest of --the WMAC. -- --Signed-off-by: Felix Fietkau ----- -- ----- a/drivers/net/wireless/ath/ath9k/hw.c --+++ b/drivers/net/wireless/ath/ath9k/hw.c --@@ -1311,39 +1311,56 @@ void ath9k_hw_get_delta_slope_vals(struc -- *coef_exponent = coef_exp - 16; -- } -- ---/* AR9330 WAR: --- * call external reset function to reset WMAC if: --- * - doing a cold reset --- * - we have pending frames in the TX queues. --- */ ---static bool ath9k_hw_ar9330_reset_war(struct ath_hw *ah, int type) --+static bool ath9k_hw_need_external_reset(struct ath_hw *ah, int type) -- { --- int i, npend = 0; --+ int i; -- --- for (i = 0; i < AR_NUM_QCU; i++) { --- npend = ath9k_hw_numtxpending(ah, i); --- if (npend) --- break; --- } --- --- if (ah->external_reset && --- (npend || type == ATH9K_RESET_COLD)) { --- int reset_err = 0; --- --- ath_dbg(ath9k_hw_common(ah), RESET, --- "reset MAC via external reset\n"); --- --- reset_err = ah->external_reset(); --- if (reset_err) { --- ath_err(ath9k_hw_common(ah), --- "External reset failed, err=%d\n", --- reset_err); --- return false; --+ if (type == ATH9K_RESET_COLD) --+ return true; --+ --+ if (AR_SREV_9550(ah)) --+ return true; --+ --+ /* AR9330 WAR: --+ * call external reset function to reset WMAC if: --+ * - doing a cold reset --+ * - we have pending frames in the TX queues. --+ */ --+ if (AR_SREV_9330(ah)) { --+ for (i = 0; i < AR_NUM_QCU; i++) { --+ if (ath9k_hw_numtxpending(ah, i)) --+ return true; -- } --+ } --+ --+ return false; --+} --+ --+static bool ath9k_hw_external_reset(struct ath_hw *ah, int type) --+{ --+ int err; --+ --+ if (!ah->external_reset || !ath9k_hw_need_external_reset(ah, type)) --+ return true; --+ --+ ath_dbg(ath9k_hw_common(ah), RESET, --+ "reset MAC via external reset\n"); -- --- REG_WRITE(ah, AR_RTC_RESET, 1); --+ err = ah->external_reset(); --+ if (err) { --+ ath_err(ath9k_hw_common(ah), --+ "External reset failed, err=%d\n", err); --+ return false; -- } -- --+ if (AR_SREV_9550(ah)) { --+ REG_WRITE(ah, AR_RTC_RESET, 0); --+ udelay(10); --+ } --+ --+ REG_WRITE(ah, AR_RTC_RESET, 1); --+ udelay(10); --+ -- return true; -- } -- --@@ -1396,24 +1413,24 @@ static bool ath9k_hw_set_reset(struct at -- rst_flags |= AR_RTC_RC_MAC_COLD; -- } -- --- if (AR_SREV_9330(ah)) { --- if (!ath9k_hw_ar9330_reset_war(ah, type)) --- return false; --- } --- -- if (ath9k_hw_mci_is_enabled(ah)) -- ar9003_mci_check_gpm_offset(ah); -- -- /* DMA HALT added to resolve ar9300 and ar9580 bus error during --- * RTC_RC reg read --+ * RTC_RC reg read. Also needed for AR9550 external reset -- */ --- if (AR_SREV_9300(ah) || AR_SREV_9580(ah)) { --+ if (AR_SREV_9300(ah) || AR_SREV_9580(ah) || AR_SREV_9550(ah)) { -- REG_SET_BIT(ah, AR_CFG, AR_CFG_HALT_REQ); -- ath9k_hw_wait(ah, AR_CFG, AR_CFG_HALT_ACK, AR_CFG_HALT_ACK, -- 20 * AH_WAIT_TIMEOUT); --- REG_CLR_BIT(ah, AR_CFG, AR_CFG_HALT_REQ); -- } -- --+ if (!AR_SREV_9100(ah)) --+ ath9k_hw_external_reset(ah, type); --+ --+ if (AR_SREV_9300(ah) || AR_SREV_9580(ah)) --+ REG_CLR_BIT(ah, AR_CFG, AR_CFG_HALT_REQ); --+ -- REG_WRITE(ah, AR_RTC_RC, rst_flags); -- -- REGWRITE_BUFFER_FLUSH(ah); -diff --git a/package/kernel/mac80211/patches/ath9k/354-ath9k-force-rx_clear-when-disabling-rx.patch b/package/kernel/mac80211/patches/ath9k/354-ath9k-force-rx_clear-when-disabling-rx.patch -deleted file mode 100644 -index 8aaccf49b4..0000000000 ---- a/package/kernel/mac80211/patches/ath9k/354-ath9k-force-rx_clear-when-disabling-rx.patch -+++ /dev/null -@@ -1,35 +0,0 @@ --From: Felix Fietkau --Date: Sun, 7 Jun 2015 13:53:35 +0200 --Subject: [PATCH] ath9k: force rx_clear when disabling rx -- --This makes stopping Rx more reliable and should reduce the frequency of --Rx related DMA stop warnings. Don't use rx_clear in TX99 mode. -- --Cc: stable@vger.kernel.org --Signed-off-by: Felix Fietkau --Signed-off-by: Helmut Schaa ----- -- ----- a/drivers/net/wireless/ath/ath9k/mac.c --+++ b/drivers/net/wireless/ath/ath9k/mac.c --@@ -678,13 +678,18 @@ void ath9k_hw_startpcureceive(struct ath -- -- ath9k_ani_reset(ah, is_scanning); -- --- REG_CLR_BIT(ah, AR_DIAG_SW, (AR_DIAG_RX_DIS | AR_DIAG_RX_ABORT)); --+ REG_CLR_BIT(ah, AR_DIAG_SW, --+ AR_DIAG_RX_DIS | AR_DIAG_RX_ABORT | AR_DIAG_FORCE_RX_CLEAR); -- } -- EXPORT_SYMBOL(ath9k_hw_startpcureceive); -- -- void ath9k_hw_abortpcurecv(struct ath_hw *ah) -- { --- REG_SET_BIT(ah, AR_DIAG_SW, AR_DIAG_RX_ABORT | AR_DIAG_RX_DIS); --+ u32 reg = AR_DIAG_RX_DIS | AR_DIAG_RX_ABORT; --+ --+ if (!IS_ENABLED(CPTCFG_ATH9K_TX99)) --+ reg |= AR_DIAG_FORCE_RX_CLEAR; --+ REG_SET_BIT(ah, AR_DIAG_SW, reg); -- -- ath9k_hw_disable_mib_counters(ah); -- } -diff --git a/package/kernel/mac80211/patches/ath9k/356-Revert-ath9k-interpret-requested-txpower-in-EIRP-dom.patch b/package/kernel/mac80211/patches/ath9k/356-Revert-ath9k-interpret-requested-txpower-in-EIRP-dom.patch -deleted file mode 100644 -index 385eea0116..0000000000 ---- a/package/kernel/mac80211/patches/ath9k/356-Revert-ath9k-interpret-requested-txpower-in-EIRP-dom.patch -+++ /dev/null -@@ -1,36 +0,0 @@ --From: Felix Fietkau --Date: Sat, 14 May 2016 14:51:02 +0200 --Subject: [PATCH] Revert "ath9k: interpret requested txpower in EIRP -- domain" -- --This reverts commit 71f5137bf010c6faffab50c0ec15374c59c4a411. ----- -- ----- a/drivers/net/wireless/ath/ath9k/hw.c --+++ b/drivers/net/wireless/ath/ath9k/hw.c --@@ -2977,7 +2977,8 @@ void ath9k_hw_apply_txpower(struct ath_h -- { -- struct ath_regulatory *reg = ath9k_hw_regulatory(ah); -- struct ieee80211_channel *channel; --- int chan_pwr, new_pwr; --+ int chan_pwr, new_pwr, max_gain; --+ int ant_gain, ant_reduction = 0; -- u16 ctl = NO_CTL; -- -- if (!chan) --@@ -2989,9 +2990,14 @@ void ath9k_hw_apply_txpower(struct ath_h -- channel = chan->chan; -- chan_pwr = min_t(int, channel->max_power * 2, MAX_COMBINED_POWER); -- new_pwr = min_t(int, chan_pwr, reg->power_limit); --+ max_gain = chan_pwr - new_pwr + channel->max_antenna_gain * 2; --+ --+ ant_gain = get_antenna_gain(ah, chan); --+ if (ant_gain > max_gain) --+ ant_reduction = ant_gain - max_gain; -- -- ah->eep_ops->set_txpower(ah, chan, ctl, --- get_antenna_gain(ah, chan), new_pwr, test); --+ ant_reduction, new_pwr, test); -- } -- -- void ath9k_hw_set_txpowerlimit(struct ath_hw *ah, u32 limit, bool test) -diff --git a/package/kernel/mac80211/patches/ath9k/365-ath9k-adjust-tx-power-reduction-for-US-regulatory-do.patch b/package/kernel/mac80211/patches/ath9k/365-ath9k-adjust-tx-power-reduction-for-US-regulatory-do.patch -deleted file mode 100644 -index 0c3edc1260..0000000000 ---- a/package/kernel/mac80211/patches/ath9k/365-ath9k-adjust-tx-power-reduction-for-US-regulatory-do.patch -+++ /dev/null -@@ -1,24 +0,0 @@ --From: Felix Fietkau --Date: Wed, 19 Jul 2017 08:49:31 +0200 --Subject: [PATCH] ath9k: adjust tx power reduction for US regulatory -- domain -- --FCC regulatory rules allow for up to 6 dBi antenna gain. Account for --this in the EEPROM based tx power reduction code. -- --Signed-off-by: Felix Fietkau ----- -- ----- a/drivers/net/wireless/ath/ath9k/hw.c --+++ b/drivers/net/wireless/ath/ath9k/hw.c --@@ -2996,6 +2996,10 @@ void ath9k_hw_apply_txpower(struct ath_h -- if (ant_gain > max_gain) -- ant_reduction = ant_gain - max_gain; -- --+ /* FCC allows maximum antenna gain of 6 dBi */ --+ if (reg->region == NL80211_DFS_FCC) --+ ant_reduction = max_t(int, ant_reduction - 12, 0); --+ -- ah->eep_ops->set_txpower(ah, chan, ctl, -- ant_reduction, new_pwr, test); -- } -diff --git a/package/kernel/mac80211/patches/ath9k/401-ath9k_blink_default.patch b/package/kernel/mac80211/patches/ath9k/401-ath9k_blink_default.patch -deleted file mode 100644 -index 3eb57bb1cf..0000000000 ---- a/package/kernel/mac80211/patches/ath9k/401-ath9k_blink_default.patch -+++ /dev/null -@@ -1,11 +0,0 @@ ----- a/drivers/net/wireless/ath/ath9k/init.c --+++ b/drivers/net/wireless/ath/ath9k/init.c --@@ -48,7 +48,7 @@ int ath9k_modparam_nohwcrypt; -- module_param_named(nohwcrypt, ath9k_modparam_nohwcrypt, int, 0444); -- MODULE_PARM_DESC(nohwcrypt, "Disable hardware encryption"); -- ---int ath9k_led_blink; --+int ath9k_led_blink = 1; -- module_param_named(blink, ath9k_led_blink, int, 0444); -- MODULE_PARM_DESC(blink, "Enable LED blink on activity"); -- -diff --git a/package/kernel/mac80211/patches/ath9k/410-ath9k_allow_adhoc_and_ap.patch b/package/kernel/mac80211/patches/ath9k/410-ath9k_allow_adhoc_and_ap.patch -deleted file mode 100644 -index b2f2763e8e..0000000000 ---- a/package/kernel/mac80211/patches/ath9k/410-ath9k_allow_adhoc_and_ap.patch -+++ /dev/null -@@ -1,10 +0,0 @@ ----- a/drivers/net/wireless/ath/ath9k/init.c --+++ b/drivers/net/wireless/ath/ath9k/init.c --@@ -882,6 +882,7 @@ static const struct ieee80211_iface_limi -- BIT(NL80211_IFTYPE_AP) }, -- { .max = 1, .types = BIT(NL80211_IFTYPE_P2P_CLIENT) | -- BIT(NL80211_IFTYPE_P2P_GO) }, --+ { .max = 1, .types = BIT(NL80211_IFTYPE_ADHOC) }, -- }; -- -- #ifdef CPTCFG_ATH9K_CHANNEL_CONTEXT -diff --git a/package/kernel/mac80211/patches/ath9k/450-ath9k-enabled-MFP-capability-unconditionally.patch b/package/kernel/mac80211/patches/ath9k/450-ath9k-enabled-MFP-capability-unconditionally.patch -deleted file mode 100644 -index f424ca530b..0000000000 ---- a/package/kernel/mac80211/patches/ath9k/450-ath9k-enabled-MFP-capability-unconditionally.patch -+++ /dev/null -@@ -1,34 +0,0 @@ --From d946085ff5a331de64e91a2e3c96b9ca79d740f5 Mon Sep 17 00:00:00 2001 --From: David Bauer --Date: Mon, 15 Jun 2020 00:10:34 +0200 --Subject: [PATCH] ath9k: enabled MFP capability unconditionally -- --ath9k will already fallback on software-crypto for chipsets not --supporting IEEE802.11w (MFP). So advertising MFP is not dependent --on disabling HW crypto for all traffic entirely. -- --Signed-off-by: David Bauer ----- -- drivers/net/wireless/ath/ath9k/init.c | 4 +--- -- 1 file changed, 1 insertion(+), 3 deletions(-) -- ----- a/drivers/net/wireless/ath/ath9k/init.c --+++ b/drivers/net/wireless/ath/ath9k/init.c --@@ -963,6 +963,7 @@ static void ath9k_set_hw_capab(struct at -- ieee80211_hw_set(hw, HOST_BROADCAST_PS_BUFFERING); -- ieee80211_hw_set(hw, SUPPORT_FAST_XMIT); -- ieee80211_hw_set(hw, SUPPORTS_CLONED_SKBS); --+ ieee80211_hw_set(hw, MFP_CAPABLE); -- -- if (ath9k_ps_enable) -- ieee80211_hw_set(hw, SUPPORTS_PS); --@@ -975,9 +976,6 @@ static void ath9k_set_hw_capab(struct at -- IEEE80211_RADIOTAP_MCS_HAVE_STBC; -- } -- --- if (AR_SREV_9160_10_OR_LATER(sc->sc_ah) || ath9k_modparam_nohwcrypt) --- ieee80211_hw_set(hw, MFP_CAPABLE); --- -- hw->wiphy->features |= NL80211_FEATURE_ACTIVE_MONITOR | -- NL80211_FEATURE_AP_MODE_CHAN_WIDTH_CHANGE | -- NL80211_FEATURE_P2P_GO_CTWIN; -diff --git a/package/kernel/mac80211/patches/ath9k/500-ath9k_eeprom_debugfs.patch b/package/kernel/mac80211/patches/ath9k/500-ath9k_eeprom_debugfs.patch -deleted file mode 100644 -index 2f5e75be8a..0000000000 ---- a/package/kernel/mac80211/patches/ath9k/500-ath9k_eeprom_debugfs.patch -+++ /dev/null -@@ -1,66 +0,0 @@ ----- a/drivers/net/wireless/ath/ath9k/debug.c --+++ b/drivers/net/wireless/ath/ath9k/debug.c --@@ -1413,6 +1413,54 @@ void ath9k_deinit_debug(struct ath_softc -- ath9k_cmn_spectral_deinit_debug(&sc->spec_priv); -- } -- --+static ssize_t read_file_eeprom(struct file *file, char __user *user_buf, --+ size_t count, loff_t *ppos) --+{ --+ struct ath_softc *sc = file->private_data; --+ struct ath_hw *ah = sc->sc_ah; --+ struct ath_common *common = ath9k_hw_common(ah); --+ int bytes = 0; --+ int pos = *ppos; --+ int size = 4096; --+ u16 val; --+ int i; --+ --+ if (AR_SREV_9300_20_OR_LATER(ah)) --+ size = 16384; --+ --+ if (*ppos < 0) --+ return -EINVAL; --+ --+ if (count > size - *ppos) --+ count = size - *ppos; --+ --+ for (i = *ppos / 2; count > 0; count -= bytes, *ppos += bytes, i++) { --+ void *from = &val; --+ --+ if (!common->bus_ops->eeprom_read(common, i, &val)) --+ val = 0xffff; --+ --+ if (*ppos % 2) { --+ from++; --+ bytes = 1; --+ } else if (count == 1) { --+ bytes = 1; --+ } else { --+ bytes = 2; --+ } --+ if (copy_to_user(user_buf, from, bytes)) --+ return -EFAULT; --+ user_buf += bytes; --+ } --+ return *ppos - pos; --+} --+ --+static const struct file_operations fops_eeprom = { --+ .read = read_file_eeprom, --+ .open = simple_open, --+ .owner = THIS_MODULE --+}; --+ -- int ath9k_init_debug(struct ath_hw *ah) -- { -- struct ath_common *common = ath9k_hw_common(ah); --@@ -1432,6 +1480,8 @@ int ath9k_init_debug(struct ath_hw *ah) -- ath9k_tx99_init_debug(sc); -- ath9k_cmn_spectral_init_debug(&sc->spec_priv, sc->debug.debugfs_phy); -- --+ debugfs_create_file("eeprom", S_IRUSR, sc->debug.debugfs_phy, sc, --+ &fops_eeprom); -- debugfs_create_devm_seqfile(sc->dev, "dma", sc->debug.debugfs_phy, -- read_file_dma); -- debugfs_create_devm_seqfile(sc->dev, "interrupt", sc->debug.debugfs_phy, -diff --git a/package/kernel/mac80211/patches/ath9k/501-ath9k_ahb_init.patch b/package/kernel/mac80211/patches/ath9k/501-ath9k_ahb_init.patch -deleted file mode 100644 -index 740ddc39dc..0000000000 ---- a/package/kernel/mac80211/patches/ath9k/501-ath9k_ahb_init.patch -+++ /dev/null -@@ -1,34 +0,0 @@ ----- a/drivers/net/wireless/ath/ath9k/init.c --+++ b/drivers/net/wireless/ath/ath9k/init.c --@@ -1178,25 +1178,25 @@ static int __init ath9k_init(void) -- { -- int error; -- --- error = ath_pci_init(); --+ error = ath_ahb_init(); -- if (error < 0) { --- pr_err("No PCI devices found, driver not installed\n"); -- error = -ENODEV; -- goto err_out; -- } -- --- error = ath_ahb_init(); --+ error = ath_pci_init(); -- if (error < 0) { --+ pr_err("No PCI devices found, driver not installed\n"); -- error = -ENODEV; --- goto err_pci_exit; --+ goto err_ahb_exit; -- } -- -- dmi_check_system(ath9k_quirks); -- -- return 0; -- --- err_pci_exit: --- ath_pci_exit(); --+ err_ahb_exit: --+ ath_ahb_exit(); -- err_out: -- return error; -- } -diff --git a/package/kernel/mac80211/patches/ath9k/510-ath9k_intr_mitigation_tweak.patch b/package/kernel/mac80211/patches/ath9k/510-ath9k_intr_mitigation_tweak.patch -deleted file mode 100644 -index fda050a8f2..0000000000 ---- a/package/kernel/mac80211/patches/ath9k/510-ath9k_intr_mitigation_tweak.patch -+++ /dev/null -@@ -1,18 +0,0 @@ ----- a/drivers/net/wireless/ath/ath9k/hw.c --+++ b/drivers/net/wireless/ath/ath9k/hw.c --@@ -402,13 +402,8 @@ static void ath9k_hw_init_config(struct -- -- ah->config.rx_intr_mitigation = true; -- --- if (AR_SREV_9300_20_OR_LATER(ah)) { --- ah->config.rimt_last = 500; --- ah->config.rimt_first = 2000; --- } else { --- ah->config.rimt_last = 250; --- ah->config.rimt_first = 700; --- } --+ ah->config.rimt_last = 250; --+ ah->config.rimt_first = 500; -- -- if (AR_SREV_9462(ah) || AR_SREV_9565(ah)) -- ah->config.pll_pwrsave = 7; -diff --git a/package/kernel/mac80211/patches/ath9k/511-ath9k_reduce_rxbuf.patch b/package/kernel/mac80211/patches/ath9k/511-ath9k_reduce_rxbuf.patch -deleted file mode 100644 -index 15b8d7b86b..0000000000 ---- a/package/kernel/mac80211/patches/ath9k/511-ath9k_reduce_rxbuf.patch -+++ /dev/null -@@ -1,11 +0,0 @@ ----- a/drivers/net/wireless/ath/ath9k/ath9k.h --+++ b/drivers/net/wireless/ath/ath9k/ath9k.h --@@ -88,7 +88,7 @@ int ath_descdma_setup(struct ath_softc * -- (_l) &= ((_sz) - 1); \ -- } while (0) -- ---#define ATH_RXBUF 512 --+#define ATH_RXBUF 256 -- #define ATH_TXBUF 512 -- #define ATH_TXBUF_RESERVE 5 -- #define ATH_TXMAXTRY 13 -diff --git a/package/kernel/mac80211/patches/ath9k/512-ath9k_channelbw_debugfs.patch b/package/kernel/mac80211/patches/ath9k/512-ath9k_channelbw_debugfs.patch -deleted file mode 100644 -index a871e458a4..0000000000 ---- a/package/kernel/mac80211/patches/ath9k/512-ath9k_channelbw_debugfs.patch -+++ /dev/null -@@ -1,125 +0,0 @@ ----- a/drivers/net/wireless/ath/ath9k/debug.c --+++ b/drivers/net/wireless/ath/ath9k/debug.c --@@ -1461,6 +1461,52 @@ static const struct file_operations fops -- .owner = THIS_MODULE -- }; -- --+ --+static ssize_t read_file_chan_bw(struct file *file, char __user *user_buf, --+ size_t count, loff_t *ppos) --+{ --+ struct ath_softc *sc = file->private_data; --+ struct ath_common *common = ath9k_hw_common(sc->sc_ah); --+ char buf[32]; --+ unsigned int len; --+ --+ len = sprintf(buf, "0x%08x\n", common->chan_bw); --+ return simple_read_from_buffer(user_buf, count, ppos, buf, len); --+} --+ --+static ssize_t write_file_chan_bw(struct file *file, const char __user *user_buf, --+ size_t count, loff_t *ppos) --+{ --+ struct ath_softc *sc = file->private_data; --+ struct ath_common *common = ath9k_hw_common(sc->sc_ah); --+ unsigned long chan_bw; --+ char buf[32]; --+ ssize_t len; --+ --+ len = min(count, sizeof(buf) - 1); --+ if (copy_from_user(buf, user_buf, len)) --+ return -EFAULT; --+ --+ buf[len] = '\0'; --+ if (kstrtoul(buf, 0, &chan_bw)) --+ return -EINVAL; --+ --+ common->chan_bw = chan_bw; --+ if (!test_bit(ATH_OP_INVALID, &common->op_flags)) --+ ath9k_ops.config(sc->hw, IEEE80211_CONF_CHANGE_CHANNEL); --+ --+ return count; --+} --+ --+static const struct file_operations fops_chanbw = { --+ .read = read_file_chan_bw, --+ .write = write_file_chan_bw, --+ .open = simple_open, --+ .owner = THIS_MODULE, --+ .llseek = default_llseek, --+}; --+ --+ -- int ath9k_init_debug(struct ath_hw *ah) -- { -- struct ath_common *common = ath9k_hw_common(ah); --@@ -1482,6 +1528,8 @@ int ath9k_init_debug(struct ath_hw *ah) -- -- debugfs_create_file("eeprom", S_IRUSR, sc->debug.debugfs_phy, sc, -- &fops_eeprom); --+ debugfs_create_file("chanbw", S_IRUSR | S_IWUSR, sc->debug.debugfs_phy, --+ sc, &fops_chanbw); -- debugfs_create_devm_seqfile(sc->dev, "dma", sc->debug.debugfs_phy, -- read_file_dma); -- debugfs_create_devm_seqfile(sc->dev, "interrupt", sc->debug.debugfs_phy, ----- a/drivers/net/wireless/ath/ath.h --+++ b/drivers/net/wireless/ath/ath.h --@@ -149,6 +149,7 @@ struct ath_common { -- int debug_mask; -- enum ath_device_state state; -- unsigned long op_flags; --+ u32 chan_bw; -- -- struct ath_ani ani; -- ----- a/drivers/net/wireless/ath/ath9k/common.c --+++ b/drivers/net/wireless/ath/ath9k/common.c --@@ -297,11 +297,13 @@ EXPORT_SYMBOL(ath9k_cmn_get_hw_crypto_ke -- /* -- * Update internal channel flags. -- */ ---static void ath9k_cmn_update_ichannel(struct ath9k_channel *ichan, --+static void ath9k_cmn_update_ichannel(struct ath_common *common, --+ struct ath9k_channel *ichan, -- struct cfg80211_chan_def *chandef) -- { -- struct ieee80211_channel *chan = chandef->chan; -- u16 flags = 0; --+ int width; -- -- ichan->channel = chan->center_freq; -- ichan->chan = chan; --@@ -309,7 +311,19 @@ static void ath9k_cmn_update_ichannel(st -- if (chan->band == NL80211_BAND_5GHZ) -- flags |= CHANNEL_5GHZ; -- --- switch (chandef->width) { --+ switch (common->chan_bw) { --+ case 5: --+ width = NL80211_CHAN_WIDTH_5; --+ break; --+ case 10: --+ width = NL80211_CHAN_WIDTH_10; --+ break; --+ default: --+ width = chandef->width; --+ break; --+ } --+ --+ switch (width) { -- case NL80211_CHAN_WIDTH_5: -- flags |= CHANNEL_QUARTER; -- break; --@@ -342,10 +356,11 @@ struct ath9k_channel *ath9k_cmn_get_chan -- struct cfg80211_chan_def *chandef) -- { -- struct ieee80211_channel *curchan = chandef->chan; --+ struct ath_common *common = ath9k_hw_common(ah); -- struct ath9k_channel *channel; -- -- channel = &ah->channels[curchan->hw_value]; --- ath9k_cmn_update_ichannel(channel, chandef); --+ ath9k_cmn_update_ichannel(common, channel, chandef); -- -- return channel; -- } -diff --git a/package/kernel/mac80211/patches/ath9k/513-ath9k_add_pci_ids.patch b/package/kernel/mac80211/patches/ath9k/513-ath9k_add_pci_ids.patch -deleted file mode 100644 -index a085e3a1fb..0000000000 ---- a/package/kernel/mac80211/patches/ath9k/513-ath9k_add_pci_ids.patch -+++ /dev/null -@@ -1,30 +0,0 @@ ----- a/drivers/net/wireless/ath/ath9k/hw.c --+++ b/drivers/net/wireless/ath/ath9k/hw.c --@@ -662,6 +662,7 @@ int ath9k_hw_init(struct ath_hw *ah) -- -- /* These are all the AR5008/AR9001/AR9002/AR9003 hardware family of chipsets */ -- switch (ah->hw_version.devid) { --+ case AR9300_DEVID_INVALID: -- case AR5416_DEVID_PCI: -- case AR5416_DEVID_PCIE: -- case AR5416_AR9100_DEVID: ----- a/drivers/net/wireless/ath/ath9k/hw.h --+++ b/drivers/net/wireless/ath/ath9k/hw.h --@@ -36,6 +36,7 @@ -- -- #define ATHEROS_VENDOR_ID 0x168c -- --+#define AR9300_DEVID_INVALID 0xabcd -- #define AR5416_DEVID_PCI 0x0023 -- #define AR5416_DEVID_PCIE 0x0024 -- #define AR9160_DEVID_PCI 0x0027 ----- a/drivers/net/wireless/ath/ath9k/pci.c --+++ b/drivers/net/wireless/ath/ath9k/pci.c --@@ -774,6 +774,7 @@ static const struct pci_device_id ath_pc -- .driver_data = ATH9K_PCI_BT_ANT_DIV }, -- #endif -- --+ { PCI_VDEVICE(ATHEROS, 0xabcd) }, /* PCI-E internal chip default ID */ -- { 0 } -- }; -- -diff --git a/package/kernel/mac80211/patches/ath9k/530-ath9k_extra_leds.patch b/package/kernel/mac80211/patches/ath9k/530-ath9k_extra_leds.patch -deleted file mode 100644 -index 74506657e0..0000000000 ---- a/package/kernel/mac80211/patches/ath9k/530-ath9k_extra_leds.patch -+++ /dev/null -@@ -1,267 +0,0 @@ ----- a/drivers/net/wireless/ath/ath9k/ath9k.h --+++ b/drivers/net/wireless/ath/ath9k/ath9k.h --@@ -843,6 +843,9 @@ static inline int ath9k_dump_btcoex(stru -- #ifdef CPTCFG_MAC80211_LEDS -- void ath_init_leds(struct ath_softc *sc); -- void ath_deinit_leds(struct ath_softc *sc); --+int ath_create_gpio_led(struct ath_softc *sc, int gpio, const char *name, --+ const char *trigger, bool active_low); --+ -- #else -- static inline void ath_init_leds(struct ath_softc *sc) -- { --@@ -979,6 +982,13 @@ void ath_ant_comb_scan(struct ath_softc -- -- #define ATH9K_NUM_CHANCTX 2 /* supports 2 operating channels */ -- --+struct ath_led { --+ struct list_head list; --+ struct ath_softc *sc; --+ const struct gpio_led *gpio; --+ struct led_classdev cdev; --+}; --+ -- struct ath_softc { -- struct ieee80211_hw *hw; -- struct device *dev; --@@ -1032,9 +1042,8 @@ struct ath_softc { -- spinlock_t chan_lock; -- -- #ifdef CPTCFG_MAC80211_LEDS --- bool led_registered; --- char led_name[32]; --- struct led_classdev led_cdev; --+ const char *led_default_trigger; --+ struct list_head leds; -- #endif -- -- #ifdef CPTCFG_ATH9K_DEBUGFS ----- a/drivers/net/wireless/ath/ath9k/gpio.c --+++ b/drivers/net/wireless/ath/ath9k/gpio.c --@@ -39,61 +39,111 @@ static void ath_fill_led_pin(struct ath_ -- else -- ah->led_pin = ATH_LED_PIN_DEF; -- } --+} --+ --+static void ath_led_brightness(struct led_classdev *led_cdev, --+ enum led_brightness brightness) --+{ --+ struct ath_led *led = container_of(led_cdev, struct ath_led, cdev); --+ struct ath_softc *sc = led->sc; --+ --+ ath9k_ps_wakeup(sc); --+ ath9k_hw_set_gpio(sc->sc_ah, led->gpio->gpio, --+ (brightness != LED_OFF) ^ led->gpio->active_low); --+ ath9k_ps_restore(sc); --+} --+ --+static int ath_add_led(struct ath_softc *sc, struct ath_led *led) --+{ --+ const struct gpio_led *gpio = led->gpio; --+ int ret; --+ --+ led->cdev.name = gpio->name; --+ led->cdev.default_trigger = gpio->default_trigger; --+ led->cdev.brightness_set = ath_led_brightness; --+ --+ ret = led_classdev_register(wiphy_dev(sc->hw->wiphy), &led->cdev); --+ if (ret < 0) --+ return ret; --+ --+ led->sc = sc; --+ list_add(&led->list, &sc->leds); -- -- /* Configure gpio for output */ --- ath9k_hw_gpio_request_out(ah, ah->led_pin, "ath9k-led", --+ ath9k_hw_gpio_request_out(sc->sc_ah, gpio->gpio, gpio->name, -- AR_GPIO_OUTPUT_MUX_AS_OUTPUT); -- --- /* LED off, active low */ --- ath9k_hw_set_gpio(ah, ah->led_pin, ah->config.led_active_high ? 0 : 1); --+ /* LED off */ --+ ath9k_hw_set_gpio(sc->sc_ah, gpio->gpio, gpio->active_low); --+ --+ return 0; -- } -- ---static void ath_led_brightness(struct led_classdev *led_cdev, --- enum led_brightness brightness) --+int ath_create_gpio_led(struct ath_softc *sc, int gpio_num, const char *name, --+ const char *trigger, bool active_low) -- { --- struct ath_softc *sc = container_of(led_cdev, struct ath_softc, led_cdev); --- u32 val = (brightness == LED_OFF); --+ struct ath_led *led; --+ struct gpio_led *gpio; --+ char *_name; --+ int ret; -- --- if (sc->sc_ah->config.led_active_high) --- val = !val; --+ led = kzalloc(sizeof(*led) + sizeof(*gpio) + strlen(name) + 1, --+ GFP_KERNEL); --+ if (!led) --+ return -ENOMEM; --+ --+ led->gpio = gpio = (struct gpio_led *) (led + 1); --+ _name = (char *) (led->gpio + 1); --+ --+ strcpy(_name, name); --+ gpio->name = _name; --+ gpio->gpio = gpio_num; --+ gpio->active_low = active_low; --+ gpio->default_trigger = trigger; --+ --+ ret = ath_add_led(sc, led); --+ if (unlikely(ret < 0)) --+ kfree(led); -- --- ath9k_hw_set_gpio(sc->sc_ah, sc->sc_ah->led_pin, val); --+ return ret; -- } -- -- void ath_deinit_leds(struct ath_softc *sc) -- { --- if (!sc->led_registered) --- return; --+ struct ath_led *led; -- --- ath_led_brightness(&sc->led_cdev, LED_OFF); --- led_classdev_unregister(&sc->led_cdev); --- --- ath9k_hw_gpio_free(sc->sc_ah, sc->sc_ah->led_pin); --+ while (!list_empty(&sc->leds)) { --+ led = list_first_entry(&sc->leds, struct ath_led, list); --+ list_del(&led->list); --+ ath_led_brightness(&led->cdev, LED_OFF); --+ led_classdev_unregister(&led->cdev); --+ ath9k_hw_gpio_free(sc->sc_ah, led->gpio->gpio); --+ kfree(led); --+ } -- } -- -- void ath_init_leds(struct ath_softc *sc) -- { --- int ret; --+ char led_name[32]; --+ const char *trigger; --+ --+ INIT_LIST_HEAD(&sc->leds); -- -- if (AR_SREV_9100(sc->sc_ah)) -- return; -- -- ath_fill_led_pin(sc); -- --- if (!ath9k_led_blink) --- sc->led_cdev.default_trigger = --- ieee80211_get_radio_led_name(sc->hw); --- --- snprintf(sc->led_name, sizeof(sc->led_name), --- "ath9k-%s", wiphy_name(sc->hw->wiphy)); --- sc->led_cdev.name = sc->led_name; --- sc->led_cdev.brightness_set = ath_led_brightness; --+ snprintf(led_name, sizeof(led_name), "ath9k-%s", --+ wiphy_name(sc->hw->wiphy)); -- --- ret = led_classdev_register(wiphy_dev(sc->hw->wiphy), &sc->led_cdev); --- if (ret < 0) --- return; --+ if (ath9k_led_blink) --+ trigger = sc->led_default_trigger; --+ else --+ trigger = ieee80211_get_radio_led_name(sc->hw); -- --- sc->led_registered = true; --+ ath_create_gpio_led(sc, sc->sc_ah->led_pin, led_name, trigger, --+ !sc->sc_ah->config.led_active_high); -- } -- #endif -- ----- a/drivers/net/wireless/ath/ath9k/init.c --+++ b/drivers/net/wireless/ath/ath9k/init.c --@@ -1088,7 +1088,7 @@ int ath9k_init_device(u16 devid, struct -- -- #ifdef CPTCFG_MAC80211_LEDS -- /* must be initialized before ieee80211_register_hw */ --- sc->led_cdev.default_trigger = ieee80211_create_tpt_led_trigger(sc->hw, --+ sc->led_default_trigger = ieee80211_create_tpt_led_trigger(sc->hw, -- IEEE80211_TPT_LEDTRIG_FL_RADIO, ath9k_tpt_blink, -- ARRAY_SIZE(ath9k_tpt_blink)); -- #endif ----- a/drivers/net/wireless/ath/ath9k/debug.c --+++ b/drivers/net/wireless/ath/ath9k/debug.c --@@ -1506,6 +1506,61 @@ static const struct file_operations fops -- .llseek = default_llseek, -- }; -- --+#ifdef CONFIG_MAC80211_LEDS --+ --+static ssize_t write_file_gpio_led(struct file *file, const char __user *ubuf, --+ size_t count, loff_t *ppos) --+{ --+ struct ath_softc *sc = file->private_data; --+ char buf[32], *str, *name, *c; --+ ssize_t len; --+ unsigned int gpio; --+ bool active_low = false; --+ --+ len = min(count, sizeof(buf) - 1); --+ if (copy_from_user(buf, ubuf, len)) --+ return -EFAULT; --+ --+ buf[len] = '\0'; --+ name = strchr(buf, ','); --+ if (!name) --+ return -EINVAL; --+ --+ *(name++) = 0; --+ if (!*name) --+ return -EINVAL; --+ --+ c = strchr(name, '\n'); --+ if (c) --+ *c = 0; --+ --+ str = buf; --+ if (*str == '!') { --+ str++; --+ active_low = true; --+ } --+ --+ if (kstrtouint(str, 0, &gpio) < 0) --+ return -EINVAL; --+ --+ if (gpio >= sc->sc_ah->caps.num_gpio_pins) --+ return -EINVAL; --+ --+ if (ath_create_gpio_led(sc, gpio, name, NULL, active_low) < 0) --+ return -EINVAL; --+ --+ return count; --+} --+ --+static const struct file_operations fops_gpio_led = { --+ .write = write_file_gpio_led, --+ .open = simple_open, --+ .owner = THIS_MODULE, --+ .llseek = default_llseek, --+}; --+ --+#endif --+ -- -- int ath9k_init_debug(struct ath_hw *ah) -- { --@@ -1530,6 +1585,10 @@ int ath9k_init_debug(struct ath_hw *ah) -- &fops_eeprom); -- debugfs_create_file("chanbw", S_IRUSR | S_IWUSR, sc->debug.debugfs_phy, -- sc, &fops_chanbw); --+#ifdef CONFIG_MAC80211_LEDS --+ debugfs_create_file("gpio_led", S_IWUSR, --+ sc->debug.debugfs_phy, sc, &fops_gpio_led); --+#endif -- debugfs_create_devm_seqfile(sc->dev, "dma", sc->debug.debugfs_phy, -- read_file_dma); -- debugfs_create_devm_seqfile(sc->dev, "interrupt", sc->debug.debugfs_phy, -diff --git a/package/kernel/mac80211/patches/ath9k/531-ath9k_extra_platform_leds.patch b/package/kernel/mac80211/patches/ath9k/531-ath9k_extra_platform_leds.patch -deleted file mode 100644 -index 8ed7ad8a09..0000000000 ---- a/package/kernel/mac80211/patches/ath9k/531-ath9k_extra_platform_leds.patch -+++ /dev/null -@@ -1,76 +0,0 @@ ----- a/include/linux/ath9k_platform.h --+++ b/include/linux/ath9k_platform.h --@@ -46,6 +46,9 @@ struct ath9k_platform_data { -- int (*external_reset)(void); -- -- bool use_eeprom; --+ --+ int num_leds; --+ const struct gpio_led *leds; -- }; -- -- #endif /* _LINUX_ATH9K_PLATFORM_H */ ----- a/drivers/net/wireless/ath/ath9k/gpio.c --+++ b/drivers/net/wireless/ath/ath9k/gpio.c --@@ -15,6 +15,7 @@ -- */ -- -- #include "ath9k.h" --+#include -- -- /********************************/ -- /* LED functions */ --@@ -108,6 +109,24 @@ int ath_create_gpio_led(struct ath_softc -- return ret; -- } -- --+static int ath_create_platform_led(struct ath_softc *sc, --+ const struct gpio_led *gpio) --+{ --+ struct ath_led *led; --+ int ret; --+ --+ led = kzalloc(sizeof(*led), GFP_KERNEL); --+ if (!led) --+ return -ENOMEM; --+ --+ led->gpio = gpio; --+ ret = ath_add_led(sc, led); --+ if (ret < 0) --+ kfree(led); --+ --+ return ret; --+} --+ -- void ath_deinit_leds(struct ath_softc *sc) -- { -- struct ath_led *led; --@@ -124,8 +143,10 @@ void ath_deinit_leds(struct ath_softc *s -- -- void ath_init_leds(struct ath_softc *sc) -- { --+ struct ath9k_platform_data *pdata = sc->dev->platform_data; -- char led_name[32]; -- const char *trigger; --+ int i; -- -- INIT_LIST_HEAD(&sc->leds); -- --@@ -134,6 +155,17 @@ void ath_init_leds(struct ath_softc *sc) -- -- ath_fill_led_pin(sc); -- --+ if (pdata && pdata->leds && pdata->num_leds) --+ for (i = 0; i < pdata->num_leds; i++) { --+ if (pdata->leds[i].gpio == sc->sc_ah->led_pin) --+ sc->sc_ah->led_pin = -1; --+ --+ ath_create_platform_led(sc, &pdata->leds[i]); --+ } --+ --+ if (sc->sc_ah->led_pin < 0) --+ return; --+ -- snprintf(led_name, sizeof(led_name), "ath9k-%s", -- wiphy_name(sc->hw->wiphy)); -- -diff --git a/package/kernel/mac80211/patches/ath9k/540-ath9k_reduce_ani_interval.patch b/package/kernel/mac80211/patches/ath9k/540-ath9k_reduce_ani_interval.patch -deleted file mode 100644 -index e899903478..0000000000 ---- a/package/kernel/mac80211/patches/ath9k/540-ath9k_reduce_ani_interval.patch -+++ /dev/null -@@ -1,11 +0,0 @@ ----- a/drivers/net/wireless/ath/ath9k/ani.h --+++ b/drivers/net/wireless/ath/ath9k/ani.h --@@ -42,7 +42,7 @@ -- #define ATH9K_ANI_PERIOD 300 -- -- /* in ms */ ---#define ATH9K_ANI_POLLINTERVAL 1000 --+#define ATH9K_ANI_POLLINTERVAL 300 -- -- #define ATH9K_SIG_FIRSTEP_SETTING_MIN 0 -- #define ATH9K_SIG_FIRSTEP_SETTING_MAX 20 -diff --git a/package/kernel/mac80211/patches/ath9k/542-ath9k_debugfs_diag.patch b/package/kernel/mac80211/patches/ath9k/542-ath9k_debugfs_diag.patch -deleted file mode 100644 -index e09bbc08ea..0000000000 ---- a/package/kernel/mac80211/patches/ath9k/542-ath9k_debugfs_diag.patch -+++ /dev/null -@@ -1,139 +0,0 @@ ----- a/drivers/net/wireless/ath/ath9k/debug.c --+++ b/drivers/net/wireless/ath/ath9k/debug.c --@@ -1562,6 +1562,50 @@ static const struct file_operations fops -- #endif -- -- --+static ssize_t read_file_diag(struct file *file, char __user *user_buf, --+ size_t count, loff_t *ppos) --+{ --+ struct ath_softc *sc = file->private_data; --+ struct ath_hw *ah = sc->sc_ah; --+ char buf[32]; --+ unsigned int len; --+ --+ len = sprintf(buf, "0x%08lx\n", ah->diag); --+ return simple_read_from_buffer(user_buf, count, ppos, buf, len); --+} --+ --+static ssize_t write_file_diag(struct file *file, const char __user *user_buf, --+ size_t count, loff_t *ppos) --+{ --+ struct ath_softc *sc = file->private_data; --+ struct ath_hw *ah = sc->sc_ah; --+ unsigned long diag; --+ char buf[32]; --+ ssize_t len; --+ --+ len = min(count, sizeof(buf) - 1); --+ if (copy_from_user(buf, user_buf, len)) --+ return -EFAULT; --+ --+ buf[len] = '\0'; --+ if (kstrtoul(buf, 0, &diag)) --+ return -EINVAL; --+ --+ ah->diag = diag; --+ ath9k_hw_update_diag(ah); --+ --+ return count; --+} --+ --+static const struct file_operations fops_diag = { --+ .read = read_file_diag, --+ .write = write_file_diag, --+ .open = simple_open, --+ .owner = THIS_MODULE, --+ .llseek = default_llseek, --+}; --+ --+ -- int ath9k_init_debug(struct ath_hw *ah) -- { -- struct ath_common *common = ath9k_hw_common(ah); --@@ -1589,6 +1633,8 @@ int ath9k_init_debug(struct ath_hw *ah) -- debugfs_create_file("gpio_led", S_IWUSR, -- sc->debug.debugfs_phy, sc, &fops_gpio_led); -- #endif --+ debugfs_create_file("diag", S_IRUSR | S_IWUSR, sc->debug.debugfs_phy, --+ sc, &fops_diag); -- debugfs_create_devm_seqfile(sc->dev, "dma", sc->debug.debugfs_phy, -- read_file_dma); -- debugfs_create_devm_seqfile(sc->dev, "interrupt", sc->debug.debugfs_phy, ----- a/drivers/net/wireless/ath/ath9k/hw.h --+++ b/drivers/net/wireless/ath/ath9k/hw.h --@@ -522,6 +522,12 @@ enum { -- ATH9K_RESET_COLD, -- }; -- --+enum { --+ ATH_DIAG_DISABLE_RX, --+ ATH_DIAG_DISABLE_TX, --+ ATH_DIAG_TRIGGER_ERROR, --+}; --+ -- struct ath9k_hw_version { -- u32 magic; -- u16 devid; --@@ -810,6 +816,8 @@ struct ath_hw { -- u32 ah_flags; -- s16 nf_override; -- --+ unsigned long diag; --+ -- bool reset_power_on; -- bool htc_reset_init; -- --@@ -1079,6 +1087,7 @@ void ath9k_hw_check_nav(struct ath_hw *a -- bool ath9k_hw_check_alive(struct ath_hw *ah); -- -- bool ath9k_hw_setpower(struct ath_hw *ah, enum ath9k_power_mode mode); --+void ath9k_hw_update_diag(struct ath_hw *ah); -- -- /* Generic hw timer primitives */ -- struct ath_gen_timer *ath_gen_timer_alloc(struct ath_hw *ah, ----- a/drivers/net/wireless/ath/ath9k/hw.c --+++ b/drivers/net/wireless/ath/ath9k/hw.c --@@ -1881,6 +1881,20 @@ u32 ath9k_hw_get_tsf_offset(struct times -- } -- EXPORT_SYMBOL(ath9k_hw_get_tsf_offset); -- --+void ath9k_hw_update_diag(struct ath_hw *ah) --+{ --+ if (test_bit(ATH_DIAG_DISABLE_RX, &ah->diag)) --+ REG_SET_BIT(ah, AR_DIAG_SW, AR_DIAG_RX_DIS); --+ else --+ REG_CLR_BIT(ah, AR_DIAG_SW, AR_DIAG_RX_DIS); --+ --+ if (test_bit(ATH_DIAG_DISABLE_TX, &ah->diag)) --+ REG_SET_BIT(ah, AR_DIAG_SW, AR_DIAG_LOOP_BACK); --+ else --+ REG_CLR_BIT(ah, AR_DIAG_SW, AR_DIAG_LOOP_BACK); --+} --+EXPORT_SYMBOL(ath9k_hw_update_diag); --+ -- int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan, -- struct ath9k_hw_cal_data *caldata, bool fastcc) -- { --@@ -2089,6 +2103,7 @@ int ath9k_hw_reset(struct ath_hw *ah, st -- ar9003_hw_disable_phy_restart(ah); -- -- ath9k_hw_apply_gpio_override(ah); --+ ath9k_hw_update_diag(ah); -- -- if (AR_SREV_9565(ah) && common->bt_ant_diversity) -- REG_SET_BIT(ah, AR_BTCOEX_WL_LNADIV, AR_BTCOEX_WL_LNADIV_FORCE_ON); ----- a/drivers/net/wireless/ath/ath9k/main.c --+++ b/drivers/net/wireless/ath/ath9k/main.c --@@ -538,6 +538,11 @@ irqreturn_t ath_isr(int irq, void *dev) -- return IRQ_HANDLED; -- } -- --+ if (test_bit(ATH_DIAG_TRIGGER_ERROR, &ah->diag)) { --+ status |= ATH9K_INT_FATAL; --+ clear_bit(ATH_DIAG_TRIGGER_ERROR, &ah->diag); --+ } --+ -- /* -- * If there are no status bits set, then this interrupt was not -- * for me (should have been caught above). -diff --git a/package/kernel/mac80211/patches/ath9k/543-ath9k_entropy_from_adc.patch b/package/kernel/mac80211/patches/ath9k/543-ath9k_entropy_from_adc.patch -deleted file mode 100644 -index 6acc864d1e..0000000000 ---- a/package/kernel/mac80211/patches/ath9k/543-ath9k_entropy_from_adc.patch -+++ /dev/null -@@ -1,186 +0,0 @@ ----- a/drivers/net/wireless/ath/ath9k/hw.h --+++ b/drivers/net/wireless/ath/ath9k/hw.h --@@ -723,6 +723,7 @@ struct ath_spec_scan { -- * @config_pci_powersave: -- * @calibrate: periodic calibration for NF, ANI, IQ, ADC gain, ADC-DC -- * --+ * @get_adc_entropy: get entropy from the raw ADC I/Q output -- * @spectral_scan_config: set parameters for spectral scan and enable/disable it -- * @spectral_scan_trigger: trigger a spectral scan run -- * @spectral_scan_wait: wait for a spectral scan run to finish --@@ -745,6 +746,7 @@ struct ath_hw_ops { -- struct ath_hw_antcomb_conf *antconf); -- void (*antdiv_comb_conf_set)(struct ath_hw *ah, -- struct ath_hw_antcomb_conf *antconf); --+ void (*get_adc_entropy)(struct ath_hw *ah, u8 *buf, size_t len); -- void (*spectral_scan_config)(struct ath_hw *ah, -- struct ath_spec_scan *param); -- void (*spectral_scan_trigger)(struct ath_hw *ah); ----- a/drivers/net/wireless/ath/ath9k/ar9003_phy.c --+++ b/drivers/net/wireless/ath/ath9k/ar9003_phy.c --@@ -1918,6 +1918,26 @@ void ar9003_hw_init_rate_txpower(struct -- } -- } -- --+static void ar9003_hw_get_adc_entropy(struct ath_hw *ah, u8 *buf, size_t len) --+{ --+ int i, j; --+ --+ REG_RMW_FIELD(ah, AR_PHY_TEST, AR_PHY_TEST_BBB_OBS_SEL, 1); --+ REG_CLR_BIT(ah, AR_PHY_TEST, AR_PHY_TEST_RX_OBS_SEL_BIT5); --+ REG_RMW_FIELD(ah, AR_PHY_TEST_CTL_STATUS, AR_PHY_TEST_CTL_RX_OBS_SEL, 0); --+ --+ memset(buf, 0, len); --+ for (i = 0; i < len; i++) { --+ for (j = 0; j < 4; j++) { --+ u32 regval = REG_READ(ah, AR_PHY_TST_ADC); --+ --+ buf[i] <<= 2; --+ buf[i] |= (regval & 1) | ((regval & BIT(10)) >> 9); --+ udelay(1); --+ } --+ } --+} --+ -- void ar9003_hw_attach_phy_ops(struct ath_hw *ah) -- { -- struct ath_hw_private_ops *priv_ops = ath9k_hw_private_ops(ah); --@@ -1954,6 +1974,7 @@ void ar9003_hw_attach_phy_ops(struct ath -- priv_ops->set_radar_params = ar9003_hw_set_radar_params; -- priv_ops->fast_chan_change = ar9003_hw_fast_chan_change; -- --+ ops->get_adc_entropy = ar9003_hw_get_adc_entropy; -- ops->antdiv_comb_conf_get = ar9003_hw_antdiv_comb_conf_get; -- ops->antdiv_comb_conf_set = ar9003_hw_antdiv_comb_conf_set; -- ops->spectral_scan_config = ar9003_hw_spectral_scan_config; ----- a/drivers/net/wireless/ath/ath9k/init.c --+++ b/drivers/net/wireless/ath/ath9k/init.c --@@ -870,7 +870,8 @@ static void ath9k_init_txpower_limits(st -- if (ah->caps.hw_caps & ATH9K_HW_CAP_5GHZ) -- ath9k_init_band_txpower(sc, NL80211_BAND_5GHZ); -- --- ah->curchan = curchan; --+ if (curchan) --+ ah->curchan = curchan; -- } -- -- static const struct ieee80211_iface_limit if_limits[] = { --@@ -1048,6 +1049,18 @@ static void ath9k_set_hw_capab(struct at -- wiphy_ext_feature_set(hw->wiphy, NL80211_EXT_FEATURE_CAN_REPLACE_PTK0); -- } -- --+static void ath_get_initial_entropy(struct ath_softc *sc) --+{ --+ struct ath_hw *ah = sc->sc_ah; --+ char buf[256]; --+ --+ /* reuse last channel initialized by the tx power test */ --+ ath9k_hw_reset(ah, ah->curchan, NULL, false); --+ --+ ath9k_hw_get_adc_entropy(ah, buf, sizeof(buf)); --+ add_device_randomness(buf, sizeof(buf)); --+} --+ -- int ath9k_init_device(u16 devid, struct ath_softc *sc, -- const struct ath_bus_ops *bus_ops) -- { --@@ -1095,6 +1108,8 @@ int ath9k_init_device(u16 devid, struct -- -- wiphy_read_of_freq_limits(hw->wiphy); -- --+ ath_get_initial_entropy(sc); --+ -- /* Register with mac80211 */ -- error = ieee80211_register_hw(hw); -- if (error) ----- a/drivers/net/wireless/ath/ath9k/hw-ops.h --+++ b/drivers/net/wireless/ath/ath9k/hw-ops.h --@@ -100,6 +100,12 @@ static inline void ath9k_hw_tx99_set_txp -- ath9k_hw_ops(ah)->tx99_set_txpower(ah, power); -- } -- --+static inline void ath9k_hw_get_adc_entropy(struct ath_hw *ah, --+ u8 *buf, size_t len) --+{ --+ ath9k_hw_ops(ah)->get_adc_entropy(ah, buf, len); --+} --+ -- #ifdef CPTCFG_ATH9K_BTCOEX_SUPPORT -- -- static inline void ath9k_hw_set_bt_ant_diversity(struct ath_hw *ah, bool enable) ----- a/drivers/net/wireless/ath/ath9k/ar5008_phy.c --+++ b/drivers/net/wireless/ath/ath9k/ar5008_phy.c --@@ -1340,9 +1340,30 @@ void ar5008_hw_init_rate_txpower(struct -- } -- } -- --+static void ar5008_hw_get_adc_entropy(struct ath_hw *ah, u8 *buf, size_t len) --+{ --+ int i, j; --+ --+ REG_RMW_FIELD(ah, AR_PHY_TEST, AR_PHY_TEST_BBB_OBS_SEL, 1); --+ REG_CLR_BIT(ah, AR_PHY_TEST, AR_PHY_TEST_RX_OBS_SEL_BIT5); --+ REG_RMW_FIELD(ah, AR_PHY_TEST2, AR_PHY_TEST2_RX_OBS_SEL, 0); --+ --+ memset(buf, 0, len); --+ for (i = 0; i < len; i++) { --+ for (j = 0; j < 4; j++) { --+ u32 regval = REG_READ(ah, AR_PHY_TST_ADC); --+ --+ buf[i] <<= 2; --+ buf[i] |= (regval & 1) | ((regval & BIT(9)) >> 8); --+ udelay(1); --+ } --+ } --+} --+ -- int ar5008_hw_attach_phy_ops(struct ath_hw *ah) -- { -- struct ath_hw_private_ops *priv_ops = ath9k_hw_private_ops(ah); --+ struct ath_hw_ops *ops = ath9k_hw_ops(ah); -- static const u32 ar5416_cca_regs[6] = { -- AR_PHY_CCA, -- AR_PHY_CH1_CCA, --@@ -1357,6 +1378,8 @@ int ar5008_hw_attach_phy_ops(struct ath_ -- if (ret) -- return ret; -- --+ ops->get_adc_entropy = ar5008_hw_get_adc_entropy; --+ -- priv_ops->rf_set_freq = ar5008_hw_set_channel; -- priv_ops->spur_mitigate_freq = ar5008_hw_spur_mitigate; -- ----- a/drivers/net/wireless/ath/ath9k/ar9002_phy.h --+++ b/drivers/net/wireless/ath/ath9k/ar9002_phy.h --@@ -20,6 +20,12 @@ -- #define PHY_AGC_CLR 0x10000000 -- #define RFSILENT_BB 0x00002000 -- --+#define AR_PHY_TEST_BBB_OBS_SEL 0x780000 --+#define AR_PHY_TEST_BBB_OBS_SEL_S 19 --+ --+#define AR_PHY_TEST_RX_OBS_SEL_BIT5_S 23 --+#define AR_PHY_TEST_RX_OBS_SEL_BIT5 (1 << AR_PHY_TEST_RX_OBS_SEL_BIT5_S) --+ -- #define AR_PHY_TURBO 0x9804 -- #define AR_PHY_FC_TURBO_MODE 0x00000001 -- #define AR_PHY_FC_TURBO_SHORT 0x00000002 --@@ -36,6 +42,9 @@ -- -- #define AR_PHY_TEST2 0x9808 -- --+#define AR_PHY_TEST2_RX_OBS_SEL 0x3C00 --+#define AR_PHY_TEST2_RX_OBS_SEL_S 10 --+ -- #define AR_PHY_TIMING2 0x9810 -- #define AR_PHY_TIMING3 0x9814 -- #define AR_PHY_TIMING3_DSC_MAN 0xFFFE0000 --@@ -393,6 +402,8 @@ -- #define AR_PHY_RFBUS_GRANT 0x9C20 -- #define AR_PHY_RFBUS_GRANT_EN 0x00000001 -- --+#define AR_PHY_TST_ADC 0x9C24 --+ -- #define AR_PHY_CHAN_INFO_GAIN_DIFF 0x9CF4 -- #define AR_PHY_CHAN_INFO_GAIN_DIFF_UPPER_LIMIT 320 -- -diff --git a/package/kernel/mac80211/patches/ath9k/544-ath9k-ar933x-usb-hang-workaround.patch b/package/kernel/mac80211/patches/ath9k/544-ath9k-ar933x-usb-hang-workaround.patch -deleted file mode 100644 -index 23a81864fa..0000000000 ---- a/package/kernel/mac80211/patches/ath9k/544-ath9k-ar933x-usb-hang-workaround.patch -+++ /dev/null -@@ -1,79 +0,0 @@ ----- a/drivers/net/wireless/ath/ath9k/hw.c --+++ b/drivers/net/wireless/ath/ath9k/hw.c --@@ -247,6 +247,19 @@ void ath9k_hw_get_channel_centers(struct -- centers->synth_center + (extoff * HT40_CHANNEL_CENTER_SHIFT); -- } -- --+static inline void ath9k_hw_disable_pll_lock_detect(struct ath_hw *ah) --+{ --+ /* On AR9330 and AR9340 devices, some PHY registers must be --+ * tuned to gain better stability/performance. These registers --+ * might be changed while doing wlan reset so the registers must --+ * be reprogrammed after each reset. --+ */ --+ REG_CLR_BIT(ah, AR_PHY_USB_CTRL1, BIT(20)); --+ REG_RMW(ah, AR_PHY_USB_CTRL2, --+ (1 << 21) | (0xf << 22), --+ (1 << 21) | (0x3 << 22)); --+} --+ -- /******************/ -- /* Chip Revisions */ -- /******************/ --@@ -1454,6 +1467,9 @@ static bool ath9k_hw_set_reset(struct at -- udelay(50); -- } -- --+ if (AR_SREV_9330(ah) || AR_SREV_9340(ah)) --+ ath9k_hw_disable_pll_lock_detect(ah); --+ -- return true; -- } -- --@@ -1553,6 +1569,9 @@ static bool ath9k_hw_chip_reset(struct a -- ar9003_hw_internal_regulator_apply(ah); -- ath9k_hw_init_pll(ah, chan); -- --+ if (AR_SREV_9330(ah) || AR_SREV_9340(ah)) --+ ath9k_hw_disable_pll_lock_detect(ah); --+ -- return true; -- } -- --@@ -1859,8 +1878,14 @@ static int ath9k_hw_do_fastcc(struct ath -- if (AR_SREV_9271(ah)) -- ar9002_hw_load_ani_reg(ah, chan); -- --+ if (AR_SREV_9330(ah) || AR_SREV_9340(ah)) --+ ath9k_hw_disable_pll_lock_detect(ah); --+ -- return 0; -- fail: --+ if (AR_SREV_9330(ah) || AR_SREV_9340(ah)) --+ ath9k_hw_disable_pll_lock_detect(ah); --+ -- return -EINVAL; -- } -- --@@ -2114,6 +2139,9 @@ int ath9k_hw_reset(struct ath_hw *ah, st -- ath9k_hw_set_radar_params(ah); -- } -- --+ if (AR_SREV_9330(ah) || AR_SREV_9340(ah)) --+ ath9k_hw_disable_pll_lock_detect(ah); --+ -- return 0; -- } -- EXPORT_SYMBOL(ath9k_hw_reset); ----- a/drivers/net/wireless/ath/ath9k/phy.h --+++ b/drivers/net/wireless/ath/ath9k/phy.h --@@ -48,6 +48,9 @@ -- #define AR_PHY_PLL_CONTROL 0x16180 -- #define AR_PHY_PLL_MODE 0x16184 -- --+#define AR_PHY_USB_CTRL1 0x16c84 --+#define AR_PHY_USB_CTRL2 0x16c88 --+ -- enum ath9k_ant_div_comb_lna_conf { -- ATH_ANT_DIV_COMB_LNA1_MINUS_LNA2, -- ATH_ANT_DIV_COMB_LNA2, -diff --git a/package/kernel/mac80211/patches/ath9k/545-ath9k_ani_ws_detect.patch b/package/kernel/mac80211/patches/ath9k/545-ath9k_ani_ws_detect.patch -deleted file mode 100644 -index d3bf07ff92..0000000000 ---- a/package/kernel/mac80211/patches/ath9k/545-ath9k_ani_ws_detect.patch -+++ /dev/null -@@ -1,155 +0,0 @@ ----- a/drivers/net/wireless/ath/ath9k/ar5008_phy.c --+++ b/drivers/net/wireless/ath/ath9k/ar5008_phy.c --@@ -969,55 +969,6 @@ static bool ar5008_hw_ani_control_new(st -- * on == 0 means more noise imm -- */ -- u32 on = param ? 1 : 0; --- /* --- * make register setting for default --- * (weak sig detect ON) come from INI file --- */ --- int m1ThreshLow = on ? --- aniState->iniDef.m1ThreshLow : m1ThreshLow_off; --- int m2ThreshLow = on ? --- aniState->iniDef.m2ThreshLow : m2ThreshLow_off; --- int m1Thresh = on ? --- aniState->iniDef.m1Thresh : m1Thresh_off; --- int m2Thresh = on ? --- aniState->iniDef.m2Thresh : m2Thresh_off; --- int m2CountThr = on ? --- aniState->iniDef.m2CountThr : m2CountThr_off; --- int m2CountThrLow = on ? --- aniState->iniDef.m2CountThrLow : m2CountThrLow_off; --- int m1ThreshLowExt = on ? --- aniState->iniDef.m1ThreshLowExt : m1ThreshLowExt_off; --- int m2ThreshLowExt = on ? --- aniState->iniDef.m2ThreshLowExt : m2ThreshLowExt_off; --- int m1ThreshExt = on ? --- aniState->iniDef.m1ThreshExt : m1ThreshExt_off; --- int m2ThreshExt = on ? --- aniState->iniDef.m2ThreshExt : m2ThreshExt_off; --- --- REG_RMW_FIELD(ah, AR_PHY_SFCORR_LOW, --- AR_PHY_SFCORR_LOW_M1_THRESH_LOW, --- m1ThreshLow); --- REG_RMW_FIELD(ah, AR_PHY_SFCORR_LOW, --- AR_PHY_SFCORR_LOW_M2_THRESH_LOW, --- m2ThreshLow); --- REG_RMW_FIELD(ah, AR_PHY_SFCORR, --- AR_PHY_SFCORR_M1_THRESH, m1Thresh); --- REG_RMW_FIELD(ah, AR_PHY_SFCORR, --- AR_PHY_SFCORR_M2_THRESH, m2Thresh); --- REG_RMW_FIELD(ah, AR_PHY_SFCORR, --- AR_PHY_SFCORR_M2COUNT_THR, m2CountThr); --- REG_RMW_FIELD(ah, AR_PHY_SFCORR_LOW, --- AR_PHY_SFCORR_LOW_M2COUNT_THR_LOW, --- m2CountThrLow); --- --- REG_RMW_FIELD(ah, AR_PHY_SFCORR_EXT, --- AR_PHY_SFCORR_EXT_M1_THRESH_LOW, m1ThreshLowExt); --- REG_RMW_FIELD(ah, AR_PHY_SFCORR_EXT, --- AR_PHY_SFCORR_EXT_M2_THRESH_LOW, m2ThreshLowExt); --- REG_RMW_FIELD(ah, AR_PHY_SFCORR_EXT, --- AR_PHY_SFCORR_EXT_M1_THRESH, m1ThreshExt); --- REG_RMW_FIELD(ah, AR_PHY_SFCORR_EXT, --- AR_PHY_SFCORR_EXT_M2_THRESH, m2ThreshExt); -- -- if (on) -- REG_SET_BIT(ah, AR_PHY_SFCORR_LOW, ----- a/drivers/net/wireless/ath/ath9k/ar9003_phy.c --+++ b/drivers/net/wireless/ath/ath9k/ar9003_phy.c --@@ -42,20 +42,6 @@ static const int cycpwrThr1_table[] = -- /* level: 0 1 2 3 4 5 6 7 8 */ -- { -6, -4, -2, 0, 2, 4, 6, 8 }; /* lvl 0-7, default 3 */ -- ---/* --- * register values to turn OFDM weak signal detection OFF --- */ ---static const int m1ThreshLow_off = 127; ---static const int m2ThreshLow_off = 127; ---static const int m1Thresh_off = 127; ---static const int m2Thresh_off = 127; ---static const int m2CountThr_off = 31; ---static const int m2CountThrLow_off = 63; ---static const int m1ThreshLowExt_off = 127; ---static const int m2ThreshLowExt_off = 127; ---static const int m1ThreshExt_off = 127; ---static const int m2ThreshExt_off = 127; --- -- static const u8 ofdm2pwr[] = { -- ALL_TARGET_LEGACY_6_24, -- ALL_TARGET_LEGACY_6_24, --@@ -1068,11 +1054,6 @@ static bool ar9003_hw_ani_control(struct -- struct ath_common *common = ath9k_hw_common(ah); -- struct ath9k_channel *chan = ah->curchan; -- struct ar5416AniState *aniState = &ah->ani; --- int m1ThreshLow, m2ThreshLow; --- int m1Thresh, m2Thresh; --- int m2CountThr, m2CountThrLow; --- int m1ThreshLowExt, m2ThreshLowExt; --- int m1ThreshExt, m2ThreshExt; -- s32 value, value2; -- -- switch (cmd & ah->ani_function) { --@@ -1086,61 +1067,6 @@ static bool ar9003_hw_ani_control(struct -- */ -- u32 on = param ? 1 : 0; -- --- if (AR_SREV_9462(ah) || AR_SREV_9565(ah)) --- goto skip_ws_det; --- --- m1ThreshLow = on ? --- aniState->iniDef.m1ThreshLow : m1ThreshLow_off; --- m2ThreshLow = on ? --- aniState->iniDef.m2ThreshLow : m2ThreshLow_off; --- m1Thresh = on ? --- aniState->iniDef.m1Thresh : m1Thresh_off; --- m2Thresh = on ? --- aniState->iniDef.m2Thresh : m2Thresh_off; --- m2CountThr = on ? --- aniState->iniDef.m2CountThr : m2CountThr_off; --- m2CountThrLow = on ? --- aniState->iniDef.m2CountThrLow : m2CountThrLow_off; --- m1ThreshLowExt = on ? --- aniState->iniDef.m1ThreshLowExt : m1ThreshLowExt_off; --- m2ThreshLowExt = on ? --- aniState->iniDef.m2ThreshLowExt : m2ThreshLowExt_off; --- m1ThreshExt = on ? --- aniState->iniDef.m1ThreshExt : m1ThreshExt_off; --- m2ThreshExt = on ? --- aniState->iniDef.m2ThreshExt : m2ThreshExt_off; --- --- REG_RMW_FIELD(ah, AR_PHY_SFCORR_LOW, --- AR_PHY_SFCORR_LOW_M1_THRESH_LOW, --- m1ThreshLow); --- REG_RMW_FIELD(ah, AR_PHY_SFCORR_LOW, --- AR_PHY_SFCORR_LOW_M2_THRESH_LOW, --- m2ThreshLow); --- REG_RMW_FIELD(ah, AR_PHY_SFCORR, --- AR_PHY_SFCORR_M1_THRESH, --- m1Thresh); --- REG_RMW_FIELD(ah, AR_PHY_SFCORR, --- AR_PHY_SFCORR_M2_THRESH, --- m2Thresh); --- REG_RMW_FIELD(ah, AR_PHY_SFCORR, --- AR_PHY_SFCORR_M2COUNT_THR, --- m2CountThr); --- REG_RMW_FIELD(ah, AR_PHY_SFCORR_LOW, --- AR_PHY_SFCORR_LOW_M2COUNT_THR_LOW, --- m2CountThrLow); --- REG_RMW_FIELD(ah, AR_PHY_SFCORR_EXT, --- AR_PHY_SFCORR_EXT_M1_THRESH_LOW, --- m1ThreshLowExt); --- REG_RMW_FIELD(ah, AR_PHY_SFCORR_EXT, --- AR_PHY_SFCORR_EXT_M2_THRESH_LOW, --- m2ThreshLowExt); --- REG_RMW_FIELD(ah, AR_PHY_SFCORR_EXT, --- AR_PHY_SFCORR_EXT_M1_THRESH, --- m1ThreshExt); --- REG_RMW_FIELD(ah, AR_PHY_SFCORR_EXT, --- AR_PHY_SFCORR_EXT_M2_THRESH, --- m2ThreshExt); ---skip_ws_det: -- if (on) -- REG_SET_BIT(ah, AR_PHY_SFCORR_LOW, -- AR_PHY_SFCORR_LOW_USE_SELF_CORR_LOW); -diff --git a/package/kernel/mac80211/patches/ath9k/547-ath9k_led_defstate_fix.patch b/package/kernel/mac80211/patches/ath9k/547-ath9k_led_defstate_fix.patch -deleted file mode 100644 -index 5d84cf0c42..0000000000 ---- a/package/kernel/mac80211/patches/ath9k/547-ath9k_led_defstate_fix.patch -+++ /dev/null -@@ -1,29 +0,0 @@ --From: Michal Cieslakiewicz --Date: Sun, 31 Jan 2016 20:48:49 +0100 --Subject: [PATCH v4 2/8] mac80211: ath9k: set default state for platform LEDs -- --Support default state for platform LEDs connected to ath9k device. --Now LEDs are correctly set on or off at ath9k module initialization. --Very useful if power LED is connected to wireless chip. -- --Signed-off-by: Michal Cieslakiewicz ----- -- gpio.c | 7 +++++-- -- 1 file changed, 5 insertions(+), 2 deletions(-) -- ----- a/drivers/net/wireless/ath/ath9k/gpio.c --+++ b/drivers/net/wireless/ath/ath9k/gpio.c --@@ -74,8 +74,11 @@ static int ath_add_led(struct ath_softc -- ath9k_hw_gpio_request_out(sc->sc_ah, gpio->gpio, gpio->name, -- AR_GPIO_OUTPUT_MUX_AS_OUTPUT); -- --- /* LED off */ --- ath9k_hw_set_gpio(sc->sc_ah, gpio->gpio, gpio->active_low); --+ /* Set default LED state */ --+ if (gpio->default_state == LEDS_GPIO_DEFSTATE_ON) --+ ath9k_hw_set_gpio(sc->sc_ah, gpio->gpio, !gpio->active_low); --+ else --+ ath9k_hw_set_gpio(sc->sc_ah, gpio->gpio, gpio->active_low); -- -- return 0; -- } -diff --git a/package/kernel/mac80211/patches/ath9k/548-ath9k_enable_gpio_chip.patch b/package/kernel/mac80211/patches/ath9k/548-ath9k_enable_gpio_chip.patch -deleted file mode 100644 -index 78206d2860..0000000000 ---- a/package/kernel/mac80211/patches/ath9k/548-ath9k_enable_gpio_chip.patch -+++ /dev/null -@@ -1,251 +0,0 @@ --From: Michal Cieslakiewicz --Date: Sun, 31 Jan 2016 21:01:31 +0100 --Subject: [PATCH v4 4/8] mac80211: ath9k: enable access to GPIO -- --Enable access to GPIO chip and its pins for Atheros AR92xx --wireless devices. For now AR9285 and AR9287 are supported. -- --Signed-off-by: Michal Cieslakiewicz --Signed-off-by: Felix Fietkau ----- ----- a/drivers/net/wireless/ath/ath9k/ath9k.h --+++ b/drivers/net/wireless/ath/ath9k/ath9k.h --@@ -24,6 +24,7 @@ -- #include -- #include -- #include --+#include -- -- #include "common.h" -- #include "debug.h" --@@ -989,6 +990,14 @@ struct ath_led { -- struct led_classdev cdev; -- }; -- --+#ifdef CONFIG_GPIOLIB --+struct ath9k_gpio_chip { --+ struct ath_softc *sc; --+ char label[32]; --+ struct gpio_chip gchip; --+}; --+#endif --+ -- struct ath_softc { -- struct ieee80211_hw *hw; -- struct device *dev; --@@ -1044,6 +1053,9 @@ struct ath_softc { -- #ifdef CPTCFG_MAC80211_LEDS -- const char *led_default_trigger; -- struct list_head leds; --+#ifdef CONFIG_GPIOLIB --+ struct ath9k_gpio_chip *gpiochip; --+#endif -- #endif -- -- #ifdef CPTCFG_ATH9K_DEBUGFS ----- a/drivers/net/wireless/ath/ath9k/gpio.c --+++ b/drivers/net/wireless/ath/ath9k/gpio.c --@@ -16,13 +16,139 @@ -- -- #include "ath9k.h" -- #include --+#include --+ --+#ifdef CPTCFG_MAC80211_LEDS --+ --+#ifdef CONFIG_GPIOLIB --+ --+/***************/ --+/* GPIO Chip */ --+/***************/ --+ --+/* gpio_chip handler : set GPIO to input */ --+static int ath9k_gpio_pin_cfg_input(struct gpio_chip *chip, unsigned offset) --+{ --+ struct ath9k_gpio_chip *gc = container_of(chip, struct ath9k_gpio_chip, --+ gchip); --+ --+ ath9k_hw_gpio_request_in(gc->sc->sc_ah, offset, "ath9k-gpio"); --+ --+ return 0; --+} --+ --+/* gpio_chip handler : set GPIO to output */ --+static int ath9k_gpio_pin_cfg_output(struct gpio_chip *chip, unsigned offset, --+ int value) --+{ --+ struct ath9k_gpio_chip *gc = container_of(chip, struct ath9k_gpio_chip, --+ gchip); --+ --+ ath9k_hw_gpio_request_out(gc->sc->sc_ah, offset, "ath9k-gpio", --+ AR_GPIO_OUTPUT_MUX_AS_OUTPUT); --+ ath9k_hw_set_gpio(gc->sc->sc_ah, offset, value); --+ --+ return 0; --+} --+ --+/* gpio_chip handler : query GPIO direction (0=out, 1=in) */ --+static int ath9k_gpio_pin_get_dir(struct gpio_chip *chip, unsigned offset) --+{ --+ struct ath9k_gpio_chip *gc = container_of(chip, struct ath9k_gpio_chip, --+ gchip); --+ struct ath_hw *ah = gc->sc->sc_ah; --+ --+ return !((REG_READ(ah, AR_GPIO_OE_OUT) >> (offset * 2)) & 3); --+} --+ --+/* gpio_chip handler : get GPIO pin value */ --+static int ath9k_gpio_pin_get(struct gpio_chip *chip, unsigned offset) --+{ --+ struct ath9k_gpio_chip *gc = container_of(chip, struct ath9k_gpio_chip, --+ gchip); --+ --+ return ath9k_hw_gpio_get(gc->sc->sc_ah, offset); --+} --+ --+/* gpio_chip handler : set GPIO pin to value */ --+static void ath9k_gpio_pin_set(struct gpio_chip *chip, unsigned offset, --+ int value) --+{ --+ struct ath9k_gpio_chip *gc = container_of(chip, struct ath9k_gpio_chip, --+ gchip); --+ --+ ath9k_hw_set_gpio(gc->sc->sc_ah, offset, value); --+} --+ --+/* register GPIO chip */ --+static void ath9k_register_gpio_chip(struct ath_softc *sc) --+{ --+ struct ath9k_gpio_chip *gc; --+ struct ath_hw *ah = sc->sc_ah; --+ --+ gc = kzalloc(sizeof(struct ath9k_gpio_chip), GFP_KERNEL); --+ if (!gc) --+ return; --+ --+ gc->sc = sc; --+ snprintf(gc->label, sizeof(gc->label), "ath9k-%s", --+ wiphy_name(sc->hw->wiphy)); --+#ifdef CONFIG_OF --+#if LINUX_VERSION_CODE >= KERNEL_VERSION(4,5,0) --+ gc->gchip.parent = sc->dev; --+#else --+ gc->gchip.dev = sc->dev; --+#endif --+#endif --+ gc->gchip.label = gc->label; --+ gc->gchip.base = -1; /* determine base automatically */ --+ gc->gchip.ngpio = ah->caps.num_gpio_pins; --+ gc->gchip.direction_input = ath9k_gpio_pin_cfg_input; --+ gc->gchip.direction_output = ath9k_gpio_pin_cfg_output; --+ gc->gchip.get_direction = ath9k_gpio_pin_get_dir; --+ gc->gchip.get = ath9k_gpio_pin_get; --+ gc->gchip.set = ath9k_gpio_pin_set; --+ --+ if (gpiochip_add(&gc->gchip)) { --+ kfree(gc); --+ return; --+ } --+ --+#ifdef CONFIG_OF --+ gc->gchip.owner = NULL; --+#endif --+ sc->gpiochip = gc; --+} --+ --+/* remove GPIO chip */ --+static void ath9k_unregister_gpio_chip(struct ath_softc *sc) --+{ --+ struct ath9k_gpio_chip *gc = sc->gpiochip; --+ --+ if (!gc) --+ return; --+ --+ gpiochip_remove(&gc->gchip); --+ kfree(gc); --+ sc->gpiochip = NULL; --+} --+ --+#else /* CONFIG_GPIOLIB */ --+ --+static inline void ath9k_register_gpio_chip(struct ath_softc *sc) --+{ --+} --+ --+static inline void ath9k_unregister_gpio_chip(struct ath_softc *sc) --+{ --+} --+ --+#endif /* CONFIG_GPIOLIB */ -- -- /********************************/ -- /* LED functions */ -- /********************************/ -- ---#ifdef CPTCFG_MAC80211_LEDS --- -- static void ath_fill_led_pin(struct ath_softc *sc) -- { -- struct ath_hw *ah = sc->sc_ah; --@@ -80,6 +206,12 @@ static int ath_add_led(struct ath_softc -- else -- ath9k_hw_set_gpio(sc->sc_ah, gpio->gpio, gpio->active_low); -- --+#ifdef CONFIG_GPIOLIB --+ /* If there is GPIO chip configured, reserve LED pin */ --+ if (sc->gpiochip) --+ gpio_request(sc->gpiochip->gchip.base + gpio->gpio, gpio->name); --+#endif --+ -- return 0; -- } -- --@@ -136,17 +268,24 @@ void ath_deinit_leds(struct ath_softc *s -- -- while (!list_empty(&sc->leds)) { -- led = list_first_entry(&sc->leds, struct ath_led, list); --+#ifdef CONFIG_GPIOLIB --+ /* If there is GPIO chip configured, free LED pin */ --+ if (sc->gpiochip) --+ gpio_free(sc->gpiochip->gchip.base + led->gpio->gpio); --+#endif -- list_del(&led->list); -- ath_led_brightness(&led->cdev, LED_OFF); -- led_classdev_unregister(&led->cdev); -- ath9k_hw_gpio_free(sc->sc_ah, led->gpio->gpio); -- kfree(led); -- } --+ ath9k_unregister_gpio_chip(sc); -- } -- -- void ath_init_leds(struct ath_softc *sc) -- { -- struct ath9k_platform_data *pdata = sc->dev->platform_data; --+ struct device_node *np = sc->dev->of_node; -- char led_name[32]; -- const char *trigger; -- int i; --@@ -156,6 +295,15 @@ void ath_init_leds(struct ath_softc *sc) -- if (AR_SREV_9100(sc->sc_ah)) -- return; -- --+ if (!np) --+ ath9k_register_gpio_chip(sc); --+ --+ /* setup gpio controller only if requested and skip the led_pin setup */ --+ if (of_property_read_bool(np, "gpio-controller")) { --+ ath9k_register_gpio_chip(sc); --+ return; --+ } --+ -- ath_fill_led_pin(sc); -- -- if (pdata && pdata->leds && pdata->num_leds) --@@ -180,6 +328,7 @@ void ath_init_leds(struct ath_softc *sc) -- ath_create_gpio_led(sc, sc->sc_ah->led_pin, led_name, trigger, -- !sc->sc_ah->config.led_active_high); -- } --+ -- #endif -- -- /*******************/ -diff --git a/package/kernel/mac80211/patches/ath9k/549-ath9k_enable_gpio_buttons.patch b/package/kernel/mac80211/patches/ath9k/549-ath9k_enable_gpio_buttons.patch -deleted file mode 100644 -index 716e09f351..0000000000 ---- a/package/kernel/mac80211/patches/ath9k/549-ath9k_enable_gpio_buttons.patch -+++ /dev/null -@@ -1,143 +0,0 @@ --From: Michal Cieslakiewicz --Subject: [PATCH v5 5/8] mac80211: ath9k: enable GPIO buttons -- --Enable platform-defined GPIO button support for ath9k device. --Key poller is activated for attached platform buttons. --Requires ath9k GPIO chip access. -- --Signed-off-by: Michal Cieslakiewicz --Signed-off-by: Felix Fietkau ----- ----- a/drivers/net/wireless/ath/ath9k/ath9k.h --+++ b/drivers/net/wireless/ath/ath9k/ath9k.h --@@ -1055,6 +1055,7 @@ struct ath_softc { -- struct list_head leds; -- #ifdef CONFIG_GPIOLIB -- struct ath9k_gpio_chip *gpiochip; --+ struct platform_device *btnpdev; /* gpio-keys-polled */ -- #endif -- #endif -- ----- a/drivers/net/wireless/ath/ath9k/gpio.c --+++ b/drivers/net/wireless/ath/ath9k/gpio.c --@@ -17,6 +17,8 @@ -- #include "ath9k.h" -- #include -- #include --+#include --+#include -- -- #ifdef CPTCFG_MAC80211_LEDS -- --@@ -133,6 +135,67 @@ static void ath9k_unregister_gpio_chip(s -- sc->gpiochip = NULL; -- } -- --+/******************/ --+/* GPIO Buttons */ --+/******************/ --+ --+/* add GPIO buttons */ --+static void ath9k_init_buttons(struct ath_softc *sc) --+{ --+ struct ath9k_platform_data *pdata = sc->dev->platform_data; --+ struct platform_device *pdev; --+ struct gpio_keys_platform_data gkpdata; --+ struct gpio_keys_button *bt; --+ int i; --+ --+ if (!sc->gpiochip) --+ return; --+ --+ if (!pdata || !pdata->btns || !pdata->num_btns) --+ return; --+ --+ bt = devm_kmemdup(sc->dev, pdata->btns, --+ pdata->num_btns * sizeof(struct gpio_keys_button), --+ GFP_KERNEL); --+ if (!bt) --+ return; --+ --+ for (i = 0; i < pdata->num_btns; i++) { --+ if (pdata->btns[i].gpio == sc->sc_ah->led_pin) --+ sc->sc_ah->led_pin = -1; --+ --+ ath9k_hw_gpio_request_in(sc->sc_ah, pdata->btns[i].gpio, --+ "ath9k-gpio"); --+ bt[i].gpio = sc->gpiochip->gchip.base + pdata->btns[i].gpio; --+ } --+ --+ memset(&gkpdata, 0, sizeof(struct gpio_keys_platform_data)); --+ gkpdata.buttons = bt; --+ gkpdata.nbuttons = pdata->num_btns; --+ gkpdata.poll_interval = pdata->btn_poll_interval; --+ --+ pdev = platform_device_register_data(sc->dev, "gpio-keys-polled", --+ PLATFORM_DEVID_AUTO, &gkpdata, --+ sizeof(gkpdata)); --+ if (!IS_ERR_OR_NULL(pdev)) --+ sc->btnpdev = pdev; --+ else { --+ sc->btnpdev = NULL; --+ devm_kfree(sc->dev, bt); --+ } --+} --+ --+/* remove GPIO buttons */ --+static void ath9k_deinit_buttons(struct ath_softc *sc) --+{ --+ if (!sc->gpiochip || !sc->btnpdev) --+ return; --+ --+ platform_device_unregister(sc->btnpdev); --+ --+ sc->btnpdev = NULL; --+} --+ -- #else /* CONFIG_GPIOLIB */ -- -- static inline void ath9k_register_gpio_chip(struct ath_softc *sc) --@@ -143,6 +206,14 @@ static inline void ath9k_unregister_gpio -- { -- } -- --+static inline void ath9k_init_buttons(struct ath_softc *sc) --+{ --+} --+ --+static inline void ath9k_deinit_buttons(struct ath_softc *sc) --+{ --+} --+ -- #endif /* CONFIG_GPIOLIB */ -- -- /********************************/ --@@ -266,6 +337,7 @@ void ath_deinit_leds(struct ath_softc *s -- { -- struct ath_led *led; -- --+ ath9k_deinit_buttons(sc); -- while (!list_empty(&sc->leds)) { -- led = list_first_entry(&sc->leds, struct ath_led, list); -- #ifdef CONFIG_GPIOLIB --@@ -305,6 +377,7 @@ void ath_init_leds(struct ath_softc *sc) -- } -- -- ath_fill_led_pin(sc); --+ ath9k_init_buttons(sc); -- -- if (pdata && pdata->leds && pdata->num_leds) -- for (i = 0; i < pdata->num_leds; i++) { ----- a/include/linux/ath9k_platform.h --+++ b/include/linux/ath9k_platform.h --@@ -49,6 +49,10 @@ struct ath9k_platform_data { -- -- int num_leds; -- const struct gpio_led *leds; --+ --+ unsigned num_btns; --+ const struct gpio_keys_button *btns; --+ unsigned btn_poll_interval; -- }; -- -- #endif /* _LINUX_ATH9K_PLATFORM_H */ -diff --git a/package/kernel/mac80211/patches/ath9k/551-ath9k_ubnt_uap_plus_hsr.patch b/package/kernel/mac80211/patches/ath9k/551-ath9k_ubnt_uap_plus_hsr.patch -deleted file mode 100644 -index efc4b9187c..0000000000 ---- a/package/kernel/mac80211/patches/ath9k/551-ath9k_ubnt_uap_plus_hsr.patch -+++ /dev/null -@@ -1,403 +0,0 @@ ----- a/drivers/net/wireless/ath/ath9k/channel.c --+++ b/drivers/net/wireless/ath/ath9k/channel.c --@@ -15,6 +15,7 @@ -- */ -- -- #include "ath9k.h" --+#include "hsr.h" -- -- /* Set/change channels. If the channel is really being changed, it's done -- * by reseting the chip. To accomplish this we must first cleanup any pending --@@ -22,6 +23,7 @@ -- */ -- static int ath_set_channel(struct ath_softc *sc) -- { --+ struct device_node *np = sc->dev->of_node; -- struct ath_hw *ah = sc->sc_ah; -- struct ath_common *common = ath9k_hw_common(ah); -- struct ieee80211_hw *hw = sc->hw; --@@ -42,6 +44,11 @@ static int ath_set_channel(struct ath_so -- ath_dbg(common, CONFIG, "Set channel: %d MHz width: %d\n", -- chan->center_freq, chandef->width); -- --+ if (of_property_read_bool(np, "ubnt,hsr")) { --+ ath9k_hsr_enable(ah, chandef->width, chan->center_freq); --+ ath9k_hsr_status(ah); --+ } --+ -- /* update survey stats for the old channel before switching */ -- spin_lock_irqsave(&common->cc_lock, flags); -- ath_update_survey_stats(sc); ----- /dev/null --+++ b/drivers/net/wireless/ath/ath9k/hsr.c --@@ -0,0 +1,247 @@ --+/* --+ * --+ * The MIT License (MIT) --+ * --+ * Copyright (c) 2015 Kirill Berezin --+ * --+ * Permission is hereby granted, free of charge, to any person obtaining a copy --+ * of this software and associated documentation files (the "Software"), to deal --+ * in the Software without restriction, including without limitation the rights --+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell --+ * copies of the Software, and to permit persons to whom the Software is --+ * furnished to do so, subject to the following conditions: --+ * --+ * The above copyright notice and this permission notice shall be included in --+ * all copies or substantial portions of the Software. --+ * --+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR --+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, --+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE --+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER --+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, --+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE --+ * SOFTWARE. --+ * --+ */ --+ --+#include --+#include --+#include --+#include --+#include --+#include --+#include --+#include --+ --+#include "hw.h" --+#include "ath9k.h" --+ --+#define HSR_GPIO_CSN 8 --+#define HSR_GPIO_CLK 6 --+#define HSR_GPIO_DOUT 7 --+#define HSR_GPIO_DIN 5 --+ --+/* delays are in useconds */ --+#define HSR_DELAY_HALF_TICK 100 --+#define HSR_DELAY_PRE_WRITE 75 --+#define HSR_DELAY_FINAL 20000 --+#define HSR_DELAY_TRAILING 200 --+ --+void ath9k_hsr_init(struct ath_hw *ah) --+{ --+ ath9k_hw_gpio_request_in(ah, HSR_GPIO_DIN, NULL); --+ ath9k_hw_gpio_request_out(ah, HSR_GPIO_CSN, NULL, --+ AR_GPIO_OUTPUT_MUX_AS_OUTPUT); --+ ath9k_hw_gpio_request_out(ah, HSR_GPIO_CLK, NULL, --+ AR_GPIO_OUTPUT_MUX_AS_OUTPUT); --+ ath9k_hw_gpio_request_out(ah, HSR_GPIO_DOUT, NULL, --+ AR_GPIO_OUTPUT_MUX_AS_OUTPUT); --+ --+ ath9k_hw_set_gpio(ah, HSR_GPIO_CSN, 1); --+ ath9k_hw_set_gpio(ah, HSR_GPIO_CLK, 0); --+ ath9k_hw_set_gpio(ah, HSR_GPIO_DOUT, 0); --+ --+ udelay(HSR_DELAY_TRAILING); --+} --+ --+static u32 ath9k_hsr_write_byte(struct ath_hw *ah, int delay, u32 value) --+{ --+ struct ath_common *common = ath9k_hw_common(ah); --+ int i; --+ u32 rval = 0; --+ --+ udelay(delay); --+ --+ ath9k_hw_set_gpio(ah, HSR_GPIO_CLK, 0); --+ udelay(HSR_DELAY_HALF_TICK); --+ --+ ath9k_hw_set_gpio(ah, HSR_GPIO_CSN, 0); --+ udelay(HSR_DELAY_HALF_TICK); --+ --+ for (i = 0; i < 8; ++i) { --+ rval = rval << 1; --+ --+ /* pattern is left to right, that is 7-th bit runs first */ --+ ath9k_hw_set_gpio(ah, HSR_GPIO_DOUT, (value >> (7 - i)) & 0x1); --+ udelay(HSR_DELAY_HALF_TICK); --+ --+ ath9k_hw_set_gpio(ah, HSR_GPIO_CLK, 1); --+ udelay(HSR_DELAY_HALF_TICK); --+ --+ rval |= ath9k_hw_gpio_get(ah, HSR_GPIO_DIN); --+ --+ ath9k_hw_set_gpio(ah, HSR_GPIO_CLK, 0); --+ udelay(HSR_DELAY_HALF_TICK); --+ } --+ --+ ath9k_hw_set_gpio(ah, HSR_GPIO_CSN, 1); --+ udelay(HSR_DELAY_HALF_TICK); --+ --+ ath_dbg(common, CONFIG, "ath9k_hsr_write_byte: write byte %d return value is %d %c\n", --+ value, rval, rval > 32 ? rval : '-'); --+ --+ return rval & 0xff; --+} --+ --+static int ath9k_hsr_write_a_chain(struct ath_hw *ah, char *chain, int items) --+{ --+ int status = 0; --+ int i = 0; --+ int err; --+ --+ /* a preamble */ --+ ath9k_hsr_write_byte(ah, HSR_DELAY_PRE_WRITE, 0); --+ status = ath9k_hsr_write_byte(ah, HSR_DELAY_PRE_WRITE, 0); --+ --+ /* clear HSR's reply buffer */ --+ if (status) { --+ int loop = 0; --+ --+ for (loop = 0; (loop < 42) && status; ++loop) --+ status = ath9k_hsr_write_byte(ah, HSR_DELAY_PRE_WRITE, --+ 0); --+ --+ if (loop >= 42) { --+ ATH_DBG_WARN(1, --+ "ath9k_hsr_write_a_chain: can't clear an output buffer after a 42 cycles.\n"); --+ return -1; --+ } --+ } --+ --+ for (i = 0; (i < items) && (chain[i] != 0); ++i) --+ ath9k_hsr_write_byte(ah, HSR_DELAY_PRE_WRITE, (u32)chain[i]); --+ --+ ath9k_hsr_write_byte(ah, HSR_DELAY_PRE_WRITE, 0); --+ mdelay(HSR_DELAY_FINAL / 1000); --+ --+ /* reply */ --+ memset(chain, 0, items); --+ --+ ath9k_hsr_write_byte(ah, HSR_DELAY_PRE_WRITE, 0); --+ udelay(HSR_DELAY_TRAILING); --+ --+ for (i = 0; i < (items - 1); ++i) { --+ u32 ret; --+ --+ ret = ath9k_hsr_write_byte(ah, HSR_DELAY_PRE_WRITE, 0); --+ if (ret != 0) --+ chain[i] = (char)ret; --+ else --+ break; --+ --+ udelay(HSR_DELAY_TRAILING); --+ } --+ --+ if (i <= 1) --+ return 0; --+ --+ err = kstrtoint(chain + 1, 10, &i); --+ if (err) --+ return err; --+ --+ return i; --+} --+ --+int ath9k_hsr_disable(struct ath_hw *ah) --+{ --+ char cmd[10] = {'b', '4', '0', 0, 0, 0, 0, 0, 0, 0}; --+ int ret; --+ --+ ret = ath9k_hsr_write_a_chain(ah, cmd, sizeof(cmd)); --+ if ((ret > 0) && (*cmd == 'B')) --+ return 0; --+ --+ return -1; --+} --+ --+int ath9k_hsr_enable(struct ath_hw *ah, int bw, int fq) --+{ --+ char cmd[10]; --+ int ret; --+ --+ /* Bandwidth argument is 0 sometimes. Assume default 802.11bgn --+ * 20MHz on invalid values --+ */ --+ if ((bw != 5) && (bw != 10) && (bw != 20) && (bw != 40)) --+ bw = 20; --+ --+ memset(cmd, 0, sizeof(cmd)); --+ *cmd = 'b'; --+ snprintf(cmd + 1, 3, "%02d", bw); --+ --+ ret = ath9k_hsr_write_a_chain(ah, cmd, sizeof(cmd)); --+ if ((*cmd != 'B') || (ret != bw)) { --+ ATH_DBG_WARN(1, --+ "ath9k_hsr_enable: failed changing bandwidth -> set (%d,%d) reply (%d, %d)\n", --+ 'b', bw, *cmd, ret); --+ return -1; --+ } --+ --+ memset(cmd, 0, sizeof(cmd)); --+ *cmd = 'x'; --+ ret = ath9k_hsr_write_a_chain(ah, cmd, sizeof(cmd)); --+ if (*cmd != 'X') { --+ ATH_DBG_WARN(1, --+ "ath9k_hsr_enable: failed 'x' command -> reply (%d, %d)\n", --+ *cmd, ret); --+ return -1; --+ } --+ --+ memset(cmd, 0, sizeof(cmd)); --+ *cmd = 'm'; --+ ret = ath9k_hsr_write_a_chain(ah, cmd, sizeof(cmd)); --+ if (*cmd != 'M') { --+ ATH_DBG_WARN(1, --+ "ath9k_hsr_enable: failed 'm' command -> reply (%d, %d)\n", --+ *cmd, ret); --+ return -1; --+ } --+ --+ memset(cmd, 0, sizeof(cmd)); --+ *cmd = 'f'; --+ snprintf(cmd + 1, 6, "%05d", fq); --+ ret = ath9k_hsr_write_a_chain(ah, cmd, sizeof(cmd)); --+ if ((*cmd != 'F') && (ret != fq)) { --+ ATH_DBG_WARN(1, --+ "ath9k_hsr_enable: failed set frequency -> reply (%d, %d)\n", --+ *cmd, ret); --+ return -1; --+ } --+ --+ return 0; --+} --+ --+int ath9k_hsr_status(struct ath_hw *ah) --+{ --+ char cmd[10] = {'s', 0, 0, 0, 0, 0, 0, 0, 0, 0}; --+ int ret; --+ --+ ret = ath9k_hsr_write_a_chain(ah, cmd, sizeof(cmd)); --+ if (*cmd != 'S') { --+ ATH_DBG_WARN(1, "ath9k_hsr_status: returned %d,%d\n", *cmd, --+ ret); --+ return -1; --+ } --+ --+ return 0; --+} ----- /dev/null --+++ b/drivers/net/wireless/ath/ath9k/hsr.h --@@ -0,0 +1,48 @@ --+/* --+ * The MIT License (MIT) --+ * --+ * Copyright (c) 2015 Kirill Berezin --+ * --+ * Permission is hereby granted, free of charge, to any person obtaining a copy --+ * of this software and associated documentation files (the "Software"), to deal --+ * in the Software without restriction, including without limitation the rights --+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell --+ * copies of the Software, and to permit persons to whom the Software is --+ * furnished to do so, subject to the following conditions: --+ * --+ * The above copyright notice and this permission notice shall be included in --+ * all copies or substantial portions of the Software. --+ * --+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR --+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, --+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE --+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER --+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, --+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE --+ * SOFTWARE. --+ */ --+ --+#ifndef HSR_H --+#define HSR_H --+ --+#ifdef CPTCFG_ATH9K_UBNTHSR --+ --+void ath9k_hsr_init(struct ath_hw *ah); --+int ath9k_hsr_disable(struct ath_hw *ah); --+int ath9k_hsr_enable(struct ath_hw *ah, int bw, int fq); --+int ath9k_hsr_status(struct ath_hw *ah); --+ --+#else --+static inline void ath9k_hsr_init(struct ath_hw *ah) {} --+ --+static inline int ath9k_hsr_enable(struct ath_hw *ah, int bw, int fq) --+{ --+ return 0; --+} --+ --+static inline int ath9k_hsr_disable(struct ath_hw *ah) { return 0; } --+static inline int ath9k_hsr_status(struct ath_hw *ah) { return 0; } --+ --+#endif --+ --+#endif /* HSR_H */ ----- a/drivers/net/wireless/ath/ath9k/main.c --+++ b/drivers/net/wireless/ath/ath9k/main.c --@@ -18,6 +18,7 @@ -- #include -- #include "ath9k.h" -- #include "btcoex.h" --+#include "hsr.h" -- -- static void ath9k_flush(struct ieee80211_hw *hw, struct ieee80211_vif *vif, -- u32 queues, bool drop); --@@ -659,6 +660,7 @@ void ath_reset_work(struct work_struct * -- static int ath9k_start(struct ieee80211_hw *hw) -- { -- struct ath_softc *sc = hw->priv; --+ struct device_node *np = sc->dev->of_node; -- struct ath_hw *ah = sc->sc_ah; -- struct ath_common *common = ath9k_hw_common(ah); -- struct ieee80211_channel *curchan = sc->cur_chan->chandef.chan; --@@ -737,6 +739,11 @@ static int ath9k_start(struct ieee80211_ -- AR_GPIO_OUTPUT_MUX_AS_OUTPUT); -- } -- --+ if (of_property_read_bool(np, "ubnt,hsr")) { --+ ath9k_hsr_init(ah); --+ ath9k_hsr_disable(ah); --+ } --+ -- /* -- * Reset key cache to sane defaults (all entries cleared) instead of -- * semi-random values after suspend/resume. ----- a/drivers/net/wireless/ath/ath9k/Makefile --+++ b/drivers/net/wireless/ath/ath9k/Makefile --@@ -17,6 +17,7 @@ ath9k-$(CPTCFG_ATH9K_DFS_CERTIFIED) += d -- ath9k-$(CPTCFG_ATH9K_TX99) += tx99.o -- ath9k-$(CPTCFG_ATH9K_WOW) += wow.o -- ath9k-$(CPTCFG_ATH9K_HWRNG) += rng.o --+ath9k-$(CPTCFG_ATH9K_UBNTHSR) += hsr.o -- -- ath9k-$(CPTCFG_ATH9K_DEBUGFS) += debug.o -- ----- a/local-symbols --+++ b/local-symbols --@@ -129,6 +129,7 @@ ATH9K_WOW= -- ATH9K_RFKILL= -- ATH9K_CHANNEL_CONTEXT= -- ATH9K_PCOEM= --+ATH9K_UBNTHSR= -- ATH9K_PCI_NO_EEPROM= -- ATH9K_HTC= -- ATH9K_HTC_DEBUGFS= ----- a/drivers/net/wireless/ath/ath9k/Kconfig --+++ b/drivers/net/wireless/ath/ath9k/Kconfig --@@ -58,6 +58,19 @@ config ATH9K_AHB -- Say Y, if you have a SoC with a compatible built-in -- wireless MAC. Say N if unsure. -- --+config ATH9K_UBNTHSR --+ bool "Ubiquiti UniFi Outdoor Plus HSR support" --+ depends on ATH9K --+ ---help--- --+ This options enables code to control the HSR RF --+ filter in the receive path of the Ubiquiti UniFi --+ Outdoor Plus access point. --+ --+ Say Y if you want to use the access point. The --+ code will only be used if the device is detected, --+ so it does not harm other setup other than occupying --+ a bit of memory. --+ -- config ATH9K_DEBUGFS -- bool "Atheros ath9k debugging" -- depends on ATH9K && DEBUG_FS -diff --git a/package/kernel/mac80211/patches/ath9k/552-ath9k-ahb_of.patch b/package/kernel/mac80211/patches/ath9k/552-ath9k-ahb_of.patch -deleted file mode 100644 -index 57eef54e89..0000000000 ---- a/package/kernel/mac80211/patches/ath9k/552-ath9k-ahb_of.patch -+++ /dev/null -@@ -1,331 +0,0 @@ ----- a/drivers/net/wireless/ath/ath9k/ahb.c --+++ b/drivers/net/wireless/ath/ath9k/ahb.c --@@ -20,7 +20,15 @@ -- #include -- #include -- #include --+#include -- #include "ath9k.h" --+#include --+ --+#ifdef CONFIG_OF --+#include --+#include --+#include --+#endif -- -- static const struct platform_device_id ath9k_platform_id_table[] = { -- { --@@ -69,6 +77,236 @@ static const struct ath_bus_ops ath_ahb_ -- .eeprom_read = ath_ahb_eeprom_read, -- }; -- --+#ifdef CONFIG_OF --+ --+#define QCA955X_DDR_CTL_CONFIG 0x108 --+#define QCA955X_DDR_CTL_CONFIG_ACT_WMAC BIT(23) --+ --+static int of_get_wifi_cal(struct device_node *np, struct ath9k_platform_data *pdata) --+{ --+#ifdef CONFIG_MTD --+ struct device_node *mtd_np = NULL; --+ size_t retlen; --+ int size, ret; --+ struct mtd_info *mtd; --+ const char *part; --+ const __be32 *list; --+ phandle phandle; --+ --+ list = of_get_property(np, "mtd-cal-data", &size); --+ if (!list) --+ return 0; --+ --+ if (size != (2 * sizeof(*list))) --+ return 1; --+ --+ phandle = be32_to_cpup(list++); --+ if (phandle) --+ mtd_np = of_find_node_by_phandle(phandle); --+ --+ if (!mtd_np) --+ return 1; --+ --+ part = of_get_property(mtd_np, "label", NULL); --+ if (!part) --+ part = mtd_np->name; --+ --+ mtd = get_mtd_device_nm(part); --+ if (IS_ERR(mtd)) --+ return 1; --+ --+ ret = mtd_read(mtd, be32_to_cpup(list), sizeof(pdata->eeprom_data), --+ &retlen, (u8*)pdata->eeprom_data); --+ put_mtd_device(mtd); --+ --+#endif --+ return 0; --+} --+ --+static int ar913x_wmac_reset(void) --+{ --+ ath79_device_reset_set(AR913X_RESET_AMBA2WMAC); --+ mdelay(10); --+ --+ ath79_device_reset_clear(AR913X_RESET_AMBA2WMAC); --+ mdelay(10); --+ --+ return 0; --+} --+ --+static int ar933x_wmac_reset(void) --+{ --+ int retries = 20; --+ --+ ath79_device_reset_set(AR933X_RESET_WMAC); --+ ath79_device_reset_clear(AR933X_RESET_WMAC); --+ --+ while (1) { --+ u32 bootstrap; --+ --+ bootstrap = ath79_reset_rr(AR933X_RESET_REG_BOOTSTRAP); --+ if ((bootstrap & AR933X_BOOTSTRAP_EEPBUSY) == 0) --+ return 0; --+ --+ if (retries-- == 0) --+ break; --+ --+ udelay(10000); --+ } --+ --+ pr_err("ar933x: WMAC reset timed out"); --+ return -ETIMEDOUT; --+} --+ --+static int qca955x_wmac_reset(void) --+{ --+ int i; --+ --+ /* Try to wait for WMAC DDR activity to stop */ --+ for (i = 0; i < 10; i++) { --+ if (!(__raw_readl(ath79_ddr_base + QCA955X_DDR_CTL_CONFIG) & --+ QCA955X_DDR_CTL_CONFIG_ACT_WMAC)) --+ break; --+ --+ udelay(10); --+ } --+ --+ ath79_device_reset_set(QCA955X_RESET_RTC); --+ udelay(10); --+ ath79_device_reset_clear(QCA955X_RESET_RTC); --+ udelay(10); --+ --+ return 0; --+} --+ --+enum { --+ AR913X_WMAC = 0, --+ AR933X_WMAC, --+ AR934X_WMAC, --+ QCA953X_WMAC, --+ QCA955X_WMAC, --+ QCA956X_WMAC, --+}; --+ --+static int ar9330_get_soc_revision(void) --+{ --+ if (ath79_soc_rev == 1) --+ return ath79_soc_rev; --+ --+ return 0; --+} --+ --+static int ath79_get_soc_revision(void) --+{ --+ return ath79_soc_rev; --+} --+ --+static const struct of_ath_ahb_data { --+ u16 dev_id; --+ u32 bootstrap_reg; --+ u32 bootstrap_ref; --+ --+ int (*soc_revision)(void); --+ int (*wmac_reset)(void); --+} of_ath_ahb_data[] = { --+ [AR913X_WMAC] = { --+ .dev_id = AR5416_AR9100_DEVID, --+ .wmac_reset = ar913x_wmac_reset, --+ --+ }, --+ [AR933X_WMAC] = { --+ .dev_id = AR9300_DEVID_AR9330, --+ .bootstrap_reg = AR933X_RESET_REG_BOOTSTRAP, --+ .bootstrap_ref = AR933X_BOOTSTRAP_REF_CLK_40, --+ .soc_revision = ar9330_get_soc_revision, --+ .wmac_reset = ar933x_wmac_reset, --+ }, --+ [AR934X_WMAC] = { --+ .dev_id = AR9300_DEVID_AR9340, --+ .bootstrap_reg = AR934X_RESET_REG_BOOTSTRAP, --+ .bootstrap_ref = AR934X_BOOTSTRAP_REF_CLK_40, --+ .soc_revision = ath79_get_soc_revision, --+ }, --+ [QCA953X_WMAC] = { --+ .dev_id = AR9300_DEVID_AR953X, --+ .bootstrap_reg = QCA953X_RESET_REG_BOOTSTRAP, --+ .bootstrap_ref = QCA953X_BOOTSTRAP_REF_CLK_40, --+ .soc_revision = ath79_get_soc_revision, --+ }, --+ [QCA955X_WMAC] = { --+ .dev_id = AR9300_DEVID_QCA955X, --+ .bootstrap_reg = QCA955X_RESET_REG_BOOTSTRAP, --+ .bootstrap_ref = QCA955X_BOOTSTRAP_REF_CLK_40, --+ .wmac_reset = qca955x_wmac_reset, --+ }, --+ [QCA956X_WMAC] = { --+ .dev_id = AR9300_DEVID_QCA956X, --+ .bootstrap_reg = QCA956X_RESET_REG_BOOTSTRAP, --+ .bootstrap_ref = QCA956X_BOOTSTRAP_REF_CLK_40, --+ .soc_revision = ath79_get_soc_revision, --+ }, --+}; --+ --+const struct of_device_id of_ath_ahb_match[] = { --+ { .compatible = "qca,ar9130-wmac", .data = &of_ath_ahb_data[AR913X_WMAC] }, --+ { .compatible = "qca,ar9330-wmac", .data = &of_ath_ahb_data[AR933X_WMAC] }, --+ { .compatible = "qca,ar9340-wmac", .data = &of_ath_ahb_data[AR934X_WMAC] }, --+ { .compatible = "qca,qca9530-wmac", .data = &of_ath_ahb_data[QCA953X_WMAC] }, --+ { .compatible = "qca,qca9550-wmac", .data = &of_ath_ahb_data[QCA955X_WMAC] }, --+ { .compatible = "qca,qca9560-wmac", .data = &of_ath_ahb_data[QCA956X_WMAC] }, --+ {}, --+}; --+MODULE_DEVICE_TABLE(of, of_ath_ahb_match); --+ --+static int of_ath_ahb_probe(struct platform_device *pdev) --+{ --+ struct ath9k_platform_data *pdata; --+ const struct of_device_id *match; --+ const struct of_ath_ahb_data *data; --+ u8 led_pin; --+ --+ match = of_match_device(of_ath_ahb_match, &pdev->dev); --+ data = (const struct of_ath_ahb_data *)match->data; --+ --+ pdata = dev_get_platdata(&pdev->dev); --+ --+ if (!of_property_read_u8(pdev->dev.of_node, "qca,led-pin", &led_pin)) --+ pdata->led_pin = led_pin; --+ else --+ pdata->led_pin = -1; --+ --+ if (of_property_read_bool(pdev->dev.of_node, "qca,tx-gain-buffalo")) --+ pdata->tx_gain_buffalo = true; --+ --+ if (data->wmac_reset) { --+ data->wmac_reset(); --+ pdata->external_reset = data->wmac_reset; --+ } --+ --+ if (data->dev_id == AR9300_DEVID_AR953X) { --+ /* --+ * QCA953x only supports 25MHz refclk. --+ * Some vendors have an invalid bootstrap option --+ * set, which would break the WMAC here. --+ */ --+ pdata->is_clk_25mhz = true; --+ } else if (data->bootstrap_reg && data->bootstrap_ref) { --+ u32 t = ath79_reset_rr(data->bootstrap_reg); --+ if (t & data->bootstrap_ref) --+ pdata->is_clk_25mhz = false; --+ else --+ pdata->is_clk_25mhz = true; --+ } --+ --+ pdata->get_mac_revision = data->soc_revision; --+ --+ if (of_get_wifi_cal(pdev->dev.of_node, pdata)) --+ dev_err(&pdev->dev, "failed to load calibration data from mtd device\n"); --+ --+ return data->dev_id; --+} --+#endif --+ -- static int ath_ahb_probe(struct platform_device *pdev) -- { -- void __iomem *mem; --@@ -80,6 +318,17 @@ static int ath_ahb_probe(struct platform -- int ret = 0; -- struct ath_hw *ah; -- char hw_name[64]; --+ u16 dev_id; --+ --+ if (id) --+ dev_id = id->driver_data; --+ --+#ifdef CONFIG_OF --+ if (pdev->dev.of_node) --+ pdev->dev.platform_data = devm_kzalloc(&pdev->dev, --+ sizeof(struct ath9k_platform_data), --+ GFP_KERNEL); --+#endif -- -- if (!dev_get_platdata(&pdev->dev)) { -- dev_err(&pdev->dev, "no platform data specified\n"); --@@ -118,13 +367,16 @@ static int ath_ahb_probe(struct platform -- sc->mem = mem; -- sc->irq = irq; -- --+#ifdef CONFIG_OF --+ dev_id = of_ath_ahb_probe(pdev); --+#endif -- ret = request_irq(irq, ath_isr, IRQF_SHARED, "ath9k", sc); -- if (ret) { -- dev_err(&pdev->dev, "request_irq failed\n"); -- goto err_free_hw; -- } -- --- ret = ath9k_init_device(id->driver_data, sc, &ath_ahb_bus_ops); --+ ret = ath9k_init_device(dev_id, sc, &ath_ahb_bus_ops); -- if (ret) { -- dev_err(&pdev->dev, "failed to initialize device\n"); -- goto err_irq; --@@ -155,6 +407,9 @@ static int ath_ahb_remove(struct platfor -- free_irq(sc->irq, sc); -- ieee80211_free_hw(sc->hw); -- } --+#ifdef CONFIG_OF --+ pdev->dev.platform_data = NULL; --+#endif -- -- return 0; -- } --@@ -164,6 +419,9 @@ static struct platform_driver ath_ahb_dr -- .remove = ath_ahb_remove, -- .driver = { -- .name = "ath9k", --+#ifdef CONFIG_OF --+ .of_match_table = of_ath_ahb_match, --+#endif -- }, -- .id_table = ath9k_platform_id_table, -- }; ----- a/drivers/net/wireless/ath/ath9k/ath9k.h --+++ b/drivers/net/wireless/ath/ath9k/ath9k.h --@@ -25,6 +25,7 @@ -- #include -- #include -- #include --+#include -- -- #include "common.h" -- #include "debug.h" --@@ -1011,6 +1012,9 @@ struct ath_softc { -- struct ath_hw *sc_ah; -- void __iomem *mem; -- int irq; --+#ifdef CONFIG_OF --+ struct reset_control *reset; --+#endif -- spinlock_t sc_serial_rw; -- spinlock_t sc_pm_lock; -- spinlock_t sc_pcu_lock; -diff --git a/package/kernel/mac80211/patches/ath9k/553-ath9k_of_gpio_mask.patch b/package/kernel/mac80211/patches/ath9k/553-ath9k_of_gpio_mask.patch -deleted file mode 100644 -index 6d1820ecb7..0000000000 ---- a/package/kernel/mac80211/patches/ath9k/553-ath9k_of_gpio_mask.patch -+++ /dev/null -@@ -1,25 +0,0 @@ ----- a/drivers/net/wireless/ath/ath9k/init.c --+++ b/drivers/net/wireless/ath/ath9k/init.c --@@ -696,6 +696,12 @@ static int ath9k_of_init(struct ath_soft -- return 0; -- } -- --+static void ath9k_of_gpio_mask(struct ath_softc *sc) --+{ --+ of_property_read_u32(sc->dev->of_node, "qca,gpio-mask", --+ &sc->sc_ah->caps.gpio_mask); --+} --+ -- static int ath9k_init_softc(u16 devid, struct ath_softc *sc, -- const struct ath_bus_ops *bus_ops) -- { --@@ -803,6 +809,9 @@ static int ath9k_init_softc(u16 devid, s -- if (ret) -- goto err_hw; -- --+ /* GPIO mask quirk */ --+ ath9k_of_gpio_mask(sc); --+ -- ret = ath9k_init_queues(sc); -- if (ret) -- goto err_queues; -diff --git a/package/kernel/mac80211/patches/brcm/040-brcmutil_option.patch b/package/kernel/mac80211/patches/brcm/040-brcmutil_option.patch -deleted file mode 100644 -index 3e8505b5b4..0000000000 ---- a/package/kernel/mac80211/patches/brcm/040-brcmutil_option.patch -+++ /dev/null -@@ -1,10 +0,0 @@ ----- a/drivers/net/wireless/broadcom/brcm80211/Kconfig --+++ b/drivers/net/wireless/broadcom/brcm80211/Kconfig --@@ -1,6 +1,6 @@ -- # SPDX-License-Identifier: GPL-2.0-only -- config BRCMUTIL --- tristate --+ tristate "Broadcom 802.11 driver utility functions" -- depends on m -- -- config BRCMSMAC -diff --git a/package/kernel/mac80211/patches/brcm/810-b43-gpio-mask-module-option.patch b/package/kernel/mac80211/patches/brcm/810-b43-gpio-mask-module-option.patch -deleted file mode 100644 -index 09ef50526f..0000000000 ---- a/package/kernel/mac80211/patches/brcm/810-b43-gpio-mask-module-option.patch -+++ /dev/null -@@ -1,37 +0,0 @@ ----- a/drivers/net/wireless/broadcom/b43/b43.h --+++ b/drivers/net/wireless/broadcom/b43/b43.h --@@ -840,6 +840,7 @@ struct b43_wldev { -- bool qos_enabled; /* TRUE, if QoS is used. */ -- bool hwcrypto_enabled; /* TRUE, if HW crypto acceleration is enabled. */ -- bool use_pio; /* TRUE if next init should use PIO */ --+ int gpiomask; /* GPIO LED mask as a module parameter */ -- -- /* PHY/Radio device. */ -- struct b43_phy phy; ----- a/drivers/net/wireless/broadcom/b43/main.c --+++ b/drivers/net/wireless/broadcom/b43/main.c --@@ -72,6 +72,11 @@ MODULE_FIRMWARE("b43/ucode40.fw"); -- MODULE_FIRMWARE("b43/ucode42.fw"); -- MODULE_FIRMWARE("b43/ucode9.fw"); -- --+static int modparam_gpiomask = 0x000F; --+module_param_named(gpiomask, modparam_gpiomask, int, 0444); --+MODULE_PARM_DESC(gpiomask, --+ "GPIO mask for LED control (default 0x000F)"); --+ -- static int modparam_bad_frames_preempt; -- module_param_named(bad_frames_preempt, modparam_bad_frames_preempt, int, 0444); -- MODULE_PARM_DESC(bad_frames_preempt, --@@ -2869,10 +2874,10 @@ static int b43_gpio_init(struct b43_wlde -- u32 mask, set; -- -- b43_maskset32(dev, B43_MMIO_MACCTL, ~B43_MACCTL_GPOUTSMSK, 0); --- b43_maskset16(dev, B43_MMIO_GPIO_MASK, ~0, 0xF); --+ b43_maskset16(dev, B43_MMIO_GPIO_MASK, ~0, modparam_gpiomask); -- -- mask = 0x0000001F; --- set = 0x0000000F; --+ set = modparam_gpiomask; -- if (dev->dev->chip_id == 0x4301) { -- mask |= 0x0060; -- set |= 0x0060; -diff --git a/package/kernel/mac80211/patches/brcm/811-b43_no_pio.patch b/package/kernel/mac80211/patches/brcm/811-b43_no_pio.patch -deleted file mode 100644 -index e395d48202..0000000000 ---- a/package/kernel/mac80211/patches/brcm/811-b43_no_pio.patch -+++ /dev/null -@@ -1,86 +0,0 @@ ----- a/drivers/net/wireless/broadcom/b43/Makefile --+++ b/drivers/net/wireless/broadcom/b43/Makefile --@@ -18,7 +18,7 @@ b43-$(CPTCFG_B43_PHY_AC) += phy_ac.o -- b43-y += sysfs.o -- b43-y += xmit.o -- b43-y += dma.o ---b43-y += pio.o --+b43-$(CPTCFG_B43_PIO) += pio.o -- b43-y += rfkill.o -- b43-y += ppr.o -- b43-$(CPTCFG_B43_LEDS) += leds.o ----- a/drivers/net/wireless/broadcom/b43/main.c --+++ b/drivers/net/wireless/broadcom/b43/main.c --@@ -2001,10 +2001,12 @@ static void b43_do_interrupt_thread(stru -- dma_reason[0], dma_reason[1], -- dma_reason[2], dma_reason[3], -- dma_reason[4], dma_reason[5]); --+#ifdef CPTCFG_B43_PIO -- b43err(dev->wl, "This device does not support DMA " -- "on your system. It will now be switched to PIO.\n"); -- /* Fall back to PIO transfers if we get fatal DMA errors! */ -- dev->use_pio = true; --+#endif -- b43_controller_restart(dev, "DMA error"); -- return; -- } ----- a/drivers/net/wireless/broadcom/b43/pio.h --+++ b/drivers/net/wireless/broadcom/b43/pio.h --@@ -151,7 +151,7 @@ static inline void b43_piorx_write32(str -- b43_write32(q->dev, q->mmio_base + offset, value); -- } -- --- --+#ifdef CPTCFG_B43_PIO -- int b43_pio_init(struct b43_wldev *dev); -- void b43_pio_free(struct b43_wldev *dev); -- --@@ -162,5 +162,37 @@ void b43_pio_rx(struct b43_pio_rxqueue * -- -- void b43_pio_tx_suspend(struct b43_wldev *dev); -- void b43_pio_tx_resume(struct b43_wldev *dev); --+#else --+static inline int b43_pio_init(struct b43_wldev *dev) --+{ --+ return 0; --+} --+ --+static inline void b43_pio_free(struct b43_wldev *dev) --+{ --+} --+ --+static inline int b43_pio_tx(struct b43_wldev *dev, struct sk_buff *skb) --+{ --+ return 0; --+} --+ --+static inline void b43_pio_handle_txstatus(struct b43_wldev *dev, --+ const struct b43_txstatus *status) --+{ --+} --+ --+static inline void b43_pio_rx(struct b43_pio_rxqueue *q) --+{ --+} --+ --+static inline void b43_pio_tx_suspend(struct b43_wldev *dev) --+{ --+} --+ --+static inline void b43_pio_tx_resume(struct b43_wldev *dev) --+{ --+} --+#endif /* CPTCFG_B43_PIO */ -- -- #endif /* B43_PIO_H_ */ ----- a/drivers/net/wireless/broadcom/b43/Kconfig --+++ b/drivers/net/wireless/broadcom/b43/Kconfig --@@ -100,7 +100,7 @@ config B43_BCMA_PIO -- default y -- -- config B43_PIO --- bool --+ bool "Broadcom 43xx PIO support" -- depends on B43 && B43_SSB -- depends on SSB_BLOCKIO -- default y -diff --git a/package/kernel/mac80211/patches/brcm/812-b43-add-antenna-control.patch b/package/kernel/mac80211/patches/brcm/812-b43-add-antenna-control.patch -deleted file mode 100644 -index 22b67c49d8..0000000000 ---- a/package/kernel/mac80211/patches/brcm/812-b43-add-antenna-control.patch -+++ /dev/null -@@ -1,131 +0,0 @@ ----- a/drivers/net/wireless/broadcom/b43/main.c --+++ b/drivers/net/wireless/broadcom/b43/main.c --@@ -1643,7 +1643,7 @@ static void b43_write_beacon_template(st -- len, ram_offset, shm_size_offset, rate); -- -- /* Write the PHY TX control parameters. */ --- antenna = B43_ANTENNA_DEFAULT; --+ antenna = dev->tx_antenna; -- antenna = b43_antenna_to_phyctl(antenna); -- ctl = b43_shm_read16(dev, B43_SHM_SHARED, B43_SHM_SH_BEACPHYCTL); -- /* We can't send beacons with short preamble. Would get PHY errors. */ --@@ -3284,8 +3284,8 @@ static int b43_chip_init(struct b43_wlde -- -- /* Select the antennae */ -- if (phy->ops->set_rx_antenna) --- phy->ops->set_rx_antenna(dev, B43_ANTENNA_DEFAULT); --- b43_mgmtframe_txantenna(dev, B43_ANTENNA_DEFAULT); --+ phy->ops->set_rx_antenna(dev, dev->rx_antenna); --+ b43_mgmtframe_txantenna(dev, dev->tx_antenna); -- -- if (phy->type == B43_PHYTYPE_B) { -- value16 = b43_read16(dev, 0x005E); --@@ -3986,7 +3986,6 @@ static int b43_op_config(struct ieee8021 -- struct b43_wldev *dev = wl->current_dev; -- struct b43_phy *phy = &dev->phy; -- struct ieee80211_conf *conf = &hw->conf; --- int antenna; -- int err = 0; -- -- mutex_lock(&wl->mutex); --@@ -4029,11 +4028,9 @@ static int b43_op_config(struct ieee8021 -- } -- -- /* Antennas for RX and management frame TX. */ --- antenna = B43_ANTENNA_DEFAULT; --- b43_mgmtframe_txantenna(dev, antenna); --- antenna = B43_ANTENNA_DEFAULT; --+ b43_mgmtframe_txantenna(dev, dev->tx_antenna); -- if (phy->ops->set_rx_antenna) --- phy->ops->set_rx_antenna(dev, antenna); --+ phy->ops->set_rx_antenna(dev, dev->rx_antenna); -- -- if (wl->radio_enabled != phy->radio_on) { -- if (wl->radio_enabled) { --@@ -5176,6 +5173,47 @@ static int b43_op_get_survey(struct ieee -- return 0; -- } -- --+static int b43_op_set_antenna(struct ieee80211_hw *hw, u32 tx_ant, u32 rx_ant) --+{ --+ struct b43_wl *wl = hw_to_b43_wl(hw); --+ struct b43_wldev *dev = wl->current_dev; --+ --+ if (tx_ant == 1 && rx_ant == 1) { --+ dev->tx_antenna = B43_ANTENNA0; --+ dev->rx_antenna = B43_ANTENNA0; --+ } --+ else if (tx_ant == 2 && rx_ant == 2) { --+ dev->tx_antenna = B43_ANTENNA1; --+ dev->rx_antenna = B43_ANTENNA1; --+ } --+ else if ((tx_ant & 3) == 3 && (rx_ant & 3) == 3) { --+ dev->tx_antenna = B43_ANTENNA_DEFAULT; --+ dev->rx_antenna = B43_ANTENNA_DEFAULT; --+ } --+ else { --+ return -EINVAL; --+ } --+ --+ return 0; --+} --+ --+ --+static int b43_op_get_antenna(struct ieee80211_hw *hw, u32 *tx_ant, u32 *rx_ant) --+{ --+ struct b43_wl *wl = hw_to_b43_wl(hw); --+ struct b43_wldev *dev = wl->current_dev; --+ --+ switch (dev->tx_antenna) { --+ case B43_ANTENNA0: --+ *tx_ant = 1; *rx_ant = 1; break; --+ case B43_ANTENNA1: --+ *tx_ant = 2; *rx_ant = 2; break; --+ case B43_ANTENNA_DEFAULT: --+ *tx_ant = 3; *rx_ant = 3; break; --+ } --+ return 0; --+} --+ -- static const struct ieee80211_ops b43_hw_ops = { -- .tx = b43_op_tx, -- .wake_tx_queue = ieee80211_handle_wake_tx_queue, --@@ -5198,6 +5236,8 @@ static const struct ieee80211_ops b43_hw -- .sw_scan_complete = b43_op_sw_scan_complete_notifier, -- .get_survey = b43_op_get_survey, -- .rfkill_poll = b43_rfkill_poll, --+ .set_antenna = b43_op_set_antenna, --+ .get_antenna = b43_op_get_antenna, -- }; -- -- /* Hard-reset the chip. Do not call this directly. --@@ -5499,6 +5539,8 @@ static int b43_one_core_attach(struct b4 -- if (!wldev) -- goto out; -- --+ wldev->rx_antenna = B43_ANTENNA_DEFAULT; --+ wldev->tx_antenna = B43_ANTENNA_DEFAULT; -- wldev->use_pio = b43_modparam_pio; -- wldev->dev = dev; -- wldev->wl = wl; --@@ -5590,6 +5632,9 @@ static struct b43_wl *b43_wireless_init( -- -- wiphy_ext_feature_set(hw->wiphy, NL80211_EXT_FEATURE_CQM_RSSI_LIST); -- --+ hw->wiphy->available_antennas_rx = 0x3; --+ hw->wiphy->available_antennas_tx = 0x3; --+ -- wl->hw_registered = false; -- hw->max_rates = 2; -- SET_IEEE80211_DEV(hw, dev->dev); ----- a/drivers/net/wireless/broadcom/b43/b43.h --+++ b/drivers/net/wireless/broadcom/b43/b43.h --@@ -841,6 +841,8 @@ struct b43_wldev { -- bool hwcrypto_enabled; /* TRUE, if HW crypto acceleration is enabled. */ -- bool use_pio; /* TRUE if next init should use PIO */ -- int gpiomask; /* GPIO LED mask as a module parameter */ --+ int rx_antenna; /* Used RX antenna (B43_ANTENNAxxx) */ --+ int tx_antenna; /* Used TX antenna (B43_ANTENNAxxx) */ -- -- /* PHY/Radio device. */ -- struct b43_phy phy; -diff --git a/package/kernel/mac80211/patches/brcm/813-b43-reduce-number-of-RX-slots.patch b/package/kernel/mac80211/patches/brcm/813-b43-reduce-number-of-RX-slots.patch -deleted file mode 100644 -index 85c52c0282..0000000000 ---- a/package/kernel/mac80211/patches/brcm/813-b43-reduce-number-of-RX-slots.patch -+++ /dev/null -@@ -1,11 +0,0 @@ ----- a/drivers/net/wireless/broadcom/b43/dma.h --+++ b/drivers/net/wireless/broadcom/b43/dma.h --@@ -170,7 +170,7 @@ struct b43_dmadesc_generic { -- -- /* DMA engine tuning knobs */ -- #define B43_TXRING_SLOTS 256 ---#define B43_RXRING_SLOTS 256 --+#define B43_RXRING_SLOTS 32 -- #define B43_DMA0_RX_FW598_BUFSIZE (B43_DMA0_RX_FW598_FO + IEEE80211_MAX_FRAME_LEN) -- #define B43_DMA0_RX_FW351_BUFSIZE (B43_DMA0_RX_FW351_FO + IEEE80211_MAX_FRAME_LEN) -- -diff --git a/package/kernel/mac80211/patches/brcm/814-b43-only-use-gpio-0-1-for-led.patch b/package/kernel/mac80211/patches/brcm/814-b43-only-use-gpio-0-1-for-led.patch -deleted file mode 100644 -index 9cb0a32fd4..0000000000 ---- a/package/kernel/mac80211/patches/brcm/814-b43-only-use-gpio-0-1-for-led.patch -+++ /dev/null -@@ -1,17 +0,0 @@ ----- a/drivers/net/wireless/broadcom/b43/main.c --+++ b/drivers/net/wireless/broadcom/b43/main.c --@@ -2886,6 +2886,14 @@ static int b43_gpio_init(struct b43_wlde -- } else if (dev->dev->chip_id == 0x5354) { -- /* Don't allow overtaking buttons GPIOs */ -- set &= 0x2; /* 0x2 is LED GPIO on BCM5354 */ --+ } else if (dev->dev->chip_id == BCMA_CHIP_ID_BCM4716 || --+ dev->dev->chip_id == BCMA_CHIP_ID_BCM47162 || --+ dev->dev->chip_id == BCMA_CHIP_ID_BCM5356 || --+ dev->dev->chip_id == BCMA_CHIP_ID_BCM5357 || --+ dev->dev->chip_id == BCMA_CHIP_ID_BCM53572) { --+ /* just use gpio 0 and 1 for 2.4 GHz wifi led */ --+ set &= 0x3; --+ mask &= 0x3; -- } -- -- if (0 /* FIXME: conditional unknown */ ) { -diff --git a/package/kernel/mac80211/patches/brcm/815-b43-always-take-overlapping-devs.patch b/package/kernel/mac80211/patches/brcm/815-b43-always-take-overlapping-devs.patch -deleted file mode 100644 -index 3700eaa1a0..0000000000 ---- a/package/kernel/mac80211/patches/brcm/815-b43-always-take-overlapping-devs.patch -+++ /dev/null -@@ -1,11 +0,0 @@ ----- a/drivers/net/wireless/broadcom/b43/main.c --+++ b/drivers/net/wireless/broadcom/b43/main.c --@@ -114,7 +114,7 @@ static int b43_modparam_pio; -- module_param_named(pio, b43_modparam_pio, int, 0644); -- MODULE_PARM_DESC(pio, "Use PIO accesses by default: 0=DMA, 1=PIO"); -- ---static int modparam_allhwsupport = !IS_ENABLED(CPTCFG_BRCMSMAC); --+static int modparam_allhwsupport = 1; -- module_param_named(allhwsupport, modparam_allhwsupport, int, 0444); -- MODULE_PARM_DESC(allhwsupport, "Enable support for all hardware (even it if overlaps with the brcmsmac driver)"); -- -diff --git a/package/kernel/mac80211/patches/brcm/850-brcmsmac-remove-extra-regulation-restriction.patch b/package/kernel/mac80211/patches/brcm/850-brcmsmac-remove-extra-regulation-restriction.patch -deleted file mode 100644 -index 3c93386b30..0000000000 ---- a/package/kernel/mac80211/patches/brcm/850-brcmsmac-remove-extra-regulation-restriction.patch -+++ /dev/null -@@ -1,27 +0,0 @@ ----- a/drivers/net/wireless/broadcom/brcm80211/brcmsmac/channel.c --+++ b/drivers/net/wireless/broadcom/brcm80211/brcmsmac/channel.c --@@ -58,19 +58,12 @@ -- (((c) < 149) ? 3 : 4)))) -- -- #define BRCM_2GHZ_2412_2462 REG_RULE(2412-10, 2462+10, 40, 0, 19, 0) ---#define BRCM_2GHZ_2467_2472 REG_RULE(2467-10, 2472+10, 20, 0, 19, \ --- NL80211_RRF_NO_IR) --+#define BRCM_2GHZ_2467_2472 REG_RULE(2467-10, 2472+10, 20, 0, 19, 0) -- ---#define BRCM_5GHZ_5180_5240 REG_RULE(5180-10, 5240+10, 40, 0, 21, \ --- NL80211_RRF_NO_IR) ---#define BRCM_5GHZ_5260_5320 REG_RULE(5260-10, 5320+10, 40, 0, 21, \ --- NL80211_RRF_DFS | \ --- NL80211_RRF_NO_IR) ---#define BRCM_5GHZ_5500_5700 REG_RULE(5500-10, 5700+10, 40, 0, 21, \ --- NL80211_RRF_DFS | \ --- NL80211_RRF_NO_IR) ---#define BRCM_5GHZ_5745_5825 REG_RULE(5745-10, 5825+10, 40, 0, 21, \ --- NL80211_RRF_NO_IR) --+#define BRCM_5GHZ_5180_5240 REG_RULE(5180-10, 5240+10, 40, 0, 21, 0) --+#define BRCM_5GHZ_5260_5320 REG_RULE(5260-10, 5320+10, 40, 0, 21, 0) --+#define BRCM_5GHZ_5500_5700 REG_RULE(5500-10, 5700+10, 40, 0, 21, 0) --+#define BRCM_5GHZ_5745_5825 REG_RULE(5745-10, 5825+10, 40, 0, 21, 0) -- -- static const struct ieee80211_regdomain brcms_regdom_x2 = { -- .n_reg_rules = 6, -diff --git a/package/kernel/mac80211/patches/brcm/861-brcmfmac-workaround-bug-with-some-inconsistent-BSSes.patch b/package/kernel/mac80211/patches/brcm/861-brcmfmac-workaround-bug-with-some-inconsistent-BSSes.patch -deleted file mode 100644 -index b82b442a1e..0000000000 ---- a/package/kernel/mac80211/patches/brcm/861-brcmfmac-workaround-bug-with-some-inconsistent-BSSes.patch -+++ /dev/null -@@ -1,49 +0,0 @@ --From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= --Date: Thu, 9 Jul 2015 00:07:59 +0200 --Subject: [PATCH] brcmfmac: workaround bug with some inconsistent BSSes state --MIME-Version: 1.0 --Content-Type: text/plain; charset=UTF-8 --Content-Transfer-Encoding: 8bit -- --Signed-off-by: Rafał Miłecki ----- -- ----- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c --+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c --@@ -713,8 +713,36 @@ static struct wireless_dev *brcmf_cfg802 -- struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy); -- struct brcmf_pub *drvr = cfg->pub; -- struct wireless_dev *wdev; --+ struct net_device *dev; -- int err; -- --+ /* --+ * There is a bug with in-firmware BSS management. When adding virtual --+ * interface brcmfmac first tells firmware to create new BSS and then --+ * it creates new struct net_device. --+ * --+ * If creating/registering netdev(ice) fails, BSS remains in some bugged --+ * state. It conflicts with existing BSSes by overtaking their auth --+ * requests. --+ * --+ * It results in one BSS (addresss X) sending beacons and another BSS --+ * (address Y) replying to authentication requests. This makes interface --+ * unusable as AP. --+ * --+ * To workaround this bug we may try to guess if register_netdev(ice) --+ * will fail. The most obvious case is using interface name that already --+ * exists. This is actually quite likely with brcmfmac & some user space --+ * scripts as brcmfmac doesn't allow deleting virtual interfaces. --+ * So this bug can be triggered even by something trivial like: --+ * iw dev wlan0 delete --+ * iw phy phy0 interface add wlan0 type __ap --+ */ --+ dev = dev_get_by_name(&init_net, name); --+ if (dev) { --+ dev_put(dev); --+ return ERR_PTR(-ENFILE); --+ } --+ -- brcmf_dbg(TRACE, "enter: %s type %d\n", name, type); -- err = brcmf_vif_add_validate(wiphy_to_cfg(wiphy), type); -- if (err) { -diff --git a/package/kernel/mac80211/patches/brcm/862-brcmfmac-Disable-power-management.patch b/package/kernel/mac80211/patches/brcm/862-brcmfmac-Disable-power-management.patch -deleted file mode 100644 -index 080ab8f7ef..0000000000 ---- a/package/kernel/mac80211/patches/brcm/862-brcmfmac-Disable-power-management.patch -+++ /dev/null -@@ -1,27 +0,0 @@ --From 66ae1b1750720a33e29792a177b1e696f4f005fb Mon Sep 17 00:00:00 2001 --From: Phil Elwell --Date: Wed, 9 Mar 2016 17:25:59 +0000 --Subject: [PATCH] brcmfmac: Disable power management -- --Disable wireless power saving in the brcmfmac WLAN driver. This is a --temporary measure until the connectivity loss resulting from power --saving is resolved. -- --Signed-off-by: Phil Elwell ----- -- drivers/net/wireless/brcm80211/brcmfmac/cfg80211.c | 2 ++ -- 1 file changed, 2 insertions(+) -- ----- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c --+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c --@@ -2976,6 +2976,10 @@ brcmf_cfg80211_set_power_mgmt(struct wip -- * preference in cfg struct to apply this to -- * FW later while initializing the dongle -- */ --+#if defined(CONFIG_ARCH_BCM2835) --+ brcmf_dbg(INFO, "power management disabled\n"); --+ enabled = false; --+#endif -- cfg->pwr_save = enabled; -- if (!check_vif_up(ifp->vif)) { -- -diff --git a/package/kernel/mac80211/patches/brcm/863-brcmfmac-add-in-driver-tables-with-country-codes.patch b/package/kernel/mac80211/patches/brcm/863-brcmfmac-add-in-driver-tables-with-country-codes.patch -deleted file mode 100644 -index 25191b6439..0000000000 ---- a/package/kernel/mac80211/patches/brcm/863-brcmfmac-add-in-driver-tables-with-country-codes.patch -+++ /dev/null -@@ -1,60 +0,0 @@ --From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= --Subject: [PATCH] brcmfmac: add in-driver tables with country codes --MIME-Version: 1.0 --Content-Type: text/plain; charset=UTF-8 --Content-Transfer-Encoding: 8bit -- --This adds early support for changing region. Ideally this data should --be stored in DT as all these mappings are devices specific. -- --Signed-off-by: Rafał Miłecki ----- -- ----- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/of.c --+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/of.c --@@ -65,6 +65,36 @@ static int brcmf_of_get_country_codes(st -- return 0; -- } -- --+/* TODO: FIXME: Use DT */ --+static void brcmf_of_probe_cc(struct device *dev, --+ struct brcmf_mp_device *settings) --+{ --+ static struct brcmfmac_pd_cc_entry netgear_r8000_cc_ent[] = { --+ { "JP", "JP", 78 }, --+ { "US", "Q2", 86 }, --+ }; --+ struct brcmfmac_pd_cc_entry *cc_ent = NULL; --+ int table_size = 0; --+ --+ if (of_machine_is_compatible("netgear,r8000")) { --+ cc_ent = netgear_r8000_cc_ent; --+ table_size = ARRAY_SIZE(netgear_r8000_cc_ent); --+ } --+ --+ if (cc_ent && table_size) { --+ struct brcmfmac_pd_cc *cc; --+ size_t memsize; --+ --+ memsize = table_size * sizeof(struct brcmfmac_pd_cc_entry); --+ cc = devm_kzalloc(dev, sizeof(*cc) + memsize, GFP_KERNEL); --+ if (!cc) --+ return; --+ cc->table_size = table_size; --+ memcpy(cc->table, cc_ent, memsize); --+ settings->country_codes = cc; --+ } --+} --+ -- void brcmf_of_probe(struct device *dev, enum brcmf_bus_type bus_type, -- struct brcmf_mp_device *settings) -- { --@@ -106,6 +136,8 @@ void brcmf_of_probe(struct device *dev, -- of_node_put(root); -- } -- --+ brcmf_of_probe_cc(dev, settings); --+ -- if (!np || !of_device_is_compatible(np, "brcm,bcm4329-fmac")) -- return; -- -diff --git a/package/kernel/mac80211/patches/brcm/864-brcmfmac-do-not-use-internal-roaming-engine-by-default.patch b/package/kernel/mac80211/patches/brcm/864-brcmfmac-do-not-use-internal-roaming-engine-by-default.patch -deleted file mode 100644 -index fe79c40c11..0000000000 ---- a/package/kernel/mac80211/patches/brcm/864-brcmfmac-do-not-use-internal-roaming-engine-by-default.patch -+++ /dev/null -@@ -1,23 +0,0 @@ --brcmfmac: do not use internal roaming engine by default -- --Some evidence of curing disconnects with this disabled, so make it a default. --Can be overridden with module parameter roamoff=0 --See: http://projectable.me/optimize-my-pi-wi-fi/ -- --Signed-off-by: Phil Elwell ----- -- ----- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.c --+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.c --@@ -59,7 +59,11 @@ static int brcmf_fcmode; -- module_param_named(fcmode, brcmf_fcmode, int, 0); -- MODULE_PARM_DESC(fcmode, "Mode of firmware signalled flow control"); -- --+#if defined(CONFIG_ARCH_BCM2835) --+static int brcmf_roamoff = 1; --+#else -- static int brcmf_roamoff; --+#endif -- module_param_named(roamoff, brcmf_roamoff, int, 0400); -- MODULE_PARM_DESC(roamoff, "Do not use internal roaming engine"); -- -diff --git a/package/kernel/mac80211/patches/brcm/865-brcmfmac-Read-alternative-firmware-names-from-DT.patch b/package/kernel/mac80211/patches/brcm/865-brcmfmac-Read-alternative-firmware-names-from-DT.patch -deleted file mode 100644 -index 8df285f8b1..0000000000 ---- a/package/kernel/mac80211/patches/brcm/865-brcmfmac-Read-alternative-firmware-names-from-DT.patch -+++ /dev/null -@@ -1,191 +0,0 @@ --From 4e32024cbb14230af3048e249e84f8c2b25ce45a Mon Sep 17 00:00:00 2001 --From: Phil Elwell --Date: Thu, 28 Oct 2021 15:03:16 +0100 --Subject: [PATCH] brcmfmac: Read alternative firmware names from DT -- --Add the ability to load the names of alternative firmwares from the --Device Tree node. This permits separate firmwares for 43436s and 43438 --and allows downstream firmwares to coexist with upstream. -- --Signed-off-by: Phil Elwell ----- -- .../wireless/broadcom/brcm80211/brcmfmac/of.c | 36 ++++++++++++++ -- .../wireless/broadcom/brcm80211/brcmfmac/of.h | 7 +++ -- .../broadcom/brcm80211/brcmfmac/sdio.c | 47 +++++++++++++++++-- -- 3 files changed, 87 insertions(+), 3 deletions(-) -- ----- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/of.c --+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/of.c --@@ -11,6 +11,7 @@ -- #include "debug.h" -- #include "core.h" -- #include "common.h" --+#include "firmware.h" -- #include "of.h" -- -- static int brcmf_of_get_country_codes(struct device *dev, --@@ -168,3 +169,38 @@ void brcmf_of_probe(struct device *dev, -- sdio->oob_irq_nr = irq; -- sdio->oob_irq_flags = irqf; -- } --+ --+struct brcmf_firmware_mapping * --+brcmf_of_fwnames(struct device *dev, u32 *fwname_count) --+{ --+ struct device_node *np = dev->of_node; --+ struct brcmf_firmware_mapping *fwnames; --+ struct device_node *map_np, *fw_np; --+ int of_count; --+ int count = 0; --+ --+ map_np = of_get_child_by_name(np, "firmwares"); --+ of_count = of_get_child_count(map_np); --+ if (!of_count) --+ return NULL; --+ --+ fwnames = devm_kcalloc(dev, of_count, --+ sizeof(struct brcmf_firmware_mapping), --+ GFP_KERNEL); --+ --+ for_each_child_of_node(map_np, fw_np) --+ { --+ struct brcmf_firmware_mapping *cur = &fwnames[count]; --+ --+ if (of_property_read_u32(fw_np, "chipid", &cur->chipid) || --+ of_property_read_u32(fw_np, "revmask", &cur->revmask)) --+ continue; --+ cur->fw_base = of_get_property(fw_np, "fw_base", NULL); --+ if (cur->fw_base) --+ count++; --+ } --+ --+ *fwname_count = count; --+ --+ return count ? fwnames : NULL; --+} ----- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/of.h --+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/of.h --@@ -5,9 +5,20 @@ -- #ifdef CONFIG_OF -- void brcmf_of_probe(struct device *dev, enum brcmf_bus_type bus_type, -- struct brcmf_mp_device *settings); --+#ifdef CPTCFG_BRCMFMAC_SDIO --+struct brcmf_firmware_mapping * --+brcmf_of_fwnames(struct device *dev, u32 *map_count); --+#endif -- #else -- static void brcmf_of_probe(struct device *dev, enum brcmf_bus_type bus_type, -- struct brcmf_mp_device *settings) -- { -- } --+#ifdef CPTCFG_BRCMFMAC_SDIO --+static struct brcmf_firmware_mapping * --+brcmf_of_fwnames(struct device *dev, u32 *map_count) --+{ --+ return NULL; --+} --+#endif -- #endif /* CONFIG_OF */ ----- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c --+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c --@@ -35,6 +35,7 @@ -- #include "core.h" -- #include "common.h" -- #include "bcdc.h" --+#include "of.h" -- -- #define DCMD_RESP_TIMEOUT msecs_to_jiffies(2500) -- #define CTL_DONE_TIMEOUT msecs_to_jiffies(2500) --@@ -634,7 +635,7 @@ MODULE_FIRMWARE(BRCMF_FW_DEFAULT_PATH "b -- /* per-board firmware binaries */ -- MODULE_FIRMWARE(BRCMF_FW_DEFAULT_PATH "brcmfmac*-sdio.*.bin"); -- ---static const struct brcmf_firmware_mapping brcmf_sdio_fwnames[] = { --+static const struct brcmf_firmware_mapping sdio_fwnames[] = { -- BRCMF_FW_ENTRY(BRCM_CC_43143_CHIP_ID, 0xFFFFFFFF, 43143), -- BRCMF_FW_ENTRY(BRCM_CC_43241_CHIP_ID, 0x0000001F, 43241B0), -- BRCMF_FW_ENTRY(BRCM_CC_43241_CHIP_ID, 0x00000020, 43241B4), --@@ -662,6 +663,9 @@ static const struct brcmf_firmware_mappi -- BRCMF_FW_ENTRY(CY_CC_43752_CHIP_ID, 0xFFFFFFFF, 43752) -- }; -- --+static const struct brcmf_firmware_mapping *brcmf_sdio_fwnames = sdio_fwnames; --+static u32 brcmf_sdio_fwnames_count = ARRAY_SIZE(sdio_fwnames); --+ -- #define TXCTL_CREDITS 2 -- -- static void pkt_align(struct sk_buff *p, int len, int align) --@@ -4193,6 +4197,9 @@ static const struct brcmf_bus_ops brcmf_ -- #define BRCMF_SDIO_FW_NVRAM 1 -- #define BRCMF_SDIO_FW_CLM 2 -- --+static struct brcmf_fw_request * --+brcmf_sdio_prepare_fw_request(struct brcmf_sdio *bus); --+ -- static void brcmf_sdio_firmware_callback(struct device *dev, int err, -- struct brcmf_fw_request *fwreq) -- { --@@ -4208,6 +4215,22 @@ static void brcmf_sdio_firmware_callback -- -- brcmf_dbg(TRACE, "Enter: dev=%s, err=%d\n", dev_name(dev), err); -- --+ if (err && brcmf_sdio_fwnames != sdio_fwnames) { --+ /* Try again with the standard firmware names */ --+ brcmf_sdio_fwnames = sdio_fwnames; --+ brcmf_sdio_fwnames_count = ARRAY_SIZE(sdio_fwnames); --+ kfree(fwreq); --+ fwreq = brcmf_sdio_prepare_fw_request(bus); --+ if (!fwreq) { --+ err = -ENOMEM; --+ goto fail; --+ } --+ err = brcmf_fw_get_firmwares(dev, fwreq, --+ brcmf_sdio_firmware_callback); --+ if (!err) --+ return; --+ } --+ -- if (err) -- goto fail; -- --@@ -4418,7 +4441,7 @@ brcmf_sdio_prepare_fw_request(struct brc -- -- fwreq = brcmf_fw_alloc_request(bus->ci->chip, bus->ci->chiprev, -- brcmf_sdio_fwnames, --- ARRAY_SIZE(brcmf_sdio_fwnames), --+ brcmf_sdio_fwnames_count, -- fwnames, ARRAY_SIZE(fwnames)); -- if (!fwreq) -- return NULL; --@@ -4438,6 +4461,9 @@ struct brcmf_sdio *brcmf_sdio_probe(stru -- struct brcmf_sdio *bus; -- struct workqueue_struct *wq; -- struct brcmf_fw_request *fwreq; --+ struct brcmf_firmware_mapping *of_fwnames, *fwnames = NULL; --+ const int fwname_size = sizeof(struct brcmf_firmware_mapping); --+ u32 of_fw_count; -- -- brcmf_dbg(TRACE, "Enter\n"); -- --@@ -4520,6 +4546,21 @@ struct brcmf_sdio *brcmf_sdio_probe(stru -- -- brcmf_dbg(INFO, "completed!!\n"); -- --+ of_fwnames = brcmf_of_fwnames(sdiodev->dev, &of_fw_count); --+ if (of_fwnames) --+ fwnames = devm_kcalloc(sdiodev->dev, --+ of_fw_count + brcmf_sdio_fwnames_count, --+ fwname_size, GFP_KERNEL); --+ --+ if (fwnames) { --+ /* The array is scanned in order, so overrides come first */ --+ memcpy(fwnames, of_fwnames, of_fw_count * fwname_size); --+ memcpy(fwnames + of_fw_count, sdio_fwnames, --+ brcmf_sdio_fwnames_count * fwname_size); --+ brcmf_sdio_fwnames = fwnames; --+ brcmf_sdio_fwnames_count += of_fw_count; --+ } --+ -- fwreq = brcmf_sdio_prepare_fw_request(bus); -- if (!fwreq) { -- ret = -ENOMEM; -diff --git a/package/kernel/mac80211/patches/build/000-fix_kconfig.patch b/package/kernel/mac80211/patches/build/000-fix_kconfig.patch -deleted file mode 100644 -index 3987aae4f5..0000000000 ---- a/package/kernel/mac80211/patches/build/000-fix_kconfig.patch -+++ /dev/null -@@ -1,14 +0,0 @@ ----- a/kconf/Makefile --+++ b/kconf/Makefile --@@ -1,9 +1,9 @@ ---CFLAGS=-Wall -Wmissing-prototypes -Wstrict-prototypes -O2 -fomit-frame-pointer --+CFLAGS=-Wall -Wmissing-prototypes -Wstrict-prototypes -O2 -fomit-frame-pointer -DKBUILD_NO_NLS -- -- LXDIALOG := lxdialog/checklist.o lxdialog/inputbox.o lxdialog/menubox.o lxdialog/textbox.o lxdialog/util.o lxdialog/yesno.o -- -- conf: conf.o zconf.tab.o ---mconf_CFLAGS := $(shell ./lxdialog/check-lxdialog.sh -ccflags) -DLOCALE --+mconf_CFLAGS := $(shell ./lxdialog/check-lxdialog.sh -ccflags) -- mconf_LDFLAGS := $(shell ./lxdialog/check-lxdialog.sh -ldflags $(CC)) -- mconf: CFLAGS += $(mconf_CFLAGS) -- -diff --git a/package/kernel/mac80211/patches/build/001-fix_build.patch b/package/kernel/mac80211/patches/build/001-fix_build.patch -deleted file mode 100644 -index 8f63d36e2e..0000000000 ---- a/package/kernel/mac80211/patches/build/001-fix_build.patch -+++ /dev/null -@@ -1,169 +0,0 @@ ----- a/Makefile --+++ b/Makefile --@@ -5,7 +5,7 @@ -- ifeq ($(KERNELRELEASE),) -- -- MAKEFLAGS += --no-print-directory ---SHELL := /bin/bash --+SHELL := /usr/bin/env bash -- BACKPORT_DIR := $(shell pwd) -- -- KMODDIR ?= updates --@@ -19,6 +19,7 @@ KLIB_BUILD ?= $(KLIB)/build/ -- KERNEL_CONFIG := $(KLIB_BUILD)/.config -- KERNEL_MAKEFILE := $(KLIB_BUILD)/Makefile -- CONFIG_MD5 := $(shell md5sum $(KERNEL_CONFIG) 2>/dev/null | sed 's/\s.*//') --+STAMP_KERNEL_CONFIG := .kernel_config_md5_$(CONFIG_MD5) -- -- export KLIB KLIB_BUILD BACKPORT_DIR KMODDIR KMODPATH_ARG -- --@@ -36,7 +37,8 @@ mrproper: -- @rm -f .kernel_config_md5 Kconfig.versions Kconfig.kernel -- @rm -f backport-include/backport/autoconf.h -- ---.DEFAULT: --+.SILENT: $(STAMP_KERNEL_CONFIG) --+$(STAMP_KERNEL_CONFIG): -- @set -e ; test -f local-symbols || ( \ -- echo "/--------------" ;\ -- echo "| You shouldn't run make in the backports tree, but only in" ;\ --@@ -60,58 +62,62 @@ mrproper: -- echo "| (that isn't currently running.)" ;\ -- echo "\\--" ;\ -- false) --- @set -e ; if [ "$$(cat .kernel_config_md5 2>/dev/null)" != "$(CONFIG_MD5)" ] ;\ --- then \ --- echo -n "Generating local configuration database from kernel ..." ;\ --- grep -v -f local-symbols $(KERNEL_CONFIG) | grep = | ( \ --- while read l ; do \ --- if [ "$${l:0:7}" != "CONFIG_" ] ; then \ --- continue ;\ --- fi ;\ --- l=$${l:7} ;\ --- n=$${l%%=*} ;\ --- v=$${l#*=} ;\ --- if [ "$$v" = "m" ] ; then \ --- echo config $$n ;\ --- echo ' tristate' ;\ --- elif [ "$$v" = "y" ] ; then \ --- echo config $$n ;\ --- echo ' bool' ;\ --- else \ --- continue ;\ --- fi ;\ --- echo " default $$v" ;\ --- echo "" ;\ --- done \ --- ) > Kconfig.kernel ;\ --- kver=$$($(MAKE) --no-print-directory -C $(KLIB_BUILD) M=$(BACKPORT_DIR) \ --- kernelversion | sed 's/^\(\([3-5]\|2\.6\)\.[0-9]\+\).*/\1/;t;d');\ --- test "$$kver" != "" || echo "Kernel version parse failed!" ;\ --- test "$$kver" != "" ;\ --- kvers="$$(seq 14 39 | sed 's/^/2.6./')" ;\ --- kvers="$$kvers $$(seq 0 19 | sed 's/^/3./')" ;\ --- kvers="$$kvers $$(seq 0 20 | sed 's/^/4./')" ;\ --- kvers="$$kvers $$(seq 0 99 | sed 's/^/5./')" ;\ --- print=0 ;\ --- for v in $$kvers ; do \ --- if [ "$$print" = "1" ] ; then \ --- echo config KERNEL_$$(echo $$v | tr . _) ;\ --- echo " def_bool y" ;\ --- fi ;\ --- if [ "$$v" = "$$kver" ] ; then print=1 ; fi ;\ --- done > Kconfig.versions ;\ --- # RHEL as well, sadly we need to grep for it ;\ --- RHEL_MAJOR=$$(grep '^RHEL_MAJOR' $(KERNEL_MAKEFILE) | \ --- sed 's/.*=\s*\([0-9]*\)/\1/;t;d') ;\ --- RHEL_MINOR=$$(grep '^RHEL_MINOR' $(KERNEL_MAKEFILE) | \ --- sed 's/.*=\s*\([0-9]*\)/\1/;t;d') ;\ --- for v in $$(seq 0 $$RHEL_MINOR) ; do \ --- echo config BACKPORT_RHEL_KERNEL_$${RHEL_MAJOR}_$$v ;\ --- echo " def_bool y" ;\ --- done >> Kconfig.versions ;\ --- echo " done." ;\ --- fi ;\ --- echo "$(CONFIG_MD5)" > .kernel_config_md5 --+ @rm -f .kernel_config_md5_* --+ @touch $@ --+ --+Kconfig.kernel: $(STAMP_KERNEL_CONFIG) local-symbols --+ @printf "Generating local configuration database from kernel ..." --+ @grep -v -f local-symbols $(KERNEL_CONFIG) | grep = | ( \ --+ while read l ; do \ --+ if [ "$${l:0:7}" != "CONFIG_" ] ; then \ --+ continue ;\ --+ fi ;\ --+ l=$${l:7} ;\ --+ n=$${l%%=*} ;\ --+ v=$${l#*=} ;\ --+ if [ "$$v" = "m" ] ; then \ --+ echo config $$n ;\ --+ echo ' tristate' ;\ --+ elif [ "$$v" = "y" ] ; then \ --+ echo config $$n ;\ --+ echo ' bool' ;\ --+ else \ --+ continue ;\ --+ fi ;\ --+ echo " default $$v" ;\ --+ echo "" ;\ --+ done \ --+ ) > $@ --+ @echo " done." --+ --+Kconfig.versions: Kconfig.kernel --+ @kver=$$($(MAKE) --no-print-directory -C $(KLIB_BUILD) M=$(BACKPORT_DIR) \ --+ kernelversion | sed 's/^\(\([3-5]\|2\.6\)\.[0-9]\+\).*/\1/;t;d');\ --+ test "$$kver" != "" || echo "Kernel version parse failed!" ;\ --+ test "$$kver" != "" ;\ --+ kvers="$$(seq 14 39 | sed 's/^/2.6./')" ;\ --+ kvers="$$kvers $$(seq 0 19 | sed 's/^/3./')" ;\ --+ kvers="$$kvers $$(seq 0 20 | sed 's/^/4./')" ;\ --+ kvers="$$kvers $$(seq 0 99 | sed 's/^/5./')" ;\ --+ print=0 ;\ --+ for v in $$kvers ; do \ --+ if [ "$$print" = "1" ] ; then \ --+ echo config KERNEL_$$(echo $$v | tr . _) ;\ --+ echo " def_bool y" ;\ --+ fi ;\ --+ if [ "$$v" = "$$kver" ] ; then print=1 ; fi ;\ --+ done > $@ --+ @RHEL_MAJOR=$$(grep '^RHEL_MAJOR' $(KERNEL_MAKEFILE) | \ --+ sed 's/.*=\s*\([0-9]*\)/\1/;t;d') ;\ --+ RHEL_MINOR=$$(grep '^RHEL_MINOR' $(KERNEL_MAKEFILE) | \ --+ sed 's/.*=\s*\([0-9]*\)/\1/;t;d') ;\ --+ for v in $$(seq 0 $$RHEL_MINOR) ; do \ --+ echo config BACKPORT_RHEL_KERNEL_$${RHEL_MAJOR}_$$v ;\ --+ echo " def_bool y" ;\ --+ done >> $@ --+ --+.DEFAULT: --+ @$(MAKE) Kconfig.versions -- @$(MAKE) -f Makefile.real "$@" -- -- .PHONY: defconfig-help ----- a/Makefile.real --+++ b/Makefile.real --@@ -59,7 +59,7 @@ defconfig-%:: -- -- backport-include/backport/autoconf.h: .config Kconfig.versions Kconfig.kernel -- @$(MAKE) oldconfig --- @echo -n "Building backport-include/backport/autoconf.h ..." --+ @printf "Building backport-include/backport/autoconf.h ..." -- @grep -f local-symbols .config | ( \ -- echo "#ifndef COMPAT_AUTOCONF_INCLUDED" ;\ -- echo "#define COMPAT_AUTOCONF_INCLUDED" ;\ --@@ -80,7 +80,12 @@ backport-include/backport/autoconf.h: .c -- esac ;\ -- done ;\ -- echo "#endif /* COMPAT_AUTOCONF_INCLUDED */" ;\ --- ) > backport-include/backport/autoconf.h --+ ) > $@.new --+ @if cmp -s $@ $@.new; then \ --+ rm -f $@.new; \ --+ else \ --+ mv $@.new $@; \ --+ fi -- @echo " done." -- -- .PHONY: modules -diff --git a/package/kernel/mac80211/patches/build/002-change_allconfig.patch b/package/kernel/mac80211/patches/build/002-change_allconfig.patch -deleted file mode 100644 -index 368725d0c3..0000000000 ---- a/package/kernel/mac80211/patches/build/002-change_allconfig.patch -+++ /dev/null -@@ -1,64 +0,0 @@ ----- a/kconf/conf.c --+++ b/kconf/conf.c --@@ -598,40 +598,12 @@ int main(int ac, char **av) -- case oldconfig: -- case listnewconfig: -- case olddefconfig: --- conf_read(NULL); --- break; -- case allnoconfig: -- case allyesconfig: -- case allmodconfig: -- case alldefconfig: -- case randconfig: --- name = getenv("KCONFIG_ALLCONFIG"); --- if (!name) --- break; --- if ((strcmp(name, "") != 0) && (strcmp(name, "1") != 0)) { --- if (conf_read_simple(name, S_DEF_USER)) { --- fprintf(stderr, --- _("*** Can't read seed configuration \"%s\"!\n"), --- name); --- exit(1); --- } --- break; --- } --- switch (input_mode) { --- case allnoconfig: name = "allno.config"; break; --- case allyesconfig: name = "allyes.config"; break; --- case allmodconfig: name = "allmod.config"; break; --- case alldefconfig: name = "alldef.config"; break; --- case randconfig: name = "allrandom.config"; break; --- default: break; --- } --- if (conf_read_simple(name, S_DEF_USER) && --- conf_read_simple("all.config", S_DEF_USER)) { --- fprintf(stderr, --- _("*** KCONFIG_ALLCONFIG set, but no \"%s\" or \"all.config\" file found\n"), --- name); --- exit(1); --- } --+ conf_read(NULL); -- break; -- default: -- break; ----- a/kconf/confdata.c --+++ b/kconf/confdata.c --@@ -1170,6 +1170,8 @@ bool conf_set_all_new_symbols(enum conf_ -- } -- bool has_changed = false; -- --+ sym_clear_all_valid(); --+ -- for_all_symbols(i, sym) { -- if (sym_has_value(sym) || (sym->flags & SYMBOL_VALID)) -- continue; --@@ -1213,8 +1215,6 @@ bool conf_set_all_new_symbols(enum conf_ -- -- } -- --- sym_clear_all_valid(); --- -- /* -- * We have different type of choice blocks. -- * If curr.tri equals to mod then we can select several -diff --git a/package/kernel/mac80211/patches/build/003-remove_bogus_modparams.patch b/package/kernel/mac80211/patches/build/003-remove_bogus_modparams.patch -deleted file mode 100644 -index aa26c8cb2a..0000000000 ---- a/package/kernel/mac80211/patches/build/003-remove_bogus_modparams.patch -+++ /dev/null -@@ -1,34 +0,0 @@ ----- a/compat/main.c --+++ b/compat/main.c --@@ -19,31 +19,6 @@ MODULE_LICENSE("GPL"); -- #error "You need a CPTCFG_VERSION" -- #endif -- ---static char *backported_kernel_name = CPTCFG_KERNEL_NAME; --- ---module_param(backported_kernel_name, charp, 0400); ---MODULE_PARM_DESC(backported_kernel_name, --- "The kernel tree name that was used for this backport (" CPTCFG_KERNEL_NAME ")"); --- ---#ifdef BACKPORTS_GIT_TRACKED ---static char *backports_tracker_id = BACKPORTS_GIT_TRACKED; ---module_param(backports_tracker_id, charp, 0400); ---MODULE_PARM_DESC(backports_tracker_id, --- "The version of the tree containing this backport (" BACKPORTS_GIT_TRACKED ")"); ---#else ---static char *backported_kernel_version = CPTCFG_KERNEL_VERSION; ---static char *backports_version = CPTCFG_VERSION; --- ---module_param(backported_kernel_version, charp, 0400); ---MODULE_PARM_DESC(backported_kernel_version, --- "The kernel version that was used for this backport (" CPTCFG_KERNEL_VERSION ")"); --- ---module_param(backports_version, charp, 0400); ---MODULE_PARM_DESC(backports_version, --- "The git version of the backports tree used to generate this backport (" CPTCFG_VERSION ")"); --- ---#endif --- -- void backport_dependency_symbol(void) -- { -- } -diff --git a/package/kernel/mac80211/patches/build/012-kernel_build_check.patch b/package/kernel/mac80211/patches/build/012-kernel_build_check.patch -deleted file mode 100644 -index d225ba1820..0000000000 ---- a/package/kernel/mac80211/patches/build/012-kernel_build_check.patch -+++ /dev/null -@@ -1,11 +0,0 @@ ----- a/Makefile --+++ b/Makefile --@@ -2,7 +2,7 @@ -- # Makefile for the output source package -- # -- ---ifeq ($(KERNELRELEASE),) --+ifeq ($(KERNELVERSION),) -- -- MAKEFLAGS += --no-print-directory -- SHELL := /usr/bin/env bash -diff --git a/package/kernel/mac80211/patches/build/050-lib80211_option.patch b/package/kernel/mac80211/patches/build/050-lib80211_option.patch -deleted file mode 100644 -index c1b1bc757f..0000000000 ---- a/package/kernel/mac80211/patches/build/050-lib80211_option.patch -+++ /dev/null -@@ -1,34 +0,0 @@ ----- a/net/wireless/Kconfig --+++ b/net/wireless/Kconfig --@@ -188,7 +188,7 @@ config CFG80211_WEXT_EXPORT -- endif # CFG80211 -- -- config LIB80211 --- tristate --+ tristate "lib80211" -- depends on m -- default n -- help --@@ -198,19 +198,19 @@ config LIB80211 -- Drivers should select this themselves if needed. -- -- config LIB80211_CRYPT_WEP --- tristate --+ tristate "lib80211 WEP support" -- depends on m -- select BPAUTO_CRYPTO_LIB_ARC4 -- -- config LIB80211_CRYPT_CCMP --- tristate --+ tristate "lib80211 CCMP support" -- depends on m -- depends on CRYPTO -- depends on CRYPTO_AES -- depends on CRYPTO_CCM -- -- config LIB80211_CRYPT_TKIP --- tristate --+ tristate "lib80211 TKIP support" -- depends on m -- select BPAUTO_CRYPTO_LIB_ARC4 -- -diff --git a/package/kernel/mac80211/patches/build/060-no_local_ssb_bcma.patch b/package/kernel/mac80211/patches/build/060-no_local_ssb_bcma.patch -deleted file mode 100644 -index 4ad2ac081a..0000000000 ---- a/package/kernel/mac80211/patches/build/060-no_local_ssb_bcma.patch -+++ /dev/null -@@ -1,314 +0,0 @@ ----- a/local-symbols --+++ b/local-symbols --@@ -470,43 +470,6 @@ USB_VL600= -- USB_NET_CH9200= -- USB_NET_AQC111= -- USB_RTL8153_ECM= ---SSB_POSSIBLE= ---SSB= ---SSB_SPROM= ---SSB_BLOCKIO= ---SSB_PCIHOST_POSSIBLE= ---SSB_PCIHOST= ---SSB_B43_PCI_BRIDGE= ---SSB_PCMCIAHOST_POSSIBLE= ---SSB_PCMCIAHOST= ---SSB_SDIOHOST_POSSIBLE= ---SSB_SDIOHOST= ---SSB_HOST_SOC= ---SSB_SERIAL= ---SSB_DRIVER_PCICORE_POSSIBLE= ---SSB_DRIVER_PCICORE= ---SSB_PCICORE_HOSTMODE= ---SSB_DRIVER_MIPS= ---SSB_SFLASH= ---SSB_EMBEDDED= ---SSB_DRIVER_EXTIF= ---SSB_DRIVER_GIGE= ---SSB_DRIVER_GPIO= ---BCMA_POSSIBLE= ---BCMA= ---BCMA_BLOCKIO= ---BCMA_HOST_PCI_POSSIBLE= ---BCMA_HOST_PCI= ---BCMA_HOST_SOC= ---BCMA_DRIVER_PCI= ---BCMA_DRIVER_PCI_HOSTMODE= ---BCMA_DRIVER_MIPS= ---BCMA_PFLASH= ---BCMA_SFLASH= ---BCMA_NFLASH= ---BCMA_DRIVER_GMAC_CMN= ---BCMA_DRIVER_GPIO= ---BCMA_DEBUG= -- USB_ACM= -- USB_PRINTER= -- USB_WDM= ----- a/drivers/net/wireless/broadcom/b43/Kconfig --+++ b/drivers/net/wireless/broadcom/b43/Kconfig --@@ -63,21 +63,21 @@ endchoice -- config B43_PCI_AUTOSELECT -- bool -- depends on B43 && SSB_PCIHOST_POSSIBLE --- select SSB_PCIHOST --- select SSB_B43_PCI_BRIDGE --+ depends on SSB_PCIHOST --+ depends on SSB_B43_PCI_BRIDGE -- default y -- -- # Auto-select SSB PCICORE driver, if possible -- config B43_PCICORE_AUTOSELECT -- bool -- depends on B43 && SSB_DRIVER_PCICORE_POSSIBLE --- select SSB_DRIVER_PCICORE --+ depends on SSB_DRIVER_PCICORE -- default y -- -- config B43_SDIO -- bool "Broadcom 43xx SDIO device support" -- depends on B43 && B43_SSB && SSB_SDIOHOST_POSSIBLE --- select SSB_SDIOHOST --+ depends on SSB_SDIOHOST -- help -- Broadcom 43xx device support for Soft-MAC SDIO devices. -- --@@ -96,13 +96,13 @@ config B43_SDIO -- config B43_BCMA_PIO -- bool -- depends on B43 && B43_BCMA --- select BCMA_BLOCKIO --+ depends on BCMA_BLOCKIO -- default y -- -- config B43_PIO -- bool -- depends on B43 && B43_SSB --- select SSB_BLOCKIO --+ depends on SSB_BLOCKIO -- default y -- -- config B43_PHY_G ----- a/drivers/net/wireless/broadcom/b43/main.c --+++ b/drivers/net/wireless/broadcom/b43/main.c --@@ -2853,7 +2853,7 @@ static struct ssb_device *b43_ssb_gpio_d -- { -- struct ssb_bus *bus = dev->dev->sdev->bus; -- ---#ifdef CPTCFG_SSB_DRIVER_PCICORE --+#ifdef CONFIG_SSB_DRIVER_PCICORE -- return (bus->chipco.dev ? bus->chipco.dev : bus->pcicore.dev); -- #else -- return bus->chipco.dev; --@@ -4871,7 +4871,7 @@ static int b43_wireless_core_init(struct -- } -- if (sprom->boardflags_lo & B43_BFL_XTAL_NOSLOW) -- hf |= B43_HF_DSCRQ; /* Disable slowclock requests from ucode. */ ---#if defined(CPTCFG_B43_SSB) && defined(CPTCFG_SSB_DRIVER_PCICORE) --+#if defined(CPTCFG_B43_SSB) && defined(CONFIG_SSB_DRIVER_PCICORE) -- if (dev->dev->bus_type == B43_BUS_SSB && -- dev->dev->sdev->bus->bustype == SSB_BUSTYPE_PCI && -- dev->dev->sdev->bus->pcicore.dev->id.revision <= 10) ----- a/drivers/net/wireless/broadcom/b43legacy/Kconfig --+++ b/drivers/net/wireless/broadcom/b43legacy/Kconfig --@@ -3,7 +3,7 @@ config B43LEGACY -- tristate "Broadcom 43xx-legacy wireless support (mac80211 stack)" -- depends on m -- depends on SSB_POSSIBLE && MAC80211 && HAS_DMA --- select SSB --+ depends on SSB -- depends on FW_LOADER -- help -- b43legacy is a driver for 802.11b devices from Broadcom (BCM4301 and --@@ -25,15 +25,15 @@ config B43LEGACY -- config B43LEGACY_PCI_AUTOSELECT -- bool -- depends on B43LEGACY && SSB_PCIHOST_POSSIBLE --- select SSB_PCIHOST --- select SSB_B43_PCI_BRIDGE --+ depends on SSB_PCIHOST --+ depends on SSB_B43_PCI_BRIDGE -- default y -- -- # Auto-select SSB PCICORE driver, if possible -- config B43LEGACY_PCICORE_AUTOSELECT -- bool -- depends on B43LEGACY && SSB_DRIVER_PCICORE_POSSIBLE --- select SSB_DRIVER_PCICORE --+ depends on SSB_DRIVER_PCICORE -- default y -- -- # LED support ----- a/drivers/net/wireless/broadcom/b43legacy/main.c --+++ b/drivers/net/wireless/broadcom/b43legacy/main.c --@@ -1907,7 +1907,7 @@ static int b43legacy_gpio_init(struct b4 -- if (dev->dev->id.revision >= 2) -- mask |= 0x0010; /* FIXME: This is redundant. */ -- ---#ifdef CPTCFG_SSB_DRIVER_PCICORE --+#ifdef CONFIG_SSB_DRIVER_PCICORE -- pcidev = bus->pcicore.dev; -- #endif -- gpiodev = bus->chipco.dev ? : pcidev; --@@ -1926,7 +1926,7 @@ static void b43legacy_gpio_cleanup(struc -- struct ssb_bus *bus = dev->dev->bus; -- struct ssb_device *gpiodev, *pcidev = NULL; -- ---#ifdef CPTCFG_SSB_DRIVER_PCICORE --+#ifdef CONFIG_SSB_DRIVER_PCICORE -- pcidev = bus->pcicore.dev; -- #endif -- gpiodev = bus->chipco.dev ? : pcidev; ----- a/drivers/net/wireless/broadcom/brcm80211/Kconfig --+++ b/drivers/net/wireless/broadcom/brcm80211/Kconfig --@@ -8,7 +8,7 @@ config BRCMSMAC -- depends on m -- depends on MAC80211 -- depends on BCMA_POSSIBLE --- select BCMA --+ depends on BCMA -- select BRCMUTIL -- depends on FW_LOADER -- depends on CORDIC ----- a/Kconfig.local --+++ b/Kconfig.local --@@ -1414,117 +1414,6 @@ config BACKPORTED_USB_NET_AQC111 -- config BACKPORTED_USB_RTL8153_ECM -- tristate -- default USB_RTL8153_ECM ---config BACKPORTED_SSB_POSSIBLE --- tristate --- default SSB_POSSIBLE ---config BACKPORTED_SSB --- tristate --- default SSB ---config BACKPORTED_SSB_SPROM --- tristate --- default SSB_SPROM ---config BACKPORTED_SSB_BLOCKIO --- tristate --- default SSB_BLOCKIO ---config BACKPORTED_SSB_PCIHOST_POSSIBLE --- tristate --- default SSB_PCIHOST_POSSIBLE ---config BACKPORTED_SSB_PCIHOST --- tristate --- default SSB_PCIHOST ---config BACKPORTED_SSB_B43_PCI_BRIDGE --- tristate --- default SSB_B43_PCI_BRIDGE ---config BACKPORTED_SSB_PCMCIAHOST_POSSIBLE --- tristate --- default SSB_PCMCIAHOST_POSSIBLE ---config BACKPORTED_SSB_PCMCIAHOST --- tristate --- default SSB_PCMCIAHOST ---config BACKPORTED_SSB_SDIOHOST_POSSIBLE --- tristate --- default SSB_SDIOHOST_POSSIBLE ---config BACKPORTED_SSB_SDIOHOST --- tristate --- default SSB_SDIOHOST ---config BACKPORTED_SSB_HOST_SOC --- tristate --- default SSB_HOST_SOC ---config BACKPORTED_SSB_SERIAL --- tristate --- default SSB_SERIAL ---config BACKPORTED_SSB_DRIVER_PCICORE_POSSIBLE --- tristate --- default SSB_DRIVER_PCICORE_POSSIBLE ---config BACKPORTED_SSB_DRIVER_PCICORE --- tristate --- default SSB_DRIVER_PCICORE ---config BACKPORTED_SSB_PCICORE_HOSTMODE --- tristate --- default SSB_PCICORE_HOSTMODE ---config BACKPORTED_SSB_DRIVER_MIPS --- tristate --- default SSB_DRIVER_MIPS ---config BACKPORTED_SSB_SFLASH --- tristate --- default SSB_SFLASH ---config BACKPORTED_SSB_EMBEDDED --- tristate --- default SSB_EMBEDDED ---config BACKPORTED_SSB_DRIVER_EXTIF --- tristate --- default SSB_DRIVER_EXTIF ---config BACKPORTED_SSB_DRIVER_GIGE --- tristate --- default SSB_DRIVER_GIGE ---config BACKPORTED_SSB_DRIVER_GPIO --- tristate --- default SSB_DRIVER_GPIO ---config BACKPORTED_BCMA_POSSIBLE --- tristate --- default BCMA_POSSIBLE ---config BACKPORTED_BCMA --- tristate --- default BCMA ---config BACKPORTED_BCMA_BLOCKIO --- tristate --- default BCMA_BLOCKIO ---config BACKPORTED_BCMA_HOST_PCI_POSSIBLE --- tristate --- default BCMA_HOST_PCI_POSSIBLE ---config BACKPORTED_BCMA_HOST_PCI --- tristate --- default BCMA_HOST_PCI ---config BACKPORTED_BCMA_HOST_SOC --- tristate --- default BCMA_HOST_SOC ---config BACKPORTED_BCMA_DRIVER_PCI --- tristate --- default BCMA_DRIVER_PCI ---config BACKPORTED_BCMA_DRIVER_PCI_HOSTMODE --- tristate --- default BCMA_DRIVER_PCI_HOSTMODE ---config BACKPORTED_BCMA_DRIVER_MIPS --- tristate --- default BCMA_DRIVER_MIPS ---config BACKPORTED_BCMA_PFLASH --- tristate --- default BCMA_PFLASH ---config BACKPORTED_BCMA_SFLASH --- tristate --- default BCMA_SFLASH ---config BACKPORTED_BCMA_NFLASH --- tristate --- default BCMA_NFLASH ---config BACKPORTED_BCMA_DRIVER_GMAC_CMN --- tristate --- default BCMA_DRIVER_GMAC_CMN ---config BACKPORTED_BCMA_DRIVER_GPIO --- tristate --- default BCMA_DRIVER_GPIO ---config BACKPORTED_BCMA_DEBUG --- tristate --- default BCMA_DEBUG -- config BACKPORTED_USB_ACM -- tristate -- default USB_ACM ----- a/Kconfig.sources --+++ b/Kconfig.sources --@@ -10,9 +10,6 @@ source "$BACKPORT_DIR/drivers/soc/qcom/K -- source "$BACKPORT_DIR/drivers/net/wireless/Kconfig" -- source "$BACKPORT_DIR/drivers/net/usb/Kconfig" -- ---source "$BACKPORT_DIR/drivers/ssb/Kconfig" ---source "$BACKPORT_DIR/drivers/bcma/Kconfig" --- -- source "$BACKPORT_DIR/drivers/usb/class/Kconfig" -- -- source "$BACKPORT_DIR/drivers/staging/Kconfig" ----- a/Makefile.kernel --+++ b/Makefile.kernel --@@ -43,8 +43,6 @@ obj-$(CPTCFG_QRTR) += net/qrtr/ -- obj-$(CPTCFG_QCOM_QMI_HELPERS) += drivers/soc/qcom/ -- obj-$(CPTCFG_MHI_BUS) += drivers/bus/mhi/ -- obj-$(CPTCFG_WLAN) += drivers/net/wireless/ ---obj-$(CPTCFG_SSB) += drivers/ssb/ ---obj-$(CPTCFG_BCMA) += drivers/bcma/ -- obj-$(CPTCFG_USB_NET_RNDIS_WLAN) += drivers/net/usb/ -- -- obj-$(CPTCFG_USB_WDM) += drivers/usb/class/ -diff --git a/package/kernel/mac80211/patches/build/070-remove-broken-wext-select.patch b/package/kernel/mac80211/patches/build/070-remove-broken-wext-select.patch -deleted file mode 100644 -index 121b7faad9..0000000000 ---- a/package/kernel/mac80211/patches/build/070-remove-broken-wext-select.patch -+++ /dev/null -@@ -1,10 +0,0 @@ ----- a/drivers/staging/rtl8723bs/Kconfig --+++ b/drivers/staging/rtl8723bs/Kconfig --@@ -5,7 +5,6 @@ config RTL8723BS -- depends on m -- depends on WLAN && MMC && CFG80211 -- depends on m --- select CFG80211_WEXT -- depends on CRYPTO -- select BPAUTO_CRYPTO_LIB_ARC4 -- help -diff --git a/package/kernel/mac80211/patches/build/080-resv_start_op.patch b/package/kernel/mac80211/patches/build/080-resv_start_op.patch -deleted file mode 100644 -index 40b8e94a20..0000000000 ---- a/package/kernel/mac80211/patches/build/080-resv_start_op.patch -+++ /dev/null -@@ -1,24 +0,0 @@ ----- a/drivers/net/wireless/mac80211_hwsim.c --+++ b/drivers/net/wireless/mac80211_hwsim.c --@@ -5363,7 +5363,9 @@ static struct genl_family hwsim_genl_fam -- .module = THIS_MODULE, -- .small_ops = hwsim_ops, -- .n_small_ops = ARRAY_SIZE(hwsim_ops), --+#if LINUX_VERSION_IS_GEQ(6,1,0) -- .resv_start_op = HWSIM_CMD_DEL_MAC_ADDR + 1, --+#endif -- .mcgrps = hwsim_mcgrps, -- .n_mcgrps = ARRAY_SIZE(hwsim_mcgrps), -- }; ----- a/net/wireless/nl80211.c --+++ b/net/wireless/nl80211.c --@@ -17233,7 +17233,9 @@ static struct genl_family nl80211_fam __ -- .n_ops = ARRAY_SIZE(nl80211_ops), -- .small_ops = nl80211_small_ops, -- .n_small_ops = ARRAY_SIZE(nl80211_small_ops), --+#if LINUX_VERSION_IS_GEQ(6,1,0) -- .resv_start_op = NL80211_CMD_REMOVE_LINK_STA + 1, --+#endif -- .mcgrps = nl80211_mcgrps, -- .n_mcgrps = ARRAY_SIZE(nl80211_mcgrps), -- .parallel_ops = true, -diff --git a/package/kernel/mac80211/patches/build/090-bcma-otp.patch b/package/kernel/mac80211/patches/build/090-bcma-otp.patch -deleted file mode 100644 -index 3974776124..0000000000 ---- a/package/kernel/mac80211/patches/build/090-bcma-otp.patch -+++ /dev/null -@@ -1,13 +0,0 @@ ----- /dev/null --+++ b/backport-include/linux/bcma/bcma_driver_chipcommon.h --@@ -0,0 +1,10 @@ --+#ifndef __BACKPORT_BCMA_DRIVER_CHIPCOMMON_H --+#define __BACKPORT_BCMA_DRIVER_CHIPCOMMON_H --+ --+#include_next --+ --+#ifndef BCMA_CC_SROM_CONTROL_OTP_PRESENT --+#define BCMA_CC_SROM_CONTROL_OTP_PRESENT 0x00000020 --+#endif --+ --+#endif -diff --git a/package/kernel/mac80211/patches/build/100-backports-drop-QRTR-and-MHI.patch b/package/kernel/mac80211/patches/build/100-backports-drop-QRTR-and-MHI.patch -deleted file mode 100644 -index b017a0ce14..0000000000 ---- a/package/kernel/mac80211/patches/build/100-backports-drop-QRTR-and-MHI.patch -+++ /dev/null -@@ -1,76 +0,0 @@ --From 54e0f9aaf340377fb76acdffee9ec7372c4b70ae Mon Sep 17 00:00:00 2001 --From: Robert Marko --Date: Mon, 17 Oct 2022 11:35:36 +0200 --Subject: [PATCH] backports: drop QRTR and MHI -- --Backports currently include QRTR and MHI due to ath11k-pci requiring them, --however this at the same time prevents us from adding ath11k-ahb as it --also requires QRTR however its AHB variant from the kernel will conflict --with the core provided by backports. -- --Since MHI also conflicts with existing OpenWrt kmods providing MHI drop --both from backports and use the ones provided by OpenWrt kernel. -- --Signed-off-by: Robert Marko ----- -- Kconfig.sources | 2 -- -- Makefile.kernel | 2 -- -- drivers/net/wireless/ath/ath11k/Kconfig | 6 +++--- -- local-symbols | 8 -------- -- 4 files changed, 3 insertions(+), 15 deletions(-) -- ----- a/Kconfig.sources --+++ b/Kconfig.sources --@@ -4,8 +4,6 @@ source "$BACKPORT_DIR/compat/Kconfig" -- # these are copied from the kernel -- source "$BACKPORT_DIR/net/wireless/Kconfig" -- source "$BACKPORT_DIR/net/mac80211/Kconfig" ---source "$BACKPORT_DIR/net/qrtr/Kconfig" ---source "$BACKPORT_DIR/drivers/bus/mhi/Kconfig" -- source "$BACKPORT_DIR/drivers/soc/qcom/Kconfig" -- source "$BACKPORT_DIR/drivers/net/wireless/Kconfig" -- source "$BACKPORT_DIR/drivers/net/usb/Kconfig" ----- a/Makefile.kernel --+++ b/Makefile.kernel --@@ -39,9 +39,7 @@ obj-y += compat/ -- -- obj-$(CPTCFG_CFG80211) += net/wireless/ -- obj-$(CPTCFG_MAC80211) += net/mac80211/ ---obj-$(CPTCFG_QRTR) += net/qrtr/ -- obj-$(CPTCFG_QCOM_QMI_HELPERS) += drivers/soc/qcom/ ---obj-$(CPTCFG_MHI_BUS) += drivers/bus/mhi/ -- obj-$(CPTCFG_WLAN) += drivers/net/wireless/ -- obj-$(CPTCFG_USB_NET_RNDIS_WLAN) += drivers/net/usb/ -- ----- a/drivers/net/wireless/ath/ath11k/Kconfig --+++ b/drivers/net/wireless/ath/ath11k/Kconfig --@@ -25,9 +25,9 @@ config ATH11K_PCI -- tristate "Atheros ath11k PCI support" -- depends on m -- depends on ATH11K && PCI --- select MHI_BUS --- select QRTR --- select QRTR_MHI --+ depends on MHI_BUS --+ depends on QRTR --+ depends on QRTR_MHI -- help -- This module adds support for PCIE bus -- ----- a/local-symbols --+++ b/local-symbols --@@ -65,14 +65,6 @@ MAC80211_MESH_PS_DEBUG= -- MAC80211_TDLS_DEBUG= -- MAC80211_DEBUG_COUNTERS= -- MAC80211_STA_HASH_MAX_SIZE= ---QRTR= ---QRTR_SMD= ---QRTR_TUN= ---QRTR_MHI= ---MHI_BUS= ---MHI_BUS_DEBUG= ---MHI_BUS_PCI_GENERIC= ---MHI_BUS_EP= -- QCOM_AOSS_QMP= -- QCOM_COMMAND_DB= -- QCOM_CPR= -diff --git a/package/kernel/mac80211/patches/build/110-backport_napi_build_skb.patch b/package/kernel/mac80211/patches/build/110-backport_napi_build_skb.patch -deleted file mode 100644 -index 1e152fecea..0000000000 ---- a/package/kernel/mac80211/patches/build/110-backport_napi_build_skb.patch -+++ /dev/null -@@ -1,11 +0,0 @@ ----- a/backport-include/linux/skbuff.h --+++ b/backport-include/linux/skbuff.h --@@ -144,4 +144,8 @@ static inline u64 skb_get_kcov_handle(st -- #define napi_build_skb build_skb -- #endif -- --+#if LINUX_VERSION_IS_LESS(5,11,0) --+#define napi_build_skb build_skb --+#endif --+ -- #endif /* __BACKPORT_SKBUFF_H */ -diff --git a/package/kernel/mac80211/patches/mt7601u/001-wifi-mt7601u-update-firmware-path.patch b/package/kernel/mac80211/patches/mt7601u/001-wifi-mt7601u-update-firmware-path.patch -deleted file mode 100644 -index 5d982906c5..0000000000 ---- a/package/kernel/mac80211/patches/mt7601u/001-wifi-mt7601u-update-firmware-path.patch -+++ /dev/null -@@ -1,55 +0,0 @@ --From patchwork Mon May 15 22:56:53 2023 --Content-Type: text/plain; charset="utf-8" --MIME-Version: 1.0 --Content-Transfer-Encoding: 7bit --X-Patchwork-Submitter: Daniel Golle --X-Patchwork-Id: 13242309 --X-Patchwork-Delegate: kvalo@adurom.com --Return-Path: --Date: Tue, 16 May 2023 00:56:53 +0200 --From: Daniel Golle --To: Jakub Kicinski , Kalle Valo , -- "David S. Miller" , -- Eric Dumazet , -- Paolo Abeni , -- Matthias Brugger , -- AngeloGioacchino Del Regno -- , -- linux-wireless@vger.kernel.org, netdev@vger.kernel.org, -- linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org, -- linux-mediatek@lists.infradead.org --Subject: [PATCH] wifi: mt7601u: update firmware path --Message-ID: -- --MIME-Version: 1.0 --Content-Disposition: inline --Precedence: bulk --List-ID: --X-Mailing-List: linux-wireless@vger.kernel.org -- --mt7601u.bin was moved to mediatek/ folder in linux-wireless via commit --8451c2b1 ("mt76xx: Move the old Mediatek WiFi firmware to mediatek") --and linux-firmware release 20230515. -- --Update the firmware path requested by the mt7601u driver to follow up --with the move of the file. -- --Signed-off-by: Daniel Golle ----- -- drivers/net/wireless/mediatek/mt7601u/usb.h | 2 +- -- 1 file changed, 1 insertion(+), 1 deletion(-) -- -- --base-commit: 0d9b41daa5907756a31772d8af8ac5ff25cf17c1 -- ----- a/drivers/net/wireless/mediatek/mt7601u/usb.h --+++ b/drivers/net/wireless/mediatek/mt7601u/usb.h --@@ -8,7 +8,7 @@ -- -- #include "mt7601u.h" -- ---#define MT7601U_FIRMWARE "mt7601u.bin" --+#define MT7601U_FIRMWARE "mediatek/mt7601u.bin" -- -- #define MT_VEND_REQ_MAX_RETRY 10 -- #define MT_VEND_REQ_TOUT_MS 300 -diff --git a/package/kernel/mac80211/patches/mwl/700-mwl8k-missing-pci-id-for-WNR854T.patch b/package/kernel/mac80211/patches/mwl/700-mwl8k-missing-pci-id-for-WNR854T.patch -deleted file mode 100644 -index 11536651b5..0000000000 ---- a/package/kernel/mac80211/patches/mwl/700-mwl8k-missing-pci-id-for-WNR854T.patch -+++ /dev/null -@@ -1,10 +0,0 @@ ----- a/drivers/net/wireless/marvell/mwl8k.c --+++ b/drivers/net/wireless/marvell/mwl8k.c --@@ -5703,6 +5703,7 @@ MODULE_FIRMWARE("mwl8k/fmimage_8366.fw") -- MODULE_FIRMWARE(MWL8K_8366_AP_FW(MWL8K_8366_AP_FW_API)); -- -- static const struct pci_device_id mwl8k_pci_id_table[] = { --+ { PCI_VDEVICE(MARVELL, 0x2a02), .driver_data = MWL8363, }, -- { PCI_VDEVICE(MARVELL, 0x2a0a), .driver_data = MWL8363, }, -- { PCI_VDEVICE(MARVELL, 0x2a0c), .driver_data = MWL8363, }, -- { PCI_VDEVICE(MARVELL, 0x2a24), .driver_data = MWL8363, }, -diff --git a/package/kernel/mac80211/patches/mwl/801-libertas-configure-sysfs-links.patch b/package/kernel/mac80211/patches/mwl/801-libertas-configure-sysfs-links.patch -deleted file mode 100644 -index 1dbcb1bfef..0000000000 ---- a/package/kernel/mac80211/patches/mwl/801-libertas-configure-sysfs-links.patch -+++ /dev/null -@@ -1,21 +0,0 @@ ----- a/drivers/net/wireless/marvell/libertas/cfg.c --+++ b/drivers/net/wireless/marvell/libertas/cfg.c --@@ -2052,6 +2052,8 @@ struct wireless_dev *lbs_cfg_alloc(struc -- goto err_wiphy_new; -- } -- --+ set_wiphy_dev(wdev->wiphy, dev); --+ -- return wdev; -- -- err_wiphy_new: ----- a/drivers/net/wireless/marvell/libertas/main.c --+++ b/drivers/net/wireless/marvell/libertas/main.c --@@ -935,6 +935,7 @@ struct lbs_private *lbs_add_card(void *c -- goto err_adapter; -- } -- --+ dev_net_set(dev, wiphy_net(wdev->wiphy)); -- dev->ieee80211_ptr = wdev; -- dev->ml_priv = priv; -- SET_NETDEV_DEV(dev, dmdev); -diff --git a/package/kernel/mac80211/patches/mwl/802-libertas-set-wireless-macaddr.patch b/package/kernel/mac80211/patches/mwl/802-libertas-set-wireless-macaddr.patch -deleted file mode 100644 -index b47aee5490..0000000000 ---- a/package/kernel/mac80211/patches/mwl/802-libertas-set-wireless-macaddr.patch -+++ /dev/null -@@ -1,11 +0,0 @@ ----- a/drivers/net/wireless/marvell/libertas/cfg.c --+++ b/drivers/net/wireless/marvell/libertas/cfg.c --@@ -2128,6 +2128,8 @@ int lbs_cfg_register(struct lbs_private -- wdev->wiphy->n_cipher_suites = ARRAY_SIZE(cipher_suites); -- wdev->wiphy->reg_notifier = lbs_reg_notifier; -- --+ memcpy(wdev->wiphy->perm_addr, priv->current_addr, ETH_ALEN); --+ -- ret = wiphy_register(wdev->wiphy); -- if (ret < 0) -- pr_err("cannot register wiphy device\n"); -diff --git a/package/kernel/mac80211/patches/mwl/900-mwifiex-increase-the-global-limit-up-to-4-SSID.patch b/package/kernel/mac80211/patches/mwl/900-mwifiex-increase-the-global-limit-up-to-4-SSID.patch -deleted file mode 100644 -index caa139a2c6..0000000000 ---- a/package/kernel/mac80211/patches/mwl/900-mwifiex-increase-the-global-limit-up-to-4-SSID.patch -+++ /dev/null -@@ -1,41 +0,0 @@ --From ef8098cd6cb8b5989afef2e8461fe6ba9570a854 Mon Sep 17 00:00:00 2001 --From: Josef Schlehofer --Date: Wed, 24 Nov 2021 12:47:40 +0100 --Subject: [PATCH] mwifiex: increase the global limit up to 4 SSID -- --Firmware for SDIO (88W8997), which is used in Turris MOX SDIO addon [1], --allows up to 4 SSID. Unfortunately, driver (even in mainline kernel) --has a global limit for all Marvell cards up to 3 SSID. -- --Pali Rohár tested this patch and verified that the SDIO Wi-Fi addon works --with the 4 SSID. So, let's increase the global limit from 3 to 4. -- --Ideally, this patch should be done differently before sending --it to Linux kernel. It means that limit definition should be moved to --the card-specific structure. -- --[1] https://docs.turris.cz/hw/mox/addons/#wi-fi-sdio ----- -- drivers/net/wireless/marvell/mwifiex/decl.h | 4 ++-- -- 1 file changed, 2 insertions(+), 2 deletions(-) -- ----- a/drivers/net/wireless/marvell/mwifiex/decl.h --+++ b/drivers/net/wireless/marvell/mwifiex/decl.h --@@ -18,7 +18,7 @@ -- #include -- -- #define MWIFIEX_BSS_COEX_COUNT 2 ---#define MWIFIEX_MAX_BSS_NUM (3) --+#define MWIFIEX_MAX_BSS_NUM (4) -- -- #define MWIFIEX_DMA_ALIGN_SZ 64 -- #define MWIFIEX_RX_HEADROOM 64 --@@ -100,7 +100,7 @@ -- #define MWIFIEX_RATE_INDEX_OFDM0 4 -- -- #define MWIFIEX_MAX_STA_NUM 3 ---#define MWIFIEX_MAX_UAP_NUM 3 --+#define MWIFIEX_MAX_UAP_NUM 4 -- #define MWIFIEX_MAX_P2P_NUM 3 -- -- #define MWIFIEX_A_BAND_START_FREQ 5000 -diff --git a/package/kernel/mac80211/patches/mwl/940-mwl8k_init_devices_synchronously.patch b/package/kernel/mac80211/patches/mwl/940-mwl8k_init_devices_synchronously.patch -deleted file mode 100644 -index c8d24283aa..0000000000 ---- a/package/kernel/mac80211/patches/mwl/940-mwl8k_init_devices_synchronously.patch -+++ /dev/null -@@ -1,20 +0,0 @@ ----- a/drivers/net/wireless/marvell/mwl8k.c --+++ b/drivers/net/wireless/marvell/mwl8k.c --@@ -6289,6 +6289,8 @@ static int mwl8k_probe(struct pci_dev *p -- -- priv->running_bsses = 0; -- --+ wait_for_completion(&priv->firmware_loading_complete); --+ -- return rc; -- -- err_stop_firmware: --@@ -6322,8 +6324,6 @@ static void mwl8k_remove(struct pci_dev -- return; -- priv = hw->priv; -- --- wait_for_completion(&priv->firmware_loading_complete); --- -- if (priv->fw_state == FW_STATE_ERROR) { -- mwl8k_hw_reset(priv); -- goto unmap; -diff --git a/package/kernel/mac80211/patches/mwl/950-mwifiex-Print-stringified-name-of-command-in-error-l.patch b/package/kernel/mac80211/patches/mwl/950-mwifiex-Print-stringified-name-of-command-in-error-l.patch -deleted file mode 100644 -index 98ed9e60e9..0000000000 ---- a/package/kernel/mac80211/patches/mwl/950-mwifiex-Print-stringified-name-of-command-in-error-l.patch -+++ /dev/null -@@ -1,189 +0,0 @@ --From f7252b1b5755150535af226e806594bbefd45e0f Mon Sep 17 00:00:00 2001 --From: =?UTF-8?q?Pali=20Roh=C3=A1r?= --Date: Sun, 26 Sep 2021 14:39:44 +0200 --Subject: [PATCH] mwifiex: Print stringified name of command in error log --MIME-Version: 1.0 --Content-Type: text/plain; charset=UTF-8 --Content-Transfer-Encoding: 8bit -- --Failed hex command number in error log is hard to understand. --So add also more human readable stringified command name into error log. -- --Signed-off-by: Pali Rohár ----- -- drivers/net/wireless/marvell/mwifiex/cmdevt.c | 96 +++++++++++++++++-- -- drivers/net/wireless/marvell/mwifiex/main.h | 2 + -- .../wireless/marvell/mwifiex/sta_cmdresp.c | 5 +- -- .../net/wireless/marvell/mwifiex/uap_cmd.c | 3 +- -- 4 files changed, 95 insertions(+), 11 deletions(-) -- ----- a/drivers/net/wireless/marvell/mwifiex/cmdevt.c --+++ b/drivers/net/wireless/marvell/mwifiex/cmdevt.c --@@ -16,6 +16,85 @@ -- -- static void mwifiex_cancel_pending_ioctl(struct mwifiex_adapter *adapter); -- --+const char * --+mwifiex_cmd_to_str(u16 command) --+{ --+ switch (command) { --+ case HostCmd_CMD_GET_HW_SPEC: return "GET_HW_SPEC"; --+ case HostCmd_CMD_802_11_SCAN: return "SCAN"; --+ case HostCmd_CMD_802_11_GET_LOG: return "GET_LOG"; --+ case HostCmd_CMD_MAC_MULTICAST_ADR: return "MAC_MULTICAST_ADR"; --+ case HostCmd_CMD_802_11_EEPROM_ACCESS: return "EEPROM_ACCESS"; --+ case HostCmd_CMD_802_11_ASSOCIATE: return "ASSOCIATE"; --+ case HostCmd_CMD_802_11_SNMP_MIB: return "SNMP_MIB"; --+ case HostCmd_CMD_MAC_REG_ACCESS: return "MAC_REG_ACCESS"; --+ case HostCmd_CMD_BBP_REG_ACCESS: return "BBP_REG_ACCESS"; --+ case HostCmd_CMD_RF_REG_ACCESS: return "RF_REG_ACCESS"; --+ case HostCmd_CMD_PMIC_REG_ACCESS: return "PMIC_REG_ACCESS"; --+ case HostCmd_CMD_RF_TX_PWR: return "RF_TX_PWR"; --+ case HostCmd_CMD_RF_ANTENNA: return "RF_ANTENNA"; --+ case HostCmd_CMD_802_11_DEAUTHENTICATE: return "DEAUTHENTICATE"; --+ case HostCmd_CMD_MAC_CONTROL: return "MAC_CONTROL"; --+ case HostCmd_CMD_802_11_AD_HOC_START: return "AD_HOC_START"; --+ case HostCmd_CMD_802_11_AD_HOC_JOIN: return "AD_HOC_JOIN"; --+ case HostCmd_CMD_802_11_AD_HOC_STOP: return "AD_HOC_STOP"; --+ case HostCmd_CMD_802_11_MAC_ADDRESS: return "MAC_ADDRESS"; --+ case HostCmd_CMD_802_11D_DOMAIN_INFO: return "DOMAIN_INFO"; --+ case HostCmd_CMD_802_11_KEY_MATERIAL: return "KEY_MATERIAL"; --+ case HostCmd_CMD_802_11_BG_SCAN_CONFIG: return "BG_SCAN_CONFIG"; --+ case HostCmd_CMD_802_11_BG_SCAN_QUERY: return "BG_SCAN_QUERY"; --+ case HostCmd_CMD_WMM_GET_STATUS: return "WMM_GET_STATUS"; --+ case HostCmd_CMD_802_11_SUBSCRIBE_EVENT: return "SUBSCRIBE_EVENT"; --+ case HostCmd_CMD_802_11_TX_RATE_QUERY: return "TX_RATE_QUERY"; --+ case HostCmd_CMD_802_11_IBSS_COALESCING_STATUS: return "IBSS_COALESCING_STATUS"; --+ case HostCmd_CMD_MEM_ACCESS: return "MEM_ACCESS"; --+ case HostCmd_CMD_CFG_DATA: return "CFG_DATA"; --+ case HostCmd_CMD_VERSION_EXT: return "VERSION_EXT"; --+ case HostCmd_CMD_MEF_CFG: return "MEF_CFG"; --+ case HostCmd_CMD_RSSI_INFO: return "RSSI_INFO"; --+ case HostCmd_CMD_FUNC_INIT: return "FUNC_INIT"; --+ case HostCmd_CMD_FUNC_SHUTDOWN: return "FUNC_SHUTDOWN"; --+ case HOST_CMD_APCMD_SYS_RESET: return "SYS_RESET"; --+ case HostCmd_CMD_UAP_SYS_CONFIG: return "UAP_SYS_CONFIG"; --+ case HostCmd_CMD_UAP_BSS_START: return "UAP_BSS_START"; --+ case HostCmd_CMD_UAP_BSS_STOP: return "UAP_BSS_STOP"; --+ case HOST_CMD_APCMD_STA_LIST: return "STA_LIST"; --+ case HostCmd_CMD_UAP_STA_DEAUTH: return "UAP_STA_DEAUTH"; --+ case HostCmd_CMD_11N_CFG: return "11N_CFG"; --+ case HostCmd_CMD_11N_ADDBA_REQ: return "ADDBA_REQ"; --+ case HostCmd_CMD_11N_ADDBA_RSP: return "ADDBA_RSP"; --+ case HostCmd_CMD_11N_DELBA: return "DELBA"; --+ case HostCmd_CMD_RECONFIGURE_TX_BUFF: return "RECONFIGURE_TX_BUFF"; --+ case HostCmd_CMD_CHAN_REPORT_REQUEST: return "CHAN_REPORT_REQUEST"; --+ case HostCmd_CMD_AMSDU_AGGR_CTRL: return "AMSDU_AGGR_CTRL"; --+ case HostCmd_CMD_TXPWR_CFG: return "TXPWR_CFG"; --+ case HostCmd_CMD_TX_RATE_CFG: return "TX_RATE_CFG"; --+ case HostCmd_CMD_ROBUST_COEX: return "ROBUST_COEX"; --+ case HostCmd_CMD_802_11_PS_MODE_ENH: return "PS_MODE_ENH"; --+ case HostCmd_CMD_802_11_HS_CFG_ENH: return "HS_CFG_ENH"; --+ case HostCmd_CMD_P2P_MODE_CFG: return "P2P_MODE_CFG"; --+ case HostCmd_CMD_CAU_REG_ACCESS: return "CAU_REG_ACCESS"; --+ case HostCmd_CMD_SET_BSS_MODE: return "SET_BSS_MODE"; --+ case HostCmd_CMD_PCIE_DESC_DETAILS: return "PCIE_DESC_DETAILS"; --+ case HostCmd_CMD_802_11_SCAN_EXT: return "SCAN_EXT"; --+ case HostCmd_CMD_COALESCE_CFG: return "COALESCE_CFG"; --+ case HostCmd_CMD_MGMT_FRAME_REG: return "MGMT_FRAME_REG"; --+ case HostCmd_CMD_REMAIN_ON_CHAN: return "REMAIN_ON_CHAN"; --+ case HostCmd_CMD_GTK_REKEY_OFFLOAD_CFG: return "GTK_REKEY_OFFLOAD_CFG"; --+ case HostCmd_CMD_11AC_CFG: return "11AC_CFG"; --+ case HostCmd_CMD_HS_WAKEUP_REASON: return "HS_WAKEUP_REASON"; --+ case HostCmd_CMD_TDLS_CONFIG: return "TDLS_CONFIG"; --+ case HostCmd_CMD_MC_POLICY: return "MC_POLICY"; --+ case HostCmd_CMD_TDLS_OPER: return "TDLS_OPER"; --+ case HostCmd_CMD_FW_DUMP_EVENT: return "FW_DUMP_EVENT"; --+ case HostCmd_CMD_SDIO_SP_RX_AGGR_CFG: return "SDIO_SP_RX_AGGR_CFG"; --+ case HostCmd_CMD_STA_CONFIGURE: return "STA_CONFIGURE"; --+ case HostCmd_CMD_CHAN_REGION_CFG: return "CHAN_REGION_CFG"; --+ case HostCmd_CMD_PACKET_AGGR_CTRL: return "PACKET_AGGR_CTRL"; --+ default: return "UNKNOWN"; --+ } --+} --+ -- /* -- * This function initializes a command node. -- * --@@ -193,8 +272,8 @@ static int mwifiex_dnld_cmd_to_fw(struct -- cmd_code != HostCmd_CMD_FUNC_SHUTDOWN && -- cmd_code != HostCmd_CMD_FUNC_INIT) { -- mwifiex_dbg(adapter, ERROR, --- "DNLD_CMD: FW in reset state, ignore cmd %#x\n", --- cmd_code); --+ "DNLD_CMD: FW in reset state, ignore cmd %s (%#x)\n", --+ mwifiex_cmd_to_str(cmd_code), cmd_code); -- mwifiex_recycle_cmd_node(adapter, cmd_node); -- queue_work(adapter->workqueue, &adapter->main_work); -- return -1; --@@ -653,8 +732,8 @@ int mwifiex_send_cmd(struct mwifiex_priv -- /* Return error, since the command preparation failed */ -- if (ret) { -- mwifiex_dbg(adapter, ERROR, --- "PREP_CMD: cmd %#x preparation failed\n", --- cmd_no); --+ "PREP_CMD: cmd %s (%#x) preparation failed\n", --+ mwifiex_cmd_to_str(cmd_no), cmd_no); -- mwifiex_insert_cmd_to_free_q(adapter, cmd_node); -- return -1; -- } --@@ -902,8 +981,9 @@ int mwifiex_process_cmdresp(struct mwifi -- if (adapter->hw_status == MWIFIEX_HW_STATUS_INITIALIZING) { -- if (ret) { -- mwifiex_dbg(adapter, ERROR, --- "%s: cmd %#x failed during\t" --- "initialization\n", __func__, cmdresp_no); --+ "%s: cmd %s (%#x) failed during\t" --+ "initialization\n", __func__, --+ mwifiex_cmd_to_str(cmdresp_no), cmdresp_no); -- mwifiex_init_fw_complete(adapter); -- return -1; -- } else if (adapter->last_init_cmd == cmdresp_no) --@@ -1273,8 +1353,8 @@ mwifiex_process_sleep_confirm_resp(struc -- -- if (command != HostCmd_CMD_802_11_PS_MODE_ENH) { -- mwifiex_dbg(adapter, ERROR, --- "%s: rcvd unexpected resp for cmd %#x, result = %x\n", --- __func__, command, result); --+ "%s: rcvd unexpected resp for cmd %s (%#x), result = %x\n", --+ __func__, mwifiex_cmd_to_str(command), command, result); -- return; -- } -- ----- a/drivers/net/wireless/marvell/mwifiex/main.h --+++ b/drivers/net/wireless/marvell/mwifiex/main.h --@@ -1099,6 +1099,8 @@ void mwifiex_cancel_all_pending_cmd(stru -- void mwifiex_cancel_pending_scan_cmd(struct mwifiex_adapter *adapter); -- void mwifiex_cancel_scan(struct mwifiex_adapter *adapter); -- --+const char *mwifiex_cmd_to_str(u16 command); --+ -- void mwifiex_recycle_cmd_node(struct mwifiex_adapter *adapter, -- struct cmd_ctrl_node *cmd_node); -- ----- a/drivers/net/wireless/marvell/mwifiex/sta_cmdresp.c --+++ b/drivers/net/wireless/marvell/mwifiex/sta_cmdresp.c --@@ -36,8 +36,9 @@ mwifiex_process_cmdresp_error(struct mwi -- struct host_cmd_ds_802_11_ps_mode_enh *pm; -- -- mwifiex_dbg(adapter, ERROR, --- "CMD_RESP: cmd %#x error, result=%#x\n", --- resp->command, resp->result); --+ "CMD_RESP: cmd %s (%#x) error, result=%#x\n", --+ mwifiex_cmd_to_str(le16_to_cpu(resp->command)), --+ le16_to_cpu(resp->command), le16_to_cpu(resp->result)); -- -- if (adapter->curr_cmd->wait_q_enabled) -- adapter->cmd_wait_q.status = -1; ----- a/drivers/net/wireless/marvell/mwifiex/uap_cmd.c --+++ b/drivers/net/wireless/marvell/mwifiex/uap_cmd.c --@@ -794,7 +794,8 @@ int mwifiex_uap_prepare_cmd(struct mwifi -- break; -- default: -- mwifiex_dbg(priv->adapter, ERROR, --- "PREP_CMD: unknown cmd %#x\n", cmd_no); --+ "PREP_CMD: unknown cmd (%s) %#x\n", --+ mwifiex_cmd_to_str(cmd_no), cmd_no); -- return -1; -- } -- -diff --git a/package/kernel/mac80211/patches/rt2x00/100-rt2x00_options.patch b/package/kernel/mac80211/patches/rt2x00/100-rt2x00_options.patch -deleted file mode 100644 -index 295904c64e..0000000000 ---- a/package/kernel/mac80211/patches/rt2x00/100-rt2x00_options.patch -+++ /dev/null -@@ -1,47 +0,0 @@ ----- a/drivers/net/wireless/ralink/rt2x00/Kconfig --+++ b/drivers/net/wireless/ralink/rt2x00/Kconfig --@@ -226,36 +226,37 @@ config RT2800SOC -- -- -- config RT2800_LIB --- tristate --+ tristate "RT2800 USB/PCI support" -- depends on m -- -- config RT2800_LIB_MMIO --- tristate --+ tristate "RT2800 MMIO support" -- depends on m -- select RT2X00_LIB_MMIO -- select RT2800_LIB -- -- config RT2X00_LIB_MMIO --- tristate --+ tristate "RT2x00 MMIO support" -- depends on m -- -- config RT2X00_LIB_PCI --- tristate --+ tristate "RT2x00 PCI support" -- depends on m -- select RT2X00_LIB -- -- config RT2X00_LIB_SOC --- tristate --+ tristate "RT2x00 SoC support" --+ depends on SOC_RT288X || SOC_RT305X || SOC_MT7620 -- depends on m -- select RT2X00_LIB -- -- config RT2X00_LIB_USB --- tristate --+ tristate "RT2x00 USB support" -- depends on m -- select RT2X00_LIB -- -- config RT2X00_LIB --- tristate --+ tristate "RT2x00 support" -- depends on m -- -- config RT2X00_LIB_FIRMWARE -diff --git a/package/kernel/mac80211/patches/rt2x00/501-rt2x00-allow-to-build-rt2800soc-module-for-RT3883.patch b/package/kernel/mac80211/patches/rt2x00/501-rt2x00-allow-to-build-rt2800soc-module-for-RT3883.patch -deleted file mode 100644 -index b4106b0197..0000000000 ---- a/package/kernel/mac80211/patches/rt2x00/501-rt2x00-allow-to-build-rt2800soc-module-for-RT3883.patch -+++ /dev/null -@@ -1,30 +0,0 @@ --From 91094ed065f7794886b4a5490fd6de942f036bb4 Mon Sep 17 00:00:00 2001 --From: Gabor Juhos --Date: Sun, 24 Mar 2013 19:26:26 +0100 --Subject: [PATCH] rt2x00: allow to build rt2800soc module for RT3883 -- --Signed-off-by: Gabor Juhos ----- -- drivers/net/wireless/ralink/rt2x00/Kconfig | 2 +- -- 1 file changed, 1 insertion(+), 1 deletion(-) -- ----- a/drivers/net/wireless/ralink/rt2x00/Kconfig --+++ b/drivers/net/wireless/ralink/rt2x00/Kconfig --@@ -211,7 +211,7 @@ endif -- config RT2800SOC -- tristate "Ralink WiSoC support" -- depends on m --- depends on SOC_RT288X || SOC_RT305X || SOC_MT7620 --+ depends on SOC_RT288X || SOC_RT305X || SOC_RT3883 || SOC_MT7620 -- select RT2X00_LIB_SOC -- select RT2X00_LIB_MMIO -- select RT2X00_LIB_CRYPTO --@@ -246,7 +246,7 @@ config RT2X00_LIB_PCI -- -- config RT2X00_LIB_SOC -- tristate "RT2x00 SoC support" --- depends on SOC_RT288X || SOC_RT305X || SOC_MT7620 --+ depends on SOC_RT288X || SOC_RT305X || SOC_RT3883 || SOC_MT7620 -- depends on m -- select RT2X00_LIB -- -diff --git a/package/kernel/mac80211/patches/rt2x00/601-rt2x00-introduce-rt2x00_platform_h.patch b/package/kernel/mac80211/patches/rt2x00/601-rt2x00-introduce-rt2x00_platform_h.patch -deleted file mode 100644 -index 1e6211a470..0000000000 ---- a/package/kernel/mac80211/patches/rt2x00/601-rt2x00-introduce-rt2x00_platform_h.patch -+++ /dev/null -@@ -1,32 +0,0 @@ ----- /dev/null --+++ b/include/linux/rt2x00_platform.h --@@ -0,0 +1,19 @@ --+/* --+ * Platform data definition for the rt2x00 driver --+ * --+ * Copyright (C) 2011 Gabor Juhos --+ * --+ * This program is free software; you can redistribute it and/or modify it --+ * under the terms of the GNU General Public License version 2 as published --+ * by the Free Software Foundation. --+ * --+ */ --+ --+#ifndef _RT2X00_PLATFORM_H --+#define _RT2X00_PLATFORM_H --+ --+struct rt2x00_platform_data { --+ char *eeprom_file_name; --+}; --+ --+#endif /* _RT2X00_PLATFORM_H */ ----- a/drivers/net/wireless/ralink/rt2x00/rt2x00.h --+++ b/drivers/net/wireless/ralink/rt2x00/rt2x00.h --@@ -28,6 +28,7 @@ -- #include -- #include -- #include --+#include -- -- #include -- -diff --git a/package/kernel/mac80211/patches/rt2x00/602-rt2x00-introduce-rt2x00eeprom.patch b/package/kernel/mac80211/patches/rt2x00/602-rt2x00-introduce-rt2x00eeprom.patch -deleted file mode 100644 -index ab0fa3670d..0000000000 ---- a/package/kernel/mac80211/patches/rt2x00/602-rt2x00-introduce-rt2x00eeprom.patch -+++ /dev/null -@@ -1,296 +0,0 @@ ----- a/local-symbols --+++ b/local-symbols --@@ -347,6 +347,7 @@ RT2X00_LIB_FIRMWARE= -- RT2X00_LIB_CRYPTO= -- RT2X00_LIB_LEDS= -- RT2X00_LIB_DEBUGFS= --+RT2X00_LIB_EEPROM= -- RT2X00_DEBUG= -- WLAN_VENDOR_REALTEK= -- RTL8180= ----- a/drivers/net/wireless/ralink/rt2x00/Kconfig --+++ b/drivers/net/wireless/ralink/rt2x00/Kconfig --@@ -70,6 +70,7 @@ config RT2800PCI -- select RT2X00_LIB_MMIO -- select RT2X00_LIB_PCI -- select RT2X00_LIB_FIRMWARE --+ select RT2X00_LIB_EEPROM -- select RT2X00_LIB_CRYPTO -- depends on CRC_CCITT -- depends on EEPROM_93CX6 --@@ -216,6 +217,7 @@ config RT2800SOC -- select RT2X00_LIB_MMIO -- select RT2X00_LIB_CRYPTO -- select RT2X00_LIB_FIRMWARE --+ select RT2X00_LIB_EEPROM -- select RT2800_LIB -- select RT2800_LIB_MMIO -- help --@@ -266,6 +268,9 @@ config RT2X00_LIB_FIRMWARE -- config RT2X00_LIB_CRYPTO -- bool -- --+config RT2X00_LIB_EEPROM --+ bool --+ -- config RT2X00_LIB_LEDS -- bool -- default y if (RT2X00_LIB=y && LEDS_CLASS=y) || (RT2X00_LIB=m && LEDS_CLASS!=n) ----- a/drivers/net/wireless/ralink/rt2x00/Makefile --+++ b/drivers/net/wireless/ralink/rt2x00/Makefile --@@ -8,6 +8,7 @@ rt2x00lib-$(CPTCFG_RT2X00_LIB_DEBUGFS) + -- rt2x00lib-$(CPTCFG_RT2X00_LIB_CRYPTO) += rt2x00crypto.o -- rt2x00lib-$(CPTCFG_RT2X00_LIB_FIRMWARE) += rt2x00firmware.o -- rt2x00lib-$(CPTCFG_RT2X00_LIB_LEDS) += rt2x00leds.o --+rt2x00lib-$(CPTCFG_RT2X00_LIB_EEPROM) += rt2x00eeprom.o -- -- obj-$(CPTCFG_RT2X00_LIB) += rt2x00lib.o -- obj-$(CPTCFG_RT2X00_LIB_MMIO) += rt2x00mmio.o ----- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.h --+++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.h --@@ -47,6 +47,8 @@ struct rt2800_drv_data { -- struct ieee80211_sta *wcid_to_sta[STA_IDS_SIZE]; -- }; -- --+#include "rt2800.h" --+ -- struct rt2800_ops { -- u32 (*register_read)(struct rt2x00_dev *rt2x00dev, -- const unsigned int offset); --@@ -145,6 +147,15 @@ static inline int rt2800_read_eeprom(str -- { -- const struct rt2800_ops *rt2800ops = rt2x00dev->ops->drv; -- --+ if (rt2x00dev->eeprom_file) { --+ memcpy(rt2x00dev->eeprom, rt2x00dev->eeprom_file->data, --+ EEPROM_SIZE); --+ return 0; --+ } --+ --+ if (!rt2800ops->read_eeprom) --+ return -EINVAL; --+ -- return rt2800ops->read_eeprom(rt2x00dev); -- } -- ----- a/drivers/net/wireless/ralink/rt2x00/rt2800soc.c --+++ b/drivers/net/wireless/ralink/rt2x00/rt2800soc.c --@@ -90,19 +90,6 @@ static int rt2800soc_set_device_state(st -- return retval; -- } -- ---static int rt2800soc_read_eeprom(struct rt2x00_dev *rt2x00dev) ---{ --- void __iomem *base_addr = ioremap(0x1F040000, EEPROM_SIZE); --- --- if (!base_addr) --- return -ENOMEM; --- --- memcpy_fromio(rt2x00dev->eeprom, base_addr, EEPROM_SIZE); --- --- iounmap(base_addr); --- return 0; ---} --- -- /* Firmware functions */ -- static char *rt2800soc_get_firmware_name(struct rt2x00_dev *rt2x00dev) -- { --@@ -168,7 +155,6 @@ static const struct rt2800_ops rt2800soc -- .register_multiread = rt2x00mmio_register_multiread, -- .register_multiwrite = rt2x00mmio_register_multiwrite, -- .regbusy_read = rt2x00mmio_regbusy_read, --- .read_eeprom = rt2800soc_read_eeprom, -- .hwcrypt_disabled = rt2800soc_hwcrypt_disabled, -- .drv_write_firmware = rt2800soc_write_firmware, -- .drv_init_registers = rt2800mmio_init_registers, ----- a/drivers/net/wireless/ralink/rt2x00/rt2x00.h --+++ b/drivers/net/wireless/ralink/rt2x00/rt2x00.h --@@ -703,6 +703,7 @@ enum rt2x00_capability_flags { -- REQUIRE_HT_TX_DESC, -- REQUIRE_PS_AUTOWAKE, -- REQUIRE_DELAYED_RFKILL, --+ REQUIRE_EEPROM_FILE, -- -- /* -- * Capabilities --@@ -980,6 +981,11 @@ struct rt2x00_dev { -- const struct firmware *fw; -- -- /* --+ * EEPROM image. --+ */ --+ const struct firmware *eeprom_file; --+ --+ /* -- * FIFO for storing tx status reports between isr and tasklet. -- */ -- DECLARE_KFIFO_PTR(txstatus_fifo, u32); ----- a/drivers/net/wireless/ralink/rt2x00/rt2x00dev.c --+++ b/drivers/net/wireless/ralink/rt2x00/rt2x00dev.c --@@ -1419,6 +1419,10 @@ int rt2x00lib_probe_dev(struct rt2x00_de -- INIT_DELAYED_WORK(&rt2x00dev->autowakeup_work, rt2x00lib_autowakeup); -- INIT_WORK(&rt2x00dev->sleep_work, rt2x00lib_sleep); -- --+ retval = rt2x00lib_load_eeprom_file(rt2x00dev); --+ if (retval) --+ goto exit; --+ -- /* -- * Let the driver probe the device to detect the capabilities. -- */ --@@ -1559,6 +1563,11 @@ void rt2x00lib_remove_dev(struct rt2x00_ -- * Free the driver data. -- */ -- kfree(rt2x00dev->drv_data); --+ --+ /* --+ * Free EEPROM image. --+ */ --+ rt2x00lib_free_eeprom_file(rt2x00dev); -- } -- EXPORT_SYMBOL_GPL(rt2x00lib_remove_dev); -- ----- /dev/null --+++ b/drivers/net/wireless/ralink/rt2x00/rt2x00eeprom.c --@@ -0,0 +1,106 @@ --+/* --+ Copyright (C) 2004 - 2009 Ivo van Doorn --+ Copyright (C) 2004 - 2009 Gertjan van Wingerde --+ --+ --+ 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. --+ --+ This program is distributed in the hope that it will be useful, --+ but WITHOUT ANY WARRANTY; without even the implied warranty of --+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the --+ GNU General Public License for more details. --+ --+ You should have received a copy of the GNU General Public License --+ along with this program; if not, write to the --+ Free Software Foundation, Inc., --+ 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. --+ */ --+ --+/* --+ Module: rt2x00lib --+ Abstract: rt2x00 eeprom file loading routines. --+ */ --+ --+#include --+#include --+ --+#include "rt2x00.h" --+#include "rt2x00lib.h" --+ --+static const char * --+rt2x00lib_get_eeprom_file_name(struct rt2x00_dev *rt2x00dev) --+{ --+ struct rt2x00_platform_data *pdata = rt2x00dev->dev->platform_data; --+ --+ if (pdata && pdata->eeprom_file_name) --+ return pdata->eeprom_file_name; --+ --+ return NULL; --+} --+ --+static int rt2x00lib_request_eeprom_file(struct rt2x00_dev *rt2x00dev) --+{ --+ const struct firmware *ee; --+ const char *ee_name; --+ int retval; --+ --+ ee_name = rt2x00lib_get_eeprom_file_name(rt2x00dev); --+ if (!ee_name && test_bit(REQUIRE_EEPROM_FILE, &rt2x00dev->cap_flags)) { --+ rt2x00_err(rt2x00dev, "Required EEPROM name is missing."); --+ return -EINVAL; --+ } --+ --+ if (!ee_name) --+ return 0; --+ --+ rt2x00_info(rt2x00dev, "Loading EEPROM data from '%s'.\n", ee_name); --+ --+ retval = request_firmware(&ee, ee_name, rt2x00dev->dev); --+ if (retval) { --+ rt2x00_err(rt2x00dev, "Failed to request EEPROM.\n"); --+ return retval; --+ } --+ --+ if (!ee || !ee->size || !ee->data) { --+ rt2x00_err(rt2x00dev, "Failed to read EEPROM file.\n"); --+ retval = -ENOENT; --+ goto err_exit; --+ } --+ --+ if (ee->size != rt2x00dev->ops->eeprom_size) { --+ rt2x00_err(rt2x00dev, --+ "EEPROM file size is invalid, it should be %d bytes\n", --+ rt2x00dev->ops->eeprom_size); --+ retval = -EINVAL; --+ goto err_release_ee; --+ } --+ --+ rt2x00dev->eeprom_file = ee; --+ return 0; --+ --+err_release_ee: --+ release_firmware(ee); --+err_exit: --+ return retval; --+} --+ --+int rt2x00lib_load_eeprom_file(struct rt2x00_dev *rt2x00dev) --+{ --+ int retval; --+ --+ retval = rt2x00lib_request_eeprom_file(rt2x00dev); --+ if (retval) --+ return retval; --+ --+ return 0; --+} --+ --+void rt2x00lib_free_eeprom_file(struct rt2x00_dev *rt2x00dev) --+{ --+ if (rt2x00dev->eeprom_file && rt2x00dev->eeprom_file->size) --+ release_firmware(rt2x00dev->eeprom_file); --+ rt2x00dev->eeprom_file = NULL; --+} ----- a/drivers/net/wireless/ralink/rt2x00/rt2x00lib.h --+++ b/drivers/net/wireless/ralink/rt2x00/rt2x00lib.h --@@ -286,6 +286,22 @@ static inline void rt2x00lib_free_firmwa -- #endif /* CPTCFG_RT2X00_LIB_FIRMWARE */ -- -- /* --+ * EEPROM file handlers. --+ */ --+#ifdef CPTCFG_RT2X00_LIB_EEPROM --+int rt2x00lib_load_eeprom_file(struct rt2x00_dev *rt2x00dev); --+void rt2x00lib_free_eeprom_file(struct rt2x00_dev *rt2x00dev); --+#else --+static inline int rt2x00lib_load_eeprom_file(struct rt2x00_dev *rt2x00dev) --+{ --+ return 0; --+} --+static inline void rt2x00lib_free_eeprom_file(struct rt2x00_dev *rt2x00dev) --+{ --+} --+#endif /* CPTCFG_RT2X00_LIB_EEPROM */ --+ --+/* -- * Debugfs handlers. -- */ -- #ifdef CPTCFG_RT2X00_LIB_DEBUGFS ----- a/drivers/net/wireless/ralink/rt2x00/rt2x00soc.c --+++ b/drivers/net/wireless/ralink/rt2x00/rt2x00soc.c --@@ -86,6 +86,7 @@ int rt2x00soc_probe(struct platform_devi -- if (IS_ERR(rt2x00dev->clk)) -- rt2x00dev->clk = NULL; -- --+ set_bit(REQUIRE_EEPROM_FILE, &rt2x00dev->cap_flags); -- rt2x00_set_chip_intf(rt2x00dev, RT2X00_CHIP_INTF_SOC); -- -- retval = rt2x00soc_alloc_reg(rt2x00dev); -diff --git a/package/kernel/mac80211/patches/rt2x00/603-rt2x00-of_load_eeprom_filename.patch b/package/kernel/mac80211/patches/rt2x00/603-rt2x00-of_load_eeprom_filename.patch -deleted file mode 100644 -index 431e090237..0000000000 ---- a/package/kernel/mac80211/patches/rt2x00/603-rt2x00-of_load_eeprom_filename.patch -+++ /dev/null -@@ -1,31 +0,0 @@ ----- a/drivers/net/wireless/ralink/rt2x00/rt2x00eeprom.c --+++ b/drivers/net/wireless/ralink/rt2x00/rt2x00eeprom.c --@@ -26,6 +26,7 @@ -- -- #include -- #include --+#include -- -- #include "rt2x00.h" -- #include "rt2x00lib.h" --@@ -34,10 +35,20 @@ static const char * -- rt2x00lib_get_eeprom_file_name(struct rt2x00_dev *rt2x00dev) -- { -- struct rt2x00_platform_data *pdata = rt2x00dev->dev->platform_data; --+#ifdef CONFIG_OF --+ struct device_node *np; --+ const char *eep; --+#endif -- -- if (pdata && pdata->eeprom_file_name) -- return pdata->eeprom_file_name; -- --+#ifdef CONFIG_OF --+ np = rt2x00dev->dev->of_node; --+ if (np && of_property_read_string(np, "ralink,eeprom", &eep) == 0) --+ return eep; --+#endif --+ -- return NULL; -- } -- -diff --git a/package/kernel/mac80211/patches/rt2x00/604-rt2x00-load-eeprom-on-SoC-from-a-mtd-device-defines-.patch b/package/kernel/mac80211/patches/rt2x00/604-rt2x00-load-eeprom-on-SoC-from-a-mtd-device-defines-.patch -deleted file mode 100644 -index 7338eb15b2..0000000000 ---- a/package/kernel/mac80211/patches/rt2x00/604-rt2x00-load-eeprom-on-SoC-from-a-mtd-device-defines-.patch -+++ /dev/null -@@ -1,113 +0,0 @@ --From 339fe73f340161a624cc08e738d2244814852c3e Mon Sep 17 00:00:00 2001 --From: John Crispin --Date: Sun, 17 Mar 2013 00:55:04 +0100 --Subject: [PATCH] rt2x00: load eeprom on SoC from a mtd device defines inside -- OF -- --Signed-off-by: John Crispin ----- -- drivers/net/wireless/ralink/rt2x00/Kconfig | 1 + -- drivers/net/wireless/ralink/rt2x00/rt2x00eeprom.c | 65 +++++++++++++++++++++++ -- 2 files changed, 66 insertions(+) -- ----- a/drivers/net/wireless/ralink/rt2x00/Kconfig --+++ b/drivers/net/wireless/ralink/rt2x00/Kconfig --@@ -220,6 +220,7 @@ config RT2800SOC -- select RT2X00_LIB_EEPROM -- select RT2800_LIB -- select RT2800_LIB_MMIO --+ select MTD if SOC_RT288X || SOC_RT305X -- help -- This adds support for Ralink WiSoC devices. -- Supported chips: RT2880, RT3050, RT3052, RT3350, RT3352. ----- a/drivers/net/wireless/ralink/rt2x00/rt2x00eeprom.c --+++ b/drivers/net/wireless/ralink/rt2x00/rt2x00eeprom.c --@@ -26,11 +26,76 @@ -- -- #include -- #include --+#if IS_ENABLED(CONFIG_MTD) --+#include --+#include --+#endif -- #include -- -- #include "rt2x00.h" -- #include "rt2x00lib.h" -- --+#if IS_ENABLED(CONFIG_MTD) --+static int rt2800lib_read_eeprom_mtd(struct rt2x00_dev *rt2x00dev) --+{ --+ int ret = -EINVAL; --+#ifdef CONFIG_OF --+ static struct firmware mtd_fw; --+ struct device_node *np = rt2x00dev->dev->of_node, *mtd_np = NULL; --+ size_t retlen, len = rt2x00dev->ops->eeprom_size; --+ int i, size, offset = 0; --+ struct mtd_info *mtd; --+ const char *part; --+ const __be32 *list; --+ phandle phandle; --+ --+ list = of_get_property(np, "ralink,mtd-eeprom", &size); --+ if (!list) --+ return -ENOENT; --+ --+ phandle = be32_to_cpup(list++); --+ if (phandle) --+ mtd_np = of_find_node_by_phandle(phandle); --+ if (!mtd_np) { --+ dev_err(rt2x00dev->dev, "failed to load mtd phandle\n"); --+ return -EINVAL; --+ } --+ --+ part = of_get_property(mtd_np, "label", NULL); --+ if (!part) --+ part = mtd_np->name; --+ --+ mtd = get_mtd_device_nm(part); --+ if (IS_ERR(mtd)) { --+ dev_err(rt2x00dev->dev, "failed to get mtd device \"%s\"\n", part); --+ return PTR_ERR(mtd); --+ } --+ --+ if (size > sizeof(*list)) --+ offset = be32_to_cpup(list); --+ --+ ret = mtd_read(mtd, offset, len, &retlen, (u_char *) rt2x00dev->eeprom); --+ put_mtd_device(mtd); --+ --+ if ((retlen != rt2x00dev->ops->eeprom_size) || ret) { --+ dev_err(rt2x00dev->dev, "failed to load eeprom from device \"%s\"\n", part); --+ return ret; --+ } --+ --+ if (of_find_property(np, "ralink,mtd-eeprom-swap", NULL)) --+ for (i = 0; i < len/sizeof(u16); i++) --+ rt2x00dev->eeprom[i] = swab16(rt2x00dev->eeprom[i]); --+ --+ rt2x00dev->eeprom_file = &mtd_fw; --+ mtd_fw.data = (const u8 *) rt2x00dev->eeprom; --+ --+ dev_info(rt2x00dev->dev, "loaded eeprom from mtd device \"%s\"\n", part); --+#endif --+ --+ return ret; --+} --+#endif --+ -- static const char * -- rt2x00lib_get_eeprom_file_name(struct rt2x00_dev *rt2x00dev) -- { --@@ -58,6 +123,11 @@ static int rt2x00lib_request_eeprom_file -- const char *ee_name; -- int retval; -- --+#if IS_ENABLED(CONFIG_MTD) --+ if (!rt2800lib_read_eeprom_mtd(rt2x00dev)) --+ return 0; --+#endif --+ -- ee_name = rt2x00lib_get_eeprom_file_name(rt2x00dev); -- if (!ee_name && test_bit(REQUIRE_EEPROM_FILE, &rt2x00dev->cap_flags)) { -- rt2x00_err(rt2x00dev, "Required EEPROM name is missing."); -diff --git a/package/kernel/mac80211/patches/rt2x00/606-rt2x00-allow_disabling_bands_through_platform_data.patch b/package/kernel/mac80211/patches/rt2x00/606-rt2x00-allow_disabling_bands_through_platform_data.patch -deleted file mode 100644 -index ffee2189d2..0000000000 ---- a/package/kernel/mac80211/patches/rt2x00/606-rt2x00-allow_disabling_bands_through_platform_data.patch -+++ /dev/null -@@ -1,47 +0,0 @@ ----- a/include/linux/rt2x00_platform.h --+++ b/include/linux/rt2x00_platform.h --@@ -14,6 +14,9 @@ -- -- struct rt2x00_platform_data { -- char *eeprom_file_name; --+ --+ int disable_2ghz; --+ int disable_5ghz; -- }; -- -- #endif /* _RT2X00_PLATFORM_H */ ----- a/drivers/net/wireless/ralink/rt2x00/rt2x00dev.c --+++ b/drivers/net/wireless/ralink/rt2x00/rt2x00dev.c --@@ -1007,6 +1007,22 @@ static int rt2x00lib_probe_hw_modes(stru -- unsigned int num_rates; -- unsigned int i; -- --+ if (rt2x00dev->dev->platform_data) { --+ struct rt2x00_platform_data *pdata; --+ --+ pdata = rt2x00dev->dev->platform_data; --+ if (pdata->disable_2ghz) --+ spec->supported_bands &= ~SUPPORT_BAND_2GHZ; --+ if (pdata->disable_5ghz) --+ spec->supported_bands &= ~SUPPORT_BAND_5GHZ; --+ } --+ --+ if ((spec->supported_bands & SUPPORT_BAND_BOTH) == 0) { --+ rt2x00_err(rt2x00dev, "No supported bands\n"); --+ return -EINVAL; --+ } --+ --+ -- num_rates = 0; -- if (spec->supported_rates & SUPPORT_RATE_CCK) -- num_rates += 4; ----- a/drivers/net/wireless/ralink/rt2x00/rt2x00.h --+++ b/drivers/net/wireless/ralink/rt2x00/rt2x00.h --@@ -408,6 +408,7 @@ struct hw_mode_spec { -- unsigned int supported_bands; -- #define SUPPORT_BAND_2GHZ 0x00000001 -- #define SUPPORT_BAND_5GHZ 0x00000002 --+#define SUPPORT_BAND_BOTH (SUPPORT_BAND_2GHZ | SUPPORT_BAND_5GHZ) -- -- unsigned int supported_rates; -- #define SUPPORT_RATE_CCK 0x00000001 -diff --git a/package/kernel/mac80211/patches/rt2x00/607-rt2x00-add_platform_data_mac_addr.patch b/package/kernel/mac80211/patches/rt2x00/607-rt2x00-add_platform_data_mac_addr.patch -deleted file mode 100644 -index 37553bb80a..0000000000 ---- a/package/kernel/mac80211/patches/rt2x00/607-rt2x00-add_platform_data_mac_addr.patch -+++ /dev/null -@@ -1,25 +0,0 @@ ----- a/drivers/net/wireless/ralink/rt2x00/rt2x00dev.c --+++ b/drivers/net/wireless/ralink/rt2x00/rt2x00dev.c --@@ -989,6 +989,12 @@ static void rt2x00lib_rate(struct ieee80 -- -- void rt2x00lib_set_mac_address(struct rt2x00_dev *rt2x00dev, u8 *eeprom_mac_addr) -- { --+ struct rt2x00_platform_data *pdata; --+ --+ pdata = rt2x00dev->dev->platform_data; --+ if (pdata && pdata->mac_address) --+ ether_addr_copy(eeprom_mac_addr, pdata->mac_address); --+ -- of_get_mac_address(rt2x00dev->dev->of_node, eeprom_mac_addr); -- -- if (!is_valid_ether_addr(eeprom_mac_addr)) { ----- a/include/linux/rt2x00_platform.h --+++ b/include/linux/rt2x00_platform.h --@@ -14,6 +14,7 @@ -- -- struct rt2x00_platform_data { -- char *eeprom_file_name; --+ const u8 *mac_address; -- -- int disable_2ghz; -- int disable_5ghz; -diff --git a/package/kernel/mac80211/patches/rt2x00/608-rt2x00-allow_disabling_bands_through_dts.patch b/package/kernel/mac80211/patches/rt2x00/608-rt2x00-allow_disabling_bands_through_dts.patch -deleted file mode 100644 -index 6211809c0a..0000000000 ---- a/package/kernel/mac80211/patches/rt2x00/608-rt2x00-allow_disabling_bands_through_dts.patch -+++ /dev/null -@@ -1,19 +0,0 @@ ----- a/drivers/net/wireless/ralink/rt2x00/rt2x00dev.c --+++ b/drivers/net/wireless/ralink/rt2x00/rt2x00dev.c --@@ -1012,6 +1012,16 @@ static int rt2x00lib_probe_hw_modes(stru -- struct ieee80211_rate *rates; -- unsigned int num_rates; -- unsigned int i; --+#ifdef CONFIG_OF --+ struct device_node *np = rt2x00dev->dev->of_node; --+ unsigned int enabled; --+ if (!of_property_read_u32(np, "ralink,2ghz", --+ &enabled) && !enabled) --+ spec->supported_bands &= ~SUPPORT_BAND_2GHZ; --+ if (!of_property_read_u32(np, "ralink,5ghz", --+ &enabled) && !enabled) --+ spec->supported_bands &= ~SUPPORT_BAND_5GHZ; --+#endif /* CONFIG_OF */ -- -- if (rt2x00dev->dev->platform_data) { -- struct rt2x00_platform_data *pdata; -diff --git a/package/kernel/mac80211/patches/rt2x00/609-rt2x00-make-wmac-loadable-via-OF-on-rt288x-305x-SoC.patch b/package/kernel/mac80211/patches/rt2x00/609-rt2x00-make-wmac-loadable-via-OF-on-rt288x-305x-SoC.patch -deleted file mode 100644 -index 8964f8bf10..0000000000 ---- a/package/kernel/mac80211/patches/rt2x00/609-rt2x00-make-wmac-loadable-via-OF-on-rt288x-305x-SoC.patch -+++ /dev/null -@@ -1,33 +0,0 @@ --From 04dbd87265f6ba4a373b211ba324b437d224fb2d Mon Sep 17 00:00:00 2001 --From: John Crispin --Date: Sun, 17 Mar 2013 00:03:31 +0100 --Subject: [PATCH 21/38] rt2x00: make wmac loadable via OF on rt288x/305x SoC -- --This patch ads the match table to allow loading the wmac support from a --devicetree. -- --Signed-off-by: John Crispin ----- -- drivers/net/wireless/ralink/rt2x00/rt2800pci.c | 7 +++++++ -- 1 file changed, 7 insertions(+) -- ----- a/drivers/net/wireless/ralink/rt2x00/rt2800soc.c --+++ b/drivers/net/wireless/ralink/rt2x00/rt2800soc.c --@@ -225,10 +225,17 @@ static int rt2800soc_probe(struct platfo -- return rt2x00soc_probe(pdev, &rt2800soc_ops); -- } -- --+static const struct of_device_id rt2880_wmac_match[] = { --+ { .compatible = "ralink,rt2880-wmac" }, --+ {}, --+}; --+MODULE_DEVICE_TABLE(of, rt2880_wmac_match); --+ -- static struct platform_driver rt2800soc_driver = { -- .driver = { -- .name = "rt2800_wmac", -- .mod_name = KBUILD_MODNAME, --+ .of_match_table = rt2880_wmac_match, -- }, -- .probe = rt2800soc_probe, -- .remove = rt2x00soc_remove, -diff --git a/package/kernel/mac80211/patches/rt2x00/610-rt2x00-change-led-polarity-from-OF.patch b/package/kernel/mac80211/patches/rt2x00/610-rt2x00-change-led-polarity-from-OF.patch -deleted file mode 100644 -index acc8a8edb8..0000000000 ---- a/package/kernel/mac80211/patches/rt2x00/610-rt2x00-change-led-polarity-from-OF.patch -+++ /dev/null -@@ -1,40 +0,0 @@ ----- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c --+++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c --@@ -25,6 +25,7 @@ -- #include -- #include -- #include --+#include -- -- #include "rt2x00.h" -- #include "rt2800lib.h" --@@ -11131,6 +11132,17 @@ static int rt2800_init_eeprom(struct rt2 -- rt2800_init_led(rt2x00dev, &rt2x00dev->led_assoc, LED_TYPE_ASSOC); -- rt2800_init_led(rt2x00dev, &rt2x00dev->led_qual, LED_TYPE_QUALITY); -- --+ { --+ struct device_node *np = rt2x00dev->dev->of_node; --+ unsigned int led_polarity; --+ --+ /* Allow overriding polarity from OF */ --+ if (!of_property_read_u32(np, "ralink,led-polarity", --+ &led_polarity)) --+ rt2x00_set_field16(&eeprom, EEPROM_FREQ_LED_POLARITY, --+ led_polarity); --+ } --+ -- rt2x00dev->led_mcu_reg = eeprom; -- #endif /* CPTCFG_RT2X00_LIB_LEDS */ -- ----- a/drivers/net/wireless/ralink/rt2x00/rt2x00leds.c --+++ b/drivers/net/wireless/ralink/rt2x00/rt2x00leds.c --@@ -98,6 +98,9 @@ static int rt2x00leds_register_led(struc -- led->led_dev.name = name; -- led->led_dev.brightness = LED_OFF; -- --+ if (rt2x00_is_soc(rt2x00dev)) --+ led->led_dev.brightness_set(&led->led_dev, LED_OFF); --+ -- retval = led_classdev_register(device, &led->led_dev); -- if (retval) { -- rt2x00_err(rt2x00dev, "Failed to register led handler\n"); -diff --git a/package/kernel/mac80211/patches/rt2x00/611-rt2x00-add-AP+STA-support.patch b/package/kernel/mac80211/patches/rt2x00/611-rt2x00-add-AP+STA-support.patch -deleted file mode 100644 -index 5ef5fc8def..0000000000 ---- a/package/kernel/mac80211/patches/rt2x00/611-rt2x00-add-AP+STA-support.patch -+++ /dev/null -@@ -1,11 +0,0 @@ ----- a/drivers/net/wireless/ralink/rt2x00/rt2x00dev.c --+++ b/drivers/net/wireless/ralink/rt2x00/rt2x00dev.c --@@ -1358,7 +1358,7 @@ static inline void rt2x00lib_set_if_comb -- */ -- if_limit = &rt2x00dev->if_limits_ap; -- if_limit->max = rt2x00dev->ops->max_ap_intf; --- if_limit->types = BIT(NL80211_IFTYPE_AP); --+ if_limit->types = BIT(NL80211_IFTYPE_AP) | BIT(NL80211_IFTYPE_STATION); -- #ifdef CPTCFG_MAC80211_MESH -- if_limit->types |= BIT(NL80211_IFTYPE_MESH_POINT); -- #endif -diff --git a/package/kernel/mac80211/patches/rt2x00/994-rt2x00-import-support-for-external-LNA-on-MT7620.patch b/package/kernel/mac80211/patches/rt2x00/994-rt2x00-import-support-for-external-LNA-on-MT7620.patch -deleted file mode 100644 -index deaa03be6c..0000000000 ---- a/package/kernel/mac80211/patches/rt2x00/994-rt2x00-import-support-for-external-LNA-on-MT7620.patch -+++ /dev/null -@@ -1,161 +0,0 @@ --From 0fce1109f894ec7fcd72cb098843a1eff786716a Mon Sep 17 00:00:00 2001 --From: Daniel Golle --Date: Fri, 16 Sep 2022 20:49:42 +0100 --Subject: [PATCH 16/16] rt2x00: import support for external LNA on MT7620 --To: linux-wireless@vger.kernel.org, -- Stanislaw Gruszka , -- Helmut Schaa --Cc: Kalle Valo , -- David S. Miller , -- Eric Dumazet , -- Jakub Kicinski , -- Paolo Abeni , -- Johannes Berg -- --In order to carry out calibration on boards with ePA or eLNA the PA pin --needs to be switch to GPIO mode on MT7620. Implement that by selecting --pinctrl state "pa_gpio" which should be defined for MT7620 boards with --eLNA or ePA beside the "default" state. -- --Reported-by: Serge Vasilugin --Signed-off-by: Daniel Golle ----- -- .../net/wireless/ralink/rt2x00/rt2800lib.c | 58 +++++++++++++++++++ -- drivers/net/wireless/ralink/rt2x00/rt2x00.h | 5 ++ -- .../net/wireless/ralink/rt2x00/rt2x00soc.c | 15 +++++ -- 3 files changed, 78 insertions(+) -- ----- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c --+++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c --@@ -304,6 +304,24 @@ static void rt2800_rf_write(struct rt2x0 -- mutex_unlock(&rt2x00dev->csr_mutex); -- } -- --+void rt6352_enable_pa_pin(struct rt2x00_dev *rt2x00dev, int enable) --+{ --+ if (!rt2x00dev->pinctrl) --+ return; --+ --+ if (enable) { --+ if (!rt2x00dev->pins_default) --+ return; --+ --+ pinctrl_select_state(rt2x00dev->pinctrl, rt2x00dev->pins_default); --+ } else { --+ if (!rt2x00dev->pins_pa_gpio) --+ return; --+ --+ pinctrl_select_state(rt2x00dev->pinctrl, rt2x00dev->pins_pa_gpio); --+ } --+} --+ -- static const unsigned int rt2800_eeprom_map[EEPROM_WORD_COUNT] = { -- [EEPROM_CHIP_ID] = 0x0000, -- [EEPROM_VERSION] = 0x0001, --@@ -4469,6 +4487,29 @@ static void rt2800_config_channel(struct -- rt2800_register_write(rt2x00dev, TX1_RF_GAIN_ATTEN, -- 0x6C6C6B6C); -- } --+ --+ if (rt2x00_has_cap_external_lna_bg(rt2x00dev)) { --+ reg = rt2800_register_read(rt2x00dev, RF_CONTROL3); --+ reg |= 0x00000101; --+ rt2800_register_write(rt2x00dev, RF_CONTROL3, reg); --+ --+ reg = rt2800_register_read(rt2x00dev, RF_BYPASS3); --+ reg |= 0x00000101; --+ rt2800_register_write(rt2x00dev, RF_BYPASS3, reg); --+ --+ rt2800_rfcsr_write_chanreg(rt2x00dev, 14, 0x66); --+ rt2800_rfcsr_write_chanreg(rt2x00dev, 17, 0x20); --+ rt2800_rfcsr_write_chanreg(rt2x00dev, 18, 0x42); --+ rt2800_bbp_write(rt2x00dev, 75, 0x68); --+ rt2800_bbp_write(rt2x00dev, 76, 0x4C); --+ rt2800_bbp_write(rt2x00dev, 79, 0x1C); --+ rt2800_bbp_write(rt2x00dev, 80, 0x0C); --+ rt2800_bbp_write(rt2x00dev, 82, 0xB6); --+ /* bank 0 RF reg 42 and glrt BBP reg 141 will be set in --+ * config channel function in dependence of channel and --+ * HT20/HT40 so don't touch it --+ */ --+ } -- } -- -- bbp = rt2800_bbp_read(rt2x00dev, 4); --@@ -10583,6 +10624,7 @@ static void rt2800_init_rfcsr_6352(struc -- rt2800_rfcsr_write_dccal(rt2x00dev, 5, 0x00); -- rt2800_rfcsr_write_dccal(rt2x00dev, 17, 0x7C); -- --+ rt6352_enable_pa_pin(rt2x00dev, 0); -- rt2800_r_calibration(rt2x00dev); -- rt2800_rf_self_txdc_cal(rt2x00dev); -- rt2800_rxdcoc_calibration(rt2x00dev); --@@ -10590,6 +10632,22 @@ static void rt2800_init_rfcsr_6352(struc -- rt2800_bw_filter_calibration(rt2x00dev, false); -- rt2800_loft_iq_calibration(rt2x00dev); -- rt2800_rxiq_calibration(rt2x00dev); --+ rt6352_enable_pa_pin(rt2x00dev, 1); --+ --+ if (rt2x00_has_cap_external_lna_bg(rt2x00dev)) { --+ rt2800_rfcsr_write_chanreg(rt2x00dev, 14, 0x66); --+ rt2800_rfcsr_write_chanreg(rt2x00dev, 17, 0x20); --+ rt2800_rfcsr_write_chanreg(rt2x00dev, 18, 0x42); --+ rt2800_bbp_write(rt2x00dev, 75, 0x68); --+ rt2800_bbp_write(rt2x00dev, 76, 0x4C); --+ rt2800_bbp_write(rt2x00dev, 79, 0x1C); --+ rt2800_bbp_write(rt2x00dev, 80, 0x0C); --+ rt2800_bbp_write(rt2x00dev, 82, 0xB6); --+ /* bank 0 RF reg 42 and glrt BBP reg 141 will be set in config --+ * channel function in dependence of channel and HT20/HT40, --+ * so don't touch them here. --+ */ --+ } -- } -- -- static void rt2800_init_rfcsr(struct rt2x00_dev *rt2x00dev) ----- a/drivers/net/wireless/ralink/rt2x00/rt2x00.h --+++ b/drivers/net/wireless/ralink/rt2x00/rt2x00.h --@@ -28,6 +28,7 @@ -- #include -- #include -- #include --+#include -- #include -- -- #include --@@ -1029,6 +1030,11 @@ struct rt2x00_dev { -- -- /* Clock for System On Chip devices. */ -- struct clk *clk; --+ --+ /* pinctrl and states for System On Chip devices with PA/LNA. */ --+ struct pinctrl *pinctrl; --+ struct pinctrl_state *pins_default; --+ struct pinctrl_state *pins_pa_gpio; -- }; -- -- struct rt2x00_bar_list_entry { ----- a/drivers/net/wireless/ralink/rt2x00/rt2x00soc.c --+++ b/drivers/net/wireless/ralink/rt2x00/rt2x00soc.c --@@ -97,6 +97,21 @@ int rt2x00soc_probe(struct platform_devi -- if (retval) -- goto exit_free_reg; -- --+ rt2x00dev->pinctrl = devm_pinctrl_get(&pdev->dev); --+ if (IS_ERR(rt2x00dev->pinctrl)) { --+ rt2x00dev->pinctrl = NULL; --+ rt2x00dev->pins_default = NULL; --+ rt2x00dev->pins_pa_gpio = NULL; --+ } else { --+ rt2x00dev->pins_default = pinctrl_lookup_state(rt2x00dev->pinctrl, "default"); --+ if (IS_ERR(rt2x00dev->pins_default)) --+ rt2x00dev->pins_default = NULL; --+ --+ rt2x00dev->pins_pa_gpio = pinctrl_lookup_state(rt2x00dev->pinctrl, "pa_gpio"); --+ if (IS_ERR(rt2x00dev->pins_pa_gpio)) --+ rt2x00dev->pins_pa_gpio = NULL; --+ } --+ -- return 0; -- -- exit_free_reg: -diff --git a/package/kernel/mac80211/patches/rt2x00/995-rt2x00-mt7620-introduce-accessors-for-CHIP_VER-register.patch b/package/kernel/mac80211/patches/rt2x00/995-rt2x00-mt7620-introduce-accessors-for-CHIP_VER-register.patch -deleted file mode 100644 -index 97a56de2b3..0000000000 ---- a/package/kernel/mac80211/patches/rt2x00/995-rt2x00-mt7620-introduce-accessors-for-CHIP_VER-register.patch -+++ /dev/null -@@ -1,139 +0,0 @@ ----- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.h --+++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.h --@@ -78,6 +78,9 @@ struct rt2800_ops { -- int (*drv_init_registers)(struct rt2x00_dev *rt2x00dev); -- __le32 *(*drv_get_txwi)(struct queue_entry *entry); -- unsigned int (*drv_get_dma_done)(struct data_queue *queue); --+ int (*hw_get_chippkg)(void); --+ int (*hw_get_chipver)(void); --+ int (*hw_get_chipeco)(void); -- }; -- -- static inline u32 rt2800_register_read(struct rt2x00_dev *rt2x00dev, --@@ -195,6 +198,27 @@ static inline unsigned int rt2800_drv_ge -- return rt2800ops->drv_get_dma_done(queue); -- } -- --+static inline int rt2800_hw_get_chippkg(struct rt2x00_dev *rt2x00dev) --+{ --+ const struct rt2800_ops *rt2800ops = rt2x00dev->ops->drv; --+ --+ return rt2800ops->hw_get_chippkg(); --+} --+ --+static inline int rt2800_hw_get_chipver(struct rt2x00_dev *rt2x00dev) --+{ --+ const struct rt2800_ops *rt2800ops = rt2x00dev->ops->drv; --+ --+ return rt2800ops->hw_get_chipver(); --+} --+ --+static inline int rt2800_hw_get_chipeco(struct rt2x00_dev *rt2x00dev) --+{ --+ const struct rt2800_ops *rt2800ops = rt2x00dev->ops->drv; --+ --+ return rt2800ops->hw_get_chipeco(); --+} --+ -- void rt2800_mcu_request(struct rt2x00_dev *rt2x00dev, -- const u8 command, const u8 token, -- const u8 arg0, const u8 arg1); ----- a/drivers/net/wireless/ralink/rt2x00/rt2800pci.c --+++ b/drivers/net/wireless/ralink/rt2x00/rt2800pci.c --@@ -286,6 +286,10 @@ static int rt2800pci_read_eeprom(struct -- return retval; -- } -- --+static int rt2800pci_get_chippkg(void) { return 0; } --+static int rt2800pci_get_chipver(void) { return 0; } --+static int rt2800pci_get_chipeco(void) { return 0; } --+ -- static const struct ieee80211_ops rt2800pci_mac80211_ops = { -- .tx = rt2x00mac_tx, -- .wake_tx_queue = ieee80211_handle_wake_tx_queue, --@@ -329,6 +333,9 @@ static const struct rt2800_ops rt2800pci -- .drv_init_registers = rt2800mmio_init_registers, -- .drv_get_txwi = rt2800mmio_get_txwi, -- .drv_get_dma_done = rt2800mmio_get_dma_done, --+ .hw_get_chippkg = rt2800pci_get_chippkg, --+ .hw_get_chipver = rt2800pci_get_chipver, --+ .hw_get_chipeco = rt2800pci_get_chipeco, -- }; -- -- static const struct rt2x00lib_ops rt2800pci_rt2x00_ops = { ----- a/drivers/net/wireless/ralink/rt2x00/rt2800soc.c --+++ b/drivers/net/wireless/ralink/rt2x00/rt2800soc.c --@@ -27,6 +27,12 @@ -- #include "rt2800lib.h" -- #include "rt2800mmio.h" -- --+/* Needed to probe CHIP_VER register on MT7620 */ --+#ifdef CONFIG_SOC_MT7620 --+#include --+#include --+#endif --+ -- /* Allow hardware encryption to be disabled. */ -- static bool modparam_nohwcrypt; -- module_param_named(nohwcrypt, modparam_nohwcrypt, bool, 0444); --@@ -118,6 +124,27 @@ static int rt2800soc_write_firmware(stru -- return 0; -- } -- --+#ifdef CONFIG_SOC_MT7620 --+static int rt2800soc_get_chippkg(void) --+{ --+ return mt7620_get_pkg(); --+} --+ --+static int rt2800soc_get_chipver(void) --+{ --+ return mt7620_get_chipver(); --+} --+ --+static int rt2800soc_get_chipeco(void) --+{ --+ return mt7620_get_eco(); --+} --+#else --+static int rt2800soc_get_chippkg(void) { return 0; } --+static int rt2800soc_get_chipver(void) { return 0; } --+static int rt2800soc_get_chipeco(void) { return 0; } --+#endif --+ -- static const struct ieee80211_ops rt2800soc_mac80211_ops = { -- .tx = rt2x00mac_tx, -- .wake_tx_queue = ieee80211_handle_wake_tx_queue, --@@ -160,6 +187,9 @@ static const struct rt2800_ops rt2800soc -- .drv_init_registers = rt2800mmio_init_registers, -- .drv_get_txwi = rt2800mmio_get_txwi, -- .drv_get_dma_done = rt2800mmio_get_dma_done, --+ .hw_get_chippkg = rt2800soc_get_chippkg, --+ .hw_get_chipver = rt2800soc_get_chipver, --+ .hw_get_chipeco = rt2800soc_get_chipeco, -- }; -- -- static const struct rt2x00lib_ops rt2800soc_rt2x00_ops = { ----- a/drivers/net/wireless/ralink/rt2x00/rt2800usb.c --+++ b/drivers/net/wireless/ralink/rt2x00/rt2800usb.c --@@ -628,6 +628,10 @@ static int rt2800usb_probe_hw(struct rt2 -- return 0; -- } -- --+static int rt2800usb_get_chippkg(void) { return 0; } --+static int rt2800usb_get_chipver(void) { return 0; } --+static int rt2800usb_get_chipeco(void) { return 0; } --+ -- static const struct ieee80211_ops rt2800usb_mac80211_ops = { -- .tx = rt2x00mac_tx, -- .wake_tx_queue = ieee80211_handle_wake_tx_queue, --@@ -672,6 +676,9 @@ static const struct rt2800_ops rt2800usb -- .drv_init_registers = rt2800usb_init_registers, -- .drv_get_txwi = rt2800usb_get_txwi, -- .drv_get_dma_done = rt2800usb_get_dma_done, --+ .hw_get_chippkg = rt2800usb_get_chippkg, --+ .hw_get_chipver = rt2800usb_get_chipver, --+ .hw_get_chipeco = rt2800usb_get_chipeco, -- }; -- -- static const struct rt2x00lib_ops rt2800usb_rt2x00_ops = { -diff --git a/package/kernel/mac80211/patches/rt2x00/996-rt2x00-mt7620-differentiate-based-on-SoC-CHIP_VER.patch b/package/kernel/mac80211/patches/rt2x00/996-rt2x00-mt7620-differentiate-based-on-SoC-CHIP_VER.patch -deleted file mode 100644 -index dab6e05ffd..0000000000 ---- a/package/kernel/mac80211/patches/rt2x00/996-rt2x00-mt7620-differentiate-based-on-SoC-CHIP_VER.patch -+++ /dev/null -@@ -1,408 +0,0 @@ ----- a/drivers/net/wireless/ralink/rt2x00/rt2800.h --+++ b/drivers/net/wireless/ralink/rt2x00/rt2800.h --@@ -1044,6 +1044,11 @@ -- #define MIMO_PS_CFG_RX_STBY_POL FIELD32(0x00000010) -- #define MIMO_PS_CFG_RX_RX_STBY0 FIELD32(0x00000020) -- --+#define BB_PA_MODE_CFG0 0x1214 --+#define BB_PA_MODE_CFG1 0x1218 --+#define RF_PA_MODE_CFG0 0x121C --+#define RF_PA_MODE_CFG1 0x1220 --+ -- /* -- * EDCA_AC0_CFG: -- */ ----- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c --+++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c --@@ -3778,14 +3778,16 @@ static void rt2800_config_channel_rf7620 -- rt2x00_set_field8(&rfcsr, RFCSR19_K, rf->rf4); -- rt2800_rfcsr_write(rt2x00dev, 19, rfcsr); -- --- /* Default: XO=20MHz , SDM mode */ --- rfcsr = rt2800_rfcsr_read(rt2x00dev, 16); --- rt2x00_set_field8(&rfcsr, RFCSR16_SDM_MODE_MT7620, 0x80); --- rt2800_rfcsr_write(rt2x00dev, 16, rfcsr); --- --- rfcsr = rt2800_rfcsr_read(rt2x00dev, 21); --- rt2x00_set_field8(&rfcsr, RFCSR21_BIT8, 1); --- rt2800_rfcsr_write(rt2x00dev, 21, rfcsr); --+ if (rt2800_hw_get_chipver(rt2x00dev) > 1) { --+ /* Default: XO=20MHz , SDM mode */ --+ rfcsr = rt2800_rfcsr_read(rt2x00dev, 16); --+ rt2x00_set_field8(&rfcsr, RFCSR16_SDM_MODE_MT7620, 0x80); --+ rt2800_rfcsr_write(rt2x00dev, 16, rfcsr); --+ --+ rfcsr = rt2800_rfcsr_read(rt2x00dev, 21); --+ rt2x00_set_field8(&rfcsr, RFCSR21_BIT8, 1); --+ rt2800_rfcsr_write(rt2x00dev, 21, rfcsr); --+ } -- -- rfcsr = rt2800_rfcsr_read(rt2x00dev, 1); -- rt2x00_set_field8(&rfcsr, RFCSR1_TX2_EN_MT7620, --@@ -3819,18 +3821,23 @@ static void rt2800_config_channel_rf7620 -- rt2800_rfcsr_write_dccal(rt2x00dev, 59, 0x20); -- } -- --- if (conf_is_ht40(conf)) { --- rt2800_rfcsr_write_dccal(rt2x00dev, 58, 0x08); --- rt2800_rfcsr_write_dccal(rt2x00dev, 59, 0x08); --- } else { --- rt2800_rfcsr_write_dccal(rt2x00dev, 58, 0x28); --- rt2800_rfcsr_write_dccal(rt2x00dev, 59, 0x28); --+ if (rt2800_hw_get_chipver(rt2x00dev) > 1) { --+ if (conf_is_ht40(conf)) { --+ rt2800_rfcsr_write_dccal(rt2x00dev, 58, 0x08); --+ rt2800_rfcsr_write_dccal(rt2x00dev, 59, 0x08); --+ } else { --+ rt2800_rfcsr_write_dccal(rt2x00dev, 58, 0x28); --+ rt2800_rfcsr_write_dccal(rt2x00dev, 59, 0x28); --+ } -- } -- --- rfcsr = rt2800_rfcsr_read(rt2x00dev, 28); --- rt2x00_set_field8(&rfcsr, RFCSR28_CH11_HT40, --- conf_is_ht40(conf) && (rf->channel == 11)); --- rt2800_rfcsr_write(rt2x00dev, 28, rfcsr); --+ if (rt2800_hw_get_chipver(rt2x00dev) > 1 && --+ rt2800_hw_get_chipeco(rt2x00dev) == 2) { --+ rfcsr = rt2800_rfcsr_read(rt2x00dev, 28); --+ rt2x00_set_field8(&rfcsr, RFCSR28_CH11_HT40, --+ conf_is_ht40(conf) && (rf->channel == 11)); --+ rt2800_rfcsr_write(rt2x00dev, 28, rfcsr); --+ } -- -- if (!test_bit(DEVICE_STATE_SCANNING, &rt2x00dev->flags)) { -- if (conf_is_ht40(conf)) { --@@ -3929,25 +3936,29 @@ static void rt2800_config_alc(struct rt2 -- if (unlikely(rt2800_wait_bbp_rf_ready(rt2x00dev, MAC_STATUS_CFG_BBP_RF_BUSY))) -- rt2x00_warn(rt2x00dev, "RF busy while configuring ALC\n"); -- --- if (chan->center_freq > 2457) { --- bbp = rt2800_bbp_read(rt2x00dev, 30); --- bbp = 0x40; --- rt2800_bbp_write(rt2x00dev, 30, bbp); --- rt2800_rfcsr_write(rt2x00dev, 39, 0); --- if (rt2x00_has_cap_external_lna_bg(rt2x00dev)) --- rt2800_rfcsr_write(rt2x00dev, 42, 0xfb); --- else --- rt2800_rfcsr_write(rt2x00dev, 42, 0x7b); --- } else { --- bbp = rt2800_bbp_read(rt2x00dev, 30); --- bbp = 0x1f; --- rt2800_bbp_write(rt2x00dev, 30, bbp); --- rt2800_rfcsr_write(rt2x00dev, 39, 0x80); --- if (rt2x00_has_cap_external_lna_bg(rt2x00dev)) --- rt2800_rfcsr_write(rt2x00dev, 42, 0xdb); --- else --- rt2800_rfcsr_write(rt2x00dev, 42, 0x5b); --+ if (rt2800_hw_get_chipver(rt2x00dev) > 1 && --+ rt2800_hw_get_chipeco(rt2x00dev) >= 2) { --+ if (chan->center_freq > 2457) { --+ bbp = rt2800_bbp_read(rt2x00dev, 30); --+ bbp = 0x40; --+ rt2800_bbp_write(rt2x00dev, 30, bbp); --+ rt2800_rfcsr_write(rt2x00dev, 39, 0); --+ if (rt2x00_has_cap_external_lna_bg(rt2x00dev)) --+ rt2800_rfcsr_write(rt2x00dev, 42, 0xfb); --+ else --+ rt2800_rfcsr_write(rt2x00dev, 42, 0x7b); --+ } else { --+ bbp = rt2800_bbp_read(rt2x00dev, 30); --+ bbp = 0x1f; --+ rt2800_bbp_write(rt2x00dev, 30, bbp); --+ rt2800_rfcsr_write(rt2x00dev, 39, 0x80); --+ if (rt2x00_has_cap_external_lna_bg(rt2x00dev)) --+ rt2800_rfcsr_write(rt2x00dev, 42, 0xdb); --+ else --+ rt2800_rfcsr_write(rt2x00dev, 42, 0x5b); --+ } -- } --+ -- rt2800_register_write(rt2x00dev, MAC_SYS_CTRL, mac_sys_ctrl); -- -- rt2800_vco_calibration(rt2x00dev); --@@ -6011,18 +6022,33 @@ static int rt2800_init_registers(struct -- } else if (rt2x00_rt(rt2x00dev, RT5350)) { -- rt2800_register_write(rt2x00dev, TX_SW_CFG0, 0x00000404); -- } else if (rt2x00_rt(rt2x00dev, RT6352)) { --- rt2800_register_write(rt2x00dev, TX_SW_CFG0, 0x00000401); --- rt2800_register_write(rt2x00dev, TX_SW_CFG1, 0x000C0001); --- rt2800_register_write(rt2x00dev, TX_SW_CFG2, 0x00000000); --- rt2800_register_write(rt2x00dev, TX_ALC_VGA3, 0x00000000); --- rt2800_register_write(rt2x00dev, TX0_BB_GAIN_ATTEN, 0x0); --- rt2800_register_write(rt2x00dev, TX1_BB_GAIN_ATTEN, 0x0); --- rt2800_register_write(rt2x00dev, TX0_RF_GAIN_ATTEN, 0x6C6C666C); --- rt2800_register_write(rt2x00dev, TX1_RF_GAIN_ATTEN, 0x6C6C666C); --- rt2800_register_write(rt2x00dev, TX0_RF_GAIN_CORRECT, --- 0x3630363A); --- rt2800_register_write(rt2x00dev, TX1_RF_GAIN_CORRECT, --- 0x3630363A); --+ if (rt2800_hw_get_chipver(rt2x00dev) <= 1) { --+ rt2800_register_write(rt2x00dev, TX_ALC_VGA3, --+ 0x00000000); --+ rt2800_register_write(rt2x00dev, BB_PA_MODE_CFG0, --+ 0x000055FF); --+ rt2800_register_write(rt2x00dev, BB_PA_MODE_CFG1, --+ 0x00550055); --+ rt2800_register_write(rt2x00dev, RF_PA_MODE_CFG0, --+ 0x000055FF); --+ rt2800_register_write(rt2x00dev, RF_PA_MODE_CFG1, --+ 0x00550055); --+ } else { --+ rt2800_register_write(rt2x00dev, TX_SW_CFG0, 0x00000401); --+ rt2800_register_write(rt2x00dev, TX_SW_CFG1, 0x000C0001); --+ rt2800_register_write(rt2x00dev, TX_SW_CFG2, 0x00000000); --+ rt2800_register_write(rt2x00dev, TX_ALC_VGA3, 0x00000000); --+ rt2800_register_write(rt2x00dev, TX0_BB_GAIN_ATTEN, 0x0); --+ rt2800_register_write(rt2x00dev, TX1_BB_GAIN_ATTEN, 0x0); --+ rt2800_register_write(rt2x00dev, TX0_RF_GAIN_ATTEN, --+ 0x6C6C666C); --+ rt2800_register_write(rt2x00dev, TX1_RF_GAIN_ATTEN, --+ 0x6C6C666C); --+ rt2800_register_write(rt2x00dev, TX0_RF_GAIN_CORRECT, --+ 0x3630363A); --+ rt2800_register_write(rt2x00dev, TX1_RF_GAIN_CORRECT, --+ 0x3630363A); --+ } -- reg = rt2800_register_read(rt2x00dev, TX_ALC_CFG_1); -- rt2x00_set_field32(®, TX_ALC_CFG_1_ROS_BUSY_EN, 0); -- rt2800_register_write(rt2x00dev, TX_ALC_CFG_1, reg); --@@ -7127,14 +7153,16 @@ static void rt2800_init_bbp_6352(struct -- rt2800_bbp_write(rt2x00dev, 188, 0x00); -- rt2800_bbp_write(rt2x00dev, 189, 0x00); -- --- rt2800_bbp_write(rt2x00dev, 91, 0x06); --- rt2800_bbp_write(rt2x00dev, 92, 0x04); --- rt2800_bbp_write(rt2x00dev, 93, 0x54); --- rt2800_bbp_write(rt2x00dev, 99, 0x50); --- rt2800_bbp_write(rt2x00dev, 148, 0x84); --- rt2800_bbp_write(rt2x00dev, 167, 0x80); --- rt2800_bbp_write(rt2x00dev, 178, 0xFF); --- rt2800_bbp_write(rt2x00dev, 106, 0x13); --+ if (rt2800_hw_get_chipver(rt2x00dev) > 1) { --+ rt2800_bbp_write(rt2x00dev, 91, 0x06); --+ rt2800_bbp_write(rt2x00dev, 92, 0x04); --+ rt2800_bbp_write(rt2x00dev, 93, 0x54); --+ rt2800_bbp_write(rt2x00dev, 99, 0x50); --+ rt2800_bbp_write(rt2x00dev, 148, 0x84); --+ rt2800_bbp_write(rt2x00dev, 167, 0x80); --+ rt2800_bbp_write(rt2x00dev, 178, 0xFF); --+ rt2800_bbp_write(rt2x00dev, 106, 0x13); --+ } -- -- /* BBP for G band GLRT function (BBP_128 ~ BBP_221) */ -- rt2800_bbp_glrt_write(rt2x00dev, 0, 0x00); --@@ -10408,31 +10436,36 @@ static void rt2800_init_rfcsr_6352(struc -- rt2800_rfcsr_write(rt2x00dev, 42, 0x5B); -- rt2800_rfcsr_write(rt2x00dev, 43, 0x00); -- --- rt2800_rfcsr_write(rt2x00dev, 11, 0x21); --- if (rt2800_clk_is_20mhz(rt2x00dev)) --- rt2800_rfcsr_write(rt2x00dev, 13, 0x03); --- else --- rt2800_rfcsr_write(rt2x00dev, 13, 0x00); --- rt2800_rfcsr_write(rt2x00dev, 14, 0x7C); --- rt2800_rfcsr_write(rt2x00dev, 16, 0x80); --- rt2800_rfcsr_write(rt2x00dev, 17, 0x99); --- rt2800_rfcsr_write(rt2x00dev, 18, 0x99); --- rt2800_rfcsr_write(rt2x00dev, 19, 0x09); --- rt2800_rfcsr_write(rt2x00dev, 20, 0x50); --- rt2800_rfcsr_write(rt2x00dev, 21, 0xB0); --- rt2800_rfcsr_write(rt2x00dev, 22, 0x00); --- rt2800_rfcsr_write(rt2x00dev, 23, 0x06); --- rt2800_rfcsr_write(rt2x00dev, 24, 0x00); --- rt2800_rfcsr_write(rt2x00dev, 25, 0x00); --- rt2800_rfcsr_write(rt2x00dev, 26, 0x5D); --- rt2800_rfcsr_write(rt2x00dev, 27, 0x00); --- rt2800_rfcsr_write(rt2x00dev, 28, 0x61); --- rt2800_rfcsr_write(rt2x00dev, 29, 0xB5); --- rt2800_rfcsr_write(rt2x00dev, 43, 0x02); --- --- rt2800_rfcsr_write(rt2x00dev, 28, 0x62); --- rt2800_rfcsr_write(rt2x00dev, 29, 0xAD); --- rt2800_rfcsr_write(rt2x00dev, 39, 0x80); --+ if (rt2800_hw_get_chipver(rt2x00dev) > 1) { --+ rt2800_rfcsr_write(rt2x00dev, 11, 0x21); --+ if (rt2800_clk_is_20mhz(rt2x00dev)) --+ rt2800_rfcsr_write(rt2x00dev, 13, 0x03); --+ else --+ rt2800_rfcsr_write(rt2x00dev, 13, 0x00); --+ rt2800_rfcsr_write(rt2x00dev, 14, 0x7C); --+ rt2800_rfcsr_write(rt2x00dev, 16, 0x80); --+ rt2800_rfcsr_write(rt2x00dev, 17, 0x99); --+ rt2800_rfcsr_write(rt2x00dev, 18, 0x99); --+ rt2800_rfcsr_write(rt2x00dev, 19, 0x09); --+ rt2800_rfcsr_write(rt2x00dev, 20, 0x50); --+ rt2800_rfcsr_write(rt2x00dev, 21, 0xB0); --+ rt2800_rfcsr_write(rt2x00dev, 22, 0x00); --+ rt2800_rfcsr_write(rt2x00dev, 23, 0x06); --+ rt2800_rfcsr_write(rt2x00dev, 24, 0x00); --+ rt2800_rfcsr_write(rt2x00dev, 25, 0x00); --+ rt2800_rfcsr_write(rt2x00dev, 26, 0x5D); --+ rt2800_rfcsr_write(rt2x00dev, 27, 0x00); --+ rt2800_rfcsr_write(rt2x00dev, 28, 0x61); --+ rt2800_rfcsr_write(rt2x00dev, 29, 0xB5); --+ rt2800_rfcsr_write(rt2x00dev, 43, 0x02); --+ } --+ --+ if (rt2800_hw_get_chipver(rt2x00dev) > 1 && --+ rt2800_hw_get_chipeco(rt2x00dev) >= 2) { --+ rt2800_rfcsr_write(rt2x00dev, 28, 0x62); --+ rt2800_rfcsr_write(rt2x00dev, 29, 0xAD); --+ rt2800_rfcsr_write(rt2x00dev, 39, 0x80); --+ } -- -- /* Initialize RF channel register to default value */ -- rt2800_rfcsr_write_chanreg(rt2x00dev, 0, 0x03); --@@ -10498,63 +10531,71 @@ static void rt2800_init_rfcsr_6352(struc -- -- rt2800_rfcsr_write_bank(rt2x00dev, 6, 45, 0xC5); -- --- rt2800_rfcsr_write_chanreg(rt2x00dev, 9, 0x47); --- rt2800_rfcsr_write_chanreg(rt2x00dev, 10, 0x71); --- rt2800_rfcsr_write_chanreg(rt2x00dev, 11, 0x33); --- rt2800_rfcsr_write_chanreg(rt2x00dev, 14, 0x0E); --- rt2800_rfcsr_write_chanreg(rt2x00dev, 17, 0x23); --- rt2800_rfcsr_write_chanreg(rt2x00dev, 19, 0xA4); --- rt2800_rfcsr_write_chanreg(rt2x00dev, 20, 0x02); --- rt2800_rfcsr_write_chanreg(rt2x00dev, 21, 0x12); --- rt2800_rfcsr_write_chanreg(rt2x00dev, 28, 0x1C); --- rt2800_rfcsr_write_chanreg(rt2x00dev, 29, 0xEB); --- rt2800_rfcsr_write_chanreg(rt2x00dev, 32, 0x7D); --- rt2800_rfcsr_write_chanreg(rt2x00dev, 34, 0xD6); --- rt2800_rfcsr_write_chanreg(rt2x00dev, 36, 0x08); --- rt2800_rfcsr_write_chanreg(rt2x00dev, 38, 0xB4); --- rt2800_rfcsr_write_chanreg(rt2x00dev, 43, 0xD3); --- rt2800_rfcsr_write_chanreg(rt2x00dev, 44, 0xB3); --- rt2800_rfcsr_write_chanreg(rt2x00dev, 45, 0xD5); --- rt2800_rfcsr_write_chanreg(rt2x00dev, 46, 0x27); --- rt2800_rfcsr_write_bank(rt2x00dev, 4, 47, 0x67); --- rt2800_rfcsr_write_bank(rt2x00dev, 6, 47, 0x69); --- rt2800_rfcsr_write_chanreg(rt2x00dev, 48, 0xFF); --- rt2800_rfcsr_write_bank(rt2x00dev, 4, 54, 0x27); --- rt2800_rfcsr_write_bank(rt2x00dev, 6, 54, 0x20); --- rt2800_rfcsr_write_chanreg(rt2x00dev, 55, 0x66); --- rt2800_rfcsr_write_chanreg(rt2x00dev, 56, 0xFF); --- rt2800_rfcsr_write_chanreg(rt2x00dev, 57, 0x1C); --- rt2800_rfcsr_write_chanreg(rt2x00dev, 58, 0x20); --- rt2800_rfcsr_write_chanreg(rt2x00dev, 59, 0x6B); --- rt2800_rfcsr_write_chanreg(rt2x00dev, 60, 0xF7); --- rt2800_rfcsr_write_chanreg(rt2x00dev, 61, 0x09); --- --- rt2800_rfcsr_write_chanreg(rt2x00dev, 10, 0x51); --- rt2800_rfcsr_write_chanreg(rt2x00dev, 14, 0x06); --- rt2800_rfcsr_write_chanreg(rt2x00dev, 19, 0xA7); --- rt2800_rfcsr_write_chanreg(rt2x00dev, 28, 0x2C); --- rt2800_rfcsr_write_chanreg(rt2x00dev, 55, 0x64); --- rt2800_rfcsr_write_chanreg(rt2x00dev, 8, 0x51); --- rt2800_rfcsr_write_chanreg(rt2x00dev, 9, 0x36); --- rt2800_rfcsr_write_chanreg(rt2x00dev, 11, 0x53); --- rt2800_rfcsr_write_chanreg(rt2x00dev, 14, 0x16); --- --- rt2800_rfcsr_write_chanreg(rt2x00dev, 47, 0x6C); --- rt2800_rfcsr_write_chanreg(rt2x00dev, 48, 0xFC); --- rt2800_rfcsr_write_chanreg(rt2x00dev, 49, 0x1F); --- rt2800_rfcsr_write_chanreg(rt2x00dev, 54, 0x27); --- rt2800_rfcsr_write_chanreg(rt2x00dev, 55, 0x66); --- rt2800_rfcsr_write_chanreg(rt2x00dev, 59, 0x6B); --- --- /* Initialize RF channel register for DRQFN */ --- rt2800_rfcsr_write_chanreg(rt2x00dev, 43, 0xD3); --- rt2800_rfcsr_write_chanreg(rt2x00dev, 44, 0xE3); --- rt2800_rfcsr_write_chanreg(rt2x00dev, 45, 0xE5); --- rt2800_rfcsr_write_chanreg(rt2x00dev, 47, 0x28); --- rt2800_rfcsr_write_chanreg(rt2x00dev, 55, 0x68); --- rt2800_rfcsr_write_chanreg(rt2x00dev, 56, 0xF7); --- rt2800_rfcsr_write_chanreg(rt2x00dev, 58, 0x02); --- rt2800_rfcsr_write_chanreg(rt2x00dev, 60, 0xC7); --+ if (rt2800_hw_get_chipver(rt2x00dev) > 1) { --+ rt2800_rfcsr_write_chanreg(rt2x00dev, 9, 0x47); --+ rt2800_rfcsr_write_chanreg(rt2x00dev, 10, 0x71); --+ rt2800_rfcsr_write_chanreg(rt2x00dev, 11, 0x33); --+ rt2800_rfcsr_write_chanreg(rt2x00dev, 14, 0x0E); --+ rt2800_rfcsr_write_chanreg(rt2x00dev, 17, 0x23); --+ rt2800_rfcsr_write_chanreg(rt2x00dev, 19, 0xA4); --+ rt2800_rfcsr_write_chanreg(rt2x00dev, 20, 0x02); --+ rt2800_rfcsr_write_chanreg(rt2x00dev, 21, 0x12); --+ rt2800_rfcsr_write_chanreg(rt2x00dev, 28, 0x1C); --+ rt2800_rfcsr_write_chanreg(rt2x00dev, 29, 0xEB); --+ rt2800_rfcsr_write_chanreg(rt2x00dev, 32, 0x7D); --+ rt2800_rfcsr_write_chanreg(rt2x00dev, 34, 0xD6); --+ rt2800_rfcsr_write_chanreg(rt2x00dev, 36, 0x08); --+ rt2800_rfcsr_write_chanreg(rt2x00dev, 38, 0xB4); --+ rt2800_rfcsr_write_chanreg(rt2x00dev, 43, 0xD3); --+ rt2800_rfcsr_write_chanreg(rt2x00dev, 44, 0xB3); --+ rt2800_rfcsr_write_chanreg(rt2x00dev, 45, 0xD5); --+ rt2800_rfcsr_write_chanreg(rt2x00dev, 46, 0x27); --+ rt2800_rfcsr_write_bank(rt2x00dev, 4, 47, 0x67); --+ rt2800_rfcsr_write_bank(rt2x00dev, 6, 47, 0x69); --+ rt2800_rfcsr_write_chanreg(rt2x00dev, 48, 0xFF); --+ rt2800_rfcsr_write_bank(rt2x00dev, 4, 54, 0x27); --+ rt2800_rfcsr_write_bank(rt2x00dev, 6, 54, 0x20); --+ rt2800_rfcsr_write_chanreg(rt2x00dev, 55, 0x66); --+ rt2800_rfcsr_write_chanreg(rt2x00dev, 56, 0xFF); --+ rt2800_rfcsr_write_chanreg(rt2x00dev, 57, 0x1C); --+ rt2800_rfcsr_write_chanreg(rt2x00dev, 58, 0x20); --+ rt2800_rfcsr_write_chanreg(rt2x00dev, 59, 0x6B); --+ rt2800_rfcsr_write_chanreg(rt2x00dev, 60, 0xF7); --+ rt2800_rfcsr_write_chanreg(rt2x00dev, 61, 0x09); --+ } --+ --+ if (rt2800_hw_get_chipver(rt2x00dev) > 1 && --+ rt2800_hw_get_chipeco(rt2x00dev) >= 2) { --+ rt2800_rfcsr_write_chanreg(rt2x00dev, 10, 0x51); --+ rt2800_rfcsr_write_chanreg(rt2x00dev, 14, 0x06); --+ rt2800_rfcsr_write_chanreg(rt2x00dev, 19, 0xA7); --+ rt2800_rfcsr_write_chanreg(rt2x00dev, 28, 0x2C); --+ rt2800_rfcsr_write_chanreg(rt2x00dev, 55, 0x64); --+ rt2800_rfcsr_write_chanreg(rt2x00dev, 8, 0x51); --+ rt2800_rfcsr_write_chanreg(rt2x00dev, 9, 0x36); --+ rt2800_rfcsr_write_chanreg(rt2x00dev, 11, 0x53); --+ rt2800_rfcsr_write_chanreg(rt2x00dev, 14, 0x16); --+ --+ rt2800_rfcsr_write_chanreg(rt2x00dev, 47, 0x6C); --+ rt2800_rfcsr_write_chanreg(rt2x00dev, 48, 0xFC); --+ rt2800_rfcsr_write_chanreg(rt2x00dev, 49, 0x1F); --+ rt2800_rfcsr_write_chanreg(rt2x00dev, 54, 0x27); --+ rt2800_rfcsr_write_chanreg(rt2x00dev, 55, 0x66); --+ rt2800_rfcsr_write_chanreg(rt2x00dev, 59, 0x6B); --+ } --+ --+ if (rt2800_hw_get_chippkg(rt2x00dev) == 0 && --+ rt2800_hw_get_chipver(rt2x00dev) == 1) { --+ /* Initialize RF channel register for DRQFN */ --+ rt2800_rfcsr_write_chanreg(rt2x00dev, 43, 0xD3); --+ rt2800_rfcsr_write_chanreg(rt2x00dev, 44, 0xE3); --+ rt2800_rfcsr_write_chanreg(rt2x00dev, 45, 0xE5); --+ rt2800_rfcsr_write_chanreg(rt2x00dev, 47, 0x28); --+ rt2800_rfcsr_write_chanreg(rt2x00dev, 55, 0x68); --+ rt2800_rfcsr_write_chanreg(rt2x00dev, 56, 0xF7); --+ rt2800_rfcsr_write_chanreg(rt2x00dev, 58, 0x02); --+ rt2800_rfcsr_write_chanreg(rt2x00dev, 60, 0xC7); --+ } -- -- /* Initialize RF DC calibration register to default value */ -- rt2800_rfcsr_write_dccal(rt2x00dev, 0, 0x47); --@@ -10617,12 +10658,17 @@ static void rt2800_init_rfcsr_6352(struc -- rt2800_rfcsr_write_dccal(rt2x00dev, 62, 0x00); -- rt2800_rfcsr_write_dccal(rt2x00dev, 63, 0x00); -- --- rt2800_rfcsr_write_dccal(rt2x00dev, 3, 0x08); --- rt2800_rfcsr_write_dccal(rt2x00dev, 4, 0x04); --- rt2800_rfcsr_write_dccal(rt2x00dev, 5, 0x20); --+ if (rt2800_hw_get_chipver(rt2x00dev) > 1) { --+ rt2800_rfcsr_write_dccal(rt2x00dev, 3, 0x08); --+ rt2800_rfcsr_write_dccal(rt2x00dev, 4, 0x04); --+ rt2800_rfcsr_write_dccal(rt2x00dev, 5, 0x20); --+ } -- --- rt2800_rfcsr_write_dccal(rt2x00dev, 5, 0x00); --- rt2800_rfcsr_write_dccal(rt2x00dev, 17, 0x7C); --+ if (rt2800_hw_get_chipver(rt2x00dev) > 1 && --+ rt2800_hw_get_chipeco(rt2x00dev) >= 2) { --+ rt2800_rfcsr_write_dccal(rt2x00dev, 5, 0x00); --+ rt2800_rfcsr_write_dccal(rt2x00dev, 17, 0x7C); --+ } -- -- rt6352_enable_pa_pin(rt2x00dev, 0); -- rt2800_r_calibration(rt2x00dev); -diff --git a/package/kernel/mac80211/patches/subsys/110-mac80211_keep_keys_on_stop_ap.patch b/package/kernel/mac80211/patches/subsys/110-mac80211_keep_keys_on_stop_ap.patch -deleted file mode 100644 -index 4d4a2a8f5e..0000000000 ---- a/package/kernel/mac80211/patches/subsys/110-mac80211_keep_keys_on_stop_ap.patch -+++ /dev/null -@@ -1,19 +0,0 @@ --From: Felix Fietkau --Date: Mon, 27 Oct 2014 00:00:00 +0100 --Subject: [PATCH] mac80211: preseve AP mode keys across STA reconnect -- --Used for AP+STA support in OpenWrt - preserve AP mode keys across STA reconnect ----- -- net/mac80211/cfg.c | 1 - -- 1 file changed, 1 deletion(-) -- ----- a/net/mac80211/cfg.c --+++ b/net/mac80211/cfg.c --@@ -1519,7 +1519,6 @@ static int ieee80211_stop_ap(struct wiph -- link_conf->bssid_indicator = 0; -- -- __sta_info_flush(sdata, true); --- ieee80211_free_keys(sdata, true); -- -- link_conf->enable_beacon = false; -- sdata->beacon_rate_set = false; -diff --git a/package/kernel/mac80211/patches/subsys/120-cfg80211_allow_perm_addr_change.patch b/package/kernel/mac80211/patches/subsys/120-cfg80211_allow_perm_addr_change.patch -deleted file mode 100644 -index f315ae5ca2..0000000000 ---- a/package/kernel/mac80211/patches/subsys/120-cfg80211_allow_perm_addr_change.patch -+++ /dev/null -@@ -1,52 +0,0 @@ --From: Felix Fietkau --Date: Thu, 11 Dec 2014 00:00:00 +0100 --Subject: [PATCH] cfg80211: add support for changing the device mac address via -- sysfs -- ----- -- net/wireless/sysfs.c | 27 ++++++++++++++++++++++----- -- 1 file changed, 22 insertions(+), 5 deletions(-) -- ----- a/net/wireless/sysfs.c --+++ b/net/wireless/sysfs.c --@@ -24,18 +24,35 @@ static inline struct cfg80211_registered -- return container_of(dev, struct cfg80211_registered_device, wiphy.dev); -- } -- ---#define SHOW_FMT(name, fmt, member) \ --+#define SHOW_FMT(name, fmt, member, mode) \ -- static ssize_t name ## _show(struct device *dev, \ -- struct device_attribute *attr, \ -- char *buf) \ -- { \ -- return sprintf(buf, fmt "\n", dev_to_rdev(dev)->member); \ -- } \ ---static DEVICE_ATTR_RO(name) --+static DEVICE_ATTR_##mode(name) -- ---SHOW_FMT(index, "%d", wiphy_idx); ---SHOW_FMT(macaddress, "%pM", wiphy.perm_addr); ---SHOW_FMT(address_mask, "%pM", wiphy.addr_mask); --+static ssize_t macaddress_store(struct device *dev, --+ struct device_attribute *attr, --+ const char *buf, size_t len) --+{ --+ u8 mac[ETH_ALEN]; --+ --+ if (!mac_pton(buf, mac)) --+ return -EINVAL; --+ --+ if (buf[3 * ETH_ALEN - 1] && buf[3 * ETH_ALEN - 1] != '\n') --+ return -EINVAL; --+ --+ memcpy(dev_to_rdev(dev)->wiphy.perm_addr, mac, ETH_ALEN); --+ --+ return strnlen(buf, len); --+} --+ --+SHOW_FMT(index, "%d", wiphy_idx, RO); --+SHOW_FMT(macaddress, "%pM", wiphy.perm_addr, RW); --+SHOW_FMT(address_mask, "%pM", wiphy.addr_mask, RO); -- -- static ssize_t name_show(struct device *dev, -- struct device_attribute *attr, -diff --git a/package/kernel/mac80211/patches/subsys/210-ap_scan.patch b/package/kernel/mac80211/patches/subsys/210-ap_scan.patch -deleted file mode 100644 -index 10b842d9af..0000000000 ---- a/package/kernel/mac80211/patches/subsys/210-ap_scan.patch -+++ /dev/null -@@ -1,19 +0,0 @@ --From: Felix Fietkau --Date: Wed, 3 Oct 2012 00:00:00 +0200 --Subject: [PATCH] mac80211: allow scans in access point mode (for site survey) -- ----- -- net/mac80211/cfg.c | 2 +- -- 1 file changed, 1 insertion(+), 1 deletion(-) -- ----- a/net/mac80211/cfg.c --+++ b/net/mac80211/cfg.c --@@ -2727,6 +2727,8 @@ static int ieee80211_scan(struct wiphy * -- */ -- fallthrough; -- case NL80211_IFTYPE_AP: --+ /* skip check */ --+ break; -- /* -- * If the scan has been forced (and the driver supports -- * forcing), don't care about being beaconing already. -diff --git a/package/kernel/mac80211/patches/subsys/301-mac80211-sta-randomize-BA-session-dialog-token-alloc.patch b/package/kernel/mac80211/patches/subsys/301-mac80211-sta-randomize-BA-session-dialog-token-alloc.patch -deleted file mode 100644 -index 63b2177471..0000000000 ---- a/package/kernel/mac80211/patches/subsys/301-mac80211-sta-randomize-BA-session-dialog-token-alloc.patch -+++ /dev/null -@@ -1,38 +0,0 @@ --From b478e06a16a8baa00c5ecc87c1d636981f2206d5 Mon Sep 17 00:00:00 2001 --From: Johannes Berg --Date: Tue, 29 Oct 2019 10:25:25 +0100 --Subject: [PATCH] mac80211: sta: randomize BA session dialog token allocator -- --We currently always start the dialog token generator at zero, --so the first dialog token we use is always 1. This would be --OK if we had a perfect guarantee that we always do a proper --deauth/re-auth handshake, but in IBSS mode this doesn't always --happen properly. -- --To make problems with block ack (aggregation) sessions getting --stuck less likely, randomize the dialog token so if we start a --new session but the peer still has old state for us, it can --better detect this. -- --This is really just a workaround to make things a bit more --robust than they are now - a better fix would be to do a full --authentication handshake in IBSS mode upon having discovered a --new station, and on the receiver resetting the state (removing --and re-adding the station) on receiving the authentication --packet. -- --Signed-off-by: Johannes Berg ----- -- net/mac80211/sta_info.c | 1 + -- 1 file changed, 1 insertion(+) -- ----- a/net/mac80211/sta_info.c --+++ b/net/mac80211/sta_info.c --@@ -554,6 +554,7 @@ __sta_info_alloc(struct ieee80211_sub_if -- INIT_WORK(&sta->drv_deliver_wk, sta_deliver_ps_frames); -- INIT_WORK(&sta->ampdu_mlme.work, ieee80211_ba_session_work); -- mutex_init(&sta->ampdu_mlme.mtx); --+ sta->ampdu_mlme.dialog_token_allocator = prandom_u32_max(U8_MAX); -- #ifdef CPTCFG_MAC80211_MESH -- if (ieee80211_vif_is_mesh(&sdata->vif)) { -- sta->mesh = kzalloc(sizeof(*sta->mesh), gfp); -diff --git a/package/kernel/mac80211/patches/subsys/302-mac80211-minstrel_ht-fix-MINSTREL_FRAC-macro.patch b/package/kernel/mac80211/patches/subsys/302-mac80211-minstrel_ht-fix-MINSTREL_FRAC-macro.patch -deleted file mode 100644 -index 0d475b7329..0000000000 ---- a/package/kernel/mac80211/patches/subsys/302-mac80211-minstrel_ht-fix-MINSTREL_FRAC-macro.patch -+++ /dev/null -@@ -1,21 +0,0 @@ --From: Felix Fietkau --Date: Wed, 28 Apr 2021 21:03:13 +0200 --Subject: [PATCH] mac80211: minstrel_ht: fix MINSTREL_FRAC macro -- --Add missing braces to avoid issues with e.g. using additions in the --div expression -- --Signed-off-by: Felix Fietkau ----- -- ----- a/net/mac80211/rc80211_minstrel_ht.h --+++ b/net/mac80211/rc80211_minstrel_ht.h --@@ -14,7 +14,7 @@ -- -- /* scaled fraction values */ -- #define MINSTREL_SCALE 12 ---#define MINSTREL_FRAC(val, div) (((val) << MINSTREL_SCALE) / div) --+#define MINSTREL_FRAC(val, div) (((val) << MINSTREL_SCALE) / (div)) -- #define MINSTREL_TRUNC(val) ((val) >> MINSTREL_SCALE) -- -- #define EWMA_LEVEL 96 /* ewma weighting factor [/EWMA_DIV] */ -diff --git a/package/kernel/mac80211/patches/subsys/303-mac80211-minstrel_ht-reduce-fluctuations-in-rate-pro.patch b/package/kernel/mac80211/patches/subsys/303-mac80211-minstrel_ht-reduce-fluctuations-in-rate-pro.patch -deleted file mode 100644 -index f26477e811..0000000000 ---- a/package/kernel/mac80211/patches/subsys/303-mac80211-minstrel_ht-reduce-fluctuations-in-rate-pro.patch -+++ /dev/null -@@ -1,30 +0,0 @@ --From: Felix Fietkau --Date: Sat, 6 Feb 2021 16:08:01 +0100 --Subject: [PATCH] mac80211: minstrel_ht: reduce fluctuations in rate -- probability stats -- --In some scenarios when there is a lot of fluctuation in packet error rates, --rate switching can be amplified when the statistics get skewed by time slots --with very few tries. --Make the input data to the moving average more smooth by adding the --success/attempts count from the last stats window as well. This has the --advantage of smoothing the data without introducing any extra lag to sampling --rates. --This significantly improves rate stability on a strong test link subjected to --periodic noise bursts generated with a SDR -- --Signed-off-by: Felix Fietkau ----- -- ----- a/net/mac80211/rc80211_minstrel_ht.c --+++ b/net/mac80211/rc80211_minstrel_ht.c --@@ -769,7 +769,8 @@ minstrel_ht_calc_rate_stats(struct minst -- unsigned int cur_prob; -- -- if (unlikely(mrs->attempts > 0)) { --- cur_prob = MINSTREL_FRAC(mrs->success, mrs->attempts); --+ cur_prob = MINSTREL_FRAC(mrs->success + mrs->last_success, --+ mrs->attempts + mrs->last_attempts); -- minstrel_filter_avg_add(&mrs->prob_avg, -- &mrs->prob_avg_1, cur_prob); -- mrs->att_hist += mrs->attempts; -diff --git a/package/kernel/mac80211/patches/subsys/304-mac80211-minstrel_ht-rework-rate-downgrade-code-and-.patch b/package/kernel/mac80211/patches/subsys/304-mac80211-minstrel_ht-rework-rate-downgrade-code-and-.patch -deleted file mode 100644 -index 9b3cc3a664..0000000000 ---- a/package/kernel/mac80211/patches/subsys/304-mac80211-minstrel_ht-rework-rate-downgrade-code-and-.patch -+++ /dev/null -@@ -1,151 +0,0 @@ --From: Felix Fietkau --Date: Sat, 6 Feb 2021 16:33:14 +0100 --Subject: [PATCH] mac80211: minstrel_ht: rework rate downgrade code and -- max_prob rate selection -- --The current fallback code for fast rate switching on potentially failing rates --is triggering too often if there is some strong noise on the channel. This can --lead to wild fluctuations in the rate selection. --Additionally, switching down to max_prob_rate can create a significant gap down --in throughput, especially when using only 2 spatial streams, because max_prob_rate --is limited to using fewer streams than the max_tp rates. --In order to improve throughput without reducing reliability too much, use the --rate downgrade code for the max_prob_rate only, and allow the non-downgraded --max_prob_rate to use as many spatial streams as the max_tp rates -- --Signed-off-by: Felix Fietkau ----- -- ----- a/net/mac80211/rc80211_minstrel_ht.c --+++ b/net/mac80211/rc80211_minstrel_ht.c --@@ -580,6 +580,14 @@ minstrel_ht_set_best_prob_rate(struct mi -- int cur_tp_avg, cur_group, cur_idx; -- int max_gpr_group, max_gpr_idx; -- int max_gpr_tp_avg, max_gpr_prob; --+ int min_dur; --+ --+ min_dur = max(minstrel_get_duration(mi->max_tp_rate[0]), --+ minstrel_get_duration(mi->max_tp_rate[1])); --+ --+ /* make the rate at least 18% slower than max tp rates */ --+ if (minstrel_get_duration(index) <= min_dur * 19 / 16) --+ return; -- -- cur_group = MI_RATE_GROUP(index); -- cur_idx = MI_RATE_IDX(index); --@@ -601,11 +609,6 @@ minstrel_ht_set_best_prob_rate(struct mi -- !minstrel_ht_is_legacy_group(max_tp_group)) -- return; -- --- /* skip rates faster than max tp rate with lower prob */ --- if (minstrel_get_duration(mi->max_tp_rate[0]) > minstrel_get_duration(index) && --- mrs->prob_avg < max_tp_prob) --- return; --- -- max_gpr_group = MI_RATE_GROUP(mg->max_group_prob_rate); -- max_gpr_idx = MI_RATE_IDX(mg->max_group_prob_rate); -- max_gpr_prob = mi->groups[max_gpr_group].rates[max_gpr_idx].prob_avg; --@@ -663,40 +666,6 @@ minstrel_ht_assign_best_tp_rates(struct -- -- } -- ---/* --- * Try to increase robustness of max_prob rate by decrease number of --- * streams if possible. --- */ ---static inline void ---minstrel_ht_prob_rate_reduce_streams(struct minstrel_ht_sta *mi) ---{ --- struct minstrel_mcs_group_data *mg; --- int tmp_max_streams, group, tmp_idx, tmp_prob; --- int tmp_tp = 0; --- --- if (!mi->sta->deflink.ht_cap.ht_supported) --- return; --- --- group = MI_RATE_GROUP(mi->max_tp_rate[0]); --- tmp_max_streams = minstrel_mcs_groups[group].streams; --- for (group = 0; group < ARRAY_SIZE(minstrel_mcs_groups); group++) { --- mg = &mi->groups[group]; --- if (!mi->supported[group] || group == MINSTREL_CCK_GROUP) --- continue; --- --- tmp_idx = MI_RATE_IDX(mg->max_group_prob_rate); --- tmp_prob = mi->groups[group].rates[tmp_idx].prob_avg; --- --- if (tmp_tp < minstrel_ht_get_tp_avg(mi, group, tmp_idx, tmp_prob) && --- (minstrel_mcs_groups[group].streams < tmp_max_streams)) { --- mi->max_prob_rate = mg->max_group_prob_rate; --- tmp_tp = minstrel_ht_get_tp_avg(mi, group, --- tmp_idx, --- tmp_prob); --- } --- } ---} --- -- static u16 -- __minstrel_ht_get_sample_rate(struct minstrel_ht_sta *mi, -- enum minstrel_sample_type type) --@@ -1176,8 +1145,6 @@ minstrel_ht_update_stats(struct minstrel -- -- mi->max_prob_rate = tmp_max_prob_rate; -- --- /* Try to increase robustness of max_prob_rate*/ --- minstrel_ht_prob_rate_reduce_streams(mi); -- minstrel_ht_refill_sample_rates(mi); -- -- #ifdef CPTCFG_MAC80211_DEBUGFS --@@ -1256,7 +1223,7 @@ minstrel_ht_ri_txstat_valid(struct minst -- } -- -- static void ---minstrel_downgrade_rate(struct minstrel_ht_sta *mi, u16 *idx, bool primary) --+minstrel_downgrade_prob_rate(struct minstrel_ht_sta *mi, u16 *idx) -- { -- int group, orig_group; -- --@@ -1271,11 +1238,7 @@ minstrel_downgrade_rate(struct minstrel_ -- minstrel_mcs_groups[orig_group].streams) -- continue; -- --- if (primary) --- *idx = mi->groups[group].max_group_tp_rate[0]; --- else --- *idx = mi->groups[group].max_group_tp_rate[1]; --- break; --+ *idx = mi->groups[group].max_group_prob_rate; -- } -- } -- --@@ -1286,7 +1249,7 @@ minstrel_ht_tx_status(void *priv, struct -- struct ieee80211_tx_info *info = st->info; -- struct minstrel_ht_sta *mi = priv_sta; -- struct ieee80211_tx_rate *ar = info->status.rates; --- struct minstrel_rate_stats *rate, *rate2; --+ struct minstrel_rate_stats *rate; -- struct minstrel_priv *mp = priv; -- u32 update_interval = mp->update_interval; -- bool last, update = false; --@@ -1354,18 +1317,13 @@ minstrel_ht_tx_status(void *priv, struct -- /* -- * check for sudden death of spatial multiplexing, -- * downgrade to a lower number of streams if necessary. --+ * only do this for the max_prob_rate to prevent spurious --+ * rate fluctuations when the link changes suddenly -- */ --- rate = minstrel_get_ratestats(mi, mi->max_tp_rate[0]); --+ rate = minstrel_get_ratestats(mi, mi->max_prob_rate); -- if (rate->attempts > 30 && -- rate->success < rate->attempts / 4) { --- minstrel_downgrade_rate(mi, &mi->max_tp_rate[0], true); --- update = true; --- } --- --- rate2 = minstrel_get_ratestats(mi, mi->max_tp_rate[1]); --- if (rate2->attempts > 30 && --- rate2->success < rate2->attempts / 4) { --- minstrel_downgrade_rate(mi, &mi->max_tp_rate[1], false); --+ minstrel_downgrade_prob_rate(mi, &mi->max_prob_rate); -- update = true; -- } -- } -diff --git a/package/kernel/mac80211/patches/subsys/305-mac80211-increase-quantum-for-airtime-scheduler.patch b/package/kernel/mac80211/patches/subsys/305-mac80211-increase-quantum-for-airtime-scheduler.patch -deleted file mode 100644 -index 0ac972955f..0000000000 ---- a/package/kernel/mac80211/patches/subsys/305-mac80211-increase-quantum-for-airtime-scheduler.patch -+++ /dev/null -@@ -1,53 +0,0 @@ --From: Felix Fietkau --Date: Sun, 26 Jun 2022 11:43:25 +0200 --Subject: [PATCH] mac80211: increase quantum for airtime scheduler -- --Given the typical AQL budget and queue length, a quantum of 256 with the --default station weight often requires iterating over all queues frequently, --until one of them becomes eligible. --Improve performance by using 8 times station weight as scheduler quantum -- --Signed-off-by: Felix Fietkau ----- -- ----- a/net/mac80211/ieee80211_i.h --+++ b/net/mac80211/ieee80211_i.h --@@ -90,6 +90,8 @@ extern const u8 ieee80211_ac_to_qos_mask -- */ -- #define AIRTIME_ACTIVE_DURATION (HZ / 10) -- --+#define AIRTIME_QUANTUM_SHIFT 3 --+ -- struct ieee80211_bss { -- u32 device_ts_beacon, device_ts_presp; -- ----- a/net/mac80211/tx.c --+++ b/net/mac80211/tx.c --@@ -3984,7 +3984,7 @@ struct ieee80211_txq *ieee80211_next_txq -- -- if (deficit < 0) -- sta->airtime[txqi->txq.ac].deficit += --- sta->airtime_weight; --+ sta->airtime_weight << AIRTIME_QUANTUM_SHIFT; -- -- if (deficit < 0 || !aql_check) { -- list_move_tail(&txqi->schedule_order, --@@ -4127,7 +4127,8 @@ bool ieee80211_txq_may_transmit(struct i -- } -- sta = container_of(iter->txq.sta, struct sta_info, sta); -- if (ieee80211_sta_deficit(sta, ac) < 0) --- sta->airtime[ac].deficit += sta->airtime_weight; --+ sta->airtime[ac].deficit += sta->airtime_weight << --+ AIRTIME_QUANTUM_SHIFT; -- list_move_tail(&iter->schedule_order, &local->active_txqs[ac]); -- } -- --@@ -4135,7 +4136,7 @@ bool ieee80211_txq_may_transmit(struct i -- if (sta->airtime[ac].deficit >= 0) -- goto out; -- --- sta->airtime[ac].deficit += sta->airtime_weight; --+ sta->airtime[ac].deficit += sta->airtime_weight << AIRTIME_QUANTUM_SHIFT; -- list_move_tail(&txqi->schedule_order, &local->active_txqs[ac]); -- spin_unlock_bh(&local->active_txq_lock[ac]); -- -diff --git a/package/kernel/mac80211/patches/subsys/306-01-v6.2-wifi-mac80211-add-internal-handler-for-wake_tx_queue.patch b/package/kernel/mac80211/patches/subsys/306-01-v6.2-wifi-mac80211-add-internal-handler-for-wake_tx_queue.patch -deleted file mode 100644 -index d14ba05e69..0000000000 ---- a/package/kernel/mac80211/patches/subsys/306-01-v6.2-wifi-mac80211-add-internal-handler-for-wake_tx_queue.patch -+++ /dev/null -@@ -1,183 +0,0 @@ --From: Alexander Wetzel --Date: Sun, 9 Oct 2022 18:30:38 +0200 --Subject: [PATCH] wifi: mac80211: add internal handler for wake_tx_queue -- --Start to align the TX handling to only use internal TX queues (iTXQs): -- --Provide a handler for drivers not having a custom wake_tx_queue --callback and update the documentation. -- --Signed-off-by: Alexander Wetzel --Signed-off-by: Johannes Berg ----- -- ----- a/include/net/mac80211.h --+++ b/include/net/mac80211.h --@@ -89,15 +89,13 @@ -- /** -- * DOC: mac80211 software tx queueing -- * --- * mac80211 provides an optional intermediate queueing implementation designed --- * to allow the driver to keep hardware queues short and provide some fairness --- * between different stations/interfaces. --- * In this model, the driver pulls data frames from the mac80211 queue instead --- * of letting mac80211 push them via drv_tx(). --- * Other frames (e.g. control or management) are still pushed using drv_tx(). --+ * mac80211 uses an intermediate queueing implementation, designed to allow the --+ * driver to keep hardware queues short and to provide some fairness between --+ * different stations/interfaces. -- * --- * Drivers indicate that they use this model by implementing the .wake_tx_queue --- * driver operation. --+ * Drivers must provide the .wake_tx_queue driver operation by either --+ * linking it to ieee80211_handle_wake_tx_queue() or implementing a custom --+ * handler. -- * -- * Intermediate queues (struct ieee80211_txq) are kept per-sta per-tid, with -- * another per-sta for non-data/non-mgmt and bufferable management frames, and --@@ -106,9 +104,12 @@ -- * The driver is expected to initialize its private per-queue data for stations -- * and interfaces in the .add_interface and .sta_add ops. -- * --- * The driver can't access the queue directly. To dequeue a frame from a --- * txq, it calls ieee80211_tx_dequeue(). Whenever mac80211 adds a new frame to a --- * queue, it calls the .wake_tx_queue driver op. --+ * The driver can't access the internal TX queues (iTXQs) directly. --+ * Whenever mac80211 adds a new frame to a queue, it calls the .wake_tx_queue --+ * driver op. --+ * Drivers implementing a custom .wake_tx_queue op can get them by calling --+ * ieee80211_tx_dequeue(). Drivers using ieee80211_handle_wake_tx_queue() will --+ * simply get the individual frames pushed via the .tx driver operation. -- * -- * Drivers can optionally delegate responsibility for scheduling queues to -- * mac80211, to take advantage of airtime fairness accounting. In this case, to --@@ -2248,8 +2249,8 @@ struct ieee80211_link_sta { -- * For non MLO STA it will point to the deflink data. For MLO STA -- * ieee80211_sta_recalc_aggregates() must be called to update it. -- * @support_p2p_ps: indicates whether the STA supports P2P PS mechanism or not. --- * @txq: per-TID data TX queues (if driver uses the TXQ abstraction); note that --- * the last entry (%IEEE80211_NUM_TIDS) is used for non-data frames --+ * @txq: per-TID data TX queues; note that the last entry (%IEEE80211_NUM_TIDS) --+ * is used for non-data frames -- * @deflink: This holds the default link STA information, for non MLO STA all link -- * specific STA information is accessed through @deflink or through -- * link[0] which points to address of @deflink. For MLO Link STA --@@ -5687,7 +5688,7 @@ void ieee80211_key_replay(struct ieee802 -- * @hw: pointer as obtained from ieee80211_alloc_hw(). -- * @queue: queue number (counted from zero). -- * --- * Drivers should use this function instead of netif_wake_queue. --+ * Drivers must use this function instead of netif_wake_queue. -- */ -- void ieee80211_wake_queue(struct ieee80211_hw *hw, int queue); -- --@@ -5696,7 +5697,7 @@ void ieee80211_wake_queue(struct ieee802 -- * @hw: pointer as obtained from ieee80211_alloc_hw(). -- * @queue: queue number (counted from zero). -- * --- * Drivers should use this function instead of netif_stop_queue. --+ * Drivers must use this function instead of netif_stop_queue. -- */ -- void ieee80211_stop_queue(struct ieee80211_hw *hw, int queue); -- --@@ -5705,7 +5706,7 @@ void ieee80211_stop_queue(struct ieee802 -- * @hw: pointer as obtained from ieee80211_alloc_hw(). -- * @queue: queue number (counted from zero). -- * --- * Drivers should use this function instead of netif_stop_queue. --+ * Drivers must use this function instead of netif_queue_stopped. -- * -- * Return: %true if the queue is stopped. %false otherwise. -- */ --@@ -5716,7 +5717,7 @@ int ieee80211_queue_stopped(struct ieee8 -- * ieee80211_stop_queues - stop all queues -- * @hw: pointer as obtained from ieee80211_alloc_hw(). -- * --- * Drivers should use this function instead of netif_stop_queue. --+ * Drivers must use this function instead of netif_tx_stop_all_queues. -- */ -- void ieee80211_stop_queues(struct ieee80211_hw *hw); -- --@@ -5724,7 +5725,7 @@ void ieee80211_stop_queues(struct ieee80 -- * ieee80211_wake_queues - wake all queues -- * @hw: pointer as obtained from ieee80211_alloc_hw(). -- * --- * Drivers should use this function instead of netif_wake_queue. --+ * Drivers must use this function instead of netif_tx_wake_all_queues. -- */ -- void ieee80211_wake_queues(struct ieee80211_hw *hw); -- --@@ -6946,6 +6947,18 @@ static inline struct sk_buff *ieee80211_ -- } -- -- /** --+ * ieee80211_handle_wake_tx_queue - mac80211 handler for wake_tx_queue callback --+ * --+ * @hw: pointer as obtained from wake_tx_queue() callback(). --+ * @txq: pointer as obtained from wake_tx_queue() callback(). --+ * --+ * Drivers can use this function for the mandatory mac80211 wake_tx_queue --+ * callback in struct ieee80211_ops. They should not call this function. --+ */ --+void ieee80211_handle_wake_tx_queue(struct ieee80211_hw *hw, --+ struct ieee80211_txq *txq); --+ --+/** -- * ieee80211_next_txq - get next tx queue to pull packets from -- * -- * @hw: pointer as obtained from ieee80211_alloc_hw() ----- a/net/mac80211/util.c --+++ b/net/mac80211/util.c --@@ -288,6 +288,52 @@ __le16 ieee80211_ctstoself_duration(stru -- } -- EXPORT_SYMBOL(ieee80211_ctstoself_duration); -- --+static void wake_tx_push_queue(struct ieee80211_local *local, --+ struct ieee80211_sub_if_data *sdata, --+ struct ieee80211_txq *queue) --+{ --+ int q = sdata->vif.hw_queue[queue->ac]; --+ struct ieee80211_tx_control control = { --+ .sta = queue->sta, --+ }; --+ struct sk_buff *skb; --+ unsigned long flags; --+ bool q_stopped; --+ --+ while (1) { --+ spin_lock_irqsave(&local->queue_stop_reason_lock, flags); --+ q_stopped = local->queue_stop_reasons[q]; --+ spin_unlock_irqrestore(&local->queue_stop_reason_lock, flags); --+ --+ if (q_stopped) --+ break; --+ --+ skb = ieee80211_tx_dequeue(&local->hw, queue); --+ if (!skb) --+ break; --+ --+ drv_tx(local, &control, skb); --+ } --+} --+ --+/* wake_tx_queue handler for driver not implementing a custom one*/ --+void ieee80211_handle_wake_tx_queue(struct ieee80211_hw *hw, --+ struct ieee80211_txq *txq) --+{ --+ struct ieee80211_local *local = hw_to_local(hw); --+ struct ieee80211_sub_if_data *sdata = vif_to_sdata(txq->vif); --+ struct ieee80211_txq *queue; --+ --+ /* Use ieee80211_next_txq() for airtime fairness accounting */ --+ ieee80211_txq_schedule_start(hw, txq->ac); --+ while ((queue = ieee80211_next_txq(hw, txq->ac))) { --+ wake_tx_push_queue(local, sdata, queue); --+ ieee80211_return_txq(hw, queue, false); --+ } --+ ieee80211_txq_schedule_end(hw, txq->ac); --+} --+EXPORT_SYMBOL(ieee80211_handle_wake_tx_queue); --+ -- static void __ieee80211_wake_txqs(struct ieee80211_sub_if_data *sdata, int ac) -- { -- struct ieee80211_local *local = sdata->local; -diff --git a/package/kernel/mac80211/patches/subsys/306-02-v6.2-wifi-mac80211-add-wake_tx_queue-callback-to-drivers.patch b/package/kernel/mac80211/patches/subsys/306-02-v6.2-wifi-mac80211-add-wake_tx_queue-callback-to-drivers.patch -deleted file mode 100644 -index fee038d90c..0000000000 ---- a/package/kernel/mac80211/patches/subsys/306-02-v6.2-wifi-mac80211-add-wake_tx_queue-callback-to-drivers.patch -+++ /dev/null -@@ -1,396 +0,0 @@ --From: Alexander Wetzel --Date: Sun, 9 Oct 2022 18:30:39 +0200 --Subject: [PATCH] wifi: mac80211: add wake_tx_queue callback to drivers -- --mac80211 is fully switching over to the internal TX queue (iTXQ) --implementation. Update all drivers not yet providing the now mandatory --wake_tx_queue() callback. -- --As an side effect the netdev interfaces of all updated drivers will --switch to the noqueue qdisc. -- --Signed-off-by: Alexander Wetzel --[add staging drivers] --Signed-off-by: Johannes Berg ----- -- ----- a/drivers/net/wireless/admtek/adm8211.c --+++ b/drivers/net/wireless/admtek/adm8211.c --@@ -1760,6 +1760,7 @@ static int adm8211_alloc_rings(struct ie -- -- static const struct ieee80211_ops adm8211_ops = { -- .tx = adm8211_tx, --+ .wake_tx_queue = ieee80211_handle_wake_tx_queue, -- .start = adm8211_start, -- .stop = adm8211_stop, -- .add_interface = adm8211_add_interface, ----- a/drivers/net/wireless/ath/ar5523/ar5523.c --+++ b/drivers/net/wireless/ath/ar5523/ar5523.c --@@ -1361,6 +1361,7 @@ static const struct ieee80211_ops ar5523 -- .start = ar5523_start, -- .stop = ar5523_stop, -- .tx = ar5523_tx, --+ .wake_tx_queue = ieee80211_handle_wake_tx_queue, -- .set_rts_threshold = ar5523_set_rts_threshold, -- .add_interface = ar5523_add_interface, -- .remove_interface = ar5523_remove_interface, ----- a/drivers/net/wireless/ath/ath11k/mac.c --+++ b/drivers/net/wireless/ath/ath11k/mac.c --@@ -8587,6 +8587,7 @@ err_fallback: -- -- static const struct ieee80211_ops ath11k_ops = { -- .tx = ath11k_mac_op_tx, --+ .wake_tx_queue = ieee80211_handle_wake_tx_queue, -- .start = ath11k_mac_op_start, -- .stop = ath11k_mac_op_stop, -- .reconfig_complete = ath11k_mac_op_reconfig_complete, ----- a/drivers/net/wireless/ath/ath5k/mac80211-ops.c --+++ b/drivers/net/wireless/ath/ath5k/mac80211-ops.c --@@ -781,6 +781,7 @@ static int ath5k_set_ringparam(struct ie -- -- const struct ieee80211_ops ath5k_hw_ops = { -- .tx = ath5k_tx, --+ .wake_tx_queue = ieee80211_handle_wake_tx_queue, -- .start = ath5k_start, -- .stop = ath5k_stop, -- .add_interface = ath5k_add_interface, ----- a/drivers/net/wireless/ath/ath9k/htc_drv_main.c --+++ b/drivers/net/wireless/ath/ath9k/htc_drv_main.c --@@ -1870,6 +1870,7 @@ static void ath9k_htc_channel_switch_bea -- -- struct ieee80211_ops ath9k_htc_ops = { -- .tx = ath9k_htc_tx, --+ .wake_tx_queue = ieee80211_handle_wake_tx_queue, -- .start = ath9k_htc_start, -- .stop = ath9k_htc_stop, -- .add_interface = ath9k_htc_add_interface, ----- a/drivers/net/wireless/ath/carl9170/main.c --+++ b/drivers/net/wireless/ath/carl9170/main.c --@@ -1715,6 +1715,7 @@ static const struct ieee80211_ops carl91 -- .start = carl9170_op_start, -- .stop = carl9170_op_stop, -- .tx = carl9170_op_tx, --+ .wake_tx_queue = ieee80211_handle_wake_tx_queue, -- .flush = carl9170_op_flush, -- .add_interface = carl9170_op_add_interface, -- .remove_interface = carl9170_op_remove_interface, ----- a/drivers/net/wireless/ath/wcn36xx/main.c --+++ b/drivers/net/wireless/ath/wcn36xx/main.c --@@ -1362,6 +1362,7 @@ static const struct ieee80211_ops wcn36x -- .prepare_multicast = wcn36xx_prepare_multicast, -- .configure_filter = wcn36xx_configure_filter, -- .tx = wcn36xx_tx, --+ .wake_tx_queue = ieee80211_handle_wake_tx_queue, -- .set_key = wcn36xx_set_key, -- .hw_scan = wcn36xx_hw_scan, -- .cancel_hw_scan = wcn36xx_cancel_hw_scan, ----- a/drivers/net/wireless/atmel/at76c50x-usb.c --+++ b/drivers/net/wireless/atmel/at76c50x-usb.c --@@ -2187,6 +2187,7 @@ static int at76_set_key(struct ieee80211 -- -- static const struct ieee80211_ops at76_ops = { -- .tx = at76_mac80211_tx, --+ .wake_tx_queue = ieee80211_handle_wake_tx_queue, -- .add_interface = at76_add_interface, -- .remove_interface = at76_remove_interface, -- .config = at76_config, ----- a/drivers/net/wireless/broadcom/b43/main.c --+++ b/drivers/net/wireless/broadcom/b43/main.c --@@ -5171,6 +5171,7 @@ static int b43_op_get_survey(struct ieee -- -- static const struct ieee80211_ops b43_hw_ops = { -- .tx = b43_op_tx, --+ .wake_tx_queue = ieee80211_handle_wake_tx_queue, -- .conf_tx = b43_op_conf_tx, -- .add_interface = b43_op_add_interface, -- .remove_interface = b43_op_remove_interface, ----- a/drivers/net/wireless/broadcom/b43legacy/main.c --+++ b/drivers/net/wireless/broadcom/b43legacy/main.c --@@ -3532,6 +3532,7 @@ static int b43legacy_op_get_survey(struc -- -- static const struct ieee80211_ops b43legacy_hw_ops = { -- .tx = b43legacy_op_tx, --+ .wake_tx_queue = ieee80211_handle_wake_tx_queue, -- .conf_tx = b43legacy_op_conf_tx, -- .add_interface = b43legacy_op_add_interface, -- .remove_interface = b43legacy_op_remove_interface, ----- a/drivers/net/wireless/broadcom/brcm80211/brcmsmac/mac80211_if.c --+++ b/drivers/net/wireless/broadcom/brcm80211/brcmsmac/mac80211_if.c --@@ -962,6 +962,7 @@ static int brcms_ops_beacon_set_tim(stru -- -- static const struct ieee80211_ops brcms_ops = { -- .tx = brcms_ops_tx, --+ .wake_tx_queue = ieee80211_handle_wake_tx_queue, -- .start = brcms_ops_start, -- .stop = brcms_ops_stop, -- .add_interface = brcms_ops_add_interface, ----- a/drivers/net/wireless/intel/iwlegacy/3945-mac.c --+++ b/drivers/net/wireless/intel/iwlegacy/3945-mac.c --@@ -3439,6 +3439,7 @@ static const struct attribute_group il39 -- -- static struct ieee80211_ops il3945_mac_ops __ro_after_init = { -- .tx = il3945_mac_tx, --+ .wake_tx_queue = ieee80211_handle_wake_tx_queue, -- .start = il3945_mac_start, -- .stop = il3945_mac_stop, -- .add_interface = il_mac_add_interface, ----- a/drivers/net/wireless/intel/iwlegacy/4965-mac.c --+++ b/drivers/net/wireless/intel/iwlegacy/4965-mac.c --@@ -6308,6 +6308,7 @@ il4965_tx_queue_set_status(struct il_pri -- -- static const struct ieee80211_ops il4965_mac_ops = { -- .tx = il4965_mac_tx, --+ .wake_tx_queue = ieee80211_handle_wake_tx_queue, -- .start = il4965_mac_start, -- .stop = il4965_mac_stop, -- .add_interface = il_mac_add_interface, ----- a/drivers/net/wireless/intel/iwlwifi/dvm/mac80211.c --+++ b/drivers/net/wireless/intel/iwlwifi/dvm/mac80211.c --@@ -1571,6 +1571,7 @@ static void iwlagn_mac_sta_notify(struct -- -- const struct ieee80211_ops iwlagn_hw_ops = { -- .tx = iwlagn_mac_tx, --+ .wake_tx_queue = ieee80211_handle_wake_tx_queue, -- .start = iwlagn_mac_start, -- .stop = iwlagn_mac_stop, -- #ifdef CONFIG_PM_SLEEP ----- a/drivers/net/wireless/intersil/p54/main.c --+++ b/drivers/net/wireless/intersil/p54/main.c --@@ -705,6 +705,7 @@ static void p54_set_coverage_class(struc -- -- static const struct ieee80211_ops p54_ops = { -- .tx = p54_tx_80211, --+ .wake_tx_queue = ieee80211_handle_wake_tx_queue, -- .start = p54_start, -- .stop = p54_stop, -- .add_interface = p54_add_interface, ----- a/drivers/net/wireless/mac80211_hwsim.c --+++ b/drivers/net/wireless/mac80211_hwsim.c --@@ -3109,6 +3109,7 @@ static int mac80211_hwsim_change_sta_lin -- -- #define HWSIM_COMMON_OPS \ -- .tx = mac80211_hwsim_tx, \ --+ .wake_tx_queue = ieee80211_handle_wake_tx_queue, \ -- .start = mac80211_hwsim_start, \ -- .stop = mac80211_hwsim_stop, \ -- .add_interface = mac80211_hwsim_add_interface, \ ----- a/drivers/net/wireless/marvell/libertas_tf/main.c --+++ b/drivers/net/wireless/marvell/libertas_tf/main.c --@@ -474,6 +474,7 @@ static int lbtf_op_get_survey(struct iee -- -- static const struct ieee80211_ops lbtf_ops = { -- .tx = lbtf_op_tx, --+ .wake_tx_queue = ieee80211_handle_wake_tx_queue, -- .start = lbtf_op_start, -- .stop = lbtf_op_stop, -- .add_interface = lbtf_op_add_interface, ----- a/drivers/net/wireless/marvell/mwl8k.c --+++ b/drivers/net/wireless/marvell/mwl8k.c --@@ -5611,6 +5611,7 @@ static void mwl8k_sw_scan_complete(struc -- -- static const struct ieee80211_ops mwl8k_ops = { -- .tx = mwl8k_tx, --+ .wake_tx_queue = ieee80211_handle_wake_tx_queue, -- .start = mwl8k_start, -- .stop = mwl8k_stop, -- .add_interface = mwl8k_add_interface, ----- a/drivers/net/wireless/mediatek/mt7601u/main.c --+++ b/drivers/net/wireless/mediatek/mt7601u/main.c --@@ -406,6 +406,7 @@ out: -- -- const struct ieee80211_ops mt7601u_ops = { -- .tx = mt7601u_tx, --+ .wake_tx_queue = ieee80211_handle_wake_tx_queue, -- .start = mt7601u_start, -- .stop = mt7601u_stop, -- .add_interface = mt7601u_add_interface, ----- a/drivers/net/wireless/ralink/rt2x00/rt2400pci.c --+++ b/drivers/net/wireless/ralink/rt2x00/rt2400pci.c --@@ -1706,6 +1706,7 @@ static int rt2400pci_tx_last_beacon(stru -- -- static const struct ieee80211_ops rt2400pci_mac80211_ops = { -- .tx = rt2x00mac_tx, --+ .wake_tx_queue = ieee80211_handle_wake_tx_queue, -- .start = rt2x00mac_start, -- .stop = rt2x00mac_stop, -- .add_interface = rt2x00mac_add_interface, ----- a/drivers/net/wireless/ralink/rt2x00/rt2500pci.c --+++ b/drivers/net/wireless/ralink/rt2x00/rt2500pci.c --@@ -2004,6 +2004,7 @@ static int rt2500pci_tx_last_beacon(stru -- -- static const struct ieee80211_ops rt2500pci_mac80211_ops = { -- .tx = rt2x00mac_tx, --+ .wake_tx_queue = ieee80211_handle_wake_tx_queue, -- .start = rt2x00mac_start, -- .stop = rt2x00mac_stop, -- .add_interface = rt2x00mac_add_interface, ----- a/drivers/net/wireless/ralink/rt2x00/rt2500usb.c --+++ b/drivers/net/wireless/ralink/rt2x00/rt2500usb.c --@@ -1795,6 +1795,7 @@ static int rt2500usb_probe_hw(struct rt2 -- -- static const struct ieee80211_ops rt2500usb_mac80211_ops = { -- .tx = rt2x00mac_tx, --+ .wake_tx_queue = ieee80211_handle_wake_tx_queue, -- .start = rt2x00mac_start, -- .stop = rt2x00mac_stop, -- .add_interface = rt2x00mac_add_interface, ----- a/drivers/net/wireless/ralink/rt2x00/rt2800pci.c --+++ b/drivers/net/wireless/ralink/rt2x00/rt2800pci.c --@@ -288,6 +288,7 @@ static int rt2800pci_read_eeprom(struct -- -- static const struct ieee80211_ops rt2800pci_mac80211_ops = { -- .tx = rt2x00mac_tx, --+ .wake_tx_queue = ieee80211_handle_wake_tx_queue, -- .start = rt2x00mac_start, -- .stop = rt2x00mac_stop, -- .add_interface = rt2x00mac_add_interface, ----- a/drivers/net/wireless/ralink/rt2x00/rt2800soc.c --+++ b/drivers/net/wireless/ralink/rt2x00/rt2800soc.c --@@ -133,6 +133,7 @@ static int rt2800soc_write_firmware(stru -- -- static const struct ieee80211_ops rt2800soc_mac80211_ops = { -- .tx = rt2x00mac_tx, --+ .wake_tx_queue = ieee80211_handle_wake_tx_queue, -- .start = rt2x00mac_start, -- .stop = rt2x00mac_stop, -- .add_interface = rt2x00mac_add_interface, ----- a/drivers/net/wireless/ralink/rt2x00/rt2800usb.c --+++ b/drivers/net/wireless/ralink/rt2x00/rt2800usb.c --@@ -630,6 +630,7 @@ static int rt2800usb_probe_hw(struct rt2 -- -- static const struct ieee80211_ops rt2800usb_mac80211_ops = { -- .tx = rt2x00mac_tx, --+ .wake_tx_queue = ieee80211_handle_wake_tx_queue, -- .start = rt2x00mac_start, -- .stop = rt2x00mac_stop, -- .add_interface = rt2x00mac_add_interface, ----- a/drivers/net/wireless/ralink/rt2x00/rt61pci.c --+++ b/drivers/net/wireless/ralink/rt2x00/rt61pci.c --@@ -2873,6 +2873,7 @@ static u64 rt61pci_get_tsf(struct ieee80 -- -- static const struct ieee80211_ops rt61pci_mac80211_ops = { -- .tx = rt2x00mac_tx, --+ .wake_tx_queue = ieee80211_handle_wake_tx_queue, -- .start = rt2x00mac_start, -- .stop = rt2x00mac_stop, -- .add_interface = rt2x00mac_add_interface, ----- a/drivers/net/wireless/ralink/rt2x00/rt73usb.c --+++ b/drivers/net/wireless/ralink/rt2x00/rt73usb.c --@@ -2292,6 +2292,7 @@ static u64 rt73usb_get_tsf(struct ieee80 -- -- static const struct ieee80211_ops rt73usb_mac80211_ops = { -- .tx = rt2x00mac_tx, --+ .wake_tx_queue = ieee80211_handle_wake_tx_queue, -- .start = rt2x00mac_start, -- .stop = rt2x00mac_stop, -- .add_interface = rt2x00mac_add_interface, ----- a/drivers/net/wireless/realtek/rtl818x/rtl8180/dev.c --+++ b/drivers/net/wireless/realtek/rtl818x/rtl8180/dev.c --@@ -1608,6 +1608,7 @@ static void rtl8180_configure_filter(str -- -- static const struct ieee80211_ops rtl8180_ops = { -- .tx = rtl8180_tx, --+ .wake_tx_queue = ieee80211_handle_wake_tx_queue, -- .start = rtl8180_start, -- .stop = rtl8180_stop, -- .add_interface = rtl8180_add_interface, ----- a/drivers/net/wireless/realtek/rtl818x/rtl8187/dev.c --+++ b/drivers/net/wireless/realtek/rtl818x/rtl8187/dev.c --@@ -1378,6 +1378,7 @@ static int rtl8187_conf_tx(struct ieee80 -- -- static const struct ieee80211_ops rtl8187_ops = { -- .tx = rtl8187_tx, --+ .wake_tx_queue = ieee80211_handle_wake_tx_queue, -- .start = rtl8187_start, -- .stop = rtl8187_stop, -- .add_interface = rtl8187_add_interface, ----- a/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c --+++ b/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c --@@ -6548,6 +6548,7 @@ static void rtl8xxxu_stop(struct ieee802 -- -- static const struct ieee80211_ops rtl8xxxu_ops = { -- .tx = rtl8xxxu_tx, --+ .wake_tx_queue = ieee80211_handle_wake_tx_queue, -- .add_interface = rtl8xxxu_add_interface, -- .remove_interface = rtl8xxxu_remove_interface, -- .config = rtl8xxxu_config, ----- a/drivers/net/wireless/realtek/rtlwifi/core.c --+++ b/drivers/net/wireless/realtek/rtlwifi/core.c --@@ -1912,6 +1912,7 @@ const struct ieee80211_ops rtl_ops = { -- .start = rtl_op_start, -- .stop = rtl_op_stop, -- .tx = rtl_op_tx, --+ .wake_tx_queue = ieee80211_handle_wake_tx_queue, -- .add_interface = rtl_op_add_interface, -- .remove_interface = rtl_op_remove_interface, -- .change_interface = rtl_op_change_interface, ----- a/drivers/net/wireless/realtek/rtw88/mac80211.c --+++ b/drivers/net/wireless/realtek/rtw88/mac80211.c --@@ -896,6 +896,7 @@ static void rtw_ops_sta_rc_update(struct -- -- const struct ieee80211_ops rtw_ops = { -- .tx = rtw_ops_tx, --+ .wake_tx_queue = ieee80211_handle_wake_tx_queue, -- .wake_tx_queue = rtw_ops_wake_tx_queue, -- .start = rtw_ops_start, -- .stop = rtw_ops_stop, ----- a/drivers/net/wireless/realtek/rtw89/mac80211.c --+++ b/drivers/net/wireless/realtek/rtw89/mac80211.c --@@ -918,6 +918,7 @@ static int rtw89_ops_set_tid_config(stru -- -- const struct ieee80211_ops rtw89_ops = { -- .tx = rtw89_ops_tx, --+ .wake_tx_queue = ieee80211_handle_wake_tx_queue, -- .wake_tx_queue = rtw89_ops_wake_tx_queue, -- .start = rtw89_ops_start, -- .stop = rtw89_ops_stop, ----- a/drivers/net/wireless/rsi/rsi_91x_mac80211.c --+++ b/drivers/net/wireless/rsi/rsi_91x_mac80211.c --@@ -1958,6 +1958,7 @@ static int rsi_mac80211_resume(struct ie -- -- static const struct ieee80211_ops mac80211_ops = { -- .tx = rsi_mac80211_tx, --+ .wake_tx_queue = ieee80211_handle_wake_tx_queue, -- .start = rsi_mac80211_start, -- .stop = rsi_mac80211_stop, -- .add_interface = rsi_mac80211_add_interface, ----- a/drivers/net/wireless/st/cw1200/main.c --+++ b/drivers/net/wireless/st/cw1200/main.c --@@ -209,6 +209,7 @@ static const struct ieee80211_ops cw1200 -- .remove_interface = cw1200_remove_interface, -- .change_interface = cw1200_change_interface, -- .tx = cw1200_tx, --+ .wake_tx_queue = ieee80211_handle_wake_tx_queue, -- .hw_scan = cw1200_hw_scan, -- .set_tim = cw1200_set_tim, -- .sta_notify = cw1200_sta_notify, ----- a/drivers/net/wireless/ti/wl1251/main.c --+++ b/drivers/net/wireless/ti/wl1251/main.c --@@ -1359,6 +1359,7 @@ static const struct ieee80211_ops wl1251 -- .prepare_multicast = wl1251_op_prepare_multicast, -- .configure_filter = wl1251_op_configure_filter, -- .tx = wl1251_op_tx, --+ .wake_tx_queue = ieee80211_handle_wake_tx_queue, -- .set_key = wl1251_op_set_key, -- .hw_scan = wl1251_op_hw_scan, -- .bss_info_changed = wl1251_op_bss_info_changed, ----- a/drivers/net/wireless/ti/wlcore/main.c --+++ b/drivers/net/wireless/ti/wlcore/main.c --@@ -5942,6 +5942,7 @@ static const struct ieee80211_ops wl1271 -- .prepare_multicast = wl1271_op_prepare_multicast, -- .configure_filter = wl1271_op_configure_filter, -- .tx = wl1271_op_tx, --+ .wake_tx_queue = ieee80211_handle_wake_tx_queue, -- .set_key = wlcore_op_set_key, -- .hw_scan = wl1271_op_hw_scan, -- .cancel_hw_scan = wl1271_op_cancel_hw_scan, ----- a/drivers/net/wireless/zydas/zd1211rw/zd_mac.c --+++ b/drivers/net/wireless/zydas/zd1211rw/zd_mac.c --@@ -1344,6 +1344,7 @@ static u64 zd_op_get_tsf(struct ieee8021 -- -- static const struct ieee80211_ops zd_ops = { -- .tx = zd_op_tx, --+ .wake_tx_queue = ieee80211_handle_wake_tx_queue, -- .start = zd_op_start, -- .stop = zd_op_stop, -- .add_interface = zd_op_add_interface, -diff --git a/package/kernel/mac80211/patches/subsys/306-03-v6.2-wifi-mac80211-Drop-support-for-TX-push-path.patch b/package/kernel/mac80211/patches/subsys/306-03-v6.2-wifi-mac80211-Drop-support-for-TX-push-path.patch -deleted file mode 100644 -index f9f9977cee..0000000000 ---- a/package/kernel/mac80211/patches/subsys/306-03-v6.2-wifi-mac80211-Drop-support-for-TX-push-path.patch -+++ /dev/null -@@ -1,683 +0,0 @@ --From: Alexander Wetzel --Date: Sun, 9 Oct 2022 18:30:40 +0200 --Subject: [PATCH] wifi: mac80211: Drop support for TX push path -- --All drivers are now using mac80211 internal queues (iTXQs). --Drop mac80211 internal support for the old push path. -- --Signed-off-by: Alexander Wetzel --Signed-off-by: Johannes Berg ----- -- ----- a/net/mac80211/cfg.c --+++ b/net/mac80211/cfg.c --@@ -4346,9 +4346,6 @@ static int ieee80211_get_txq_stats(struc -- struct ieee80211_sub_if_data *sdata; -- int ret = 0; -- --- if (!local->ops->wake_tx_queue) --- return 1; --- -- spin_lock_bh(&local->fq.lock); -- rcu_read_lock(); -- ----- a/net/mac80211/debugfs.c --+++ b/net/mac80211/debugfs.c --@@ -663,9 +663,7 @@ void debugfs_hw_add(struct ieee80211_loc -- DEBUGFS_ADD_MODE(force_tx_status, 0600); -- DEBUGFS_ADD_MODE(aql_enable, 0600); -- DEBUGFS_ADD(aql_pending); --- --- if (local->ops->wake_tx_queue) --- DEBUGFS_ADD_MODE(aqm, 0600); --+ DEBUGFS_ADD_MODE(aqm, 0600); -- -- DEBUGFS_ADD_MODE(airtime_flags, 0600); -- ----- a/net/mac80211/debugfs_netdev.c --+++ b/net/mac80211/debugfs_netdev.c --@@ -677,8 +677,7 @@ static void add_common_files(struct ieee -- DEBUGFS_ADD(rc_rateidx_vht_mcs_mask_5ghz); -- DEBUGFS_ADD(hw_queues); -- --- if (sdata->local->ops->wake_tx_queue && --- sdata->vif.type != NL80211_IFTYPE_P2P_DEVICE && --+ if (sdata->vif.type != NL80211_IFTYPE_P2P_DEVICE && -- sdata->vif.type != NL80211_IFTYPE_NAN) -- DEBUGFS_ADD(aqm); -- } ----- a/net/mac80211/debugfs_sta.c --+++ b/net/mac80211/debugfs_sta.c --@@ -1057,10 +1057,8 @@ void ieee80211_sta_debugfs_add(struct st -- DEBUGFS_ADD_COUNTER(rx_fragments, deflink.rx_stats.fragments); -- DEBUGFS_ADD_COUNTER(tx_filtered, deflink.status_stats.filtered); -- --- if (local->ops->wake_tx_queue) { --- DEBUGFS_ADD(aqm); --- DEBUGFS_ADD(airtime); --- } --+ DEBUGFS_ADD(aqm); --+ DEBUGFS_ADD(airtime); -- -- if (wiphy_ext_feature_isset(local->hw.wiphy, -- NL80211_EXT_FEATURE_AQL)) ----- a/net/mac80211/ieee80211_i.h --+++ b/net/mac80211/ieee80211_i.h --@@ -2294,7 +2294,6 @@ void ieee80211_wake_queue_by_reason(stru -- void ieee80211_stop_queue_by_reason(struct ieee80211_hw *hw, int queue, -- enum queue_stop_reason reason, -- bool refcounted); ---void ieee80211_propagate_queue_wake(struct ieee80211_local *local, int queue); -- void ieee80211_add_pending_skb(struct ieee80211_local *local, -- struct sk_buff *skb); -- void ieee80211_add_pending_skbs(struct ieee80211_local *local, ----- a/net/mac80211/iface.c --+++ b/net/mac80211/iface.c --@@ -460,12 +460,6 @@ static void ieee80211_do_stop(struct iee -- if (cancel_scan) -- ieee80211_scan_cancel(local); -- --- /* --- * Stop TX on this interface first. --- */ --- if (!local->ops->wake_tx_queue && sdata->dev) --- netif_tx_stop_all_queues(sdata->dev); --- -- ieee80211_roc_purge(local, sdata); -- -- switch (sdata->vif.type) { --@@ -813,13 +807,6 @@ static void ieee80211_uninit(struct net_ -- ieee80211_teardown_sdata(IEEE80211_DEV_TO_SUB_IF(dev)); -- } -- ---static u16 ieee80211_netdev_select_queue(struct net_device *dev, --- struct sk_buff *skb, --- struct net_device *sb_dev) ---{ --- return ieee80211_select_queue(IEEE80211_DEV_TO_SUB_IF(dev), skb); ---} --- -- static void -- ieee80211_get_stats64(struct net_device *dev, struct rtnl_link_stats64 *stats) -- { --@@ -833,7 +820,6 @@ static const struct net_device_ops ieee8 -- .ndo_start_xmit = ieee80211_subif_start_xmit, -- .ndo_set_rx_mode = ieee80211_set_multicast_list, -- .ndo_set_mac_address = ieee80211_change_mac, --- .ndo_select_queue = ieee80211_netdev_select_queue, -- .ndo_get_stats64 = ieee80211_get_stats64, -- }; -- --@@ -941,7 +927,6 @@ static const struct net_device_ops ieee8 -- .ndo_start_xmit = ieee80211_subif_start_xmit_8023, -- .ndo_set_rx_mode = ieee80211_set_multicast_list, -- .ndo_set_mac_address = ieee80211_change_mac, --- .ndo_select_queue = ieee80211_netdev_select_queue, -- .ndo_get_stats64 = ieee80211_get_stats64, -- .ndo_fill_forward_path = ieee80211_netdev_fill_forward_path, -- }; --@@ -1443,35 +1428,6 @@ int ieee80211_do_open(struct wireless_de -- -- ieee80211_recalc_ps(local); -- --- if (sdata->vif.type == NL80211_IFTYPE_MONITOR || --- sdata->vif.type == NL80211_IFTYPE_AP_VLAN || --- local->ops->wake_tx_queue) { --- /* XXX: for AP_VLAN, actually track AP queues */ --- if (dev) --- netif_tx_start_all_queues(dev); --- } else if (dev) { --- unsigned long flags; --- int n_acs = IEEE80211_NUM_ACS; --- int ac; --- --- if (local->hw.queues < IEEE80211_NUM_ACS) --- n_acs = 1; --- --- spin_lock_irqsave(&local->queue_stop_reason_lock, flags); --- if (sdata->vif.cab_queue == IEEE80211_INVAL_HW_QUEUE || --- (local->queue_stop_reasons[sdata->vif.cab_queue] == 0 && --- skb_queue_empty(&local->pending[sdata->vif.cab_queue]))) { --- for (ac = 0; ac < n_acs; ac++) { --- int ac_queue = sdata->vif.hw_queue[ac]; --- --- if (local->queue_stop_reasons[ac_queue] == 0 && --- skb_queue_empty(&local->pending[ac_queue])) --- netif_start_subqueue(dev, ac); --- } --- } --- spin_unlock_irqrestore(&local->queue_stop_reason_lock, flags); --- } --- -- set_bit(SDATA_STATE_RUNNING, &sdata->state); -- -- return 0; --@@ -1501,17 +1457,12 @@ static void ieee80211_if_setup(struct ne -- { -- ether_setup(dev); -- dev->priv_flags &= ~IFF_TX_SKB_SHARING; --+ dev->priv_flags |= IFF_NO_QUEUE; -- dev->netdev_ops = &ieee80211_dataif_ops; -- dev->needs_free_netdev = true; -- dev->priv_destructor = ieee80211_if_free; -- } -- ---static void ieee80211_if_setup_no_queue(struct net_device *dev) ---{ --- ieee80211_if_setup(dev); --- dev->priv_flags |= IFF_NO_QUEUE; ---} --- -- static void ieee80211_iface_process_skb(struct ieee80211_local *local, -- struct ieee80211_sub_if_data *sdata, -- struct sk_buff *skb) --@@ -2096,9 +2047,7 @@ int ieee80211_if_add(struct ieee80211_lo -- struct net_device *ndev = NULL; -- struct ieee80211_sub_if_data *sdata = NULL; -- struct txq_info *txqi; --- void (*if_setup)(struct net_device *dev); -- int ret, i; --- int txqs = 1; -- -- ASSERT_RTNL(); -- --@@ -2121,30 +2070,18 @@ int ieee80211_if_add(struct ieee80211_lo -- sizeof(void *)); -- int txq_size = 0; -- --- if (local->ops->wake_tx_queue && --- type != NL80211_IFTYPE_AP_VLAN && --+ if (type != NL80211_IFTYPE_AP_VLAN && -- (type != NL80211_IFTYPE_MONITOR || -- (params->flags & MONITOR_FLAG_ACTIVE))) -- txq_size += sizeof(struct txq_info) + -- local->hw.txq_data_size; -- --- if (local->ops->wake_tx_queue) { --- if_setup = ieee80211_if_setup_no_queue; --- } else { --- if_setup = ieee80211_if_setup; --- if (local->hw.queues >= IEEE80211_NUM_ACS) --- txqs = IEEE80211_NUM_ACS; --- } --- -- ndev = alloc_netdev_mqs(size + txq_size, -- name, name_assign_type, --- if_setup, txqs, 1); --+ ieee80211_if_setup, 1, 1); -- if (!ndev) -- return -ENOMEM; -- --- if (!local->ops->wake_tx_queue && local->hw.wiphy->tx_queue_len) --- ndev->tx_queue_len = local->hw.wiphy->tx_queue_len; --- -- dev_net_set(ndev, wiphy_net(local->hw.wiphy)); -- -- ndev->tstats = netdev_alloc_pcpu_stats(struct pcpu_sw_netstats); ----- a/net/mac80211/main.c --+++ b/net/mac80211/main.c --@@ -630,7 +630,7 @@ struct ieee80211_hw *ieee80211_alloc_hw_ -- -- if (WARN_ON(!ops->tx || !ops->start || !ops->stop || !ops->config || -- !ops->add_interface || !ops->remove_interface || --- !ops->configure_filter)) --+ !ops->configure_filter || !ops->wake_tx_queue)) -- return NULL; -- -- if (WARN_ON(ops->sta_state && (ops->sta_add || ops->sta_remove))) --@@ -719,9 +719,7 @@ struct ieee80211_hw *ieee80211_alloc_hw_ -- if (!ops->set_key) -- wiphy->flags |= WIPHY_FLAG_IBSS_RSN; -- --- if (ops->wake_tx_queue) --- wiphy_ext_feature_set(wiphy, NL80211_EXT_FEATURE_TXQS); --- --+ wiphy_ext_feature_set(wiphy, NL80211_EXT_FEATURE_TXQS); -- wiphy_ext_feature_set(wiphy, NL80211_EXT_FEATURE_RRM); -- -- wiphy->bss_priv_size = sizeof(struct ieee80211_bss); --@@ -834,10 +832,7 @@ struct ieee80211_hw *ieee80211_alloc_hw_ -- atomic_set(&local->agg_queue_stop[i], 0); -- } -- tasklet_setup(&local->tx_pending_tasklet, ieee80211_tx_pending); --- --- if (ops->wake_tx_queue) --- tasklet_setup(&local->wake_txqs_tasklet, ieee80211_wake_txqs); --- --+ 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 --@@ -1571,9 +1571,6 @@ 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,17 +140,15 @@ static void __cleanup_single_sta(struct -- atomic_dec(&ps->num_sta_ps); -- } -- --- if (sta->sta.txq[0]) { --- for (i = 0; i < ARRAY_SIZE(sta->sta.txq); i++) { --- struct txq_info *txqi; --+ 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++) { --@@ -425,8 +423,7 @@ void sta_info_free(struct ieee80211_loca -- -- sta_dbg(sta->sdata, "Destroyed STA %pM\n", sta->sta.addr); -- --- if (sta->sta.txq[0]) --- kfree(to_txq_info(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); --@@ -527,6 +524,8 @@ __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); --@@ -597,21 +596,18 @@ __sta_info_alloc(struct ieee80211_sub_if -- -- sta->last_connected = ktime_get_seconds(); -- --- if (local->ops->wake_tx_queue) { --- void *txq_data; --- int size = sizeof(struct txq_info) + --- ALIGN(hw->txq_data_size, sizeof(void *)); --+ 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; --+ 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)) --@@ -685,8 +681,7 @@ __sta_info_alloc(struct ieee80211_sub_if -- return sta; -- -- free_txq: --- if (sta->sta.txq[0]) --- kfree(to_txq_info(sta->sta.txq[0])); --+ kfree(to_txq_info(sta->sta.txq[0])); -- free: -- sta_info_free_link(&sta->deflink); -- #ifdef CPTCFG_MAC80211_MESH --@@ -1960,9 +1955,6 @@ 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)) || --@@ -2447,7 +2439,7 @@ static void sta_set_tidstats(struct sta_ -- tidstats->tx_msdu_failed = sta->deflink.status_stats.msdu_failed[tid]; -- } -- --- if (local->ops->wake_tx_queue && tid < IEEE80211_NUM_TIDS) { --+ if (tid < IEEE80211_NUM_TIDS) { -- spin_lock_bh(&local->fq.lock); -- rcu_read_lock(); -- --@@ -2775,9 +2767,6 @@ unsigned long ieee80211_sta_last_active( -- -- static void sta_update_codel_params(struct sta_info *sta, u32 thr) -- { --- if (!sta->sdata->local->ops->wake_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/tdls.c --+++ b/net/mac80211/tdls.c --@@ -1016,7 +1016,6 @@ ieee80211_tdls_prep_mgmt_packet(struct w -- skb->priority = 256 + 5; -- break; -- } --- skb_set_queue_mapping(skb, ieee80211_select_queue(sdata, skb)); -- -- /* -- * Set the WLAN_TDLS_TEARDOWN flag to indicate a teardown in progress. ----- a/net/mac80211/tx.c --+++ b/net/mac80211/tx.c --@@ -1600,9 +1600,6 @@ int ieee80211_txq_setup_flows(struct iee -- bool supp_vht = false; -- enum nl80211_band band; -- --- if (!local->ops->wake_tx_queue) --- return 0; --- -- ret = fq_init(fq, 4096); -- if (ret) -- return ret; --@@ -1650,9 +1647,6 @@ void ieee80211_txq_teardown_flows(struct -- { -- struct fq *fq = &local->fq; -- --- if (!local->ops->wake_tx_queue) --- return; --- -- kfree(local->cvars); -- local->cvars = NULL; -- --@@ -1669,8 +1663,7 @@ static bool ieee80211_queue_skb(struct i -- struct ieee80211_vif *vif; -- struct txq_info *txqi; -- --- if (!local->ops->wake_tx_queue || --- sdata->vif.type == NL80211_IFTYPE_MONITOR) --+ if (sdata->vif.type == NL80211_IFTYPE_MONITOR) -- return false; -- -- if (sdata->vif.type == NL80211_IFTYPE_AP_VLAN) --@@ -4193,12 +4186,7 @@ void __ieee80211_subif_start_xmit(struct -- if (IS_ERR(sta)) -- sta = NULL; -- --- if (local->ops->wake_tx_queue) { --- u16 queue = __ieee80211_select_queue(sdata, sta, skb); --- skb_set_queue_mapping(skb, queue); --- skb_get_hash(skb); --- } --- --+ skb_set_queue_mapping(skb, ieee80211_select_queue(sdata, sta, skb)); -- ieee80211_aggr_check(sdata, sta, skb); -- -- sk_pacing_shift_update(skb->sk, sdata->local->hw.tx_sk_pacing_shift); --@@ -4509,11 +4497,7 @@ static void ieee80211_8023_xmit(struct i -- struct tid_ampdu_tx *tid_tx; -- u8 tid; -- --- if (local->ops->wake_tx_queue) { --- u16 queue = __ieee80211_select_queue(sdata, sta, skb); --- skb_set_queue_mapping(skb, queue); --- skb_get_hash(skb); --- } --+ skb_set_queue_mapping(skb, ieee80211_select_queue(sdata, sta, skb)); -- -- if (unlikely(test_bit(SCAN_SW_SCANNING, &local->scanning)) && -- test_bit(SDATA_STATE_OFFCHANNEL, &sdata->state)) --@@ -4767,9 +4751,6 @@ void ieee80211_tx_pending(struct tasklet -- if (!txok) -- break; -- } --- --- if (skb_queue_empty(&local->pending[i])) --- ieee80211_propagate_queue_wake(local, i); -- } -- spin_unlock_irqrestore(&local->queue_stop_reason_lock, flags); -- --@@ -5962,10 +5943,9 @@ int ieee80211_tx_control_port(struct wip -- } -- -- if (!IS_ERR(sta)) { --- u16 queue = __ieee80211_select_queue(sdata, sta, skb); --+ u16 queue = ieee80211_select_queue(sdata, sta, skb); -- -- skb_set_queue_mapping(skb, queue); --- skb_get_hash(skb); -- -- /* -- * for MLO STA, the SA should be the AP MLD address, but ----- a/net/mac80211/util.c --+++ b/net/mac80211/util.c --@@ -444,39 +444,6 @@ void ieee80211_wake_txqs(struct tasklet_ -- spin_unlock_irqrestore(&local->queue_stop_reason_lock, flags); -- } -- ---void ieee80211_propagate_queue_wake(struct ieee80211_local *local, int queue) ---{ --- struct ieee80211_sub_if_data *sdata; --- int n_acs = IEEE80211_NUM_ACS; --- --- if (local->ops->wake_tx_queue) --- return; --- --- if (local->hw.queues < IEEE80211_NUM_ACS) --- n_acs = 1; --- --- list_for_each_entry_rcu(sdata, &local->interfaces, list) { --- int ac; --- --- if (!sdata->dev) --- continue; --- --- if (sdata->vif.cab_queue != IEEE80211_INVAL_HW_QUEUE && --- local->queue_stop_reasons[sdata->vif.cab_queue] != 0) --- continue; --- --- for (ac = 0; ac < n_acs; ac++) { --- int ac_queue = sdata->vif.hw_queue[ac]; --- --- if (ac_queue == queue || --- (sdata->vif.cab_queue == queue && --- local->queue_stop_reasons[ac_queue] == 0 && --- skb_queue_empty(&local->pending[ac_queue]))) --- netif_wake_subqueue(sdata->dev, ac); --- } --- } ---} --- -- static void __ieee80211_wake_queue(struct ieee80211_hw *hw, int queue, -- enum queue_stop_reason reason, -- bool refcounted, --@@ -507,11 +474,7 @@ static void __ieee80211_wake_queue(struc -- /* someone still has this queue stopped */ -- return; -- --- if (skb_queue_empty(&local->pending[queue])) { --- rcu_read_lock(); --- ieee80211_propagate_queue_wake(local, queue); --- rcu_read_unlock(); --- } else --+ if (!skb_queue_empty(&local->pending[queue])) -- tasklet_schedule(&local->tx_pending_tasklet); -- -- /* --@@ -521,12 +484,10 @@ 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 (local->ops->wake_tx_queue) { --- if (reason == IEEE80211_QUEUE_STOP_REASON_DRIVER) --- tasklet_schedule(&local->wake_txqs_tasklet); --- else --- _ieee80211_wake_txqs(local, flags); --- } --+ if (reason == IEEE80211_QUEUE_STOP_REASON_DRIVER) --+ tasklet_schedule(&local->wake_txqs_tasklet); --+ else --+ _ieee80211_wake_txqs(local, flags); -- } -- -- void ieee80211_wake_queue_by_reason(struct ieee80211_hw *hw, int queue, --@@ -554,8 +515,6 @@ static void __ieee80211_stop_queue(struc -- bool refcounted) -- { -- struct ieee80211_local *local = hw_to_local(hw); --- struct ieee80211_sub_if_data *sdata; --- int n_acs = IEEE80211_NUM_ACS; -- -- trace_stop_queue(local, queue, reason); -- --@@ -567,27 +526,7 @@ static void __ieee80211_stop_queue(struc -- else -- local->q_stop_reasons[queue][reason]++; -- --- if (__test_and_set_bit(reason, &local->queue_stop_reasons[queue])) --- return; --- --- if (local->hw.queues < IEEE80211_NUM_ACS) --- n_acs = 1; --- --- rcu_read_lock(); --- list_for_each_entry_rcu(sdata, &local->interfaces, list) { --- int ac; --- --- if (!sdata->dev) --- continue; --- --- for (ac = 0; ac < n_acs; ac++) { --- if (!local->ops->wake_tx_queue && --- (sdata->vif.hw_queue[ac] == queue || --- sdata->vif.cab_queue == queue)) --- netif_stop_subqueue(sdata->dev, ac); --- } --- } --- rcu_read_unlock(); --+ set_bit(reason, &local->queue_stop_reasons[queue]); -- } -- -- void ieee80211_stop_queue_by_reason(struct ieee80211_hw *hw, int queue, ----- a/net/mac80211/wme.c --+++ b/net/mac80211/wme.c --@@ -122,6 +122,9 @@ u16 ieee80211_select_queue_80211(struct -- struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); -- u8 *p; -- --+ /* Ensure hash is set prior to potential SW encryption */ --+ skb_get_hash(skb); --+ -- if ((info->control.flags & IEEE80211_TX_CTRL_DONT_REORDER) || -- local->hw.queues < IEEE80211_NUM_ACS) -- return 0; --@@ -141,13 +144,16 @@ u16 ieee80211_select_queue_80211(struct -- return ieee80211_downgrade_queue(sdata, NULL, skb); -- } -- ---u16 __ieee80211_select_queue(struct ieee80211_sub_if_data *sdata, --- struct sta_info *sta, struct sk_buff *skb) --+u16 ieee80211_select_queue(struct ieee80211_sub_if_data *sdata, --+ struct sta_info *sta, struct sk_buff *skb) -- { -- const struct ethhdr *eth = (void *)skb->data; -- struct mac80211_qos_map *qos_map; -- bool qos; -- --+ /* Ensure hash is set prior to potential SW encryption */ --+ skb_get_hash(skb); --+ -- /* all mesh/ocb stations are required to support WME */ -- if ((sdata->vif.type == NL80211_IFTYPE_MESH_POINT && -- !is_multicast_ether_addr(eth->h_dest)) || --@@ -178,59 +184,6 @@ u16 __ieee80211_select_queue(struct ieee -- return ieee80211_downgrade_queue(sdata, sta, skb); -- } -- --- ---/* Indicate which queue to use. */ ---u16 ieee80211_select_queue(struct ieee80211_sub_if_data *sdata, --- struct sk_buff *skb) ---{ --- struct ieee80211_local *local = sdata->local; --- struct sta_info *sta = NULL; --- const u8 *ra = NULL; --- u16 ret; --- --- /* when using iTXQ, we can do this later */ --- if (local->ops->wake_tx_queue) --- return 0; --- --- if (local->hw.queues < IEEE80211_NUM_ACS || skb->len < 6) { --- skb->priority = 0; /* required for correct WPA/11i MIC */ --- return 0; --- } --- --- rcu_read_lock(); --- switch (sdata->vif.type) { --- case NL80211_IFTYPE_AP_VLAN: --- sta = rcu_dereference(sdata->u.vlan.sta); --- if (sta) --- break; --- fallthrough; --- case NL80211_IFTYPE_AP: --- ra = skb->data; --- break; --- case NL80211_IFTYPE_STATION: --- /* might be a TDLS station */ --- sta = sta_info_get(sdata, skb->data); --- if (sta) --- break; --- --- ra = sdata->deflink.u.mgd.bssid; --- break; --- case NL80211_IFTYPE_ADHOC: --- ra = skb->data; --- break; --- default: --- break; --- } --- --- if (!sta && ra && !is_multicast_ether_addr(ra)) --- sta = sta_info_get(sdata, ra); --- --- ret = __ieee80211_select_queue(sdata, sta, skb); --- --- rcu_read_unlock(); --- return ret; ---} --- -- /** -- * ieee80211_set_qos_hdr - Fill in the QoS header if there is one. -- * ----- a/net/mac80211/wme.h --+++ b/net/mac80211/wme.h --@@ -13,10 +13,8 @@ -- u16 ieee80211_select_queue_80211(struct ieee80211_sub_if_data *sdata, -- struct sk_buff *skb, -- struct ieee80211_hdr *hdr); ---u16 __ieee80211_select_queue(struct ieee80211_sub_if_data *sdata, --- struct sta_info *sta, struct sk_buff *skb); -- u16 ieee80211_select_queue(struct ieee80211_sub_if_data *sdata, --- struct sk_buff *skb); --+ struct sta_info *sta, struct sk_buff *skb); -- void ieee80211_set_qos_hdr(struct ieee80211_sub_if_data *sdata, -- struct sk_buff *skb); -- -diff --git a/package/kernel/mac80211/patches/subsys/306-04-v6.2-wifi-realtek-remove-duplicated-wake_tx_queue.patch b/package/kernel/mac80211/patches/subsys/306-04-v6.2-wifi-realtek-remove-duplicated-wake_tx_queue.patch -deleted file mode 100644 -index f0dfc75a78..0000000000 ---- a/package/kernel/mac80211/patches/subsys/306-04-v6.2-wifi-realtek-remove-duplicated-wake_tx_queue.patch -+++ /dev/null -@@ -1,32 +0,0 @@ --From: Johannes Berg --Date: Mon, 10 Oct 2022 19:17:46 +0200 --Subject: [PATCH] wifi: realtek: remove duplicated wake_tx_queue -- --By accident, the previous patch duplicated the initialization --of the wake_tx_queue callback. Fix that by removing the new --initializations. -- --Fixes: a790cc3a4fad ("wifi: mac80211: add wake_tx_queue callback to drivers") --Signed-off-by: Johannes Berg ----- -- ----- a/drivers/net/wireless/realtek/rtw88/mac80211.c --+++ b/drivers/net/wireless/realtek/rtw88/mac80211.c --@@ -896,7 +896,6 @@ static void rtw_ops_sta_rc_update(struct -- -- const struct ieee80211_ops rtw_ops = { -- .tx = rtw_ops_tx, --- .wake_tx_queue = ieee80211_handle_wake_tx_queue, -- .wake_tx_queue = rtw_ops_wake_tx_queue, -- .start = rtw_ops_start, -- .stop = rtw_ops_stop, ----- a/drivers/net/wireless/realtek/rtw89/mac80211.c --+++ b/drivers/net/wireless/realtek/rtw89/mac80211.c --@@ -918,7 +918,6 @@ static int rtw89_ops_set_tid_config(stru -- -- const struct ieee80211_ops rtw89_ops = { -- .tx = rtw89_ops_tx, --- .wake_tx_queue = ieee80211_handle_wake_tx_queue, -- .wake_tx_queue = rtw89_ops_wake_tx_queue, -- .start = rtw89_ops_start, -- .stop = rtw89_ops_stop, -diff --git a/package/kernel/mac80211/patches/subsys/310-v6.2-mac80211-add-support-for-restricting-netdev-features.patch b/package/kernel/mac80211/patches/subsys/310-v6.2-mac80211-add-support-for-restricting-netdev-features.patch -deleted file mode 100644 -index 812b12189c..0000000000 ---- a/package/kernel/mac80211/patches/subsys/310-v6.2-mac80211-add-support-for-restricting-netdev-features.patch -+++ /dev/null -@@ -1,506 +0,0 @@ --From: Felix Fietkau --Date: Sun, 9 Oct 2022 20:15:46 +0200 --Subject: [PATCH] mac80211: add support for restricting netdev features per vif -- --This can be used to selectively disable feature flags for checksum offload, --scatter/gather or GSO by changing vif->netdev_features. --Removing features from vif->netdev_features does not affect the netdev --features themselves, but instead fixes up skbs in the tx path so that the --offloads are not needed in the driver. -- --Aside from making it easier to deal with vif type based hardware limitations, --this also makes it possible to optimize performance on hardware without native --GSO support by declaring GSO support in hw->netdev_features and removing it --from vif->netdev_features. This allows mac80211 to handle GSO segmentation --after the sta lookup, but before itxq enqueue, thus reducing the number of --unnecessary sta lookups, as well as some other per-packet processing. -- --Signed-off-by: Felix Fietkau ----- -- ----- a/include/net/fq_impl.h --+++ b/include/net/fq_impl.h --@@ -200,6 +200,7 @@ static void fq_tin_enqueue(struct fq *fq -- fq_skb_free_t free_func) -- { -- struct fq_flow *flow; --+ struct sk_buff *next; -- bool oom; -- -- lockdep_assert_held(&fq->lock); --@@ -214,11 +215,15 @@ static void fq_tin_enqueue(struct fq *fq -- } -- -- flow->tin = tin; --- flow->backlog += skb->len; --- tin->backlog_bytes += skb->len; --- tin->backlog_packets++; --- fq->memory_usage += skb->truesize; --- fq->backlog++; --+ skb_list_walk_safe(skb, skb, next) { --+ skb_mark_not_on_list(skb); --+ flow->backlog += skb->len; --+ tin->backlog_bytes += skb->len; --+ tin->backlog_packets++; --+ fq->memory_usage += skb->truesize; --+ fq->backlog++; --+ __skb_queue_tail(&flow->queue, skb); --+ } -- -- if (list_empty(&flow->flowchain)) { -- flow->deficit = fq->quantum; --@@ -226,7 +231,6 @@ static void fq_tin_enqueue(struct fq *fq -- &tin->new_flows); -- } -- --- __skb_queue_tail(&flow->queue, skb); -- oom = (fq->memory_usage > fq->memory_limit); -- while (fq->backlog > fq->limit || oom) { -- flow = fq_find_fattest_flow(fq); ----- a/include/net/mac80211.h --+++ b/include/net/mac80211.h --@@ -1807,6 +1807,10 @@ struct ieee80211_vif_cfg { -- * @addr: address of this interface -- * @p2p: indicates whether this AP or STA interface is a p2p -- * interface, i.e. a GO or p2p-sta respectively --+ * @netdev_features: tx netdev features supported by the hardware for this --+ * vif. mac80211 initializes this to hw->netdev_features, and the driver --+ * can mask out specific tx features. mac80211 will handle software fixup --+ * for masked offloads (GSO, CSUM) -- * @driver_flags: flags/capabilities the driver has for this interface, -- * these need to be set (or cleared) when the interface is added -- * or, if supported by the driver, the interface type is changed --@@ -1846,6 +1850,7 @@ struct ieee80211_vif { -- -- struct ieee80211_txq *txq; -- --+ netdev_features_t netdev_features; -- u32 driver_flags; -- u32 offload_flags; -- ----- a/net/mac80211/iface.c --+++ b/net/mac80211/iface.c --@@ -2181,6 +2181,7 @@ int ieee80211_if_add(struct ieee80211_lo -- ndev->priv_flags |= IFF_LIVE_ADDR_CHANGE; -- ndev->hw_features |= ndev->features & -- MAC80211_SUPPORTED_FEATURES_TX; --+ sdata->vif.netdev_features = local->hw.netdev_features; -- -- netdev_set_default_ethtool_ops(ndev, &ieee80211_ethtool_ops); -- ----- a/net/mac80211/tx.c --+++ b/net/mac80211/tx.c --@@ -1356,7 +1356,11 @@ static struct txq_info *ieee80211_get_tx -- -- static void ieee80211_set_skb_enqueue_time(struct sk_buff *skb) -- { --- IEEE80211_SKB_CB(skb)->control.enqueue_time = codel_get_time(); --+ struct sk_buff *next; --+ codel_time_t now = codel_get_time(); --+ --+ skb_list_walk_safe(skb, skb, next) --+ IEEE80211_SKB_CB(skb)->control.enqueue_time = now; -- } -- -- static u32 codel_skb_len_func(const struct sk_buff *skb) --@@ -3579,55 +3583,79 @@ ieee80211_xmit_fast_finish(struct ieee80 -- return TX_CONTINUE; -- } -- ---static bool ieee80211_xmit_fast(struct ieee80211_sub_if_data *sdata, --- struct sta_info *sta, --- struct ieee80211_fast_tx *fast_tx, --- struct sk_buff *skb) --+static netdev_features_t --+ieee80211_sdata_netdev_features(struct ieee80211_sub_if_data *sdata) -- { --- struct ieee80211_local *local = sdata->local; --- u16 ethertype = (skb->data[12] << 8) | skb->data[13]; --- int extra_head = fast_tx->hdr_len - (ETH_HLEN - 2); --- int hw_headroom = sdata->local->hw.extra_tx_headroom; --- struct ethhdr eth; --- struct ieee80211_tx_info *info; --- struct ieee80211_hdr *hdr = (void *)fast_tx->hdr; --- struct ieee80211_tx_data tx; --- ieee80211_tx_result r; --- struct tid_ampdu_tx *tid_tx = NULL; --- u8 tid = IEEE80211_NUM_TIDS; --+ if (sdata->vif.type != NL80211_IFTYPE_AP_VLAN) --+ return sdata->vif.netdev_features; -- --- /* control port protocol needs a lot of special handling */ --- if (cpu_to_be16(ethertype) == sdata->control_port_protocol) --- return false; --+ if (!sdata->bss) --+ return 0; -- --- /* only RFC 1042 SNAP */ --- if (ethertype < ETH_P_802_3_MIN) --- return false; --+ sdata = container_of(sdata->bss, struct ieee80211_sub_if_data, u.ap); --+ return sdata->vif.netdev_features; --+} -- --- /* don't handle TX status request here either */ --- if (skb->sk && skb_shinfo(skb)->tx_flags & SKBTX_WIFI_STATUS) --- return false; --+static struct sk_buff * --+ieee80211_tx_skb_fixup(struct sk_buff *skb, netdev_features_t features) --+{ --+ if (skb_is_gso(skb)) { --+ struct sk_buff *segs; -- --- if (hdr->frame_control & cpu_to_le16(IEEE80211_STYPE_QOS_DATA)) { --- 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)) --- return false; --- if (tid_tx->timeout) --- tid_tx->last_tx = jiffies; --- } --+ segs = skb_gso_segment(skb, features); --+ if (!segs) --+ return skb; --+ if (IS_ERR(segs)) --+ goto free; --+ --+ consume_skb(skb); --+ return segs; -- } -- --- /* after this point (skb is modified) we cannot return false */ --+ if (skb_needs_linearize(skb, features) && __skb_linearize(skb)) --+ goto free; --+ --+ if (skb->ip_summed == CHECKSUM_PARTIAL) { --+ int ofs = skb_checksum_start_offset(skb); --+ --+ if (skb->encapsulation) --+ skb_set_inner_transport_header(skb, ofs); --+ else --+ skb_set_transport_header(skb, ofs); --+ --+ if (skb_csum_hwoffload_help(skb, features)) --+ goto free; --+ } --+ --+ skb_mark_not_on_list(skb); --+ return skb; --+ --+free: --+ kfree_skb(skb); --+ return NULL; --+} --+ --+static void __ieee80211_xmit_fast(struct ieee80211_sub_if_data *sdata, --+ struct sta_info *sta, --+ struct ieee80211_fast_tx *fast_tx, --+ struct sk_buff *skb, u8 tid, bool ampdu) --+{ --+ struct ieee80211_local *local = sdata->local; --+ struct ieee80211_hdr *hdr = (void *)fast_tx->hdr; --+ struct ieee80211_tx_info *info; --+ struct ieee80211_tx_data tx; --+ ieee80211_tx_result r; --+ int hw_headroom = sdata->local->hw.extra_tx_headroom; --+ int extra_head = fast_tx->hdr_len - (ETH_HLEN - 2); --+ struct ethhdr eth; -- -- skb = skb_share_check(skb, GFP_ATOMIC); -- if (unlikely(!skb)) --- return true; --+ return; -- -- if ((hdr->frame_control & cpu_to_le16(IEEE80211_STYPE_QOS_DATA)) && -- ieee80211_amsdu_aggregate(sdata, sta, fast_tx, skb)) --- return true; --+ return; -- -- /* will not be crypto-handled beyond what we do here, so use false -- * as the may-encrypt argument for the resize to not account for --@@ -3636,10 +3664,8 @@ static bool ieee80211_xmit_fast(struct i -- if (unlikely(ieee80211_skb_resize(sdata, skb, -- max_t(int, extra_head + hw_headroom - -- skb_headroom(skb), 0), --- ENCRYPT_NO))) { --- kfree_skb(skb); --- return true; --- } --+ ENCRYPT_NO))) --+ goto free; -- -- memcpy(ð, skb->data, ETH_HLEN - 2); -- hdr = skb_push(skb, extra_head); --@@ -3653,7 +3679,7 @@ static bool ieee80211_xmit_fast(struct i -- info->control.vif = &sdata->vif; -- info->flags = IEEE80211_TX_CTL_FIRST_FRAGMENT | -- IEEE80211_TX_CTL_DONTFRAG | --- (tid_tx ? IEEE80211_TX_CTL_AMPDU : 0); --+ (ampdu ? IEEE80211_TX_CTL_AMPDU : 0); -- info->control.flags = IEEE80211_TX_CTRL_FAST_XMIT | -- u32_encode_bits(IEEE80211_LINK_UNSPECIFIED, -- IEEE80211_TX_CTRL_MLO_LINK); --@@ -3677,16 +3703,14 @@ static bool ieee80211_xmit_fast(struct i -- tx.key = fast_tx->key; -- -- if (ieee80211_queue_skb(local, sdata, sta, skb)) --- return true; --+ return; -- -- tx.skb = skb; -- r = ieee80211_xmit_fast_finish(sdata, sta, fast_tx->pn_offs, -- fast_tx->key, &tx); -- tx.skb = NULL; --- if (r == TX_DROP) { --- kfree_skb(skb); --- return true; --- } --+ if (r == TX_DROP) --+ goto free; -- -- if (sdata->vif.type == NL80211_IFTYPE_AP_VLAN) -- sdata = container_of(sdata->bss, --@@ -3694,6 +3718,56 @@ static bool ieee80211_xmit_fast(struct i -- -- __skb_queue_tail(&tx.skbs, skb); -- ieee80211_tx_frags(local, &sdata->vif, sta, &tx.skbs, false); --+ return; --+ --+free: --+ kfree_skb(skb); --+} --+ --+static bool ieee80211_xmit_fast(struct ieee80211_sub_if_data *sdata, --+ struct sta_info *sta, --+ struct ieee80211_fast_tx *fast_tx, --+ struct sk_buff *skb) --+{ --+ u16 ethertype = (skb->data[12] << 8) | skb->data[13]; --+ struct ieee80211_hdr *hdr = (void *)fast_tx->hdr; --+ struct tid_ampdu_tx *tid_tx = NULL; --+ struct sk_buff *next; --+ u8 tid = IEEE80211_NUM_TIDS; --+ --+ /* control port protocol needs a lot of special handling */ --+ if (cpu_to_be16(ethertype) == sdata->control_port_protocol) --+ return false; --+ --+ /* only RFC 1042 SNAP */ --+ if (ethertype < ETH_P_802_3_MIN) --+ return false; --+ --+ /* don't handle TX status request here either */ --+ if (skb->sk && skb_shinfo(skb)->tx_flags & SKBTX_WIFI_STATUS) --+ return false; --+ --+ if (hdr->frame_control & cpu_to_le16(IEEE80211_STYPE_QOS_DATA)) { --+ 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)) --+ return false; --+ if (tid_tx->timeout) --+ tid_tx->last_tx = jiffies; --+ } --+ } --+ --+ /* after this point (skb is modified) we cannot return false */ --+ skb = ieee80211_tx_skb_fixup(skb, ieee80211_sdata_netdev_features(sdata)); --+ if (!skb) --+ return true; --+ --+ skb_list_walk_safe(skb, skb, next) { --+ skb_mark_not_on_list(skb); --+ __ieee80211_xmit_fast(sdata, sta, fast_tx, skb, tid, tid_tx); --+ } --+ -- return true; -- } -- --@@ -4201,31 +4275,14 @@ void __ieee80211_subif_start_xmit(struct -- goto out; -- } -- --- if (skb_is_gso(skb)) { --- struct sk_buff *segs; --- --- segs = skb_gso_segment(skb, 0); --- if (IS_ERR(segs)) { --- goto out_free; --- } else if (segs) { --- consume_skb(skb); --- skb = segs; --- } --- } else { --- /* we cannot process non-linear frames on this path */ --- if (skb_linearize(skb)) --- goto out_free; --- --- /* the frame could be fragmented, software-encrypted, and other --- * things so we cannot really handle checksum offload with it - --- * fix it up in software before we handle anything else. --- */ --- if (skb->ip_summed == CHECKSUM_PARTIAL) { --- skb_set_transport_header(skb, --- skb_checksum_start_offset(skb)); --- if (skb_checksum_help(skb)) --- goto out_free; --- } --+ /* the frame could be fragmented, software-encrypted, and other --+ * 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); --+ if (!skb) { --+ len = 0; --+ goto out; -- } -- -- skb_list_walk_safe(skb, skb, next) { --@@ -4443,9 +4500,11 @@ normal: -- return NETDEV_TX_OK; -- } -- ---static bool ieee80211_tx_8023(struct ieee80211_sub_if_data *sdata, --- struct sk_buff *skb, struct sta_info *sta, --- bool txpending) --+ --+ --+static bool __ieee80211_tx_8023(struct ieee80211_sub_if_data *sdata, --+ struct sk_buff *skb, struct sta_info *sta, --+ bool txpending) -- { -- struct ieee80211_local *local = sdata->local; -- struct ieee80211_tx_control control = {}; --@@ -4454,14 +4513,6 @@ static bool ieee80211_tx_8023(struct iee -- unsigned long flags; -- int q = info->hw_queue; -- --- if (sta) --- sk_pacing_shift_update(skb->sk, local->hw.tx_sk_pacing_shift); --- --- ieee80211_tpt_led_trig_tx(local, skb->len); --- --- if (ieee80211_queue_skb(local, sdata, sta, skb)) --- return true; --- -- spin_lock_irqsave(&local->queue_stop_reason_lock, flags); -- -- if (local->queue_stop_reasons[q] || --@@ -4488,6 +4539,26 @@ static bool ieee80211_tx_8023(struct iee -- return true; -- } -- --+static bool ieee80211_tx_8023(struct ieee80211_sub_if_data *sdata, --+ struct sk_buff *skb, struct sta_info *sta, --+ bool txpending) --+{ --+ struct ieee80211_local *local = sdata->local; --+ struct sk_buff *next; --+ bool ret = true; --+ --+ if (ieee80211_queue_skb(local, sdata, sta, skb)) --+ return true; --+ --+ skb_list_walk_safe(skb, skb, next) { --+ skb_mark_not_on_list(skb); --+ if (!__ieee80211_tx_8023(sdata, skb, sta, txpending)) --+ ret = false; --+ } --+ --+ return ret; --+} --+ -- 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) --@@ -4495,9 +4566,13 @@ static void ieee80211_8023_xmit(struct i -- struct ieee80211_tx_info *info; -- 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; -- u8 tid; -- --- skb_set_queue_mapping(skb, ieee80211_select_queue(sdata, sta, skb)); --+ queue = ieee80211_select_queue(sdata, sta, skb); --+ skb_set_queue_mapping(skb, queue); -- -- if (unlikely(test_bit(SCAN_SW_SCANNING, &local->scanning)) && -- test_bit(SDATA_STATE_OFFCHANNEL, &sdata->state)) --@@ -4507,9 +4582,6 @@ static void ieee80211_8023_xmit(struct i -- if (unlikely(!skb)) -- return; -- --- info = IEEE80211_SKB_CB(skb); --- memset(info, 0, sizeof(*info)); --- -- ieee80211_aggr_check(sdata, sta, skb); -- -- tid = skb->priority & IEEE80211_QOS_CTL_TAG1D_MASK; --@@ -4523,22 +4595,20 @@ static void ieee80211_8023_xmit(struct i -- return; -- } -- --- info->flags |= IEEE80211_TX_CTL_AMPDU; -- if (tid_tx->timeout) -- tid_tx->last_tx = jiffies; -- } -- --- 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); --+ skb = ieee80211_tx_skb_fixup(skb, ieee80211_sdata_netdev_features(sdata)); --+ if (!skb) --+ return; -- --- info->hw_queue = sdata->vif.hw_queue[skb_get_queue_mapping(skb)]; --+ info = IEEE80211_SKB_CB(skb); --+ memset(info, 0, sizeof(*info)); --+ if (tid_tx) --+ info->flags |= IEEE80211_TX_CTL_AMPDU; -- --- dev_sw_netstats_tx_add(dev, 1, skb->len); --- --- sta->deflink.tx_stats.bytes[skb_get_queue_mapping(skb)] += skb->len; --- sta->deflink.tx_stats.packets[skb_get_queue_mapping(skb)]++; --+ info->hw_queue = sdata->vif.hw_queue[queue]; -- -- if (sdata->vif.type == NL80211_IFTYPE_AP_VLAN) -- sdata = container_of(sdata->bss, --@@ -4550,6 +4620,24 @@ static void ieee80211_8023_xmit(struct i -- if (key) -- info->control.hw_key = &key->conf; -- --+ skb_list_walk_safe(skb, seg, next) { --+ skbs++; --+ len += seg->len; --+ if (seg != skb) --+ memcpy(IEEE80211_SKB_CB(seg), info, 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); --+ --+ dev_sw_netstats_tx_add(dev, skbs, len); --+ sta->deflink.tx_stats.packets[queue] += skbs; --+ sta->deflink.tx_stats.bytes[queue] += len; --+ --+ ieee80211_tpt_led_trig_tx(local, len); --+ -- ieee80211_tx_8023(sdata, skb, sta, false); -- -- return; --@@ -4591,6 +4679,7 @@ netdev_tx_t ieee80211_subif_start_xmit_8 -- key->conf.cipher == WLAN_CIPHER_SUITE_TKIP)) -- goto skip_offload; -- --+ sk_pacing_shift_update(skb->sk, sdata->local->hw.tx_sk_pacing_shift); -- ieee80211_8023_xmit(sdata, dev, sta, key, skb); -- goto out; -- -diff --git a/package/kernel/mac80211/patches/subsys/311-v6.2-wifi-mac80211-fix-and-simplify-unencrypted-drop-chec.patch b/package/kernel/mac80211/patches/subsys/311-v6.2-wifi-mac80211-fix-and-simplify-unencrypted-drop-chec.patch -deleted file mode 100644 -index 804b02eb30..0000000000 ---- a/package/kernel/mac80211/patches/subsys/311-v6.2-wifi-mac80211-fix-and-simplify-unencrypted-drop-chec.patch -+++ /dev/null -@@ -1,87 +0,0 @@ --From: Felix Fietkau --Date: Thu, 1 Dec 2022 14:57:30 +0100 --Subject: [PATCH] wifi: mac80211: fix and simplify unencrypted drop check for -- mesh -- --ieee80211_drop_unencrypted is called from ieee80211_rx_h_mesh_fwding and --ieee80211_frame_allowed. -- --Since ieee80211_rx_h_mesh_fwding can forward packets for other mesh nodes --and is called earlier, it needs to check the decryptions status and if the --packet is using the control protocol on its own, instead of deferring to --the later call from ieee80211_frame_allowed. -- --Because of that, ieee80211_drop_unencrypted has a mesh specific check --that skips over the mesh header in order to check the payload protocol. --This code is invalid when called from ieee80211_frame_allowed, since that --happens after the 802.11->802.3 conversion. -- --Fix this by moving the mesh specific check directly into --ieee80211_rx_h_mesh_fwding. -- --Signed-off-by: Felix Fietkau --Link: https://lore.kernel.org/r/20221201135730.19723-1-nbd@nbd.name --Signed-off-by: Johannes Berg ----- -- ----- a/net/mac80211/rx.c --+++ b/net/mac80211/rx.c --@@ -2403,7 +2403,6 @@ static int ieee80211_802_1x_port_control -- -- static int ieee80211_drop_unencrypted(struct ieee80211_rx_data *rx, __le16 fc) -- { --- struct ieee80211_hdr *hdr = (void *)rx->skb->data; -- struct sk_buff *skb = rx->skb; -- struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb); -- --@@ -2414,31 +2413,6 @@ static int ieee80211_drop_unencrypted(st -- if (status->flag & RX_FLAG_DECRYPTED) -- return 0; -- --- /* check mesh EAPOL frames first */ --- if (unlikely(rx->sta && ieee80211_vif_is_mesh(&rx->sdata->vif) && --- ieee80211_is_data(fc))) { --- struct ieee80211s_hdr *mesh_hdr; --- u16 hdr_len = ieee80211_hdrlen(fc); --- u16 ethertype_offset; --- __be16 ethertype; --- --- if (!ether_addr_equal(hdr->addr1, rx->sdata->vif.addr)) --- goto drop_check; --- --- /* make sure fixed part of mesh header is there, also checks skb len */ --- if (!pskb_may_pull(rx->skb, hdr_len + 6)) --- goto drop_check; --- --- mesh_hdr = (struct ieee80211s_hdr *)(skb->data + hdr_len); --- ethertype_offset = hdr_len + ieee80211_get_mesh_hdrlen(mesh_hdr) + --- sizeof(rfc1042_header); --- --- if (skb_copy_bits(rx->skb, ethertype_offset, ðertype, 2) == 0 && --- ethertype == rx->sdata->control_port_protocol) --- return 0; --- } --- ---drop_check: -- /* Drop unencrypted frames if key is set. */ -- if (unlikely(!ieee80211_has_protected(fc) && -- !ieee80211_is_any_nullfunc(fc) && --@@ -2892,8 +2866,16 @@ ieee80211_rx_h_mesh_fwding(struct ieee80 -- hdr = (struct ieee80211_hdr *) skb->data; -- mesh_hdr = (struct ieee80211s_hdr *) (skb->data + hdrlen); -- --- if (ieee80211_drop_unencrypted(rx, hdr->frame_control)) --- return RX_DROP_MONITOR; --+ if (ieee80211_drop_unencrypted(rx, hdr->frame_control)) { --+ int offset = hdrlen + ieee80211_get_mesh_hdrlen(mesh_hdr) + --+ sizeof(rfc1042_header); --+ __be16 ethertype; --+ --+ if (!ether_addr_equal(hdr->addr1, rx->sdata->vif.addr) || --+ skb_copy_bits(rx->skb, offset, ðertype, 2) != 0 || --+ ethertype != rx->sdata->control_port_protocol) --+ return RX_DROP_MONITOR; --+ } -- -- /* frame is in RMC, don't forward */ -- if (ieee80211_is_data(hdr->frame_control) && -diff --git a/package/kernel/mac80211/patches/subsys/312-v6.3-wifi-cfg80211-move-A-MSDU-check-in-ieee80211_data_to.patch b/package/kernel/mac80211/patches/subsys/312-v6.3-wifi-cfg80211-move-A-MSDU-check-in-ieee80211_data_to.patch -deleted file mode 100644 -index f668905cca..0000000000 ---- a/package/kernel/mac80211/patches/subsys/312-v6.3-wifi-cfg80211-move-A-MSDU-check-in-ieee80211_data_to.patch -+++ /dev/null -@@ -1,25 +0,0 @@ --From: Felix Fietkau --Date: Fri, 2 Dec 2022 13:53:11 +0100 --Subject: [PATCH] wifi: cfg80211: move A-MSDU check in -- ieee80211_data_to_8023_exthdr -- --When parsing the outer A-MSDU header, don't check for inner bridge tunnel --or RFC1042 headers. This is handled by ieee80211_amsdu_to_8023s already. -- --Signed-off-by: Felix Fietkau ----- -- ----- a/net/wireless/util.c --+++ b/net/wireless/util.c --@@ -631,8 +631,9 @@ int ieee80211_data_to_8023_exthdr(struct -- break; -- } -- --- if (likely(skb_copy_bits(skb, hdrlen, &payload, sizeof(payload)) == 0 && --- ((!is_amsdu && ether_addr_equal(payload.hdr, rfc1042_header) && --+ if (likely(!is_amsdu && --+ skb_copy_bits(skb, hdrlen, &payload, sizeof(payload)) == 0 && --+ ((ether_addr_equal(payload.hdr, rfc1042_header) && -- payload.proto != htons(ETH_P_AARP) && -- payload.proto != htons(ETH_P_IPX)) || -- ether_addr_equal(payload.hdr, bridge_tunnel_header)))) { -diff --git a/package/kernel/mac80211/patches/subsys/313-v6.3-wifi-cfg80211-factor-out-bridge-tunnel-RFC1042-heade.patch b/package/kernel/mac80211/patches/subsys/313-v6.3-wifi-cfg80211-factor-out-bridge-tunnel-RFC1042-heade.patch -deleted file mode 100644 -index 8641057869..0000000000 ---- a/package/kernel/mac80211/patches/subsys/313-v6.3-wifi-cfg80211-factor-out-bridge-tunnel-RFC1042-heade.patch -+++ /dev/null -@@ -1,76 +0,0 @@ --From: Felix Fietkau --Date: Fri, 2 Dec 2022 13:54:15 +0100 --Subject: [PATCH] wifi: cfg80211: factor out bridge tunnel / RFC1042 header -- check -- --The same check is done in multiple places, unify it. -- --Signed-off-by: Felix Fietkau ----- -- ----- a/net/wireless/util.c --+++ b/net/wireless/util.c --@@ -542,6 +542,21 @@ unsigned int ieee80211_get_mesh_hdrlen(s -- } -- EXPORT_SYMBOL(ieee80211_get_mesh_hdrlen); -- --+static bool ieee80211_get_8023_tunnel_proto(const void *hdr, __be16 *proto) --+{ --+ const __be16 *hdr_proto = hdr + ETH_ALEN; --+ --+ if (!(ether_addr_equal(hdr, rfc1042_header) && --+ *hdr_proto != htons(ETH_P_AARP) && --+ *hdr_proto != htons(ETH_P_IPX)) && --+ !ether_addr_equal(hdr, bridge_tunnel_header)) --+ return false; --+ --+ *proto = *hdr_proto; --+ --+ return true; --+} --+ -- int ieee80211_data_to_8023_exthdr(struct sk_buff *skb, struct ethhdr *ehdr, -- const u8 *addr, enum nl80211_iftype iftype, -- u8 data_offset, bool is_amsdu) --@@ -633,14 +648,9 @@ int ieee80211_data_to_8023_exthdr(struct -- -- if (likely(!is_amsdu && -- skb_copy_bits(skb, hdrlen, &payload, sizeof(payload)) == 0 && --- ((ether_addr_equal(payload.hdr, rfc1042_header) && --- payload.proto != htons(ETH_P_AARP) && --- payload.proto != htons(ETH_P_IPX)) || --- ether_addr_equal(payload.hdr, bridge_tunnel_header)))) { --- /* remove RFC1042 or Bridge-Tunnel encapsulation and --- * replace EtherType */ --+ ieee80211_get_8023_tunnel_proto(&payload, &tmp.h_proto))) { --+ /* remove RFC1042 or Bridge-Tunnel encapsulation */ -- hdrlen += ETH_ALEN + 2; --- tmp.h_proto = payload.proto; -- skb_postpull_rcsum(skb, &payload, ETH_ALEN + 2); -- } else { -- tmp.h_proto = htons(skb->len - hdrlen); --@@ -756,8 +766,6 @@ void ieee80211_amsdu_to_8023s(struct sk_ -- { -- unsigned int hlen = ALIGN(extra_headroom, 4); -- struct sk_buff *frame = NULL; --- u16 ethertype; --- u8 *payload; -- int offset = 0, remaining; -- struct ethhdr eth; -- bool reuse_frag = skb->head_frag && !skb_has_frag_list(skb); --@@ -811,14 +819,8 @@ void ieee80211_amsdu_to_8023s(struct sk_ -- frame->dev = skb->dev; -- frame->priority = skb->priority; -- --- payload = frame->data; --- ethertype = (payload[6] << 8) | payload[7]; --- if (likely((ether_addr_equal(payload, rfc1042_header) && --- ethertype != ETH_P_AARP && ethertype != ETH_P_IPX) || --- ether_addr_equal(payload, bridge_tunnel_header))) { --- eth.h_proto = htons(ethertype); --+ if (likely(ieee80211_get_8023_tunnel_proto(frame->data, ð.h_proto))) -- skb_pull(frame, ETH_ALEN + 2); --- } -- -- memcpy(skb_push(frame, sizeof(eth)), ð, sizeof(eth)); -- __skb_queue_tail(list, frame); -diff --git a/package/kernel/mac80211/patches/subsys/314-v6.3-wifi-mac80211-remove-mesh-forwarding-congestion-chec.patch b/package/kernel/mac80211/patches/subsys/314-v6.3-wifi-mac80211-remove-mesh-forwarding-congestion-chec.patch -deleted file mode 100644 -index 515176f0de..0000000000 ---- a/package/kernel/mac80211/patches/subsys/314-v6.3-wifi-mac80211-remove-mesh-forwarding-congestion-chec.patch -+++ /dev/null -@@ -1,54 +0,0 @@ --From: Felix Fietkau --Date: Fri, 2 Dec 2022 17:01:46 +0100 --Subject: [PATCH] wifi: mac80211: remove mesh forwarding congestion check -- --Now that all drivers use iTXQ, it does not make sense to check to drop --tx forwarding packets when the driver has stopped the queues. --fq_codel will take care of dropping packets when the queues fill up -- --Signed-off-by: Felix Fietkau ----- -- ----- a/net/mac80211/debugfs_netdev.c --+++ b/net/mac80211/debugfs_netdev.c --@@ -603,8 +603,6 @@ IEEE80211_IF_FILE(fwded_mcast, u.mesh.ms -- IEEE80211_IF_FILE(fwded_unicast, u.mesh.mshstats.fwded_unicast, DEC); -- IEEE80211_IF_FILE(fwded_frames, u.mesh.mshstats.fwded_frames, DEC); -- IEEE80211_IF_FILE(dropped_frames_ttl, u.mesh.mshstats.dropped_frames_ttl, DEC); ---IEEE80211_IF_FILE(dropped_frames_congestion, --- u.mesh.mshstats.dropped_frames_congestion, DEC); -- IEEE80211_IF_FILE(dropped_frames_no_route, -- u.mesh.mshstats.dropped_frames_no_route, DEC); -- --@@ -740,7 +738,6 @@ static void add_mesh_stats(struct ieee80 -- MESHSTATS_ADD(fwded_frames); -- MESHSTATS_ADD(dropped_frames_ttl); -- MESHSTATS_ADD(dropped_frames_no_route); --- MESHSTATS_ADD(dropped_frames_congestion); -- #undef MESHSTATS_ADD -- } -- ----- a/net/mac80211/ieee80211_i.h --+++ b/net/mac80211/ieee80211_i.h --@@ -329,7 +329,6 @@ struct mesh_stats { -- __u32 fwded_frames; /* Mesh total forwarded frames */ -- __u32 dropped_frames_ttl; /* Not transmitted since mesh_ttl == 0*/ -- __u32 dropped_frames_no_route; /* Not transmitted, no route found */ --- __u32 dropped_frames_congestion;/* Not forwarded due to congestion */ -- }; -- -- #define PREQ_Q_F_START 0x1 ----- a/net/mac80211/rx.c --+++ b/net/mac80211/rx.c --@@ -2926,11 +2926,6 @@ ieee80211_rx_h_mesh_fwding(struct ieee80 -- return RX_CONTINUE; -- -- ac = ieee802_1d_to_ac[skb->priority]; --- q = sdata->vif.hw_queue[ac]; --- if (ieee80211_queue_stopped(&local->hw, q)) { --- IEEE80211_IFSTA_MESH_CTR_INC(ifmsh, dropped_frames_congestion); --- return RX_DROP_MONITOR; --- } -- skb_set_queue_mapping(skb, ac); -- -- if (!--mesh_hdr->ttl) { -diff --git a/package/kernel/mac80211/patches/subsys/315-v6.3-wifi-mac80211-fix-receiving-A-MSDU-frames-on-mesh-in.patch b/package/kernel/mac80211/patches/subsys/315-v6.3-wifi-mac80211-fix-receiving-A-MSDU-frames-on-mesh-in.patch -deleted file mode 100644 -index 6aec9bc85f..0000000000 ---- a/package/kernel/mac80211/patches/subsys/315-v6.3-wifi-mac80211-fix-receiving-A-MSDU-frames-on-mesh-in.patch -+++ /dev/null -@@ -1,753 +0,0 @@ --From: Felix Fietkau --Date: Tue, 6 Dec 2022 11:15:02 +0100 --Subject: [PATCH] wifi: mac80211: fix receiving A-MSDU frames on mesh -- interfaces -- --The current mac80211 mesh A-MSDU receive path fails to parse A-MSDU packets --on mesh interfaces, because it assumes that the Mesh Control field is always --directly after the 802.11 header. --802.11-2020 9.3.2.2.2 Figure 9-70 shows that the Mesh Control field is --actually part of the A-MSDU subframe header. --This makes more sense, since it allows packets for multiple different --destinations to be included in the same A-MSDU, as long as RA and TID are --still the same. --Another issue is the fact that the A-MSDU subframe length field was apparently --accidentally defined as little-endian in the standard. -- --In order to fix this, the mesh forwarding path needs happen at a different --point in the receive path. -- --ieee80211_data_to_8023_exthdr is changed to ignore the mesh control field --and leave it in after the ethernet header. This also affects the source/dest --MAC address fields, which now in the case of mesh point to the mesh SA/DA. -- --ieee80211_amsdu_to_8023s is changed to deal with the endian difference and --to add the Mesh Control length to the subframe length, since it's not covered --by the MSDU length field. -- --With these changes, the mac80211 will get the same packet structure for --converted regular data packets and unpacked A-MSDU subframes. -- --The mesh forwarding checks are now only performed after the A-MSDU decap. --For locally received packets, the Mesh Control header is stripped away. --For forwarded packets, a new 802.11 header gets added. -- --Signed-off-by: Felix Fietkau ----- -- ----- a/drivers/net/wireless/marvell/mwifiex/11n_rxreorder.c --+++ b/drivers/net/wireless/marvell/mwifiex/11n_rxreorder.c --@@ -33,7 +33,7 @@ static int mwifiex_11n_dispatch_amsdu_pk -- skb_trim(skb, le16_to_cpu(local_rx_pd->rx_pkt_length)); -- -- ieee80211_amsdu_to_8023s(skb, &list, priv->curr_addr, --- priv->wdev.iftype, 0, NULL, NULL); --+ priv->wdev.iftype, 0, NULL, NULL, false); -- -- while (!skb_queue_empty(&list)) { -- struct rx_packet_hdr *rx_hdr; ----- a/include/net/cfg80211.h --+++ b/include/net/cfg80211.h --@@ -6208,11 +6208,36 @@ static inline int ieee80211_data_to_8023 -- * @extra_headroom: The hardware extra headroom for SKBs in the @list. -- * @check_da: DA to check in the inner ethernet header, or NULL -- * @check_sa: SA to check in the inner ethernet header, or NULL --+ * @mesh_control: A-MSDU subframe header includes the mesh control field -- */ -- void ieee80211_amsdu_to_8023s(struct sk_buff *skb, struct sk_buff_head *list, -- const u8 *addr, enum nl80211_iftype iftype, -- const unsigned int extra_headroom, --- const u8 *check_da, const u8 *check_sa); --+ const u8 *check_da, const u8 *check_sa, --+ bool mesh_control); --+ --+/** --+ * ieee80211_get_8023_tunnel_proto - get RFC1042 or bridge tunnel encap protocol --+ * --+ * Check for RFC1042 or bridge tunnel header and fetch the encapsulated --+ * protocol. --+ * --+ * @hdr: pointer to the MSDU payload --+ * @proto: destination pointer to store the protocol --+ * Return: true if encapsulation was found --+ */ --+bool ieee80211_get_8023_tunnel_proto(const void *hdr, __be16 *proto); --+ --+/** --+ * ieee80211_strip_8023_mesh_hdr - strip mesh header from converted 802.3 frames --+ * --+ * Strip the mesh header, which was left in by ieee80211_data_to_8023 as part --+ * of the MSDU data. Also move any source/destination addresses from the mesh --+ * header to the ethernet header (if present). --+ * --+ * @skb: The 802.3 frame with embedded mesh header --+ */ --+int ieee80211_strip_8023_mesh_hdr(struct sk_buff *skb); -- -- /** -- * cfg80211_classify8021d - determine the 802.1p/1d tag for a data frame ----- a/net/mac80211/rx.c --+++ b/net/mac80211/rx.c --@@ -2720,6 +2720,174 @@ ieee80211_deliver_skb(struct ieee80211_r -- } -- } -- --+static ieee80211_rx_result --+ieee80211_rx_mesh_data(struct ieee80211_sub_if_data *sdata, struct sta_info *sta, --+ struct sk_buff *skb) --+{ --+#ifdef CPTCFG_MAC80211_MESH --+ struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh; --+ struct ieee80211_local *local = sdata->local; --+ uint16_t fc = IEEE80211_FTYPE_DATA | IEEE80211_STYPE_QOS_DATA; --+ struct ieee80211_hdr hdr = { --+ .frame_control = cpu_to_le16(fc) --+ }; --+ struct ieee80211_hdr *fwd_hdr; --+ struct ieee80211s_hdr *mesh_hdr; --+ struct ieee80211_tx_info *info; --+ struct sk_buff *fwd_skb; --+ struct ethhdr *eth; --+ bool multicast; --+ int tailroom = 0; --+ int hdrlen, mesh_hdrlen; --+ u8 *qos; --+ --+ if (!ieee80211_vif_is_mesh(&sdata->vif)) --+ return RX_CONTINUE; --+ --+ if (!pskb_may_pull(skb, sizeof(*eth) + 6)) --+ return RX_DROP_MONITOR; --+ --+ mesh_hdr = (struct ieee80211s_hdr *)(skb->data + sizeof(*eth)); --+ mesh_hdrlen = ieee80211_get_mesh_hdrlen(mesh_hdr); --+ --+ if (!pskb_may_pull(skb, sizeof(*eth) + mesh_hdrlen)) --+ return RX_DROP_MONITOR; --+ --+ eth = (struct ethhdr *)skb->data; --+ multicast = is_multicast_ether_addr(eth->h_dest); --+ --+ mesh_hdr = (struct ieee80211s_hdr *)(eth + 1); --+ if (!mesh_hdr->ttl) --+ return RX_DROP_MONITOR; --+ --+ /* frame is in RMC, don't forward */ --+ if (is_multicast_ether_addr(eth->h_dest) && --+ mesh_rmc_check(sdata, eth->h_source, mesh_hdr)) --+ return RX_DROP_MONITOR; --+ --+ /* Frame has reached destination. Don't forward */ --+ if (ether_addr_equal(sdata->vif.addr, eth->h_dest)) --+ goto rx_accept; --+ --+ if (!ifmsh->mshcfg.dot11MeshForwarding) { --+ if (is_multicast_ether_addr(eth->h_dest)) --+ goto rx_accept; --+ --+ return RX_DROP_MONITOR; --+ } --+ --+ /* forward packet */ --+ if (sdata->crypto_tx_tailroom_needed_cnt) --+ tailroom = IEEE80211_ENCRYPT_TAILROOM; --+ --+ if (!--mesh_hdr->ttl) { --+ if (multicast) --+ goto rx_accept; --+ --+ IEEE80211_IFSTA_MESH_CTR_INC(ifmsh, dropped_frames_ttl); --+ return RX_DROP_MONITOR; --+ } --+ --+ if (mesh_hdr->flags & MESH_FLAGS_AE) { --+ struct mesh_path *mppath; --+ char *proxied_addr; --+ --+ if (multicast) --+ proxied_addr = mesh_hdr->eaddr1; --+ else if ((mesh_hdr->flags & MESH_FLAGS_AE) == MESH_FLAGS_AE_A5_A6) --+ /* has_a4 already checked in ieee80211_rx_mesh_check */ --+ proxied_addr = mesh_hdr->eaddr2; --+ else --+ return RX_DROP_MONITOR; --+ --+ rcu_read_lock(); --+ mppath = mpp_path_lookup(sdata, proxied_addr); --+ if (!mppath) { --+ mpp_path_add(sdata, proxied_addr, eth->h_source); --+ } else { --+ spin_lock_bh(&mppath->state_lock); --+ if (!ether_addr_equal(mppath->mpp, eth->h_source)) --+ memcpy(mppath->mpp, eth->h_source, ETH_ALEN); --+ mppath->exp_time = jiffies; --+ spin_unlock_bh(&mppath->state_lock); --+ } --+ rcu_read_unlock(); --+ } --+ --+ skb_set_queue_mapping(skb, ieee802_1d_to_ac[skb->priority]); --+ --+ ieee80211_fill_mesh_addresses(&hdr, &hdr.frame_control, --+ eth->h_dest, eth->h_source); --+ hdrlen = ieee80211_hdrlen(hdr.frame_control); --+ if (multicast) { --+ int extra_head = sizeof(struct ieee80211_hdr) - sizeof(*eth); --+ --+ fwd_skb = skb_copy_expand(skb, local->tx_headroom + extra_head + --+ IEEE80211_ENCRYPT_HEADROOM, --+ tailroom, GFP_ATOMIC); --+ if (!fwd_skb) --+ goto rx_accept; --+ } else { --+ fwd_skb = skb; --+ skb = NULL; --+ --+ if (skb_cow_head(fwd_skb, hdrlen - sizeof(struct ethhdr))) --+ return RX_DROP_UNUSABLE; --+ } --+ --+ fwd_hdr = skb_push(fwd_skb, hdrlen - sizeof(struct ethhdr)); --+ memcpy(fwd_hdr, &hdr, hdrlen - 2); --+ qos = ieee80211_get_qos_ctl(fwd_hdr); --+ qos[0] = qos[1] = 0; --+ --+ skb_reset_mac_header(fwd_skb); --+ hdrlen += mesh_hdrlen; --+ if (ieee80211_get_8023_tunnel_proto(fwd_skb->data + hdrlen, --+ &fwd_skb->protocol)) --+ hdrlen += ETH_ALEN; --+ else --+ fwd_skb->protocol = htons(fwd_skb->len - hdrlen); --+ skb_set_network_header(fwd_skb, hdrlen); --+ --+ info = IEEE80211_SKB_CB(fwd_skb); --+ memset(info, 0, sizeof(*info)); --+ info->control.flags |= IEEE80211_TX_INTCFL_NEED_TXPROCESSING; --+ info->control.vif = &sdata->vif; --+ info->control.jiffies = jiffies; --+ if (multicast) { --+ IEEE80211_IFSTA_MESH_CTR_INC(ifmsh, fwded_mcast); --+ memcpy(fwd_hdr->addr2, sdata->vif.addr, ETH_ALEN); --+ /* update power mode indication when forwarding */ --+ ieee80211_mps_set_frame_flags(sdata, NULL, fwd_hdr); --+ } else if (!mesh_nexthop_lookup(sdata, fwd_skb)) { --+ /* mesh power mode flags updated in mesh_nexthop_lookup */ --+ IEEE80211_IFSTA_MESH_CTR_INC(ifmsh, fwded_unicast); --+ } else { --+ /* unable to resolve next hop */ --+ if (sta) --+ mesh_path_error_tx(sdata, ifmsh->mshcfg.element_ttl, --+ hdr.addr3, 0, --+ WLAN_REASON_MESH_PATH_NOFORWARD, --+ sta->sta.addr); --+ IEEE80211_IFSTA_MESH_CTR_INC(ifmsh, dropped_frames_no_route); --+ kfree_skb(fwd_skb); --+ goto rx_accept; --+ } --+ --+ IEEE80211_IFSTA_MESH_CTR_INC(ifmsh, fwded_frames); --+ fwd_skb->dev = sdata->dev; --+ ieee80211_add_pending_skb(local, fwd_skb); --+ --+rx_accept: --+ if (!skb) --+ return RX_QUEUED; --+ --+ ieee80211_strip_8023_mesh_hdr(skb); --+#endif --+ --+ return RX_CONTINUE; --+} --+ -- static ieee80211_rx_result debug_noinline -- __ieee80211_rx_h_amsdu(struct ieee80211_rx_data *rx, u8 data_offset) -- { --@@ -2728,8 +2896,10 @@ __ieee80211_rx_h_amsdu(struct ieee80211_ -- struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; -- __le16 fc = hdr->frame_control; -- struct sk_buff_head frame_list; --+ static ieee80211_rx_result res; -- struct ethhdr ethhdr; -- const u8 *check_da = ethhdr.h_dest, *check_sa = ethhdr.h_source; --+ bool mesh = false; -- -- if (unlikely(ieee80211_has_a4(hdr->frame_control))) { -- check_da = NULL; --@@ -2746,6 +2916,8 @@ __ieee80211_rx_h_amsdu(struct ieee80211_ -- break; -- case NL80211_IFTYPE_MESH_POINT: -- check_sa = NULL; --+ check_da = NULL; --+ mesh = true; -- break; -- default: -- break; --@@ -2763,17 +2935,29 @@ __ieee80211_rx_h_amsdu(struct ieee80211_ -- ieee80211_amsdu_to_8023s(skb, &frame_list, dev->dev_addr, -- rx->sdata->vif.type, -- rx->local->hw.extra_tx_headroom, --- check_da, check_sa); --+ check_da, check_sa, mesh); -- -- while (!skb_queue_empty(&frame_list)) { -- rx->skb = __skb_dequeue(&frame_list); -- --- if (!ieee80211_frame_allowed(rx, fc)) { --- dev_kfree_skb(rx->skb); --+ res = ieee80211_rx_mesh_data(rx->sdata, rx->sta, rx->skb); --+ switch (res) { --+ case RX_QUEUED: -- continue; --+ case RX_CONTINUE: --+ break; --+ default: --+ goto free; -- } -- --+ if (!ieee80211_frame_allowed(rx, fc)) --+ goto free; --+ -- ieee80211_deliver_skb(rx); --+ continue; --+ --+free: --+ dev_kfree_skb(rx->skb); -- } -- -- return RX_QUEUED; --@@ -2806,6 +2990,8 @@ ieee80211_rx_h_amsdu(struct ieee80211_rx -- if (!rx->sdata->u.mgd.use_4addr) -- return RX_DROP_UNUSABLE; -- break; --+ case NL80211_IFTYPE_MESH_POINT: --+ break; -- default: -- return RX_DROP_UNUSABLE; -- } --@@ -2834,155 +3020,6 @@ ieee80211_rx_h_amsdu(struct ieee80211_rx -- return __ieee80211_rx_h_amsdu(rx, 0); -- } -- ---#ifdef CPTCFG_MAC80211_MESH ---static ieee80211_rx_result ---ieee80211_rx_h_mesh_fwding(struct ieee80211_rx_data *rx) ---{ --- struct ieee80211_hdr *fwd_hdr, *hdr; --- struct ieee80211_tx_info *info; --- struct ieee80211s_hdr *mesh_hdr; --- struct sk_buff *skb = rx->skb, *fwd_skb; --- struct ieee80211_local *local = rx->local; --- struct ieee80211_sub_if_data *sdata = rx->sdata; --- struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh; --- u16 ac, q, hdrlen; --- int tailroom = 0; --- --- hdr = (struct ieee80211_hdr *) skb->data; --- hdrlen = ieee80211_hdrlen(hdr->frame_control); --- --- /* make sure fixed part of mesh header is there, also checks skb len */ --- if (!pskb_may_pull(rx->skb, hdrlen + 6)) --- return RX_DROP_MONITOR; --- --- mesh_hdr = (struct ieee80211s_hdr *) (skb->data + hdrlen); --- --- /* make sure full mesh header is there, also checks skb len */ --- if (!pskb_may_pull(rx->skb, --- hdrlen + ieee80211_get_mesh_hdrlen(mesh_hdr))) --- return RX_DROP_MONITOR; --- --- /* reload pointers */ --- hdr = (struct ieee80211_hdr *) skb->data; --- mesh_hdr = (struct ieee80211s_hdr *) (skb->data + hdrlen); --- --- if (ieee80211_drop_unencrypted(rx, hdr->frame_control)) { --- int offset = hdrlen + ieee80211_get_mesh_hdrlen(mesh_hdr) + --- sizeof(rfc1042_header); --- __be16 ethertype; --- --- if (!ether_addr_equal(hdr->addr1, rx->sdata->vif.addr) || --- skb_copy_bits(rx->skb, offset, ðertype, 2) != 0 || --- ethertype != rx->sdata->control_port_protocol) --- return RX_DROP_MONITOR; --- } --- --- /* frame is in RMC, don't forward */ --- if (ieee80211_is_data(hdr->frame_control) && --- is_multicast_ether_addr(hdr->addr1) && --- mesh_rmc_check(rx->sdata, hdr->addr3, mesh_hdr)) --- return RX_DROP_MONITOR; --- --- if (!ieee80211_is_data(hdr->frame_control)) --- return RX_CONTINUE; --- --- if (!mesh_hdr->ttl) --- return RX_DROP_MONITOR; --- --- if (mesh_hdr->flags & MESH_FLAGS_AE) { --- struct mesh_path *mppath; --- char *proxied_addr; --- char *mpp_addr; --- --- if (is_multicast_ether_addr(hdr->addr1)) { --- mpp_addr = hdr->addr3; --- proxied_addr = mesh_hdr->eaddr1; --- } else if ((mesh_hdr->flags & MESH_FLAGS_AE) == --- MESH_FLAGS_AE_A5_A6) { --- /* has_a4 already checked in ieee80211_rx_mesh_check */ --- mpp_addr = hdr->addr4; --- proxied_addr = mesh_hdr->eaddr2; --- } else { --- return RX_DROP_MONITOR; --- } --- --- 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)) --- memcpy(mppath->mpp, mpp_addr, ETH_ALEN); --- mppath->exp_time = jiffies; --- spin_unlock_bh(&mppath->state_lock); --- } --- rcu_read_unlock(); --- } --- --- /* Frame has reached destination. Don't forward */ --- if (!is_multicast_ether_addr(hdr->addr1) && --- ether_addr_equal(sdata->vif.addr, hdr->addr3)) --- return RX_CONTINUE; --- --- ac = ieee802_1d_to_ac[skb->priority]; --- skb_set_queue_mapping(skb, ac); --- --- if (!--mesh_hdr->ttl) { --- if (!is_multicast_ether_addr(hdr->addr1)) --- IEEE80211_IFSTA_MESH_CTR_INC(ifmsh, --- dropped_frames_ttl); --- goto out; --- } --- --- if (!ifmsh->mshcfg.dot11MeshForwarding) --- goto out; --- --- if (sdata->crypto_tx_tailroom_needed_cnt) --- tailroom = IEEE80211_ENCRYPT_TAILROOM; --- --- fwd_skb = skb_copy_expand(skb, local->tx_headroom + --- IEEE80211_ENCRYPT_HEADROOM, --- tailroom, GFP_ATOMIC); --- if (!fwd_skb) --- goto out; --- --- fwd_skb->dev = sdata->dev; --- fwd_hdr = (struct ieee80211_hdr *) fwd_skb->data; --- fwd_hdr->frame_control &= ~cpu_to_le16(IEEE80211_FCTL_RETRY); --- info = IEEE80211_SKB_CB(fwd_skb); --- memset(info, 0, sizeof(*info)); --- info->control.flags |= IEEE80211_TX_INTCFL_NEED_TXPROCESSING; --- info->control.vif = &rx->sdata->vif; --- info->control.jiffies = jiffies; --- if (is_multicast_ether_addr(fwd_hdr->addr1)) { --- IEEE80211_IFSTA_MESH_CTR_INC(ifmsh, fwded_mcast); --- memcpy(fwd_hdr->addr2, sdata->vif.addr, ETH_ALEN); --- /* update power mode indication when forwarding */ --- ieee80211_mps_set_frame_flags(sdata, NULL, fwd_hdr); --- } else if (!mesh_nexthop_lookup(sdata, fwd_skb)) { --- /* mesh power mode flags updated in mesh_nexthop_lookup */ --- IEEE80211_IFSTA_MESH_CTR_INC(ifmsh, fwded_unicast); --- } else { --- /* unable to resolve next hop */ --- mesh_path_error_tx(sdata, ifmsh->mshcfg.element_ttl, --- fwd_hdr->addr3, 0, --- WLAN_REASON_MESH_PATH_NOFORWARD, --- fwd_hdr->addr2); --- IEEE80211_IFSTA_MESH_CTR_INC(ifmsh, dropped_frames_no_route); --- kfree_skb(fwd_skb); --- return RX_DROP_MONITOR; --- } --- --- IEEE80211_IFSTA_MESH_CTR_INC(ifmsh, fwded_frames); --- ieee80211_add_pending_skb(local, fwd_skb); --- out: --- if (is_multicast_ether_addr(hdr->addr1)) --- return RX_CONTINUE; --- return RX_DROP_MONITOR; ---} ---#endif --- -- static ieee80211_rx_result debug_noinline -- ieee80211_rx_h_data(struct ieee80211_rx_data *rx) -- { --@@ -2991,6 +3028,7 @@ ieee80211_rx_h_data(struct ieee80211_rx_ -- struct net_device *dev = sdata->dev; -- struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)rx->skb->data; -- __le16 fc = hdr->frame_control; --+ static ieee80211_rx_result res; -- bool port_control; -- int err; -- --@@ -3017,6 +3055,10 @@ ieee80211_rx_h_data(struct ieee80211_rx_ -- if (unlikely(err)) -- return RX_DROP_UNUSABLE; -- --+ res = ieee80211_rx_mesh_data(rx->sdata, rx->sta, rx->skb); --+ if (res != RX_CONTINUE) --+ return res; --+ -- if (!ieee80211_frame_allowed(rx, fc)) -- return RX_DROP_MONITOR; -- --@@ -3987,10 +4029,6 @@ static void ieee80211_rx_handlers(struct -- CALL_RXH(ieee80211_rx_h_defragment); -- CALL_RXH(ieee80211_rx_h_michael_mic_verify); -- /* must be after MMIC verify so header is counted in MPDU mic */ ---#ifdef CPTCFG_MAC80211_MESH --- if (ieee80211_vif_is_mesh(&rx->sdata->vif)) --- CALL_RXH(ieee80211_rx_h_mesh_fwding); ---#endif -- CALL_RXH(ieee80211_rx_h_amsdu); -- CALL_RXH(ieee80211_rx_h_data); -- ----- a/net/wireless/util.c --+++ b/net/wireless/util.c --@@ -542,7 +542,7 @@ unsigned int ieee80211_get_mesh_hdrlen(s -- } -- EXPORT_SYMBOL(ieee80211_get_mesh_hdrlen); -- ---static bool ieee80211_get_8023_tunnel_proto(const void *hdr, __be16 *proto) --+bool ieee80211_get_8023_tunnel_proto(const void *hdr, __be16 *proto) -- { -- const __be16 *hdr_proto = hdr + ETH_ALEN; -- --@@ -556,6 +556,49 @@ static bool ieee80211_get_8023_tunnel_pr -- -- return true; -- } --+EXPORT_SYMBOL(ieee80211_get_8023_tunnel_proto); --+ --+int ieee80211_strip_8023_mesh_hdr(struct sk_buff *skb) --+{ --+ const void *mesh_addr; --+ struct { --+ struct ethhdr eth; --+ u8 flags; --+ } payload; --+ int hdrlen; --+ int ret; --+ --+ ret = skb_copy_bits(skb, 0, &payload, sizeof(payload)); --+ if (ret) --+ return ret; --+ --+ hdrlen = sizeof(payload.eth) + __ieee80211_get_mesh_hdrlen(payload.flags); --+ --+ if (likely(pskb_may_pull(skb, hdrlen + 8) && --+ ieee80211_get_8023_tunnel_proto(skb->data + hdrlen, --+ &payload.eth.h_proto))) --+ hdrlen += ETH_ALEN + 2; --+ else if (!pskb_may_pull(skb, hdrlen)) --+ return -EINVAL; --+ --+ mesh_addr = skb->data + sizeof(payload.eth) + ETH_ALEN; --+ switch (payload.flags & MESH_FLAGS_AE) { --+ case MESH_FLAGS_AE_A4: --+ memcpy(&payload.eth.h_source, mesh_addr, ETH_ALEN); --+ break; --+ case MESH_FLAGS_AE_A5_A6: --+ memcpy(&payload.eth.h_dest, mesh_addr, 2 * ETH_ALEN); --+ break; --+ default: --+ break; --+ } --+ --+ pskb_pull(skb, hdrlen - sizeof(payload.eth)); --+ memcpy(skb->data, &payload.eth, sizeof(payload.eth)); --+ --+ return 0; --+} --+EXPORT_SYMBOL(ieee80211_strip_8023_mesh_hdr); -- -- int ieee80211_data_to_8023_exthdr(struct sk_buff *skb, struct ethhdr *ehdr, -- const u8 *addr, enum nl80211_iftype iftype, --@@ -568,7 +611,6 @@ int ieee80211_data_to_8023_exthdr(struct -- } payload; -- struct ethhdr tmp; -- u16 hdrlen; --- u8 mesh_flags = 0; -- -- if (unlikely(!ieee80211_is_data_present(hdr->frame_control))) -- return -1; --@@ -589,12 +631,6 @@ int ieee80211_data_to_8023_exthdr(struct -- memcpy(tmp.h_dest, ieee80211_get_DA(hdr), ETH_ALEN); -- memcpy(tmp.h_source, ieee80211_get_SA(hdr), ETH_ALEN); -- --- if (iftype == NL80211_IFTYPE_MESH_POINT && --- skb_copy_bits(skb, hdrlen, &mesh_flags, 1) < 0) --- return -1; --- --- mesh_flags &= MESH_FLAGS_AE; --- -- switch (hdr->frame_control & -- cpu_to_le16(IEEE80211_FCTL_TODS | IEEE80211_FCTL_FROMDS)) { -- case cpu_to_le16(IEEE80211_FCTL_TODS): --@@ -608,17 +644,6 @@ int ieee80211_data_to_8023_exthdr(struct -- iftype != NL80211_IFTYPE_AP_VLAN && -- iftype != NL80211_IFTYPE_STATION)) -- return -1; --- if (iftype == NL80211_IFTYPE_MESH_POINT) { --- if (mesh_flags == MESH_FLAGS_AE_A4) --- return -1; --- if (mesh_flags == MESH_FLAGS_AE_A5_A6 && --- skb_copy_bits(skb, hdrlen + --- offsetof(struct ieee80211s_hdr, eaddr1), --- tmp.h_dest, 2 * ETH_ALEN) < 0) --- return -1; --- --- hdrlen += __ieee80211_get_mesh_hdrlen(mesh_flags); --- } -- break; -- case cpu_to_le16(IEEE80211_FCTL_FROMDS): -- if ((iftype != NL80211_IFTYPE_STATION && --@@ -627,16 +652,6 @@ int ieee80211_data_to_8023_exthdr(struct -- (is_multicast_ether_addr(tmp.h_dest) && -- ether_addr_equal(tmp.h_source, addr))) -- return -1; --- if (iftype == NL80211_IFTYPE_MESH_POINT) { --- if (mesh_flags == MESH_FLAGS_AE_A5_A6) --- return -1; --- if (mesh_flags == MESH_FLAGS_AE_A4 && --- skb_copy_bits(skb, hdrlen + --- offsetof(struct ieee80211s_hdr, eaddr1), --- tmp.h_source, ETH_ALEN) < 0) --- return -1; --- hdrlen += __ieee80211_get_mesh_hdrlen(mesh_flags); --- } -- break; -- case cpu_to_le16(0): -- if (iftype != NL80211_IFTYPE_ADHOC && --@@ -646,7 +661,7 @@ int ieee80211_data_to_8023_exthdr(struct -- break; -- } -- --- if (likely(!is_amsdu && --+ if (likely(!is_amsdu && iftype != NL80211_IFTYPE_MESH_POINT && -- skb_copy_bits(skb, hdrlen, &payload, sizeof(payload)) == 0 && -- ieee80211_get_8023_tunnel_proto(&payload, &tmp.h_proto))) { -- /* remove RFC1042 or Bridge-Tunnel encapsulation */ --@@ -722,7 +737,8 @@ __ieee80211_amsdu_copy_frag(struct sk_bu -- -- static struct sk_buff * -- __ieee80211_amsdu_copy(struct sk_buff *skb, unsigned int hlen, --- int offset, int len, bool reuse_frag) --+ int offset, int len, bool reuse_frag, --+ int min_len) -- { -- struct sk_buff *frame; -- int cur_len = len; --@@ -736,7 +752,7 @@ __ieee80211_amsdu_copy(struct sk_buff *s -- * in the stack later. -- */ -- if (reuse_frag) --- cur_len = min_t(int, len, 32); --+ cur_len = min_t(int, len, min_len); -- -- /* -- * Allocate and reserve two bytes more for payload --@@ -746,6 +762,7 @@ __ieee80211_amsdu_copy(struct sk_buff *s -- if (!frame) -- return NULL; -- --+ frame->priority = skb->priority; -- skb_reserve(frame, hlen + sizeof(struct ethhdr) + 2); -- skb_copy_bits(skb, offset, skb_put(frame, cur_len), cur_len); -- --@@ -762,23 +779,37 @@ __ieee80211_amsdu_copy(struct sk_buff *s -- void ieee80211_amsdu_to_8023s(struct sk_buff *skb, struct sk_buff_head *list, -- const u8 *addr, enum nl80211_iftype iftype, -- const unsigned int extra_headroom, --- const u8 *check_da, const u8 *check_sa) --+ const u8 *check_da, const u8 *check_sa, --+ bool mesh_control) -- { -- unsigned int hlen = ALIGN(extra_headroom, 4); -- struct sk_buff *frame = NULL; -- int offset = 0, remaining; --- struct ethhdr eth; --+ struct { --+ struct ethhdr eth; --+ uint8_t flags; --+ } hdr; -- bool reuse_frag = skb->head_frag && !skb_has_frag_list(skb); -- bool reuse_skb = false; -- bool last = false; --+ int copy_len = sizeof(hdr.eth); --+ --+ if (iftype == NL80211_IFTYPE_MESH_POINT) --+ copy_len = sizeof(hdr); -- -- while (!last) { -- unsigned int subframe_len; --- int len; --+ int len, mesh_len = 0; -- u8 padding; -- --- skb_copy_bits(skb, offset, ð, sizeof(eth)); --- len = ntohs(eth.h_proto); --+ skb_copy_bits(skb, offset, &hdr, copy_len); --+ if (iftype == NL80211_IFTYPE_MESH_POINT) --+ mesh_len = __ieee80211_get_mesh_hdrlen(hdr.flags); --+ if (mesh_control) --+ len = le16_to_cpu(*(__le16 *)&hdr.eth.h_proto) + mesh_len; --+ else --+ len = ntohs(hdr.eth.h_proto); --+ -- subframe_len = sizeof(struct ethhdr) + len; -- padding = (4 - subframe_len) & 0x3; -- --@@ -787,16 +818,16 @@ void ieee80211_amsdu_to_8023s(struct sk_ -- if (subframe_len > remaining) -- goto purge; -- /* mitigate A-MSDU aggregation injection attacks */ --- if (ether_addr_equal(eth.h_dest, rfc1042_header)) --+ if (ether_addr_equal(hdr.eth.h_dest, rfc1042_header)) -- goto purge; -- -- offset += sizeof(struct ethhdr); -- last = remaining <= subframe_len + padding; -- -- /* FIXME: should we really accept multicast DA? */ --- if ((check_da && !is_multicast_ether_addr(eth.h_dest) && --- !ether_addr_equal(check_da, eth.h_dest)) || --- (check_sa && !ether_addr_equal(check_sa, eth.h_source))) { --+ if ((check_da && !is_multicast_ether_addr(hdr.eth.h_dest) && --+ !ether_addr_equal(check_da, hdr.eth.h_dest)) || --+ (check_sa && !ether_addr_equal(check_sa, hdr.eth.h_source))) { -- offset += len + padding; -- continue; -- } --@@ -808,7 +839,7 @@ void ieee80211_amsdu_to_8023s(struct sk_ -- reuse_skb = true; -- } else { -- frame = __ieee80211_amsdu_copy(skb, hlen, offset, len, --- reuse_frag); --+ reuse_frag, 32 + mesh_len); -- if (!frame) -- goto purge; -- --@@ -819,10 +850,11 @@ void ieee80211_amsdu_to_8023s(struct sk_ -- frame->dev = skb->dev; -- frame->priority = skb->priority; -- --- if (likely(ieee80211_get_8023_tunnel_proto(frame->data, ð.h_proto))) --+ if (likely(iftype != NL80211_IFTYPE_MESH_POINT && --+ ieee80211_get_8023_tunnel_proto(frame->data, &hdr.eth.h_proto))) -- skb_pull(frame, ETH_ALEN + 2); -- --- memcpy(skb_push(frame, sizeof(eth)), ð, sizeof(eth)); --+ memcpy(skb_push(frame, sizeof(hdr.eth)), &hdr.eth, sizeof(hdr.eth)); -- __skb_queue_tail(list, frame); -- } -- -diff --git a/package/kernel/mac80211/patches/subsys/316-v6.3-wifi-mac80211-add-a-workaround-for-receiving-non-sta.patch b/package/kernel/mac80211/patches/subsys/316-v6.3-wifi-mac80211-add-a-workaround-for-receiving-non-sta.patch -deleted file mode 100644 -index 6dc98ae16a..0000000000 ---- a/package/kernel/mac80211/patches/subsys/316-v6.3-wifi-mac80211-add-a-workaround-for-receiving-non-sta.patch -+++ /dev/null -@@ -1,145 +0,0 @@ --From: Felix Fietkau --Date: Fri, 9 Dec 2022 21:15:04 +0100 --Subject: [PATCH] wifi: mac80211: add a workaround for receiving -- non-standard mesh A-MSDU -- --At least ath10k and ath11k supported hardware (maybe more) does not implement --mesh A-MSDU aggregation in a standard compliant way. --802.11-2020 9.3.2.2.2 declares that the Mesh Control field is part of the --A-MSDU header. As such, its length must not be included in the subframe --length field. --Hardware affected by this bug treats the mesh control field as part of the --MSDU data and sets the length accordingly. --In order to avoid packet loss, keep track of which stations are affected --by this and take it into account when converting A-MSDU to 802.3 + mesh control --packets. -- --Signed-off-by: Felix Fietkau ----- -- ----- a/include/net/cfg80211.h --+++ b/include/net/cfg80211.h --@@ -6194,6 +6194,19 @@ static inline int ieee80211_data_to_8023 -- } -- -- /** --+ * ieee80211_is_valid_amsdu - check if subframe lengths of an A-MSDU are valid --+ * --+ * This is used to detect non-standard A-MSDU frames, e.g. the ones generated --+ * by ath10k and ath11k, where the subframe length includes the length of the --+ * mesh control field. --+ * --+ * @skb: The input A-MSDU frame without any headers. --+ * @mesh_hdr: use standard compliant mesh A-MSDU subframe header --+ * Returns: true if subframe header lengths are valid for the @mesh_hdr mode --+ */ --+bool ieee80211_is_valid_amsdu(struct sk_buff *skb, bool mesh_hdr); --+ --+/** -- * ieee80211_amsdu_to_8023s - decode an IEEE 802.11n A-MSDU frame -- * -- * Decode an IEEE 802.11 A-MSDU and convert it to a list of 802.3 frames. ----- a/net/mac80211/rx.c --+++ b/net/mac80211/rx.c --@@ -2899,7 +2899,6 @@ __ieee80211_rx_h_amsdu(struct ieee80211_ -- static ieee80211_rx_result res; -- struct ethhdr ethhdr; -- const u8 *check_da = ethhdr.h_dest, *check_sa = ethhdr.h_source; --- bool mesh = false; -- -- if (unlikely(ieee80211_has_a4(hdr->frame_control))) { -- check_da = NULL; --@@ -2917,7 +2916,6 @@ __ieee80211_rx_h_amsdu(struct ieee80211_ -- case NL80211_IFTYPE_MESH_POINT: -- check_sa = NULL; -- check_da = NULL; --- mesh = true; -- break; -- default: -- break; --@@ -2932,10 +2930,21 @@ __ieee80211_rx_h_amsdu(struct ieee80211_ -- data_offset, true)) -- return RX_DROP_UNUSABLE; -- --+ if (rx->sta && rx->sta->amsdu_mesh_control < 0) { --+ bool valid_std = ieee80211_is_valid_amsdu(skb, true); --+ bool valid_nonstd = ieee80211_is_valid_amsdu(skb, false); --+ --+ if (valid_std && !valid_nonstd) --+ rx->sta->amsdu_mesh_control = 1; --+ else if (valid_nonstd && !valid_std) --+ rx->sta->amsdu_mesh_control = 0; --+ } --+ -- ieee80211_amsdu_to_8023s(skb, &frame_list, dev->dev_addr, -- rx->sdata->vif.type, -- rx->local->hw.extra_tx_headroom, --- check_da, check_sa, mesh); --+ check_da, check_sa, --+ rx->sta->amsdu_mesh_control); -- -- while (!skb_queue_empty(&frame_list)) { -- rx->skb = __skb_dequeue(&frame_list); ----- a/net/mac80211/sta_info.c --+++ b/net/mac80211/sta_info.c --@@ -591,6 +591,9 @@ __sta_info_alloc(struct ieee80211_sub_if -- -- sta->sta_state = IEEE80211_STA_NONE; -- --+ if (sdata->vif.type == NL80211_IFTYPE_MESH_POINT) --+ sta->amsdu_mesh_control = -1; --+ -- /* Mark TID as unreserved */ -- sta->reserved_tid = IEEE80211_TID_UNRESERVED; -- ----- a/net/mac80211/sta_info.h --+++ b/net/mac80211/sta_info.h --@@ -702,6 +702,7 @@ struct sta_info { -- struct codel_params cparams; -- -- u8 reserved_tid; --+ s8 amsdu_mesh_control; -- -- struct cfg80211_chan_def tdls_chandef; -- ----- a/net/wireless/util.c --+++ b/net/wireless/util.c --@@ -776,6 +776,38 @@ __ieee80211_amsdu_copy(struct sk_buff *s -- return frame; -- } -- --+bool ieee80211_is_valid_amsdu(struct sk_buff *skb, bool mesh_hdr) --+{ --+ int offset = 0, remaining, subframe_len, padding; --+ --+ for (offset = 0; offset < skb->len; offset += subframe_len + padding) { --+ struct { --+ __be16 len; --+ u8 mesh_flags; --+ } hdr; --+ u16 len; --+ --+ if (skb_copy_bits(skb, offset + 2 * ETH_ALEN, &hdr, sizeof(hdr)) < 0) --+ return false; --+ --+ if (mesh_hdr) --+ len = le16_to_cpu(*(__le16 *)&hdr.len) + --+ __ieee80211_get_mesh_hdrlen(hdr.mesh_flags); --+ else --+ len = ntohs(hdr.len); --+ --+ subframe_len = sizeof(struct ethhdr) + len; --+ padding = (4 - subframe_len) & 0x3; --+ remaining = skb->len - offset; --+ --+ if (subframe_len > remaining) --+ return false; --+ } --+ --+ return true; --+} --+EXPORT_SYMBOL(ieee80211_is_valid_amsdu); --+ -- void ieee80211_amsdu_to_8023s(struct sk_buff *skb, struct sk_buff_head *list, -- const u8 *addr, enum nl80211_iftype iftype, -- const unsigned int extra_headroom, -diff --git a/package/kernel/mac80211/patches/subsys/318-wifi-mac80211-fix-race-in-mesh-sequence-number-assig.patch b/package/kernel/mac80211/patches/subsys/318-wifi-mac80211-fix-race-in-mesh-sequence-number-assig.patch -deleted file mode 100644 -index 7d01ffdfff..0000000000 ---- a/package/kernel/mac80211/patches/subsys/318-wifi-mac80211-fix-race-in-mesh-sequence-number-assig.patch -+++ /dev/null -@@ -1,37 +0,0 @@ --From: Felix Fietkau --Date: Wed, 15 Feb 2023 15:21:37 +0100 --Subject: [PATCH] wifi: mac80211: fix race in mesh sequence number -- assignment -- --Since the sequence number is shared across different tx queues, it needs --to be atomic in order to avoid accidental duplicate assignment -- --Signed-off-by: Felix Fietkau ----- -- ----- a/net/mac80211/ieee80211_i.h --+++ b/net/mac80211/ieee80211_i.h --@@ -696,7 +696,7 @@ struct ieee80211_if_mesh { -- struct mesh_stats mshstats; -- struct mesh_config mshcfg; -- atomic_t estab_plinks; --- u32 mesh_seqnum; --+ atomic_t mesh_seqnum; -- bool accepting_plinks; -- int num_gates; -- struct beacon_data __rcu *beacon; ----- a/net/mac80211/mesh.c --+++ b/net/mac80211/mesh.c --@@ -752,10 +752,8 @@ unsigned int ieee80211_new_mesh_header(s -- -- meshhdr->ttl = sdata->u.mesh.mshcfg.dot11MeshTTL; -- --- /* FIXME: racy -- TX on multiple queues can be concurrent */ --- put_unaligned(cpu_to_le32(sdata->u.mesh.mesh_seqnum), &meshhdr->seqnum); --- sdata->u.mesh.mesh_seqnum++; --- --+ put_unaligned_le32(atomic_inc_return(&sdata->u.mesh.mesh_seqnum), --+ &meshhdr->seqnum); -- if (addr4or5 && !addr6) { -- meshhdr->flags |= MESH_FLAGS_AE_A4; -- memcpy(meshhdr->eaddr1, addr4or5, ETH_ALEN); -diff --git a/package/kernel/mac80211/patches/subsys/319-wifi-mac80211-mesh-fast-xmit-support.patch b/package/kernel/mac80211/patches/subsys/319-wifi-mac80211-mesh-fast-xmit-support.patch -deleted file mode 100644 -index 968d2885f2..0000000000 ---- a/package/kernel/mac80211/patches/subsys/319-wifi-mac80211-mesh-fast-xmit-support.patch -+++ /dev/null -@@ -1,850 +0,0 @@ --From: Felix Fietkau --Date: Sun, 26 Feb 2023 13:53:08 +0100 --Subject: [PATCH] wifi: mac80211: mesh fast xmit support -- --Previously, fast xmit only worked on interface types where initially a --sta lookup is performed, and a cached header can be attached to the sta, --requiring only some fields to be updated at runtime. -- --This technique is not directly applicable for a mesh device type due --to the dynamic nature of the topology and protocol. There are more --addresses that need to be filled, and there is an extra header with a --dynamic length based on the addressing mode. -- --Change the code to cache entries contain a copy of the mesh subframe header + --bridge tunnel header, as well as an embedded struct ieee80211_fast_tx, which --contains the information for building the 802.11 header. -- --Add a mesh specific early fast xmit call, which looks up a cached entry and --adds only the mesh subframe header, before passing it over to the generic --fast xmit code. -- --To ensure the changes in network are reflected in these cached headers, --flush affected cached entries on path changes, as well as other conditions --that currently trigger a fast xmit check in other modes (key changes etc.) -- --This code is loosely based on a previous implementation by: --Sriram R -- --Signed-off-by: Ryder Lee --Signed-off-by: Felix Fietkau ----- -- ----- a/net/mac80211/ieee80211_i.h --+++ b/net/mac80211/ieee80211_i.h --@@ -37,6 +37,7 @@ -- extern const struct cfg80211_ops mac80211_config_ops; -- -- struct ieee80211_local; --+struct ieee80211_mesh_fast_tx; -- -- /* Maximum number of broadcast/multicast frames to buffer when some of the -- * associated stations are using power saving. */ --@@ -656,6 +657,19 @@ struct mesh_table { -- atomic_t entries; /* Up to MAX_MESH_NEIGHBOURS */ -- }; -- --+/** --+ * struct mesh_tx_cache - mesh fast xmit header cache --+ * --+ * @rht: hash table containing struct ieee80211_mesh_fast_tx, using skb DA as key --+ * @walk_head: linked list containing all ieee80211_mesh_fast_tx objects --+ * @walk_lock: lock protecting walk_head and rht --+ */ --+struct mesh_tx_cache { --+ struct rhashtable rht; --+ struct hlist_head walk_head; --+ spinlock_t walk_lock; --+}; --+ -- struct ieee80211_if_mesh { -- struct timer_list housekeeping_timer; -- struct timer_list mesh_path_timer; --@@ -734,6 +748,7 @@ struct ieee80211_if_mesh { -- struct mesh_table mpp_paths; /* Store paths for MPP&MAP */ -- int mesh_paths_generation; -- int mpp_paths_generation; --+ struct mesh_tx_cache tx_cache; -- }; -- -- #ifdef CPTCFG_MAC80211_MESH --@@ -2002,6 +2017,11 @@ int ieee80211_tx_control_port(struct wip -- int link_id, u64 *cookie); -- int ieee80211_probe_mesh_link(struct wiphy *wiphy, struct net_device *dev, -- const u8 *buf, size_t len); --+void __ieee80211_xmit_fast(struct ieee80211_sub_if_data *sdata, --+ struct sta_info *sta, --+ struct ieee80211_fast_tx *fast_tx, --+ struct sk_buff *skb, bool ampdu, --+ const u8 *da, const u8 *sa); -- -- /* HT */ -- void ieee80211_apply_htcap_overrides(struct ieee80211_sub_if_data *sdata, ----- a/net/mac80211/mesh.c --+++ b/net/mac80211/mesh.c --@@ -10,6 +10,7 @@ -- #include -- #include "ieee80211_i.h" -- #include "mesh.h" --+#include "wme.h" -- #include "driver-ops.h" -- -- static int mesh_allocated; --@@ -698,6 +699,95 @@ ieee80211_mesh_update_bss_params(struct -- __le32_to_cpu(he_oper->he_oper_params); -- } -- --+bool ieee80211_mesh_xmit_fast(struct ieee80211_sub_if_data *sdata, --+ struct sk_buff *skb, u32 ctrl_flags) --+{ --+ struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh; --+ struct ieee80211_mesh_fast_tx *entry; --+ struct ieee80211s_hdr *meshhdr; --+ u8 sa[ETH_ALEN] __aligned(2); --+ struct tid_ampdu_tx *tid_tx; --+ struct sta_info *sta; --+ bool copy_sa = false; --+ u16 ethertype; --+ u8 tid; --+ --+ if (ctrl_flags & IEEE80211_TX_CTRL_SKIP_MPATH_LOOKUP) --+ return false; --+ --+ if (ifmsh->mshcfg.dot11MeshNolearn) --+ return false; --+ --+ /* Add support for these cases later */ --+ if (ifmsh->ps_peers_light_sleep || ifmsh->ps_peers_deep_sleep) --+ return false; --+ --+ if (is_multicast_ether_addr(skb->data)) --+ return false; --+ --+ ethertype = (skb->data[12] << 8) | skb->data[13]; --+ if (ethertype < ETH_P_802_3_MIN) --+ return false; --+ --+ if (skb->sk && skb_shinfo(skb)->tx_flags & SKBTX_WIFI_STATUS) --+ return false; --+ --+ if (skb->ip_summed == CHECKSUM_PARTIAL) { --+ skb_set_transport_header(skb, skb_checksum_start_offset(skb)); --+ if (skb_checksum_help(skb)) --+ return false; --+ } --+ --+ entry = mesh_fast_tx_get(sdata, skb->data); --+ if (!entry) --+ return false; --+ --+ if (skb_headroom(skb) < entry->hdrlen + entry->fast_tx.hdr_len) --+ return false; --+ --+ sta = rcu_dereference(entry->mpath->next_hop); --+ if (!sta) --+ return false; --+ --+ 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)) --+ return false; --+ if (tid_tx->timeout) --+ tid_tx->last_tx = jiffies; --+ } --+ --+ skb = skb_share_check(skb, GFP_ATOMIC); --+ if (!skb) --+ return true; --+ --+ 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) { --+ /* preserve SA from eth header for 6-addr frames */ --+ ether_addr_copy(sa, skb->data + ETH_ALEN); --+ copy_sa = true; --+ } --+ --+ memcpy(skb_push(skb, entry->hdrlen - 2 * ETH_ALEN), entry->hdr, --+ entry->hdrlen); --+ --+ meshhdr = (struct ieee80211s_hdr *)skb->data; --+ put_unaligned_le32(atomic_inc_return(&sdata->u.mesh.mesh_seqnum), --+ &meshhdr->seqnum); --+ meshhdr->ttl = sdata->u.mesh.mshcfg.dot11MeshTTL; --+ if (copy_sa) --+ ether_addr_copy(meshhdr->eaddr2, sa); --+ --+ skb_push(skb, 2 * ETH_ALEN); --+ __ieee80211_xmit_fast(sdata, sta, &entry->fast_tx, skb, tid_tx, --+ entry->mpath->dst, sdata->vif.addr); --+ --+ return true; --+} --+ -- /** -- * ieee80211_fill_mesh_addresses - fill addresses of a locally originated mesh frame -- * @hdr: 802.11 frame header --@@ -780,6 +870,8 @@ static void ieee80211_mesh_housekeeping( -- changed = mesh_accept_plinks_update(sdata); -- ieee80211_mbss_info_change_notify(sdata, changed); -- --+ mesh_fast_tx_gc(sdata); --+ -- mod_timer(&ifmsh->housekeeping_timer, -- round_jiffies(jiffies + -- IEEE80211_MESH_HOUSEKEEPING_INTERVAL)); ----- a/net/mac80211/mesh.h --+++ b/net/mac80211/mesh.h --@@ -122,11 +122,41 @@ struct mesh_path { -- u8 rann_snd_addr[ETH_ALEN]; -- u32 rann_metric; -- unsigned long last_preq_to_root; --+ unsigned long fast_tx_check; -- bool is_root; -- bool is_gate; -- u32 path_change_count; -- }; -- --+#define MESH_FAST_TX_CACHE_MAX_SIZE 512 --+#define MESH_FAST_TX_CACHE_THRESHOLD_SIZE 384 --+#define MESH_FAST_TX_CACHE_TIMEOUT 8000 /* msecs */ --+ --+/** --+ * struct ieee80211_mesh_fast_tx - cached mesh fast tx entry --+ * @rhash: rhashtable pointer --+ * @addr_key: The Ethernet DA which is the key for this entry --+ * @fast_tx: base fast_tx data --+ * @hdr: cached mesh and rfc1042 headers --+ * @hdrlen: length of mesh + rfc1042 --+ * @walk_list: list containing all the fast tx entries --+ * @mpath: mesh path corresponding to the Mesh DA --+ * @mppath: MPP entry corresponding to this DA --+ * @timestamp: Last used time of this entry --+ */ --+struct ieee80211_mesh_fast_tx { --+ struct rhash_head rhash; --+ u8 addr_key[ETH_ALEN] __aligned(2); --+ --+ struct ieee80211_fast_tx fast_tx; --+ u8 hdr[sizeof(struct ieee80211s_hdr) + sizeof(rfc1042_header)]; --+ u16 hdrlen; --+ --+ struct mesh_path *mpath, *mppath; --+ struct hlist_node walk_list; --+ unsigned long timestamp; --+}; --+ -- /* Recent multicast cache */ -- /* RMC_BUCKETS must be a power of 2, maximum 256 */ -- #define RMC_BUCKETS 256 --@@ -298,6 +328,20 @@ 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); --+struct ieee80211_mesh_fast_tx * --+mesh_fast_tx_get(struct ieee80211_sub_if_data *sdata, const u8 *addr); --+bool ieee80211_mesh_xmit_fast(struct ieee80211_sub_if_data *sdata, --+ struct sk_buff *skb, u32 ctrl_flags); --+void mesh_fast_tx_cache(struct ieee80211_sub_if_data *sdata, --+ struct sk_buff *skb, struct mesh_path *mpath); --+void mesh_fast_tx_gc(struct ieee80211_sub_if_data *sdata); --+void mesh_fast_tx_flush_addr(struct ieee80211_sub_if_data *sdata, --+ const u8 *addr); --+void mesh_fast_tx_flush_mpath(struct mesh_path *mpath); --+void mesh_fast_tx_flush_sta(struct ieee80211_sub_if_data *sdata, --+ struct sta_info *sta); --+void mesh_path_refresh(struct ieee80211_sub_if_data *sdata, --+ struct mesh_path *mpath, const u8 *addr); -- -- #ifdef CPTCFG_MAC80211_MESH -- static inline ----- a/net/mac80211/mesh_hwmp.c --+++ b/net/mac80211/mesh_hwmp.c --@@ -394,6 +394,7 @@ static u32 hwmp_route_info_get(struct ie -- u32 orig_sn, orig_metric; -- unsigned long orig_lifetime, exp_time; -- u32 last_hop_metric, new_metric; --+ bool flush_mpath = false; -- bool process = true; -- u8 hopcount; -- --@@ -491,8 +492,10 @@ static u32 hwmp_route_info_get(struct ie -- } -- -- if (fresh_info) { --- if (rcu_access_pointer(mpath->next_hop) != sta) --+ if (rcu_access_pointer(mpath->next_hop) != sta) { -- mpath->path_change_count++; --+ flush_mpath = true; --+ } -- mesh_path_assign_nexthop(mpath, sta); -- mpath->flags |= MESH_PATH_SN_VALID; -- mpath->metric = new_metric; --@@ -502,6 +505,8 @@ static u32 hwmp_route_info_get(struct ie -- mpath->hop_count = hopcount; -- mesh_path_activate(mpath); -- spin_unlock_bh(&mpath->state_lock); --+ if (flush_mpath) --+ mesh_fast_tx_flush_mpath(mpath); -- ewma_mesh_fail_avg_init(&sta->mesh->fail_avg); -- /* init it at a low value - 0 start is tricky */ -- ewma_mesh_fail_avg_add(&sta->mesh->fail_avg, 1); --@@ -539,8 +544,10 @@ static u32 hwmp_route_info_get(struct ie -- } -- -- if (fresh_info) { --- if (rcu_access_pointer(mpath->next_hop) != sta) --+ if (rcu_access_pointer(mpath->next_hop) != sta) { -- mpath->path_change_count++; --+ flush_mpath = true; --+ } -- mesh_path_assign_nexthop(mpath, sta); -- mpath->metric = last_hop_metric; -- mpath->exp_time = time_after(mpath->exp_time, exp_time) --@@ -548,6 +555,8 @@ static u32 hwmp_route_info_get(struct ie -- mpath->hop_count = 1; -- mesh_path_activate(mpath); -- spin_unlock_bh(&mpath->state_lock); --+ if (flush_mpath) --+ mesh_fast_tx_flush_mpath(mpath); -- ewma_mesh_fail_avg_init(&sta->mesh->fail_avg); -- /* init it at a low value - 0 start is tricky */ -- ewma_mesh_fail_avg_add(&sta->mesh->fail_avg, 1); --@@ -1215,6 +1224,20 @@ static int mesh_nexthop_lookup_nolearn(s -- return 0; -- } -- --+void mesh_path_refresh(struct ieee80211_sub_if_data *sdata, --+ struct mesh_path *mpath, const u8 *addr) --+{ --+ if (mpath->flags & (MESH_PATH_REQ_QUEUED | MESH_PATH_FIXED | --+ MESH_PATH_RESOLVING)) --+ return; --+ --+ if (time_after(jiffies, --+ mpath->exp_time - --+ msecs_to_jiffies(sdata->u.mesh.mshcfg.path_refresh_time)) && --+ (!addr || ether_addr_equal(sdata->vif.addr, addr))) --+ mesh_queue_preq(mpath, PREQ_Q_F_START | PREQ_Q_F_REFRESH); --+} --+ -- /** -- * mesh_nexthop_lookup - put the appropriate next hop on a mesh frame. Calling -- * this function is considered "using" the associated mpath, so preempt a path --@@ -1242,19 +1265,15 @@ int mesh_nexthop_lookup(struct ieee80211 -- if (!mpath || !(mpath->flags & MESH_PATH_ACTIVE)) -- return -ENOENT; -- --- if (time_after(jiffies, --- mpath->exp_time - --- msecs_to_jiffies(sdata->u.mesh.mshcfg.path_refresh_time)) && --- ether_addr_equal(sdata->vif.addr, hdr->addr4) && --- !(mpath->flags & MESH_PATH_RESOLVING) && --- !(mpath->flags & MESH_PATH_FIXED)) --- mesh_queue_preq(mpath, PREQ_Q_F_START | PREQ_Q_F_REFRESH); --+ mesh_path_refresh(sdata, mpath, hdr->addr4); -- -- next_hop = rcu_dereference(mpath->next_hop); -- if (next_hop) { -- memcpy(hdr->addr1, next_hop->sta.addr, ETH_ALEN); -- memcpy(hdr->addr2, sdata->vif.addr, ETH_ALEN); -- ieee80211_mps_set_frame_flags(sdata, next_hop, hdr); --+ if (ieee80211_hw_check(&sdata->local->hw, SUPPORT_FAST_XMIT)) --+ mesh_fast_tx_cache(sdata, skb, mpath); -- return 0; -- } -- ----- a/net/mac80211/mesh_pathtbl.c --+++ b/net/mac80211/mesh_pathtbl.c --@@ -14,6 +14,7 @@ -- #include "wme.h" -- #include "ieee80211_i.h" -- #include "mesh.h" --+#include -- -- static void mesh_path_free_rcu(struct mesh_table *tbl, struct mesh_path *mpath); -- --@@ -32,6 +33,41 @@ static const struct rhashtable_params me -- .hashfn = mesh_table_hash, -- }; -- --+static const struct rhashtable_params fast_tx_rht_params = { --+ .nelem_hint = 10, --+ .automatic_shrinking = true, --+ .key_len = ETH_ALEN, --+ .key_offset = offsetof(struct ieee80211_mesh_fast_tx, addr_key), --+ .head_offset = offsetof(struct ieee80211_mesh_fast_tx, rhash), --+ .hashfn = mesh_table_hash, --+}; --+ --+static void __mesh_fast_tx_entry_free(void *ptr, void *tblptr) --+{ --+ struct ieee80211_mesh_fast_tx *entry = ptr; --+ --+ kfree_rcu(entry, fast_tx.rcu_head); --+} --+ --+static void mesh_fast_tx_deinit(struct ieee80211_sub_if_data *sdata) --+{ --+ struct mesh_tx_cache *cache; --+ --+ cache = &sdata->u.mesh.tx_cache; --+ rhashtable_free_and_destroy(&cache->rht, --+ __mesh_fast_tx_entry_free, NULL); --+} --+ --+static void mesh_fast_tx_init(struct ieee80211_sub_if_data *sdata) --+{ --+ struct mesh_tx_cache *cache; --+ --+ cache = &sdata->u.mesh.tx_cache; --+ rhashtable_init(&cache->rht, &fast_tx_rht_params); --+ INIT_HLIST_HEAD(&cache->walk_head); --+ spin_lock_init(&cache->walk_lock); --+} --+ -- static inline bool mpath_expired(struct mesh_path *mpath) -- { -- return (mpath->flags & MESH_PATH_ACTIVE) && --@@ -381,6 +417,243 @@ struct mesh_path *mesh_path_new(struct i -- return new_mpath; -- } -- --+static void mesh_fast_tx_entry_free(struct mesh_tx_cache *cache, --+ struct ieee80211_mesh_fast_tx *entry) --+{ --+ hlist_del_rcu(&entry->walk_list); --+ rhashtable_remove_fast(&cache->rht, &entry->rhash, fast_tx_rht_params); --+ kfree_rcu(entry, fast_tx.rcu_head); --+} --+ --+struct ieee80211_mesh_fast_tx * --+mesh_fast_tx_get(struct ieee80211_sub_if_data *sdata, const u8 *addr) --+{ --+ struct ieee80211_mesh_fast_tx *entry; --+ struct mesh_tx_cache *cache; --+ --+ cache = &sdata->u.mesh.tx_cache; --+ entry = rhashtable_lookup(&cache->rht, addr, fast_tx_rht_params); --+ if (!entry) --+ return NULL; --+ --+ if (!(entry->mpath->flags & MESH_PATH_ACTIVE) || --+ mpath_expired(entry->mpath)) { --+ spin_lock_bh(&cache->walk_lock); --+ entry = rhashtable_lookup(&cache->rht, addr, fast_tx_rht_params); --+ if (entry) --+ mesh_fast_tx_entry_free(cache, entry); --+ spin_unlock_bh(&cache->walk_lock); --+ return NULL; --+ } --+ --+ mesh_path_refresh(sdata, entry->mpath, NULL); --+ if (entry->mppath) --+ entry->mppath->exp_time = jiffies; --+ entry->timestamp = jiffies; --+ --+ return entry; --+} --+ --+void mesh_fast_tx_cache(struct ieee80211_sub_if_data *sdata, --+ struct sk_buff *skb, struct mesh_path *mpath) --+{ --+ struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; --+ struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); --+ struct ieee80211_mesh_fast_tx *entry, *prev; --+ struct ieee80211_mesh_fast_tx build = {}; --+ struct ieee80211s_hdr *meshhdr; --+ struct mesh_tx_cache *cache; --+ struct ieee80211_key *key; --+ struct mesh_path *mppath; --+ struct sta_info *sta; --+ u8 *qc; --+ --+ if (sdata->noack_map || --+ !ieee80211_is_data_qos(hdr->frame_control)) --+ return; --+ --+ build.fast_tx.hdr_len = ieee80211_hdrlen(hdr->frame_control); --+ meshhdr = (struct ieee80211s_hdr *)(skb->data + build.fast_tx.hdr_len); --+ build.hdrlen = ieee80211_get_mesh_hdrlen(meshhdr); --+ --+ cache = &sdata->u.mesh.tx_cache; --+ if (atomic_read(&cache->rht.nelems) >= MESH_FAST_TX_CACHE_MAX_SIZE) --+ return; --+ --+ sta = rcu_dereference(mpath->next_hop); --+ if (!sta) --+ return; --+ --+ if ((meshhdr->flags & MESH_FLAGS_AE) == MESH_FLAGS_AE_A5_A6) { --+ /* This is required to keep the mppath alive */ --+ mppath = mpp_path_lookup(sdata, meshhdr->eaddr1); --+ if (!mppath) --+ return; --+ build.mppath = mppath; --+ } else if (ieee80211_has_a4(hdr->frame_control)) { --+ mppath = mpath; --+ } else { --+ return; --+ } --+ --+ /* rate limit, in case fast xmit can't be enabled */ --+ if (mppath->fast_tx_check == jiffies) --+ return; --+ --+ mppath->fast_tx_check = jiffies; --+ --+ /* --+ * Same use of the sta lock as in ieee80211_check_fast_xmit, in order --+ * to protect against concurrent sta key updates. --+ */ --+ spin_lock_bh(&sta->lock); --+ key = rcu_access_pointer(sta->ptk[sta->ptk_idx]); --+ if (!key) --+ key = rcu_access_pointer(sdata->default_unicast_key); --+ build.fast_tx.key = key; --+ --+ if (key) { --+ bool gen_iv, iv_spc; --+ --+ gen_iv = key->conf.flags & IEEE80211_KEY_FLAG_GENERATE_IV; --+ iv_spc = key->conf.flags & IEEE80211_KEY_FLAG_PUT_IV_SPACE; --+ --+ if (!(key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE) || --+ (key->flags & KEY_FLAG_TAINTED)) --+ goto unlock_sta; --+ --+ switch (key->conf.cipher) { --+ case WLAN_CIPHER_SUITE_CCMP: --+ case WLAN_CIPHER_SUITE_CCMP_256: --+ if (gen_iv) --+ build.fast_tx.pn_offs = build.fast_tx.hdr_len; --+ if (gen_iv || iv_spc) --+ build.fast_tx.hdr_len += IEEE80211_CCMP_HDR_LEN; --+ break; --+ case WLAN_CIPHER_SUITE_GCMP: --+ case WLAN_CIPHER_SUITE_GCMP_256: --+ if (gen_iv) --+ build.fast_tx.pn_offs = build.fast_tx.hdr_len; --+ if (gen_iv || iv_spc) --+ build.fast_tx.hdr_len += IEEE80211_GCMP_HDR_LEN; --+ break; --+ default: --+ goto unlock_sta; --+ } --+ } --+ --+ memcpy(build.addr_key, mppath->dst, ETH_ALEN); --+ build.timestamp = jiffies; --+ build.fast_tx.band = info->band; --+ build.fast_tx.da_offs = offsetof(struct ieee80211_hdr, addr3); --+ build.fast_tx.sa_offs = offsetof(struct ieee80211_hdr, addr4); --+ build.mpath = mpath; --+ memcpy(build.hdr, meshhdr, build.hdrlen); --+ memcpy(build.hdr + build.hdrlen, rfc1042_header, sizeof(rfc1042_header)); --+ build.hdrlen += sizeof(rfc1042_header); --+ memcpy(build.fast_tx.hdr, hdr, build.fast_tx.hdr_len); --+ --+ hdr = (struct ieee80211_hdr *)build.fast_tx.hdr; --+ if (build.fast_tx.key) --+ hdr->frame_control |= cpu_to_le16(IEEE80211_FCTL_PROTECTED); --+ --+ qc = ieee80211_get_qos_ctl(hdr); --+ qc[1] |= IEEE80211_QOS_CTL_MESH_CONTROL_PRESENT >> 8; --+ --+ entry = kmemdup(&build, sizeof(build), GFP_ATOMIC); --+ if (!entry) --+ goto unlock_sta; --+ --+ spin_lock(&cache->walk_lock); --+ prev = rhashtable_lookup_get_insert_fast(&cache->rht, --+ &entry->rhash, --+ fast_tx_rht_params); --+ if (unlikely(IS_ERR(prev))) { --+ kfree(entry); --+ goto unlock_cache; --+ } --+ --+ /* --+ * replace any previous entry in the hash table, in case we're --+ * replacing it with a different type (e.g. mpath -> mpp) --+ */ --+ if (unlikely(prev)) { --+ rhashtable_replace_fast(&cache->rht, &prev->rhash, --+ &entry->rhash, fast_tx_rht_params); --+ hlist_del_rcu(&prev->walk_list); --+ kfree_rcu(prev, fast_tx.rcu_head); --+ } --+ --+ hlist_add_head(&entry->walk_list, &cache->walk_head); --+ --+unlock_cache: --+ spin_unlock(&cache->walk_lock); --+unlock_sta: --+ spin_unlock_bh(&sta->lock); --+} --+ --+void mesh_fast_tx_gc(struct ieee80211_sub_if_data *sdata) --+{ --+ unsigned long timeout = msecs_to_jiffies(MESH_FAST_TX_CACHE_TIMEOUT); --+ struct mesh_tx_cache *cache; --+ struct ieee80211_mesh_fast_tx *entry; --+ struct hlist_node *n; --+ --+ cache = &sdata->u.mesh.tx_cache; --+ if (atomic_read(&cache->rht.nelems) < MESH_FAST_TX_CACHE_THRESHOLD_SIZE) --+ return; --+ --+ spin_lock_bh(&cache->walk_lock); --+ hlist_for_each_entry_safe(entry, n, &cache->walk_head, walk_list) --+ if (!time_is_after_jiffies(entry->timestamp + timeout)) --+ mesh_fast_tx_entry_free(cache, entry); --+ spin_unlock_bh(&cache->walk_lock); --+} --+ --+void mesh_fast_tx_flush_mpath(struct mesh_path *mpath) --+{ --+ struct ieee80211_sub_if_data *sdata = mpath->sdata; --+ struct mesh_tx_cache *cache = &sdata->u.mesh.tx_cache; --+ struct ieee80211_mesh_fast_tx *entry; --+ struct hlist_node *n; --+ --+ cache = &sdata->u.mesh.tx_cache; --+ spin_lock_bh(&cache->walk_lock); --+ hlist_for_each_entry_safe(entry, n, &cache->walk_head, walk_list) --+ if (entry->mpath == mpath) --+ mesh_fast_tx_entry_free(cache, entry); --+ spin_unlock_bh(&cache->walk_lock); --+} --+ --+void mesh_fast_tx_flush_sta(struct ieee80211_sub_if_data *sdata, --+ struct sta_info *sta) --+{ --+ struct mesh_tx_cache *cache = &sdata->u.mesh.tx_cache; --+ struct ieee80211_mesh_fast_tx *entry; --+ struct hlist_node *n; --+ --+ cache = &sdata->u.mesh.tx_cache; --+ spin_lock_bh(&cache->walk_lock); --+ hlist_for_each_entry_safe(entry, n, &cache->walk_head, walk_list) --+ if (rcu_access_pointer(entry->mpath->next_hop) == sta) --+ mesh_fast_tx_entry_free(cache, entry); --+ spin_unlock_bh(&cache->walk_lock); --+} --+ --+void mesh_fast_tx_flush_addr(struct ieee80211_sub_if_data *sdata, --+ const u8 *addr) --+{ --+ struct mesh_tx_cache *cache = &sdata->u.mesh.tx_cache; --+ struct ieee80211_mesh_fast_tx *entry; --+ --+ cache = &sdata->u.mesh.tx_cache; --+ spin_lock_bh(&cache->walk_lock); --+ entry = rhashtable_lookup(&cache->rht, addr, fast_tx_rht_params); --+ if (entry) --+ mesh_fast_tx_entry_free(cache, entry); --+ 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) --@@ -464,6 +737,8 @@ int mpp_path_add(struct ieee80211_sub_if -- -- if (ret) -- kfree(new_mpath); --+ else --+ mesh_fast_tx_flush_addr(sdata, dst); -- -- sdata->u.mesh.mpp_paths_generation++; -- return ret; --@@ -523,6 +798,10 @@ static void __mesh_path_del(struct mesh_ -- { -- hlist_del_rcu(&mpath->walk_list); -- rhashtable_remove_fast(&tbl->rhead, &mpath->rhash, mesh_rht_params); --+ if (tbl == &mpath->sdata->u.mesh.mpp_paths) --+ mesh_fast_tx_flush_addr(mpath->sdata, mpath->dst); --+ else --+ mesh_fast_tx_flush_mpath(mpath); -- mesh_path_free_rcu(tbl, mpath); -- } -- --@@ -747,6 +1026,7 @@ void mesh_path_fix_nexthop(struct mesh_p -- mpath->exp_time = 0; -- mpath->flags = MESH_PATH_FIXED | MESH_PATH_SN_VALID; -- mesh_path_activate(mpath); --+ mesh_fast_tx_flush_mpath(mpath); -- spin_unlock_bh(&mpath->state_lock); -- ewma_mesh_fail_avg_init(&next_hop->mesh->fail_avg); -- /* init it at a low value - 0 start is tricky */ --@@ -758,6 +1038,7 @@ void mesh_pathtbl_init(struct ieee80211_ -- { -- mesh_table_init(&sdata->u.mesh.mesh_paths); -- mesh_table_init(&sdata->u.mesh.mpp_paths); --+ mesh_fast_tx_init(sdata); -- } -- -- static --@@ -785,6 +1066,7 @@ void mesh_path_expire(struct ieee80211_s -- -- void mesh_pathtbl_unregister(struct ieee80211_sub_if_data *sdata) -- { --+ mesh_fast_tx_deinit(sdata); -- mesh_table_free(&sdata->u.mesh.mesh_paths); -- mesh_table_free(&sdata->u.mesh.mpp_paths); -- } ----- a/net/mac80211/rx.c --+++ b/net/mac80211/rx.c --@@ -2791,6 +2791,7 @@ ieee80211_rx_mesh_data(struct ieee80211_ -- if (mesh_hdr->flags & MESH_FLAGS_AE) { -- struct mesh_path *mppath; -- char *proxied_addr; --+ bool update = false; -- -- if (multicast) -- proxied_addr = mesh_hdr->eaddr1; --@@ -2806,11 +2807,18 @@ ieee80211_rx_mesh_data(struct ieee80211_ -- mpp_path_add(sdata, proxied_addr, eth->h_source); -- } else { -- spin_lock_bh(&mppath->state_lock); --- if (!ether_addr_equal(mppath->mpp, eth->h_source)) --+ if (!ether_addr_equal(mppath->mpp, eth->h_source)) { -- memcpy(mppath->mpp, eth->h_source, ETH_ALEN); --+ update = true; --+ } -- mppath->exp_time = jiffies; -- spin_unlock_bh(&mppath->state_lock); -- } --+ --+ /* flush fast xmit cache if the address path changed */ --+ if (update) --+ mesh_fast_tx_flush_addr(sdata, proxied_addr); --+ -- rcu_read_unlock(); -- } -- ----- a/net/mac80211/tx.c --+++ b/net/mac80211/tx.c --@@ -3022,6 +3022,9 @@ void ieee80211_check_fast_xmit(struct st -- if (!ieee80211_hw_check(&local->hw, SUPPORT_FAST_XMIT)) -- return; -- --+ if (ieee80211_vif_is_mesh(&sdata->vif)) --+ mesh_fast_tx_flush_sta(sdata, sta); --+ -- /* Locking here protects both the pointer itself, and against concurrent -- * invocations winning data access races to, e.g., the key pointer that -- * is used. --@@ -3403,6 +3406,9 @@ static bool ieee80211_amsdu_aggregate(st -- if (sdata->vif.offload_flags & IEEE80211_OFFLOAD_ENCAP_ENABLED) -- return false; -- --+ if (ieee80211_vif_is_mesh(&sdata->vif)) --+ return false; --+ -- if (skb_is_gso(skb)) -- return false; -- --@@ -3635,10 +3641,11 @@ free: -- return NULL; -- } -- ---static void __ieee80211_xmit_fast(struct ieee80211_sub_if_data *sdata, --- struct sta_info *sta, --- struct ieee80211_fast_tx *fast_tx, --- struct sk_buff *skb, u8 tid, bool ampdu) --+void __ieee80211_xmit_fast(struct ieee80211_sub_if_data *sdata, --+ struct sta_info *sta, --+ struct ieee80211_fast_tx *fast_tx, --+ struct sk_buff *skb, bool ampdu, --+ const u8 *da, const u8 *sa) -- { -- struct ieee80211_local *local = sdata->local; -- struct ieee80211_hdr *hdr = (void *)fast_tx->hdr; --@@ -3647,7 +3654,6 @@ static void __ieee80211_xmit_fast(struct -- ieee80211_tx_result r; -- int hw_headroom = sdata->local->hw.extra_tx_headroom; -- int extra_head = fast_tx->hdr_len - (ETH_HLEN - 2); --- struct ethhdr eth; -- -- skb = skb_share_check(skb, GFP_ATOMIC); -- if (unlikely(!skb)) --@@ -3667,11 +3673,10 @@ static void __ieee80211_xmit_fast(struct -- ENCRYPT_NO))) -- goto free; -- --- memcpy(ð, skb->data, ETH_HLEN - 2); -- hdr = skb_push(skb, extra_head); -- memcpy(skb->data, fast_tx->hdr, fast_tx->hdr_len); --- memcpy(skb->data + fast_tx->da_offs, eth.h_dest, ETH_ALEN); --- memcpy(skb->data + fast_tx->sa_offs, eth.h_source, ETH_ALEN); --+ memcpy(skb->data + fast_tx->da_offs, da, ETH_ALEN); --+ memcpy(skb->data + fast_tx->sa_offs, sa, ETH_ALEN); -- -- info = IEEE80211_SKB_CB(skb); -- memset(info, 0, sizeof(*info)); --@@ -3690,7 +3695,8 @@ static void __ieee80211_xmit_fast(struct -- #endif -- -- if (hdr->frame_control & cpu_to_le16(IEEE80211_STYPE_QOS_DATA)) { --- tid = skb->priority & IEEE80211_QOS_CTL_TAG1D_MASK; --+ u8 tid = skb->priority & IEEE80211_QOS_CTL_TAG1D_MASK; --+ -- *ieee80211_get_qos_ctl(hdr) = tid; -- } -- --@@ -3733,6 +3739,7 @@ static bool ieee80211_xmit_fast(struct i -- struct ieee80211_hdr *hdr = (void *)fast_tx->hdr; -- struct tid_ampdu_tx *tid_tx = NULL; -- struct sk_buff *next; --+ struct ethhdr eth; -- u8 tid = IEEE80211_NUM_TIDS; -- -- /* control port protocol needs a lot of special handling */ --@@ -3758,6 +3765,8 @@ 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)); -- if (!skb) --@@ -3765,7 +3774,8 @@ static bool ieee80211_xmit_fast(struct i -- -- skb_list_walk_safe(skb, skb, next) { -- skb_mark_not_on_list(skb); --- __ieee80211_xmit_fast(sdata, sta, fast_tx, skb, tid, tid_tx); --+ __ieee80211_xmit_fast(sdata, sta, fast_tx, skb, tid_tx, --+ eth.h_dest, eth.h_source); -- } -- -- return true; --@@ -4252,8 +4262,15 @@ void __ieee80211_subif_start_xmit(struct -- return; -- } -- --+ sk_pacing_shift_update(skb->sk, sdata->local->hw.tx_sk_pacing_shift); --+ -- rcu_read_lock(); -- --+ if (ieee80211_vif_is_mesh(&sdata->vif) && --+ ieee80211_hw_check(&local->hw, SUPPORT_FAST_XMIT) && --+ ieee80211_mesh_xmit_fast(sdata, skb, ctrl_flags)) --+ goto out; --+ -- if (ieee80211_lookup_ra_sta(sdata, skb, &sta)) -- goto out_free; -- --@@ -4263,8 +4280,6 @@ void __ieee80211_subif_start_xmit(struct -- skb_set_queue_mapping(skb, ieee80211_select_queue(sdata, sta, skb)); -- ieee80211_aggr_check(sdata, sta, skb); -- --- sk_pacing_shift_update(skb->sk, sdata->local->hw.tx_sk_pacing_shift); --- -- if (sta) { -- struct ieee80211_fast_tx *fast_tx; -- -diff --git a/package/kernel/mac80211/patches/subsys/320-wifi-mac80211-use-mesh-header-cache-to-speed-up-mesh.patch b/package/kernel/mac80211/patches/subsys/320-wifi-mac80211-use-mesh-header-cache-to-speed-up-mesh.patch -deleted file mode 100644 -index 28b1ff1106..0000000000 ---- a/package/kernel/mac80211/patches/subsys/320-wifi-mac80211-use-mesh-header-cache-to-speed-up-mesh.patch -+++ /dev/null -@@ -1,132 +0,0 @@ --From: Felix Fietkau --Date: Thu, 16 Feb 2023 11:07:30 +0100 --Subject: [PATCH] wifi: mac80211: use mesh header cache to speed up mesh -- forwarding -- --Significantly reduces mesh forwarding path CPU usage and enables the --direct use of iTXQ. -- --Signed-off-by: Felix Fietkau ----- -- ----- a/net/mac80211/rx.c --+++ b/net/mac80211/rx.c --@@ -2720,6 +2720,65 @@ ieee80211_deliver_skb(struct ieee80211_r -- } -- } -- --+#ifdef CPTCFG_MAC80211_MESH --+static bool --+ieee80211_rx_mesh_fast_forward(struct ieee80211_sub_if_data *sdata, --+ struct sk_buff *skb, int hdrlen) --+{ --+ struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh; --+ struct ieee80211_mesh_fast_tx *entry = NULL; --+ struct ieee80211s_hdr *mesh_hdr; --+ struct tid_ampdu_tx *tid_tx; --+ struct sta_info *sta; --+ struct ethhdr eth; --+ u8 tid; --+ --+ mesh_hdr = (struct ieee80211s_hdr *)(skb->data + sizeof(eth)); --+ if ((mesh_hdr->flags & MESH_FLAGS_AE) == MESH_FLAGS_AE_A5_A6) --+ entry = mesh_fast_tx_get(sdata, mesh_hdr->eaddr1); --+ else if (!(mesh_hdr->flags & MESH_FLAGS_AE)) --+ entry = mesh_fast_tx_get(sdata, skb->data); --+ if (!entry) --+ return false; --+ --+ sta = rcu_dereference(entry->mpath->next_hop); --+ if (!sta) --+ return false; --+ --+ if (skb_linearize(skb)) --+ return false; --+ --+ 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)) --+ return false; --+ --+ if (tid_tx->timeout) --+ tid_tx->last_tx = jiffies; --+ } --+ --+ ieee80211_aggr_check(sdata, sta, skb); --+ --+ if (ieee80211_get_8023_tunnel_proto(skb->data + hdrlen, --+ &skb->protocol)) --+ hdrlen += ETH_ALEN; --+ else --+ skb->protocol = htons(skb->len - hdrlen); --+ skb_set_network_header(skb, hdrlen + 2); --+ --+ skb->dev = sdata->dev; --+ memcpy(ð, skb->data, ETH_HLEN - 2); --+ skb_pull(skb, 2); --+ __ieee80211_xmit_fast(sdata, sta, &entry->fast_tx, skb, tid_tx, --+ eth.h_dest, eth.h_source); --+ IEEE80211_IFSTA_MESH_CTR_INC(ifmsh, fwded_unicast); --+ IEEE80211_IFSTA_MESH_CTR_INC(ifmsh, fwded_frames); --+ --+ return true; --+} --+#endif --+ -- static ieee80211_rx_result -- ieee80211_rx_mesh_data(struct ieee80211_sub_if_data *sdata, struct sta_info *sta, -- struct sk_buff *skb) --@@ -2824,6 +2883,10 @@ ieee80211_rx_mesh_data(struct ieee80211_ -- -- skb_set_queue_mapping(skb, ieee802_1d_to_ac[skb->priority]); -- --+ if (!multicast && --+ ieee80211_rx_mesh_fast_forward(sdata, skb, mesh_hdrlen)) --+ return RX_QUEUED; --+ -- ieee80211_fill_mesh_addresses(&hdr, &hdr.frame_control, -- eth->h_dest, eth->h_source); -- hdrlen = ieee80211_hdrlen(hdr.frame_control); --@@ -2862,6 +2925,7 @@ ieee80211_rx_mesh_data(struct ieee80211_ -- info->control.flags |= IEEE80211_TX_INTCFL_NEED_TXPROCESSING; -- info->control.vif = &sdata->vif; -- info->control.jiffies = jiffies; --+ fwd_skb->dev = sdata->dev; -- if (multicast) { -- IEEE80211_IFSTA_MESH_CTR_INC(ifmsh, fwded_mcast); -- memcpy(fwd_hdr->addr2, sdata->vif.addr, ETH_ALEN); --@@ -2883,7 +2947,6 @@ ieee80211_rx_mesh_data(struct ieee80211_ -- } -- -- IEEE80211_IFSTA_MESH_CTR_INC(ifmsh, fwded_frames); --- fwd_skb->dev = sdata->dev; -- ieee80211_add_pending_skb(local, fwd_skb); -- -- rx_accept: ----- a/net/mac80211/ieee80211_i.h --+++ b/net/mac80211/ieee80211_i.h --@@ -2022,6 +2022,8 @@ void __ieee80211_xmit_fast(struct ieee80 -- struct ieee80211_fast_tx *fast_tx, -- struct sk_buff *skb, bool ampdu, -- const u8 *da, const u8 *sa); --+void ieee80211_aggr_check(struct ieee80211_sub_if_data *sdata, --+ struct sta_info *sta, struct sk_buff *skb); -- -- /* HT */ -- void ieee80211_apply_htcap_overrides(struct ieee80211_sub_if_data *sdata, ----- a/net/mac80211/tx.c --+++ b/net/mac80211/tx.c --@@ -1191,10 +1191,8 @@ static bool ieee80211_tx_prep_agg(struct -- return queued; -- } -- ---static void ---ieee80211_aggr_check(struct ieee80211_sub_if_data *sdata, --- struct sta_info *sta, --- struct sk_buff *skb) --+void ieee80211_aggr_check(struct ieee80211_sub_if_data *sdata, --+ struct sta_info *sta, struct sk_buff *skb) -- { -- struct rate_control_ref *ref = sdata->local->rate_ctrl; -- u16 tid; -diff --git a/package/kernel/mac80211/patches/subsys/321-mac80211-fix-mesh-forwarding.patch b/package/kernel/mac80211/patches/subsys/321-mac80211-fix-mesh-forwarding.patch -deleted file mode 100644 -index e2b268ae4c..0000000000 ---- a/package/kernel/mac80211/patches/subsys/321-mac80211-fix-mesh-forwarding.patch -+++ /dev/null -@@ -1,32 +0,0 @@ --From: Felix Fietkau --Date: Mon, 20 Feb 2023 12:50:50 +0100 --Subject: [PATCH] mac80211: fix mesh forwarding -- --Linearize packets (needed for forwarding A-MSDU subframes). --Fix network header offset to fix flow dissector (and fair queueing). -- --Fixes: 986e43b19ae9 ("wifi: mac80211: fix receiving A-MSDU frames on mesh interfaces") --Signed-off-by: Felix Fietkau ----- -- ----- a/net/mac80211/rx.c --+++ b/net/mac80211/rx.c --@@ -2904,6 +2904,9 @@ ieee80211_rx_mesh_data(struct ieee80211_ -- -- if (skb_cow_head(fwd_skb, hdrlen - sizeof(struct ethhdr))) -- return RX_DROP_UNUSABLE; --+ --+ if (skb_linearize(fwd_skb)) --+ return RX_DROP_UNUSABLE; -- } -- -- fwd_hdr = skb_push(fwd_skb, hdrlen - sizeof(struct ethhdr)); --@@ -2918,7 +2921,7 @@ ieee80211_rx_mesh_data(struct ieee80211_ -- hdrlen += ETH_ALEN; -- else -- fwd_skb->protocol = htons(fwd_skb->len - hdrlen); --- skb_set_network_header(fwd_skb, hdrlen); --+ skb_set_network_header(fwd_skb, hdrlen + 2); -- -- info = IEEE80211_SKB_CB(fwd_skb); -- memset(info, 0, sizeof(*info)); -diff --git a/package/kernel/mac80211/patches/subsys/322-wifi-mac80211-fix-mesh-path-discovery-based-on-unica.patch b/package/kernel/mac80211/patches/subsys/322-wifi-mac80211-fix-mesh-path-discovery-based-on-unica.patch -deleted file mode 100644 -index 292a89ef92..0000000000 ---- a/package/kernel/mac80211/patches/subsys/322-wifi-mac80211-fix-mesh-path-discovery-based-on-unica.patch -+++ /dev/null -@@ -1,52 +0,0 @@ --From: Felix Fietkau --Date: Sun, 26 Feb 2023 20:30:20 +0100 --Subject: [PATCH] wifi: mac80211: fix mesh path discovery based on unicast -- packets -- --If a packet has reached its intended destination, it was bumped to the code --that accepts it, without first checking if a mesh_path needs to be created --based on the discovered source. --Fix this by moving the destination address check further down -- --Fixes: 986e43b19ae9 ("wifi: mac80211: fix receiving A-MSDU frames on mesh interfaces") --Signed-off-by: Felix Fietkau ----- -- ----- a/net/mac80211/rx.c --+++ b/net/mac80211/rx.c --@@ -2824,17 +2824,6 @@ ieee80211_rx_mesh_data(struct ieee80211_ -- mesh_rmc_check(sdata, eth->h_source, mesh_hdr)) -- return RX_DROP_MONITOR; -- --- /* Frame has reached destination. Don't forward */ --- if (ether_addr_equal(sdata->vif.addr, eth->h_dest)) --- goto rx_accept; --- --- if (!ifmsh->mshcfg.dot11MeshForwarding) { --- if (is_multicast_ether_addr(eth->h_dest)) --- goto rx_accept; --- --- return RX_DROP_MONITOR; --- } --- -- /* forward packet */ -- if (sdata->crypto_tx_tailroom_needed_cnt) -- tailroom = IEEE80211_ENCRYPT_TAILROOM; --@@ -2881,6 +2870,17 @@ ieee80211_rx_mesh_data(struct ieee80211_ -- rcu_read_unlock(); -- } -- --+ /* Frame has reached destination. Don't forward */ --+ if (ether_addr_equal(sdata->vif.addr, eth->h_dest)) --+ goto rx_accept; --+ --+ if (!ifmsh->mshcfg.dot11MeshForwarding) { --+ if (is_multicast_ether_addr(eth->h_dest)) --+ goto rx_accept; --+ --+ return RX_DROP_MONITOR; --+ } --+ -- skb_set_queue_mapping(skb, ieee802_1d_to_ac[skb->priority]); -- -- if (!multicast && -diff --git a/package/kernel/mac80211/patches/subsys/323-v6.3-wifi-mac80211-Add-VHT-MU-MIMO-related-flags-in-ieee8.patch b/package/kernel/mac80211/patches/subsys/323-v6.3-wifi-mac80211-Add-VHT-MU-MIMO-related-flags-in-ieee8.patch -deleted file mode 100644 -index e23dc4d226..0000000000 ---- a/package/kernel/mac80211/patches/subsys/323-v6.3-wifi-mac80211-Add-VHT-MU-MIMO-related-flags-in-ieee8.patch -+++ /dev/null -@@ -1,68 +0,0 @@ --From: Muna Sinada --Date: Wed, 5 Oct 2022 14:54:45 -0700 --Subject: [PATCH] wifi: mac80211: Add VHT MU-MIMO related flags in -- ieee80211_bss_conf -- --Adding flags for SU Beamformer, SU Beamformee, MU Beamformer and --MU Beamformee for VHT. This is utilized to pass MU-MIMO --configurations from user space to driver in AP mode. -- --Signed-off-by: Muna Sinada --Link: https://lore.kernel.org/r/1665006886-23874-1-git-send-email-quic_msinada@quicinc.com --[fixed indentation, removed redundant !!] --Signed-off-by: Johannes Berg ----- -- ----- a/include/net/mac80211.h --+++ b/include/net/mac80211.h --@@ -653,6 +653,14 @@ struct ieee80211_fils_discovery { -- * write-protected by sdata_lock and local->mtx so holding either is fine -- * for read access. -- * @color_change_color: the bss color that will be used after the change. --+ * @vht_su_beamformer: in AP mode, does this BSS support operation as an VHT SU --+ * beamformer --+ * @vht_su_beamformee: in AP mode, does this BSS support operation as an VHT SU --+ * beamformee --+ * @vht_mu_beamformer: in AP mode, does this BSS support operation as an VHT MU --+ * beamformer --+ * @vht_mu_beamformee: in AP mode, does this BSS support operation as an VHT MU --+ * beamformee -- */ -- struct ieee80211_bss_conf { -- const u8 *bssid; --@@ -726,6 +734,11 @@ struct ieee80211_bss_conf { -- -- bool color_change_active; -- u8 color_change_color; --+ --+ bool vht_su_beamformer; --+ bool vht_su_beamformee; --+ bool vht_mu_beamformer; --+ bool vht_mu_beamformee; -- }; -- -- /** ----- a/net/mac80211/cfg.c --+++ b/net/mac80211/cfg.c --@@ -1252,6 +1252,21 @@ static int ieee80211_start_ap(struct wip -- prev_beacon_int = link_conf->beacon_int; -- link_conf->beacon_int = params->beacon_interval; -- --+ if (params->vht_cap) { --+ link_conf->vht_su_beamformer = --+ params->vht_cap->vht_cap_info & --+ cpu_to_le32(IEEE80211_VHT_CAP_SU_BEAMFORMER_CAPABLE); --+ link_conf->vht_su_beamformee = --+ params->vht_cap->vht_cap_info & --+ cpu_to_le32(IEEE80211_VHT_CAP_SU_BEAMFORMEE_CAPABLE); --+ link_conf->vht_mu_beamformer = --+ params->vht_cap->vht_cap_info & --+ cpu_to_le32(IEEE80211_VHT_CAP_MU_BEAMFORMER_CAPABLE); --+ link_conf->vht_mu_beamformee = --+ params->vht_cap->vht_cap_info & --+ cpu_to_le32(IEEE80211_VHT_CAP_MU_BEAMFORMEE_CAPABLE); --+ } --+ -- if (params->he_cap && params->he_oper) { -- link_conf->he_support = true; -- link_conf->htc_trig_based_pkt_ext = -diff --git a/package/kernel/mac80211/patches/subsys/324-v6.3-wifi-mac80211-Add-HE-MU-MIMO-related-flags-in-ieee80.patch b/package/kernel/mac80211/patches/subsys/324-v6.3-wifi-mac80211-Add-HE-MU-MIMO-related-flags-in-ieee80.patch -deleted file mode 100644 -index f843dba123..0000000000 ---- a/package/kernel/mac80211/patches/subsys/324-v6.3-wifi-mac80211-Add-HE-MU-MIMO-related-flags-in-ieee80.patch -+++ /dev/null -@@ -1,68 +0,0 @@ --From: Muna Sinada --Date: Wed, 5 Oct 2022 14:54:46 -0700 --Subject: [PATCH] wifi: mac80211: Add HE MU-MIMO related flags in -- ieee80211_bss_conf -- --Adding flags for SU Beamformer, SU Beamformee, MU Beamformer and Full --Bandwidth UL MU-MIMO for HE. This is utilized to pass MU-MIMO --configurations from user space to driver in AP mode. -- --Signed-off-by: Muna Sinada --Link: https://lore.kernel.org/r/1665006886-23874-2-git-send-email-quic_msinada@quicinc.com --[fixed indentation, removed redundant !!] --Signed-off-by: Johannes Berg ----- -- ----- a/include/net/mac80211.h --+++ b/include/net/mac80211.h --@@ -661,6 +661,15 @@ struct ieee80211_fils_discovery { -- * beamformer -- * @vht_mu_beamformee: in AP mode, does this BSS support operation as an VHT MU -- * beamformee --+ * @he_su_beamformer: in AP-mode, does this BSS support operation as an HE SU --+ * beamformer --+ * @he_su_beamformee: in AP-mode, does this BSS support operation as an HE SU --+ * beamformee --+ * @he_mu_beamformer: in AP-mode, does this BSS support operation as an HE MU --+ * beamformer --+ * @he_full_ul_mumimo: does this BSS support the reception (AP) or transmission --+ * (non-AP STA) of an HE TB PPDU on an RU that spans the entire PPDU --+ * bandwidth -- */ -- struct ieee80211_bss_conf { -- const u8 *bssid; --@@ -739,6 +748,10 @@ struct ieee80211_bss_conf { -- bool vht_su_beamformee; -- bool vht_mu_beamformer; -- bool vht_mu_beamformee; --+ bool he_su_beamformer; --+ bool he_su_beamformee; --+ bool he_mu_beamformer; --+ bool he_full_ul_mumimo; -- }; -- -- /** ----- a/net/mac80211/cfg.c --+++ b/net/mac80211/cfg.c --@@ -1281,6 +1281,21 @@ static int ieee80211_start_ap(struct wip -- changed |= BSS_CHANGED_HE_BSS_COLOR; -- } -- --+ if (params->he_cap) { --+ link_conf->he_su_beamformer = --+ params->he_cap->phy_cap_info[3] & --+ IEEE80211_HE_PHY_CAP3_SU_BEAMFORMER; --+ link_conf->he_su_beamformee = --+ params->he_cap->phy_cap_info[4] & --+ IEEE80211_HE_PHY_CAP4_SU_BEAMFORMEE; --+ link_conf->he_mu_beamformer = --+ params->he_cap->phy_cap_info[4] & --+ IEEE80211_HE_PHY_CAP4_MU_BEAMFORMER; --+ link_conf->he_full_ul_mumimo = --+ params->he_cap->phy_cap_info[2] & --+ IEEE80211_HE_PHY_CAP2_UL_MU_FULL_MU_MIMO; --+ } --+ -- if (sdata->vif.type == NL80211_IFTYPE_AP && -- params->mbssid_config.tx_wdev) { -- err = ieee80211_set_ap_mbssid_options(sdata, -diff --git a/package/kernel/mac80211/patches/subsys/325-wifi-mac80211-introduce-ieee80211_refresh_tx_agg_ses.patch b/package/kernel/mac80211/patches/subsys/325-wifi-mac80211-introduce-ieee80211_refresh_tx_agg_ses.patch -deleted file mode 100644 -index 1be5fcfbfa..0000000000 ---- a/package/kernel/mac80211/patches/subsys/325-wifi-mac80211-introduce-ieee80211_refresh_tx_agg_ses.patch -+++ /dev/null -@@ -1,60 +0,0 @@ --From: Ryder Lee --Date: Sat, 18 Feb 2023 01:50:05 +0800 --Subject: [PATCH] wifi: mac80211: introduce -- ieee80211_refresh_tx_agg_session_timer() -- --This allows low level drivers to refresh the tx agg session timer, based on --querying stats from the firmware usually. Especially for some mt76 devices --support .net_fill_forward_path would bypass mac80211, which leads to tx BA --session timeout for certain clients. -- --Signed-off-by: Ryder Lee ----- -- ----- a/include/net/mac80211.h --+++ b/include/net/mac80211.h --@@ -5964,6 +5964,18 @@ void ieee80211_queue_delayed_work(struct -- unsigned long delay); -- -- /** --+ * ieee80211_refresh_tx_agg_session_timer - Refresh a tx agg session timer. --+ * @sta: the station for which to start a BA session --+ * @tid: the TID to BA on. --+ * --+ * This function allows low level driver to refresh tx agg session timer --+ * to maintain BA session, the session level will still be managed by the --+ * mac80211. --+ */ --+void ieee80211_refresh_tx_agg_session_timer(struct ieee80211_sta *sta, --+ u16 tid); --+ --+/** -- * ieee80211_start_tx_ba_session - Start a tx Block Ack session. -- * @sta: the station for which to start a BA session -- * @tid: the TID to BA on. ----- a/net/mac80211/agg-tx.c --+++ b/net/mac80211/agg-tx.c --@@ -554,6 +554,23 @@ void ieee80211_tx_ba_session_handle_star -- ieee80211_send_addba_with_timeout(sta, tid_tx); -- } -- --+void ieee80211_refresh_tx_agg_session_timer(struct ieee80211_sta *pubsta, --+ u16 tid) --+{ --+ struct sta_info *sta = container_of(pubsta, struct sta_info, sta); --+ struct tid_ampdu_tx *tid_tx; --+ --+ if (WARN_ON_ONCE(tid >= IEEE80211_NUM_TIDS)) --+ return; --+ --+ tid_tx = rcu_dereference(sta->ampdu_mlme.tid_tx[tid]); --+ if (!tid_tx) --+ return; --+ --+ tid_tx->last_tx = jiffies; --+} --+EXPORT_SYMBOL(ieee80211_refresh_tx_agg_session_timer); --+ -- /* -- * After accepting the AddBA Response we activated a timer, -- * resetting it after each frame that we send. -diff --git a/package/kernel/mac80211/patches/subsys/326-wifi-mac80211-add-mesh-fast-rx-support.patch b/package/kernel/mac80211/patches/subsys/326-wifi-mac80211-add-mesh-fast-rx-support.patch -deleted file mode 100644 -index 11f39c2d10..0000000000 ---- a/package/kernel/mac80211/patches/subsys/326-wifi-mac80211-add-mesh-fast-rx-support.patch -+++ /dev/null -@@ -1,77 +0,0 @@ --From: Felix Fietkau --Date: Thu, 2 Mar 2023 13:52:29 +0100 --Subject: [PATCH] wifi: mac80211: add mesh fast-rx support -- --This helps bring down rx CPU usage by avoiding calls to the rx handlers in --the slow path. Supports forwarding and local rx, including A-MSDU. -- --Signed-off-by: Felix Fietkau ----- -- ----- a/net/mac80211/rx.c --+++ b/net/mac80211/rx.c --@@ -4564,6 +4564,12 @@ void ieee80211_check_fast_rx(struct sta_ -- } -- -- break; --+ case NL80211_IFTYPE_MESH_POINT: --+ 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); --+ break; -- default: -- goto clear; -- } --@@ -4772,6 +4778,7 @@ static bool ieee80211_invoke_fast_rx(str -- struct sk_buff *skb = rx->skb; -- struct ieee80211_hdr *hdr = (void *)skb->data; -- struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb); --+ static ieee80211_rx_result res; -- int orig_len = skb->len; -- int hdrlen = ieee80211_hdrlen(hdr->frame_control); -- int snap_offs = hdrlen; --@@ -4833,7 +4840,8 @@ static bool ieee80211_invoke_fast_rx(str -- snap_offs += IEEE80211_CCMP_HDR_LEN; -- } -- --- if (!(status->rx_flags & IEEE80211_RX_AMSDU)) { --+ if (!ieee80211_vif_is_mesh(&rx->sdata->vif) && --+ !(status->rx_flags & IEEE80211_RX_AMSDU)) { -- if (!pskb_may_pull(skb, snap_offs + sizeof(*payload))) -- return false; -- --@@ -4872,13 +4880,29 @@ static bool ieee80211_invoke_fast_rx(str -- /* 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); --- skb_postpull_rcsum(skb, skb->data + snap_offs, --- sizeof(rfc1042_header) + 2); --- /* remove the SNAP but leave the ethertype */ --- skb_pull(skb, snap_offs + sizeof(rfc1042_header)); --+ if (ieee80211_vif_is_mesh(&rx->sdata->vif)) { --+ skb_pull(skb, snap_offs - 2); --+ put_unaligned_be16(skb->len - 2, skb->data); --+ } else { --+ skb_postpull_rcsum(skb, skb->data + snap_offs, --+ sizeof(rfc1042_header) + 2); --+ --+ /* remove the SNAP but leave the ethertype */ --+ skb_pull(skb, snap_offs + sizeof(rfc1042_header)); --+ } -- /* push the addresses in front */ -- memcpy(skb_push(skb, sizeof(addrs)), &addrs, sizeof(addrs)); -- --+ res = ieee80211_rx_mesh_data(rx->sdata, rx->sta, rx->skb); --+ switch (res) { --+ case RX_QUEUED: --+ return true; --+ case RX_CONTINUE: --+ break; --+ default: --+ goto drop; --+ } --+ -- ieee80211_rx_8023(rx, fast_rx, orig_len); -- -- return true; -diff --git a/package/kernel/mac80211/patches/subsys/327-wifi-mac80211-add-support-for-letting-drivers-regist.patch b/package/kernel/mac80211/patches/subsys/327-wifi-mac80211-add-support-for-letting-drivers-regist.patch -deleted file mode 100644 -index ac290b5360..0000000000 ---- a/package/kernel/mac80211/patches/subsys/327-wifi-mac80211-add-support-for-letting-drivers-regist.patch -+++ /dev/null -@@ -1,149 +0,0 @@ --From: Felix Fietkau --Date: Mon, 20 Mar 2023 14:28:08 +0100 --Subject: [PATCH] wifi: mac80211: add support for letting drivers register tc -- offload support -- --On newer MediaTek SoCs (e.g. MT7986), WLAN->WLAN or WLAN->Ethernet flows can --be offloaded by the SoC. In order to support that, the .ndo_setup_tc op is --needed. -- --Signed-off-by: Felix Fietkau ----- -- ----- a/include/net/mac80211.h --+++ b/include/net/mac80211.h --@@ -4192,6 +4192,10 @@ struct ieee80211_prep_tx_info { -- * Note that a sta can also be inserted or removed with valid links, -- * i.e. passed to @sta_add/@sta_state with sta->valid_links not zero. -- * In fact, cannot change from having valid_links and not having them. --+ * @net_setup_tc: Called from .ndo_setup_tc in order to prepare hardware --+ * flow offloading for flows originating from the vif. --+ * Note that the driver must not assume that the vif driver_data is valid --+ * at this point, since the callback can be called during netdev teardown. -- */ -- struct ieee80211_ops { -- void (*tx)(struct ieee80211_hw *hw, --@@ -4547,6 +4551,11 @@ struct ieee80211_ops { -- struct ieee80211_vif *vif, -- struct ieee80211_sta *sta, -- u16 old_links, u16 new_links); --+ int (*net_setup_tc)(struct ieee80211_hw *hw, --+ struct ieee80211_vif *vif, --+ struct net_device *dev, --+ enum tc_setup_type type, --+ void *type_data); -- }; -- -- /** ----- a/net/mac80211/driver-ops.h --+++ b/net/mac80211/driver-ops.h --@@ -1470,6 +1470,23 @@ static inline int drv_net_fill_forward_p -- return ret; -- } -- --+static inline int drv_net_setup_tc(struct ieee80211_local *local, --+ struct ieee80211_sub_if_data *sdata, --+ struct net_device *dev, --+ enum tc_setup_type type, void *type_data) --+{ --+ int ret = -EOPNOTSUPP; --+ --+ sdata = get_bss_sdata(sdata); --+ trace_drv_net_setup_tc(local, sdata, type); --+ if (local->ops->net_setup_tc) --+ ret = local->ops->net_setup_tc(&local->hw, &sdata->vif, dev, --+ type, type_data); --+ trace_drv_return_int(local, ret); --+ --+ return ret; --+} --+ -- int drv_change_vif_links(struct ieee80211_local *local, -- struct ieee80211_sub_if_data *sdata, -- u16 old_links, u16 new_links, ----- a/net/mac80211/ieee80211_i.h --+++ b/net/mac80211/ieee80211_i.h --@@ -1939,7 +1939,8 @@ void ieee80211_color_collision_detection -- /* interface handling */ -- #define MAC80211_SUPPORTED_FEATURES_TX (NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM | \ -- NETIF_F_HW_CSUM | NETIF_F_SG | \ --- NETIF_F_HIGHDMA | NETIF_F_GSO_SOFTWARE) --+ NETIF_F_HIGHDMA | NETIF_F_GSO_SOFTWARE | \ --+ NETIF_F_HW_TC) -- #define MAC80211_SUPPORTED_FEATURES_RX (NETIF_F_RXCSUM) -- #define MAC80211_SUPPORTED_FEATURES (MAC80211_SUPPORTED_FEATURES_TX | \ -- MAC80211_SUPPORTED_FEATURES_RX) ----- a/net/mac80211/iface.c --+++ b/net/mac80211/iface.c --@@ -813,6 +813,21 @@ ieee80211_get_stats64(struct net_device -- dev_fetch_sw_netstats(stats, dev->tstats); -- } -- --+static int ieee80211_netdev_setup_tc(struct net_device *dev, --+ enum tc_setup_type type, void *type_data) --+{ --+ struct ieee80211_sub_if_data *sdata; --+ struct ieee80211_local *local; --+ --+ sdata = IEEE80211_DEV_TO_SUB_IF(dev); --+ local = sdata->local; --+ --+ if (!local->ops->net_setup_tc) --+ return -EOPNOTSUPP; --+ --+ return drv_net_setup_tc(local, sdata, dev, type, type_data); --+} --+ -- static const struct net_device_ops ieee80211_dataif_ops = { -- .ndo_open = ieee80211_open, -- .ndo_stop = ieee80211_stop, --@@ -821,6 +836,7 @@ static const struct net_device_ops ieee8 -- .ndo_set_rx_mode = ieee80211_set_multicast_list, -- .ndo_set_mac_address = ieee80211_change_mac, -- .ndo_get_stats64 = ieee80211_get_stats64, --+ .ndo_setup_tc = ieee80211_netdev_setup_tc, -- }; -- -- static u16 ieee80211_monitor_select_queue(struct net_device *dev, --@@ -929,6 +945,7 @@ static const struct net_device_ops ieee8 -- .ndo_set_mac_address = ieee80211_change_mac, -- .ndo_get_stats64 = ieee80211_get_stats64, -- .ndo_fill_forward_path = ieee80211_netdev_fill_forward_path, --+ .ndo_setup_tc = ieee80211_netdev_setup_tc, -- }; -- -- static bool ieee80211_iftype_supports_hdr_offload(enum nl80211_iftype iftype) ----- a/net/mac80211/trace.h --+++ b/net/mac80211/trace.h --@@ -2478,6 +2478,31 @@ DEFINE_EVENT(sta_event, drv_net_fill_for -- TP_ARGS(local, sdata, sta) -- ); -- --+TRACE_EVENT(drv_net_setup_tc, --+ TP_PROTO(struct ieee80211_local *local, --+ struct ieee80211_sub_if_data *sdata, --+ u8 type), --+ --+ TP_ARGS(local, sdata, type), --+ --+ TP_STRUCT__entry( --+ LOCAL_ENTRY --+ VIF_ENTRY --+ __field(u8, type) --+ ), --+ --+ TP_fast_assign( --+ LOCAL_ASSIGN; --+ VIF_ASSIGN; --+ __entry->type = type; --+ ), --+ --+ TP_printk( --+ LOCAL_PR_FMT VIF_PR_FMT " type:%d\n", --+ LOCAL_PR_ARG, VIF_PR_ARG, __entry->type --+ ) --+); --+ -- TRACE_EVENT(drv_change_vif_links, -- TP_PROTO(struct ieee80211_local *local, -- struct ieee80211_sub_if_data *sdata, -diff --git a/package/kernel/mac80211/patches/subsys/329-wifi-mac80211-fix-receiving-mesh-packets-in-forwardi.patch b/package/kernel/mac80211/patches/subsys/329-wifi-mac80211-fix-receiving-mesh-packets-in-forwardi.patch -deleted file mode 100644 -index 6882694da8..0000000000 ---- a/package/kernel/mac80211/patches/subsys/329-wifi-mac80211-fix-receiving-mesh-packets-in-forwardi.patch -+++ /dev/null -@@ -1,50 +0,0 @@ --From: Felix Fietkau --Date: Sun, 26 Mar 2023 17:11:34 +0200 --Subject: [PATCH] wifi: mac80211: fix receiving mesh packets in forwarding=0 -- networks --MIME-Version: 1.0 --Content-Type: text/plain; charset=UTF-8 --Content-Transfer-Encoding: 8bit -- --When forwarding is set to 0, frames are typically sent with ttl=1. --Move the ttl decrement check below the check for local receive in order to --fix packet drops. -- --Reported-by: Thomas Hühn --Reported-by: Nick Hainke --Fixes: 986e43b19ae9 ("wifi: mac80211: fix receiving A-MSDU frames on mesh interfaces") --Signed-off-by: Felix Fietkau ----- -- ----- a/net/mac80211/rx.c --+++ b/net/mac80211/rx.c --@@ -2828,14 +2828,6 @@ ieee80211_rx_mesh_data(struct ieee80211_ -- if (sdata->crypto_tx_tailroom_needed_cnt) -- tailroom = IEEE80211_ENCRYPT_TAILROOM; -- --- if (!--mesh_hdr->ttl) { --- if (multicast) --- goto rx_accept; --- --- IEEE80211_IFSTA_MESH_CTR_INC(ifmsh, dropped_frames_ttl); --- return RX_DROP_MONITOR; --- } --- -- if (mesh_hdr->flags & MESH_FLAGS_AE) { -- struct mesh_path *mppath; -- char *proxied_addr; --@@ -2874,6 +2866,14 @@ ieee80211_rx_mesh_data(struct ieee80211_ -- if (ether_addr_equal(sdata->vif.addr, eth->h_dest)) -- goto rx_accept; -- --+ if (!--mesh_hdr->ttl) { --+ if (multicast) --+ goto rx_accept; --+ --+ IEEE80211_IFSTA_MESH_CTR_INC(ifmsh, dropped_frames_ttl); --+ return RX_DROP_MONITOR; --+ } --+ -- if (!ifmsh->mshcfg.dot11MeshForwarding) { -- if (is_multicast_ether_addr(eth->h_dest)) -- goto rx_accept; -diff --git a/package/kernel/mac80211/patches/subsys/330-wifi-ieee80211-correctly-mark-FTM-frames-non-buffera.patch b/package/kernel/mac80211/patches/subsys/330-wifi-ieee80211-correctly-mark-FTM-frames-non-buffera.patch -deleted file mode 100644 -index 079dd2a868..0000000000 ---- a/package/kernel/mac80211/patches/subsys/330-wifi-ieee80211-correctly-mark-FTM-frames-non-buffera.patch -+++ /dev/null -@@ -1,134 +0,0 @@ --From: Johannes Berg --Date: Wed, 29 Mar 2023 16:46:26 +0200 --Subject: [PATCH] wifi: ieee80211: correctly mark FTM frames non-bufferable -- --The checks of whether or not a frame is bufferable were not --taking into account that some action frames aren't, such as --FTM. Check this, which requires some changes to the function --ieee80211_is_bufferable_mmpdu() since we need the whole skb --for the checks now. -- --Signed-off-by: Johannes Berg --Reviewed-by: Greenman, Gregory --Reviewed-by: Peer, Ilan ----- -- ----- a/drivers/net/wireless/intel/iwlwifi/mvm/tx.c --+++ b/drivers/net/wireless/intel/iwlwifi/mvm/tx.c --@@ -601,8 +601,9 @@ static void iwl_mvm_skb_prepare_status(s -- -- static int iwl_mvm_get_ctrl_vif_queue(struct iwl_mvm *mvm, -- struct ieee80211_tx_info *info, --- struct ieee80211_hdr *hdr) --+ struct sk_buff *skb) -- { --+ struct ieee80211_hdr *hdr = (void *)skb->data; -- struct iwl_mvm_vif *mvmvif = -- iwl_mvm_vif_from_mac80211(info->control.vif); -- __le16 fc = hdr->frame_control; --@@ -621,7 +622,7 @@ static int iwl_mvm_get_ctrl_vif_queue(st -- * reason 7 ("Class 3 frame received from nonassociated STA"). -- */ -- if (ieee80211_is_mgmt(fc) && --- (!ieee80211_is_bufferable_mmpdu(fc) || --+ (!ieee80211_is_bufferable_mmpdu(skb) || -- ieee80211_is_deauth(fc) || ieee80211_is_disassoc(fc))) -- return mvm->probe_queue; -- --@@ -740,7 +741,7 @@ int iwl_mvm_tx_skb_non_sta(struct iwl_mv -- else -- sta_id = mvmvif->mcast_sta.sta_id; -- --- queue = iwl_mvm_get_ctrl_vif_queue(mvm, &info, hdr); --+ queue = iwl_mvm_get_ctrl_vif_queue(mvm, &info, skb); -- } else if (info.control.vif->type == NL80211_IFTYPE_MONITOR) { -- queue = mvm->snif_queue; -- sta_id = mvm->snif_sta.sta_id; ----- a/include/linux/ieee80211.h --+++ b/include/linux/ieee80211.h --@@ -772,20 +772,6 @@ static inline bool ieee80211_is_any_null -- } -- -- /** --- * ieee80211_is_bufferable_mmpdu - check if frame is bufferable MMPDU --- * @fc: frame control field in little-endian byteorder --- */ ---static inline bool ieee80211_is_bufferable_mmpdu(__le16 fc) ---{ --- /* IEEE 802.11-2012, definition of "bufferable management frame"; --- * note that this ignores the IBSS special case. */ --- return ieee80211_is_mgmt(fc) && --- (ieee80211_is_action(fc) || --- ieee80211_is_disassoc(fc) || --- ieee80211_is_deauth(fc)); ---} --- ---/** -- * ieee80211_is_first_frag - check if IEEE80211_SCTL_FRAG is not set -- * @seq_ctrl: frame sequence control bytes in little-endian byteorder -- */ --@@ -4121,6 +4107,44 @@ static inline u8 *ieee80211_get_DA(struc -- } -- -- /** --+ * ieee80211_is_bufferable_mmpdu - check if frame is bufferable MMPDU --+ * @skb: the skb to check, starting with the 802.11 header --+ */ --+static inline bool ieee80211_is_bufferable_mmpdu(struct sk_buff *skb) --+{ --+ struct ieee80211_mgmt *mgmt = (void *)skb->data; --+ __le16 fc = mgmt->frame_control; --+ --+ /* --+ * IEEE 802.11 REVme D2.0 definition of bufferable MMPDU; --+ * note that this ignores the IBSS special case. --+ */ --+ if (!ieee80211_is_mgmt(fc)) --+ return false; --+ --+ if (ieee80211_is_disassoc(fc) || ieee80211_is_deauth(fc)) --+ return true; --+ --+ if (!ieee80211_is_action(fc)) --+ return false; --+ --+ if (skb->len < offsetofend(typeof(*mgmt), u.action.u.ftm.action_code)) --+ return true; --+ --+ /* action frame - additionally check for non-bufferable FTM */ --+ --+ if (mgmt->u.action.category != WLAN_CATEGORY_PUBLIC && --+ mgmt->u.action.category != WLAN_CATEGORY_PROTECTED_DUAL_OF_ACTION) --+ return true; --+ --+ if (mgmt->u.action.u.ftm.action_code == WLAN_PUB_ACTION_FTM_REQUEST || --+ mgmt->u.action.u.ftm.action_code == WLAN_PUBLIC_ACTION_FTM_RESPONSE) --+ return false; --+ --+ return true; --+} --+ --+/** -- * _ieee80211_is_robust_mgmt_frame - check if frame is a robust management frame -- * @hdr: the frame (buffer must include at least the first octet of payload) -- */ ----- a/net/mac80211/tx.c --+++ b/net/mac80211/tx.c --@@ -488,7 +488,7 @@ ieee80211_tx_h_unicast_ps_buf(struct iee -- int ac = skb_get_queue_mapping(tx->skb); -- -- if (ieee80211_is_mgmt(hdr->frame_control) && --- !ieee80211_is_bufferable_mmpdu(hdr->frame_control)) { --+ !ieee80211_is_bufferable_mmpdu(tx->skb)) { -- info->flags |= IEEE80211_TX_CTL_NO_PS_BUFFER; -- return TX_CONTINUE; -- } --@@ -1326,7 +1326,7 @@ static struct txq_info *ieee80211_get_tx -- if (!(info->flags & IEEE80211_TX_CTL_HW_80211_ENCAP) && -- unlikely(!ieee80211_is_data_present(hdr->frame_control))) { -- if ((!ieee80211_is_mgmt(hdr->frame_control) || --- ieee80211_is_bufferable_mmpdu(hdr->frame_control) || --+ ieee80211_is_bufferable_mmpdu(skb) || -- vif->type == NL80211_IFTYPE_STATION) && -- sta && sta->uploaded) { -- /* -diff --git a/package/kernel/mac80211/patches/subsys/331-wifi-mac80211-flush-queues-on-STA-removal.patch b/package/kernel/mac80211/patches/subsys/331-wifi-mac80211-flush-queues-on-STA-removal.patch -deleted file mode 100644 -index 00232ec1b9..0000000000 ---- a/package/kernel/mac80211/patches/subsys/331-wifi-mac80211-flush-queues-on-STA-removal.patch -+++ /dev/null -@@ -1,36 +0,0 @@ --From: Johannes Berg --Date: Mon, 13 Mar 2023 11:42:12 +0100 --Subject: [PATCH] wifi: mac80211: flush queues on STA removal -- --When we remove a station, we first make it unreachable, --then we (must) remove its keys, and then remove the --station itself. Depending on the hardware design, if --we have hardware crypto at all, frames still sitting --on hardware queues may then be transmitted without a --valid key, possibly unencrypted or with a fixed key. -- --Fix this by flushing the queues when removing stations --so this cannot happen. -- --Cc: stable@vger.kernel.org --Signed-off-by: Johannes Berg --Reviewed-by: Greenman, Gregory ----- -- ----- a/net/mac80211/sta_info.c --+++ b/net/mac80211/sta_info.c --@@ -1271,6 +1271,14 @@ 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) --+ ieee80211_flush_queues(local, sta->sdata, false); --+ -- /* now keys can no longer be reached */ -- ieee80211_free_sta_keys(local, sta); -- -diff --git a/package/kernel/mac80211/patches/subsys/332-wifi-iwlwifi-mvm-support-flush-on-AP-interfaces.patch b/package/kernel/mac80211/patches/subsys/332-wifi-iwlwifi-mvm-support-flush-on-AP-interfaces.patch -deleted file mode 100644 -index 3c31dfeddc..0000000000 ---- a/package/kernel/mac80211/patches/subsys/332-wifi-iwlwifi-mvm-support-flush-on-AP-interfaces.patch -+++ /dev/null -@@ -1,34 +0,0 @@ --From: Johannes Berg --Date: Mon, 13 Mar 2023 12:02:58 +0100 --Subject: [PATCH] wifi: iwlwifi: mvm: support flush on AP interfaces -- --Support TX flush on AP interfaces so that we will do a --proper flush for frames on the queue before keys are --removed. -- --Signed-off-by: Johannes Berg --Reviewed-by: Greenman, Gregory ----- -- ----- a/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c --+++ b/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c --@@ -4854,9 +4854,6 @@ static void iwl_mvm_mac_flush(struct iee -- return; -- } -- --- if (vif->type != NL80211_IFTYPE_STATION) --- return; --- -- /* Make sure we're done with the deferred traffic before flushing */ -- flush_work(&mvm->add_stream_wk); -- --@@ -4874,9 +4871,6 @@ static void iwl_mvm_mac_flush(struct iee -- if (mvmsta->vif != vif) -- continue; -- --- /* make sure only TDLS peers or the AP are flushed */ --- WARN_ON(i != mvmvif->ap_sta_id && !sta->tdls); --- -- if (drop) { -- if (iwl_mvm_flush_sta(mvm, mvmsta, false)) -- IWL_ERR(mvm, "flush request fail\n"); -diff --git a/package/kernel/mac80211/patches/subsys/333-wifi-mac80211-add-flush_sta-method.patch b/package/kernel/mac80211/patches/subsys/333-wifi-mac80211-add-flush_sta-method.patch -deleted file mode 100644 -index 3bba0b7e66..0000000000 ---- a/package/kernel/mac80211/patches/subsys/333-wifi-mac80211-add-flush_sta-method.patch -+++ /dev/null -@@ -1,91 +0,0 @@ --From: Johannes Berg --Date: Mon, 13 Mar 2023 11:53:51 +0100 --Subject: [PATCH] wifi: mac80211: add flush_sta method -- --Some drivers like iwlwifi might have per-STA queues, so we --may want to flush/drop just those queues rather than all --when removing a station. Add a separate method for that. -- --Signed-off-by: Johannes Berg --Reviewed-by: Greenman, Gregory ----- -- ----- a/include/net/mac80211.h --+++ b/include/net/mac80211.h --@@ -3918,6 +3918,10 @@ struct ieee80211_prep_tx_info { -- * Note that vif can be NULL. -- * The callback can sleep. -- * --+ * @flush_sta: Flush or drop all pending frames from the hardware queue(s) for --+ * the given station, as it's about to be removed. --+ * The callback can sleep. --+ * -- * @channel_switch: Drivers that need (or want) to offload the channel -- * switch operation for CSAs received from the AP may implement this -- * callback. They must then call ieee80211_chswitch_done() to indicate --@@ -4372,6 +4376,8 @@ struct ieee80211_ops { -- #endif -- void (*flush)(struct ieee80211_hw *hw, struct ieee80211_vif *vif, -- u32 queues, bool drop); --+ void (*flush_sta)(struct ieee80211_hw *hw, struct ieee80211_vif *vif, --+ struct ieee80211_sta *sta); -- void (*channel_switch)(struct ieee80211_hw *hw, -- struct ieee80211_vif *vif, -- struct ieee80211_channel_switch *ch_switch); ----- a/net/mac80211/driver-ops.h --+++ b/net/mac80211/driver-ops.h --@@ -617,6 +617,21 @@ static inline void drv_flush(struct ieee -- trace_drv_return_void(local); -- } -- --+static inline void drv_flush_sta(struct ieee80211_local *local, --+ struct ieee80211_sub_if_data *sdata, --+ struct sta_info *sta) --+{ --+ might_sleep(); --+ --+ if (sdata && !check_sdata_in_driver(sdata)) --+ return; --+ --+ trace_drv_flush_sta(local, sdata, &sta->sta); --+ if (local->ops->flush_sta) --+ local->ops->flush_sta(&local->hw, &sdata->vif, &sta->sta); --+ trace_drv_return_void(local); --+} --+ -- static inline void drv_channel_switch(struct ieee80211_local *local, -- struct ieee80211_sub_if_data *sdata, -- struct ieee80211_channel_switch *ch_switch) ----- a/net/mac80211/sta_info.c --+++ b/net/mac80211/sta_info.c --@@ -1276,8 +1276,12 @@ static void __sta_info_destroy_part2(str -- * frames sitting on hardware queues might be sent out without -- * any encryption at all. -- */ --- if (local->ops->set_key) --- ieee80211_flush_queues(local, sta->sdata, false); --+ 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/trace.h --+++ b/net/mac80211/trace.h --@@ -1177,6 +1177,13 @@ TRACE_EVENT(drv_flush, -- ) -- ); -- --+DEFINE_EVENT(sta_event, drv_flush_sta, --+ TP_PROTO(struct ieee80211_local *local, --+ struct ieee80211_sub_if_data *sdata, --+ struct ieee80211_sta *sta), --+ TP_ARGS(local, sdata, sta) --+); --+ -- TRACE_EVENT(drv_channel_switch, -- TP_PROTO(struct ieee80211_local *local, -- struct ieee80211_sub_if_data *sdata, -diff --git a/package/kernel/mac80211/patches/subsys/334-wifi-iwlwifi-mvm-support-new-flush_sta-method.patch b/package/kernel/mac80211/patches/subsys/334-wifi-iwlwifi-mvm-support-new-flush_sta-method.patch -deleted file mode 100644 -index 18f39d505f..0000000000 ---- a/package/kernel/mac80211/patches/subsys/334-wifi-iwlwifi-mvm-support-new-flush_sta-method.patch -+++ /dev/null -@@ -1,53 +0,0 @@ --From: Johannes Berg --Date: Mon, 13 Mar 2023 12:05:35 +0100 --Subject: [PATCH] wifi: iwlwifi: mvm: support new flush_sta method -- --For iwlwifi this is simple to implement, and on newer hardware --it's an improvement since we have per-station queues. -- --Signed-off-by: Johannes Berg --Reviewed-by: Greenman, Gregory ----- -- ----- a/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c --+++ b/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c --@@ -4890,6 +4890,31 @@ static void iwl_mvm_mac_flush(struct iee -- iwl_trans_wait_tx_queues_empty(mvm->trans, msk); -- } -- --+static void iwl_mvm_mac_flush_sta(struct ieee80211_hw *hw, --+ struct ieee80211_vif *vif, --+ struct ieee80211_sta *sta) --+{ --+ struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw); --+ int i; --+ --+ mutex_lock(&mvm->mutex); --+ for (i = 0; i < mvm->fw->ucode_capa.num_stations; i++) { --+ struct iwl_mvm_sta *mvmsta; --+ struct ieee80211_sta *tmp; --+ --+ tmp = rcu_dereference_protected(mvm->fw_id_to_mac_id[i], --+ lockdep_is_held(&mvm->mutex)); --+ if (tmp != sta) --+ continue; --+ --+ mvmsta = iwl_mvm_sta_from_mac80211(sta); --+ --+ if (iwl_mvm_flush_sta(mvm, mvmsta, false)) --+ IWL_ERR(mvm, "flush request fail\n"); --+ } --+ mutex_unlock(&mvm->mutex); --+} --+ -- static int iwl_mvm_mac_get_survey(struct ieee80211_hw *hw, int idx, -- struct survey_info *survey) -- { --@@ -5417,6 +5442,7 @@ const struct ieee80211_ops iwl_mvm_hw_op -- .mgd_complete_tx = iwl_mvm_mac_mgd_complete_tx, -- .mgd_protect_tdls_discover = iwl_mvm_mac_mgd_protect_tdls_discover, -- .flush = iwl_mvm_mac_flush, --+ .flush_sta = iwl_mvm_mac_flush_sta, -- .sched_scan_start = iwl_mvm_mac_sched_scan_start, -- .sched_scan_stop = iwl_mvm_mac_sched_scan_stop, -- .set_key = iwl_mvm_mac_set_key, -diff --git a/package/kernel/mac80211/patches/subsys/335-wifi-mac80211-add-LDPC-related-flags-in-ieee80211_bs.patch b/package/kernel/mac80211/patches/subsys/335-wifi-mac80211-add-LDPC-related-flags-in-ieee80211_bs.patch -deleted file mode 100644 -index 1b379b76ae..0000000000 ---- a/package/kernel/mac80211/patches/subsys/335-wifi-mac80211-add-LDPC-related-flags-in-ieee80211_bs.patch -+++ /dev/null -@@ -1,62 +0,0 @@ --From: Ryder Lee --Date: Sat, 18 Feb 2023 01:49:25 +0800 --Subject: [PATCH] wifi: mac80211: add LDPC related flags in ieee80211_bss_conf -- --This is utilized to pass LDPC configurations from user space --(i.e. hostapd) to driver. -- --Signed-off-by: Ryder Lee --Link: https://lore.kernel.org/r/1de696aaa34efd77a926eb657b8c0fda05aaa177.1676628065.git.ryder.lee@mediatek.com --Signed-off-by: Johannes Berg ----- -- ----- a/include/net/mac80211.h --+++ b/include/net/mac80211.h --@@ -653,6 +653,9 @@ struct ieee80211_fils_discovery { -- * write-protected by sdata_lock and local->mtx so holding either is fine -- * for read access. -- * @color_change_color: the bss color that will be used after the change. --+ * @ht_ldpc: in AP mode, indicates interface has HT LDPC capability. --+ * @vht_ldpc: in AP mode, indicates interface has VHT LDPC capability. --+ * @he_ldpc: in AP mode, indicates interface has HE LDPC capability. -- * @vht_su_beamformer: in AP mode, does this BSS support operation as an VHT SU -- * beamformer -- * @vht_su_beamformee: in AP mode, does this BSS support operation as an VHT SU --@@ -744,6 +747,9 @@ struct ieee80211_bss_conf { -- bool color_change_active; -- u8 color_change_color; -- --+ bool ht_ldpc; --+ bool vht_ldpc; --+ bool he_ldpc; -- bool vht_su_beamformer; -- bool vht_su_beamformee; -- bool vht_mu_beamformer; ----- a/net/mac80211/cfg.c --+++ b/net/mac80211/cfg.c --@@ -1252,7 +1252,15 @@ static int ieee80211_start_ap(struct wip -- prev_beacon_int = link_conf->beacon_int; -- link_conf->beacon_int = params->beacon_interval; -- --+ if (params->ht_cap) --+ link_conf->ht_ldpc = --+ params->ht_cap->cap_info & --+ cpu_to_le16(IEEE80211_HT_CAP_LDPC_CODING); --+ -- if (params->vht_cap) { --+ link_conf->vht_ldpc = --+ params->vht_cap->vht_cap_info & --+ cpu_to_le32(IEEE80211_VHT_CAP_RXLDPC); -- link_conf->vht_su_beamformer = -- params->vht_cap->vht_cap_info & -- cpu_to_le32(IEEE80211_VHT_CAP_SU_BEAMFORMER_CAPABLE); --@@ -1282,6 +1290,9 @@ static int ieee80211_start_ap(struct wip -- } -- -- if (params->he_cap) { --+ link_conf->he_ldpc = --+ params->he_cap->phy_cap_info[1] & --+ IEEE80211_HE_PHY_CAP1_LDPC_CODING_IN_PAYLOAD; -- link_conf->he_su_beamformer = -- params->he_cap->phy_cap_info[3] & -- IEEE80211_HE_PHY_CAP3_SU_BEAMFORMER; -diff --git a/package/kernel/mac80211/patches/subsys/336-v6.4-wifi-mac80211-generate-EMA-beacons-in-AP-mode.patch b/package/kernel/mac80211/patches/subsys/336-v6.4-wifi-mac80211-generate-EMA-beacons-in-AP-mode.patch -deleted file mode 100644 -index 088f468e37..0000000000 ---- a/package/kernel/mac80211/patches/subsys/336-v6.4-wifi-mac80211-generate-EMA-beacons-in-AP-mode.patch -+++ /dev/null -@@ -1,372 +0,0 @@ --From bd54f3c29077f23dad92ef82a78061b40be30c65 Mon Sep 17 00:00:00 2001 --From: Aloka Dixit --Date: Mon, 5 Dec 2022 16:50:37 -0800 --Subject: [PATCH] wifi: mac80211: generate EMA beacons in AP mode -- --Add APIs to generate an array of beacons for an EMA AP (enhanced --multiple BSSID advertisements), each including a single MBSSID element. --EMA profile periodicity equals the count of elements. -- --- ieee80211_beacon_get_template_ema_list() - Generate and return all --EMA beacon templates. Drivers must call ieee80211_beacon_free_ema_list() --to free the memory. No change in the prototype for the existing API, --ieee80211_beacon_get_template(), which should be used for non-EMA AP. -- --- ieee80211_beacon_get_template_ema_index() - Generate a beacon which --includes the multiple BSSID element at the given index. Drivers can use --this function in a loop until NULL is returned which indicates end of --available MBSSID elements. -- --- ieee80211_beacon_free_ema_list() - free the memory allocated for the --list of EMA beacon templates. -- --Modify existing functions ieee80211_beacon_get_ap(), --ieee80211_get_mbssid_beacon_len() and ieee80211_beacon_add_mbssid() --to accept a new parameter for EMA index. -- --Signed-off-by: Aloka Dixit --Co-developed-by: John Crispin --Signed-off-by: John Crispin --Link: https://lore.kernel.org/r/20221206005040.3177-2-quic_alokad@quicinc.com --Signed-off-by: Johannes Berg ----- -- include/net/mac80211.h | 68 +++++++++++++++++++ -- net/mac80211/cfg.c | 11 +-- -- net/mac80211/ieee80211_i.h | 10 ++- -- net/mac80211/tx.c | 134 ++++++++++++++++++++++++++++++++++--- -- 4 files changed, 205 insertions(+), 18 deletions(-) -- ----- a/include/net/mac80211.h --+++ b/include/net/mac80211.h --@@ -5252,6 +5252,74 @@ ieee80211_beacon_get_template(struct iee -- unsigned int link_id); -- -- /** --+ * ieee80211_beacon_get_template_ema_index - EMA beacon template generation --+ * @hw: pointer obtained from ieee80211_alloc_hw(). --+ * @vif: &struct ieee80211_vif pointer from the add_interface callback. --+ * @offs: &struct ieee80211_mutable_offsets pointer to struct that will --+ * receive the offsets that may be updated by the driver. --+ * @link_id: the link id to which the beacon belongs (or 0 for a non-MLD AP). --+ * @ema_index: index of the beacon in the EMA set. --+ * --+ * This function follows the same rules as ieee80211_beacon_get_template() --+ * but returns a beacon template which includes multiple BSSID element at the --+ * requested index. --+ * --+ * Return: The beacon template. %NULL indicates the end of EMA templates. --+ */ --+struct sk_buff * --+ieee80211_beacon_get_template_ema_index(struct ieee80211_hw *hw, --+ struct ieee80211_vif *vif, --+ struct ieee80211_mutable_offsets *offs, --+ unsigned int link_id, u8 ema_index); --+ --+/** --+ * struct ieee80211_ema_beacons - List of EMA beacons --+ * @cnt: count of EMA beacons. --+ * --+ * @bcn: array of EMA beacons. --+ * @bcn.skb: the skb containing this specific beacon --+ * @bcn.offs: &struct ieee80211_mutable_offsets pointer to struct that will --+ * receive the offsets that may be updated by the driver. --+ */ --+struct ieee80211_ema_beacons { --+ u8 cnt; --+ struct { --+ struct sk_buff *skb; --+ struct ieee80211_mutable_offsets offs; --+ } bcn[]; --+}; --+ --+/** --+ * ieee80211_beacon_get_template_ema_list - EMA beacon template generation --+ * @hw: pointer obtained from ieee80211_alloc_hw(). --+ * @vif: &struct ieee80211_vif pointer from the add_interface callback. --+ * @link_id: the link id to which the beacon belongs (or 0 for a non-MLD AP) --+ * --+ * This function follows the same rules as ieee80211_beacon_get_template() --+ * but allocates and returns a pointer to list of all beacon templates required --+ * to cover all profiles in the multiple BSSID set. Each template includes only --+ * one multiple BSSID element. --+ * --+ * Driver must call ieee80211_beacon_free_ema_list() to free the memory. --+ * --+ * Return: EMA beacon templates of type struct ieee80211_ema_beacons *. --+ * %NULL on error. --+ */ --+struct ieee80211_ema_beacons * --+ieee80211_beacon_get_template_ema_list(struct ieee80211_hw *hw, --+ struct ieee80211_vif *vif, --+ unsigned int link_id); --+ --+/** --+ * ieee80211_beacon_free_ema_list - free an EMA beacon template list --+ * @ema_beacons: list of EMA beacons of type &struct ieee80211_ema_beacons pointers. --+ * --+ * This function will free a list previously acquired by calling --+ * ieee80211_beacon_get_template_ema_list() --+ */ --+void ieee80211_beacon_free_ema_list(struct ieee80211_ema_beacons *ema_beacons); --+ --+/** -- * ieee80211_beacon_get_tim - beacon generation function -- * @hw: pointer obtained from ieee80211_alloc_hw(). -- * @vif: &struct ieee80211_vif pointer from the add_interface callback. ----- a/net/mac80211/cfg.c --+++ b/net/mac80211/cfg.c --@@ -1122,11 +1122,11 @@ static int ieee80211_assign_beacon(struc -- if (params->mbssid_ies) { -- mbssid = params->mbssid_ies; -- size += struct_size(new->mbssid_ies, elem, mbssid->cnt); --- size += ieee80211_get_mbssid_beacon_len(mbssid); --+ size += ieee80211_get_mbssid_beacon_len(mbssid, mbssid->cnt); -- } else if (old && old->mbssid_ies) { -- mbssid = old->mbssid_ies; -- size += struct_size(new->mbssid_ies, elem, mbssid->cnt); --- size += ieee80211_get_mbssid_beacon_len(mbssid); --+ size += ieee80211_get_mbssid_beacon_len(mbssid, mbssid->cnt); -- } -- -- new = kzalloc(size, GFP_KERNEL); --@@ -3384,8 +3384,11 @@ cfg80211_beacon_dup(struct cfg80211_beac -- -- len = beacon->head_len + beacon->tail_len + beacon->beacon_ies_len + -- beacon->proberesp_ies_len + beacon->assocresp_ies_len + --- beacon->probe_resp_len + beacon->lci_len + beacon->civicloc_len + --- ieee80211_get_mbssid_beacon_len(beacon->mbssid_ies); --+ beacon->probe_resp_len + beacon->lci_len + beacon->civicloc_len; --+ --+ if (beacon->mbssid_ies) --+ len += ieee80211_get_mbssid_beacon_len(beacon->mbssid_ies, --+ beacon->mbssid_ies->cnt); -- -- new_beacon = kzalloc(sizeof(*new_beacon) + len, GFP_KERNEL); -- if (!new_beacon) ----- a/net/mac80211/ieee80211_i.h --+++ b/net/mac80211/ieee80211_i.h --@@ -1182,13 +1182,17 @@ ieee80211_vif_get_shift(struct ieee80211 -- } -- -- static inline int ---ieee80211_get_mbssid_beacon_len(struct cfg80211_mbssid_elems *elems) --+ieee80211_get_mbssid_beacon_len(struct cfg80211_mbssid_elems *elems, u8 i) -- { --- int i, len = 0; --+ int len = 0; -- --- if (!elems) --+ if (!elems || !elems->cnt || i > elems->cnt) -- return 0; -- --+ if (i < elems->cnt) --+ return elems->elem[i].len; --+ --+ /* i == elems->cnt, calculate total length of all MBSSID elements */ -- for (i = 0; i < elems->cnt; i++) -- len += elems->elem[i].len; -- ----- a/net/mac80211/tx.c --+++ b/net/mac80211/tx.c --@@ -5205,13 +5205,20 @@ ieee80211_beacon_get_finish(struct ieee8 -- } -- -- static void ---ieee80211_beacon_add_mbssid(struct sk_buff *skb, struct beacon_data *beacon) --+ieee80211_beacon_add_mbssid(struct sk_buff *skb, struct beacon_data *beacon, --+ u8 i) -- { --- int i; --+ if (!beacon->mbssid_ies || !beacon->mbssid_ies->cnt || --+ i > beacon->mbssid_ies->cnt) --+ return; -- --- if (!beacon->mbssid_ies) --+ if (i < beacon->mbssid_ies->cnt) { --+ skb_put_data(skb, beacon->mbssid_ies->elem[i].data, --+ beacon->mbssid_ies->elem[i].len); -- return; --+ } -- --+ /* i == beacon->mbssid_ies->cnt, include all MBSSID elements */ -- for (i = 0; i < beacon->mbssid_ies->cnt; i++) -- skb_put_data(skb, beacon->mbssid_ies->elem[i].data, -- beacon->mbssid_ies->elem[i].len); --@@ -5224,7 +5231,8 @@ ieee80211_beacon_get_ap(struct ieee80211 -- struct ieee80211_mutable_offsets *offs, -- bool is_template, -- struct beacon_data *beacon, --- struct ieee80211_chanctx_conf *chanctx_conf) --+ struct ieee80211_chanctx_conf *chanctx_conf, --+ u8 ema_index) -- { -- struct ieee80211_local *local = hw_to_local(hw); -- struct ieee80211_sub_if_data *sdata = vif_to_sdata(vif); --@@ -5243,7 +5251,9 @@ ieee80211_beacon_get_ap(struct ieee80211 -- /* headroom, head length, -- * tail length, maximum TIM length and multiple BSSID length -- */ --- mbssid_len = ieee80211_get_mbssid_beacon_len(beacon->mbssid_ies); --+ mbssid_len = ieee80211_get_mbssid_beacon_len(beacon->mbssid_ies, --+ ema_index); --+ -- skb = dev_alloc_skb(local->tx_headroom + beacon->head_len + -- beacon->tail_len + 256 + -- local->hw.extra_beacon_tailroom + mbssid_len); --@@ -5261,7 +5271,7 @@ ieee80211_beacon_get_ap(struct ieee80211 -- offs->cntdwn_counter_offs[0] = beacon->cntdwn_counter_offsets[0]; -- -- if (mbssid_len) { --- ieee80211_beacon_add_mbssid(skb, beacon); --+ ieee80211_beacon_add_mbssid(skb, beacon, ema_index); -- offs->mbssid_off = skb->len - mbssid_len; -- } -- --@@ -5280,12 +5290,51 @@ ieee80211_beacon_get_ap(struct ieee80211 -- return skb; -- } -- --+static struct ieee80211_ema_beacons * --+ieee80211_beacon_get_ap_ema_list(struct ieee80211_hw *hw, --+ struct ieee80211_vif *vif, --+ struct ieee80211_link_data *link, --+ struct ieee80211_mutable_offsets *offs, --+ bool is_template, struct beacon_data *beacon, --+ struct ieee80211_chanctx_conf *chanctx_conf) --+{ --+ struct ieee80211_ema_beacons *ema = NULL; --+ --+ if (!beacon->mbssid_ies || !beacon->mbssid_ies->cnt) --+ return NULL; --+ --+ ema = kzalloc(struct_size(ema, bcn, beacon->mbssid_ies->cnt), --+ GFP_ATOMIC); --+ if (!ema) --+ return NULL; --+ --+ for (ema->cnt = 0; ema->cnt < beacon->mbssid_ies->cnt; ema->cnt++) { --+ ema->bcn[ema->cnt].skb = --+ ieee80211_beacon_get_ap(hw, vif, link, --+ &ema->bcn[ema->cnt].offs, --+ is_template, beacon, --+ chanctx_conf, ema->cnt); --+ if (!ema->bcn[ema->cnt].skb) --+ break; --+ } --+ --+ if (ema->cnt == beacon->mbssid_ies->cnt) --+ return ema; --+ --+ ieee80211_beacon_free_ema_list(ema); --+ return NULL; --+} --+ --+#define IEEE80211_INCLUDE_ALL_MBSSID_ELEMS -1 --+ -- static struct sk_buff * -- __ieee80211_beacon_get(struct ieee80211_hw *hw, -- struct ieee80211_vif *vif, -- struct ieee80211_mutable_offsets *offs, -- bool is_template, --- unsigned int link_id) --+ unsigned int link_id, --+ int ema_index, --+ struct ieee80211_ema_beacons **ema_beacons) -- { -- struct ieee80211_local *local = hw_to_local(hw); -- struct beacon_data *beacon = NULL; --@@ -5314,8 +5363,29 @@ __ieee80211_beacon_get(struct ieee80211_ -- if (!beacon) -- goto out; -- --- skb = ieee80211_beacon_get_ap(hw, vif, link, offs, is_template, --- beacon, chanctx_conf); --+ if (ema_beacons) { --+ *ema_beacons = --+ ieee80211_beacon_get_ap_ema_list(hw, vif, link, --+ offs, --+ is_template, --+ beacon, --+ chanctx_conf); --+ } else { --+ if (beacon->mbssid_ies && beacon->mbssid_ies->cnt) { --+ if (ema_index >= beacon->mbssid_ies->cnt) --+ goto out; /* End of MBSSID elements */ --+ --+ if (ema_index <= IEEE80211_INCLUDE_ALL_MBSSID_ELEMS) --+ ema_index = beacon->mbssid_ies->cnt; --+ } else { --+ ema_index = 0; --+ } --+ --+ skb = ieee80211_beacon_get_ap(hw, vif, link, offs, --+ is_template, beacon, --+ chanctx_conf, --+ ema_index); --+ } -- } else if (sdata->vif.type == NL80211_IFTYPE_ADHOC) { -- struct ieee80211_if_ibss *ifibss = &sdata->u.ibss; -- struct ieee80211_hdr *hdr; --@@ -5403,10 +5473,50 @@ ieee80211_beacon_get_template(struct iee -- struct ieee80211_mutable_offsets *offs, -- unsigned int link_id) -- { --- return __ieee80211_beacon_get(hw, vif, offs, true, link_id); --+ return __ieee80211_beacon_get(hw, vif, offs, true, link_id, --+ IEEE80211_INCLUDE_ALL_MBSSID_ELEMS, NULL); -- } -- EXPORT_SYMBOL(ieee80211_beacon_get_template); -- --+struct sk_buff * --+ieee80211_beacon_get_template_ema_index(struct ieee80211_hw *hw, --+ struct ieee80211_vif *vif, --+ struct ieee80211_mutable_offsets *offs, --+ unsigned int link_id, u8 ema_index) --+{ --+ return __ieee80211_beacon_get(hw, vif, offs, true, link_id, ema_index, --+ NULL); --+} --+EXPORT_SYMBOL(ieee80211_beacon_get_template_ema_index); --+ --+void ieee80211_beacon_free_ema_list(struct ieee80211_ema_beacons *ema_beacons) --+{ --+ u8 i; --+ --+ if (!ema_beacons) --+ return; --+ --+ for (i = 0; i < ema_beacons->cnt; i++) --+ kfree_skb(ema_beacons->bcn[i].skb); --+ --+ kfree(ema_beacons); --+} --+EXPORT_SYMBOL(ieee80211_beacon_free_ema_list); --+ --+struct ieee80211_ema_beacons * --+ieee80211_beacon_get_template_ema_list(struct ieee80211_hw *hw, --+ struct ieee80211_vif *vif, --+ unsigned int link_id) --+{ --+ struct ieee80211_ema_beacons *ema_beacons = NULL; --+ --+ WARN_ON(__ieee80211_beacon_get(hw, vif, NULL, false, link_id, 0, --+ &ema_beacons)); --+ --+ return ema_beacons; --+} --+EXPORT_SYMBOL(ieee80211_beacon_get_template_ema_list); --+ -- struct sk_buff *ieee80211_beacon_get_tim(struct ieee80211_hw *hw, -- struct ieee80211_vif *vif, -- u16 *tim_offset, u16 *tim_length, --@@ -5414,7 +5524,9 @@ struct sk_buff *ieee80211_beacon_get_tim -- { -- struct ieee80211_mutable_offsets offs = {}; -- struct sk_buff *bcn = __ieee80211_beacon_get(hw, vif, &offs, false, --- link_id); --+ link_id, --+ IEEE80211_INCLUDE_ALL_MBSSID_ELEMS, --+ NULL); -- struct sk_buff *copy; -- int shift; -- -diff --git a/package/kernel/mac80211/patches/subsys/340-mac80211-always-use-mac80211-loss-detection.patch b/package/kernel/mac80211/patches/subsys/340-mac80211-always-use-mac80211-loss-detection.patch -deleted file mode 100644 -index e084773fd9..0000000000 ---- a/package/kernel/mac80211/patches/subsys/340-mac80211-always-use-mac80211-loss-detection.patch -+++ /dev/null -@@ -1,36 +0,0 @@ --From cdf461888f900c3a149b10a04d72b4a590ecdec3 Mon Sep 17 00:00:00 2001 --From: David Bauer --Date: Tue, 16 May 2023 23:11:32 +0200 --Subject: [PATCH] mac80211: always use mac80211 loss detection -- --ath10k does not report excessive loss in case of broken block-ack --sessions. The loss is communicated to the host-os, but ath10k does not --trigger a low-ack events by itself. -- --The mac80211 framework for loss detection however detects this --circumstance well in case of ath10k. So use it regardless of ath10k's --own loss detection mechanism. -- --Patching this in mac80211 does allow this hack to be used with any --flavor of ath10k/ath11k. -- --Signed-off-by: David Bauer ----- -- net/mac80211/status.c | 6 ------ -- 1 file changed, 6 deletions(-) -- ----- a/net/mac80211/status.c --+++ b/net/mac80211/status.c --@@ -794,12 +794,6 @@ static void ieee80211_lost_packet(struct -- unsigned long pkt_time = STA_LOST_PKT_TIME; -- unsigned int pkt_thr = STA_LOST_PKT_THRESHOLD; -- --- /* If driver relies on its own algorithm for station kickout, skip --- * mac80211 packet loss mechanism. --- */ --- if (ieee80211_hw_check(&sta->local->hw, REPORTS_LOW_ACK)) --- return; --- -- /* This packet was aggregated but doesn't carry status info */ -- if ((info->flags & IEEE80211_TX_CTL_AMPDU) && -- !(info->flags & IEEE80211_TX_STAT_AMPDU)) -diff --git a/package/kernel/mac80211/patches/subsys/400-allow-ibss-mixed.patch b/package/kernel/mac80211/patches/subsys/400-allow-ibss-mixed.patch -deleted file mode 100644 -index c38fa13f03..0000000000 ---- a/package/kernel/mac80211/patches/subsys/400-allow-ibss-mixed.patch -+++ /dev/null -@@ -1,40 +0,0 @@ --From: Hauke Mehrtens --Date: Mon, 24 Feb 2020 00:00:00 +0100 --Subject: [PATCH] mac80211: Allow IBSS mode and different beacon intervals -- --ath10k-ct supports the combination to select IBSS (ADHOC) mode and --different beacon intervals together. mac80211 does not like this --combination, but Ben says this is ok, so remove this check. -- --ath10k-ct starting with version 5.2 allows the combination of --NL80211_IFTYPE_ADHOC and beacon_int_min_gcd in ath10k_10x_ct_if_comb --which triggers this warning. Ben told me that this is not a big problem --and we should ignore this. ----- -- net/wireless/core.c | 15 --------------- -- 1 file changed, 15 deletions(-) -- ----- a/net/wireless/core.c --+++ b/net/wireless/core.c --@@ -614,21 +614,6 @@ static int wiphy_verify_combinations(str -- c->limits[j].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) && --- c->beacon_int_min_gcd)) { --- return -EINVAL; --- } --- -- cnt += c->limits[j].max; -- /* -- * Don't advertise an unsupported type -diff --git a/package/kernel/mac80211/patches/subsys/500-mac80211_configure_antenna_gain.patch b/package/kernel/mac80211/patches/subsys/500-mac80211_configure_antenna_gain.patch -deleted file mode 100644 -index 4a3984fb42..0000000000 ---- a/package/kernel/mac80211/patches/subsys/500-mac80211_configure_antenna_gain.patch -+++ /dev/null -@@ -1,162 +0,0 @@ ----- a/include/net/cfg80211.h --+++ b/include/net/cfg80211.h --@@ -4081,6 +4081,7 @@ struct mgmt_frame_regs { -- * (as advertised by the nl80211 feature flag.) -- * @get_tx_power: store the current TX power into the dbm variable; -- * return 0 if successful --+ * @set_antenna_gain: set antenna gain to reduce maximum tx power if necessary -- * -- * @rfkill_poll: polls the hw rfkill line, use cfg80211 reporting -- * functions to adjust rfkill hw state --@@ -4431,6 +4432,7 @@ struct cfg80211_ops { -- enum nl80211_tx_power_setting type, int mbm); -- int (*get_tx_power)(struct wiphy *wiphy, struct wireless_dev *wdev, -- int *dbm); --+ int (*set_antenna_gain)(struct wiphy *wiphy, int dbi); -- -- void (*rfkill_poll)(struct wiphy *wiphy); -- ----- a/include/net/mac80211.h --+++ b/include/net/mac80211.h --@@ -1677,6 +1677,7 @@ enum ieee80211_smps_mode { -- * -- * @power_level: requested transmit power (in dBm), backward compatibility -- * value only that is set to the minimum of all interfaces --+ * @max_antenna_gain: maximum antenna gain adjusted by user config (in dBi) -- * -- * @chandef: the channel definition to tune to -- * @radar_enabled: whether radar detection is enabled --@@ -1697,6 +1698,7 @@ enum ieee80211_smps_mode { -- struct ieee80211_conf { -- u32 flags; -- int power_level, dynamic_ps_timeout; --+ int max_antenna_gain; -- -- u16 listen_interval; -- u8 ps_dtim_period; ----- a/include/uapi/linux/nl80211.h --+++ b/include/uapi/linux/nl80211.h --@@ -2749,6 +2749,9 @@ enum nl80211_commands { -- * When used with %NL80211_CMD_FRAME_TX_STATUS, indicates the ack RX -- * timestamp. When used with %NL80211_CMD_FRAME RX notification, indicates -- * the incoming frame RX timestamp. --+ * @NL80211_ATTR_WIPHY_ANTENNA_GAIN: Configured antenna gain. Used to reduce --+ * transmit power to stay within regulatory limits. u32, dBi. --+ * -- * @NUM_NL80211_ATTR: total number of nl80211_attrs available -- * @NL80211_ATTR_MAX: highest attribute number currently defined -- * @__NL80211_ATTR_AFTER_LAST: internal use --@@ -3277,6 +3280,8 @@ enum nl80211_attrs { -- NL80211_ATTR_TX_HW_TIMESTAMP, -- NL80211_ATTR_RX_HW_TIMESTAMP, -- --+ NL80211_ATTR_WIPHY_ANTENNA_GAIN, --+ -- /* add attributes here, update the policy in nl80211.c */ -- -- __NL80211_ATTR_AFTER_LAST, ----- a/net/mac80211/cfg.c --+++ b/net/mac80211/cfg.c --@@ -3046,6 +3046,19 @@ static int ieee80211_get_tx_power(struct -- return 0; -- } -- --+static int ieee80211_set_antenna_gain(struct wiphy *wiphy, int dbi) --+{ --+ struct ieee80211_local *local = wiphy_priv(wiphy); --+ --+ if (dbi < 0) --+ return -EINVAL; --+ --+ local->user_antenna_gain = dbi; --+ ieee80211_hw_config(local, 0); --+ --+ return 0; --+} --+ -- static void ieee80211_rfkill_poll(struct wiphy *wiphy) -- { -- struct ieee80211_local *local = wiphy_priv(wiphy); --@@ -4956,6 +4969,7 @@ const struct cfg80211_ops mac80211_confi -- .set_wiphy_params = ieee80211_set_wiphy_params, -- .set_tx_power = ieee80211_set_tx_power, -- .get_tx_power = ieee80211_get_tx_power, --+ .set_antenna_gain = ieee80211_set_antenna_gain, -- .rfkill_poll = ieee80211_rfkill_poll, -- CFG80211_TESTMODE_CMD(ieee80211_testmode_cmd) -- CFG80211_TESTMODE_DUMP(ieee80211_testmode_dump) ----- a/net/mac80211/ieee80211_i.h --+++ b/net/mac80211/ieee80211_i.h --@@ -1542,6 +1542,7 @@ struct ieee80211_local { -- int dynamic_ps_forced_timeout; -- -- int user_power_level; /* in dBm, for all interfaces */ --+ int user_antenna_gain; /* in dBi */ -- -- enum ieee80211_smps_mode smps_mode; -- ----- a/net/mac80211/main.c --+++ b/net/mac80211/main.c --@@ -96,7 +96,7 @@ static u32 ieee80211_hw_conf_chan(struct -- struct ieee80211_sub_if_data *sdata; -- struct cfg80211_chan_def chandef = {}; -- u32 changed = 0; --- int power; --+ int power, max_power; -- u32 offchannel_flag; -- -- offchannel_flag = local->hw.conf.flags & IEEE80211_CONF_OFFCHANNEL; --@@ -157,6 +157,12 @@ static u32 ieee80211_hw_conf_chan(struct -- } -- rcu_read_unlock(); -- --+ max_power = chandef.chan->max_reg_power; --+ if (local->user_antenna_gain > 0) { --+ max_power -= local->user_antenna_gain; --+ power = min(power, max_power); --+ } --+ -- if (local->hw.conf.power_level != power) { -- changed |= IEEE80211_CONF_CHANGE_POWER; -- local->hw.conf.power_level = power; --@@ -762,6 +768,7 @@ struct ieee80211_hw *ieee80211_alloc_hw_ -- IEEE80211_RADIOTAP_MCS_HAVE_BW; -- local->hw.radiotap_vht_details = IEEE80211_RADIOTAP_VHT_KNOWN_GI | -- IEEE80211_RADIOTAP_VHT_KNOWN_BANDWIDTH; --+ local->user_antenna_gain = 0; -- local->hw.uapsd_queues = IEEE80211_DEFAULT_UAPSD_QUEUES; -- local->hw.uapsd_max_sp_len = IEEE80211_DEFAULT_MAX_SP_LEN; -- local->hw.max_mtu = IEEE80211_MAX_DATA_LEN; ----- a/net/wireless/nl80211.c --+++ b/net/wireless/nl80211.c --@@ -799,6 +799,7 @@ static const struct nla_policy nl80211_p -- [NL80211_ATTR_MLD_ADDR] = NLA_POLICY_EXACT_LEN(ETH_ALEN), -- [NL80211_ATTR_MLO_SUPPORT] = { .type = NLA_FLAG }, -- [NL80211_ATTR_MAX_NUM_AKM_SUITES] = { .type = NLA_REJECT }, --+ [NL80211_ATTR_WIPHY_ANTENNA_GAIN] = { .type = NLA_U32 }, -- }; -- -- /* policy for the key attributes */ --@@ -3511,6 +3512,22 @@ static int nl80211_set_wiphy(struct sk_b -- if (result) -- goto out; -- } --+ --+ if (info->attrs[NL80211_ATTR_WIPHY_ANTENNA_GAIN]) { --+ int idx, dbi = 0; --+ --+ if (!rdev->ops->set_antenna_gain) { --+ result = -EOPNOTSUPP; --+ goto out; --+ } --+ --+ idx = NL80211_ATTR_WIPHY_ANTENNA_GAIN; --+ dbi = nla_get_u32(info->attrs[idx]); --+ --+ result = rdev->ops->set_antenna_gain(&rdev->wiphy, dbi); --+ if (result) --+ goto out; --+ } -- -- if (info->attrs[NL80211_ATTR_WIPHY_TX_POWER_SETTING]) { -- struct wireless_dev *txp_wdev = wdev; -diff --git a/package/kernel/mac80211/patches/subsys/782-net-next-1-of-net-pass-the-dst-buffer-to-of_get_mac_address.patch b/package/kernel/mac80211/patches/subsys/782-net-next-1-of-net-pass-the-dst-buffer-to-of_get_mac_address.patch -deleted file mode 100644 -index 26af6a2fb9..0000000000 ---- a/package/kernel/mac80211/patches/subsys/782-net-next-1-of-net-pass-the-dst-buffer-to-of_get_mac_address.patch -+++ /dev/null -@@ -1,29 +0,0 @@ ----- a/backport-include/linux/of_net.h --+++ /dev/null --@@ -1,26 +0,0 @@ ---#ifndef _BP_OF_NET_H ---#define _BP_OF_NET_H ---#include_next ---#include ---#include --- ---/* The behavior of of_get_mac_address() changed in kernel 5.2, it now --- * returns an error code and not NULL in case of an error. --- */ ---#if LINUX_VERSION_IS_LESS(5,13,0) ---static inline int backport_of_get_mac_address(struct device_node *np, u8 *mac_out) ---{ --- const void *mac = of_get_mac_address(np); --- --- if (!mac) --- return -ENODEV; --- if (IS_ERR(mac)) --- return PTR_ERR(mac); --- ether_addr_copy(mac_out, mac); --- --- return 0; ---} ---#define of_get_mac_address LINUX_BACKPORT(of_get_mac_address) ---#endif /* < 5.2 */ --- ---#endif /* _BP_OF_NET_H */ -diff --git a/package/kernel/mac80211/ralink.mk b/package/kernel/mac80211/ralink.mk -deleted file mode 100644 -index 83d208ee1a..0000000000 ---- a/package/kernel/mac80211/ralink.mk -+++ /dev/null -@@ -1,131 +0,0 @@ --PKG_DRIVERS += \ -- rt2x00-lib rt2x00-pci rt2x00-usb rt2x00-mmio \ -- rt2800-lib rt2800-mmio rt2800-pci rt2800-soc rt2800-usb -- --PKG_CONFIG_DEPENDS += \ -- CONFIG_PACKAGE_RT2X00_LIB_DEBUGFS \ -- CONFIG_PACKAGE_RT2X00_DEBUG -- --config-$(call config_package,rt2x00-lib) += RT2X00 RT2X00_LIB --config-$(call config_package,rt2x00-pci) += RT2X00_LIB_PCI --config-$(call config_package,rt2x00-mmio) += RT2X00_LIB_MMIO --config-$(call config_package,rt2x00-usb) += RT2X00_LIB_USB --config-$(CONFIG_PACKAGE_RT2X00_LIB_DEBUGFS) += RT2X00_LIB_DEBUGFS --config-$(CONFIG_PACKAGE_RT2X00_DEBUG) += RT2X00_DEBUG -- --config-$(call config_package,rt2400-pci) += RT2400PCI --config-$(call config_package,rt2500-pci) += RT2500PCI --config-$(call config_package,rt2500-usb) += RT2500USB --config-$(call config_package,rt61-pci) += RT61PCI --config-$(call config_package,rt73-usb) += RT73USB -- --config-$(call config_package,rt2800-lib) += RT2800_LIB -- --config-$(call config_package,rt2800-soc) += RT2800SOC --config-$(call config_package,rt2800-pci) += RT2800PCI --config-y += RT2800PCI_RT33XX RT2800PCI_RT35XX RT2800PCI_RT53XX RT2800PCI_RT3290 -- --config-$(call config_package,rt2800-usb) += RT2800USB --config-y += RT2800USB_RT33XX RT2800USB_RT35XX RT2800USB_RT3573 RT2800USB_RT53XX RT2800USB_RT55XX RT2800USB_UNKNOWN -- --define KernelPackage/rt2x00/Default -- $(call KernelPackage/mac80211/Default) -- TITLE:=Ralink Drivers for RT2x00 cards --endef -- --define KernelPackage/rt2x00-lib --$(call KernelPackage/rt2x00/Default) -- DEPENDS+= @(PCI_SUPPORT||USB_SUPPORT||TARGET_ramips) +kmod-mac80211 -- TITLE+= (LIB) -- FILES:=$(PKG_BUILD_DIR)/drivers/net/wireless/ralink/rt2x00/rt2x00lib.ko -- MENU:=1 --endef -- --define KernelPackage/rt2x00-lib/config -- if PACKAGE_kmod-rt2x00-lib -- -- config PACKAGE_RT2X00_LIB_DEBUGFS -- bool "Enable rt2x00 debugfs support" -- depends on PACKAGE_MAC80211_DEBUGFS -- help -- Enable creation of debugfs files for the rt2x00 drivers. -- These debugfs files support both reading and writing of the -- most important register types of the rt2x00 hardware. -- -- config PACKAGE_RT2X00_DEBUG -- bool "Enable rt2x00 debug output" -- help -- Enable debugging output for all rt2x00 modules -- -- endif --endef -- --define KernelPackage/rt2x00-mmio --$(call KernelPackage/rt2x00/Default) -- DEPENDS+= @(PCI_SUPPORT||TARGET_ramips) +kmod-rt2x00-lib -- HIDDEN:=1 -- TITLE+= (MMIO) -- FILES:= $(PKG_BUILD_DIR)/drivers/net/wireless/ralink/rt2x00/rt2x00mmio.ko --endef -- --define KernelPackage/rt2x00-pci --$(call KernelPackage/rt2x00/Default) -- DEPENDS+= @PCI_SUPPORT +kmod-rt2x00-mmio +kmod-rt2x00-lib -- HIDDEN:=1 -- TITLE+= (PCI) -- FILES:= $(PKG_BUILD_DIR)/drivers/net/wireless/ralink/rt2x00/rt2x00pci.ko -- AUTOLOAD:=$(call AutoProbe,rt2x00pci) --endef -- --define KernelPackage/rt2x00-usb --$(call KernelPackage/rt2x00/Default) -- DEPENDS+= @USB_SUPPORT +kmod-rt2x00-lib +kmod-usb-core -- HIDDEN:=1 -- TITLE+= (USB) -- FILES:=$(PKG_BUILD_DIR)/drivers/net/wireless/ralink/rt2x00/rt2x00usb.ko -- AUTOLOAD:=$(call AutoProbe,rt2x00usb) --endef -- --define KernelPackage/rt2800-lib --$(call KernelPackage/rt2x00/Default) -- DEPENDS+= @(PCI_SUPPORT||USB_SUPPORT||TARGET_ramips) +kmod-rt2x00-lib +kmod-lib-crc-ccitt -- HIDDEN:=1 -- TITLE+= (rt2800 LIB) -- FILES:=$(PKG_BUILD_DIR)/drivers/net/wireless/ralink/rt2x00/rt2800lib.ko --endef -- --define KernelPackage/rt2800-mmio --$(call KernelPackage/rt2x00/Default) -- TITLE += (RT28xx/RT3xxx MMIO) -- DEPENDS += +kmod-rt2800-lib +kmod-rt2x00-mmio -- HIDDEN:=1 -- FILES:=$(PKG_BUILD_DIR)/drivers/net/wireless/ralink/rt2x00/rt2800mmio.ko --endef -- --define KernelPackage/rt2800-soc --$(call KernelPackage/rt2x00/Default) -- DEPENDS += @(TARGET_ramips_rt288x||TARGET_ramips_rt305x||TARGET_ramips_rt3883||TARGET_ramips_mt7620) +kmod-rt2800-mmio +kmod-rt2800-lib -- TITLE += (RT28xx/RT3xxx SoC) -- FILES := \ -- $(PKG_BUILD_DIR)/drivers/net/wireless/ralink/rt2x00/rt2x00soc.ko \ -- $(PKG_BUILD_DIR)/drivers/net/wireless/ralink/rt2x00/rt2800soc.ko -- AUTOLOAD:=$(call AutoProbe,rt2800soc) --endef -- --define KernelPackage/rt2800-pci --$(call KernelPackage/rt2x00/Default) -- DEPENDS+= @PCI_SUPPORT +kmod-rt2x00-pci +kmod-rt2800-lib +kmod-rt2800-mmio +kmod-eeprom-93cx6 +rt2800-pci-firmware -- TITLE+= (RT2860 PCI) -- FILES:=$(PKG_BUILD_DIR)/drivers/net/wireless/ralink/rt2x00/rt2800pci.ko -- AUTOLOAD:=$(call AutoProbe,rt2800pci) --endef -- --define KernelPackage/rt2800-usb --$(call KernelPackage/rt2x00/Default) -- DEPENDS+= @USB_SUPPORT +kmod-rt2x00-usb +kmod-rt2800-lib +kmod-lib-crc-ccitt +rt2800-usb-firmware -- TITLE+= (RT2870 USB) -- FILES:=$(PKG_BUILD_DIR)/drivers/net/wireless/ralink/rt2x00/rt2800usb.ko -- AUTOLOAD:=$(call AutoProbe,rt2800usb) --endef -- -- -diff --git a/package/kernel/mac80211/realtek.mk b/package/kernel/mac80211/realtek.mk -deleted file mode 100644 -index 9c14358326..0000000000 ---- a/package/kernel/mac80211/realtek.mk -+++ /dev/null -@@ -1,197 +0,0 @@ --PKG_DRIVERS += \ -- rtlwifi rtlwifi-pci rtlwifi-btcoexist rtlwifi-usb rtl8192c-common \ -- rtl8192ce rtl8192se rtl8192de rtl8192cu rtl8723bs rtl8821ae \ -- rtl8xxxu rtw88 -- --config-$(call config_package,rtlwifi) += RTL_CARDS RTLWIFI --config-$(call config_package,rtlwifi-pci) += RTLWIFI_PCI --config-$(call config_package,rtlwifi-btcoexist) += RTLBTCOEXIST --config-$(call config_package,rtlwifi-usb) += RTLWIFI_USB --config-$(call config_package,rtl8192c-common) += RTL8192C_COMMON --config-$(call config_package,rtl8192ce) += RTL8192CE --config-$(call config_package,rtl8192se) += RTL8192SE --config-$(call config_package,rtl8192de) += RTL8192DE --config-$(call config_package,rtl8192cu) += RTL8192CU --config-$(call config_package,rtl8821ae) += RTL8821AE --config-$(CONFIG_PACKAGE_RTLWIFI_DEBUG) += RTLWIFI_DEBUG -- --config-$(call config_package,rtl8xxxu) += RTL8XXXU --config-y += RTL8XXXU_UNTESTED -- --config-$(call config_package,rtl8723bs) += RTL8723BS --config-y += STAGING -- --config-$(call config_package,rtw88) += RTW88 RTW88_CORE RTW88_PCI --config-y += RTW88_8822BE RTW88_8822CE RTW88_8723DE --config-$(CONFIG_PACKAGE_RTW88_DEBUG) += RTW88_DEBUG --config-$(CONFIG_PACKAGE_RTW88_DEBUGFS) += RTW88_DEBUGFS -- --define KernelPackage/rtlwifi/config -- config PACKAGE_RTLWIFI_DEBUG -- bool "Realtek wireless debugging" -- depends on PACKAGE_kmod-rtlwifi -- help -- Say Y, if you want to debug realtek wireless drivers. -- --endef -- --define KernelPackage/rtlwifi -- $(call KernelPackage/mac80211/Default) -- TITLE:=Realtek common driver part -- DEPENDS+= @(PCI_SUPPORT||USB_SUPPORT) +kmod-mac80211 -- FILES:=$(PKG_BUILD_DIR)/drivers/net/wireless/realtek/rtlwifi/rtlwifi.ko -- HIDDEN:=1 --endef -- --define KernelPackage/rtlwifi-pci -- $(call KernelPackage/mac80211/Default) -- TITLE:=Realtek common driver part (PCI support) -- DEPENDS+= @PCI_SUPPORT +kmod-rtlwifi -- FILES:=$(PKG_BUILD_DIR)/drivers/net/wireless/realtek/rtlwifi/rtl_pci.ko -- AUTOLOAD:=$(call AutoProbe,rtl_pci) -- HIDDEN:=1 --endef -- --define KernelPackage/rtlwifi-btcoexist -- $(call KernelPackage/mac80211/Default) -- TITLE:=Realtek BT coexist support -- DEPENDS+= +kmod-rtlwifi -- FILES:=$(PKG_BUILD_DIR)/drivers/net/wireless/realtek/rtlwifi/btcoexist/btcoexist.ko -- AUTOLOAD:=$(call AutoProbe,btcoexist) -- HIDDEN:=1 --endef -- --define KernelPackage/rtlwifi-usb -- $(call KernelPackage/mac80211/Default) -- TITLE:=Realtek common driver part (USB support) -- DEPENDS+= @USB_SUPPORT +kmod-usb-core +kmod-rtlwifi -- FILES:=$(PKG_BUILD_DIR)/drivers/net/wireless/realtek/rtlwifi/rtl_usb.ko -- AUTOLOAD:=$(call AutoProbe,rtl_usb) -- HIDDEN:=1 --endef -- --define KernelPackage/rtl8192c-common -- $(call KernelPackage/mac80211/Default) -- TITLE:=Realtek RTL8192CE/RTL8192CU common support module -- DEPENDS+= +kmod-rtlwifi -- FILES:= $(PKG_BUILD_DIR)/drivers/net/wireless/realtek/rtlwifi/rtl8192c/rtl8192c-common.ko -- HIDDEN:=1 --endef -- --define KernelPackage/rtl8192ce -- $(call KernelPackage/mac80211/Default) -- TITLE:=Realtek RTL8192CE/RTL8188CE support -- DEPENDS+= +kmod-rtlwifi-pci +kmod-rtl8192c-common +rtl8192ce-firmware -- FILES:= $(PKG_BUILD_DIR)/drivers/net/wireless/realtek/rtlwifi/rtl8192ce/rtl8192ce.ko -- AUTOLOAD:=$(call AutoProbe,rtl8192ce) --endef -- --define KernelPackage/rtl8192se -- $(call KernelPackage/mac80211/Default) -- TITLE:=Realtek RTL8192SE/RTL8191SE support -- DEPENDS+= +kmod-rtlwifi-pci +rtl8192se-firmware -- FILES:=$(PKG_BUILD_DIR)/drivers/net/wireless/realtek/rtlwifi/rtl8192se/rtl8192se.ko -- AUTOLOAD:=$(call AutoProbe,rtl8192se) --endef -- --define KernelPackage/rtl8192de -- $(call KernelPackage/mac80211/Default) -- TITLE:=Realtek RTL8192DE/RTL8188DE support -- DEPENDS+= +kmod-rtlwifi-pci +rtl8192de-firmware -- FILES:= $(PKG_BUILD_DIR)/drivers/net/wireless/realtek/rtlwifi/rtl8192de/rtl8192de.ko -- AUTOLOAD:=$(call AutoProbe,rtl8192de) --endef -- --define KernelPackage/rtl8192cu -- $(call KernelPackage/mac80211/Default) -- TITLE:=Realtek RTL8192CU/RTL8188CU support -- DEPENDS+= +kmod-rtlwifi-usb +kmod-rtl8192c-common +rtl8192cu-firmware -- FILES:= $(PKG_BUILD_DIR)/drivers/net/wireless/realtek/rtlwifi/rtl8192cu/rtl8192cu.ko -- AUTOLOAD:=$(call AutoProbe,rtl8192cu) --endef -- --define KernelPackage/rtl8821ae -- $(call KernelPackage/mac80211/Default) -- TITLE:=Realtek RTL8821AE support -- DEPENDS+= +kmod-rtlwifi-btcoexist +kmod-rtlwifi-pci +rtl8821ae-firmware -- FILES:= $(PKG_BUILD_DIR)/drivers/net/wireless/realtek/rtlwifi/rtl8821ae/rtl8821ae.ko -- AUTOLOAD:=$(call AutoProbe,rtl8821ae) --endef -- --define KernelPackage/rtl8xxxu -- $(call KernelPackage/mac80211/Default) -- TITLE:=alternative Realtek RTL8XXXU support -- DEPENDS+= @USB_SUPPORT +kmod-usb-core +kmod-mac80211 -- FILES:= $(PKG_BUILD_DIR)/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu.ko -- AUTOLOAD:=$(call AutoProbe,rtl8xxxu) --endef -- --define KernelPackage/rtl8xxxu/description -- This is an alternative driver for various Realtek RTL8XXX -- parts written to utilize the Linux mac80211 stack. -- The driver is known to work with a number of RTL8723AU, -- RL8188CU, RTL8188RU, RTL8191CU, and RTL8192CU devices -- -- This driver is under development and has a limited feature -- set. In particular it does not yet support 40MHz channels -- and power management. However it should have a smaller -- memory footprint than the vendor drivers and benetifs -- from the in kernel mac80211 stack. -- -- It can coexist with drivers from drivers/staging/rtl8723au, -- drivers/staging/rtl8192u, and drivers/net/wireless/rtlwifi, -- but you will need to control which module you wish to load. -- -- RTL8XXXU_UNTESTED is enabled -- This option enables detection of Realtek 8723/8188/8191/8192 WiFi -- USB devices which have not been tested directly by the driver -- author or reported to be working by third parties. -- -- Please report your results! --endef -- --define KernelPackage/rtw88/config -- config PACKAGE_RTW88_DEBUG -- bool "Realtek wireless debugging (rtw88)" -- depends on PACKAGE_kmod-rtw88 -- help -- Enable debugging output for rtw88 devices -- -- config PACKAGE_RTW88_DEBUGFS -- bool "Enable rtw88 debugfS support" -- select KERNEL_DEBUG_FS -- depends on PACKAGE_kmod-rtw88 -- help -- Select this to see extensive information about -- the internal state of rtw88 in debugfs. --endef -- --define KernelPackage/rtw88 -- $(call KernelPackage/mac80211/Default) -- TITLE:=Realtek RTL8822BE/RTL8822CE/RTL8723DE -- DEPENDS+= @(PCI_SUPPORT) +kmod-mac80211 +@DRIVER_11AC_SUPPORT -- FILES:=\ -- $(PKG_BUILD_DIR)/drivers/net/wireless/realtek/rtw88/rtw88_8822be.ko \ -- $(PKG_BUILD_DIR)/drivers/net/wireless/realtek/rtw88/rtw88_8822b.ko \ -- $(PKG_BUILD_DIR)/drivers/net/wireless/realtek/rtw88/rtw88_8822ce.ko \ -- $(PKG_BUILD_DIR)/drivers/net/wireless/realtek/rtw88/rtw88_8822c.ko \ -- $(PKG_BUILD_DIR)/drivers/net/wireless/realtek/rtw88/rtw88_8723de.ko \ -- $(PKG_BUILD_DIR)/drivers/net/wireless/realtek/rtw88/rtw88_8723d.ko \ -- $(PKG_BUILD_DIR)/drivers/net/wireless/realtek/rtw88/rtw88_core.ko \ -- $(PKG_BUILD_DIR)/drivers/net/wireless/realtek/rtw88/rtw88_pci.ko -- AUTOLOAD:=$(call AutoProbe,rtw88_8822be rtw88_8822ce rtw88_8723de) --endef -- --define KernelPackage/rtl8723bs -- $(call KernelPackage/mac80211/Default) -- TITLE:=Realtek RTL8723BS SDIO Wireless LAN NIC driver (staging) -- DEPENDS+=+kmod-mmc +kmod-mac80211 -- FILES:=$(PKG_BUILD_DIR)/drivers/staging/rtl8723bs/r8723bs.ko -- AUTOLOAD:=$(call AutoProbe,r8723bs) --endef -- --define KernelPackage/rtl8723bs/description -- This option enables support for RTL8723BS SDIO drivers, such as the wifi found -- on the 1st gen Intel Compute Stick, the CHIP and many other Intel Atom and ARM -- based devices. --endef -diff --git a/package/kernel/mac80211/scripts/import-backports.sh b/package/kernel/mac80211/scripts/import-backports.sh -deleted file mode 100755 -index 35aa411e6c..0000000000 ---- a/package/kernel/mac80211/scripts/import-backports.sh -+++ /dev/null -@@ -1,109 +0,0 @@ --#!/usr/bin/env bash --BASE=$1; shift -- --usage() { -- echo "Usage: $0 NNN ..." -- exit 1 --} -- --check_number() { -- case "$1" in -- [0-9][0-9][0-9]) return 0;; -- esac -- return 1; --} -- --patch_header() --{ -- awk ' -- /^(---|\*\*\*|Index:)[ \t][^ \t]|^diff -/ \ -- { exit } -- { print } -- ' --} -- --strip_diffstat() --{ -- awk ' -- /#? .* \| / \ -- { eat = eat $0 "\n" -- next } -- /^#? .* files? changed(, .* insertions?\(\+\))?(, .* deletions?\(-\))?/ \ -- { eat = "" -- next } -- { print eat $0 -- eat = "" } -- ' --} -- --strip_trailing_whitespace() { -- sed -e 's:[ '$'\t'']*$::' --} -- --fixup_header() { -- awk ' -- /^From / { next } -- /^Subject: / { -- sub("Subject: \\[[^\]]*\\]", "Subject: [PATCH]") -- } -- { print } -- ' --} -- --check_number "$BASE" || usage -- --quilt series > /dev/null || { -- echo "Not in quilt directory" -- exit 2 --} -- --get_next() { -- NEW=$BASE -- quilt series | while read CUR; do -- [ -n "$CUR" ] || break -- CUR=${CUR%%-*} -- check_number "$CUR" || continue -- [ "$CUR" -lt "$NEW" ] && continue -- [ "$CUR" -ge "$(($BASE + 100))" ] && continue -- NEW="$(($CUR + 1))" -- echo $NEW -- done | tail -n1 --} -- --CUR=$(get_next) --CUR="${CUR:-$BASE}" -- --while [ -n "$1" ]; do -- FILE="$1"; shift -- NAME="$(basename $FILE)" -- NAME="${NAME#[0-9]*-}" -- echo -n "Processing patch $NAME: " -- -- [ -e "$FILE" ] || { -- echo "file $FILE not found" -- exit 1 -- } -- -- grep -qE "$NAME$" patches/series && { -- echo "already applied" -- continue -- } -- -- quilt new "$CUR-$NAME" || exit 1 -- patch_header < "$FILE" | -- strip_diffstat | -- strip_trailing_whitespace | -- fixup_header > "patches/$CUR-$NAME" -- -- quilt fold < "$FILE" || { -- cp "$FILE" ./cur_patch -- echo "patch $FILE failed to apply, copied to ./cur_patch" -- exit 1 -- } -- -- quilt refresh -p ab --no-index --no-timestamps -- -- CUR="$(($CUR + 1))" --done -- --exit 0 --- -2.34.1 - diff --git a/patches/0053-mac80211-update-to-HEAD.patch b/patches/0053-mac80211-update-to-HEAD.patch deleted file mode 100644 index b166740ca..000000000 --- a/patches/0053-mac80211-update-to-HEAD.patch +++ /dev/null @@ -1,29739 +0,0 @@ -From 44bfdae6e35c6474057a88fe0faafb9be8e65b31 Mon Sep 17 00:00:00 2001 -From: John Crispin -Date: Mon, 4 Sep 2023 08:43:20 +0200 -Subject: [PATCH 53/55] mac80211: update to HEAD - -Signed-off-by: John Crispin ---- - package/kernel/mac80211/Makefile | 397 ++++++ - package/kernel/mac80211/ath.mk | 391 ++++++ - package/kernel/mac80211/broadcom.mk | 492 +++++++ - .../files/lib/netifd/wireless/mac80211.sh | 1219 +++++++++++++++++ - .../mac80211/files/lib/wifi/mac80211.sh | 217 +++ - .../kernel/mac80211/files/mac80211.hotplug | 5 + - package/kernel/mac80211/intel.mk | 77 ++ - package/kernel/mac80211/marvell.mk | 51 + - .../patches/ath/070-ath_common_config.patch | 10 + - .../patches/ath/400-ath_move_debug_code.patch | 31 + - .../patches/ath/402-ath_regd_optional.patch | 92 ++ - .../patches/ath/403-world_regd_fixup.patch | 84 ++ - .../patches/ath/404-regd_no_assoc_hints.patch | 19 + - .../patches/ath/405-ath_regd_us.patch | 26 + - .../ath/406-ath_relax_default_regd.patch | 51 + - ...add_platform_eeprom_support_to_ath5k.patch | 56 + - .../ath10k/080-ath10k_thermal_config.patch | 47 + - ...21-ath10k_init_devices_synchronously.patch | 33 + - .../930-ath10k_add_tpt_led_trigger.patch | 37 + - ...rolling-support-for-various-chipsets.patch | 609 ++++++++ - ...75-ath10k-use-tpt-trigger-by-default.patch | 53 + - ...-power-reduction-for-US-regulatory-d.patch | 101 ++ - ...h10k-Try-to-get-mac-address-from-dts.patch | 37 + - ...k-always-use-mac80211-loss-detection.patch | 28 + - .../ath10k/990-ath10k-small-buffers.patch | 64 + - ...-tx-queues-immediately-upon-firmware.patch | 78 ++ - ...-ath11k-Don-t-exit-on-wakeup-failure.patch | 45 + - ...-Fix-spelling-mistake-chnange-change.patch | 25 + - ...-ath11k-suppress-add-interface-error.patch | 52 + - ...support-to-configure-channel-dwell-t.patch | 102 ++ - ...firmware-crash-on-vdev-delete-race-c.patch | 116 ++ - ...monitor-vdev-creation-with-firmware-.patch | 40 + - ...qmi_msg_handler-data-structure-initi.patch | 33 + - ...hronize-ath11k_mac_he_gi_to_nl80211_.patch | 42 + - ...-ath11k-Make-QMI-message-rules-const.patch | 341 +++++ - ...ger-sta-disconnect-on-hardware-resta.patch | 119 ++ - ...race-condition-with-struct-htt_ppdu_.patch | 103 ++ - ...-ath11k-update-hw-params-for-IPQ5018.patch | 125 ++ - ...update-ce-configurations-for-IPQ5018.patch | 246 ++++ - ...-remap-ce-register-space-for-IPQ5018.patch | 351 +++++ - ...11k-update-hal-srng-regs-for-IPQ5018.patch | 130 ++ - ...ath11k-initialize-hw_ops-for-IPQ5018.patch | 90 ++ - ...new-hw-ops-for-IPQ5018-to-get-rx-des.patch | 84 ++ - ...fi-ath11k-add-ipq5018-device-support.patch | 31 + - ...scan-request-param-frame-size-warnin.patch | 161 +++ - ...support-to-configure-FTM-responder-r.patch | 169 +++ - ...-channel-177-into-5-GHz-channel-list.patch | 41 + - ...ix-ce-memory-mapping-for-ahb-devices.patch | 114 ++ - ...ext-passive-scan-flag-to-adjust-pass.patch | 73 + - ...return-value-check-in-ath11k_ahb_pro.patch | 27 + - ...platform_get_irq-to-get-the-interrup.patch | 50 + - ...SAC-bug-on-peer-addition-with-sta-ba.patch | 53 + - ...low-system-suspend-to-survive-ath11k.patch | 43 + - ...fy-accessor-macros-to-match-index-si.patch | 61 + - ...-MU-MIMO-params-from-hostapd-to-hard.patch | 300 ++++ - ...-HE-MCS-mapper-to-a-separate-functio.patch | 67 + - ...rate-rx-and-tx-mcs-maps-for-supporte.patch | 64 + - ...tx-ack-signal-support-for-management.patch | 150 ++ - ...proper-regulatory-reference-for-band.patch | 216 +++ - ...support-to-parse-new-WMI-event-for-6.patch | 844 ++++++++++++ - ...debug-prints-in-regulatory-WMI-event.patch | 567 ++++++++ - ...ace-fake-flex-array-with-flexible-ar.patch | 246 ++++ - ...deinitialization-of-firmware-resourc.patch | 79 ++ - ...BUFFER_DONE-read-on-monitor-ring-rx-.patch | 130 ++ - ...wifi-ath11k-Optimize-6-GHz-scan-time.patch | 101 ++ - ...igure-the-FTM-responder-role-using-f.patch | 117 ++ - ...rssi-station-dump-not-updated-in-QCN.patch | 158 +++ - ...invalid-management-rx-frame-length-i.patch | 115 ++ - ...-writing-to-unintended-memory-region.patch | 43 + - ...-11d-scan-start-before-WMI_START_SCA.patch | 61 + - ...1k-Remove-redundant-pci_clear_master.patch | 58 + - ...ble-Spectral-scan-upon-removing-inte.patch | 36 + - ...ath11k-enable-SAR-support-on-WCN6750.patch | 29 + - ...pci-Add-more-MODULE_FIRMWARE-entries.patch | 36 + - ...t-a-warning-when-crypto_alloc_shash-.patch | 34 + - ...re-frags-from-uninitialized-peer-in-.patch | 104 ++ - ...-undefined-behavior-with-__fls-in-dp.patch | 29 + - ...double-free-of-peer-rx_tid-during-re.patch | 144 ++ - ...wifi-ath11k-Prevent-REO-cmd-failures.patch | 43 + - ...peer-mac-information-in-failure-case.patch | 74 + - ...tx-status-reporting-in-encap-offload.patch | 119 ++ - ...-incorrect-update-of-radiotap-fields.patch | 49 + - ...SKB-corruption-in-REO-destination-ri.patch | 70 + - ...emove-disabling-of-80-80-and-160-MHz.patch | 49 + - ...registration-of-6Ghz-only-phy-withou.patch | 61 + - ...ound-false-positive-stringop-overrea.patch | 84 ++ - ...k-driver-settings-for-MBSSID-and-EMA.patch | 133 ++ - ...ID-configuration-during-vdev-create-.patch | 215 +++ - ...ame-MBSSID-fields-in-wmi_vdev_up_cmd.patch | 52 + - ...ID-parameter-configuration-in-AP-mod.patch | 138 ++ - ...efactor-vif-parameter-configurations.patch | 86 ++ - ...76-wifi-ath11k-MBSSID-beacon-support.patch | 190 +++ - .../0077-wifi-ath11k-EMA-beacon-support.patch | 156 +++ - ...cate-the-func-ath11k_mac_bitrate_mas.patch | 75 + - ...-HT-fixed-rate-in-WMI-peer-fixed-par.patch | 141 ++ - ...support-default-regdb-while-searchin.patch | 127 ++ - ...ve-unused-function-ath11k_tm_event_w.patch | 128 ++ - ...ifi-ath11k-factory-test-mode-support.patch | 850 ++++++++++++ - ...w-ath11k-to-boot-without-caldata-in-.patch | 47 + - ...11k-Add-HTT-stats-for-PHY-reset-case.patch | 261 ++++ - ...i-ath11k-use-unique-QRTR-instance-ID.patch | 162 +++ - ...k-control-thermal-support-via-symbol.patch | 66 + - ...ci-fix-compilation-in-5.16-and-older.patch | 29 + - ...ble-coldboot-calibration-for-IPQ8074.patch | 24 + - ...upport-setting-FW-memory-mode-via-DT.patch | 74 + - ...tersection-support-for-regulatory-ru.patch | 317 +++++ - .../201-ath5k-WAR-for-AR71xx-PCI-bug.patch | 38 + - .../ath5k/411-ath5k_allow_adhoc_and_ap.patch | 46 + - .../ath5k/420-ath5k_disable_fast_cc.patch | 18 + - .../ath5k/430-add_ath5k_platform.patch | 33 + - .../patches/ath5k/432-ath5k_add_pciids.patch | 11 + - .../ath5k/440-ath5k_channel_bw_debugfs.patch | 142 ++ - ...w-reset-AHB-WMAC-interface-on-AR91xx.patch | 25 + - ..._hw-issue-external-reset-for-QCA955x.patch | 129 ++ - ...h9k-force-rx_clear-when-disabling-rx.patch | 35 + - ...erpret-requested-txpower-in-EIRP-dom.patch | 36 + - ...power-reduction-for-US-regulatory-do.patch | 24 + - .../ath9k/401-ath9k_blink_default.patch | 11 + - .../ath9k/410-ath9k_allow_adhoc_and_ap.patch | 10 + - ...abled-MFP-capability-unconditionally.patch | 34 + - .../ath9k/500-ath9k_eeprom_debugfs.patch | 66 + - .../patches/ath9k/501-ath9k_ahb_init.patch | 34 + - .../510-ath9k_intr_mitigation_tweak.patch | 18 + - .../ath9k/511-ath9k_reduce_rxbuf.patch | 11 + - .../ath9k/512-ath9k_channelbw_debugfs.patch | 125 ++ - .../patches/ath9k/513-ath9k_add_pci_ids.patch | 30 + - .../patches/ath9k/530-ath9k_extra_leds.patch | 267 ++++ - .../ath9k/531-ath9k_extra_platform_leds.patch | 76 + - .../ath9k/540-ath9k_reduce_ani_interval.patch | 11 + - .../ath9k/542-ath9k_debugfs_diag.patch | 139 ++ - .../ath9k/543-ath9k_entropy_from_adc.patch | 186 +++ - ...544-ath9k-ar933x-usb-hang-workaround.patch | 79 ++ - .../ath9k/545-ath9k_ani_ws_detect.patch | 155 +++ - .../ath9k/547-ath9k_led_defstate_fix.patch | 29 + - .../ath9k/548-ath9k_enable_gpio_chip.patch | 251 ++++ - .../ath9k/549-ath9k_enable_gpio_buttons.patch | 143 ++ - .../ath9k/551-ath9k_ubnt_uap_plus_hsr.patch | 403 ++++++ - .../patches/ath9k/552-ath9k-ahb_of.patch | 331 +++++ - .../ath9k/553-ath9k_of_gpio_mask.patch | 25 + - .../patches/brcm/040-brcmutil_option.patch | 10 + - .../810-b43-gpio-mask-module-option.patch | 37 + - .../patches/brcm/811-b43_no_pio.patch | 86 ++ - .../brcm/812-b43-add-antenna-control.patch | 131 ++ - .../813-b43-reduce-number-of-RX-slots.patch | 11 + - .../814-b43-only-use-gpio-0-1-for-led.patch | 17 + - ...815-b43-always-take-overlapping-devs.patch | 11 + - ...-remove-extra-regulation-restriction.patch | 27 + - ...und-bug-with-some-inconsistent-BSSes.patch | 49 + - ...62-brcmfmac-Disable-power-management.patch | 27 + - ...-in-driver-tables-with-country-codes.patch | 60 + - ...e-internal-roaming-engine-by-default.patch | 23 + - ...d-alternative-firmware-names-from-DT.patch | 191 +++ - .../patches/build/000-fix_kconfig.patch | 14 + - .../patches/build/001-fix_build.patch | 169 +++ - .../patches/build/002-change_allconfig.patch | 64 + - .../build/003-remove_bogus_modparams.patch | 34 + - .../build/012-kernel_build_check.patch | 11 + - .../patches/build/060-no_local_ssb_bcma.patch | 314 +++++ - .../build/070-remove-broken-wext-select.patch | 10 + - .../patches/build/080-resv_start_op.patch | 24 + - .../mac80211/patches/build/090-bcma-otp.patch | 13 + - .../100-backports-drop-QRTR-and-MHI.patch | 76 + - .../build/110-backport_napi_build_skb.patch | 11 + - ...01-wifi-mt7601u-update-firmware-path.patch | 55 + - ...700-mwl8k-missing-pci-id-for-WNR854T.patch | 10 + - .../801-libertas-configure-sysfs-links.patch | 21 + - .../802-libertas-set-wireless-macaddr.patch | 11 + - ...crease-the-global-limit-up-to-4-SSID.patch | 41 + - ...940-mwl8k_init_devices_synchronously.patch | 20 + - ...ringified-name-of-command-in-error-l.patch | 189 +++ - .../patches/rt2x00/100-rt2x00_options.patch | 47 + - ...to-build-rt2800soc-module-for-RT3883.patch | 30 + - ...1-rt2x00-introduce-rt2x00_platform_h.patch | 32 + - .../602-rt2x00-introduce-rt2x00eeprom.patch | 296 ++++ - .../603-rt2x00-of_load_eeprom_filename.patch | 31 + - ...om-on-SoC-from-a-mtd-device-defines-.patch | 113 ++ - ...isabling_bands_through_platform_data.patch | 47 + - ...07-rt2x00-add_platform_data_mac_addr.patch | 25 + - ...00-allow_disabling_bands_through_dts.patch | 19 + - ...c-loadable-via-OF-on-rt288x-305x-SoC.patch | 33 + - ...0-rt2x00-change-led-polarity-from-OF.patch | 40 + - .../611-rt2x00-add-AP+STA-support.patch | 11 + - ...t-support-for-external-LNA-on-MT7620.patch | 161 +++ - ...duce-accessors-for-CHIP_VER-register.patch | 139 ++ - ...-differentiate-based-on-SoC-CHIP_VER.patch | 408 ++++++ - ...t-MT7620-TX-power-based-on-eeprom-ca.patch | 106 ++ - ...-rework-MT7620-PA-LNA-RF-calibration.patch | 413 ++++++ - .../110-mac80211_keep_keys_on_stop_ap.patch | 19 + - .../120-cfg80211_allow_perm_addr_change.patch | 52 + - .../mac80211/patches/subsys/210-ap_scan.patch | 19 + - ...domize-BA-session-dialog-token-alloc.patch | 38 + - ...-minstrel_ht-fix-MINSTREL_FRAC-macro.patch | 21 + - ...l_ht-reduce-fluctuations-in-rate-pro.patch | 30 + - ...l_ht-rework-rate-downgrade-code-and-.patch | 151 ++ - ...crease-quantum-for-airtime-scheduler.patch | 53 + - ...d-internal-handler-for-wake_tx_queue.patch | 183 +++ - ...dd-wake_tx_queue-callback-to-drivers.patch | 396 ++++++ - ...c80211-Drop-support-for-TX-push-path.patch | 683 +++++++++ - ...ltek-remove-duplicated-wake_tx_queue.patch | 32 + - ...port-for-restricting-netdev-features.patch | 506 +++++++ - ...x-and-simplify-unencrypted-drop-chec.patch | 87 ++ - ...ve-A-MSDU-check-in-ieee80211_data_to.patch | 25 + - ...ctor-out-bridge-tunnel-RFC1042-heade.patch | 76 + - ...move-mesh-forwarding-congestion-chec.patch | 54 + - ...x-receiving-A-MSDU-frames-on-mesh-in.patch | 762 +++++++++++ - ...d-a-workaround-for-receiving-non-sta.patch | 145 ++ - ...x-race-in-mesh-sequence-number-assig.patch | 37 + - ...wifi-mac80211-mesh-fast-xmit-support.patch | 850 ++++++++++++ - ...e-mesh-header-cache-to-speed-up-mesh.patch | 132 ++ - .../321-mac80211-fix-mesh-forwarding.patch | 32 + - ...x-mesh-path-discovery-based-on-unica.patch | 52 + - ...d-VHT-MU-MIMO-related-flags-in-ieee8.patch | 68 + - ...d-HE-MU-MIMO-related-flags-in-ieee80.patch | 68 + - ...troduce-ieee80211_refresh_tx_agg_ses.patch | 60 + - ...fi-mac80211-add-mesh-fast-rx-support.patch | 77 ++ - ...d-support-for-letting-drivers-regist.patch | 149 ++ - ...x-receiving-mesh-packets-in-forwardi.patch | 50 + - ...orrectly-mark-FTM-frames-non-buffera.patch | 134 ++ - ...mac80211-flush-queues-on-STA-removal.patch | 36 + - ...i-mvm-support-flush-on-AP-interfaces.patch | 34 + - ...3-wifi-mac80211-add-flush_sta-method.patch | 91 ++ - ...ifi-mvm-support-new-flush_sta-method.patch | 53 + - ...d-LDPC-related-flags-in-ieee80211_bs.patch | 62 + - ...0211-generate-EMA-beacons-in-AP-mode.patch | 372 +++++ - ...sband-iftype-data-lookup-for-AP_VLAN.patch | 23 + - ...esh-fast-tx-cache-into-local-proxied.patch | 219 +++ - ...x-receving-mesh-packets-without-RFC1.patch | 25 + - .../patches/subsys/400-allow-ibss-mixed.patch | 40 + - ...the-dst-buffer-to-of_get_mac_address.patch | 29 + - package/kernel/mac80211/ralink.mk | 131 ++ - package/kernel/mac80211/realtek.mk | 197 +++ - .../mac80211/scripts/import-backports.sh | 109 ++ - 232 files changed, 27871 insertions(+) - create mode 100644 package/kernel/mac80211/Makefile - create mode 100644 package/kernel/mac80211/ath.mk - create mode 100644 package/kernel/mac80211/broadcom.mk - create mode 100644 package/kernel/mac80211/files/lib/netifd/wireless/mac80211.sh - create mode 100644 package/kernel/mac80211/files/lib/wifi/mac80211.sh - create mode 100644 package/kernel/mac80211/files/mac80211.hotplug - create mode 100644 package/kernel/mac80211/intel.mk - create mode 100644 package/kernel/mac80211/marvell.mk - create mode 100644 package/kernel/mac80211/patches/ath/070-ath_common_config.patch - create mode 100644 package/kernel/mac80211/patches/ath/400-ath_move_debug_code.patch - create mode 100644 package/kernel/mac80211/patches/ath/402-ath_regd_optional.patch - create mode 100644 package/kernel/mac80211/patches/ath/403-world_regd_fixup.patch - create mode 100644 package/kernel/mac80211/patches/ath/404-regd_no_assoc_hints.patch - create mode 100644 package/kernel/mac80211/patches/ath/405-ath_regd_us.patch - create mode 100644 package/kernel/mac80211/patches/ath/406-ath_relax_default_regd.patch - create mode 100644 package/kernel/mac80211/patches/ath/431-add_platform_eeprom_support_to_ath5k.patch - create mode 100644 package/kernel/mac80211/patches/ath10k/080-ath10k_thermal_config.patch - create mode 100644 package/kernel/mac80211/patches/ath10k/921-ath10k_init_devices_synchronously.patch - create mode 100644 package/kernel/mac80211/patches/ath10k/930-ath10k_add_tpt_led_trigger.patch - create mode 100644 package/kernel/mac80211/patches/ath10k/974-ath10k_add-LED-and-GPIO-controlling-support-for-various-chipsets.patch - create mode 100644 package/kernel/mac80211/patches/ath10k/975-ath10k-use-tpt-trigger-by-default.patch - create mode 100644 package/kernel/mac80211/patches/ath10k/981-ath10k-adjust-tx-power-reduction-for-US-regulatory-d.patch - create mode 100644 package/kernel/mac80211/patches/ath10k/984-ath10k-Try-to-get-mac-address-from-dts.patch - create mode 100644 package/kernel/mac80211/patches/ath10k/988-ath10k-always-use-mac80211-loss-detection.patch - create mode 100644 package/kernel/mac80211/patches/ath10k/990-ath10k-small-buffers.patch - create mode 100644 package/kernel/mac80211/patches/ath11k/0001-wifi-ath11k-stop-tx-queues-immediately-upon-firmware.patch - create mode 100644 package/kernel/mac80211/patches/ath11k/0002-wifi-ath11k-Don-t-exit-on-wakeup-failure.patch - create mode 100644 package/kernel/mac80211/patches/ath11k/0005-wifi-ath11k-Fix-spelling-mistake-chnange-change.patch - create mode 100644 package/kernel/mac80211/patches/ath11k/0007-wifi-ath11k-suppress-add-interface-error.patch - create mode 100644 package/kernel/mac80211/patches/ath11k/0008-wifi-ath11k-add-support-to-configure-channel-dwell-t.patch - create mode 100644 package/kernel/mac80211/patches/ath11k/0010-wifi-ath11k-Fix-firmware-crash-on-vdev-delete-race-c.patch - create mode 100644 package/kernel/mac80211/patches/ath11k/0011-wifi-ath11k-fix-monitor-vdev-creation-with-firmware-.patch - create mode 100644 package/kernel/mac80211/patches/ath11k/0012-wifi-ath11k-Fix-qmi_msg_handler-data-structure-initi.patch - create mode 100644 package/kernel/mac80211/patches/ath11k/0013-wifi-ath11k-synchronize-ath11k_mac_he_gi_to_nl80211_.patch - create mode 100644 package/kernel/mac80211/patches/ath11k/0016-wifi-ath11k-Make-QMI-message-rules-const.patch - create mode 100644 package/kernel/mac80211/patches/ath11k/0017-wifi-ath11k-Trigger-sta-disconnect-on-hardware-resta.patch - create mode 100644 package/kernel/mac80211/patches/ath11k/0018-wifi-ath11k-Fix-race-condition-with-struct-htt_ppdu_.patch - create mode 100644 package/kernel/mac80211/patches/ath11k/0019-wifi-ath11k-update-hw-params-for-IPQ5018.patch - create mode 100644 package/kernel/mac80211/patches/ath11k/0020-wifi-ath11k-update-ce-configurations-for-IPQ5018.patch - create mode 100644 package/kernel/mac80211/patches/ath11k/0021-wifi-ath11k-remap-ce-register-space-for-IPQ5018.patch - create mode 100644 package/kernel/mac80211/patches/ath11k/0022-wifi-ath11k-update-hal-srng-regs-for-IPQ5018.patch - create mode 100644 package/kernel/mac80211/patches/ath11k/0023-wifi-ath11k-initialize-hw_ops-for-IPQ5018.patch - create mode 100644 package/kernel/mac80211/patches/ath11k/0024-wifi-ath11k-add-new-hw-ops-for-IPQ5018-to-get-rx-des.patch - create mode 100644 package/kernel/mac80211/patches/ath11k/0025-wifi-ath11k-add-ipq5018-device-support.patch - create mode 100644 package/kernel/mac80211/patches/ath11k/0026-wifi-ath11k-Fix-scan-request-param-frame-size-warnin.patch - create mode 100644 package/kernel/mac80211/patches/ath11k/0029-wifi-ath11k-Add-support-to-configure-FTM-responder-r.patch - create mode 100644 package/kernel/mac80211/patches/ath11k/0030-wifi-ath11k-add-channel-177-into-5-GHz-channel-list.patch - create mode 100644 package/kernel/mac80211/patches/ath11k/0031-wifi-ath11k-fix-ce-memory-mapping-for-ahb-devices.patch - create mode 100644 package/kernel/mac80211/patches/ath11k/0033-wifi-ath11k-Set-ext-passive-scan-flag-to-adjust-pass.patch - create mode 100644 package/kernel/mac80211/patches/ath11k/0034-wifi-ath11k-fix-return-value-check-in-ath11k_ahb_pro.patch - create mode 100644 package/kernel/mac80211/patches/ath11k/0035-wifi-ath11k-Use-platform_get_irq-to-get-the-interrup.patch - create mode 100644 package/kernel/mac80211/patches/ath11k/0036-wifi-ath11k-fix-SAC-bug-on-peer-addition-with-sta-ba.patch - create mode 100644 package/kernel/mac80211/patches/ath11k/0037-wifi-ath11k-allow-system-suspend-to-survive-ath11k.patch - create mode 100644 package/kernel/mac80211/patches/ath11k/0038-wifi-ath11k-modify-accessor-macros-to-match-index-si.patch - create mode 100644 package/kernel/mac80211/patches/ath11k/0039-wifi-ath11k-push-MU-MIMO-params-from-hostapd-to-hard.patch - create mode 100644 package/kernel/mac80211/patches/ath11k/0040-wifi-ath11k-move-HE-MCS-mapper-to-a-separate-functio.patch - create mode 100644 package/kernel/mac80211/patches/ath11k/0041-wifi-ath11k-generate-rx-and-tx-mcs-maps-for-supporte.patch - create mode 100644 package/kernel/mac80211/patches/ath11k/0042-wifi-ath11k-Add-tx-ack-signal-support-for-management.patch - create mode 100644 package/kernel/mac80211/patches/ath11k/0043-wifi-ath11k-use-proper-regulatory-reference-for-band.patch - create mode 100644 package/kernel/mac80211/patches/ath11k/0044-wifi-ath11k-add-support-to-parse-new-WMI-event-for-6.patch - create mode 100644 package/kernel/mac80211/patches/ath11k/0045-wifi-ath11k-add-debug-prints-in-regulatory-WMI-event.patch - create mode 100644 package/kernel/mac80211/patches/ath11k/0046-wifi-ath11k-Replace-fake-flex-array-with-flexible-ar.patch - create mode 100644 package/kernel/mac80211/patches/ath11k/0047-wifi-ath11k-fix-deinitialization-of-firmware-resourc.patch - create mode 100644 package/kernel/mac80211/patches/ath11k/0048-wifi-ath11k-fix-BUFFER_DONE-read-on-monitor-ring-rx-.patch - create mode 100644 package/kernel/mac80211/patches/ath11k/0049-wifi-ath11k-Optimize-6-GHz-scan-time.patch - create mode 100644 package/kernel/mac80211/patches/ath11k/0050-wifi-ath11k-Configure-the-FTM-responder-role-using-f.patch - create mode 100644 package/kernel/mac80211/patches/ath11k/0051-wifi-ath11k-fix-rssi-station-dump-not-updated-in-QCN.patch - create mode 100644 package/kernel/mac80211/patches/ath11k/0052-wifi-ath11k-Fix-invalid-management-rx-frame-length-i.patch - create mode 100644 package/kernel/mac80211/patches/ath11k/0053-wifi-ath11k-fix-writing-to-unintended-memory-region.patch - create mode 100644 package/kernel/mac80211/patches/ath11k/0054-wifi-ath11k-Send-11d-scan-start-before-WMI_START_SCA.patch - create mode 100644 package/kernel/mac80211/patches/ath11k/0055-wifi-ath11k-Remove-redundant-pci_clear_master.patch - create mode 100644 package/kernel/mac80211/patches/ath11k/0056-wifi-ath11k-Disable-Spectral-scan-upon-removing-inte.patch - create mode 100644 package/kernel/mac80211/patches/ath11k/0057-wifi-ath11k-enable-SAR-support-on-WCN6750.patch - create mode 100644 package/kernel/mac80211/patches/ath11k/0058-wifi-ath11k-pci-Add-more-MODULE_FIRMWARE-entries.patch - create mode 100644 package/kernel/mac80211/patches/ath11k/0059-wifi-ath11k-print-a-warning-when-crypto_alloc_shash-.patch - create mode 100644 package/kernel/mac80211/patches/ath11k/0060-wifi-ath11k-Ignore-frags-from-uninitialized-peer-in-.patch - create mode 100644 package/kernel/mac80211/patches/ath11k/0061-wifi-ath11k-fix-undefined-behavior-with-__fls-in-dp.patch - create mode 100644 package/kernel/mac80211/patches/ath11k/0062-wifi-ath11k-fix-double-free-of-peer-rx_tid-during-re.patch - create mode 100644 package/kernel/mac80211/patches/ath11k/0063-wifi-ath11k-Prevent-REO-cmd-failures.patch - create mode 100644 package/kernel/mac80211/patches/ath11k/0064-wifi-ath11k-add-peer-mac-information-in-failure-case.patch - create mode 100644 package/kernel/mac80211/patches/ath11k/0065-wifi-ath11k-fix-tx-status-reporting-in-encap-offload.patch - create mode 100644 package/kernel/mac80211/patches/ath11k/0066-wifi-ath11k-Fix-incorrect-update-of-radiotap-fields.patch - create mode 100644 package/kernel/mac80211/patches/ath11k/0067-wifi-ath11k-Fix-SKB-corruption-in-REO-destination-ri.patch - create mode 100644 package/kernel/mac80211/patches/ath11k/0068-wifi-ath11k-Remove-disabling-of-80-80-and-160-MHz.patch - create mode 100644 package/kernel/mac80211/patches/ath11k/0069-wifi-ath11k-fix-registration-of-6Ghz-only-phy-withou.patch - create mode 100644 package/kernel/mac80211/patches/ath11k/0070-wifi-ath-work-around-false-positive-stringop-overrea.patch - create mode 100644 package/kernel/mac80211/patches/ath11k/0071-wifi-ath11k-driver-settings-for-MBSSID-and-EMA.patch - create mode 100644 package/kernel/mac80211/patches/ath11k/0072-wifi-ath11k-MBSSID-configuration-during-vdev-create-.patch - create mode 100644 package/kernel/mac80211/patches/ath11k/0073-wifi-ath11k-rename-MBSSID-fields-in-wmi_vdev_up_cmd.patch - create mode 100644 package/kernel/mac80211/patches/ath11k/0074-wifi-ath11k-MBSSID-parameter-configuration-in-AP-mod.patch - create mode 100644 package/kernel/mac80211/patches/ath11k/0075-wifi-ath11k-refactor-vif-parameter-configurations.patch - create mode 100644 package/kernel/mac80211/patches/ath11k/0076-wifi-ath11k-MBSSID-beacon-support.patch - create mode 100644 package/kernel/mac80211/patches/ath11k/0077-wifi-ath11k-EMA-beacon-support.patch - create mode 100644 package/kernel/mac80211/patches/ath11k/0078-wifi-ath11k-Relocate-the-func-ath11k_mac_bitrate_mas.patch - create mode 100644 package/kernel/mac80211/patches/ath11k/0079-wifi-ath11k-Send-HT-fixed-rate-in-WMI-peer-fixed-par.patch - create mode 100644 package/kernel/mac80211/patches/ath11k/0080-wifi-ath11k-add-support-default-regdb-while-searchin.patch - create mode 100644 package/kernel/mac80211/patches/ath11k/0081-wifi-ath11k-remove-unused-function-ath11k_tm_event_w.patch - create mode 100644 package/kernel/mac80211/patches/ath11k/0082-wifi-ath11k-factory-test-mode-support.patch - create mode 100644 package/kernel/mac80211/patches/ath11k/0083-wifi-ath11k-Allow-ath11k-to-boot-without-caldata-in-.patch - create mode 100644 package/kernel/mac80211/patches/ath11k/0084-wifi-ath11k-Add-HTT-stats-for-PHY-reset-case.patch - create mode 100644 package/kernel/mac80211/patches/ath11k/100-wifi-ath11k-use-unique-QRTR-instance-ID.patch - create mode 100644 package/kernel/mac80211/patches/ath11k/900-ath11k-control-thermal-support-via-symbol.patch - create mode 100644 package/kernel/mac80211/patches/ath11k/901-wifi-ath11k-pci-fix-compilation-in-5.16-and-older.patch - create mode 100644 package/kernel/mac80211/patches/ath11k/902-ath11k-Disable-coldboot-calibration-for-IPQ8074.patch - create mode 100644 package/kernel/mac80211/patches/ath11k/903-ath11k-support-setting-FW-memory-mode-via-DT.patch - create mode 100644 package/kernel/mac80211/patches/ath11k/905-ath11k-remove-intersection-support-for-regulatory-ru.patch - create mode 100644 package/kernel/mac80211/patches/ath5k/201-ath5k-WAR-for-AR71xx-PCI-bug.patch - create mode 100644 package/kernel/mac80211/patches/ath5k/411-ath5k_allow_adhoc_and_ap.patch - create mode 100644 package/kernel/mac80211/patches/ath5k/420-ath5k_disable_fast_cc.patch - create mode 100644 package/kernel/mac80211/patches/ath5k/430-add_ath5k_platform.patch - create mode 100644 package/kernel/mac80211/patches/ath5k/432-ath5k_add_pciids.patch - create mode 100644 package/kernel/mac80211/patches/ath5k/440-ath5k_channel_bw_debugfs.patch - create mode 100644 package/kernel/mac80211/patches/ath9k/350-ath9k_hw-reset-AHB-WMAC-interface-on-AR91xx.patch - create mode 100644 package/kernel/mac80211/patches/ath9k/351-ath9k_hw-issue-external-reset-for-QCA955x.patch - create mode 100644 package/kernel/mac80211/patches/ath9k/354-ath9k-force-rx_clear-when-disabling-rx.patch - create mode 100644 package/kernel/mac80211/patches/ath9k/356-Revert-ath9k-interpret-requested-txpower-in-EIRP-dom.patch - create mode 100644 package/kernel/mac80211/patches/ath9k/365-ath9k-adjust-tx-power-reduction-for-US-regulatory-do.patch - create mode 100644 package/kernel/mac80211/patches/ath9k/401-ath9k_blink_default.patch - create mode 100644 package/kernel/mac80211/patches/ath9k/410-ath9k_allow_adhoc_and_ap.patch - create mode 100644 package/kernel/mac80211/patches/ath9k/450-ath9k-enabled-MFP-capability-unconditionally.patch - create mode 100644 package/kernel/mac80211/patches/ath9k/500-ath9k_eeprom_debugfs.patch - create mode 100644 package/kernel/mac80211/patches/ath9k/501-ath9k_ahb_init.patch - create mode 100644 package/kernel/mac80211/patches/ath9k/510-ath9k_intr_mitigation_tweak.patch - create mode 100644 package/kernel/mac80211/patches/ath9k/511-ath9k_reduce_rxbuf.patch - create mode 100644 package/kernel/mac80211/patches/ath9k/512-ath9k_channelbw_debugfs.patch - create mode 100644 package/kernel/mac80211/patches/ath9k/513-ath9k_add_pci_ids.patch - create mode 100644 package/kernel/mac80211/patches/ath9k/530-ath9k_extra_leds.patch - create mode 100644 package/kernel/mac80211/patches/ath9k/531-ath9k_extra_platform_leds.patch - create mode 100644 package/kernel/mac80211/patches/ath9k/540-ath9k_reduce_ani_interval.patch - create mode 100644 package/kernel/mac80211/patches/ath9k/542-ath9k_debugfs_diag.patch - create mode 100644 package/kernel/mac80211/patches/ath9k/543-ath9k_entropy_from_adc.patch - create mode 100644 package/kernel/mac80211/patches/ath9k/544-ath9k-ar933x-usb-hang-workaround.patch - create mode 100644 package/kernel/mac80211/patches/ath9k/545-ath9k_ani_ws_detect.patch - create mode 100644 package/kernel/mac80211/patches/ath9k/547-ath9k_led_defstate_fix.patch - create mode 100644 package/kernel/mac80211/patches/ath9k/548-ath9k_enable_gpio_chip.patch - create mode 100644 package/kernel/mac80211/patches/ath9k/549-ath9k_enable_gpio_buttons.patch - create mode 100644 package/kernel/mac80211/patches/ath9k/551-ath9k_ubnt_uap_plus_hsr.patch - create mode 100644 package/kernel/mac80211/patches/ath9k/552-ath9k-ahb_of.patch - create mode 100644 package/kernel/mac80211/patches/ath9k/553-ath9k_of_gpio_mask.patch - create mode 100644 package/kernel/mac80211/patches/brcm/040-brcmutil_option.patch - create mode 100644 package/kernel/mac80211/patches/brcm/810-b43-gpio-mask-module-option.patch - create mode 100644 package/kernel/mac80211/patches/brcm/811-b43_no_pio.patch - create mode 100644 package/kernel/mac80211/patches/brcm/812-b43-add-antenna-control.patch - create mode 100644 package/kernel/mac80211/patches/brcm/813-b43-reduce-number-of-RX-slots.patch - create mode 100644 package/kernel/mac80211/patches/brcm/814-b43-only-use-gpio-0-1-for-led.patch - create mode 100644 package/kernel/mac80211/patches/brcm/815-b43-always-take-overlapping-devs.patch - create mode 100644 package/kernel/mac80211/patches/brcm/850-brcmsmac-remove-extra-regulation-restriction.patch - create mode 100644 package/kernel/mac80211/patches/brcm/861-brcmfmac-workaround-bug-with-some-inconsistent-BSSes.patch - create mode 100644 package/kernel/mac80211/patches/brcm/862-brcmfmac-Disable-power-management.patch - create mode 100644 package/kernel/mac80211/patches/brcm/863-brcmfmac-add-in-driver-tables-with-country-codes.patch - create mode 100644 package/kernel/mac80211/patches/brcm/864-brcmfmac-do-not-use-internal-roaming-engine-by-default.patch - create mode 100644 package/kernel/mac80211/patches/brcm/865-brcmfmac-Read-alternative-firmware-names-from-DT.patch - create mode 100644 package/kernel/mac80211/patches/build/000-fix_kconfig.patch - create mode 100644 package/kernel/mac80211/patches/build/001-fix_build.patch - create mode 100644 package/kernel/mac80211/patches/build/002-change_allconfig.patch - create mode 100644 package/kernel/mac80211/patches/build/003-remove_bogus_modparams.patch - create mode 100644 package/kernel/mac80211/patches/build/012-kernel_build_check.patch - create mode 100644 package/kernel/mac80211/patches/build/060-no_local_ssb_bcma.patch - create mode 100644 package/kernel/mac80211/patches/build/070-remove-broken-wext-select.patch - create mode 100644 package/kernel/mac80211/patches/build/080-resv_start_op.patch - create mode 100644 package/kernel/mac80211/patches/build/090-bcma-otp.patch - create mode 100644 package/kernel/mac80211/patches/build/100-backports-drop-QRTR-and-MHI.patch - create mode 100644 package/kernel/mac80211/patches/build/110-backport_napi_build_skb.patch - create mode 100644 package/kernel/mac80211/patches/mt7601u/001-wifi-mt7601u-update-firmware-path.patch - create mode 100644 package/kernel/mac80211/patches/mwl/700-mwl8k-missing-pci-id-for-WNR854T.patch - create mode 100644 package/kernel/mac80211/patches/mwl/801-libertas-configure-sysfs-links.patch - create mode 100644 package/kernel/mac80211/patches/mwl/802-libertas-set-wireless-macaddr.patch - create mode 100644 package/kernel/mac80211/patches/mwl/900-mwifiex-increase-the-global-limit-up-to-4-SSID.patch - create mode 100644 package/kernel/mac80211/patches/mwl/940-mwl8k_init_devices_synchronously.patch - create mode 100644 package/kernel/mac80211/patches/mwl/950-mwifiex-Print-stringified-name-of-command-in-error-l.patch - create mode 100644 package/kernel/mac80211/patches/rt2x00/100-rt2x00_options.patch - create mode 100644 package/kernel/mac80211/patches/rt2x00/501-rt2x00-allow-to-build-rt2800soc-module-for-RT3883.patch - create mode 100644 package/kernel/mac80211/patches/rt2x00/601-rt2x00-introduce-rt2x00_platform_h.patch - create mode 100644 package/kernel/mac80211/patches/rt2x00/602-rt2x00-introduce-rt2x00eeprom.patch - create mode 100644 package/kernel/mac80211/patches/rt2x00/603-rt2x00-of_load_eeprom_filename.patch - create mode 100644 package/kernel/mac80211/patches/rt2x00/604-rt2x00-load-eeprom-on-SoC-from-a-mtd-device-defines-.patch - create mode 100644 package/kernel/mac80211/patches/rt2x00/606-rt2x00-allow_disabling_bands_through_platform_data.patch - create mode 100644 package/kernel/mac80211/patches/rt2x00/607-rt2x00-add_platform_data_mac_addr.patch - create mode 100644 package/kernel/mac80211/patches/rt2x00/608-rt2x00-allow_disabling_bands_through_dts.patch - create mode 100644 package/kernel/mac80211/patches/rt2x00/609-rt2x00-make-wmac-loadable-via-OF-on-rt288x-305x-SoC.patch - create mode 100644 package/kernel/mac80211/patches/rt2x00/610-rt2x00-change-led-polarity-from-OF.patch - create mode 100644 package/kernel/mac80211/patches/rt2x00/611-rt2x00-add-AP+STA-support.patch - create mode 100644 package/kernel/mac80211/patches/rt2x00/994-rt2x00-import-support-for-external-LNA-on-MT7620.patch - create mode 100644 package/kernel/mac80211/patches/rt2x00/995-rt2x00-mt7620-introduce-accessors-for-CHIP_VER-register.patch - create mode 100644 package/kernel/mac80211/patches/rt2x00/996-rt2x00-mt7620-differentiate-based-on-SoC-CHIP_VER.patch - create mode 100644 package/kernel/mac80211/patches/rt2x00/997-wifi-rt2x00-limit-MT7620-TX-power-based-on-eeprom-ca.patch - create mode 100644 package/kernel/mac80211/patches/rt2x00/998-wifi-rt2x00-rework-MT7620-PA-LNA-RF-calibration.patch - create mode 100644 package/kernel/mac80211/patches/subsys/110-mac80211_keep_keys_on_stop_ap.patch - create mode 100644 package/kernel/mac80211/patches/subsys/120-cfg80211_allow_perm_addr_change.patch - create mode 100644 package/kernel/mac80211/patches/subsys/210-ap_scan.patch - create mode 100644 package/kernel/mac80211/patches/subsys/301-mac80211-sta-randomize-BA-session-dialog-token-alloc.patch - create mode 100644 package/kernel/mac80211/patches/subsys/302-mac80211-minstrel_ht-fix-MINSTREL_FRAC-macro.patch - create mode 100644 package/kernel/mac80211/patches/subsys/303-mac80211-minstrel_ht-reduce-fluctuations-in-rate-pro.patch - create mode 100644 package/kernel/mac80211/patches/subsys/304-mac80211-minstrel_ht-rework-rate-downgrade-code-and-.patch - create mode 100644 package/kernel/mac80211/patches/subsys/305-mac80211-increase-quantum-for-airtime-scheduler.patch - create mode 100644 package/kernel/mac80211/patches/subsys/306-01-v6.2-wifi-mac80211-add-internal-handler-for-wake_tx_queue.patch - create mode 100644 package/kernel/mac80211/patches/subsys/306-02-v6.2-wifi-mac80211-add-wake_tx_queue-callback-to-drivers.patch - create mode 100644 package/kernel/mac80211/patches/subsys/306-03-v6.2-wifi-mac80211-Drop-support-for-TX-push-path.patch - create mode 100644 package/kernel/mac80211/patches/subsys/306-04-v6.2-wifi-realtek-remove-duplicated-wake_tx_queue.patch - create mode 100644 package/kernel/mac80211/patches/subsys/310-v6.2-mac80211-add-support-for-restricting-netdev-features.patch - create mode 100644 package/kernel/mac80211/patches/subsys/311-v6.2-wifi-mac80211-fix-and-simplify-unencrypted-drop-chec.patch - create mode 100644 package/kernel/mac80211/patches/subsys/312-v6.3-wifi-cfg80211-move-A-MSDU-check-in-ieee80211_data_to.patch - create mode 100644 package/kernel/mac80211/patches/subsys/313-v6.3-wifi-cfg80211-factor-out-bridge-tunnel-RFC1042-heade.patch - create mode 100644 package/kernel/mac80211/patches/subsys/314-v6.3-wifi-mac80211-remove-mesh-forwarding-congestion-chec.patch - create mode 100644 package/kernel/mac80211/patches/subsys/315-v6.3-wifi-mac80211-fix-receiving-A-MSDU-frames-on-mesh-in.patch - create mode 100644 package/kernel/mac80211/patches/subsys/316-v6.3-wifi-mac80211-add-a-workaround-for-receiving-non-sta.patch - create mode 100644 package/kernel/mac80211/patches/subsys/318-wifi-mac80211-fix-race-in-mesh-sequence-number-assig.patch - create mode 100644 package/kernel/mac80211/patches/subsys/319-wifi-mac80211-mesh-fast-xmit-support.patch - create mode 100644 package/kernel/mac80211/patches/subsys/320-wifi-mac80211-use-mesh-header-cache-to-speed-up-mesh.patch - create mode 100644 package/kernel/mac80211/patches/subsys/321-mac80211-fix-mesh-forwarding.patch - create mode 100644 package/kernel/mac80211/patches/subsys/322-wifi-mac80211-fix-mesh-path-discovery-based-on-unica.patch - create mode 100644 package/kernel/mac80211/patches/subsys/323-v6.3-wifi-mac80211-Add-VHT-MU-MIMO-related-flags-in-ieee8.patch - create mode 100644 package/kernel/mac80211/patches/subsys/324-v6.3-wifi-mac80211-Add-HE-MU-MIMO-related-flags-in-ieee80.patch - create mode 100644 package/kernel/mac80211/patches/subsys/325-wifi-mac80211-introduce-ieee80211_refresh_tx_agg_ses.patch - create mode 100644 package/kernel/mac80211/patches/subsys/326-wifi-mac80211-add-mesh-fast-rx-support.patch - create mode 100644 package/kernel/mac80211/patches/subsys/327-wifi-mac80211-add-support-for-letting-drivers-regist.patch - create mode 100644 package/kernel/mac80211/patches/subsys/329-wifi-mac80211-fix-receiving-mesh-packets-in-forwardi.patch - create mode 100644 package/kernel/mac80211/patches/subsys/330-wifi-ieee80211-correctly-mark-FTM-frames-non-buffera.patch - create mode 100644 package/kernel/mac80211/patches/subsys/331-wifi-mac80211-flush-queues-on-STA-removal.patch - create mode 100644 package/kernel/mac80211/patches/subsys/332-wifi-iwlwifi-mvm-support-flush-on-AP-interfaces.patch - create mode 100644 package/kernel/mac80211/patches/subsys/333-wifi-mac80211-add-flush_sta-method.patch - create mode 100644 package/kernel/mac80211/patches/subsys/334-wifi-iwlwifi-mvm-support-new-flush_sta-method.patch - create mode 100644 package/kernel/mac80211/patches/subsys/335-wifi-mac80211-add-LDPC-related-flags-in-ieee80211_bs.patch - create mode 100644 package/kernel/mac80211/patches/subsys/336-v6.4-wifi-mac80211-generate-EMA-beacons-in-AP-mode.patch - create mode 100644 package/kernel/mac80211/patches/subsys/337-mac80211-fix-sband-iftype-data-lookup-for-AP_VLAN.patch - create mode 100644 package/kernel/mac80211/patches/subsys/338-mac80211-split-mesh-fast-tx-cache-into-local-proxied.patch - create mode 100644 package/kernel/mac80211/patches/subsys/339-wifi-cfg80211-fix-receving-mesh-packets-without-RFC1.patch - create mode 100644 package/kernel/mac80211/patches/subsys/400-allow-ibss-mixed.patch - create mode 100644 package/kernel/mac80211/patches/subsys/782-net-next-1-of-net-pass-the-dst-buffer-to-of_get_mac_address.patch - create mode 100644 package/kernel/mac80211/ralink.mk - create mode 100644 package/kernel/mac80211/realtek.mk - create mode 100755 package/kernel/mac80211/scripts/import-backports.sh - -diff --git a/package/kernel/mac80211/Makefile b/package/kernel/mac80211/Makefile -new file mode 100644 -index 0000000000..a7472ee779 ---- /dev/null -+++ b/package/kernel/mac80211/Makefile -@@ -0,0 +1,397 @@ -+# -+# Copyright (C) 2007-2015 OpenWrt.org -+# -+# 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:=mac80211 -+ -+PKG_VERSION:=6.1.24 -+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:=5d39aca7e34c33cb9b3e366117b2e86841b7bdd37933679d6b1e61be6b150648 -+ -+PKG_SOURCE:=backports-$(PKG_VERSION).tar.xz -+PKG_BUILD_DIR:=$(KERNEL_BUILD_DIR)/backports-$(PKG_VERSION) -+PKG_BUILD_PARALLEL:=1 -+ -+PKG_MAINTAINER:=Felix Fietkau -+ -+PKG_DRIVERS = \ -+ mac80211-hwsim \ -+ mt7601u \ -+ rsi91x rsi91x-usb rsi91x-sdio\ -+ wlcore wl12xx wl18xx -+ -+PKG_CONFIG_DEPENDS:= \ -+ CONFIG_PACKAGE_kmod-mac80211 \ -+ CONFIG_PACKAGE_CFG80211_TESTMODE \ -+ CONFIG_PACKAGE_MAC80211_DEBUGFS \ -+ CONFIG_PACKAGE_MAC80211_MESH \ -+ CONFIG_PACKAGE_MAC80211_TRACING \ -+ CONFIG_PACKAGE_IWLWIFI_DEBUG \ -+ CONFIG_PACKAGE_IWLWIFI_DEBUGFS \ -+ CONFIG_PACKAGE_RTLWIFI_DEBUG \ -+ -+include $(INCLUDE_DIR)/package.mk -+ -+WMENU:=Wireless Drivers -+ -+define KernelPackage/mac80211/Default -+ SUBMENU:=$(WMENU) -+ URL:=https://wireless.wiki.kernel.org/ -+ MAINTAINER:=Felix Fietkau -+endef -+ -+config_package=$(if $(CONFIG_PACKAGE_kmod-$(1)),m) -+ -+config-y:= \ -+ WLAN \ -+ CFG80211_CERTIFICATION_ONUS \ -+ MAC80211_RC_MINSTREL \ -+ MAC80211_RC_MINSTREL_HT \ -+ MAC80211_RC_MINSTREL_VHT \ -+ MAC80211_RC_DEFAULT_MINSTREL \ -+ WLAN_VENDOR_ADMTEK \ -+ WLAN_VENDOR_ATH \ -+ WLAN_VENDOR_ATMEL \ -+ WLAN_VENDOR_BROADCOM \ -+ WLAN_VENDOR_CISCO \ -+ WLAN_VENDOR_INTEL \ -+ WLAN_VENDOR_INTERSIL \ -+ WLAN_VENDOR_MARVELL \ -+ WLAN_VENDOR_MEDIATEK \ -+ WLAN_VENDOR_RALINK \ -+ WLAN_VENDOR_REALTEK \ -+ WLAN_VENDOR_RSI \ -+ WLAN_VENDOR_ST \ -+ WLAN_VENDOR_TI \ -+ WLAN_VENDOR_ZYDAS \ -+ -+config-$(call config_package,cfg80211) += CFG80211 -+config-$(CONFIG_PACKAGE_CFG80211_TESTMODE) += NL80211_TESTMODE -+ -+config-$(call config_package,mac80211) += MAC80211 -+config-$(CONFIG_PACKAGE_MAC80211_MESH) += MAC80211_MESH -+ -+include ath.mk -+include broadcom.mk -+include intel.mk -+include marvell.mk -+include ralink.mk -+include realtek.mk -+ -+PKG_CONFIG_DEPENDS += \ -+ $(patsubst %,CONFIG_PACKAGE_kmod-%,$(PKG_DRIVERS)) -+ -+define KernelPackage/cfg80211 -+ $(call KernelPackage/mac80211/Default) -+ TITLE:=cfg80211 - wireless configuration API -+ DEPENDS+= +iw +iwinfo +wireless-regdb +USE_RFKILL:kmod-rfkill -+ ABI_VERSION:=$(PKG_VERSION)-$(PKG_RELEASE) -+ FILES:= \ -+ $(PKG_BUILD_DIR)/compat/compat.ko \ -+ $(PKG_BUILD_DIR)/net/wireless/cfg80211.ko -+endef -+ -+define KernelPackage/cfg80211/description -+cfg80211 is the Linux wireless LAN (802.11) configuration API. -+endef -+ -+define KernelPackage/cfg80211/config -+ if PACKAGE_kmod-cfg80211 -+ -+ config PACKAGE_CFG80211_TESTMODE -+ bool "Enable testmode command support" -+ default n -+ help -+ This is typically used for tests and calibration during -+ manufacturing, or vendor specific debugging features -+ -+ endif -+endef -+ -+ -+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 -+ KCONFIG:=\ -+ CONFIG_AVERAGE=y -+ FILES:= $(PKG_BUILD_DIR)/net/mac80211/mac80211.ko -+ ABI_VERSION:=$(PKG_VERSION)-$(PKG_RELEASE) -+ MENU:=1 -+endef -+ -+define KernelPackage/mac80211/config -+ if PACKAGE_kmod-mac80211 -+ -+ config PACKAGE_MAC80211_DEBUGFS -+ bool "Export mac80211 internals in DebugFS" -+ select KERNEL_DEBUG_FS -+ default y -+ help -+ Select this to see extensive information about -+ the internal state of mac80211 in debugfs. -+ -+ config PACKAGE_MAC80211_TRACING -+ bool "Enable tracing (mac80211 and supported drivers)" -+ select KERNEL_FTRACE -+ select KERNEL_ENABLE_DEFAULT_TRACERS -+ default n -+ help -+ Select this to enable tracing of mac80211 and -+ related wifi drivers (using trace-cmd). -+ -+ config PACKAGE_MAC80211_MESH -+ bool "Enable 802.11s mesh support" -+ default y -+ -+ endif -+endef -+ -+define KernelPackage/mac80211/description -+Generic IEEE 802.11 Networking Stack (mac80211) -+endef -+ -+define KernelPackage/mac80211-hwsim -+ $(call KernelPackage/mac80211/Default) -+ TITLE:=mac80211 HW simulation device -+ DEPENDS+= +kmod-mac80211 +@DRIVER_11AX_SUPPORT +@DRIVER_11AC_SUPPORT -+ FILES:=$(PKG_BUILD_DIR)/drivers/net/wireless/mac80211_hwsim.ko -+ AUTOLOAD:=$(call AutoProbe,mac80211_hwsim) -+endef -+ -+ -+define KernelPackage/mt7601u -+ $(call KernelPackage/mac80211/Default) -+ TITLE:=MT7601U-based USB dongles Wireless Driver -+ DEPENDS+= +kmod-mac80211 @USB_SUPPORT +kmod-usb-core +mt7601u-firmware -+ FILES:=$(PKG_BUILD_DIR)/drivers/net/wireless/mediatek/mt7601u/mt7601u.ko -+ AUTOLOAD:=$(call AutoProbe,mt7601u) -+endef -+ -+define KernelPackage/rsi91x -+ $(call KernelPackage/mac80211/Default) -+ TITLE:=Redpine Signals Inc 91x WLAN driver support -+ DEPENDS+= +kmod-mac80211 +rs9113-firmware -+ FILES:=$(PKG_BUILD_DIR)/drivers/net/wireless/rsi/rsi_91x.ko -+endef -+ -+define KernelPackage/rsi91x-usb -+ $(call KernelPackage/mac80211/Default) -+ TITLE:=Redpine Signals USB bus support -+ DEPENDS+=@USB_SUPPORT +kmod-usb-core +kmod-mac80211 +kmod-rsi91x +rs9113-firmware -+ FILES:=$(PKG_BUILD_DIR)/drivers/net/wireless/rsi/rsi_usb.ko -+ AUTOLOAD:=$(call AutoProbe,rsi_usb) -+endef -+ -+define KernelPackage/rsi91x-sdio -+ $(call KernelPackage/mac80211/Default) -+ TITLE:=Redpine Signals SDIO bus support -+ DEPENDS+= +kmod-mac80211 +kmod-mmc +kmod-rsi91x +rs9113-firmware -+ FILES:=$(PKG_BUILD_DIR)/drivers/net/wireless/rsi/rsi_sdio.ko -+ AUTOLOAD:=$(call AutoProbe,rsi_sdio) -+endef -+ -+ -+define KernelPackage/wlcore -+ $(call KernelPackage/mac80211/Default) -+ TITLE:=TI common driver part -+ DEPENDS+= +kmod-mmc +kmod-mac80211 -+ FILES:= \ -+ $(PKG_BUILD_DIR)/drivers/net/wireless/ti/wlcore/wlcore.ko \ -+ $(PKG_BUILD_DIR)/drivers/net/wireless/ti/wlcore/wlcore_sdio.ko -+ AUTOLOAD:=$(call AutoProbe,wlcore wlcore_sdio) -+endef -+ -+define KernelPackage/wlcore/description -+ This module contains some common parts needed by TI Wireless drivers. -+endef -+ -+define KernelPackage/wl12xx -+ $(call KernelPackage/mac80211/Default) -+ TITLE:=Driver for TI WL12xx -+ URL:=https://wireless.wiki.kernel.org/en/users/drivers/wl12xx -+ DEPENDS+= +kmod-wlcore +wl12xx-firmware -+ FILES:=$(PKG_BUILD_DIR)/drivers/net/wireless/ti/wl12xx/wl12xx.ko -+ AUTOLOAD:=$(call AutoProbe,wl12xx) -+endef -+ -+define KernelPackage/wl12xx/description -+ Kernel modules for TI WL12xx -+endef -+ -+define KernelPackage/wl18xx -+ $(call KernelPackage/mac80211/Default) -+ TITLE:=Driver for TI WL18xx -+ URL:=https://wireless.wiki.kernel.org/en/users/drivers/wl18xx -+ DEPENDS+= +kmod-wlcore +wl18xx-firmware -+ FILES:=$(PKG_BUILD_DIR)/drivers/net/wireless/ti/wl18xx/wl18xx.ko -+ AUTOLOAD:=$(call AutoProbe,wl18xx) -+endef -+ -+define KernelPackage/wl18xx/description -+ Kernel modules for TI WL18xx -+endef -+ -+ -+ifdef CONFIG_PACKAGE_MAC80211_DEBUGFS -+ config-y += \ -+ CFG80211_DEBUGFS \ -+ MAC80211_DEBUGFS -+endif -+ -+ifdef CONFIG_PACKAGE_MAC80211_TRACING -+ config-y += \ -+ IWLWIFI_DEVICE_TRACING -+endif -+ -+config-$(call config_package,mac80211-hwsim) += MAC80211_HWSIM -+config-$(call config_package,mt7601u) += MT7601U -+config-y += WL_MEDIATEK -+ -+config-$(call config_package,wlcore) += WLCORE WLCORE_SDIO -+config-$(call config_package,wl12xx) += WL12XX -+config-$(call config_package,wl18xx) += WL18XX -+config-y += WL_TI WILINK_PLATFORM_DATA -+config-$(call config_package,rsi91x) += RSI_91X -+config-$(call config_package,rsi91x-usb) += RSI_USB -+config-$(call config_package,rsi91x-sdio) += RSI_SDIO -+ -+config-$(CONFIG_LEDS_TRIGGERS) += MAC80211_LEDS -+ -+C_DEFINES= -+ -+ifeq ($(BUILD_VARIANT),smallbuffers) -+ C_DEFINES+= -DCONFIG_ATH10K_SMALLBUFFERS -+endif -+ -+MAKE_OPTS:= \ -+ $(subst -C $(LINUX_DIR),-C "$(PKG_BUILD_DIR)",$(KERNEL_MAKEOPTS)) \ -+ EXTRA_CFLAGS="-I$(PKG_BUILD_DIR)/include $(IREMAP_CFLAGS) $(C_DEFINES)" \ -+ KLIB_BUILD="$(LINUX_DIR)" \ -+ MODPROBE=true \ -+ KLIB=$(TARGET_MODULES_DIR) \ -+ KERNEL_SUBLEVEL=$(lastword $(subst ., ,$(KERNEL_PATCHVER))) \ -+ KBUILD_LDFLAGS_MODULE_PREREQ= -+ -+define ConfigVars -+$(subst $(space),,$(foreach opt,$(config-$(1)),CPTCFG_$(opt)=$(1) -+)) -+endef -+ -+define mac80211_config -+$(call ConfigVars,m)$(call ConfigVars,y) -+endef -+$(eval $(call shexport,mac80211_config)) -+ -+define Build/Prepare -+ rm -rf $(PKG_BUILD_DIR) -+ mkdir -p $(PKG_BUILD_DIR) -+ $(PKG_UNPACK) -+ $(Build/Patch) -+ rm -rf \ -+ $(PKG_BUILD_DIR)/include/linux/ssb \ -+ $(PKG_BUILD_DIR)/include/linux/bcma \ -+ $(PKG_BUILD_DIR)/include/net/bluetooth -+ -+ rm -f \ -+ $(PKG_BUILD_DIR)/include/linux/cordic.h \ -+ $(PKG_BUILD_DIR)/include/linux/crc8.h \ -+ $(PKG_BUILD_DIR)/include/linux/eeprom_93cx6.h \ -+ $(PKG_BUILD_DIR)/include/linux/wl12xx.h \ -+ $(PKG_BUILD_DIR)/include/linux/mhi.h \ -+ $(PKG_BUILD_DIR)/include/net/ieee80211.h \ -+ $(PKG_BUILD_DIR)/backport-include/linux/bcm47xx_nvram.h -+ -+ echo 'compat-wireless-$(PKG_VERSION)-$(PKG_RELEASE)-$(REVISION)' > $(PKG_BUILD_DIR)/compat_version -+endef -+ -+ifneq ($(CONFIG_PACKAGE_kmod-cfg80211),) -+ define Build/Compile/kmod -+ rm -rf $(PKG_BUILD_DIR)/modules -+ +$(MAKE) $(PKG_JOBS) $(MAKE_OPTS) modules -+ endef -+endif -+ -+#do not Build/Configure for EXTERNAL KERNEL -+ifeq ($(strip $(CONFIG_EXTERNAL_KERNEL_TREE)),"") -+ ifeq ($(strip $(CONFIG_KERNEL_GIT_CLONE_URI)),"") -+ define Build/Configure -+ cmp $(PKG_BUILD_DIR)/include/linux/ath9k_platform.h $(LINUX_DIR)/include/linux/ath9k_platform.h -+ cmp $(PKG_BUILD_DIR)/include/linux/ath5k_platform.h $(LINUX_DIR)/include/linux/ath5k_platform.h -+ cmp $(PKG_BUILD_DIR)/include/linux/rt2x00_platform.h $(LINUX_DIR)/include/linux/rt2x00_platform.h -+ endef -+ endif -+endif -+ -+define Build/Patch -+ $(if $(QUILT),rm -rf $(PKG_BUILD_DIR)/patches; mkdir -p $(PKG_BUILD_DIR)/patches) -+ $(call PatchDir,$(PKG_BUILD_DIR),$(PATCH_DIR)/build,build/) -+ $(call PatchDir,$(PKG_BUILD_DIR),$(PATCH_DIR)/subsys,subsys/) -+ $(call PatchDir,$(PKG_BUILD_DIR),$(PATCH_DIR)/ath,ath/) -+ $(call PatchDir,$(PKG_BUILD_DIR),$(PATCH_DIR)/ath5k,ath5k/) -+ $(call PatchDir,$(PKG_BUILD_DIR),$(PATCH_DIR)/ath9k,ath9k/) -+ $(call PatchDir,$(PKG_BUILD_DIR),$(PATCH_DIR)/ath10k,ath10k/) -+ $(call PatchDir,$(PKG_BUILD_DIR),$(PATCH_DIR)/ath11k,ath11k/) -+ $(call PatchDir,$(PKG_BUILD_DIR),$(PATCH_DIR)/rt2x00,rt2x00/) -+ $(call PatchDir,$(PKG_BUILD_DIR),$(PATCH_DIR)/mt7601u,mt7601u/) -+ $(call PatchDir,$(PKG_BUILD_DIR),$(PATCH_DIR)/mwl,mwl/) -+ $(call PatchDir,$(PKG_BUILD_DIR),$(PATCH_DIR)/brcm,brcm/) -+ $(call PatchDir,$(PKG_BUILD_DIR),$(PATCH_DIR)/rtl,rtl/) -+ $(if $(QUILT),touch $(PKG_BUILD_DIR)/.quilt_used) -+endef -+ -+define Quilt/Refresh/Package -+ $(call Quilt/RefreshDir,$(PKG_BUILD_DIR),$(PATCH_DIR)/build,build/) -+ $(call Quilt/RefreshDir,$(PKG_BUILD_DIR),$(PATCH_DIR)/subsys,subsys/) -+ $(call Quilt/RefreshDir,$(PKG_BUILD_DIR),$(PATCH_DIR)/ath,ath/) -+ $(call Quilt/RefreshDir,$(PKG_BUILD_DIR),$(PATCH_DIR)/ath5k,ath5k/) -+ $(call Quilt/RefreshDir,$(PKG_BUILD_DIR),$(PATCH_DIR)/ath9k,ath9k/) -+ $(call Quilt/RefreshDir,$(PKG_BUILD_DIR),$(PATCH_DIR)/ath10k,ath10k/) -+ $(call Quilt/RefreshDir,$(PKG_BUILD_DIR),$(PATCH_DIR)/ath11k,ath11k/) -+ $(call Quilt/RefreshDir,$(PKG_BUILD_DIR),$(PATCH_DIR)/rt2x00,rt2x00/) -+ $(call Quilt/RefreshDir,$(PKG_BUILD_DIR),$(PATCH_DIR)/mt7601u,mt7601u/) -+ $(call Quilt/RefreshDir,$(PKG_BUILD_DIR),$(PATCH_DIR)/mwl,mwl/) -+ $(call Quilt/RefreshDir,$(PKG_BUILD_DIR),$(PATCH_DIR)/brcm,brcm/) -+ $(call Quilt/RefreshDir,$(PKG_BUILD_DIR),$(PATCH_DIR)/rtl,rtl/) -+endef -+ -+define Build/Compile -+ $(SH_FUNC) var2file "$(call shvar,mac80211_config)" $(PKG_BUILD_DIR)/.config -+ $(MAKE) $(MAKE_OPTS) allnoconfig -+ $(call Build/Compile/kmod) -+endef -+ -+define Build/InstallDev -+ mkdir -p \ -+ $(1)/usr/include/mac80211 \ -+ $(1)/usr/include/mac80211-backport \ -+ $(1)/usr/include/mac80211/ath \ -+ $(1)/usr/include/net/mac80211 -+ $(CP) $(PKG_BUILD_DIR)/net/mac80211/*.h $(PKG_BUILD_DIR)/include/* $(1)/usr/include/mac80211/ -+ $(CP) $(PKG_BUILD_DIR)/backport-include/* $(1)/usr/include/mac80211-backport/ -+ $(CP) $(PKG_BUILD_DIR)/net/mac80211/rate.h $(1)/usr/include/net/mac80211/ -+ $(CP) $(PKG_BUILD_DIR)/drivers/net/wireless/ath/*.h $(1)/usr/include/mac80211/ath/ -+ rm -f $(1)/usr/include/mac80211-backport/linux/module.h -+endef -+ -+ -+define KernelPackage/cfg80211/install -+ $(INSTALL_DIR) $(1)/lib/wifi $(1)/lib/netifd/wireless -+ $(INSTALL_DATA) ./files/lib/wifi/mac80211.sh $(1)/lib/wifi -+ $(INSTALL_BIN) ./files/lib/netifd/wireless/mac80211.sh $(1)/lib/netifd/wireless -+ $(INSTALL_DIR) $(1)/etc/hotplug.d/ieee80211 -+ $(INSTALL_DATA) ./files/mac80211.hotplug $(1)/etc/hotplug.d/ieee80211/10-wifi-detect -+endef -+ -+$(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 -new file mode 100644 -index 0000000000..881c89db25 ---- /dev/null -+++ b/package/kernel/mac80211/ath.mk -@@ -0,0 +1,391 @@ -+PKG_DRIVERS += \ -+ ath ath5k ath6kl ath6kl-sdio ath6kl-usb ath9k ath9k-common ath9k-htc ath10k ath10k-smallbuffers \ -+ ath11k ath11k-ahb ath11k-pci carl9170 owl-loader ar5523 wil6210 -+ -+PKG_CONFIG_DEPENDS += \ -+ CONFIG_PACKAGE_ATH_DEBUG \ -+ CONFIG_PACKAGE_ATH_DFS \ -+ CONFIG_PACKAGE_ATH_SPECTRAL \ -+ CONFIG_PACKAGE_ATH_DYNACK \ -+ CONFIG_ATH9K_HWRNG \ -+ CONFIG_ATH9K_SUPPORT_PCOEM \ -+ CONFIG_ATH9K_TX99 \ -+ CONFIG_ATH10K_LEDS \ -+ CONFIG_ATH10K_THERMAL \ -+ CONFIG_ATH11K_THERMAL \ -+ CONFIG_ATH_USER_REGD -+ -+ifdef CONFIG_PACKAGE_MAC80211_DEBUGFS -+ config-y += \ -+ ATH9K_DEBUGFS \ -+ ATH9K_HTC_DEBUGFS \ -+ ATH10K_DEBUGFS \ -+ ATH11K_DEBUGFS \ -+ CARL9170_DEBUGFS \ -+ ATH5K_DEBUG \ -+ ATH6KL_DEBUG \ -+ WIL6210_DEBUGFS -+endif -+ -+ifdef CONFIG_PACKAGE_MAC80211_TRACING -+ config-y += \ -+ ATH10K_TRACING \ -+ ATH11K_TRACING \ -+ ATH6KL_TRACING \ -+ ATH_TRACEPOINTS \ -+ ATH5K_TRACER \ -+ WIL6210_TRACING -+endif -+ -+config-$(call config_package,ath) += ATH_CARDS ATH_COMMON -+config-$(CONFIG_PACKAGE_ATH_DEBUG) += ATH_DEBUG ATH10K_DEBUG ATH11K_DEBUG ATH9K_STATION_STATISTICS -+config-$(CONFIG_PACKAGE_ATH_DFS) += ATH9K_DFS_CERTIFIED ATH10K_DFS_CERTIFIED -+config-$(CONFIG_PACKAGE_ATH_SPECTRAL) += ATH9K_COMMON_SPECTRAL ATH10K_SPECTRAL ATH11K_SPECTRAL -+config-$(CONFIG_PACKAGE_ATH_DYNACK) += ATH9K_DYNACK -+config-$(call config_package,ath9k) += ATH9K -+config-$(call config_package,ath9k-common) += ATH9K_COMMON -+config-$(call config_package,owl-loader) += ATH9K_PCI_NO_EEPROM -+config-$(CONFIG_TARGET_ath79) += ATH9K_AHB -+config-$(CONFIG_TARGET_ipq40xx) += ATH10K_AHB -+config-$(CONFIG_PCI) += ATH9K_PCI -+config-$(CONFIG_ATH_USER_REGD) += ATH_USER_REGD ATH_REG_DYNAMIC_USER_REG_HINTS -+config-$(CONFIG_ATH9K_HWRNG) += ATH9K_HWRNG -+config-$(CONFIG_ATH9K_SUPPORT_PCOEM) += ATH9K_PCOEM -+config-$(CONFIG_ATH9K_TX99) += ATH9K_TX99 -+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-$(call config_package,ath9k-htc) += ATH9K_HTC -+config-$(call config_package,ath10k) += ATH10K ATH10K_PCI -+config-$(call config_package,ath10k-smallbuffers) += ATH10K ATH10K_PCI ATH10K_SMALLBUFFERS -+config-$(call config_package,ath11k) += ATH11K -+config-$(call config_package,ath11k-ahb) += ATH11K_AHB -+config-$(call config_package,ath11k-pci) += ATH11K_PCI -+ -+config-$(call config_package,ath5k) += ATH5K -+ifdef CONFIG_TARGET_ath25 -+ config-y += ATH5K_AHB -+else -+ config-y += ATH5K_PCI -+endif -+ -+config-$(call config_package,ath6kl) += ATH6KL -+config-$(call config_package,ath6kl-sdio) += ATH6KL_SDIO -+config-$(call config_package,ath6kl-usb) += ATH6KL_USB -+ -+config-$(call config_package,carl9170) += CARL9170 -+config-$(call config_package,ar5523) += AR5523 -+ -+config-$(call config_package,wil6210) += WIL6210 -+ -+define KernelPackage/ath/config -+ if PACKAGE_kmod-ath -+ config ATH_USER_REGD -+ bool "Force Atheros drivers to respect the user's regdomain settings" -+ default y -+ help -+ Atheros' idea of regulatory handling is that the EEPROM of the card defines -+ the regulatory limits and the user is only allowed to restrict the settings -+ even further, even if the country allows frequencies or power levels that -+ are forbidden by the EEPROM settings. -+ -+ Select this option if you want the driver to respect the user's decision about -+ regulatory settings. -+ -+ config PACKAGE_ATH_DEBUG -+ bool "Atheros wireless debugging" -+ help -+ Say Y, if you want to debug atheros wireless drivers. -+ Only ath9k & ath10k & ath11k make use of this. -+ -+ config PACKAGE_ATH_DFS -+ bool "Enable DFS support" -+ default y -+ help -+ Dynamic frequency selection (DFS) is required for most of the 5 GHz band -+ channels in Europe, US, and Japan. -+ -+ Select this option if you want to use such channels. -+ -+ config PACKAGE_ATH_SPECTRAL -+ bool "Atheros spectral scan support" -+ depends on PACKAGE_ATH_DEBUG -+ select KERNEL_RELAY -+ help -+ Say Y to enable access to the FFT/spectral data via debugfs. -+ -+ config PACKAGE_ATH_DYNACK -+ bool "Enable Dynack support" -+ depends on PACKAGE_kmod-ath9k-common -+ help -+ Enables support for Dynamic ACK estimation, which allows the fastest possible speed -+ at any distance automatically by increasing/decreasing the max frame ACK time for -+ the most remote station detected. It can be enabled by using iw (iw phy0 set distance auto), -+ or by sending the NL80211_ATTR_WIPHY_DYN_ACK flag to mac80211 driver using netlink. -+ -+ Select this option if you want to enable this feature -+ -+ endif -+endef -+ -+define KernelPackage/ath -+ $(call KernelPackage/mac80211/Default) -+ TITLE:=Atheros common driver part -+ DEPENDS+= @PCI_SUPPORT||USB_SUPPORT||TARGET_ath79||TARGET_ath25 +kmod-mac80211 -+ FILES:=$(PKG_BUILD_DIR)/drivers/net/wireless/ath/ath.ko -+ MENU:=1 -+endef -+ -+define KernelPackage/ath/description -+ This module contains some common parts needed by Atheros Wireless drivers. -+endef -+ -+define KernelPackage/ath5k -+ $(call KernelPackage/mac80211/Default) -+ TITLE:=Atheros 5xxx wireless cards support -+ URL:=https://wireless.wiki.kernel.org/en/users/drivers/ath5k -+ DEPENDS+= @(PCI_SUPPORT||TARGET_ath25) +kmod-ath -+ FILES:=$(PKG_BUILD_DIR)/drivers/net/wireless/ath/ath5k/ath5k.ko -+ AUTOLOAD:=$(call AutoProbe,ath5k) -+endef -+ -+define KernelPackage/ath5k/description -+ This module adds support for wireless adapters based on -+ Atheros 5xxx chipset. -+endef -+ -+define KernelPackage/ath6kl -+ $(call KernelPackage/mac80211/Default) -+ TITLE:=Atheros FullMAC wireless devices (common code for ath6kl_sdio and ath6kl_usb) -+ URL:=https://wireless.wiki.kernel.org/en/users/drivers/ath6kl -+ HIDDEN:=1 -+ DEPENDS+= +kmod-ath -+ FILES:= $(PKG_BUILD_DIR)/drivers/net/wireless/ath/ath6kl/ath6kl_core.ko -+endef -+ -+define KernelPackage/ath6kl-sdio -+ $(call KernelPackage/mac80211/Default) -+ TITLE:=Atheros 802.11n SDIO wireless cards support -+ URL:=https://wireless.wiki.kernel.org/en/users/drivers/ath6kl -+ DEPENDS+= +kmod-mmc +kmod-ath6kl -+ FILES:= $(PKG_BUILD_DIR)/drivers/net/wireless/ath/ath6kl/ath6kl_sdio.ko -+ AUTOLOAD:=$(call AutoProbe,ath6kl_sdio) -+endef -+ -+define KernelPackage/ath6kl-sdio/description -+This module adds support for wireless adapters based on -+Atheros IEEE 802.11n AR6003 and AR6004 family of chipsets. -+endef -+ -+define KernelPackage/ath6kl-usb -+ $(call KernelPackage/mac80211/Default) -+ TITLE:=Atheros 802.11n USB wireless cards support -+ URL:=https://wireless.wiki.kernel.org/en/users/drivers/ath6kl -+ DEPENDS+= @USB_SUPPORT +kmod-usb-core +kmod-ath6kl -+ FILES:= $(PKG_BUILD_DIR)/drivers/net/wireless/ath/ath6kl/ath6kl_usb.ko -+ AUTOLOAD:=$(call AutoProbe,ath6kl_usb) -+endef -+ -+define KernelPackage/ath6kl-usb/description -+This module adds support for wireless adapters based on the -+Atheros IEEE 802.11n AR6004 chipset. -+endef -+ -+define KernelPackage/ath9k-common -+ $(call KernelPackage/mac80211/Default) -+ TITLE:=Atheros 802.11n wireless devices (common code for ath9k and ath9k_htc) -+ URL:=https://wireless.wiki.kernel.org/en/users/drivers/ath9k -+ HIDDEN:=1 -+ DEPENDS+= @PCI_SUPPORT||USB_SUPPORT||TARGET_ath79 +kmod-ath +kmod-random-core -+ FILES:= \ -+ $(PKG_BUILD_DIR)/drivers/net/wireless/ath/ath9k/ath9k_common.ko \ -+ $(PKG_BUILD_DIR)/drivers/net/wireless/ath/ath9k/ath9k_hw.ko -+endef -+ -+define KernelPackage/ath9k -+ $(call KernelPackage/mac80211/Default) -+ TITLE:=Atheros 802.11n PCI wireless cards support -+ URL:=https://wireless.wiki.kernel.org/en/users/drivers/ath9k -+ DEPENDS+= @PCI_SUPPORT||TARGET_ath79 +kmod-ath9k-common -+ FILES:= \ -+ $(PKG_BUILD_DIR)/drivers/net/wireless/ath/ath9k/ath9k.ko -+ AUTOLOAD:=$(call AutoProbe,ath9k) -+endef -+ -+define KernelPackage/ath9k/description -+This module adds support for wireless adapters based on -+Atheros IEEE 802.11n AR5008 and AR9001 family of chipsets. -+endef -+ -+define KernelPackage/ath9k/config -+ -+ config ATH9K_HWRNG -+ bool "Add wireless noise as source of randomness to kernel entropy pool" -+ depends on PACKAGE_kmod-ath9k -+ select PACKAGE_kmod-random-core -+ default y -+ -+ config ATH9K_SUPPORT_PCOEM -+ bool "Support chips used in PC OEM cards" -+ depends on PACKAGE_kmod-ath9k -+ default y if (x86_64 || i386) -+ -+ config ATH9K_TX99 -+ bool "Enable TX99 support (WARNING: testing only, breaks normal operation!)" -+ depends on PACKAGE_kmod-ath9k -+ -+ config ATH9K_UBNTHSR -+ bool "Support for Ubiquiti UniFi Outdoor+ access point" -+ depends on PACKAGE_kmod-ath9k && TARGET_ath79 -+ default y -+ -+endef -+ -+define KernelPackage/ath9k-htc -+ $(call KernelPackage/mac80211/Default) -+ TITLE:=Atheros 802.11n USB device support -+ URL:=https://wireless.wiki.kernel.org/en/users/drivers/ath9k -+ DEPENDS+= @USB_SUPPORT +kmod-ath9k-common +kmod-usb-core +ath9k-htc-firmware -+ FILES:= \ -+ $(PKG_BUILD_DIR)/drivers/net/wireless/ath/ath9k/ath9k_htc.ko -+ AUTOLOAD:=$(call AutoProbe,ath9k_htc) -+endef -+ -+define KernelPackage/ath9k-htc/description -+This module adds support for wireless adapters based on -+Atheros USB AR9271 and AR7010 family of chipsets. -+endef -+ -+define KernelPackage/ath10k -+ $(call KernelPackage/mac80211/Default) -+ TITLE:=Atheros 802.11ac wireless cards support -+ URL:=https://wireless.wiki.kernel.org/en/users/drivers/ath10k -+ DEPENDS+= @PCI_SUPPORT +kmod-ath +@DRIVER_11AC_SUPPORT \ -+ +ATH10K_THERMAL:kmod-hwmon-core +ATH10K_THERMAL:kmod-thermal -+ FILES:= \ -+ $(PKG_BUILD_DIR)/drivers/net/wireless/ath/ath10k/ath10k_core.ko \ -+ $(PKG_BUILD_DIR)/drivers/net/wireless/ath/ath10k/ath10k_pci.ko -+ AUTOLOAD:=$(call AutoProbe,ath10k_core ath10k_pci) -+ MODPARAMS.ath10k_core:=frame_mode=2 -+ VARIANT:=regular -+endef -+ -+define KernelPackage/ath10k/description -+This module adds support for wireless adapters based on -+Atheros IEEE 802.11ac family of chipsets. For now only -+PCI is supported. -+endef -+ -+define KernelPackage/ath10k/config -+ -+ config ATH10K_LEDS -+ bool "Enable LED support" -+ default y -+ depends on PACKAGE_kmod-ath10k || PACKAGE_kmod-ath10k-smallbuffers -+ -+ config ATH10K_THERMAL -+ bool "Enable thermal sensors and throttling support" -+ depends on PACKAGE_kmod-ath10k || PACKAGE_kmod-ath10k-smallbuffers -+ -+endef -+ -+define KernelPackage/ath10k-smallbuffers -+ $(call KernelPackage/ath10k) -+ TITLE+= (small buffers for low-RAM devices) -+ VARIANT:=smallbuffers -+endef -+ -+define KernelPackage/ath11k -+ $(call KernelPackage/mac80211/Default) -+ 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 -+ FILES:=$(PKG_BUILD_DIR)/drivers/soc/qcom/qmi_helpers.ko \ -+ $(PKG_BUILD_DIR)/drivers/net/wireless/ath/ath11k/ath11k.ko -+endef -+ -+define KernelPackage/ath11k/description -+This module adds support for Qualcomm Technologies 802.11ax family of -+chipsets. -+endef -+ -+define KernelPackage/ath11k/config -+ -+ config ATH11K_THERMAL -+ bool "Enable thermal sensors and throttling support" -+ depends on PACKAGE_kmod-ath11k -+ default y if TARGET_qualcommax -+ -+endef -+ -+define KernelPackage/ath11k-ahb -+ $(call KernelPackage/mac80211/Default) -+ TITLE:=Qualcomm 802.11ax AHB wireless chipset support -+ URL:=https://wireless.wiki.kernel.org/en/users/drivers/ath11k -+ DEPENDS+= @TARGET_qualcommax +kmod-ath11k +kmod-qrtr-smd -+ FILES:=$(PKG_BUILD_DIR)/drivers/net/wireless/ath/ath11k/ath11k_ahb.ko -+ AUTOLOAD:=$(call AutoProbe,ath11k_ahb) -+endef -+ -+define KernelPackage/ath11k-ahb/description -+This module adds support for Qualcomm Technologies 802.11ax family of -+chipsets with AHB bus. -+endef -+ -+define KernelPackage/ath11k-pci -+ $(call KernelPackage/mac80211/Default) -+ TITLE:=Qualcomm 802.11ax PCI wireless chipset support -+ URL:=https://wireless.wiki.kernel.org/en/users/drivers/ath11k -+ DEPENDS+= @PCI_SUPPORT +kmod-qrtr-mhi +kmod-ath11k -+ FILES:=$(PKG_BUILD_DIR)/drivers/net/wireless/ath/ath11k/ath11k_pci.ko -+ AUTOLOAD:=$(call AutoProbe,ath11k_pci) -+endef -+ -+define KernelPackage/ath11k-pci/description -+This module adds support for Qualcomm Technologies 802.11ax family of -+chipsets with PCI bus. -+endef -+ -+define KernelPackage/carl9170 -+ $(call KernelPackage/mac80211/Default) -+ TITLE:=Driver for Atheros AR9170 USB sticks -+ DEPENDS:=@USB_SUPPORT +kmod-mac80211 +kmod-ath +kmod-usb-core +kmod-input-core +carl9170-firmware -+ FILES:=$(PKG_BUILD_DIR)/drivers/net/wireless/ath/carl9170/carl9170.ko -+ AUTOLOAD:=$(call AutoProbe,carl9170) -+endef -+ -+define KernelPackage/owl-loader -+ $(call KernelPackage/mac80211/Default) -+ TITLE:=Owl loader for initializing Atheros PCI(e) Wifi chips -+ DEPENDS:=@PCI_SUPPORT +kmod-ath9k -+ FILES:=$(PKG_BUILD_DIR)/drivers/net/wireless/ath/ath9k/ath9k_pci_owl_loader.ko -+ AUTOLOAD:=$(call AutoProbe,ath9k_pci_owl_loader) -+endef -+ -+define KernelPackage/owl-loader/description -+ Kernel module that helps to initialize certain Qualcomm -+ Atheros' PCI(e) Wifi chips, which have the init data -+ (which contains the PCI device ID for example) stored -+ together with the calibration data in the file system. -+ -+ This is necessary for devices like the Cisco Meraki Z1. -+endef -+ -+define KernelPackage/ar5523 -+ $(call KernelPackage/mac80211/Default) -+ TITLE:=Driver for Atheros AR5523 USB sticks -+ DEPENDS:=@USB_SUPPORT +kmod-mac80211 +kmod-ath +kmod-usb-core +kmod-input-core -+ FILES:=$(PKG_BUILD_DIR)/drivers/net/wireless/ath/ar5523/ar5523.ko -+ AUTOLOAD:=$(call AutoProbe,ar5523) -+endef -+ -+define KernelPackage/wil6210 -+ $(call KernelPackage/mac80211/Default) -+ TITLE:=QCA/Wilocity 60g WiFi card wil6210 support -+ DEPENDS+= @PCI_SUPPORT +kmod-mac80211 +wil6210-firmware -+ FILES:=$(PKG_BUILD_DIR)/drivers/net/wireless/ath/wil6210/wil6210.ko -+ AUTOLOAD:=$(call AutoProbe,wil6210) -+endef -diff --git a/package/kernel/mac80211/broadcom.mk b/package/kernel/mac80211/broadcom.mk -new file mode 100644 -index 0000000000..13da62a6f4 ---- /dev/null -+++ b/package/kernel/mac80211/broadcom.mk -@@ -0,0 +1,492 @@ -+PKG_DRIVERS += \ -+ b43 brcmsmac brcmfmac brcmutil -+ -+PKG_CONFIG_DEPENDS += \ -+ CONFIG_PACKAGE_B43_DEBUG \ -+ CONFIG_PACKAGE_B43_PIO \ -+ CONFIG_PACKAGE_B43_PHY_G \ -+ CONFIG_PACKAGE_B43_PHY_N \ -+ CONFIG_PACKAGE_B43_PHY_LP \ -+ CONFIG_PACKAGE_B43_PHY_HT \ -+ CONFIG_PACKAGE_B43_BUSES_BCMA_AND_SSB \ -+ CONFIG_PACKAGE_B43_BUSES_BCMA \ -+ CONFIG_PACKAGE_B43_BUSES_SSB \ -+ CONFIG_PACKAGE_BRCM80211_DEBUG -+ -+config-$(call config_package,b43) += B43 -+config-$(CONFIG_PACKAGE_B43_BUSES_BCMA_AND_SSB) += B43_BUSES_BCMA_AND_SSB -+config-$(CONFIG_PACKAGE_B43_BUSES_BCMA) += B43_BUSES_BCMA -+config-$(CONFIG_PACKAGE_B43_BUSES_SSB) += B43_BUSES_SSB -+config-$(CONFIG_PACKAGE_B43_PHY_G) += B43_PHY_G -+config-$(CONFIG_PACKAGE_B43_PHY_N) += B43_PHY_N -+config-$(CONFIG_PACKAGE_B43_PHY_LP) += B43_PHY_LP -+config-$(CONFIG_PACKAGE_B43_PHY_HT) += B43_PHY_HT -+config-$(CONFIG_PACKAGE_B43_PIO) += B43_PIO -+config-$(CONFIG_PACKAGE_B43_DEBUG) += B43_DEBUG -+ -+config-$(call config_package,brcmutil) += BRCMUTIL -+config-$(call config_package,brcmsmac) += BRCMSMAC -+config-$(call config_package,brcmfmac) += BRCMFMAC -+config-$(CONFIG_BRCMFMAC_SDIO) += BRCMFMAC_SDIO -+config-$(CONFIG_BRCMFMAC_USB) += BRCMFMAC_USB -+config-$(CONFIG_BRCMFMAC_PCIE) += BRCMFMAC_PCIE -+config-$(CONFIG_PACKAGE_BRCM80211_DEBUG) += BRCMDBG -+ -+config-$(CONFIG_LEDS_TRIGGERS) += B43_LEDS B43LEGACY_LEDS -+ -+#Broadcom firmware -+ifneq ($(CONFIG_B43_FW_6_30),) -+ PKG_B43_FWV4_NAME:=broadcom-wl -+ PKG_B43_FWV4_VERSION:=6.30.163.46 -+ PKG_B43_FWV4_OBJECT:=$(PKG_B43_FWV4_NAME)-$(PKG_B43_FWV4_VERSION).wl_apsta.o -+ PKG_B43_FWV4_SOURCE:=$(PKG_B43_FWV4_NAME)-$(PKG_B43_FWV4_VERSION).tar.bz2 -+ PKG_B43_FWV4_SOURCE_URL:=http://www.lwfinger.com/b43-firmware/ -+ PKG_B43_FWV4_HASH:=a07c3b6b277833c7dbe61daa511f908cd66c5e2763eb7a0859abc36cd9335c2d -+else -+ifneq ($(CONFIG_B43_FW_5_10),) -+ PKG_B43_FWV4_NAME:=broadcom-wl -+ PKG_B43_FWV4_VERSION:=5.10.56.27.3 -+ PKG_B43_FWV4_OBJECT:=$(PKG_B43_FWV4_NAME)-$(PKG_B43_FWV4_VERSION)/driver/wl_apsta/wl_prebuilt.o -+ PKG_B43_FWV4_SOURCE:=$(PKG_B43_FWV4_NAME)-$(PKG_B43_FWV4_VERSION)_mipsel.tar.bz2 -+ PKG_B43_FWV4_SOURCE_URL:=@OPENWRT -+ PKG_B43_FWV4_HASH:=26a8c370f48fc129d0731cfd751c36cae1419b0bc8ca35781126744e60eae009 -+else -+ifneq ($(CONFIG_B43_FW_4_178),) -+ PKG_B43_FWV4_NAME:=broadcom-wl -+ PKG_B43_FWV4_VERSION:=4.178.10.4 -+ PKG_B43_FWV4_OBJECT:=$(PKG_B43_FWV4_NAME)-$(PKG_B43_FWV4_VERSION)/linux/wl_apsta.o -+ PKG_B43_FWV4_SOURCE:=$(PKG_B43_FWV4_NAME)-$(PKG_B43_FWV4_VERSION).tar.bz2 -+ PKG_B43_FWV4_SOURCE_URL:=@OPENWRT -+ PKG_B43_FWV4_HASH:=32f6ad98facbb9045646fdc8b54bb03086d204153253f9c65d0234a5d90ae53f -+else -+ifneq ($(CONFIG_B43_FW_5_100_138),) -+ PKG_B43_FWV4_NAME:=broadcom-wl -+ PKG_B43_FWV4_VERSION:=5.100.138 -+ PKG_B43_FWV4_OBJECT:=$(PKG_B43_FWV4_NAME)-$(PKG_B43_FWV4_VERSION)/linux/wl_apsta.o -+ PKG_B43_FWV4_SOURCE:=$(PKG_B43_FWV4_NAME)-$(PKG_B43_FWV4_VERSION).tar.bz2 -+ PKG_B43_FWV4_SOURCE_URL:=http://www.lwfinger.com/b43-firmware/ -+ PKG_B43_FWV4_HASH:=f1e7067aac5b62b67b8b6e4c517990277804339ac16065eb13c731ff909ae46f -+else -+ PKG_B43_FWV4_NAME:=broadcom-wl -+ PKG_B43_FWV4_VERSION:=4.150.10.5 -+ PKG_B43_FWV4_OBJECT:=$(PKG_B43_FWV4_NAME)-$(PKG_B43_FWV4_VERSION)/driver/wl_apsta_mimo.o -+ PKG_B43_FWV4_SOURCE:=$(PKG_B43_FWV4_NAME)-$(PKG_B43_FWV4_VERSION).tar.bz2 -+ PKG_B43_FWV4_SOURCE_URL:=@OPENWRT -+ PKG_B43_FWV4_HASH:=a9f4e276a4d8d3a1cd0f2eb87080ae89b77f0a7140f06d4e9e2135fc44fdd533 -+endif -+endif -+endif -+endif -+ifneq ($(CONFIG_B43_OPENFIRMWARE),) -+ PKG_B43_FWV4_NAME:=broadcom-wl -+ PKG_B43_FWV4_VERSION:=5.2 -+ PKG_B43_FWV4_OBJECT:=openfwwf-$(PKG_B43_FWV4_VERSION) -+ PKG_B43_FWV4_SOURCE:=openfwwf-$(PKG_B43_FWV4_VERSION).tar.gz -+ PKG_B43_FWV4_SOURCE_URL:=http://netweb.ing.unibs.it/~openfwwf/firmware -+ PKG_B43_FWV4_HASH:=9de03320083201080b2e94b81637ac07a159cf4e6f3481383e1a217e627bc0dc -+endif -+ -+ -+define Download/b43 -+ FILE:=$(PKG_B43_FWV4_SOURCE) -+ URL:=$(PKG_B43_FWV4_SOURCE_URL) -+ HASH:=$(PKG_B43_FWV4_HASH) -+endef -+$(eval $(call Download,b43)) -+ -+define KernelPackage/b43 -+ $(call KernelPackage/mac80211/Default) -+ TITLE:=Broadcom 43xx wireless support -+ URL:=https://wireless.wiki.kernel.org/en/users/drivers/b43 -+ KCONFIG:= \ -+ CONFIG_HW_RANDOM=y -+ # Depend on PCI_SUPPORT to make sure we can select kmod-bcma or kmod-ssb -+ DEPENDS += \ -+ @PCI_SUPPORT +kmod-mac80211 +kmod-lib-cordic \ -+ $(if $(CONFIG_PACKAGE_B43_USE_SSB),+kmod-ssb) \ -+ $(if $(CONFIG_PACKAGE_B43_USE_BCMA),+kmod-bcma) -+ FILES:=$(PKG_BUILD_DIR)/drivers/net/wireless/broadcom/b43/b43.ko -+ AUTOLOAD:=$(call AutoProbe,b43) -+ MENU:=1 -+endef -+ -+define KernelPackage/b43/config -+ -+config PACKAGE_B43_USE_SSB -+ select PACKAGE_kmod-ssb -+ tristate -+ depends on !TARGET_bcm47xx && !TARGET_bcm63xx -+ default PACKAGE_kmod-b43 if PACKAGE_B43_BUSES_BCMA_AND_SSB -+ default PACKAGE_kmod-b43 if PACKAGE_B43_BUSES_SSB -+ -+config PACKAGE_B43_USE_BCMA -+ select PACKAGE_kmod-bcma -+ tristate -+ depends on !TARGET_bcm47xx && !TARGET_bcm53xx -+ default PACKAGE_kmod-b43 if PACKAGE_B43_BUSES_BCMA_AND_SSB -+ default PACKAGE_kmod-b43 if PACKAGE_B43_BUSES_BCMA -+ -+ if PACKAGE_kmod-b43 -+ -+ choice -+ prompt "b43 firmware version" -+ default B43_FW_5_100_138 -+ help -+ This option allows you to select the version of the b43 firmware. -+ -+ config B43_FW_4_150 -+ bool "Firmware 410.2160 from driver 4.150.10.5 (old stable)" -+ help -+ Old stable firmware for BCM43xx devices. -+ -+ If unsure, select this. -+ -+ config B43_FW_4_178 -+ bool "Firmware 478.104 from driver 4.178.10.4" -+ help -+ Older firmware for BCM43xx devices. -+ -+ If unsure, select the "stable" firmware. -+ -+ config B43_FW_5_10 -+ bool "Firmware 508.1084 from driver 5.10.56.27" -+ help -+ Older firmware for BCM43xx devices. -+ -+ If unsure, select the "stable" firmware. -+ -+ config B43_FW_5_100_138 -+ bool "Firmware 666.2 from driver 5.100.138 (stable)" -+ help -+ The currently default firmware for BCM43xx devices. -+ -+ This firmware currently gets most of the testing and is needed for some N-PHY devices. -+ -+ If unsure, select the this firmware. -+ -+ config B43_FW_6_30 -+ bool "Firmware 784.2 from driver 6.30.163.46 (experimental)" -+ help -+ Newer experimental firmware for BCM43xx devices. -+ -+ This firmware is mostly untested. -+ -+ If unsure, select the "stable" firmware. -+ -+ config B43_OPENFIRMWARE -+ bool "Open FirmWare for WiFi networks" -+ help -+ Opensource firmware for BCM43xx devices. -+ -+ Do _not_ select this, unless you know what you are doing. -+ The Opensource firmware is not suitable for embedded devices, yet. -+ It does not support QoS, which is bad for AccessPoints. -+ It does not support hardware crypto acceleration, which is a showstopper -+ for embedded devices with low CPU resources. -+ -+ If unsure, select the "stable" firmware. -+ -+ endchoice -+ -+ config B43_FW_SQUASH -+ bool "Remove unnecessary firmware files" -+ depends on !B43_OPENFIRMWARE -+ default y -+ help -+ This options allows you to remove unnecessary b43 firmware files -+ from the final rootfs image. This can reduce the rootfs size by -+ up to 200k. -+ -+ If unsure, say Y. -+ -+ config B43_FW_SQUASH_COREREVS -+ string "Core revisions to include" -+ depends on B43_FW_SQUASH -+ default "5,6,7,8,9,10,11,13,15" if TARGET_bcm47xx_legacy -+ default "16,28,29,30" if TARGET_bcm47xx_mips74k -+ default "5,6,7,8,9,10,11,13,15,16,28,29,30" -+ help -+ This is a comma separated list of core revision numbers. -+ -+ Example (keep files for rev5 only): -+ 5 -+ -+ Example (keep files for rev5 and rev11): -+ 5,11 -+ -+ config B43_FW_SQUASH_PHYTYPES -+ string "PHY types to include" -+ depends on B43_FW_SQUASH -+ default "G,N,LP" if TARGET_bcm47xx_legacy -+ default "N,HT" if TARGET_bcm47xx_mips74k -+ default "G,N,LP,HT" -+ help -+ This is a comma separated list of PHY types: -+ A => A-PHY -+ AG => Dual A-PHY G-PHY -+ G => G-PHY -+ LP => LP-PHY -+ N => N-PHY -+ HT => HT-PHY -+ LCN => LCN-PHY -+ LCN40 => LCN40-PHY -+ AC => AC-PHY -+ -+ Example (keep files for G-PHY only): -+ G -+ -+ Example (keep files for G-PHY and N-PHY): -+ G,N -+ -+ choice -+ prompt "Supported buses" -+ default PACKAGE_B43_BUSES_BCMA_AND_SSB -+ help -+ This allows choosing buses that b43 should support. -+ -+ config PACKAGE_B43_BUSES_BCMA_AND_SSB -+ depends on !TARGET_bcm47xx_legacy && !TARGET_bcm47xx_mips74k && !TARGET_bcm53xx && !TARGET_bmips -+ bool "BCMA and SSB" -+ -+ config PACKAGE_B43_BUSES_BCMA -+ depends on !TARGET_bcm47xx_legacy && !TARGET_bmips_bcm6358 && !TARGET_bmips_bcm6368 -+ bool "BCMA only" -+ -+ config PACKAGE_B43_BUSES_SSB -+ depends on !TARGET_bcm47xx_mips74k && !TARGET_bcm53xx -+ bool "SSB only" -+ -+ endchoice -+ -+ config PACKAGE_B43_DEBUG -+ bool "Enable debug output and debugfs for b43" -+ default n -+ help -+ Enable additional debug output and runtime sanity checks for b43 -+ and enables the debugfs interface. -+ -+ If unsure, say N. -+ -+ config PACKAGE_B43_PIO -+ bool "Enable support for PIO transfer mode" -+ default n -+ help -+ Enable support for using PIO instead of DMA. Unless you have DMA -+ transfer problems you don't need this. -+ -+ If unsure, say N. -+ -+ config PACKAGE_B43_PHY_G -+ bool "Enable support for G-PHYs" -+ default n if TARGET_bcm47xx_mips74k -+ default y -+ help -+ Enable support for G-PHY. This includes support for the following devices: -+ PCI: BCM4306, BCM4311, BCM4318 -+ SoC: BCM5352E, BCM4712 -+ -+ If unsure, say Y. -+ -+ config PACKAGE_B43_PHY_N -+ bool "Enable support for N-PHYs" -+ default y -+ help -+ Enable support for N-PHY. This includes support for the following devices: -+ PCI: BCM4321, BCM4322, BCM43222, BCM43224, BCM43225 -+ SoC: BCM4716, BCM4717, BCM4718 -+ -+ Currently only 11g speed is available. -+ -+ If unsure, say Y. -+ -+ config PACKAGE_B43_PHY_LP -+ bool "Enable support for LP-PHYs" -+ default n if TARGET_bcm47xx_mips74k -+ default y -+ help -+ Enable support for LP-PHY. This includes support for the following devices: -+ PCI: BCM4312 -+ SoC: BCM5354 -+ -+ If unsure, say Y. -+ -+ config PACKAGE_B43_PHY_HT -+ bool "Enable support for HT-PHYs" -+ default n if TARGET_bcm47xx_legacy -+ default y -+ help -+ Enable support for HT-PHY. This includes support for the following devices: -+ PCI: BCM4331 -+ -+ Currently only 11g speed is available. -+ -+ If unsure, say Y. -+ -+ config PACKAGE_B43_PHY_LCN -+ bool "Enable support for LCN-PHYs" -+ depends on BROKEN -+ default n -+ help -+ Currently broken. -+ -+ If unsure, say N. -+ -+ endif -+endef -+ -+define KernelPackage/b43/description -+Kernel module for Broadcom 43xx wireless support (mac80211 stack) new -+endef -+ -+define KernelPackage/brcmutil -+ $(call KernelPackage/mac80211/Default) -+ TITLE:=Broadcom IEEE802.11n common driver parts -+ URL:=https://wireless.wiki.kernel.org/en/users/drivers/brcm80211 -+ DEPENDS+=@PCI_SUPPORT||USB_SUPPORT -+ FILES:=$(PKG_BUILD_DIR)/drivers/net/wireless/broadcom/brcm80211/brcmutil/brcmutil.ko -+ AUTOLOAD:=$(call AutoProbe,brcmutil) -+ MENU:=1 -+endef -+ -+define KernelPackage/brcmutil/description -+ This module contains some common parts needed by Broadcom Wireless drivers brcmsmac and brcmfmac. -+endef -+ -+define KernelPackage/brcmutil/config -+ if PACKAGE_kmod-brcmutil -+ -+ config PACKAGE_BRCM80211_DEBUG -+ bool "Broadcom wireless driver debugging" -+ help -+ Say Y, if you want to debug brcmsmac and brcmfmac wireless driver. -+ -+ endif -+endef -+ -+PKG_BRCMSMAC_FW_NAME:=broadcom-wl -+PKG_BRCMSMAC_FW_VERSION:=5.100.138 -+PKG_BRCMSMAC_FW_OBJECT:=$(PKG_BRCMSMAC_FW_NAME)-$(PKG_BRCMSMAC_FW_VERSION)/linux/wl_apsta.o -+PKG_BRCMSMAC_FW_SOURCE:=$(PKG_BRCMSMAC_FW_NAME)-$(PKG_BRCMSMAC_FW_VERSION).tar.bz2 -+PKG_BRCMSMAC_FW_SOURCE_URL:=http://www.lwfinger.com/b43-firmware/ -+PKG_BRCMSMAC_FW_HASH:=f1e7067aac5b62b67b8b6e4c517990277804339ac16065eb13c731ff909ae46f -+ -+define Download/brcmsmac -+ FILE:=$(PKG_BRCMSMAC_FW_SOURCE) -+ URL:=$(PKG_BRCMSMAC_FW_SOURCE_URL) -+ HASH:=$(PKG_BRCMSMAC_FW_HASH) -+endef -+$(eval $(call Download,brcmsmac)) -+ -+define KernelPackage/brcmsmac -+ $(call KernelPackage/mac80211/Default) -+ TITLE:=Broadcom IEEE802.11n PCIe SoftMAC WLAN driver -+ URL:=https://wireless.wiki.kernel.org/en/users/drivers/brcm80211 -+ DEPENDS+=@!TARGET_bcm47xx_legacy +kmod-mac80211 +!TARGET_bcm47xx:kmod-bcma +kmod-lib-cordic +kmod-lib-crc8 +kmod-brcmutil +!BRCMSMAC_USE_FW_FROM_WL:brcmsmac-firmware -+ FILES:=$(PKG_BUILD_DIR)/drivers/net/wireless/broadcom/brcm80211/brcmsmac/brcmsmac.ko -+ AUTOLOAD:=$(call AutoProbe,brcmsmac) -+ MENU:=1 -+endef -+ -+define KernelPackage/brcmsmac/description -+ Kernel module for Broadcom IEEE802.11n PCIe Wireless cards -+endef -+ -+define KernelPackage/brcmsmac/config -+ if PACKAGE_kmod-brcmsmac -+ -+ config BRCMSMAC_USE_FW_FROM_WL -+ bool "Use firmware extracted from broadcom proprietary driver" -+ default y -+ help -+ Instead of using the official brcmsmac firmware a firmware -+ version 666.2 extracted from the proprietary Broadcom driver -+ is used. This is needed to get core rev 17 used in bcm4716 -+ to work. -+ -+ If unsure, say Y. -+ -+ endif -+endef -+ -+ -+define KernelPackage/brcmfmac -+ $(call KernelPackage/mac80211/Default) -+ TITLE:=Broadcom IEEE802.11n USB FullMAC WLAN driver -+ URL:=https://wireless.wiki.kernel.org/en/users/drivers/brcm80211 -+ DEPENDS+= @USB_SUPPORT +kmod-cfg80211 +@DRIVER_11AC_SUPPORT \ -+ +kmod-brcmutil +BRCMFMAC_SDIO:kmod-mmc @!TARGET_uml \ -+ +BRCMFMAC_USB:kmod-usb-core +BRCMFMAC_USB:brcmfmac-firmware-usb -+ FILES:=$(PKG_BUILD_DIR)/drivers/net/wireless/broadcom/brcm80211/brcmfmac/brcmfmac.ko -+ AUTOLOAD:=$(call AutoProbe,brcmfmac) -+endef -+ -+define KernelPackage/brcmfmac/description -+ Kernel module for Broadcom IEEE802.11n USB Wireless cards -+endef -+ -+define KernelPackage/brcmfmac/config -+ if PACKAGE_kmod-brcmfmac -+ -+ config BRCMFMAC_SDIO -+ bool "Enable SDIO bus interface support" -+ default y if TARGET_bcm27xx -+ default y if TARGET_imx_cortexa7 -+ default y if TARGET_rockchip -+ default y if TARGET_sunxi -+ default n -+ help -+ Enable support for cards attached to an SDIO bus. -+ Select this option only if you are sure that your -+ board has a Broadcom wireless chip atacched to -+ that bus. -+ -+ config BRCMFMAC_USB -+ bool "Enable USB bus interface support" -+ depends on USB_SUPPORT -+ default y -+ help -+ Supported USB connected chipsets: -+ BCM43235, BCM43236, BCM43238 (all in revision 3 only) -+ BCM43143, BCM43242, BCM43566, BCM43569 -+ -+ config BRCMFMAC_PCIE -+ bool "Enable PCIE bus interface support" -+ depends on PCI_SUPPORT -+ default y -+ help -+ Supported PCIe connected chipsets: -+ BCM4354, BCM4356, BCM43567, BCM43570, BCM43602 -+ -+ endif -+endef -+ -+ -+define KernelPackage/b43/install -+ rm -rf $(1)/lib/firmware/ -+ifeq ($(CONFIG_B43_OPENFIRMWARE),y) -+ tar xzf "$(DL_DIR)/$(PKG_B43_FWV4_SOURCE)" -C "$(PKG_BUILD_DIR)" -+else -+ tar xjf "$(DL_DIR)/$(PKG_B43_FWV4_SOURCE)" -C "$(PKG_BUILD_DIR)" -+endif -+ $(INSTALL_DIR) $(1)/lib/firmware/ -+ifeq ($(CONFIG_B43_OPENFIRMWARE),y) -+ $(MAKE) -C "$(PKG_BUILD_DIR)/$(PKG_B43_FWV4_OBJECT)/" -+ $(INSTALL_DIR) $(1)/lib/firmware/b43-open/ -+ $(INSTALL_DATA) $(PKG_BUILD_DIR)/$(PKG_B43_FWV4_OBJECT)/ucode5.fw $(1)/lib/firmware/b43-open/ucode5.fw -+ $(INSTALL_DATA) $(PKG_BUILD_DIR)/$(PKG_B43_FWV4_OBJECT)/b0g0bsinitvals5.fw $(1)/lib/firmware/b43-open/b0g0bsinitvals5.fw -+ $(INSTALL_DATA) $(PKG_BUILD_DIR)/$(PKG_B43_FWV4_OBJECT)/b0g0initvals5.fw $(1)/lib/firmware/b43-open/b0g0initvals5.fw -+else -+ b43-fwcutter -w $(1)/lib/firmware/ $(PKG_BUILD_DIR)/$(PKG_B43_FWV4_OBJECT) -+endif -+ifneq ($(CONFIG_B43_FW_SQUASH),) -+ b43-fwsquash.py "$(CONFIG_B43_FW_SQUASH_PHYTYPES)" "$(CONFIG_B43_FW_SQUASH_COREREVS)" "$(1)/lib/firmware/b43" -+endif -+endef -+ -+define KernelPackage/brcmsmac/install -+ $(INSTALL_DIR) $(1)/lib/firmware/brcm -+ifeq ($(CONFIG_BRCMSMAC_USE_FW_FROM_WL),y) -+ tar xjf "$(DL_DIR)/$(PKG_BRCMSMAC_FW_SOURCE)" -C "$(PKG_BUILD_DIR)" -+ b43-fwcutter --brcmsmac -w $(1)/lib/firmware/ $(PKG_BUILD_DIR)/$(PKG_BRCMSMAC_FW_OBJECT) -+endif -+endef -diff --git a/package/kernel/mac80211/files/lib/netifd/wireless/mac80211.sh b/package/kernel/mac80211/files/lib/netifd/wireless/mac80211.sh -new file mode 100644 -index 0000000000..3b88af4679 ---- /dev/null -+++ b/package/kernel/mac80211/files/lib/netifd/wireless/mac80211.sh -@@ -0,0 +1,1219 @@ -+#!/bin/sh -+. /lib/netifd/netifd-wireless.sh -+. /lib/netifd/hostapd.sh -+. /lib/functions/system.sh -+ -+init_wireless_driver "$@" -+ -+MP_CONFIG_INT="mesh_retry_timeout mesh_confirm_timeout mesh_holding_timeout mesh_max_peer_links -+ mesh_max_retries mesh_ttl mesh_element_ttl mesh_hwmp_max_preq_retries -+ mesh_path_refresh_time mesh_min_discovery_timeout mesh_hwmp_active_path_timeout -+ mesh_hwmp_preq_min_interval mesh_hwmp_net_diameter_traversal_time mesh_hwmp_rootmode -+ mesh_hwmp_rann_interval mesh_gate_announcements mesh_sync_offset_max_neighor -+ mesh_rssi_threshold mesh_hwmp_active_path_to_root_timeout mesh_hwmp_root_interval -+ mesh_hwmp_confirmation_interval mesh_awake_window mesh_plink_timeout" -+MP_CONFIG_BOOL="mesh_auto_open_plinks mesh_fwding" -+MP_CONFIG_STRING="mesh_power_mode" -+ -+wdev_tool() { -+ ucode /usr/share/hostap/wdev.uc "$@" -+} -+ -+drv_mac80211_init_device_config() { -+ hostapd_common_add_device_config -+ -+ config_add_string path phy 'macaddr:macaddr' -+ config_add_string tx_burst -+ config_add_string distance -+ config_add_int beacon_int chanbw frag rts -+ config_add_int rxantenna txantenna txpower min_tx_power -+ config_add_boolean noscan ht_coex acs_exclude_dfs background_radar -+ config_add_array ht_capab -+ config_add_array channels -+ config_add_array scan_list -+ config_add_boolean \ -+ rxldpc \ -+ short_gi_80 \ -+ short_gi_160 \ -+ tx_stbc_2by1 \ -+ su_beamformer \ -+ su_beamformee \ -+ mu_beamformer \ -+ mu_beamformee \ -+ he_su_beamformer \ -+ he_su_beamformee \ -+ he_mu_beamformer \ -+ vht_txop_ps \ -+ htc_vht \ -+ rx_antenna_pattern \ -+ tx_antenna_pattern \ -+ he_spr_sr_control \ -+ he_spr_psr_enabled \ -+ he_bss_color_enabled \ -+ he_twt_required -+ config_add_int \ -+ beamformer_antennas \ -+ beamformee_antennas \ -+ vht_max_a_mpdu_len_exp \ -+ vht_max_mpdu \ -+ vht_link_adapt \ -+ vht160 \ -+ rx_stbc \ -+ tx_stbc \ -+ he_bss_color \ -+ he_spr_non_srg_obss_pd_max_offset -+ config_add_boolean \ -+ ldpc \ -+ greenfield \ -+ short_gi_20 \ -+ short_gi_40 \ -+ max_amsdu \ -+ dsss_cck_40 -+} -+ -+drv_mac80211_init_iface_config() { -+ hostapd_common_add_bss_config -+ -+ config_add_string 'macaddr:macaddr' ifname -+ -+ config_add_boolean wds powersave enable -+ config_add_string wds_bridge -+ config_add_int maxassoc -+ config_add_int max_listen_int -+ config_add_int dtim_period -+ config_add_int start_disabled -+ -+ # mesh -+ config_add_string mesh_id -+ config_add_int $MP_CONFIG_INT -+ config_add_boolean $MP_CONFIG_BOOL -+ config_add_string $MP_CONFIG_STRING -+} -+ -+mac80211_add_capabilities() { -+ local __var="$1"; shift -+ local __mask="$1"; shift -+ local __out= oifs -+ -+ oifs="$IFS" -+ IFS=: -+ for capab in "$@"; do -+ set -- $capab -+ -+ [ "$(($4))" -gt 0 ] || continue -+ [ "$(($__mask & $2))" -eq "$((${3:-$2}))" ] || continue -+ __out="$__out[$1]" -+ done -+ IFS="$oifs" -+ -+ export -n -- "$__var=$__out" -+} -+ -+mac80211_add_he_capabilities() { -+ local __out= oifs -+ -+ oifs="$IFS" -+ IFS=: -+ for capab in "$@"; do -+ set -- $capab -+ [ "$(($4))" -gt 0 ] || continue -+ [ "$(((0x$2) & $3))" -gt 0 ] || { -+ eval "$1=0" -+ continue -+ } -+ append base_cfg "$1=1" "$N" -+ done -+ IFS="$oifs" -+} -+ -+mac80211_hostapd_setup_base() { -+ local phy="$1" -+ -+ json_select config -+ -+ [ "$auto_channel" -gt 0 ] && channel=acs_survey -+ -+ [ "$auto_channel" -gt 0 ] && json_get_vars acs_exclude_dfs -+ [ -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_values ht_capab_list ht_capab -+ json_get_values channel_list channels -+ -+ [ "$auto_channel" = 0 ] && [ -z "$channel_list" ] && \ -+ channel_list="$channel" -+ -+ [ "$min_tx_power" -gt 0 ] && append base_cfg "min_tx_power=$min_tx_power" -+ -+ set_default noscan 0 -+ -+ [ "$noscan" -gt 0 ] && hostapd_noscan=1 -+ [ "$tx_burst" = 0 ] && tx_burst= -+ -+ chan_ofs=0 -+ [ "$band" = "6g" ] && chan_ofs=1 -+ -+ ieee80211n=1 -+ ht_capab= -+ case "$htmode" in -+ VHT20|HT20|HE20) ;; -+ HT40*|VHT40|VHT80|VHT160|HE40|HE80|HE160) -+ case "$hwmode" in -+ a) -+ case "$(( (($channel / 4) + $chan_ofs) % 2 ))" in -+ 1) ht_capab="[HT40+]";; -+ 0) ht_capab="[HT40-]";; -+ esac -+ ;; -+ *) -+ case "$htmode" in -+ HT40+) ht_capab="[HT40+]";; -+ HT40-) ht_capab="[HT40-]";; -+ *) -+ if [ "$channel" -lt 7 ]; then -+ ht_capab="[HT40+]" -+ else -+ ht_capab="[HT40-]" -+ fi -+ ;; -+ esac -+ ;; -+ esac -+ [ "$auto_channel" -gt 0 ] && ht_capab="[HT40+]" -+ ;; -+ *) ieee80211n= ;; -+ esac -+ -+ [ -n "$ieee80211n" ] && { -+ append base_cfg "ieee80211n=1" "$N" -+ -+ set_default ht_coex 0 -+ append base_cfg "ht_coex=$ht_coex" "$N" -+ -+ json_get_vars \ -+ ldpc:1 \ -+ greenfield:0 \ -+ short_gi_20:1 \ -+ short_gi_40:1 \ -+ tx_stbc:1 \ -+ rx_stbc:3 \ -+ max_amsdu:1 \ -+ dsss_cck_40:1 -+ -+ ht_cap_mask=0 -+ for cap in $(iw phy "$phy" info | grep 'Capabilities:' | cut -d: -f2); do -+ ht_cap_mask="$(($ht_cap_mask | $cap))" -+ done -+ -+ cap_rx_stbc=$((($ht_cap_mask >> 8) & 3)) -+ [ "$rx_stbc" -lt "$cap_rx_stbc" ] && cap_rx_stbc="$rx_stbc" -+ ht_cap_mask="$(( ($ht_cap_mask & ~(0x300)) | ($cap_rx_stbc << 8) ))" -+ -+ mac80211_add_capabilities ht_capab_flags $ht_cap_mask \ -+ LDPC:0x1::$ldpc \ -+ GF:0x10::$greenfield \ -+ SHORT-GI-20:0x20::$short_gi_20 \ -+ SHORT-GI-40:0x40::$short_gi_40 \ -+ TX-STBC:0x80::$tx_stbc \ -+ RX-STBC1:0x300:0x100:1 \ -+ RX-STBC12:0x300:0x200:1 \ -+ RX-STBC123:0x300:0x300:1 \ -+ MAX-AMSDU-7935:0x800::$max_amsdu \ -+ DSSS_CCK-40:0x1000::$dsss_cck_40 -+ -+ ht_capab="$ht_capab$ht_capab_flags" -+ [ -n "$ht_capab" ] && append base_cfg "ht_capab=$ht_capab" "$N" -+ } -+ -+ # 802.11ac -+ enable_ac=0 -+ vht_oper_chwidth=0 -+ vht_center_seg0= -+ -+ idx="$channel" -+ case "$htmode" in -+ VHT20|HE20) enable_ac=1;; -+ VHT40|HE40) -+ case "$(( (($channel / 4) + $chan_ofs) % 2 ))" in -+ 1) idx=$(($channel + 2));; -+ 0) idx=$(($channel - 2));; -+ esac -+ enable_ac=1 -+ vht_center_seg0=$idx -+ ;; -+ VHT80|HE80) -+ case "$(( (($channel / 4) + $chan_ofs) % 4 ))" in -+ 1) idx=$(($channel + 6));; -+ 2) idx=$(($channel + 2));; -+ 3) idx=$(($channel - 2));; -+ 0) idx=$(($channel - 6));; -+ esac -+ enable_ac=1 -+ vht_oper_chwidth=1 -+ vht_center_seg0=$idx -+ ;; -+ VHT160|HE160) -+ if [ "$band" = "6g" ]; then -+ case "$channel" in -+ 1|5|9|13|17|21|25|29) idx=15;; -+ 33|37|41|45|49|53|57|61) idx=47;; -+ 65|69|73|77|81|85|89|93) idx=79;; -+ 97|101|105|109|113|117|121|125) idx=111;; -+ 129|133|137|141|145|149|153|157) idx=143;; -+ 161|165|169|173|177|181|185|189) idx=175;; -+ 193|197|201|205|209|213|217|221) idx=207;; -+ esac -+ else -+ case "$channel" in -+ 36|40|44|48|52|56|60|64) idx=50;; -+ 100|104|108|112|116|120|124|128) idx=114;; -+ esac -+ fi -+ enable_ac=1 -+ vht_oper_chwidth=2 -+ vht_center_seg0=$idx -+ ;; -+ esac -+ [ "$band" = "5g" ] && { -+ json_get_vars background_radar:0 -+ -+ [ "$background_radar" -eq 1 ] && append base_cfg "enable_background_radar=1" "$N" -+ } -+ [ "$band" = "6g" ] && { -+ op_class= -+ case "$htmode" in -+ HE20) op_class=131;; -+ HE*) op_class=$((132 + $vht_oper_chwidth)) -+ esac -+ [ -n "$op_class" ] && append base_cfg "op_class=$op_class" "$N" -+ } -+ [ "$hwmode" = "a" ] || enable_ac=0 -+ -+ if [ "$enable_ac" != "0" ]; then -+ json_get_vars \ -+ rxldpc:1 \ -+ short_gi_80:1 \ -+ short_gi_160:1 \ -+ tx_stbc_2by1:1 \ -+ su_beamformer:1 \ -+ su_beamformee:1 \ -+ mu_beamformer:1 \ -+ mu_beamformee:1 \ -+ vht_txop_ps:1 \ -+ htc_vht:1 \ -+ beamformee_antennas:4 \ -+ beamformer_antennas:4 \ -+ rx_antenna_pattern:1 \ -+ tx_antenna_pattern:1 \ -+ vht_max_a_mpdu_len_exp:7 \ -+ vht_max_mpdu:11454 \ -+ rx_stbc:4 \ -+ vht_link_adapt:3 \ -+ vht160:2 -+ -+ set_default tx_burst 2.0 -+ append base_cfg "ieee80211ac=1" "$N" -+ vht_cap=0 -+ for cap in $(iw phy "$phy" info | awk -F "[()]" '/VHT Capabilities/ { print $2 }'); do -+ vht_cap="$(($vht_cap | $cap))" -+ done -+ -+ append base_cfg "vht_oper_chwidth=$vht_oper_chwidth" "$N" -+ append base_cfg "vht_oper_centr_freq_seg0_idx=$vht_center_seg0" "$N" -+ -+ cap_rx_stbc=$((($vht_cap >> 8) & 7)) -+ [ "$rx_stbc" -lt "$cap_rx_stbc" ] && cap_rx_stbc="$rx_stbc" -+ vht_cap="$(( ($vht_cap & ~(0x700)) | ($cap_rx_stbc << 8) ))" -+ -+ mac80211_add_capabilities vht_capab $vht_cap \ -+ RXLDPC:0x10::$rxldpc \ -+ SHORT-GI-80:0x20::$short_gi_80 \ -+ SHORT-GI-160:0x40::$short_gi_160 \ -+ TX-STBC-2BY1:0x80::$tx_stbc_2by1 \ -+ SU-BEAMFORMER:0x800::$su_beamformer \ -+ SU-BEAMFORMEE:0x1000::$su_beamformee \ -+ MU-BEAMFORMER:0x80000::$mu_beamformer \ -+ MU-BEAMFORMEE:0x100000::$mu_beamformee \ -+ VHT-TXOP-PS:0x200000::$vht_txop_ps \ -+ HTC-VHT:0x400000::$htc_vht \ -+ RX-ANTENNA-PATTERN:0x10000000::$rx_antenna_pattern \ -+ TX-ANTENNA-PATTERN:0x20000000::$tx_antenna_pattern \ -+ RX-STBC-1:0x700:0x100:1 \ -+ RX-STBC-12:0x700:0x200:1 \ -+ RX-STBC-123:0x700:0x300:1 \ -+ RX-STBC-1234:0x700:0x400:1 \ -+ -+ [ "$(($vht_cap & 0x800))" -gt 0 -a "$su_beamformer" -gt 0 ] && { -+ cap_ant="$(( ( ($vht_cap >> 16) & 3 ) + 1 ))" -+ [ "$cap_ant" -gt "$beamformer_antennas" ] && cap_ant="$beamformer_antennas" -+ [ "$cap_ant" -gt 1 ] && vht_capab="$vht_capab[SOUNDING-DIMENSION-$cap_ant]" -+ } -+ -+ [ "$(($vht_cap & 0x1000))" -gt 0 -a "$su_beamformee" -gt 0 ] && { -+ cap_ant="$(( ( ($vht_cap >> 13) & 3 ) + 1 ))" -+ [ "$cap_ant" -gt "$beamformee_antennas" ] && cap_ant="$beamformee_antennas" -+ [ "$cap_ant" -gt 1 ] && vht_capab="$vht_capab[BF-ANTENNA-$cap_ant]" -+ } -+ -+ # supported Channel widths -+ vht160_hw=0 -+ [ "$(($vht_cap & 12))" -eq 4 -a 1 -le "$vht160" ] && \ -+ vht160_hw=1 -+ [ "$(($vht_cap & 12))" -eq 8 -a 2 -le "$vht160" ] && \ -+ vht160_hw=2 -+ [ "$vht160_hw" = 1 ] && vht_capab="$vht_capab[VHT160]" -+ [ "$vht160_hw" = 2 ] && vht_capab="$vht_capab[VHT160-80PLUS80]" -+ -+ # maximum MPDU length -+ vht_max_mpdu_hw=3895 -+ [ "$(($vht_cap & 3))" -ge 1 -a 7991 -le "$vht_max_mpdu" ] && \ -+ vht_max_mpdu_hw=7991 -+ [ "$(($vht_cap & 3))" -ge 2 -a 11454 -le "$vht_max_mpdu" ] && \ -+ vht_max_mpdu_hw=11454 -+ [ "$vht_max_mpdu_hw" != 3895 ] && \ -+ vht_capab="$vht_capab[MAX-MPDU-$vht_max_mpdu_hw]" -+ -+ # maximum A-MPDU length exponent -+ vht_max_a_mpdu_len_exp_hw=0 -+ [ "$(($vht_cap & 58720256))" -ge 8388608 -a 1 -le "$vht_max_a_mpdu_len_exp" ] && \ -+ vht_max_a_mpdu_len_exp_hw=1 -+ [ "$(($vht_cap & 58720256))" -ge 16777216 -a 2 -le "$vht_max_a_mpdu_len_exp" ] && \ -+ vht_max_a_mpdu_len_exp_hw=2 -+ [ "$(($vht_cap & 58720256))" -ge 25165824 -a 3 -le "$vht_max_a_mpdu_len_exp" ] && \ -+ vht_max_a_mpdu_len_exp_hw=3 -+ [ "$(($vht_cap & 58720256))" -ge 33554432 -a 4 -le "$vht_max_a_mpdu_len_exp" ] && \ -+ vht_max_a_mpdu_len_exp_hw=4 -+ [ "$(($vht_cap & 58720256))" -ge 41943040 -a 5 -le "$vht_max_a_mpdu_len_exp" ] && \ -+ vht_max_a_mpdu_len_exp_hw=5 -+ [ "$(($vht_cap & 58720256))" -ge 50331648 -a 6 -le "$vht_max_a_mpdu_len_exp" ] && \ -+ vht_max_a_mpdu_len_exp_hw=6 -+ [ "$(($vht_cap & 58720256))" -ge 58720256 -a 7 -le "$vht_max_a_mpdu_len_exp" ] && \ -+ vht_max_a_mpdu_len_exp_hw=7 -+ vht_capab="$vht_capab[MAX-A-MPDU-LEN-EXP$vht_max_a_mpdu_len_exp_hw]" -+ -+ # whether or not the STA supports link adaptation using VHT variant -+ vht_link_adapt_hw=0 -+ [ "$(($vht_cap & 201326592))" -ge 134217728 -a 2 -le "$vht_link_adapt" ] && \ -+ vht_link_adapt_hw=2 -+ [ "$(($vht_cap & 201326592))" -ge 201326592 -a 3 -le "$vht_link_adapt" ] && \ -+ vht_link_adapt_hw=3 -+ [ "$vht_link_adapt_hw" != 0 ] && \ -+ vht_capab="$vht_capab[VHT-LINK-ADAPT-$vht_link_adapt_hw]" -+ -+ [ -n "$vht_capab" ] && append base_cfg "vht_capab=$vht_capab" "$N" -+ fi -+ -+ # 802.11ax -+ enable_ax=0 -+ case "$htmode" in -+ HE*) enable_ax=1 ;; -+ esac -+ -+ if [ "$enable_ax" != "0" ]; then -+ json_get_vars \ -+ he_su_beamformer:1 \ -+ he_su_beamformee:1 \ -+ he_mu_beamformer:1 \ -+ he_twt_required:0 \ -+ he_spr_sr_control:3 \ -+ he_spr_psr_enabled:0 \ -+ he_spr_non_srg_obss_pd_max_offset:0 \ -+ he_bss_color:128 \ -+ he_bss_color_enabled:1 -+ -+ he_phy_cap=$(iw phy "$phy" info | sed -n '/HE Iftypes: AP/,$p' | awk -F "[()]" '/HE PHY Capabilities/ { print $2 }' | head -1) -+ he_phy_cap=${he_phy_cap:2} -+ he_mac_cap=$(iw phy "$phy" info | sed -n '/HE Iftypes: AP/,$p' | awk -F "[()]" '/HE MAC Capabilities/ { print $2 }' | head -1) -+ he_mac_cap=${he_mac_cap:2} -+ -+ append base_cfg "ieee80211ax=1" "$N" -+ [ "$hwmode" = "a" ] && { -+ append base_cfg "he_oper_chwidth=$vht_oper_chwidth" "$N" -+ append base_cfg "he_oper_centr_freq_seg0_idx=$vht_center_seg0" "$N" -+ } -+ -+ mac80211_add_he_capabilities \ -+ he_su_beamformer:${he_phy_cap:6:2}:0x80:$he_su_beamformer \ -+ he_su_beamformee:${he_phy_cap:8:2}:0x1:$he_su_beamformee \ -+ he_mu_beamformer:${he_phy_cap:8:2}:0x2:$he_mu_beamformer \ -+ he_spr_psr_enabled:${he_phy_cap:14:2}:0x1:$he_spr_psr_enabled \ -+ he_twt_required:${he_mac_cap:0:2}:0x6:$he_twt_required -+ -+ if [ "$he_bss_color_enabled" -gt 0 ]; then -+ append base_cfg "he_bss_color=$he_bss_color" "$N" -+ [ "$he_spr_non_srg_obss_pd_max_offset" -gt 0 ] && { \ -+ append base_cfg "he_spr_non_srg_obss_pd_max_offset=$he_spr_non_srg_obss_pd_max_offset" "$N" -+ he_spr_sr_control=$((he_spr_sr_control | (1 << 2))) -+ } -+ [ "$he_spr_psr_enabled" -gt 0 ] || he_spr_sr_control=$((he_spr_sr_control | (1 << 0))) -+ append base_cfg "he_spr_sr_control=$he_spr_sr_control" "$N" -+ else -+ append base_cfg "he_bss_color_disabled=1" "$N" -+ fi -+ -+ -+ append base_cfg "he_default_pe_duration=4" "$N" -+ append base_cfg "he_rts_threshold=1023" "$N" -+ append base_cfg "he_mu_edca_qos_info_param_count=0" "$N" -+ append base_cfg "he_mu_edca_qos_info_q_ack=0" "$N" -+ append base_cfg "he_mu_edca_qos_info_queue_request=0" "$N" -+ append base_cfg "he_mu_edca_qos_info_txop_request=0" "$N" -+ append base_cfg "he_mu_edca_ac_be_aifsn=8" "$N" -+ append base_cfg "he_mu_edca_ac_be_aci=0" "$N" -+ append base_cfg "he_mu_edca_ac_be_ecwmin=9" "$N" -+ append base_cfg "he_mu_edca_ac_be_ecwmax=10" "$N" -+ append base_cfg "he_mu_edca_ac_be_timer=255" "$N" -+ append base_cfg "he_mu_edca_ac_bk_aifsn=15" "$N" -+ append base_cfg "he_mu_edca_ac_bk_aci=1" "$N" -+ append base_cfg "he_mu_edca_ac_bk_ecwmin=9" "$N" -+ append base_cfg "he_mu_edca_ac_bk_ecwmax=10" "$N" -+ append base_cfg "he_mu_edca_ac_bk_timer=255" "$N" -+ append base_cfg "he_mu_edca_ac_vi_ecwmin=5" "$N" -+ append base_cfg "he_mu_edca_ac_vi_ecwmax=7" "$N" -+ append base_cfg "he_mu_edca_ac_vi_aifsn=5" "$N" -+ append base_cfg "he_mu_edca_ac_vi_aci=2" "$N" -+ append base_cfg "he_mu_edca_ac_vi_timer=255" "$N" -+ append base_cfg "he_mu_edca_ac_vo_aifsn=5" "$N" -+ append base_cfg "he_mu_edca_ac_vo_aci=3" "$N" -+ append base_cfg "he_mu_edca_ac_vo_ecwmin=5" "$N" -+ append base_cfg "he_mu_edca_ac_vo_ecwmax=7" "$N" -+ append base_cfg "he_mu_edca_ac_vo_timer=255" "$N" -+ fi -+ -+ hostapd_prepare_device_config "$hostapd_conf_file" nl80211 -+ cat >> "$hostapd_conf_file" <> /var/run/hostapd-$phy.conf </dev/null); do -+ grep -i -q "$macaddr" "/sys/class/ieee80211/${phy}/macaddress" && { -+ path="$(iwinfo nl80211 path "$phy")" -+ rename_board_phy_by_path "$path" -+ return 0 -+ } -+ done -+ } -+ return 1 -+} -+ -+mac80211_check_ap() { -+ has_ap=1 -+} -+ -+mac80211_set_ifname() { -+ local phy="$1" -+ local prefix="$2" -+ eval "ifname=\"$phy-$prefix\${idx_$prefix:-0}\"; idx_$prefix=\$((\${idx_$prefix:-0 } + 1))" -+} -+ -+mac80211_prepare_vif() { -+ json_select config -+ -+ json_get_vars ifname mode ssid wds powersave macaddr enable wpa_psk_file vlan_file -+ -+ [ -n "$ifname" ] || { -+ local prefix; -+ -+ case "$mode" in -+ ap|sta|mesh) prefix=$mode;; -+ adhoc) prefix=ibss;; -+ monitor) prefix=mon;; -+ esac -+ -+ mac80211_set_ifname "$phy" "$prefix" -+ } -+ -+ append active_ifnames "$ifname" -+ set_default wds 0 -+ set_default powersave 0 -+ json_add_string _ifname "$ifname" -+ -+ if [ -z "$macaddr" ]; then -+ macaddr="$(mac80211_generate_mac $phy)" -+ macidx="$(($macidx + 1))" -+ elif [ "$macaddr" = 'random' ]; then -+ macaddr="$(macaddr_random)" -+ fi -+ json_add_string _macaddr "$macaddr" -+ json_select .. -+ -+ -+ [ "$mode" == "ap" ] && { -+ [ -z "$wpa_psk_file" ] && hostapd_set_psk "$ifname" -+ [ -z "$vlan_file" ] && hostapd_set_vlan "$ifname" -+ } -+ -+ json_select config -+ -+ # It is far easier to delete and create the desired interface -+ case "$mode" in -+ ap) -+ # Hostapd will handle recreating the interface and -+ # subsequent virtual APs belonging to the same PHY -+ if [ -n "$hostapd_ctrl" ]; then -+ type=bss -+ else -+ type=interface -+ fi -+ -+ mac80211_hostapd_setup_bss "$phy" "$ifname" "$macaddr" "$type" || return -+ -+ [ -n "$hostapd_ctrl" ] || { -+ ap_ifname="${ifname}" -+ hostapd_ctrl="${hostapd_ctrl:-/var/run/hostapd/$ifname}" -+ } -+ ;; -+ esac -+ -+ json_select .. -+} -+ -+mac80211_prepare_iw_htmode() { -+ case "$htmode" in -+ VHT20|HT20|HE20) iw_htmode=HT20;; -+ HT40*|VHT40|VHT160|HE40) -+ case "$band" in -+ 2g) -+ case "$htmode" in -+ HT40+) iw_htmode="HT40+";; -+ HT40-) iw_htmode="HT40-";; -+ *) -+ if [ "$channel" -lt 7 ]; then -+ iw_htmode="HT40+" -+ else -+ iw_htmode="HT40-" -+ fi -+ ;; -+ esac -+ ;; -+ *) -+ case "$(( ($channel / 4) % 2 ))" in -+ 1) iw_htmode="HT40+" ;; -+ 0) iw_htmode="HT40-";; -+ esac -+ ;; -+ esac -+ [ "$auto_channel" -gt 0 ] && iw_htmode="HT40+" -+ ;; -+ VHT80|HE80) -+ iw_htmode="80MHZ" -+ ;; -+ NONE|NOHT) -+ iw_htmode="NOHT" -+ ;; -+ *) iw_htmode="" ;; -+ esac -+} -+ -+mac80211_add_mesh_params() { -+ for var in $MP_CONFIG_INT $MP_CONFIG_BOOL $MP_CONFIG_STRING; do -+ eval "mp_val=\"\$$var\"" -+ [ -n "$mp_val" ] && json_add_string "$var" "$mp_val" -+ done -+} -+ -+mac80211_setup_adhoc() { -+ local enable=$1 -+ json_get_vars bssid ssid key mcast_rate -+ -+ NEWUMLIST="${NEWUMLIST}$ifname " -+ -+ [ "$enable" = 0 ] && { -+ ip link set dev "$ifname" down -+ return 0 -+ } -+ -+ keyspec= -+ [ "$auth_type" = "wep" ] && { -+ set_default key 1 -+ case "$key" in -+ [1234]) -+ local idx -+ for idx in 1 2 3 4; do -+ json_get_var ikey "key$idx" -+ -+ [ -n "$ikey" ] && { -+ ikey="$(($idx - 1)):$(prepare_key_wep "$ikey")" -+ [ $idx -eq $key ] && ikey="d:$ikey" -+ append keyspec "$ikey" -+ } -+ done -+ ;; -+ *) -+ append keyspec "d:0:$(prepare_key_wep "$key")" -+ ;; -+ esac -+ } -+ -+ brstr= -+ for br in $basic_rate_list; do -+ wpa_supplicant_add_rate brstr "$br" -+ done -+ -+ mcval= -+ [ -n "$mcast_rate" ] && wpa_supplicant_add_rate mcval "$mcast_rate" -+ -+ local prev -+ json_set_namespace wdev_uc prev -+ -+ json_add_object "$ifname" -+ json_add_string mode adhoc -+ json_add_string macaddr "$macaddr" -+ json_add_string ssid "$ssid" -+ json_add_string freq "$freq" -+ json_add_string htmode "$iw_htmode" -+ [ -n "$bssid" ] && json_add_string bssid "$bssid" -+ json_add_int beacon-interval "$beacon_int" -+ [ -n "$brstr" ] && json_add_string basic-rates "$brstr" -+ [ -n "$mcval" ] && json_add_string mcast-rate "$mcval" -+ [ -n "$keyspec" ] && json_add_string keys "$keyspec" -+ json_close_object -+ -+ json_set_namespace "$prev" -+} -+ -+mac80211_setup_mesh() { -+ json_get_vars ssid mesh_id mcast_rate -+ -+ mcval= -+ [ -n "$mcast_rate" ] && wpa_supplicant_add_rate mcval "$mcast_rate" -+ [ -n "$mesh_id" ] && ssid="$mesh_id" -+ -+ local prev -+ json_set_namespace wdev_uc prev -+ -+ json_add_object "$ifname" -+ json_add_string mode mesh -+ json_add_string macaddr "$macaddr" -+ json_add_string ssid "$ssid" -+ json_add_string freq "$freq" -+ json_add_string htmode "$iw_htmode" -+ [ -n "$mcval" ] && json_add_string mcast-rate "$mcval" -+ json_add_int beacon-interval "$beacon_int" -+ mac80211_add_mesh_params -+ -+ json_close_object -+ -+ json_set_namespace "$prev" -+} -+ -+mac80211_setup_monitor() { -+ local prev -+ json_set_namespace wdev_uc prev -+ -+ json_add_object "$ifname" -+ json_add_string mode monitor -+ [ -n "$freq" ] && json_add_string freq "$freq" -+ json_add_string htmode "$iw_htmode" -+ json_close_object -+ -+ json_set_namespace "$prev" -+} -+ -+mac80211_set_vif_txpower() { -+ local name="$1" -+ -+ json_select config -+ json_get_var ifname _ifname -+ json_get_vars vif_txpower -+ json_select .. -+ -+ [ -z "$vif_txpower" ] || iw dev "$ifname" set txpower fixed "${vif_txpower%%.*}00" -+} -+ -+wpa_supplicant_init_config() { -+ json_set_namespace wpa_supp prev -+ -+ json_init -+ json_add_array config -+ -+ json_set_namespace "$prev" -+} -+ -+wpa_supplicant_add_interface() { -+ local ifname="$1" -+ local mode="$2" -+ local prev -+ -+ _wpa_supplicant_common "$ifname" -+ -+ json_set_namespace wpa_supp prev -+ -+ json_add_object -+ json_add_string ctrl "$_rpath" -+ json_add_string iface "$ifname" -+ json_add_string mode "$mode" -+ json_add_string config "$_config" -+ json_add_string macaddr "$macaddr" -+ [ -n "$network_bridge" ] && json_add_string bridge "$network_bridge" -+ [ -n "$wds" ] && json_add_boolean 4addr "$wds" -+ json_add_boolean powersave "$powersave" -+ [ "$mode" = "mesh" ] && mac80211_add_mesh_params -+ json_close_object -+ -+ json_set_namespace "$prev" -+ -+ wpa_supp_init=1 -+} -+ -+wpa_supplicant_set_config() { -+ local phy="$1" -+ local prev -+ -+ json_set_namespace wpa_supp prev -+ json_close_array -+ json_add_string phy "$phy" -+ json_add_boolean defer 1 -+ local data="$(json_dump)" -+ -+ json_cleanup -+ json_set_namespace "$prev" -+ -+ ubus -S -t 0 wait_for wpa_supplicant || { -+ [ -n "$wpa_supp_init" ] || return 0 -+ -+ ubus wait_for wpa_supplicant -+ } -+ -+ local supplicant_res="$(ubus call wpa_supplicant config_set "$data")" -+ ret="$?" -+ [ "$ret" != 0 -o -z "$supplicant_res" ] && wireless_setup_vif_failed WPA_SUPPLICANT_FAILED -+ -+ wireless_add_process "$(jsonfilter -s "$supplicant_res" -l 1 -e @.pid)" "/usr/sbin/wpa_supplicant" 1 1 -+ -+} -+ -+hostapd_set_config() { -+ [ -n "$hostapd_ctrl" ] || { -+ ubus call hostapd config_set '{ "phy": "'"$phy"'", "config": "", "prev_config": "'"${hostapd_conf_file}.prev"'" }' > /dev/null -+ return 0; -+ } -+ -+ ubus wait_for hostapd -+ local hostapd_res="$(ubus call hostapd config_set "{ \"phy\": \"$phy\", \"config\":\"${hostapd_conf_file}\", \"prev_config\": \"${hostapd_conf_file}.prev\"}")" -+ ret="$?" -+ [ "$ret" != 0 -o -z "$hostapd_res" ] && { -+ wireless_setup_failed HOSTAPD_START_FAILED -+ return -+ } -+ wireless_add_process "$(jsonfilter -s "$hostapd_res" -l 1 -e @.pid)" "/usr/sbin/hostapd" 1 1 -+} -+ -+ -+wpa_supplicant_start() { -+ local phy="$1" -+ -+ [ -n "$wpa_supp_init" ] || return 0 -+ -+ ubus call wpa_supplicant config_set '{ "phy": "'"$phy"'" }' > /dev/null -+} -+ -+mac80211_setup_supplicant() { -+ local enable=$1 -+ local add_sp=0 -+ -+ wpa_supplicant_prepare_interface "$ifname" nl80211 || return 1 -+ -+ if [ "$mode" = "sta" ]; then -+ wpa_supplicant_add_network "$ifname" -+ else -+ wpa_supplicant_add_network "$ifname" "$freq" "$htmode" "$noscan" -+ fi -+ -+ wpa_supplicant_add_interface "$ifname" "$mode" -+ -+ return 0 -+} -+ -+mac80211_setup_vif() { -+ local name="$1" -+ local failed -+ -+ json_select config -+ json_get_var ifname _ifname -+ json_get_var macaddr _macaddr -+ json_get_vars mode wds powersave -+ -+ set_default powersave 0 -+ set_default wds 0 -+ -+ case "$mode" in -+ mesh) -+ json_get_vars $MP_CONFIG_INT $MP_CONFIG_BOOL $MP_CONFIG_STRING -+ wireless_vif_parse_encryption -+ [ -z "$htmode" ] && htmode="NOHT"; -+ if wpa_supplicant -vmesh; then -+ mac80211_setup_supplicant || failed=1 -+ else -+ mac80211_setup_mesh -+ fi -+ ;; -+ adhoc) -+ wireless_vif_parse_encryption -+ if [ "$wpa" -gt 0 -o "$auto_channel" -gt 0 ]; then -+ mac80211_setup_supplicant || failed=1 -+ else -+ mac80211_setup_adhoc -+ fi -+ ;; -+ sta) -+ mac80211_setup_supplicant || failed=1 -+ ;; -+ monitor) -+ mac80211_setup_monitor -+ ;; -+ esac -+ -+ json_select .. -+ [ -n "$failed" ] || wireless_add_vif "$name" "$ifname" -+} -+ -+get_freq() { -+ local phy="$1" -+ local channel="$2" -+ local band="$3" -+ -+ case "$band" in -+ 2g) band="1:";; -+ 5g) band="2:";; -+ 60g) band="3:";; -+ 6g) band="4:";; -+ esac -+ -+ iw "$phy" info | awk -v band="$band" -v channel="[$channel]" ' -+ -+$1 ~ /Band/ { -+ band_match = band == $2 -+} -+ -+band_match && $3 == "MHz" && $4 == channel { -+ print $2 -+ exit -+} -+' -+} -+ -+chan_is_dfs() { -+ local phy="$1" -+ local chan="$2" -+ iw "$phy" info | grep -E -m1 "(\* ${chan:-....} MHz${chan:+|\\[$chan\\]})" | grep -q "MHz.*radar detection" -+ return $! -+} -+ -+mac80211_set_noscan() { -+ hostapd_noscan=1 -+} -+ -+drv_mac80211_cleanup() { -+ hostapd_common_cleanup -+} -+ -+mac80211_reset_config() { -+ local phy="$1" -+ -+ hostapd_conf_file="/var/run/hostapd-$phy.conf" -+ ubus call hostapd config_set '{ "phy": "'"$phy"'", "config": "", "prev_config": "'"$hostapd_conf_file"'" }' > /dev/null -+ ubus call wpa_supplicant config_set '{ "phy": "'"$phy"'", "config": [] }' > /dev/null -+ wdev_tool "$phy" '{}' -+} -+ -+drv_mac80211_setup() { -+ json_select config -+ json_get_vars \ -+ phy macaddr path \ -+ country chanbw distance \ -+ txpower \ -+ rxantenna txantenna \ -+ frag rts beacon_int:100 htmode -+ json_get_values basic_rate_list basic_rate -+ json_get_values scan_list scan_list -+ json_select .. -+ -+ json_select data && { -+ json_get_var prev_rxantenna rxantenna -+ json_get_var prev_txantenna txantenna -+ json_select .. -+ } -+ -+ find_phy || { -+ echo "Could not find PHY for device '$1'" -+ wireless_set_retry 0 -+ return 1 -+ } -+ -+ local wdev -+ local cwdev -+ local found -+ -+ # convert channel to frequency -+ [ "$auto_channel" -gt 0 ] || freq="$(get_freq "$phy" "$channel" "$band")" -+ -+ [ -n "$country" ] && { -+ iw reg get | grep -q "^country $country:" || { -+ iw reg set "$country" -+ sleep 1 -+ } -+ } -+ -+ hostapd_conf_file="/var/run/hostapd-$phy.conf" -+ -+ macidx=0 -+ staidx=0 -+ -+ [ -n "$chanbw" ] && { -+ for file in /sys/kernel/debug/ieee80211/$phy/ath9k*/chanbw /sys/kernel/debug/ieee80211/$phy/ath5k/bwmode; do -+ [ -f "$file" ] && echo "$chanbw" > "$file" -+ done -+ } -+ -+ set_default rxantenna 0xffffffff -+ set_default txantenna 0xffffffff -+ set_default distance 0 -+ -+ [ "$txantenna" = "all" ] && txantenna=0xffffffff -+ [ "$rxantenna" = "all" ] && rxantenna=0xffffffff -+ -+ [ "$rxantenna" = "$prev_rxantenna" -a "$txantenna" = "$prev_txantenna" ] || mac80211_reset_config "$phy" -+ wireless_set_data phy="$phy" txantenna="$txantenna" rxantenna="$rxantenna" -+ -+ iw phy "$phy" set antenna $txantenna $rxantenna >/dev/null 2>&1 -+ iw phy "$phy" set distance "$distance" >/dev/null 2>&1 -+ -+ if [ -n "$txpower" ]; then -+ iw phy "$phy" set txpower fixed "${txpower%%.*}00" -+ else -+ iw phy "$phy" set txpower auto -+ fi -+ -+ [ -n "$frag" ] && iw phy "$phy" set frag "${frag%%.*}" -+ [ -n "$rts" ] && iw phy "$phy" set rts "${rts%%.*}" -+ -+ has_ap= -+ hostapd_ctrl= -+ ap_ifname= -+ hostapd_noscan= -+ wpa_supp_init= -+ for_each_interface "ap" mac80211_check_ap -+ -+ [ -f "$hostapd_conf_file" ] && mv "$hostapd_conf_file" "$hostapd_conf_file.prev" -+ -+ for_each_interface "sta adhoc mesh" mac80211_set_noscan -+ [ -n "$has_ap" ] && mac80211_hostapd_setup_base "$phy" -+ -+ local prev -+ json_set_namespace wdev_uc prev -+ json_init -+ json_set_namespace "$prev" -+ -+ wpa_supplicant_init_config -+ -+ mac80211_prepare_iw_htmode -+ active_ifnames= -+ for_each_interface "ap sta adhoc mesh monitor" mac80211_prepare_vif -+ for_each_interface "ap sta adhoc mesh monitor" mac80211_setup_vif -+ -+ [ -x /usr/sbin/wpa_supplicant ] && wpa_supplicant_set_config "$phy" -+ [ -x /usr/sbin/hostapd ] && hostapd_set_config "$phy" -+ -+ [ -x /usr/sbin/wpa_supplicant ] && wpa_supplicant_start "$phy" -+ -+ json_set_namespace wdev_uc prev -+ wdev_tool "$phy" "$(json_dump)" $active_ifnames -+ json_set_namespace "$prev" -+ -+ for_each_interface "ap sta adhoc mesh monitor" mac80211_set_vif_txpower -+ wireless_set_up -+} -+ -+_list_phy_interfaces() { -+ local phy="$1" -+ if [ -d "/sys/class/ieee80211/${phy}/device/net" ]; then -+ ls "/sys/class/ieee80211/${phy}/device/net" 2>/dev/null; -+ else -+ ls "/sys/class/ieee80211/${phy}/device" 2>/dev/null | grep net: | sed -e 's,net:,,g' -+ fi -+} -+ -+list_phy_interfaces() { -+ local phy="$1" -+ -+ for dev in $(_list_phy_interfaces "$phy"); do -+ readlink "/sys/class/net/${dev}/phy80211" | grep -q "/${phy}\$" || continue -+ echo "$dev" -+ done -+} -+ -+drv_mac80211_teardown() { -+ json_select data -+ json_get_vars phy -+ json_select .. -+ [ -n "$phy" ] || { -+ echo "Bug: PHY is undefined for device '$1'" -+ return 1 -+ } -+ -+ mac80211_reset_config "$phy" -+ -+ for wdev in $(list_phy_interfaces "$phy"); do -+ ip link set dev "$wdev" down -+ iw dev "$wdev" del -+ done -+} -+ -+add_driver mac80211 -diff --git a/package/kernel/mac80211/files/lib/wifi/mac80211.sh b/package/kernel/mac80211/files/lib/wifi/mac80211.sh -new file mode 100644 -index 0000000000..e24a2a634e ---- /dev/null -+++ b/package/kernel/mac80211/files/lib/wifi/mac80211.sh -@@ -0,0 +1,217 @@ -+#!/bin/sh -+ -+append DRIVERS "mac80211" -+ -+check_mac80211_device() { -+ local device="$1" -+ local path="$2" -+ local macaddr="$3" -+ -+ [ -n "$found" ] && return 0 -+ -+ phy_path= -+ config_get phy "$device" phy -+ json_select wlan -+ [ -n "$phy" ] && case "$phy" in -+ phy*) -+ [ -d /sys/class/ieee80211/$phy ] && \ -+ phy_path="$(iwinfo nl80211 path "$dev")" -+ ;; -+ *) -+ if json_is_a "$phy" object; then -+ json_select "$phy" -+ json_get_var phy_path path -+ json_select .. -+ elif json_is_a "${phy%.*}" object; then -+ json_select "${phy%.*}" -+ json_get_var phy_path path -+ json_select .. -+ phy_path="$phy_path+${phy##*.}" -+ fi -+ ;; -+ esac -+ json_select .. -+ [ -n "$phy_path" ] || config_get phy_path "$device" path -+ [ -n "$path" -a "$phy_path" = "$path" ] && { -+ found=1 -+ return 0 -+ } -+ -+ config_get dev_macaddr "$device" macaddr -+ -+ [ -n "$macaddr" -a "$dev_macaddr" = "$macaddr" ] && found=1 -+ -+ return 0 -+} -+ -+ -+__get_band_defaults() { -+ local phy="$1" -+ -+ ( iw phy "$phy" info; echo ) | awk ' -+BEGIN { -+ bands = "" -+} -+ -+($1 == "Band" || $1 == "") && band { -+ if (channel) { -+ mode="NOHT" -+ if (ht) mode="HT20" -+ if (vht && band != "1:") mode="VHT80" -+ if (he) mode="HE80" -+ if (he && band == "1:") mode="HE20" -+ sub("\\[", "", channel) -+ sub("\\]", "", channel) -+ bands = bands band channel ":" mode " " -+ } -+ band="" -+} -+ -+$1 == "Band" { -+ band = $2 -+ channel = "" -+ vht = "" -+ ht = "" -+ he = "" -+} -+ -+$0 ~ "Capabilities:" { -+ ht=1 -+} -+ -+$0 ~ "VHT Capabilities" { -+ vht=1 -+} -+ -+$0 ~ "HE Iftypes" { -+ he=1 -+} -+ -+$1 == "*" && $3 == "MHz" && $0 !~ /disabled/ && band && !channel { -+ channel = $4 -+} -+ -+END { -+ print bands -+}' -+} -+ -+get_band_defaults() { -+ local phy="$1" -+ -+ for c in $(__get_band_defaults "$phy"); do -+ local band="${c%%:*}" -+ c="${c#*:}" -+ local chan="${c%%:*}" -+ c="${c#*:}" -+ local mode="${c%%:*}" -+ -+ case "$band" in -+ 1) band=2g;; -+ 2) band=5g;; -+ 3) band=60g;; -+ 4) band=6g;; -+ *) band="";; -+ esac -+ -+ [ -n "$band" ] || continue -+ [ -n "$mode_band" -a "$band" = "6g" ] && return -+ -+ mode_band="$band" -+ channel="$chan" -+ htmode="$mode" -+ done -+} -+ -+check_devidx() { -+ case "$1" in -+ radio[0-9]*) -+ local idx="${1#radio}" -+ [ "$devidx" -ge "${1#radio}" ] && devidx=$((idx + 1)) -+ ;; -+ esac -+} -+ -+check_board_phy() { -+ local name="$2" -+ -+ json_select "$name" -+ json_get_var phy_path path -+ json_select .. -+ -+ if [ "$path" = "$phy_path" ]; then -+ board_dev="$name" -+ elif [ "${path%+*}" = "$phy_path" ]; then -+ fallback_board_dev="$name.${path#*+}" -+ fi -+} -+ -+detect_mac80211() { -+ devidx=0 -+ config_load wireless -+ config_foreach check_devidx wifi-device -+ -+ json_load_file /etc/board.json -+ -+ for _dev in /sys/class/ieee80211/*; do -+ [ -e "$_dev" ] || continue -+ -+ dev="${_dev##*/}" -+ -+ mode_band="" -+ channel="" -+ htmode="" -+ ht_capab="" -+ -+ get_band_defaults "$dev" -+ -+ path="$(iwinfo nl80211 path "$dev")" -+ macaddr="$(cat /sys/class/ieee80211/${dev}/macaddress)" -+ -+ # work around phy rename related race condition -+ [ -n "$path" -o -n "$macaddr" ] || continue -+ -+ board_dev= -+ fallback_board_dev= -+ json_for_each_item check_board_phy wlan -+ [ -n "$board_dev" ] || board_dev="$fallback_board_dev" -+ [ -n "$board_dev" ] && dev="$board_dev" -+ -+ found= -+ config_foreach check_mac80211_device wifi-device "$path" "$macaddr" -+ [ -n "$found" ] && continue -+ -+ name="radio${devidx}" -+ devidx=$(($devidx + 1)) -+ case "$dev" in -+ phy*) -+ if [ -n "$path" ]; then -+ dev_id="set wireless.${name}.path='$path'" -+ else -+ dev_id="set wireless.${name}.macaddr='$macaddr'" -+ fi -+ ;; -+ *) -+ dev_id="set wireless.${name}.phy='$dev'" -+ ;; -+ esac -+ -+ uci -q batch <<-EOF -+ set wireless.${name}=wifi-device -+ set wireless.${name}.type=mac80211 -+ ${dev_id} -+ set wireless.${name}.channel=${channel} -+ set wireless.${name}.band=${mode_band} -+ set wireless.${name}.htmode=$htmode -+ set wireless.${name}.disabled=1 -+ -+ set wireless.default_${name}=wifi-iface -+ set wireless.default_${name}.device=${name} -+ set wireless.default_${name}.network=lan -+ set wireless.default_${name}.mode=ap -+ set wireless.default_${name}.ssid=OpenWrt -+ set wireless.default_${name}.encryption=none -+EOF -+ uci -q commit wireless -+ done -+} -diff --git a/package/kernel/mac80211/files/mac80211.hotplug b/package/kernel/mac80211/files/mac80211.hotplug -new file mode 100644 -index 0000000000..b865552661 ---- /dev/null -+++ b/package/kernel/mac80211/files/mac80211.hotplug -@@ -0,0 +1,5 @@ -+#!/bin/sh -+ -+[ "${ACTION}" = "add" ] && { -+ /sbin/wifi config -+} -diff --git a/package/kernel/mac80211/intel.mk b/package/kernel/mac80211/intel.mk -new file mode 100644 -index 0000000000..8d374d73e7 ---- /dev/null -+++ b/package/kernel/mac80211/intel.mk -@@ -0,0 +1,77 @@ -+PKG_DRIVERS += iwlwifi -+ -+config-$(call config_package,iwlwifi) += IWLWIFI IWLDVM IWLMVM -+config-$(CONFIG_PACKAGE_IWLWIFI_DEBUG)+= IWLWIFI_DEBUG -+config-$(CONFIG_PACKAGE_IWLWIFI_DEBUGFS)+= IWLWIFI_DEBUGFS -+ -+define KernelPackage/iwlwifi -+ $(call KernelPackage/mac80211/Default) -+ DEPENDS:= +kmod-mac80211 @PCI_SUPPORT +@DRIVER_11AC_SUPPORT +@DRIVER_11AX_SUPPORT -+ TITLE:=Intel AGN Wireless support -+ FILES:= \ -+ $(PKG_BUILD_DIR)/drivers/net/wireless/intel/iwlwifi/iwlwifi.ko \ -+ $(PKG_BUILD_DIR)/drivers/net/wireless/intel/iwlwifi/dvm/iwldvm.ko \ -+ $(PKG_BUILD_DIR)/drivers/net/wireless/intel/iwlwifi/mvm/iwlmvm.ko -+ AUTOLOAD:=$(call AutoProbe,iwlwifi iwldvm iwlmvm) -+ MENU:=1 -+endef -+ -+define KernelPackage/iwlwifi/description -+ iwlwifi kernel module for -+ Intel Wireless WiFi Link 6250AGN Adapter -+ Intel 6000 Series Wi-Fi Adapters (6200AGN and 6300AGN) -+ Intel WiFi Link 1000BGN -+ Intel Wireless WiFi 5150AGN -+ Intel Wireless WiFi 5100AGN, 5300AGN, and 5350AGN -+ Intel 6005 Series Wi-Fi Adapters -+ Intel 6030 Series Wi-Fi Adapters -+ Intel Wireless WiFi Link 6150BGN 2 Adapter -+ Intel 100 Series Wi-Fi Adapters (100BGN and 130BGN) -+ Intel 2000 Series Wi-Fi Adapters -+ Intel 7260 Wi-Fi Adapter -+ Intel 3160 Wi-Fi Adapter -+ Intel 7265 Wi-Fi Adapter -+ Intel 8260 Wi-Fi Adapter -+ Intel 3165 Wi-Fi Adapter -+endef -+ -+define KernelPackage/iwlwifi/config -+ if PACKAGE_kmod-iwlwifi -+ -+ config PACKAGE_IWLWIFI_DEBUG -+ bool "Enable full debugging output in the iwlwifi driver" -+ default n -+ help -+ This option will enable debug tracing output for the iwlwifi drivers -+ -+ This will result in the kernel module being ~100k larger. You can -+ control which debug output is sent to the kernel log by setting the -+ value in -+ -+ /sys/module/iwlwifi/parameters/debug -+ -+ This entry will only exist if this option is enabled. -+ -+ To set a value, simply echo an 8-byte hex value to the same file: -+ -+ % echo 0x43fff > /sys/module/iwlwifi/parameters/debug -+ -+ You can find the list of debug mask values in: -+ drivers/net/wireless/intel/iwlwifi/iwl-debug.h -+ -+ If this is your first time using this driver, you should say Y here -+ as the debug information can assist others in helping you resolve -+ any problems you may encounter. -+ -+ config PACKAGE_IWLWIFI_DEBUGFS -+ bool "iwlwifi debugfs support" -+ depends on PACKAGE_MAC80211_DEBUGFS -+ default n -+ help -+ Enable creation of debugfs files for the iwlwifi drivers. This -+ is a low-impact option that allows getting insight into the -+ driver's state at runtime. -+ -+ endif -+endef -+ -diff --git a/package/kernel/mac80211/marvell.mk b/package/kernel/mac80211/marvell.mk -new file mode 100644 -index 0000000000..dbd07a80da ---- /dev/null -+++ b/package/kernel/mac80211/marvell.mk -@@ -0,0 +1,51 @@ -+PKG_DRIVERS += \ -+ mwl8k mwifiex-pcie mwifiex-sdio -+ -+config-$(call config_package,mwl8k) += MWL8K -+config-$(call config_package,mwifiex-pcie) += MWIFIEX MWIFIEX_PCIE -+config-$(call config_package,mwifiex-sdio) += MWIFIEX MWIFIEX_SDIO -+ -+define KernelPackage/mwl8k -+ $(call KernelPackage/mac80211/Default) -+ TITLE:=Driver for Marvell TOPDOG 802.11 Wireless cards -+ URL:=https://wireless.wiki.kernel.org/en/users/drivers/mwl8k -+ DEPENDS+= @PCI_SUPPORT +kmod-mac80211 +mwl8k-firmware -+ FILES:=$(PKG_BUILD_DIR)/drivers/net/wireless/marvell/mwl8k.ko -+ AUTOLOAD:=$(call AutoProbe,mwl8k) -+endef -+ -+define KernelPackage/mwl8k/description -+ Kernel modules for Marvell TOPDOG 802.11 Wireless cards -+endef -+ -+ -+define KernelPackage/mwifiex-pcie -+ $(call KernelPackage/mac80211/Default) -+ TITLE:=Driver for Marvell 802.11n/802.11ac PCIe Wireless cards -+ URL:=https://wireless.wiki.kernel.org/en/users/drivers/mwifiex -+ DEPENDS+= @PCI_SUPPORT +kmod-mac80211 +@DRIVER_11AC_SUPPORT +mwifiex-pcie-firmware -+ FILES:= \ -+ $(PKG_BUILD_DIR)/drivers/net/wireless/marvell/mwifiex/mwifiex.ko \ -+ $(PKG_BUILD_DIR)/drivers/net/wireless/marvell/mwifiex/mwifiex_pcie.ko -+ AUTOLOAD:=$(call AutoProbe,mwifiex_pcie) -+endef -+ -+define KernelPackage/mwifiex-pcie/description -+ Kernel modules for Marvell 802.11n/802.11ac PCIe Wireless cards -+endef -+ -+define KernelPackage/mwifiex-sdio -+ $(call KernelPackage/mac80211/Default) -+ TITLE:=Driver for Marvell 802.11n/802.11ac SDIO Wireless cards -+ URL:=https://wireless.wiki.kernel.org/en/users/drivers/mwifiex -+ DEPENDS+= +kmod-mmc +kmod-mac80211 +@DRIVER_11AC_SUPPORT +mwifiex-sdio-firmware -+ FILES:= \ -+ $(PKG_BUILD_DIR)/drivers/net/wireless/marvell/mwifiex/mwifiex.ko \ -+ $(PKG_BUILD_DIR)/drivers/net/wireless/marvell/mwifiex/mwifiex_sdio.ko -+ AUTOLOAD:=$(call AutoProbe,mwifiex_sdio) -+endef -+ -+define KernelPackage/mwifiex-sdio/description -+ Kernel modules for Marvell 802.11n/802.11ac SDIO Wireless cards -+endef -+ -diff --git a/package/kernel/mac80211/patches/ath/070-ath_common_config.patch b/package/kernel/mac80211/patches/ath/070-ath_common_config.patch -new file mode 100644 -index 0000000000..3d0b4d6b1a ---- /dev/null -+++ b/package/kernel/mac80211/patches/ath/070-ath_common_config.patch -@@ -0,0 +1,10 @@ -+--- a/drivers/net/wireless/ath/Kconfig -++++ b/drivers/net/wireless/ath/Kconfig -+@@ -1,6 +1,6 @@ -+ # SPDX-License-Identifier: ISC -+ config ATH_COMMON -+- tristate -++ tristate "ath.ko" -+ depends on m -+ -+ config WLAN_VENDOR_ATH -diff --git a/package/kernel/mac80211/patches/ath/400-ath_move_debug_code.patch b/package/kernel/mac80211/patches/ath/400-ath_move_debug_code.patch -new file mode 100644 -index 0000000000..eacc72776e ---- /dev/null -+++ b/package/kernel/mac80211/patches/ath/400-ath_move_debug_code.patch -@@ -0,0 +1,31 @@ -+--- a/drivers/net/wireless/ath/Makefile -++++ b/drivers/net/wireless/ath/Makefile -+@@ -15,10 +15,10 @@ ath-objs := main.o \ -+ regd.o \ -+ hw.o \ -+ key.o \ -++ debug.o \ -+ dfs_pattern_detector.o \ -+ dfs_pri_detector.o -+ -+-ath-$(CPTCFG_ATH_DEBUG) += debug.o -+ ath-$(CPTCFG_ATH_TRACEPOINTS) += trace.o -+ -+ CFLAGS_trace.o := -I$(src) -+--- a/drivers/net/wireless/ath/ath.h -++++ b/drivers/net/wireless/ath/ath.h -+@@ -317,14 +317,7 @@ void _ath_dbg(struct ath_common *common, -+ #endif /* CPTCFG_ATH_DEBUG */ -+ -+ /** Returns string describing opmode, or NULL if unknown mode. */ -+-#ifdef CPTCFG_ATH_DEBUG -+ const char *ath_opmode_to_string(enum nl80211_iftype opmode); -+-#else -+-static inline const char *ath_opmode_to_string(enum nl80211_iftype opmode) -+-{ -+- return "UNKNOWN"; -+-} -+-#endif -+ -+ extern const char *ath_bus_type_strings[]; -+ static inline const char *ath_bus_type_to_string(enum ath_bus_type bustype) -diff --git a/package/kernel/mac80211/patches/ath/402-ath_regd_optional.patch b/package/kernel/mac80211/patches/ath/402-ath_regd_optional.patch -new file mode 100644 -index 0000000000..fd5493de71 ---- /dev/null -+++ b/package/kernel/mac80211/patches/ath/402-ath_regd_optional.patch -@@ -0,0 +1,92 @@ -+--- a/drivers/net/wireless/ath/regd.c -++++ b/drivers/net/wireless/ath/regd.c -+@@ -24,6 +24,7 @@ -+ #include "regd_common.h" -+ -+ static int __ath_regd_init(struct ath_regulatory *reg); -++static struct reg_dmn_pair_mapping *ath_get_regpair(int regdmn); -+ -+ /* -+ * This is a set of common rules used by our world regulatory domains. -+@@ -116,6 +117,9 @@ static const struct ieee80211_regdomain -+ -+ static bool dynamic_country_user_possible(struct ath_regulatory *reg) -+ { -++ if (IS_ENABLED(CPTCFG_ATH_USER_REGD)) -++ return true; -++ -+ if (IS_ENABLED(CPTCFG_ATH_REG_DYNAMIC_USER_CERT_TESTING)) -+ return true; -+ -+@@ -188,6 +192,8 @@ static bool dynamic_country_user_possibl -+ -+ static bool ath_reg_dyn_country_user_allow(struct ath_regulatory *reg) -+ { -++ if (IS_ENABLED(CPTCFG_ATH_USER_REGD)) -++ return true; -+ if (!IS_ENABLED(CPTCFG_ATH_REG_DYNAMIC_USER_REG_HINTS)) -+ return false; -+ if (!dynamic_country_user_possible(reg)) -+@@ -345,6 +351,9 @@ ath_reg_apply_beaconing_flags(struct wip -+ struct ieee80211_channel *ch; -+ unsigned int i; -+ -++ if (IS_ENABLED(CPTCFG_ATH_USER_REGD)) -++ return; -++ -+ for (band = 0; band < NUM_NL80211_BANDS; band++) { -+ if (!wiphy->bands[band]) -+ continue; -+@@ -379,6 +388,9 @@ ath_reg_apply_ir_flags(struct wiphy *wip -+ { -+ struct ieee80211_supported_band *sband; -+ -++ if (IS_ENABLED(CPTCFG_ATH_USER_REGD)) -++ return; -++ -+ sband = wiphy->bands[NL80211_BAND_2GHZ]; -+ if (!sband) -+ return; -+@@ -408,6 +420,9 @@ static void ath_reg_apply_radar_flags(st -+ struct ieee80211_channel *ch; -+ unsigned int i; -+ -++ if (IS_ENABLED(CPTCFG_ATH_USER_REGD)) -++ return; -++ -+ if (!wiphy->bands[NL80211_BAND_5GHZ]) -+ return; -+ -+@@ -640,6 +655,10 @@ ath_regd_init_wiphy(struct ath_regulator -+ const struct ieee80211_regdomain *regd; -+ -+ wiphy->reg_notifier = reg_notifier; -++ -++ if (IS_ENABLED(CPTCFG_ATH_USER_REGD)) -++ return 0; -++ -+ wiphy->regulatory_flags |= REGULATORY_STRICT_REG | -+ REGULATORY_CUSTOM_REG; -+ -+--- a/drivers/net/wireless/ath/Kconfig -++++ b/drivers/net/wireless/ath/Kconfig -+@@ -24,6 +24,9 @@ config WLAN_VENDOR_ATH -+ -+ if WLAN_VENDOR_ATH -+ -++config ATH_USER_REGD -++ bool "Do not enforce EEPROM regulatory restrictions" -++ -+ config ATH_DEBUG -+ bool "Atheros wireless debugging" -+ help -+--- a/local-symbols -++++ b/local-symbols -+@@ -102,6 +102,7 @@ ADM8211= -+ ATH_COMMON= -+ WLAN_VENDOR_ATH= -+ ATH_DEBUG= -++ATH_USER_REGD= -+ ATH_TRACEPOINTS= -+ ATH_REG_DYNAMIC_USER_REG_HINTS= -+ ATH_REG_DYNAMIC_USER_CERT_TESTING= -diff --git a/package/kernel/mac80211/patches/ath/403-world_regd_fixup.patch b/package/kernel/mac80211/patches/ath/403-world_regd_fixup.patch -new file mode 100644 -index 0000000000..ed616b7532 ---- /dev/null -+++ b/package/kernel/mac80211/patches/ath/403-world_regd_fixup.patch -@@ -0,0 +1,84 @@ -+--- a/drivers/net/wireless/ath/regd.c -++++ b/drivers/net/wireless/ath/regd.c -+@@ -44,7 +44,8 @@ static struct reg_dmn_pair_mapping *ath_ -+ NL80211_RRF_NO_OFDM) -+ -+ /* We allow IBSS on these on a case by case basis by regulatory domain */ -+-#define ATH_5GHZ_5150_5350 REG_RULE(5150-10, 5350+10, 80, 0, 30,\ -++#define ATH_5GHZ_5150_5350 REG_RULE(5150-10, 5240+10, 80, 0, 30, 0),\ -++ REG_RULE(5260-10, 5350+10, 80, 0, 30,\ -+ NL80211_RRF_NO_IR) -+ #define ATH_5GHZ_5470_5850 REG_RULE(5470-10, 5850+10, 80, 0, 30,\ -+ NL80211_RRF_NO_IR) -+@@ -62,57 +63,56 @@ static struct reg_dmn_pair_mapping *ath_ -+ #define ATH_5GHZ_NO_MIDBAND ATH_5GHZ_5150_5350, \ -+ ATH_5GHZ_5725_5850 -+ -++#define REGD_RULES(...) \ -++ .reg_rules = { __VA_ARGS__ }, \ -++ .n_reg_rules = ARRAY_SIZE(((struct ieee80211_reg_rule[]) { __VA_ARGS__ })) -++ -+ /* Can be used for: -+ * 0x60, 0x61, 0x62 */ -+ static const struct ieee80211_regdomain ath_world_regdom_60_61_62 = { -+- .n_reg_rules = 5, -+ .alpha2 = "99", -+- .reg_rules = { -++ REGD_RULES( -+ ATH_2GHZ_ALL, -+ ATH_5GHZ_ALL, -+- } -++ ) -+ }; -+ -+ /* Can be used by 0x63 and 0x65 */ -+ static const struct ieee80211_regdomain ath_world_regdom_63_65 = { -+- .n_reg_rules = 4, -+ .alpha2 = "99", -+- .reg_rules = { -++ REGD_RULES( -+ ATH_2GHZ_CH01_11, -+ ATH_2GHZ_CH12_13, -+ ATH_5GHZ_NO_MIDBAND, -+- } -++ ) -+ }; -+ -+ /* Can be used by 0x64 only */ -+ static const struct ieee80211_regdomain ath_world_regdom_64 = { -+- .n_reg_rules = 3, -+ .alpha2 = "99", -+- .reg_rules = { -++ REGD_RULES( -+ ATH_2GHZ_CH01_11, -+ ATH_5GHZ_NO_MIDBAND, -+- } -++ ) -+ }; -+ -+ /* Can be used by 0x66 and 0x69 */ -+ static const struct ieee80211_regdomain ath_world_regdom_66_69 = { -+- .n_reg_rules = 3, -+ .alpha2 = "99", -+- .reg_rules = { -++ REGD_RULES( -+ ATH_2GHZ_CH01_11, -+ ATH_5GHZ_ALL, -+- } -++ ) -+ }; -+ -+ /* Can be used by 0x67, 0x68, 0x6A and 0x6C */ -+ static const struct ieee80211_regdomain ath_world_regdom_67_68_6A_6C = { -+- .n_reg_rules = 4, -+ .alpha2 = "99", -+- .reg_rules = { -++ REGD_RULES( -+ ATH_2GHZ_CH01_11, -+ ATH_2GHZ_CH12_13, -+ ATH_5GHZ_ALL, -+- } -++ ) -+ }; -+ -+ static bool dynamic_country_user_possible(struct ath_regulatory *reg) -diff --git a/package/kernel/mac80211/patches/ath/404-regd_no_assoc_hints.patch b/package/kernel/mac80211/patches/ath/404-regd_no_assoc_hints.patch -new file mode 100644 -index 0000000000..8d83921a3b ---- /dev/null -+++ b/package/kernel/mac80211/patches/ath/404-regd_no_assoc_hints.patch -@@ -0,0 +1,19 @@ -+--- a/net/wireless/reg.c -++++ b/net/wireless/reg.c -+@@ -3370,6 +3370,8 @@ void regulatory_hint_country_ie(struct w -+ enum environment_cap env = ENVIRON_ANY; -+ struct regulatory_request *request = NULL, *lr; -+ -++ return; -++ -+ /* IE len must be evenly divisible by 2 */ -+ if (country_ie_len & 0x01) -+ return; -+@@ -3621,6 +3623,7 @@ static bool is_wiphy_all_set_reg_flag(en -+ -+ void regulatory_hint_disconnect(void) -+ { -++ return; -+ /* Restore of regulatory settings is not required when wiphy(s) -+ * ignore IE from connected access point but clearance of beacon hints -+ * is required when wiphy(s) supports beacon hints. -diff --git a/package/kernel/mac80211/patches/ath/405-ath_regd_us.patch b/package/kernel/mac80211/patches/ath/405-ath_regd_us.patch -new file mode 100644 -index 0000000000..6723721a47 ---- /dev/null -+++ b/package/kernel/mac80211/patches/ath/405-ath_regd_us.patch -@@ -0,0 +1,26 @@ -+--- a/drivers/net/wireless/ath/regd_common.h -++++ b/drivers/net/wireless/ath/regd_common.h -+@@ -32,6 +32,7 @@ enum EnumRd { -+ FCC2_WORLD = 0x21, -+ FCC2_ETSIC = 0x22, -+ FCC6_WORLD = 0x23, -++ FCC3_FCCA_2 = 0x2A, -+ FRANCE_RES = 0x31, -+ FCC3_FCCA = 0x3A, -+ FCC3_WORLD = 0x3B, -+@@ -173,6 +174,7 @@ static struct reg_dmn_pair_mapping regDo -+ {FCC2_WORLD, CTL_FCC, CTL_ETSI}, -+ {FCC2_ETSIC, CTL_FCC, CTL_ETSI}, -+ {FCC3_FCCA, CTL_FCC, CTL_FCC}, -++ {FCC3_FCCA_2, CTL_FCC, CTL_FCC}, -+ {FCC3_WORLD, CTL_FCC, CTL_ETSI}, -+ {FCC3_ETSIC, CTL_FCC, CTL_ETSI}, -+ {FCC4_FCCA, CTL_FCC, CTL_FCC}, -+@@ -486,6 +488,7 @@ static struct country_code_to_enum_rd al -+ {CTRY_UAE, NULL1_WORLD, "AE"}, -+ {CTRY_UNITED_KINGDOM, ETSI1_WORLD, "GB"}, -+ {CTRY_UNITED_STATES, FCC3_FCCA, "US"}, -++ {CTRY_UNITED_STATES, FCC3_FCCA_2, "US"}, -+ {CTRY_UNITED_STATES2, FCC3_FCCA, "US"}, -+ {CTRY_UNITED_STATES3, FCC3_FCCA, "US"}, -+ /* This "PS" is for US public safety actually... to support this we -diff --git a/package/kernel/mac80211/patches/ath/406-ath_relax_default_regd.patch b/package/kernel/mac80211/patches/ath/406-ath_relax_default_regd.patch -new file mode 100644 -index 0000000000..ee4e461342 ---- /dev/null -+++ b/package/kernel/mac80211/patches/ath/406-ath_relax_default_regd.patch -@@ -0,0 +1,51 @@ -+--- a/drivers/net/wireless/ath/regd.c -++++ b/drivers/net/wireless/ath/regd.c -+@@ -115,6 +115,16 @@ static const struct ieee80211_regdomain -+ ) -+ }; -+ -++static u16 ath_regd_get_eepromRD(struct ath_regulatory *reg) -++{ -++ return reg->current_rd & ~WORLDWIDE_ROAMING_FLAG; -++} -++ -++static bool is_default_regd(struct ath_regulatory *reg) -++{ -++ return ath_regd_get_eepromRD(reg) == CTRY_DEFAULT; -++} -++ -+ static bool dynamic_country_user_possible(struct ath_regulatory *reg) -+ { -+ if (IS_ENABLED(CPTCFG_ATH_USER_REGD)) -+@@ -123,6 +133,9 @@ static bool dynamic_country_user_possibl -+ if (IS_ENABLED(CPTCFG_ATH_REG_DYNAMIC_USER_CERT_TESTING)) -+ return true; -+ -++ if (is_default_regd(reg)) -++ return true; -++ -+ switch (reg->country_code) { -+ case CTRY_UNITED_STATES: -+ case CTRY_JAPAN1: -+@@ -208,11 +221,6 @@ static inline bool is_wwr_sku(u16 regd) -+ (regd == WORLD)); -+ } -+ -+-static u16 ath_regd_get_eepromRD(struct ath_regulatory *reg) -+-{ -+- return reg->current_rd & ~WORLDWIDE_ROAMING_FLAG; -+-} -+- -+ bool ath_is_world_regd(struct ath_regulatory *reg) -+ { -+ return is_wwr_sku(ath_regd_get_eepromRD(reg)); -+@@ -659,6 +667,9 @@ ath_regd_init_wiphy(struct ath_regulator -+ if (IS_ENABLED(CPTCFG_ATH_USER_REGD)) -+ return 0; -+ -++ if (is_default_regd(reg)) -++ return 0; -++ -+ wiphy->regulatory_flags |= REGULATORY_STRICT_REG | -+ REGULATORY_CUSTOM_REG; -+ -diff --git a/package/kernel/mac80211/patches/ath/431-add_platform_eeprom_support_to_ath5k.patch b/package/kernel/mac80211/patches/ath/431-add_platform_eeprom_support_to_ath5k.patch -new file mode 100644 -index 0000000000..136be19894 ---- /dev/null -+++ b/package/kernel/mac80211/patches/ath/431-add_platform_eeprom_support_to_ath5k.patch -@@ -0,0 +1,56 @@ -+--- a/drivers/net/wireless/ath/ath5k/pci.c -++++ b/drivers/net/wireless/ath/ath5k/pci.c -+@@ -20,6 +20,7 @@ -+ #include -+ #include -+ #include -++#include -+ #include "../ath.h" -+ #include "ath5k.h" -+ #include "debug.h" -+@@ -71,7 +72,7 @@ static void ath5k_pci_read_cachesize(str -+ } -+ -+ /* -+- * Read from eeprom -++ * Read from eeprom or platform_data -+ */ -+ static bool -+ ath5k_pci_eeprom_read(struct ath_common *common, u32 offset, u16 *data) -+@@ -79,6 +80,19 @@ ath5k_pci_eeprom_read(struct ath_common -+ struct ath5k_hw *ah = (struct ath5k_hw *) common->ah; -+ u32 status, timeout; -+ -++ struct ath5k_platform_data *pdata = NULL; -++ -++ if (ah->pdev) -++ pdata = ah->pdev->dev.platform_data; -++ -++ if (pdata && pdata->eeprom_data && pdata->eeprom_data[61] == AR5K_EEPROM_MAGIC_VALUE) { -++ if (offset >= ATH5K_PLAT_EEP_MAX_WORDS) -++ return false; -++ -++ *data = pdata->eeprom_data[offset]; -++ return true; -++ } -++ -+ /* -+ * Initialize EEPROM access -+ */ -+@@ -122,6 +136,16 @@ static int ath5k_pci_eeprom_read_mac(str -+ u16 data; -+ int octet; -+ -++ struct ath5k_platform_data *pdata = NULL; -++ -++ if (ah->pdev) -++ pdata = ah->pdev->dev.platform_data; -++ -++ if (pdata && pdata->macaddr) { -++ memcpy(mac, pdata->macaddr, ETH_ALEN); -++ return 0; -++ } -++ -+ AR5K_EEPROM_READ(0x20, data); -+ -+ for (offset = 0x1f, octet = 0, total = 0; offset >= 0x1d; offset--) { -diff --git a/package/kernel/mac80211/patches/ath10k/080-ath10k_thermal_config.patch b/package/kernel/mac80211/patches/ath10k/080-ath10k_thermal_config.patch -new file mode 100644 -index 0000000000..41ad6006b5 ---- /dev/null -+++ b/package/kernel/mac80211/patches/ath10k/080-ath10k_thermal_config.patch -@@ -0,0 +1,47 @@ -+--- a/drivers/net/wireless/ath/ath10k/Kconfig -++++ b/drivers/net/wireless/ath/ath10k/Kconfig -+@@ -86,6 +86,12 @@ config ATH10K_TRACING -+ help -+ Select this to ath10k use tracing infrastructure. -+ -++config ATH10K_THERMAL -++ bool "Atheros ath10k thermal monitoring support" -++ depends on THERMAL -++ ---help--- -++ Select this to ath10k use hwmon for thermal measurement. -++ -+ config ATH10K_DFS_CERTIFIED -+ bool "Atheros DFS support for certified platforms" -+ depends on ATH10K && CFG80211_CERTIFICATION_ONUS -+--- a/drivers/net/wireless/ath/ath10k/Makefile -++++ b/drivers/net/wireless/ath/ath10k/Makefile -+@@ -18,7 +18,7 @@ ath10k_core-y += mac.o \ -+ ath10k_core-$(CPTCFG_ATH10K_SPECTRAL) += spectral.o -+ ath10k_core-$(CPTCFG_NL80211_TESTMODE) += testmode.o -+ ath10k_core-$(CPTCFG_ATH10K_TRACING) += trace.o -+-ath10k_core-$(CONFIG_THERMAL) += thermal.o -++ath10k_core-$(CPTCFG_ATH10K_THERMAL) += thermal.o -+ ath10k_core-$(CPTCFG_MAC80211_DEBUGFS) += debugfs_sta.o -+ ath10k_core-$(CONFIG_PM) += wow.o -+ ath10k_core-$(CONFIG_DEV_COREDUMP) += coredump.o -+--- a/drivers/net/wireless/ath/ath10k/thermal.h -++++ b/drivers/net/wireless/ath/ath10k/thermal.h -+@@ -25,7 +25,7 @@ struct ath10k_thermal { -+ int temperature; -+ }; -+ -+-#if IS_REACHABLE(CONFIG_THERMAL) -++#if IS_REACHABLE(CPTCFG_ATH10K_THERMAL) -+ int ath10k_thermal_register(struct ath10k *ar); -+ void ath10k_thermal_unregister(struct ath10k *ar); -+ void ath10k_thermal_event_temperature(struct ath10k *ar, int temperature); -+--- a/local-symbols -++++ b/local-symbols -+@@ -161,6 +161,7 @@ ATH10K_SNOC= -+ ATH10K_DEBUG= -+ ATH10K_DEBUGFS= -+ ATH10K_SPECTRAL= -++ATH10K_THERMAL= -+ ATH10K_TRACING= -+ ATH10K_DFS_CERTIFIED= -+ WCN36XX= -diff --git a/package/kernel/mac80211/patches/ath10k/921-ath10k_init_devices_synchronously.patch b/package/kernel/mac80211/patches/ath10k/921-ath10k_init_devices_synchronously.patch -new file mode 100644 -index 0000000000..7a38cf3e4e ---- /dev/null -+++ b/package/kernel/mac80211/patches/ath10k/921-ath10k_init_devices_synchronously.patch -@@ -0,0 +1,33 @@ -+From: Sven Eckelmann -+Date: Tue, 18 Nov 2014 12:29:28 +0100 -+Subject: [PATCH] ath10k: Don't initialize devices asynchronously -+ -+OpenWrt requires all PHYs to be initialized to create the configuration files -+during bootup. ath10k violates this because it delays the creation of the PHY -+to a not well defined point in the future. -+ -+Forcing the work to be done immediately works around this problem but may also -+delay the boot when firmware images cannot be found. -+ -+Signed-off-by: Sven Eckelmann -+--- -+ -+--- a/drivers/net/wireless/ath/ath10k/core.c -++++ b/drivers/net/wireless/ath/ath10k/core.c -+@@ -3516,6 +3516,16 @@ int ath10k_core_register(struct ath10k * -+ -+ queue_work(ar->workqueue, &ar->register_work); -+ -++ /* OpenWrt requires all PHYs to be initialized to create the -++ * configuration files during bootup. ath10k violates this -++ * because it delays the creation of the PHY to a not well defined -++ * point in the future. -++ * -++ * Forcing the work to be done immediately works around this problem -++ * but may also delay the boot when firmware images cannot be found. -++ */ -++ flush_workqueue(ar->workqueue); -++ -+ return 0; -+ } -+ EXPORT_SYMBOL(ath10k_core_register); -diff --git a/package/kernel/mac80211/patches/ath10k/930-ath10k_add_tpt_led_trigger.patch b/package/kernel/mac80211/patches/ath10k/930-ath10k_add_tpt_led_trigger.patch -new file mode 100644 -index 0000000000..e8beed17e8 ---- /dev/null -+++ b/package/kernel/mac80211/patches/ath10k/930-ath10k_add_tpt_led_trigger.patch -@@ -0,0 +1,37 @@ -+--- a/drivers/net/wireless/ath/ath10k/mac.c -++++ b/drivers/net/wireless/ath/ath10k/mac.c -+@@ -9909,6 +9909,21 @@ static int ath10k_mac_init_rd(struct ath -+ return 0; -+ } -+ -++#ifdef CPTCFG_MAC80211_LEDS -++static const struct ieee80211_tpt_blink ath10k_tpt_blink[] = { -++ { .throughput = 0 * 1024, .blink_time = 334 }, -++ { .throughput = 1 * 1024, .blink_time = 260 }, -++ { .throughput = 2 * 1024, .blink_time = 220 }, -++ { .throughput = 5 * 1024, .blink_time = 190 }, -++ { .throughput = 10 * 1024, .blink_time = 170 }, -++ { .throughput = 25 * 1024, .blink_time = 150 }, -++ { .throughput = 54 * 1024, .blink_time = 130 }, -++ { .throughput = 120 * 1024, .blink_time = 110 }, -++ { .throughput = 265 * 1024, .blink_time = 80 }, -++ { .throughput = 586 * 1024, .blink_time = 50 }, -++}; -++#endif -++ -+ int ath10k_mac_register(struct ath10k *ar) -+ { -+ static const u32 cipher_suites[] = { -+@@ -10267,6 +10282,12 @@ int ath10k_mac_register(struct ath10k *a -+ -+ ar->hw->weight_multiplier = ATH10K_AIRTIME_WEIGHT_MULTIPLIER; -+ -++#ifdef CPTCFG_MAC80211_LEDS -++ ieee80211_create_tpt_led_trigger(ar->hw, -++ IEEE80211_TPT_LEDTRIG_FL_RADIO, ath10k_tpt_blink, -++ ARRAY_SIZE(ath10k_tpt_blink)); -++#endif -++ -+ ret = ieee80211_register_hw(ar->hw); -+ if (ret) { -+ ath10k_err(ar, "failed to register ieee80211: %d\n", ret); -diff --git a/package/kernel/mac80211/patches/ath10k/974-ath10k_add-LED-and-GPIO-controlling-support-for-various-chipsets.patch b/package/kernel/mac80211/patches/ath10k/974-ath10k_add-LED-and-GPIO-controlling-support-for-various-chipsets.patch -new file mode 100644 -index 0000000000..1c1630c051 ---- /dev/null -+++ b/package/kernel/mac80211/patches/ath10k/974-ath10k_add-LED-and-GPIO-controlling-support-for-various-chipsets.patch -@@ -0,0 +1,609 @@ -+From: Sebastian Gottschall -+ -+Adds LED and GPIO Control support for 988x, 9887, 9888, 99x0, 9984 based -+chipsets with on chipset connected led's using WMI Firmware API. The LED -+device will get available named as "ath10k-phyX" at sysfs and can be controlled -+with various triggers. adds also debugfs interface for gpio control. -+ -+This patch is specific for OpenWRt base, as is use old backported package -+with old wireless source. Support for QCA9984 is removed and a simbol -+is added to local-simbol file to export the actually compile the code -+with the ATH10K_LEDS simbol. -+ -+ -+Signed-off-by: Sebastian Gottschall -+Reviewed-by: Steve deRosier -+[kvalo: major reorg and cleanup] -+Signed-off-by: Kalle Valo -+Signed-off-by: Ansuel Smith -+--- -+ -+v13: -+ -+* only compile tested! -+ -+* fix all checkpatch warnings -+ -+* fix commit log -+ -+* sizeof(struct ath10k_gpiocontrol) -> sizeof(*gpio) -+ -+* unsigned -> unsigned int -+ -+* remove GPIOLIB code, that should be added in a separate patch -+ -+* rename gpio.c to leds.c -+ -+* add leds.h -+ -+* rename some functions: -+ -+ ath10k_attach_led() -> ath10k_leds_register() -+ ath10k_unregister_led() -> ath10k_leds_unregister() -+ ath10k_reset_led_pin() -> ath10k_leds_start() -+ -+* call ath10k_leds_unregister() before ath10k_thermal_unregister() to preserve ordering -+ -+* call ath10k_leds_start() only from ath10k_core_start() and not from mac.c -+ -+* rename struct ath10k_gpiocontrol as anonymous function under struct -+ ath10k::leds, no need for memory allocation -+ -+* merge ath10k_add_led() to ath10k_attach_led(), which is it's only caller -+ -+* remove #if IS_ENABLED() checks from most of places, memory savings from those were not worth it -+ -+* Kconfig help text improvement and move it lower in the menu, also don't enable it by default -+ -+* switch to set_brightness_blocking() so that the callback can sleep, -+ then no need to use ath10k_wmi_cmd_send_nowait() and can take mutex -+ to access ar->state -+ -+* don't touch ath10k_wmi_pdev_get_temperature() -+ -+* as QCA6174/QCA9377 are not (yet) supported don't add the command to WMI-TLV interface -+ -+* remove debugfs interface, that should be added in another patch -+ -+* cleanup includes -+ -+ -+ drivers/net/wireless/ath/ath10k/Kconfig | 10 +++ -+ drivers/net/wireless/ath/ath10k/Makefile | 1 + -+ drivers/net/wireless/ath/ath10k/core.c | 22 +++++++ -+ drivers/net/wireless/ath/ath10k/core.h | 9 ++- -+ drivers/net/wireless/ath/ath10k/hw.h | 1 + -+ drivers/net/wireless/ath/ath10k/leds.c | 103 ++++++++++++++++++++++++++++++ -+ drivers/net/wireless/ath/ath10k/leds.h | 45 +++++++++++++ -+ drivers/net/wireless/ath/ath10k/mac.c | 1 + -+ drivers/net/wireless/ath/ath10k/wmi-ops.h | 32 ++++++++++ -+ drivers/net/wireless/ath/ath10k/wmi-tlv.c | 2 + -+ drivers/net/wireless/ath/ath10k/wmi.c | 54 ++++++++++++++++ -+ drivers/net/wireless/ath/ath10k/wmi.h | 35 ++++++++++ -+ 12 files changed, 314 insertions(+), 1 deletion(-) -+ create mode 100644 drivers/net/wireless/ath/ath10k/leds.c -+ create mode 100644 drivers/net/wireless/ath/ath10k/leds.h -+--- a/drivers/net/wireless/ath/ath10k/Kconfig -++++ b/drivers/net/wireless/ath/ath10k/Kconfig -+@@ -71,6 +71,16 @@ config ATH10K_DEBUGFS -+ -+ If unsure, say Y to make it easier to debug problems. -+ -++config ATH10K_LEDS -++ bool "Atheros ath10k LED support" -++ depends on ATH10K -++ select MAC80211_LEDS -++ select LEDS_CLASS -++ select NEW_LEDS -++ default y -++ ---help--- -++ This option is necessary, if you want LED support for chipset connected led pins. If unsure, say N. -++ -+ config ATH10K_SPECTRAL -+ bool "Atheros ath10k spectral scan support" -+ depends on ATH10K_DEBUGFS -+--- a/drivers/net/wireless/ath/ath10k/Makefile -++++ b/drivers/net/wireless/ath/ath10k/Makefile -+@@ -19,6 +19,7 @@ ath10k_core-$(CPTCFG_ATH10K_SPECTRAL) += -+ ath10k_core-$(CPTCFG_NL80211_TESTMODE) += testmode.o -+ ath10k_core-$(CPTCFG_ATH10K_TRACING) += trace.o -+ ath10k_core-$(CPTCFG_ATH10K_THERMAL) += thermal.o -++ath10k_core-$(CPTCFG_ATH10K_LEDS) += leds.o -+ ath10k_core-$(CPTCFG_MAC80211_DEBUGFS) += debugfs_sta.o -+ ath10k_core-$(CONFIG_PM) += wow.o -+ ath10k_core-$(CONFIG_DEV_COREDUMP) += coredump.o -+--- a/local-symbols -++++ b/local-symbols -+@@ -162,6 +162,7 @@ ATH10K_DEBUG= -+ ATH10K_DEBUGFS= -+ ATH10K_SPECTRAL= -+ ATH10K_THERMAL= -++ATH10K_LEDS= -+ ATH10K_TRACING= -+ ATH10K_DFS_CERTIFIED= -+ WCN36XX= -+--- a/drivers/net/wireless/ath/ath10k/core.c -++++ b/drivers/net/wireless/ath/ath10k/core.c -+@@ -26,6 +26,7 @@ -+ #include "testmode.h" -+ #include "wmi-ops.h" -+ #include "coredump.h" -++#include "leds.h" -+ -+ unsigned int ath10k_debug_mask; -+ EXPORT_SYMBOL(ath10k_debug_mask); -+@@ -65,6 +66,7 @@ static const struct ath10k_hw_params ath -+ .dev_id = QCA988X_2_0_DEVICE_ID, -+ .bus = ATH10K_BUS_PCI, -+ .name = "qca988x hw2.0", -++ .led_pin = 1, -+ .patch_load_addr = QCA988X_HW_2_0_PATCH_LOAD_ADDR, -+ .uart_pin = 7, -+ .cc_wraparound_type = ATH10K_HW_CC_WRAP_SHIFTED_ALL, -+@@ -146,6 +148,7 @@ static const struct ath10k_hw_params ath -+ .dev_id = QCA9887_1_0_DEVICE_ID, -+ .bus = ATH10K_BUS_PCI, -+ .name = "qca9887 hw1.0", -++ .led_pin = 1, -+ .patch_load_addr = QCA9887_HW_1_0_PATCH_LOAD_ADDR, -+ .uart_pin = 7, -+ .cc_wraparound_type = ATH10K_HW_CC_WRAP_SHIFTED_ALL, -+@@ -387,6 +390,7 @@ static const struct ath10k_hw_params ath -+ .dev_id = QCA99X0_2_0_DEVICE_ID, -+ .bus = ATH10K_BUS_PCI, -+ .name = "qca99x0 hw2.0", -++ .led_pin = 17, -+ .patch_load_addr = QCA99X0_HW_2_0_PATCH_LOAD_ADDR, -+ .uart_pin = 7, -+ .otp_exe_param = 0x00000700, -+@@ -433,6 +437,7 @@ static const struct ath10k_hw_params ath -+ .dev_id = QCA9984_1_0_DEVICE_ID, -+ .bus = ATH10K_BUS_PCI, -+ .name = "qca9984/qca9994 hw1.0", -++ .led_pin = 17, -+ .patch_load_addr = QCA9984_HW_1_0_PATCH_LOAD_ADDR, -+ .uart_pin = 7, -+ .cc_wraparound_type = ATH10K_HW_CC_WRAP_SHIFTED_EACH, -+@@ -486,6 +491,7 @@ static const struct ath10k_hw_params ath -+ .dev_id = QCA9888_2_0_DEVICE_ID, -+ .bus = ATH10K_BUS_PCI, -+ .name = "qca9888 hw2.0", -++ .led_pin = 17, -+ .patch_load_addr = QCA9888_HW_2_0_PATCH_LOAD_ADDR, -+ .uart_pin = 7, -+ .cc_wraparound_type = ATH10K_HW_CC_WRAP_SHIFTED_EACH, -+@@ -3231,6 +3237,10 @@ int ath10k_core_start(struct ath10k *ar, -+ goto err_hif_stop; -+ } -+ -++ status = ath10k_leds_start(ar); -++ if (status) -++ goto err_hif_stop; -++ -+ return 0; -+ -+ err_hif_stop: -+@@ -3489,9 +3499,18 @@ static void ath10k_core_register_work(st -+ goto err_spectral_destroy; -+ } -+ -++ status = ath10k_leds_register(ar); -++ if (status) { -++ ath10k_err(ar, "could not register leds: %d\n", -++ status); -++ goto err_thermal_unregister; -++ } -++ -+ set_bit(ATH10K_FLAG_CORE_REGISTERED, &ar->dev_flags); -+ return; -+ -++err_thermal_unregister: -++ ath10k_thermal_unregister(ar); -+ err_spectral_destroy: -+ ath10k_spectral_destroy(ar); -+ err_debug_destroy: -+@@ -3537,6 +3556,8 @@ void ath10k_core_unregister(struct ath10 -+ if (!test_bit(ATH10K_FLAG_CORE_REGISTERED, &ar->dev_flags)) -+ return; -+ -++ ath10k_leds_unregister(ar); -++ -+ ath10k_thermal_unregister(ar); -+ /* Stop spectral before unregistering from mac80211 to remove the -+ * relayfs debugfs file cleanly. Otherwise the parent debugfs tree -+--- a/drivers/net/wireless/ath/ath10k/core.h -++++ b/drivers/net/wireless/ath/ath10k/core.h -+@@ -14,6 +14,7 @@ -+ #include -+ #include -+ #include -++#include -+ -+ #include "htt.h" -+ #include "htc.h" -+@@ -1253,6 +1254,13 @@ struct ath10k { -+ } testmode; -+ -+ struct { -++ struct gpio_led wifi_led; -++ struct led_classdev cdev; -++ char label[48]; -++ u32 gpio_state_pin; -++ } leds; -++ -++ struct { -+ /* protected by data_lock */ -+ u32 rx_crc_err_drop; -+ u32 fw_crash_counter; -+--- a/drivers/net/wireless/ath/ath10k/hw.h -++++ b/drivers/net/wireless/ath/ath10k/hw.h -+@@ -519,6 +519,7 @@ struct ath10k_hw_params { -+ const char *name; -+ u32 patch_load_addr; -+ int uart_pin; -++ int led_pin; -+ u32 otp_exe_param; -+ -+ /* Type of hw cycle counter wraparound logic, for more info -+--- /dev/null -++++ b/drivers/net/wireless/ath/ath10k/leds.c -+@@ -0,0 +1,103 @@ -++/* -++ * Copyright (c) 2005-2011 Atheros Communications Inc. -++ * Copyright (c) 2011-2017 Qualcomm Atheros, Inc. -++ * Copyright (c) 2018 Sebastian Gottschall -++ * Copyright (c) 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 "core.h" -++#include "wmi.h" -++#include "wmi-ops.h" -++ -++#include "leds.h" -++ -++static int ath10k_leds_set_brightness_blocking(struct led_classdev *led_cdev, -++ enum led_brightness brightness) -++{ -++ struct ath10k *ar = container_of(led_cdev, struct ath10k, -++ leds.cdev); -++ struct gpio_led *led = &ar->leds.wifi_led; -++ -++ mutex_lock(&ar->conf_mutex); -++ -++ if (ar->state != ATH10K_STATE_ON) -++ goto out; -++ -++ ar->leds.gpio_state_pin = (brightness != LED_OFF) ^ led->active_low; -++ ath10k_wmi_gpio_output(ar, led->gpio, ar->leds.gpio_state_pin); -++ -++out: -++ mutex_unlock(&ar->conf_mutex); -++ -++ return 0; -++} -++ -++int ath10k_leds_start(struct ath10k *ar) -++{ -++ if (ar->hw_params.led_pin == 0) -++ /* leds not supported */ -++ return 0; -++ -++ /* under some circumstances, the gpio pin gets reconfigured -++ * to default state by the firmware, so we need to -++ * reconfigure it this behaviour has only ben seen on -++ * QCA9984 and QCA99XX devices so far -++ */ -++ ath10k_wmi_gpio_config(ar, ar->hw_params.led_pin, 0, -++ WMI_GPIO_PULL_NONE, WMI_GPIO_INTTYPE_DISABLE); -++ ath10k_wmi_gpio_output(ar, ar->hw_params.led_pin, 1); -++ -++ return 0; -++} -++ -++int ath10k_leds_register(struct ath10k *ar) -++{ -++ int ret; -++ -++ if (ar->hw_params.led_pin == 0) -++ /* leds not supported */ -++ return 0; -++ -++ snprintf(ar->leds.label, sizeof(ar->leds.label), "ath10k-%s", -++ wiphy_name(ar->hw->wiphy)); -++ ar->leds.wifi_led.active_low = 1; -++ ar->leds.wifi_led.gpio = ar->hw_params.led_pin; -++ ar->leds.wifi_led.name = ar->leds.label; -++ ar->leds.wifi_led.default_state = LEDS_GPIO_DEFSTATE_KEEP; -++ -++ ar->leds.cdev.name = ar->leds.label; -++ ar->leds.cdev.brightness_set_blocking = ath10k_leds_set_brightness_blocking; -++ -++ /* FIXME: this assignment doesn't make sense as it's NULL, remove it? */ -++ ar->leds.cdev.default_trigger = ar->leds.wifi_led.default_trigger; -++ -++ ret = led_classdev_register(wiphy_dev(ar->hw->wiphy), &ar->leds.cdev); -++ if (ret) -++ return ret; -++ -++ return 0; -++} -++ -++void ath10k_leds_unregister(struct ath10k *ar) -++{ -++ if (ar->hw_params.led_pin == 0) -++ /* leds not supported */ -++ return; -++ -++ led_classdev_unregister(&ar->leds.cdev); -++} -++ -+--- /dev/null -++++ b/drivers/net/wireless/ath/ath10k/leds.h -+@@ -0,0 +1,41 @@ -++/* -++ * Copyright (c) 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. -++ */ -++#ifndef _LEDS_H_ -++#define _LEDS_H_ -++ -++#include "core.h" -++ -++#ifdef CPTCFG_ATH10K_LEDS -++void ath10k_leds_unregister(struct ath10k *ar); -++int ath10k_leds_start(struct ath10k *ar); -++int ath10k_leds_register(struct ath10k *ar); -++#else -++static inline void ath10k_leds_unregister(struct ath10k *ar) -++{ -++} -++ -++static inline int ath10k_leds_start(struct ath10k *ar) -++{ -++ return 0; -++} -++ -++static inline int ath10k_leds_register(struct ath10k *ar) -++{ -++ return 0; -++} -++ -++#endif -++#endif /* _LEDS_H_ */ -+--- a/drivers/net/wireless/ath/ath10k/mac.c -++++ b/drivers/net/wireless/ath/ath10k/mac.c -+@@ -24,6 +24,7 @@ -+ #include "wmi-tlv.h" -+ #include "wmi-ops.h" -+ #include "wow.h" -++#include "leds.h" -+ -+ /*********/ -+ /* Rates */ -+--- a/drivers/net/wireless/ath/ath10k/wmi-ops.h -++++ b/drivers/net/wireless/ath/ath10k/wmi-ops.h -+@@ -226,7 +226,10 @@ struct wmi_ops { -+ const struct wmi_bb_timing_cfg_arg *arg); -+ struct sk_buff *(*gen_per_peer_per_tid_cfg)(struct ath10k *ar, -+ const struct wmi_per_peer_per_tid_cfg_arg *arg); -++ struct sk_buff *(*gen_gpio_config)(struct ath10k *ar, u32 gpio_num, -++ u32 input, u32 pull_type, u32 intr_mode); -+ -++ struct sk_buff *(*gen_gpio_output)(struct ath10k *ar, u32 gpio_num, u32 set); -+ }; -+ -+ int ath10k_wmi_cmd_send(struct ath10k *ar, struct sk_buff *skb, u32 cmd_id); -+@@ -1122,6 +1125,35 @@ ath10k_wmi_force_fw_hang(struct ath10k * -+ return ath10k_wmi_cmd_send(ar, skb, ar->wmi.cmd->force_fw_hang_cmdid); -+ } -+ -++static inline int ath10k_wmi_gpio_config(struct ath10k *ar, u32 gpio_num, -++ u32 input, u32 pull_type, u32 intr_mode) -++{ -++ struct sk_buff *skb; -++ -++ if (!ar->wmi.ops->gen_gpio_config) -++ return -EOPNOTSUPP; -++ -++ skb = ar->wmi.ops->gen_gpio_config(ar, gpio_num, input, pull_type, intr_mode); -++ if (IS_ERR(skb)) -++ return PTR_ERR(skb); -++ -++ return ath10k_wmi_cmd_send(ar, skb, ar->wmi.cmd->gpio_config_cmdid); -++} -++ -++static inline int ath10k_wmi_gpio_output(struct ath10k *ar, u32 gpio_num, u32 set) -++{ -++ struct sk_buff *skb; -++ -++ if (!ar->wmi.ops->gen_gpio_config) -++ return -EOPNOTSUPP; -++ -++ skb = ar->wmi.ops->gen_gpio_output(ar, gpio_num, set); -++ if (IS_ERR(skb)) -++ return PTR_ERR(skb); -++ -++ return ath10k_wmi_cmd_send(ar, skb, ar->wmi.cmd->gpio_output_cmdid); -++} -++ -+ static inline int -+ ath10k_wmi_dbglog_cfg(struct ath10k *ar, u64 module_enable, u32 log_level) -+ { -+--- a/drivers/net/wireless/ath/ath10k/wmi-tlv.c -++++ b/drivers/net/wireless/ath/ath10k/wmi-tlv.c -+@@ -4594,6 +4594,8 @@ static const struct wmi_ops wmi_tlv_ops -+ .gen_echo = ath10k_wmi_tlv_op_gen_echo, -+ .gen_vdev_spectral_conf = ath10k_wmi_tlv_op_gen_vdev_spectral_conf, -+ .gen_vdev_spectral_enable = ath10k_wmi_tlv_op_gen_vdev_spectral_enable, -++ /* .gen_gpio_config not implemented */ -++ /* .gen_gpio_output not implemented */ -+ }; -+ -+ static const struct wmi_peer_flags_map wmi_tlv_peer_flags_map = { -+--- a/drivers/net/wireless/ath/ath10k/wmi.c -++++ b/drivers/net/wireless/ath/ath10k/wmi.c -+@@ -7472,6 +7472,49 @@ ath10k_wmi_op_gen_peer_set_param(struct -+ return skb; -+ } -+ -++static struct sk_buff *ath10k_wmi_op_gen_gpio_config(struct ath10k *ar, -++ u32 gpio_num, u32 input, -++ u32 pull_type, u32 intr_mode) -++{ -++ struct wmi_gpio_config_cmd *cmd; -++ struct sk_buff *skb; -++ -++ skb = ath10k_wmi_alloc_skb(ar, sizeof(*cmd)); -++ if (!skb) -++ return ERR_PTR(-ENOMEM); -++ -++ cmd = (struct wmi_gpio_config_cmd *)skb->data; -++ cmd->pull_type = __cpu_to_le32(pull_type); -++ cmd->gpio_num = __cpu_to_le32(gpio_num); -++ cmd->input = __cpu_to_le32(input); -++ cmd->intr_mode = __cpu_to_le32(intr_mode); -++ -++ ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi gpio_config gpio_num 0x%08x input 0x%08x pull_type 0x%08x intr_mode 0x%08x\n", -++ gpio_num, input, pull_type, intr_mode); -++ -++ return skb; -++} -++ -++static struct sk_buff *ath10k_wmi_op_gen_gpio_output(struct ath10k *ar, -++ u32 gpio_num, u32 set) -++{ -++ struct wmi_gpio_output_cmd *cmd; -++ struct sk_buff *skb; -++ -++ skb = ath10k_wmi_alloc_skb(ar, sizeof(*cmd)); -++ if (!skb) -++ return ERR_PTR(-ENOMEM); -++ -++ cmd = (struct wmi_gpio_output_cmd *)skb->data; -++ cmd->gpio_num = __cpu_to_le32(gpio_num); -++ cmd->set = __cpu_to_le32(set); -++ -++ ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi gpio_output gpio_num 0x%08x set 0x%08x\n", -++ gpio_num, set); -++ -++ return skb; -++} -++ -+ static struct sk_buff * -+ ath10k_wmi_op_gen_set_psmode(struct ath10k *ar, u32 vdev_id, -+ enum wmi_sta_ps_mode psmode) -+@@ -9160,6 +9203,9 @@ static const struct wmi_ops wmi_ops = { -+ .fw_stats_fill = ath10k_wmi_main_op_fw_stats_fill, -+ .get_vdev_subtype = ath10k_wmi_op_get_vdev_subtype, -+ .gen_echo = ath10k_wmi_op_gen_echo, -++ .gen_gpio_config = ath10k_wmi_op_gen_gpio_config, -++ .gen_gpio_output = ath10k_wmi_op_gen_gpio_output, -++ -+ /* .gen_bcn_tmpl not implemented */ -+ /* .gen_prb_tmpl not implemented */ -+ /* .gen_p2p_go_bcn_ie not implemented */ -+@@ -9230,6 +9276,8 @@ static const struct wmi_ops wmi_10_1_ops -+ .fw_stats_fill = ath10k_wmi_10x_op_fw_stats_fill, -+ .get_vdev_subtype = ath10k_wmi_op_get_vdev_subtype, -+ .gen_echo = ath10k_wmi_op_gen_echo, -++ .gen_gpio_config = ath10k_wmi_op_gen_gpio_config, -++ .gen_gpio_output = ath10k_wmi_op_gen_gpio_output, -+ /* .gen_bcn_tmpl not implemented */ -+ /* .gen_prb_tmpl not implemented */ -+ /* .gen_p2p_go_bcn_ie not implemented */ -+@@ -9302,6 +9350,8 @@ static const struct wmi_ops wmi_10_2_ops -+ .gen_delba_send = ath10k_wmi_op_gen_delba_send, -+ .fw_stats_fill = ath10k_wmi_10x_op_fw_stats_fill, -+ .get_vdev_subtype = ath10k_wmi_op_get_vdev_subtype, -++ .gen_gpio_config = ath10k_wmi_op_gen_gpio_config, -++ .gen_gpio_output = ath10k_wmi_op_gen_gpio_output, -+ /* .gen_pdev_enable_adaptive_cca not implemented */ -+ }; -+ -+@@ -9373,6 +9423,8 @@ static const struct wmi_ops wmi_10_2_4_o -+ ath10k_wmi_op_gen_pdev_enable_adaptive_cca, -+ .get_vdev_subtype = ath10k_wmi_10_2_4_op_get_vdev_subtype, -+ .gen_bb_timing = ath10k_wmi_10_2_4_op_gen_bb_timing, -++ .gen_gpio_config = ath10k_wmi_op_gen_gpio_config, -++ .gen_gpio_output = ath10k_wmi_op_gen_gpio_output, -+ /* .gen_bcn_tmpl not implemented */ -+ /* .gen_prb_tmpl not implemented */ -+ /* .gen_p2p_go_bcn_ie not implemented */ -+@@ -9454,6 +9506,8 @@ static const struct wmi_ops wmi_10_4_ops -+ .gen_pdev_bss_chan_info_req = ath10k_wmi_10_2_op_gen_pdev_bss_chan_info, -+ .gen_echo = ath10k_wmi_op_gen_echo, -+ .gen_pdev_get_tpc_config = ath10k_wmi_10_2_4_op_gen_pdev_get_tpc_config, -++ .gen_gpio_config = ath10k_wmi_op_gen_gpio_config, -++ .gen_gpio_output = ath10k_wmi_op_gen_gpio_output, -+ }; -+ -+ int ath10k_wmi_attach(struct ath10k *ar) -+--- a/drivers/net/wireless/ath/ath10k/wmi.h -++++ b/drivers/net/wireless/ath/ath10k/wmi.h -+@@ -3030,6 +3030,41 @@ enum wmi_10_4_feature_mask { -+ -+ }; -+ -++/* WMI_GPIO_CONFIG_CMDID */ -++enum { -++ WMI_GPIO_PULL_NONE, -++ WMI_GPIO_PULL_UP, -++ WMI_GPIO_PULL_DOWN, -++}; -++ -++enum { -++ WMI_GPIO_INTTYPE_DISABLE, -++ WMI_GPIO_INTTYPE_RISING_EDGE, -++ WMI_GPIO_INTTYPE_FALLING_EDGE, -++ WMI_GPIO_INTTYPE_BOTH_EDGE, -++ WMI_GPIO_INTTYPE_LEVEL_LOW, -++ WMI_GPIO_INTTYPE_LEVEL_HIGH -++}; -++ -++/* WMI_GPIO_CONFIG_CMDID */ -++struct wmi_gpio_config_cmd { -++ __le32 gpio_num; /* GPIO number to be setup */ -++ __le32 input; /* 0 - Output/ 1 - Input */ -++ __le32 pull_type; /* Pull type defined above */ -++ __le32 intr_mode; /* Interrupt mode defined above (Input) */ -++} __packed; -++ -++/* WMI_GPIO_OUTPUT_CMDID */ -++struct wmi_gpio_output_cmd { -++ __le32 gpio_num; /* GPIO number to be setup */ -++ __le32 set; /* Set the GPIO pin*/ -++} __packed; -++ -++/* WMI_GPIO_INPUT_EVENTID */ -++struct wmi_gpio_input_event { -++ __le32 gpio_num; /* GPIO number which changed state */ -++} __packed; -++ -+ struct wmi_ext_resource_config_10_4_cmd { -+ /* contains enum wmi_host_platform_type */ -+ __le32 host_platform_config; -diff --git a/package/kernel/mac80211/patches/ath10k/975-ath10k-use-tpt-trigger-by-default.patch b/package/kernel/mac80211/patches/ath10k/975-ath10k-use-tpt-trigger-by-default.patch -new file mode 100644 -index 0000000000..4c1f9aa815 ---- /dev/null -+++ b/package/kernel/mac80211/patches/ath10k/975-ath10k-use-tpt-trigger-by-default.patch -@@ -0,0 +1,53 @@ -+From 79c9d7aabae1d1da9eea97d83b61e1517a8a2221 Mon Sep 17 00:00:00 2001 -+From: Mathias Kresin -+Date: Fri, 22 Jun 2018 18:59:44 +0200 -+Subject: [PATCH] ath10k: use tpt LED trigger by default -+ -+Use the tpt LED trigger for each created phy led. Ths way LEDs attached -+to the ath10k GPIO pins are indicating the phy status and blink on -+traffic. -+ -+Signed-off-by: Mathias Kresin -+--- -+ drivers/net/wireless/ath/ath10k/core.h | 4 ++++ -+ drivers/net/wireless/ath/ath10k/leds.c | 4 +--- -+ drivers/net/wireless/ath/ath10k/mac.c | 2 +- -+ 3 files changed, 6 insertions(+), 4 deletions(-) -+ -+--- a/drivers/net/wireless/ath/ath10k/core.h -++++ b/drivers/net/wireless/ath/ath10k/core.h -+@@ -1309,6 +1309,10 @@ struct ath10k { -+ s32 tx_power_2g_limit; -+ s32 tx_power_5g_limit; -+ -++#ifdef CPTCFG_MAC80211_LEDS -++ const char *led_default_trigger; -++#endif -++ -+ /* must be last */ -+ u8 drv_priv[] __aligned(sizeof(void *)); -+ }; -+--- a/drivers/net/wireless/ath/ath10k/leds.c -++++ b/drivers/net/wireless/ath/ath10k/leds.c -+@@ -81,9 +81,7 @@ int ath10k_leds_register(struct ath10k * -+ -+ ar->leds.cdev.name = ar->leds.label; -+ ar->leds.cdev.brightness_set_blocking = ath10k_leds_set_brightness_blocking; -+- -+- /* FIXME: this assignment doesn't make sense as it's NULL, remove it? */ -+- ar->leds.cdev.default_trigger = ar->leds.wifi_led.default_trigger; -++ ar->leds.cdev.default_trigger = ar->led_default_trigger; -+ -+ ret = led_classdev_register(wiphy_dev(ar->hw->wiphy), &ar->leds.cdev); -+ if (ret) -+--- a/drivers/net/wireless/ath/ath10k/mac.c -++++ b/drivers/net/wireless/ath/ath10k/mac.c -+@@ -10284,7 +10284,7 @@ int ath10k_mac_register(struct ath10k *a -+ ar->hw->weight_multiplier = ATH10K_AIRTIME_WEIGHT_MULTIPLIER; -+ -+ #ifdef CPTCFG_MAC80211_LEDS -+- ieee80211_create_tpt_led_trigger(ar->hw, -++ ar->led_default_trigger = ieee80211_create_tpt_led_trigger(ar->hw, -+ IEEE80211_TPT_LEDTRIG_FL_RADIO, ath10k_tpt_blink, -+ ARRAY_SIZE(ath10k_tpt_blink)); -+ #endif -diff --git a/package/kernel/mac80211/patches/ath10k/981-ath10k-adjust-tx-power-reduction-for-US-regulatory-d.patch b/package/kernel/mac80211/patches/ath10k/981-ath10k-adjust-tx-power-reduction-for-US-regulatory-d.patch -new file mode 100644 -index 0000000000..3626debf19 ---- /dev/null -+++ b/package/kernel/mac80211/patches/ath10k/981-ath10k-adjust-tx-power-reduction-for-US-regulatory-d.patch -@@ -0,0 +1,101 @@ -+From: Sven Eckelmann -+Date: Wed, 28 Nov 2018 16:16:27 +0100 -+Subject: ath10k: adjust tx power reduction for US regulatory domain -+ -+FCC allows maximum antenna gain of 6 dBi. 15.247(b)(4): -+ -+> (4) The conducted output power limit -+> specified in paragraph (b) of this section -+> is based on the use of antennas -+> with directional gains that do not exceed -+> 6 dBi. Except as shown in paragraph -+> (c) of this section, if transmitting -+> antennas of directional gain greater -+> than 6 dBi are used, the conducted -+> output power from the intentional radiator -+> shall be reduced below the stated -+> values in paragraphs (b)(1), (b)(2), -+> and (b)(3) of this section, as appropriate, -+> by the amount in dB that the -+> directional gain of the antenna exceeds -+> 6 dBi. -+ -+https://www.gpo.gov/fdsys/pkg/CFR-2013-title47-vol1/pdf/CFR-2013-title47-vol1-sec15-247.pdf -+ -+Signed-off-by: Sven Eckelmann -+ -+Forwarded: no -+ -+--- a/drivers/net/wireless/ath/ath10k/mac.c -++++ b/drivers/net/wireless/ath/ath10k/mac.c -+@@ -1028,6 +1028,40 @@ static inline int ath10k_vdev_setup_sync -+ return ar->last_wmi_vdev_start_status; -+ } -+ -++static u32 ath10k_get_max_antenna_gain(struct ath10k *ar, -++ u32 ch_max_antenna_gain) -++{ -++ u32 max_antenna_gain; -++ -++ if (ar->dfs_detector && ar->dfs_detector->region == NL80211_DFS_FCC) { -++ /* FCC allows maximum antenna gain of 6 dBi. 15.247(b)(4): -++ * -++ * > (4) The conducted output power limit -++ * > specified in paragraph (b) of this section -++ * > is based on the use of antennas -++ * > with directional gains that do not exceed -++ * > 6 dBi. Except as shown in paragraph -++ * > (c) of this section, if transmitting -++ * > antennas of directional gain greater -++ * > than 6 dBi are used, the conducted -++ * > output power from the intentional radiator -++ * > shall be reduced below the stated -++ * > values in paragraphs (b)(1), (b)(2), -++ * > and (b)(3) of this section, as appropriate, -++ * > by the amount in dB that the -++ * > directional gain of the antenna exceeds -++ * > 6 dBi. -++ * -++ * https://www.gpo.gov/fdsys/pkg/CFR-2013-title47-vol1/pdf/CFR-2013-title47-vol1-sec15-247.pdf -++ */ -++ max_antenna_gain = 6; -++ } else { -++ max_antenna_gain = 0; -++ } -++ -++ return max(ch_max_antenna_gain, max_antenna_gain); -++} -++ -+ static int ath10k_monitor_vdev_start(struct ath10k *ar, int vdev_id) -+ { -+ struct cfg80211_chan_def *chandef = NULL; -+@@ -1060,7 +1094,8 @@ static int ath10k_monitor_vdev_start(str -+ arg.channel.min_power = 0; -+ arg.channel.max_power = channel->max_power * 2; -+ arg.channel.max_reg_power = channel->max_reg_power * 2; -+- arg.channel.max_antenna_gain = channel->max_antenna_gain; -++ arg.channel.max_antenna_gain = ath10k_get_max_antenna_gain(ar, -++ channel->max_antenna_gain); -+ -+ reinit_completion(&ar->vdev_setup_done); -+ reinit_completion(&ar->vdev_delete_done); -+@@ -1506,7 +1541,8 @@ static int ath10k_vdev_start_restart(str -+ arg.channel.min_power = 0; -+ arg.channel.max_power = chandef->chan->max_power * 2; -+ arg.channel.max_reg_power = chandef->chan->max_reg_power * 2; -+- arg.channel.max_antenna_gain = chandef->chan->max_antenna_gain; -++ arg.channel.max_antenna_gain = ath10k_get_max_antenna_gain(ar, -++ chandef->chan->max_antenna_gain); -+ -+ if (arvif->vdev_type == WMI_VDEV_TYPE_AP) { -+ arg.ssid = arvif->u.ap.ssid; -+@@ -3437,7 +3473,8 @@ static int ath10k_update_channel_list(st -+ ch->min_power = 0; -+ ch->max_power = channel->max_power * 2; -+ ch->max_reg_power = channel->max_reg_power * 2; -+- ch->max_antenna_gain = channel->max_antenna_gain; -++ ch->max_antenna_gain = ath10k_get_max_antenna_gain(ar, -++ channel->max_antenna_gain); -+ ch->reg_class_id = 0; /* FIXME */ -+ -+ /* FIXME: why use only legacy modes, why not any -diff --git a/package/kernel/mac80211/patches/ath10k/984-ath10k-Try-to-get-mac-address-from-dts.patch b/package/kernel/mac80211/patches/ath10k/984-ath10k-Try-to-get-mac-address-from-dts.patch -new file mode 100644 -index 0000000000..084e28a2d9 ---- /dev/null -+++ b/package/kernel/mac80211/patches/ath10k/984-ath10k-Try-to-get-mac-address-from-dts.patch -@@ -0,0 +1,37 @@ -+From 22fb5991a44c78ff18ec0082dc90c809356eb893 Mon Sep 17 00:00:00 2001 -+From: Ansuel Smith -+Date: Sun, 27 Sep 2020 19:23:35 +0200 -+Subject: [PATCH 1/2] ath10k: Try to get mac-address from dts -+ -+Most of embedded device that have the ath10k wifi integrated store the -+mac-address in nvmem partitions. Try to fetch the mac-address using the -+standard 'of_get_mac_address' than in all the check also try to fetch the -+address using the nvmem api searching for a defined 'mac-address' cell. -+Mac-address defined in the dts have priority than any other address found. -+ -+Tested-on: QCA9984 hw1.0 PCI 10.4 -+ -+Signed-off-by: Ansuel Smith -+--- -+ drivers/net/wireless/ath/ath10k/core.c | 10 ++++++++++ -+ 1 file changed, 10 insertions(+) -+ -+--- a/drivers/net/wireless/ath/ath10k/core.c -++++ b/drivers/net/wireless/ath/ath10k/core.c -+@@ -8,6 +8,7 @@ -+ #include -+ #include -+ #include -++#include -+ #include -+ #include -+ #include -+@@ -3407,6 +3408,8 @@ static int ath10k_core_probe_fw(struct a -+ -+ device_get_mac_address(ar->dev, ar->mac_addr); -+ -++ of_get_mac_address(ar->dev->of_node, ar->mac_addr); -++ -+ ret = ath10k_core_init_firmware_features(ar); -+ if (ret) { -+ ath10k_err(ar, "fatal problem with firmware features: %d\n", -diff --git a/package/kernel/mac80211/patches/ath10k/988-ath10k-always-use-mac80211-loss-detection.patch b/package/kernel/mac80211/patches/ath10k/988-ath10k-always-use-mac80211-loss-detection.patch -new file mode 100644 -index 0000000000..f025fea63b ---- /dev/null -+++ b/package/kernel/mac80211/patches/ath10k/988-ath10k-always-use-mac80211-loss-detection.patch -@@ -0,0 +1,28 @@ -+From f7d6edafe4358e3880a26775cfde4cd5c71ba063 Mon Sep 17 00:00:00 2001 -+From: David Bauer -+Date: Wed, 5 Jul 2023 01:30:29 +0200 -+Subject: [PATCH] ath10k: always use mac80211 loss detection -+ -+ath10k does not report excessive loss in case of broken block-ack -+sessions. The loss is communicated to the host-os, but ath10k does not -+trigger a low-ack events by itself. -+ -+The mac80211 framework for loss detection however detects this -+circumstance well in case of ath10k. So use it regardless of ath10k's -+own loss detection mechanism. -+ -+Signed-off-by: David Bauer -+--- -+ drivers/net/wireless/ath/ath10k/mac.c | 1 - -+ 1 file changed, 1 deletion(-) -+ -+--- a/drivers/net/wireless/ath/ath10k/mac.c -++++ b/drivers/net/wireless/ath/ath10k/mac.c -+@@ -10080,7 +10080,6 @@ int ath10k_mac_register(struct ath10k *a -+ ieee80211_hw_set(ar->hw, CHANCTX_STA_CSA); -+ ieee80211_hw_set(ar->hw, QUEUE_CONTROL); -+ ieee80211_hw_set(ar->hw, SUPPORTS_TX_FRAG); -+- ieee80211_hw_set(ar->hw, REPORTS_LOW_ACK); -+ -+ if (!test_bit(ATH10K_FLAG_RAW_MODE, &ar->dev_flags)) -+ ieee80211_hw_set(ar->hw, SW_CRYPTO_CONTROL); -diff --git a/package/kernel/mac80211/patches/ath10k/990-ath10k-small-buffers.patch b/package/kernel/mac80211/patches/ath10k/990-ath10k-small-buffers.patch -new file mode 100644 -index 0000000000..2f560c70a0 ---- /dev/null -+++ b/package/kernel/mac80211/patches/ath10k/990-ath10k-small-buffers.patch -@@ -0,0 +1,64 @@ -+--- a/drivers/net/wireless/ath/ath10k/htt.h -++++ b/drivers/net/wireless/ath/ath10k/htt.h -+@@ -235,7 +235,11 @@ enum htt_rx_ring_flags { -+ }; -+ -+ #define HTT_RX_RING_SIZE_MIN 128 -++#ifndef CONFIG_ATH10K_SMALLBUFFERS -+ #define HTT_RX_RING_SIZE_MAX 2048 -++#else -++#define HTT_RX_RING_SIZE_MAX 512 -++#endif -+ #define HTT_RX_RING_SIZE HTT_RX_RING_SIZE_MAX -+ #define HTT_RX_RING_FILL_LEVEL (((HTT_RX_RING_SIZE) / 2) - 1) -+ #define HTT_RX_RING_FILL_LEVEL_DUAL_MAC (HTT_RX_RING_SIZE - 1) -+--- a/drivers/net/wireless/ath/ath10k/pci.c -++++ b/drivers/net/wireless/ath/ath10k/pci.c -+@@ -131,7 +131,11 @@ static const struct ce_attr pci_host_ce_ -+ .flags = CE_ATTR_FLAGS, -+ .src_nentries = 0, -+ .src_sz_max = 2048, -++#ifndef CONFIG_ATH10K_SMALLBUFFERS -+ .dest_nentries = 512, -++#else -++ .dest_nentries = 128, -++#endif -+ .recv_cb = ath10k_pci_htt_htc_rx_cb, -+ }, -+ -+@@ -140,7 +144,11 @@ static const struct ce_attr pci_host_ce_ -+ .flags = CE_ATTR_FLAGS, -+ .src_nentries = 0, -+ .src_sz_max = 2048, -++#ifndef CONFIG_ATH10K_SMALLBUFFERS -+ .dest_nentries = 128, -++#else -++ .dest_nentries = 64, -++#endif -+ .recv_cb = ath10k_pci_htc_rx_cb, -+ }, -+ -+@@ -167,7 +175,11 @@ static const struct ce_attr pci_host_ce_ -+ .flags = CE_ATTR_FLAGS, -+ .src_nentries = 0, -+ .src_sz_max = 512, -++#ifndef CONFIG_ATH10K_SMALLBUFFERS -+ .dest_nentries = 512, -++#else -++ .dest_nentries = 128, -++#endif -+ .recv_cb = ath10k_pci_htt_rx_cb, -+ }, -+ -+@@ -192,7 +204,11 @@ static const struct ce_attr pci_host_ce_ -+ .flags = CE_ATTR_FLAGS, -+ .src_nentries = 0, -+ .src_sz_max = 2048, -++#ifndef CONFIG_ATH10K_SMALLBUFFERS -+ .dest_nentries = 128, -++#else -++ .dest_nentries = 96, -++#endif -+ .recv_cb = ath10k_pci_pktlog_rx_cb, -+ }, -+ -diff --git a/package/kernel/mac80211/patches/ath11k/0001-wifi-ath11k-stop-tx-queues-immediately-upon-firmware.patch b/package/kernel/mac80211/patches/ath11k/0001-wifi-ath11k-stop-tx-queues-immediately-upon-firmware.patch -new file mode 100644 -index 0000000000..d0dc04febf ---- /dev/null -+++ b/package/kernel/mac80211/patches/ath11k/0001-wifi-ath11k-stop-tx-queues-immediately-upon-firmware.patch -@@ -0,0 +1,78 @@ -+From 81e60b2dfb2744ab6642c4aa62534b4f711fdc5d Mon Sep 17 00:00:00 2001 -+From: Aditya Kumar Singh -+Date: Tue, 27 Sep 2022 09:18:54 +0300 -+Subject: [PATCH] wifi: ath11k: stop tx queues immediately upon firmware exit -+ -+Currently, recovery flag is set immediately upon firmware -+exit but tx queues are stopped once firmware arrives back -+and is ready which is during ath11k_core_restart. Once -+ieee80211 hw restart is completed, tx queues are resumed. -+If during the time delta between firmware exit and firmware -+ready, mac80211 send packets, currently ath11k will drop it -+since recovery flag will be set. But warning prints will -+come - -+ "ath11k c000000.wifi: failed to transmit frame -108" -+ -+If more tx packets are there, this could lead to flooding -+of above print. -+ -+However, actually tx queues should be stopped immediately -+when firmware leaves. This will prevent packets to get -+dropped when firmware is recovering. -+ -+Add fix to stop tx queues immediately after firmware exit. -+ -+Tested-on: IPQ8074 hw2.0 AHB WLAN.HK.2.5.0.1-01100-QCAHKSWPL_SILICONZ-1 -+ -+Signed-off-by: Aditya Kumar Singh -+Signed-off-by: Kalle Valo -+Link: https://lore.kernel.org/r/20220923170235.18873-1-quic_adisi@quicinc.com -+--- -+ drivers/net/wireless/ath/ath11k/core.c | 5 +---- -+ drivers/net/wireless/ath/ath11k/core.h | 1 + -+ drivers/net/wireless/ath/ath11k/qmi.c | 3 +++ -+ 3 files changed, 5 insertions(+), 4 deletions(-) -+ -+--- a/drivers/net/wireless/ath/ath11k/core.c -++++ b/drivers/net/wireless/ath/ath11k/core.c -+@@ -1641,7 +1641,7 @@ static void ath11k_update_11d(struct wor -+ } -+ } -+ -+-static void ath11k_core_pre_reconfigure_recovery(struct ath11k_base *ab) -++void ath11k_core_pre_reconfigure_recovery(struct ath11k_base *ab) -+ { -+ struct ath11k *ar; -+ struct ath11k_pdev *pdev; -+@@ -1730,9 +1730,6 @@ static void ath11k_core_restart(struct w -+ struct ath11k_base *ab = container_of(work, struct ath11k_base, restart_work); -+ int ret; -+ -+- if (!ab->is_reset) -+- ath11k_core_pre_reconfigure_recovery(ab); -+- -+ ret = ath11k_core_reconfigure_on_crash(ab); -+ if (ret) { -+ ath11k_err(ab, "failed to reconfigure driver on crash recovery\n"); -+--- a/drivers/net/wireless/ath/ath11k/core.h -++++ b/drivers/net/wireless/ath/ath11k/core.h -+@@ -1158,6 +1158,7 @@ int ath11k_core_check_smbios(struct ath1 -+ void ath11k_core_halt(struct ath11k *ar); -+ int ath11k_core_resume(struct ath11k_base *ab); -+ int ath11k_core_suspend(struct ath11k_base *ab); -++void ath11k_core_pre_reconfigure_recovery(struct ath11k_base *ab); -+ -+ const struct firmware *ath11k_core_firmware_request(struct ath11k_base *ab, -+ const char *filename); -+--- a/drivers/net/wireless/ath/ath11k/qmi.c -++++ b/drivers/net/wireless/ath/ath11k/qmi.c -+@@ -3164,6 +3164,9 @@ static void ath11k_qmi_driver_event_work -+ case ATH11K_QMI_EVENT_SERVER_EXIT: -+ set_bit(ATH11K_FLAG_CRASH_FLUSH, &ab->dev_flags); -+ set_bit(ATH11K_FLAG_RECOVERY, &ab->dev_flags); -++ -++ if (!ab->is_reset) -++ ath11k_core_pre_reconfigure_recovery(ab); -+ break; -+ case ATH11K_QMI_EVENT_REQUEST_MEM: -+ ret = ath11k_qmi_event_mem_request(qmi); -diff --git a/package/kernel/mac80211/patches/ath11k/0002-wifi-ath11k-Don-t-exit-on-wakeup-failure.patch b/package/kernel/mac80211/patches/ath11k/0002-wifi-ath11k-Don-t-exit-on-wakeup-failure.patch -new file mode 100644 -index 0000000000..47385e0458 ---- /dev/null -+++ b/package/kernel/mac80211/patches/ath11k/0002-wifi-ath11k-Don-t-exit-on-wakeup-failure.patch -@@ -0,0 +1,45 @@ -+From 45d2e268369b0c768d5a644f319758bcfd370521 Mon Sep 17 00:00:00 2001 -+From: Baochen Qiang -+Date: Wed, 28 Sep 2022 09:51:40 +0800 -+Subject: [PATCH] wifi: ath11k: Don't exit on wakeup failure -+ -+Currently, ath11k_pcic_read() returns an error if wakeup() -+fails, this makes firmware crash debug quite hard because we can -+get nothing. -+ -+Change to go ahead on wakeup failure, in that case we still may -+get something valid to check. There should be no mislead due -+to incorrect content because we are aware of the failure with the -+log printed. -+ -+Tested-on: WCN6855 hw2.0 PCI WLAN.HSP.1.1-01720.1-QCAHSPSWPL_V1_V2_SILICONZ_LITE-1 -+ -+Signed-off-by: Baochen Qiang -+Signed-off-by: Kalle Valo -+Link: https://lore.kernel.org/r/20220928015140.5431-1-quic_bqiang@quicinc.com -+--- -+ drivers/net/wireless/ath/ath11k/pcic.c | 13 ++++++++++--- -+ 1 file changed, 10 insertions(+), 3 deletions(-) -+ -+--- a/drivers/net/wireless/ath/ath11k/pcic.c -++++ b/drivers/net/wireless/ath/ath11k/pcic.c -+@@ -218,9 +218,16 @@ int ath11k_pcic_read(struct ath11k_base -+ if (wakeup_required && ab->pci.ops->wakeup) { -+ ret = ab->pci.ops->wakeup(ab); -+ if (ret) { -+- ath11k_warn(ab, "failed to wakeup for read from 0x%x: %d\n", -+- start, ret); -+- return ret; -++ ath11k_warn(ab, -++ "wakeup failed, data may be invalid: %d", -++ ret); -++ /* Even though wakeup() failed, continue processing rather -++ * than returning because some parts of the data may still -++ * be valid and useful in some cases, e.g. could give us -++ * some clues on firmware crash. -++ * Mislead due to invalid data could be avoided because we -++ * are aware of the wakeup failure. -++ */ -+ } -+ } -+ -diff --git a/package/kernel/mac80211/patches/ath11k/0005-wifi-ath11k-Fix-spelling-mistake-chnange-change.patch b/package/kernel/mac80211/patches/ath11k/0005-wifi-ath11k-Fix-spelling-mistake-chnange-change.patch -new file mode 100644 -index 0000000000..4b52252ef3 ---- /dev/null -+++ b/package/kernel/mac80211/patches/ath11k/0005-wifi-ath11k-Fix-spelling-mistake-chnange-change.patch -@@ -0,0 +1,25 @@ -+From a797f479bf3e02c6d179c2e6aeace7f9b22b0acd Mon Sep 17 00:00:00 2001 -+From: Colin Ian King -+Date: Wed, 28 Sep 2022 15:38:34 +0100 -+Subject: [PATCH] wifi: ath11k: Fix spelling mistake "chnange" -> "change" -+ -+There is a spelling mistake in an ath11k_dbg debug message. Fix it. -+ -+Signed-off-by: Colin Ian King -+Signed-off-by: Kalle Valo -+Link: https://lore.kernel.org/r/20220928143834.35189-1-colin.i.king@gmail.com -+--- -+ drivers/net/wireless/ath/ath11k/wmi.c | 2 +- -+ 1 file changed, 1 insertion(+), 1 deletion(-) -+ -+--- a/drivers/net/wireless/ath/ath11k/wmi.c -++++ b/drivers/net/wireless/ath/ath11k/wmi.c -+@@ -6829,7 +6829,7 @@ static void ath11k_wmi_event_peer_sta_ps -+ } -+ -+ ath11k_dbg(ab, ATH11K_DBG_WMI, -+- "peer sta ps chnange ev addr %pM state %u sup_bitmap %x ps_valid %u ts %u\n", -++ "peer sta ps change ev addr %pM state %u sup_bitmap %x ps_valid %u ts %u\n", -+ ev->peer_macaddr.addr, ev->peer_ps_state, -+ ev->ps_supported_bitmap, ev->peer_ps_valid, -+ ev->peer_ps_timestamp); -diff --git a/package/kernel/mac80211/patches/ath11k/0007-wifi-ath11k-suppress-add-interface-error.patch b/package/kernel/mac80211/patches/ath11k/0007-wifi-ath11k-suppress-add-interface-error.patch -new file mode 100644 -index 0000000000..fbef0abb8d ---- /dev/null -+++ b/package/kernel/mac80211/patches/ath11k/0007-wifi-ath11k-suppress-add-interface-error.patch -@@ -0,0 +1,52 @@ -+From 638b26652b0438563a76ec90014c8cba34db982b Mon Sep 17 00:00:00 2001 -+From: Karthikeyan Periyasamy -+Date: Thu, 6 Oct 2022 06:28:42 +0530 -+Subject: [PATCH 7/9] wifi: ath11k: suppress add interface error -+ -+In the VIF (other than monitor type) creation request, we should not -+throw the error code when the monitor VIF creation fails, since the -+actual VIF creation succeeds. If we throw the error code from driver -+then the actual VIF creation get fail. So suppress the monitor VIF -+creation error by throwing warning message instead of error code. -+ -+Tested-on: QCN9074 hw1.0 PCI WLAN.HK.2.6.0.1-00760-QCAHKSWPL_SILICONZ-1 -+ -+Signed-off-by: Karthikeyan Periyasamy -+Signed-off-by: Kalle Valo -+Link: https://lore.kernel.org/r/20221006005842.8599-1-quic_periyasa@quicinc.com -+--- -+ drivers/net/wireless/ath/ath11k/mac.c | 9 +++------ -+ 1 file changed, 3 insertions(+), 6 deletions(-) -+ -+--- a/drivers/net/wireless/ath/ath11k/mac.c -++++ b/drivers/net/wireless/ath/ath11k/mac.c -+@@ -6421,18 +6421,16 @@ static int ath11k_mac_op_add_interface(s -+ -+ ath11k_dp_vdev_tx_attach(ar, arvif); -+ -++ ath11k_debugfs_add_interface(arvif); -++ -+ if (vif->type != NL80211_IFTYPE_MONITOR && -+ test_bit(ATH11K_FLAG_MONITOR_CONF_ENABLED, &ar->monitor_flags)) { -+ ret = ath11k_mac_monitor_vdev_create(ar); -+- if (ret) { -++ if (ret) -+ ath11k_warn(ar->ab, "failed to create monitor vdev during add interface: %d", -+ ret); -+- goto err_peer_del; -+- } -+ } -+ -+- ath11k_debugfs_add_interface(arvif); -+- -+ mutex_unlock(&ar->conf_mutex); -+ -+ return 0; -+@@ -6457,7 +6455,6 @@ err_vdev_del: -+ spin_unlock_bh(&ar->data_lock); -+ -+ err: -+- ath11k_debugfs_remove_interface(arvif); -+ mutex_unlock(&ar->conf_mutex); -+ -+ return ret; -diff --git a/package/kernel/mac80211/patches/ath11k/0008-wifi-ath11k-add-support-to-configure-channel-dwell-t.patch b/package/kernel/mac80211/patches/ath11k/0008-wifi-ath11k-add-support-to-configure-channel-dwell-t.patch -new file mode 100644 -index 0000000000..d0b19fe59f ---- /dev/null -+++ b/package/kernel/mac80211/patches/ath11k/0008-wifi-ath11k-add-support-to-configure-channel-dwell-t.patch -@@ -0,0 +1,102 @@ -+From c362daa213cdeb0a9e7c2ed84849544c24505720 Mon Sep 17 00:00:00 2001 -+From: Manikanta Pubbisetty -+Date: Fri, 7 Oct 2022 10:41:30 +0530 -+Subject: [PATCH 8/9] wifi: ath11k: add support to configure channel dwell time -+ -+Add support to configure channel dwell time during scan. -+Dwell time help to stay on the channel for a specified duration -+during scan and aid userspace in finding WiFi networks. Very -+useful in passive scans where longer dwell times are needed -+to find the WiFi networks. -+ -+Configure channel dwell time from duration of the scan request -+received from mac80211 when the duration is non-zero. When the -+scan request does not have duration value, use the default ones, -+the current implementation. -+ -+Advertise corresponding feature flag NL80211_EXT_FEATURE_SET_SCAN_DWELL -+to enable the feature. -+ -+Change is applicable for all ath11k hardware. -+ -+Tested-on: WCN6750 hw1.0 AHB WLAN.MSL.1.0.1-00887-QCAMSLSWPLZ-1 -+ -+Signed-off-by: Manikanta Pubbisetty -+Reviewed-by: Jeff Johnson -+Signed-off-by: Kalle Valo -+Link: https://lore.kernel.org/r/20221007051130.6067-1-quic_mpubbise@quicinc.com -+--- -+ drivers/net/wireless/ath/ath11k/mac.c | 33 +++++++++++++++++++++++---- -+ 1 file changed, 29 insertions(+), 4 deletions(-) -+ -+--- a/drivers/net/wireless/ath/ath11k/mac.c -++++ b/drivers/net/wireless/ath/ath11k/mac.c -+@@ -241,7 +241,10 @@ const struct htt_rx_ring_tlv_filter ath1 -+ #define ath11k_a_rates (ath11k_legacy_rates + 4) -+ #define ath11k_a_rates_size (ARRAY_SIZE(ath11k_legacy_rates) - 4) -+ -+-#define ATH11K_MAC_SCAN_TIMEOUT_MSECS 200 /* in msecs */ -++#define ATH11K_MAC_SCAN_CMD_EVT_OVERHEAD 200 /* in msecs */ -++ -++/* Overhead due to the processing of channel switch events from FW */ -++#define ATH11K_SCAN_CHANNEL_SWITCH_WMI_EVT_OVERHEAD 10 /* in msecs */ -+ -+ static const u32 ath11k_smps_map[] = { -+ [WLAN_HT_CAP_SM_PS_STATIC] = WMI_PEER_SMPS_STATIC, -+@@ -3612,6 +3615,7 @@ static int ath11k_mac_op_hw_scan(struct -+ struct scan_req_params arg; -+ int ret = 0; -+ int i; -++ u32 scan_timeout; -+ -+ mutex_lock(&ar->conf_mutex); -+ -+@@ -3681,6 +3685,26 @@ static int ath11k_mac_op_hw_scan(struct -+ ether_addr_copy(arg.mac_mask.addr, req->mac_addr_mask); -+ } -+ -++ /* if duration is set, default dwell times will be overwritten */ -++ if (req->duration) { -++ arg.dwell_time_active = req->duration; -++ arg.dwell_time_active_2g = req->duration; -++ arg.dwell_time_active_6g = req->duration; -++ arg.dwell_time_passive = req->duration; -++ arg.dwell_time_passive_6g = req->duration; -++ arg.burst_duration = req->duration; -++ -++ scan_timeout = min_t(u32, arg.max_rest_time * -++ (arg.num_chan - 1) + (req->duration + -++ ATH11K_SCAN_CHANNEL_SWITCH_WMI_EVT_OVERHEAD) * -++ arg.num_chan, arg.max_scan_time); -++ } else { -++ scan_timeout = arg.max_scan_time; -++ } -++ -++ /* Add a margin to account for event/command processing */ -++ scan_timeout += ATH11K_MAC_SCAN_CMD_EVT_OVERHEAD; -++ -+ ret = ath11k_start_scan(ar, &arg); -+ if (ret) { -+ ath11k_warn(ar->ab, "failed to start hw scan: %d\n", ret); -+@@ -3689,10 +3713,8 @@ static int ath11k_mac_op_hw_scan(struct -+ spin_unlock_bh(&ar->data_lock); -+ } -+ -+- /* Add a 200ms margin to account for event/command processing */ -+ ieee80211_queue_delayed_work(ar->hw, &ar->scan.timeout, -+- msecs_to_jiffies(arg.max_scan_time + -+- ATH11K_MAC_SCAN_TIMEOUT_MSECS)); -++ msecs_to_jiffies(scan_timeout)); -+ -+ exit: -+ kfree(arg.chan_list); -+@@ -9060,6 +9082,9 @@ static int __ath11k_mac_register(struct -+ NL80211_EXT_FEATURE_UNSOL_BCAST_PROBE_RESP); -+ } -+ -++ wiphy_ext_feature_set(ar->hw->wiphy, -++ NL80211_EXT_FEATURE_SET_SCAN_DWELL); -++ -+ ath11k_reg_init(ar); -+ -+ if (!test_bit(ATH11K_FLAG_RAW_MODE, &ab->dev_flags)) { -diff --git a/package/kernel/mac80211/patches/ath11k/0010-wifi-ath11k-Fix-firmware-crash-on-vdev-delete-race-c.patch b/package/kernel/mac80211/patches/ath11k/0010-wifi-ath11k-Fix-firmware-crash-on-vdev-delete-race-c.patch -new file mode 100644 -index 0000000000..7275af06ea ---- /dev/null -+++ b/package/kernel/mac80211/patches/ath11k/0010-wifi-ath11k-Fix-firmware-crash-on-vdev-delete-race-c.patch -@@ -0,0 +1,116 @@ -+From 3811fa1f231f1a3e29759efef4992116604aab8b Mon Sep 17 00:00:00 2001 -+From: Sowmiya Sree Elavalagan -+Date: Tue, 11 Oct 2022 15:23:46 +0530 -+Subject: [PATCH] wifi: ath11k: Fix firmware crash on vdev delete race -+ condition -+ -+Current code does not wait for vdev delete completion on vdev create -+failures and tries to send another vdev create followed by vdev set -+param to firmware with same vdev id. This causes firmware crash. -+Fix this crash by waiting for vdev delete completion on vdev -+create failures. -+ -+Tested-on: IPQ8074 hw2.0 AHB WLAN.HK.2.6.0.1-00905-QCAHKSWPL_SILICONZ-1 -+ -+Signed-off-by: Sowmiya Sree Elavalagan -+Signed-off-by: Kalle Valo -+Link: https://lore.kernel.org/r/20221011095346.3901-1-quic_ssreeela@quicinc.com -+--- -+ drivers/net/wireless/ath/ath11k/mac.c | 60 +++++++++++++++++---------- -+ 1 file changed, 37 insertions(+), 23 deletions(-) -+ -+--- a/drivers/net/wireless/ath/ath11k/mac.c -++++ b/drivers/net/wireless/ath/ath11k/mac.c -+@@ -6233,6 +6233,40 @@ void ath11k_mac_11d_scan_stop_all(struct -+ } -+ } -+ -++static int ath11k_mac_vdev_delete(struct ath11k *ar, struct ath11k_vif *arvif) -++{ -++ unsigned long time_left; -++ struct ieee80211_vif *vif = arvif->vif; -++ int ret = 0; -++ -++ lockdep_assert_held(&ar->conf_mutex); -++ -++ reinit_completion(&ar->vdev_delete_done); -++ -++ ret = ath11k_wmi_vdev_delete(ar, arvif->vdev_id); -++ if (ret) { -++ ath11k_warn(ar->ab, "failed to delete WMI vdev %d: %d\n", -++ arvif->vdev_id, ret); -++ return ret; -++ } -++ -++ time_left = wait_for_completion_timeout(&ar->vdev_delete_done, -++ ATH11K_VDEV_DELETE_TIMEOUT_HZ); -++ if (time_left == 0) { -++ ath11k_warn(ar->ab, "Timeout in receiving vdev delete response\n"); -++ return -ETIMEDOUT; -++ } -++ -++ ar->ab->free_vdev_map |= 1LL << (arvif->vdev_id); -++ ar->allocated_vdev_map &= ~(1LL << arvif->vdev_id); -++ ar->num_created_vdevs--; -++ -++ ath11k_dbg(ar->ab, ATH11K_DBG_MAC, "vdev %pM deleted, vdev_id %d\n", -++ vif->addr, arvif->vdev_id); -++ -++ return ret; -++} -++ -+ static int ath11k_mac_op_add_interface(struct ieee80211_hw *hw, -+ struct ieee80211_vif *vif) -+ { -+@@ -6468,10 +6502,7 @@ err_peer_del: -+ } -+ -+ err_vdev_del: -+- ath11k_wmi_vdev_delete(ar, arvif->vdev_id); -+- ar->num_created_vdevs--; -+- ar->allocated_vdev_map &= ~(1LL << arvif->vdev_id); -+- ab->free_vdev_map |= 1LL << arvif->vdev_id; -++ ath11k_mac_vdev_delete(ar, arvif); -+ spin_lock_bh(&ar->data_lock); -+ list_del(&arvif->list); -+ spin_unlock_bh(&ar->data_lock); -+@@ -6499,7 +6530,6 @@ 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; -+- unsigned long time_left; -+ int ret; -+ int i; -+ -+@@ -6520,29 +6550,13 @@ static void ath11k_mac_op_remove_interfa -+ arvif->vdev_id, ret); -+ } -+ -+- reinit_completion(&ar->vdev_delete_done); -+- -+- ret = ath11k_wmi_vdev_delete(ar, arvif->vdev_id); -++ ret = ath11k_mac_vdev_delete(ar, arvif); -+ if (ret) { -+- ath11k_warn(ab, "failed to delete WMI vdev %d: %d\n", -++ ath11k_warn(ab, "failed to delete vdev %d: %d\n", -+ arvif->vdev_id, ret); -+ goto err_vdev_del; -+ } -+ -+- time_left = wait_for_completion_timeout(&ar->vdev_delete_done, -+- ATH11K_VDEV_DELETE_TIMEOUT_HZ); -+- if (time_left == 0) { -+- ath11k_warn(ab, "Timeout in receiving vdev delete response\n"); -+- goto err_vdev_del; -+- } -+- -+- ab->free_vdev_map |= 1LL << (arvif->vdev_id); -+- ar->allocated_vdev_map &= ~(1LL << arvif->vdev_id); -+- ar->num_created_vdevs--; -+- -+- ath11k_dbg(ab, ATH11K_DBG_MAC, "vdev %pM deleted, vdev_id %d\n", -+- vif->addr, arvif->vdev_id); -+- -+ if (arvif->vdev_type == WMI_VDEV_TYPE_MONITOR) { -+ clear_bit(ATH11K_FLAG_MONITOR_VDEV_CREATED, &ar->monitor_flags); -+ ar->monitor_vdev_id = -1; -diff --git a/package/kernel/mac80211/patches/ath11k/0011-wifi-ath11k-fix-monitor-vdev-creation-with-firmware-.patch b/package/kernel/mac80211/patches/ath11k/0011-wifi-ath11k-fix-monitor-vdev-creation-with-firmware-.patch -new file mode 100644 -index 0000000000..2f066d0a56 ---- /dev/null -+++ b/package/kernel/mac80211/patches/ath11k/0011-wifi-ath11k-fix-monitor-vdev-creation-with-firmware-.patch -@@ -0,0 +1,40 @@ -+From f3ca72b0327101a074a871539e61775d43908ca4 Mon Sep 17 00:00:00 2001 -+From: Nagarajan Maran -+Date: Fri, 14 Oct 2022 21:20:54 +0530 -+Subject: [PATCH] wifi: ath11k: fix monitor vdev creation with firmware -+ recovery -+ -+During firmware recovery, the monitor interface is not -+getting created in the driver and firmware since -+the respective flags are not updated properly. -+ -+So after firmware recovery is successful, when monitor -+interface is brought down manually, firmware assertion -+is observed, since we are trying to bring down the -+interface which is not yet created in the firmware. -+ -+Fix this by updating the monitor flags properly per -+phy#, during firmware recovery. -+ -+Tested-on: IPQ8074 hw2.0 AHB WLAN.HK.2.7.0.1-01744-QCAHKSWPL_SILICONZ-1 -+ -+Signed-off-by: Nagarajan Maran -+Signed-off-by: Kalle Valo -+Link: https://lore.kernel.org/r/20221014155054.11471-1-quic_nmaran@quicinc.com -+--- -+ drivers/net/wireless/ath/ath11k/core.c | 4 ++++ -+ 1 file changed, 4 insertions(+) -+ -+--- a/drivers/net/wireless/ath/ath11k/core.c -++++ b/drivers/net/wireless/ath/ath11k/core.c -+@@ -1677,6 +1677,10 @@ void ath11k_core_pre_reconfigure_recover -+ ath11k_mac_tx_mgmt_pending_free, ar); -+ idr_destroy(&ar->txmgmt_idr); -+ wake_up(&ar->txmgmt_empty_waitq); -++ -++ ar->monitor_vdev_id = -1; -++ clear_bit(ATH11K_FLAG_MONITOR_STARTED, &ar->monitor_flags); -++ clear_bit(ATH11K_FLAG_MONITOR_VDEV_CREATED, &ar->monitor_flags); -+ } -+ -+ wake_up(&ab->wmi_ab.tx_credits_wq); -diff --git a/package/kernel/mac80211/patches/ath11k/0012-wifi-ath11k-Fix-qmi_msg_handler-data-structure-initi.patch b/package/kernel/mac80211/patches/ath11k/0012-wifi-ath11k-Fix-qmi_msg_handler-data-structure-initi.patch -new file mode 100644 -index 0000000000..fccfa4385a ---- /dev/null -+++ b/package/kernel/mac80211/patches/ath11k/0012-wifi-ath11k-Fix-qmi_msg_handler-data-structure-initi.patch -@@ -0,0 +1,33 @@ -+From ed3725e15a154ebebf44e0c34806c57525483f92 Mon Sep 17 00:00:00 2001 -+From: Rahul Bhattacharjee -+Date: Fri, 21 Oct 2022 14:31:26 +0530 -+Subject: [PATCH] wifi: ath11k: Fix qmi_msg_handler data structure -+ initialization -+ -+qmi_msg_handler is required to be null terminated by QMI module. -+There might be a case where a handler for a msg id is not present in the -+handlers array which can lead to infinite loop while searching the handler -+and therefore out of bound access in qmi_invoke_handler(). -+Hence update the initialization in qmi_msg_handler data structure. -+ -+Tested-on: IPQ8074 hw2.0 AHB WLAN.HK.2.5.0.1-01100-QCAHKSWPL_SILICONZ-1 -+ -+Signed-off-by: Rahul Bhattacharjee -+Signed-off-by: Kalle Valo -+Link: https://lore.kernel.org/r/20221021090126.28626-1-quic_rbhattac@quicinc.com -+--- -+ drivers/net/wireless/ath/ath11k/qmi.c | 3 +++ -+ 1 file changed, 3 insertions(+) -+ -+--- a/drivers/net/wireless/ath/ath11k/qmi.c -++++ b/drivers/net/wireless/ath/ath11k/qmi.c -+@@ -1702,6 +1702,9 @@ static struct qmi_elem_info qmi_wlfw_fw_ -+ .data_type = QMI_EOTI, -+ .array_type = NO_ARRAY, -+ }, -++ -++ /* end of list */ -++ {}, -+ }; -+ -+ static int ath11k_qmi_host_cap_send(struct ath11k_base *ab) -diff --git a/package/kernel/mac80211/patches/ath11k/0013-wifi-ath11k-synchronize-ath11k_mac_he_gi_to_nl80211_.patch b/package/kernel/mac80211/patches/ath11k/0013-wifi-ath11k-synchronize-ath11k_mac_he_gi_to_nl80211_.patch -new file mode 100644 -index 0000000000..1e89b4d4f2 ---- /dev/null -+++ b/package/kernel/mac80211/patches/ath11k/0013-wifi-ath11k-synchronize-ath11k_mac_he_gi_to_nl80211_.patch -@@ -0,0 +1,42 @@ -+From dd1c2322694522f674c874f5fa02ac5ae39135dd Mon Sep 17 00:00:00 2001 -+From: "Jiri Slaby (SUSE)" -+Date: Mon, 31 Oct 2022 12:43:41 +0100 -+Subject: [PATCH] wifi: ath11k: synchronize -+ ath11k_mac_he_gi_to_nl80211_he_gi()'s return type -+ -+ath11k_mac_he_gi_to_nl80211_he_gi() generates a valid warning with gcc-13: -+ drivers/net/wireless/ath/ath11k/mac.c:321:20: error: conflicting types for 'ath11k_mac_he_gi_to_nl80211_he_gi' due to enum/integer mismatch; have 'enum nl80211_he_gi(u8)' -+ drivers/net/wireless/ath/ath11k/mac.h:166:5: note: previous declaration of 'ath11k_mac_he_gi_to_nl80211_he_gi' with type 'u32(u8)' -+ -+I.e. the type of the return value ath11k_mac_he_gi_to_nl80211_he_gi() in -+the declaration is u32, while the definition spells enum nl80211_he_gi. -+Synchronize them to the latter. -+ -+Cc: Martin Liska -+Cc: Kalle Valo -+Cc: "David S. Miller" -+Cc: Eric Dumazet -+Cc: Jakub Kicinski -+Cc: Paolo Abeni -+Cc: ath11k@lists.infradead.org -+Cc: linux-wireless@vger.kernel.org -+Cc: netdev@vger.kernel.org -+Signed-off-by: Jiri Slaby (SUSE) -+Reviewed-by: Jeff Johnson -+Signed-off-by: Kalle Valo -+Link: https://lore.kernel.org/r/20221031114341.10377-1-jirislaby@kernel.org -+--- -+ drivers/net/wireless/ath/ath11k/mac.h | 2 +- -+ 1 file changed, 1 insertion(+), 1 deletion(-) -+ -+--- a/drivers/net/wireless/ath/ath11k/mac.h -++++ b/drivers/net/wireless/ath/ath11k/mac.h -+@@ -163,7 +163,7 @@ void ath11k_mac_drain_tx(struct ath11k * -+ void ath11k_mac_peer_cleanup_all(struct ath11k *ar); -+ int ath11k_mac_tx_mgmt_pending_free(int buf_id, void *skb, void *ctx); -+ u8 ath11k_mac_bw_to_mac80211_bw(u8 bw); -+-u32 ath11k_mac_he_gi_to_nl80211_he_gi(u8 sgi); -++enum nl80211_he_gi ath11k_mac_he_gi_to_nl80211_he_gi(u8 sgi); -+ enum nl80211_he_ru_alloc ath11k_mac_phy_he_ru_to_nl80211_he_ru_alloc(u16 ru_phy); -+ enum nl80211_he_ru_alloc ath11k_mac_he_ru_tones_to_nl80211_he_ru_alloc(u16 ru_tones); -+ enum ath11k_supported_bw ath11k_mac_mac80211_bw_to_ath11k_bw(enum rate_info_bw bw); -diff --git a/package/kernel/mac80211/patches/ath11k/0016-wifi-ath11k-Make-QMI-message-rules-const.patch b/package/kernel/mac80211/patches/ath11k/0016-wifi-ath11k-Make-QMI-message-rules-const.patch -new file mode 100644 -index 0000000000..1f48df73f7 ---- /dev/null -+++ b/package/kernel/mac80211/patches/ath11k/0016-wifi-ath11k-Make-QMI-message-rules-const.patch -@@ -0,0 +1,341 @@ -+From 93c1592889fca46d09d833455628bab05516cdbf Mon Sep 17 00:00:00 2001 -+From: Jeff Johnson -+Date: Wed, 14 Sep 2022 17:23:03 -0700 -+Subject: [PATCH] wifi: ath11k: Make QMI message rules const -+ -+Commit ff6d365898d4 ("soc: qcom: qmi: use const for struct -+qmi_elem_info") allows QMI message encoding/decoding rules to be -+const, so do that for ath11k. -+ -+Compile tested only. -+ -+Signed-off-by: Jeff Johnson -+Signed-off-by: Kalle Valo -+Link: https://lore.kernel.org/r/20220915002303.12206-1-quic_jjohnson@quicinc.com -+--- -+ drivers/net/wireless/ath/ath11k/qmi.c | 72 +++++++++++++-------------- -+ 1 file changed, 36 insertions(+), 36 deletions(-) -+ -+--- a/drivers/net/wireless/ath/ath11k/qmi.c -++++ b/drivers/net/wireless/ath/ath11k/qmi.c -+@@ -29,7 +29,7 @@ module_param_named(cold_boot_cal, ath11k -+ MODULE_PARM_DESC(cold_boot_cal, -+ "Decrease the channel switch time but increase the driver load time (Default: true)"); -+ -+-static struct qmi_elem_info qmi_wlanfw_host_cap_req_msg_v01_ei[] = { -++static const struct qmi_elem_info qmi_wlanfw_host_cap_req_msg_v01_ei[] = { -+ { -+ .data_type = QMI_OPT_FLAG, -+ .elem_len = 1, -+@@ -280,7 +280,7 @@ static struct qmi_elem_info qmi_wlanfw_h -+ }, -+ }; -+ -+-static struct qmi_elem_info qmi_wlanfw_host_cap_resp_msg_v01_ei[] = { -++static const struct qmi_elem_info qmi_wlanfw_host_cap_resp_msg_v01_ei[] = { -+ { -+ .data_type = QMI_STRUCT, -+ .elem_len = 1, -+@@ -297,7 +297,7 @@ static struct qmi_elem_info qmi_wlanfw_h -+ }, -+ }; -+ -+-static struct qmi_elem_info qmi_wlanfw_ind_register_req_msg_v01_ei[] = { -++static const struct qmi_elem_info qmi_wlanfw_ind_register_req_msg_v01_ei[] = { -+ { -+ .data_type = QMI_OPT_FLAG, -+ .elem_len = 1, -+@@ -522,7 +522,7 @@ static struct qmi_elem_info qmi_wlanfw_i -+ }, -+ }; -+ -+-static struct qmi_elem_info qmi_wlanfw_ind_register_resp_msg_v01_ei[] = { -++static const struct qmi_elem_info qmi_wlanfw_ind_register_resp_msg_v01_ei[] = { -+ { -+ .data_type = QMI_STRUCT, -+ .elem_len = 1, -+@@ -558,7 +558,7 @@ static struct qmi_elem_info qmi_wlanfw_i -+ }, -+ }; -+ -+-static struct qmi_elem_info qmi_wlanfw_mem_cfg_s_v01_ei[] = { -++static const struct qmi_elem_info qmi_wlanfw_mem_cfg_s_v01_ei[] = { -+ { -+ .data_type = QMI_UNSIGNED_8_BYTE, -+ .elem_len = 1, -+@@ -590,7 +590,7 @@ static struct qmi_elem_info qmi_wlanfw_m -+ }, -+ }; -+ -+-static struct qmi_elem_info qmi_wlanfw_mem_seg_s_v01_ei[] = { -++static const struct qmi_elem_info qmi_wlanfw_mem_seg_s_v01_ei[] = { -+ { -+ .data_type = QMI_UNSIGNED_4_BYTE, -+ .elem_len = 1, -+@@ -632,7 +632,7 @@ static struct qmi_elem_info qmi_wlanfw_m -+ }, -+ }; -+ -+-static struct qmi_elem_info qmi_wlanfw_request_mem_ind_msg_v01_ei[] = { -++static const struct qmi_elem_info qmi_wlanfw_request_mem_ind_msg_v01_ei[] = { -+ { -+ .data_type = QMI_DATA_LEN, -+ .elem_len = 1, -+@@ -659,7 +659,7 @@ static struct qmi_elem_info qmi_wlanfw_r -+ }, -+ }; -+ -+-static struct qmi_elem_info qmi_wlanfw_mem_seg_resp_s_v01_ei[] = { -++static const struct qmi_elem_info qmi_wlanfw_mem_seg_resp_s_v01_ei[] = { -+ { -+ .data_type = QMI_UNSIGNED_8_BYTE, -+ .elem_len = 1, -+@@ -699,7 +699,7 @@ static struct qmi_elem_info qmi_wlanfw_m -+ }, -+ }; -+ -+-static struct qmi_elem_info qmi_wlanfw_respond_mem_req_msg_v01_ei[] = { -++static const struct qmi_elem_info qmi_wlanfw_respond_mem_req_msg_v01_ei[] = { -+ { -+ .data_type = QMI_DATA_LEN, -+ .elem_len = 1, -+@@ -726,7 +726,7 @@ static struct qmi_elem_info qmi_wlanfw_r -+ }, -+ }; -+ -+-static struct qmi_elem_info qmi_wlanfw_respond_mem_resp_msg_v01_ei[] = { -++static const struct qmi_elem_info qmi_wlanfw_respond_mem_resp_msg_v01_ei[] = { -+ { -+ .data_type = QMI_STRUCT, -+ .elem_len = 1, -+@@ -744,7 +744,7 @@ static struct qmi_elem_info qmi_wlanfw_r -+ }, -+ }; -+ -+-static struct qmi_elem_info qmi_wlanfw_cap_req_msg_v01_ei[] = { -++static const struct qmi_elem_info qmi_wlanfw_cap_req_msg_v01_ei[] = { -+ { -+ .data_type = QMI_EOTI, -+ .array_type = NO_ARRAY, -+@@ -752,7 +752,7 @@ static struct qmi_elem_info qmi_wlanfw_c -+ }, -+ }; -+ -+-static struct qmi_elem_info qmi_wlanfw_device_info_req_msg_v01_ei[] = { -++static const struct qmi_elem_info qmi_wlanfw_device_info_req_msg_v01_ei[] = { -+ { -+ .data_type = QMI_EOTI, -+ .array_type = NO_ARRAY, -+@@ -760,7 +760,7 @@ static struct qmi_elem_info qmi_wlanfw_d -+ }, -+ }; -+ -+-static struct qmi_elem_info qmi_wlfw_device_info_resp_msg_v01_ei[] = { -++static const struct qmi_elem_info qmi_wlfw_device_info_resp_msg_v01_ei[] = { -+ { -+ .data_type = QMI_STRUCT, -+ .elem_len = 1, -+@@ -814,7 +814,7 @@ static struct qmi_elem_info qmi_wlfw_dev -+ }, -+ }; -+ -+-static struct qmi_elem_info qmi_wlanfw_rf_chip_info_s_v01_ei[] = { -++static const struct qmi_elem_info qmi_wlanfw_rf_chip_info_s_v01_ei[] = { -+ { -+ .data_type = QMI_UNSIGNED_4_BYTE, -+ .elem_len = 1, -+@@ -840,7 +840,7 @@ static struct qmi_elem_info qmi_wlanfw_r -+ }, -+ }; -+ -+-static struct qmi_elem_info qmi_wlanfw_rf_board_info_s_v01_ei[] = { -++static const struct qmi_elem_info qmi_wlanfw_rf_board_info_s_v01_ei[] = { -+ { -+ .data_type = QMI_UNSIGNED_4_BYTE, -+ .elem_len = 1, -+@@ -857,7 +857,7 @@ static struct qmi_elem_info qmi_wlanfw_r -+ }, -+ }; -+ -+-static struct qmi_elem_info qmi_wlanfw_soc_info_s_v01_ei[] = { -++static const struct qmi_elem_info qmi_wlanfw_soc_info_s_v01_ei[] = { -+ { -+ .data_type = QMI_UNSIGNED_4_BYTE, -+ .elem_len = 1, -+@@ -873,7 +873,7 @@ static struct qmi_elem_info qmi_wlanfw_s -+ }, -+ }; -+ -+-static struct qmi_elem_info qmi_wlanfw_fw_version_info_s_v01_ei[] = { -++static const struct qmi_elem_info qmi_wlanfw_fw_version_info_s_v01_ei[] = { -+ { -+ .data_type = QMI_UNSIGNED_4_BYTE, -+ .elem_len = 1, -+@@ -899,7 +899,7 @@ static struct qmi_elem_info qmi_wlanfw_f -+ }, -+ }; -+ -+-static struct qmi_elem_info qmi_wlanfw_cap_resp_msg_v01_ei[] = { -++static const struct qmi_elem_info qmi_wlanfw_cap_resp_msg_v01_ei[] = { -+ { -+ .data_type = QMI_STRUCT, -+ .elem_len = 1, -+@@ -1100,7 +1100,7 @@ static struct qmi_elem_info qmi_wlanfw_c -+ }, -+ }; -+ -+-static struct qmi_elem_info qmi_wlanfw_bdf_download_req_msg_v01_ei[] = { -++static const struct qmi_elem_info qmi_wlanfw_bdf_download_req_msg_v01_ei[] = { -+ { -+ .data_type = QMI_UNSIGNED_1_BYTE, -+ .elem_len = 1, -+@@ -1235,7 +1235,7 @@ static struct qmi_elem_info qmi_wlanfw_b -+ }, -+ }; -+ -+-static struct qmi_elem_info qmi_wlanfw_bdf_download_resp_msg_v01_ei[] = { -++static const struct qmi_elem_info qmi_wlanfw_bdf_download_resp_msg_v01_ei[] = { -+ { -+ .data_type = QMI_STRUCT, -+ .elem_len = 1, -+@@ -1253,7 +1253,7 @@ static struct qmi_elem_info qmi_wlanfw_b -+ }, -+ }; -+ -+-static struct qmi_elem_info qmi_wlanfw_m3_info_req_msg_v01_ei[] = { -++static const struct qmi_elem_info qmi_wlanfw_m3_info_req_msg_v01_ei[] = { -+ { -+ .data_type = QMI_UNSIGNED_8_BYTE, -+ .elem_len = 1, -+@@ -1277,7 +1277,7 @@ static struct qmi_elem_info qmi_wlanfw_m -+ }, -+ }; -+ -+-static struct qmi_elem_info qmi_wlanfw_m3_info_resp_msg_v01_ei[] = { -++static const struct qmi_elem_info qmi_wlanfw_m3_info_resp_msg_v01_ei[] = { -+ { -+ .data_type = QMI_STRUCT, -+ .elem_len = 1, -+@@ -1294,7 +1294,7 @@ static struct qmi_elem_info qmi_wlanfw_m -+ }, -+ }; -+ -+-static struct qmi_elem_info qmi_wlanfw_ce_tgt_pipe_cfg_s_v01_ei[] = { -++static const struct qmi_elem_info qmi_wlanfw_ce_tgt_pipe_cfg_s_v01_ei[] = { -+ { -+ .data_type = QMI_UNSIGNED_4_BYTE, -+ .elem_len = 1, -+@@ -1347,7 +1347,7 @@ static struct qmi_elem_info qmi_wlanfw_c -+ }, -+ }; -+ -+-static struct qmi_elem_info qmi_wlanfw_ce_svc_pipe_cfg_s_v01_ei[] = { -++static const struct qmi_elem_info qmi_wlanfw_ce_svc_pipe_cfg_s_v01_ei[] = { -+ { -+ .data_type = QMI_UNSIGNED_4_BYTE, -+ .elem_len = 1, -+@@ -1382,7 +1382,7 @@ static struct qmi_elem_info qmi_wlanfw_c -+ }, -+ }; -+ -+-static struct qmi_elem_info qmi_wlanfw_shadow_reg_cfg_s_v01_ei[] = { -++static const struct qmi_elem_info qmi_wlanfw_shadow_reg_cfg_s_v01_ei[] = { -+ { -+ .data_type = QMI_UNSIGNED_2_BYTE, -+ .elem_len = 1, -+@@ -1406,7 +1406,7 @@ static struct qmi_elem_info qmi_wlanfw_s -+ }, -+ }; -+ -+-static struct qmi_elem_info qmi_wlanfw_shadow_reg_v2_cfg_s_v01_ei[] = { -++static const struct qmi_elem_info qmi_wlanfw_shadow_reg_v2_cfg_s_v01_ei[] = { -+ { -+ .data_type = QMI_UNSIGNED_4_BYTE, -+ .elem_len = 1, -+@@ -1423,7 +1423,7 @@ static struct qmi_elem_info qmi_wlanfw_s -+ }, -+ }; -+ -+-static struct qmi_elem_info qmi_wlanfw_wlan_mode_req_msg_v01_ei[] = { -++static const struct qmi_elem_info qmi_wlanfw_wlan_mode_req_msg_v01_ei[] = { -+ { -+ .data_type = QMI_UNSIGNED_4_BYTE, -+ .elem_len = 1, -+@@ -1458,7 +1458,7 @@ static struct qmi_elem_info qmi_wlanfw_w -+ }, -+ }; -+ -+-static struct qmi_elem_info qmi_wlanfw_wlan_mode_resp_msg_v01_ei[] = { -++static const struct qmi_elem_info qmi_wlanfw_wlan_mode_resp_msg_v01_ei[] = { -+ { -+ .data_type = QMI_STRUCT, -+ .elem_len = 1, -+@@ -1476,7 +1476,7 @@ static struct qmi_elem_info qmi_wlanfw_w -+ }, -+ }; -+ -+-static struct qmi_elem_info qmi_wlanfw_wlan_cfg_req_msg_v01_ei[] = { -++static const struct qmi_elem_info qmi_wlanfw_wlan_cfg_req_msg_v01_ei[] = { -+ { -+ .data_type = QMI_OPT_FLAG, -+ .elem_len = 1, -+@@ -1615,7 +1615,7 @@ static struct qmi_elem_info qmi_wlanfw_w -+ }, -+ }; -+ -+-static struct qmi_elem_info qmi_wlanfw_wlan_cfg_resp_msg_v01_ei[] = { -++static const struct qmi_elem_info qmi_wlanfw_wlan_cfg_resp_msg_v01_ei[] = { -+ { -+ .data_type = QMI_STRUCT, -+ .elem_len = 1, -+@@ -1632,28 +1632,28 @@ static struct qmi_elem_info qmi_wlanfw_w -+ }, -+ }; -+ -+-static struct qmi_elem_info qmi_wlanfw_mem_ready_ind_msg_v01_ei[] = { -++static const struct qmi_elem_info qmi_wlanfw_mem_ready_ind_msg_v01_ei[] = { -+ { -+ .data_type = QMI_EOTI, -+ .array_type = NO_ARRAY, -+ }, -+ }; -+ -+-static struct qmi_elem_info qmi_wlanfw_fw_ready_ind_msg_v01_ei[] = { -++static const struct qmi_elem_info qmi_wlanfw_fw_ready_ind_msg_v01_ei[] = { -+ { -+ .data_type = QMI_EOTI, -+ .array_type = NO_ARRAY, -+ }, -+ }; -+ -+-static struct qmi_elem_info qmi_wlanfw_cold_boot_cal_done_ind_msg_v01_ei[] = { -++static const struct qmi_elem_info qmi_wlanfw_cold_boot_cal_done_ind_msg_v01_ei[] = { -+ { -+ .data_type = QMI_EOTI, -+ .array_type = NO_ARRAY, -+ }, -+ }; -+ -+-static struct qmi_elem_info qmi_wlanfw_wlan_ini_req_msg_v01_ei[] = { -++static const struct qmi_elem_info qmi_wlanfw_wlan_ini_req_msg_v01_ei[] = { -+ { -+ .data_type = QMI_OPT_FLAG, -+ .elem_len = 1, -+@@ -1679,7 +1679,7 @@ static struct qmi_elem_info qmi_wlanfw_w -+ }, -+ }; -+ -+-static struct qmi_elem_info qmi_wlanfw_wlan_ini_resp_msg_v01_ei[] = { -++static const struct qmi_elem_info qmi_wlanfw_wlan_ini_resp_msg_v01_ei[] = { -+ { -+ .data_type = QMI_STRUCT, -+ .elem_len = 1, -+@@ -1697,7 +1697,7 @@ static struct qmi_elem_info qmi_wlanfw_w -+ }, -+ }; -+ -+-static struct qmi_elem_info qmi_wlfw_fw_init_done_ind_msg_v01_ei[] = { -++static const struct qmi_elem_info qmi_wlfw_fw_init_done_ind_msg_v01_ei[] = { -+ { -+ .data_type = QMI_EOTI, -+ .array_type = NO_ARRAY, -diff --git a/package/kernel/mac80211/patches/ath11k/0017-wifi-ath11k-Trigger-sta-disconnect-on-hardware-resta.patch b/package/kernel/mac80211/patches/ath11k/0017-wifi-ath11k-Trigger-sta-disconnect-on-hardware-resta.patch -new file mode 100644 -index 0000000000..f95e5027b2 ---- /dev/null -+++ b/package/kernel/mac80211/patches/ath11k/0017-wifi-ath11k-Trigger-sta-disconnect-on-hardware-resta.patch -@@ -0,0 +1,119 @@ -+From a018750a2cceaf4427c4ee3d9ce3e83a171d5bd6 Mon Sep 17 00:00:00 2001 -+From: Youghandhar Chintala -+Date: Fri, 4 Nov 2022 14:24:03 +0530 -+Subject: [PATCH] wifi: ath11k: Trigger sta disconnect on hardware restart -+ -+Currently after the hardware restart triggered from the driver, the -+station interface connection remains intact, since a disconnect trigger -+is not sent to userspace. This can lead to a problem in targets where -+the wifi mac sequence is added by the firmware. -+ -+After the target restart, its wifi mac sequence number gets reset to -+zero. Hence AP to which our device is connected will receive frames with -+a wifi mac sequence number jump to the past, thereby resulting in the -+AP dropping all these frames, until the frame arrives with a wifi mac -+sequence number which AP was expecting. -+ -+To avoid such frame drops, its better to trigger a station disconnect -+upon target hardware restart which can be done with API -+ieee80211_reconfig_disconnect exposed to mac80211. -+ -+The other targets are not affected by this change, since the hardware -+params flag is not set. -+ -+Reported-by: kernel test robot -+ -+Tested-on: WCN6750 hw1.0 AHB WLAN.MSL.1.0.1-00887-QCAMSLSWPLZ-1 -+ -+Signed-off-by: Youghandhar Chintala -+Signed-off-by: Kalle Valo -+Link: https://lore.kernel.org/r/20221104085403.11025-1-quic_youghand@quicinc.com -+--- -+ drivers/net/wireless/ath/ath11k/core.c | 6 ++++++ -+ drivers/net/wireless/ath/ath11k/hw.h | 1 + -+ drivers/net/wireless/ath/ath11k/mac.c | 7 +++++++ -+ 3 files changed, 14 insertions(+) -+ -+--- a/drivers/net/wireless/ath/ath11k/core.c -++++ b/drivers/net/wireless/ath/ath11k/core.c -+@@ -195,6 +195,7 @@ static const struct ath11k_hw_params ath -+ .tcl_ring_retry = true, -+ .tx_ring_size = DP_TCL_DATA_RING_SIZE, -+ .smp2p_wow_exit = false, -++ .support_fw_mac_sequence = false, -+ }, -+ { -+ .name = "qca6390 hw2.0", -+@@ -277,6 +278,7 @@ static const struct ath11k_hw_params ath -+ .tcl_ring_retry = true, -+ .tx_ring_size = DP_TCL_DATA_RING_SIZE, -+ .smp2p_wow_exit = false, -++ .support_fw_mac_sequence = true, -+ }, -+ { -+ .name = "qcn9074 hw1.0", -+@@ -356,6 +358,7 @@ static const struct ath11k_hw_params ath -+ .tcl_ring_retry = true, -+ .tx_ring_size = DP_TCL_DATA_RING_SIZE, -+ .smp2p_wow_exit = false, -++ .support_fw_mac_sequence = false, -+ }, -+ { -+ .name = "wcn6855 hw2.0", -+@@ -438,6 +441,7 @@ static const struct ath11k_hw_params ath -+ .tcl_ring_retry = true, -+ .tx_ring_size = DP_TCL_DATA_RING_SIZE, -+ .smp2p_wow_exit = false, -++ .support_fw_mac_sequence = true, -+ }, -+ { -+ .name = "wcn6855 hw2.1", -+@@ -519,6 +523,7 @@ static const struct ath11k_hw_params ath -+ .tcl_ring_retry = true, -+ .tx_ring_size = DP_TCL_DATA_RING_SIZE, -+ .smp2p_wow_exit = false, -++ .support_fw_mac_sequence = true, -+ }, -+ { -+ .name = "wcn6750 hw1.0", -+@@ -597,6 +602,7 @@ static const struct ath11k_hw_params ath -+ .tcl_ring_retry = false, -+ .tx_ring_size = DP_TCL_DATA_RING_SIZE_WCN6750, -+ .smp2p_wow_exit = true, -++ .support_fw_mac_sequence = true, -+ }, -+ }; -+ -+--- a/drivers/net/wireless/ath/ath11k/hw.h -++++ b/drivers/net/wireless/ath/ath11k/hw.h -+@@ -219,6 +219,7 @@ struct ath11k_hw_params { -+ bool tcl_ring_retry; -+ u32 tx_ring_size; -+ bool smp2p_wow_exit; -++ bool support_fw_mac_sequence; -+ }; -+ -+ struct ath11k_hw_ops { -+--- a/drivers/net/wireless/ath/ath11k/mac.c -++++ b/drivers/net/wireless/ath/ath11k/mac.c -+@@ -8010,6 +8010,7 @@ ath11k_mac_op_reconfig_complete(struct i -+ struct ath11k *ar = hw->priv; -+ struct ath11k_base *ab = ar->ab; -+ int recovery_count; -++ struct ath11k_vif *arvif; -+ -+ if (reconfig_type != IEEE80211_RECONFIG_TYPE_RESTART) -+ return; -+@@ -8045,6 +8046,12 @@ ath11k_mac_op_reconfig_complete(struct i -+ ath11k_dbg(ab, ATH11K_DBG_BOOT, "reset success\n"); -+ } -+ } -++ if (ar->ab->hw_params.support_fw_mac_sequence) { -++ list_for_each_entry(arvif, &ar->arvifs, list) { -++ if (arvif->is_up && arvif->vdev_type == WMI_VDEV_TYPE_STA) -++ ieee80211_hw_restart_disconnect(arvif->vif); -++ } -++ } -+ } -+ -+ mutex_unlock(&ar->conf_mutex); -diff --git a/package/kernel/mac80211/patches/ath11k/0018-wifi-ath11k-Fix-race-condition-with-struct-htt_ppdu_.patch b/package/kernel/mac80211/patches/ath11k/0018-wifi-ath11k-Fix-race-condition-with-struct-htt_ppdu_.patch -new file mode 100644 -index 0000000000..cef61ee344 ---- /dev/null -+++ b/package/kernel/mac80211/patches/ath11k/0018-wifi-ath11k-Fix-race-condition-with-struct-htt_ppdu_.patch -@@ -0,0 +1,103 @@ -+From e44de90453bb2b46a523df78c39eb896bab35dcd Mon Sep 17 00:00:00 2001 -+From: Govindaraj Saminathan -+Date: Tue, 29 Nov 2022 13:04:02 +0200 -+Subject: [PATCH] wifi: ath11k: Fix race condition with struct -+ htt_ppdu_stats_info -+ -+A crash happens when running the traffic with multiple clients: -+ -+Crash Signature : Unable to handle kernel paging request at -+virtual address ffffffd700970918 During the crash, PC points to -+"ieee80211_tx_rate_update+0x30/0x68 [mac80211]" -+LR points to "ath11k_dp_htt_htc_t2h_msg_handler+0x5a8/0x8a0 [ath11k]". -+ -+Struct ppdu_stats_info is allocated and accessed from event callback via copy -+engine tasklet, this has a problem when freeing it from ath11k_mac_op_stop(). -+ -+Use data_lock during entire ath11k_dp_htt_get_ppdu_desc() call to protect -+struct htt_ppdu_stats_info access and to avoid race condition when accessing it -+from ath11k_mac_op_stop(). -+ -+Tested-on: IPQ8074 hw2.0 AHB WLAN.HK.2.7.0.1-01744-QCAHKSWPL_SILICONZ-1 -+ -+Signed-off-by: Govindaraj Saminathan -+Co-developed-by: Karthikeyan Kathirvel -+Signed-off-by: Karthikeyan Kathirvel -+Signed-off-by: Kalle Valo -+Link: https://lore.kernel.org/r/20221124071104.22506-1-quic_kathirve@quicinc.com -+--- -+ drivers/net/wireless/ath/ath11k/dp_rx.c | 22 +++++++++++----------- -+ 1 file changed, 11 insertions(+), 11 deletions(-) -+ -+--- a/drivers/net/wireless/ath/ath11k/dp_rx.c -++++ b/drivers/net/wireless/ath/ath11k/dp_rx.c -+@@ -1535,13 +1535,12 @@ struct htt_ppdu_stats_info *ath11k_dp_ht -+ { -+ struct htt_ppdu_stats_info *ppdu_info; -+ -+- spin_lock_bh(&ar->data_lock); -++ lockdep_assert_held(&ar->data_lock); -++ -+ if (!list_empty(&ar->ppdu_stats_info)) { -+ list_for_each_entry(ppdu_info, &ar->ppdu_stats_info, list) { -+- if (ppdu_info->ppdu_id == ppdu_id) { -+- spin_unlock_bh(&ar->data_lock); -++ if (ppdu_info->ppdu_id == ppdu_id) -+ return ppdu_info; -+- } -+ } -+ -+ if (ar->ppdu_stat_list_depth > HTT_PPDU_DESC_MAX_DEPTH) { -+@@ -1553,16 +1552,13 @@ struct htt_ppdu_stats_info *ath11k_dp_ht -+ kfree(ppdu_info); -+ } -+ } -+- spin_unlock_bh(&ar->data_lock); -+ -+ ppdu_info = kzalloc(sizeof(*ppdu_info), GFP_ATOMIC); -+ if (!ppdu_info) -+ return NULL; -+ -+- spin_lock_bh(&ar->data_lock); -+ list_add_tail(&ppdu_info->list, &ar->ppdu_stats_info); -+ ar->ppdu_stat_list_depth++; -+- spin_unlock_bh(&ar->data_lock); -+ -+ return ppdu_info; -+ } -+@@ -1586,16 +1582,17 @@ static int ath11k_htt_pull_ppdu_stats(st -+ ar = ath11k_mac_get_ar_by_pdev_id(ab, pdev_id); -+ if (!ar) { -+ ret = -EINVAL; -+- goto exit; -++ goto out; -+ } -+ -+ if (ath11k_debugfs_is_pktlog_lite_mode_enabled(ar)) -+ trace_ath11k_htt_ppdu_stats(ar, skb->data, len); -+ -++ spin_lock_bh(&ar->data_lock); -+ ppdu_info = ath11k_dp_htt_get_ppdu_desc(ar, ppdu_id); -+ if (!ppdu_info) { -+ ret = -EINVAL; -+- goto exit; -++ goto out_unlock_data; -+ } -+ -+ ppdu_info->ppdu_id = ppdu_id; -+@@ -1604,10 +1601,13 @@ static int ath11k_htt_pull_ppdu_stats(st -+ (void *)ppdu_info); -+ if (ret) { -+ ath11k_warn(ab, "Failed to parse tlv %d\n", ret); -+- goto exit; -++ goto out_unlock_data; -+ } -+ -+-exit: -++out_unlock_data: -++ spin_unlock_bh(&ar->data_lock); -++ -++out: -+ rcu_read_unlock(); -+ -+ return ret; -diff --git a/package/kernel/mac80211/patches/ath11k/0019-wifi-ath11k-update-hw-params-for-IPQ5018.patch b/package/kernel/mac80211/patches/ath11k/0019-wifi-ath11k-update-hw-params-for-IPQ5018.patch -new file mode 100644 -index 0000000000..25d39ddb0d ---- /dev/null -+++ b/package/kernel/mac80211/patches/ath11k/0019-wifi-ath11k-update-hw-params-for-IPQ5018.patch -@@ -0,0 +1,125 @@ -+From 8dfe875aa24aec68baf6702018633c84c2c1feca Mon Sep 17 00:00:00 2001 -+From: Sriram R -+Date: Fri, 2 Dec 2022 23:37:13 +0200 -+Subject: [PATCH] wifi: ath11k: update hw params for IPQ5018 -+ -+Add new compatible string for IPQ5018 and add -+required hw params for IPQ5018. The hw descriptors size and -+datapath ops are similar to QCN9074, hence reuse the same. -+ -+Tested-on: IPQ5018 hw1.0 AHB WLAN.HK.2.6.0.1-00861-QCAHKSWPL_SILICONZ-1 -+ -+Signed-off-by: Sriram R -+Co-developed-by: Karthikeyan Kathirvel -+Signed-off-by: Karthikeyan Kathirvel -+Signed-off-by: Kalle Valo -+Link: https://lore.kernel.org/r/20221122132152.17771-3-quic_kathirve@quicinc.com -+--- -+ drivers/net/wireless/ath/ath11k/core.c | 71 ++++++++++++++++++++++++++ -+ drivers/net/wireless/ath/ath11k/core.h | 8 +++ -+ 2 files changed, 79 insertions(+) -+ -+--- a/drivers/net/wireless/ath/ath11k/core.c -++++ b/drivers/net/wireless/ath/ath11k/core.c -+@@ -604,6 +604,77 @@ static const struct ath11k_hw_params ath -+ .smp2p_wow_exit = true, -+ .support_fw_mac_sequence = true, -+ }, -++ { -++ .hw_rev = ATH11K_HW_IPQ5018_HW10, -++ .name = "ipq5018 hw1.0", -++ .fw = { -++ .dir = "IPQ5018/hw1.0", -++ .board_size = 256 * 1024, -++ .cal_offset = 128 * 1024, -++ }, -++ .max_radios = MAX_RADIOS_5018, -++ .bdf_addr = 0x4BA00000, -++ /* hal_desc_sz and hw ops are similar to qcn9074 */ -++ .hal_desc_sz = sizeof(struct hal_rx_desc_qcn9074), -++ .qmi_service_ins_id = ATH11K_QMI_WLFW_SERVICE_INS_ID_V01_IPQ8074, -++ .ring_mask = &ath11k_hw_ring_mask_ipq8074, -++ .credit_flow = false, -++ .max_tx_ring = 1, -++ .spectral = { -++ .fft_sz = 2, -++ .fft_pad_sz = 0, -++ .summary_pad_sz = 16, -++ .fft_hdr_len = 24, -++ .max_fft_bins = 1024, -++ }, -++ .internal_sleep_clock = false, -++ .host_ce_config = ath11k_host_ce_config_qcn9074, -++ .ce_count = CE_CNT_5018, -++ .rxdma1_enable = true, -++ .num_rxmda_per_pdev = RXDMA_PER_PDEV_5018, -++ .rx_mac_buf_ring = false, -++ .vdev_start_delay = false, -++ .htt_peer_map_v2 = true, -++ .interface_modes = BIT(NL80211_IFTYPE_STATION) | -++ BIT(NL80211_IFTYPE_AP) | -++ BIT(NL80211_IFTYPE_MESH_POINT), -++ .supports_monitor = false, -++ .supports_sta_ps = false, -++ .supports_shadow_regs = false, -++ .fw_mem_mode = 0, -++ .num_vdevs = 16 + 1, -++ .num_peers = 512, -++ .supports_regdb = false, -++ .idle_ps = false, -++ .supports_suspend = false, -++ .hal_params = &ath11k_hw_hal_params_ipq8074, -++ .single_pdev_only = false, -++ .cold_boot_calib = true, -++ .fix_l1ss = true, -++ .supports_dynamic_smps_6ghz = false, -++ .alloc_cacheable_memory = true, -++ .supports_rssi_stats = false, -++ .fw_wmi_diag_event = false, -++ .current_cc_support = false, -++ .dbr_debug_support = true, -++ .global_reset = false, -++ .bios_sar_capa = NULL, -++ .m3_fw_support = false, -++ .fixed_bdf_addr = true, -++ .fixed_mem_region = true, -++ .static_window_map = false, -++ .hybrid_bus_type = false, -++ .fixed_fw_mem = false, -++ .support_off_channel_tx = false, -++ .supports_multi_bssid = false, -++ -++ .sram_dump = {}, -++ -++ .tcl_ring_retry = true, -++ .tx_ring_size = DP_TCL_DATA_RING_SIZE, -++ .smp2p_wow_exit = false, -++ .support_fw_mac_sequence = false, -++ }, -+ }; -+ -+ static inline struct ath11k_pdev *ath11k_core_get_single_pdev(struct ath11k_base *ab) -+--- a/drivers/net/wireless/ath/ath11k/core.h -++++ b/drivers/net/wireless/ath/ath11k/core.h -+@@ -142,6 +142,7 @@ enum ath11k_hw_rev { -+ ATH11K_HW_WCN6855_HW20, -+ ATH11K_HW_WCN6855_HW21, -+ ATH11K_HW_WCN6750_HW10, -++ ATH11K_HW_IPQ5018_HW10, -+ }; -+ -+ enum ath11k_firmware_mode { -+@@ -230,6 +231,13 @@ struct ath11k_he { -+ -+ #define MAX_RADIOS 3 -+ -++/* ipq5018 hw param macros */ -++#define MAX_RADIOS_5018 1 -++#define CE_CNT_5018 6 -++#define TARGET_CE_CNT_5018 9 -++#define SVC_CE_MAP_LEN_5018 17 -++#define RXDMA_PER_PDEV_5018 1 -++ -+ enum { -+ WMI_HOST_TP_SCALE_MAX = 0, -+ WMI_HOST_TP_SCALE_50 = 1, -diff --git a/package/kernel/mac80211/patches/ath11k/0020-wifi-ath11k-update-ce-configurations-for-IPQ5018.patch b/package/kernel/mac80211/patches/ath11k/0020-wifi-ath11k-update-ce-configurations-for-IPQ5018.patch -new file mode 100644 -index 0000000000..95643a95fe ---- /dev/null -+++ b/package/kernel/mac80211/patches/ath11k/0020-wifi-ath11k-update-ce-configurations-for-IPQ5018.patch -@@ -0,0 +1,246 @@ -+From 26af7aabd2d8225c6b2056234626ba5099610871 Mon Sep 17 00:00:00 2001 -+From: Sriram R -+Date: Fri, 2 Dec 2022 23:37:14 +0200 -+Subject: [PATCH] wifi: ath11k: update ce configurations for IPQ5018 -+ -+IPQ5018 is a single pdev device. Update host -+and target CE configurations accordingly. -+ -+Tested-on: IPQ5018 hw1.0 AHB WLAN.HK.2.6.0.1-00861-QCAHKSWPL_SILICONZ-1 -+ -+Signed-off-by: Sriram R -+Co-developed-by: Karthikeyan Kathirvel -+Signed-off-by: Karthikeyan Kathirvel -+Signed-off-by: Kalle Valo -+Link: https://lore.kernel.org/r/20221122132152.17771-4-quic_kathirve@quicinc.com -+--- -+ drivers/net/wireless/ath/ath11k/core.c | 4 + -+ drivers/net/wireless/ath/ath11k/core.h | 3 + -+ drivers/net/wireless/ath/ath11k/hw.c | 191 +++++++++++++++++++++++++ -+ 3 files changed, 198 insertions(+) -+ -+--- a/drivers/net/wireless/ath/ath11k/core.c -++++ b/drivers/net/wireless/ath/ath11k/core.c -+@@ -630,6 +630,10 @@ static const struct ath11k_hw_params ath -+ .internal_sleep_clock = false, -+ .host_ce_config = ath11k_host_ce_config_qcn9074, -+ .ce_count = CE_CNT_5018, -++ .target_ce_config = ath11k_target_ce_config_wlan_ipq5018, -++ .target_ce_count = TARGET_CE_CNT_5018, -++ .svc_to_ce_map = ath11k_target_service_to_ce_map_wlan_ipq5018, -++ .svc_to_ce_map_len = SVC_CE_MAP_LEN_5018, -+ .rxdma1_enable = true, -+ .num_rxmda_per_pdev = RXDMA_PER_PDEV_5018, -+ .rx_mac_buf_ring = false, -+--- a/drivers/net/wireless/ath/ath11k/core.h -++++ b/drivers/net/wireless/ath/ath11k/core.h -+@@ -1145,6 +1145,9 @@ extern const struct service_to_pipe ath1 -+ extern const struct ce_pipe_config ath11k_target_ce_config_wlan_qca6390[]; -+ extern const struct service_to_pipe ath11k_target_service_to_ce_map_wlan_qca6390[]; -+ -++extern const struct ce_pipe_config ath11k_target_ce_config_wlan_ipq5018[]; -++extern const struct service_to_pipe ath11k_target_service_to_ce_map_wlan_ipq5018[]; -++ -+ extern const struct ce_pipe_config ath11k_target_ce_config_wlan_qcn9074[]; -+ extern const struct service_to_pipe ath11k_target_service_to_ce_map_wlan_qcn9074[]; -+ int ath11k_core_qmi_firmware_ready(struct ath11k_base *ab); -+--- a/drivers/net/wireless/ath/ath11k/hw.c -++++ b/drivers/net/wireless/ath/ath11k/hw.c -+@@ -1972,6 +1972,197 @@ const struct ath11k_hw_ring_mask ath11k_ -+ }, -+ }; -+ -++/* Target firmware's Copy Engine configuration for IPQ5018 */ -++const struct ce_pipe_config ath11k_target_ce_config_wlan_ipq5018[] = { -++ /* CE0: host->target HTC control and raw streams */ -++ { -++ .pipenum = __cpu_to_le32(0), -++ .pipedir = __cpu_to_le32(PIPEDIR_OUT), -++ .nentries = __cpu_to_le32(32), -++ .nbytes_max = __cpu_to_le32(2048), -++ .flags = __cpu_to_le32(CE_ATTR_FLAGS), -++ .reserved = __cpu_to_le32(0), -++ }, -++ -++ /* CE1: target->host HTT + HTC control */ -++ { -++ .pipenum = __cpu_to_le32(1), -++ .pipedir = __cpu_to_le32(PIPEDIR_IN), -++ .nentries = __cpu_to_le32(32), -++ .nbytes_max = __cpu_to_le32(2048), -++ .flags = __cpu_to_le32(CE_ATTR_FLAGS), -++ .reserved = __cpu_to_le32(0), -++ }, -++ -++ /* CE2: target->host WMI */ -++ { -++ .pipenum = __cpu_to_le32(2), -++ .pipedir = __cpu_to_le32(PIPEDIR_IN), -++ .nentries = __cpu_to_le32(32), -++ .nbytes_max = __cpu_to_le32(2048), -++ .flags = __cpu_to_le32(CE_ATTR_FLAGS), -++ .reserved = __cpu_to_le32(0), -++ }, -++ -++ /* CE3: host->target WMI */ -++ { -++ .pipenum = __cpu_to_le32(3), -++ .pipedir = __cpu_to_le32(PIPEDIR_OUT), -++ .nentries = __cpu_to_le32(32), -++ .nbytes_max = __cpu_to_le32(2048), -++ .flags = __cpu_to_le32(CE_ATTR_FLAGS), -++ .reserved = __cpu_to_le32(0), -++ }, -++ -++ /* CE4: host->target HTT */ -++ { -++ .pipenum = __cpu_to_le32(4), -++ .pipedir = __cpu_to_le32(PIPEDIR_OUT), -++ .nentries = __cpu_to_le32(256), -++ .nbytes_max = __cpu_to_le32(256), -++ .flags = __cpu_to_le32(CE_ATTR_FLAGS | CE_ATTR_DIS_INTR), -++ .reserved = __cpu_to_le32(0), -++ }, -++ -++ /* CE5: target->host Pktlog */ -++ { -++ .pipenum = __cpu_to_le32(5), -++ .pipedir = __cpu_to_le32(PIPEDIR_IN), -++ .nentries = __cpu_to_le32(32), -++ .nbytes_max = __cpu_to_le32(2048), -++ .flags = __cpu_to_le32(CE_ATTR_FLAGS), -++ .reserved = __cpu_to_le32(0), -++ }, -++ -++ /* CE6: Reserved for target autonomous hif_memcpy */ -++ { -++ .pipenum = __cpu_to_le32(6), -++ .pipedir = __cpu_to_le32(PIPEDIR_INOUT), -++ .nentries = __cpu_to_le32(32), -++ .nbytes_max = __cpu_to_le32(16384), -++ .flags = __cpu_to_le32(CE_ATTR_FLAGS), -++ .reserved = __cpu_to_le32(0), -++ }, -++ -++ /* CE7 used only by Host */ -++ { -++ .pipenum = __cpu_to_le32(7), -++ .pipedir = __cpu_to_le32(PIPEDIR_OUT), -++ .nentries = __cpu_to_le32(32), -++ .nbytes_max = __cpu_to_le32(2048), -++ .flags = __cpu_to_le32(0x2000), -++ .reserved = __cpu_to_le32(0), -++ }, -++ -++ /* CE8 target->host used only by IPA */ -++ { -++ .pipenum = __cpu_to_le32(8), -++ .pipedir = __cpu_to_le32(PIPEDIR_INOUT), -++ .nentries = __cpu_to_le32(32), -++ .nbytes_max = __cpu_to_le32(16384), -++ .flags = __cpu_to_le32(CE_ATTR_FLAGS), -++ .reserved = __cpu_to_le32(0), -++ }, -++}; -++ -++/* Map from service/endpoint to Copy Engine for IPQ5018. -++ * This table is derived from the CE TABLE, above. -++ * It is passed to the Target at startup for use by firmware. -++ */ -++const struct service_to_pipe ath11k_target_service_to_ce_map_wlan_ipq5018[] = { -++ { -++ .service_id = __cpu_to_le32(ATH11K_HTC_SVC_ID_WMI_DATA_VO), -++ .pipedir = __cpu_to_le32(PIPEDIR_OUT), /* out = UL = host -> target */ -++ .pipenum = __cpu_to_le32(3), -++ }, -++ { -++ .service_id = __cpu_to_le32(ATH11K_HTC_SVC_ID_WMI_DATA_VO), -++ .pipedir = __cpu_to_le32(PIPEDIR_IN), /* in = DL = target -> host */ -++ .pipenum = __cpu_to_le32(2), -++ }, -++ { -++ .service_id = __cpu_to_le32(ATH11K_HTC_SVC_ID_WMI_DATA_BK), -++ .pipedir = __cpu_to_le32(PIPEDIR_OUT), /* out = UL = host -> target */ -++ .pipenum = __cpu_to_le32(3), -++ }, -++ { -++ .service_id = __cpu_to_le32(ATH11K_HTC_SVC_ID_WMI_DATA_BK), -++ .pipedir = __cpu_to_le32(PIPEDIR_IN), /* in = DL = target -> host */ -++ .pipenum = __cpu_to_le32(2), -++ }, -++ { -++ .service_id = __cpu_to_le32(ATH11K_HTC_SVC_ID_WMI_DATA_BE), -++ .pipedir = __cpu_to_le32(PIPEDIR_OUT), /* out = UL = host -> target */ -++ .pipenum = __cpu_to_le32(3), -++ }, -++ { -++ .service_id = __cpu_to_le32(ATH11K_HTC_SVC_ID_WMI_DATA_BE), -++ .pipedir = __cpu_to_le32(PIPEDIR_IN), /* in = DL = target -> host */ -++ .pipenum = __cpu_to_le32(2), -++ }, -++ { -++ .service_id = __cpu_to_le32(ATH11K_HTC_SVC_ID_WMI_DATA_VI), -++ .pipedir = __cpu_to_le32(PIPEDIR_OUT), /* out = UL = host -> target */ -++ .pipenum = __cpu_to_le32(3), -++ }, -++ { -++ .service_id = __cpu_to_le32(ATH11K_HTC_SVC_ID_WMI_DATA_VI), -++ .pipedir = __cpu_to_le32(PIPEDIR_IN), /* in = DL = target -> host */ -++ .pipenum = __cpu_to_le32(2), -++ }, -++ { -++ .service_id = __cpu_to_le32(ATH11K_HTC_SVC_ID_WMI_CONTROL), -++ .pipedir = __cpu_to_le32(PIPEDIR_OUT), /* out = UL = host -> target */ -++ .pipenum = __cpu_to_le32(3), -++ }, -++ { -++ .service_id = __cpu_to_le32(ATH11K_HTC_SVC_ID_WMI_CONTROL), -++ .pipedir = __cpu_to_le32(PIPEDIR_IN), /* in = DL = target -> host */ -++ .pipenum = __cpu_to_le32(2), -++ }, -++ -++ { -++ .service_id = __cpu_to_le32(ATH11K_HTC_SVC_ID_RSVD_CTRL), -++ .pipedir = __cpu_to_le32(PIPEDIR_OUT), /* out = UL = host -> target */ -++ .pipenum = __cpu_to_le32(0), -++ }, -++ { -++ .service_id = __cpu_to_le32(ATH11K_HTC_SVC_ID_RSVD_CTRL), -++ .pipedir = __cpu_to_le32(PIPEDIR_IN), /* in = DL = target -> host */ -++ .pipenum = __cpu_to_le32(1), -++ }, -++ -++ { -++ .service_id = __cpu_to_le32(ATH11K_HTC_SVC_ID_TEST_RAW_STREAMS), -++ .pipedir = __cpu_to_le32(PIPEDIR_OUT), /* out = UL = host -> target */ -++ .pipenum = __cpu_to_le32(0), -++ }, -++ { -++ .service_id = __cpu_to_le32(ATH11K_HTC_SVC_ID_TEST_RAW_STREAMS), -++ .pipedir = __cpu_to_le32(PIPEDIR_IN), /* in = DL = target -> host */ -++ .pipenum = __cpu_to_le32(1), -++ }, -++ { -++ .service_id = __cpu_to_le32(ATH11K_HTC_SVC_ID_HTT_DATA_MSG), -++ .pipedir = __cpu_to_le32(PIPEDIR_OUT), /* out = UL = host -> target */ -++ .pipenum = __cpu_to_le32(4), -++ }, -++ { -++ .service_id = __cpu_to_le32(ATH11K_HTC_SVC_ID_HTT_DATA_MSG), -++ .pipedir = __cpu_to_le32(PIPEDIR_IN), /* in = DL = target -> host */ -++ .pipenum = __cpu_to_le32(1), -++ }, -++ { -++ .service_id = __cpu_to_le32(ATH11K_HTC_SVC_ID_PKT_LOG), -++ .pipedir = __cpu_to_le32(PIPEDIR_IN), /* in = DL = target -> host */ -++ .pipenum = __cpu_to_le32(5), -++ }, -++ -++ /* (Additions here) */ -++ -++ { /* terminator entry */ } -++}; -++ -+ const struct ath11k_hw_regs ipq8074_regs = { -+ /* SW2TCL(x) R0 ring configuration address */ -+ .hal_tcl1_ring_base_lsb = 0x00000510, -diff --git a/package/kernel/mac80211/patches/ath11k/0021-wifi-ath11k-remap-ce-register-space-for-IPQ5018.patch b/package/kernel/mac80211/patches/ath11k/0021-wifi-ath11k-remap-ce-register-space-for-IPQ5018.patch -new file mode 100644 -index 0000000000..d07a258ac2 ---- /dev/null -+++ b/package/kernel/mac80211/patches/ath11k/0021-wifi-ath11k-remap-ce-register-space-for-IPQ5018.patch -@@ -0,0 +1,351 @@ -+From b42b3678c91f3ca6e0888bf5a15c1e8678fd5f2d Mon Sep 17 00:00:00 2001 -+From: Sriram R -+Date: Fri, 2 Dec 2022 23:37:14 +0200 -+Subject: [PATCH] wifi: ath11k: remap ce register space for IPQ5018 -+ -+In IPQ5018 ce register space is moved out of wcss unlike -+ipq8074 or ipq6018 and the space is not contiguous, -+hence remap the CE registers to a new space to access them. -+ -+Register read/write is modified to check if the register to be written -+falls in the CE register space and corresponding register is written. -+Also adjust the interrupt register address to ce irq enable/disable. -+ -+Tested-on: IPQ5018 hw1.0 AHB WLAN.HK.2.6.0.1-00861-QCAHKSWPL_SILICONZ-1 -+ -+Signed-off-by: Sriram R -+Co-developed-by: Karthikeyan Kathirvel -+Signed-off-by: Karthikeyan Kathirvel -+Signed-off-by: Kalle Valo -+Link: https://lore.kernel.org/r/20221122132152.17771-5-quic_kathirve@quicinc.com -+--- -+ drivers/net/wireless/ath/ath11k/ahb.c | 44 ++++++++++++++++++++++---- -+ drivers/net/wireless/ath/ath11k/ce.h | 16 ++++++++++ -+ drivers/net/wireless/ath/ath11k/core.c | 8 +++++ -+ drivers/net/wireless/ath/ath11k/core.h | 1 + -+ drivers/net/wireless/ath/ath11k/hal.c | 17 ++++++---- -+ drivers/net/wireless/ath/ath11k/hal.h | 5 +++ -+ drivers/net/wireless/ath/ath11k/hw.c | 17 ++++++++++ -+ drivers/net/wireless/ath/ath11k/hw.h | 9 ++++++ -+ drivers/net/wireless/ath/ath11k/pci.c | 2 ++ -+ 9 files changed, 107 insertions(+), 12 deletions(-) -+ -+--- a/drivers/net/wireless/ath/ath11k/ahb.c -++++ b/drivers/net/wireless/ath/ath11k/ahb.c -+@@ -267,30 +267,42 @@ static void ath11k_ahb_clearbit32(struct -+ static void ath11k_ahb_ce_irq_enable(struct ath11k_base *ab, u16 ce_id) -+ { -+ const struct ce_attr *ce_attr; -++ const struct ce_ie_addr *ce_ie_addr = ab->hw_params.ce_ie_addr; -++ u32 ie1_reg_addr, ie2_reg_addr, ie3_reg_addr; -++ -++ ie1_reg_addr = ce_ie_addr->ie1_reg_addr + ATH11K_CE_OFFSET(ab); -++ ie2_reg_addr = ce_ie_addr->ie2_reg_addr + ATH11K_CE_OFFSET(ab); -++ ie3_reg_addr = ce_ie_addr->ie3_reg_addr + ATH11K_CE_OFFSET(ab); -+ -+ ce_attr = &ab->hw_params.host_ce_config[ce_id]; -+ if (ce_attr->src_nentries) -+- ath11k_ahb_setbit32(ab, ce_id, CE_HOST_IE_ADDRESS); -++ ath11k_ahb_setbit32(ab, ce_id, ie1_reg_addr); -+ -+ if (ce_attr->dest_nentries) { -+- ath11k_ahb_setbit32(ab, ce_id, CE_HOST_IE_2_ADDRESS); -++ ath11k_ahb_setbit32(ab, ce_id, ie2_reg_addr); -+ ath11k_ahb_setbit32(ab, ce_id + CE_HOST_IE_3_SHIFT, -+- CE_HOST_IE_3_ADDRESS); -++ ie3_reg_addr); -+ } -+ } -+ -+ static void ath11k_ahb_ce_irq_disable(struct ath11k_base *ab, u16 ce_id) -+ { -+ const struct ce_attr *ce_attr; -++ const struct ce_ie_addr *ce_ie_addr = ab->hw_params.ce_ie_addr; -++ u32 ie1_reg_addr, ie2_reg_addr, ie3_reg_addr; -++ -++ ie1_reg_addr = ce_ie_addr->ie1_reg_addr + ATH11K_CE_OFFSET(ab); -++ ie2_reg_addr = ce_ie_addr->ie2_reg_addr + ATH11K_CE_OFFSET(ab); -++ ie3_reg_addr = ce_ie_addr->ie3_reg_addr + ATH11K_CE_OFFSET(ab); -+ -+ ce_attr = &ab->hw_params.host_ce_config[ce_id]; -+ if (ce_attr->src_nentries) -+- ath11k_ahb_clearbit32(ab, ce_id, CE_HOST_IE_ADDRESS); -++ ath11k_ahb_clearbit32(ab, ce_id, ie1_reg_addr); -+ -+ if (ce_attr->dest_nentries) { -+- ath11k_ahb_clearbit32(ab, ce_id, CE_HOST_IE_2_ADDRESS); -++ ath11k_ahb_clearbit32(ab, ce_id, ie2_reg_addr); -+ ath11k_ahb_clearbit32(ab, ce_id + CE_HOST_IE_3_SHIFT, -+- CE_HOST_IE_3_ADDRESS); -++ ie3_reg_addr); -+ } -+ } -+ -+@@ -1142,10 +1154,26 @@ static int ath11k_ahb_probe(struct platf -+ goto err_core_free; -+ } -+ -++ ab->mem_ce = ab->mem; -++ -+ ret = ath11k_core_pre_init(ab); -+ if (ret) -+ goto err_core_free; -+ -++ if (ab->hw_params.ce_remap) { -++ const struct ce_remap *ce_remap = ab->hw_params.ce_remap; -++ /* ce register space is moved out of wcss unlike ipq8074 or ipq6018 -++ * and the space is not contiguous, hence remapping the CE registers -++ * to a new space for accessing them. -++ */ -++ ab->mem_ce = ioremap(ce_remap->base, ce_remap->size); -++ if (IS_ERR(ab->mem_ce)) { -++ dev_err(&pdev->dev, "ce ioremap error\n"); -++ ret = -ENOMEM; -++ goto err_core_free; -++ } -++ } -++ -+ ret = ath11k_ahb_setup_resources(ab); -+ if (ret) -+ goto err_core_free; -+@@ -1236,6 +1264,10 @@ static void ath11k_ahb_free_resources(st -+ ath11k_ahb_release_smp2p_handle(ab); -+ ath11k_ahb_fw_resource_deinit(ab); -+ ath11k_ce_free_pipes(ab); -++ -++ if (ab->hw_params.ce_remap) -++ iounmap(ab->mem_ce); -++ -+ ath11k_core_free(ab); -+ platform_set_drvdata(pdev, NULL); -+ } -+--- a/drivers/net/wireless/ath/ath11k/ce.h -++++ b/drivers/net/wireless/ath/ath11k/ce.h -+@@ -49,6 +49,11 @@ void ath11k_ce_byte_swap(void *mem, u32 -+ #define CE_HOST_IE_2_ADDRESS 0x00A18040 -+ #define CE_HOST_IE_3_ADDRESS CE_HOST_IE_ADDRESS -+ -++/* CE IE registers are different for IPQ5018 */ -++#define CE_HOST_IPQ5018_IE_ADDRESS 0x0841804C -++#define CE_HOST_IPQ5018_IE_2_ADDRESS 0x08418050 -++#define CE_HOST_IPQ5018_IE_3_ADDRESS CE_HOST_IPQ5018_IE_ADDRESS -++ -+ #define CE_HOST_IE_3_SHIFT 0xC -+ -+ #define CE_RING_IDX_INCR(nentries_mask, idx) (((idx) + 1) & (nentries_mask)) -+@@ -84,6 +89,17 @@ struct ce_pipe_config { -+ __le32 reserved; -+ }; -+ -++struct ce_ie_addr { -++ u32 ie1_reg_addr; -++ u32 ie2_reg_addr; -++ u32 ie3_reg_addr; -++}; -++ -++struct ce_remap { -++ u32 base; -++ u32 size; -++}; -++ -+ struct ce_attr { -+ /* CE_ATTR_* values */ -+ unsigned int flags; -+--- a/drivers/net/wireless/ath/ath11k/core.c -++++ b/drivers/net/wireless/ath/ath11k/core.c -+@@ -54,6 +54,7 @@ static const struct ath11k_hw_params ath -+ .target_ce_count = 11, -+ .svc_to_ce_map = ath11k_target_service_to_ce_map_wlan_ipq8074, -+ .svc_to_ce_map_len = 21, -++ .ce_ie_addr = &ath11k_ce_ie_addr_ipq8074, -+ .single_pdev_only = false, -+ .rxdma1_enable = true, -+ .num_rxmda_per_pdev = 1, -+@@ -137,6 +138,7 @@ static const struct ath11k_hw_params ath -+ .target_ce_count = 11, -+ .svc_to_ce_map = ath11k_target_service_to_ce_map_wlan_ipq6018, -+ .svc_to_ce_map_len = 19, -++ .ce_ie_addr = &ath11k_ce_ie_addr_ipq8074, -+ .single_pdev_only = false, -+ .rxdma1_enable = true, -+ .num_rxmda_per_pdev = 1, -+@@ -218,6 +220,7 @@ static const struct ath11k_hw_params ath -+ .target_ce_count = 9, -+ .svc_to_ce_map = ath11k_target_service_to_ce_map_wlan_qca6390, -+ .svc_to_ce_map_len = 14, -++ .ce_ie_addr = &ath11k_ce_ie_addr_ipq8074, -+ .single_pdev_only = true, -+ .rxdma1_enable = false, -+ .num_rxmda_per_pdev = 2, -+@@ -301,6 +304,7 @@ static const struct ath11k_hw_params ath -+ .target_ce_count = 9, -+ .svc_to_ce_map = ath11k_target_service_to_ce_map_wlan_qcn9074, -+ .svc_to_ce_map_len = 18, -++ .ce_ie_addr = &ath11k_ce_ie_addr_ipq8074, -+ .rxdma1_enable = true, -+ .num_rxmda_per_pdev = 1, -+ .rx_mac_buf_ring = false, -+@@ -381,6 +385,7 @@ static const struct ath11k_hw_params ath -+ .target_ce_count = 9, -+ .svc_to_ce_map = ath11k_target_service_to_ce_map_wlan_qca6390, -+ .svc_to_ce_map_len = 14, -++ .ce_ie_addr = &ath11k_ce_ie_addr_ipq8074, -+ .single_pdev_only = true, -+ .rxdma1_enable = false, -+ .num_rxmda_per_pdev = 2, -+@@ -546,6 +551,7 @@ static const struct ath11k_hw_params ath -+ .target_ce_count = 9, -+ .svc_to_ce_map = ath11k_target_service_to_ce_map_wlan_qca6390, -+ .svc_to_ce_map_len = 14, -++ .ce_ie_addr = &ath11k_ce_ie_addr_ipq8074, -+ .single_pdev_only = true, -+ .rxdma1_enable = false, -+ .num_rxmda_per_pdev = 1, -+@@ -634,6 +640,8 @@ static const struct ath11k_hw_params ath -+ .target_ce_count = TARGET_CE_CNT_5018, -+ .svc_to_ce_map = ath11k_target_service_to_ce_map_wlan_ipq5018, -+ .svc_to_ce_map_len = SVC_CE_MAP_LEN_5018, -++ .ce_ie_addr = &ath11k_ce_ie_addr_ipq5018, -++ .ce_remap = &ath11k_ce_remap_ipq5018, -+ .rxdma1_enable = true, -+ .num_rxmda_per_pdev = RXDMA_PER_PDEV_5018, -+ .rx_mac_buf_ring = false, -+--- a/drivers/net/wireless/ath/ath11k/core.h -++++ b/drivers/net/wireless/ath/ath11k/core.h -+@@ -851,6 +851,7 @@ struct ath11k_base { -+ struct ath11k_dp dp; -+ -+ void __iomem *mem; -++ void __iomem *mem_ce; -+ unsigned long mem_len; -+ -+ struct { -+--- a/drivers/net/wireless/ath/ath11k/hal.c -++++ b/drivers/net/wireless/ath/ath11k/hal.c -+@@ -1220,16 +1220,20 @@ static int ath11k_hal_srng_create_config -+ s->reg_start[1] = HAL_SEQ_WCSS_UMAC_TCL_REG + HAL_TCL_STATUS_RING_HP; -+ -+ s = &hal->srng_config[HAL_CE_SRC]; -+- s->reg_start[0] = HAL_SEQ_WCSS_UMAC_CE0_SRC_REG(ab) + HAL_CE_DST_RING_BASE_LSB; -+- s->reg_start[1] = HAL_SEQ_WCSS_UMAC_CE0_SRC_REG(ab) + HAL_CE_DST_RING_HP; -++ s->reg_start[0] = HAL_SEQ_WCSS_UMAC_CE0_SRC_REG(ab) + HAL_CE_DST_RING_BASE_LSB + -++ ATH11K_CE_OFFSET(ab); -++ s->reg_start[1] = HAL_SEQ_WCSS_UMAC_CE0_SRC_REG(ab) + HAL_CE_DST_RING_HP + -++ ATH11K_CE_OFFSET(ab); -+ s->reg_size[0] = HAL_SEQ_WCSS_UMAC_CE1_SRC_REG(ab) - -+ HAL_SEQ_WCSS_UMAC_CE0_SRC_REG(ab); -+ s->reg_size[1] = HAL_SEQ_WCSS_UMAC_CE1_SRC_REG(ab) - -+ HAL_SEQ_WCSS_UMAC_CE0_SRC_REG(ab); -+ -+ s = &hal->srng_config[HAL_CE_DST]; -+- s->reg_start[0] = HAL_SEQ_WCSS_UMAC_CE0_DST_REG(ab) + HAL_CE_DST_RING_BASE_LSB; -+- s->reg_start[1] = HAL_SEQ_WCSS_UMAC_CE0_DST_REG(ab) + HAL_CE_DST_RING_HP; -++ s->reg_start[0] = HAL_SEQ_WCSS_UMAC_CE0_DST_REG(ab) + HAL_CE_DST_RING_BASE_LSB + -++ ATH11K_CE_OFFSET(ab); -++ s->reg_start[1] = HAL_SEQ_WCSS_UMAC_CE0_DST_REG(ab) + HAL_CE_DST_RING_HP + -++ ATH11K_CE_OFFSET(ab); -+ s->reg_size[0] = HAL_SEQ_WCSS_UMAC_CE1_DST_REG(ab) - -+ HAL_SEQ_WCSS_UMAC_CE0_DST_REG(ab); -+ s->reg_size[1] = HAL_SEQ_WCSS_UMAC_CE1_DST_REG(ab) - -+@@ -1237,8 +1241,9 @@ static int ath11k_hal_srng_create_config -+ -+ s = &hal->srng_config[HAL_CE_DST_STATUS]; -+ s->reg_start[0] = HAL_SEQ_WCSS_UMAC_CE0_DST_REG(ab) + -+- HAL_CE_DST_STATUS_RING_BASE_LSB; -+- s->reg_start[1] = HAL_SEQ_WCSS_UMAC_CE0_DST_REG(ab) + HAL_CE_DST_STATUS_RING_HP; -++ HAL_CE_DST_STATUS_RING_BASE_LSB + ATH11K_CE_OFFSET(ab); -++ s->reg_start[1] = HAL_SEQ_WCSS_UMAC_CE0_DST_REG(ab) + HAL_CE_DST_STATUS_RING_HP + -++ ATH11K_CE_OFFSET(ab); -+ s->reg_size[0] = HAL_SEQ_WCSS_UMAC_CE1_DST_REG(ab) - -+ HAL_SEQ_WCSS_UMAC_CE0_DST_REG(ab); -+ s->reg_size[1] = HAL_SEQ_WCSS_UMAC_CE1_DST_REG(ab) - -+--- a/drivers/net/wireless/ath/ath11k/hal.h -++++ b/drivers/net/wireless/ath/ath11k/hal.h -+@@ -321,6 +321,10 @@ struct ath11k_base; -+ #define HAL_WBM2SW_RELEASE_RING_BASE_MSB_RING_SIZE 0x000fffff -+ #define HAL_RXDMA_RING_MAX_SIZE 0x0000ffff -+ -++/* IPQ5018 ce registers */ -++#define HAL_IPQ5018_CE_WFSS_REG_BASE 0x08400000 -++#define HAL_IPQ5018_CE_SIZE 0x200000 -++ -+ /* Add any other errors here and return them in -+ * ath11k_hal_rx_desc_get_err(). -+ */ -+@@ -519,6 +523,7 @@ enum hal_srng_dir { -+ #define HAL_SRNG_FLAGS_MSI_INTR 0x00020000 -+ #define HAL_SRNG_FLAGS_CACHED 0x20000000 -+ #define HAL_SRNG_FLAGS_LMAC_RING 0x80000000 -++#define HAL_SRNG_FLAGS_REMAP_CE_RING 0x10000000 -+ -+ #define HAL_SRNG_TLV_HDR_TAG GENMASK(9, 1) -+ #define HAL_SRNG_TLV_HDR_LEN GENMASK(25, 10) -+--- a/drivers/net/wireless/ath/ath11k/hw.c -++++ b/drivers/net/wireless/ath/ath11k/hw.c -+@@ -2163,6 +2163,23 @@ const struct service_to_pipe ath11k_targ -+ { /* terminator entry */ } -+ }; -+ -++const struct ce_ie_addr ath11k_ce_ie_addr_ipq8074 = { -++ .ie1_reg_addr = CE_HOST_IE_ADDRESS, -++ .ie2_reg_addr = CE_HOST_IE_2_ADDRESS, -++ .ie3_reg_addr = CE_HOST_IE_3_ADDRESS, -++}; -++ -++const struct ce_ie_addr ath11k_ce_ie_addr_ipq5018 = { -++ .ie1_reg_addr = CE_HOST_IPQ5018_IE_ADDRESS - HAL_IPQ5018_CE_WFSS_REG_BASE, -++ .ie2_reg_addr = CE_HOST_IPQ5018_IE_2_ADDRESS - HAL_IPQ5018_CE_WFSS_REG_BASE, -++ .ie3_reg_addr = CE_HOST_IPQ5018_IE_3_ADDRESS - HAL_IPQ5018_CE_WFSS_REG_BASE, -++}; -++ -++const struct ce_remap ath11k_ce_remap_ipq5018 = { -++ .base = HAL_IPQ5018_CE_WFSS_REG_BASE, -++ .size = HAL_IPQ5018_CE_SIZE, -++}; -++ -+ const struct ath11k_hw_regs ipq8074_regs = { -+ /* SW2TCL(x) R0 ring configuration address */ -+ .hal_tcl1_ring_base_lsb = 0x00000510, -+--- a/drivers/net/wireless/ath/ath11k/hw.h -++++ b/drivers/net/wireless/ath/ath11k/hw.h -+@@ -80,6 +80,8 @@ -+ #define ATH11K_M3_FILE "m3.bin" -+ #define ATH11K_REGDB_FILE_NAME "regdb.bin" -+ -++#define ATH11K_CE_OFFSET(ab) (ab->mem_ce - ab->mem) -++ -+ enum ath11k_hw_rate_cck { -+ ATH11K_HW_RATE_CCK_LP_11M = 0, -+ ATH11K_HW_RATE_CCK_LP_5_5M, -+@@ -158,6 +160,8 @@ struct ath11k_hw_params { -+ u32 target_ce_count; -+ const struct service_to_pipe *svc_to_ce_map; -+ u32 svc_to_ce_map_len; -++ const struct ce_ie_addr *ce_ie_addr; -++ const struct ce_remap *ce_remap; -+ -+ bool single_pdev_only; -+ -+@@ -277,6 +281,11 @@ extern const struct ath11k_hw_ring_mask -+ extern const struct ath11k_hw_ring_mask ath11k_hw_ring_mask_qcn9074; -+ extern const struct ath11k_hw_ring_mask ath11k_hw_ring_mask_wcn6750; -+ -++extern const struct ce_ie_addr ath11k_ce_ie_addr_ipq8074; -++extern const struct ce_ie_addr ath11k_ce_ie_addr_ipq5018; -++ -++extern const struct ce_remap ath11k_ce_remap_ipq5018; -++ -+ extern const struct ath11k_hw_hal_params ath11k_hw_hal_params_ipq8074; -+ extern const struct ath11k_hw_hal_params ath11k_hw_hal_params_qca6390; -+ extern const struct ath11k_hw_hal_params ath11k_hw_hal_params_wcn6750; -+--- a/drivers/net/wireless/ath/ath11k/pci.c -++++ b/drivers/net/wireless/ath/ath11k/pci.c -+@@ -543,6 +543,8 @@ static int ath11k_pci_claim(struct ath11 -+ goto clear_master; -+ } -+ -++ ab->mem_ce = ab->mem; -++ -+ ath11k_dbg(ab, ATH11K_DBG_BOOT, "boot pci_mem 0x%pK\n", ab->mem); -+ return 0; -+ -diff --git a/package/kernel/mac80211/patches/ath11k/0022-wifi-ath11k-update-hal-srng-regs-for-IPQ5018.patch b/package/kernel/mac80211/patches/ath11k/0022-wifi-ath11k-update-hal-srng-regs-for-IPQ5018.patch -new file mode 100644 -index 0000000000..35ea20a3c4 ---- /dev/null -+++ b/package/kernel/mac80211/patches/ath11k/0022-wifi-ath11k-update-hal-srng-regs-for-IPQ5018.patch -@@ -0,0 +1,130 @@ -+From 711b80acbdfb9667a9cf8374e13320a6e624ce73 Mon Sep 17 00:00:00 2001 -+From: Sriram R -+Date: Fri, 2 Dec 2022 23:37:14 +0200 -+Subject: [PATCH] wifi: ath11k: update hal srng regs for IPQ5018 -+ -+IPQ5018 hal srng register address & offsets are not -+similar to IPQ8074/IPQ6018/QCN9074, hence define a -+new set of srng register group data for IPQ5018. -+ -+Tested-on: IPQ5018 hw1.0 AHB WLAN.HK.2.6.0.1-00861-QCAHKSWPL_SILICONZ-1 -+ -+Signed-off-by: Sriram R -+Co-developed-by: Karthikeyan Kathirvel -+Signed-off-by: Karthikeyan Kathirvel -+Signed-off-by: Kalle Valo -+Link: https://lore.kernel.org/r/20221122132152.17771-6-quic_kathirve@quicinc.com -+--- -+ drivers/net/wireless/ath/ath11k/core.c | 1 + -+ drivers/net/wireless/ath/ath11k/hw.c | 79 ++++++++++++++++++++++++++ -+ drivers/net/wireless/ath/ath11k/hw.h | 1 + -+ 3 files changed, 81 insertions(+) -+ -+--- a/drivers/net/wireless/ath/ath11k/core.c -++++ b/drivers/net/wireless/ath/ath11k/core.c -+@@ -634,6 +634,7 @@ static const struct ath11k_hw_params ath -+ .max_fft_bins = 1024, -+ }, -+ .internal_sleep_clock = false, -++ .regs = &ipq5018_regs, -+ .host_ce_config = ath11k_host_ce_config_qcn9074, -+ .ce_count = CE_CNT_5018, -+ .target_ce_config = ath11k_target_ce_config_wlan_ipq5018, -+--- a/drivers/net/wireless/ath/ath11k/hw.c -++++ b/drivers/net/wireless/ath/ath11k/hw.c -+@@ -2645,6 +2645,85 @@ static const struct ath11k_hw_tcl2wbm_rb -+ }, -+ }; -+ -++const struct ath11k_hw_regs ipq5018_regs = { -++ /* SW2TCL(x) R0 ring configuration address */ -++ .hal_tcl1_ring_base_lsb = 0x00000694, -++ .hal_tcl1_ring_base_msb = 0x00000698, -++ .hal_tcl1_ring_id = 0x0000069c, -++ .hal_tcl1_ring_misc = 0x000006a4, -++ .hal_tcl1_ring_tp_addr_lsb = 0x000006b0, -++ .hal_tcl1_ring_tp_addr_msb = 0x000006b4, -++ .hal_tcl1_ring_consumer_int_setup_ix0 = 0x000006c4, -++ .hal_tcl1_ring_consumer_int_setup_ix1 = 0x000006c8, -++ .hal_tcl1_ring_msi1_base_lsb = 0x000006dc, -++ .hal_tcl1_ring_msi1_base_msb = 0x000006e0, -++ .hal_tcl1_ring_msi1_data = 0x000006e4, -++ .hal_tcl2_ring_base_lsb = 0x000006ec, -++ .hal_tcl_ring_base_lsb = 0x0000079c, -++ -++ /* TCL STATUS ring address */ -++ .hal_tcl_status_ring_base_lsb = 0x000008a4, -++ -++ /* REO2SW(x) R0 ring configuration address */ -++ .hal_reo1_ring_base_lsb = 0x000001ec, -++ .hal_reo1_ring_base_msb = 0x000001f0, -++ .hal_reo1_ring_id = 0x000001f4, -++ .hal_reo1_ring_misc = 0x000001fc, -++ .hal_reo1_ring_hp_addr_lsb = 0x00000200, -++ .hal_reo1_ring_hp_addr_msb = 0x00000204, -++ .hal_reo1_ring_producer_int_setup = 0x00000210, -++ .hal_reo1_ring_msi1_base_lsb = 0x00000234, -++ .hal_reo1_ring_msi1_base_msb = 0x00000238, -++ .hal_reo1_ring_msi1_data = 0x0000023c, -++ .hal_reo2_ring_base_lsb = 0x00000244, -++ .hal_reo1_aging_thresh_ix_0 = 0x00000564, -++ .hal_reo1_aging_thresh_ix_1 = 0x00000568, -++ .hal_reo1_aging_thresh_ix_2 = 0x0000056c, -++ .hal_reo1_aging_thresh_ix_3 = 0x00000570, -++ -++ /* REO2SW(x) R2 ring pointers (head/tail) address */ -++ .hal_reo1_ring_hp = 0x00003028, -++ .hal_reo1_ring_tp = 0x0000302c, -++ .hal_reo2_ring_hp = 0x00003030, -++ -++ /* REO2TCL R0 ring configuration address */ -++ .hal_reo_tcl_ring_base_lsb = 0x000003fc, -++ .hal_reo_tcl_ring_hp = 0x00003058, -++ -++ /* SW2REO ring address */ -++ .hal_sw2reo_ring_base_lsb = 0x0000013c, -++ .hal_sw2reo_ring_hp = 0x00003018, -++ -++ /* REO CMD ring address */ -++ .hal_reo_cmd_ring_base_lsb = 0x000000e4, -++ .hal_reo_cmd_ring_hp = 0x00003010, -++ -++ /* REO status address */ -++ .hal_reo_status_ring_base_lsb = 0x00000504, -++ .hal_reo_status_hp = 0x00003070, -++ -++ /* WCSS relative address */ -++ .hal_seq_wcss_umac_ce0_src_reg = 0x08400000 -++ - HAL_IPQ5018_CE_WFSS_REG_BASE, -++ .hal_seq_wcss_umac_ce0_dst_reg = 0x08401000 -++ - HAL_IPQ5018_CE_WFSS_REG_BASE, -++ .hal_seq_wcss_umac_ce1_src_reg = 0x08402000 -++ - HAL_IPQ5018_CE_WFSS_REG_BASE, -++ .hal_seq_wcss_umac_ce1_dst_reg = 0x08403000 -++ - HAL_IPQ5018_CE_WFSS_REG_BASE, -++ -++ /* WBM Idle address */ -++ .hal_wbm_idle_link_ring_base_lsb = 0x00000874, -++ .hal_wbm_idle_link_ring_misc = 0x00000884, -++ -++ /* SW2WBM release address */ -++ .hal_wbm_release_ring_base_lsb = 0x000001ec, -++ -++ /* WBM2SW release address */ -++ .hal_wbm0_release_ring_base_lsb = 0x00000924, -++ .hal_wbm1_release_ring_base_lsb = 0x0000097c, -++}; -++ -+ const struct ath11k_hw_hal_params ath11k_hw_hal_params_ipq8074 = { -+ .rx_buf_rbm = HAL_RX_BUF_RBM_SW3_BM, -+ .tcl2wbm_rbm_map = ath11k_hw_tcl2wbm_rbm_map_ipq8074, -+--- a/drivers/net/wireless/ath/ath11k/hw.h -++++ b/drivers/net/wireless/ath/ath11k/hw.h -+@@ -415,6 +415,7 @@ extern const struct ath11k_hw_regs qca63 -+ extern const struct ath11k_hw_regs qcn9074_regs; -+ extern const struct ath11k_hw_regs wcn6855_regs; -+ extern const struct ath11k_hw_regs wcn6750_regs; -++extern const struct ath11k_hw_regs ipq5018_regs; -+ -+ static inline const char *ath11k_bd_ie_type_str(enum ath11k_bd_ie_type type) -+ { -diff --git a/package/kernel/mac80211/patches/ath11k/0023-wifi-ath11k-initialize-hw_ops-for-IPQ5018.patch b/package/kernel/mac80211/patches/ath11k/0023-wifi-ath11k-initialize-hw_ops-for-IPQ5018.patch -new file mode 100644 -index 0000000000..5ef701a445 ---- /dev/null -+++ b/package/kernel/mac80211/patches/ath11k/0023-wifi-ath11k-initialize-hw_ops-for-IPQ5018.patch -@@ -0,0 +1,90 @@ -+From ba60f2793d3a37a00da14bb56a26558a902d2831 Mon Sep 17 00:00:00 2001 -+From: Sriram R -+Date: Fri, 2 Dec 2022 23:37:14 +0200 -+Subject: [PATCH] wifi: ath11k: initialize hw_ops for IPQ5018 -+ -+The ipq5018_ops is initialized for IPQ5018. This is different from -+other platforms. -+ -+Tested-on: IPQ5018 hw1.0 AHB WLAN.HK.2.6.0.1-00861-QCAHKSWPL_SILICONZ-1 -+ -+Signed-off-by: Sriram R -+Co-developed-by: Karthikeyan Kathirvel -+Signed-off-by: Karthikeyan Kathirvel -+Signed-off-by: Kalle Valo -+Link: https://lore.kernel.org/r/20221122132152.17771-7-quic_kathirve@quicinc.com -+--- -+ drivers/net/wireless/ath/ath11k/core.c | 1 + -+ drivers/net/wireless/ath/ath11k/hw.c | 40 ++++++++++++++++++++++++++ -+ drivers/net/wireless/ath/ath11k/hw.h | 1 + -+ 3 files changed, 42 insertions(+) -+ -+--- a/drivers/net/wireless/ath/ath11k/core.c -++++ b/drivers/net/wireless/ath/ath11k/core.c -+@@ -635,6 +635,7 @@ static const struct ath11k_hw_params ath -+ }, -+ .internal_sleep_clock = false, -+ .regs = &ipq5018_regs, -++ .hw_ops = &ipq5018_ops, -+ .host_ce_config = ath11k_host_ce_config_qcn9074, -+ .ce_count = CE_CNT_5018, -+ .target_ce_config = ath11k_target_ce_config_wlan_ipq5018, -+--- a/drivers/net/wireless/ath/ath11k/hw.c -++++ b/drivers/net/wireless/ath/ath11k/hw.c -+@@ -1084,6 +1084,46 @@ const struct ath11k_hw_ops wcn6750_ops = -+ .get_ring_selector = ath11k_hw_wcn6750_get_tcl_ring_selector, -+ }; -+ -++/* IPQ5018 hw ops is similar to QCN9074 except for the dest ring remap */ -++const struct ath11k_hw_ops ipq5018_ops = { -++ .get_hw_mac_from_pdev_id = ath11k_hw_ipq6018_mac_from_pdev_id, -++ .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, -++ .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, -++ .rx_desc_get_l3_pad_bytes = ath11k_hw_qcn9074_rx_desc_get_l3_pad_bytes, -++ .rx_desc_get_hdr_status = ath11k_hw_qcn9074_rx_desc_get_hdr_status, -++ .rx_desc_encrypt_valid = ath11k_hw_qcn9074_rx_desc_encrypt_valid, -++ .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_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, -++ .rx_desc_get_mpdu_start_seq_no = ath11k_hw_qcn9074_rx_desc_get_mpdu_start_seq_no, -++ .rx_desc_get_msdu_len = ath11k_hw_qcn9074_rx_desc_get_msdu_len, -++ .rx_desc_get_msdu_sgi = ath11k_hw_qcn9074_rx_desc_get_msdu_sgi, -++ .rx_desc_get_msdu_rate_mcs = ath11k_hw_qcn9074_rx_desc_get_msdu_rate_mcs, -++ .rx_desc_get_msdu_rx_bw = ath11k_hw_qcn9074_rx_desc_get_msdu_rx_bw, -++ .rx_desc_get_msdu_freq = ath11k_hw_qcn9074_rx_desc_get_msdu_freq, -++ .rx_desc_get_msdu_pkt_type = ath11k_hw_qcn9074_rx_desc_get_msdu_pkt_type, -++ .rx_desc_get_msdu_nss = ath11k_hw_qcn9074_rx_desc_get_msdu_nss, -++ .rx_desc_get_mpdu_tid = ath11k_hw_qcn9074_rx_desc_get_mpdu_tid, -++ .rx_desc_get_mpdu_peer_id = ath11k_hw_qcn9074_rx_desc_get_mpdu_peer_id, -++ .rx_desc_copy_attn_end_tlv = ath11k_hw_qcn9074_rx_desc_copy_attn_end, -++ .rx_desc_get_mpdu_start_tag = ath11k_hw_qcn9074_rx_desc_get_mpdu_start_tag, -++ .rx_desc_get_mpdu_ppdu_id = ath11k_hw_qcn9074_rx_desc_get_mpdu_ppdu_id, -++ .rx_desc_set_msdu_len = ath11k_hw_qcn9074_rx_desc_set_msdu_len, -++ .rx_desc_get_attention = ath11k_hw_qcn9074_rx_desc_get_attention, -++ .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, -++ -++}; -++ -+ #define ATH11K_TX_RING_MASK_0 BIT(0) -+ #define ATH11K_TX_RING_MASK_1 BIT(1) -+ #define ATH11K_TX_RING_MASK_2 BIT(2) -+--- a/drivers/net/wireless/ath/ath11k/hw.h -++++ b/drivers/net/wireless/ath/ath11k/hw.h -+@@ -275,6 +275,7 @@ extern const struct ath11k_hw_ops qca639 -+ extern const struct ath11k_hw_ops qcn9074_ops; -+ extern const struct ath11k_hw_ops wcn6855_ops; -+ extern const struct ath11k_hw_ops wcn6750_ops; -++extern const struct ath11k_hw_ops ipq5018_ops; -+ -+ extern const struct ath11k_hw_ring_mask ath11k_hw_ring_mask_ipq8074; -+ extern const struct ath11k_hw_ring_mask ath11k_hw_ring_mask_qca6390; -diff --git a/package/kernel/mac80211/patches/ath11k/0024-wifi-ath11k-add-new-hw-ops-for-IPQ5018-to-get-rx-des.patch b/package/kernel/mac80211/patches/ath11k/0024-wifi-ath11k-add-new-hw-ops-for-IPQ5018-to-get-rx-des.patch -new file mode 100644 -index 0000000000..64531f13f8 ---- /dev/null -+++ b/package/kernel/mac80211/patches/ath11k/0024-wifi-ath11k-add-new-hw-ops-for-IPQ5018-to-get-rx-des.patch -@@ -0,0 +1,84 @@ -+From 69968f88f1770d61cae0febef805fd00d66cf6a1 Mon Sep 17 00:00:00 2001 -+From: Sriram R -+Date: Fri, 2 Dec 2022 23:37:15 +0200 -+Subject: [PATCH] wifi: ath11k: add new hw ops for IPQ5018 to get rx dest ring -+ hashmap -+ -+The Destination ring control register is different -+for IPQ5018 when compared to IPQ8074/IPQ6018/QCN9074. -+Hence create a new hw ops to fetch the hash ring map -+for different device variants. ipq5018 hw ops -+is similar to qcn9074 except for this change, so reuse -+all the qcn9074 ops for ipq5018. -+ -+Tested-on: IPQ5018 hw1.0 AHB WLAN.HK.2.6.0.1-00861-QCAHKSWPL_SILICONZ-1 -+ -+Signed-off-by: Sriram R -+Co-developed-by: Karthikeyan Kathirvel -+Signed-off-by: Karthikeyan Kathirvel -+Signed-off-by: Kalle Valo -+Link: https://lore.kernel.org/r/20221122132152.17771-8-quic_kathirve@quicinc.com -+--- -+ drivers/net/wireless/ath/ath11k/hw.c | 44 ++++++++++++++++++++++++++++ -+ 1 file changed, 44 insertions(+) -+ -+--- a/drivers/net/wireless/ath/ath11k/hw.c -++++ b/drivers/net/wireless/ath/ath11k/hw.c -+@@ -791,6 +791,49 @@ static void ath11k_hw_wcn6855_reo_setup( -+ ring_hash_map); -+ } -+ -++static void ath11k_hw_ipq5018_reo_setup(struct ath11k_base *ab) -++{ -++ 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 << 4 | -++ HAL_HASH_ROUTING_RING_SW3 << 8 | -++ HAL_HASH_ROUTING_RING_SW4 << 12 | -++ HAL_HASH_ROUTING_RING_SW1 << 16 | -++ HAL_HASH_ROUTING_RING_SW2 << 20 | -++ HAL_HASH_ROUTING_RING_SW3 << 24 | -++ HAL_HASH_ROUTING_RING_SW4 << 28; -++ -++ 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) | -++ 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); -++ -++ ath11k_hif_write32(ab, reo_base + HAL_REO1_AGING_THRESH_IX_0(ab), -++ HAL_DEFAULT_REO_TIMEOUT_USEC); -++ ath11k_hif_write32(ab, reo_base + HAL_REO1_AGING_THRESH_IX_1(ab), -++ HAL_DEFAULT_REO_TIMEOUT_USEC); -++ ath11k_hif_write32(ab, reo_base + HAL_REO1_AGING_THRESH_IX_2(ab), -++ 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); -++} -++ -+ static u16 ath11k_hw_ipq8074_mpdu_info_get_peerid(u8 *tlv_data) -+ { -+ u16 peer_id = 0; -+@@ -1117,6 +1160,7 @@ const struct ath11k_hw_ops ipq5018_ops = -+ .rx_desc_get_mpdu_ppdu_id = ath11k_hw_qcn9074_rx_desc_get_mpdu_ppdu_id, -+ .rx_desc_set_msdu_len = ath11k_hw_qcn9074_rx_desc_set_msdu_len, -+ .rx_desc_get_attention = ath11k_hw_qcn9074_rx_desc_get_attention, -++ .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, -diff --git a/package/kernel/mac80211/patches/ath11k/0025-wifi-ath11k-add-ipq5018-device-support.patch b/package/kernel/mac80211/patches/ath11k/0025-wifi-ath11k-add-ipq5018-device-support.patch -new file mode 100644 -index 0000000000..5b930e8d4f ---- /dev/null -+++ b/package/kernel/mac80211/patches/ath11k/0025-wifi-ath11k-add-ipq5018-device-support.patch -@@ -0,0 +1,31 @@ -+From 25edca7bb18a2a40cc7e54c6f522e9b3c917e2c5 Mon Sep 17 00:00:00 2001 -+From: Sriram R -+Date: Fri, 2 Dec 2022 23:37:15 +0200 -+Subject: [PATCH] wifi: ath11k: add ipq5018 device support -+ -+ipq5018 is a ahb 2ghz device, enable the compatible support for -+ipq5018 in ahb. -+ -+Tested-on: IPQ5018 hw1.0 AHB WLAN.HK.2.6.0.1-00861-QCAHKSWPL_SILICONZ-1 -+ -+Signed-off-by: Sriram R -+Co-developed-by: Karthikeyan Kathirvel -+Signed-off-by: Karthikeyan Kathirvel -+Signed-off-by: Kalle Valo -+Link: https://lore.kernel.org/r/20221122132152.17771-9-quic_kathirve@quicinc.com -+--- -+ drivers/net/wireless/ath/ath11k/ahb.c | 3 +++ -+ 1 file changed, 3 insertions(+) -+ -+--- a/drivers/net/wireless/ath/ath11k/ahb.c -++++ b/drivers/net/wireless/ath/ath11k/ahb.c -+@@ -32,6 +32,9 @@ static const struct of_device_id ath11k_ -+ { .compatible = "qcom,wcn6750-wifi", -+ .data = (void *)ATH11K_HW_WCN6750_HW10, -+ }, -++ { .compatible = "qcom,ipq5018-wifi", -++ .data = (void *)ATH11K_HW_IPQ5018_HW10, -++ }, -+ { } -+ }; -+ -diff --git a/package/kernel/mac80211/patches/ath11k/0026-wifi-ath11k-Fix-scan-request-param-frame-size-warnin.patch b/package/kernel/mac80211/patches/ath11k/0026-wifi-ath11k-Fix-scan-request-param-frame-size-warnin.patch -new file mode 100644 -index 0000000000..50c14e7b98 ---- /dev/null -+++ b/package/kernel/mac80211/patches/ath11k/0026-wifi-ath11k-Fix-scan-request-param-frame-size-warnin.patch -@@ -0,0 +1,161 @@ -+From d45daa6d1a8da080f1b516c570a8428a7b9225e4 Mon Sep 17 00:00:00 2001 -+From: Karthikeyan Kathirvel -+Date: Tue, 6 Dec 2022 00:51:25 +0530 -+Subject: [PATCH] wifi: ath11k: Fix scan request param frame size warning -+ -+Following warning was observed -+ -+drivers/net/wireless/ath/ath11k/mac.c:2351:1: warning: the frame -+size of 1184 bytes is larger than 1024 bytes [-Wframe-larger-than=] -+ -+A local variable is declared with a size larger than 1024 bytes -+this causing a compilation warning. Change the local variable to -+heap memory to fix the warning. -+ -+Tested-on: IPQ8074 AHB WLAN.HK.2.7.0.1-01701-QCAHKSWPL_SILICONZ-1 v2 -+ -+Signed-off-by: Karthikeyan Kathirvel -+Signed-off-by: Kalle Valo -+Link: https://lore.kernel.org/r/20221205192125.13533-1-quic_kathirve@quicinc.com -+--- -+ drivers/net/wireless/ath/ath11k/mac.c | 83 +++++++++++++++------------ -+ 1 file changed, 45 insertions(+), 38 deletions(-) -+ -+--- a/drivers/net/wireless/ath/ath11k/mac.c -++++ b/drivers/net/wireless/ath/ath11k/mac.c -+@@ -3612,7 +3612,7 @@ static int ath11k_mac_op_hw_scan(struct -+ struct ath11k *ar = hw->priv; -+ struct ath11k_vif *arvif = ath11k_vif_to_arvif(vif); -+ struct cfg80211_scan_request *req = &hw_req->req; -+- struct scan_req_params arg; -++ struct scan_req_params *arg = NULL; -+ int ret = 0; -+ int i; -+ u32 scan_timeout; -+@@ -3640,72 +3640,78 @@ static int ath11k_mac_op_hw_scan(struct -+ if (ret) -+ goto exit; -+ -+- memset(&arg, 0, sizeof(arg)); -+- ath11k_wmi_start_scan_init(ar, &arg); -+- arg.vdev_id = arvif->vdev_id; -+- arg.scan_id = ATH11K_SCAN_ID; -++ arg = kzalloc(sizeof(*arg), GFP_KERNEL); -++ -++ if (!arg) { -++ ret = -ENOMEM; -++ goto exit; -++ } -++ -++ ath11k_wmi_start_scan_init(ar, arg); -++ arg->vdev_id = arvif->vdev_id; -++ arg->scan_id = ATH11K_SCAN_ID; -+ -+ if (req->ie_len) { -+- arg.extraie.ptr = kmemdup(req->ie, req->ie_len, GFP_KERNEL); -+- if (!arg.extraie.ptr) { -++ arg->extraie.ptr = kmemdup(req->ie, req->ie_len, GFP_KERNEL); -++ if (!arg->extraie.ptr) { -+ ret = -ENOMEM; -+ goto exit; -+ } -+- arg.extraie.len = req->ie_len; -++ arg->extraie.len = req->ie_len; -+ } -+ -+ if (req->n_ssids) { -+- arg.num_ssids = req->n_ssids; -+- for (i = 0; i < arg.num_ssids; i++) { -+- arg.ssid[i].length = req->ssids[i].ssid_len; -+- memcpy(&arg.ssid[i].ssid, req->ssids[i].ssid, -++ arg->num_ssids = req->n_ssids; -++ for (i = 0; i < arg->num_ssids; i++) { -++ arg->ssid[i].length = req->ssids[i].ssid_len; -++ memcpy(&arg->ssid[i].ssid, req->ssids[i].ssid, -+ req->ssids[i].ssid_len); -+ } -+ } else { -+- arg.scan_flags |= WMI_SCAN_FLAG_PASSIVE; -++ arg->scan_flags |= WMI_SCAN_FLAG_PASSIVE; -+ } -+ -+ if (req->n_channels) { -+- arg.num_chan = req->n_channels; -+- arg.chan_list = kcalloc(arg.num_chan, sizeof(*arg.chan_list), -+- GFP_KERNEL); -++ arg->num_chan = req->n_channels; -++ arg->chan_list = kcalloc(arg->num_chan, sizeof(*arg->chan_list), -++ GFP_KERNEL); -+ -+- if (!arg.chan_list) { -++ if (!arg->chan_list) { -+ ret = -ENOMEM; -+ goto exit; -+ } -+ -+- for (i = 0; i < arg.num_chan; i++) -+- arg.chan_list[i] = req->channels[i]->center_freq; -++ for (i = 0; i < arg->num_chan; i++) -++ arg->chan_list[i] = req->channels[i]->center_freq; -+ } -+ -+ if (req->flags & NL80211_SCAN_FLAG_RANDOM_ADDR) { -+- arg.scan_f_add_spoofed_mac_in_probe = 1; -+- ether_addr_copy(arg.mac_addr.addr, req->mac_addr); -+- ether_addr_copy(arg.mac_mask.addr, req->mac_addr_mask); -++ arg->scan_f_add_spoofed_mac_in_probe = 1; -++ ether_addr_copy(arg->mac_addr.addr, req->mac_addr); -++ ether_addr_copy(arg->mac_mask.addr, req->mac_addr_mask); -+ } -+ -+ /* if duration is set, default dwell times will be overwritten */ -+ if (req->duration) { -+- arg.dwell_time_active = req->duration; -+- arg.dwell_time_active_2g = req->duration; -+- arg.dwell_time_active_6g = req->duration; -+- arg.dwell_time_passive = req->duration; -+- arg.dwell_time_passive_6g = req->duration; -+- arg.burst_duration = req->duration; -++ arg->dwell_time_active = req->duration; -++ arg->dwell_time_active_2g = req->duration; -++ arg->dwell_time_active_6g = req->duration; -++ arg->dwell_time_passive = req->duration; -++ arg->dwell_time_passive_6g = req->duration; -++ arg->burst_duration = req->duration; -+ -+- scan_timeout = min_t(u32, arg.max_rest_time * -+- (arg.num_chan - 1) + (req->duration + -++ scan_timeout = min_t(u32, arg->max_rest_time * -++ (arg->num_chan - 1) + (req->duration + -+ ATH11K_SCAN_CHANNEL_SWITCH_WMI_EVT_OVERHEAD) * -+- arg.num_chan, arg.max_scan_time); -++ arg->num_chan, arg->max_scan_time); -+ } else { -+- scan_timeout = arg.max_scan_time; -++ scan_timeout = arg->max_scan_time; -+ } -+ -+ /* Add a margin to account for event/command processing */ -+ scan_timeout += ATH11K_MAC_SCAN_CMD_EVT_OVERHEAD; -+ -+- ret = ath11k_start_scan(ar, &arg); -++ ret = ath11k_start_scan(ar, arg); -+ if (ret) { -+ ath11k_warn(ar->ab, "failed to start hw scan: %d\n", ret); -+ spin_lock_bh(&ar->data_lock); -+@@ -3717,10 +3723,11 @@ static int ath11k_mac_op_hw_scan(struct -+ msecs_to_jiffies(scan_timeout)); -+ -+ exit: -+- kfree(arg.chan_list); -+- -+- if (req->ie_len) -+- kfree(arg.extraie.ptr); -++ if (arg) { -++ kfree(arg->chan_list); -++ kfree(arg->extraie.ptr); -++ kfree(arg); -++ } -+ -+ mutex_unlock(&ar->conf_mutex); -+ -diff --git a/package/kernel/mac80211/patches/ath11k/0029-wifi-ath11k-Add-support-to-configure-FTM-responder-r.patch b/package/kernel/mac80211/patches/ath11k/0029-wifi-ath11k-Add-support-to-configure-FTM-responder-r.patch -new file mode 100644 -index 0000000000..f652d689b5 ---- /dev/null -+++ b/package/kernel/mac80211/patches/ath11k/0029-wifi-ath11k-Add-support-to-configure-FTM-responder-r.patch -@@ -0,0 +1,169 @@ -+From a27c6a5853eb9d4f293b99be73a6891fe88263c7 Mon Sep 17 00:00:00 2001 -+From: Sowmiya Sree Elavalagan -+Date: Tue, 10 Jan 2023 15:30:57 +0200 -+Subject: [PATCH] wifi: ath11k: Add support to configure FTM responder role -+ -+Fine Timing Measurement(FTM) support is used to measure round trip -+time between two nodes. -+ -+Enable FTM responder feature using hw_params on supported device. -+Since FTM functionality is offloaded to firmware, adding the -+interface allows user space to enable or disable FTM responder. -+Also add support for advertising the same in extended capabilities. -+ -+QCA6390, WCN6855 and WCN6750 do not support this feature. -+ -+Tested-on: IPQ8074 hw2.0 AHB WLAN.HK.2.7.0.1-01744-QCAHKSWPL_SILICONZ-1 -+Tested-on: QCN9074 hw1.0 PCI WLAN.HK.2.7.0.1-01744-QCAHKSWPL_SILICONZ-1 -+ -+Signed-off-by: Sowmiya Sree Elavalagan -+Signed-off-by: Raj Kumar Bhagat -+Signed-off-by: Kalle Valo -+Link: https://lore.kernel.org/r/20221220044435.10506-1-quic_rajkbhag@quicinc.com -+--- -+ drivers/net/wireless/ath/ath11k/core.c | 8 ++++++++ -+ drivers/net/wireless/ath/ath11k/core.h | 1 + -+ drivers/net/wireless/ath/ath11k/hw.h | 1 + -+ drivers/net/wireless/ath/ath11k/mac.c | 20 +++++++++++++++++++- -+ drivers/net/wireless/ath/ath11k/wmi.h | 1 + -+ 5 files changed, 30 insertions(+), 1 deletion(-) -+ -+--- a/drivers/net/wireless/ath/ath11k/core.c -++++ b/drivers/net/wireless/ath/ath11k/core.c -+@@ -116,6 +116,7 @@ static const struct ath11k_hw_params ath -+ .tcl_ring_retry = true, -+ .tx_ring_size = DP_TCL_DATA_RING_SIZE, -+ .smp2p_wow_exit = false, -++ .ftm_responder = true, -+ }, -+ { -+ .hw_rev = ATH11K_HW_IPQ6018_HW10, -+@@ -198,6 +199,7 @@ static const struct ath11k_hw_params ath -+ .tx_ring_size = DP_TCL_DATA_RING_SIZE, -+ .smp2p_wow_exit = false, -+ .support_fw_mac_sequence = false, -++ .ftm_responder = true, -+ }, -+ { -+ .name = "qca6390 hw2.0", -+@@ -282,6 +284,7 @@ static const struct ath11k_hw_params ath -+ .tx_ring_size = DP_TCL_DATA_RING_SIZE, -+ .smp2p_wow_exit = false, -+ .support_fw_mac_sequence = true, -++ .ftm_responder = false, -+ }, -+ { -+ .name = "qcn9074 hw1.0", -+@@ -363,6 +366,7 @@ static const struct ath11k_hw_params ath -+ .tx_ring_size = DP_TCL_DATA_RING_SIZE, -+ .smp2p_wow_exit = false, -+ .support_fw_mac_sequence = false, -++ .ftm_responder = true, -+ }, -+ { -+ .name = "wcn6855 hw2.0", -+@@ -447,6 +451,7 @@ static const struct ath11k_hw_params ath -+ .tx_ring_size = DP_TCL_DATA_RING_SIZE, -+ .smp2p_wow_exit = false, -+ .support_fw_mac_sequence = true, -++ .ftm_responder = false, -+ }, -+ { -+ .name = "wcn6855 hw2.1", -+@@ -529,6 +534,7 @@ static const struct ath11k_hw_params ath -+ .tx_ring_size = DP_TCL_DATA_RING_SIZE, -+ .smp2p_wow_exit = false, -+ .support_fw_mac_sequence = true, -++ .ftm_responder = false, -+ }, -+ { -+ .name = "wcn6750 hw1.0", -+@@ -609,6 +615,7 @@ static const struct ath11k_hw_params ath -+ .tx_ring_size = DP_TCL_DATA_RING_SIZE_WCN6750, -+ .smp2p_wow_exit = true, -+ .support_fw_mac_sequence = true, -++ .ftm_responder = false, -+ }, -+ { -+ .hw_rev = ATH11K_HW_IPQ5018_HW10, -+@@ -688,6 +695,7 @@ static const struct ath11k_hw_params ath -+ .tx_ring_size = DP_TCL_DATA_RING_SIZE, -+ .smp2p_wow_exit = false, -+ .support_fw_mac_sequence = false, -++ .ftm_responder = true, -+ }, -+ }; -+ -+--- a/drivers/net/wireless/ath/ath11k/core.h -++++ b/drivers/net/wireless/ath/ath11k/core.h -+@@ -346,6 +346,7 @@ struct ath11k_vif { -+ -+ bool is_started; -+ bool is_up; -++ bool ftm_responder; -+ bool spectral_enabled; -+ bool ps; -+ u32 aid; -+--- a/drivers/net/wireless/ath/ath11k/hw.h -++++ b/drivers/net/wireless/ath/ath11k/hw.h -+@@ -224,6 +224,7 @@ struct ath11k_hw_params { -+ u32 tx_ring_size; -+ bool smp2p_wow_exit; -+ bool support_fw_mac_sequence; -++ bool ftm_responder; -+ }; -+ -+ struct ath11k_hw_ops { -+--- a/drivers/net/wireless/ath/ath11k/mac.c -++++ b/drivers/net/wireless/ath/ath11k/mac.c -+@@ -3110,7 +3110,7 @@ static void ath11k_mac_op_bss_info_chang -+ u16 bitrate; -+ int ret = 0; -+ u8 rateidx; -+- u32 rate; -++ u32 rate, param; -+ u32 ipv4_cnt; -+ -+ mutex_lock(&ar->conf_mutex); -+@@ -3412,6 +3412,20 @@ static void ath11k_mac_op_bss_info_chang -+ } -+ } -+ -++ if (changed & BSS_CHANGED_FTM_RESPONDER && -++ arvif->ftm_responder != info->ftm_responder && -++ ar->ab->hw_params.ftm_responder && -++ (vif->type == NL80211_IFTYPE_AP || -++ vif->type == NL80211_IFTYPE_MESH_POINT)) { -++ arvif->ftm_responder = info->ftm_responder; -++ param = WMI_VDEV_PARAM_ENABLE_DISABLE_RTT_RESPONDER_ROLE; -++ ret = ath11k_wmi_vdev_set_param_cmd(ar, arvif->vdev_id, param, -++ arvif->ftm_responder); -++ if (ret) -++ ath11k_warn(ar->ab, "Failed to set ftm responder %i: %d\n", -++ arvif->vdev_id, ret); -++ } -++ -+ if (changed & BSS_CHANGED_FILS_DISCOVERY || -+ changed & BSS_CHANGED_UNSOL_BCAST_PROBE_RESP) -+ ath11k_mac_fils_discovery(arvif, info); -+@@ -9113,6 +9127,10 @@ static int __ath11k_mac_register(struct -+ wiphy_ext_feature_set(ar->hw->wiphy, -+ NL80211_EXT_FEATURE_SET_SCAN_DWELL); -+ -++ if (ab->hw_params.ftm_responder) -++ wiphy_ext_feature_set(ar->hw->wiphy, -++ NL80211_EXT_FEATURE_ENABLE_FTM_RESPONDER); -++ -+ ath11k_reg_init(ar); -+ -+ if (!test_bit(ATH11K_FLAG_RAW_MODE, &ab->dev_flags)) { -+--- a/drivers/net/wireless/ath/ath11k/wmi.h -++++ b/drivers/net/wireless/ath/ath11k/wmi.h -+@@ -1073,6 +1073,7 @@ enum wmi_tlv_vdev_param { -+ WMI_VDEV_PARAM_ENABLE_BCAST_PROBE_RESPONSE, -+ WMI_VDEV_PARAM_FILS_MAX_CHANNEL_GUARD_TIME, -+ WMI_VDEV_PARAM_HE_LTF = 0x74, -++ WMI_VDEV_PARAM_ENABLE_DISABLE_RTT_RESPONDER_ROLE = 0x7d, -+ WMI_VDEV_PARAM_BA_MODE = 0x7e, -+ WMI_VDEV_PARAM_AUTORATE_MISC_CFG = 0x80, -+ WMI_VDEV_PARAM_SET_HE_SOUNDING_MODE = 0x87, -diff --git a/package/kernel/mac80211/patches/ath11k/0030-wifi-ath11k-add-channel-177-into-5-GHz-channel-list.patch b/package/kernel/mac80211/patches/ath11k/0030-wifi-ath11k-add-channel-177-into-5-GHz-channel-list.patch -new file mode 100644 -index 0000000000..d0ed9c54b8 ---- /dev/null -+++ b/package/kernel/mac80211/patches/ath11k/0030-wifi-ath11k-add-channel-177-into-5-GHz-channel-list.patch -@@ -0,0 +1,41 @@ -+From e5e94d10c85653609a2893c8d0ef24a27471b68f Mon Sep 17 00:00:00 2001 -+From: Wen Gong -+Date: Tue, 10 Jan 2023 15:30:58 +0200 -+Subject: [PATCH] wifi: ath11k: add channel 177 into 5 GHz channel list -+ -+Add support for the 5 GHz channel 177 with center frequency 5885 MHz and -+operating class 125 per IEEE Std 802.11ax-2021, Table E-4. -+ -+Tested-on: WCN6855 hw2.0 PCI WLAN.HSP.1.1-03125-QCAHSPSWPL_V1_V2_SILICONZ_LITE-3 -+ -+Signed-off-by: Wen Gong -+Signed-off-by: Kalle Valo -+Link: https://lore.kernel.org/r/20221220101912.30816-1-quic_wgong@quicinc.com -+--- -+ drivers/net/wireless/ath/ath11k/core.h | 4 ++-- -+ drivers/net/wireless/ath/ath11k/mac.c | 1 + -+ 2 files changed, 3 insertions(+), 2 deletions(-) -+ -+--- a/drivers/net/wireless/ath/ath11k/core.h -++++ b/drivers/net/wireless/ath/ath11k/core.h -+@@ -521,8 +521,8 @@ struct ath11k_sta { -+ #define ATH11K_MIN_5G_FREQ 4150 -+ #define ATH11K_MIN_6G_FREQ 5925 -+ #define ATH11K_MAX_6G_FREQ 7115 -+-#define ATH11K_NUM_CHANS 101 -+-#define ATH11K_MAX_5G_CHAN 173 -++#define ATH11K_NUM_CHANS 102 -++#define ATH11K_MAX_5G_CHAN 177 -+ -+ enum ath11k_state { -+ ATH11K_STATE_OFF, -+--- a/drivers/net/wireless/ath/ath11k/mac.c -++++ b/drivers/net/wireless/ath/ath11k/mac.c -+@@ -96,6 +96,7 @@ static const struct ieee80211_channel at -+ CHAN5G(165, 5825, 0), -+ CHAN5G(169, 5845, 0), -+ CHAN5G(173, 5865, 0), -++ CHAN5G(177, 5885, 0), -+ }; -+ -+ static const struct ieee80211_channel ath11k_6ghz_channels[] = { -diff --git a/package/kernel/mac80211/patches/ath11k/0031-wifi-ath11k-fix-ce-memory-mapping-for-ahb-devices.patch b/package/kernel/mac80211/patches/ath11k/0031-wifi-ath11k-fix-ce-memory-mapping-for-ahb-devices.patch -new file mode 100644 -index 0000000000..2786799972 ---- /dev/null -+++ b/package/kernel/mac80211/patches/ath11k/0031-wifi-ath11k-fix-ce-memory-mapping-for-ahb-devices.patch -@@ -0,0 +1,114 @@ -+From 53a998c4d7284debd77734d01e1466e59a1d03b2 Mon Sep 17 00:00:00 2001 -+From: Raj Kumar Bhagat -+Date: Fri, 13 Jan 2023 12:02:09 +0530 -+Subject: [PATCH] wifi: ath11k: fix ce memory mapping for ahb devices -+ -+Currently ath11k_ahb module is not loaded successfully and the wifi -+interface is not created. Kernel trace is seen while loading the -+ath11k_ahb module. The issue is seen in all ath11k AHB devices except -+in IPQ5018. -+ -+This happens because in ath11k_ahb_probe(), ab->mem_ce is initialized -+with the value of ab->mem. However, at this instant ab->mem is not -+yet set. -+ -+Later, during write to a particular memory via ath11k_ahb_write32() -+this ab->mem_ce is used with particular offset. Since ab->mem_ce is -+not set properly this possibly leads to memory conflict to handle -+kernel paging request and the below trace is seen. -+ -+[ 93.035047] Unable to handle kernel paging request at virtual address ffff800100a00000 -+[ 93.035083] Mem abort info: -+[ 93.041869] ESR = 0x0000000096000045 -+[ 93.044561] EC = 0x25: DABT (current EL), IL = 32 bits -+[ 93.048377] SET = 0, FnV = 0 -+[ 93.053840] EA = 0, S1PTW = 0 -+[ 93.056704] FSC = 0x05: level 1 translation fault -+[ 93.059745] Data abort info: -+[ 93.064603] ISV = 0, ISS = 0x00000045 -+[ 93.067729] CM = 0, WnR = 1 -+[ 93.071287] swapper pgtable: 4k pages, 48-bit VAs, pgdp=0000000042219000 -+[ 93.074409] [ffff800100a00000] pgd=100000007ffff003, p4d=100000007ffff003, pud=0000000000000000 -+[ 93.081195] Internal error: Oops: 0000000096000045 [#1] PREEMPT SMP -+[ 93.089598] Modules linked in: ath11k_ahb ath11k_pci ath11k qmi_helpers -+[ 93.095851] CPU: 2 PID: 66 Comm: kworker/u8:3 Not tainted 6.1.0-rc8-wt-ath-658126-g58e4b9df840c-dirty #2 -+[ 93.102454] Hardware name: Qualcomm Technologies, Inc. IPQ8074/AP-HK14 (DT) -+[ 93.112171] Workqueue: ath11k_qmi_driver_event ath11k_qmi_driver_event_work [ath11k] -+[ 93.118856] pstate: 40000005 (nZcv daif -PAN -UAO -TCO -DIT -SSBS BTYPE=--) -+[ 93.126838] pc : ath11k_ahb_write32+0xc/0x18 [ath11k_ahb] -+[ 93.133520] lr : ath11k_hal_srng_setup+0x860/0x8f0 [ath11k] -+[ 93.139075] sp : ffff80000aaebb70 -+[ 93.144452] x29: ffff80000aaebb70 x28: 0000000000000020 x27: ffff80000aaebc50 -+[ 93.147934] x26: ffff000004923750 x25: ffff000004921200 x24: ffff000004928000 -+[ 93.155051] x23: 0000000000000020 x22: ffff000004930000 x21: ffff000004923200 -+[ 93.162170] x20: ffff000004920000 x19: 00000000eea00000 x18: ffff0000049200f0 -+[ 93.169288] x17: 0000000000000000 x16: 0000000000000000 x15: 000000000000025e -+[ 93.176405] x14: ffff000003c414f0 x13: 0000000000000000 x12: 0000000000000008 -+[ 93.183524] x11: ffff000003c41488 x10: 0000000000000040 x9 : 0000000000000000 -+[ 93.190641] x8 : ffff80000a9dd100 x7 : 0000000000000000 x6 : 000000000000003f -+[ 93.197759] x5 : ffff800100a00400 x4 : ffff8000031f4018 x3 : 0000000000000004 -+[ 93.204877] x2 : 0000000047b62000 x1 : ffff800100a00000 x0 : ffff800012000000 -+[ 93.211996] Call trace: -+[ 93.219104] ath11k_ahb_write32+0xc/0x18 [ath11k_ahb] -+[ 93.221366] ath11k_ce_init_ring+0x184/0x278 [ath11k] -+[ 93.226576] ath11k_ce_init_pipes+0x4c/0x1a0 [ath11k] -+[ 93.231610] ath11k_core_qmi_firmware_ready+0x3c/0x568 [ath11k] -+[ 93.236646] ath11k_qmi_driver_event_work+0x168/0x4f8 [ath11k] -+[ 93.242376] process_one_work+0x144/0x350 -+[ 93.248275] worker_thread+0x120/0x430 -+[ 93.252352] kthread+0xf4/0x110 -+[ 93.255997] ret_from_fork+0x10/0x20 -+[ 93.259043] Code: d503201f f94e1c00 8b214001 d50332bf (b9000022) -+[ 93.262863] ---[ end trace 0000000000000000 ]--- -+ -+However, for the device IPQ5018 ath11k_hw_params .ce_remap is -+defined. This parameter is used to recalculate ab->mem_ce and hence, -+this issue is not seen in IPQ5018. -+ -+Hence, fix this by initializing ab->mem_ce after ab->mem is set. -+ab->mem is set inside the ath11k_ahb_setup_resources() therefore -+initialize ab->mem_ce after ath11k_ahb_setup_resources(). -+ -+Tested-on: IPQ8074 hw2.0 AHB WLAN.HK.2.7.0.1-01744-QCAHKSWPL_SILICONZ-1 -+ -+Fixes: b42b3678c91f ("wifi: ath11k: remap ce register space for IPQ5018") -+ -+Signed-off-by: Raj Kumar Bhagat -+Signed-off-by: Kalle Valo -+Link: https://lore.kernel.org/r/20230113063209.7256-1-quic_rajkbhag@quicinc.com -+--- -+ drivers/net/wireless/ath/ath11k/ahb.c | 12 ++++++------ -+ 1 file changed, 6 insertions(+), 6 deletions(-) -+ -+--- a/drivers/net/wireless/ath/ath11k/ahb.c -++++ b/drivers/net/wireless/ath/ath11k/ahb.c -+@@ -1157,12 +1157,16 @@ static int ath11k_ahb_probe(struct platf -+ goto err_core_free; -+ } -+ -+- ab->mem_ce = ab->mem; -+- -+ ret = ath11k_core_pre_init(ab); -+ if (ret) -+ goto err_core_free; -+ -++ ret = ath11k_ahb_setup_resources(ab); -++ if (ret) -++ goto err_core_free; -++ -++ ab->mem_ce = ab->mem; -++ -+ if (ab->hw_params.ce_remap) { -+ const struct ce_remap *ce_remap = ab->hw_params.ce_remap; -+ /* ce register space is moved out of wcss unlike ipq8074 or ipq6018 -+@@ -1177,10 +1181,6 @@ static int ath11k_ahb_probe(struct platf -+ } -+ } -+ -+- ret = ath11k_ahb_setup_resources(ab); -+- if (ret) -+- goto err_core_free; -+- -+ ret = ath11k_ahb_fw_resources_init(ab); -+ if (ret) -+ goto err_core_free; -diff --git a/package/kernel/mac80211/patches/ath11k/0033-wifi-ath11k-Set-ext-passive-scan-flag-to-adjust-pass.patch b/package/kernel/mac80211/patches/ath11k/0033-wifi-ath11k-Set-ext-passive-scan-flag-to-adjust-pass.patch -new file mode 100644 -index 0000000000..79b79e1053 ---- /dev/null -+++ b/package/kernel/mac80211/patches/ath11k/0033-wifi-ath11k-Set-ext-passive-scan-flag-to-adjust-pass.patch -@@ -0,0 +1,73 @@ -+From cf8f3d4deb02a8fdc806c46d4112b69868544697 Mon Sep 17 00:00:00 2001 -+From: Tamizh Chelvam Raja -+Date: Wed, 15 Feb 2023 20:31:36 +0200 -+Subject: [PATCH] wifi: ath11k: Set ext passive scan flag to adjust passive -+ scan start time -+ -+Set the WMI_SCAN_FLAG_EXT_PASSIVE_SCAN_START_TIME_ENHANCE flag -+while sending the scan command. If this flag is enabled when the -+incoming scan request comes with a strict start time and its duration -+overlaps with next TBTT, then target adjust the start time accordingly -+for passive scan. Target supporting this feature will advertise -+WMI_TLV_SERVICE_PASSIVE_SCAN_START_TIME_ENHANCE. -+ -+Tested-on: IPQ8074 hw2.0 AHB WLAN.HK.2.4.0.1-01467-QCAHKSWPL_SILICONZ-1 -+ -+Signed-off-by: Tamizh Chelvam Raja -+Signed-off-by: Kalle Valo -+Link: https://lore.kernel.org/r/20221222131720.11368-1-quic_tamizhr@quicinc.com -+--- -+ drivers/net/wireless/ath/ath11k/wmi.c | 8 ++++++++ -+ drivers/net/wireless/ath/ath11k/wmi.h | 3 +++ -+ 2 files changed, 11 insertions(+) -+ -+--- a/drivers/net/wireless/ath/ath11k/wmi.c -++++ b/drivers/net/wireless/ath/ath11k/wmi.c -+@@ -2068,6 +2068,12 @@ void ath11k_wmi_start_scan_init(struct a -+ WMI_SCAN_EVENT_FOREIGN_CHAN | -+ WMI_SCAN_EVENT_DEQUEUED; -+ arg->scan_flags |= WMI_SCAN_CHAN_STAT_EVENT; -++ -++ if (test_bit(WMI_TLV_SERVICE_PASSIVE_SCAN_START_TIME_ENHANCE, -++ ar->ab->wmi_ab.svc_map)) -++ arg->scan_ctrl_flags_ext |= -++ WMI_SCAN_FLAG_EXT_PASSIVE_SCAN_START_TIME_ENHANCE; -++ -+ arg->num_bssid = 1; -+ -+ /* fill bssid_list[0] with 0xff, otherwise bssid and RA will be -+@@ -2149,6 +2155,8 @@ ath11k_wmi_copy_scan_event_cntrl_flags(s -+ /* for adaptive scan mode using 3 bits (21 - 23 bits) */ -+ WMI_SCAN_SET_DWELL_MODE(cmd->scan_ctrl_flags, -+ param->adaptive_dwell_time_mode); -++ -++ cmd->scan_ctrl_flags_ext = param->scan_ctrl_flags_ext; -+ } -+ -+ int ath11k_wmi_send_scan_start_cmd(struct ath11k *ar, -+--- a/drivers/net/wireless/ath/ath11k/wmi.h -++++ b/drivers/net/wireless/ath/ath11k/wmi.h -+@@ -2093,6 +2093,7 @@ enum wmi_tlv_service { -+ WMI_TLV_SERVICE_EXT2_MSG = 220, -+ WMI_TLV_SERVICE_PEER_POWER_SAVE_DURATION_SUPPORT = 246, -+ WMI_TLV_SERVICE_SRG_SRP_SPATIAL_REUSE_SUPPORT = 249, -++ WMI_TLV_SERVICE_PASSIVE_SCAN_START_TIME_ENHANCE = 263, -+ -+ /* The second 128 bits */ -+ WMI_MAX_EXT_SERVICE = 256, -+@@ -3223,6 +3224,7 @@ struct wmi_start_scan_cmd { -+ -+ #define WMI_SCAN_DWELL_MODE_MASK 0x00E00000 -+ #define WMI_SCAN_DWELL_MODE_SHIFT 21 -++#define WMI_SCAN_FLAG_EXT_PASSIVE_SCAN_START_TIME_ENHANCE 0x00000800 -+ -+ enum { -+ WMI_SCAN_DWELL_MODE_DEFAULT = 0, -+@@ -3270,6 +3272,7 @@ struct scan_req_params { -+ }; -+ u32 scan_events; -+ }; -++ u32 scan_ctrl_flags_ext; -+ u32 dwell_time_active; -+ u32 dwell_time_active_2g; -+ u32 dwell_time_passive; -diff --git a/package/kernel/mac80211/patches/ath11k/0034-wifi-ath11k-fix-return-value-check-in-ath11k_ahb_pro.patch b/package/kernel/mac80211/patches/ath11k/0034-wifi-ath11k-fix-return-value-check-in-ath11k_ahb_pro.patch -new file mode 100644 -index 0000000000..59132913bd ---- /dev/null -+++ b/package/kernel/mac80211/patches/ath11k/0034-wifi-ath11k-fix-return-value-check-in-ath11k_ahb_pro.patch -@@ -0,0 +1,27 @@ -+From 342fcde9d91460f01f65707e16368a1571271a3a Mon Sep 17 00:00:00 2001 -+From: Yang Yingliang -+Date: Fri, 17 Feb 2023 11:00:31 +0800 -+Subject: [PATCH] wifi: ath11k: fix return value check in ath11k_ahb_probe() -+ -+ioremap() returns NULL pointer not PTR_ERR() when it fails, -+so replace the IS_ERR() check with NULL pointer check. -+ -+Fixes: b42b3678c91f ("wifi: ath11k: remap ce register space for IPQ5018") -+Signed-off-by: Yang Yingliang -+Signed-off-by: Kalle Valo -+Link: https://lore.kernel.org/r/20230217030031.4021289-1-yangyingliang@huawei.com -+--- -+ drivers/net/wireless/ath/ath11k/ahb.c | 2 +- -+ 1 file changed, 1 insertion(+), 1 deletion(-) -+ -+--- a/drivers/net/wireless/ath/ath11k/ahb.c -++++ b/drivers/net/wireless/ath/ath11k/ahb.c -+@@ -1174,7 +1174,7 @@ static int ath11k_ahb_probe(struct platf -+ * to a new space for accessing them. -+ */ -+ ab->mem_ce = ioremap(ce_remap->base, ce_remap->size); -+- if (IS_ERR(ab->mem_ce)) { -++ if (!ab->mem_ce) { -+ dev_err(&pdev->dev, "ce ioremap error\n"); -+ ret = -ENOMEM; -+ goto err_core_free; -diff --git a/package/kernel/mac80211/patches/ath11k/0035-wifi-ath11k-Use-platform_get_irq-to-get-the-interrup.patch b/package/kernel/mac80211/patches/ath11k/0035-wifi-ath11k-Use-platform_get_irq-to-get-the-interrup.patch -new file mode 100644 -index 0000000000..93a9da8fc2 ---- /dev/null -+++ b/package/kernel/mac80211/patches/ath11k/0035-wifi-ath11k-Use-platform_get_irq-to-get-the-interrup.patch -@@ -0,0 +1,50 @@ -+From f117276638b7600b981b3fe28550823cfbe1ef23 Mon Sep 17 00:00:00 2001 -+From: Douglas Anderson -+Date: Wed, 1 Feb 2023 08:54:42 -0800 -+Subject: [PATCH] wifi: ath11k: Use platform_get_irq() to get the interrupt -+ -+As of commit a1a2b7125e10 ("of/platform: Drop static setup of IRQ -+resource from DT core"), we need to use platform_get_irq() instead of -+platform_get_resource() to get our IRQs because -+platform_get_resource() simply won't get them anymore. -+ -+This was already fixed in several other Atheros WiFi drivers, -+apparently in response to Zeal Robot reports. An example of another -+fix is commit 9503a1fc123d ("ath9k: Use platform_get_irq() to get the -+interrupt"). ath11k seems to have been missed in this effort, though. -+ -+Without this change, WiFi wasn't coming up on my Qualcomm sc7280-based -+hardware. Specifically, "platform_get_resource(pdev, IORESOURCE_IRQ, -+i)" was failing even for i=0. -+ -+Tested-on: WCN6750 hw1.0 AHB WLAN.MSL.1.0.1-00887-QCAMSLSWPLZ-1 -+ -+Fixes: a1a2b7125e10 ("of/platform: Drop static setup of IRQ resource from DT core") -+Fixes: 00402f49d26f ("ath11k: Add support for WCN6750 device") -+Signed-off-by: Douglas Anderson -+Tested-by: Jun Yu -+Reviewed-by: Lad Prabhakar -+Signed-off-by: Kalle Valo -+Link: https://lore.kernel.org/r/20230201084131.v2.1.I69cf3d56c97098287fe3a70084ee515098390b70@changeid -+--- -+ drivers/net/wireless/ath/ath11k/ahb.c | 8 ++++---- -+ 1 file changed, 4 insertions(+), 4 deletions(-) -+ -+--- a/drivers/net/wireless/ath/ath11k/ahb.c -++++ b/drivers/net/wireless/ath/ath11k/ahb.c -+@@ -874,11 +874,11 @@ static int ath11k_ahb_setup_msi_resource -+ ab->pci.msi.ep_base_data = int_prop + 32; -+ -+ for (i = 0; i < ab->pci.msi.config->total_vectors; i++) { -+- res = platform_get_resource(pdev, IORESOURCE_IRQ, i); -+- if (!res) -+- return -ENODEV; -++ ret = platform_get_irq(pdev, i); -++ if (ret < 0) -++ return ret; -+ -+- ab->pci.msi.irqs[i] = res->start; -++ ab->pci.msi.irqs[i] = ret; -+ } -+ -+ set_bit(ATH11K_FLAG_MULTI_MSI_VECTORS, &ab->dev_flags); -diff --git a/package/kernel/mac80211/patches/ath11k/0036-wifi-ath11k-fix-SAC-bug-on-peer-addition-with-sta-ba.patch b/package/kernel/mac80211/patches/ath11k/0036-wifi-ath11k-fix-SAC-bug-on-peer-addition-with-sta-ba.patch -new file mode 100644 -index 0000000000..b37f070ba6 ---- /dev/null -+++ b/package/kernel/mac80211/patches/ath11k/0036-wifi-ath11k-fix-SAC-bug-on-peer-addition-with-sta-ba.patch -@@ -0,0 +1,53 @@ -+From 60b7d62ba8cdbd073997bff0f1cdae8d844002c0 Mon Sep 17 00:00:00 2001 -+From: Christian Marangi -+Date: Thu, 9 Feb 2023 23:26:22 +0100 -+Subject: [PATCH] wifi: ath11k: fix SAC bug on peer addition with sta band -+ migration -+ -+Fix sleep in atomic context warning detected by Smatch static checker -+analyzer. -+ -+Following the locking pattern for peer_rhash_add lock tbl_mtx_lock mutex -+always even if sta is not transitioning to another band. -+This is peer_add function and a more secure locking should not cause -+performance regression. -+ -+Tested-on: IPQ8074 hw2.0 AHB WLAN.HK.2.5.0.1-01208-QCAHKSWPL_SILICONZ-1 -+ -+Fixes: d673cb6fe6c0 ("wifi: ath11k: fix peer addition/deletion error on sta band migration") -+Reported-by: Dan Carpenter -+Signed-off-by: Christian Marangi -+Signed-off-by: Kalle Valo -+Link: https://lore.kernel.org/r/20230209222622.1751-1-ansuelsmth@gmail.com -+--- -+ drivers/net/wireless/ath/ath11k/peer.c | 5 +++-- -+ 1 file changed, 3 insertions(+), 2 deletions(-) -+ -+--- a/drivers/net/wireless/ath/ath11k/peer.c -++++ b/drivers/net/wireless/ath/ath11k/peer.c -+@@ -382,22 +382,23 @@ int ath11k_peer_create(struct ath11k *ar -+ return -ENOBUFS; -+ } -+ -++ mutex_lock(&ar->ab->tbl_mtx_lock); -+ spin_lock_bh(&ar->ab->base_lock); -+ peer = ath11k_peer_find_by_addr(ar->ab, param->peer_addr); -+ if (peer) { -+ if (peer->vdev_id == param->vdev_id) { -+ spin_unlock_bh(&ar->ab->base_lock); -++ mutex_unlock(&ar->ab->tbl_mtx_lock); -+ return -EINVAL; -+ } -+ -+ /* Assume sta is transitioning to another band. -+ * Remove here the peer from rhash. -+ */ -+- mutex_lock(&ar->ab->tbl_mtx_lock); -+ ath11k_peer_rhash_delete(ar->ab, peer); -+- mutex_unlock(&ar->ab->tbl_mtx_lock); -+ } -+ spin_unlock_bh(&ar->ab->base_lock); -++ mutex_unlock(&ar->ab->tbl_mtx_lock); -+ -+ ret = ath11k_wmi_send_peer_create_cmd(ar, param); -+ if (ret) { -diff --git a/package/kernel/mac80211/patches/ath11k/0037-wifi-ath11k-allow-system-suspend-to-survive-ath11k.patch b/package/kernel/mac80211/patches/ath11k/0037-wifi-ath11k-allow-system-suspend-to-survive-ath11k.patch -new file mode 100644 -index 0000000000..fa680954e6 ---- /dev/null -+++ b/package/kernel/mac80211/patches/ath11k/0037-wifi-ath11k-allow-system-suspend-to-survive-ath11k.patch -@@ -0,0 +1,43 @@ -+From 7c15430822e71e90203d87e6d0cfe83fa058b0dc Mon Sep 17 00:00:00 2001 -+From: Len Brown -+Date: Wed, 1 Feb 2023 12:32:01 -0600 -+Subject: [PATCH] wifi: ath11k: allow system suspend to survive ath11k -+ -+When ath11k runs into internal errors upon suspend, -+it returns an error code to pci_pm_suspend, which -+aborts the entire system suspend. -+ -+The driver should not abort system suspend, but should -+keep its internal errors to itself, and allow the system -+to suspend. Otherwise, a user can suspend a laptop -+by closing the lid and sealing it into a case, assuming -+that is will suspend, rather than heating up and draining -+the battery when in transit. -+ -+In practice, the ath11k device seems to have plenty of transient -+errors, and subsequent suspend cycles after this failure -+often succeed. -+ -+https://bugzilla.kernel.org/show_bug.cgi?id=216968 -+ -+Fixes: d1b0c33850d29 ("ath11k: implement suspend for QCA6390 PCI devices") -+ -+Signed-off-by: Len Brown -+Cc: stable@vger.kernel.org -+Signed-off-by: Kalle Valo -+Link: https://lore.kernel.org/r/20230201183201.14431-1-len.brown@intel.com -+--- -+ drivers/net/wireless/ath/ath11k/pci.c | 2 +- -+ 1 file changed, 1 insertion(+), 1 deletion(-) -+ -+--- a/drivers/net/wireless/ath/ath11k/pci.c -++++ b/drivers/net/wireless/ath/ath11k/pci.c -+@@ -998,7 +998,7 @@ static __maybe_unused int ath11k_pci_pm_ -+ if (ret) -+ ath11k_warn(ab, "failed to resume core: %d\n", ret); -+ -+- return ret; -++ return 0; -+ } -+ -+ static SIMPLE_DEV_PM_OPS(ath11k_pci_pm_ops, -diff --git a/package/kernel/mac80211/patches/ath11k/0038-wifi-ath11k-modify-accessor-macros-to-match-index-si.patch b/package/kernel/mac80211/patches/ath11k/0038-wifi-ath11k-modify-accessor-macros-to-match-index-si.patch -new file mode 100644 -index 0000000000..42bf170a03 ---- /dev/null -+++ b/package/kernel/mac80211/patches/ath11k/0038-wifi-ath11k-modify-accessor-macros-to-match-index-si.patch -@@ -0,0 +1,61 @@ -+From a96f10422e74cde27c100b321b127ec32ae75747 Mon Sep 17 00:00:00 2001 -+From: Muna Sinada -+Date: Fri, 24 Feb 2023 12:28:03 +0200 -+Subject: [PATCH] wifi: ath11k: modify accessor macros to match index size -+ -+HE PHY is only 11 bytes, therefore it should be using byte indexes -+instead of dword. Change corresponding macros to reflect this. -+ -+Signed-off-by: Muna Sinada -+Signed-off-by: Kalle Valo -+Link: https://lore.kernel.org/r/1666128501-12364-2-git-send-email-quic_msinada@quicinc.com -+--- -+ drivers/net/wireless/ath/ath11k/wmi.h | 24 +++++++++++++----------- -+ 1 file changed, 13 insertions(+), 11 deletions(-) -+ -+--- a/drivers/net/wireless/ath/ath11k/wmi.h -++++ b/drivers/net/wireless/ath/ath11k/wmi.h -+@@ -2859,30 +2859,32 @@ struct rx_reorder_queue_remove_params { -+ #define WMI_VDEV_PARAM_TXBF_SU_TX_BFER BIT(2) -+ #define WMI_VDEV_PARAM_TXBF_MU_TX_BFER BIT(3) -+ -+-#define HECAP_PHYDWORD_0 0 -+-#define HECAP_PHYDWORD_1 1 -+-#define HECAP_PHYDWORD_2 2 -++#define HE_PHYCAP_BYTE_0 0 -++#define HE_PHYCAP_BYTE_1 1 -++#define HE_PHYCAP_BYTE_2 2 -++#define HE_PHYCAP_BYTE_3 3 -++#define HE_PHYCAP_BYTE_4 4 -+ -+-#define HECAP_PHY_SU_BFER BIT(31) -++#define HECAP_PHY_SU_BFER BIT(7) -+ #define HECAP_PHY_SU_BFEE BIT(0) -+ #define HECAP_PHY_MU_BFER BIT(1) -+-#define HECAP_PHY_UL_MUMIMO BIT(22) -+-#define HECAP_PHY_UL_MUOFDMA BIT(23) -++#define HECAP_PHY_UL_MUMIMO BIT(6) -++#define HECAP_PHY_UL_MUOFDMA BIT(7) -+ -+ #define HECAP_PHY_SUBFMR_GET(hecap_phy) \ -+- FIELD_GET(HECAP_PHY_SU_BFER, hecap_phy[HECAP_PHYDWORD_0]) -++ FIELD_GET(HECAP_PHY_SU_BFER, hecap_phy[HE_PHYCAP_BYTE_3]) -+ -+ #define HECAP_PHY_SUBFME_GET(hecap_phy) \ -+- FIELD_GET(HECAP_PHY_SU_BFEE, hecap_phy[HECAP_PHYDWORD_1]) -++ FIELD_GET(HECAP_PHY_SU_BFEE, hecap_phy[HE_PHYCAP_BYTE_4]) -+ -+ #define HECAP_PHY_MUBFMR_GET(hecap_phy) \ -+- FIELD_GET(HECAP_PHY_MU_BFER, hecap_phy[HECAP_PHYDWORD_1]) -++ FIELD_GET(HECAP_PHY_MU_BFER, hecap_phy[HE_PHYCAP_BYTE_4]) -+ -+ #define HECAP_PHY_ULMUMIMO_GET(hecap_phy) \ -+- FIELD_GET(HECAP_PHY_UL_MUMIMO, hecap_phy[HECAP_PHYDWORD_0]) -++ FIELD_GET(HECAP_PHY_UL_MUMIMO, hecap_phy[HE_PHYCAP_BYTE_2]) -+ -+ #define HECAP_PHY_ULOFDMA_GET(hecap_phy) \ -+- FIELD_GET(HECAP_PHY_UL_MUOFDMA, hecap_phy[HECAP_PHYDWORD_0]) -++ FIELD_GET(HECAP_PHY_UL_MUOFDMA, hecap_phy[HE_PHYCAP_BYTE_2]) -+ -+ #define HE_MODE_SU_TX_BFEE BIT(0) -+ #define HE_MODE_SU_TX_BFER BIT(1) -diff --git a/package/kernel/mac80211/patches/ath11k/0039-wifi-ath11k-push-MU-MIMO-params-from-hostapd-to-hard.patch b/package/kernel/mac80211/patches/ath11k/0039-wifi-ath11k-push-MU-MIMO-params-from-hostapd-to-hard.patch -new file mode 100644 -index 0000000000..298ce1a612 ---- /dev/null -+++ b/package/kernel/mac80211/patches/ath11k/0039-wifi-ath11k-push-MU-MIMO-params-from-hostapd-to-hard.patch -@@ -0,0 +1,300 @@ -+From 38dfe775d0abf511341f37c1cb77b919a3ad410b Mon Sep 17 00:00:00 2001 -+From: Muna Sinada -+Date: Fri, 24 Feb 2023 12:28:04 +0200 -+Subject: [PATCH] wifi: ath11k: push MU-MIMO params from hostapd to hardware -+ -+In the previous behaviour only HE IE in management frames are changed -+regarding MU-MIMO configurations and not in hardware. Adding push of -+MU-MIMO configurations to the hardware as well. -+ -+Tested-on: IPQ8074 hw2.0 AHB WLAN.HK.2.4.0.1-00356-QCAHKSWPL_SILICONZ-1 -+ -+Co-developed-by: Anilkumar Kolli -+Signed-off-by: Anilkumar Kolli -+Signed-off-by: Muna Sinada -+Signed-off-by: Kalle Valo -+Link: https://lore.kernel.org/r/1666128501-12364-3-git-send-email-quic_msinada@quicinc.com -+--- -+ drivers/net/wireless/ath/ath11k/mac.c | 200 ++++++++++++++++---------- -+ drivers/net/wireless/ath/ath11k/wmi.h | 3 + -+ 2 files changed, 130 insertions(+), 73 deletions(-) -+ -+--- a/drivers/net/wireless/ath/ath11k/mac.c -++++ b/drivers/net/wireless/ath/ath11k/mac.c -+@@ -2699,6 +2699,117 @@ static int ath11k_setup_peer_smps(struct -+ ath11k_smps_map[smps]); -+ } -+ -++static bool ath11k_mac_set_he_txbf_conf(struct ath11k_vif *arvif) -++{ -++ struct ath11k *ar = arvif->ar; -++ u32 param, value; -++ int ret; -++ -++ if (!arvif->vif->bss_conf.he_support) -++ return true; -++ -++ param = WMI_VDEV_PARAM_SET_HEMU_MODE; -++ value = 0; -++ if (arvif->vif->bss_conf.he_su_beamformer) { -++ value |= FIELD_PREP(HE_MODE_SU_TX_BFER, HE_SU_BFER_ENABLE); -++ if (arvif->vif->bss_conf.he_mu_beamformer && -++ arvif->vdev_type == WMI_VDEV_TYPE_AP) -++ value |= FIELD_PREP(HE_MODE_MU_TX_BFER, HE_MU_BFER_ENABLE); -++ } -++ -++ if (arvif->vif->type != NL80211_IFTYPE_MESH_POINT) { -++ value |= FIELD_PREP(HE_MODE_DL_OFDMA, HE_DL_MUOFDMA_ENABLE) | -++ FIELD_PREP(HE_MODE_UL_OFDMA, HE_UL_MUOFDMA_ENABLE); -++ -++ if (arvif->vif->bss_conf.he_full_ul_mumimo) -++ value |= FIELD_PREP(HE_MODE_UL_MUMIMO, HE_UL_MUMIMO_ENABLE); -++ -++ if (arvif->vif->bss_conf.he_su_beamformee) -++ value |= FIELD_PREP(HE_MODE_SU_TX_BFEE, HE_SU_BFEE_ENABLE); -++ } -++ -++ ret = ath11k_wmi_vdev_set_param_cmd(ar, arvif->vdev_id, param, value); -++ if (ret) { -++ ath11k_warn(ar->ab, "failed to set vdev %d HE MU mode: %d\n", -++ arvif->vdev_id, ret); -++ return false; -++ } -++ -++ param = WMI_VDEV_PARAM_SET_HE_SOUNDING_MODE; -++ value = FIELD_PREP(HE_VHT_SOUNDING_MODE, HE_VHT_SOUNDING_MODE_ENABLE) | -++ FIELD_PREP(HE_TRIG_NONTRIG_SOUNDING_MODE, -++ HE_TRIG_NONTRIG_SOUNDING_MODE_ENABLE); -++ ret = ath11k_wmi_vdev_set_param_cmd(ar, arvif->vdev_id, -++ param, value); -++ if (ret) { -++ ath11k_warn(ar->ab, "failed to set vdev %d sounding mode: %d\n", -++ arvif->vdev_id, ret); -++ return false; -++ } -++ return true; -++} -++ -++static bool ath11k_mac_vif_recalc_sta_he_txbf(struct ath11k *ar, -++ struct ieee80211_vif *vif, -++ struct ieee80211_sta_he_cap *he_cap) -++{ -++ struct ath11k_vif *arvif = (void *)vif->drv_priv; -++ struct ieee80211_he_cap_elem he_cap_elem = {0}; -++ struct ieee80211_sta_he_cap *cap_band = NULL; -++ struct cfg80211_chan_def def; -++ u32 param = WMI_VDEV_PARAM_SET_HEMU_MODE; -++ u32 hemode = 0; -++ int ret; -++ -++ if (!vif->bss_conf.he_support) -++ return true; -++ -++ if (vif->type != NL80211_IFTYPE_STATION) -++ return false; -++ -++ if (WARN_ON(ath11k_mac_vif_chan(vif, &def))) -++ return false; -++ -++ if (def.chan->band == NL80211_BAND_2GHZ) -++ cap_band = &ar->mac.iftype[NL80211_BAND_2GHZ][vif->type].he_cap; -++ else -++ cap_band = &ar->mac.iftype[NL80211_BAND_5GHZ][vif->type].he_cap; -++ -++ memcpy(&he_cap_elem, &cap_band->he_cap_elem, sizeof(he_cap_elem)); -++ -++ if (HECAP_PHY_SUBFME_GET(he_cap_elem.phy_cap_info)) { -++ if (HECAP_PHY_SUBFMR_GET(he_cap->he_cap_elem.phy_cap_info)) -++ hemode |= FIELD_PREP(HE_MODE_SU_TX_BFEE, HE_SU_BFEE_ENABLE); -++ if (HECAP_PHY_MUBFMR_GET(he_cap->he_cap_elem.phy_cap_info)) -++ hemode |= FIELD_PREP(HE_MODE_MU_TX_BFEE, HE_MU_BFEE_ENABLE); -++ } -++ -++ if (vif->type != NL80211_IFTYPE_MESH_POINT) { -++ hemode |= FIELD_PREP(HE_MODE_DL_OFDMA, HE_DL_MUOFDMA_ENABLE) | -++ FIELD_PREP(HE_MODE_UL_OFDMA, HE_UL_MUOFDMA_ENABLE); -++ -++ if (HECAP_PHY_ULMUMIMO_GET(he_cap_elem.phy_cap_info)) -++ if (HECAP_PHY_ULMUMIMO_GET(he_cap->he_cap_elem.phy_cap_info)) -++ hemode |= FIELD_PREP(HE_MODE_UL_MUMIMO, -++ HE_UL_MUMIMO_ENABLE); -++ -++ if (FIELD_GET(HE_MODE_MU_TX_BFEE, hemode)) -++ hemode |= FIELD_PREP(HE_MODE_SU_TX_BFEE, HE_SU_BFEE_ENABLE); -++ -++ if (FIELD_GET(HE_MODE_MU_TX_BFER, hemode)) -++ hemode |= FIELD_PREP(HE_MODE_SU_TX_BFER, HE_SU_BFER_ENABLE); -++ } -++ -++ ret = ath11k_wmi_vdev_set_param_cmd(ar, arvif->vdev_id, param, hemode); -++ if (ret) { -++ ath11k_warn(ar->ab, "failed to submit vdev param txbf 0x%x: %d\n", -++ hemode, ret); -++ return false; -++ } -++ -++ return true; -++} -++ -+ static void ath11k_bss_assoc(struct ieee80211_hw *hw, -+ struct ieee80211_vif *vif, -+ struct ieee80211_bss_conf *bss_conf) -+@@ -2709,6 +2820,7 @@ static void ath11k_bss_assoc(struct ieee -+ struct ieee80211_sta *ap_sta; -+ struct ath11k_peer *peer; -+ bool is_auth = false; -++ struct ieee80211_sta_he_cap he_cap; -+ int ret; -+ -+ lockdep_assert_held(&ar->conf_mutex); -+@@ -2726,6 +2838,9 @@ static void ath11k_bss_assoc(struct ieee -+ return; -+ } -+ -++ /* he_cap here is updated at assoc success for sta mode only */ -++ he_cap = ap_sta->deflink.he_cap; -++ -+ ath11k_peer_assoc_prepare(ar, vif, ap_sta, &peer_arg, false); -+ -+ rcu_read_unlock(); -+@@ -2753,6 +2868,12 @@ static void ath11k_bss_assoc(struct ieee -+ return; -+ } -+ -++ if (!ath11k_mac_vif_recalc_sta_he_txbf(ar, vif, &he_cap)) { -++ ath11k_warn(ar->ab, "failed to recalc he txbf for vdev %i on bss %pM\n", -++ arvif->vdev_id, bss_conf->bssid); -++ return; -++ } -++ -+ WARN_ON(arvif->is_up); -+ -+ arvif->aid = vif->cfg.aid; -+@@ -3202,6 +3323,8 @@ static void ath11k_mac_op_bss_info_chang -+ ether_addr_copy(arvif->bssid, info->bssid); -+ -+ if (changed & BSS_CHANGED_BEACON_ENABLED) { -++ if (info->enable_beacon) -++ ath11k_mac_set_he_txbf_conf(arvif); -+ ath11k_control_beaconing(arvif, info); -+ -+ if (arvif->is_up && vif->bss_conf.he_support && -+@@ -5392,6 +5515,10 @@ static int ath11k_mac_copy_he_cap(struct -+ -+ he_cap_elem->mac_cap_info[1] &= -+ IEEE80211_HE_MAC_CAP1_TF_MAC_PAD_DUR_MASK; -++ he_cap_elem->phy_cap_info[0] &= -++ ~IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_160MHZ_IN_5G; -++ he_cap_elem->phy_cap_info[0] &= -++ ~IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_80PLUS80_MHZ_IN_5G; -+ -+ he_cap_elem->phy_cap_info[5] &= -+ ~IEEE80211_HE_PHY_CAP5_BEAMFORMEE_NUM_SND_DIM_UNDER_80MHZ_MASK; -+@@ -6026,69 +6153,6 @@ ath11k_mac_setup_vdev_create_params(stru -+ } -+ } -+ -+-static u32 -+-ath11k_mac_prepare_he_mode(struct ath11k_pdev *pdev, u32 viftype) -+-{ -+- struct ath11k_pdev_cap *pdev_cap = &pdev->cap; -+- struct ath11k_band_cap *cap_band = NULL; -+- u32 *hecap_phy_ptr = NULL; -+- u32 hemode = 0; -+- -+- if (pdev->cap.supported_bands & WMI_HOST_WLAN_2G_CAP) -+- cap_band = &pdev_cap->band[NL80211_BAND_2GHZ]; -+- else -+- cap_band = &pdev_cap->band[NL80211_BAND_5GHZ]; -+- -+- hecap_phy_ptr = &cap_band->he_cap_phy_info[0]; -+- -+- hemode = FIELD_PREP(HE_MODE_SU_TX_BFEE, HE_SU_BFEE_ENABLE) | -+- FIELD_PREP(HE_MODE_SU_TX_BFER, HECAP_PHY_SUBFMR_GET(hecap_phy_ptr)) | -+- FIELD_PREP(HE_MODE_UL_MUMIMO, HECAP_PHY_ULMUMIMO_GET(hecap_phy_ptr)); -+- -+- /* TODO WDS and other modes */ -+- if (viftype == NL80211_IFTYPE_AP) { -+- hemode |= FIELD_PREP(HE_MODE_MU_TX_BFER, -+- HECAP_PHY_MUBFMR_GET(hecap_phy_ptr)) | -+- FIELD_PREP(HE_MODE_DL_OFDMA, HE_DL_MUOFDMA_ENABLE) | -+- FIELD_PREP(HE_MODE_UL_OFDMA, HE_UL_MUOFDMA_ENABLE); -+- } else { -+- hemode |= FIELD_PREP(HE_MODE_MU_TX_BFEE, HE_MU_BFEE_ENABLE); -+- } -+- -+- return hemode; -+-} -+- -+-static int ath11k_set_he_mu_sounding_mode(struct ath11k *ar, -+- struct ath11k_vif *arvif) -+-{ -+- u32 param_id, param_value; -+- struct ath11k_base *ab = ar->ab; -+- int ret = 0; -+- -+- param_id = WMI_VDEV_PARAM_SET_HEMU_MODE; -+- param_value = ath11k_mac_prepare_he_mode(ar->pdev, arvif->vif->type); -+- ret = ath11k_wmi_vdev_set_param_cmd(ar, arvif->vdev_id, -+- param_id, param_value); -+- if (ret) { -+- ath11k_warn(ab, "failed to set vdev %d HE MU mode: %d param_value %x\n", -+- arvif->vdev_id, ret, param_value); -+- return ret; -+- } -+- param_id = WMI_VDEV_PARAM_SET_HE_SOUNDING_MODE; -+- param_value = -+- FIELD_PREP(HE_VHT_SOUNDING_MODE, HE_VHT_SOUNDING_MODE_ENABLE) | -+- FIELD_PREP(HE_TRIG_NONTRIG_SOUNDING_MODE, -+- HE_TRIG_NONTRIG_SOUNDING_MODE_ENABLE); -+- ret = ath11k_wmi_vdev_set_param_cmd(ar, arvif->vdev_id, -+- param_id, param_value); -+- if (ret) { -+- ath11k_warn(ab, "failed to set vdev %d HE MU mode: %d\n", -+- arvif->vdev_id, ret); -+- return ret; -+- } -+- return ret; -+-} -+- -+ static void ath11k_mac_op_update_vif_offload(struct ieee80211_hw *hw, -+ struct ieee80211_vif *vif) -+ { -+@@ -6757,7 +6821,6 @@ ath11k_mac_vdev_start_restart(struct ath -+ struct ath11k_base *ab = ar->ab; -+ struct wmi_vdev_start_req_arg arg = {}; -+ const struct cfg80211_chan_def *chandef = &ctx->def; -+- int he_support = arvif->vif->bss_conf.he_support; -+ int ret = 0; -+ -+ lockdep_assert_held(&ar->conf_mutex); -+@@ -6798,15 +6861,6 @@ ath11k_mac_vdev_start_restart(struct ath -+ spin_lock_bh(&ab->base_lock); -+ arg.regdomain = ar->ab->dfs_region; -+ spin_unlock_bh(&ab->base_lock); -+- -+- if (he_support) { -+- ret = ath11k_set_he_mu_sounding_mode(ar, arvif); -+- if (ret) { -+- ath11k_warn(ar->ab, "failed to set he mode vdev %i\n", -+- arg.vdev_id); -+- return ret; -+- } -+- } -+ } -+ -+ arg.channel.passive |= !!(chandef->chan->flags & IEEE80211_CHAN_NO_IR); -+--- a/drivers/net/wireless/ath/ath11k/wmi.h -++++ b/drivers/net/wireless/ath/ath11k/wmi.h -+@@ -2897,8 +2897,11 @@ struct rx_reorder_queue_remove_params { -+ #define HE_DL_MUOFDMA_ENABLE 1 -+ #define HE_UL_MUOFDMA_ENABLE 1 -+ #define HE_DL_MUMIMO_ENABLE 1 -++#define HE_UL_MUMIMO_ENABLE 1 -+ #define HE_MU_BFEE_ENABLE 1 -+ #define HE_SU_BFEE_ENABLE 1 -++#define HE_MU_BFER_ENABLE 1 -++#define HE_SU_BFER_ENABLE 1 -+ -+ #define HE_VHT_SOUNDING_MODE_ENABLE 1 -+ #define HE_SU_MU_SOUNDING_MODE_ENABLE 1 -diff --git a/package/kernel/mac80211/patches/ath11k/0040-wifi-ath11k-move-HE-MCS-mapper-to-a-separate-functio.patch b/package/kernel/mac80211/patches/ath11k/0040-wifi-ath11k-move-HE-MCS-mapper-to-a-separate-functio.patch -new file mode 100644 -index 0000000000..6bc9880e10 ---- /dev/null -+++ b/package/kernel/mac80211/patches/ath11k/0040-wifi-ath11k-move-HE-MCS-mapper-to-a-separate-functio.patch -@@ -0,0 +1,67 @@ -+From 8077c1bbbc28e527fb29143c46f32c6a9d6cadf0 Mon Sep 17 00:00:00 2001 -+From: Muna Sinada -+Date: Fri, 24 Feb 2023 12:28:04 +0200 -+Subject: [PATCH] wifi: ath11k: move HE MCS mapper to a separate function -+ -+Move HE MCS mapper to a separate function and call new function -+in ath11k_mac_copy_he_cap(). -+ -+Tested-on: IPQ8074 hw2.0 AHB WLAN.HK.2.4.0.1-00356-QCAHKSWPL_SILICONZ-1 -+ -+Signed-off-by: Muna Sinada -+Signed-off-by: Kalle Valo -+Link: https://lore.kernel.org/r/1666128501-12364-4-git-send-email-quic_msinada@quicinc.com -+--- -+ drivers/net/wireless/ath/ath11k/mac.c | 34 +++++++++++++++++---------- -+ 1 file changed, 22 insertions(+), 12 deletions(-) -+ -+--- a/drivers/net/wireless/ath/ath11k/mac.c -++++ b/drivers/net/wireless/ath/ath11k/mac.c -+@@ -5483,6 +5483,27 @@ static __le16 ath11k_mac_setup_he_6ghz_c -+ return cpu_to_le16(bcap->he_6ghz_capa); -+ } -+ -++static void ath11k_mac_set_hemcsmap(struct ath11k *ar, -++ struct ath11k_pdev_cap *cap, -++ struct ieee80211_sta_he_cap *he_cap, -++ int band) -++{ -++ struct ath11k_band_cap *band_cap = &cap->band[band]; -++ -++ he_cap->he_mcs_nss_supp.rx_mcs_80 = -++ cpu_to_le16(band_cap->he_mcs & 0xffff); -++ he_cap->he_mcs_nss_supp.tx_mcs_80 = -++ cpu_to_le16(band_cap->he_mcs & 0xffff); -++ he_cap->he_mcs_nss_supp.rx_mcs_160 = -++ cpu_to_le16((band_cap->he_mcs >> 16) & 0xffff); -++ he_cap->he_mcs_nss_supp.tx_mcs_160 = -++ cpu_to_le16((band_cap->he_mcs >> 16) & 0xffff); -++ he_cap->he_mcs_nss_supp.rx_mcs_80p80 = -++ cpu_to_le16((band_cap->he_mcs >> 16) & 0xffff); -++ he_cap->he_mcs_nss_supp.tx_mcs_80p80 = -++ cpu_to_le16((band_cap->he_mcs >> 16) & 0xffff); -++} -++ -+ static int ath11k_mac_copy_he_cap(struct ath11k *ar, -+ struct ath11k_pdev_cap *cap, -+ struct ieee80211_sband_iftype_data *data, -+@@ -5544,18 +5565,7 @@ static int ath11k_mac_copy_he_cap(struct -+ break; -+ } -+ -+- he_cap->he_mcs_nss_supp.rx_mcs_80 = -+- cpu_to_le16(band_cap->he_mcs & 0xffff); -+- he_cap->he_mcs_nss_supp.tx_mcs_80 = -+- cpu_to_le16(band_cap->he_mcs & 0xffff); -+- he_cap->he_mcs_nss_supp.rx_mcs_160 = -+- cpu_to_le16((band_cap->he_mcs >> 16) & 0xffff); -+- he_cap->he_mcs_nss_supp.tx_mcs_160 = -+- cpu_to_le16((band_cap->he_mcs >> 16) & 0xffff); -+- he_cap->he_mcs_nss_supp.rx_mcs_80p80 = -+- cpu_to_le16((band_cap->he_mcs >> 16) & 0xffff); -+- he_cap->he_mcs_nss_supp.tx_mcs_80p80 = -+- cpu_to_le16((band_cap->he_mcs >> 16) & 0xffff); -++ ath11k_mac_set_hemcsmap(ar, cap, he_cap, band); -+ -+ memset(he_cap->ppe_thres, 0, sizeof(he_cap->ppe_thres)); -+ if (he_cap_elem->phy_cap_info[6] & -diff --git a/package/kernel/mac80211/patches/ath11k/0041-wifi-ath11k-generate-rx-and-tx-mcs-maps-for-supporte.patch b/package/kernel/mac80211/patches/ath11k/0041-wifi-ath11k-generate-rx-and-tx-mcs-maps-for-supporte.patch -new file mode 100644 -index 0000000000..5cb7801b29 ---- /dev/null -+++ b/package/kernel/mac80211/patches/ath11k/0041-wifi-ath11k-generate-rx-and-tx-mcs-maps-for-supporte.patch -@@ -0,0 +1,64 @@ -+From ebf82988f844dd98e6b007cffcc5e95986056995 Mon Sep 17 00:00:00 2001 -+From: Muna Sinada -+Date: Fri, 24 Feb 2023 12:28:04 +0200 -+Subject: [PATCH] wifi: ath11k: generate rx and tx mcs maps for supported HE -+ mcs -+ -+Generate rx and tx mcs maps in ath11k_mac_set_hemcsmap() and set them -+in supported mcs/nss for HE capabilities. -+ -+Tested-on: IPQ8074 hw2.0 AHB WLAN.HK.2.4.0.1-00356-QCAHKSWPL_SILICONZ-1 -+ -+Signed-off-by: Muna Sinada -+Signed-off-by: Kalle Valo -+Link: https://lore.kernel.org/r/1666128501-12364-5-git-send-email-quic_msinada@quicinc.com -+--- -+ drivers/net/wireless/ath/ath11k/mac.c | 30 ++++++++++++++++++++------- -+ 1 file changed, 23 insertions(+), 7 deletions(-) -+ -+--- a/drivers/net/wireless/ath/ath11k/mac.c -++++ b/drivers/net/wireless/ath/ath11k/mac.c -+@@ -5488,20 +5488,36 @@ static void ath11k_mac_set_hemcsmap(stru -+ struct ieee80211_sta_he_cap *he_cap, -+ int band) -+ { -+- struct ath11k_band_cap *band_cap = &cap->band[band]; -++ u16 txmcs_map, rxmcs_map; -++ u32 i; -+ -++ rxmcs_map = 0; -++ txmcs_map = 0; -++ for (i = 0; i < 8; i++) { -++ if (i < ar->num_tx_chains && -++ (ar->cfg_tx_chainmask >> cap->tx_chain_mask_shift) & BIT(i)) -++ txmcs_map |= IEEE80211_HE_MCS_SUPPORT_0_11 << (i * 2); -++ else -++ txmcs_map |= IEEE80211_HE_MCS_NOT_SUPPORTED << (i * 2); -++ -++ if (i < ar->num_rx_chains && -++ (ar->cfg_rx_chainmask >> cap->tx_chain_mask_shift) & BIT(i)) -++ rxmcs_map |= IEEE80211_HE_MCS_SUPPORT_0_11 << (i * 2); -++ else -++ rxmcs_map |= IEEE80211_HE_MCS_NOT_SUPPORTED << (i * 2); -++ } -+ he_cap->he_mcs_nss_supp.rx_mcs_80 = -+- cpu_to_le16(band_cap->he_mcs & 0xffff); -++ cpu_to_le16(rxmcs_map & 0xffff); -+ he_cap->he_mcs_nss_supp.tx_mcs_80 = -+- cpu_to_le16(band_cap->he_mcs & 0xffff); -++ cpu_to_le16(txmcs_map & 0xffff); -+ he_cap->he_mcs_nss_supp.rx_mcs_160 = -+- cpu_to_le16((band_cap->he_mcs >> 16) & 0xffff); -++ cpu_to_le16(rxmcs_map & 0xffff); -+ he_cap->he_mcs_nss_supp.tx_mcs_160 = -+- cpu_to_le16((band_cap->he_mcs >> 16) & 0xffff); -++ cpu_to_le16(txmcs_map & 0xffff); -+ he_cap->he_mcs_nss_supp.rx_mcs_80p80 = -+- cpu_to_le16((band_cap->he_mcs >> 16) & 0xffff); -++ cpu_to_le16(rxmcs_map & 0xffff); -+ he_cap->he_mcs_nss_supp.tx_mcs_80p80 = -+- cpu_to_le16((band_cap->he_mcs >> 16) & 0xffff); -++ cpu_to_le16(txmcs_map & 0xffff); -+ } -+ -+ static int ath11k_mac_copy_he_cap(struct ath11k *ar, -diff --git a/package/kernel/mac80211/patches/ath11k/0042-wifi-ath11k-Add-tx-ack-signal-support-for-management.patch b/package/kernel/mac80211/patches/ath11k/0042-wifi-ath11k-Add-tx-ack-signal-support-for-management.patch -new file mode 100644 -index 0000000000..8d41657311 ---- /dev/null -+++ b/package/kernel/mac80211/patches/ath11k/0042-wifi-ath11k-Add-tx-ack-signal-support-for-management.patch -@@ -0,0 +1,150 @@ -+From 01c6c9fccbd51c1d9eab0f5794b0271b026178df Mon Sep 17 00:00:00 2001 -+From: Abinaya Kalaiselvan -+Date: Mon, 19 Dec 2022 11:08:44 +0530 -+Subject: [PATCH] wifi: ath11k: Add tx ack signal support for management -+ packets -+ -+Add support to notify tx ack signal values for management -+packets to userspace through nl80211 interface. -+ -+Advertise NL80211_EXT_FEATURE_ACK_SIGNAL_SUPPORT flag -+to enable this feature and it will be used for data -+packets as well. -+ -+Tested-on: IPQ8074 hw2.0 AHB WLAN.HK.2.7.0.1-01744-QCAHKSWPL_SILICONZ-1 -+ -+Signed-off-by: Abinaya Kalaiselvan -+Signed-off-by: Maharaja Kennadyrajan -+Signed-off-by: Kalle Valo -+Link: https://lore.kernel.org/r/20221219053844.4084486-1-quic_mkenna@quicinc.com -+--- -+ drivers/net/wireless/ath/ath11k/hw.c | 1 + -+ drivers/net/wireless/ath/ath11k/mac.c | 5 +++++ -+ drivers/net/wireless/ath/ath11k/wmi.c | 27 ++++++++++++++++----------- -+ drivers/net/wireless/ath/ath11k/wmi.h | 3 +++ -+ 4 files changed, 25 insertions(+), 11 deletions(-) -+ -+--- a/drivers/net/wireless/ath/ath11k/hw.c -++++ b/drivers/net/wireless/ath/ath11k/hw.c -+@@ -201,6 +201,7 @@ static void ath11k_init_wmi_config_ipq80 -+ config->twt_ap_pdev_count = ab->num_radios; -+ config->twt_ap_sta_count = 1000; -+ config->flag1 |= WMI_RSRC_CFG_FLAG1_BSS_CHANNEL_INFO_64; -++ config->flag1 |= WMI_RSRC_CFG_FLAG1_ACK_RSSI; -+ } -+ -+ static int ath11k_hw_mac_id_to_pdev_id_ipq8074(struct ath11k_hw_params *hw, -+--- a/drivers/net/wireless/ath/ath11k/mac.c -++++ b/drivers/net/wireless/ath/ath11k/mac.c -+@@ -9174,6 +9174,11 @@ static int __ath11k_mac_register(struct -+ goto err_free_if_combs; -+ } -+ -++ if (test_bit(WMI_TLV_SERVICE_TX_DATA_MGMT_ACK_RSSI, -++ ar->ab->wmi_ab.svc_map)) -++ 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 -+@@ -5229,8 +5229,8 @@ static int ath11k_pull_mgmt_rx_params_tl -+ return 0; -+ } -+ -+-static int wmi_process_mgmt_tx_comp(struct ath11k *ar, u32 desc_id, -+- u32 status) -++static int wmi_process_mgmt_tx_comp(struct ath11k *ar, -++ struct wmi_mgmt_tx_compl_event *tx_compl_param) -+ { -+ struct sk_buff *msdu; -+ struct ieee80211_tx_info *info; -+@@ -5238,24 +5238,29 @@ static int wmi_process_mgmt_tx_comp(stru -+ int num_mgmt; -+ -+ spin_lock_bh(&ar->txmgmt_idr_lock); -+- msdu = idr_find(&ar->txmgmt_idr, desc_id); -++ msdu = idr_find(&ar->txmgmt_idr, tx_compl_param->desc_id); -+ -+ if (!msdu) { -+ ath11k_warn(ar->ab, "received mgmt tx compl for invalid msdu_id: %d\n", -+- desc_id); -++ tx_compl_param->desc_id); -+ spin_unlock_bh(&ar->txmgmt_idr_lock); -+ return -ENOENT; -+ } -+ -+- idr_remove(&ar->txmgmt_idr, desc_id); -++ idr_remove(&ar->txmgmt_idr, tx_compl_param->desc_id); -+ spin_unlock_bh(&ar->txmgmt_idr_lock); -+ -+ skb_cb = ATH11K_SKB_CB(msdu); -+ dma_unmap_single(ar->ab->dev, skb_cb->paddr, msdu->len, DMA_TO_DEVICE); -+ -+ info = IEEE80211_SKB_CB(msdu); -+- if ((!(info->flags & IEEE80211_TX_CTL_NO_ACK)) && !status) -++ if ((!(info->flags & IEEE80211_TX_CTL_NO_ACK)) && -++ !tx_compl_param->status) { -+ info->flags |= IEEE80211_TX_STAT_ACK; -++ if (test_bit(WMI_TLV_SERVICE_TX_DATA_MGMT_ACK_RSSI, -++ ar->ab->wmi_ab.svc_map)) -++ info->status.ack_signal = tx_compl_param->ack_rssi; -++ } -+ -+ ieee80211_tx_status_irqsafe(ar->hw, msdu); -+ -+@@ -5267,7 +5272,7 @@ static int wmi_process_mgmt_tx_comp(stru -+ -+ ath11k_dbg(ar->ab, ATH11K_DBG_WMI, -+ "wmi mgmt tx comp pending %d desc id %d\n", -+- num_mgmt, desc_id); -++ num_mgmt, tx_compl_param->desc_id); -+ -+ if (!num_mgmt) -+ wake_up(&ar->txmgmt_empty_waitq); -+@@ -5300,6 +5305,7 @@ static int ath11k_pull_mgmt_tx_compl_par -+ param->pdev_id = ev->pdev_id; -+ param->desc_id = ev->desc_id; -+ param->status = ev->status; -++ param->ack_rssi = ev->ack_rssi; -+ -+ kfree(tb); -+ return 0; -+@@ -7070,13 +7076,12 @@ static void ath11k_mgmt_tx_compl_event(s -+ goto exit; -+ } -+ -+- wmi_process_mgmt_tx_comp(ar, tx_compl_param.desc_id, -+- tx_compl_param.status); -++ wmi_process_mgmt_tx_comp(ar, &tx_compl_param); -+ -+ ath11k_dbg(ab, ATH11K_DBG_MGMT, -+- "mgmt tx compl ev pdev_id %d, desc_id %d, status %d", -++ "mgmt tx compl ev pdev_id %d, desc_id %d, status %d ack_rssi %d", -+ tx_compl_param.pdev_id, tx_compl_param.desc_id, -+- tx_compl_param.status); -++ tx_compl_param.status, tx_compl_param.ack_rssi); -+ -+ exit: -+ rcu_read_unlock(); -+--- a/drivers/net/wireless/ath/ath11k/wmi.h -++++ b/drivers/net/wireless/ath/ath11k/wmi.h -+@@ -2311,6 +2311,7 @@ struct wmi_init_cmd { -+ } __packed; -+ -+ #define WMI_RSRC_CFG_FLAG1_BSS_CHANNEL_INFO_64 BIT(5) -++#define WMI_RSRC_CFG_FLAG1_ACK_RSSI BIT(18) -+ -+ struct wmi_resource_config { -+ u32 tlv_header; -+@@ -4550,6 +4551,8 @@ struct wmi_mgmt_tx_compl_event { -+ u32 desc_id; -+ u32 status; -+ u32 pdev_id; -++ u32 ppdu_id; -++ u32 ack_rssi; -+ } __packed; -+ -+ struct wmi_scan_event { -diff --git a/package/kernel/mac80211/patches/ath11k/0043-wifi-ath11k-use-proper-regulatory-reference-for-band.patch b/package/kernel/mac80211/patches/ath11k/0043-wifi-ath11k-use-proper-regulatory-reference-for-band.patch -new file mode 100644 -index 0000000000..5bc195528e ---- /dev/null -+++ b/package/kernel/mac80211/patches/ath11k/0043-wifi-ath11k-use-proper-regulatory-reference-for-band.patch -@@ -0,0 +1,216 @@ -+From 25e289e1f52e1f4fb1d07622c6a24f8d8a8e420d Mon Sep 17 00:00:00 2001 -+From: Aditya Kumar Singh -+Date: Wed, 1 Mar 2023 16:20:58 +0200 -+Subject: [PATCH] wifi: ath11k: use proper regulatory reference for bands -+ -+Currently, during regulatory event, 2 GHz/5 GHz is referred -+to as 2G/5G including variable names. However, there is no -+such entity as 2G or 5G. -+ -+Re-name such occurences to its proper name. No functional changes. -+ -+Tested-on: IPQ8074 hw2.0 AHB WLAN.HK.2.7.0.1-01744-QCAHKSWPL_SILICONZ-1 -+Tested-on: QCN9074 hw1.0 PCI WLAN.HK.2.7.0.1-01744-QCAHKSWPL_SILICONZ-1 -+Tested-on: QCN9074 hw1.0 PCI WLAN.HK.2.5.0.1-01100-QCAHKSWPL_SILICONZ-1 -+ -+Signed-off-by: Aditya Kumar Singh -+Signed-off-by: Kalle Valo -+Link: https://lore.kernel.org/r/20230110121024.14051-2-quic_adisi@quicinc.com -+--- -+ drivers/net/wireless/ath/ath11k/reg.c | 20 ++++----- -+ drivers/net/wireless/ath/ath11k/wmi.c | 58 ++++++++++++++------------- -+ drivers/net/wireless/ath/ath11k/wmi.h | 28 ++++++------- -+ 3 files changed, 54 insertions(+), 52 deletions(-) -+ -+--- a/drivers/net/wireless/ath/ath11k/reg.c -++++ b/drivers/net/wireless/ath/ath11k/reg.c -+@@ -619,7 +619,7 @@ ath11k_reg_build_regd(struct ath11k_base -+ u32 flags; -+ char alpha2[3]; -+ -+- num_rules = reg_info->num_5g_reg_rules + reg_info->num_2g_reg_rules; -++ num_rules = reg_info->num_5ghz_reg_rules + reg_info->num_2ghz_reg_rules; -+ -+ if (!num_rules) -+ goto ret; -+@@ -644,20 +644,20 @@ ath11k_reg_build_regd(struct ath11k_base -+ alpha2, ath11k_reg_get_regdom_str(tmp_regd->dfs_region), -+ reg_info->dfs_region, num_rules); -+ /* Update reg_rules[] below. Firmware is expected to -+- * send these rules in order(2G rules first and then 5G) -++ * send these rules in order(2 GHz rules first and then 5 GHz) -+ */ -+ for (; i < num_rules; i++) { -+- if (reg_info->num_2g_reg_rules && -+- (i < reg_info->num_2g_reg_rules)) { -+- reg_rule = reg_info->reg_rules_2g_ptr + i; -++ if (reg_info->num_2ghz_reg_rules && -++ (i < reg_info->num_2ghz_reg_rules)) { -++ reg_rule = reg_info->reg_rules_2ghz_ptr + i; -+ max_bw = min_t(u16, reg_rule->max_bw, -+- reg_info->max_bw_2g); -++ reg_info->max_bw_2ghz); -+ flags = 0; -+- } else if (reg_info->num_5g_reg_rules && -+- (j < reg_info->num_5g_reg_rules)) { -+- reg_rule = reg_info->reg_rules_5g_ptr + j++; -++ } else if (reg_info->num_5ghz_reg_rules && -++ (j < reg_info->num_5ghz_reg_rules)) { -++ reg_rule = reg_info->reg_rules_5ghz_ptr + j++; -+ max_bw = min_t(u16, reg_rule->max_bw, -+- reg_info->max_bw_5g); -++ reg_info->max_bw_5ghz); -+ -+ /* FW doesn't pass NL80211_RRF_AUTO_BW flag for -+ * BW Auto correction, we can enable this by default -+--- a/drivers/net/wireless/ath/ath11k/wmi.c -++++ b/drivers/net/wireless/ath/ath11k/wmi.c -+@@ -4959,7 +4959,7 @@ static int ath11k_pull_reg_chan_list_upd -+ const void **tb; -+ const struct wmi_reg_chan_list_cc_event *chan_list_event_hdr; -+ struct wmi_regulatory_rule_struct *wmi_reg_rule; -+- u32 num_2g_reg_rules, num_5g_reg_rules; -++ u32 num_2ghz_reg_rules, num_5ghz_reg_rules; -+ int ret; -+ -+ ath11k_dbg(ab, ATH11K_DBG_WMI, "processing regulatory channel list\n"); -+@@ -4978,10 +4978,10 @@ static int ath11k_pull_reg_chan_list_upd -+ return -EPROTO; -+ } -+ -+- reg_info->num_2g_reg_rules = chan_list_event_hdr->num_2g_reg_rules; -+- reg_info->num_5g_reg_rules = chan_list_event_hdr->num_5g_reg_rules; -++ reg_info->num_2ghz_reg_rules = chan_list_event_hdr->num_2ghz_reg_rules; -++ reg_info->num_5ghz_reg_rules = chan_list_event_hdr->num_5ghz_reg_rules; -+ -+- if (!(reg_info->num_2g_reg_rules + reg_info->num_5g_reg_rules)) { -++ if (!(reg_info->num_2ghz_reg_rules + reg_info->num_5ghz_reg_rules)) { -+ ath11k_warn(ab, "No regulatory rules available in the event info\n"); -+ kfree(tb); -+ return -EINVAL; -+@@ -5008,46 +5008,48 @@ static int ath11k_pull_reg_chan_list_upd -+ else if (chan_list_event_hdr->status_code == WMI_REG_SET_CC_STATUS_FAIL) -+ reg_info->status_code = REG_SET_CC_STATUS_FAIL; -+ -+- reg_info->min_bw_2g = chan_list_event_hdr->min_bw_2g; -+- reg_info->max_bw_2g = chan_list_event_hdr->max_bw_2g; -+- reg_info->min_bw_5g = chan_list_event_hdr->min_bw_5g; -+- reg_info->max_bw_5g = chan_list_event_hdr->max_bw_5g; -++ reg_info->min_bw_2ghz = chan_list_event_hdr->min_bw_2ghz; -++ reg_info->max_bw_2ghz = chan_list_event_hdr->max_bw_2ghz; -++ reg_info->min_bw_5ghz = chan_list_event_hdr->min_bw_5ghz; -++ reg_info->max_bw_5ghz = chan_list_event_hdr->max_bw_5ghz; -+ -+- num_2g_reg_rules = reg_info->num_2g_reg_rules; -+- num_5g_reg_rules = reg_info->num_5g_reg_rules; -++ num_2ghz_reg_rules = reg_info->num_2ghz_reg_rules; -++ num_5ghz_reg_rules = reg_info->num_5ghz_reg_rules; -+ -+ ath11k_dbg(ab, ATH11K_DBG_WMI, -+- "%s:cc %s dsf %d BW: min_2g %d max_2g %d min_5g %d max_5g %d", -++ "%s:cc %s dsf %d BW: min_2ghz %d max_2ghz %d min_5ghz %d max_5ghz %d", -+ __func__, reg_info->alpha2, reg_info->dfs_region, -+- reg_info->min_bw_2g, reg_info->max_bw_2g, -+- reg_info->min_bw_5g, reg_info->max_bw_5g); -++ reg_info->min_bw_2ghz, reg_info->max_bw_2ghz, -++ reg_info->min_bw_5ghz, reg_info->max_bw_5ghz); -+ -+ ath11k_dbg(ab, ATH11K_DBG_WMI, -+- "%s: num_2g_reg_rules %d num_5g_reg_rules %d", __func__, -+- num_2g_reg_rules, num_5g_reg_rules); -++ "%s: num_2ghz_reg_rules %d num_5ghz_reg_rules %d", __func__, -++ num_2ghz_reg_rules, num_5ghz_reg_rules); -+ -+ wmi_reg_rule = -+ (struct wmi_regulatory_rule_struct *)((u8 *)chan_list_event_hdr -+ + sizeof(*chan_list_event_hdr) -+ + sizeof(struct wmi_tlv)); -+ -+- if (num_2g_reg_rules) { -+- reg_info->reg_rules_2g_ptr = create_reg_rules_from_wmi(num_2g_reg_rules, -+- wmi_reg_rule); -+- if (!reg_info->reg_rules_2g_ptr) { -++ if (num_2ghz_reg_rules) { -++ reg_info->reg_rules_2ghz_ptr = -++ create_reg_rules_from_wmi(num_2ghz_reg_rules, -++ wmi_reg_rule); -++ if (!reg_info->reg_rules_2ghz_ptr) { -+ kfree(tb); -+- ath11k_warn(ab, "Unable to Allocate memory for 2g rules\n"); -++ ath11k_warn(ab, "Unable to Allocate memory for 2 GHz rules\n"); -+ return -ENOMEM; -+ } -+ } -+ -+- if (num_5g_reg_rules) { -+- wmi_reg_rule += num_2g_reg_rules; -+- reg_info->reg_rules_5g_ptr = create_reg_rules_from_wmi(num_5g_reg_rules, -+- wmi_reg_rule); -+- if (!reg_info->reg_rules_5g_ptr) { -++ if (num_5ghz_reg_rules) { -++ wmi_reg_rule += num_2ghz_reg_rules; -++ reg_info->reg_rules_5ghz_ptr = -++ create_reg_rules_from_wmi(num_5ghz_reg_rules, -++ wmi_reg_rule); -++ if (!reg_info->reg_rules_5ghz_ptr) { -+ kfree(tb); -+- ath11k_warn(ab, "Unable to Allocate memory for 5g rules\n"); -++ ath11k_warn(ab, "Unable to Allocate memory for 5 GHz rules\n"); -+ return -ENOMEM; -+ } -+ } -+@@ -6619,8 +6621,8 @@ fallback: -+ WARN_ON(1); -+ mem_free: -+ if (reg_info) { -+- kfree(reg_info->reg_rules_2g_ptr); -+- kfree(reg_info->reg_rules_5g_ptr); -++ kfree(reg_info->reg_rules_2ghz_ptr); -++ kfree(reg_info->reg_rules_5ghz_ptr); -+ kfree(reg_info); -+ } -+ return ret; -+--- a/drivers/net/wireless/ath/ath11k/wmi.h -++++ b/drivers/net/wireless/ath/ath11k/wmi.h -+@@ -4129,14 +4129,14 @@ struct cur_regulatory_info { -+ u8 alpha2[REG_ALPHA2_LEN + 1]; -+ u32 dfs_region; -+ u32 phybitmap; -+- u32 min_bw_2g; -+- u32 max_bw_2g; -+- u32 min_bw_5g; -+- u32 max_bw_5g; -+- u32 num_2g_reg_rules; -+- u32 num_5g_reg_rules; -+- struct cur_reg_rule *reg_rules_2g_ptr; -+- struct cur_reg_rule *reg_rules_5g_ptr; -++ u32 min_bw_2ghz; -++ u32 max_bw_2ghz; -++ u32 min_bw_5ghz; -++ u32 max_bw_5ghz; -++ u32 num_2ghz_reg_rules; -++ u32 num_5ghz_reg_rules; -++ struct cur_reg_rule *reg_rules_2ghz_ptr; -++ struct cur_reg_rule *reg_rules_5ghz_ptr; -+ }; -+ -+ struct wmi_reg_chan_list_cc_event { -+@@ -4148,12 +4148,12 @@ struct wmi_reg_chan_list_cc_event { -+ u32 domain_code; -+ u32 dfs_region; -+ u32 phybitmap; -+- u32 min_bw_2g; -+- u32 max_bw_2g; -+- u32 min_bw_5g; -+- u32 max_bw_5g; -+- u32 num_2g_reg_rules; -+- u32 num_5g_reg_rules; -++ u32 min_bw_2ghz; -++ u32 max_bw_2ghz; -++ u32 min_bw_5ghz; -++ u32 max_bw_5ghz; -++ u32 num_2ghz_reg_rules; -++ u32 num_5ghz_reg_rules; -+ } __packed; -+ -+ struct wmi_regulatory_rule_struct { -diff --git a/package/kernel/mac80211/patches/ath11k/0044-wifi-ath11k-add-support-to-parse-new-WMI-event-for-6.patch b/package/kernel/mac80211/patches/ath11k/0044-wifi-ath11k-add-support-to-parse-new-WMI-event-for-6.patch -new file mode 100644 -index 0000000000..e165c09dc4 ---- /dev/null -+++ b/package/kernel/mac80211/patches/ath11k/0044-wifi-ath11k-add-support-to-parse-new-WMI-event-for-6.patch -@@ -0,0 +1,844 @@ -+From 91fa00fa69224aae5afb720c5e68b22e4c4f7333 Mon Sep 17 00:00:00 2001 -+From: Aditya Kumar Singh -+Date: Wed, 1 Mar 2023 16:20:59 +0200 -+Subject: [PATCH] wifi: ath11k: add support to parse new WMI event for 6 GHz -+ -+In order to support different power levels of 6 GHz AP and client, -+new WMI event for regulatory - WMI_REG_CHAN_LIST_CC_EXT_EVENTID is -+added in firmware. This event provides new parameters required for -+6 GHz regulatory rules. -+ -+Add support for parsing 2.4 GHz, 5 GHz and 6 GHz reg rules and other -+parameters from WMI_REG_CHAN_LIST_CC_EXT_EVENTID. -+ -+Tested-on: IPQ8074 hw2.0 AHB WLAN.HK.2.7.0.1-01744-QCAHKSWPL_SILICONZ-1 -+Tested-on: QCN9074 hw1.0 PCI WLAN.HK.2.7.0.1-01744-QCAHKSWPL_SILICONZ-1 -+Tested-on: QCN9074 hw1.0 PCI WLAN.HK.2.5.0.1-01100-QCAHKSWPL_SILICONZ-1 -+ -+Signed-off-by: Lavanya Suresh -+Signed-off-by: Wen Gong -+Signed-off-by: Aditya Kumar Singh -+Signed-off-by: Kalle Valo -+Link: https://lore.kernel.org/r/20230110121024.14051-3-quic_adisi@quicinc.com -+--- -+ drivers/net/wireless/ath/ath11k/reg.c | 37 ++- -+ drivers/net/wireless/ath/ath11k/wmi.c | 418 +++++++++++++++++++++++++- -+ drivers/net/wireless/ath/ath11k/wmi.h | 163 +++++++++- -+ 3 files changed, 584 insertions(+), 34 deletions(-) -+ -+--- a/drivers/net/wireless/ath/ath11k/reg.c -++++ b/drivers/net/wireless/ath/ath11k/reg.c -+@@ -613,7 +613,7 @@ ath11k_reg_build_regd(struct ath11k_base -+ { -+ struct ieee80211_regdomain *tmp_regd, *default_regd, *new_regd = NULL; -+ struct cur_reg_rule *reg_rule; -+- u8 i = 0, j = 0; -++ u8 i = 0, j = 0, k = 0; -+ u8 num_rules; -+ u16 max_bw; -+ u32 flags; -+@@ -621,6 +621,12 @@ ath11k_reg_build_regd(struct ath11k_base -+ -+ num_rules = reg_info->num_5ghz_reg_rules + reg_info->num_2ghz_reg_rules; -+ -++ /* FIXME: Currently taking reg rules for 6 GHz only from Indoor AP mode list. -++ * This can be updated after complete 6 GHz regulatory support is added. -++ */ -++ if (reg_info->is_ext_reg_event) -++ num_rules += reg_info->num_6ghz_rules_ap[WMI_REG_INDOOR_AP]; -++ -+ if (!num_rules) -+ goto ret; -+ -+@@ -666,6 +672,14 @@ ath11k_reg_build_regd(struct ath11k_base -+ * per other BW rule flags we pass from here -+ */ -+ flags = NL80211_RRF_AUTO_BW; -++ } else if (reg_info->is_ext_reg_event && -++ reg_info->num_6ghz_rules_ap[WMI_REG_INDOOR_AP] && -++ (k < reg_info->num_6ghz_rules_ap[WMI_REG_INDOOR_AP])) { -++ reg_rule = reg_info->reg_rules_6ghz_ap_ptr[WMI_REG_INDOOR_AP] + -++ k++; -++ max_bw = min_t(u16, reg_rule->max_bw, -++ reg_info->max_bw_6ghz_ap[WMI_REG_INDOOR_AP]); -++ flags = NL80211_RRF_AUTO_BW; -+ } else { -+ break; -+ } -+@@ -693,12 +707,21 @@ ath11k_reg_build_regd(struct ath11k_base -+ continue; -+ } -+ -+- ath11k_dbg(ab, ATH11K_DBG_REG, -+- "\t%d. (%d - %d @ %d) (%d, %d) (%d ms) (FLAGS %d)\n", -+- i + 1, reg_rule->start_freq, reg_rule->end_freq, -+- max_bw, reg_rule->ant_gain, reg_rule->reg_power, -+- tmp_regd->reg_rules[i].dfs_cac_ms, -+- flags); -++ if (reg_info->is_ext_reg_event) { -++ ath11k_dbg(ab, ATH11K_DBG_REG, -++ "\t%d. (%d - %d @ %d) (%d, %d) (%d ms) (FLAGS %d) (%d, %d)\n", -++ i + 1, reg_rule->start_freq, reg_rule->end_freq, -++ max_bw, reg_rule->ant_gain, reg_rule->reg_power, -++ tmp_regd->reg_rules[i].dfs_cac_ms, flags, -++ reg_rule->psd_flag, reg_rule->psd_eirp); -++ } else { -++ ath11k_dbg(ab, ATH11K_DBG_REG, -++ "\t%d. (%d - %d @ %d) (%d, %d) (%d ms) (FLAGS %d)\n", -++ i + 1, reg_rule->start_freq, reg_rule->end_freq, -++ max_bw, reg_rule->ant_gain, reg_rule->reg_power, -++ tmp_regd->reg_rules[i].dfs_cac_ms, -++ flags); -++ } -+ } -+ -+ tmp_regd->n_reg_rules = i; -+--- a/drivers/net/wireless/ath/ath11k/wmi.c -++++ b/drivers/net/wireless/ath/ath11k/wmi.c -+@@ -105,6 +105,8 @@ static const struct wmi_tlv_policy wmi_t -+ = { .min_len = sizeof(struct wmi_vdev_stopped_event) }, -+ [WMI_TAG_REG_CHAN_LIST_CC_EVENT] -+ = { .min_len = sizeof(struct 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) }, -+ [WMI_TAG_MGMT_RX_HDR] -+ = { .min_len = sizeof(struct wmi_mgmt_rx_hdr) }, -+ [WMI_TAG_MGMT_TX_COMPL_EVENT] -+@@ -3974,6 +3976,10 @@ ath11k_wmi_copy_resource_config(struct w -+ wmi_cfg->sched_params = tg_cfg->sched_params; -+ wmi_cfg->twt_ap_pdev_count = tg_cfg->twt_ap_pdev_count; -+ wmi_cfg->twt_ap_sta_count = tg_cfg->twt_ap_sta_count; -++ wmi_cfg->host_service_flags &= -++ ~(1 << WMI_CFG_HOST_SERVICE_FLAG_REG_CC_EXT); -++ wmi_cfg->host_service_flags |= (tg_cfg->is_reg_cc_ext_event_supported << -++ WMI_CFG_HOST_SERVICE_FLAG_REG_CC_EXT); -+ } -+ -+ static int ath11k_init_cmd_send(struct ath11k_pdev_wmi *wmi, -+@@ -4192,6 +4198,10 @@ int ath11k_wmi_cmd_init(struct ath11k_ba -+ -+ ab->hw_params.hw_ops->wmi_init_config(ab, &config); -+ -++ if (test_bit(WMI_TLV_SERVICE_REG_CC_EXT_EVENT_SUPPORT, -++ ab->wmi_ab.svc_map)) -++ config.is_reg_cc_ext_event_supported = 1; -++ -+ memcpy(&wmi_sc->wlan_resource_config, &config, sizeof(config)); -+ -+ init_param.res_cfg = &wmi_sc->wlan_resource_config; -+@@ -4995,18 +5005,11 @@ static int ath11k_pull_reg_chan_list_upd -+ reg_info->phy_id = chan_list_event_hdr->phy_id; -+ reg_info->ctry_code = chan_list_event_hdr->country_id; -+ reg_info->reg_dmn_pair = chan_list_event_hdr->domain_code; -+- if (chan_list_event_hdr->status_code == WMI_REG_SET_CC_STATUS_PASS) -+- reg_info->status_code = REG_SET_CC_STATUS_PASS; -+- else if (chan_list_event_hdr->status_code == WMI_REG_CURRENT_ALPHA2_NOT_FOUND) -+- reg_info->status_code = REG_CURRENT_ALPHA2_NOT_FOUND; -+- else if (chan_list_event_hdr->status_code == WMI_REG_INIT_ALPHA2_NOT_FOUND) -+- reg_info->status_code = REG_INIT_ALPHA2_NOT_FOUND; -+- else if (chan_list_event_hdr->status_code == WMI_REG_SET_CC_CHANGE_NOT_ALLOWED) -+- reg_info->status_code = REG_SET_CC_CHANGE_NOT_ALLOWED; -+- else if (chan_list_event_hdr->status_code == WMI_REG_SET_CC_STATUS_NO_MEMORY) -+- reg_info->status_code = REG_SET_CC_STATUS_NO_MEMORY; -+- else if (chan_list_event_hdr->status_code == WMI_REG_SET_CC_STATUS_FAIL) -+- reg_info->status_code = REG_SET_CC_STATUS_FAIL; -++ -++ reg_info->status_code = -++ ath11k_wmi_cc_setting_code_to_reg(chan_list_event_hdr->status_code); -++ -++ reg_info->is_ext_reg_event = false; -+ -+ reg_info->min_bw_2ghz = chan_list_event_hdr->min_bw_2ghz; -+ reg_info->max_bw_2ghz = chan_list_event_hdr->max_bw_2ghz; -+@@ -5060,6 +5063,372 @@ static int ath11k_pull_reg_chan_list_upd -+ return 0; -+ } -+ -++static struct cur_reg_rule -++*create_ext_reg_rules_from_wmi(u32 num_reg_rules, -++ struct wmi_regulatory_ext_rule *wmi_reg_rule) -++{ -++ struct cur_reg_rule *reg_rule_ptr; -++ u32 count; -++ -++ reg_rule_ptr = kcalloc(num_reg_rules, sizeof(*reg_rule_ptr), GFP_ATOMIC); -++ -++ if (!reg_rule_ptr) -++ return NULL; -++ -++ for (count = 0; count < num_reg_rules; count++) { -++ reg_rule_ptr[count].start_freq = -++ u32_get_bits(wmi_reg_rule[count].freq_info, -++ REG_RULE_START_FREQ); -++ reg_rule_ptr[count].end_freq = -++ u32_get_bits(wmi_reg_rule[count].freq_info, -++ REG_RULE_END_FREQ); -++ reg_rule_ptr[count].max_bw = -++ u32_get_bits(wmi_reg_rule[count].bw_pwr_info, -++ REG_RULE_MAX_BW); -++ reg_rule_ptr[count].reg_power = -++ u32_get_bits(wmi_reg_rule[count].bw_pwr_info, -++ REG_RULE_REG_PWR); -++ reg_rule_ptr[count].ant_gain = -++ u32_get_bits(wmi_reg_rule[count].bw_pwr_info, -++ REG_RULE_ANT_GAIN); -++ reg_rule_ptr[count].flags = -++ u32_get_bits(wmi_reg_rule[count].flag_info, -++ REG_RULE_FLAGS); -++ reg_rule_ptr[count].psd_flag = -++ u32_get_bits(wmi_reg_rule[count].psd_power_info, -++ REG_RULE_PSD_INFO); -++ reg_rule_ptr[count].psd_eirp = -++ u32_get_bits(wmi_reg_rule[count].psd_power_info, -++ REG_RULE_PSD_EIRP); -++ } -++ -++ return reg_rule_ptr; -++} -++ -++static u8 -++ath11k_invalid_5ghz_reg_ext_rules_from_wmi(u32 num_reg_rules, -++ const struct wmi_regulatory_ext_rule *rule) -++{ -++ u8 num_invalid_5ghz_rules = 0; -++ u32 count, start_freq; -++ -++ for (count = 0; count < num_reg_rules; count++) { -++ start_freq = u32_get_bits(rule[count].freq_info, -++ REG_RULE_START_FREQ); -++ -++ if (start_freq >= ATH11K_MIN_6G_FREQ) -++ num_invalid_5ghz_rules++; -++ } -++ -++ return num_invalid_5ghz_rules; -++} -++ -++static int ath11k_pull_reg_chan_list_ext_update_ev(struct ath11k_base *ab, -++ struct sk_buff *skb, -++ struct cur_regulatory_info *reg_info) -++{ -++ const void **tb; -++ const struct wmi_reg_chan_list_cc_ext_event *ext_chan_list_event_hdr; -++ struct wmi_regulatory_ext_rule *ext_wmi_reg_rule; -++ u32 num_2ghz_reg_rules, num_5ghz_reg_rules; -++ u32 num_6ghz_reg_rules_ap[WMI_REG_CURRENT_MAX_AP_TYPE]; -++ u32 num_6ghz_client[WMI_REG_CURRENT_MAX_AP_TYPE][WMI_REG_MAX_CLIENT_TYPE]; -++ u32 total_reg_rules = 0; -++ int ret, i, j, num_invalid_5ghz_ext_rules = 0; -++ -++ ath11k_dbg(ab, ATH11K_DBG_WMI, "processing regulatory ext channel list\n"); -++ -++ 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; -++ } -++ -++ ext_chan_list_event_hdr = tb[WMI_TAG_REG_CHAN_LIST_CC_EXT_EVENT]; -++ if (!ext_chan_list_event_hdr) { -++ ath11k_warn(ab, "failed to fetch reg chan list ext update ev\n"); -++ kfree(tb); -++ return -EPROTO; -++ } -++ -++ reg_info->num_2ghz_reg_rules = -++ ext_chan_list_event_hdr->num_2ghz_reg_rules; -++ reg_info->num_5ghz_reg_rules = -++ ext_chan_list_event_hdr->num_5ghz_reg_rules; -++ reg_info->num_6ghz_rules_ap[WMI_REG_INDOOR_AP] = -++ ext_chan_list_event_hdr->num_6ghz_reg_rules_ap_lpi; -++ reg_info->num_6ghz_rules_ap[WMI_REG_STANDARD_POWER_AP] = -++ ext_chan_list_event_hdr->num_6ghz_reg_rules_ap_sp; -++ reg_info->num_6ghz_rules_ap[WMI_REG_VERY_LOW_POWER_AP] = -++ ext_chan_list_event_hdr->num_6ghz_reg_rules_ap_vlp; -++ -++ for (i = 0; i < WMI_REG_MAX_CLIENT_TYPE; i++) { -++ reg_info->num_6ghz_rules_client[WMI_REG_INDOOR_AP][i] = -++ ext_chan_list_event_hdr->num_6ghz_reg_rules_client_lpi[i]; -++ reg_info->num_6ghz_rules_client[WMI_REG_STANDARD_POWER_AP][i] = -++ ext_chan_list_event_hdr->num_6ghz_reg_rules_client_sp[i]; -++ reg_info->num_6ghz_rules_client[WMI_REG_VERY_LOW_POWER_AP][i] = -++ ext_chan_list_event_hdr->num_6ghz_reg_rules_client_vlp[i]; -++ } -++ -++ num_2ghz_reg_rules = reg_info->num_2ghz_reg_rules; -++ num_5ghz_reg_rules = reg_info->num_5ghz_reg_rules; -++ -++ total_reg_rules += num_2ghz_reg_rules; -++ total_reg_rules += num_5ghz_reg_rules; -++ -++ if ((num_2ghz_reg_rules > MAX_REG_RULES) || -++ (num_5ghz_reg_rules > MAX_REG_RULES)) { -++ ath11k_warn(ab, "Num reg rules for 2.4 GHz/5 GHz exceeds max limit (num_2ghz_reg_rules: %d num_5ghz_reg_rules: %d max_rules: %d)\n", -++ num_2ghz_reg_rules, num_5ghz_reg_rules, MAX_REG_RULES); -++ kfree(tb); -++ return -EINVAL; -++ } -++ -++ for (i = 0; i < WMI_REG_CURRENT_MAX_AP_TYPE; i++) { -++ num_6ghz_reg_rules_ap[i] = reg_info->num_6ghz_rules_ap[i]; -++ -++ if (num_6ghz_reg_rules_ap[i] > MAX_6GHZ_REG_RULES) { -++ ath11k_warn(ab, "Num 6 GHz reg rules for AP mode(%d) exceeds max limit (num_6ghz_reg_rules_ap: %d, max_rules: %d)\n", -++ i, num_6ghz_reg_rules_ap[i], MAX_6GHZ_REG_RULES); -++ kfree(tb); -++ return -EINVAL; -++ } -++ -++ total_reg_rules += num_6ghz_reg_rules_ap[i]; -++ } -++ -++ for (i = 0; i < WMI_REG_MAX_CLIENT_TYPE; i++) { -++ num_6ghz_client[WMI_REG_INDOOR_AP][i] = -++ reg_info->num_6ghz_rules_client[WMI_REG_INDOOR_AP][i]; -++ total_reg_rules += num_6ghz_client[WMI_REG_INDOOR_AP][i]; -++ -++ num_6ghz_client[WMI_REG_STANDARD_POWER_AP][i] = -++ reg_info->num_6ghz_rules_client[WMI_REG_STANDARD_POWER_AP][i]; -++ total_reg_rules += num_6ghz_client[WMI_REG_STANDARD_POWER_AP][i]; -++ -++ num_6ghz_client[WMI_REG_VERY_LOW_POWER_AP][i] = -++ reg_info->num_6ghz_rules_client[WMI_REG_VERY_LOW_POWER_AP][i]; -++ total_reg_rules += num_6ghz_client[WMI_REG_VERY_LOW_POWER_AP][i]; -++ -++ if ((num_6ghz_client[WMI_REG_INDOOR_AP][i] > MAX_6GHZ_REG_RULES) || -++ (num_6ghz_client[WMI_REG_STANDARD_POWER_AP][i] > -++ MAX_6GHZ_REG_RULES) || -++ (num_6ghz_client[WMI_REG_VERY_LOW_POWER_AP][i] > -++ MAX_6GHZ_REG_RULES)) { -++ ath11k_warn(ab, -++ "Num 6 GHz client reg rules exceeds max limit, for client(type: %d)\n", -++ i); -++ kfree(tb); -++ return -EINVAL; -++ } -++ } -++ -++ if (!total_reg_rules) { -++ ath11k_warn(ab, "No reg rules available\n"); -++ kfree(tb); -++ return -EINVAL; -++ } -++ -++ memcpy(reg_info->alpha2, &ext_chan_list_event_hdr->alpha2, -++ REG_ALPHA2_LEN); -++ -++ reg_info->dfs_region = ext_chan_list_event_hdr->dfs_region; -++ reg_info->phybitmap = ext_chan_list_event_hdr->phybitmap; -++ reg_info->num_phy = ext_chan_list_event_hdr->num_phy; -++ reg_info->phy_id = ext_chan_list_event_hdr->phy_id; -++ reg_info->ctry_code = ext_chan_list_event_hdr->country_id; -++ reg_info->reg_dmn_pair = ext_chan_list_event_hdr->domain_code; -++ -++ reg_info->status_code = -++ ath11k_wmi_cc_setting_code_to_reg(ext_chan_list_event_hdr->status_code); -++ -++ reg_info->is_ext_reg_event = true; -++ -++ reg_info->min_bw_2ghz = ext_chan_list_event_hdr->min_bw_2ghz; -++ reg_info->max_bw_2ghz = ext_chan_list_event_hdr->max_bw_2ghz; -++ reg_info->min_bw_5ghz = ext_chan_list_event_hdr->min_bw_5ghz; -++ reg_info->max_bw_5ghz = ext_chan_list_event_hdr->max_bw_5ghz; -++ -++ reg_info->min_bw_6ghz_ap[WMI_REG_INDOOR_AP] = -++ ext_chan_list_event_hdr->min_bw_6ghz_ap_lpi; -++ reg_info->max_bw_6ghz_ap[WMI_REG_INDOOR_AP] = -++ ext_chan_list_event_hdr->max_bw_6ghz_ap_lpi; -++ reg_info->min_bw_6ghz_ap[WMI_REG_STANDARD_POWER_AP] = -++ ext_chan_list_event_hdr->min_bw_6ghz_ap_sp; -++ reg_info->max_bw_6ghz_ap[WMI_REG_STANDARD_POWER_AP] = -++ ext_chan_list_event_hdr->max_bw_6ghz_ap_sp; -++ reg_info->min_bw_6ghz_ap[WMI_REG_VERY_LOW_POWER_AP] = -++ ext_chan_list_event_hdr->min_bw_6ghz_ap_vlp; -++ reg_info->max_bw_6ghz_ap[WMI_REG_VERY_LOW_POWER_AP] = -++ ext_chan_list_event_hdr->max_bw_6ghz_ap_vlp; -++ -++ for (i = 0; i < WMI_REG_MAX_CLIENT_TYPE; i++) { -++ reg_info->min_bw_6ghz_client[WMI_REG_INDOOR_AP][i] = -++ ext_chan_list_event_hdr->min_bw_6ghz_client_lpi[i]; -++ reg_info->max_bw_6ghz_client[WMI_REG_INDOOR_AP][i] = -++ ext_chan_list_event_hdr->max_bw_6ghz_client_lpi[i]; -++ reg_info->min_bw_6ghz_client[WMI_REG_STANDARD_POWER_AP][i] = -++ ext_chan_list_event_hdr->min_bw_6ghz_client_sp[i]; -++ reg_info->max_bw_6ghz_client[WMI_REG_STANDARD_POWER_AP][i] = -++ ext_chan_list_event_hdr->max_bw_6ghz_client_sp[i]; -++ reg_info->min_bw_6ghz_client[WMI_REG_VERY_LOW_POWER_AP][i] = -++ ext_chan_list_event_hdr->min_bw_6ghz_client_vlp[i]; -++ reg_info->max_bw_6ghz_client[WMI_REG_VERY_LOW_POWER_AP][i] = -++ ext_chan_list_event_hdr->max_bw_6ghz_client_vlp[i]; -++ } -++ -++ ath11k_dbg(ab, ATH11K_DBG_WMI, -++ "%s:cc_ext %s dsf %d BW: min_2ghz %d max_2ghz %d min_5ghz %d max_5ghz %d", -++ __func__, reg_info->alpha2, reg_info->dfs_region, -++ reg_info->min_bw_2ghz, reg_info->max_bw_2ghz, -++ reg_info->min_bw_5ghz, reg_info->max_bw_5ghz); -++ -++ ath11k_dbg(ab, ATH11K_DBG_WMI, -++ "num_2ghz_reg_rules %d num_5ghz_reg_rules %d", -++ num_2ghz_reg_rules, num_5ghz_reg_rules); -++ -++ ath11k_dbg(ab, ATH11K_DBG_WMI, -++ "num_6ghz_reg_rules_ap_lpi: %d num_6ghz_reg_rules_ap_sp: %d num_6ghz_reg_rules_ap_vlp: %d", -++ num_6ghz_reg_rules_ap[WMI_REG_INDOOR_AP], -++ num_6ghz_reg_rules_ap[WMI_REG_STANDARD_POWER_AP], -++ num_6ghz_reg_rules_ap[WMI_REG_VERY_LOW_POWER_AP]); -++ -++ j = WMI_REG_DEFAULT_CLIENT; -++ ath11k_dbg(ab, ATH11K_DBG_WMI, -++ "6 GHz Regular client: num_6ghz_reg_rules_lpi: %d num_6ghz_reg_rules_sp: %d num_6ghz_reg_rules_vlp: %d", -++ num_6ghz_client[WMI_REG_INDOOR_AP][j], -++ num_6ghz_client[WMI_REG_STANDARD_POWER_AP][j], -++ num_6ghz_client[WMI_REG_VERY_LOW_POWER_AP][j]); -++ -++ j = WMI_REG_SUBORDINATE_CLIENT; -++ ath11k_dbg(ab, ATH11K_DBG_WMI, -++ "6 GHz Subordinate client: num_6ghz_reg_rules_lpi: %d num_6ghz_reg_rules_sp: %d num_6ghz_reg_rules_vlp: %d", -++ num_6ghz_client[WMI_REG_INDOOR_AP][j], -++ num_6ghz_client[WMI_REG_STANDARD_POWER_AP][j], -++ num_6ghz_client[WMI_REG_VERY_LOW_POWER_AP][j]); -++ -++ ext_wmi_reg_rule = -++ (struct wmi_regulatory_ext_rule *)((u8 *)ext_chan_list_event_hdr -++ + sizeof(*ext_chan_list_event_hdr) -++ + sizeof(struct wmi_tlv)); -++ if (num_2ghz_reg_rules) { -++ reg_info->reg_rules_2ghz_ptr = -++ create_ext_reg_rules_from_wmi(num_2ghz_reg_rules, -++ ext_wmi_reg_rule); -++ -++ if (!reg_info->reg_rules_2ghz_ptr) { -++ kfree(tb); -++ ath11k_warn(ab, "Unable to Allocate memory for 2 GHz rules\n"); -++ return -ENOMEM; -++ } -++ } -++ -++ ext_wmi_reg_rule += num_2ghz_reg_rules; -++ -++ /* Firmware might include 6 GHz reg rule in 5 GHz rule list -++ * for few countries along with separate 6 GHz rule. -++ * Having same 6 GHz reg rule in 5 GHz and 6 GHz rules list -++ * causes intersect check to be true, and same rules will be -++ * shown multiple times in iw cmd. -++ * Hence, avoid parsing 6 GHz rule from 5 GHz reg rule list -++ */ -++ num_invalid_5ghz_ext_rules = -++ ath11k_invalid_5ghz_reg_ext_rules_from_wmi(num_5ghz_reg_rules, -++ ext_wmi_reg_rule); -++ -++ if (num_invalid_5ghz_ext_rules) { -++ ath11k_dbg(ab, ATH11K_DBG_WMI, -++ "CC: %s 5 GHz reg rules number %d from fw, %d number of invalid 5 GHz rules", -++ reg_info->alpha2, reg_info->num_5ghz_reg_rules, -++ num_invalid_5ghz_ext_rules); -++ -++ num_5ghz_reg_rules = num_5ghz_reg_rules - num_invalid_5ghz_ext_rules; -++ reg_info->num_5ghz_reg_rules = num_5ghz_reg_rules; -++ } -++ -++ if (num_5ghz_reg_rules) { -++ reg_info->reg_rules_5ghz_ptr = -++ create_ext_reg_rules_from_wmi(num_5ghz_reg_rules, -++ ext_wmi_reg_rule); -++ -++ if (!reg_info->reg_rules_5ghz_ptr) { -++ kfree(tb); -++ ath11k_warn(ab, "Unable to Allocate memory for 5 GHz rules\n"); -++ return -ENOMEM; -++ } -++ } -++ -++ /* We have adjusted the number of 5 GHz reg rules above. But still those -++ * many rules needs to be adjusted in ext_wmi_reg_rule. -++ * -++ * NOTE: num_invalid_5ghz_ext_rules will be 0 for rest other cases. -++ */ -++ ext_wmi_reg_rule += (num_5ghz_reg_rules + num_invalid_5ghz_ext_rules); -++ -++ for (i = 0; i < WMI_REG_CURRENT_MAX_AP_TYPE; i++) { -++ reg_info->reg_rules_6ghz_ap_ptr[i] = -++ create_ext_reg_rules_from_wmi(num_6ghz_reg_rules_ap[i], -++ ext_wmi_reg_rule); -++ -++ if (!reg_info->reg_rules_6ghz_ap_ptr[i]) { -++ kfree(tb); -++ ath11k_warn(ab, "Unable to Allocate memory for 6 GHz AP rules\n"); -++ return -ENOMEM; -++ } -++ -++ ext_wmi_reg_rule += num_6ghz_reg_rules_ap[i]; -++ } -++ -++ for (j = 0; j < WMI_REG_CURRENT_MAX_AP_TYPE; j++) { -++ for (i = 0; i < WMI_REG_MAX_CLIENT_TYPE; i++) { -++ reg_info->reg_rules_6ghz_client_ptr[j][i] = -++ create_ext_reg_rules_from_wmi(num_6ghz_client[j][i], -++ ext_wmi_reg_rule); -++ -++ if (!reg_info->reg_rules_6ghz_client_ptr[j][i]) { -++ kfree(tb); -++ ath11k_warn(ab, "Unable to Allocate memory for 6 GHz client rules\n"); -++ return -ENOMEM; -++ } -++ -++ ext_wmi_reg_rule += num_6ghz_client[j][i]; -++ } -++ } -++ -++ reg_info->client_type = ext_chan_list_event_hdr->client_type; -++ reg_info->rnr_tpe_usable = ext_chan_list_event_hdr->rnr_tpe_usable; -++ reg_info->unspecified_ap_usable = -++ ext_chan_list_event_hdr->unspecified_ap_usable; -++ reg_info->domain_code_6ghz_ap[WMI_REG_INDOOR_AP] = -++ ext_chan_list_event_hdr->domain_code_6ghz_ap_lpi; -++ reg_info->domain_code_6ghz_ap[WMI_REG_STANDARD_POWER_AP] = -++ ext_chan_list_event_hdr->domain_code_6ghz_ap_sp; -++ reg_info->domain_code_6ghz_ap[WMI_REG_VERY_LOW_POWER_AP] = -++ ext_chan_list_event_hdr->domain_code_6ghz_ap_vlp; -++ -++ for (i = 0; i < WMI_REG_MAX_CLIENT_TYPE; i++) { -++ reg_info->domain_code_6ghz_client[WMI_REG_INDOOR_AP][i] = -++ ext_chan_list_event_hdr->domain_code_6ghz_client_lpi[i]; -++ reg_info->domain_code_6ghz_client[WMI_REG_STANDARD_POWER_AP][i] = -++ ext_chan_list_event_hdr->domain_code_6ghz_client_sp[i]; -++ reg_info->domain_code_6ghz_client[WMI_REG_VERY_LOW_POWER_AP][i] = -++ ext_chan_list_event_hdr->domain_code_6ghz_client_vlp[i]; -++ } -++ -++ reg_info->domain_code_6ghz_super_id = -++ ext_chan_list_event_hdr->domain_code_6ghz_super_id; -++ -++ ath11k_dbg(ab, ATH11K_DBG_WMI, "6 GHz client_type: %d domain_code_6ghz_super_id: %d", -++ reg_info->client_type, reg_info->domain_code_6ghz_super_id); -++ -++ ath11k_dbg(ab, ATH11K_DBG_WMI, "processed regulatory ext channel list\n"); -++ -++ kfree(tb); -++ return 0; -++} -++ -+ static int ath11k_pull_peer_del_resp_ev(struct ath11k_base *ab, struct sk_buff *skb, -+ struct wmi_peer_delete_resp_event *peer_del_resp) -+ { -+@@ -6507,12 +6876,14 @@ static bool ath11k_reg_is_world_alpha(ch -+ return false; -+ } -+ -+-static int ath11k_reg_chan_list_event(struct ath11k_base *ab, struct sk_buff *skb) -++static int ath11k_reg_chan_list_event(struct ath11k_base *ab, -++ struct sk_buff *skb, -++ enum wmi_reg_chan_list_cmd_type id) -+ { -+ struct cur_regulatory_info *reg_info = NULL; -+ struct ieee80211_regdomain *regd = NULL; -+ bool intersect = false; -+- int ret = 0, pdev_idx; -++ int ret = 0, pdev_idx, i, j; -+ struct ath11k *ar; -+ -+ reg_info = kzalloc(sizeof(*reg_info), GFP_ATOMIC); -+@@ -6521,7 +6892,11 @@ static int ath11k_reg_chan_list_event(st -+ goto fallback; -+ } -+ -+- ret = ath11k_pull_reg_chan_list_update_ev(ab, skb, reg_info); -++ if (id == WMI_REG_CHAN_LIST_CC_ID) -++ ret = ath11k_pull_reg_chan_list_update_ev(ab, skb, reg_info); -++ else -++ ret = ath11k_pull_reg_chan_list_ext_update_ev(ab, skb, reg_info); -++ -+ if (ret) { -+ ath11k_warn(ab, "failed to extract regulatory info from received event\n"); -+ goto fallback; -+@@ -6623,6 +6998,14 @@ mem_free: -+ if (reg_info) { -+ kfree(reg_info->reg_rules_2ghz_ptr); -+ kfree(reg_info->reg_rules_5ghz_ptr); -++ if (reg_info->is_ext_reg_event) { -++ for (i = 0; i < WMI_REG_CURRENT_MAX_AP_TYPE; i++) -++ kfree(reg_info->reg_rules_6ghz_ap_ptr[i]); -++ -++ for (j = 0; j < WMI_REG_CURRENT_MAX_AP_TYPE; j++) -++ for (i = 0; i < WMI_REG_MAX_CLIENT_TYPE; i++) -++ kfree(reg_info->reg_rules_6ghz_client_ptr[j][i]); -++ } -+ kfree(reg_info); -+ } -+ return ret; -+@@ -8054,7 +8437,10 @@ static void ath11k_wmi_tlv_op_rx(struct -+ ath11k_service_ready_ext2_event(ab, skb); -+ break; -+ case WMI_REG_CHAN_LIST_CC_EVENTID: -+- ath11k_reg_chan_list_event(ab, skb); -++ ath11k_reg_chan_list_event(ab, skb, WMI_REG_CHAN_LIST_CC_ID); -++ break; -++ case WMI_REG_CHAN_LIST_CC_EXT_EVENTID: -++ ath11k_reg_chan_list_event(ab, skb, WMI_REG_CHAN_LIST_CC_EXT_ID); -+ break; -+ case WMI_READY_EVENTID: -+ ath11k_ready_event(ab, skb); -+--- a/drivers/net/wireless/ath/ath11k/wmi.h -++++ b/drivers/net/wireless/ath/ath11k/wmi.h -+@@ -797,6 +797,7 @@ enum wmi_tlv_event_id { -+ WMI_RMC_NEW_LEADER_EVENTID = WMI_TLV_CMD(WMI_GRP_RMC), -+ WMI_REG_CHAN_LIST_CC_EVENTID = WMI_TLV_CMD(WMI_GRP_REGULATORY), -+ WMI_11D_NEW_COUNTRY_EVENTID, -++ WMI_REG_CHAN_LIST_CC_EXT_EVENTID, -+ WMI_NDI_CAP_RSP_EVENTID = WMI_TLV_CMD(WMI_GRP_PROTOTYPE), -+ WMI_NDP_INITIATOR_RSP_EVENTID, -+ WMI_NDP_RESPONDER_RSP_EVENTID, -+@@ -1865,6 +1866,8 @@ enum wmi_tlv_tag { -+ WMI_TAG_PDEV_SRG_OBSS_BSSID_ENABLE_BITMAP_CMD, -+ WMI_TAG_PDEV_NON_SRG_OBSS_COLOR_ENABLE_BITMAP_CMD, -+ 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, -+ WMI_TAG_MAX -+@@ -2097,6 +2100,7 @@ enum wmi_tlv_service { -+ -+ /* The second 128 bits */ -+ WMI_MAX_EXT_SERVICE = 256, -++ WMI_TLV_SERVICE_REG_CC_EXT_EVENT_SUPPORT = 281, -+ WMI_TLV_SERVICE_BIOS_SAR_SUPPORT = 326, -+ -+ /* The third 128 bits */ -+@@ -2313,6 +2317,8 @@ struct wmi_init_cmd { -+ #define WMI_RSRC_CFG_FLAG1_BSS_CHANNEL_INFO_64 BIT(5) -+ #define WMI_RSRC_CFG_FLAG1_ACK_RSSI BIT(18) -+ -++#define WMI_CFG_HOST_SERVICE_FLAG_REG_CC_EXT 4 -++ -+ struct wmi_resource_config { -+ u32 tlv_header; -+ u32 num_vdevs; -+@@ -2372,6 +2378,15 @@ struct wmi_resource_config { -+ u32 sched_params; -+ u32 twt_ap_pdev_count; -+ u32 twt_ap_sta_count; -++ u32 max_nlo_ssids; -++ u32 num_pkt_filters; -++ u32 num_max_sta_vdevs; -++ u32 max_bssid_indicator; -++ u32 ul_resp_config; -++ u32 msdu_flow_override_config0; -++ u32 msdu_flow_override_config1; -++ u32 flags2; -++ u32 host_service_flags; -+ } __packed; -+ -+ struct wmi_service_ready_event { -+@@ -2854,6 +2869,8 @@ struct rx_reorder_queue_remove_params { -+ #define REG_RULE_MAX_BW 0x0000ffff -+ #define REG_RULE_REG_PWR 0x00ff0000 -+ #define REG_RULE_ANT_GAIN 0xff000000 -++#define REG_RULE_PSD_INFO BIT(0) -++#define REG_RULE_PSD_EIRP 0xff0000 -+ -+ #define WMI_VDEV_PARAM_TXBF_SU_TX_BFEE BIT(0) -+ #define WMI_VDEV_PARAM_TXBF_MU_TX_BFEE BIT(1) -+@@ -4049,6 +4066,7 @@ struct wmi_he_rate_set { -+ -+ #define MAX_REG_RULES 10 -+ #define REG_ALPHA2_LEN 2 -++#define MAX_6GHZ_REG_RULES 5 -+ -+ enum wmi_start_event_param { -+ WMI_VDEV_START_RESP_EVENT = 0, -+@@ -4079,16 +4097,6 @@ enum wmi_vdev_start_resp_status_code { -+ WMI_VDEV_START_RESPONSE_INVALID_REGDOMAIN = 4, -+ }; -+ -+-; -+-enum cc_setting_code { -+- REG_SET_CC_STATUS_PASS = 0, -+- REG_CURRENT_ALPHA2_NOT_FOUND = 1, -+- REG_INIT_ALPHA2_NOT_FOUND = 2, -+- REG_SET_CC_CHANGE_NOT_ALLOWED = 3, -+- REG_SET_CC_STATUS_NO_MEMORY = 4, -+- REG_SET_CC_STATUS_FAIL = 5, -+-}; -+- -+ /* Regaulatory Rule Flags Passed by FW */ -+ #define REGULATORY_CHAN_DISABLED BIT(0) -+ #define REGULATORY_CHAN_NO_IR BIT(1) -+@@ -4102,13 +4110,72 @@ enum cc_setting_code { -+ #define REGULATORY_CHAN_NO_20MHZ BIT(11) -+ #define REGULATORY_CHAN_NO_10MHZ BIT(12) -+ -+-enum { -++enum wmi_reg_chan_list_cmd_type { -++ WMI_REG_CHAN_LIST_CC_ID = 0, -++ WMI_REG_CHAN_LIST_CC_EXT_ID = 1, -++}; -++ -++enum wmi_reg_cc_setting_code { -+ WMI_REG_SET_CC_STATUS_PASS = 0, -+ WMI_REG_CURRENT_ALPHA2_NOT_FOUND = 1, -+ WMI_REG_INIT_ALPHA2_NOT_FOUND = 2, -+ WMI_REG_SET_CC_CHANGE_NOT_ALLOWED = 3, -+ WMI_REG_SET_CC_STATUS_NO_MEMORY = 4, -+ WMI_REG_SET_CC_STATUS_FAIL = 5, -++ -++ /* add new setting code above, update in -++ * @enum cc_setting_code as well. -++ * Also handle it in ath11k_wmi_cc_setting_code_to_reg() -++ */ -++}; -++ -++enum cc_setting_code { -++ REG_SET_CC_STATUS_PASS = 0, -++ REG_CURRENT_ALPHA2_NOT_FOUND = 1, -++ REG_INIT_ALPHA2_NOT_FOUND = 2, -++ REG_SET_CC_CHANGE_NOT_ALLOWED = 3, -++ REG_SET_CC_STATUS_NO_MEMORY = 4, -++ REG_SET_CC_STATUS_FAIL = 5, -++ -++ /* add new setting code above, update in -++ * @enum wmi_reg_cc_setting_code as well. -++ */ -++}; -++ -++static inline enum cc_setting_code -++ath11k_wmi_cc_setting_code_to_reg(enum wmi_reg_cc_setting_code status_code) -++{ -++ switch (status_code) { -++ case WMI_REG_SET_CC_STATUS_PASS: -++ return REG_SET_CC_STATUS_PASS; -++ case WMI_REG_CURRENT_ALPHA2_NOT_FOUND: -++ return REG_CURRENT_ALPHA2_NOT_FOUND; -++ case WMI_REG_INIT_ALPHA2_NOT_FOUND: -++ return REG_INIT_ALPHA2_NOT_FOUND; -++ case WMI_REG_SET_CC_CHANGE_NOT_ALLOWED: -++ return REG_SET_CC_CHANGE_NOT_ALLOWED; -++ case WMI_REG_SET_CC_STATUS_NO_MEMORY: -++ return REG_SET_CC_STATUS_NO_MEMORY; -++ case WMI_REG_SET_CC_STATUS_FAIL: -++ return REG_SET_CC_STATUS_FAIL; -++ } -++ -++ return REG_SET_CC_STATUS_FAIL; -++} -++ -++enum wmi_reg_6ghz_ap_type { -++ WMI_REG_INDOOR_AP = 0, -++ WMI_REG_STANDARD_POWER_AP = 1, -++ WMI_REG_VERY_LOW_POWER_AP = 2, -++ -++ WMI_REG_CURRENT_MAX_AP_TYPE, -++ WMI_REG_MAX_AP_TYPE = 7, -++}; -++ -++enum wmi_reg_6ghz_client_type { -++ WMI_REG_DEFAULT_CLIENT = 0, -++ WMI_REG_SUBORDINATE_CLIENT = 1, -++ WMI_REG_MAX_CLIENT_TYPE = 2, -+ }; -+ -+ struct cur_reg_rule { -+@@ -4118,6 +4185,8 @@ struct cur_reg_rule { -+ u8 reg_power; -+ u8 ant_gain; -+ u16 flags; -++ bool psd_flag; -++ s8 psd_eirp; -+ }; -+ -+ struct cur_regulatory_info { -+@@ -4137,6 +4206,22 @@ struct cur_regulatory_info { -+ u32 num_5ghz_reg_rules; -+ struct cur_reg_rule *reg_rules_2ghz_ptr; -+ struct cur_reg_rule *reg_rules_5ghz_ptr; -++ bool is_ext_reg_event; -++ enum wmi_reg_6ghz_client_type client_type; -++ bool rnr_tpe_usable; -++ bool unspecified_ap_usable; -++ u8 domain_code_6ghz_ap[WMI_REG_CURRENT_MAX_AP_TYPE]; -++ u8 domain_code_6ghz_client[WMI_REG_CURRENT_MAX_AP_TYPE][WMI_REG_MAX_CLIENT_TYPE]; -++ u32 domain_code_6ghz_super_id; -++ u32 min_bw_6ghz_ap[WMI_REG_CURRENT_MAX_AP_TYPE]; -++ u32 max_bw_6ghz_ap[WMI_REG_CURRENT_MAX_AP_TYPE]; -++ u32 min_bw_6ghz_client[WMI_REG_CURRENT_MAX_AP_TYPE][WMI_REG_MAX_CLIENT_TYPE]; -++ u32 max_bw_6ghz_client[WMI_REG_CURRENT_MAX_AP_TYPE][WMI_REG_MAX_CLIENT_TYPE]; -++ u32 num_6ghz_rules_ap[WMI_REG_CURRENT_MAX_AP_TYPE]; -++ u32 num_6ghz_rules_client[WMI_REG_CURRENT_MAX_AP_TYPE][WMI_REG_MAX_CLIENT_TYPE]; -++ struct cur_reg_rule *reg_rules_6ghz_ap_ptr[WMI_REG_CURRENT_MAX_AP_TYPE]; -++ struct cur_reg_rule *reg_rules_6ghz_client_ptr -++ [WMI_REG_CURRENT_MAX_AP_TYPE][WMI_REG_MAX_CLIENT_TYPE]; -+ }; -+ -+ struct wmi_reg_chan_list_cc_event { -+@@ -4163,6 +4248,61 @@ struct wmi_regulatory_rule_struct { -+ u32 flag_info; -+ }; -+ -++#define WMI_REG_CLIENT_MAX 4 -++ -++struct wmi_reg_chan_list_cc_ext_event { -++ u32 status_code; -++ u32 phy_id; -++ u32 alpha2; -++ u32 num_phy; -++ u32 country_id; -++ u32 domain_code; -++ u32 dfs_region; -++ u32 phybitmap; -++ u32 min_bw_2ghz; -++ u32 max_bw_2ghz; -++ u32 min_bw_5ghz; -++ u32 max_bw_5ghz; -++ u32 num_2ghz_reg_rules; -++ u32 num_5ghz_reg_rules; -++ u32 client_type; -++ u32 rnr_tpe_usable; -++ u32 unspecified_ap_usable; -++ u32 domain_code_6ghz_ap_lpi; -++ u32 domain_code_6ghz_ap_sp; -++ u32 domain_code_6ghz_ap_vlp; -++ u32 domain_code_6ghz_client_lpi[WMI_REG_CLIENT_MAX]; -++ u32 domain_code_6ghz_client_sp[WMI_REG_CLIENT_MAX]; -++ u32 domain_code_6ghz_client_vlp[WMI_REG_CLIENT_MAX]; -++ u32 domain_code_6ghz_super_id; -++ u32 min_bw_6ghz_ap_sp; -++ u32 max_bw_6ghz_ap_sp; -++ u32 min_bw_6ghz_ap_lpi; -++ u32 max_bw_6ghz_ap_lpi; -++ u32 min_bw_6ghz_ap_vlp; -++ u32 max_bw_6ghz_ap_vlp; -++ u32 min_bw_6ghz_client_sp[WMI_REG_CLIENT_MAX]; -++ u32 max_bw_6ghz_client_sp[WMI_REG_CLIENT_MAX]; -++ u32 min_bw_6ghz_client_lpi[WMI_REG_CLIENT_MAX]; -++ u32 max_bw_6ghz_client_lpi[WMI_REG_CLIENT_MAX]; -++ u32 min_bw_6ghz_client_vlp[WMI_REG_CLIENT_MAX]; -++ u32 max_bw_6ghz_client_vlp[WMI_REG_CLIENT_MAX]; -++ u32 num_6ghz_reg_rules_ap_sp; -++ u32 num_6ghz_reg_rules_ap_lpi; -++ u32 num_6ghz_reg_rules_ap_vlp; -++ u32 num_6ghz_reg_rules_client_sp[WMI_REG_CLIENT_MAX]; -++ u32 num_6ghz_reg_rules_client_lpi[WMI_REG_CLIENT_MAX]; -++ u32 num_6ghz_reg_rules_client_vlp[WMI_REG_CLIENT_MAX]; -++} __packed; -++ -++struct wmi_regulatory_ext_rule { -++ u32 tlv_header; -++ u32 freq_info; -++ u32 bw_pwr_info; -++ u32 flag_info; -++ u32 psd_power_info; -++} __packed; -++ -+ struct wmi_vdev_delete_resp_event { -+ u32 vdev_id; -+ } __packed; -+@@ -5358,6 +5498,7 @@ struct target_resource_config { -+ u32 sched_params; -+ u32 twt_ap_pdev_count; -+ u32 twt_ap_sta_count; -++ u8 is_reg_cc_ext_event_supported; -+ }; -+ -+ enum wmi_debug_log_param { -diff --git a/package/kernel/mac80211/patches/ath11k/0045-wifi-ath11k-add-debug-prints-in-regulatory-WMI-event.patch b/package/kernel/mac80211/patches/ath11k/0045-wifi-ath11k-add-debug-prints-in-regulatory-WMI-event.patch -new file mode 100644 -index 0000000000..b88e51928f ---- /dev/null -+++ b/package/kernel/mac80211/patches/ath11k/0045-wifi-ath11k-add-debug-prints-in-regulatory-WMI-event.patch -@@ -0,0 +1,567 @@ -+From e238e62ba8868a784e485eb94451c87cd1b85cee Mon Sep 17 00:00:00 2001 -+From: Aditya Kumar Singh -+Date: Wed, 1 Mar 2023 16:20:59 +0200 -+Subject: [PATCH] wifi: ath11k: add debug prints in regulatory WMI event -+ processing -+ -+Add some more debug prints in processing regulatory WMI event in order to -+increase more debuggability. -+ -+Tested-on: IPQ8074 hw2.0 AHB WLAN.HK.2.7.0.1-01744-QCAHKSWPL_SILICONZ-1 -+Tested-on: QCN9074 hw1.0 PCI WLAN.HK.2.7.0.1-01744-QCAHKSWPL_SILICONZ-1 -+Tested-on: QCN9074 hw1.0 PCI WLAN.HK.2.5.0.1-01100-QCAHKSWPL_SILICONZ-1 -+ -+Signed-off-by: Aditya Kumar Singh -+Signed-off-by: Kalle Valo -+Link: https://lore.kernel.org/r/20230110121024.14051-4-quic_adisi@quicinc.com -+--- -+ drivers/net/wireless/ath/ath11k/reg.c | 2 +- -+ drivers/net/wireless/ath/ath11k/wmi.c | 207 ++++++++++++++++++-------- -+ drivers/net/wireless/ath/ath11k/wmi.h | 142 ++++++++++++++++++ -+ 3 files changed, 291 insertions(+), 60 deletions(-) -+ -+--- a/drivers/net/wireless/ath/ath11k/reg.c -++++ b/drivers/net/wireless/ath/ath11k/reg.c -+@@ -646,7 +646,7 @@ ath11k_reg_build_regd(struct ath11k_base -+ tmp_regd->dfs_region = ath11k_map_fw_dfs_region(reg_info->dfs_region); -+ -+ ath11k_dbg(ab, ATH11K_DBG_REG, -+- "\r\nCountry %s, CFG Regdomain %s FW Regdomain %d, num_reg_rules %d\n", -++ "Country %s, CFG Regdomain %s FW Regdomain %d, num_reg_rules %d\n", -+ alpha2, ath11k_reg_get_regdom_str(tmp_regd->dfs_region), -+ reg_info->dfs_region, num_rules); -+ /* Update reg_rules[] below. Firmware is expected to -+--- a/drivers/net/wireless/ath/ath11k/wmi.c -++++ b/drivers/net/wireless/ath/ath11k/wmi.c -+@@ -4925,6 +4925,26 @@ static int ath11k_pull_vdev_start_resp_t -+ return 0; -+ } -+ -++static void ath11k_print_reg_rule(struct ath11k_base *ab, const char *band, -++ u32 num_reg_rules, -++ struct cur_reg_rule *reg_rule_ptr) -++{ -++ struct cur_reg_rule *reg_rule = reg_rule_ptr; -++ u32 count; -++ -++ ath11k_dbg(ab, ATH11K_DBG_WMI, "number of reg rules in %s band: %d\n", -++ band, num_reg_rules); -++ -++ for (count = 0; count < num_reg_rules; count++) { -++ ath11k_dbg(ab, ATH11K_DBG_WMI, -++ "reg rule %d: (%d - %d @ %d) (%d, %d) (FLAGS %d)\n", -++ count + 1, reg_rule->start_freq, reg_rule->end_freq, -++ reg_rule->max_bw, reg_rule->ant_gain, -++ reg_rule->reg_power, reg_rule->flags); -++ reg_rule++; -++ } -++} -++ -+ static struct cur_reg_rule -+ *create_reg_rules_from_wmi(u32 num_reg_rules, -+ struct wmi_regulatory_rule_struct *wmi_reg_rule) -+@@ -5006,6 +5026,10 @@ static int ath11k_pull_reg_chan_list_upd -+ reg_info->ctry_code = chan_list_event_hdr->country_id; -+ reg_info->reg_dmn_pair = chan_list_event_hdr->domain_code; -+ -++ ath11k_dbg(ab, ATH11K_DBG_WMI, -++ "status_code %s", -++ ath11k_cc_status_to_str(reg_info->status_code)); -++ -+ reg_info->status_code = -+ ath11k_wmi_cc_setting_code_to_reg(chan_list_event_hdr->status_code); -+ -+@@ -5020,13 +5044,13 @@ static int ath11k_pull_reg_chan_list_upd -+ num_5ghz_reg_rules = reg_info->num_5ghz_reg_rules; -+ -+ ath11k_dbg(ab, ATH11K_DBG_WMI, -+- "%s:cc %s dsf %d BW: min_2ghz %d max_2ghz %d min_5ghz %d max_5ghz %d", -+- __func__, reg_info->alpha2, reg_info->dfs_region, -++ "cc %s dsf %d BW: min_2ghz %d max_2ghz %d min_5ghz %d max_5ghz %d", -++ reg_info->alpha2, reg_info->dfs_region, -+ reg_info->min_bw_2ghz, reg_info->max_bw_2ghz, -+ reg_info->min_bw_5ghz, reg_info->max_bw_5ghz); -+ -+ ath11k_dbg(ab, ATH11K_DBG_WMI, -+- "%s: num_2ghz_reg_rules %d num_5ghz_reg_rules %d", __func__, -++ "num_2ghz_reg_rules %d num_5ghz_reg_rules %d", -+ num_2ghz_reg_rules, num_5ghz_reg_rules); -+ -+ wmi_reg_rule = -+@@ -5043,6 +5067,10 @@ static int ath11k_pull_reg_chan_list_upd -+ ath11k_warn(ab, "Unable to Allocate memory for 2 GHz rules\n"); -+ return -ENOMEM; -+ } -++ -++ ath11k_print_reg_rule(ab, "2 GHz", -++ num_2ghz_reg_rules, -++ reg_info->reg_rules_2ghz_ptr); -+ } -+ -+ if (num_5ghz_reg_rules) { -+@@ -5055,6 +5083,10 @@ static int ath11k_pull_reg_chan_list_upd -+ ath11k_warn(ab, "Unable to Allocate memory for 5 GHz rules\n"); -+ return -ENOMEM; -+ } -++ -++ ath11k_print_reg_rule(ab, "5 GHz", -++ num_5ghz_reg_rules, -++ reg_info->reg_rules_5ghz_ptr); -+ } -+ -+ ath11k_dbg(ab, ATH11K_DBG_WMI, "processed regulatory channel list\n"); -+@@ -5128,7 +5160,7 @@ static int ath11k_pull_reg_chan_list_ext -+ struct cur_regulatory_info *reg_info) -+ { -+ const void **tb; -+- const struct wmi_reg_chan_list_cc_ext_event *ext_chan_list_event_hdr; -++ const struct wmi_reg_chan_list_cc_ext_event *ev; -+ struct wmi_regulatory_ext_rule *ext_wmi_reg_rule; -+ u32 num_2ghz_reg_rules, num_5ghz_reg_rules; -+ u32 num_6ghz_reg_rules_ap[WMI_REG_CURRENT_MAX_AP_TYPE]; -+@@ -5145,31 +5177,29 @@ static int ath11k_pull_reg_chan_list_ext -+ return ret; -+ } -+ -+- ext_chan_list_event_hdr = tb[WMI_TAG_REG_CHAN_LIST_CC_EXT_EVENT]; -+- if (!ext_chan_list_event_hdr) { -++ ev = tb[WMI_TAG_REG_CHAN_LIST_CC_EXT_EVENT]; -++ if (!ev) { -+ ath11k_warn(ab, "failed to fetch reg chan list ext update ev\n"); -+ kfree(tb); -+ return -EPROTO; -+ } -+ -+- reg_info->num_2ghz_reg_rules = -+- ext_chan_list_event_hdr->num_2ghz_reg_rules; -+- reg_info->num_5ghz_reg_rules = -+- ext_chan_list_event_hdr->num_5ghz_reg_rules; -++ reg_info->num_2ghz_reg_rules = ev->num_2ghz_reg_rules; -++ reg_info->num_5ghz_reg_rules = ev->num_5ghz_reg_rules; -+ reg_info->num_6ghz_rules_ap[WMI_REG_INDOOR_AP] = -+- ext_chan_list_event_hdr->num_6ghz_reg_rules_ap_lpi; -++ ev->num_6ghz_reg_rules_ap_lpi; -+ reg_info->num_6ghz_rules_ap[WMI_REG_STANDARD_POWER_AP] = -+- ext_chan_list_event_hdr->num_6ghz_reg_rules_ap_sp; -++ ev->num_6ghz_reg_rules_ap_sp; -+ reg_info->num_6ghz_rules_ap[WMI_REG_VERY_LOW_POWER_AP] = -+- ext_chan_list_event_hdr->num_6ghz_reg_rules_ap_vlp; -++ ev->num_6ghz_reg_rules_ap_vlp; -+ -+ for (i = 0; i < WMI_REG_MAX_CLIENT_TYPE; i++) { -+ reg_info->num_6ghz_rules_client[WMI_REG_INDOOR_AP][i] = -+- ext_chan_list_event_hdr->num_6ghz_reg_rules_client_lpi[i]; -++ ev->num_6ghz_reg_rules_client_lpi[i]; -+ reg_info->num_6ghz_rules_client[WMI_REG_STANDARD_POWER_AP][i] = -+- ext_chan_list_event_hdr->num_6ghz_reg_rules_client_sp[i]; -++ ev->num_6ghz_reg_rules_client_sp[i]; -+ reg_info->num_6ghz_rules_client[WMI_REG_VERY_LOW_POWER_AP][i] = -+- ext_chan_list_event_hdr->num_6ghz_reg_rules_client_vlp[i]; -++ ev->num_6ghz_reg_rules_client_vlp[i]; -+ } -+ -+ num_2ghz_reg_rules = reg_info->num_2ghz_reg_rules; -+@@ -5231,57 +5261,79 @@ static int ath11k_pull_reg_chan_list_ext -+ return -EINVAL; -+ } -+ -+- memcpy(reg_info->alpha2, &ext_chan_list_event_hdr->alpha2, -+- REG_ALPHA2_LEN); -++ memcpy(reg_info->alpha2, &ev->alpha2, REG_ALPHA2_LEN); -++ -++ reg_info->dfs_region = ev->dfs_region; -++ reg_info->phybitmap = ev->phybitmap; -++ reg_info->num_phy = ev->num_phy; -++ reg_info->phy_id = ev->phy_id; -++ reg_info->ctry_code = ev->country_id; -++ reg_info->reg_dmn_pair = ev->domain_code; -+ -+- reg_info->dfs_region = ext_chan_list_event_hdr->dfs_region; -+- reg_info->phybitmap = ext_chan_list_event_hdr->phybitmap; -+- reg_info->num_phy = ext_chan_list_event_hdr->num_phy; -+- reg_info->phy_id = ext_chan_list_event_hdr->phy_id; -+- reg_info->ctry_code = ext_chan_list_event_hdr->country_id; -+- reg_info->reg_dmn_pair = ext_chan_list_event_hdr->domain_code; -++ ath11k_dbg(ab, ATH11K_DBG_WMI, -++ "status_code %s", -++ ath11k_cc_status_to_str(reg_info->status_code)); -+ -+ reg_info->status_code = -+- ath11k_wmi_cc_setting_code_to_reg(ext_chan_list_event_hdr->status_code); -++ ath11k_wmi_cc_setting_code_to_reg(ev->status_code); -+ -+ reg_info->is_ext_reg_event = true; -+ -+- reg_info->min_bw_2ghz = ext_chan_list_event_hdr->min_bw_2ghz; -+- reg_info->max_bw_2ghz = ext_chan_list_event_hdr->max_bw_2ghz; -+- reg_info->min_bw_5ghz = ext_chan_list_event_hdr->min_bw_5ghz; -+- reg_info->max_bw_5ghz = ext_chan_list_event_hdr->max_bw_5ghz; -++ reg_info->min_bw_2ghz = ev->min_bw_2ghz; -++ reg_info->max_bw_2ghz = ev->max_bw_2ghz; -++ reg_info->min_bw_5ghz = ev->min_bw_5ghz; -++ reg_info->max_bw_5ghz = ev->max_bw_5ghz; -+ -+ reg_info->min_bw_6ghz_ap[WMI_REG_INDOOR_AP] = -+- ext_chan_list_event_hdr->min_bw_6ghz_ap_lpi; -++ ev->min_bw_6ghz_ap_lpi; -+ reg_info->max_bw_6ghz_ap[WMI_REG_INDOOR_AP] = -+- ext_chan_list_event_hdr->max_bw_6ghz_ap_lpi; -++ ev->max_bw_6ghz_ap_lpi; -+ reg_info->min_bw_6ghz_ap[WMI_REG_STANDARD_POWER_AP] = -+- ext_chan_list_event_hdr->min_bw_6ghz_ap_sp; -++ ev->min_bw_6ghz_ap_sp; -+ reg_info->max_bw_6ghz_ap[WMI_REG_STANDARD_POWER_AP] = -+- ext_chan_list_event_hdr->max_bw_6ghz_ap_sp; -++ ev->max_bw_6ghz_ap_sp; -+ reg_info->min_bw_6ghz_ap[WMI_REG_VERY_LOW_POWER_AP] = -+- ext_chan_list_event_hdr->min_bw_6ghz_ap_vlp; -++ ev->min_bw_6ghz_ap_vlp; -+ reg_info->max_bw_6ghz_ap[WMI_REG_VERY_LOW_POWER_AP] = -+- ext_chan_list_event_hdr->max_bw_6ghz_ap_vlp; -++ ev->max_bw_6ghz_ap_vlp; -++ -++ ath11k_dbg(ab, ATH11K_DBG_WMI, -++ "6 GHz AP BW: LPI (%d - %d), SP (%d - %d), VLP (%d - %d)\n", -++ reg_info->min_bw_6ghz_ap[WMI_REG_INDOOR_AP], -++ reg_info->max_bw_6ghz_ap[WMI_REG_INDOOR_AP], -++ reg_info->min_bw_6ghz_ap[WMI_REG_STANDARD_POWER_AP], -++ reg_info->max_bw_6ghz_ap[WMI_REG_STANDARD_POWER_AP], -++ reg_info->min_bw_6ghz_ap[WMI_REG_VERY_LOW_POWER_AP], -++ reg_info->max_bw_6ghz_ap[WMI_REG_VERY_LOW_POWER_AP]); -+ -+ for (i = 0; i < WMI_REG_MAX_CLIENT_TYPE; i++) { -+ reg_info->min_bw_6ghz_client[WMI_REG_INDOOR_AP][i] = -+- ext_chan_list_event_hdr->min_bw_6ghz_client_lpi[i]; -++ ev->min_bw_6ghz_client_lpi[i]; -+ reg_info->max_bw_6ghz_client[WMI_REG_INDOOR_AP][i] = -+- ext_chan_list_event_hdr->max_bw_6ghz_client_lpi[i]; -++ ev->max_bw_6ghz_client_lpi[i]; -+ reg_info->min_bw_6ghz_client[WMI_REG_STANDARD_POWER_AP][i] = -+- ext_chan_list_event_hdr->min_bw_6ghz_client_sp[i]; -++ ev->min_bw_6ghz_client_sp[i]; -+ reg_info->max_bw_6ghz_client[WMI_REG_STANDARD_POWER_AP][i] = -+- ext_chan_list_event_hdr->max_bw_6ghz_client_sp[i]; -++ ev->max_bw_6ghz_client_sp[i]; -+ reg_info->min_bw_6ghz_client[WMI_REG_VERY_LOW_POWER_AP][i] = -+- ext_chan_list_event_hdr->min_bw_6ghz_client_vlp[i]; -++ ev->min_bw_6ghz_client_vlp[i]; -+ reg_info->max_bw_6ghz_client[WMI_REG_VERY_LOW_POWER_AP][i] = -+- ext_chan_list_event_hdr->max_bw_6ghz_client_vlp[i]; -++ ev->max_bw_6ghz_client_vlp[i]; -++ -++ ath11k_dbg(ab, ATH11K_DBG_WMI, -++ "6 GHz %s BW: LPI (%d - %d), SP (%d - %d), VLP (%d - %d)\n", -++ ath11k_6ghz_client_type_to_str(i), -++ reg_info->min_bw_6ghz_client[WMI_REG_INDOOR_AP][i], -++ reg_info->max_bw_6ghz_client[WMI_REG_INDOOR_AP][i], -++ reg_info->min_bw_6ghz_client[WMI_REG_STANDARD_POWER_AP][i], -++ reg_info->max_bw_6ghz_client[WMI_REG_STANDARD_POWER_AP][i], -++ reg_info->min_bw_6ghz_client[WMI_REG_VERY_LOW_POWER_AP][i], -++ reg_info->max_bw_6ghz_client[WMI_REG_VERY_LOW_POWER_AP][i]); -+ } -+ -+ ath11k_dbg(ab, ATH11K_DBG_WMI, -+- "%s:cc_ext %s dsf %d BW: min_2ghz %d max_2ghz %d min_5ghz %d max_5ghz %d", -+- __func__, reg_info->alpha2, reg_info->dfs_region, -++ "cc_ext %s dsf %d BW: min_2ghz %d max_2ghz %d min_5ghz %d max_5ghz %d", -++ reg_info->alpha2, reg_info->dfs_region, -+ reg_info->min_bw_2ghz, reg_info->max_bw_2ghz, -+ reg_info->min_bw_5ghz, reg_info->max_bw_5ghz); -+ -+@@ -5310,9 +5362,8 @@ static int ath11k_pull_reg_chan_list_ext -+ num_6ghz_client[WMI_REG_VERY_LOW_POWER_AP][j]); -+ -+ ext_wmi_reg_rule = -+- (struct wmi_regulatory_ext_rule *)((u8 *)ext_chan_list_event_hdr -+- + sizeof(*ext_chan_list_event_hdr) -+- + sizeof(struct wmi_tlv)); -++ (struct wmi_regulatory_ext_rule *)((u8 *)ev + sizeof(*ev) + -++ sizeof(struct wmi_tlv)); -+ if (num_2ghz_reg_rules) { -+ reg_info->reg_rules_2ghz_ptr = -+ create_ext_reg_rules_from_wmi(num_2ghz_reg_rules, -+@@ -5323,6 +5374,10 @@ static int ath11k_pull_reg_chan_list_ext -+ ath11k_warn(ab, "Unable to Allocate memory for 2 GHz rules\n"); -+ return -ENOMEM; -+ } -++ -++ ath11k_print_reg_rule(ab, "2 GHz", -++ num_2ghz_reg_rules, -++ reg_info->reg_rules_2ghz_ptr); -+ } -+ -+ ext_wmi_reg_rule += num_2ghz_reg_rules; -+@@ -5358,6 +5413,10 @@ static int ath11k_pull_reg_chan_list_ext -+ ath11k_warn(ab, "Unable to Allocate memory for 5 GHz rules\n"); -+ return -ENOMEM; -+ } -++ -++ ath11k_print_reg_rule(ab, "5 GHz", -++ num_5ghz_reg_rules, -++ reg_info->reg_rules_5ghz_ptr); -+ } -+ -+ /* We have adjusted the number of 5 GHz reg rules above. But still those -+@@ -5378,10 +5437,17 @@ static int ath11k_pull_reg_chan_list_ext -+ return -ENOMEM; -+ } -+ -++ ath11k_print_reg_rule(ab, ath11k_6ghz_ap_type_to_str(i), -++ num_6ghz_reg_rules_ap[i], -++ reg_info->reg_rules_6ghz_ap_ptr[i]); -++ -+ ext_wmi_reg_rule += num_6ghz_reg_rules_ap[i]; -+ } -+ -+ for (j = 0; j < WMI_REG_CURRENT_MAX_AP_TYPE; j++) { -++ ath11k_dbg(ab, ATH11K_DBG_WMI, -++ "6 GHz AP type %s", ath11k_6ghz_ap_type_to_str(j)); -++ -+ for (i = 0; i < WMI_REG_MAX_CLIENT_TYPE; i++) { -+ reg_info->reg_rules_6ghz_client_ptr[j][i] = -+ create_ext_reg_rules_from_wmi(num_6ghz_client[j][i], -+@@ -5393,35 +5459,58 @@ static int ath11k_pull_reg_chan_list_ext -+ return -ENOMEM; -+ } -+ -++ ath11k_print_reg_rule(ab, -++ ath11k_6ghz_client_type_to_str(i), -++ num_6ghz_client[j][i], -++ reg_info->reg_rules_6ghz_client_ptr[j][i]); -++ -+ ext_wmi_reg_rule += num_6ghz_client[j][i]; -+ } -+ } -+ -+- reg_info->client_type = ext_chan_list_event_hdr->client_type; -+- reg_info->rnr_tpe_usable = ext_chan_list_event_hdr->rnr_tpe_usable; -++ reg_info->client_type = ev->client_type; -++ reg_info->rnr_tpe_usable = ev->rnr_tpe_usable; -+ reg_info->unspecified_ap_usable = -+- ext_chan_list_event_hdr->unspecified_ap_usable; -++ ev->unspecified_ap_usable; -+ reg_info->domain_code_6ghz_ap[WMI_REG_INDOOR_AP] = -+- ext_chan_list_event_hdr->domain_code_6ghz_ap_lpi; -++ ev->domain_code_6ghz_ap_lpi; -+ reg_info->domain_code_6ghz_ap[WMI_REG_STANDARD_POWER_AP] = -+- ext_chan_list_event_hdr->domain_code_6ghz_ap_sp; -++ ev->domain_code_6ghz_ap_sp; -+ reg_info->domain_code_6ghz_ap[WMI_REG_VERY_LOW_POWER_AP] = -+- ext_chan_list_event_hdr->domain_code_6ghz_ap_vlp; -++ ev->domain_code_6ghz_ap_vlp; -++ -++ ath11k_dbg(ab, ATH11K_DBG_WMI, -++ "6 GHz reg info client type %s rnr_tpe_usable %d unspecified_ap_usable %d AP sub domain: lpi %s, sp %s, vlp %s\n", -++ ath11k_6ghz_client_type_to_str(reg_info->client_type), -++ reg_info->rnr_tpe_usable, -++ reg_info->unspecified_ap_usable, -++ ath11k_sub_reg_6ghz_to_str(ev->domain_code_6ghz_ap_lpi), -++ ath11k_sub_reg_6ghz_to_str(ev->domain_code_6ghz_ap_sp), -++ ath11k_sub_reg_6ghz_to_str(ev->domain_code_6ghz_ap_vlp)); -+ -+ for (i = 0; i < WMI_REG_MAX_CLIENT_TYPE; i++) { -+ reg_info->domain_code_6ghz_client[WMI_REG_INDOOR_AP][i] = -+- ext_chan_list_event_hdr->domain_code_6ghz_client_lpi[i]; -++ ev->domain_code_6ghz_client_lpi[i]; -+ reg_info->domain_code_6ghz_client[WMI_REG_STANDARD_POWER_AP][i] = -+- ext_chan_list_event_hdr->domain_code_6ghz_client_sp[i]; -++ ev->domain_code_6ghz_client_sp[i]; -+ reg_info->domain_code_6ghz_client[WMI_REG_VERY_LOW_POWER_AP][i] = -+- ext_chan_list_event_hdr->domain_code_6ghz_client_vlp[i]; -++ ev->domain_code_6ghz_client_vlp[i]; -++ -++ ath11k_dbg(ab, ATH11K_DBG_WMI, -++ "6 GHz client type %s client sub domain: lpi %s, sp %s, vlp %s\n", -++ ath11k_6ghz_client_type_to_str(i), -++ ath11k_sub_reg_6ghz_to_str(ev->domain_code_6ghz_client_lpi[i]), -++ ath11k_sub_reg_6ghz_to_str(ev->domain_code_6ghz_client_sp[i]), -++ ath11k_sub_reg_6ghz_to_str(ev->domain_code_6ghz_client_vlp[i]) -++ ); -+ } -+ -+- reg_info->domain_code_6ghz_super_id = -+- ext_chan_list_event_hdr->domain_code_6ghz_super_id; -++ reg_info->domain_code_6ghz_super_id = ev->domain_code_6ghz_super_id; -+ -+- ath11k_dbg(ab, ATH11K_DBG_WMI, "6 GHz client_type: %d domain_code_6ghz_super_id: %d", -+- reg_info->client_type, reg_info->domain_code_6ghz_super_id); -++ ath11k_dbg(ab, ATH11K_DBG_WMI, -++ "6 GHz client_type %s 6 GHz super domain %s", -++ ath11k_6ghz_client_type_to_str(reg_info->client_type), -++ ath11k_super_reg_6ghz_to_str(reg_info->domain_code_6ghz_super_id)); -+ -+ ath11k_dbg(ab, ATH11K_DBG_WMI, "processed regulatory ext channel list\n"); -+ -+--- a/drivers/net/wireless/ath/ath11k/wmi.h -++++ b/drivers/net/wireless/ath/ath11k/wmi.h -+@@ -4139,6 +4139,7 @@ enum cc_setting_code { -+ -+ /* add new setting code above, update in -+ * @enum wmi_reg_cc_setting_code as well. -++ * Also handle it in ath11k_cc_status_to_str() -+ */ -+ }; -+ -+@@ -4163,21 +4164,162 @@ ath11k_wmi_cc_setting_code_to_reg(enum w -+ return REG_SET_CC_STATUS_FAIL; -+ } -+ -++static inline const char *ath11k_cc_status_to_str(enum cc_setting_code code) -++{ -++ switch (code) { -++ case REG_SET_CC_STATUS_PASS: -++ return "REG_SET_CC_STATUS_PASS"; -++ case REG_CURRENT_ALPHA2_NOT_FOUND: -++ return "REG_CURRENT_ALPHA2_NOT_FOUND"; -++ case REG_INIT_ALPHA2_NOT_FOUND: -++ return "REG_INIT_ALPHA2_NOT_FOUND"; -++ case REG_SET_CC_CHANGE_NOT_ALLOWED: -++ return "REG_SET_CC_CHANGE_NOT_ALLOWED"; -++ case REG_SET_CC_STATUS_NO_MEMORY: -++ return "REG_SET_CC_STATUS_NO_MEMORY"; -++ case REG_SET_CC_STATUS_FAIL: -++ return "REG_SET_CC_STATUS_FAIL"; -++ } -++ -++ return "Unknown CC status"; -++} -++ -+ enum wmi_reg_6ghz_ap_type { -+ WMI_REG_INDOOR_AP = 0, -+ WMI_REG_STANDARD_POWER_AP = 1, -+ WMI_REG_VERY_LOW_POWER_AP = 2, -+ -++ /* add AP type above, handle in ath11k_6ghz_ap_type_to_str() -++ */ -+ WMI_REG_CURRENT_MAX_AP_TYPE, -+ WMI_REG_MAX_AP_TYPE = 7, -+ }; -+ -++static inline const char * -++ath11k_6ghz_ap_type_to_str(enum wmi_reg_6ghz_ap_type type) -++{ -++ switch (type) { -++ case WMI_REG_INDOOR_AP: -++ return "INDOOR AP"; -++ case WMI_REG_STANDARD_POWER_AP: -++ return "STANDARD POWER AP"; -++ case WMI_REG_VERY_LOW_POWER_AP: -++ return "VERY LOW POWER AP"; -++ case WMI_REG_CURRENT_MAX_AP_TYPE: -++ return "CURRENT_MAX_AP_TYPE"; -++ case WMI_REG_MAX_AP_TYPE: -++ return "MAX_AP_TYPE"; -++ } -++ -++ return "unknown 6 GHz AP type"; -++} -++ -+ enum wmi_reg_6ghz_client_type { -+ WMI_REG_DEFAULT_CLIENT = 0, -+ WMI_REG_SUBORDINATE_CLIENT = 1, -+ WMI_REG_MAX_CLIENT_TYPE = 2, -++ -++ /* add client type above, handle it in -++ * ath11k_6ghz_client_type_to_str() -++ */ -++}; -++ -++static inline const char * -++ath11k_6ghz_client_type_to_str(enum wmi_reg_6ghz_client_type type) -++{ -++ switch (type) { -++ case WMI_REG_DEFAULT_CLIENT: -++ return "DEFAULT CLIENT"; -++ case WMI_REG_SUBORDINATE_CLIENT: -++ return "SUBORDINATE CLIENT"; -++ case WMI_REG_MAX_CLIENT_TYPE: -++ return "MAX_CLIENT_TYPE"; -++ } -++ -++ return "unknown 6 GHz client type"; -++} -++ -++enum reg_subdomains_6ghz { -++ EMPTY_6GHZ = 0x0, -++ FCC1_CLIENT_LPI_REGULAR_6GHZ = 0x01, -++ FCC1_CLIENT_SP_6GHZ = 0x02, -++ FCC1_AP_LPI_6GHZ = 0x03, -++ FCC1_CLIENT_LPI_SUBORDINATE = FCC1_AP_LPI_6GHZ, -++ FCC1_AP_SP_6GHZ = 0x04, -++ ETSI1_LPI_6GHZ = 0x10, -++ ETSI1_VLP_6GHZ = 0x11, -++ ETSI2_LPI_6GHZ = 0x12, -++ ETSI2_VLP_6GHZ = 0x13, -++ APL1_LPI_6GHZ = 0x20, -++ APL1_VLP_6GHZ = 0x21, -++ -++ /* add sub-domain above, handle it in -++ * ath11k_sub_reg_6ghz_to_str() -++ */ -++}; -++ -++static inline const char * -++ath11k_sub_reg_6ghz_to_str(enum reg_subdomains_6ghz sub_id) -++{ -++ switch (sub_id) { -++ case EMPTY_6GHZ: -++ return "N/A"; -++ case FCC1_CLIENT_LPI_REGULAR_6GHZ: -++ return "FCC1_CLIENT_LPI_REGULAR_6GHZ"; -++ case FCC1_CLIENT_SP_6GHZ: -++ return "FCC1_CLIENT_SP_6GHZ"; -++ case FCC1_AP_LPI_6GHZ: -++ return "FCC1_AP_LPI_6GHZ/FCC1_CLIENT_LPI_SUBORDINATE"; -++ case FCC1_AP_SP_6GHZ: -++ return "FCC1_AP_SP_6GHZ"; -++ case ETSI1_LPI_6GHZ: -++ return "ETSI1_LPI_6GHZ"; -++ case ETSI1_VLP_6GHZ: -++ return "ETSI1_VLP_6GHZ"; -++ case ETSI2_LPI_6GHZ: -++ return "ETSI2_LPI_6GHZ"; -++ case ETSI2_VLP_6GHZ: -++ return "ETSI2_VLP_6GHZ"; -++ case APL1_LPI_6GHZ: -++ return "APL1_LPI_6GHZ"; -++ case APL1_VLP_6GHZ: -++ return "APL1_VLP_6GHZ"; -++ } -++ -++ return "unknown sub reg id"; -++} -++ -++enum reg_super_domain_6ghz { -++ FCC1_6GHZ = 0x01, -++ ETSI1_6GHZ = 0x02, -++ ETSI2_6GHZ = 0x03, -++ APL1_6GHZ = 0x04, -++ FCC1_6GHZ_CL = 0x05, -++ -++ /* add super domain above, handle it in -++ * ath11k_super_reg_6ghz_to_str() -++ */ -+ }; -+ -++static inline const char * -++ath11k_super_reg_6ghz_to_str(enum reg_super_domain_6ghz domain_id) -++{ -++ switch (domain_id) { -++ case FCC1_6GHZ: -++ return "FCC1_6GHZ"; -++ case ETSI1_6GHZ: -++ return "ETSI1_6GHZ"; -++ case ETSI2_6GHZ: -++ return "ETSI2_6GHZ"; -++ case APL1_6GHZ: -++ return "APL1_6GHZ"; -++ case FCC1_6GHZ_CL: -++ return "FCC1_6GHZ_CL"; -++ } -++ -++ return "unknown domain id"; -++} -++ -+ struct cur_reg_rule { -+ u16 start_freq; -+ u16 end_freq; -diff --git a/package/kernel/mac80211/patches/ath11k/0046-wifi-ath11k-Replace-fake-flex-array-with-flexible-ar.patch b/package/kernel/mac80211/patches/ath11k/0046-wifi-ath11k-Replace-fake-flex-array-with-flexible-ar.patch -new file mode 100644 -index 0000000000..bd16178564 ---- /dev/null -+++ b/package/kernel/mac80211/patches/ath11k/0046-wifi-ath11k-Replace-fake-flex-array-with-flexible-ar.patch -@@ -0,0 +1,246 @@ -+From 3b1088a09ec9438523c251d8435e78988824bc0d Mon Sep 17 00:00:00 2001 -+From: "Gustavo A. R. Silva" -+Date: Tue, 7 Mar 2023 16:22:39 -0600 -+Subject: [PATCH] wifi: ath11k: Replace fake flex-array with flexible-array -+ member -+MIME-Version: 1.0 -+Content-Type: text/plain; charset=UTF-8 -+Content-Transfer-Encoding: 8bit -+ -+Zero-length arrays as fake flexible arrays are deprecated and we are -+moving towards adopting C99 flexible-array members instead. -+ -+Address 25 of the following warnings found with GCC-13 and -+-fstrict-flex-arrays=3 enabled: -+drivers/net/wireless/ath/ath11k/debugfs_htt_stats.c:30:51: warning: array subscript is outside array bounds of ‘const u32[0]’ {aka ‘const unsigned int[]’} [-Warray-bounds=] -+ -+This helps with the ongoing efforts to tighten the FORTIFY_SOURCE -+routines on memcpy() and help us make progress towards globally -+enabling -fstrict-flex-arrays=3 [1]. -+ -+Link: https://github.com/KSPP/linux/issues/21 -+Link: https://github.com/KSPP/linux/issues/266 -+Link: https://gcc.gnu.org/pipermail/gcc-patches/2022-October/602902.html [1] -+Signed-off-by: Gustavo A. R. Silva -+Reviewed-by: Simon Horman -+Signed-off-by: Kalle Valo -+Link: https://lore.kernel.org/r/ZAe5L5DtmsQxzqRH@work -+--- -+ .../wireless/ath/ath11k/debugfs_htt_stats.h | 73 +++++++++++-------- -+ 1 file changed, 43 insertions(+), 30 deletions(-) -+ -+--- a/drivers/net/wireless/ath/ath11k/debugfs_htt_stats.h -++++ b/drivers/net/wireless/ath/ath11k/debugfs_htt_stats.h -+@@ -143,7 +143,8 @@ enum htt_tx_pdev_underrun_enum { -+ /* Bytes stored in little endian order */ -+ /* Length should be multiple of DWORD */ -+ struct htt_stats_string_tlv { -+- u32 data[0]; /* Can be variable length */ -++ /* Can be variable length */ -++ DECLARE_FLEX_ARRAY(u32, data); -+ } __packed; -+ -+ #define HTT_STATS_MAC_ID GENMASK(7, 0) -+@@ -205,27 +206,32 @@ struct htt_tx_pdev_stats_cmn_tlv { -+ -+ /* NOTE: Variable length TLV, use length spec to infer array size */ -+ struct htt_tx_pdev_stats_urrn_tlv_v { -+- u32 urrn_stats[0]; /* HTT_TX_PDEV_MAX_URRN_STATS */ -++ /* HTT_TX_PDEV_MAX_URRN_STATS */ -++ DECLARE_FLEX_ARRAY(u32, urrn_stats); -+ }; -+ -+ /* NOTE: Variable length TLV, use length spec to infer array size */ -+ struct htt_tx_pdev_stats_flush_tlv_v { -+- u32 flush_errs[0]; /* HTT_TX_PDEV_MAX_FLUSH_REASON_STATS */ -++ /* HTT_TX_PDEV_MAX_FLUSH_REASON_STATS */ -++ DECLARE_FLEX_ARRAY(u32, flush_errs); -+ }; -+ -+ /* NOTE: Variable length TLV, use length spec to infer array size */ -+ struct htt_tx_pdev_stats_sifs_tlv_v { -+- u32 sifs_status[0]; /* HTT_TX_PDEV_MAX_SIFS_BURST_STATS */ -++ /* HTT_TX_PDEV_MAX_SIFS_BURST_STATS */ -++ DECLARE_FLEX_ARRAY(u32, sifs_status); -+ }; -+ -+ /* NOTE: Variable length TLV, use length spec to infer array size */ -+ struct htt_tx_pdev_stats_phy_err_tlv_v { -+- u32 phy_errs[0]; /* HTT_TX_PDEV_MAX_PHY_ERR_STATS */ -++ /* HTT_TX_PDEV_MAX_PHY_ERR_STATS */ -++ DECLARE_FLEX_ARRAY(u32, phy_errs); -+ }; -+ -+ /* NOTE: Variable length TLV, use length spec to infer array size */ -+ struct htt_tx_pdev_stats_sifs_hist_tlv_v { -+- u32 sifs_hist_status[0]; /* HTT_TX_PDEV_SIFS_BURST_HIST_STATS */ -++ /* HTT_TX_PDEV_SIFS_BURST_HIST_STATS */ -++ DECLARE_FLEX_ARRAY(u32, sifs_hist_status); -+ }; -+ -+ struct htt_tx_pdev_stats_tx_ppdu_stats_tlv_v { -+@@ -590,20 +596,20 @@ struct htt_tx_hwq_difs_latency_stats_tlv -+ -+ /* NOTE: Variable length TLV, use length spec to infer array size */ -+ struct htt_tx_hwq_cmd_result_stats_tlv_v { -+- /* Histogram of sched cmd result */ -+- u32 cmd_result[0]; /* HTT_TX_HWQ_MAX_CMD_RESULT_STATS */ -++ /* Histogram of sched cmd result, HTT_TX_HWQ_MAX_CMD_RESULT_STATS */ -++ DECLARE_FLEX_ARRAY(u32, cmd_result); -+ }; -+ -+ /* NOTE: Variable length TLV, use length spec to infer array size */ -+ struct htt_tx_hwq_cmd_stall_stats_tlv_v { -+- /* Histogram of various pause conitions */ -+- u32 cmd_stall_status[0]; /* HTT_TX_HWQ_MAX_CMD_STALL_STATS */ -++ /* Histogram of various pause conitions, HTT_TX_HWQ_MAX_CMD_STALL_STATS */ -++ DECLARE_FLEX_ARRAY(u32, cmd_stall_status); -+ }; -+ -+ /* NOTE: Variable length TLV, use length spec to infer array size */ -+ struct htt_tx_hwq_fes_result_stats_tlv_v { -+- /* Histogram of number of user fes result */ -+- u32 fes_result[0]; /* HTT_TX_HWQ_MAX_FES_RESULT_STATS */ -++ /* Histogram of number of user fes result, HTT_TX_HWQ_MAX_FES_RESULT_STATS */ -++ DECLARE_FLEX_ARRAY(u32, fes_result); -+ }; -+ -+ /* NOTE: Variable length TLV, use length spec to infer array size -+@@ -635,8 +641,8 @@ struct htt_tx_hwq_tried_mpdu_cnt_hist_tl -+ * #define WAL_TXOP_USED_HISTOGRAM_INTERVAL 1000 ( 1 ms ) -+ */ -+ struct htt_tx_hwq_txop_used_cnt_hist_tlv_v { -+- /* Histogram of txop used cnt */ -+- u32 txop_used_cnt_hist[0]; /* HTT_TX_HWQ_TXOP_USED_CNT_HIST */ -++ /* Histogram of txop used cnt, HTT_TX_HWQ_TXOP_USED_CNT_HIST */ -++ DECLARE_FLEX_ARRAY(u32, txop_used_cnt_hist); -+ }; -+ -+ /* == TX SELFGEN STATS == */ -+@@ -804,17 +810,20 @@ struct htt_tx_pdev_mpdu_stats_tlv { -+ /* == TX SCHED STATS == */ -+ /* NOTE: Variable length TLV, use length spec to infer array size */ -+ struct htt_sched_txq_cmd_posted_tlv_v { -+- u32 sched_cmd_posted[0]; /* HTT_TX_PDEV_SCHED_TX_MODE_MAX */ -++ /* HTT_TX_PDEV_SCHED_TX_MODE_MAX */ -++ DECLARE_FLEX_ARRAY(u32, sched_cmd_posted); -+ }; -+ -+ /* NOTE: Variable length TLV, use length spec to infer array size */ -+ struct htt_sched_txq_cmd_reaped_tlv_v { -+- u32 sched_cmd_reaped[0]; /* HTT_TX_PDEV_SCHED_TX_MODE_MAX */ -++ /* HTT_TX_PDEV_SCHED_TX_MODE_MAX */ -++ DECLARE_FLEX_ARRAY(u32, sched_cmd_reaped); -+ }; -+ -+ /* NOTE: Variable length TLV, use length spec to infer array size */ -+ struct htt_sched_txq_sched_order_su_tlv_v { -+- u32 sched_order_su[0]; /* HTT_TX_PDEV_NUM_SCHED_ORDER_LOG */ -++ /* HTT_TX_PDEV_NUM_SCHED_ORDER_LOG */ -++ DECLARE_FLEX_ARRAY(u32, sched_order_su); -+ }; -+ -+ enum htt_sched_txq_sched_ineligibility_tlv_enum { -+@@ -842,7 +851,7 @@ enum htt_sched_txq_sched_ineligibility_t -+ /* NOTE: Variable length TLV, use length spec to infer array size */ -+ struct htt_sched_txq_sched_ineligibility_tlv_v { -+ /* indexed by htt_sched_txq_sched_ineligibility_tlv_enum */ -+- u32 sched_ineligibility[0]; -++ DECLARE_FLEX_ARRAY(u32, sched_ineligibility); -+ }; -+ -+ #define HTT_TX_PDEV_STATS_SCHED_PER_TXQ_MAC_ID GENMASK(7, 0) -+@@ -888,18 +897,20 @@ struct htt_stats_tx_sched_cmn_tlv { -+ -+ /* NOTE: Variable length TLV, use length spec to infer array size */ -+ struct htt_tx_tqm_gen_mpdu_stats_tlv_v { -+- u32 gen_mpdu_end_reason[0]; /* HTT_TX_TQM_MAX_GEN_MPDU_END_REASON */ -++ /* HTT_TX_TQM_MAX_GEN_MPDU_END_REASON */ -++ DECLARE_FLEX_ARRAY(u32, gen_mpdu_end_reason); -+ }; -+ -+ /* NOTE: Variable length TLV, use length spec to infer array size */ -+ struct htt_tx_tqm_list_mpdu_stats_tlv_v { -+- u32 list_mpdu_end_reason[0]; /* HTT_TX_TQM_MAX_LIST_MPDU_END_REASON */ -++ /* HTT_TX_TQM_MAX_LIST_MPDU_END_REASON */ -++ DECLARE_FLEX_ARRAY(u32, list_mpdu_end_reason); -+ }; -+ -+ /* NOTE: Variable length TLV, use length spec to infer array size */ -+ struct htt_tx_tqm_list_mpdu_cnt_tlv_v { -+- u32 list_mpdu_cnt_hist[0]; -+- /* HTT_TX_TQM_MAX_LIST_MPDU_CNT_HISTOGRAM_BINS */ -++ /* HTT_TX_TQM_MAX_LIST_MPDU_CNT_HISTOGRAM_BINS */ -++ DECLARE_FLEX_ARRAY(u32, list_mpdu_cnt_hist); -+ }; -+ -+ struct htt_tx_tqm_pdev_stats_tlv_v { -+@@ -1098,7 +1109,7 @@ struct htt_tx_de_compl_stats_tlv { -+ * ENTRIES_PER_BIN_COUNT) -+ */ -+ struct htt_tx_de_fw2wbm_ring_full_hist_tlv { -+- u32 fw2wbm_ring_full_hist[0]; -++ DECLARE_FLEX_ARRAY(u32, fw2wbm_ring_full_hist); -+ }; -+ -+ struct htt_tx_de_cmn_stats_tlv { -+@@ -1151,7 +1162,7 @@ struct htt_ring_if_cmn_tlv { -+ /* NOTE: Variable length TLV, use length spec to infer array size */ -+ struct htt_sfm_client_user_tlv_v { -+ /* Number of DWORDS used per user and per client */ -+- u32 dwords_used_by_user_n[0]; -++ DECLARE_FLEX_ARRAY(u32, dwords_used_by_user_n); -+ }; -+ -+ struct htt_sfm_client_tlv { -+@@ -1436,12 +1447,14 @@ struct htt_rx_soc_fw_stats_tlv { -+ -+ /* NOTE: Variable length TLV, use length spec to infer array size */ -+ struct htt_rx_soc_fw_refill_ring_empty_tlv_v { -+- u32 refill_ring_empty_cnt[0]; /* HTT_RX_STATS_REFILL_MAX_RING */ -++ /* HTT_RX_STATS_REFILL_MAX_RING */ -++ DECLARE_FLEX_ARRAY(u32, refill_ring_empty_cnt); -+ }; -+ -+ /* NOTE: Variable length TLV, use length spec to infer array size */ -+ struct htt_rx_soc_fw_refill_ring_num_refill_tlv_v { -+- u32 refill_ring_num_refill[0]; /* HTT_RX_STATS_REFILL_MAX_RING */ -++ /* HTT_RX_STATS_REFILL_MAX_RING */ -++ DECLARE_FLEX_ARRAY(u32, refill_ring_num_refill); -+ }; -+ -+ /* RXDMA error code from WBM released packets */ -+@@ -1473,7 +1486,7 @@ enum htt_rx_rxdma_error_code_enum { -+ -+ /* NOTE: Variable length TLV, use length spec to infer array size */ -+ struct htt_rx_soc_fw_refill_ring_num_rxdma_err_tlv_v { -+- u32 rxdma_err[0]; /* HTT_RX_RXDMA_MAX_ERR_CODE */ -++ DECLARE_FLEX_ARRAY(u32, rxdma_err); /* HTT_RX_RXDMA_MAX_ERR_CODE */ -+ }; -+ -+ /* REO error code from WBM released packets */ -+@@ -1505,7 +1518,7 @@ enum htt_rx_reo_error_code_enum { -+ -+ /* NOTE: Variable length TLV, use length spec to infer array size */ -+ struct htt_rx_soc_fw_refill_ring_num_reo_err_tlv_v { -+- u32 reo_err[0]; /* HTT_RX_REO_MAX_ERR_CODE */ -++ DECLARE_FLEX_ARRAY(u32, reo_err); /* HTT_RX_REO_MAX_ERR_CODE */ -+ }; -+ -+ /* == RX PDEV STATS == */ -+@@ -1622,13 +1635,13 @@ struct htt_rx_pdev_fw_stats_phy_err_tlv -+ /* NOTE: Variable length TLV, use length spec to infer array size */ -+ struct htt_rx_pdev_fw_ring_mpdu_err_tlv_v { -+ /* Num error MPDU for each RxDMA error type */ -+- u32 fw_ring_mpdu_err[0]; /* HTT_RX_STATS_RXDMA_MAX_ERR */ -++ DECLARE_FLEX_ARRAY(u32, fw_ring_mpdu_err); /* HTT_RX_STATS_RXDMA_MAX_ERR */ -+ }; -+ -+ /* NOTE: Variable length TLV, use length spec to infer array size */ -+ struct htt_rx_pdev_fw_mpdu_drop_tlv_v { -+ /* Num MPDU dropped */ -+- u32 fw_mpdu_drop[0]; /* HTT_RX_STATS_FW_DROP_REASON_MAX */ -++ DECLARE_FLEX_ARRAY(u32, fw_mpdu_drop); /* HTT_RX_STATS_FW_DROP_REASON_MAX */ -+ }; -+ -+ #define HTT_PDEV_CCA_STATS_TX_FRAME_INFO_PRESENT (0x1) -diff --git a/package/kernel/mac80211/patches/ath11k/0047-wifi-ath11k-fix-deinitialization-of-firmware-resourc.patch b/package/kernel/mac80211/patches/ath11k/0047-wifi-ath11k-fix-deinitialization-of-firmware-resourc.patch -new file mode 100644 -index 0000000000..eec11f50e3 ---- /dev/null -+++ b/package/kernel/mac80211/patches/ath11k/0047-wifi-ath11k-fix-deinitialization-of-firmware-resourc.patch -@@ -0,0 +1,79 @@ -+From 5a78ac33e3cb8822da64dd1af196e83664b332b0 Mon Sep 17 00:00:00 2001 -+From: Aditya Kumar Singh -+Date: Thu, 9 Mar 2023 15:23:08 +0530 -+Subject: [PATCH] wifi: ath11k: fix deinitialization of firmware resources -+ -+Currently, in ath11k_ahb_fw_resources_init(), iommu domain -+mapping is done only for the chipsets having fixed firmware -+memory. Also, for such chipsets, mapping is done only if it -+does not have TrustZone support. -+ -+During deinitialization, only if TrustZone support is not there, -+iommu is unmapped back. However, for non fixed firmware memory -+chipsets, TrustZone support is not there and this makes the -+condition check to true and it tries to unmap the memory which -+was not mapped during initialization. -+ -+This leads to the following trace - -+ -+[ 83.198790] Unable to handle kernel NULL pointer dereference at virtual address 0000000000000008 -+[ 83.259537] Modules linked in: ath11k_ahb ath11k qmi_helpers -+.. snip .. -+[ 83.280286] pstate: 20000005 (nzCv daif -PAN -UAO -TCO -DIT -SSBS BTYPE=--) -+[ 83.287228] pc : __iommu_unmap+0x30/0x140 -+[ 83.293907] lr : iommu_unmap+0x5c/0xa4 -+[ 83.298072] sp : ffff80000b3abad0 -+.. snip .. -+[ 83.369175] Call trace: -+[ 83.376282] __iommu_unmap+0x30/0x140 -+[ 83.378541] iommu_unmap+0x5c/0xa4 -+[ 83.382360] ath11k_ahb_fw_resource_deinit.part.12+0x2c/0xac [ath11k_ahb] -+[ 83.385666] ath11k_ahb_free_resources+0x140/0x17c [ath11k_ahb] -+[ 83.392521] ath11k_ahb_shutdown+0x34/0x40 [ath11k_ahb] -+[ 83.398248] platform_shutdown+0x20/0x2c -+[ 83.403455] device_shutdown+0x16c/0x1c4 -+[ 83.407621] kernel_restart_prepare+0x34/0x3c -+[ 83.411529] kernel_restart+0x14/0x74 -+[ 83.415781] __do_sys_reboot+0x1c4/0x22c -+[ 83.419427] __arm64_sys_reboot+0x1c/0x24 -+[ 83.423420] invoke_syscall+0x44/0xfc -+[ 83.427326] el0_svc_common.constprop.3+0xac/0xe8 -+[ 83.430974] do_el0_svc+0xa0/0xa8 -+[ 83.435659] el0_svc+0x1c/0x44 -+[ 83.438957] el0t_64_sync_handler+0x60/0x144 -+[ 83.441910] el0t_64_sync+0x15c/0x160 -+[ 83.446343] Code: aa0103f4 f9400001 f90027a1 d2800001 (f94006a0) -+[ 83.449903] ---[ end trace 0000000000000000 ]--- -+ -+This can be reproduced by probing an AHB chipset which is not -+having a fixed memory region. During reboot (or rmmod) trace -+can be seen. -+ -+Fix this issue by adding a condition check on firmware fixed memory -+hw_param as done in the counter initialization function. -+ -+Tested-on: IPQ8074 hw2.0 AHB WLAN.HK.2.7.0.1-01744-QCAHKSWPL_SILICONZ-1 -+ -+Fixes: f9eec4947add ("ath11k: Add support for targets without trustzone") -+Signed-off-by: Aditya Kumar Singh -+Signed-off-by: Kalle Valo -+Link: https://lore.kernel.org/r/20230309095308.24937-1-quic_adisi@quicinc.com -+--- -+ drivers/net/wireless/ath/ath11k/ahb.c | 6 ++++++ -+ 1 file changed, 6 insertions(+) -+ -+--- a/drivers/net/wireless/ath/ath11k/ahb.c -++++ b/drivers/net/wireless/ath/ath11k/ahb.c -+@@ -1078,6 +1078,12 @@ static int ath11k_ahb_fw_resource_deinit -+ struct iommu_domain *iommu; -+ size_t unmapped_size; -+ -++ /* Chipsets not requiring MSA would have not initialized -++ * MSA resources, return success in such cases. -++ */ -++ if (!ab->hw_params.fixed_fw_mem) -++ return 0; -++ -+ if (ab_ahb->fw.use_tz) -+ return 0; -+ -diff --git a/package/kernel/mac80211/patches/ath11k/0048-wifi-ath11k-fix-BUFFER_DONE-read-on-monitor-ring-rx-.patch b/package/kernel/mac80211/patches/ath11k/0048-wifi-ath11k-fix-BUFFER_DONE-read-on-monitor-ring-rx-.patch -new file mode 100644 -index 0000000000..3e22645331 ---- /dev/null -+++ b/package/kernel/mac80211/patches/ath11k/0048-wifi-ath11k-fix-BUFFER_DONE-read-on-monitor-ring-rx-.patch -@@ -0,0 +1,130 @@ -+From 68e93ac5a31d4975b25f819b2dfe914c72abc3bb Mon Sep 17 00:00:00 2001 -+From: Harshitha Prem -+Date: Wed, 15 Mar 2023 12:24:43 +0200 -+Subject: [PATCH] wifi: ath11k: fix BUFFER_DONE read on monitor ring rx buffer -+ -+Perform dma_sync_single_for_cpu() on monitor ring rx buffer before -+reading BUFFER_DONE tag and do dma_unmap_single() only after device -+had set BUFFER_DONE tag to the buffer. -+ -+Also when BUFFER_DONE tag is not set, allow the buffer to get read -+next time without freeing skb. -+ -+This helps to fix AP+Monitor VAP with flood traffic scenario to see -+monitor ring rx buffer overrun missing BUFFER_DONE tag to be set. -+ -+Also remove redundant rx dma buf free performed on DP -+rx_mon_status_refill_ring. -+ -+Tested-on: IPQ8074 hw2.0 AHB WLAN.HK.2.7.0.1-01744-QCAHKSWPL_SILICONZ-1 -+ -+Signed-off-by: Sathishkumar Muruganandam -+Signed-off-by: Harshitha Prem -+Signed-off-by: Kalle Valo -+Link: https://lore.kernel.org/r/20230309164434.32660-1-quic_hprem@quicinc.com -+--- -+ drivers/net/wireless/ath/ath11k/dp_rx.c | 57 ++++++++++--------------- -+ 1 file changed, 23 insertions(+), 34 deletions(-) -+ -+--- a/drivers/net/wireless/ath/ath11k/dp_rx.c -++++ b/drivers/net/wireless/ath/ath11k/dp_rx.c -+@@ -435,7 +435,6 @@ fail_free_skb: -+ static int ath11k_dp_rxdma_buf_ring_free(struct ath11k *ar, -+ struct dp_rxdma_ring *rx_ring) -+ { -+- struct ath11k_pdev_dp *dp = &ar->dp; -+ struct sk_buff *skb; -+ int buf_id; -+ -+@@ -453,28 +452,6 @@ static int ath11k_dp_rxdma_buf_ring_free -+ idr_destroy(&rx_ring->bufs_idr); -+ spin_unlock_bh(&rx_ring->idr_lock); -+ -+- /* if rxdma1_enable is false, mon_status_refill_ring -+- * isn't setup, so don't clean. -+- */ -+- if (!ar->ab->hw_params.rxdma1_enable) -+- return 0; -+- -+- rx_ring = &dp->rx_mon_status_refill_ring[0]; -+- -+- spin_lock_bh(&rx_ring->idr_lock); -+- idr_for_each_entry(&rx_ring->bufs_idr, skb, buf_id) { -+- idr_remove(&rx_ring->bufs_idr, buf_id); -+- /* XXX: Understand where internal driver does this dma_unmap -+- * of rxdma_buffer. -+- */ -+- dma_unmap_single(ar->ab->dev, ATH11K_SKB_RXCB(skb)->paddr, -+- skb->len + skb_tailroom(skb), DMA_BIDIRECTIONAL); -+- dev_kfree_skb_any(skb); -+- } -+- -+- idr_destroy(&rx_ring->bufs_idr); -+- spin_unlock_bh(&rx_ring->idr_lock); -+- -+ return 0; -+ } -+ -+@@ -3029,39 +3006,51 @@ static int ath11k_dp_rx_reap_mon_status_ -+ -+ 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) { -+ ath11k_warn(ab, "rx monitor status with invalid buf_id %d\n", -+ buf_id); -+- spin_unlock_bh(&rx_ring->idr_lock); -+ pmon->buf_state = DP_MON_STATUS_REPLINISH; -+ goto move_next; -+ } -+ -+- 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, -+- skb->len + skb_tailroom(skb), -+- DMA_FROM_DEVICE); -++ 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) { -+- ath11k_warn(ab, "mon status DONE not set %lx\n", -++ ath11k_warn(ab, "mon status DONE not set %lx, buf_id %d\n", -+ FIELD_GET(HAL_TLV_HDR_TAG, -+- tlv->tl)); -+- dev_kfree_skb_any(skb); -++ 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 -++ */ -+ pmon->buf_state = DP_MON_STATUS_NO_DMA; -+- goto move_next; -++ break; -+ } -+ -++ spin_lock_bh(&rx_ring->idr_lock); -++ idr_remove(&rx_ring->bufs_idr, buf_id); -++ spin_unlock_bh(&rx_ring->idr_lock); -+ if (ab->hw_params.full_monitor_mode) { -+ ath11k_dp_rx_mon_update_status_buf_state(pmon, tlv); -+ if (paddr == pmon->mon_status_paddr) -+ pmon->buf_state = DP_MON_STATUS_MATCH; -+ } -++ -++ dma_unmap_single(ab->dev, rxcb->paddr, -++ skb->len + skb_tailroom(skb), -++ DMA_FROM_DEVICE); -++ -+ __skb_queue_tail(skb_list, skb); -+ } else { -+ pmon->buf_state = DP_MON_STATUS_REPLINISH; -diff --git a/package/kernel/mac80211/patches/ath11k/0049-wifi-ath11k-Optimize-6-GHz-scan-time.patch b/package/kernel/mac80211/patches/ath11k/0049-wifi-ath11k-Optimize-6-GHz-scan-time.patch -new file mode 100644 -index 0000000000..f468990feb ---- /dev/null -+++ b/package/kernel/mac80211/patches/ath11k/0049-wifi-ath11k-Optimize-6-GHz-scan-time.patch -@@ -0,0 +1,101 @@ -+From 8b4d2f080afbd4280ecca0f4b3ceea943a7a86d0 Mon Sep 17 00:00:00 2001 -+From: Manikanta Pubbisetty -+Date: Thu, 23 Mar 2023 11:39:13 +0530 -+Subject: [PATCH] wifi: ath11k: Optimize 6 GHz scan time -+ -+Currently, time taken to scan all supported channels on WCN6750 -+is ~8 seconds and connection time is almost 10 seconds. WCN6750 -+supports three Wi-Fi bands (i.e., 2.4/5/6 GHz) and the numbers of -+channels for scan come around ~100 channels (default case). -+Since the chip doesn't have support for DBS (Dual Band Simultaneous), -+scans cannot be parallelized resulting in longer scan times. -+ -+Among the 100 odd channels, ~60 channels are in 6 GHz band. Therefore, -+optimizing the scan for 6 GHz channels will bring down the overall -+scan time. -+ -+WCN6750 firmware has support to scan a 6 GHz channel based on co-located -+AP information i.e., RNR IE which is found in the legacy 2.4/5 GHz scan -+results. When a scan request with all supported channel list is enqueued -+to the firmware, then based on WMI_SCAN_CHAN_FLAG_SCAN_ONLY_IF_RNR_FOUND -+scan channel flag, firmware will scan only those 6 GHz channels for which -+RNR IEs are found in the legacy scan results. -+ -+In the proposed design, based on NL80211_SCAN_FLAG_COLOCATED_6GHZ scan -+flag, driver will set the WMI_SCAN_CHAN_FLAG_SCAN_ONLY_IF_RNR_FOUND flag -+for non-PSC channels. Since there is high probability to find 6 GHz APs -+on PSC channels, these channels are always scanned. Only non-PSC channels -+are selectively scanned based on cached RNR information from the legacy -+scan results. -+ -+If NL80211_SCAN_FLAG_COLOCATED_6GHZ is not set in the scan flags, -+then scan will happen on all supported channels (default behavior). -+ -+With these optimizations, scan time is improved by 1.5-1.8 seconds on -+WCN6750. Similar savings have been observed on WCN6855. -+ -+Tested-on: WCN6750 hw1.0 AHB WLAN.MSL.1.0.1-00887-QCAMSLSWPLZ-1 -+Tested-on: WCN6855 hw2.1 PCI WLAN.HSP.1.1-03125-QCAHSPSWPL_V1_V2_SILICONZ_LITE-3.6510.16 -+ -+Signed-off-by: Manikanta Pubbisetty -+Signed-off-by: Kalle Valo -+Link: https://lore.kernel.org/r/20230323060913.10097-1-quic_mpubbise@quicinc.com -+--- -+ drivers/net/wireless/ath/ath11k/mac.c | 25 +++++++++++++++++++++++-- -+ drivers/net/wireless/ath/ath11k/wmi.h | 4 ++++ -+ 2 files changed, 27 insertions(+), 2 deletions(-) -+ -+--- a/drivers/net/wireless/ath/ath11k/mac.c -++++ b/drivers/net/wireless/ath/ath11k/mac.c -+@@ -3819,8 +3819,29 @@ static int ath11k_mac_op_hw_scan(struct -+ goto exit; -+ } -+ -+- for (i = 0; i < arg->num_chan; i++) -+- arg->chan_list[i] = req->channels[i]->center_freq; -++ for (i = 0; i < arg->num_chan; i++) { -++ if (test_bit(WMI_TLV_SERVICE_SCAN_CONFIG_PER_CHANNEL, -++ ar->ab->wmi_ab.svc_map)) { -++ arg->chan_list[i] = -++ u32_encode_bits(req->channels[i]->center_freq, -++ WMI_SCAN_CONFIG_PER_CHANNEL_MASK); -++ -++ /* If NL80211_SCAN_FLAG_COLOCATED_6GHZ is set in scan -++ * flags, then scan all PSC channels in 6 GHz band and -++ * those non-PSC channels where RNR IE is found during -++ * the legacy 2.4/5 GHz scan. -++ * If NL80211_SCAN_FLAG_COLOCATED_6GHZ is not set, -++ * then all channels in 6 GHz will be scanned. -++ */ -++ if (req->channels[i]->band == NL80211_BAND_6GHZ && -++ req->flags & NL80211_SCAN_FLAG_COLOCATED_6GHZ && -++ !cfg80211_channel_is_psc(req->channels[i])) -++ arg->chan_list[i] |= -++ WMI_SCAN_CH_FLAG_SCAN_ONLY_IF_RNR_FOUND; -++ } else { -++ arg->chan_list[i] = req->channels[i]->center_freq; -++ } -++ } -+ } -+ -+ if (req->flags & NL80211_SCAN_FLAG_RANDOM_ADDR) { -+--- a/drivers/net/wireless/ath/ath11k/wmi.h -++++ b/drivers/net/wireless/ath/ath11k/wmi.h -+@@ -2100,6 +2100,7 @@ enum wmi_tlv_service { -+ -+ /* The second 128 bits */ -+ WMI_MAX_EXT_SERVICE = 256, -++ WMI_TLV_SERVICE_SCAN_CONFIG_PER_CHANNEL = 265, -+ WMI_TLV_SERVICE_REG_CC_EXT_EVENT_SUPPORT = 281, -+ WMI_TLV_SERVICE_BIOS_SAR_SUPPORT = 326, -+ -+@@ -3249,6 +3250,9 @@ struct wmi_start_scan_cmd { -+ #define WMI_SCAN_DWELL_MODE_SHIFT 21 -+ #define WMI_SCAN_FLAG_EXT_PASSIVE_SCAN_START_TIME_ENHANCE 0x00000800 -+ -++#define WMI_SCAN_CONFIG_PER_CHANNEL_MASK GENMASK(19, 0) -++#define WMI_SCAN_CH_FLAG_SCAN_ONLY_IF_RNR_FOUND BIT(20) -++ -+ enum { -+ WMI_SCAN_DWELL_MODE_DEFAULT = 0, -+ WMI_SCAN_DWELL_MODE_CONSERVATIVE = 1, -diff --git a/package/kernel/mac80211/patches/ath11k/0050-wifi-ath11k-Configure-the-FTM-responder-role-using-f.patch b/package/kernel/mac80211/patches/ath11k/0050-wifi-ath11k-Configure-the-FTM-responder-role-using-f.patch -new file mode 100644 -index 0000000000..bca08b177f ---- /dev/null -+++ b/package/kernel/mac80211/patches/ath11k/0050-wifi-ath11k-Configure-the-FTM-responder-role-using-f.patch -@@ -0,0 +1,117 @@ -+From 813968c24126cc5c8320cd5db0e262069a535063 Mon Sep 17 00:00:00 2001 -+From: Ganesh Babu Jothiram -+Date: Fri, 24 Mar 2023 16:57:00 +0200 -+Subject: [PATCH] wifi: ath11k: Configure the FTM responder role using firmware -+ capability flag -+ -+Fine Time Measurement(FTM) is offloaded feature to firmware. -+Hence, the configuration of FTM responder role is done using -+firmware capability flag instead of hw param. -+ -+Tested-on: QCN9074 hw1.0 PCI WLAN.HK.2.7.0.1-01744-QCAHKSWPL_SILICONZ-1 -+ -+Signed-off-by: Ganesh Babu Jothiram -+Signed-off-by: Kalle Valo -+Link: https://lore.kernel.org/r/20230317072034.8217-1-quic_gjothira@quicinc.com -+--- -+ drivers/net/wireless/ath/ath11k/core.c | 8 -------- -+ drivers/net/wireless/ath/ath11k/hw.h | 1 - -+ drivers/net/wireless/ath/ath11k/mac.c | 4 ++-- -+ 3 files changed, 2 insertions(+), 11 deletions(-) -+ -+--- a/drivers/net/wireless/ath/ath11k/core.c -++++ b/drivers/net/wireless/ath/ath11k/core.c -+@@ -116,7 +116,6 @@ static const struct ath11k_hw_params ath -+ .tcl_ring_retry = true, -+ .tx_ring_size = DP_TCL_DATA_RING_SIZE, -+ .smp2p_wow_exit = false, -+- .ftm_responder = true, -+ }, -+ { -+ .hw_rev = ATH11K_HW_IPQ6018_HW10, -+@@ -199,7 +198,6 @@ static const struct ath11k_hw_params ath -+ .tx_ring_size = DP_TCL_DATA_RING_SIZE, -+ .smp2p_wow_exit = false, -+ .support_fw_mac_sequence = false, -+- .ftm_responder = true, -+ }, -+ { -+ .name = "qca6390 hw2.0", -+@@ -284,7 +282,6 @@ static const struct ath11k_hw_params ath -+ .tx_ring_size = DP_TCL_DATA_RING_SIZE, -+ .smp2p_wow_exit = false, -+ .support_fw_mac_sequence = true, -+- .ftm_responder = false, -+ }, -+ { -+ .name = "qcn9074 hw1.0", -+@@ -366,7 +363,6 @@ static const struct ath11k_hw_params ath -+ .tx_ring_size = DP_TCL_DATA_RING_SIZE, -+ .smp2p_wow_exit = false, -+ .support_fw_mac_sequence = false, -+- .ftm_responder = true, -+ }, -+ { -+ .name = "wcn6855 hw2.0", -+@@ -451,7 +447,6 @@ static const struct ath11k_hw_params ath -+ .tx_ring_size = DP_TCL_DATA_RING_SIZE, -+ .smp2p_wow_exit = false, -+ .support_fw_mac_sequence = true, -+- .ftm_responder = false, -+ }, -+ { -+ .name = "wcn6855 hw2.1", -+@@ -534,7 +529,6 @@ static const struct ath11k_hw_params ath -+ .tx_ring_size = DP_TCL_DATA_RING_SIZE, -+ .smp2p_wow_exit = false, -+ .support_fw_mac_sequence = true, -+- .ftm_responder = false, -+ }, -+ { -+ .name = "wcn6750 hw1.0", -+@@ -615,7 +609,6 @@ static const struct ath11k_hw_params ath -+ .tx_ring_size = DP_TCL_DATA_RING_SIZE_WCN6750, -+ .smp2p_wow_exit = true, -+ .support_fw_mac_sequence = true, -+- .ftm_responder = false, -+ }, -+ { -+ .hw_rev = ATH11K_HW_IPQ5018_HW10, -+@@ -695,7 +688,6 @@ static const struct ath11k_hw_params ath -+ .tx_ring_size = DP_TCL_DATA_RING_SIZE, -+ .smp2p_wow_exit = false, -+ .support_fw_mac_sequence = false, -+- .ftm_responder = true, -+ }, -+ }; -+ -+--- a/drivers/net/wireless/ath/ath11k/hw.h -++++ b/drivers/net/wireless/ath/ath11k/hw.h -+@@ -224,7 +224,6 @@ struct ath11k_hw_params { -+ u32 tx_ring_size; -+ bool smp2p_wow_exit; -+ bool support_fw_mac_sequence; -+- bool ftm_responder; -+ }; -+ -+ struct ath11k_hw_ops { -+--- a/drivers/net/wireless/ath/ath11k/mac.c -++++ b/drivers/net/wireless/ath/ath11k/mac.c -+@@ -3538,7 +3538,7 @@ static void ath11k_mac_op_bss_info_chang -+ -+ if (changed & BSS_CHANGED_FTM_RESPONDER && -+ arvif->ftm_responder != info->ftm_responder && -+- ar->ab->hw_params.ftm_responder && -++ test_bit(WMI_TLV_SERVICE_RTT, ar->ab->wmi_ab.svc_map) && -+ (vif->type == NL80211_IFTYPE_AP || -+ vif->type == NL80211_IFTYPE_MESH_POINT)) { -+ arvif->ftm_responder = info->ftm_responder; -+@@ -9234,7 +9234,7 @@ static int __ath11k_mac_register(struct -+ wiphy_ext_feature_set(ar->hw->wiphy, -+ NL80211_EXT_FEATURE_SET_SCAN_DWELL); -+ -+- if (ab->hw_params.ftm_responder) -++ if (test_bit(WMI_TLV_SERVICE_RTT, ar->ab->wmi_ab.svc_map)) -+ wiphy_ext_feature_set(ar->hw->wiphy, -+ NL80211_EXT_FEATURE_ENABLE_FTM_RESPONDER); -+ -diff --git a/package/kernel/mac80211/patches/ath11k/0051-wifi-ath11k-fix-rssi-station-dump-not-updated-in-QCN.patch b/package/kernel/mac80211/patches/ath11k/0051-wifi-ath11k-fix-rssi-station-dump-not-updated-in-QCN.patch -new file mode 100644 -index 0000000000..835dece1fe ---- /dev/null -+++ b/package/kernel/mac80211/patches/ath11k/0051-wifi-ath11k-fix-rssi-station-dump-not-updated-in-QCN.patch -@@ -0,0 +1,158 @@ -+From 031ffa6c2cd305a57ccc6d610f2decd956b2e7f6 Mon Sep 17 00:00:00 2001 -+From: P Praneesh -+Date: Fri, 24 Mar 2023 16:57:00 +0200 -+Subject: [PATCH] wifi: ath11k: fix rssi station dump not updated in QCN9074 -+ -+In QCN9074, station dump signal values display default value which -+is -95 dbm, since there is firmware header change for HAL_RX_MPDU_START -+between QCN9074 and IPQ8074 which cause wrong peer_id fetch from msdu. -+Fix this by updating hal_rx_mpdu_info with corresponding QCN9074 tlv -+format. -+ -+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.4.0.1-01695-QCAHKSWPL_SILICONZ-1 -+ -+Signed-off-by: P Praneesh -+Signed-off-by: Kalle Valo -+Link: https://lore.kernel.org/r/20230320110312.20639-1-quic_ppranees@quicinc.com -+--- -+ drivers/net/wireless/ath/ath11k/hal_rx.c | 10 ++++++++- -+ drivers/net/wireless/ath/ath11k/hal_rx.h | 18 +++++++++++++++- -+ drivers/net/wireless/ath/ath11k/hw.c | 27 ++++++++++++++++-------- -+ drivers/net/wireless/ath/ath11k/hw.h | 2 +- -+ 4 files changed, 45 insertions(+), 12 deletions(-) -+ -+--- a/drivers/net/wireless/ath/ath11k/hal_rx.c -++++ b/drivers/net/wireless/ath/ath11k/hal_rx.c -+@@ -865,6 +865,12 @@ ath11k_hal_rx_populate_mu_user_info(void -+ ath11k_hal_rx_populate_byte_count(rx_tlv, ppdu_info, rx_user_status); -+ } -+ -++static u16 ath11k_hal_rx_mpduinfo_get_peerid(struct ath11k_base *ab, -++ struct hal_rx_mpdu_info *mpdu_info) -++{ -++ return ab->hw_params.hw_ops->mpdu_info_get_peerid(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, -+@@ -1459,9 +1465,11 @@ ath11k_hal_rx_parse_mon_status_tlv(struc -+ break; -+ } -+ case HAL_RX_MPDU_START: { -++ struct hal_rx_mpdu_info *mpdu_info = -++ (struct hal_rx_mpdu_info *)tlv_data; -+ u16 peer_id; -+ -+- peer_id = ab->hw_params.hw_ops->mpdu_info_get_peerid(tlv_data); -++ peer_id = ath11k_hal_rx_mpduinfo_get_peerid(ab, mpdu_info); -+ if (peer_id) -+ ppdu_info->peer_id = peer_id; -+ break; -+--- a/drivers/net/wireless/ath/ath11k/hal_rx.h -++++ b/drivers/net/wireless/ath/ath11k/hal_rx.h -+@@ -405,7 +405,7 @@ struct hal_rx_phyrx_rssi_legacy_info { -+ #define HAL_RX_MPDU_INFO_INFO0_PEERID_WCN6855 GENMASK(15, 0) -+ #define HAL_RX_MPDU_INFO_INFO1_MPDU_LEN GENMASK(13, 0) -+ -+-struct hal_rx_mpdu_info { -++struct hal_rx_mpdu_info_ipq8074 { -+ __le32 rsvd0; -+ __le32 info0; -+ __le32 rsvd1[11]; -+@@ -413,12 +413,28 @@ struct hal_rx_mpdu_info { -+ __le32 rsvd2[9]; -+ } __packed; -+ -++struct hal_rx_mpdu_info_qcn9074 { -++ __le32 rsvd0[10]; -++ __le32 info0; -++ __le32 rsvd1[2]; -++ __le32 info1; -++ __le32 rsvd2[9]; -++} __packed; -++ -+ struct hal_rx_mpdu_info_wcn6855 { -+ __le32 rsvd0[8]; -+ __le32 info0; -+ __le32 rsvd1[14]; -+ } __packed; -+ -++struct hal_rx_mpdu_info { -++ union { -++ struct hal_rx_mpdu_info_ipq8074 ipq8074; -++ struct hal_rx_mpdu_info_qcn9074 qcn9074; -++ struct hal_rx_mpdu_info_wcn6855 wcn6855; -++ } u; -++} __packed; -++ -+ #define HAL_RX_PPDU_END_DURATION GENMASK(23, 0) -+ struct hal_rx_ppdu_end_duration { -+ __le32 rsvd0[9]; -+--- a/drivers/net/wireless/ath/ath11k/hw.c -++++ b/drivers/net/wireless/ath/ath11k/hw.c -+@@ -835,26 +835,35 @@ static void ath11k_hw_ipq5018_reo_setup( -+ ring_hash_map); -+ } -+ -+-static u16 ath11k_hw_ipq8074_mpdu_info_get_peerid(u8 *tlv_data) -++static u16 -++ath11k_hw_ipq8074_mpdu_info_get_peerid(struct hal_rx_mpdu_info *mpdu_info) -+ { -+ u16 peer_id = 0; -+- struct hal_rx_mpdu_info *mpdu_info = -+- (struct hal_rx_mpdu_info *)tlv_data; -+ -+ peer_id = FIELD_GET(HAL_RX_MPDU_INFO_INFO0_PEERID, -+- __le32_to_cpu(mpdu_info->info0)); -++ __le32_to_cpu(mpdu_info->u.ipq8074.info0)); -+ -+ return peer_id; -+ } -+ -+-static u16 ath11k_hw_wcn6855_mpdu_info_get_peerid(u8 *tlv_data) -++static u16 -++ath11k_hw_qcn9074_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.qcn9074.info0)); -++ -++ return peer_id; -++} -++ -++static u16 -++ath11k_hw_wcn6855_mpdu_info_get_peerid(struct hal_rx_mpdu_info *mpdu_info) -+ { -+ u16 peer_id = 0; -+- struct hal_rx_mpdu_info_wcn6855 *mpdu_info = -+- (struct hal_rx_mpdu_info_wcn6855 *)tlv_data; -+ -+ peer_id = FIELD_GET(HAL_RX_MPDU_INFO_INFO0_PEERID_WCN6855, -+- __le32_to_cpu(mpdu_info->info0)); -++ __le32_to_cpu(mpdu_info->u.wcn6855.info0)); -+ return peer_id; -+ } -+ -+@@ -1042,7 +1051,7 @@ const struct ath11k_hw_ops qcn9074_ops = -+ .rx_desc_get_attention = ath11k_hw_qcn9074_rx_desc_get_attention, -+ .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_ipq8074_mpdu_info_get_peerid, -++ .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 -+@@ -263,7 +263,7 @@ struct ath11k_hw_ops { -+ struct rx_attention *(*rx_desc_get_attention)(struct hal_rx_desc *desc); -+ u8 *(*rx_desc_get_msdu_payload)(struct hal_rx_desc *desc); -+ void (*reo_setup)(struct ath11k_base *ab); -+- u16 (*mpdu_info_get_peerid)(u8 *tlv_data); -++ u16 (*mpdu_info_get_peerid)(struct hal_rx_mpdu_info *mpdu_info); -+ 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/0052-wifi-ath11k-Fix-invalid-management-rx-frame-length-i.patch b/package/kernel/mac80211/patches/ath11k/0052-wifi-ath11k-Fix-invalid-management-rx-frame-length-i.patch -new file mode 100644 -index 0000000000..0c1637fb04 ---- /dev/null -+++ b/package/kernel/mac80211/patches/ath11k/0052-wifi-ath11k-Fix-invalid-management-rx-frame-length-i.patch -@@ -0,0 +1,115 @@ -+From 447b0398a9cd41ca343dfd43e555af92d6214487 Mon Sep 17 00:00:00 2001 -+From: Bhagavathi Perumal S -+Date: Fri, 24 Mar 2023 16:57:00 +0200 -+Subject: [PATCH] wifi: ath11k: Fix invalid management rx frame length issue -+ -+The WMI management rx event has multiple arrays of TLVs, however the common -+WMI TLV parser won't handle multiple TLV tags of same type. -+So the multiple array tags of WMI management rx TLV is parsed incorrectly -+and the length calculated becomes wrong when the target sends multiple -+array tags. -+ -+Add separate TLV parser to handle multiple arrays for WMI management rx -+TLV. This fixes invalid length issue when the target sends multiple array -+tags. -+ -+Tested-on: QCN9074 hw1.0 PCI WLAN.HK.2.7.0.1-01744-QCAHKSWPL_SILICONZ-1 -+ -+Signed-off-by: Bhagavathi Perumal S -+Co-developed-by: Nagarajan Maran -+Signed-off-by: Nagarajan Maran -+Signed-off-by: Kalle Valo -+Link: https://lore.kernel.org/r/20230320133840.30162-1-quic_nmaran@quicinc.com -+--- -+ drivers/net/wireless/ath/ath11k/wmi.c | 45 +++++++++++++++++++++------ -+ 1 file changed, 35 insertions(+), 10 deletions(-) -+ -+--- a/drivers/net/wireless/ath/ath11k/wmi.c -++++ b/drivers/net/wireless/ath/ath11k/wmi.c -+@@ -82,6 +82,12 @@ struct wmi_tlv_fw_stats_parse { -+ bool chain_rssi_done; -+ }; -+ -++struct wmi_tlv_mgmt_rx_parse { -++ const struct wmi_mgmt_rx_hdr *fixed; -++ const u8 *frame_buf; -++ bool frame_buf_done; -++}; -++ -+ static const struct wmi_tlv_policy wmi_tlv_policies[] = { -+ [WMI_TAG_ARRAY_BYTE] -+ = { .min_len = 0 }, -+@@ -5633,28 +5639,49 @@ static int ath11k_pull_vdev_stopped_para -+ return 0; -+ } -+ -++static int ath11k_wmi_tlv_mgmt_rx_parse(struct ath11k_base *ab, -++ u16 tag, u16 len, -++ const void *ptr, void *data) -++{ -++ struct wmi_tlv_mgmt_rx_parse *parse = data; -++ -++ switch (tag) { -++ case WMI_TAG_MGMT_RX_HDR: -++ parse->fixed = ptr; -++ break; -++ case WMI_TAG_ARRAY_BYTE: -++ if (!parse->frame_buf_done) { -++ parse->frame_buf = ptr; -++ parse->frame_buf_done = true; -++ } -++ break; -++ } -++ return 0; -++} -++ -+ static int ath11k_pull_mgmt_rx_params_tlv(struct ath11k_base *ab, -+ struct sk_buff *skb, -+ struct mgmt_rx_event_params *hdr) -+ { -+- const void **tb; -++ struct wmi_tlv_mgmt_rx_parse parse = { }; -+ const struct wmi_mgmt_rx_hdr *ev; -+ const u8 *frame; -+ 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); -++ ret = ath11k_wmi_tlv_iter(ab, skb->data, skb->len, -++ ath11k_wmi_tlv_mgmt_rx_parse, -++ &parse); -++ if (ret) { -++ ath11k_warn(ab, "failed to parse mgmt rx tlv %d\n", -++ ret); -+ return ret; -+ } -+ -+- ev = tb[WMI_TAG_MGMT_RX_HDR]; -+- frame = tb[WMI_TAG_ARRAY_BYTE]; -++ ev = parse.fixed; -++ frame = parse.frame_buf; -+ -+ if (!ev || !frame) { -+ ath11k_warn(ab, "failed to fetch mgmt rx hdr"); -+- kfree(tb); -+ return -EPROTO; -+ } -+ -+@@ -5673,7 +5700,6 @@ static int ath11k_pull_mgmt_rx_params_tl -+ -+ if (skb->len < (frame - skb->data) + hdr->buf_len) { -+ ath11k_warn(ab, "invalid length in mgmt rx hdr ev"); -+- kfree(tb); -+ return -EPROTO; -+ } -+ -+@@ -5685,7 +5711,6 @@ static int ath11k_pull_mgmt_rx_params_tl -+ -+ ath11k_ce_byte_swap(skb->data, hdr->buf_len); -+ -+- kfree(tb); -+ return 0; -+ } -+ -diff --git a/package/kernel/mac80211/patches/ath11k/0053-wifi-ath11k-fix-writing-to-unintended-memory-region.patch b/package/kernel/mac80211/patches/ath11k/0053-wifi-ath11k-fix-writing-to-unintended-memory-region.patch -new file mode 100644 -index 0000000000..7b8a7d4543 ---- /dev/null -+++ b/package/kernel/mac80211/patches/ath11k/0053-wifi-ath11k-fix-writing-to-unintended-memory-region.patch -@@ -0,0 +1,43 @@ -+From 756a7f90878f0866fd2fe167ef37e90b47326b96 Mon Sep 17 00:00:00 2001 -+From: P Praneesh -+Date: Fri, 24 Mar 2023 16:57:01 +0200 -+Subject: [PATCH] wifi: ath11k: fix writing to unintended memory region -+ -+While initializing spectral, the magic value is getting written to the -+invalid memory address leading to random boot-up crash. This occurs -+due to the incorrect index increment in ath11k_dbring_fill_magic_value -+function. Fix it by replacing the existing logic with memset32 to ensure -+there is no invalid memory access. -+ -+Tested-on: QCN9074 hw1.0 PCI WLAN.HK.2.4.0.1-01838-QCAHKSWPL_SILICONZ-1 -+ -+Fixes: d3d358efc553 ("ath11k: add spectral/CFR buffer validation support") -+Signed-off-by: P Praneesh -+Signed-off-by: Kalle Valo -+Link: https://lore.kernel.org/r/20230321052900.16895-1-quic_ppranees@quicinc.com -+--- -+ drivers/net/wireless/ath/ath11k/dbring.c | 12 ++++++------ -+ 1 file changed, 6 insertions(+), 6 deletions(-) -+ -+--- a/drivers/net/wireless/ath/ath11k/dbring.c -++++ b/drivers/net/wireless/ath/ath11k/dbring.c -+@@ -26,13 +26,13 @@ int ath11k_dbring_validate_buffer(struct -+ static void ath11k_dbring_fill_magic_value(struct ath11k *ar, -+ void *buffer, u32 size) -+ { -+- u32 *temp; -+- int idx; -++ /* memset32 function fills buffer payload with the ATH11K_DB_MAGIC_VALUE -++ * and the variable size is expected to be the number of u32 values -++ * to be stored, not the number of bytes. -++ */ -++ size = size / sizeof(u32); -+ -+- size = size >> 2; -+- -+- for (idx = 0, temp = buffer; idx < size; idx++, temp++) -+- *temp++ = ATH11K_DB_MAGIC_VALUE; -++ memset32(buffer, ATH11K_DB_MAGIC_VALUE, size); -+ } -+ -+ static int ath11k_dbring_bufs_replenish(struct ath11k *ar, -diff --git a/package/kernel/mac80211/patches/ath11k/0054-wifi-ath11k-Send-11d-scan-start-before-WMI_START_SCA.patch b/package/kernel/mac80211/patches/ath11k/0054-wifi-ath11k-Send-11d-scan-start-before-WMI_START_SCA.patch -new file mode 100644 -index 0000000000..0f8e637592 ---- /dev/null -+++ b/package/kernel/mac80211/patches/ath11k/0054-wifi-ath11k-Send-11d-scan-start-before-WMI_START_SCA.patch -@@ -0,0 +1,61 @@ -+From e89a51aedf380bc60219dc9afa96c36507060fb3 Mon Sep 17 00:00:00 2001 -+From: Manikanta Pubbisetty -+Date: Wed, 15 Mar 2023 21:48:17 +0530 -+Subject: [PATCH] wifi: ath11k: Send 11d scan start before WMI_START_SCAN_CMDID -+ -+Firmwares advertising the support of triggering 11d algorithm on the -+scan results of a regular scan expects driver to send -+WMI_11D_SCAN_START_CMDID before sending WMI_START_SCAN_CMDID. -+Triggering 11d algorithm on the scan results of a normal scan helps -+in completely avoiding a separate 11d scan for determining regdomain. -+This indirectly helps in speeding up connections on station -+interfaces on the chipsets supporting 11D scan. -+ -+To enable this feature, send WMI_11D_SCAN_START_CMDID just before -+sending WMI_START_SCAN_CMDID if the firmware advertises -+WMI_TLV_SERVICE_SUPPORT_11D_FOR_HOST_SCAN service flag. -+ -+WCN6750 & WCN6855 supports this feature. -+ -+Tested-on: WCN6750 hw1.0 AHB WLAN.MSL.1.0.1-01160-QCAMSLSWPLZ-1 -+Tested-on: WCN6855 hw2.1 PCI WLAN.HSP.1.1-03125-QCAHSPSWPL_V1_V2_SILICONZ_LITE-3.6510.23 -+ -+Signed-off-by: Manikanta Pubbisetty -+Signed-off-by: Kalle Valo -+Link: https://lore.kernel.org/r/20230315161817.29627-1-quic_mpubbise@quicinc.com -+--- -+ drivers/net/wireless/ath/ath11k/mac.c | 12 ++++++++++++ -+ drivers/net/wireless/ath/ath11k/wmi.h | 1 + -+ 2 files changed, 13 insertions(+) -+ -+--- a/drivers/net/wireless/ath/ath11k/mac.c -++++ b/drivers/net/wireless/ath/ath11k/mac.c -+@@ -3755,6 +3755,18 @@ static int ath11k_mac_op_hw_scan(struct -+ int i; -+ u32 scan_timeout; -+ -++ /* Firmwares advertising the support of triggering 11D algorithm -++ * on the scan results of a regular scan expects driver to send -++ * WMI_11D_SCAN_START_CMDID before sending WMI_START_SCAN_CMDID. -++ * With this feature, separate 11D scan can be avoided since -++ * regdomain can be determined with the scan results of the -++ * regular scan. -++ */ -++ if (ar->state_11d == ATH11K_11D_PREPARING && -++ test_bit(WMI_TLV_SERVICE_SUPPORT_11D_FOR_HOST_SCAN, -++ ar->ab->wmi_ab.svc_map)) -++ ath11k_mac_11d_scan_start(ar, arvif->vdev_id); -++ -+ mutex_lock(&ar->conf_mutex); -+ -+ spin_lock_bh(&ar->data_lock); -+--- a/drivers/net/wireless/ath/ath11k/wmi.h -++++ b/drivers/net/wireless/ath/ath11k/wmi.h -+@@ -2103,6 +2103,7 @@ enum wmi_tlv_service { -+ WMI_TLV_SERVICE_SCAN_CONFIG_PER_CHANNEL = 265, -+ WMI_TLV_SERVICE_REG_CC_EXT_EVENT_SUPPORT = 281, -+ WMI_TLV_SERVICE_BIOS_SAR_SUPPORT = 326, -++ WMI_TLV_SERVICE_SUPPORT_11D_FOR_HOST_SCAN = 357, -+ -+ /* The third 128 bits */ -+ WMI_MAX_EXT2_SERVICE = 384 -diff --git a/package/kernel/mac80211/patches/ath11k/0055-wifi-ath11k-Remove-redundant-pci_clear_master.patch b/package/kernel/mac80211/patches/ath11k/0055-wifi-ath11k-Remove-redundant-pci_clear_master.patch -new file mode 100644 -index 0000000000..0439727e72 ---- /dev/null -+++ b/package/kernel/mac80211/patches/ath11k/0055-wifi-ath11k-Remove-redundant-pci_clear_master.patch -@@ -0,0 +1,58 @@ -+From f812e2a9f85d6bea78957ccb5197e4491316848b Mon Sep 17 00:00:00 2001 -+From: Cai Huoqing -+Date: Thu, 23 Mar 2023 19:26:09 +0800 -+Subject: [PATCH] wifi: ath11k: Remove redundant pci_clear_master -+ -+Remove pci_clear_master to simplify the code, -+the bus-mastering is also cleared in do_pci_disable_device, -+like this: -+./drivers/pci/pci.c:2197 -+static void do_pci_disable_device(struct pci_dev *dev) -+{ -+ u16 pci_command; -+ -+ pci_read_config_word(dev, PCI_COMMAND, &pci_command); -+ if (pci_command & PCI_COMMAND_MASTER) { -+ pci_command &= ~PCI_COMMAND_MASTER; -+ pci_write_config_word(dev, PCI_COMMAND, pci_command); -+ } -+ -+ pcibios_disable_device(dev); -+}. -+And dev->is_busmaster is set to 0 in pci_disable_device. -+ -+Signed-off-by: Cai Huoqing -+Signed-off-by: Kalle Valo -+Link: https://lore.kernel.org/r/20230323112613.7550-1-cai.huoqing@linux.dev -+--- -+ drivers/net/wireless/ath/ath11k/pci.c | 5 +---- -+ 1 file changed, 1 insertion(+), 4 deletions(-) -+ -+--- a/drivers/net/wireless/ath/ath11k/pci.c -++++ b/drivers/net/wireless/ath/ath11k/pci.c -+@@ -540,7 +540,7 @@ static int ath11k_pci_claim(struct ath11 -+ if (!ab->mem) { -+ ath11k_err(ab, "failed to map pci bar %d\n", ATH11K_PCI_BAR_NUM); -+ ret = -EIO; -+- goto clear_master; -++ goto release_region; -+ } -+ -+ ab->mem_ce = ab->mem; -+@@ -548,8 +548,6 @@ static int ath11k_pci_claim(struct ath11 -+ ath11k_dbg(ab, ATH11K_DBG_BOOT, "boot pci_mem 0x%pK\n", ab->mem); -+ return 0; -+ -+-clear_master: -+- pci_clear_master(pdev); -+ release_region: -+ pci_release_region(pdev, ATH11K_PCI_BAR_NUM); -+ disable_device: -+@@ -565,7 +563,6 @@ static void ath11k_pci_free_region(struc -+ -+ pci_iounmap(pci_dev, ab->mem); -+ ab->mem = NULL; -+- pci_clear_master(pci_dev); -+ pci_release_region(pci_dev, ATH11K_PCI_BAR_NUM); -+ if (pci_is_enabled(pci_dev)) -+ pci_disable_device(pci_dev); -diff --git a/package/kernel/mac80211/patches/ath11k/0056-wifi-ath11k-Disable-Spectral-scan-upon-removing-inte.patch b/package/kernel/mac80211/patches/ath11k/0056-wifi-ath11k-Disable-Spectral-scan-upon-removing-inte.patch -new file mode 100644 -index 0000000000..44532a4d72 ---- /dev/null -+++ b/package/kernel/mac80211/patches/ath11k/0056-wifi-ath11k-Disable-Spectral-scan-upon-removing-inte.patch -@@ -0,0 +1,36 @@ -+From 5c690db63b45c6c4c4932b13173af71df369dba5 Mon Sep 17 00:00:00 2001 -+From: Tamizh Chelvam Raja -+Date: Tue, 28 Mar 2023 12:41:50 +0530 -+Subject: [PATCH] wifi: ath11k: Disable Spectral scan upon removing interface -+ -+Host might receive spectral events during interface -+down sequence and this might create below errors. -+ -+failed to handle dma buf release event -22 -+failed to handle dma buf release event -22 -+ -+Fix this by disabling spectral config during remove interface. -+ -+Tested-on: IPQ5018 hw1.0 AHB WLAN.HK.2.6.0.1-00861-QCAHKSWPL_SILICONZ-1 -+ -+Signed-off-by: Tamizh Chelvam Raja -+Signed-off-by: Kalle Valo -+Link: https://lore.kernel.org/r/20230328071150.29645-1-quic_tamizhr@quicinc.com -+--- -+ drivers/net/wireless/ath/ath11k/mac.c | 5 +++++ -+ 1 file changed, 5 insertions(+) -+ -+--- a/drivers/net/wireless/ath/ath11k/mac.c -++++ b/drivers/net/wireless/ath/ath11k/mac.c -+@@ -6685,6 +6685,11 @@ static void ath11k_mac_op_remove_interfa -+ ath11k_dbg(ab, ATH11K_DBG_MAC, "mac remove interface (vdev %d)\n", -+ arvif->vdev_id); -+ -++ ret = ath11k_spectral_vif_stop(arvif); -++ if (ret) -++ ath11k_warn(ab, "failed to stop spectral for vdev %i: %d\n", -++ arvif->vdev_id, ret); -++ -+ if (arvif->vdev_type == WMI_VDEV_TYPE_STA) -+ ath11k_mac_11d_scan_stop(ar); -+ -diff --git a/package/kernel/mac80211/patches/ath11k/0057-wifi-ath11k-enable-SAR-support-on-WCN6750.patch b/package/kernel/mac80211/patches/ath11k/0057-wifi-ath11k-enable-SAR-support-on-WCN6750.patch -new file mode 100644 -index 0000000000..5e64e552c1 ---- /dev/null -+++ b/package/kernel/mac80211/patches/ath11k/0057-wifi-ath11k-enable-SAR-support-on-WCN6750.patch -@@ -0,0 +1,29 @@ -+From abf57d84973ce1abcb67504ac0df8aea1fe09a76 Mon Sep 17 00:00:00 2001 -+From: Youghandhar Chintala -+Date: Tue, 28 Mar 2023 17:04:55 +0530 -+Subject: [PATCH] wifi: ath11k: enable SAR support on WCN6750 -+ -+Currently, SAR is enabled only on WCN6855, enable this for WCN6750 too. This -+functionality gets triggered, when the user space application calls -+NL80211_CMD_SET_SAR_SPECS. -+ -+Tested-on: WCN6750 hw1.0 AHB WLAN.MSL.1.0.1-00887-QCAMSLSWPLZ-1 -+ -+Signed-off-by: Youghandhar Chintala -+Signed-off-by: Kalle Valo -+Link: https://lore.kernel.org/r/20230328113455.11252-1-quic_youghand@quicinc.com -+--- -+ drivers/net/wireless/ath/ath11k/core.c | 2 +- -+ 1 file changed, 1 insertion(+), 1 deletion(-) -+ -+--- a/drivers/net/wireless/ath/ath11k/core.c -++++ b/drivers/net/wireless/ath/ath11k/core.c -+@@ -593,7 +593,7 @@ static const struct ath11k_hw_params ath -+ .current_cc_support = true, -+ .dbr_debug_support = false, -+ .global_reset = false, -+- .bios_sar_capa = NULL, -++ .bios_sar_capa = &ath11k_hw_sar_capa_wcn6855, -+ .m3_fw_support = false, -+ .fixed_bdf_addr = false, -+ .fixed_mem_region = false, -diff --git a/package/kernel/mac80211/patches/ath11k/0058-wifi-ath11k-pci-Add-more-MODULE_FIRMWARE-entries.patch b/package/kernel/mac80211/patches/ath11k/0058-wifi-ath11k-pci-Add-more-MODULE_FIRMWARE-entries.patch -new file mode 100644 -index 0000000000..585864eff2 ---- /dev/null -+++ b/package/kernel/mac80211/patches/ath11k/0058-wifi-ath11k-pci-Add-more-MODULE_FIRMWARE-entries.patch -@@ -0,0 +1,36 @@ -+From 06c58473969239e00d76b683edd511952060ca56 Mon Sep 17 00:00:00 2001 -+From: Takashi Iwai -+Date: Thu, 30 Mar 2023 16:37:18 +0200 -+Subject: [PATCH] wifi: ath11k: pci: Add more MODULE_FIRMWARE() entries -+ -+As there are a few more models supported by the driver, let's add the -+missing MODULE_FIRMWARE() entries for them. The lack of them resulted -+in the missing device enablement on some systems, such as the -+installation image of openSUSE. -+ -+While we are at it, use the wildcard instead of listing each firmware -+files individually for each. -+ -+Signed-off-by: Takashi Iwai -+Reviewed-by: Simon Horman -+Signed-off-by: Kalle Valo -+Link: https://lore.kernel.org/r/20230330143718.19511-1-tiwai@suse.de -+--- -+ drivers/net/wireless/ath/ath11k/pci.c | 9 +++++---- -+ 1 file changed, 5 insertions(+), 4 deletions(-) -+ -+--- a/drivers/net/wireless/ath/ath11k/pci.c -++++ b/drivers/net/wireless/ath/ath11k/pci.c -+@@ -1036,7 +1036,8 @@ module_exit(ath11k_pci_exit); -+ MODULE_DESCRIPTION("Driver support for Qualcomm Technologies 802.11ax WLAN PCIe devices"); -+ MODULE_LICENSE("Dual BSD/GPL"); -+ -+-/* QCA639x 2.0 firmware files */ -+-MODULE_FIRMWARE(ATH11K_FW_DIR "/QCA6390/hw2.0/" ATH11K_BOARD_API2_FILE); -+-MODULE_FIRMWARE(ATH11K_FW_DIR "/QCA6390/hw2.0/" ATH11K_AMSS_FILE); -+-MODULE_FIRMWARE(ATH11K_FW_DIR "/QCA6390/hw2.0/" ATH11K_M3_FILE); -++/* firmware files */ -++MODULE_FIRMWARE(ATH11K_FW_DIR "/QCA6390/hw2.0/*"); -++MODULE_FIRMWARE(ATH11K_FW_DIR "/QCN9074/hw1.0/*"); -++MODULE_FIRMWARE(ATH11K_FW_DIR "/WCN6855/hw2.0/*"); -++MODULE_FIRMWARE(ATH11K_FW_DIR "/WCN6855/hw2.1/*"); -diff --git a/package/kernel/mac80211/patches/ath11k/0059-wifi-ath11k-print-a-warning-when-crypto_alloc_shash-.patch b/package/kernel/mac80211/patches/ath11k/0059-wifi-ath11k-print-a-warning-when-crypto_alloc_shash-.patch -new file mode 100644 -index 0000000000..fab52a0fa7 ---- /dev/null -+++ b/package/kernel/mac80211/patches/ath11k/0059-wifi-ath11k-print-a-warning-when-crypto_alloc_shash-.patch -@@ -0,0 +1,34 @@ -+From a87a9110ac0dcbfd9458b6665c141fa1c16a669d Mon Sep 17 00:00:00 2001 -+From: Kalle Valo -+Date: Wed, 5 Apr 2023 12:04:25 +0300 -+Subject: [PATCH] wifi: ath11k: print a warning when crypto_alloc_shash() fails -+ -+Christoph reported that ath11k failed to initialise when michael_mic.ko -+module was not installed. To make it easier to notice that case print a -+warning when crypto_alloc_shash() fails. -+ -+Compile tested only. -+ -+Reported-by: Christoph Hellwig -+Link: https://lore.kernel.org/all/20221130133016.GC3055@lst.de/ -+Signed-off-by: Kalle Valo -+Link: https://lore.kernel.org/r/20230405090425.1351-1-kvalo@kernel.org -+--- -+ drivers/net/wireless/ath/ath11k/dp_rx.c | 5 ++++- -+ 1 file changed, 4 insertions(+), 1 deletion(-) -+ -+--- a/drivers/net/wireless/ath/ath11k/dp_rx.c -++++ b/drivers/net/wireless/ath/ath11k/dp_rx.c -+@@ -3106,8 +3106,11 @@ int ath11k_peer_rx_frag_setup(struct ath -+ int i; -+ -+ tfm = crypto_alloc_shash("michael_mic", 0, 0); -+- if (IS_ERR(tfm)) -++ if (IS_ERR(tfm)) { -++ ath11k_warn(ab, "failed to allocate michael_mic shash: %ld\n", -++ PTR_ERR(tfm)); -+ return PTR_ERR(tfm); -++ } -+ -+ spin_lock_bh(&ab->base_lock); -+ -diff --git a/package/kernel/mac80211/patches/ath11k/0060-wifi-ath11k-Ignore-frags-from-uninitialized-peer-in-.patch b/package/kernel/mac80211/patches/ath11k/0060-wifi-ath11k-Ignore-frags-from-uninitialized-peer-in-.patch -new file mode 100644 -index 0000000000..5bbf9e04a4 ---- /dev/null -+++ b/package/kernel/mac80211/patches/ath11k/0060-wifi-ath11k-Ignore-frags-from-uninitialized-peer-in-.patch -@@ -0,0 +1,104 @@ -+From a06bfb3c9f69f303692cdae87bc0899d2ae8b2a6 Mon Sep 17 00:00:00 2001 -+From: Harshitha Prem -+Date: Tue, 4 Apr 2023 00:11:54 +0530 -+Subject: [PATCH] wifi: ath11k: Ignore frags from uninitialized peer in dp. -+ -+When max virtual ap interfaces are configured in all the bands with -+ACS and hostapd restart is done every 60s, a crash is observed at -+random times. -+In this certain scenario, a 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. -+ -+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) -+ -+Tested-on: IPQ8074 hw2.0 AHB WLAN.HK.2.7.0.1-01744-QCAHKSWPL_SILICONZ-1 -+ -+Signed-off-by: Harshitha Prem -+Signed-off-by: Nagarajan Maran -+Signed-off-by: Kalle Valo -+Link: https://lore.kernel.org/r/20230403184155.8670-2-quic_nmaran@quicinc.com -+--- -+ drivers/net/wireless/ath/ath11k/dp.c | 4 +++- -+ drivers/net/wireless/ath/ath11k/dp_rx.c | 8 ++++++++ -+ drivers/net/wireless/ath/ath11k/peer.h | 1 + -+ 3 files changed, 12 insertions(+), 1 deletion(-) -+ -+--- a/drivers/net/wireless/ath/ath11k/dp.c -++++ b/drivers/net/wireless/ath/ath11k/dp.c -+@@ -36,6 +36,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); -+ spin_unlock_bh(&ab->base_lock); -+ } -+@@ -72,7 +73,8 @@ int ath11k_dp_peer_setup(struct ath11k * -+ ret = ath11k_peer_rx_frag_setup(ar, addr, vdev_id); -+ if (ret) { -+ ath11k_warn(ab, "failed to setup rx defrag context\n"); -+- return ret; -++ tid--; -++ goto peer_clean; -+ } -+ -+ /* TODO: Setup other peer specific resource used in data path */ -+--- a/drivers/net/wireless/ath/ath11k/dp_rx.c -++++ b/drivers/net/wireless/ath/ath11k/dp_rx.c -+@@ -3130,6 +3130,7 @@ int ath11k_peer_rx_frag_setup(struct ath -+ } -+ -+ peer->tfm_mmic = tfm; -++ peer->dp_setup_done = true; -+ spin_unlock_bh(&ab->base_lock); -+ -+ return 0; -+@@ -3575,6 +3576,13 @@ static int ath11k_dp_rx_frag_h_mpdu(stru -+ ret = -ENOENT; -+ goto out_unlock; -+ } -++ if (!peer->dp_setup_done) { -++ ath11k_warn(ab, "The peer %pM [%d] has uninitialized datapath\n", -++ peer->addr, peer_id); -++ ret = -ENOENT; -++ goto out_unlock; -++ } -++ -+ rx_tid = &peer->rx_tid[tid]; -+ -+ if ((!skb_queue_empty(&rx_tid->rx_frags) && seqno != rx_tid->cur_sn) || -+--- a/drivers/net/wireless/ath/ath11k/peer.h -++++ b/drivers/net/wireless/ath/ath11k/peer.h -+@@ -35,6 +35,7 @@ struct ath11k_peer { -+ u16 sec_type; -+ u16 sec_type_grp; -+ bool is_authorized; -++ bool dp_setup_done; -+ }; -+ -+ void ath11k_peer_unmap_event(struct ath11k_base *ab, u16 peer_id); -diff --git a/package/kernel/mac80211/patches/ath11k/0061-wifi-ath11k-fix-undefined-behavior-with-__fls-in-dp.patch b/package/kernel/mac80211/patches/ath11k/0061-wifi-ath11k-fix-undefined-behavior-with-__fls-in-dp.patch -new file mode 100644 -index 0000000000..d68c19f160 ---- /dev/null -+++ b/package/kernel/mac80211/patches/ath11k/0061-wifi-ath11k-fix-undefined-behavior-with-__fls-in-dp.patch -@@ -0,0 +1,29 @@ -+From 41e02bf4ae32cf2ac47b08b4caaa9c1a032e4ce7 Mon Sep 17 00:00:00 2001 -+From: Harshitha Prem -+Date: Tue, 4 Apr 2023 00:11:55 +0530 -+Subject: [PATCH] wifi: ath11k: fix undefined behavior with __fls in dp -+ -+"__fls" would have an undefined behavior if the argument is passed -+as "0". Hence, added changes to handle the same. -+ -+Tested-on: IPQ8074 hw2.0 AHB WLAN.HK.2.7.0.1-01744-QCAHKSWPL_SILICONZ-1 -+ -+Signed-off-by: Harshitha Prem -+Signed-off-by: Nagarajan Maran -+Signed-off-by: Kalle Valo -+Link: https://lore.kernel.org/r/20230403184155.8670-3-quic_nmaran@quicinc.com -+--- -+ drivers/net/wireless/ath/ath11k/dp_rx.c | 2 +- -+ 1 file changed, 1 insertion(+), 1 deletion(-) -+ -+--- a/drivers/net/wireless/ath/ath11k/dp_rx.c -++++ b/drivers/net/wireless/ath/ath11k/dp_rx.c -+@@ -3598,7 +3598,7 @@ static int ath11k_dp_rx_frag_h_mpdu(stru -+ goto out_unlock; -+ } -+ -+- if (frag_no > __fls(rx_tid->rx_frag_bitmap)) -++ if (!rx_tid->rx_frag_bitmap || (frag_no > __fls(rx_tid->rx_frag_bitmap))) -+ __skb_queue_tail(&rx_tid->rx_frags, msdu); -+ else -+ ath11k_dp_rx_h_sort_frags(ar, &rx_tid->rx_frags, msdu); -diff --git a/package/kernel/mac80211/patches/ath11k/0062-wifi-ath11k-fix-double-free-of-peer-rx_tid-during-re.patch b/package/kernel/mac80211/patches/ath11k/0062-wifi-ath11k-fix-double-free-of-peer-rx_tid-during-re.patch -new file mode 100644 -index 0000000000..dd37b1e4fa ---- /dev/null -+++ b/package/kernel/mac80211/patches/ath11k/0062-wifi-ath11k-fix-double-free-of-peer-rx_tid-during-re.patch -@@ -0,0 +1,144 @@ -+From 93a91f40c25c3d0e61f8540a7accf105090f9995 Mon Sep 17 00:00:00 2001 -+From: Harshitha Prem -+Date: Mon, 17 Apr 2023 13:35:00 +0300 -+Subject: [PATCH] wifi: 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. -+ -+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: Sathishkumar Muruganandam -+Signed-off-by: Harshitha Prem -+Signed-off-by: Kalle Valo -+Link: https://lore.kernel.org/r/20230403182420.23375-2-quic_hprem@quicinc.com -+--- -+ drivers/net/wireless/ath/ath11k/dp_rx.c | 43 ++++++++++++++++++------- -+ 1 file changed, 31 insertions(+), 12 deletions(-) -+ -+--- a/drivers/net/wireless/ath/ath11k/dp_rx.c -++++ b/drivers/net/wireless/ath/ath11k/dp_rx.c -+@@ -668,13 +668,18 @@ void ath11k_dp_reo_cmd_list_cleanup(stru -+ struct ath11k_dp *dp = &ab->dp; -+ struct dp_reo_cmd *cmd, *tmp; -+ struct dp_reo_cache_flush_elem *cmd_cache, *tmp_cache; -++ struct dp_rx_tid *rx_tid; -+ -+ spin_lock_bh(&dp->reo_cmd_lock); -+ list_for_each_entry_safe(cmd, tmp, &dp->reo_cmd_list, list) { -+ list_del(&cmd->list); -+- dma_unmap_single(ab->dev, cmd->data.paddr, -+- cmd->data.size, DMA_BIDIRECTIONAL); -+- kfree(cmd->data.vaddr); -++ rx_tid = &cmd->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); -+ } -+ -+@@ -682,9 +687,13 @@ void ath11k_dp_reo_cmd_list_cleanup(stru -+ &dp->reo_cmd_cache_flush_list, list) { -+ list_del(&cmd_cache->list); -+ dp->reo_cmd_cache_flush_count--; -+- dma_unmap_single(ab->dev, cmd_cache->data.paddr, -+- cmd_cache->data.size, DMA_BIDIRECTIONAL); -+- kfree(cmd_cache->data.vaddr); -++ rx_tid = &cmd_cache->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_cache); -+ } -+ spin_unlock_bh(&dp->reo_cmd_lock); -+@@ -698,10 +707,12 @@ static void ath11k_dp_reo_cmd_free(struc -+ if (status != HAL_REO_CMD_SUCCESS) -+ ath11k_warn(dp->ab, "failed to flush rx tid hw desc, tid %d status %d\n", -+ rx_tid->tid, status); -+- -+- dma_unmap_single(dp->ab->dev, rx_tid->paddr, rx_tid->size, -+- DMA_BIDIRECTIONAL); -+- kfree(rx_tid->vaddr); -++ if (rx_tid->vaddr) { -++ dma_unmap_single(dp->ab->dev, rx_tid->paddr, rx_tid->size, -++ DMA_BIDIRECTIONAL); -++ kfree(rx_tid->vaddr); -++ rx_tid->vaddr = NULL; -++ } -+ } -+ -+ static void ath11k_dp_reo_cache_flush(struct ath11k_base *ab, -+@@ -740,6 +751,7 @@ static void ath11k_dp_reo_cache_flush(st -+ dma_unmap_single(ab->dev, rx_tid->paddr, rx_tid->size, -+ DMA_BIDIRECTIONAL); -+ kfree(rx_tid->vaddr); -++ rx_tid->vaddr = NULL; -+ } -+ } -+ -+@@ -792,6 +804,7 @@ free_desc: -+ dma_unmap_single(ab->dev, rx_tid->paddr, rx_tid->size, -+ DMA_BIDIRECTIONAL); -+ kfree(rx_tid->vaddr); -++ rx_tid->vaddr = NULL; -+ } -+ -+ void ath11k_peer_rx_tid_delete(struct ath11k *ar, -+@@ -804,6 +817,8 @@ void ath11k_peer_rx_tid_delete(struct at -+ if (!rx_tid->active) -+ return; -+ -++ 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); -+@@ -818,9 +833,11 @@ void ath11k_peer_rx_tid_delete(struct at -+ dma_unmap_single(ar->ab->dev, rx_tid->paddr, rx_tid->size, -+ DMA_BIDIRECTIONAL); -+ kfree(rx_tid->vaddr); -++ rx_tid->vaddr = NULL; -+ } -+ -+- rx_tid->active = false; -++ rx_tid->paddr = 0; -++ rx_tid->size = 0; -+ } -+ -+ static int ath11k_dp_rx_link_desc_return(struct ath11k_base *ab, -+@@ -967,6 +984,7 @@ static void ath11k_dp_rx_tid_mem_free(st -+ dma_unmap_single(ab->dev, rx_tid->paddr, rx_tid->size, -+ DMA_BIDIRECTIONAL); -+ kfree(rx_tid->vaddr); -++ rx_tid->vaddr = NULL; -+ -+ rx_tid->active = false; -+ -+@@ -1067,7 +1085,8 @@ int ath11k_peer_rx_tid_setup(struct ath1 -+ return ret; -+ -+ err_mem_free: -+- kfree(vaddr); -++ kfree(rx_tid->vaddr); -++ rx_tid->vaddr = NULL; -+ -+ return ret; -+ } -diff --git a/package/kernel/mac80211/patches/ath11k/0063-wifi-ath11k-Prevent-REO-cmd-failures.patch b/package/kernel/mac80211/patches/ath11k/0063-wifi-ath11k-Prevent-REO-cmd-failures.patch -new file mode 100644 -index 0000000000..4b9af18062 ---- /dev/null -+++ b/package/kernel/mac80211/patches/ath11k/0063-wifi-ath11k-Prevent-REO-cmd-failures.patch -@@ -0,0 +1,43 @@ -+From a8ae833657a45746debde85c38bb7f070d344026 Mon Sep 17 00:00:00 2001 -+From: Harshitha Prem -+Date: Mon, 17 Apr 2023 13:35:01 +0300 -+Subject: [PATCH] wifi: ath11k: Prevent REO cmd failures -+ -+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. -+ -+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: Sathishkumar Muruganandam -+Signed-off-by: Harshitha Prem -+Signed-off-by: Kalle Valo -+Link: https://lore.kernel.org/r/20230403182420.23375-3-quic_hprem@quicinc.com -+--- -+ drivers/net/wireless/ath/ath11k/dp.h | 2 +- -+ drivers/net/wireless/ath/ath11k/hw.c | 1 + -+ 2 files changed, 2 insertions(+), 1 deletion(-) -+ -+--- a/drivers/net/wireless/ath/ath11k/dp.h -++++ b/drivers/net/wireless/ath/ath11k/dp.h -+@@ -214,7 +214,7 @@ struct ath11k_pdev_dp { -+ #define DP_REO_REINJECT_RING_SIZE 32 -+ #define DP_RX_RELEASE_RING_SIZE 1024 -+ #define DP_REO_EXCEPTION_RING_SIZE 128 -+-#define DP_REO_CMD_RING_SIZE 128 -++#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 -+--- a/drivers/net/wireless/ath/ath11k/hw.c -++++ b/drivers/net/wireless/ath/ath11k/hw.c -+@@ -1233,6 +1233,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/0064-wifi-ath11k-add-peer-mac-information-in-failure-case.patch b/package/kernel/mac80211/patches/ath11k/0064-wifi-ath11k-add-peer-mac-information-in-failure-case.patch -new file mode 100644 -index 0000000000..fbcbdfff71 ---- /dev/null -+++ b/package/kernel/mac80211/patches/ath11k/0064-wifi-ath11k-add-peer-mac-information-in-failure-case.patch -@@ -0,0 +1,74 @@ -+From 20487cc3ff36bbfa9505f0a078ba98f09abfc717 Mon Sep 17 00:00:00 2001 -+From: Harshitha Prem -+Date: Mon, 17 Apr 2023 13:35:01 +0300 -+Subject: [PATCH] wifi: ath11k: add peer mac information in failure cases -+ -+During reo command failure, the peer mac detail for which the reo -+command was not successful is unknown. Hence, to improve the -+debuggability, add the peer mac information in the failure cases -+which would be useful during multi client cases. -+ -+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: Sathishkumar Muruganandam -+Signed-off-by: Harshitha Prem -+Signed-off-by: Kalle Valo -+Link: https://lore.kernel.org/r/20230403182420.23375-4-quic_hprem@quicinc.com -+--- -+ drivers/net/wireless/ath/ath11k/dp_rx.c | 16 ++++++++++------ -+ 1 file changed, 10 insertions(+), 6 deletions(-) -+ -+--- a/drivers/net/wireless/ath/ath11k/dp_rx.c -++++ b/drivers/net/wireless/ath/ath11k/dp_rx.c -+@@ -1009,7 +1009,8 @@ int ath11k_peer_rx_tid_setup(struct ath1 -+ -+ peer = ath11k_peer_find(ab, vdev_id, peer_mac); -+ if (!peer) { -+- ath11k_warn(ab, "failed to find the peer to set up rx tid\n"); -++ ath11k_warn(ab, "failed to find the peer %pM to set up rx tid\n", -++ peer_mac); -+ spin_unlock_bh(&ab->base_lock); -+ return -ENOENT; -+ } -+@@ -1022,7 +1023,8 @@ int ath11k_peer_rx_tid_setup(struct ath1 -+ ba_win_sz, ssn, true); -+ spin_unlock_bh(&ab->base_lock); -+ if (ret) { -+- ath11k_warn(ab, "failed to update reo for rx tid %d\n", tid); -++ ath11k_warn(ab, "failed to update reo for peer %pM rx tid %d\n: %d", -++ peer_mac, tid, ret); -+ return ret; -+ } -+ -+@@ -1030,8 +1032,8 @@ int ath11k_peer_rx_tid_setup(struct ath1 -+ peer_mac, paddr, -+ tid, 1, ba_win_sz); -+ if (ret) -+- ath11k_warn(ab, "failed to send wmi command to update rx reorder queue, tid :%d (%d)\n", -+- tid, ret); -++ ath11k_warn(ab, "failed to send wmi rx reorder queue for peer %pM tid %d: %d\n", -++ peer_mac, tid, ret); -+ return ret; -+ } -+ -+@@ -1064,6 +1066,8 @@ int ath11k_peer_rx_tid_setup(struct ath1 -+ ret = dma_mapping_error(ab->dev, paddr); -+ if (ret) { -+ spin_unlock_bh(&ab->base_lock); -++ ath11k_warn(ab, "failed to setup dma map for peer %pM rx tid %d: %d\n", -++ peer_mac, tid, ret); -+ goto err_mem_free; -+ } -+ -+@@ -1077,8 +1081,8 @@ int ath11k_peer_rx_tid_setup(struct ath1 -+ ret = ath11k_wmi_peer_rx_reorder_queue_setup(ar, vdev_id, peer_mac, -+ paddr, tid, 1, ba_win_sz); -+ if (ret) { -+- ath11k_warn(ar->ab, "failed to setup rx reorder queue, tid :%d (%d)\n", -+- tid, ret); -++ ath11k_warn(ar->ab, "failed to setup rx reorder queue for peer %pM tid %d: %d\n", -++ peer_mac, tid, ret); -+ ath11k_dp_rx_tid_mem_free(ab, peer_mac, vdev_id, tid); -+ } -+ -diff --git a/package/kernel/mac80211/patches/ath11k/0065-wifi-ath11k-fix-tx-status-reporting-in-encap-offload.patch b/package/kernel/mac80211/patches/ath11k/0065-wifi-ath11k-fix-tx-status-reporting-in-encap-offload.patch -new file mode 100644 -index 0000000000..e2fe419158 ---- /dev/null -+++ b/package/kernel/mac80211/patches/ath11k/0065-wifi-ath11k-fix-tx-status-reporting-in-encap-offload.patch -@@ -0,0 +1,119 @@ -+From 6257c702264c44d74c6b71f0c62a7665da2dc356 Mon Sep 17 00:00:00 2001 -+From: Pradeep Kumar Chitrapu -+Date: Mon, 17 Apr 2023 13:35:02 +0300 -+Subject: [PATCH] wifi: ath11k: fix tx status reporting in encap offload mode -+ -+ieee80211_tx_status() treats packets in 802.11 frame format and -+tries to extract sta address from packet header. When tx encap -+offload is enabled, this becomes invalid operation. Hence, switch -+to using ieee80211_tx_status_ext() after filling in station -+address for handling both 802.11 and 802.3 frames. -+ -+Tested-on: QCN9074 hw1.0 PCI WLAN.HK.2.7.0.1-01744-QCAHKSWPL_SILICONZ-1 -+ -+Signed-off-by: Pradeep Kumar Chitrapu -+Signed-off-by: Kalle Valo -+Link: https://lore.kernel.org/r/20230403195738.25367-2-quic_pradeepc@quicinc.com -+--- -+ drivers/net/wireless/ath/ath11k/dp.h | 4 +++ -+ drivers/net/wireless/ath/ath11k/dp_tx.c | 33 ++++++++++++++++++++++++- -+ drivers/net/wireless/ath/ath11k/dp_tx.h | 1 + -+ 3 files changed, 37 insertions(+), 1 deletion(-) -+ -+--- a/drivers/net/wireless/ath/ath11k/dp.h -++++ b/drivers/net/wireless/ath/ath11k/dp.h -+@@ -303,12 +303,16 @@ struct ath11k_dp { -+ -+ #define HTT_TX_WBM_COMP_STATUS_OFFSET 8 -+ -++#define HTT_INVALID_PEER_ID 0xffff -++ -+ /* HTT tx completion is overlaid in wbm_release_ring */ -+ #define HTT_TX_WBM_COMP_INFO0_STATUS GENMASK(12, 9) -+ #define HTT_TX_WBM_COMP_INFO0_REINJECT_REASON GENMASK(16, 13) -+ #define HTT_TX_WBM_COMP_INFO0_REINJECT_REASON GENMASK(16, 13) -+ -+ #define HTT_TX_WBM_COMP_INFO1_ACK_RSSI GENMASK(31, 24) -++#define HTT_TX_WBM_COMP_INFO2_SW_PEER_ID GENMASK(15, 0) -++#define HTT_TX_WBM_COMP_INFO2_VALID BIT(21) -+ -+ struct htt_tx_wbm_completion { -+ u32 info0; -+--- a/drivers/net/wireless/ath/ath11k/dp_tx.c -++++ b/drivers/net/wireless/ath/ath11k/dp_tx.c -+@@ -316,10 +316,12 @@ ath11k_dp_tx_htt_tx_complete_buf(struct -+ struct dp_tx_ring *tx_ring, -+ struct ath11k_dp_htt_wbm_tx_status *ts) -+ { -++ struct ieee80211_tx_status status = { 0 }; -+ struct sk_buff *msdu; -+ struct ieee80211_tx_info *info; -+ struct ath11k_skb_cb *skb_cb; -+ struct ath11k *ar; -++ struct ath11k_peer *peer; -+ -+ spin_lock(&tx_ring->tx_idr_lock); -+ msdu = idr_remove(&tx_ring->txbuf_idr, ts->msdu_id); -+@@ -341,6 +343,11 @@ ath11k_dp_tx_htt_tx_complete_buf(struct -+ -+ dma_unmap_single(ab->dev, skb_cb->paddr, msdu->len, DMA_TO_DEVICE); -+ -++ if (!skb_cb->vif) { -++ dev_kfree_skb_any(msdu); -++ return; -++ } -++ -+ memset(&info->status, 0, sizeof(info->status)); -+ -+ if (ts->acked) { -+@@ -355,7 +362,23 @@ ath11k_dp_tx_htt_tx_complete_buf(struct -+ } -+ } -+ -+- ieee80211_tx_status(ar->hw, msdu); -++ spin_lock_bh(&ab->base_lock); -++ peer = ath11k_peer_find_by_id(ab, ts->peer_id); -++ if (!peer || !peer->sta) { -++ ath11k_dbg(ab, ATH11K_DBG_DATA, -++ "dp_tx: failed to find the peer with peer_id %d\n", -++ ts->peer_id); -++ spin_unlock_bh(&ab->base_lock); -++ dev_kfree_skb_any(msdu); -++ return; -++ } -++ spin_unlock_bh(&ab->base_lock); -++ -++ status.sta = peer->sta; -++ status.info = info; -++ status.skb = msdu; -++ -++ ieee80211_tx_status_ext(ar->hw, &status); -+ } -+ -+ static void -+@@ -379,7 +402,15 @@ ath11k_dp_tx_process_htt_tx_complete(str -+ ts.msdu_id = msdu_id; -+ ts.ack_rssi = FIELD_GET(HTT_TX_WBM_COMP_INFO1_ACK_RSSI, -+ status_desc->info1); -++ -++ if (FIELD_GET(HTT_TX_WBM_COMP_INFO2_VALID, status_desc->info2)) -++ ts.peer_id = FIELD_GET(HTT_TX_WBM_COMP_INFO2_SW_PEER_ID, -++ status_desc->info2); -++ else -++ ts.peer_id = HTT_INVALID_PEER_ID; -++ -+ ath11k_dp_tx_htt_tx_complete_buf(ab, tx_ring, &ts); -++ -+ break; -+ case HAL_WBM_REL_HTT_TX_COMP_STATUS_REINJ: -+ case HAL_WBM_REL_HTT_TX_COMP_STATUS_INSPECT: -+--- a/drivers/net/wireless/ath/ath11k/dp_tx.h -++++ b/drivers/net/wireless/ath/ath11k/dp_tx.h -+@@ -13,6 +13,7 @@ struct ath11k_dp_htt_wbm_tx_status { -+ u32 msdu_id; -+ bool acked; -+ int ack_rssi; -++ u16 peer_id; -+ }; -+ -+ void ath11k_dp_tx_update_txcompl(struct ath11k *ar, struct hal_tx_status *ts); -diff --git a/package/kernel/mac80211/patches/ath11k/0066-wifi-ath11k-Fix-incorrect-update-of-radiotap-fields.patch b/package/kernel/mac80211/patches/ath11k/0066-wifi-ath11k-Fix-incorrect-update-of-radiotap-fields.patch -new file mode 100644 -index 0000000000..4f94580100 ---- /dev/null -+++ b/package/kernel/mac80211/patches/ath11k/0066-wifi-ath11k-Fix-incorrect-update-of-radiotap-fields.patch -@@ -0,0 +1,49 @@ -+From 2f0c9ac8362da09c80f1cd422ef7fd6fa9b252b9 Mon Sep 17 00:00:00 2001 -+From: Pradeep Kumar Chitrapu -+Date: Mon, 17 Apr 2023 13:35:02 +0300 -+Subject: [PATCH] wifi: ath11k: Fix incorrect update of radiotap fields -+ -+Fix incorrect update of ppdu stats causing incorrect radiotap -+fields. -+ -+Tested-on: QCN9074 hw1.0 PCI WLAN.HK.2.7.0.1-01744-QCAHKSWPL_SILICONZ-1 -+ -+Signed-off-by: Pradeep Kumar Chitrapu -+Signed-off-by: Kalle Valo -+Link: https://lore.kernel.org/r/20230403195738.25367-3-quic_pradeepc@quicinc.com -+--- -+ drivers/net/wireless/ath/ath11k/hal_rx.c | 4 ++-- -+ drivers/net/wireless/ath/ath11k/hal_rx.h | 2 +- -+ 2 files changed, 3 insertions(+), 3 deletions(-) -+ -+--- a/drivers/net/wireless/ath/ath11k/hal_rx.c -++++ b/drivers/net/wireless/ath/ath11k/hal_rx.c -+@@ -1029,7 +1029,7 @@ ath11k_hal_rx_parse_mon_status_tlv(struc -+ info1 = __le32_to_cpu(vht_sig->info1); -+ -+ ppdu_info->ldpc = FIELD_GET(HAL_RX_VHT_SIG_A_INFO_INFO1_SU_MU_CODING, -+- info0); -++ info1); -+ ppdu_info->mcs = FIELD_GET(HAL_RX_VHT_SIG_A_INFO_INFO1_MCS, -+ info1); -+ gi_setting = FIELD_GET(HAL_RX_VHT_SIG_A_INFO_INFO1_GI_SETTING, -+@@ -1452,7 +1452,7 @@ ath11k_hal_rx_parse_mon_status_tlv(struc -+ * PHYRX_OTHER_RECEIVE_INFO TLV. -+ */ -+ ppdu_info->rssi_comb = -+- FIELD_GET(HAL_RX_PHYRX_RSSI_LEGACY_INFO_INFO1_RSSI_COMB, -++ FIELD_GET(HAL_RX_PHYRX_RSSI_LEGACY_INFO_INFO0_RSSI_COMB, -+ __le32_to_cpu(rssi->info0)); -+ -+ if (db2dbm) { -+--- a/drivers/net/wireless/ath/ath11k/hal_rx.h -++++ b/drivers/net/wireless/ath/ath11k/hal_rx.h -+@@ -385,7 +385,7 @@ struct hal_rx_he_sig_b2_ofdma_info { -+ __le32 info0; -+ } __packed; -+ -+-#define HAL_RX_PHYRX_RSSI_LEGACY_INFO_INFO1_RSSI_COMB GENMASK(15, 8) -++#define HAL_RX_PHYRX_RSSI_LEGACY_INFO_INFO0_RSSI_COMB GENMASK(15, 8) -+ -+ #define HAL_RX_PHYRX_RSSI_PREAMBLE_PRI20 GENMASK(7, 0) -+ -diff --git a/package/kernel/mac80211/patches/ath11k/0067-wifi-ath11k-Fix-SKB-corruption-in-REO-destination-ri.patch b/package/kernel/mac80211/patches/ath11k/0067-wifi-ath11k-Fix-SKB-corruption-in-REO-destination-ri.patch -new file mode 100644 -index 0000000000..8b300f3a79 ---- /dev/null -+++ b/package/kernel/mac80211/patches/ath11k/0067-wifi-ath11k-Fix-SKB-corruption-in-REO-destination-ri.patch -@@ -0,0 +1,70 @@ -+From f9fff67d2d7ca6fa8066132003a3deef654c55b1 Mon Sep 17 00:00:00 2001 -+From: Nagarajan Maran -+Date: Mon, 17 Apr 2023 13:35:02 +0300 -+Subject: [PATCH] wifi: ath11k: Fix SKB corruption in REO destination ring -+ -+While running traffics for a long time, randomly an RX descriptor -+filled with value "0" from REO destination ring is received. -+This descriptor which is invalid causes the wrong SKB (SKB stored in -+the IDR lookup with buffer id "0") to be fetched which in turn -+causes SKB memory corruption issue and the same leads to crash -+after some time. -+ -+Changed the start id for idr allocation to "1" and the buffer id "0" -+is reserved for error validation. Introduced Sanity check to validate -+the descriptor, before processing the SKB. -+ -+Crash Signature : -+ -+Unable to handle kernel paging request at virtual address 3f004900 -+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) -+ -+Tested-on: IPQ8074 hw2.0 AHB WLAN.HK.2.7.0.1-01744-QCAHKSWPL_SILICONZ-1 -+ -+Signed-off-by: Nagarajan Maran -+Signed-off-by: Kalle Valo -+Link: https://lore.kernel.org/r/20230403191533.28114-1-quic_nmaran@quicinc.com -+--- -+ drivers/net/wireless/ath/ath11k/dp_rx.c | 9 ++++++--- -+ 1 file changed, 6 insertions(+), 3 deletions(-) -+ -+--- a/drivers/net/wireless/ath/ath11k/dp_rx.c -++++ b/drivers/net/wireless/ath/ath11k/dp_rx.c -+@@ -389,10 +389,10 @@ 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, 0, -+- rx_ring->bufs_max * 3, 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) -++ if (buf_id <= 0) -+ goto fail_dma_unmap; -+ -+ desc = ath11k_hal_srng_src_get_next_entry(ab, srng); -+@@ -2665,6 +2665,9 @@ try_again: -+ cookie); -+ mac_id = FIELD_GET(DP_RXDMA_BUF_COOKIE_PDEV_ID, cookie); -+ -++ if (unlikely(buf_id == 0)) -++ continue; -++ -+ ar = ab->pdevs[mac_id].ar; -+ rx_ring = &ar->dp.rx_refill_buf_ring; -+ spin_lock_bh(&rx_ring->idr_lock); -diff --git a/package/kernel/mac80211/patches/ath11k/0068-wifi-ath11k-Remove-disabling-of-80-80-and-160-MHz.patch b/package/kernel/mac80211/patches/ath11k/0068-wifi-ath11k-Remove-disabling-of-80-80-and-160-MHz.patch -new file mode 100644 -index 0000000000..ce5ffd273b ---- /dev/null -+++ b/package/kernel/mac80211/patches/ath11k/0068-wifi-ath11k-Remove-disabling-of-80-80-and-160-MHz.patch -@@ -0,0 +1,49 @@ -+From b100722a777f6455d913666a376f81342b2cb995 Mon Sep 17 00:00:00 2001 -+From: Muna Sinada -+Date: Mon, 17 Apr 2023 13:22:27 -0700 -+Subject: [PATCH] wifi: ath11k: Remove disabling of 80+80 and 160 MHz -+ -+This is a regression fix for 80+80 and 160 MHz support bits being -+cleared, therefore not adverised. Remove disable of 80+80 and 160 MHz -+capability flags and assign valid center frequency 2 similar to -+VHT80_80. -+ -+Fixes: 38dfe775d0ab ("wifi: ath11k: push MU-MIMO params from hostapd to hardware") -+Reported-by: Robert Marko -+Tested-by: Robert Marko # IPQ8074 WLAN.HK.2.9.0.1-01385-QCAHKSWPL_SILICONZ-1 -+Link: https://bugzilla.kernel.org/show_bug.cgi?id=217299 -+Co-developed-by: P Praneesh -+Signed-off-by: P Praneesh -+Signed-off-by: Muna Sinada -+Signed-off-by: Kalle Valo -+Link: https://lore.kernel.org/r/1681762947-13882-1-git-send-email-quic_msinada@quicinc.com -+--- -+ drivers/net/wireless/ath/ath11k/mac.c | 4 ---- -+ drivers/net/wireless/ath/ath11k/wmi.c | 3 ++- -+ 2 files changed, 2 insertions(+), 5 deletions(-) -+ -+--- a/drivers/net/wireless/ath/ath11k/mac.c -++++ b/drivers/net/wireless/ath/ath11k/mac.c -+@@ -5585,10 +5585,6 @@ static int ath11k_mac_copy_he_cap(struct -+ -+ he_cap_elem->mac_cap_info[1] &= -+ IEEE80211_HE_MAC_CAP1_TF_MAC_PAD_DUR_MASK; -+- he_cap_elem->phy_cap_info[0] &= -+- ~IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_160MHZ_IN_5G; -+- he_cap_elem->phy_cap_info[0] &= -+- ~IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_80PLUS80_MHZ_IN_5G; -+ -+ he_cap_elem->phy_cap_info[5] &= -+ ~IEEE80211_HE_PHY_CAP5_BEAMFORMEE_NUM_SND_DIM_UNDER_80MHZ_MASK; -+--- a/drivers/net/wireless/ath/ath11k/wmi.c -++++ b/drivers/net/wireless/ath/ath11k/wmi.c -+@@ -871,7 +871,8 @@ static void ath11k_wmi_put_wmi_channel(s -+ -+ chan->band_center_freq2 = arg->channel.band_center_freq1; -+ -+- } else if (arg->channel.mode == MODE_11AC_VHT80_80) { -++ } else if ((arg->channel.mode == MODE_11AC_VHT80_80) || -++ (arg->channel.mode == MODE_11AX_HE80_80)) { -+ chan->band_center_freq2 = arg->channel.band_center_freq2; -+ } else { -+ chan->band_center_freq2 = 0; -diff --git a/package/kernel/mac80211/patches/ath11k/0069-wifi-ath11k-fix-registration-of-6Ghz-only-phy-withou.patch b/package/kernel/mac80211/patches/ath11k/0069-wifi-ath11k-fix-registration-of-6Ghz-only-phy-withou.patch -new file mode 100644 -index 0000000000..32468dbc4c ---- /dev/null -+++ b/package/kernel/mac80211/patches/ath11k/0069-wifi-ath11k-fix-registration-of-6Ghz-only-phy-withou.patch -@@ -0,0 +1,61 @@ -+From e2ceb1de2f83aafd8003f0b72dfd4b7441e97d14 Mon Sep 17 00:00:00 2001 -+From: Maxime Bizon -+Date: Fri, 21 Apr 2023 16:54:45 +0200 -+Subject: [PATCH] wifi: ath11k: fix registration of 6Ghz-only phy without the -+ full channel range -+ -+Because of what seems to be a typo, a 6Ghz-only phy for which the BDF -+does not allow the 7115Mhz channel will fail to register: -+ -+ WARNING: CPU: 2 PID: 106 at net/wireless/core.c:907 wiphy_register+0x914/0x954 -+ Modules linked in: ath11k_pci sbsa_gwdt -+ CPU: 2 PID: 106 Comm: kworker/u8:5 Not tainted 6.3.0-rc7-next-20230418-00549-g1e096a17625a-dirty #9 -+ Hardware name: Freebox V7R Board (DT) -+ Workqueue: ath11k_qmi_driver_event ath11k_qmi_driver_event_work -+ pstate: 60000005 (nZCv daif -PAN -UAO -TCO -DIT -SSBS BTYPE=--) -+ pc : wiphy_register+0x914/0x954 -+ lr : ieee80211_register_hw+0x67c/0xc10 -+ sp : ffffff800b123aa0 -+ x29: ffffff800b123aa0 x28: 0000000000000000 x27: 0000000000000000 -+ x26: 0000000000000000 x25: 0000000000000006 x24: ffffffc008d51418 -+ x23: ffffffc008cb0838 x22: ffffff80176c2460 x21: 0000000000000168 -+ x20: ffffff80176c0000 x19: ffffff80176c03e0 x18: 0000000000000014 -+ x17: 00000000cbef338c x16: 00000000d2a26f21 x15: 00000000ad6bb85f -+ x14: 0000000000000020 x13: 0000000000000020 x12: 00000000ffffffbd -+ x11: 0000000000000208 x10: 00000000fffffdf7 x9 : ffffffc009394718 -+ x8 : ffffff80176c0528 x7 : 000000007fffffff x6 : 0000000000000006 -+ x5 : 0000000000000005 x4 : ffffff800b304284 x3 : ffffff800b304284 -+ x2 : ffffff800b304d98 x1 : 0000000000000000 x0 : 0000000000000000 -+ Call trace: -+ wiphy_register+0x914/0x954 -+ ieee80211_register_hw+0x67c/0xc10 -+ ath11k_mac_register+0x7c4/0xe10 -+ ath11k_core_qmi_firmware_ready+0x1f4/0x570 -+ ath11k_qmi_driver_event_work+0x198/0x590 -+ process_one_work+0x1b8/0x328 -+ worker_thread+0x6c/0x414 -+ kthread+0x100/0x104 -+ ret_from_fork+0x10/0x20 -+ ---[ end trace 0000000000000000 ]--- -+ ath11k_pci 0002:01:00.0: ieee80211 registration failed: -22 -+ ath11k_pci 0002:01:00.0: failed register the radio with mac80211: -22 -+ ath11k_pci 0002:01:00.0: failed to create pdev core: -22 -+ -+Signed-off-by: Maxime Bizon -+Signed-off-by: Kalle Valo -+Link: https://lore.kernel.org/r/20230421145445.2612280-1-mbizon@freebox.fr -+--- -+ drivers/net/wireless/ath/ath11k/mac.c | 2 +- -+ 1 file changed, 1 insertion(+), 1 deletion(-) -+ -+--- a/drivers/net/wireless/ath/ath11k/mac.c -++++ b/drivers/net/wireless/ath/ath11k/mac.c -+@@ -8892,7 +8892,7 @@ static int ath11k_mac_setup_channels_rat -+ } -+ -+ if (supported_bands & WMI_HOST_WLAN_5G_CAP) { -+- if (reg_cap->high_5ghz_chan >= ATH11K_MAX_6G_FREQ) { -++ if (reg_cap->high_5ghz_chan >= ATH11K_MIN_6G_FREQ) { -+ channels = kmemdup(ath11k_6ghz_channels, -+ sizeof(ath11k_6ghz_channels), GFP_KERNEL); -+ if (!channels) { -diff --git a/package/kernel/mac80211/patches/ath11k/0070-wifi-ath-work-around-false-positive-stringop-overrea.patch b/package/kernel/mac80211/patches/ath11k/0070-wifi-ath-work-around-false-positive-stringop-overrea.patch -new file mode 100644 -index 0000000000..aa4df16a90 ---- /dev/null -+++ b/package/kernel/mac80211/patches/ath11k/0070-wifi-ath-work-around-false-positive-stringop-overrea.patch -@@ -0,0 +1,84 @@ -+From 695df2f417d25202bdac9cde3c82d2acb6492b4d Mon Sep 17 00:00:00 2001 -+From: Arnd Bergmann -+Date: Fri, 5 May 2023 16:11:25 +0300 -+Subject: [PATCH] wifi: ath: work around false-positive stringop-overread -+ warning -+ -+In a rare arm64 randconfig build, I got multiple warnings for ath11k -+and ath12k: -+ -+In function 'ath11k_peer_assoc_h_ht', -+ inlined from 'ath11k_peer_assoc_prepare' at drivers/net/wireless/ath/ath11k/mac.c:2665:2: -+drivers/net/wireless/ath/ath11k/mac.c:1709:13: error: 'ath11k_peer_assoc_h_ht_masked' reading 10 bytes from a region of size 0 [-Werror=stringop-overread] -+ 1709 | if (ath11k_peer_assoc_h_ht_masked(ht_mcs_mask)) -+ | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -+ -+This happens whenever gcc-13 fails to inline one of the functions -+that take a fixed-length array argument but gets passed a pointer. -+ -+Change these functions to all take a regular pointer argument -+instead. -+ -+Signed-off-by: Arnd Bergmann -+Signed-off-by: Kalle Valo -+Link: https://lore.kernel.org/r/20230417205447.1800912-1-arnd@kernel.org -+--- -+ drivers/net/wireless/ath/ath11k/mac.c | 12 ++++++------ -+ 1 file changed, 6 insertions(+), 6 deletions(-) -+ -+--- a/drivers/net/wireless/ath/ath11k/mac.c -++++ b/drivers/net/wireless/ath/ath11k/mac.c -+@@ -433,7 +433,7 @@ u8 ath11k_mac_bitrate_to_idx(const struc -+ } -+ -+ static u32 -+-ath11k_mac_max_ht_nss(const u8 ht_mcs_mask[IEEE80211_HT_MCS_MASK_LEN]) -++ath11k_mac_max_ht_nss(const u8 *ht_mcs_mask) -+ { -+ int nss; -+ -+@@ -445,7 +445,7 @@ ath11k_mac_max_ht_nss(const u8 ht_mcs_ma -+ } -+ -+ static u32 -+-ath11k_mac_max_vht_nss(const u16 vht_mcs_mask[NL80211_VHT_NSS_MAX]) -++ath11k_mac_max_vht_nss(const u16 *vht_mcs_mask) -+ { -+ int nss; -+ -+@@ -457,7 +457,7 @@ ath11k_mac_max_vht_nss(const u16 vht_mcs -+ } -+ -+ static u32 -+-ath11k_mac_max_he_nss(const u16 he_mcs_mask[NL80211_HE_NSS_MAX]) -++ath11k_mac_max_he_nss(const u16 *he_mcs_mask) -+ { -+ int nss; -+ -+@@ -1658,7 +1658,7 @@ static void ath11k_peer_assoc_h_rates(st -+ } -+ -+ static bool -+-ath11k_peer_assoc_h_ht_masked(const u8 ht_mcs_mask[IEEE80211_HT_MCS_MASK_LEN]) -++ath11k_peer_assoc_h_ht_masked(const u8 *ht_mcs_mask) -+ { -+ int nss; -+ -+@@ -1670,7 +1670,7 @@ ath11k_peer_assoc_h_ht_masked(const u8 h -+ } -+ -+ static bool -+-ath11k_peer_assoc_h_vht_masked(const u16 vht_mcs_mask[]) -++ath11k_peer_assoc_h_vht_masked(const u16 *vht_mcs_mask) -+ { -+ int nss; -+ -+@@ -2065,7 +2065,7 @@ static u16 ath11k_peer_assoc_h_he_limit( -+ } -+ -+ static bool -+-ath11k_peer_assoc_h_he_masked(const u16 he_mcs_mask[NL80211_HE_NSS_MAX]) -++ath11k_peer_assoc_h_he_masked(const u16 *he_mcs_mask) -+ { -+ int nss; -+ -diff --git a/package/kernel/mac80211/patches/ath11k/0071-wifi-ath11k-driver-settings-for-MBSSID-and-EMA.patch b/package/kernel/mac80211/patches/ath11k/0071-wifi-ath11k-driver-settings-for-MBSSID-and-EMA.patch -new file mode 100644 -index 0000000000..bede4819ca ---- /dev/null -+++ b/package/kernel/mac80211/patches/ath11k/0071-wifi-ath11k-driver-settings-for-MBSSID-and-EMA.patch -@@ -0,0 +1,133 @@ -+From a08dbb04d7365a04d52882143cf196005bfc88c3 Mon Sep 17 00:00:00 2001 -+From: Aloka Dixit -+Date: Fri, 5 May 2023 16:11:27 +0300 -+Subject: [PATCH 71/77] wifi: ath11k: driver settings for MBSSID and EMA -+ -+Advertise the driver support for multiple BSSID (MBSSID) and -+enhanced multi-BSSID advertisements (EMA) by setting extended -+capabilities. -+ -+Configure mbssid_max_interfaces and ema_max_profile_periodicity -+fields in structure wiphy which are used to advertise maximum number -+of interfaces and profile periodicity supported by the driver. -+ -+Add new WMI fields to configure maximum vdev count supported for -+MBSSID and profile periodicity in case of EMA. -+Setting WMI_RSRC_CFG_FLAG2_CALC_NEXT_DTIM_COUNT_SET flag -+indicates that the firmware should track and update the DTIM counts -+for each non-transmitted profile. -+ -+Tested-on: IPQ8074 hw2.0 AHB WLAN.HK.2.7.0.1-01744-QCAHKSWPL_SILICONZ-1 -+ -+Signed-off-by: Aloka Dixit -+Co-developed-by: John Crispin -+Signed-off-by: John Crispin -+Signed-off-by: Kalle Valo -+Link: https://lore.kernel.org/r/20230405221648.17950-2-quic_alokad@quicinc.com -+--- -+ drivers/net/wireless/ath/ath11k/hw.c | 3 +++ -+ drivers/net/wireless/ath/ath11k/hw.h | 1 + -+ drivers/net/wireless/ath/ath11k/mac.c | 7 +++++++ -+ drivers/net/wireless/ath/ath11k/wmi.c | 3 +++ -+ drivers/net/wireless/ath/ath11k/wmi.h | 6 ++++++ -+ 5 files changed, 20 insertions(+) -+ -+--- a/drivers/net/wireless/ath/ath11k/hw.c -++++ b/drivers/net/wireless/ath/ath11k/hw.c -+@@ -202,6 +202,9 @@ static void ath11k_init_wmi_config_ipq80 -+ config->twt_ap_sta_count = 1000; -+ config->flag1 |= WMI_RSRC_CFG_FLAG1_BSS_CHANNEL_INFO_64; -+ config->flag1 |= WMI_RSRC_CFG_FLAG1_ACK_RSSI; -++ config->ema_max_vap_cnt = ab->num_radios; -++ config->ema_max_profile_period = TARGET_EMA_MAX_PROFILE_PERIOD; -++ config->beacon_tx_offload_max_vdev += config->ema_max_vap_cnt; -+ } -+ -+ static int ath11k_hw_mac_id_to_pdev_id_ipq8074(struct ath11k_hw_params *hw, -+--- a/drivers/net/wireless/ath/ath11k/hw.h -++++ b/drivers/net/wireless/ath/ath11k/hw.h -+@@ -64,6 +64,7 @@ -+ #define TARGET_NUM_WDS_ENTRIES 32 -+ #define TARGET_DMA_BURST_SIZE 1 -+ #define TARGET_RX_BATCHMODE 1 -++#define TARGET_EMA_MAX_PROFILE_PERIOD 8 -+ -+ #define ATH11K_HW_MAX_QUEUES 4 -+ #define ATH11K_QUEUE_LEN 4096 -+--- a/drivers/net/wireless/ath/ath11k/mac.c -++++ b/drivers/net/wireless/ath/ath11k/mac.c -+@@ -9001,19 +9001,23 @@ static int ath11k_mac_setup_iface_combin -+ -+ static const u8 ath11k_if_types_ext_capa[] = { -+ [0] = WLAN_EXT_CAPA1_EXT_CHANNEL_SWITCHING, -++ [2] = WLAN_EXT_CAPA3_MULTI_BSSID_SUPPORT, -+ [7] = WLAN_EXT_CAPA8_OPMODE_NOTIF, -+ }; -+ -+ static const u8 ath11k_if_types_ext_capa_sta[] = { -+ [0] = WLAN_EXT_CAPA1_EXT_CHANNEL_SWITCHING, -++ [2] = WLAN_EXT_CAPA3_MULTI_BSSID_SUPPORT, -+ [7] = WLAN_EXT_CAPA8_OPMODE_NOTIF, -+ [9] = WLAN_EXT_CAPA10_TWT_REQUESTER_SUPPORT, -+ }; -+ -+ static const u8 ath11k_if_types_ext_capa_ap[] = { -+ [0] = WLAN_EXT_CAPA1_EXT_CHANNEL_SWITCHING, -++ [2] = WLAN_EXT_CAPA3_MULTI_BSSID_SUPPORT, -+ [7] = WLAN_EXT_CAPA8_OPMODE_NOTIF, -+ [9] = WLAN_EXT_CAPA10_TWT_RESPONDER_SUPPORT, -++ [10] = WLAN_EXT_CAPA11_EMA_SUPPORT, -+ }; -+ -+ static const struct wiphy_iftype_ext_capab ath11k_iftypes_ext_capa[] = { -+@@ -9251,6 +9255,9 @@ static int __ath11k_mac_register(struct -+ wiphy_ext_feature_set(ar->hw->wiphy, -+ NL80211_EXT_FEATURE_ENABLE_FTM_RESPONDER); -+ -++ ar->hw->wiphy->mbssid_max_interfaces = TARGET_NUM_VDEVS(ab); -++ ar->hw->wiphy->ema_max_profile_periodicity = TARGET_EMA_MAX_PROFILE_PERIOD; -++ -+ ath11k_reg_init(ar); -+ -+ if (!test_bit(ATH11K_FLAG_RAW_MODE, &ab->dev_flags)) { -+--- a/drivers/net/wireless/ath/ath11k/wmi.c -++++ b/drivers/net/wireless/ath/ath11k/wmi.c -+@@ -3987,6 +3987,9 @@ ath11k_wmi_copy_resource_config(struct w -+ ~(1 << WMI_CFG_HOST_SERVICE_FLAG_REG_CC_EXT); -+ wmi_cfg->host_service_flags |= (tg_cfg->is_reg_cc_ext_event_supported << -+ WMI_CFG_HOST_SERVICE_FLAG_REG_CC_EXT); -++ 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; -+ } -+ -+ static int ath11k_init_cmd_send(struct ath11k_pdev_wmi *wmi, -+--- a/drivers/net/wireless/ath/ath11k/wmi.h -++++ b/drivers/net/wireless/ath/ath11k/wmi.h -+@@ -2317,6 +2317,7 @@ struct wmi_init_cmd { -+ } __packed; -+ -+ #define WMI_RSRC_CFG_FLAG1_BSS_CHANNEL_INFO_64 BIT(5) -++#define WMI_RSRC_CFG_FLAG2_CALC_NEXT_DTIM_COUNT_SET BIT(9) -+ #define WMI_RSRC_CFG_FLAG1_ACK_RSSI BIT(18) -+ -+ #define WMI_CFG_HOST_SERVICE_FLAG_REG_CC_EXT 4 -+@@ -2389,6 +2390,9 @@ struct wmi_resource_config { -+ u32 msdu_flow_override_config1; -+ u32 flags2; -+ u32 host_service_flags; -++ u32 max_rnr_neighbours; -++ u32 ema_max_vap_cnt; -++ u32 ema_max_profile_period; -+ } __packed; -+ -+ struct wmi_service_ready_event { -+@@ -5646,6 +5650,8 @@ struct target_resource_config { -+ u32 twt_ap_pdev_count; -+ u32 twt_ap_sta_count; -+ u8 is_reg_cc_ext_event_supported; -++ u32 ema_max_vap_cnt; -++ u32 ema_max_profile_period; -+ }; -+ -+ enum wmi_debug_log_param { -diff --git a/package/kernel/mac80211/patches/ath11k/0072-wifi-ath11k-MBSSID-configuration-during-vdev-create-.patch b/package/kernel/mac80211/patches/ath11k/0072-wifi-ath11k-MBSSID-configuration-during-vdev-create-.patch -new file mode 100644 -index 0000000000..4ba0717319 ---- /dev/null -+++ b/package/kernel/mac80211/patches/ath11k/0072-wifi-ath11k-MBSSID-configuration-during-vdev-create-.patch -@@ -0,0 +1,215 @@ -+From 5a81610acf66c4ad6e1a1fbd09f3f555fca863b1 Mon Sep 17 00:00:00 2001 -+From: Aloka Dixit -+Date: Fri, 5 May 2023 16:11:27 +0300 -+Subject: [PATCH 72/77] wifi: ath11k: MBSSID configuration during vdev -+ create/start -+ -+Configure multiple BSSID flags and index of the transmitting interface -+in vdev create/start commands depending on the service bit -+WMI_TLV_SERVICE_MBSS_PARAM_IN_VDEV_START_SUPPORT. -+ -+Tested-on: IPQ8074 hw2.0 AHB WLAN.HK.2.7.0.1-01744-QCAHKSWPL_SILICONZ-1 -+ -+Signed-off-by: Aloka Dixit -+Co-developed-by: John Crispin -+Signed-off-by: John Crispin -+Signed-off-by: Kalle Valo -+Link: https://lore.kernel.org/r/20230405221648.17950-3-quic_alokad@quicinc.com -+--- -+ drivers/net/wireless/ath/ath11k/mac.c | 70 +++++++++++++++++++++++++-- -+ drivers/net/wireless/ath/ath11k/wmi.c | 5 ++ -+ drivers/net/wireless/ath/ath11k/wmi.h | 19 ++++++++ -+ 3 files changed, 90 insertions(+), 4 deletions(-) -+ -+--- a/drivers/net/wireless/ath/ath11k/mac.c -++++ b/drivers/net/wireless/ath/ath11k/mac.c -+@@ -6181,17 +6181,62 @@ static void ath11k_mac_op_stop(struct ie -+ atomic_set(&ar->num_pending_mgmt_tx, 0); -+ } -+ -+-static void -+-ath11k_mac_setup_vdev_create_params(struct ath11k_vif *arvif, -+- struct vdev_create_params *params) -++static int ath11k_mac_setup_vdev_params_mbssid(struct ath11k_vif *arvif, -++ u32 *flags, u32 *tx_vdev_id) -++{ -++ struct ath11k *ar = arvif->ar; -++ struct ath11k_vif *tx_arvif; -++ struct ieee80211_vif *tx_vif; -++ -++ *tx_vdev_id = 0; -++ tx_vif = arvif->vif->mbssid_tx_vif; -++ if (!tx_vif) { -++ *flags = WMI_HOST_VDEV_FLAGS_NON_MBSSID_AP; -++ return 0; -++ } -++ -++ tx_arvif = (void *)tx_vif->drv_priv; -++ -++ if (arvif->vif->bss_conf.nontransmitted) { -++ if (ar->hw->wiphy != ieee80211_vif_to_wdev(tx_vif)->wiphy) -++ return -EINVAL; -++ -++ *flags = WMI_HOST_VDEV_FLAGS_NON_TRANSMIT_AP; -++ *tx_vdev_id = ath11k_vif_to_arvif(tx_vif)->vdev_id; -++ } else if (tx_arvif == arvif) { -++ *flags = WMI_HOST_VDEV_FLAGS_TRANSMIT_AP; -++ } else { -++ return -EINVAL; -++ } -++ -++ if (arvif->vif->bss_conf.ema_ap) -++ *flags |= WMI_HOST_VDEV_FLAGS_EMA_MODE; -++ -++ return 0; -++} -++ -++static int ath11k_mac_setup_vdev_create_params(struct ath11k_vif *arvif, -++ struct vdev_create_params *params) -+ { -+ struct ath11k *ar = arvif->ar; -+ struct ath11k_pdev *pdev = ar->pdev; -++ int ret; -+ -+ params->if_id = arvif->vdev_id; -+ params->type = arvif->vdev_type; -+ params->subtype = arvif->vdev_subtype; -+ params->pdev_id = pdev->pdev_id; -++ params->mbssid_flags = 0; -++ params->mbssid_tx_vdev_id = 0; -++ -++ if (!test_bit(WMI_TLV_SERVICE_MBSS_PARAM_IN_VDEV_START_SUPPORT, -++ ar->ab->wmi_ab.svc_map)) { -++ ret = ath11k_mac_setup_vdev_params_mbssid(arvif, -++ ¶ms->mbssid_flags, -++ ¶ms->mbssid_tx_vdev_id); -++ if (ret) -++ return ret; -++ } -+ -+ if (pdev->cap.supported_bands & WMI_HOST_WLAN_2G_CAP) { -+ params->chains[NL80211_BAND_2GHZ].tx = ar->num_tx_chains; -+@@ -6206,6 +6251,7 @@ ath11k_mac_setup_vdev_create_params(stru -+ params->chains[NL80211_BAND_6GHZ].tx = ar->num_tx_chains; -+ params->chains[NL80211_BAND_6GHZ].rx = ar->num_rx_chains; -+ } -++ return 0; -+ } -+ -+ static void ath11k_mac_op_update_vif_offload(struct ieee80211_hw *hw, -+@@ -6500,7 +6546,12 @@ static int ath11k_mac_op_add_interface(s -+ for (i = 0; i < ARRAY_SIZE(vif->hw_queue); i++) -+ vif->hw_queue[i] = i % (ATH11K_HW_MAX_QUEUES - 1); -+ -+- ath11k_mac_setup_vdev_create_params(arvif, &vdev_param); -++ ret = ath11k_mac_setup_vdev_create_params(arvif, &vdev_param); -++ if (ret) { -++ ath11k_warn(ab, "failed to create vdev parameters %d: %d\n", -++ arvif->vdev_id, ret); -++ goto err; -++ } -+ -+ ret = ath11k_wmi_vdev_create(ar, vif->addr, &vdev_param); -+ if (ret) { -+@@ -6905,6 +6956,17 @@ ath11k_mac_vdev_start_restart(struct ath -+ arg.pref_tx_streams = ar->num_tx_chains; -+ arg.pref_rx_streams = ar->num_rx_chains; -+ -++ arg.mbssid_flags = 0; -++ arg.mbssid_tx_vdev_id = 0; -++ if (test_bit(WMI_TLV_SERVICE_MBSS_PARAM_IN_VDEV_START_SUPPORT, -++ ar->ab->wmi_ab.svc_map)) { -++ ret = ath11k_mac_setup_vdev_params_mbssid(arvif, -++ &arg.mbssid_flags, -++ &arg.mbssid_tx_vdev_id); -++ if (ret) -++ return ret; -++ } -++ -+ if (arvif->vdev_type == WMI_VDEV_TYPE_AP) { -+ arg.ssid = arvif->u.ap.ssid; -+ arg.ssid_len = arvif->u.ap.ssid_len; -+--- a/drivers/net/wireless/ath/ath11k/wmi.c -++++ b/drivers/net/wireless/ath/ath11k/wmi.c -+@@ -724,6 +724,9 @@ int ath11k_wmi_vdev_create(struct ath11k -+ cmd->vdev_subtype = param->subtype; -+ cmd->num_cfg_txrx_streams = WMI_NUM_SUPPORTED_BAND_MAX; -+ cmd->pdev_id = param->pdev_id; -++ cmd->mbssid_flags = param->mbssid_flags; -++ cmd->mbssid_tx_vdev_id = param->mbssid_tx_vdev_id; -++ -+ ether_addr_copy(cmd->vdev_macaddr.addr, macaddr); -+ -+ ptr = skb->data + sizeof(*cmd); -+@@ -941,6 +944,8 @@ int ath11k_wmi_vdev_start(struct ath11k -+ cmd->cac_duration_ms = arg->cac_duration_ms; -+ cmd->regdomain = arg->regdomain; -+ cmd->he_ops = arg->he_ops; -++ cmd->mbssid_flags = arg->mbssid_flags; -++ cmd->mbssid_tx_vdev_id = arg->mbssid_tx_vdev_id; -+ -+ if (!restart) { -+ if (arg->ssid) { -+--- a/drivers/net/wireless/ath/ath11k/wmi.h -++++ b/drivers/net/wireless/ath/ath11k/wmi.h -+@@ -137,6 +137,14 @@ enum { -+ WMI_AUTORATE_3200NS_GI = BIT(11), -+ }; -+ -++enum { -++ WMI_HOST_VDEV_FLAGS_NON_MBSSID_AP = 0x00000001, -++ WMI_HOST_VDEV_FLAGS_TRANSMIT_AP = 0x00000002, -++ WMI_HOST_VDEV_FLAGS_NON_TRANSMIT_AP = 0x00000004, -++ WMI_HOST_VDEV_FLAGS_EMA_MODE = 0x00000008, -++ WMI_HOST_VDEV_FLAGS_SCAN_MODE_VAP = 0x00000010, -++}; -++ -+ /* -+ * wmi command groups. -+ */ -+@@ -2096,6 +2104,7 @@ enum wmi_tlv_service { -+ WMI_TLV_SERVICE_EXT2_MSG = 220, -+ 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_PASSIVE_SCAN_START_TIME_ENHANCE = 263, -+ -+ /* The second 128 bits */ -+@@ -2583,6 +2592,8 @@ struct vdev_create_params { -+ u8 rx; -+ } chains[NUM_NL80211_BANDS]; -+ u32 pdev_id; -++ u32 mbssid_flags; -++ u32 mbssid_tx_vdev_id; -+ }; -+ -+ struct wmi_vdev_create_cmd { -+@@ -2593,6 +2604,8 @@ struct wmi_vdev_create_cmd { -+ struct wmi_mac_addr vdev_macaddr; -+ u32 num_cfg_txrx_streams; -+ u32 pdev_id; -++ u32 mbssid_flags; -++ u32 mbssid_tx_vdev_id; -+ } __packed; -+ -+ struct wmi_vdev_txrx_streams { -+@@ -2656,6 +2669,9 @@ struct wmi_vdev_start_request_cmd { -+ u32 he_ops; -+ u32 cac_duration_ms; -+ u32 regdomain; -++ u32 min_data_rate; -++ u32 mbssid_flags; -++ u32 mbssid_tx_vdev_id; -+ } __packed; -+ -+ #define MGMT_TX_DL_FRM_LEN 64 -+@@ -2825,6 +2841,9 @@ struct wmi_vdev_start_req_arg { -+ u32 pref_rx_streams; -+ u32 pref_tx_streams; -+ u32 num_noa_descriptors; -++ u32 min_data_rate; -++ u32 mbssid_flags; -++ u32 mbssid_tx_vdev_id; -+ }; -+ -+ struct peer_create_params { -diff --git a/package/kernel/mac80211/patches/ath11k/0073-wifi-ath11k-rename-MBSSID-fields-in-wmi_vdev_up_cmd.patch b/package/kernel/mac80211/patches/ath11k/0073-wifi-ath11k-rename-MBSSID-fields-in-wmi_vdev_up_cmd.patch -new file mode 100644 -index 0000000000..023a1dbb9f ---- /dev/null -+++ b/package/kernel/mac80211/patches/ath11k/0073-wifi-ath11k-rename-MBSSID-fields-in-wmi_vdev_up_cmd.patch -@@ -0,0 +1,52 @@ -+From cf604e72bc6e6db68c7fcaa8779b03ec14b8d2fa Mon Sep 17 00:00:00 2001 -+From: Aloka Dixit -+Date: Fri, 5 May 2023 16:11:27 +0300 -+Subject: [PATCH 73/77] wifi: ath11k: rename MBSSID fields in wmi_vdev_up_cmd -+ -+Rename trans_bssid to tx_vdev_bssid to make it similar to vdev_bssid. -+ -+Rename profile_num to nontx_profile_cnt, and profile_idx to -+nontx_profile_idx which makes it clear that these store configurations -+related to MBSSID non-transmitting profiles. -+ -+Tested-on: IPQ8074 hw2.0 AHB WLAN.HK.2.7.0.1-01744-QCAHKSWPL_SILICONZ-1 -+ -+Signed-off-by: Aloka Dixit -+Signed-off-by: Kalle Valo -+Link: https://lore.kernel.org/r/20230405221648.17950-4-quic_alokad@quicinc.com -+--- -+ drivers/net/wireless/ath/ath11k/wmi.c | 6 +++--- -+ drivers/net/wireless/ath/ath11k/wmi.h | 6 +++--- -+ 2 files changed, 6 insertions(+), 6 deletions(-) -+ -+--- a/drivers/net/wireless/ath/ath11k/wmi.c -++++ b/drivers/net/wireless/ath/ath11k/wmi.c -+@@ -1029,10 +1029,10 @@ int ath11k_wmi_vdev_up(struct ath11k *ar -+ bss_conf = &arvif->vif->bss_conf; -+ -+ if (bss_conf->nontransmitted) { -+- ether_addr_copy(cmd->trans_bssid.addr, -++ ether_addr_copy(cmd->tx_vdev_bssid.addr, -+ bss_conf->transmitter_bssid); -+- cmd->profile_idx = bss_conf->bssid_index; -+- cmd->profile_num = bss_conf->bssid_indicator; -++ cmd->nontx_profile_idx = bss_conf->bssid_index; -++ cmd->nontx_profile_cnt = bss_conf->bssid_indicator; -+ } -+ } -+ -+--- a/drivers/net/wireless/ath/ath11k/wmi.h -++++ b/drivers/net/wireless/ath/ath11k/wmi.h -+@@ -2625,9 +2625,9 @@ struct wmi_vdev_up_cmd { -+ u32 vdev_id; -+ u32 vdev_assoc_id; -+ struct wmi_mac_addr vdev_bssid; -+- struct wmi_mac_addr trans_bssid; -+- u32 profile_idx; -+- u32 profile_num; -++ struct wmi_mac_addr tx_vdev_bssid; -++ u32 nontx_profile_idx; -++ u32 nontx_profile_cnt; -+ } __packed; -+ -+ struct wmi_vdev_stop_cmd { -diff --git a/package/kernel/mac80211/patches/ath11k/0074-wifi-ath11k-MBSSID-parameter-configuration-in-AP-mod.patch b/package/kernel/mac80211/patches/ath11k/0074-wifi-ath11k-MBSSID-parameter-configuration-in-AP-mod.patch -new file mode 100644 -index 0000000000..d93e27dd42 ---- /dev/null -+++ b/package/kernel/mac80211/patches/ath11k/0074-wifi-ath11k-MBSSID-parameter-configuration-in-AP-mod.patch -@@ -0,0 +1,138 @@ -+From c82dc33f252fd8883be66f2d0230af0fd734c683 Mon Sep 17 00:00:00 2001 -+From: Aloka Dixit -+Date: Fri, 5 May 2023 16:11:27 +0300 -+Subject: [PATCH 74/77] wifi: ath11k: MBSSID parameter configuration in AP mode -+ -+Include MBSSID parameters in WMI vdev up operation. -+ -+Tested-on: IPQ8074 hw2.0 AHB WLAN.HK.2.7.0.1-01744-QCAHKSWPL_SILICONZ-1 -+ -+Signed-off-by: Aloka Dixit -+Co-developed-by: John Crispin -+Signed-off-by: John Crispin -+Signed-off-by: Kalle Valo -+Link: https://lore.kernel.org/r/20230405221648.17950-5-quic_alokad@quicinc.com -+--- -+ drivers/net/wireless/ath/ath11k/mac.c | 29 +++++++++++++++++++++------ -+ drivers/net/wireless/ath/ath11k/wmi.c | 8 +++++++- -+ drivers/net/wireless/ath/ath11k/wmi.h | 3 ++- -+ 3 files changed, 32 insertions(+), 8 deletions(-) -+ -+--- a/drivers/net/wireless/ath/ath11k/mac.c -++++ b/drivers/net/wireless/ath/ath11k/mac.c -+@@ -964,7 +964,7 @@ static int ath11k_mac_monitor_vdev_start -+ return ret; -+ } -+ -+- ret = ath11k_wmi_vdev_up(ar, vdev_id, 0, ar->mac_addr); -++ ret = ath11k_wmi_vdev_up(ar, vdev_id, 0, ar->mac_addr, NULL, 0, 0); -+ if (ret) { -+ ath11k_warn(ar->ab, "failed to put up monitor vdev %i: %d\n", -+ vdev_id, ret); -+@@ -1423,6 +1423,7 @@ static void ath11k_control_beaconing(str -+ struct ieee80211_bss_conf *info) -+ { -+ struct ath11k *ar = arvif->ar; -++ struct ath11k_vif *tx_arvif = NULL; -+ int ret = 0; -+ -+ lockdep_assert_held(&arvif->ar->conf_mutex); -+@@ -1451,8 +1452,14 @@ static void ath11k_control_beaconing(str -+ -+ ether_addr_copy(arvif->bssid, info->bssid); -+ -++ if (arvif->vif->mbssid_tx_vif) -++ tx_arvif = (struct ath11k_vif *)arvif->vif->mbssid_tx_vif->drv_priv; -++ -+ ret = ath11k_wmi_vdev_up(arvif->ar, arvif->vdev_id, arvif->aid, -+- arvif->bssid); -++ arvif->bssid, -++ tx_arvif ? tx_arvif->bssid : NULL, -++ info->bssid_index, -++ 1 << info->bssid_indicator); -+ if (ret) { -+ ath11k_warn(ar->ab, "failed to bring up vdev %d: %i\n", -+ arvif->vdev_id, ret); -+@@ -2879,7 +2886,8 @@ static void ath11k_bss_assoc(struct ieee -+ arvif->aid = vif->cfg.aid; -+ ether_addr_copy(arvif->bssid, bss_conf->bssid); -+ -+- ret = ath11k_wmi_vdev_up(ar, arvif->vdev_id, arvif->aid, arvif->bssid); -++ ret = ath11k_wmi_vdev_up(ar, arvif->vdev_id, arvif->aid, arvif->bssid, -++ NULL, 0, 0); -+ if (ret) { -+ ath11k_warn(ar->ab, "failed to set vdev %d up: %d\n", -+ arvif->vdev_id, ret); -+@@ -7133,7 +7141,8 @@ ath11k_mac_update_vif_chan(struct ath11k -+ int n_vifs) -+ { -+ struct ath11k_base *ab = ar->ab; -+- struct ath11k_vif *arvif; -++ struct ath11k_vif *arvif, *tx_arvif = NULL; -++ struct ieee80211_vif *mbssid_tx_vif; -+ int ret; -+ int i; -+ bool monitor_vif = false; -+@@ -7187,8 +7196,15 @@ ath11k_mac_update_vif_chan(struct ath11k -+ ath11k_warn(ab, "failed to update bcn tmpl during csa: %d\n", -+ ret); -+ -++ mbssid_tx_vif = arvif->vif->mbssid_tx_vif; -++ if (mbssid_tx_vif) -++ tx_arvif = (struct ath11k_vif *)mbssid_tx_vif->drv_priv; -++ -+ ret = ath11k_wmi_vdev_up(arvif->ar, arvif->vdev_id, arvif->aid, -+- arvif->bssid); -++ arvif->bssid, -++ tx_arvif ? tx_arvif->bssid : NULL, -++ arvif->vif->bss_conf.bssid_index, -++ 1 << arvif->vif->bss_conf.bssid_indicator); -+ if (ret) { -+ ath11k_warn(ab, "failed to bring vdev up %d: %d\n", -+ arvif->vdev_id, ret); -+@@ -7306,7 +7322,8 @@ static int ath11k_start_vdev_delay(struc -+ } -+ -+ if (arvif->vdev_type == WMI_VDEV_TYPE_MONITOR) { -+- ret = ath11k_wmi_vdev_up(ar, arvif->vdev_id, 0, ar->mac_addr); -++ ret = ath11k_wmi_vdev_up(ar, arvif->vdev_id, 0, ar->mac_addr, -++ NULL, 0, 0); -+ if (ret) { -+ ath11k_warn(ab, "failed put monitor up: %d\n", ret); -+ return ret; -+--- a/drivers/net/wireless/ath/ath11k/wmi.c -++++ b/drivers/net/wireless/ath/ath11k/wmi.c -+@@ -1001,7 +1001,8 @@ int ath11k_wmi_vdev_start(struct ath11k -+ return ret; -+ } -+ -+-int ath11k_wmi_vdev_up(struct ath11k *ar, u32 vdev_id, u32 aid, const u8 *bssid) -++int ath11k_wmi_vdev_up(struct ath11k *ar, u32 vdev_id, u32 aid, const u8 *bssid, -++ u8 *tx_bssid, u32 nontx_profile_idx, u32 nontx_profile_cnt) -+ { -+ struct ath11k_pdev_wmi *wmi = ar->wmi; -+ struct wmi_vdev_up_cmd *cmd; -+@@ -1025,6 +1026,11 @@ int ath11k_wmi_vdev_up(struct ath11k *ar -+ -+ ether_addr_copy(cmd->vdev_bssid.addr, bssid); -+ -++ cmd->nontx_profile_idx = nontx_profile_idx; -++ cmd->nontx_profile_cnt = nontx_profile_cnt; -++ if (tx_bssid) -++ ether_addr_copy(cmd->tx_vdev_bssid.addr, tx_bssid); -++ -+ if (arvif && arvif->vif->type == NL80211_IFTYPE_STATION) { -+ bss_conf = &arvif->vif->bss_conf; -+ -+--- a/drivers/net/wireless/ath/ath11k/wmi.h -++++ b/drivers/net/wireless/ath/ath11k/wmi.h -+@@ -6301,7 +6301,8 @@ int ath11k_wmi_bcn_tmpl(struct ath11k *a -+ struct sk_buff *bcn); -+ int ath11k_wmi_vdev_down(struct ath11k *ar, u8 vdev_id); -+ int ath11k_wmi_vdev_up(struct ath11k *ar, u32 vdev_id, u32 aid, -+- const u8 *bssid); -++ const u8 *bssid, u8 *tx_bssid, u32 nontx_profile_idx, -++ u32 nontx_profile_cnt); -+ int ath11k_wmi_vdev_stop(struct ath11k *ar, u8 vdev_id); -+ int ath11k_wmi_vdev_start(struct ath11k *ar, struct wmi_vdev_start_req_arg *arg, -+ bool restart); -diff --git a/package/kernel/mac80211/patches/ath11k/0075-wifi-ath11k-refactor-vif-parameter-configurations.patch b/package/kernel/mac80211/patches/ath11k/0075-wifi-ath11k-refactor-vif-parameter-configurations.patch -new file mode 100644 -index 0000000000..8509e55978 ---- /dev/null -+++ b/package/kernel/mac80211/patches/ath11k/0075-wifi-ath11k-refactor-vif-parameter-configurations.patch -@@ -0,0 +1,86 @@ -+From cb9bea773c85e372931cd7a177db4165adf29d95 Mon Sep 17 00:00:00 2001 -+From: Aloka Dixit -+Date: Fri, 5 May 2023 16:11:28 +0300 -+Subject: [PATCH 75/77] wifi: ath11k: refactor vif parameter configurations -+ -+Security parameters for each non-transmitting profile can be -+different when MBSSID is enabled and this information is included -+in the MBSSID element in the Beacon frame. Current implementation -+to set rsnie_present and wpaie_present does not parse this element -+hence it applies only to the transmitting interface. -+ -+Move the code to a separate function to make additions for -+non-transmitting interfaces cleaner. -+ -+Tested-on: IPQ8074 hw2.0 AHB WLAN.HK.2.7.0.1-01744-QCAHKSWPL_SILICONZ-1 -+ -+Signed-off-by: Aloka Dixit -+Signed-off-by: Kalle Valo -+Link: https://lore.kernel.org/r/20230405221648.17950-6-quic_alokad@quicinc.com -+--- -+ drivers/net/wireless/ath/ath11k/mac.c | 41 ++++++++++++++++----------- -+ 1 file changed, 24 insertions(+), 17 deletions(-) -+ -+--- a/drivers/net/wireless/ath/ath11k/mac.c -++++ b/drivers/net/wireless/ath/ath11k/mac.c -+@@ -1351,28 +1351,14 @@ err_mon_del: -+ return ret; -+ } -+ -+-static int ath11k_mac_setup_bcn_tmpl(struct ath11k_vif *arvif) -++static void ath11k_mac_set_vif_params(struct ath11k_vif *arvif, -++ struct sk_buff *bcn) -+ { -+- struct ath11k *ar = arvif->ar; -+- struct ath11k_base *ab = ar->ab; -+- struct ieee80211_hw *hw = ar->hw; -+- struct ieee80211_vif *vif = arvif->vif; -+- struct ieee80211_mutable_offsets offs = {}; -+- struct sk_buff *bcn; -+ struct ieee80211_mgmt *mgmt; -+ u8 *ies; -+- int ret; -+- -+- if (arvif->vdev_type != WMI_VDEV_TYPE_AP) -+- return 0; -+- -+- bcn = ieee80211_beacon_get_template(hw, vif, &offs, 0); -+- if (!bcn) { -+- ath11k_warn(ab, "failed to get beacon template from mac80211\n"); -+- return -EPERM; -+- } -+ -+ ies = bcn->data + ieee80211_get_hdrlen_from_skb(bcn); -++ mgmt = (struct ieee80211_mgmt *)bcn->data; -+ ies += sizeof(mgmt->u.beacon); -+ -+ if (cfg80211_find_ie(WLAN_EID_RSN, ies, (skb_tail_pointer(bcn) - ies))) -+@@ -1386,7 +1372,28 @@ static int ath11k_mac_setup_bcn_tmpl(str -+ arvif->wpaie_present = true; -+ else -+ arvif->wpaie_present = false; -++} -++ -++static int ath11k_mac_setup_bcn_tmpl(struct ath11k_vif *arvif) -++{ -++ struct ath11k *ar = arvif->ar; -++ struct ath11k_base *ab = ar->ab; -++ struct ieee80211_hw *hw = ar->hw; -++ struct ieee80211_vif *vif = arvif->vif; -++ struct ieee80211_mutable_offsets offs = {}; -++ struct sk_buff *bcn; -++ int ret; -++ -++ if (arvif->vdev_type != WMI_VDEV_TYPE_AP) -++ return 0; -++ -++ bcn = ieee80211_beacon_get_template(hw, vif, &offs, 0); -++ if (!bcn) { -++ ath11k_warn(ab, "failed to get beacon template from mac80211\n"); -++ return -EPERM; -++ } -+ -++ ath11k_mac_set_vif_params(arvif, bcn); -+ ret = ath11k_wmi_bcn_tmpl(ar, arvif->vdev_id, &offs, bcn); -+ -+ kfree_skb(bcn); -diff --git a/package/kernel/mac80211/patches/ath11k/0076-wifi-ath11k-MBSSID-beacon-support.patch b/package/kernel/mac80211/patches/ath11k/0076-wifi-ath11k-MBSSID-beacon-support.patch -new file mode 100644 -index 0000000000..d23ea8deea ---- /dev/null -+++ b/package/kernel/mac80211/patches/ath11k/0076-wifi-ath11k-MBSSID-beacon-support.patch -@@ -0,0 +1,190 @@ -+From 335a92765d308dfe22826f5562cd4b4389b45e71 Mon Sep 17 00:00:00 2001 -+From: Aloka Dixit -+Date: Fri, 5 May 2023 16:11:28 +0300 -+Subject: [PATCH 76/77] wifi: ath11k: MBSSID beacon support -+ -+- Split ath11k_mac_setup_bcn_tmpl() to move the beacon retrieval and -+ WMI command to a new function, ath11k_mac_setup_bcn_tmpl_legacy(). -+ In the original function add checks to use the transmitting interface -+ when MBSSID is enabled. -+- Set rsnie_present and wpaie_present fields for the non-transmitting -+ interfaces when MBSSID is enabled. -+ -+Tested-on: IPQ8074 hw2.0 AHB WLAN.HK.2.7.0.1-01744-QCAHKSWPL_SILICONZ-1 -+ -+Signed-off-by: Aloka Dixit -+Co-developed-by: John Crispin -+Signed-off-by: John Crispin -+Signed-off-by: Kalle Valo -+Link: https://lore.kernel.org/r/20230405221648.17950-7-quic_alokad@quicinc.com -+--- -+ drivers/net/wireless/ath/ath11k/mac.c | 116 ++++++++++++++++++++++++-- -+ drivers/net/wireless/ath/ath11k/wmi.c | 1 + -+ 2 files changed, 112 insertions(+), 5 deletions(-) -+ -+--- a/drivers/net/wireless/ath/ath11k/mac.c -++++ b/drivers/net/wireless/ath/ath11k/mac.c -+@@ -1351,6 +1351,84 @@ err_mon_del: -+ return ret; -+ } -+ -++static void ath11k_mac_setup_nontx_vif_rsnie(struct ath11k_vif *arvif, -++ bool tx_arvif_rsnie_present, -++ const u8 *profile, u8 profile_len) -++{ -++ if (cfg80211_find_ie(WLAN_EID_RSN, profile, profile_len)) { -++ arvif->rsnie_present = true; -++ } else if (tx_arvif_rsnie_present) { -++ int i; -++ u8 nie_len; -++ const u8 *nie = cfg80211_find_ext_ie(WLAN_EID_EXT_NON_INHERITANCE, -++ profile, profile_len); -++ if (!nie) -++ return; -++ -++ nie_len = nie[1]; -++ nie += 2; -++ for (i = 0; i < nie_len; i++) { -++ if (nie[i] == WLAN_EID_RSN) { -++ arvif->rsnie_present = false; -++ break; -++ } -++ } -++ } -++} -++ -++static bool ath11k_mac_set_nontx_vif_params(struct ath11k_vif *tx_arvif, -++ struct ath11k_vif *arvif, -++ struct sk_buff *bcn) -++{ -++ struct ieee80211_mgmt *mgmt; -++ const u8 *ies, *profile, *next_profile; -++ int ies_len; -++ -++ ies = bcn->data + ieee80211_get_hdrlen_from_skb(bcn); -++ mgmt = (struct ieee80211_mgmt *)bcn->data; -++ ies += sizeof(mgmt->u.beacon); -++ ies_len = skb_tail_pointer(bcn) - ies; -++ -++ ies = cfg80211_find_ie(WLAN_EID_MULTIPLE_BSSID, ies, ies_len); -++ arvif->rsnie_present = tx_arvif->rsnie_present; -++ -++ while (ies) { -++ u8 mbssid_len; -++ -++ ies_len -= (2 + ies[1]); -++ mbssid_len = ies[1] - 1; -++ profile = &ies[3]; -++ -++ while (mbssid_len) { -++ u8 profile_len; -++ -++ profile_len = profile[1]; -++ next_profile = profile + (2 + profile_len); -++ mbssid_len -= (2 + profile_len); -++ -++ profile += 2; -++ profile_len -= (2 + profile[1]); -++ profile += (2 + profile[1]); /* nontx capabilities */ -++ profile_len -= (2 + profile[1]); -++ profile += (2 + profile[1]); /* SSID */ -++ if (profile[2] == arvif->vif->bss_conf.bssid_index) { -++ profile_len -= 5; -++ profile = profile + 5; -++ ath11k_mac_setup_nontx_vif_rsnie(arvif, -++ tx_arvif->rsnie_present, -++ profile, -++ profile_len); -++ return true; -++ } -++ profile = next_profile; -++ } -++ ies = cfg80211_find_ie(WLAN_EID_MULTIPLE_BSSID, profile, -++ ies_len); -++ } -++ -++ return false; -++} -++ -+ static void ath11k_mac_set_vif_params(struct ath11k_vif *arvif, -+ struct sk_buff *bcn) -+ { -+@@ -1374,18 +1452,26 @@ static void ath11k_mac_set_vif_params(st -+ arvif->wpaie_present = false; -+ } -+ -+-static int ath11k_mac_setup_bcn_tmpl(struct ath11k_vif *arvif) -++static int ath11k_mac_setup_bcn_tmpl_mbssid(struct ath11k_vif *arvif) -+ { -+ struct ath11k *ar = arvif->ar; -+ struct ath11k_base *ab = ar->ab; -++ struct ath11k_vif *tx_arvif = arvif; -+ struct ieee80211_hw *hw = ar->hw; -+ struct ieee80211_vif *vif = arvif->vif; -+ struct ieee80211_mutable_offsets offs = {}; -+ struct sk_buff *bcn; -+ int ret; -+ -+- if (arvif->vdev_type != WMI_VDEV_TYPE_AP) -+- return 0; -++ if (arvif->vif->mbssid_tx_vif) { -++ tx_arvif = (void *)arvif->vif->mbssid_tx_vif->drv_priv; -++ if (tx_arvif != arvif) { -++ ar = tx_arvif->ar; -++ ab = ar->ab; -++ hw = ar->hw; -++ vif = tx_arvif->vif; -++ } -++ } -+ -+ bcn = ieee80211_beacon_get_template(hw, vif, &offs, 0); -+ if (!bcn) { -+@@ -1393,9 +1479,12 @@ static int ath11k_mac_setup_bcn_tmpl(str -+ return -EPERM; -+ } -+ -+- ath11k_mac_set_vif_params(arvif, bcn); -+- ret = ath11k_wmi_bcn_tmpl(ar, arvif->vdev_id, &offs, bcn); -++ if (tx_arvif == arvif) -++ ath11k_mac_set_vif_params(tx_arvif, bcn); -++ else if (!ath11k_mac_set_nontx_vif_params(tx_arvif, arvif, bcn)) -++ return -EINVAL; -+ -++ ret = ath11k_wmi_bcn_tmpl(ar, arvif->vdev_id, &offs, bcn); -+ kfree_skb(bcn); -+ -+ if (ret) -+@@ -1405,6 +1494,23 @@ static int ath11k_mac_setup_bcn_tmpl(str -+ return ret; -+ } -+ -++static int ath11k_mac_setup_bcn_tmpl(struct ath11k_vif *arvif) -++{ -++ struct ieee80211_vif *vif = arvif->vif; -++ -++ if (arvif->vdev_type != WMI_VDEV_TYPE_AP) -++ return 0; -++ -++ /* Target does not expect beacon templates for the already up -++ * non-transmitting interfaces, and results in a crash if sent. -++ */ -++ if (vif->mbssid_tx_vif && -++ arvif != (void *)vif->mbssid_tx_vif->drv_priv && arvif->is_up) -++ return 0; -++ -++ return ath11k_mac_setup_bcn_tmpl_mbssid(arvif); -++} -++ -+ void ath11k_mac_bcn_tx_event(struct ath11k_vif *arvif) -+ { -+ struct ieee80211_vif *vif = arvif->vif; -+--- a/drivers/net/wireless/ath/ath11k/wmi.c -++++ b/drivers/net/wireless/ath/ath11k/wmi.c -+@@ -1737,6 +1737,7 @@ int ath11k_wmi_bcn_tmpl(struct ath11k *a -+ } -+ -+ cmd->buf_len = bcn->len; -++ cmd->mbssid_ie_offset = offs->mbssid_off; -+ -+ ptr = skb->data + sizeof(*cmd); -+ -diff --git a/package/kernel/mac80211/patches/ath11k/0077-wifi-ath11k-EMA-beacon-support.patch b/package/kernel/mac80211/patches/ath11k/0077-wifi-ath11k-EMA-beacon-support.patch -new file mode 100644 -index 0000000000..51353fa3e4 ---- /dev/null -+++ b/package/kernel/mac80211/patches/ath11k/0077-wifi-ath11k-EMA-beacon-support.patch -@@ -0,0 +1,156 @@ -+From 87bd401138161008fdb82fbca6e213af117bfeb9 Mon Sep 17 00:00:00 2001 -+From: Aloka Dixit -+Date: Fri, 5 May 2023 16:11:28 +0300 -+Subject: [PATCH 77/77] wifi: ath11k: EMA beacon support -+ -+Add new function ath11k_mac_setup_bcn_tmpl_ema() which invokes the new -+API provided by MAC80211 to retrieve EMA beacons. -+ -+Tested-on: IPQ8074 hw2.0 AHB WLAN.HK.2.7.0.1-01744-QCAHKSWPL_SILICONZ-1 -+ -+Signed-off-by: Aloka Dixit -+Co-developed-by: John Crispin -+Signed-off-by: John Crispin -+Signed-off-by: Kalle Valo -+Link: https://lore.kernel.org/r/20230405221648.17950-8-quic_alokad@quicinc.com -+--- -+ drivers/net/wireless/ath/ath11k/mac.c | 59 ++++++++++++++++++++++++++- -+ drivers/net/wireless/ath/ath11k/wmi.c | 3 +- -+ drivers/net/wireless/ath/ath11k/wmi.h | 11 ++++- -+ 3 files changed, 70 insertions(+), 3 deletions(-) -+ -+--- a/drivers/net/wireless/ath/ath11k/mac.c -++++ b/drivers/net/wireless/ath/ath11k/mac.c -+@@ -1452,6 +1452,60 @@ static void ath11k_mac_set_vif_params(st -+ arvif->wpaie_present = false; -+ } -+ -++static int ath11k_mac_setup_bcn_tmpl_ema(struct ath11k_vif *arvif) -++{ -++ struct ath11k_vif *tx_arvif; -++ struct ieee80211_ema_beacons *beacons; -++ int ret = 0; -++ bool nontx_vif_params_set = false; -++ u32 params = 0; -++ u8 i = 0; -++ -++ tx_arvif = (void *)arvif->vif->mbssid_tx_vif->drv_priv; -++ -++ beacons = ieee80211_beacon_get_template_ema_list(tx_arvif->ar->hw, -++ tx_arvif->vif, 0); -++ if (!beacons || !beacons->cnt) { -++ ath11k_warn(arvif->ar->ab, -++ "failed to get ema beacon templates from mac80211\n"); -++ return -EPERM; -++ } -++ -++ if (tx_arvif == arvif) -++ ath11k_mac_set_vif_params(tx_arvif, beacons->bcn[0].skb); -++ else -++ arvif->wpaie_present = tx_arvif->wpaie_present; -++ -++ for (i = 0; i < beacons->cnt; i++) { -++ if (tx_arvif != arvif && !nontx_vif_params_set) -++ nontx_vif_params_set = -++ ath11k_mac_set_nontx_vif_params(tx_arvif, arvif, -++ beacons->bcn[i].skb); -++ -++ params = beacons->cnt; -++ params |= (i << WMI_EMA_TMPL_IDX_SHIFT); -++ params |= ((!i ? 1 : 0) << WMI_EMA_FIRST_TMPL_SHIFT); -++ params |= ((i + 1 == beacons->cnt ? 1 : 0) << WMI_EMA_LAST_TMPL_SHIFT); -++ -++ ret = ath11k_wmi_bcn_tmpl(tx_arvif->ar, tx_arvif->vdev_id, -++ &beacons->bcn[i].offs, -++ beacons->bcn[i].skb, params); -++ if (ret) { -++ ath11k_warn(tx_arvif->ar->ab, -++ "failed to set ema beacon template id %i error %d\n", -++ i, ret); -++ break; -++ } -++ } -++ -++ ieee80211_beacon_free_ema_list(beacons); -++ -++ if (tx_arvif != arvif && !nontx_vif_params_set) -++ return -EINVAL; /* Profile not found in the beacons */ -++ -++ return ret; -++} -++ -+ static int ath11k_mac_setup_bcn_tmpl_mbssid(struct ath11k_vif *arvif) -+ { -+ struct ath11k *ar = arvif->ar; -+@@ -1484,7 +1538,7 @@ static int ath11k_mac_setup_bcn_tmpl_mbs -+ else if (!ath11k_mac_set_nontx_vif_params(tx_arvif, arvif, bcn)) -+ return -EINVAL; -+ -+- ret = ath11k_wmi_bcn_tmpl(ar, arvif->vdev_id, &offs, bcn); -++ ret = ath11k_wmi_bcn_tmpl(ar, arvif->vdev_id, &offs, bcn, 0); -+ kfree_skb(bcn); -+ -+ if (ret) -+@@ -1508,6 +1562,9 @@ static int ath11k_mac_setup_bcn_tmpl(str -+ arvif != (void *)vif->mbssid_tx_vif->drv_priv && arvif->is_up) -+ return 0; -+ -++ if (vif->bss_conf.ema_ap && vif->mbssid_tx_vif) -++ return ath11k_mac_setup_bcn_tmpl_ema(arvif); -++ -+ return ath11k_mac_setup_bcn_tmpl_mbssid(arvif); -+ } -+ -+--- a/drivers/net/wireless/ath/ath11k/wmi.c -++++ b/drivers/net/wireless/ath/ath11k/wmi.c -+@@ -1699,7 +1699,7 @@ int ath11k_wmi_send_bcn_offload_control_ -+ -+ int ath11k_wmi_bcn_tmpl(struct ath11k *ar, u32 vdev_id, -+ struct ieee80211_mutable_offsets *offs, -+- struct sk_buff *bcn) -++ struct sk_buff *bcn, u32 ema_params) -+ { -+ struct ath11k_pdev_wmi *wmi = ar->wmi; -+ struct wmi_bcn_tmpl_cmd *cmd; -+@@ -1738,6 +1738,7 @@ int ath11k_wmi_bcn_tmpl(struct ath11k *a -+ -+ cmd->buf_len = bcn->len; -+ cmd->mbssid_ie_offset = offs->mbssid_off; -++ cmd->ema_params = ema_params; -+ -+ ptr = skb->data + sizeof(*cmd); -+ -+--- a/drivers/net/wireless/ath/ath11k/wmi.h -++++ b/drivers/net/wireless/ath/ath11k/wmi.h -+@@ -3566,6 +3566,10 @@ struct wmi_get_pdev_temperature_cmd { -+ -+ #define WMI_BEACON_TX_BUFFER_SIZE 512 -+ -++#define WMI_EMA_TMPL_IDX_SHIFT 8 -++#define WMI_EMA_FIRST_TMPL_SHIFT 16 -++#define WMI_EMA_LAST_TMPL_SHIFT 24 -++ -+ struct wmi_bcn_tmpl_cmd { -+ u32 tlv_header; -+ u32 vdev_id; -+@@ -3576,6 +3580,11 @@ struct wmi_bcn_tmpl_cmd { -+ u32 csa_event_bitmap; -+ u32 mbssid_ie_offset; -+ u32 esp_ie_offset; -++ u32 csc_switch_count_offset; -++ u32 csc_event_bitmap; -++ u32 mu_edca_ie_offset; -++ u32 feature_enable_bitmap; -++ u32 ema_params; -+ } __packed; -+ -+ struct wmi_key_seq_counter { -+@@ -6298,7 +6307,7 @@ int ath11k_wmi_mgmt_send(struct ath11k * -+ struct sk_buff *frame); -+ int ath11k_wmi_bcn_tmpl(struct ath11k *ar, u32 vdev_id, -+ struct ieee80211_mutable_offsets *offs, -+- struct sk_buff *bcn); -++ struct sk_buff *bcn, u32 ema_param); -+ int ath11k_wmi_vdev_down(struct ath11k *ar, u8 vdev_id); -+ int ath11k_wmi_vdev_up(struct ath11k *ar, u32 vdev_id, u32 aid, -+ const u8 *bssid, u8 *tx_bssid, u32 nontx_profile_idx, -diff --git a/package/kernel/mac80211/patches/ath11k/0078-wifi-ath11k-Relocate-the-func-ath11k_mac_bitrate_mas.patch b/package/kernel/mac80211/patches/ath11k/0078-wifi-ath11k-Relocate-the-func-ath11k_mac_bitrate_mas.patch -new file mode 100644 -index 0000000000..610bf72514 ---- /dev/null -+++ b/package/kernel/mac80211/patches/ath11k/0078-wifi-ath11k-Relocate-the-func-ath11k_mac_bitrate_mas.patch -@@ -0,0 +1,75 @@ -+From 570eec3d40505c30babbe3b8f85a38496c975ab2 Mon Sep 17 00:00:00 2001 -+From: Maharaja Kennadyrajan -+Date: Tue, 9 May 2023 20:07:23 +0300 -+Subject: [PATCH] wifi: ath11k: Relocate the func -+ ath11k_mac_bitrate_mask_num_ht_rates() and change hweight16 to hweight8 -+ -+Relocate the function ath11k_mac_bitrate_mask_num_ht_rates() definition -+to call this function from other functions which helps to avoid the -+compilation error (function not defined). -+ -+ht_mcs[] is 1 byte array and it is enough to use hweight8() instead -+of hweight16(). Hence, fixed the same. -+ -+Tested on: Compile tested only. -+ -+Signed-off-by: Maharaja Kennadyrajan -+Signed-off-by: Kalle Valo -+Link: https://lore.kernel.org/r/20230504092033.3542456-2-quic_mkenna@quicinc.com -+--- -+ drivers/net/wireless/ath/ath11k/mac.c | 30 +++++++++++++-------------- -+ 1 file changed, 15 insertions(+), 15 deletions(-) -+ -+--- a/drivers/net/wireless/ath/ath11k/mac.c -++++ b/drivers/net/wireless/ath/ath11k/mac.c -+@@ -1,7 +1,7 @@ -+ // SPDX-License-Identifier: BSD-3-Clause-Clear -+ /* -+ * Copyright (c) 2018-2019 The Linux Foundation. All rights reserved. -+- * Copyright (c) 2021-2022 Qualcomm Innovation Center, Inc. All rights reserved. -++ * Copyright (c) 2021-2023 Qualcomm Innovation Center, Inc. All rights reserved. -+ */ -+ -+ #include -+@@ -4338,6 +4338,20 @@ exit: -+ } -+ -+ static int -++ath11k_mac_bitrate_mask_num_ht_rates(struct ath11k *ar, -++ enum nl80211_band band, -++ const struct cfg80211_bitrate_mask *mask) -++{ -++ int num_rates = 0; -++ int i; -++ -++ for (i = 0; i < ARRAY_SIZE(mask->control[band].ht_mcs); i++) -++ num_rates += hweight8(mask->control[band].ht_mcs[i]); -++ -++ return num_rates; -++} -++ -++static int -+ ath11k_mac_bitrate_mask_num_vht_rates(struct ath11k *ar, -+ enum nl80211_band band, -+ const struct cfg80211_bitrate_mask *mask) -+@@ -7791,20 +7805,6 @@ static void ath11k_mac_op_flush(struct i -+ ath11k_mac_flush_tx_complete(ar); -+ } -+ -+-static int -+-ath11k_mac_bitrate_mask_num_ht_rates(struct ath11k *ar, -+- enum nl80211_band band, -+- const struct cfg80211_bitrate_mask *mask) -+-{ -+- int num_rates = 0; -+- int i; -+- -+- for (i = 0; i < ARRAY_SIZE(mask->control[band].ht_mcs); i++) -+- num_rates += hweight16(mask->control[band].ht_mcs[i]); -+- -+- return num_rates; -+-} -+- -+ static bool -+ ath11k_mac_has_single_legacy_rate(struct ath11k *ar, -+ enum nl80211_band band, -diff --git a/package/kernel/mac80211/patches/ath11k/0079-wifi-ath11k-Send-HT-fixed-rate-in-WMI-peer-fixed-par.patch b/package/kernel/mac80211/patches/ath11k/0079-wifi-ath11k-Send-HT-fixed-rate-in-WMI-peer-fixed-par.patch -new file mode 100644 -index 0000000000..6282f4462e ---- /dev/null -+++ b/package/kernel/mac80211/patches/ath11k/0079-wifi-ath11k-Send-HT-fixed-rate-in-WMI-peer-fixed-par.patch -@@ -0,0 +1,141 @@ -+From df8e3729ffc0aa645839693f74ee7b6d999cdf64 Mon Sep 17 00:00:00 2001 -+From: Maharaja Kennadyrajan -+Date: Tue, 9 May 2023 20:07:24 +0300 -+Subject: [PATCH] wifi: ath11k: Send HT fixed rate in WMI peer fixed param -+ -+Due to the firmware behavior with HT fixed rate setting, -+HT fixed rate MCS with NSS > 1 are treated as NSS = 1 -+HT rates in the firmware and enables the HT fixed rate of -+NSS = 1. -+ -+This leads to HT fixed rate is always configured for NSS = 1 -+even though the user sets NSS = 2 or > 1 HT fixed MCS in the -+set bitrate command. -+ -+Currently HT fixed MCS is sent via WMI peer assoc command. -+Fix this issue, by sending the HT fixed rate MCS in WMI peer -+fixed param instead of sending in peer assoc command. -+ -+Tested-on: QCN9074 hw1.0 PCI WLAN.HK.2.7.0.1-01744-QCAHKSWPL_SILICONZ-1 -+ -+Signed-off-by: Maharaja Kennadyrajan -+Signed-off-by: Kalle Valo -+Link: https://lore.kernel.org/r/20230504092033.3542456-3-quic_mkenna@quicinc.com -+--- -+ drivers/net/wireless/ath/ath11k/mac.c | 63 ++++++++++++++++++++++++++- -+ 1 file changed, 61 insertions(+), 2 deletions(-) -+ -+--- a/drivers/net/wireless/ath/ath11k/mac.c -++++ b/drivers/net/wireless/ath/ath11k/mac.c -+@@ -4480,6 +4480,54 @@ ath11k_mac_set_peer_he_fixed_rate(struct -+ return ret; -+ } -+ -++static int -++ath11k_mac_set_peer_ht_fixed_rate(struct ath11k_vif *arvif, -++ struct ieee80211_sta *sta, -++ const struct cfg80211_bitrate_mask *mask, -++ enum nl80211_band band) -++{ -++ struct ath11k *ar = arvif->ar; -++ u8 ht_rate, nss = 0; -++ u32 rate_code; -++ int ret, i; -++ -++ lockdep_assert_held(&ar->conf_mutex); -++ -++ for (i = 0; i < ARRAY_SIZE(mask->control[band].ht_mcs); i++) { -++ if (hweight8(mask->control[band].ht_mcs[i]) == 1) { -++ nss = i + 1; -++ ht_rate = ffs(mask->control[band].ht_mcs[i]) - 1; -++ } -++ } -++ -++ if (!nss) { -++ ath11k_warn(ar->ab, "No single HT Fixed rate found to set for %pM", -++ sta->addr); -++ return -EINVAL; -++ } -++ -++ /* Avoid updating invalid nss as fixed rate*/ -++ if (nss > sta->deflink.rx_nss) -++ return -EINVAL; -++ -++ ath11k_dbg(ar->ab, ATH11K_DBG_MAC, -++ "Setting Fixed HT Rate for peer %pM. Device will not switch to any other selected rates", -++ sta->addr); -++ -++ rate_code = ATH11K_HW_RATE_CODE(ht_rate, nss - 1, -++ WMI_RATE_PREAMBLE_HT); -++ ret = ath11k_wmi_set_peer_param(ar, sta->addr, -++ arvif->vdev_id, -++ WMI_PEER_PARAM_FIXED_RATE, -++ rate_code); -++ if (ret) -++ ath11k_warn(ar->ab, -++ "failed to update STA %pM HT Fixed Rate %d: %d\n", -++ sta->addr, rate_code, ret); -++ -++ return ret; -++} -++ -+ static int ath11k_station_assoc(struct ath11k *ar, -+ struct ieee80211_vif *vif, -+ struct ieee80211_sta *sta, -+@@ -4491,7 +4539,7 @@ static int ath11k_station_assoc(struct a -+ struct cfg80211_chan_def def; -+ enum nl80211_band band; -+ struct cfg80211_bitrate_mask *mask; -+- u8 num_vht_rates, num_he_rates; -++ u8 num_ht_rates, num_vht_rates, num_he_rates; -+ -+ lockdep_assert_held(&ar->conf_mutex); -+ -+@@ -4519,6 +4567,7 @@ static int ath11k_station_assoc(struct a -+ -+ num_vht_rates = ath11k_mac_bitrate_mask_num_vht_rates(ar, band, mask); -+ num_he_rates = ath11k_mac_bitrate_mask_num_he_rates(ar, band, mask); -++ num_ht_rates = ath11k_mac_bitrate_mask_num_ht_rates(ar, band, mask); -+ -+ /* If single VHT/HE rate is configured (by set_bitrate_mask()), -+ * peer_assoc will disable VHT/HE. This is now enabled by a peer specific -+@@ -4535,6 +4584,11 @@ static int ath11k_station_assoc(struct a -+ band); -+ if (ret) -+ return ret; -++ } else if (sta->deflink.ht_cap.ht_supported && num_ht_rates == 1) { -++ ret = ath11k_mac_set_peer_ht_fixed_rate(arvif, sta, mask, -++ band); -++ if (ret) -++ return ret; -+ } -+ -+ /* Re-assoc is run only to update supported rates for given station. It -+@@ -4608,7 +4662,7 @@ static void ath11k_sta_rc_update_wk(stru -+ const u16 *vht_mcs_mask; -+ const u16 *he_mcs_mask; -+ u32 changed, bw, nss, smps, bw_prev; -+- int err, num_vht_rates, num_he_rates; -++ int err, num_ht_rates, num_vht_rates, num_he_rates; -+ const struct cfg80211_bitrate_mask *mask; -+ struct peer_assoc_params peer_arg; -+ enum wmi_phy_mode peer_phymode; -+@@ -4724,6 +4778,8 @@ static void ath11k_sta_rc_update_wk(stru -+ -+ if (changed & IEEE80211_RC_SUPP_RATES_CHANGED) { -+ mask = &arvif->bitrate_mask; -++ num_ht_rates = ath11k_mac_bitrate_mask_num_ht_rates(ar, band, -++ mask); -+ num_vht_rates = ath11k_mac_bitrate_mask_num_vht_rates(ar, band, -+ mask); -+ num_he_rates = ath11k_mac_bitrate_mask_num_he_rates(ar, band, -+@@ -4746,6 +4802,9 @@ static void ath11k_sta_rc_update_wk(stru -+ } else if (sta->deflink.he_cap.has_he && num_he_rates == 1) { -+ ath11k_mac_set_peer_he_fixed_rate(arvif, sta, mask, -+ band); -++ } else if (sta->deflink.ht_cap.ht_supported && num_ht_rates == 1) { -++ ath11k_mac_set_peer_ht_fixed_rate(arvif, sta, mask, -++ band); -+ } else { -+ /* If the peer is non-VHT/HE or no fixed VHT/HE rate -+ * is provided in the new bitrate mask we set the -diff --git a/package/kernel/mac80211/patches/ath11k/0080-wifi-ath11k-add-support-default-regdb-while-searchin.patch b/package/kernel/mac80211/patches/ath11k/0080-wifi-ath11k-add-support-default-regdb-while-searchin.patch -new file mode 100644 -index 0000000000..5ff40aac7a ---- /dev/null -+++ b/package/kernel/mac80211/patches/ath11k/0080-wifi-ath11k-add-support-default-regdb-while-searchin.patch -@@ -0,0 +1,127 @@ -+From 88ca89202f8e8afb5225eb5244d79cd67c15d744 Mon Sep 17 00:00:00 2001 -+From: Wen Gong -+Date: Fri, 26 May 2023 12:41:06 +0300 -+Subject: [PATCH] wifi: ath11k: add support default regdb while searching -+ board-2.bin for WCN6855 -+ -+Sometimes board-2.bin does not have the regdb data which matched the -+parameters such as vendor, device, subsystem-vendor, subsystem-device -+and etc. Add default regdb data with 'bus=%s' into board-2.bin for -+WCN6855, then ath11k use 'bus=pci' to search regdb data in board-2.bin -+for WCN6855. -+ -+kernel: [ 122.515808] ath11k_pci 0000:03:00.0: boot using board name 'bus=pci,vendor=17cb,device=1103,subsystem-vendor=17cb,subsystem-device=3374,qmi-chip-id=2,qmi-board-id=262' -+kernel: [ 122.517240] ath11k_pci 0000:03:00.0: boot firmware request ath11k/WCN6855/hw2.0/board-2.bin size 6179564 -+kernel: [ 122.517280] ath11k_pci 0000:03:00.0: failed to fetch regdb data for bus=pci,vendor=17cb,device=1103,subsystem-vendor=17cb,subsystem-device=3374,qmi-chip-id=2,qmi-board-id=262 from ath11k/WCN6855/hw2.0/board-2.bin -+kernel: [ 122.517464] ath11k_pci 0000:03:00.0: boot using board name 'bus=pci' -+kernel: [ 122.518901] ath11k_pci 0000:03:00.0: boot firmware request ath11k/WCN6855/hw2.0/board-2.bin size 6179564 -+kernel: [ 122.518915] ath11k_pci 0000:03:00.0: board name -+kernel: [ 122.518917] ath11k_pci 0000:03:00.0: 00000000: 62 75 73 3d 70 63 69 bus=pci -+kernel: [ 122.518918] ath11k_pci 0000:03:00.0: boot found match regdb data for name 'bus=pci' -+kernel: [ 122.518920] ath11k_pci 0000:03:00.0: boot found regdb data for 'bus=pci' -+kernel: [ 122.518921] ath11k_pci 0000:03:00.0: fetched regdb -+ -+Tested-on: WCN6855 hw2.0 PCI WLAN.HSP.1.1-03125-QCAHSPSWPL_V1_V2_SILICONZ_LITE-3 -+ -+Signed-off-by: Wen Gong -+Signed-off-by: Kalle Valo -+Link: https://lore.kernel.org/r/20230517133959.8224-1-quic_wgong@quicinc.com -+--- -+ drivers/net/wireless/ath/ath11k/core.c | 53 +++++++++++++++++++------- -+ 1 file changed, 40 insertions(+), 13 deletions(-) -+ -+--- a/drivers/net/wireless/ath/ath11k/core.c -++++ b/drivers/net/wireless/ath/ath11k/core.c -+@@ -961,7 +961,8 @@ int ath11k_core_check_dt(struct ath11k_b -+ } -+ -+ static int __ath11k_core_create_board_name(struct ath11k_base *ab, char *name, -+- size_t name_len, bool with_variant) -++ size_t name_len, bool with_variant, -++ bool bus_type_mode) -+ { -+ /* strlen(',variant=') + strlen(ab->qmi.target.bdf_ext) */ -+ char variant[9 + ATH11K_QMI_BDF_EXT_STR_LENGTH] = { 0 }; -+@@ -972,15 +973,20 @@ static int __ath11k_core_create_board_na -+ -+ switch (ab->id.bdf_search) { -+ case ATH11K_BDF_SEARCH_BUS_AND_BOARD: -+- 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); -++ if (bus_type_mode) -++ scnprintf(name, name_len, -++ "bus=%s", -++ ath11k_bus_str(ab->hif.bus)); -++ else -++ 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; -+ default: -+ scnprintf(name, name_len, -+@@ -999,13 +1005,19 @@ static int __ath11k_core_create_board_na -+ static int ath11k_core_create_board_name(struct ath11k_base *ab, char *name, -+ size_t name_len) -+ { -+- return __ath11k_core_create_board_name(ab, name, name_len, true); -++ return __ath11k_core_create_board_name(ab, name, name_len, true, false); -+ } -+ -+ 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); -++ return __ath11k_core_create_board_name(ab, name, name_len, false, false); -++} -++ -++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, true); -+ } -+ -+ const struct firmware *ath11k_core_firmware_request(struct ath11k_base *ab, -+@@ -1309,7 +1321,7 @@ success: -+ -+ int ath11k_core_fetch_regdb(struct ath11k_base *ab, struct ath11k_board_data *bd) -+ { -+- char boardname[BOARD_NAME_SIZE]; -++ char boardname[BOARD_NAME_SIZE], default_boardname[BOARD_NAME_SIZE]; -+ int ret; -+ -+ ret = ath11k_core_create_board_name(ab, boardname, BOARD_NAME_SIZE); -+@@ -1323,6 +1335,21 @@ int ath11k_core_fetch_regdb(struct ath11 -+ ATH11K_BD_IE_REGDB, -+ ATH11K_BD_IE_REGDB_NAME, -+ ATH11K_BD_IE_REGDB_DATA); -++ if (!ret) -++ goto exit; -++ -++ ret = ath11k_core_create_bus_type_board_name(ab, default_boardname, -++ BOARD_NAME_SIZE); -++ if (ret) { -++ ath11k_dbg(ab, ATH11K_DBG_BOOT, -++ "failed to create default board name for regdb: %d", ret); -++ goto exit; -++ } -++ -++ ret = ath11k_core_fetch_board_data_api_n(ab, bd, default_boardname, -++ ATH11K_BD_IE_REGDB, -++ ATH11K_BD_IE_REGDB_NAME, -++ ATH11K_BD_IE_REGDB_DATA); -+ if (!ret) -+ goto exit; -+ -diff --git a/package/kernel/mac80211/patches/ath11k/0081-wifi-ath11k-remove-unused-function-ath11k_tm_event_w.patch b/package/kernel/mac80211/patches/ath11k/0081-wifi-ath11k-remove-unused-function-ath11k_tm_event_w.patch -new file mode 100644 -index 0000000000..b5dc83f007 ---- /dev/null -+++ b/package/kernel/mac80211/patches/ath11k/0081-wifi-ath11k-remove-unused-function-ath11k_tm_event_w.patch -@@ -0,0 +1,128 @@ -+From 86f85575a3f6a20cef1c8bb98e78585fe3a53ccc Mon Sep 17 00:00:00 2001 -+From: Govindaraj Saminathan -+Date: Fri, 26 May 2023 12:41:06 +0300 -+Subject: [PATCH 82/84] wifi: ath11k: remove unused function -+ ath11k_tm_event_wmi() -+ -+The function ath11k_tm_event_wmi() is only defined and it is not used -+anywhere. Hence remove the unused. -+ -+Tested-on: IPQ8074 hw2.0 AHB WLAN.HK.2.7.0.1-01744-QCAHKSWPL_SILICONZ-1 -+ -+Signed-off-by: Govindaraj Saminathan -+Signed-off-by: Raj Kumar Bhagat -+Signed-off-by: Kalle Valo -+Link: https://lore.kernel.org/r/20230517135934.16408-2-quic_rajkbhag@quicinc.com -+--- -+ drivers/net/wireless/ath/ath11k/testmode.c | 64 +--------------------- -+ drivers/net/wireless/ath/ath11k/testmode.h | 8 +-- -+ 2 files changed, 2 insertions(+), 70 deletions(-) -+ -+--- a/drivers/net/wireless/ath/ath11k/testmode.c -++++ b/drivers/net/wireless/ath/ath11k/testmode.c -+@@ -1,6 +1,7 @@ -+ // SPDX-License-Identifier: BSD-3-Clause-Clear -+ /* -+ * Copyright (c) 2018-2019 The Linux Foundation. All rights reserved. -++ * Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights reserved. -+ */ -+ -+ #include "testmode.h" -+@@ -20,69 +21,6 @@ static const struct nla_policy ath11k_tm -+ [ATH11K_TM_ATTR_VERSION_MINOR] = { .type = NLA_U32 }, -+ }; -+ -+-/* Returns true if callee consumes the skb and the skb should be discarded. -+- * Returns false if skb is not used. Does not sleep. -+- */ -+-bool ath11k_tm_event_wmi(struct ath11k *ar, u32 cmd_id, struct sk_buff *skb) -+-{ -+- struct sk_buff *nl_skb; -+- bool consumed; -+- int ret; -+- -+- ath11k_dbg(ar->ab, ATH11K_DBG_TESTMODE, -+- "testmode event wmi cmd_id %d skb %pK skb->len %d\n", -+- cmd_id, skb, skb->len); -+- -+- ath11k_dbg_dump(ar->ab, ATH11K_DBG_TESTMODE, NULL, "", skb->data, skb->len); -+- -+- spin_lock_bh(&ar->data_lock); -+- -+- consumed = true; -+- -+- nl_skb = cfg80211_testmode_alloc_event_skb(ar->hw->wiphy, -+- 2 * sizeof(u32) + skb->len, -+- GFP_ATOMIC); -+- if (!nl_skb) { -+- ath11k_warn(ar->ab, -+- "failed to allocate skb for testmode wmi event\n"); -+- goto out; -+- } -+- -+- ret = nla_put_u32(nl_skb, ATH11K_TM_ATTR_CMD, ATH11K_TM_CMD_WMI); -+- if (ret) { -+- ath11k_warn(ar->ab, -+- "failed to put testmode wmi event cmd attribute: %d\n", -+- ret); -+- kfree_skb(nl_skb); -+- goto out; -+- } -+- -+- ret = nla_put_u32(nl_skb, ATH11K_TM_ATTR_WMI_CMDID, cmd_id); -+- if (ret) { -+- ath11k_warn(ar->ab, -+- "failed to put testmode wmi even cmd_id: %d\n", -+- ret); -+- kfree_skb(nl_skb); -+- goto out; -+- } -+- -+- ret = nla_put(nl_skb, ATH11K_TM_ATTR_DATA, skb->len, skb->data); -+- if (ret) { -+- ath11k_warn(ar->ab, -+- "failed to copy skb to testmode wmi event: %d\n", -+- ret); -+- kfree_skb(nl_skb); -+- goto out; -+- } -+- -+- cfg80211_testmode_event(nl_skb, GFP_ATOMIC); -+- -+-out: -+- spin_unlock_bh(&ar->data_lock); -+- -+- return consumed; -+-} -+- -+ static int ath11k_tm_cmd_get_version(struct ath11k *ar, struct nlattr *tb[]) -+ { -+ struct sk_buff *skb; -+--- a/drivers/net/wireless/ath/ath11k/testmode.h -++++ b/drivers/net/wireless/ath/ath11k/testmode.h -+@@ -1,24 +1,18 @@ -+ /* SPDX-License-Identifier: BSD-3-Clause-Clear */ -+ /* -+ * Copyright (c) 2018-2019 The Linux Foundation. All rights reserved. -++ * Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights reserved. -+ */ -+ -+ #include "core.h" -+ -+ #ifdef CPTCFG_NL80211_TESTMODE -+ -+-bool ath11k_tm_event_wmi(struct ath11k *ar, u32 cmd_id, struct sk_buff *skb); -+ int ath11k_tm_cmd(struct ieee80211_hw *hw, struct ieee80211_vif *vif, -+ void *data, int len); -+ -+ #else -+ -+-static inline bool ath11k_tm_event_wmi(struct ath11k *ar, u32 cmd_id, -+- struct sk_buff *skb) -+-{ -+- return false; -+-} -+- -+ static inline int ath11k_tm_cmd(struct ieee80211_hw *hw, -+ struct ieee80211_vif *vif, -+ void *data, int len) -diff --git a/package/kernel/mac80211/patches/ath11k/0082-wifi-ath11k-factory-test-mode-support.patch b/package/kernel/mac80211/patches/ath11k/0082-wifi-ath11k-factory-test-mode-support.patch -new file mode 100644 -index 0000000000..f1b262724f ---- /dev/null -+++ b/package/kernel/mac80211/patches/ath11k/0082-wifi-ath11k-factory-test-mode-support.patch -@@ -0,0 +1,850 @@ -+From b43310e44edc823a7f02af1e1e2b4e8a9abc7d91 Mon Sep 17 00:00:00 2001 -+From: Govindaraj Saminathan -+Date: Fri, 26 May 2023 12:41:07 +0300 -+Subject: [PATCH 83/84] wifi: ath11k: factory test mode support -+ -+Add support to process factory test mode commands (FTM) for calibration. -+By default firmware start with NORMAL mode and to process the FTM commands -+firmware needs to be restarted in FTM mode using module parameter ftm_mode. -+The pre-request is all the radios should be down before starting the test. -+ -+When start command ATH11K_TM_CMD_TESTMODE_START is received, ar->state -+is set to Test Mode. If the FTM command or event length is greater -+than 256 bytes, it will be broken down into multiple segments and -+encoded with TLV header if it is segmented commands, else it is sent -+to firmware as it is. -+ -+On receiving UTF event from firmware, if it is segmented event, the driver -+will wait until it receives all the segments and notify the complete -+data to user application. In case the segmented sequence are missed or -+lost from the firmware, driver will skip the already received partial data. -+ -+In case of unsegmented UTF event from firmware, driver notifies the -+data to the user application as it comes. Applications handles -+the data further. -+ -+Command to boot in ftm mode: -+ -+insmod ath11k ftm_mode=1 -+ -+Tested-on: IPQ8074 hw2.0 AHB WLAN.HK.2.7.0.1-01744-QCAHKSWPL_SILICONZ-1 -+ -+Signed-off-by: Govindaraj Saminathan -+Co-developed-by: Sowmiya Sree Elavalagan -+Signed-off-by: Sowmiya Sree Elavalagan -+Signed-off-by: Raj Kumar Bhagat -+Signed-off-by: Kalle Valo -+Link: https://lore.kernel.org/r/20230517135934.16408-4-quic_rajkbhag@quicinc.com -+--- -+ drivers/net/wireless/ath/ath11k/ahb.c | 3 +- -+ drivers/net/wireless/ath/ath11k/core.c | 21 +- -+ drivers/net/wireless/ath/ath11k/core.h | 16 +- -+ drivers/net/wireless/ath/ath11k/debug.h | 1 + -+ drivers/net/wireless/ath/ath11k/mac.c | 11 +- -+ drivers/net/wireless/ath/ath11k/pci.c | 3 +- -+ drivers/net/wireless/ath/ath11k/testmode.c | 350 ++++++++++++++++++- -+ drivers/net/wireless/ath/ath11k/testmode.h | 6 + -+ drivers/net/wireless/ath/ath11k/testmode_i.h | 18 +- -+ drivers/net/wireless/ath/ath11k/wmi.c | 11 +- -+ drivers/net/wireless/ath/ath11k/wmi.h | 22 ++ -+ drivers/net/wireless/ath/ath11k/wow.c | 3 +- -+ 12 files changed, 444 insertions(+), 21 deletions(-) -+ -+--- a/drivers/net/wireless/ath/ath11k/ahb.c -++++ b/drivers/net/wireless/ath/ath11k/ahb.c -+@@ -1,7 +1,7 @@ -+ // SPDX-License-Identifier: BSD-3-Clause-Clear -+ /* -+ * Copyright (c) 2018-2019 The Linux Foundation. All rights reserved. -+- * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved. -++ * Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved. -+ */ -+ -+ #include -+@@ -1155,6 +1155,7 @@ static int ath11k_ahb_probe(struct platf -+ ab->hif.ops = hif_ops; -+ ab->pdev = pdev; -+ ab->hw_rev = hw_rev; -++ ab->fw_mode = ATH11K_FIRMWARE_MODE_NORMAL; -+ platform_set_drvdata(pdev, ab); -+ -+ ret = ath11k_pcic_register_pci_ops(ab, pci_ops); -+--- a/drivers/net/wireless/ath/ath11k/core.c -++++ b/drivers/net/wireless/ath/ath11k/core.c -+@@ -1,7 +1,7 @@ -+ // SPDX-License-Identifier: BSD-3-Clause-Clear -+ /* -+ * Copyright (c) 2018-2019 The Linux Foundation. All rights reserved. -+- * Copyright (c) 2021-2022 Qualcomm Innovation Center, Inc. All rights reserved. -++ * Copyright (c) 2021-2023 Qualcomm Innovation Center, Inc. All rights reserved. -+ */ -+ -+ #include -+@@ -32,6 +32,10 @@ module_param_named(frame_mode, ath11k_fr -+ 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_hw_params ath11k_hw_params[] = { -+ { -+ .hw_rev = ATH11K_HW_IPQ8074, -+@@ -1381,6 +1385,11 @@ static int ath11k_core_soc_create(struct -+ { -+ int ret; -+ -++ if (ath11k_ftm_mode) { -++ ab->fw_mode = ATH11K_FIRMWARE_MODE_FTM; -++ ath11k_info(ab, "Booting in factory test mode\n"); -++ } -++ -+ ret = ath11k_qmi_init_service(ab); -+ if (ret) { -+ ath11k_err(ab, "failed to initialize qmi :%d\n", ret); -+@@ -1607,7 +1616,7 @@ int ath11k_core_qmi_firmware_ready(struc -+ { -+ int ret; -+ -+- ret = ath11k_core_start_firmware(ab, ATH11K_FIRMWARE_MODE_NORMAL); -++ ret = ath11k_core_start_firmware(ab, ab->fw_mode); -+ if (ret) { -+ ath11k_err(ab, "failed to start firmware: %d\n", ret); -+ return ret; -+@@ -1772,7 +1781,8 @@ void ath11k_core_pre_reconfigure_recover -+ for (i = 0; i < ab->num_radios; i++) { -+ pdev = &ab->pdevs[i]; -+ ar = pdev->ar; -+- if (!ar || ar->state == ATH11K_STATE_OFF) -++ if (!ar || ar->state == ATH11K_STATE_OFF || -++ ar->state == ATH11K_STATE_FTM) -+ continue; -+ -+ ieee80211_stop_queues(ar->hw); -+@@ -1841,7 +1851,12 @@ static void ath11k_core_post_reconfigure -+ ath11k_warn(ab, -+ "device is wedged, will not restart radio %d\n", i); -+ break; -++ case ATH11K_STATE_FTM: -++ ath11k_dbg(ab, ATH11K_DBG_TESTMODE, -++ "fw mode reset done radio %d\n", i); -++ break; -+ } -++ -+ mutex_unlock(&ar->conf_mutex); -+ } -+ complete(&ab->driver_recovery); -+--- a/drivers/net/wireless/ath/ath11k/core.h -++++ b/drivers/net/wireless/ath/ath11k/core.h -+@@ -1,7 +1,7 @@ -+ /* SPDX-License-Identifier: BSD-3-Clause-Clear */ -+ /* -+ * Copyright (c) 2018-2019 The Linux Foundation. All rights reserved. -+- * Copyright (c) 2021-2022 Qualcomm Innovation Center, Inc. All rights reserved. -++ * Copyright (c) 2021-2023 Qualcomm Innovation Center, Inc. All rights reserved. -+ */ -+ -+ #ifndef ATH11K_CORE_H -+@@ -52,6 +52,7 @@ -+ #define ATH11K_SMBIOS_BDF_EXT_MAGIC "BDF_" -+ -+ extern unsigned int ath11k_frame_mode; -++extern bool ath11k_ftm_mode; -+ -+ #define ATH11K_SCAN_TIMEOUT_HZ (20 * HZ) -+ -+@@ -277,6 +278,7 @@ enum ath11k_dev_flags { -+ ATH11K_FLAG_FIXED_MEM_RGN, -+ ATH11K_FLAG_DEVICE_INIT_DONE, -+ ATH11K_FLAG_MULTI_MSI_VECTORS, -++ ATH11K_FLAG_FTM_SEGMENTED, -+ }; -+ -+ enum ath11k_monitor_flags { -+@@ -530,6 +532,7 @@ enum ath11k_state { -+ ATH11K_STATE_RESTARTING, -+ ATH11K_STATE_RESTARTED, -+ ATH11K_STATE_WEDGED, -++ ATH11K_STATE_FTM, -+ /* Add other states as required */ -+ }; -+ -+@@ -709,6 +712,8 @@ struct ath11k { -+ u32 last_ppdu_id; -+ u32 cached_ppdu_id; -+ int monitor_vdev_id; -++ struct completion fw_mode_reset; -++ u8 ftm_msgref; -+ #ifdef CPTCFG_ATH11K_DEBUGFS -+ struct ath11k_debug debug; -+ #endif -+@@ -838,6 +843,7 @@ struct ath11k_msi_config { -+ /* Master structure to hold the hw data which may be used in core module */ -+ struct ath11k_base { -+ enum ath11k_hw_rev hw_rev; -++ enum ath11k_firmware_mode fw_mode; -+ struct platform_device *pdev; -+ struct device *dev; -+ struct ath11k_qmi qmi; -+@@ -978,6 +984,14 @@ struct ath11k_base { -+ const struct ath11k_pci_ops *ops; -+ } pci; -+ -++#ifdef CPTCFG_NL80211_TESTMODE -++ struct { -++ u32 data_pos; -++ u32 expected_seq; -++ u8 *eventdata; -++ } testmode; -++#endif -++ -+ /* must be last */ -+ u8 drv_priv[] __aligned(sizeof(void *)); -+ }; -+--- a/drivers/net/wireless/ath/ath11k/debug.h -++++ b/drivers/net/wireless/ath/ath11k/debug.h -+@@ -1,6 +1,7 @@ -+ /* SPDX-License-Identifier: BSD-3-Clause-Clear */ -+ /* -+ * Copyright (c) 2018-2019 The Linux Foundation. All rights reserved. -++ * Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights reserved. -+ */ -+ -+ #ifndef _ATH11K_DEBUG_H_ -+--- a/drivers/net/wireless/ath/ath11k/mac.c -++++ b/drivers/net/wireless/ath/ath11k/mac.c -+@@ -643,7 +643,10 @@ struct ath11k *ath11k_mac_get_ar_by_pdev -+ return NULL; -+ -+ for (i = 0; i < ab->num_radios; i++) { -+- pdev = rcu_dereference(ab->pdevs_active[i]); -++ if (ab->fw_mode == ATH11K_FIRMWARE_MODE_FTM) -++ pdev = &ab->pdevs[i]; -++ else -++ pdev = rcu_dereference(ab->pdevs_active[i]); -+ -+ if (pdev && pdev->pdev_id == pdev_id) -+ return (pdev->ar ? pdev->ar : NULL); -+@@ -6271,6 +6274,11 @@ static int ath11k_mac_op_start(struct ie -+ struct ath11k_pdev *pdev = ar->pdev; -+ int ret; -+ -++ if (ath11k_ftm_mode) { -++ ath11k_warn(ab, "mac operations not supported in factory test mode\n"); -++ return -EOPNOTSUPP; -++ } -++ -+ ath11k_mac_drain_tx(ar); -+ mutex_lock(&ar->conf_mutex); -+ -+@@ -6285,6 +6293,7 @@ static int ath11k_mac_op_start(struct ie -+ case ATH11K_STATE_RESTARTED: -+ case ATH11K_STATE_WEDGED: -+ case ATH11K_STATE_ON: -++ case ATH11K_STATE_FTM: -+ WARN_ON(1); -+ ret = -EINVAL; -+ goto err; -+--- a/drivers/net/wireless/ath/ath11k/pci.c -++++ b/drivers/net/wireless/ath/ath11k/pci.c -+@@ -1,7 +1,7 @@ -+ // SPDX-License-Identifier: BSD-3-Clause-Clear -+ /* -+ * Copyright (c) 2019-2020 The Linux Foundation. All rights reserved. -+- * Copyright (c) 2021-2022, Qualcomm Innovation Center, Inc. All rights reserved. -++ * Copyright (c) 2021-2023 Qualcomm Innovation Center, Inc. All rights reserved. -+ */ -+ -+ #include -+@@ -745,6 +745,7 @@ static int ath11k_pci_probe(struct pci_d -+ ab_pci->ab = ab; -+ ab_pci->pdev = pdev; -+ ab->hif.ops = &ath11k_pci_hif_ops; -++ ab->fw_mode = ATH11K_FIRMWARE_MODE_NORMAL; -+ pci_set_drvdata(pdev, ab); -+ spin_lock_init(&ab_pci->window_lock); -+ -+--- a/drivers/net/wireless/ath/ath11k/testmode.c -++++ b/drivers/net/wireless/ath/ath11k/testmode.c -+@@ -12,6 +12,9 @@ -+ #include "core.h" -+ #include "testmode_i.h" -+ -++#define ATH11K_FTM_SEGHDR_CURRENT_SEQ GENMASK(3, 0) -++#define ATH11K_FTM_SEGHDR_TOTAL_SEGMENTS GENMASK(7, 4) -++ -+ static const struct nla_policy ath11k_tm_policy[ATH11K_TM_ATTR_MAX + 1] = { -+ [ATH11K_TM_ATTR_CMD] = { .type = NLA_U32 }, -+ [ATH11K_TM_ATTR_DATA] = { .type = NLA_BINARY, -+@@ -21,13 +24,217 @@ static const struct nla_policy ath11k_tm -+ [ATH11K_TM_ATTR_VERSION_MINOR] = { .type = NLA_U32 }, -+ }; -+ -++static struct ath11k *ath11k_tm_get_ar(struct ath11k_base *ab) -++{ -++ struct ath11k_pdev *pdev; -++ struct ath11k *ar = NULL; -++ int i; -++ -++ for (i = 0; i < ab->num_radios; i++) { -++ pdev = &ab->pdevs[i]; -++ ar = pdev->ar; -++ -++ if (ar && ar->state == ATH11K_STATE_FTM) -++ break; -++ } -++ -++ return ar; -++} -++ -++/* This function handles unsegmented events. Data in various events are aggregated -++ * in application layer, this event is unsegmented from host perspective. -++ */ -++static void ath11k_tm_wmi_event_unsegmented(struct ath11k_base *ab, u32 cmd_id, -++ struct sk_buff *skb) -++{ -++ struct sk_buff *nl_skb; -++ struct ath11k *ar; -++ -++ ath11k_dbg(ab, ATH11K_DBG_TESTMODE, -++ "event wmi cmd_id %d skb length %d\n", -++ cmd_id, skb->len); -++ ath11k_dbg_dump(ab, ATH11K_DBG_TESTMODE, NULL, "", skb->data, skb->len); -++ -++ ar = ath11k_tm_get_ar(ab); -++ if (!ar) { -++ ath11k_warn(ab, "testmode event not handled due to invalid pdev\n"); -++ return; -++ } -++ -++ spin_lock_bh(&ar->data_lock); -++ -++ nl_skb = cfg80211_testmode_alloc_event_skb(ar->hw->wiphy, -++ 2 * nla_total_size(sizeof(u32)) + -++ nla_total_size(skb->len), -++ GFP_ATOMIC); -++ if (!nl_skb) { -++ ath11k_warn(ab, -++ "failed to allocate skb for unsegmented testmode wmi event\n"); -++ goto out; -++ } -++ -++ if (nla_put_u32(nl_skb, ATH11K_TM_ATTR_CMD, ATH11K_TM_CMD_WMI) || -++ nla_put_u32(nl_skb, ATH11K_TM_ATTR_WMI_CMDID, cmd_id) || -++ nla_put(nl_skb, ATH11K_TM_ATTR_DATA, skb->len, skb->data)) { -++ ath11k_warn(ab, "failed to populate testmode unsegmented event\n"); -++ kfree_skb(nl_skb); -++ goto out; -++ } -++ -++ cfg80211_testmode_event(nl_skb, GFP_ATOMIC); -++ spin_unlock_bh(&ar->data_lock); -++ return; -++ -++out: -++ spin_unlock_bh(&ar->data_lock); -++ ath11k_warn(ab, "Failed to send testmode event to higher layers\n"); -++} -++ -++/* This function handles segmented events. Data of various events received -++ * from firmware is aggregated and sent to application layer -++ */ -++static int ath11k_tm_process_event(struct ath11k_base *ab, u32 cmd_id, -++ const struct wmi_ftm_event_msg *ftm_msg, -++ u16 length) -++{ -++ struct sk_buff *nl_skb; -++ int ret = 0; -++ struct ath11k *ar; -++ u8 const *buf_pos; -++ u16 datalen; -++ u8 total_segments, current_seq; -++ u32 data_pos; -++ u32 pdev_id; -++ -++ ath11k_dbg(ab, ATH11K_DBG_TESTMODE, -++ "event wmi cmd_id %d ftm event msg %pK datalen %d\n", -++ cmd_id, ftm_msg, length); -++ ath11k_dbg_dump(ab, ATH11K_DBG_TESTMODE, NULL, "", ftm_msg, length); -++ pdev_id = DP_HW2SW_MACID(ftm_msg->seg_hdr.pdev_id); -++ -++ if (pdev_id >= ab->num_radios) { -++ ath11k_warn(ab, "testmode event not handled due to invalid pdev id: %d\n", -++ pdev_id); -++ return -EINVAL; -++ } -++ -++ ar = ab->pdevs[pdev_id].ar; -++ if (!ar) { -++ ath11k_warn(ab, "testmode event not handled due to absence of pdev\n"); -++ return -ENODEV; -++ } -++ -++ current_seq = FIELD_GET(ATH11K_FTM_SEGHDR_CURRENT_SEQ, -++ ftm_msg->seg_hdr.segmentinfo); -++ total_segments = FIELD_GET(ATH11K_FTM_SEGHDR_TOTAL_SEGMENTS, -++ ftm_msg->seg_hdr.segmentinfo); -++ datalen = length - (sizeof(struct wmi_ftm_seg_hdr)); -++ buf_pos = ftm_msg->data; -++ -++ spin_lock_bh(&ar->data_lock); -++ -++ if (current_seq == 0) { -++ ab->testmode.expected_seq = 0; -++ ab->testmode.data_pos = 0; -++ } -++ -++ data_pos = ab->testmode.data_pos; -++ -++ if ((data_pos + datalen) > ATH11K_FTM_EVENT_MAX_BUF_LENGTH) { -++ ath11k_warn(ab, "Invalid ftm event length at %d: %d\n", -++ data_pos, datalen); -++ ret = -EINVAL; -++ goto out; -++ } -++ -++ memcpy(&ab->testmode.eventdata[data_pos], buf_pos, datalen); -++ data_pos += datalen; -++ -++ if (++ab->testmode.expected_seq != total_segments) { -++ ab->testmode.data_pos = data_pos; -++ ath11k_dbg(ab, ATH11K_DBG_TESTMODE, -++ "partial data received current_seq %d total_seg %d\n", -++ current_seq, total_segments); -++ goto out; -++ } -++ -++ ath11k_dbg(ab, ATH11K_DBG_TESTMODE, -++ "total data length pos %d len %d\n", -++ data_pos, ftm_msg->seg_hdr.len); -++ nl_skb = cfg80211_testmode_alloc_event_skb(ar->hw->wiphy, -++ 2 * nla_total_size(sizeof(u32)) + -++ nla_total_size(data_pos), -++ GFP_ATOMIC); -++ if (!nl_skb) { -++ ath11k_warn(ab, -++ "failed to allocate skb for segmented testmode wmi event\n"); -++ ret = -ENOMEM; -++ goto out; -++ } -++ -++ if (nla_put_u32(nl_skb, ATH11K_TM_ATTR_CMD, -++ ATH11K_TM_CMD_WMI_FTM) || -++ nla_put_u32(nl_skb, ATH11K_TM_ATTR_WMI_CMDID, cmd_id) || -++ nla_put(nl_skb, ATH11K_TM_ATTR_DATA, data_pos, -++ &ab->testmode.eventdata[0])) { -++ ath11k_warn(ab, "failed to populate segmented testmode event"); -++ kfree_skb(nl_skb); -++ ret = -ENOBUFS; -++ goto out; -++ } -++ -++ cfg80211_testmode_event(nl_skb, GFP_ATOMIC); -++ -++out: -++ spin_unlock_bh(&ar->data_lock); -++ return ret; -++} -++ -++static void ath11k_tm_wmi_event_segmented(struct ath11k_base *ab, u32 cmd_id, -++ struct sk_buff *skb) -++{ -++ const void **tb; -++ const struct wmi_ftm_event_msg *ev; -++ u16 length; -++ 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 ftm event tlv: %d\n", ret); -++ return; -++ } -++ -++ ev = tb[WMI_TAG_ARRAY_BYTE]; -++ if (!ev) { -++ ath11k_warn(ab, "failed to fetch ftm msg\n"); -++ kfree(tb); -++ return; -++ } -++ -++ length = skb->len - TLV_HDR_SIZE; -++ ret = ath11k_tm_process_event(ab, cmd_id, ev, length); -++ if (ret) -++ ath11k_warn(ab, "Failed to process ftm event\n"); -++ -++ kfree(tb); -++} -++ -++void ath11k_tm_wmi_event(struct ath11k_base *ab, u32 cmd_id, struct sk_buff *skb) -++{ -++ if (test_bit(ATH11K_FLAG_FTM_SEGMENTED, &ab->dev_flags)) -++ ath11k_tm_wmi_event_segmented(ab, cmd_id, skb); -++ else -++ ath11k_tm_wmi_event_unsegmented(ab, cmd_id, skb); -++} -++ -+ static int ath11k_tm_cmd_get_version(struct ath11k *ar, struct nlattr *tb[]) -+ { -+ struct sk_buff *skb; -+ int ret; -+ -+ ath11k_dbg(ar->ab, ATH11K_DBG_TESTMODE, -+- "testmode cmd get version_major %d version_minor %d\n", -++ "cmd get version_major %d version_minor %d\n", -+ ATH11K_TESTMODE_VERSION_MAJOR, -+ ATH11K_TESTMODE_VERSION_MINOR); -+ -+@@ -53,6 +260,43 @@ static int ath11k_tm_cmd_get_version(str -+ return cfg80211_testmode_reply(skb); -+ } -+ -++static int ath11k_tm_cmd_testmode_start(struct ath11k *ar, struct nlattr *tb[]) -++{ -++ int ret; -++ -++ mutex_lock(&ar->conf_mutex); -++ -++ if (ar->state == ATH11K_STATE_FTM) { -++ ret = -EALREADY; -++ goto err; -++ } -++ -++ /* start utf only when the driver is not in use */ -++ if (ar->state != ATH11K_STATE_OFF) { -++ ret = -EBUSY; -++ goto err; -++ } -++ -++ ar->ab->testmode.eventdata = kzalloc(ATH11K_FTM_EVENT_MAX_BUF_LENGTH, -++ GFP_KERNEL); -++ if (!ar->ab->testmode.eventdata) { -++ ret = -ENOMEM; -++ goto err; -++ } -++ -++ ar->state = ATH11K_STATE_FTM; -++ ar->ftm_msgref = 0; -++ -++ mutex_unlock(&ar->conf_mutex); -++ -++ ath11k_dbg(ar->ab, ATH11K_DBG_TESTMODE, "cmd start\n"); -++ return 0; -++ -++err: -++ mutex_unlock(&ar->conf_mutex); -++ return ret; -++} -++ -+ static int ath11k_tm_cmd_wmi(struct ath11k *ar, struct nlattr *tb[]) -+ { -+ struct ath11k_pdev_wmi *wmi = ar->wmi; -+@@ -63,11 +307,6 @@ static int ath11k_tm_cmd_wmi(struct ath1 -+ -+ mutex_lock(&ar->conf_mutex); -+ -+- if (ar->state != ATH11K_STATE_ON) { -+- ret = -ENETDOWN; -+- goto out; -+- } -+- -+ if (!tb[ATH11K_TM_ATTR_DATA]) { -+ ret = -EINVAL; -+ goto out; -+@@ -80,11 +319,17 @@ static int ath11k_tm_cmd_wmi(struct ath1 -+ -+ buf = nla_data(tb[ATH11K_TM_ATTR_DATA]); -+ buf_len = nla_len(tb[ATH11K_TM_ATTR_DATA]); -++ if (!buf_len) { -++ ath11k_warn(ar->ab, "No data present in testmode wmi command\n"); -++ ret = -EINVAL; -++ goto out; -++ } -++ -+ cmd_id = nla_get_u32(tb[ATH11K_TM_ATTR_WMI_CMDID]); -+ -+ ath11k_dbg(ar->ab, ATH11K_DBG_TESTMODE, -+- "testmode cmd wmi cmd_id %d buf %pK buf_len %d\n", -+- cmd_id, buf, buf_len); -++ "cmd wmi cmd_id %d buf length %d\n", -++ cmd_id, buf_len); -+ -+ ath11k_dbg_dump(ar->ab, ATH11K_DBG_TESTMODE, NULL, "", buf, buf_len); -+ -+@@ -111,6 +356,91 @@ out: -+ return ret; -+ } -+ -++static int ath11k_tm_cmd_wmi_ftm(struct ath11k *ar, struct nlattr *tb[]) -++{ -++ struct ath11k_pdev_wmi *wmi = ar->wmi; -++ struct ath11k_base *ab = ar->ab; -++ struct sk_buff *skb; -++ u32 cmd_id, buf_len, hdr_info; -++ int ret; -++ void *buf; -++ u8 segnumber = 0, seginfo; -++ u16 chunk_len, total_bytes, num_segments; -++ u8 *bufpos; -++ struct wmi_ftm_cmd *ftm_cmd; -++ -++ set_bit(ATH11K_FLAG_FTM_SEGMENTED, &ab->dev_flags); -++ -++ mutex_lock(&ar->conf_mutex); -++ -++ if (ar->state != ATH11K_STATE_FTM) { -++ ret = -ENETDOWN; -++ goto out; -++ } -++ -++ if (!tb[ATH11K_TM_ATTR_DATA]) { -++ ret = -EINVAL; -++ goto out; -++ } -++ -++ buf = nla_data(tb[ATH11K_TM_ATTR_DATA]); -++ buf_len = nla_len(tb[ATH11K_TM_ATTR_DATA]); -++ cmd_id = WMI_PDEV_UTF_CMDID; -++ -++ ath11k_dbg(ar->ab, ATH11K_DBG_TESTMODE, -++ "cmd wmi ftm cmd_id %d buffer length %d\n", -++ cmd_id, buf_len); -++ ath11k_dbg_dump(ar->ab, ATH11K_DBG_TESTMODE, NULL, "", buf, buf_len); -++ -++ bufpos = buf; -++ total_bytes = buf_len; -++ num_segments = total_bytes / MAX_WMI_UTF_LEN; -++ -++ if (buf_len - (num_segments * MAX_WMI_UTF_LEN)) -++ num_segments++; -++ -++ while (buf_len) { -++ chunk_len = min_t(u16, buf_len, MAX_WMI_UTF_LEN); -++ -++ skb = ath11k_wmi_alloc_skb(wmi->wmi_ab, (chunk_len + -++ sizeof(struct wmi_ftm_cmd))); -++ if (!skb) { -++ ret = -ENOMEM; -++ goto out; -++ } -++ -++ ftm_cmd = (struct wmi_ftm_cmd *)skb->data; -++ hdr_info = FIELD_PREP(WMI_TLV_TAG, WMI_TAG_ARRAY_BYTE) | -++ FIELD_PREP(WMI_TLV_LEN, (chunk_len + -++ sizeof(struct wmi_ftm_seg_hdr))); -++ ftm_cmd->tlv_header = hdr_info; -++ ftm_cmd->seg_hdr.len = total_bytes; -++ ftm_cmd->seg_hdr.msgref = ar->ftm_msgref; -++ seginfo = FIELD_PREP(ATH11K_FTM_SEGHDR_TOTAL_SEGMENTS, num_segments) | -++ FIELD_PREP(ATH11K_FTM_SEGHDR_CURRENT_SEQ, segnumber); -++ ftm_cmd->seg_hdr.segmentinfo = seginfo; -++ segnumber++; -++ -++ memcpy(&ftm_cmd->data, bufpos, chunk_len); -++ -++ ret = ath11k_wmi_cmd_send(wmi, skb, cmd_id); -++ if (ret) { -++ ath11k_warn(ar->ab, "failed to send wmi ftm command: %d\n", ret); -++ goto out; -++ } -++ -++ buf_len -= chunk_len; -++ bufpos += chunk_len; -++ } -++ -++ ar->ftm_msgref++; -++ ret = 0; -++ -++out: -++ mutex_unlock(&ar->conf_mutex); -++ return ret; -++} -++ -+ int ath11k_tm_cmd(struct ieee80211_hw *hw, struct ieee80211_vif *vif, -+ void *data, int len) -+ { -+@@ -131,6 +461,10 @@ int ath11k_tm_cmd(struct ieee80211_hw *h -+ return ath11k_tm_cmd_get_version(ar, tb); -+ case ATH11K_TM_CMD_WMI: -+ return ath11k_tm_cmd_wmi(ar, tb); -++ case ATH11K_TM_CMD_TESTMODE_START: -++ return ath11k_tm_cmd_testmode_start(ar, tb); -++ case ATH11K_TM_CMD_WMI_FTM: -++ return ath11k_tm_cmd_wmi_ftm(ar, tb); -+ default: -+ return -EOPNOTSUPP; -+ } -+--- a/drivers/net/wireless/ath/ath11k/testmode.h -++++ b/drivers/net/wireless/ath/ath11k/testmode.h -+@@ -8,11 +8,17 @@ -+ -+ #ifdef CPTCFG_NL80211_TESTMODE -+ -++void ath11k_tm_wmi_event(struct ath11k_base *ab, u32 cmd_id, struct sk_buff *skb); -+ int ath11k_tm_cmd(struct ieee80211_hw *hw, struct ieee80211_vif *vif, -+ void *data, int len); -+ -+ #else -+ -++static inline void ath11k_tm_wmi_event(struct ath11k_base *ab, u32 cmd_id, -++ struct sk_buff *skb) -++{ -++} -++ -+ static inline int ath11k_tm_cmd(struct ieee80211_hw *hw, -+ struct ieee80211_vif *vif, -+ void *data, int len) -+--- a/drivers/net/wireless/ath/ath11k/testmode_i.h -++++ b/drivers/net/wireless/ath/ath11k/testmode_i.h -+@@ -1,6 +1,7 @@ -+ /* SPDX-License-Identifier: BSD-3-Clause-Clear */ -+ /* -+ * Copyright (c) 2018-2019 The Linux Foundation. All rights reserved. -++ * Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights reserved. -+ */ -+ -+ /* "API" level of the ath11k testmode interface. Bump it after every -+@@ -11,9 +12,10 @@ -+ /* Bump this after every _compatible_ interface change, for example -+ * addition of a new command or an attribute. -+ */ -+-#define ATH11K_TESTMODE_VERSION_MINOR 0 -++#define ATH11K_TESTMODE_VERSION_MINOR 1 -+ -+ #define ATH11K_TM_DATA_MAX_LEN 5000 -++#define ATH11K_FTM_EVENT_MAX_BUF_LENGTH 2048 -+ -+ enum ath11k_tm_attr { -+ __ATH11K_TM_ATTR_INVALID = 0, -+@@ -47,4 +49,18 @@ enum ath11k_tm_cmd { -+ * ATH11K_TM_ATTR_DATA. -+ */ -+ ATH11K_TM_CMD_WMI = 1, -++ -++ /* Boots the UTF firmware, the netdev interface must be down at the -++ * time. -++ */ -++ ATH11K_TM_CMD_TESTMODE_START = 2, -++ -++ /* The command used to transmit a FTM WMI command to the firmware -++ * and the event to receive WMI events from the firmware. The data -++ * received only contain the payload, need to add the tlv header -++ * and send the cmd to firmware with command id WMI_PDEV_UTF_CMDID. -++ * The data payload size could be large and the driver needs to -++ * send segmented data to firmware. -++ */ -++ ATH11K_TM_CMD_WMI_FTM = 3, -+ }; -+--- a/drivers/net/wireless/ath/ath11k/wmi.c -++++ b/drivers/net/wireless/ath/ath11k/wmi.c -+@@ -1,7 +1,7 @@ -+ // SPDX-License-Identifier: BSD-3-Clause-Clear -+ /* -+ * Copyright (c) 2018-2019 The Linux Foundation. All rights reserved. -+- * Copyright (c) 2021, Qualcomm Innovation Center, Inc. All rights reserved. -++ * Copyright (c) 2021, 2023 Qualcomm Innovation Center, Inc. All rights reserved. -+ */ -+ #include -+ #include -+@@ -19,6 +19,7 @@ -+ #include "mac.h" -+ #include "hw.h" -+ #include "peer.h" -++#include "testmode.h" -+ -+ struct wmi_tlv_policy { -+ size_t min_len; -+@@ -237,9 +238,8 @@ static int ath11k_wmi_tlv_parse(struct a -+ (void *)tb); -+ } -+ -+-static const void ** -+-ath11k_wmi_tlv_parse_alloc(struct ath11k_base *ab, const void *ptr, -+- size_t len, gfp_t gfp) -++const void **ath11k_wmi_tlv_parse_alloc(struct ath11k_base *ab, const void *ptr, -++ size_t len, gfp_t gfp) -+ { -+ const void **tb; -+ int ret; -+@@ -8628,6 +8628,9 @@ static void ath11k_wmi_tlv_op_rx(struct -+ case WMI_PDEV_CSA_SWITCH_COUNT_STATUS_EVENTID: -+ ath11k_wmi_pdev_csa_switch_count_status_event(ab, skb); -+ break; -++ case WMI_PDEV_UTF_EVENTID: -++ ath11k_tm_wmi_event(ab, id, skb); -++ break; -+ case WMI_PDEV_TEMPERATURE_EVENTID: -+ ath11k_wmi_pdev_temperature_event(ab, skb); -+ break; -+--- a/drivers/net/wireless/ath/ath11k/wmi.h -++++ b/drivers/net/wireless/ath/ath11k/wmi.h -+@@ -1,6 +1,7 @@ -+ /* SPDX-License-Identifier: BSD-3-Clause-Clear */ -+ /* -+ * Copyright (c) 2018-2019 The Linux Foundation. All rights reserved. -++ * Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights reserved. -+ */ -+ -+ #ifndef ATH11K_WMI_H -+@@ -68,6 +69,7 @@ struct wmi_tlv { -+ -+ #define WMI_APPEND_TO_EXISTING_CHAN_LIST_FLAG 1 -+ -++#define MAX_WMI_UTF_LEN 252 -+ #define WMI_BA_MODE_BUFFER_SIZE_256 3 -+ /* -+ * HW mode config type replicated from FW header -+@@ -3564,6 +3566,24 @@ struct wmi_get_pdev_temperature_cmd { -+ u32 pdev_id; -+ } __packed; -+ -++struct wmi_ftm_seg_hdr { -++ u32 len; -++ u32 msgref; -++ u32 segmentinfo; -++ u32 pdev_id; -++} __packed; -++ -++struct wmi_ftm_cmd { -++ u32 tlv_header; -++ struct wmi_ftm_seg_hdr seg_hdr; -++ u8 data[]; -++} __packed; -++ -++struct wmi_ftm_event_msg { -++ struct wmi_ftm_seg_hdr seg_hdr; -++ u8 data[]; -++} __packed; -++ -+ #define WMI_BEACON_TX_BUFFER_SIZE 512 -+ -+ #define WMI_EMA_TMPL_IDX_SHIFT 8 -+@@ -6300,6 +6320,8 @@ enum wmi_sta_keepalive_method { -+ #define WMI_STA_KEEPALIVE_INTERVAL_DEFAULT 30 -+ #define WMI_STA_KEEPALIVE_INTERVAL_DISABLE 0 -+ -++const void **ath11k_wmi_tlv_parse_alloc(struct ath11k_base *ab, const void *ptr, -++ size_t len, gfp_t gfp); -+ int ath11k_wmi_cmd_send(struct ath11k_pdev_wmi *wmi, struct sk_buff *skb, -+ u32 cmd_id); -+ struct sk_buff *ath11k_wmi_alloc_skb(struct ath11k_wmi_base *wmi_sc, u32 len); -+--- a/drivers/net/wireless/ath/ath11k/wow.c -++++ b/drivers/net/wireless/ath/ath11k/wow.c -+@@ -1,7 +1,7 @@ -+ // SPDX-License-Identifier: BSD-3-Clause-Clear -+ /* -+ * Copyright (c) 2020 The Linux Foundation. All rights reserved. -+- * Copyright (c) 2022, Qualcomm Innovation Center, Inc. All rights reserved. -++ * Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved. -+ */ -+ -+ #include -+@@ -838,6 +838,7 @@ exit: -+ case ATH11K_STATE_RESTARTING: -+ case ATH11K_STATE_RESTARTED: -+ case ATH11K_STATE_WEDGED: -++ case ATH11K_STATE_FTM: -+ ath11k_warn(ar->ab, "encountered unexpected device state %d on resume, cannot recover\n", -+ ar->state); -+ ret = -EIO; -diff --git a/package/kernel/mac80211/patches/ath11k/0083-wifi-ath11k-Allow-ath11k-to-boot-without-caldata-in-.patch b/package/kernel/mac80211/patches/ath11k/0083-wifi-ath11k-Allow-ath11k-to-boot-without-caldata-in-.patch -new file mode 100644 -index 0000000000..5a1fa88294 ---- /dev/null -+++ b/package/kernel/mac80211/patches/ath11k/0083-wifi-ath11k-Allow-ath11k-to-boot-without-caldata-in-.patch -@@ -0,0 +1,47 @@ -+From 8aeba427296bff6a6051686f1d139c89a0b00e4c Mon Sep 17 00:00:00 2001 -+From: Sowmiya Sree Elavalagan -+Date: Fri, 26 May 2023 12:41:07 +0300 -+Subject: [PATCH 84/84] wifi: ath11k: Allow ath11k to boot without caldata in -+ ftm mode -+ -+Currently, if ath11k is unable to load the calibration data file it will -+always exit. However the calibration data may not be present in factory -+test mode, so update the logic to allow the driver to execute in FTM mode -+even if downloading the calibration data fails. -+ -+Tested-on : IPQ8074 hw2.0 AHB WLAN.HK.2.7.0.1-01744-QCAHKSWPL_SILICONZ-1 -+ -+Signed-off-by: Sowmiya Sree Elavalagan -+Signed-off-by: Raj Kumar Bhagat -+Signed-off-by: Kalle Valo -+Link: https://lore.kernel.org/r/20230517135934.16408-5-quic_rajkbhag@quicinc.com -+--- -+ drivers/net/wireless/ath/ath11k/qmi.c | 10 +++++++++- -+ 1 file changed, 9 insertions(+), 1 deletion(-) -+ -+--- a/drivers/net/wireless/ath/ath11k/qmi.c -++++ b/drivers/net/wireless/ath/ath11k/qmi.c -+@@ -1,7 +1,7 @@ -+ // SPDX-License-Identifier: BSD-3-Clause-Clear -+ /* -+ * Copyright (c) 2018-2019 The Linux Foundation. All rights reserved. -+- * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved. -++ * Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved. -+ */ -+ -+ #include -+@@ -2460,6 +2460,14 @@ static int ath11k_qmi_load_bdf_qmi(struc -+ -+ fw_entry = ath11k_core_firmware_request(ab, ATH11K_DEFAULT_CAL_FILE); -+ if (IS_ERR(fw_entry)) { -++ /* Caldata may not be present during first time calibration in -++ * factory hence allow to boot without loading caldata in ftm mode -++ */ -++ if (ath11k_ftm_mode) { -++ ath11k_info(ab, -++ "Booting without cal data file in factory test mode\n"); -++ return 0; -++ } -+ ret = PTR_ERR(fw_entry); -+ ath11k_warn(ab, -+ "qmi failed to load CAL data file:%s\n", -diff --git a/package/kernel/mac80211/patches/ath11k/0084-wifi-ath11k-Add-HTT-stats-for-PHY-reset-case.patch b/package/kernel/mac80211/patches/ath11k/0084-wifi-ath11k-Add-HTT-stats-for-PHY-reset-case.patch -new file mode 100644 -index 0000000000..946f5f7b57 ---- /dev/null -+++ b/package/kernel/mac80211/patches/ath11k/0084-wifi-ath11k-Add-HTT-stats-for-PHY-reset-case.patch -@@ -0,0 +1,261 @@ -+From 2d4f9093e2d8531ad0a2bb98fe5b36dc8addf2a2 Mon Sep 17 00:00:00 2001 -+From: Nidhi Jain -+Date: Fri, 26 May 2023 12:41:07 +0300 -+Subject: [PATCH] wifi: ath11k: Add HTT stats for PHY reset case -+ -+New HTT stats are added with stats type 37 to -+provide PHY reset stats and PHY reset counter stats. -+ -+PHY reset stats are used to display the current -+PHY-related operation information such as band, CCA -+threshold, current operating channel etc., -+ -+PHY reset counter stats are used to display the -+PHY reset counter values like calibration counts, -+temperature based recalibration counts etc., -+ -+Usage: -+echo 37 > /sys/kernel/debug/ieee80211/phyX/ath11k/htt_stats_type -+cat /sys/kernel/debug/ieee80211/phyx/ath11k/htt_stats -+ -+Output: -+ -+HTT_PHY_RESET_STATS_TLV: -+pdev_id = 0 -+chan_mhz = 5180 -+chan_band_center_freq1 = 5210 -+chan_band_center_freq2 = 0 -+chan_phy_mode = 18 -+chan_flags = 0x8 -+chan_num = 36 -+reset_cause = 0x50000 -+prev_reset_cause = 0x50000 -+phy_warm_reset_src = 0x0 -+rx_gain_tbl_mode = 0 -+xbar_val = 0xfac688 -+force_calibration = 0 -+phyrf_mode = 0 -+phy_homechan = 0 -+phy_tx_ch_mask = 0x3 -+phy_rx_ch_mask = 0x3 -+phybb_ini_mask = 0x5 -+phyrf_ini_mask = 0x0 -+phy_dfs_en_mask = 0x0 -+phy_sscan_en_mask = 0x0 -+phy_synth_sel_mask = 0x0 -+phy_adfs_freq = 0 -+cck_fir_settings = 0x0 -+phy_dyn_pri_chan = 6 -+cca_thresh = 0x26232020 -+dyn_cca_status = 0 -+rxdesense_thresh_hw = 0xcfe0afe -+rxdesense_thresh_sw = 0xcfe0afe -+ -+HTT_PHY_RESET_COUNTERS_TLV: -+pdev_id = 0 -+cf_active_low_fail_cnt = 0 -+cf_active_low_pass_cnt = 0 -+phy_off_through_vreg_cnt = 0 -+force_calibration_cnt = 0 -+rf_mode_switch_phy_off_cnt = 0 -+ -+Tested-on: IPQ8074 hw2.0 AHB WLAN.HK.2.7.0.1-01744-QCAHKSWPL_SILICONZ-1 -+ -+Signed-off-by: Nidhi Jain -+Signed-off-by: Maharaja Kennadyrajan -+Signed-off-by: Kalle Valo -+Link: https://lore.kernel.org/r/20230517141242.2754293-1-quic_mkenna@quicinc.com -+--- -+ .../wireless/ath/ath11k/debugfs_htt_stats.c | 114 ++++++++++++++++++ -+ .../wireless/ath/ath11k/debugfs_htt_stats.h | 43 +++++++ -+ 2 files changed, 157 insertions(+) -+ -+--- a/drivers/net/wireless/ath/ath11k/debugfs_htt_stats.c -++++ b/drivers/net/wireless/ath/ath11k/debugfs_htt_stats.c -+@@ -4011,6 +4011,114 @@ void htt_print_phy_stats_tlv(const void -+ stats_req->buf_len = len; -+ } -+ -++static inline void -++htt_print_phy_reset_counters_tlv(const void *tag_buf, -++ u16 tag_len, -++ struct debug_htt_stats_req *stats_req) -++{ -++ const struct htt_phy_reset_counters_tlv *htt_stats_buf = tag_buf; -++ u8 *buf = stats_req->buf; -++ u32 len = stats_req->buf_len; -++ u32 buf_len = ATH11K_HTT_STATS_BUF_SIZE; -++ -++ if (tag_len < sizeof(*htt_stats_buf)) -++ return; -++ -++ len += scnprintf(buf + len, buf_len - len, "HTT_PHY_RESET_COUNTERS_TLV:\n"); -++ -++ len += scnprintf(buf + len, buf_len - len, "pdev_id = %u\n", -++ htt_stats_buf->pdev_id); -++ len += scnprintf(buf + len, buf_len - len, "cf_active_low_fail_cnt = %u\n", -++ htt_stats_buf->cf_active_low_fail_cnt); -++ len += scnprintf(buf + len, buf_len - len, "cf_active_low_pass_cnt = %u\n", -++ htt_stats_buf->cf_active_low_pass_cnt); -++ len += scnprintf(buf + len, buf_len - len, "phy_off_through_vreg_cnt = %u\n", -++ htt_stats_buf->phy_off_through_vreg_cnt); -++ len += scnprintf(buf + len, buf_len - len, "force_calibration_cnt = %u\n", -++ htt_stats_buf->force_calibration_cnt); -++ len += scnprintf(buf + len, buf_len - len, "rf_mode_switch_phy_off_cnt = %u\n", -++ htt_stats_buf->rf_mode_switch_phy_off_cnt); -++ -++ stats_req->buf_len = len; -++} -++ -++static inline void -++htt_print_phy_reset_stats_tlv(const void *tag_buf, -++ u16 tag_len, -++ struct debug_htt_stats_req *stats_req) -++{ -++ const struct htt_phy_reset_stats_tlv *htt_stats_buf = tag_buf; -++ u8 *buf = stats_req->buf; -++ u32 len = stats_req->buf_len; -++ u32 buf_len = ATH11K_HTT_STATS_BUF_SIZE; -++ -++ if (tag_len < sizeof(*htt_stats_buf)) -++ return; -++ -++ len += scnprintf(buf + len, buf_len - len, "HTT_PHY_RESET_STATS_TLV:\n"); -++ -++ len += scnprintf(buf + len, buf_len - len, "pdev_id = %u\n", -++ htt_stats_buf->pdev_id); -++ len += scnprintf(buf + len, buf_len - len, "chan_mhz = %u\n", -++ htt_stats_buf->chan_mhz); -++ len += scnprintf(buf + len, buf_len - len, "chan_band_center_freq1 = %u\n", -++ htt_stats_buf->chan_band_center_freq1); -++ len += scnprintf(buf + len, buf_len - len, "chan_band_center_freq2 = %u\n", -++ htt_stats_buf->chan_band_center_freq2); -++ len += scnprintf(buf + len, buf_len - len, "chan_phy_mode = %u\n", -++ htt_stats_buf->chan_phy_mode); -++ len += scnprintf(buf + len, buf_len - len, "chan_flags = 0x%0x\n", -++ htt_stats_buf->chan_flags); -++ len += scnprintf(buf + len, buf_len - len, "chan_num = %u\n", -++ htt_stats_buf->chan_num); -++ len += scnprintf(buf + len, buf_len - len, "reset_cause = 0x%0x\n", -++ htt_stats_buf->reset_cause); -++ len += scnprintf(buf + len, buf_len - len, "prev_reset_cause = 0x%0x\n", -++ htt_stats_buf->prev_reset_cause); -++ len += scnprintf(buf + len, buf_len - len, "phy_warm_reset_src = 0x%0x\n", -++ htt_stats_buf->phy_warm_reset_src); -++ len += scnprintf(buf + len, buf_len - len, "rx_gain_tbl_mode = %d\n", -++ htt_stats_buf->rx_gain_tbl_mode); -++ len += scnprintf(buf + len, buf_len - len, "xbar_val = 0x%0x\n", -++ htt_stats_buf->xbar_val); -++ len += scnprintf(buf + len, buf_len - len, "force_calibration = %u\n", -++ htt_stats_buf->force_calibration); -++ len += scnprintf(buf + len, buf_len - len, "phyrf_mode = %u\n", -++ htt_stats_buf->phyrf_mode); -++ len += scnprintf(buf + len, buf_len - len, "phy_homechan = %u\n", -++ htt_stats_buf->phy_homechan); -++ len += scnprintf(buf + len, buf_len - len, "phy_tx_ch_mask = 0x%0x\n", -++ htt_stats_buf->phy_tx_ch_mask); -++ len += scnprintf(buf + len, buf_len - len, "phy_rx_ch_mask = 0x%0x\n", -++ htt_stats_buf->phy_rx_ch_mask); -++ len += scnprintf(buf + len, buf_len - len, "phybb_ini_mask = 0x%0x\n", -++ htt_stats_buf->phybb_ini_mask); -++ len += scnprintf(buf + len, buf_len - len, "phyrf_ini_mask = 0x%0x\n", -++ htt_stats_buf->phyrf_ini_mask); -++ len += scnprintf(buf + len, buf_len - len, "phy_dfs_en_mask = 0x%0x\n", -++ htt_stats_buf->phy_dfs_en_mask); -++ len += scnprintf(buf + len, buf_len - len, "phy_sscan_en_mask = 0x%0x\n", -++ htt_stats_buf->phy_sscan_en_mask); -++ len += scnprintf(buf + len, buf_len - len, "phy_synth_sel_mask = 0x%0x\n", -++ htt_stats_buf->phy_synth_sel_mask); -++ len += scnprintf(buf + len, buf_len - len, "phy_adfs_freq = %u\n", -++ htt_stats_buf->phy_adfs_freq); -++ len += scnprintf(buf + len, buf_len - len, "cck_fir_settings = 0x%0x\n", -++ htt_stats_buf->cck_fir_settings); -++ len += scnprintf(buf + len, buf_len - len, "phy_dyn_pri_chan = %u\n", -++ htt_stats_buf->phy_dyn_pri_chan); -++ len += scnprintf(buf + len, buf_len - len, "cca_thresh = 0x%0x\n", -++ htt_stats_buf->cca_thresh); -++ len += scnprintf(buf + len, buf_len - len, "dyn_cca_status = %u\n", -++ htt_stats_buf->dyn_cca_status); -++ len += scnprintf(buf + len, buf_len - len, "rxdesense_thresh_hw = 0x%x\n", -++ htt_stats_buf->rxdesense_thresh_hw); -++ len += scnprintf(buf + len, buf_len - len, "rxdesense_thresh_sw = 0x%x\n", -++ htt_stats_buf->rxdesense_thresh_sw); -++ -++ stats_req->buf_len = len; -++} -++ -+ static inline -+ void htt_print_peer_ctrl_path_txrx_stats_tlv(const void *tag_buf, -+ struct debug_htt_stats_req *stats_req) -+@@ -4425,6 +4533,12 @@ static int ath11k_dbg_htt_ext_stats_pars -+ case HTT_STATS_PHY_STATS_TAG: -+ htt_print_phy_stats_tlv(tag_buf, stats_req); -+ break; -++ case HTT_STATS_PHY_RESET_COUNTERS_TAG: -++ htt_print_phy_reset_counters_tlv(tag_buf, len, stats_req); -++ break; -++ case HTT_STATS_PHY_RESET_STATS_TAG: -++ htt_print_phy_reset_stats_tlv(tag_buf, len, stats_req); -++ break; -+ case HTT_STATS_PEER_CTRL_PATH_TXRX_STATS_TAG: -+ htt_print_peer_ctrl_path_txrx_stats_tlv(tag_buf, stats_req); -+ break; -+--- a/drivers/net/wireless/ath/ath11k/debugfs_htt_stats.h -++++ b/drivers/net/wireless/ath/ath11k/debugfs_htt_stats.h -+@@ -111,6 +111,8 @@ enum htt_tlv_tag_t { -+ HTT_STATS_TXBF_OFDMA_STEER_STATS_TAG = 116, -+ HTT_STATS_PHY_COUNTERS_TAG = 121, -+ HTT_STATS_PHY_STATS_TAG = 122, -++ HTT_STATS_PHY_RESET_COUNTERS_TAG = 123, -++ HTT_STATS_PHY_RESET_STATS_TAG = 124, -+ -+ HTT_STATS_MAX_TAG, -+ }; -+@@ -1964,6 +1966,47 @@ struct htt_phy_stats_tlv { -+ u32 fw_run_time; -+ }; -+ -++struct htt_phy_reset_counters_tlv { -++ u32 pdev_id; -++ u32 cf_active_low_fail_cnt; -++ u32 cf_active_low_pass_cnt; -++ u32 phy_off_through_vreg_cnt; -++ u32 force_calibration_cnt; -++ u32 rf_mode_switch_phy_off_cnt; -++}; -++ -++struct htt_phy_reset_stats_tlv { -++ u32 pdev_id; -++ u32 chan_mhz; -++ u32 chan_band_center_freq1; -++ u32 chan_band_center_freq2; -++ u32 chan_phy_mode; -++ u32 chan_flags; -++ u32 chan_num; -++ u32 reset_cause; -++ u32 prev_reset_cause; -++ u32 phy_warm_reset_src; -++ u32 rx_gain_tbl_mode; -++ u32 xbar_val; -++ u32 force_calibration; -++ u32 phyrf_mode; -++ u32 phy_homechan; -++ u32 phy_tx_ch_mask; -++ u32 phy_rx_ch_mask; -++ u32 phybb_ini_mask; -++ u32 phyrf_ini_mask; -++ u32 phy_dfs_en_mask; -++ u32 phy_sscan_en_mask; -++ u32 phy_synth_sel_mask; -++ u32 phy_adfs_freq; -++ u32 cck_fir_settings; -++ u32 phy_dyn_pri_chan; -++ u32 cca_thresh; -++ u32 dyn_cca_status; -++ u32 rxdesense_thresh_hw; -++ u32 rxdesense_thresh_sw; -++}; -++ -+ struct htt_peer_ctrl_path_txrx_stats_tlv { -+ /* peer mac address */ -+ u8 peer_mac_addr[ETH_ALEN]; -diff --git a/package/kernel/mac80211/patches/ath11k/100-wifi-ath11k-use-unique-QRTR-instance-ID.patch b/package/kernel/mac80211/patches/ath11k/100-wifi-ath11k-use-unique-QRTR-instance-ID.patch -new file mode 100644 -index 0000000000..39d5a61d5a ---- /dev/null -+++ b/package/kernel/mac80211/patches/ath11k/100-wifi-ath11k-use-unique-QRTR-instance-ID.patch -@@ -0,0 +1,162 @@ -+From 534a5f99d589cfa6b244b4433c192b6a278a67ff Mon Sep 17 00:00:00 2001 -+From: Robert Marko -+Date: Sat, 5 Nov 2022 20:15:40 +0100 -+Subject: [PATCH] wifi: ath11k: use unique QRTR instance ID -+ -+Currently, trying to use AHB + PCI/MHI cards or multiple PCI/MHI cards -+will cause a clash in the QRTR instance node ID and prevent the driver -+from talking via QMI to the card and thus initializing it with: -+[ 9.836329] ath11k c000000.wifi: host capability request failed: 1 90 -+[ 9.842047] ath11k c000000.wifi: failed to send qmi host cap: -22 -+ -+So, in order to allow for this combination of cards, especially AHB + PCI -+cards like IPQ8074 + QCN9074 (Used by me and tested on) set the desired -+QRTR instance ID offset by calculating a unique one based on PCI domain -+and bus ID-s and writing it to bits 7-0 of BHI_ERRDBG2 MHI register by -+using the SBL state callback that is added as part of the series. -+We also have to make sure that new QRTR offset is added on top of the -+default QRTR instance ID-s that are currently used in the driver. -+ -+This finally allows using AHB + PCI or multiple PCI cards on the same -+system. -+ -+Since this is not supported on QCA6390 and like, its limited to QCN9074 -+which is known to support changing QRTR instance ID. -+ -+Before: -+root@OpenWrt:/# qrtr-lookup -+ Service Version Instance Node Port -+ 1054 1 0 7 1 -+ 69 1 2 7 3 ATH10k WLAN firmware service -+ -+After: -+root@OpenWrt:/# qrtr-lookup -+ Service Version Instance Node Port -+ 1054 1 0 7 1 -+ 69 1 2 7 3 ATH10k WLAN firmware service -+ 15 1 0 8 1 Test service -+ 69 1 8 8 2 ATH10k WLAN firmware service -+ -+Tested-on: IPQ8074 hw2.0 AHB WLAN.HK.2.5.0.1-01208-QCAHKSWPL_SILICONZ-1 -+Tested-on: QCN9074 hw1.0 PCI WLAN.HK.2.5.0.1-01208-QCAHKSWPL_SILICONZ-1 -+ -+Signed-off-by: Robert Marko -+--- -+ drivers/net/wireless/ath/ath11k/mhi.c | 49 ++++++++++++++++++--------- -+ drivers/net/wireless/ath/ath11k/mhi.h | 3 ++ -+ drivers/net/wireless/ath/ath11k/pci.c | 9 ++++- -+ 3 files changed, 44 insertions(+), 17 deletions(-) -+ -+--- a/drivers/net/wireless/ath/ath11k/mhi.c -++++ b/drivers/net/wireless/ath/ath11k/mhi.c -+@@ -294,6 +294,34 @@ static void ath11k_mhi_op_runtime_put(st -+ { -+ } -+ -++static int ath11k_mhi_op_read_reg(struct mhi_controller *mhi_cntrl, -++ void __iomem *addr, -++ u32 *out) -++{ -++ *out = readl(addr); -++ -++ return 0; -++} -++ -++static void ath11k_mhi_op_write_reg(struct mhi_controller *mhi_cntrl, -++ void __iomem *addr, -++ u32 val) -++{ -++ writel(val, addr); -++} -++ -++static void ath11k_mhi_qrtr_instance_set(struct mhi_controller *mhi_cntrl) -++{ -++ struct ath11k_base *ab = dev_get_drvdata(mhi_cntrl->cntrl_dev); -++ -++ if (ab->hw_rev == ATH11K_HW_QCN9074_HW10) { -++ ath11k_mhi_op_write_reg(mhi_cntrl, -++ mhi_cntrl->bhi + BHI_ERRDBG2, -++ FIELD_PREP(QRTR_INSTANCE_MASK, -++ ab->qmi.service_ins_id - ab->hw_params.qmi_service_ins_id)); -++ } -++} -++ -+ static char *ath11k_mhi_op_callback_to_str(enum mhi_callback reason) -+ { -+ switch (reason) { -+@@ -315,6 +343,8 @@ static char *ath11k_mhi_op_callback_to_s -+ return "MHI_CB_FATAL_ERROR"; -+ case MHI_CB_BW_REQ: -+ return "MHI_CB_BW_REQ"; -++ case MHI_CB_EE_SBL_MODE: -++ return "MHI_CB_EE_SBL_MODE"; -+ default: -+ return "UNKNOWN"; -+ } -+@@ -336,27 +366,14 @@ static void ath11k_mhi_op_status_cb(stru -+ if (!(test_bit(ATH11K_FLAG_UNREGISTERING, &ab->dev_flags))) -+ queue_work(ab->workqueue_aux, &ab->reset_work); -+ break; -++ case MHI_CB_EE_SBL_MODE: -++ ath11k_mhi_qrtr_instance_set(mhi_cntrl); -++ break; -+ default: -+ break; -+ } -+ } -+ -+-static int ath11k_mhi_op_read_reg(struct mhi_controller *mhi_cntrl, -+- void __iomem *addr, -+- u32 *out) -+-{ -+- *out = readl(addr); -+- -+- return 0; -+-} -+- -+-static void ath11k_mhi_op_write_reg(struct mhi_controller *mhi_cntrl, -+- void __iomem *addr, -+- u32 val) -+-{ -+- writel(val, addr); -+-} -+- -+ static int ath11k_mhi_read_addr_from_dt(struct mhi_controller *mhi_ctrl) -+ { -+ struct device_node *np; -+--- a/drivers/net/wireless/ath/ath11k/mhi.h -++++ b/drivers/net/wireless/ath/ath11k/mhi.h -+@@ -16,6 +16,9 @@ -+ #define MHICTRL 0x38 -+ #define MHICTRL_RESET_MASK 0x2 -+ -++#define BHI_ERRDBG2 0x38 -++#define QRTR_INSTANCE_MASK GENMASK(7, 0) -++ -+ int ath11k_mhi_start(struct ath11k_pci *ar_pci); -+ void ath11k_mhi_stop(struct ath11k_pci *ar_pci); -+ int ath11k_mhi_register(struct ath11k_pci *ar_pci); -+--- a/drivers/net/wireless/ath/ath11k/pci.c -++++ b/drivers/net/wireless/ath/ath11k/pci.c -+@@ -370,13 +370,20 @@ static void ath11k_pci_sw_reset(struct a -+ static void ath11k_pci_init_qmi_ce_config(struct ath11k_base *ab) -+ { -+ struct ath11k_qmi_ce_cfg *cfg = &ab->qmi.ce_cfg; -++ struct ath11k_pci *ab_pci = ath11k_pci_priv(ab); -++ struct pci_bus *bus = ab_pci->pdev->bus; -+ -+ cfg->tgt_ce = ab->hw_params.target_ce_config; -+ cfg->tgt_ce_len = ab->hw_params.target_ce_count; -+ -+ cfg->svc_to_ce_map = ab->hw_params.svc_to_ce_map; -+ cfg->svc_to_ce_map_len = ab->hw_params.svc_to_ce_map_len; -+- ab->qmi.service_ins_id = ab->hw_params.qmi_service_ins_id; -++ -++ if (ab->hw_rev == ATH11K_HW_QCN9074_HW10) { -++ ab->qmi.service_ins_id = ab->hw_params.qmi_service_ins_id + -++ (((pci_domain_nr(bus) & 0xF) << 4) | (bus->number & 0xF)); -++ } else -++ ab->qmi.service_ins_id = ab->hw_params.qmi_service_ins_id; -+ -+ ath11k_ce_get_shadow_config(ab, &cfg->shadow_reg_v2, -+ &cfg->shadow_reg_v2_len); -diff --git a/package/kernel/mac80211/patches/ath11k/900-ath11k-control-thermal-support-via-symbol.patch b/package/kernel/mac80211/patches/ath11k/900-ath11k-control-thermal-support-via-symbol.patch -new file mode 100644 -index 0000000000..60720a721e ---- /dev/null -+++ b/package/kernel/mac80211/patches/ath11k/900-ath11k-control-thermal-support-via-symbol.patch -@@ -0,0 +1,66 @@ -+From 703d6551f71e7290619d6effe2a25a64e10538b7 Mon Sep 17 00:00:00 2001 -+From: Robert Marko -+Date: Thu, 15 Dec 2022 12:20:52 +0100 -+Subject: [PATCH] ath11k: control thermal support via symbol -+ -+Currently, thermal support will get built if CONFIG_THERMAL is reachable, -+however this is not suitable for OpenWrt as with ALL_KMODS being set to y -+ATH11K_THERMAL wont get selected and so hwmon and thermal kmods wont get -+pulled in resulting in a build-failure. -+ -+So, to avoid that, lets do what is already done for ath10k and add a -+config symbol into backports for enabling thermal support. -+ -+Signed-off-by: Robert Marko -+--- -+ drivers/net/wireless/ath/ath11k/Kconfig | 7 +++++++ -+ drivers/net/wireless/ath/ath11k/Makefile | 2 +- -+ drivers/net/wireless/ath/ath11k/thermal.h | 2 +- -+ local-symbols | 1 + -+ 4 files changed, 10 insertions(+), 2 deletions(-) -+ -+--- a/drivers/net/wireless/ath/ath11k/Kconfig -++++ b/drivers/net/wireless/ath/ath11k/Kconfig -+@@ -61,3 +61,10 @@ config ATH11K_SPECTRAL -+ Enable ath11k spectral scan support -+ -+ Say Y to enable access to the FFT/spectral data via debugfs. -++ -++config ATH11K_THERMAL -++ bool "ath11k thermal sensors and throttling support" -++ depends on ATH11K -++ depends on THERMAL -++ help -++ Enable ath11k thermal sensors and throttling support. -+--- a/drivers/net/wireless/ath/ath11k/Makefile -++++ b/drivers/net/wireless/ath/ath11k/Makefile -+@@ -22,7 +22,7 @@ ath11k-y += core.o \ -+ ath11k-$(CPTCFG_ATH11K_DEBUGFS) += debugfs.o debugfs_htt_stats.o debugfs_sta.o -+ ath11k-$(CPTCFG_NL80211_TESTMODE) += testmode.o -+ ath11k-$(CPTCFG_ATH11K_TRACING) += trace.o -+-ath11k-$(CONFIG_THERMAL) += thermal.o -++ath11k-$(CPTCFG_ATH11K_THERMAL) += thermal.o -+ ath11k-$(CPTCFG_ATH11K_SPECTRAL) += spectral.o -+ ath11k-$(CONFIG_PM) += wow.o -+ -+--- a/drivers/net/wireless/ath/ath11k/thermal.h -++++ b/drivers/net/wireless/ath/ath11k/thermal.h -+@@ -25,7 +25,7 @@ struct ath11k_thermal { -+ int temperature; -+ }; -+ -+-#if IS_REACHABLE(CONFIG_THERMAL) -++#if IS_REACHABLE(CPTCFG_ATH11K_THERMAL) -+ int ath11k_thermal_register(struct ath11k_base *sc); -+ void ath11k_thermal_unregister(struct ath11k_base *sc); -+ int ath11k_thermal_set_throttling(struct ath11k *ar, u32 throttle_state); -+--- a/local-symbols -++++ b/local-symbols -+@@ -174,6 +174,7 @@ ATH11K_DEBUG= -+ ATH11K_DEBUGFS= -+ ATH11K_TRACING= -+ ATH11K_SPECTRAL= -++ATH11K_THERMAL= -+ WLAN_VENDOR_ATMEL= -+ ATMEL= -+ PCI_ATMEL= -diff --git a/package/kernel/mac80211/patches/ath11k/901-wifi-ath11k-pci-fix-compilation-in-5.16-and-older.patch b/package/kernel/mac80211/patches/ath11k/901-wifi-ath11k-pci-fix-compilation-in-5.16-and-older.patch -new file mode 100644 -index 0000000000..7215656389 ---- /dev/null -+++ b/package/kernel/mac80211/patches/ath11k/901-wifi-ath11k-pci-fix-compilation-in-5.16-and-older.patch -@@ -0,0 +1,29 @@ -+From 04178918e7f6b5f34dde81ec79ee8a1ccace3be3 Mon Sep 17 00:00:00 2001 -+From: Robert Marko -+Date: Mon, 17 Oct 2022 11:45:03 +0200 -+Subject: [PATCH] wifi: ath11k: pci: fix compilation in 5.16 and older -+ -+Commit ("genirq/msi, treewide: Use a named struct for PCI/MSI attributes") -+changed the msi_desc structure a bit, however that is only available in -+kernels 5.17 and newer, so check for kernel version to allow compilation -+in 5.16 and older. -+ -+Signed-off-by: Robert Marko -+--- -+ drivers/net/wireless/ath/ath11k/pci.c | 4 ++++ -+ 1 file changed, 4 insertions(+) -+ -+--- a/drivers/net/wireless/ath/ath11k/pci.c -++++ b/drivers/net/wireless/ath/ath11k/pci.c -+@@ -458,7 +458,11 @@ static int ath11k_pci_alloc_msi(struct a -+ pci_read_config_dword(pci_dev, pci_dev->msi_cap + PCI_MSI_ADDRESS_LO, -+ &ab->pci.msi.addr_lo); -+ -++#if (LINUX_VERSION_CODE > KERNEL_VERSION(5, 17, 0)) -+ if (msi_desc->pci.msi_attrib.is_64) { -++#else -++ if (msi_desc->msi_attrib.is_64) { -++#endif -+ pci_read_config_dword(pci_dev, pci_dev->msi_cap + PCI_MSI_ADDRESS_HI, -+ &ab->pci.msi.addr_hi); -+ } else { -diff --git a/package/kernel/mac80211/patches/ath11k/902-ath11k-Disable-coldboot-calibration-for-IPQ8074.patch b/package/kernel/mac80211/patches/ath11k/902-ath11k-Disable-coldboot-calibration-for-IPQ8074.patch -new file mode 100644 -index 0000000000..5454fa75e4 ---- /dev/null -+++ b/package/kernel/mac80211/patches/ath11k/902-ath11k-Disable-coldboot-calibration-for-IPQ8074.patch -@@ -0,0 +1,24 @@ -+From dd3b9c59cfa1e9e0b73a575f4646be905691eaef Mon Sep 17 00:00:00 2001 -+From: Robert Marko -+Date: Sat, 16 Oct 2021 19:34:10 +0200 -+Subject: [PATCH 241/241] ath11k: Disable coldboot calibration for IPQ8074 -+ -+There is a bug with the remoteproc reset after coldboot calibration, -+so until that is resolved disabled it to allow using the radio. -+ -+Signed-off-by: Robert Marko -+--- -+ drivers/net/wireless/ath/ath11k/core.c | 2 +- -+ 1 file changed, 1 insertion(+), 1 deletion(-) -+ -+--- a/drivers/net/wireless/ath/ath11k/core.c -++++ b/drivers/net/wireless/ath/ath11k/core.c -+@@ -86,7 +86,7 @@ static const struct ath11k_hw_params ath -+ .supports_shadow_regs = false, -+ .idle_ps = false, -+ .supports_sta_ps = false, -+- .cold_boot_calib = true, -++ .cold_boot_calib = false, -+ .cbcal_restart_fw = true, -+ .fw_mem_mode = 0, -+ .num_vdevs = 16 + 1, -diff --git a/package/kernel/mac80211/patches/ath11k/903-ath11k-support-setting-FW-memory-mode-via-DT.patch b/package/kernel/mac80211/patches/ath11k/903-ath11k-support-setting-FW-memory-mode-via-DT.patch -new file mode 100644 -index 0000000000..22c2493ca9 ---- /dev/null -+++ b/package/kernel/mac80211/patches/ath11k/903-ath11k-support-setting-FW-memory-mode-via-DT.patch -@@ -0,0 +1,74 @@ -+From fb1c40c225cbc413d82c872dd8c8af3469b2b921 Mon Sep 17 00:00:00 2001 -+From: Robert Marko -+Date: Fri, 16 Dec 2022 17:17:52 +0100 -+Subject: [PATCH] ath11k: support setting FW memory mode via DT -+ -+ath11k is really memory intensive for devices with less that 1GB of RAM, -+so lets allow saving a significant amount of memory by setting the FW to -+Mode-1 via DTS for devices that need it. -+ -+However the drawback is reduced number of VDEV-s and peers which is a -+reasonable tradeoff. -+ -+Mode-2 allows for further reduction, but it has further restrictions. -+ -+While we are here, lets add a print to be able to easily determine what -+FW memory mode is being used. -+ -+Signed-off-by: Robert Marko -+--- -+ drivers/net/wireless/ath/ath11k/core.c | 28 ++++++++++++++++++++++++-- -+ 1 file changed, 26 insertions(+), 2 deletions(-) -+ -+--- a/drivers/net/wireless/ath/ath11k/core.c -++++ b/drivers/net/wireless/ath/ath11k/core.c -+@@ -36,7 +36,7 @@ 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_hw_params ath11k_hw_params[] = { -++static struct ath11k_hw_params ath11k_hw_params[] = { -+ { -+ .hw_rev = ATH11K_HW_IPQ8074, -+ .name = "ipq8074 hw2.0", -+@@ -1953,7 +1953,8 @@ static void ath11k_core_reset(struct wor -+ static int ath11k_init_hw_params(struct ath11k_base *ab) -+ { -+ const struct ath11k_hw_params *hw_params = NULL; -+- int i; -++ u32 fw_mem_mode; -++ int i, ret; -+ -+ for (i = 0; i < ARRAY_SIZE(ath11k_hw_params); i++) { -+ hw_params = &ath11k_hw_params[i]; -+@@ -1969,7 +1970,30 @@ static int ath11k_init_hw_params(struct -+ -+ ab->hw_params = *hw_params; -+ -++ ret = of_property_read_u32(ab->dev->of_node, -++ "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) { -++ ab->hw_params.fw_mem_mode = 1; -++ ab->hw_params.num_vdevs = 8; -++ ab->hw_params.num_peers = 128; -++ } else if (fw_mem_mode == 2) { -++ ab->hw_params.fw_mem_mode = 2; -++ ab->hw_params.num_vdevs = 8; -++ ab->hw_params.num_peers = 128; -++ ab->hw_params.cold_boot_calib = false; -++ } else -++ ath11k_info(ab, "Unsupported FW memory mode: %u\n", fw_mem_mode); -++ } -++ -+ ath11k_info(ab, "%s\n", ab->hw_params.name); -++ ath11k_info(ab, "FW memory mode: %d\n", ab->hw_params.fw_mem_mode); -+ -+ return 0; -+ } -diff --git a/package/kernel/mac80211/patches/ath11k/905-ath11k-remove-intersection-support-for-regulatory-ru.patch b/package/kernel/mac80211/patches/ath11k/905-ath11k-remove-intersection-support-for-regulatory-ru.patch -new file mode 100644 -index 0000000000..b0ceb00ba0 ---- /dev/null -+++ b/package/kernel/mac80211/patches/ath11k/905-ath11k-remove-intersection-support-for-regulatory-ru.patch -@@ -0,0 +1,317 @@ -+From abdd0985a36189ef2cc0e393b027276e86137ace Mon Sep 17 00:00:00 2001 -+From: Aditya Kumar Singh -+Date: Tue, 11 Apr 2023 20:08:49 +0200 -+Subject: [PATCH] ath11k: remove intersection support for regulatory rules -+ -+Currently, regulatory rules from new country settings is intersected with -+rules from default country settings(during initialisation) in order to prevent -+users to bypass their default country settings such as power limits, channel -+flags, etc. -+ -+However, the country setting in the BDF will take higher higher precendence -+and FW will protect it. Therefore, there is no need to handle intersection -+on the driver side now. -+ -+Remove regulatory rules intersection logic support. -+ -+Signed-off-by: Aditya Kumar Singh -+--- -+ drivers/net/wireless/ath/ath11k/reg.c | 168 +++----------------------- -+ drivers/net/wireless/ath/ath11k/reg.h | 2 +- -+ drivers/net/wireless/ath/ath11k/wmi.c | 24 +--- -+ 3 files changed, 16 insertions(+), 178 deletions(-) -+ -+--- a/drivers/net/wireless/ath/ath11k/reg.c -++++ b/drivers/net/wireless/ath/ath11k/reg.c -+@@ -352,129 +352,6 @@ static u32 ath11k_map_fw_reg_flags(u16 r -+ return flags; -+ } -+ -+-static bool -+-ath11k_reg_can_intersect(struct ieee80211_reg_rule *rule1, -+- struct ieee80211_reg_rule *rule2) -+-{ -+- u32 start_freq1, end_freq1; -+- u32 start_freq2, end_freq2; -+- -+- start_freq1 = rule1->freq_range.start_freq_khz; -+- start_freq2 = rule2->freq_range.start_freq_khz; -+- -+- end_freq1 = rule1->freq_range.end_freq_khz; -+- end_freq2 = rule2->freq_range.end_freq_khz; -+- -+- if ((start_freq1 >= start_freq2 && -+- start_freq1 < end_freq2) || -+- (start_freq2 > start_freq1 && -+- start_freq2 < end_freq1)) -+- return true; -+- -+- /* TODO: Should we restrict intersection feasibility -+- * based on min bandwidth of the intersected region also, -+- * say the intersected rule should have a min bandwidth -+- * of 20MHz? -+- */ -+- -+- return false; -+-} -+- -+-static void ath11k_reg_intersect_rules(struct ieee80211_reg_rule *rule1, -+- struct ieee80211_reg_rule *rule2, -+- struct ieee80211_reg_rule *new_rule) -+-{ -+- u32 start_freq1, end_freq1; -+- u32 start_freq2, end_freq2; -+- u32 freq_diff, max_bw; -+- -+- start_freq1 = rule1->freq_range.start_freq_khz; -+- start_freq2 = rule2->freq_range.start_freq_khz; -+- -+- end_freq1 = rule1->freq_range.end_freq_khz; -+- end_freq2 = rule2->freq_range.end_freq_khz; -+- -+- new_rule->freq_range.start_freq_khz = max_t(u32, start_freq1, -+- start_freq2); -+- new_rule->freq_range.end_freq_khz = min_t(u32, end_freq1, end_freq2); -+- -+- freq_diff = new_rule->freq_range.end_freq_khz - -+- new_rule->freq_range.start_freq_khz; -+- max_bw = min_t(u32, rule1->freq_range.max_bandwidth_khz, -+- rule2->freq_range.max_bandwidth_khz); -+- new_rule->freq_range.max_bandwidth_khz = min_t(u32, max_bw, freq_diff); -+- -+- new_rule->power_rule.max_antenna_gain = -+- min_t(u32, rule1->power_rule.max_antenna_gain, -+- rule2->power_rule.max_antenna_gain); -+- -+- new_rule->power_rule.max_eirp = min_t(u32, rule1->power_rule.max_eirp, -+- rule2->power_rule.max_eirp); -+- -+- /* Use the flags of both the rules */ -+- new_rule->flags = rule1->flags | rule2->flags; -+- -+- /* To be safe, lts use the max cac timeout of both rules */ -+- new_rule->dfs_cac_ms = max_t(u32, rule1->dfs_cac_ms, -+- rule2->dfs_cac_ms); -+-} -+- -+-static struct ieee80211_regdomain * -+-ath11k_regd_intersect(struct ieee80211_regdomain *default_regd, -+- struct ieee80211_regdomain *curr_regd) -+-{ -+- u8 num_old_regd_rules, num_curr_regd_rules, num_new_regd_rules; -+- struct ieee80211_reg_rule *old_rule, *curr_rule, *new_rule; -+- struct ieee80211_regdomain *new_regd = NULL; -+- u8 i, j, k; -+- -+- num_old_regd_rules = default_regd->n_reg_rules; -+- num_curr_regd_rules = curr_regd->n_reg_rules; -+- num_new_regd_rules = 0; -+- -+- /* Find the number of intersecting rules to allocate new regd memory */ -+- for (i = 0; i < num_old_regd_rules; i++) { -+- old_rule = default_regd->reg_rules + i; -+- for (j = 0; j < num_curr_regd_rules; j++) { -+- curr_rule = curr_regd->reg_rules + j; -+- -+- if (ath11k_reg_can_intersect(old_rule, curr_rule)) -+- num_new_regd_rules++; -+- } -+- } -+- -+- if (!num_new_regd_rules) -+- return NULL; -+- -+- new_regd = kzalloc(sizeof(*new_regd) + (num_new_regd_rules * -+- sizeof(struct ieee80211_reg_rule)), -+- GFP_ATOMIC); -+- -+- if (!new_regd) -+- return NULL; -+- -+- /* We set the new country and dfs region directly and only trim -+- * the freq, power, antenna gain by intersecting with the -+- * default regdomain. Also MAX of the dfs cac timeout is selected. -+- */ -+- new_regd->n_reg_rules = num_new_regd_rules; -+- memcpy(new_regd->alpha2, curr_regd->alpha2, sizeof(new_regd->alpha2)); -+- new_regd->dfs_region = curr_regd->dfs_region; -+- new_rule = new_regd->reg_rules; -+- -+- for (i = 0, k = 0; i < num_old_regd_rules; i++) { -+- old_rule = default_regd->reg_rules + i; -+- for (j = 0; j < num_curr_regd_rules; j++) { -+- curr_rule = curr_regd->reg_rules + j; -+- -+- if (ath11k_reg_can_intersect(old_rule, curr_rule)) -+- ath11k_reg_intersect_rules(old_rule, curr_rule, -+- (new_rule + k++)); -+- } -+- } -+- return new_regd; -+-} -+- -+ static const char * -+ ath11k_reg_get_regdom_str(enum nl80211_dfs_regions dfs_region) -+ { -+@@ -609,9 +486,9 @@ ath11k_reg_update_weather_radar_band(str -+ -+ struct ieee80211_regdomain * -+ ath11k_reg_build_regd(struct ath11k_base *ab, -+- struct cur_regulatory_info *reg_info, bool intersect) -++ struct cur_regulatory_info *reg_info) -+ { -+- struct ieee80211_regdomain *tmp_regd, *default_regd, *new_regd = NULL; -++ struct ieee80211_regdomain *new_regd = NULL; -+ struct cur_reg_rule *reg_rule; -+ u8 i = 0, j = 0, k = 0; -+ u8 num_rules; -+@@ -628,26 +505,26 @@ ath11k_reg_build_regd(struct ath11k_base -+ num_rules += reg_info->num_6ghz_rules_ap[WMI_REG_INDOOR_AP]; -+ -+ if (!num_rules) -+- goto ret; -++ return new_regd; -+ -+ /* Add max additional rules to accommodate weather radar band */ -+ if (reg_info->dfs_region == ATH11K_DFS_REG_ETSI) -+ num_rules += 2; -+ -+- tmp_regd = kzalloc(sizeof(*tmp_regd) + -++ new_regd = kzalloc(sizeof(*new_regd) + -+ (num_rules * sizeof(struct ieee80211_reg_rule)), -+ GFP_ATOMIC); -+- if (!tmp_regd) -+- goto ret; -++ if (!new_regd) -++ return new_regd; -+ -+- memcpy(tmp_regd->alpha2, reg_info->alpha2, REG_ALPHA2_LEN + 1); -++ memcpy(new_regd->alpha2, reg_info->alpha2, REG_ALPHA2_LEN + 1); -+ memcpy(alpha2, reg_info->alpha2, REG_ALPHA2_LEN + 1); -+ alpha2[2] = '\0'; -+- tmp_regd->dfs_region = ath11k_map_fw_dfs_region(reg_info->dfs_region); -++ new_regd->dfs_region = ath11k_map_fw_dfs_region(reg_info->dfs_region); -+ -+ ath11k_dbg(ab, ATH11K_DBG_REG, -+ "Country %s, CFG Regdomain %s FW Regdomain %d, num_reg_rules %d\n", -+- alpha2, ath11k_reg_get_regdom_str(tmp_regd->dfs_region), -++ alpha2, ath11k_reg_get_regdom_str(new_regd->dfs_region), -+ reg_info->dfs_region, num_rules); -+ /* Update reg_rules[] below. Firmware is expected to -+ * send these rules in order(2 GHz rules first and then 5 GHz) -+@@ -686,7 +563,7 @@ ath11k_reg_build_regd(struct ath11k_base -+ -+ flags |= ath11k_map_fw_reg_flags(reg_rule->flags); -+ -+- ath11k_reg_update_rule(tmp_regd->reg_rules + i, -++ ath11k_reg_update_rule(new_regd->reg_rules + i, -+ reg_rule->start_freq, -+ reg_rule->end_freq, max_bw, -+ reg_rule->ant_gain, reg_rule->reg_power, -+@@ -701,7 +578,7 @@ ath11k_reg_build_regd(struct ath11k_base -+ reg_info->dfs_region == ATH11K_DFS_REG_ETSI && -+ (reg_rule->end_freq > ETSI_WEATHER_RADAR_BAND_LOW && -+ reg_rule->start_freq < ETSI_WEATHER_RADAR_BAND_HIGH)){ -+- ath11k_reg_update_weather_radar_band(ab, tmp_regd, -++ ath11k_reg_update_weather_radar_band(ab, new_regd, -+ reg_rule, &i, -+ flags, max_bw); -+ continue; -+@@ -712,37 +589,20 @@ ath11k_reg_build_regd(struct ath11k_base -+ "\t%d. (%d - %d @ %d) (%d, %d) (%d ms) (FLAGS %d) (%d, %d)\n", -+ i + 1, reg_rule->start_freq, reg_rule->end_freq, -+ max_bw, reg_rule->ant_gain, reg_rule->reg_power, -+- tmp_regd->reg_rules[i].dfs_cac_ms, flags, -++ new_regd->reg_rules[i].dfs_cac_ms, flags, -+ reg_rule->psd_flag, reg_rule->psd_eirp); -+ } else { -+ ath11k_dbg(ab, ATH11K_DBG_REG, -+ "\t%d. (%d - %d @ %d) (%d, %d) (%d ms) (FLAGS %d)\n", -+ i + 1, reg_rule->start_freq, reg_rule->end_freq, -+ max_bw, reg_rule->ant_gain, reg_rule->reg_power, -+- tmp_regd->reg_rules[i].dfs_cac_ms, -++ new_regd->reg_rules[i].dfs_cac_ms, -+ flags); -+ } -+ } -+ -+- tmp_regd->n_reg_rules = i; -+- -+- if (intersect) { -+- default_regd = ab->default_regd[reg_info->phy_id]; -+- -+- /* Get a new regd by intersecting the received regd with -+- * our default regd. -+- */ -+- new_regd = ath11k_regd_intersect(default_regd, tmp_regd); -+- kfree(tmp_regd); -+- if (!new_regd) { -+- ath11k_warn(ab, "Unable to create intersected regdomain\n"); -+- goto ret; -+- } -+- } else { -+- new_regd = tmp_regd; -+- } -++ new_regd->n_reg_rules = i; -+ -+-ret: -+ return new_regd; -+ } -+ -+--- a/drivers/net/wireless/ath/ath11k/reg.h -++++ b/drivers/net/wireless/ath/ath11k/reg.h -+@@ -30,7 +30,7 @@ void ath11k_reg_free(struct ath11k_base -+ void ath11k_regd_update_work(struct work_struct *work); -+ struct ieee80211_regdomain * -+ ath11k_reg_build_regd(struct ath11k_base *ab, -+- struct cur_regulatory_info *reg_info, bool intersect); -++ struct cur_regulatory_info *reg_info); -+ int ath11k_regd_update(struct ath11k *ar); -+ int ath11k_reg_update_chan_list(struct ath11k *ar, bool wait); -+ #endif -+--- a/drivers/net/wireless/ath/ath11k/wmi.c -++++ b/drivers/net/wireless/ath/ath11k/wmi.c -+@@ -6996,24 +6996,12 @@ static void ath11k_wmi_htc_tx_complete(s -+ wake_up(&wmi->tx_ce_desc_wq); -+ } -+ -+-static bool ath11k_reg_is_world_alpha(char *alpha) -+-{ -+- if (alpha[0] == '0' && alpha[1] == '0') -+- return true; -+- -+- if (alpha[0] == 'n' && alpha[1] == 'a') -+- return true; -+- -+- return false; -+-} -+- -+ static int ath11k_reg_chan_list_event(struct ath11k_base *ab, -+ struct sk_buff *skb, -+ enum wmi_reg_chan_list_cmd_type id) -+ { -+ struct cur_regulatory_info *reg_info = NULL; -+ struct ieee80211_regdomain *regd = NULL; -+- bool intersect = false; -+ int ret = 0, pdev_idx, i, j; -+ struct ath11k *ar; -+ -+@@ -7075,17 +7063,7 @@ static int ath11k_reg_chan_list_event(st -+ (char *)reg_info->alpha2, 2)) -+ goto mem_free; -+ -+- /* Intersect new rules with default regd if a new country setting was -+- * requested, i.e a default regd was already set during initialization -+- * and the regd coming from this event has a valid country info. -+- */ -+- if (ab->default_regd[pdev_idx] && -+- !ath11k_reg_is_world_alpha((char *) -+- ab->default_regd[pdev_idx]->alpha2) && -+- !ath11k_reg_is_world_alpha((char *)reg_info->alpha2)) -+- intersect = true; -+- -+- regd = ath11k_reg_build_regd(ab, reg_info, intersect); -++ regd = ath11k_reg_build_regd(ab, reg_info); -+ if (!regd) { -+ ath11k_warn(ab, "failed to build regd from reg_info\n"); -+ goto fallback; -diff --git a/package/kernel/mac80211/patches/ath5k/201-ath5k-WAR-for-AR71xx-PCI-bug.patch b/package/kernel/mac80211/patches/ath5k/201-ath5k-WAR-for-AR71xx-PCI-bug.patch -new file mode 100644 -index 0000000000..4fc97dfaec ---- /dev/null -+++ b/package/kernel/mac80211/patches/ath5k/201-ath5k-WAR-for-AR71xx-PCI-bug.patch -@@ -0,0 +1,38 @@ -+--- a/drivers/net/wireless/ath/ath5k/initvals.c -++++ b/drivers/net/wireless/ath/ath5k/initvals.c -+@@ -62,8 +62,14 @@ static const struct ath5k_ini ar5210_ini -+ { AR5K_IMR, 0 }, -+ { AR5K_IER, AR5K_IER_DISABLE }, -+ { AR5K_BSR, 0, AR5K_INI_READ }, -++#if !defined(CONFIG_ATHEROS_AR71XX) && !defined(CONFIG_ATH79) -+ { AR5K_TXCFG, AR5K_DMASIZE_128B }, -+ { AR5K_RXCFG, AR5K_DMASIZE_128B }, -++#else -++ /* WAR for AR71xx PCI bug */ -++ { AR5K_TXCFG, AR5K_DMASIZE_128B }, -++ { AR5K_RXCFG, AR5K_DMASIZE_4B }, -++#endif -+ { AR5K_CFG, AR5K_INIT_CFG }, -+ { AR5K_TOPS, 8 }, -+ { AR5K_RXNOFRM, 8 }, -+--- a/drivers/net/wireless/ath/ath5k/dma.c -++++ b/drivers/net/wireless/ath/ath5k/dma.c -+@@ -854,10 +854,18 @@ ath5k_hw_dma_init(struct ath5k_hw *ah) -+ * guess we can tweak it and see how it goes ;-) -+ */ -+ if (ah->ah_version != AR5K_AR5210) { -++#if !defined(CONFIG_ATHEROS_AR71XX) && !defined(CONFIG_ATH79) -+ AR5K_REG_WRITE_BITS(ah, AR5K_TXCFG, -+ AR5K_TXCFG_SDMAMR, AR5K_DMASIZE_128B); -+ AR5K_REG_WRITE_BITS(ah, AR5K_RXCFG, -+ AR5K_RXCFG_SDMAMW, AR5K_DMASIZE_128B); -++#else -++ /* WAR for AR71xx PCI bug */ -++ AR5K_REG_WRITE_BITS(ah, AR5K_TXCFG, -++ AR5K_TXCFG_SDMAMR, AR5K_DMASIZE_128B); -++ AR5K_REG_WRITE_BITS(ah, AR5K_RXCFG, -++ AR5K_RXCFG_SDMAMW, AR5K_DMASIZE_4B); -++#endif -+ } -+ -+ /* Pre-enable interrupts on 5211/5212*/ -diff --git a/package/kernel/mac80211/patches/ath5k/411-ath5k_allow_adhoc_and_ap.patch b/package/kernel/mac80211/patches/ath5k/411-ath5k_allow_adhoc_and_ap.patch -new file mode 100644 -index 0000000000..1df4aab57e ---- /dev/null -+++ b/package/kernel/mac80211/patches/ath5k/411-ath5k_allow_adhoc_and_ap.patch -@@ -0,0 +1,46 @@ -+--- a/drivers/net/wireless/ath/ath5k/mac80211-ops.c -++++ b/drivers/net/wireless/ath/ath5k/mac80211-ops.c -+@@ -86,13 +86,8 @@ ath5k_add_interface(struct ieee80211_hw -+ goto end; -+ } -+ -+- /* Don't allow other interfaces if one ad-hoc is configured. -+- * TODO: Fix the problems with ad-hoc and multiple other interfaces. -+- * We would need to operate the HW in ad-hoc mode to allow TSF updates -+- * for the IBSS, but this breaks with additional AP or STA interfaces -+- * at the moment. */ -+- if (ah->num_adhoc_vifs || -+- (ah->nvifs && vif->type == NL80211_IFTYPE_ADHOC)) { -++ /* Don't allow more than one ad-hoc interface */ -++ if (ah->num_adhoc_vifs && vif->type == NL80211_IFTYPE_ADHOC) { -+ ATH5K_ERR(ah, "Only one single ad-hoc interface is allowed.\n"); -+ ret = -ELNRNG; -+ goto end; -+--- a/drivers/net/wireless/ath/ath5k/base.c -++++ b/drivers/net/wireless/ath/ath5k/base.c -+@@ -2009,7 +2009,7 @@ ath5k_beacon_send(struct ath5k_hw *ah) -+ } -+ -+ if ((ah->opmode == NL80211_IFTYPE_AP && ah->num_ap_vifs + -+- ah->num_mesh_vifs > 1) || -++ ah->num_adhoc_vifs + ah->num_mesh_vifs > 1) || -+ ah->opmode == NL80211_IFTYPE_MESH_POINT) { -+ u64 tsf = ath5k_hw_get_tsf64(ah); -+ u32 tsftu = TSF_TO_TU(tsf); -+@@ -2095,7 +2095,7 @@ ath5k_beacon_update_timers(struct ath5k_ -+ -+ intval = ah->bintval & AR5K_BEACON_PERIOD; -+ if (ah->opmode == NL80211_IFTYPE_AP && ah->num_ap_vifs -+- + ah->num_mesh_vifs > 1) { -++ + ah->num_adhoc_vifs + ah->num_mesh_vifs > 1) { -+ intval /= ATH_BCBUF; /* staggered multi-bss beacons */ -+ if (intval < 15) -+ ATH5K_WARN(ah, "intval %u is too low, min 15\n", -+@@ -2561,6 +2561,7 @@ static const struct ieee80211_iface_limi -+ BIT(NL80211_IFTYPE_MESH_POINT) | -+ #endif -+ BIT(NL80211_IFTYPE_AP) }, -++ { .max = 1, .types = BIT(NL80211_IFTYPE_ADHOC) }, -+ }; -+ -+ static const struct ieee80211_iface_combination if_comb = { -diff --git a/package/kernel/mac80211/patches/ath5k/420-ath5k_disable_fast_cc.patch b/package/kernel/mac80211/patches/ath5k/420-ath5k_disable_fast_cc.patch -new file mode 100644 -index 0000000000..414f49508f ---- /dev/null -+++ b/package/kernel/mac80211/patches/ath5k/420-ath5k_disable_fast_cc.patch -@@ -0,0 +1,18 @@ -+--- a/drivers/net/wireless/ath/ath5k/reset.c -++++ b/drivers/net/wireless/ath/ath5k/reset.c -+@@ -1154,6 +1154,7 @@ ath5k_hw_reset(struct ath5k_hw *ah, enum -+ tsf_lo = 0; -+ mode = 0; -+ -++#if 0 -+ /* -+ * Sanity check for fast flag -+ * Fast channel change only available -+@@ -1161,6 +1162,7 @@ ath5k_hw_reset(struct ath5k_hw *ah, enum -+ */ -+ if (fast && (ah->ah_radio != AR5K_RF2413) && -+ (ah->ah_radio != AR5K_RF5413)) -++#endif -+ fast = false; -+ -+ /* Disable sleep clock operation -diff --git a/package/kernel/mac80211/patches/ath5k/430-add_ath5k_platform.patch b/package/kernel/mac80211/patches/ath5k/430-add_ath5k_platform.patch -new file mode 100644 -index 0000000000..b213e2a819 ---- /dev/null -+++ b/package/kernel/mac80211/patches/ath5k/430-add_ath5k_platform.patch -@@ -0,0 +1,33 @@ -+--- /dev/null -++++ b/include/linux/ath5k_platform.h -+@@ -0,0 +1,30 @@ -++/* -++ * Copyright (c) 2008 Atheros Communications Inc. -++ * Copyright (c) 2009 Gabor Juhos -++ * Copyright (c) 2009 Imre Kaloz -++ * Copyright (c) 2010 Daniel Golle -++ * -++ * 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_ATH5K_PLATFORM_H -++#define _LINUX_ATH5K_PLATFORM_H -++ -++#define ATH5K_PLAT_EEP_MAX_WORDS 2048 -++ -++struct ath5k_platform_data { -++ u16 *eeprom_data; -++ u8 *macaddr; -++}; -++ -++#endif /* _LINUX_ATH5K_PLATFORM_H */ -diff --git a/package/kernel/mac80211/patches/ath5k/432-ath5k_add_pciids.patch b/package/kernel/mac80211/patches/ath5k/432-ath5k_add_pciids.patch -new file mode 100644 -index 0000000000..bd0e6707a5 ---- /dev/null -+++ b/package/kernel/mac80211/patches/ath5k/432-ath5k_add_pciids.patch -@@ -0,0 +1,11 @@ -+--- a/drivers/net/wireless/ath/ath5k/pci.c -++++ b/drivers/net/wireless/ath/ath5k/pci.c -+@@ -47,6 +47,8 @@ static const struct pci_device_id ath5k_ -+ { PCI_VDEVICE(ATHEROS, 0x001b) }, /* 5413 Eagle */ -+ { PCI_VDEVICE(ATHEROS, 0x001c) }, /* PCI-E cards */ -+ { PCI_VDEVICE(ATHEROS, 0x001d) }, /* 2417 Nala */ -++ { PCI_VDEVICE(ATHEROS, 0xff16) }, /* 2413,2414 sx76x on lantiq_danube */ -++ { PCI_VDEVICE(ATHEROS, 0xff1a) }, /* 2417 arv45xx on lantiq_danube */ -+ { PCI_VDEVICE(ATHEROS, 0xff1b) }, /* AR5BXB63 */ -+ { 0 } -+ }; -diff --git a/package/kernel/mac80211/patches/ath5k/440-ath5k_channel_bw_debugfs.patch b/package/kernel/mac80211/patches/ath5k/440-ath5k_channel_bw_debugfs.patch -new file mode 100644 -index 0000000000..a63f0c881b ---- /dev/null -+++ b/package/kernel/mac80211/patches/ath5k/440-ath5k_channel_bw_debugfs.patch -@@ -0,0 +1,142 @@ -+This adds a bwmode debugfs file which can be used to set alternate -+channel operating bandwidths. Only tested with AR5413 and only at -+5 and 20 mhz channels. -+ -+Signed-off-by: Pat Erley -+--- -+Other devices will need to be added to the switch in write_file_bwmode -+ -+drivers/net/wireless/ath/ath5k/debug.c | 86 ++++++++++++++++++++++++++++++++ -+ 1 files changed, 86 insertions(+), 0 deletions(-) -+ -+--- a/drivers/net/wireless/ath/ath5k/debug.c -++++ b/drivers/net/wireless/ath/ath5k/debug.c -+@@ -803,6 +803,97 @@ static const struct file_operations fops -+ .llseek = default_llseek, -+ }; -+ -++/* debugfs: bwmode */ -++ -++static ssize_t read_file_bwmode(struct file *file, char __user *user_buf, -++ size_t count, loff_t *ppos) -++{ -++ struct ath5k_hw *ah = file->private_data; -++ char buf[15]; -++ unsigned int len = 0; -++ -++ int cur_ah_bwmode = ah->ah_bwmode_debug; -++ -++#define print_selected(MODE, LABEL) \ -++ if (cur_ah_bwmode == MODE) \ -++ len += snprintf(buf+len, sizeof(buf)-len, "[%s]", LABEL); \ -++ else \ -++ len += snprintf(buf+len, sizeof(buf)-len, "%s", LABEL); \ -++ len += snprintf(buf+len, sizeof(buf)-len, " "); -++ -++ print_selected(AR5K_BWMODE_5MHZ, "5"); -++ print_selected(AR5K_BWMODE_10MHZ, "10"); -++ print_selected(AR5K_BWMODE_DEFAULT, "20"); -++ print_selected(AR5K_BWMODE_40MHZ, "40"); -++#undef print_selected -++ -++ len += snprintf(buf+len, sizeof(buf)-len, "\n"); -++ -++ return simple_read_from_buffer(user_buf, count, ppos, buf, len); -++} -++ -++static ssize_t write_file_bwmode(struct file *file, -++ const char __user *userbuf, -++ size_t count, loff_t *ppos) -++{ -++ struct ath5k_hw *ah = file->private_data; -++ char buf[3]; -++ int bw = 20; -++ int tobwmode = AR5K_BWMODE_DEFAULT; -++ -++ if (copy_from_user(buf, userbuf, min(count, sizeof(buf)))) -++ return -EFAULT; -++ -++ /* TODO: Add check for active interface */ -++ -++ if(strncmp(buf, "5", 1) == 0 ) { -++ tobwmode = AR5K_BWMODE_5MHZ; -++ bw = 5; -++ } else if ( strncmp(buf, "10", 2) == 0 ) { -++ tobwmode = AR5K_BWMODE_10MHZ; -++ bw = 10; -++ } else if ( strncmp(buf, "20", 2) == 0 ) { -++ tobwmode = AR5K_BWMODE_DEFAULT; -++ bw = 20; -++ } else if ( strncmp(buf, "40", 2) == 0 ) { -++ tobwmode = AR5K_BWMODE_40MHZ; -++ bw = 40; -++ } else -++ return -EINVAL; -++ -++ ATH5K_INFO(ah, "Changing to %imhz channel width[%i]\n", -++ bw, tobwmode); -++ -++ switch (ah->ah_radio) { -++ /* TODO: only define radios that actually support 5/10mhz channels */ -++ case AR5K_RF5413: -++ case AR5K_RF5110: -++ case AR5K_RF5111: -++ case AR5K_RF5112: -++ case AR5K_RF2413: -++ case AR5K_RF2316: -++ case AR5K_RF2317: -++ case AR5K_RF2425: -++ if(ah->ah_bwmode_debug != tobwmode) { -++ mutex_lock(&ah->lock); -++ ah->ah_bwmode = tobwmode; -++ ah->ah_bwmode_debug = tobwmode; -++ mutex_unlock(&ah->lock); -++ } -++ break; -++ default: -++ return -EOPNOTSUPP; -++ } -++ return count; -++} -++ -++static const struct file_operations fops_bwmode = { -++ .read = read_file_bwmode, -++ .write = write_file_bwmode, -++ .open = simple_open, -++ .owner = THIS_MODULE, -++ .llseek = default_llseek, -++}; -+ -+ /* debugfs: queues etc */ -+ -+@@ -997,6 +1088,8 @@ ath5k_debug_init_device(struct ath5k_hw -+ debugfs_create_file("queue", 0600, phydir, ah, &fops_queue); -+ debugfs_create_bool("32khz_clock", 0600, phydir, -+ &ah->ah_use_32khz_clock); -++ debugfs_create_file("bwmode", S_IWUSR | S_IRUSR, phydir, ah, -++ &fops_bwmode); -+ } -+ -+ /* functions used in other places */ -+--- a/drivers/net/wireless/ath/ath5k/ath5k.h -++++ b/drivers/net/wireless/ath/ath5k/ath5k.h -+@@ -1372,6 +1372,7 @@ struct ath5k_hw { -+ u8 ah_coverage_class; -+ bool ah_ack_bitrate_high; -+ u8 ah_bwmode; -++ u8 ah_bwmode_debug; -+ bool ah_short_slot; -+ -+ /* Antenna Control */ -+--- a/drivers/net/wireless/ath/ath5k/base.c -++++ b/drivers/net/wireless/ath/ath5k/base.c -+@@ -465,6 +465,9 @@ ath5k_chan_set(struct ath5k_hw *ah, stru -+ return -EINVAL; -+ } -+ -++ if (ah->ah_bwmode_debug != AR5K_BWMODE_DEFAULT) -++ ah->ah_bwmode = ah->ah_bwmode_debug; -++ -+ /* -+ * To switch channels clear any pending DMA operations; -+ * wait long enough for the RX fifo to drain, reset the -diff --git a/package/kernel/mac80211/patches/ath9k/350-ath9k_hw-reset-AHB-WMAC-interface-on-AR91xx.patch b/package/kernel/mac80211/patches/ath9k/350-ath9k_hw-reset-AHB-WMAC-interface-on-AR91xx.patch -new file mode 100644 -index 0000000000..3a0171d4a2 ---- /dev/null -+++ b/package/kernel/mac80211/patches/ath9k/350-ath9k_hw-reset-AHB-WMAC-interface-on-AR91xx.patch -@@ -0,0 +1,25 @@ -+From: Felix Fietkau -+Date: Sat, 9 Jul 2016 15:25:24 +0200 -+Subject: [PATCH] ath9k_hw: reset AHB-WMAC interface on AR91xx -+ -+Should fix a few stability issues -+ -+Signed-off-by: Felix Fietkau -+--- -+ -+--- a/drivers/net/wireless/ath/ath9k/hw.c -++++ b/drivers/net/wireless/ath/ath9k/hw.c -+@@ -1434,8 +1434,12 @@ static bool ath9k_hw_set_reset(struct at -+ if (!AR_SREV_9100(ah)) -+ REG_WRITE(ah, AR_RC, 0); -+ -+- if (AR_SREV_9100(ah)) -++ if (AR_SREV_9100(ah)) { -++ /* Reset the AHB-WMAC interface */ -++ if (ah->external_reset) -++ ah->external_reset(); -+ udelay(50); -++ } -+ -+ return true; -+ } -diff --git a/package/kernel/mac80211/patches/ath9k/351-ath9k_hw-issue-external-reset-for-QCA955x.patch b/package/kernel/mac80211/patches/ath9k/351-ath9k_hw-issue-external-reset-for-QCA955x.patch -new file mode 100644 -index 0000000000..53b7ba08bc ---- /dev/null -+++ b/package/kernel/mac80211/patches/ath9k/351-ath9k_hw-issue-external-reset-for-QCA955x.patch -@@ -0,0 +1,129 @@ -+From: Felix Fietkau -+Date: Sat, 9 Jul 2016 15:26:44 +0200 -+Subject: [PATCH] ath9k_hw: issue external reset for QCA955x -+ -+The RTC interface on the SoC needs to be reset along with the rest of -+the WMAC. -+ -+Signed-off-by: Felix Fietkau -+--- -+ -+--- a/drivers/net/wireless/ath/ath9k/hw.c -++++ b/drivers/net/wireless/ath/ath9k/hw.c -+@@ -1311,39 +1311,56 @@ void ath9k_hw_get_delta_slope_vals(struc -+ *coef_exponent = coef_exp - 16; -+ } -+ -+-/* AR9330 WAR: -+- * call external reset function to reset WMAC if: -+- * - doing a cold reset -+- * - we have pending frames in the TX queues. -+- */ -+-static bool ath9k_hw_ar9330_reset_war(struct ath_hw *ah, int type) -++static bool ath9k_hw_need_external_reset(struct ath_hw *ah, int type) -+ { -+- int i, npend = 0; -++ int i; -+ -+- for (i = 0; i < AR_NUM_QCU; i++) { -+- npend = ath9k_hw_numtxpending(ah, i); -+- if (npend) -+- break; -+- } -+- -+- if (ah->external_reset && -+- (npend || type == ATH9K_RESET_COLD)) { -+- int reset_err = 0; -+- -+- ath_dbg(ath9k_hw_common(ah), RESET, -+- "reset MAC via external reset\n"); -+- -+- reset_err = ah->external_reset(); -+- if (reset_err) { -+- ath_err(ath9k_hw_common(ah), -+- "External reset failed, err=%d\n", -+- reset_err); -+- return false; -++ if (type == ATH9K_RESET_COLD) -++ return true; -++ -++ if (AR_SREV_9550(ah)) -++ return true; -++ -++ /* AR9330 WAR: -++ * call external reset function to reset WMAC if: -++ * - doing a cold reset -++ * - we have pending frames in the TX queues. -++ */ -++ if (AR_SREV_9330(ah)) { -++ for (i = 0; i < AR_NUM_QCU; i++) { -++ if (ath9k_hw_numtxpending(ah, i)) -++ return true; -+ } -++ } -++ -++ return false; -++} -++ -++static bool ath9k_hw_external_reset(struct ath_hw *ah, int type) -++{ -++ int err; -++ -++ if (!ah->external_reset || !ath9k_hw_need_external_reset(ah, type)) -++ return true; -++ -++ ath_dbg(ath9k_hw_common(ah), RESET, -++ "reset MAC via external reset\n"); -+ -+- REG_WRITE(ah, AR_RTC_RESET, 1); -++ err = ah->external_reset(); -++ if (err) { -++ ath_err(ath9k_hw_common(ah), -++ "External reset failed, err=%d\n", err); -++ return false; -+ } -+ -++ if (AR_SREV_9550(ah)) { -++ REG_WRITE(ah, AR_RTC_RESET, 0); -++ udelay(10); -++ } -++ -++ REG_WRITE(ah, AR_RTC_RESET, 1); -++ udelay(10); -++ -+ return true; -+ } -+ -+@@ -1396,24 +1413,24 @@ static bool ath9k_hw_set_reset(struct at -+ rst_flags |= AR_RTC_RC_MAC_COLD; -+ } -+ -+- if (AR_SREV_9330(ah)) { -+- if (!ath9k_hw_ar9330_reset_war(ah, type)) -+- return false; -+- } -+- -+ if (ath9k_hw_mci_is_enabled(ah)) -+ ar9003_mci_check_gpm_offset(ah); -+ -+ /* DMA HALT added to resolve ar9300 and ar9580 bus error during -+- * RTC_RC reg read -++ * RTC_RC reg read. Also needed for AR9550 external reset -+ */ -+- if (AR_SREV_9300(ah) || AR_SREV_9580(ah)) { -++ if (AR_SREV_9300(ah) || AR_SREV_9580(ah) || AR_SREV_9550(ah)) { -+ REG_SET_BIT(ah, AR_CFG, AR_CFG_HALT_REQ); -+ ath9k_hw_wait(ah, AR_CFG, AR_CFG_HALT_ACK, AR_CFG_HALT_ACK, -+ 20 * AH_WAIT_TIMEOUT); -+- REG_CLR_BIT(ah, AR_CFG, AR_CFG_HALT_REQ); -+ } -+ -++ if (!AR_SREV_9100(ah)) -++ ath9k_hw_external_reset(ah, type); -++ -++ if (AR_SREV_9300(ah) || AR_SREV_9580(ah)) -++ REG_CLR_BIT(ah, AR_CFG, AR_CFG_HALT_REQ); -++ -+ REG_WRITE(ah, AR_RTC_RC, rst_flags); -+ -+ REGWRITE_BUFFER_FLUSH(ah); -diff --git a/package/kernel/mac80211/patches/ath9k/354-ath9k-force-rx_clear-when-disabling-rx.patch b/package/kernel/mac80211/patches/ath9k/354-ath9k-force-rx_clear-when-disabling-rx.patch -new file mode 100644 -index 0000000000..8aaccf49b4 ---- /dev/null -+++ b/package/kernel/mac80211/patches/ath9k/354-ath9k-force-rx_clear-when-disabling-rx.patch -@@ -0,0 +1,35 @@ -+From: Felix Fietkau -+Date: Sun, 7 Jun 2015 13:53:35 +0200 -+Subject: [PATCH] ath9k: force rx_clear when disabling rx -+ -+This makes stopping Rx more reliable and should reduce the frequency of -+Rx related DMA stop warnings. Don't use rx_clear in TX99 mode. -+ -+Cc: stable@vger.kernel.org -+Signed-off-by: Felix Fietkau -+Signed-off-by: Helmut Schaa -+--- -+ -+--- a/drivers/net/wireless/ath/ath9k/mac.c -++++ b/drivers/net/wireless/ath/ath9k/mac.c -+@@ -678,13 +678,18 @@ void ath9k_hw_startpcureceive(struct ath -+ -+ ath9k_ani_reset(ah, is_scanning); -+ -+- REG_CLR_BIT(ah, AR_DIAG_SW, (AR_DIAG_RX_DIS | AR_DIAG_RX_ABORT)); -++ REG_CLR_BIT(ah, AR_DIAG_SW, -++ AR_DIAG_RX_DIS | AR_DIAG_RX_ABORT | AR_DIAG_FORCE_RX_CLEAR); -+ } -+ EXPORT_SYMBOL(ath9k_hw_startpcureceive); -+ -+ void ath9k_hw_abortpcurecv(struct ath_hw *ah) -+ { -+- REG_SET_BIT(ah, AR_DIAG_SW, AR_DIAG_RX_ABORT | AR_DIAG_RX_DIS); -++ u32 reg = AR_DIAG_RX_DIS | AR_DIAG_RX_ABORT; -++ -++ if (!IS_ENABLED(CPTCFG_ATH9K_TX99)) -++ reg |= AR_DIAG_FORCE_RX_CLEAR; -++ REG_SET_BIT(ah, AR_DIAG_SW, reg); -+ -+ ath9k_hw_disable_mib_counters(ah); -+ } -diff --git a/package/kernel/mac80211/patches/ath9k/356-Revert-ath9k-interpret-requested-txpower-in-EIRP-dom.patch b/package/kernel/mac80211/patches/ath9k/356-Revert-ath9k-interpret-requested-txpower-in-EIRP-dom.patch -new file mode 100644 -index 0000000000..385eea0116 ---- /dev/null -+++ b/package/kernel/mac80211/patches/ath9k/356-Revert-ath9k-interpret-requested-txpower-in-EIRP-dom.patch -@@ -0,0 +1,36 @@ -+From: Felix Fietkau -+Date: Sat, 14 May 2016 14:51:02 +0200 -+Subject: [PATCH] Revert "ath9k: interpret requested txpower in EIRP -+ domain" -+ -+This reverts commit 71f5137bf010c6faffab50c0ec15374c59c4a411. -+--- -+ -+--- a/drivers/net/wireless/ath/ath9k/hw.c -++++ b/drivers/net/wireless/ath/ath9k/hw.c -+@@ -2977,7 +2977,8 @@ void ath9k_hw_apply_txpower(struct ath_h -+ { -+ struct ath_regulatory *reg = ath9k_hw_regulatory(ah); -+ struct ieee80211_channel *channel; -+- int chan_pwr, new_pwr; -++ int chan_pwr, new_pwr, max_gain; -++ int ant_gain, ant_reduction = 0; -+ u16 ctl = NO_CTL; -+ -+ if (!chan) -+@@ -2989,9 +2990,14 @@ void ath9k_hw_apply_txpower(struct ath_h -+ channel = chan->chan; -+ chan_pwr = min_t(int, channel->max_power * 2, MAX_COMBINED_POWER); -+ new_pwr = min_t(int, chan_pwr, reg->power_limit); -++ max_gain = chan_pwr - new_pwr + channel->max_antenna_gain * 2; -++ -++ ant_gain = get_antenna_gain(ah, chan); -++ if (ant_gain > max_gain) -++ ant_reduction = ant_gain - max_gain; -+ -+ ah->eep_ops->set_txpower(ah, chan, ctl, -+- get_antenna_gain(ah, chan), new_pwr, test); -++ ant_reduction, new_pwr, test); -+ } -+ -+ void ath9k_hw_set_txpowerlimit(struct ath_hw *ah, u32 limit, bool test) -diff --git a/package/kernel/mac80211/patches/ath9k/365-ath9k-adjust-tx-power-reduction-for-US-regulatory-do.patch b/package/kernel/mac80211/patches/ath9k/365-ath9k-adjust-tx-power-reduction-for-US-regulatory-do.patch -new file mode 100644 -index 0000000000..0c3edc1260 ---- /dev/null -+++ b/package/kernel/mac80211/patches/ath9k/365-ath9k-adjust-tx-power-reduction-for-US-regulatory-do.patch -@@ -0,0 +1,24 @@ -+From: Felix Fietkau -+Date: Wed, 19 Jul 2017 08:49:31 +0200 -+Subject: [PATCH] ath9k: adjust tx power reduction for US regulatory -+ domain -+ -+FCC regulatory rules allow for up to 6 dBi antenna gain. Account for -+this in the EEPROM based tx power reduction code. -+ -+Signed-off-by: Felix Fietkau -+--- -+ -+--- a/drivers/net/wireless/ath/ath9k/hw.c -++++ b/drivers/net/wireless/ath/ath9k/hw.c -+@@ -2996,6 +2996,10 @@ void ath9k_hw_apply_txpower(struct ath_h -+ if (ant_gain > max_gain) -+ ant_reduction = ant_gain - max_gain; -+ -++ /* FCC allows maximum antenna gain of 6 dBi */ -++ if (reg->region == NL80211_DFS_FCC) -++ ant_reduction = max_t(int, ant_reduction - 12, 0); -++ -+ ah->eep_ops->set_txpower(ah, chan, ctl, -+ ant_reduction, new_pwr, test); -+ } -diff --git a/package/kernel/mac80211/patches/ath9k/401-ath9k_blink_default.patch b/package/kernel/mac80211/patches/ath9k/401-ath9k_blink_default.patch -new file mode 100644 -index 0000000000..3eb57bb1cf ---- /dev/null -+++ b/package/kernel/mac80211/patches/ath9k/401-ath9k_blink_default.patch -@@ -0,0 +1,11 @@ -+--- a/drivers/net/wireless/ath/ath9k/init.c -++++ b/drivers/net/wireless/ath/ath9k/init.c -+@@ -48,7 +48,7 @@ int ath9k_modparam_nohwcrypt; -+ module_param_named(nohwcrypt, ath9k_modparam_nohwcrypt, int, 0444); -+ MODULE_PARM_DESC(nohwcrypt, "Disable hardware encryption"); -+ -+-int ath9k_led_blink; -++int ath9k_led_blink = 1; -+ module_param_named(blink, ath9k_led_blink, int, 0444); -+ MODULE_PARM_DESC(blink, "Enable LED blink on activity"); -+ -diff --git a/package/kernel/mac80211/patches/ath9k/410-ath9k_allow_adhoc_and_ap.patch b/package/kernel/mac80211/patches/ath9k/410-ath9k_allow_adhoc_and_ap.patch -new file mode 100644 -index 0000000000..b2f2763e8e ---- /dev/null -+++ b/package/kernel/mac80211/patches/ath9k/410-ath9k_allow_adhoc_and_ap.patch -@@ -0,0 +1,10 @@ -+--- a/drivers/net/wireless/ath/ath9k/init.c -++++ b/drivers/net/wireless/ath/ath9k/init.c -+@@ -882,6 +882,7 @@ static const struct ieee80211_iface_limi -+ BIT(NL80211_IFTYPE_AP) }, -+ { .max = 1, .types = BIT(NL80211_IFTYPE_P2P_CLIENT) | -+ BIT(NL80211_IFTYPE_P2P_GO) }, -++ { .max = 1, .types = BIT(NL80211_IFTYPE_ADHOC) }, -+ }; -+ -+ #ifdef CPTCFG_ATH9K_CHANNEL_CONTEXT -diff --git a/package/kernel/mac80211/patches/ath9k/450-ath9k-enabled-MFP-capability-unconditionally.patch b/package/kernel/mac80211/patches/ath9k/450-ath9k-enabled-MFP-capability-unconditionally.patch -new file mode 100644 -index 0000000000..f424ca530b ---- /dev/null -+++ b/package/kernel/mac80211/patches/ath9k/450-ath9k-enabled-MFP-capability-unconditionally.patch -@@ -0,0 +1,34 @@ -+From d946085ff5a331de64e91a2e3c96b9ca79d740f5 Mon Sep 17 00:00:00 2001 -+From: David Bauer -+Date: Mon, 15 Jun 2020 00:10:34 +0200 -+Subject: [PATCH] ath9k: enabled MFP capability unconditionally -+ -+ath9k will already fallback on software-crypto for chipsets not -+supporting IEEE802.11w (MFP). So advertising MFP is not dependent -+on disabling HW crypto for all traffic entirely. -+ -+Signed-off-by: David Bauer -+--- -+ drivers/net/wireless/ath/ath9k/init.c | 4 +--- -+ 1 file changed, 1 insertion(+), 3 deletions(-) -+ -+--- a/drivers/net/wireless/ath/ath9k/init.c -++++ b/drivers/net/wireless/ath/ath9k/init.c -+@@ -963,6 +963,7 @@ static void ath9k_set_hw_capab(struct at -+ ieee80211_hw_set(hw, HOST_BROADCAST_PS_BUFFERING); -+ ieee80211_hw_set(hw, SUPPORT_FAST_XMIT); -+ ieee80211_hw_set(hw, SUPPORTS_CLONED_SKBS); -++ ieee80211_hw_set(hw, MFP_CAPABLE); -+ -+ if (ath9k_ps_enable) -+ ieee80211_hw_set(hw, SUPPORTS_PS); -+@@ -975,9 +976,6 @@ static void ath9k_set_hw_capab(struct at -+ IEEE80211_RADIOTAP_MCS_HAVE_STBC; -+ } -+ -+- if (AR_SREV_9160_10_OR_LATER(sc->sc_ah) || ath9k_modparam_nohwcrypt) -+- ieee80211_hw_set(hw, MFP_CAPABLE); -+- -+ hw->wiphy->features |= NL80211_FEATURE_ACTIVE_MONITOR | -+ NL80211_FEATURE_AP_MODE_CHAN_WIDTH_CHANGE | -+ NL80211_FEATURE_P2P_GO_CTWIN; -diff --git a/package/kernel/mac80211/patches/ath9k/500-ath9k_eeprom_debugfs.patch b/package/kernel/mac80211/patches/ath9k/500-ath9k_eeprom_debugfs.patch -new file mode 100644 -index 0000000000..2f5e75be8a ---- /dev/null -+++ b/package/kernel/mac80211/patches/ath9k/500-ath9k_eeprom_debugfs.patch -@@ -0,0 +1,66 @@ -+--- a/drivers/net/wireless/ath/ath9k/debug.c -++++ b/drivers/net/wireless/ath/ath9k/debug.c -+@@ -1413,6 +1413,54 @@ void ath9k_deinit_debug(struct ath_softc -+ ath9k_cmn_spectral_deinit_debug(&sc->spec_priv); -+ } -+ -++static ssize_t read_file_eeprom(struct file *file, char __user *user_buf, -++ size_t count, loff_t *ppos) -++{ -++ struct ath_softc *sc = file->private_data; -++ struct ath_hw *ah = sc->sc_ah; -++ struct ath_common *common = ath9k_hw_common(ah); -++ int bytes = 0; -++ int pos = *ppos; -++ int size = 4096; -++ u16 val; -++ int i; -++ -++ if (AR_SREV_9300_20_OR_LATER(ah)) -++ size = 16384; -++ -++ if (*ppos < 0) -++ return -EINVAL; -++ -++ if (count > size - *ppos) -++ count = size - *ppos; -++ -++ for (i = *ppos / 2; count > 0; count -= bytes, *ppos += bytes, i++) { -++ void *from = &val; -++ -++ if (!common->bus_ops->eeprom_read(common, i, &val)) -++ val = 0xffff; -++ -++ if (*ppos % 2) { -++ from++; -++ bytes = 1; -++ } else if (count == 1) { -++ bytes = 1; -++ } else { -++ bytes = 2; -++ } -++ if (copy_to_user(user_buf, from, bytes)) -++ return -EFAULT; -++ user_buf += bytes; -++ } -++ return *ppos - pos; -++} -++ -++static const struct file_operations fops_eeprom = { -++ .read = read_file_eeprom, -++ .open = simple_open, -++ .owner = THIS_MODULE -++}; -++ -+ int ath9k_init_debug(struct ath_hw *ah) -+ { -+ struct ath_common *common = ath9k_hw_common(ah); -+@@ -1432,6 +1480,8 @@ int ath9k_init_debug(struct ath_hw *ah) -+ ath9k_tx99_init_debug(sc); -+ ath9k_cmn_spectral_init_debug(&sc->spec_priv, sc->debug.debugfs_phy); -+ -++ debugfs_create_file("eeprom", S_IRUSR, sc->debug.debugfs_phy, sc, -++ &fops_eeprom); -+ debugfs_create_devm_seqfile(sc->dev, "dma", sc->debug.debugfs_phy, -+ read_file_dma); -+ debugfs_create_devm_seqfile(sc->dev, "interrupt", sc->debug.debugfs_phy, -diff --git a/package/kernel/mac80211/patches/ath9k/501-ath9k_ahb_init.patch b/package/kernel/mac80211/patches/ath9k/501-ath9k_ahb_init.patch -new file mode 100644 -index 0000000000..740ddc39dc ---- /dev/null -+++ b/package/kernel/mac80211/patches/ath9k/501-ath9k_ahb_init.patch -@@ -0,0 +1,34 @@ -+--- a/drivers/net/wireless/ath/ath9k/init.c -++++ b/drivers/net/wireless/ath/ath9k/init.c -+@@ -1178,25 +1178,25 @@ static int __init ath9k_init(void) -+ { -+ int error; -+ -+- error = ath_pci_init(); -++ error = ath_ahb_init(); -+ if (error < 0) { -+- pr_err("No PCI devices found, driver not installed\n"); -+ error = -ENODEV; -+ goto err_out; -+ } -+ -+- error = ath_ahb_init(); -++ error = ath_pci_init(); -+ if (error < 0) { -++ pr_err("No PCI devices found, driver not installed\n"); -+ error = -ENODEV; -+- goto err_pci_exit; -++ goto err_ahb_exit; -+ } -+ -+ dmi_check_system(ath9k_quirks); -+ -+ return 0; -+ -+- err_pci_exit: -+- ath_pci_exit(); -++ err_ahb_exit: -++ ath_ahb_exit(); -+ err_out: -+ return error; -+ } -diff --git a/package/kernel/mac80211/patches/ath9k/510-ath9k_intr_mitigation_tweak.patch b/package/kernel/mac80211/patches/ath9k/510-ath9k_intr_mitigation_tweak.patch -new file mode 100644 -index 0000000000..fda050a8f2 ---- /dev/null -+++ b/package/kernel/mac80211/patches/ath9k/510-ath9k_intr_mitigation_tweak.patch -@@ -0,0 +1,18 @@ -+--- a/drivers/net/wireless/ath/ath9k/hw.c -++++ b/drivers/net/wireless/ath/ath9k/hw.c -+@@ -402,13 +402,8 @@ static void ath9k_hw_init_config(struct -+ -+ ah->config.rx_intr_mitigation = true; -+ -+- if (AR_SREV_9300_20_OR_LATER(ah)) { -+- ah->config.rimt_last = 500; -+- ah->config.rimt_first = 2000; -+- } else { -+- ah->config.rimt_last = 250; -+- ah->config.rimt_first = 700; -+- } -++ ah->config.rimt_last = 250; -++ ah->config.rimt_first = 500; -+ -+ if (AR_SREV_9462(ah) || AR_SREV_9565(ah)) -+ ah->config.pll_pwrsave = 7; -diff --git a/package/kernel/mac80211/patches/ath9k/511-ath9k_reduce_rxbuf.patch b/package/kernel/mac80211/patches/ath9k/511-ath9k_reduce_rxbuf.patch -new file mode 100644 -index 0000000000..15b8d7b86b ---- /dev/null -+++ b/package/kernel/mac80211/patches/ath9k/511-ath9k_reduce_rxbuf.patch -@@ -0,0 +1,11 @@ -+--- a/drivers/net/wireless/ath/ath9k/ath9k.h -++++ b/drivers/net/wireless/ath/ath9k/ath9k.h -+@@ -88,7 +88,7 @@ int ath_descdma_setup(struct ath_softc * -+ (_l) &= ((_sz) - 1); \ -+ } while (0) -+ -+-#define ATH_RXBUF 512 -++#define ATH_RXBUF 256 -+ #define ATH_TXBUF 512 -+ #define ATH_TXBUF_RESERVE 5 -+ #define ATH_TXMAXTRY 13 -diff --git a/package/kernel/mac80211/patches/ath9k/512-ath9k_channelbw_debugfs.patch b/package/kernel/mac80211/patches/ath9k/512-ath9k_channelbw_debugfs.patch -new file mode 100644 -index 0000000000..a871e458a4 ---- /dev/null -+++ b/package/kernel/mac80211/patches/ath9k/512-ath9k_channelbw_debugfs.patch -@@ -0,0 +1,125 @@ -+--- a/drivers/net/wireless/ath/ath9k/debug.c -++++ b/drivers/net/wireless/ath/ath9k/debug.c -+@@ -1461,6 +1461,52 @@ static const struct file_operations fops -+ .owner = THIS_MODULE -+ }; -+ -++ -++static ssize_t read_file_chan_bw(struct file *file, char __user *user_buf, -++ size_t count, loff_t *ppos) -++{ -++ struct ath_softc *sc = file->private_data; -++ struct ath_common *common = ath9k_hw_common(sc->sc_ah); -++ char buf[32]; -++ unsigned int len; -++ -++ len = sprintf(buf, "0x%08x\n", common->chan_bw); -++ return simple_read_from_buffer(user_buf, count, ppos, buf, len); -++} -++ -++static ssize_t write_file_chan_bw(struct file *file, const char __user *user_buf, -++ size_t count, loff_t *ppos) -++{ -++ struct ath_softc *sc = file->private_data; -++ struct ath_common *common = ath9k_hw_common(sc->sc_ah); -++ unsigned long chan_bw; -++ char buf[32]; -++ ssize_t len; -++ -++ len = min(count, sizeof(buf) - 1); -++ if (copy_from_user(buf, user_buf, len)) -++ return -EFAULT; -++ -++ buf[len] = '\0'; -++ if (kstrtoul(buf, 0, &chan_bw)) -++ return -EINVAL; -++ -++ common->chan_bw = chan_bw; -++ if (!test_bit(ATH_OP_INVALID, &common->op_flags)) -++ ath9k_ops.config(sc->hw, IEEE80211_CONF_CHANGE_CHANNEL); -++ -++ return count; -++} -++ -++static const struct file_operations fops_chanbw = { -++ .read = read_file_chan_bw, -++ .write = write_file_chan_bw, -++ .open = simple_open, -++ .owner = THIS_MODULE, -++ .llseek = default_llseek, -++}; -++ -++ -+ int ath9k_init_debug(struct ath_hw *ah) -+ { -+ struct ath_common *common = ath9k_hw_common(ah); -+@@ -1482,6 +1528,8 @@ int ath9k_init_debug(struct ath_hw *ah) -+ -+ debugfs_create_file("eeprom", S_IRUSR, sc->debug.debugfs_phy, sc, -+ &fops_eeprom); -++ debugfs_create_file("chanbw", S_IRUSR | S_IWUSR, sc->debug.debugfs_phy, -++ sc, &fops_chanbw); -+ debugfs_create_devm_seqfile(sc->dev, "dma", sc->debug.debugfs_phy, -+ read_file_dma); -+ debugfs_create_devm_seqfile(sc->dev, "interrupt", sc->debug.debugfs_phy, -+--- a/drivers/net/wireless/ath/ath.h -++++ b/drivers/net/wireless/ath/ath.h -+@@ -149,6 +149,7 @@ struct ath_common { -+ int debug_mask; -+ enum ath_device_state state; -+ unsigned long op_flags; -++ u32 chan_bw; -+ -+ struct ath_ani ani; -+ -+--- a/drivers/net/wireless/ath/ath9k/common.c -++++ b/drivers/net/wireless/ath/ath9k/common.c -+@@ -297,11 +297,13 @@ EXPORT_SYMBOL(ath9k_cmn_get_hw_crypto_ke -+ /* -+ * Update internal channel flags. -+ */ -+-static void ath9k_cmn_update_ichannel(struct ath9k_channel *ichan, -++static void ath9k_cmn_update_ichannel(struct ath_common *common, -++ struct ath9k_channel *ichan, -+ struct cfg80211_chan_def *chandef) -+ { -+ struct ieee80211_channel *chan = chandef->chan; -+ u16 flags = 0; -++ int width; -+ -+ ichan->channel = chan->center_freq; -+ ichan->chan = chan; -+@@ -309,7 +311,19 @@ static void ath9k_cmn_update_ichannel(st -+ if (chan->band == NL80211_BAND_5GHZ) -+ flags |= CHANNEL_5GHZ; -+ -+- switch (chandef->width) { -++ switch (common->chan_bw) { -++ case 5: -++ width = NL80211_CHAN_WIDTH_5; -++ break; -++ case 10: -++ width = NL80211_CHAN_WIDTH_10; -++ break; -++ default: -++ width = chandef->width; -++ break; -++ } -++ -++ switch (width) { -+ case NL80211_CHAN_WIDTH_5: -+ flags |= CHANNEL_QUARTER; -+ break; -+@@ -342,10 +356,11 @@ struct ath9k_channel *ath9k_cmn_get_chan -+ struct cfg80211_chan_def *chandef) -+ { -+ struct ieee80211_channel *curchan = chandef->chan; -++ struct ath_common *common = ath9k_hw_common(ah); -+ struct ath9k_channel *channel; -+ -+ channel = &ah->channels[curchan->hw_value]; -+- ath9k_cmn_update_ichannel(channel, chandef); -++ ath9k_cmn_update_ichannel(common, channel, chandef); -+ -+ return channel; -+ } -diff --git a/package/kernel/mac80211/patches/ath9k/513-ath9k_add_pci_ids.patch b/package/kernel/mac80211/patches/ath9k/513-ath9k_add_pci_ids.patch -new file mode 100644 -index 0000000000..a085e3a1fb ---- /dev/null -+++ b/package/kernel/mac80211/patches/ath9k/513-ath9k_add_pci_ids.patch -@@ -0,0 +1,30 @@ -+--- a/drivers/net/wireless/ath/ath9k/hw.c -++++ b/drivers/net/wireless/ath/ath9k/hw.c -+@@ -662,6 +662,7 @@ int ath9k_hw_init(struct ath_hw *ah) -+ -+ /* These are all the AR5008/AR9001/AR9002/AR9003 hardware family of chipsets */ -+ switch (ah->hw_version.devid) { -++ case AR9300_DEVID_INVALID: -+ case AR5416_DEVID_PCI: -+ case AR5416_DEVID_PCIE: -+ case AR5416_AR9100_DEVID: -+--- a/drivers/net/wireless/ath/ath9k/hw.h -++++ b/drivers/net/wireless/ath/ath9k/hw.h -+@@ -36,6 +36,7 @@ -+ -+ #define ATHEROS_VENDOR_ID 0x168c -+ -++#define AR9300_DEVID_INVALID 0xabcd -+ #define AR5416_DEVID_PCI 0x0023 -+ #define AR5416_DEVID_PCIE 0x0024 -+ #define AR9160_DEVID_PCI 0x0027 -+--- a/drivers/net/wireless/ath/ath9k/pci.c -++++ b/drivers/net/wireless/ath/ath9k/pci.c -+@@ -774,6 +774,7 @@ static const struct pci_device_id ath_pc -+ .driver_data = ATH9K_PCI_BT_ANT_DIV }, -+ #endif -+ -++ { PCI_VDEVICE(ATHEROS, 0xabcd) }, /* PCI-E internal chip default ID */ -+ { 0 } -+ }; -+ -diff --git a/package/kernel/mac80211/patches/ath9k/530-ath9k_extra_leds.patch b/package/kernel/mac80211/patches/ath9k/530-ath9k_extra_leds.patch -new file mode 100644 -index 0000000000..74506657e0 ---- /dev/null -+++ b/package/kernel/mac80211/patches/ath9k/530-ath9k_extra_leds.patch -@@ -0,0 +1,267 @@ -+--- a/drivers/net/wireless/ath/ath9k/ath9k.h -++++ b/drivers/net/wireless/ath/ath9k/ath9k.h -+@@ -843,6 +843,9 @@ static inline int ath9k_dump_btcoex(stru -+ #ifdef CPTCFG_MAC80211_LEDS -+ void ath_init_leds(struct ath_softc *sc); -+ void ath_deinit_leds(struct ath_softc *sc); -++int ath_create_gpio_led(struct ath_softc *sc, int gpio, const char *name, -++ const char *trigger, bool active_low); -++ -+ #else -+ static inline void ath_init_leds(struct ath_softc *sc) -+ { -+@@ -979,6 +982,13 @@ void ath_ant_comb_scan(struct ath_softc -+ -+ #define ATH9K_NUM_CHANCTX 2 /* supports 2 operating channels */ -+ -++struct ath_led { -++ struct list_head list; -++ struct ath_softc *sc; -++ const struct gpio_led *gpio; -++ struct led_classdev cdev; -++}; -++ -+ struct ath_softc { -+ struct ieee80211_hw *hw; -+ struct device *dev; -+@@ -1032,9 +1042,8 @@ struct ath_softc { -+ spinlock_t chan_lock; -+ -+ #ifdef CPTCFG_MAC80211_LEDS -+- bool led_registered; -+- char led_name[32]; -+- struct led_classdev led_cdev; -++ const char *led_default_trigger; -++ struct list_head leds; -+ #endif -+ -+ #ifdef CPTCFG_ATH9K_DEBUGFS -+--- a/drivers/net/wireless/ath/ath9k/gpio.c -++++ b/drivers/net/wireless/ath/ath9k/gpio.c -+@@ -39,61 +39,111 @@ static void ath_fill_led_pin(struct ath_ -+ else -+ ah->led_pin = ATH_LED_PIN_DEF; -+ } -++} -++ -++static void ath_led_brightness(struct led_classdev *led_cdev, -++ enum led_brightness brightness) -++{ -++ struct ath_led *led = container_of(led_cdev, struct ath_led, cdev); -++ struct ath_softc *sc = led->sc; -++ -++ ath9k_ps_wakeup(sc); -++ ath9k_hw_set_gpio(sc->sc_ah, led->gpio->gpio, -++ (brightness != LED_OFF) ^ led->gpio->active_low); -++ ath9k_ps_restore(sc); -++} -++ -++static int ath_add_led(struct ath_softc *sc, struct ath_led *led) -++{ -++ const struct gpio_led *gpio = led->gpio; -++ int ret; -++ -++ led->cdev.name = gpio->name; -++ led->cdev.default_trigger = gpio->default_trigger; -++ led->cdev.brightness_set = ath_led_brightness; -++ -++ ret = led_classdev_register(wiphy_dev(sc->hw->wiphy), &led->cdev); -++ if (ret < 0) -++ return ret; -++ -++ led->sc = sc; -++ list_add(&led->list, &sc->leds); -+ -+ /* Configure gpio for output */ -+- ath9k_hw_gpio_request_out(ah, ah->led_pin, "ath9k-led", -++ ath9k_hw_gpio_request_out(sc->sc_ah, gpio->gpio, gpio->name, -+ AR_GPIO_OUTPUT_MUX_AS_OUTPUT); -+ -+- /* LED off, active low */ -+- ath9k_hw_set_gpio(ah, ah->led_pin, ah->config.led_active_high ? 0 : 1); -++ /* LED off */ -++ ath9k_hw_set_gpio(sc->sc_ah, gpio->gpio, gpio->active_low); -++ -++ return 0; -+ } -+ -+-static void ath_led_brightness(struct led_classdev *led_cdev, -+- enum led_brightness brightness) -++int ath_create_gpio_led(struct ath_softc *sc, int gpio_num, const char *name, -++ const char *trigger, bool active_low) -+ { -+- struct ath_softc *sc = container_of(led_cdev, struct ath_softc, led_cdev); -+- u32 val = (brightness == LED_OFF); -++ struct ath_led *led; -++ struct gpio_led *gpio; -++ char *_name; -++ int ret; -+ -+- if (sc->sc_ah->config.led_active_high) -+- val = !val; -++ led = kzalloc(sizeof(*led) + sizeof(*gpio) + strlen(name) + 1, -++ GFP_KERNEL); -++ if (!led) -++ return -ENOMEM; -++ -++ led->gpio = gpio = (struct gpio_led *) (led + 1); -++ _name = (char *) (led->gpio + 1); -++ -++ strcpy(_name, name); -++ gpio->name = _name; -++ gpio->gpio = gpio_num; -++ gpio->active_low = active_low; -++ gpio->default_trigger = trigger; -++ -++ ret = ath_add_led(sc, led); -++ if (unlikely(ret < 0)) -++ kfree(led); -+ -+- ath9k_hw_set_gpio(sc->sc_ah, sc->sc_ah->led_pin, val); -++ return ret; -+ } -+ -+ void ath_deinit_leds(struct ath_softc *sc) -+ { -+- if (!sc->led_registered) -+- return; -++ struct ath_led *led; -+ -+- ath_led_brightness(&sc->led_cdev, LED_OFF); -+- led_classdev_unregister(&sc->led_cdev); -+- -+- ath9k_hw_gpio_free(sc->sc_ah, sc->sc_ah->led_pin); -++ while (!list_empty(&sc->leds)) { -++ led = list_first_entry(&sc->leds, struct ath_led, list); -++ list_del(&led->list); -++ ath_led_brightness(&led->cdev, LED_OFF); -++ led_classdev_unregister(&led->cdev); -++ ath9k_hw_gpio_free(sc->sc_ah, led->gpio->gpio); -++ kfree(led); -++ } -+ } -+ -+ void ath_init_leds(struct ath_softc *sc) -+ { -+- int ret; -++ char led_name[32]; -++ const char *trigger; -++ -++ INIT_LIST_HEAD(&sc->leds); -+ -+ if (AR_SREV_9100(sc->sc_ah)) -+ return; -+ -+ ath_fill_led_pin(sc); -+ -+- if (!ath9k_led_blink) -+- sc->led_cdev.default_trigger = -+- ieee80211_get_radio_led_name(sc->hw); -+- -+- snprintf(sc->led_name, sizeof(sc->led_name), -+- "ath9k-%s", wiphy_name(sc->hw->wiphy)); -+- sc->led_cdev.name = sc->led_name; -+- sc->led_cdev.brightness_set = ath_led_brightness; -++ snprintf(led_name, sizeof(led_name), "ath9k-%s", -++ wiphy_name(sc->hw->wiphy)); -+ -+- ret = led_classdev_register(wiphy_dev(sc->hw->wiphy), &sc->led_cdev); -+- if (ret < 0) -+- return; -++ if (ath9k_led_blink) -++ trigger = sc->led_default_trigger; -++ else -++ trigger = ieee80211_get_radio_led_name(sc->hw); -+ -+- sc->led_registered = true; -++ ath_create_gpio_led(sc, sc->sc_ah->led_pin, led_name, trigger, -++ !sc->sc_ah->config.led_active_high); -+ } -+ #endif -+ -+--- a/drivers/net/wireless/ath/ath9k/init.c -++++ b/drivers/net/wireless/ath/ath9k/init.c -+@@ -1088,7 +1088,7 @@ int ath9k_init_device(u16 devid, struct -+ -+ #ifdef CPTCFG_MAC80211_LEDS -+ /* must be initialized before ieee80211_register_hw */ -+- sc->led_cdev.default_trigger = ieee80211_create_tpt_led_trigger(sc->hw, -++ sc->led_default_trigger = ieee80211_create_tpt_led_trigger(sc->hw, -+ IEEE80211_TPT_LEDTRIG_FL_RADIO, ath9k_tpt_blink, -+ ARRAY_SIZE(ath9k_tpt_blink)); -+ #endif -+--- a/drivers/net/wireless/ath/ath9k/debug.c -++++ b/drivers/net/wireless/ath/ath9k/debug.c -+@@ -1506,6 +1506,61 @@ static const struct file_operations fops -+ .llseek = default_llseek, -+ }; -+ -++#ifdef CONFIG_MAC80211_LEDS -++ -++static ssize_t write_file_gpio_led(struct file *file, const char __user *ubuf, -++ size_t count, loff_t *ppos) -++{ -++ struct ath_softc *sc = file->private_data; -++ char buf[32], *str, *name, *c; -++ ssize_t len; -++ unsigned int gpio; -++ bool active_low = false; -++ -++ len = min(count, sizeof(buf) - 1); -++ if (copy_from_user(buf, ubuf, len)) -++ return -EFAULT; -++ -++ buf[len] = '\0'; -++ name = strchr(buf, ','); -++ if (!name) -++ return -EINVAL; -++ -++ *(name++) = 0; -++ if (!*name) -++ return -EINVAL; -++ -++ c = strchr(name, '\n'); -++ if (c) -++ *c = 0; -++ -++ str = buf; -++ if (*str == '!') { -++ str++; -++ active_low = true; -++ } -++ -++ if (kstrtouint(str, 0, &gpio) < 0) -++ return -EINVAL; -++ -++ if (gpio >= sc->sc_ah->caps.num_gpio_pins) -++ return -EINVAL; -++ -++ if (ath_create_gpio_led(sc, gpio, name, NULL, active_low) < 0) -++ return -EINVAL; -++ -++ return count; -++} -++ -++static const struct file_operations fops_gpio_led = { -++ .write = write_file_gpio_led, -++ .open = simple_open, -++ .owner = THIS_MODULE, -++ .llseek = default_llseek, -++}; -++ -++#endif -++ -+ -+ int ath9k_init_debug(struct ath_hw *ah) -+ { -+@@ -1530,6 +1585,10 @@ int ath9k_init_debug(struct ath_hw *ah) -+ &fops_eeprom); -+ debugfs_create_file("chanbw", S_IRUSR | S_IWUSR, sc->debug.debugfs_phy, -+ sc, &fops_chanbw); -++#ifdef CONFIG_MAC80211_LEDS -++ debugfs_create_file("gpio_led", S_IWUSR, -++ sc->debug.debugfs_phy, sc, &fops_gpio_led); -++#endif -+ debugfs_create_devm_seqfile(sc->dev, "dma", sc->debug.debugfs_phy, -+ read_file_dma); -+ debugfs_create_devm_seqfile(sc->dev, "interrupt", sc->debug.debugfs_phy, -diff --git a/package/kernel/mac80211/patches/ath9k/531-ath9k_extra_platform_leds.patch b/package/kernel/mac80211/patches/ath9k/531-ath9k_extra_platform_leds.patch -new file mode 100644 -index 0000000000..8ed7ad8a09 ---- /dev/null -+++ b/package/kernel/mac80211/patches/ath9k/531-ath9k_extra_platform_leds.patch -@@ -0,0 +1,76 @@ -+--- a/include/linux/ath9k_platform.h -++++ b/include/linux/ath9k_platform.h -+@@ -46,6 +46,9 @@ struct ath9k_platform_data { -+ int (*external_reset)(void); -+ -+ bool use_eeprom; -++ -++ int num_leds; -++ const struct gpio_led *leds; -+ }; -+ -+ #endif /* _LINUX_ATH9K_PLATFORM_H */ -+--- a/drivers/net/wireless/ath/ath9k/gpio.c -++++ b/drivers/net/wireless/ath/ath9k/gpio.c -+@@ -15,6 +15,7 @@ -+ */ -+ -+ #include "ath9k.h" -++#include -+ -+ /********************************/ -+ /* LED functions */ -+@@ -108,6 +109,24 @@ int ath_create_gpio_led(struct ath_softc -+ return ret; -+ } -+ -++static int ath_create_platform_led(struct ath_softc *sc, -++ const struct gpio_led *gpio) -++{ -++ struct ath_led *led; -++ int ret; -++ -++ led = kzalloc(sizeof(*led), GFP_KERNEL); -++ if (!led) -++ return -ENOMEM; -++ -++ led->gpio = gpio; -++ ret = ath_add_led(sc, led); -++ if (ret < 0) -++ kfree(led); -++ -++ return ret; -++} -++ -+ void ath_deinit_leds(struct ath_softc *sc) -+ { -+ struct ath_led *led; -+@@ -124,8 +143,10 @@ void ath_deinit_leds(struct ath_softc *s -+ -+ void ath_init_leds(struct ath_softc *sc) -+ { -++ struct ath9k_platform_data *pdata = sc->dev->platform_data; -+ char led_name[32]; -+ const char *trigger; -++ int i; -+ -+ INIT_LIST_HEAD(&sc->leds); -+ -+@@ -134,6 +155,17 @@ void ath_init_leds(struct ath_softc *sc) -+ -+ ath_fill_led_pin(sc); -+ -++ if (pdata && pdata->leds && pdata->num_leds) -++ for (i = 0; i < pdata->num_leds; i++) { -++ if (pdata->leds[i].gpio == sc->sc_ah->led_pin) -++ sc->sc_ah->led_pin = -1; -++ -++ ath_create_platform_led(sc, &pdata->leds[i]); -++ } -++ -++ if (sc->sc_ah->led_pin < 0) -++ return; -++ -+ snprintf(led_name, sizeof(led_name), "ath9k-%s", -+ wiphy_name(sc->hw->wiphy)); -+ -diff --git a/package/kernel/mac80211/patches/ath9k/540-ath9k_reduce_ani_interval.patch b/package/kernel/mac80211/patches/ath9k/540-ath9k_reduce_ani_interval.patch -new file mode 100644 -index 0000000000..e899903478 ---- /dev/null -+++ b/package/kernel/mac80211/patches/ath9k/540-ath9k_reduce_ani_interval.patch -@@ -0,0 +1,11 @@ -+--- a/drivers/net/wireless/ath/ath9k/ani.h -++++ b/drivers/net/wireless/ath/ath9k/ani.h -+@@ -42,7 +42,7 @@ -+ #define ATH9K_ANI_PERIOD 300 -+ -+ /* in ms */ -+-#define ATH9K_ANI_POLLINTERVAL 1000 -++#define ATH9K_ANI_POLLINTERVAL 300 -+ -+ #define ATH9K_SIG_FIRSTEP_SETTING_MIN 0 -+ #define ATH9K_SIG_FIRSTEP_SETTING_MAX 20 -diff --git a/package/kernel/mac80211/patches/ath9k/542-ath9k_debugfs_diag.patch b/package/kernel/mac80211/patches/ath9k/542-ath9k_debugfs_diag.patch -new file mode 100644 -index 0000000000..e09bbc08ea ---- /dev/null -+++ b/package/kernel/mac80211/patches/ath9k/542-ath9k_debugfs_diag.patch -@@ -0,0 +1,139 @@ -+--- a/drivers/net/wireless/ath/ath9k/debug.c -++++ b/drivers/net/wireless/ath/ath9k/debug.c -+@@ -1562,6 +1562,50 @@ static const struct file_operations fops -+ #endif -+ -+ -++static ssize_t read_file_diag(struct file *file, char __user *user_buf, -++ size_t count, loff_t *ppos) -++{ -++ struct ath_softc *sc = file->private_data; -++ struct ath_hw *ah = sc->sc_ah; -++ char buf[32]; -++ unsigned int len; -++ -++ len = sprintf(buf, "0x%08lx\n", ah->diag); -++ return simple_read_from_buffer(user_buf, count, ppos, buf, len); -++} -++ -++static ssize_t write_file_diag(struct file *file, const char __user *user_buf, -++ size_t count, loff_t *ppos) -++{ -++ struct ath_softc *sc = file->private_data; -++ struct ath_hw *ah = sc->sc_ah; -++ unsigned long diag; -++ char buf[32]; -++ ssize_t len; -++ -++ len = min(count, sizeof(buf) - 1); -++ if (copy_from_user(buf, user_buf, len)) -++ return -EFAULT; -++ -++ buf[len] = '\0'; -++ if (kstrtoul(buf, 0, &diag)) -++ return -EINVAL; -++ -++ ah->diag = diag; -++ ath9k_hw_update_diag(ah); -++ -++ return count; -++} -++ -++static const struct file_operations fops_diag = { -++ .read = read_file_diag, -++ .write = write_file_diag, -++ .open = simple_open, -++ .owner = THIS_MODULE, -++ .llseek = default_llseek, -++}; -++ -++ -+ int ath9k_init_debug(struct ath_hw *ah) -+ { -+ struct ath_common *common = ath9k_hw_common(ah); -+@@ -1589,6 +1633,8 @@ int ath9k_init_debug(struct ath_hw *ah) -+ debugfs_create_file("gpio_led", S_IWUSR, -+ sc->debug.debugfs_phy, sc, &fops_gpio_led); -+ #endif -++ debugfs_create_file("diag", S_IRUSR | S_IWUSR, sc->debug.debugfs_phy, -++ sc, &fops_diag); -+ debugfs_create_devm_seqfile(sc->dev, "dma", sc->debug.debugfs_phy, -+ read_file_dma); -+ debugfs_create_devm_seqfile(sc->dev, "interrupt", sc->debug.debugfs_phy, -+--- a/drivers/net/wireless/ath/ath9k/hw.h -++++ b/drivers/net/wireless/ath/ath9k/hw.h -+@@ -522,6 +522,12 @@ enum { -+ ATH9K_RESET_COLD, -+ }; -+ -++enum { -++ ATH_DIAG_DISABLE_RX, -++ ATH_DIAG_DISABLE_TX, -++ ATH_DIAG_TRIGGER_ERROR, -++}; -++ -+ struct ath9k_hw_version { -+ u32 magic; -+ u16 devid; -+@@ -810,6 +816,8 @@ struct ath_hw { -+ u32 ah_flags; -+ s16 nf_override; -+ -++ unsigned long diag; -++ -+ bool reset_power_on; -+ bool htc_reset_init; -+ -+@@ -1079,6 +1087,7 @@ void ath9k_hw_check_nav(struct ath_hw *a -+ bool ath9k_hw_check_alive(struct ath_hw *ah); -+ -+ bool ath9k_hw_setpower(struct ath_hw *ah, enum ath9k_power_mode mode); -++void ath9k_hw_update_diag(struct ath_hw *ah); -+ -+ /* Generic hw timer primitives */ -+ struct ath_gen_timer *ath_gen_timer_alloc(struct ath_hw *ah, -+--- a/drivers/net/wireless/ath/ath9k/hw.c -++++ b/drivers/net/wireless/ath/ath9k/hw.c -+@@ -1881,6 +1881,20 @@ u32 ath9k_hw_get_tsf_offset(struct times -+ } -+ EXPORT_SYMBOL(ath9k_hw_get_tsf_offset); -+ -++void ath9k_hw_update_diag(struct ath_hw *ah) -++{ -++ if (test_bit(ATH_DIAG_DISABLE_RX, &ah->diag)) -++ REG_SET_BIT(ah, AR_DIAG_SW, AR_DIAG_RX_DIS); -++ else -++ REG_CLR_BIT(ah, AR_DIAG_SW, AR_DIAG_RX_DIS); -++ -++ if (test_bit(ATH_DIAG_DISABLE_TX, &ah->diag)) -++ REG_SET_BIT(ah, AR_DIAG_SW, AR_DIAG_LOOP_BACK); -++ else -++ REG_CLR_BIT(ah, AR_DIAG_SW, AR_DIAG_LOOP_BACK); -++} -++EXPORT_SYMBOL(ath9k_hw_update_diag); -++ -+ int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan, -+ struct ath9k_hw_cal_data *caldata, bool fastcc) -+ { -+@@ -2089,6 +2103,7 @@ int ath9k_hw_reset(struct ath_hw *ah, st -+ ar9003_hw_disable_phy_restart(ah); -+ -+ ath9k_hw_apply_gpio_override(ah); -++ ath9k_hw_update_diag(ah); -+ -+ if (AR_SREV_9565(ah) && common->bt_ant_diversity) -+ REG_SET_BIT(ah, AR_BTCOEX_WL_LNADIV, AR_BTCOEX_WL_LNADIV_FORCE_ON); -+--- a/drivers/net/wireless/ath/ath9k/main.c -++++ b/drivers/net/wireless/ath/ath9k/main.c -+@@ -538,6 +538,11 @@ irqreturn_t ath_isr(int irq, void *dev) -+ return IRQ_HANDLED; -+ } -+ -++ if (test_bit(ATH_DIAG_TRIGGER_ERROR, &ah->diag)) { -++ status |= ATH9K_INT_FATAL; -++ clear_bit(ATH_DIAG_TRIGGER_ERROR, &ah->diag); -++ } -++ -+ /* -+ * If there are no status bits set, then this interrupt was not -+ * for me (should have been caught above). -diff --git a/package/kernel/mac80211/patches/ath9k/543-ath9k_entropy_from_adc.patch b/package/kernel/mac80211/patches/ath9k/543-ath9k_entropy_from_adc.patch -new file mode 100644 -index 0000000000..6acc864d1e ---- /dev/null -+++ b/package/kernel/mac80211/patches/ath9k/543-ath9k_entropy_from_adc.patch -@@ -0,0 +1,186 @@ -+--- a/drivers/net/wireless/ath/ath9k/hw.h -++++ b/drivers/net/wireless/ath/ath9k/hw.h -+@@ -723,6 +723,7 @@ struct ath_spec_scan { -+ * @config_pci_powersave: -+ * @calibrate: periodic calibration for NF, ANI, IQ, ADC gain, ADC-DC -+ * -++ * @get_adc_entropy: get entropy from the raw ADC I/Q output -+ * @spectral_scan_config: set parameters for spectral scan and enable/disable it -+ * @spectral_scan_trigger: trigger a spectral scan run -+ * @spectral_scan_wait: wait for a spectral scan run to finish -+@@ -745,6 +746,7 @@ struct ath_hw_ops { -+ struct ath_hw_antcomb_conf *antconf); -+ void (*antdiv_comb_conf_set)(struct ath_hw *ah, -+ struct ath_hw_antcomb_conf *antconf); -++ void (*get_adc_entropy)(struct ath_hw *ah, u8 *buf, size_t len); -+ void (*spectral_scan_config)(struct ath_hw *ah, -+ struct ath_spec_scan *param); -+ void (*spectral_scan_trigger)(struct ath_hw *ah); -+--- a/drivers/net/wireless/ath/ath9k/ar9003_phy.c -++++ b/drivers/net/wireless/ath/ath9k/ar9003_phy.c -+@@ -1918,6 +1918,26 @@ void ar9003_hw_init_rate_txpower(struct -+ } -+ } -+ -++static void ar9003_hw_get_adc_entropy(struct ath_hw *ah, u8 *buf, size_t len) -++{ -++ int i, j; -++ -++ REG_RMW_FIELD(ah, AR_PHY_TEST, AR_PHY_TEST_BBB_OBS_SEL, 1); -++ REG_CLR_BIT(ah, AR_PHY_TEST, AR_PHY_TEST_RX_OBS_SEL_BIT5); -++ REG_RMW_FIELD(ah, AR_PHY_TEST_CTL_STATUS, AR_PHY_TEST_CTL_RX_OBS_SEL, 0); -++ -++ memset(buf, 0, len); -++ for (i = 0; i < len; i++) { -++ for (j = 0; j < 4; j++) { -++ u32 regval = REG_READ(ah, AR_PHY_TST_ADC); -++ -++ buf[i] <<= 2; -++ buf[i] |= (regval & 1) | ((regval & BIT(10)) >> 9); -++ udelay(1); -++ } -++ } -++} -++ -+ void ar9003_hw_attach_phy_ops(struct ath_hw *ah) -+ { -+ struct ath_hw_private_ops *priv_ops = ath9k_hw_private_ops(ah); -+@@ -1954,6 +1974,7 @@ void ar9003_hw_attach_phy_ops(struct ath -+ priv_ops->set_radar_params = ar9003_hw_set_radar_params; -+ priv_ops->fast_chan_change = ar9003_hw_fast_chan_change; -+ -++ ops->get_adc_entropy = ar9003_hw_get_adc_entropy; -+ ops->antdiv_comb_conf_get = ar9003_hw_antdiv_comb_conf_get; -+ ops->antdiv_comb_conf_set = ar9003_hw_antdiv_comb_conf_set; -+ ops->spectral_scan_config = ar9003_hw_spectral_scan_config; -+--- a/drivers/net/wireless/ath/ath9k/init.c -++++ b/drivers/net/wireless/ath/ath9k/init.c -+@@ -870,7 +870,8 @@ static void ath9k_init_txpower_limits(st -+ if (ah->caps.hw_caps & ATH9K_HW_CAP_5GHZ) -+ ath9k_init_band_txpower(sc, NL80211_BAND_5GHZ); -+ -+- ah->curchan = curchan; -++ if (curchan) -++ ah->curchan = curchan; -+ } -+ -+ static const struct ieee80211_iface_limit if_limits[] = { -+@@ -1048,6 +1049,18 @@ static void ath9k_set_hw_capab(struct at -+ wiphy_ext_feature_set(hw->wiphy, NL80211_EXT_FEATURE_CAN_REPLACE_PTK0); -+ } -+ -++static void ath_get_initial_entropy(struct ath_softc *sc) -++{ -++ struct ath_hw *ah = sc->sc_ah; -++ char buf[256]; -++ -++ /* reuse last channel initialized by the tx power test */ -++ ath9k_hw_reset(ah, ah->curchan, NULL, false); -++ -++ ath9k_hw_get_adc_entropy(ah, buf, sizeof(buf)); -++ add_device_randomness(buf, sizeof(buf)); -++} -++ -+ int ath9k_init_device(u16 devid, struct ath_softc *sc, -+ const struct ath_bus_ops *bus_ops) -+ { -+@@ -1095,6 +1108,8 @@ int ath9k_init_device(u16 devid, struct -+ -+ wiphy_read_of_freq_limits(hw->wiphy); -+ -++ ath_get_initial_entropy(sc); -++ -+ /* Register with mac80211 */ -+ error = ieee80211_register_hw(hw); -+ if (error) -+--- a/drivers/net/wireless/ath/ath9k/hw-ops.h -++++ b/drivers/net/wireless/ath/ath9k/hw-ops.h -+@@ -100,6 +100,12 @@ static inline void ath9k_hw_tx99_set_txp -+ ath9k_hw_ops(ah)->tx99_set_txpower(ah, power); -+ } -+ -++static inline void ath9k_hw_get_adc_entropy(struct ath_hw *ah, -++ u8 *buf, size_t len) -++{ -++ ath9k_hw_ops(ah)->get_adc_entropy(ah, buf, len); -++} -++ -+ #ifdef CPTCFG_ATH9K_BTCOEX_SUPPORT -+ -+ static inline void ath9k_hw_set_bt_ant_diversity(struct ath_hw *ah, bool enable) -+--- a/drivers/net/wireless/ath/ath9k/ar5008_phy.c -++++ b/drivers/net/wireless/ath/ath9k/ar5008_phy.c -+@@ -1340,9 +1340,30 @@ void ar5008_hw_init_rate_txpower(struct -+ } -+ } -+ -++static void ar5008_hw_get_adc_entropy(struct ath_hw *ah, u8 *buf, size_t len) -++{ -++ int i, j; -++ -++ REG_RMW_FIELD(ah, AR_PHY_TEST, AR_PHY_TEST_BBB_OBS_SEL, 1); -++ REG_CLR_BIT(ah, AR_PHY_TEST, AR_PHY_TEST_RX_OBS_SEL_BIT5); -++ REG_RMW_FIELD(ah, AR_PHY_TEST2, AR_PHY_TEST2_RX_OBS_SEL, 0); -++ -++ memset(buf, 0, len); -++ for (i = 0; i < len; i++) { -++ for (j = 0; j < 4; j++) { -++ u32 regval = REG_READ(ah, AR_PHY_TST_ADC); -++ -++ buf[i] <<= 2; -++ buf[i] |= (regval & 1) | ((regval & BIT(9)) >> 8); -++ udelay(1); -++ } -++ } -++} -++ -+ int ar5008_hw_attach_phy_ops(struct ath_hw *ah) -+ { -+ struct ath_hw_private_ops *priv_ops = ath9k_hw_private_ops(ah); -++ struct ath_hw_ops *ops = ath9k_hw_ops(ah); -+ static const u32 ar5416_cca_regs[6] = { -+ AR_PHY_CCA, -+ AR_PHY_CH1_CCA, -+@@ -1357,6 +1378,8 @@ int ar5008_hw_attach_phy_ops(struct ath_ -+ if (ret) -+ return ret; -+ -++ ops->get_adc_entropy = ar5008_hw_get_adc_entropy; -++ -+ priv_ops->rf_set_freq = ar5008_hw_set_channel; -+ priv_ops->spur_mitigate_freq = ar5008_hw_spur_mitigate; -+ -+--- a/drivers/net/wireless/ath/ath9k/ar9002_phy.h -++++ b/drivers/net/wireless/ath/ath9k/ar9002_phy.h -+@@ -20,6 +20,12 @@ -+ #define PHY_AGC_CLR 0x10000000 -+ #define RFSILENT_BB 0x00002000 -+ -++#define AR_PHY_TEST_BBB_OBS_SEL 0x780000 -++#define AR_PHY_TEST_BBB_OBS_SEL_S 19 -++ -++#define AR_PHY_TEST_RX_OBS_SEL_BIT5_S 23 -++#define AR_PHY_TEST_RX_OBS_SEL_BIT5 (1 << AR_PHY_TEST_RX_OBS_SEL_BIT5_S) -++ -+ #define AR_PHY_TURBO 0x9804 -+ #define AR_PHY_FC_TURBO_MODE 0x00000001 -+ #define AR_PHY_FC_TURBO_SHORT 0x00000002 -+@@ -36,6 +42,9 @@ -+ -+ #define AR_PHY_TEST2 0x9808 -+ -++#define AR_PHY_TEST2_RX_OBS_SEL 0x3C00 -++#define AR_PHY_TEST2_RX_OBS_SEL_S 10 -++ -+ #define AR_PHY_TIMING2 0x9810 -+ #define AR_PHY_TIMING3 0x9814 -+ #define AR_PHY_TIMING3_DSC_MAN 0xFFFE0000 -+@@ -393,6 +402,8 @@ -+ #define AR_PHY_RFBUS_GRANT 0x9C20 -+ #define AR_PHY_RFBUS_GRANT_EN 0x00000001 -+ -++#define AR_PHY_TST_ADC 0x9C24 -++ -+ #define AR_PHY_CHAN_INFO_GAIN_DIFF 0x9CF4 -+ #define AR_PHY_CHAN_INFO_GAIN_DIFF_UPPER_LIMIT 320 -+ -diff --git a/package/kernel/mac80211/patches/ath9k/544-ath9k-ar933x-usb-hang-workaround.patch b/package/kernel/mac80211/patches/ath9k/544-ath9k-ar933x-usb-hang-workaround.patch -new file mode 100644 -index 0000000000..23a81864fa ---- /dev/null -+++ b/package/kernel/mac80211/patches/ath9k/544-ath9k-ar933x-usb-hang-workaround.patch -@@ -0,0 +1,79 @@ -+--- a/drivers/net/wireless/ath/ath9k/hw.c -++++ b/drivers/net/wireless/ath/ath9k/hw.c -+@@ -247,6 +247,19 @@ void ath9k_hw_get_channel_centers(struct -+ centers->synth_center + (extoff * HT40_CHANNEL_CENTER_SHIFT); -+ } -+ -++static inline void ath9k_hw_disable_pll_lock_detect(struct ath_hw *ah) -++{ -++ /* On AR9330 and AR9340 devices, some PHY registers must be -++ * tuned to gain better stability/performance. These registers -++ * might be changed while doing wlan reset so the registers must -++ * be reprogrammed after each reset. -++ */ -++ REG_CLR_BIT(ah, AR_PHY_USB_CTRL1, BIT(20)); -++ REG_RMW(ah, AR_PHY_USB_CTRL2, -++ (1 << 21) | (0xf << 22), -++ (1 << 21) | (0x3 << 22)); -++} -++ -+ /******************/ -+ /* Chip Revisions */ -+ /******************/ -+@@ -1454,6 +1467,9 @@ static bool ath9k_hw_set_reset(struct at -+ udelay(50); -+ } -+ -++ if (AR_SREV_9330(ah) || AR_SREV_9340(ah)) -++ ath9k_hw_disable_pll_lock_detect(ah); -++ -+ return true; -+ } -+ -+@@ -1553,6 +1569,9 @@ static bool ath9k_hw_chip_reset(struct a -+ ar9003_hw_internal_regulator_apply(ah); -+ ath9k_hw_init_pll(ah, chan); -+ -++ if (AR_SREV_9330(ah) || AR_SREV_9340(ah)) -++ ath9k_hw_disable_pll_lock_detect(ah); -++ -+ return true; -+ } -+ -+@@ -1859,8 +1878,14 @@ static int ath9k_hw_do_fastcc(struct ath -+ if (AR_SREV_9271(ah)) -+ ar9002_hw_load_ani_reg(ah, chan); -+ -++ if (AR_SREV_9330(ah) || AR_SREV_9340(ah)) -++ ath9k_hw_disable_pll_lock_detect(ah); -++ -+ return 0; -+ fail: -++ if (AR_SREV_9330(ah) || AR_SREV_9340(ah)) -++ ath9k_hw_disable_pll_lock_detect(ah); -++ -+ return -EINVAL; -+ } -+ -+@@ -2114,6 +2139,9 @@ int ath9k_hw_reset(struct ath_hw *ah, st -+ ath9k_hw_set_radar_params(ah); -+ } -+ -++ if (AR_SREV_9330(ah) || AR_SREV_9340(ah)) -++ ath9k_hw_disable_pll_lock_detect(ah); -++ -+ return 0; -+ } -+ EXPORT_SYMBOL(ath9k_hw_reset); -+--- a/drivers/net/wireless/ath/ath9k/phy.h -++++ b/drivers/net/wireless/ath/ath9k/phy.h -+@@ -48,6 +48,9 @@ -+ #define AR_PHY_PLL_CONTROL 0x16180 -+ #define AR_PHY_PLL_MODE 0x16184 -+ -++#define AR_PHY_USB_CTRL1 0x16c84 -++#define AR_PHY_USB_CTRL2 0x16c88 -++ -+ enum ath9k_ant_div_comb_lna_conf { -+ ATH_ANT_DIV_COMB_LNA1_MINUS_LNA2, -+ ATH_ANT_DIV_COMB_LNA2, -diff --git a/package/kernel/mac80211/patches/ath9k/545-ath9k_ani_ws_detect.patch b/package/kernel/mac80211/patches/ath9k/545-ath9k_ani_ws_detect.patch -new file mode 100644 -index 0000000000..d3bf07ff92 ---- /dev/null -+++ b/package/kernel/mac80211/patches/ath9k/545-ath9k_ani_ws_detect.patch -@@ -0,0 +1,155 @@ -+--- a/drivers/net/wireless/ath/ath9k/ar5008_phy.c -++++ b/drivers/net/wireless/ath/ath9k/ar5008_phy.c -+@@ -969,55 +969,6 @@ static bool ar5008_hw_ani_control_new(st -+ * on == 0 means more noise imm -+ */ -+ u32 on = param ? 1 : 0; -+- /* -+- * make register setting for default -+- * (weak sig detect ON) come from INI file -+- */ -+- int m1ThreshLow = on ? -+- aniState->iniDef.m1ThreshLow : m1ThreshLow_off; -+- int m2ThreshLow = on ? -+- aniState->iniDef.m2ThreshLow : m2ThreshLow_off; -+- int m1Thresh = on ? -+- aniState->iniDef.m1Thresh : m1Thresh_off; -+- int m2Thresh = on ? -+- aniState->iniDef.m2Thresh : m2Thresh_off; -+- int m2CountThr = on ? -+- aniState->iniDef.m2CountThr : m2CountThr_off; -+- int m2CountThrLow = on ? -+- aniState->iniDef.m2CountThrLow : m2CountThrLow_off; -+- int m1ThreshLowExt = on ? -+- aniState->iniDef.m1ThreshLowExt : m1ThreshLowExt_off; -+- int m2ThreshLowExt = on ? -+- aniState->iniDef.m2ThreshLowExt : m2ThreshLowExt_off; -+- int m1ThreshExt = on ? -+- aniState->iniDef.m1ThreshExt : m1ThreshExt_off; -+- int m2ThreshExt = on ? -+- aniState->iniDef.m2ThreshExt : m2ThreshExt_off; -+- -+- REG_RMW_FIELD(ah, AR_PHY_SFCORR_LOW, -+- AR_PHY_SFCORR_LOW_M1_THRESH_LOW, -+- m1ThreshLow); -+- REG_RMW_FIELD(ah, AR_PHY_SFCORR_LOW, -+- AR_PHY_SFCORR_LOW_M2_THRESH_LOW, -+- m2ThreshLow); -+- REG_RMW_FIELD(ah, AR_PHY_SFCORR, -+- AR_PHY_SFCORR_M1_THRESH, m1Thresh); -+- REG_RMW_FIELD(ah, AR_PHY_SFCORR, -+- AR_PHY_SFCORR_M2_THRESH, m2Thresh); -+- REG_RMW_FIELD(ah, AR_PHY_SFCORR, -+- AR_PHY_SFCORR_M2COUNT_THR, m2CountThr); -+- REG_RMW_FIELD(ah, AR_PHY_SFCORR_LOW, -+- AR_PHY_SFCORR_LOW_M2COUNT_THR_LOW, -+- m2CountThrLow); -+- -+- REG_RMW_FIELD(ah, AR_PHY_SFCORR_EXT, -+- AR_PHY_SFCORR_EXT_M1_THRESH_LOW, m1ThreshLowExt); -+- REG_RMW_FIELD(ah, AR_PHY_SFCORR_EXT, -+- AR_PHY_SFCORR_EXT_M2_THRESH_LOW, m2ThreshLowExt); -+- REG_RMW_FIELD(ah, AR_PHY_SFCORR_EXT, -+- AR_PHY_SFCORR_EXT_M1_THRESH, m1ThreshExt); -+- REG_RMW_FIELD(ah, AR_PHY_SFCORR_EXT, -+- AR_PHY_SFCORR_EXT_M2_THRESH, m2ThreshExt); -+ -+ if (on) -+ REG_SET_BIT(ah, AR_PHY_SFCORR_LOW, -+--- a/drivers/net/wireless/ath/ath9k/ar9003_phy.c -++++ b/drivers/net/wireless/ath/ath9k/ar9003_phy.c -+@@ -42,20 +42,6 @@ static const int cycpwrThr1_table[] = -+ /* level: 0 1 2 3 4 5 6 7 8 */ -+ { -6, -4, -2, 0, 2, 4, 6, 8 }; /* lvl 0-7, default 3 */ -+ -+-/* -+- * register values to turn OFDM weak signal detection OFF -+- */ -+-static const int m1ThreshLow_off = 127; -+-static const int m2ThreshLow_off = 127; -+-static const int m1Thresh_off = 127; -+-static const int m2Thresh_off = 127; -+-static const int m2CountThr_off = 31; -+-static const int m2CountThrLow_off = 63; -+-static const int m1ThreshLowExt_off = 127; -+-static const int m2ThreshLowExt_off = 127; -+-static const int m1ThreshExt_off = 127; -+-static const int m2ThreshExt_off = 127; -+- -+ static const u8 ofdm2pwr[] = { -+ ALL_TARGET_LEGACY_6_24, -+ ALL_TARGET_LEGACY_6_24, -+@@ -1068,11 +1054,6 @@ static bool ar9003_hw_ani_control(struct -+ struct ath_common *common = ath9k_hw_common(ah); -+ struct ath9k_channel *chan = ah->curchan; -+ struct ar5416AniState *aniState = &ah->ani; -+- int m1ThreshLow, m2ThreshLow; -+- int m1Thresh, m2Thresh; -+- int m2CountThr, m2CountThrLow; -+- int m1ThreshLowExt, m2ThreshLowExt; -+- int m1ThreshExt, m2ThreshExt; -+ s32 value, value2; -+ -+ switch (cmd & ah->ani_function) { -+@@ -1086,61 +1067,6 @@ static bool ar9003_hw_ani_control(struct -+ */ -+ u32 on = param ? 1 : 0; -+ -+- if (AR_SREV_9462(ah) || AR_SREV_9565(ah)) -+- goto skip_ws_det; -+- -+- m1ThreshLow = on ? -+- aniState->iniDef.m1ThreshLow : m1ThreshLow_off; -+- m2ThreshLow = on ? -+- aniState->iniDef.m2ThreshLow : m2ThreshLow_off; -+- m1Thresh = on ? -+- aniState->iniDef.m1Thresh : m1Thresh_off; -+- m2Thresh = on ? -+- aniState->iniDef.m2Thresh : m2Thresh_off; -+- m2CountThr = on ? -+- aniState->iniDef.m2CountThr : m2CountThr_off; -+- m2CountThrLow = on ? -+- aniState->iniDef.m2CountThrLow : m2CountThrLow_off; -+- m1ThreshLowExt = on ? -+- aniState->iniDef.m1ThreshLowExt : m1ThreshLowExt_off; -+- m2ThreshLowExt = on ? -+- aniState->iniDef.m2ThreshLowExt : m2ThreshLowExt_off; -+- m1ThreshExt = on ? -+- aniState->iniDef.m1ThreshExt : m1ThreshExt_off; -+- m2ThreshExt = on ? -+- aniState->iniDef.m2ThreshExt : m2ThreshExt_off; -+- -+- REG_RMW_FIELD(ah, AR_PHY_SFCORR_LOW, -+- AR_PHY_SFCORR_LOW_M1_THRESH_LOW, -+- m1ThreshLow); -+- REG_RMW_FIELD(ah, AR_PHY_SFCORR_LOW, -+- AR_PHY_SFCORR_LOW_M2_THRESH_LOW, -+- m2ThreshLow); -+- REG_RMW_FIELD(ah, AR_PHY_SFCORR, -+- AR_PHY_SFCORR_M1_THRESH, -+- m1Thresh); -+- REG_RMW_FIELD(ah, AR_PHY_SFCORR, -+- AR_PHY_SFCORR_M2_THRESH, -+- m2Thresh); -+- REG_RMW_FIELD(ah, AR_PHY_SFCORR, -+- AR_PHY_SFCORR_M2COUNT_THR, -+- m2CountThr); -+- REG_RMW_FIELD(ah, AR_PHY_SFCORR_LOW, -+- AR_PHY_SFCORR_LOW_M2COUNT_THR_LOW, -+- m2CountThrLow); -+- REG_RMW_FIELD(ah, AR_PHY_SFCORR_EXT, -+- AR_PHY_SFCORR_EXT_M1_THRESH_LOW, -+- m1ThreshLowExt); -+- REG_RMW_FIELD(ah, AR_PHY_SFCORR_EXT, -+- AR_PHY_SFCORR_EXT_M2_THRESH_LOW, -+- m2ThreshLowExt); -+- REG_RMW_FIELD(ah, AR_PHY_SFCORR_EXT, -+- AR_PHY_SFCORR_EXT_M1_THRESH, -+- m1ThreshExt); -+- REG_RMW_FIELD(ah, AR_PHY_SFCORR_EXT, -+- AR_PHY_SFCORR_EXT_M2_THRESH, -+- m2ThreshExt); -+-skip_ws_det: -+ if (on) -+ REG_SET_BIT(ah, AR_PHY_SFCORR_LOW, -+ AR_PHY_SFCORR_LOW_USE_SELF_CORR_LOW); -diff --git a/package/kernel/mac80211/patches/ath9k/547-ath9k_led_defstate_fix.patch b/package/kernel/mac80211/patches/ath9k/547-ath9k_led_defstate_fix.patch -new file mode 100644 -index 0000000000..5d84cf0c42 ---- /dev/null -+++ b/package/kernel/mac80211/patches/ath9k/547-ath9k_led_defstate_fix.patch -@@ -0,0 +1,29 @@ -+From: Michal Cieslakiewicz -+Date: Sun, 31 Jan 2016 20:48:49 +0100 -+Subject: [PATCH v4 2/8] mac80211: ath9k: set default state for platform LEDs -+ -+Support default state for platform LEDs connected to ath9k device. -+Now LEDs are correctly set on or off at ath9k module initialization. -+Very useful if power LED is connected to wireless chip. -+ -+Signed-off-by: Michal Cieslakiewicz -+--- -+ gpio.c | 7 +++++-- -+ 1 file changed, 5 insertions(+), 2 deletions(-) -+ -+--- a/drivers/net/wireless/ath/ath9k/gpio.c -++++ b/drivers/net/wireless/ath/ath9k/gpio.c -+@@ -74,8 +74,11 @@ static int ath_add_led(struct ath_softc -+ ath9k_hw_gpio_request_out(sc->sc_ah, gpio->gpio, gpio->name, -+ AR_GPIO_OUTPUT_MUX_AS_OUTPUT); -+ -+- /* LED off */ -+- ath9k_hw_set_gpio(sc->sc_ah, gpio->gpio, gpio->active_low); -++ /* Set default LED state */ -++ if (gpio->default_state == LEDS_GPIO_DEFSTATE_ON) -++ ath9k_hw_set_gpio(sc->sc_ah, gpio->gpio, !gpio->active_low); -++ else -++ ath9k_hw_set_gpio(sc->sc_ah, gpio->gpio, gpio->active_low); -+ -+ return 0; -+ } -diff --git a/package/kernel/mac80211/patches/ath9k/548-ath9k_enable_gpio_chip.patch b/package/kernel/mac80211/patches/ath9k/548-ath9k_enable_gpio_chip.patch -new file mode 100644 -index 0000000000..78206d2860 ---- /dev/null -+++ b/package/kernel/mac80211/patches/ath9k/548-ath9k_enable_gpio_chip.patch -@@ -0,0 +1,251 @@ -+From: Michal Cieslakiewicz -+Date: Sun, 31 Jan 2016 21:01:31 +0100 -+Subject: [PATCH v4 4/8] mac80211: ath9k: enable access to GPIO -+ -+Enable access to GPIO chip and its pins for Atheros AR92xx -+wireless devices. For now AR9285 and AR9287 are supported. -+ -+Signed-off-by: Michal Cieslakiewicz -+Signed-off-by: Felix Fietkau -+--- -+--- a/drivers/net/wireless/ath/ath9k/ath9k.h -++++ b/drivers/net/wireless/ath/ath9k/ath9k.h -+@@ -24,6 +24,7 @@ -+ #include -+ #include -+ #include -++#include -+ -+ #include "common.h" -+ #include "debug.h" -+@@ -989,6 +990,14 @@ struct ath_led { -+ struct led_classdev cdev; -+ }; -+ -++#ifdef CONFIG_GPIOLIB -++struct ath9k_gpio_chip { -++ struct ath_softc *sc; -++ char label[32]; -++ struct gpio_chip gchip; -++}; -++#endif -++ -+ struct ath_softc { -+ struct ieee80211_hw *hw; -+ struct device *dev; -+@@ -1044,6 +1053,9 @@ struct ath_softc { -+ #ifdef CPTCFG_MAC80211_LEDS -+ const char *led_default_trigger; -+ struct list_head leds; -++#ifdef CONFIG_GPIOLIB -++ struct ath9k_gpio_chip *gpiochip; -++#endif -+ #endif -+ -+ #ifdef CPTCFG_ATH9K_DEBUGFS -+--- a/drivers/net/wireless/ath/ath9k/gpio.c -++++ b/drivers/net/wireless/ath/ath9k/gpio.c -+@@ -16,13 +16,139 @@ -+ -+ #include "ath9k.h" -+ #include -++#include -++ -++#ifdef CPTCFG_MAC80211_LEDS -++ -++#ifdef CONFIG_GPIOLIB -++ -++/***************/ -++/* GPIO Chip */ -++/***************/ -++ -++/* gpio_chip handler : set GPIO to input */ -++static int ath9k_gpio_pin_cfg_input(struct gpio_chip *chip, unsigned offset) -++{ -++ struct ath9k_gpio_chip *gc = container_of(chip, struct ath9k_gpio_chip, -++ gchip); -++ -++ ath9k_hw_gpio_request_in(gc->sc->sc_ah, offset, "ath9k-gpio"); -++ -++ return 0; -++} -++ -++/* gpio_chip handler : set GPIO to output */ -++static int ath9k_gpio_pin_cfg_output(struct gpio_chip *chip, unsigned offset, -++ int value) -++{ -++ struct ath9k_gpio_chip *gc = container_of(chip, struct ath9k_gpio_chip, -++ gchip); -++ -++ ath9k_hw_gpio_request_out(gc->sc->sc_ah, offset, "ath9k-gpio", -++ AR_GPIO_OUTPUT_MUX_AS_OUTPUT); -++ ath9k_hw_set_gpio(gc->sc->sc_ah, offset, value); -++ -++ return 0; -++} -++ -++/* gpio_chip handler : query GPIO direction (0=out, 1=in) */ -++static int ath9k_gpio_pin_get_dir(struct gpio_chip *chip, unsigned offset) -++{ -++ struct ath9k_gpio_chip *gc = container_of(chip, struct ath9k_gpio_chip, -++ gchip); -++ struct ath_hw *ah = gc->sc->sc_ah; -++ -++ return !((REG_READ(ah, AR_GPIO_OE_OUT) >> (offset * 2)) & 3); -++} -++ -++/* gpio_chip handler : get GPIO pin value */ -++static int ath9k_gpio_pin_get(struct gpio_chip *chip, unsigned offset) -++{ -++ struct ath9k_gpio_chip *gc = container_of(chip, struct ath9k_gpio_chip, -++ gchip); -++ -++ return ath9k_hw_gpio_get(gc->sc->sc_ah, offset); -++} -++ -++/* gpio_chip handler : set GPIO pin to value */ -++static void ath9k_gpio_pin_set(struct gpio_chip *chip, unsigned offset, -++ int value) -++{ -++ struct ath9k_gpio_chip *gc = container_of(chip, struct ath9k_gpio_chip, -++ gchip); -++ -++ ath9k_hw_set_gpio(gc->sc->sc_ah, offset, value); -++} -++ -++/* register GPIO chip */ -++static void ath9k_register_gpio_chip(struct ath_softc *sc) -++{ -++ struct ath9k_gpio_chip *gc; -++ struct ath_hw *ah = sc->sc_ah; -++ -++ gc = kzalloc(sizeof(struct ath9k_gpio_chip), GFP_KERNEL); -++ if (!gc) -++ return; -++ -++ gc->sc = sc; -++ snprintf(gc->label, sizeof(gc->label), "ath9k-%s", -++ wiphy_name(sc->hw->wiphy)); -++#ifdef CONFIG_OF -++#if LINUX_VERSION_CODE >= KERNEL_VERSION(4,5,0) -++ gc->gchip.parent = sc->dev; -++#else -++ gc->gchip.dev = sc->dev; -++#endif -++#endif -++ gc->gchip.label = gc->label; -++ gc->gchip.base = -1; /* determine base automatically */ -++ gc->gchip.ngpio = ah->caps.num_gpio_pins; -++ gc->gchip.direction_input = ath9k_gpio_pin_cfg_input; -++ gc->gchip.direction_output = ath9k_gpio_pin_cfg_output; -++ gc->gchip.get_direction = ath9k_gpio_pin_get_dir; -++ gc->gchip.get = ath9k_gpio_pin_get; -++ gc->gchip.set = ath9k_gpio_pin_set; -++ -++ if (gpiochip_add(&gc->gchip)) { -++ kfree(gc); -++ return; -++ } -++ -++#ifdef CONFIG_OF -++ gc->gchip.owner = NULL; -++#endif -++ sc->gpiochip = gc; -++} -++ -++/* remove GPIO chip */ -++static void ath9k_unregister_gpio_chip(struct ath_softc *sc) -++{ -++ struct ath9k_gpio_chip *gc = sc->gpiochip; -++ -++ if (!gc) -++ return; -++ -++ gpiochip_remove(&gc->gchip); -++ kfree(gc); -++ sc->gpiochip = NULL; -++} -++ -++#else /* CONFIG_GPIOLIB */ -++ -++static inline void ath9k_register_gpio_chip(struct ath_softc *sc) -++{ -++} -++ -++static inline void ath9k_unregister_gpio_chip(struct ath_softc *sc) -++{ -++} -++ -++#endif /* CONFIG_GPIOLIB */ -+ -+ /********************************/ -+ /* LED functions */ -+ /********************************/ -+ -+-#ifdef CPTCFG_MAC80211_LEDS -+- -+ static void ath_fill_led_pin(struct ath_softc *sc) -+ { -+ struct ath_hw *ah = sc->sc_ah; -+@@ -80,6 +206,12 @@ static int ath_add_led(struct ath_softc -+ else -+ ath9k_hw_set_gpio(sc->sc_ah, gpio->gpio, gpio->active_low); -+ -++#ifdef CONFIG_GPIOLIB -++ /* If there is GPIO chip configured, reserve LED pin */ -++ if (sc->gpiochip) -++ gpio_request(sc->gpiochip->gchip.base + gpio->gpio, gpio->name); -++#endif -++ -+ return 0; -+ } -+ -+@@ -136,17 +268,24 @@ void ath_deinit_leds(struct ath_softc *s -+ -+ while (!list_empty(&sc->leds)) { -+ led = list_first_entry(&sc->leds, struct ath_led, list); -++#ifdef CONFIG_GPIOLIB -++ /* If there is GPIO chip configured, free LED pin */ -++ if (sc->gpiochip) -++ gpio_free(sc->gpiochip->gchip.base + led->gpio->gpio); -++#endif -+ list_del(&led->list); -+ ath_led_brightness(&led->cdev, LED_OFF); -+ led_classdev_unregister(&led->cdev); -+ ath9k_hw_gpio_free(sc->sc_ah, led->gpio->gpio); -+ kfree(led); -+ } -++ ath9k_unregister_gpio_chip(sc); -+ } -+ -+ void ath_init_leds(struct ath_softc *sc) -+ { -+ struct ath9k_platform_data *pdata = sc->dev->platform_data; -++ struct device_node *np = sc->dev->of_node; -+ char led_name[32]; -+ const char *trigger; -+ int i; -+@@ -156,6 +295,15 @@ void ath_init_leds(struct ath_softc *sc) -+ if (AR_SREV_9100(sc->sc_ah)) -+ return; -+ -++ if (!np) -++ ath9k_register_gpio_chip(sc); -++ -++ /* setup gpio controller only if requested and skip the led_pin setup */ -++ if (of_property_read_bool(np, "gpio-controller")) { -++ ath9k_register_gpio_chip(sc); -++ return; -++ } -++ -+ ath_fill_led_pin(sc); -+ -+ if (pdata && pdata->leds && pdata->num_leds) -+@@ -180,6 +328,7 @@ void ath_init_leds(struct ath_softc *sc) -+ ath_create_gpio_led(sc, sc->sc_ah->led_pin, led_name, trigger, -+ !sc->sc_ah->config.led_active_high); -+ } -++ -+ #endif -+ -+ /*******************/ -diff --git a/package/kernel/mac80211/patches/ath9k/549-ath9k_enable_gpio_buttons.patch b/package/kernel/mac80211/patches/ath9k/549-ath9k_enable_gpio_buttons.patch -new file mode 100644 -index 0000000000..716e09f351 ---- /dev/null -+++ b/package/kernel/mac80211/patches/ath9k/549-ath9k_enable_gpio_buttons.patch -@@ -0,0 +1,143 @@ -+From: Michal Cieslakiewicz -+Subject: [PATCH v5 5/8] mac80211: ath9k: enable GPIO buttons -+ -+Enable platform-defined GPIO button support for ath9k device. -+Key poller is activated for attached platform buttons. -+Requires ath9k GPIO chip access. -+ -+Signed-off-by: Michal Cieslakiewicz -+Signed-off-by: Felix Fietkau -+--- -+--- a/drivers/net/wireless/ath/ath9k/ath9k.h -++++ b/drivers/net/wireless/ath/ath9k/ath9k.h -+@@ -1055,6 +1055,7 @@ struct ath_softc { -+ struct list_head leds; -+ #ifdef CONFIG_GPIOLIB -+ struct ath9k_gpio_chip *gpiochip; -++ struct platform_device *btnpdev; /* gpio-keys-polled */ -+ #endif -+ #endif -+ -+--- a/drivers/net/wireless/ath/ath9k/gpio.c -++++ b/drivers/net/wireless/ath/ath9k/gpio.c -+@@ -17,6 +17,8 @@ -+ #include "ath9k.h" -+ #include -+ #include -++#include -++#include -+ -+ #ifdef CPTCFG_MAC80211_LEDS -+ -+@@ -133,6 +135,67 @@ static void ath9k_unregister_gpio_chip(s -+ sc->gpiochip = NULL; -+ } -+ -++/******************/ -++/* GPIO Buttons */ -++/******************/ -++ -++/* add GPIO buttons */ -++static void ath9k_init_buttons(struct ath_softc *sc) -++{ -++ struct ath9k_platform_data *pdata = sc->dev->platform_data; -++ struct platform_device *pdev; -++ struct gpio_keys_platform_data gkpdata; -++ struct gpio_keys_button *bt; -++ int i; -++ -++ if (!sc->gpiochip) -++ return; -++ -++ if (!pdata || !pdata->btns || !pdata->num_btns) -++ return; -++ -++ bt = devm_kmemdup(sc->dev, pdata->btns, -++ pdata->num_btns * sizeof(struct gpio_keys_button), -++ GFP_KERNEL); -++ if (!bt) -++ return; -++ -++ for (i = 0; i < pdata->num_btns; i++) { -++ if (pdata->btns[i].gpio == sc->sc_ah->led_pin) -++ sc->sc_ah->led_pin = -1; -++ -++ ath9k_hw_gpio_request_in(sc->sc_ah, pdata->btns[i].gpio, -++ "ath9k-gpio"); -++ bt[i].gpio = sc->gpiochip->gchip.base + pdata->btns[i].gpio; -++ } -++ -++ memset(&gkpdata, 0, sizeof(struct gpio_keys_platform_data)); -++ gkpdata.buttons = bt; -++ gkpdata.nbuttons = pdata->num_btns; -++ gkpdata.poll_interval = pdata->btn_poll_interval; -++ -++ pdev = platform_device_register_data(sc->dev, "gpio-keys-polled", -++ PLATFORM_DEVID_AUTO, &gkpdata, -++ sizeof(gkpdata)); -++ if (!IS_ERR_OR_NULL(pdev)) -++ sc->btnpdev = pdev; -++ else { -++ sc->btnpdev = NULL; -++ devm_kfree(sc->dev, bt); -++ } -++} -++ -++/* remove GPIO buttons */ -++static void ath9k_deinit_buttons(struct ath_softc *sc) -++{ -++ if (!sc->gpiochip || !sc->btnpdev) -++ return; -++ -++ platform_device_unregister(sc->btnpdev); -++ -++ sc->btnpdev = NULL; -++} -++ -+ #else /* CONFIG_GPIOLIB */ -+ -+ static inline void ath9k_register_gpio_chip(struct ath_softc *sc) -+@@ -143,6 +206,14 @@ static inline void ath9k_unregister_gpio -+ { -+ } -+ -++static inline void ath9k_init_buttons(struct ath_softc *sc) -++{ -++} -++ -++static inline void ath9k_deinit_buttons(struct ath_softc *sc) -++{ -++} -++ -+ #endif /* CONFIG_GPIOLIB */ -+ -+ /********************************/ -+@@ -266,6 +337,7 @@ void ath_deinit_leds(struct ath_softc *s -+ { -+ struct ath_led *led; -+ -++ ath9k_deinit_buttons(sc); -+ while (!list_empty(&sc->leds)) { -+ led = list_first_entry(&sc->leds, struct ath_led, list); -+ #ifdef CONFIG_GPIOLIB -+@@ -305,6 +377,7 @@ void ath_init_leds(struct ath_softc *sc) -+ } -+ -+ ath_fill_led_pin(sc); -++ ath9k_init_buttons(sc); -+ -+ if (pdata && pdata->leds && pdata->num_leds) -+ for (i = 0; i < pdata->num_leds; i++) { -+--- a/include/linux/ath9k_platform.h -++++ b/include/linux/ath9k_platform.h -+@@ -49,6 +49,10 @@ struct ath9k_platform_data { -+ -+ int num_leds; -+ const struct gpio_led *leds; -++ -++ unsigned num_btns; -++ const struct gpio_keys_button *btns; -++ unsigned btn_poll_interval; -+ }; -+ -+ #endif /* _LINUX_ATH9K_PLATFORM_H */ -diff --git a/package/kernel/mac80211/patches/ath9k/551-ath9k_ubnt_uap_plus_hsr.patch b/package/kernel/mac80211/patches/ath9k/551-ath9k_ubnt_uap_plus_hsr.patch -new file mode 100644 -index 0000000000..efc4b9187c ---- /dev/null -+++ b/package/kernel/mac80211/patches/ath9k/551-ath9k_ubnt_uap_plus_hsr.patch -@@ -0,0 +1,403 @@ -+--- a/drivers/net/wireless/ath/ath9k/channel.c -++++ b/drivers/net/wireless/ath/ath9k/channel.c -+@@ -15,6 +15,7 @@ -+ */ -+ -+ #include "ath9k.h" -++#include "hsr.h" -+ -+ /* Set/change channels. If the channel is really being changed, it's done -+ * by reseting the chip. To accomplish this we must first cleanup any pending -+@@ -22,6 +23,7 @@ -+ */ -+ static int ath_set_channel(struct ath_softc *sc) -+ { -++ struct device_node *np = sc->dev->of_node; -+ struct ath_hw *ah = sc->sc_ah; -+ struct ath_common *common = ath9k_hw_common(ah); -+ struct ieee80211_hw *hw = sc->hw; -+@@ -42,6 +44,11 @@ static int ath_set_channel(struct ath_so -+ ath_dbg(common, CONFIG, "Set channel: %d MHz width: %d\n", -+ chan->center_freq, chandef->width); -+ -++ if (of_property_read_bool(np, "ubnt,hsr")) { -++ ath9k_hsr_enable(ah, chandef->width, chan->center_freq); -++ ath9k_hsr_status(ah); -++ } -++ -+ /* update survey stats for the old channel before switching */ -+ spin_lock_irqsave(&common->cc_lock, flags); -+ ath_update_survey_stats(sc); -+--- /dev/null -++++ b/drivers/net/wireless/ath/ath9k/hsr.c -+@@ -0,0 +1,247 @@ -++/* -++ * -++ * The MIT License (MIT) -++ * -++ * Copyright (c) 2015 Kirill Berezin -++ * -++ * Permission is hereby granted, free of charge, to any person obtaining a copy -++ * of this software and associated documentation files (the "Software"), to deal -++ * in the Software without restriction, including without limitation the rights -++ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -++ * copies of the Software, and to permit persons to whom the Software is -++ * furnished to do so, subject to the following conditions: -++ * -++ * The above copyright notice and this permission notice shall be included in -++ * all copies or substantial portions of the Software. -++ * -++ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -++ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -++ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -++ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -++ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -++ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -++ * SOFTWARE. -++ * -++ */ -++ -++#include -++#include -++#include -++#include -++#include -++#include -++#include -++#include -++ -++#include "hw.h" -++#include "ath9k.h" -++ -++#define HSR_GPIO_CSN 8 -++#define HSR_GPIO_CLK 6 -++#define HSR_GPIO_DOUT 7 -++#define HSR_GPIO_DIN 5 -++ -++/* delays are in useconds */ -++#define HSR_DELAY_HALF_TICK 100 -++#define HSR_DELAY_PRE_WRITE 75 -++#define HSR_DELAY_FINAL 20000 -++#define HSR_DELAY_TRAILING 200 -++ -++void ath9k_hsr_init(struct ath_hw *ah) -++{ -++ ath9k_hw_gpio_request_in(ah, HSR_GPIO_DIN, NULL); -++ ath9k_hw_gpio_request_out(ah, HSR_GPIO_CSN, NULL, -++ AR_GPIO_OUTPUT_MUX_AS_OUTPUT); -++ ath9k_hw_gpio_request_out(ah, HSR_GPIO_CLK, NULL, -++ AR_GPIO_OUTPUT_MUX_AS_OUTPUT); -++ ath9k_hw_gpio_request_out(ah, HSR_GPIO_DOUT, NULL, -++ AR_GPIO_OUTPUT_MUX_AS_OUTPUT); -++ -++ ath9k_hw_set_gpio(ah, HSR_GPIO_CSN, 1); -++ ath9k_hw_set_gpio(ah, HSR_GPIO_CLK, 0); -++ ath9k_hw_set_gpio(ah, HSR_GPIO_DOUT, 0); -++ -++ udelay(HSR_DELAY_TRAILING); -++} -++ -++static u32 ath9k_hsr_write_byte(struct ath_hw *ah, int delay, u32 value) -++{ -++ struct ath_common *common = ath9k_hw_common(ah); -++ int i; -++ u32 rval = 0; -++ -++ udelay(delay); -++ -++ ath9k_hw_set_gpio(ah, HSR_GPIO_CLK, 0); -++ udelay(HSR_DELAY_HALF_TICK); -++ -++ ath9k_hw_set_gpio(ah, HSR_GPIO_CSN, 0); -++ udelay(HSR_DELAY_HALF_TICK); -++ -++ for (i = 0; i < 8; ++i) { -++ rval = rval << 1; -++ -++ /* pattern is left to right, that is 7-th bit runs first */ -++ ath9k_hw_set_gpio(ah, HSR_GPIO_DOUT, (value >> (7 - i)) & 0x1); -++ udelay(HSR_DELAY_HALF_TICK); -++ -++ ath9k_hw_set_gpio(ah, HSR_GPIO_CLK, 1); -++ udelay(HSR_DELAY_HALF_TICK); -++ -++ rval |= ath9k_hw_gpio_get(ah, HSR_GPIO_DIN); -++ -++ ath9k_hw_set_gpio(ah, HSR_GPIO_CLK, 0); -++ udelay(HSR_DELAY_HALF_TICK); -++ } -++ -++ ath9k_hw_set_gpio(ah, HSR_GPIO_CSN, 1); -++ udelay(HSR_DELAY_HALF_TICK); -++ -++ ath_dbg(common, CONFIG, "ath9k_hsr_write_byte: write byte %d return value is %d %c\n", -++ value, rval, rval > 32 ? rval : '-'); -++ -++ return rval & 0xff; -++} -++ -++static int ath9k_hsr_write_a_chain(struct ath_hw *ah, char *chain, int items) -++{ -++ int status = 0; -++ int i = 0; -++ int err; -++ -++ /* a preamble */ -++ ath9k_hsr_write_byte(ah, HSR_DELAY_PRE_WRITE, 0); -++ status = ath9k_hsr_write_byte(ah, HSR_DELAY_PRE_WRITE, 0); -++ -++ /* clear HSR's reply buffer */ -++ if (status) { -++ int loop = 0; -++ -++ for (loop = 0; (loop < 42) && status; ++loop) -++ status = ath9k_hsr_write_byte(ah, HSR_DELAY_PRE_WRITE, -++ 0); -++ -++ if (loop >= 42) { -++ ATH_DBG_WARN(1, -++ "ath9k_hsr_write_a_chain: can't clear an output buffer after a 42 cycles.\n"); -++ return -1; -++ } -++ } -++ -++ for (i = 0; (i < items) && (chain[i] != 0); ++i) -++ ath9k_hsr_write_byte(ah, HSR_DELAY_PRE_WRITE, (u32)chain[i]); -++ -++ ath9k_hsr_write_byte(ah, HSR_DELAY_PRE_WRITE, 0); -++ mdelay(HSR_DELAY_FINAL / 1000); -++ -++ /* reply */ -++ memset(chain, 0, items); -++ -++ ath9k_hsr_write_byte(ah, HSR_DELAY_PRE_WRITE, 0); -++ udelay(HSR_DELAY_TRAILING); -++ -++ for (i = 0; i < (items - 1); ++i) { -++ u32 ret; -++ -++ ret = ath9k_hsr_write_byte(ah, HSR_DELAY_PRE_WRITE, 0); -++ if (ret != 0) -++ chain[i] = (char)ret; -++ else -++ break; -++ -++ udelay(HSR_DELAY_TRAILING); -++ } -++ -++ if (i <= 1) -++ return 0; -++ -++ err = kstrtoint(chain + 1, 10, &i); -++ if (err) -++ return err; -++ -++ return i; -++} -++ -++int ath9k_hsr_disable(struct ath_hw *ah) -++{ -++ char cmd[10] = {'b', '4', '0', 0, 0, 0, 0, 0, 0, 0}; -++ int ret; -++ -++ ret = ath9k_hsr_write_a_chain(ah, cmd, sizeof(cmd)); -++ if ((ret > 0) && (*cmd == 'B')) -++ return 0; -++ -++ return -1; -++} -++ -++int ath9k_hsr_enable(struct ath_hw *ah, int bw, int fq) -++{ -++ char cmd[10]; -++ int ret; -++ -++ /* Bandwidth argument is 0 sometimes. Assume default 802.11bgn -++ * 20MHz on invalid values -++ */ -++ if ((bw != 5) && (bw != 10) && (bw != 20) && (bw != 40)) -++ bw = 20; -++ -++ memset(cmd, 0, sizeof(cmd)); -++ *cmd = 'b'; -++ snprintf(cmd + 1, 3, "%02d", bw); -++ -++ ret = ath9k_hsr_write_a_chain(ah, cmd, sizeof(cmd)); -++ if ((*cmd != 'B') || (ret != bw)) { -++ ATH_DBG_WARN(1, -++ "ath9k_hsr_enable: failed changing bandwidth -> set (%d,%d) reply (%d, %d)\n", -++ 'b', bw, *cmd, ret); -++ return -1; -++ } -++ -++ memset(cmd, 0, sizeof(cmd)); -++ *cmd = 'x'; -++ ret = ath9k_hsr_write_a_chain(ah, cmd, sizeof(cmd)); -++ if (*cmd != 'X') { -++ ATH_DBG_WARN(1, -++ "ath9k_hsr_enable: failed 'x' command -> reply (%d, %d)\n", -++ *cmd, ret); -++ return -1; -++ } -++ -++ memset(cmd, 0, sizeof(cmd)); -++ *cmd = 'm'; -++ ret = ath9k_hsr_write_a_chain(ah, cmd, sizeof(cmd)); -++ if (*cmd != 'M') { -++ ATH_DBG_WARN(1, -++ "ath9k_hsr_enable: failed 'm' command -> reply (%d, %d)\n", -++ *cmd, ret); -++ return -1; -++ } -++ -++ memset(cmd, 0, sizeof(cmd)); -++ *cmd = 'f'; -++ snprintf(cmd + 1, 6, "%05d", fq); -++ ret = ath9k_hsr_write_a_chain(ah, cmd, sizeof(cmd)); -++ if ((*cmd != 'F') && (ret != fq)) { -++ ATH_DBG_WARN(1, -++ "ath9k_hsr_enable: failed set frequency -> reply (%d, %d)\n", -++ *cmd, ret); -++ return -1; -++ } -++ -++ return 0; -++} -++ -++int ath9k_hsr_status(struct ath_hw *ah) -++{ -++ char cmd[10] = {'s', 0, 0, 0, 0, 0, 0, 0, 0, 0}; -++ int ret; -++ -++ ret = ath9k_hsr_write_a_chain(ah, cmd, sizeof(cmd)); -++ if (*cmd != 'S') { -++ ATH_DBG_WARN(1, "ath9k_hsr_status: returned %d,%d\n", *cmd, -++ ret); -++ return -1; -++ } -++ -++ return 0; -++} -+--- /dev/null -++++ b/drivers/net/wireless/ath/ath9k/hsr.h -+@@ -0,0 +1,48 @@ -++/* -++ * The MIT License (MIT) -++ * -++ * Copyright (c) 2015 Kirill Berezin -++ * -++ * Permission is hereby granted, free of charge, to any person obtaining a copy -++ * of this software and associated documentation files (the "Software"), to deal -++ * in the Software without restriction, including without limitation the rights -++ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -++ * copies of the Software, and to permit persons to whom the Software is -++ * furnished to do so, subject to the following conditions: -++ * -++ * The above copyright notice and this permission notice shall be included in -++ * all copies or substantial portions of the Software. -++ * -++ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -++ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -++ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -++ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -++ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -++ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -++ * SOFTWARE. -++ */ -++ -++#ifndef HSR_H -++#define HSR_H -++ -++#ifdef CPTCFG_ATH9K_UBNTHSR -++ -++void ath9k_hsr_init(struct ath_hw *ah); -++int ath9k_hsr_disable(struct ath_hw *ah); -++int ath9k_hsr_enable(struct ath_hw *ah, int bw, int fq); -++int ath9k_hsr_status(struct ath_hw *ah); -++ -++#else -++static inline void ath9k_hsr_init(struct ath_hw *ah) {} -++ -++static inline int ath9k_hsr_enable(struct ath_hw *ah, int bw, int fq) -++{ -++ return 0; -++} -++ -++static inline int ath9k_hsr_disable(struct ath_hw *ah) { return 0; } -++static inline int ath9k_hsr_status(struct ath_hw *ah) { return 0; } -++ -++#endif -++ -++#endif /* HSR_H */ -+--- a/drivers/net/wireless/ath/ath9k/main.c -++++ b/drivers/net/wireless/ath/ath9k/main.c -+@@ -18,6 +18,7 @@ -+ #include -+ #include "ath9k.h" -+ #include "btcoex.h" -++#include "hsr.h" -+ -+ static void ath9k_flush(struct ieee80211_hw *hw, struct ieee80211_vif *vif, -+ u32 queues, bool drop); -+@@ -659,6 +660,7 @@ void ath_reset_work(struct work_struct * -+ static int ath9k_start(struct ieee80211_hw *hw) -+ { -+ struct ath_softc *sc = hw->priv; -++ struct device_node *np = sc->dev->of_node; -+ struct ath_hw *ah = sc->sc_ah; -+ struct ath_common *common = ath9k_hw_common(ah); -+ struct ieee80211_channel *curchan = sc->cur_chan->chandef.chan; -+@@ -737,6 +739,11 @@ static int ath9k_start(struct ieee80211_ -+ AR_GPIO_OUTPUT_MUX_AS_OUTPUT); -+ } -+ -++ if (of_property_read_bool(np, "ubnt,hsr")) { -++ ath9k_hsr_init(ah); -++ ath9k_hsr_disable(ah); -++ } -++ -+ /* -+ * Reset key cache to sane defaults (all entries cleared) instead of -+ * semi-random values after suspend/resume. -+--- a/drivers/net/wireless/ath/ath9k/Makefile -++++ b/drivers/net/wireless/ath/ath9k/Makefile -+@@ -17,6 +17,7 @@ ath9k-$(CPTCFG_ATH9K_DFS_CERTIFIED) += d -+ ath9k-$(CPTCFG_ATH9K_TX99) += tx99.o -+ ath9k-$(CPTCFG_ATH9K_WOW) += wow.o -+ ath9k-$(CPTCFG_ATH9K_HWRNG) += rng.o -++ath9k-$(CPTCFG_ATH9K_UBNTHSR) += hsr.o -+ -+ ath9k-$(CPTCFG_ATH9K_DEBUGFS) += debug.o -+ -+--- a/local-symbols -++++ b/local-symbols -+@@ -129,6 +129,7 @@ ATH9K_WOW= -+ ATH9K_RFKILL= -+ ATH9K_CHANNEL_CONTEXT= -+ ATH9K_PCOEM= -++ATH9K_UBNTHSR= -+ ATH9K_PCI_NO_EEPROM= -+ ATH9K_HTC= -+ ATH9K_HTC_DEBUGFS= -+--- a/drivers/net/wireless/ath/ath9k/Kconfig -++++ b/drivers/net/wireless/ath/ath9k/Kconfig -+@@ -58,6 +58,19 @@ config ATH9K_AHB -+ Say Y, if you have a SoC with a compatible built-in -+ wireless MAC. Say N if unsure. -+ -++config ATH9K_UBNTHSR -++ bool "Ubiquiti UniFi Outdoor Plus HSR support" -++ depends on ATH9K -++ ---help--- -++ This options enables code to control the HSR RF -++ filter in the receive path of the Ubiquiti UniFi -++ Outdoor Plus access point. -++ -++ Say Y if you want to use the access point. The -++ code will only be used if the device is detected, -++ so it does not harm other setup other than occupying -++ a bit of memory. -++ -+ config ATH9K_DEBUGFS -+ bool "Atheros ath9k debugging" -+ depends on ATH9K && DEBUG_FS -diff --git a/package/kernel/mac80211/patches/ath9k/552-ath9k-ahb_of.patch b/package/kernel/mac80211/patches/ath9k/552-ath9k-ahb_of.patch -new file mode 100644 -index 0000000000..57eef54e89 ---- /dev/null -+++ b/package/kernel/mac80211/patches/ath9k/552-ath9k-ahb_of.patch -@@ -0,0 +1,331 @@ -+--- a/drivers/net/wireless/ath/ath9k/ahb.c -++++ b/drivers/net/wireless/ath/ath9k/ahb.c -+@@ -20,7 +20,15 @@ -+ #include -+ #include -+ #include -++#include -+ #include "ath9k.h" -++#include -++ -++#ifdef CONFIG_OF -++#include -++#include -++#include -++#endif -+ -+ static const struct platform_device_id ath9k_platform_id_table[] = { -+ { -+@@ -69,6 +77,236 @@ static const struct ath_bus_ops ath_ahb_ -+ .eeprom_read = ath_ahb_eeprom_read, -+ }; -+ -++#ifdef CONFIG_OF -++ -++#define QCA955X_DDR_CTL_CONFIG 0x108 -++#define QCA955X_DDR_CTL_CONFIG_ACT_WMAC BIT(23) -++ -++static int of_get_wifi_cal(struct device_node *np, struct ath9k_platform_data *pdata) -++{ -++#ifdef CONFIG_MTD -++ struct device_node *mtd_np = NULL; -++ size_t retlen; -++ int size, ret; -++ struct mtd_info *mtd; -++ const char *part; -++ const __be32 *list; -++ phandle phandle; -++ -++ list = of_get_property(np, "mtd-cal-data", &size); -++ if (!list) -++ return 0; -++ -++ if (size != (2 * sizeof(*list))) -++ return 1; -++ -++ phandle = be32_to_cpup(list++); -++ if (phandle) -++ mtd_np = of_find_node_by_phandle(phandle); -++ -++ if (!mtd_np) -++ return 1; -++ -++ part = of_get_property(mtd_np, "label", NULL); -++ if (!part) -++ part = mtd_np->name; -++ -++ mtd = get_mtd_device_nm(part); -++ if (IS_ERR(mtd)) -++ return 1; -++ -++ ret = mtd_read(mtd, be32_to_cpup(list), sizeof(pdata->eeprom_data), -++ &retlen, (u8*)pdata->eeprom_data); -++ put_mtd_device(mtd); -++ -++#endif -++ return 0; -++} -++ -++static int ar913x_wmac_reset(void) -++{ -++ ath79_device_reset_set(AR913X_RESET_AMBA2WMAC); -++ mdelay(10); -++ -++ ath79_device_reset_clear(AR913X_RESET_AMBA2WMAC); -++ mdelay(10); -++ -++ return 0; -++} -++ -++static int ar933x_wmac_reset(void) -++{ -++ int retries = 20; -++ -++ ath79_device_reset_set(AR933X_RESET_WMAC); -++ ath79_device_reset_clear(AR933X_RESET_WMAC); -++ -++ while (1) { -++ u32 bootstrap; -++ -++ bootstrap = ath79_reset_rr(AR933X_RESET_REG_BOOTSTRAP); -++ if ((bootstrap & AR933X_BOOTSTRAP_EEPBUSY) == 0) -++ return 0; -++ -++ if (retries-- == 0) -++ break; -++ -++ udelay(10000); -++ } -++ -++ pr_err("ar933x: WMAC reset timed out"); -++ return -ETIMEDOUT; -++} -++ -++static int qca955x_wmac_reset(void) -++{ -++ int i; -++ -++ /* Try to wait for WMAC DDR activity to stop */ -++ for (i = 0; i < 10; i++) { -++ if (!(__raw_readl(ath79_ddr_base + QCA955X_DDR_CTL_CONFIG) & -++ QCA955X_DDR_CTL_CONFIG_ACT_WMAC)) -++ break; -++ -++ udelay(10); -++ } -++ -++ ath79_device_reset_set(QCA955X_RESET_RTC); -++ udelay(10); -++ ath79_device_reset_clear(QCA955X_RESET_RTC); -++ udelay(10); -++ -++ return 0; -++} -++ -++enum { -++ AR913X_WMAC = 0, -++ AR933X_WMAC, -++ AR934X_WMAC, -++ QCA953X_WMAC, -++ QCA955X_WMAC, -++ QCA956X_WMAC, -++}; -++ -++static int ar9330_get_soc_revision(void) -++{ -++ if (ath79_soc_rev == 1) -++ return ath79_soc_rev; -++ -++ return 0; -++} -++ -++static int ath79_get_soc_revision(void) -++{ -++ return ath79_soc_rev; -++} -++ -++static const struct of_ath_ahb_data { -++ u16 dev_id; -++ u32 bootstrap_reg; -++ u32 bootstrap_ref; -++ -++ int (*soc_revision)(void); -++ int (*wmac_reset)(void); -++} of_ath_ahb_data[] = { -++ [AR913X_WMAC] = { -++ .dev_id = AR5416_AR9100_DEVID, -++ .wmac_reset = ar913x_wmac_reset, -++ -++ }, -++ [AR933X_WMAC] = { -++ .dev_id = AR9300_DEVID_AR9330, -++ .bootstrap_reg = AR933X_RESET_REG_BOOTSTRAP, -++ .bootstrap_ref = AR933X_BOOTSTRAP_REF_CLK_40, -++ .soc_revision = ar9330_get_soc_revision, -++ .wmac_reset = ar933x_wmac_reset, -++ }, -++ [AR934X_WMAC] = { -++ .dev_id = AR9300_DEVID_AR9340, -++ .bootstrap_reg = AR934X_RESET_REG_BOOTSTRAP, -++ .bootstrap_ref = AR934X_BOOTSTRAP_REF_CLK_40, -++ .soc_revision = ath79_get_soc_revision, -++ }, -++ [QCA953X_WMAC] = { -++ .dev_id = AR9300_DEVID_AR953X, -++ .bootstrap_reg = QCA953X_RESET_REG_BOOTSTRAP, -++ .bootstrap_ref = QCA953X_BOOTSTRAP_REF_CLK_40, -++ .soc_revision = ath79_get_soc_revision, -++ }, -++ [QCA955X_WMAC] = { -++ .dev_id = AR9300_DEVID_QCA955X, -++ .bootstrap_reg = QCA955X_RESET_REG_BOOTSTRAP, -++ .bootstrap_ref = QCA955X_BOOTSTRAP_REF_CLK_40, -++ .wmac_reset = qca955x_wmac_reset, -++ }, -++ [QCA956X_WMAC] = { -++ .dev_id = AR9300_DEVID_QCA956X, -++ .bootstrap_reg = QCA956X_RESET_REG_BOOTSTRAP, -++ .bootstrap_ref = QCA956X_BOOTSTRAP_REF_CLK_40, -++ .soc_revision = ath79_get_soc_revision, -++ }, -++}; -++ -++const struct of_device_id of_ath_ahb_match[] = { -++ { .compatible = "qca,ar9130-wmac", .data = &of_ath_ahb_data[AR913X_WMAC] }, -++ { .compatible = "qca,ar9330-wmac", .data = &of_ath_ahb_data[AR933X_WMAC] }, -++ { .compatible = "qca,ar9340-wmac", .data = &of_ath_ahb_data[AR934X_WMAC] }, -++ { .compatible = "qca,qca9530-wmac", .data = &of_ath_ahb_data[QCA953X_WMAC] }, -++ { .compatible = "qca,qca9550-wmac", .data = &of_ath_ahb_data[QCA955X_WMAC] }, -++ { .compatible = "qca,qca9560-wmac", .data = &of_ath_ahb_data[QCA956X_WMAC] }, -++ {}, -++}; -++MODULE_DEVICE_TABLE(of, of_ath_ahb_match); -++ -++static int of_ath_ahb_probe(struct platform_device *pdev) -++{ -++ struct ath9k_platform_data *pdata; -++ const struct of_device_id *match; -++ const struct of_ath_ahb_data *data; -++ u8 led_pin; -++ -++ match = of_match_device(of_ath_ahb_match, &pdev->dev); -++ data = (const struct of_ath_ahb_data *)match->data; -++ -++ pdata = dev_get_platdata(&pdev->dev); -++ -++ if (!of_property_read_u8(pdev->dev.of_node, "qca,led-pin", &led_pin)) -++ pdata->led_pin = led_pin; -++ else -++ pdata->led_pin = -1; -++ -++ if (of_property_read_bool(pdev->dev.of_node, "qca,tx-gain-buffalo")) -++ pdata->tx_gain_buffalo = true; -++ -++ if (data->wmac_reset) { -++ data->wmac_reset(); -++ pdata->external_reset = data->wmac_reset; -++ } -++ -++ if (data->dev_id == AR9300_DEVID_AR953X) { -++ /* -++ * QCA953x only supports 25MHz refclk. -++ * Some vendors have an invalid bootstrap option -++ * set, which would break the WMAC here. -++ */ -++ pdata->is_clk_25mhz = true; -++ } else if (data->bootstrap_reg && data->bootstrap_ref) { -++ u32 t = ath79_reset_rr(data->bootstrap_reg); -++ if (t & data->bootstrap_ref) -++ pdata->is_clk_25mhz = false; -++ else -++ pdata->is_clk_25mhz = true; -++ } -++ -++ pdata->get_mac_revision = data->soc_revision; -++ -++ if (of_get_wifi_cal(pdev->dev.of_node, pdata)) -++ dev_err(&pdev->dev, "failed to load calibration data from mtd device\n"); -++ -++ return data->dev_id; -++} -++#endif -++ -+ static int ath_ahb_probe(struct platform_device *pdev) -+ { -+ void __iomem *mem; -+@@ -80,6 +318,17 @@ static int ath_ahb_probe(struct platform -+ int ret = 0; -+ struct ath_hw *ah; -+ char hw_name[64]; -++ u16 dev_id; -++ -++ if (id) -++ dev_id = id->driver_data; -++ -++#ifdef CONFIG_OF -++ if (pdev->dev.of_node) -++ pdev->dev.platform_data = devm_kzalloc(&pdev->dev, -++ sizeof(struct ath9k_platform_data), -++ GFP_KERNEL); -++#endif -+ -+ if (!dev_get_platdata(&pdev->dev)) { -+ dev_err(&pdev->dev, "no platform data specified\n"); -+@@ -118,13 +367,16 @@ static int ath_ahb_probe(struct platform -+ sc->mem = mem; -+ sc->irq = irq; -+ -++#ifdef CONFIG_OF -++ dev_id = of_ath_ahb_probe(pdev); -++#endif -+ ret = request_irq(irq, ath_isr, IRQF_SHARED, "ath9k", sc); -+ if (ret) { -+ dev_err(&pdev->dev, "request_irq failed\n"); -+ goto err_free_hw; -+ } -+ -+- ret = ath9k_init_device(id->driver_data, sc, &ath_ahb_bus_ops); -++ ret = ath9k_init_device(dev_id, sc, &ath_ahb_bus_ops); -+ if (ret) { -+ dev_err(&pdev->dev, "failed to initialize device\n"); -+ goto err_irq; -+@@ -155,6 +407,9 @@ static int ath_ahb_remove(struct platfor -+ free_irq(sc->irq, sc); -+ ieee80211_free_hw(sc->hw); -+ } -++#ifdef CONFIG_OF -++ pdev->dev.platform_data = NULL; -++#endif -+ -+ return 0; -+ } -+@@ -164,6 +419,9 @@ static struct platform_driver ath_ahb_dr -+ .remove = ath_ahb_remove, -+ .driver = { -+ .name = "ath9k", -++#ifdef CONFIG_OF -++ .of_match_table = of_ath_ahb_match, -++#endif -+ }, -+ .id_table = ath9k_platform_id_table, -+ }; -+--- a/drivers/net/wireless/ath/ath9k/ath9k.h -++++ b/drivers/net/wireless/ath/ath9k/ath9k.h -+@@ -25,6 +25,7 @@ -+ #include -+ #include -+ #include -++#include -+ -+ #include "common.h" -+ #include "debug.h" -+@@ -1011,6 +1012,9 @@ struct ath_softc { -+ struct ath_hw *sc_ah; -+ void __iomem *mem; -+ int irq; -++#ifdef CONFIG_OF -++ struct reset_control *reset; -++#endif -+ spinlock_t sc_serial_rw; -+ spinlock_t sc_pm_lock; -+ spinlock_t sc_pcu_lock; -diff --git a/package/kernel/mac80211/patches/ath9k/553-ath9k_of_gpio_mask.patch b/package/kernel/mac80211/patches/ath9k/553-ath9k_of_gpio_mask.patch -new file mode 100644 -index 0000000000..6d1820ecb7 ---- /dev/null -+++ b/package/kernel/mac80211/patches/ath9k/553-ath9k_of_gpio_mask.patch -@@ -0,0 +1,25 @@ -+--- a/drivers/net/wireless/ath/ath9k/init.c -++++ b/drivers/net/wireless/ath/ath9k/init.c -+@@ -696,6 +696,12 @@ static int ath9k_of_init(struct ath_soft -+ return 0; -+ } -+ -++static void ath9k_of_gpio_mask(struct ath_softc *sc) -++{ -++ of_property_read_u32(sc->dev->of_node, "qca,gpio-mask", -++ &sc->sc_ah->caps.gpio_mask); -++} -++ -+ static int ath9k_init_softc(u16 devid, struct ath_softc *sc, -+ const struct ath_bus_ops *bus_ops) -+ { -+@@ -803,6 +809,9 @@ static int ath9k_init_softc(u16 devid, s -+ if (ret) -+ goto err_hw; -+ -++ /* GPIO mask quirk */ -++ ath9k_of_gpio_mask(sc); -++ -+ ret = ath9k_init_queues(sc); -+ if (ret) -+ goto err_queues; -diff --git a/package/kernel/mac80211/patches/brcm/040-brcmutil_option.patch b/package/kernel/mac80211/patches/brcm/040-brcmutil_option.patch -new file mode 100644 -index 0000000000..3e8505b5b4 ---- /dev/null -+++ b/package/kernel/mac80211/patches/brcm/040-brcmutil_option.patch -@@ -0,0 +1,10 @@ -+--- a/drivers/net/wireless/broadcom/brcm80211/Kconfig -++++ b/drivers/net/wireless/broadcom/brcm80211/Kconfig -+@@ -1,6 +1,6 @@ -+ # SPDX-License-Identifier: GPL-2.0-only -+ config BRCMUTIL -+- tristate -++ tristate "Broadcom 802.11 driver utility functions" -+ depends on m -+ -+ config BRCMSMAC -diff --git a/package/kernel/mac80211/patches/brcm/810-b43-gpio-mask-module-option.patch b/package/kernel/mac80211/patches/brcm/810-b43-gpio-mask-module-option.patch -new file mode 100644 -index 0000000000..09ef50526f ---- /dev/null -+++ b/package/kernel/mac80211/patches/brcm/810-b43-gpio-mask-module-option.patch -@@ -0,0 +1,37 @@ -+--- a/drivers/net/wireless/broadcom/b43/b43.h -++++ b/drivers/net/wireless/broadcom/b43/b43.h -+@@ -840,6 +840,7 @@ struct b43_wldev { -+ bool qos_enabled; /* TRUE, if QoS is used. */ -+ bool hwcrypto_enabled; /* TRUE, if HW crypto acceleration is enabled. */ -+ bool use_pio; /* TRUE if next init should use PIO */ -++ int gpiomask; /* GPIO LED mask as a module parameter */ -+ -+ /* PHY/Radio device. */ -+ struct b43_phy phy; -+--- a/drivers/net/wireless/broadcom/b43/main.c -++++ b/drivers/net/wireless/broadcom/b43/main.c -+@@ -72,6 +72,11 @@ MODULE_FIRMWARE("b43/ucode40.fw"); -+ MODULE_FIRMWARE("b43/ucode42.fw"); -+ MODULE_FIRMWARE("b43/ucode9.fw"); -+ -++static int modparam_gpiomask = 0x000F; -++module_param_named(gpiomask, modparam_gpiomask, int, 0444); -++MODULE_PARM_DESC(gpiomask, -++ "GPIO mask for LED control (default 0x000F)"); -++ -+ static int modparam_bad_frames_preempt; -+ module_param_named(bad_frames_preempt, modparam_bad_frames_preempt, int, 0444); -+ MODULE_PARM_DESC(bad_frames_preempt, -+@@ -2869,10 +2874,10 @@ static int b43_gpio_init(struct b43_wlde -+ u32 mask, set; -+ -+ b43_maskset32(dev, B43_MMIO_MACCTL, ~B43_MACCTL_GPOUTSMSK, 0); -+- b43_maskset16(dev, B43_MMIO_GPIO_MASK, ~0, 0xF); -++ b43_maskset16(dev, B43_MMIO_GPIO_MASK, ~0, modparam_gpiomask); -+ -+ mask = 0x0000001F; -+- set = 0x0000000F; -++ set = modparam_gpiomask; -+ if (dev->dev->chip_id == 0x4301) { -+ mask |= 0x0060; -+ set |= 0x0060; -diff --git a/package/kernel/mac80211/patches/brcm/811-b43_no_pio.patch b/package/kernel/mac80211/patches/brcm/811-b43_no_pio.patch -new file mode 100644 -index 0000000000..e395d48202 ---- /dev/null -+++ b/package/kernel/mac80211/patches/brcm/811-b43_no_pio.patch -@@ -0,0 +1,86 @@ -+--- a/drivers/net/wireless/broadcom/b43/Makefile -++++ b/drivers/net/wireless/broadcom/b43/Makefile -+@@ -18,7 +18,7 @@ b43-$(CPTCFG_B43_PHY_AC) += phy_ac.o -+ b43-y += sysfs.o -+ b43-y += xmit.o -+ b43-y += dma.o -+-b43-y += pio.o -++b43-$(CPTCFG_B43_PIO) += pio.o -+ b43-y += rfkill.o -+ b43-y += ppr.o -+ b43-$(CPTCFG_B43_LEDS) += leds.o -+--- a/drivers/net/wireless/broadcom/b43/main.c -++++ b/drivers/net/wireless/broadcom/b43/main.c -+@@ -2001,10 +2001,12 @@ static void b43_do_interrupt_thread(stru -+ dma_reason[0], dma_reason[1], -+ dma_reason[2], dma_reason[3], -+ dma_reason[4], dma_reason[5]); -++#ifdef CPTCFG_B43_PIO -+ b43err(dev->wl, "This device does not support DMA " -+ "on your system. It will now be switched to PIO.\n"); -+ /* Fall back to PIO transfers if we get fatal DMA errors! */ -+ dev->use_pio = true; -++#endif -+ b43_controller_restart(dev, "DMA error"); -+ return; -+ } -+--- a/drivers/net/wireless/broadcom/b43/pio.h -++++ b/drivers/net/wireless/broadcom/b43/pio.h -+@@ -151,7 +151,7 @@ static inline void b43_piorx_write32(str -+ b43_write32(q->dev, q->mmio_base + offset, value); -+ } -+ -+- -++#ifdef CPTCFG_B43_PIO -+ int b43_pio_init(struct b43_wldev *dev); -+ void b43_pio_free(struct b43_wldev *dev); -+ -+@@ -162,5 +162,37 @@ void b43_pio_rx(struct b43_pio_rxqueue * -+ -+ void b43_pio_tx_suspend(struct b43_wldev *dev); -+ void b43_pio_tx_resume(struct b43_wldev *dev); -++#else -++static inline int b43_pio_init(struct b43_wldev *dev) -++{ -++ return 0; -++} -++ -++static inline void b43_pio_free(struct b43_wldev *dev) -++{ -++} -++ -++static inline int b43_pio_tx(struct b43_wldev *dev, struct sk_buff *skb) -++{ -++ return 0; -++} -++ -++static inline void b43_pio_handle_txstatus(struct b43_wldev *dev, -++ const struct b43_txstatus *status) -++{ -++} -++ -++static inline void b43_pio_rx(struct b43_pio_rxqueue *q) -++{ -++} -++ -++static inline void b43_pio_tx_suspend(struct b43_wldev *dev) -++{ -++} -++ -++static inline void b43_pio_tx_resume(struct b43_wldev *dev) -++{ -++} -++#endif /* CPTCFG_B43_PIO */ -+ -+ #endif /* B43_PIO_H_ */ -+--- a/drivers/net/wireless/broadcom/b43/Kconfig -++++ b/drivers/net/wireless/broadcom/b43/Kconfig -+@@ -100,7 +100,7 @@ config B43_BCMA_PIO -+ default y -+ -+ config B43_PIO -+- bool -++ bool "Broadcom 43xx PIO support" -+ depends on B43 && B43_SSB -+ depends on SSB_BLOCKIO -+ default y -diff --git a/package/kernel/mac80211/patches/brcm/812-b43-add-antenna-control.patch b/package/kernel/mac80211/patches/brcm/812-b43-add-antenna-control.patch -new file mode 100644 -index 0000000000..22b67c49d8 ---- /dev/null -+++ b/package/kernel/mac80211/patches/brcm/812-b43-add-antenna-control.patch -@@ -0,0 +1,131 @@ -+--- a/drivers/net/wireless/broadcom/b43/main.c -++++ b/drivers/net/wireless/broadcom/b43/main.c -+@@ -1643,7 +1643,7 @@ static void b43_write_beacon_template(st -+ len, ram_offset, shm_size_offset, rate); -+ -+ /* Write the PHY TX control parameters. */ -+- antenna = B43_ANTENNA_DEFAULT; -++ antenna = dev->tx_antenna; -+ antenna = b43_antenna_to_phyctl(antenna); -+ ctl = b43_shm_read16(dev, B43_SHM_SHARED, B43_SHM_SH_BEACPHYCTL); -+ /* We can't send beacons with short preamble. Would get PHY errors. */ -+@@ -3284,8 +3284,8 @@ static int b43_chip_init(struct b43_wlde -+ -+ /* Select the antennae */ -+ if (phy->ops->set_rx_antenna) -+- phy->ops->set_rx_antenna(dev, B43_ANTENNA_DEFAULT); -+- b43_mgmtframe_txantenna(dev, B43_ANTENNA_DEFAULT); -++ phy->ops->set_rx_antenna(dev, dev->rx_antenna); -++ b43_mgmtframe_txantenna(dev, dev->tx_antenna); -+ -+ if (phy->type == B43_PHYTYPE_B) { -+ value16 = b43_read16(dev, 0x005E); -+@@ -3986,7 +3986,6 @@ static int b43_op_config(struct ieee8021 -+ struct b43_wldev *dev = wl->current_dev; -+ struct b43_phy *phy = &dev->phy; -+ struct ieee80211_conf *conf = &hw->conf; -+- int antenna; -+ int err = 0; -+ -+ mutex_lock(&wl->mutex); -+@@ -4029,11 +4028,9 @@ static int b43_op_config(struct ieee8021 -+ } -+ -+ /* Antennas for RX and management frame TX. */ -+- antenna = B43_ANTENNA_DEFAULT; -+- b43_mgmtframe_txantenna(dev, antenna); -+- antenna = B43_ANTENNA_DEFAULT; -++ b43_mgmtframe_txantenna(dev, dev->tx_antenna); -+ if (phy->ops->set_rx_antenna) -+- phy->ops->set_rx_antenna(dev, antenna); -++ phy->ops->set_rx_antenna(dev, dev->rx_antenna); -+ -+ if (wl->radio_enabled != phy->radio_on) { -+ if (wl->radio_enabled) { -+@@ -5176,6 +5173,47 @@ static int b43_op_get_survey(struct ieee -+ return 0; -+ } -+ -++static int b43_op_set_antenna(struct ieee80211_hw *hw, u32 tx_ant, u32 rx_ant) -++{ -++ struct b43_wl *wl = hw_to_b43_wl(hw); -++ struct b43_wldev *dev = wl->current_dev; -++ -++ if (tx_ant == 1 && rx_ant == 1) { -++ dev->tx_antenna = B43_ANTENNA0; -++ dev->rx_antenna = B43_ANTENNA0; -++ } -++ else if (tx_ant == 2 && rx_ant == 2) { -++ dev->tx_antenna = B43_ANTENNA1; -++ dev->rx_antenna = B43_ANTENNA1; -++ } -++ else if ((tx_ant & 3) == 3 && (rx_ant & 3) == 3) { -++ dev->tx_antenna = B43_ANTENNA_DEFAULT; -++ dev->rx_antenna = B43_ANTENNA_DEFAULT; -++ } -++ else { -++ return -EINVAL; -++ } -++ -++ return 0; -++} -++ -++ -++static int b43_op_get_antenna(struct ieee80211_hw *hw, u32 *tx_ant, u32 *rx_ant) -++{ -++ struct b43_wl *wl = hw_to_b43_wl(hw); -++ struct b43_wldev *dev = wl->current_dev; -++ -++ switch (dev->tx_antenna) { -++ case B43_ANTENNA0: -++ *tx_ant = 1; *rx_ant = 1; break; -++ case B43_ANTENNA1: -++ *tx_ant = 2; *rx_ant = 2; break; -++ case B43_ANTENNA_DEFAULT: -++ *tx_ant = 3; *rx_ant = 3; break; -++ } -++ return 0; -++} -++ -+ static const struct ieee80211_ops b43_hw_ops = { -+ .tx = b43_op_tx, -+ .wake_tx_queue = ieee80211_handle_wake_tx_queue, -+@@ -5198,6 +5236,8 @@ static const struct ieee80211_ops b43_hw -+ .sw_scan_complete = b43_op_sw_scan_complete_notifier, -+ .get_survey = b43_op_get_survey, -+ .rfkill_poll = b43_rfkill_poll, -++ .set_antenna = b43_op_set_antenna, -++ .get_antenna = b43_op_get_antenna, -+ }; -+ -+ /* Hard-reset the chip. Do not call this directly. -+@@ -5499,6 +5539,8 @@ static int b43_one_core_attach(struct b4 -+ if (!wldev) -+ goto out; -+ -++ wldev->rx_antenna = B43_ANTENNA_DEFAULT; -++ wldev->tx_antenna = B43_ANTENNA_DEFAULT; -+ wldev->use_pio = b43_modparam_pio; -+ wldev->dev = dev; -+ wldev->wl = wl; -+@@ -5590,6 +5632,9 @@ static struct b43_wl *b43_wireless_init( -+ -+ wiphy_ext_feature_set(hw->wiphy, NL80211_EXT_FEATURE_CQM_RSSI_LIST); -+ -++ hw->wiphy->available_antennas_rx = 0x3; -++ hw->wiphy->available_antennas_tx = 0x3; -++ -+ wl->hw_registered = false; -+ hw->max_rates = 2; -+ SET_IEEE80211_DEV(hw, dev->dev); -+--- a/drivers/net/wireless/broadcom/b43/b43.h -++++ b/drivers/net/wireless/broadcom/b43/b43.h -+@@ -841,6 +841,8 @@ struct b43_wldev { -+ bool hwcrypto_enabled; /* TRUE, if HW crypto acceleration is enabled. */ -+ bool use_pio; /* TRUE if next init should use PIO */ -+ int gpiomask; /* GPIO LED mask as a module parameter */ -++ int rx_antenna; /* Used RX antenna (B43_ANTENNAxxx) */ -++ int tx_antenna; /* Used TX antenna (B43_ANTENNAxxx) */ -+ -+ /* PHY/Radio device. */ -+ struct b43_phy phy; -diff --git a/package/kernel/mac80211/patches/brcm/813-b43-reduce-number-of-RX-slots.patch b/package/kernel/mac80211/patches/brcm/813-b43-reduce-number-of-RX-slots.patch -new file mode 100644 -index 0000000000..85c52c0282 ---- /dev/null -+++ b/package/kernel/mac80211/patches/brcm/813-b43-reduce-number-of-RX-slots.patch -@@ -0,0 +1,11 @@ -+--- a/drivers/net/wireless/broadcom/b43/dma.h -++++ b/drivers/net/wireless/broadcom/b43/dma.h -+@@ -170,7 +170,7 @@ struct b43_dmadesc_generic { -+ -+ /* DMA engine tuning knobs */ -+ #define B43_TXRING_SLOTS 256 -+-#define B43_RXRING_SLOTS 256 -++#define B43_RXRING_SLOTS 32 -+ #define B43_DMA0_RX_FW598_BUFSIZE (B43_DMA0_RX_FW598_FO + IEEE80211_MAX_FRAME_LEN) -+ #define B43_DMA0_RX_FW351_BUFSIZE (B43_DMA0_RX_FW351_FO + IEEE80211_MAX_FRAME_LEN) -+ -diff --git a/package/kernel/mac80211/patches/brcm/814-b43-only-use-gpio-0-1-for-led.patch b/package/kernel/mac80211/patches/brcm/814-b43-only-use-gpio-0-1-for-led.patch -new file mode 100644 -index 0000000000..9cb0a32fd4 ---- /dev/null -+++ b/package/kernel/mac80211/patches/brcm/814-b43-only-use-gpio-0-1-for-led.patch -@@ -0,0 +1,17 @@ -+--- a/drivers/net/wireless/broadcom/b43/main.c -++++ b/drivers/net/wireless/broadcom/b43/main.c -+@@ -2886,6 +2886,14 @@ static int b43_gpio_init(struct b43_wlde -+ } else if (dev->dev->chip_id == 0x5354) { -+ /* Don't allow overtaking buttons GPIOs */ -+ set &= 0x2; /* 0x2 is LED GPIO on BCM5354 */ -++ } else if (dev->dev->chip_id == BCMA_CHIP_ID_BCM4716 || -++ dev->dev->chip_id == BCMA_CHIP_ID_BCM47162 || -++ dev->dev->chip_id == BCMA_CHIP_ID_BCM5356 || -++ dev->dev->chip_id == BCMA_CHIP_ID_BCM5357 || -++ dev->dev->chip_id == BCMA_CHIP_ID_BCM53572) { -++ /* just use gpio 0 and 1 for 2.4 GHz wifi led */ -++ set &= 0x3; -++ mask &= 0x3; -+ } -+ -+ if (0 /* FIXME: conditional unknown */ ) { -diff --git a/package/kernel/mac80211/patches/brcm/815-b43-always-take-overlapping-devs.patch b/package/kernel/mac80211/patches/brcm/815-b43-always-take-overlapping-devs.patch -new file mode 100644 -index 0000000000..3700eaa1a0 ---- /dev/null -+++ b/package/kernel/mac80211/patches/brcm/815-b43-always-take-overlapping-devs.patch -@@ -0,0 +1,11 @@ -+--- a/drivers/net/wireless/broadcom/b43/main.c -++++ b/drivers/net/wireless/broadcom/b43/main.c -+@@ -114,7 +114,7 @@ static int b43_modparam_pio; -+ module_param_named(pio, b43_modparam_pio, int, 0644); -+ MODULE_PARM_DESC(pio, "Use PIO accesses by default: 0=DMA, 1=PIO"); -+ -+-static int modparam_allhwsupport = !IS_ENABLED(CPTCFG_BRCMSMAC); -++static int modparam_allhwsupport = 1; -+ module_param_named(allhwsupport, modparam_allhwsupport, int, 0444); -+ MODULE_PARM_DESC(allhwsupport, "Enable support for all hardware (even it if overlaps with the brcmsmac driver)"); -+ -diff --git a/package/kernel/mac80211/patches/brcm/850-brcmsmac-remove-extra-regulation-restriction.patch b/package/kernel/mac80211/patches/brcm/850-brcmsmac-remove-extra-regulation-restriction.patch -new file mode 100644 -index 0000000000..3c93386b30 ---- /dev/null -+++ b/package/kernel/mac80211/patches/brcm/850-brcmsmac-remove-extra-regulation-restriction.patch -@@ -0,0 +1,27 @@ -+--- a/drivers/net/wireless/broadcom/brcm80211/brcmsmac/channel.c -++++ b/drivers/net/wireless/broadcom/brcm80211/brcmsmac/channel.c -+@@ -58,19 +58,12 @@ -+ (((c) < 149) ? 3 : 4)))) -+ -+ #define BRCM_2GHZ_2412_2462 REG_RULE(2412-10, 2462+10, 40, 0, 19, 0) -+-#define BRCM_2GHZ_2467_2472 REG_RULE(2467-10, 2472+10, 20, 0, 19, \ -+- NL80211_RRF_NO_IR) -++#define BRCM_2GHZ_2467_2472 REG_RULE(2467-10, 2472+10, 20, 0, 19, 0) -+ -+-#define BRCM_5GHZ_5180_5240 REG_RULE(5180-10, 5240+10, 40, 0, 21, \ -+- NL80211_RRF_NO_IR) -+-#define BRCM_5GHZ_5260_5320 REG_RULE(5260-10, 5320+10, 40, 0, 21, \ -+- NL80211_RRF_DFS | \ -+- NL80211_RRF_NO_IR) -+-#define BRCM_5GHZ_5500_5700 REG_RULE(5500-10, 5700+10, 40, 0, 21, \ -+- NL80211_RRF_DFS | \ -+- NL80211_RRF_NO_IR) -+-#define BRCM_5GHZ_5745_5825 REG_RULE(5745-10, 5825+10, 40, 0, 21, \ -+- NL80211_RRF_NO_IR) -++#define BRCM_5GHZ_5180_5240 REG_RULE(5180-10, 5240+10, 40, 0, 21, 0) -++#define BRCM_5GHZ_5260_5320 REG_RULE(5260-10, 5320+10, 40, 0, 21, 0) -++#define BRCM_5GHZ_5500_5700 REG_RULE(5500-10, 5700+10, 40, 0, 21, 0) -++#define BRCM_5GHZ_5745_5825 REG_RULE(5745-10, 5825+10, 40, 0, 21, 0) -+ -+ static const struct ieee80211_regdomain brcms_regdom_x2 = { -+ .n_reg_rules = 6, -diff --git a/package/kernel/mac80211/patches/brcm/861-brcmfmac-workaround-bug-with-some-inconsistent-BSSes.patch b/package/kernel/mac80211/patches/brcm/861-brcmfmac-workaround-bug-with-some-inconsistent-BSSes.patch -new file mode 100644 -index 0000000000..b82b442a1e ---- /dev/null -+++ b/package/kernel/mac80211/patches/brcm/861-brcmfmac-workaround-bug-with-some-inconsistent-BSSes.patch -@@ -0,0 +1,49 @@ -+From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= -+Date: Thu, 9 Jul 2015 00:07:59 +0200 -+Subject: [PATCH] brcmfmac: workaround bug with some inconsistent BSSes state -+MIME-Version: 1.0 -+Content-Type: text/plain; charset=UTF-8 -+Content-Transfer-Encoding: 8bit -+ -+Signed-off-by: Rafał Miłecki -+--- -+ -+--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c -++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c -+@@ -713,8 +713,36 @@ static struct wireless_dev *brcmf_cfg802 -+ struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy); -+ struct brcmf_pub *drvr = cfg->pub; -+ struct wireless_dev *wdev; -++ struct net_device *dev; -+ int err; -+ -++ /* -++ * There is a bug with in-firmware BSS management. When adding virtual -++ * interface brcmfmac first tells firmware to create new BSS and then -++ * it creates new struct net_device. -++ * -++ * If creating/registering netdev(ice) fails, BSS remains in some bugged -++ * state. It conflicts with existing BSSes by overtaking their auth -++ * requests. -++ * -++ * It results in one BSS (addresss X) sending beacons and another BSS -++ * (address Y) replying to authentication requests. This makes interface -++ * unusable as AP. -++ * -++ * To workaround this bug we may try to guess if register_netdev(ice) -++ * will fail. The most obvious case is using interface name that already -++ * exists. This is actually quite likely with brcmfmac & some user space -++ * scripts as brcmfmac doesn't allow deleting virtual interfaces. -++ * So this bug can be triggered even by something trivial like: -++ * iw dev wlan0 delete -++ * iw phy phy0 interface add wlan0 type __ap -++ */ -++ dev = dev_get_by_name(&init_net, name); -++ if (dev) { -++ dev_put(dev); -++ return ERR_PTR(-ENFILE); -++ } -++ -+ brcmf_dbg(TRACE, "enter: %s type %d\n", name, type); -+ err = brcmf_vif_add_validate(wiphy_to_cfg(wiphy), type); -+ if (err) { -diff --git a/package/kernel/mac80211/patches/brcm/862-brcmfmac-Disable-power-management.patch b/package/kernel/mac80211/patches/brcm/862-brcmfmac-Disable-power-management.patch -new file mode 100644 -index 0000000000..080ab8f7ef ---- /dev/null -+++ b/package/kernel/mac80211/patches/brcm/862-brcmfmac-Disable-power-management.patch -@@ -0,0 +1,27 @@ -+From 66ae1b1750720a33e29792a177b1e696f4f005fb Mon Sep 17 00:00:00 2001 -+From: Phil Elwell -+Date: Wed, 9 Mar 2016 17:25:59 +0000 -+Subject: [PATCH] brcmfmac: Disable power management -+ -+Disable wireless power saving in the brcmfmac WLAN driver. This is a -+temporary measure until the connectivity loss resulting from power -+saving is resolved. -+ -+Signed-off-by: Phil Elwell -+--- -+ drivers/net/wireless/brcm80211/brcmfmac/cfg80211.c | 2 ++ -+ 1 file changed, 2 insertions(+) -+ -+--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c -++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c -+@@ -2976,6 +2976,10 @@ brcmf_cfg80211_set_power_mgmt(struct wip -+ * preference in cfg struct to apply this to -+ * FW later while initializing the dongle -+ */ -++#if defined(CONFIG_ARCH_BCM2835) -++ brcmf_dbg(INFO, "power management disabled\n"); -++ enabled = false; -++#endif -+ cfg->pwr_save = enabled; -+ if (!check_vif_up(ifp->vif)) { -+ -diff --git a/package/kernel/mac80211/patches/brcm/863-brcmfmac-add-in-driver-tables-with-country-codes.patch b/package/kernel/mac80211/patches/brcm/863-brcmfmac-add-in-driver-tables-with-country-codes.patch -new file mode 100644 -index 0000000000..25191b6439 ---- /dev/null -+++ b/package/kernel/mac80211/patches/brcm/863-brcmfmac-add-in-driver-tables-with-country-codes.patch -@@ -0,0 +1,60 @@ -+From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= -+Subject: [PATCH] brcmfmac: add in-driver tables with country codes -+MIME-Version: 1.0 -+Content-Type: text/plain; charset=UTF-8 -+Content-Transfer-Encoding: 8bit -+ -+This adds early support for changing region. Ideally this data should -+be stored in DT as all these mappings are devices specific. -+ -+Signed-off-by: Rafał Miłecki -+--- -+ -+--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/of.c -++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/of.c -+@@ -65,6 +65,36 @@ static int brcmf_of_get_country_codes(st -+ return 0; -+ } -+ -++/* TODO: FIXME: Use DT */ -++static void brcmf_of_probe_cc(struct device *dev, -++ struct brcmf_mp_device *settings) -++{ -++ static struct brcmfmac_pd_cc_entry netgear_r8000_cc_ent[] = { -++ { "JP", "JP", 78 }, -++ { "US", "Q2", 86 }, -++ }; -++ struct brcmfmac_pd_cc_entry *cc_ent = NULL; -++ int table_size = 0; -++ -++ if (of_machine_is_compatible("netgear,r8000")) { -++ cc_ent = netgear_r8000_cc_ent; -++ table_size = ARRAY_SIZE(netgear_r8000_cc_ent); -++ } -++ -++ if (cc_ent && table_size) { -++ struct brcmfmac_pd_cc *cc; -++ size_t memsize; -++ -++ memsize = table_size * sizeof(struct brcmfmac_pd_cc_entry); -++ cc = devm_kzalloc(dev, sizeof(*cc) + memsize, GFP_KERNEL); -++ if (!cc) -++ return; -++ cc->table_size = table_size; -++ memcpy(cc->table, cc_ent, memsize); -++ settings->country_codes = cc; -++ } -++} -++ -+ void brcmf_of_probe(struct device *dev, enum brcmf_bus_type bus_type, -+ struct brcmf_mp_device *settings) -+ { -+@@ -106,6 +136,8 @@ void brcmf_of_probe(struct device *dev, -+ of_node_put(root); -+ } -+ -++ brcmf_of_probe_cc(dev, settings); -++ -+ if (!np || !of_device_is_compatible(np, "brcm,bcm4329-fmac")) -+ return; -+ -diff --git a/package/kernel/mac80211/patches/brcm/864-brcmfmac-do-not-use-internal-roaming-engine-by-default.patch b/package/kernel/mac80211/patches/brcm/864-brcmfmac-do-not-use-internal-roaming-engine-by-default.patch -new file mode 100644 -index 0000000000..fe79c40c11 ---- /dev/null -+++ b/package/kernel/mac80211/patches/brcm/864-brcmfmac-do-not-use-internal-roaming-engine-by-default.patch -@@ -0,0 +1,23 @@ -+brcmfmac: do not use internal roaming engine by default -+ -+Some evidence of curing disconnects with this disabled, so make it a default. -+Can be overridden with module parameter roamoff=0 -+See: http://projectable.me/optimize-my-pi-wi-fi/ -+ -+Signed-off-by: Phil Elwell -+--- -+ -+--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.c -++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.c -+@@ -59,7 +59,11 @@ static int brcmf_fcmode; -+ module_param_named(fcmode, brcmf_fcmode, int, 0); -+ MODULE_PARM_DESC(fcmode, "Mode of firmware signalled flow control"); -+ -++#if defined(CONFIG_ARCH_BCM2835) -++static int brcmf_roamoff = 1; -++#else -+ static int brcmf_roamoff; -++#endif -+ module_param_named(roamoff, brcmf_roamoff, int, 0400); -+ MODULE_PARM_DESC(roamoff, "Do not use internal roaming engine"); -+ -diff --git a/package/kernel/mac80211/patches/brcm/865-brcmfmac-Read-alternative-firmware-names-from-DT.patch b/package/kernel/mac80211/patches/brcm/865-brcmfmac-Read-alternative-firmware-names-from-DT.patch -new file mode 100644 -index 0000000000..8df285f8b1 ---- /dev/null -+++ b/package/kernel/mac80211/patches/brcm/865-brcmfmac-Read-alternative-firmware-names-from-DT.patch -@@ -0,0 +1,191 @@ -+From 4e32024cbb14230af3048e249e84f8c2b25ce45a Mon Sep 17 00:00:00 2001 -+From: Phil Elwell -+Date: Thu, 28 Oct 2021 15:03:16 +0100 -+Subject: [PATCH] brcmfmac: Read alternative firmware names from DT -+ -+Add the ability to load the names of alternative firmwares from the -+Device Tree node. This permits separate firmwares for 43436s and 43438 -+and allows downstream firmwares to coexist with upstream. -+ -+Signed-off-by: Phil Elwell -+--- -+ .../wireless/broadcom/brcm80211/brcmfmac/of.c | 36 ++++++++++++++ -+ .../wireless/broadcom/brcm80211/brcmfmac/of.h | 7 +++ -+ .../broadcom/brcm80211/brcmfmac/sdio.c | 47 +++++++++++++++++-- -+ 3 files changed, 87 insertions(+), 3 deletions(-) -+ -+--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/of.c -++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/of.c -+@@ -11,6 +11,7 @@ -+ #include "debug.h" -+ #include "core.h" -+ #include "common.h" -++#include "firmware.h" -+ #include "of.h" -+ -+ static int brcmf_of_get_country_codes(struct device *dev, -+@@ -168,3 +169,38 @@ void brcmf_of_probe(struct device *dev, -+ sdio->oob_irq_nr = irq; -+ sdio->oob_irq_flags = irqf; -+ } -++ -++struct brcmf_firmware_mapping * -++brcmf_of_fwnames(struct device *dev, u32 *fwname_count) -++{ -++ struct device_node *np = dev->of_node; -++ struct brcmf_firmware_mapping *fwnames; -++ struct device_node *map_np, *fw_np; -++ int of_count; -++ int count = 0; -++ -++ map_np = of_get_child_by_name(np, "firmwares"); -++ of_count = of_get_child_count(map_np); -++ if (!of_count) -++ return NULL; -++ -++ fwnames = devm_kcalloc(dev, of_count, -++ sizeof(struct brcmf_firmware_mapping), -++ GFP_KERNEL); -++ -++ for_each_child_of_node(map_np, fw_np) -++ { -++ struct brcmf_firmware_mapping *cur = &fwnames[count]; -++ -++ if (of_property_read_u32(fw_np, "chipid", &cur->chipid) || -++ of_property_read_u32(fw_np, "revmask", &cur->revmask)) -++ continue; -++ cur->fw_base = of_get_property(fw_np, "fw_base", NULL); -++ if (cur->fw_base) -++ count++; -++ } -++ -++ *fwname_count = count; -++ -++ return count ? fwnames : NULL; -++} -+--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/of.h -++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/of.h -+@@ -5,9 +5,20 @@ -+ #ifdef CONFIG_OF -+ void brcmf_of_probe(struct device *dev, enum brcmf_bus_type bus_type, -+ struct brcmf_mp_device *settings); -++#ifdef CPTCFG_BRCMFMAC_SDIO -++struct brcmf_firmware_mapping * -++brcmf_of_fwnames(struct device *dev, u32 *map_count); -++#endif -+ #else -+ static void brcmf_of_probe(struct device *dev, enum brcmf_bus_type bus_type, -+ struct brcmf_mp_device *settings) -+ { -+ } -++#ifdef CPTCFG_BRCMFMAC_SDIO -++static struct brcmf_firmware_mapping * -++brcmf_of_fwnames(struct device *dev, u32 *map_count) -++{ -++ return NULL; -++} -++#endif -+ #endif /* CONFIG_OF */ -+--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c -++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c -+@@ -35,6 +35,7 @@ -+ #include "core.h" -+ #include "common.h" -+ #include "bcdc.h" -++#include "of.h" -+ -+ #define DCMD_RESP_TIMEOUT msecs_to_jiffies(2500) -+ #define CTL_DONE_TIMEOUT msecs_to_jiffies(2500) -+@@ -634,7 +635,7 @@ MODULE_FIRMWARE(BRCMF_FW_DEFAULT_PATH "b -+ /* per-board firmware binaries */ -+ MODULE_FIRMWARE(BRCMF_FW_DEFAULT_PATH "brcmfmac*-sdio.*.bin"); -+ -+-static const struct brcmf_firmware_mapping brcmf_sdio_fwnames[] = { -++static const struct brcmf_firmware_mapping sdio_fwnames[] = { -+ BRCMF_FW_ENTRY(BRCM_CC_43143_CHIP_ID, 0xFFFFFFFF, 43143), -+ BRCMF_FW_ENTRY(BRCM_CC_43241_CHIP_ID, 0x0000001F, 43241B0), -+ BRCMF_FW_ENTRY(BRCM_CC_43241_CHIP_ID, 0x00000020, 43241B4), -+@@ -662,6 +663,9 @@ static const struct brcmf_firmware_mappi -+ BRCMF_FW_ENTRY(CY_CC_43752_CHIP_ID, 0xFFFFFFFF, 43752) -+ }; -+ -++static const struct brcmf_firmware_mapping *brcmf_sdio_fwnames = sdio_fwnames; -++static u32 brcmf_sdio_fwnames_count = ARRAY_SIZE(sdio_fwnames); -++ -+ #define TXCTL_CREDITS 2 -+ -+ static void pkt_align(struct sk_buff *p, int len, int align) -+@@ -4193,6 +4197,9 @@ static const struct brcmf_bus_ops brcmf_ -+ #define BRCMF_SDIO_FW_NVRAM 1 -+ #define BRCMF_SDIO_FW_CLM 2 -+ -++static struct brcmf_fw_request * -++brcmf_sdio_prepare_fw_request(struct brcmf_sdio *bus); -++ -+ static void brcmf_sdio_firmware_callback(struct device *dev, int err, -+ struct brcmf_fw_request *fwreq) -+ { -+@@ -4208,6 +4215,22 @@ static void brcmf_sdio_firmware_callback -+ -+ brcmf_dbg(TRACE, "Enter: dev=%s, err=%d\n", dev_name(dev), err); -+ -++ if (err && brcmf_sdio_fwnames != sdio_fwnames) { -++ /* Try again with the standard firmware names */ -++ brcmf_sdio_fwnames = sdio_fwnames; -++ brcmf_sdio_fwnames_count = ARRAY_SIZE(sdio_fwnames); -++ kfree(fwreq); -++ fwreq = brcmf_sdio_prepare_fw_request(bus); -++ if (!fwreq) { -++ err = -ENOMEM; -++ goto fail; -++ } -++ err = brcmf_fw_get_firmwares(dev, fwreq, -++ brcmf_sdio_firmware_callback); -++ if (!err) -++ return; -++ } -++ -+ if (err) -+ goto fail; -+ -+@@ -4418,7 +4441,7 @@ brcmf_sdio_prepare_fw_request(struct brc -+ -+ fwreq = brcmf_fw_alloc_request(bus->ci->chip, bus->ci->chiprev, -+ brcmf_sdio_fwnames, -+- ARRAY_SIZE(brcmf_sdio_fwnames), -++ brcmf_sdio_fwnames_count, -+ fwnames, ARRAY_SIZE(fwnames)); -+ if (!fwreq) -+ return NULL; -+@@ -4438,6 +4461,9 @@ struct brcmf_sdio *brcmf_sdio_probe(stru -+ struct brcmf_sdio *bus; -+ struct workqueue_struct *wq; -+ struct brcmf_fw_request *fwreq; -++ struct brcmf_firmware_mapping *of_fwnames, *fwnames = NULL; -++ const int fwname_size = sizeof(struct brcmf_firmware_mapping); -++ u32 of_fw_count; -+ -+ brcmf_dbg(TRACE, "Enter\n"); -+ -+@@ -4520,6 +4546,21 @@ struct brcmf_sdio *brcmf_sdio_probe(stru -+ -+ brcmf_dbg(INFO, "completed!!\n"); -+ -++ of_fwnames = brcmf_of_fwnames(sdiodev->dev, &of_fw_count); -++ if (of_fwnames) -++ fwnames = devm_kcalloc(sdiodev->dev, -++ of_fw_count + brcmf_sdio_fwnames_count, -++ fwname_size, GFP_KERNEL); -++ -++ if (fwnames) { -++ /* The array is scanned in order, so overrides come first */ -++ memcpy(fwnames, of_fwnames, of_fw_count * fwname_size); -++ memcpy(fwnames + of_fw_count, sdio_fwnames, -++ brcmf_sdio_fwnames_count * fwname_size); -++ brcmf_sdio_fwnames = fwnames; -++ brcmf_sdio_fwnames_count += of_fw_count; -++ } -++ -+ fwreq = brcmf_sdio_prepare_fw_request(bus); -+ if (!fwreq) { -+ ret = -ENOMEM; -diff --git a/package/kernel/mac80211/patches/build/000-fix_kconfig.patch b/package/kernel/mac80211/patches/build/000-fix_kconfig.patch -new file mode 100644 -index 0000000000..3987aae4f5 ---- /dev/null -+++ b/package/kernel/mac80211/patches/build/000-fix_kconfig.patch -@@ -0,0 +1,14 @@ -+--- a/kconf/Makefile -++++ b/kconf/Makefile -+@@ -1,9 +1,9 @@ -+-CFLAGS=-Wall -Wmissing-prototypes -Wstrict-prototypes -O2 -fomit-frame-pointer -++CFLAGS=-Wall -Wmissing-prototypes -Wstrict-prototypes -O2 -fomit-frame-pointer -DKBUILD_NO_NLS -+ -+ LXDIALOG := lxdialog/checklist.o lxdialog/inputbox.o lxdialog/menubox.o lxdialog/textbox.o lxdialog/util.o lxdialog/yesno.o -+ -+ conf: conf.o zconf.tab.o -+-mconf_CFLAGS := $(shell ./lxdialog/check-lxdialog.sh -ccflags) -DLOCALE -++mconf_CFLAGS := $(shell ./lxdialog/check-lxdialog.sh -ccflags) -+ mconf_LDFLAGS := $(shell ./lxdialog/check-lxdialog.sh -ldflags $(CC)) -+ mconf: CFLAGS += $(mconf_CFLAGS) -+ -diff --git a/package/kernel/mac80211/patches/build/001-fix_build.patch b/package/kernel/mac80211/patches/build/001-fix_build.patch -new file mode 100644 -index 0000000000..8f63d36e2e ---- /dev/null -+++ b/package/kernel/mac80211/patches/build/001-fix_build.patch -@@ -0,0 +1,169 @@ -+--- a/Makefile -++++ b/Makefile -+@@ -5,7 +5,7 @@ -+ ifeq ($(KERNELRELEASE),) -+ -+ MAKEFLAGS += --no-print-directory -+-SHELL := /bin/bash -++SHELL := /usr/bin/env bash -+ BACKPORT_DIR := $(shell pwd) -+ -+ KMODDIR ?= updates -+@@ -19,6 +19,7 @@ KLIB_BUILD ?= $(KLIB)/build/ -+ KERNEL_CONFIG := $(KLIB_BUILD)/.config -+ KERNEL_MAKEFILE := $(KLIB_BUILD)/Makefile -+ CONFIG_MD5 := $(shell md5sum $(KERNEL_CONFIG) 2>/dev/null | sed 's/\s.*//') -++STAMP_KERNEL_CONFIG := .kernel_config_md5_$(CONFIG_MD5) -+ -+ export KLIB KLIB_BUILD BACKPORT_DIR KMODDIR KMODPATH_ARG -+ -+@@ -36,7 +37,8 @@ mrproper: -+ @rm -f .kernel_config_md5 Kconfig.versions Kconfig.kernel -+ @rm -f backport-include/backport/autoconf.h -+ -+-.DEFAULT: -++.SILENT: $(STAMP_KERNEL_CONFIG) -++$(STAMP_KERNEL_CONFIG): -+ @set -e ; test -f local-symbols || ( \ -+ echo "/--------------" ;\ -+ echo "| You shouldn't run make in the backports tree, but only in" ;\ -+@@ -60,58 +62,62 @@ mrproper: -+ echo "| (that isn't currently running.)" ;\ -+ echo "\\--" ;\ -+ false) -+- @set -e ; if [ "$$(cat .kernel_config_md5 2>/dev/null)" != "$(CONFIG_MD5)" ] ;\ -+- then \ -+- echo -n "Generating local configuration database from kernel ..." ;\ -+- grep -v -f local-symbols $(KERNEL_CONFIG) | grep = | ( \ -+- while read l ; do \ -+- if [ "$${l:0:7}" != "CONFIG_" ] ; then \ -+- continue ;\ -+- fi ;\ -+- l=$${l:7} ;\ -+- n=$${l%%=*} ;\ -+- v=$${l#*=} ;\ -+- if [ "$$v" = "m" ] ; then \ -+- echo config $$n ;\ -+- echo ' tristate' ;\ -+- elif [ "$$v" = "y" ] ; then \ -+- echo config $$n ;\ -+- echo ' bool' ;\ -+- else \ -+- continue ;\ -+- fi ;\ -+- echo " default $$v" ;\ -+- echo "" ;\ -+- done \ -+- ) > Kconfig.kernel ;\ -+- kver=$$($(MAKE) --no-print-directory -C $(KLIB_BUILD) M=$(BACKPORT_DIR) \ -+- kernelversion | sed 's/^\(\([3-5]\|2\.6\)\.[0-9]\+\).*/\1/;t;d');\ -+- test "$$kver" != "" || echo "Kernel version parse failed!" ;\ -+- test "$$kver" != "" ;\ -+- kvers="$$(seq 14 39 | sed 's/^/2.6./')" ;\ -+- kvers="$$kvers $$(seq 0 19 | sed 's/^/3./')" ;\ -+- kvers="$$kvers $$(seq 0 20 | sed 's/^/4./')" ;\ -+- kvers="$$kvers $$(seq 0 99 | sed 's/^/5./')" ;\ -+- print=0 ;\ -+- for v in $$kvers ; do \ -+- if [ "$$print" = "1" ] ; then \ -+- echo config KERNEL_$$(echo $$v | tr . _) ;\ -+- echo " def_bool y" ;\ -+- fi ;\ -+- if [ "$$v" = "$$kver" ] ; then print=1 ; fi ;\ -+- done > Kconfig.versions ;\ -+- # RHEL as well, sadly we need to grep for it ;\ -+- RHEL_MAJOR=$$(grep '^RHEL_MAJOR' $(KERNEL_MAKEFILE) | \ -+- sed 's/.*=\s*\([0-9]*\)/\1/;t;d') ;\ -+- RHEL_MINOR=$$(grep '^RHEL_MINOR' $(KERNEL_MAKEFILE) | \ -+- sed 's/.*=\s*\([0-9]*\)/\1/;t;d') ;\ -+- for v in $$(seq 0 $$RHEL_MINOR) ; do \ -+- echo config BACKPORT_RHEL_KERNEL_$${RHEL_MAJOR}_$$v ;\ -+- echo " def_bool y" ;\ -+- done >> Kconfig.versions ;\ -+- echo " done." ;\ -+- fi ;\ -+- echo "$(CONFIG_MD5)" > .kernel_config_md5 -++ @rm -f .kernel_config_md5_* -++ @touch $@ -++ -++Kconfig.kernel: $(STAMP_KERNEL_CONFIG) local-symbols -++ @printf "Generating local configuration database from kernel ..." -++ @grep -v -f local-symbols $(KERNEL_CONFIG) | grep = | ( \ -++ while read l ; do \ -++ if [ "$${l:0:7}" != "CONFIG_" ] ; then \ -++ continue ;\ -++ fi ;\ -++ l=$${l:7} ;\ -++ n=$${l%%=*} ;\ -++ v=$${l#*=} ;\ -++ if [ "$$v" = "m" ] ; then \ -++ echo config $$n ;\ -++ echo ' tristate' ;\ -++ elif [ "$$v" = "y" ] ; then \ -++ echo config $$n ;\ -++ echo ' bool' ;\ -++ else \ -++ continue ;\ -++ fi ;\ -++ echo " default $$v" ;\ -++ echo "" ;\ -++ done \ -++ ) > $@ -++ @echo " done." -++ -++Kconfig.versions: Kconfig.kernel -++ @kver=$$($(MAKE) --no-print-directory -C $(KLIB_BUILD) M=$(BACKPORT_DIR) \ -++ kernelversion | sed 's/^\(\([3-5]\|2\.6\)\.[0-9]\+\).*/\1/;t;d');\ -++ test "$$kver" != "" || echo "Kernel version parse failed!" ;\ -++ test "$$kver" != "" ;\ -++ kvers="$$(seq 14 39 | sed 's/^/2.6./')" ;\ -++ kvers="$$kvers $$(seq 0 19 | sed 's/^/3./')" ;\ -++ kvers="$$kvers $$(seq 0 20 | sed 's/^/4./')" ;\ -++ kvers="$$kvers $$(seq 0 99 | sed 's/^/5./')" ;\ -++ print=0 ;\ -++ for v in $$kvers ; do \ -++ if [ "$$print" = "1" ] ; then \ -++ echo config KERNEL_$$(echo $$v | tr . _) ;\ -++ echo " def_bool y" ;\ -++ fi ;\ -++ if [ "$$v" = "$$kver" ] ; then print=1 ; fi ;\ -++ done > $@ -++ @RHEL_MAJOR=$$(grep '^RHEL_MAJOR' $(KERNEL_MAKEFILE) | \ -++ sed 's/.*=\s*\([0-9]*\)/\1/;t;d') ;\ -++ RHEL_MINOR=$$(grep '^RHEL_MINOR' $(KERNEL_MAKEFILE) | \ -++ sed 's/.*=\s*\([0-9]*\)/\1/;t;d') ;\ -++ for v in $$(seq 0 $$RHEL_MINOR) ; do \ -++ echo config BACKPORT_RHEL_KERNEL_$${RHEL_MAJOR}_$$v ;\ -++ echo " def_bool y" ;\ -++ done >> $@ -++ -++.DEFAULT: -++ @$(MAKE) Kconfig.versions -+ @$(MAKE) -f Makefile.real "$@" -+ -+ .PHONY: defconfig-help -+--- a/Makefile.real -++++ b/Makefile.real -+@@ -59,7 +59,7 @@ defconfig-%:: -+ -+ backport-include/backport/autoconf.h: .config Kconfig.versions Kconfig.kernel -+ @$(MAKE) oldconfig -+- @echo -n "Building backport-include/backport/autoconf.h ..." -++ @printf "Building backport-include/backport/autoconf.h ..." -+ @grep -f local-symbols .config | ( \ -+ echo "#ifndef COMPAT_AUTOCONF_INCLUDED" ;\ -+ echo "#define COMPAT_AUTOCONF_INCLUDED" ;\ -+@@ -80,7 +80,12 @@ backport-include/backport/autoconf.h: .c -+ esac ;\ -+ done ;\ -+ echo "#endif /* COMPAT_AUTOCONF_INCLUDED */" ;\ -+- ) > backport-include/backport/autoconf.h -++ ) > $@.new -++ @if cmp -s $@ $@.new; then \ -++ rm -f $@.new; \ -++ else \ -++ mv $@.new $@; \ -++ fi -+ @echo " done." -+ -+ .PHONY: modules -diff --git a/package/kernel/mac80211/patches/build/002-change_allconfig.patch b/package/kernel/mac80211/patches/build/002-change_allconfig.patch -new file mode 100644 -index 0000000000..368725d0c3 ---- /dev/null -+++ b/package/kernel/mac80211/patches/build/002-change_allconfig.patch -@@ -0,0 +1,64 @@ -+--- a/kconf/conf.c -++++ b/kconf/conf.c -+@@ -598,40 +598,12 @@ int main(int ac, char **av) -+ case oldconfig: -+ case listnewconfig: -+ case olddefconfig: -+- conf_read(NULL); -+- break; -+ case allnoconfig: -+ case allyesconfig: -+ case allmodconfig: -+ case alldefconfig: -+ case randconfig: -+- name = getenv("KCONFIG_ALLCONFIG"); -+- if (!name) -+- break; -+- if ((strcmp(name, "") != 0) && (strcmp(name, "1") != 0)) { -+- if (conf_read_simple(name, S_DEF_USER)) { -+- fprintf(stderr, -+- _("*** Can't read seed configuration \"%s\"!\n"), -+- name); -+- exit(1); -+- } -+- break; -+- } -+- switch (input_mode) { -+- case allnoconfig: name = "allno.config"; break; -+- case allyesconfig: name = "allyes.config"; break; -+- case allmodconfig: name = "allmod.config"; break; -+- case alldefconfig: name = "alldef.config"; break; -+- case randconfig: name = "allrandom.config"; break; -+- default: break; -+- } -+- if (conf_read_simple(name, S_DEF_USER) && -+- conf_read_simple("all.config", S_DEF_USER)) { -+- fprintf(stderr, -+- _("*** KCONFIG_ALLCONFIG set, but no \"%s\" or \"all.config\" file found\n"), -+- name); -+- exit(1); -+- } -++ conf_read(NULL); -+ break; -+ default: -+ break; -+--- a/kconf/confdata.c -++++ b/kconf/confdata.c -+@@ -1170,6 +1170,8 @@ bool conf_set_all_new_symbols(enum conf_ -+ } -+ bool has_changed = false; -+ -++ sym_clear_all_valid(); -++ -+ for_all_symbols(i, sym) { -+ if (sym_has_value(sym) || (sym->flags & SYMBOL_VALID)) -+ continue; -+@@ -1213,8 +1215,6 @@ bool conf_set_all_new_symbols(enum conf_ -+ -+ } -+ -+- sym_clear_all_valid(); -+- -+ /* -+ * We have different type of choice blocks. -+ * If curr.tri equals to mod then we can select several -diff --git a/package/kernel/mac80211/patches/build/003-remove_bogus_modparams.patch b/package/kernel/mac80211/patches/build/003-remove_bogus_modparams.patch -new file mode 100644 -index 0000000000..aa26c8cb2a ---- /dev/null -+++ b/package/kernel/mac80211/patches/build/003-remove_bogus_modparams.patch -@@ -0,0 +1,34 @@ -+--- a/compat/main.c -++++ b/compat/main.c -+@@ -19,31 +19,6 @@ MODULE_LICENSE("GPL"); -+ #error "You need a CPTCFG_VERSION" -+ #endif -+ -+-static char *backported_kernel_name = CPTCFG_KERNEL_NAME; -+- -+-module_param(backported_kernel_name, charp, 0400); -+-MODULE_PARM_DESC(backported_kernel_name, -+- "The kernel tree name that was used for this backport (" CPTCFG_KERNEL_NAME ")"); -+- -+-#ifdef BACKPORTS_GIT_TRACKED -+-static char *backports_tracker_id = BACKPORTS_GIT_TRACKED; -+-module_param(backports_tracker_id, charp, 0400); -+-MODULE_PARM_DESC(backports_tracker_id, -+- "The version of the tree containing this backport (" BACKPORTS_GIT_TRACKED ")"); -+-#else -+-static char *backported_kernel_version = CPTCFG_KERNEL_VERSION; -+-static char *backports_version = CPTCFG_VERSION; -+- -+-module_param(backported_kernel_version, charp, 0400); -+-MODULE_PARM_DESC(backported_kernel_version, -+- "The kernel version that was used for this backport (" CPTCFG_KERNEL_VERSION ")"); -+- -+-module_param(backports_version, charp, 0400); -+-MODULE_PARM_DESC(backports_version, -+- "The git version of the backports tree used to generate this backport (" CPTCFG_VERSION ")"); -+- -+-#endif -+- -+ void backport_dependency_symbol(void) -+ { -+ } -diff --git a/package/kernel/mac80211/patches/build/012-kernel_build_check.patch b/package/kernel/mac80211/patches/build/012-kernel_build_check.patch -new file mode 100644 -index 0000000000..d225ba1820 ---- /dev/null -+++ b/package/kernel/mac80211/patches/build/012-kernel_build_check.patch -@@ -0,0 +1,11 @@ -+--- a/Makefile -++++ b/Makefile -+@@ -2,7 +2,7 @@ -+ # Makefile for the output source package -+ # -+ -+-ifeq ($(KERNELRELEASE),) -++ifeq ($(KERNELVERSION),) -+ -+ MAKEFLAGS += --no-print-directory -+ SHELL := /usr/bin/env bash -diff --git a/package/kernel/mac80211/patches/build/060-no_local_ssb_bcma.patch b/package/kernel/mac80211/patches/build/060-no_local_ssb_bcma.patch -new file mode 100644 -index 0000000000..4ad2ac081a ---- /dev/null -+++ b/package/kernel/mac80211/patches/build/060-no_local_ssb_bcma.patch -@@ -0,0 +1,314 @@ -+--- a/local-symbols -++++ b/local-symbols -+@@ -470,43 +470,6 @@ USB_VL600= -+ USB_NET_CH9200= -+ USB_NET_AQC111= -+ USB_RTL8153_ECM= -+-SSB_POSSIBLE= -+-SSB= -+-SSB_SPROM= -+-SSB_BLOCKIO= -+-SSB_PCIHOST_POSSIBLE= -+-SSB_PCIHOST= -+-SSB_B43_PCI_BRIDGE= -+-SSB_PCMCIAHOST_POSSIBLE= -+-SSB_PCMCIAHOST= -+-SSB_SDIOHOST_POSSIBLE= -+-SSB_SDIOHOST= -+-SSB_HOST_SOC= -+-SSB_SERIAL= -+-SSB_DRIVER_PCICORE_POSSIBLE= -+-SSB_DRIVER_PCICORE= -+-SSB_PCICORE_HOSTMODE= -+-SSB_DRIVER_MIPS= -+-SSB_SFLASH= -+-SSB_EMBEDDED= -+-SSB_DRIVER_EXTIF= -+-SSB_DRIVER_GIGE= -+-SSB_DRIVER_GPIO= -+-BCMA_POSSIBLE= -+-BCMA= -+-BCMA_BLOCKIO= -+-BCMA_HOST_PCI_POSSIBLE= -+-BCMA_HOST_PCI= -+-BCMA_HOST_SOC= -+-BCMA_DRIVER_PCI= -+-BCMA_DRIVER_PCI_HOSTMODE= -+-BCMA_DRIVER_MIPS= -+-BCMA_PFLASH= -+-BCMA_SFLASH= -+-BCMA_NFLASH= -+-BCMA_DRIVER_GMAC_CMN= -+-BCMA_DRIVER_GPIO= -+-BCMA_DEBUG= -+ USB_ACM= -+ USB_PRINTER= -+ USB_WDM= -+--- a/drivers/net/wireless/broadcom/b43/Kconfig -++++ b/drivers/net/wireless/broadcom/b43/Kconfig -+@@ -63,21 +63,21 @@ endchoice -+ config B43_PCI_AUTOSELECT -+ bool -+ depends on B43 && SSB_PCIHOST_POSSIBLE -+- select SSB_PCIHOST -+- select SSB_B43_PCI_BRIDGE -++ depends on SSB_PCIHOST -++ depends on SSB_B43_PCI_BRIDGE -+ default y -+ -+ # Auto-select SSB PCICORE driver, if possible -+ config B43_PCICORE_AUTOSELECT -+ bool -+ depends on B43 && SSB_DRIVER_PCICORE_POSSIBLE -+- select SSB_DRIVER_PCICORE -++ depends on SSB_DRIVER_PCICORE -+ default y -+ -+ config B43_SDIO -+ bool "Broadcom 43xx SDIO device support" -+ depends on B43 && B43_SSB && SSB_SDIOHOST_POSSIBLE -+- select SSB_SDIOHOST -++ depends on SSB_SDIOHOST -+ help -+ Broadcom 43xx device support for Soft-MAC SDIO devices. -+ -+@@ -96,13 +96,13 @@ config B43_SDIO -+ config B43_BCMA_PIO -+ bool -+ depends on B43 && B43_BCMA -+- select BCMA_BLOCKIO -++ depends on BCMA_BLOCKIO -+ default y -+ -+ config B43_PIO -+ bool -+ depends on B43 && B43_SSB -+- select SSB_BLOCKIO -++ depends on SSB_BLOCKIO -+ default y -+ -+ config B43_PHY_G -+--- a/drivers/net/wireless/broadcom/b43/main.c -++++ b/drivers/net/wireless/broadcom/b43/main.c -+@@ -2853,7 +2853,7 @@ static struct ssb_device *b43_ssb_gpio_d -+ { -+ struct ssb_bus *bus = dev->dev->sdev->bus; -+ -+-#ifdef CPTCFG_SSB_DRIVER_PCICORE -++#ifdef CONFIG_SSB_DRIVER_PCICORE -+ return (bus->chipco.dev ? bus->chipco.dev : bus->pcicore.dev); -+ #else -+ return bus->chipco.dev; -+@@ -4871,7 +4871,7 @@ static int b43_wireless_core_init(struct -+ } -+ if (sprom->boardflags_lo & B43_BFL_XTAL_NOSLOW) -+ hf |= B43_HF_DSCRQ; /* Disable slowclock requests from ucode. */ -+-#if defined(CPTCFG_B43_SSB) && defined(CPTCFG_SSB_DRIVER_PCICORE) -++#if defined(CPTCFG_B43_SSB) && defined(CONFIG_SSB_DRIVER_PCICORE) -+ if (dev->dev->bus_type == B43_BUS_SSB && -+ dev->dev->sdev->bus->bustype == SSB_BUSTYPE_PCI && -+ dev->dev->sdev->bus->pcicore.dev->id.revision <= 10) -+--- a/drivers/net/wireless/broadcom/b43legacy/Kconfig -++++ b/drivers/net/wireless/broadcom/b43legacy/Kconfig -+@@ -3,7 +3,7 @@ config B43LEGACY -+ tristate "Broadcom 43xx-legacy wireless support (mac80211 stack)" -+ depends on m -+ depends on SSB_POSSIBLE && MAC80211 && HAS_DMA -+- select SSB -++ depends on SSB -+ depends on FW_LOADER -+ help -+ b43legacy is a driver for 802.11b devices from Broadcom (BCM4301 and -+@@ -25,15 +25,15 @@ config B43LEGACY -+ config B43LEGACY_PCI_AUTOSELECT -+ bool -+ depends on B43LEGACY && SSB_PCIHOST_POSSIBLE -+- select SSB_PCIHOST -+- select SSB_B43_PCI_BRIDGE -++ depends on SSB_PCIHOST -++ depends on SSB_B43_PCI_BRIDGE -+ default y -+ -+ # Auto-select SSB PCICORE driver, if possible -+ config B43LEGACY_PCICORE_AUTOSELECT -+ bool -+ depends on B43LEGACY && SSB_DRIVER_PCICORE_POSSIBLE -+- select SSB_DRIVER_PCICORE -++ depends on SSB_DRIVER_PCICORE -+ default y -+ -+ # LED support -+--- a/drivers/net/wireless/broadcom/b43legacy/main.c -++++ b/drivers/net/wireless/broadcom/b43legacy/main.c -+@@ -1907,7 +1907,7 @@ static int b43legacy_gpio_init(struct b4 -+ if (dev->dev->id.revision >= 2) -+ mask |= 0x0010; /* FIXME: This is redundant. */ -+ -+-#ifdef CPTCFG_SSB_DRIVER_PCICORE -++#ifdef CONFIG_SSB_DRIVER_PCICORE -+ pcidev = bus->pcicore.dev; -+ #endif -+ gpiodev = bus->chipco.dev ? : pcidev; -+@@ -1926,7 +1926,7 @@ static void b43legacy_gpio_cleanup(struc -+ struct ssb_bus *bus = dev->dev->bus; -+ struct ssb_device *gpiodev, *pcidev = NULL; -+ -+-#ifdef CPTCFG_SSB_DRIVER_PCICORE -++#ifdef CONFIG_SSB_DRIVER_PCICORE -+ pcidev = bus->pcicore.dev; -+ #endif -+ gpiodev = bus->chipco.dev ? : pcidev; -+--- a/drivers/net/wireless/broadcom/brcm80211/Kconfig -++++ b/drivers/net/wireless/broadcom/brcm80211/Kconfig -+@@ -8,7 +8,7 @@ config BRCMSMAC -+ depends on m -+ depends on MAC80211 -+ depends on BCMA_POSSIBLE -+- select BCMA -++ depends on BCMA -+ select BRCMUTIL -+ depends on FW_LOADER -+ depends on CORDIC -+--- a/Kconfig.local -++++ b/Kconfig.local -+@@ -1414,117 +1414,6 @@ config BACKPORTED_USB_NET_AQC111 -+ config BACKPORTED_USB_RTL8153_ECM -+ tristate -+ default USB_RTL8153_ECM -+-config BACKPORTED_SSB_POSSIBLE -+- tristate -+- default SSB_POSSIBLE -+-config BACKPORTED_SSB -+- tristate -+- default SSB -+-config BACKPORTED_SSB_SPROM -+- tristate -+- default SSB_SPROM -+-config BACKPORTED_SSB_BLOCKIO -+- tristate -+- default SSB_BLOCKIO -+-config BACKPORTED_SSB_PCIHOST_POSSIBLE -+- tristate -+- default SSB_PCIHOST_POSSIBLE -+-config BACKPORTED_SSB_PCIHOST -+- tristate -+- default SSB_PCIHOST -+-config BACKPORTED_SSB_B43_PCI_BRIDGE -+- tristate -+- default SSB_B43_PCI_BRIDGE -+-config BACKPORTED_SSB_PCMCIAHOST_POSSIBLE -+- tristate -+- default SSB_PCMCIAHOST_POSSIBLE -+-config BACKPORTED_SSB_PCMCIAHOST -+- tristate -+- default SSB_PCMCIAHOST -+-config BACKPORTED_SSB_SDIOHOST_POSSIBLE -+- tristate -+- default SSB_SDIOHOST_POSSIBLE -+-config BACKPORTED_SSB_SDIOHOST -+- tristate -+- default SSB_SDIOHOST -+-config BACKPORTED_SSB_HOST_SOC -+- tristate -+- default SSB_HOST_SOC -+-config BACKPORTED_SSB_SERIAL -+- tristate -+- default SSB_SERIAL -+-config BACKPORTED_SSB_DRIVER_PCICORE_POSSIBLE -+- tristate -+- default SSB_DRIVER_PCICORE_POSSIBLE -+-config BACKPORTED_SSB_DRIVER_PCICORE -+- tristate -+- default SSB_DRIVER_PCICORE -+-config BACKPORTED_SSB_PCICORE_HOSTMODE -+- tristate -+- default SSB_PCICORE_HOSTMODE -+-config BACKPORTED_SSB_DRIVER_MIPS -+- tristate -+- default SSB_DRIVER_MIPS -+-config BACKPORTED_SSB_SFLASH -+- tristate -+- default SSB_SFLASH -+-config BACKPORTED_SSB_EMBEDDED -+- tristate -+- default SSB_EMBEDDED -+-config BACKPORTED_SSB_DRIVER_EXTIF -+- tristate -+- default SSB_DRIVER_EXTIF -+-config BACKPORTED_SSB_DRIVER_GIGE -+- tristate -+- default SSB_DRIVER_GIGE -+-config BACKPORTED_SSB_DRIVER_GPIO -+- tristate -+- default SSB_DRIVER_GPIO -+-config BACKPORTED_BCMA_POSSIBLE -+- tristate -+- default BCMA_POSSIBLE -+-config BACKPORTED_BCMA -+- tristate -+- default BCMA -+-config BACKPORTED_BCMA_BLOCKIO -+- tristate -+- default BCMA_BLOCKIO -+-config BACKPORTED_BCMA_HOST_PCI_POSSIBLE -+- tristate -+- default BCMA_HOST_PCI_POSSIBLE -+-config BACKPORTED_BCMA_HOST_PCI -+- tristate -+- default BCMA_HOST_PCI -+-config BACKPORTED_BCMA_HOST_SOC -+- tristate -+- default BCMA_HOST_SOC -+-config BACKPORTED_BCMA_DRIVER_PCI -+- tristate -+- default BCMA_DRIVER_PCI -+-config BACKPORTED_BCMA_DRIVER_PCI_HOSTMODE -+- tristate -+- default BCMA_DRIVER_PCI_HOSTMODE -+-config BACKPORTED_BCMA_DRIVER_MIPS -+- tristate -+- default BCMA_DRIVER_MIPS -+-config BACKPORTED_BCMA_PFLASH -+- tristate -+- default BCMA_PFLASH -+-config BACKPORTED_BCMA_SFLASH -+- tristate -+- default BCMA_SFLASH -+-config BACKPORTED_BCMA_NFLASH -+- tristate -+- default BCMA_NFLASH -+-config BACKPORTED_BCMA_DRIVER_GMAC_CMN -+- tristate -+- default BCMA_DRIVER_GMAC_CMN -+-config BACKPORTED_BCMA_DRIVER_GPIO -+- tristate -+- default BCMA_DRIVER_GPIO -+-config BACKPORTED_BCMA_DEBUG -+- tristate -+- default BCMA_DEBUG -+ config BACKPORTED_USB_ACM -+ tristate -+ default USB_ACM -+--- a/Kconfig.sources -++++ b/Kconfig.sources -+@@ -10,9 +10,6 @@ source "$BACKPORT_DIR/drivers/soc/qcom/K -+ source "$BACKPORT_DIR/drivers/net/wireless/Kconfig" -+ source "$BACKPORT_DIR/drivers/net/usb/Kconfig" -+ -+-source "$BACKPORT_DIR/drivers/ssb/Kconfig" -+-source "$BACKPORT_DIR/drivers/bcma/Kconfig" -+- -+ source "$BACKPORT_DIR/drivers/usb/class/Kconfig" -+ -+ source "$BACKPORT_DIR/drivers/staging/Kconfig" -+--- a/Makefile.kernel -++++ b/Makefile.kernel -+@@ -43,8 +43,6 @@ obj-$(CPTCFG_QRTR) += net/qrtr/ -+ obj-$(CPTCFG_QCOM_QMI_HELPERS) += drivers/soc/qcom/ -+ obj-$(CPTCFG_MHI_BUS) += drivers/bus/mhi/ -+ obj-$(CPTCFG_WLAN) += drivers/net/wireless/ -+-obj-$(CPTCFG_SSB) += drivers/ssb/ -+-obj-$(CPTCFG_BCMA) += drivers/bcma/ -+ obj-$(CPTCFG_USB_NET_RNDIS_WLAN) += drivers/net/usb/ -+ -+ obj-$(CPTCFG_USB_WDM) += drivers/usb/class/ -diff --git a/package/kernel/mac80211/patches/build/070-remove-broken-wext-select.patch b/package/kernel/mac80211/patches/build/070-remove-broken-wext-select.patch -new file mode 100644 -index 0000000000..121b7faad9 ---- /dev/null -+++ b/package/kernel/mac80211/patches/build/070-remove-broken-wext-select.patch -@@ -0,0 +1,10 @@ -+--- a/drivers/staging/rtl8723bs/Kconfig -++++ b/drivers/staging/rtl8723bs/Kconfig -+@@ -5,7 +5,6 @@ config RTL8723BS -+ depends on m -+ depends on WLAN && MMC && CFG80211 -+ depends on m -+- select CFG80211_WEXT -+ depends on CRYPTO -+ select BPAUTO_CRYPTO_LIB_ARC4 -+ help -diff --git a/package/kernel/mac80211/patches/build/080-resv_start_op.patch b/package/kernel/mac80211/patches/build/080-resv_start_op.patch -new file mode 100644 -index 0000000000..40b8e94a20 ---- /dev/null -+++ b/package/kernel/mac80211/patches/build/080-resv_start_op.patch -@@ -0,0 +1,24 @@ -+--- a/drivers/net/wireless/mac80211_hwsim.c -++++ b/drivers/net/wireless/mac80211_hwsim.c -+@@ -5363,7 +5363,9 @@ static struct genl_family hwsim_genl_fam -+ .module = THIS_MODULE, -+ .small_ops = hwsim_ops, -+ .n_small_ops = ARRAY_SIZE(hwsim_ops), -++#if LINUX_VERSION_IS_GEQ(6,1,0) -+ .resv_start_op = HWSIM_CMD_DEL_MAC_ADDR + 1, -++#endif -+ .mcgrps = hwsim_mcgrps, -+ .n_mcgrps = ARRAY_SIZE(hwsim_mcgrps), -+ }; -+--- a/net/wireless/nl80211.c -++++ b/net/wireless/nl80211.c -+@@ -17233,7 +17233,9 @@ static struct genl_family nl80211_fam __ -+ .n_ops = ARRAY_SIZE(nl80211_ops), -+ .small_ops = nl80211_small_ops, -+ .n_small_ops = ARRAY_SIZE(nl80211_small_ops), -++#if LINUX_VERSION_IS_GEQ(6,1,0) -+ .resv_start_op = NL80211_CMD_REMOVE_LINK_STA + 1, -++#endif -+ .mcgrps = nl80211_mcgrps, -+ .n_mcgrps = ARRAY_SIZE(nl80211_mcgrps), -+ .parallel_ops = true, -diff --git a/package/kernel/mac80211/patches/build/090-bcma-otp.patch b/package/kernel/mac80211/patches/build/090-bcma-otp.patch -new file mode 100644 -index 0000000000..3974776124 ---- /dev/null -+++ b/package/kernel/mac80211/patches/build/090-bcma-otp.patch -@@ -0,0 +1,13 @@ -+--- /dev/null -++++ b/backport-include/linux/bcma/bcma_driver_chipcommon.h -+@@ -0,0 +1,10 @@ -++#ifndef __BACKPORT_BCMA_DRIVER_CHIPCOMMON_H -++#define __BACKPORT_BCMA_DRIVER_CHIPCOMMON_H -++ -++#include_next -++ -++#ifndef BCMA_CC_SROM_CONTROL_OTP_PRESENT -++#define BCMA_CC_SROM_CONTROL_OTP_PRESENT 0x00000020 -++#endif -++ -++#endif -diff --git a/package/kernel/mac80211/patches/build/100-backports-drop-QRTR-and-MHI.patch b/package/kernel/mac80211/patches/build/100-backports-drop-QRTR-and-MHI.patch -new file mode 100644 -index 0000000000..b017a0ce14 ---- /dev/null -+++ b/package/kernel/mac80211/patches/build/100-backports-drop-QRTR-and-MHI.patch -@@ -0,0 +1,76 @@ -+From 54e0f9aaf340377fb76acdffee9ec7372c4b70ae Mon Sep 17 00:00:00 2001 -+From: Robert Marko -+Date: Mon, 17 Oct 2022 11:35:36 +0200 -+Subject: [PATCH] backports: drop QRTR and MHI -+ -+Backports currently include QRTR and MHI due to ath11k-pci requiring them, -+however this at the same time prevents us from adding ath11k-ahb as it -+also requires QRTR however its AHB variant from the kernel will conflict -+with the core provided by backports. -+ -+Since MHI also conflicts with existing OpenWrt kmods providing MHI drop -+both from backports and use the ones provided by OpenWrt kernel. -+ -+Signed-off-by: Robert Marko -+--- -+ Kconfig.sources | 2 -- -+ Makefile.kernel | 2 -- -+ drivers/net/wireless/ath/ath11k/Kconfig | 6 +++--- -+ local-symbols | 8 -------- -+ 4 files changed, 3 insertions(+), 15 deletions(-) -+ -+--- a/Kconfig.sources -++++ b/Kconfig.sources -+@@ -4,8 +4,6 @@ source "$BACKPORT_DIR/compat/Kconfig" -+ # these are copied from the kernel -+ source "$BACKPORT_DIR/net/wireless/Kconfig" -+ source "$BACKPORT_DIR/net/mac80211/Kconfig" -+-source "$BACKPORT_DIR/net/qrtr/Kconfig" -+-source "$BACKPORT_DIR/drivers/bus/mhi/Kconfig" -+ source "$BACKPORT_DIR/drivers/soc/qcom/Kconfig" -+ source "$BACKPORT_DIR/drivers/net/wireless/Kconfig" -+ source "$BACKPORT_DIR/drivers/net/usb/Kconfig" -+--- a/Makefile.kernel -++++ b/Makefile.kernel -+@@ -39,9 +39,7 @@ obj-y += compat/ -+ -+ obj-$(CPTCFG_CFG80211) += net/wireless/ -+ obj-$(CPTCFG_MAC80211) += net/mac80211/ -+-obj-$(CPTCFG_QRTR) += net/qrtr/ -+ obj-$(CPTCFG_QCOM_QMI_HELPERS) += drivers/soc/qcom/ -+-obj-$(CPTCFG_MHI_BUS) += drivers/bus/mhi/ -+ obj-$(CPTCFG_WLAN) += drivers/net/wireless/ -+ obj-$(CPTCFG_USB_NET_RNDIS_WLAN) += drivers/net/usb/ -+ -+--- a/drivers/net/wireless/ath/ath11k/Kconfig -++++ b/drivers/net/wireless/ath/ath11k/Kconfig -+@@ -25,9 +25,9 @@ config ATH11K_PCI -+ tristate "Atheros ath11k PCI support" -+ depends on m -+ depends on ATH11K && PCI -+- select MHI_BUS -+- select QRTR -+- select QRTR_MHI -++ depends on MHI_BUS -++ depends on QRTR -++ depends on QRTR_MHI -+ help -+ This module adds support for PCIE bus -+ -+--- a/local-symbols -++++ b/local-symbols -+@@ -65,14 +65,6 @@ MAC80211_MESH_PS_DEBUG= -+ MAC80211_TDLS_DEBUG= -+ MAC80211_DEBUG_COUNTERS= -+ MAC80211_STA_HASH_MAX_SIZE= -+-QRTR= -+-QRTR_SMD= -+-QRTR_TUN= -+-QRTR_MHI= -+-MHI_BUS= -+-MHI_BUS_DEBUG= -+-MHI_BUS_PCI_GENERIC= -+-MHI_BUS_EP= -+ QCOM_AOSS_QMP= -+ QCOM_COMMAND_DB= -+ QCOM_CPR= -diff --git a/package/kernel/mac80211/patches/build/110-backport_napi_build_skb.patch b/package/kernel/mac80211/patches/build/110-backport_napi_build_skb.patch -new file mode 100644 -index 0000000000..1e152fecea ---- /dev/null -+++ b/package/kernel/mac80211/patches/build/110-backport_napi_build_skb.patch -@@ -0,0 +1,11 @@ -+--- a/backport-include/linux/skbuff.h -++++ b/backport-include/linux/skbuff.h -+@@ -144,4 +144,8 @@ static inline u64 skb_get_kcov_handle(st -+ #define napi_build_skb build_skb -+ #endif -+ -++#if LINUX_VERSION_IS_LESS(5,11,0) -++#define napi_build_skb build_skb -++#endif -++ -+ #endif /* __BACKPORT_SKBUFF_H */ -diff --git a/package/kernel/mac80211/patches/mt7601u/001-wifi-mt7601u-update-firmware-path.patch b/package/kernel/mac80211/patches/mt7601u/001-wifi-mt7601u-update-firmware-path.patch -new file mode 100644 -index 0000000000..5d982906c5 ---- /dev/null -+++ b/package/kernel/mac80211/patches/mt7601u/001-wifi-mt7601u-update-firmware-path.patch -@@ -0,0 +1,55 @@ -+From patchwork Mon May 15 22:56:53 2023 -+Content-Type: text/plain; charset="utf-8" -+MIME-Version: 1.0 -+Content-Transfer-Encoding: 7bit -+X-Patchwork-Submitter: Daniel Golle -+X-Patchwork-Id: 13242309 -+X-Patchwork-Delegate: kvalo@adurom.com -+Return-Path: -+Date: Tue, 16 May 2023 00:56:53 +0200 -+From: Daniel Golle -+To: Jakub Kicinski , Kalle Valo , -+ "David S. Miller" , -+ Eric Dumazet , -+ Paolo Abeni , -+ Matthias Brugger , -+ AngeloGioacchino Del Regno -+ , -+ linux-wireless@vger.kernel.org, netdev@vger.kernel.org, -+ linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org, -+ linux-mediatek@lists.infradead.org -+Subject: [PATCH] wifi: mt7601u: update firmware path -+Message-ID: -+ -+MIME-Version: 1.0 -+Content-Disposition: inline -+Precedence: bulk -+List-ID: -+X-Mailing-List: linux-wireless@vger.kernel.org -+ -+mt7601u.bin was moved to mediatek/ folder in linux-wireless via commit -+8451c2b1 ("mt76xx: Move the old Mediatek WiFi firmware to mediatek") -+and linux-firmware release 20230515. -+ -+Update the firmware path requested by the mt7601u driver to follow up -+with the move of the file. -+ -+Signed-off-by: Daniel Golle -+--- -+ drivers/net/wireless/mediatek/mt7601u/usb.h | 2 +- -+ 1 file changed, 1 insertion(+), 1 deletion(-) -+ -+ -+base-commit: 0d9b41daa5907756a31772d8af8ac5ff25cf17c1 -+ -+--- a/drivers/net/wireless/mediatek/mt7601u/usb.h -++++ b/drivers/net/wireless/mediatek/mt7601u/usb.h -+@@ -8,7 +8,7 @@ -+ -+ #include "mt7601u.h" -+ -+-#define MT7601U_FIRMWARE "mt7601u.bin" -++#define MT7601U_FIRMWARE "mediatek/mt7601u.bin" -+ -+ #define MT_VEND_REQ_MAX_RETRY 10 -+ #define MT_VEND_REQ_TOUT_MS 300 -diff --git a/package/kernel/mac80211/patches/mwl/700-mwl8k-missing-pci-id-for-WNR854T.patch b/package/kernel/mac80211/patches/mwl/700-mwl8k-missing-pci-id-for-WNR854T.patch -new file mode 100644 -index 0000000000..11536651b5 ---- /dev/null -+++ b/package/kernel/mac80211/patches/mwl/700-mwl8k-missing-pci-id-for-WNR854T.patch -@@ -0,0 +1,10 @@ -+--- a/drivers/net/wireless/marvell/mwl8k.c -++++ b/drivers/net/wireless/marvell/mwl8k.c -+@@ -5703,6 +5703,7 @@ MODULE_FIRMWARE("mwl8k/fmimage_8366.fw") -+ MODULE_FIRMWARE(MWL8K_8366_AP_FW(MWL8K_8366_AP_FW_API)); -+ -+ static const struct pci_device_id mwl8k_pci_id_table[] = { -++ { PCI_VDEVICE(MARVELL, 0x2a02), .driver_data = MWL8363, }, -+ { PCI_VDEVICE(MARVELL, 0x2a0a), .driver_data = MWL8363, }, -+ { PCI_VDEVICE(MARVELL, 0x2a0c), .driver_data = MWL8363, }, -+ { PCI_VDEVICE(MARVELL, 0x2a24), .driver_data = MWL8363, }, -diff --git a/package/kernel/mac80211/patches/mwl/801-libertas-configure-sysfs-links.patch b/package/kernel/mac80211/patches/mwl/801-libertas-configure-sysfs-links.patch -new file mode 100644 -index 0000000000..1dbcb1bfef ---- /dev/null -+++ b/package/kernel/mac80211/patches/mwl/801-libertas-configure-sysfs-links.patch -@@ -0,0 +1,21 @@ -+--- a/drivers/net/wireless/marvell/libertas/cfg.c -++++ b/drivers/net/wireless/marvell/libertas/cfg.c -+@@ -2052,6 +2052,8 @@ struct wireless_dev *lbs_cfg_alloc(struc -+ goto err_wiphy_new; -+ } -+ -++ set_wiphy_dev(wdev->wiphy, dev); -++ -+ return wdev; -+ -+ err_wiphy_new: -+--- a/drivers/net/wireless/marvell/libertas/main.c -++++ b/drivers/net/wireless/marvell/libertas/main.c -+@@ -935,6 +935,7 @@ struct lbs_private *lbs_add_card(void *c -+ goto err_adapter; -+ } -+ -++ dev_net_set(dev, wiphy_net(wdev->wiphy)); -+ dev->ieee80211_ptr = wdev; -+ dev->ml_priv = priv; -+ SET_NETDEV_DEV(dev, dmdev); -diff --git a/package/kernel/mac80211/patches/mwl/802-libertas-set-wireless-macaddr.patch b/package/kernel/mac80211/patches/mwl/802-libertas-set-wireless-macaddr.patch -new file mode 100644 -index 0000000000..b47aee5490 ---- /dev/null -+++ b/package/kernel/mac80211/patches/mwl/802-libertas-set-wireless-macaddr.patch -@@ -0,0 +1,11 @@ -+--- a/drivers/net/wireless/marvell/libertas/cfg.c -++++ b/drivers/net/wireless/marvell/libertas/cfg.c -+@@ -2128,6 +2128,8 @@ int lbs_cfg_register(struct lbs_private -+ wdev->wiphy->n_cipher_suites = ARRAY_SIZE(cipher_suites); -+ wdev->wiphy->reg_notifier = lbs_reg_notifier; -+ -++ memcpy(wdev->wiphy->perm_addr, priv->current_addr, ETH_ALEN); -++ -+ ret = wiphy_register(wdev->wiphy); -+ if (ret < 0) -+ pr_err("cannot register wiphy device\n"); -diff --git a/package/kernel/mac80211/patches/mwl/900-mwifiex-increase-the-global-limit-up-to-4-SSID.patch b/package/kernel/mac80211/patches/mwl/900-mwifiex-increase-the-global-limit-up-to-4-SSID.patch -new file mode 100644 -index 0000000000..caa139a2c6 ---- /dev/null -+++ b/package/kernel/mac80211/patches/mwl/900-mwifiex-increase-the-global-limit-up-to-4-SSID.patch -@@ -0,0 +1,41 @@ -+From ef8098cd6cb8b5989afef2e8461fe6ba9570a854 Mon Sep 17 00:00:00 2001 -+From: Josef Schlehofer -+Date: Wed, 24 Nov 2021 12:47:40 +0100 -+Subject: [PATCH] mwifiex: increase the global limit up to 4 SSID -+ -+Firmware for SDIO (88W8997), which is used in Turris MOX SDIO addon [1], -+allows up to 4 SSID. Unfortunately, driver (even in mainline kernel) -+has a global limit for all Marvell cards up to 3 SSID. -+ -+Pali Rohár tested this patch and verified that the SDIO Wi-Fi addon works -+with the 4 SSID. So, let's increase the global limit from 3 to 4. -+ -+Ideally, this patch should be done differently before sending -+it to Linux kernel. It means that limit definition should be moved to -+the card-specific structure. -+ -+[1] https://docs.turris.cz/hw/mox/addons/#wi-fi-sdio -+--- -+ drivers/net/wireless/marvell/mwifiex/decl.h | 4 ++-- -+ 1 file changed, 2 insertions(+), 2 deletions(-) -+ -+--- a/drivers/net/wireless/marvell/mwifiex/decl.h -++++ b/drivers/net/wireless/marvell/mwifiex/decl.h -+@@ -18,7 +18,7 @@ -+ #include -+ -+ #define MWIFIEX_BSS_COEX_COUNT 2 -+-#define MWIFIEX_MAX_BSS_NUM (3) -++#define MWIFIEX_MAX_BSS_NUM (4) -+ -+ #define MWIFIEX_DMA_ALIGN_SZ 64 -+ #define MWIFIEX_RX_HEADROOM 64 -+@@ -100,7 +100,7 @@ -+ #define MWIFIEX_RATE_INDEX_OFDM0 4 -+ -+ #define MWIFIEX_MAX_STA_NUM 3 -+-#define MWIFIEX_MAX_UAP_NUM 3 -++#define MWIFIEX_MAX_UAP_NUM 4 -+ #define MWIFIEX_MAX_P2P_NUM 3 -+ -+ #define MWIFIEX_A_BAND_START_FREQ 5000 -diff --git a/package/kernel/mac80211/patches/mwl/940-mwl8k_init_devices_synchronously.patch b/package/kernel/mac80211/patches/mwl/940-mwl8k_init_devices_synchronously.patch -new file mode 100644 -index 0000000000..c8d24283aa ---- /dev/null -+++ b/package/kernel/mac80211/patches/mwl/940-mwl8k_init_devices_synchronously.patch -@@ -0,0 +1,20 @@ -+--- a/drivers/net/wireless/marvell/mwl8k.c -++++ b/drivers/net/wireless/marvell/mwl8k.c -+@@ -6289,6 +6289,8 @@ static int mwl8k_probe(struct pci_dev *p -+ -+ priv->running_bsses = 0; -+ -++ wait_for_completion(&priv->firmware_loading_complete); -++ -+ return rc; -+ -+ err_stop_firmware: -+@@ -6322,8 +6324,6 @@ static void mwl8k_remove(struct pci_dev -+ return; -+ priv = hw->priv; -+ -+- wait_for_completion(&priv->firmware_loading_complete); -+- -+ if (priv->fw_state == FW_STATE_ERROR) { -+ mwl8k_hw_reset(priv); -+ goto unmap; -diff --git a/package/kernel/mac80211/patches/mwl/950-mwifiex-Print-stringified-name-of-command-in-error-l.patch b/package/kernel/mac80211/patches/mwl/950-mwifiex-Print-stringified-name-of-command-in-error-l.patch -new file mode 100644 -index 0000000000..98ed9e60e9 ---- /dev/null -+++ b/package/kernel/mac80211/patches/mwl/950-mwifiex-Print-stringified-name-of-command-in-error-l.patch -@@ -0,0 +1,189 @@ -+From f7252b1b5755150535af226e806594bbefd45e0f Mon Sep 17 00:00:00 2001 -+From: =?UTF-8?q?Pali=20Roh=C3=A1r?= -+Date: Sun, 26 Sep 2021 14:39:44 +0200 -+Subject: [PATCH] mwifiex: Print stringified name of command in error log -+MIME-Version: 1.0 -+Content-Type: text/plain; charset=UTF-8 -+Content-Transfer-Encoding: 8bit -+ -+Failed hex command number in error log is hard to understand. -+So add also more human readable stringified command name into error log. -+ -+Signed-off-by: Pali Rohár -+--- -+ drivers/net/wireless/marvell/mwifiex/cmdevt.c | 96 +++++++++++++++++-- -+ drivers/net/wireless/marvell/mwifiex/main.h | 2 + -+ .../wireless/marvell/mwifiex/sta_cmdresp.c | 5 +- -+ .../net/wireless/marvell/mwifiex/uap_cmd.c | 3 +- -+ 4 files changed, 95 insertions(+), 11 deletions(-) -+ -+--- a/drivers/net/wireless/marvell/mwifiex/cmdevt.c -++++ b/drivers/net/wireless/marvell/mwifiex/cmdevt.c -+@@ -16,6 +16,85 @@ -+ -+ static void mwifiex_cancel_pending_ioctl(struct mwifiex_adapter *adapter); -+ -++const char * -++mwifiex_cmd_to_str(u16 command) -++{ -++ switch (command) { -++ case HostCmd_CMD_GET_HW_SPEC: return "GET_HW_SPEC"; -++ case HostCmd_CMD_802_11_SCAN: return "SCAN"; -++ case HostCmd_CMD_802_11_GET_LOG: return "GET_LOG"; -++ case HostCmd_CMD_MAC_MULTICAST_ADR: return "MAC_MULTICAST_ADR"; -++ case HostCmd_CMD_802_11_EEPROM_ACCESS: return "EEPROM_ACCESS"; -++ case HostCmd_CMD_802_11_ASSOCIATE: return "ASSOCIATE"; -++ case HostCmd_CMD_802_11_SNMP_MIB: return "SNMP_MIB"; -++ case HostCmd_CMD_MAC_REG_ACCESS: return "MAC_REG_ACCESS"; -++ case HostCmd_CMD_BBP_REG_ACCESS: return "BBP_REG_ACCESS"; -++ case HostCmd_CMD_RF_REG_ACCESS: return "RF_REG_ACCESS"; -++ case HostCmd_CMD_PMIC_REG_ACCESS: return "PMIC_REG_ACCESS"; -++ case HostCmd_CMD_RF_TX_PWR: return "RF_TX_PWR"; -++ case HostCmd_CMD_RF_ANTENNA: return "RF_ANTENNA"; -++ case HostCmd_CMD_802_11_DEAUTHENTICATE: return "DEAUTHENTICATE"; -++ case HostCmd_CMD_MAC_CONTROL: return "MAC_CONTROL"; -++ case HostCmd_CMD_802_11_AD_HOC_START: return "AD_HOC_START"; -++ case HostCmd_CMD_802_11_AD_HOC_JOIN: return "AD_HOC_JOIN"; -++ case HostCmd_CMD_802_11_AD_HOC_STOP: return "AD_HOC_STOP"; -++ case HostCmd_CMD_802_11_MAC_ADDRESS: return "MAC_ADDRESS"; -++ case HostCmd_CMD_802_11D_DOMAIN_INFO: return "DOMAIN_INFO"; -++ case HostCmd_CMD_802_11_KEY_MATERIAL: return "KEY_MATERIAL"; -++ case HostCmd_CMD_802_11_BG_SCAN_CONFIG: return "BG_SCAN_CONFIG"; -++ case HostCmd_CMD_802_11_BG_SCAN_QUERY: return "BG_SCAN_QUERY"; -++ case HostCmd_CMD_WMM_GET_STATUS: return "WMM_GET_STATUS"; -++ case HostCmd_CMD_802_11_SUBSCRIBE_EVENT: return "SUBSCRIBE_EVENT"; -++ case HostCmd_CMD_802_11_TX_RATE_QUERY: return "TX_RATE_QUERY"; -++ case HostCmd_CMD_802_11_IBSS_COALESCING_STATUS: return "IBSS_COALESCING_STATUS"; -++ case HostCmd_CMD_MEM_ACCESS: return "MEM_ACCESS"; -++ case HostCmd_CMD_CFG_DATA: return "CFG_DATA"; -++ case HostCmd_CMD_VERSION_EXT: return "VERSION_EXT"; -++ case HostCmd_CMD_MEF_CFG: return "MEF_CFG"; -++ case HostCmd_CMD_RSSI_INFO: return "RSSI_INFO"; -++ case HostCmd_CMD_FUNC_INIT: return "FUNC_INIT"; -++ case HostCmd_CMD_FUNC_SHUTDOWN: return "FUNC_SHUTDOWN"; -++ case HOST_CMD_APCMD_SYS_RESET: return "SYS_RESET"; -++ case HostCmd_CMD_UAP_SYS_CONFIG: return "UAP_SYS_CONFIG"; -++ case HostCmd_CMD_UAP_BSS_START: return "UAP_BSS_START"; -++ case HostCmd_CMD_UAP_BSS_STOP: return "UAP_BSS_STOP"; -++ case HOST_CMD_APCMD_STA_LIST: return "STA_LIST"; -++ case HostCmd_CMD_UAP_STA_DEAUTH: return "UAP_STA_DEAUTH"; -++ case HostCmd_CMD_11N_CFG: return "11N_CFG"; -++ case HostCmd_CMD_11N_ADDBA_REQ: return "ADDBA_REQ"; -++ case HostCmd_CMD_11N_ADDBA_RSP: return "ADDBA_RSP"; -++ case HostCmd_CMD_11N_DELBA: return "DELBA"; -++ case HostCmd_CMD_RECONFIGURE_TX_BUFF: return "RECONFIGURE_TX_BUFF"; -++ case HostCmd_CMD_CHAN_REPORT_REQUEST: return "CHAN_REPORT_REQUEST"; -++ case HostCmd_CMD_AMSDU_AGGR_CTRL: return "AMSDU_AGGR_CTRL"; -++ case HostCmd_CMD_TXPWR_CFG: return "TXPWR_CFG"; -++ case HostCmd_CMD_TX_RATE_CFG: return "TX_RATE_CFG"; -++ case HostCmd_CMD_ROBUST_COEX: return "ROBUST_COEX"; -++ case HostCmd_CMD_802_11_PS_MODE_ENH: return "PS_MODE_ENH"; -++ case HostCmd_CMD_802_11_HS_CFG_ENH: return "HS_CFG_ENH"; -++ case HostCmd_CMD_P2P_MODE_CFG: return "P2P_MODE_CFG"; -++ case HostCmd_CMD_CAU_REG_ACCESS: return "CAU_REG_ACCESS"; -++ case HostCmd_CMD_SET_BSS_MODE: return "SET_BSS_MODE"; -++ case HostCmd_CMD_PCIE_DESC_DETAILS: return "PCIE_DESC_DETAILS"; -++ case HostCmd_CMD_802_11_SCAN_EXT: return "SCAN_EXT"; -++ case HostCmd_CMD_COALESCE_CFG: return "COALESCE_CFG"; -++ case HostCmd_CMD_MGMT_FRAME_REG: return "MGMT_FRAME_REG"; -++ case HostCmd_CMD_REMAIN_ON_CHAN: return "REMAIN_ON_CHAN"; -++ case HostCmd_CMD_GTK_REKEY_OFFLOAD_CFG: return "GTK_REKEY_OFFLOAD_CFG"; -++ case HostCmd_CMD_11AC_CFG: return "11AC_CFG"; -++ case HostCmd_CMD_HS_WAKEUP_REASON: return "HS_WAKEUP_REASON"; -++ case HostCmd_CMD_TDLS_CONFIG: return "TDLS_CONFIG"; -++ case HostCmd_CMD_MC_POLICY: return "MC_POLICY"; -++ case HostCmd_CMD_TDLS_OPER: return "TDLS_OPER"; -++ case HostCmd_CMD_FW_DUMP_EVENT: return "FW_DUMP_EVENT"; -++ case HostCmd_CMD_SDIO_SP_RX_AGGR_CFG: return "SDIO_SP_RX_AGGR_CFG"; -++ case HostCmd_CMD_STA_CONFIGURE: return "STA_CONFIGURE"; -++ case HostCmd_CMD_CHAN_REGION_CFG: return "CHAN_REGION_CFG"; -++ case HostCmd_CMD_PACKET_AGGR_CTRL: return "PACKET_AGGR_CTRL"; -++ default: return "UNKNOWN"; -++ } -++} -++ -+ /* -+ * This function initializes a command node. -+ * -+@@ -193,8 +272,8 @@ static int mwifiex_dnld_cmd_to_fw(struct -+ cmd_code != HostCmd_CMD_FUNC_SHUTDOWN && -+ cmd_code != HostCmd_CMD_FUNC_INIT) { -+ mwifiex_dbg(adapter, ERROR, -+- "DNLD_CMD: FW in reset state, ignore cmd %#x\n", -+- cmd_code); -++ "DNLD_CMD: FW in reset state, ignore cmd %s (%#x)\n", -++ mwifiex_cmd_to_str(cmd_code), cmd_code); -+ mwifiex_recycle_cmd_node(adapter, cmd_node); -+ queue_work(adapter->workqueue, &adapter->main_work); -+ return -1; -+@@ -653,8 +732,8 @@ int mwifiex_send_cmd(struct mwifiex_priv -+ /* Return error, since the command preparation failed */ -+ if (ret) { -+ mwifiex_dbg(adapter, ERROR, -+- "PREP_CMD: cmd %#x preparation failed\n", -+- cmd_no); -++ "PREP_CMD: cmd %s (%#x) preparation failed\n", -++ mwifiex_cmd_to_str(cmd_no), cmd_no); -+ mwifiex_insert_cmd_to_free_q(adapter, cmd_node); -+ return -1; -+ } -+@@ -902,8 +981,9 @@ int mwifiex_process_cmdresp(struct mwifi -+ if (adapter->hw_status == MWIFIEX_HW_STATUS_INITIALIZING) { -+ if (ret) { -+ mwifiex_dbg(adapter, ERROR, -+- "%s: cmd %#x failed during\t" -+- "initialization\n", __func__, cmdresp_no); -++ "%s: cmd %s (%#x) failed during\t" -++ "initialization\n", __func__, -++ mwifiex_cmd_to_str(cmdresp_no), cmdresp_no); -+ mwifiex_init_fw_complete(adapter); -+ return -1; -+ } else if (adapter->last_init_cmd == cmdresp_no) -+@@ -1273,8 +1353,8 @@ mwifiex_process_sleep_confirm_resp(struc -+ -+ if (command != HostCmd_CMD_802_11_PS_MODE_ENH) { -+ mwifiex_dbg(adapter, ERROR, -+- "%s: rcvd unexpected resp for cmd %#x, result = %x\n", -+- __func__, command, result); -++ "%s: rcvd unexpected resp for cmd %s (%#x), result = %x\n", -++ __func__, mwifiex_cmd_to_str(command), command, result); -+ return; -+ } -+ -+--- a/drivers/net/wireless/marvell/mwifiex/main.h -++++ b/drivers/net/wireless/marvell/mwifiex/main.h -+@@ -1099,6 +1099,8 @@ void mwifiex_cancel_all_pending_cmd(stru -+ void mwifiex_cancel_pending_scan_cmd(struct mwifiex_adapter *adapter); -+ void mwifiex_cancel_scan(struct mwifiex_adapter *adapter); -+ -++const char *mwifiex_cmd_to_str(u16 command); -++ -+ void mwifiex_recycle_cmd_node(struct mwifiex_adapter *adapter, -+ struct cmd_ctrl_node *cmd_node); -+ -+--- a/drivers/net/wireless/marvell/mwifiex/sta_cmdresp.c -++++ b/drivers/net/wireless/marvell/mwifiex/sta_cmdresp.c -+@@ -36,8 +36,9 @@ mwifiex_process_cmdresp_error(struct mwi -+ struct host_cmd_ds_802_11_ps_mode_enh *pm; -+ -+ mwifiex_dbg(adapter, ERROR, -+- "CMD_RESP: cmd %#x error, result=%#x\n", -+- resp->command, resp->result); -++ "CMD_RESP: cmd %s (%#x) error, result=%#x\n", -++ mwifiex_cmd_to_str(le16_to_cpu(resp->command)), -++ le16_to_cpu(resp->command), le16_to_cpu(resp->result)); -+ -+ if (adapter->curr_cmd->wait_q_enabled) -+ adapter->cmd_wait_q.status = -1; -+--- a/drivers/net/wireless/marvell/mwifiex/uap_cmd.c -++++ b/drivers/net/wireless/marvell/mwifiex/uap_cmd.c -+@@ -794,7 +794,8 @@ int mwifiex_uap_prepare_cmd(struct mwifi -+ break; -+ default: -+ mwifiex_dbg(priv->adapter, ERROR, -+- "PREP_CMD: unknown cmd %#x\n", cmd_no); -++ "PREP_CMD: unknown cmd (%s) %#x\n", -++ mwifiex_cmd_to_str(cmd_no), cmd_no); -+ return -1; -+ } -+ -diff --git a/package/kernel/mac80211/patches/rt2x00/100-rt2x00_options.patch b/package/kernel/mac80211/patches/rt2x00/100-rt2x00_options.patch -new file mode 100644 -index 0000000000..295904c64e ---- /dev/null -+++ b/package/kernel/mac80211/patches/rt2x00/100-rt2x00_options.patch -@@ -0,0 +1,47 @@ -+--- a/drivers/net/wireless/ralink/rt2x00/Kconfig -++++ b/drivers/net/wireless/ralink/rt2x00/Kconfig -+@@ -226,36 +226,37 @@ config RT2800SOC -+ -+ -+ config RT2800_LIB -+- tristate -++ tristate "RT2800 USB/PCI support" -+ depends on m -+ -+ config RT2800_LIB_MMIO -+- tristate -++ tristate "RT2800 MMIO support" -+ depends on m -+ select RT2X00_LIB_MMIO -+ select RT2800_LIB -+ -+ config RT2X00_LIB_MMIO -+- tristate -++ tristate "RT2x00 MMIO support" -+ depends on m -+ -+ config RT2X00_LIB_PCI -+- tristate -++ tristate "RT2x00 PCI support" -+ depends on m -+ select RT2X00_LIB -+ -+ config RT2X00_LIB_SOC -+- tristate -++ tristate "RT2x00 SoC support" -++ depends on SOC_RT288X || SOC_RT305X || SOC_MT7620 -+ depends on m -+ select RT2X00_LIB -+ -+ config RT2X00_LIB_USB -+- tristate -++ tristate "RT2x00 USB support" -+ depends on m -+ select RT2X00_LIB -+ -+ config RT2X00_LIB -+- tristate -++ tristate "RT2x00 support" -+ depends on m -+ -+ config RT2X00_LIB_FIRMWARE -diff --git a/package/kernel/mac80211/patches/rt2x00/501-rt2x00-allow-to-build-rt2800soc-module-for-RT3883.patch b/package/kernel/mac80211/patches/rt2x00/501-rt2x00-allow-to-build-rt2800soc-module-for-RT3883.patch -new file mode 100644 -index 0000000000..b4106b0197 ---- /dev/null -+++ b/package/kernel/mac80211/patches/rt2x00/501-rt2x00-allow-to-build-rt2800soc-module-for-RT3883.patch -@@ -0,0 +1,30 @@ -+From 91094ed065f7794886b4a5490fd6de942f036bb4 Mon Sep 17 00:00:00 2001 -+From: Gabor Juhos -+Date: Sun, 24 Mar 2013 19:26:26 +0100 -+Subject: [PATCH] rt2x00: allow to build rt2800soc module for RT3883 -+ -+Signed-off-by: Gabor Juhos -+--- -+ drivers/net/wireless/ralink/rt2x00/Kconfig | 2 +- -+ 1 file changed, 1 insertion(+), 1 deletion(-) -+ -+--- a/drivers/net/wireless/ralink/rt2x00/Kconfig -++++ b/drivers/net/wireless/ralink/rt2x00/Kconfig -+@@ -211,7 +211,7 @@ endif -+ config RT2800SOC -+ tristate "Ralink WiSoC support" -+ depends on m -+- depends on SOC_RT288X || SOC_RT305X || SOC_MT7620 -++ depends on SOC_RT288X || SOC_RT305X || SOC_RT3883 || SOC_MT7620 -+ select RT2X00_LIB_SOC -+ select RT2X00_LIB_MMIO -+ select RT2X00_LIB_CRYPTO -+@@ -246,7 +246,7 @@ config RT2X00_LIB_PCI -+ -+ config RT2X00_LIB_SOC -+ tristate "RT2x00 SoC support" -+- depends on SOC_RT288X || SOC_RT305X || SOC_MT7620 -++ depends on SOC_RT288X || SOC_RT305X || SOC_RT3883 || SOC_MT7620 -+ depends on m -+ select RT2X00_LIB -+ -diff --git a/package/kernel/mac80211/patches/rt2x00/601-rt2x00-introduce-rt2x00_platform_h.patch b/package/kernel/mac80211/patches/rt2x00/601-rt2x00-introduce-rt2x00_platform_h.patch -new file mode 100644 -index 0000000000..1e6211a470 ---- /dev/null -+++ b/package/kernel/mac80211/patches/rt2x00/601-rt2x00-introduce-rt2x00_platform_h.patch -@@ -0,0 +1,32 @@ -+--- /dev/null -++++ b/include/linux/rt2x00_platform.h -+@@ -0,0 +1,19 @@ -++/* -++ * Platform data definition for the rt2x00 driver -++ * -++ * Copyright (C) 2011 Gabor Juhos -++ * -++ * This program is free software; you can redistribute it and/or modify it -++ * under the terms of the GNU General Public License version 2 as published -++ * by the Free Software Foundation. -++ * -++ */ -++ -++#ifndef _RT2X00_PLATFORM_H -++#define _RT2X00_PLATFORM_H -++ -++struct rt2x00_platform_data { -++ char *eeprom_file_name; -++}; -++ -++#endif /* _RT2X00_PLATFORM_H */ -+--- a/drivers/net/wireless/ralink/rt2x00/rt2x00.h -++++ b/drivers/net/wireless/ralink/rt2x00/rt2x00.h -+@@ -28,6 +28,7 @@ -+ #include -+ #include -+ #include -++#include -+ -+ #include -+ -diff --git a/package/kernel/mac80211/patches/rt2x00/602-rt2x00-introduce-rt2x00eeprom.patch b/package/kernel/mac80211/patches/rt2x00/602-rt2x00-introduce-rt2x00eeprom.patch -new file mode 100644 -index 0000000000..ab0fa3670d ---- /dev/null -+++ b/package/kernel/mac80211/patches/rt2x00/602-rt2x00-introduce-rt2x00eeprom.patch -@@ -0,0 +1,296 @@ -+--- a/local-symbols -++++ b/local-symbols -+@@ -347,6 +347,7 @@ RT2X00_LIB_FIRMWARE= -+ RT2X00_LIB_CRYPTO= -+ RT2X00_LIB_LEDS= -+ RT2X00_LIB_DEBUGFS= -++RT2X00_LIB_EEPROM= -+ RT2X00_DEBUG= -+ WLAN_VENDOR_REALTEK= -+ RTL8180= -+--- a/drivers/net/wireless/ralink/rt2x00/Kconfig -++++ b/drivers/net/wireless/ralink/rt2x00/Kconfig -+@@ -70,6 +70,7 @@ config RT2800PCI -+ select RT2X00_LIB_MMIO -+ select RT2X00_LIB_PCI -+ select RT2X00_LIB_FIRMWARE -++ select RT2X00_LIB_EEPROM -+ select RT2X00_LIB_CRYPTO -+ depends on CRC_CCITT -+ depends on EEPROM_93CX6 -+@@ -216,6 +217,7 @@ config RT2800SOC -+ select RT2X00_LIB_MMIO -+ select RT2X00_LIB_CRYPTO -+ select RT2X00_LIB_FIRMWARE -++ select RT2X00_LIB_EEPROM -+ select RT2800_LIB -+ select RT2800_LIB_MMIO -+ help -+@@ -266,6 +268,9 @@ config RT2X00_LIB_FIRMWARE -+ config RT2X00_LIB_CRYPTO -+ bool -+ -++config RT2X00_LIB_EEPROM -++ bool -++ -+ config RT2X00_LIB_LEDS -+ bool -+ default y if (RT2X00_LIB=y && LEDS_CLASS=y) || (RT2X00_LIB=m && LEDS_CLASS!=n) -+--- a/drivers/net/wireless/ralink/rt2x00/Makefile -++++ b/drivers/net/wireless/ralink/rt2x00/Makefile -+@@ -8,6 +8,7 @@ rt2x00lib-$(CPTCFG_RT2X00_LIB_DEBUGFS) + -+ rt2x00lib-$(CPTCFG_RT2X00_LIB_CRYPTO) += rt2x00crypto.o -+ rt2x00lib-$(CPTCFG_RT2X00_LIB_FIRMWARE) += rt2x00firmware.o -+ rt2x00lib-$(CPTCFG_RT2X00_LIB_LEDS) += rt2x00leds.o -++rt2x00lib-$(CPTCFG_RT2X00_LIB_EEPROM) += rt2x00eeprom.o -+ -+ obj-$(CPTCFG_RT2X00_LIB) += rt2x00lib.o -+ obj-$(CPTCFG_RT2X00_LIB_MMIO) += rt2x00mmio.o -+--- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.h -++++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.h -+@@ -47,6 +47,8 @@ struct rt2800_drv_data { -+ struct ieee80211_sta *wcid_to_sta[STA_IDS_SIZE]; -+ }; -+ -++#include "rt2800.h" -++ -+ struct rt2800_ops { -+ u32 (*register_read)(struct rt2x00_dev *rt2x00dev, -+ const unsigned int offset); -+@@ -145,6 +147,15 @@ static inline int rt2800_read_eeprom(str -+ { -+ const struct rt2800_ops *rt2800ops = rt2x00dev->ops->drv; -+ -++ if (rt2x00dev->eeprom_file) { -++ memcpy(rt2x00dev->eeprom, rt2x00dev->eeprom_file->data, -++ EEPROM_SIZE); -++ return 0; -++ } -++ -++ if (!rt2800ops->read_eeprom) -++ return -EINVAL; -++ -+ return rt2800ops->read_eeprom(rt2x00dev); -+ } -+ -+--- a/drivers/net/wireless/ralink/rt2x00/rt2800soc.c -++++ b/drivers/net/wireless/ralink/rt2x00/rt2800soc.c -+@@ -90,19 +90,6 @@ static int rt2800soc_set_device_state(st -+ return retval; -+ } -+ -+-static int rt2800soc_read_eeprom(struct rt2x00_dev *rt2x00dev) -+-{ -+- void __iomem *base_addr = ioremap(0x1F040000, EEPROM_SIZE); -+- -+- if (!base_addr) -+- return -ENOMEM; -+- -+- memcpy_fromio(rt2x00dev->eeprom, base_addr, EEPROM_SIZE); -+- -+- iounmap(base_addr); -+- return 0; -+-} -+- -+ /* Firmware functions */ -+ static char *rt2800soc_get_firmware_name(struct rt2x00_dev *rt2x00dev) -+ { -+@@ -168,7 +155,6 @@ static const struct rt2800_ops rt2800soc -+ .register_multiread = rt2x00mmio_register_multiread, -+ .register_multiwrite = rt2x00mmio_register_multiwrite, -+ .regbusy_read = rt2x00mmio_regbusy_read, -+- .read_eeprom = rt2800soc_read_eeprom, -+ .hwcrypt_disabled = rt2800soc_hwcrypt_disabled, -+ .drv_write_firmware = rt2800soc_write_firmware, -+ .drv_init_registers = rt2800mmio_init_registers, -+--- a/drivers/net/wireless/ralink/rt2x00/rt2x00.h -++++ b/drivers/net/wireless/ralink/rt2x00/rt2x00.h -+@@ -703,6 +703,7 @@ enum rt2x00_capability_flags { -+ REQUIRE_HT_TX_DESC, -+ REQUIRE_PS_AUTOWAKE, -+ REQUIRE_DELAYED_RFKILL, -++ REQUIRE_EEPROM_FILE, -+ -+ /* -+ * Capabilities -+@@ -980,6 +981,11 @@ struct rt2x00_dev { -+ const struct firmware *fw; -+ -+ /* -++ * EEPROM image. -++ */ -++ const struct firmware *eeprom_file; -++ -++ /* -+ * FIFO for storing tx status reports between isr and tasklet. -+ */ -+ DECLARE_KFIFO_PTR(txstatus_fifo, u32); -+--- a/drivers/net/wireless/ralink/rt2x00/rt2x00dev.c -++++ b/drivers/net/wireless/ralink/rt2x00/rt2x00dev.c -+@@ -1419,6 +1419,10 @@ int rt2x00lib_probe_dev(struct rt2x00_de -+ INIT_DELAYED_WORK(&rt2x00dev->autowakeup_work, rt2x00lib_autowakeup); -+ INIT_WORK(&rt2x00dev->sleep_work, rt2x00lib_sleep); -+ -++ retval = rt2x00lib_load_eeprom_file(rt2x00dev); -++ if (retval) -++ goto exit; -++ -+ /* -+ * Let the driver probe the device to detect the capabilities. -+ */ -+@@ -1559,6 +1563,11 @@ void rt2x00lib_remove_dev(struct rt2x00_ -+ * Free the driver data. -+ */ -+ kfree(rt2x00dev->drv_data); -++ -++ /* -++ * Free EEPROM image. -++ */ -++ rt2x00lib_free_eeprom_file(rt2x00dev); -+ } -+ EXPORT_SYMBOL_GPL(rt2x00lib_remove_dev); -+ -+--- /dev/null -++++ b/drivers/net/wireless/ralink/rt2x00/rt2x00eeprom.c -+@@ -0,0 +1,106 @@ -++/* -++ Copyright (C) 2004 - 2009 Ivo van Doorn -++ Copyright (C) 2004 - 2009 Gertjan van Wingerde -++ -++ -++ 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. -++ -++ This program is distributed in the hope that it will be useful, -++ but WITHOUT ANY WARRANTY; without even the implied warranty of -++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -++ GNU General Public License for more details. -++ -++ You should have received a copy of the GNU General Public License -++ along with this program; if not, write to the -++ Free Software Foundation, Inc., -++ 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -++ */ -++ -++/* -++ Module: rt2x00lib -++ Abstract: rt2x00 eeprom file loading routines. -++ */ -++ -++#include -++#include -++ -++#include "rt2x00.h" -++#include "rt2x00lib.h" -++ -++static const char * -++rt2x00lib_get_eeprom_file_name(struct rt2x00_dev *rt2x00dev) -++{ -++ struct rt2x00_platform_data *pdata = rt2x00dev->dev->platform_data; -++ -++ if (pdata && pdata->eeprom_file_name) -++ return pdata->eeprom_file_name; -++ -++ return NULL; -++} -++ -++static int rt2x00lib_request_eeprom_file(struct rt2x00_dev *rt2x00dev) -++{ -++ const struct firmware *ee; -++ const char *ee_name; -++ int retval; -++ -++ ee_name = rt2x00lib_get_eeprom_file_name(rt2x00dev); -++ if (!ee_name && test_bit(REQUIRE_EEPROM_FILE, &rt2x00dev->cap_flags)) { -++ rt2x00_err(rt2x00dev, "Required EEPROM name is missing."); -++ return -EINVAL; -++ } -++ -++ if (!ee_name) -++ return 0; -++ -++ rt2x00_info(rt2x00dev, "Loading EEPROM data from '%s'.\n", ee_name); -++ -++ retval = request_firmware(&ee, ee_name, rt2x00dev->dev); -++ if (retval) { -++ rt2x00_err(rt2x00dev, "Failed to request EEPROM.\n"); -++ return retval; -++ } -++ -++ if (!ee || !ee->size || !ee->data) { -++ rt2x00_err(rt2x00dev, "Failed to read EEPROM file.\n"); -++ retval = -ENOENT; -++ goto err_exit; -++ } -++ -++ if (ee->size != rt2x00dev->ops->eeprom_size) { -++ rt2x00_err(rt2x00dev, -++ "EEPROM file size is invalid, it should be %d bytes\n", -++ rt2x00dev->ops->eeprom_size); -++ retval = -EINVAL; -++ goto err_release_ee; -++ } -++ -++ rt2x00dev->eeprom_file = ee; -++ return 0; -++ -++err_release_ee: -++ release_firmware(ee); -++err_exit: -++ return retval; -++} -++ -++int rt2x00lib_load_eeprom_file(struct rt2x00_dev *rt2x00dev) -++{ -++ int retval; -++ -++ retval = rt2x00lib_request_eeprom_file(rt2x00dev); -++ if (retval) -++ return retval; -++ -++ return 0; -++} -++ -++void rt2x00lib_free_eeprom_file(struct rt2x00_dev *rt2x00dev) -++{ -++ if (rt2x00dev->eeprom_file && rt2x00dev->eeprom_file->size) -++ release_firmware(rt2x00dev->eeprom_file); -++ rt2x00dev->eeprom_file = NULL; -++} -+--- a/drivers/net/wireless/ralink/rt2x00/rt2x00lib.h -++++ b/drivers/net/wireless/ralink/rt2x00/rt2x00lib.h -+@@ -286,6 +286,22 @@ static inline void rt2x00lib_free_firmwa -+ #endif /* CPTCFG_RT2X00_LIB_FIRMWARE */ -+ -+ /* -++ * EEPROM file handlers. -++ */ -++#ifdef CPTCFG_RT2X00_LIB_EEPROM -++int rt2x00lib_load_eeprom_file(struct rt2x00_dev *rt2x00dev); -++void rt2x00lib_free_eeprom_file(struct rt2x00_dev *rt2x00dev); -++#else -++static inline int rt2x00lib_load_eeprom_file(struct rt2x00_dev *rt2x00dev) -++{ -++ return 0; -++} -++static inline void rt2x00lib_free_eeprom_file(struct rt2x00_dev *rt2x00dev) -++{ -++} -++#endif /* CPTCFG_RT2X00_LIB_EEPROM */ -++ -++/* -+ * Debugfs handlers. -+ */ -+ #ifdef CPTCFG_RT2X00_LIB_DEBUGFS -+--- a/drivers/net/wireless/ralink/rt2x00/rt2x00soc.c -++++ b/drivers/net/wireless/ralink/rt2x00/rt2x00soc.c -+@@ -86,6 +86,7 @@ int rt2x00soc_probe(struct platform_devi -+ if (IS_ERR(rt2x00dev->clk)) -+ rt2x00dev->clk = NULL; -+ -++ set_bit(REQUIRE_EEPROM_FILE, &rt2x00dev->cap_flags); -+ rt2x00_set_chip_intf(rt2x00dev, RT2X00_CHIP_INTF_SOC); -+ -+ retval = rt2x00soc_alloc_reg(rt2x00dev); -diff --git a/package/kernel/mac80211/patches/rt2x00/603-rt2x00-of_load_eeprom_filename.patch b/package/kernel/mac80211/patches/rt2x00/603-rt2x00-of_load_eeprom_filename.patch -new file mode 100644 -index 0000000000..431e090237 ---- /dev/null -+++ b/package/kernel/mac80211/patches/rt2x00/603-rt2x00-of_load_eeprom_filename.patch -@@ -0,0 +1,31 @@ -+--- a/drivers/net/wireless/ralink/rt2x00/rt2x00eeprom.c -++++ b/drivers/net/wireless/ralink/rt2x00/rt2x00eeprom.c -+@@ -26,6 +26,7 @@ -+ -+ #include -+ #include -++#include -+ -+ #include "rt2x00.h" -+ #include "rt2x00lib.h" -+@@ -34,10 +35,20 @@ static const char * -+ rt2x00lib_get_eeprom_file_name(struct rt2x00_dev *rt2x00dev) -+ { -+ struct rt2x00_platform_data *pdata = rt2x00dev->dev->platform_data; -++#ifdef CONFIG_OF -++ struct device_node *np; -++ const char *eep; -++#endif -+ -+ if (pdata && pdata->eeprom_file_name) -+ return pdata->eeprom_file_name; -+ -++#ifdef CONFIG_OF -++ np = rt2x00dev->dev->of_node; -++ if (np && of_property_read_string(np, "ralink,eeprom", &eep) == 0) -++ return eep; -++#endif -++ -+ return NULL; -+ } -+ -diff --git a/package/kernel/mac80211/patches/rt2x00/604-rt2x00-load-eeprom-on-SoC-from-a-mtd-device-defines-.patch b/package/kernel/mac80211/patches/rt2x00/604-rt2x00-load-eeprom-on-SoC-from-a-mtd-device-defines-.patch -new file mode 100644 -index 0000000000..7338eb15b2 ---- /dev/null -+++ b/package/kernel/mac80211/patches/rt2x00/604-rt2x00-load-eeprom-on-SoC-from-a-mtd-device-defines-.patch -@@ -0,0 +1,113 @@ -+From 339fe73f340161a624cc08e738d2244814852c3e Mon Sep 17 00:00:00 2001 -+From: John Crispin -+Date: Sun, 17 Mar 2013 00:55:04 +0100 -+Subject: [PATCH] rt2x00: load eeprom on SoC from a mtd device defines inside -+ OF -+ -+Signed-off-by: John Crispin -+--- -+ drivers/net/wireless/ralink/rt2x00/Kconfig | 1 + -+ drivers/net/wireless/ralink/rt2x00/rt2x00eeprom.c | 65 +++++++++++++++++++++++ -+ 2 files changed, 66 insertions(+) -+ -+--- a/drivers/net/wireless/ralink/rt2x00/Kconfig -++++ b/drivers/net/wireless/ralink/rt2x00/Kconfig -+@@ -220,6 +220,7 @@ config RT2800SOC -+ select RT2X00_LIB_EEPROM -+ select RT2800_LIB -+ select RT2800_LIB_MMIO -++ select MTD if SOC_RT288X || SOC_RT305X -+ help -+ This adds support for Ralink WiSoC devices. -+ Supported chips: RT2880, RT3050, RT3052, RT3350, RT3352. -+--- a/drivers/net/wireless/ralink/rt2x00/rt2x00eeprom.c -++++ b/drivers/net/wireless/ralink/rt2x00/rt2x00eeprom.c -+@@ -26,11 +26,76 @@ -+ -+ #include -+ #include -++#if IS_ENABLED(CONFIG_MTD) -++#include -++#include -++#endif -+ #include -+ -+ #include "rt2x00.h" -+ #include "rt2x00lib.h" -+ -++#if IS_ENABLED(CONFIG_MTD) -++static int rt2800lib_read_eeprom_mtd(struct rt2x00_dev *rt2x00dev) -++{ -++ int ret = -EINVAL; -++#ifdef CONFIG_OF -++ static struct firmware mtd_fw; -++ struct device_node *np = rt2x00dev->dev->of_node, *mtd_np = NULL; -++ size_t retlen, len = rt2x00dev->ops->eeprom_size; -++ int i, size, offset = 0; -++ struct mtd_info *mtd; -++ const char *part; -++ const __be32 *list; -++ phandle phandle; -++ -++ list = of_get_property(np, "ralink,mtd-eeprom", &size); -++ if (!list) -++ return -ENOENT; -++ -++ phandle = be32_to_cpup(list++); -++ if (phandle) -++ mtd_np = of_find_node_by_phandle(phandle); -++ if (!mtd_np) { -++ dev_err(rt2x00dev->dev, "failed to load mtd phandle\n"); -++ return -EINVAL; -++ } -++ -++ part = of_get_property(mtd_np, "label", NULL); -++ if (!part) -++ part = mtd_np->name; -++ -++ mtd = get_mtd_device_nm(part); -++ if (IS_ERR(mtd)) { -++ dev_err(rt2x00dev->dev, "failed to get mtd device \"%s\"\n", part); -++ return PTR_ERR(mtd); -++ } -++ -++ if (size > sizeof(*list)) -++ offset = be32_to_cpup(list); -++ -++ ret = mtd_read(mtd, offset, len, &retlen, (u_char *) rt2x00dev->eeprom); -++ put_mtd_device(mtd); -++ -++ if ((retlen != rt2x00dev->ops->eeprom_size) || ret) { -++ dev_err(rt2x00dev->dev, "failed to load eeprom from device \"%s\"\n", part); -++ return ret; -++ } -++ -++ if (of_find_property(np, "ralink,mtd-eeprom-swap", NULL)) -++ for (i = 0; i < len/sizeof(u16); i++) -++ rt2x00dev->eeprom[i] = swab16(rt2x00dev->eeprom[i]); -++ -++ rt2x00dev->eeprom_file = &mtd_fw; -++ mtd_fw.data = (const u8 *) rt2x00dev->eeprom; -++ -++ dev_info(rt2x00dev->dev, "loaded eeprom from mtd device \"%s\"\n", part); -++#endif -++ -++ return ret; -++} -++#endif -++ -+ static const char * -+ rt2x00lib_get_eeprom_file_name(struct rt2x00_dev *rt2x00dev) -+ { -+@@ -58,6 +123,11 @@ static int rt2x00lib_request_eeprom_file -+ const char *ee_name; -+ int retval; -+ -++#if IS_ENABLED(CONFIG_MTD) -++ if (!rt2800lib_read_eeprom_mtd(rt2x00dev)) -++ return 0; -++#endif -++ -+ ee_name = rt2x00lib_get_eeprom_file_name(rt2x00dev); -+ if (!ee_name && test_bit(REQUIRE_EEPROM_FILE, &rt2x00dev->cap_flags)) { -+ rt2x00_err(rt2x00dev, "Required EEPROM name is missing."); -diff --git a/package/kernel/mac80211/patches/rt2x00/606-rt2x00-allow_disabling_bands_through_platform_data.patch b/package/kernel/mac80211/patches/rt2x00/606-rt2x00-allow_disabling_bands_through_platform_data.patch -new file mode 100644 -index 0000000000..ffee2189d2 ---- /dev/null -+++ b/package/kernel/mac80211/patches/rt2x00/606-rt2x00-allow_disabling_bands_through_platform_data.patch -@@ -0,0 +1,47 @@ -+--- a/include/linux/rt2x00_platform.h -++++ b/include/linux/rt2x00_platform.h -+@@ -14,6 +14,9 @@ -+ -+ struct rt2x00_platform_data { -+ char *eeprom_file_name; -++ -++ int disable_2ghz; -++ int disable_5ghz; -+ }; -+ -+ #endif /* _RT2X00_PLATFORM_H */ -+--- a/drivers/net/wireless/ralink/rt2x00/rt2x00dev.c -++++ b/drivers/net/wireless/ralink/rt2x00/rt2x00dev.c -+@@ -1007,6 +1007,22 @@ static int rt2x00lib_probe_hw_modes(stru -+ unsigned int num_rates; -+ unsigned int i; -+ -++ if (rt2x00dev->dev->platform_data) { -++ struct rt2x00_platform_data *pdata; -++ -++ pdata = rt2x00dev->dev->platform_data; -++ if (pdata->disable_2ghz) -++ spec->supported_bands &= ~SUPPORT_BAND_2GHZ; -++ if (pdata->disable_5ghz) -++ spec->supported_bands &= ~SUPPORT_BAND_5GHZ; -++ } -++ -++ if ((spec->supported_bands & SUPPORT_BAND_BOTH) == 0) { -++ rt2x00_err(rt2x00dev, "No supported bands\n"); -++ return -EINVAL; -++ } -++ -++ -+ num_rates = 0; -+ if (spec->supported_rates & SUPPORT_RATE_CCK) -+ num_rates += 4; -+--- a/drivers/net/wireless/ralink/rt2x00/rt2x00.h -++++ b/drivers/net/wireless/ralink/rt2x00/rt2x00.h -+@@ -408,6 +408,7 @@ struct hw_mode_spec { -+ unsigned int supported_bands; -+ #define SUPPORT_BAND_2GHZ 0x00000001 -+ #define SUPPORT_BAND_5GHZ 0x00000002 -++#define SUPPORT_BAND_BOTH (SUPPORT_BAND_2GHZ | SUPPORT_BAND_5GHZ) -+ -+ unsigned int supported_rates; -+ #define SUPPORT_RATE_CCK 0x00000001 -diff --git a/package/kernel/mac80211/patches/rt2x00/607-rt2x00-add_platform_data_mac_addr.patch b/package/kernel/mac80211/patches/rt2x00/607-rt2x00-add_platform_data_mac_addr.patch -new file mode 100644 -index 0000000000..37553bb80a ---- /dev/null -+++ b/package/kernel/mac80211/patches/rt2x00/607-rt2x00-add_platform_data_mac_addr.patch -@@ -0,0 +1,25 @@ -+--- a/drivers/net/wireless/ralink/rt2x00/rt2x00dev.c -++++ b/drivers/net/wireless/ralink/rt2x00/rt2x00dev.c -+@@ -989,6 +989,12 @@ static void rt2x00lib_rate(struct ieee80 -+ -+ void rt2x00lib_set_mac_address(struct rt2x00_dev *rt2x00dev, u8 *eeprom_mac_addr) -+ { -++ struct rt2x00_platform_data *pdata; -++ -++ pdata = rt2x00dev->dev->platform_data; -++ if (pdata && pdata->mac_address) -++ ether_addr_copy(eeprom_mac_addr, pdata->mac_address); -++ -+ of_get_mac_address(rt2x00dev->dev->of_node, eeprom_mac_addr); -+ -+ if (!is_valid_ether_addr(eeprom_mac_addr)) { -+--- a/include/linux/rt2x00_platform.h -++++ b/include/linux/rt2x00_platform.h -+@@ -14,6 +14,7 @@ -+ -+ struct rt2x00_platform_data { -+ char *eeprom_file_name; -++ const u8 *mac_address; -+ -+ int disable_2ghz; -+ int disable_5ghz; -diff --git a/package/kernel/mac80211/patches/rt2x00/608-rt2x00-allow_disabling_bands_through_dts.patch b/package/kernel/mac80211/patches/rt2x00/608-rt2x00-allow_disabling_bands_through_dts.patch -new file mode 100644 -index 0000000000..6211809c0a ---- /dev/null -+++ b/package/kernel/mac80211/patches/rt2x00/608-rt2x00-allow_disabling_bands_through_dts.patch -@@ -0,0 +1,19 @@ -+--- a/drivers/net/wireless/ralink/rt2x00/rt2x00dev.c -++++ b/drivers/net/wireless/ralink/rt2x00/rt2x00dev.c -+@@ -1012,6 +1012,16 @@ static int rt2x00lib_probe_hw_modes(stru -+ struct ieee80211_rate *rates; -+ unsigned int num_rates; -+ unsigned int i; -++#ifdef CONFIG_OF -++ struct device_node *np = rt2x00dev->dev->of_node; -++ unsigned int enabled; -++ if (!of_property_read_u32(np, "ralink,2ghz", -++ &enabled) && !enabled) -++ spec->supported_bands &= ~SUPPORT_BAND_2GHZ; -++ if (!of_property_read_u32(np, "ralink,5ghz", -++ &enabled) && !enabled) -++ spec->supported_bands &= ~SUPPORT_BAND_5GHZ; -++#endif /* CONFIG_OF */ -+ -+ if (rt2x00dev->dev->platform_data) { -+ struct rt2x00_platform_data *pdata; -diff --git a/package/kernel/mac80211/patches/rt2x00/609-rt2x00-make-wmac-loadable-via-OF-on-rt288x-305x-SoC.patch b/package/kernel/mac80211/patches/rt2x00/609-rt2x00-make-wmac-loadable-via-OF-on-rt288x-305x-SoC.patch -new file mode 100644 -index 0000000000..8964f8bf10 ---- /dev/null -+++ b/package/kernel/mac80211/patches/rt2x00/609-rt2x00-make-wmac-loadable-via-OF-on-rt288x-305x-SoC.patch -@@ -0,0 +1,33 @@ -+From 04dbd87265f6ba4a373b211ba324b437d224fb2d Mon Sep 17 00:00:00 2001 -+From: John Crispin -+Date: Sun, 17 Mar 2013 00:03:31 +0100 -+Subject: [PATCH 21/38] rt2x00: make wmac loadable via OF on rt288x/305x SoC -+ -+This patch ads the match table to allow loading the wmac support from a -+devicetree. -+ -+Signed-off-by: John Crispin -+--- -+ drivers/net/wireless/ralink/rt2x00/rt2800pci.c | 7 +++++++ -+ 1 file changed, 7 insertions(+) -+ -+--- a/drivers/net/wireless/ralink/rt2x00/rt2800soc.c -++++ b/drivers/net/wireless/ralink/rt2x00/rt2800soc.c -+@@ -225,10 +225,17 @@ static int rt2800soc_probe(struct platfo -+ return rt2x00soc_probe(pdev, &rt2800soc_ops); -+ } -+ -++static const struct of_device_id rt2880_wmac_match[] = { -++ { .compatible = "ralink,rt2880-wmac" }, -++ {}, -++}; -++MODULE_DEVICE_TABLE(of, rt2880_wmac_match); -++ -+ static struct platform_driver rt2800soc_driver = { -+ .driver = { -+ .name = "rt2800_wmac", -+ .mod_name = KBUILD_MODNAME, -++ .of_match_table = rt2880_wmac_match, -+ }, -+ .probe = rt2800soc_probe, -+ .remove = rt2x00soc_remove, -diff --git a/package/kernel/mac80211/patches/rt2x00/610-rt2x00-change-led-polarity-from-OF.patch b/package/kernel/mac80211/patches/rt2x00/610-rt2x00-change-led-polarity-from-OF.patch -new file mode 100644 -index 0000000000..acc8a8edb8 ---- /dev/null -+++ b/package/kernel/mac80211/patches/rt2x00/610-rt2x00-change-led-polarity-from-OF.patch -@@ -0,0 +1,40 @@ -+--- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c -++++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c -+@@ -25,6 +25,7 @@ -+ #include -+ #include -+ #include -++#include -+ -+ #include "rt2x00.h" -+ #include "rt2800lib.h" -+@@ -11131,6 +11132,17 @@ static int rt2800_init_eeprom(struct rt2 -+ rt2800_init_led(rt2x00dev, &rt2x00dev->led_assoc, LED_TYPE_ASSOC); -+ rt2800_init_led(rt2x00dev, &rt2x00dev->led_qual, LED_TYPE_QUALITY); -+ -++ { -++ struct device_node *np = rt2x00dev->dev->of_node; -++ unsigned int led_polarity; -++ -++ /* Allow overriding polarity from OF */ -++ if (!of_property_read_u32(np, "ralink,led-polarity", -++ &led_polarity)) -++ rt2x00_set_field16(&eeprom, EEPROM_FREQ_LED_POLARITY, -++ led_polarity); -++ } -++ -+ rt2x00dev->led_mcu_reg = eeprom; -+ #endif /* CPTCFG_RT2X00_LIB_LEDS */ -+ -+--- a/drivers/net/wireless/ralink/rt2x00/rt2x00leds.c -++++ b/drivers/net/wireless/ralink/rt2x00/rt2x00leds.c -+@@ -98,6 +98,9 @@ static int rt2x00leds_register_led(struc -+ led->led_dev.name = name; -+ led->led_dev.brightness = LED_OFF; -+ -++ if (rt2x00_is_soc(rt2x00dev)) -++ led->led_dev.brightness_set(&led->led_dev, LED_OFF); -++ -+ retval = led_classdev_register(device, &led->led_dev); -+ if (retval) { -+ rt2x00_err(rt2x00dev, "Failed to register led handler\n"); -diff --git a/package/kernel/mac80211/patches/rt2x00/611-rt2x00-add-AP+STA-support.patch b/package/kernel/mac80211/patches/rt2x00/611-rt2x00-add-AP+STA-support.patch -new file mode 100644 -index 0000000000..5ef5fc8def ---- /dev/null -+++ b/package/kernel/mac80211/patches/rt2x00/611-rt2x00-add-AP+STA-support.patch -@@ -0,0 +1,11 @@ -+--- a/drivers/net/wireless/ralink/rt2x00/rt2x00dev.c -++++ b/drivers/net/wireless/ralink/rt2x00/rt2x00dev.c -+@@ -1358,7 +1358,7 @@ static inline void rt2x00lib_set_if_comb -+ */ -+ if_limit = &rt2x00dev->if_limits_ap; -+ if_limit->max = rt2x00dev->ops->max_ap_intf; -+- if_limit->types = BIT(NL80211_IFTYPE_AP); -++ if_limit->types = BIT(NL80211_IFTYPE_AP) | BIT(NL80211_IFTYPE_STATION); -+ #ifdef CPTCFG_MAC80211_MESH -+ if_limit->types |= BIT(NL80211_IFTYPE_MESH_POINT); -+ #endif -diff --git a/package/kernel/mac80211/patches/rt2x00/994-rt2x00-import-support-for-external-LNA-on-MT7620.patch b/package/kernel/mac80211/patches/rt2x00/994-rt2x00-import-support-for-external-LNA-on-MT7620.patch -new file mode 100644 -index 0000000000..deaa03be6c ---- /dev/null -+++ b/package/kernel/mac80211/patches/rt2x00/994-rt2x00-import-support-for-external-LNA-on-MT7620.patch -@@ -0,0 +1,161 @@ -+From 0fce1109f894ec7fcd72cb098843a1eff786716a Mon Sep 17 00:00:00 2001 -+From: Daniel Golle -+Date: Fri, 16 Sep 2022 20:49:42 +0100 -+Subject: [PATCH 16/16] rt2x00: import support for external LNA on MT7620 -+To: linux-wireless@vger.kernel.org, -+ Stanislaw Gruszka , -+ Helmut Schaa -+Cc: Kalle Valo , -+ David S. Miller , -+ Eric Dumazet , -+ Jakub Kicinski , -+ Paolo Abeni , -+ Johannes Berg -+ -+In order to carry out calibration on boards with ePA or eLNA the PA pin -+needs to be switch to GPIO mode on MT7620. Implement that by selecting -+pinctrl state "pa_gpio" which should be defined for MT7620 boards with -+eLNA or ePA beside the "default" state. -+ -+Reported-by: Serge Vasilugin -+Signed-off-by: Daniel Golle -+--- -+ .../net/wireless/ralink/rt2x00/rt2800lib.c | 58 +++++++++++++++++++ -+ drivers/net/wireless/ralink/rt2x00/rt2x00.h | 5 ++ -+ .../net/wireless/ralink/rt2x00/rt2x00soc.c | 15 +++++ -+ 3 files changed, 78 insertions(+) -+ -+--- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c -++++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c -+@@ -304,6 +304,24 @@ static void rt2800_rf_write(struct rt2x0 -+ mutex_unlock(&rt2x00dev->csr_mutex); -+ } -+ -++void rt6352_enable_pa_pin(struct rt2x00_dev *rt2x00dev, int enable) -++{ -++ if (!rt2x00dev->pinctrl) -++ return; -++ -++ if (enable) { -++ if (!rt2x00dev->pins_default) -++ return; -++ -++ pinctrl_select_state(rt2x00dev->pinctrl, rt2x00dev->pins_default); -++ } else { -++ if (!rt2x00dev->pins_pa_gpio) -++ return; -++ -++ pinctrl_select_state(rt2x00dev->pinctrl, rt2x00dev->pins_pa_gpio); -++ } -++} -++ -+ static const unsigned int rt2800_eeprom_map[EEPROM_WORD_COUNT] = { -+ [EEPROM_CHIP_ID] = 0x0000, -+ [EEPROM_VERSION] = 0x0001, -+@@ -4469,6 +4487,29 @@ static void rt2800_config_channel(struct -+ rt2800_register_write(rt2x00dev, TX1_RF_GAIN_ATTEN, -+ 0x6C6C6B6C); -+ } -++ -++ if (rt2x00_has_cap_external_lna_bg(rt2x00dev)) { -++ reg = rt2800_register_read(rt2x00dev, RF_CONTROL3); -++ reg |= 0x00000101; -++ rt2800_register_write(rt2x00dev, RF_CONTROL3, reg); -++ -++ reg = rt2800_register_read(rt2x00dev, RF_BYPASS3); -++ reg |= 0x00000101; -++ rt2800_register_write(rt2x00dev, RF_BYPASS3, reg); -++ -++ rt2800_rfcsr_write_chanreg(rt2x00dev, 14, 0x66); -++ rt2800_rfcsr_write_chanreg(rt2x00dev, 17, 0x20); -++ rt2800_rfcsr_write_chanreg(rt2x00dev, 18, 0x42); -++ rt2800_bbp_write(rt2x00dev, 75, 0x68); -++ rt2800_bbp_write(rt2x00dev, 76, 0x4C); -++ rt2800_bbp_write(rt2x00dev, 79, 0x1C); -++ rt2800_bbp_write(rt2x00dev, 80, 0x0C); -++ rt2800_bbp_write(rt2x00dev, 82, 0xB6); -++ /* bank 0 RF reg 42 and glrt BBP reg 141 will be set in -++ * config channel function in dependence of channel and -++ * HT20/HT40 so don't touch it -++ */ -++ } -+ } -+ -+ bbp = rt2800_bbp_read(rt2x00dev, 4); -+@@ -10583,6 +10624,7 @@ static void rt2800_init_rfcsr_6352(struc -+ rt2800_rfcsr_write_dccal(rt2x00dev, 5, 0x00); -+ rt2800_rfcsr_write_dccal(rt2x00dev, 17, 0x7C); -+ -++ rt6352_enable_pa_pin(rt2x00dev, 0); -+ rt2800_r_calibration(rt2x00dev); -+ rt2800_rf_self_txdc_cal(rt2x00dev); -+ rt2800_rxdcoc_calibration(rt2x00dev); -+@@ -10590,6 +10632,22 @@ static void rt2800_init_rfcsr_6352(struc -+ rt2800_bw_filter_calibration(rt2x00dev, false); -+ rt2800_loft_iq_calibration(rt2x00dev); -+ rt2800_rxiq_calibration(rt2x00dev); -++ rt6352_enable_pa_pin(rt2x00dev, 1); -++ -++ if (rt2x00_has_cap_external_lna_bg(rt2x00dev)) { -++ rt2800_rfcsr_write_chanreg(rt2x00dev, 14, 0x66); -++ rt2800_rfcsr_write_chanreg(rt2x00dev, 17, 0x20); -++ rt2800_rfcsr_write_chanreg(rt2x00dev, 18, 0x42); -++ rt2800_bbp_write(rt2x00dev, 75, 0x68); -++ rt2800_bbp_write(rt2x00dev, 76, 0x4C); -++ rt2800_bbp_write(rt2x00dev, 79, 0x1C); -++ rt2800_bbp_write(rt2x00dev, 80, 0x0C); -++ rt2800_bbp_write(rt2x00dev, 82, 0xB6); -++ /* bank 0 RF reg 42 and glrt BBP reg 141 will be set in config -++ * channel function in dependence of channel and HT20/HT40, -++ * so don't touch them here. -++ */ -++ } -+ } -+ -+ static void rt2800_init_rfcsr(struct rt2x00_dev *rt2x00dev) -+--- a/drivers/net/wireless/ralink/rt2x00/rt2x00.h -++++ b/drivers/net/wireless/ralink/rt2x00/rt2x00.h -+@@ -28,6 +28,7 @@ -+ #include -+ #include -+ #include -++#include -+ #include -+ -+ #include -+@@ -1029,6 +1030,11 @@ struct rt2x00_dev { -+ -+ /* Clock for System On Chip devices. */ -+ struct clk *clk; -++ -++ /* pinctrl and states for System On Chip devices with PA/LNA. */ -++ struct pinctrl *pinctrl; -++ struct pinctrl_state *pins_default; -++ struct pinctrl_state *pins_pa_gpio; -+ }; -+ -+ struct rt2x00_bar_list_entry { -+--- a/drivers/net/wireless/ralink/rt2x00/rt2x00soc.c -++++ b/drivers/net/wireless/ralink/rt2x00/rt2x00soc.c -+@@ -97,6 +97,21 @@ int rt2x00soc_probe(struct platform_devi -+ if (retval) -+ goto exit_free_reg; -+ -++ rt2x00dev->pinctrl = devm_pinctrl_get(&pdev->dev); -++ if (IS_ERR(rt2x00dev->pinctrl)) { -++ rt2x00dev->pinctrl = NULL; -++ rt2x00dev->pins_default = NULL; -++ rt2x00dev->pins_pa_gpio = NULL; -++ } else { -++ rt2x00dev->pins_default = pinctrl_lookup_state(rt2x00dev->pinctrl, "default"); -++ if (IS_ERR(rt2x00dev->pins_default)) -++ rt2x00dev->pins_default = NULL; -++ -++ rt2x00dev->pins_pa_gpio = pinctrl_lookup_state(rt2x00dev->pinctrl, "pa_gpio"); -++ if (IS_ERR(rt2x00dev->pins_pa_gpio)) -++ rt2x00dev->pins_pa_gpio = NULL; -++ } -++ -+ return 0; -+ -+ exit_free_reg: -diff --git a/package/kernel/mac80211/patches/rt2x00/995-rt2x00-mt7620-introduce-accessors-for-CHIP_VER-register.patch b/package/kernel/mac80211/patches/rt2x00/995-rt2x00-mt7620-introduce-accessors-for-CHIP_VER-register.patch -new file mode 100644 -index 0000000000..97a56de2b3 ---- /dev/null -+++ b/package/kernel/mac80211/patches/rt2x00/995-rt2x00-mt7620-introduce-accessors-for-CHIP_VER-register.patch -@@ -0,0 +1,139 @@ -+--- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.h -++++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.h -+@@ -78,6 +78,9 @@ struct rt2800_ops { -+ int (*drv_init_registers)(struct rt2x00_dev *rt2x00dev); -+ __le32 *(*drv_get_txwi)(struct queue_entry *entry); -+ unsigned int (*drv_get_dma_done)(struct data_queue *queue); -++ int (*hw_get_chippkg)(void); -++ int (*hw_get_chipver)(void); -++ int (*hw_get_chipeco)(void); -+ }; -+ -+ static inline u32 rt2800_register_read(struct rt2x00_dev *rt2x00dev, -+@@ -195,6 +198,27 @@ static inline unsigned int rt2800_drv_ge -+ return rt2800ops->drv_get_dma_done(queue); -+ } -+ -++static inline int rt2800_hw_get_chippkg(struct rt2x00_dev *rt2x00dev) -++{ -++ const struct rt2800_ops *rt2800ops = rt2x00dev->ops->drv; -++ -++ return rt2800ops->hw_get_chippkg(); -++} -++ -++static inline int rt2800_hw_get_chipver(struct rt2x00_dev *rt2x00dev) -++{ -++ const struct rt2800_ops *rt2800ops = rt2x00dev->ops->drv; -++ -++ return rt2800ops->hw_get_chipver(); -++} -++ -++static inline int rt2800_hw_get_chipeco(struct rt2x00_dev *rt2x00dev) -++{ -++ const struct rt2800_ops *rt2800ops = rt2x00dev->ops->drv; -++ -++ return rt2800ops->hw_get_chipeco(); -++} -++ -+ void rt2800_mcu_request(struct rt2x00_dev *rt2x00dev, -+ const u8 command, const u8 token, -+ const u8 arg0, const u8 arg1); -+--- a/drivers/net/wireless/ralink/rt2x00/rt2800pci.c -++++ b/drivers/net/wireless/ralink/rt2x00/rt2800pci.c -+@@ -286,6 +286,10 @@ static int rt2800pci_read_eeprom(struct -+ return retval; -+ } -+ -++static int rt2800pci_get_chippkg(void) { return 0; } -++static int rt2800pci_get_chipver(void) { return 0; } -++static int rt2800pci_get_chipeco(void) { return 0; } -++ -+ static const struct ieee80211_ops rt2800pci_mac80211_ops = { -+ .tx = rt2x00mac_tx, -+ .wake_tx_queue = ieee80211_handle_wake_tx_queue, -+@@ -329,6 +333,9 @@ static const struct rt2800_ops rt2800pci -+ .drv_init_registers = rt2800mmio_init_registers, -+ .drv_get_txwi = rt2800mmio_get_txwi, -+ .drv_get_dma_done = rt2800mmio_get_dma_done, -++ .hw_get_chippkg = rt2800pci_get_chippkg, -++ .hw_get_chipver = rt2800pci_get_chipver, -++ .hw_get_chipeco = rt2800pci_get_chipeco, -+ }; -+ -+ static const struct rt2x00lib_ops rt2800pci_rt2x00_ops = { -+--- a/drivers/net/wireless/ralink/rt2x00/rt2800soc.c -++++ b/drivers/net/wireless/ralink/rt2x00/rt2800soc.c -+@@ -27,6 +27,12 @@ -+ #include "rt2800lib.h" -+ #include "rt2800mmio.h" -+ -++/* Needed to probe CHIP_VER register on MT7620 */ -++#ifdef CONFIG_SOC_MT7620 -++#include -++#include -++#endif -++ -+ /* Allow hardware encryption to be disabled. */ -+ static bool modparam_nohwcrypt; -+ module_param_named(nohwcrypt, modparam_nohwcrypt, bool, 0444); -+@@ -118,6 +124,27 @@ static int rt2800soc_write_firmware(stru -+ return 0; -+ } -+ -++#ifdef CONFIG_SOC_MT7620 -++static int rt2800soc_get_chippkg(void) -++{ -++ return mt7620_get_pkg(); -++} -++ -++static int rt2800soc_get_chipver(void) -++{ -++ return mt7620_get_chipver(); -++} -++ -++static int rt2800soc_get_chipeco(void) -++{ -++ return mt7620_get_eco(); -++} -++#else -++static int rt2800soc_get_chippkg(void) { return 0; } -++static int rt2800soc_get_chipver(void) { return 0; } -++static int rt2800soc_get_chipeco(void) { return 0; } -++#endif -++ -+ static const struct ieee80211_ops rt2800soc_mac80211_ops = { -+ .tx = rt2x00mac_tx, -+ .wake_tx_queue = ieee80211_handle_wake_tx_queue, -+@@ -160,6 +187,9 @@ static const struct rt2800_ops rt2800soc -+ .drv_init_registers = rt2800mmio_init_registers, -+ .drv_get_txwi = rt2800mmio_get_txwi, -+ .drv_get_dma_done = rt2800mmio_get_dma_done, -++ .hw_get_chippkg = rt2800soc_get_chippkg, -++ .hw_get_chipver = rt2800soc_get_chipver, -++ .hw_get_chipeco = rt2800soc_get_chipeco, -+ }; -+ -+ static const struct rt2x00lib_ops rt2800soc_rt2x00_ops = { -+--- a/drivers/net/wireless/ralink/rt2x00/rt2800usb.c -++++ b/drivers/net/wireless/ralink/rt2x00/rt2800usb.c -+@@ -628,6 +628,10 @@ static int rt2800usb_probe_hw(struct rt2 -+ return 0; -+ } -+ -++static int rt2800usb_get_chippkg(void) { return 0; } -++static int rt2800usb_get_chipver(void) { return 0; } -++static int rt2800usb_get_chipeco(void) { return 0; } -++ -+ static const struct ieee80211_ops rt2800usb_mac80211_ops = { -+ .tx = rt2x00mac_tx, -+ .wake_tx_queue = ieee80211_handle_wake_tx_queue, -+@@ -672,6 +676,9 @@ static const struct rt2800_ops rt2800usb -+ .drv_init_registers = rt2800usb_init_registers, -+ .drv_get_txwi = rt2800usb_get_txwi, -+ .drv_get_dma_done = rt2800usb_get_dma_done, -++ .hw_get_chippkg = rt2800usb_get_chippkg, -++ .hw_get_chipver = rt2800usb_get_chipver, -++ .hw_get_chipeco = rt2800usb_get_chipeco, -+ }; -+ -+ static const struct rt2x00lib_ops rt2800usb_rt2x00_ops = { -diff --git a/package/kernel/mac80211/patches/rt2x00/996-rt2x00-mt7620-differentiate-based-on-SoC-CHIP_VER.patch b/package/kernel/mac80211/patches/rt2x00/996-rt2x00-mt7620-differentiate-based-on-SoC-CHIP_VER.patch -new file mode 100644 -index 0000000000..dab6e05ffd ---- /dev/null -+++ b/package/kernel/mac80211/patches/rt2x00/996-rt2x00-mt7620-differentiate-based-on-SoC-CHIP_VER.patch -@@ -0,0 +1,408 @@ -+--- a/drivers/net/wireless/ralink/rt2x00/rt2800.h -++++ b/drivers/net/wireless/ralink/rt2x00/rt2800.h -+@@ -1044,6 +1044,11 @@ -+ #define MIMO_PS_CFG_RX_STBY_POL FIELD32(0x00000010) -+ #define MIMO_PS_CFG_RX_RX_STBY0 FIELD32(0x00000020) -+ -++#define BB_PA_MODE_CFG0 0x1214 -++#define BB_PA_MODE_CFG1 0x1218 -++#define RF_PA_MODE_CFG0 0x121C -++#define RF_PA_MODE_CFG1 0x1220 -++ -+ /* -+ * EDCA_AC0_CFG: -+ */ -+--- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c -++++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c -+@@ -3778,14 +3778,16 @@ static void rt2800_config_channel_rf7620 -+ rt2x00_set_field8(&rfcsr, RFCSR19_K, rf->rf4); -+ rt2800_rfcsr_write(rt2x00dev, 19, rfcsr); -+ -+- /* Default: XO=20MHz , SDM mode */ -+- rfcsr = rt2800_rfcsr_read(rt2x00dev, 16); -+- rt2x00_set_field8(&rfcsr, RFCSR16_SDM_MODE_MT7620, 0x80); -+- rt2800_rfcsr_write(rt2x00dev, 16, rfcsr); -+- -+- rfcsr = rt2800_rfcsr_read(rt2x00dev, 21); -+- rt2x00_set_field8(&rfcsr, RFCSR21_BIT8, 1); -+- rt2800_rfcsr_write(rt2x00dev, 21, rfcsr); -++ if (rt2800_hw_get_chipver(rt2x00dev) > 1) { -++ /* Default: XO=20MHz , SDM mode */ -++ rfcsr = rt2800_rfcsr_read(rt2x00dev, 16); -++ rt2x00_set_field8(&rfcsr, RFCSR16_SDM_MODE_MT7620, 0x80); -++ rt2800_rfcsr_write(rt2x00dev, 16, rfcsr); -++ -++ rfcsr = rt2800_rfcsr_read(rt2x00dev, 21); -++ rt2x00_set_field8(&rfcsr, RFCSR21_BIT8, 1); -++ rt2800_rfcsr_write(rt2x00dev, 21, rfcsr); -++ } -+ -+ rfcsr = rt2800_rfcsr_read(rt2x00dev, 1); -+ rt2x00_set_field8(&rfcsr, RFCSR1_TX2_EN_MT7620, -+@@ -3819,18 +3821,23 @@ static void rt2800_config_channel_rf7620 -+ rt2800_rfcsr_write_dccal(rt2x00dev, 59, 0x20); -+ } -+ -+- if (conf_is_ht40(conf)) { -+- rt2800_rfcsr_write_dccal(rt2x00dev, 58, 0x08); -+- rt2800_rfcsr_write_dccal(rt2x00dev, 59, 0x08); -+- } else { -+- rt2800_rfcsr_write_dccal(rt2x00dev, 58, 0x28); -+- rt2800_rfcsr_write_dccal(rt2x00dev, 59, 0x28); -++ if (rt2800_hw_get_chipver(rt2x00dev) > 1) { -++ if (conf_is_ht40(conf)) { -++ rt2800_rfcsr_write_dccal(rt2x00dev, 58, 0x08); -++ rt2800_rfcsr_write_dccal(rt2x00dev, 59, 0x08); -++ } else { -++ rt2800_rfcsr_write_dccal(rt2x00dev, 58, 0x28); -++ rt2800_rfcsr_write_dccal(rt2x00dev, 59, 0x28); -++ } -+ } -+ -+- rfcsr = rt2800_rfcsr_read(rt2x00dev, 28); -+- rt2x00_set_field8(&rfcsr, RFCSR28_CH11_HT40, -+- conf_is_ht40(conf) && (rf->channel == 11)); -+- rt2800_rfcsr_write(rt2x00dev, 28, rfcsr); -++ if (rt2800_hw_get_chipver(rt2x00dev) > 1 && -++ rt2800_hw_get_chipeco(rt2x00dev) == 2) { -++ rfcsr = rt2800_rfcsr_read(rt2x00dev, 28); -++ rt2x00_set_field8(&rfcsr, RFCSR28_CH11_HT40, -++ conf_is_ht40(conf) && (rf->channel == 11)); -++ rt2800_rfcsr_write(rt2x00dev, 28, rfcsr); -++ } -+ -+ if (!test_bit(DEVICE_STATE_SCANNING, &rt2x00dev->flags)) { -+ if (conf_is_ht40(conf)) { -+@@ -3929,25 +3936,29 @@ static void rt2800_config_alc(struct rt2 -+ if (unlikely(rt2800_wait_bbp_rf_ready(rt2x00dev, MAC_STATUS_CFG_BBP_RF_BUSY))) -+ rt2x00_warn(rt2x00dev, "RF busy while configuring ALC\n"); -+ -+- if (chan->center_freq > 2457) { -+- bbp = rt2800_bbp_read(rt2x00dev, 30); -+- bbp = 0x40; -+- rt2800_bbp_write(rt2x00dev, 30, bbp); -+- rt2800_rfcsr_write(rt2x00dev, 39, 0); -+- if (rt2x00_has_cap_external_lna_bg(rt2x00dev)) -+- rt2800_rfcsr_write(rt2x00dev, 42, 0xfb); -+- else -+- rt2800_rfcsr_write(rt2x00dev, 42, 0x7b); -+- } else { -+- bbp = rt2800_bbp_read(rt2x00dev, 30); -+- bbp = 0x1f; -+- rt2800_bbp_write(rt2x00dev, 30, bbp); -+- rt2800_rfcsr_write(rt2x00dev, 39, 0x80); -+- if (rt2x00_has_cap_external_lna_bg(rt2x00dev)) -+- rt2800_rfcsr_write(rt2x00dev, 42, 0xdb); -+- else -+- rt2800_rfcsr_write(rt2x00dev, 42, 0x5b); -++ if (rt2800_hw_get_chipver(rt2x00dev) > 1 && -++ rt2800_hw_get_chipeco(rt2x00dev) >= 2) { -++ if (chan->center_freq > 2457) { -++ bbp = rt2800_bbp_read(rt2x00dev, 30); -++ bbp = 0x40; -++ rt2800_bbp_write(rt2x00dev, 30, bbp); -++ rt2800_rfcsr_write(rt2x00dev, 39, 0); -++ if (rt2x00_has_cap_external_lna_bg(rt2x00dev)) -++ rt2800_rfcsr_write(rt2x00dev, 42, 0xfb); -++ else -++ rt2800_rfcsr_write(rt2x00dev, 42, 0x7b); -++ } else { -++ bbp = rt2800_bbp_read(rt2x00dev, 30); -++ bbp = 0x1f; -++ rt2800_bbp_write(rt2x00dev, 30, bbp); -++ rt2800_rfcsr_write(rt2x00dev, 39, 0x80); -++ if (rt2x00_has_cap_external_lna_bg(rt2x00dev)) -++ rt2800_rfcsr_write(rt2x00dev, 42, 0xdb); -++ else -++ rt2800_rfcsr_write(rt2x00dev, 42, 0x5b); -++ } -+ } -++ -+ rt2800_register_write(rt2x00dev, MAC_SYS_CTRL, mac_sys_ctrl); -+ -+ rt2800_vco_calibration(rt2x00dev); -+@@ -6011,18 +6022,33 @@ static int rt2800_init_registers(struct -+ } else if (rt2x00_rt(rt2x00dev, RT5350)) { -+ rt2800_register_write(rt2x00dev, TX_SW_CFG0, 0x00000404); -+ } else if (rt2x00_rt(rt2x00dev, RT6352)) { -+- rt2800_register_write(rt2x00dev, TX_SW_CFG0, 0x00000401); -+- rt2800_register_write(rt2x00dev, TX_SW_CFG1, 0x000C0001); -+- rt2800_register_write(rt2x00dev, TX_SW_CFG2, 0x00000000); -+- rt2800_register_write(rt2x00dev, TX_ALC_VGA3, 0x00000000); -+- rt2800_register_write(rt2x00dev, TX0_BB_GAIN_ATTEN, 0x0); -+- rt2800_register_write(rt2x00dev, TX1_BB_GAIN_ATTEN, 0x0); -+- rt2800_register_write(rt2x00dev, TX0_RF_GAIN_ATTEN, 0x6C6C666C); -+- rt2800_register_write(rt2x00dev, TX1_RF_GAIN_ATTEN, 0x6C6C666C); -+- rt2800_register_write(rt2x00dev, TX0_RF_GAIN_CORRECT, -+- 0x3630363A); -+- rt2800_register_write(rt2x00dev, TX1_RF_GAIN_CORRECT, -+- 0x3630363A); -++ if (rt2800_hw_get_chipver(rt2x00dev) <= 1) { -++ rt2800_register_write(rt2x00dev, TX_ALC_VGA3, -++ 0x00000000); -++ rt2800_register_write(rt2x00dev, BB_PA_MODE_CFG0, -++ 0x000055FF); -++ rt2800_register_write(rt2x00dev, BB_PA_MODE_CFG1, -++ 0x00550055); -++ rt2800_register_write(rt2x00dev, RF_PA_MODE_CFG0, -++ 0x000055FF); -++ rt2800_register_write(rt2x00dev, RF_PA_MODE_CFG1, -++ 0x00550055); -++ } else { -++ rt2800_register_write(rt2x00dev, TX_SW_CFG0, 0x00000401); -++ rt2800_register_write(rt2x00dev, TX_SW_CFG1, 0x000C0001); -++ rt2800_register_write(rt2x00dev, TX_SW_CFG2, 0x00000000); -++ rt2800_register_write(rt2x00dev, TX_ALC_VGA3, 0x00000000); -++ rt2800_register_write(rt2x00dev, TX0_BB_GAIN_ATTEN, 0x0); -++ rt2800_register_write(rt2x00dev, TX1_BB_GAIN_ATTEN, 0x0); -++ rt2800_register_write(rt2x00dev, TX0_RF_GAIN_ATTEN, -++ 0x6C6C666C); -++ rt2800_register_write(rt2x00dev, TX1_RF_GAIN_ATTEN, -++ 0x6C6C666C); -++ rt2800_register_write(rt2x00dev, TX0_RF_GAIN_CORRECT, -++ 0x3630363A); -++ rt2800_register_write(rt2x00dev, TX1_RF_GAIN_CORRECT, -++ 0x3630363A); -++ } -+ reg = rt2800_register_read(rt2x00dev, TX_ALC_CFG_1); -+ rt2x00_set_field32(®, TX_ALC_CFG_1_ROS_BUSY_EN, 0); -+ rt2800_register_write(rt2x00dev, TX_ALC_CFG_1, reg); -+@@ -7127,14 +7153,16 @@ static void rt2800_init_bbp_6352(struct -+ rt2800_bbp_write(rt2x00dev, 188, 0x00); -+ rt2800_bbp_write(rt2x00dev, 189, 0x00); -+ -+- rt2800_bbp_write(rt2x00dev, 91, 0x06); -+- rt2800_bbp_write(rt2x00dev, 92, 0x04); -+- rt2800_bbp_write(rt2x00dev, 93, 0x54); -+- rt2800_bbp_write(rt2x00dev, 99, 0x50); -+- rt2800_bbp_write(rt2x00dev, 148, 0x84); -+- rt2800_bbp_write(rt2x00dev, 167, 0x80); -+- rt2800_bbp_write(rt2x00dev, 178, 0xFF); -+- rt2800_bbp_write(rt2x00dev, 106, 0x13); -++ if (rt2800_hw_get_chipver(rt2x00dev) > 1) { -++ rt2800_bbp_write(rt2x00dev, 91, 0x06); -++ rt2800_bbp_write(rt2x00dev, 92, 0x04); -++ rt2800_bbp_write(rt2x00dev, 93, 0x54); -++ rt2800_bbp_write(rt2x00dev, 99, 0x50); -++ rt2800_bbp_write(rt2x00dev, 148, 0x84); -++ rt2800_bbp_write(rt2x00dev, 167, 0x80); -++ rt2800_bbp_write(rt2x00dev, 178, 0xFF); -++ rt2800_bbp_write(rt2x00dev, 106, 0x13); -++ } -+ -+ /* BBP for G band GLRT function (BBP_128 ~ BBP_221) */ -+ rt2800_bbp_glrt_write(rt2x00dev, 0, 0x00); -+@@ -10408,31 +10436,36 @@ static void rt2800_init_rfcsr_6352(struc -+ rt2800_rfcsr_write(rt2x00dev, 42, 0x5B); -+ rt2800_rfcsr_write(rt2x00dev, 43, 0x00); -+ -+- rt2800_rfcsr_write(rt2x00dev, 11, 0x21); -+- if (rt2800_clk_is_20mhz(rt2x00dev)) -+- rt2800_rfcsr_write(rt2x00dev, 13, 0x03); -+- else -+- rt2800_rfcsr_write(rt2x00dev, 13, 0x00); -+- rt2800_rfcsr_write(rt2x00dev, 14, 0x7C); -+- rt2800_rfcsr_write(rt2x00dev, 16, 0x80); -+- rt2800_rfcsr_write(rt2x00dev, 17, 0x99); -+- rt2800_rfcsr_write(rt2x00dev, 18, 0x99); -+- rt2800_rfcsr_write(rt2x00dev, 19, 0x09); -+- rt2800_rfcsr_write(rt2x00dev, 20, 0x50); -+- rt2800_rfcsr_write(rt2x00dev, 21, 0xB0); -+- rt2800_rfcsr_write(rt2x00dev, 22, 0x00); -+- rt2800_rfcsr_write(rt2x00dev, 23, 0x06); -+- rt2800_rfcsr_write(rt2x00dev, 24, 0x00); -+- rt2800_rfcsr_write(rt2x00dev, 25, 0x00); -+- rt2800_rfcsr_write(rt2x00dev, 26, 0x5D); -+- rt2800_rfcsr_write(rt2x00dev, 27, 0x00); -+- rt2800_rfcsr_write(rt2x00dev, 28, 0x61); -+- rt2800_rfcsr_write(rt2x00dev, 29, 0xB5); -+- rt2800_rfcsr_write(rt2x00dev, 43, 0x02); -+- -+- rt2800_rfcsr_write(rt2x00dev, 28, 0x62); -+- rt2800_rfcsr_write(rt2x00dev, 29, 0xAD); -+- rt2800_rfcsr_write(rt2x00dev, 39, 0x80); -++ if (rt2800_hw_get_chipver(rt2x00dev) > 1) { -++ rt2800_rfcsr_write(rt2x00dev, 11, 0x21); -++ if (rt2800_clk_is_20mhz(rt2x00dev)) -++ rt2800_rfcsr_write(rt2x00dev, 13, 0x03); -++ else -++ rt2800_rfcsr_write(rt2x00dev, 13, 0x00); -++ rt2800_rfcsr_write(rt2x00dev, 14, 0x7C); -++ rt2800_rfcsr_write(rt2x00dev, 16, 0x80); -++ rt2800_rfcsr_write(rt2x00dev, 17, 0x99); -++ rt2800_rfcsr_write(rt2x00dev, 18, 0x99); -++ rt2800_rfcsr_write(rt2x00dev, 19, 0x09); -++ rt2800_rfcsr_write(rt2x00dev, 20, 0x50); -++ rt2800_rfcsr_write(rt2x00dev, 21, 0xB0); -++ rt2800_rfcsr_write(rt2x00dev, 22, 0x00); -++ rt2800_rfcsr_write(rt2x00dev, 23, 0x06); -++ rt2800_rfcsr_write(rt2x00dev, 24, 0x00); -++ rt2800_rfcsr_write(rt2x00dev, 25, 0x00); -++ rt2800_rfcsr_write(rt2x00dev, 26, 0x5D); -++ rt2800_rfcsr_write(rt2x00dev, 27, 0x00); -++ rt2800_rfcsr_write(rt2x00dev, 28, 0x61); -++ rt2800_rfcsr_write(rt2x00dev, 29, 0xB5); -++ rt2800_rfcsr_write(rt2x00dev, 43, 0x02); -++ } -++ -++ if (rt2800_hw_get_chipver(rt2x00dev) > 1 && -++ rt2800_hw_get_chipeco(rt2x00dev) >= 2) { -++ rt2800_rfcsr_write(rt2x00dev, 28, 0x62); -++ rt2800_rfcsr_write(rt2x00dev, 29, 0xAD); -++ rt2800_rfcsr_write(rt2x00dev, 39, 0x80); -++ } -+ -+ /* Initialize RF channel register to default value */ -+ rt2800_rfcsr_write_chanreg(rt2x00dev, 0, 0x03); -+@@ -10498,63 +10531,71 @@ static void rt2800_init_rfcsr_6352(struc -+ -+ rt2800_rfcsr_write_bank(rt2x00dev, 6, 45, 0xC5); -+ -+- rt2800_rfcsr_write_chanreg(rt2x00dev, 9, 0x47); -+- rt2800_rfcsr_write_chanreg(rt2x00dev, 10, 0x71); -+- rt2800_rfcsr_write_chanreg(rt2x00dev, 11, 0x33); -+- rt2800_rfcsr_write_chanreg(rt2x00dev, 14, 0x0E); -+- rt2800_rfcsr_write_chanreg(rt2x00dev, 17, 0x23); -+- rt2800_rfcsr_write_chanreg(rt2x00dev, 19, 0xA4); -+- rt2800_rfcsr_write_chanreg(rt2x00dev, 20, 0x02); -+- rt2800_rfcsr_write_chanreg(rt2x00dev, 21, 0x12); -+- rt2800_rfcsr_write_chanreg(rt2x00dev, 28, 0x1C); -+- rt2800_rfcsr_write_chanreg(rt2x00dev, 29, 0xEB); -+- rt2800_rfcsr_write_chanreg(rt2x00dev, 32, 0x7D); -+- rt2800_rfcsr_write_chanreg(rt2x00dev, 34, 0xD6); -+- rt2800_rfcsr_write_chanreg(rt2x00dev, 36, 0x08); -+- rt2800_rfcsr_write_chanreg(rt2x00dev, 38, 0xB4); -+- rt2800_rfcsr_write_chanreg(rt2x00dev, 43, 0xD3); -+- rt2800_rfcsr_write_chanreg(rt2x00dev, 44, 0xB3); -+- rt2800_rfcsr_write_chanreg(rt2x00dev, 45, 0xD5); -+- rt2800_rfcsr_write_chanreg(rt2x00dev, 46, 0x27); -+- rt2800_rfcsr_write_bank(rt2x00dev, 4, 47, 0x67); -+- rt2800_rfcsr_write_bank(rt2x00dev, 6, 47, 0x69); -+- rt2800_rfcsr_write_chanreg(rt2x00dev, 48, 0xFF); -+- rt2800_rfcsr_write_bank(rt2x00dev, 4, 54, 0x27); -+- rt2800_rfcsr_write_bank(rt2x00dev, 6, 54, 0x20); -+- rt2800_rfcsr_write_chanreg(rt2x00dev, 55, 0x66); -+- rt2800_rfcsr_write_chanreg(rt2x00dev, 56, 0xFF); -+- rt2800_rfcsr_write_chanreg(rt2x00dev, 57, 0x1C); -+- rt2800_rfcsr_write_chanreg(rt2x00dev, 58, 0x20); -+- rt2800_rfcsr_write_chanreg(rt2x00dev, 59, 0x6B); -+- rt2800_rfcsr_write_chanreg(rt2x00dev, 60, 0xF7); -+- rt2800_rfcsr_write_chanreg(rt2x00dev, 61, 0x09); -+- -+- rt2800_rfcsr_write_chanreg(rt2x00dev, 10, 0x51); -+- rt2800_rfcsr_write_chanreg(rt2x00dev, 14, 0x06); -+- rt2800_rfcsr_write_chanreg(rt2x00dev, 19, 0xA7); -+- rt2800_rfcsr_write_chanreg(rt2x00dev, 28, 0x2C); -+- rt2800_rfcsr_write_chanreg(rt2x00dev, 55, 0x64); -+- rt2800_rfcsr_write_chanreg(rt2x00dev, 8, 0x51); -+- rt2800_rfcsr_write_chanreg(rt2x00dev, 9, 0x36); -+- rt2800_rfcsr_write_chanreg(rt2x00dev, 11, 0x53); -+- rt2800_rfcsr_write_chanreg(rt2x00dev, 14, 0x16); -+- -+- rt2800_rfcsr_write_chanreg(rt2x00dev, 47, 0x6C); -+- rt2800_rfcsr_write_chanreg(rt2x00dev, 48, 0xFC); -+- rt2800_rfcsr_write_chanreg(rt2x00dev, 49, 0x1F); -+- rt2800_rfcsr_write_chanreg(rt2x00dev, 54, 0x27); -+- rt2800_rfcsr_write_chanreg(rt2x00dev, 55, 0x66); -+- rt2800_rfcsr_write_chanreg(rt2x00dev, 59, 0x6B); -+- -+- /* Initialize RF channel register for DRQFN */ -+- rt2800_rfcsr_write_chanreg(rt2x00dev, 43, 0xD3); -+- rt2800_rfcsr_write_chanreg(rt2x00dev, 44, 0xE3); -+- rt2800_rfcsr_write_chanreg(rt2x00dev, 45, 0xE5); -+- rt2800_rfcsr_write_chanreg(rt2x00dev, 47, 0x28); -+- rt2800_rfcsr_write_chanreg(rt2x00dev, 55, 0x68); -+- rt2800_rfcsr_write_chanreg(rt2x00dev, 56, 0xF7); -+- rt2800_rfcsr_write_chanreg(rt2x00dev, 58, 0x02); -+- rt2800_rfcsr_write_chanreg(rt2x00dev, 60, 0xC7); -++ if (rt2800_hw_get_chipver(rt2x00dev) > 1) { -++ rt2800_rfcsr_write_chanreg(rt2x00dev, 9, 0x47); -++ rt2800_rfcsr_write_chanreg(rt2x00dev, 10, 0x71); -++ rt2800_rfcsr_write_chanreg(rt2x00dev, 11, 0x33); -++ rt2800_rfcsr_write_chanreg(rt2x00dev, 14, 0x0E); -++ rt2800_rfcsr_write_chanreg(rt2x00dev, 17, 0x23); -++ rt2800_rfcsr_write_chanreg(rt2x00dev, 19, 0xA4); -++ rt2800_rfcsr_write_chanreg(rt2x00dev, 20, 0x02); -++ rt2800_rfcsr_write_chanreg(rt2x00dev, 21, 0x12); -++ rt2800_rfcsr_write_chanreg(rt2x00dev, 28, 0x1C); -++ rt2800_rfcsr_write_chanreg(rt2x00dev, 29, 0xEB); -++ rt2800_rfcsr_write_chanreg(rt2x00dev, 32, 0x7D); -++ rt2800_rfcsr_write_chanreg(rt2x00dev, 34, 0xD6); -++ rt2800_rfcsr_write_chanreg(rt2x00dev, 36, 0x08); -++ rt2800_rfcsr_write_chanreg(rt2x00dev, 38, 0xB4); -++ rt2800_rfcsr_write_chanreg(rt2x00dev, 43, 0xD3); -++ rt2800_rfcsr_write_chanreg(rt2x00dev, 44, 0xB3); -++ rt2800_rfcsr_write_chanreg(rt2x00dev, 45, 0xD5); -++ rt2800_rfcsr_write_chanreg(rt2x00dev, 46, 0x27); -++ rt2800_rfcsr_write_bank(rt2x00dev, 4, 47, 0x67); -++ rt2800_rfcsr_write_bank(rt2x00dev, 6, 47, 0x69); -++ rt2800_rfcsr_write_chanreg(rt2x00dev, 48, 0xFF); -++ rt2800_rfcsr_write_bank(rt2x00dev, 4, 54, 0x27); -++ rt2800_rfcsr_write_bank(rt2x00dev, 6, 54, 0x20); -++ rt2800_rfcsr_write_chanreg(rt2x00dev, 55, 0x66); -++ rt2800_rfcsr_write_chanreg(rt2x00dev, 56, 0xFF); -++ rt2800_rfcsr_write_chanreg(rt2x00dev, 57, 0x1C); -++ rt2800_rfcsr_write_chanreg(rt2x00dev, 58, 0x20); -++ rt2800_rfcsr_write_chanreg(rt2x00dev, 59, 0x6B); -++ rt2800_rfcsr_write_chanreg(rt2x00dev, 60, 0xF7); -++ rt2800_rfcsr_write_chanreg(rt2x00dev, 61, 0x09); -++ } -++ -++ if (rt2800_hw_get_chipver(rt2x00dev) > 1 && -++ rt2800_hw_get_chipeco(rt2x00dev) >= 2) { -++ rt2800_rfcsr_write_chanreg(rt2x00dev, 10, 0x51); -++ rt2800_rfcsr_write_chanreg(rt2x00dev, 14, 0x06); -++ rt2800_rfcsr_write_chanreg(rt2x00dev, 19, 0xA7); -++ rt2800_rfcsr_write_chanreg(rt2x00dev, 28, 0x2C); -++ rt2800_rfcsr_write_chanreg(rt2x00dev, 55, 0x64); -++ rt2800_rfcsr_write_chanreg(rt2x00dev, 8, 0x51); -++ rt2800_rfcsr_write_chanreg(rt2x00dev, 9, 0x36); -++ rt2800_rfcsr_write_chanreg(rt2x00dev, 11, 0x53); -++ rt2800_rfcsr_write_chanreg(rt2x00dev, 14, 0x16); -++ -++ rt2800_rfcsr_write_chanreg(rt2x00dev, 47, 0x6C); -++ rt2800_rfcsr_write_chanreg(rt2x00dev, 48, 0xFC); -++ rt2800_rfcsr_write_chanreg(rt2x00dev, 49, 0x1F); -++ rt2800_rfcsr_write_chanreg(rt2x00dev, 54, 0x27); -++ rt2800_rfcsr_write_chanreg(rt2x00dev, 55, 0x66); -++ rt2800_rfcsr_write_chanreg(rt2x00dev, 59, 0x6B); -++ } -++ -++ if (rt2800_hw_get_chippkg(rt2x00dev) == 0 && -++ rt2800_hw_get_chipver(rt2x00dev) == 1) { -++ /* Initialize RF channel register for DRQFN */ -++ rt2800_rfcsr_write_chanreg(rt2x00dev, 43, 0xD3); -++ rt2800_rfcsr_write_chanreg(rt2x00dev, 44, 0xE3); -++ rt2800_rfcsr_write_chanreg(rt2x00dev, 45, 0xE5); -++ rt2800_rfcsr_write_chanreg(rt2x00dev, 47, 0x28); -++ rt2800_rfcsr_write_chanreg(rt2x00dev, 55, 0x68); -++ rt2800_rfcsr_write_chanreg(rt2x00dev, 56, 0xF7); -++ rt2800_rfcsr_write_chanreg(rt2x00dev, 58, 0x02); -++ rt2800_rfcsr_write_chanreg(rt2x00dev, 60, 0xC7); -++ } -+ -+ /* Initialize RF DC calibration register to default value */ -+ rt2800_rfcsr_write_dccal(rt2x00dev, 0, 0x47); -+@@ -10617,12 +10658,17 @@ static void rt2800_init_rfcsr_6352(struc -+ rt2800_rfcsr_write_dccal(rt2x00dev, 62, 0x00); -+ rt2800_rfcsr_write_dccal(rt2x00dev, 63, 0x00); -+ -+- rt2800_rfcsr_write_dccal(rt2x00dev, 3, 0x08); -+- rt2800_rfcsr_write_dccal(rt2x00dev, 4, 0x04); -+- rt2800_rfcsr_write_dccal(rt2x00dev, 5, 0x20); -++ if (rt2800_hw_get_chipver(rt2x00dev) > 1) { -++ rt2800_rfcsr_write_dccal(rt2x00dev, 3, 0x08); -++ rt2800_rfcsr_write_dccal(rt2x00dev, 4, 0x04); -++ rt2800_rfcsr_write_dccal(rt2x00dev, 5, 0x20); -++ } -+ -+- rt2800_rfcsr_write_dccal(rt2x00dev, 5, 0x00); -+- rt2800_rfcsr_write_dccal(rt2x00dev, 17, 0x7C); -++ if (rt2800_hw_get_chipver(rt2x00dev) > 1 && -++ rt2800_hw_get_chipeco(rt2x00dev) >= 2) { -++ rt2800_rfcsr_write_dccal(rt2x00dev, 5, 0x00); -++ rt2800_rfcsr_write_dccal(rt2x00dev, 17, 0x7C); -++ } -+ -+ rt6352_enable_pa_pin(rt2x00dev, 0); -+ rt2800_r_calibration(rt2x00dev); -diff --git a/package/kernel/mac80211/patches/rt2x00/997-wifi-rt2x00-limit-MT7620-TX-power-based-on-eeprom-ca.patch b/package/kernel/mac80211/patches/rt2x00/997-wifi-rt2x00-limit-MT7620-TX-power-based-on-eeprom-ca.patch -new file mode 100644 -index 0000000000..fd1b3d8bf3 ---- /dev/null -+++ b/package/kernel/mac80211/patches/rt2x00/997-wifi-rt2x00-limit-MT7620-TX-power-based-on-eeprom-ca.patch -@@ -0,0 +1,106 @@ -+From: Shiji Yang -+Date: Sat, 22 Jul 2023 21:56:30 +0800 -+Subject: [PATCH] wifi: rt2x00: limit MT7620 TX power based on eeprom -+ calibration -+ -+In the vendor driver, the current channel power is queried from -+EEPROM_TXPOWER_BG1 and EEPROM_TXPOWER_BG2. And then the mixed value -+will be written into the low half-word of the TX_ALC_CFG_0 register. -+The high half-word of the TX_ALC_CFG_0 is a fixed value 0x2f2f. -+ -+We can't get the accurate TX power. Based on my tests and the new -+MediaTek mt76 driver source code, the real TX power is approximately -+equal to channel_power + (max) rate_power. Usually max rate_power is -+the gain of the OFDM 6M rate, which can be readed from the offset -+EEPROM_TXPOWER_BYRATE +1. -+ -+Based on these eeprom values, this patch adds basic TX power control -+for the MT7620 and limits its maximum TX power. This can avoid the -+link speed decrease caused by chip overheating. rt2800_config_alc() -+function has also been renamed to rt2800_config_alc_rt6352() because -+it's only used by RT6352(MT7620). -+ -+Notice: -+It's still need some work to sync the max channel power to the user -+interface. This part is missing from the rt2x00 driver structure. If -+we set the power exceed the calibration value, it won't take effect. -+ -+Signed-off-by: Shiji Yang -+--- -+ .../net/wireless/ralink/rt2x00/rt2800lib.c | 49 +++++++++++++------ -+ 1 file changed, 34 insertions(+), 15 deletions(-) -+ -+--- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c -++++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c -+@@ -3891,28 +3891,47 @@ static void rt2800_config_channel_rf7620 -+ } -+ } -+ -+-static void rt2800_config_alc(struct rt2x00_dev *rt2x00dev, -++static void rt2800_config_alc_rt6352(struct rt2x00_dev *rt2x00dev, -+ struct ieee80211_channel *chan, -+ int power_level) { -+- u16 eeprom, target_power, max_power; -++ u16 eeprom, chan_power, rate_power, target_power; -++ u16 tx_power[2]; -++ s8 *power_group[2]; -+ u32 mac_sys_ctrl; -+- u32 reg; -++ u32 cnt, reg; -+ u8 bbp; -+ -+- /* hardware unit is 0.5dBm, limited to 23.5dBm */ -+- power_level *= 2; -+- if (power_level > 0x2f) -+- power_level = 0x2f; -+- -+- max_power = chan->max_power * 2; -+- if (max_power > 0x2f) -+- max_power = 0x2f; -++ /* get per channel power, 2 channels in total, unit is 0.5dBm */ -++ power_level = (power_level - 3) * 2; -++ /* -++ * We can't get the accurate TX power. Based on some tests, the real -++ * TX power is approximately equal to channel_power + (max)rate_power. -++ * Usually max rate_power is the gain of the OFDM 6M rate. The antenna -++ * gain and externel PA gain are not included as we are unable to -++ * obtain these values. -++ */ -++ rate_power = rt2800_eeprom_read_from_array(rt2x00dev, -++ EEPROM_TXPOWER_BYRATE, 1) & 0x3f; -++ power_level -= rate_power; -++ if (power_level < 1) -++ power_level = 1; -++ if (power_level > chan->max_power * 2) -++ power_level = chan->max_power * 2; -++ -++ power_group[0] = rt2800_eeprom_addr(rt2x00dev, EEPROM_TXPOWER_BG1); -++ power_group[1] = rt2800_eeprom_addr(rt2x00dev, EEPROM_TXPOWER_BG2); -++ for (cnt = 0; cnt < 2; cnt++) { -++ chan_power = power_group[cnt][rt2x00dev->rf_channel - 1]; -++ if (chan_power >= 0x20 || chan_power == 0) -++ chan_power = 0x10; -++ tx_power[cnt] = power_level < chan_power ? power_level : chan_power; -++ } -+ -+ reg = rt2800_register_read(rt2x00dev, TX_ALC_CFG_0); -+- rt2x00_set_field32(®, TX_ALC_CFG_0_CH_INIT_0, power_level); -+- rt2x00_set_field32(®, TX_ALC_CFG_0_CH_INIT_1, power_level); -+- rt2x00_set_field32(®, TX_ALC_CFG_0_LIMIT_0, max_power); -+- rt2x00_set_field32(®, TX_ALC_CFG_0_LIMIT_1, max_power); -++ rt2x00_set_field32(®, TX_ALC_CFG_0_CH_INIT_0, tx_power[0]); -++ rt2x00_set_field32(®, TX_ALC_CFG_0_CH_INIT_1, tx_power[1]); -++ rt2x00_set_field32(®, TX_ALC_CFG_0_LIMIT_0, 0x2f); -++ rt2x00_set_field32(®, TX_ALC_CFG_0_LIMIT_1, 0x2f); -+ -+ eeprom = rt2800_eeprom_read(rt2x00dev, EEPROM_NIC_CONF1); -+ if (rt2x00_get_field16(eeprom, EEPROM_NIC_CONF1_INTERNAL_TX_ALC)) { -+@@ -5321,7 +5340,7 @@ static void rt2800_config_txpower_rt6352 -+ rt2x00_set_field32(&pwreg, TX_PWR_CFG_9B_STBC_MCS7, t); -+ rt2800_register_write(rt2x00dev, TX_PWR_CFG_9, pwreg); -+ -+- rt2800_config_alc(rt2x00dev, chan, power_level); -++ rt2800_config_alc_rt6352(rt2x00dev, chan, power_level); -+ -+ /* TODO: temperature compensation code! */ -+ } -diff --git a/package/kernel/mac80211/patches/rt2x00/998-wifi-rt2x00-rework-MT7620-PA-LNA-RF-calibration.patch b/package/kernel/mac80211/patches/rt2x00/998-wifi-rt2x00-rework-MT7620-PA-LNA-RF-calibration.patch -new file mode 100644 -index 0000000000..5f6f5140d9 ---- /dev/null -+++ b/package/kernel/mac80211/patches/rt2x00/998-wifi-rt2x00-rework-MT7620-PA-LNA-RF-calibration.patch -@@ -0,0 +1,413 @@ -+From: Shiji Yang -+Date: Tue, 25 Jul 2023 20:05:06 +0800 -+Subject: [PATCH] wifi: rt2x00: rework MT7620 PA/LNA RF calibration -+ -+1. Move MT7620 PA/LNA calibration code to dedicated functions. -+2. For external PA/LNA devices, restore RF and BBP registers before -+ R-Calibration. -+3. Do Rx DCOC calibration again before RXIQ calibration. -+4. Correct MAC_SYS_CTRL register RX mask to 0x08 in R-Calibration -+ function. For MAC_SYS_CTRL register, Bit[2] controls MAC_TX_EN -+ and Bit[3] controls MAC_RX_EN (Bit index starts from 0). -+5. Move the channel configuration code from rt2800_vco_calibration() -+ to the rt2800_config_channel(). -+6. Use MT7620 SOC specific AGC initial LNA value instead of the -+ RT5592's value. -+7. Adjust the register operation sequence according to the vendor -+ driver code. This may not be useful, but it can make things -+ clearer when developers try to review it. -+ -+Signed-off-by: Shiji Yang -+--- -+ .../net/wireless/ralink/rt2x00/rt2800lib.c | 306 ++++++++++-------- -+ drivers/net/wireless/ralink/rt2x00/rt2x00.h | 6 + -+ 2 files changed, 182 insertions(+), 130 deletions(-) -+ -+--- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c -++++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c -+@@ -3881,14 +3881,6 @@ static void rt2800_config_channel_rf7620 -+ rfcsr |= tx_agc_fc; -+ rt2800_rfcsr_write_bank(rt2x00dev, 7, 59, rfcsr); -+ } -+- -+- if (conf_is_ht40(conf)) { -+- rt2800_bbp_glrt_write(rt2x00dev, 141, 0x10); -+- rt2800_bbp_glrt_write(rt2x00dev, 157, 0x2f); -+- } else { -+- rt2800_bbp_glrt_write(rt2x00dev, 141, 0x1a); -+- rt2800_bbp_glrt_write(rt2x00dev, 157, 0x40); -+- } -+ } -+ -+ static void rt2800_config_alc_rt6352(struct rt2x00_dev *rt2x00dev, -+@@ -4457,89 +4449,63 @@ static void rt2800_config_channel(struct -+ usleep_range(1000, 1500); -+ } -+ -+- if (rt2x00_rt(rt2x00dev, RT5592) || rt2x00_rt(rt2x00dev, RT6352)) { -++ if (rt2x00_rt(rt2x00dev, RT5592)) { -+ reg = 0x10; -+- if (!conf_is_ht40(conf)) { -+- if (rt2x00_rt(rt2x00dev, RT6352) && -+- rt2x00_has_cap_external_lna_bg(rt2x00dev)) { -+- reg |= 0x5; -+- } else { -+- reg |= 0xa; -+- } -+- } -++ if (!conf_is_ht40(conf)) -++ reg |= 0xa; -+ rt2800_bbp_write(rt2x00dev, 195, 141); -+ rt2800_bbp_write(rt2x00dev, 196, reg); -+ -+- /* AGC init. -+- * Despite the vendor driver using different values here for -+- * RT6352 chip, we use 0x1c for now. This may have to be changed -+- * once TSSI got implemented. -+- */ -+ reg = (rf->channel <= 14 ? 0x1c : 0x24) + 2*rt2x00dev->lna_gain; -+ rt2800_bbp_write_with_rx_chain(rt2x00dev, 66, reg); -+- -+- if (rt2x00_rt(rt2x00dev, RT5592)) -+- rt2800_iq_calibrate(rt2x00dev, rf->channel); -++ -++ rt2800_iq_calibrate(rt2x00dev, rf->channel); -+ } -+ -+ if (rt2x00_rt(rt2x00dev, RT6352)) { -+- if (test_bit(CAPABILITY_EXTERNAL_PA_TX0, -+- &rt2x00dev->cap_flags)) { -+- reg = rt2800_register_read(rt2x00dev, RF_CONTROL3); -+- reg |= 0x00000101; -+- rt2800_register_write(rt2x00dev, RF_CONTROL3, reg); -+- -+- reg = rt2800_register_read(rt2x00dev, RF_BYPASS3); -+- reg |= 0x00000101; -+- rt2800_register_write(rt2x00dev, RF_BYPASS3, reg); -+- -+- rt2800_rfcsr_write_chanreg(rt2x00dev, 43, 0x73); -+- rt2800_rfcsr_write_chanreg(rt2x00dev, 44, 0x73); -+- rt2800_rfcsr_write_chanreg(rt2x00dev, 45, 0x73); -+- rt2800_rfcsr_write_chanreg(rt2x00dev, 46, 0x27); -+- rt2800_rfcsr_write_chanreg(rt2x00dev, 47, 0xC8); -+- rt2800_rfcsr_write_chanreg(rt2x00dev, 48, 0xA4); -+- rt2800_rfcsr_write_chanreg(rt2x00dev, 49, 0x05); -+- rt2800_rfcsr_write_chanreg(rt2x00dev, 54, 0x27); -+- rt2800_rfcsr_write_chanreg(rt2x00dev, 55, 0xC8); -+- rt2800_rfcsr_write_chanreg(rt2x00dev, 56, 0xA4); -+- rt2800_rfcsr_write_chanreg(rt2x00dev, 57, 0x05); -+- rt2800_rfcsr_write_chanreg(rt2x00dev, 58, 0x27); -+- rt2800_rfcsr_write_chanreg(rt2x00dev, 59, 0xC8); -+- rt2800_rfcsr_write_chanreg(rt2x00dev, 60, 0xA4); -+- rt2800_rfcsr_write_chanreg(rt2x00dev, 61, 0x05); -+- rt2800_rfcsr_write_dccal(rt2x00dev, 05, 0x00); -++ /* BBP for GLRT BW */ -++ if (conf_is_ht40(conf)) { -++ rt2800_bbp_glrt_write(rt2x00dev, 141, 0x10); -++ rt2800_bbp_glrt_write(rt2x00dev, 157, 0x2f); -++ } else { -++ rt2800_bbp_glrt_write(rt2x00dev, 141, 0x1a); -++ rt2800_bbp_glrt_write(rt2x00dev, 157, 0x40); -+ -+- rt2800_register_write(rt2x00dev, TX0_RF_GAIN_CORRECT, -+- 0x36303636); -+- rt2800_register_write(rt2x00dev, TX0_RF_GAIN_ATTEN, -+- 0x6C6C6B6C); -+- rt2800_register_write(rt2x00dev, TX1_RF_GAIN_ATTEN, -+- 0x6C6C6B6C); -++ if (rt2800_hw_get_chippkg(rt2x00dev) == 1 && -++ rt2x00_has_cap_external_lna_bg(rt2x00dev)) -++ rt2800_bbp_glrt_write(rt2x00dev, 141, 0x15); -+ } -+ -+- if (rt2x00_has_cap_external_lna_bg(rt2x00dev)) { -+- reg = rt2800_register_read(rt2x00dev, RF_CONTROL3); -+- reg |= 0x00000101; -+- rt2800_register_write(rt2x00dev, RF_CONTROL3, reg); -+- -+- reg = rt2800_register_read(rt2x00dev, RF_BYPASS3); -+- reg |= 0x00000101; -+- rt2800_register_write(rt2x00dev, RF_BYPASS3, reg); -+- -+- rt2800_rfcsr_write_chanreg(rt2x00dev, 14, 0x66); -+- rt2800_rfcsr_write_chanreg(rt2x00dev, 17, 0x20); -+- rt2800_rfcsr_write_chanreg(rt2x00dev, 18, 0x42); -+- rt2800_bbp_write(rt2x00dev, 75, 0x68); -+- rt2800_bbp_write(rt2x00dev, 76, 0x4C); -+- rt2800_bbp_write(rt2x00dev, 79, 0x1C); -+- rt2800_bbp_write(rt2x00dev, 80, 0x0C); -+- rt2800_bbp_write(rt2x00dev, 82, 0xB6); -+- /* bank 0 RF reg 42 and glrt BBP reg 141 will be set in -+- * config channel function in dependence of channel and -+- * HT20/HT40 so don't touch it -+- */ -++ if (rt2x00dev->default_ant.rx_chain_num == 1) { -++ rt2800_bbp_write(rt2x00dev, 91, 0x07); -++ rt2800_bbp_write(rt2x00dev, 95, 0x1A); -++ rt2800_bbp_write(rt2x00dev, 195, 128); -++ rt2800_bbp_write(rt2x00dev, 196, 0xA0); -++ rt2800_bbp_write(rt2x00dev, 195, 170); -++ rt2800_bbp_write(rt2x00dev, 196, 0x12); -++ rt2800_bbp_write(rt2x00dev, 195, 171); -++ rt2800_bbp_write(rt2x00dev, 196, 0x10); -++ } else { -++ rt2800_bbp_write(rt2x00dev, 91, 0x06); -++ rt2800_bbp_write(rt2x00dev, 95, 0x9A); -++ rt2800_bbp_write(rt2x00dev, 195, 128); -++ rt2800_bbp_write(rt2x00dev, 196, 0xE0); -++ rt2800_bbp_write(rt2x00dev, 195, 170); -++ rt2800_bbp_write(rt2x00dev, 196, 0x30); -++ rt2800_bbp_write(rt2x00dev, 195, 171); -++ rt2800_bbp_write(rt2x00dev, 196, 0x30); -+ } -++ -++ /* AGC init */ -++ reg = rf->channel <= 14 ? 0x04 + 2 * rt2x00dev->lna_gain : 0; -++ rt2800_bbp_write_with_rx_chain(rt2x00dev, 66, reg); -++ -++ /* On 11A, We should delay and wait RF/BBP to be stable -++ * and the appropriate time should be 1000 micro seconds -++ * 2005/06/05 - On 11G, we also need this delay time. -++ * Otherwise it's difficult to pass the WHQL. -++ */ -++ usleep_range(1000, 1500); -+ } -+ -+ bbp = rt2800_bbp_read(rt2x00dev, 4); -+@@ -5649,43 +5615,6 @@ void rt2800_vco_calibration(struct rt2x0 -+ } -+ } -+ rt2800_register_write(rt2x00dev, TX_PIN_CFG, tx_pin); -+- -+- if (rt2x00_rt(rt2x00dev, RT6352)) { -+- if (rt2x00dev->default_ant.rx_chain_num == 1) { -+- rt2800_bbp_write(rt2x00dev, 91, 0x07); -+- rt2800_bbp_write(rt2x00dev, 95, 0x1A); -+- rt2800_bbp_write(rt2x00dev, 195, 128); -+- rt2800_bbp_write(rt2x00dev, 196, 0xA0); -+- rt2800_bbp_write(rt2x00dev, 195, 170); -+- rt2800_bbp_write(rt2x00dev, 196, 0x12); -+- rt2800_bbp_write(rt2x00dev, 195, 171); -+- rt2800_bbp_write(rt2x00dev, 196, 0x10); -+- } else { -+- rt2800_bbp_write(rt2x00dev, 91, 0x06); -+- rt2800_bbp_write(rt2x00dev, 95, 0x9A); -+- rt2800_bbp_write(rt2x00dev, 195, 128); -+- rt2800_bbp_write(rt2x00dev, 196, 0xE0); -+- rt2800_bbp_write(rt2x00dev, 195, 170); -+- rt2800_bbp_write(rt2x00dev, 196, 0x30); -+- rt2800_bbp_write(rt2x00dev, 195, 171); -+- rt2800_bbp_write(rt2x00dev, 196, 0x30); -+- } -+- -+- if (rt2x00_has_cap_external_lna_bg(rt2x00dev)) { -+- rt2800_bbp_write(rt2x00dev, 75, 0x68); -+- rt2800_bbp_write(rt2x00dev, 76, 0x4C); -+- rt2800_bbp_write(rt2x00dev, 79, 0x1C); -+- rt2800_bbp_write(rt2x00dev, 80, 0x0C); -+- rt2800_bbp_write(rt2x00dev, 82, 0xB6); -+- } -+- -+- /* On 11A, We should delay and wait RF/BBP to be stable -+- * and the appropriate time should be 1000 micro seconds -+- * 2005/06/05 - On 11G, we also need this delay time. -+- * Otherwise it's difficult to pass the WHQL. -+- */ -+- usleep_range(1000, 1500); -+- } -+ } -+ EXPORT_SYMBOL_GPL(rt2800_vco_calibration); -+ -+@@ -8650,7 +8579,7 @@ static void rt2800_r_calibration(struct -+ rt2x00_warn(rt2x00dev, "Wait MAC Tx Status to MAX !!!\n"); -+ -+ maccfg = rt2800_register_read(rt2x00dev, MAC_SYS_CTRL); -+- maccfg &= (~0x04); -++ maccfg &= (~0x08); -+ rt2800_register_write(rt2x00dev, MAC_SYS_CTRL, maccfg); -+ -+ if (unlikely(rt2800_wait_bbp_rf_ready(rt2x00dev, MAC_STATUS_CFG_BBP_RF_BUSY_RX))) -+@@ -10688,30 +10617,143 @@ static void rt2800_init_rfcsr_6352(struc -+ rt2800_rfcsr_write_dccal(rt2x00dev, 5, 0x00); -+ rt2800_rfcsr_write_dccal(rt2x00dev, 17, 0x7C); -+ } -++} -+ -+- rt6352_enable_pa_pin(rt2x00dev, 0); -+- rt2800_r_calibration(rt2x00dev); -+- rt2800_rf_self_txdc_cal(rt2x00dev); -+- rt2800_rxdcoc_calibration(rt2x00dev); -+- rt2800_bw_filter_calibration(rt2x00dev, true); -+- rt2800_bw_filter_calibration(rt2x00dev, false); -+- rt2800_loft_iq_calibration(rt2x00dev); -+- rt2800_rxiq_calibration(rt2x00dev); -+- rt6352_enable_pa_pin(rt2x00dev, 1); -++static void rt2800_init_palna_rt6352(struct rt2x00_dev *rt2x00dev) -++{ -++ u32 reg; -++ -++ if (rt2x00_has_cap_external_pa(rt2x00dev)) { -++ reg = rt2800_register_read(rt2x00dev, RF_CONTROL3); -++ reg |= 0x00000101; -++ rt2800_register_write(rt2x00dev, RF_CONTROL3, reg); -++ -++ reg = rt2800_register_read(rt2x00dev, RF_BYPASS3); -++ reg |= 0x00000101; -++ rt2800_register_write(rt2x00dev, RF_BYPASS3, reg); -++ } -+ -+- if (rt2x00_has_cap_external_lna_bg(rt2x00dev)) { -++ if (rt2800_hw_get_chippkg(rt2x00dev) == 1 && -++ rt2x00_has_cap_external_lna_bg(rt2x00dev)) { -+ rt2800_rfcsr_write_chanreg(rt2x00dev, 14, 0x66); -+ rt2800_rfcsr_write_chanreg(rt2x00dev, 17, 0x20); -+ rt2800_rfcsr_write_chanreg(rt2x00dev, 18, 0x42); -++ } -++ -++ if (rt2800_hw_get_chippkg(rt2x00dev) == 1 && -++ rt2x00_has_cap_external_pa(rt2x00dev)) { -++ rt2800_rfcsr_write_chanreg(rt2x00dev, 43, 0x73); -++ rt2800_rfcsr_write_chanreg(rt2x00dev, 44, 0x73); -++ rt2800_rfcsr_write_chanreg(rt2x00dev, 45, 0x73); -++ rt2800_rfcsr_write_chanreg(rt2x00dev, 46, 0x27); -++ rt2800_rfcsr_write_chanreg(rt2x00dev, 47, 0xC8); -++ rt2800_rfcsr_write_chanreg(rt2x00dev, 48, 0xA4); -++ rt2800_rfcsr_write_chanreg(rt2x00dev, 49, 0x05); -++ rt2800_rfcsr_write_chanreg(rt2x00dev, 54, 0x27); -++ rt2800_rfcsr_write_chanreg(rt2x00dev, 55, 0xC8); -++ rt2800_rfcsr_write_chanreg(rt2x00dev, 56, 0xA4); -++ rt2800_rfcsr_write_chanreg(rt2x00dev, 57, 0x05); -++ rt2800_rfcsr_write_chanreg(rt2x00dev, 58, 0x27); -++ rt2800_rfcsr_write_chanreg(rt2x00dev, 59, 0xC8); -++ rt2800_rfcsr_write_chanreg(rt2x00dev, 60, 0xA4); -++ rt2800_rfcsr_write_chanreg(rt2x00dev, 61, 0x05); -++ } -++ -++ if (rt2800_hw_get_chippkg(rt2x00dev) == 1 && -++ rt2x00_has_cap_external_pa(rt2x00dev)) -++ rt2800_rfcsr_write_dccal(rt2x00dev, 05, 0x00); -++ -++ if (rt2800_hw_get_chippkg(rt2x00dev) == 1 && -++ rt2x00_has_cap_external_lna_bg(rt2x00dev)) { -+ rt2800_bbp_write(rt2x00dev, 75, 0x68); -+ rt2800_bbp_write(rt2x00dev, 76, 0x4C); -+ rt2800_bbp_write(rt2x00dev, 79, 0x1C); -+ rt2800_bbp_write(rt2x00dev, 80, 0x0C); -+ rt2800_bbp_write(rt2x00dev, 82, 0xB6); -+- /* bank 0 RF reg 42 and glrt BBP reg 141 will be set in config -+- * channel function in dependence of channel and HT20/HT40, -+- * so don't touch them here. -+- */ -++ } -++ -++ if (rt2800_hw_get_chippkg(rt2x00dev) == 1 && -++ rt2x00_has_cap_external_pa(rt2x00dev)) { -++ rt2800_register_write(rt2x00dev, TX0_RF_GAIN_CORRECT, 0x36303636); -++ rt2800_register_write(rt2x00dev, TX0_RF_GAIN_ATTEN, 0x6C6C6B6C); -++ rt2800_register_write(rt2x00dev, TX1_RF_GAIN_ATTEN, 0x6C6C6B6C); -++ } -++} -++ -++static void rt2800_restore_rf_bbp_rt6352(struct rt2x00_dev *rt2x00dev) -++{ -++ if (rt2x00_has_cap_external_pa(rt2x00dev)) { -++ rt2800_register_write(rt2x00dev, RF_CONTROL3, 0x0); -++ rt2800_register_write(rt2x00dev, RF_BYPASS3, 0x0); -++ } -++ -++ if (rt2800_hw_get_chippkg(rt2x00dev) == 1 && -++ rt2x00_has_cap_external_lna_bg(rt2x00dev)) { -++ rt2800_rfcsr_write_chanreg(rt2x00dev, 14, 0x16); -++ rt2800_rfcsr_write_chanreg(rt2x00dev, 17, 0x23); -++ rt2800_rfcsr_write_chanreg(rt2x00dev, 18, 0x02); -++ } -++ -++ if (rt2800_hw_get_chippkg(rt2x00dev) == 1 && -++ rt2x00_has_cap_external_pa(rt2x00dev)) { -++ rt2800_rfcsr_write_chanreg(rt2x00dev, 43, 0xD3); -++ rt2800_rfcsr_write_chanreg(rt2x00dev, 44, 0xB3); -++ rt2800_rfcsr_write_chanreg(rt2x00dev, 45, 0xD5); -++ rt2800_rfcsr_write_chanreg(rt2x00dev, 46, 0x27); -++ rt2800_rfcsr_write_chanreg(rt2x00dev, 47, 0x6C); -++ rt2800_rfcsr_write_chanreg(rt2x00dev, 48, 0xFC); -++ rt2800_rfcsr_write_chanreg(rt2x00dev, 49, 0x1F); -++ rt2800_rfcsr_write_chanreg(rt2x00dev, 54, 0x27); -++ rt2800_rfcsr_write_chanreg(rt2x00dev, 55, 0x66); -++ rt2800_rfcsr_write_chanreg(rt2x00dev, 56, 0xFF); -++ rt2800_rfcsr_write_chanreg(rt2x00dev, 57, 0x1C); -++ rt2800_rfcsr_write_chanreg(rt2x00dev, 58, 0x20); -++ rt2800_rfcsr_write_chanreg(rt2x00dev, 59, 0x6B); -++ rt2800_rfcsr_write_chanreg(rt2x00dev, 60, 0xF7); -++ rt2800_rfcsr_write_chanreg(rt2x00dev, 61, 0x09); -++ } -++ -++ if (rt2800_hw_get_chippkg(rt2x00dev) == 1 && -++ rt2x00_has_cap_external_lna_bg(rt2x00dev)) { -++ rt2800_bbp_write(rt2x00dev, 75, 0x60); -++ rt2800_bbp_write(rt2x00dev, 76, 0x44); -++ rt2800_bbp_write(rt2x00dev, 79, 0x1C); -++ rt2800_bbp_write(rt2x00dev, 80, 0x0C); -++ rt2800_bbp_write(rt2x00dev, 82, 0xB6); -++ } -++ -++ if (rt2800_hw_get_chippkg(rt2x00dev) == 1 && -++ rt2x00_has_cap_external_pa(rt2x00dev)) { -++ rt2800_register_write(rt2x00dev, TX0_RF_GAIN_CORRECT, 0x3630363A); -++ rt2800_register_write(rt2x00dev, TX0_RF_GAIN_ATTEN, 0x6C6C666C); -++ rt2800_register_write(rt2x00dev, TX1_RF_GAIN_ATTEN, 0x6C6C666C); -++ } -++} -++ -++static void rt2800_calibration_rt6352(struct rt2x00_dev *rt2x00dev) -++{ -++ if (rt2x00_has_cap_external_pa(rt2x00dev) || -++ rt2x00_has_cap_external_lna_bg(rt2x00dev)) { -++ rt6352_enable_pa_pin(rt2x00dev, 0); -++ rt2800_restore_rf_bbp_rt6352(rt2x00dev); -++ } -++ -++ rt2800_r_calibration(rt2x00dev); -++ rt2800_rf_self_txdc_cal(rt2x00dev); -++ rt2800_rxdcoc_calibration(rt2x00dev); -++ rt2800_bw_filter_calibration(rt2x00dev, true); -++ rt2800_bw_filter_calibration(rt2x00dev, false); -++ rt2800_loft_iq_calibration(rt2x00dev); -++ -++ /* missing DPD Calibration for devices using internal PA */ -++ -++ rt2800_rxdcoc_calibration(rt2x00dev); -++ rt2800_rxiq_calibration(rt2x00dev); -++ -++ if (rt2x00_has_cap_external_pa(rt2x00dev) || -++ rt2x00_has_cap_external_lna_bg(rt2x00dev)) { -++ rt6352_enable_pa_pin(rt2x00dev, 1); -++ rt2800_init_palna_rt6352(rt2x00dev); -+ } -+ } -+ -+@@ -10804,6 +10846,10 @@ int rt2800_enable_radio(struct rt2x00_de -+ rt2800_init_bbp(rt2x00dev); -+ rt2800_init_rfcsr(rt2x00dev); -+ -++ /* Do calibration and init PA/LNA for RT6352 */ -++ if (rt2x00_rt(rt2x00dev, RT6352)) -++ rt2800_calibration_rt6352(rt2x00dev); -++ -+ if (rt2x00_is_usb(rt2x00dev) && -+ (rt2x00_rt(rt2x00dev, RT3070) || -+ rt2x00_rt(rt2x00dev, RT3071) || -+--- a/drivers/net/wireless/ralink/rt2x00/rt2x00.h -++++ b/drivers/net/wireless/ralink/rt2x00/rt2x00.h -+@@ -1277,6 +1277,12 @@ rt2x00_has_cap_external_lna_bg(struct rt -+ } -+ -+ static inline bool -++rt2x00_has_cap_external_pa(struct rt2x00_dev *rt2x00dev) -++{ -++ return rt2x00_has_cap_flag(rt2x00dev, CAPABILITY_EXTERNAL_PA_TX0); -++} -++ -++static inline bool -+ rt2x00_has_cap_double_antenna(struct rt2x00_dev *rt2x00dev) -+ { -+ return rt2x00_has_cap_flag(rt2x00dev, CAPABILITY_DOUBLE_ANTENNA); -diff --git a/package/kernel/mac80211/patches/subsys/110-mac80211_keep_keys_on_stop_ap.patch b/package/kernel/mac80211/patches/subsys/110-mac80211_keep_keys_on_stop_ap.patch -new file mode 100644 -index 0000000000..4d4a2a8f5e ---- /dev/null -+++ b/package/kernel/mac80211/patches/subsys/110-mac80211_keep_keys_on_stop_ap.patch -@@ -0,0 +1,19 @@ -+From: Felix Fietkau -+Date: Mon, 27 Oct 2014 00:00:00 +0100 -+Subject: [PATCH] mac80211: preseve AP mode keys across STA reconnect -+ -+Used for AP+STA support in OpenWrt - preserve AP mode keys across STA reconnect -+--- -+ net/mac80211/cfg.c | 1 - -+ 1 file changed, 1 deletion(-) -+ -+--- a/net/mac80211/cfg.c -++++ b/net/mac80211/cfg.c -+@@ -1519,7 +1519,6 @@ static int ieee80211_stop_ap(struct wiph -+ link_conf->bssid_indicator = 0; -+ -+ __sta_info_flush(sdata, true); -+- ieee80211_free_keys(sdata, true); -+ -+ link_conf->enable_beacon = false; -+ sdata->beacon_rate_set = false; -diff --git a/package/kernel/mac80211/patches/subsys/120-cfg80211_allow_perm_addr_change.patch b/package/kernel/mac80211/patches/subsys/120-cfg80211_allow_perm_addr_change.patch -new file mode 100644 -index 0000000000..f315ae5ca2 ---- /dev/null -+++ b/package/kernel/mac80211/patches/subsys/120-cfg80211_allow_perm_addr_change.patch -@@ -0,0 +1,52 @@ -+From: Felix Fietkau -+Date: Thu, 11 Dec 2014 00:00:00 +0100 -+Subject: [PATCH] cfg80211: add support for changing the device mac address via -+ sysfs -+ -+--- -+ net/wireless/sysfs.c | 27 ++++++++++++++++++++++----- -+ 1 file changed, 22 insertions(+), 5 deletions(-) -+ -+--- a/net/wireless/sysfs.c -++++ b/net/wireless/sysfs.c -+@@ -24,18 +24,35 @@ static inline struct cfg80211_registered -+ return container_of(dev, struct cfg80211_registered_device, wiphy.dev); -+ } -+ -+-#define SHOW_FMT(name, fmt, member) \ -++#define SHOW_FMT(name, fmt, member, mode) \ -+ static ssize_t name ## _show(struct device *dev, \ -+ struct device_attribute *attr, \ -+ char *buf) \ -+ { \ -+ return sprintf(buf, fmt "\n", dev_to_rdev(dev)->member); \ -+ } \ -+-static DEVICE_ATTR_RO(name) -++static DEVICE_ATTR_##mode(name) -+ -+-SHOW_FMT(index, "%d", wiphy_idx); -+-SHOW_FMT(macaddress, "%pM", wiphy.perm_addr); -+-SHOW_FMT(address_mask, "%pM", wiphy.addr_mask); -++static ssize_t macaddress_store(struct device *dev, -++ struct device_attribute *attr, -++ const char *buf, size_t len) -++{ -++ u8 mac[ETH_ALEN]; -++ -++ if (!mac_pton(buf, mac)) -++ return -EINVAL; -++ -++ if (buf[3 * ETH_ALEN - 1] && buf[3 * ETH_ALEN - 1] != '\n') -++ return -EINVAL; -++ -++ memcpy(dev_to_rdev(dev)->wiphy.perm_addr, mac, ETH_ALEN); -++ -++ return strnlen(buf, len); -++} -++ -++SHOW_FMT(index, "%d", wiphy_idx, RO); -++SHOW_FMT(macaddress, "%pM", wiphy.perm_addr, RW); -++SHOW_FMT(address_mask, "%pM", wiphy.addr_mask, RO); -+ -+ static ssize_t name_show(struct device *dev, -+ struct device_attribute *attr, -diff --git a/package/kernel/mac80211/patches/subsys/210-ap_scan.patch b/package/kernel/mac80211/patches/subsys/210-ap_scan.patch -new file mode 100644 -index 0000000000..10b842d9af ---- /dev/null -+++ b/package/kernel/mac80211/patches/subsys/210-ap_scan.patch -@@ -0,0 +1,19 @@ -+From: Felix Fietkau -+Date: Wed, 3 Oct 2012 00:00:00 +0200 -+Subject: [PATCH] mac80211: allow scans in access point mode (for site survey) -+ -+--- -+ net/mac80211/cfg.c | 2 +- -+ 1 file changed, 1 insertion(+), 1 deletion(-) -+ -+--- a/net/mac80211/cfg.c -++++ b/net/mac80211/cfg.c -+@@ -2727,6 +2727,8 @@ static int ieee80211_scan(struct wiphy * -+ */ -+ fallthrough; -+ case NL80211_IFTYPE_AP: -++ /* skip check */ -++ break; -+ /* -+ * If the scan has been forced (and the driver supports -+ * forcing), don't care about being beaconing already. -diff --git a/package/kernel/mac80211/patches/subsys/301-mac80211-sta-randomize-BA-session-dialog-token-alloc.patch b/package/kernel/mac80211/patches/subsys/301-mac80211-sta-randomize-BA-session-dialog-token-alloc.patch -new file mode 100644 -index 0000000000..63b2177471 ---- /dev/null -+++ b/package/kernel/mac80211/patches/subsys/301-mac80211-sta-randomize-BA-session-dialog-token-alloc.patch -@@ -0,0 +1,38 @@ -+From b478e06a16a8baa00c5ecc87c1d636981f2206d5 Mon Sep 17 00:00:00 2001 -+From: Johannes Berg -+Date: Tue, 29 Oct 2019 10:25:25 +0100 -+Subject: [PATCH] mac80211: sta: randomize BA session dialog token allocator -+ -+We currently always start the dialog token generator at zero, -+so the first dialog token we use is always 1. This would be -+OK if we had a perfect guarantee that we always do a proper -+deauth/re-auth handshake, but in IBSS mode this doesn't always -+happen properly. -+ -+To make problems with block ack (aggregation) sessions getting -+stuck less likely, randomize the dialog token so if we start a -+new session but the peer still has old state for us, it can -+better detect this. -+ -+This is really just a workaround to make things a bit more -+robust than they are now - a better fix would be to do a full -+authentication handshake in IBSS mode upon having discovered a -+new station, and on the receiver resetting the state (removing -+and re-adding the station) on receiving the authentication -+packet. -+ -+Signed-off-by: Johannes Berg -+--- -+ net/mac80211/sta_info.c | 1 + -+ 1 file changed, 1 insertion(+) -+ -+--- a/net/mac80211/sta_info.c -++++ b/net/mac80211/sta_info.c -+@@ -554,6 +554,7 @@ __sta_info_alloc(struct ieee80211_sub_if -+ INIT_WORK(&sta->drv_deliver_wk, sta_deliver_ps_frames); -+ INIT_WORK(&sta->ampdu_mlme.work, ieee80211_ba_session_work); -+ mutex_init(&sta->ampdu_mlme.mtx); -++ sta->ampdu_mlme.dialog_token_allocator = prandom_u32_max(U8_MAX); -+ #ifdef CPTCFG_MAC80211_MESH -+ if (ieee80211_vif_is_mesh(&sdata->vif)) { -+ sta->mesh = kzalloc(sizeof(*sta->mesh), gfp); -diff --git a/package/kernel/mac80211/patches/subsys/302-mac80211-minstrel_ht-fix-MINSTREL_FRAC-macro.patch b/package/kernel/mac80211/patches/subsys/302-mac80211-minstrel_ht-fix-MINSTREL_FRAC-macro.patch -new file mode 100644 -index 0000000000..0d475b7329 ---- /dev/null -+++ b/package/kernel/mac80211/patches/subsys/302-mac80211-minstrel_ht-fix-MINSTREL_FRAC-macro.patch -@@ -0,0 +1,21 @@ -+From: Felix Fietkau -+Date: Wed, 28 Apr 2021 21:03:13 +0200 -+Subject: [PATCH] mac80211: minstrel_ht: fix MINSTREL_FRAC macro -+ -+Add missing braces to avoid issues with e.g. using additions in the -+div expression -+ -+Signed-off-by: Felix Fietkau -+--- -+ -+--- a/net/mac80211/rc80211_minstrel_ht.h -++++ b/net/mac80211/rc80211_minstrel_ht.h -+@@ -14,7 +14,7 @@ -+ -+ /* scaled fraction values */ -+ #define MINSTREL_SCALE 12 -+-#define MINSTREL_FRAC(val, div) (((val) << MINSTREL_SCALE) / div) -++#define MINSTREL_FRAC(val, div) (((val) << MINSTREL_SCALE) / (div)) -+ #define MINSTREL_TRUNC(val) ((val) >> MINSTREL_SCALE) -+ -+ #define EWMA_LEVEL 96 /* ewma weighting factor [/EWMA_DIV] */ -diff --git a/package/kernel/mac80211/patches/subsys/303-mac80211-minstrel_ht-reduce-fluctuations-in-rate-pro.patch b/package/kernel/mac80211/patches/subsys/303-mac80211-minstrel_ht-reduce-fluctuations-in-rate-pro.patch -new file mode 100644 -index 0000000000..f26477e811 ---- /dev/null -+++ b/package/kernel/mac80211/patches/subsys/303-mac80211-minstrel_ht-reduce-fluctuations-in-rate-pro.patch -@@ -0,0 +1,30 @@ -+From: Felix Fietkau -+Date: Sat, 6 Feb 2021 16:08:01 +0100 -+Subject: [PATCH] mac80211: minstrel_ht: reduce fluctuations in rate -+ probability stats -+ -+In some scenarios when there is a lot of fluctuation in packet error rates, -+rate switching can be amplified when the statistics get skewed by time slots -+with very few tries. -+Make the input data to the moving average more smooth by adding the -+success/attempts count from the last stats window as well. This has the -+advantage of smoothing the data without introducing any extra lag to sampling -+rates. -+This significantly improves rate stability on a strong test link subjected to -+periodic noise bursts generated with a SDR -+ -+Signed-off-by: Felix Fietkau -+--- -+ -+--- a/net/mac80211/rc80211_minstrel_ht.c -++++ b/net/mac80211/rc80211_minstrel_ht.c -+@@ -769,7 +769,8 @@ minstrel_ht_calc_rate_stats(struct minst -+ unsigned int cur_prob; -+ -+ if (unlikely(mrs->attempts > 0)) { -+- cur_prob = MINSTREL_FRAC(mrs->success, mrs->attempts); -++ cur_prob = MINSTREL_FRAC(mrs->success + mrs->last_success, -++ mrs->attempts + mrs->last_attempts); -+ minstrel_filter_avg_add(&mrs->prob_avg, -+ &mrs->prob_avg_1, cur_prob); -+ mrs->att_hist += mrs->attempts; -diff --git a/package/kernel/mac80211/patches/subsys/304-mac80211-minstrel_ht-rework-rate-downgrade-code-and-.patch b/package/kernel/mac80211/patches/subsys/304-mac80211-minstrel_ht-rework-rate-downgrade-code-and-.patch -new file mode 100644 -index 0000000000..9b3cc3a664 ---- /dev/null -+++ b/package/kernel/mac80211/patches/subsys/304-mac80211-minstrel_ht-rework-rate-downgrade-code-and-.patch -@@ -0,0 +1,151 @@ -+From: Felix Fietkau -+Date: Sat, 6 Feb 2021 16:33:14 +0100 -+Subject: [PATCH] mac80211: minstrel_ht: rework rate downgrade code and -+ max_prob rate selection -+ -+The current fallback code for fast rate switching on potentially failing rates -+is triggering too often if there is some strong noise on the channel. This can -+lead to wild fluctuations in the rate selection. -+Additionally, switching down to max_prob_rate can create a significant gap down -+in throughput, especially when using only 2 spatial streams, because max_prob_rate -+is limited to using fewer streams than the max_tp rates. -+In order to improve throughput without reducing reliability too much, use the -+rate downgrade code for the max_prob_rate only, and allow the non-downgraded -+max_prob_rate to use as many spatial streams as the max_tp rates -+ -+Signed-off-by: Felix Fietkau -+--- -+ -+--- a/net/mac80211/rc80211_minstrel_ht.c -++++ b/net/mac80211/rc80211_minstrel_ht.c -+@@ -580,6 +580,14 @@ minstrel_ht_set_best_prob_rate(struct mi -+ int cur_tp_avg, cur_group, cur_idx; -+ int max_gpr_group, max_gpr_idx; -+ int max_gpr_tp_avg, max_gpr_prob; -++ int min_dur; -++ -++ min_dur = max(minstrel_get_duration(mi->max_tp_rate[0]), -++ minstrel_get_duration(mi->max_tp_rate[1])); -++ -++ /* make the rate at least 18% slower than max tp rates */ -++ if (minstrel_get_duration(index) <= min_dur * 19 / 16) -++ return; -+ -+ cur_group = MI_RATE_GROUP(index); -+ cur_idx = MI_RATE_IDX(index); -+@@ -601,11 +609,6 @@ minstrel_ht_set_best_prob_rate(struct mi -+ !minstrel_ht_is_legacy_group(max_tp_group)) -+ return; -+ -+- /* skip rates faster than max tp rate with lower prob */ -+- if (minstrel_get_duration(mi->max_tp_rate[0]) > minstrel_get_duration(index) && -+- mrs->prob_avg < max_tp_prob) -+- return; -+- -+ max_gpr_group = MI_RATE_GROUP(mg->max_group_prob_rate); -+ max_gpr_idx = MI_RATE_IDX(mg->max_group_prob_rate); -+ max_gpr_prob = mi->groups[max_gpr_group].rates[max_gpr_idx].prob_avg; -+@@ -663,40 +666,6 @@ minstrel_ht_assign_best_tp_rates(struct -+ -+ } -+ -+-/* -+- * Try to increase robustness of max_prob rate by decrease number of -+- * streams if possible. -+- */ -+-static inline void -+-minstrel_ht_prob_rate_reduce_streams(struct minstrel_ht_sta *mi) -+-{ -+- struct minstrel_mcs_group_data *mg; -+- int tmp_max_streams, group, tmp_idx, tmp_prob; -+- int tmp_tp = 0; -+- -+- if (!mi->sta->deflink.ht_cap.ht_supported) -+- return; -+- -+- group = MI_RATE_GROUP(mi->max_tp_rate[0]); -+- tmp_max_streams = minstrel_mcs_groups[group].streams; -+- for (group = 0; group < ARRAY_SIZE(minstrel_mcs_groups); group++) { -+- mg = &mi->groups[group]; -+- if (!mi->supported[group] || group == MINSTREL_CCK_GROUP) -+- continue; -+- -+- tmp_idx = MI_RATE_IDX(mg->max_group_prob_rate); -+- tmp_prob = mi->groups[group].rates[tmp_idx].prob_avg; -+- -+- if (tmp_tp < minstrel_ht_get_tp_avg(mi, group, tmp_idx, tmp_prob) && -+- (minstrel_mcs_groups[group].streams < tmp_max_streams)) { -+- mi->max_prob_rate = mg->max_group_prob_rate; -+- tmp_tp = minstrel_ht_get_tp_avg(mi, group, -+- tmp_idx, -+- tmp_prob); -+- } -+- } -+-} -+- -+ static u16 -+ __minstrel_ht_get_sample_rate(struct minstrel_ht_sta *mi, -+ enum minstrel_sample_type type) -+@@ -1176,8 +1145,6 @@ minstrel_ht_update_stats(struct minstrel -+ -+ mi->max_prob_rate = tmp_max_prob_rate; -+ -+- /* Try to increase robustness of max_prob_rate*/ -+- minstrel_ht_prob_rate_reduce_streams(mi); -+ minstrel_ht_refill_sample_rates(mi); -+ -+ #ifdef CPTCFG_MAC80211_DEBUGFS -+@@ -1256,7 +1223,7 @@ minstrel_ht_ri_txstat_valid(struct minst -+ } -+ -+ static void -+-minstrel_downgrade_rate(struct minstrel_ht_sta *mi, u16 *idx, bool primary) -++minstrel_downgrade_prob_rate(struct minstrel_ht_sta *mi, u16 *idx) -+ { -+ int group, orig_group; -+ -+@@ -1271,11 +1238,7 @@ minstrel_downgrade_rate(struct minstrel_ -+ minstrel_mcs_groups[orig_group].streams) -+ continue; -+ -+- if (primary) -+- *idx = mi->groups[group].max_group_tp_rate[0]; -+- else -+- *idx = mi->groups[group].max_group_tp_rate[1]; -+- break; -++ *idx = mi->groups[group].max_group_prob_rate; -+ } -+ } -+ -+@@ -1286,7 +1249,7 @@ minstrel_ht_tx_status(void *priv, struct -+ struct ieee80211_tx_info *info = st->info; -+ struct minstrel_ht_sta *mi = priv_sta; -+ struct ieee80211_tx_rate *ar = info->status.rates; -+- struct minstrel_rate_stats *rate, *rate2; -++ struct minstrel_rate_stats *rate; -+ struct minstrel_priv *mp = priv; -+ u32 update_interval = mp->update_interval; -+ bool last, update = false; -+@@ -1354,18 +1317,13 @@ minstrel_ht_tx_status(void *priv, struct -+ /* -+ * check for sudden death of spatial multiplexing, -+ * downgrade to a lower number of streams if necessary. -++ * only do this for the max_prob_rate to prevent spurious -++ * rate fluctuations when the link changes suddenly -+ */ -+- rate = minstrel_get_ratestats(mi, mi->max_tp_rate[0]); -++ rate = minstrel_get_ratestats(mi, mi->max_prob_rate); -+ if (rate->attempts > 30 && -+ rate->success < rate->attempts / 4) { -+- minstrel_downgrade_rate(mi, &mi->max_tp_rate[0], true); -+- update = true; -+- } -+- -+- rate2 = minstrel_get_ratestats(mi, mi->max_tp_rate[1]); -+- if (rate2->attempts > 30 && -+- rate2->success < rate2->attempts / 4) { -+- minstrel_downgrade_rate(mi, &mi->max_tp_rate[1], false); -++ minstrel_downgrade_prob_rate(mi, &mi->max_prob_rate); -+ update = true; -+ } -+ } -diff --git a/package/kernel/mac80211/patches/subsys/305-mac80211-increase-quantum-for-airtime-scheduler.patch b/package/kernel/mac80211/patches/subsys/305-mac80211-increase-quantum-for-airtime-scheduler.patch -new file mode 100644 -index 0000000000..0ac972955f ---- /dev/null -+++ b/package/kernel/mac80211/patches/subsys/305-mac80211-increase-quantum-for-airtime-scheduler.patch -@@ -0,0 +1,53 @@ -+From: Felix Fietkau -+Date: Sun, 26 Jun 2022 11:43:25 +0200 -+Subject: [PATCH] mac80211: increase quantum for airtime scheduler -+ -+Given the typical AQL budget and queue length, a quantum of 256 with the -+default station weight often requires iterating over all queues frequently, -+until one of them becomes eligible. -+Improve performance by using 8 times station weight as scheduler quantum -+ -+Signed-off-by: Felix Fietkau -+--- -+ -+--- a/net/mac80211/ieee80211_i.h -++++ b/net/mac80211/ieee80211_i.h -+@@ -90,6 +90,8 @@ extern const u8 ieee80211_ac_to_qos_mask -+ */ -+ #define AIRTIME_ACTIVE_DURATION (HZ / 10) -+ -++#define AIRTIME_QUANTUM_SHIFT 3 -++ -+ struct ieee80211_bss { -+ u32 device_ts_beacon, device_ts_presp; -+ -+--- a/net/mac80211/tx.c -++++ b/net/mac80211/tx.c -+@@ -3984,7 +3984,7 @@ struct ieee80211_txq *ieee80211_next_txq -+ -+ if (deficit < 0) -+ sta->airtime[txqi->txq.ac].deficit += -+- sta->airtime_weight; -++ sta->airtime_weight << AIRTIME_QUANTUM_SHIFT; -+ -+ if (deficit < 0 || !aql_check) { -+ list_move_tail(&txqi->schedule_order, -+@@ -4127,7 +4127,8 @@ bool ieee80211_txq_may_transmit(struct i -+ } -+ sta = container_of(iter->txq.sta, struct sta_info, sta); -+ if (ieee80211_sta_deficit(sta, ac) < 0) -+- sta->airtime[ac].deficit += sta->airtime_weight; -++ sta->airtime[ac].deficit += sta->airtime_weight << -++ AIRTIME_QUANTUM_SHIFT; -+ list_move_tail(&iter->schedule_order, &local->active_txqs[ac]); -+ } -+ -+@@ -4135,7 +4136,7 @@ bool ieee80211_txq_may_transmit(struct i -+ if (sta->airtime[ac].deficit >= 0) -+ goto out; -+ -+- sta->airtime[ac].deficit += sta->airtime_weight; -++ sta->airtime[ac].deficit += sta->airtime_weight << AIRTIME_QUANTUM_SHIFT; -+ list_move_tail(&txqi->schedule_order, &local->active_txqs[ac]); -+ spin_unlock_bh(&local->active_txq_lock[ac]); -+ -diff --git a/package/kernel/mac80211/patches/subsys/306-01-v6.2-wifi-mac80211-add-internal-handler-for-wake_tx_queue.patch b/package/kernel/mac80211/patches/subsys/306-01-v6.2-wifi-mac80211-add-internal-handler-for-wake_tx_queue.patch -new file mode 100644 -index 0000000000..d14ba05e69 ---- /dev/null -+++ b/package/kernel/mac80211/patches/subsys/306-01-v6.2-wifi-mac80211-add-internal-handler-for-wake_tx_queue.patch -@@ -0,0 +1,183 @@ -+From: Alexander Wetzel -+Date: Sun, 9 Oct 2022 18:30:38 +0200 -+Subject: [PATCH] wifi: mac80211: add internal handler for wake_tx_queue -+ -+Start to align the TX handling to only use internal TX queues (iTXQs): -+ -+Provide a handler for drivers not having a custom wake_tx_queue -+callback and update the documentation. -+ -+Signed-off-by: Alexander Wetzel -+Signed-off-by: Johannes Berg -+--- -+ -+--- a/include/net/mac80211.h -++++ b/include/net/mac80211.h -+@@ -89,15 +89,13 @@ -+ /** -+ * DOC: mac80211 software tx queueing -+ * -+- * mac80211 provides an optional intermediate queueing implementation designed -+- * to allow the driver to keep hardware queues short and provide some fairness -+- * between different stations/interfaces. -+- * In this model, the driver pulls data frames from the mac80211 queue instead -+- * of letting mac80211 push them via drv_tx(). -+- * Other frames (e.g. control or management) are still pushed using drv_tx(). -++ * mac80211 uses an intermediate queueing implementation, designed to allow the -++ * driver to keep hardware queues short and to provide some fairness between -++ * different stations/interfaces. -+ * -+- * Drivers indicate that they use this model by implementing the .wake_tx_queue -+- * driver operation. -++ * Drivers must provide the .wake_tx_queue driver operation by either -++ * linking it to ieee80211_handle_wake_tx_queue() or implementing a custom -++ * handler. -+ * -+ * Intermediate queues (struct ieee80211_txq) are kept per-sta per-tid, with -+ * another per-sta for non-data/non-mgmt and bufferable management frames, and -+@@ -106,9 +104,12 @@ -+ * The driver is expected to initialize its private per-queue data for stations -+ * and interfaces in the .add_interface and .sta_add ops. -+ * -+- * The driver can't access the queue directly. To dequeue a frame from a -+- * txq, it calls ieee80211_tx_dequeue(). Whenever mac80211 adds a new frame to a -+- * queue, it calls the .wake_tx_queue driver op. -++ * The driver can't access the internal TX queues (iTXQs) directly. -++ * Whenever mac80211 adds a new frame to a queue, it calls the .wake_tx_queue -++ * driver op. -++ * Drivers implementing a custom .wake_tx_queue op can get them by calling -++ * ieee80211_tx_dequeue(). Drivers using ieee80211_handle_wake_tx_queue() will -++ * simply get the individual frames pushed via the .tx driver operation. -+ * -+ * Drivers can optionally delegate responsibility for scheduling queues to -+ * mac80211, to take advantage of airtime fairness accounting. In this case, to -+@@ -2248,8 +2249,8 @@ struct ieee80211_link_sta { -+ * For non MLO STA it will point to the deflink data. For MLO STA -+ * ieee80211_sta_recalc_aggregates() must be called to update it. -+ * @support_p2p_ps: indicates whether the STA supports P2P PS mechanism or not. -+- * @txq: per-TID data TX queues (if driver uses the TXQ abstraction); note that -+- * the last entry (%IEEE80211_NUM_TIDS) is used for non-data frames -++ * @txq: per-TID data TX queues; note that the last entry (%IEEE80211_NUM_TIDS) -++ * is used for non-data frames -+ * @deflink: This holds the default link STA information, for non MLO STA all link -+ * specific STA information is accessed through @deflink or through -+ * link[0] which points to address of @deflink. For MLO Link STA -+@@ -5687,7 +5688,7 @@ void ieee80211_key_replay(struct ieee802 -+ * @hw: pointer as obtained from ieee80211_alloc_hw(). -+ * @queue: queue number (counted from zero). -+ * -+- * Drivers should use this function instead of netif_wake_queue. -++ * Drivers must use this function instead of netif_wake_queue. -+ */ -+ void ieee80211_wake_queue(struct ieee80211_hw *hw, int queue); -+ -+@@ -5696,7 +5697,7 @@ void ieee80211_wake_queue(struct ieee802 -+ * @hw: pointer as obtained from ieee80211_alloc_hw(). -+ * @queue: queue number (counted from zero). -+ * -+- * Drivers should use this function instead of netif_stop_queue. -++ * Drivers must use this function instead of netif_stop_queue. -+ */ -+ void ieee80211_stop_queue(struct ieee80211_hw *hw, int queue); -+ -+@@ -5705,7 +5706,7 @@ void ieee80211_stop_queue(struct ieee802 -+ * @hw: pointer as obtained from ieee80211_alloc_hw(). -+ * @queue: queue number (counted from zero). -+ * -+- * Drivers should use this function instead of netif_stop_queue. -++ * Drivers must use this function instead of netif_queue_stopped. -+ * -+ * Return: %true if the queue is stopped. %false otherwise. -+ */ -+@@ -5716,7 +5717,7 @@ int ieee80211_queue_stopped(struct ieee8 -+ * ieee80211_stop_queues - stop all queues -+ * @hw: pointer as obtained from ieee80211_alloc_hw(). -+ * -+- * Drivers should use this function instead of netif_stop_queue. -++ * Drivers must use this function instead of netif_tx_stop_all_queues. -+ */ -+ void ieee80211_stop_queues(struct ieee80211_hw *hw); -+ -+@@ -5724,7 +5725,7 @@ void ieee80211_stop_queues(struct ieee80 -+ * ieee80211_wake_queues - wake all queues -+ * @hw: pointer as obtained from ieee80211_alloc_hw(). -+ * -+- * Drivers should use this function instead of netif_wake_queue. -++ * Drivers must use this function instead of netif_tx_wake_all_queues. -+ */ -+ void ieee80211_wake_queues(struct ieee80211_hw *hw); -+ -+@@ -6946,6 +6947,18 @@ static inline struct sk_buff *ieee80211_ -+ } -+ -+ /** -++ * ieee80211_handle_wake_tx_queue - mac80211 handler for wake_tx_queue callback -++ * -++ * @hw: pointer as obtained from wake_tx_queue() callback(). -++ * @txq: pointer as obtained from wake_tx_queue() callback(). -++ * -++ * Drivers can use this function for the mandatory mac80211 wake_tx_queue -++ * callback in struct ieee80211_ops. They should not call this function. -++ */ -++void ieee80211_handle_wake_tx_queue(struct ieee80211_hw *hw, -++ struct ieee80211_txq *txq); -++ -++/** -+ * ieee80211_next_txq - get next tx queue to pull packets from -+ * -+ * @hw: pointer as obtained from ieee80211_alloc_hw() -+--- a/net/mac80211/util.c -++++ b/net/mac80211/util.c -+@@ -288,6 +288,52 @@ __le16 ieee80211_ctstoself_duration(stru -+ } -+ EXPORT_SYMBOL(ieee80211_ctstoself_duration); -+ -++static void wake_tx_push_queue(struct ieee80211_local *local, -++ struct ieee80211_sub_if_data *sdata, -++ struct ieee80211_txq *queue) -++{ -++ int q = sdata->vif.hw_queue[queue->ac]; -++ struct ieee80211_tx_control control = { -++ .sta = queue->sta, -++ }; -++ struct sk_buff *skb; -++ unsigned long flags; -++ bool q_stopped; -++ -++ while (1) { -++ spin_lock_irqsave(&local->queue_stop_reason_lock, flags); -++ q_stopped = local->queue_stop_reasons[q]; -++ spin_unlock_irqrestore(&local->queue_stop_reason_lock, flags); -++ -++ if (q_stopped) -++ break; -++ -++ skb = ieee80211_tx_dequeue(&local->hw, queue); -++ if (!skb) -++ break; -++ -++ drv_tx(local, &control, skb); -++ } -++} -++ -++/* wake_tx_queue handler for driver not implementing a custom one*/ -++void ieee80211_handle_wake_tx_queue(struct ieee80211_hw *hw, -++ struct ieee80211_txq *txq) -++{ -++ struct ieee80211_local *local = hw_to_local(hw); -++ struct ieee80211_sub_if_data *sdata = vif_to_sdata(txq->vif); -++ struct ieee80211_txq *queue; -++ -++ /* Use ieee80211_next_txq() for airtime fairness accounting */ -++ ieee80211_txq_schedule_start(hw, txq->ac); -++ while ((queue = ieee80211_next_txq(hw, txq->ac))) { -++ wake_tx_push_queue(local, sdata, queue); -++ ieee80211_return_txq(hw, queue, false); -++ } -++ ieee80211_txq_schedule_end(hw, txq->ac); -++} -++EXPORT_SYMBOL(ieee80211_handle_wake_tx_queue); -++ -+ static void __ieee80211_wake_txqs(struct ieee80211_sub_if_data *sdata, int ac) -+ { -+ struct ieee80211_local *local = sdata->local; -diff --git a/package/kernel/mac80211/patches/subsys/306-02-v6.2-wifi-mac80211-add-wake_tx_queue-callback-to-drivers.patch b/package/kernel/mac80211/patches/subsys/306-02-v6.2-wifi-mac80211-add-wake_tx_queue-callback-to-drivers.patch -new file mode 100644 -index 0000000000..fee038d90c ---- /dev/null -+++ b/package/kernel/mac80211/patches/subsys/306-02-v6.2-wifi-mac80211-add-wake_tx_queue-callback-to-drivers.patch -@@ -0,0 +1,396 @@ -+From: Alexander Wetzel -+Date: Sun, 9 Oct 2022 18:30:39 +0200 -+Subject: [PATCH] wifi: mac80211: add wake_tx_queue callback to drivers -+ -+mac80211 is fully switching over to the internal TX queue (iTXQ) -+implementation. Update all drivers not yet providing the now mandatory -+wake_tx_queue() callback. -+ -+As an side effect the netdev interfaces of all updated drivers will -+switch to the noqueue qdisc. -+ -+Signed-off-by: Alexander Wetzel -+[add staging drivers] -+Signed-off-by: Johannes Berg -+--- -+ -+--- a/drivers/net/wireless/admtek/adm8211.c -++++ b/drivers/net/wireless/admtek/adm8211.c -+@@ -1760,6 +1760,7 @@ static int adm8211_alloc_rings(struct ie -+ -+ static const struct ieee80211_ops adm8211_ops = { -+ .tx = adm8211_tx, -++ .wake_tx_queue = ieee80211_handle_wake_tx_queue, -+ .start = adm8211_start, -+ .stop = adm8211_stop, -+ .add_interface = adm8211_add_interface, -+--- a/drivers/net/wireless/ath/ar5523/ar5523.c -++++ b/drivers/net/wireless/ath/ar5523/ar5523.c -+@@ -1361,6 +1361,7 @@ static const struct ieee80211_ops ar5523 -+ .start = ar5523_start, -+ .stop = ar5523_stop, -+ .tx = ar5523_tx, -++ .wake_tx_queue = ieee80211_handle_wake_tx_queue, -+ .set_rts_threshold = ar5523_set_rts_threshold, -+ .add_interface = ar5523_add_interface, -+ .remove_interface = ar5523_remove_interface, -+--- a/drivers/net/wireless/ath/ath11k/mac.c -++++ b/drivers/net/wireless/ath/ath11k/mac.c -+@@ -8587,6 +8587,7 @@ err_fallback: -+ -+ static const struct ieee80211_ops ath11k_ops = { -+ .tx = ath11k_mac_op_tx, -++ .wake_tx_queue = ieee80211_handle_wake_tx_queue, -+ .start = ath11k_mac_op_start, -+ .stop = ath11k_mac_op_stop, -+ .reconfig_complete = ath11k_mac_op_reconfig_complete, -+--- a/drivers/net/wireless/ath/ath5k/mac80211-ops.c -++++ b/drivers/net/wireless/ath/ath5k/mac80211-ops.c -+@@ -781,6 +781,7 @@ static int ath5k_set_ringparam(struct ie -+ -+ const struct ieee80211_ops ath5k_hw_ops = { -+ .tx = ath5k_tx, -++ .wake_tx_queue = ieee80211_handle_wake_tx_queue, -+ .start = ath5k_start, -+ .stop = ath5k_stop, -+ .add_interface = ath5k_add_interface, -+--- a/drivers/net/wireless/ath/ath9k/htc_drv_main.c -++++ b/drivers/net/wireless/ath/ath9k/htc_drv_main.c -+@@ -1870,6 +1870,7 @@ static void ath9k_htc_channel_switch_bea -+ -+ struct ieee80211_ops ath9k_htc_ops = { -+ .tx = ath9k_htc_tx, -++ .wake_tx_queue = ieee80211_handle_wake_tx_queue, -+ .start = ath9k_htc_start, -+ .stop = ath9k_htc_stop, -+ .add_interface = ath9k_htc_add_interface, -+--- a/drivers/net/wireless/ath/carl9170/main.c -++++ b/drivers/net/wireless/ath/carl9170/main.c -+@@ -1715,6 +1715,7 @@ static const struct ieee80211_ops carl91 -+ .start = carl9170_op_start, -+ .stop = carl9170_op_stop, -+ .tx = carl9170_op_tx, -++ .wake_tx_queue = ieee80211_handle_wake_tx_queue, -+ .flush = carl9170_op_flush, -+ .add_interface = carl9170_op_add_interface, -+ .remove_interface = carl9170_op_remove_interface, -+--- a/drivers/net/wireless/ath/wcn36xx/main.c -++++ b/drivers/net/wireless/ath/wcn36xx/main.c -+@@ -1362,6 +1362,7 @@ static const struct ieee80211_ops wcn36x -+ .prepare_multicast = wcn36xx_prepare_multicast, -+ .configure_filter = wcn36xx_configure_filter, -+ .tx = wcn36xx_tx, -++ .wake_tx_queue = ieee80211_handle_wake_tx_queue, -+ .set_key = wcn36xx_set_key, -+ .hw_scan = wcn36xx_hw_scan, -+ .cancel_hw_scan = wcn36xx_cancel_hw_scan, -+--- a/drivers/net/wireless/atmel/at76c50x-usb.c -++++ b/drivers/net/wireless/atmel/at76c50x-usb.c -+@@ -2187,6 +2187,7 @@ static int at76_set_key(struct ieee80211 -+ -+ static const struct ieee80211_ops at76_ops = { -+ .tx = at76_mac80211_tx, -++ .wake_tx_queue = ieee80211_handle_wake_tx_queue, -+ .add_interface = at76_add_interface, -+ .remove_interface = at76_remove_interface, -+ .config = at76_config, -+--- a/drivers/net/wireless/broadcom/b43/main.c -++++ b/drivers/net/wireless/broadcom/b43/main.c -+@@ -5171,6 +5171,7 @@ static int b43_op_get_survey(struct ieee -+ -+ static const struct ieee80211_ops b43_hw_ops = { -+ .tx = b43_op_tx, -++ .wake_tx_queue = ieee80211_handle_wake_tx_queue, -+ .conf_tx = b43_op_conf_tx, -+ .add_interface = b43_op_add_interface, -+ .remove_interface = b43_op_remove_interface, -+--- a/drivers/net/wireless/broadcom/b43legacy/main.c -++++ b/drivers/net/wireless/broadcom/b43legacy/main.c -+@@ -3532,6 +3532,7 @@ static int b43legacy_op_get_survey(struc -+ -+ static const struct ieee80211_ops b43legacy_hw_ops = { -+ .tx = b43legacy_op_tx, -++ .wake_tx_queue = ieee80211_handle_wake_tx_queue, -+ .conf_tx = b43legacy_op_conf_tx, -+ .add_interface = b43legacy_op_add_interface, -+ .remove_interface = b43legacy_op_remove_interface, -+--- a/drivers/net/wireless/broadcom/brcm80211/brcmsmac/mac80211_if.c -++++ b/drivers/net/wireless/broadcom/brcm80211/brcmsmac/mac80211_if.c -+@@ -962,6 +962,7 @@ static int brcms_ops_beacon_set_tim(stru -+ -+ static const struct ieee80211_ops brcms_ops = { -+ .tx = brcms_ops_tx, -++ .wake_tx_queue = ieee80211_handle_wake_tx_queue, -+ .start = brcms_ops_start, -+ .stop = brcms_ops_stop, -+ .add_interface = brcms_ops_add_interface, -+--- a/drivers/net/wireless/intel/iwlegacy/3945-mac.c -++++ b/drivers/net/wireless/intel/iwlegacy/3945-mac.c -+@@ -3439,6 +3439,7 @@ static const struct attribute_group il39 -+ -+ static struct ieee80211_ops il3945_mac_ops __ro_after_init = { -+ .tx = il3945_mac_tx, -++ .wake_tx_queue = ieee80211_handle_wake_tx_queue, -+ .start = il3945_mac_start, -+ .stop = il3945_mac_stop, -+ .add_interface = il_mac_add_interface, -+--- a/drivers/net/wireless/intel/iwlegacy/4965-mac.c -++++ b/drivers/net/wireless/intel/iwlegacy/4965-mac.c -+@@ -6308,6 +6308,7 @@ il4965_tx_queue_set_status(struct il_pri -+ -+ static const struct ieee80211_ops il4965_mac_ops = { -+ .tx = il4965_mac_tx, -++ .wake_tx_queue = ieee80211_handle_wake_tx_queue, -+ .start = il4965_mac_start, -+ .stop = il4965_mac_stop, -+ .add_interface = il_mac_add_interface, -+--- a/drivers/net/wireless/intel/iwlwifi/dvm/mac80211.c -++++ b/drivers/net/wireless/intel/iwlwifi/dvm/mac80211.c -+@@ -1571,6 +1571,7 @@ static void iwlagn_mac_sta_notify(struct -+ -+ const struct ieee80211_ops iwlagn_hw_ops = { -+ .tx = iwlagn_mac_tx, -++ .wake_tx_queue = ieee80211_handle_wake_tx_queue, -+ .start = iwlagn_mac_start, -+ .stop = iwlagn_mac_stop, -+ #ifdef CONFIG_PM_SLEEP -+--- a/drivers/net/wireless/intersil/p54/main.c -++++ b/drivers/net/wireless/intersil/p54/main.c -+@@ -705,6 +705,7 @@ static void p54_set_coverage_class(struc -+ -+ static const struct ieee80211_ops p54_ops = { -+ .tx = p54_tx_80211, -++ .wake_tx_queue = ieee80211_handle_wake_tx_queue, -+ .start = p54_start, -+ .stop = p54_stop, -+ .add_interface = p54_add_interface, -+--- a/drivers/net/wireless/mac80211_hwsim.c -++++ b/drivers/net/wireless/mac80211_hwsim.c -+@@ -3109,6 +3109,7 @@ static int mac80211_hwsim_change_sta_lin -+ -+ #define HWSIM_COMMON_OPS \ -+ .tx = mac80211_hwsim_tx, \ -++ .wake_tx_queue = ieee80211_handle_wake_tx_queue, \ -+ .start = mac80211_hwsim_start, \ -+ .stop = mac80211_hwsim_stop, \ -+ .add_interface = mac80211_hwsim_add_interface, \ -+--- a/drivers/net/wireless/marvell/libertas_tf/main.c -++++ b/drivers/net/wireless/marvell/libertas_tf/main.c -+@@ -474,6 +474,7 @@ static int lbtf_op_get_survey(struct iee -+ -+ static const struct ieee80211_ops lbtf_ops = { -+ .tx = lbtf_op_tx, -++ .wake_tx_queue = ieee80211_handle_wake_tx_queue, -+ .start = lbtf_op_start, -+ .stop = lbtf_op_stop, -+ .add_interface = lbtf_op_add_interface, -+--- a/drivers/net/wireless/marvell/mwl8k.c -++++ b/drivers/net/wireless/marvell/mwl8k.c -+@@ -5611,6 +5611,7 @@ static void mwl8k_sw_scan_complete(struc -+ -+ static const struct ieee80211_ops mwl8k_ops = { -+ .tx = mwl8k_tx, -++ .wake_tx_queue = ieee80211_handle_wake_tx_queue, -+ .start = mwl8k_start, -+ .stop = mwl8k_stop, -+ .add_interface = mwl8k_add_interface, -+--- a/drivers/net/wireless/mediatek/mt7601u/main.c -++++ b/drivers/net/wireless/mediatek/mt7601u/main.c -+@@ -406,6 +406,7 @@ out: -+ -+ const struct ieee80211_ops mt7601u_ops = { -+ .tx = mt7601u_tx, -++ .wake_tx_queue = ieee80211_handle_wake_tx_queue, -+ .start = mt7601u_start, -+ .stop = mt7601u_stop, -+ .add_interface = mt7601u_add_interface, -+--- a/drivers/net/wireless/ralink/rt2x00/rt2400pci.c -++++ b/drivers/net/wireless/ralink/rt2x00/rt2400pci.c -+@@ -1706,6 +1706,7 @@ static int rt2400pci_tx_last_beacon(stru -+ -+ static const struct ieee80211_ops rt2400pci_mac80211_ops = { -+ .tx = rt2x00mac_tx, -++ .wake_tx_queue = ieee80211_handle_wake_tx_queue, -+ .start = rt2x00mac_start, -+ .stop = rt2x00mac_stop, -+ .add_interface = rt2x00mac_add_interface, -+--- a/drivers/net/wireless/ralink/rt2x00/rt2500pci.c -++++ b/drivers/net/wireless/ralink/rt2x00/rt2500pci.c -+@@ -2004,6 +2004,7 @@ static int rt2500pci_tx_last_beacon(stru -+ -+ static const struct ieee80211_ops rt2500pci_mac80211_ops = { -+ .tx = rt2x00mac_tx, -++ .wake_tx_queue = ieee80211_handle_wake_tx_queue, -+ .start = rt2x00mac_start, -+ .stop = rt2x00mac_stop, -+ .add_interface = rt2x00mac_add_interface, -+--- a/drivers/net/wireless/ralink/rt2x00/rt2500usb.c -++++ b/drivers/net/wireless/ralink/rt2x00/rt2500usb.c -+@@ -1795,6 +1795,7 @@ static int rt2500usb_probe_hw(struct rt2 -+ -+ static const struct ieee80211_ops rt2500usb_mac80211_ops = { -+ .tx = rt2x00mac_tx, -++ .wake_tx_queue = ieee80211_handle_wake_tx_queue, -+ .start = rt2x00mac_start, -+ .stop = rt2x00mac_stop, -+ .add_interface = rt2x00mac_add_interface, -+--- a/drivers/net/wireless/ralink/rt2x00/rt2800pci.c -++++ b/drivers/net/wireless/ralink/rt2x00/rt2800pci.c -+@@ -288,6 +288,7 @@ static int rt2800pci_read_eeprom(struct -+ -+ static const struct ieee80211_ops rt2800pci_mac80211_ops = { -+ .tx = rt2x00mac_tx, -++ .wake_tx_queue = ieee80211_handle_wake_tx_queue, -+ .start = rt2x00mac_start, -+ .stop = rt2x00mac_stop, -+ .add_interface = rt2x00mac_add_interface, -+--- a/drivers/net/wireless/ralink/rt2x00/rt2800soc.c -++++ b/drivers/net/wireless/ralink/rt2x00/rt2800soc.c -+@@ -133,6 +133,7 @@ static int rt2800soc_write_firmware(stru -+ -+ static const struct ieee80211_ops rt2800soc_mac80211_ops = { -+ .tx = rt2x00mac_tx, -++ .wake_tx_queue = ieee80211_handle_wake_tx_queue, -+ .start = rt2x00mac_start, -+ .stop = rt2x00mac_stop, -+ .add_interface = rt2x00mac_add_interface, -+--- a/drivers/net/wireless/ralink/rt2x00/rt2800usb.c -++++ b/drivers/net/wireless/ralink/rt2x00/rt2800usb.c -+@@ -630,6 +630,7 @@ static int rt2800usb_probe_hw(struct rt2 -+ -+ static const struct ieee80211_ops rt2800usb_mac80211_ops = { -+ .tx = rt2x00mac_tx, -++ .wake_tx_queue = ieee80211_handle_wake_tx_queue, -+ .start = rt2x00mac_start, -+ .stop = rt2x00mac_stop, -+ .add_interface = rt2x00mac_add_interface, -+--- a/drivers/net/wireless/ralink/rt2x00/rt61pci.c -++++ b/drivers/net/wireless/ralink/rt2x00/rt61pci.c -+@@ -2873,6 +2873,7 @@ static u64 rt61pci_get_tsf(struct ieee80 -+ -+ static const struct ieee80211_ops rt61pci_mac80211_ops = { -+ .tx = rt2x00mac_tx, -++ .wake_tx_queue = ieee80211_handle_wake_tx_queue, -+ .start = rt2x00mac_start, -+ .stop = rt2x00mac_stop, -+ .add_interface = rt2x00mac_add_interface, -+--- a/drivers/net/wireless/ralink/rt2x00/rt73usb.c -++++ b/drivers/net/wireless/ralink/rt2x00/rt73usb.c -+@@ -2292,6 +2292,7 @@ static u64 rt73usb_get_tsf(struct ieee80 -+ -+ static const struct ieee80211_ops rt73usb_mac80211_ops = { -+ .tx = rt2x00mac_tx, -++ .wake_tx_queue = ieee80211_handle_wake_tx_queue, -+ .start = rt2x00mac_start, -+ .stop = rt2x00mac_stop, -+ .add_interface = rt2x00mac_add_interface, -+--- a/drivers/net/wireless/realtek/rtl818x/rtl8180/dev.c -++++ b/drivers/net/wireless/realtek/rtl818x/rtl8180/dev.c -+@@ -1608,6 +1608,7 @@ static void rtl8180_configure_filter(str -+ -+ static const struct ieee80211_ops rtl8180_ops = { -+ .tx = rtl8180_tx, -++ .wake_tx_queue = ieee80211_handle_wake_tx_queue, -+ .start = rtl8180_start, -+ .stop = rtl8180_stop, -+ .add_interface = rtl8180_add_interface, -+--- a/drivers/net/wireless/realtek/rtl818x/rtl8187/dev.c -++++ b/drivers/net/wireless/realtek/rtl818x/rtl8187/dev.c -+@@ -1378,6 +1378,7 @@ static int rtl8187_conf_tx(struct ieee80 -+ -+ static const struct ieee80211_ops rtl8187_ops = { -+ .tx = rtl8187_tx, -++ .wake_tx_queue = ieee80211_handle_wake_tx_queue, -+ .start = rtl8187_start, -+ .stop = rtl8187_stop, -+ .add_interface = rtl8187_add_interface, -+--- a/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c -++++ b/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c -+@@ -6548,6 +6548,7 @@ static void rtl8xxxu_stop(struct ieee802 -+ -+ static const struct ieee80211_ops rtl8xxxu_ops = { -+ .tx = rtl8xxxu_tx, -++ .wake_tx_queue = ieee80211_handle_wake_tx_queue, -+ .add_interface = rtl8xxxu_add_interface, -+ .remove_interface = rtl8xxxu_remove_interface, -+ .config = rtl8xxxu_config, -+--- a/drivers/net/wireless/realtek/rtlwifi/core.c -++++ b/drivers/net/wireless/realtek/rtlwifi/core.c -+@@ -1912,6 +1912,7 @@ const struct ieee80211_ops rtl_ops = { -+ .start = rtl_op_start, -+ .stop = rtl_op_stop, -+ .tx = rtl_op_tx, -++ .wake_tx_queue = ieee80211_handle_wake_tx_queue, -+ .add_interface = rtl_op_add_interface, -+ .remove_interface = rtl_op_remove_interface, -+ .change_interface = rtl_op_change_interface, -+--- a/drivers/net/wireless/realtek/rtw88/mac80211.c -++++ b/drivers/net/wireless/realtek/rtw88/mac80211.c -+@@ -896,6 +896,7 @@ static void rtw_ops_sta_rc_update(struct -+ -+ const struct ieee80211_ops rtw_ops = { -+ .tx = rtw_ops_tx, -++ .wake_tx_queue = ieee80211_handle_wake_tx_queue, -+ .wake_tx_queue = rtw_ops_wake_tx_queue, -+ .start = rtw_ops_start, -+ .stop = rtw_ops_stop, -+--- a/drivers/net/wireless/realtek/rtw89/mac80211.c -++++ b/drivers/net/wireless/realtek/rtw89/mac80211.c -+@@ -918,6 +918,7 @@ static int rtw89_ops_set_tid_config(stru -+ -+ const struct ieee80211_ops rtw89_ops = { -+ .tx = rtw89_ops_tx, -++ .wake_tx_queue = ieee80211_handle_wake_tx_queue, -+ .wake_tx_queue = rtw89_ops_wake_tx_queue, -+ .start = rtw89_ops_start, -+ .stop = rtw89_ops_stop, -+--- a/drivers/net/wireless/rsi/rsi_91x_mac80211.c -++++ b/drivers/net/wireless/rsi/rsi_91x_mac80211.c -+@@ -1958,6 +1958,7 @@ static int rsi_mac80211_resume(struct ie -+ -+ static const struct ieee80211_ops mac80211_ops = { -+ .tx = rsi_mac80211_tx, -++ .wake_tx_queue = ieee80211_handle_wake_tx_queue, -+ .start = rsi_mac80211_start, -+ .stop = rsi_mac80211_stop, -+ .add_interface = rsi_mac80211_add_interface, -+--- a/drivers/net/wireless/st/cw1200/main.c -++++ b/drivers/net/wireless/st/cw1200/main.c -+@@ -209,6 +209,7 @@ static const struct ieee80211_ops cw1200 -+ .remove_interface = cw1200_remove_interface, -+ .change_interface = cw1200_change_interface, -+ .tx = cw1200_tx, -++ .wake_tx_queue = ieee80211_handle_wake_tx_queue, -+ .hw_scan = cw1200_hw_scan, -+ .set_tim = cw1200_set_tim, -+ .sta_notify = cw1200_sta_notify, -+--- a/drivers/net/wireless/ti/wl1251/main.c -++++ b/drivers/net/wireless/ti/wl1251/main.c -+@@ -1359,6 +1359,7 @@ static const struct ieee80211_ops wl1251 -+ .prepare_multicast = wl1251_op_prepare_multicast, -+ .configure_filter = wl1251_op_configure_filter, -+ .tx = wl1251_op_tx, -++ .wake_tx_queue = ieee80211_handle_wake_tx_queue, -+ .set_key = wl1251_op_set_key, -+ .hw_scan = wl1251_op_hw_scan, -+ .bss_info_changed = wl1251_op_bss_info_changed, -+--- a/drivers/net/wireless/ti/wlcore/main.c -++++ b/drivers/net/wireless/ti/wlcore/main.c -+@@ -5942,6 +5942,7 @@ static const struct ieee80211_ops wl1271 -+ .prepare_multicast = wl1271_op_prepare_multicast, -+ .configure_filter = wl1271_op_configure_filter, -+ .tx = wl1271_op_tx, -++ .wake_tx_queue = ieee80211_handle_wake_tx_queue, -+ .set_key = wlcore_op_set_key, -+ .hw_scan = wl1271_op_hw_scan, -+ .cancel_hw_scan = wl1271_op_cancel_hw_scan, -+--- a/drivers/net/wireless/zydas/zd1211rw/zd_mac.c -++++ b/drivers/net/wireless/zydas/zd1211rw/zd_mac.c -+@@ -1344,6 +1344,7 @@ static u64 zd_op_get_tsf(struct ieee8021 -+ -+ static const struct ieee80211_ops zd_ops = { -+ .tx = zd_op_tx, -++ .wake_tx_queue = ieee80211_handle_wake_tx_queue, -+ .start = zd_op_start, -+ .stop = zd_op_stop, -+ .add_interface = zd_op_add_interface, -diff --git a/package/kernel/mac80211/patches/subsys/306-03-v6.2-wifi-mac80211-Drop-support-for-TX-push-path.patch b/package/kernel/mac80211/patches/subsys/306-03-v6.2-wifi-mac80211-Drop-support-for-TX-push-path.patch -new file mode 100644 -index 0000000000..f9f9977cee ---- /dev/null -+++ b/package/kernel/mac80211/patches/subsys/306-03-v6.2-wifi-mac80211-Drop-support-for-TX-push-path.patch -@@ -0,0 +1,683 @@ -+From: Alexander Wetzel -+Date: Sun, 9 Oct 2022 18:30:40 +0200 -+Subject: [PATCH] wifi: mac80211: Drop support for TX push path -+ -+All drivers are now using mac80211 internal queues (iTXQs). -+Drop mac80211 internal support for the old push path. -+ -+Signed-off-by: Alexander Wetzel -+Signed-off-by: Johannes Berg -+--- -+ -+--- a/net/mac80211/cfg.c -++++ b/net/mac80211/cfg.c -+@@ -4346,9 +4346,6 @@ static int ieee80211_get_txq_stats(struc -+ struct ieee80211_sub_if_data *sdata; -+ int ret = 0; -+ -+- if (!local->ops->wake_tx_queue) -+- return 1; -+- -+ spin_lock_bh(&local->fq.lock); -+ rcu_read_lock(); -+ -+--- a/net/mac80211/debugfs.c -++++ b/net/mac80211/debugfs.c -+@@ -663,9 +663,7 @@ void debugfs_hw_add(struct ieee80211_loc -+ DEBUGFS_ADD_MODE(force_tx_status, 0600); -+ DEBUGFS_ADD_MODE(aql_enable, 0600); -+ DEBUGFS_ADD(aql_pending); -+- -+- if (local->ops->wake_tx_queue) -+- DEBUGFS_ADD_MODE(aqm, 0600); -++ DEBUGFS_ADD_MODE(aqm, 0600); -+ -+ DEBUGFS_ADD_MODE(airtime_flags, 0600); -+ -+--- a/net/mac80211/debugfs_netdev.c -++++ b/net/mac80211/debugfs_netdev.c -+@@ -677,8 +677,7 @@ static void add_common_files(struct ieee -+ DEBUGFS_ADD(rc_rateidx_vht_mcs_mask_5ghz); -+ DEBUGFS_ADD(hw_queues); -+ -+- if (sdata->local->ops->wake_tx_queue && -+- sdata->vif.type != NL80211_IFTYPE_P2P_DEVICE && -++ if (sdata->vif.type != NL80211_IFTYPE_P2P_DEVICE && -+ sdata->vif.type != NL80211_IFTYPE_NAN) -+ DEBUGFS_ADD(aqm); -+ } -+--- a/net/mac80211/debugfs_sta.c -++++ b/net/mac80211/debugfs_sta.c -+@@ -1057,10 +1057,8 @@ void ieee80211_sta_debugfs_add(struct st -+ DEBUGFS_ADD_COUNTER(rx_fragments, deflink.rx_stats.fragments); -+ DEBUGFS_ADD_COUNTER(tx_filtered, deflink.status_stats.filtered); -+ -+- if (local->ops->wake_tx_queue) { -+- DEBUGFS_ADD(aqm); -+- DEBUGFS_ADD(airtime); -+- } -++ DEBUGFS_ADD(aqm); -++ DEBUGFS_ADD(airtime); -+ -+ if (wiphy_ext_feature_isset(local->hw.wiphy, -+ NL80211_EXT_FEATURE_AQL)) -+--- a/net/mac80211/ieee80211_i.h -++++ b/net/mac80211/ieee80211_i.h -+@@ -2294,7 +2294,6 @@ void ieee80211_wake_queue_by_reason(stru -+ void ieee80211_stop_queue_by_reason(struct ieee80211_hw *hw, int queue, -+ enum queue_stop_reason reason, -+ bool refcounted); -+-void ieee80211_propagate_queue_wake(struct ieee80211_local *local, int queue); -+ void ieee80211_add_pending_skb(struct ieee80211_local *local, -+ struct sk_buff *skb); -+ void ieee80211_add_pending_skbs(struct ieee80211_local *local, -+--- a/net/mac80211/iface.c -++++ b/net/mac80211/iface.c -+@@ -460,12 +460,6 @@ static void ieee80211_do_stop(struct iee -+ if (cancel_scan) -+ ieee80211_scan_cancel(local); -+ -+- /* -+- * Stop TX on this interface first. -+- */ -+- if (!local->ops->wake_tx_queue && sdata->dev) -+- netif_tx_stop_all_queues(sdata->dev); -+- -+ ieee80211_roc_purge(local, sdata); -+ -+ switch (sdata->vif.type) { -+@@ -813,13 +807,6 @@ static void ieee80211_uninit(struct net_ -+ ieee80211_teardown_sdata(IEEE80211_DEV_TO_SUB_IF(dev)); -+ } -+ -+-static u16 ieee80211_netdev_select_queue(struct net_device *dev, -+- struct sk_buff *skb, -+- struct net_device *sb_dev) -+-{ -+- return ieee80211_select_queue(IEEE80211_DEV_TO_SUB_IF(dev), skb); -+-} -+- -+ static void -+ ieee80211_get_stats64(struct net_device *dev, struct rtnl_link_stats64 *stats) -+ { -+@@ -833,7 +820,6 @@ static const struct net_device_ops ieee8 -+ .ndo_start_xmit = ieee80211_subif_start_xmit, -+ .ndo_set_rx_mode = ieee80211_set_multicast_list, -+ .ndo_set_mac_address = ieee80211_change_mac, -+- .ndo_select_queue = ieee80211_netdev_select_queue, -+ .ndo_get_stats64 = ieee80211_get_stats64, -+ }; -+ -+@@ -941,7 +927,6 @@ static const struct net_device_ops ieee8 -+ .ndo_start_xmit = ieee80211_subif_start_xmit_8023, -+ .ndo_set_rx_mode = ieee80211_set_multicast_list, -+ .ndo_set_mac_address = ieee80211_change_mac, -+- .ndo_select_queue = ieee80211_netdev_select_queue, -+ .ndo_get_stats64 = ieee80211_get_stats64, -+ .ndo_fill_forward_path = ieee80211_netdev_fill_forward_path, -+ }; -+@@ -1443,35 +1428,6 @@ int ieee80211_do_open(struct wireless_de -+ -+ ieee80211_recalc_ps(local); -+ -+- if (sdata->vif.type == NL80211_IFTYPE_MONITOR || -+- sdata->vif.type == NL80211_IFTYPE_AP_VLAN || -+- local->ops->wake_tx_queue) { -+- /* XXX: for AP_VLAN, actually track AP queues */ -+- if (dev) -+- netif_tx_start_all_queues(dev); -+- } else if (dev) { -+- unsigned long flags; -+- int n_acs = IEEE80211_NUM_ACS; -+- int ac; -+- -+- if (local->hw.queues < IEEE80211_NUM_ACS) -+- n_acs = 1; -+- -+- spin_lock_irqsave(&local->queue_stop_reason_lock, flags); -+- if (sdata->vif.cab_queue == IEEE80211_INVAL_HW_QUEUE || -+- (local->queue_stop_reasons[sdata->vif.cab_queue] == 0 && -+- skb_queue_empty(&local->pending[sdata->vif.cab_queue]))) { -+- for (ac = 0; ac < n_acs; ac++) { -+- int ac_queue = sdata->vif.hw_queue[ac]; -+- -+- if (local->queue_stop_reasons[ac_queue] == 0 && -+- skb_queue_empty(&local->pending[ac_queue])) -+- netif_start_subqueue(dev, ac); -+- } -+- } -+- spin_unlock_irqrestore(&local->queue_stop_reason_lock, flags); -+- } -+- -+ set_bit(SDATA_STATE_RUNNING, &sdata->state); -+ -+ return 0; -+@@ -1501,17 +1457,12 @@ static void ieee80211_if_setup(struct ne -+ { -+ ether_setup(dev); -+ dev->priv_flags &= ~IFF_TX_SKB_SHARING; -++ dev->priv_flags |= IFF_NO_QUEUE; -+ dev->netdev_ops = &ieee80211_dataif_ops; -+ dev->needs_free_netdev = true; -+ dev->priv_destructor = ieee80211_if_free; -+ } -+ -+-static void ieee80211_if_setup_no_queue(struct net_device *dev) -+-{ -+- ieee80211_if_setup(dev); -+- dev->priv_flags |= IFF_NO_QUEUE; -+-} -+- -+ static void ieee80211_iface_process_skb(struct ieee80211_local *local, -+ struct ieee80211_sub_if_data *sdata, -+ struct sk_buff *skb) -+@@ -2096,9 +2047,7 @@ int ieee80211_if_add(struct ieee80211_lo -+ struct net_device *ndev = NULL; -+ struct ieee80211_sub_if_data *sdata = NULL; -+ struct txq_info *txqi; -+- void (*if_setup)(struct net_device *dev); -+ int ret, i; -+- int txqs = 1; -+ -+ ASSERT_RTNL(); -+ -+@@ -2121,30 +2070,18 @@ int ieee80211_if_add(struct ieee80211_lo -+ sizeof(void *)); -+ int txq_size = 0; -+ -+- if (local->ops->wake_tx_queue && -+- type != NL80211_IFTYPE_AP_VLAN && -++ if (type != NL80211_IFTYPE_AP_VLAN && -+ (type != NL80211_IFTYPE_MONITOR || -+ (params->flags & MONITOR_FLAG_ACTIVE))) -+ txq_size += sizeof(struct txq_info) + -+ local->hw.txq_data_size; -+ -+- if (local->ops->wake_tx_queue) { -+- if_setup = ieee80211_if_setup_no_queue; -+- } else { -+- if_setup = ieee80211_if_setup; -+- if (local->hw.queues >= IEEE80211_NUM_ACS) -+- txqs = IEEE80211_NUM_ACS; -+- } -+- -+ ndev = alloc_netdev_mqs(size + txq_size, -+ name, name_assign_type, -+- if_setup, txqs, 1); -++ ieee80211_if_setup, 1, 1); -+ if (!ndev) -+ return -ENOMEM; -+ -+- if (!local->ops->wake_tx_queue && local->hw.wiphy->tx_queue_len) -+- ndev->tx_queue_len = local->hw.wiphy->tx_queue_len; -+- -+ dev_net_set(ndev, wiphy_net(local->hw.wiphy)); -+ -+ ndev->tstats = netdev_alloc_pcpu_stats(struct pcpu_sw_netstats); -+--- a/net/mac80211/main.c -++++ b/net/mac80211/main.c -+@@ -630,7 +630,7 @@ struct ieee80211_hw *ieee80211_alloc_hw_ -+ -+ if (WARN_ON(!ops->tx || !ops->start || !ops->stop || !ops->config || -+ !ops->add_interface || !ops->remove_interface || -+- !ops->configure_filter)) -++ !ops->configure_filter || !ops->wake_tx_queue)) -+ return NULL; -+ -+ if (WARN_ON(ops->sta_state && (ops->sta_add || ops->sta_remove))) -+@@ -719,9 +719,7 @@ struct ieee80211_hw *ieee80211_alloc_hw_ -+ if (!ops->set_key) -+ wiphy->flags |= WIPHY_FLAG_IBSS_RSN; -+ -+- if (ops->wake_tx_queue) -+- wiphy_ext_feature_set(wiphy, NL80211_EXT_FEATURE_TXQS); -+- -++ wiphy_ext_feature_set(wiphy, NL80211_EXT_FEATURE_TXQS); -+ wiphy_ext_feature_set(wiphy, NL80211_EXT_FEATURE_RRM); -+ -+ wiphy->bss_priv_size = sizeof(struct ieee80211_bss); -+@@ -834,10 +832,7 @@ struct ieee80211_hw *ieee80211_alloc_hw_ -+ atomic_set(&local->agg_queue_stop[i], 0); -+ } -+ tasklet_setup(&local->tx_pending_tasklet, ieee80211_tx_pending); -+- -+- if (ops->wake_tx_queue) -+- tasklet_setup(&local->wake_txqs_tasklet, ieee80211_wake_txqs); -+- -++ 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 -+@@ -1571,9 +1571,6 @@ 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,17 +140,15 @@ static void __cleanup_single_sta(struct -+ atomic_dec(&ps->num_sta_ps); -+ } -+ -+- if (sta->sta.txq[0]) { -+- for (i = 0; i < ARRAY_SIZE(sta->sta.txq); i++) { -+- struct txq_info *txqi; -++ 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++) { -+@@ -425,8 +423,7 @@ void sta_info_free(struct ieee80211_loca -+ -+ sta_dbg(sta->sdata, "Destroyed STA %pM\n", sta->sta.addr); -+ -+- if (sta->sta.txq[0]) -+- kfree(to_txq_info(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); -+@@ -527,6 +524,8 @@ __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); -+@@ -597,21 +596,18 @@ __sta_info_alloc(struct ieee80211_sub_if -+ -+ sta->last_connected = ktime_get_seconds(); -+ -+- if (local->ops->wake_tx_queue) { -+- void *txq_data; -+- int size = sizeof(struct txq_info) + -+- ALIGN(hw->txq_data_size, sizeof(void *)); -++ 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; -++ 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)) -+@@ -685,8 +681,7 @@ __sta_info_alloc(struct ieee80211_sub_if -+ return sta; -+ -+ free_txq: -+- if (sta->sta.txq[0]) -+- kfree(to_txq_info(sta->sta.txq[0])); -++ kfree(to_txq_info(sta->sta.txq[0])); -+ free: -+ sta_info_free_link(&sta->deflink); -+ #ifdef CPTCFG_MAC80211_MESH -+@@ -1960,9 +1955,6 @@ 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)) || -+@@ -2447,7 +2439,7 @@ static void sta_set_tidstats(struct sta_ -+ tidstats->tx_msdu_failed = sta->deflink.status_stats.msdu_failed[tid]; -+ } -+ -+- if (local->ops->wake_tx_queue && tid < IEEE80211_NUM_TIDS) { -++ if (tid < IEEE80211_NUM_TIDS) { -+ spin_lock_bh(&local->fq.lock); -+ rcu_read_lock(); -+ -+@@ -2775,9 +2767,6 @@ unsigned long ieee80211_sta_last_active( -+ -+ static void sta_update_codel_params(struct sta_info *sta, u32 thr) -+ { -+- if (!sta->sdata->local->ops->wake_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/tdls.c -++++ b/net/mac80211/tdls.c -+@@ -1016,7 +1016,6 @@ ieee80211_tdls_prep_mgmt_packet(struct w -+ skb->priority = 256 + 5; -+ break; -+ } -+- skb_set_queue_mapping(skb, ieee80211_select_queue(sdata, skb)); -+ -+ /* -+ * Set the WLAN_TDLS_TEARDOWN flag to indicate a teardown in progress. -+--- a/net/mac80211/tx.c -++++ b/net/mac80211/tx.c -+@@ -1600,9 +1600,6 @@ int ieee80211_txq_setup_flows(struct iee -+ bool supp_vht = false; -+ enum nl80211_band band; -+ -+- if (!local->ops->wake_tx_queue) -+- return 0; -+- -+ ret = fq_init(fq, 4096); -+ if (ret) -+ return ret; -+@@ -1650,9 +1647,6 @@ void ieee80211_txq_teardown_flows(struct -+ { -+ struct fq *fq = &local->fq; -+ -+- if (!local->ops->wake_tx_queue) -+- return; -+- -+ kfree(local->cvars); -+ local->cvars = NULL; -+ -+@@ -1669,8 +1663,7 @@ static bool ieee80211_queue_skb(struct i -+ struct ieee80211_vif *vif; -+ struct txq_info *txqi; -+ -+- if (!local->ops->wake_tx_queue || -+- sdata->vif.type == NL80211_IFTYPE_MONITOR) -++ if (sdata->vif.type == NL80211_IFTYPE_MONITOR) -+ return false; -+ -+ if (sdata->vif.type == NL80211_IFTYPE_AP_VLAN) -+@@ -4193,12 +4186,7 @@ void __ieee80211_subif_start_xmit(struct -+ if (IS_ERR(sta)) -+ sta = NULL; -+ -+- if (local->ops->wake_tx_queue) { -+- u16 queue = __ieee80211_select_queue(sdata, sta, skb); -+- skb_set_queue_mapping(skb, queue); -+- skb_get_hash(skb); -+- } -+- -++ skb_set_queue_mapping(skb, ieee80211_select_queue(sdata, sta, skb)); -+ ieee80211_aggr_check(sdata, sta, skb); -+ -+ sk_pacing_shift_update(skb->sk, sdata->local->hw.tx_sk_pacing_shift); -+@@ -4509,11 +4497,7 @@ static void ieee80211_8023_xmit(struct i -+ struct tid_ampdu_tx *tid_tx; -+ u8 tid; -+ -+- if (local->ops->wake_tx_queue) { -+- u16 queue = __ieee80211_select_queue(sdata, sta, skb); -+- skb_set_queue_mapping(skb, queue); -+- skb_get_hash(skb); -+- } -++ skb_set_queue_mapping(skb, ieee80211_select_queue(sdata, sta, skb)); -+ -+ if (unlikely(test_bit(SCAN_SW_SCANNING, &local->scanning)) && -+ test_bit(SDATA_STATE_OFFCHANNEL, &sdata->state)) -+@@ -4767,9 +4751,6 @@ void ieee80211_tx_pending(struct tasklet -+ if (!txok) -+ break; -+ } -+- -+- if (skb_queue_empty(&local->pending[i])) -+- ieee80211_propagate_queue_wake(local, i); -+ } -+ spin_unlock_irqrestore(&local->queue_stop_reason_lock, flags); -+ -+@@ -5962,10 +5943,9 @@ int ieee80211_tx_control_port(struct wip -+ } -+ -+ if (!IS_ERR(sta)) { -+- u16 queue = __ieee80211_select_queue(sdata, sta, skb); -++ u16 queue = ieee80211_select_queue(sdata, sta, skb); -+ -+ skb_set_queue_mapping(skb, queue); -+- skb_get_hash(skb); -+ -+ /* -+ * for MLO STA, the SA should be the AP MLD address, but -+--- a/net/mac80211/util.c -++++ b/net/mac80211/util.c -+@@ -444,39 +444,6 @@ void ieee80211_wake_txqs(struct tasklet_ -+ spin_unlock_irqrestore(&local->queue_stop_reason_lock, flags); -+ } -+ -+-void ieee80211_propagate_queue_wake(struct ieee80211_local *local, int queue) -+-{ -+- struct ieee80211_sub_if_data *sdata; -+- int n_acs = IEEE80211_NUM_ACS; -+- -+- if (local->ops->wake_tx_queue) -+- return; -+- -+- if (local->hw.queues < IEEE80211_NUM_ACS) -+- n_acs = 1; -+- -+- list_for_each_entry_rcu(sdata, &local->interfaces, list) { -+- int ac; -+- -+- if (!sdata->dev) -+- continue; -+- -+- if (sdata->vif.cab_queue != IEEE80211_INVAL_HW_QUEUE && -+- local->queue_stop_reasons[sdata->vif.cab_queue] != 0) -+- continue; -+- -+- for (ac = 0; ac < n_acs; ac++) { -+- int ac_queue = sdata->vif.hw_queue[ac]; -+- -+- if (ac_queue == queue || -+- (sdata->vif.cab_queue == queue && -+- local->queue_stop_reasons[ac_queue] == 0 && -+- skb_queue_empty(&local->pending[ac_queue]))) -+- netif_wake_subqueue(sdata->dev, ac); -+- } -+- } -+-} -+- -+ static void __ieee80211_wake_queue(struct ieee80211_hw *hw, int queue, -+ enum queue_stop_reason reason, -+ bool refcounted, -+@@ -507,11 +474,7 @@ static void __ieee80211_wake_queue(struc -+ /* someone still has this queue stopped */ -+ return; -+ -+- if (skb_queue_empty(&local->pending[queue])) { -+- rcu_read_lock(); -+- ieee80211_propagate_queue_wake(local, queue); -+- rcu_read_unlock(); -+- } else -++ if (!skb_queue_empty(&local->pending[queue])) -+ tasklet_schedule(&local->tx_pending_tasklet); -+ -+ /* -+@@ -521,12 +484,10 @@ 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 (local->ops->wake_tx_queue) { -+- if (reason == IEEE80211_QUEUE_STOP_REASON_DRIVER) -+- tasklet_schedule(&local->wake_txqs_tasklet); -+- else -+- _ieee80211_wake_txqs(local, flags); -+- } -++ if (reason == IEEE80211_QUEUE_STOP_REASON_DRIVER) -++ tasklet_schedule(&local->wake_txqs_tasklet); -++ else -++ _ieee80211_wake_txqs(local, flags); -+ } -+ -+ void ieee80211_wake_queue_by_reason(struct ieee80211_hw *hw, int queue, -+@@ -554,8 +515,6 @@ static void __ieee80211_stop_queue(struc -+ bool refcounted) -+ { -+ struct ieee80211_local *local = hw_to_local(hw); -+- struct ieee80211_sub_if_data *sdata; -+- int n_acs = IEEE80211_NUM_ACS; -+ -+ trace_stop_queue(local, queue, reason); -+ -+@@ -567,27 +526,7 @@ static void __ieee80211_stop_queue(struc -+ else -+ local->q_stop_reasons[queue][reason]++; -+ -+- if (__test_and_set_bit(reason, &local->queue_stop_reasons[queue])) -+- return; -+- -+- if (local->hw.queues < IEEE80211_NUM_ACS) -+- n_acs = 1; -+- -+- rcu_read_lock(); -+- list_for_each_entry_rcu(sdata, &local->interfaces, list) { -+- int ac; -+- -+- if (!sdata->dev) -+- continue; -+- -+- for (ac = 0; ac < n_acs; ac++) { -+- if (!local->ops->wake_tx_queue && -+- (sdata->vif.hw_queue[ac] == queue || -+- sdata->vif.cab_queue == queue)) -+- netif_stop_subqueue(sdata->dev, ac); -+- } -+- } -+- rcu_read_unlock(); -++ set_bit(reason, &local->queue_stop_reasons[queue]); -+ } -+ -+ void ieee80211_stop_queue_by_reason(struct ieee80211_hw *hw, int queue, -+--- a/net/mac80211/wme.c -++++ b/net/mac80211/wme.c -+@@ -122,6 +122,9 @@ u16 ieee80211_select_queue_80211(struct -+ struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); -+ u8 *p; -+ -++ /* Ensure hash is set prior to potential SW encryption */ -++ skb_get_hash(skb); -++ -+ if ((info->control.flags & IEEE80211_TX_CTRL_DONT_REORDER) || -+ local->hw.queues < IEEE80211_NUM_ACS) -+ return 0; -+@@ -141,13 +144,16 @@ u16 ieee80211_select_queue_80211(struct -+ return ieee80211_downgrade_queue(sdata, NULL, skb); -+ } -+ -+-u16 __ieee80211_select_queue(struct ieee80211_sub_if_data *sdata, -+- struct sta_info *sta, struct sk_buff *skb) -++u16 ieee80211_select_queue(struct ieee80211_sub_if_data *sdata, -++ struct sta_info *sta, struct sk_buff *skb) -+ { -+ const struct ethhdr *eth = (void *)skb->data; -+ struct mac80211_qos_map *qos_map; -+ bool qos; -+ -++ /* Ensure hash is set prior to potential SW encryption */ -++ skb_get_hash(skb); -++ -+ /* all mesh/ocb stations are required to support WME */ -+ if ((sdata->vif.type == NL80211_IFTYPE_MESH_POINT && -+ !is_multicast_ether_addr(eth->h_dest)) || -+@@ -178,59 +184,6 @@ u16 __ieee80211_select_queue(struct ieee -+ return ieee80211_downgrade_queue(sdata, sta, skb); -+ } -+ -+- -+-/* Indicate which queue to use. */ -+-u16 ieee80211_select_queue(struct ieee80211_sub_if_data *sdata, -+- struct sk_buff *skb) -+-{ -+- struct ieee80211_local *local = sdata->local; -+- struct sta_info *sta = NULL; -+- const u8 *ra = NULL; -+- u16 ret; -+- -+- /* when using iTXQ, we can do this later */ -+- if (local->ops->wake_tx_queue) -+- return 0; -+- -+- if (local->hw.queues < IEEE80211_NUM_ACS || skb->len < 6) { -+- skb->priority = 0; /* required for correct WPA/11i MIC */ -+- return 0; -+- } -+- -+- rcu_read_lock(); -+- switch (sdata->vif.type) { -+- case NL80211_IFTYPE_AP_VLAN: -+- sta = rcu_dereference(sdata->u.vlan.sta); -+- if (sta) -+- break; -+- fallthrough; -+- case NL80211_IFTYPE_AP: -+- ra = skb->data; -+- break; -+- case NL80211_IFTYPE_STATION: -+- /* might be a TDLS station */ -+- sta = sta_info_get(sdata, skb->data); -+- if (sta) -+- break; -+- -+- ra = sdata->deflink.u.mgd.bssid; -+- break; -+- case NL80211_IFTYPE_ADHOC: -+- ra = skb->data; -+- break; -+- default: -+- break; -+- } -+- -+- if (!sta && ra && !is_multicast_ether_addr(ra)) -+- sta = sta_info_get(sdata, ra); -+- -+- ret = __ieee80211_select_queue(sdata, sta, skb); -+- -+- rcu_read_unlock(); -+- return ret; -+-} -+- -+ /** -+ * ieee80211_set_qos_hdr - Fill in the QoS header if there is one. -+ * -+--- a/net/mac80211/wme.h -++++ b/net/mac80211/wme.h -+@@ -13,10 +13,8 @@ -+ u16 ieee80211_select_queue_80211(struct ieee80211_sub_if_data *sdata, -+ struct sk_buff *skb, -+ struct ieee80211_hdr *hdr); -+-u16 __ieee80211_select_queue(struct ieee80211_sub_if_data *sdata, -+- struct sta_info *sta, struct sk_buff *skb); -+ u16 ieee80211_select_queue(struct ieee80211_sub_if_data *sdata, -+- struct sk_buff *skb); -++ struct sta_info *sta, struct sk_buff *skb); -+ void ieee80211_set_qos_hdr(struct ieee80211_sub_if_data *sdata, -+ struct sk_buff *skb); -+ -diff --git a/package/kernel/mac80211/patches/subsys/306-04-v6.2-wifi-realtek-remove-duplicated-wake_tx_queue.patch b/package/kernel/mac80211/patches/subsys/306-04-v6.2-wifi-realtek-remove-duplicated-wake_tx_queue.patch -new file mode 100644 -index 0000000000..f0dfc75a78 ---- /dev/null -+++ b/package/kernel/mac80211/patches/subsys/306-04-v6.2-wifi-realtek-remove-duplicated-wake_tx_queue.patch -@@ -0,0 +1,32 @@ -+From: Johannes Berg -+Date: Mon, 10 Oct 2022 19:17:46 +0200 -+Subject: [PATCH] wifi: realtek: remove duplicated wake_tx_queue -+ -+By accident, the previous patch duplicated the initialization -+of the wake_tx_queue callback. Fix that by removing the new -+initializations. -+ -+Fixes: a790cc3a4fad ("wifi: mac80211: add wake_tx_queue callback to drivers") -+Signed-off-by: Johannes Berg -+--- -+ -+--- a/drivers/net/wireless/realtek/rtw88/mac80211.c -++++ b/drivers/net/wireless/realtek/rtw88/mac80211.c -+@@ -896,7 +896,6 @@ static void rtw_ops_sta_rc_update(struct -+ -+ const struct ieee80211_ops rtw_ops = { -+ .tx = rtw_ops_tx, -+- .wake_tx_queue = ieee80211_handle_wake_tx_queue, -+ .wake_tx_queue = rtw_ops_wake_tx_queue, -+ .start = rtw_ops_start, -+ .stop = rtw_ops_stop, -+--- a/drivers/net/wireless/realtek/rtw89/mac80211.c -++++ b/drivers/net/wireless/realtek/rtw89/mac80211.c -+@@ -918,7 +918,6 @@ static int rtw89_ops_set_tid_config(stru -+ -+ const struct ieee80211_ops rtw89_ops = { -+ .tx = rtw89_ops_tx, -+- .wake_tx_queue = ieee80211_handle_wake_tx_queue, -+ .wake_tx_queue = rtw89_ops_wake_tx_queue, -+ .start = rtw89_ops_start, -+ .stop = rtw89_ops_stop, -diff --git a/package/kernel/mac80211/patches/subsys/310-v6.2-mac80211-add-support-for-restricting-netdev-features.patch b/package/kernel/mac80211/patches/subsys/310-v6.2-mac80211-add-support-for-restricting-netdev-features.patch -new file mode 100644 -index 0000000000..812b12189c ---- /dev/null -+++ b/package/kernel/mac80211/patches/subsys/310-v6.2-mac80211-add-support-for-restricting-netdev-features.patch -@@ -0,0 +1,506 @@ -+From: Felix Fietkau -+Date: Sun, 9 Oct 2022 20:15:46 +0200 -+Subject: [PATCH] mac80211: add support for restricting netdev features per vif -+ -+This can be used to selectively disable feature flags for checksum offload, -+scatter/gather or GSO by changing vif->netdev_features. -+Removing features from vif->netdev_features does not affect the netdev -+features themselves, but instead fixes up skbs in the tx path so that the -+offloads are not needed in the driver. -+ -+Aside from making it easier to deal with vif type based hardware limitations, -+this also makes it possible to optimize performance on hardware without native -+GSO support by declaring GSO support in hw->netdev_features and removing it -+from vif->netdev_features. This allows mac80211 to handle GSO segmentation -+after the sta lookup, but before itxq enqueue, thus reducing the number of -+unnecessary sta lookups, as well as some other per-packet processing. -+ -+Signed-off-by: Felix Fietkau -+--- -+ -+--- a/include/net/fq_impl.h -++++ b/include/net/fq_impl.h -+@@ -200,6 +200,7 @@ static void fq_tin_enqueue(struct fq *fq -+ fq_skb_free_t free_func) -+ { -+ struct fq_flow *flow; -++ struct sk_buff *next; -+ bool oom; -+ -+ lockdep_assert_held(&fq->lock); -+@@ -214,11 +215,15 @@ static void fq_tin_enqueue(struct fq *fq -+ } -+ -+ flow->tin = tin; -+- flow->backlog += skb->len; -+- tin->backlog_bytes += skb->len; -+- tin->backlog_packets++; -+- fq->memory_usage += skb->truesize; -+- fq->backlog++; -++ skb_list_walk_safe(skb, skb, next) { -++ skb_mark_not_on_list(skb); -++ flow->backlog += skb->len; -++ tin->backlog_bytes += skb->len; -++ tin->backlog_packets++; -++ fq->memory_usage += skb->truesize; -++ fq->backlog++; -++ __skb_queue_tail(&flow->queue, skb); -++ } -+ -+ if (list_empty(&flow->flowchain)) { -+ flow->deficit = fq->quantum; -+@@ -226,7 +231,6 @@ static void fq_tin_enqueue(struct fq *fq -+ &tin->new_flows); -+ } -+ -+- __skb_queue_tail(&flow->queue, skb); -+ oom = (fq->memory_usage > fq->memory_limit); -+ while (fq->backlog > fq->limit || oom) { -+ flow = fq_find_fattest_flow(fq); -+--- a/include/net/mac80211.h -++++ b/include/net/mac80211.h -+@@ -1807,6 +1807,10 @@ struct ieee80211_vif_cfg { -+ * @addr: address of this interface -+ * @p2p: indicates whether this AP or STA interface is a p2p -+ * interface, i.e. a GO or p2p-sta respectively -++ * @netdev_features: tx netdev features supported by the hardware for this -++ * vif. mac80211 initializes this to hw->netdev_features, and the driver -++ * can mask out specific tx features. mac80211 will handle software fixup -++ * for masked offloads (GSO, CSUM) -+ * @driver_flags: flags/capabilities the driver has for this interface, -+ * these need to be set (or cleared) when the interface is added -+ * or, if supported by the driver, the interface type is changed -+@@ -1846,6 +1850,7 @@ struct ieee80211_vif { -+ -+ struct ieee80211_txq *txq; -+ -++ netdev_features_t netdev_features; -+ u32 driver_flags; -+ u32 offload_flags; -+ -+--- a/net/mac80211/iface.c -++++ b/net/mac80211/iface.c -+@@ -2181,6 +2181,7 @@ int ieee80211_if_add(struct ieee80211_lo -+ ndev->priv_flags |= IFF_LIVE_ADDR_CHANGE; -+ ndev->hw_features |= ndev->features & -+ MAC80211_SUPPORTED_FEATURES_TX; -++ sdata->vif.netdev_features = local->hw.netdev_features; -+ -+ netdev_set_default_ethtool_ops(ndev, &ieee80211_ethtool_ops); -+ -+--- a/net/mac80211/tx.c -++++ b/net/mac80211/tx.c -+@@ -1356,7 +1356,11 @@ static struct txq_info *ieee80211_get_tx -+ -+ static void ieee80211_set_skb_enqueue_time(struct sk_buff *skb) -+ { -+- IEEE80211_SKB_CB(skb)->control.enqueue_time = codel_get_time(); -++ struct sk_buff *next; -++ codel_time_t now = codel_get_time(); -++ -++ skb_list_walk_safe(skb, skb, next) -++ IEEE80211_SKB_CB(skb)->control.enqueue_time = now; -+ } -+ -+ static u32 codel_skb_len_func(const struct sk_buff *skb) -+@@ -3579,55 +3583,79 @@ ieee80211_xmit_fast_finish(struct ieee80 -+ return TX_CONTINUE; -+ } -+ -+-static bool ieee80211_xmit_fast(struct ieee80211_sub_if_data *sdata, -+- struct sta_info *sta, -+- struct ieee80211_fast_tx *fast_tx, -+- struct sk_buff *skb) -++static netdev_features_t -++ieee80211_sdata_netdev_features(struct ieee80211_sub_if_data *sdata) -+ { -+- struct ieee80211_local *local = sdata->local; -+- u16 ethertype = (skb->data[12] << 8) | skb->data[13]; -+- int extra_head = fast_tx->hdr_len - (ETH_HLEN - 2); -+- int hw_headroom = sdata->local->hw.extra_tx_headroom; -+- struct ethhdr eth; -+- struct ieee80211_tx_info *info; -+- struct ieee80211_hdr *hdr = (void *)fast_tx->hdr; -+- struct ieee80211_tx_data tx; -+- ieee80211_tx_result r; -+- struct tid_ampdu_tx *tid_tx = NULL; -+- u8 tid = IEEE80211_NUM_TIDS; -++ if (sdata->vif.type != NL80211_IFTYPE_AP_VLAN) -++ return sdata->vif.netdev_features; -+ -+- /* control port protocol needs a lot of special handling */ -+- if (cpu_to_be16(ethertype) == sdata->control_port_protocol) -+- return false; -++ if (!sdata->bss) -++ return 0; -+ -+- /* only RFC 1042 SNAP */ -+- if (ethertype < ETH_P_802_3_MIN) -+- return false; -++ sdata = container_of(sdata->bss, struct ieee80211_sub_if_data, u.ap); -++ return sdata->vif.netdev_features; -++} -+ -+- /* don't handle TX status request here either */ -+- if (skb->sk && skb_shinfo(skb)->tx_flags & SKBTX_WIFI_STATUS) -+- return false; -++static struct sk_buff * -++ieee80211_tx_skb_fixup(struct sk_buff *skb, netdev_features_t features) -++{ -++ if (skb_is_gso(skb)) { -++ struct sk_buff *segs; -+ -+- if (hdr->frame_control & cpu_to_le16(IEEE80211_STYPE_QOS_DATA)) { -+- 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)) -+- return false; -+- if (tid_tx->timeout) -+- tid_tx->last_tx = jiffies; -+- } -++ segs = skb_gso_segment(skb, features); -++ if (!segs) -++ return skb; -++ if (IS_ERR(segs)) -++ goto free; -++ -++ consume_skb(skb); -++ return segs; -+ } -+ -+- /* after this point (skb is modified) we cannot return false */ -++ if (skb_needs_linearize(skb, features) && __skb_linearize(skb)) -++ goto free; -++ -++ if (skb->ip_summed == CHECKSUM_PARTIAL) { -++ int ofs = skb_checksum_start_offset(skb); -++ -++ if (skb->encapsulation) -++ skb_set_inner_transport_header(skb, ofs); -++ else -++ skb_set_transport_header(skb, ofs); -++ -++ if (skb_csum_hwoffload_help(skb, features)) -++ goto free; -++ } -++ -++ skb_mark_not_on_list(skb); -++ return skb; -++ -++free: -++ kfree_skb(skb); -++ return NULL; -++} -++ -++static void __ieee80211_xmit_fast(struct ieee80211_sub_if_data *sdata, -++ struct sta_info *sta, -++ struct ieee80211_fast_tx *fast_tx, -++ struct sk_buff *skb, u8 tid, bool ampdu) -++{ -++ struct ieee80211_local *local = sdata->local; -++ struct ieee80211_hdr *hdr = (void *)fast_tx->hdr; -++ struct ieee80211_tx_info *info; -++ struct ieee80211_tx_data tx; -++ ieee80211_tx_result r; -++ int hw_headroom = sdata->local->hw.extra_tx_headroom; -++ int extra_head = fast_tx->hdr_len - (ETH_HLEN - 2); -++ struct ethhdr eth; -+ -+ skb = skb_share_check(skb, GFP_ATOMIC); -+ if (unlikely(!skb)) -+- return true; -++ return; -+ -+ if ((hdr->frame_control & cpu_to_le16(IEEE80211_STYPE_QOS_DATA)) && -+ ieee80211_amsdu_aggregate(sdata, sta, fast_tx, skb)) -+- return true; -++ return; -+ -+ /* will not be crypto-handled beyond what we do here, so use false -+ * as the may-encrypt argument for the resize to not account for -+@@ -3636,10 +3664,8 @@ static bool ieee80211_xmit_fast(struct i -+ if (unlikely(ieee80211_skb_resize(sdata, skb, -+ max_t(int, extra_head + hw_headroom - -+ skb_headroom(skb), 0), -+- ENCRYPT_NO))) { -+- kfree_skb(skb); -+- return true; -+- } -++ ENCRYPT_NO))) -++ goto free; -+ -+ memcpy(ð, skb->data, ETH_HLEN - 2); -+ hdr = skb_push(skb, extra_head); -+@@ -3653,7 +3679,7 @@ static bool ieee80211_xmit_fast(struct i -+ info->control.vif = &sdata->vif; -+ info->flags = IEEE80211_TX_CTL_FIRST_FRAGMENT | -+ IEEE80211_TX_CTL_DONTFRAG | -+- (tid_tx ? IEEE80211_TX_CTL_AMPDU : 0); -++ (ampdu ? IEEE80211_TX_CTL_AMPDU : 0); -+ info->control.flags = IEEE80211_TX_CTRL_FAST_XMIT | -+ u32_encode_bits(IEEE80211_LINK_UNSPECIFIED, -+ IEEE80211_TX_CTRL_MLO_LINK); -+@@ -3677,16 +3703,14 @@ static bool ieee80211_xmit_fast(struct i -+ tx.key = fast_tx->key; -+ -+ if (ieee80211_queue_skb(local, sdata, sta, skb)) -+- return true; -++ return; -+ -+ tx.skb = skb; -+ r = ieee80211_xmit_fast_finish(sdata, sta, fast_tx->pn_offs, -+ fast_tx->key, &tx); -+ tx.skb = NULL; -+- if (r == TX_DROP) { -+- kfree_skb(skb); -+- return true; -+- } -++ if (r == TX_DROP) -++ goto free; -+ -+ if (sdata->vif.type == NL80211_IFTYPE_AP_VLAN) -+ sdata = container_of(sdata->bss, -+@@ -3694,6 +3718,56 @@ static bool ieee80211_xmit_fast(struct i -+ -+ __skb_queue_tail(&tx.skbs, skb); -+ ieee80211_tx_frags(local, &sdata->vif, sta, &tx.skbs, false); -++ return; -++ -++free: -++ kfree_skb(skb); -++} -++ -++static bool ieee80211_xmit_fast(struct ieee80211_sub_if_data *sdata, -++ struct sta_info *sta, -++ struct ieee80211_fast_tx *fast_tx, -++ struct sk_buff *skb) -++{ -++ u16 ethertype = (skb->data[12] << 8) | skb->data[13]; -++ struct ieee80211_hdr *hdr = (void *)fast_tx->hdr; -++ struct tid_ampdu_tx *tid_tx = NULL; -++ struct sk_buff *next; -++ u8 tid = IEEE80211_NUM_TIDS; -++ -++ /* control port protocol needs a lot of special handling */ -++ if (cpu_to_be16(ethertype) == sdata->control_port_protocol) -++ return false; -++ -++ /* only RFC 1042 SNAP */ -++ if (ethertype < ETH_P_802_3_MIN) -++ return false; -++ -++ /* don't handle TX status request here either */ -++ if (skb->sk && skb_shinfo(skb)->tx_flags & SKBTX_WIFI_STATUS) -++ return false; -++ -++ if (hdr->frame_control & cpu_to_le16(IEEE80211_STYPE_QOS_DATA)) { -++ 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)) -++ return false; -++ if (tid_tx->timeout) -++ tid_tx->last_tx = jiffies; -++ } -++ } -++ -++ /* after this point (skb is modified) we cannot return false */ -++ skb = ieee80211_tx_skb_fixup(skb, ieee80211_sdata_netdev_features(sdata)); -++ if (!skb) -++ return true; -++ -++ skb_list_walk_safe(skb, skb, next) { -++ skb_mark_not_on_list(skb); -++ __ieee80211_xmit_fast(sdata, sta, fast_tx, skb, tid, tid_tx); -++ } -++ -+ return true; -+ } -+ -+@@ -4201,31 +4275,14 @@ void __ieee80211_subif_start_xmit(struct -+ goto out; -+ } -+ -+- if (skb_is_gso(skb)) { -+- struct sk_buff *segs; -+- -+- segs = skb_gso_segment(skb, 0); -+- if (IS_ERR(segs)) { -+- goto out_free; -+- } else if (segs) { -+- consume_skb(skb); -+- skb = segs; -+- } -+- } else { -+- /* we cannot process non-linear frames on this path */ -+- if (skb_linearize(skb)) -+- goto out_free; -+- -+- /* the frame could be fragmented, software-encrypted, and other -+- * things so we cannot really handle checksum offload with it - -+- * fix it up in software before we handle anything else. -+- */ -+- if (skb->ip_summed == CHECKSUM_PARTIAL) { -+- skb_set_transport_header(skb, -+- skb_checksum_start_offset(skb)); -+- if (skb_checksum_help(skb)) -+- goto out_free; -+- } -++ /* the frame could be fragmented, software-encrypted, and other -++ * 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); -++ if (!skb) { -++ len = 0; -++ goto out; -+ } -+ -+ skb_list_walk_safe(skb, skb, next) { -+@@ -4443,9 +4500,11 @@ normal: -+ return NETDEV_TX_OK; -+ } -+ -+-static bool ieee80211_tx_8023(struct ieee80211_sub_if_data *sdata, -+- struct sk_buff *skb, struct sta_info *sta, -+- bool txpending) -++ -++ -++static bool __ieee80211_tx_8023(struct ieee80211_sub_if_data *sdata, -++ struct sk_buff *skb, struct sta_info *sta, -++ bool txpending) -+ { -+ struct ieee80211_local *local = sdata->local; -+ struct ieee80211_tx_control control = {}; -+@@ -4454,14 +4513,6 @@ static bool ieee80211_tx_8023(struct iee -+ unsigned long flags; -+ int q = info->hw_queue; -+ -+- if (sta) -+- sk_pacing_shift_update(skb->sk, local->hw.tx_sk_pacing_shift); -+- -+- ieee80211_tpt_led_trig_tx(local, skb->len); -+- -+- if (ieee80211_queue_skb(local, sdata, sta, skb)) -+- return true; -+- -+ spin_lock_irqsave(&local->queue_stop_reason_lock, flags); -+ -+ if (local->queue_stop_reasons[q] || -+@@ -4488,6 +4539,26 @@ static bool ieee80211_tx_8023(struct iee -+ return true; -+ } -+ -++static bool ieee80211_tx_8023(struct ieee80211_sub_if_data *sdata, -++ struct sk_buff *skb, struct sta_info *sta, -++ bool txpending) -++{ -++ struct ieee80211_local *local = sdata->local; -++ struct sk_buff *next; -++ bool ret = true; -++ -++ if (ieee80211_queue_skb(local, sdata, sta, skb)) -++ return true; -++ -++ skb_list_walk_safe(skb, skb, next) { -++ skb_mark_not_on_list(skb); -++ if (!__ieee80211_tx_8023(sdata, skb, sta, txpending)) -++ ret = false; -++ } -++ -++ return ret; -++} -++ -+ 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) -+@@ -4495,9 +4566,13 @@ static void ieee80211_8023_xmit(struct i -+ struct ieee80211_tx_info *info; -+ 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; -+ u8 tid; -+ -+- skb_set_queue_mapping(skb, ieee80211_select_queue(sdata, sta, skb)); -++ queue = ieee80211_select_queue(sdata, sta, skb); -++ skb_set_queue_mapping(skb, queue); -+ -+ if (unlikely(test_bit(SCAN_SW_SCANNING, &local->scanning)) && -+ test_bit(SDATA_STATE_OFFCHANNEL, &sdata->state)) -+@@ -4507,9 +4582,6 @@ static void ieee80211_8023_xmit(struct i -+ if (unlikely(!skb)) -+ return; -+ -+- info = IEEE80211_SKB_CB(skb); -+- memset(info, 0, sizeof(*info)); -+- -+ ieee80211_aggr_check(sdata, sta, skb); -+ -+ tid = skb->priority & IEEE80211_QOS_CTL_TAG1D_MASK; -+@@ -4523,22 +4595,20 @@ static void ieee80211_8023_xmit(struct i -+ return; -+ } -+ -+- info->flags |= IEEE80211_TX_CTL_AMPDU; -+ if (tid_tx->timeout) -+ tid_tx->last_tx = jiffies; -+ } -+ -+- 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); -++ skb = ieee80211_tx_skb_fixup(skb, ieee80211_sdata_netdev_features(sdata)); -++ if (!skb) -++ return; -+ -+- info->hw_queue = sdata->vif.hw_queue[skb_get_queue_mapping(skb)]; -++ info = IEEE80211_SKB_CB(skb); -++ memset(info, 0, sizeof(*info)); -++ if (tid_tx) -++ info->flags |= IEEE80211_TX_CTL_AMPDU; -+ -+- dev_sw_netstats_tx_add(dev, 1, skb->len); -+- -+- sta->deflink.tx_stats.bytes[skb_get_queue_mapping(skb)] += skb->len; -+- sta->deflink.tx_stats.packets[skb_get_queue_mapping(skb)]++; -++ info->hw_queue = sdata->vif.hw_queue[queue]; -+ -+ if (sdata->vif.type == NL80211_IFTYPE_AP_VLAN) -+ sdata = container_of(sdata->bss, -+@@ -4550,6 +4620,24 @@ static void ieee80211_8023_xmit(struct i -+ if (key) -+ info->control.hw_key = &key->conf; -+ -++ skb_list_walk_safe(skb, seg, next) { -++ skbs++; -++ len += seg->len; -++ if (seg != skb) -++ memcpy(IEEE80211_SKB_CB(seg), info, 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); -++ -++ dev_sw_netstats_tx_add(dev, skbs, len); -++ sta->deflink.tx_stats.packets[queue] += skbs; -++ sta->deflink.tx_stats.bytes[queue] += len; -++ -++ ieee80211_tpt_led_trig_tx(local, len); -++ -+ ieee80211_tx_8023(sdata, skb, sta, false); -+ -+ return; -+@@ -4591,6 +4679,7 @@ netdev_tx_t ieee80211_subif_start_xmit_8 -+ key->conf.cipher == WLAN_CIPHER_SUITE_TKIP)) -+ goto skip_offload; -+ -++ sk_pacing_shift_update(skb->sk, sdata->local->hw.tx_sk_pacing_shift); -+ ieee80211_8023_xmit(sdata, dev, sta, key, skb); -+ goto out; -+ -diff --git a/package/kernel/mac80211/patches/subsys/311-v6.2-wifi-mac80211-fix-and-simplify-unencrypted-drop-chec.patch b/package/kernel/mac80211/patches/subsys/311-v6.2-wifi-mac80211-fix-and-simplify-unencrypted-drop-chec.patch -new file mode 100644 -index 0000000000..804b02eb30 ---- /dev/null -+++ b/package/kernel/mac80211/patches/subsys/311-v6.2-wifi-mac80211-fix-and-simplify-unencrypted-drop-chec.patch -@@ -0,0 +1,87 @@ -+From: Felix Fietkau -+Date: Thu, 1 Dec 2022 14:57:30 +0100 -+Subject: [PATCH] wifi: mac80211: fix and simplify unencrypted drop check for -+ mesh -+ -+ieee80211_drop_unencrypted is called from ieee80211_rx_h_mesh_fwding and -+ieee80211_frame_allowed. -+ -+Since ieee80211_rx_h_mesh_fwding can forward packets for other mesh nodes -+and is called earlier, it needs to check the decryptions status and if the -+packet is using the control protocol on its own, instead of deferring to -+the later call from ieee80211_frame_allowed. -+ -+Because of that, ieee80211_drop_unencrypted has a mesh specific check -+that skips over the mesh header in order to check the payload protocol. -+This code is invalid when called from ieee80211_frame_allowed, since that -+happens after the 802.11->802.3 conversion. -+ -+Fix this by moving the mesh specific check directly into -+ieee80211_rx_h_mesh_fwding. -+ -+Signed-off-by: Felix Fietkau -+Link: https://lore.kernel.org/r/20221201135730.19723-1-nbd@nbd.name -+Signed-off-by: Johannes Berg -+--- -+ -+--- a/net/mac80211/rx.c -++++ b/net/mac80211/rx.c -+@@ -2403,7 +2403,6 @@ static int ieee80211_802_1x_port_control -+ -+ static int ieee80211_drop_unencrypted(struct ieee80211_rx_data *rx, __le16 fc) -+ { -+- struct ieee80211_hdr *hdr = (void *)rx->skb->data; -+ struct sk_buff *skb = rx->skb; -+ struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb); -+ -+@@ -2414,31 +2413,6 @@ static int ieee80211_drop_unencrypted(st -+ if (status->flag & RX_FLAG_DECRYPTED) -+ return 0; -+ -+- /* check mesh EAPOL frames first */ -+- if (unlikely(rx->sta && ieee80211_vif_is_mesh(&rx->sdata->vif) && -+- ieee80211_is_data(fc))) { -+- struct ieee80211s_hdr *mesh_hdr; -+- u16 hdr_len = ieee80211_hdrlen(fc); -+- u16 ethertype_offset; -+- __be16 ethertype; -+- -+- if (!ether_addr_equal(hdr->addr1, rx->sdata->vif.addr)) -+- goto drop_check; -+- -+- /* make sure fixed part of mesh header is there, also checks skb len */ -+- if (!pskb_may_pull(rx->skb, hdr_len + 6)) -+- goto drop_check; -+- -+- mesh_hdr = (struct ieee80211s_hdr *)(skb->data + hdr_len); -+- ethertype_offset = hdr_len + ieee80211_get_mesh_hdrlen(mesh_hdr) + -+- sizeof(rfc1042_header); -+- -+- if (skb_copy_bits(rx->skb, ethertype_offset, ðertype, 2) == 0 && -+- ethertype == rx->sdata->control_port_protocol) -+- return 0; -+- } -+- -+-drop_check: -+ /* Drop unencrypted frames if key is set. */ -+ if (unlikely(!ieee80211_has_protected(fc) && -+ !ieee80211_is_any_nullfunc(fc) && -+@@ -2892,8 +2866,16 @@ ieee80211_rx_h_mesh_fwding(struct ieee80 -+ hdr = (struct ieee80211_hdr *) skb->data; -+ mesh_hdr = (struct ieee80211s_hdr *) (skb->data + hdrlen); -+ -+- if (ieee80211_drop_unencrypted(rx, hdr->frame_control)) -+- return RX_DROP_MONITOR; -++ if (ieee80211_drop_unencrypted(rx, hdr->frame_control)) { -++ int offset = hdrlen + ieee80211_get_mesh_hdrlen(mesh_hdr) + -++ sizeof(rfc1042_header); -++ __be16 ethertype; -++ -++ if (!ether_addr_equal(hdr->addr1, rx->sdata->vif.addr) || -++ skb_copy_bits(rx->skb, offset, ðertype, 2) != 0 || -++ ethertype != rx->sdata->control_port_protocol) -++ return RX_DROP_MONITOR; -++ } -+ -+ /* frame is in RMC, don't forward */ -+ if (ieee80211_is_data(hdr->frame_control) && -diff --git a/package/kernel/mac80211/patches/subsys/312-v6.3-wifi-cfg80211-move-A-MSDU-check-in-ieee80211_data_to.patch b/package/kernel/mac80211/patches/subsys/312-v6.3-wifi-cfg80211-move-A-MSDU-check-in-ieee80211_data_to.patch -new file mode 100644 -index 0000000000..f668905cca ---- /dev/null -+++ b/package/kernel/mac80211/patches/subsys/312-v6.3-wifi-cfg80211-move-A-MSDU-check-in-ieee80211_data_to.patch -@@ -0,0 +1,25 @@ -+From: Felix Fietkau -+Date: Fri, 2 Dec 2022 13:53:11 +0100 -+Subject: [PATCH] wifi: cfg80211: move A-MSDU check in -+ ieee80211_data_to_8023_exthdr -+ -+When parsing the outer A-MSDU header, don't check for inner bridge tunnel -+or RFC1042 headers. This is handled by ieee80211_amsdu_to_8023s already. -+ -+Signed-off-by: Felix Fietkau -+--- -+ -+--- a/net/wireless/util.c -++++ b/net/wireless/util.c -+@@ -631,8 +631,9 @@ int ieee80211_data_to_8023_exthdr(struct -+ break; -+ } -+ -+- if (likely(skb_copy_bits(skb, hdrlen, &payload, sizeof(payload)) == 0 && -+- ((!is_amsdu && ether_addr_equal(payload.hdr, rfc1042_header) && -++ if (likely(!is_amsdu && -++ skb_copy_bits(skb, hdrlen, &payload, sizeof(payload)) == 0 && -++ ((ether_addr_equal(payload.hdr, rfc1042_header) && -+ payload.proto != htons(ETH_P_AARP) && -+ payload.proto != htons(ETH_P_IPX)) || -+ ether_addr_equal(payload.hdr, bridge_tunnel_header)))) { -diff --git a/package/kernel/mac80211/patches/subsys/313-v6.3-wifi-cfg80211-factor-out-bridge-tunnel-RFC1042-heade.patch b/package/kernel/mac80211/patches/subsys/313-v6.3-wifi-cfg80211-factor-out-bridge-tunnel-RFC1042-heade.patch -new file mode 100644 -index 0000000000..8641057869 ---- /dev/null -+++ b/package/kernel/mac80211/patches/subsys/313-v6.3-wifi-cfg80211-factor-out-bridge-tunnel-RFC1042-heade.patch -@@ -0,0 +1,76 @@ -+From: Felix Fietkau -+Date: Fri, 2 Dec 2022 13:54:15 +0100 -+Subject: [PATCH] wifi: cfg80211: factor out bridge tunnel / RFC1042 header -+ check -+ -+The same check is done in multiple places, unify it. -+ -+Signed-off-by: Felix Fietkau -+--- -+ -+--- a/net/wireless/util.c -++++ b/net/wireless/util.c -+@@ -542,6 +542,21 @@ unsigned int ieee80211_get_mesh_hdrlen(s -+ } -+ EXPORT_SYMBOL(ieee80211_get_mesh_hdrlen); -+ -++static bool ieee80211_get_8023_tunnel_proto(const void *hdr, __be16 *proto) -++{ -++ const __be16 *hdr_proto = hdr + ETH_ALEN; -++ -++ if (!(ether_addr_equal(hdr, rfc1042_header) && -++ *hdr_proto != htons(ETH_P_AARP) && -++ *hdr_proto != htons(ETH_P_IPX)) && -++ !ether_addr_equal(hdr, bridge_tunnel_header)) -++ return false; -++ -++ *proto = *hdr_proto; -++ -++ return true; -++} -++ -+ int ieee80211_data_to_8023_exthdr(struct sk_buff *skb, struct ethhdr *ehdr, -+ const u8 *addr, enum nl80211_iftype iftype, -+ u8 data_offset, bool is_amsdu) -+@@ -633,14 +648,9 @@ int ieee80211_data_to_8023_exthdr(struct -+ -+ if (likely(!is_amsdu && -+ skb_copy_bits(skb, hdrlen, &payload, sizeof(payload)) == 0 && -+- ((ether_addr_equal(payload.hdr, rfc1042_header) && -+- payload.proto != htons(ETH_P_AARP) && -+- payload.proto != htons(ETH_P_IPX)) || -+- ether_addr_equal(payload.hdr, bridge_tunnel_header)))) { -+- /* remove RFC1042 or Bridge-Tunnel encapsulation and -+- * replace EtherType */ -++ ieee80211_get_8023_tunnel_proto(&payload, &tmp.h_proto))) { -++ /* remove RFC1042 or Bridge-Tunnel encapsulation */ -+ hdrlen += ETH_ALEN + 2; -+- tmp.h_proto = payload.proto; -+ skb_postpull_rcsum(skb, &payload, ETH_ALEN + 2); -+ } else { -+ tmp.h_proto = htons(skb->len - hdrlen); -+@@ -756,8 +766,6 @@ void ieee80211_amsdu_to_8023s(struct sk_ -+ { -+ unsigned int hlen = ALIGN(extra_headroom, 4); -+ struct sk_buff *frame = NULL; -+- u16 ethertype; -+- u8 *payload; -+ int offset = 0, remaining; -+ struct ethhdr eth; -+ bool reuse_frag = skb->head_frag && !skb_has_frag_list(skb); -+@@ -811,14 +819,8 @@ void ieee80211_amsdu_to_8023s(struct sk_ -+ frame->dev = skb->dev; -+ frame->priority = skb->priority; -+ -+- payload = frame->data; -+- ethertype = (payload[6] << 8) | payload[7]; -+- if (likely((ether_addr_equal(payload, rfc1042_header) && -+- ethertype != ETH_P_AARP && ethertype != ETH_P_IPX) || -+- ether_addr_equal(payload, bridge_tunnel_header))) { -+- eth.h_proto = htons(ethertype); -++ if (likely(ieee80211_get_8023_tunnel_proto(frame->data, ð.h_proto))) -+ skb_pull(frame, ETH_ALEN + 2); -+- } -+ -+ memcpy(skb_push(frame, sizeof(eth)), ð, sizeof(eth)); -+ __skb_queue_tail(list, frame); -diff --git a/package/kernel/mac80211/patches/subsys/314-v6.3-wifi-mac80211-remove-mesh-forwarding-congestion-chec.patch b/package/kernel/mac80211/patches/subsys/314-v6.3-wifi-mac80211-remove-mesh-forwarding-congestion-chec.patch -new file mode 100644 -index 0000000000..515176f0de ---- /dev/null -+++ b/package/kernel/mac80211/patches/subsys/314-v6.3-wifi-mac80211-remove-mesh-forwarding-congestion-chec.patch -@@ -0,0 +1,54 @@ -+From: Felix Fietkau -+Date: Fri, 2 Dec 2022 17:01:46 +0100 -+Subject: [PATCH] wifi: mac80211: remove mesh forwarding congestion check -+ -+Now that all drivers use iTXQ, it does not make sense to check to drop -+tx forwarding packets when the driver has stopped the queues. -+fq_codel will take care of dropping packets when the queues fill up -+ -+Signed-off-by: Felix Fietkau -+--- -+ -+--- a/net/mac80211/debugfs_netdev.c -++++ b/net/mac80211/debugfs_netdev.c -+@@ -603,8 +603,6 @@ IEEE80211_IF_FILE(fwded_mcast, u.mesh.ms -+ IEEE80211_IF_FILE(fwded_unicast, u.mesh.mshstats.fwded_unicast, DEC); -+ IEEE80211_IF_FILE(fwded_frames, u.mesh.mshstats.fwded_frames, DEC); -+ IEEE80211_IF_FILE(dropped_frames_ttl, u.mesh.mshstats.dropped_frames_ttl, DEC); -+-IEEE80211_IF_FILE(dropped_frames_congestion, -+- u.mesh.mshstats.dropped_frames_congestion, DEC); -+ IEEE80211_IF_FILE(dropped_frames_no_route, -+ u.mesh.mshstats.dropped_frames_no_route, DEC); -+ -+@@ -740,7 +738,6 @@ static void add_mesh_stats(struct ieee80 -+ MESHSTATS_ADD(fwded_frames); -+ MESHSTATS_ADD(dropped_frames_ttl); -+ MESHSTATS_ADD(dropped_frames_no_route); -+- MESHSTATS_ADD(dropped_frames_congestion); -+ #undef MESHSTATS_ADD -+ } -+ -+--- a/net/mac80211/ieee80211_i.h -++++ b/net/mac80211/ieee80211_i.h -+@@ -329,7 +329,6 @@ struct mesh_stats { -+ __u32 fwded_frames; /* Mesh total forwarded frames */ -+ __u32 dropped_frames_ttl; /* Not transmitted since mesh_ttl == 0*/ -+ __u32 dropped_frames_no_route; /* Not transmitted, no route found */ -+- __u32 dropped_frames_congestion;/* Not forwarded due to congestion */ -+ }; -+ -+ #define PREQ_Q_F_START 0x1 -+--- a/net/mac80211/rx.c -++++ b/net/mac80211/rx.c -+@@ -2926,11 +2926,6 @@ ieee80211_rx_h_mesh_fwding(struct ieee80 -+ return RX_CONTINUE; -+ -+ ac = ieee802_1d_to_ac[skb->priority]; -+- q = sdata->vif.hw_queue[ac]; -+- if (ieee80211_queue_stopped(&local->hw, q)) { -+- IEEE80211_IFSTA_MESH_CTR_INC(ifmsh, dropped_frames_congestion); -+- return RX_DROP_MONITOR; -+- } -+ skb_set_queue_mapping(skb, ac); -+ -+ if (!--mesh_hdr->ttl) { -diff --git a/package/kernel/mac80211/patches/subsys/315-v6.3-wifi-mac80211-fix-receiving-A-MSDU-frames-on-mesh-in.patch b/package/kernel/mac80211/patches/subsys/315-v6.3-wifi-mac80211-fix-receiving-A-MSDU-frames-on-mesh-in.patch -new file mode 100644 -index 0000000000..59b799b6b1 ---- /dev/null -+++ b/package/kernel/mac80211/patches/subsys/315-v6.3-wifi-mac80211-fix-receiving-A-MSDU-frames-on-mesh-in.patch -@@ -0,0 +1,762 @@ -+From 986e43b19ae9176093da35e0a844e65c8bf9ede7 Mon Sep 17 00:00:00 2001 -+From: Felix Fietkau -+Date: Mon, 13 Feb 2023 11:08:54 +0100 -+Subject: [PATCH] wifi: mac80211: fix receiving A-MSDU frames on mesh -+ interfaces -+ -+The current mac80211 mesh A-MSDU receive path fails to parse A-MSDU packets -+on mesh interfaces, because it assumes that the Mesh Control field is always -+directly after the 802.11 header. -+802.11-2020 9.3.2.2.2 Figure 9-70 shows that the Mesh Control field is -+actually part of the A-MSDU subframe header. -+This makes more sense, since it allows packets for multiple different -+destinations to be included in the same A-MSDU, as long as RA and TID are -+still the same. -+Another issue is the fact that the A-MSDU subframe length field was apparently -+accidentally defined as little-endian in the standard. -+ -+In order to fix this, the mesh forwarding path needs happen at a different -+point in the receive path. -+ -+ieee80211_data_to_8023_exthdr is changed to ignore the mesh control field -+and leave it in after the ethernet header. This also affects the source/dest -+MAC address fields, which now in the case of mesh point to the mesh SA/DA. -+ -+ieee80211_amsdu_to_8023s is changed to deal with the endian difference and -+to add the Mesh Control length to the subframe length, since it's not covered -+by the MSDU length field. -+ -+With these changes, the mac80211 will get the same packet structure for -+converted regular data packets and unpacked A-MSDU subframes. -+ -+The mesh forwarding checks are now only performed after the A-MSDU decap. -+For locally received packets, the Mesh Control header is stripped away. -+For forwarded packets, a new 802.11 header gets added. -+ -+Signed-off-by: Felix Fietkau -+Link: https://lore.kernel.org/r/20230213100855.34315-4-nbd@nbd.name -+[fix fortify build error] -+Signed-off-by: Johannes Berg -+--- -+ .../wireless/marvell/mwifiex/11n_rxreorder.c | 2 +- -+ include/net/cfg80211.h | 27 +- -+ net/mac80211/rx.c | 350 ++++++++++-------- -+ net/wireless/util.c | 120 +++--- -+ 4 files changed, 297 insertions(+), 202 deletions(-) -+ -+--- a/drivers/net/wireless/marvell/mwifiex/11n_rxreorder.c -++++ b/drivers/net/wireless/marvell/mwifiex/11n_rxreorder.c -+@@ -33,7 +33,7 @@ static int mwifiex_11n_dispatch_amsdu_pk -+ skb_trim(skb, le16_to_cpu(local_rx_pd->rx_pkt_length)); -+ -+ ieee80211_amsdu_to_8023s(skb, &list, priv->curr_addr, -+- priv->wdev.iftype, 0, NULL, NULL); -++ priv->wdev.iftype, 0, NULL, NULL, false); -+ -+ while (!skb_queue_empty(&list)) { -+ struct rx_packet_hdr *rx_hdr; -+--- a/include/net/cfg80211.h -++++ b/include/net/cfg80211.h -+@@ -6208,11 +6208,36 @@ static inline int ieee80211_data_to_8023 -+ * @extra_headroom: The hardware extra headroom for SKBs in the @list. -+ * @check_da: DA to check in the inner ethernet header, or NULL -+ * @check_sa: SA to check in the inner ethernet header, or NULL -++ * @mesh_control: A-MSDU subframe header includes the mesh control field -+ */ -+ void ieee80211_amsdu_to_8023s(struct sk_buff *skb, struct sk_buff_head *list, -+ const u8 *addr, enum nl80211_iftype iftype, -+ const unsigned int extra_headroom, -+- const u8 *check_da, const u8 *check_sa); -++ const u8 *check_da, const u8 *check_sa, -++ bool mesh_control); -++ -++/** -++ * ieee80211_get_8023_tunnel_proto - get RFC1042 or bridge tunnel encap protocol -++ * -++ * Check for RFC1042 or bridge tunnel header and fetch the encapsulated -++ * protocol. -++ * -++ * @hdr: pointer to the MSDU payload -++ * @proto: destination pointer to store the protocol -++ * Return: true if encapsulation was found -++ */ -++bool ieee80211_get_8023_tunnel_proto(const void *hdr, __be16 *proto); -++ -++/** -++ * ieee80211_strip_8023_mesh_hdr - strip mesh header from converted 802.3 frames -++ * -++ * Strip the mesh header, which was left in by ieee80211_data_to_8023 as part -++ * of the MSDU data. Also move any source/destination addresses from the mesh -++ * header to the ethernet header (if present). -++ * -++ * @skb: The 802.3 frame with embedded mesh header -++ */ -++int ieee80211_strip_8023_mesh_hdr(struct sk_buff *skb); -+ -+ /** -+ * cfg80211_classify8021d - determine the 802.1p/1d tag for a data frame -+--- a/net/mac80211/rx.c -++++ b/net/mac80211/rx.c -+@@ -2720,6 +2720,174 @@ ieee80211_deliver_skb(struct ieee80211_r -+ } -+ } -+ -++static ieee80211_rx_result -++ieee80211_rx_mesh_data(struct ieee80211_sub_if_data *sdata, struct sta_info *sta, -++ struct sk_buff *skb) -++{ -++#ifdef CPTCFG_MAC80211_MESH -++ struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh; -++ struct ieee80211_local *local = sdata->local; -++ uint16_t fc = IEEE80211_FTYPE_DATA | IEEE80211_STYPE_QOS_DATA; -++ struct ieee80211_hdr hdr = { -++ .frame_control = cpu_to_le16(fc) -++ }; -++ struct ieee80211_hdr *fwd_hdr; -++ struct ieee80211s_hdr *mesh_hdr; -++ struct ieee80211_tx_info *info; -++ struct sk_buff *fwd_skb; -++ struct ethhdr *eth; -++ bool multicast; -++ int tailroom = 0; -++ int hdrlen, mesh_hdrlen; -++ u8 *qos; -++ -++ if (!ieee80211_vif_is_mesh(&sdata->vif)) -++ return RX_CONTINUE; -++ -++ if (!pskb_may_pull(skb, sizeof(*eth) + 6)) -++ return RX_DROP_MONITOR; -++ -++ mesh_hdr = (struct ieee80211s_hdr *)(skb->data + sizeof(*eth)); -++ mesh_hdrlen = ieee80211_get_mesh_hdrlen(mesh_hdr); -++ -++ if (!pskb_may_pull(skb, sizeof(*eth) + mesh_hdrlen)) -++ return RX_DROP_MONITOR; -++ -++ eth = (struct ethhdr *)skb->data; -++ multicast = is_multicast_ether_addr(eth->h_dest); -++ -++ mesh_hdr = (struct ieee80211s_hdr *)(eth + 1); -++ if (!mesh_hdr->ttl) -++ return RX_DROP_MONITOR; -++ -++ /* frame is in RMC, don't forward */ -++ if (is_multicast_ether_addr(eth->h_dest) && -++ mesh_rmc_check(sdata, eth->h_source, mesh_hdr)) -++ return RX_DROP_MONITOR; -++ -++ /* Frame has reached destination. Don't forward */ -++ if (ether_addr_equal(sdata->vif.addr, eth->h_dest)) -++ goto rx_accept; -++ -++ if (!ifmsh->mshcfg.dot11MeshForwarding) { -++ if (is_multicast_ether_addr(eth->h_dest)) -++ goto rx_accept; -++ -++ return RX_DROP_MONITOR; -++ } -++ -++ /* forward packet */ -++ if (sdata->crypto_tx_tailroom_needed_cnt) -++ tailroom = IEEE80211_ENCRYPT_TAILROOM; -++ -++ if (!--mesh_hdr->ttl) { -++ if (multicast) -++ goto rx_accept; -++ -++ IEEE80211_IFSTA_MESH_CTR_INC(ifmsh, dropped_frames_ttl); -++ return RX_DROP_MONITOR; -++ } -++ -++ if (mesh_hdr->flags & MESH_FLAGS_AE) { -++ struct mesh_path *mppath; -++ char *proxied_addr; -++ -++ if (multicast) -++ proxied_addr = mesh_hdr->eaddr1; -++ else if ((mesh_hdr->flags & MESH_FLAGS_AE) == MESH_FLAGS_AE_A5_A6) -++ /* has_a4 already checked in ieee80211_rx_mesh_check */ -++ proxied_addr = mesh_hdr->eaddr2; -++ else -++ return RX_DROP_MONITOR; -++ -++ rcu_read_lock(); -++ mppath = mpp_path_lookup(sdata, proxied_addr); -++ if (!mppath) { -++ mpp_path_add(sdata, proxied_addr, eth->h_source); -++ } else { -++ spin_lock_bh(&mppath->state_lock); -++ if (!ether_addr_equal(mppath->mpp, eth->h_source)) -++ memcpy(mppath->mpp, eth->h_source, ETH_ALEN); -++ mppath->exp_time = jiffies; -++ spin_unlock_bh(&mppath->state_lock); -++ } -++ rcu_read_unlock(); -++ } -++ -++ skb_set_queue_mapping(skb, ieee802_1d_to_ac[skb->priority]); -++ -++ ieee80211_fill_mesh_addresses(&hdr, &hdr.frame_control, -++ eth->h_dest, eth->h_source); -++ hdrlen = ieee80211_hdrlen(hdr.frame_control); -++ if (multicast) { -++ int extra_head = sizeof(struct ieee80211_hdr) - sizeof(*eth); -++ -++ fwd_skb = skb_copy_expand(skb, local->tx_headroom + extra_head + -++ IEEE80211_ENCRYPT_HEADROOM, -++ tailroom, GFP_ATOMIC); -++ if (!fwd_skb) -++ goto rx_accept; -++ } else { -++ fwd_skb = skb; -++ skb = NULL; -++ -++ if (skb_cow_head(fwd_skb, hdrlen - sizeof(struct ethhdr))) -++ return RX_DROP_UNUSABLE; -++ } -++ -++ fwd_hdr = skb_push(fwd_skb, hdrlen - sizeof(struct ethhdr)); -++ memcpy(fwd_hdr, &hdr, hdrlen - 2); -++ qos = ieee80211_get_qos_ctl(fwd_hdr); -++ qos[0] = qos[1] = 0; -++ -++ skb_reset_mac_header(fwd_skb); -++ hdrlen += mesh_hdrlen; -++ if (ieee80211_get_8023_tunnel_proto(fwd_skb->data + hdrlen, -++ &fwd_skb->protocol)) -++ hdrlen += ETH_ALEN; -++ else -++ fwd_skb->protocol = htons(fwd_skb->len - hdrlen); -++ skb_set_network_header(fwd_skb, hdrlen); -++ -++ info = IEEE80211_SKB_CB(fwd_skb); -++ memset(info, 0, sizeof(*info)); -++ info->control.flags |= IEEE80211_TX_INTCFL_NEED_TXPROCESSING; -++ info->control.vif = &sdata->vif; -++ info->control.jiffies = jiffies; -++ if (multicast) { -++ IEEE80211_IFSTA_MESH_CTR_INC(ifmsh, fwded_mcast); -++ memcpy(fwd_hdr->addr2, sdata->vif.addr, ETH_ALEN); -++ /* update power mode indication when forwarding */ -++ ieee80211_mps_set_frame_flags(sdata, NULL, fwd_hdr); -++ } else if (!mesh_nexthop_lookup(sdata, fwd_skb)) { -++ /* mesh power mode flags updated in mesh_nexthop_lookup */ -++ IEEE80211_IFSTA_MESH_CTR_INC(ifmsh, fwded_unicast); -++ } else { -++ /* unable to resolve next hop */ -++ if (sta) -++ mesh_path_error_tx(sdata, ifmsh->mshcfg.element_ttl, -++ hdr.addr3, 0, -++ WLAN_REASON_MESH_PATH_NOFORWARD, -++ sta->sta.addr); -++ IEEE80211_IFSTA_MESH_CTR_INC(ifmsh, dropped_frames_no_route); -++ kfree_skb(fwd_skb); -++ goto rx_accept; -++ } -++ -++ IEEE80211_IFSTA_MESH_CTR_INC(ifmsh, fwded_frames); -++ fwd_skb->dev = sdata->dev; -++ ieee80211_add_pending_skb(local, fwd_skb); -++ -++rx_accept: -++ if (!skb) -++ return RX_QUEUED; -++ -++ ieee80211_strip_8023_mesh_hdr(skb); -++#endif -++ -++ return RX_CONTINUE; -++} -++ -+ static ieee80211_rx_result debug_noinline -+ __ieee80211_rx_h_amsdu(struct ieee80211_rx_data *rx, u8 data_offset) -+ { -+@@ -2728,8 +2896,10 @@ __ieee80211_rx_h_amsdu(struct ieee80211_ -+ struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; -+ __le16 fc = hdr->frame_control; -+ struct sk_buff_head frame_list; -++ static ieee80211_rx_result res; -+ struct ethhdr ethhdr; -+ const u8 *check_da = ethhdr.h_dest, *check_sa = ethhdr.h_source; -++ bool mesh = false; -+ -+ if (unlikely(ieee80211_has_a4(hdr->frame_control))) { -+ check_da = NULL; -+@@ -2746,6 +2916,8 @@ __ieee80211_rx_h_amsdu(struct ieee80211_ -+ break; -+ case NL80211_IFTYPE_MESH_POINT: -+ check_sa = NULL; -++ check_da = NULL; -++ mesh = true; -+ break; -+ default: -+ break; -+@@ -2763,17 +2935,29 @@ __ieee80211_rx_h_amsdu(struct ieee80211_ -+ ieee80211_amsdu_to_8023s(skb, &frame_list, dev->dev_addr, -+ rx->sdata->vif.type, -+ rx->local->hw.extra_tx_headroom, -+- check_da, check_sa); -++ check_da, check_sa, mesh); -+ -+ while (!skb_queue_empty(&frame_list)) { -+ rx->skb = __skb_dequeue(&frame_list); -+ -+- if (!ieee80211_frame_allowed(rx, fc)) { -+- dev_kfree_skb(rx->skb); -++ res = ieee80211_rx_mesh_data(rx->sdata, rx->sta, rx->skb); -++ switch (res) { -++ case RX_QUEUED: -+ continue; -++ case RX_CONTINUE: -++ break; -++ default: -++ goto free; -+ } -+ -++ if (!ieee80211_frame_allowed(rx, fc)) -++ goto free; -++ -+ ieee80211_deliver_skb(rx); -++ continue; -++ -++free: -++ dev_kfree_skb(rx->skb); -+ } -+ -+ return RX_QUEUED; -+@@ -2806,6 +2990,8 @@ ieee80211_rx_h_amsdu(struct ieee80211_rx -+ if (!rx->sdata->u.mgd.use_4addr) -+ return RX_DROP_UNUSABLE; -+ break; -++ case NL80211_IFTYPE_MESH_POINT: -++ break; -+ default: -+ return RX_DROP_UNUSABLE; -+ } -+@@ -2834,155 +3020,6 @@ ieee80211_rx_h_amsdu(struct ieee80211_rx -+ return __ieee80211_rx_h_amsdu(rx, 0); -+ } -+ -+-#ifdef CPTCFG_MAC80211_MESH -+-static ieee80211_rx_result -+-ieee80211_rx_h_mesh_fwding(struct ieee80211_rx_data *rx) -+-{ -+- struct ieee80211_hdr *fwd_hdr, *hdr; -+- struct ieee80211_tx_info *info; -+- struct ieee80211s_hdr *mesh_hdr; -+- struct sk_buff *skb = rx->skb, *fwd_skb; -+- struct ieee80211_local *local = rx->local; -+- struct ieee80211_sub_if_data *sdata = rx->sdata; -+- struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh; -+- u16 ac, q, hdrlen; -+- int tailroom = 0; -+- -+- hdr = (struct ieee80211_hdr *) skb->data; -+- hdrlen = ieee80211_hdrlen(hdr->frame_control); -+- -+- /* make sure fixed part of mesh header is there, also checks skb len */ -+- if (!pskb_may_pull(rx->skb, hdrlen + 6)) -+- return RX_DROP_MONITOR; -+- -+- mesh_hdr = (struct ieee80211s_hdr *) (skb->data + hdrlen); -+- -+- /* make sure full mesh header is there, also checks skb len */ -+- if (!pskb_may_pull(rx->skb, -+- hdrlen + ieee80211_get_mesh_hdrlen(mesh_hdr))) -+- return RX_DROP_MONITOR; -+- -+- /* reload pointers */ -+- hdr = (struct ieee80211_hdr *) skb->data; -+- mesh_hdr = (struct ieee80211s_hdr *) (skb->data + hdrlen); -+- -+- if (ieee80211_drop_unencrypted(rx, hdr->frame_control)) { -+- int offset = hdrlen + ieee80211_get_mesh_hdrlen(mesh_hdr) + -+- sizeof(rfc1042_header); -+- __be16 ethertype; -+- -+- if (!ether_addr_equal(hdr->addr1, rx->sdata->vif.addr) || -+- skb_copy_bits(rx->skb, offset, ðertype, 2) != 0 || -+- ethertype != rx->sdata->control_port_protocol) -+- return RX_DROP_MONITOR; -+- } -+- -+- /* frame is in RMC, don't forward */ -+- if (ieee80211_is_data(hdr->frame_control) && -+- is_multicast_ether_addr(hdr->addr1) && -+- mesh_rmc_check(rx->sdata, hdr->addr3, mesh_hdr)) -+- return RX_DROP_MONITOR; -+- -+- if (!ieee80211_is_data(hdr->frame_control)) -+- return RX_CONTINUE; -+- -+- if (!mesh_hdr->ttl) -+- return RX_DROP_MONITOR; -+- -+- if (mesh_hdr->flags & MESH_FLAGS_AE) { -+- struct mesh_path *mppath; -+- char *proxied_addr; -+- char *mpp_addr; -+- -+- if (is_multicast_ether_addr(hdr->addr1)) { -+- mpp_addr = hdr->addr3; -+- proxied_addr = mesh_hdr->eaddr1; -+- } else if ((mesh_hdr->flags & MESH_FLAGS_AE) == -+- MESH_FLAGS_AE_A5_A6) { -+- /* has_a4 already checked in ieee80211_rx_mesh_check */ -+- mpp_addr = hdr->addr4; -+- proxied_addr = mesh_hdr->eaddr2; -+- } else { -+- return RX_DROP_MONITOR; -+- } -+- -+- 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)) -+- memcpy(mppath->mpp, mpp_addr, ETH_ALEN); -+- mppath->exp_time = jiffies; -+- spin_unlock_bh(&mppath->state_lock); -+- } -+- rcu_read_unlock(); -+- } -+- -+- /* Frame has reached destination. Don't forward */ -+- if (!is_multicast_ether_addr(hdr->addr1) && -+- ether_addr_equal(sdata->vif.addr, hdr->addr3)) -+- return RX_CONTINUE; -+- -+- ac = ieee802_1d_to_ac[skb->priority]; -+- skb_set_queue_mapping(skb, ac); -+- -+- if (!--mesh_hdr->ttl) { -+- if (!is_multicast_ether_addr(hdr->addr1)) -+- IEEE80211_IFSTA_MESH_CTR_INC(ifmsh, -+- dropped_frames_ttl); -+- goto out; -+- } -+- -+- if (!ifmsh->mshcfg.dot11MeshForwarding) -+- goto out; -+- -+- if (sdata->crypto_tx_tailroom_needed_cnt) -+- tailroom = IEEE80211_ENCRYPT_TAILROOM; -+- -+- fwd_skb = skb_copy_expand(skb, local->tx_headroom + -+- IEEE80211_ENCRYPT_HEADROOM, -+- tailroom, GFP_ATOMIC); -+- if (!fwd_skb) -+- goto out; -+- -+- fwd_skb->dev = sdata->dev; -+- fwd_hdr = (struct ieee80211_hdr *) fwd_skb->data; -+- fwd_hdr->frame_control &= ~cpu_to_le16(IEEE80211_FCTL_RETRY); -+- info = IEEE80211_SKB_CB(fwd_skb); -+- memset(info, 0, sizeof(*info)); -+- info->control.flags |= IEEE80211_TX_INTCFL_NEED_TXPROCESSING; -+- info->control.vif = &rx->sdata->vif; -+- info->control.jiffies = jiffies; -+- if (is_multicast_ether_addr(fwd_hdr->addr1)) { -+- IEEE80211_IFSTA_MESH_CTR_INC(ifmsh, fwded_mcast); -+- memcpy(fwd_hdr->addr2, sdata->vif.addr, ETH_ALEN); -+- /* update power mode indication when forwarding */ -+- ieee80211_mps_set_frame_flags(sdata, NULL, fwd_hdr); -+- } else if (!mesh_nexthop_lookup(sdata, fwd_skb)) { -+- /* mesh power mode flags updated in mesh_nexthop_lookup */ -+- IEEE80211_IFSTA_MESH_CTR_INC(ifmsh, fwded_unicast); -+- } else { -+- /* unable to resolve next hop */ -+- mesh_path_error_tx(sdata, ifmsh->mshcfg.element_ttl, -+- fwd_hdr->addr3, 0, -+- WLAN_REASON_MESH_PATH_NOFORWARD, -+- fwd_hdr->addr2); -+- IEEE80211_IFSTA_MESH_CTR_INC(ifmsh, dropped_frames_no_route); -+- kfree_skb(fwd_skb); -+- return RX_DROP_MONITOR; -+- } -+- -+- IEEE80211_IFSTA_MESH_CTR_INC(ifmsh, fwded_frames); -+- ieee80211_add_pending_skb(local, fwd_skb); -+- out: -+- if (is_multicast_ether_addr(hdr->addr1)) -+- return RX_CONTINUE; -+- return RX_DROP_MONITOR; -+-} -+-#endif -+- -+ static ieee80211_rx_result debug_noinline -+ ieee80211_rx_h_data(struct ieee80211_rx_data *rx) -+ { -+@@ -2991,6 +3028,7 @@ ieee80211_rx_h_data(struct ieee80211_rx_ -+ struct net_device *dev = sdata->dev; -+ struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)rx->skb->data; -+ __le16 fc = hdr->frame_control; -++ static ieee80211_rx_result res; -+ bool port_control; -+ int err; -+ -+@@ -3017,6 +3055,10 @@ ieee80211_rx_h_data(struct ieee80211_rx_ -+ if (unlikely(err)) -+ return RX_DROP_UNUSABLE; -+ -++ res = ieee80211_rx_mesh_data(rx->sdata, rx->sta, rx->skb); -++ if (res != RX_CONTINUE) -++ return res; -++ -+ if (!ieee80211_frame_allowed(rx, fc)) -+ return RX_DROP_MONITOR; -+ -+@@ -3987,10 +4029,6 @@ static void ieee80211_rx_handlers(struct -+ CALL_RXH(ieee80211_rx_h_defragment); -+ CALL_RXH(ieee80211_rx_h_michael_mic_verify); -+ /* must be after MMIC verify so header is counted in MPDU mic */ -+-#ifdef CPTCFG_MAC80211_MESH -+- if (ieee80211_vif_is_mesh(&rx->sdata->vif)) -+- CALL_RXH(ieee80211_rx_h_mesh_fwding); -+-#endif -+ CALL_RXH(ieee80211_rx_h_amsdu); -+ CALL_RXH(ieee80211_rx_h_data); -+ -+--- a/net/wireless/util.c -++++ b/net/wireless/util.c -+@@ -542,7 +542,7 @@ unsigned int ieee80211_get_mesh_hdrlen(s -+ } -+ EXPORT_SYMBOL(ieee80211_get_mesh_hdrlen); -+ -+-static bool ieee80211_get_8023_tunnel_proto(const void *hdr, __be16 *proto) -++bool ieee80211_get_8023_tunnel_proto(const void *hdr, __be16 *proto) -+ { -+ const __be16 *hdr_proto = hdr + ETH_ALEN; -+ -+@@ -556,6 +556,49 @@ static bool ieee80211_get_8023_tunnel_pr -+ -+ return true; -+ } -++EXPORT_SYMBOL(ieee80211_get_8023_tunnel_proto); -++ -++int ieee80211_strip_8023_mesh_hdr(struct sk_buff *skb) -++{ -++ const void *mesh_addr; -++ struct { -++ struct ethhdr eth; -++ u8 flags; -++ } payload; -++ int hdrlen; -++ int ret; -++ -++ ret = skb_copy_bits(skb, 0, &payload, sizeof(payload)); -++ if (ret) -++ return ret; -++ -++ hdrlen = sizeof(payload.eth) + __ieee80211_get_mesh_hdrlen(payload.flags); -++ -++ if (likely(pskb_may_pull(skb, hdrlen + 8) && -++ ieee80211_get_8023_tunnel_proto(skb->data + hdrlen, -++ &payload.eth.h_proto))) -++ hdrlen += ETH_ALEN + 2; -++ else if (!pskb_may_pull(skb, hdrlen)) -++ return -EINVAL; -++ -++ mesh_addr = skb->data + sizeof(payload.eth) + ETH_ALEN; -++ switch (payload.flags & MESH_FLAGS_AE) { -++ case MESH_FLAGS_AE_A4: -++ memcpy(&payload.eth.h_source, mesh_addr, ETH_ALEN); -++ break; -++ case MESH_FLAGS_AE_A5_A6: -++ memcpy(&payload.eth, mesh_addr, 2 * ETH_ALEN); -++ break; -++ default: -++ break; -++ } -++ -++ pskb_pull(skb, hdrlen - sizeof(payload.eth)); -++ memcpy(skb->data, &payload.eth, sizeof(payload.eth)); -++ -++ return 0; -++} -++EXPORT_SYMBOL(ieee80211_strip_8023_mesh_hdr); -+ -+ int ieee80211_data_to_8023_exthdr(struct sk_buff *skb, struct ethhdr *ehdr, -+ const u8 *addr, enum nl80211_iftype iftype, -+@@ -568,7 +611,6 @@ int ieee80211_data_to_8023_exthdr(struct -+ } payload; -+ struct ethhdr tmp; -+ u16 hdrlen; -+- u8 mesh_flags = 0; -+ -+ if (unlikely(!ieee80211_is_data_present(hdr->frame_control))) -+ return -1; -+@@ -589,12 +631,6 @@ int ieee80211_data_to_8023_exthdr(struct -+ memcpy(tmp.h_dest, ieee80211_get_DA(hdr), ETH_ALEN); -+ memcpy(tmp.h_source, ieee80211_get_SA(hdr), ETH_ALEN); -+ -+- if (iftype == NL80211_IFTYPE_MESH_POINT && -+- skb_copy_bits(skb, hdrlen, &mesh_flags, 1) < 0) -+- return -1; -+- -+- mesh_flags &= MESH_FLAGS_AE; -+- -+ switch (hdr->frame_control & -+ cpu_to_le16(IEEE80211_FCTL_TODS | IEEE80211_FCTL_FROMDS)) { -+ case cpu_to_le16(IEEE80211_FCTL_TODS): -+@@ -608,17 +644,6 @@ int ieee80211_data_to_8023_exthdr(struct -+ iftype != NL80211_IFTYPE_AP_VLAN && -+ iftype != NL80211_IFTYPE_STATION)) -+ return -1; -+- if (iftype == NL80211_IFTYPE_MESH_POINT) { -+- if (mesh_flags == MESH_FLAGS_AE_A4) -+- return -1; -+- if (mesh_flags == MESH_FLAGS_AE_A5_A6 && -+- skb_copy_bits(skb, hdrlen + -+- offsetof(struct ieee80211s_hdr, eaddr1), -+- tmp.h_dest, 2 * ETH_ALEN) < 0) -+- return -1; -+- -+- hdrlen += __ieee80211_get_mesh_hdrlen(mesh_flags); -+- } -+ break; -+ case cpu_to_le16(IEEE80211_FCTL_FROMDS): -+ if ((iftype != NL80211_IFTYPE_STATION && -+@@ -627,16 +652,6 @@ int ieee80211_data_to_8023_exthdr(struct -+ (is_multicast_ether_addr(tmp.h_dest) && -+ ether_addr_equal(tmp.h_source, addr))) -+ return -1; -+- if (iftype == NL80211_IFTYPE_MESH_POINT) { -+- if (mesh_flags == MESH_FLAGS_AE_A5_A6) -+- return -1; -+- if (mesh_flags == MESH_FLAGS_AE_A4 && -+- skb_copy_bits(skb, hdrlen + -+- offsetof(struct ieee80211s_hdr, eaddr1), -+- tmp.h_source, ETH_ALEN) < 0) -+- return -1; -+- hdrlen += __ieee80211_get_mesh_hdrlen(mesh_flags); -+- } -+ break; -+ case cpu_to_le16(0): -+ if (iftype != NL80211_IFTYPE_ADHOC && -+@@ -646,7 +661,7 @@ int ieee80211_data_to_8023_exthdr(struct -+ break; -+ } -+ -+- if (likely(!is_amsdu && -++ if (likely(!is_amsdu && iftype != NL80211_IFTYPE_MESH_POINT && -+ skb_copy_bits(skb, hdrlen, &payload, sizeof(payload)) == 0 && -+ ieee80211_get_8023_tunnel_proto(&payload, &tmp.h_proto))) { -+ /* remove RFC1042 or Bridge-Tunnel encapsulation */ -+@@ -722,7 +737,8 @@ __ieee80211_amsdu_copy_frag(struct sk_bu -+ -+ static struct sk_buff * -+ __ieee80211_amsdu_copy(struct sk_buff *skb, unsigned int hlen, -+- int offset, int len, bool reuse_frag) -++ int offset, int len, bool reuse_frag, -++ int min_len) -+ { -+ struct sk_buff *frame; -+ int cur_len = len; -+@@ -736,7 +752,7 @@ __ieee80211_amsdu_copy(struct sk_buff *s -+ * in the stack later. -+ */ -+ if (reuse_frag) -+- cur_len = min_t(int, len, 32); -++ cur_len = min_t(int, len, min_len); -+ -+ /* -+ * Allocate and reserve two bytes more for payload -+@@ -746,6 +762,7 @@ __ieee80211_amsdu_copy(struct sk_buff *s -+ if (!frame) -+ return NULL; -+ -++ frame->priority = skb->priority; -+ skb_reserve(frame, hlen + sizeof(struct ethhdr) + 2); -+ skb_copy_bits(skb, offset, skb_put(frame, cur_len), cur_len); -+ -+@@ -762,23 +779,37 @@ __ieee80211_amsdu_copy(struct sk_buff *s -+ void ieee80211_amsdu_to_8023s(struct sk_buff *skb, struct sk_buff_head *list, -+ const u8 *addr, enum nl80211_iftype iftype, -+ const unsigned int extra_headroom, -+- const u8 *check_da, const u8 *check_sa) -++ const u8 *check_da, const u8 *check_sa, -++ bool mesh_control) -+ { -+ unsigned int hlen = ALIGN(extra_headroom, 4); -+ struct sk_buff *frame = NULL; -+ int offset = 0, remaining; -+- struct ethhdr eth; -++ struct { -++ struct ethhdr eth; -++ uint8_t flags; -++ } hdr; -+ bool reuse_frag = skb->head_frag && !skb_has_frag_list(skb); -+ bool reuse_skb = false; -+ bool last = false; -++ int copy_len = sizeof(hdr.eth); -++ -++ if (iftype == NL80211_IFTYPE_MESH_POINT) -++ copy_len = sizeof(hdr); -+ -+ while (!last) { -+ unsigned int subframe_len; -+- int len; -++ int len, mesh_len = 0; -+ u8 padding; -+ -+- skb_copy_bits(skb, offset, ð, sizeof(eth)); -+- len = ntohs(eth.h_proto); -++ skb_copy_bits(skb, offset, &hdr, copy_len); -++ if (iftype == NL80211_IFTYPE_MESH_POINT) -++ mesh_len = __ieee80211_get_mesh_hdrlen(hdr.flags); -++ if (mesh_control) -++ len = le16_to_cpu(*(__le16 *)&hdr.eth.h_proto) + mesh_len; -++ else -++ len = ntohs(hdr.eth.h_proto); -++ -+ subframe_len = sizeof(struct ethhdr) + len; -+ padding = (4 - subframe_len) & 0x3; -+ -+@@ -787,16 +818,16 @@ void ieee80211_amsdu_to_8023s(struct sk_ -+ if (subframe_len > remaining) -+ goto purge; -+ /* mitigate A-MSDU aggregation injection attacks */ -+- if (ether_addr_equal(eth.h_dest, rfc1042_header)) -++ if (ether_addr_equal(hdr.eth.h_dest, rfc1042_header)) -+ goto purge; -+ -+ offset += sizeof(struct ethhdr); -+ last = remaining <= subframe_len + padding; -+ -+ /* FIXME: should we really accept multicast DA? */ -+- if ((check_da && !is_multicast_ether_addr(eth.h_dest) && -+- !ether_addr_equal(check_da, eth.h_dest)) || -+- (check_sa && !ether_addr_equal(check_sa, eth.h_source))) { -++ if ((check_da && !is_multicast_ether_addr(hdr.eth.h_dest) && -++ !ether_addr_equal(check_da, hdr.eth.h_dest)) || -++ (check_sa && !ether_addr_equal(check_sa, hdr.eth.h_source))) { -+ offset += len + padding; -+ continue; -+ } -+@@ -808,7 +839,7 @@ void ieee80211_amsdu_to_8023s(struct sk_ -+ reuse_skb = true; -+ } else { -+ frame = __ieee80211_amsdu_copy(skb, hlen, offset, len, -+- reuse_frag); -++ reuse_frag, 32 + mesh_len); -+ if (!frame) -+ goto purge; -+ -+@@ -819,10 +850,11 @@ void ieee80211_amsdu_to_8023s(struct sk_ -+ frame->dev = skb->dev; -+ frame->priority = skb->priority; -+ -+- if (likely(ieee80211_get_8023_tunnel_proto(frame->data, ð.h_proto))) -++ if (likely(iftype != NL80211_IFTYPE_MESH_POINT && -++ ieee80211_get_8023_tunnel_proto(frame->data, &hdr.eth.h_proto))) -+ skb_pull(frame, ETH_ALEN + 2); -+ -+- memcpy(skb_push(frame, sizeof(eth)), ð, sizeof(eth)); -++ memcpy(skb_push(frame, sizeof(hdr.eth)), &hdr.eth, sizeof(hdr.eth)); -+ __skb_queue_tail(list, frame); -+ } -+ -diff --git a/package/kernel/mac80211/patches/subsys/316-v6.3-wifi-mac80211-add-a-workaround-for-receiving-non-sta.patch b/package/kernel/mac80211/patches/subsys/316-v6.3-wifi-mac80211-add-a-workaround-for-receiving-non-sta.patch -new file mode 100644 -index 0000000000..6dc98ae16a ---- /dev/null -+++ b/package/kernel/mac80211/patches/subsys/316-v6.3-wifi-mac80211-add-a-workaround-for-receiving-non-sta.patch -@@ -0,0 +1,145 @@ -+From: Felix Fietkau -+Date: Fri, 9 Dec 2022 21:15:04 +0100 -+Subject: [PATCH] wifi: mac80211: add a workaround for receiving -+ non-standard mesh A-MSDU -+ -+At least ath10k and ath11k supported hardware (maybe more) does not implement -+mesh A-MSDU aggregation in a standard compliant way. -+802.11-2020 9.3.2.2.2 declares that the Mesh Control field is part of the -+A-MSDU header. As such, its length must not be included in the subframe -+length field. -+Hardware affected by this bug treats the mesh control field as part of the -+MSDU data and sets the length accordingly. -+In order to avoid packet loss, keep track of which stations are affected -+by this and take it into account when converting A-MSDU to 802.3 + mesh control -+packets. -+ -+Signed-off-by: Felix Fietkau -+--- -+ -+--- a/include/net/cfg80211.h -++++ b/include/net/cfg80211.h -+@@ -6194,6 +6194,19 @@ static inline int ieee80211_data_to_8023 -+ } -+ -+ /** -++ * ieee80211_is_valid_amsdu - check if subframe lengths of an A-MSDU are valid -++ * -++ * This is used to detect non-standard A-MSDU frames, e.g. the ones generated -++ * by ath10k and ath11k, where the subframe length includes the length of the -++ * mesh control field. -++ * -++ * @skb: The input A-MSDU frame without any headers. -++ * @mesh_hdr: use standard compliant mesh A-MSDU subframe header -++ * Returns: true if subframe header lengths are valid for the @mesh_hdr mode -++ */ -++bool ieee80211_is_valid_amsdu(struct sk_buff *skb, bool mesh_hdr); -++ -++/** -+ * ieee80211_amsdu_to_8023s - decode an IEEE 802.11n A-MSDU frame -+ * -+ * Decode an IEEE 802.11 A-MSDU and convert it to a list of 802.3 frames. -+--- a/net/mac80211/rx.c -++++ b/net/mac80211/rx.c -+@@ -2899,7 +2899,6 @@ __ieee80211_rx_h_amsdu(struct ieee80211_ -+ static ieee80211_rx_result res; -+ struct ethhdr ethhdr; -+ const u8 *check_da = ethhdr.h_dest, *check_sa = ethhdr.h_source; -+- bool mesh = false; -+ -+ if (unlikely(ieee80211_has_a4(hdr->frame_control))) { -+ check_da = NULL; -+@@ -2917,7 +2916,6 @@ __ieee80211_rx_h_amsdu(struct ieee80211_ -+ case NL80211_IFTYPE_MESH_POINT: -+ check_sa = NULL; -+ check_da = NULL; -+- mesh = true; -+ break; -+ default: -+ break; -+@@ -2932,10 +2930,21 @@ __ieee80211_rx_h_amsdu(struct ieee80211_ -+ data_offset, true)) -+ return RX_DROP_UNUSABLE; -+ -++ if (rx->sta && rx->sta->amsdu_mesh_control < 0) { -++ bool valid_std = ieee80211_is_valid_amsdu(skb, true); -++ bool valid_nonstd = ieee80211_is_valid_amsdu(skb, false); -++ -++ if (valid_std && !valid_nonstd) -++ rx->sta->amsdu_mesh_control = 1; -++ else if (valid_nonstd && !valid_std) -++ rx->sta->amsdu_mesh_control = 0; -++ } -++ -+ ieee80211_amsdu_to_8023s(skb, &frame_list, dev->dev_addr, -+ rx->sdata->vif.type, -+ rx->local->hw.extra_tx_headroom, -+- check_da, check_sa, mesh); -++ check_da, check_sa, -++ rx->sta->amsdu_mesh_control); -+ -+ while (!skb_queue_empty(&frame_list)) { -+ rx->skb = __skb_dequeue(&frame_list); -+--- a/net/mac80211/sta_info.c -++++ b/net/mac80211/sta_info.c -+@@ -591,6 +591,9 @@ __sta_info_alloc(struct ieee80211_sub_if -+ -+ sta->sta_state = IEEE80211_STA_NONE; -+ -++ if (sdata->vif.type == NL80211_IFTYPE_MESH_POINT) -++ sta->amsdu_mesh_control = -1; -++ -+ /* Mark TID as unreserved */ -+ sta->reserved_tid = IEEE80211_TID_UNRESERVED; -+ -+--- a/net/mac80211/sta_info.h -++++ b/net/mac80211/sta_info.h -+@@ -702,6 +702,7 @@ struct sta_info { -+ struct codel_params cparams; -+ -+ u8 reserved_tid; -++ s8 amsdu_mesh_control; -+ -+ struct cfg80211_chan_def tdls_chandef; -+ -+--- a/net/wireless/util.c -++++ b/net/wireless/util.c -+@@ -776,6 +776,38 @@ __ieee80211_amsdu_copy(struct sk_buff *s -+ return frame; -+ } -+ -++bool ieee80211_is_valid_amsdu(struct sk_buff *skb, bool mesh_hdr) -++{ -++ int offset = 0, remaining, subframe_len, padding; -++ -++ for (offset = 0; offset < skb->len; offset += subframe_len + padding) { -++ struct { -++ __be16 len; -++ u8 mesh_flags; -++ } hdr; -++ u16 len; -++ -++ if (skb_copy_bits(skb, offset + 2 * ETH_ALEN, &hdr, sizeof(hdr)) < 0) -++ return false; -++ -++ if (mesh_hdr) -++ len = le16_to_cpu(*(__le16 *)&hdr.len) + -++ __ieee80211_get_mesh_hdrlen(hdr.mesh_flags); -++ else -++ len = ntohs(hdr.len); -++ -++ subframe_len = sizeof(struct ethhdr) + len; -++ padding = (4 - subframe_len) & 0x3; -++ remaining = skb->len - offset; -++ -++ if (subframe_len > remaining) -++ return false; -++ } -++ -++ return true; -++} -++EXPORT_SYMBOL(ieee80211_is_valid_amsdu); -++ -+ void ieee80211_amsdu_to_8023s(struct sk_buff *skb, struct sk_buff_head *list, -+ const u8 *addr, enum nl80211_iftype iftype, -+ const unsigned int extra_headroom, -diff --git a/package/kernel/mac80211/patches/subsys/318-wifi-mac80211-fix-race-in-mesh-sequence-number-assig.patch b/package/kernel/mac80211/patches/subsys/318-wifi-mac80211-fix-race-in-mesh-sequence-number-assig.patch -new file mode 100644 -index 0000000000..7d01ffdfff ---- /dev/null -+++ b/package/kernel/mac80211/patches/subsys/318-wifi-mac80211-fix-race-in-mesh-sequence-number-assig.patch -@@ -0,0 +1,37 @@ -+From: Felix Fietkau -+Date: Wed, 15 Feb 2023 15:21:37 +0100 -+Subject: [PATCH] wifi: mac80211: fix race in mesh sequence number -+ assignment -+ -+Since the sequence number is shared across different tx queues, it needs -+to be atomic in order to avoid accidental duplicate assignment -+ -+Signed-off-by: Felix Fietkau -+--- -+ -+--- a/net/mac80211/ieee80211_i.h -++++ b/net/mac80211/ieee80211_i.h -+@@ -696,7 +696,7 @@ struct ieee80211_if_mesh { -+ struct mesh_stats mshstats; -+ struct mesh_config mshcfg; -+ atomic_t estab_plinks; -+- u32 mesh_seqnum; -++ atomic_t mesh_seqnum; -+ bool accepting_plinks; -+ int num_gates; -+ struct beacon_data __rcu *beacon; -+--- a/net/mac80211/mesh.c -++++ b/net/mac80211/mesh.c -+@@ -752,10 +752,8 @@ unsigned int ieee80211_new_mesh_header(s -+ -+ meshhdr->ttl = sdata->u.mesh.mshcfg.dot11MeshTTL; -+ -+- /* FIXME: racy -- TX on multiple queues can be concurrent */ -+- put_unaligned(cpu_to_le32(sdata->u.mesh.mesh_seqnum), &meshhdr->seqnum); -+- sdata->u.mesh.mesh_seqnum++; -+- -++ put_unaligned_le32(atomic_inc_return(&sdata->u.mesh.mesh_seqnum), -++ &meshhdr->seqnum); -+ if (addr4or5 && !addr6) { -+ meshhdr->flags |= MESH_FLAGS_AE_A4; -+ memcpy(meshhdr->eaddr1, addr4or5, ETH_ALEN); -diff --git a/package/kernel/mac80211/patches/subsys/319-wifi-mac80211-mesh-fast-xmit-support.patch b/package/kernel/mac80211/patches/subsys/319-wifi-mac80211-mesh-fast-xmit-support.patch -new file mode 100644 -index 0000000000..968d2885f2 ---- /dev/null -+++ b/package/kernel/mac80211/patches/subsys/319-wifi-mac80211-mesh-fast-xmit-support.patch -@@ -0,0 +1,850 @@ -+From: Felix Fietkau -+Date: Sun, 26 Feb 2023 13:53:08 +0100 -+Subject: [PATCH] wifi: mac80211: mesh fast xmit support -+ -+Previously, fast xmit only worked on interface types where initially a -+sta lookup is performed, and a cached header can be attached to the sta, -+requiring only some fields to be updated at runtime. -+ -+This technique is not directly applicable for a mesh device type due -+to the dynamic nature of the topology and protocol. There are more -+addresses that need to be filled, and there is an extra header with a -+dynamic length based on the addressing mode. -+ -+Change the code to cache entries contain a copy of the mesh subframe header + -+bridge tunnel header, as well as an embedded struct ieee80211_fast_tx, which -+contains the information for building the 802.11 header. -+ -+Add a mesh specific early fast xmit call, which looks up a cached entry and -+adds only the mesh subframe header, before passing it over to the generic -+fast xmit code. -+ -+To ensure the changes in network are reflected in these cached headers, -+flush affected cached entries on path changes, as well as other conditions -+that currently trigger a fast xmit check in other modes (key changes etc.) -+ -+This code is loosely based on a previous implementation by: -+Sriram R -+ -+Signed-off-by: Ryder Lee -+Signed-off-by: Felix Fietkau -+--- -+ -+--- a/net/mac80211/ieee80211_i.h -++++ b/net/mac80211/ieee80211_i.h -+@@ -37,6 +37,7 @@ -+ extern const struct cfg80211_ops mac80211_config_ops; -+ -+ struct ieee80211_local; -++struct ieee80211_mesh_fast_tx; -+ -+ /* Maximum number of broadcast/multicast frames to buffer when some of the -+ * associated stations are using power saving. */ -+@@ -656,6 +657,19 @@ struct mesh_table { -+ atomic_t entries; /* Up to MAX_MESH_NEIGHBOURS */ -+ }; -+ -++/** -++ * struct mesh_tx_cache - mesh fast xmit header cache -++ * -++ * @rht: hash table containing struct ieee80211_mesh_fast_tx, using skb DA as key -++ * @walk_head: linked list containing all ieee80211_mesh_fast_tx objects -++ * @walk_lock: lock protecting walk_head and rht -++ */ -++struct mesh_tx_cache { -++ struct rhashtable rht; -++ struct hlist_head walk_head; -++ spinlock_t walk_lock; -++}; -++ -+ struct ieee80211_if_mesh { -+ struct timer_list housekeeping_timer; -+ struct timer_list mesh_path_timer; -+@@ -734,6 +748,7 @@ struct ieee80211_if_mesh { -+ struct mesh_table mpp_paths; /* Store paths for MPP&MAP */ -+ int mesh_paths_generation; -+ int mpp_paths_generation; -++ struct mesh_tx_cache tx_cache; -+ }; -+ -+ #ifdef CPTCFG_MAC80211_MESH -+@@ -2002,6 +2017,11 @@ int ieee80211_tx_control_port(struct wip -+ int link_id, u64 *cookie); -+ int ieee80211_probe_mesh_link(struct wiphy *wiphy, struct net_device *dev, -+ const u8 *buf, size_t len); -++void __ieee80211_xmit_fast(struct ieee80211_sub_if_data *sdata, -++ struct sta_info *sta, -++ struct ieee80211_fast_tx *fast_tx, -++ struct sk_buff *skb, bool ampdu, -++ const u8 *da, const u8 *sa); -+ -+ /* HT */ -+ void ieee80211_apply_htcap_overrides(struct ieee80211_sub_if_data *sdata, -+--- a/net/mac80211/mesh.c -++++ b/net/mac80211/mesh.c -+@@ -10,6 +10,7 @@ -+ #include -+ #include "ieee80211_i.h" -+ #include "mesh.h" -++#include "wme.h" -+ #include "driver-ops.h" -+ -+ static int mesh_allocated; -+@@ -698,6 +699,95 @@ ieee80211_mesh_update_bss_params(struct -+ __le32_to_cpu(he_oper->he_oper_params); -+ } -+ -++bool ieee80211_mesh_xmit_fast(struct ieee80211_sub_if_data *sdata, -++ struct sk_buff *skb, u32 ctrl_flags) -++{ -++ struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh; -++ struct ieee80211_mesh_fast_tx *entry; -++ struct ieee80211s_hdr *meshhdr; -++ u8 sa[ETH_ALEN] __aligned(2); -++ struct tid_ampdu_tx *tid_tx; -++ struct sta_info *sta; -++ bool copy_sa = false; -++ u16 ethertype; -++ u8 tid; -++ -++ if (ctrl_flags & IEEE80211_TX_CTRL_SKIP_MPATH_LOOKUP) -++ return false; -++ -++ if (ifmsh->mshcfg.dot11MeshNolearn) -++ return false; -++ -++ /* Add support for these cases later */ -++ if (ifmsh->ps_peers_light_sleep || ifmsh->ps_peers_deep_sleep) -++ return false; -++ -++ if (is_multicast_ether_addr(skb->data)) -++ return false; -++ -++ ethertype = (skb->data[12] << 8) | skb->data[13]; -++ if (ethertype < ETH_P_802_3_MIN) -++ return false; -++ -++ if (skb->sk && skb_shinfo(skb)->tx_flags & SKBTX_WIFI_STATUS) -++ return false; -++ -++ if (skb->ip_summed == CHECKSUM_PARTIAL) { -++ skb_set_transport_header(skb, skb_checksum_start_offset(skb)); -++ if (skb_checksum_help(skb)) -++ return false; -++ } -++ -++ entry = mesh_fast_tx_get(sdata, skb->data); -++ if (!entry) -++ return false; -++ -++ if (skb_headroom(skb) < entry->hdrlen + entry->fast_tx.hdr_len) -++ return false; -++ -++ sta = rcu_dereference(entry->mpath->next_hop); -++ if (!sta) -++ return false; -++ -++ 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)) -++ return false; -++ if (tid_tx->timeout) -++ tid_tx->last_tx = jiffies; -++ } -++ -++ skb = skb_share_check(skb, GFP_ATOMIC); -++ if (!skb) -++ return true; -++ -++ 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) { -++ /* preserve SA from eth header for 6-addr frames */ -++ ether_addr_copy(sa, skb->data + ETH_ALEN); -++ copy_sa = true; -++ } -++ -++ memcpy(skb_push(skb, entry->hdrlen - 2 * ETH_ALEN), entry->hdr, -++ entry->hdrlen); -++ -++ meshhdr = (struct ieee80211s_hdr *)skb->data; -++ put_unaligned_le32(atomic_inc_return(&sdata->u.mesh.mesh_seqnum), -++ &meshhdr->seqnum); -++ meshhdr->ttl = sdata->u.mesh.mshcfg.dot11MeshTTL; -++ if (copy_sa) -++ ether_addr_copy(meshhdr->eaddr2, sa); -++ -++ skb_push(skb, 2 * ETH_ALEN); -++ __ieee80211_xmit_fast(sdata, sta, &entry->fast_tx, skb, tid_tx, -++ entry->mpath->dst, sdata->vif.addr); -++ -++ return true; -++} -++ -+ /** -+ * ieee80211_fill_mesh_addresses - fill addresses of a locally originated mesh frame -+ * @hdr: 802.11 frame header -+@@ -780,6 +870,8 @@ static void ieee80211_mesh_housekeeping( -+ changed = mesh_accept_plinks_update(sdata); -+ ieee80211_mbss_info_change_notify(sdata, changed); -+ -++ mesh_fast_tx_gc(sdata); -++ -+ mod_timer(&ifmsh->housekeeping_timer, -+ round_jiffies(jiffies + -+ IEEE80211_MESH_HOUSEKEEPING_INTERVAL)); -+--- a/net/mac80211/mesh.h -++++ b/net/mac80211/mesh.h -+@@ -122,11 +122,41 @@ struct mesh_path { -+ u8 rann_snd_addr[ETH_ALEN]; -+ u32 rann_metric; -+ unsigned long last_preq_to_root; -++ unsigned long fast_tx_check; -+ bool is_root; -+ bool is_gate; -+ u32 path_change_count; -+ }; -+ -++#define MESH_FAST_TX_CACHE_MAX_SIZE 512 -++#define MESH_FAST_TX_CACHE_THRESHOLD_SIZE 384 -++#define MESH_FAST_TX_CACHE_TIMEOUT 8000 /* msecs */ -++ -++/** -++ * struct ieee80211_mesh_fast_tx - cached mesh fast tx entry -++ * @rhash: rhashtable pointer -++ * @addr_key: The Ethernet DA which is the key for this entry -++ * @fast_tx: base fast_tx data -++ * @hdr: cached mesh and rfc1042 headers -++ * @hdrlen: length of mesh + rfc1042 -++ * @walk_list: list containing all the fast tx entries -++ * @mpath: mesh path corresponding to the Mesh DA -++ * @mppath: MPP entry corresponding to this DA -++ * @timestamp: Last used time of this entry -++ */ -++struct ieee80211_mesh_fast_tx { -++ struct rhash_head rhash; -++ u8 addr_key[ETH_ALEN] __aligned(2); -++ -++ struct ieee80211_fast_tx fast_tx; -++ u8 hdr[sizeof(struct ieee80211s_hdr) + sizeof(rfc1042_header)]; -++ u16 hdrlen; -++ -++ struct mesh_path *mpath, *mppath; -++ struct hlist_node walk_list; -++ unsigned long timestamp; -++}; -++ -+ /* Recent multicast cache */ -+ /* RMC_BUCKETS must be a power of 2, maximum 256 */ -+ #define RMC_BUCKETS 256 -+@@ -298,6 +328,20 @@ 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); -++struct ieee80211_mesh_fast_tx * -++mesh_fast_tx_get(struct ieee80211_sub_if_data *sdata, const u8 *addr); -++bool ieee80211_mesh_xmit_fast(struct ieee80211_sub_if_data *sdata, -++ struct sk_buff *skb, u32 ctrl_flags); -++void mesh_fast_tx_cache(struct ieee80211_sub_if_data *sdata, -++ struct sk_buff *skb, struct mesh_path *mpath); -++void mesh_fast_tx_gc(struct ieee80211_sub_if_data *sdata); -++void mesh_fast_tx_flush_addr(struct ieee80211_sub_if_data *sdata, -++ const u8 *addr); -++void mesh_fast_tx_flush_mpath(struct mesh_path *mpath); -++void mesh_fast_tx_flush_sta(struct ieee80211_sub_if_data *sdata, -++ struct sta_info *sta); -++void mesh_path_refresh(struct ieee80211_sub_if_data *sdata, -++ struct mesh_path *mpath, const u8 *addr); -+ -+ #ifdef CPTCFG_MAC80211_MESH -+ static inline -+--- a/net/mac80211/mesh_hwmp.c -++++ b/net/mac80211/mesh_hwmp.c -+@@ -394,6 +394,7 @@ static u32 hwmp_route_info_get(struct ie -+ u32 orig_sn, orig_metric; -+ unsigned long orig_lifetime, exp_time; -+ u32 last_hop_metric, new_metric; -++ bool flush_mpath = false; -+ bool process = true; -+ u8 hopcount; -+ -+@@ -491,8 +492,10 @@ static u32 hwmp_route_info_get(struct ie -+ } -+ -+ if (fresh_info) { -+- if (rcu_access_pointer(mpath->next_hop) != sta) -++ if (rcu_access_pointer(mpath->next_hop) != sta) { -+ mpath->path_change_count++; -++ flush_mpath = true; -++ } -+ mesh_path_assign_nexthop(mpath, sta); -+ mpath->flags |= MESH_PATH_SN_VALID; -+ mpath->metric = new_metric; -+@@ -502,6 +505,8 @@ static u32 hwmp_route_info_get(struct ie -+ mpath->hop_count = hopcount; -+ mesh_path_activate(mpath); -+ spin_unlock_bh(&mpath->state_lock); -++ if (flush_mpath) -++ mesh_fast_tx_flush_mpath(mpath); -+ ewma_mesh_fail_avg_init(&sta->mesh->fail_avg); -+ /* init it at a low value - 0 start is tricky */ -+ ewma_mesh_fail_avg_add(&sta->mesh->fail_avg, 1); -+@@ -539,8 +544,10 @@ static u32 hwmp_route_info_get(struct ie -+ } -+ -+ if (fresh_info) { -+- if (rcu_access_pointer(mpath->next_hop) != sta) -++ if (rcu_access_pointer(mpath->next_hop) != sta) { -+ mpath->path_change_count++; -++ flush_mpath = true; -++ } -+ mesh_path_assign_nexthop(mpath, sta); -+ mpath->metric = last_hop_metric; -+ mpath->exp_time = time_after(mpath->exp_time, exp_time) -+@@ -548,6 +555,8 @@ static u32 hwmp_route_info_get(struct ie -+ mpath->hop_count = 1; -+ mesh_path_activate(mpath); -+ spin_unlock_bh(&mpath->state_lock); -++ if (flush_mpath) -++ mesh_fast_tx_flush_mpath(mpath); -+ ewma_mesh_fail_avg_init(&sta->mesh->fail_avg); -+ /* init it at a low value - 0 start is tricky */ -+ ewma_mesh_fail_avg_add(&sta->mesh->fail_avg, 1); -+@@ -1215,6 +1224,20 @@ static int mesh_nexthop_lookup_nolearn(s -+ return 0; -+ } -+ -++void mesh_path_refresh(struct ieee80211_sub_if_data *sdata, -++ struct mesh_path *mpath, const u8 *addr) -++{ -++ if (mpath->flags & (MESH_PATH_REQ_QUEUED | MESH_PATH_FIXED | -++ MESH_PATH_RESOLVING)) -++ return; -++ -++ if (time_after(jiffies, -++ mpath->exp_time - -++ msecs_to_jiffies(sdata->u.mesh.mshcfg.path_refresh_time)) && -++ (!addr || ether_addr_equal(sdata->vif.addr, addr))) -++ mesh_queue_preq(mpath, PREQ_Q_F_START | PREQ_Q_F_REFRESH); -++} -++ -+ /** -+ * mesh_nexthop_lookup - put the appropriate next hop on a mesh frame. Calling -+ * this function is considered "using" the associated mpath, so preempt a path -+@@ -1242,19 +1265,15 @@ int mesh_nexthop_lookup(struct ieee80211 -+ if (!mpath || !(mpath->flags & MESH_PATH_ACTIVE)) -+ return -ENOENT; -+ -+- if (time_after(jiffies, -+- mpath->exp_time - -+- msecs_to_jiffies(sdata->u.mesh.mshcfg.path_refresh_time)) && -+- ether_addr_equal(sdata->vif.addr, hdr->addr4) && -+- !(mpath->flags & MESH_PATH_RESOLVING) && -+- !(mpath->flags & MESH_PATH_FIXED)) -+- mesh_queue_preq(mpath, PREQ_Q_F_START | PREQ_Q_F_REFRESH); -++ mesh_path_refresh(sdata, mpath, hdr->addr4); -+ -+ next_hop = rcu_dereference(mpath->next_hop); -+ if (next_hop) { -+ memcpy(hdr->addr1, next_hop->sta.addr, ETH_ALEN); -+ memcpy(hdr->addr2, sdata->vif.addr, ETH_ALEN); -+ ieee80211_mps_set_frame_flags(sdata, next_hop, hdr); -++ if (ieee80211_hw_check(&sdata->local->hw, SUPPORT_FAST_XMIT)) -++ mesh_fast_tx_cache(sdata, skb, mpath); -+ return 0; -+ } -+ -+--- a/net/mac80211/mesh_pathtbl.c -++++ b/net/mac80211/mesh_pathtbl.c -+@@ -14,6 +14,7 @@ -+ #include "wme.h" -+ #include "ieee80211_i.h" -+ #include "mesh.h" -++#include -+ -+ static void mesh_path_free_rcu(struct mesh_table *tbl, struct mesh_path *mpath); -+ -+@@ -32,6 +33,41 @@ static const struct rhashtable_params me -+ .hashfn = mesh_table_hash, -+ }; -+ -++static const struct rhashtable_params fast_tx_rht_params = { -++ .nelem_hint = 10, -++ .automatic_shrinking = true, -++ .key_len = ETH_ALEN, -++ .key_offset = offsetof(struct ieee80211_mesh_fast_tx, addr_key), -++ .head_offset = offsetof(struct ieee80211_mesh_fast_tx, rhash), -++ .hashfn = mesh_table_hash, -++}; -++ -++static void __mesh_fast_tx_entry_free(void *ptr, void *tblptr) -++{ -++ struct ieee80211_mesh_fast_tx *entry = ptr; -++ -++ kfree_rcu(entry, fast_tx.rcu_head); -++} -++ -++static void mesh_fast_tx_deinit(struct ieee80211_sub_if_data *sdata) -++{ -++ struct mesh_tx_cache *cache; -++ -++ cache = &sdata->u.mesh.tx_cache; -++ rhashtable_free_and_destroy(&cache->rht, -++ __mesh_fast_tx_entry_free, NULL); -++} -++ -++static void mesh_fast_tx_init(struct ieee80211_sub_if_data *sdata) -++{ -++ struct mesh_tx_cache *cache; -++ -++ cache = &sdata->u.mesh.tx_cache; -++ rhashtable_init(&cache->rht, &fast_tx_rht_params); -++ INIT_HLIST_HEAD(&cache->walk_head); -++ spin_lock_init(&cache->walk_lock); -++} -++ -+ static inline bool mpath_expired(struct mesh_path *mpath) -+ { -+ return (mpath->flags & MESH_PATH_ACTIVE) && -+@@ -381,6 +417,243 @@ struct mesh_path *mesh_path_new(struct i -+ return new_mpath; -+ } -+ -++static void mesh_fast_tx_entry_free(struct mesh_tx_cache *cache, -++ struct ieee80211_mesh_fast_tx *entry) -++{ -++ hlist_del_rcu(&entry->walk_list); -++ rhashtable_remove_fast(&cache->rht, &entry->rhash, fast_tx_rht_params); -++ kfree_rcu(entry, fast_tx.rcu_head); -++} -++ -++struct ieee80211_mesh_fast_tx * -++mesh_fast_tx_get(struct ieee80211_sub_if_data *sdata, const u8 *addr) -++{ -++ struct ieee80211_mesh_fast_tx *entry; -++ struct mesh_tx_cache *cache; -++ -++ cache = &sdata->u.mesh.tx_cache; -++ entry = rhashtable_lookup(&cache->rht, addr, fast_tx_rht_params); -++ if (!entry) -++ return NULL; -++ -++ if (!(entry->mpath->flags & MESH_PATH_ACTIVE) || -++ mpath_expired(entry->mpath)) { -++ spin_lock_bh(&cache->walk_lock); -++ entry = rhashtable_lookup(&cache->rht, addr, fast_tx_rht_params); -++ if (entry) -++ mesh_fast_tx_entry_free(cache, entry); -++ spin_unlock_bh(&cache->walk_lock); -++ return NULL; -++ } -++ -++ mesh_path_refresh(sdata, entry->mpath, NULL); -++ if (entry->mppath) -++ entry->mppath->exp_time = jiffies; -++ entry->timestamp = jiffies; -++ -++ return entry; -++} -++ -++void mesh_fast_tx_cache(struct ieee80211_sub_if_data *sdata, -++ struct sk_buff *skb, struct mesh_path *mpath) -++{ -++ struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; -++ struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); -++ struct ieee80211_mesh_fast_tx *entry, *prev; -++ struct ieee80211_mesh_fast_tx build = {}; -++ struct ieee80211s_hdr *meshhdr; -++ struct mesh_tx_cache *cache; -++ struct ieee80211_key *key; -++ struct mesh_path *mppath; -++ struct sta_info *sta; -++ u8 *qc; -++ -++ if (sdata->noack_map || -++ !ieee80211_is_data_qos(hdr->frame_control)) -++ return; -++ -++ build.fast_tx.hdr_len = ieee80211_hdrlen(hdr->frame_control); -++ meshhdr = (struct ieee80211s_hdr *)(skb->data + build.fast_tx.hdr_len); -++ build.hdrlen = ieee80211_get_mesh_hdrlen(meshhdr); -++ -++ cache = &sdata->u.mesh.tx_cache; -++ if (atomic_read(&cache->rht.nelems) >= MESH_FAST_TX_CACHE_MAX_SIZE) -++ return; -++ -++ sta = rcu_dereference(mpath->next_hop); -++ if (!sta) -++ return; -++ -++ if ((meshhdr->flags & MESH_FLAGS_AE) == MESH_FLAGS_AE_A5_A6) { -++ /* This is required to keep the mppath alive */ -++ mppath = mpp_path_lookup(sdata, meshhdr->eaddr1); -++ if (!mppath) -++ return; -++ build.mppath = mppath; -++ } else if (ieee80211_has_a4(hdr->frame_control)) { -++ mppath = mpath; -++ } else { -++ return; -++ } -++ -++ /* rate limit, in case fast xmit can't be enabled */ -++ if (mppath->fast_tx_check == jiffies) -++ return; -++ -++ mppath->fast_tx_check = jiffies; -++ -++ /* -++ * Same use of the sta lock as in ieee80211_check_fast_xmit, in order -++ * to protect against concurrent sta key updates. -++ */ -++ spin_lock_bh(&sta->lock); -++ key = rcu_access_pointer(sta->ptk[sta->ptk_idx]); -++ if (!key) -++ key = rcu_access_pointer(sdata->default_unicast_key); -++ build.fast_tx.key = key; -++ -++ if (key) { -++ bool gen_iv, iv_spc; -++ -++ gen_iv = key->conf.flags & IEEE80211_KEY_FLAG_GENERATE_IV; -++ iv_spc = key->conf.flags & IEEE80211_KEY_FLAG_PUT_IV_SPACE; -++ -++ if (!(key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE) || -++ (key->flags & KEY_FLAG_TAINTED)) -++ goto unlock_sta; -++ -++ switch (key->conf.cipher) { -++ case WLAN_CIPHER_SUITE_CCMP: -++ case WLAN_CIPHER_SUITE_CCMP_256: -++ if (gen_iv) -++ build.fast_tx.pn_offs = build.fast_tx.hdr_len; -++ if (gen_iv || iv_spc) -++ build.fast_tx.hdr_len += IEEE80211_CCMP_HDR_LEN; -++ break; -++ case WLAN_CIPHER_SUITE_GCMP: -++ case WLAN_CIPHER_SUITE_GCMP_256: -++ if (gen_iv) -++ build.fast_tx.pn_offs = build.fast_tx.hdr_len; -++ if (gen_iv || iv_spc) -++ build.fast_tx.hdr_len += IEEE80211_GCMP_HDR_LEN; -++ break; -++ default: -++ goto unlock_sta; -++ } -++ } -++ -++ memcpy(build.addr_key, mppath->dst, ETH_ALEN); -++ build.timestamp = jiffies; -++ build.fast_tx.band = info->band; -++ build.fast_tx.da_offs = offsetof(struct ieee80211_hdr, addr3); -++ build.fast_tx.sa_offs = offsetof(struct ieee80211_hdr, addr4); -++ build.mpath = mpath; -++ memcpy(build.hdr, meshhdr, build.hdrlen); -++ memcpy(build.hdr + build.hdrlen, rfc1042_header, sizeof(rfc1042_header)); -++ build.hdrlen += sizeof(rfc1042_header); -++ memcpy(build.fast_tx.hdr, hdr, build.fast_tx.hdr_len); -++ -++ hdr = (struct ieee80211_hdr *)build.fast_tx.hdr; -++ if (build.fast_tx.key) -++ hdr->frame_control |= cpu_to_le16(IEEE80211_FCTL_PROTECTED); -++ -++ qc = ieee80211_get_qos_ctl(hdr); -++ qc[1] |= IEEE80211_QOS_CTL_MESH_CONTROL_PRESENT >> 8; -++ -++ entry = kmemdup(&build, sizeof(build), GFP_ATOMIC); -++ if (!entry) -++ goto unlock_sta; -++ -++ spin_lock(&cache->walk_lock); -++ prev = rhashtable_lookup_get_insert_fast(&cache->rht, -++ &entry->rhash, -++ fast_tx_rht_params); -++ if (unlikely(IS_ERR(prev))) { -++ kfree(entry); -++ goto unlock_cache; -++ } -++ -++ /* -++ * replace any previous entry in the hash table, in case we're -++ * replacing it with a different type (e.g. mpath -> mpp) -++ */ -++ if (unlikely(prev)) { -++ rhashtable_replace_fast(&cache->rht, &prev->rhash, -++ &entry->rhash, fast_tx_rht_params); -++ hlist_del_rcu(&prev->walk_list); -++ kfree_rcu(prev, fast_tx.rcu_head); -++ } -++ -++ hlist_add_head(&entry->walk_list, &cache->walk_head); -++ -++unlock_cache: -++ spin_unlock(&cache->walk_lock); -++unlock_sta: -++ spin_unlock_bh(&sta->lock); -++} -++ -++void mesh_fast_tx_gc(struct ieee80211_sub_if_data *sdata) -++{ -++ unsigned long timeout = msecs_to_jiffies(MESH_FAST_TX_CACHE_TIMEOUT); -++ struct mesh_tx_cache *cache; -++ struct ieee80211_mesh_fast_tx *entry; -++ struct hlist_node *n; -++ -++ cache = &sdata->u.mesh.tx_cache; -++ if (atomic_read(&cache->rht.nelems) < MESH_FAST_TX_CACHE_THRESHOLD_SIZE) -++ return; -++ -++ spin_lock_bh(&cache->walk_lock); -++ hlist_for_each_entry_safe(entry, n, &cache->walk_head, walk_list) -++ if (!time_is_after_jiffies(entry->timestamp + timeout)) -++ mesh_fast_tx_entry_free(cache, entry); -++ spin_unlock_bh(&cache->walk_lock); -++} -++ -++void mesh_fast_tx_flush_mpath(struct mesh_path *mpath) -++{ -++ struct ieee80211_sub_if_data *sdata = mpath->sdata; -++ struct mesh_tx_cache *cache = &sdata->u.mesh.tx_cache; -++ struct ieee80211_mesh_fast_tx *entry; -++ struct hlist_node *n; -++ -++ cache = &sdata->u.mesh.tx_cache; -++ spin_lock_bh(&cache->walk_lock); -++ hlist_for_each_entry_safe(entry, n, &cache->walk_head, walk_list) -++ if (entry->mpath == mpath) -++ mesh_fast_tx_entry_free(cache, entry); -++ spin_unlock_bh(&cache->walk_lock); -++} -++ -++void mesh_fast_tx_flush_sta(struct ieee80211_sub_if_data *sdata, -++ struct sta_info *sta) -++{ -++ struct mesh_tx_cache *cache = &sdata->u.mesh.tx_cache; -++ struct ieee80211_mesh_fast_tx *entry; -++ struct hlist_node *n; -++ -++ cache = &sdata->u.mesh.tx_cache; -++ spin_lock_bh(&cache->walk_lock); -++ hlist_for_each_entry_safe(entry, n, &cache->walk_head, walk_list) -++ if (rcu_access_pointer(entry->mpath->next_hop) == sta) -++ mesh_fast_tx_entry_free(cache, entry); -++ spin_unlock_bh(&cache->walk_lock); -++} -++ -++void mesh_fast_tx_flush_addr(struct ieee80211_sub_if_data *sdata, -++ const u8 *addr) -++{ -++ struct mesh_tx_cache *cache = &sdata->u.mesh.tx_cache; -++ struct ieee80211_mesh_fast_tx *entry; -++ -++ cache = &sdata->u.mesh.tx_cache; -++ spin_lock_bh(&cache->walk_lock); -++ entry = rhashtable_lookup(&cache->rht, addr, fast_tx_rht_params); -++ if (entry) -++ mesh_fast_tx_entry_free(cache, entry); -++ 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) -+@@ -464,6 +737,8 @@ int mpp_path_add(struct ieee80211_sub_if -+ -+ if (ret) -+ kfree(new_mpath); -++ else -++ mesh_fast_tx_flush_addr(sdata, dst); -+ -+ sdata->u.mesh.mpp_paths_generation++; -+ return ret; -+@@ -523,6 +798,10 @@ static void __mesh_path_del(struct mesh_ -+ { -+ hlist_del_rcu(&mpath->walk_list); -+ rhashtable_remove_fast(&tbl->rhead, &mpath->rhash, mesh_rht_params); -++ if (tbl == &mpath->sdata->u.mesh.mpp_paths) -++ mesh_fast_tx_flush_addr(mpath->sdata, mpath->dst); -++ else -++ mesh_fast_tx_flush_mpath(mpath); -+ mesh_path_free_rcu(tbl, mpath); -+ } -+ -+@@ -747,6 +1026,7 @@ void mesh_path_fix_nexthop(struct mesh_p -+ mpath->exp_time = 0; -+ mpath->flags = MESH_PATH_FIXED | MESH_PATH_SN_VALID; -+ mesh_path_activate(mpath); -++ mesh_fast_tx_flush_mpath(mpath); -+ spin_unlock_bh(&mpath->state_lock); -+ ewma_mesh_fail_avg_init(&next_hop->mesh->fail_avg); -+ /* init it at a low value - 0 start is tricky */ -+@@ -758,6 +1038,7 @@ void mesh_pathtbl_init(struct ieee80211_ -+ { -+ mesh_table_init(&sdata->u.mesh.mesh_paths); -+ mesh_table_init(&sdata->u.mesh.mpp_paths); -++ mesh_fast_tx_init(sdata); -+ } -+ -+ static -+@@ -785,6 +1066,7 @@ void mesh_path_expire(struct ieee80211_s -+ -+ void mesh_pathtbl_unregister(struct ieee80211_sub_if_data *sdata) -+ { -++ mesh_fast_tx_deinit(sdata); -+ mesh_table_free(&sdata->u.mesh.mesh_paths); -+ mesh_table_free(&sdata->u.mesh.mpp_paths); -+ } -+--- a/net/mac80211/rx.c -++++ b/net/mac80211/rx.c -+@@ -2791,6 +2791,7 @@ ieee80211_rx_mesh_data(struct ieee80211_ -+ if (mesh_hdr->flags & MESH_FLAGS_AE) { -+ struct mesh_path *mppath; -+ char *proxied_addr; -++ bool update = false; -+ -+ if (multicast) -+ proxied_addr = mesh_hdr->eaddr1; -+@@ -2806,11 +2807,18 @@ ieee80211_rx_mesh_data(struct ieee80211_ -+ mpp_path_add(sdata, proxied_addr, eth->h_source); -+ } else { -+ spin_lock_bh(&mppath->state_lock); -+- if (!ether_addr_equal(mppath->mpp, eth->h_source)) -++ if (!ether_addr_equal(mppath->mpp, eth->h_source)) { -+ memcpy(mppath->mpp, eth->h_source, ETH_ALEN); -++ update = true; -++ } -+ mppath->exp_time = jiffies; -+ spin_unlock_bh(&mppath->state_lock); -+ } -++ -++ /* flush fast xmit cache if the address path changed */ -++ if (update) -++ mesh_fast_tx_flush_addr(sdata, proxied_addr); -++ -+ rcu_read_unlock(); -+ } -+ -+--- a/net/mac80211/tx.c -++++ b/net/mac80211/tx.c -+@@ -3022,6 +3022,9 @@ void ieee80211_check_fast_xmit(struct st -+ if (!ieee80211_hw_check(&local->hw, SUPPORT_FAST_XMIT)) -+ return; -+ -++ if (ieee80211_vif_is_mesh(&sdata->vif)) -++ mesh_fast_tx_flush_sta(sdata, sta); -++ -+ /* Locking here protects both the pointer itself, and against concurrent -+ * invocations winning data access races to, e.g., the key pointer that -+ * is used. -+@@ -3403,6 +3406,9 @@ static bool ieee80211_amsdu_aggregate(st -+ if (sdata->vif.offload_flags & IEEE80211_OFFLOAD_ENCAP_ENABLED) -+ return false; -+ -++ if (ieee80211_vif_is_mesh(&sdata->vif)) -++ return false; -++ -+ if (skb_is_gso(skb)) -+ return false; -+ -+@@ -3635,10 +3641,11 @@ free: -+ return NULL; -+ } -+ -+-static void __ieee80211_xmit_fast(struct ieee80211_sub_if_data *sdata, -+- struct sta_info *sta, -+- struct ieee80211_fast_tx *fast_tx, -+- struct sk_buff *skb, u8 tid, bool ampdu) -++void __ieee80211_xmit_fast(struct ieee80211_sub_if_data *sdata, -++ struct sta_info *sta, -++ struct ieee80211_fast_tx *fast_tx, -++ struct sk_buff *skb, bool ampdu, -++ const u8 *da, const u8 *sa) -+ { -+ struct ieee80211_local *local = sdata->local; -+ struct ieee80211_hdr *hdr = (void *)fast_tx->hdr; -+@@ -3647,7 +3654,6 @@ static void __ieee80211_xmit_fast(struct -+ ieee80211_tx_result r; -+ int hw_headroom = sdata->local->hw.extra_tx_headroom; -+ int extra_head = fast_tx->hdr_len - (ETH_HLEN - 2); -+- struct ethhdr eth; -+ -+ skb = skb_share_check(skb, GFP_ATOMIC); -+ if (unlikely(!skb)) -+@@ -3667,11 +3673,10 @@ static void __ieee80211_xmit_fast(struct -+ ENCRYPT_NO))) -+ goto free; -+ -+- memcpy(ð, skb->data, ETH_HLEN - 2); -+ hdr = skb_push(skb, extra_head); -+ memcpy(skb->data, fast_tx->hdr, fast_tx->hdr_len); -+- memcpy(skb->data + fast_tx->da_offs, eth.h_dest, ETH_ALEN); -+- memcpy(skb->data + fast_tx->sa_offs, eth.h_source, ETH_ALEN); -++ memcpy(skb->data + fast_tx->da_offs, da, ETH_ALEN); -++ memcpy(skb->data + fast_tx->sa_offs, sa, ETH_ALEN); -+ -+ info = IEEE80211_SKB_CB(skb); -+ memset(info, 0, sizeof(*info)); -+@@ -3690,7 +3695,8 @@ static void __ieee80211_xmit_fast(struct -+ #endif -+ -+ if (hdr->frame_control & cpu_to_le16(IEEE80211_STYPE_QOS_DATA)) { -+- tid = skb->priority & IEEE80211_QOS_CTL_TAG1D_MASK; -++ u8 tid = skb->priority & IEEE80211_QOS_CTL_TAG1D_MASK; -++ -+ *ieee80211_get_qos_ctl(hdr) = tid; -+ } -+ -+@@ -3733,6 +3739,7 @@ static bool ieee80211_xmit_fast(struct i -+ struct ieee80211_hdr *hdr = (void *)fast_tx->hdr; -+ struct tid_ampdu_tx *tid_tx = NULL; -+ struct sk_buff *next; -++ struct ethhdr eth; -+ u8 tid = IEEE80211_NUM_TIDS; -+ -+ /* control port protocol needs a lot of special handling */ -+@@ -3758,6 +3765,8 @@ 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)); -+ if (!skb) -+@@ -3765,7 +3774,8 @@ static bool ieee80211_xmit_fast(struct i -+ -+ skb_list_walk_safe(skb, skb, next) { -+ skb_mark_not_on_list(skb); -+- __ieee80211_xmit_fast(sdata, sta, fast_tx, skb, tid, tid_tx); -++ __ieee80211_xmit_fast(sdata, sta, fast_tx, skb, tid_tx, -++ eth.h_dest, eth.h_source); -+ } -+ -+ return true; -+@@ -4252,8 +4262,15 @@ void __ieee80211_subif_start_xmit(struct -+ return; -+ } -+ -++ sk_pacing_shift_update(skb->sk, sdata->local->hw.tx_sk_pacing_shift); -++ -+ rcu_read_lock(); -+ -++ if (ieee80211_vif_is_mesh(&sdata->vif) && -++ ieee80211_hw_check(&local->hw, SUPPORT_FAST_XMIT) && -++ ieee80211_mesh_xmit_fast(sdata, skb, ctrl_flags)) -++ goto out; -++ -+ if (ieee80211_lookup_ra_sta(sdata, skb, &sta)) -+ goto out_free; -+ -+@@ -4263,8 +4280,6 @@ void __ieee80211_subif_start_xmit(struct -+ skb_set_queue_mapping(skb, ieee80211_select_queue(sdata, sta, skb)); -+ ieee80211_aggr_check(sdata, sta, skb); -+ -+- sk_pacing_shift_update(skb->sk, sdata->local->hw.tx_sk_pacing_shift); -+- -+ if (sta) { -+ struct ieee80211_fast_tx *fast_tx; -+ -diff --git a/package/kernel/mac80211/patches/subsys/320-wifi-mac80211-use-mesh-header-cache-to-speed-up-mesh.patch b/package/kernel/mac80211/patches/subsys/320-wifi-mac80211-use-mesh-header-cache-to-speed-up-mesh.patch -new file mode 100644 -index 0000000000..28b1ff1106 ---- /dev/null -+++ b/package/kernel/mac80211/patches/subsys/320-wifi-mac80211-use-mesh-header-cache-to-speed-up-mesh.patch -@@ -0,0 +1,132 @@ -+From: Felix Fietkau -+Date: Thu, 16 Feb 2023 11:07:30 +0100 -+Subject: [PATCH] wifi: mac80211: use mesh header cache to speed up mesh -+ forwarding -+ -+Significantly reduces mesh forwarding path CPU usage and enables the -+direct use of iTXQ. -+ -+Signed-off-by: Felix Fietkau -+--- -+ -+--- a/net/mac80211/rx.c -++++ b/net/mac80211/rx.c -+@@ -2720,6 +2720,65 @@ ieee80211_deliver_skb(struct ieee80211_r -+ } -+ } -+ -++#ifdef CPTCFG_MAC80211_MESH -++static bool -++ieee80211_rx_mesh_fast_forward(struct ieee80211_sub_if_data *sdata, -++ struct sk_buff *skb, int hdrlen) -++{ -++ struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh; -++ struct ieee80211_mesh_fast_tx *entry = NULL; -++ struct ieee80211s_hdr *mesh_hdr; -++ struct tid_ampdu_tx *tid_tx; -++ struct sta_info *sta; -++ struct ethhdr eth; -++ u8 tid; -++ -++ mesh_hdr = (struct ieee80211s_hdr *)(skb->data + sizeof(eth)); -++ if ((mesh_hdr->flags & MESH_FLAGS_AE) == MESH_FLAGS_AE_A5_A6) -++ entry = mesh_fast_tx_get(sdata, mesh_hdr->eaddr1); -++ else if (!(mesh_hdr->flags & MESH_FLAGS_AE)) -++ entry = mesh_fast_tx_get(sdata, skb->data); -++ if (!entry) -++ return false; -++ -++ sta = rcu_dereference(entry->mpath->next_hop); -++ if (!sta) -++ return false; -++ -++ if (skb_linearize(skb)) -++ return false; -++ -++ 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)) -++ return false; -++ -++ if (tid_tx->timeout) -++ tid_tx->last_tx = jiffies; -++ } -++ -++ ieee80211_aggr_check(sdata, sta, skb); -++ -++ if (ieee80211_get_8023_tunnel_proto(skb->data + hdrlen, -++ &skb->protocol)) -++ hdrlen += ETH_ALEN; -++ else -++ skb->protocol = htons(skb->len - hdrlen); -++ skb_set_network_header(skb, hdrlen + 2); -++ -++ skb->dev = sdata->dev; -++ memcpy(ð, skb->data, ETH_HLEN - 2); -++ skb_pull(skb, 2); -++ __ieee80211_xmit_fast(sdata, sta, &entry->fast_tx, skb, tid_tx, -++ eth.h_dest, eth.h_source); -++ IEEE80211_IFSTA_MESH_CTR_INC(ifmsh, fwded_unicast); -++ IEEE80211_IFSTA_MESH_CTR_INC(ifmsh, fwded_frames); -++ -++ return true; -++} -++#endif -++ -+ static ieee80211_rx_result -+ ieee80211_rx_mesh_data(struct ieee80211_sub_if_data *sdata, struct sta_info *sta, -+ struct sk_buff *skb) -+@@ -2824,6 +2883,10 @@ ieee80211_rx_mesh_data(struct ieee80211_ -+ -+ skb_set_queue_mapping(skb, ieee802_1d_to_ac[skb->priority]); -+ -++ if (!multicast && -++ ieee80211_rx_mesh_fast_forward(sdata, skb, mesh_hdrlen)) -++ return RX_QUEUED; -++ -+ ieee80211_fill_mesh_addresses(&hdr, &hdr.frame_control, -+ eth->h_dest, eth->h_source); -+ hdrlen = ieee80211_hdrlen(hdr.frame_control); -+@@ -2862,6 +2925,7 @@ ieee80211_rx_mesh_data(struct ieee80211_ -+ info->control.flags |= IEEE80211_TX_INTCFL_NEED_TXPROCESSING; -+ info->control.vif = &sdata->vif; -+ info->control.jiffies = jiffies; -++ fwd_skb->dev = sdata->dev; -+ if (multicast) { -+ IEEE80211_IFSTA_MESH_CTR_INC(ifmsh, fwded_mcast); -+ memcpy(fwd_hdr->addr2, sdata->vif.addr, ETH_ALEN); -+@@ -2883,7 +2947,6 @@ ieee80211_rx_mesh_data(struct ieee80211_ -+ } -+ -+ IEEE80211_IFSTA_MESH_CTR_INC(ifmsh, fwded_frames); -+- fwd_skb->dev = sdata->dev; -+ ieee80211_add_pending_skb(local, fwd_skb); -+ -+ rx_accept: -+--- a/net/mac80211/ieee80211_i.h -++++ b/net/mac80211/ieee80211_i.h -+@@ -2022,6 +2022,8 @@ void __ieee80211_xmit_fast(struct ieee80 -+ struct ieee80211_fast_tx *fast_tx, -+ struct sk_buff *skb, bool ampdu, -+ const u8 *da, const u8 *sa); -++void ieee80211_aggr_check(struct ieee80211_sub_if_data *sdata, -++ struct sta_info *sta, struct sk_buff *skb); -+ -+ /* HT */ -+ void ieee80211_apply_htcap_overrides(struct ieee80211_sub_if_data *sdata, -+--- a/net/mac80211/tx.c -++++ b/net/mac80211/tx.c -+@@ -1191,10 +1191,8 @@ static bool ieee80211_tx_prep_agg(struct -+ return queued; -+ } -+ -+-static void -+-ieee80211_aggr_check(struct ieee80211_sub_if_data *sdata, -+- struct sta_info *sta, -+- struct sk_buff *skb) -++void ieee80211_aggr_check(struct ieee80211_sub_if_data *sdata, -++ struct sta_info *sta, struct sk_buff *skb) -+ { -+ struct rate_control_ref *ref = sdata->local->rate_ctrl; -+ u16 tid; -diff --git a/package/kernel/mac80211/patches/subsys/321-mac80211-fix-mesh-forwarding.patch b/package/kernel/mac80211/patches/subsys/321-mac80211-fix-mesh-forwarding.patch -new file mode 100644 -index 0000000000..e2b268ae4c ---- /dev/null -+++ b/package/kernel/mac80211/patches/subsys/321-mac80211-fix-mesh-forwarding.patch -@@ -0,0 +1,32 @@ -+From: Felix Fietkau -+Date: Mon, 20 Feb 2023 12:50:50 +0100 -+Subject: [PATCH] mac80211: fix mesh forwarding -+ -+Linearize packets (needed for forwarding A-MSDU subframes). -+Fix network header offset to fix flow dissector (and fair queueing). -+ -+Fixes: 986e43b19ae9 ("wifi: mac80211: fix receiving A-MSDU frames on mesh interfaces") -+Signed-off-by: Felix Fietkau -+--- -+ -+--- a/net/mac80211/rx.c -++++ b/net/mac80211/rx.c -+@@ -2904,6 +2904,9 @@ ieee80211_rx_mesh_data(struct ieee80211_ -+ -+ if (skb_cow_head(fwd_skb, hdrlen - sizeof(struct ethhdr))) -+ return RX_DROP_UNUSABLE; -++ -++ if (skb_linearize(fwd_skb)) -++ return RX_DROP_UNUSABLE; -+ } -+ -+ fwd_hdr = skb_push(fwd_skb, hdrlen - sizeof(struct ethhdr)); -+@@ -2918,7 +2921,7 @@ ieee80211_rx_mesh_data(struct ieee80211_ -+ hdrlen += ETH_ALEN; -+ else -+ fwd_skb->protocol = htons(fwd_skb->len - hdrlen); -+- skb_set_network_header(fwd_skb, hdrlen); -++ skb_set_network_header(fwd_skb, hdrlen + 2); -+ -+ info = IEEE80211_SKB_CB(fwd_skb); -+ memset(info, 0, sizeof(*info)); -diff --git a/package/kernel/mac80211/patches/subsys/322-wifi-mac80211-fix-mesh-path-discovery-based-on-unica.patch b/package/kernel/mac80211/patches/subsys/322-wifi-mac80211-fix-mesh-path-discovery-based-on-unica.patch -new file mode 100644 -index 0000000000..292a89ef92 ---- /dev/null -+++ b/package/kernel/mac80211/patches/subsys/322-wifi-mac80211-fix-mesh-path-discovery-based-on-unica.patch -@@ -0,0 +1,52 @@ -+From: Felix Fietkau -+Date: Sun, 26 Feb 2023 20:30:20 +0100 -+Subject: [PATCH] wifi: mac80211: fix mesh path discovery based on unicast -+ packets -+ -+If a packet has reached its intended destination, it was bumped to the code -+that accepts it, without first checking if a mesh_path needs to be created -+based on the discovered source. -+Fix this by moving the destination address check further down -+ -+Fixes: 986e43b19ae9 ("wifi: mac80211: fix receiving A-MSDU frames on mesh interfaces") -+Signed-off-by: Felix Fietkau -+--- -+ -+--- a/net/mac80211/rx.c -++++ b/net/mac80211/rx.c -+@@ -2824,17 +2824,6 @@ ieee80211_rx_mesh_data(struct ieee80211_ -+ mesh_rmc_check(sdata, eth->h_source, mesh_hdr)) -+ return RX_DROP_MONITOR; -+ -+- /* Frame has reached destination. Don't forward */ -+- if (ether_addr_equal(sdata->vif.addr, eth->h_dest)) -+- goto rx_accept; -+- -+- if (!ifmsh->mshcfg.dot11MeshForwarding) { -+- if (is_multicast_ether_addr(eth->h_dest)) -+- goto rx_accept; -+- -+- return RX_DROP_MONITOR; -+- } -+- -+ /* forward packet */ -+ if (sdata->crypto_tx_tailroom_needed_cnt) -+ tailroom = IEEE80211_ENCRYPT_TAILROOM; -+@@ -2881,6 +2870,17 @@ ieee80211_rx_mesh_data(struct ieee80211_ -+ rcu_read_unlock(); -+ } -+ -++ /* Frame has reached destination. Don't forward */ -++ if (ether_addr_equal(sdata->vif.addr, eth->h_dest)) -++ goto rx_accept; -++ -++ if (!ifmsh->mshcfg.dot11MeshForwarding) { -++ if (is_multicast_ether_addr(eth->h_dest)) -++ goto rx_accept; -++ -++ return RX_DROP_MONITOR; -++ } -++ -+ skb_set_queue_mapping(skb, ieee802_1d_to_ac[skb->priority]); -+ -+ if (!multicast && -diff --git a/package/kernel/mac80211/patches/subsys/323-v6.3-wifi-mac80211-Add-VHT-MU-MIMO-related-flags-in-ieee8.patch b/package/kernel/mac80211/patches/subsys/323-v6.3-wifi-mac80211-Add-VHT-MU-MIMO-related-flags-in-ieee8.patch -new file mode 100644 -index 0000000000..e23dc4d226 ---- /dev/null -+++ b/package/kernel/mac80211/patches/subsys/323-v6.3-wifi-mac80211-Add-VHT-MU-MIMO-related-flags-in-ieee8.patch -@@ -0,0 +1,68 @@ -+From: Muna Sinada -+Date: Wed, 5 Oct 2022 14:54:45 -0700 -+Subject: [PATCH] wifi: mac80211: Add VHT MU-MIMO related flags in -+ ieee80211_bss_conf -+ -+Adding flags for SU Beamformer, SU Beamformee, MU Beamformer and -+MU Beamformee for VHT. This is utilized to pass MU-MIMO -+configurations from user space to driver in AP mode. -+ -+Signed-off-by: Muna Sinada -+Link: https://lore.kernel.org/r/1665006886-23874-1-git-send-email-quic_msinada@quicinc.com -+[fixed indentation, removed redundant !!] -+Signed-off-by: Johannes Berg -+--- -+ -+--- a/include/net/mac80211.h -++++ b/include/net/mac80211.h -+@@ -653,6 +653,14 @@ struct ieee80211_fils_discovery { -+ * write-protected by sdata_lock and local->mtx so holding either is fine -+ * for read access. -+ * @color_change_color: the bss color that will be used after the change. -++ * @vht_su_beamformer: in AP mode, does this BSS support operation as an VHT SU -++ * beamformer -++ * @vht_su_beamformee: in AP mode, does this BSS support operation as an VHT SU -++ * beamformee -++ * @vht_mu_beamformer: in AP mode, does this BSS support operation as an VHT MU -++ * beamformer -++ * @vht_mu_beamformee: in AP mode, does this BSS support operation as an VHT MU -++ * beamformee -+ */ -+ struct ieee80211_bss_conf { -+ const u8 *bssid; -+@@ -726,6 +734,11 @@ struct ieee80211_bss_conf { -+ -+ bool color_change_active; -+ u8 color_change_color; -++ -++ bool vht_su_beamformer; -++ bool vht_su_beamformee; -++ bool vht_mu_beamformer; -++ bool vht_mu_beamformee; -+ }; -+ -+ /** -+--- a/net/mac80211/cfg.c -++++ b/net/mac80211/cfg.c -+@@ -1252,6 +1252,21 @@ static int ieee80211_start_ap(struct wip -+ prev_beacon_int = link_conf->beacon_int; -+ link_conf->beacon_int = params->beacon_interval; -+ -++ if (params->vht_cap) { -++ link_conf->vht_su_beamformer = -++ params->vht_cap->vht_cap_info & -++ cpu_to_le32(IEEE80211_VHT_CAP_SU_BEAMFORMER_CAPABLE); -++ link_conf->vht_su_beamformee = -++ params->vht_cap->vht_cap_info & -++ cpu_to_le32(IEEE80211_VHT_CAP_SU_BEAMFORMEE_CAPABLE); -++ link_conf->vht_mu_beamformer = -++ params->vht_cap->vht_cap_info & -++ cpu_to_le32(IEEE80211_VHT_CAP_MU_BEAMFORMER_CAPABLE); -++ link_conf->vht_mu_beamformee = -++ params->vht_cap->vht_cap_info & -++ cpu_to_le32(IEEE80211_VHT_CAP_MU_BEAMFORMEE_CAPABLE); -++ } -++ -+ if (params->he_cap && params->he_oper) { -+ link_conf->he_support = true; -+ link_conf->htc_trig_based_pkt_ext = -diff --git a/package/kernel/mac80211/patches/subsys/324-v6.3-wifi-mac80211-Add-HE-MU-MIMO-related-flags-in-ieee80.patch b/package/kernel/mac80211/patches/subsys/324-v6.3-wifi-mac80211-Add-HE-MU-MIMO-related-flags-in-ieee80.patch -new file mode 100644 -index 0000000000..f843dba123 ---- /dev/null -+++ b/package/kernel/mac80211/patches/subsys/324-v6.3-wifi-mac80211-Add-HE-MU-MIMO-related-flags-in-ieee80.patch -@@ -0,0 +1,68 @@ -+From: Muna Sinada -+Date: Wed, 5 Oct 2022 14:54:46 -0700 -+Subject: [PATCH] wifi: mac80211: Add HE MU-MIMO related flags in -+ ieee80211_bss_conf -+ -+Adding flags for SU Beamformer, SU Beamformee, MU Beamformer and Full -+Bandwidth UL MU-MIMO for HE. This is utilized to pass MU-MIMO -+configurations from user space to driver in AP mode. -+ -+Signed-off-by: Muna Sinada -+Link: https://lore.kernel.org/r/1665006886-23874-2-git-send-email-quic_msinada@quicinc.com -+[fixed indentation, removed redundant !!] -+Signed-off-by: Johannes Berg -+--- -+ -+--- a/include/net/mac80211.h -++++ b/include/net/mac80211.h -+@@ -661,6 +661,15 @@ struct ieee80211_fils_discovery { -+ * beamformer -+ * @vht_mu_beamformee: in AP mode, does this BSS support operation as an VHT MU -+ * beamformee -++ * @he_su_beamformer: in AP-mode, does this BSS support operation as an HE SU -++ * beamformer -++ * @he_su_beamformee: in AP-mode, does this BSS support operation as an HE SU -++ * beamformee -++ * @he_mu_beamformer: in AP-mode, does this BSS support operation as an HE MU -++ * beamformer -++ * @he_full_ul_mumimo: does this BSS support the reception (AP) or transmission -++ * (non-AP STA) of an HE TB PPDU on an RU that spans the entire PPDU -++ * bandwidth -+ */ -+ struct ieee80211_bss_conf { -+ const u8 *bssid; -+@@ -739,6 +748,10 @@ struct ieee80211_bss_conf { -+ bool vht_su_beamformee; -+ bool vht_mu_beamformer; -+ bool vht_mu_beamformee; -++ bool he_su_beamformer; -++ bool he_su_beamformee; -++ bool he_mu_beamformer; -++ bool he_full_ul_mumimo; -+ }; -+ -+ /** -+--- a/net/mac80211/cfg.c -++++ b/net/mac80211/cfg.c -+@@ -1281,6 +1281,21 @@ static int ieee80211_start_ap(struct wip -+ changed |= BSS_CHANGED_HE_BSS_COLOR; -+ } -+ -++ if (params->he_cap) { -++ link_conf->he_su_beamformer = -++ params->he_cap->phy_cap_info[3] & -++ IEEE80211_HE_PHY_CAP3_SU_BEAMFORMER; -++ link_conf->he_su_beamformee = -++ params->he_cap->phy_cap_info[4] & -++ IEEE80211_HE_PHY_CAP4_SU_BEAMFORMEE; -++ link_conf->he_mu_beamformer = -++ params->he_cap->phy_cap_info[4] & -++ IEEE80211_HE_PHY_CAP4_MU_BEAMFORMER; -++ link_conf->he_full_ul_mumimo = -++ params->he_cap->phy_cap_info[2] & -++ IEEE80211_HE_PHY_CAP2_UL_MU_FULL_MU_MIMO; -++ } -++ -+ if (sdata->vif.type == NL80211_IFTYPE_AP && -+ params->mbssid_config.tx_wdev) { -+ err = ieee80211_set_ap_mbssid_options(sdata, -diff --git a/package/kernel/mac80211/patches/subsys/325-wifi-mac80211-introduce-ieee80211_refresh_tx_agg_ses.patch b/package/kernel/mac80211/patches/subsys/325-wifi-mac80211-introduce-ieee80211_refresh_tx_agg_ses.patch -new file mode 100644 -index 0000000000..1be5fcfbfa ---- /dev/null -+++ b/package/kernel/mac80211/patches/subsys/325-wifi-mac80211-introduce-ieee80211_refresh_tx_agg_ses.patch -@@ -0,0 +1,60 @@ -+From: Ryder Lee -+Date: Sat, 18 Feb 2023 01:50:05 +0800 -+Subject: [PATCH] wifi: mac80211: introduce -+ ieee80211_refresh_tx_agg_session_timer() -+ -+This allows low level drivers to refresh the tx agg session timer, based on -+querying stats from the firmware usually. Especially for some mt76 devices -+support .net_fill_forward_path would bypass mac80211, which leads to tx BA -+session timeout for certain clients. -+ -+Signed-off-by: Ryder Lee -+--- -+ -+--- a/include/net/mac80211.h -++++ b/include/net/mac80211.h -+@@ -5964,6 +5964,18 @@ void ieee80211_queue_delayed_work(struct -+ unsigned long delay); -+ -+ /** -++ * ieee80211_refresh_tx_agg_session_timer - Refresh a tx agg session timer. -++ * @sta: the station for which to start a BA session -++ * @tid: the TID to BA on. -++ * -++ * This function allows low level driver to refresh tx agg session timer -++ * to maintain BA session, the session level will still be managed by the -++ * mac80211. -++ */ -++void ieee80211_refresh_tx_agg_session_timer(struct ieee80211_sta *sta, -++ u16 tid); -++ -++/** -+ * ieee80211_start_tx_ba_session - Start a tx Block Ack session. -+ * @sta: the station for which to start a BA session -+ * @tid: the TID to BA on. -+--- a/net/mac80211/agg-tx.c -++++ b/net/mac80211/agg-tx.c -+@@ -554,6 +554,23 @@ void ieee80211_tx_ba_session_handle_star -+ ieee80211_send_addba_with_timeout(sta, tid_tx); -+ } -+ -++void ieee80211_refresh_tx_agg_session_timer(struct ieee80211_sta *pubsta, -++ u16 tid) -++{ -++ struct sta_info *sta = container_of(pubsta, struct sta_info, sta); -++ struct tid_ampdu_tx *tid_tx; -++ -++ if (WARN_ON_ONCE(tid >= IEEE80211_NUM_TIDS)) -++ return; -++ -++ tid_tx = rcu_dereference(sta->ampdu_mlme.tid_tx[tid]); -++ if (!tid_tx) -++ return; -++ -++ tid_tx->last_tx = jiffies; -++} -++EXPORT_SYMBOL(ieee80211_refresh_tx_agg_session_timer); -++ -+ /* -+ * After accepting the AddBA Response we activated a timer, -+ * resetting it after each frame that we send. -diff --git a/package/kernel/mac80211/patches/subsys/326-wifi-mac80211-add-mesh-fast-rx-support.patch b/package/kernel/mac80211/patches/subsys/326-wifi-mac80211-add-mesh-fast-rx-support.patch -new file mode 100644 -index 0000000000..11f39c2d10 ---- /dev/null -+++ b/package/kernel/mac80211/patches/subsys/326-wifi-mac80211-add-mesh-fast-rx-support.patch -@@ -0,0 +1,77 @@ -+From: Felix Fietkau -+Date: Thu, 2 Mar 2023 13:52:29 +0100 -+Subject: [PATCH] wifi: mac80211: add mesh fast-rx support -+ -+This helps bring down rx CPU usage by avoiding calls to the rx handlers in -+the slow path. Supports forwarding and local rx, including A-MSDU. -+ -+Signed-off-by: Felix Fietkau -+--- -+ -+--- a/net/mac80211/rx.c -++++ b/net/mac80211/rx.c -+@@ -4564,6 +4564,12 @@ void ieee80211_check_fast_rx(struct sta_ -+ } -+ -+ break; -++ case NL80211_IFTYPE_MESH_POINT: -++ 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); -++ break; -+ default: -+ goto clear; -+ } -+@@ -4772,6 +4778,7 @@ static bool ieee80211_invoke_fast_rx(str -+ struct sk_buff *skb = rx->skb; -+ struct ieee80211_hdr *hdr = (void *)skb->data; -+ struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb); -++ static ieee80211_rx_result res; -+ int orig_len = skb->len; -+ int hdrlen = ieee80211_hdrlen(hdr->frame_control); -+ int snap_offs = hdrlen; -+@@ -4833,7 +4840,8 @@ static bool ieee80211_invoke_fast_rx(str -+ snap_offs += IEEE80211_CCMP_HDR_LEN; -+ } -+ -+- if (!(status->rx_flags & IEEE80211_RX_AMSDU)) { -++ if (!ieee80211_vif_is_mesh(&rx->sdata->vif) && -++ !(status->rx_flags & IEEE80211_RX_AMSDU)) { -+ if (!pskb_may_pull(skb, snap_offs + sizeof(*payload))) -+ return false; -+ -+@@ -4872,13 +4880,29 @@ static bool ieee80211_invoke_fast_rx(str -+ /* 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); -+- skb_postpull_rcsum(skb, skb->data + snap_offs, -+- sizeof(rfc1042_header) + 2); -+- /* remove the SNAP but leave the ethertype */ -+- skb_pull(skb, snap_offs + sizeof(rfc1042_header)); -++ if (ieee80211_vif_is_mesh(&rx->sdata->vif)) { -++ skb_pull(skb, snap_offs - 2); -++ put_unaligned_be16(skb->len - 2, skb->data); -++ } else { -++ skb_postpull_rcsum(skb, skb->data + snap_offs, -++ sizeof(rfc1042_header) + 2); -++ -++ /* remove the SNAP but leave the ethertype */ -++ skb_pull(skb, snap_offs + sizeof(rfc1042_header)); -++ } -+ /* push the addresses in front */ -+ memcpy(skb_push(skb, sizeof(addrs)), &addrs, sizeof(addrs)); -+ -++ res = ieee80211_rx_mesh_data(rx->sdata, rx->sta, rx->skb); -++ switch (res) { -++ case RX_QUEUED: -++ return true; -++ case RX_CONTINUE: -++ break; -++ default: -++ goto drop; -++ } -++ -+ ieee80211_rx_8023(rx, fast_rx, orig_len); -+ -+ return true; -diff --git a/package/kernel/mac80211/patches/subsys/327-wifi-mac80211-add-support-for-letting-drivers-regist.patch b/package/kernel/mac80211/patches/subsys/327-wifi-mac80211-add-support-for-letting-drivers-regist.patch -new file mode 100644 -index 0000000000..ac290b5360 ---- /dev/null -+++ b/package/kernel/mac80211/patches/subsys/327-wifi-mac80211-add-support-for-letting-drivers-regist.patch -@@ -0,0 +1,149 @@ -+From: Felix Fietkau -+Date: Mon, 20 Mar 2023 14:28:08 +0100 -+Subject: [PATCH] wifi: mac80211: add support for letting drivers register tc -+ offload support -+ -+On newer MediaTek SoCs (e.g. MT7986), WLAN->WLAN or WLAN->Ethernet flows can -+be offloaded by the SoC. In order to support that, the .ndo_setup_tc op is -+needed. -+ -+Signed-off-by: Felix Fietkau -+--- -+ -+--- a/include/net/mac80211.h -++++ b/include/net/mac80211.h -+@@ -4192,6 +4192,10 @@ struct ieee80211_prep_tx_info { -+ * Note that a sta can also be inserted or removed with valid links, -+ * i.e. passed to @sta_add/@sta_state with sta->valid_links not zero. -+ * In fact, cannot change from having valid_links and not having them. -++ * @net_setup_tc: Called from .ndo_setup_tc in order to prepare hardware -++ * flow offloading for flows originating from the vif. -++ * Note that the driver must not assume that the vif driver_data is valid -++ * at this point, since the callback can be called during netdev teardown. -+ */ -+ struct ieee80211_ops { -+ void (*tx)(struct ieee80211_hw *hw, -+@@ -4547,6 +4551,11 @@ struct ieee80211_ops { -+ struct ieee80211_vif *vif, -+ struct ieee80211_sta *sta, -+ u16 old_links, u16 new_links); -++ int (*net_setup_tc)(struct ieee80211_hw *hw, -++ struct ieee80211_vif *vif, -++ struct net_device *dev, -++ enum tc_setup_type type, -++ void *type_data); -+ }; -+ -+ /** -+--- a/net/mac80211/driver-ops.h -++++ b/net/mac80211/driver-ops.h -+@@ -1470,6 +1470,23 @@ static inline int drv_net_fill_forward_p -+ return ret; -+ } -+ -++static inline int drv_net_setup_tc(struct ieee80211_local *local, -++ struct ieee80211_sub_if_data *sdata, -++ struct net_device *dev, -++ enum tc_setup_type type, void *type_data) -++{ -++ int ret = -EOPNOTSUPP; -++ -++ sdata = get_bss_sdata(sdata); -++ trace_drv_net_setup_tc(local, sdata, type); -++ if (local->ops->net_setup_tc) -++ ret = local->ops->net_setup_tc(&local->hw, &sdata->vif, dev, -++ type, type_data); -++ trace_drv_return_int(local, ret); -++ -++ return ret; -++} -++ -+ int drv_change_vif_links(struct ieee80211_local *local, -+ struct ieee80211_sub_if_data *sdata, -+ u16 old_links, u16 new_links, -+--- a/net/mac80211/ieee80211_i.h -++++ b/net/mac80211/ieee80211_i.h -+@@ -1939,7 +1939,8 @@ void ieee80211_color_collision_detection -+ /* interface handling */ -+ #define MAC80211_SUPPORTED_FEATURES_TX (NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM | \ -+ NETIF_F_HW_CSUM | NETIF_F_SG | \ -+- NETIF_F_HIGHDMA | NETIF_F_GSO_SOFTWARE) -++ NETIF_F_HIGHDMA | NETIF_F_GSO_SOFTWARE | \ -++ NETIF_F_HW_TC) -+ #define MAC80211_SUPPORTED_FEATURES_RX (NETIF_F_RXCSUM) -+ #define MAC80211_SUPPORTED_FEATURES (MAC80211_SUPPORTED_FEATURES_TX | \ -+ MAC80211_SUPPORTED_FEATURES_RX) -+--- a/net/mac80211/iface.c -++++ b/net/mac80211/iface.c -+@@ -813,6 +813,21 @@ ieee80211_get_stats64(struct net_device -+ dev_fetch_sw_netstats(stats, dev->tstats); -+ } -+ -++static int ieee80211_netdev_setup_tc(struct net_device *dev, -++ enum tc_setup_type type, void *type_data) -++{ -++ struct ieee80211_sub_if_data *sdata; -++ struct ieee80211_local *local; -++ -++ sdata = IEEE80211_DEV_TO_SUB_IF(dev); -++ local = sdata->local; -++ -++ if (!local->ops->net_setup_tc) -++ return -EOPNOTSUPP; -++ -++ return drv_net_setup_tc(local, sdata, dev, type, type_data); -++} -++ -+ static const struct net_device_ops ieee80211_dataif_ops = { -+ .ndo_open = ieee80211_open, -+ .ndo_stop = ieee80211_stop, -+@@ -821,6 +836,7 @@ static const struct net_device_ops ieee8 -+ .ndo_set_rx_mode = ieee80211_set_multicast_list, -+ .ndo_set_mac_address = ieee80211_change_mac, -+ .ndo_get_stats64 = ieee80211_get_stats64, -++ .ndo_setup_tc = ieee80211_netdev_setup_tc, -+ }; -+ -+ static u16 ieee80211_monitor_select_queue(struct net_device *dev, -+@@ -929,6 +945,7 @@ static const struct net_device_ops ieee8 -+ .ndo_set_mac_address = ieee80211_change_mac, -+ .ndo_get_stats64 = ieee80211_get_stats64, -+ .ndo_fill_forward_path = ieee80211_netdev_fill_forward_path, -++ .ndo_setup_tc = ieee80211_netdev_setup_tc, -+ }; -+ -+ static bool ieee80211_iftype_supports_hdr_offload(enum nl80211_iftype iftype) -+--- a/net/mac80211/trace.h -++++ b/net/mac80211/trace.h -+@@ -2478,6 +2478,31 @@ DEFINE_EVENT(sta_event, drv_net_fill_for -+ TP_ARGS(local, sdata, sta) -+ ); -+ -++TRACE_EVENT(drv_net_setup_tc, -++ TP_PROTO(struct ieee80211_local *local, -++ struct ieee80211_sub_if_data *sdata, -++ u8 type), -++ -++ TP_ARGS(local, sdata, type), -++ -++ TP_STRUCT__entry( -++ LOCAL_ENTRY -++ VIF_ENTRY -++ __field(u8, type) -++ ), -++ -++ TP_fast_assign( -++ LOCAL_ASSIGN; -++ VIF_ASSIGN; -++ __entry->type = type; -++ ), -++ -++ TP_printk( -++ LOCAL_PR_FMT VIF_PR_FMT " type:%d\n", -++ LOCAL_PR_ARG, VIF_PR_ARG, __entry->type -++ ) -++); -++ -+ TRACE_EVENT(drv_change_vif_links, -+ TP_PROTO(struct ieee80211_local *local, -+ struct ieee80211_sub_if_data *sdata, -diff --git a/package/kernel/mac80211/patches/subsys/329-wifi-mac80211-fix-receiving-mesh-packets-in-forwardi.patch b/package/kernel/mac80211/patches/subsys/329-wifi-mac80211-fix-receiving-mesh-packets-in-forwardi.patch -new file mode 100644 -index 0000000000..6882694da8 ---- /dev/null -+++ b/package/kernel/mac80211/patches/subsys/329-wifi-mac80211-fix-receiving-mesh-packets-in-forwardi.patch -@@ -0,0 +1,50 @@ -+From: Felix Fietkau -+Date: Sun, 26 Mar 2023 17:11:34 +0200 -+Subject: [PATCH] wifi: mac80211: fix receiving mesh packets in forwarding=0 -+ networks -+MIME-Version: 1.0 -+Content-Type: text/plain; charset=UTF-8 -+Content-Transfer-Encoding: 8bit -+ -+When forwarding is set to 0, frames are typically sent with ttl=1. -+Move the ttl decrement check below the check for local receive in order to -+fix packet drops. -+ -+Reported-by: Thomas Hühn -+Reported-by: Nick Hainke -+Fixes: 986e43b19ae9 ("wifi: mac80211: fix receiving A-MSDU frames on mesh interfaces") -+Signed-off-by: Felix Fietkau -+--- -+ -+--- a/net/mac80211/rx.c -++++ b/net/mac80211/rx.c -+@@ -2828,14 +2828,6 @@ ieee80211_rx_mesh_data(struct ieee80211_ -+ if (sdata->crypto_tx_tailroom_needed_cnt) -+ tailroom = IEEE80211_ENCRYPT_TAILROOM; -+ -+- if (!--mesh_hdr->ttl) { -+- if (multicast) -+- goto rx_accept; -+- -+- IEEE80211_IFSTA_MESH_CTR_INC(ifmsh, dropped_frames_ttl); -+- return RX_DROP_MONITOR; -+- } -+- -+ if (mesh_hdr->flags & MESH_FLAGS_AE) { -+ struct mesh_path *mppath; -+ char *proxied_addr; -+@@ -2874,6 +2866,14 @@ ieee80211_rx_mesh_data(struct ieee80211_ -+ if (ether_addr_equal(sdata->vif.addr, eth->h_dest)) -+ goto rx_accept; -+ -++ if (!--mesh_hdr->ttl) { -++ if (multicast) -++ goto rx_accept; -++ -++ IEEE80211_IFSTA_MESH_CTR_INC(ifmsh, dropped_frames_ttl); -++ return RX_DROP_MONITOR; -++ } -++ -+ if (!ifmsh->mshcfg.dot11MeshForwarding) { -+ if (is_multicast_ether_addr(eth->h_dest)) -+ goto rx_accept; -diff --git a/package/kernel/mac80211/patches/subsys/330-wifi-ieee80211-correctly-mark-FTM-frames-non-buffera.patch b/package/kernel/mac80211/patches/subsys/330-wifi-ieee80211-correctly-mark-FTM-frames-non-buffera.patch -new file mode 100644 -index 0000000000..079dd2a868 ---- /dev/null -+++ b/package/kernel/mac80211/patches/subsys/330-wifi-ieee80211-correctly-mark-FTM-frames-non-buffera.patch -@@ -0,0 +1,134 @@ -+From: Johannes Berg -+Date: Wed, 29 Mar 2023 16:46:26 +0200 -+Subject: [PATCH] wifi: ieee80211: correctly mark FTM frames non-bufferable -+ -+The checks of whether or not a frame is bufferable were not -+taking into account that some action frames aren't, such as -+FTM. Check this, which requires some changes to the function -+ieee80211_is_bufferable_mmpdu() since we need the whole skb -+for the checks now. -+ -+Signed-off-by: Johannes Berg -+Reviewed-by: Greenman, Gregory -+Reviewed-by: Peer, Ilan -+--- -+ -+--- a/drivers/net/wireless/intel/iwlwifi/mvm/tx.c -++++ b/drivers/net/wireless/intel/iwlwifi/mvm/tx.c -+@@ -601,8 +601,9 @@ static void iwl_mvm_skb_prepare_status(s -+ -+ static int iwl_mvm_get_ctrl_vif_queue(struct iwl_mvm *mvm, -+ struct ieee80211_tx_info *info, -+- struct ieee80211_hdr *hdr) -++ struct sk_buff *skb) -+ { -++ struct ieee80211_hdr *hdr = (void *)skb->data; -+ struct iwl_mvm_vif *mvmvif = -+ iwl_mvm_vif_from_mac80211(info->control.vif); -+ __le16 fc = hdr->frame_control; -+@@ -621,7 +622,7 @@ static int iwl_mvm_get_ctrl_vif_queue(st -+ * reason 7 ("Class 3 frame received from nonassociated STA"). -+ */ -+ if (ieee80211_is_mgmt(fc) && -+- (!ieee80211_is_bufferable_mmpdu(fc) || -++ (!ieee80211_is_bufferable_mmpdu(skb) || -+ ieee80211_is_deauth(fc) || ieee80211_is_disassoc(fc))) -+ return mvm->probe_queue; -+ -+@@ -740,7 +741,7 @@ int iwl_mvm_tx_skb_non_sta(struct iwl_mv -+ else -+ sta_id = mvmvif->mcast_sta.sta_id; -+ -+- queue = iwl_mvm_get_ctrl_vif_queue(mvm, &info, hdr); -++ queue = iwl_mvm_get_ctrl_vif_queue(mvm, &info, skb); -+ } else if (info.control.vif->type == NL80211_IFTYPE_MONITOR) { -+ queue = mvm->snif_queue; -+ sta_id = mvm->snif_sta.sta_id; -+--- a/include/linux/ieee80211.h -++++ b/include/linux/ieee80211.h -+@@ -772,20 +772,6 @@ static inline bool ieee80211_is_any_null -+ } -+ -+ /** -+- * ieee80211_is_bufferable_mmpdu - check if frame is bufferable MMPDU -+- * @fc: frame control field in little-endian byteorder -+- */ -+-static inline bool ieee80211_is_bufferable_mmpdu(__le16 fc) -+-{ -+- /* IEEE 802.11-2012, definition of "bufferable management frame"; -+- * note that this ignores the IBSS special case. */ -+- return ieee80211_is_mgmt(fc) && -+- (ieee80211_is_action(fc) || -+- ieee80211_is_disassoc(fc) || -+- ieee80211_is_deauth(fc)); -+-} -+- -+-/** -+ * ieee80211_is_first_frag - check if IEEE80211_SCTL_FRAG is not set -+ * @seq_ctrl: frame sequence control bytes in little-endian byteorder -+ */ -+@@ -4121,6 +4107,44 @@ static inline u8 *ieee80211_get_DA(struc -+ } -+ -+ /** -++ * ieee80211_is_bufferable_mmpdu - check if frame is bufferable MMPDU -++ * @skb: the skb to check, starting with the 802.11 header -++ */ -++static inline bool ieee80211_is_bufferable_mmpdu(struct sk_buff *skb) -++{ -++ struct ieee80211_mgmt *mgmt = (void *)skb->data; -++ __le16 fc = mgmt->frame_control; -++ -++ /* -++ * IEEE 802.11 REVme D2.0 definition of bufferable MMPDU; -++ * note that this ignores the IBSS special case. -++ */ -++ if (!ieee80211_is_mgmt(fc)) -++ return false; -++ -++ if (ieee80211_is_disassoc(fc) || ieee80211_is_deauth(fc)) -++ return true; -++ -++ if (!ieee80211_is_action(fc)) -++ return false; -++ -++ if (skb->len < offsetofend(typeof(*mgmt), u.action.u.ftm.action_code)) -++ return true; -++ -++ /* action frame - additionally check for non-bufferable FTM */ -++ -++ if (mgmt->u.action.category != WLAN_CATEGORY_PUBLIC && -++ mgmt->u.action.category != WLAN_CATEGORY_PROTECTED_DUAL_OF_ACTION) -++ return true; -++ -++ if (mgmt->u.action.u.ftm.action_code == WLAN_PUB_ACTION_FTM_REQUEST || -++ mgmt->u.action.u.ftm.action_code == WLAN_PUBLIC_ACTION_FTM_RESPONSE) -++ return false; -++ -++ return true; -++} -++ -++/** -+ * _ieee80211_is_robust_mgmt_frame - check if frame is a robust management frame -+ * @hdr: the frame (buffer must include at least the first octet of payload) -+ */ -+--- a/net/mac80211/tx.c -++++ b/net/mac80211/tx.c -+@@ -488,7 +488,7 @@ ieee80211_tx_h_unicast_ps_buf(struct iee -+ int ac = skb_get_queue_mapping(tx->skb); -+ -+ if (ieee80211_is_mgmt(hdr->frame_control) && -+- !ieee80211_is_bufferable_mmpdu(hdr->frame_control)) { -++ !ieee80211_is_bufferable_mmpdu(tx->skb)) { -+ info->flags |= IEEE80211_TX_CTL_NO_PS_BUFFER; -+ return TX_CONTINUE; -+ } -+@@ -1326,7 +1326,7 @@ static struct txq_info *ieee80211_get_tx -+ if (!(info->flags & IEEE80211_TX_CTL_HW_80211_ENCAP) && -+ unlikely(!ieee80211_is_data_present(hdr->frame_control))) { -+ if ((!ieee80211_is_mgmt(hdr->frame_control) || -+- ieee80211_is_bufferable_mmpdu(hdr->frame_control) || -++ ieee80211_is_bufferable_mmpdu(skb) || -+ vif->type == NL80211_IFTYPE_STATION) && -+ sta && sta->uploaded) { -+ /* -diff --git a/package/kernel/mac80211/patches/subsys/331-wifi-mac80211-flush-queues-on-STA-removal.patch b/package/kernel/mac80211/patches/subsys/331-wifi-mac80211-flush-queues-on-STA-removal.patch -new file mode 100644 -index 0000000000..00232ec1b9 ---- /dev/null -+++ b/package/kernel/mac80211/patches/subsys/331-wifi-mac80211-flush-queues-on-STA-removal.patch -@@ -0,0 +1,36 @@ -+From: Johannes Berg -+Date: Mon, 13 Mar 2023 11:42:12 +0100 -+Subject: [PATCH] wifi: mac80211: flush queues on STA removal -+ -+When we remove a station, we first make it unreachable, -+then we (must) remove its keys, and then remove the -+station itself. Depending on the hardware design, if -+we have hardware crypto at all, frames still sitting -+on hardware queues may then be transmitted without a -+valid key, possibly unencrypted or with a fixed key. -+ -+Fix this by flushing the queues when removing stations -+so this cannot happen. -+ -+Cc: stable@vger.kernel.org -+Signed-off-by: Johannes Berg -+Reviewed-by: Greenman, Gregory -+--- -+ -+--- a/net/mac80211/sta_info.c -++++ b/net/mac80211/sta_info.c -+@@ -1271,6 +1271,14 @@ 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) -++ ieee80211_flush_queues(local, sta->sdata, false); -++ -+ /* now keys can no longer be reached */ -+ ieee80211_free_sta_keys(local, sta); -+ -diff --git a/package/kernel/mac80211/patches/subsys/332-wifi-iwlwifi-mvm-support-flush-on-AP-interfaces.patch b/package/kernel/mac80211/patches/subsys/332-wifi-iwlwifi-mvm-support-flush-on-AP-interfaces.patch -new file mode 100644 -index 0000000000..3c31dfeddc ---- /dev/null -+++ b/package/kernel/mac80211/patches/subsys/332-wifi-iwlwifi-mvm-support-flush-on-AP-interfaces.patch -@@ -0,0 +1,34 @@ -+From: Johannes Berg -+Date: Mon, 13 Mar 2023 12:02:58 +0100 -+Subject: [PATCH] wifi: iwlwifi: mvm: support flush on AP interfaces -+ -+Support TX flush on AP interfaces so that we will do a -+proper flush for frames on the queue before keys are -+removed. -+ -+Signed-off-by: Johannes Berg -+Reviewed-by: Greenman, Gregory -+--- -+ -+--- a/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c -++++ b/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c -+@@ -4854,9 +4854,6 @@ static void iwl_mvm_mac_flush(struct iee -+ return; -+ } -+ -+- if (vif->type != NL80211_IFTYPE_STATION) -+- return; -+- -+ /* Make sure we're done with the deferred traffic before flushing */ -+ flush_work(&mvm->add_stream_wk); -+ -+@@ -4874,9 +4871,6 @@ static void iwl_mvm_mac_flush(struct iee -+ if (mvmsta->vif != vif) -+ continue; -+ -+- /* make sure only TDLS peers or the AP are flushed */ -+- WARN_ON(i != mvmvif->ap_sta_id && !sta->tdls); -+- -+ if (drop) { -+ if (iwl_mvm_flush_sta(mvm, mvmsta, false)) -+ IWL_ERR(mvm, "flush request fail\n"); -diff --git a/package/kernel/mac80211/patches/subsys/333-wifi-mac80211-add-flush_sta-method.patch b/package/kernel/mac80211/patches/subsys/333-wifi-mac80211-add-flush_sta-method.patch -new file mode 100644 -index 0000000000..3bba0b7e66 ---- /dev/null -+++ b/package/kernel/mac80211/patches/subsys/333-wifi-mac80211-add-flush_sta-method.patch -@@ -0,0 +1,91 @@ -+From: Johannes Berg -+Date: Mon, 13 Mar 2023 11:53:51 +0100 -+Subject: [PATCH] wifi: mac80211: add flush_sta method -+ -+Some drivers like iwlwifi might have per-STA queues, so we -+may want to flush/drop just those queues rather than all -+when removing a station. Add a separate method for that. -+ -+Signed-off-by: Johannes Berg -+Reviewed-by: Greenman, Gregory -+--- -+ -+--- a/include/net/mac80211.h -++++ b/include/net/mac80211.h -+@@ -3918,6 +3918,10 @@ struct ieee80211_prep_tx_info { -+ * Note that vif can be NULL. -+ * The callback can sleep. -+ * -++ * @flush_sta: Flush or drop all pending frames from the hardware queue(s) for -++ * the given station, as it's about to be removed. -++ * The callback can sleep. -++ * -+ * @channel_switch: Drivers that need (or want) to offload the channel -+ * switch operation for CSAs received from the AP may implement this -+ * callback. They must then call ieee80211_chswitch_done() to indicate -+@@ -4372,6 +4376,8 @@ struct ieee80211_ops { -+ #endif -+ void (*flush)(struct ieee80211_hw *hw, struct ieee80211_vif *vif, -+ u32 queues, bool drop); -++ void (*flush_sta)(struct ieee80211_hw *hw, struct ieee80211_vif *vif, -++ struct ieee80211_sta *sta); -+ void (*channel_switch)(struct ieee80211_hw *hw, -+ struct ieee80211_vif *vif, -+ struct ieee80211_channel_switch *ch_switch); -+--- a/net/mac80211/driver-ops.h -++++ b/net/mac80211/driver-ops.h -+@@ -617,6 +617,21 @@ static inline void drv_flush(struct ieee -+ trace_drv_return_void(local); -+ } -+ -++static inline void drv_flush_sta(struct ieee80211_local *local, -++ struct ieee80211_sub_if_data *sdata, -++ struct sta_info *sta) -++{ -++ might_sleep(); -++ -++ if (sdata && !check_sdata_in_driver(sdata)) -++ return; -++ -++ trace_drv_flush_sta(local, sdata, &sta->sta); -++ if (local->ops->flush_sta) -++ local->ops->flush_sta(&local->hw, &sdata->vif, &sta->sta); -++ trace_drv_return_void(local); -++} -++ -+ static inline void drv_channel_switch(struct ieee80211_local *local, -+ struct ieee80211_sub_if_data *sdata, -+ struct ieee80211_channel_switch *ch_switch) -+--- a/net/mac80211/sta_info.c -++++ b/net/mac80211/sta_info.c -+@@ -1276,8 +1276,12 @@ static void __sta_info_destroy_part2(str -+ * frames sitting on hardware queues might be sent out without -+ * any encryption at all. -+ */ -+- if (local->ops->set_key) -+- ieee80211_flush_queues(local, sta->sdata, false); -++ 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/trace.h -++++ b/net/mac80211/trace.h -+@@ -1177,6 +1177,13 @@ TRACE_EVENT(drv_flush, -+ ) -+ ); -+ -++DEFINE_EVENT(sta_event, drv_flush_sta, -++ TP_PROTO(struct ieee80211_local *local, -++ struct ieee80211_sub_if_data *sdata, -++ struct ieee80211_sta *sta), -++ TP_ARGS(local, sdata, sta) -++); -++ -+ TRACE_EVENT(drv_channel_switch, -+ TP_PROTO(struct ieee80211_local *local, -+ struct ieee80211_sub_if_data *sdata, -diff --git a/package/kernel/mac80211/patches/subsys/334-wifi-iwlwifi-mvm-support-new-flush_sta-method.patch b/package/kernel/mac80211/patches/subsys/334-wifi-iwlwifi-mvm-support-new-flush_sta-method.patch -new file mode 100644 -index 0000000000..18f39d505f ---- /dev/null -+++ b/package/kernel/mac80211/patches/subsys/334-wifi-iwlwifi-mvm-support-new-flush_sta-method.patch -@@ -0,0 +1,53 @@ -+From: Johannes Berg -+Date: Mon, 13 Mar 2023 12:05:35 +0100 -+Subject: [PATCH] wifi: iwlwifi: mvm: support new flush_sta method -+ -+For iwlwifi this is simple to implement, and on newer hardware -+it's an improvement since we have per-station queues. -+ -+Signed-off-by: Johannes Berg -+Reviewed-by: Greenman, Gregory -+--- -+ -+--- a/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c -++++ b/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c -+@@ -4890,6 +4890,31 @@ static void iwl_mvm_mac_flush(struct iee -+ iwl_trans_wait_tx_queues_empty(mvm->trans, msk); -+ } -+ -++static void iwl_mvm_mac_flush_sta(struct ieee80211_hw *hw, -++ struct ieee80211_vif *vif, -++ struct ieee80211_sta *sta) -++{ -++ struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw); -++ int i; -++ -++ mutex_lock(&mvm->mutex); -++ for (i = 0; i < mvm->fw->ucode_capa.num_stations; i++) { -++ struct iwl_mvm_sta *mvmsta; -++ struct ieee80211_sta *tmp; -++ -++ tmp = rcu_dereference_protected(mvm->fw_id_to_mac_id[i], -++ lockdep_is_held(&mvm->mutex)); -++ if (tmp != sta) -++ continue; -++ -++ mvmsta = iwl_mvm_sta_from_mac80211(sta); -++ -++ if (iwl_mvm_flush_sta(mvm, mvmsta, false)) -++ IWL_ERR(mvm, "flush request fail\n"); -++ } -++ mutex_unlock(&mvm->mutex); -++} -++ -+ static int iwl_mvm_mac_get_survey(struct ieee80211_hw *hw, int idx, -+ struct survey_info *survey) -+ { -+@@ -5417,6 +5442,7 @@ const struct ieee80211_ops iwl_mvm_hw_op -+ .mgd_complete_tx = iwl_mvm_mac_mgd_complete_tx, -+ .mgd_protect_tdls_discover = iwl_mvm_mac_mgd_protect_tdls_discover, -+ .flush = iwl_mvm_mac_flush, -++ .flush_sta = iwl_mvm_mac_flush_sta, -+ .sched_scan_start = iwl_mvm_mac_sched_scan_start, -+ .sched_scan_stop = iwl_mvm_mac_sched_scan_stop, -+ .set_key = iwl_mvm_mac_set_key, -diff --git a/package/kernel/mac80211/patches/subsys/335-wifi-mac80211-add-LDPC-related-flags-in-ieee80211_bs.patch b/package/kernel/mac80211/patches/subsys/335-wifi-mac80211-add-LDPC-related-flags-in-ieee80211_bs.patch -new file mode 100644 -index 0000000000..1b379b76ae ---- /dev/null -+++ b/package/kernel/mac80211/patches/subsys/335-wifi-mac80211-add-LDPC-related-flags-in-ieee80211_bs.patch -@@ -0,0 +1,62 @@ -+From: Ryder Lee -+Date: Sat, 18 Feb 2023 01:49:25 +0800 -+Subject: [PATCH] wifi: mac80211: add LDPC related flags in ieee80211_bss_conf -+ -+This is utilized to pass LDPC configurations from user space -+(i.e. hostapd) to driver. -+ -+Signed-off-by: Ryder Lee -+Link: https://lore.kernel.org/r/1de696aaa34efd77a926eb657b8c0fda05aaa177.1676628065.git.ryder.lee@mediatek.com -+Signed-off-by: Johannes Berg -+--- -+ -+--- a/include/net/mac80211.h -++++ b/include/net/mac80211.h -+@@ -653,6 +653,9 @@ struct ieee80211_fils_discovery { -+ * write-protected by sdata_lock and local->mtx so holding either is fine -+ * for read access. -+ * @color_change_color: the bss color that will be used after the change. -++ * @ht_ldpc: in AP mode, indicates interface has HT LDPC capability. -++ * @vht_ldpc: in AP mode, indicates interface has VHT LDPC capability. -++ * @he_ldpc: in AP mode, indicates interface has HE LDPC capability. -+ * @vht_su_beamformer: in AP mode, does this BSS support operation as an VHT SU -+ * beamformer -+ * @vht_su_beamformee: in AP mode, does this BSS support operation as an VHT SU -+@@ -744,6 +747,9 @@ struct ieee80211_bss_conf { -+ bool color_change_active; -+ u8 color_change_color; -+ -++ bool ht_ldpc; -++ bool vht_ldpc; -++ bool he_ldpc; -+ bool vht_su_beamformer; -+ bool vht_su_beamformee; -+ bool vht_mu_beamformer; -+--- a/net/mac80211/cfg.c -++++ b/net/mac80211/cfg.c -+@@ -1252,7 +1252,15 @@ static int ieee80211_start_ap(struct wip -+ prev_beacon_int = link_conf->beacon_int; -+ link_conf->beacon_int = params->beacon_interval; -+ -++ if (params->ht_cap) -++ link_conf->ht_ldpc = -++ params->ht_cap->cap_info & -++ cpu_to_le16(IEEE80211_HT_CAP_LDPC_CODING); -++ -+ if (params->vht_cap) { -++ link_conf->vht_ldpc = -++ params->vht_cap->vht_cap_info & -++ cpu_to_le32(IEEE80211_VHT_CAP_RXLDPC); -+ link_conf->vht_su_beamformer = -+ params->vht_cap->vht_cap_info & -+ cpu_to_le32(IEEE80211_VHT_CAP_SU_BEAMFORMER_CAPABLE); -+@@ -1282,6 +1290,9 @@ static int ieee80211_start_ap(struct wip -+ } -+ -+ if (params->he_cap) { -++ link_conf->he_ldpc = -++ params->he_cap->phy_cap_info[1] & -++ IEEE80211_HE_PHY_CAP1_LDPC_CODING_IN_PAYLOAD; -+ link_conf->he_su_beamformer = -+ params->he_cap->phy_cap_info[3] & -+ IEEE80211_HE_PHY_CAP3_SU_BEAMFORMER; -diff --git a/package/kernel/mac80211/patches/subsys/336-v6.4-wifi-mac80211-generate-EMA-beacons-in-AP-mode.patch b/package/kernel/mac80211/patches/subsys/336-v6.4-wifi-mac80211-generate-EMA-beacons-in-AP-mode.patch -new file mode 100644 -index 0000000000..088f468e37 ---- /dev/null -+++ b/package/kernel/mac80211/patches/subsys/336-v6.4-wifi-mac80211-generate-EMA-beacons-in-AP-mode.patch -@@ -0,0 +1,372 @@ -+From bd54f3c29077f23dad92ef82a78061b40be30c65 Mon Sep 17 00:00:00 2001 -+From: Aloka Dixit -+Date: Mon, 5 Dec 2022 16:50:37 -0800 -+Subject: [PATCH] wifi: mac80211: generate EMA beacons in AP mode -+ -+Add APIs to generate an array of beacons for an EMA AP (enhanced -+multiple BSSID advertisements), each including a single MBSSID element. -+EMA profile periodicity equals the count of elements. -+ -+- ieee80211_beacon_get_template_ema_list() - Generate and return all -+EMA beacon templates. Drivers must call ieee80211_beacon_free_ema_list() -+to free the memory. No change in the prototype for the existing API, -+ieee80211_beacon_get_template(), which should be used for non-EMA AP. -+ -+- ieee80211_beacon_get_template_ema_index() - Generate a beacon which -+includes the multiple BSSID element at the given index. Drivers can use -+this function in a loop until NULL is returned which indicates end of -+available MBSSID elements. -+ -+- ieee80211_beacon_free_ema_list() - free the memory allocated for the -+list of EMA beacon templates. -+ -+Modify existing functions ieee80211_beacon_get_ap(), -+ieee80211_get_mbssid_beacon_len() and ieee80211_beacon_add_mbssid() -+to accept a new parameter for EMA index. -+ -+Signed-off-by: Aloka Dixit -+Co-developed-by: John Crispin -+Signed-off-by: John Crispin -+Link: https://lore.kernel.org/r/20221206005040.3177-2-quic_alokad@quicinc.com -+Signed-off-by: Johannes Berg -+--- -+ include/net/mac80211.h | 68 +++++++++++++++++++ -+ net/mac80211/cfg.c | 11 +-- -+ net/mac80211/ieee80211_i.h | 10 ++- -+ net/mac80211/tx.c | 134 ++++++++++++++++++++++++++++++++++--- -+ 4 files changed, 205 insertions(+), 18 deletions(-) -+ -+--- a/include/net/mac80211.h -++++ b/include/net/mac80211.h -+@@ -5252,6 +5252,74 @@ ieee80211_beacon_get_template(struct iee -+ unsigned int link_id); -+ -+ /** -++ * ieee80211_beacon_get_template_ema_index - EMA beacon template generation -++ * @hw: pointer obtained from ieee80211_alloc_hw(). -++ * @vif: &struct ieee80211_vif pointer from the add_interface callback. -++ * @offs: &struct ieee80211_mutable_offsets pointer to struct that will -++ * receive the offsets that may be updated by the driver. -++ * @link_id: the link id to which the beacon belongs (or 0 for a non-MLD AP). -++ * @ema_index: index of the beacon in the EMA set. -++ * -++ * This function follows the same rules as ieee80211_beacon_get_template() -++ * but returns a beacon template which includes multiple BSSID element at the -++ * requested index. -++ * -++ * Return: The beacon template. %NULL indicates the end of EMA templates. -++ */ -++struct sk_buff * -++ieee80211_beacon_get_template_ema_index(struct ieee80211_hw *hw, -++ struct ieee80211_vif *vif, -++ struct ieee80211_mutable_offsets *offs, -++ unsigned int link_id, u8 ema_index); -++ -++/** -++ * struct ieee80211_ema_beacons - List of EMA beacons -++ * @cnt: count of EMA beacons. -++ * -++ * @bcn: array of EMA beacons. -++ * @bcn.skb: the skb containing this specific beacon -++ * @bcn.offs: &struct ieee80211_mutable_offsets pointer to struct that will -++ * receive the offsets that may be updated by the driver. -++ */ -++struct ieee80211_ema_beacons { -++ u8 cnt; -++ struct { -++ struct sk_buff *skb; -++ struct ieee80211_mutable_offsets offs; -++ } bcn[]; -++}; -++ -++/** -++ * ieee80211_beacon_get_template_ema_list - EMA beacon template generation -++ * @hw: pointer obtained from ieee80211_alloc_hw(). -++ * @vif: &struct ieee80211_vif pointer from the add_interface callback. -++ * @link_id: the link id to which the beacon belongs (or 0 for a non-MLD AP) -++ * -++ * This function follows the same rules as ieee80211_beacon_get_template() -++ * but allocates and returns a pointer to list of all beacon templates required -++ * to cover all profiles in the multiple BSSID set. Each template includes only -++ * one multiple BSSID element. -++ * -++ * Driver must call ieee80211_beacon_free_ema_list() to free the memory. -++ * -++ * Return: EMA beacon templates of type struct ieee80211_ema_beacons *. -++ * %NULL on error. -++ */ -++struct ieee80211_ema_beacons * -++ieee80211_beacon_get_template_ema_list(struct ieee80211_hw *hw, -++ struct ieee80211_vif *vif, -++ unsigned int link_id); -++ -++/** -++ * ieee80211_beacon_free_ema_list - free an EMA beacon template list -++ * @ema_beacons: list of EMA beacons of type &struct ieee80211_ema_beacons pointers. -++ * -++ * This function will free a list previously acquired by calling -++ * ieee80211_beacon_get_template_ema_list() -++ */ -++void ieee80211_beacon_free_ema_list(struct ieee80211_ema_beacons *ema_beacons); -++ -++/** -+ * ieee80211_beacon_get_tim - beacon generation function -+ * @hw: pointer obtained from ieee80211_alloc_hw(). -+ * @vif: &struct ieee80211_vif pointer from the add_interface callback. -+--- a/net/mac80211/cfg.c -++++ b/net/mac80211/cfg.c -+@@ -1122,11 +1122,11 @@ static int ieee80211_assign_beacon(struc -+ if (params->mbssid_ies) { -+ mbssid = params->mbssid_ies; -+ size += struct_size(new->mbssid_ies, elem, mbssid->cnt); -+- size += ieee80211_get_mbssid_beacon_len(mbssid); -++ size += ieee80211_get_mbssid_beacon_len(mbssid, mbssid->cnt); -+ } else if (old && old->mbssid_ies) { -+ mbssid = old->mbssid_ies; -+ size += struct_size(new->mbssid_ies, elem, mbssid->cnt); -+- size += ieee80211_get_mbssid_beacon_len(mbssid); -++ size += ieee80211_get_mbssid_beacon_len(mbssid, mbssid->cnt); -+ } -+ -+ new = kzalloc(size, GFP_KERNEL); -+@@ -3384,8 +3384,11 @@ cfg80211_beacon_dup(struct cfg80211_beac -+ -+ len = beacon->head_len + beacon->tail_len + beacon->beacon_ies_len + -+ beacon->proberesp_ies_len + beacon->assocresp_ies_len + -+- beacon->probe_resp_len + beacon->lci_len + beacon->civicloc_len + -+- ieee80211_get_mbssid_beacon_len(beacon->mbssid_ies); -++ beacon->probe_resp_len + beacon->lci_len + beacon->civicloc_len; -++ -++ if (beacon->mbssid_ies) -++ len += ieee80211_get_mbssid_beacon_len(beacon->mbssid_ies, -++ beacon->mbssid_ies->cnt); -+ -+ new_beacon = kzalloc(sizeof(*new_beacon) + len, GFP_KERNEL); -+ if (!new_beacon) -+--- a/net/mac80211/ieee80211_i.h -++++ b/net/mac80211/ieee80211_i.h -+@@ -1182,13 +1182,17 @@ ieee80211_vif_get_shift(struct ieee80211 -+ } -+ -+ static inline int -+-ieee80211_get_mbssid_beacon_len(struct cfg80211_mbssid_elems *elems) -++ieee80211_get_mbssid_beacon_len(struct cfg80211_mbssid_elems *elems, u8 i) -+ { -+- int i, len = 0; -++ int len = 0; -+ -+- if (!elems) -++ if (!elems || !elems->cnt || i > elems->cnt) -+ return 0; -+ -++ if (i < elems->cnt) -++ return elems->elem[i].len; -++ -++ /* i == elems->cnt, calculate total length of all MBSSID elements */ -+ for (i = 0; i < elems->cnt; i++) -+ len += elems->elem[i].len; -+ -+--- a/net/mac80211/tx.c -++++ b/net/mac80211/tx.c -+@@ -5205,13 +5205,20 @@ ieee80211_beacon_get_finish(struct ieee8 -+ } -+ -+ static void -+-ieee80211_beacon_add_mbssid(struct sk_buff *skb, struct beacon_data *beacon) -++ieee80211_beacon_add_mbssid(struct sk_buff *skb, struct beacon_data *beacon, -++ u8 i) -+ { -+- int i; -++ if (!beacon->mbssid_ies || !beacon->mbssid_ies->cnt || -++ i > beacon->mbssid_ies->cnt) -++ return; -+ -+- if (!beacon->mbssid_ies) -++ if (i < beacon->mbssid_ies->cnt) { -++ skb_put_data(skb, beacon->mbssid_ies->elem[i].data, -++ beacon->mbssid_ies->elem[i].len); -+ return; -++ } -+ -++ /* i == beacon->mbssid_ies->cnt, include all MBSSID elements */ -+ for (i = 0; i < beacon->mbssid_ies->cnt; i++) -+ skb_put_data(skb, beacon->mbssid_ies->elem[i].data, -+ beacon->mbssid_ies->elem[i].len); -+@@ -5224,7 +5231,8 @@ ieee80211_beacon_get_ap(struct ieee80211 -+ struct ieee80211_mutable_offsets *offs, -+ bool is_template, -+ struct beacon_data *beacon, -+- struct ieee80211_chanctx_conf *chanctx_conf) -++ struct ieee80211_chanctx_conf *chanctx_conf, -++ u8 ema_index) -+ { -+ struct ieee80211_local *local = hw_to_local(hw); -+ struct ieee80211_sub_if_data *sdata = vif_to_sdata(vif); -+@@ -5243,7 +5251,9 @@ ieee80211_beacon_get_ap(struct ieee80211 -+ /* headroom, head length, -+ * tail length, maximum TIM length and multiple BSSID length -+ */ -+- mbssid_len = ieee80211_get_mbssid_beacon_len(beacon->mbssid_ies); -++ mbssid_len = ieee80211_get_mbssid_beacon_len(beacon->mbssid_ies, -++ ema_index); -++ -+ skb = dev_alloc_skb(local->tx_headroom + beacon->head_len + -+ beacon->tail_len + 256 + -+ local->hw.extra_beacon_tailroom + mbssid_len); -+@@ -5261,7 +5271,7 @@ ieee80211_beacon_get_ap(struct ieee80211 -+ offs->cntdwn_counter_offs[0] = beacon->cntdwn_counter_offsets[0]; -+ -+ if (mbssid_len) { -+- ieee80211_beacon_add_mbssid(skb, beacon); -++ ieee80211_beacon_add_mbssid(skb, beacon, ema_index); -+ offs->mbssid_off = skb->len - mbssid_len; -+ } -+ -+@@ -5280,12 +5290,51 @@ ieee80211_beacon_get_ap(struct ieee80211 -+ return skb; -+ } -+ -++static struct ieee80211_ema_beacons * -++ieee80211_beacon_get_ap_ema_list(struct ieee80211_hw *hw, -++ struct ieee80211_vif *vif, -++ struct ieee80211_link_data *link, -++ struct ieee80211_mutable_offsets *offs, -++ bool is_template, struct beacon_data *beacon, -++ struct ieee80211_chanctx_conf *chanctx_conf) -++{ -++ struct ieee80211_ema_beacons *ema = NULL; -++ -++ if (!beacon->mbssid_ies || !beacon->mbssid_ies->cnt) -++ return NULL; -++ -++ ema = kzalloc(struct_size(ema, bcn, beacon->mbssid_ies->cnt), -++ GFP_ATOMIC); -++ if (!ema) -++ return NULL; -++ -++ for (ema->cnt = 0; ema->cnt < beacon->mbssid_ies->cnt; ema->cnt++) { -++ ema->bcn[ema->cnt].skb = -++ ieee80211_beacon_get_ap(hw, vif, link, -++ &ema->bcn[ema->cnt].offs, -++ is_template, beacon, -++ chanctx_conf, ema->cnt); -++ if (!ema->bcn[ema->cnt].skb) -++ break; -++ } -++ -++ if (ema->cnt == beacon->mbssid_ies->cnt) -++ return ema; -++ -++ ieee80211_beacon_free_ema_list(ema); -++ return NULL; -++} -++ -++#define IEEE80211_INCLUDE_ALL_MBSSID_ELEMS -1 -++ -+ static struct sk_buff * -+ __ieee80211_beacon_get(struct ieee80211_hw *hw, -+ struct ieee80211_vif *vif, -+ struct ieee80211_mutable_offsets *offs, -+ bool is_template, -+- unsigned int link_id) -++ unsigned int link_id, -++ int ema_index, -++ struct ieee80211_ema_beacons **ema_beacons) -+ { -+ struct ieee80211_local *local = hw_to_local(hw); -+ struct beacon_data *beacon = NULL; -+@@ -5314,8 +5363,29 @@ __ieee80211_beacon_get(struct ieee80211_ -+ if (!beacon) -+ goto out; -+ -+- skb = ieee80211_beacon_get_ap(hw, vif, link, offs, is_template, -+- beacon, chanctx_conf); -++ if (ema_beacons) { -++ *ema_beacons = -++ ieee80211_beacon_get_ap_ema_list(hw, vif, link, -++ offs, -++ is_template, -++ beacon, -++ chanctx_conf); -++ } else { -++ if (beacon->mbssid_ies && beacon->mbssid_ies->cnt) { -++ if (ema_index >= beacon->mbssid_ies->cnt) -++ goto out; /* End of MBSSID elements */ -++ -++ if (ema_index <= IEEE80211_INCLUDE_ALL_MBSSID_ELEMS) -++ ema_index = beacon->mbssid_ies->cnt; -++ } else { -++ ema_index = 0; -++ } -++ -++ skb = ieee80211_beacon_get_ap(hw, vif, link, offs, -++ is_template, beacon, -++ chanctx_conf, -++ ema_index); -++ } -+ } else if (sdata->vif.type == NL80211_IFTYPE_ADHOC) { -+ struct ieee80211_if_ibss *ifibss = &sdata->u.ibss; -+ struct ieee80211_hdr *hdr; -+@@ -5403,10 +5473,50 @@ ieee80211_beacon_get_template(struct iee -+ struct ieee80211_mutable_offsets *offs, -+ unsigned int link_id) -+ { -+- return __ieee80211_beacon_get(hw, vif, offs, true, link_id); -++ return __ieee80211_beacon_get(hw, vif, offs, true, link_id, -++ IEEE80211_INCLUDE_ALL_MBSSID_ELEMS, NULL); -+ } -+ EXPORT_SYMBOL(ieee80211_beacon_get_template); -+ -++struct sk_buff * -++ieee80211_beacon_get_template_ema_index(struct ieee80211_hw *hw, -++ struct ieee80211_vif *vif, -++ struct ieee80211_mutable_offsets *offs, -++ unsigned int link_id, u8 ema_index) -++{ -++ return __ieee80211_beacon_get(hw, vif, offs, true, link_id, ema_index, -++ NULL); -++} -++EXPORT_SYMBOL(ieee80211_beacon_get_template_ema_index); -++ -++void ieee80211_beacon_free_ema_list(struct ieee80211_ema_beacons *ema_beacons) -++{ -++ u8 i; -++ -++ if (!ema_beacons) -++ return; -++ -++ for (i = 0; i < ema_beacons->cnt; i++) -++ kfree_skb(ema_beacons->bcn[i].skb); -++ -++ kfree(ema_beacons); -++} -++EXPORT_SYMBOL(ieee80211_beacon_free_ema_list); -++ -++struct ieee80211_ema_beacons * -++ieee80211_beacon_get_template_ema_list(struct ieee80211_hw *hw, -++ struct ieee80211_vif *vif, -++ unsigned int link_id) -++{ -++ struct ieee80211_ema_beacons *ema_beacons = NULL; -++ -++ WARN_ON(__ieee80211_beacon_get(hw, vif, NULL, false, link_id, 0, -++ &ema_beacons)); -++ -++ return ema_beacons; -++} -++EXPORT_SYMBOL(ieee80211_beacon_get_template_ema_list); -++ -+ struct sk_buff *ieee80211_beacon_get_tim(struct ieee80211_hw *hw, -+ struct ieee80211_vif *vif, -+ u16 *tim_offset, u16 *tim_length, -+@@ -5414,7 +5524,9 @@ struct sk_buff *ieee80211_beacon_get_tim -+ { -+ struct ieee80211_mutable_offsets offs = {}; -+ struct sk_buff *bcn = __ieee80211_beacon_get(hw, vif, &offs, false, -+- link_id); -++ link_id, -++ IEEE80211_INCLUDE_ALL_MBSSID_ELEMS, -++ NULL); -+ struct sk_buff *copy; -+ int shift; -+ -diff --git a/package/kernel/mac80211/patches/subsys/337-mac80211-fix-sband-iftype-data-lookup-for-AP_VLAN.patch b/package/kernel/mac80211/patches/subsys/337-mac80211-fix-sband-iftype-data-lookup-for-AP_VLAN.patch -new file mode 100644 -index 0000000000..67b4284949 ---- /dev/null -+++ b/package/kernel/mac80211/patches/subsys/337-mac80211-fix-sband-iftype-data-lookup-for-AP_VLAN.patch -@@ -0,0 +1,23 @@ -+From: Felix Fietkau -+Date: Thu, 22 Jun 2023 18:02:25 +0200 -+Subject: [PATCH] mac80211: fix sband iftype data lookup for AP_VLAN -+ -+AP_VLAN interfaces are virtual, so doesn't really exist as a type for -+capabilities. When passed in as a type, AP is the one that's really intended. -+ -+Fixes: c4cbaf7973a7 ("cfg80211: Add support for HE") -+Signed-off-by: Felix Fietkau -+--- -+ -+--- a/include/net/cfg80211.h -++++ b/include/net/cfg80211.h -+@@ -567,6 +567,9 @@ ieee80211_get_sband_iftype_data(const st -+ if (WARN_ON(iftype >= NL80211_IFTYPE_MAX)) -+ return NULL; -+ -++ if (iftype == NL80211_IFTYPE_AP_VLAN) -++ iftype = NL80211_IFTYPE_AP; -++ -+ for (i = 0; i < sband->n_iftype_data; i++) { -+ const struct ieee80211_sband_iftype_data *data = -+ &sband->iftype_data[i]; -diff --git a/package/kernel/mac80211/patches/subsys/338-mac80211-split-mesh-fast-tx-cache-into-local-proxied.patch b/package/kernel/mac80211/patches/subsys/338-mac80211-split-mesh-fast-tx-cache-into-local-proxied.patch -new file mode 100644 -index 0000000000..f7391a5809 ---- /dev/null -+++ b/package/kernel/mac80211/patches/subsys/338-mac80211-split-mesh-fast-tx-cache-into-local-proxied.patch -@@ -0,0 +1,219 @@ -+From: Felix Fietkau -+Date: Fri, 30 Jun 2023 13:11:51 +0200 -+Subject: [PATCH] mac80211: split mesh fast tx cache into -+ local/proxied/forwarded -+ -+Depending on the origin of the packets (and their SA), 802.11 + mesh headers -+could be filled in differently. In order to properly deal with that, add a -+new field to the lookup key, indicating the type (local, proxied or -+forwarded). This can fix spurious packet drop issues that depend on the order -+in which nodes/hosts communicate with each other. -+ -+Signed-off-by: Felix Fietkau -+--- -+ -+--- a/net/mac80211/mesh.c -++++ b/net/mac80211/mesh.c -+@@ -703,6 +703,9 @@ bool ieee80211_mesh_xmit_fast(struct iee -+ struct sk_buff *skb, u32 ctrl_flags) -+ { -+ struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh; -++ struct ieee80211_mesh_fast_tx_key key = { -++ .type = MESH_FAST_TX_TYPE_LOCAL -++ }; -+ struct ieee80211_mesh_fast_tx *entry; -+ struct ieee80211s_hdr *meshhdr; -+ u8 sa[ETH_ALEN] __aligned(2); -+@@ -738,7 +741,10 @@ bool ieee80211_mesh_xmit_fast(struct iee -+ return false; -+ } -+ -+- entry = mesh_fast_tx_get(sdata, skb->data); -++ ether_addr_copy(key.addr, skb->data); -++ if (!ether_addr_equal(skb->data + ETH_ALEN, sdata->vif.addr)) -++ key.type = MESH_FAST_TX_TYPE_PROXIED; -++ entry = mesh_fast_tx_get(sdata, &key); -+ if (!entry) -+ return false; -+ -+--- a/net/mac80211/mesh.h -++++ b/net/mac80211/mesh.h -+@@ -133,9 +133,33 @@ struct mesh_path { -+ #define MESH_FAST_TX_CACHE_TIMEOUT 8000 /* msecs */ -+ -+ /** -++ * enum ieee80211_mesh_fast_tx_type - cached mesh fast tx entry type -++ * -++ * @MESH_FAST_TX_TYPE_LOCAL: tx from the local vif address as SA -++ * @MESH_FAST_TX_TYPE_PROXIED: local tx with a different SA (e.g. bridged) -++ * @MESH_FAST_TX_TYPE_FORWARDED: forwarded from a different mesh point -++ */ -++enum ieee80211_mesh_fast_tx_type { -++ MESH_FAST_TX_TYPE_LOCAL, -++ MESH_FAST_TX_TYPE_PROXIED, -++ MESH_FAST_TX_TYPE_FORWARDED, -++}; -++ -++/** -++ * struct ieee80211_mesh_fast_tx_key - cached mesh fast tx entry key -++ * -++ * @addr: The Ethernet DA for this entry -++ * @type: cache entry type -++ */ -++struct ieee80211_mesh_fast_tx_key { -++ u8 addr[ETH_ALEN] __aligned(2); -++ enum ieee80211_mesh_fast_tx_type type; -++}; -++ -++/** -+ * struct ieee80211_mesh_fast_tx - cached mesh fast tx entry -+ * @rhash: rhashtable pointer -+- * @addr_key: The Ethernet DA which is the key for this entry -++ * @key: the lookup key for this cache entry -+ * @fast_tx: base fast_tx data -+ * @hdr: cached mesh and rfc1042 headers -+ * @hdrlen: length of mesh + rfc1042 -+@@ -146,7 +170,7 @@ struct mesh_path { -+ */ -+ struct ieee80211_mesh_fast_tx { -+ struct rhash_head rhash; -+- u8 addr_key[ETH_ALEN] __aligned(2); -++ struct ieee80211_mesh_fast_tx_key key; -+ -+ struct ieee80211_fast_tx fast_tx; -+ u8 hdr[sizeof(struct ieee80211s_hdr) + sizeof(rfc1042_header)]; -+@@ -329,7 +353,8 @@ void mesh_path_tx_root_frame(struct ieee -+ -+ bool mesh_action_is_path_sel(struct ieee80211_mgmt *mgmt); -+ struct ieee80211_mesh_fast_tx * -+-mesh_fast_tx_get(struct ieee80211_sub_if_data *sdata, const u8 *addr); -++mesh_fast_tx_get(struct ieee80211_sub_if_data *sdata, -++ struct ieee80211_mesh_fast_tx_key *key); -+ bool ieee80211_mesh_xmit_fast(struct ieee80211_sub_if_data *sdata, -+ struct sk_buff *skb, u32 ctrl_flags); -+ void mesh_fast_tx_cache(struct ieee80211_sub_if_data *sdata, -+--- a/net/mac80211/mesh_pathtbl.c -++++ b/net/mac80211/mesh_pathtbl.c -+@@ -36,8 +36,8 @@ static const struct rhashtable_params me -+ static const struct rhashtable_params fast_tx_rht_params = { -+ .nelem_hint = 10, -+ .automatic_shrinking = true, -+- .key_len = ETH_ALEN, -+- .key_offset = offsetof(struct ieee80211_mesh_fast_tx, addr_key), -++ .key_len = sizeof(struct ieee80211_mesh_fast_tx_key), -++ .key_offset = offsetof(struct ieee80211_mesh_fast_tx, key), -+ .head_offset = offsetof(struct ieee80211_mesh_fast_tx, rhash), -+ .hashfn = mesh_table_hash, -+ }; -+@@ -426,20 +426,21 @@ static void mesh_fast_tx_entry_free(stru -+ } -+ -+ struct ieee80211_mesh_fast_tx * -+-mesh_fast_tx_get(struct ieee80211_sub_if_data *sdata, const u8 *addr) -++mesh_fast_tx_get(struct ieee80211_sub_if_data *sdata, -++ struct ieee80211_mesh_fast_tx_key *key) -+ { -+ struct ieee80211_mesh_fast_tx *entry; -+ struct mesh_tx_cache *cache; -+ -+ cache = &sdata->u.mesh.tx_cache; -+- entry = rhashtable_lookup(&cache->rht, addr, fast_tx_rht_params); -++ entry = rhashtable_lookup(&cache->rht, key, fast_tx_rht_params); -+ if (!entry) -+ return NULL; -+ -+ if (!(entry->mpath->flags & MESH_PATH_ACTIVE) || -+ mpath_expired(entry->mpath)) { -+ spin_lock_bh(&cache->walk_lock); -+- entry = rhashtable_lookup(&cache->rht, addr, fast_tx_rht_params); -++ entry = rhashtable_lookup(&cache->rht, key, fast_tx_rht_params); -+ if (entry) -+ mesh_fast_tx_entry_free(cache, entry); -+ spin_unlock_bh(&cache->walk_lock); -+@@ -484,18 +485,24 @@ void mesh_fast_tx_cache(struct ieee80211 -+ if (!sta) -+ return; -+ -++ build.key.type = MESH_FAST_TX_TYPE_LOCAL; -+ if ((meshhdr->flags & MESH_FLAGS_AE) == MESH_FLAGS_AE_A5_A6) { -+ /* This is required to keep the mppath alive */ -+ mppath = mpp_path_lookup(sdata, meshhdr->eaddr1); -+ if (!mppath) -+ return; -+ build.mppath = mppath; -++ if (!ether_addr_equal(meshhdr->eaddr2, sdata->vif.addr)) -++ build.key.type = MESH_FAST_TX_TYPE_PROXIED; -+ } else if (ieee80211_has_a4(hdr->frame_control)) { -+ mppath = mpath; -+ } else { -+ return; -+ } -+ -++ if (!ether_addr_equal(hdr->addr4, sdata->vif.addr)) -++ build.key.type = MESH_FAST_TX_TYPE_FORWARDED; -++ -+ /* rate limit, in case fast xmit can't be enabled */ -+ if (mppath->fast_tx_check == jiffies) -+ return; -+@@ -542,7 +549,7 @@ void mesh_fast_tx_cache(struct ieee80211 -+ } -+ } -+ -+- memcpy(build.addr_key, mppath->dst, ETH_ALEN); -++ memcpy(build.key.addr, mppath->dst, ETH_ALEN); -+ build.timestamp = jiffies; -+ build.fast_tx.band = info->band; -+ build.fast_tx.da_offs = offsetof(struct ieee80211_hdr, addr3); -+@@ -644,13 +651,19 @@ void mesh_fast_tx_flush_addr(struct ieee -+ const u8 *addr) -+ { -+ struct mesh_tx_cache *cache = &sdata->u.mesh.tx_cache; -++ struct ieee80211_mesh_fast_tx_key key = {}; -+ struct ieee80211_mesh_fast_tx *entry; -++ int i; -+ -++ ether_addr_copy(key.addr, addr); -+ cache = &sdata->u.mesh.tx_cache; -+ spin_lock_bh(&cache->walk_lock); -+- entry = rhashtable_lookup(&cache->rht, addr, fast_tx_rht_params); -+- if (entry) -+- mesh_fast_tx_entry_free(cache, entry); -++ for (i = MESH_FAST_TX_TYPE_LOCAL; i < MESH_FAST_TX_TYPE_FORWARDED; i++) { -++ key.type = i; -++ entry = rhashtable_lookup(&cache->rht, &key, fast_tx_rht_params); -++ if (entry) -++ mesh_fast_tx_entry_free(cache, entry); -++ } -+ spin_unlock_bh(&cache->walk_lock); -+ } -+ -+--- a/net/mac80211/rx.c -++++ b/net/mac80211/rx.c -+@@ -2726,7 +2726,10 @@ ieee80211_rx_mesh_fast_forward(struct ie -+ struct sk_buff *skb, int hdrlen) -+ { -+ struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh; -+- struct ieee80211_mesh_fast_tx *entry = NULL; -++ struct ieee80211_mesh_fast_tx_key key = { -++ .type = MESH_FAST_TX_TYPE_FORWARDED -++ }; -++ struct ieee80211_mesh_fast_tx *entry; -+ struct ieee80211s_hdr *mesh_hdr; -+ struct tid_ampdu_tx *tid_tx; -+ struct sta_info *sta; -+@@ -2735,9 +2738,13 @@ ieee80211_rx_mesh_fast_forward(struct ie -+ -+ mesh_hdr = (struct ieee80211s_hdr *)(skb->data + sizeof(eth)); -+ if ((mesh_hdr->flags & MESH_FLAGS_AE) == MESH_FLAGS_AE_A5_A6) -+- entry = mesh_fast_tx_get(sdata, mesh_hdr->eaddr1); -++ ether_addr_copy(key.addr, mesh_hdr->eaddr1); -+ else if (!(mesh_hdr->flags & MESH_FLAGS_AE)) -+- entry = mesh_fast_tx_get(sdata, skb->data); -++ ether_addr_copy(key.addr, skb->data); -++ else -++ return false; -++ -++ entry = mesh_fast_tx_get(sdata, &key); -+ if (!entry) -+ return false; -+ -diff --git a/package/kernel/mac80211/patches/subsys/339-wifi-cfg80211-fix-receving-mesh-packets-without-RFC1.patch b/package/kernel/mac80211/patches/subsys/339-wifi-cfg80211-fix-receving-mesh-packets-without-RFC1.patch -new file mode 100644 -index 0000000000..e32c6ae1f3 ---- /dev/null -+++ b/package/kernel/mac80211/patches/subsys/339-wifi-cfg80211-fix-receving-mesh-packets-without-RFC1.patch -@@ -0,0 +1,25 @@ -+From: Felix Fietkau -+Date: Tue, 11 Jul 2023 13:30:12 +0200 -+Subject: [PATCH] wifi: cfg80211: fix receving mesh packets without RFC1042 -+ header -+ -+Fix ethernet header length field after stripping the mesh header -+ -+Cc: stable@vger.kernel.org -+Link: https://lore.kernel.org/all/CT5GNZSK28AI.2K6M69OXM9RW5@syracuse/ -+Fixes: 986e43b19ae9 ("wifi: mac80211: fix receiving A-MSDU frames on mesh interfaces") -+Reported-by: Nicolas Escande -+Signed-off-by: Felix Fietkau -+--- -+ -+--- a/net/wireless/util.c -++++ b/net/wireless/util.c -+@@ -580,6 +580,8 @@ int ieee80211_strip_8023_mesh_hdr(struct -+ hdrlen += ETH_ALEN + 2; -+ else if (!pskb_may_pull(skb, hdrlen)) -+ return -EINVAL; -++ else -++ payload.eth.h_proto = htons(skb->len - hdrlen); -+ -+ mesh_addr = skb->data + sizeof(payload.eth) + ETH_ALEN; -+ switch (payload.flags & MESH_FLAGS_AE) { -diff --git a/package/kernel/mac80211/patches/subsys/400-allow-ibss-mixed.patch b/package/kernel/mac80211/patches/subsys/400-allow-ibss-mixed.patch -new file mode 100644 -index 0000000000..c38fa13f03 ---- /dev/null -+++ b/package/kernel/mac80211/patches/subsys/400-allow-ibss-mixed.patch -@@ -0,0 +1,40 @@ -+From: Hauke Mehrtens -+Date: Mon, 24 Feb 2020 00:00:00 +0100 -+Subject: [PATCH] mac80211: Allow IBSS mode and different beacon intervals -+ -+ath10k-ct supports the combination to select IBSS (ADHOC) mode and -+different beacon intervals together. mac80211 does not like this -+combination, but Ben says this is ok, so remove this check. -+ -+ath10k-ct starting with version 5.2 allows the combination of -+NL80211_IFTYPE_ADHOC and beacon_int_min_gcd in ath10k_10x_ct_if_comb -+which triggers this warning. Ben told me that this is not a big problem -+and we should ignore this. -+--- -+ net/wireless/core.c | 15 --------------- -+ 1 file changed, 15 deletions(-) -+ -+--- a/net/wireless/core.c -++++ b/net/wireless/core.c -+@@ -614,21 +614,6 @@ static int wiphy_verify_combinations(str -+ c->limits[j].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) && -+- c->beacon_int_min_gcd)) { -+- return -EINVAL; -+- } -+- -+ cnt += c->limits[j].max; -+ /* -+ * Don't advertise an unsupported type -diff --git a/package/kernel/mac80211/patches/subsys/782-net-next-1-of-net-pass-the-dst-buffer-to-of_get_mac_address.patch b/package/kernel/mac80211/patches/subsys/782-net-next-1-of-net-pass-the-dst-buffer-to-of_get_mac_address.patch -new file mode 100644 -index 0000000000..26af6a2fb9 ---- /dev/null -+++ b/package/kernel/mac80211/patches/subsys/782-net-next-1-of-net-pass-the-dst-buffer-to-of_get_mac_address.patch -@@ -0,0 +1,29 @@ -+--- a/backport-include/linux/of_net.h -++++ /dev/null -+@@ -1,26 +0,0 @@ -+-#ifndef _BP_OF_NET_H -+-#define _BP_OF_NET_H -+-#include_next -+-#include -+-#include -+- -+-/* The behavior of of_get_mac_address() changed in kernel 5.2, it now -+- * returns an error code and not NULL in case of an error. -+- */ -+-#if LINUX_VERSION_IS_LESS(5,13,0) -+-static inline int backport_of_get_mac_address(struct device_node *np, u8 *mac_out) -+-{ -+- const void *mac = of_get_mac_address(np); -+- -+- if (!mac) -+- return -ENODEV; -+- if (IS_ERR(mac)) -+- return PTR_ERR(mac); -+- ether_addr_copy(mac_out, mac); -+- -+- return 0; -+-} -+-#define of_get_mac_address LINUX_BACKPORT(of_get_mac_address) -+-#endif /* < 5.2 */ -+- -+-#endif /* _BP_OF_NET_H */ -diff --git a/package/kernel/mac80211/ralink.mk b/package/kernel/mac80211/ralink.mk -new file mode 100644 -index 0000000000..83d208ee1a ---- /dev/null -+++ b/package/kernel/mac80211/ralink.mk -@@ -0,0 +1,131 @@ -+PKG_DRIVERS += \ -+ rt2x00-lib rt2x00-pci rt2x00-usb rt2x00-mmio \ -+ rt2800-lib rt2800-mmio rt2800-pci rt2800-soc rt2800-usb -+ -+PKG_CONFIG_DEPENDS += \ -+ CONFIG_PACKAGE_RT2X00_LIB_DEBUGFS \ -+ CONFIG_PACKAGE_RT2X00_DEBUG -+ -+config-$(call config_package,rt2x00-lib) += RT2X00 RT2X00_LIB -+config-$(call config_package,rt2x00-pci) += RT2X00_LIB_PCI -+config-$(call config_package,rt2x00-mmio) += RT2X00_LIB_MMIO -+config-$(call config_package,rt2x00-usb) += RT2X00_LIB_USB -+config-$(CONFIG_PACKAGE_RT2X00_LIB_DEBUGFS) += RT2X00_LIB_DEBUGFS -+config-$(CONFIG_PACKAGE_RT2X00_DEBUG) += RT2X00_DEBUG -+ -+config-$(call config_package,rt2400-pci) += RT2400PCI -+config-$(call config_package,rt2500-pci) += RT2500PCI -+config-$(call config_package,rt2500-usb) += RT2500USB -+config-$(call config_package,rt61-pci) += RT61PCI -+config-$(call config_package,rt73-usb) += RT73USB -+ -+config-$(call config_package,rt2800-lib) += RT2800_LIB -+ -+config-$(call config_package,rt2800-soc) += RT2800SOC -+config-$(call config_package,rt2800-pci) += RT2800PCI -+config-y += RT2800PCI_RT33XX RT2800PCI_RT35XX RT2800PCI_RT53XX RT2800PCI_RT3290 -+ -+config-$(call config_package,rt2800-usb) += RT2800USB -+config-y += RT2800USB_RT33XX RT2800USB_RT35XX RT2800USB_RT3573 RT2800USB_RT53XX RT2800USB_RT55XX RT2800USB_UNKNOWN -+ -+define KernelPackage/rt2x00/Default -+ $(call KernelPackage/mac80211/Default) -+ TITLE:=Ralink Drivers for RT2x00 cards -+endef -+ -+define KernelPackage/rt2x00-lib -+$(call KernelPackage/rt2x00/Default) -+ DEPENDS+= @(PCI_SUPPORT||USB_SUPPORT||TARGET_ramips) +kmod-mac80211 -+ TITLE+= (LIB) -+ FILES:=$(PKG_BUILD_DIR)/drivers/net/wireless/ralink/rt2x00/rt2x00lib.ko -+ MENU:=1 -+endef -+ -+define KernelPackage/rt2x00-lib/config -+ if PACKAGE_kmod-rt2x00-lib -+ -+ config PACKAGE_RT2X00_LIB_DEBUGFS -+ bool "Enable rt2x00 debugfs support" -+ depends on PACKAGE_MAC80211_DEBUGFS -+ help -+ Enable creation of debugfs files for the rt2x00 drivers. -+ These debugfs files support both reading and writing of the -+ most important register types of the rt2x00 hardware. -+ -+ config PACKAGE_RT2X00_DEBUG -+ bool "Enable rt2x00 debug output" -+ help -+ Enable debugging output for all rt2x00 modules -+ -+ endif -+endef -+ -+define KernelPackage/rt2x00-mmio -+$(call KernelPackage/rt2x00/Default) -+ DEPENDS+= @(PCI_SUPPORT||TARGET_ramips) +kmod-rt2x00-lib -+ HIDDEN:=1 -+ TITLE+= (MMIO) -+ FILES:= $(PKG_BUILD_DIR)/drivers/net/wireless/ralink/rt2x00/rt2x00mmio.ko -+endef -+ -+define KernelPackage/rt2x00-pci -+$(call KernelPackage/rt2x00/Default) -+ DEPENDS+= @PCI_SUPPORT +kmod-rt2x00-mmio +kmod-rt2x00-lib -+ HIDDEN:=1 -+ TITLE+= (PCI) -+ FILES:= $(PKG_BUILD_DIR)/drivers/net/wireless/ralink/rt2x00/rt2x00pci.ko -+ AUTOLOAD:=$(call AutoProbe,rt2x00pci) -+endef -+ -+define KernelPackage/rt2x00-usb -+$(call KernelPackage/rt2x00/Default) -+ DEPENDS+= @USB_SUPPORT +kmod-rt2x00-lib +kmod-usb-core -+ HIDDEN:=1 -+ TITLE+= (USB) -+ FILES:=$(PKG_BUILD_DIR)/drivers/net/wireless/ralink/rt2x00/rt2x00usb.ko -+ AUTOLOAD:=$(call AutoProbe,rt2x00usb) -+endef -+ -+define KernelPackage/rt2800-lib -+$(call KernelPackage/rt2x00/Default) -+ DEPENDS+= @(PCI_SUPPORT||USB_SUPPORT||TARGET_ramips) +kmod-rt2x00-lib +kmod-lib-crc-ccitt -+ HIDDEN:=1 -+ TITLE+= (rt2800 LIB) -+ FILES:=$(PKG_BUILD_DIR)/drivers/net/wireless/ralink/rt2x00/rt2800lib.ko -+endef -+ -+define KernelPackage/rt2800-mmio -+$(call KernelPackage/rt2x00/Default) -+ TITLE += (RT28xx/RT3xxx MMIO) -+ DEPENDS += +kmod-rt2800-lib +kmod-rt2x00-mmio -+ HIDDEN:=1 -+ FILES:=$(PKG_BUILD_DIR)/drivers/net/wireless/ralink/rt2x00/rt2800mmio.ko -+endef -+ -+define KernelPackage/rt2800-soc -+$(call KernelPackage/rt2x00/Default) -+ DEPENDS += @(TARGET_ramips_rt288x||TARGET_ramips_rt305x||TARGET_ramips_rt3883||TARGET_ramips_mt7620) +kmod-rt2800-mmio +kmod-rt2800-lib -+ TITLE += (RT28xx/RT3xxx SoC) -+ FILES := \ -+ $(PKG_BUILD_DIR)/drivers/net/wireless/ralink/rt2x00/rt2x00soc.ko \ -+ $(PKG_BUILD_DIR)/drivers/net/wireless/ralink/rt2x00/rt2800soc.ko -+ AUTOLOAD:=$(call AutoProbe,rt2800soc) -+endef -+ -+define KernelPackage/rt2800-pci -+$(call KernelPackage/rt2x00/Default) -+ DEPENDS+= @PCI_SUPPORT +kmod-rt2x00-pci +kmod-rt2800-lib +kmod-rt2800-mmio +kmod-eeprom-93cx6 +rt2800-pci-firmware -+ TITLE+= (RT2860 PCI) -+ FILES:=$(PKG_BUILD_DIR)/drivers/net/wireless/ralink/rt2x00/rt2800pci.ko -+ AUTOLOAD:=$(call AutoProbe,rt2800pci) -+endef -+ -+define KernelPackage/rt2800-usb -+$(call KernelPackage/rt2x00/Default) -+ DEPENDS+= @USB_SUPPORT +kmod-rt2x00-usb +kmod-rt2800-lib +kmod-lib-crc-ccitt +rt2800-usb-firmware -+ TITLE+= (RT2870 USB) -+ FILES:=$(PKG_BUILD_DIR)/drivers/net/wireless/ralink/rt2x00/rt2800usb.ko -+ AUTOLOAD:=$(call AutoProbe,rt2800usb) -+endef -+ -+ -diff --git a/package/kernel/mac80211/realtek.mk b/package/kernel/mac80211/realtek.mk -new file mode 100644 -index 0000000000..9c14358326 ---- /dev/null -+++ b/package/kernel/mac80211/realtek.mk -@@ -0,0 +1,197 @@ -+PKG_DRIVERS += \ -+ rtlwifi rtlwifi-pci rtlwifi-btcoexist rtlwifi-usb rtl8192c-common \ -+ rtl8192ce rtl8192se rtl8192de rtl8192cu rtl8723bs rtl8821ae \ -+ rtl8xxxu rtw88 -+ -+config-$(call config_package,rtlwifi) += RTL_CARDS RTLWIFI -+config-$(call config_package,rtlwifi-pci) += RTLWIFI_PCI -+config-$(call config_package,rtlwifi-btcoexist) += RTLBTCOEXIST -+config-$(call config_package,rtlwifi-usb) += RTLWIFI_USB -+config-$(call config_package,rtl8192c-common) += RTL8192C_COMMON -+config-$(call config_package,rtl8192ce) += RTL8192CE -+config-$(call config_package,rtl8192se) += RTL8192SE -+config-$(call config_package,rtl8192de) += RTL8192DE -+config-$(call config_package,rtl8192cu) += RTL8192CU -+config-$(call config_package,rtl8821ae) += RTL8821AE -+config-$(CONFIG_PACKAGE_RTLWIFI_DEBUG) += RTLWIFI_DEBUG -+ -+config-$(call config_package,rtl8xxxu) += RTL8XXXU -+config-y += RTL8XXXU_UNTESTED -+ -+config-$(call config_package,rtl8723bs) += RTL8723BS -+config-y += STAGING -+ -+config-$(call config_package,rtw88) += RTW88 RTW88_CORE RTW88_PCI -+config-y += RTW88_8822BE RTW88_8822CE RTW88_8723DE -+config-$(CONFIG_PACKAGE_RTW88_DEBUG) += RTW88_DEBUG -+config-$(CONFIG_PACKAGE_RTW88_DEBUGFS) += RTW88_DEBUGFS -+ -+define KernelPackage/rtlwifi/config -+ config PACKAGE_RTLWIFI_DEBUG -+ bool "Realtek wireless debugging" -+ depends on PACKAGE_kmod-rtlwifi -+ help -+ Say Y, if you want to debug realtek wireless drivers. -+ -+endef -+ -+define KernelPackage/rtlwifi -+ $(call KernelPackage/mac80211/Default) -+ TITLE:=Realtek common driver part -+ DEPENDS+= @(PCI_SUPPORT||USB_SUPPORT) +kmod-mac80211 -+ FILES:=$(PKG_BUILD_DIR)/drivers/net/wireless/realtek/rtlwifi/rtlwifi.ko -+ HIDDEN:=1 -+endef -+ -+define KernelPackage/rtlwifi-pci -+ $(call KernelPackage/mac80211/Default) -+ TITLE:=Realtek common driver part (PCI support) -+ DEPENDS+= @PCI_SUPPORT +kmod-rtlwifi -+ FILES:=$(PKG_BUILD_DIR)/drivers/net/wireless/realtek/rtlwifi/rtl_pci.ko -+ AUTOLOAD:=$(call AutoProbe,rtl_pci) -+ HIDDEN:=1 -+endef -+ -+define KernelPackage/rtlwifi-btcoexist -+ $(call KernelPackage/mac80211/Default) -+ TITLE:=Realtek BT coexist support -+ DEPENDS+= +kmod-rtlwifi -+ FILES:=$(PKG_BUILD_DIR)/drivers/net/wireless/realtek/rtlwifi/btcoexist/btcoexist.ko -+ AUTOLOAD:=$(call AutoProbe,btcoexist) -+ HIDDEN:=1 -+endef -+ -+define KernelPackage/rtlwifi-usb -+ $(call KernelPackage/mac80211/Default) -+ TITLE:=Realtek common driver part (USB support) -+ DEPENDS+= @USB_SUPPORT +kmod-usb-core +kmod-rtlwifi -+ FILES:=$(PKG_BUILD_DIR)/drivers/net/wireless/realtek/rtlwifi/rtl_usb.ko -+ AUTOLOAD:=$(call AutoProbe,rtl_usb) -+ HIDDEN:=1 -+endef -+ -+define KernelPackage/rtl8192c-common -+ $(call KernelPackage/mac80211/Default) -+ TITLE:=Realtek RTL8192CE/RTL8192CU common support module -+ DEPENDS+= +kmod-rtlwifi -+ FILES:= $(PKG_BUILD_DIR)/drivers/net/wireless/realtek/rtlwifi/rtl8192c/rtl8192c-common.ko -+ HIDDEN:=1 -+endef -+ -+define KernelPackage/rtl8192ce -+ $(call KernelPackage/mac80211/Default) -+ TITLE:=Realtek RTL8192CE/RTL8188CE support -+ DEPENDS+= +kmod-rtlwifi-pci +kmod-rtl8192c-common +rtl8192ce-firmware -+ FILES:= $(PKG_BUILD_DIR)/drivers/net/wireless/realtek/rtlwifi/rtl8192ce/rtl8192ce.ko -+ AUTOLOAD:=$(call AutoProbe,rtl8192ce) -+endef -+ -+define KernelPackage/rtl8192se -+ $(call KernelPackage/mac80211/Default) -+ TITLE:=Realtek RTL8192SE/RTL8191SE support -+ DEPENDS+= +kmod-rtlwifi-pci +rtl8192se-firmware -+ FILES:=$(PKG_BUILD_DIR)/drivers/net/wireless/realtek/rtlwifi/rtl8192se/rtl8192se.ko -+ AUTOLOAD:=$(call AutoProbe,rtl8192se) -+endef -+ -+define KernelPackage/rtl8192de -+ $(call KernelPackage/mac80211/Default) -+ TITLE:=Realtek RTL8192DE/RTL8188DE support -+ DEPENDS+= +kmod-rtlwifi-pci +rtl8192de-firmware -+ FILES:= $(PKG_BUILD_DIR)/drivers/net/wireless/realtek/rtlwifi/rtl8192de/rtl8192de.ko -+ AUTOLOAD:=$(call AutoProbe,rtl8192de) -+endef -+ -+define KernelPackage/rtl8192cu -+ $(call KernelPackage/mac80211/Default) -+ TITLE:=Realtek RTL8192CU/RTL8188CU support -+ DEPENDS+= +kmod-rtlwifi-usb +kmod-rtl8192c-common +rtl8192cu-firmware -+ FILES:= $(PKG_BUILD_DIR)/drivers/net/wireless/realtek/rtlwifi/rtl8192cu/rtl8192cu.ko -+ AUTOLOAD:=$(call AutoProbe,rtl8192cu) -+endef -+ -+define KernelPackage/rtl8821ae -+ $(call KernelPackage/mac80211/Default) -+ TITLE:=Realtek RTL8821AE support -+ DEPENDS+= +kmod-rtlwifi-btcoexist +kmod-rtlwifi-pci +rtl8821ae-firmware -+ FILES:= $(PKG_BUILD_DIR)/drivers/net/wireless/realtek/rtlwifi/rtl8821ae/rtl8821ae.ko -+ AUTOLOAD:=$(call AutoProbe,rtl8821ae) -+endef -+ -+define KernelPackage/rtl8xxxu -+ $(call KernelPackage/mac80211/Default) -+ TITLE:=alternative Realtek RTL8XXXU support -+ DEPENDS+= @USB_SUPPORT +kmod-usb-core +kmod-mac80211 -+ FILES:= $(PKG_BUILD_DIR)/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu.ko -+ AUTOLOAD:=$(call AutoProbe,rtl8xxxu) -+endef -+ -+define KernelPackage/rtl8xxxu/description -+ This is an alternative driver for various Realtek RTL8XXX -+ parts written to utilize the Linux mac80211 stack. -+ The driver is known to work with a number of RTL8723AU, -+ RL8188CU, RTL8188RU, RTL8191CU, and RTL8192CU devices -+ -+ This driver is under development and has a limited feature -+ set. In particular it does not yet support 40MHz channels -+ and power management. However it should have a smaller -+ memory footprint than the vendor drivers and benetifs -+ from the in kernel mac80211 stack. -+ -+ It can coexist with drivers from drivers/staging/rtl8723au, -+ drivers/staging/rtl8192u, and drivers/net/wireless/rtlwifi, -+ but you will need to control which module you wish to load. -+ -+ RTL8XXXU_UNTESTED is enabled -+ This option enables detection of Realtek 8723/8188/8191/8192 WiFi -+ USB devices which have not been tested directly by the driver -+ author or reported to be working by third parties. -+ -+ Please report your results! -+endef -+ -+define KernelPackage/rtw88/config -+ config PACKAGE_RTW88_DEBUG -+ bool "Realtek wireless debugging (rtw88)" -+ depends on PACKAGE_kmod-rtw88 -+ help -+ Enable debugging output for rtw88 devices -+ -+ config PACKAGE_RTW88_DEBUGFS -+ bool "Enable rtw88 debugfS support" -+ select KERNEL_DEBUG_FS -+ depends on PACKAGE_kmod-rtw88 -+ help -+ Select this to see extensive information about -+ the internal state of rtw88 in debugfs. -+endef -+ -+define KernelPackage/rtw88 -+ $(call KernelPackage/mac80211/Default) -+ TITLE:=Realtek RTL8822BE/RTL8822CE/RTL8723DE -+ DEPENDS+= @(PCI_SUPPORT) +kmod-mac80211 +@DRIVER_11AC_SUPPORT -+ FILES:=\ -+ $(PKG_BUILD_DIR)/drivers/net/wireless/realtek/rtw88/rtw88_8822be.ko \ -+ $(PKG_BUILD_DIR)/drivers/net/wireless/realtek/rtw88/rtw88_8822b.ko \ -+ $(PKG_BUILD_DIR)/drivers/net/wireless/realtek/rtw88/rtw88_8822ce.ko \ -+ $(PKG_BUILD_DIR)/drivers/net/wireless/realtek/rtw88/rtw88_8822c.ko \ -+ $(PKG_BUILD_DIR)/drivers/net/wireless/realtek/rtw88/rtw88_8723de.ko \ -+ $(PKG_BUILD_DIR)/drivers/net/wireless/realtek/rtw88/rtw88_8723d.ko \ -+ $(PKG_BUILD_DIR)/drivers/net/wireless/realtek/rtw88/rtw88_core.ko \ -+ $(PKG_BUILD_DIR)/drivers/net/wireless/realtek/rtw88/rtw88_pci.ko -+ AUTOLOAD:=$(call AutoProbe,rtw88_8822be rtw88_8822ce rtw88_8723de) -+endef -+ -+define KernelPackage/rtl8723bs -+ $(call KernelPackage/mac80211/Default) -+ TITLE:=Realtek RTL8723BS SDIO Wireless LAN NIC driver (staging) -+ DEPENDS+=+kmod-mmc +kmod-mac80211 -+ FILES:=$(PKG_BUILD_DIR)/drivers/staging/rtl8723bs/r8723bs.ko -+ AUTOLOAD:=$(call AutoProbe,r8723bs) -+endef -+ -+define KernelPackage/rtl8723bs/description -+ This option enables support for RTL8723BS SDIO drivers, such as the wifi found -+ on the 1st gen Intel Compute Stick, the CHIP and many other Intel Atom and ARM -+ based devices. -+endef -diff --git a/package/kernel/mac80211/scripts/import-backports.sh b/package/kernel/mac80211/scripts/import-backports.sh -new file mode 100755 -index 0000000000..35aa411e6c ---- /dev/null -+++ b/package/kernel/mac80211/scripts/import-backports.sh -@@ -0,0 +1,109 @@ -+#!/usr/bin/env bash -+BASE=$1; shift -+ -+usage() { -+ echo "Usage: $0 NNN ..." -+ exit 1 -+} -+ -+check_number() { -+ case "$1" in -+ [0-9][0-9][0-9]) return 0;; -+ esac -+ return 1; -+} -+ -+patch_header() -+{ -+ awk ' -+ /^(---|\*\*\*|Index:)[ \t][^ \t]|^diff -/ \ -+ { exit } -+ { print } -+ ' -+} -+ -+strip_diffstat() -+{ -+ awk ' -+ /#? .* \| / \ -+ { eat = eat $0 "\n" -+ next } -+ /^#? .* files? changed(, .* insertions?\(\+\))?(, .* deletions?\(-\))?/ \ -+ { eat = "" -+ next } -+ { print eat $0 -+ eat = "" } -+ ' -+} -+ -+strip_trailing_whitespace() { -+ sed -e 's:[ '$'\t'']*$::' -+} -+ -+fixup_header() { -+ awk ' -+ /^From / { next } -+ /^Subject: / { -+ sub("Subject: \\[[^\]]*\\]", "Subject: [PATCH]") -+ } -+ { print } -+ ' -+} -+ -+check_number "$BASE" || usage -+ -+quilt series > /dev/null || { -+ echo "Not in quilt directory" -+ exit 2 -+} -+ -+get_next() { -+ NEW=$BASE -+ quilt series | while read CUR; do -+ [ -n "$CUR" ] || break -+ CUR=${CUR%%-*} -+ check_number "$CUR" || continue -+ [ "$CUR" -lt "$NEW" ] && continue -+ [ "$CUR" -ge "$(($BASE + 100))" ] && continue -+ NEW="$(($CUR + 1))" -+ echo $NEW -+ done | tail -n1 -+} -+ -+CUR=$(get_next) -+CUR="${CUR:-$BASE}" -+ -+while [ -n "$1" ]; do -+ FILE="$1"; shift -+ NAME="$(basename $FILE)" -+ NAME="${NAME#[0-9]*-}" -+ echo -n "Processing patch $NAME: " -+ -+ [ -e "$FILE" ] || { -+ echo "file $FILE not found" -+ exit 1 -+ } -+ -+ grep -qE "$NAME$" patches/series && { -+ echo "already applied" -+ continue -+ } -+ -+ quilt new "$CUR-$NAME" || exit 1 -+ patch_header < "$FILE" | -+ strip_diffstat | -+ strip_trailing_whitespace | -+ fixup_header > "patches/$CUR-$NAME" -+ -+ quilt fold < "$FILE" || { -+ cp "$FILE" ./cur_patch -+ echo "patch $FILE failed to apply, copied to ./cur_patch" -+ exit 1 -+ } -+ -+ quilt refresh -p ab --no-index --no-timestamps -+ -+ CUR="$(($CUR + 1))" -+done -+ -+exit 0 --- -2.34.1 - diff --git a/patches/0054-mac80211-drop-hostapd-dependency.patch b/patches/0054-mac80211-drop-hostapd-dependency.patch deleted file mode 100644 index 4b20d0f37..000000000 --- a/patches/0054-mac80211-drop-hostapd-dependency.patch +++ /dev/null @@ -1,26 +0,0 @@ -From d8d0935355a83ea46437d5c145d4c55067d2db00 Mon Sep 17 00:00:00 2001 -From: John Crispin -Date: Fri, 18 Aug 2023 08:37:27 +0200 -Subject: [PATCH 54/55] mac80211: drop hostapd dependency - -Signed-off-by: John Crispin ---- - 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 a7472ee779..1cd537b140 100644 ---- a/package/kernel/mac80211/Makefile -+++ b/package/kernel/mac80211/Makefile -@@ -121,7 +121,7 @@ define KernelPackage/mac80211 - $(call KernelPackage/mac80211/Default) - TITLE:=Linux 802.11 Wireless Networking Stack - # +kmod-crypto-cmac is a runtime only dependency of net/mac80211/aes_cmac.c -- DEPENDS+= +kmod-cfg80211 +kmod-crypto-cmac +kmod-crypto-ccm +kmod-crypto-gcm +hostapd-common -+ DEPENDS+= +kmod-cfg80211 +kmod-crypto-cmac +kmod-crypto-ccm +kmod-crypto-gcm - KCONFIG:=\ - CONFIG_AVERAGE=y - FILES:= $(PKG_BUILD_DIR)/net/mac80211/mac80211.ko --- -2.34.1 - diff --git a/patches/0056-ipq40xx-remove-23.05-version-of-the-target.patch b/patches/0056-ipq40xx-remove-23.05-version-of-the-target.patch index ff34438c3..38f60ff64 100644 --- a/patches/0056-ipq40xx-remove-23.05-version-of-the-target.patch +++ b/patches/0056-ipq40xx-remove-23.05-version-of-the-target.patch @@ -1,6 +1,6 @@ -From e17d18a7872779d67633a74905ba4ca97571aad8 Mon Sep 17 00:00:00 2001 +From a467e92b85d4a1f11614af82a4bd9078fcfa84bc Mon Sep 17 00:00:00 2001 From: John Crispin -Date: Thu, 7 Sep 2023 05:55:04 +0200 +Date: Tue, 19 Sep 2023 06:47:20 +0200 Subject: [PATCH] ipq40xx: drop upstream target Signed-off-by: John Crispin @@ -32226,7 +32226,7 @@ index f6ac69ecf1..0000000000 -TARGET_DEVICES += google_wifi diff --git a/target/linux/ipq40xx/image/generic.mk b/target/linux/ipq40xx/image/generic.mk deleted file mode 100644 -index 7f4806b63d..0000000000 +index 08cbd63b3c..0000000000 --- a/target/linux/ipq40xx/image/generic.mk +++ /dev/null @@ -1,1234 +0,0 @@ @@ -33404,7 +33404,7 @@ index 7f4806b63d..0000000000 -# exploit for the web interface - IMAGES += factory.bin recovery.bin - IMAGE/factory.bin := append-ubi -- IMAGE/recovery.bin := append-squashfs4-fakeroot | sysupgrade-tar kernel=$$$$(BIN_DIR)/openwrt-$$(BOARD)$$(if $$(SUBTARGET),-$$(SUBTARGET))-$$(DEVICE_NAME)-initramfs-zImage.itb rootfs=$$$$@ | append-metadata +- IMAGE/recovery.bin := append-squashfs4-fakeroot | sysupgrade-tar kernel=$$$$(BIN_DIR)/$$(KERNEL_INITRAMFS_IMAGE) rootfs=$$$$@ | append-metadata -endef - -define Device/zte_mf287plus