[][MAC80211][misc][Add MT7996 external openwrt build]

[Description]
Add EHT support patches
Sync CMP2.0 Firmware (20230118)

[Release-log]
N/A

Change-Id: I57f73587515cae6a1fad40ce8a83f8094af5e08d
Reviewed-on: https://gerrit.mediatek.inc/c/openwrt/feeds/mtk_openwrt_feeds/+/7117487
diff --git a/autobuild_mac80211_release/lede-build-sanity.sh b/autobuild_mac80211_release/lede-build-sanity.sh
index 0b06fbc..1b3e0b5 100755
--- a/autobuild_mac80211_release/lede-build-sanity.sh
+++ b/autobuild_mac80211_release/lede-build-sanity.sh
@@ -174,6 +174,9 @@
 	rm -rf ${BUILD_DIR}/package/network/utils/iwinfo
 	cp -fpR ${BUILD_DIR}/./../mac80211_package/package/network/utils/iwinfo ${BUILD_DIR}/package/network/utils
 
+	rm -rf ${BUILD_DIR}/package/network/config/netifd
+	cp -fpR ${BUILD_DIR}/./../mac80211_package/package/network/config/netifd ${BUILD_DIR}/package/network/config
+
 	rm -rf ${BUILD_DIR}/package/kernel/mac80211
 	if [ $1 = "1" ]; then
 		echo "=========================MAC80211 v6.1==================="
@@ -190,10 +193,10 @@
 	cp -fpR ${BUILD_DIR}/./../mac80211_package/package/firmware/wireless-regdb ${BUILD_DIR}/package/firmware
 
 	# do not directly remove mt76 folder, since the firmware folder will also be removed and enter an unsync state
-        rm -rf ${BUILD_DIR}/package/kernel/mt76/Makefile
-        rm -rf ${BUILD_DIR}/package/kernel/mt76/patches
-        rm -rf ${BUILD_DIR}/package/kernel/mt76/src
-        cp -fpR ${BUILD_DIR}/./../mac80211_package/package/kernel/mt76 ${BUILD_DIR}/package/kernel
+	rm -rf ${BUILD_DIR}/package/kernel/mt76/Makefile
+	rm -rf ${BUILD_DIR}/package/kernel/mt76/patches
+	rm -rf ${BUILD_DIR}/package/kernel/mt76/src
+	cp -fpR ${BUILD_DIR}/./../mac80211_package/package/kernel/mt76 ${BUILD_DIR}/package/kernel
 
 	#hack hostapd config
 	echo "CONFIG_MBO=y" >> ./package/network/services/hostapd/files/hostapd-full.config
@@ -279,7 +282,7 @@
 }
 
 install_output_at() {
-	tar -zcvf to at.tgz -C ${INSTALL_DIR}/$1 .
+	tar -zcvf to_at.tgz -C ${INSTALL_DIR}/$1 .
 	mv to_at.tgz ${INSTALL_DIR}/
 }
 
diff --git a/autobuild_mac80211_release/mt7988_mt7996_mac80211/.config b/autobuild_mac80211_release/mt7988_mt7996_mac80211/.config
index 93649af..176446e 100644
--- a/autobuild_mac80211_release/mt7988_mt7996_mac80211/.config
+++ b/autobuild_mac80211_release/mt7988_mt7996_mac80211/.config
@@ -1574,7 +1574,7 @@
 CONFIG_PACKAGE_urngd=y
 CONFIG_PACKAGE_usign=y
 # CONFIG_PACKAGE_uxc is not set
-CONFIG_PACKAGE_wireless-tools=y
+# CONFIG_PACKAGE_wireless-tools is not set
 # CONFIG_PACKAGE_zram-swap is not set
 # end of Base system
 
@@ -4494,7 +4494,7 @@
 # CONFIG_PACKAGE_AFC is not set
 # CONFIG_PACKAGE_apcli_detectd is not set
 # CONFIG_PACKAGE_ated_ext is not set
-# CONFIG_PACKAGE_atenl is not set
+CONFIG_PACKAGE_atenl=y
 # CONFIG_PACKAGE_atf-fuzzer-tool is not set
 # CONFIG_PACKAGE_bluedroid is not set
 # CONFIG_PACKAGE_bndstrg_plus is not set
@@ -4508,7 +4508,7 @@
 # CONFIG_PACKAGE_miniupnpd-1.6 is not set
 # CONFIG_PACKAGE_mtk-efuse-nl-tool is not set
 CONFIG_PACKAGE_regs=y
-CONFIG_PACKAGE_sigma_daemon=y
+# CONFIG_PACKAGE_sigma_daemon is not set
 # CONFIG_PACKAGE_sigma_dut is not set
 # CONFIG_PACKAGE_sigma_one is not set
 CONFIG_PACKAGE_switch=y
diff --git a/autobuild_mac80211_release/mt7988_mt7996_mac80211/0001-support-EHT-for-mac80211.sh.patch b/autobuild_mac80211_release/mt7988_mt7996_mac80211/0001-support-EHT-for-mac80211.sh.patch
new file mode 100644
index 0000000..2b57f70
--- /dev/null
+++ b/autobuild_mac80211_release/mt7988_mt7996_mac80211/0001-support-EHT-for-mac80211.sh.patch
@@ -0,0 +1,207 @@
+diff --git a/package/kernel/mac80211/files/lib/netifd/wireless/mac80211.sh b/package/kernel/mac80211/files/lib/netifd/wireless/mac80211.sh
+index a055005..0c31ad4 100644
+--- a/package/kernel/mac80211/files/lib/netifd/wireless/mac80211.sh
++++ b/package/kernel/mac80211/files/lib/netifd/wireless/mac80211.sh
+@@ -157,8 +157,8 @@ mac80211_hostapd_setup_base() {
+ 	ieee80211n=1
+ 	ht_capab=
+ 	case "$htmode" in
+-		VHT20|HT20|HE20) ;;
+-		HT40*|VHT40|VHT80|VHT160|HE40|HE80|HE160)
++		VHT20|HT20|HE20|EHT20) ;;
++		HT40*|VHT40|VHT80|VHT160|HE40|HE80|HE160|EHT40|EHT80|EHT160|EHT320*)
+ 			case "$hwmode" in
+ 				a)
+ 					case "$(( (($channel / 4) + $chan_ofs) % 2 ))" in
+@@ -202,7 +202,7 @@ mac80211_hostapd_setup_base() {
+ 			dsss_cck_40:1
+ 
+ 		ht_cap_mask=0
+-		for cap in $(iw phy "$phy" info | grep 'Capabilities:' | cut -d: -f2); do
++		for cap in $(iw phy "$phy" info | grep 'Capabilities: 0x' | cut -d: -f2); do
+ 			ht_cap_mask="$(($ht_cap_mask | $cap))"
+ 		done
+ 
+@@ -233,8 +233,8 @@ mac80211_hostapd_setup_base() {
+ 
+ 	idx="$channel"
+ 	case "$htmode" in
+-		VHT20|HE20) enable_ac=1;;
+-		VHT40|HE40)
++		VHT20|HE20|EHT20) enable_ac=1;;
++		VHT40|HE40|EHT40)
+ 			case "$(( (($channel / 4) + $chan_ofs) % 2 ))" in
+ 				1) idx=$(($channel + 2));;
+ 				0) idx=$(($channel - 2));;
+@@ -242,7 +242,7 @@ mac80211_hostapd_setup_base() {
+ 			enable_ac=1
+ 			vht_center_seg0=$idx
+ 		;;
+-		VHT80|HE80)
++		VHT80|HE80|EHT80)
+ 			case "$(( (($channel / 4) + $chan_ofs) % 4 ))" in
+ 				1) idx=$(($channel + 6));;
+ 				2) idx=$(($channel + 2));;
+@@ -253,7 +253,7 @@ mac80211_hostapd_setup_base() {
+ 			vht_oper_chwidth=1
+ 			vht_center_seg0=$idx
+ 		;;
+-		VHT160|HE160)
++		VHT160|HE160|EHT160)
+ 			if [ "$band" = "6g" ]; then
+ 				case "$channel" in
+ 					1|5|9|13|17|21|25|29) idx=15;;
+@@ -274,6 +274,36 @@ mac80211_hostapd_setup_base() {
+ 			vht_oper_chwidth=2
+ 			vht_center_seg0=$idx
+ 		;;
++		EHT320*)
++			case "$channel" in
++				1|5|9|13|17|21|25|29) idx=31;;
++				33|37|41|45|49|53|57|61| \
++				65|69|73|77|81|85|89|93) idx=63;;
++				97|101|105|109|113|117|121|125| \
++				129|133|137|141|145|149|153|157) idx=127;;
++				161|165|169|173|177|181|185|189| \
++				193|197|201|205|209|213|217|221) idx=191;;
++			esac
++			if [[ "$htmode" = "EHT320-1" && "$channel" -ge "193" ]] ||
++			   [[ "$htmode" = "EHT320-2" && "$channel" -le "29" ]]; then
++				echo "Could not set the center freq with this EHT setting"
++				return 1
++			elif [[ "$htmode" = "EHT320-1" && "$channel" -ge "33" ]]; then
++				if [ "$channel" -gt $idx ]; then
++					idx=$(($idx + 32))
++				else
++					idx=$(($idx - 32))
++				fi
++			fi
++			vht_oper_chwidth=2
++			if [ "$channel" -gt $idx ]; then
++				vht_center_seg0=$(($idx + 16))
++			else
++				vht_center_seg0=$(($idx - 16))
++			fi
++			eht_oper_chwidth=9
++			eht_oper_centr_freq_seg0_idx=$idx
++		;;
+ 	esac
+ 	[ "$band" = "5g" ] && {
+ 		json_get_vars background_radar:0
+@@ -283,8 +313,9 @@ mac80211_hostapd_setup_base() {
+ 	[ "$band" = "6g" ] && {
+ 		op_class=
+ 		case "$htmode" in
+-			HE20) op_class=131;;
+-			HE*) op_class=$((132 + $vht_oper_chwidth))
++			HE20|EHT20) op_class=131;;
++			EHT320*) op_class=137;;
++			HE*|EHT*) op_class=$((132 + $vht_oper_chwidth))
+ 		esac
+ 		[ -n "$op_class" ] && append base_cfg "op_class=$op_class" "$N"
+ 	}
+@@ -407,7 +438,7 @@ mac80211_hostapd_setup_base() {
+ 	# 802.11ax
+ 	enable_ax=0
+ 	case "$htmode" in
+-		HE*) enable_ax=1 ;;
++		HE*|EHT*) enable_ax=1 ;;
+ 	esac
+ 
+ 	if [ "$enable_ax" != "0" ]; then
+@@ -481,6 +512,28 @@ mac80211_hostapd_setup_base() {
+ 		append base_cfg "he_mu_edca_ac_vo_timer=255" "$N"
+ 	fi
+ 
++	# 802.11be
++	enable_be=0
++	case "$htmode" in
++		EHT*) enable_be=1 ;;
++	esac
++
++	if [ "$enable_be" != "0" ]; then
++		append base_cfg "ieee80211be=1" "$N"
++		[ "$hwmode" = "a" ] && {
++			case $htmode in
++				EHT320*)
++					append base_cfg "eht_oper_chwidth=$eht_oper_chwidth" "$N"
++					append base_cfg "eht_oper_centr_freq_seg0_idx=$eht_oper_centr_freq_seg0_idx" "$N"
++				;;
++				*)
++					append base_cfg "eht_oper_chwidth=$vht_oper_chwidth" "$N"
++					append base_cfg "eht_oper_centr_freq_seg0_idx=$vht_center_seg0" "$N"
++				;;
++			esac
++		}
++	fi
++
+ 	hostapd_prepare_device_config "$hostapd_conf_file" nl80211
+ 	cat >> "$hostapd_conf_file" <<EOF
+ ${channel:+channel=$channel}
+diff --git a/package/kernel/mac80211/files/lib/wifi/mac80211.sh b/package/kernel/mac80211/files/lib/wifi/mac80211.sh
+index 438bf92..cb85bac 100644
+--- a/package/kernel/mac80211/files/lib/wifi/mac80211.sh
++++ b/package/kernel/mac80211/files/lib/wifi/mac80211.sh
+@@ -60,6 +60,8 @@ BEGIN {
+ 		if (vht && band != "1:") mode="VHT80"
+ 		if (he) mode="HE80"
+ 		if (he && band == "1:") mode="HE20"
++		if (eht) mode="EHT80"
++		if (eht && band == "1:") mode="EHT20"
+                 sub("\\[", "", channel)
+                 sub("\\]", "", channel)
+                 bands = bands band channel ":" mode " "
+@@ -73,6 +75,7 @@ $1 == "Band" {
+ 	vht = ""
+ 	ht = ""
+ 	he = ""
++	eht = ""
+ }
+ 
+ $0 ~ "Capabilities:" {
+@@ -87,6 +90,10 @@ $0 ~ "HE Iftypes" {
+ 	he=1
+ }
+ 
++$0 ~ "EHT Iftypes" {
++	eht=1
++}
++
+ $1 == "*" && $3 == "MHz" && $0 !~ /disabled/ && band && !channel {
+         channel = $4
+ }
+@@ -160,6 +167,10 @@ detect_mac80211() {
+ 
+ 	json_load_file /etc/board.json
+ 
++	# generate random bytes for macaddr
++	rand=$(hexdump -C /dev/urandom | head -n 1 &)
++	killall hexdump
++
+ 	for _dev in /sys/class/ieee80211/*; do
+ 		[ -e "$_dev" ] || continue
+ 
+@@ -201,6 +212,11 @@ detect_mac80211() {
+ 				;;
+ 		esac
+ 
++		macaddr=""
++		for i in $(seq 2 3); do
++			macaddr=${macaddr}:$(echo $rand | cut -d ' ' -f $i)
++		done
++
+ 		uci -q batch <<-EOF
+ 			set wireless.${name}=wifi-device
+ 			set wireless.${name}.type=mac80211
+@@ -217,6 +233,8 @@ detect_mac80211() {
+ 			set wireless.default_${name}.ssid=OpenWrt
+ 			set wireless.default_${name}.encryption=${encryption}
+ 
++			set wireless.default_${name}.macaddr=00:0$(($devidx - 1)):55:66${macaddr}
++
+ EOF
+ 		[ -n "$key" ] && {
+ 			uci -q set wireless.default_${name}.key=${key}
+-- 
+2.25.1
+
diff --git a/autobuild_mac80211_release/mt7988_mt7996_mac80211/0002-add-EHT-config-for-hostapd.patch b/autobuild_mac80211_release/mt7988_mt7996_mac80211/0002-add-EHT-config-for-hostapd.patch
new file mode 100644
index 0000000..1b89906
--- /dev/null
+++ b/autobuild_mac80211_release/mt7988_mt7996_mac80211/0002-add-EHT-config-for-hostapd.patch
@@ -0,0 +1,58 @@
+From 2fc6bba3bf6691c388a48b0503f30c6e5fa8d226 Mon Sep 17 00:00:00 2001
+From: Shayne Chen <shayne.chen@mediatek.com>
+Date: Wed, 21 Dec 2022 14:27:08 +0800
+Subject: [PATCH] add EHT config for hostapd
+
+Signed-off-by: Shayne Chen <shayne.chen@mediatek.com>
+---
+ package/network/services/hostapd/Config.in | 4 ++++
+ package/network/services/hostapd/Makefile  | 6 ++++++
+ 2 files changed, 10 insertions(+)
+
+diff --git a/package/network/services/hostapd/Config.in b/package/network/services/hostapd/Config.in
+index 8f28eb2..d268056 100644
+--- a/package/network/services/hostapd/Config.in
++++ b/package/network/services/hostapd/Config.in
+@@ -87,6 +87,10 @@ config DRIVER_11AX_SUPPORT
+ 	default n
+ 	select WPA_MBO_SUPPORT
+ 
++config DRIVER_11BE_SUPPORT
++	bool
++	default n
++
+ config WPA_ENABLE_WEP
+ 	bool "Enable support for unsecure and obsolete WEP"
+ 	help
+diff --git a/package/network/services/hostapd/Makefile b/package/network/services/hostapd/Makefile
+index 829879f..08fd4ef 100644
+--- a/package/network/services/hostapd/Makefile
++++ b/package/network/services/hostapd/Makefile
+@@ -30,6 +30,7 @@ PKG_CONFIG_DEPENDS:= \
+ 	CONFIG_DRIVER_WEXT_SUPPORT \
+ 	CONFIG_DRIVER_11AC_SUPPORT \
+ 	CONFIG_DRIVER_11AX_SUPPORT \
++	CONFIG_DRIVER_11BE_SUPPORT \
+ 	CONFIG_WPA_ENABLE_WEP
+ 
+ EAPOL_TEST_PROVIDERS:=eapol-test eapol-test-openssl eapol-test-wolfssl
+@@ -80,11 +81,16 @@ ifneq ($(CONFIG_DRIVER_11AX_SUPPORT),)
+   HOSTAPD_IEEE80211AX:=y
+ endif
+ 
++ifneq ($(CONFIG_DRIVER_11BE_SUPPORT),)
++  HOSTAPD_IEEE80211BE:=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_IEEE80211BE=$(HOSTAPD_IEEE80211BE) \
+ 	CONFIG_DRIVER_WEXT=$(CONFIG_DRIVER_WEXT_SUPPORT) \
+ 	CONFIG_MBO=$(CONFIG_WPA_MBO_SUPPORT)
+ 
+-- 
+2.25.1
+
diff --git a/autobuild_mac80211_release/mt7988_mt7996_mac80211/lede-branch-build-sanity.sh b/autobuild_mac80211_release/mt7988_mt7996_mac80211/lede-branch-build-sanity.sh
index 53fc917..f26ba61 100755
--- a/autobuild_mac80211_release/mt7988_mt7996_mac80211/lede-branch-build-sanity.sh
+++ b/autobuild_mac80211_release/mt7988_mt7996_mac80211/lede-branch-build-sanity.sh
@@ -4,16 +4,12 @@
 #get the brach_name
 temp=${0%/*}
 branch_name=${temp##*/}
-rro=0
 hwpath=0
 backport_new=1
 args=
 
 for arg in $*; do
 	case "$arg" in
-	"rro")
-		rro=1
-		;;
 	"hwpath")
 		hwpath=1
 		;;
@@ -25,11 +21,6 @@
 set -- $args
 
 change_dot_config() {
-	[ "$rro" = "0" ] && {
-		rm -rf ${BUILD_DIR}/package/kernel/mt76/patches/*pao*.patch
-		rm -rf ${BUILD_DIR}/package/kernel/mt76/patches/*rro*.patch
-		rm -rf ${BUILD_DIR}/package/kernel/mt76/patches/*bellwether*.patch
-	}
 	[ "$hwpath" = "0" ] && {
 		echo "==========SW PATH========="
 		sed -i 's/CONFIG_BRIDGE_NETFILTER=y/# CONFIG_BRIDGE_NETFILTER is not set/g' ${BUILD_DIR}/target/linux/mediatek/mt7988/config-5.4
@@ -37,7 +28,7 @@
 		sed -i 's/CONFIG_SKB_EXTENSIONS=y/# CONFIG_SKB_EXTENSIONS is not set/g' ${BUILD_DIR}/target/linux/mediatek/mt7988/config-5.4
 	}
 	[ "$backport_new" = "1" ] && {
-                rm -rf ${BUILD_DIR}/package/kernel/mt76/patches/*revert-for-backports*.patch
+		rm -rf ${BUILD_DIR}/package/kernel/mt76/patches/*revert-for-backports*.patch
         }
 }
 
@@ -52,17 +43,23 @@
 echo "CONFIG_RELAY=y" >> ${BUILD_DIR}/target/linux/mediatek/mt7988/config-5.4
 
 prepare_flowoffload
-##############################################################################
-rm -rf  ${MTK_FEED_DIR}/autobuild_mac80211_release/package/kernel/mt76/patches
-##############################################################################
 
 #prepare mac80211 mt76 wifi stuff
 prepare_mac80211 ${backport_new}
 
-###############################################################################
-# remove hostapd internal patches
-rm -rf ${BUILD_DIR}/package/network/services/hostapd/patches/999*mtk*.patch
-###############################################################################
+# find ${BUILD_DIR}/package/kernel/mt76/patches -name "*-mt76-*.patch" -delete
+rm -rf ${BUILD_DIR}/package/kernel/mt76/patches/*
+
+# ========== specific modification on mt7996 autobuild for EHT support ==========
+# patch mac80211.sh script
+patch -p1 < ${BUILD_DIR}/autobuild/${branch_name}/0001-support-EHT-for-mac80211.sh.patch
+# patch hostapd to use latest version and add 11BE config
+patch -p1 < ${BUILD_DIR}/autobuild/${branch_name}/0002-add-EHT-config-for-hostapd.patch
+
+# remove some iw patches to let EHT work normally
+rm -rf ${BUILD_DIR}/package/network/utils/iw/patches/001-nl80211_h_sync.patch
+rm -rf ${BUILD_DIR}/package/network/utils/iw/patches/120-antenna_gain.patch
+# ===========================================================
 
 prepare_final ${branch_name}
 
diff --git a/autobuild_mac80211_release/mt7988_mt7996_mac80211/package/kernel/mac80211/patches/subsys/9999901-mac80211-mtk-add-rate-duration-for-EHT-rate.patch b/autobuild_mac80211_release/mt7988_mt7996_mac80211/package/kernel/mac80211/patches/subsys/9999901-mac80211-mtk-add-rate-duration-for-EHT-rate.patch
new file mode 100644
index 0000000..0675c5e
--- /dev/null
+++ b/autobuild_mac80211_release/mt7988_mt7996_mac80211/package/kernel/mac80211/patches/subsys/9999901-mac80211-mtk-add-rate-duration-for-EHT-rate.patch
@@ -0,0 +1,464 @@
+From 06ae5e66a56e6def22c1d4d61d75815f9b1f7ee2 Mon Sep 17 00:00:00 2001
+From: Evelyn Tsai <evelyn.tsai@mediatek.com>
+Date: Sun, 25 Dec 2022 22:43:46 +0800
+Subject: [PATCH 9999901/9999902] mac80211: mtk: add rate duration for EHT
+ rate.
+
+---
+ include/net/mac80211.h |   4 +-
+ net/mac80211/airtime.c | 349 ++++++++++++++++++++++++++++++++++++++++-
+ 2 files changed, 348 insertions(+), 5 deletions(-)
+
+diff --git a/include/net/mac80211.h b/include/net/mac80211.h
+index dd9e834..f7fcefe 100644
+--- a/include/net/mac80211.h
++++ b/include/net/mac80211.h
+@@ -1437,6 +1437,7 @@ enum mac80211_rx_encoding {
+ 	RX_ENC_HT,
+ 	RX_ENC_VHT,
+ 	RX_ENC_HE,
++	RX_ENC_EHT,
+ };
+ 
+ /**
+@@ -1499,8 +1500,7 @@ struct ieee80211_rx_status {
+ 	u32 flag;
+ 	u16 freq: 13, freq_offset: 1;
+ 	u8 enc_flags;
+-	u8 encoding:2, bw:3, he_ru:3;
+-	u8 he_gi:2, he_dcm:1;
++	u16 encoding:3, bw:3, he_ru:3, he_gi:2, he_dcm:1;
+ 	u8 rate_idx;
+ 	u8 nss;
+ 	u8 rx_flags;
+diff --git a/net/mac80211/airtime.c b/net/mac80211/airtime.c
+index e8ebd34..b1de6d0 100644
+--- a/net/mac80211/airtime.c
++++ b/net/mac80211/airtime.c
+@@ -55,10 +55,21 @@
+ #define HE_DURATION_S(shift, streams, gi, bps)		\
+ 	(HE_DURATION(streams, gi, bps) >> shift)
+ 
++/* Transmit duration for the raw data part of an average sized packet */
++#define EHT_GI_08 HE_GI_08
++#define EHT_GI_16 HE_GI_16
++#define EHT_GI_32 HE_GI_32
++
++#define EHT_DURATION(streams, gi, bps)			\
++	HE_DURATION(streams, gi, bps)
++#define EHT_DURATION_S(shift, streams, gi, bps)		\
++	HE_DURATION_S(shift, streams, gi, bps)
++
+ #define BW_20			0
+ #define BW_40			1
+ #define BW_80			2
+ #define BW_160			3
++#define BW_320			4
+ 
+ /*
+  * Define group sort order: HT40 -> SGI -> #streams
+@@ -68,17 +79,26 @@
+ #define IEEE80211_VHT_STREAM_GROUPS	8 /* BW(=4) * SGI(=2) */
+ 
+ #define IEEE80211_HE_MAX_STREAMS	8
++#define IEEE80211_HE_STREAM_GROUPS	12 /* BW(=4) * GI(=3) */
++
++#define IEEE80211_EHT_MAX_STREAMS	16
++#define IEEE80211_EHT_STREAM_GROUPS	15 /* BW(=5) * GI(=3) */
+ 
+ #define IEEE80211_HT_GROUPS_NB	(IEEE80211_MAX_STREAMS *	\
+ 				 IEEE80211_HT_STREAM_GROUPS)
+ #define IEEE80211_VHT_GROUPS_NB	(IEEE80211_MAX_STREAMS *	\
+ 					 IEEE80211_VHT_STREAM_GROUPS)
++#define IEEE80211_HE_GROUPS_NB	(IEEE80211_HE_MAX_STREAMS *	\
++				 IEEE80211_HE_STREAM_GROUPS)
++#define IEEE80211_EHT_GROUPS_NB	(IEEE80211_EHT_MAX_STREAMS *	\
++				 IEEE80211_EHT_STREAM_GROUPS)
+ 
+ #define IEEE80211_HT_GROUP_0	0
+ #define IEEE80211_VHT_GROUP_0	(IEEE80211_HT_GROUP_0 + IEEE80211_HT_GROUPS_NB)
+ #define IEEE80211_HE_GROUP_0	(IEEE80211_VHT_GROUP_0 + IEEE80211_VHT_GROUPS_NB)
++#define IEEE80211_EHT_GROUP_0	(IEEE80211_HE_GROUP_0 + IEEE80211_HE_GROUPS_NB)
+ 
+-#define MCS_GROUP_RATES		12
++#define MCS_GROUP_RATES		14
+ 
+ #define HT_GROUP_IDX(_streams, _sgi, _ht40)	\
+ 	IEEE80211_HT_GROUP_0 +			\
+@@ -203,6 +223,59 @@
+ #define HE_GROUP(_streams, _gi, _bw)					\
+ 	__HE_GROUP(_streams, _gi, _bw,				\
+ 		   HE_GROUP_SHIFT(_streams, _gi, _bw))
++
++#define EHT_BW2VBPS(_bw, r5, r4, r3, r2, r1)					\
++	(_bw == BW_320 ? r5 : _bw == BW_160 ? r4 : _bw == BW_80 ? r3 : _bw == BW_40 ? r2 : r1)
++
++#define EHT_GROUP_IDX(_streams, _gi, _bw)				\
++	(IEEE80211_EHT_GROUP_0 +					\
++	 IEEE80211_EHT_MAX_STREAMS * 3 * (_bw) +			\
++	 IEEE80211_EHT_MAX_STREAMS * (_gi) +				\
++	 (_streams) - 1)
++
++#define __EHT_GROUP(_streams, _gi, _bw, _s)				\
++	[EHT_GROUP_IDX(_streams, _gi, _bw)] = {			\
++	.shift = _s,							\
++	.duration = {							\
++		EHT_DURATION_S(_s, _streams, _gi,			\
++			      EHT_BW2VBPS(_bw,   1960,   979,  489,  230,  115)),	\
++		EHT_DURATION_S(_s, _streams, _gi,			\
++			      EHT_BW2VBPS(_bw,   3920,  1958,  979,  475,  230)),	\
++		EHT_DURATION_S(_s, _streams, _gi,			\
++			      EHT_BW2VBPS(_bw,   5880,  2937, 1468,  705,  345)),	\
++		EHT_DURATION_S(_s, _streams, _gi,			\
++			      EHT_BW2VBPS(_bw,   7840,  3916, 1958,  936,  475)),	\
++		EHT_DURATION_S(_s, _streams, _gi,			\
++			      EHT_BW2VBPS(_bw,  11760,  5875, 2937, 1411,  705)),	\
++		EHT_DURATION_S(_s, _streams, _gi,			\
++			      EHT_BW2VBPS(_bw,  15680,  7833, 3916, 1872,  936)),	\
++		EHT_DURATION_S(_s, _streams, _gi,			\
++			      EHT_BW2VBPS(_bw,  17640,  8827, 4406, 2102, 1051)),	\
++		EHT_DURATION_S(_s, _streams, _gi,			\
++			      EHT_BW2VBPS(_bw,  19600,  9806, 4896, 2347, 1166)),	\
++		EHT_DURATION_S(_s, _streams, _gi,			\
++			      EHT_BW2VBPS(_bw,  23520, 11764, 5875, 2808, 1411)),	\
++		EHT_DURATION_S(_s, _streams, _gi,			\
++			      EHT_BW2VBPS(_bw,  26133, 13060, 6523, 3124, 1555)),	\
++		EHT_DURATION_S(_s, _streams, _gi,			\
++			      EHT_BW2VBPS(_bw,  29400, 14702, 7344, 3513, 1756)),	\
++		EHT_DURATION_S(_s, _streams, _gi,			\
++			      EHT_BW2VBPS(_bw,  32666, 16329, 8164, 3902, 1944)),	\
++		EHT_DURATION_S(_s, _streams, _gi,			\
++			      EHT_BW2VBPS(_bw,  35280, 17640, 8820, 4212, 2106)),	\
++		EHT_DURATION_S(_s, _streams, _gi,			\
++			      EHT_BW2VBPS(_bw,  39200, 19600, 9800, 4680, 2340))	\
++        }								\
++}
++
++#define EHT_GROUP_SHIFT(_streams, _gi, _bw)				\
++	GROUP_SHIFT(EHT_DURATION(_streams, _gi,			\
++				EHT_BW2VBPS(_bw,   1960,   979,  489,  230,  115)))
++
++#define EHT_GROUP(_streams, _gi, _bw)					\
++	__EHT_GROUP(_streams, _gi, _bw,				\
++		   EHT_GROUP_SHIFT(_streams, _gi, _bw))
++
+ struct mcs_group {
+ 	u8 shift;
+ 	u16 duration[MCS_GROUP_RATES];
+@@ -376,6 +449,262 @@ static const struct mcs_group airtime_mcs_groups[] = {
+ 	HE_GROUP(6, HE_GI_32, BW_160),
+ 	HE_GROUP(7, HE_GI_32, BW_160),
+ 	HE_GROUP(8, HE_GI_32, BW_160),
++
++	/* EHT */
++	EHT_GROUP( 1, EHT_GI_08, BW_20),
++	EHT_GROUP( 2, EHT_GI_08, BW_20),
++	EHT_GROUP( 3, EHT_GI_08, BW_20),
++	EHT_GROUP( 4, EHT_GI_08, BW_20),
++	EHT_GROUP( 5, EHT_GI_08, BW_20),
++	EHT_GROUP( 6, EHT_GI_08, BW_20),
++	EHT_GROUP( 7, EHT_GI_08, BW_20),
++	EHT_GROUP( 8, EHT_GI_08, BW_20),
++	EHT_GROUP( 9, EHT_GI_08, BW_20),
++	EHT_GROUP(10, EHT_GI_08, BW_20),
++	EHT_GROUP(11, EHT_GI_08, BW_20),
++	EHT_GROUP(12, EHT_GI_08, BW_20),
++	EHT_GROUP(13, EHT_GI_08, BW_20),
++	EHT_GROUP(14, EHT_GI_08, BW_20),
++	EHT_GROUP(15, EHT_GI_08, BW_20),
++	EHT_GROUP(16, EHT_GI_08, BW_20),
++
++	EHT_GROUP( 1, EHT_GI_16, BW_20),
++	EHT_GROUP( 2, EHT_GI_16, BW_20),
++	EHT_GROUP( 3, EHT_GI_16, BW_20),
++	EHT_GROUP( 4, EHT_GI_16, BW_20),
++	EHT_GROUP( 5, EHT_GI_16, BW_20),
++	EHT_GROUP( 6, EHT_GI_16, BW_20),
++	EHT_GROUP( 7, EHT_GI_16, BW_20),
++	EHT_GROUP( 8, EHT_GI_16, BW_20),
++	EHT_GROUP( 9, EHT_GI_16, BW_20),
++	EHT_GROUP(10, EHT_GI_16, BW_20),
++	EHT_GROUP(11, EHT_GI_16, BW_20),
++	EHT_GROUP(12, EHT_GI_16, BW_20),
++	EHT_GROUP(13, EHT_GI_16, BW_20),
++	EHT_GROUP(14, EHT_GI_16, BW_20),
++	EHT_GROUP(15, EHT_GI_16, BW_20),
++	EHT_GROUP(16, EHT_GI_16, BW_20),
++
++	EHT_GROUP( 1, EHT_GI_32, BW_20),
++	EHT_GROUP( 2, EHT_GI_32, BW_20),
++	EHT_GROUP( 3, EHT_GI_32, BW_20),
++	EHT_GROUP( 4, EHT_GI_32, BW_20),
++	EHT_GROUP( 5, EHT_GI_32, BW_20),
++	EHT_GROUP( 6, EHT_GI_32, BW_20),
++	EHT_GROUP( 7, EHT_GI_32, BW_20),
++	EHT_GROUP( 8, EHT_GI_32, BW_20),
++	EHT_GROUP( 9, EHT_GI_32, BW_20),
++	EHT_GROUP(10, EHT_GI_32, BW_20),
++	EHT_GROUP(11, EHT_GI_32, BW_20),
++	EHT_GROUP(12, EHT_GI_32, BW_20),
++	EHT_GROUP(13, EHT_GI_32, BW_20),
++	EHT_GROUP(14, EHT_GI_32, BW_20),
++	EHT_GROUP(15, EHT_GI_32, BW_20),
++	EHT_GROUP(16, EHT_GI_32, BW_20),
++
++	EHT_GROUP( 1, EHT_GI_08, BW_40),
++	EHT_GROUP( 2, EHT_GI_08, BW_40),
++	EHT_GROUP( 3, EHT_GI_08, BW_40),
++	EHT_GROUP( 4, EHT_GI_08, BW_40),
++	EHT_GROUP( 5, EHT_GI_08, BW_40),
++	EHT_GROUP( 6, EHT_GI_08, BW_40),
++	EHT_GROUP( 7, EHT_GI_08, BW_40),
++	EHT_GROUP( 8, EHT_GI_08, BW_40),
++	EHT_GROUP( 9, EHT_GI_08, BW_40),
++	EHT_GROUP(10, EHT_GI_08, BW_40),
++	EHT_GROUP(11, EHT_GI_08, BW_40),
++	EHT_GROUP(12, EHT_GI_08, BW_40),
++	EHT_GROUP(13, EHT_GI_08, BW_40),
++	EHT_GROUP(14, EHT_GI_08, BW_40),
++	EHT_GROUP(15, EHT_GI_08, BW_40),
++	EHT_GROUP(16, EHT_GI_08, BW_40),
++
++	EHT_GROUP( 1, EHT_GI_16, BW_40),
++	EHT_GROUP( 2, EHT_GI_16, BW_40),
++	EHT_GROUP( 3, EHT_GI_16, BW_40),
++	EHT_GROUP( 4, EHT_GI_16, BW_40),
++	EHT_GROUP( 5, EHT_GI_16, BW_40),
++	EHT_GROUP( 6, EHT_GI_16, BW_40),
++	EHT_GROUP( 7, EHT_GI_16, BW_40),
++	EHT_GROUP( 8, EHT_GI_16, BW_40),
++	EHT_GROUP( 9, EHT_GI_16, BW_40),
++	EHT_GROUP(10, EHT_GI_16, BW_40),
++	EHT_GROUP(11, EHT_GI_16, BW_40),
++	EHT_GROUP(12, EHT_GI_16, BW_40),
++	EHT_GROUP(13, EHT_GI_16, BW_40),
++	EHT_GROUP(14, EHT_GI_16, BW_40),
++	EHT_GROUP(15, EHT_GI_16, BW_40),
++	EHT_GROUP(16, EHT_GI_16, BW_40),
++
++	EHT_GROUP( 1, EHT_GI_32, BW_40),
++	EHT_GROUP( 2, EHT_GI_32, BW_40),
++	EHT_GROUP( 3, EHT_GI_32, BW_40),
++	EHT_GROUP( 4, EHT_GI_32, BW_40),
++	EHT_GROUP( 5, EHT_GI_32, BW_40),
++	EHT_GROUP( 6, EHT_GI_32, BW_40),
++	EHT_GROUP( 7, EHT_GI_32, BW_40),
++	EHT_GROUP( 8, EHT_GI_32, BW_40),
++	EHT_GROUP( 9, EHT_GI_32, BW_40),
++	EHT_GROUP(10, EHT_GI_32, BW_40),
++	EHT_GROUP(11, EHT_GI_32, BW_40),
++	EHT_GROUP(12, EHT_GI_32, BW_40),
++	EHT_GROUP(13, EHT_GI_32, BW_40),
++	EHT_GROUP(14, EHT_GI_32, BW_40),
++	EHT_GROUP(15, EHT_GI_32, BW_40),
++	EHT_GROUP(16, EHT_GI_32, BW_40),
++
++	EHT_GROUP( 1, EHT_GI_08, BW_80),
++	EHT_GROUP( 2, EHT_GI_08, BW_80),
++	EHT_GROUP( 3, EHT_GI_08, BW_80),
++	EHT_GROUP( 4, EHT_GI_08, BW_80),
++	EHT_GROUP( 5, EHT_GI_08, BW_80),
++	EHT_GROUP( 6, EHT_GI_08, BW_80),
++	EHT_GROUP( 7, EHT_GI_08, BW_80),
++	EHT_GROUP( 8, EHT_GI_08, BW_80),
++	EHT_GROUP( 9, EHT_GI_08, BW_80),
++	EHT_GROUP(10, EHT_GI_08, BW_80),
++	EHT_GROUP(11, EHT_GI_08, BW_80),
++	EHT_GROUP(12, EHT_GI_08, BW_80),
++	EHT_GROUP(13, EHT_GI_08, BW_80),
++	EHT_GROUP(14, EHT_GI_08, BW_80),
++	EHT_GROUP(15, EHT_GI_08, BW_80),
++	EHT_GROUP(16, EHT_GI_08, BW_80),
++
++	EHT_GROUP( 1, EHT_GI_16, BW_80),
++	EHT_GROUP( 2, EHT_GI_16, BW_80),
++	EHT_GROUP( 3, EHT_GI_16, BW_80),
++	EHT_GROUP( 4, EHT_GI_16, BW_80),
++	EHT_GROUP( 5, EHT_GI_16, BW_80),
++	EHT_GROUP( 6, EHT_GI_16, BW_80),
++	EHT_GROUP( 7, EHT_GI_16, BW_80),
++	EHT_GROUP( 8, EHT_GI_16, BW_80),
++	EHT_GROUP( 9, EHT_GI_16, BW_80),
++	EHT_GROUP(10, EHT_GI_16, BW_80),
++	EHT_GROUP(11, EHT_GI_16, BW_80),
++	EHT_GROUP(12, EHT_GI_16, BW_80),
++	EHT_GROUP(13, EHT_GI_16, BW_80),
++	EHT_GROUP(14, EHT_GI_16, BW_80),
++	EHT_GROUP(15, EHT_GI_16, BW_80),
++	EHT_GROUP(16, EHT_GI_16, BW_80),
++
++	EHT_GROUP( 1, EHT_GI_32, BW_80),
++	EHT_GROUP( 2, EHT_GI_32, BW_80),
++	EHT_GROUP( 3, EHT_GI_32, BW_80),
++	EHT_GROUP( 4, EHT_GI_32, BW_80),
++	EHT_GROUP( 5, EHT_GI_32, BW_80),
++	EHT_GROUP( 6, EHT_GI_32, BW_80),
++	EHT_GROUP( 7, EHT_GI_32, BW_80),
++	EHT_GROUP( 8, EHT_GI_32, BW_80),
++	EHT_GROUP( 9, EHT_GI_32, BW_80),
++	EHT_GROUP(10, EHT_GI_32, BW_80),
++	EHT_GROUP(11, EHT_GI_32, BW_80),
++	EHT_GROUP(12, EHT_GI_32, BW_80),
++	EHT_GROUP(13, EHT_GI_32, BW_80),
++	EHT_GROUP(14, EHT_GI_32, BW_80),
++	EHT_GROUP(15, EHT_GI_32, BW_80),
++	EHT_GROUP(16, EHT_GI_32, BW_80),
++
++	EHT_GROUP( 1, EHT_GI_08, BW_160),
++	EHT_GROUP( 2, EHT_GI_08, BW_160),
++	EHT_GROUP( 3, EHT_GI_08, BW_160),
++	EHT_GROUP( 4, EHT_GI_08, BW_160),
++	EHT_GROUP( 5, EHT_GI_08, BW_160),
++	EHT_GROUP( 6, EHT_GI_08, BW_160),
++	EHT_GROUP( 7, EHT_GI_08, BW_160),
++	EHT_GROUP( 8, EHT_GI_08, BW_160),
++	EHT_GROUP( 9, EHT_GI_08, BW_160),
++	EHT_GROUP(10, EHT_GI_08, BW_160),
++	EHT_GROUP(11, EHT_GI_08, BW_160),
++	EHT_GROUP(12, EHT_GI_08, BW_160),
++	EHT_GROUP(13, EHT_GI_08, BW_160),
++	EHT_GROUP(14, EHT_GI_08, BW_160),
++	EHT_GROUP(15, EHT_GI_08, BW_160),
++	EHT_GROUP(16, EHT_GI_08, BW_160),
++
++	EHT_GROUP( 1, EHT_GI_16, BW_160),
++	EHT_GROUP( 2, EHT_GI_16, BW_160),
++	EHT_GROUP( 3, EHT_GI_16, BW_160),
++	EHT_GROUP( 4, EHT_GI_16, BW_160),
++	EHT_GROUP( 5, EHT_GI_16, BW_160),
++	EHT_GROUP( 6, EHT_GI_16, BW_160),
++	EHT_GROUP( 7, EHT_GI_16, BW_160),
++	EHT_GROUP( 8, EHT_GI_16, BW_160),
++	EHT_GROUP( 9, EHT_GI_16, BW_160),
++	EHT_GROUP(10, EHT_GI_16, BW_160),
++	EHT_GROUP(11, EHT_GI_16, BW_160),
++	EHT_GROUP(12, EHT_GI_16, BW_160),
++	EHT_GROUP(13, EHT_GI_16, BW_160),
++	EHT_GROUP(14, EHT_GI_16, BW_160),
++	EHT_GROUP(15, EHT_GI_16, BW_160),
++	EHT_GROUP(16, EHT_GI_16, BW_160),
++
++	EHT_GROUP( 1, EHT_GI_32, BW_160),
++	EHT_GROUP( 2, EHT_GI_32, BW_160),
++	EHT_GROUP( 3, EHT_GI_32, BW_160),
++	EHT_GROUP( 4, EHT_GI_32, BW_160),
++	EHT_GROUP( 5, EHT_GI_32, BW_160),
++	EHT_GROUP( 6, EHT_GI_32, BW_160),
++	EHT_GROUP( 7, EHT_GI_32, BW_160),
++	EHT_GROUP( 8, EHT_GI_32, BW_160),
++	EHT_GROUP( 9, EHT_GI_32, BW_160),
++	EHT_GROUP(10, EHT_GI_32, BW_160),
++	EHT_GROUP(11, EHT_GI_32, BW_160),
++	EHT_GROUP(12, EHT_GI_32, BW_160),
++	EHT_GROUP(13, EHT_GI_32, BW_160),
++	EHT_GROUP(14, EHT_GI_32, BW_160),
++	EHT_GROUP(15, EHT_GI_32, BW_160),
++	EHT_GROUP(16, EHT_GI_32, BW_160),
++
++	EHT_GROUP( 1, EHT_GI_08, BW_320),
++	EHT_GROUP( 2, EHT_GI_08, BW_320),
++	EHT_GROUP( 3, EHT_GI_08, BW_320),
++	EHT_GROUP( 4, EHT_GI_08, BW_320),
++	EHT_GROUP( 5, EHT_GI_08, BW_320),
++	EHT_GROUP( 6, EHT_GI_08, BW_320),
++	EHT_GROUP( 7, EHT_GI_08, BW_320),
++	EHT_GROUP( 8, EHT_GI_08, BW_320),
++	EHT_GROUP( 9, EHT_GI_08, BW_320),
++	EHT_GROUP(10, EHT_GI_08, BW_320),
++	EHT_GROUP(11, EHT_GI_08, BW_320),
++	EHT_GROUP(12, EHT_GI_08, BW_320),
++	EHT_GROUP(13, EHT_GI_08, BW_320),
++	EHT_GROUP(14, EHT_GI_08, BW_320),
++	EHT_GROUP(15, EHT_GI_08, BW_320),
++	EHT_GROUP(16, EHT_GI_08, BW_320),
++
++	EHT_GROUP( 1, EHT_GI_16, BW_320),
++	EHT_GROUP( 2, EHT_GI_16, BW_320),
++	EHT_GROUP( 3, EHT_GI_16, BW_320),
++	EHT_GROUP( 4, EHT_GI_16, BW_320),
++	EHT_GROUP( 5, EHT_GI_16, BW_320),
++	EHT_GROUP( 6, EHT_GI_16, BW_320),
++	EHT_GROUP( 7, EHT_GI_16, BW_320),
++	EHT_GROUP( 8, EHT_GI_16, BW_320),
++	EHT_GROUP( 9, EHT_GI_16, BW_320),
++	EHT_GROUP(10, EHT_GI_16, BW_320),
++	EHT_GROUP(11, EHT_GI_16, BW_320),
++	EHT_GROUP(12, EHT_GI_16, BW_320),
++	EHT_GROUP(13, EHT_GI_16, BW_320),
++	EHT_GROUP(14, EHT_GI_16, BW_320),
++	EHT_GROUP(15, EHT_GI_16, BW_320),
++	EHT_GROUP(16, EHT_GI_16, BW_320),
++
++	EHT_GROUP( 1, EHT_GI_32, BW_320),
++	EHT_GROUP( 2, EHT_GI_32, BW_320),
++	EHT_GROUP( 3, EHT_GI_32, BW_320),
++	EHT_GROUP( 4, EHT_GI_32, BW_320),
++	EHT_GROUP( 5, EHT_GI_32, BW_320),
++	EHT_GROUP( 6, EHT_GI_32, BW_320),
++	EHT_GROUP( 7, EHT_GI_32, BW_320),
++	EHT_GROUP( 8, EHT_GI_32, BW_320),
++	EHT_GROUP( 9, EHT_GI_32, BW_320),
++	EHT_GROUP(10, EHT_GI_32, BW_320),
++	EHT_GROUP(11, EHT_GI_32, BW_320),
++	EHT_GROUP(12, EHT_GI_32, BW_320),
++	EHT_GROUP(13, EHT_GI_32, BW_320),
++	EHT_GROUP(14, EHT_GI_32, BW_320),
++	EHT_GROUP(15, EHT_GI_32, BW_320),
++	EHT_GROUP(16, EHT_GI_32, BW_320),
+ };
+ 
+ static u32
+@@ -422,6 +751,9 @@ static u32 ieee80211_get_rate_duration(struct ieee80211_hw *hw,
+ 	case RATE_INFO_BW_160:
+ 		bw = BW_160;
+ 		break;
++	case RATE_INFO_BW_320:
++		bw = BW_320;
++		break;
+ 	default:
+ 		WARN_ON_ONCE(1);
+ 		return 0;
+@@ -443,11 +775,20 @@ static u32 ieee80211_get_rate_duration(struct ieee80211_hw *hw,
+ 		idx = status->rate_idx;
+ 		group = HE_GROUP_IDX(streams, status->he_gi, bw);
+ 		break;
++	case RX_ENC_EHT:
++		streams = status->nss;
++		idx = status->rate_idx;
++		group = EHT_GROUP_IDX(streams, status->he_gi, bw);
++		break;
+ 	default:
+ 		WARN_ON_ONCE(1);
+ 		return 0;
+ 	}
+ 
++	if (WARN_ON_ONCE((status->encoding != RX_ENC_EHT && streams > 8) ||
++			 (status->encoding == RX_ENC_EHT && streams > 16)))
++		return 0;
++
+ 	if (WARN_ON_ONCE((status->encoding != RX_ENC_HE && streams > 4) ||
+ 			 (status->encoding == RX_ENC_HE && streams > 8)))
+ 		return 0;
+@@ -517,7 +858,9 @@ static bool ieee80211_fill_rate_info(struct ieee80211_hw *hw,
+ 	stat->nss = ri->nss;
+ 	stat->rate_idx = ri->mcs;
+ 
+-	if (ri->flags & RATE_INFO_FLAGS_HE_MCS)
++	if (ri->flags & RATE_INFO_FLAGS_EHT_MCS)
++		stat->encoding = RX_ENC_EHT;
++	else if (ri->flags & RATE_INFO_FLAGS_HE_MCS)
+ 		stat->encoding = RX_ENC_HE;
+ 	else if (ri->flags & RATE_INFO_FLAGS_VHT_MCS)
+ 		stat->encoding = RX_ENC_VHT;
+@@ -529,7 +872,7 @@ static bool ieee80211_fill_rate_info(struct ieee80211_hw *hw,
+ 	if (ri->flags & RATE_INFO_FLAGS_SHORT_GI)
+ 		stat->enc_flags |= RX_ENC_FLAG_SHORT_GI;
+ 
+-	stat->he_gi = ri->he_gi;
++	stat->he_gi = (ri->flags & RATE_INFO_FLAGS_EHT_MCS) ? ri->eht_gi : ri->he_gi;
+ 
+ 	if (stat->encoding != RX_ENC_LEGACY)
+ 		return true;
+-- 
+2.18.0
+
diff --git a/autobuild_mac80211_release/mt7988_mt7996_mac80211/package/kernel/mac80211/patches/subsys/9999902-mac80211-mtk-add-EHT-BA1024-support.patch b/autobuild_mac80211_release/mt7988_mt7996_mac80211/package/kernel/mac80211/patches/subsys/9999902-mac80211-mtk-add-EHT-BA1024-support.patch
new file mode 100644
index 0000000..76dd9ef
--- /dev/null
+++ b/autobuild_mac80211_release/mt7988_mt7996_mac80211/package/kernel/mac80211/patches/subsys/9999902-mac80211-mtk-add-EHT-BA1024-support.patch
@@ -0,0 +1,114 @@
+From 85dde30ef0509def7bfec494aef7e5395e656c50 Mon Sep 17 00:00:00 2001
+From: Evelyn Tsai <evelyn.tsai@mediatek.com>
+Date: Sun, 25 Dec 2022 22:43:46 +0800
+Subject: [PATCH 9999902/9999902] mac80211: mtk: add EHT BA1024 support
+
+---
+ include/linux/ieee80211.h |  2 ++
+ net/mac80211/agg-tx.c     | 45 +++++++++++++++++++++++++++++++++++++--
+ 2 files changed, 45 insertions(+), 2 deletions(-)
+
+diff --git a/include/linux/ieee80211.h b/include/linux/ieee80211.h
+index 6f70394..27321f2 100644
+--- a/include/linux/ieee80211.h
++++ b/include/linux/ieee80211.h
+@@ -1270,6 +1270,8 @@ struct ieee80211_mgmt {
+ 					__le16 status;
+ 					__le16 capab;
+ 					__le16 timeout;
++					/* followed by BA Extension */
++					u8 variable[0];
+ 				} __packed addba_resp;
+ 				struct{
+ 					u8 action_code;
+diff --git a/net/mac80211/agg-tx.c b/net/mac80211/agg-tx.c
+index 318c71e..7f750c1 100755
+--- a/net/mac80211/agg-tx.c
++++ b/net/mac80211/agg-tx.c
+@@ -66,10 +66,17 @@ static void ieee80211_send_addba_request(struct ieee80211_sub_if_data *sdata,
+ 	struct ieee80211_local *local = sdata->local;
+ 	struct sk_buff *skb;
+ 	struct ieee80211_mgmt *mgmt;
++	struct ieee80211_addba_ext_ie *addba_ext;
++	u8 *pos;
+ 	u16 capab = 0;
+ 	bool amsdu = ieee80211_hw_check(&local->hw, SUPPORTS_AMSDU_IN_AMPDU);
+ 
+-	skb = dev_alloc_skb(sizeof(*mgmt) + local->hw.extra_tx_headroom);
++	if (agg_size >= 1024)
++		skb = dev_alloc_skb(sizeof(*mgmt) +
++				    2 + sizeof(struct ieee80211_addba_ext_ie) +
++				    local->hw.extra_tx_headroom);
++	else
++		skb = dev_alloc_skb(sizeof(*mgmt) + local->hw.extra_tx_headroom);
+ 
+ 	if (!skb)
+ 		return;
+@@ -108,6 +115,15 @@ static void ieee80211_send_addba_request(struct ieee80211_sub_if_data *sdata,
+ 	mgmt->u.action.u.addba_req.start_seq_num =
+ 					cpu_to_le16(start_seq_num << 4);
+ 
++	if (agg_size >= 1024 ) {
++		pos = skb_put_zero(skb, 2 + sizeof(struct ieee80211_addba_ext_ie));
++		*pos++ = WLAN_EID_ADDBA_EXT;
++		*pos++ = sizeof(struct ieee80211_addba_ext_ie);
++		addba_ext = (struct ieee80211_addba_ext_ie *)pos;
++		addba_ext->data = u8_encode_bits(agg_size >> IEEE80211_ADDBA_EXT_BUF_SIZE_SHIFT,
++						 IEEE80211_ADDBA_EXT_BUF_SIZE_MASK);
++	}
++
+ 	ieee80211_tx_skb_tid(sdata, skb, tid, -1);
+ }
+ 
+@@ -469,8 +485,11 @@ static void ieee80211_send_addba_with_timeout(struct sta_info *sta,
+ 	sta->ampdu_mlme.addba_req_num[tid]++;
+ 	spin_unlock_bh(&sta->lock);
+ 
+-	if (sta->sta.deflink.he_cap.has_he) {
++	if (sta->sta.deflink.eht_cap.has_eht) {
+ 		buf_size = local->hw.max_tx_aggregation_subframes;
++	} else if (sta->sta.deflink.he_cap.has_he) {
++		buf_size = min_t(u16, local->hw.max_tx_aggregation_subframes,
++				 IEEE80211_MAX_AMPDU_BUF_HE);
+ 	} else {
+ 		/*
+ 		 * We really should use what the driver told us it will
+@@ -960,13 +979,35 @@ void ieee80211_process_addba_resp(struct ieee80211_local *local,
+ {
+ 	struct tid_ampdu_tx *tid_tx;
+ 	struct ieee80211_txq *txq;
++	struct ieee802_11_elems *elems;
+ 	u16 capab, tid, buf_size;
+ 	bool amsdu;
++	int ext_ie_len;
+ 
+ 	capab = le16_to_cpu(mgmt->u.action.u.addba_resp.capab);
+ 	amsdu = capab & IEEE80211_ADDBA_PARAM_AMSDU_MASK;
+ 	tid = u16_get_bits(capab, IEEE80211_ADDBA_PARAM_TID_MASK);
+ 	buf_size = u16_get_bits(capab, IEEE80211_ADDBA_PARAM_BUF_SIZE_MASK);
++	ext_ie_len = len - offsetof(struct ieee80211_mgmt,
++				    u.action.u.addba_resp.variable);
++
++	if (ext_ie_len < 0)
++		goto next;
++
++	elems = ieee802_11_parse_elems(mgmt->u.action.u.addba_resp.variable,
++				       ext_ie_len, true, NULL);
++
++	if (elems && !elems->parse_error) {
++		if (sta->sta.deflink.eht_cap.has_eht && elems->addba_ext_ie) {
++			u8 buf_size_1k = u8_get_bits(elems->addba_ext_ie->data,
++						     IEEE80211_ADDBA_EXT_BUF_SIZE_MASK);
++			buf_size |= buf_size_1k << IEEE80211_ADDBA_EXT_BUF_SIZE_SHIFT;
++		}
++	}
++
++	if (elems)
++		kfree(elems);
++next:
+ 	buf_size = min(buf_size, local->hw.max_tx_aggregation_subframes);
+ 
+ 	txq = sta->sta.txq[tid];
+-- 
+2.18.0
+
diff --git a/autobuild_mac80211_release/mt7988_mt7996_mac80211/package/network/services/hostapd/patches/99920-hostapd-add-eht-oper.patch b/autobuild_mac80211_release/mt7988_mt7996_mac80211/package/network/services/hostapd/patches/99920-hostapd-add-eht-oper.patch
new file mode 100644
index 0000000..17363be
--- /dev/null
+++ b/autobuild_mac80211_release/mt7988_mt7996_mac80211/package/network/services/hostapd/patches/99920-hostapd-add-eht-oper.patch
@@ -0,0 +1,51 @@
+From 93b4d02dcb26ba9e655acb00ab2a6e28f9cb4d54 Mon Sep 17 00:00:00 2001
+From: Peter Chiu <chui-hao.chiu@mediatek.com>
+Date: Fri, 30 Sep 2022 00:16:21 +0800
+Subject: [PATCH] hostapd add eht oper
+
+---
+ src/ap/ieee802_11_eht.c      | 5 +++--
+ src/common/ieee802_11_defs.h | 1 +
+ 2 files changed, 4 insertions(+), 2 deletions(-)
+
+diff --git a/src/ap/ieee802_11_eht.c b/src/ap/ieee802_11_eht.c
+index ec36a9e..fc472b8 100644
+--- a/src/ap/ieee802_11_eht.c
++++ b/src/ap/ieee802_11_eht.c
+@@ -183,7 +183,7 @@ u8 * hostapd_eid_eht_operation(struct hostapd_data *hapd, u8 *eid)
+ 		return eid;
+ 
+ 	*pos++ = WLAN_EID_EXTENSION;
+-	*pos++ = 5;
++	*pos++ = 9;
+ 	*pos++ = WLAN_EID_EXT_EHT_OPERATION;
+ 
+ 	oper = (struct ieee80211_eht_operation *) pos;
+@@ -224,10 +224,11 @@ u8 * hostapd_eid_eht_operation(struct hostapd_data *hapd, u8 *eid)
+ 		return eid;
+ 	}
+ 
++	oper->mcs_nss_set = 0x11111111;
+ 	oper->oper_info.ccfs0 = seg0 ? seg0 : hapd->iconf->channel;
+ 	oper->oper_info.ccfs1 = seg1;
+ 
+-	return pos + 4;
++	return pos + 8;
+ }
+ 
+ 
+diff --git a/src/common/ieee802_11_defs.h b/src/common/ieee802_11_defs.h
+index 65e125e..d240b87 100644
+--- a/src/common/ieee802_11_defs.h
++++ b/src/common/ieee802_11_defs.h
+@@ -2432,6 +2432,7 @@ struct ieee80211_eht_oper_info {
+ /* Figure 9-1002a: EHT Operation element format */
+ struct ieee80211_eht_operation {
+ 	u8 oper_params; /* EHT Operation Parameters: EHT_OPER_* bits */
++	le32 mcs_nss_set;
+ 	struct ieee80211_eht_oper_info oper_info; /* 0 or 3 or 5 octets */
+ } STRUCT_PACKED;
+ 
+-- 
+2.18.0
+
diff --git a/autobuild_mac80211_release/package/kernel/mt76/src/firmware/mt7996/mt7996_rom_patch.bin b/autobuild_mac80211_release/package/kernel/mt76/src/firmware/mt7996/mt7996_rom_patch.bin
index 9243dae..6a25364 100644
--- a/autobuild_mac80211_release/package/kernel/mt76/src/firmware/mt7996/mt7996_rom_patch.bin
+++ b/autobuild_mac80211_release/package/kernel/mt76/src/firmware/mt7996/mt7996_rom_patch.bin
Binary files differ
diff --git a/autobuild_mac80211_release/package/kernel/mt76/src/firmware/mt7996/mt7996_wa.bin b/autobuild_mac80211_release/package/kernel/mt76/src/firmware/mt7996/mt7996_wa.bin
index 9541e61..3201bfc 100644
--- a/autobuild_mac80211_release/package/kernel/mt76/src/firmware/mt7996/mt7996_wa.bin
+++ b/autobuild_mac80211_release/package/kernel/mt76/src/firmware/mt7996/mt7996_wa.bin
Binary files differ
diff --git a/autobuild_mac80211_release/package/kernel/mt76/src/firmware/mt7996/mt7996_wm.bin b/autobuild_mac80211_release/package/kernel/mt76/src/firmware/mt7996/mt7996_wm.bin
index 256dd41..4375155 100644
--- a/autobuild_mac80211_release/package/kernel/mt76/src/firmware/mt7996/mt7996_wm.bin
+++ b/autobuild_mac80211_release/package/kernel/mt76/src/firmware/mt7996/mt7996_wm.bin
Binary files differ