[][MAC80211][Rebase Patches][mt76 build fail]
[Description]
Fix MT76 External Build Fail
WiFi7: mt76-2023-05-13-969b7b5e
WiFi6: mt76-2023-06-27-f36b9216
[Release-log]
N/A
Change-Id: I72eb46c8c0d1d12557f127e67e5f7a1599884007
Reviewed-on: https://gerrit.mediatek.inc/c/openwrt/feeds/mtk_openwrt_feeds/+/7682878
diff --git a/autobuild_mac80211_release/mt7988_mt7996_mac80211/package/kernel/mt76/Makefile b/autobuild_mac80211_release/mt7988_mt7996_mac80211/package/kernel/mt76/Makefile
new file mode 100644
index 0000000..04db7fe
--- /dev/null
+++ b/autobuild_mac80211_release/mt7988_mt7996_mac80211/package/kernel/mt76/Makefile
@@ -0,0 +1,574 @@
+include $(TOPDIR)/rules.mk
+
+PKG_NAME:=mt76
+PKG_RELEASE=1
+
+PKG_LICENSE:=GPLv2
+PKG_LICENSE_FILES:=
+
+PKG_SOURCE_URL:=https://github.com/openwrt/mt76
+PKG_SOURCE_PROTO:=git
+PKG_SOURCE_DATE:=2023-05-13
+PKG_SOURCE_VERSION:=969b7b5ebd129068ca56e4b0d831593a2f92382f
+PKG_MIRROR_HASH:=d28869591d1cb9a967b72f5cd8215c7b2c3388b7b31147b7b18c797018ab8ffb
+
+PKG_MAINTAINER:=Felix Fietkau <nbd@nbd.name>
+PKG_USE_NINJA:=0
+PKG_BUILD_PARALLEL:=1
+
+PKG_CONFIG_DEPENDS += \
+ CONFIG_PACKAGE_kmod-mt76-usb \
+ CONFIG_PACKAGE_kmod-mt76x02-common \
+ CONFIG_PACKAGE_kmod-mt76x0-common \
+ CONFIG_PACKAGE_kmod-mt76x0u \
+ CONFIG_PACKAGE_kmod-mt76x2-common \
+ CONFIG_PACKAGE_kmod-mt76x2 \
+ CONFIG_PACKAGE_kmod-mt76x2u \
+ CONFIG_PACKAGE_kmod-mt7603 \
+ CONFIG_PACKAGE_CFG80211_TESTMODE
+
+STAMP_CONFIGURED_DEPENDS := $(STAGING_DIR)/usr/include/mac80211-backport/backport/autoconf.h
+
+include $(INCLUDE_DIR)/kernel.mk
+include $(INCLUDE_DIR)/package.mk
+include $(INCLUDE_DIR)/cmake.mk
+
+CMAKE_SOURCE_DIR:=$(PKG_BUILD_DIR)/tools
+CMAKE_BINARY_DIR:=$(PKG_BUILD_DIR)/tools
+
+define KernelPackage/mt76-default
+ SUBMENU:=Wireless Drivers
+ DEPENDS:= \
+ +kmod-mac80211 \
+ +@DRIVER_11AC_SUPPORT \
+ +@KERNEL_PAGE_POOL
+endef
+
+define KernelPackage/mt76
+ SUBMENU:=Wireless Drivers
+ TITLE:=MediaTek MT76x2/MT7603 wireless driver (metapackage)
+ DEPENDS:= \
+ +kmod-mt76-core +kmod-mt76x2 +kmod-mt7603
+endef
+
+define KernelPackage/mt76-core
+ $(KernelPackage/mt76-default)
+ TITLE:=MediaTek MT76xx wireless driver
+ HIDDEN:=1
+ FILES:=\
+ $(PKG_BUILD_DIR)/mt76.ko
+endef
+
+define KernelPackage/mt76-usb
+ $(KernelPackage/mt76-default)
+ TITLE:=MediaTek MT76xx wireless driver USB support
+ DEPENDS += +kmod-usb-core +kmod-mt76-core
+ HIDDEN:=1
+ FILES:=\
+ $(PKG_BUILD_DIR)/mt76-usb.ko
+endef
+
+define KernelPackage/mt76x02-usb
+ $(KernelPackage/mt76-default)
+ TITLE:=MediaTek MT76x0/MT76x2 USB wireless driver common code
+ DEPENDS+=+kmod-mt76-usb +kmod-mt76x02-common
+ HIDDEN:=1
+ FILES:=$(PKG_BUILD_DIR)/mt76x02-usb.ko
+endef
+
+define KernelPackage/mt76x02-common
+ $(KernelPackage/mt76-default)
+ TITLE:=MediaTek MT76x0/MT76x2 wireless driver common code
+ DEPENDS+=+kmod-mt76-core
+ HIDDEN:=1
+ FILES:=$(PKG_BUILD_DIR)/mt76x02-lib.ko
+endef
+
+define KernelPackage/mt76x0-common
+ $(KernelPackage/mt76-default)
+ TITLE:=MediaTek MT76x0 wireless driver common code
+ DEPENDS+=+kmod-mt76x02-common
+ HIDDEN:=1
+ FILES:=$(PKG_BUILD_DIR)/mt76x0/mt76x0-common.ko
+endef
+
+define KernelPackage/mt76x0e
+ $(KernelPackage/mt76-default)
+ TITLE:=MediaTek MT76x0E wireless driver
+ DEPENDS+=@PCI_SUPPORT +kmod-mt76x0-common
+ FILES:=\
+ $(PKG_BUILD_DIR)/mt76x0/mt76x0e.ko
+ AUTOLOAD:=$(call AutoProbe,mt76x0e)
+endef
+
+define KernelPackage/mt76x0u
+ $(KernelPackage/mt76-default)
+ TITLE:=MediaTek MT76x0U wireless driver
+ DEPENDS+=+kmod-mt76x0-common +kmod-mt76x02-usb
+ FILES:=\
+ $(PKG_BUILD_DIR)/mt76x0/mt76x0u.ko
+ AUTOLOAD:=$(call AutoProbe,mt76x0u)
+endef
+
+define KernelPackage/mt76x2-common
+ $(KernelPackage/mt76-default)
+ TITLE:=MediaTek MT76x2 wireless driver common code
+ DEPENDS+=+kmod-mt76-core +kmod-mt76x02-common
+ HIDDEN:=1
+ FILES:=$(PKG_BUILD_DIR)/mt76x2/mt76x2-common.ko
+endef
+
+define KernelPackage/mt76x2u
+ $(KernelPackage/mt76-default)
+ TITLE:=MediaTek MT76x2U wireless driver
+ DEPENDS+=+kmod-mt76x2-common +kmod-mt76x02-usb
+ FILES:=\
+ $(PKG_BUILD_DIR)/mt76x2/mt76x2u.ko
+ AUTOLOAD:=$(call AutoProbe,mt76x2u)
+endef
+
+define KernelPackage/mt76x2
+ $(KernelPackage/mt76-default)
+ TITLE:=MediaTek MT76x2 wireless driver
+ DEPENDS+=@PCI_SUPPORT +kmod-mt76x2-common
+ FILES:=\
+ $(PKG_BUILD_DIR)/mt76x2/mt76x2e.ko
+ AUTOLOAD:=$(call AutoProbe,mt76x2e)
+endef
+
+define KernelPackage/mt7603
+ $(KernelPackage/mt76-default)
+ TITLE:=MediaTek MT7603 wireless driver
+ DEPENDS+=@PCI_SUPPORT +kmod-mt76-core
+ FILES:=\
+ $(PKG_BUILD_DIR)/mt7603/mt7603e.ko
+ AUTOLOAD:=$(call AutoProbe,mt7603e)
+endef
+
+define KernelPackage/mt76-connac
+ $(KernelPackage/mt76-default)
+ TITLE:=MediaTek MT7615/MT79xx wireless driver common code
+ HIDDEN:=1
+ DEPENDS+=+kmod-mt76-core
+ FILES:= $(PKG_BUILD_DIR)/mt76-connac-lib.ko
+endef
+
+define KernelPackage/mt76-sdio
+ $(KernelPackage/mt76-default)
+ TITLE:=MediaTek MT7615/MT79xx SDIO driver common code
+ HIDDEN:=1
+ DEPENDS+=+kmod-mt76-core +kmod-mmc
+ FILES:= $(PKG_BUILD_DIR)/mt76-sdio.ko
+endef
+
+define KernelPackage/mt7615-common
+ $(KernelPackage/mt76-default)
+ TITLE:=MediaTek MT7615 wireless driver common code
+ HIDDEN:=1
+ DEPENDS+=@PCI_SUPPORT +kmod-mt76-core +kmod-mt76-connac +kmod-hwmon-core
+ FILES:= $(PKG_BUILD_DIR)/mt7615/mt7615-common.ko
+endef
+
+define KernelPackage/mt7615-firmware
+ $(KernelPackage/mt76-default)
+ TITLE:=MediaTek MT7615e firmware
+ DEPENDS+=+kmod-mt7615e
+endef
+
+define KernelPackage/mt7615e
+ $(KernelPackage/mt76-default)
+ TITLE:=MediaTek MT7615e wireless driver
+ DEPENDS+=@PCI_SUPPORT +kmod-mt7615-common
+ FILES:= $(PKG_BUILD_DIR)/mt7615/mt7615e.ko
+ AUTOLOAD:=$(call AutoProbe,mt7615e)
+endef
+
+define KernelPackage/mt7622-firmware
+ $(KernelPackage/mt76-default)
+ TITLE:=MediaTek MT7622 firmware
+ DEPENDS+=+kmod-mt7615e
+endef
+
+define KernelPackage/mt7663-firmware-ap
+ $(KernelPackage/mt76-default)
+ TITLE:=MediaTek MT7663e firmware (optimized for AP)
+endef
+
+define KernelPackage/mt7663-firmware-sta
+ $(KernelPackage/mt76-default)
+ TITLE:=MediaTek MT7663e firmware (client mode offload)
+endef
+
+define KernelPackage/mt7663-usb-sdio
+ $(KernelPackage/mt76-default)
+ TITLE:=MediaTek MT7663 USB/SDIO shared code
+ DEPENDS+=+kmod-mt7615-common
+ HIDDEN:=1
+ FILES:= \
+ $(PKG_BUILD_DIR)/mt7615/mt7663-usb-sdio-common.ko
+endef
+
+define KernelPackage/mt7663s
+ $(KernelPackage/mt76-default)
+ TITLE:=MediaTek MT7663s wireless driver
+ DEPENDS+=+kmod-mt76-sdio +kmod-mt7615-common +kmod-mt7663-usb-sdio
+ FILES:= \
+ $(PKG_BUILD_DIR)/mt7615/mt7663s.ko
+ AUTOLOAD:=$(call AutoProbe,mt7663s)
+endef
+
+define KernelPackage/mt7663u
+ $(KernelPackage/mt76-default)
+ TITLE:=MediaTek MT7663u wireless driver
+ DEPENDS+=+kmod-mt76-usb +kmod-mt7615-common +kmod-mt7663-usb-sdio
+ FILES:= $(PKG_BUILD_DIR)/mt7615/mt7663u.ko
+ AUTOLOAD:=$(call AutoProbe,mt7663u)
+endef
+
+define KernelPackage/mt7915-firmware
+ $(KernelPackage/mt76-default)
+ TITLE:=MediaTek MT7915 firmware
+ DEPENDS+=+kmod-mt7915e
+endef
+
+define KernelPackage/mt7915e
+ $(KernelPackage/mt76-default)
+ TITLE:=MediaTek MT7915e wireless driver
+ DEPENDS+=@PCI_SUPPORT +kmod-mt76-connac +kmod-hwmon-core +kmod-thermal +@DRIVER_11AX_SUPPORT +@KERNEL_RELAY
+ FILES:= $(PKG_BUILD_DIR)/mt7915/mt7915e.ko
+ AUTOLOAD:=$(call AutoProbe,mt7915e)
+endef
+
+define KernelPackage/mt7916-firmware
+ $(KernelPackage/mt76-default)
+ DEPENDS+=+kmod-mt7915e
+ TITLE:=MediaTek MT7916 firmware
+endef
+
+define KernelPackage/mt7981-firmware
+ $(KernelPackage/mt76-default)
+ DEPENDS:=@TARGET_mediatek_filogic
+ TITLE:=MediaTek MT7981 firmware
+endef
+
+define KernelPackage/mt7986-firmware
+ $(KernelPackage/mt76-default)
+ DEPENDS:=@TARGET_mediatek_filogic
+ TITLE:=MediaTek MT7986 firmware
+endef
+
+define KernelPackage/mt7921-firmware
+ $(KernelPackage/mt76-default)
+ TITLE:=MediaTek MT7921 firmware
+endef
+
+define KernelPackage/mt7921-common
+ $(KernelPackage/mt76-default)
+ TITLE:=MediaTek MT7615 wireless driver common code
+ HIDDEN:=1
+ DEPENDS+=+kmod-mt76-connac +kmod-mt7921-firmware +@DRIVER_11AX_SUPPORT
+ FILES:= $(PKG_BUILD_DIR)/mt7921/mt7921-common.ko
+endef
+
+define KernelPackage/mt7921u
+ $(KernelPackage/mt76-default)
+ TITLE:=MediaTek MT7921U wireless driver
+ DEPENDS+=+kmod-mt76-usb +kmod-mt7921-common
+ FILES:= $(PKG_BUILD_DIR)/mt7921/mt7921u.ko
+ AUTOLOAD:=$(call AutoProbe,mt7921u)
+endef
+
+define KernelPackage/mt7921s
+ $(KernelPackage/mt76-default)
+ TITLE:=MediaTek MT7921S wireless driver
+ DEPENDS+=+kmod-mt76-sdio +kmod-mt7921-common
+ FILES:= $(PKG_BUILD_DIR)/mt7921/mt7921s.ko
+ AUTOLOAD:=$(call AutoProbe,mt7921s)
+endef
+
+define KernelPackage/mt7921e
+ $(KernelPackage/mt76-default)
+ TITLE:=MediaTek MT7921e wireless driver
+ DEPENDS+=@PCI_SUPPORT +kmod-mt7921-common
+ FILES:= $(PKG_BUILD_DIR)/mt7921/mt7921e.ko
+ AUTOLOAD:=$(call AutoProbe,mt7921e)
+endef
+
+define Package/mt76-test
+ SECTION:=devel
+ CATEGORY:=Development
+ TITLE:=mt76 testmode CLI
+ DEPENDS:=kmod-mt76-core +libnl-tiny
+endef
+
+TARGET_CFLAGS += -I$(STAGING_DIR)/usr/include/libnl-tiny
+
+NOSTDINC_FLAGS := \
+ $(KERNEL_NOSTDINC_FLAGS) \
+ -I$(PKG_BUILD_DIR) \
+ -I$(STAGING_DIR)/usr/include/mac80211-backport/uapi \
+ -I$(STAGING_DIR)/usr/include/mac80211-backport \
+ -I$(STAGING_DIR)/usr/include/mac80211/uapi \
+ -I$(STAGING_DIR)/usr/include/mac80211 \
+ -include backport/autoconf.h \
+ -include backport/backport.h
+
+ifdef CONFIG_PACKAGE_MAC80211_MESH
+ NOSTDINC_FLAGS += -DCONFIG_MAC80211_MESH
+endif
+
+ifdef CONFIG_PACKAGE_CFG80211_TESTMODE
+ NOSTDINC_FLAGS += -DCONFIG_NL80211_TESTMODE
+ PKG_MAKE_FLAGS += CONFIG_NL80211_TESTMODE=y
+endif
+
+ifdef CONFIG_PACKAGE_kmod-mt76-usb
+ PKG_MAKE_FLAGS += CONFIG_MT76_USB=m
+endif
+ifdef CONFIG_PACKAGE_kmod-mt76x02-common
+ PKG_MAKE_FLAGS += CONFIG_MT76x02_LIB=m
+endif
+ifdef CONFIG_PACKAGE_kmod-mt76x02-usb
+ PKG_MAKE_FLAGS += CONFIG_MT76x02_USB=m
+endif
+ifdef CONFIG_PACKAGE_kmod-mt76x0-common
+ PKG_MAKE_FLAGS += CONFIG_MT76x0_COMMON=m
+endif
+ifdef CONFIG_PACKAGE_kmod-mt76x0e
+ PKG_MAKE_FLAGS += CONFIG_MT76x0E=m
+endif
+ifdef CONFIG_PACKAGE_kmod-mt76x0u
+ PKG_MAKE_FLAGS += CONFIG_MT76x0U=m
+endif
+ifdef CONFIG_PACKAGE_kmod-mt76x2-common
+ PKG_MAKE_FLAGS += CONFIG_MT76x2_COMMON=m
+endif
+ifdef CONFIG_PACKAGE_kmod-mt76x2
+ PKG_MAKE_FLAGS += CONFIG_MT76x2E=m
+endif
+ifdef CONFIG_PACKAGE_kmod-mt76x2u
+ PKG_MAKE_FLAGS += CONFIG_MT76x2U=m
+endif
+ifdef CONFIG_PACKAGE_kmod-mt7603
+ PKG_MAKE_FLAGS += CONFIG_MT7603E=m
+endif
+ifdef CONFIG_PACKAGE_kmod-mt76-connac
+ PKG_MAKE_FLAGS += CONFIG_MT76_CONNAC_LIB=m
+endif
+ifdef CONFIG_PACKAGE_kmod-mt76-sdio
+ PKG_MAKE_FLAGS += CONFIG_MT76_SDIO=m
+endif
+ifdef CONFIG_PACKAGE_kmod-mt7615-common
+ PKG_MAKE_FLAGS += CONFIG_MT7615_COMMON=m
+endif
+ifdef CONFIG_PACKAGE_kmod-mt7615e
+ PKG_MAKE_FLAGS += CONFIG_MT7615E=m
+ ifdef CONFIG_TARGET_mediatek_mt7622
+ PKG_MAKE_FLAGS += CONFIG_MT7622_WMAC=y
+ NOSTDINC_FLAGS += -DCONFIG_MT7622_WMAC
+ endif
+endif
+ifdef CONFIG_PACKAGE_kmod-mt7663-usb-sdio
+ PKG_MAKE_FLAGS += CONFIG_MT7663_USB_SDIO_COMMON=m
+endif
+ifdef CONFIG_PACKAGE_kmod-mt7663s
+ PKG_MAKE_FLAGS += CONFIG_MT7663S=m
+endif
+ifdef CONFIG_PACKAGE_kmod-mt7663u
+ PKG_MAKE_FLAGS += CONFIG_MT7663U=m
+endif
+ifdef CONFIG_PACKAGE_kmod-mt7915e
+ PKG_MAKE_FLAGS += CONFIG_MT7915E=m
+ ifdef CONFIG_TARGET_mediatek_filogic
+ PKG_MAKE_FLAGS += CONFIG_MT798X_WMAC=y
+ NOSTDINC_FLAGS += -DCONFIG_MT798X_WMAC
+ endif
+endif
+ifdef CONFIG_PACKAGE_kmod-mt7921-common
+ PKG_MAKE_FLAGS += CONFIG_MT7921_COMMON=m
+endif
+ifdef CONFIG_PACKAGE_kmod-mt7921u
+ PKG_MAKE_FLAGS += CONFIG_MT7921U=m
+endif
+ifdef CONFIG_PACKAGE_kmod-mt7921s
+ PKG_MAKE_FLAGS += CONFIG_MT7921S=m
+endif
+ifdef CONFIG_PACKAGE_kmod-mt7921e
+ PKG_MAKE_FLAGS += CONFIG_MT7921E=m
+endif
+
+define Build/Compile
+ +$(KERNEL_MAKE) $(PKG_JOBS) \
+ $(PKG_MAKE_FLAGS) \
+ M="$(PKG_BUILD_DIR)" \
+ NOSTDINC_FLAGS="$(NOSTDINC_FLAGS)" \
+ modules
+ $(MAKE) -C $(PKG_BUILD_DIR)/tools
+endef
+
+define Build/Install
+ :
+endef
+
+define Package/kmod-mt76/install
+ true
+endef
+
+define KernelPackage/mt76x0-common/install
+ $(INSTALL_DIR) $(1)/lib/firmware/mediatek
+ cp \
+ $(PKG_BUILD_DIR)/firmware/mt7610e.bin \
+ $(1)/lib/firmware/mediatek
+endef
+
+define KernelPackage/mt76x2-common/install
+ $(INSTALL_DIR) $(1)/lib/firmware
+ cp \
+ $(PKG_BUILD_DIR)/firmware/mt7662_rom_patch.bin \
+ $(PKG_BUILD_DIR)/firmware/mt7662.bin \
+ $(1)/lib/firmware
+endef
+
+define KernelPackage/mt76x0u/install
+ $(INSTALL_DIR) $(1)/lib/firmware/mediatek
+ ln -sf mt7610e.bin $(1)/lib/firmware/mediatek/mt7610u.bin
+endef
+
+define KernelPackage/mt76x2u/install
+ $(INSTALL_DIR) $(1)/lib/firmware/mediatek
+ ln -sf ../mt7662.bin $(1)/lib/firmware/mediatek/mt7662u.bin
+ ln -sf ../mt7662_rom_patch.bin $(1)/lib/firmware/mediatek/mt7662u_rom_patch.bin
+endef
+
+define KernelPackage/mt7603/install
+ $(INSTALL_DIR) $(1)/lib/firmware
+ cp $(if $(CONFIG_TARGET_ramips_mt76x8), \
+ $(PKG_BUILD_DIR)/firmware/mt7628_e1.bin \
+ $(PKG_BUILD_DIR)/firmware/mt7628_e2.bin \
+ ,\
+ $(PKG_BUILD_DIR)/firmware/mt7603_e1.bin \
+ $(PKG_BUILD_DIR)/firmware/mt7603_e2.bin \
+ ) \
+ $(1)/lib/firmware
+endef
+
+define KernelPackage/mt7615-firmware/install
+ $(INSTALL_DIR) $(1)/lib/firmware/mediatek
+ cp \
+ $(PKG_BUILD_DIR)/firmware/mt7615_cr4.bin \
+ $(PKG_BUILD_DIR)/firmware/mt7615_n9.bin \
+ $(PKG_BUILD_DIR)/firmware/mt7615_rom_patch.bin \
+ $(1)/lib/firmware/mediatek
+endef
+
+define KernelPackage/mt7622-firmware/install
+ $(INSTALL_DIR) $(1)/lib/firmware/mediatek
+ cp \
+ $(PKG_BUILD_DIR)/firmware/mt7622_n9.bin \
+ $(PKG_BUILD_DIR)/firmware/mt7622_rom_patch.bin \
+ $(1)/lib/firmware/mediatek
+endef
+
+define KernelPackage/mt7663-firmware-ap/install
+ $(INSTALL_DIR) $(1)/lib/firmware/mediatek
+ cp \
+ $(PKG_BUILD_DIR)/firmware/mt7663_n9_rebb.bin \
+ $(PKG_BUILD_DIR)/firmware/mt7663pr2h_rebb.bin \
+ $(1)/lib/firmware/mediatek
+endef
+
+define KernelPackage/mt7663-firmware-sta/install
+ $(INSTALL_DIR) $(1)/lib/firmware/mediatek
+ cp \
+ $(PKG_BUILD_DIR)/firmware/mt7663_n9_v3.bin \
+ $(PKG_BUILD_DIR)/firmware/mt7663pr2h.bin \
+ $(1)/lib/firmware/mediatek
+endef
+
+define KernelPackage/mt7915-firmware/install
+ $(INSTALL_DIR) $(1)/lib/firmware/mediatek
+ cp \
+ $(PKG_BUILD_DIR)/firmware/mt7915_wa.bin \
+ $(PKG_BUILD_DIR)/firmware/mt7915_wm.bin \
+ $(PKG_BUILD_DIR)/firmware/mt7915_rom_patch.bin \
+ $(1)/lib/firmware/mediatek
+endef
+
+define KernelPackage/mt7916-firmware/install
+ $(INSTALL_DIR) $(1)/lib/firmware/mediatek
+ cp \
+ $(PKG_BUILD_DIR)/firmware/mt7916_wa.bin \
+ $(PKG_BUILD_DIR)/firmware/mt7916_wm.bin \
+ $(PKG_BUILD_DIR)/firmware/mt7916_rom_patch.bin \
+ $(1)/lib/firmware/mediatek
+endef
+
+define KernelPackage/mt7981-firmware/install
+ $(INSTALL_DIR) $(1)/lib/firmware/mediatek
+ cp \
+ $(PKG_BUILD_DIR)/firmware/mt7981_wa.bin \
+ $(PKG_BUILD_DIR)/firmware/mt7981_wm.bin \
+ $(PKG_BUILD_DIR)/firmware/mt7981_rom_patch.bin \
+ $(1)/lib/firmware/mediatek
+endef
+
+define KernelPackage/mt7986-firmware/install
+ $(INSTALL_DIR) $(1)/lib/firmware/mediatek
+ cp \
+ $(PKG_BUILD_DIR)/firmware/mt7986_wa.bin \
+ $(PKG_BUILD_DIR)/firmware/mt7986_wm_mt7975.bin \
+ $(PKG_BUILD_DIR)/firmware/mt7986_wm.bin \
+ $(PKG_BUILD_DIR)/firmware/mt7986_rom_patch_mt7975.bin \
+ $(PKG_BUILD_DIR)/firmware/mt7986_rom_patch.bin \
+ $(PKG_BUILD_DIR)/firmware/mt7986_eeprom_mt7975_dual.bin \
+ $(PKG_BUILD_DIR)/firmware/mt7986_eeprom_mt7976_dual.bin \
+ $(1)/lib/firmware/mediatek
+endef
+
+define KernelPackage/mt7921-firmware/install
+ $(INSTALL_DIR) $(1)/lib/firmware/mediatek
+ cp \
+ $(PKG_BUILD_DIR)/firmware/WIFI_MT7961_patch_mcu_1_2_hdr.bin \
+ $(PKG_BUILD_DIR)/firmware/WIFI_RAM_CODE_MT7961_1.bin \
+ $(1)/lib/firmware/mediatek
+endef
+
+define Package/mt76-test/install
+ mkdir -p $(1)/usr/sbin
+ $(INSTALL_BIN) $(PKG_BUILD_DIR)/tools/mt76-test $(1)/usr/sbin
+endef
+
+$(eval $(call KernelPackage,mt76-core))
+$(eval $(call KernelPackage,mt76-usb))
+$(eval $(call KernelPackage,mt76x02-usb))
+$(eval $(call KernelPackage,mt76x02-common))
+$(eval $(call KernelPackage,mt76x0-common))
+$(eval $(call KernelPackage,mt76x0e))
+$(eval $(call KernelPackage,mt76x0u))
+$(eval $(call KernelPackage,mt76x2-common))
+$(eval $(call KernelPackage,mt76x2u))
+$(eval $(call KernelPackage,mt76x2))
+$(eval $(call KernelPackage,mt7603))
+$(eval $(call KernelPackage,mt76-connac))
+$(eval $(call KernelPackage,mt76-sdio))
+$(eval $(call KernelPackage,mt7615-common))
+$(eval $(call KernelPackage,mt7615-firmware))
+$(eval $(call KernelPackage,mt7622-firmware))
+$(eval $(call KernelPackage,mt7615e))
+$(eval $(call KernelPackage,mt7663-firmware-ap))
+$(eval $(call KernelPackage,mt7663-firmware-sta))
+$(eval $(call KernelPackage,mt7663-usb-sdio))
+$(eval $(call KernelPackage,mt7663u))
+$(eval $(call KernelPackage,mt7663s))
+$(eval $(call KernelPackage,mt7915-firmware))
+$(eval $(call KernelPackage,mt7915e))
+$(eval $(call KernelPackage,mt7916-firmware))
+$(eval $(call KernelPackage,mt7981-firmware))
+$(eval $(call KernelPackage,mt7986-firmware))
+$(eval $(call KernelPackage,mt7921-firmware))
+$(eval $(call KernelPackage,mt7921-common))
+$(eval $(call KernelPackage,mt7921u))
+$(eval $(call KernelPackage,mt7921s))
+$(eval $(call KernelPackage,mt7921e))
+$(eval $(call KernelPackage,mt76))
+$(eval $(call BuildPackage,mt76-test))
diff --git a/autobuild_mac80211_release/package/kernel/mt76/patches/0000-sync-to-master-codebase.patch b/autobuild_mac80211_release/package/kernel/mt76/patches/0000-sync-to-master-codebase.patch
deleted file mode 100644
index 1ee1534..0000000
--- a/autobuild_mac80211_release/package/kernel/mt76/patches/0000-sync-to-master-codebase.patch
+++ /dev/null
@@ -1,5882 +0,0 @@
-From d10be7604c55c961bd06a2e4aaeff1baf4fda24a Mon Sep 17 00:00:00 2001
-From: Lorenzo Bianconi <lorenzo@kernel.org>
-Date: Wed, 24 May 2023 16:39:32 +0200
-Subject: [PATCH] sync to master codebase
-
----
- Makefile | 2 +-
- dma.c | 6 +
- mac80211.c | 6 +
- mt76.h | 106 ++++++-
- mt7603/init.c | 2 -
- mt7603/mac.c | 22 +-
- mt7603/main.c | 20 +-
- mt7603/mt7603.h | 4 -
- mt7615/init.c | 4 +-
- mt7615/mac.c | 30 +-
- mt7615/main.c | 49 +++-
- mt7615/mt7615.h | 4 -
- mt7615/regs.h | 9 +
- mt76_connac.h | 10 +-
- mt76_connac2_mac.h | 4 +-
- mt76_connac3_mac.c | 182 ++++++++++++
- mt76_connac3_mac.h | 325 +++++++++++++++++++++
- mt76_connac_mac.c | 109 ++++++-
- mt76_connac_mcu.c | 3 +
- mt76_connac_mcu.h | 6 +-
- mt76x02_util.c | 13 -
- mt7915/debugfs.c | 128 ++++----
- mt7915/dma.c | 148 +++++-----
- mt7915/init.c | 12 +-
- mt7915/mac.c | 192 +++++-------
- mt7915/mac.h | 7 +-
- mt7915/main.c | 184 +++++++++---
- mt7915/mcu.c | 119 +++++++-
- mt7915/mmio.c | 34 +--
- mt7915/mt7915.h | 74 +----
- mt7915/regs.h | 3 +
- mt7915/soc.c | 53 ++--
- mt7921/debugfs.c | 2 +-
- mt7921/dma.c | 10 +-
- mt7921/init.c | 72 ++++-
- mt7921/mac.c | 118 +++-----
- mt7921/main.c | 42 ++-
- mt7921/mcu.c | 25 +-
- mt7921/mt7921.h | 43 +--
- mt7921/pci.c | 10 +-
- mt7921/pci_mac.c | 16 +-
- mt7921/regs.h | 1 -
- mt7921/usb.c | 3 +
- mt7996/debugfs.c | 4 +-
- mt7996/dma.c | 83 +++---
- mt7996/init.c | 5 +-
- mt7996/mac.c | 317 +++++---------------
- mt7996/mac.h | 315 +-------------------
- mt7996/main.c | 114 +++++---
- mt7996/mcu.c | 182 +++++++++---
- mt7996/mcu.h | 17 ++
- mt7996/mt7996.h | 80 +----
- mt7996/pci.c | 1 +
- mt7996/regs.h | 21 +-
- tx.c | 16 +-
- 59 files changed, 1908 insertions(+), 1459 deletions(-)
- create mode 100644 mt76_connac3_mac.c
- create mode 100644 mt76_connac3_mac.h
-
-diff --git a/Makefile b/Makefile
-index 9c287cf4..f9b94280 100644
---- a/Makefile
-+++ b/Makefile
-@@ -28,7 +28,7 @@ mt76x02-lib-y := mt76x02_util.o mt76x02_mac.o mt76x02_mcu.o \
-
- mt76x02-usb-y := mt76x02_usb_mcu.o mt76x02_usb_core.o
-
--mt76-connac-lib-y := mt76_connac_mcu.o mt76_connac_mac.o
-+mt76-connac-lib-y := mt76_connac_mcu.o mt76_connac_mac.o mt76_connac3_mac.o
-
- obj-$(CONFIG_MT76x0_COMMON) += mt76x0/
- obj-$(CONFIG_MT76x2_COMMON) += mt76x2/
-diff --git a/dma.c b/dma.c
-index 465190eb..05d9ab3c 100644
---- a/dma.c
-+++ b/dma.c
-@@ -466,6 +466,9 @@ mt76_dma_tx_queue_skb_raw(struct mt76_dev *dev, struct mt76_queue *q,
- struct mt76_queue_buf buf = {};
- dma_addr_t addr;
-
-+ if (test_bit(MT76_MCU_RESET, &dev->phy.state))
-+ goto error;
-+
- if (q->queued + 1 >= q->ndesc - 1)
- goto error;
-
-@@ -507,6 +510,9 @@ mt76_dma_tx_queue_skb(struct mt76_dev *dev, struct mt76_queue *q,
- dma_addr_t addr;
- u8 *txwi;
-
-+ if (test_bit(MT76_RESET, &dev->phy.state))
-+ goto free_skb;
-+
- t = mt76_get_txwi(dev);
- if (!t)
- goto free_skb;
-diff --git a/mac80211.c b/mac80211.c
-index 2c4a5290..85407387 100644
---- a/mac80211.c
-+++ b/mac80211.c
-@@ -76,6 +76,7 @@ static const struct ieee80211_channel mt76_channels_5ghz[] = {
- CHAN5G(165, 5825),
- CHAN5G(169, 5845),
- CHAN5G(173, 5865),
-+ CHAN5G(177, 5885),
- };
-
- static const struct ieee80211_channel mt76_channels_6ghz[] = {
-@@ -660,6 +661,8 @@ mt76_alloc_device(struct device *pdev, unsigned int size,
- idr_init(&dev->rx_token);
-
- INIT_LIST_HEAD(&dev->wcid_list);
-+ INIT_LIST_HEAD(&dev->sta_poll_list);
-+ spin_lock_init(&dev->sta_poll_lock);
-
- INIT_LIST_HEAD(&dev->txwi_cache);
- INIT_LIST_HEAD(&dev->rxwi_cache);
-@@ -1738,6 +1741,9 @@ void mt76_ethtool_worker(struct mt76_ethtool_worker_info *wi,
- for (i = 0; i < (eht ? 14 : 12); i++)
- data[ei++] += stats->tx_mcs[i];
-
-+ for (i = 0; i < 4; i++)
-+ data[ei++] += stats->tx_nss[i];
-+
- wi->worker_stat_count = ei - wi->initial_stat_idx;
- }
- EXPORT_SYMBOL_GPL(mt76_ethtool_worker);
-diff --git a/mt76.h b/mt76.h
-index 8b4635e9..034ab90c 100644
---- a/mt76.h
-+++ b/mt76.h
-@@ -277,7 +277,7 @@ struct mt76_sta_stats {
- u64 tx_mcs[16]; /* mcs idx */
- u64 tx_bytes;
- /* WED TX */
-- u32 tx_packets;
-+ u32 tx_packets; /* unit: MSDU */
- u32 tx_retries;
- u32 tx_failed;
- /* WED RX */
-@@ -316,6 +316,7 @@ struct mt76_wcid {
- int inactive_count;
-
- struct rate_info rate;
-+ unsigned long ampdu_state;
-
- u16 idx;
- u8 hw_key_idx;
-@@ -336,6 +337,8 @@ struct mt76_wcid {
- struct idr pktid;
-
- struct mt76_sta_stats stats;
-+
-+ struct list_head poll_list;
- };
-
- struct mt76_txq {
-@@ -692,6 +695,9 @@ struct mt76_vif {
- u8 wmm_idx;
- u8 scan_seq_num;
- u8 cipher;
-+ u8 basic_rates_idx;
-+ u8 mcast_rates_idx;
-+ u8 beacon_rates_idx;
- };
-
- struct mt76_phy {
-@@ -813,6 +819,9 @@ struct mt76_dev {
- struct mt76_wcid __rcu *wcid[MT76_N_WCIDS];
- struct list_head wcid_list;
-
-+ struct list_head sta_poll_list;
-+ spinlock_t sta_poll_lock;
-+
- u32 rev;
-
- struct tasklet_struct pre_tbtt_tasklet;
-@@ -847,6 +856,101 @@ struct mt76_dev {
- };
- };
-
-+/* per-phy stats. */
-+struct mt76_mib_stats {
-+ u32 ack_fail_cnt;
-+ u32 fcs_err_cnt;
-+ u32 rts_cnt;
-+ u32 rts_retries_cnt;
-+ u32 ba_miss_cnt;
-+ u32 tx_bf_cnt;
-+ u32 tx_mu_bf_cnt;
-+ u32 tx_mu_mpdu_cnt;
-+ u32 tx_mu_acked_mpdu_cnt;
-+ u32 tx_su_acked_mpdu_cnt;
-+ u32 tx_bf_ibf_ppdu_cnt;
-+ u32 tx_bf_ebf_ppdu_cnt;
-+
-+ u32 tx_bf_rx_fb_all_cnt;
-+ u32 tx_bf_rx_fb_eht_cnt;
-+ u32 tx_bf_rx_fb_he_cnt;
-+ u32 tx_bf_rx_fb_vht_cnt;
-+ u32 tx_bf_rx_fb_ht_cnt;
-+
-+ u32 tx_bf_rx_fb_bw; /* value of last sample, not cumulative */
-+ u32 tx_bf_rx_fb_nc_cnt;
-+ u32 tx_bf_rx_fb_nr_cnt;
-+ u32 tx_bf_fb_cpl_cnt;
-+ u32 tx_bf_fb_trig_cnt;
-+
-+ u32 tx_ampdu_cnt;
-+ u32 tx_stop_q_empty_cnt;
-+ u32 tx_mpdu_attempts_cnt;
-+ u32 tx_mpdu_success_cnt;
-+ u32 tx_pkt_ebf_cnt;
-+ u32 tx_pkt_ibf_cnt;
-+
-+ u32 tx_rwp_fail_cnt;
-+ u32 tx_rwp_need_cnt;
-+
-+ /* rx stats */
-+ u32 rx_fifo_full_cnt;
-+ u32 channel_idle_cnt;
-+ u32 primary_cca_busy_time;
-+ u32 secondary_cca_busy_time;
-+ u32 primary_energy_detect_time;
-+ u32 cck_mdrdy_time;
-+ u32 ofdm_mdrdy_time;
-+ u32 green_mdrdy_time;
-+ u32 rx_vector_mismatch_cnt;
-+ u32 rx_delimiter_fail_cnt;
-+ u32 rx_mrdy_cnt;
-+ u32 rx_len_mismatch_cnt;
-+ u32 rx_mpdu_cnt;
-+ u32 rx_ampdu_cnt;
-+ u32 rx_ampdu_bytes_cnt;
-+ u32 rx_ampdu_valid_subframe_cnt;
-+ u32 rx_ampdu_valid_subframe_bytes_cnt;
-+ u32 rx_pfdrop_cnt;
-+ u32 rx_vec_queue_overflow_drop_cnt;
-+ u32 rx_ba_cnt;
-+
-+ u32 tx_amsdu[8];
-+ u32 tx_amsdu_cnt;
-+
-+ /* mcu_muru_stats */
-+ u32 dl_cck_cnt;
-+ u32 dl_ofdm_cnt;
-+ u32 dl_htmix_cnt;
-+ u32 dl_htgf_cnt;
-+ u32 dl_vht_su_cnt;
-+ u32 dl_vht_2mu_cnt;
-+ u32 dl_vht_3mu_cnt;
-+ u32 dl_vht_4mu_cnt;
-+ u32 dl_he_su_cnt;
-+ u32 dl_he_ext_su_cnt;
-+ u32 dl_he_2ru_cnt;
-+ u32 dl_he_2mu_cnt;
-+ u32 dl_he_3ru_cnt;
-+ u32 dl_he_3mu_cnt;
-+ u32 dl_he_4ru_cnt;
-+ u32 dl_he_4mu_cnt;
-+ u32 dl_he_5to8ru_cnt;
-+ u32 dl_he_9to16ru_cnt;
-+ u32 dl_he_gtr16ru_cnt;
-+
-+ u32 ul_hetrig_su_cnt;
-+ u32 ul_hetrig_2ru_cnt;
-+ u32 ul_hetrig_3ru_cnt;
-+ u32 ul_hetrig_4ru_cnt;
-+ u32 ul_hetrig_5to8ru_cnt;
-+ u32 ul_hetrig_9to16ru_cnt;
-+ u32 ul_hetrig_gtr16ru_cnt;
-+ u32 ul_hetrig_2mu_cnt;
-+ u32 ul_hetrig_3mu_cnt;
-+ u32 ul_hetrig_4mu_cnt;
-+};
-+
- struct mt76_power_limits {
- s8 cck[4];
- s8 ofdm[8];
-diff --git a/mt7603/init.c b/mt7603/init.c
-index 9a2e632d..0762de3c 100644
---- a/mt7603/init.c
-+++ b/mt7603/init.c
-@@ -500,8 +500,6 @@ int mt7603_register_device(struct mt7603_dev *dev)
- bus_ops->rmw = mt7603_rmw;
- dev->mt76.bus = bus_ops;
-
-- INIT_LIST_HEAD(&dev->sta_poll_list);
-- spin_lock_init(&dev->sta_poll_lock);
- spin_lock_init(&dev->ps_lock);
-
- INIT_DELAYED_WORK(&dev->mphy.mac_work, mt7603_mac_work);
-diff --git a/mt7603/mac.c b/mt7603/mac.c
-index 12e0af52..de11557e 100644
---- a/mt7603/mac.c
-+++ b/mt7603/mac.c
-@@ -412,16 +412,16 @@ void mt7603_mac_sta_poll(struct mt7603_dev *dev)
- while (1) {
- bool clear = false;
-
-- spin_lock_bh(&dev->sta_poll_lock);
-- if (list_empty(&dev->sta_poll_list)) {
-- spin_unlock_bh(&dev->sta_poll_lock);
-+ spin_lock_bh(&dev->mt76.sta_poll_lock);
-+ if (list_empty(&dev->mt76.sta_poll_list)) {
-+ spin_unlock_bh(&dev->mt76.sta_poll_lock);
- break;
- }
-
-- msta = list_first_entry(&dev->sta_poll_list, struct mt7603_sta,
-- poll_list);
-- list_del_init(&msta->poll_list);
-- spin_unlock_bh(&dev->sta_poll_lock);
-+ msta = list_first_entry(&dev->mt76.sta_poll_list,
-+ struct mt7603_sta, wcid.poll_list);
-+ list_del_init(&msta->wcid.poll_list);
-+ spin_unlock_bh(&dev->mt76.sta_poll_lock);
-
- addr = mt7603_wtbl4_addr(msta->wcid.idx);
- for (i = 0; i < 4; i++) {
-@@ -1267,10 +1267,10 @@ void mt7603_mac_add_txs(struct mt7603_dev *dev, void *data)
- msta = container_of(wcid, struct mt7603_sta, wcid);
- sta = wcid_to_sta(wcid);
-
-- if (list_empty(&msta->poll_list)) {
-- spin_lock_bh(&dev->sta_poll_lock);
-- list_add_tail(&msta->poll_list, &dev->sta_poll_list);
-- spin_unlock_bh(&dev->sta_poll_lock);
-+ if (list_empty(&msta->wcid.poll_list)) {
-+ spin_lock_bh(&dev->mt76.sta_poll_lock);
-+ list_add_tail(&msta->wcid.poll_list, &dev->mt76.sta_poll_list);
-+ spin_unlock_bh(&dev->mt76.sta_poll_lock);
- }
-
- if (mt7603_mac_add_txs_skb(dev, msta, pid, txs_data))
-diff --git a/mt7603/main.c b/mt7603/main.c
-index 1b1358c6..1d489341 100644
---- a/mt7603/main.c
-+++ b/mt7603/main.c
-@@ -66,7 +66,7 @@ mt7603_add_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif)
-
- idx = MT7603_WTBL_RESERVED - 1 - mvif->idx;
- dev->mt76.vif_mask |= BIT_ULL(mvif->idx);
-- INIT_LIST_HEAD(&mvif->sta.poll_list);
-+ INIT_LIST_HEAD(&mvif->sta.wcid.poll_list);
- mvif->sta.wcid.idx = idx;
- mvif->sta.wcid.hw_key_idx = -1;
- mt76_packet_id_init(&mvif->sta.wcid);
-@@ -100,10 +100,10 @@ mt7603_remove_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif)
-
- rcu_assign_pointer(dev->mt76.wcid[idx], NULL);
-
-- spin_lock_bh(&dev->sta_poll_lock);
-- if (!list_empty(&msta->poll_list))
-- list_del_init(&msta->poll_list);
-- spin_unlock_bh(&dev->sta_poll_lock);
-+ spin_lock_bh(&dev->mt76.sta_poll_lock);
-+ if (!list_empty(&msta->wcid.poll_list))
-+ list_del_init(&msta->wcid.poll_list);
-+ spin_unlock_bh(&dev->mt76.sta_poll_lock);
-
- mutex_lock(&dev->mt76.mutex);
- dev->mt76.vif_mask &= ~BIT_ULL(mvif->idx);
-@@ -351,7 +351,7 @@ mt7603_sta_add(struct mt76_dev *mdev, struct ieee80211_vif *vif,
- if (idx < 0)
- return -ENOSPC;
-
-- INIT_LIST_HEAD(&msta->poll_list);
-+ INIT_LIST_HEAD(&msta->wcid.poll_list);
- __skb_queue_head_init(&msta->psq);
- msta->ps = ~0;
- msta->smps = ~0;
-@@ -388,10 +388,10 @@ mt7603_sta_remove(struct mt76_dev *mdev, struct ieee80211_vif *vif,
- mt7603_filter_tx(dev, wcid->idx, true);
- spin_unlock_bh(&dev->ps_lock);
-
-- spin_lock_bh(&dev->sta_poll_lock);
-- if (!list_empty(&msta->poll_list))
-- list_del_init(&msta->poll_list);
-- spin_unlock_bh(&dev->sta_poll_lock);
-+ spin_lock_bh(&mdev->sta_poll_lock);
-+ if (!list_empty(&msta->wcid.poll_list))
-+ list_del_init(&msta->wcid.poll_list);
-+ spin_unlock_bh(&mdev->sta_poll_lock);
-
- mt7603_wtbl_clear(dev, wcid->idx);
- }
-diff --git a/mt7603/mt7603.h b/mt7603/mt7603.h
-index 7c3be596..354b1898 100644
---- a/mt7603/mt7603.h
-+++ b/mt7603/mt7603.h
-@@ -64,7 +64,6 @@ struct mt7603_sta {
-
- struct mt7603_vif *vif;
-
-- struct list_head poll_list;
- u32 tx_airtime_ac[4];
-
- struct sk_buff_head psq;
-@@ -110,9 +109,6 @@ struct mt7603_dev {
-
- u32 rxfilter;
-
-- struct list_head sta_poll_list;
-- spinlock_t sta_poll_lock;
--
- struct mt7603_sta global_sta;
-
- u32 agc0, agc3;
-diff --git a/mt7615/init.c b/mt7615/init.c
-index 621e69f0..18a50ccf 100644
---- a/mt7615/init.c
-+++ b/mt7615/init.c
-@@ -397,6 +397,8 @@ mt7615_init_wiphy(struct ieee80211_hw *hw)
- wiphy_ext_feature_set(wiphy, NL80211_EXT_FEATURE_SET_SCAN_DWELL);
- wiphy_ext_feature_set(wiphy, NL80211_EXT_FEATURE_VHT_IBSS);
- wiphy_ext_feature_set(wiphy, NL80211_EXT_FEATURE_CAN_REPLACE_PTK0);
-+ if (!is_mt7622(&phy->dev->mt76))
-+ wiphy_ext_feature_set(wiphy, NL80211_EXT_FEATURE_MU_MIMO_AIR_SNIFFER);
-
- ieee80211_hw_set(hw, SINGLE_SCAN_ON_ALL_BANDS);
- ieee80211_hw_set(hw, TX_STATUS_NO_AMPDU_LEN);
-@@ -626,8 +628,6 @@ void mt7615_init_device(struct mt7615_dev *dev)
- INIT_DELAYED_WORK(&dev->coredump.work, mt7615_coredump_work);
- skb_queue_head_init(&dev->phy.scan_event_list);
- skb_queue_head_init(&dev->coredump.msg_list);
-- INIT_LIST_HEAD(&dev->sta_poll_list);
-- spin_lock_init(&dev->sta_poll_lock);
- init_waitqueue_head(&dev->reset_wait);
- init_waitqueue_head(&dev->phy.roc_wait);
-
-diff --git a/mt7615/mac.c b/mt7615/mac.c
-index da1d17b7..7ba78983 100644
---- a/mt7615/mac.c
-+++ b/mt7615/mac.c
-@@ -387,10 +387,11 @@ static int mt7615_mac_fill_rx(struct mt7615_dev *dev, struct sk_buff *skb)
- struct mt7615_sta *msta;
-
- msta = container_of(status->wcid, struct mt7615_sta, wcid);
-- spin_lock_bh(&dev->sta_poll_lock);
-- if (list_empty(&msta->poll_list))
-- list_add_tail(&msta->poll_list, &dev->sta_poll_list);
-- spin_unlock_bh(&dev->sta_poll_lock);
-+ spin_lock_bh(&dev->mt76.sta_poll_lock);
-+ if (list_empty(&msta->wcid.poll_list))
-+ list_add_tail(&msta->wcid.poll_list,
-+ &dev->mt76.sta_poll_list);
-+ spin_unlock_bh(&dev->mt76.sta_poll_lock);
- }
-
- if (mt76_is_mmio(&dev->mt76) && (rxd0 & csum_mask) == csum_mask &&
-@@ -905,16 +906,19 @@ void mt7615_mac_sta_poll(struct mt7615_dev *dev)
- int i;
-
- INIT_LIST_HEAD(&sta_poll_list);
-- spin_lock_bh(&dev->sta_poll_lock);
-- list_splice_init(&dev->sta_poll_list, &sta_poll_list);
-- spin_unlock_bh(&dev->sta_poll_lock);
-+ spin_lock_bh(&dev->mt76.sta_poll_lock);
-+ list_splice_init(&dev->mt76.sta_poll_list, &sta_poll_list);
-+ spin_unlock_bh(&dev->mt76.sta_poll_lock);
-
- while (!list_empty(&sta_poll_list)) {
- bool clear = false;
-
- msta = list_first_entry(&sta_poll_list, struct mt7615_sta,
-- poll_list);
-- list_del_init(&msta->poll_list);
-+ wcid.poll_list);
-+
-+ spin_lock_bh(&dev->mt76.sta_poll_lock);
-+ list_del_init(&msta->wcid.poll_list);
-+ spin_unlock_bh(&dev->mt76.sta_poll_lock);
-
- addr = mt7615_mac_wtbl_addr(dev, msta->wcid.idx) + 19 * 4;
-
-@@ -1511,10 +1515,10 @@ static void mt7615_mac_add_txs(struct mt7615_dev *dev, void *data)
- msta = container_of(wcid, struct mt7615_sta, wcid);
- sta = wcid_to_sta(wcid);
-
-- spin_lock_bh(&dev->sta_poll_lock);
-- if (list_empty(&msta->poll_list))
-- list_add_tail(&msta->poll_list, &dev->sta_poll_list);
-- spin_unlock_bh(&dev->sta_poll_lock);
-+ spin_lock_bh(&dev->mt76.sta_poll_lock);
-+ if (list_empty(&msta->wcid.poll_list))
-+ list_add_tail(&msta->wcid.poll_list, &dev->mt76.sta_poll_list);
-+ spin_unlock_bh(&dev->mt76.sta_poll_lock);
-
- if (mt7615_mac_add_txs_skb(dev, msta, pid, txs_data))
- goto out;
-diff --git a/mt7615/main.c b/mt7615/main.c
-index dadb13f2..200b1752 100644
---- a/mt7615/main.c
-+++ b/mt7615/main.c
-@@ -222,7 +222,7 @@ static int mt7615_add_interface(struct ieee80211_hw *hw,
-
- idx = MT7615_WTBL_RESERVED - mvif->mt76.idx;
-
-- INIT_LIST_HEAD(&mvif->sta.poll_list);
-+ INIT_LIST_HEAD(&mvif->sta.wcid.poll_list);
- mvif->sta.wcid.idx = idx;
- mvif->sta.wcid.phy_idx = mvif->mt76.band_idx;
- mvif->sta.wcid.hw_key_idx = -1;
-@@ -274,10 +274,10 @@ static void mt7615_remove_interface(struct ieee80211_hw *hw,
-
- mt7615_mutex_release(dev);
-
-- spin_lock_bh(&dev->sta_poll_lock);
-- if (!list_empty(&msta->poll_list))
-- list_del_init(&msta->poll_list);
-- spin_unlock_bh(&dev->sta_poll_lock);
-+ spin_lock_bh(&dev->mt76.sta_poll_lock);
-+ if (!list_empty(&msta->wcid.poll_list))
-+ list_del_init(&msta->wcid.poll_list);
-+ spin_unlock_bh(&dev->mt76.sta_poll_lock);
-
- mt76_packet_id_flush(&dev->mt76, &mvif->sta.wcid);
- }
-@@ -552,6 +552,32 @@ static void mt7615_configure_filter(struct ieee80211_hw *hw,
- mt7615_mutex_release(dev);
- }
-
-+static void
-+mt7615_update_mu_group(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
-+ struct ieee80211_bss_conf *info)
-+{
-+ struct mt7615_vif *mvif = (struct mt7615_vif *)vif->drv_priv;
-+ struct mt7615_dev *dev = mt7615_hw_dev(hw);
-+ u8 i, band = mvif->mt76.band_idx;
-+ u32 *mu;
-+
-+ mu = (u32 *)info->mu_group.membership;
-+ for (i = 0; i < WLAN_MEMBERSHIP_LEN / sizeof(*mu); i++) {
-+ if (is_mt7663(&dev->mt76))
-+ mt76_wr(dev, MT7663_WF_PHY_GID_TAB_VLD(band, i), mu[i]);
-+ else
-+ mt76_wr(dev, MT_WF_PHY_GID_TAB_VLD(band, i), mu[i]);
-+ }
-+
-+ mu = (u32 *)info->mu_group.position;
-+ for (i = 0; i < WLAN_USER_POSITION_LEN / sizeof(*mu); i++) {
-+ if (is_mt7663(&dev->mt76))
-+ mt76_wr(dev, MT7663_WF_PHY_GID_TAB_POS(band, i), mu[i]);
-+ else
-+ mt76_wr(dev, MT_WF_PHY_GID_TAB_POS(band, i), mu[i]);
-+ }
-+}
-+
- static void mt7615_bss_info_changed(struct ieee80211_hw *hw,
- struct ieee80211_vif *vif,
- struct ieee80211_bss_conf *info,
-@@ -600,6 +626,9 @@ static void mt7615_bss_info_changed(struct ieee80211_hw *hw,
- if (changed & BSS_CHANGED_ASSOC)
- mt7615_mac_set_beacon_filter(phy, vif, vif->cfg.assoc);
-
-+ if (changed & BSS_CHANGED_MU_GROUPS)
-+ mt7615_update_mu_group(hw, vif, info);
-+
- mt7615_mutex_release(dev);
- }
-
-@@ -628,7 +657,7 @@ int mt7615_mac_sta_add(struct mt76_dev *mdev, struct ieee80211_vif *vif,
- if (idx < 0)
- return -ENOSPC;
-
-- INIT_LIST_HEAD(&msta->poll_list);
-+ INIT_LIST_HEAD(&msta->wcid.poll_list);
- msta->vif = mvif;
- msta->wcid.sta = 1;
- msta->wcid.idx = idx;
-@@ -676,10 +705,10 @@ void mt7615_mac_sta_remove(struct mt76_dev *mdev, struct ieee80211_vif *vif,
- if (vif->type == NL80211_IFTYPE_STATION && !sta->tdls)
- mt7615_mcu_add_bss_info(phy, vif, sta, false);
-
-- spin_lock_bh(&dev->sta_poll_lock);
-- if (!list_empty(&msta->poll_list))
-- list_del_init(&msta->poll_list);
-- spin_unlock_bh(&dev->sta_poll_lock);
-+ spin_lock_bh(&mdev->sta_poll_lock);
-+ if (!list_empty(&msta->wcid.poll_list))
-+ list_del_init(&msta->wcid.poll_list);
-+ spin_unlock_bh(&mdev->sta_poll_lock);
-
- mt76_connac_power_save_sched(phy->mt76, &dev->pm);
- }
-diff --git a/mt7615/mt7615.h b/mt7615/mt7615.h
-index 582d1b5b..a20322aa 100644
---- a/mt7615/mt7615.h
-+++ b/mt7615/mt7615.h
-@@ -125,7 +125,6 @@ struct mt7615_sta {
-
- struct mt7615_vif *vif;
-
-- struct list_head poll_list;
- u32 airtime_ac[8];
-
- struct ieee80211_tx_rate rates[4];
-@@ -262,9 +261,6 @@ struct mt7615_dev {
- wait_queue_head_t reset_wait;
- u32 reset_state;
-
-- struct list_head sta_poll_list;
-- spinlock_t sta_poll_lock;
--
- struct {
- u8 n_pulses;
- u32 period;
-diff --git a/mt7615/regs.h b/mt7615/regs.h
-index 7cecb22c..806b3887 100644
---- a/mt7615/regs.h
-+++ b/mt7615/regs.h
-@@ -212,6 +212,15 @@ enum mt7615_reg_base {
-
- #define MT7663_WF_PHY_R0_PHYCTRL_STS5(_phy) MT_WF_PHY(0x0224 + ((_phy) << 12))
-
-+#define MT_WF_PHY_GID_TAB_VLD(_phy, i) MT_WF_PHY(0x0254 + (i) * 4 + \
-+ ((_phy) << 9))
-+#define MT7663_WF_PHY_GID_TAB_VLD(_phy, i) MT_WF_PHY(0x0254 + (i) * 4 + \
-+ ((_phy) << 12))
-+#define MT_WF_PHY_GID_TAB_POS(_phy, i) MT_WF_PHY(0x025c + (i) * 4 + \
-+ ((_phy) << 9))
-+#define MT7663_WF_PHY_GID_TAB_POS(_phy, i) MT_WF_PHY(0x025c + (i) * 4 + \
-+ ((_phy) << 12))
-+
- #define MT_WF_PHY_MIN_PRI_PWR(_phy) MT_WF_PHY((_phy) ? 0x084 : 0x229c)
- #define MT_WF_PHY_PD_OFDM_MASK(_phy) ((_phy) ? GENMASK(24, 16) : \
- GENMASK(28, 20))
-diff --git a/mt76_connac.h b/mt76_connac.h
-index 77ca8f05..22878f08 100644
---- a/mt76_connac.h
-+++ b/mt76_connac.h
-@@ -419,5 +419,13 @@ int mt76_connac2_mac_fill_rx_rate(struct mt76_dev *dev,
- struct mt76_rx_status *status,
- struct ieee80211_supported_band *sband,
- __le32 *rxv, u8 *mode);
--
-+void mt76_connac2_tx_check_aggr(struct ieee80211_sta *sta, __le32 *txwi);
-+void mt76_connac2_txwi_free(struct mt76_dev *dev, struct mt76_txwi_cache *t,
-+ struct ieee80211_sta *sta,
-+ struct list_head *free_list);
-+void mt76_connac2_tx_token_put(struct mt76_dev *dev);
-+
-+/* connac3 */
-+void mt76_connac3_mac_decode_he_radiotap(struct sk_buff *skb, __le32 *rxv,
-+ u8 mode);
- #endif /* __MT76_CONNAC_H */
-diff --git a/mt76_connac2_mac.h b/mt76_connac2_mac.h
-index a5ec0f63..bd2a9246 100644
---- a/mt76_connac2_mac.h
-+++ b/mt76_connac2_mac.h
-@@ -34,7 +34,7 @@ enum {
-
- #define MT_TX_FREE_MSDU_CNT GENMASK(9, 0)
- #define MT_TX_FREE_WLAN_ID GENMASK(23, 14)
--#define MT_TX_FREE_LATENCY GENMASK(12, 0)
-+#define MT_TX_FREE_COUNT GENMASK(12, 0)
- /* 0: success, others: dropped */
- #define MT_TX_FREE_STATUS GENMASK(14, 13)
- #define MT_TX_FREE_MSDU_ID GENMASK(30, 16)
-@@ -173,7 +173,7 @@ enum {
- #define MT_TXS5_MPDU_TX_CNT GENMASK(31, 23)
-
- #define MT_TXS6_MPDU_FAIL_CNT GENMASK(31, 23)
--
-+#define MT_TXS7_MPDU_RETRY_BYTE GENMASK(22, 0)
- #define MT_TXS7_MPDU_RETRY_CNT GENMASK(31, 23)
-
- /* RXD DW0 */
-diff --git a/mt76_connac3_mac.c b/mt76_connac3_mac.c
-new file mode 100644
-index 00000000..73e9f283
---- /dev/null
-+++ b/mt76_connac3_mac.c
-@@ -0,0 +1,182 @@
-+// SPDX-License-Identifier: ISC
-+/* Copyright (C) 2023 MediaTek Inc. */
-+
-+#include "mt76_connac.h"
-+#include "mt76_connac3_mac.h"
-+#include "dma.h"
-+
-+#define HE_BITS(f) cpu_to_le16(IEEE80211_RADIOTAP_HE_##f)
-+#define HE_PREP(f, m, v) le16_encode_bits(le32_get_bits(v, MT_CRXV_HE_##m),\
-+ IEEE80211_RADIOTAP_HE_##f)
-+
-+static void
-+mt76_connac3_mac_decode_he_radiotap_ru(struct mt76_rx_status *status,
-+ struct ieee80211_radiotap_he *he,
-+ __le32 *rxv)
-+{
-+ u32 ru = le32_get_bits(rxv[0], MT_PRXV_HE_RU_ALLOC), offs = 0;
-+
-+ status->bw = RATE_INFO_BW_HE_RU;
-+
-+ switch (ru) {
-+ case 0 ... 36:
-+ status->he_ru = NL80211_RATE_INFO_HE_RU_ALLOC_26;
-+ offs = ru;
-+ break;
-+ case 37 ... 52:
-+ status->he_ru = NL80211_RATE_INFO_HE_RU_ALLOC_52;
-+ offs = ru - 37;
-+ break;
-+ case 53 ... 60:
-+ status->he_ru = NL80211_RATE_INFO_HE_RU_ALLOC_106;
-+ offs = ru - 53;
-+ break;
-+ case 61 ... 64:
-+ status->he_ru = NL80211_RATE_INFO_HE_RU_ALLOC_242;
-+ offs = ru - 61;
-+ break;
-+ case 65 ... 66:
-+ status->he_ru = NL80211_RATE_INFO_HE_RU_ALLOC_484;
-+ offs = ru - 65;
-+ break;
-+ case 67:
-+ status->he_ru = NL80211_RATE_INFO_HE_RU_ALLOC_996;
-+ break;
-+ case 68:
-+ status->he_ru = NL80211_RATE_INFO_HE_RU_ALLOC_2x996;
-+ break;
-+ }
-+
-+ he->data1 |= HE_BITS(DATA1_BW_RU_ALLOC_KNOWN);
-+ he->data2 |= HE_BITS(DATA2_RU_OFFSET_KNOWN) |
-+ le16_encode_bits(offs,
-+ IEEE80211_RADIOTAP_HE_DATA2_RU_OFFSET);
-+}
-+
-+#define MU_PREP(f, v) le16_encode_bits(v, IEEE80211_RADIOTAP_HE_MU_##f)
-+static void
-+mt76_connac3_mac_decode_he_mu_radiotap(struct sk_buff *skb, __le32 *rxv)
-+{
-+ struct mt76_rx_status *status = (struct mt76_rx_status *)skb->cb;
-+ static const struct ieee80211_radiotap_he_mu mu_known = {
-+ .flags1 = HE_BITS(MU_FLAGS1_SIG_B_MCS_KNOWN) |
-+ HE_BITS(MU_FLAGS1_SIG_B_DCM_KNOWN) |
-+ HE_BITS(MU_FLAGS1_CH1_RU_KNOWN) |
-+ HE_BITS(MU_FLAGS1_SIG_B_SYMS_USERS_KNOWN),
-+ .flags2 = HE_BITS(MU_FLAGS2_BW_FROM_SIG_A_BW_KNOWN),
-+ };
-+ struct ieee80211_radiotap_he_mu *he_mu;
-+
-+ status->flag |= RX_FLAG_RADIOTAP_HE_MU;
-+
-+ he_mu = skb_push(skb, sizeof(mu_known));
-+ memcpy(he_mu, &mu_known, sizeof(mu_known));
-+
-+ he_mu->flags1 |= MU_PREP(FLAGS1_SIG_B_MCS, status->rate_idx);
-+ if (status->he_dcm)
-+ he_mu->flags1 |= MU_PREP(FLAGS1_SIG_B_DCM, status->he_dcm);
-+
-+ he_mu->flags2 |= MU_PREP(FLAGS2_BW_FROM_SIG_A_BW, status->bw) |
-+ MU_PREP(FLAGS2_SIG_B_SYMS_USERS,
-+ le32_get_bits(rxv[4], MT_CRXV_HE_NUM_USER));
-+
-+ he_mu->ru_ch1[0] = le32_get_bits(rxv[16], MT_CRXV_HE_RU0) & 0xff;
-+
-+ if (status->bw >= RATE_INFO_BW_40) {
-+ he_mu->flags1 |= HE_BITS(MU_FLAGS1_CH2_RU_KNOWN);
-+ he_mu->ru_ch2[0] = le32_get_bits(rxv[16], MT_CRXV_HE_RU1) & 0xff;
-+ }
-+
-+ if (status->bw >= RATE_INFO_BW_80) {
-+ u32 ru_h, ru_l;
-+
-+ he_mu->ru_ch1[1] = le32_get_bits(rxv[16], MT_CRXV_HE_RU2) & 0xff;
-+
-+ ru_l = le32_get_bits(rxv[16], MT_CRXV_HE_RU3_L);
-+ ru_h = le32_get_bits(rxv[17], MT_CRXV_HE_RU3_H) & 0x7;
-+ he_mu->ru_ch2[1] = (u8)(ru_l | ru_h << 4);
-+ }
-+}
-+
-+void mt76_connac3_mac_decode_he_radiotap(struct sk_buff *skb, __le32 *rxv,
-+ u8 mode)
-+{
-+ struct mt76_rx_status *status = (struct mt76_rx_status *)skb->cb;
-+ static const struct ieee80211_radiotap_he known = {
-+ .data1 = HE_BITS(DATA1_DATA_MCS_KNOWN) |
-+ HE_BITS(DATA1_DATA_DCM_KNOWN) |
-+ HE_BITS(DATA1_STBC_KNOWN) |
-+ HE_BITS(DATA1_CODING_KNOWN) |
-+ HE_BITS(DATA1_LDPC_XSYMSEG_KNOWN) |
-+ HE_BITS(DATA1_DOPPLER_KNOWN) |
-+ HE_BITS(DATA1_SPTL_REUSE_KNOWN) |
-+ HE_BITS(DATA1_BSS_COLOR_KNOWN),
-+ .data2 = HE_BITS(DATA2_GI_KNOWN) |
-+ HE_BITS(DATA2_TXBF_KNOWN) |
-+ HE_BITS(DATA2_PE_DISAMBIG_KNOWN) |
-+ HE_BITS(DATA2_TXOP_KNOWN),
-+ };
-+ u32 ltf_size = le32_get_bits(rxv[4], MT_CRXV_HE_LTF_SIZE) + 1;
-+ struct ieee80211_radiotap_he *he;
-+
-+ status->flag |= RX_FLAG_RADIOTAP_HE;
-+
-+ he = skb_push(skb, sizeof(known));
-+ memcpy(he, &known, sizeof(known));
-+
-+ he->data3 = HE_PREP(DATA3_BSS_COLOR, BSS_COLOR, rxv[9]) |
-+ HE_PREP(DATA3_LDPC_XSYMSEG, LDPC_EXT_SYM, rxv[4]);
-+ he->data4 = HE_PREP(DATA4_SU_MU_SPTL_REUSE, SR_MASK, rxv[13]);
-+ he->data5 = HE_PREP(DATA5_PE_DISAMBIG, PE_DISAMBIG, rxv[5]) |
-+ le16_encode_bits(ltf_size,
-+ IEEE80211_RADIOTAP_HE_DATA5_LTF_SIZE);
-+ if (le32_to_cpu(rxv[0]) & MT_PRXV_TXBF)
-+ he->data5 |= HE_BITS(DATA5_TXBF);
-+ he->data6 = HE_PREP(DATA6_TXOP, TXOP_DUR, rxv[9]) |
-+ HE_PREP(DATA6_DOPPLER, DOPPLER, rxv[9]);
-+
-+ switch (mode) {
-+ case MT_PHY_TYPE_HE_SU:
-+ he->data1 |= HE_BITS(DATA1_FORMAT_SU) |
-+ HE_BITS(DATA1_UL_DL_KNOWN) |
-+ HE_BITS(DATA1_BEAM_CHANGE_KNOWN) |
-+ HE_BITS(DATA1_BW_RU_ALLOC_KNOWN);
-+
-+ he->data3 |= HE_PREP(DATA3_BEAM_CHANGE, BEAM_CHNG, rxv[8]) |
-+ HE_PREP(DATA3_UL_DL, UPLINK, rxv[5]);
-+ break;
-+ case MT_PHY_TYPE_HE_EXT_SU:
-+ he->data1 |= HE_BITS(DATA1_FORMAT_EXT_SU) |
-+ HE_BITS(DATA1_UL_DL_KNOWN) |
-+ HE_BITS(DATA1_BW_RU_ALLOC_KNOWN);
-+
-+ he->data3 |= HE_PREP(DATA3_UL_DL, UPLINK, rxv[5]);
-+ break;
-+ case MT_PHY_TYPE_HE_MU:
-+ he->data1 |= HE_BITS(DATA1_FORMAT_MU) |
-+ HE_BITS(DATA1_UL_DL_KNOWN);
-+
-+ he->data3 |= HE_PREP(DATA3_UL_DL, UPLINK, rxv[5]);
-+ he->data4 |= HE_PREP(DATA4_MU_STA_ID, MU_AID, rxv[8]);
-+
-+ mt76_connac3_mac_decode_he_radiotap_ru(status, he, rxv);
-+ mt76_connac3_mac_decode_he_mu_radiotap(skb, rxv);
-+ break;
-+ case MT_PHY_TYPE_HE_TB:
-+ he->data1 |= HE_BITS(DATA1_FORMAT_TRIG) |
-+ HE_BITS(DATA1_SPTL_REUSE2_KNOWN) |
-+ HE_BITS(DATA1_SPTL_REUSE3_KNOWN) |
-+ HE_BITS(DATA1_SPTL_REUSE4_KNOWN);
-+
-+ he->data4 |= HE_PREP(DATA4_TB_SPTL_REUSE1, SR_MASK, rxv[13]) |
-+ HE_PREP(DATA4_TB_SPTL_REUSE2, SR1_MASK, rxv[13]) |
-+ HE_PREP(DATA4_TB_SPTL_REUSE3, SR2_MASK, rxv[13]) |
-+ HE_PREP(DATA4_TB_SPTL_REUSE4, SR3_MASK, rxv[13]);
-+
-+ mt76_connac3_mac_decode_he_radiotap_ru(status, he, rxv);
-+ break;
-+ default:
-+ break;
-+ }
-+}
-+EXPORT_SYMBOL_GPL(mt76_connac3_mac_decode_he_radiotap);
-diff --git a/mt76_connac3_mac.h b/mt76_connac3_mac.h
-new file mode 100644
-index 00000000..6663a0b4
---- /dev/null
-+++ b/mt76_connac3_mac.h
-@@ -0,0 +1,325 @@
-+/* SPDX-License-Identifier: ISC */
-+/* Copyright (C) 2023 MediaTek Inc. */
-+
-+#ifndef __MT76_CONNAC3_MAC_H
-+#define __MT76_CONNAC3_MAC_H
-+
-+#define MT_CT_PARSE_LEN 72
-+#define MT_CT_DMA_BUF_NUM 2
-+
-+#define MT_RXD0_LENGTH GENMASK(15, 0)
-+#define MT_RXD0_PKT_FLAG GENMASK(19, 16)
-+#define MT_RXD0_PKT_TYPE GENMASK(31, 27)
-+
-+#define MT_RXD0_MESH BIT(18)
-+#define MT_RXD0_MHCP BIT(19)
-+#define MT_RXD0_NORMAL_ETH_TYPE_OFS GENMASK(22, 16)
-+#define MT_RXD0_NORMAL_IP_SUM BIT(23)
-+#define MT_RXD0_NORMAL_UDP_TCP_SUM BIT(24)
-+
-+#define MT_RXD0_SW_PKT_TYPE_MASK GENMASK(31, 16)
-+#define MT_RXD0_SW_PKT_TYPE_MAP 0x380F
-+#define MT_RXD0_SW_PKT_TYPE_FRAME 0x3801
-+
-+/* RXD DW1 */
-+#define MT_RXD1_NORMAL_WLAN_IDX GENMASK(11, 0)
-+#define MT_RXD1_NORMAL_GROUP_1 BIT(16)
-+#define MT_RXD1_NORMAL_GROUP_2 BIT(17)
-+#define MT_RXD1_NORMAL_GROUP_3 BIT(18)
-+#define MT_RXD1_NORMAL_GROUP_4 BIT(19)
-+#define MT_RXD1_NORMAL_GROUP_5 BIT(20)
-+#define MT_RXD1_NORMAL_KEY_ID GENMASK(22, 21)
-+#define MT_RXD1_NORMAL_CM BIT(23)
-+#define MT_RXD1_NORMAL_CLM BIT(24)
-+#define MT_RXD1_NORMAL_ICV_ERR BIT(25)
-+#define MT_RXD1_NORMAL_TKIP_MIC_ERR BIT(26)
-+#define MT_RXD1_NORMAL_BAND_IDX GENMASK(28, 27)
-+#define MT_RXD1_NORMAL_SPP_EN BIT(29)
-+#define MT_RXD1_NORMAL_ADD_OM BIT(30)
-+#define MT_RXD1_NORMAL_SEC_DONE BIT(31)
-+
-+/* RXD DW2 */
-+#define MT_RXD2_NORMAL_BSSID GENMASK(5, 0)
-+#define MT_RXD2_NORMAL_MAC_HDR_LEN GENMASK(12, 8)
-+#define MT_RXD2_NORMAL_HDR_TRANS BIT(7)
-+#define MT_RXD2_NORMAL_HDR_OFFSET GENMASK(15, 13)
-+#define MT_RXD2_NORMAL_SEC_MODE GENMASK(20, 16)
-+#define MT_RXD2_NORMAL_MU_BAR BIT(21)
-+#define MT_RXD2_NORMAL_SW_BIT BIT(22)
-+#define MT_RXD2_NORMAL_AMSDU_ERR BIT(23)
-+#define MT_RXD2_NORMAL_MAX_LEN_ERROR BIT(24)
-+#define MT_RXD2_NORMAL_HDR_TRANS_ERROR BIT(25)
-+#define MT_RXD2_NORMAL_INT_FRAME BIT(26)
-+#define MT_RXD2_NORMAL_FRAG BIT(27)
-+#define MT_RXD2_NORMAL_NULL_FRAME BIT(28)
-+#define MT_RXD2_NORMAL_NDATA BIT(29)
-+#define MT_RXD2_NORMAL_NON_AMPDU BIT(30)
-+#define MT_RXD2_NORMAL_BF_REPORT BIT(31)
-+
-+/* RXD DW3 */
-+#define MT_RXD3_NORMAL_RXV_SEQ GENMASK(7, 0)
-+#define MT_RXD3_NORMAL_CH_FREQ GENMASK(15, 8)
-+#define MT_RXD3_NORMAL_ADDR_TYPE GENMASK(17, 16)
-+#define MT_RXD3_NORMAL_U2M BIT(0)
-+#define MT_RXD3_NORMAL_HTC_VLD BIT(18)
-+#define MT_RXD3_NORMAL_BEACON_MC BIT(20)
-+#define MT_RXD3_NORMAL_BEACON_UC BIT(21)
-+#define MT_RXD3_NORMAL_CO_ANT BIT(22)
-+#define MT_RXD3_NORMAL_FCS_ERR BIT(24)
-+#define MT_RXD3_NORMAL_VLAN2ETH BIT(31)
-+
-+/* RXD DW4 */
-+#define MT_RXD4_NORMAL_PAYLOAD_FORMAT GENMASK(1, 0)
-+#define MT_RXD4_FIRST_AMSDU_FRAME GENMASK(1, 0)
-+#define MT_RXD4_MID_AMSDU_FRAME BIT(1)
-+#define MT_RXD4_LAST_AMSDU_FRAME BIT(0)
-+
-+#define MT_RXV_HDR_BAND_IDX BIT(24)
-+
-+/* RXD GROUP4 */
-+#define MT_RXD8_FRAME_CONTROL GENMASK(15, 0)
-+
-+#define MT_RXD10_SEQ_CTRL GENMASK(15, 0)
-+#define MT_RXD10_QOS_CTL GENMASK(31, 16)
-+
-+#define MT_RXD11_HT_CONTROL GENMASK(31, 0)
-+
-+/* P-RXV */
-+#define MT_PRXV_TX_RATE GENMASK(6, 0)
-+#define MT_PRXV_TX_DCM BIT(4)
-+#define MT_PRXV_TX_ER_SU_106T BIT(5)
-+#define MT_PRXV_NSTS GENMASK(10, 7)
-+#define MT_PRXV_TXBF BIT(11)
-+#define MT_PRXV_HT_AD_CODE BIT(12)
-+#define MT_PRXV_HE_RU_ALLOC GENMASK(30, 22)
-+#define MT_PRXV_RCPI3 GENMASK(31, 24)
-+#define MT_PRXV_RCPI2 GENMASK(23, 16)
-+#define MT_PRXV_RCPI1 GENMASK(15, 8)
-+#define MT_PRXV_RCPI0 GENMASK(7, 0)
-+#define MT_PRXV_HT_SHORT_GI GENMASK(4, 3)
-+#define MT_PRXV_HT_STBC GENMASK(10, 9)
-+#define MT_PRXV_TX_MODE GENMASK(14, 11)
-+#define MT_PRXV_FRAME_MODE GENMASK(2, 0)
-+#define MT_PRXV_DCM BIT(5)
-+
-+/* C-RXV */
-+#define MT_CRXV_HE_NUM_USER GENMASK(26, 20)
-+#define MT_CRXV_HE_LTF_SIZE GENMASK(28, 27)
-+#define MT_CRXV_HE_LDPC_EXT_SYM BIT(30)
-+
-+#define MT_CRXV_HE_PE_DISAMBIG BIT(1)
-+#define MT_CRXV_HE_UPLINK BIT(2)
-+
-+#define MT_CRXV_HE_MU_AID GENMASK(27, 17)
-+#define MT_CRXV_HE_BEAM_CHNG BIT(29)
-+
-+#define MT_CRXV_HE_DOPPLER BIT(0)
-+#define MT_CRXV_HE_BSS_COLOR GENMASK(15, 10)
-+#define MT_CRXV_HE_TXOP_DUR GENMASK(19, 17)
-+
-+#define MT_CRXV_HE_SR_MASK GENMASK(11, 8)
-+#define MT_CRXV_HE_SR1_MASK GENMASK(16, 12)
-+#define MT_CRXV_HE_SR2_MASK GENMASK(20, 17)
-+#define MT_CRXV_HE_SR3_MASK GENMASK(24, 21)
-+
-+#define MT_CRXV_HE_RU0 GENMASK(8, 0)
-+#define MT_CRXV_HE_RU1 GENMASK(17, 9)
-+#define MT_CRXV_HE_RU2 GENMASK(26, 18)
-+#define MT_CRXV_HE_RU3_L GENMASK(31, 27)
-+#define MT_CRXV_HE_RU3_H GENMASK(3, 0)
-+
-+enum tx_header_format {
-+ MT_HDR_FORMAT_802_3,
-+ MT_HDR_FORMAT_CMD,
-+ MT_HDR_FORMAT_802_11,
-+ MT_HDR_FORMAT_802_11_EXT,
-+};
-+
-+enum tx_pkt_type {
-+ MT_TX_TYPE_CT,
-+ MT_TX_TYPE_SF,
-+ MT_TX_TYPE_CMD,
-+ MT_TX_TYPE_FW,
-+};
-+
-+enum tx_port_idx {
-+ MT_TX_PORT_IDX_LMAC,
-+ MT_TX_PORT_IDX_MCU
-+};
-+
-+enum tx_mcu_port_q_idx {
-+ MT_TX_MCU_PORT_RX_Q0 = 0x20,
-+ MT_TX_MCU_PORT_RX_Q1,
-+ MT_TX_MCU_PORT_RX_Q2,
-+ MT_TX_MCU_PORT_RX_Q3,
-+ MT_TX_MCU_PORT_RX_FWDL = 0x3e
-+};
-+
-+enum tx_mgnt_type {
-+ MT_TX_NORMAL,
-+ MT_TX_TIMING,
-+ MT_TX_ADDBA,
-+};
-+
-+#define MT_CT_INFO_APPLY_TXD BIT(0)
-+#define MT_CT_INFO_COPY_HOST_TXD_ALL BIT(1)
-+#define MT_CT_INFO_MGMT_FRAME BIT(2)
-+#define MT_CT_INFO_NONE_CIPHER_FRAME BIT(3)
-+#define MT_CT_INFO_HSR2_TX BIT(4)
-+#define MT_CT_INFO_FROM_HOST BIT(7)
-+
-+#define MT_TXD_SIZE (8 * 4)
-+
-+#define MT_TXD0_Q_IDX GENMASK(31, 25)
-+#define MT_TXD0_PKT_FMT GENMASK(24, 23)
-+#define MT_TXD0_ETH_TYPE_OFFSET GENMASK(22, 16)
-+#define MT_TXD0_TX_BYTES GENMASK(15, 0)
-+
-+#define MT_TXD1_FIXED_RATE BIT(31)
-+#define MT_TXD1_OWN_MAC GENMASK(30, 25)
-+#define MT_TXD1_TID GENMASK(24, 21)
-+#define MT_TXD1_BIP BIT(24)
-+#define MT_TXD1_ETH_802_3 BIT(20)
-+#define MT_TXD1_HDR_INFO GENMASK(20, 16)
-+#define MT_TXD1_HDR_FORMAT GENMASK(15, 14)
-+#define MT_TXD1_TGID GENMASK(13, 12)
-+#define MT_TXD1_WLAN_IDX GENMASK(11, 0)
-+
-+#define MT_TXD2_POWER_OFFSET GENMASK(31, 26)
-+#define MT_TXD2_MAX_TX_TIME GENMASK(25, 16)
-+#define MT_TXD2_FRAG GENMASK(15, 14)
-+#define MT_TXD2_HTC_VLD BIT(13)
-+#define MT_TXD2_DURATION BIT(12)
-+#define MT_TXD2_HDR_PAD GENMASK(11, 10)
-+#define MT_TXD2_RTS BIT(9)
-+#define MT_TXD2_OWN_MAC_MAP BIT(8)
-+#define MT_TXD2_BF_TYPE GENMASK(6, 7)
-+#define MT_TXD2_FRAME_TYPE GENMASK(5, 4)
-+#define MT_TXD2_SUB_TYPE GENMASK(3, 0)
-+
-+#define MT_TXD3_SN_VALID BIT(31)
-+#define MT_TXD3_PN_VALID BIT(30)
-+#define MT_TXD3_SW_POWER_MGMT BIT(29)
-+#define MT_TXD3_BA_DISABLE BIT(28)
-+#define MT_TXD3_SEQ GENMASK(27, 16)
-+#define MT_TXD3_REM_TX_COUNT GENMASK(15, 11)
-+#define MT_TXD3_TX_COUNT GENMASK(10, 6)
-+#define MT_TXD3_HW_AMSDU BIT(5)
-+#define MT_TXD3_BCM BIT(4)
-+#define MT_TXD3_EEOSP BIT(3)
-+#define MT_TXD3_EMRD BIT(2)
-+#define MT_TXD3_PROTECT_FRAME BIT(1)
-+#define MT_TXD3_NO_ACK BIT(0)
-+
-+#define MT_TXD4_PN_LOW GENMASK(31, 0)
-+
-+#define MT_TXD5_PN_HIGH GENMASK(31, 16)
-+#define MT_TXD5_FL BIT(15)
-+#define MT_TXD5_BYPASS_TBB BIT(14)
-+#define MT_TXD5_BYPASS_RBB BIT(13)
-+#define MT_TXD5_BSS_COLOR_ZERO BIT(12)
-+#define MT_TXD5_TX_STATUS_HOST BIT(10)
-+#define MT_TXD5_TX_STATUS_MCU BIT(9)
-+#define MT_TXD5_TX_STATUS_FMT BIT(8)
-+#define MT_TXD5_PID GENMASK(7, 0)
-+
-+#define MT_TXD6_TX_SRC GENMASK(31, 30)
-+#define MT_TXD6_VTA BIT(28)
-+#define MT_TXD6_BW GENMASK(25, 22)
-+#define MT_TXD6_TX_RATE GENMASK(21, 16)
-+#define MT_TXD6_TIMESTAMP_OFS_EN BIT(15)
-+#define MT_TXD6_TIMESTAMP_OFS_IDX GENMASK(14, 10)
-+#define MT_TXD6_MSDU_CNT GENMASK(9, 4)
-+#define MT_TXD6_DIS_MAT BIT(3)
-+#define MT_TXD6_DAS BIT(2)
-+#define MT_TXD6_AMSDU_CAP BIT(1)
-+
-+#define MT_TXD7_TXD_LEN GENMASK(31, 30)
-+#define MT_TXD7_IP_SUM BIT(29)
-+#define MT_TXD7_DROP_BY_SDO BIT(28)
-+#define MT_TXD7_MAC_TXD BIT(27)
-+#define MT_TXD7_CTXD BIT(26)
-+#define MT_TXD7_CTXD_CNT GENMASK(25, 22)
-+#define MT_TXD7_UDP_TCP_SUM BIT(15)
-+#define MT_TXD7_TX_TIME GENMASK(9, 0)
-+
-+#define MT_TX_RATE_STBC BIT(14)
-+#define MT_TX_RATE_NSS GENMASK(13, 10)
-+#define MT_TX_RATE_MODE GENMASK(9, 6)
-+#define MT_TX_RATE_SU_EXT_TONE BIT(5)
-+#define MT_TX_RATE_DCM BIT(4)
-+/* VHT/HE only use bits 0-3 */
-+#define MT_TX_RATE_IDX GENMASK(5, 0)
-+
-+#define MT_TXFREE0_PKT_TYPE GENMASK(31, 27)
-+#define MT_TXFREE0_MSDU_CNT GENMASK(25, 16)
-+#define MT_TXFREE0_RX_BYTE GENMASK(15, 0)
-+
-+#define MT_TXFREE1_VER GENMASK(18, 16)
-+
-+#define MT_TXFREE_INFO_PAIR BIT(31)
-+#define MT_TXFREE_INFO_HEADER BIT(30)
-+#define MT_TXFREE_INFO_WLAN_ID GENMASK(23, 12)
-+#define MT_TXFREE_INFO_MSDU_ID GENMASK(14, 0)
-+#define MT_TXFREE_INFO_COUNT GENMASK(27, 24)
-+#define MT_TXFREE_INFO_STAT GENMASK(29, 28)
-+
-+#define MT_TXS0_BW GENMASK(31, 29)
-+#define MT_TXS0_TID GENMASK(28, 26)
-+#define MT_TXS0_AMPDU BIT(25)
-+#define MT_TXS0_TXS_FORMAT GENMASK(24, 23)
-+#define MT_TXS0_BA_ERROR BIT(22)
-+#define MT_TXS0_PS_FLAG BIT(21)
-+#define MT_TXS0_TXOP_TIMEOUT BIT(20)
-+#define MT_TXS0_BIP_ERROR BIT(19)
-+
-+#define MT_TXS0_QUEUE_TIMEOUT BIT(18)
-+#define MT_TXS0_RTS_TIMEOUT BIT(17)
-+#define MT_TXS0_ACK_TIMEOUT BIT(16)
-+#define MT_TXS0_ACK_ERROR_MASK GENMASK(18, 16)
-+
-+#define MT_TXS0_TX_STATUS_HOST BIT(15)
-+#define MT_TXS0_TX_STATUS_MCU BIT(14)
-+#define MT_TXS0_TX_RATE GENMASK(13, 0)
-+
-+#define MT_TXS1_SEQNO GENMASK(31, 20)
-+#define MT_TXS1_RESP_RATE GENMASK(19, 16)
-+#define MT_TXS1_RXV_SEQNO GENMASK(15, 8)
-+#define MT_TXS1_TX_POWER_DBM GENMASK(7, 0)
-+
-+#define MT_TXS2_BF_STATUS GENMASK(31, 30)
-+#define MT_TXS2_BAND GENMASK(29, 28)
-+#define MT_TXS2_WCID GENMASK(27, 16)
-+#define MT_TXS2_TX_DELAY GENMASK(15, 0)
-+
-+#define MT_TXS3_PID GENMASK(31, 24)
-+#define MT_TXS3_RATE_STBC BIT(7)
-+#define MT_TXS3_FIXED_RATE BIT(6)
-+#define MT_TXS3_SRC GENMASK(5, 4)
-+#define MT_TXS3_SHARED_ANTENNA BIT(3)
-+#define MT_TXS3_LAST_TX_RATE GENMASK(2, 0)
-+
-+#define MT_TXS4_TIMESTAMP GENMASK(31, 0)
-+
-+#define MT_TXS5_F0_FINAL_MPDU BIT(31)
-+#define MT_TXS5_F0_QOS BIT(30)
-+#define MT_TXS5_F0_TX_COUNT GENMASK(29, 25)
-+#define MT_TXS5_F0_FRONT_TIME GENMASK(24, 0)
-+#define MT_TXS5_F1_MPDU_TX_COUNT GENMASK(31, 24)
-+#define MT_TXS5_F1_MPDU_TX_BYTES GENMASK(23, 0)
-+
-+#define MT_TXS6_F0_NOISE_3 GENMASK(31, 24)
-+#define MT_TXS6_F0_NOISE_2 GENMASK(23, 16)
-+#define MT_TXS6_F0_NOISE_1 GENMASK(15, 8)
-+#define MT_TXS6_F0_NOISE_0 GENMASK(7, 0)
-+#define MT_TXS6_F1_MPDU_FAIL_COUNT GENMASK(31, 24)
-+#define MT_TXS6_F1_MPDU_FAIL_BYTES GENMASK(23, 0)
-+
-+#define MT_TXS7_F0_RCPI_3 GENMASK(31, 24)
-+#define MT_TXS7_F0_RCPI_2 GENMASK(23, 16)
-+#define MT_TXS7_F0_RCPI_1 GENMASK(15, 8)
-+#define MT_TXS7_F0_RCPI_0 GENMASK(7, 0)
-+#define MT_TXS7_F1_MPDU_RETRY_COUNT GENMASK(31, 24)
-+#define MT_TXS7_F1_MPDU_RETRY_BYTES GENMASK(23, 0)
-+
-+#endif /* __MT76_CONNAC3_MAC_H */
-diff --git a/mt76_connac_mac.c b/mt76_connac_mac.c
-index ee0fbfcd..ee5177fd 100644
---- a/mt76_connac_mac.c
-+++ b/mt76_connac_mac.c
-@@ -495,6 +495,7 @@ void mt76_connac2_mac_write_txwi(struct mt76_dev *dev, __le32 *txwi,
- BSS_CHANGED_BEACON_ENABLED));
- bool inband_disc = !!(changed & (BSS_CHANGED_UNSOL_BCAST_PROBE_RESP |
- BSS_CHANGED_FILS_DISCOVERY));
-+ bool amsdu_en = wcid->amsdu;
-
- if (vif) {
- struct mt76_vif *mvif = (struct mt76_vif *)vif->drv_priv;
-@@ -521,9 +522,9 @@ void mt76_connac2_mac_write_txwi(struct mt76_dev *dev, __le32 *txwi,
- q_idx = wmm_idx * MT76_CONNAC_MAX_WMM_SETS +
- mt76_connac_lmac_mapping(skb_get_queue_mapping(skb));
-
-- /* counting non-offloading skbs */
-- wcid->stats.tx_bytes += skb->len;
-- wcid->stats.tx_packets++;
-+ /* mt7915 WA only counts WED path */
-+ if (is_mt7915(dev) && mtk_wed_device_active(&dev->mmio.wed))
-+ wcid->stats.tx_packets++;
- }
-
- val = FIELD_PREP(MT_TXD0_TX_BYTES, skb->len + sz_txd) |
-@@ -554,12 +555,14 @@ void mt76_connac2_mac_write_txwi(struct mt76_dev *dev, __le32 *txwi,
- txwi[4] = 0;
-
- val = FIELD_PREP(MT_TXD5_PID, pid);
-- if (pid >= MT_PACKET_ID_FIRST)
-+ if (pid >= MT_PACKET_ID_FIRST) {
- val |= MT_TXD5_TX_STATUS_HOST;
-+ amsdu_en = amsdu_en && !is_mt7921(dev);
-+ }
-
- txwi[5] = cpu_to_le32(val);
- txwi[6] = 0;
-- txwi[7] = wcid->amsdu ? cpu_to_le32(MT_TXD7_HW_AMSDU) : 0;
-+ txwi[7] = amsdu_en ? cpu_to_le32(MT_TXD7_HW_AMSDU) : 0;
-
- if (is_8023)
- mt76_connac2_mac_write_txwi_8023(txwi, skb, wcid);
-@@ -606,11 +609,11 @@ bool mt76_connac2_mac_fill_txs(struct mt76_dev *dev, struct mt76_wcid *wcid,
- txs = le32_to_cpu(txs_data[0]);
-
- /* PPDU based reporting */
-- if (FIELD_GET(MT_TXS0_TXS_FORMAT, txs) > 1) {
-+ if (mtk_wed_device_active(&dev->mmio.wed) &&
-+ FIELD_GET(MT_TXS0_TXS_FORMAT, txs) > 1) {
- stats->tx_bytes +=
-- le32_get_bits(txs_data[5], MT_TXS5_MPDU_TX_BYTE);
-- stats->tx_packets +=
-- le32_get_bits(txs_data[5], MT_TXS5_MPDU_TX_CNT);
-+ le32_get_bits(txs_data[5], MT_TXS5_MPDU_TX_BYTE) -
-+ le32_get_bits(txs_data[7], MT_TXS7_MPDU_RETRY_BYTE);
- stats->tx_failed +=
- le32_get_bits(txs_data[6], MT_TXS6_MPDU_FAIL_CNT);
- stats->tx_retries +=
-@@ -728,17 +731,15 @@ bool mt76_connac2_mac_add_txs_skb(struct mt76_dev *dev, struct mt76_wcid *wcid,
- skb = mt76_tx_status_skb_get(dev, wcid, pid, &list);
- if (skb) {
- struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
-- bool noacked = !(info->flags & IEEE80211_TX_STAT_ACK);
-
- if (!(le32_to_cpu(txs_data[0]) & MT_TXS0_ACK_ERROR_MASK))
- info->flags |= IEEE80211_TX_STAT_ACK;
-
- info->status.ampdu_len = 1;
-- info->status.ampdu_ack_len = !noacked;
-+ info->status.ampdu_ack_len =
-+ !!(info->flags & IEEE80211_TX_STAT_ACK);
- info->status.rates[0].idx = -1;
-
-- wcid->stats.tx_failed += noacked;
--
- mt76_connac2_mac_fill_txs(dev, wcid, txs_data);
- mt76_tx_status_skb_done(dev, skb, &list);
- }
-@@ -1111,3 +1112,85 @@ int mt76_connac2_mac_fill_rx_rate(struct mt76_dev *dev,
- return 0;
- }
- EXPORT_SYMBOL_GPL(mt76_connac2_mac_fill_rx_rate);
-+
-+void mt76_connac2_tx_check_aggr(struct ieee80211_sta *sta, __le32 *txwi)
-+{
-+ struct mt76_wcid *wcid;
-+ u16 fc, tid;
-+ u32 val;
-+
-+ if (!sta ||
-+ !(sta->deflink.ht_cap.ht_supported || sta->deflink.he_cap.has_he))
-+ return;
-+
-+ tid = le32_get_bits(txwi[1], MT_TXD1_TID);
-+ if (tid >= 6) /* skip VO queue */
-+ return;
-+
-+ val = le32_to_cpu(txwi[2]);
-+ fc = FIELD_GET(MT_TXD2_FRAME_TYPE, val) << 2 |
-+ FIELD_GET(MT_TXD2_SUB_TYPE, val) << 4;
-+ if (unlikely(fc != (IEEE80211_FTYPE_DATA | IEEE80211_STYPE_QOS_DATA)))
-+ return;
-+
-+ wcid = (struct mt76_wcid *)sta->drv_priv;
-+ if (!test_and_set_bit(tid, &wcid->ampdu_state))
-+ ieee80211_start_tx_ba_session(sta, tid, 0);
-+}
-+EXPORT_SYMBOL_GPL(mt76_connac2_tx_check_aggr);
-+
-+void mt76_connac2_txwi_free(struct mt76_dev *dev, struct mt76_txwi_cache *t,
-+ struct ieee80211_sta *sta,
-+ struct list_head *free_list)
-+{
-+ struct mt76_wcid *wcid;
-+ __le32 *txwi;
-+ u16 wcid_idx;
-+
-+ mt76_connac_txp_skb_unmap(dev, t);
-+ if (!t->skb)
-+ goto out;
-+
-+ txwi = (__le32 *)mt76_get_txwi_ptr(dev, t);
-+ if (sta) {
-+ wcid = (struct mt76_wcid *)sta->drv_priv;
-+ wcid_idx = wcid->idx;
-+ } else {
-+ wcid_idx = le32_get_bits(txwi[1], MT_TXD1_WLAN_IDX);
-+ wcid = rcu_dereference(dev->wcid[wcid_idx]);
-+
-+ if (wcid && wcid->sta) {
-+ sta = container_of((void *)wcid, struct ieee80211_sta,
-+ drv_priv);
-+ spin_lock_bh(&dev->sta_poll_lock);
-+ if (list_empty(&wcid->poll_list))
-+ list_add_tail(&wcid->poll_list,
-+ &dev->sta_poll_list);
-+ spin_unlock_bh(&dev->sta_poll_lock);
-+ }
-+ }
-+
-+ if (sta && likely(t->skb->protocol != cpu_to_be16(ETH_P_PAE)))
-+ mt76_connac2_tx_check_aggr(sta, txwi);
-+
-+ __mt76_tx_complete_skb(dev, wcid_idx, t->skb, free_list);
-+out:
-+ t->skb = NULL;
-+ mt76_put_txwi(dev, t);
-+}
-+EXPORT_SYMBOL_GPL(mt76_connac2_txwi_free);
-+
-+void mt76_connac2_tx_token_put(struct mt76_dev *dev)
-+{
-+ struct mt76_txwi_cache *txwi;
-+ int id;
-+
-+ spin_lock_bh(&dev->token_lock);
-+ idr_for_each_entry(&dev->token, txwi, id) {
-+ mt76_connac2_txwi_free(dev, txwi, NULL, NULL);
-+ dev->token_count--;
-+ }
-+ spin_unlock_bh(&dev->token_lock);
-+ idr_destroy(&dev->token);
-+}
-+EXPORT_SYMBOL_GPL(mt76_connac2_tx_token_put);
-diff --git a/mt76_connac_mcu.c b/mt76_connac_mcu.c
-index 46f69aa8..0f0a519f 100644
---- a/mt76_connac_mcu.c
-+++ b/mt76_connac_mcu.c
-@@ -1221,6 +1221,9 @@ EXPORT_SYMBOL_GPL(mt76_connac_mcu_sta_ba_tlv);
-
- int mt76_connac_mcu_sta_wed_update(struct mt76_dev *dev, struct sk_buff *skb)
- {
-+ if (!mt76_is_mmio(dev))
-+ return 0;
-+
- if (!mtk_wed_device_active(&dev->mmio.wed))
- return 0;
-
-diff --git a/mt76_connac_mcu.h b/mt76_connac_mcu.h
-index 91d98eff..fe729bbf 100644
---- a/mt76_connac_mcu.h
-+++ b/mt76_connac_mcu.h
-@@ -22,6 +22,7 @@
-
- #define FW_START_OVERRIDE BIT(0)
- #define FW_START_WORKING_PDA_CR4 BIT(2)
-+#define FW_START_WORKING_PDA_DSP BIT(3)
-
- #define PATCH_SEC_NOT_SUPPORT GENMASK(31, 0)
- #define PATCH_SEC_TYPE_MASK GENMASK(15, 0)
-@@ -518,7 +519,8 @@ struct sta_rec_muru {
- u8 uo_ra;
- u8 he_2x996_tone;
- u8 rx_t_frame_11ac;
-- u8 rsv[3];
-+ u8 rx_ctrl_frame_to_mbss;
-+ u8 rsv[2];
- } ofdma_ul;
-
- struct {
-@@ -998,6 +1000,7 @@ enum {
- MCU_EXT_EVENT_ASSERT_DUMP = 0x23,
- MCU_EXT_EVENT_RDD_REPORT = 0x3a,
- MCU_EXT_EVENT_CSA_NOTIFY = 0x4f,
-+ MCU_EXT_EVENT_WA_TX_STAT = 0x74,
- MCU_EXT_EVENT_BCC_NOTIFY = 0x75,
- MCU_EXT_EVENT_MURU_CTRL = 0x9f,
- };
-@@ -1287,6 +1290,7 @@ enum {
- UNI_BSS_INFO_UAPSD = 19,
- UNI_BSS_INFO_PS = 21,
- UNI_BSS_INFO_BCNFT = 22,
-+ UNI_BSS_INFO_IFS_TIME = 23,
- UNI_BSS_INFO_OFFLOAD = 25,
- UNI_BSS_INFO_MLD = 26,
- };
-diff --git a/mt76x02_util.c b/mt76x02_util.c
-index dcbb5c60..a9b77083 100644
---- a/mt76x02_util.c
-+++ b/mt76x02_util.c
-@@ -413,12 +413,9 @@ int mt76x02_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
- struct mt76x02_sta *msta;
- struct mt76_wcid *wcid;
- int idx = key->keyidx;
-- int ret;
-
- /* fall back to sw encryption for unsupported ciphers */
- switch (key->cipher) {
-- case WLAN_CIPHER_SUITE_WEP40:
-- case WLAN_CIPHER_SUITE_WEP104:
- case WLAN_CIPHER_SUITE_TKIP:
- case WLAN_CIPHER_SUITE_CCMP:
- break;
-@@ -471,16 +468,6 @@ int mt76x02_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
- }
- mt76_wcid_key_setup(&dev->mt76, wcid, key);
-
-- if (!msta) {
-- if (key || wcid->hw_key_idx == idx) {
-- ret = mt76x02_mac_wcid_set_key(dev, wcid->idx, key);
-- if (ret)
-- return ret;
-- }
--
-- return mt76x02_mac_shared_key_setup(dev, mvif->idx, idx, key);
-- }
--
- return mt76x02_mac_wcid_set_key(dev, msta->wcid.idx, key);
- }
- EXPORT_SYMBOL_GPL(mt76x02_set_key);
-diff --git a/mt7915/debugfs.c b/mt7915/debugfs.c
-index 879884ea..6c3696c8 100644
---- a/mt7915/debugfs.c
-+++ b/mt7915/debugfs.c
-@@ -251,7 +251,6 @@ static int mt7915_muru_stats_show(struct seq_file *file, void *data)
- {
- struct mt7915_phy *phy = file->private;
- struct mt7915_dev *dev = phy->dev;
-- struct mt7915_mcu_muru_stats mu_stats = {};
- static const char * const dl_non_he_type[] = {
- "CCK", "OFDM", "HT MIX", "HT GF",
- "VHT SU", "VHT 2MU", "VHT 3MU", "VHT 4MU"
-@@ -275,7 +274,7 @@ static int mt7915_muru_stats_show(struct seq_file *file, void *data)
-
- mutex_lock(&dev->mt76.mutex);
-
-- ret = mt7915_mcu_muru_debug_get(phy, &mu_stats);
-+ ret = mt7915_mcu_muru_debug_get(phy);
- if (ret)
- goto exit;
-
-@@ -285,14 +284,13 @@ static int mt7915_muru_stats_show(struct seq_file *file, void *data)
- for (i = 0; i < 5; i++)
- seq_printf(file, "%8s | ", dl_non_he_type[i]);
-
--#define __dl_u32(s) le32_to_cpu(mu_stats.dl.s)
- seq_puts(file, "\nTotal Count:");
- seq_printf(file, "%8u | %8u | %8u | %8u | %8u | ",
-- __dl_u32(cck_cnt),
-- __dl_u32(ofdm_cnt),
-- __dl_u32(htmix_cnt),
-- __dl_u32(htgf_cnt),
-- __dl_u32(vht_su_cnt));
-+ phy->mib.dl_cck_cnt,
-+ phy->mib.dl_ofdm_cnt,
-+ phy->mib.dl_htmix_cnt,
-+ phy->mib.dl_htgf_cnt,
-+ phy->mib.dl_vht_su_cnt);
-
- seq_puts(file, "\nDownlink MU-MIMO\nData Type: ");
-
-@@ -301,23 +299,23 @@ static int mt7915_muru_stats_show(struct seq_file *file, void *data)
-
- seq_puts(file, "\nTotal Count:");
- seq_printf(file, "%8u | %8u | %8u | ",
-- __dl_u32(vht_2mu_cnt),
-- __dl_u32(vht_3mu_cnt),
-- __dl_u32(vht_4mu_cnt));
-+ phy->mib.dl_vht_2mu_cnt,
-+ phy->mib.dl_vht_3mu_cnt,
-+ phy->mib.dl_vht_4mu_cnt);
-
-- sub_total_cnt = __dl_u32(vht_2mu_cnt) +
-- __dl_u32(vht_3mu_cnt) +
-- __dl_u32(vht_4mu_cnt);
-+ sub_total_cnt = phy->mib.dl_vht_2mu_cnt +
-+ phy->mib.dl_vht_3mu_cnt +
-+ phy->mib.dl_vht_4mu_cnt;
-
- seq_printf(file, "\nTotal non-HE MU-MIMO DL PPDU count: %lld",
- sub_total_cnt);
-
- total_ppdu_cnt = sub_total_cnt +
-- __dl_u32(cck_cnt) +
-- __dl_u32(ofdm_cnt) +
-- __dl_u32(htmix_cnt) +
-- __dl_u32(htgf_cnt) +
-- __dl_u32(vht_su_cnt);
-+ phy->mib.dl_cck_cnt +
-+ phy->mib.dl_ofdm_cnt +
-+ phy->mib.dl_htmix_cnt +
-+ phy->mib.dl_htgf_cnt +
-+ phy->mib.dl_vht_su_cnt;
-
- seq_printf(file, "\nAll non-HE DL PPDU count: %lld", total_ppdu_cnt);
-
-@@ -329,8 +327,7 @@ static int mt7915_muru_stats_show(struct seq_file *file, void *data)
-
- seq_puts(file, "\nTotal Count:");
- seq_printf(file, "%8u | %8u | ",
-- __dl_u32(he_su_cnt),
-- __dl_u32(he_ext_su_cnt));
-+ phy->mib.dl_he_su_cnt, phy->mib.dl_he_ext_su_cnt);
-
- seq_puts(file, "\nDownlink MU-MIMO\nData Type: ");
-
-@@ -339,9 +336,8 @@ static int mt7915_muru_stats_show(struct seq_file *file, void *data)
-
- seq_puts(file, "\nTotal Count:");
- seq_printf(file, "%8u | %8u | %8u | ",
-- __dl_u32(he_2mu_cnt),
-- __dl_u32(he_3mu_cnt),
-- __dl_u32(he_4mu_cnt));
-+ phy->mib.dl_he_2mu_cnt, phy->mib.dl_he_3mu_cnt,
-+ phy->mib.dl_he_4mu_cnt);
-
- seq_puts(file, "\nDownlink OFDMA\nData Type: ");
-
-@@ -350,37 +346,35 @@ static int mt7915_muru_stats_show(struct seq_file *file, void *data)
-
- seq_puts(file, "\nTotal Count:");
- seq_printf(file, "%8u | %8u | %8u | %8u | %9u | %8u | ",
-- __dl_u32(he_2ru_cnt),
-- __dl_u32(he_3ru_cnt),
-- __dl_u32(he_4ru_cnt),
-- __dl_u32(he_5to8ru_cnt),
-- __dl_u32(he_9to16ru_cnt),
-- __dl_u32(he_gtr16ru_cnt));
--
-- sub_total_cnt = __dl_u32(he_2mu_cnt) +
-- __dl_u32(he_3mu_cnt) +
-- __dl_u32(he_4mu_cnt);
-+ phy->mib.dl_he_2ru_cnt,
-+ phy->mib.dl_he_3ru_cnt,
-+ phy->mib.dl_he_4ru_cnt,
-+ phy->mib.dl_he_5to8ru_cnt,
-+ phy->mib.dl_he_9to16ru_cnt,
-+ phy->mib.dl_he_gtr16ru_cnt);
-+
-+ sub_total_cnt = phy->mib.dl_he_2mu_cnt +
-+ phy->mib.dl_he_3mu_cnt +
-+ phy->mib.dl_he_4mu_cnt;
- total_ppdu_cnt = sub_total_cnt;
-
- seq_printf(file, "\nTotal HE MU-MIMO DL PPDU count: %lld",
- sub_total_cnt);
-
-- sub_total_cnt = __dl_u32(he_2ru_cnt) +
-- __dl_u32(he_3ru_cnt) +
-- __dl_u32(he_4ru_cnt) +
-- __dl_u32(he_5to8ru_cnt) +
-- __dl_u32(he_9to16ru_cnt) +
-- __dl_u32(he_gtr16ru_cnt);
-+ sub_total_cnt = phy->mib.dl_he_2ru_cnt +
-+ phy->mib.dl_he_3ru_cnt +
-+ phy->mib.dl_he_4ru_cnt +
-+ phy->mib.dl_he_5to8ru_cnt +
-+ phy->mib.dl_he_9to16ru_cnt +
-+ phy->mib.dl_he_gtr16ru_cnt;
- total_ppdu_cnt += sub_total_cnt;
-
- seq_printf(file, "\nTotal HE OFDMA DL PPDU count: %lld",
- sub_total_cnt);
-
-- total_ppdu_cnt += __dl_u32(he_su_cnt) +
-- __dl_u32(he_ext_su_cnt);
-+ total_ppdu_cnt += phy->mib.dl_he_su_cnt + phy->mib.dl_he_ext_su_cnt;
-
- seq_printf(file, "\nAll HE DL PPDU count: %lld", total_ppdu_cnt);
--#undef __dl_u32
-
- /* HE Uplink */
- seq_puts(file, "\n\nUplink");
-@@ -389,12 +383,11 @@ static int mt7915_muru_stats_show(struct seq_file *file, void *data)
- for (i = 0; i < 3; i++)
- seq_printf(file, "%8s | ", ul_he_type[i]);
-
--#define __ul_u32(s) le32_to_cpu(mu_stats.ul.s)
- seq_puts(file, "\nTotal Count:");
- seq_printf(file, "%8u | %8u | %8u | ",
-- __ul_u32(hetrig_2mu_cnt),
-- __ul_u32(hetrig_3mu_cnt),
-- __ul_u32(hetrig_4mu_cnt));
-+ phy->mib.ul_hetrig_2mu_cnt,
-+ phy->mib.ul_hetrig_3mu_cnt,
-+ phy->mib.ul_hetrig_4mu_cnt);
-
- seq_puts(file, "\nTrigger-based Uplink OFDMA\nData Type: ");
-
-@@ -403,37 +396,36 @@ static int mt7915_muru_stats_show(struct seq_file *file, void *data)
-
- seq_puts(file, "\nTotal Count:");
- seq_printf(file, "%8u | %8u | %8u | %8u | %8u | %9u | %7u | ",
-- __ul_u32(hetrig_su_cnt),
-- __ul_u32(hetrig_2ru_cnt),
-- __ul_u32(hetrig_3ru_cnt),
-- __ul_u32(hetrig_4ru_cnt),
-- __ul_u32(hetrig_5to8ru_cnt),
-- __ul_u32(hetrig_9to16ru_cnt),
-- __ul_u32(hetrig_gtr16ru_cnt));
--
-- sub_total_cnt = __ul_u32(hetrig_2mu_cnt) +
-- __ul_u32(hetrig_3mu_cnt) +
-- __ul_u32(hetrig_4mu_cnt);
-+ phy->mib.ul_hetrig_su_cnt,
-+ phy->mib.ul_hetrig_2ru_cnt,
-+ phy->mib.ul_hetrig_3ru_cnt,
-+ phy->mib.ul_hetrig_4ru_cnt,
-+ phy->mib.ul_hetrig_5to8ru_cnt,
-+ phy->mib.ul_hetrig_9to16ru_cnt,
-+ phy->mib.ul_hetrig_gtr16ru_cnt);
-+
-+ sub_total_cnt = phy->mib.ul_hetrig_2mu_cnt +
-+ phy->mib.ul_hetrig_3mu_cnt +
-+ phy->mib.ul_hetrig_4mu_cnt;
- total_ppdu_cnt = sub_total_cnt;
-
- seq_printf(file, "\nTotal HE MU-MIMO UL TB PPDU count: %lld",
- sub_total_cnt);
-
-- sub_total_cnt = __ul_u32(hetrig_2ru_cnt) +
-- __ul_u32(hetrig_3ru_cnt) +
-- __ul_u32(hetrig_4ru_cnt) +
-- __ul_u32(hetrig_5to8ru_cnt) +
-- __ul_u32(hetrig_9to16ru_cnt) +
-- __ul_u32(hetrig_gtr16ru_cnt);
-+ sub_total_cnt = phy->mib.ul_hetrig_2ru_cnt +
-+ phy->mib.ul_hetrig_3ru_cnt +
-+ phy->mib.ul_hetrig_4ru_cnt +
-+ phy->mib.ul_hetrig_5to8ru_cnt +
-+ phy->mib.ul_hetrig_9to16ru_cnt +
-+ phy->mib.ul_hetrig_gtr16ru_cnt;
- total_ppdu_cnt += sub_total_cnt;
-
- seq_printf(file, "\nTotal HE OFDMA UL TB PPDU count: %lld",
- sub_total_cnt);
-
-- total_ppdu_cnt += __ul_u32(hetrig_su_cnt);
-+ total_ppdu_cnt += phy->mib.ul_hetrig_su_cnt;
-
- seq_printf(file, "\nAll HE UL TB PPDU count: %lld\n", total_ppdu_cnt);
--#undef __ul_u32
-
- exit:
- mutex_unlock(&dev->mt76.mutex);
-@@ -719,10 +711,10 @@ mt7915_ampdu_stat_read_phy(struct mt7915_phy *phy,
- static void
- mt7915_txbf_stat_read_phy(struct mt7915_phy *phy, struct seq_file *s)
- {
-+ struct mt76_mib_stats *mib = &phy->mib;
- static const char * const bw[] = {
- "BW20", "BW40", "BW80", "BW160"
- };
-- struct mib_stats *mib = &phy->mib;
-
- /* Tx Beamformer monitor */
- seq_puts(s, "\nTx Beamformer applied PPDU counts: ");
-@@ -768,7 +760,7 @@ mt7915_tx_stats_show(struct seq_file *file, void *data)
- {
- struct mt7915_phy *phy = file->private;
- struct mt7915_dev *dev = phy->dev;
-- struct mib_stats *mib = &phy->mib;
-+ struct mt76_mib_stats *mib = &phy->mib;
- int i;
-
- mutex_lock(&dev->mt76.mutex);
-diff --git a/mt7915/dma.c b/mt7915/dma.c
-index 86a93ded..59a44d79 100644
---- a/mt7915/dma.c
-+++ b/mt7915/dma.c
-@@ -250,12 +250,90 @@ static void mt7915_dma_disable(struct mt7915_dev *dev, bool rst)
- }
- }
-
--static int mt7915_dma_enable(struct mt7915_dev *dev)
-+int mt7915_dma_start(struct mt7915_dev *dev, bool reset, bool wed_reset)
- {
- struct mt76_dev *mdev = &dev->mt76;
- u32 hif1_ofs = 0;
- u32 irq_mask;
-
-+ if (dev->hif2)
-+ hif1_ofs = MT_WFDMA0_PCIE1(0) - MT_WFDMA0(0);
-+
-+ /* enable wpdma tx/rx */
-+ if (!reset) {
-+ mt76_set(dev, MT_WFDMA0_GLO_CFG,
-+ MT_WFDMA0_GLO_CFG_TX_DMA_EN |
-+ MT_WFDMA0_GLO_CFG_RX_DMA_EN |
-+ MT_WFDMA0_GLO_CFG_OMIT_TX_INFO |
-+ MT_WFDMA0_GLO_CFG_OMIT_RX_INFO_PFET2);
-+
-+ if (is_mt7915(mdev))
-+ mt76_set(dev, MT_WFDMA1_GLO_CFG,
-+ MT_WFDMA1_GLO_CFG_TX_DMA_EN |
-+ MT_WFDMA1_GLO_CFG_RX_DMA_EN |
-+ MT_WFDMA1_GLO_CFG_OMIT_TX_INFO |
-+ MT_WFDMA1_GLO_CFG_OMIT_RX_INFO);
-+
-+ if (dev->hif2) {
-+ mt76_set(dev, MT_WFDMA0_GLO_CFG + hif1_ofs,
-+ MT_WFDMA0_GLO_CFG_TX_DMA_EN |
-+ MT_WFDMA0_GLO_CFG_RX_DMA_EN |
-+ MT_WFDMA0_GLO_CFG_OMIT_TX_INFO |
-+ MT_WFDMA0_GLO_CFG_OMIT_RX_INFO_PFET2);
-+
-+ if (is_mt7915(mdev))
-+ mt76_set(dev, MT_WFDMA1_GLO_CFG + hif1_ofs,
-+ MT_WFDMA1_GLO_CFG_TX_DMA_EN |
-+ MT_WFDMA1_GLO_CFG_RX_DMA_EN |
-+ MT_WFDMA1_GLO_CFG_OMIT_TX_INFO |
-+ MT_WFDMA1_GLO_CFG_OMIT_RX_INFO);
-+
-+ mt76_set(dev, MT_WFDMA_HOST_CONFIG,
-+ MT_WFDMA_HOST_CONFIG_PDMA_BAND);
-+ }
-+ }
-+
-+ /* enable interrupts for TX/RX rings */
-+ irq_mask = MT_INT_RX_DONE_MCU |
-+ MT_INT_TX_DONE_MCU |
-+ MT_INT_MCU_CMD;
-+
-+ if (!dev->phy.mt76->band_idx)
-+ irq_mask |= MT_INT_BAND0_RX_DONE;
-+
-+ if (dev->dbdc_support || dev->phy.mt76->band_idx)
-+ irq_mask |= MT_INT_BAND1_RX_DONE;
-+
-+ if (mtk_wed_device_active(&dev->mt76.mmio.wed) && wed_reset) {
-+ u32 wed_irq_mask = irq_mask;
-+ int ret;
-+
-+ wed_irq_mask |= MT_INT_TX_DONE_BAND0 | MT_INT_TX_DONE_BAND1;
-+ if (!is_mt798x(&dev->mt76))
-+ mt76_wr(dev, MT_INT_WED_MASK_CSR, wed_irq_mask);
-+ else
-+ mt76_wr(dev, MT_INT_MASK_CSR, wed_irq_mask);
-+
-+ ret = mt7915_mcu_wed_enable_rx_stats(dev);
-+ if (ret)
-+ return ret;
-+
-+ mtk_wed_device_start(&dev->mt76.mmio.wed, wed_irq_mask);
-+ }
-+
-+ irq_mask = reset ? MT_INT_MCU_CMD : irq_mask;
-+
-+ mt7915_irq_enable(dev, irq_mask);
-+ mt7915_irq_disable(dev, 0);
-+
-+ return 0;
-+}
-+
-+static int mt7915_dma_enable(struct mt7915_dev *dev, bool reset)
-+{
-+ struct mt76_dev *mdev = &dev->mt76;
-+ u32 hif1_ofs = 0;
-+
- if (dev->hif2)
- hif1_ofs = MT_WFDMA0_PCIE1(0) - MT_WFDMA0(0);
-
-@@ -322,69 +400,7 @@ static int mt7915_dma_enable(struct mt7915_dev *dev)
- mt76_poll(dev, MT_WFDMA_EXT_CSR_HIF_MISC,
- MT_WFDMA_EXT_CSR_HIF_MISC_BUSY, 0, 1000);
-
-- /* set WFDMA Tx/Rx */
-- mt76_set(dev, MT_WFDMA0_GLO_CFG,
-- MT_WFDMA0_GLO_CFG_TX_DMA_EN |
-- MT_WFDMA0_GLO_CFG_RX_DMA_EN |
-- MT_WFDMA0_GLO_CFG_OMIT_TX_INFO |
-- MT_WFDMA0_GLO_CFG_OMIT_RX_INFO_PFET2);
--
-- if (is_mt7915(mdev))
-- mt76_set(dev, MT_WFDMA1_GLO_CFG,
-- MT_WFDMA1_GLO_CFG_TX_DMA_EN |
-- MT_WFDMA1_GLO_CFG_RX_DMA_EN |
-- MT_WFDMA1_GLO_CFG_OMIT_TX_INFO |
-- MT_WFDMA1_GLO_CFG_OMIT_RX_INFO);
--
-- if (dev->hif2) {
-- mt76_set(dev, MT_WFDMA0_GLO_CFG + hif1_ofs,
-- MT_WFDMA0_GLO_CFG_TX_DMA_EN |
-- MT_WFDMA0_GLO_CFG_RX_DMA_EN |
-- MT_WFDMA0_GLO_CFG_OMIT_TX_INFO |
-- MT_WFDMA0_GLO_CFG_OMIT_RX_INFO_PFET2);
--
-- if (is_mt7915(mdev))
-- mt76_set(dev, MT_WFDMA1_GLO_CFG + hif1_ofs,
-- MT_WFDMA1_GLO_CFG_TX_DMA_EN |
-- MT_WFDMA1_GLO_CFG_RX_DMA_EN |
-- MT_WFDMA1_GLO_CFG_OMIT_TX_INFO |
-- MT_WFDMA1_GLO_CFG_OMIT_RX_INFO);
--
-- mt76_set(dev, MT_WFDMA_HOST_CONFIG,
-- MT_WFDMA_HOST_CONFIG_PDMA_BAND);
-- }
--
-- /* enable interrupts for TX/RX rings */
-- irq_mask = MT_INT_RX_DONE_MCU |
-- MT_INT_TX_DONE_MCU |
-- MT_INT_MCU_CMD;
--
-- if (!dev->phy.mt76->band_idx)
-- irq_mask |= MT_INT_BAND0_RX_DONE;
--
-- if (dev->dbdc_support || dev->phy.mt76->band_idx)
-- irq_mask |= MT_INT_BAND1_RX_DONE;
--
-- if (mtk_wed_device_active(&dev->mt76.mmio.wed)) {
-- u32 wed_irq_mask = irq_mask;
-- int ret;
--
-- wed_irq_mask |= MT_INT_TX_DONE_BAND0 | MT_INT_TX_DONE_BAND1;
-- if (!is_mt798x(&dev->mt76))
-- mt76_wr(dev, MT_INT_WED_MASK_CSR, wed_irq_mask);
-- else
-- mt76_wr(dev, MT_INT_MASK_CSR, wed_irq_mask);
--
-- ret = mt7915_mcu_wed_enable_rx_stats(dev);
-- if (ret)
-- return ret;
--
-- mtk_wed_device_start(&dev->mt76.mmio.wed, wed_irq_mask);
-- }
--
-- mt7915_irq_enable(dev, irq_mask);
--
-- return 0;
-+ return mt7915_dma_start(dev, reset, true);
- }
-
- int mt7915_dma_init(struct mt7915_dev *dev, struct mt7915_phy *phy2)
-@@ -560,7 +576,7 @@ int mt7915_dma_init(struct mt7915_dev *dev, struct mt7915_phy *phy2)
- mt7915_poll_tx);
- napi_enable(&dev->mt76.tx_napi);
-
-- mt7915_dma_enable(dev);
-+ mt7915_dma_enable(dev, false);
-
- return 0;
- }
-@@ -642,7 +658,7 @@ int mt7915_dma_reset(struct mt7915_dev *dev, bool force)
- mt76_rmw(dev, MT_WFDMA0_EXT0_CFG, MT_WFDMA0_EXT0_RXWB_KEEP,
- MT_WFDMA0_EXT0_RXWB_KEEP);
-
-- mt7915_dma_enable(dev);
-+ mt7915_dma_enable(dev, !force);
-
- return 0;
- }
-diff --git a/mt7915/init.c b/mt7915/init.c
-index f85f7d39..e156a3c2 100644
---- a/mt7915/init.c
-+++ b/mt7915/init.c
-@@ -505,6 +505,12 @@ mt7915_mac_init_band(struct mt7915_dev *dev, u8 band)
- set = FIELD_PREP(MT_WTBLOFF_TOP_RSCR_RCPI_MODE, 0) |
- FIELD_PREP(MT_WTBLOFF_TOP_RSCR_RCPI_PARAM, 0x3);
- mt76_rmw(dev, MT_WTBLOFF_TOP_RSCR(band), mask, set);
-+
-+ /* MT_TXD5_TX_STATUS_HOST (MPDU format) has higher priority than
-+ * MT_AGG_ACR_PPDU_TXS2H (PPDU format) even though ACR bit is set.
-+ */
-+ if (mtk_wed_device_active(&dev->mt76.mmio.wed))
-+ mt76_set(dev, MT_AGG_ACR4(band), MT_AGG_ACR_PPDU_TXS2H);
- }
-
- static void
-@@ -587,6 +593,8 @@ void mt7915_mac_init(struct mt7915_dev *dev)
-
- if (!is_mt7915(&dev->mt76))
- mt76_clear(dev, MT_MDP_DCR2, MT_MDP_DCR2_RX_TRANS_SHORT);
-+ else
-+ mt76_clear(dev, MT_PLE_HOST_RPT0, MT_PLE_HOST_RPT0_TX_LATENCY);
-
- /* enable hardware de-agg */
- mt76_set(dev, MT_MDP_DCR0, MT_MDP_DCR0_DAMSDU_EN);
-@@ -1164,7 +1172,7 @@ static void mt7915_unregister_ext_phy(struct mt7915_dev *dev)
- static void mt7915_stop_hardware(struct mt7915_dev *dev)
- {
- mt7915_mcu_exit(dev);
-- mt7915_tx_token_put(dev);
-+ mt76_connac2_tx_token_put(&dev->mt76);
- mt7915_dma_cleanup(dev);
- tasklet_disable(&dev->mt76.irq_tasklet);
-
-@@ -1183,9 +1191,7 @@ int mt7915_register_device(struct mt7915_dev *dev)
- INIT_WORK(&dev->rc_work, mt7915_mac_sta_rc_work);
- INIT_DELAYED_WORK(&dev->mphy.mac_work, mt7915_mac_work);
- INIT_LIST_HEAD(&dev->sta_rc_list);
-- INIT_LIST_HEAD(&dev->sta_poll_list);
- INIT_LIST_HEAD(&dev->twt_list);
-- spin_lock_init(&dev->sta_poll_lock);
-
- init_waitqueue_head(&dev->reset_wait);
- INIT_WORK(&dev->reset_work, mt7915_mac_reset_work);
-diff --git a/mt7915/mac.c b/mt7915/mac.c
-index fb6bab87..b8b0c0fd 100644
---- a/mt7915/mac.c
-+++ b/mt7915/mac.c
-@@ -105,9 +105,9 @@ static void mt7915_mac_sta_poll(struct mt7915_dev *dev)
- LIST_HEAD(sta_poll_list);
- int i;
-
-- spin_lock_bh(&dev->sta_poll_lock);
-- list_splice_init(&dev->sta_poll_list, &sta_poll_list);
-- spin_unlock_bh(&dev->sta_poll_lock);
-+ spin_lock_bh(&dev->mt76.sta_poll_lock);
-+ list_splice_init(&dev->mt76.sta_poll_list, &sta_poll_list);
-+ spin_unlock_bh(&dev->mt76.sta_poll_lock);
-
- rcu_read_lock();
-
-@@ -118,15 +118,15 @@ static void mt7915_mac_sta_poll(struct mt7915_dev *dev)
- s8 rssi[4];
- u8 bw;
-
-- spin_lock_bh(&dev->sta_poll_lock);
-+ spin_lock_bh(&dev->mt76.sta_poll_lock);
- if (list_empty(&sta_poll_list)) {
-- spin_unlock_bh(&dev->sta_poll_lock);
-+ spin_unlock_bh(&dev->mt76.sta_poll_lock);
- break;
- }
- msta = list_first_entry(&sta_poll_list,
-- struct mt7915_sta, poll_list);
-- list_del_init(&msta->poll_list);
-- spin_unlock_bh(&dev->sta_poll_lock);
-+ struct mt7915_sta, wcid.poll_list);
-+ list_del_init(&msta->wcid.poll_list);
-+ spin_unlock_bh(&dev->mt76.sta_poll_lock);
-
- idx = msta->wcid.idx;
-
-@@ -326,10 +326,11 @@ mt7915_mac_fill_rx(struct mt7915_dev *dev, struct sk_buff *skb,
-
- if (status->wcid) {
- msta = container_of(status->wcid, struct mt7915_sta, wcid);
-- spin_lock_bh(&dev->sta_poll_lock);
-- if (list_empty(&msta->poll_list))
-- list_add_tail(&msta->poll_list, &dev->sta_poll_list);
-- spin_unlock_bh(&dev->sta_poll_lock);
-+ spin_lock_bh(&dev->mt76.sta_poll_lock);
-+ if (list_empty(&msta->wcid.poll_list))
-+ list_add_tail(&msta->wcid.poll_list,
-+ &dev->mt76.sta_poll_list);
-+ spin_unlock_bh(&dev->mt76.sta_poll_lock);
- }
-
- status->freq = mphy->chandef.chan->center_freq;
-@@ -841,74 +842,6 @@ u32 mt7915_wed_init_buf(void *ptr, dma_addr_t phys, int token_id)
- return MT_TXD_SIZE + sizeof(*txp);
- }
-
--static void
--mt7915_tx_check_aggr(struct ieee80211_sta *sta, __le32 *txwi)
--{
-- struct mt7915_sta *msta;
-- u16 fc, tid;
-- u32 val;
--
-- if (!sta || !(sta->deflink.ht_cap.ht_supported || sta->deflink.he_cap.has_he))
-- return;
--
-- tid = le32_get_bits(txwi[1], MT_TXD1_TID);
-- if (tid >= 6) /* skip VO queue */
-- return;
--
-- val = le32_to_cpu(txwi[2]);
-- fc = FIELD_GET(MT_TXD2_FRAME_TYPE, val) << 2 |
-- FIELD_GET(MT_TXD2_SUB_TYPE, val) << 4;
-- if (unlikely(fc != (IEEE80211_FTYPE_DATA | IEEE80211_STYPE_QOS_DATA)))
-- return;
--
-- msta = (struct mt7915_sta *)sta->drv_priv;
-- if (!test_and_set_bit(tid, &msta->ampdu_state))
-- ieee80211_start_tx_ba_session(sta, tid, 0);
--}
--
--static void
--mt7915_txwi_free(struct mt7915_dev *dev, struct mt76_txwi_cache *t,
-- struct ieee80211_sta *sta, struct list_head *free_list)
--{
-- struct mt76_dev *mdev = &dev->mt76;
-- struct mt7915_sta *msta;
-- struct mt76_wcid *wcid;
-- __le32 *txwi;
-- u16 wcid_idx;
--
-- mt76_connac_txp_skb_unmap(mdev, t);
-- if (!t->skb)
-- goto out;
--
-- txwi = (__le32 *)mt76_get_txwi_ptr(mdev, t);
-- if (sta) {
-- wcid = (struct mt76_wcid *)sta->drv_priv;
-- wcid_idx = wcid->idx;
-- } else {
-- wcid_idx = le32_get_bits(txwi[1], MT_TXD1_WLAN_IDX);
-- wcid = rcu_dereference(dev->mt76.wcid[wcid_idx]);
--
-- if (wcid && wcid->sta) {
-- msta = container_of(wcid, struct mt7915_sta, wcid);
-- sta = container_of((void *)msta, struct ieee80211_sta,
-- drv_priv);
-- spin_lock_bh(&dev->sta_poll_lock);
-- if (list_empty(&msta->poll_list))
-- list_add_tail(&msta->poll_list, &dev->sta_poll_list);
-- spin_unlock_bh(&dev->sta_poll_lock);
-- }
-- }
--
-- if (sta && likely(t->skb->protocol != cpu_to_be16(ETH_P_PAE)))
-- mt7915_tx_check_aggr(sta, txwi);
--
-- __mt76_tx_complete_skb(mdev, wcid_idx, t->skb, free_list);
--
--out:
-- t->skb = NULL;
-- mt76_put_txwi(mdev, t);
--}
--
- static void
- mt7915_mac_tx_free_prepare(struct mt7915_dev *dev)
- {
-@@ -951,6 +884,7 @@ mt7915_mac_tx_free(struct mt7915_dev *dev, void *data, int len)
- struct mt76_dev *mdev = &dev->mt76;
- struct mt76_txwi_cache *txwi;
- struct ieee80211_sta *sta = NULL;
-+ struct mt76_wcid *wcid = NULL;
- LIST_HEAD(free_list);
- void *end = data + len;
- bool v3, wake = false;
-@@ -977,7 +911,6 @@ mt7915_mac_tx_free(struct mt7915_dev *dev, void *data, int len)
- info = le32_to_cpu(*cur_info);
- if (info & MT_TX_FREE_PAIR) {
- struct mt7915_sta *msta;
-- struct mt76_wcid *wcid;
- u16 idx;
-
- idx = FIELD_GET(MT_TX_FREE_WLAN_ID, info);
-@@ -987,14 +920,33 @@ mt7915_mac_tx_free(struct mt7915_dev *dev, void *data, int len)
- continue;
-
- msta = container_of(wcid, struct mt7915_sta, wcid);
-- spin_lock_bh(&dev->sta_poll_lock);
-- if (list_empty(&msta->poll_list))
-- list_add_tail(&msta->poll_list, &dev->sta_poll_list);
-- spin_unlock_bh(&dev->sta_poll_lock);
-+ spin_lock_bh(&mdev->sta_poll_lock);
-+ if (list_empty(&msta->wcid.poll_list))
-+ list_add_tail(&msta->wcid.poll_list,
-+ &mdev->sta_poll_list);
-+ spin_unlock_bh(&mdev->sta_poll_lock);
- continue;
- }
-
-- if (v3 && (info & MT_TX_FREE_MPDU_HEADER))
-+ if (!mtk_wed_device_active(&mdev->mmio.wed) && wcid) {
-+ u32 tx_retries = 0, tx_failed = 0;
-+
-+ if (v3 && (info & MT_TX_FREE_MPDU_HEADER_V3)) {
-+ tx_retries =
-+ FIELD_GET(MT_TX_FREE_COUNT_V3, info) - 1;
-+ tx_failed = tx_retries +
-+ !!FIELD_GET(MT_TX_FREE_STAT_V3, info);
-+ } else if (!v3 && (info & MT_TX_FREE_MPDU_HEADER)) {
-+ tx_retries =
-+ FIELD_GET(MT_TX_FREE_COUNT, info) - 1;
-+ tx_failed = tx_retries +
-+ !!FIELD_GET(MT_TX_FREE_STAT, info);
-+ }
-+ wcid->stats.tx_retries += tx_retries;
-+ wcid->stats.tx_failed += tx_failed;
-+ }
-+
-+ if (v3 && (info & MT_TX_FREE_MPDU_HEADER_V3))
- continue;
-
- for (i = 0; i < 1 + v3; i++) {
-@@ -1010,7 +962,7 @@ mt7915_mac_tx_free(struct mt7915_dev *dev, void *data, int len)
- if (!txwi)
- continue;
-
-- mt7915_txwi_free(dev, txwi, sta, &free_list);
-+ mt76_connac2_txwi_free(mdev, txwi, sta, &free_list);
- }
- }
-
-@@ -1042,7 +994,7 @@ mt7915_mac_tx_free_v0(struct mt7915_dev *dev, void *data, int len)
- if (!txwi)
- continue;
-
-- mt7915_txwi_free(dev, txwi, NULL, &free_list);
-+ mt76_connac2_txwi_free(mdev, txwi, NULL, &free_list);
- }
-
- mt7915_mac_tx_free_done(dev, &free_list, wake);
-@@ -1081,10 +1033,10 @@ static void mt7915_mac_add_txs(struct mt7915_dev *dev, void *data)
- if (!wcid->sta)
- goto out;
-
-- spin_lock_bh(&dev->sta_poll_lock);
-- if (list_empty(&msta->poll_list))
-- list_add_tail(&msta->poll_list, &dev->sta_poll_list);
-- spin_unlock_bh(&dev->sta_poll_lock);
-+ spin_lock_bh(&dev->mt76.sta_poll_lock);
-+ if (list_empty(&msta->wcid.poll_list))
-+ list_add_tail(&msta->wcid.poll_list, &dev->mt76.sta_poll_list);
-+ spin_unlock_bh(&dev->mt76.sta_poll_lock);
-
- out:
- rcu_read_unlock();
-@@ -1357,20 +1309,6 @@ mt7915_update_beacons(struct mt7915_dev *dev)
- mt7915_update_vif_beacon, mphy_ext->hw);
- }
-
--void mt7915_tx_token_put(struct mt7915_dev *dev)
--{
-- struct mt76_txwi_cache *txwi;
-- int id;
--
-- spin_lock_bh(&dev->mt76.token_lock);
-- idr_for_each_entry(&dev->mt76.token, txwi, id) {
-- mt7915_txwi_free(dev, txwi, NULL, NULL);
-- dev->mt76.token_count--;
-- }
-- spin_unlock_bh(&dev->mt76.token_lock);
-- idr_destroy(&dev->mt76.token);
--}
--
- static int
- mt7915_mac_restart(struct mt7915_dev *dev)
- {
-@@ -1389,8 +1327,12 @@ mt7915_mac_restart(struct mt7915_dev *dev)
-
- if (dev_is_pci(mdev->dev)) {
- mt76_wr(dev, MT_PCIE_MAC_INT_ENABLE, 0x0);
-- if (dev->hif2)
-- mt76_wr(dev, MT_PCIE1_MAC_INT_ENABLE, 0x0);
-+ if (dev->hif2) {
-+ if (is_mt7915(mdev))
-+ mt76_wr(dev, MT_PCIE1_MAC_INT_ENABLE, 0x0);
-+ else
-+ mt76_wr(dev, MT_PCIE1_MAC_INT_ENABLE_MT7916, 0x0);
-+ }
- }
-
- set_bit(MT76_RESET, &dev->mphy.state);
-@@ -1415,7 +1357,7 @@ mt7915_mac_restart(struct mt7915_dev *dev)
- napi_disable(&dev->mt76.tx_napi);
-
- /* token reinit */
-- mt7915_tx_token_put(dev);
-+ mt76_connac2_tx_token_put(&dev->mt76);
- idr_init(&dev->mt76.token);
-
- mt7915_dma_reset(dev, true);
-@@ -1440,8 +1382,12 @@ mt7915_mac_restart(struct mt7915_dev *dev)
- }
- if (dev_is_pci(mdev->dev)) {
- mt76_wr(dev, MT_PCIE_MAC_INT_ENABLE, 0xff);
-- if (dev->hif2)
-- mt76_wr(dev, MT_PCIE1_MAC_INT_ENABLE, 0xff);
-+ if (dev->hif2) {
-+ if (is_mt7915(mdev))
-+ mt76_wr(dev, MT_PCIE1_MAC_INT_ENABLE, 0xff);
-+ else
-+ mt76_wr(dev, MT_PCIE1_MAC_INT_ENABLE_MT7916, 0xff);
-+ }
- }
-
- /* load firmware */
-@@ -1604,13 +1550,19 @@ void mt7915_mac_reset_work(struct work_struct *work)
- if (mt7915_wait_reset_state(dev, MT_MCU_CMD_RESET_DONE)) {
- mt7915_dma_reset(dev, false);
-
-- mt7915_tx_token_put(dev);
-+ mt76_connac2_tx_token_put(&dev->mt76);
- idr_init(&dev->mt76.token);
-
- mt76_wr(dev, MT_MCU_INT_EVENT, MT_MCU_INT_EVENT_DMA_INIT);
- mt7915_wait_reset_state(dev, MT_MCU_CMD_RECOVERY_DONE);
- }
-
-+ mt76_wr(dev, MT_MCU_INT_EVENT, MT_MCU_INT_EVENT_RESET_DONE);
-+ mt7915_wait_reset_state(dev, MT_MCU_CMD_NORMAL_STATE);
-+
-+ /* enable DMA Tx/Rx and interrupt */
-+ mt7915_dma_start(dev, false, false);
-+
- clear_bit(MT76_MCU_RESET, &dev->mphy.state);
- clear_bit(MT76_RESET, &dev->mphy.state);
- if (phy2)
-@@ -1625,9 +1577,6 @@ void mt7915_mac_reset_work(struct work_struct *work)
-
- tasklet_schedule(&dev->mt76.irq_tasklet);
-
-- mt76_wr(dev, MT_MCU_INT_EVENT, MT_MCU_INT_EVENT_RESET_DONE);
-- mt7915_wait_reset_state(dev, MT_MCU_CMD_NORMAL_STATE);
--
- mt76_worker_enable(&dev->mt76.tx_worker);
-
- local_bh_disable();
-@@ -1747,8 +1696,8 @@ void mt7915_reset(struct mt7915_dev *dev)
-
- void mt7915_mac_update_stats(struct mt7915_phy *phy)
- {
-+ struct mt76_mib_stats *mib = &phy->mib;
- struct mt7915_dev *dev = phy->dev;
-- struct mib_stats *mib = &phy->mib;
- int i, aggr0 = 0, aggr1, cnt;
- u8 band = phy->mt76->band_idx;
- u32 val;
-@@ -2010,7 +1959,7 @@ void mt7915_mac_sta_rc_work(struct work_struct *work)
- u32 changed;
- LIST_HEAD(list);
-
-- spin_lock_bh(&dev->sta_poll_lock);
-+ spin_lock_bh(&dev->mt76.sta_poll_lock);
- list_splice_init(&dev->sta_rc_list, &list);
-
- while (!list_empty(&list)) {
-@@ -2018,7 +1967,7 @@ void mt7915_mac_sta_rc_work(struct work_struct *work)
- list_del_init(&msta->rc_list);
- changed = msta->changed;
- msta->changed = 0;
-- spin_unlock_bh(&dev->sta_poll_lock);
-+ spin_unlock_bh(&dev->mt76.sta_poll_lock);
-
- sta = container_of((void *)msta, struct ieee80211_sta, drv_priv);
- vif = container_of((void *)msta->vif, struct ieee80211_vif, drv_priv);
-@@ -2031,10 +1980,10 @@ void mt7915_mac_sta_rc_work(struct work_struct *work)
- if (changed & IEEE80211_RC_SMPS_CHANGED)
- mt7915_mcu_add_smps(dev, vif, sta);
-
-- spin_lock_bh(&dev->sta_poll_lock);
-+ spin_lock_bh(&dev->mt76.sta_poll_lock);
- }
-
-- spin_unlock_bh(&dev->sta_poll_lock);
-+ spin_unlock_bh(&dev->mt76.sta_poll_lock);
- }
-
- void mt7915_mac_work(struct work_struct *work)
-@@ -2054,6 +2003,9 @@ void mt7915_mac_work(struct work_struct *work)
-
- mt7915_mac_update_stats(phy);
- mt7915_mac_severe_check(phy);
-+
-+ if (phy->dev->muru_debug)
-+ mt7915_mcu_muru_debug_get(phy);
- }
-
- mutex_unlock(&mphy->dev->mutex);
-diff --git a/mt7915/mac.h b/mt7915/mac.h
-index ce94f87e..448b1b38 100644
---- a/mt7915/mac.h
-+++ b/mt7915/mac.h
-@@ -9,7 +9,12 @@
- #define MT_TX_FREE_VER GENMASK(18, 16)
- #define MT_TX_FREE_MSDU_CNT_V0 GENMASK(6, 0)
- /* 0: success, others: dropped */
--#define MT_TX_FREE_MPDU_HEADER BIT(30)
-+#define MT_TX_FREE_COUNT GENMASK(12, 0)
-+#define MT_TX_FREE_COUNT_V3 GENMASK(27, 24)
-+#define MT_TX_FREE_STAT GENMASK(14, 13)
-+#define MT_TX_FREE_STAT_V3 GENMASK(29, 28)
-+#define MT_TX_FREE_MPDU_HEADER BIT(15)
-+#define MT_TX_FREE_MPDU_HEADER_V3 BIT(30)
- #define MT_TX_FREE_MSDU_ID_V3 GENMASK(14, 0)
-
- #define MT_TXS5_F0_FINAL_MPDU BIT(31)
-diff --git a/mt7915/main.c b/mt7915/main.c
-index 8ce7b1c5..ca5631f5 100644
---- a/mt7915/main.c
-+++ b/mt7915/main.c
-@@ -248,7 +248,7 @@ static int mt7915_add_interface(struct ieee80211_hw *hw,
- idx = MT7915_WTBL_RESERVED - mvif->mt76.idx;
-
- INIT_LIST_HEAD(&mvif->sta.rc_list);
-- INIT_LIST_HEAD(&mvif->sta.poll_list);
-+ INIT_LIST_HEAD(&mvif->sta.wcid.poll_list);
- mvif->sta.wcid.idx = idx;
- mvif->sta.wcid.phy_idx = ext_phy;
- mvif->sta.wcid.hw_key_idx = -1;
-@@ -308,10 +308,10 @@ static void mt7915_remove_interface(struct ieee80211_hw *hw,
- phy->omac_mask &= ~BIT_ULL(mvif->mt76.omac_idx);
- mutex_unlock(&dev->mt76.mutex);
-
-- spin_lock_bh(&dev->sta_poll_lock);
-- if (!list_empty(&msta->poll_list))
-- list_del_init(&msta->poll_list);
-- spin_unlock_bh(&dev->sta_poll_lock);
-+ spin_lock_bh(&dev->mt76.sta_poll_lock);
-+ if (!list_empty(&msta->wcid.poll_list))
-+ list_del_init(&msta->wcid.poll_list);
-+ spin_unlock_bh(&dev->mt76.sta_poll_lock);
-
- mt76_packet_id_flush(&dev->mt76, &msta->wcid);
- }
-@@ -629,11 +629,6 @@ static void mt7915_bss_info_changed(struct ieee80211_hw *hw,
- }
- }
-
-- if (changed & BSS_CHANGED_BEACON_ENABLED && info->enable_beacon) {
-- mt7915_mcu_add_bss_info(phy, vif, true);
-- mt7915_mcu_add_sta(dev, vif, NULL, true);
-- }
--
- /* ensure that enable txcmd_mode after bss_info */
- if (changed & (BSS_CHANGED_QOS | BSS_CHANGED_BEACON_ENABLED))
- mt7915_mcu_set_tx(dev, vif);
-@@ -653,6 +648,37 @@ static void mt7915_bss_info_changed(struct ieee80211_hw *hw,
- mutex_unlock(&dev->mt76.mutex);
- }
-
-+static int
-+mt7915_start_ap(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
-+ struct ieee80211_bss_conf *link_conf)
-+{
-+ struct mt7915_phy *phy = mt7915_hw_phy(hw);
-+ struct mt7915_dev *dev = mt7915_hw_dev(hw);
-+ int err;
-+
-+ mutex_lock(&dev->mt76.mutex);
-+
-+ err = mt7915_mcu_add_bss_info(phy, vif, true);
-+ if (err)
-+ goto out;
-+ err = mt7915_mcu_add_sta(dev, vif, NULL, true);
-+out:
-+ mutex_unlock(&dev->mt76.mutex);
-+
-+ return err;
-+}
-+
-+static void
-+mt7915_stop_ap(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
-+ struct ieee80211_bss_conf *link_conf)
-+{
-+ struct mt7915_dev *dev = mt7915_hw_dev(hw);
-+
-+ mutex_lock(&dev->mt76.mutex);
-+ mt7915_mcu_add_sta(dev, vif, NULL, false);
-+ mutex_unlock(&dev->mt76.mutex);
-+}
-+
- static void
- mt7915_channel_switch_beacon(struct ieee80211_hw *hw,
- struct ieee80211_vif *vif,
-@@ -679,7 +705,7 @@ int mt7915_mac_sta_add(struct mt76_dev *mdev, struct ieee80211_vif *vif,
- return -ENOSPC;
-
- INIT_LIST_HEAD(&msta->rc_list);
-- INIT_LIST_HEAD(&msta->poll_list);
-+ INIT_LIST_HEAD(&msta->wcid.poll_list);
- msta->vif = mvif;
- msta->wcid.sta = 1;
- msta->wcid.idx = idx;
-@@ -714,12 +740,12 @@ void mt7915_mac_sta_remove(struct mt76_dev *mdev, struct ieee80211_vif *vif,
- for (i = 0; i < ARRAY_SIZE(msta->twt.flow); i++)
- mt7915_mac_twt_teardown_flow(dev, msta, i);
-
-- spin_lock_bh(&dev->sta_poll_lock);
-- if (!list_empty(&msta->poll_list))
-- list_del_init(&msta->poll_list);
-+ spin_lock_bh(&mdev->sta_poll_lock);
-+ if (!list_empty(&msta->wcid.poll_list))
-+ list_del_init(&msta->wcid.poll_list);
- if (!list_empty(&msta->rc_list))
- list_del_init(&msta->rc_list);
-- spin_unlock_bh(&dev->sta_poll_lock);
-+ spin_unlock_bh(&mdev->sta_poll_lock);
- }
-
- static void mt7915_tx(struct ieee80211_hw *hw,
-@@ -801,16 +827,16 @@ mt7915_ampdu_action(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
- case IEEE80211_AMPDU_TX_STOP_FLUSH:
- case IEEE80211_AMPDU_TX_STOP_FLUSH_CONT:
- mtxq->aggr = false;
-- clear_bit(tid, &msta->ampdu_state);
-+ clear_bit(tid, &msta->wcid.ampdu_state);
- ret = mt7915_mcu_add_tx_ba(dev, params, false);
- break;
- case IEEE80211_AMPDU_TX_START:
-- set_bit(tid, &msta->ampdu_state);
-+ set_bit(tid, &msta->wcid.ampdu_state);
- ret = IEEE80211_AMPDU_TX_START_IMMEDIATE;
- break;
- case IEEE80211_AMPDU_TX_STOP_CONT:
- mtxq->aggr = false;
-- clear_bit(tid, &msta->ampdu_state);
-+ clear_bit(tid, &msta->wcid.ampdu_state);
- ret = mt7915_mcu_add_tx_ba(dev, params, false);
- ieee80211_stop_tx_ba_cb_irqsafe(vif, sta->addr, tid);
- break;
-@@ -842,7 +868,7 @@ mt7915_get_stats(struct ieee80211_hw *hw,
- {
- struct mt7915_phy *phy = mt7915_hw_phy(hw);
- struct mt7915_dev *dev = mt7915_hw_dev(hw);
-- struct mib_stats *mib = &phy->mib;
-+ struct mt76_mib_stats *mib = &phy->mib;
-
- mutex_lock(&dev->mt76.mutex);
-
-@@ -1019,21 +1045,20 @@ static void mt7915_sta_statistics(struct ieee80211_hw *hw,
- sinfo->filled |= BIT_ULL(NL80211_STA_INFO_RX_BITRATE);
- }
-
-- if (!txrate->legacy && !txrate->flags)
-- return;
--
-- if (txrate->legacy) {
-- sinfo->txrate.legacy = txrate->legacy;
-- } else {
-- sinfo->txrate.mcs = txrate->mcs;
-- sinfo->txrate.nss = txrate->nss;
-- sinfo->txrate.bw = txrate->bw;
-- sinfo->txrate.he_gi = txrate->he_gi;
-- sinfo->txrate.he_dcm = txrate->he_dcm;
-- sinfo->txrate.he_ru_alloc = txrate->he_ru_alloc;
-+ if (txrate->legacy || txrate->flags) {
-+ if (txrate->legacy) {
-+ sinfo->txrate.legacy = txrate->legacy;
-+ } else {
-+ sinfo->txrate.mcs = txrate->mcs;
-+ sinfo->txrate.nss = txrate->nss;
-+ sinfo->txrate.bw = txrate->bw;
-+ sinfo->txrate.he_gi = txrate->he_gi;
-+ sinfo->txrate.he_dcm = txrate->he_dcm;
-+ sinfo->txrate.he_ru_alloc = txrate->he_ru_alloc;
-+ }
-+ sinfo->txrate.flags = txrate->flags;
-+ sinfo->filled |= BIT_ULL(NL80211_STA_INFO_TX_BITRATE);
- }
-- sinfo->txrate.flags = txrate->flags;
-- sinfo->filled |= BIT_ULL(NL80211_STA_INFO_TX_BITRATE);
-
- /* offloading flows bypass networking stack, so driver counts and
- * reports sta statistics via NL80211_STA_INFO when WED is active.
-@@ -1042,14 +1067,10 @@ static void mt7915_sta_statistics(struct ieee80211_hw *hw,
- sinfo->tx_bytes = msta->wcid.stats.tx_bytes;
- sinfo->filled |= BIT_ULL(NL80211_STA_INFO_TX_BYTES64);
-
-- sinfo->tx_packets = msta->wcid.stats.tx_packets;
-- sinfo->filled |= BIT_ULL(NL80211_STA_INFO_TX_PACKETS);
--
-- sinfo->tx_failed = msta->wcid.stats.tx_failed;
-- sinfo->filled |= BIT_ULL(NL80211_STA_INFO_TX_FAILED);
--
-- sinfo->tx_retries = msta->wcid.stats.tx_retries;
-- sinfo->filled |= BIT_ULL(NL80211_STA_INFO_TX_RETRIES);
-+ if (!mt7915_mcu_wed_wa_tx_stats(phy->dev, msta->wcid.idx)) {
-+ sinfo->tx_packets = msta->wcid.stats.tx_packets;
-+ sinfo->filled |= BIT_ULL(NL80211_STA_INFO_TX_PACKETS);
-+ }
-
- if (mtk_wed_get_rx_capa(&phy->dev->mt76.mmio.wed)) {
- sinfo->rx_bytes = msta->wcid.stats.rx_bytes;
-@@ -1060,6 +1081,12 @@ static void mt7915_sta_statistics(struct ieee80211_hw *hw,
- }
- }
-
-+ sinfo->tx_failed = msta->wcid.stats.tx_failed;
-+ sinfo->filled |= BIT_ULL(NL80211_STA_INFO_TX_FAILED);
-+
-+ sinfo->tx_retries = msta->wcid.stats.tx_retries;
-+ sinfo->filled |= BIT_ULL(NL80211_STA_INFO_TX_RETRIES);
-+
- sinfo->ack_signal = (s8)msta->ack_signal;
- sinfo->filled |= BIT_ULL(NL80211_STA_INFO_ACK_SIGNAL);
-
-@@ -1073,11 +1100,11 @@ static void mt7915_sta_rc_work(void *data, struct ieee80211_sta *sta)
- struct mt7915_dev *dev = msta->vif->phy->dev;
- u32 *changed = data;
-
-- spin_lock_bh(&dev->sta_poll_lock);
-+ spin_lock_bh(&dev->mt76.sta_poll_lock);
- msta->changed |= *changed;
- if (list_empty(&msta->rc_list))
- list_add_tail(&msta->rc_list, &dev->sta_rc_list);
-- spin_unlock_bh(&dev->sta_poll_lock);
-+ spin_unlock_bh(&dev->mt76.sta_poll_lock);
- }
-
- static void mt7915_sta_rc_update(struct ieee80211_hw *hw,
-@@ -1253,6 +1280,38 @@ static const char mt7915_gstrings_stats[][ETH_GSTRING_LEN] = {
- "rx_vec_queue_overflow_drop_cnt",
- "rx_ba_cnt",
-
-+ /* muru mu-mimo and ofdma related stats */
-+ "dl_cck_cnt",
-+ "dl_ofdm_cnt",
-+ "dl_htmix_cnt",
-+ "dl_htgf_cnt",
-+ "dl_vht_su_cnt",
-+ "dl_vht_2mu_cnt",
-+ "dl_vht_3mu_cnt",
-+ "dl_vht_4mu_cnt",
-+ "dl_he_su_cnt",
-+ "dl_he_ext_su_cnt",
-+ "dl_he_2ru_cnt",
-+ "dl_he_2mu_cnt",
-+ "dl_he_3ru_cnt",
-+ "dl_he_3mu_cnt",
-+ "dl_he_4ru_cnt",
-+ "dl_he_4mu_cnt",
-+ "dl_he_5to8ru_cnt",
-+ "dl_he_9to16ru_cnt",
-+ "dl_he_gtr16ru_cnt",
-+
-+ "ul_hetrig_su_cnt",
-+ "ul_hetrig_2ru_cnt",
-+ "ul_hetrig_3ru_cnt",
-+ "ul_hetrig_4ru_cnt",
-+ "ul_hetrig_5to8ru_cnt",
-+ "ul_hetrig_9to16ru_cnt",
-+ "ul_hetrig_gtr16ru_cnt",
-+ "ul_hetrig_2mu_cnt",
-+ "ul_hetrig_3mu_cnt",
-+ "ul_hetrig_4mu_cnt",
-+
- /* per vif counters */
- "v_tx_mode_cck",
- "v_tx_mode_ofdm",
-@@ -1279,6 +1338,10 @@ static const char mt7915_gstrings_stats[][ETH_GSTRING_LEN] = {
- "v_tx_mcs_9",
- "v_tx_mcs_10",
- "v_tx_mcs_11",
-+ "v_tx_nss_1",
-+ "v_tx_nss_2",
-+ "v_tx_nss_3",
-+ "v_tx_nss_4",
- };
-
- #define MT7915_SSTATS_LEN ARRAY_SIZE(mt7915_gstrings_stats)
-@@ -1326,11 +1389,11 @@ void mt7915_get_et_stats(struct ieee80211_hw *hw,
- struct mt7915_dev *dev = mt7915_hw_dev(hw);
- struct mt7915_phy *phy = mt7915_hw_phy(hw);
- struct mt7915_vif *mvif = (struct mt7915_vif *)vif->drv_priv;
-+ struct mt76_mib_stats *mib = &phy->mib;
- struct mt76_ethtool_worker_info wi = {
- .data = data,
- .idx = mvif->mt76.idx,
- };
-- struct mib_stats *mib = &phy->mib;
- /* See mt7915_ampdu_stat_read_phy, etc */
- int i, ei = 0, stats_size;
-
-@@ -1403,6 +1466,37 @@ void mt7915_get_et_stats(struct ieee80211_hw *hw,
- data[ei++] = mib->rx_vec_queue_overflow_drop_cnt;
- data[ei++] = mib->rx_ba_cnt;
-
-+ data[ei++] = mib->dl_cck_cnt;
-+ data[ei++] = mib->dl_ofdm_cnt;
-+ data[ei++] = mib->dl_htmix_cnt;
-+ data[ei++] = mib->dl_htgf_cnt;
-+ data[ei++] = mib->dl_vht_su_cnt;
-+ data[ei++] = mib->dl_vht_2mu_cnt;
-+ data[ei++] = mib->dl_vht_3mu_cnt;
-+ data[ei++] = mib->dl_vht_4mu_cnt;
-+ data[ei++] = mib->dl_he_su_cnt;
-+ data[ei++] = mib->dl_he_ext_su_cnt;
-+ data[ei++] = mib->dl_he_2ru_cnt;
-+ data[ei++] = mib->dl_he_2mu_cnt;
-+ data[ei++] = mib->dl_he_3ru_cnt;
-+ data[ei++] = mib->dl_he_3mu_cnt;
-+ data[ei++] = mib->dl_he_4ru_cnt;
-+ data[ei++] = mib->dl_he_4mu_cnt;
-+ data[ei++] = mib->dl_he_5to8ru_cnt;
-+ data[ei++] = mib->dl_he_9to16ru_cnt;
-+ data[ei++] = mib->dl_he_gtr16ru_cnt;
-+
-+ data[ei++] = mib->ul_hetrig_su_cnt;
-+ data[ei++] = mib->ul_hetrig_2ru_cnt;
-+ data[ei++] = mib->ul_hetrig_3ru_cnt;
-+ data[ei++] = mib->ul_hetrig_4ru_cnt;
-+ data[ei++] = mib->ul_hetrig_5to8ru_cnt;
-+ data[ei++] = mib->ul_hetrig_9to16ru_cnt;
-+ data[ei++] = mib->ul_hetrig_gtr16ru_cnt;
-+ data[ei++] = mib->ul_hetrig_2mu_cnt;
-+ data[ei++] = mib->ul_hetrig_3mu_cnt;
-+ data[ei++] = mib->ul_hetrig_4mu_cnt;
-+
- /* Add values for all stations owned by this vif */
- wi.initial_stat_idx = ei;
- ieee80211_iterate_stations_atomic(hw, mt7915_ethtool_worker, &wi);
-@@ -1540,6 +1634,8 @@ const struct ieee80211_ops mt7915_ops = {
- .conf_tx = mt7915_conf_tx,
- .configure_filter = mt7915_configure_filter,
- .bss_info_changed = mt7915_bss_info_changed,
-+ .start_ap = mt7915_start_ap,
-+ .stop_ap = mt7915_stop_ap,
- .sta_add = mt7915_sta_add,
- .sta_remove = mt7915_sta_remove,
- .sta_pre_rcu_remove = mt76_sta_pre_rcu_remove,
-diff --git a/mt7915/mcu.c b/mt7915/mcu.c
-index aa706ff6..71eeb54a 100644
---- a/mt7915/mcu.c
-+++ b/mt7915/mcu.c
-@@ -167,7 +167,9 @@ mt7915_mcu_parse_response(struct mt76_dev *mdev, int cmd,
- }
-
- rxd = (struct mt76_connac2_mcu_rxd *)skb->data;
-- if (seq != rxd->seq)
-+ if (seq != rxd->seq &&
-+ !(rxd->eid == MCU_CMD_EXT_CID &&
-+ rxd->ext_eid == MCU_EXT_EVENT_WA_TX_STAT))
- return -EAGAIN;
-
- if (cmd == MCU_CMD(PATCH_SEM_CONTROL)) {
-@@ -277,7 +279,7 @@ mt7915_mcu_rx_radar_detected(struct mt7915_dev *dev, struct sk_buff *skb)
-
- r = (struct mt7915_mcu_rdd_report *)skb->data;
-
-- if (r->band_idx > MT_BAND1)
-+ if (r->band_idx > MT_RX_SEL2)
- return;
-
- if ((r->band_idx && !dev->phy.mt76->band_idx) &&
-@@ -398,12 +400,14 @@ void mt7915_mcu_rx_event(struct mt7915_dev *dev, struct sk_buff *skb)
- struct mt76_connac2_mcu_rxd *rxd;
-
- rxd = (struct mt76_connac2_mcu_rxd *)skb->data;
-- if (rxd->ext_eid == MCU_EXT_EVENT_THERMAL_PROTECT ||
-- rxd->ext_eid == MCU_EXT_EVENT_FW_LOG_2_HOST ||
-- rxd->ext_eid == MCU_EXT_EVENT_ASSERT_DUMP ||
-- rxd->ext_eid == MCU_EXT_EVENT_PS_SYNC ||
-- rxd->ext_eid == MCU_EXT_EVENT_BCC_NOTIFY ||
-- !rxd->seq)
-+ if ((rxd->ext_eid == MCU_EXT_EVENT_THERMAL_PROTECT ||
-+ rxd->ext_eid == MCU_EXT_EVENT_FW_LOG_2_HOST ||
-+ rxd->ext_eid == MCU_EXT_EVENT_ASSERT_DUMP ||
-+ rxd->ext_eid == MCU_EXT_EVENT_PS_SYNC ||
-+ rxd->ext_eid == MCU_EXT_EVENT_BCC_NOTIFY ||
-+ !rxd->seq) &&
-+ !(rxd->eid == MCU_CMD_EXT_CID &&
-+ rxd->ext_eid == MCU_EXT_EVENT_WA_TX_STAT))
- mt7915_mcu_rx_unsolicited_event(dev, skb);
- else
- mt76_mcu_rx_event(&dev->mt76, skb);
-@@ -2115,12 +2119,11 @@ int mt7915_mcu_muru_debug_set(struct mt7915_dev *dev, bool enabled)
- sizeof(data), false);
- }
-
--int mt7915_mcu_muru_debug_get(struct mt7915_phy *phy, void *ms)
-+int mt7915_mcu_muru_debug_get(struct mt7915_phy *phy)
- {
- struct mt7915_dev *dev = phy->dev;
- struct sk_buff *skb;
-- struct mt7915_mcu_muru_stats *mu_stats =
-- (struct mt7915_mcu_muru_stats *)ms;
-+ struct mt7915_mcu_muru_stats *mu_stats;
- int ret;
-
- struct {
-@@ -2136,7 +2139,43 @@ int mt7915_mcu_muru_debug_get(struct mt7915_phy *phy, void *ms)
- if (ret)
- return ret;
-
-- memcpy(mu_stats, skb->data, sizeof(struct mt7915_mcu_muru_stats));
-+ mu_stats = (struct mt7915_mcu_muru_stats *)(skb->data);
-+
-+ /* accumulate stats, these are clear-on-read */
-+#define __dl_u32(s) phy->mib.dl_##s += le32_to_cpu(mu_stats->dl.s)
-+#define __ul_u32(s) phy->mib.ul_##s += le32_to_cpu(mu_stats->ul.s)
-+ __dl_u32(cck_cnt);
-+ __dl_u32(ofdm_cnt);
-+ __dl_u32(htmix_cnt);
-+ __dl_u32(htgf_cnt);
-+ __dl_u32(vht_su_cnt);
-+ __dl_u32(vht_2mu_cnt);
-+ __dl_u32(vht_3mu_cnt);
-+ __dl_u32(vht_4mu_cnt);
-+ __dl_u32(he_su_cnt);
-+ __dl_u32(he_2ru_cnt);
-+ __dl_u32(he_2mu_cnt);
-+ __dl_u32(he_3ru_cnt);
-+ __dl_u32(he_3mu_cnt);
-+ __dl_u32(he_4ru_cnt);
-+ __dl_u32(he_4mu_cnt);
-+ __dl_u32(he_5to8ru_cnt);
-+ __dl_u32(he_9to16ru_cnt);
-+ __dl_u32(he_gtr16ru_cnt);
-+
-+ __ul_u32(hetrig_su_cnt);
-+ __ul_u32(hetrig_2ru_cnt);
-+ __ul_u32(hetrig_3ru_cnt);
-+ __ul_u32(hetrig_4ru_cnt);
-+ __ul_u32(hetrig_5to8ru_cnt);
-+ __ul_u32(hetrig_9to16ru_cnt);
-+ __ul_u32(hetrig_gtr16ru_cnt);
-+ __ul_u32(hetrig_2mu_cnt);
-+ __ul_u32(hetrig_3mu_cnt);
-+ __ul_u32(hetrig_4mu_cnt);
-+#undef __dl_u32
-+#undef __ul_u32
-+
- dev_kfree_skb(skb);
-
- return 0;
-@@ -3736,6 +3775,62 @@ int mt7915_mcu_twt_agrt_update(struct mt7915_dev *dev,
- &req, sizeof(req), true);
- }
-
-+int mt7915_mcu_wed_wa_tx_stats(struct mt7915_dev *dev, u16 wlan_idx)
-+{
-+ struct {
-+ __le32 cmd;
-+ __le32 num;
-+ __le32 __rsv;
-+ __le16 wlan_idx;
-+ } req = {
-+ .cmd = cpu_to_le32(0x15),
-+ .num = cpu_to_le32(1),
-+ .wlan_idx = cpu_to_le16(wlan_idx),
-+ };
-+ struct mt7915_mcu_wa_tx_stat {
-+ __le16 wlan_idx;
-+ u8 __rsv[2];
-+
-+ /* tx_bytes is deprecated since WA byte counter uses u32,
-+ * which easily leads to overflow.
-+ */
-+ __le32 tx_bytes;
-+ __le32 tx_packets;
-+ } *res;
-+ struct mt76_wcid *wcid;
-+ struct sk_buff *skb;
-+ int ret;
-+
-+ ret = mt76_mcu_send_and_get_msg(&dev->mt76, MCU_WA_PARAM_CMD(QUERY),
-+ &req, sizeof(req), true, &skb);
-+ if (ret)
-+ return ret;
-+
-+ if (!is_mt7915(&dev->mt76))
-+ skb_pull(skb, 4);
-+
-+ res = (struct mt7915_mcu_wa_tx_stat *)skb->data;
-+
-+ if (le16_to_cpu(res->wlan_idx) != wlan_idx) {
-+ ret = -EINVAL;
-+ goto out;
-+ }
-+
-+ rcu_read_lock();
-+
-+ wcid = rcu_dereference(dev->mt76.wcid[wlan_idx]);
-+ if (wcid)
-+ wcid->stats.tx_packets += le32_to_cpu(res->tx_packets);
-+ else
-+ ret = -EINVAL;
-+
-+ rcu_read_unlock();
-+out:
-+ dev_kfree_skb(skb);
-+
-+ return ret;
-+}
-+
- int mt7915_mcu_rf_regval(struct mt7915_dev *dev, u32 regidx, u32 *val, bool set)
- {
- struct {
-diff --git a/mt7915/mmio.c b/mt7915/mmio.c
-index 984b5f60..fc7ace63 100644
---- a/mt7915/mmio.c
-+++ b/mt7915/mmio.c
-@@ -545,8 +545,6 @@ static u32 mt7915_rmw(struct mt76_dev *mdev, u32 offset, u32 mask, u32 val)
- static int mt7915_mmio_wed_offload_enable(struct mtk_wed_device *wed)
- {
- struct mt7915_dev *dev;
-- struct mt7915_phy *phy;
-- int ret;
-
- dev = container_of(wed, struct mt7915_dev, mt76.mmio.wed);
-
-@@ -554,43 +552,19 @@ static int mt7915_mmio_wed_offload_enable(struct mtk_wed_device *wed)
- dev->mt76.token_size = wed->wlan.token_start;
- spin_unlock_bh(&dev->mt76.token_lock);
-
-- ret = wait_event_timeout(dev->mt76.tx_wait,
-- !dev->mt76.wed_token_count, HZ);
-- if (!ret)
-- return -EAGAIN;
--
-- phy = &dev->phy;
-- mt76_set(dev, MT_AGG_ACR4(phy->mt76->band_idx), MT_AGG_ACR_PPDU_TXS2H);
--
-- phy = dev->mt76.phys[MT_BAND1] ? dev->mt76.phys[MT_BAND1]->priv : NULL;
-- if (phy)
-- mt76_set(dev, MT_AGG_ACR4(phy->mt76->band_idx),
-- MT_AGG_ACR_PPDU_TXS2H);
--
-- return 0;
-+ return !wait_event_timeout(dev->mt76.tx_wait,
-+ !dev->mt76.wed_token_count, HZ);
- }
-
- static void mt7915_mmio_wed_offload_disable(struct mtk_wed_device *wed)
- {
- struct mt7915_dev *dev;
-- struct mt7915_phy *phy;
-
- dev = container_of(wed, struct mt7915_dev, mt76.mmio.wed);
-
- spin_lock_bh(&dev->mt76.token_lock);
- dev->mt76.token_size = MT7915_TOKEN_SIZE;
- spin_unlock_bh(&dev->mt76.token_lock);
--
-- /* MT_TXD5_TX_STATUS_HOST (MPDU format) has higher priority than
-- * MT_AGG_ACR_PPDU_TXS2H (PPDU format) even though ACR bit is set.
-- */
-- phy = &dev->phy;
-- mt76_clear(dev, MT_AGG_ACR4(phy->mt76->band_idx), MT_AGG_ACR_PPDU_TXS2H);
--
-- phy = dev->mt76.phys[MT_BAND1] ? dev->mt76.phys[MT_BAND1]->priv : NULL;
-- if (phy)
-- mt76_clear(dev, MT_AGG_ACR4(phy->mt76->band_idx),
-- MT_AGG_ACR_PPDU_TXS2H);
- }
-
- static void mt7915_mmio_wed_release_rx_buf(struct mtk_wed_device *wed)
-@@ -1064,7 +1038,7 @@ static int __init mt7915_init(void)
- goto error_pci;
-
- if (IS_ENABLED(CONFIG_MT798X_WMAC)) {
-- ret = platform_driver_register(&mt7986_wmac_driver);
-+ ret = platform_driver_register(&mt798x_wmac_driver);
- if (ret)
- goto error_wmac;
- }
-@@ -1082,7 +1056,7 @@ error_pci:
- static void __exit mt7915_exit(void)
- {
- if (IS_ENABLED(CONFIG_MT798X_WMAC))
-- platform_driver_unregister(&mt7986_wmac_driver);
-+ platform_driver_unregister(&mt798x_wmac_driver);
-
- pci_unregister_driver(&mt7915_pci_driver);
- pci_unregister_driver(&mt7915_hif_driver);
-diff --git a/mt7915/mt7915.h b/mt7915/mt7915.h
-index 103cd0d7..0c7226b8 100644
---- a/mt7915/mt7915.h
-+++ b/mt7915/mt7915.h
-@@ -136,7 +136,6 @@ struct mt7915_sta {
-
- struct mt7915_vif *vif;
-
-- struct list_head poll_list;
- struct list_head rc_list;
- u32 airtime_ac[8];
-
-@@ -145,7 +144,6 @@ struct mt7915_sta {
-
- unsigned long changed;
- unsigned long jiffies;
-- unsigned long ampdu_state;
- struct mt76_connac_sta_key_conf bip;
-
- struct {
-@@ -164,67 +162,6 @@ struct mt7915_vif {
- struct cfg80211_bitrate_mask bitrate_mask;
- };
-
--/* per-phy stats. */
--struct mib_stats {
-- u32 ack_fail_cnt;
-- u32 fcs_err_cnt;
-- u32 rts_cnt;
-- u32 rts_retries_cnt;
-- u32 ba_miss_cnt;
-- u32 tx_bf_cnt;
-- u32 tx_mu_mpdu_cnt;
-- u32 tx_mu_acked_mpdu_cnt;
-- u32 tx_su_acked_mpdu_cnt;
-- u32 tx_bf_ibf_ppdu_cnt;
-- u32 tx_bf_ebf_ppdu_cnt;
--
-- u32 tx_bf_rx_fb_all_cnt;
-- u32 tx_bf_rx_fb_he_cnt;
-- u32 tx_bf_rx_fb_vht_cnt;
-- u32 tx_bf_rx_fb_ht_cnt;
--
-- u32 tx_bf_rx_fb_bw; /* value of last sample, not cumulative */
-- u32 tx_bf_rx_fb_nc_cnt;
-- u32 tx_bf_rx_fb_nr_cnt;
-- u32 tx_bf_fb_cpl_cnt;
-- u32 tx_bf_fb_trig_cnt;
--
-- u32 tx_ampdu_cnt;
-- u32 tx_stop_q_empty_cnt;
-- u32 tx_mpdu_attempts_cnt;
-- u32 tx_mpdu_success_cnt;
-- u32 tx_pkt_ebf_cnt;
-- u32 tx_pkt_ibf_cnt;
--
-- u32 tx_rwp_fail_cnt;
-- u32 tx_rwp_need_cnt;
--
-- /* rx stats */
-- u32 rx_fifo_full_cnt;
-- u32 channel_idle_cnt;
-- u32 primary_cca_busy_time;
-- u32 secondary_cca_busy_time;
-- u32 primary_energy_detect_time;
-- u32 cck_mdrdy_time;
-- u32 ofdm_mdrdy_time;
-- u32 green_mdrdy_time;
-- u32 rx_vector_mismatch_cnt;
-- u32 rx_delimiter_fail_cnt;
-- u32 rx_mrdy_cnt;
-- u32 rx_len_mismatch_cnt;
-- u32 rx_mpdu_cnt;
-- u32 rx_ampdu_cnt;
-- u32 rx_ampdu_bytes_cnt;
-- u32 rx_ampdu_valid_subframe_cnt;
-- u32 rx_ampdu_valid_subframe_bytes_cnt;
-- u32 rx_pfdrop_cnt;
-- u32 rx_vec_queue_overflow_drop_cnt;
-- u32 rx_ba_cnt;
--
-- u32 tx_amsdu[8];
-- u32 tx_amsdu_cnt;
--};
--
- /* crash-dump */
- struct mt7915_crash_data {
- guid_t guid;
-@@ -270,7 +207,7 @@ struct mt7915_phy {
- u32 rx_ampdu_ts;
- u32 ampdu_ref;
-
-- struct mib_stats mib;
-+ struct mt76_mib_stats mib;
- struct mt76_channel_state state_ts;
-
- #ifdef CONFIG_NL80211_TESTMODE
-@@ -335,9 +272,7 @@ struct mt7915_dev {
- #endif
-
- struct list_head sta_rc_list;
-- struct list_head sta_poll_list;
- struct list_head twt_list;
-- spinlock_t sta_poll_lock;
-
- u32 hw_pattern;
-
-@@ -437,7 +372,7 @@ extern const struct ieee80211_ops mt7915_ops;
- extern const struct mt76_testmode_ops mt7915_testmode_ops;
- extern struct pci_driver mt7915_pci_driver;
- extern struct pci_driver mt7915_hif_driver;
--extern struct platform_driver mt7986_wmac_driver;
-+extern struct platform_driver mt798x_wmac_driver;
-
- #ifdef CONFIG_MT798X_WMAC
- int mt7986_wmac_enable(struct mt7915_dev *dev);
-@@ -472,6 +407,7 @@ int mt7915_dma_init(struct mt7915_dev *dev, struct mt7915_phy *phy2);
- void mt7915_dma_prefetch(struct mt7915_dev *dev);
- void mt7915_dma_cleanup(struct mt7915_dev *dev);
- int mt7915_dma_reset(struct mt7915_dev *dev, bool force);
-+int mt7915_dma_start(struct mt7915_dev *dev, bool reset, bool wed_reset);
- int mt7915_txbf_init(struct mt7915_dev *dev);
- void mt7915_init_txpower(struct mt7915_dev *dev,
- struct ieee80211_supported_band *sband);
-@@ -545,6 +481,7 @@ int mt7915_mcu_get_rx_rate(struct mt7915_phy *phy, struct ieee80211_vif *vif,
- struct ieee80211_sta *sta, struct rate_info *rate);
- int mt7915_mcu_rdd_background_enable(struct mt7915_phy *phy,
- struct cfg80211_chan_def *chandef);
-+int mt7915_mcu_wed_wa_tx_stats(struct mt7915_dev *dev, u16 wcid);
- int mt7915_mcu_rf_regval(struct mt7915_dev *dev, u32 regidx, u32 *val, bool set);
- int mt7915_mcu_wa_cmd(struct mt7915_dev *dev, int cmd, u32 a1, u32 a2, u32 a3);
- int mt7915_mcu_fw_log_2_host(struct mt7915_dev *dev, u8 type, u8 ctrl);
-@@ -618,7 +555,6 @@ int mt7915_tx_prepare_skb(struct mt76_dev *mdev, void *txwi_ptr,
- enum mt76_txq_id qid, struct mt76_wcid *wcid,
- struct ieee80211_sta *sta,
- struct mt76_tx_info *tx_info);
--void mt7915_tx_token_put(struct mt7915_dev *dev);
- void mt7915_queue_rx_skb(struct mt76_dev *mdev, enum mt76_rxq_id q,
- struct sk_buff *skb, u32 *info);
- bool mt7915_rx_check(struct mt76_dev *mdev, void *data, int len);
-@@ -629,7 +565,7 @@ void mt7915_set_stream_he_caps(struct mt7915_phy *phy);
- void mt7915_set_stream_vht_txbf_caps(struct mt7915_phy *phy);
- void mt7915_update_channel(struct mt76_phy *mphy);
- int mt7915_mcu_muru_debug_set(struct mt7915_dev *dev, bool enable);
--int mt7915_mcu_muru_debug_get(struct mt7915_phy *phy, void *ms);
-+int mt7915_mcu_muru_debug_get(struct mt7915_phy *phy);
- int mt7915_mcu_wed_enable_rx_stats(struct mt7915_dev *dev);
- int mt7915_init_debugfs(struct mt7915_phy *phy);
- void mt7915_debugfs_rx_fw_monitor(struct mt7915_dev *dev, const void *data, int len);
-diff --git a/mt7915/regs.h b/mt7915/regs.h
-index 374677f7..588cd87e 100644
---- a/mt7915/regs.h
-+++ b/mt7915/regs.h
-@@ -145,6 +145,9 @@ enum offs_rev {
- #define MT_PLE_BASE 0x820c0000
- #define MT_PLE(ofs) (MT_PLE_BASE + (ofs))
-
-+#define MT_PLE_HOST_RPT0 MT_PLE(0x030)
-+#define MT_PLE_HOST_RPT0_TX_LATENCY BIT(3)
-+
- #define MT_FL_Q_EMPTY MT_PLE(__OFFS(PLE_FL_Q_EMPTY))
- #define MT_FL_Q0_CTRL MT_PLE(__OFFS(PLE_FL_Q_CTRL))
- #define MT_FL_Q2_CTRL MT_PLE(__OFFS(PLE_FL_Q_CTRL) + 0x8)
-diff --git a/mt7915/soc.c b/mt7915/soc.c
-index fffe3623..1f23e60f 100644
---- a/mt7915/soc.c
-+++ b/mt7915/soc.c
-@@ -174,10 +174,11 @@ static u8 mt798x_wmac_check_adie_type(struct mt7915_dev *dev)
- {
- u32 val;
-
-+ /* Only DBDC A-die is used with MT7981 */
- if (is_mt7981(&dev->mt76))
- return ADIE_DBDC;
-- else
-- val = readl(dev->sku + MT_TOP_POS_SKU);
-+
-+ val = readl(dev->sku + MT_TOP_POS_SKU);
-
- return FIELD_GET(MT_TOP_POS_SKU_ADIE_DBDC_MASK, val);
- }
-@@ -268,10 +269,14 @@ static int mt798x_wmac_coninfra_check(struct mt7915_dev *dev)
- u32 cur;
- u32 con_infra_version;
-
-- if (is_mt7981(&dev->mt76))
-+ if (is_mt7981(&dev->mt76)) {
- con_infra_version = MT7981_CON_INFRA_VERSION;
-- if (is_mt7986(&dev->mt76))
-+ } else if (is_mt7986(&dev->mt76)) {
- con_infra_version = MT7986_CON_INFRA_VERSION;
-+ } else {
-+ WARN_ON(1);
-+ return -EINVAL;
-+ }
-
- return read_poll_timeout(mt76_rr, cur, (cur == con_infra_version),
- USEC_PER_MSEC, 50 * USEC_PER_MSEC,
-@@ -308,12 +313,9 @@ static int mt798x_wmac_coninfra_setup(struct mt7915_dev *dev)
- MT_TOP_MCU_EMI_BASE_MASK, val);
-
- if (is_mt7981(&dev->mt76)) {
-- /* TODO: mt7981: unsure if we need this at all
-- * This base could be also valid for the mt7986 */
- mt76_rmw_field(dev, MT_TOP_WF_AP_PERI_BASE,
- MT_TOP_WF_AP_PERI_BASE_MASK, 0x300d0000 >> 16);
-
-- /* TODO: mt7986: replace by efuse reserved region? */
- mt76_rmw_field(dev, MT_TOP_EFUSE_BASE,
- MT_TOP_EFUSE_BASE_MASK, 0x11f20000 >> 16);
- }
-@@ -519,10 +521,14 @@ static int mt798x_wmac_adie_patch_7976(struct mt7915_dev *dev, u8 adie)
- rg_xo_01 = 0x1d59080f;
- rg_xo_03 = 0x34c00fe0;
- } else {
-- if (is_mt7981(&dev->mt76))
-+ if (is_mt7981(&dev->mt76)) {
- rg_xo_01 = 0x1959c80f;
-- else if (is_mt7986(&dev->mt76))
-+ } else if (is_mt7986(&dev->mt76)) {
- rg_xo_01 = 0x1959f80f;
-+ } else {
-+ WARN_ON(1);
-+ return -EINVAL;
-+ }
- rg_xo_03 = 0x34d00fe0;
- }
-
-@@ -644,10 +650,15 @@ static int mt7986_wmac_adie_patch_7975(struct mt7915_dev *dev, u8 adie)
- return ret;
-
- /* turn on SX0 LTBUF */
-- if (is_mt7981(&dev->mt76))
-+ if (is_mt7981(&dev->mt76)) {
- ret = mt76_wmac_spi_write(dev, adie, 0x074, 0x00000007);
-- else if (is_mt7986(&dev->mt76))
-+ } else if (is_mt7986(&dev->mt76)) {
- ret = mt76_wmac_spi_write(dev, adie, 0x074, 0x00000002);
-+ } else {
-+ WARN_ON(1);
-+ return -EINVAL;
-+ }
-+
- if (ret)
- return ret;
-
-@@ -784,7 +795,6 @@ mt7986_wmac_afe_cal(struct mt7915_dev *dev, u8 adie, bool dbdc, u32 adie_type)
- MT_AFE_RG_WBG_EN_WPLL_UP_MASK, 0x1);
- usleep_range(60, 100);
-
-- /* TODO: mt7981: sets also bit WF4, but mt7986 doesn't need/allow this? */
- txcal = (MT_AFE_RG_WBG_EN_TXCAL_BT |
- MT_AFE_RG_WBG_EN_TXCAL_WF0 |
- MT_AFE_RG_WBG_EN_TXCAL_WF1 |
-@@ -930,7 +940,6 @@ static int mt7986_wmac_wm_enable(struct mt7915_dev *dev, bool enable)
- {
- u32 cur;
-
-- /* TODO: check if this is really needed or should be also used for mt7981 */
- if (is_mt7986(&dev->mt76))
- mt76_wr(dev, MT_CONNINFRA_SKU_DEC_ADDR, 0);
-
-@@ -1217,7 +1226,7 @@ static int mt798x_wmac_init(struct mt7915_dev *dev)
- return 0;
- }
-
--static int mt7986_wmac_probe(struct platform_device *pdev)
-+static int mt798x_wmac_probe(struct platform_device *pdev)
- {
- void __iomem *mem_base;
- struct mt7915_dev *dev;
-@@ -1277,7 +1286,7 @@ free_device:
- return ret;
- }
-
--static int mt7986_wmac_remove(struct platform_device *pdev)
-+static int mt798x_wmac_remove(struct platform_device *pdev)
- {
- struct mt7915_dev *dev = platform_get_drvdata(pdev);
-
-@@ -1286,21 +1295,21 @@ static int mt7986_wmac_remove(struct platform_device *pdev)
- return 0;
- }
-
--static const struct of_device_id mt7986_wmac_of_match[] = {
-+static const struct of_device_id mt798x_wmac_of_match[] = {
- { .compatible = "mediatek,mt7981-wmac", .data = (u32 *)0x7981 },
- { .compatible = "mediatek,mt7986-wmac", .data = (u32 *)0x7986 },
- {},
- };
-
--MODULE_DEVICE_TABLE(of, mt7986_wmac_of_match);
-+MODULE_DEVICE_TABLE(of, mt798x_wmac_of_match);
-
--struct platform_driver mt7986_wmac_driver = {
-+struct platform_driver mt798x_wmac_driver = {
- .driver = {
-- .name = "mt7986-wmac",
-- .of_match_table = mt7986_wmac_of_match,
-+ .name = "mt798x-wmac",
-+ .of_match_table = mt798x_wmac_of_match,
- },
-- .probe = mt7986_wmac_probe,
-- .remove = mt7986_wmac_remove,
-+ .probe = mt798x_wmac_probe,
-+ .remove = mt798x_wmac_remove,
- };
-
- MODULE_FIRMWARE(MT7986_FIRMWARE_WA);
-diff --git a/mt7921/debugfs.c b/mt7921/debugfs.c
-index d6b6edba..d6c66e77 100644
---- a/mt7921/debugfs.c
-+++ b/mt7921/debugfs.c
-@@ -95,7 +95,7 @@ mt7921_tx_stats_show(struct seq_file *file, void *data)
- {
- struct mt7921_dev *dev = file->private;
- struct mt7921_phy *phy = &dev->phy;
-- struct mib_stats *mib = &phy->mib;
-+ struct mt76_mib_stats *mib = &phy->mib;
- int i;
-
- mt7921_mutex_acquire(dev);
-diff --git a/mt7921/dma.c b/mt7921/dma.c
-index 73d8dc14..4153cd6c 100644
---- a/mt7921/dma.c
-+++ b/mt7921/dma.c
-@@ -74,9 +74,9 @@ static int mt7921_dma_disable(struct mt7921_dev *dev, bool force)
- MT_WFDMA0_GLO_CFG_OMIT_RX_INFO |
- MT_WFDMA0_GLO_CFG_OMIT_RX_INFO_PFET2);
-
-- if (!mt76_poll(dev, MT_WFDMA0_GLO_CFG,
-- MT_WFDMA0_GLO_CFG_TX_DMA_BUSY |
-- MT_WFDMA0_GLO_CFG_RX_DMA_BUSY, 0, 1000))
-+ if (!mt76_poll_msec_tick(dev, MT_WFDMA0_GLO_CFG,
-+ MT_WFDMA0_GLO_CFG_TX_DMA_BUSY |
-+ MT_WFDMA0_GLO_CFG_RX_DMA_BUSY, 0, 100, 1))
- return -ETIMEDOUT;
-
- /* disable dmashdl */
-@@ -231,10 +231,6 @@ int mt7921_dma_init(struct mt7921_dev *dev)
- if (ret)
- return ret;
-
-- ret = mt7921_wfsys_reset(dev);
-- if (ret)
-- return ret;
--
- /* init tx queue */
- ret = mt76_connac_init_tx_queues(dev->phy.mt76, MT7921_TXQ_BAND0,
- MT7921_TX_RING_SIZE,
-diff --git a/mt7921/init.c b/mt7921/init.c
-index e929f6eb..94b7cdfd 100644
---- a/mt7921/init.c
-+++ b/mt7921/init.c
-@@ -2,6 +2,9 @@
- /* Copyright (C) 2020 MediaTek Inc. */
-
- #include <linux/etherdevice.h>
-+#include <linux/hwmon.h>
-+#include <linux/hwmon-sysfs.h>
-+#include <linux/thermal.h>
- #include <linux/firmware.h>
- #include "mt7921.h"
- #include "../mt76_connac2_mac.h"
-@@ -51,6 +54,57 @@ static const struct ieee80211_iface_combination if_comb_chanctx[] = {
- }
- };
-
-+static ssize_t mt7921_thermal_temp_show(struct device *dev,
-+ struct device_attribute *attr,
-+ char *buf)
-+{
-+ switch (to_sensor_dev_attr(attr)->index) {
-+ case 0: {
-+ struct mt7921_phy *phy = dev_get_drvdata(dev);
-+ struct mt7921_dev *mdev = phy->dev;
-+ int temperature;
-+
-+ mt7921_mutex_acquire(mdev);
-+ temperature = mt7921_mcu_get_temperature(phy);
-+ mt7921_mutex_release(mdev);
-+
-+ if (temperature < 0)
-+ return temperature;
-+ /* display in millidegree Celsius */
-+ return sprintf(buf, "%u\n", temperature * 1000);
-+ }
-+ default:
-+ return -EINVAL;
-+ }
-+}
-+static SENSOR_DEVICE_ATTR_RO(temp1_input, mt7921_thermal_temp, 0);
-+
-+static struct attribute *mt7921_hwmon_attrs[] = {
-+ &sensor_dev_attr_temp1_input.dev_attr.attr,
-+ NULL,
-+};
-+ATTRIBUTE_GROUPS(mt7921_hwmon);
-+
-+static int mt7921_thermal_init(struct mt7921_phy *phy)
-+{
-+ struct wiphy *wiphy = phy->mt76->hw->wiphy;
-+ struct device *hwmon;
-+ const char *name;
-+
-+ if (!IS_REACHABLE(CONFIG_HWMON))
-+ return 0;
-+
-+ name = devm_kasprintf(&wiphy->dev, GFP_KERNEL, "mt7921_%s",
-+ wiphy_name(wiphy));
-+
-+ hwmon = devm_hwmon_device_register_with_groups(&wiphy->dev, name, phy,
-+ mt7921_hwmon_groups);
-+ if (IS_ERR(hwmon))
-+ return PTR_ERR(hwmon);
-+
-+ return 0;
-+}
-+
- static void
- mt7921_regd_notifier(struct wiphy *wiphy,
- struct regulatory_request *request)
-@@ -113,7 +167,8 @@ mt7921_init_wiphy(struct ieee80211_hw *hw)
- wiphy->max_sched_scan_ssids = MT76_CONNAC_MAX_SCHED_SCAN_SSID;
- wiphy->max_match_sets = MT76_CONNAC_MAX_SCAN_MATCH;
- wiphy->max_sched_scan_reqs = 1;
-- wiphy->flags |= WIPHY_FLAG_HAS_CHANNEL_SWITCH;
-+ wiphy->flags |= WIPHY_FLAG_HAS_CHANNEL_SWITCH |
-+ WIPHY_FLAG_SPLIT_SCAN_6GHZ;
- wiphy->reg_notifier = mt7921_regd_notifier;
-
- wiphy->features |= NL80211_FEATURE_SCHED_SCAN_RANDOM_MAC_ADDR |
-@@ -176,12 +231,12 @@ mt7921_mac_init_band(struct mt7921_dev *dev, u8 band)
- static u8
- mt7921_get_offload_capability(struct device *dev, const char *fw_wm)
- {
-- struct mt7921_fw_features *features = NULL;
- const struct mt76_connac2_fw_trailer *hdr;
- struct mt7921_realease_info *rel_info;
- const struct firmware *fw;
- int ret, i, offset = 0;
- const u8 *data, *end;
-+ u8 offload_caps = 0;
-
- ret = request_firmware(&fw, fw_wm, dev);
- if (ret)
-@@ -213,7 +268,10 @@ mt7921_get_offload_capability(struct device *dev, const char *fw_wm)
- data += sizeof(*rel_info);
-
- if (rel_info->tag == MT7921_FW_TAG_FEATURE) {
-+ struct mt7921_fw_features *features;
-+
- features = (struct mt7921_fw_features *)data;
-+ offload_caps = features->data;
- break;
- }
-
-@@ -223,7 +281,7 @@ mt7921_get_offload_capability(struct device *dev, const char *fw_wm)
- out:
- release_firmware(fw);
-
-- return features ? features->data : 0;
-+ return offload_caps;
- }
-
- struct ieee80211_ops *
-@@ -359,6 +417,12 @@ static void mt7921_init_work(struct work_struct *work)
- return;
- }
-
-+ ret = mt7921_thermal_init(&dev->phy);
-+ if (ret) {
-+ dev_err(dev->mt76.dev, "thermal init failed\n");
-+ return;
-+ }
-+
- /* we support chip reset now */
- dev->hw_init_done = true;
-
-@@ -392,8 +456,6 @@ int mt7921_register_device(struct mt7921_dev *dev)
- #endif
- skb_queue_head_init(&dev->phy.scan_event_list);
- skb_queue_head_init(&dev->coredump.msg_list);
-- INIT_LIST_HEAD(&dev->sta_poll_list);
-- spin_lock_init(&dev->sta_poll_lock);
-
- INIT_WORK(&dev->reset_work, mt7921_mac_reset_work);
- INIT_WORK(&dev->init_work, mt7921_init_work);
-diff --git a/mt7921/mac.c b/mt7921/mac.c
-index 1675bf52..368f9271 100644
---- a/mt7921/mac.c
-+++ b/mt7921/mac.c
-@@ -52,7 +52,7 @@ bool mt7921_mac_wtbl_update(struct mt7921_dev *dev, int idx, u32 mask)
- 0, 5000);
- }
-
--void mt7921_mac_sta_poll(struct mt7921_dev *dev)
-+static void mt7921_mac_sta_poll(struct mt7921_dev *dev)
- {
- static const u8 ac_to_tid[] = {
- [IEEE80211_AC_BE] = 0,
-@@ -68,9 +68,9 @@ void mt7921_mac_sta_poll(struct mt7921_dev *dev)
- s8 rssi[4];
- int i;
-
-- spin_lock_bh(&dev->sta_poll_lock);
-- list_splice_init(&dev->sta_poll_list, &sta_poll_list);
-- spin_unlock_bh(&dev->sta_poll_lock);
-+ spin_lock_bh(&dev->mt76.sta_poll_lock);
-+ list_splice_init(&dev->mt76.sta_poll_list, &sta_poll_list);
-+ spin_unlock_bh(&dev->mt76.sta_poll_lock);
-
- while (true) {
- bool clear = false;
-@@ -78,15 +78,15 @@ void mt7921_mac_sta_poll(struct mt7921_dev *dev)
- u16 idx;
- u8 bw;
-
-- spin_lock_bh(&dev->sta_poll_lock);
-+ spin_lock_bh(&dev->mt76.sta_poll_lock);
- if (list_empty(&sta_poll_list)) {
-- spin_unlock_bh(&dev->sta_poll_lock);
-+ spin_unlock_bh(&dev->mt76.sta_poll_lock);
- break;
- }
- msta = list_first_entry(&sta_poll_list,
-- struct mt7921_sta, poll_list);
-- list_del_init(&msta->poll_list);
-- spin_unlock_bh(&dev->sta_poll_lock);
-+ struct mt7921_sta, wcid.poll_list);
-+ list_del_init(&msta->wcid.poll_list);
-+ spin_unlock_bh(&dev->mt76.sta_poll_lock);
-
- idx = msta->wcid.idx;
- addr = mt7921_mac_wtbl_lmac_addr(idx, MT_WTBL_AC0_CTT_OFFSET);
-@@ -183,7 +183,6 @@ void mt7921_mac_sta_poll(struct mt7921_dev *dev)
- ewma_avg_signal_add(&msta->avg_ack_signal, -msta->ack_signal);
- }
- }
--EXPORT_SYMBOL_GPL(mt7921_mac_sta_poll);
-
- static void
- mt7921_get_status_freq_info(struct mt7921_dev *dev, struct mt76_phy *mphy,
-@@ -281,10 +280,11 @@ mt7921_mac_fill_rx(struct mt7921_dev *dev, struct sk_buff *skb)
-
- if (status->wcid) {
- msta = container_of(status->wcid, struct mt7921_sta, wcid);
-- spin_lock_bh(&dev->sta_poll_lock);
-- if (list_empty(&msta->poll_list))
-- list_add_tail(&msta->poll_list, &dev->sta_poll_list);
-- spin_unlock_bh(&dev->sta_poll_lock);
-+ spin_lock_bh(&dev->mt76.sta_poll_lock);
-+ if (list_empty(&msta->wcid.poll_list))
-+ list_add_tail(&msta->wcid.poll_list,
-+ &dev->mt76.sta_poll_list);
-+ spin_unlock_bh(&dev->mt76.sta_poll_lock);
- }
-
- mt7921_get_status_freq_info(dev, mphy, status, chfreq);
-@@ -511,30 +511,6 @@ mt7921_mac_fill_rx(struct mt7921_dev *dev, struct sk_buff *skb)
- return 0;
- }
-
--static void mt7921_tx_check_aggr(struct ieee80211_sta *sta, __le32 *txwi)
--{
-- struct mt7921_sta *msta;
-- u16 fc, tid;
-- u32 val;
--
-- if (!sta || !(sta->deflink.ht_cap.ht_supported || sta->deflink.he_cap.has_he))
-- return;
--
-- tid = le32_get_bits(txwi[1], MT_TXD1_TID);
-- if (tid >= 6) /* skip VO queue */
-- return;
--
-- val = le32_to_cpu(txwi[2]);
-- fc = FIELD_GET(MT_TXD2_FRAME_TYPE, val) << 2 |
-- FIELD_GET(MT_TXD2_SUB_TYPE, val) << 4;
-- if (unlikely(fc != (IEEE80211_FTYPE_DATA | IEEE80211_STYPE_QOS_DATA)))
-- return;
--
-- msta = (struct mt7921_sta *)sta->drv_priv;
-- if (!test_and_set_bit(tid, &msta->ampdu_state))
-- ieee80211_start_tx_ba_session(sta, tid, 0);
--}
--
- void mt7921_mac_add_txs(struct mt7921_dev *dev, void *data)
- {
- struct mt7921_sta *msta = NULL;
-@@ -567,46 +543,15 @@ void mt7921_mac_add_txs(struct mt7921_dev *dev, void *data)
- if (!wcid->sta)
- goto out;
-
-- spin_lock_bh(&dev->sta_poll_lock);
-- if (list_empty(&msta->poll_list))
-- list_add_tail(&msta->poll_list, &dev->sta_poll_list);
-- spin_unlock_bh(&dev->sta_poll_lock);
-+ spin_lock_bh(&dev->mt76.sta_poll_lock);
-+ if (list_empty(&msta->wcid.poll_list))
-+ list_add_tail(&msta->wcid.poll_list, &dev->mt76.sta_poll_list);
-+ spin_unlock_bh(&dev->mt76.sta_poll_lock);
-
- out:
- rcu_read_unlock();
- }
-
--void mt7921_txwi_free(struct mt7921_dev *dev, struct mt76_txwi_cache *t,
-- struct ieee80211_sta *sta, bool clear_status,
-- struct list_head *free_list)
--{
-- struct mt76_dev *mdev = &dev->mt76;
-- __le32 *txwi;
-- u16 wcid_idx;
--
-- mt76_connac_txp_skb_unmap(mdev, t);
-- if (!t->skb)
-- goto out;
--
-- txwi = (__le32 *)mt76_get_txwi_ptr(mdev, t);
-- if (sta) {
-- struct mt76_wcid *wcid = (struct mt76_wcid *)sta->drv_priv;
--
-- if (likely(t->skb->protocol != cpu_to_be16(ETH_P_PAE)))
-- mt7921_tx_check_aggr(sta, txwi);
--
-- wcid_idx = wcid->idx;
-- } else {
-- wcid_idx = le32_get_bits(txwi[1], MT_TXD1_WLAN_IDX);
-- }
--
-- __mt76_tx_complete_skb(mdev, wcid_idx, t->skb, free_list);
--out:
-- t->skb = NULL;
-- mt76_put_txwi(mdev, t);
--}
--EXPORT_SYMBOL_GPL(mt7921_txwi_free);
--
- static void mt7921_mac_tx_free(struct mt7921_dev *dev, void *data, int len)
- {
- struct mt76_connac_tx_free *free = data;
-@@ -614,6 +559,7 @@ static void mt7921_mac_tx_free(struct mt7921_dev *dev, void *data, int len)
- struct mt76_dev *mdev = &dev->mt76;
- struct mt76_txwi_cache *txwi;
- struct ieee80211_sta *sta = NULL;
-+ struct mt76_wcid *wcid = NULL;
- struct sk_buff *skb, *tmp;
- void *end = data + len;
- LIST_HEAD(free_list);
-@@ -637,7 +583,6 @@ static void mt7921_mac_tx_free(struct mt7921_dev *dev, void *data, int len)
- */
- if (info & MT_TX_FREE_PAIR) {
- struct mt7921_sta *msta;
-- struct mt76_wcid *wcid;
- u16 idx;
-
- count++;
-@@ -648,21 +593,28 @@ static void mt7921_mac_tx_free(struct mt7921_dev *dev, void *data, int len)
- continue;
-
- msta = container_of(wcid, struct mt7921_sta, wcid);
-- spin_lock_bh(&dev->sta_poll_lock);
-- if (list_empty(&msta->poll_list))
-- list_add_tail(&msta->poll_list, &dev->sta_poll_list);
-- spin_unlock_bh(&dev->sta_poll_lock);
-+ spin_lock_bh(&mdev->sta_poll_lock);
-+ if (list_empty(&msta->wcid.poll_list))
-+ list_add_tail(&msta->wcid.poll_list,
-+ &mdev->sta_poll_list);
-+ spin_unlock_bh(&mdev->sta_poll_lock);
- continue;
- }
-
- msdu = FIELD_GET(MT_TX_FREE_MSDU_ID, info);
- stat = FIELD_GET(MT_TX_FREE_STATUS, info);
-
-+ if (wcid) {
-+ wcid->stats.tx_retries +=
-+ FIELD_GET(MT_TX_FREE_COUNT, info) - 1;
-+ wcid->stats.tx_failed += !!stat;
-+ }
-+
- txwi = mt76_token_release(mdev, msdu, &wake);
- if (!txwi)
- continue;
-
-- mt7921_txwi_free(dev, txwi, sta, stat, &free_list);
-+ mt76_connac2_txwi_free(mdev, txwi, sta, &free_list);
- }
-
- if (wake)
-@@ -952,8 +904,8 @@ EXPORT_SYMBOL_GPL(mt7921_reset);
-
- void mt7921_mac_update_mib_stats(struct mt7921_phy *phy)
- {
-+ struct mt76_mib_stats *mib = &phy->mib;
- struct mt7921_dev *dev = phy->dev;
-- struct mib_stats *mib = &phy->mib;
- int i, aggr0 = 0, aggr1;
- u32 val;
-
-@@ -1180,6 +1132,10 @@ int mt7921_usb_sdio_tx_prepare_skb(struct mt76_dev *mdev, void *txwi_ptr,
- if (unlikely(tx_info->skb->len <= ETH_HLEN))
- return -EINVAL;
-
-+ err = skb_cow_head(skb, MT_SDIO_TXD_SIZE + MT_SDIO_HDR_SIZE);
-+ if (err)
-+ return err;
-+
- if (!wcid)
- wcid = &dev->mt76.global_wcid;
-
-@@ -1224,7 +1180,7 @@ void mt7921_usb_sdio_tx_complete_skb(struct mt76_dev *mdev,
- sta = wcid_to_sta(wcid);
-
- if (sta && likely(e->skb->protocol != cpu_to_be16(ETH_P_PAE)))
-- mt7921_tx_check_aggr(sta, txwi);
-+ mt76_connac2_tx_check_aggr(sta, txwi);
-
- skb_pull(e->skb, headroom);
- mt76_tx_complete_skb(mdev, e->wcid, e->skb);
-diff --git a/mt7921/main.c b/mt7921/main.c
-index 3b6adb29..87067ac3 100644
---- a/mt7921/main.c
-+++ b/mt7921/main.c
-@@ -313,7 +313,7 @@ static int mt7921_add_interface(struct ieee80211_hw *hw,
-
- idx = MT7921_WTBL_RESERVED - mvif->mt76.idx;
-
-- INIT_LIST_HEAD(&mvif->sta.poll_list);
-+ INIT_LIST_HEAD(&mvif->sta.wcid.poll_list);
- mvif->sta.wcid.idx = idx;
- mvif->sta.wcid.phy_idx = mvif->mt76.band_idx;
- mvif->sta.wcid.hw_key_idx = -1;
-@@ -357,10 +357,10 @@ static void mt7921_remove_interface(struct ieee80211_hw *hw,
- phy->omac_mask &= ~BIT_ULL(mvif->mt76.omac_idx);
- mt7921_mutex_release(dev);
-
-- spin_lock_bh(&dev->sta_poll_lock);
-- if (!list_empty(&msta->poll_list))
-- list_del_init(&msta->poll_list);
-- spin_unlock_bh(&dev->sta_poll_lock);
-+ spin_lock_bh(&dev->mt76.sta_poll_lock);
-+ if (!list_empty(&msta->wcid.poll_list))
-+ list_del_init(&msta->wcid.poll_list);
-+ spin_unlock_bh(&dev->mt76.sta_poll_lock);
-
- mt76_packet_id_flush(&dev->mt76, &msta->wcid);
- }
-@@ -764,7 +764,7 @@ int mt7921_mac_sta_add(struct mt76_dev *mdev, struct ieee80211_vif *vif,
- if (idx < 0)
- return -ENOSPC;
-
-- INIT_LIST_HEAD(&msta->poll_list);
-+ INIT_LIST_HEAD(&msta->wcid.poll_list);
- msta->vif = mvif;
- msta->wcid.sta = 1;
- msta->wcid.idx = idx;
-@@ -842,10 +842,10 @@ void mt7921_mac_sta_remove(struct mt76_dev *mdev, struct ieee80211_vif *vif,
- mvif->ctx);
- }
-
-- spin_lock_bh(&dev->sta_poll_lock);
-- if (!list_empty(&msta->poll_list))
-- list_del_init(&msta->poll_list);
-- spin_unlock_bh(&dev->sta_poll_lock);
-+ spin_lock_bh(&dev->mt76.sta_poll_lock);
-+ if (!list_empty(&msta->wcid.poll_list))
-+ list_del_init(&msta->wcid.poll_list);
-+ spin_unlock_bh(&dev->mt76.sta_poll_lock);
-
- mt76_connac_power_save_sched(&dev->mphy, &dev->pm);
- }
-@@ -954,16 +954,16 @@ mt7921_ampdu_action(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
- case IEEE80211_AMPDU_TX_STOP_FLUSH:
- case IEEE80211_AMPDU_TX_STOP_FLUSH_CONT:
- mtxq->aggr = false;
-- clear_bit(tid, &msta->ampdu_state);
-+ clear_bit(tid, &msta->wcid.ampdu_state);
- mt7921_mcu_uni_tx_ba(dev, params, false);
- break;
- case IEEE80211_AMPDU_TX_START:
-- set_bit(tid, &msta->ampdu_state);
-+ set_bit(tid, &msta->wcid.ampdu_state);
- ret = IEEE80211_AMPDU_TX_START_IMMEDIATE;
- break;
- case IEEE80211_AMPDU_TX_STOP_CONT:
- mtxq->aggr = false;
-- clear_bit(tid, &msta->ampdu_state);
-+ clear_bit(tid, &msta->wcid.ampdu_state);
- mt7921_mcu_uni_tx_ba(dev, params, false);
- ieee80211_stop_tx_ba_cb_irqsafe(vif, sta->addr, tid);
- break;
-@@ -995,7 +995,7 @@ mt7921_get_stats(struct ieee80211_hw *hw,
- struct ieee80211_low_level_stats *stats)
- {
- struct mt7921_phy *phy = mt7921_hw_phy(hw);
-- struct mib_stats *mib = &phy->mib;
-+ struct mt76_mib_stats *mib = &phy->mib;
-
- mt7921_mutex_acquire(phy->dev);
-
-@@ -1077,6 +1077,10 @@ static const char mt7921_gstrings_stats[][ETH_GSTRING_LEN] = {
- "v_tx_mcs_9",
- "v_tx_mcs_10",
- "v_tx_mcs_11",
-+ "v_tx_nss_1",
-+ "v_tx_nss_2",
-+ "v_tx_nss_3",
-+ "v_tx_nss_4",
- };
-
- static void
-@@ -1133,7 +1137,7 @@ void mt7921_get_et_stats(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
- int stats_size = ARRAY_SIZE(mt7921_gstrings_stats);
- struct mt7921_phy *phy = mt7921_hw_phy(hw);
- struct mt7921_dev *dev = phy->dev;
-- struct mib_stats *mib = &phy->mib;
-+ struct mt76_mib_stats *mib = &phy->mib;
- struct mt76_ethtool_worker_info wi = {
- .data = data,
- .idx = mvif->mt76.idx,
-@@ -1363,7 +1367,7 @@ mt7921_set_antenna(struct ieee80211_hw *hw, u32 tx_ant, u32 rx_ant)
- return -EINVAL;
-
- if ((BIT(hweight8(tx_ant)) - 1) != tx_ant)
-- tx_ant = BIT(ffs(tx_ant) - 1) - 1;
-+ return -EINVAL;
-
- mt7921_mutex_acquire(dev);
-
-@@ -1399,6 +1403,12 @@ static void mt7921_sta_statistics(struct ieee80211_hw *hw,
- sinfo->txrate.he_dcm = txrate->he_dcm;
- sinfo->txrate.he_ru_alloc = txrate->he_ru_alloc;
- }
-+ sinfo->tx_failed = msta->wcid.stats.tx_failed;
-+ sinfo->filled |= BIT_ULL(NL80211_STA_INFO_TX_FAILED);
-+
-+ sinfo->tx_retries = msta->wcid.stats.tx_retries;
-+ sinfo->filled |= BIT_ULL(NL80211_STA_INFO_TX_RETRIES);
-+
- sinfo->txrate.flags = txrate->flags;
- sinfo->filled |= BIT_ULL(NL80211_STA_INFO_TX_BITRATE);
-
-diff --git a/mt7921/mcu.c b/mt7921/mcu.c
-index c69ce6df..a0ad18c7 100644
---- a/mt7921/mcu.c
-+++ b/mt7921/mcu.c
-@@ -476,12 +476,6 @@ static int mt7921_load_firmware(struct mt7921_dev *dev)
- {
- int ret;
-
-- ret = mt76_get_field(dev, MT_CONN_ON_MISC, MT_TOP_MISC2_FW_N9_RDY);
-- if (ret && mt76_is_mmio(&dev->mt76)) {
-- dev_dbg(dev->mt76.dev, "Firmware is already download\n");
-- goto fw_loaded;
-- }
--
- ret = mt76_connac2_load_patch(&dev->mt76, mt7921_patch_name(dev));
- if (ret)
- return ret;
-@@ -504,8 +498,6 @@ static int mt7921_load_firmware(struct mt7921_dev *dev)
- return -EIO;
- }
-
--fw_loaded:
--
- #ifdef CONFIG_PM
- dev->mt76.hw->wiphy->wowlan = &mt76_connac_wowlan_support;
- #endif /* CONFIG_PM */
-@@ -1313,6 +1305,23 @@ int mt7921_mcu_set_clc(struct mt7921_dev *dev, u8 *alpha2,
- return 0;
- }
-
-+int mt7921_mcu_get_temperature(struct mt7921_phy *phy)
-+{
-+ struct mt7921_dev *dev = phy->dev;
-+ struct {
-+ u8 ctrl_id;
-+ u8 action;
-+ u8 band_idx;
-+ u8 rsv[5];
-+ } req = {
-+ .ctrl_id = THERMAL_SENSOR_TEMP_QUERY,
-+ .band_idx = phy->mt76->band_idx,
-+ };
-+
-+ return mt76_mcu_send_msg(&dev->mt76, MCU_EXT_CMD(THERMAL_CTRL), &req,
-+ sizeof(req), true);
-+}
-+
- int mt7921_mcu_set_rxfilter(struct mt7921_dev *dev, u32 fif,
- u8 bit_op, u32 bit_map)
- {
-diff --git a/mt7921/mt7921.h b/mt7921/mt7921.h
-index 149acb16..ec987965 100644
---- a/mt7921/mt7921.h
-+++ b/mt7921/mt7921.h
-@@ -19,7 +19,6 @@
- #define MT7921_PM_TIMEOUT (HZ / 12)
- #define MT7921_HW_SCAN_TIMEOUT (HZ / 10)
- #define MT7921_WATCHDOG_TIME (HZ / 4)
--#define MT7921_RESET_TIMEOUT (30 * HZ)
-
- #define MT7921_TX_RING_SIZE 2048
- #define MT7921_TX_MCU_RING_SIZE 256
-@@ -151,14 +150,12 @@ struct mt7921_sta {
-
- struct mt7921_vif *vif;
-
-- struct list_head poll_list;
- u32 airtime_ac[8];
-
- int ack_signal;
- struct ewma_avg_signal avg_ack_signal;
-
- unsigned long last_txs;
-- unsigned long ampdu_state;
-
- struct mt76_connac_sta_key_conf bip;
- };
-@@ -179,35 +176,6 @@ struct mt7921_vif {
- struct ieee80211_chanctx_conf *ctx;
- };
-
--struct mib_stats {
-- u32 ack_fail_cnt;
-- u32 fcs_err_cnt;
-- u32 rts_cnt;
-- u32 rts_retries_cnt;
-- u32 ba_miss_cnt;
--
-- u32 tx_bf_ibf_ppdu_cnt;
-- u32 tx_bf_ebf_ppdu_cnt;
-- u32 tx_bf_rx_fb_all_cnt;
-- u32 tx_bf_rx_fb_he_cnt;
-- u32 tx_bf_rx_fb_vht_cnt;
-- u32 tx_bf_rx_fb_ht_cnt;
--
-- u32 tx_ampdu_cnt;
-- u32 tx_mpdu_attempts_cnt;
-- u32 tx_mpdu_success_cnt;
-- u32 tx_pkt_ebf_cnt;
-- u32 tx_pkt_ibf_cnt;
--
-- u32 rx_mpdu_cnt;
-- u32 rx_ampdu_cnt;
-- u32 rx_ampdu_bytes_cnt;
-- u32 rx_ba_cnt;
--
-- u32 tx_amsdu[8];
-- u32 tx_amsdu_cnt;
--};
--
- enum {
- MT7921_CLC_POWER,
- MT7921_CLC_CHAN,
-@@ -247,7 +215,7 @@ struct mt7921_phy {
- u32 rx_ampdu_ts;
- u32 ampdu_ref;
-
-- struct mib_stats mib;
-+ struct mt76_mib_stats mib;
-
- u8 sta_work_count;
-
-@@ -304,9 +272,6 @@ struct mt7921_dev {
- bool hw_init_done:1;
- bool fw_assert:1;
-
-- struct list_head sta_poll_list;
-- spinlock_t sta_poll_lock;
--
- struct work_struct init_work;
-
- u8 fw_debug;
-@@ -477,7 +442,6 @@ int mt7921e_tx_prepare_skb(struct mt76_dev *mdev, void *txwi_ptr,
- struct mt76_tx_info *tx_info);
-
- void mt7921_tx_worker(struct mt76_worker *w);
--void mt7921_tx_token_put(struct mt7921_dev *dev);
- bool mt7921_rx_check(struct mt76_dev *mdev, void *data, int len);
- void mt7921_queue_rx_skb(struct mt76_dev *mdev, enum mt76_rxq_id q,
- struct sk_buff *skb, u32 *info);
-@@ -510,10 +474,6 @@ int mt7921_testmode_cmd(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
- void *data, int len);
- int mt7921_testmode_dump(struct ieee80211_hw *hw, struct sk_buff *msg,
- struct netlink_callback *cb, void *data, int len);
--void mt7921_txwi_free(struct mt7921_dev *dev, struct mt76_txwi_cache *t,
-- struct ieee80211_sta *sta, bool clear_status,
-- struct list_head *free_list);
--void mt7921_mac_sta_poll(struct mt7921_dev *dev);
- int mt7921_mcu_parse_response(struct mt76_dev *mdev, int cmd,
- struct sk_buff *skb, int seq);
-
-@@ -540,6 +500,7 @@ int mt7921_mcu_set_sniffer(struct mt7921_dev *dev, struct ieee80211_vif *vif,
- bool enable);
- int mt7921_mcu_config_sniffer(struct mt7921_vif *vif,
- struct ieee80211_chanctx_conf *ctx);
-+int mt7921_mcu_get_temperature(struct mt7921_phy *phy);
-
- int mt7921_usb_sdio_tx_prepare_skb(struct mt76_dev *mdev, void *txwi_ptr,
- enum mt76_txq_id qid, struct mt76_wcid *wcid,
-diff --git a/mt7921/pci.c b/mt7921/pci.c
-index 1c727870..7c8bf719 100644
---- a/mt7921/pci.c
-+++ b/mt7921/pci.c
-@@ -115,7 +115,7 @@ static void mt7921e_unregister_device(struct mt7921_dev *dev)
- cancel_work_sync(&pm->wake_work);
- cancel_work_sync(&dev->reset_work);
-
-- mt7921_tx_token_put(dev);
-+ mt76_connac2_tx_token_put(&dev->mt76);
- __mt7921_mcu_drv_pmctrl(dev);
- mt7921_dma_cleanup(dev);
- mt7921_wfsys_reset(dev);
-@@ -325,6 +325,10 @@ static int mt7921_pci_probe(struct pci_dev *pdev,
- bus_ops->rmw = mt7921_rmw;
- dev->mt76.bus = bus_ops;
-
-+ ret = mt7921e_mcu_fw_pmctrl(dev);
-+ if (ret)
-+ goto err_free_dev;
-+
- ret = __mt7921e_mcu_drv_pmctrl(dev);
- if (ret)
- goto err_free_dev;
-@@ -333,6 +337,10 @@ static int mt7921_pci_probe(struct pci_dev *pdev,
- (mt7921_l1_rr(dev, MT_HW_REV) & 0xff);
- dev_info(mdev->dev, "ASIC revision: %04x\n", mdev->rev);
-
-+ ret = mt7921_wfsys_reset(dev);
-+ if (ret)
-+ goto err_free_dev;
-+
- mt76_wr(dev, MT_WFDMA0_HOST_INT_ENA, 0);
-
- mt76_wr(dev, MT_PCIE_MAC_INT_ENABLE, 0xff);
-diff --git a/mt7921/pci_mac.c b/mt7921/pci_mac.c
-index 6053a255..978c90a0 100644
---- a/mt7921/pci_mac.c
-+++ b/mt7921/pci_mac.c
-@@ -53,20 +53,6 @@ int mt7921e_tx_prepare_skb(struct mt76_dev *mdev, void *txwi_ptr,
- return 0;
- }
-
--void mt7921_tx_token_put(struct mt7921_dev *dev)
--{
-- struct mt76_txwi_cache *txwi;
-- int id;
--
-- spin_lock_bh(&dev->mt76.token_lock);
-- idr_for_each_entry(&dev->mt76.token, txwi, id) {
-- mt7921_txwi_free(dev, txwi, NULL, false, NULL);
-- dev->mt76.token_count--;
-- }
-- spin_unlock_bh(&dev->mt76.token_lock);
-- idr_destroy(&dev->mt76.token);
--}
--
- int mt7921e_mac_reset(struct mt7921_dev *dev)
- {
- int i, err;
-@@ -91,7 +77,7 @@ int mt7921e_mac_reset(struct mt7921_dev *dev)
- napi_disable(&dev->mt76.napi[MT_RXQ_MCU_WA]);
- napi_disable(&dev->mt76.tx_napi);
-
-- mt7921_tx_token_put(dev);
-+ mt76_connac2_tx_token_put(&dev->mt76);
- idr_init(&dev->mt76.token);
-
- mt7921_wpdma_reset(dev, true);
-diff --git a/mt7921/regs.h b/mt7921/regs.h
-index e52977ff..b1801425 100644
---- a/mt7921/regs.h
-+++ b/mt7921/regs.h
-@@ -158,7 +158,6 @@
-
- #define MT_MIB_MB_SDR0(_band, n) MT_WF_MIB(_band, 0x100 + ((n) << 4))
- #define MT_MIB_RTS_RETRIES_COUNT_MASK GENMASK(31, 16)
--#define MT_MIB_RTS_COUNT_MASK GENMASK(15, 0)
-
- #define MT_MIB_MB_BSDR0(_band) MT_WF_MIB(_band, 0x688)
- #define MT_MIB_RTS_COUNT_MASK GENMASK(15, 0)
-diff --git a/mt7996/debugfs.c b/mt7996/debugfs.c
-index 513ab4ba..4d40ec7f 100644
---- a/mt7996/debugfs.c
-+++ b/mt7996/debugfs.c
-@@ -474,10 +474,10 @@ mt7996_ampdu_stat_read_phy(struct mt7996_phy *phy, struct seq_file *file)
- static void
- mt7996_txbf_stat_read_phy(struct mt7996_phy *phy, struct seq_file *s)
- {
-+ struct mt76_mib_stats *mib = &phy->mib;
- static const char * const bw[] = {
- "BW20", "BW40", "BW80", "BW160"
- };
-- struct mib_stats *mib = &phy->mib;
-
- /* Tx Beamformer monitor */
- seq_puts(s, "\nTx Beamformer applied PPDU counts: ");
-@@ -523,7 +523,7 @@ mt7996_tx_stats_show(struct seq_file *file, void *data)
- {
- struct mt7996_phy *phy = file->private;
- struct mt7996_dev *dev = phy->dev;
-- struct mib_stats *mib = &phy->mib;
-+ struct mt76_mib_stats *mib = &phy->mib;
- int i;
- u32 attempts, success, per;
-
-diff --git a/mt7996/dma.c b/mt7996/dma.c
-index 53414346..586e247a 100644
---- a/mt7996/dma.c
-+++ b/mt7996/dma.c
-@@ -128,11 +128,55 @@ static void mt7996_dma_disable(struct mt7996_dev *dev, bool reset)
- }
- }
-
--static int mt7996_dma_enable(struct mt7996_dev *dev)
-+void mt7996_dma_start(struct mt7996_dev *dev, bool reset)
- {
- u32 hif1_ofs = 0;
- u32 irq_mask;
-
-+ if (dev->hif2)
-+ hif1_ofs = MT_WFDMA0_PCIE1(0) - MT_WFDMA0(0);
-+
-+ /* enable WFDMA Tx/Rx */
-+ if (!reset) {
-+ mt76_set(dev, MT_WFDMA0_GLO_CFG,
-+ MT_WFDMA0_GLO_CFG_TX_DMA_EN |
-+ MT_WFDMA0_GLO_CFG_RX_DMA_EN |
-+ MT_WFDMA0_GLO_CFG_OMIT_TX_INFO |
-+ MT_WFDMA0_GLO_CFG_OMIT_RX_INFO_PFET2);
-+
-+ if (dev->hif2)
-+ mt76_set(dev, MT_WFDMA0_GLO_CFG + hif1_ofs,
-+ MT_WFDMA0_GLO_CFG_TX_DMA_EN |
-+ MT_WFDMA0_GLO_CFG_RX_DMA_EN |
-+ MT_WFDMA0_GLO_CFG_OMIT_TX_INFO |
-+ MT_WFDMA0_GLO_CFG_OMIT_RX_INFO_PFET2);
-+ }
-+
-+ /* enable interrupts for TX/RX rings */
-+ irq_mask = MT_INT_MCU_CMD;
-+ if (reset)
-+ goto done;
-+
-+ irq_mask = MT_INT_RX_DONE_MCU | MT_INT_TX_DONE_MCU;
-+
-+ if (!dev->mphy.band_idx)
-+ irq_mask |= MT_INT_BAND0_RX_DONE;
-+
-+ if (dev->dbdc_support)
-+ irq_mask |= MT_INT_BAND1_RX_DONE;
-+
-+ if (dev->tbtc_support)
-+ irq_mask |= MT_INT_BAND2_RX_DONE;
-+
-+done:
-+ mt7996_irq_enable(dev, irq_mask);
-+ mt7996_irq_disable(dev, 0);
-+}
-+
-+static void mt7996_dma_enable(struct mt7996_dev *dev, bool reset)
-+{
-+ u32 hif1_ofs = 0;
-+
- if (dev->hif2)
- hif1_ofs = MT_WFDMA0_PCIE1(0) - MT_WFDMA0(0);
-
-@@ -170,13 +214,6 @@ static int mt7996_dma_enable(struct mt7996_dev *dev)
- mt76_poll(dev, MT_WFDMA_EXT_CSR_HIF_MISC,
- MT_WFDMA_EXT_CSR_HIF_MISC_BUSY, 0, 1000);
-
-- /* set WFDMA Tx/Rx */
-- mt76_set(dev, MT_WFDMA0_GLO_CFG,
-- MT_WFDMA0_GLO_CFG_TX_DMA_EN |
-- MT_WFDMA0_GLO_CFG_RX_DMA_EN |
-- MT_WFDMA0_GLO_CFG_OMIT_TX_INFO |
-- MT_WFDMA0_GLO_CFG_OMIT_RX_INFO_PFET2);
--
- /* GLO_CFG_EXT0 */
- mt76_set(dev, WF_WFDMA0_GLO_CFG_EXT0,
- WF_WFDMA0_GLO_CFG_EXT0_RX_WB_RXD |
-@@ -187,12 +224,6 @@ static int mt7996_dma_enable(struct mt7996_dev *dev)
- WF_WFDMA0_GLO_CFG_EXT1_TX_FCTRL_MODE);
-
- if (dev->hif2) {
-- mt76_set(dev, MT_WFDMA0_GLO_CFG + hif1_ofs,
-- MT_WFDMA0_GLO_CFG_TX_DMA_EN |
-- MT_WFDMA0_GLO_CFG_RX_DMA_EN |
-- MT_WFDMA0_GLO_CFG_OMIT_TX_INFO |
-- MT_WFDMA0_GLO_CFG_OMIT_RX_INFO_PFET2);
--
- /* GLO_CFG_EXT0 */
- mt76_set(dev, WF_WFDMA0_GLO_CFG_EXT0 + hif1_ofs,
- WF_WFDMA0_GLO_CFG_EXT0_RX_WB_RXD |
-@@ -216,23 +247,7 @@ static int mt7996_dma_enable(struct mt7996_dev *dev)
- /* TODO: redirect rx ring6 interrupt to pcie0 for wed function */
- }
-
-- /* enable interrupts for TX/RX rings */
-- irq_mask = MT_INT_RX_DONE_MCU |
-- MT_INT_TX_DONE_MCU |
-- MT_INT_MCU_CMD;
--
-- if (!dev->mphy.band_idx)
-- irq_mask |= MT_INT_BAND0_RX_DONE;
--
-- if (dev->dbdc_support)
-- irq_mask |= MT_INT_BAND1_RX_DONE;
--
-- if (dev->tbtc_support)
-- irq_mask |= MT_INT_BAND2_RX_DONE;
--
-- mt7996_irq_enable(dev, irq_mask);
--
-- return 0;
-+ mt7996_dma_start(dev, reset);
- }
-
- int mt7996_dma_init(struct mt7996_dev *dev)
-@@ -293,7 +308,7 @@ int mt7996_dma_init(struct mt7996_dev *dev)
- /* event from WA */
- ret = mt76_queue_alloc(dev, &dev->mt76.q_rx[MT_RXQ_MCU_WA],
- MT_RXQ_ID(MT_RXQ_MCU_WA),
-- MT7996_RX_MCU_RING_SIZE,
-+ MT7996_RX_MCU_RING_SIZE_WA,
- MT_RX_BUF_SIZE,
- MT_RXQ_RING_BASE(MT_RXQ_MCU_WA));
- if (ret)
-@@ -347,7 +362,7 @@ int mt7996_dma_init(struct mt7996_dev *dev)
- mt7996_poll_tx);
- napi_enable(&dev->mt76.tx_napi);
-
-- mt7996_dma_enable(dev);
-+ mt7996_dma_enable(dev, false);
-
- return 0;
- }
-@@ -413,7 +428,7 @@ void mt7996_dma_reset(struct mt7996_dev *dev, bool force)
- mt76_for_each_q_rx(&dev->mt76, i)
- mt76_queue_rx_reset(dev, i);
-
-- mt7996_dma_enable(dev);
-+ mt7996_dma_enable(dev, !force);
- }
-
- void mt7996_dma_cleanup(struct mt7996_dev *dev)
-diff --git a/mt7996/init.c b/mt7996/init.c
-index f1b48cdd..e297e7cb 100644
---- a/mt7996/init.c
-+++ b/mt7996/init.c
-@@ -183,6 +183,7 @@ mt7996_init_wiphy(struct ieee80211_hw *hw)
- wiphy_ext_feature_set(wiphy, NL80211_EXT_FEATURE_FILS_DISCOVERY);
- wiphy_ext_feature_set(wiphy, NL80211_EXT_FEATURE_ACK_SIGNAL_SUPPORT);
- wiphy_ext_feature_set(wiphy, NL80211_EXT_FEATURE_CAN_REPLACE_PTK0);
-+ wiphy_ext_feature_set(wiphy, NL80211_EXT_FEATURE_MU_MIMO_AIR_SNIFFER);
-
- if (!mdev->dev->of_node ||
- !of_property_read_bool(mdev->dev->of_node,
-@@ -217,6 +218,8 @@ mt7996_init_wiphy(struct ieee80211_hw *hw)
- IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_160MHZ;
- phy->mt76->sband_5g.sband.ht_cap.ampdu_density =
- IEEE80211_HT_MPDU_DENSITY_1;
-+
-+ ieee80211_hw_set(hw, SUPPORTS_VHT_EXT_NSS_BW);
- }
-
- mt76_set_stream_caps(phy->mt76, true);
-@@ -853,9 +856,7 @@ int mt7996_register_device(struct mt7996_dev *dev)
- INIT_WORK(&dev->rc_work, mt7996_mac_sta_rc_work);
- INIT_DELAYED_WORK(&dev->mphy.mac_work, mt7996_mac_work);
- INIT_LIST_HEAD(&dev->sta_rc_list);
-- INIT_LIST_HEAD(&dev->sta_poll_list);
- INIT_LIST_HEAD(&dev->twt_list);
-- spin_lock_init(&dev->sta_poll_lock);
-
- init_waitqueue_head(&dev->reset_wait);
- INIT_WORK(&dev->reset_work, mt7996_mac_reset_work);
-diff --git a/mt7996/mac.c b/mt7996/mac.c
-index 0d51090d..17dd531e 100644
---- a/mt7996/mac.c
-+++ b/mt7996/mac.c
-@@ -13,10 +13,6 @@
-
- #define to_rssi(field, rcpi) ((FIELD_GET(field, rcpi) - 220) / 2)
-
--#define HE_BITS(f) cpu_to_le16(IEEE80211_RADIOTAP_HE_##f)
--#define HE_PREP(f, m, v) le16_encode_bits(le32_get_bits(v, MT_CRXV_HE_##m),\
-- IEEE80211_RADIOTAP_HE_##f)
--
- static const struct mt7996_dfs_radar_spec etsi_radar_specs = {
- .pulse_th = { 110, -10, -80, 40, 5200, 128, 5200 },
- .radar_pattern = {
-@@ -111,9 +107,9 @@ static void mt7996_mac_sta_poll(struct mt7996_dev *dev)
- LIST_HEAD(sta_poll_list);
- int i;
-
-- spin_lock_bh(&dev->sta_poll_lock);
-- list_splice_init(&dev->sta_poll_list, &sta_poll_list);
-- spin_unlock_bh(&dev->sta_poll_lock);
-+ spin_lock_bh(&dev->mt76.sta_poll_lock);
-+ list_splice_init(&dev->mt76.sta_poll_list, &sta_poll_list);
-+ spin_unlock_bh(&dev->mt76.sta_poll_lock);
-
- rcu_read_lock();
-
-@@ -124,15 +120,15 @@ static void mt7996_mac_sta_poll(struct mt7996_dev *dev)
- s8 rssi[4];
- u8 bw;
-
-- spin_lock_bh(&dev->sta_poll_lock);
-+ spin_lock_bh(&dev->mt76.sta_poll_lock);
- if (list_empty(&sta_poll_list)) {
-- spin_unlock_bh(&dev->sta_poll_lock);
-+ spin_unlock_bh(&dev->mt76.sta_poll_lock);
- break;
- }
- msta = list_first_entry(&sta_poll_list,
-- struct mt7996_sta, poll_list);
-- list_del_init(&msta->poll_list);
-- spin_unlock_bh(&dev->sta_poll_lock);
-+ struct mt7996_sta, wcid.poll_list);
-+ list_del_init(&msta->wcid.poll_list);
-+ spin_unlock_bh(&dev->mt76.sta_poll_lock);
-
- idx = msta->wcid.idx;
-
-@@ -263,180 +259,6 @@ void mt7996_mac_set_fixed_rate_table(struct mt7996_dev *dev,
- mt76_wr(dev, MT_WTBL_ITCR, ctrl);
- }
-
--static void
--mt7996_mac_decode_he_radiotap_ru(struct mt76_rx_status *status,
-- struct ieee80211_radiotap_he *he,
-- __le32 *rxv)
--{
-- u32 ru, offs = 0;
--
-- ru = le32_get_bits(rxv[0], MT_PRXV_HE_RU_ALLOC);
--
-- status->bw = RATE_INFO_BW_HE_RU;
--
-- switch (ru) {
-- case 0 ... 36:
-- status->he_ru = NL80211_RATE_INFO_HE_RU_ALLOC_26;
-- offs = ru;
-- break;
-- case 37 ... 52:
-- status->he_ru = NL80211_RATE_INFO_HE_RU_ALLOC_52;
-- offs = ru - 37;
-- break;
-- case 53 ... 60:
-- status->he_ru = NL80211_RATE_INFO_HE_RU_ALLOC_106;
-- offs = ru - 53;
-- break;
-- case 61 ... 64:
-- status->he_ru = NL80211_RATE_INFO_HE_RU_ALLOC_242;
-- offs = ru - 61;
-- break;
-- case 65 ... 66:
-- status->he_ru = NL80211_RATE_INFO_HE_RU_ALLOC_484;
-- offs = ru - 65;
-- break;
-- case 67:
-- status->he_ru = NL80211_RATE_INFO_HE_RU_ALLOC_996;
-- break;
-- case 68:
-- status->he_ru = NL80211_RATE_INFO_HE_RU_ALLOC_2x996;
-- break;
-- }
--
-- he->data1 |= HE_BITS(DATA1_BW_RU_ALLOC_KNOWN);
-- he->data2 |= HE_BITS(DATA2_RU_OFFSET_KNOWN) |
-- le16_encode_bits(offs,
-- IEEE80211_RADIOTAP_HE_DATA2_RU_OFFSET);
--}
--
--static void
--mt7996_mac_decode_he_mu_radiotap(struct sk_buff *skb, __le32 *rxv)
--{
-- struct mt76_rx_status *status = (struct mt76_rx_status *)skb->cb;
-- static const struct ieee80211_radiotap_he_mu mu_known = {
-- .flags1 = HE_BITS(MU_FLAGS1_SIG_B_MCS_KNOWN) |
-- HE_BITS(MU_FLAGS1_SIG_B_DCM_KNOWN) |
-- HE_BITS(MU_FLAGS1_CH1_RU_KNOWN) |
-- HE_BITS(MU_FLAGS1_SIG_B_SYMS_USERS_KNOWN),
-- .flags2 = HE_BITS(MU_FLAGS2_BW_FROM_SIG_A_BW_KNOWN),
-- };
-- struct ieee80211_radiotap_he_mu *he_mu = NULL;
--
-- status->flag |= RX_FLAG_RADIOTAP_HE_MU;
--
-- he_mu = skb_push(skb, sizeof(mu_known));
-- memcpy(he_mu, &mu_known, sizeof(mu_known));
--
--#define MU_PREP(f, v) le16_encode_bits(v, IEEE80211_RADIOTAP_HE_MU_##f)
--
-- he_mu->flags1 |= MU_PREP(FLAGS1_SIG_B_MCS, status->rate_idx);
-- if (status->he_dcm)
-- he_mu->flags1 |= MU_PREP(FLAGS1_SIG_B_DCM, status->he_dcm);
--
-- he_mu->flags2 |= MU_PREP(FLAGS2_BW_FROM_SIG_A_BW, status->bw) |
-- MU_PREP(FLAGS2_SIG_B_SYMS_USERS,
-- le32_get_bits(rxv[4], MT_CRXV_HE_NUM_USER));
--
-- he_mu->ru_ch1[0] = le32_get_bits(rxv[16], MT_CRXV_HE_RU0) & 0xff;
--
-- if (status->bw >= RATE_INFO_BW_40) {
-- he_mu->flags1 |= HE_BITS(MU_FLAGS1_CH2_RU_KNOWN);
-- he_mu->ru_ch2[0] = le32_get_bits(rxv[16], MT_CRXV_HE_RU1) & 0xff;
-- }
--
-- if (status->bw >= RATE_INFO_BW_80) {
-- u32 ru_h, ru_l;
--
-- he_mu->ru_ch1[1] = le32_get_bits(rxv[16], MT_CRXV_HE_RU2) & 0xff;
--
-- ru_l = le32_get_bits(rxv[16], MT_CRXV_HE_RU3_L);
-- ru_h = le32_get_bits(rxv[17], MT_CRXV_HE_RU3_H) & 0x7;
-- he_mu->ru_ch2[1] = (u8)(ru_l | ru_h << 4);
-- }
--}
--
--static void
--mt7996_mac_decode_he_radiotap(struct sk_buff *skb, __le32 *rxv, u8 mode)
--{
-- struct mt76_rx_status *status = (struct mt76_rx_status *)skb->cb;
-- static const struct ieee80211_radiotap_he known = {
-- .data1 = HE_BITS(DATA1_DATA_MCS_KNOWN) |
-- HE_BITS(DATA1_DATA_DCM_KNOWN) |
-- HE_BITS(DATA1_STBC_KNOWN) |
-- HE_BITS(DATA1_CODING_KNOWN) |
-- HE_BITS(DATA1_LDPC_XSYMSEG_KNOWN) |
-- HE_BITS(DATA1_DOPPLER_KNOWN) |
-- HE_BITS(DATA1_SPTL_REUSE_KNOWN) |
-- HE_BITS(DATA1_BSS_COLOR_KNOWN),
-- .data2 = HE_BITS(DATA2_GI_KNOWN) |
-- HE_BITS(DATA2_TXBF_KNOWN) |
-- HE_BITS(DATA2_PE_DISAMBIG_KNOWN) |
-- HE_BITS(DATA2_TXOP_KNOWN),
-- };
-- struct ieee80211_radiotap_he *he = NULL;
-- u32 ltf_size = le32_get_bits(rxv[4], MT_CRXV_HE_LTF_SIZE) + 1;
--
-- status->flag |= RX_FLAG_RADIOTAP_HE;
--
-- he = skb_push(skb, sizeof(known));
-- memcpy(he, &known, sizeof(known));
--
-- he->data3 = HE_PREP(DATA3_BSS_COLOR, BSS_COLOR, rxv[9]) |
-- HE_PREP(DATA3_LDPC_XSYMSEG, LDPC_EXT_SYM, rxv[4]);
-- he->data4 = HE_PREP(DATA4_SU_MU_SPTL_REUSE, SR_MASK, rxv[13]);
-- he->data5 = HE_PREP(DATA5_PE_DISAMBIG, PE_DISAMBIG, rxv[5]) |
-- le16_encode_bits(ltf_size,
-- IEEE80211_RADIOTAP_HE_DATA5_LTF_SIZE);
-- if (le32_to_cpu(rxv[0]) & MT_PRXV_TXBF)
-- he->data5 |= HE_BITS(DATA5_TXBF);
-- he->data6 = HE_PREP(DATA6_TXOP, TXOP_DUR, rxv[9]) |
-- HE_PREP(DATA6_DOPPLER, DOPPLER, rxv[9]);
--
-- switch (mode) {
-- case MT_PHY_TYPE_HE_SU:
-- he->data1 |= HE_BITS(DATA1_FORMAT_SU) |
-- HE_BITS(DATA1_UL_DL_KNOWN) |
-- HE_BITS(DATA1_BEAM_CHANGE_KNOWN) |
-- HE_BITS(DATA1_BW_RU_ALLOC_KNOWN);
--
-- he->data3 |= HE_PREP(DATA3_BEAM_CHANGE, BEAM_CHNG, rxv[8]) |
-- HE_PREP(DATA3_UL_DL, UPLINK, rxv[5]);
-- break;
-- case MT_PHY_TYPE_HE_EXT_SU:
-- he->data1 |= HE_BITS(DATA1_FORMAT_EXT_SU) |
-- HE_BITS(DATA1_UL_DL_KNOWN) |
-- HE_BITS(DATA1_BW_RU_ALLOC_KNOWN);
--
-- he->data3 |= HE_PREP(DATA3_UL_DL, UPLINK, rxv[5]);
-- break;
-- case MT_PHY_TYPE_HE_MU:
-- he->data1 |= HE_BITS(DATA1_FORMAT_MU) |
-- HE_BITS(DATA1_UL_DL_KNOWN);
--
-- he->data3 |= HE_PREP(DATA3_UL_DL, UPLINK, rxv[5]);
-- he->data4 |= HE_PREP(DATA4_MU_STA_ID, MU_AID, rxv[8]);
--
-- mt7996_mac_decode_he_radiotap_ru(status, he, rxv);
-- mt7996_mac_decode_he_mu_radiotap(skb, rxv);
-- break;
-- case MT_PHY_TYPE_HE_TB:
-- he->data1 |= HE_BITS(DATA1_FORMAT_TRIG) |
-- HE_BITS(DATA1_SPTL_REUSE2_KNOWN) |
-- HE_BITS(DATA1_SPTL_REUSE3_KNOWN) |
-- HE_BITS(DATA1_SPTL_REUSE4_KNOWN);
--
-- he->data4 |= HE_PREP(DATA4_TB_SPTL_REUSE1, SR_MASK, rxv[13]) |
-- HE_PREP(DATA4_TB_SPTL_REUSE2, SR1_MASK, rxv[13]) |
-- HE_PREP(DATA4_TB_SPTL_REUSE3, SR2_MASK, rxv[13]) |
-- HE_PREP(DATA4_TB_SPTL_REUSE4, SR3_MASK, rxv[13]);
--
-- mt7996_mac_decode_he_radiotap_ru(status, he, rxv);
-- break;
-- default:
-- break;
-- }
--}
--
- /* The HW does not translate the mac header to 802.3 for mesh point */
- static int mt7996_reverse_frag0_hdr_trans(struct sk_buff *skb, u16 hdr_gap)
- {
-@@ -680,10 +502,11 @@ mt7996_mac_fill_rx(struct mt7996_dev *dev, struct sk_buff *skb)
- struct mt7996_sta *msta;
-
- msta = container_of(status->wcid, struct mt7996_sta, wcid);
-- spin_lock_bh(&dev->sta_poll_lock);
-- if (list_empty(&msta->poll_list))
-- list_add_tail(&msta->poll_list, &dev->sta_poll_list);
-- spin_unlock_bh(&dev->sta_poll_lock);
-+ spin_lock_bh(&dev->mt76.sta_poll_lock);
-+ if (list_empty(&msta->wcid.poll_list))
-+ list_add_tail(&msta->wcid.poll_list,
-+ &dev->mt76.sta_poll_list);
-+ spin_unlock_bh(&dev->mt76.sta_poll_lock);
- }
-
- status->freq = mphy->chandef.chan->center_freq;
-@@ -835,14 +658,19 @@ mt7996_mac_fill_rx(struct mt7996_dev *dev, struct sk_buff *skb)
- skb_pull(skb, hdr_gap);
- if (!hdr_trans && status->amsdu && !(ieee80211_has_a4(fc) && is_mesh)) {
- pad_start = ieee80211_get_hdrlen_from_skb(skb);
-- } else if (hdr_trans && (rxd2 & MT_RXD2_NORMAL_HDR_TRANS_ERROR) &&
-- get_unaligned_be16(skb->data + pad_start) == ETH_P_8021Q) {
-+ } else if (hdr_trans && (rxd2 & MT_RXD2_NORMAL_HDR_TRANS_ERROR)) {
- /* When header translation failure is indicated,
- * the hardware will insert an extra 2-byte field
- * containing the data length after the protocol
-- * type field.
-+ * type field. This happens either when the LLC-SNAP
-+ * pattern did not match, or if a VLAN header was
-+ * detected.
- */
-- pad_start = 16;
-+ pad_start = 12;
-+ if (get_unaligned_be16(skb->data + pad_start) == ETH_P_8021Q)
-+ pad_start += 4;
-+ else
-+ pad_start = 0;
- }
-
- if (pad_start) {
-@@ -880,7 +708,7 @@ mt7996_mac_fill_rx(struct mt7996_dev *dev, struct sk_buff *skb)
- }
-
- if (rxv && mode >= MT_PHY_TYPE_HE_SU && !(status->flag & RX_FLAG_8023))
-- mt7996_mac_decode_he_radiotap(skb, rxv, mode);
-+ mt76_connac3_mac_decode_he_radiotap(skb, rxv, mode);
-
- if (!status->wcid || !ieee80211_is_data_qos(fc))
- return 0;
-@@ -1003,7 +831,7 @@ void mt7996_mac_write_txwi(struct mt7996_dev *dev, __le32 *txwi,
- {
- struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
- struct ieee80211_vif *vif = info->control.vif;
-- struct mt7996_vif *mvif = (struct mt7996_vif *)vif->drv_priv;
-+ struct mt76_vif *mvif;
- struct mt76_phy *mphy = &dev->mphy;
- u8 band_idx = (info->hw_queue & MT_TX_HW_QUEUE_PHY) >> 2;
- u8 p_fmt, q_idx, omac_idx = 0, wmm_idx = 0;
-@@ -1015,10 +843,11 @@ void mt7996_mac_write_txwi(struct mt7996_dev *dev, __le32 *txwi,
- bool inband_disc = !!(changed & (BSS_CHANGED_UNSOL_BCAST_PROBE_RESP |
- BSS_CHANGED_FILS_DISCOVERY));
-
-- if (vif) {
-- omac_idx = mvif->mt76.omac_idx;
-- wmm_idx = mvif->mt76.wmm_idx;
-- band_idx = mvif->mt76.band_idx;
-+ mvif = vif ? (struct mt76_vif *)vif->drv_priv : NULL;
-+ if (mvif) {
-+ omac_idx = mvif->omac_idx;
-+ wmm_idx = mvif->wmm_idx;
-+ band_idx = mvif->band_idx;
- }
-
- mphy = mt76_dev_phy(&dev->mt76, band_idx);
-@@ -1083,14 +912,18 @@ void mt7996_mac_write_txwi(struct mt7996_dev *dev, __le32 *txwi,
- struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
- bool mcast = ieee80211_is_data(hdr->frame_control) &&
- is_multicast_ether_addr(hdr->addr1);
-- u8 idx = mvif->basic_rates_idx;
-+ u8 idx = MT7996_BASIC_RATES_TBL;
-
-- if (mcast && mvif->mcast_rates_idx)
-- idx = mvif->mcast_rates_idx;
-- else if (beacon && mvif->beacon_rates_idx)
-- idx = mvif->beacon_rates_idx;
-+ if (mvif) {
-+ if (mcast && mvif->mcast_rates_idx)
-+ idx = mvif->mcast_rates_idx;
-+ else if (beacon && mvif->beacon_rates_idx)
-+ idx = mvif->beacon_rates_idx;
-+ else
-+ idx = mvif->basic_rates_idx;
-+ }
-
-- txwi[6] |= FIELD_PREP(MT_TXD6_TX_RATE, idx);
-+ txwi[6] |= cpu_to_le32(FIELD_PREP(MT_TXD6_TX_RATE, idx));
- txwi[3] |= cpu_to_le32(MT_TXD3_BA_DISABLE);
- }
- }
-@@ -1200,7 +1033,7 @@ mt7996_tx_check_aggr(struct ieee80211_sta *sta, __le32 *txwi)
- return;
-
- msta = (struct mt7996_sta *)sta->drv_priv;
-- if (!test_and_set_bit(tid, &msta->ampdu_state))
-+ if (!test_and_set_bit(tid, &msta->wcid.ampdu_state))
- ieee80211_start_tx_ba_session(sta, tid, 0);
- }
-
-@@ -1288,10 +1121,11 @@ mt7996_mac_tx_free(struct mt7996_dev *dev, void *data, int len)
- continue;
-
- msta = container_of(wcid, struct mt7996_sta, wcid);
-- spin_lock_bh(&dev->sta_poll_lock);
-- if (list_empty(&msta->poll_list))
-- list_add_tail(&msta->poll_list, &dev->sta_poll_list);
-- spin_unlock_bh(&dev->sta_poll_lock);
-+ spin_lock_bh(&mdev->sta_poll_lock);
-+ if (list_empty(&msta->wcid.poll_list))
-+ list_add_tail(&msta->wcid.poll_list,
-+ &mdev->sta_poll_list);
-+ spin_unlock_bh(&mdev->sta_poll_lock);
- continue;
- }
-
-@@ -1326,9 +1160,10 @@ mt7996_mac_tx_free(struct mt7996_dev *dev, void *data, int len)
- }
-
- static bool
--mt7996_mac_add_txs_skb(struct mt7996_dev *dev, struct mt76_wcid *wcid, int pid,
-- __le32 *txs_data, struct mt76_sta_stats *stats)
-+mt7996_mac_add_txs_skb(struct mt7996_dev *dev, struct mt76_wcid *wcid,
-+ int pid, __le32 *txs_data)
- {
-+ struct mt76_sta_stats *stats = &wcid->stats;
- struct ieee80211_supported_band *sband;
- struct mt76_dev *mdev = &dev->mt76;
- struct mt76_phy *mphy;
-@@ -1490,15 +1325,15 @@ static void mt7996_mac_add_txs(struct mt7996_dev *dev, void *data)
-
- msta = container_of(wcid, struct mt7996_sta, wcid);
-
-- mt7996_mac_add_txs_skb(dev, wcid, pid, txs_data, &msta->stats);
-+ mt7996_mac_add_txs_skb(dev, wcid, pid, txs_data);
-
- if (!wcid->sta)
- goto out;
-
-- spin_lock_bh(&dev->sta_poll_lock);
-- if (list_empty(&msta->poll_list))
-- list_add_tail(&msta->poll_list, &dev->sta_poll_list);
-- spin_unlock_bh(&dev->sta_poll_lock);
-+ spin_lock_bh(&dev->mt76.sta_poll_lock);
-+ if (list_empty(&msta->wcid.poll_list))
-+ list_add_tail(&msta->wcid.poll_list, &dev->mt76.sta_poll_list);
-+ spin_unlock_bh(&dev->mt76.sta_poll_lock);
-
- out:
- rcu_read_unlock();
-@@ -1611,20 +1446,19 @@ void mt7996_mac_reset_counters(struct mt7996_phy *phy)
- mt7996_mcu_get_chan_mib_info(phy, true);
- }
-
--void mt7996_mac_set_timing(struct mt7996_phy *phy)
-+void mt7996_mac_set_coverage_class(struct mt7996_phy *phy)
- {
- s16 coverage_class = phy->coverage_class;
- struct mt7996_dev *dev = phy->dev;
- struct mt7996_phy *phy2 = mt7996_phy2(dev);
- struct mt7996_phy *phy3 = mt7996_phy3(dev);
-- u32 val, reg_offset;
-+ u32 reg_offset;
- u32 cck = FIELD_PREP(MT_TIMEOUT_VAL_PLCP, 231) |
- FIELD_PREP(MT_TIMEOUT_VAL_CCA, 48);
- u32 ofdm = FIELD_PREP(MT_TIMEOUT_VAL_PLCP, 60) |
- FIELD_PREP(MT_TIMEOUT_VAL_CCA, 28);
- u8 band_idx = phy->mt76->band_idx;
- int offset;
-- bool a_band = !(phy->mt76->chandef.chan->band == NL80211_BAND_2GHZ);
-
- if (!test_bit(MT76_STATE_RUNNING, &phy->mt76->state))
- return;
-@@ -1637,34 +1471,12 @@ void mt7996_mac_set_timing(struct mt7996_phy *phy)
- coverage_class = max_t(s16, coverage_class,
- phy3->coverage_class);
-
-- mt76_set(dev, MT_ARB_SCR(band_idx),
-- MT_ARB_SCR_TX_DISABLE | MT_ARB_SCR_RX_DISABLE);
-- udelay(1);
--
- offset = 3 * coverage_class;
- reg_offset = FIELD_PREP(MT_TIMEOUT_VAL_PLCP, offset) |
- FIELD_PREP(MT_TIMEOUT_VAL_CCA, offset);
-
- mt76_wr(dev, MT_TMAC_CDTR(band_idx), cck + reg_offset);
- mt76_wr(dev, MT_TMAC_ODTR(band_idx), ofdm + reg_offset);
-- mt76_wr(dev, MT_TMAC_ICR0(band_idx),
-- FIELD_PREP(MT_IFS_EIFS_OFDM, a_band ? 84 : 78) |
-- FIELD_PREP(MT_IFS_RIFS, 2) |
-- FIELD_PREP(MT_IFS_SIFS, 10) |
-- FIELD_PREP(MT_IFS_SLOT, phy->slottime));
--
-- if (!a_band)
-- mt76_wr(dev, MT_TMAC_ICR1(band_idx),
-- FIELD_PREP(MT_IFS_EIFS_CCK, 314));
--
-- if (phy->slottime < 20 || a_band)
-- val = MT7996_CFEND_RATE_DEFAULT;
-- else
-- val = MT7996_CFEND_RATE_11B;
--
-- mt76_rmw_field(dev, MT_RATE_HRCR0(band_idx), MT_RATE_HRCR0_CFEND_RATE, val);
-- mt76_clear(dev, MT_ARB_SCR(band_idx),
-- MT_ARB_SCR_TX_DISABLE | MT_ARB_SCR_RX_DISABLE);
- }
-
- void mt7996_mac_enable_nf(struct mt7996_dev *dev, u8 band)
-@@ -2048,6 +1860,12 @@ void mt7996_mac_reset_work(struct work_struct *work)
- mt7996_wait_reset_state(dev, MT_MCU_CMD_RECOVERY_DONE);
- }
-
-+ mt76_wr(dev, MT_MCU_INT_EVENT, MT_MCU_INT_EVENT_RESET_DONE);
-+ mt7996_wait_reset_state(dev, MT_MCU_CMD_NORMAL_STATE);
-+
-+ /* enable DMA Tx/Tx and interrupt */
-+ mt7996_dma_start(dev, false);
-+
- clear_bit(MT76_MCU_RESET, &dev->mphy.state);
- clear_bit(MT76_RESET, &dev->mphy.state);
- if (phy2)
-@@ -2064,9 +1882,6 @@ void mt7996_mac_reset_work(struct work_struct *work)
-
- tasklet_schedule(&dev->mt76.irq_tasklet);
-
-- mt76_wr(dev, MT_MCU_INT_EVENT, MT_MCU_INT_EVENT_RESET_DONE);
-- mt7996_wait_reset_state(dev, MT_MCU_CMD_NORMAL_STATE);
--
- mt76_worker_enable(&dev->mt76.tx_worker);
-
- local_bh_disable();
-@@ -2193,8 +2008,8 @@ void mt7996_reset(struct mt7996_dev *dev)
-
- void mt7996_mac_update_stats(struct mt7996_phy *phy)
- {
-+ struct mt76_mib_stats *mib = &phy->mib;
- struct mt7996_dev *dev = phy->dev;
-- struct mib_stats *mib = &phy->mib;
- u8 band_idx = phy->mt76->band_idx;
- u32 cnt;
- int i;
-@@ -2341,7 +2156,7 @@ void mt7996_mac_sta_rc_work(struct work_struct *work)
- u32 changed;
- LIST_HEAD(list);
-
-- spin_lock_bh(&dev->sta_poll_lock);
-+ spin_lock_bh(&dev->mt76.sta_poll_lock);
- list_splice_init(&dev->sta_rc_list, &list);
-
- while (!list_empty(&list)) {
-@@ -2349,7 +2164,7 @@ void mt7996_mac_sta_rc_work(struct work_struct *work)
- list_del_init(&msta->rc_list);
- changed = msta->changed;
- msta->changed = 0;
-- spin_unlock_bh(&dev->sta_poll_lock);
-+ spin_unlock_bh(&dev->mt76.sta_poll_lock);
-
- sta = container_of((void *)msta, struct ieee80211_sta, drv_priv);
- vif = container_of((void *)msta->vif, struct ieee80211_vif, drv_priv);
-@@ -2361,10 +2176,10 @@ void mt7996_mac_sta_rc_work(struct work_struct *work)
-
- /* TODO: smps change */
-
-- spin_lock_bh(&dev->sta_poll_lock);
-+ spin_lock_bh(&dev->mt76.sta_poll_lock);
- }
-
-- spin_unlock_bh(&dev->sta_poll_lock);
-+ spin_unlock_bh(&dev->mt76.sta_poll_lock);
- }
-
- void mt7996_mac_work(struct work_struct *work)
-diff --git a/mt7996/mac.h b/mt7996/mac.h
-index bc4e6c55..e629324a 100644
---- a/mt7996/mac.h
-+++ b/mt7996/mac.h
-@@ -6,320 +6,7 @@
- #ifndef __MT7996_MAC_H
- #define __MT7996_MAC_H
-
--#define MT_CT_PARSE_LEN 72
--#define MT_CT_DMA_BUF_NUM 2
--
--#define MT_RXD0_LENGTH GENMASK(15, 0)
--#define MT_RXD0_PKT_TYPE GENMASK(31, 27)
--
--#define MT_RXD0_MESH BIT(18)
--#define MT_RXD0_MHCP BIT(19)
--#define MT_RXD0_NORMAL_ETH_TYPE_OFS GENMASK(22, 16)
--#define MT_RXD0_NORMAL_IP_SUM BIT(23)
--#define MT_RXD0_NORMAL_UDP_TCP_SUM BIT(24)
--
--#define MT_RXD0_SW_PKT_TYPE_MASK GENMASK(31, 16)
--#define MT_RXD0_SW_PKT_TYPE_MAP 0x380F
--#define MT_RXD0_SW_PKT_TYPE_FRAME 0x3801
--
--/* RXD DW1 */
--#define MT_RXD1_NORMAL_WLAN_IDX GENMASK(11, 0)
--#define MT_RXD1_NORMAL_GROUP_1 BIT(16)
--#define MT_RXD1_NORMAL_GROUP_2 BIT(17)
--#define MT_RXD1_NORMAL_GROUP_3 BIT(18)
--#define MT_RXD1_NORMAL_GROUP_4 BIT(19)
--#define MT_RXD1_NORMAL_GROUP_5 BIT(20)
--#define MT_RXD1_NORMAL_KEY_ID GENMASK(22, 21)
--#define MT_RXD1_NORMAL_CM BIT(23)
--#define MT_RXD1_NORMAL_CLM BIT(24)
--#define MT_RXD1_NORMAL_ICV_ERR BIT(25)
--#define MT_RXD1_NORMAL_TKIP_MIC_ERR BIT(26)
--#define MT_RXD1_NORMAL_BAND_IDX GENMASK(28, 27)
--#define MT_RXD1_NORMAL_SPP_EN BIT(29)
--#define MT_RXD1_NORMAL_ADD_OM BIT(30)
--#define MT_RXD1_NORMAL_SEC_DONE BIT(31)
--
--/* RXD DW2 */
--#define MT_RXD2_NORMAL_BSSID GENMASK(5, 0)
--#define MT_RXD2_NORMAL_MAC_HDR_LEN GENMASK(12, 8)
--#define MT_RXD2_NORMAL_HDR_TRANS BIT(7)
--#define MT_RXD2_NORMAL_HDR_OFFSET GENMASK(15, 13)
--#define MT_RXD2_NORMAL_SEC_MODE GENMASK(20, 16)
--#define MT_RXD2_NORMAL_MU_BAR BIT(21)
--#define MT_RXD2_NORMAL_SW_BIT BIT(22)
--#define MT_RXD2_NORMAL_AMSDU_ERR BIT(23)
--#define MT_RXD2_NORMAL_MAX_LEN_ERROR BIT(24)
--#define MT_RXD2_NORMAL_HDR_TRANS_ERROR BIT(25)
--#define MT_RXD2_NORMAL_INT_FRAME BIT(26)
--#define MT_RXD2_NORMAL_FRAG BIT(27)
--#define MT_RXD2_NORMAL_NULL_FRAME BIT(28)
--#define MT_RXD2_NORMAL_NDATA BIT(29)
--#define MT_RXD2_NORMAL_NON_AMPDU BIT(30)
--#define MT_RXD2_NORMAL_BF_REPORT BIT(31)
--
--/* RXD DW3 */
--#define MT_RXD3_NORMAL_RXV_SEQ GENMASK(7, 0)
--#define MT_RXD3_NORMAL_CH_FREQ GENMASK(15, 8)
--#define MT_RXD3_NORMAL_ADDR_TYPE GENMASK(17, 16)
--#define MT_RXD3_NORMAL_U2M BIT(0)
--#define MT_RXD3_NORMAL_HTC_VLD BIT(18)
--#define MT_RXD3_NORMAL_BEACON_MC BIT(20)
--#define MT_RXD3_NORMAL_BEACON_UC BIT(21)
--#define MT_RXD3_NORMAL_CO_ANT BIT(22)
--#define MT_RXD3_NORMAL_FCS_ERR BIT(24)
--#define MT_RXD3_NORMAL_VLAN2ETH BIT(31)
--
--/* RXD DW4 */
--#define MT_RXD4_NORMAL_PAYLOAD_FORMAT GENMASK(1, 0)
--#define MT_RXD4_FIRST_AMSDU_FRAME GENMASK(1, 0)
--#define MT_RXD4_MID_AMSDU_FRAME BIT(1)
--#define MT_RXD4_LAST_AMSDU_FRAME BIT(0)
--
--#define MT_RXV_HDR_BAND_IDX BIT(24)
--
--/* RXD GROUP4 */
--#define MT_RXD8_FRAME_CONTROL GENMASK(15, 0)
--
--#define MT_RXD10_SEQ_CTRL GENMASK(15, 0)
--#define MT_RXD10_QOS_CTL GENMASK(31, 16)
--
--#define MT_RXD11_HT_CONTROL GENMASK(31, 0)
--
--/* P-RXV */
--#define MT_PRXV_TX_RATE GENMASK(6, 0)
--#define MT_PRXV_TX_DCM BIT(4)
--#define MT_PRXV_TX_ER_SU_106T BIT(5)
--#define MT_PRXV_NSTS GENMASK(10, 7)
--#define MT_PRXV_TXBF BIT(11)
--#define MT_PRXV_HT_AD_CODE BIT(12)
--#define MT_PRXV_HE_RU_ALLOC GENMASK(30, 22)
--#define MT_PRXV_RCPI3 GENMASK(31, 24)
--#define MT_PRXV_RCPI2 GENMASK(23, 16)
--#define MT_PRXV_RCPI1 GENMASK(15, 8)
--#define MT_PRXV_RCPI0 GENMASK(7, 0)
--#define MT_PRXV_HT_SHORT_GI GENMASK(4, 3)
--#define MT_PRXV_HT_STBC GENMASK(10, 9)
--#define MT_PRXV_TX_MODE GENMASK(14, 11)
--#define MT_PRXV_FRAME_MODE GENMASK(2, 0)
--#define MT_PRXV_DCM BIT(5)
--
--/* C-RXV */
--#define MT_CRXV_HE_NUM_USER GENMASK(26, 20)
--#define MT_CRXV_HE_LTF_SIZE GENMASK(28, 27)
--#define MT_CRXV_HE_LDPC_EXT_SYM BIT(30)
--
--#define MT_CRXV_HE_PE_DISAMBIG BIT(1)
--#define MT_CRXV_HE_UPLINK BIT(2)
--
--#define MT_CRXV_HE_MU_AID GENMASK(27, 17)
--#define MT_CRXV_HE_BEAM_CHNG BIT(29)
--
--#define MT_CRXV_HE_DOPPLER BIT(0)
--#define MT_CRXV_HE_BSS_COLOR GENMASK(15, 10)
--#define MT_CRXV_HE_TXOP_DUR GENMASK(19, 17)
--
--#define MT_CRXV_HE_SR_MASK GENMASK(11, 8)
--#define MT_CRXV_HE_SR1_MASK GENMASK(16, 12)
--#define MT_CRXV_HE_SR2_MASK GENMASK(20, 17)
--#define MT_CRXV_HE_SR3_MASK GENMASK(24, 21)
--
--#define MT_CRXV_HE_RU0 GENMASK(8, 0)
--#define MT_CRXV_HE_RU1 GENMASK(17, 9)
--#define MT_CRXV_HE_RU2 GENMASK(26, 18)
--#define MT_CRXV_HE_RU3_L GENMASK(31, 27)
--#define MT_CRXV_HE_RU3_H GENMASK(3, 0)
--
--enum tx_header_format {
-- MT_HDR_FORMAT_802_3,
-- MT_HDR_FORMAT_CMD,
-- MT_HDR_FORMAT_802_11,
-- MT_HDR_FORMAT_802_11_EXT,
--};
--
--enum tx_pkt_type {
-- MT_TX_TYPE_CT,
-- MT_TX_TYPE_SF,
-- MT_TX_TYPE_CMD,
-- MT_TX_TYPE_FW,
--};
--
--enum tx_port_idx {
-- MT_TX_PORT_IDX_LMAC,
-- MT_TX_PORT_IDX_MCU
--};
--
--enum tx_mcu_port_q_idx {
-- MT_TX_MCU_PORT_RX_Q0 = 0x20,
-- MT_TX_MCU_PORT_RX_Q1,
-- MT_TX_MCU_PORT_RX_Q2,
-- MT_TX_MCU_PORT_RX_Q3,
-- MT_TX_MCU_PORT_RX_FWDL = 0x3e
--};
--
--enum tx_mgnt_type {
-- MT_TX_NORMAL,
-- MT_TX_TIMING,
-- MT_TX_ADDBA,
--};
--
--#define MT_CT_INFO_APPLY_TXD BIT(0)
--#define MT_CT_INFO_COPY_HOST_TXD_ALL BIT(1)
--#define MT_CT_INFO_MGMT_FRAME BIT(2)
--#define MT_CT_INFO_NONE_CIPHER_FRAME BIT(3)
--#define MT_CT_INFO_HSR2_TX BIT(4)
--#define MT_CT_INFO_FROM_HOST BIT(7)
--
--#define MT_TXD_SIZE (8 * 4)
--
--#define MT_TXD0_Q_IDX GENMASK(31, 25)
--#define MT_TXD0_PKT_FMT GENMASK(24, 23)
--#define MT_TXD0_ETH_TYPE_OFFSET GENMASK(22, 16)
--#define MT_TXD0_TX_BYTES GENMASK(15, 0)
--
--#define MT_TXD1_FIXED_RATE BIT(31)
--#define MT_TXD1_OWN_MAC GENMASK(30, 25)
--#define MT_TXD1_TID GENMASK(24, 21)
--#define MT_TXD1_BIP BIT(24)
--#define MT_TXD1_ETH_802_3 BIT(20)
--#define MT_TXD1_HDR_INFO GENMASK(20, 16)
--#define MT_TXD1_HDR_FORMAT GENMASK(15, 14)
--#define MT_TXD1_TGID GENMASK(13, 12)
--#define MT_TXD1_WLAN_IDX GENMASK(11, 0)
--
--#define MT_TXD2_POWER_OFFSET GENMASK(31, 26)
--#define MT_TXD2_MAX_TX_TIME GENMASK(25, 16)
--#define MT_TXD2_FRAG GENMASK(15, 14)
--#define MT_TXD2_HTC_VLD BIT(13)
--#define MT_TXD2_DURATION BIT(12)
--#define MT_TXD2_HDR_PAD GENMASK(11, 10)
--#define MT_TXD2_RTS BIT(9)
--#define MT_TXD2_OWN_MAC_MAP BIT(8)
--#define MT_TXD2_BF_TYPE GENMASK(6, 7)
--#define MT_TXD2_FRAME_TYPE GENMASK(5, 4)
--#define MT_TXD2_SUB_TYPE GENMASK(3, 0)
--
--#define MT_TXD3_SN_VALID BIT(31)
--#define MT_TXD3_PN_VALID BIT(30)
--#define MT_TXD3_SW_POWER_MGMT BIT(29)
--#define MT_TXD3_BA_DISABLE BIT(28)
--#define MT_TXD3_SEQ GENMASK(27, 16)
--#define MT_TXD3_REM_TX_COUNT GENMASK(15, 11)
--#define MT_TXD3_TX_COUNT GENMASK(10, 6)
--#define MT_TXD3_HW_AMSDU BIT(5)
--#define MT_TXD3_BCM BIT(4)
--#define MT_TXD3_EEOSP BIT(3)
--#define MT_TXD3_EMRD BIT(2)
--#define MT_TXD3_PROTECT_FRAME BIT(1)
--#define MT_TXD3_NO_ACK BIT(0)
--
--#define MT_TXD4_PN_LOW GENMASK(31, 0)
--
--#define MT_TXD5_PN_HIGH GENMASK(31, 16)
--#define MT_TXD5_FL BIT(15)
--#define MT_TXD5_BYPASS_TBB BIT(14)
--#define MT_TXD5_BYPASS_RBB BIT(13)
--#define MT_TXD5_BSS_COLOR_ZERO BIT(12)
--#define MT_TXD5_TX_STATUS_HOST BIT(10)
--#define MT_TXD5_TX_STATUS_MCU BIT(9)
--#define MT_TXD5_TX_STATUS_FMT BIT(8)
--#define MT_TXD5_PID GENMASK(7, 0)
--
--#define MT_TXD6_TX_SRC GENMASK(31, 30)
--#define MT_TXD6_VTA BIT(28)
--#define MT_TXD6_BW GENMASK(25, 22)
--#define MT_TXD6_TX_RATE GENMASK(21, 16)
--#define MT_TXD6_TIMESTAMP_OFS_EN BIT(15)
--#define MT_TXD6_TIMESTAMP_OFS_IDX GENMASK(14, 10)
--#define MT_TXD6_MSDU_CNT GENMASK(9, 4)
--#define MT_TXD6_DIS_MAT BIT(3)
--#define MT_TXD6_DAS BIT(2)
--#define MT_TXD6_AMSDU_CAP BIT(1)
--
--#define MT_TXD7_TXD_LEN GENMASK(31, 30)
--#define MT_TXD7_IP_SUM BIT(29)
--#define MT_TXD7_DROP_BY_SDO BIT(28)
--#define MT_TXD7_MAC_TXD BIT(27)
--#define MT_TXD7_CTXD BIT(26)
--#define MT_TXD7_CTXD_CNT GENMASK(25, 22)
--#define MT_TXD7_UDP_TCP_SUM BIT(15)
--#define MT_TXD7_TX_TIME GENMASK(9, 0)
--
--#define MT_TX_RATE_STBC BIT(14)
--#define MT_TX_RATE_NSS GENMASK(13, 10)
--#define MT_TX_RATE_MODE GENMASK(9, 6)
--#define MT_TX_RATE_SU_EXT_TONE BIT(5)
--#define MT_TX_RATE_DCM BIT(4)
--/* VHT/HE only use bits 0-3 */
--#define MT_TX_RATE_IDX GENMASK(5, 0)
--
--#define MT_TXFREE0_PKT_TYPE GENMASK(31, 27)
--#define MT_TXFREE0_MSDU_CNT GENMASK(25, 16)
--#define MT_TXFREE0_RX_BYTE GENMASK(15, 0)
--
--#define MT_TXFREE1_VER GENMASK(18, 16)
--
--#define MT_TXFREE_INFO_PAIR BIT(31)
--#define MT_TXFREE_INFO_HEADER BIT(30)
--#define MT_TXFREE_INFO_WLAN_ID GENMASK(23, 12)
--#define MT_TXFREE_INFO_MSDU_ID GENMASK(14, 0)
--
--#define MT_TXS0_BW GENMASK(31, 29)
--#define MT_TXS0_TID GENMASK(28, 26)
--#define MT_TXS0_AMPDU BIT(25)
--#define MT_TXS0_TXS_FORMAT GENMASK(24, 23)
--#define MT_TXS0_BA_ERROR BIT(22)
--#define MT_TXS0_PS_FLAG BIT(21)
--#define MT_TXS0_TXOP_TIMEOUT BIT(20)
--#define MT_TXS0_BIP_ERROR BIT(19)
--
--#define MT_TXS0_QUEUE_TIMEOUT BIT(18)
--#define MT_TXS0_RTS_TIMEOUT BIT(17)
--#define MT_TXS0_ACK_TIMEOUT BIT(16)
--#define MT_TXS0_ACK_ERROR_MASK GENMASK(18, 16)
--
--#define MT_TXS0_TX_STATUS_HOST BIT(15)
--#define MT_TXS0_TX_STATUS_MCU BIT(14)
--#define MT_TXS0_TX_RATE GENMASK(13, 0)
--
--#define MT_TXS1_SEQNO GENMASK(31, 20)
--#define MT_TXS1_RESP_RATE GENMASK(19, 16)
--#define MT_TXS1_RXV_SEQNO GENMASK(15, 8)
--#define MT_TXS1_TX_POWER_DBM GENMASK(7, 0)
--
--#define MT_TXS2_BF_STATUS GENMASK(31, 30)
--#define MT_TXS2_BAND GENMASK(29, 28)
--#define MT_TXS2_WCID GENMASK(27, 16)
--#define MT_TXS2_TX_DELAY GENMASK(15, 0)
--
--#define MT_TXS3_PID GENMASK(31, 24)
--#define MT_TXS3_RATE_STBC BIT(7)
--#define MT_TXS3_FIXED_RATE BIT(6)
--#define MT_TXS3_SRC GENMASK(5, 4)
--#define MT_TXS3_SHARED_ANTENNA BIT(3)
--#define MT_TXS3_LAST_TX_RATE GENMASK(2, 0)
--
--#define MT_TXS4_TIMESTAMP GENMASK(31, 0)
--
--#define MT_TXS5_F0_FINAL_MPDU BIT(31)
--#define MT_TXS5_F0_QOS BIT(30)
--#define MT_TXS5_F0_TX_COUNT GENMASK(29, 25)
--#define MT_TXS5_F0_FRONT_TIME GENMASK(24, 0)
--#define MT_TXS5_F1_MPDU_TX_COUNT GENMASK(31, 24)
--#define MT_TXS5_F1_MPDU_TX_BYTES GENMASK(23, 0)
--
--#define MT_TXS6_F0_NOISE_3 GENMASK(31, 24)
--#define MT_TXS6_F0_NOISE_2 GENMASK(23, 16)
--#define MT_TXS6_F0_NOISE_1 GENMASK(15, 8)
--#define MT_TXS6_F0_NOISE_0 GENMASK(7, 0)
--#define MT_TXS6_F1_MPDU_FAIL_COUNT GENMASK(31, 24)
--#define MT_TXS6_F1_MPDU_FAIL_BYTES GENMASK(23, 0)
--
--#define MT_TXS7_F0_RCPI_3 GENMASK(31, 24)
--#define MT_TXS7_F0_RCPI_2 GENMASK(23, 16)
--#define MT_TXS7_F0_RCPI_1 GENMASK(15, 8)
--#define MT_TXS7_F0_RCPI_0 GENMASK(7, 0)
--#define MT_TXS7_F1_MPDU_RETRY_COUNT GENMASK(31, 24)
--#define MT_TXS7_F1_MPDU_RETRY_BYTES GENMASK(23, 0)
-+#include "../mt76_connac3_mac.h"
-
- struct mt7996_dfs_pulse {
- u32 max_width; /* us */
-diff --git a/mt7996/main.c b/mt7996/main.c
-index f306e9c5..c3a479dc 100644
---- a/mt7996/main.c
-+++ b/mt7996/main.c
-@@ -43,6 +43,10 @@ int mt7996_run(struct ieee80211_hw *hw)
- if (ret)
- goto out;
-
-+ ret = mt7996_mcu_set_radio_en(phy, true);
-+ if (ret)
-+ goto out;
-+
- ret = mt7996_mcu_set_chan_info(phy, UNI_CHANNEL_RX_PATH);
- if (ret)
- goto out;
-@@ -82,6 +86,8 @@ static void mt7996_stop(struct ieee80211_hw *hw)
-
- mutex_lock(&dev->mt76.mutex);
-
-+ mt7996_mcu_set_radio_en(phy, false);
-+
- clear_bit(MT76_STATE_RUNNING, &phy->mt76->state);
-
- mutex_unlock(&dev->mt76.mutex);
-@@ -190,17 +196,13 @@ static int mt7996_add_interface(struct ieee80211_hw *hw,
- if (ret)
- goto out;
-
-- ret = mt7996_mcu_set_radio_en(phy, true);
-- if (ret)
-- goto out;
--
- dev->mt76.vif_mask |= BIT_ULL(mvif->mt76.idx);
- phy->omac_mask |= BIT_ULL(mvif->mt76.omac_idx);
-
- idx = MT7996_WTBL_RESERVED - mvif->mt76.idx;
-
- INIT_LIST_HEAD(&mvif->sta.rc_list);
-- INIT_LIST_HEAD(&mvif->sta.poll_list);
-+ INIT_LIST_HEAD(&mvif->sta.wcid.poll_list);
- mvif->sta.wcid.idx = idx;
- mvif->sta.wcid.phy_idx = band_idx;
- mvif->sta.wcid.hw_key_idx = -1;
-@@ -221,9 +223,9 @@ static int mt7996_add_interface(struct ieee80211_hw *hw,
- vif->offload_flags |= IEEE80211_OFFLOAD_ENCAP_4ADDR;
-
- if (phy->mt76->chandef.chan->band != NL80211_BAND_2GHZ)
-- mvif->basic_rates_idx = MT7996_BASIC_RATES_TBL + 4;
-+ mvif->mt76.basic_rates_idx = MT7996_BASIC_RATES_TBL + 4;
- else
-- mvif->basic_rates_idx = MT7996_BASIC_RATES_TBL;
-+ mvif->mt76.basic_rates_idx = MT7996_BASIC_RATES_TBL;
-
- mt7996_init_bitrate_mask(vif);
-
-@@ -253,7 +255,6 @@ static void mt7996_remove_interface(struct ieee80211_hw *hw,
- phy->monitor_vif = NULL;
-
- mt7996_mcu_add_dev_info(phy, vif, false);
-- mt7996_mcu_set_radio_en(phy, false);
-
- rcu_assign_pointer(dev->mt76.wcid[idx], NULL);
-
-@@ -262,10 +263,10 @@ static void mt7996_remove_interface(struct ieee80211_hw *hw,
- phy->omac_mask &= ~BIT_ULL(mvif->mt76.omac_idx);
- mutex_unlock(&dev->mt76.mutex);
-
-- spin_lock_bh(&dev->sta_poll_lock);
-- if (!list_empty(&msta->poll_list))
-- list_del_init(&msta->poll_list);
-- spin_unlock_bh(&dev->sta_poll_lock);
-+ spin_lock_bh(&dev->mt76.sta_poll_lock);
-+ if (!list_empty(&msta->wcid.poll_list))
-+ list_del_init(&msta->wcid.poll_list);
-+ spin_unlock_bh(&dev->mt76.sta_poll_lock);
-
- mt76_packet_id_flush(&dev->mt76, &msta->wcid);
- }
-@@ -286,7 +287,6 @@ int mt7996_set_channel(struct mt7996_phy *phy)
- if (ret)
- goto out;
-
-- mt7996_mac_set_timing(phy);
- ret = mt7996_dfs_init_radar_detector(phy);
- mt7996_mac_cca_stats_reset(phy);
-
-@@ -505,7 +505,7 @@ static u8
- mt7996_get_rates_table(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
- bool beacon, bool mcast)
- {
-- struct mt7996_vif *mvif = (struct mt7996_vif *)vif->drv_priv;
-+ struct mt76_vif *mvif = (struct mt76_vif *)vif->drv_priv;
- struct mt76_phy *mphy = hw->priv;
- u16 rate;
- u8 i, idx, ht;
-@@ -517,7 +517,7 @@ mt7996_get_rates_table(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
- struct mt7996_dev *dev = mt7996_hw_dev(hw);
-
- /* must odd index */
-- idx = MT7996_BEACON_RATES_TBL + 2 * (mvif->mt76.idx % 20);
-+ idx = MT7996_BEACON_RATES_TBL + 2 * (mvif->idx % 20);
- mt7996_mac_set_fixed_rate_table(dev, idx, rate);
- return idx;
- }
-@@ -530,12 +530,32 @@ mt7996_get_rates_table(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
- return mvif->basic_rates_idx;
- }
-
-+static void
-+mt7996_update_mu_group(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
-+ struct ieee80211_bss_conf *info)
-+{
-+ struct mt7996_vif *mvif = (struct mt7996_vif *)vif->drv_priv;
-+ struct mt7996_dev *dev = mt7996_hw_dev(hw);
-+ u8 band = mvif->mt76.band_idx;
-+ u32 *mu;
-+
-+ mu = (u32 *)info->mu_group.membership;
-+ mt76_wr(dev, MT_WF_PHYRX_BAND_GID_TAB_VLD0(band), mu[0]);
-+ mt76_wr(dev, MT_WF_PHYRX_BAND_GID_TAB_VLD1(band), mu[1]);
-+
-+ mu = (u32 *)info->mu_group.position;
-+ mt76_wr(dev, MT_WF_PHYRX_BAND_GID_TAB_POS0(band), mu[0]);
-+ mt76_wr(dev, MT_WF_PHYRX_BAND_GID_TAB_POS1(band), mu[1]);
-+ mt76_wr(dev, MT_WF_PHYRX_BAND_GID_TAB_POS2(band), mu[2]);
-+ mt76_wr(dev, MT_WF_PHYRX_BAND_GID_TAB_POS3(band), mu[3]);
-+}
-+
- static void mt7996_bss_info_changed(struct ieee80211_hw *hw,
- struct ieee80211_vif *vif,
- struct ieee80211_bss_conf *info,
- u64 changed)
- {
-- struct mt7996_vif *mvif = (struct mt7996_vif *)vif->drv_priv;
-+ struct mt76_vif *mvif = (struct mt76_vif *)vif->drv_priv;
- struct mt7996_phy *phy = mt7996_hw_phy(hw);
- struct mt7996_dev *dev = mt7996_hw_dev(hw);
-
-@@ -563,7 +583,7 @@ static void mt7996_bss_info_changed(struct ieee80211_hw *hw,
-
- if (slottime != phy->slottime) {
- phy->slottime = slottime;
-- mt7996_mac_set_timing(phy);
-+ mt7996_mcu_set_timing(phy, vif);
- }
- }
-
-@@ -602,6 +622,9 @@ static void mt7996_bss_info_changed(struct ieee80211_hw *hw,
- changed & BSS_CHANGED_FILS_DISCOVERY)
- mt7996_mcu_beacon_inband_discov(dev, vif, changed);
-
-+ if (changed & BSS_CHANGED_MU_GROUPS)
-+ mt7996_update_mu_group(hw, vif, info);
-+
- mutex_unlock(&dev->mt76.mutex);
- }
-
-@@ -631,7 +654,7 @@ int mt7996_mac_sta_add(struct mt76_dev *mdev, struct ieee80211_vif *vif,
- return -ENOSPC;
-
- INIT_LIST_HEAD(&msta->rc_list);
-- INIT_LIST_HEAD(&msta->poll_list);
-+ INIT_LIST_HEAD(&msta->wcid.poll_list);
- msta->vif = mvif;
- msta->wcid.sta = 1;
- msta->wcid.idx = idx;
-@@ -666,12 +689,12 @@ void mt7996_mac_sta_remove(struct mt76_dev *mdev, struct ieee80211_vif *vif,
- for (i = 0; i < ARRAY_SIZE(msta->twt.flow); i++)
- mt7996_mac_twt_teardown_flow(dev, msta, i);
-
-- spin_lock_bh(&dev->sta_poll_lock);
-- if (!list_empty(&msta->poll_list))
-- list_del_init(&msta->poll_list);
-+ spin_lock_bh(&mdev->sta_poll_lock);
-+ if (!list_empty(&msta->wcid.poll_list))
-+ list_del_init(&msta->wcid.poll_list);
- if (!list_empty(&msta->rc_list))
- list_del_init(&msta->rc_list);
-- spin_unlock_bh(&dev->sta_poll_lock);
-+ spin_unlock_bh(&mdev->sta_poll_lock);
- }
-
- static void mt7996_tx(struct ieee80211_hw *hw,
-@@ -751,16 +774,16 @@ mt7996_ampdu_action(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
- case IEEE80211_AMPDU_TX_STOP_FLUSH:
- case IEEE80211_AMPDU_TX_STOP_FLUSH_CONT:
- mtxq->aggr = false;
-- clear_bit(tid, &msta->ampdu_state);
-+ clear_bit(tid, &msta->wcid.ampdu_state);
- ret = mt7996_mcu_add_tx_ba(dev, params, false);
- break;
- case IEEE80211_AMPDU_TX_START:
-- set_bit(tid, &msta->ampdu_state);
-+ set_bit(tid, &msta->wcid.ampdu_state);
- ret = IEEE80211_AMPDU_TX_START_IMMEDIATE;
- break;
- case IEEE80211_AMPDU_TX_STOP_CONT:
- mtxq->aggr = false;
-- clear_bit(tid, &msta->ampdu_state);
-+ clear_bit(tid, &msta->wcid.ampdu_state);
- ret = mt7996_mcu_add_tx_ba(dev, params, false);
- ieee80211_stop_tx_ba_cb_irqsafe(vif, sta->addr, tid);
- break;
-@@ -792,7 +815,7 @@ mt7996_get_stats(struct ieee80211_hw *hw,
- {
- struct mt7996_phy *phy = mt7996_hw_phy(hw);
- struct mt7996_dev *dev = mt7996_hw_dev(hw);
-- struct mib_stats *mib = &phy->mib;
-+ struct mt76_mib_stats *mib = &phy->mib;
-
- mutex_lock(&dev->mt76.mutex);
-
-@@ -903,7 +926,7 @@ mt7996_set_coverage_class(struct ieee80211_hw *hw, s16 coverage_class)
-
- mutex_lock(&dev->mt76.mutex);
- phy->coverage_class = max_t(s16, coverage_class, 0);
-- mt7996_mac_set_timing(phy);
-+ mt7996_mac_set_coverage_class(phy);
- mutex_unlock(&dev->mt76.mutex);
- }
-
-@@ -952,18 +975,19 @@ static void mt7996_sta_statistics(struct ieee80211_hw *hw,
- struct mt7996_sta *msta = (struct mt7996_sta *)sta->drv_priv;
- struct rate_info *txrate = &msta->wcid.rate;
-
-- if (!txrate->legacy && !txrate->flags)
-- return;
--
-- if (txrate->legacy) {
-- sinfo->txrate.legacy = txrate->legacy;
-- } else {
-- sinfo->txrate.mcs = txrate->mcs;
-- sinfo->txrate.nss = txrate->nss;
-- sinfo->txrate.bw = txrate->bw;
-- sinfo->txrate.he_gi = txrate->he_gi;
-- sinfo->txrate.he_dcm = txrate->he_dcm;
-- sinfo->txrate.he_ru_alloc = txrate->he_ru_alloc;
-+ if (txrate->legacy || txrate->flags) {
-+ if (txrate->legacy) {
-+ sinfo->txrate.legacy = txrate->legacy;
-+ } else {
-+ sinfo->txrate.mcs = txrate->mcs;
-+ sinfo->txrate.nss = txrate->nss;
-+ sinfo->txrate.bw = txrate->bw;
-+ sinfo->txrate.he_gi = txrate->he_gi;
-+ sinfo->txrate.he_dcm = txrate->he_dcm;
-+ sinfo->txrate.he_ru_alloc = txrate->he_ru_alloc;
-+ }
-+ sinfo->txrate.flags = txrate->flags;
-+ sinfo->filled |= BIT_ULL(NL80211_STA_INFO_TX_BITRATE);
- }
- sinfo->txrate.flags = txrate->flags;
- sinfo->filled |= BIT_ULL(NL80211_STA_INFO_TX_BITRATE);
-@@ -981,11 +1005,11 @@ static void mt7996_sta_rc_work(void *data, struct ieee80211_sta *sta)
- struct mt7996_dev *dev = msta->vif->phy->dev;
- u32 *changed = data;
-
-- spin_lock_bh(&dev->sta_poll_lock);
-+ spin_lock_bh(&dev->mt76.sta_poll_lock);
- msta->changed |= *changed;
- if (list_empty(&msta->rc_list))
- list_add_tail(&msta->rc_list, &dev->sta_rc_list);
-- spin_unlock_bh(&dev->sta_poll_lock);
-+ spin_unlock_bh(&dev->mt76.sta_poll_lock);
- }
-
- static void mt7996_sta_rc_update(struct ieee80211_hw *hw,
-@@ -1153,6 +1177,10 @@ static const char mt7996_gstrings_stats[][ETH_GSTRING_LEN] = {
- "v_tx_mcs_11",
- "v_tx_mcs_12",
- "v_tx_mcs_13",
-+ "v_tx_nss_1",
-+ "v_tx_nss_2",
-+ "v_tx_nss_3",
-+ "v_tx_nss_4",
- };
-
- #define MT7996_SSTATS_LEN ARRAY_SIZE(mt7996_gstrings_stats)
-@@ -1186,7 +1214,7 @@ static void mt7996_ethtool_worker(void *wi_data, struct ieee80211_sta *sta)
- if (msta->vif->mt76.idx != wi->idx)
- return;
-
-- mt76_ethtool_worker(wi, &msta->stats, true);
-+ mt76_ethtool_worker(wi, &msta->wcid.stats, true);
- }
-
- static
-@@ -1197,11 +1225,11 @@ void mt7996_get_et_stats(struct ieee80211_hw *hw,
- struct mt7996_dev *dev = mt7996_hw_dev(hw);
- struct mt7996_phy *phy = mt7996_hw_phy(hw);
- struct mt7996_vif *mvif = (struct mt7996_vif *)vif->drv_priv;
-+ struct mt76_mib_stats *mib = &phy->mib;
- struct mt76_ethtool_worker_info wi = {
- .data = data,
- .idx = mvif->mt76.idx,
- };
-- struct mib_stats *mib = &phy->mib;
- /* See mt7996_ampdu_stat_read_phy, etc */
- int i, ei = 0;
-
-diff --git a/mt7996/mcu.c b/mt7996/mcu.c
-index 88e2f9d0..4a30db49 100644
---- a/mt7996/mcu.c
-+++ b/mt7996/mcu.c
-@@ -339,7 +339,11 @@ mt7996_mcu_rx_radar_detected(struct mt7996_dev *dev, struct sk_buff *skb)
- if (r->band_idx >= ARRAY_SIZE(dev->mt76.phys))
- return;
-
-- mphy = dev->mt76.phys[r->band_idx];
-+ if (dev->rdd2_phy && r->band_idx == MT_RX_SEL2)
-+ mphy = dev->rdd2_phy->mt76;
-+ else
-+ mphy = dev->mt76.phys[r->band_idx];
-+
- if (!mphy)
- return;
-
-@@ -600,7 +604,7 @@ static void
- mt7996_mcu_bss_bmc_tlv(struct sk_buff *skb, struct ieee80211_vif *vif,
- struct mt7996_phy *phy)
- {
-- struct mt7996_vif *mvif = (struct mt7996_vif *)vif->drv_priv;
-+ struct mt76_vif *mvif = (struct mt76_vif *)vif->drv_priv;
- struct bss_rate_tlv *bmc;
- struct cfg80211_chan_def *chandef = &phy->mt76->chandef;
- enum nl80211_band band = chandef->chan->band;
-@@ -701,6 +705,34 @@ mt7996_mcu_muar_config(struct mt7996_phy *phy, struct ieee80211_vif *vif,
- sizeof(req), true);
- }
-
-+static void
-+mt7996_mcu_bss_ifs_timing_tlv(struct sk_buff *skb, struct ieee80211_vif *vif)
-+{
-+ struct mt7996_vif *mvif = (struct mt7996_vif *)vif->drv_priv;
-+ struct mt7996_phy *phy = mvif->phy;
-+ struct bss_ifs_time_tlv *ifs_time;
-+ struct tlv *tlv;
-+ bool is_2ghz = phy->mt76->chandef.chan->band == NL80211_BAND_2GHZ;
-+
-+ tlv = mt7996_mcu_add_uni_tlv(skb, UNI_BSS_INFO_IFS_TIME, sizeof(*ifs_time));
-+
-+ ifs_time = (struct bss_ifs_time_tlv *)tlv;
-+ ifs_time->slot_valid = true;
-+ ifs_time->sifs_valid = true;
-+ ifs_time->rifs_valid = true;
-+ ifs_time->eifs_valid = true;
-+
-+ ifs_time->slot_time = cpu_to_le16(phy->slottime);
-+ ifs_time->sifs_time = cpu_to_le16(10);
-+ ifs_time->rifs_time = cpu_to_le16(2);
-+ ifs_time->eifs_time = cpu_to_le16(is_2ghz ? 78 : 84);
-+
-+ if (is_2ghz) {
-+ ifs_time->eifs_cck_valid = true;
-+ ifs_time->eifs_cck_time = cpu_to_le16(314);
-+ }
-+}
-+
- static int
- mt7996_mcu_bss_basic_tlv(struct sk_buff *skb,
- struct ieee80211_vif *vif,
-@@ -712,6 +744,7 @@ mt7996_mcu_bss_basic_tlv(struct sk_buff *skb,
- struct cfg80211_chan_def *chandef = &phy->chandef;
- struct mt76_connac_bss_basic_tlv *bss;
- u32 type = CONNECTION_INFRA_AP;
-+ u16 sta_wlan_idx = wlan_idx;
- struct tlv *tlv;
- int idx;
-
-@@ -731,7 +764,7 @@ mt7996_mcu_bss_basic_tlv(struct sk_buff *skb,
- struct mt76_wcid *wcid;
-
- wcid = (struct mt76_wcid *)sta->drv_priv;
-- wlan_idx = wcid->idx;
-+ sta_wlan_idx = wcid->idx;
- }
- rcu_read_unlock();
- }
-@@ -751,7 +784,7 @@ mt7996_mcu_bss_basic_tlv(struct sk_buff *skb,
- bss->bcn_interval = cpu_to_le16(vif->bss_conf.beacon_int);
- bss->dtim_period = vif->bss_conf.dtim_period;
- bss->bmc_tx_wlan_idx = cpu_to_le16(wlan_idx);
-- bss->sta_idx = cpu_to_le16(wlan_idx);
-+ bss->sta_idx = cpu_to_le16(sta_wlan_idx);
- bss->conn_type = cpu_to_le32(type);
- bss->omac_idx = mvif->omac_idx;
- bss->band_idx = mvif->band_idx;
-@@ -825,6 +858,7 @@ int mt7996_mcu_add_bss_info(struct mt7996_phy *phy,
- mt7996_mcu_bss_bmc_tlv(skb, vif, phy);
- mt7996_mcu_bss_ra_tlv(skb, vif, phy);
- mt7996_mcu_bss_txcmd_tlv(skb, true);
-+ mt7996_mcu_bss_ifs_timing_tlv(skb, vif);
-
- if (vif->bss_conf.he_support)
- mt7996_mcu_bss_he_tlv(skb, vif, phy);
-@@ -837,6 +871,23 @@ out:
- MCU_WMWA_UNI_CMD(BSS_INFO_UPDATE), true);
- }
-
-+int mt7996_mcu_set_timing(struct mt7996_phy *phy, struct ieee80211_vif *vif)
-+{
-+ struct mt7996_vif *mvif = (struct mt7996_vif *)vif->drv_priv;
-+ struct mt7996_dev *dev = phy->dev;
-+ struct sk_buff *skb;
-+
-+ skb = __mt7996_mcu_alloc_bss_req(&dev->mt76, &mvif->mt76,
-+ MT7996_BSS_UPDATE_MAX_SIZE);
-+ if (IS_ERR(skb))
-+ return PTR_ERR(skb);
-+
-+ mt7996_mcu_bss_ifs_timing_tlv(skb, vif);
-+
-+ return mt76_mcu_skb_send_msg(&dev->mt76, skb,
-+ MCU_WMWA_UNI_CMD(BSS_INFO_UPDATE), true);
-+}
-+
- static int
- mt7996_mcu_sta_ba(struct mt76_dev *dev, struct mt76_vif *mvif,
- struct ieee80211_ampdu_params *params,
-@@ -1050,6 +1101,59 @@ mt7996_mcu_sta_amsdu_tlv(struct mt7996_dev *dev, struct sk_buff *skb,
- }
- }
-
-+static void
-+mt7996_mcu_sta_muru_tlv(struct mt7996_dev *dev, struct sk_buff *skb,
-+ struct ieee80211_vif *vif, struct ieee80211_sta *sta)
-+{
-+ struct ieee80211_he_cap_elem *elem = &sta->deflink.he_cap.he_cap_elem;
-+ struct sta_rec_muru *muru;
-+ struct tlv *tlv;
-+
-+ if (vif->type != NL80211_IFTYPE_STATION &&
-+ vif->type != NL80211_IFTYPE_AP)
-+ return;
-+
-+ tlv = mt76_connac_mcu_add_tlv(skb, STA_REC_MURU, sizeof(*muru));
-+
-+ muru = (struct sta_rec_muru *)tlv;
-+ muru->cfg.mimo_dl_en = vif->bss_conf.eht_mu_beamformer ||
-+ vif->bss_conf.he_mu_beamformer ||
-+ vif->bss_conf.vht_mu_beamformer ||
-+ vif->bss_conf.vht_mu_beamformee;
-+ muru->cfg.ofdma_dl_en = true;
-+
-+ if (sta->deflink.vht_cap.vht_supported)
-+ muru->mimo_dl.vht_mu_bfee =
-+ !!(sta->deflink.vht_cap.cap & IEEE80211_VHT_CAP_MU_BEAMFORMEE_CAPABLE);
-+
-+ if (!sta->deflink.he_cap.has_he)
-+ return;
-+
-+ muru->mimo_dl.partial_bw_dl_mimo =
-+ HE_PHY(CAP6_PARTIAL_BANDWIDTH_DL_MUMIMO, elem->phy_cap_info[6]);
-+
-+ muru->mimo_ul.full_ul_mimo =
-+ HE_PHY(CAP2_UL_MU_FULL_MU_MIMO, elem->phy_cap_info[2]);
-+ muru->mimo_ul.partial_ul_mimo =
-+ HE_PHY(CAP2_UL_MU_PARTIAL_MU_MIMO, elem->phy_cap_info[2]);
-+
-+ muru->ofdma_dl.punc_pream_rx =
-+ HE_PHY(CAP1_PREAMBLE_PUNC_RX_MASK, elem->phy_cap_info[1]);
-+ muru->ofdma_dl.he_20m_in_40m_2g =
-+ HE_PHY(CAP8_20MHZ_IN_40MHZ_HE_PPDU_IN_2G, elem->phy_cap_info[8]);
-+ muru->ofdma_dl.he_20m_in_160m =
-+ HE_PHY(CAP8_20MHZ_IN_160MHZ_HE_PPDU, elem->phy_cap_info[8]);
-+ muru->ofdma_dl.he_80m_in_160m =
-+ HE_PHY(CAP8_80MHZ_IN_160MHZ_HE_PPDU, elem->phy_cap_info[8]);
-+
-+ muru->ofdma_ul.t_frame_dur =
-+ HE_MAC(CAP1_TF_MAC_PAD_DUR_MASK, elem->mac_cap_info[1]);
-+ muru->ofdma_ul.mu_cascading =
-+ HE_MAC(CAP2_MU_CASCADING, elem->mac_cap_info[2]);
-+ muru->ofdma_ul.uo_ra =
-+ HE_MAC(CAP3_OFDMA_RA, elem->mac_cap_info[3]);
-+}
-+
- static inline bool
- mt7996_is_ebf_supported(struct mt7996_phy *phy, struct ieee80211_vif *vif,
- struct ieee80211_sta *sta, bool bfee)
-@@ -1727,7 +1831,8 @@ int mt7996_mcu_add_sta(struct mt7996_dev *dev, struct ieee80211_vif *vif,
- mt7996_mcu_sta_he_6g_tlv(skb, sta);
- /* starec eht */
- mt7996_mcu_sta_eht_tlv(skb, sta);
-- /* TODO: starec muru */
-+ /* starec muru */
-+ mt7996_mcu_sta_muru_tlv(dev, skb, vif, sta);
- /* starec bfee */
- mt7996_mcu_sta_bfee_tlv(dev, skb, vif, sta);
- /* starec hdr trans */
-@@ -2155,7 +2260,7 @@ out:
- static int
- mt7996_mcu_send_ram_firmware(struct mt7996_dev *dev,
- const struct mt7996_fw_trailer *hdr,
-- const u8 *data, bool is_wa)
-+ const u8 *data, enum mt7996_ram_type type)
- {
- int i, offset = 0;
- u32 override = 0, option = 0;
-@@ -2167,8 +2272,10 @@ mt7996_mcu_send_ram_firmware(struct mt7996_dev *dev,
-
- region = (const struct mt7996_fw_region *)((const u8 *)hdr -
- (hdr->n_region - i) * sizeof(*region));
-+ /* DSP and WA use same mode */
- mode = mt76_connac_mcu_gen_dl_mode(&dev->mt76,
-- region->feature_set, is_wa);
-+ region->feature_set,
-+ type != MT7996_RAM_TYPE_WM);
- len = le32_to_cpu(region->len);
- addr = le32_to_cpu(region->addr);
-
-@@ -2195,19 +2302,22 @@ mt7996_mcu_send_ram_firmware(struct mt7996_dev *dev,
- if (override)
- option |= FW_START_OVERRIDE;
-
-- if (is_wa)
-+ if (type == MT7996_RAM_TYPE_WA)
- option |= FW_START_WORKING_PDA_CR4;
-+ else if (type == MT7996_RAM_TYPE_DSP)
-+ option |= FW_START_WORKING_PDA_DSP;
-
- return mt76_connac_mcu_start_firmware(&dev->mt76, override, option);
- }
-
--static int mt7996_load_ram(struct mt7996_dev *dev)
-+static int __mt7996_load_ram(struct mt7996_dev *dev, const char *fw_type,
-+ const char *fw_file, enum mt7996_ram_type ram_type)
- {
- const struct mt7996_fw_trailer *hdr;
- const struct firmware *fw;
- int ret;
-
-- ret = request_firmware(&fw, MT7996_FIRMWARE_WM, dev->mt76.dev);
-+ ret = request_firmware(&fw, fw_file, dev->mt76.dev);
- if (ret)
- return ret;
-
-@@ -2217,37 +2327,13 @@ static int mt7996_load_ram(struct mt7996_dev *dev)
- goto out;
- }
-
-- hdr = (const struct mt7996_fw_trailer *)(fw->data + fw->size - sizeof(*hdr));
-+ hdr = (const void *)(fw->data + fw->size - sizeof(*hdr));
-+ dev_info(dev->mt76.dev, "%s Firmware Version: %.10s, Build Time: %.15s\n",
-+ fw_type, hdr->fw_ver, hdr->build_date);
-
-- dev_info(dev->mt76.dev, "WM Firmware Version: %.10s, Build Time: %.15s\n",
-- hdr->fw_ver, hdr->build_date);
--
-- ret = mt7996_mcu_send_ram_firmware(dev, hdr, fw->data, false);
-+ ret = mt7996_mcu_send_ram_firmware(dev, hdr, fw->data, ram_type);
- if (ret) {
-- dev_err(dev->mt76.dev, "Failed to start WM firmware\n");
-- goto out;
-- }
--
-- release_firmware(fw);
--
-- ret = request_firmware(&fw, MT7996_FIRMWARE_WA, dev->mt76.dev);
-- if (ret)
-- return ret;
--
-- if (!fw || !fw->data || fw->size < sizeof(*hdr)) {
-- dev_err(dev->mt76.dev, "Invalid firmware\n");
-- ret = -EINVAL;
-- goto out;
-- }
--
-- hdr = (const struct mt7996_fw_trailer *)(fw->data + fw->size - sizeof(*hdr));
--
-- dev_info(dev->mt76.dev, "WA Firmware Version: %.10s, Build Time: %.15s\n",
-- hdr->fw_ver, hdr->build_date);
--
-- ret = mt7996_mcu_send_ram_firmware(dev, hdr, fw->data, true);
-- if (ret) {
-- dev_err(dev->mt76.dev, "Failed to start WA firmware\n");
-+ dev_err(dev->mt76.dev, "Failed to start %s firmware\n", fw_type);
- goto out;
- }
-
-@@ -2261,6 +2347,24 @@ out:
- return ret;
- }
-
-+static int mt7996_load_ram(struct mt7996_dev *dev)
-+{
-+ int ret;
-+
-+ ret = __mt7996_load_ram(dev, "WM", MT7996_FIRMWARE_WM,
-+ MT7996_RAM_TYPE_WM);
-+ if (ret)
-+ return ret;
-+
-+ ret = __mt7996_load_ram(dev, "DSP", MT7996_FIRMWARE_DSP,
-+ MT7996_RAM_TYPE_DSP);
-+ if (ret)
-+ return ret;
-+
-+ return __mt7996_load_ram(dev, "WA", MT7996_FIRMWARE_WA,
-+ MT7996_RAM_TYPE_WA);
-+}
-+
- static int
- mt7996_firmware_state(struct mt7996_dev *dev, bool wa)
- {
-diff --git a/mt7996/mcu.h b/mt7996/mcu.h
-index d7075a4d..078f8285 100644
---- a/mt7996/mcu.h
-+++ b/mt7996/mcu.h
-@@ -317,6 +317,22 @@ struct bss_sec_tlv {
- u8 __rsv2[1];
- } __packed;
-
-+struct bss_ifs_time_tlv {
-+ __le16 tag;
-+ __le16 len;
-+ u8 slot_valid;
-+ u8 sifs_valid;
-+ u8 rifs_valid;
-+ u8 eifs_valid;
-+ __le16 slot_time;
-+ __le16 sifs_time;
-+ __le16 rifs_time;
-+ __le16 eifs_time;
-+ u8 eifs_cck_valid;
-+ u8 rsv;
-+ __le16 eifs_cck_time;
-+} __packed;
-+
- struct bss_power_save {
- __le16 tag;
- __le16 len;
-@@ -552,6 +568,7 @@ enum {
- sizeof(struct bss_txcmd_tlv) + \
- sizeof(struct bss_power_save) + \
- sizeof(struct bss_sec_tlv) + \
-+ sizeof(struct bss_ifs_time_tlv) + \
- sizeof(struct bss_mld_tlv))
-
- #define MT7996_STA_UPDATE_MAX_SIZE (sizeof(struct sta_req_hdr) + \
-diff --git a/mt7996/mt7996.h b/mt7996/mt7996.h
-index 4d7dcb95..726c222e 100644
---- a/mt7996/mt7996.h
-+++ b/mt7996/mt7996.h
-@@ -26,15 +26,17 @@
-
- #define MT7996_RX_RING_SIZE 1536
- #define MT7996_RX_MCU_RING_SIZE 512
-+#define MT7996_RX_MCU_RING_SIZE_WA 1024
-
- #define MT7996_FIRMWARE_WA "mediatek/mt7996/mt7996_wa.bin"
- #define MT7996_FIRMWARE_WM "mediatek/mt7996/mt7996_wm.bin"
-+#define MT7996_FIRMWARE_DSP "mediatek/mt7996/mt7996_dsp.bin"
- #define MT7996_ROM_PATCH "mediatek/mt7996/mt7996_rom_patch.bin"
-
- #define MT7996_EEPROM_DEFAULT "mediatek/mt7996/mt7996_eeprom.bin"
- #define MT7996_EEPROM_SIZE 7680
- #define MT7996_EEPROM_BLOCK_SIZE 16
--#define MT7996_TOKEN_SIZE 8192
-+#define MT7996_TOKEN_SIZE 16384
-
- #define MT7996_CFEND_RATE_DEFAULT 0x49 /* OFDM 24M */
- #define MT7996_CFEND_RATE_11B 0x03 /* 11B LP, 11M */
-@@ -52,6 +54,12 @@ struct mt7996_sta;
- struct mt7996_dfs_pulse;
- struct mt7996_dfs_pattern;
-
-+enum mt7996_ram_type {
-+ MT7996_RAM_TYPE_WM,
-+ MT7996_RAM_TYPE_WA,
-+ MT7996_RAM_TYPE_DSP,
-+};
-+
- enum mt7996_txq_id {
- MT7996_TXQ_FWDL = 16,
- MT7996_TXQ_MCU_WM,
-@@ -95,7 +103,6 @@ struct mt7996_sta {
-
- struct mt7996_vif *vif;
-
-- struct list_head poll_list;
- struct list_head rc_list;
- u32 airtime_ac[8];
-
-@@ -104,9 +111,6 @@ struct mt7996_sta {
-
- unsigned long changed;
- unsigned long jiffies;
-- unsigned long ampdu_state;
--
-- struct mt76_sta_stats stats;
-
- struct mt76_connac_sta_key_conf bip;
-
-@@ -124,64 +128,6 @@ struct mt7996_vif {
-
- struct ieee80211_tx_queue_params queue_params[IEEE80211_NUM_ACS];
- struct cfg80211_bitrate_mask bitrate_mask;
--
-- u8 basic_rates_idx;
-- u8 mcast_rates_idx;
-- u8 beacon_rates_idx;
--};
--
--/* per-phy stats. */
--struct mib_stats {
-- u32 ack_fail_cnt;
-- u32 fcs_err_cnt;
-- u32 rts_cnt;
-- u32 rts_retries_cnt;
-- u32 ba_miss_cnt;
-- u32 tx_mu_bf_cnt;
-- u32 tx_mu_mpdu_cnt;
-- u32 tx_mu_acked_mpdu_cnt;
-- u32 tx_su_acked_mpdu_cnt;
-- u32 tx_bf_ibf_ppdu_cnt;
-- u32 tx_bf_ebf_ppdu_cnt;
--
-- u32 tx_bf_rx_fb_all_cnt;
-- u32 tx_bf_rx_fb_eht_cnt;
-- u32 tx_bf_rx_fb_he_cnt;
-- u32 tx_bf_rx_fb_vht_cnt;
-- u32 tx_bf_rx_fb_ht_cnt;
--
-- u32 tx_bf_rx_fb_bw; /* value of last sample, not cumulative */
-- u32 tx_bf_rx_fb_nc_cnt;
-- u32 tx_bf_rx_fb_nr_cnt;
-- u32 tx_bf_fb_cpl_cnt;
-- u32 tx_bf_fb_trig_cnt;
--
-- u32 tx_ampdu_cnt;
-- u32 tx_stop_q_empty_cnt;
-- u32 tx_mpdu_attempts_cnt;
-- u32 tx_mpdu_success_cnt;
-- /* BF counter is PPDU-based, so remove MPDU-based BF counter */
--
-- u32 tx_rwp_fail_cnt;
-- u32 tx_rwp_need_cnt;
--
-- /* rx stats */
-- u32 rx_fifo_full_cnt;
-- u32 channel_idle_cnt;
-- u32 rx_vector_mismatch_cnt;
-- u32 rx_delimiter_fail_cnt;
-- u32 rx_len_mismatch_cnt;
-- u32 rx_mpdu_cnt;
-- u32 rx_ampdu_cnt;
-- u32 rx_ampdu_bytes_cnt;
-- u32 rx_ampdu_valid_subframe_cnt;
-- u32 rx_ampdu_valid_subframe_bytes_cnt;
-- u32 rx_pfdrop_cnt;
-- u32 rx_vec_queue_overflow_drop_cnt;
-- u32 rx_ba_cnt;
--
-- u32 tx_amsdu[8];
-- u32 tx_amsdu_cnt;
- };
-
- /* crash-dump */
-@@ -222,7 +168,7 @@ struct mt7996_phy {
- u32 rx_ampdu_ts;
- u32 ampdu_ref;
-
-- struct mib_stats mib;
-+ struct mt76_mib_stats mib;
- struct mt76_channel_state state_ts;
- };
-
-@@ -272,9 +218,7 @@ struct mt7996_dev {
- #endif
-
- struct list_head sta_rc_list;
-- struct list_head sta_poll_list;
- struct list_head twt_list;
-- spinlock_t sta_poll_lock;
-
- u32 hw_pattern;
-
-@@ -405,6 +349,7 @@ int mt7996_dma_init(struct mt7996_dev *dev);
- void mt7996_dma_reset(struct mt7996_dev *dev, bool force);
- void mt7996_dma_prefetch(struct mt7996_dev *dev);
- void mt7996_dma_cleanup(struct mt7996_dev *dev);
-+void mt7996_dma_start(struct mt7996_dev *dev, bool reset);
- void mt7996_init_txpower(struct mt7996_dev *dev,
- struct ieee80211_supported_band *sband);
- int mt7996_txbf_init(struct mt7996_dev *dev);
-@@ -456,6 +401,7 @@ int mt7996_mcu_set_radar_th(struct mt7996_dev *dev, int index,
- const struct mt7996_dfs_pattern *pattern);
- int mt7996_mcu_set_radio_en(struct mt7996_phy *phy, bool enable);
- int mt7996_mcu_set_rts_thresh(struct mt7996_phy *phy, u32 val);
-+int mt7996_mcu_set_timing(struct mt7996_phy *phy, struct ieee80211_vif *vif);
- int mt7996_mcu_get_chan_mib_info(struct mt7996_phy *phy, bool chan_switch);
- int mt7996_mcu_rdd_cmd(struct mt7996_dev *dev, int cmd, u8 index,
- u8 rx_sel, u8 val);
-@@ -519,7 +465,7 @@ void mt7996_mac_write_txwi(struct mt7996_dev *dev, __le32 *txwi,
- struct sk_buff *skb, struct mt76_wcid *wcid,
- struct ieee80211_key_conf *key, int pid,
- enum mt76_txq_id qid, u32 changed);
--void mt7996_mac_set_timing(struct mt7996_phy *phy);
-+void mt7996_mac_set_coverage_class(struct mt7996_phy *phy);
- int mt7996_mac_sta_add(struct mt76_dev *mdev, struct ieee80211_vif *vif,
- struct ieee80211_sta *sta);
- void mt7996_mac_sta_remove(struct mt76_dev *mdev, struct ieee80211_vif *vif,
-diff --git a/mt7996/pci.c b/mt7996/pci.c
-index 64aee3fb..c5301050 100644
---- a/mt7996/pci.c
-+++ b/mt7996/pci.c
-@@ -219,4 +219,5 @@ MODULE_DEVICE_TABLE(pci, mt7996_pci_device_table);
- MODULE_DEVICE_TABLE(pci, mt7996_hif_device_table);
- MODULE_FIRMWARE(MT7996_FIRMWARE_WA);
- MODULE_FIRMWARE(MT7996_FIRMWARE_WM);
-+MODULE_FIRMWARE(MT7996_FIRMWARE_DSP);
- MODULE_FIRMWARE(MT7996_ROM_PATCH);
-diff --git a/mt7996/regs.h b/mt7996/regs.h
-index d1d3d154..97beab92 100644
---- a/mt7996/regs.h
-+++ b/mt7996/regs.h
-@@ -557,22 +557,29 @@ enum base_rev {
-
- #define MT_PCIE1_MAC_INT_ENABLE MT_PCIE1_MAC(0x188)
-
-+/* PHYRX CSD */
-+#define MT_WF_PHYRX_CSD_BASE 0x83000000
-+#define MT_WF_PHYRX_CSD(_band, _wf, ofs) (MT_WF_PHYRX_CSD_BASE + \
-+ ((_band) << 20) + \
-+ ((_wf) << 16) + (ofs))
-+#define MT_WF_PHYRX_CSD_IRPI(_band, _wf) MT_WF_PHYRX_CSD(_band, _wf, 0x1000)
-+
- /* PHYRX CTRL */
- #define MT_WF_PHYRX_BAND_BASE 0x83080000
- #define MT_WF_PHYRX_BAND(_band, ofs) (MT_WF_PHYRX_BAND_BASE + \
- ((_band) << 20) + (ofs))
-
-+#define MT_WF_PHYRX_BAND_GID_TAB_VLD0(_band) MT_WF_PHYRX_BAND(_band, 0x1054)
-+#define MT_WF_PHYRX_BAND_GID_TAB_VLD1(_band) MT_WF_PHYRX_BAND(_band, 0x1058)
-+#define MT_WF_PHYRX_BAND_GID_TAB_POS0(_band) MT_WF_PHYRX_BAND(_band, 0x105c)
-+#define MT_WF_PHYRX_BAND_GID_TAB_POS1(_band) MT_WF_PHYRX_BAND(_band, 0x1060)
-+#define MT_WF_PHYRX_BAND_GID_TAB_POS2(_band) MT_WF_PHYRX_BAND(_band, 0x1064)
-+#define MT_WF_PHYRX_BAND_GID_TAB_POS3(_band) MT_WF_PHYRX_BAND(_band, 0x1068)
-+
- #define MT_WF_PHYRX_BAND_RX_CTRL1(_band) MT_WF_PHYRX_BAND(_band, 0x2004)
- #define MT_WF_PHYRX_BAND_RX_CTRL1_IPI_EN GENMASK(2, 0)
- #define MT_WF_PHYRX_BAND_RX_CTRL1_STSCNT_EN GENMASK(11, 9)
-
--/* PHYRX CSD */
--#define MT_WF_PHYRX_CSD_BASE 0x83000000
--#define MT_WF_PHYRX_CSD(_band, _wf, ofs) (MT_WF_PHYRX_CSD_BASE + \
-- ((_band) << 20) + \
-- ((_wf) << 16) + (ofs))
--#define MT_WF_PHYRX_CSD_IRPI(_band, _wf) MT_WF_PHYRX_CSD(_band, _wf, 0x1000)
--
- /* PHYRX CSD BAND */
- #define MT_WF_PHYRX_CSD_BAND_RXTD12(_band) MT_WF_PHYRX_BAND(_band, 0x8230)
- #define MT_WF_PHYRX_CSD_BAND_RXTD12_IRPI_SW_CLR_ONLY BIT(18)
-diff --git a/tx.c b/tx.c
-index 72b3ec71..6cc26cc6 100644
---- a/tx.c
-+++ b/tx.c
-@@ -121,6 +121,7 @@ int
- mt76_tx_status_skb_add(struct mt76_dev *dev, struct mt76_wcid *wcid,
- struct sk_buff *skb)
- {
-+ struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
- struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
- struct mt76_tx_cb *cb = mt76_tx_skb_cb(skb);
- int pid;
-@@ -134,8 +135,14 @@ mt76_tx_status_skb_add(struct mt76_dev *dev, struct mt76_wcid *wcid,
- return MT_PACKET_ID_NO_ACK;
-
- if (!(info->flags & (IEEE80211_TX_CTL_REQ_TX_STATUS |
-- IEEE80211_TX_CTL_RATE_CTRL_PROBE)))
-+ IEEE80211_TX_CTL_RATE_CTRL_PROBE))) {
-+ if (mtk_wed_device_active(&dev->mmio.wed) &&
-+ ((info->flags & IEEE80211_TX_CTL_HW_80211_ENCAP) ||
-+ ieee80211_is_data(hdr->frame_control)))
-+ return MT_PACKET_ID_WED;
-+
- return MT_PACKET_ID_NO_SKB;
-+ }
-
- spin_lock_bh(&dev->status_lock);
-
-@@ -263,8 +270,15 @@ void __mt76_tx_complete_skb(struct mt76_dev *dev, u16 wcid_idx, struct sk_buff *
- #endif
-
- if (cb->pktid < MT_PACKET_ID_FIRST) {
-+ struct ieee80211_rate_status rs = {};
-+
- hw = mt76_tx_status_get_hw(dev, skb);
- status.sta = wcid_to_sta(wcid);
-+ if (status.sta && (wcid->rate.flags || wcid->rate.legacy)) {
-+ rs.rate_idx = wcid->rate;
-+ status.rates = &rs;
-+ status.n_rates = 1;
-+ }
- spin_lock_bh(&dev->rx_lock);
- ieee80211_tx_status_ext(hw, &status);
- spin_unlock_bh(&dev->rx_lock);
---
-2.18.0
-