From a9c6efde39372d9d301a96d9da1a16cf0f7f90df Mon Sep 17 00:00:00 2001 From: morrownr <69053122+morrownr@users.noreply.github.com> Date: Thu, 25 Jul 2024 15:37:43 -0500 Subject: [PATCH 001/193] Update README.md --- README.md | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 46978add..6369259c 100644 --- a/README.md +++ b/README.md @@ -194,11 +194,17 @@ The available options for rtw_core are disable_lps_deep, support_bf, and debug_ When your kernel updates, run: ```bash cd ~/rtw88 +``` +``` git pull +``` +``` make +``` +``` sudo make install ``` -💡 **Remember, every new kernel requires this step - no exceptions**. If the update means that you have no network, skip the 'git pull' and build the possible oldeer version, but do that step once you have network, and rebuild if any updates were pulled. +💡 **Remember, every new kernel requires this step - no exceptions**. If the kernel update means that you have no network, skip the 'git pull' and build the driver as it is, but run `git pull` once you have connectivity, and rebuild if any updates were pulled. ## FAQ From 610e04fc38343dcdcef95475c1579efc07572f1f Mon Sep 17 00:00:00 2001 From: Bitterblue Smith Date: Sat, 27 Jul 2024 16:41:28 +0300 Subject: [PATCH 002/193] wifi: rtw88: Avoid using macid 0 in AP mode In AP mode, the firmware stops transmitting beacons if it receives H2C_CMD_RA_INFO for macid 0. Leave macid 0 unused in AP mode. Macid 1 is already reserved for broadcast/multicast. That means the first connected client is now assigned macid 2. Signed-off-by: Bitterblue Smith --- mac80211.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/mac80211.c b/mac80211.c index 6b97ae36..742817d7 100644 --- a/mac80211.c +++ b/mac80211.c @@ -473,6 +473,7 @@ static int rtw_ops_start_ap(struct ieee80211_hw *hw, struct ieee80211_vif *vif) const struct rtw_chip_info *chip = rtwdev->chip; mutex_lock(&rtwdev->mutex); + set_bit(0, rtwdev->mac_id_map); rtw_write32_set(rtwdev, REG_TCR, BIT_TCR_UPDATE_HGQMD); rtwdev->ap_active = true; rtw_store_op_chan(rtwdev, true); @@ -498,6 +499,7 @@ static void rtw_ops_stop_ap(struct ieee80211_hw *hw, rtwdev->ap_active = false; if (!rtw_core_check_sta_active(rtwdev)) rtw_clear_op_chan(rtwdev); + clear_bit(0, rtwdev->mac_id_map); mutex_unlock(&rtwdev->mutex); } From e1ce1992d74358ed89f55300bb7ac897aeff35e5 Mon Sep 17 00:00:00 2001 From: 5kft <5kft@users.noreply.github.com> Date: Sun, 28 Jul 2024 17:58:15 -0700 Subject: [PATCH 003/193] Update for compilation in kernel v6.11 --- mac80211.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/mac80211.c b/mac80211.c index 742817d7..3105d5b8 100644 --- a/mac80211.c +++ b/mac80211.c @@ -64,7 +64,11 @@ static int rtw_ops_start(struct ieee80211_hw *hw) return ret; } +#if (LINUX_VERSION_CODE < KERNEL_VERSION(6, 11, 0)) static void rtw_ops_stop(struct ieee80211_hw *hw) +#else +static void rtw_ops_stop(struct ieee80211_hw *hw, bool suspend) +#endif { struct rtw_dev *rtwdev = hw->priv; From 5bacfb36fde2e44cbdd06cbbbbd41a8a0b2a8630 Mon Sep 17 00:00:00 2001 From: Zenm Chen Date: Mon, 22 Jul 2024 22:07:23 +0800 Subject: [PATCH 004/193] Clean up Makefile --- Makefile | 162 +++++++++++++++++++++++++++---------------------------- 1 file changed, 78 insertions(+), 84 deletions(-) diff --git a/Makefile b/Makefile index 6387d75e..54ec968a 100644 --- a/Makefile +++ b/Makefile @@ -2,7 +2,6 @@ SHELL := /bin/sh KVER ?= $(if $(KERNELRELEASE),$(KERNELRELEASE),$(shell uname -r)) KSRC ?= $(if $(KERNEL_SRC),$(KERNEL_SRC),/lib/modules/$(KVER)/build) FIRMWAREDIR := /lib/firmware/rtw88 -PWD := $(shell pwd) # Handle the move of the entire rtw88 tree ifneq ("","$(wildcard /lib/modules/$(KVER)/kernel/drivers/net/wireless/realtek)") MODDESTDIR := /lib/modules/$(KVER)/kernel/drivers/net/wireless/realtek/rtw88 @@ -42,137 +41,132 @@ EXTRA_CFLAGS += -DCONFIG_RTW88_DEBUG=1 EXTRA_CFLAGS += -DCONFIG_RTW88_DEBUGFS=1 #EXTRA_CFLAGS += -DCONFIG_RTW88_REGD_USER_REG_HINTS -obj-m += rtw_core.o -rtw_core-objs += main.o \ - mac80211.o \ - util.o \ - debug.o \ - tx.o \ - rx.o \ - mac.o \ - phy.o \ - coex.o \ - efuse.o \ - fw.o \ - ps.o \ - sec.o \ - bf.o \ - regd.o \ - sar.o +obj-m += rtw_core.o +rtw_core-objs += main.o \ + mac80211.o \ + util.o \ + debug.o \ + tx.o \ + rx.o \ + mac.o \ + phy.o \ + coex.o \ + efuse.o \ + fw.o \ + ps.o \ + sec.o \ + bf.o \ + regd.o \ + sar.o ifeq ($(CONFIG_PM), y) -rtw_core-objs += wow.o +rtw_core-objs += wow.o endif -obj-m += rtw_8822b.o -rtw_8822b-objs := rtw8822b.o rtw8822b_table.o - -ifeq ($(CONFIG_PCI), y) -obj-m += rtw_8822be.o -rtw_8822be-objs := rtw8822be.o -endif - -obj-m += rtw_8822bu.o -rtw_8822bu-objs := rtw8822bu.o +obj-m += rtw_8703b.o +rtw_8703b-objs := rtw8703b.o rtw8703b_tables.o ifneq ($(CONFIG_MMC), ) -obj-m += rtw_8822bs.o -rtw_8822bs-objs := rtw8822bs.o +obj-m += rtw_8723cs.o +rtw_8723cs-objs := rtw8723cs.o endif -obj-m += rtw_8822c.o -rtw_8822c-objs := rtw8822c.o rtw8822c_table.o +obj-m += rtw_8723d.o +rtw_8723d-objs := rtw8723d.o rtw8723d_table.o ifeq ($(CONFIG_PCI), y) -obj-m += rtw_8822ce.o -rtw_8822ce-objs := rtw8822ce.o +obj-m += rtw_8723de.o +rtw_8723de-objs := rtw8723de.o endif -obj-m += rtw_8822cu.o -rtw_8822cu-objs := rtw8822cu.o +ifneq ($(CONFIG_MMC), ) +obj-m += rtw_8723ds.o +rtw_8723ds-objs := rtw8723ds.o +endif -obj-m += rtw_8723x.o -rtw_8723x-objs := rtw8723x.o +obj-m += rtw_8723du.o +rtw_8723du-objs := rtw8723du.o -obj-m += rtw_8703b.o -rtw_8703b-objs := rtw8703b.o rtw8703b_tables.o +obj-m += rtw_8723x.o +rtw_8723x-objs := rtw8723x.o -obj-m += rtw_8723x.o -rtw_8723x-objs := rtw8723x.o +obj-m += rtw_8812au.o +rtw_8812au-objs := rtw8812au.o -ifneq ($(CONFIG_MMC), ) -obj-m += rtw_8822cs.o -rtw_8822cs-objs := rtw8822cs.o +obj-m += rtw_8821a.o +rtw_8821a-objs := rtw8821a.o rtw8821a_table.o rtw8812a_table.o -obj-m += rtw_8723cs.o -rtw_8723cs-objs := rtw8723cs.o -endif +obj-m += rtw_8821au.o +rtw_8821au-objs := rtw8821au.o -obj-m += rtw_8723d.o -rtw_8723d-objs := rtw8723d.o rtw8723d_table.o +obj-m += rtw_8821c.o +rtw_8821c-objs := rtw8821c.o rtw8821c_table.o ifeq ($(CONFIG_PCI), y) -obj-m += rtw_8723de.o -rtw_8723de-objs := rtw8723de.o +obj-m += rtw_8821ce.o +rtw_8821ce-objs := rtw8821ce.o endif -obj-m += rtw_8723du.o -rtw_8723du-objs := rtw8723du.o - ifneq ($(CONFIG_MMC), ) -obj-m += rtw_8723ds.o -rtw_8723ds-objs := rtw8723ds.o +obj-m += rtw_8821cs.o +rtw_8821cs-objs := rtw8821cs.o endif -obj-m += rtw_8821c.o -rtw_8821c-objs := rtw8821c.o rtw8821c_table.o +obj-m += rtw_8821cu.o +rtw_8821cu-objs := rtw8821cu.o + +obj-m += rtw_8822b.o +rtw_8822b-objs := rtw8822b.o rtw8822b_table.o ifeq ($(CONFIG_PCI), y) -obj-m += rtw_8821ce.o -rtw_8821ce-objs := rtw8821ce.o +obj-m += rtw_8822be.o +rtw_8822be-objs := rtw8822be.o +endif + +ifneq ($(CONFIG_MMC), ) +obj-m += rtw_8822bs.o +rtw_8822bs-objs := rtw8822bs.o endif -obj-m += rtw_8821a.o -rtw_8821a-objs := rtw8821a.o rtw8821a_table.o rtw8812a_table.o +obj-m += rtw_8822bu.o +rtw_8822bu-objs := rtw8822bu.o -obj-m += rtw_8821au.o -rtw_8821au-objs := rtw8821au.o +obj-m += rtw_8822c.o +rtw_8822c-objs := rtw8822c.o rtw8822c_table.o -obj-m += rtw_8812au.o -rtw_8812au-objs := rtw8812au.o +ifeq ($(CONFIG_PCI), y) +obj-m += rtw_8822ce.o +rtw_8822ce-objs := rtw8822ce.o +endif ifneq ($(CONFIG_MMC), ) -obj-m += rtw_8821cs.o -rtw_8821cs-objs := rtw8821cs.o +obj-m += rtw_8822cs.o +rtw_8822cs-objs := rtw8822cs.o endif -obj-m += rtw_8821cu.o -rtw_8821cu-objs := rtw8821cu.o +obj-m += rtw_8822cu.o +rtw_8822cu-objs := rtw8822cu.o ifeq ($(CONFIG_PCI), y) -obj-m += rtw_pci.o -rtw_pci-objs := pci.o +obj-m += rtw_pci.o +rtw_pci-objs := pci.o endif ifneq ($(CONFIG_MMC), ) -obj-m += rtw_sdio.o -rtw_sdio-objs := sdio.o +obj-m += rtw_sdio.o +rtw_sdio-objs := sdio.o endif -obj-m += rtw_usb.o -rtw_usb-objs := usb.o - -obj-m += rtw_usb.o -rtw_usb-objs := usb.o +obj-m += rtw_usb.o +rtw_usb-objs := usb.o ccflags-y += -D__CHECK_ENDIAN__ all: - $(MAKE) -j`nproc` -C $(KSRC) M=$(PWD) modules + $(MAKE) -j`nproc` -C $(KSRC) M=$$PWD modules install: all @install -D -m 644 -t $(MODDESTDIR) *.ko - @# copy firmware images to target folder @install -D -m 644 -t $(FIRMWAREDIR) firmware/*.bin ifeq ($(COMPRESS_GZIP), y) @@ -230,7 +224,7 @@ ifeq ($(NO_SKIP_SIGN), y) else echo "Skipping key creation" endif - @for mod in $(shell find ./ -name "*.ko"); do \ + @for mod in $(wildcard *.ko); do \ $(KSRC)/scripts/sign-file sha256 MOK.priv MOK.der $$mod; \ done From dcf562154d30c3c2d6d7e2ba7fd860a50225de01 Mon Sep 17 00:00:00 2001 From: Zenm Chen Date: Mon, 22 Jul 2024 22:11:32 +0800 Subject: [PATCH 005/193] Clean up dkms.conf 1. Sort the directives "BUILT_MODULE_NAME[]" by module names. 2. Directive "DEST_MODULE_LOCATION[]" is ignored on Fedora, RHEL, OpenSuSE, Debian, Ubuntu, Arch Linux and some other distros, and built modules are always installed to /lib/modules/$(uname -r)/updates/dkms, so we install them to this place, too. --- dkms.conf | 110 +++++++++++++++++++++++++++--------------------------- 1 file changed, 55 insertions(+), 55 deletions(-) diff --git a/dkms.conf b/dkms.conf index 903f88d8..bbd65609 100644 --- a/dkms.conf +++ b/dkms.conf @@ -1,57 +1,57 @@ PACKAGE_NAME="rtw88" -PACKAGE_VERSION=0.6 -MAKE="make -C $kernel_source_dir M=$dkms_tree/$PACKAGE_NAME/$PACKAGE_VERSION/build" -CLEAN="make clean" -BUILT_MODULE_NAME[0]="rtw_pci" -BUILT_MODULE_NAME[1]="rtw_usb" -BUILT_MODULE_NAME[2]="rtw_sdio" -BUILT_MODULE_NAME[3]="rtw_8703b" -BUILT_MODULE_NAME[4]="rtw_8723cs" -BUILT_MODULE_NAME[5]="rtw_8723de" -BUILT_MODULE_NAME[6]="rtw_8723ds" -BUILT_MODULE_NAME[7]="rtw_8723du" -BUILT_MODULE_NAME[8]="rtw_8723d" -BUILT_MODULE_NAME[9]="rtw_8723x" -BUILT_MODULE_NAME[10]="rtw_8822be" -BUILT_MODULE_NAME[11]="rtw_8822bs" -BUILT_MODULE_NAME[12]="rtw_8822bu" -BUILT_MODULE_NAME[13]="rtw_8822b" -BUILT_MODULE_NAME[14]="rtw_8822ce" -BUILT_MODULE_NAME[15]="rtw_8822cs" -BUILT_MODULE_NAME[16]="rtw_8822cu" -BUILT_MODULE_NAME[17]="rtw_8822c" -BUILT_MODULE_NAME[18]="rtw_8821ce" -BUILT_MODULE_NAME[19]="rtw_8821cs" -BUILT_MODULE_NAME[20]="rtw_8821cu" -BUILT_MODULE_NAME[21]="rtw_8821c" -BUILT_MODULE_NAME[22]="rtw_8821a" -BUILT_MODULE_NAME[23]="rtw_8821au" -BUILT_MODULE_NAME[24]="rtw_8812au" -BUILT_MODULE_NAME[25]="rtw_core" -DEST_MODULE_LOCATION[0]="/updates" -DEST_MODULE_LOCATION[1]="/updates" -DEST_MODULE_LOCATION[2]="/updates" -DEST_MODULE_LOCATION[3]="/updates" -DEST_MODULE_LOCATION[4]="/updates" -DEST_MODULE_LOCATION[5]="/updates" -DEST_MODULE_LOCATION[6]="/updates" -DEST_MODULE_LOCATION[7]="/updates" -DEST_MODULE_LOCATION[8]="/updates" -DEST_MODULE_LOCATION[9]="/updates" -DEST_MODULE_LOCATION[10]="/updates" -DEST_MODULE_LOCATION[11]="/updates" -DEST_MODULE_LOCATION[12]="/updates" -DEST_MODULE_LOCATION[13]="/updates" -DEST_MODULE_LOCATION[14]="/updates" -DEST_MODULE_LOCATION[15]="/updates" -DEST_MODULE_LOCATION[16]="/updates" -DEST_MODULE_LOCATION[17]="/updates" -DEST_MODULE_LOCATION[18]="/updates" -DEST_MODULE_LOCATION[19]="/updates" -DEST_MODULE_LOCATION[20]="/updates" -DEST_MODULE_LOCATION[21]="/updates" -DEST_MODULE_LOCATION[22]="/updates" -DEST_MODULE_LOCATION[23]="/updates" -DEST_MODULE_LOCATION[24]="/updates" -DEST_MODULE_LOCATION[25]="/updates" +PACKAGE_VERSION="0.6" +MAKE="KVER=${kernelver} 'make' all" +CLEAN="KVER=${kernelver} 'make' clean" AUTOINSTALL=yes +BUILT_MODULE_NAME[0]="rtw_8703b" +BUILT_MODULE_NAME[1]="rtw_8723cs" +BUILT_MODULE_NAME[2]="rtw_8723d" +BUILT_MODULE_NAME[3]="rtw_8723de" +BUILT_MODULE_NAME[4]="rtw_8723ds" +BUILT_MODULE_NAME[5]="rtw_8723du" +BUILT_MODULE_NAME[6]="rtw_8723x" +BUILT_MODULE_NAME[7]="rtw_8812au" +BUILT_MODULE_NAME[8]="rtw_8821a" +BUILT_MODULE_NAME[9]="rtw_8821au" +BUILT_MODULE_NAME[10]="rtw_8821c" +BUILT_MODULE_NAME[11]="rtw_8821ce" +BUILT_MODULE_NAME[12]="rtw_8821cs" +BUILT_MODULE_NAME[13]="rtw_8821cu" +BUILT_MODULE_NAME[14]="rtw_8822b" +BUILT_MODULE_NAME[15]="rtw_8822be" +BUILT_MODULE_NAME[16]="rtw_8822bs" +BUILT_MODULE_NAME[17]="rtw_8822bu" +BUILT_MODULE_NAME[18]="rtw_8822c" +BUILT_MODULE_NAME[19]="rtw_8822ce" +BUILT_MODULE_NAME[20]="rtw_8822cs" +BUILT_MODULE_NAME[21]="rtw_8822cu" +BUILT_MODULE_NAME[22]="rtw_core" +BUILT_MODULE_NAME[23]="rtw_pci" +BUILT_MODULE_NAME[24]="rtw_sdio" +BUILT_MODULE_NAME[25]="rtw_usb" +DEST_MODULE_LOCATION[0]="/updates/dkms" +DEST_MODULE_LOCATION[1]="/updates/dkms" +DEST_MODULE_LOCATION[2]="/updates/dkms" +DEST_MODULE_LOCATION[3]="/updates/dkms" +DEST_MODULE_LOCATION[4]="/updates/dkms" +DEST_MODULE_LOCATION[5]="/updates/dkms" +DEST_MODULE_LOCATION[6]="/updates/dkms" +DEST_MODULE_LOCATION[7]="/updates/dkms" +DEST_MODULE_LOCATION[8]="/updates/dkms" +DEST_MODULE_LOCATION[9]="/updates/dkms" +DEST_MODULE_LOCATION[10]="/updates/dkms" +DEST_MODULE_LOCATION[11]="/updates/dkms" +DEST_MODULE_LOCATION[12]="/updates/dkms" +DEST_MODULE_LOCATION[13]="/updates/dkms" +DEST_MODULE_LOCATION[14]="/updates/dkms" +DEST_MODULE_LOCATION[15]="/updates/dkms" +DEST_MODULE_LOCATION[16]="/updates/dkms" +DEST_MODULE_LOCATION[17]="/updates/dkms" +DEST_MODULE_LOCATION[18]="/updates/dkms" +DEST_MODULE_LOCATION[19]="/updates/dkms" +DEST_MODULE_LOCATION[20]="/updates/dkms" +DEST_MODULE_LOCATION[21]="/updates/dkms" +DEST_MODULE_LOCATION[22]="/updates/dkms" +DEST_MODULE_LOCATION[23]="/updates/dkms" +DEST_MODULE_LOCATION[24]="/updates/dkms" +DEST_MODULE_LOCATION[25]="/updates/dkms" From fd9ff7d1875b854120984e2c86a25598f039932c Mon Sep 17 00:00:00 2001 From: Zenm Chen Date: Mon, 22 Jul 2024 22:41:58 +0800 Subject: [PATCH 006/193] Blacklist in-kernel rtw88 driver after installation --- Makefile | 1 + blacklist-rtw88.conf | 23 +++++++++++++++++++++++ dkms.conf | 1 + dkms/post_install.sh | 5 +++++ 4 files changed, 30 insertions(+) create mode 100644 blacklist-rtw88.conf create mode 100755 dkms/post_install.sh diff --git a/Makefile b/Makefile index 54ec968a..c97133b3 100644 --- a/Makefile +++ b/Makefile @@ -168,6 +168,7 @@ all: install: all @install -D -m 644 -t $(MODDESTDIR) *.ko @install -D -m 644 -t $(FIRMWAREDIR) firmware/*.bin + @install -D -m 644 -t /etc/modprobe.d blacklist-rtw88.conf ifeq ($(COMPRESS_GZIP), y) @gzip -f $(MODDESTDIR)/*.ko diff --git a/blacklist-rtw88.conf b/blacklist-rtw88.conf new file mode 100644 index 00000000..40a72a00 --- /dev/null +++ b/blacklist-rtw88.conf @@ -0,0 +1,23 @@ +blacklist rtw88_8703b +blacklist rtw88_8723cs +blacklist rtw88_8723d +blacklist rtw88_8723de +blacklist rtw88_8723ds +blacklist rtw88_8723du +blacklist rtw88_8723x +blacklist rtw88_8821c +blacklist rtw88_8821ce +blacklist rtw88_8821cs +blacklist rtw88_8821cu +blacklist rtw88_8822b +blacklist rtw88_8822be +blacklist rtw88_8822bs +blacklist rtw88_8822bu +blacklist rtw88_8822c +blacklist rtw88_8822ce +blacklist rtw88_8822cs +blacklist rtw88_8822cu +blacklist rtw88_core +blacklist rtw88_pci +blacklist rtw88_sdio +blacklist rtw88_usb diff --git a/dkms.conf b/dkms.conf index bbd65609..8c8efab4 100644 --- a/dkms.conf +++ b/dkms.conf @@ -2,6 +2,7 @@ PACKAGE_NAME="rtw88" PACKAGE_VERSION="0.6" MAKE="KVER=${kernelver} 'make' all" CLEAN="KVER=${kernelver} 'make' clean" +POST_INSTALL="dkms/post_install.sh" AUTOINSTALL=yes BUILT_MODULE_NAME[0]="rtw_8703b" BUILT_MODULE_NAME[1]="rtw_8723cs" diff --git a/dkms/post_install.sh b/dkms/post_install.sh new file mode 100755 index 00000000..40703bec --- /dev/null +++ b/dkms/post_install.sh @@ -0,0 +1,5 @@ +#! /bin/sh + +install -D -m 644 -t /etc/modprobe.d blacklist-rtw88.conf + +exit 0 From acafbf7e5d94f674f0e905b32dd4c5742dcd16d7 Mon Sep 17 00:00:00 2001 From: Zenm Chen Date: Wed, 24 Jul 2024 23:14:08 +0800 Subject: [PATCH 007/193] Simplify the uninstall target in Makefile The leading sign "-" will tell make to ignore the exit staus of the command so that uninstallation wouldn't stop for any reason. --- Makefile | 39 +++++++++------------------------------ README.md | 10 ++++++++++ 2 files changed, 19 insertions(+), 30 deletions(-) diff --git a/Makefile b/Makefile index c97133b3..af5f779d 100644 --- a/Makefile +++ b/Makefile @@ -181,38 +181,17 @@ ifeq ($(COMPRESS_ZSTD), y) endif @depmod $(DEPMOD_ARGS) -a $(KVER) - @echo "The driver rtw88 and its firmware installed successfully!" + @echo "The driver rtw88 and its firmware were installed successfully!" uninstall: - modprobe -r rtw_8723cs -ifeq ($(CONFIG_PCI), y) - modprobe -r rtw_8723de -endif - modprobe -r rtw_8723ds - modprobe -r rtw_8723du - modprobe -r rtw_8812au - modprobe -r rtw_8821au -ifeq ($(CONFIG_PCI), y) - modprobe -r rtw_8821ce -endif - modprobe -r rtw_8821cs - modprobe -r rtw_8821cu -ifeq ($(CONFIG_PCI), y) - modprobe -r rtw_8822be -endif - modprobe -r rtw_8822bs - modprobe -r rtw_8822bu -ifeq ($(CONFIG_PCI), y) - modprobe -r rtw_8822ce -endif - modprobe -r rtw_8822cs - modprobe -r rtw_8822cu - - rm -f $(MODDESTDIR)/rtw_*.ko* - - depmod $(DEPMOD_ARGS) - - @echo "Uninstall rtw88 SUCCESS" + @-rmmod -s rtw_8723{cs,de,ds,du} rtw_8812au rtw_8821{au,ce,cs,cu} rtw_8822{b{e,s,u},c{e,s,u}} + @-rmmod -s rtw_8703b rtw_8723d rtw_8821{a,c} rtw_8822{b,c} + @-rmmod -s rtw_{8723x,pci,sdio,usb} + @-rmmod -s rtw_core + @rm -vf $(MODDESTDIR)/rtw_*.ko* + @rm -vf /etc/modprobe.d/blacklist-rtw88.conf + @depmod $(DEPMOD_ARGS) + @echo "The driver rtw88 was removed successfully." clean: $(MAKE) -C $(KSRC) M=$$PWD clean diff --git a/README.md b/README.md index 6369259c..87c79765 100644 --- a/README.md +++ b/README.md @@ -241,3 +241,13 @@ Yes, this repository provides a way to sign the kernel modules to be compatible ### Q5: My card isn't listed. Can I request a feature? For feature requests like supporting a new card, you should reach out to Realtek engineers via E-mail at [linux-wireless@vger.kernel.org](mailto:linux-wireless@vger.kernel.org). + +--- + +### Q6: How to remove this driver if it doesn't work as expected? +Run this command in the rtw88 source directory and then the rtw88 driver will be unloaded and removed. + +`sudo make -s uninstall` + +--- + From f80a60b04766227829dcc43892a63414e1f608fb Mon Sep 17 00:00:00 2001 From: morrownr <69053122+morrownr@users.noreply.github.com> Date: Fri, 9 Aug 2024 15:20:00 -0500 Subject: [PATCH 008/193] Update Makefile Very minor English language mods. --- Makefile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Makefile b/Makefile index af5f779d..0f11d86a 100644 --- a/Makefile +++ b/Makefile @@ -181,7 +181,7 @@ ifeq ($(COMPRESS_ZSTD), y) endif @depmod $(DEPMOD_ARGS) -a $(KVER) - @echo "The driver rtw88 and its firmware were installed successfully!" + @echo "The rtw88 drivers and firmware files were installed successfully." uninstall: @-rmmod -s rtw_8723{cs,de,ds,du} rtw_8812au rtw_8821{au,ce,cs,cu} rtw_8822{b{e,s,u},c{e,s,u}} @@ -191,7 +191,7 @@ uninstall: @rm -vf $(MODDESTDIR)/rtw_*.ko* @rm -vf /etc/modprobe.d/blacklist-rtw88.conf @depmod $(DEPMOD_ARGS) - @echo "The driver rtw88 was removed successfully." + @echo "The rtw88 drivers were removed successfully." clean: $(MAKE) -C $(KSRC) M=$$PWD clean From 9a3e610b2e9e2adb98132e9b8340f3245fee5e9f Mon Sep 17 00:00:00 2001 From: morrownr <69053122+morrownr@users.noreply.github.com> Date: Fri, 9 Aug 2024 17:56:01 -0500 Subject: [PATCH 009/193] Update blacklist-rtw88.conf for new 8821au and 8812au drivers Since the rtw88_8812au and rtw88_8821au drivers will be going into mainline soon, we should blacklist them now so that we do not forget. --- blacklist-rtw88.conf | 3 +++ 1 file changed, 3 insertions(+) diff --git a/blacklist-rtw88.conf b/blacklist-rtw88.conf index 40a72a00..b57816d3 100644 --- a/blacklist-rtw88.conf +++ b/blacklist-rtw88.conf @@ -5,6 +5,9 @@ blacklist rtw88_8723de blacklist rtw88_8723ds blacklist rtw88_8723du blacklist rtw88_8723x +blacklist rtw88_8812au +blacklist rtw88_8821a +blacklist rtw88_8821a blacklist rtw88_8821c blacklist rtw88_8821ce blacklist rtw88_8821cs From a41b1232335601eb4207d61cf989d1abf2e6bc5e Mon Sep 17 00:00:00 2001 From: morrownr <69053122+morrownr@users.noreply.github.com> Date: Fri, 9 Aug 2024 17:57:35 -0500 Subject: [PATCH 010/193] Update blacklist-rtw88.conf to correct for typo Added rtw88_8821a twice and left rtw88_8821au out. This is fixed now. --- blacklist-rtw88.conf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/blacklist-rtw88.conf b/blacklist-rtw88.conf index b57816d3..820668cf 100644 --- a/blacklist-rtw88.conf +++ b/blacklist-rtw88.conf @@ -7,7 +7,7 @@ blacklist rtw88_8723du blacklist rtw88_8723x blacklist rtw88_8812au blacklist rtw88_8821a -blacklist rtw88_8821a +blacklist rtw88_8821au blacklist rtw88_8821c blacklist rtw88_8821ce blacklist rtw88_8821cs From 9f5d3a32a16f68886c35e643caf4e833f48f1d5a Mon Sep 17 00:00:00 2001 From: morrownr <69053122+morrownr@users.noreply.github.com> Date: Fri, 9 Aug 2024 18:36:08 -0500 Subject: [PATCH 011/193] Update README.md regarding the new automatic blacklisting This new automatic blacklist works for in-kernel rtw88 driver but not for out-of-kernel vendor drivers. --- README.md | 34 +++------------------------------- 1 file changed, 3 insertions(+), 31 deletions(-) diff --git a/README.md b/README.md index 87c79765..7f6d1510 100644 --- a/README.md +++ b/README.md @@ -11,35 +11,15 @@ Compatible with **Linux kernel versions 5.4 and newer** as long as your distro hasn't modified any kernel APIs. RHEL and all distros based on RHEL will have modified kernel APIs and are unlikely to be compatible with this driver. + #### Supported Chipsets - **USB** : RTW8812AU, RTW8821AU, RTW8811AU, RTW8822BU, RTW8812BU, RTW8822CU, RTW8821CU, RTW8811CU, RTW8723DU - **PCIe**: RTW8822BE, RTW8822CE, RTW8821CE, RTW8723DE - **SDIO**: RTW8822BS, RTW8822CS, RTW8821CS, RTW8723DS -**Are you looking for support for these drivers?** 🔎 ⚠️ -```bash -# We do not support the following: -RTL8188EE -RTL8192CE -RTL8192CU -RTL8192DE -RTL8192EE -RTL8192SE -RTL8723AE -RTL8723BE -RTL8821AE -``` -Check your current kernel or visit the [Backports Project](https://backports.wiki.kernel.org/index.php/Main_Page). - -## Troubleshooting & Support - -These drivers **won't build for kernels older than 5.4**. Submit GitHub issues **only** for build errors. - -For operational problems, reach out to Realtek engineers via E-mail at [linux-wireless@vger.kernel.org](mailto:linux-wireless@vger.kernel.org). ## Issues 🚨 -Report any build problems and [see the FAQ](#faq) at bottom of this README. - +Report problems in Issues after you have checked the [FAQ](#faq) at bottom of this README. ⚠️ If you see a line such as: `make[1]: *** /lib/modules/5.17.5-300.fc36.x86_64/build: No such file or directory.` **Stop.** @@ -142,15 +122,7 @@ sudo mokutil --reset Below is important information for using this driver. ### 1. Blacklisting 🚫 -If your system has ANY conflicting drivers installed, you must blacklist them as well. For kernels -5.6 and newer, this will include drivers such as rtw88_xxxx. Here is a useful [link](https://askubuntu.com/questions/110341/how-to-blacklist-kernel-modules) on how to blacklist a module. - -Once you have reached this point, then reboot. Use the command `lsmod | grep rtw` and check if there are any -conflicting drivers. The correct ones are: -- `rtw_8723de rtw_8723du rtw_8723d rtw_8822be rtw_8822bu rtw8822bs rtw_8822b rtw_8822ce rtw_8822cu rtw_8822cs - rtw_8821ce rtw_8821cu rtw_8821cs rtw_8822c rtw_8723ds rtw_core rtw_pci` - -If you have other modules installed, see if you blacklisted them correctly. +A file called `blacklist-rtw88.conf` will be installed into `/etc/modprobe.d` when you run `sudo make install`. It will blacklist all in-kernel rtw88 drivers, however, it will not blacklist out-of-kernel vendor drivers. You will need to uninstall any out-of-kernel vendor drivers that you have installed that may conflict. `blacklist-rtw88.conf` will be removed when you run `sudo make uninstall`. ### 2. Recovery Problems After Sleep/Hibernation 🛌 Some BIOSs have trouble changing power state from D3hot to D0. If you have this problem, then: From d320202e2b86310a410ed76e4d7010913dbf0673 Mon Sep 17 00:00:00 2001 From: Zenm Chen Date: Sat, 10 Aug 2024 12:43:30 +0800 Subject: [PATCH 012/193] Suppress error messages when running 'sudo make uninstall' --- Makefile | 8 ++++---- README.md | 3 +-- 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/Makefile b/Makefile index 0f11d86a..416a2221 100644 --- a/Makefile +++ b/Makefile @@ -184,10 +184,10 @@ endif @echo "The rtw88 drivers and firmware files were installed successfully." uninstall: - @-rmmod -s rtw_8723{cs,de,ds,du} rtw_8812au rtw_8821{au,ce,cs,cu} rtw_8822{b{e,s,u},c{e,s,u}} - @-rmmod -s rtw_8703b rtw_8723d rtw_8821{a,c} rtw_8822{b,c} - @-rmmod -s rtw_{8723x,pci,sdio,usb} - @-rmmod -s rtw_core + @rmmod -s rtw_8723{cs,de,ds,du} rtw_8812au rtw_8821{au,ce,cs,cu} rtw_8822{b{e,s,u},c{e,s,u}} || true + @rmmod -s rtw_8703b rtw_8723d rtw_8821{a,c} rtw_8822{b,c} || true + @rmmod -s rtw_{8723x,pci,sdio,usb} || true + @rmmod -s rtw_core || true @rm -vf $(MODDESTDIR)/rtw_*.ko* @rm -vf /etc/modprobe.d/blacklist-rtw88.conf @depmod $(DEPMOD_ARGS) diff --git a/README.md b/README.md index 7f6d1510..d15615fd 100644 --- a/README.md +++ b/README.md @@ -219,7 +219,6 @@ For feature requests like supporting a new card, you should reach out to Realtek ### Q6: How to remove this driver if it doesn't work as expected? Run this command in the rtw88 source directory and then the rtw88 driver will be unloaded and removed. -`sudo make -s uninstall` +`sudo make uninstall` ---- From f589fb82a8b0a5126e5ee70cc0ef9abc979c5fab Mon Sep 17 00:00:00 2001 From: Zenm Chen Date: Sun, 11 Aug 2024 06:26:25 +0800 Subject: [PATCH 013/193] Fix module unloading when removing the driver On Debian/Ubuntu and some other distros, the recipes in Makefile are executed by dash shell which doesn't support brace expansion, and this causes the modules won't be unloaded when removing the driver, so in this commit we use another way to unload them. --- Makefile | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/Makefile b/Makefile index 416a2221..574c95b6 100644 --- a/Makefile +++ b/Makefile @@ -2,6 +2,11 @@ SHELL := /bin/sh KVER ?= $(if $(KERNELRELEASE),$(KERNELRELEASE),$(shell uname -r)) KSRC ?= $(if $(KERNEL_SRC),$(KERNEL_SRC),/lib/modules/$(KVER)/build) FIRMWAREDIR := /lib/firmware/rtw88 +MODLIST := rtw_8723cs rtw_8723de rtw_8723ds rtw_8723du \ + rtw_8812au rtw_8821au rtw_8821ce rtw_8821cs rtw_8821cu \ + rtw_8822be rtw_8822bs rtw_8822bu rtw_8822ce rtw_8822cs rtw_8822cu \ + rtw_8703b rtw_8723d rtw_8821a rtw_8821c rtw_8822b rtw_8822c \ + rtw_8723x rtw_pci rtw_sdio rtw_usb rtw_core # Handle the move of the entire rtw88 tree ifneq ("","$(wildcard /lib/modules/$(KVER)/kernel/drivers/net/wireless/realtek)") MODDESTDIR := /lib/modules/$(KVER)/kernel/drivers/net/wireless/realtek/rtw88 @@ -184,10 +189,9 @@ endif @echo "The rtw88 drivers and firmware files were installed successfully." uninstall: - @rmmod -s rtw_8723{cs,de,ds,du} rtw_8812au rtw_8821{au,ce,cs,cu} rtw_8822{b{e,s,u},c{e,s,u}} || true - @rmmod -s rtw_8703b rtw_8723d rtw_8821{a,c} rtw_8822{b,c} || true - @rmmod -s rtw_{8723x,pci,sdio,usb} || true - @rmmod -s rtw_core || true + @for mod in $(MODLIST); do \ + rmmod -s $$mod || true; \ + done @rm -vf $(MODDESTDIR)/rtw_*.ko* @rm -vf /etc/modprobe.d/blacklist-rtw88.conf @depmod $(DEPMOD_ARGS) From f032993c0ee6d1ad61346b9d2c39d9cc4af6d010 Mon Sep 17 00:00:00 2001 From: morrownr <69053122+morrownr@users.noreply.github.com> Date: Thu, 22 Aug 2024 14:58:39 -0500 Subject: [PATCH 014/193] Update rtw8812au.c to update copyright year Final check and update prior to upstream. --- rtw8812au.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rtw8812au.c b/rtw8812au.c index 8763d133..c62a8b05 100644 --- a/rtw8812au.c +++ b/rtw8812au.c @@ -1,5 +1,5 @@ // SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause -/* Copyright(c) 2018-2019 Realtek Corporation +/* Copyright(c) 2018-2024 Realtek Corporation */ #include From 764a1ee307d7e5720a93b8139c94d76737eced91 Mon Sep 17 00:00:00 2001 From: morrownr <69053122+morrownr@users.noreply.github.com> Date: Thu, 22 Aug 2024 14:59:34 -0500 Subject: [PATCH 015/193] Update rtw8821au.c to update copyright year Final check and update prior to upstream. --- rtw8821au.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rtw8821au.c b/rtw8821au.c index a3951222..3d3334df 100644 --- a/rtw8821au.c +++ b/rtw8821au.c @@ -1,5 +1,5 @@ // SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause -/* Copyright(c) 2018-2019 Realtek Corporation +/* Copyright(c) 2018-2024 Realtek Corporation */ #include From 8742be693a8a47b0bdfca3cc015f98627952fc30 Mon Sep 17 00:00:00 2001 From: Bitterblue Smith Date: Wed, 2 Oct 2024 00:13:13 +0300 Subject: [PATCH 016/193] Fix USB RX aggregation That's not supposed to be there. Fixes slow download with RTL8822BU in USB 3 mode. https://github.com/lwfinger/rtw88/issues/224 Signed-off-by: Bitterblue Smith --- rtw8821c.c | 1 - rtw8822b.c | 1 - rtw8822c.c | 1 - 3 files changed, 3 deletions(-) diff --git a/rtw8821c.c b/rtw8821c.c index 51b810b6..29808f82 100644 --- a/rtw8821c.c +++ b/rtw8821c.c @@ -1282,7 +1282,6 @@ static void rtw8821c_rx_aggregation(struct rtw_dev *rtwdev, bool enable) u8 size, timeout; u16 val16; - rtw_write32_set(rtwdev, REG_RXDMA_AGG_PG_TH, BIT_EN_PRE_CALC); rtw_write8_set(rtwdev, REG_TXDMA_PQ_MAP, BIT_RXDMA_AGG_EN); rtw_write8_clr(rtwdev, REG_RXDMA_AGG_PG_TH + 3, BIT(7)); diff --git a/rtw8822b.c b/rtw8822b.c index a4ad5544..b114011b 100644 --- a/rtw8822b.c +++ b/rtw8822b.c @@ -1643,7 +1643,6 @@ static void rtw8822b_rx_aggregation(struct rtw_dev *rtwdev, bool enable) u8 size, timeout; u16 val16; - rtw_write32_set(rtwdev, REG_RXDMA_AGG_PG_TH, BIT_EN_PRE_CALC); rtw_write8_set(rtwdev, REG_TXDMA_PQ_MAP, BIT_RXDMA_AGG_EN); rtw_write8_clr(rtwdev, REG_RXDMA_AGG_PG_TH + 3, BIT(7)); diff --git a/rtw8822c.c b/rtw8822c.c index 4e72fe05..750027e5 100644 --- a/rtw8822c.c +++ b/rtw8822c.c @@ -4617,7 +4617,6 @@ static void rtw8822c_rx_aggregation(struct rtw_dev *rtwdev, bool enable) u8 size, timeout; u16 val16; - rtw_write32_set(rtwdev, REG_RXDMA_AGG_PG_TH, BIT_EN_PRE_CALC); rtw_write8_set(rtwdev, REG_TXDMA_PQ_MAP, BIT_RXDMA_AGG_EN); rtw_write8_clr(rtwdev, REG_RXDMA_AGG_PG_TH + 3, BIT(7)); From d528d7d22601d4f4e46402be5c059b096f4b46b8 Mon Sep 17 00:00:00 2001 From: Bitterblue Smith Date: Sun, 13 Oct 2024 17:45:02 +0300 Subject: [PATCH 017/193] wifi: rtw88: Un-embed dummy device Upstream commit d0bcb10e7b94861c714ab1e62c98bf8abaa37527. Embedding net_device into structures prohibits the usage of flexible arrays in the net_device structure. For more details, see the discussion at [1]. Un-embed the net_device from the private struct by converting it into a pointer. Then use the leverage the new alloc_netdev_dummy() helper to allocate and initialize dummy devices. [1] https://lore.kernel.org/all/20240229225910.79e224cf@kernel.org/ Tested with RTL8723DE and RTL8822CE. Signed-off-by: Breno Leitao Acked-by: Ping-Ke Shih Tested-by: Ping-Ke Shih Signed-off-by: Ping-Ke Shih Link: https://msgid.link/20240425082910.2824393-1-leitao@debian.org --- pci.c | 33 ++++++++++++++++++++++++++------- pci.h | 4 ++++ 2 files changed, 30 insertions(+), 7 deletions(-) diff --git a/pci.c b/pci.c index 02ccbeed..5f8fa6ea 100644 --- a/pci.c +++ b/pci.c @@ -1686,17 +1686,29 @@ static int rtw_pci_napi_poll(struct napi_struct *napi, int budget) return work_done; } -static void rtw_pci_napi_init(struct rtw_dev *rtwdev) +static int rtw_pci_napi_init(struct rtw_dev *rtwdev) { struct rtw_pci *rtwpci = (struct rtw_pci *)rtwdev->priv; - init_dummy_netdev(&rtwpci->netdev); -#if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 1, 0) - netif_napi_add(&rtwpci->netdev, &rtwpci->napi, rtw_pci_napi_poll); +#if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 11, 0) + rtwpci->netdev = alloc_netdev_dummy(0); + if (!rtwpci->netdev) + return -ENOMEM; + + netif_napi_add( + rtwpci->netdev #else - netif_napi_add(&rtwpci->netdev, &rtwpci->napi, rtw_pci_napi_poll, - NAPI_POLL_WEIGHT); + init_dummy_netdev(&rtwpci->netdev); + netif_napi_add( + &rtwpci->netdev +#endif + , &rtwpci->napi + , rtw_pci_napi_poll +#if LINUX_VERSION_CODE < KERNEL_VERSION(6, 1, 0) + , NAPI_POLL_WEIGHT #endif + ); + return 0; } static void rtw_pci_napi_deinit(struct rtw_dev *rtwdev) @@ -1705,6 +1717,9 @@ static void rtw_pci_napi_deinit(struct rtw_dev *rtwdev) rtw_pci_napi_stop(rtwdev); netif_napi_del(&rtwpci->napi); +#if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 11, 0) + free_netdev(rtwpci->netdev); +#endif } int rtw_pci_probe(struct pci_dev *pdev, @@ -1754,7 +1769,11 @@ int rtw_pci_probe(struct pci_dev *pdev, goto err_pci_declaim; } - rtw_pci_napi_init(rtwdev); + ret = rtw_pci_napi_init(rtwdev); + if (ret) { + rtw_err(rtwdev, "failed to setup NAPI\n"); + goto err_pci_declaim; + } ret = rtw_chip_info_setup(rtwdev); if (ret) { diff --git a/pci.h b/pci.h index 0c37efd8..c2134484 100644 --- a/pci.h +++ b/pci.h @@ -215,7 +215,11 @@ struct rtw_pci { bool running; /* napi structure */ +#if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 11, 0) + struct net_device *netdev; +#else struct net_device netdev; +#endif struct napi_struct napi; u16 rx_tag; From 7b64dfcb873b55a8a1eb1e526523379371db5cb6 Mon Sep 17 00:00:00 2001 From: Bitterblue Smith Date: Sun, 13 Oct 2024 17:59:54 +0300 Subject: [PATCH 018/193] wifi: rtw88: debugfs: support multiple adapters debugging Upstream commit 8db6c1ca64664ef9b071e6eeb646023ac5b240a8. Originally in order to read partial registers from large area, we write a range value stored into a static variable and read registers according to the static variable. However, if we install more than one adapters supported by this driver, the static variables will be overwritten by latter adapters. To resolve the problem, move the static variables to struct rtw_dev for each adapter. With changes, smatch spends too much time to parse rtw_debugfs_init(): debug.c:1289 rtw_debugfs_init() parse error: turning off implications after 60 seconds Move stuffs of adding debugfs entries to three rtw_debugfs_add_xxx() functions. Reported-by: Bitterblue Smith Closes: https://lore.kernel.org/linux-wireless/cd6a2acf3c2c36d938b40140b52a779516f446a9.camel@realtek.com/T/#m27662022c70d9f893ba96f6c6a8dd8fce2434dfe Tested-by: Bitterblue Smith Signed-off-by: Ping-Ke Shih Link: https://patch.msgid.link/20240718064155.38955-1-pkshih@realtek.com --- debug.c | 303 ++++++++++++++++++++++++++++++++------------------------ debug.h | 2 + main.c | 1 + main.h | 3 +- 4 files changed, 180 insertions(+), 129 deletions(-) diff --git a/debug.c b/debug.c index 6688b155..364ec043 100644 --- a/debug.c +++ b/debug.c @@ -43,6 +43,62 @@ struct rtw_debugfs_priv { }; }; +struct rtw_debugfs { + struct rtw_debugfs_priv mac_0; + struct rtw_debugfs_priv mac_1; + struct rtw_debugfs_priv mac_2; + struct rtw_debugfs_priv mac_3; + struct rtw_debugfs_priv mac_4; + struct rtw_debugfs_priv mac_5; + struct rtw_debugfs_priv mac_6; + struct rtw_debugfs_priv mac_7; + struct rtw_debugfs_priv mac_10; + struct rtw_debugfs_priv mac_11; + struct rtw_debugfs_priv mac_12; + struct rtw_debugfs_priv mac_13; + struct rtw_debugfs_priv mac_14; + struct rtw_debugfs_priv mac_15; + struct rtw_debugfs_priv mac_16; + struct rtw_debugfs_priv mac_17; + struct rtw_debugfs_priv bb_8; + struct rtw_debugfs_priv bb_9; + struct rtw_debugfs_priv bb_a; + struct rtw_debugfs_priv bb_b; + struct rtw_debugfs_priv bb_c; + struct rtw_debugfs_priv bb_d; + struct rtw_debugfs_priv bb_e; + struct rtw_debugfs_priv bb_f; + struct rtw_debugfs_priv bb_18; + struct rtw_debugfs_priv bb_19; + struct rtw_debugfs_priv bb_1a; + struct rtw_debugfs_priv bb_1b; + struct rtw_debugfs_priv bb_1c; + struct rtw_debugfs_priv bb_1d; + struct rtw_debugfs_priv bb_1e; + struct rtw_debugfs_priv bb_1f; + struct rtw_debugfs_priv bb_2c; + struct rtw_debugfs_priv bb_2d; + struct rtw_debugfs_priv bb_40; + struct rtw_debugfs_priv bb_41; + struct rtw_debugfs_priv rf_dump; + struct rtw_debugfs_priv tx_pwr_tbl; + struct rtw_debugfs_priv write_reg; + struct rtw_debugfs_priv h2c; + struct rtw_debugfs_priv rf_write; + struct rtw_debugfs_priv rf_read; + struct rtw_debugfs_priv read_reg; + struct rtw_debugfs_priv fix_rate; + struct rtw_debugfs_priv dump_cam; + struct rtw_debugfs_priv rsvd_page; + struct rtw_debugfs_priv phy_info; + struct rtw_debugfs_priv coex_enable; + struct rtw_debugfs_priv coex_info; + struct rtw_debugfs_priv edcca_enable; + struct rtw_debugfs_priv fw_crash; + struct rtw_debugfs_priv force_lowest_basic_rate; + struct rtw_debugfs_priv dm_cap; +}; + static const char * const rtw_dm_cap_strs[] = { [RTW_DM_CAP_NA] = "NA", [RTW_DM_CAP_TXGAPK] = "TXGAPK", @@ -524,7 +580,7 @@ static int rtw_debug_get_bb_page(struct seq_file *m, void *v) return 0; } -static int rtw_debug_get_rf_dump(struct seq_file *m, void *v) +static int rtw_debugfs_get_rf_dump(struct seq_file *m, void *v) { struct rtw_debugfs_priv *debugfs_priv = m->private; struct rtw_dev *rtwdev = debugfs_priv->rtwdev; @@ -1074,139 +1130,102 @@ static int rtw_debugfs_get_dm_cap(struct seq_file *m, void *v) return 0; } -#define rtw_debug_impl_mac(page, addr) \ -static struct rtw_debugfs_priv rtw_debug_priv_mac_ ##page = { \ +#define rtw_debug_priv_mac(addr) \ +{ \ .cb_read = rtw_debug_get_mac_page, \ .cb_data = addr, \ } -rtw_debug_impl_mac(0, 0x0000); -rtw_debug_impl_mac(1, 0x0100); -rtw_debug_impl_mac(2, 0x0200); -rtw_debug_impl_mac(3, 0x0300); -rtw_debug_impl_mac(4, 0x0400); -rtw_debug_impl_mac(5, 0x0500); -rtw_debug_impl_mac(6, 0x0600); -rtw_debug_impl_mac(7, 0x0700); -rtw_debug_impl_mac(10, 0x1000); -rtw_debug_impl_mac(11, 0x1100); -rtw_debug_impl_mac(12, 0x1200); -rtw_debug_impl_mac(13, 0x1300); -rtw_debug_impl_mac(14, 0x1400); -rtw_debug_impl_mac(15, 0x1500); -rtw_debug_impl_mac(16, 0x1600); -rtw_debug_impl_mac(17, 0x1700); - -#define rtw_debug_impl_bb(page, addr) \ -static struct rtw_debugfs_priv rtw_debug_priv_bb_ ##page = { \ +#define rtw_debug_priv_bb(addr) \ +{ \ .cb_read = rtw_debug_get_bb_page, \ .cb_data = addr, \ } -rtw_debug_impl_bb(8, 0x0800); -rtw_debug_impl_bb(9, 0x0900); -rtw_debug_impl_bb(a, 0x0a00); -rtw_debug_impl_bb(b, 0x0b00); -rtw_debug_impl_bb(c, 0x0c00); -rtw_debug_impl_bb(d, 0x0d00); -rtw_debug_impl_bb(e, 0x0e00); -rtw_debug_impl_bb(f, 0x0f00); -rtw_debug_impl_bb(18, 0x1800); -rtw_debug_impl_bb(19, 0x1900); -rtw_debug_impl_bb(1a, 0x1a00); -rtw_debug_impl_bb(1b, 0x1b00); -rtw_debug_impl_bb(1c, 0x1c00); -rtw_debug_impl_bb(1d, 0x1d00); -rtw_debug_impl_bb(1e, 0x1e00); -rtw_debug_impl_bb(1f, 0x1f00); -rtw_debug_impl_bb(2c, 0x2c00); -rtw_debug_impl_bb(2d, 0x2d00); -rtw_debug_impl_bb(40, 0x4000); -rtw_debug_impl_bb(41, 0x4100); - -static struct rtw_debugfs_priv rtw_debug_priv_rf_dump = { - .cb_read = rtw_debug_get_rf_dump, -}; - -static struct rtw_debugfs_priv rtw_debug_priv_tx_pwr_tbl = { - .cb_read = rtw_debugfs_get_tx_pwr_tbl, -}; - -static struct rtw_debugfs_priv rtw_debug_priv_write_reg = { - .cb_write = rtw_debugfs_set_write_reg, -}; - -static struct rtw_debugfs_priv rtw_debug_priv_h2c = { - .cb_write = rtw_debugfs_set_h2c, -}; - -static struct rtw_debugfs_priv rtw_debug_priv_rf_write = { - .cb_write = rtw_debugfs_set_rf_write, -}; - -static struct rtw_debugfs_priv rtw_debug_priv_rf_read = { - .cb_write = rtw_debugfs_set_rf_read, - .cb_read = rtw_debugfs_get_rf_read, -}; - -static struct rtw_debugfs_priv rtw_debug_priv_read_reg = { - .cb_write = rtw_debugfs_set_read_reg, - .cb_read = rtw_debugfs_get_read_reg, -}; - -static struct rtw_debugfs_priv rtw_debug_priv_fix_rate = { - .cb_write = rtw_debugfs_set_fix_rate, - .cb_read = rtw_debugfs_get_fix_rate, -}; - -static struct rtw_debugfs_priv rtw_debug_priv_dump_cam = { - .cb_write = rtw_debugfs_set_single_input, - .cb_read = rtw_debugfs_get_dump_cam, -}; - -static struct rtw_debugfs_priv rtw_debug_priv_rsvd_page = { - .cb_write = rtw_debugfs_set_rsvd_page, - .cb_read = rtw_debugfs_get_rsvd_page, -}; - -static struct rtw_debugfs_priv rtw_debug_priv_phy_info = { - .cb_read = rtw_debugfs_get_phy_info, -}; - -static struct rtw_debugfs_priv rtw_debug_priv_coex_enable = { - .cb_write = rtw_debugfs_set_coex_enable, - .cb_read = rtw_debugfs_get_coex_enable, -}; - -static struct rtw_debugfs_priv rtw_debug_priv_coex_info = { - .cb_read = rtw_debugfs_get_coex_info, -}; +#define rtw_debug_priv_get(name) \ +{ \ + .cb_read = rtw_debugfs_get_ ##name, \ +} -static struct rtw_debugfs_priv rtw_debug_priv_edcca_enable = { - .cb_write = rtw_debugfs_set_edcca_enable, - .cb_read = rtw_debugfs_get_edcca_enable, -}; +#define rtw_debug_priv_set(name) \ +{ \ + .cb_write = rtw_debugfs_set_ ##name, \ +} -static struct rtw_debugfs_priv rtw_debug_priv_fw_crash = { - .cb_write = rtw_debugfs_set_fw_crash, - .cb_read = rtw_debugfs_get_fw_crash, -}; +#define rtw_debug_priv_set_and_get(name) \ +{ \ + .cb_write = rtw_debugfs_set_ ##name, \ + .cb_read = rtw_debugfs_get_ ##name, \ +} -static struct rtw_debugfs_priv rtw_debug_priv_force_lowest_basic_rate = { - .cb_write = rtw_debugfs_set_force_lowest_basic_rate, - .cb_read = rtw_debugfs_get_force_lowest_basic_rate, -}; +#define rtw_debug_priv_set_single_and_get(name) \ +{ \ + .cb_write = rtw_debugfs_set_single_input, \ + .cb_read = rtw_debugfs_get_ ##name, \ +} -static struct rtw_debugfs_priv rtw_debug_priv_dm_cap = { - .cb_write = rtw_debugfs_set_dm_cap, - .cb_read = rtw_debugfs_get_dm_cap, +static const struct rtw_debugfs rtw_debugfs_templ = { + .mac_0 = rtw_debug_priv_mac(0x0000), + .mac_1 = rtw_debug_priv_mac(0x0100), + .mac_2 = rtw_debug_priv_mac(0x0200), + .mac_3 = rtw_debug_priv_mac(0x0300), + .mac_4 = rtw_debug_priv_mac(0x0400), + .mac_5 = rtw_debug_priv_mac(0x0500), + .mac_6 = rtw_debug_priv_mac(0x0600), + .mac_7 = rtw_debug_priv_mac(0x0700), + .mac_10 = rtw_debug_priv_mac(0x1000), + .mac_11 = rtw_debug_priv_mac(0x1100), + .mac_12 = rtw_debug_priv_mac(0x1200), + .mac_13 = rtw_debug_priv_mac(0x1300), + .mac_14 = rtw_debug_priv_mac(0x1400), + .mac_15 = rtw_debug_priv_mac(0x1500), + .mac_16 = rtw_debug_priv_mac(0x1600), + .mac_17 = rtw_debug_priv_mac(0x1700), + .bb_8 = rtw_debug_priv_bb(0x0800), + .bb_9 = rtw_debug_priv_bb(0x0900), + .bb_a = rtw_debug_priv_bb(0x0a00), + .bb_b = rtw_debug_priv_bb(0x0b00), + .bb_c = rtw_debug_priv_bb(0x0c00), + .bb_d = rtw_debug_priv_bb(0x0d00), + .bb_e = rtw_debug_priv_bb(0x0e00), + .bb_f = rtw_debug_priv_bb(0x0f00), + .bb_18 = rtw_debug_priv_bb(0x1800), + .bb_19 = rtw_debug_priv_bb(0x1900), + .bb_1a = rtw_debug_priv_bb(0x1a00), + .bb_1b = rtw_debug_priv_bb(0x1b00), + .bb_1c = rtw_debug_priv_bb(0x1c00), + .bb_1d = rtw_debug_priv_bb(0x1d00), + .bb_1e = rtw_debug_priv_bb(0x1e00), + .bb_1f = rtw_debug_priv_bb(0x1f00), + .bb_2c = rtw_debug_priv_bb(0x2c00), + .bb_2d = rtw_debug_priv_bb(0x2d00), + .bb_40 = rtw_debug_priv_bb(0x4000), + .bb_41 = rtw_debug_priv_bb(0x4100), + .rf_dump = rtw_debug_priv_get(rf_dump), + .tx_pwr_tbl = rtw_debug_priv_get(tx_pwr_tbl), + .write_reg = rtw_debug_priv_set(write_reg), + .h2c = rtw_debug_priv_set(h2c), + .rf_write = rtw_debug_priv_set(rf_write), + .rf_read = rtw_debug_priv_set_and_get(rf_read), + .read_reg = rtw_debug_priv_set_and_get(read_reg), + .fix_rate = rtw_debug_priv_set_and_get(fix_rate), + .dump_cam = rtw_debug_priv_set_single_and_get(dump_cam), + .rsvd_page = rtw_debug_priv_set_and_get(rsvd_page), + .phy_info = rtw_debug_priv_get(phy_info), + .coex_enable = rtw_debug_priv_set_and_get(coex_enable), + .coex_info = rtw_debug_priv_get(coex_info), + .edcca_enable = rtw_debug_priv_set_and_get(edcca_enable), + .fw_crash = rtw_debug_priv_set_and_get(fw_crash), + .force_lowest_basic_rate = rtw_debug_priv_set_and_get(force_lowest_basic_rate), + .dm_cap = rtw_debug_priv_set_and_get(dm_cap), }; #define rtw_debugfs_add_core(name, mode, fopname, parent) \ do { \ - rtw_debug_priv_ ##name.rtwdev = rtwdev; \ + struct rtw_debugfs_priv *priv = &rtwdev->debugfs->name; \ + priv->rtwdev = rtwdev; \ if (IS_ERR(debugfs_create_file(#name, mode, \ - parent, &rtw_debug_priv_ ##name,\ + parent, priv, \ &file_ops_ ##fopname))) \ pr_debug("Unable to initialize debugfs:%s\n", \ #name); \ @@ -1219,12 +1238,9 @@ static struct rtw_debugfs_priv rtw_debug_priv_dm_cap = { #define rtw_debugfs_add_r(name) \ rtw_debugfs_add_core(name, S_IFREG | 0444, single_r, debugfs_topdir) -void rtw_debugfs_init(struct rtw_dev *rtwdev) +static +void rtw_debugfs_add_basic(struct rtw_dev *rtwdev, struct dentry *debugfs_topdir) { - struct dentry *debugfs_topdir; - - debugfs_topdir = debugfs_create_dir("rtw88", - rtwdev->hw->wiphy->debugfsdir); rtw_debugfs_add_w(write_reg); rtw_debugfs_add_rw(read_reg); rtw_debugfs_add_w(rf_write); @@ -1236,6 +1252,17 @@ void rtw_debugfs_init(struct rtw_dev *rtwdev) rtw_debugfs_add_r(coex_info); rtw_debugfs_add_rw(coex_enable); rtw_debugfs_add_w(h2c); + rtw_debugfs_add_r(rf_dump); + rtw_debugfs_add_r(tx_pwr_tbl); + rtw_debugfs_add_rw(edcca_enable); + rtw_debugfs_add_rw(fw_crash); + rtw_debugfs_add_rw(force_lowest_basic_rate); + rtw_debugfs_add_rw(dm_cap); +} + +static +void rtw_debugfs_add_sec0(struct rtw_dev *rtwdev, struct dentry *debugfs_topdir) +{ rtw_debugfs_add_r(mac_0); rtw_debugfs_add_r(mac_1); rtw_debugfs_add_r(mac_2); @@ -1252,6 +1279,11 @@ void rtw_debugfs_init(struct rtw_dev *rtwdev) rtw_debugfs_add_r(bb_d); rtw_debugfs_add_r(bb_e); rtw_debugfs_add_r(bb_f); +} + +static +void rtw_debugfs_add_sec1(struct rtw_dev *rtwdev, struct dentry *debugfs_topdir) +{ rtw_debugfs_add_r(mac_10); rtw_debugfs_add_r(mac_11); rtw_debugfs_add_r(mac_12); @@ -1274,14 +1306,29 @@ void rtw_debugfs_init(struct rtw_dev *rtwdev) rtw_debugfs_add_r(bb_40); rtw_debugfs_add_r(bb_41); } - rtw_debugfs_add_r(rf_dump); - rtw_debugfs_add_r(tx_pwr_tbl); - rtw_debugfs_add_rw(edcca_enable); - rtw_debugfs_add_rw(fw_crash); - rtw_debugfs_add_rw(force_lowest_basic_rate); - rtw_debugfs_add_rw(dm_cap); } +void rtw_debugfs_init(struct rtw_dev *rtwdev) +{ + struct dentry *debugfs_topdir; + + rtwdev->debugfs = kmemdup(&rtw_debugfs_templ, sizeof(rtw_debugfs_templ), + GFP_KERNEL); + if (!rtwdev->debugfs) + return; + + debugfs_topdir = debugfs_create_dir("rtw88", + rtwdev->hw->wiphy->debugfsdir); + + rtw_debugfs_add_basic(rtwdev, debugfs_topdir); + rtw_debugfs_add_sec0(rtwdev, debugfs_topdir); + rtw_debugfs_add_sec1(rtwdev, debugfs_topdir); +} + +void rtw_debugfs_deinit(struct rtw_dev *rtwdev) +{ + kfree(rtwdev->debugfs); +} #endif /* CONFIG_RTW88_DEBUGFS */ #ifdef CONFIG_RTW88_DEBUG diff --git a/debug.h b/debug.h index cbc14885..12d5d304 100644 --- a/debug.h +++ b/debug.h @@ -34,11 +34,13 @@ enum rtw_debug_mask { #ifdef CONFIG_RTW88_DEBUGFS void rtw_debugfs_init(struct rtw_dev *rtwdev); +void rtw_debugfs_deinit(struct rtw_dev *rtwdev); void rtw_debugfs_get_simple_phy_info(struct seq_file *m); #else static inline void rtw_debugfs_init(struct rtw_dev *rtwdev) {} +static inline void rtw_debugfs_deinit(struct rtw_dev *rtwdev) {} #endif /* CONFIG_RTW88_DEBUGFS */ diff --git a/main.c b/main.c index f5f0790c..b6fd231c 100644 --- a/main.c +++ b/main.c @@ -2457,6 +2457,7 @@ void rtw_unregister_hw(struct rtw_dev *rtwdev, struct ieee80211_hw *hw) ieee80211_unregister_hw(hw); rtw_unset_supported_band(hw, chip); + rtw_debugfs_deinit(rtwdev); } EXPORT_SYMBOL(rtw_unregister_hw); diff --git a/main.h b/main.h index d8a9b273..d4eaa5a9 100644 --- a/main.h +++ b/main.h @@ -163,6 +163,7 @@ extern const struct ieee80211_ops rtw_ops; #define RTW_MAX_CHANNEL_NUM_5G 49 struct rtw_dev; +struct rtw_debugfs; enum rtw_hci_type { RTW_HCI_TYPE_PCIE, @@ -2194,7 +2195,7 @@ struct rtw_dev { bool beacon_loss; struct completion lps_leave_check; - struct dentry *debugfs; + struct rtw_debugfs *debugfs; u8 sta_cnt; u32 rts_threshold; From fa950890a05365499c5dea30dd2b8b5de63c6ed8 Mon Sep 17 00:00:00 2001 From: Bitterblue Smith Date: Sun, 13 Oct 2024 18:11:45 +0300 Subject: [PATCH 019/193] wifi: rtw88: 8822c: Parse channel from IE to correct invalid hardware reports Upstream commit 53ed4b25a79aeec5991c2dc579e635b136ef7676. For CCK packets we could get incorrect reports from hardware. And this causes wrong frequencies being reported. Parse the channel information from IE if provided by AP to fix this. Signed-off-by: Po-Hao Huang Signed-off-by: Ping-Ke Shih Link: https://patch.msgid.link/20240724050501.7550-1-pkshih@realtek.com --- main.h | 1 + pci.c | 1 + rtw8822c.c | 7 ++++--- rx.c | 41 +++++++++++++++++++++++++++++++++++++++++ rx.h | 13 +++++++++++++ sdio.c | 1 + usb.c | 3 +++ 7 files changed, 64 insertions(+), 3 deletions(-) diff --git a/main.h b/main.h index d4eaa5a9..fac32763 100644 --- a/main.h +++ b/main.h @@ -738,6 +738,7 @@ struct rtw_rx_pkt_stat { bool crc_err; bool decrypted; bool is_c2h; + bool channel_invalid; s32 signal_power; u16 pkt_len; diff --git a/pci.c b/pci.c index 5f8fa6ea..b02c3592 100644 --- a/pci.c +++ b/pci.c @@ -1088,6 +1088,7 @@ static u32 rtw_pci_rx_napi(struct rtw_dev *rtwdev, struct rtw_pci *rtwpci, /* remove rx_desc */ skb_pull(new, pkt_offset); + rtw_update_rx_freq_for_invalid(rtwdev, new, &rx_status, &pkt_stat); rtw_rx_stats(rtwdev, pkt_stat.vif, new); memcpy(new->cb, &rx_status, sizeof(rx_status)); ieee80211_rx_napi(rtwdev->hw, NULL, new, napi); diff --git a/rtw8822c.c b/rtw8822c.c index 750027e5..92d496c9 100644 --- a/rtw8822c.c +++ b/rtw8822c.c @@ -2598,9 +2598,10 @@ static void query_phy_status_page0(struct rtw_dev *rtwdev, u8 *phy_status, rx_power[RF_PATH_B] -= 110; channel = GET_PHY_STAT_P0_CHANNEL(phy_status); - if (channel == 0) - channel = rtwdev->hal.current_channel; - rtw_set_rx_freq_band(pkt_stat, channel); + if (channel != 0) + rtw_set_rx_freq_band(pkt_stat, channel); + else + pkt_stat->channel_invalid = true; pkt_stat->rx_power[RF_PATH_A] = rx_power[RF_PATH_A]; pkt_stat->rx_power[RF_PATH_B] = rx_power[RF_PATH_B]; diff --git a/rx.c b/rx.c index 35e96ec8..3dd02fa7 100644 --- a/rx.c +++ b/rx.c @@ -146,6 +146,47 @@ static void rtw_set_rx_freq_by_pktstat(struct rtw_rx_pkt_stat *pkt_stat, rx_status->band = pkt_stat->band; } +void rtw_update_rx_freq_from_ie(struct rtw_dev *rtwdev, struct sk_buff *skb, + struct ieee80211_rx_status *rx_status, + struct rtw_rx_pkt_stat *pkt_stat) +{ + struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *)skb->data; + int channel = rtwdev->hal.current_channel; + size_t hdr_len, ielen; + int channel_number; + u8 *variable; + + if (!test_bit(RTW_FLAG_SCANNING, rtwdev->flags)) + goto fill_rx_status; + + if (ieee80211_is_beacon(mgmt->frame_control)) { + variable = mgmt->u.beacon.variable; + hdr_len = offsetof(struct ieee80211_mgmt, + u.beacon.variable); + } else if (ieee80211_is_probe_resp(mgmt->frame_control)) { + variable = mgmt->u.probe_resp.variable; + hdr_len = offsetof(struct ieee80211_mgmt, + u.probe_resp.variable); + } else { + goto fill_rx_status; + } + + if (skb->len > hdr_len) + ielen = skb->len - hdr_len; + else + goto fill_rx_status; + + channel_number = cfg80211_get_ies_channel_number(variable, ielen, + NL80211_BAND_2GHZ); + if (channel_number != -1) + channel = channel_number; + +fill_rx_status: + rtw_set_rx_freq_band(pkt_stat, channel); + rtw_set_rx_freq_by_pktstat(pkt_stat, rx_status); +} +EXPORT_SYMBOL(rtw_update_rx_freq_from_ie); + void rtw_rx_fill_rx_status(struct rtw_dev *rtwdev, struct rtw_rx_pkt_stat *pkt_stat, struct ieee80211_hdr *hdr, diff --git a/rx.h b/rx.h index 8a072dd3..9f001911 100644 --- a/rx.h +++ b/rx.h @@ -50,5 +50,18 @@ void rtw_rx_fill_rx_status(struct rtw_dev *rtwdev, struct ieee80211_hdr *hdr, struct ieee80211_rx_status *rx_status, u8 *phy_status); +void rtw_update_rx_freq_from_ie(struct rtw_dev *rtwdev, struct sk_buff *skb, + struct ieee80211_rx_status *rx_status, + struct rtw_rx_pkt_stat *pkt_stat); + +static inline +void rtw_update_rx_freq_for_invalid(struct rtw_dev *rtwdev, struct sk_buff *skb, + struct ieee80211_rx_status *rx_status, + struct rtw_rx_pkt_stat *pkt_stat) +{ + if (pkt_stat->channel_invalid) + rtw_update_rx_freq_from_ie(rtwdev, skb, rx_status, pkt_stat); +} + #endif diff --git a/sdio.c b/sdio.c index 72d45ad4..8abbbfe7 100644 --- a/sdio.c +++ b/sdio.c @@ -948,6 +948,7 @@ static void rtw_sdio_rx_skb(struct rtw_dev *rtwdev, struct sk_buff *skb, skb_put(skb, pkt_stat->pkt_len); skb_reserve(skb, pkt_offset); + rtw_update_rx_freq_for_invalid(rtwdev, skb, rx_status, pkt_stat); rtw_rx_stats(rtwdev, pkt_stat->vif, skb); ieee80211_rx_irqsafe(rtwdev->hw, skb); diff --git a/usb.c b/usb.c index 3dd1bc53..1f77e933 100644 --- a/usb.c +++ b/usb.c @@ -592,6 +592,9 @@ static void rtw_usb_rx_handler(struct work_struct *work) } else { skb_pull(skb, pkt_offset); skb_trim(skb, pkt_stat.pkt_len); + rtw_update_rx_freq_for_invalid(rtwdev, skb, + &rx_status, + &pkt_stat); rtw_rx_stats(rtwdev, pkt_stat.vif, skb); memcpy(skb->cb, &rx_status, sizeof(rx_status)); ieee80211_rx_irqsafe(rtwdev->hw, skb); From 9bac9462c4579308e466681a0394a549feac81a5 Mon Sep 17 00:00:00 2001 From: Bitterblue Smith Date: Sun, 13 Oct 2024 18:13:55 +0300 Subject: [PATCH 020/193] wifi: rtw88: always wait for both firmware loading attempts Upstream commit 0e735a4c6137262bcefe45bb52fde7b1f5fc6c4d. In 'rtw_wait_firmware_completion()', always wait for both (regular and wowlan) firmware loading attempts. Otherwise if 'rtw_usb_intf_init()' has failed in 'rtw_usb_probe()', 'rtw_usb_disconnect()' may issue 'ieee80211_free_hw()' when one of 'rtw_load_firmware_cb()' (usually the wowlan one) is still in progress, causing UAF detected by KASAN. Fixes: c8e5695 ("rtw88: load wowlan firmware if wowlan is supported") Reported-by: syzbot+6c6c08700f9480c41fe3@syzkaller.appspotmail.com Closes: https://syzkaller.appspot.com/bug?extid=6c6c08700f9480c41fe3 Signed-off-by: Dmitry Antipov Signed-off-by: Ping-Ke Shih Link: https://patch.msgid.link/20240726114657.25396-1-dmantipov@yandex.ru --- main.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/main.c b/main.c index b6fd231c..fba04995 100644 --- a/main.c +++ b/main.c @@ -1437,20 +1437,21 @@ int rtw_wait_firmware_completion(struct rtw_dev *rtwdev) { const struct rtw_chip_info *chip = rtwdev->chip; struct rtw_fw_state *fw; + int ret = 0; fw = &rtwdev->fw; wait_for_completion(&fw->completion); if (!fw->firmware) - return -EINVAL; + ret = -EINVAL; if (chip->wow_fw_name) { fw = &rtwdev->wow_fw; wait_for_completion(&fw->completion); if (!fw->firmware) - return -EINVAL; + ret = -EINVAL; } - return 0; + return ret; } EXPORT_SYMBOL(rtw_wait_firmware_completion); From 197e50615d6a83ff3292ef6df017f719a3690f53 Mon Sep 17 00:00:00 2001 From: Bitterblue Smith Date: Sun, 13 Oct 2024 18:25:01 +0300 Subject: [PATCH 021/193] Revert "wifi: rtw88: Init RX burst length for 8822cu/8822bu/8821cu" This reverts commit 98de16f2f51f21d1ff67821f86b68afc3cf285f3. Will apply the upstream version in the next commit. --- reg.h | 2 -- rtw8821c.c | 22 ---------------------- rtw8822b.c | 22 ---------------------- rtw8822c.c | 22 ---------------------- 4 files changed, 68 deletions(-) diff --git a/reg.h b/reg.h index 788e450d..4d9b8668 100644 --- a/reg.h +++ b/reg.h @@ -709,8 +709,6 @@ #define REG_IGN_GNTBT4 0x4160 -#define REG_USB_USBSTAT 0xFE11 - #define RF_MODE 0x00 #define RF_MODOPT 0x01 #define RF_WLINT 0x01 diff --git a/rtw8821c.c b/rtw8821c.c index 29808f82..e6261916 100644 --- a/rtw8821c.c +++ b/rtw8821c.c @@ -205,25 +205,6 @@ static void rtw8821c_phy_set_param(struct rtw_dev *rtwdev) rtw8821c_phy_bf_init(rtwdev); } -static void rtw8821cu_init_burst_pkt_len(struct rtw_dev *rtwdev) -{ - u8 rxdma, burst_size; - - rxdma = BIT_DMA_BURST_CNT | BIT_DMA_MODE; - - if (rtw_read8(rtwdev, REG_SYS_CFG2 + 3) == 0x20) - burst_size = BIT_DMA_BURST_SIZE_1024; - else if ((rtw_read8(rtwdev, REG_USB_USBSTAT) & 0x3) == 0x1) - burst_size = BIT_DMA_BURST_SIZE_512; - else - burst_size = BIT_DMA_BURST_SIZE_64; - - u8p_replace_bits(&rxdma, burst_size, BIT_DMA_BURST_SIZE); - - rtw_write8(rtwdev, REG_RXDMA_MODE, rxdma); - rtw_write16_set(rtwdev, REG_TXDMA_OFFSET_CHK, BIT_DROP_DATA_EN); -} - static int rtw8821c_mac_init(struct rtw_dev *rtwdev) { u32 value32; @@ -281,9 +262,6 @@ static int rtw8821c_mac_init(struct rtw_dev *rtwdev) rtw_write32(rtwdev, REG_WMAC_OPTION_FUNCTION + 8, WLAN_MAC_OPT_FUNC2); rtw_write8(rtwdev, REG_WMAC_OPTION_FUNCTION + 4, WLAN_MAC_OPT_NORM_FUNC1); - if (rtw_hci_type(rtwdev) == RTW_HCI_TYPE_USB) - rtw8821cu_init_burst_pkt_len(rtwdev); - return 0; } diff --git a/rtw8822b.c b/rtw8822b.c index b114011b..2cea6d39 100644 --- a/rtw8822b.c +++ b/rtw8822b.c @@ -237,25 +237,6 @@ static void rtw8822b_phy_set_param(struct rtw_dev *rtwdev) #define WLAN_NAV_CFG (WLAN_RDG_NAV | (WLAN_TXOP_NAV << 16)) #define WLAN_RX_TSF_CFG (WLAN_CCK_RX_TSF | (WLAN_OFDM_RX_TSF) << 8) -static void rtw8822bu_init_burst_pkt_len(struct rtw_dev *rtwdev) -{ - u8 rxdma, burst_size; - - rxdma = BIT_DMA_BURST_CNT | BIT_DMA_MODE; - - if (rtw_read8(rtwdev, REG_SYS_CFG2 + 3) == 0x20) - burst_size = BIT_DMA_BURST_SIZE_1024; - else if ((rtw_read8(rtwdev, REG_USB_USBSTAT) & 0x3) == 0x1) - burst_size = BIT_DMA_BURST_SIZE_512; - else - burst_size = BIT_DMA_BURST_SIZE_64; - - u8p_replace_bits(&rxdma, burst_size, BIT_DMA_BURST_SIZE); - - rtw_write8(rtwdev, REG_RXDMA_MODE, rxdma); - rtw_write16_set(rtwdev, REG_TXDMA_OFFSET_CHK, BIT_DROP_DATA_EN); -} - static int rtw8822b_mac_init(struct rtw_dev *rtwdev) { u32 value32; @@ -303,9 +284,6 @@ static int rtw8822b_mac_init(struct rtw_dev *rtwdev) rtw_write8_set(rtwdev, REG_SND_PTCL_CTRL, BIT_DIS_CHK_VHTSIGB_CRC); - if (rtw_hci_type(rtwdev) == RTW_HCI_TYPE_USB) - rtw8822bu_init_burst_pkt_len(rtwdev); - return 0; } diff --git a/rtw8822c.c b/rtw8822c.c index 92d496c9..58446327 100644 --- a/rtw8822c.c +++ b/rtw8822c.c @@ -2001,25 +2001,6 @@ static void rtw8822c_phy_set_param(struct rtw_dev *rtwdev) #define MAC_CLK_SPEED 80 /* 80M */ #define EFUSE_PCB_INFO_OFFSET 0xCA -static void rtw8822cu_init_burst_pkt_len(struct rtw_dev *rtwdev) -{ - u8 rxdma, burst_size; - - rxdma = BIT_DMA_BURST_CNT | BIT_DMA_MODE; - - if (rtw_read8(rtwdev, REG_SYS_CFG2 + 3) == 0x20) - burst_size = BIT_DMA_BURST_SIZE_1024; - else if ((rtw_read8(rtwdev, REG_USB_USBSTAT) & 0x3) == 0x1) - burst_size = BIT_DMA_BURST_SIZE_512; - else - burst_size = BIT_DMA_BURST_SIZE_64; - - u8p_replace_bits(&rxdma, burst_size, BIT_DMA_BURST_SIZE); - - rtw_write8(rtwdev, REG_RXDMA_MODE, rxdma); - rtw_write16_set(rtwdev, REG_TXDMA_OFFSET_CHK, BIT_DROP_DATA_EN); -} - static int rtw8822c_mac_init(struct rtw_dev *rtwdev) { u8 value8; @@ -2146,9 +2127,6 @@ static int rtw8822c_mac_init(struct rtw_dev *rtwdev) /* Interrupt migration configuration */ rtw_write32(rtwdev, REG_INT_MIG, WLAN_MAC_INT_MIG_CFG); - if (rtw_hci_type(rtwdev) == RTW_HCI_TYPE_USB) - rtw8822cu_init_burst_pkt_len(rtwdev); - return 0; } From 9e7ceef1d3dd8a26ce14eb0613d60a3d180a9503 Mon Sep 17 00:00:00 2001 From: Bitterblue Smith Date: Sun, 13 Oct 2024 18:32:16 +0300 Subject: [PATCH 022/193] wifi: rtw88: usb: Init RX burst length according to USB speed Upstream commit fbbd8cb347e25b68d25c4f3871821afc495ee7a9. This is needed in order to make USB RX aggregation work with RTL8811CU (and presumably RTL8822BU and RTL8822CU also). I don't know what BIT_DMA_BURST_CNT, BIT_DMA_MODE, and BIT_DROP_DATA_EN are doing. Tested with RTL8822CU, RTL8811CU, and RTL8723DU. The RX speed is unchanged in my tests. Tested-by: Sascha Hauer Signed-off-by: Bitterblue Smith Signed-off-by: Ping-Ke Shih Link: https://patch.msgid.link/ac569c6f-7129-4341-b523-901fe10cabff@gmail.com --- usb.c | 23 ++++++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) diff --git a/usb.c b/usb.c index 1f77e933..5130972e 100644 --- a/usb.c +++ b/usb.c @@ -745,9 +745,30 @@ static void rtw_usb_link_ps(struct rtw_dev *rtwdev, bool enter) /* empty function for rtw_hci_ops */ } +static void rtw_usb_init_burst_pkt_len(struct rtw_dev *rtwdev) +{ + struct rtw_usb *rtwusb = rtw_get_usb_priv(rtwdev); + enum usb_device_speed speed = rtwusb->udev->speed; + u8 rxdma, burst_size; + + rxdma = BIT_DMA_BURST_CNT | BIT_DMA_MODE; + + if (speed == USB_SPEED_SUPER) + burst_size = BIT_DMA_BURST_SIZE_1024; + else if (speed == USB_SPEED_HIGH) + burst_size = BIT_DMA_BURST_SIZE_512; + else + burst_size = BIT_DMA_BURST_SIZE_64; + + u8p_replace_bits(&rxdma, burst_size, BIT_DMA_BURST_SIZE); + + rtw_write8(rtwdev, REG_RXDMA_MODE, rxdma); + rtw_write16_set(rtwdev, REG_TXDMA_OFFSET_CHK, BIT_DROP_DATA_EN); +} + static void rtw_usb_interface_cfg(struct rtw_dev *rtwdev) { - /* empty function for rtw_hci_ops */ + rtw_usb_init_burst_pkt_len(rtwdev); } static struct rtw_hci_ops rtw_usb_ops = { From afe3aefc293407321909290bfa52d0145b6ded07 Mon Sep 17 00:00:00 2001 From: Bitterblue Smith Date: Sun, 13 Oct 2024 21:52:04 +0300 Subject: [PATCH 023/193] Sync the USB RX aggregation with upstream More or less upstream commit 002a5db9a52a0e7af0fa9a450d31049748435748. --- hci.h | 7 ++++++ main.c | 21 +++++++---------- main.h | 1 - pci.c | 1 + rtw8821a.c | 26 -------------------- rtw8821c.c | 22 ----------------- rtw8822b.c | 22 ----------------- rtw8822c.c | 22 ----------------- sdio.c | 1 + usb.c | 69 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 10 files changed, 86 insertions(+), 106 deletions(-) diff --git a/hci.h b/hci.h index 830d7532..96aeda26 100644 --- a/hci.h +++ b/hci.h @@ -18,6 +18,7 @@ struct rtw_hci_ops { void (*deep_ps)(struct rtw_dev *rtwdev, bool enter); void (*link_ps)(struct rtw_dev *rtwdev, bool enter); void (*interface_cfg)(struct rtw_dev *rtwdev); + void (*dynamic_rx_agg)(struct rtw_dev *rtwdev, bool enable); int (*write_data_rsvd_page)(struct rtw_dev *rtwdev, u8 *buf, u32 size); int (*write_data_h2c)(struct rtw_dev *rtwdev, u8 *buf, u32 size); @@ -72,6 +73,12 @@ static inline void rtw_hci_interface_cfg(struct rtw_dev *rtwdev) rtwdev->hci.ops->interface_cfg(rtwdev); } +static inline void rtw_hci_dynamic_rx_agg(struct rtw_dev *rtwdev, bool enable) +{ + if (rtwdev->hci.ops->dynamic_rx_agg) + rtwdev->hci.ops->dynamic_rx_agg(rtwdev, enable); +} + static inline int rtw_hci_write_data_rsvd_page(struct rtw_dev *rtwdev, u8 *buf, u32 size) { diff --git a/main.c b/main.c index fba04995..07452fb5 100644 --- a/main.c +++ b/main.c @@ -216,10 +216,9 @@ static void rtw_watch_dog_work(struct work_struct *work) struct rtw_dev *rtwdev = container_of(work, struct rtw_dev, watch_dog_work.work); struct rtw_traffic_stats *stats = &rtwdev->stats; - const struct rtw_chip_info *chip = rtwdev->chip; struct rtw_watch_dog_iter_data data = {}; bool busy_traffic = test_bit(RTW_FLAG_BUSY_TRAFFIC, rtwdev->flags); - u32 tx_unicast_shift, rx_unicast_shift; + u32 tx_unicast_mbps, rx_unicast_mbps; bool ps_active; mutex_lock(&rtwdev->mutex); @@ -244,21 +243,14 @@ static void rtw_watch_dog_work(struct work_struct *work) else ps_active = false; - tx_unicast_shift = stats->tx_unicast >> RTW_TP_SHIFT; - rx_unicast_shift = stats->rx_unicast >> RTW_TP_SHIFT; + tx_unicast_mbps = stats->tx_unicast >> RTW_TP_SHIFT; + rx_unicast_mbps = stats->rx_unicast >> RTW_TP_SHIFT; - ewma_tp_add(&stats->tx_ewma_tp, tx_unicast_shift); - ewma_tp_add(&stats->rx_ewma_tp, rx_unicast_shift); + ewma_tp_add(&stats->tx_ewma_tp, tx_unicast_mbps); + ewma_tp_add(&stats->rx_ewma_tp, rx_unicast_mbps); stats->tx_throughput = ewma_tp_read(&stats->tx_ewma_tp); stats->rx_throughput = ewma_tp_read(&stats->rx_ewma_tp); - if (rtw_hci_type(rtwdev) == RTW_HCI_TYPE_USB && chip->ops->rx_aggregation) { - if (tx_unicast_shift < 1 && rx_unicast_shift < 1) - chip->ops->rx_aggregation(rtwdev, false); - else - chip->ops->rx_aggregation(rtwdev, true); - } - /* reset tx/rx statictics */ stats->tx_unicast = 0; stats->rx_unicast = 0; @@ -280,6 +272,9 @@ static void rtw_watch_dog_work(struct work_struct *work) rtw_phy_dynamic_mechanism(rtwdev); + rtw_hci_dynamic_rx_agg(rtwdev, + tx_unicast_mbps >= 1 || rx_unicast_mbps >= 1); + data.rtwdev = rtwdev; /* rtw_iterate_vifs internally uses an atomic iterator which is needed * to avoid taking local->iflist_mtx mutex diff --git a/main.h b/main.h index fac32763..a6aedf4d 100644 --- a/main.h +++ b/main.h @@ -1007,7 +1007,6 @@ struct rtw_chip_ops { void (*fill_txdesc_checksum)(struct rtw_dev *rtwdev, struct rtw_tx_pkt_info *pkt_info, u8 *txdesc); - void (*rx_aggregation)(struct rtw_dev *rtwdev, bool enable); /* for coex */ void (*coex_set_init)(struct rtw_dev *rtwdev); diff --git a/pci.c b/pci.c index b02c3592..86a015e3 100644 --- a/pci.c +++ b/pci.c @@ -1601,6 +1601,7 @@ static struct rtw_hci_ops rtw_pci_ops = { .deep_ps = rtw_pci_deep_ps, .link_ps = rtw_pci_link_ps, .interface_cfg = rtw_pci_interface_cfg, + .dynamic_rx_agg = NULL, .read8 = rtw_pci_read8, .read16 = rtw_pci_read16, diff --git a/rtw8821a.c b/rtw8821a.c index 7031ca17..90e4d7fc 100644 --- a/rtw8821a.c +++ b/rtw8821a.c @@ -551,31 +551,6 @@ static void rtw8821au_tx_aggregation(struct rtw_dev *rtwdev) chip->usb_tx_agg_desc_num << 1); } -static void rtw8821au_rx_aggregation(struct rtw_dev *rtwdev, bool enable) -{ - struct rtw_usb *rtwusb = rtw_get_usb_priv(rtwdev); - u8 rxagg_usb_size, rxagg_usb_timeout; - u16 val16; - - if (rtwusb->udev->speed == USB_SPEED_SUPER) { - rxagg_usb_size = 0x7; - rxagg_usb_timeout = 0x1a; - } else { - rxagg_usb_size = 0x5; - rxagg_usb_timeout = 0x20; - } - - if (!enable) { - rxagg_usb_size = 0x0; - rxagg_usb_timeout = 0x1; - } - - val16 = (rxagg_usb_timeout << 8) | rxagg_usb_size; - rtw_write16(rtwdev, REG_RXDMA_AGG_PG_TH, val16); - - rtw_write8_set(rtwdev, REG_TXDMA_PQ_MAP, BIT_RXDMA_AGG_EN); -} - static void rtw8821a_init_beacon_parameters(struct rtw_dev *rtwdev) { u16 val16; @@ -3811,7 +3786,6 @@ static struct rtw_chip_ops rtw8821a_ops = { .set_gid_table = NULL, .cfg_csi_rate = NULL, .fill_txdesc_checksum = rtw8821a_fill_txdesc_checksum, - .rx_aggregation = rtw8821au_rx_aggregation, .coex_set_init = rtw8821a_coex_cfg_init, .coex_set_ant_switch = rtw8821a_coex_cfg_ant_switch, .coex_set_gnt_fix = rtw8821a_coex_cfg_gnt_fix, diff --git a/rtw8821c.c b/rtw8821c.c index e6261916..6bfc075c 100644 --- a/rtw8821c.c +++ b/rtw8821c.c @@ -1255,27 +1255,6 @@ static void rtw8821c_fill_txdesc_checksum(struct rtw_dev *rtwdev, fill_txdesc_checksum_common(txdesc, 16); } -static void rtw8821c_rx_aggregation(struct rtw_dev *rtwdev, bool enable) -{ - u8 size, timeout; - u16 val16; - - rtw_write8_set(rtwdev, REG_TXDMA_PQ_MAP, BIT_RXDMA_AGG_EN); - rtw_write8_clr(rtwdev, REG_RXDMA_AGG_PG_TH + 3, BIT(7)); - - if (enable) { - size = 0x5; - timeout = 0x20; - } else { - size = 0x0; - timeout = 0x1; - } - val16 = u16_encode_bits(size, BIT_RXDMA_AGG_PG_TH) | - u16_encode_bits(timeout, BIT_DMA_AGG_TO_V1); - - rtw_write16(rtwdev, REG_RXDMA_AGG_PG_TH, val16); -} - static struct rtw_pwr_seq_cmd trans_carddis_to_cardemu_8821c[] = { {0x0086, RTW_PWR_CUT_ALL_MSK, @@ -1719,7 +1698,6 @@ static struct rtw_chip_ops rtw8821c_ops = { .set_gid_table = rtw_bf_set_gid_table, .cfg_csi_rate = rtw_bf_cfg_csi_rate, .fill_txdesc_checksum = rtw8821c_fill_txdesc_checksum, - .rx_aggregation = rtw8821c_rx_aggregation, .coex_set_init = rtw8821c_coex_cfg_init, .coex_set_ant_switch = rtw8821c_coex_cfg_ant_switch, diff --git a/rtw8822b.c b/rtw8822b.c index 2cea6d39..fa508a8c 100644 --- a/rtw8822b.c +++ b/rtw8822b.c @@ -1616,27 +1616,6 @@ static void rtw8822b_fill_txdesc_checksum(struct rtw_dev *rtwdev, fill_txdesc_checksum_common(txdesc, words); } -static void rtw8822b_rx_aggregation(struct rtw_dev *rtwdev, bool enable) -{ - u8 size, timeout; - u16 val16; - - rtw_write8_set(rtwdev, REG_TXDMA_PQ_MAP, BIT_RXDMA_AGG_EN); - rtw_write8_clr(rtwdev, REG_RXDMA_AGG_PG_TH + 3, BIT(7)); - - if (enable) { - size = 0x5; - timeout = 0x20; - } else { - size = 0x0; - timeout = 0x1; - } - val16 = u16_encode_bits(size, BIT_RXDMA_AGG_PG_TH) | - u16_encode_bits(timeout, BIT_DMA_AGG_TO_V1); - - rtw_write16(rtwdev, REG_RXDMA_AGG_PG_TH, val16); -} - static const struct rtw_pwr_seq_cmd trans_carddis_to_cardemu_8822b[] = { {0x0086, RTW_PWR_CUT_ALL_MSK, @@ -2209,7 +2188,6 @@ static struct rtw_chip_ops rtw8822b_ops = { .adaptivity_init = rtw8822b_adaptivity_init, .adaptivity = rtw8822b_adaptivity, .fill_txdesc_checksum = rtw8822b_fill_txdesc_checksum, - .rx_aggregation = rtw8822b_rx_aggregation, .coex_set_init = rtw8822b_coex_cfg_init, .coex_set_ant_switch = rtw8822b_coex_cfg_ant_switch, diff --git a/rtw8822c.c b/rtw8822c.c index 58446327..8cfca006 100644 --- a/rtw8822c.c +++ b/rtw8822c.c @@ -4591,27 +4591,6 @@ static void rtw8822c_fill_txdesc_checksum(struct rtw_dev *rtwdev, fill_txdesc_checksum_common(txdesc, words); } -static void rtw8822c_rx_aggregation(struct rtw_dev *rtwdev, bool enable) -{ - u8 size, timeout; - u16 val16; - - rtw_write8_set(rtwdev, REG_TXDMA_PQ_MAP, BIT_RXDMA_AGG_EN); - rtw_write8_clr(rtwdev, REG_RXDMA_AGG_PG_TH + 3, BIT(7)); - - if (enable) { - size = 0x5; - timeout = 0x20; - } else { - size = 0x0; - timeout = 0x1; - } - val16 = u16_encode_bits(size, BIT_RXDMA_AGG_PG_TH) | - u16_encode_bits(timeout, BIT_DMA_AGG_TO_V1); - - rtw_write16(rtwdev, REG_RXDMA_AGG_PG_TH, val16); -} - static const struct rtw_pwr_seq_cmd trans_carddis_to_cardemu_8822c[] = { {0x0086, RTW_PWR_CUT_ALL_MSK, @@ -5028,7 +5007,6 @@ static struct rtw_chip_ops rtw8822c_ops = { .config_tx_path = rtw8822c_config_tx_path, .config_txrx_mode = rtw8822c_config_trx_mode, .fill_txdesc_checksum = rtw8822c_fill_txdesc_checksum, - .rx_aggregation = rtw8822c_rx_aggregation, .coex_set_init = rtw8822c_coex_cfg_init, .coex_set_ant_switch = NULL, diff --git a/sdio.c b/sdio.c index 8abbbfe7..5d5ce880 100644 --- a/sdio.c +++ b/sdio.c @@ -1157,6 +1157,7 @@ static struct rtw_hci_ops rtw_sdio_ops = { .deep_ps = rtw_sdio_deep_ps, .link_ps = rtw_sdio_link_ps, .interface_cfg = rtw_sdio_interface_cfg, + .dynamic_rx_agg = NULL, .read8 = rtw_sdio_read8, .read16 = rtw_sdio_read16, diff --git a/usb.c b/usb.c index 5130972e..e6ea6ba8 100644 --- a/usb.c +++ b/usb.c @@ -771,6 +771,74 @@ static void rtw_usb_interface_cfg(struct rtw_dev *rtwdev) rtw_usb_init_burst_pkt_len(rtwdev); } +static void rtw_usb_dynamic_rx_agg_v1(struct rtw_dev *rtwdev, bool enable) +{ + u8 size, timeout; + u16 val16; + + rtw_write8_set(rtwdev, REG_TXDMA_PQ_MAP, BIT_RXDMA_AGG_EN); + rtw_write8_clr(rtwdev, REG_RXDMA_AGG_PG_TH + 3, BIT(7)); + + if (enable) { + size = 0x5; + timeout = 0x20; + } else { + size = 0x0; + timeout = 0x1; + } + val16 = u16_encode_bits(size, BIT_RXDMA_AGG_PG_TH) | + u16_encode_bits(timeout, BIT_DMA_AGG_TO_V1); + + rtw_write16(rtwdev, REG_RXDMA_AGG_PG_TH, val16); +} + +static void rtw_usb_dynamic_rx_agg_v2(struct rtw_dev *rtwdev, bool enable) +{ + struct rtw_usb *rtwusb = rtw_get_usb_priv(rtwdev); + u8 size, timeout; + u16 val16; + + if (rtwusb->udev->speed == USB_SPEED_SUPER) { + size = 0x7; + timeout = 0x1a; + } else { + size = 0x5; + timeout = 0x20; + } + + if (!enable) { + size = 0x0; + timeout = 0x1; + } + + val16 = u16_encode_bits(size, BIT_RXDMA_AGG_PG_TH) | + u16_encode_bits(timeout, BIT_DMA_AGG_TO_V1); + + rtw_write16(rtwdev, REG_RXDMA_AGG_PG_TH, val16); + rtw_write8_set(rtwdev, REG_TXDMA_PQ_MAP, BIT_RXDMA_AGG_EN); +} + +static void rtw_usb_dynamic_rx_agg(struct rtw_dev *rtwdev, bool enable) +{ + switch (rtwdev->chip->id) { + case RTW_CHIP_TYPE_8822C: + case RTW_CHIP_TYPE_8822B: + case RTW_CHIP_TYPE_8821C: + rtw_usb_dynamic_rx_agg_v1(rtwdev, enable); + break; + case RTW_CHIP_TYPE_8821A: + case RTW_CHIP_TYPE_8812A: + rtw_usb_dynamic_rx_agg_v2(rtwdev, enable); + break; + case RTW_CHIP_TYPE_8723D: + /* Doesn't like aggregation. */ + break; + case RTW_CHIP_TYPE_8703B: + /* Likely not found in USB devices. */ + break; + } +} + static struct rtw_hci_ops rtw_usb_ops = { .tx_write = rtw_usb_tx_write, .tx_kick_off = rtw_usb_tx_kick_off, @@ -780,6 +848,7 @@ static struct rtw_hci_ops rtw_usb_ops = { .deep_ps = rtw_usb_deep_ps, .link_ps = rtw_usb_link_ps, .interface_cfg = rtw_usb_interface_cfg, + .dynamic_rx_agg = rtw_usb_dynamic_rx_agg, .write8 = rtw_usb_write8, .write16 = rtw_usb_write16, From 6c8b460acaef7ce6be2a66446d60296236630448 Mon Sep 17 00:00:00 2001 From: Bitterblue Smith Date: Sun, 13 Oct 2024 21:55:47 +0300 Subject: [PATCH 024/193] Sync rtw_usb_rx_handler with upstream Upstream commit df3d8f463b1dfc7cb8f4fb52b1b81d290b850d03. --- usb.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/usb.c b/usb.c index e6ea6ba8..7de1168d 100644 --- a/usb.c +++ b/usb.c @@ -556,7 +556,7 @@ static void rtw_usb_rx_handler(struct work_struct *work) struct ieee80211_rx_status rx_status; u32 pkt_offset, next_pkt, urb_len; struct rtw_rx_pkt_stat pkt_stat; - struct sk_buff *next_skb = NULL; + struct sk_buff *next_skb; struct sk_buff *skb; u8 *rx_desc; int limit; @@ -585,6 +585,8 @@ static void rtw_usb_rx_handler(struct work_struct *work) if (urb_len >= next_pkt + pkt_desc_sz) next_skb = skb_clone(skb, GFP_KERNEL); + else + next_skb = NULL; if (pkt_stat.is_c2h) { skb_trim(skb, pkt_stat.pkt_len + pkt_offset); @@ -602,11 +604,10 @@ static void rtw_usb_rx_handler(struct work_struct *work) skb = next_skb; if (skb) - skb_pull(next_skb, next_pkt); + skb_pull(skb, next_pkt); urb_len -= next_pkt; - next_skb = NULL; - } while (skb && urb_len >= pkt_desc_sz); + } while (skb); } } From ed02ffc112bc4a92e652a147e3004543baa948c2 Mon Sep 17 00:00:00 2001 From: Bitterblue Smith Date: Sun, 13 Oct 2024 21:57:44 +0300 Subject: [PATCH 025/193] wifi: rtw88: remove CPT execution branch never used Upstream commit 77c977327dfaa9ae2e154964cdb89ceb5c7b7cf1. In 'rtw_coex_action_bt_a2dp_pan', 'wl_cpt_test' and 'bt_cpt_test' are hardcoded to false, so corresponding 'table_case' and 'tdma_case' assignments are never met. Also 'rtw_coex_set_rf_para(rtwdev, chip->wl_rf_para_rx[1])' is never executed. Assuming that CPT was never fully implemented, remove lookalike leftovers. Compile tested only. Found by Linux Verification Center (linuxtesting.org) with SVACE. Fixes: 76f631c ("rtw88: coex: update the mechanism for A2DP + PAN") Signed-off-by: Dmitry Kandybka Signed-off-by: Ping-Ke Shih Link: https://patch.msgid.link/20240809085310.10512-1-d.kandybka@gmail.com --- coex.c | 38 ++++++++++---------------------------- 1 file changed, 10 insertions(+), 28 deletions(-) diff --git a/coex.c b/coex.c index 91e21bdf..c929db1e 100644 --- a/coex.c +++ b/coex.c @@ -2218,7 +2218,6 @@ static void rtw_coex_action_bt_a2dp_pan(struct rtw_dev *rtwdev) struct rtw_coex_stat *coex_stat = &coex->stat; struct rtw_efuse *efuse = &rtwdev->efuse; u8 table_case, tdma_case; - bool wl_cpt_test = false, bt_cpt_test = false; rtw_dbg(rtwdev, RTW_DBG_COEX, "[BTCoex], %s()\n", __func__); @@ -2226,29 +2225,16 @@ static void rtw_coex_action_bt_a2dp_pan(struct rtw_dev *rtwdev) rtw_coex_set_rf_para(rtwdev, chip->wl_rf_para_rx[0]); if (efuse->share_ant) { /* Shared-Ant */ - if (wl_cpt_test) { - if (coex_stat->wl_gl_busy) { - table_case = 20; - tdma_case = 17; - } else { - table_case = 10; - tdma_case = 15; - } - } else if (bt_cpt_test) { - table_case = 26; - tdma_case = 26; - } else { - if (coex_stat->wl_gl_busy && - coex_stat->wl_noisy_level == 0) - table_case = 14; - else - table_case = 10; + if (coex_stat->wl_gl_busy && + coex_stat->wl_noisy_level == 0) + table_case = 14; + else + table_case = 10; - if (coex_stat->wl_gl_busy) - tdma_case = 15; - else - tdma_case = 20; - } + if (coex_stat->wl_gl_busy) + tdma_case = 15; + else + tdma_case = 20; } else { /* Non-Shared-Ant */ table_case = 112; @@ -2259,11 +2245,7 @@ static void rtw_coex_action_bt_a2dp_pan(struct rtw_dev *rtwdev) tdma_case = 120; } - if (wl_cpt_test) - rtw_coex_set_rf_para(rtwdev, chip->wl_rf_para_rx[1]); - else - rtw_coex_set_rf_para(rtwdev, chip->wl_rf_para_rx[0]); - + rtw_coex_set_rf_para(rtwdev, chip->wl_rf_para_rx[0]); rtw_coex_table(rtwdev, false, table_case); rtw_coex_tdma(rtwdev, false, tdma_case); } From 8d8578a2e16b7732ab7fb4c4fece1642f7406302 Mon Sep 17 00:00:00 2001 From: Bitterblue Smith Date: Sun, 13 Oct 2024 22:02:37 +0300 Subject: [PATCH 026/193] Fix SDIO devices not transmitting beacons Sync with upstream commit faa2e484b393c56bc1243dca6676a70bc485f775. USB devices were fixed earlier. --- fw.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/fw.c b/fw.c index a93a5426..6619ce97 100644 --- a/fw.c +++ b/fw.c @@ -1503,7 +1503,7 @@ int rtw_fw_write_data_rsvd_page(struct rtw_dev *rtwdev, u16 pg_addr, val |= BIT_ENSWBCN >> 8; rtw_write8(rtwdev, REG_CR + 1, val); - if (rtw_hci_type(rtwdev) != RTW_HCI_TYPE_USB) { + if (rtw_hci_type(rtwdev) == RTW_HCI_TYPE_PCIE) { val = rtw_read8(rtwdev, REG_FWHW_TXQ_CTRL + 2); bckp[1] = val; val &= ~(BIT_EN_BCNQ_DL >> 16); @@ -1537,7 +1537,7 @@ int rtw_fw_write_data_rsvd_page(struct rtw_dev *rtwdev, u16 pg_addr, rtw_write16(rtwdev, REG_FIFOPAGE_CTRL_2, rsvd_pg_head | BIT_BCN_VALID_V1); } - if (rtw_hci_type(rtwdev) != RTW_HCI_TYPE_USB) + if (rtw_hci_type(rtwdev) == RTW_HCI_TYPE_PCIE) rtw_write8(rtwdev, REG_FWHW_TXQ_CTRL + 2, bckp[1]); rtw_write8(rtwdev, REG_CR + 1, bckp[0]); From 0548696f0e641e3dbbceb38d56d0c12c46b1285f Mon Sep 17 00:00:00 2001 From: Bitterblue Smith Date: Sun, 13 Oct 2024 22:03:34 +0300 Subject: [PATCH 027/193] Revert "wifi: rtw88: Avoid using macid 0 in AP mode" This reverts commit 610e04fc38343dcdcef95475c1579efc07572f1f. A better fix in the next commit. --- mac80211.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/mac80211.c b/mac80211.c index 3105d5b8..b15ff573 100644 --- a/mac80211.c +++ b/mac80211.c @@ -477,7 +477,6 @@ static int rtw_ops_start_ap(struct ieee80211_hw *hw, struct ieee80211_vif *vif) const struct rtw_chip_info *chip = rtwdev->chip; mutex_lock(&rtwdev->mutex); - set_bit(0, rtwdev->mac_id_map); rtw_write32_set(rtwdev, REG_TCR, BIT_TCR_UPDATE_HGQMD); rtwdev->ap_active = true; rtw_store_op_chan(rtwdev, true); @@ -503,7 +502,6 @@ static void rtw_ops_stop_ap(struct ieee80211_hw *hw, rtwdev->ap_active = false; if (!rtw_core_check_sta_active(rtwdev)) rtw_clear_op_chan(rtwdev); - clear_bit(0, rtwdev->mac_id_map); mutex_unlock(&rtwdev->mutex); } From 557078c4c9f9a3c5511101b0f7a6b312d8143ece Mon Sep 17 00:00:00 2001 From: Bitterblue Smith Date: Sun, 13 Oct 2024 22:17:12 +0300 Subject: [PATCH 028/193] wifi: rtw88: assign mac_id for vif/sta and update to TX desc Upstream commit 902cb7b11f9a7ff07233cc4c626b54c3e4703149. A mac_id as an instance in firmware has to be assigned for each station including AP and connected stations. Firmware will use the mac_id to control TX rate and do statistics. Assignment rule is to assign mac_id to each vif when adding vif. For station mode, sta->mac_id will reuse vif->mac_id. For AP mode, dynamically allocate an sta->mac_id to a station, and vif->mac_id is used to send broadcast/multicast packets which are not belong to a station. For example, vif->mac_id sta->mac_id vif0 (STA mode) 0 0 vif1 (AP mode) 1 2... By the way, remove unused RTW_BC_MC_MACID, which was planed to send broadcast/multicast packets on fixed mac_id. Tested-on RTL8822CE with STA + AP SCC mode. Link: https://lore.kernel.org/linux-wireless/e4be0a75-43b2-4ae5-9aab-5c4a88e78097@gmail.com/ Cc: Bitterblue Smith Signed-off-by: Ping-Ke Shih Link: https://patch.msgid.link/20240819025248.17939-1-pkshih@realtek.com --- mac80211.c | 13 +++++++++++-- main.c | 34 ++++++++++++---------------------- main.h | 14 ++++++++++++-- tx.c | 11 ++++++++--- tx.h | 1 + 5 files changed, 44 insertions(+), 29 deletions(-) diff --git a/mac80211.c b/mac80211.c index b15ff573..5a1d67d9 100644 --- a/mac80211.c +++ b/mac80211.c @@ -173,6 +173,12 @@ static int rtw_ops_add_interface(struct ieee80211_hw *hw, mutex_lock(&rtwdev->mutex); + rtwvif->mac_id = rtw_acquire_macid(rtwdev); + if (rtwvif->mac_id >= RTW_MAX_MAC_ID_NUM) { + mutex_unlock(&rtwdev->mutex); + return -ENOSPC; + } + port = find_first_zero_bit(rtwdev->hw_port, RTW_PORT_NUM); if (port >= RTW_PORT_NUM) { mutex_unlock(&rtwdev->mutex); @@ -220,7 +226,8 @@ static int rtw_ops_add_interface(struct ieee80211_hw *hw, mutex_unlock(&rtwdev->mutex); - rtw_dbg(rtwdev, RTW_DBG_STATE, "start vif %pM on port %d\n", vif->addr, rtwvif->port); + rtw_dbg(rtwdev, RTW_DBG_STATE, "start vif %pM mac_id %d on port %d\n", + vif->addr, rtwvif->mac_id, rtwvif->port); return 0; } @@ -231,7 +238,8 @@ static void rtw_ops_remove_interface(struct ieee80211_hw *hw, struct rtw_vif *rtwvif = (struct rtw_vif *)vif->drv_priv; u32 config = 0; - rtw_dbg(rtwdev, RTW_DBG_STATE, "stop vif %pM on port %d\n", vif->addr, rtwvif->port); + rtw_dbg(rtwdev, RTW_DBG_STATE, "stop vif %pM mac_id %d on port %d\n", + vif->addr, rtwvif->mac_id, rtwvif->port); mutex_lock(&rtwdev->mutex); @@ -248,6 +256,7 @@ static void rtw_ops_remove_interface(struct ieee80211_hw *hw, config |= PORT_SET_BCN_CTRL; rtw_vif_port_config(rtwdev, rtwvif, config); clear_bit(rtwvif->port, rtwdev->hw_port); + rtw_release_macid(rtwdev, rtwvif->mac_id); rtw_recalc_lps(rtwdev, NULL); mutex_unlock(&rtwdev->mutex); diff --git a/main.c b/main.c index 07452fb5..b06a7e6e 100644 --- a/main.c +++ b/main.c @@ -331,17 +331,6 @@ static void rtw_ips_work(struct work_struct *work) mutex_unlock(&rtwdev->mutex); } -static u8 rtw_acquire_macid(struct rtw_dev *rtwdev) -{ - unsigned long mac_id; - - mac_id = find_first_zero_bit(rtwdev->mac_id_map, RTW_MAX_MAC_ID_NUM); - if (mac_id < RTW_MAX_MAC_ID_NUM) - set_bit(mac_id, rtwdev->mac_id_map); - - return mac_id; -} - static void rtw_sta_rc_work(struct work_struct *work) { struct rtw_sta_info *si = container_of(work, struct rtw_sta_info, @@ -360,16 +349,14 @@ int rtw_sta_add(struct rtw_dev *rtwdev, struct ieee80211_sta *sta, struct rtw_vif *rtwvif = (struct rtw_vif *)vif->drv_priv; int i; - si->mac_id = rtw_acquire_macid(rtwdev); - if (si->mac_id >= RTW_MAX_MAC_ID_NUM) - return -ENOSPC; + if (vif->type == NL80211_IFTYPE_STATION) { + si->mac_id = rtwvif->mac_id; + } else { + si->mac_id = rtw_acquire_macid(rtwdev); + if (si->mac_id >= RTW_MAX_MAC_ID_NUM) + return -ENOSPC; + } -#if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 0, 0) - if (vif->type == NL80211_IFTYPE_STATION && vif->cfg.assoc == 0) -#else - if (vif->type == NL80211_IFTYPE_STATION && vif->bss_conf.assoc == 0) -#endif - rtwvif->mac_id = si->mac_id; si->rtwdev = rtwdev; si->sta = sta; si->vif = vif; @@ -394,11 +381,13 @@ void rtw_sta_remove(struct rtw_dev *rtwdev, struct ieee80211_sta *sta, bool fw_exist) { struct rtw_sta_info *si = (struct rtw_sta_info *)sta->drv_priv; + struct ieee80211_vif *vif = si->vif; int i; cancel_work_sync(&si->rc_work); - rtw_release_macid(rtwdev, si->mac_id); + if (vif->type != NL80211_IFTYPE_STATION) + rtw_release_macid(rtwdev, si->mac_id); if (fw_exist) rtw_fw_media_status_report(rtwdev, si->mac_id, false); @@ -643,6 +632,8 @@ static void rtw_reset_vif_iter(void *data, u8 *mac, struct ieee80211_vif *vif) rtw_bf_disassoc(rtwdev, vif, NULL); rtw_vif_assoc_changed(rtwvif, NULL); rtw_txq_cleanup(rtwdev, vif->txq); + + rtw_release_macid(rtwdev, rtwvif->mac_id); } void rtw_fw_recovery(struct rtw_dev *rtwdev) @@ -2278,7 +2269,6 @@ int rtw_core_init(struct rtw_dev *rtwdev) rtwdev->sec.total_cam_num = 32; rtwdev->hal.current_channel = 1; rtwdev->dm_info.fix_rate = U8_MAX; - set_bit(RTW_BC_MC_MACID, rtwdev->mac_id_map); rtw_stats_init(rtwdev); diff --git a/main.h b/main.h index a6aedf4d..8eb75ad0 100644 --- a/main.h +++ b/main.h @@ -857,7 +857,6 @@ struct rtw_txq { unsigned long flags; }; -#define RTW_BC_MC_MACID 1 DECLARE_EWMA(rssi, 10, 16); struct rtw_sta_info { @@ -920,7 +919,7 @@ struct rtw_bf_info { struct rtw_vif { enum rtw_net_type net_type; u16 aid; - u8 mac_id; /* for STA mode only */ + u8 mac_id; u8 mac_addr[ETH_ALEN]; u8 bssid[ETH_ALEN]; u8 port; @@ -2271,6 +2270,17 @@ static inline bool rtw_chip_has_tx_stbc(struct rtw_dev *rtwdev) return rtwdev->chip->tx_stbc; } +static inline u8 rtw_acquire_macid(struct rtw_dev *rtwdev) +{ + unsigned long mac_id; + + mac_id = find_first_zero_bit(rtwdev->mac_id_map, RTW_MAX_MAC_ID_NUM); + if (mac_id < RTW_MAX_MAC_ID_NUM) + set_bit(mac_id, rtwdev->mac_id_map); + + return mac_id; +} + static inline void rtw_release_macid(struct rtw_dev *rtwdev, u8 mac_id) { clear_bit(mac_id, rtwdev->mac_id_map); diff --git a/tx.c b/tx.c index 1d8af54a..a5adcd60 100644 --- a/tx.c +++ b/tx.c @@ -47,7 +47,8 @@ void rtw_tx_fill_tx_desc(struct rtw_dev *rtwdev, le32_encode_bits(pkt_info->ls, RTW_TX_DESC_W0_LS) | le32_encode_bits(pkt_info->dis_qselseq, RTW_TX_DESC_W0_DISQSELSEQ); - tx_desc->w1 = le32_encode_bits(pkt_info->qsel, RTW_TX_DESC_W1_QSEL) | + tx_desc->w1 = le32_encode_bits(pkt_info->mac_id, RTW_TX_DESC_W1_MACID) | + le32_encode_bits(pkt_info->qsel, RTW_TX_DESC_W1_QSEL) | le32_encode_bits(pkt_info->rate_id, RTW_TX_DESC_W1_RATE_ID) | le32_encode_bits(pkt_info->sec_type, RTW_TX_DESC_W1_SEC_TYPE) | le32_encode_bits(pkt_info->pkt_offset, RTW_TX_DESC_W1_PKT_OFFSET) | @@ -440,14 +441,18 @@ void rtw_tx_pkt_info_update(struct rtw_dev *rtwdev, const struct rtw_chip_info *chip = rtwdev->chip; struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; + struct ieee80211_vif *vif = info->control.vif; struct rtw_sta_info *si; - struct ieee80211_vif *vif = NULL; + struct rtw_vif *rtwvif; __le16 fc = hdr->frame_control; bool bmc; if (sta) { si = (struct rtw_sta_info *)sta->drv_priv; - vif = si->vif; + pkt_info->mac_id = si->mac_id; + } else if (vif) { + rtwvif = (struct rtw_vif *)vif->drv_priv; + pkt_info->mac_id = rtwvif->mac_id; } if (ieee80211_is_mgmt(fc) || ieee80211_is_nullfunc(fc)) diff --git a/tx.h b/tx.h index 056d3d7d..d34cdeca 100644 --- a/tx.h +++ b/tx.h @@ -27,6 +27,7 @@ struct rtw_tx_desc { #define RTW_TX_DESC_W0_BMC BIT(24) #define RTW_TX_DESC_W0_LS BIT(26) #define RTW_TX_DESC_W0_DISQSELSEQ BIT(31) +#define RTW_TX_DESC_W1_MACID GENMASK(7, 0) #define RTW_TX_DESC_W1_QSEL GENMASK(12, 8) #define RTW_TX_DESC_W1_RATE_ID GENMASK(20, 16) #define RTW_TX_DESC_W1_SEC_TYPE GENMASK(23, 22) From 711bf579b4ed2c706354bea1e5f13fc0a5191822 Mon Sep 17 00:00:00 2001 From: Bitterblue Smith Date: Sun, 13 Oct 2024 22:53:20 +0300 Subject: [PATCH 029/193] wifi: rtw88: Constify some arrays and structs Upstream commit 140403599b74839b0a57c5397b7e8579e5332364. These are never modified, so make them const: card_enable_flow_8703b card_disable_flow_8703b rtw8703b_ops rtw8723d_ops card_enable_flow_8723d card_disable_flow_8723d trans_carddis_to_cardemu_8821c trans_cardemu_to_act_8821c trans_act_to_cardemu_8821c trans_cardemu_to_carddis_8821c card_enable_flow_8821c card_disable_flow_8821c rtw8821c_dig page_table_8821c rqpn_table_8821c prioq_addrs_8821c rtw8821c_ops card_enable_flow_8822b card_disable_flow_8822b prioq_addrs_8822b rtw8822b_ops rtw8822b_edcca_th card_enable_flow_8822c card_disable_flow_8822c prioq_addrs_8822c rtw8822c_ops rtw8822c_edcca_th Signed-off-by: Bitterblue Smith Acked-by: Ping-Ke Shih Signed-off-by: Ping-Ke Shih Link: https://patch.msgid.link/dae7994f-3491-40de-b537-ebf68df084bb@gmail.com --- fw.c | 2 +- mac.c | 4 ++-- mac.h | 2 +- main.h | 8 ++++---- phy.c | 2 +- rtw8703b.c | 6 +++--- rtw8723d.c | 6 +++--- rtw8821c.c | 22 +++++++++++----------- rtw8822b.c | 10 +++++----- rtw8822c.c | 10 +++++----- 10 files changed, 36 insertions(+), 36 deletions(-) diff --git a/fw.c b/fw.c index 6619ce97..bd4faa02 100644 --- a/fw.c +++ b/fw.c @@ -275,7 +275,7 @@ static void rtw_fw_scan_result(struct rtw_dev *rtwdev, u8 *payload, static void rtw_fw_adaptivity_result(struct rtw_dev *rtwdev, u8 *payload, u8 length) { - struct rtw_hw_reg_offset *edcca_th = rtwdev->chip->edcca_th; + const struct rtw_hw_reg_offset *edcca_th = rtwdev->chip->edcca_th; struct rtw_c2h_adaptivity *result = (struct rtw_c2h_adaptivity *)payload; rtw_dbg(rtwdev, RTW_DBG_ADAPTIVITY, diff --git a/mac.c b/mac.c index c4c2501e..cae9cca6 100644 --- a/mac.c +++ b/mac.c @@ -228,7 +228,7 @@ static int rtw_sub_pwr_seq_parser(struct rtw_dev *rtwdev, u8 intf_mask, } int rtw_pwr_seq_parser(struct rtw_dev *rtwdev, - const struct rtw_pwr_seq_cmd **cmd_seq) + const struct rtw_pwr_seq_cmd * const *cmd_seq) { u8 cut_mask; u8 intf_mask; @@ -272,7 +272,7 @@ EXPORT_SYMBOL(rtw_pwr_seq_parser); static int rtw_mac_power_switch(struct rtw_dev *rtwdev, bool pwr_on) { const struct rtw_chip_info *chip = rtwdev->chip; - const struct rtw_pwr_seq_cmd **pwr_seq; + const struct rtw_pwr_seq_cmd * const *pwr_seq; u32 imr = 0; u8 rpwm; bool cur_pwr; diff --git a/mac.h b/mac.h index cd86e0b7..6905e274 100644 --- a/mac.h +++ b/mac.h @@ -31,7 +31,7 @@ void rtw_set_channel_mac(struct rtw_dev *rtwdev, u8 channel, u8 bw, u8 primary_ch_idx); int rtw_pwr_seq_parser(struct rtw_dev *rtwdev, - const struct rtw_pwr_seq_cmd **cmd_seq); + const struct rtw_pwr_seq_cmd * const *cmd_seq); int rtw_mac_power_on(struct rtw_dev *rtwdev); void rtw_mac_power_off(struct rtw_dev *rtwdev); int rtw_download_firmware(struct rtw_dev *rtwdev, struct rtw_fw_state *fw); diff --git a/main.h b/main.h index 8eb75ad0..1b4baf3b 100644 --- a/main.h +++ b/main.h @@ -1287,7 +1287,7 @@ enum rtw_fwcd_item { /* hardware configuration for each IC */ struct rtw_chip_info { - struct rtw_chip_ops *ops; + const struct rtw_chip_ops *ops; u8 id; const char *fw_name; @@ -1332,8 +1332,8 @@ struct rtw_chip_info { /* init values */ u8 sys_func_en; - const struct rtw_pwr_seq_cmd **pwr_on_seq; - const struct rtw_pwr_seq_cmd **pwr_off_seq; + const struct rtw_pwr_seq_cmd * const *pwr_on_seq; + const struct rtw_pwr_seq_cmd * const *pwr_off_seq; const struct rtw_rqpn *rqpn_table; const struct rtw_prioq_addrs *prioq_addrs; const struct rtw_page_table *page_table; @@ -1364,7 +1364,7 @@ struct rtw_chip_info { u8 bfer_su_max_num; u8 bfer_mu_max_num; - struct rtw_hw_reg_offset *edcca_th; + const struct rtw_hw_reg_offset *edcca_th; s8 l2h_th_ini_cs; s8 l2h_th_ini_ad; diff --git a/phy.c b/phy.c index 35e05fab..192f7e90 100644 --- a/phy.c +++ b/phy.c @@ -128,7 +128,7 @@ static void rtw_phy_cck_pd_init(struct rtw_dev *rtwdev) void rtw_phy_set_edcca_th(struct rtw_dev *rtwdev, u8 l2h, u8 h2l) { - struct rtw_hw_reg_offset *edcca_th = rtwdev->chip->edcca_th; + const struct rtw_hw_reg_offset *edcca_th = rtwdev->chip->edcca_th; rtw_write32_mask(rtwdev, edcca_th[EDCCA_TH_L2H_IDX].hw_reg.addr, diff --git a/rtw8703b.c b/rtw8703b.c index ccf45050..59b79c44 100644 --- a/rtw8703b.c +++ b/rtw8703b.c @@ -482,14 +482,14 @@ static const struct rtw_pwr_seq_cmd trans_act_to_lps_8703b[] = { {TRANS_SEQ_END}, }; -static const struct rtw_pwr_seq_cmd *card_enable_flow_8703b[] = { +static const struct rtw_pwr_seq_cmd * const card_enable_flow_8703b[] = { trans_pre_enable_8703b, trans_carddis_to_cardemu_8703b, trans_cardemu_to_act_8703b, NULL }; -static const struct rtw_pwr_seq_cmd *card_disable_flow_8703b[] = { +static const struct rtw_pwr_seq_cmd * const card_disable_flow_8703b[] = { trans_act_to_lps_8703b, trans_act_to_reset_mcu_8703b, trans_act_to_cardemu_8703b, @@ -1957,7 +1957,7 @@ static const struct coex_tdma_para tdma_sant_8703b[] = { { {0x61, 0x08, 0x03, 0x11, 0x11} }, }; -static struct rtw_chip_ops rtw8703b_ops = { +static const struct rtw_chip_ops rtw8703b_ops = { .power_on = rtw_power_on, .power_off = rtw_power_off, .mac_init = rtw8723x_mac_init, diff --git a/rtw8723d.c b/rtw8723d.c index b602ddc6..a6d3496a 100644 --- a/rtw8723d.c +++ b/rtw8723d.c @@ -1430,7 +1430,7 @@ static void rtw8723d_pwr_track(struct rtw_dev *rtwdev) dm_info->pwr_trk_triggered = false; } -static struct rtw_chip_ops rtw8723d_ops = { +static const struct rtw_chip_ops rtw8723d_ops = { .power_on = rtw_power_on, .power_off = rtw_power_off, .phy_set_param = rtw8723d_phy_set_param, @@ -1790,7 +1790,7 @@ static const struct rtw_pwr_seq_cmd trans_cardemu_to_act_8723d[] = { RTW_PWR_CMD_END, 0, 0}, }; -static const struct rtw_pwr_seq_cmd *card_enable_flow_8723d[] = { +static const struct rtw_pwr_seq_cmd * const card_enable_flow_8723d[] = { trans_carddis_to_cardemu_8723d, trans_cardemu_to_act_8723d, NULL @@ -2006,7 +2006,7 @@ static const struct rtw_pwr_seq_cmd trans_act_to_post_carddis_8723d[] = { RTW_PWR_CMD_END, 0, 0}, }; -static const struct rtw_pwr_seq_cmd *card_disable_flow_8723d[] = { +static const struct rtw_pwr_seq_cmd * const card_disable_flow_8723d[] = { trans_act_to_lps_8723d, trans_act_to_pre_carddis_8723d, trans_act_to_cardemu_8723d, diff --git a/rtw8821c.c b/rtw8821c.c index 6bfc075c..d45f808a 100644 --- a/rtw8821c.c +++ b/rtw8821c.c @@ -1255,7 +1255,7 @@ static void rtw8821c_fill_txdesc_checksum(struct rtw_dev *rtwdev, fill_txdesc_checksum_common(txdesc, 16); } -static struct rtw_pwr_seq_cmd trans_carddis_to_cardemu_8821c[] = { +static const struct rtw_pwr_seq_cmd trans_carddis_to_cardemu_8821c[] = { {0x0086, RTW_PWR_CUT_ALL_MSK, RTW_PWR_INTF_SDIO_MSK, @@ -1293,7 +1293,7 @@ static struct rtw_pwr_seq_cmd trans_carddis_to_cardemu_8821c[] = { RTW_PWR_CMD_END, 0, 0}, }; -static struct rtw_pwr_seq_cmd trans_cardemu_to_act_8821c[] = { +static const struct rtw_pwr_seq_cmd trans_cardemu_to_act_8821c[] = { {0x0020, RTW_PWR_CUT_ALL_MSK, RTW_PWR_INTF_USB_MSK | RTW_PWR_INTF_SDIO_MSK, @@ -1397,7 +1397,7 @@ static struct rtw_pwr_seq_cmd trans_cardemu_to_act_8821c[] = { RTW_PWR_CMD_END, 0, 0}, }; -static struct rtw_pwr_seq_cmd trans_act_to_cardemu_8821c[] = { +static const struct rtw_pwr_seq_cmd trans_act_to_cardemu_8821c[] = { {0x0093, RTW_PWR_CUT_ALL_MSK, RTW_PWR_INTF_ALL_MSK, @@ -1455,7 +1455,7 @@ static struct rtw_pwr_seq_cmd trans_act_to_cardemu_8821c[] = { RTW_PWR_CMD_END, 0, 0}, }; -static struct rtw_pwr_seq_cmd trans_cardemu_to_carddis_8821c[] = { +static const struct rtw_pwr_seq_cmd trans_cardemu_to_carddis_8821c[] = { {0x0007, RTW_PWR_CUT_ALL_MSK, RTW_PWR_INTF_USB_MSK | RTW_PWR_INTF_SDIO_MSK, @@ -1568,13 +1568,13 @@ static struct rtw_pwr_seq_cmd trans_cardemu_to_carddis_8821c[] = { RTW_PWR_CMD_END, 0, 0}, }; -static const struct rtw_pwr_seq_cmd *card_enable_flow_8821c[] = { +static const struct rtw_pwr_seq_cmd * const card_enable_flow_8821c[] = { trans_carddis_to_cardemu_8821c, trans_cardemu_to_act_8821c, NULL }; -static const struct rtw_pwr_seq_cmd *card_disable_flow_8821c[] = { +static const struct rtw_pwr_seq_cmd * const card_disable_flow_8821c[] = { trans_act_to_cardemu_8821c, trans_cardemu_to_carddis_8821c, NULL @@ -1623,7 +1623,7 @@ static const struct rtw_intf_phy_para_table phy_para_table_8821c = { .n_gen2_para = ARRAY_SIZE(pcie_gen2_param_8821c), }; -static struct rtw_hw_reg rtw8821c_dig[] = { +static const struct rtw_hw_reg rtw8821c_dig[] = { [0] = { .addr = 0xc50, .mask = 0x7f }, }; @@ -1633,7 +1633,7 @@ static const struct rtw_ltecoex_addr rtw8821c_ltecoex_addr = { .rdata = LTECOEX_READ_DATA, }; -static struct rtw_page_table page_table_8821c[] = { +static const struct rtw_page_table page_table_8821c[] = { /* not sure what [0] stands for */ {16, 16, 16, 14, 1}, {16, 16, 16, 14, 1}, @@ -1642,7 +1642,7 @@ static struct rtw_page_table page_table_8821c[] = { {16, 16, 16, 14, 1}, }; -static struct rtw_rqpn rqpn_table_8821c[] = { +static const struct rtw_rqpn rqpn_table_8821c[] = { /* not sure what [0] stands for */ {RTW_DMA_MAPPING_NORMAL, RTW_DMA_MAPPING_NORMAL, RTW_DMA_MAPPING_LOW, RTW_DMA_MAPPING_LOW, @@ -1661,7 +1661,7 @@ static struct rtw_rqpn rqpn_table_8821c[] = { RTW_DMA_MAPPING_EXTRA, RTW_DMA_MAPPING_HIGH}, }; -static struct rtw_prioq_addrs prioq_addrs_8821c = { +static const struct rtw_prioq_addrs prioq_addrs_8821c = { .prio[RTW_DMA_MAPPING_EXTRA] = { .rsvd = REG_FIFOPAGE_INFO_4, .avail = REG_FIFOPAGE_INFO_4 + 2, }, @@ -1677,7 +1677,7 @@ static struct rtw_prioq_addrs prioq_addrs_8821c = { .wsize = true, }; -static struct rtw_chip_ops rtw8821c_ops = { +static const struct rtw_chip_ops rtw8821c_ops = { .power_on = rtw_power_on, .power_off = rtw_power_off, .phy_set_param = rtw8821c_phy_set_param, diff --git a/rtw8822b.c b/rtw8822b.c index fa508a8c..5f7858c5 100644 --- a/rtw8822b.c +++ b/rtw8822b.c @@ -1978,13 +1978,13 @@ static const struct rtw_pwr_seq_cmd trans_cardemu_to_carddis_8822b[] = { RTW_PWR_CMD_END, 0, 0}, }; -static const struct rtw_pwr_seq_cmd *card_enable_flow_8822b[] = { +static const struct rtw_pwr_seq_cmd * const card_enable_flow_8822b[] = { trans_carddis_to_cardemu_8822b, trans_cardemu_to_act_8822b, NULL }; -static const struct rtw_pwr_seq_cmd *card_disable_flow_8822b[] = { +static const struct rtw_pwr_seq_cmd * const card_disable_flow_8822b[] = { trans_act_to_cardemu_8822b, trans_cardemu_to_carddis_8822b, NULL @@ -2150,7 +2150,7 @@ static const struct rtw_rqpn rqpn_table_8822b[] = { RTW_DMA_MAPPING_EXTRA, RTW_DMA_MAPPING_HIGH}, }; -static struct rtw_prioq_addrs prioq_addrs_8822b = { +static const struct rtw_prioq_addrs prioq_addrs_8822b = { .prio[RTW_DMA_MAPPING_EXTRA] = { .rsvd = REG_FIFOPAGE_INFO_4, .avail = REG_FIFOPAGE_INFO_4 + 2, }, @@ -2166,7 +2166,7 @@ static struct rtw_prioq_addrs prioq_addrs_8822b = { .wsize = true, }; -static struct rtw_chip_ops rtw8822b_ops = { +static const struct rtw_chip_ops rtw8822b_ops = { .power_on = rtw_power_on, .power_off = rtw_power_off, .phy_set_param = rtw8822b_phy_set_param, @@ -2523,7 +2523,7 @@ static const struct rtw_reg_domain coex_info_hw_regs_8822b[] = { {0xc50, MASKBYTE0, RTW_REG_DOMAIN_MAC8}, }; -static struct rtw_hw_reg_offset rtw8822b_edcca_th[] = { +static const struct rtw_hw_reg_offset rtw8822b_edcca_th[] = { [EDCCA_TH_L2H_IDX] = {{.addr = 0x8a4, .mask = MASKBYTE0}, .offset = 0}, [EDCCA_TH_H2L_IDX] = {{.addr = 0x8a4, .mask = MASKBYTE1}, .offset = 0}, }; diff --git a/rtw8822c.c b/rtw8822c.c index 8cfca006..e33e46e2 100644 --- a/rtw8822c.c +++ b/rtw8822c.c @@ -4874,13 +4874,13 @@ static const struct rtw_pwr_seq_cmd trans_cardemu_to_carddis_8822c[] = { RTW_PWR_CMD_END, 0, 0}, }; -static const struct rtw_pwr_seq_cmd *card_enable_flow_8822c[] = { +static const struct rtw_pwr_seq_cmd * const card_enable_flow_8822c[] = { trans_carddis_to_cardemu_8822c, trans_cardemu_to_act_8822c, NULL }; -static const struct rtw_pwr_seq_cmd *card_disable_flow_8822c[] = { +static const struct rtw_pwr_seq_cmd * const card_disable_flow_8822c[] = { trans_act_to_cardemu_8822c, trans_cardemu_to_carddis_8822c, NULL @@ -4962,7 +4962,7 @@ static const struct rtw_rqpn rqpn_table_8822c[] = { RTW_DMA_MAPPING_EXTRA, RTW_DMA_MAPPING_HIGH}, }; -static struct rtw_prioq_addrs prioq_addrs_8822c = { +static const struct rtw_prioq_addrs prioq_addrs_8822c = { .prio[RTW_DMA_MAPPING_EXTRA] = { .rsvd = REG_FIFOPAGE_INFO_4, .avail = REG_FIFOPAGE_INFO_4 + 2, }, @@ -4978,7 +4978,7 @@ static struct rtw_prioq_addrs prioq_addrs_8822c = { .wsize = true, }; -static struct rtw_chip_ops rtw8822c_ops = { +static const struct rtw_chip_ops rtw8822c_ops = { .power_on = rtw_power_on, .power_off = rtw_power_off, .phy_set_param = rtw8822c_phy_set_param, @@ -5303,7 +5303,7 @@ static const struct rtw_rfe_def rtw8822c_rfe_defs[] = { [6] = RTW_DEF_RFE(8822c, 0, 0, 0), }; -static struct rtw_hw_reg_offset rtw8822c_edcca_th[] = { +static const struct rtw_hw_reg_offset rtw8822c_edcca_th[] = { [EDCCA_TH_L2H_IDX] = { {.addr = 0x84c, .mask = MASKBYTE2}, .offset = 0x80 }, From d817255521637a26ca10dddf37ed4f85af7525bb Mon Sep 17 00:00:00 2001 From: Bitterblue Smith Date: Sun, 13 Oct 2024 23:03:48 +0300 Subject: [PATCH 030/193] wifi: rtw88: use ieee80211_purge_tx_queue() to purge TX skb Upstream commit 3e5e4a801aaf4283390cc34959c6c48f910ca5ea. When removing kernel modules by: rmmod rtw88_8723cs rtw88_8703b rtw88_8723x rtw88_sdio rtw88_core Driver uses skb_queue_purge() to purge TX skb, but not report tx status causing "Have pending ack frames!" warning. Use ieee80211_purge_tx_queue() to correct this. Since ieee80211_purge_tx_queue() doesn't take locks, to prevent racing between TX work and purge TX queue, flush and destroy TX work in advance. wlan0: deauthenticating from aa:f5:fd:60:4c:a8 by local choice (Reason: 3=DEAUTH_LEAVING) ------------[ cut here ]------------ Have pending ack frames! WARNING: CPU: 3 PID: 9232 at net/mac80211/main.c:1691 ieee80211_free_ack_frame+0x5c/0x90 [mac80211] CPU: 3 PID: 9232 Comm: rmmod Tainted: G C 6.10.1-200.fc40.aarch64 #1 Hardware name: pine64 Pine64 PinePhone Braveheart (1.1)/Pine64 PinePhone Braveheart (1.1), BIOS 2024.01 01/01/2024 pstate: 60400005 (nZCv daif +PAN -UAO -TCO -DIT -SSBS BTYPE=--) pc : ieee80211_free_ack_frame+0x5c/0x90 [mac80211] lr : ieee80211_free_ack_frame+0x5c/0x90 [mac80211] sp : ffff80008c1b37b0 x29: ffff80008c1b37b0 x28: ffff000003be8000 x27: 0000000000000000 x26: 0000000000000000 x25: ffff000003dc14b8 x24: ffff80008c1b37d0 x23: ffff000000ff9f80 x22: 0000000000000000 x21: 000000007fffffff x20: ffff80007c7e93d8 x19: ffff00006e66f400 x18: 0000000000000000 x17: ffff7ffffd2b3000 x16: ffff800083fc0000 x15: 0000000000000000 x14: 0000000000000000 x13: 2173656d61726620 x12: 6b636120676e6964 x11: 0000000000000000 x10: 000000000000005d x9 : ffff8000802af2b0 x8 : ffff80008c1b3430 x7 : 0000000000000001 x6 : 0000000000000001 x5 : 0000000000000000 x4 : 0000000000000000 x3 : 0000000000000000 x2 : 0000000000000000 x1 : 0000000000000000 x0 : ffff000003be8000 Call trace: ieee80211_free_ack_frame+0x5c/0x90 [mac80211] idr_for_each+0x74/0x110 ieee80211_free_hw+0x44/0xe8 [mac80211] rtw_sdio_remove+0x9c/0xc0 [rtw88_sdio] sdio_bus_remove+0x44/0x180 device_remove+0x54/0x90 device_release_driver_internal+0x1d4/0x238 driver_detach+0x54/0xc0 bus_remove_driver+0x78/0x108 driver_unregister+0x38/0x78 sdio_unregister_driver+0x2c/0x40 rtw_8723cs_driver_exit+0x18/0x1000 [rtw88_8723cs] __do_sys_delete_module.isra.0+0x190/0x338 __arm64_sys_delete_module+0x1c/0x30 invoke_syscall+0x74/0x100 el0_svc_common.constprop.0+0x48/0xf0 do_el0_svc+0x24/0x38 el0_svc+0x3c/0x158 el0t_64_sync_handler+0x120/0x138 el0t_64_sync+0x194/0x198 ---[ end trace 0000000000000000 ]--- Reported-by: Peter Robinson Closes: https://lore.kernel.org/linux-wireless/CALeDE9OAa56KMzgknaCD3quOgYuEHFx9_hcT=OFgmMAb+8MPyA@mail.gmail.com/ Tested-by: Ping-Ke Shih # 8723DU Signed-off-by: Ping-Ke Shih Link: https://patch.msgid.link/20240822014255.10211-2-pkshih@realtek.com --- sdio.c | 7 +++++++ usb.c | 12 ++++++++++++ 2 files changed, 19 insertions(+) diff --git a/sdio.c b/sdio.c index 5d5ce880..890f539b 100644 --- a/sdio.c +++ b/sdio.c @@ -1297,12 +1297,19 @@ static void rtw_sdio_deinit_tx(struct rtw_dev *rtwdev) struct rtw_sdio *rtwsdio = (struct rtw_sdio *)rtwdev->priv; int i; +#if LINUX_VERSION_CODE < KERNEL_VERSION(6, 13, 0) for (i = 0; i < RTK_MAX_TX_QUEUE_NUM; i++) skb_queue_purge(&rtwsdio->tx_queue[i]); +#endif flush_workqueue(rtwsdio->txwq); destroy_workqueue(rtwsdio->txwq); kfree(rtwsdio->tx_handler_data); + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 13, 0) + for (i = 0; i < RTK_MAX_TX_QUEUE_NUM; i++) + ieee80211_purge_tx_queue(rtwdev->hw, &rtwsdio->tx_queue[i]); +#endif } int rtw_sdio_probe(struct sdio_func *sdio_func, diff --git a/usb.c b/usb.c index 7de1168d..b779b7d7 100644 --- a/usb.c +++ b/usb.c @@ -428,10 +428,17 @@ static void rtw_usb_tx_handler(struct work_struct *work) static void rtw_usb_tx_queue_purge(struct rtw_usb *rtwusb) { +#if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 13, 0) + struct rtw_dev *rtwdev = rtwusb->rtwdev; +#endif int i; for (i = 0; i < ARRAY_SIZE(rtwusb->tx_queue); i++) +#if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 13, 0) + ieee80211_purge_tx_queue(rtwdev->hw, &rtwusb->tx_queue[i]); +#else skb_queue_purge(&rtwusb->tx_queue[i]); +#endif } static void rtw_usb_write_port_complete(struct urb *urb) @@ -924,9 +931,14 @@ static void rtw_usb_deinit_tx(struct rtw_dev *rtwdev) { struct rtw_usb *rtwusb = rtw_get_usb_priv(rtwdev); +#if LINUX_VERSION_CODE < KERNEL_VERSION(6, 13, 0) rtw_usb_tx_queue_purge(rtwusb); +#endif flush_workqueue(rtwusb->txwq); destroy_workqueue(rtwusb->txwq); +#if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 13, 0) + rtw_usb_tx_queue_purge(rtwusb); +#endif } static int rtw_usb_intf_init(struct rtw_dev *rtwdev, From ae34dfabe640c6115e58bd82609297826f389aed Mon Sep 17 00:00:00 2001 From: Bitterblue Smith Date: Sun, 13 Oct 2024 23:13:37 +0300 Subject: [PATCH 031/193] wifi: rtw88: Parse the RX descriptor with a single function Upstream commit bbb6f9be7f99464d5ab7e2f321fa728d33eeec9a + delete rtw8821a_query_rx_desc() to keep it compiling. rtw8703b_query_rx_desc(), rtw8723d_query_rx_desc(), rtw8821c_query_rx_desc(), rtw8822b_query_rx_desc(), and rtw8822c_query_rx_desc() are almost identical, so replace them all with a single function, rtw_rx_query_rx_desc(). Also, access the RX descriptor using a struct with __le32 members and le32_get_bits(). Tested with RTL8811CU, RTL8811AU, and RTL8812AU. Signed-off-by: Bitterblue Smith Tested-by: Ping-Ke Shih # RTL8723DE and RTL8822CE Acked-by: Ping-Ke Shih Signed-off-by: Ping-Ke Shih Link: https://patch.msgid.link/913f1747-38fc-4409-85a4-57bb9cee506b@gmail.com --- main.h | 5 ++-- pci.c | 2 +- rtw8703b.c | 56 +------------------------------------------ rtw8723d.c | 43 +-------------------------------- rtw8821a.c | 44 +--------------------------------- rtw8821c.c | 43 +-------------------------------- rtw8822b.c | 43 +-------------------------------- rtw8822c.c | 44 +--------------------------------- rx.c | 70 +++++++++++++++++++++++++++++++++++++++++++++++++----- rx.h | 64 ++++++++++++++++++++++++------------------------- sdio.c | 3 +-- usb.c | 4 ++-- 12 files changed, 107 insertions(+), 314 deletions(-) diff --git a/main.h b/main.h index 1b4baf3b..acabf5fd 100644 --- a/main.h +++ b/main.h @@ -965,9 +965,8 @@ struct rtw_chip_ops { void (*phy_set_param)(struct rtw_dev *rtwdev); void (*set_channel)(struct rtw_dev *rtwdev, u8 channel, u8 bandwidth, u8 primary_chan_idx); - void (*query_rx_desc)(struct rtw_dev *rtwdev, u8 *rx_desc, - struct rtw_rx_pkt_stat *pkt_stat, - struct ieee80211_rx_status *rx_status); + void (*query_phy_status)(struct rtw_dev *rtwdev, u8 *phy_status, + struct rtw_rx_pkt_stat *pkt_stat); u32 (*read_rf)(struct rtw_dev *rtwdev, enum rtw_rf_path rf_path, u32 addr, u32 mask); bool (*write_rf)(struct rtw_dev *rtwdev, enum rtw_rf_path rf_path, diff --git a/pci.c b/pci.c index 86a015e3..e6bb7a2c 100644 --- a/pci.c +++ b/pci.c @@ -1065,7 +1065,7 @@ static u32 rtw_pci_rx_napi(struct rtw_dev *rtwdev, struct rtw_pci *rtwpci, dma_sync_single_for_cpu(rtwdev->dev, dma, RTK_PCI_RX_BUF_SIZE, DMA_FROM_DEVICE); rx_desc = skb->data; - chip->ops->query_rx_desc(rtwdev, rx_desc, &pkt_stat, &rx_status); + rtw_rx_query_rx_desc(rtwdev, rx_desc, &pkt_stat, &rx_status); /* offset from rx_desc to payload */ pkt_offset = pkt_desc_sz + pkt_stat.drv_info_sz + diff --git a/rtw8703b.c b/rtw8703b.c index 59b79c44..c107e441 100644 --- a/rtw8703b.c +++ b/rtw8703b.c @@ -30,9 +30,6 @@ #define TBTT_PROHIBIT_HOLD_TIME 0x80 #define TBTT_PROHIBIT_HOLD_TIME_STOP_BCN 0x64 -/* raw pkt_stat->drv_info_sz is in unit of 8-bytes */ -#define RX_DRV_INFO_SZ_UNIT_8703B 8 - #define TRANS_SEQ_END \ 0xFFFF, \ RTW_PWR_CUT_ALL_MSK, \ @@ -1042,57 +1039,6 @@ static void query_phy_status(struct rtw_dev *rtwdev, u8 *phy_status, query_phy_status_ofdm(rtwdev, phy_status, pkt_stat); } -static void rtw8703b_query_rx_desc(struct rtw_dev *rtwdev, u8 *rx_desc, - struct rtw_rx_pkt_stat *pkt_stat, - struct ieee80211_rx_status *rx_status) -{ - struct ieee80211_hdr *hdr; - u32 desc_sz = rtwdev->chip->rx_pkt_desc_sz; - u8 *phy_status = NULL; - - memset(pkt_stat, 0, sizeof(*pkt_stat)); - - pkt_stat->phy_status = GET_RX_DESC_PHYST(rx_desc); - pkt_stat->icv_err = GET_RX_DESC_ICV_ERR(rx_desc); - pkt_stat->crc_err = GET_RX_DESC_CRC32(rx_desc); - pkt_stat->decrypted = !GET_RX_DESC_SWDEC(rx_desc) && - GET_RX_DESC_ENC_TYPE(rx_desc) != RX_DESC_ENC_NONE; - pkt_stat->is_c2h = GET_RX_DESC_C2H(rx_desc); - pkt_stat->pkt_len = GET_RX_DESC_PKT_LEN(rx_desc); - pkt_stat->drv_info_sz = GET_RX_DESC_DRV_INFO_SIZE(rx_desc); - pkt_stat->shift = GET_RX_DESC_SHIFT(rx_desc); - pkt_stat->rate = GET_RX_DESC_RX_RATE(rx_desc); - pkt_stat->cam_id = GET_RX_DESC_MACID(rx_desc); - pkt_stat->ppdu_cnt = 0; - pkt_stat->tsf_low = GET_RX_DESC_TSFL(rx_desc); - - pkt_stat->drv_info_sz *= RX_DRV_INFO_SZ_UNIT_8703B; - - if (pkt_stat->is_c2h) - return; - - hdr = (struct ieee80211_hdr *)(rx_desc + desc_sz + pkt_stat->shift + - pkt_stat->drv_info_sz); - - pkt_stat->bw = GET_RX_DESC_BW(rx_desc); - - if (pkt_stat->phy_status) { - phy_status = rx_desc + desc_sz + pkt_stat->shift; - query_phy_status(rtwdev, phy_status, pkt_stat); - } - - rtw_rx_fill_rx_status(rtwdev, pkt_stat, hdr, rx_status, phy_status); - - /* Rtl8723cs driver checks for size < 14 or size > 8192 and - * simply drops the packet. Maybe this should go into - * rtw_rx_fill_rx_status()? - */ - if (pkt_stat->pkt_len == 0) { - rx_status->flag |= RX_FLAG_NO_PSDU; - rtw_dbg(rtwdev, RTW_DBG_RX, "zero length packet"); - } -} - #define ADDA_ON_VAL_8703B 0x03c00014 static @@ -1966,7 +1912,7 @@ static const struct rtw_chip_ops rtw8703b_ops = { .read_efuse = rtw8703b_read_efuse, .phy_set_param = rtw8703b_phy_set_param, .set_channel = rtw8703b_set_channel, - .query_rx_desc = rtw8703b_query_rx_desc, + .query_phy_status = query_phy_status, .read_rf = rtw_phy_read_rf_sipi, .write_rf = rtw_phy_write_rf_reg_sipi, .set_tx_power_index = rtw8723x_set_tx_power_index, diff --git a/rtw8723d.c b/rtw8723d.c index a6d3496a..eeca31bf 100644 --- a/rtw8723d.c +++ b/rtw8723d.c @@ -227,47 +227,6 @@ static void query_phy_status(struct rtw_dev *rtwdev, u8 *phy_status, } } -static void rtw8723d_query_rx_desc(struct rtw_dev *rtwdev, u8 *rx_desc, - struct rtw_rx_pkt_stat *pkt_stat, - struct ieee80211_rx_status *rx_status) -{ - struct ieee80211_hdr *hdr; - u32 desc_sz = rtwdev->chip->rx_pkt_desc_sz; - u8 *phy_status = NULL; - - memset(pkt_stat, 0, sizeof(*pkt_stat)); - - pkt_stat->phy_status = GET_RX_DESC_PHYST(rx_desc); - pkt_stat->icv_err = GET_RX_DESC_ICV_ERR(rx_desc); - pkt_stat->crc_err = GET_RX_DESC_CRC32(rx_desc); - pkt_stat->decrypted = !GET_RX_DESC_SWDEC(rx_desc) && - GET_RX_DESC_ENC_TYPE(rx_desc) != RX_DESC_ENC_NONE; - pkt_stat->is_c2h = GET_RX_DESC_C2H(rx_desc); - pkt_stat->pkt_len = GET_RX_DESC_PKT_LEN(rx_desc); - pkt_stat->drv_info_sz = GET_RX_DESC_DRV_INFO_SIZE(rx_desc); - pkt_stat->shift = GET_RX_DESC_SHIFT(rx_desc); - pkt_stat->rate = GET_RX_DESC_RX_RATE(rx_desc); - pkt_stat->cam_id = GET_RX_DESC_MACID(rx_desc); - pkt_stat->ppdu_cnt = 0; - pkt_stat->tsf_low = GET_RX_DESC_TSFL(rx_desc); - - /* drv_info_sz is in unit of 8-bytes */ - pkt_stat->drv_info_sz *= 8; - - /* c2h cmd pkt's rx/phy status is not interested */ - if (pkt_stat->is_c2h) - return; - - hdr = (struct ieee80211_hdr *)(rx_desc + desc_sz + pkt_stat->shift + - pkt_stat->drv_info_sz); - if (pkt_stat->phy_status) { - phy_status = rx_desc + desc_sz + pkt_stat->shift; - query_phy_status(rtwdev, phy_status, pkt_stat); - } - - rtw_rx_fill_rx_status(rtwdev, pkt_stat, hdr, rx_status, phy_status); -} - static bool rtw8723d_check_spur_ov_thres(struct rtw_dev *rtwdev, u8 channel, u32 thres) { @@ -1435,7 +1394,7 @@ static const struct rtw_chip_ops rtw8723d_ops = { .power_off = rtw_power_off, .phy_set_param = rtw8723d_phy_set_param, .read_efuse = rtw8723x_read_efuse, - .query_rx_desc = rtw8723d_query_rx_desc, + .query_phy_status = query_phy_status, .set_channel = rtw8723d_set_channel, .mac_init = rtw8723x_mac_init, .shutdown = rtw8723d_shutdown, diff --git a/rtw8821a.c b/rtw8821a.c index 90e4d7fc..d30296d8 100644 --- a/rtw8821a.c +++ b/rtw8821a.c @@ -1676,48 +1676,6 @@ static void rtw8821a_query_phy_status(struct rtw_dev *rtwdev, u8 *phy_status, } } -static void rtw8821a_query_rx_desc(struct rtw_dev *rtwdev, u8 *rx_desc, - struct rtw_rx_pkt_stat *pkt_stat, - struct ieee80211_rx_status *rx_status) -{ - u32 desc_sz = rtwdev->chip->rx_pkt_desc_sz; - struct ieee80211_hdr *hdr; - u8 *phy_status = NULL; - - memset(pkt_stat, 0, sizeof(*pkt_stat)); - - pkt_stat->phy_status = GET_RX_DESC_PHYST(rx_desc); - pkt_stat->icv_err = GET_RX_DESC_ICV_ERR(rx_desc); - pkt_stat->crc_err = GET_RX_DESC_CRC32(rx_desc); - pkt_stat->decrypted = !GET_RX_DESC_SWDEC(rx_desc) && - GET_RX_DESC_ENC_TYPE(rx_desc) != RX_DESC_ENC_NONE; - pkt_stat->is_c2h = GET_RX_DESC_C2H(rx_desc); - pkt_stat->pkt_len = GET_RX_DESC_PKT_LEN(rx_desc); - pkt_stat->drv_info_sz = GET_RX_DESC_DRV_INFO_SIZE(rx_desc); - pkt_stat->shift = GET_RX_DESC_SHIFT(rx_desc); - pkt_stat->rate = GET_RX_DESC_RX_RATE(rx_desc); - pkt_stat->cam_id = GET_RX_DESC_MACID(rx_desc); - pkt_stat->ppdu_cnt = 0; - pkt_stat->tsf_low = GET_RX_DESC_TSFL(rx_desc); - pkt_stat->bw = GET_RX_DESC_BW(rx_desc); - - /* drv_info_sz is in unit of 8-bytes */ - pkt_stat->drv_info_sz *= 8; - - /* c2h cmd pkt's rx/phy status is not interested */ - if (pkt_stat->is_c2h) - return; - - hdr = (struct ieee80211_hdr *)(rx_desc + desc_sz + pkt_stat->shift + - pkt_stat->drv_info_sz); - if (pkt_stat->phy_status) { - phy_status = rx_desc + desc_sz + pkt_stat->shift; - rtw8821a_query_phy_status(rtwdev, phy_status, pkt_stat); - } - - rtw_rx_fill_rx_status(rtwdev, pkt_stat, hdr, rx_status, phy_status); -} - static void rtw8821a_set_tx_power_index_by_rate(struct rtw_dev *rtwdev, u8 path, u8 rs, u32 *phy_pwr_idx) @@ -3769,7 +3727,7 @@ static struct rtw_chip_ops rtw8821a_ops = { .power_off = rtw8821a_power_off, .phy_set_param = NULL, .read_efuse = rtw8821a_read_efuse, - .query_rx_desc = rtw8821a_query_rx_desc, + .query_phy_status = rtw8821a_query_phy_status, .set_channel = rtw8821a_set_channel, .mac_init = NULL, .read_rf = rtw8821a_phy_read_rf, diff --git a/rtw8821c.c b/rtw8821c.c index d45f808a..9b1aa402 100644 --- a/rtw8821c.c +++ b/rtw8821c.c @@ -680,47 +680,6 @@ static void query_phy_status(struct rtw_dev *rtwdev, u8 *phy_status, } } -static void rtw8821c_query_rx_desc(struct rtw_dev *rtwdev, u8 *rx_desc, - struct rtw_rx_pkt_stat *pkt_stat, - struct ieee80211_rx_status *rx_status) -{ - struct ieee80211_hdr *hdr; - u32 desc_sz = rtwdev->chip->rx_pkt_desc_sz; - u8 *phy_status = NULL; - - memset(pkt_stat, 0, sizeof(*pkt_stat)); - - pkt_stat->phy_status = GET_RX_DESC_PHYST(rx_desc); - pkt_stat->icv_err = GET_RX_DESC_ICV_ERR(rx_desc); - pkt_stat->crc_err = GET_RX_DESC_CRC32(rx_desc); - pkt_stat->decrypted = !GET_RX_DESC_SWDEC(rx_desc) && - GET_RX_DESC_ENC_TYPE(rx_desc) != RX_DESC_ENC_NONE; - pkt_stat->is_c2h = GET_RX_DESC_C2H(rx_desc); - pkt_stat->pkt_len = GET_RX_DESC_PKT_LEN(rx_desc); - pkt_stat->drv_info_sz = GET_RX_DESC_DRV_INFO_SIZE(rx_desc); - pkt_stat->shift = GET_RX_DESC_SHIFT(rx_desc); - pkt_stat->rate = GET_RX_DESC_RX_RATE(rx_desc); - pkt_stat->cam_id = GET_RX_DESC_MACID(rx_desc); - pkt_stat->ppdu_cnt = GET_RX_DESC_PPDU_CNT(rx_desc); - pkt_stat->tsf_low = GET_RX_DESC_TSFL(rx_desc); - - /* drv_info_sz is in unit of 8-bytes */ - pkt_stat->drv_info_sz *= 8; - - /* c2h cmd pkt's rx/phy status is not interested */ - if (pkt_stat->is_c2h) - return; - - hdr = (struct ieee80211_hdr *)(rx_desc + desc_sz + pkt_stat->shift + - pkt_stat->drv_info_sz); - if (pkt_stat->phy_status) { - phy_status = rx_desc + desc_sz + pkt_stat->shift; - query_phy_status(rtwdev, phy_status, pkt_stat); - } - - rtw_rx_fill_rx_status(rtwdev, pkt_stat, hdr, rx_status, phy_status); -} - static void rtw8821c_set_tx_power_index_by_rate(struct rtw_dev *rtwdev, u8 path, u8 rs) { @@ -1682,7 +1641,7 @@ static const struct rtw_chip_ops rtw8821c_ops = { .power_off = rtw_power_off, .phy_set_param = rtw8821c_phy_set_param, .read_efuse = rtw8821c_read_efuse, - .query_rx_desc = rtw8821c_query_rx_desc, + .query_phy_status = query_phy_status, .set_channel = rtw8821c_set_channel, .mac_init = rtw8821c_mac_init, .read_rf = rtw_phy_read_rf, diff --git a/rtw8822b.c b/rtw8822b.c index 5f7858c5..c5e27059 100644 --- a/rtw8822b.c +++ b/rtw8822b.c @@ -934,47 +934,6 @@ static void query_phy_status(struct rtw_dev *rtwdev, u8 *phy_status, } } -static void rtw8822b_query_rx_desc(struct rtw_dev *rtwdev, u8 *rx_desc, - struct rtw_rx_pkt_stat *pkt_stat, - struct ieee80211_rx_status *rx_status) -{ - struct ieee80211_hdr *hdr; - u32 desc_sz = rtwdev->chip->rx_pkt_desc_sz; - u8 *phy_status = NULL; - - memset(pkt_stat, 0, sizeof(*pkt_stat)); - - pkt_stat->phy_status = GET_RX_DESC_PHYST(rx_desc); - pkt_stat->icv_err = GET_RX_DESC_ICV_ERR(rx_desc); - pkt_stat->crc_err = GET_RX_DESC_CRC32(rx_desc); - pkt_stat->decrypted = !GET_RX_DESC_SWDEC(rx_desc) && - GET_RX_DESC_ENC_TYPE(rx_desc) != RX_DESC_ENC_NONE; - pkt_stat->is_c2h = GET_RX_DESC_C2H(rx_desc); - pkt_stat->pkt_len = GET_RX_DESC_PKT_LEN(rx_desc); - pkt_stat->drv_info_sz = GET_RX_DESC_DRV_INFO_SIZE(rx_desc); - pkt_stat->shift = GET_RX_DESC_SHIFT(rx_desc); - pkt_stat->rate = GET_RX_DESC_RX_RATE(rx_desc); - pkt_stat->cam_id = GET_RX_DESC_MACID(rx_desc); - pkt_stat->ppdu_cnt = GET_RX_DESC_PPDU_CNT(rx_desc); - pkt_stat->tsf_low = GET_RX_DESC_TSFL(rx_desc); - - /* drv_info_sz is in unit of 8-bytes */ - pkt_stat->drv_info_sz *= 8; - - /* c2h cmd pkt's rx/phy status is not interested */ - if (pkt_stat->is_c2h) - return; - - hdr = (struct ieee80211_hdr *)(rx_desc + desc_sz + pkt_stat->shift + - pkt_stat->drv_info_sz); - if (pkt_stat->phy_status) { - phy_status = rx_desc + desc_sz + pkt_stat->shift; - query_phy_status(rtwdev, phy_status, pkt_stat); - } - - rtw_rx_fill_rx_status(rtwdev, pkt_stat, hdr, rx_status, phy_status); -} - static void rtw8822b_set_tx_power_index_by_rate(struct rtw_dev *rtwdev, u8 path, u8 rs) { @@ -2171,7 +2130,7 @@ static const struct rtw_chip_ops rtw8822b_ops = { .power_off = rtw_power_off, .phy_set_param = rtw8822b_phy_set_param, .read_efuse = rtw8822b_read_efuse, - .query_rx_desc = rtw8822b_query_rx_desc, + .query_phy_status = query_phy_status, .set_channel = rtw8822b_set_channel, .mac_init = rtw8822b_mac_init, .read_rf = rtw_phy_read_rf, diff --git a/rtw8822c.c b/rtw8822c.c index e33e46e2..11509adf 100644 --- a/rtw8822c.c +++ b/rtw8822c.c @@ -2690,48 +2690,6 @@ static void query_phy_status(struct rtw_dev *rtwdev, u8 *phy_status, } } -static void rtw8822c_query_rx_desc(struct rtw_dev *rtwdev, u8 *rx_desc, - struct rtw_rx_pkt_stat *pkt_stat, - struct ieee80211_rx_status *rx_status) -{ - struct ieee80211_hdr *hdr; - u32 desc_sz = rtwdev->chip->rx_pkt_desc_sz; - u8 *phy_status = NULL; - - memset(pkt_stat, 0, sizeof(*pkt_stat)); - - pkt_stat->phy_status = GET_RX_DESC_PHYST(rx_desc); - pkt_stat->icv_err = GET_RX_DESC_ICV_ERR(rx_desc); - pkt_stat->crc_err = GET_RX_DESC_CRC32(rx_desc); - pkt_stat->decrypted = !GET_RX_DESC_SWDEC(rx_desc) && - GET_RX_DESC_ENC_TYPE(rx_desc) != RX_DESC_ENC_NONE; - pkt_stat->is_c2h = GET_RX_DESC_C2H(rx_desc); - pkt_stat->pkt_len = GET_RX_DESC_PKT_LEN(rx_desc); - pkt_stat->drv_info_sz = GET_RX_DESC_DRV_INFO_SIZE(rx_desc); - pkt_stat->shift = GET_RX_DESC_SHIFT(rx_desc); - pkt_stat->rate = GET_RX_DESC_RX_RATE(rx_desc); - pkt_stat->cam_id = GET_RX_DESC_MACID(rx_desc); - pkt_stat->ppdu_cnt = GET_RX_DESC_PPDU_CNT(rx_desc); - pkt_stat->tsf_low = GET_RX_DESC_TSFL(rx_desc); - - /* drv_info_sz is in unit of 8-bytes */ - pkt_stat->drv_info_sz *= 8; - - /* c2h cmd pkt's rx/phy status is not interested */ - if (pkt_stat->is_c2h) - return; - - hdr = (struct ieee80211_hdr *)(rx_desc + desc_sz + pkt_stat->shift + - pkt_stat->drv_info_sz); - pkt_stat->hdr = hdr; - if (pkt_stat->phy_status) { - phy_status = rx_desc + desc_sz + pkt_stat->shift; - query_phy_status(rtwdev, phy_status, pkt_stat); - } - - rtw_rx_fill_rx_status(rtwdev, pkt_stat, hdr, rx_status, phy_status); -} - static void rtw8822c_set_write_tx_power_ref(struct rtw_dev *rtwdev, u8 *tx_pwr_ref_cck, u8 *tx_pwr_ref_ofdm) @@ -4983,7 +4941,7 @@ static const struct rtw_chip_ops rtw8822c_ops = { .power_off = rtw_power_off, .phy_set_param = rtw8822c_phy_set_param, .read_efuse = rtw8822c_read_efuse, - .query_rx_desc = rtw8822c_query_rx_desc, + .query_phy_status = query_phy_status, .set_channel = rtw8822c_set_channel, .mac_init = rtw8822c_mac_init, .dump_fw_crash = rtw8822c_dump_fw_crash, diff --git a/rx.c b/rx.c index 3dd02fa7..b560c0b5 100644 --- a/rx.c +++ b/rx.c @@ -187,11 +187,10 @@ void rtw_update_rx_freq_from_ie(struct rtw_dev *rtwdev, struct sk_buff *skb, } EXPORT_SYMBOL(rtw_update_rx_freq_from_ie); -void rtw_rx_fill_rx_status(struct rtw_dev *rtwdev, - struct rtw_rx_pkt_stat *pkt_stat, - struct ieee80211_hdr *hdr, - struct ieee80211_rx_status *rx_status, - u8 *phy_status) +static void rtw_rx_fill_rx_status(struct rtw_dev *rtwdev, + struct rtw_rx_pkt_stat *pkt_stat, + struct ieee80211_hdr *hdr, + struct ieee80211_rx_status *rx_status) { struct ieee80211_hw *hw = rtwdev->hw; u8 path; @@ -271,5 +270,64 @@ void rtw_rx_fill_rx_status(struct rtw_dev *rtwdev, } rtw_rx_addr_match(rtwdev, pkt_stat, hdr); + + /* Rtl8723cs driver checks for size < 14 or size > 8192 and + * simply drops the packet. + */ + if (rtwdev->chip->id == RTW_CHIP_TYPE_8703B && pkt_stat->pkt_len == 0) { + rx_status->flag |= RX_FLAG_NO_PSDU; + rtw_dbg(rtwdev, RTW_DBG_RX, "zero length packet"); + } +} + +void rtw_rx_query_rx_desc(struct rtw_dev *rtwdev, void *rx_desc8, + struct rtw_rx_pkt_stat *pkt_stat, + struct ieee80211_rx_status *rx_status) +{ + u32 desc_sz = rtwdev->chip->rx_pkt_desc_sz; + struct rtw_rx_desc *rx_desc = rx_desc8; + struct ieee80211_hdr *hdr; + u32 enc_type, swdec; + void *phy_status; + + memset(pkt_stat, 0, sizeof(*pkt_stat)); + + pkt_stat->pkt_len = le32_get_bits(rx_desc->w0, RTW_RX_DESC_W0_PKT_LEN); + pkt_stat->crc_err = le32_get_bits(rx_desc->w0, RTW_RX_DESC_W0_CRC32); + pkt_stat->icv_err = le32_get_bits(rx_desc->w0, RTW_RX_DESC_W0_ICV_ERR); + pkt_stat->drv_info_sz = le32_get_bits(rx_desc->w0, + RTW_RX_DESC_W0_DRV_INFO_SIZE); + enc_type = le32_get_bits(rx_desc->w0, RTW_RX_DESC_W0_ENC_TYPE); + pkt_stat->shift = le32_get_bits(rx_desc->w0, RTW_RX_DESC_W0_SHIFT); + pkt_stat->phy_status = le32_get_bits(rx_desc->w0, RTW_RX_DESC_W0_PHYST); + swdec = le32_get_bits(rx_desc->w0, RTW_RX_DESC_W0_SWDEC); + pkt_stat->decrypted = !swdec && enc_type != RX_DESC_ENC_NONE; + + pkt_stat->cam_id = le32_get_bits(rx_desc->w1, RTW_RX_DESC_W1_MACID); + + pkt_stat->is_c2h = le32_get_bits(rx_desc->w2, RTW_RX_DESC_W2_C2H); + pkt_stat->ppdu_cnt = le32_get_bits(rx_desc->w2, RTW_RX_DESC_W2_PPDU_CNT); + + pkt_stat->rate = le32_get_bits(rx_desc->w3, RTW_RX_DESC_W3_RX_RATE); + + pkt_stat->bw = le32_get_bits(rx_desc->w4, RTW_RX_DESC_W4_BW); + + pkt_stat->tsf_low = le32_get_bits(rx_desc->w5, RTW_RX_DESC_W5_TSFL); + + /* drv_info_sz is in unit of 8-bytes */ + pkt_stat->drv_info_sz *= 8; + + /* c2h cmd pkt's rx/phy status is not interested */ + if (pkt_stat->is_c2h) + return; + + phy_status = rx_desc8 + desc_sz + pkt_stat->shift; + hdr = phy_status + pkt_stat->drv_info_sz; + pkt_stat->hdr = hdr; + + if (pkt_stat->phy_status) + rtwdev->chip->ops->query_phy_status(rtwdev, phy_status, pkt_stat); + + rtw_rx_fill_rx_status(rtwdev, pkt_stat, hdr, rx_status); } -EXPORT_SYMBOL(rtw_rx_fill_rx_status); +EXPORT_SYMBOL(rtw_rx_query_rx_desc); diff --git a/rx.h b/rx.h index 9f001911..6b7dee24 100644 --- a/rx.h +++ b/rx.h @@ -14,42 +14,40 @@ enum rtw_rx_desc_enc { RX_DESC_ENC_WEP104 = 5, }; -#define GET_RX_DESC_PHYST(rxdesc) \ - le32_get_bits(*((__le32 *)(rxdesc) + 0x00), BIT(26)) -#define GET_RX_DESC_ICV_ERR(rxdesc) \ - le32_get_bits(*((__le32 *)(rxdesc) + 0x00), BIT(15)) -#define GET_RX_DESC_CRC32(rxdesc) \ - le32_get_bits(*((__le32 *)(rxdesc) + 0x00), BIT(14)) -#define GET_RX_DESC_SWDEC(rxdesc) \ - le32_get_bits(*((__le32 *)(rxdesc) + 0x00), BIT(27)) -#define GET_RX_DESC_C2H(rxdesc) \ - le32_get_bits(*((__le32 *)(rxdesc) + 0x02), BIT(28)) -#define GET_RX_DESC_PKT_LEN(rxdesc) \ - le32_get_bits(*((__le32 *)(rxdesc) + 0x00), GENMASK(13, 0)) -#define GET_RX_DESC_DRV_INFO_SIZE(rxdesc) \ - le32_get_bits(*((__le32 *)(rxdesc) + 0x00), GENMASK(19, 16)) -#define GET_RX_DESC_SHIFT(rxdesc) \ - le32_get_bits(*((__le32 *)(rxdesc) + 0x00), GENMASK(25, 24)) -#define GET_RX_DESC_ENC_TYPE(rxdesc) \ - le32_get_bits(*((__le32 *)(rxdesc) + 0x00), GENMASK(22, 20)) -#define GET_RX_DESC_RX_RATE(rxdesc) \ - le32_get_bits(*((__le32 *)(rxdesc) + 0x03), GENMASK(6, 0)) -#define GET_RX_DESC_MACID(rxdesc) \ - le32_get_bits(*((__le32 *)(rxdesc) + 0x01), GENMASK(6, 0)) -#define GET_RX_DESC_PPDU_CNT(rxdesc) \ - le32_get_bits(*((__le32 *)(rxdesc) + 0x02), GENMASK(30, 29)) -#define GET_RX_DESC_TSFL(rxdesc) \ - le32_get_bits(*((__le32 *)(rxdesc) + 0x05), GENMASK(31, 0)) -#define GET_RX_DESC_BW(rxdesc) \ - (le32_get_bits(*((__le32 *)(rxdesc) + 0x04), GENMASK(5, 4))) +struct rtw_rx_desc { + __le32 w0; + __le32 w1; + __le32 w2; + __le32 w3; + __le32 w4; + __le32 w5; +} __packed; + +#define RTW_RX_DESC_W0_PKT_LEN GENMASK(13, 0) +#define RTW_RX_DESC_W0_CRC32 BIT(14) +#define RTW_RX_DESC_W0_ICV_ERR BIT(15) +#define RTW_RX_DESC_W0_DRV_INFO_SIZE GENMASK(19, 16) +#define RTW_RX_DESC_W0_ENC_TYPE GENMASK(22, 20) +#define RTW_RX_DESC_W0_SHIFT GENMASK(25, 24) +#define RTW_RX_DESC_W0_PHYST BIT(26) +#define RTW_RX_DESC_W0_SWDEC BIT(27) + +#define RTW_RX_DESC_W1_MACID GENMASK(6, 0) + +#define RTW_RX_DESC_W2_C2H BIT(28) +#define RTW_RX_DESC_W2_PPDU_CNT GENMASK(30, 29) + +#define RTW_RX_DESC_W3_RX_RATE GENMASK(6, 0) + +#define RTW_RX_DESC_W4_BW GENMASK(5, 4) + +#define RTW_RX_DESC_W5_TSFL GENMASK(31, 0) void rtw_rx_stats(struct rtw_dev *rtwdev, struct ieee80211_vif *vif, struct sk_buff *skb); -void rtw_rx_fill_rx_status(struct rtw_dev *rtwdev, - struct rtw_rx_pkt_stat *pkt_stat, - struct ieee80211_hdr *hdr, - struct ieee80211_rx_status *rx_status, - u8 *phy_status); +void rtw_rx_query_rx_desc(struct rtw_dev *rtwdev, void *rx_desc8, + struct rtw_rx_pkt_stat *pkt_stat, + struct ieee80211_rx_status *rx_status); void rtw_update_rx_freq_from_ie(struct rtw_dev *rtwdev, struct sk_buff *skb, struct ieee80211_rx_status *rx_status, struct rtw_rx_pkt_stat *pkt_stat); diff --git a/sdio.c b/sdio.c index 890f539b..7b053dbb 100644 --- a/sdio.c +++ b/sdio.c @@ -981,8 +981,7 @@ static void rtw_sdio_rxfifo_recv(struct rtw_dev *rtwdev, u32 rx_len) while (true) { rx_desc = skb->data; - chip->ops->query_rx_desc(rtwdev, rx_desc, &pkt_stat, - &rx_status); + rtw_rx_query_rx_desc(rtwdev, rx_desc, &pkt_stat, &rx_status); pkt_offset = pkt_desc_sz + pkt_stat.drv_info_sz + pkt_stat.shift; diff --git a/usb.c b/usb.c index b779b7d7..45f6d08a 100644 --- a/usb.c +++ b/usb.c @@ -583,8 +583,8 @@ static void rtw_usb_rx_handler(struct work_struct *work) do { rx_desc = skb->data; - chip->ops->query_rx_desc(rtwdev, rx_desc, &pkt_stat, - &rx_status); + rtw_rx_query_rx_desc(rtwdev, rx_desc, &pkt_stat, + &rx_status); pkt_offset = pkt_desc_sz + pkt_stat.drv_info_sz + pkt_stat.shift; From 8a07dbf65e007c54342c75516ae7f55bff69b66e Mon Sep 17 00:00:00 2001 From: Bitterblue Smith Date: Sun, 13 Oct 2024 23:55:17 +0300 Subject: [PATCH 032/193] Update 8821au/8812au to match v2 of the upstream patches https://lore.kernel.org/linux-wireless/d2870a44-9b91-4090-9a25-873eb62997f5@gmail.com/ --- Makefile | 12 +- coex.h | 10 + fw.c | 19 +- fw.h | 18 +- main.c | 34 +- phy.c | 11 +- reg.h | 174 ++ rtw8812a.c | 1102 ++++++++++++ rtw8812a.h | 10 + rtw8812a_table.c | 8 +- rtw8812a_table.h | 8 +- rtw8812au.c | 4 +- rtw8821a.c | 4149 +++++++--------------------------------------- rtw8821a.h | 375 +---- rtw8821a_table.c | 14 +- rtw8821a_table.h | 8 +- rtw8821au.c | 2 +- rtw8821c.c | 1 + rtw8821c.h | 24 - rtw8822b.c | 1 + rtw8822b.h | 12 - rtw8822c.c | 1 + rtw88xxa.c | 1995 ++++++++++++++++++++++ rtw88xxa.h | 175 ++ 24 files changed, 4157 insertions(+), 4010 deletions(-) create mode 100644 rtw8812a.c create mode 100644 rtw8812a.h create mode 100644 rtw88xxa.c create mode 100644 rtw88xxa.h diff --git a/Makefile b/Makefile index 574c95b6..0aa40893 100644 --- a/Makefile +++ b/Makefile @@ -5,8 +5,8 @@ FIRMWAREDIR := /lib/firmware/rtw88 MODLIST := rtw_8723cs rtw_8723de rtw_8723ds rtw_8723du \ rtw_8812au rtw_8821au rtw_8821ce rtw_8821cs rtw_8821cu \ rtw_8822be rtw_8822bs rtw_8822bu rtw_8822ce rtw_8822cs rtw_8822cu \ - rtw_8703b rtw_8723d rtw_8821a rtw_8821c rtw_8822b rtw_8822c \ - rtw_8723x rtw_pci rtw_sdio rtw_usb rtw_core + rtw_8703b rtw_8723d rtw_8821a rtw_8812a rtw_8821c rtw_8822b rtw_8822c \ + rtw_8723x rtw_88xxa rtw_pci rtw_sdio rtw_usb rtw_core # Handle the move of the entire rtw88 tree ifneq ("","$(wildcard /lib/modules/$(KVER)/kernel/drivers/net/wireless/realtek)") MODDESTDIR := /lib/modules/$(KVER)/kernel/drivers/net/wireless/realtek/rtw88 @@ -99,7 +99,13 @@ obj-m += rtw_8812au.o rtw_8812au-objs := rtw8812au.o obj-m += rtw_8821a.o -rtw_8821a-objs := rtw8821a.o rtw8821a_table.o rtw8812a_table.o +rtw_8821a-objs := rtw8821a.o rtw8821a_table.o + +obj-m += rtw_8812a.o +rtw_8812a-objs := rtw8812a.o rtw8812a_table.o + +obj-m += rtw_88xxa.o +rtw_88xxa-objs := rtw88xxa.o obj-m += rtw_8821au.o rtw_8821au-objs := rtw8821au.o diff --git a/coex.h b/coex.h index b6400e87..c398be83 100644 --- a/coex.h +++ b/coex.h @@ -420,4 +420,14 @@ static inline bool rtw_coex_disabled(struct rtw_dev *rtwdev) return coex_stat->bt_disabled; } +static inline void rtw_coex_active_query_bt_info(struct rtw_dev *rtwdev) +{ + /* The RTL8821AU firmware doesn't send C2H_BT_INFO by itself + * when bluetooth headphones are disconnected, so we have to + * ask for it regularly. + */ + if (rtwdev->chip->id == RTW_CHIP_TYPE_8821A && rtwdev->efuse.btcoex) + rtw_coex_query_bt_info(rtwdev); +} + #endif diff --git a/fw.c b/fw.c index bd4faa02..08713c13 100644 --- a/fw.c +++ b/fw.c @@ -139,28 +139,30 @@ static u16 get_max_amsdu_len(u32 bit_rate) struct rtw_fw_iter_ra_data { struct rtw_dev *rtwdev; u8 *payload; + u8 length; }; static void rtw_fw_ra_report_iter(void *data, struct ieee80211_sta *sta) { struct rtw_fw_iter_ra_data *ra_data = data; + struct rtw_c2h_ra_rpt *ra_rpt = (struct rtw_c2h_ra_rpt *)ra_data->payload; struct rtw_sta_info *si = (struct rtw_sta_info *)sta->drv_priv; u8 mac_id, rate, sgi, bw; u8 mcs, nss; u32 bit_rate; - mac_id = GET_RA_REPORT_MACID(ra_data->payload); + mac_id = ra_rpt->mac_id; if (si->mac_id != mac_id) return; si->ra_report.txrate.flags = 0; - rate = GET_RA_REPORT_RATE(ra_data->payload); - sgi = GET_RA_REPORT_SGI(ra_data->payload); - if (si->rtwdev->chip->c2h_ra_report_size < 7) - bw = si->bw_mode; + rate = u8_get_bits(ra_rpt->rate_sgi, RTW_C2H_RA_RPT_RATE); + sgi = u8_get_bits(ra_rpt->rate_sgi, RTW_C2H_RA_RPT_SGI); + if (ra_data->length >= offsetofend(typeof(*ra_rpt), bw)) + bw = ra_rpt->bw; else - bw = GET_RA_REPORT_BW(ra_data->payload); + bw = si->bw_mode; if (rate < DESC_RATEMCS0) { si->ra_report.txrate.legacy = rtw_desc_to_bitrate(rate); @@ -204,15 +206,18 @@ static void rtw_fw_ra_report_iter(void *data, struct ieee80211_sta *sta) static void rtw_fw_ra_report_handle(struct rtw_dev *rtwdev, u8 *payload, u8 length) { + struct rtw_c2h_ra_rpt *ra_rpt = (struct rtw_c2h_ra_rpt *)payload; struct rtw_fw_iter_ra_data ra_data; if (WARN(length < rtwdev->chip->c2h_ra_report_size, "invalid ra report c2h length %d\n", length)) return; - rtwdev->dm_info.tx_rate = GET_RA_REPORT_RATE(payload); + rtwdev->dm_info.tx_rate = u8_get_bits(ra_rpt->rate_sgi, + RTW_C2H_RA_RPT_RATE); ra_data.rtwdev = rtwdev; ra_data.payload = payload; + ra_data.length = length; rtw_iterate_stas_atomic(rtwdev, rtw_fw_ra_report_iter, &ra_data); } diff --git a/fw.h b/fw.h index f287f004..a42cea5f 100644 --- a/fw.h +++ b/fw.h @@ -85,6 +85,20 @@ struct rtw_c2h_adaptivity { u8 option; } __packed; +struct rtw_c2h_ra_rpt { + u8 rate_sgi; + u8 mac_id; + u8 byte2; + u8 status; + u8 byte4; + u8 ra_ratio; + u8 bw; + u8 txcls_rate; +} __packed; + +#define RTW_C2H_RA_RPT_RATE GENMASK(6, 0) +#define RTW_C2H_RA_RPT_SGI BIT(7) + struct rtw_h2c_register { u32 w0; u32 w1; @@ -364,10 +378,6 @@ struct rtw_fw_hdr_legacy { #define GET_CHAN_SWITCH_CENTRAL_CH(c2h_payload) (c2h_payload[2]) #define GET_CHAN_SWITCH_ID(c2h_payload) (c2h_payload[3]) #define GET_CHAN_SWITCH_STATUS(c2h_payload) (c2h_payload[4]) -#define GET_RA_REPORT_RATE(c2h_payload) (c2h_payload[0] & 0x7f) -#define GET_RA_REPORT_SGI(c2h_payload) ((c2h_payload[0] & 0x80) >> 7) -#define GET_RA_REPORT_BW(c2h_payload) (c2h_payload[6]) -#define GET_RA_REPORT_MACID(c2h_payload) (c2h_payload[1]) #define GET_BCN_FILTER_NOTIFY_TYPE(c2h_payload) (c2h_payload[1] & 0xf) #define GET_BCN_FILTER_NOTIFY_EVENT(c2h_payload) (c2h_payload[1] & 0x10) diff --git a/main.c b/main.c index b06a7e6e..3a6ead45 100644 --- a/main.c +++ b/main.c @@ -208,6 +208,21 @@ static void rtw_vif_watch_dog_iter(void *data, struct ieee80211_vif *vif) rtwvif->stats.rx_cnt = 0; } +static void rtw_sw_beacon_loss_check(struct rtw_dev *rtwdev, + struct rtw_vif *rtwvif, int received_beacons) +{ + int watchdog_delay = 2000000 / 1024; /* TU */ + int beacon_int, expected_beacons; + + if (rtw_fw_feature_check(&rtwdev->fw, FW_FEATURE_BCN_FILTER) || !rtwvif) + return; + + beacon_int = rtwvif_to_vif(rtwvif)->bss_conf.beacon_int; + expected_beacons = DIV_ROUND_UP(watchdog_delay, beacon_int); + + rtwdev->beacon_loss = received_beacons < expected_beacons / 2; +} + /* process TX/RX statistics periodically for hardware, * the information helps hardware to enhance performance */ @@ -218,6 +233,7 @@ static void rtw_watch_dog_work(struct work_struct *work) struct rtw_traffic_stats *stats = &rtwdev->stats; struct rtw_watch_dog_iter_data data = {}; bool busy_traffic = test_bit(RTW_FLAG_BUSY_TRAFFIC, rtwdev->flags); + int received_beacons = rtwdev->dm_info.cur_pkt_count.num_bcn_pkt; u32 tx_unicast_mbps, rx_unicast_mbps; bool ps_active; @@ -260,15 +276,11 @@ static void rtw_watch_dog_work(struct work_struct *work) if (test_bit(RTW_FLAG_SCANNING, rtwdev->flags)) goto unlock; - int received_beacons = rtwdev->dm_info.cur_pkt_count.num_bcn_pkt; - /* make sure BB/RF is working for dynamic mech */ rtw_leave_lps(rtwdev); rtw_coex_wl_status_check(rtwdev); rtw_coex_query_bt_hid_list(rtwdev); - - if (rtwdev->chip->id == RTW_CHIP_TYPE_8821A && rtwdev->efuse.btcoex) - rtw_coex_query_bt_info(rtwdev); + rtw_coex_active_query_bt_info(rtwdev); rtw_phy_dynamic_mechanism(rtwdev); @@ -281,14 +293,7 @@ static void rtw_watch_dog_work(struct work_struct *work) */ rtw_iterate_vifs(rtwdev, rtw_vif_watch_dog_iter, &data); - if (!rtw_fw_feature_check(&rtwdev->fw, FW_FEATURE_BCN_FILTER) && - data.rtwvif) { - int beacon_int = rtwvif_to_vif(data.rtwvif)->bss_conf.beacon_int; - int watchdog_delay = 2000000 / 1024; /* TU */ - int expected_beacons = DIV_ROUND_UP(watchdog_delay, beacon_int); - - rtwdev->beacon_loss = received_beacons < expected_beacons / 2; - } + rtw_sw_beacon_loss_check(rtwdev, data.rtwvif, received_beacons); /* fw supports only one station associated to enter lps, if there are * more than two stations associated to the AP, then we can not enter @@ -2043,7 +2048,7 @@ static int rtw_dump_hw_feature(struct rtw_dev *rtwdev) int i; if (!rtwdev->chip->hw_feature_report) - goto print_hw_cap; + return 0; id = rtw_read8(rtwdev, REG_C2HEVT); if (id != C2H_HW_FEATURE_REPORT) { @@ -2069,7 +2074,6 @@ static int rtw_dump_hw_feature(struct rtw_dev *rtwdev) efuse->hw_cap.nss > rtwdev->hal.rf_path_num) efuse->hw_cap.nss = rtwdev->hal.rf_path_num; -print_hw_cap: rtw_dbg(rtwdev, RTW_DBG_EFUSE, "hw cap: hci=0x%02x, bw=0x%02x, ptcl=0x%02x, ant_num=%d, nss=%d\n", efuse->hw_cap.hci, efuse->hw_cap.bw, efuse->hw_cap.ptcl, diff --git a/phy.c b/phy.c index 192f7e90..aa4248ab 100644 --- a/phy.c +++ b/phy.c @@ -1053,8 +1053,8 @@ void rtw_phy_setup_phy_cond(struct rtw_dev *rtwdev, u32 pkg) { struct rtw_hal *hal = &rtwdev->hal; struct rtw_efuse *efuse = &rtwdev->efuse; - struct rtw_phy_cond cond = {0}; - struct rtw_phy_cond2 cond2 = {0}; + struct rtw_phy_cond cond = {}; + struct rtw_phy_cond2 cond2 = {}; cond.cut = hal->cut_version ? hal->cut_version : 15; cond.pkg = pkg ? pkg : 15; @@ -1098,7 +1098,8 @@ void rtw_phy_setup_phy_cond(struct rtw_dev *rtwdev, u32 pkg) *((u32 *)&hal->phy_cond), *((u32 *)&hal->phy_cond2)); } -static bool check_positive(struct rtw_dev *rtwdev, struct rtw_phy_cond cond, struct rtw_phy_cond2 cond2) +static bool check_positive(struct rtw_dev *rtwdev, struct rtw_phy_cond cond, + struct rtw_phy_cond2 cond2) { struct rtw_hal *hal = &rtwdev->hal; struct rtw_phy_cond drv_cond = hal->phy_cond; @@ -1143,8 +1144,8 @@ void rtw_parse_tbl_phy_cond(struct rtw_dev *rtwdev, const struct rtw_table *tbl) { const union phy_table_tile *p = tbl->data; const union phy_table_tile *end = p + tbl->size / 2; - struct rtw_phy_cond pos_cond = {0}; - struct rtw_phy_cond2 pos_cond2 = {0}; + struct rtw_phy_cond pos_cond = {}; + struct rtw_phy_cond2 pos_cond2 = {}; bool is_matched = true, is_skipped = false; BUILD_BUG_ON(sizeof(union phy_table_tile) != sizeof(struct phy_cfg_pair)); diff --git a/reg.h b/reg.h index 4d9b8668..e4d506cf 100644 --- a/reg.h +++ b/reg.h @@ -9,6 +9,7 @@ #define BIT_FEN_EN_25_1 BIT(13) #define BIT_FEN_ELDR BIT(12) #define BIT_FEN_CPUEN BIT(2) +#define BIT_FEN_USBA BIT(2) #define BIT_FEN_BB_GLB_RST BIT(1) #define BIT_FEN_BB_RSTB BIT(0) #define BIT_R_DIS_PRST BIT(6) @@ -16,6 +17,10 @@ #define REG_SYS_PW_CTRL 0x0004 #define BIT_PFM_WOWL BIT(3) #define BIT_APFM_OFFMAC BIT(9) +#define REG_APS_FSMCO 0x0004 +#define APS_FSMCO_MAC_ENABLE BIT(8) +#define APS_FSMCO_MAC_OFF BIT(9) +#define APS_FSMCO_HW_POWERDOWN BIT(15) #define REG_SYS_CLK_CTRL 0x0008 #define BIT_CPU_CLK_EN BIT(14) @@ -58,6 +63,8 @@ #define BIT_SHIFT_LDO25_VOLTAGE 4 #define BIT_LDO25_EN BIT(7) +#define REG_ACLK_MON 0x3e + #define REG_GPIO_MUXCFG 0x0040 #define BIT_FSPI_EN BIT(19) #define BIT_EN_SIC BIT(12) @@ -90,6 +97,8 @@ #define BIT_USB_SUS_DIS BIT(8) #define BIT_SDIO_PAD_E5 BIT(18) +#define REG_RF_B_CTRL 0x76 + #define REG_AFE_CTRL_4 0x0078 #define BIT_CK320M_AFE_EN BIT(4) #define BIT_EN_SYN BIT(15) @@ -134,6 +143,11 @@ #define REG_PMC_DBG_CTRL1 0xa8 #define BITS_PMC_BT_IQK_STS GENMASK(22, 21) +#define REG_HIMR0 0xb0 +#define REG_HISR0 0xb4 +#define REG_HIMR1 0xb8 +#define REG_HISR1 0xbc + #define REG_PAD_CTRL2 0x00C4 #define BIT_RSM_EN_V1 BIT(16) #define BIT_NO_PDN_CHIPOFF_V1 BIT(17) @@ -185,6 +199,15 @@ #define MAC_TRX_ENABLE (BIT_HCI_TXDMA_EN | BIT_HCI_RXDMA_EN | BIT_TXDMA_EN | \ BIT_RXDMA_EN | BIT_PROTOCOL_EN | BIT_SCHEDULE_EN | \ BIT_MACTXEN | BIT_MACRXEN) +#define REG_PBP 0x104 +#define PBP_RX_MASK 0x0f +#define PBP_TX_MASK 0xf0 +#define PBP_64 0x0 +#define PBP_128 0x1 +#define PBP_256 0x2 +#define PBP_512 0x3 +#define PBP_1024 0x4 + #define BIT_SHIFT_TXDMA_VOQ_MAP 4 #define BIT_MASK_TXDMA_VOQ_MAP 0x3 #define BIT_TXDMA_VOQ_MAP(x) \ @@ -256,6 +279,8 @@ #define REG_HMEBOX1 0x01D4 #define REG_HMEBOX2 0x01D8 #define REG_HMEBOX3 0x01DC +#define REG_LLT_INIT 0x01E0 +#define BIT_LLT_WRITE_ACCESS BIT(30) #define REG_HMEBOX0_EX 0x01F0 #define REG_HMEBOX1_EX 0x01F4 #define REG_HMEBOX2_EX 0x01F8 @@ -298,6 +323,7 @@ #define REG_AUTO_LLT 0x0224 #define BIT_AUTO_INIT_LLT BIT(16) +#define REG_DWBCN1_CTRL 0x0228 #define REG_RQPN_CTRL_1 0x0228 #define REG_RQPN_CTRL_2 0x022C #define BIT_LD_RQPN BIT(31) @@ -329,6 +355,7 @@ #define BIT_DMA_BURST_SIZE_1024 0 #define REG_RXPKTNUM 0x02B0 +#define REG_EARLY_MODE_CONTROL 0x02BC #define REG_INT_MIG 0x0304 #define REG_HCI_MIX_CFG 0x03FC @@ -336,6 +363,7 @@ #define REG_BCNQ_INFO 0x0418 #define BIT_MGQ_CPU_EMPTY BIT(24) +#define REG_TXPKT_EMPTY 0x041A #define REG_FWHW_TXQ_CTRL 0x0420 #define BIT_EN_BCNQ_DL BIT(22) #define BIT_EN_WR_FREE_TAIL BIT(20) @@ -362,10 +390,12 @@ #define REG_AMPDU_MAX_TIME_V1 0x0455 #define REG_BCNQ1_BDNY_V1 0x0456 #define REG_AMPDU_MAX_TIME 0x0456 +#define REG_AMPDU_MAX_LENGTH 0x0458 #define REG_WMAC_LBK_BF_HD 0x045D #define REG_TX_HANG_CTRL 0x045E #define BIT_EN_GNT_BT_AWAKE BIT(3) #define BIT_EN_EOF_V1 BIT(2) +#define REG_FAST_EDCA_CTRL 0x0460 #define REG_DATA_SC 0x0483 #define REG_ARFR2_V1 0x048C #define REG_ARFRH2_V1 0x0490 @@ -390,6 +420,8 @@ #define REG_PRECNT_CTRL 0x04E5 #define BIT_BTCCA_CTRL (BIT(0) | BIT(1)) #define BIT_EN_PRECNT BIT(11) +#define REG_TX_RPT_CTRL 0x04EC +#define REG_TX_RPT_TIME 0x04F0 #define REG_DUMMY_PAGE4_V1 0x04FC #define REG_EDCA_VO_PARAM 0x0500 @@ -400,6 +432,7 @@ #define BIT_MASK_CWMAX GENMASK(15, 12) #define BIT_MASK_CWMIN GENMASK(11, 8) #define BIT_MASK_AIFS GENMASK(7, 0) +#define REG_BCNTCFG 0x0510 #define REG_PIFS 0x0512 #define REG_SIFS 0x0514 #define BIT_SHIFT_SIFS_OFDM_CTX 8 @@ -526,6 +559,8 @@ #define REG_BT_COEX_V2 0x0762 #define BIT_GNT_BT_POLARITY BIT(12) #define BIT_LTE_COEX_EN BIT(7) +#define REG_GNT_BT 0x0765 +#define BIT_PTA_SW_CTL GENMASK(4, 3) #define REG_BT_COEX_ENH_INTR_CTRL 0x76E #define BIT_R_GRANTALL_WLMASK BIT(3) #define BIT_STATIS_BT_EN BIT(2) @@ -543,14 +578,43 @@ #define REG_FPGA0_RFMOD 0x0800 #define BIT_CCKEN BIT(24) #define BIT_OFDMEN BIT(25) +#define REG_CCK_RPT_FORMAT 0x0804 +#define BIT_CCK_RPT_FORMAT BIT(16) +#define REG_RXPSEL 0x0808 +#define BIT_RX_PSEL_RST (BIT(28) | BIT(29)) +#define REG_TXPSEL 0x080C #define REG_RX_GAIN_EN 0x081c +#define REG_CCASEL 0x082C +#define REG_PDMFTH 0x0830 +#define REG_BWINDICATION 0x0834 +#define REG_CCA2ND 0x0838 +#define REG_L1PKTH 0x0848 +#define REG_CLKTRK 0x0860 +#define REG_ADCCLK 0x08AC +#define REG_HSSI_READ 0x08B0 +#define REG_FPGA0_XCD_RF_PARA 0x08B4 +#define REG_RX_MCS_LIMIT 0x08BC +#define REG_ADC160 0x08C4 +#define REG_ANTSEL_SW 0x0900 +#define REG_DAC_RSTB 0x090c +#define REG_SINGLE_TONE_CONT_TX 0x0914 #define REG_RFE_CTRL_E 0x0974 #define REG_2ND_CCA_CTRL 0x0976 +#define REG_IQK_COM00 0x0978 +#define REG_IQK_COM32 0x097c +#define REG_IQK_COM64 0x0980 +#define REG_IQK_COM96 0x0984 + +#define REG_FAS 0x09a4 +#define REG_RXSB 0x0a00 +#define REG_CCK_RX 0x0a04 +#define REG_CCK_PD_TH 0x0a0a #define REG_CCK0_FAREPORT 0xa2c #define BIT_CCK0_2RX BIT(18) #define BIT_CCK0_MRC BIT(22) +#define REG_FA_CCK 0x0a5c #define REG_DIS_DPD 0x0a70 #define DIS_DPD_MASK GENMASK(9, 0) @@ -566,13 +630,109 @@ #define DIS_DPD_RATEVHT2SS_MCS1 BIT(9) #define DIS_DPD_RATEALL GENMASK(9, 0) +#define REG_CNTRST 0x0b58 + +#define REG_3WIRE_SWA 0x0c00 +#define REG_RX_IQC_AB_A 0x0c10 +#define REG_TXSCALE_A 0x0c1c +#define BB_SWING_MASK GENMASK(31, 21) +#define REG_TX_AGC_A_CCK_11_CCK_1 0xc20 +#define REG_TX_AGC_A_OFDM18_OFDM6 0xc24 +#define REG_TX_AGC_A_OFDM54_OFDM24 0xc28 +#define REG_TX_AGC_A_MCS3_MCS0 0xc2c +#define REG_TX_AGC_A_MCS7_MCS4 0xc30 +#define REG_TX_AGC_A_MCS11_MCS8 0xc34 +#define REG_TX_AGC_A_MCS15_MCS12 0xc38 +#define REG_TX_AGC_A_NSS1_INDEX3_NSS1_INDEX0 0xc3c +#define REG_TX_AGC_A_NSS1_INDEX7_NSS1_INDEX4 0xc40 +#define REG_TX_AGC_A_NSS2_INDEX1_NSS1_INDEX8 0xc44 +#define REG_TX_AGC_A_NSS2_INDEX5_NSS2_INDEX2 0xc48 +#define REG_TX_AGC_A_NSS2_INDEX9_NSS2_INDEX6 0xc4c +#define REG_RXIGI_A 0x0c50 +#define REG_TX_PWR_TRAINING_A 0x0c54 +#define REG_CK_MONHA 0x0c5c +#define REG_AFE_PWR1_A 0x0c60 +#define REG_AFE_PWR2_A 0x0c64 +#define REG_RX_WAIT_CCA_TX_CCK_RFON_A 0x0c68 +#define REG_OFDM0_XA_TX_IQ_IMBALANCE 0x0c80 +#define REG_OFDM0_A_TX_AFE 0x0c84 +#define REG_OFDM0_XB_TX_IQ_IMBALANCE 0x0c88 +#define REG_TSSI_TRK_SW 0x0c8c +#define REG_LSSI_WRITE_A 0x0c90 +#define REG_PREDISTA 0x0c90 +#define REG_TXAGCIDX 0x0c94 + +#define REG_RFE_PINMUX_A 0x0cb0 +#define REG_RFE_INV_A 0x0cb4 #define REG_RFE_CTRL8 0x0cb4 #define BIT_MASK_RFE_SEL89 GENMASK(7, 0) +#define PTA_CTRL_PIN 0x66 +#define DPDT_CTRL_PIN 0x77 +#define RFE_INV_MASK 0x3ff00000 +#define REG_RFECTL_A 0x0cb8 #define REG_RFE_INV8 0x0cbd #define BIT_MASK_RFE_INV89 GENMASK(1, 0) #define REG_RFE_INV16 0x0cbe #define BIT_RFE_BUF_EN BIT(3) +#define REG_IQK_DPD_CFG 0x0cc4 +#define REG_CFG_PMPD 0x0cc8 +#define REG_IQC_Y 0x0ccc +#define REG_IQC_X 0x0cd4 +#define REG_INTPO_SETA 0x0ce8 + +#define REG_IQKA_END 0x0d00 +#define REG_PI_READ_A 0x0d04 +#define REG_SI_READ_A 0x0d08 +#define REG_IQKB_END 0x0d40 +#define REG_PI_READ_B 0x0d44 +#define REG_SI_READ_B 0x0d48 + +#define REG_3WIRE_SWB 0x0e00 +#define REG_RX_IQC_AB_B 0x0e10 +#define REG_TXSCALE_B 0x0e1c +#define REG_TX_AGC_B_CCK_11_CCK_1 0xe20 +#define REG_TX_AGC_B_OFDM18_OFDM6 0xe24 +#define REG_TX_AGC_B_OFDM54_OFDM24 0xe28 +#define REG_TX_AGC_B_MCS3_MCS0 0xe2c +#define REG_TX_AGC_B_MCS7_MCS4 0xe30 +#define REG_TX_AGC_B_MCS11_MCS8 0xe34 +#define REG_TX_AGC_B_MCS15_MCS12 0xe38 +#define REG_TX_AGC_B_NSS1_INDEX3_NSS1_INDEX0 0xe3c +#define REG_TX_AGC_B_NSS1_INDEX7_NSS1_INDEX4 0xe40 +#define REG_TX_AGC_B_NSS2_INDEX1_NSS1_INDEX8 0xe44 +#define REG_TX_AGC_B_NSS2_INDEX5_NSS2_INDEX2 0xe48 +#define REG_TX_AGC_B_NSS2_INDEX9_NSS2_INDEX6 0xe4c +#define REG_RXIGI_B 0x0e50 +#define REG_TX_PWR_TRAINING_B 0x0e54 +#define REG_CK_MONHB 0x0e5c +#define REG_AFE_PWR1_B 0x0e60 +#define REG_AFE_PWR2_B 0x0e64 +#define REG_RX_WAIT_CCA_TX_CCK_RFON_B 0x0e68 +#define REG_TXTONEB 0x0e80 +#define REG_RXTONEB 0x0e84 +#define REG_TXPITMB 0x0e88 +#define REG_RXPITMB 0x0e8c +#define REG_LSSI_WRITE_B 0x0e90 +#define REG_PREDISTB 0x0e90 +#define REG_INIDLYB 0x0e94 +#define REG_RFE_PINMUX_B 0x0eb0 +#define REG_RFE_INV_B 0x0eb4 +#define REG_RFECTL_B 0x0eb8 +#define REG_BPBDB 0x0ec4 +#define REG_PHYTXONB 0x0ec8 +#define REG_IQKYB 0x0ecc +#define REG_IQKXB 0x0ed4 +#define REG_INTPO_SETB 0x0ee8 + +#define REG_CRC_CCK 0x0f04 +#define REG_CCA_OFDM 0x0f08 +#define REG_CRC_VHT 0x0f0c +#define REG_CRC_HT 0x0f10 +#define REG_CRC_OFDM 0x0f14 +#define REG_FA_OFDM 0x0f48 +#define REG_CCA_CCK 0x0fcc + #define REG_ANAPARSW_MAC_0 0x1010 #define BIT_CF_L_V2 GENMASK(29, 28) @@ -709,6 +869,10 @@ #define REG_IGN_GNTBT4 0x4160 +#define REG_USB_MOD 0xf008 +#define REG_USB3_RXITV 0xf050 +#define REG_USB_HRPWM 0xfe58 + #define RF_MODE 0x00 #define RF_MODOPT 0x01 #define RF_WLINT 0x01 @@ -716,7 +880,13 @@ #define RF_DTXLOK 0x08 #define RF_CFGCH 0x18 #define BIT_BAND GENMASK(18, 16) +#define RF18_BAND_MASK (BIT(16) | BIT(9) | BIT(8)) +#define RF18_CHANNEL_MASK (MASKBYTE0) +#define RF18_RFSI_MASK (BIT(18) | BIT(17)) #define RF_RCK 0x1d +#define RF_MODE_TABLE_ADDR 0x30 +#define RF_MODE_TABLE_DATA0 0x31 +#define RF_MODE_TABLE_DATA1 0x32 #define RF_LUTWA 0x33 #define RF_LUTWD1 0x3e #define RF_LUTWD0 0x3f @@ -725,10 +895,14 @@ #define RF_T_METER 0x42 #define RF_BSPAD 0x54 #define RF_GAINTX 0x56 +#define RF_TXMOD 0x58 #define RF_TXATANK 0x64 +#define RF_TXA_PREPAD 0x65 #define RF_TRXIQ 0x66 #define RF_RXIQGEN 0x8d +#define RF_RXBB2 0x8f #define RF_SYN_PFD 0xb0 +#define RF_LCK 0xb4 #define RF_XTALX2 0xb8 #define RF_SYN_CTRL 0xbb #define RF_MALSEL 0xbe diff --git a/rtw8812a.c b/rtw8812a.c new file mode 100644 index 00000000..a6ab2dee --- /dev/null +++ b/rtw8812a.c @@ -0,0 +1,1102 @@ +// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause +/* Copyright(c) 2024 Realtek Corporation + */ + +#include "main.h" +#include "coex.h" +#include "phy.h" +#include "reg.h" +#include "rtw88xxa.h" +#include "rtw8812a.h" +#include "rtw8812a_table.h" +#include "tx.h" + +static void rtw8812a_power_off(struct rtw_dev *rtwdev) +{ + rtw88xxa_power_off(rtwdev, enter_lps_flow_8812a); +} + +static s8 rtw8812a_cck_rx_pwr(u8 lna_idx, u8 vga_idx) +{ + s8 rx_pwr_all = 0; + + switch (lna_idx) { + case 7: + if (vga_idx <= 27) + rx_pwr_all = -94 + 2 * (27 - vga_idx); + else + rx_pwr_all = -94; + break; + case 6: + rx_pwr_all = -42 + 2 * (2 - vga_idx); + break; + case 5: + rx_pwr_all = -36 + 2 * (7 - vga_idx); + break; + case 4: + rx_pwr_all = -30 + 2 * (7 - vga_idx); + break; + case 3: + rx_pwr_all = -18 + 2 * (7 - vga_idx); + break; + case 2: + rx_pwr_all = 2 * (5 - vga_idx); + break; + case 1: + rx_pwr_all = 14 - 2 * vga_idx; + break; + case 0: + rx_pwr_all = 20 - 2 * vga_idx; + break; + default: + break; + } + + return rx_pwr_all; +} + +static void rtw8812a_query_phy_status(struct rtw_dev *rtwdev, u8 *phy_status, + struct rtw_rx_pkt_stat *pkt_stat) +{ + rtw88xxa_query_phy_status(rtwdev, phy_status, pkt_stat, + rtw8812a_cck_rx_pwr); + + if (pkt_stat->rate >= DESC_RATE6M) + return; + + if (rtwdev->hal.cck_high_power) + return; + + if (pkt_stat->rssi >= 80) + pkt_stat->rssi = ((pkt_stat->rssi - 80) << 1) + + ((pkt_stat->rssi - 80) >> 1) + 80; + else if (pkt_stat->rssi <= 78 && pkt_stat->rssi >= 20) + pkt_stat->rssi += 3; +} + +static void rtw8812a_cfg_ldo25(struct rtw_dev *rtwdev, bool enable) +{ +} + +static void rtw8812a_do_lck(struct rtw_dev *rtwdev) +{ + u32 cont_tx, lc_cal, i; + + cont_tx = rtw_read32_mask(rtwdev, REG_SINGLE_TONE_CONT_TX, 0x70000); + + lc_cal = rtw_read_rf(rtwdev, RF_PATH_A, RF_CFGCH, RFREG_MASK); + + if (!cont_tx) + rtw_write8(rtwdev, REG_TXPAUSE, 0xff); + + rtw_write_rf(rtwdev, RF_PATH_A, RF_LCK, BIT(14), 1); + + rtw_write_rf(rtwdev, RF_PATH_A, RF_CFGCH, 0x08000, 1); + + mdelay(150); + + for (i = 0; i < 5; i++) { + if (rtw_read_rf(rtwdev, RF_PATH_A, RF_CFGCH, 0x08000) != 1) + break; + + mdelay(10); + } + + if (i == 5) + rtw_dbg(rtwdev, RTW_DBG_RFK, "LCK timed out\n"); + + rtw_write_rf(rtwdev, RF_PATH_A, RF_CFGCH, RFREG_MASK, lc_cal); + + rtw_write_rf(rtwdev, RF_PATH_A, RF_LCK, BIT(14), 0); + + if (!cont_tx) + rtw_write8(rtwdev, REG_TXPAUSE, 0); + + rtw_write_rf(rtwdev, RF_PATH_A, RF_CFGCH, RFREG_MASK, lc_cal); +} + +static void rtw8812a_iqk_backup_rf(struct rtw_dev *rtwdev, u32 *rfa_backup, + u32 *rfb_backup, const u32 *backup_rf_reg, + u32 rf_num) +{ + u32 i; + + /* [31] = 0 --> Page C */ + rtw_write32_mask(rtwdev, REG_CCASEL, BIT(31), 0x0); + + /* Save RF Parameters */ + for (i = 0; i < rf_num; i++) { + rfa_backup[i] = rtw_read_rf(rtwdev, RF_PATH_A, + backup_rf_reg[i], MASKDWORD); + rfb_backup[i] = rtw_read_rf(rtwdev, RF_PATH_B, + backup_rf_reg[i], MASKDWORD); + } +} + +static void rtw8812a_iqk_restore_rf(struct rtw_dev *rtwdev, + enum rtw_rf_path path, + const u32 *backup_rf_reg, + u32 *RF_backup, u32 rf_reg_num) +{ + u32 i; + + /* [31] = 0 --> Page C */ + rtw_write32_mask(rtwdev, REG_CCASEL, BIT(31), 0x0); + + for (i = 0; i < rf_reg_num; i++) + rtw_write_rf(rtwdev, path, backup_rf_reg[i], + RFREG_MASK, RF_backup[i]); + + rtw_write_rf(rtwdev, path, RF_LUTWE, RFREG_MASK, 0); +} + +static void rtw8812a_iqk_restore_afe(struct rtw_dev *rtwdev, u32 *afe_backup, + const u32 *backup_afe_reg, u32 afe_num) +{ + u32 i; + + /* [31] = 0 --> Page C */ + rtw_write32_mask(rtwdev, REG_CCASEL, BIT(31), 0x0); + + /* Reload AFE Parameters */ + for (i = 0; i < afe_num; i++) + rtw_write32(rtwdev, backup_afe_reg[i], afe_backup[i]); + + /* [31] = 1 --> Page C1 */ + rtw_write32_mask(rtwdev, REG_CCASEL, BIT(31), 0x1); + + rtw_write32(rtwdev, REG_OFDM0_XA_TX_IQ_IMBALANCE, 0x0); + rtw_write32(rtwdev, REG_OFDM0_A_TX_AFE, 0x0); + rtw_write32(rtwdev, REG_OFDM0_XB_TX_IQ_IMBALANCE, 0x0); + rtw_write32(rtwdev, REG_TSSI_TRK_SW, 0x3c000000); + rtw_write32_mask(rtwdev, REG_LSSI_WRITE_A, BIT(7), 1); + rtw_write32_mask(rtwdev, REG_IQK_DPD_CFG, BIT(18), 1); + rtw_write32_mask(rtwdev, REG_IQK_DPD_CFG, BIT(29), 1); + rtw_write32_mask(rtwdev, REG_CFG_PMPD, BIT(29), 1); + + rtw_write32(rtwdev, REG_TXTONEB, 0x0); + rtw_write32(rtwdev, REG_RXTONEB, 0x0); + rtw_write32(rtwdev, REG_TXPITMB, 0x0); + rtw_write32(rtwdev, REG_RXPITMB, 0x3c000000); + rtw_write32_mask(rtwdev, REG_LSSI_WRITE_B, BIT(7), 1); + rtw_write32_mask(rtwdev, REG_BPBDB, BIT(18), 1); + rtw_write32_mask(rtwdev, REG_BPBDB, BIT(29), 1); + rtw_write32_mask(rtwdev, REG_PHYTXONB, BIT(29), 1); +} + +static void rtw8812a_iqk_rx_fill(struct rtw_dev *rtwdev, enum rtw_rf_path path, + unsigned int rx_x, unsigned int rx_y) +{ + switch (path) { + case RF_PATH_A: + /* [31] = 0 --> Page C */ + rtw_write32_mask(rtwdev, REG_CCASEL, BIT(31), 0x0); + if (rx_x >> 1 >= 0x112 || + (rx_y >> 1 >= 0x12 && rx_y >> 1 <= 0x3ee)) { + rtw_write32_mask(rtwdev, REG_RX_IQC_AB_A, + 0x000003ff, 0x100); + rtw_write32_mask(rtwdev, REG_RX_IQC_AB_A, + 0x03ff0000, 0); + } else { + rtw_write32_mask(rtwdev, REG_RX_IQC_AB_A, + 0x000003ff, rx_x >> 1); + rtw_write32_mask(rtwdev, REG_RX_IQC_AB_A, + 0x03ff0000, rx_y >> 1); + } + rtw_dbg(rtwdev, RTW_DBG_RFK, + "rx_x = %x;;rx_y = %x ====>fill to IQC\n", + rx_x >> 1 & 0x000003ff, rx_y >> 1 & 0x000003ff); + rtw_dbg(rtwdev, RTW_DBG_RFK, "0xc10 = %x ====>fill to IQC\n", + rtw_read32(rtwdev, REG_RX_IQC_AB_A)); + break; + case RF_PATH_B: + /* [31] = 0 --> Page C */ + rtw_write32_mask(rtwdev, REG_CCASEL, BIT(31), 0x0); + if (rx_x >> 1 >= 0x112 || + (rx_y >> 1 >= 0x12 && rx_y >> 1 <= 0x3ee)) { + rtw_write32_mask(rtwdev, REG_RX_IQC_AB_B, + 0x000003ff, 0x100); + rtw_write32_mask(rtwdev, REG_RX_IQC_AB_B, + 0x03ff0000, 0); + } else { + rtw_write32_mask(rtwdev, REG_RX_IQC_AB_B, + 0x000003ff, rx_x >> 1); + rtw_write32_mask(rtwdev, REG_RX_IQC_AB_B, + 0x03ff0000, rx_y >> 1); + } + rtw_dbg(rtwdev, RTW_DBG_RFK, + "rx_x = %x;;rx_y = %x ====>fill to IQC\n", + rx_x >> 1 & 0x000003ff, rx_y >> 1 & 0x000003ff); + rtw_dbg(rtwdev, RTW_DBG_RFK, "0xe10 = %x====>fill to IQC\n", + rtw_read32(rtwdev, REG_RX_IQC_AB_B)); + break; + default: + break; + } +} + +static void rtw8812a_iqk_tx_fill(struct rtw_dev *rtwdev, enum rtw_rf_path path, + unsigned int tx_x, unsigned int tx_y) +{ + switch (path) { + case RF_PATH_A: + /* [31] = 1 --> Page C1 */ + rtw_write32_mask(rtwdev, REG_CCASEL, BIT(31), 0x1); + rtw_write32_mask(rtwdev, REG_PREDISTA, BIT(7), 0x1); + rtw_write32_mask(rtwdev, REG_IQK_DPD_CFG, BIT(18), 0x1); + rtw_write32_mask(rtwdev, REG_IQK_DPD_CFG, BIT(29), 0x1); + rtw_write32_mask(rtwdev, REG_CFG_PMPD, BIT(29), 0x1); + rtw_write32_mask(rtwdev, REG_IQC_Y, 0x000007ff, tx_y); + rtw_write32_mask(rtwdev, REG_IQC_X, 0x000007ff, tx_x); + rtw_dbg(rtwdev, RTW_DBG_RFK, + "tx_x = %x;;tx_y = %x =====> fill to IQC\n", + tx_x & 0x000007ff, tx_y & 0x000007ff); + rtw_dbg(rtwdev, RTW_DBG_RFK, + "0xcd4 = %x;;0xccc = %x ====>fill to IQC\n", + rtw_read32_mask(rtwdev, REG_IQC_X, 0x000007ff), + rtw_read32_mask(rtwdev, REG_IQC_Y, 0x000007ff)); + break; + case RF_PATH_B: + /* [31] = 1 --> Page C1 */ + rtw_write32_mask(rtwdev, REG_CCASEL, BIT(31), 0x1); + rtw_write32_mask(rtwdev, REG_PREDISTB, BIT(7), 0x1); + rtw_write32_mask(rtwdev, REG_BPBDB, BIT(18), 0x1); + rtw_write32_mask(rtwdev, REG_BPBDB, BIT(29), 0x1); + rtw_write32_mask(rtwdev, REG_PHYTXONB, BIT(29), 0x1); + rtw_write32_mask(rtwdev, REG_IQKYB, 0x000007ff, tx_y); + rtw_write32_mask(rtwdev, REG_IQKXB, 0x000007ff, tx_x); + rtw_dbg(rtwdev, RTW_DBG_RFK, + "tx_x = %x;;tx_y = %x =====> fill to IQC\n", + tx_x & 0x000007ff, tx_y & 0x000007ff); + rtw_dbg(rtwdev, RTW_DBG_RFK, + "0xed4 = %x;;0xecc = %x ====>fill to IQC\n", + rtw_read32_mask(rtwdev, REG_IQKXB, 0x000007ff), + rtw_read32_mask(rtwdev, REG_IQKYB, 0x000007ff)); + break; + default: + break; + } +} + +static void rtw8812a_iqk(struct rtw_dev *rtwdev) +{ + int tx_x0_temp[10], tx_y0_temp[10], tx_x1_temp[10], tx_y1_temp[10]; + int rx_x0_temp[10], rx_y0_temp[10], rx_x1_temp[10], rx_y1_temp[10]; + bool iqk0_ready = false, tx0_finish = false, rx0_finish = false; + bool iqk1_ready = false, tx1_finish = false, rx1_finish = false; + u8 tx0_avg = 0, tx1_avg = 0, rx0_avg = 0, rx1_avg = 0; + struct rtw_efuse *efuse = &rtwdev->efuse; + bool tx0_fail = true, rx0_fail = true; + bool tx1_fail = true, rx1_fail = true; + int tx_x0, tx_y0, tx_x1, tx_y1; + int rx_x0, rx_y0, rx_x1, rx_y1; + u8 cal0_retry, cal1_retry; + u8 delay_count; + + /* [31] = 0 --> Page C */ + rtw_write32_mask(rtwdev, REG_CCASEL, BIT(31), 0x0); + + /* ========path-A AFE all on======== */ + /* Port 0 DAC/ADC on */ + rtw_write32(rtwdev, REG_AFE_PWR1_A, 0x77777777); + rtw_write32(rtwdev, REG_AFE_PWR2_A, 0x77777777); + + /* Port 1 DAC/ADC on */ + rtw_write32(rtwdev, REG_AFE_PWR1_B, 0x77777777); + rtw_write32(rtwdev, REG_AFE_PWR2_B, 0x77777777); + + rtw_write32(rtwdev, REG_RX_WAIT_CCA_TX_CCK_RFON_A, 0x19791979); + rtw_write32(rtwdev, REG_RX_WAIT_CCA_TX_CCK_RFON_B, 0x19791979); + + /* hardware 3-wire off */ + rtw_write32_mask(rtwdev, REG_3WIRE_SWA, 0xf, 0x4); + rtw_write32_mask(rtwdev, REG_3WIRE_SWB, 0xf, 0x4); + + /* DAC/ADC sampling rate (160 MHz) */ + rtw_write32_mask(rtwdev, REG_CK_MONHA, GENMASK(26, 24), 0x7); + rtw_write32_mask(rtwdev, REG_CK_MONHB, GENMASK(26, 24), 0x7); + + /* [31] = 0 --> Page C */ + rtw_write32_mask(rtwdev, REG_CCASEL, BIT(31), 0x0); + /* ====== path A TX IQK RF setting ====== */ + rtw_write_rf(rtwdev, RF_PATH_A, RF_LUTWE, RFREG_MASK, 0x80002); + rtw_write_rf(rtwdev, RF_PATH_A, RF_MODE_TABLE_ADDR, RFREG_MASK, 0x20000); + rtw_write_rf(rtwdev, RF_PATH_A, RF_MODE_TABLE_DATA0, RFREG_MASK, 0x3fffd); + rtw_write_rf(rtwdev, RF_PATH_A, RF_MODE_TABLE_DATA1, RFREG_MASK, 0xfe83f); + rtw_write_rf(rtwdev, RF_PATH_A, RF_TXA_PREPAD, RFREG_MASK, 0x931d5); + rtw_write_rf(rtwdev, RF_PATH_A, RF_RXBB2, RFREG_MASK, 0x8a001); + + /* ====== path B TX IQK RF setting ====== */ + rtw_write_rf(rtwdev, RF_PATH_B, RF_LUTWE, RFREG_MASK, 0x80002); + rtw_write_rf(rtwdev, RF_PATH_B, RF_MODE_TABLE_ADDR, RFREG_MASK, 0x20000); + rtw_write_rf(rtwdev, RF_PATH_B, RF_MODE_TABLE_DATA0, RFREG_MASK, 0x3fffd); + rtw_write_rf(rtwdev, RF_PATH_B, RF_MODE_TABLE_DATA1, RFREG_MASK, 0xfe83f); + rtw_write_rf(rtwdev, RF_PATH_B, RF_TXA_PREPAD, RFREG_MASK, 0x931d5); + rtw_write_rf(rtwdev, RF_PATH_B, RF_RXBB2, RFREG_MASK, 0x8a001); + + rtw_write32(rtwdev, REG_DAC_RSTB, 0x00008000); + rtw_write32_mask(rtwdev, REG_TXAGCIDX, BIT(0), 0x1); + rtw_write32_mask(rtwdev, REG_INIDLYB, BIT(0), 0x1); + rtw_write32(rtwdev, REG_IQK_COM00, 0x29002000); /* TX (X,Y) */ + rtw_write32(rtwdev, REG_IQK_COM32, 0xa9002000); /* RX (X,Y) */ + rtw_write32(rtwdev, REG_IQK_COM96, 0x00462910); /* [0]:AGC_en, [15]:idac_K_Mask */ + /* [31] = 1 --> Page C1 */ + rtw_write32_mask(rtwdev, REG_CCASEL, BIT(31), 0x1); + + if (efuse->ext_pa_5g) { + if (efuse->rfe_option == 1) { + rtw_write32(rtwdev, REG_OFDM0_XB_TX_IQ_IMBALANCE, 0x821403e3); + rtw_write32(rtwdev, REG_TXPITMB, 0x821403e3); + } else { + rtw_write32(rtwdev, REG_OFDM0_XB_TX_IQ_IMBALANCE, 0x821403f7); + rtw_write32(rtwdev, REG_TXPITMB, 0x821403f7); + } + } else { + rtw_write32(rtwdev, REG_OFDM0_XB_TX_IQ_IMBALANCE, 0x821403f1); + rtw_write32(rtwdev, REG_TXPITMB, 0x821403f1); + } + + if (rtwdev->hal.current_band_type == RTW_BAND_5G) { + rtw_write32(rtwdev, REG_TSSI_TRK_SW, 0x68163e96); + rtw_write32(rtwdev, REG_RXPITMB, 0x68163e96); + } else { + rtw_write32(rtwdev, REG_TSSI_TRK_SW, 0x28163e96); + rtw_write32(rtwdev, REG_RXPITMB, 0x28163e96); + + if (efuse->rfe_option == 3) { + if (efuse->ext_pa_2g) + rtw_write32(rtwdev, REG_OFDM0_XB_TX_IQ_IMBALANCE, + 0x821403e3); + else + rtw_write32(rtwdev, REG_OFDM0_XB_TX_IQ_IMBALANCE, + 0x821403f7); + } + } + + /* TX_Tone_idx[9:0], TxK_Mask[29] TX_Tone = 16 */ + rtw_write32(rtwdev, REG_OFDM0_XA_TX_IQ_IMBALANCE, 0x18008c10); + /* RX_Tone_idx[9:0], RxK_Mask[29] */ + rtw_write32(rtwdev, REG_OFDM0_A_TX_AFE, 0x38008c10); + rtw_write32(rtwdev, REG_INTPO_SETA, 0x00000000); + /* TX_Tone_idx[9:0], TxK_Mask[29] TX_Tone = 16 */ + rtw_write32(rtwdev, REG_TXTONEB, 0x18008c10); + /* RX_Tone_idx[9:0], RxK_Mask[29] */ + rtw_write32(rtwdev, REG_RXTONEB, 0x38008c10); + rtw_write32(rtwdev, REG_INTPO_SETB, 0x00000000); + + cal0_retry = 0; + cal1_retry = 0; + while (1) { + /* one shot */ + rtw_write32(rtwdev, REG_RFECTL_A, 0x00100000); + rtw_write32(rtwdev, REG_RFECTL_B, 0x00100000); + rtw_write32(rtwdev, REG_IQK_COM64, 0xfa000000); + rtw_write32(rtwdev, REG_IQK_COM64, 0xf8000000); + + mdelay(10); + + rtw_write32(rtwdev, REG_RFECTL_A, 0x00000000); + rtw_write32(rtwdev, REG_RFECTL_B, 0x00000000); + + for (delay_count = 0; delay_count < 20; delay_count++) { + if (!tx0_finish) + iqk0_ready = rtw_read32_mask(rtwdev, + REG_IQKA_END, + BIT(10)); + if (!tx1_finish) + iqk1_ready = rtw_read32_mask(rtwdev, + REG_IQKB_END, + BIT(10)); + if (iqk0_ready && iqk1_ready) + break; + + mdelay(1); + } + + rtw_dbg(rtwdev, RTW_DBG_RFK, "TX delay_count = %d\n", + delay_count); + + if (delay_count < 20) { /* If 20ms No Result, then cal_retry++ */ + /* ============TXIQK Check============== */ + tx0_fail = rtw_read32_mask(rtwdev, REG_IQKA_END, BIT(12)); + tx1_fail = rtw_read32_mask(rtwdev, REG_IQKB_END, BIT(12)); + + if (!(tx0_fail || tx0_finish)) { + rtw_write32(rtwdev, REG_RFECTL_A, 0x02000000); + tx_x0_temp[tx0_avg] = rtw_read32_mask(rtwdev, + REG_IQKA_END, + 0x07ff0000); + rtw_write32(rtwdev, REG_RFECTL_A, 0x04000000); + tx_y0_temp[tx0_avg] = rtw_read32_mask(rtwdev, + REG_IQKA_END, + 0x07ff0000); + + rtw_dbg(rtwdev, RTW_DBG_RFK, + "tx_x0[%d] = %x ;; tx_y0[%d] = %x\n", + tx0_avg, tx_x0_temp[tx0_avg], + tx0_avg, tx_y0_temp[tx0_avg]); + + tx_x0_temp[tx0_avg] <<= 21; + tx_y0_temp[tx0_avg] <<= 21; + + tx0_avg++; + } else { + cal0_retry++; + if (cal0_retry == 10) + break; + } + + if (!(tx1_fail || tx1_finish)) { + rtw_write32(rtwdev, REG_RFECTL_B, 0x02000000); + tx_x1_temp[tx1_avg] = rtw_read32_mask(rtwdev, + REG_IQKB_END, + 0x07ff0000); + rtw_write32(rtwdev, REG_RFECTL_B, 0x04000000); + tx_y1_temp[tx1_avg] = rtw_read32_mask(rtwdev, + REG_IQKB_END, + 0x07ff0000); + + rtw_dbg(rtwdev, RTW_DBG_RFK, + "tx_x1[%d] = %x ;; tx_y1[%d] = %x\n", + tx1_avg, tx_x1_temp[tx1_avg], + tx1_avg, tx_y1_temp[tx1_avg]); + + tx_x1_temp[tx1_avg] <<= 21; + tx_y1_temp[tx1_avg] <<= 21; + + tx1_avg++; + } else { + cal1_retry++; + if (cal1_retry == 10) + break; + } + } else { + cal0_retry++; + cal1_retry++; + + rtw_dbg(rtwdev, RTW_DBG_RFK, + "delay 20ms TX IQK Not Ready!!!!!\n"); + + if (cal0_retry == 10) + break; + } + + if (tx0_avg >= 2) + tx0_finish = rtw88xxa_iqk_finish(tx0_avg, 4, + tx_x0_temp, tx_y0_temp, &tx_x0, &tx_y0, + false, false); + + if (tx1_avg >= 2) + tx1_finish = rtw88xxa_iqk_finish(tx1_avg, 4, + tx_x1_temp, tx_y1_temp, &tx_x1, &tx_y1, + false, false); + + rtw_dbg(rtwdev, RTW_DBG_RFK, + "tx0_average = %d, tx1_average = %d\n", + tx0_avg, tx1_avg); + rtw_dbg(rtwdev, RTW_DBG_RFK, + "tx0_finish = %d, tx1_finish = %d\n", + tx0_finish, tx1_finish); + + if (tx0_finish && tx1_finish) + break; + + if ((cal0_retry + tx0_avg) >= 10 || + (cal1_retry + tx1_avg) >= 10) + break; + } + + rtw_dbg(rtwdev, RTW_DBG_RFK, "TXA_cal_retry = %d\n", cal0_retry); + rtw_dbg(rtwdev, RTW_DBG_RFK, "TXB_cal_retry = %d\n", cal1_retry); + + /* [31] = 0 --> Page C */ + rtw_write32_mask(rtwdev, REG_CCASEL, BIT(31), 0x0); + /* Load LOK */ + rtw_write_rf(rtwdev, RF_PATH_A, RF_TXMOD, 0x7fe00, + rtw_read_rf(rtwdev, RF_PATH_A, RF_DTXLOK, 0xffc00)); + rtw_write_rf(rtwdev, RF_PATH_B, RF_TXMOD, 0x7fe00, + rtw_read_rf(rtwdev, RF_PATH_B, RF_DTXLOK, 0xffc00)); + /* [31] = 1 --> Page C1 */ + rtw_write32_mask(rtwdev, REG_CCASEL, BIT(31), 0x1); + + /* [31] = 0 --> Page C */ + rtw_write32_mask(rtwdev, REG_CCASEL, BIT(31), 0x0); + if (tx0_finish) { + /* ====== path A RX IQK RF setting====== */ + rtw_write_rf(rtwdev, RF_PATH_A, RF_LUTWE, RFREG_MASK, 0x80000); + rtw_write_rf(rtwdev, RF_PATH_A, RF_MODE_TABLE_ADDR, RFREG_MASK, + 0x30000); + rtw_write_rf(rtwdev, RF_PATH_A, RF_MODE_TABLE_DATA0, RFREG_MASK, + 0x3f7ff); + rtw_write_rf(rtwdev, RF_PATH_A, RF_MODE_TABLE_DATA1, RFREG_MASK, + 0xfe7bf); + rtw_write_rf(rtwdev, RF_PATH_A, RF_RXBB2, RFREG_MASK, 0x88001); + rtw_write_rf(rtwdev, RF_PATH_A, RF_TXA_PREPAD, RFREG_MASK, 0x931d1); + rtw_write_rf(rtwdev, RF_PATH_A, RF_LUTWE, RFREG_MASK, 0x00000); + } + if (tx1_finish) { + /* ====== path B RX IQK RF setting====== */ + rtw_write_rf(rtwdev, RF_PATH_B, RF_LUTWE, RFREG_MASK, 0x80000); + rtw_write_rf(rtwdev, RF_PATH_B, RF_MODE_TABLE_ADDR, RFREG_MASK, + 0x30000); + rtw_write_rf(rtwdev, RF_PATH_B, RF_MODE_TABLE_DATA0, RFREG_MASK, + 0x3f7ff); + rtw_write_rf(rtwdev, RF_PATH_B, RF_MODE_TABLE_DATA1, RFREG_MASK, + 0xfe7bf); + rtw_write_rf(rtwdev, RF_PATH_B, RF_RXBB2, RFREG_MASK, 0x88001); + rtw_write_rf(rtwdev, RF_PATH_B, RF_TXA_PREPAD, RFREG_MASK, 0x931d1); + rtw_write_rf(rtwdev, RF_PATH_B, RF_LUTWE, RFREG_MASK, 0x00000); + } + + rtw_write32_mask(rtwdev, REG_IQK_COM00, BIT(31), 0x1); + rtw_write32_mask(rtwdev, REG_IQK_COM00, BIT(31), 0x0); + rtw_write32(rtwdev, REG_DAC_RSTB, 0x00008000); + + if (rtwdev->hci.type == RTW_HCI_TYPE_PCIE) + rtw_write32(rtwdev, REG_IQK_COM96, 0x0046a911); + else + rtw_write32(rtwdev, REG_IQK_COM96, 0x0046a890); + + if (efuse->rfe_option == 1) { + rtw_write32(rtwdev, REG_RFE_PINMUX_A, 0x77777717); + rtw_write32(rtwdev, REG_RFE_INV_A, 0x00000077); + rtw_write32(rtwdev, REG_RFE_PINMUX_B, 0x77777717); + rtw_write32(rtwdev, REG_RFE_INV_B, 0x00000077); + } else { + rtw_write32(rtwdev, REG_RFE_PINMUX_A, 0x77777717); + rtw_write32(rtwdev, REG_RFE_INV_A, 0x02000077); + rtw_write32(rtwdev, REG_RFE_PINMUX_B, 0x77777717); + rtw_write32(rtwdev, REG_RFE_INV_B, 0x02000077); + } + + /* [31] = 1 --> Page C1 */ + rtw_write32_mask(rtwdev, REG_CCASEL, BIT(31), 0x1); + + if (tx0_finish) { + /* TX_Tone_idx[9:0], TxK_Mask[29] TX_Tone = 16 */ + rtw_write32(rtwdev, REG_OFDM0_XA_TX_IQ_IMBALANCE, 0x38008c10); + /* RX_Tone_idx[9:0], RxK_Mask[29] */ + rtw_write32(rtwdev, REG_OFDM0_A_TX_AFE, 0x18008c10); + rtw_write32(rtwdev, REG_OFDM0_XB_TX_IQ_IMBALANCE, 0x82140119); + } + if (tx1_finish) { + /* TX_Tone_idx[9:0], TxK_Mask[29] TX_Tone = 16 */ + rtw_write32(rtwdev, REG_TXTONEB, 0x38008c10); + /* RX_Tone_idx[9:0], RxK_Mask[29] */ + rtw_write32(rtwdev, REG_RXTONEB, 0x18008c10); + rtw_write32(rtwdev, REG_TXPITMB, 0x82140119); + } + + cal0_retry = 0; + cal1_retry = 0; + while (1) { + /* one shot */ + /* [31] = 0 --> Page C */ + rtw_write32_mask(rtwdev, REG_CCASEL, BIT(31), 0x0); + + if (tx0_finish) { + rtw_write32_mask(rtwdev, REG_IQK_COM00, 0x03FF8000, + tx_x0 & 0x000007ff); + rtw_write32_mask(rtwdev, REG_IQK_COM00, 0x000007FF, + tx_y0 & 0x000007ff); + /* [31] = 1 --> Page C1 */ + rtw_write32_mask(rtwdev, REG_CCASEL, BIT(31), 0x1); + if (efuse->rfe_option == 1) + rtw_write32(rtwdev, REG_TSSI_TRK_SW, 0x28161500); + else + rtw_write32(rtwdev, REG_TSSI_TRK_SW, 0x28160cc0); + rtw_write32(rtwdev, REG_RFECTL_A, 0x00300000); + rtw_write32(rtwdev, REG_RFECTL_A, 0x00100000); + mdelay(5); + rtw_write32(rtwdev, REG_TSSI_TRK_SW, 0x3c000000); + rtw_write32(rtwdev, REG_RFECTL_A, 0x00000000); + } + + if (tx1_finish) { + /* [31] = 0 --> Page C */ + rtw_write32_mask(rtwdev, REG_CCASEL, BIT(31), 0x0); + rtw_write32_mask(rtwdev, REG_IQK_COM00, 0x03FF8000, + tx_x1 & 0x000007ff); + rtw_write32_mask(rtwdev, REG_IQK_COM00, 0x000007FF, + tx_y1 & 0x000007ff); + /* [31] = 1 --> Page C1 */ + rtw_write32_mask(rtwdev, REG_CCASEL, BIT(31), 0x1); + if (efuse->rfe_option == 1) + rtw_write32(rtwdev, REG_RXPITMB, 0x28161500); + else + rtw_write32(rtwdev, REG_RXPITMB, 0x28160ca0); + rtw_write32(rtwdev, REG_RFECTL_B, 0x00300000); + rtw_write32(rtwdev, REG_RFECTL_B, 0x00100000); + mdelay(5); + rtw_write32(rtwdev, REG_RXPITMB, 0x3c000000); + rtw_write32(rtwdev, REG_RFECTL_B, 0x00000000); + } + + for (delay_count = 0; delay_count < 20; delay_count++) { + if (!rx0_finish && tx0_finish) + iqk0_ready = rtw_read32_mask(rtwdev, + REG_IQKA_END, + BIT(10)); + if (!rx1_finish && tx1_finish) + iqk1_ready = rtw_read32_mask(rtwdev, + REG_IQKB_END, + BIT(10)); + if (iqk0_ready && iqk1_ready) + break; + + mdelay(1); + } + + rtw_dbg(rtwdev, RTW_DBG_RFK, "RX delay_count = %d\n", + delay_count); + + if (delay_count < 20) { /* If 20ms No Result, then cal_retry++ */ + /* ============RXIQK Check============== */ + rx0_fail = rtw_read32_mask(rtwdev, REG_IQKA_END, BIT(11)); + rx1_fail = rtw_read32_mask(rtwdev, REG_IQKB_END, BIT(11)); + + if (!(rx0_fail || rx0_finish) && tx0_finish) { + rtw_write32(rtwdev, REG_RFECTL_A, 0x06000000); + rx_x0_temp[rx0_avg] = rtw_read32_mask(rtwdev, + REG_IQKA_END, + 0x07ff0000); + rtw_write32(rtwdev, REG_RFECTL_A, 0x08000000); + rx_y0_temp[rx0_avg] = rtw_read32_mask(rtwdev, + REG_IQKA_END, + 0x07ff0000); + + rtw_dbg(rtwdev, RTW_DBG_RFK, + "rx_x0[%d] = %x ;; rx_y0[%d] = %x\n", + rx0_avg, rx_x0_temp[rx0_avg], + rx0_avg, rx_y0_temp[rx0_avg]); + + rx_x0_temp[rx0_avg] <<= 21; + rx_y0_temp[rx0_avg] <<= 21; + + rx0_avg++; + } else { + rtw_dbg(rtwdev, RTW_DBG_RFK, + "1. RXA_cal_retry = %d\n", cal0_retry); + + cal0_retry++; + if (cal0_retry == 10) + break; + } + + if (!(rx1_fail || rx1_finish) && tx1_finish) { + rtw_write32(rtwdev, REG_RFECTL_B, 0x06000000); + rx_x1_temp[rx1_avg] = rtw_read32_mask(rtwdev, + REG_IQKB_END, + 0x07ff0000); + rtw_write32(rtwdev, REG_RFECTL_B, 0x08000000); + rx_y1_temp[rx1_avg] = rtw_read32_mask(rtwdev, + REG_IQKB_END, + 0x07ff0000); + + rtw_dbg(rtwdev, RTW_DBG_RFK, + "rx_x1[%d] = %x ;; rx_y1[%d] = %x\n", + rx1_avg, rx_x1_temp[rx1_avg], + rx1_avg, rx_y1_temp[rx1_avg]); + + rx_x1_temp[rx1_avg] <<= 21; + rx_y1_temp[rx1_avg] <<= 21; + + rx1_avg++; + } else { + cal1_retry++; + if (cal1_retry == 10) + break; + } + } else { + rtw_dbg(rtwdev, RTW_DBG_RFK, + "2. RXA_cal_retry = %d\n", cal0_retry); + + cal0_retry++; + cal1_retry++; + + rtw_dbg(rtwdev, RTW_DBG_RFK, + "delay 20ms RX IQK Not Ready!!!!!\n"); + + if (cal0_retry == 10) + break; + } + + rtw_dbg(rtwdev, RTW_DBG_RFK, "3. RXA_cal_retry = %d\n", + cal0_retry); + + if (rx0_avg >= 2) + rx0_finish = rtw88xxa_iqk_finish(rx0_avg, 4, + rx_x0_temp, rx_y0_temp, + &rx_x0, &rx_y0, + true, false); + + if (rx1_avg >= 2) + rx1_finish = rtw88xxa_iqk_finish(rx1_avg, 4, + rx_x1_temp, rx_y1_temp, + &rx_x1, &rx_y1, + true, false); + + rtw_dbg(rtwdev, RTW_DBG_RFK, + "rx0_average = %d, rx1_average = %d\n", + rx0_avg, rx1_avg); + rtw_dbg(rtwdev, RTW_DBG_RFK, + "rx0_finish = %d, rx1_finish = %d\n", + rx0_finish, rx1_finish); + + if ((rx0_finish || !tx0_finish) && (rx1_finish || !tx1_finish)) + break; + + if ((cal0_retry + rx0_avg) >= 10 || + (cal1_retry + rx1_avg) >= 10 || + rx0_avg == 3 || rx1_avg == 3) + break; + } + + rtw_dbg(rtwdev, RTW_DBG_RFK, "RXA_cal_retry = %d\n", cal0_retry); + rtw_dbg(rtwdev, RTW_DBG_RFK, "RXB_cal_retry = %d\n", cal1_retry); + + /* FillIQK Result */ + rtw_dbg(rtwdev, RTW_DBG_RFK, "========Path_A =======\n"); + + if (tx0_finish) + rtw8812a_iqk_tx_fill(rtwdev, RF_PATH_A, tx_x0, tx_y0); + else + rtw8812a_iqk_tx_fill(rtwdev, RF_PATH_A, 0x200, 0x0); + + if (rx0_finish) + rtw8812a_iqk_rx_fill(rtwdev, RF_PATH_A, rx_x0, rx_y0); + else + rtw8812a_iqk_rx_fill(rtwdev, RF_PATH_A, 0x200, 0x0); + + rtw_dbg(rtwdev, RTW_DBG_RFK, "========Path_B =======\n"); + + if (tx1_finish) + rtw8812a_iqk_tx_fill(rtwdev, RF_PATH_B, tx_x1, tx_y1); + else + rtw8812a_iqk_tx_fill(rtwdev, RF_PATH_B, 0x200, 0x0); + + if (rx1_finish) + rtw8812a_iqk_rx_fill(rtwdev, RF_PATH_B, rx_x1, rx_y1); + else + rtw8812a_iqk_rx_fill(rtwdev, RF_PATH_B, 0x200, 0x0); +} + +#define MACBB_REG_NUM_8812A 9 +#define AFE_REG_NUM_8812A 12 +#define RF_REG_NUM_8812A 3 + +static void rtw8812a_do_iqk(struct rtw_dev *rtwdev) +{ + static const u32 backup_macbb_reg[MACBB_REG_NUM_8812A] = { + 0x520, 0x550, 0x808, 0xa04, 0x90c, 0xc00, 0xe00, 0x838, 0x82c + }; + static const u32 backup_afe_reg[AFE_REG_NUM_8812A] = { + 0xc5c, 0xc60, 0xc64, 0xc68, 0xcb0, 0xcb4, + 0xe5c, 0xe60, 0xe64, 0xe68, 0xeb0, 0xeb4 + }; + static const u32 backup_rf_reg[RF_REG_NUM_8812A] = { + 0x65, 0x8f, 0x0 + }; + u32 macbb_backup[MACBB_REG_NUM_8812A] = {}; + u32 afe_backup[AFE_REG_NUM_8812A] = {}; + u32 rfa_backup[RF_REG_NUM_8812A] = {}; + u32 rfb_backup[RF_REG_NUM_8812A] = {}; + u32 reg_cb8, reg_eb8; + + rtw88xxa_iqk_backup_mac_bb(rtwdev, macbb_backup, + backup_macbb_reg, MACBB_REG_NUM_8812A); + + rtw_write32_set(rtwdev, REG_CCASEL, BIT(31)); + reg_cb8 = rtw_read32(rtwdev, REG_RFECTL_A); + reg_eb8 = rtw_read32(rtwdev, REG_RFECTL_B); + rtw_write32_clr(rtwdev, REG_CCASEL, BIT(31)); + + rtw88xxa_iqk_backup_afe(rtwdev, afe_backup, + backup_afe_reg, AFE_REG_NUM_8812A); + rtw8812a_iqk_backup_rf(rtwdev, rfa_backup, rfb_backup, + backup_rf_reg, RF_REG_NUM_8812A); + + rtw88xxa_iqk_configure_mac(rtwdev); + + rtw8812a_iqk(rtwdev); + + rtw8812a_iqk_restore_rf(rtwdev, RF_PATH_A, backup_rf_reg, + rfa_backup, RF_REG_NUM_8812A); + rtw8812a_iqk_restore_rf(rtwdev, RF_PATH_B, backup_rf_reg, + rfb_backup, RF_REG_NUM_8812A); + + rtw8812a_iqk_restore_afe(rtwdev, afe_backup, + backup_afe_reg, AFE_REG_NUM_8812A); + + rtw_write32_set(rtwdev, REG_CCASEL, BIT(31)); + rtw_write32(rtwdev, REG_RFECTL_A, reg_cb8); + rtw_write32(rtwdev, REG_RFECTL_B, reg_eb8); + rtw_write32_clr(rtwdev, REG_CCASEL, BIT(31)); + + rtw88xxa_iqk_restore_mac_bb(rtwdev, macbb_backup, + backup_macbb_reg, MACBB_REG_NUM_8812A); +} + +static void rtw8812a_phy_calibration(struct rtw_dev *rtwdev) +{ + u8 channel = rtwdev->hal.current_channel; + + rtw8812a_do_iqk(rtwdev); + + /* The official driver wants to do this after connecting + * but before first writing a new igi (phydm_get_new_igi). + * Here seems close enough. + */ + if (channel >= 36 && channel <= 64) + rtw_load_table(rtwdev, &rtw8812a_agc_diff_lb_tbl); + else if (channel >= 100) + rtw_load_table(rtwdev, &rtw8812a_agc_diff_hb_tbl); +} + +static void rtw8812a_pwr_track(struct rtw_dev *rtwdev) +{ + struct rtw_dm_info *dm_info = &rtwdev->dm_info; + + if (!dm_info->pwr_trk_triggered) { + rtw_write_rf(rtwdev, RF_PATH_A, RF_T_METER, + GENMASK(17, 16), 0x03); + dm_info->pwr_trk_triggered = true; + return; + } + + rtw88xxa_phy_pwrtrack(rtwdev, rtw8812a_do_lck, rtw8812a_do_iqk); + dm_info->pwr_trk_triggered = false; +} + +static void rtw8812a_fill_txdesc_checksum(struct rtw_dev *rtwdev, + struct rtw_tx_pkt_info *pkt_info, + u8 *txdesc) +{ + fill_txdesc_checksum_common(txdesc, 16); +} + +static void rtw8812a_coex_cfg_init(struct rtw_dev *rtwdev) +{ +} + +static void rtw8812a_coex_cfg_gnt_fix(struct rtw_dev *rtwdev) +{ +} + +static void rtw8821a_coex_cfg_rfe_type(struct rtw_dev *rtwdev) +{ +} + +static void rtw8821a_coex_cfg_wl_tx_power(struct rtw_dev *rtwdev, u8 wl_pwr) +{ +} + +static void rtw8821a_coex_cfg_wl_rx_gain(struct rtw_dev *rtwdev, bool low_gain) +{ +} + +static const struct rtw_chip_ops rtw8812a_ops = { + .power_on = rtw88xxa_power_on, + .power_off = rtw8812a_power_off, + .phy_set_param = NULL, + .read_efuse = rtw88xxa_read_efuse, + .query_phy_status = rtw8812a_query_phy_status, + .set_channel = rtw88xxa_set_channel, + .mac_init = NULL, + .read_rf = rtw88xxa_phy_read_rf, + .write_rf = rtw_phy_write_rf_reg_sipi, + .set_antenna = NULL, + .set_tx_power_index = rtw88xxa_set_tx_power_index, + .cfg_ldo25 = rtw8812a_cfg_ldo25, + .efuse_grant = rtw88xxa_efuse_grant, + .false_alarm_statistics = rtw88xxa_false_alarm_statistics, + .phy_calibration = rtw8812a_phy_calibration, + .cck_pd_set = rtw88xxa_phy_cck_pd_set, + .pwr_track = rtw8812a_pwr_track, + .config_bfee = NULL, + .set_gid_table = NULL, + .cfg_csi_rate = NULL, + .fill_txdesc_checksum = rtw8812a_fill_txdesc_checksum, + .coex_set_init = rtw8812a_coex_cfg_init, + .coex_set_ant_switch = NULL, + .coex_set_gnt_fix = rtw8812a_coex_cfg_gnt_fix, + .coex_set_gnt_debug = NULL, + .coex_set_rfe_type = rtw8821a_coex_cfg_rfe_type, + .coex_set_wl_tx_power = rtw8821a_coex_cfg_wl_tx_power, + .coex_set_wl_rx_gain = rtw8821a_coex_cfg_wl_rx_gain, +}; + +static const struct rtw_page_table page_table_8812a[] = { + /* hq_num, nq_num, lq_num, exq_num, gapq_num */ + {0, 0, 0, 0, 0}, /* SDIO */ + {0, 0, 0, 0, 0}, /* PCI */ + {16, 0, 0, 0, 1}, /* 2 bulk out endpoints */ + {16, 0, 16, 0, 1}, /* 3 bulk out endpoints */ + {16, 0, 16, 0, 1}, /* 4 bulk out endpoints */ +}; + +static const struct rtw_rqpn rqpn_table_8812a[] = { + {RTW_DMA_MAPPING_NORMAL, RTW_DMA_MAPPING_NORMAL, + RTW_DMA_MAPPING_LOW, RTW_DMA_MAPPING_LOW, + RTW_DMA_MAPPING_EXTRA, RTW_DMA_MAPPING_HIGH}, + + {RTW_DMA_MAPPING_NORMAL, RTW_DMA_MAPPING_NORMAL, + RTW_DMA_MAPPING_LOW, RTW_DMA_MAPPING_LOW, + RTW_DMA_MAPPING_EXTRA, RTW_DMA_MAPPING_HIGH}, + + {RTW_DMA_MAPPING_HIGH, RTW_DMA_MAPPING_HIGH, + RTW_DMA_MAPPING_NORMAL, RTW_DMA_MAPPING_NORMAL, + RTW_DMA_MAPPING_HIGH, RTW_DMA_MAPPING_HIGH}, + + {RTW_DMA_MAPPING_HIGH, RTW_DMA_MAPPING_NORMAL, + RTW_DMA_MAPPING_LOW, RTW_DMA_MAPPING_LOW, + RTW_DMA_MAPPING_HIGH, RTW_DMA_MAPPING_HIGH}, + + {RTW_DMA_MAPPING_NORMAL, RTW_DMA_MAPPING_NORMAL, + RTW_DMA_MAPPING_LOW, RTW_DMA_MAPPING_LOW, + RTW_DMA_MAPPING_EXTRA, RTW_DMA_MAPPING_HIGH}, +}; + +static const struct rtw_prioq_addrs prioq_addrs_8812a = { + .prio[RTW_DMA_MAPPING_EXTRA] = { + .rsvd = REG_RQPN_NPQ + 2, .avail = REG_RQPN_NPQ + 3, + }, + .prio[RTW_DMA_MAPPING_LOW] = { + .rsvd = REG_RQPN + 1, .avail = REG_FIFOPAGE_CTRL_2 + 1, + }, + .prio[RTW_DMA_MAPPING_NORMAL] = { + .rsvd = REG_RQPN_NPQ, .avail = REG_RQPN_NPQ + 1, + }, + .prio[RTW_DMA_MAPPING_HIGH] = { + .rsvd = REG_RQPN, .avail = REG_FIFOPAGE_CTRL_2, + }, + .wsize = false, +}; + +static const struct rtw_hw_reg rtw8812a_dig[] = { + [0] = { .addr = REG_RXIGI_A, .mask = 0x7f }, + [1] = { .addr = REG_RXIGI_B, .mask = 0x7f }, +}; + +static const struct rtw_rfe_def rtw8812a_rfe_defs[] = { + [0] = { .phy_pg_tbl = &rtw8812a_bb_pg_tbl, + .txpwr_lmt_tbl = &rtw8812a_txpwr_lmt_tbl, + .pwr_track_tbl = &rtw8812a_rtw_pwr_track_tbl, }, + [1] = { .phy_pg_tbl = &rtw8812a_bb_pg_tbl, + .txpwr_lmt_tbl = &rtw8812a_txpwr_lmt_tbl, + .pwr_track_tbl = &rtw8812a_rtw_pwr_track_tbl, }, + [3] = { .phy_pg_tbl = &rtw8812a_bb_pg_rfe3_tbl, + .txpwr_lmt_tbl = &rtw8812a_txpwr_lmt_tbl, + .pwr_track_tbl = &rtw8812a_rtw_pwr_track_rfe3_tbl, }, +}; + +static const u8 wl_rssi_step_8812a[] = {101, 45, 101, 40}; +static const u8 bt_rssi_step_8812a[] = {101, 101, 101, 101}; + +static const struct coex_rf_para rf_para_tx_8812a[] = { + {0, 0, false, 7}, /* for normal */ + {0, 20, false, 7}, /* for WL-CPT */ + {8, 17, true, 4}, + {7, 18, true, 4}, + {6, 19, true, 4}, + {5, 20, true, 4} +}; + +static const struct coex_rf_para rf_para_rx_8812a[] = { + {0, 0, false, 7}, /* for normal */ + {0, 20, false, 7}, /* for WL-CPT */ + {3, 24, true, 5}, + {2, 26, true, 5}, + {1, 27, true, 5}, + {0, 28, true, 5} +}; + +static_assert(ARRAY_SIZE(rf_para_tx_8812a) == ARRAY_SIZE(rf_para_rx_8812a)); + +const struct rtw_chip_info rtw8812a_hw_spec = { + .ops = &rtw8812a_ops, + .id = RTW_CHIP_TYPE_8812A, + .fw_name = "rtw88/rtw8812a_fw.bin", + .wlan_cpu = RTW_WCPU_11N, + .tx_pkt_desc_sz = 40, + .tx_buf_desc_sz = 16, + .rx_pkt_desc_sz = 24, + .rx_buf_desc_sz = 8, + .phy_efuse_size = 512, + .log_efuse_size = 512, + .ptct_efuse_size = 96 + 1, /* TODO or just 18? */ + .txff_size = 131072, + .rxff_size = 16128, + .rsvd_drv_pg_num = 9, + .txgi_factor = 1, + .is_pwr_by_rate_dec = true, + .max_power_index = 0x3f, + .csi_buf_pg_num = 0, + .band = RTW_BAND_2G | RTW_BAND_5G, + .page_size = 512, + .dig_min = 0x20, + .ht_supported = true, + .vht_supported = true, + .lps_deep_mode_supported = 0, + .sys_func_en = 0xFD, + .pwr_on_seq = card_enable_flow_8812a, + .pwr_off_seq = card_disable_flow_8812a, + .page_table = page_table_8812a, + .rqpn_table = rqpn_table_8812a, + .prioq_addrs = &prioq_addrs_8812a, + .intf_table = NULL, + .dig = rtw8812a_dig, + .rf_sipi_addr = {REG_LSSI_WRITE_A, REG_LSSI_WRITE_B}, + .ltecoex_addr = NULL, + .mac_tbl = &rtw8812a_mac_tbl, + .agc_tbl = &rtw8812a_agc_tbl, + .bb_tbl = &rtw8812a_bb_tbl, + .rf_tbl = {&rtw8812a_rf_a_tbl, &rtw8812a_rf_b_tbl}, + .rfe_defs = rtw8812a_rfe_defs, + .rfe_defs_size = ARRAY_SIZE(rtw8812a_rfe_defs), + .rx_ldpc = false, + .hw_feature_report = false, + .c2h_ra_report_size = 4, + .old_datarate_fb_limit = true, + .usb_tx_agg_desc_num = 1, + .iqk_threshold = 8, + .ampdu_density = IEEE80211_HT_MPDU_DENSITY_16, + .max_scan_ie_len = IEEE80211_MAX_DATA_LEN, + + .coex_para_ver = 0, /* no coex code in 8812au driver */ + .bt_desired_ver = 0, + .scbd_support = false, + .new_scbd10_def = false, + .ble_hid_profile_support = false, + .wl_mimo_ps_support = false, + .pstdma_type = COEX_PSTDMA_FORCE_LPSOFF, + .bt_rssi_type = COEX_BTRSSI_RATIO, + .ant_isolation = 15, + .rssi_tolerance = 2, + .wl_rssi_step = wl_rssi_step_8812a, + .bt_rssi_step = bt_rssi_step_8812a, + .table_sant_num = 0, + .table_sant = NULL, + .table_nsant_num = 0, + .table_nsant = NULL, + .tdma_sant_num = 0, + .tdma_sant = NULL, + .tdma_nsant_num = 0, + .tdma_nsant = NULL, + .wl_rf_para_num = ARRAY_SIZE(rf_para_tx_8812a), + .wl_rf_para_tx = rf_para_tx_8812a, + .wl_rf_para_rx = rf_para_rx_8812a, + .bt_afh_span_bw20 = 0x20, + .bt_afh_span_bw40 = 0x30, + .afh_5g_num = 0, + .afh_5g = NULL, + .coex_info_hw_regs_num = 0, + .coex_info_hw_regs = NULL, +}; +EXPORT_SYMBOL(rtw8812a_hw_spec); + +MODULE_FIRMWARE("rtw88/rtw8812a_fw.bin"); + +MODULE_AUTHOR("Realtek Corporation"); +MODULE_DESCRIPTION("Realtek 802.11ac wireless 8812a driver"); +MODULE_LICENSE("Dual BSD/GPL"); diff --git a/rtw8812a.h b/rtw8812a.h new file mode 100644 index 00000000..82dab59e --- /dev/null +++ b/rtw8812a.h @@ -0,0 +1,10 @@ +/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */ +/* Copyright(c) 2024 Realtek Corporation + */ + +#ifndef __RTW8812A_H__ +#define __RTW8812A_H__ + +extern const struct rtw_chip_info rtw8812a_hw_spec; + +#endif diff --git a/rtw8812a_table.c b/rtw8812a_table.c index 0d005d88..048efbbd 100644 --- a/rtw8812a_table.c +++ b/rtw8812a_table.c @@ -1,5 +1,5 @@ // SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause -/* Copyright(c) 2018-2019 Realtek Corporation +/* Copyright(c) 2024 Realtek Corporation */ #include "main.h" @@ -2596,18 +2596,18 @@ static const struct rtw_pwr_seq_cmd trans_cardemu_to_carddis_8812a[] = { RTW_PWR_CMD_END, 0, 0}, }; -const struct rtw_pwr_seq_cmd *card_enable_flow_8812a[] = { +const struct rtw_pwr_seq_cmd * const card_enable_flow_8812a[] = { trans_carddis_to_cardemu_8812a, trans_cardemu_to_act_8812a, NULL }; -const struct rtw_pwr_seq_cmd *enter_lps_flow_8812a[] = { +const struct rtw_pwr_seq_cmd * const enter_lps_flow_8812a[] = { trans_act_to_lps_8812a, NULL }; -const struct rtw_pwr_seq_cmd *card_disable_flow_8812a[] = { +const struct rtw_pwr_seq_cmd * const card_disable_flow_8812a[] = { trans_act_to_cardemu_8812a, trans_cardemu_to_carddis_8812a, NULL diff --git a/rtw8812a_table.h b/rtw8812a_table.h index 15ecc72b..f7ab5e4c 100644 --- a/rtw8812a_table.h +++ b/rtw8812a_table.h @@ -1,5 +1,5 @@ /* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */ -/* Copyright(c) 2018-2019 Realtek Corporation +/* Copyright(c) 2024 Realtek Corporation */ #ifndef __RTW8812A_TABLE_H__ @@ -16,9 +16,9 @@ extern const struct rtw_table rtw8812a_rf_a_tbl; extern const struct rtw_table rtw8812a_rf_b_tbl; extern const struct rtw_table rtw8812a_txpwr_lmt_tbl; -extern const struct rtw_pwr_seq_cmd *card_enable_flow_8812a[]; -extern const struct rtw_pwr_seq_cmd *enter_lps_flow_8812a[]; -extern const struct rtw_pwr_seq_cmd *card_disable_flow_8812a[]; +extern const struct rtw_pwr_seq_cmd * const card_enable_flow_8812a[]; +extern const struct rtw_pwr_seq_cmd * const enter_lps_flow_8812a[]; +extern const struct rtw_pwr_seq_cmd * const card_disable_flow_8812a[]; extern const struct rtw_pwr_track_tbl rtw8812a_rtw_pwr_track_tbl; extern const struct rtw_pwr_track_tbl rtw8812a_rtw_pwr_track_rfe3_tbl; diff --git a/rtw8812au.c b/rtw8812au.c index c62a8b05..947e3e98 100644 --- a/rtw8812au.c +++ b/rtw8812au.c @@ -1,11 +1,11 @@ // SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause -/* Copyright(c) 2018-2024 Realtek Corporation +/* Copyright(c) 2024 Realtek Corporation */ #include #include #include "main.h" -#include "rtw8821a.h" +#include "rtw8812a.h" #include "usb.h" static const struct usb_device_id rtw_8812au_id_table[] = { diff --git a/rtw8821a.c b/rtw8821a.c index d30296d8..db242c9a 100644 --- a/rtw8821a.c +++ b/rtw8821a.c @@ -1,3332 +1,716 @@ // SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause -/* Copyright(c) 2018-2019 Realtek Corporation +/* Copyright(c) 2024 Realtek Corporation */ -#include #include "main.h" #include "coex.h" -#include "fw.h" -#include "tx.h" -#include "rx.h" #include "phy.h" +#include "reg.h" +#include "rtw88xxa.h" #include "rtw8821a.h" #include "rtw8821a_table.h" -#include "rtw8812a_table.h" -#include "mac.h" -#include "reg.h" -#include "sec.h" -#include "debug.h" -#include "bf.h" -#include "regd.h" -#include "efuse.h" -#include "usb.h" - -static void rtw8821a_efuse_grant(struct rtw_dev *rtwdev, bool on) -{ - if (on) { - rtw_write8(rtwdev, REG_EFUSE_ACCESS, EFUSE_ACCESS_ON); +#include "tx.h" - rtw_write16_set(rtwdev, REG_SYS_FUNC_EN, BIT_FEN_ELDR); - rtw_write16_set(rtwdev, REG_SYS_CLKR, BIT_LOADER_CLK_EN | BIT_ANA8M); - } else { - rtw_write8(rtwdev, REG_EFUSE_ACCESS, EFUSE_ACCESS_OFF); - } +static void rtw8821a_power_off(struct rtw_dev *rtwdev) +{ + rtw88xxa_power_off(rtwdev, enter_lps_flow_8821a); } -static void rtw8812a_read_amplifier_type(struct rtw_dev *rtwdev) +static s8 rtw8821a_cck_rx_pwr(u8 lna_idx, u8 vga_idx) { - struct rtw_efuse *efuse = &rtwdev->efuse; - - efuse->ext_pa_2g = (efuse->pa_type_2g & BIT(5)) && - (efuse->pa_type_2g & BIT(4)); - efuse->ext_lna_2g = (efuse->lna_type_2g & BIT(7)) && - (efuse->lna_type_2g & BIT(3)); - - efuse->ext_pa_5g = (efuse->pa_type_5g & BIT(1)) && - (efuse->pa_type_5g & BIT(0)); - efuse->ext_lna_5g = (efuse->lna_type_5g & BIT(7)) && - (efuse->lna_type_5g & BIT(3)); - - /* For rtw_phy_cond2: */ - if (efuse->ext_pa_2g) { - u8 ext_type_pa_2g_a = u8_get_bits(efuse->lna_type_2g, BIT(2)); - u8 ext_type_pa_2g_b = u8_get_bits(efuse->lna_type_2g, BIT(6)); - - efuse->gpa_type = (ext_type_pa_2g_b << 2) | ext_type_pa_2g_a; - } - - if (efuse->ext_pa_5g) { - u8 ext_type_pa_5g_a = u8_get_bits(efuse->lna_type_5g, BIT(2)); - u8 ext_type_pa_5g_b = u8_get_bits(efuse->lna_type_5g, BIT(6)); - - efuse->apa_type = (ext_type_pa_5g_b << 2) | ext_type_pa_5g_a; - } - - if (efuse->ext_lna_2g) { - u8 ext_type_lna_2g_a = u8_get_bits(efuse->lna_type_2g, - BIT(1) | BIT(0)); - u8 ext_type_lna_2g_b = u8_get_bits(efuse->lna_type_2g, - BIT(5) | BIT(4)); + static const s8 lna_gain_table[] = {15, -1, -17, 0, -30, -38}; + s8 rx_pwr_all = 0; + s8 lna_gain; - efuse->glna_type = (ext_type_lna_2g_b << 2) | ext_type_lna_2g_a; + switch (lna_idx) { + case 5: + case 4: + case 2: + case 1: + case 0: + lna_gain = lna_gain_table[lna_idx]; + rx_pwr_all = lna_gain - 2 * vga_idx; + break; + default: + break; } - if (efuse->ext_lna_5g) { - u8 ext_type_lna_5g_a = u8_get_bits(efuse->lna_type_5g, - BIT(1) | BIT(0)); - u8 ext_type_lna_5g_b = u8_get_bits(efuse->lna_type_5g, - BIT(5) | BIT(4)); - - efuse->alna_type = (ext_type_lna_5g_b << 2) | ext_type_lna_5g_a; - } + return rx_pwr_all; } -static void rtw8812a_read_rfe_type(struct rtw_dev *rtwdev, struct rtw8821a_efuse *map) +static void rtw8821a_query_phy_status(struct rtw_dev *rtwdev, u8 *phy_status, + struct rtw_rx_pkt_stat *pkt_stat) { - struct rtw_efuse *efuse = &rtwdev->efuse; - - if (map->rfe_option == 0xff) { - if (rtwdev->hci.type == RTW_HCI_TYPE_USB) - efuse->rfe_option = 0; - else if (rtwdev->hci.type == RTW_HCI_TYPE_PCIE) - efuse->rfe_option = 2; - else - efuse->rfe_option = 4; - } else if (map->rfe_option & BIT(7)) { - if (efuse->ext_lna_5g) { - if (efuse->ext_pa_5g) { - if (efuse->ext_lna_2g && efuse->ext_pa_2g) - efuse->rfe_option = 3; - else - efuse->rfe_option = 0; - } else { - efuse->rfe_option = 2; - } - } else { - efuse->rfe_option = 4; - } - } else { - efuse->rfe_option = map->rfe_option & 0x3f; - - /* Due to other customer already use incorrect EFUSE map for - * their product. We need to add workaround to prevent to - * modify spec and notify all customer to revise the IC 0xca - * content. - */ - if (efuse->rfe_option == 4 && - (efuse->ext_pa_5g || efuse->ext_pa_2g || - efuse->ext_lna_5g || efuse->ext_lna_2g)) { - if (rtwdev->hci.type == RTW_HCI_TYPE_USB) - efuse->rfe_option = 0; - else if (rtwdev->hci.type == RTW_HCI_TYPE_PCIE) - efuse->rfe_option = 2; - } - } + rtw88xxa_query_phy_status(rtwdev, phy_status, pkt_stat, + rtw8821a_cck_rx_pwr); } -static void rtw8812a_read_usb_type(struct rtw_dev *rtwdev) +static void rtw8821a_cfg_ldo25(struct rtw_dev *rtwdev, bool enable) { - struct rtw_efuse *efuse = &rtwdev->efuse; - struct rtw_hal *hal = &rtwdev->hal; - u8 antenna = 0; - u8 wmode = 0; - u8 val8, i; - - efuse->hw_cap.bw = BIT(RTW_CHANNEL_WIDTH_20) | - BIT(RTW_CHANNEL_WIDTH_40) | - BIT(RTW_CHANNEL_WIDTH_80); - efuse->hw_cap.ptcl = EFUSE_HW_CAP_PTCL_VHT; - - if (rtwdev->chip->id == RTW_CHIP_TYPE_8821A) - efuse->hw_cap.nss = 1; - else - efuse->hw_cap.nss = 2; - - if (rtwdev->chip->id == RTW_CHIP_TYPE_8821A) - return; - - for (i = 0; i < 2; i++) { - rtw_read8_physical_efuse(rtwdev, 1019 - i, &val8); +} - antenna = u8_get_bits(val8, GENMASK(7, 5)); - if (antenna) - break; - antenna = u8_get_bits(val8, GENMASK(3, 1)); - if (antenna) - break; - } +#define CAL_NUM_8821A 3 +#define MACBB_REG_NUM_8821A 8 +#define AFE_REG_NUM_8821A 4 +#define RF_REG_NUM_8821A 3 - for (i = 0; i < 2; i++) { - rtw_read8_physical_efuse(rtwdev, 1021 - i, &val8); +static void rtw8821a_iqk_backup_rf(struct rtw_dev *rtwdev, u32 *rfa_backup, + const u32 *backup_rf_reg, u32 rf_num) +{ + u32 i; - wmode = u8_get_bits(val8, GENMASK(3, 2)); - if (wmode) - break; - } + /* [31] = 0 --> Page C */ + rtw_write32_mask(rtwdev, REG_CCASEL, BIT(31), 0x0); - if (antenna == 1) { - rtw_info(rtwdev, "This RTL8812AU says it is 1T1R.\n"); - - efuse->hw_cap.nss = 1; - hal->rf_type = RF_1T1R; - hal->rf_path_num = 1; - hal->rf_phy_num = 1; - hal->antenna_tx = BB_PATH_A; - hal->antenna_rx = BB_PATH_A; - } else { - /* Override rtw_chip_parameter_setup(). It detects 8812au as 1T1R. */ - efuse->hw_cap.nss = 2; - hal->rf_type = RF_2T2R; - hal->rf_path_num = 2; - hal->rf_phy_num = 2; - hal->antenna_tx = BB_PATH_AB; - hal->antenna_rx = BB_PATH_AB; - - if (antenna == 2 && wmode == 2) { - rtw_info(rtwdev, "This RTL8812AU says it can't do VHT.\n"); - - /* Can't be EFUSE_HW_CAP_IGNORE and can't be - * EFUSE_HW_CAP_PTCL_VHT, so make it 1. - */ - efuse->hw_cap.ptcl = 1; - efuse->hw_cap.bw &= ~BIT(RTW_CHANNEL_WIDTH_80); - } - } + /* Save RF Parameters */ + for (i = 0; i < rf_num; i++) + rfa_backup[i] = rtw_read_rf(rtwdev, RF_PATH_A, + backup_rf_reg[i], MASKDWORD); } -static int rtw8821a_read_efuse(struct rtw_dev *rtwdev, u8 *log_map) +static void rtw8821a_iqk_restore_rf(struct rtw_dev *rtwdev, + const u32 *backup_rf_reg, + u32 *RF_backup, u32 rf_reg_num) { - const struct rtw_chip_info *chip = rtwdev->chip; - struct rtw_efuse *efuse = &rtwdev->efuse; - struct rtw8821a_efuse *map; - int i; - - if (chip->id == RTW_CHIP_TYPE_8812A) - rtwdev->hal.cut_version += 1; - - if (rtw_dbg_is_enabled(rtwdev, RTW_DBG_EFUSE)) - print_hex_dump(KERN_INFO, "", DUMP_PREFIX_OFFSET, 16, 1, - log_map, chip->log_efuse_size, true); - - map = (struct rtw8821a_efuse *)log_map; + u32 i; - efuse->rf_board_option = map->rf_board_option; - efuse->crystal_cap = map->xtal_k; - if (efuse->crystal_cap == 0xff) - efuse->crystal_cap = 0x20; - efuse->pa_type_2g = map->pa_type; - efuse->pa_type_5g = map->pa_type; - efuse->lna_type_2g = map->lna_type_2g; - efuse->lna_type_5g = map->lna_type_5g; - if (chip->id == RTW_CHIP_TYPE_8812A) { - rtw8812a_read_amplifier_type(rtwdev); - rtw8812a_read_rfe_type(rtwdev, map); + /* [31] = 0 --> Page C */ + rtw_write32_mask(rtwdev, REG_CCASEL, BIT(31), 0x0); - efuse->usb_mode_switch = u8_get_bits(map->usb_mode, BIT(1)); - } - efuse->channel_plan = map->channel_plan; - efuse->country_code[0] = map->country_code[0]; - efuse->country_code[1] = map->country_code[1]; - efuse->bt_setting = map->rf_bt_setting; - efuse->regd = map->rf_board_option & 0x7; - efuse->thermal_meter[0] = map->thermal_meter; - efuse->thermal_meter[1] = map->thermal_meter; - efuse->thermal_meter_k = map->thermal_meter; - efuse->tx_bb_swing_setting_2g = map->tx_bb_swing_setting_2g; - efuse->tx_bb_swing_setting_5g = map->tx_bb_swing_setting_5g; - - rtw8812a_read_usb_type(rtwdev); - - if (chip->id == RTW_CHIP_TYPE_8821A) - efuse->btcoex = rtw_read32_mask(rtwdev, REG_WL_BT_PWR_CTRL, - BIT_BT_FUNC_EN); - else - efuse->btcoex = (map->rf_board_option & 0xe0) == 0x20; - efuse->share_ant = !!(efuse->bt_setting & BIT(0)); + for (i = 0; i < rf_reg_num; i++) + rtw_write_rf(rtwdev, RF_PATH_A, backup_rf_reg[i], + RFREG_MASK, RF_backup[i]); +} - /* No antenna diversity because it's disabled in the vendor driver */ - efuse->ant_div_cfg = 0; +static void rtw8821a_iqk_restore_afe(struct rtw_dev *rtwdev, u32 *afe_backup, + const u32 *backup_afe_reg, u32 afe_num) +{ + u32 i; - efuse->ant_div_type = map->rf_antenna_option; - if (efuse->ant_div_type == 0xff) - efuse->ant_div_type = 0x3; + /* [31] = 0 --> Page C */ + rtw_write32_mask(rtwdev, REG_CCASEL, BIT(31), 0x0); - for (i = 0; i < 4; i++) - efuse->txpwr_idx_table[i] = map->txpwr_idx_table[i]; + /* Reload AFE Parameters */ + for (i = 0; i < afe_num; i++) + rtw_write32(rtwdev, backup_afe_reg[i], afe_backup[i]); - switch (rtw_hci_type(rtwdev)) { - case RTW_HCI_TYPE_USB: - if (chip->id == RTW_CHIP_TYPE_8821A) - ether_addr_copy(efuse->addr, map->rtw8821au.mac_addr); - else - ether_addr_copy(efuse->addr, map->rtw8812au.mac_addr); - break; - case RTW_HCI_TYPE_PCIE: - case RTW_HCI_TYPE_SDIO: - default: - /* unsupported now */ - return -EOPNOTSUPP; - } + /* [31] = 1 --> Page C1 */ + rtw_write32_mask(rtwdev, REG_CCASEL, BIT(31), 0x1); - return 0; + rtw_write32(rtwdev, REG_OFDM0_XA_TX_IQ_IMBALANCE, 0x0); + rtw_write32(rtwdev, REG_OFDM0_A_TX_AFE, 0x0); + rtw_write32(rtwdev, REG_OFDM0_XB_TX_IQ_IMBALANCE, 0x0); + rtw_write32(rtwdev, REG_TSSI_TRK_SW, 0x3c000000); + rtw_write32(rtwdev, REG_LSSI_WRITE_A, 0x00000080); + rtw_write32(rtwdev, REG_TXAGCIDX, 0x00000000); + rtw_write32(rtwdev, REG_IQK_DPD_CFG, 0x20040000); + rtw_write32(rtwdev, REG_CFG_PMPD, 0x20000000); + rtw_write32(rtwdev, REG_RFECTL_A, 0x0); } -static void rtw8821a_reset_8051(struct rtw_dev *rtwdev) +static void rtw8821a_iqk_rx_fill(struct rtw_dev *rtwdev, + unsigned int rx_x, unsigned int rx_y) { - const struct rtw_chip_info *chip = rtwdev->chip; - u8 val8; - - /* Reset MCU IO Wrapper */ - rtw_write8_clr(rtwdev, REG_RSV_CTRL, BIT(1)); - if (chip->id == RTW_CHIP_TYPE_8812A) - rtw_write8_clr(rtwdev, REG_RSV_CTRL + 1, BIT(3)); - else - rtw_write8_clr(rtwdev, REG_RSV_CTRL + 1, BIT(0)); + /* [31] = 0 --> Page C */ + rtw_write32_mask(rtwdev, REG_CCASEL, BIT(31), 0x0); - val8 = rtw_read8(rtwdev, REG_SYS_FUNC_EN + 1); - rtw_write8(rtwdev, REG_SYS_FUNC_EN + 1, val8 & ~BIT(2)); + rtw_write32_mask(rtwdev, REG_RX_IQC_AB_A, + 0x000003ff, rx_x >> 1); + rtw_write32_mask(rtwdev, REG_RX_IQC_AB_A, + 0x03ff0000, (rx_y >> 1) & 0x3ff); +} - /* Enable MCU IO Wrapper */ - rtw_write8_clr(rtwdev, REG_RSV_CTRL, BIT(1)); - if (chip->id == RTW_CHIP_TYPE_8812A) - rtw_write8_set(rtwdev, REG_RSV_CTRL + 1, BIT(3)); - else - rtw_write8_set(rtwdev, REG_RSV_CTRL + 1, BIT(0)); +static void rtw8821a_iqk_tx_fill(struct rtw_dev *rtwdev, + unsigned int tx_x, unsigned int tx_y) +{ + /* [31] = 1 --> Page C1 */ + rtw_write32_mask(rtwdev, REG_CCASEL, BIT(31), 0x1); - rtw_write8(rtwdev, REG_SYS_FUNC_EN + 1, val8 | BIT(2)); + rtw_write32(rtwdev, REG_LSSI_WRITE_A, 0x00000080); + rtw_write32(rtwdev, REG_IQK_DPD_CFG, 0x20040000); + rtw_write32(rtwdev, REG_CFG_PMPD, 0x20000000); + rtw_write32_mask(rtwdev, REG_IQC_Y, 0x000007ff, tx_y); + rtw_write32_mask(rtwdev, REG_IQC_X, 0x000007ff, tx_x); } -/* A lightweight deinit function */ -static void rtw8812au_hw_reset(struct rtw_dev *rtwdev) +static void rtw8821a_iqk_tx_vdf_true(struct rtw_dev *rtwdev, u32 cal, + bool *tx0iqkok, + int tx_x0[CAL_NUM_8821A], + int tx_y0[CAL_NUM_8821A]) { - u8 val8; + u32 cal_retry, delay_count, iqk_ready, tx_fail; + int tx_dt[3], vdf_y[3], vdf_x[3]; + int k; - if (!(rtw_read8(rtwdev, REG_MCUFW_CTRL) & BIT_RAM_DL_SEL)) - return; + for (k = 0; k < 3; k++) { + switch (k) { + case 0: + /* TX_Tone_idx[9:0], TxK_Mask[29] TX_Tone = 16 */ + rtw_write32(rtwdev, REG_OFDM0_XA_TX_IQ_IMBALANCE, + 0x18008c38); + /* RX_Tone_idx[9:0], RxK_Mask[29] */ + rtw_write32(rtwdev, REG_OFDM0_A_TX_AFE, 0x38008c38); + rtw_write32_mask(rtwdev, REG_INTPO_SETA, BIT(31), 0x0); + break; + case 1: + rtw_write32_mask(rtwdev, REG_OFDM0_XA_TX_IQ_IMBALANCE, + BIT(28), 0x0); + rtw_write32_mask(rtwdev, REG_OFDM0_A_TX_AFE, + BIT(28), 0x0); + rtw_write32_mask(rtwdev, REG_INTPO_SETA, BIT(31), 0x0); + break; + case 2: + rtw_dbg(rtwdev, RTW_DBG_RFK, + "vdf_y[1] = %x vdf_y[0] = %x\n", + vdf_y[1] >> 21 & 0x00007ff, + vdf_y[0] >> 21 & 0x00007ff); + + rtw_dbg(rtwdev, RTW_DBG_RFK, + "vdf_x[1] = %x vdf_x[0] = %x\n", + vdf_x[1] >> 21 & 0x00007ff, + vdf_x[0] >> 21 & 0x00007ff); - rtw8821a_reset_8051(rtwdev); - rtw_write8(rtwdev, REG_MCUFW_CTRL, 0x00); + tx_dt[cal] = (vdf_y[1] >> 20) - (vdf_y[0] >> 20); + tx_dt[cal] = (16 * tx_dt[cal]) * 10000 / 15708; + tx_dt[cal] = (tx_dt[cal] >> 1) + (tx_dt[cal] & BIT(0)); + + /* TX_Tone_idx[9:0], TxK_Mask[29] TX_Tone = 16 */ + rtw_write32(rtwdev, REG_OFDM0_XA_TX_IQ_IMBALANCE, + 0x18008c20); + /* RX_Tone_idx[9:0], RxK_Mask[29] */ + rtw_write32(rtwdev, REG_OFDM0_A_TX_AFE, 0x38008c20); + rtw_write32_mask(rtwdev, REG_INTPO_SETA, BIT(31), 0x1); + rtw_write32_mask(rtwdev, REG_INTPO_SETA, 0x3fff0000, + tx_dt[cal] & 0x00003fff); + break; + } - /* before BB reset should do clock gated */ - rtw_write32_set(rtwdev, REG_FPGA0_XCD_RF_PARA, BIT(6)); + rtw_write32(rtwdev, REG_RFECTL_A, 0x00100000); - /* reset BB */ - rtw_write8_clr(rtwdev, REG_SYS_FUNC_EN, BIT(0) | BIT(1)); + for (cal_retry = 0; cal_retry < 10; cal_retry++) { + /* one shot */ + rtw_write32(rtwdev, REG_IQK_COM64, 0xfa000000); + rtw_write32(rtwdev, REG_IQK_COM64, 0xf8000000); - /* reset RF */ - rtw_write8(rtwdev, REG_RF_CTRL, 0); + mdelay(10); - /* reset TRX path */ - rtw_write16(rtwdev, REG_CR, 0); + rtw_write32(rtwdev, REG_RFECTL_A, 0x00000000); - /* reset MAC, reg0x5[1], auto FSM off */ - rtw_write8_set(rtwdev, REG_APS_FSMCO + 1, APS_FSMCO_MAC_OFF >> 8); + for (delay_count = 0; delay_count < 20; delay_count++) { + iqk_ready = rtw_read32_mask(rtwdev, + REG_IQKA_END, + BIT(10)); - /* check if reg0x5[1] auto cleared */ - if (read_poll_timeout_atomic(rtw_read8, val8, - !(val8 & (APS_FSMCO_MAC_OFF >> 8)), - 1, 5000, false, - rtwdev, REG_APS_FSMCO + 1)) - rtw_err(rtwdev, "%s: timed out waiting for 0x5[1]\n", __func__); + /* Originally: if (~iqk_ready || delay_count > 20) + * that looks like a typo so make it more explicit + */ + iqk_ready = true; - /* reg0x5[0], auto FSM on */ - val8 |= APS_FSMCO_MAC_ENABLE >> 8; - rtw_write8(rtwdev, REG_APS_FSMCO + 1, val8); + if (iqk_ready) + break; - rtw_write8_clr(rtwdev, REG_SYS_FUNC_EN + 1, BIT(4) | BIT(7)); - rtw_write8_set(rtwdev, REG_SYS_FUNC_EN + 1, BIT(4) | BIT(7)); -} + mdelay(1); + } -static int rtw8812au_init_power_on(struct rtw_dev *rtwdev) -{ - const struct rtw_chip_info *chip = rtwdev->chip; - u16 val16; - int ret; - - ret = rtw_pwr_seq_parser(rtwdev, chip->pwr_on_seq); - if (ret) { - rtw_err(rtwdev, "power on flow failed\n"); - return ret; - } + if (delay_count < 20) { + /* ============TXIQK Check============== */ + tx_fail = rtw_read32_mask(rtwdev, + REG_IQKA_END, + BIT(12)); + + /* Originally: if (~tx_fail) { + * It looks like a typo, so make it more explicit. + */ + tx_fail = false; + + if (!tx_fail) { + rtw_write32(rtwdev, REG_RFECTL_A, + 0x02000000); + vdf_x[k] = rtw_read32_mask(rtwdev, + REG_IQKA_END, + 0x07ff0000); + vdf_x[k] <<= 21; + + rtw_write32(rtwdev, REG_RFECTL_A, + 0x04000000); + vdf_y[k] = rtw_read32_mask(rtwdev, + REG_IQKA_END, + 0x07ff0000); + vdf_y[k] <<= 21; + + *tx0iqkok = true; + break; + } - rtw_write16(rtwdev, REG_CR, 0); - val16 = HCI_TXDMA_EN | HCI_RXDMA_EN | TXDMA_EN | RXDMA_EN | - PROTOCOL_EN | SCHEDULE_EN | ENSEC | CALTMR_EN; - rtw_write16_set(rtwdev, REG_CR, val16); + rtw_write32_mask(rtwdev, REG_IQC_Y, + 0x000007ff, 0x0); + rtw_write32_mask(rtwdev, REG_IQC_X, + 0x000007ff, 0x200); + } - if (chip->id == RTW_CHIP_TYPE_8821A) { - if (rtw_read8(rtwdev, REG_SYS_CFG1 + 3) & BIT(0)) - rtw_write8_set(rtwdev, REG_LDO_SWR_CTRL, BIT(6)); + *tx0iqkok = false; + } } - return ret; + if (k == 3) { + tx_x0[cal] = vdf_x[k - 1]; + tx_y0[cal] = vdf_y[k - 1]; + } } -static int rtw8821a_llt_write(struct rtw_dev *rtwdev, u32 address, u32 data) +static void rtw8821a_iqk_tx_vdf_false(struct rtw_dev *rtwdev, u32 cal, + bool *tx0iqkok, + int tx_x0[CAL_NUM_8821A], + int tx_y0[CAL_NUM_8821A]) { - u32 value = BIT_LLT_WRITE_ACCESS | (address << 8) | data; - int status = 0; - int count = 0; + u32 cal_retry, delay_count, iqk_ready, tx_fail; - rtw_write32(rtwdev, REG_LLT_INIT, value); + /* TX_Tone_idx[9:0], TxK_Mask[29] TX_Tone = 16 */ + rtw_write32(rtwdev, REG_OFDM0_XA_TX_IQ_IMBALANCE, 0x18008c10); + /* RX_Tone_idx[9:0], RxK_Mask[29] */ + rtw_write32(rtwdev, REG_OFDM0_A_TX_AFE, 0x38008c10); + rtw_write32(rtwdev, REG_RFECTL_A, 0x00100000); - do { - if (!rtw_read32_mask(rtwdev, REG_LLT_INIT, BIT(31) | BIT(30))) - break; + for (cal_retry = 0; cal_retry < 10; cal_retry++) { + /* one shot */ + rtw_write32(rtwdev, REG_IQK_COM64, 0xfa000000); + rtw_write32(rtwdev, REG_IQK_COM64, 0xf8000000); - if (count > 20) { - rtw_err(rtwdev, "Failed to poll write LLT done at %d!\n", - address); - status = -EBUSY; - break; - } - } while (++count); + mdelay(10); + rtw_write32(rtwdev, REG_RFECTL_A, 0x00000000); - return status; -} + for (delay_count = 0; delay_count < 20; delay_count++) { + iqk_ready = rtw_read32_mask(rtwdev, REG_IQKA_END, BIT(10)); -static int rtw8821a_llt_init(struct rtw_dev *rtwdev, u32 boundary) -{ - u32 last_entry = 255; - int status = 0; - u32 i; + /* Originally: if (~iqk_ready || delay_count > 20) + * that looks like a typo so make it more explicit + */ + iqk_ready = true; - for (i = 0; i < boundary - 1; i++) { - status = rtw8821a_llt_write(rtwdev, i, i + 1); - if (status) - return status; - } + if (iqk_ready) + break; - status = rtw8821a_llt_write(rtwdev, boundary - 1, 0xFF); - if (status) - return status; + mdelay(1); + } - for (i = boundary; i < last_entry; i++) { - status = rtw8821a_llt_write(rtwdev, i, i + 1); - if (status) - return status; - } + if (delay_count < 20) { + /* ============TXIQK Check============== */ + tx_fail = rtw_read32_mask(rtwdev, REG_IQKA_END, BIT(12)); - status = rtw8821a_llt_write(rtwdev, last_entry, boundary); + /* Originally: if (~tx_fail) { + * It looks like a typo, so make it more explicit. + */ + tx_fail = false; - return status; -} + if (!tx_fail) { + rtw_write32(rtwdev, REG_RFECTL_A, 0x02000000); + tx_x0[cal] = rtw_read32_mask(rtwdev, REG_IQKA_END, + 0x07ff0000); + tx_x0[cal] <<= 21; -static void rtw8821au_init_queue_reserved_page(struct rtw_dev *rtwdev) -{ - const struct rtw_chip_info *chip = rtwdev->chip; - struct rtw_fifo_conf *fifo = &rtwdev->fifo; - const struct rtw_page_table *pg_tbl = NULL; - u16 pubq_num; - u32 val32; - - switch (rtw_hci_type(rtwdev)) { - case RTW_HCI_TYPE_PCIE: - pg_tbl = &chip->page_table[1]; - break; - case RTW_HCI_TYPE_USB: - if (rtwdev->hci.bulkout_num == 2) - pg_tbl = &chip->page_table[2]; - else if (rtwdev->hci.bulkout_num == 3) - pg_tbl = &chip->page_table[3]; - else if (rtwdev->hci.bulkout_num == 4) - pg_tbl = &chip->page_table[4]; - break; - case RTW_HCI_TYPE_SDIO: - pg_tbl = &chip->page_table[0]; - break; - default: - break; - } + rtw_write32(rtwdev, REG_RFECTL_A, 0x04000000); + tx_y0[cal] = rtw_read32_mask(rtwdev, REG_IQKA_END, + 0x07ff0000); + tx_y0[cal] <<= 21; - pubq_num = fifo->acq_pg_num - pg_tbl->hq_num - pg_tbl->lq_num - - pg_tbl->nq_num - pg_tbl->exq_num - pg_tbl->gapq_num; + *tx0iqkok = true; + break; + } - val32 = BIT_RQPN_NE(pg_tbl->nq_num, pg_tbl->exq_num); - rtw_write32(rtwdev, REG_RQPN_NPQ, val32); + rtw_write32_mask(rtwdev, REG_IQC_Y, 0x000007ff, 0x0); + rtw_write32_mask(rtwdev, REG_IQC_X, 0x000007ff, 0x200); + } - val32 = BIT_RQPN_HLP(pg_tbl->hq_num, pg_tbl->lq_num, pubq_num); - rtw_write32(rtwdev, REG_RQPN, val32); + *tx0iqkok = false; + } } -static void rtw8821au_init_tx_buffer_boundary(struct rtw_dev *rtwdev) +static void rtw8821a_iqk_rx(struct rtw_dev *rtwdev, u32 cal, bool *rx0iqkok, + int rx_x0[CAL_NUM_8821A], + int rx_y0[CAL_NUM_8821A]) { - struct rtw_fifo_conf *fifo = &rtwdev->fifo; + u32 cal_retry, delay_count, iqk_ready, rx_fail; - rtw_write8(rtwdev, REG_BCNQ_BDNY, fifo->rsvd_boundary); - rtw_write8(rtwdev, REG_MGQ_BDNY, fifo->rsvd_boundary); - rtw_write8(rtwdev, REG_WMAC_LBK_BF_HD, fifo->rsvd_boundary); - rtw_write8(rtwdev, REG_TRXFF_BNDY, fifo->rsvd_boundary); - rtw_write8(rtwdev, REG_DWBCN0_CTRL + 1, fifo->rsvd_boundary); -} + rtw_write32(rtwdev, REG_RFECTL_A, 0x00100000); -static int rtw8821au_init_queue_priority(struct rtw_dev *rtwdev) -{ - const struct rtw_chip_info *chip = rtwdev->chip; - u8 bulkout_num = rtwdev->hci.bulkout_num; - const struct rtw_rqpn *rqpn = NULL; - u16 txdma_pq_map; - - switch (rtw_hci_type(rtwdev)) { - case RTW_HCI_TYPE_PCIE: - rqpn = &chip->rqpn_table[1]; - break; - case RTW_HCI_TYPE_USB: - if (bulkout_num == 2) - rqpn = &chip->rqpn_table[2]; - else if (bulkout_num == 3) - rqpn = &chip->rqpn_table[3]; - else if (bulkout_num == 4) - rqpn = &chip->rqpn_table[4]; - else - return -EINVAL; - break; - case RTW_HCI_TYPE_SDIO: - rqpn = &chip->rqpn_table[0]; - break; - default: - return -EINVAL; - } + for (cal_retry = 0; cal_retry < 10; cal_retry++) { + /* one shot */ + rtw_write32(rtwdev, REG_IQK_COM64, 0xfa000000); + rtw_write32(rtwdev, REG_IQK_COM64, 0xf8000000); - rtwdev->fifo.rqpn = rqpn; + mdelay(10); - txdma_pq_map = rtw_read16(rtwdev, REG_TXDMA_PQ_MAP) & 0x7; - txdma_pq_map |= BIT_TXDMA_HIQ_MAP(rqpn->dma_map_hi); - txdma_pq_map |= BIT_TXDMA_MGQ_MAP(rqpn->dma_map_mg); - txdma_pq_map |= BIT_TXDMA_BKQ_MAP(rqpn->dma_map_bk); - txdma_pq_map |= BIT_TXDMA_BEQ_MAP(rqpn->dma_map_be); - txdma_pq_map |= BIT_TXDMA_VIQ_MAP(rqpn->dma_map_vi); - txdma_pq_map |= BIT_TXDMA_VOQ_MAP(rqpn->dma_map_vo); - rtw_write16(rtwdev, REG_TXDMA_PQ_MAP, txdma_pq_map); + rtw_write32(rtwdev, REG_RFECTL_A, 0x00000000); - /* Packet in Hi Queue Tx immediately (No constraint for ATIM Period). */ - if (rtw_hci_type(rtwdev) == RTW_HCI_TYPE_USB && bulkout_num == 4) - rtw_write8(rtwdev, REG_HIQ_NO_LMT_EN, 0xff); + for (delay_count = 0; delay_count < 20; delay_count++) { + iqk_ready = rtw_read32_mask(rtwdev, REG_IQKA_END, BIT(10)); - return 0; -} + /* Originally: if (~iqk_ready || delay_count > 20) + * that looks like a typo so make it more explicit + */ + iqk_ready = true; -static void rtw8821a_init_wmac_setting(struct rtw_dev *rtwdev) -{ - rtw_write16(rtwdev, REG_RXFLTMAP0, 0xffff); - rtw_write16(rtwdev, REG_RXFLTMAP1, 0x0400); - rtw_write16(rtwdev, REG_RXFLTMAP2, 0xffff); + if (iqk_ready) + break; - rtw_write32(rtwdev, REG_MAR, 0xffffffff); - rtw_write32(rtwdev, REG_MAR + 4, 0xffffffff); -} + mdelay(1); + } -static void rtw8821a_init_adaptive_ctrl(struct rtw_dev *rtwdev) -{ - rtw_write32_mask(rtwdev, REG_RRSR, 0xfffff, 0xffff1); - rtw_write16(rtwdev, REG_RETRY_LIMIT, 0x3030); -} + if (delay_count < 20) { + /* ============RXIQK Check============== */ + rx_fail = rtw_read32_mask(rtwdev, REG_IQKA_END, BIT(11)); + if (!rx_fail) { + rtw_write32(rtwdev, REG_RFECTL_A, 0x06000000); + rx_x0[cal] = rtw_read32_mask(rtwdev, REG_IQKA_END, + 0x07ff0000); + rx_x0[cal] <<= 21; -static void rtw8821a_init_edca(struct rtw_dev *rtwdev) -{ - rtw_write16(rtwdev, REG_SPEC_SIFS, 0x100a); - rtw_write16(rtwdev, REG_MAC_SPEC_SIFS, 0x100a); + rtw_write32(rtwdev, REG_RFECTL_A, 0x08000000); + rx_y0[cal] = rtw_read32_mask(rtwdev, REG_IQKA_END, + 0x07ff0000); + rx_y0[cal] <<= 21; - rtw_write16(rtwdev, REG_SIFS, 0x100a); - rtw_write16(rtwdev, REG_SIFS + 2, 0x100a); + *rx0iqkok = true; + break; + } - rtw_write32(rtwdev, REG_EDCA_BE_PARAM, 0x005EA42B); - rtw_write32(rtwdev, REG_EDCA_BK_PARAM, 0x0000A44F); - rtw_write32(rtwdev, REG_EDCA_VI_PARAM, 0x005EA324); - rtw_write32(rtwdev, REG_EDCA_VO_PARAM, 0x002FA226); + rtw_write32_mask(rtwdev, REG_RX_IQC_AB_A, + 0x000003ff, 0x200 >> 1); + rtw_write32_mask(rtwdev, REG_RX_IQC_AB_A, + 0x03ff0000, 0x0 >> 1); + } - rtw_write8(rtwdev, REG_USTIME_TSF, 0x50); - rtw_write8(rtwdev, REG_USTIME_EDCA, 0x50); + *rx0iqkok = false; + } } -static void rtw8821au_tx_aggregation(struct rtw_dev *rtwdev) +static void rtw8821a_iqk(struct rtw_dev *rtwdev) { - const struct rtw_chip_info *chip = rtwdev->chip; + int tx_average = 0, rx_average = 0, rx_iqk_loop = 0; + const struct rtw_efuse *efuse = &rtwdev->efuse; + int tx_x = 0, tx_y = 0, rx_x = 0, rx_y = 0; + const struct rtw_hal *hal = &rtwdev->hal; + bool tx0iqkok = false, rx0iqkok = false; + int rx_x_temp = 0, rx_y_temp = 0; + int rx_x0[2][CAL_NUM_8821A]; + int rx_y0[2][CAL_NUM_8821A]; + int tx_x0[CAL_NUM_8821A]; + int tx_y0[CAL_NUM_8821A]; + bool rx_finish1 = false; + bool rx_finish2 = false; + bool vdf_enable; + u32 cal; + int i; - rtw_write32_mask(rtwdev, REG_DWBCN0_CTRL, 0xf0, - chip->usb_tx_agg_desc_num); + rtw_dbg(rtwdev, RTW_DBG_RFK, + "band_width = %d, ext_pa = %d, ext_pa_5g = %d\n", + hal->current_band_width, efuse->ext_pa_2g, efuse->ext_pa_5g); - if (chip->id == RTW_CHIP_TYPE_8821A) - rtw_write8(rtwdev, REG_DWBCN1_CTRL, - chip->usb_tx_agg_desc_num << 1); -} + vdf_enable = hal->current_band_width == RTW_CHANNEL_WIDTH_80; -static void rtw8821a_init_beacon_parameters(struct rtw_dev *rtwdev) -{ - u16 val16; + for (cal = 0; cal < CAL_NUM_8821A; cal++) { + /* path-A LOK */ - val16 = (BIT_DIS_TSF_UDT << 8) | BIT_DIS_TSF_UDT; - if (rtwdev->efuse.btcoex) - val16 |= BIT_EN_BCN_FUNCTION; - rtw_write16(rtwdev, REG_BCN_CTRL, val16); + /* [31] = 0 --> Page C */ + rtw_write32_mask(rtwdev, REG_CCASEL, BIT(31), 0x0); - rtw_write32_mask(rtwdev, REG_TBTT_PROHIBIT, 0xfffff, WLAN_TBTT_TIME); - rtw_write8(rtwdev, REG_DRVERLYINT, 0x05); - rtw_write8(rtwdev, REG_BCNDMATIM, WLAN_BCN_DMA_TIME); - rtw_write16(rtwdev, REG_BCNTCFG, 0x4413); -} + /* ========path-A AFE all on======== */ + /* Port 0 DAC/ADC on */ + rtw_write32(rtwdev, REG_AFE_PWR1_A, 0x77777777); + rtw_write32(rtwdev, REG_AFE_PWR2_A, 0x77777777); -static void rtw8821au_init_burst_pkt_len(struct rtw_dev *rtwdev) -{ - const struct rtw_chip_info *chip = rtwdev->chip; - u8 speedvalue, provalue, temp; + rtw_write32(rtwdev, REG_RX_WAIT_CCA_TX_CCK_RFON_A, 0x19791979); - /* usb3 rx interval */ - rtw_write8(rtwdev, 0xf050, 0x01); + /* hardware 3-wire off */ + rtw_write32_mask(rtwdev, REG_3WIRE_SWA, 0xf, 0x4); - /* burst lenght=4, set 0x3400 for burst length=2 */ - rtw_write16(rtwdev, REG_RXDMA_STATUS, 0x7400); - rtw_write8(rtwdev, REG_RXDMA_STATUS + 1, 0xf5); + /* LOK setting */ - /* 0x456 = 0x70, sugguested by Zhilin */ - if (chip->id == RTW_CHIP_TYPE_8821A) - rtw_write8(rtwdev, REG_AMPDU_MAX_TIME, 0x5e); - else - rtw_write8(rtwdev, REG_AMPDU_MAX_TIME, 0x70); + /* 1. DAC/ADC sampling rate (160 MHz) */ + rtw_write32_mask(rtwdev, REG_CK_MONHA, GENMASK(26, 24), 0x7); - rtw_write32(rtwdev, REG_AMPDU_MAX_LENGTH, 0xffffffff); - rtw_write8(rtwdev, REG_USTIME_TSF, 0x50); - rtw_write8(rtwdev, REG_USTIME_EDCA, 0x50); + /* 2. LoK RF setting (at BW = 20M) */ + rtw_write_rf(rtwdev, RF_PATH_A, RF_LUTWE, RFREG_MASK, 0x80002); + rtw_write_rf(rtwdev, RF_PATH_A, RF_CFGCH, 0x00c00, 0x3); + rtw_write_rf(rtwdev, RF_PATH_A, RF_MODE_TABLE_ADDR, RFREG_MASK, + 0x20000); + rtw_write_rf(rtwdev, RF_PATH_A, RF_MODE_TABLE_DATA0, RFREG_MASK, + 0x0003f); + rtw_write_rf(rtwdev, RF_PATH_A, RF_MODE_TABLE_DATA1, RFREG_MASK, + 0xf3fc3); + + rtw_write_rf(rtwdev, RF_PATH_A, RF_TXA_PREPAD, RFREG_MASK, + 0x931d5); + rtw_write_rf(rtwdev, RF_PATH_A, RF_RXBB2, RFREG_MASK, 0x8a001); + rtw_write32(rtwdev, REG_DAC_RSTB, 0x00008000); + rtw_write32_mask(rtwdev, REG_TXAGCIDX, BIT(0), 0x1); + /* TX (X,Y) */ + rtw_write32(rtwdev, REG_IQK_COM00, 0x29002000); + /* RX (X,Y) */ + rtw_write32(rtwdev, REG_IQK_COM32, 0xa9002000); + /* [0]:AGC_en, [15]:idac_K_Mask */ + rtw_write32(rtwdev, REG_IQK_COM96, 0x00462910); - if (chip->id == RTW_CHIP_TYPE_8821A) - speedvalue = BIT(7); - else - /* check device operation speed: SS 0xff bit7 */ - speedvalue = rtw_read8(rtwdev, 0xff); - - provalue = rtw_read8(rtwdev, REG_RXDMA_MODE); - provalue |= BIT_DMA_BURST_CNT | BIT_DMA_MODE; - if (speedvalue & BIT(7)) { /* USB 2/1.1 Mode */ - temp = rtw_read8(rtwdev, 0xfe17); - if (((temp >> 4) & 0x03) == 0) - u8p_replace_bits(&provalue, BIT_DMA_BURST_SIZE_512, - BIT_DMA_BURST_SIZE); - else - u8p_replace_bits(&provalue, BIT_DMA_BURST_SIZE_64, - BIT_DMA_BURST_SIZE); - rtw_write8(rtwdev, REG_RXDMA_MODE, provalue); - } else { /* USB3 Mode */ - u8p_replace_bits(&provalue, BIT_DMA_BURST_SIZE_1024, - BIT_DMA_BURST_SIZE); - rtw_write8(rtwdev, REG_RXDMA_MODE, provalue); - - /* set Reg 0xf008[3:4] to 2'00 to disable U1/U2 Mode to avoid - * 2.5G spur in USB3.0. - */ - rtw_write8_clr(rtwdev, 0xf008, BIT(4) | BIT(3)); - } + /* [31] = 1 --> Page C1 */ + rtw_write32_mask(rtwdev, REG_CCASEL, BIT(31), 0x1); - rtw_write8_set(rtwdev, REG_SINGLE_AMPDU_CTRL, BIT_EN_SINGLE_APMDU); + if (efuse->ext_pa_5g) + rtw_write32(rtwdev, REG_OFDM0_XB_TX_IQ_IMBALANCE, + 0x821403f7); + else + rtw_write32(rtwdev, REG_OFDM0_XB_TX_IQ_IMBALANCE, + 0x821403f4); - /* for VHT packet length 11K */ - rtw_write8(rtwdev, REG_RX_PKT_LIMIT, 0x18); + if (hal->current_band_type == RTW_BAND_5G) + rtw_write32(rtwdev, REG_TSSI_TRK_SW, 0x68163e96); + else + rtw_write32(rtwdev, REG_TSSI_TRK_SW, 0x28163e96); - rtw_write8(rtwdev, REG_PIFS, 0x00); + /* TX_Tone_idx[9:0], TxK_Mask[29] TX_Tone = 16 */ + rtw_write32(rtwdev, REG_OFDM0_XA_TX_IQ_IMBALANCE, 0x18008c10); + /* RX_Tone_idx[9:0], RxK_Mask[29] */ + rtw_write32(rtwdev, REG_OFDM0_A_TX_AFE, 0x38008c10); + rtw_write32(rtwdev, REG_RFECTL_A, 0x00100000); + rtw_write32(rtwdev, REG_IQK_COM64, 0xfa000000); + rtw_write32(rtwdev, REG_IQK_COM64, 0xf8000000); - if (chip->id == RTW_CHIP_TYPE_8821A) { - /* 0x0a0a too small , it can't pass AC logo. change to 0x1f1f */ - rtw_write16(rtwdev, REG_MAX_AGGR_NUM, 0x1f1f); - rtw_write8(rtwdev, REG_FWHW_TXQ_CTRL, 0x80); - rtw_write32(rtwdev, REG_FAST_EDCA_CTRL, 0x03087777); - } else { - rtw_write16(rtwdev, REG_MAX_AGGR_NUM, 0x1f1f); - rtw_write8_clr(rtwdev, REG_FWHW_TXQ_CTRL, BIT(7)); - } - - /* to prevent mac is reseted by bus. */ - rtw_write8_set(rtwdev, REG_RSV_CTRL, BIT(5) | BIT(6)); - - /* ARFB table 9 for 11ac 5G 2SS */ - rtw_write32(rtwdev, REG_ARFR0, 0x00000010); - rtw_write32(rtwdev, REG_ARFRH0, 0xfffff000); - - /* ARFB table 10 for 11ac 5G 1SS */ - rtw_write32(rtwdev, REG_ARFR1_V1, 0x00000010); - rtw_write32(rtwdev, REG_ARFRH1_V1, 0x003ff000); - - /* ARFB table 11 for 11ac 24G 1SS */ - rtw_write32(rtwdev, REG_ARFR2_V1, 0x00000015); - rtw_write32(rtwdev, REG_ARFRH2_V1, 0x003ff000); - - /* ARFB table 12 for 11ac 24G 2SS */ - rtw_write32(rtwdev, REG_ARFR3_V1, 0x00000015); - rtw_write32(rtwdev, REG_ARFRH3_V1, 0xffcff000); -} - -static void rtw8821a_phy_bb_config(struct rtw_dev *rtwdev) -{ - u8 val8, crystal_cap; - - /* power on BB/RF domain */ - val8 = rtw_read8(rtwdev, REG_SYS_FUNC_EN); - val8 |= BIT_FEN_USBA; - rtw_write8(rtwdev, REG_SYS_FUNC_EN, val8); - - /* toggle BB reset */ - val8 |= BIT_FEN_BB_RSTB | BIT_FEN_BB_GLB_RST; - rtw_write8(rtwdev, REG_SYS_FUNC_EN, val8); - - rtw_write8(rtwdev, REG_RF_CTRL, - BIT_RF_EN | BIT_RF_RSTB | BIT_RF_SDM_RSTB); - rtw_write8(rtwdev, REG_RF_B_CTRL, - BIT_RF_EN | BIT_RF_RSTB | BIT_RF_SDM_RSTB); - - rtw_load_table(rtwdev, rtwdev->chip->bb_tbl); - rtw_load_table(rtwdev, rtwdev->chip->agc_tbl); - - crystal_cap = rtwdev->efuse.crystal_cap & 0x3F; - if (rtwdev->chip->id == RTW_CHIP_TYPE_8812A) - rtw_write32_mask(rtwdev, REG_AFE_CTRL3, 0x7FF80000, - crystal_cap | (crystal_cap << 6)); - else - rtw_write32_mask(rtwdev, REG_AFE_CTRL3, 0x00FFF000, - crystal_cap | (crystal_cap << 6)); -} - -static void rtw8821a_phy_rf_config(struct rtw_dev *rtwdev) -{ - u8 rf_path; - - for (rf_path = 0; rf_path < rtwdev->hal.rf_path_num; rf_path++) - rtw_load_table(rtwdev, rtwdev->chip->rf_tbl[rf_path]); -} - -static void rtw8812a_config_1t(struct rtw_dev *rtwdev) -{ - /* BB OFDM RX Path_A */ - rtw_write32_mask(rtwdev, REG_RXPSEL, 0xff, 0x11); - - /* BB OFDM TX Path_A */ - rtw_write32_mask(rtwdev, REG_TXPSEL, MASKLWORD, 0x1111); - - /* BB CCK R/Rx Path_A */ - rtw_write32_mask(rtwdev, REG_CCK_RX, 0x0c000000, 0x0); - - /* MCS support */ - rtw_write32_mask(rtwdev, 0x8bc, 0xc0000060, 0x4); - - /* RF Path_B HSSI OFF */ - rtw_write32_mask(rtwdev, 0xe00, 0xf, 0x4); - - /* RF Path_B Power Down */ - rtw_write32_mask(rtwdev, REG_LSSI_WRITE_B, MASKDWORD, 0); - - /* ADDA Path_B OFF */ - rtw_write32_mask(rtwdev, REG_AFE_PWR1_B, MASKDWORD, 0); - rtw_write32_mask(rtwdev, REG_AFE_PWR2_B, MASKDWORD, 0); -} - -static const u32 rtw8821a_txscale_tbl[] = { - 0x081, 0x088, 0x090, 0x099, 0x0a2, 0x0ac, 0x0b6, 0x0c0, 0x0cc, 0x0d8, - 0x0e5, 0x0f2, 0x101, 0x110, 0x120, 0x131, 0x143, 0x156, 0x16a, 0x180, - 0x197, 0x1af, 0x1c8, 0x1e3, 0x200, 0x21e, 0x23e, 0x261, 0x285, 0x2ab, - 0x2d3, 0x2fe, 0x32b, 0x35c, 0x38e, 0x3c4, 0x3fe -}; - -static u32 rtw8821a_get_bb_swing(struct rtw_dev *rtwdev, u8 band, u8 path) -{ - static const u32 swing2setting[4] = {0x200, 0x16a, 0x101, 0x0b6}; - struct rtw_efuse efuse = rtwdev->efuse; - u8 tx_bb_swing; - - if (band == RTW_BAND_2G) - tx_bb_swing = efuse.tx_bb_swing_setting_2g; - else - tx_bb_swing = efuse.tx_bb_swing_setting_5g; - - if (path == RF_PATH_B) - tx_bb_swing >>= 2; - tx_bb_swing &= 0x3; - - return swing2setting[tx_bb_swing]; -} - -static u8 rtw8821a_get_swing_index(struct rtw_dev *rtwdev) -{ - u32 swing, table_value; - u8 i = 0; - - swing = rtw8821a_get_bb_swing(rtwdev, rtwdev->hal.current_band_type, - RF_PATH_A); - - for (i = 0; i < ARRAY_SIZE(rtw8821a_txscale_tbl); i++) { - table_value = rtw8821a_txscale_tbl[i]; - if (swing == table_value) - break; - } - - return i; -} - -static void rtw8821a_pwrtrack_init(struct rtw_dev *rtwdev) -{ - struct rtw_dm_info *dm_info = &rtwdev->dm_info; - u8 ofdm_swing_idx; - u8 path; - - ofdm_swing_idx = rtw8821a_get_swing_index(rtwdev); - - if (ofdm_swing_idx >= ARRAY_SIZE(rtw8821a_txscale_tbl)) - dm_info->default_ofdm_index = 24; - else - dm_info->default_ofdm_index = ofdm_swing_idx; - - if (rtwdev->chip->id == RTW_CHIP_TYPE_8821A) - dm_info->default_cck_index = 0; - else - dm_info->default_cck_index = 24; - - for (path = RF_PATH_A; path < rtwdev->hal.rf_path_num; path++) { - ewma_thermal_init(&dm_info->avg_thermal[path]); - dm_info->delta_power_index[path] = 0; - dm_info->delta_power_index_last[path] = 0; - } - - dm_info->pwr_trk_triggered = false; - dm_info->pwr_trk_init_trigger = true; - dm_info->thermal_meter_k = rtwdev->efuse.thermal_meter_k; -} - -static void rtw8821a_power_off(struct rtw_dev *rtwdev) -{ - struct rtw_usb *rtwusb = rtw_get_usb_priv(rtwdev); - enum usb_device_speed speed = rtwusb->udev->speed; - u16 ori_fsmc0; - u8 reg_cr; - - reg_cr = rtw_read8(rtwdev, REG_CR); - - /* Already powered off */ - if (reg_cr == 0 || reg_cr == 0xEA) - return; - - rtw_hci_stop(rtwdev); - - if (!rtwdev->efuse.btcoex) - rtw_write16_clr(rtwdev, REG_GPIO_MUXCFG, BIT_EN_SIC); - - /* set Reg 0xf008[3:4] to 2'11 to enable U1/U2 Mode in USB3.0. */ - if (speed == USB_SPEED_SUPER) - rtw_write8_set(rtwdev, 0xf008, 0x18); - - rtw_write32(rtwdev, REG_HISR0, 0xffffffff); - rtw_write32(rtwdev, REG_HISR1, 0xffffffff); - rtw_write32(rtwdev, REG_HIMR0, 0); - rtw_write32(rtwdev, REG_HIMR1, 0); - - if (rtwdev->efuse.btcoex) - rtw_coex_power_off_setting(rtwdev); - - ori_fsmc0 = rtw_read16(rtwdev, REG_APS_FSMCO); - rtw_write16(rtwdev, REG_APS_FSMCO, ori_fsmc0 & ~APS_FSMCO_HW_POWERDOWN); - - /* Stop Tx Report Timer. */ - rtw_write8_clr(rtwdev, REG_TX_RPT_CTRL, BIT(1)); - - /* Stop Rx */ - rtw_write8(rtwdev, REG_CR, 0); - - if (rtwdev->chip->id == RTW_CHIP_TYPE_8821A) - rtw_pwr_seq_parser(rtwdev, enter_lps_flow_8821a); - else - rtw_pwr_seq_parser(rtwdev, enter_lps_flow_8812a); - - if (rtw_read8(rtwdev, REG_MCUFW_CTRL) & BIT_RAM_DL_SEL) - rtw8821a_reset_8051(rtwdev); - - rtw_write8_clr(rtwdev, REG_SYS_FUNC_EN + 1, BIT(2)); - rtw_write8(rtwdev, REG_MCUFW_CTRL, 0); - - rtw_pwr_seq_parser(rtwdev, rtwdev->chip->pwr_off_seq); - - if (ori_fsmc0 & APS_FSMCO_HW_POWERDOWN) - rtw_write16_set(rtwdev, REG_APS_FSMCO, APS_FSMCO_HW_POWERDOWN); - - clear_bit(RTW_FLAG_POWERON, rtwdev->flags); -} - -///TODO: chip identification needs to be copied as well - -static void rtw8821a_set_channel_bb_swing(struct rtw_dev *rtwdev, u8 band) -{ - rtw_write32_mask(rtwdev, REG_TXSCALE_A, BB_SWING_MASK, - rtw8821a_get_bb_swing(rtwdev, band, RF_PATH_A)); - rtw_write32_mask(rtwdev, REG_TXSCALE_B, BB_SWING_MASK, - rtw8821a_get_bb_swing(rtwdev, band, RF_PATH_B)); - rtw8821a_pwrtrack_init(rtwdev); -} - -static void rtw8821a_set_ext_band_switch(struct rtw_dev *rtwdev, u8 band) -{ - rtw_write32_mask(rtwdev, REG_LED_CFG, BIT_DPDT_SEL_EN, 0); - rtw_write32_mask(rtwdev, REG_LED_CFG, BIT_DPDT_WL_SEL, 1); - rtw_write32_mask(rtwdev, REG_RFE_INV_A, 0xf, 7); - rtw_write32_mask(rtwdev, REG_RFE_INV_A, 0xf0, 7); - - if (band == RTW_BAND_2G) - rtw_write32_mask(rtwdev, REG_RFE_INV_A, BIT(29) | BIT(28), 1); - else - rtw_write32_mask(rtwdev, REG_RFE_INV_A, BIT(29) | BIT(28), 2); -} - -static void rtw8821a_phy_set_rfe_reg_24g(struct rtw_dev *rtwdev) -{ - struct rtw_efuse *efuse = &rtwdev->efuse; - - /* Turn off RF PA and LNA */ - - /* 0xCB0[15:12] = 0x7 (LNA_On)*/ - rtw_write32_mask(rtwdev, REG_RFE_PINMUX_A, 0xF000, 0x7); - /* 0xCB0[7:4] = 0x7 (PAPE_A)*/ - rtw_write32_mask(rtwdev, REG_RFE_PINMUX_A, 0xF0, 0x7); - - if (efuse->ext_lna_2g) { - /* Turn on 2.4G External LNA */ - rtw_write32_mask(rtwdev, REG_RFE_INV_A, BIT(20), 1); - rtw_write32_mask(rtwdev, REG_RFE_INV_A, BIT(22), 0); - rtw_write32_mask(rtwdev, REG_RFE_PINMUX_A, GENMASK(2, 0), 0x2); - rtw_write32_mask(rtwdev, REG_RFE_PINMUX_A, GENMASK(10, 8), 0x2); - } else { - /* Bypass 2.4G External LNA */ - rtw_write32_mask(rtwdev, REG_RFE_INV_A, BIT(20), 0); - rtw_write32_mask(rtwdev, REG_RFE_INV_A, BIT(22), 0); - rtw_write32_mask(rtwdev, REG_RFE_PINMUX_A, GENMASK(2, 0), 0x7); - rtw_write32_mask(rtwdev, REG_RFE_PINMUX_A, GENMASK(10, 8), 0x7); - } -} - -static void rtw8821a_phy_set_rfe_reg_5g(struct rtw_dev *rtwdev) -{ - /* Turn ON RF PA and LNA */ - - /* 0xCB0[15:12] = 0x7 (LNA_On)*/ - rtw_write32_mask(rtwdev, REG_RFE_PINMUX_A, 0xF000, 0x5); - /* 0xCB0[7:4] = 0x7 (PAPE_A)*/ - rtw_write32_mask(rtwdev, REG_RFE_PINMUX_A, 0xF0, 0x4); - - /* Bypass 2.4G External LNA */ - rtw_write32_mask(rtwdev, REG_RFE_INV_A, BIT(20), 0); - rtw_write32_mask(rtwdev, REG_RFE_INV_A, BIT(22), 0); - rtw_write32_mask(rtwdev, REG_RFE_PINMUX_A, GENMASK(2, 0), 0x7); - rtw_write32_mask(rtwdev, REG_RFE_PINMUX_A, GENMASK(10, 8), 0x7); -} - -static void rtw8812a_phy_set_rfe_reg_24g(struct rtw_dev *rtwdev) -{ - switch (rtwdev->efuse.rfe_option) { - case 0: - case 2: - rtw_write32(rtwdev, REG_RFE_PINMUX_A, 0x77777777); - rtw_write32(rtwdev, REG_RFE_PINMUX_B, 0x77777777); - rtw_write32_mask(rtwdev, REG_RFE_INV_A, RFE_INV_MASK, 0x000); - rtw_write32_mask(rtwdev, REG_RFE_INV_B, RFE_INV_MASK, 0x000); - break; - case 1: - if (rtwdev->efuse.btcoex) { - rtw_write32_mask(rtwdev, REG_RFE_PINMUX_A, 0xffffff, 0x777777); - rtw_write32(rtwdev, REG_RFE_PINMUX_B, 0x77777777); - rtw_write32_mask(rtwdev, REG_RFE_INV_A, 0x33f00000, 0x000); - rtw_write32_mask(rtwdev, REG_RFE_INV_B, RFE_INV_MASK, 0x000); - } else { - rtw_write32(rtwdev, REG_RFE_PINMUX_A, 0x77777777); - rtw_write32(rtwdev, REG_RFE_PINMUX_B, 0x77777777); - rtw_write32_mask(rtwdev, REG_RFE_INV_A, RFE_INV_MASK, 0x000); - rtw_write32_mask(rtwdev, REG_RFE_INV_B, RFE_INV_MASK, 0x000); - } - break; - case 3: - rtw_write32(rtwdev, REG_RFE_PINMUX_A, 0x54337770); - rtw_write32(rtwdev, REG_RFE_PINMUX_B, 0x54337770); - rtw_write32_mask(rtwdev, REG_RFE_INV_A, RFE_INV_MASK, 0x010); - rtw_write32_mask(rtwdev, REG_RFE_INV_B, RFE_INV_MASK, 0x010); - rtw_write32_mask(rtwdev, REG_ANTSEL_SW, 0x00000303, 0x1); - break; - case 4: - rtw_write32(rtwdev, REG_RFE_PINMUX_A, 0x77777777); - rtw_write32(rtwdev, REG_RFE_PINMUX_B, 0x77777777); - rtw_write32_mask(rtwdev, REG_RFE_INV_A, RFE_INV_MASK, 0x001); - rtw_write32_mask(rtwdev, REG_RFE_INV_B, RFE_INV_MASK, 0x001); - break; - case 5: - rtw_write8(rtwdev, REG_RFE_PINMUX_A + 2, 0x77); - rtw_write32(rtwdev, REG_RFE_PINMUX_B, 0x77777777); - rtw_write8_clr(rtwdev, REG_RFE_INV_A + 3, BIT(0)); - rtw_write32_mask(rtwdev, REG_RFE_INV_B, RFE_INV_MASK, 0x000); - break; - case 6: - rtw_write32(rtwdev, REG_RFE_PINMUX_A, 0x07772770); - rtw_write32(rtwdev, REG_RFE_PINMUX_B, 0x07772770); - rtw_write32(rtwdev, REG_RFE_INV_A, 0x00000077); - rtw_write32(rtwdev, REG_RFE_INV_B, 0x00000077); - break; - default: - break; - } -} - -static void rtw8812a_phy_set_rfe_reg_5g(struct rtw_dev *rtwdev) -{ - switch (rtwdev->efuse.rfe_option) { - case 0: - rtw_write32(rtwdev, REG_RFE_PINMUX_A, 0x77337717); - rtw_write32(rtwdev, REG_RFE_PINMUX_B, 0x77337717); - rtw_write32_mask(rtwdev, REG_RFE_INV_A, RFE_INV_MASK, 0x010); - rtw_write32_mask(rtwdev, REG_RFE_INV_B, RFE_INV_MASK, 0x010); - break; - case 1: - if (rtwdev->efuse.btcoex) { - rtw_write32_mask(rtwdev, REG_RFE_PINMUX_A, 0xffffff, 0x337717); - rtw_write32(rtwdev, REG_RFE_PINMUX_B, 0x77337717); - rtw_write32_mask(rtwdev, REG_RFE_INV_A, 0x33f00000, 0x000); - rtw_write32_mask(rtwdev, REG_RFE_INV_B, RFE_INV_MASK, 0x000); - } else { - rtw_write32(rtwdev, REG_RFE_PINMUX_A, 0x77337717); - rtw_write32(rtwdev, REG_RFE_PINMUX_B, 0x77337717); - rtw_write32_mask(rtwdev, REG_RFE_INV_A, RFE_INV_MASK, 0x000); - rtw_write32_mask(rtwdev, REG_RFE_INV_B, RFE_INV_MASK, 0x000); - } - break; - case 2: - case 4: - rtw_write32(rtwdev, REG_RFE_PINMUX_A, 0x77337777); - rtw_write32(rtwdev, REG_RFE_PINMUX_B, 0x77337777); - rtw_write32_mask(rtwdev, REG_RFE_INV_A, RFE_INV_MASK, 0x010); - rtw_write32_mask(rtwdev, REG_RFE_INV_B, RFE_INV_MASK, 0x010); - break; - case 3: - rtw_write32(rtwdev, REG_RFE_PINMUX_A, 0x54337717); - rtw_write32(rtwdev, REG_RFE_PINMUX_B, 0x54337717); - rtw_write32_mask(rtwdev, REG_RFE_INV_A, RFE_INV_MASK, 0x010); - rtw_write32_mask(rtwdev, REG_RFE_INV_B, RFE_INV_MASK, 0x010); - rtw_write32_mask(rtwdev, REG_ANTSEL_SW, 0x00000303, 0x1); - break; - case 5: - rtw_write8(rtwdev, REG_RFE_PINMUX_A + 2, 0x33); - rtw_write32(rtwdev, REG_RFE_PINMUX_B, 0x77337777); - rtw_write8_set(rtwdev, REG_RFE_INV_A + 3, BIT(0)); - rtw_write32_mask(rtwdev, REG_RFE_INV_B, RFE_INV_MASK, 0x010); - break; - case 6: - rtw_write32(rtwdev, REG_RFE_PINMUX_A, 0x07737717); - rtw_write32(rtwdev, REG_RFE_PINMUX_B, 0x07737717); - rtw_write32(rtwdev, REG_RFE_INV_A, 0x00000077); - rtw_write32(rtwdev, REG_RFE_INV_B, 0x00000077); - break; - default: - break; - } -} - -static void rtw8821a_switch_band(struct rtw_dev *rtwdev, u8 new_band, u8 bw) -{ - const struct rtw_chip_info *chip = rtwdev->chip; - u16 basic_rates, reg_41a; - - /* 8811au one antenna module doesn't support antenna div, so driver must - * control antenna band, otherwise one of the band will have issue - */ - if (chip->id == RTW_CHIP_TYPE_8821A && !rtwdev->efuse.btcoex && - rtwdev->efuse.ant_div_cfg == 0) - rtw8821a_set_ext_band_switch(rtwdev, new_band); - - if (new_band == RTW_BAND_2G) { - rtw_write32_set(rtwdev, REG_RXPSEL, BIT_RX_PSEL_RST); - - if (chip->id == RTW_CHIP_TYPE_8821A) { - rtw8821a_phy_set_rfe_reg_24g(rtwdev); - - rtw_write32_mask(rtwdev, REG_TXSCALE_A, 0xf00, 0); - } else { - rtw_write32_mask(rtwdev, REG_BWINDICATION, 0x3, 0x1); - rtw_write32_mask(rtwdev, REG_PDMFTH, GENMASK(17, 13), 0x17); - - if (bw == RTW_CHANNEL_WIDTH_20 && - rtwdev->hal.rf_type == RF_1T1R && - !rtwdev->efuse.ext_lna_2g) - rtw_write32_mask(rtwdev, REG_PDMFTH, GENMASK(3, 1), 0x02); - else - rtw_write32_mask(rtwdev, REG_PDMFTH, GENMASK(3, 1), 0x04); - - rtw_write32_mask(rtwdev, REG_CCASEL, 0x3, 0); - - rtw8812a_phy_set_rfe_reg_24g(rtwdev); - } - - rtw_write32_mask(rtwdev, REG_TXPSEL, 0xf0, 0x1); - rtw_write32_mask(rtwdev, REG_CCK_RX, 0x0f000000, 0x1); - - basic_rates = BIT(DESC_RATE1M) | BIT(DESC_RATE2M) | - BIT(DESC_RATE5_5M) | BIT(DESC_RATE11M) | - BIT(DESC_RATE6M) | BIT(DESC_RATE12M) | - BIT(DESC_RATE24M); - rtw_write32_mask(rtwdev, REG_RRSR, 0xfffff, basic_rates); - - rtw_write8_clr(rtwdev, REG_CCK_CHECK, BIT_CHECK_CCK_EN); - } else { /* RTW_BAND_5G */ - if (chip->id == RTW_CHIP_TYPE_8821A) - rtw8821a_phy_set_rfe_reg_5g(rtwdev); - - rtw_write8_set(rtwdev, REG_CCK_CHECK, BIT_CHECK_CCK_EN); - - read_poll_timeout_atomic(rtw_read16, reg_41a, (reg_41a & 0x30) == 0x30, - 50, 2500, false, rtwdev, REG_TXPKT_EMPTY); - - rtw_write32_set(rtwdev, REG_RXPSEL, BIT_RX_PSEL_RST); - - if (chip->id == RTW_CHIP_TYPE_8821A) { - rtw_write32_mask(rtwdev, REG_TXSCALE_A, 0xf00, 1); - } else { - rtw_write32_mask(rtwdev, REG_BWINDICATION, 0x3, 0x2); - rtw_write32_mask(rtwdev, REG_PDMFTH, GENMASK(17, 13), 0x15); - rtw_write32_mask(rtwdev, REG_PDMFTH, GENMASK(3, 1), 0x04); - - rtw_write32_mask(rtwdev, REG_CCASEL, 0x3, 1); - - rtw8812a_phy_set_rfe_reg_5g(rtwdev); - } - - rtw_write32_mask(rtwdev, REG_TXPSEL, 0xf0, 0); - rtw_write32_mask(rtwdev, REG_CCK_RX, 0x0f000000, 0xf); - - basic_rates = BIT(DESC_RATE6M) | BIT(DESC_RATE12M) | - BIT(DESC_RATE24M); - rtw_write32_mask(rtwdev, REG_RRSR, 0xfffff, basic_rates); - } - - rtw8821a_set_channel_bb_swing(rtwdev, new_band); -} - -static int rtw8821a_power_on(struct rtw_dev *rtwdev) -{ - const struct rtw_chip_info *chip = rtwdev->chip; - struct rtw_efuse *efuse = &rtwdev->efuse; - struct rtw_hal *hal = &rtwdev->hal; - int ret; - - if (test_bit(RTW_FLAG_POWERON, rtwdev->flags)) - return 0; - - /* Override rtw_chip_efuse_info_setup() */ - if (chip->id == RTW_CHIP_TYPE_8821A) - efuse->btcoex = rtw_read32_mask(rtwdev, REG_WL_BT_PWR_CTRL, - BIT_BT_FUNC_EN); - - /* Override rtw_chip_efuse_info_setup() */ - if (chip->id == RTW_CHIP_TYPE_8812A) - rtw8812a_read_amplifier_type(rtwdev); - - ret = rtw_hci_setup(rtwdev); - if (ret) { - rtw_err(rtwdev, "failed to setup hci\n"); - goto err; - } - - /* Revise for U2/U3 switch we can not update RF-A/B reset. - * Reset after MAC power on to prevent RF R/W error. - * Is it a right method? - */ - if (chip->id == RTW_CHIP_TYPE_8812A) { - rtw_write8(rtwdev, REG_RF_CTRL, 5); - rtw_write8(rtwdev, REG_RF_CTRL, 7); - rtw_write8(rtwdev, REG_RF_B_CTRL, 5); - rtw_write8(rtwdev, REG_RF_B_CTRL, 7); - } - - /* If HW didn't go through a complete de-initial procedure, - * it probably occurs some problem for double initial - * procedure. - */ - rtw8812au_hw_reset(rtwdev); - - ret = rtw8812au_init_power_on(rtwdev); - if (ret) { - rtw_err(rtwdev, "failed to power on\n"); - goto err; - } - - ret = rtw_set_trx_fifo_info(rtwdev); - if (ret) { - rtw_err(rtwdev, "failed to set trx fifo info\n"); - goto err; - } - - ret = rtw8821a_llt_init(rtwdev, rtwdev->fifo.rsvd_boundary); - if (ret) { - rtw_err(rtwdev, "failed to init llt\n"); - goto err; - } - - rtw_write32_set(rtwdev, REG_TXDMA_OFFSET_CHK, BIT_DROP_DATA_EN); - - ret = rtw_wait_firmware_completion(rtwdev); - if (ret) { - rtw_err(rtwdev, "failed to wait firmware completion\n"); - goto err_off; - } - - ret = rtw_download_firmware(rtwdev, &rtwdev->fw); - if (ret) { - rtw_err(rtwdev, "failed to download firmware\n"); - goto err_off; - } - - rtw_write8(rtwdev, REG_HMETFR, 0xf); - - rtw_load_table(rtwdev, chip->mac_tbl); - - rtw8821au_init_queue_reserved_page(rtwdev); - rtw8821au_init_tx_buffer_boundary(rtwdev); - rtw8821au_init_queue_priority(rtwdev); - - rtw_write16(rtwdev, REG_TRXFF_BNDY + 2, - chip->rxff_size - REPORT_BUF - 1); - - if (chip->id == RTW_CHIP_TYPE_8812A) - rtw_write8(rtwdev, REG_PBP, - u8_encode_bits(PBP_512, PBP_TX_MASK) | - u8_encode_bits(PBP_64, PBP_RX_MASK)); - - rtw_write8(rtwdev, REG_RX_DRVINFO_SZ, PHY_STATUS_SIZE); - - rtw_write32(rtwdev, REG_HIMR0, 0); - rtw_write32(rtwdev, REG_HIMR1, 0); - - rtw_write32_mask(rtwdev, REG_CR, 0x30000, 0x2); - - rtw8821a_init_wmac_setting(rtwdev); - rtw8821a_init_adaptive_ctrl(rtwdev); - rtw8821a_init_edca(rtwdev); - - rtw_write8_set(rtwdev, REG_FWHW_TXQ_CTRL, BIT(7)); - rtw_write8(rtwdev, REG_ACKTO, 0x80); - - rtw8821au_tx_aggregation(rtwdev); - - rtw8821a_init_beacon_parameters(rtwdev); - rtw_write8(rtwdev, REG_BCN_MAX_ERR, 0xff); - - if (rtwdev->hci.type == RTW_HCI_TYPE_USB) - rtw8821au_init_burst_pkt_len(rtwdev); - - rtw_write8_set(rtwdev, REG_CR, MACTXEN | MACRXEN); - - ///TODO: blinking controlled by mac80211 - if (rtwdev->chip->id == RTW_CHIP_TYPE_8821A) - rtw_write8(rtwdev, REG_LED_CFG + 2, BIT(1) | BIT(5)); - else - rtw_write8(rtwdev, REG_LED_CFG, BIT(1) | BIT(5)); - - rtw8821a_phy_bb_config(rtwdev); - rtw8821a_phy_rf_config(rtwdev); - - if (chip->id == RTW_CHIP_TYPE_8812A && hal->rf_path_num == 1) - rtw8812a_config_1t(rtwdev); - - rtw8821a_switch_band(rtwdev, RTW_BAND_2G, RTW_CHANNEL_WIDTH_20); - - rtw_write32(rtwdev, RTW_SEC_CMD_REG, BIT(31) | BIT(30)); - - rtw_write8(rtwdev, REG_HWSEQ_CTRL, 0xff); - rtw_write32(rtwdev, REG_BAR_MODE_CTRL, 0x0201ffff); - rtw_write8(rtwdev, REG_NAV_CTRL + 2, 0); - - rtw_write8_clr(rtwdev, REG_GPIO_MUXCFG, BIT(5)); - - rtw_phy_init(rtwdev); - - rtw8821a_pwrtrack_init(rtwdev); - - /* 0x4c6[3] 1: RTS BW = Data BW - * 0: RTS BW depends on CCA / secondary CCA result. - */ - rtw_write8_clr(rtwdev, REG_QUEUE_CTRL, BIT(3)); - - /* enable Tx report. */ - rtw_write8(rtwdev, REG_FWHW_TXQ_CTRL + 1, 0x0f); - - /* Pretx_en, for WEP/TKIP SEC */ - rtw_write8(rtwdev, REG_EARLY_MODE_CONTROL + 3, 0x01); - - rtw_write16(rtwdev, REG_TX_RPT_TIME, 0x3df0); - - /* Reset USB mode switch setting */ - rtw_write8(rtwdev, REG_SYS_SDIO_CTRL, 0x0); - rtw_write8(rtwdev, REG_ACLK_MON, 0x0); - - rtw_write8(rtwdev, REG_USB_HRPWM, 0); - - /* ack for xmit mgmt frames. */ - rtw_write32_set(rtwdev, REG_FWHW_TXQ_CTRL, BIT(12)); - - hal->cck_high_power = rtw_read32_mask(rtwdev, REG_CCK_RPT_FORMAT, - BIT_CCK_RPT_FORMAT); - - ret = rtw_hci_start(rtwdev); - if (ret) { - rtw_err(rtwdev, "failed to start hci\n"); - goto err_off; - } - - if (efuse->btcoex) { - rtw_coex_power_on_setting(rtwdev); - rtw_coex_init_hw_config(rtwdev, false); - } - - set_bit(RTW_FLAG_POWERON, rtwdev->flags); - - return 0; - -err_off: - rtw8821a_power_off(rtwdev); - -err: - return ret; -} - -static u32 rtw8821a_phy_read_rf(struct rtw_dev *rtwdev, - enum rtw_rf_path rf_path, u32 addr, u32 mask) -{ - static const u32 pi_addr[2] = { 0xc00, 0xe00 }; - static const u32 read_addr[2][2] = { - { REG_SI_READ_A, REG_SI_READ_B }, - { REG_PI_READ_A, REG_PI_READ_B } - }; - const struct rtw_chip_info *chip = rtwdev->chip; - const struct rtw_hal *hal = &rtwdev->hal; - bool set_cca, pi_mode; - u32 val; - - if (rf_path >= hal->rf_phy_num) { - rtw_err(rtwdev, "unsupported rf path (%d)\n", rf_path); - return INV_RF_DATA; - } - - /* CCA off to avoid reading the wrong value. - * Toggling CCA would affect RF 0x0, skip it. - */ - set_cca = addr != 0x0 && chip->id == RTW_CHIP_TYPE_8812A && - hal->cut_version != RTW_CHIP_VER_CUT_C; - - if (set_cca) - rtw_write32_set(rtwdev, REG_CCA2ND, BIT(3)); - - addr &= 0xff; - - pi_mode = rtw_read32_mask(rtwdev, pi_addr[rf_path], 0x4); - - rtw_write32_mask(rtwdev, REG_HSSI_READ, MASKBYTE0, addr); - - if (chip->id == RTW_CHIP_TYPE_8821A || - hal->cut_version == RTW_CHIP_VER_CUT_C) - udelay(20); - - val = rtw_read32_mask(rtwdev, read_addr[pi_mode][rf_path], mask); - - /* CCA on */ - if (set_cca) - rtw_write32_clr(rtwdev, REG_CCA2ND, BIT(3)); - - return val; -} - -static void rtw8821a_cfg_ldo25(struct rtw_dev *rtwdev, bool enable) -{ - /* Nothing to do. */ -} - -static void rtw8812a_phy_fix_spur(struct rtw_dev *rtwdev, u8 channel, u8 bw) -{ - /* C cut Item12 ADC FIFO CLOCK */ - if (rtwdev->hal.cut_version == RTW_CHIP_VER_CUT_C) { - if (bw == RTW_CHANNEL_WIDTH_40 && channel == 11) - rtw_write32_mask(rtwdev, REG_ADCCLK, 0xC00, 0x3); - else - rtw_write32_mask(rtwdev, REG_ADCCLK, 0xC00, 0x2); - - /* A workarould to resolve 2480Mhz spur by setting ADC clock - * as 160M. - */ - if (bw == RTW_CHANNEL_WIDTH_20 && (channel == 13 || channel == 14)) { - rtw_write32_mask(rtwdev, REG_ADCCLK, 0x300, 0x3); - rtw_write32_mask(rtwdev, REG_ADC160, BIT(30), 1); - } else if (bw == RTW_CHANNEL_WIDTH_40 && channel == 11) { - rtw_write32_mask(rtwdev, REG_ADC160, BIT(30), 1); - } else if (bw != RTW_CHANNEL_WIDTH_80) { - rtw_write32_mask(rtwdev, REG_ADCCLK, 0x300, 0x2); - rtw_write32_mask(rtwdev, REG_ADC160, BIT(30), 0); - } - } else { - /* A workarould to resolve 2480Mhz spur by setting ADC clock - * as 160M. - */ - if (bw == RTW_CHANNEL_WIDTH_20 && (channel == 13 || channel == 14)) - rtw_write32_mask(rtwdev, REG_ADCCLK, 0x300, 0x3); - else if (channel <= 14) /* 2.4G only */ - rtw_write32_mask(rtwdev, REG_ADCCLK, 0x300, 0x2); - } -} - -static void rtw8821a_switch_channel(struct rtw_dev *rtwdev, u8 channel, u8 bw) -{ - struct rtw_hal *hal = &rtwdev->hal; - u32 fc_area, rf_mod_ag; - u8 path; - - switch (channel) { - case 36 ... 48: - fc_area = 0x494; - break; - case 50 ... 64: - fc_area = 0x453; - break; - case 100 ... 116: - fc_area = 0x452; - break; - default: - if (channel >= 118) - fc_area = 0x412; - else - fc_area = 0x96a; - break; - } - - rtw_write32_mask(rtwdev, REG_CLKTRK, 0x1ffe0000, fc_area); - - for (path = 0; path < hal->rf_path_num; path++) { - switch (channel) { - case 36 ... 64: - rf_mod_ag = 0x101; - break; - case 100 ... 140: - rf_mod_ag = 0x301; - break; - default: - if (channel > 140) - rf_mod_ag = 0x501; - else - rf_mod_ag = 0x000; - break; - } - - rtw_write_rf(rtwdev, path, 0x18, - RF18_RFSI_MASK | RF18_BAND_MASK, rf_mod_ag); - - if (rtwdev->chip->id == RTW_CHIP_TYPE_8812A) - rtw8812a_phy_fix_spur(rtwdev, channel, bw); - - rtw_write_rf(rtwdev, path, 0x18, RF18_CHANNEL_MASK, channel); - } -} - -static void rtw8821a_set_reg_bw(struct rtw_dev *rtwdev, u8 bw) -{ - u16 val16 = rtw_read16(rtwdev, REG_WMAC_TRXPTCL_CTL); - - val16 &= ~BIT_RFMOD; - if (bw == RTW_CHANNEL_WIDTH_80) - val16 |= BIT_RFMOD_80M; - else if (bw == RTW_CHANNEL_WIDTH_40) - val16 |= BIT_RFMOD_40M; - - rtw_write16(rtwdev, REG_WMAC_TRXPTCL_CTL, val16); -} - -static void rtw8821a_post_set_bw_mode(struct rtw_dev *rtwdev, u8 channel, u8 bw, - u8 primary_chan_idx) -{ - struct rtw_hal *hal = &rtwdev->hal; - u8 txsc40 = 0, txsc20, txsc; - u8 reg_837, l1pkval; - - rtw8821a_set_reg_bw(rtwdev, bw); - - txsc20 = primary_chan_idx; - if (bw == RTW_CHANNEL_WIDTH_80) { - if (txsc20 == RTW_SC_20_UPPER || txsc20 == RTW_SC_20_UPMOST) - txsc40 = RTW_SC_40_UPPER; - else - txsc40 = RTW_SC_40_LOWER; - } - - txsc = BIT_TXSC_20M(txsc20) | BIT_TXSC_40M(txsc40); - rtw_write8(rtwdev, REG_DATA_SC, txsc); - - reg_837 = rtw_read8(rtwdev, REG_BWINDICATION + 3); - - switch (bw) { - default: - case RTW_CHANNEL_WIDTH_20: - rtw_write32_mask(rtwdev, REG_ADCCLK, 0x003003C3, 0x00300200); - rtw_write32_mask(rtwdev, REG_ADC160, BIT(30), 0); - - if (hal->rf_type == RF_2T2R) - rtw_write32_mask(rtwdev, REG_L1PKTH, 0x03C00000, 7); - else - rtw_write32_mask(rtwdev, REG_L1PKTH, 0x03C00000, 8); - - break; - case RTW_CHANNEL_WIDTH_40: - rtw_write32_mask(rtwdev, REG_ADCCLK, 0x003003C3, 0x00300201); - rtw_write32_mask(rtwdev, REG_ADC160, BIT(30), 0); - rtw_write32_mask(rtwdev, REG_ADCCLK, 0x3C, txsc); - rtw_write32_mask(rtwdev, REG_CCA2ND, 0xf0000000, txsc); - - if (reg_837 & BIT(2)) { - l1pkval = 6; - } else { - if (hal->rf_type == RF_2T2R) - l1pkval = 7; - else - l1pkval = 8; - } - - rtw_write32_mask(rtwdev, REG_L1PKTH, 0x03C00000, l1pkval); - - if (txsc == RTW_SC_20_UPPER) - rtw_write32_set(rtwdev, REG_RXSB, BIT(4)); - else - rtw_write32_clr(rtwdev, REG_RXSB, BIT(4)); - - break; - case RTW_CHANNEL_WIDTH_80: - rtw_write32_mask(rtwdev, REG_ADCCLK, 0x003003C3, 0x00300202); - rtw_write32_mask(rtwdev, REG_ADC160, BIT(30), 1); - rtw_write32_mask(rtwdev, REG_ADCCLK, 0x3C, txsc); - rtw_write32_mask(rtwdev, REG_CCA2ND, 0xf0000000, txsc); - - if (reg_837 & BIT(2)) { - l1pkval = 5; - } else { - if (hal->rf_type == RF_2T2R) - l1pkval = 6; - else - l1pkval = 7; - } - - rtw_write32_mask(rtwdev, REG_L1PKTH, 0x03C00000, l1pkval); - - break; - } -} - -static void rtw8821a_set_channel_rf(struct rtw_dev *rtwdev, u8 channel, u8 bw) -{ - u8 path; - - for (path = RF_PATH_A; path < rtwdev->hal.rf_path_num; path++) { - switch (bw) { - case RTW_CHANNEL_WIDTH_5: - case RTW_CHANNEL_WIDTH_10: - case RTW_CHANNEL_WIDTH_20: - default: - rtw_write_rf(rtwdev, path, 0x18, RF18_BW_MASK, 3); - break; - case RTW_CHANNEL_WIDTH_40: - rtw_write_rf(rtwdev, path, 0x18, RF18_BW_MASK, 1); - break; - case RTW_CHANNEL_WIDTH_80: - rtw_write_rf(rtwdev, path, 0x18, RF18_BW_MASK, 0); - break; - } - } -} - -static void rtw8821a_set_channel(struct rtw_dev *rtwdev, u8 channel, u8 bw, - u8 primary_chan_idx) -{ - u8 old_band, new_band; - - if (rtw_read8(rtwdev, REG_CCK_CHECK) & BIT_CHECK_CCK_EN) - old_band = RTW_BAND_5G; - else - old_band = RTW_BAND_2G; - - if (channel > 14) - new_band = RTW_BAND_5G; - else - new_band = RTW_BAND_2G; - - if (new_band != old_band) - rtw8821a_switch_band(rtwdev, new_band, bw); - - rtw8821a_switch_channel(rtwdev, channel, bw); - - rtw8821a_post_set_bw_mode(rtwdev, channel, bw, primary_chan_idx); - - if (rtwdev->chip->id == RTW_CHIP_TYPE_8812A) - rtw8812a_phy_fix_spur(rtwdev, channel, bw); - - rtw8821a_set_channel_rf(rtwdev, channel, bw); -} - -static s8 rtw8821a_cck_rx_pwr(struct rtw_dev *rtwdev, u8 lna_idx, u8 vga_idx) -{ - static const s8 lna_gain_table[] = {15, -1, -17, 0, -30, -38}; - s8 rx_pwr_all = 0; - s8 lna_gain; - - switch (lna_idx) { - case 5: - case 4: - case 2: - case 1: - case 0: - lna_gain = lna_gain_table[lna_idx]; - rx_pwr_all = lna_gain - 2 * vga_idx; - break; - default: - break; - } - - return rx_pwr_all; -} - -static s8 rtw8812a_cck_rx_pwr(struct rtw_dev *rtwdev, u8 lna_idx, u8 vga_idx) -{ - s8 rx_pwr_all = 0; - - switch (lna_idx) { - case 7: - if (vga_idx <= 27) - rx_pwr_all = -94 + 2 * (27 - vga_idx); - else - rx_pwr_all = -94; - break; - case 6: - rx_pwr_all = -42 + 2 * (2 - vga_idx); - break; - case 5: - rx_pwr_all = -36 + 2 * (7 - vga_idx); - break; - case 4: - rx_pwr_all = -30 + 2 * (7 - vga_idx); - break; - case 3: - rx_pwr_all = -18 + 2 * (7 - vga_idx); - break; - case 2: - rx_pwr_all = 2 * (5 - vga_idx); - break; - case 1: - rx_pwr_all = 14 - 2 * vga_idx; - break; - case 0: - rx_pwr_all = 20 - 2 * vga_idx; - break; - default: - break; - } - - return rx_pwr_all; -} - -static void rtw8821a_query_phy_status(struct rtw_dev *rtwdev, u8 *phy_status, - struct rtw_rx_pkt_stat *pkt_stat) -{ - struct rtw_dm_info *dm_info = &rtwdev->dm_info; - struct rtw8821a_phy_status_rpt *phy_sts; - u8 lna_idx, vga_idx, cck_agc_rpt; - s8 rx_pwr_db, power_a, power_b; - const s8 min_rx_power = -120; - u8 rssi, val, i; - - phy_sts = (struct rtw8821a_phy_status_rpt *)phy_status; - - if (pkt_stat->rate <= DESC_RATE11M) { - cck_agc_rpt = phy_sts->cfosho[0]; - lna_idx = (cck_agc_rpt & 0xE0) >> 5; - vga_idx = cck_agc_rpt & 0x1F; - - if (rtwdev->chip->id == RTW_CHIP_TYPE_8821A) - rx_pwr_db = rtw8821a_cck_rx_pwr(rtwdev, lna_idx, vga_idx); - else - rx_pwr_db = rtw8812a_cck_rx_pwr(rtwdev, lna_idx, vga_idx); - - pkt_stat->rx_power[RF_PATH_A] = rx_pwr_db; - pkt_stat->rssi = rtw_phy_rf_power_2_rssi(pkt_stat->rx_power, 1); - dm_info->rssi[RF_PATH_A] = pkt_stat->rssi; - pkt_stat->bw = RTW_CHANNEL_WIDTH_20; - pkt_stat->signal_power = rx_pwr_db; - - if (rtwdev->chip->id == RTW_CHIP_TYPE_8812A && - !rtwdev->hal.cck_high_power) { - if (pkt_stat->rssi >= 80) - pkt_stat->rssi = ((pkt_stat->rssi - 80) << 1) + - ((pkt_stat->rssi - 80) >> 1) + 80; - else if (pkt_stat->rssi <= 78 && pkt_stat->rssi >= 20) - pkt_stat->rssi += 3; - } - } else { /* OFDM rate */ - for (i = RF_PATH_A; i < rtwdev->hal.rf_path_num; i++) { - val = phy_sts->gain_trsw[i]; - pkt_stat->rx_power[i] = (val & 0x7F) - 110; - rssi = rtw_phy_rf_power_2_rssi(&pkt_stat->rx_power[i], 1); - dm_info->rssi[i] = rssi; - } - - pkt_stat->rssi = rtw_phy_rf_power_2_rssi(pkt_stat->rx_power, - rtwdev->hal.rf_path_num); - - power_a = pkt_stat->rx_power[RF_PATH_A]; - power_b = pkt_stat->rx_power[RF_PATH_B]; - if (rtwdev->hal.rf_path_num == 1) - power_b = power_a; - - pkt_stat->signal_power = max3(power_a, power_b, min_rx_power); - } -} - -static void -rtw8821a_set_tx_power_index_by_rate(struct rtw_dev *rtwdev, u8 path, - u8 rs, u32 *phy_pwr_idx) -{ - static const u32 offset_txagc[2] = {0xc20, 0xe20}; - u8 rate, rate_idx, pwr_index, shift; - struct rtw_hal *hal = &rtwdev->hal; - bool write_1ss_mcs9; - u32 mask; - int j; - - for (j = 0; j < rtw_rate_size[rs]; j++) { - rate = rtw_rate_section[rs][j]; - - pwr_index = hal->tx_pwr_tbl[path][rate]; - - shift = rate & 0x3; - *phy_pwr_idx |= ((u32)pwr_index << (shift * 8)); - - write_1ss_mcs9 = rate == DESC_RATEVHT1SS_MCS9 && - hal->rf_path_num == 1; - - if (write_1ss_mcs9) - mask = MASKLWORD; - else - mask = MASKDWORD; - - if (shift == 0x3 || write_1ss_mcs9) { - rate_idx = rate & 0xfc; - if (rate >= DESC_RATEVHT1SS_MCS0) - rate_idx -= 0x10; - - rtw_write32_mask(rtwdev, offset_txagc[path] + rate_idx, - mask, *phy_pwr_idx); - - *phy_pwr_idx = 0; - } - } -} - -static void rtw8821a_tx_power_training(struct rtw_dev *rtwdev, u8 bw, - u8 channel, u8 path) -{ - static const u32 write_offset[] = { - REG_TX_PWR_TRAINING_A, REG_TX_PWR_TRAINING_B, - }; - u32 power_level, write_data; - u8 i; - - power_level = rtwdev->hal.tx_pwr_tbl[path][DESC_RATEMCS7]; - write_data = 0; - - for (i = 0; i < 3; i++) { - if (i == 0) - power_level -= 10; - else if (i == 1) - power_level -= 8; - else - power_level -= 6; - - write_data |= max_t(u32, power_level, 2) << (i * 8); - } - - rtw_write32_mask(rtwdev, write_offset[path], 0xffffff, write_data); -} - -static void rtw8821a_set_tx_power_index(struct rtw_dev *rtwdev) -{ - struct rtw_hal *hal = &rtwdev->hal; - u32 phy_pwr_idx = 0; - int rs, path; - - for (path = 0; path < hal->rf_path_num; path++) { - for (rs = 0; rs < RTW_RATE_SECTION_MAX; rs++) { - if (hal->rf_path_num == 1 && - (rs == RTW_RATE_SECTION_HT_2S || - rs == RTW_RATE_SECTION_VHT_2S)) - continue; - - if (test_bit(RTW_FLAG_SCANNING, rtwdev->flags) && - rs > RTW_RATE_SECTION_OFDM) - continue; - - if (hal->current_band_type == RTW_BAND_5G && - rs == RTW_RATE_SECTION_CCK) - continue; - - rtw8821a_set_tx_power_index_by_rate(rtwdev, path, rs, - &phy_pwr_idx); - } - - rtw8821a_tx_power_training(rtwdev, hal->current_band_width, - hal->current_channel, path); - } -} - -static void rtw8821a_false_alarm_statistics(struct rtw_dev *rtwdev) -{ - struct rtw_dm_info *dm_info = &rtwdev->dm_info; - u32 cck_fa_cnt, ofdm_fa_cnt; - u32 crc32_cnt, cca32_cnt; - u32 cck_enable; - - cck_enable = rtw_read32(rtwdev, REG_RXPSEL) & BIT(28); - cck_fa_cnt = rtw_read16(rtwdev, REG_FA_CCK); - ofdm_fa_cnt = rtw_read16(rtwdev, REG_FA_OFDM); - - dm_info->cck_fa_cnt = cck_fa_cnt; - dm_info->ofdm_fa_cnt = ofdm_fa_cnt; - dm_info->total_fa_cnt = ofdm_fa_cnt; - if (cck_enable) - dm_info->total_fa_cnt += cck_fa_cnt; - - crc32_cnt = rtw_read32(rtwdev, REG_CRC_CCK); - dm_info->cck_ok_cnt = FIELD_GET(GENMASK(15, 0), crc32_cnt); - dm_info->cck_err_cnt = FIELD_GET(GENMASK(31, 16), crc32_cnt); - - crc32_cnt = rtw_read32(rtwdev, REG_CRC_OFDM); - dm_info->ofdm_ok_cnt = FIELD_GET(GENMASK(15, 0), crc32_cnt); - dm_info->ofdm_err_cnt = FIELD_GET(GENMASK(31, 16), crc32_cnt); - - crc32_cnt = rtw_read32(rtwdev, REG_CRC_HT); - dm_info->ht_ok_cnt = FIELD_GET(GENMASK(15, 0), crc32_cnt); - dm_info->ht_err_cnt = FIELD_GET(GENMASK(31, 16), crc32_cnt); - - crc32_cnt = rtw_read32(rtwdev, REG_CRC_VHT); - dm_info->vht_ok_cnt = FIELD_GET(GENMASK(15, 0), crc32_cnt); - dm_info->vht_err_cnt = FIELD_GET(GENMASK(31, 16), crc32_cnt); - - cca32_cnt = rtw_read32(rtwdev, REG_CCA_OFDM); - dm_info->ofdm_cca_cnt = FIELD_GET(GENMASK(31, 16), cca32_cnt); - dm_info->total_cca_cnt = dm_info->ofdm_cca_cnt; - if (cck_enable) { - cca32_cnt = rtw_read32(rtwdev, REG_CCA_CCK); - dm_info->cck_cca_cnt = FIELD_GET(GENMASK(15, 0), cca32_cnt); - dm_info->total_cca_cnt += dm_info->cck_cca_cnt; - } - - rtw_write32_set(rtwdev, REG_FAS, BIT(17)); - rtw_write32_clr(rtwdev, REG_FAS, BIT(17)); - rtw_write32_clr(rtwdev, REG_RXDESC, BIT(15)); - rtw_write32_set(rtwdev, REG_RXDESC, BIT(15)); - rtw_write32_set(rtwdev, REG_CNTRST, BIT(0)); - rtw_write32_clr(rtwdev, REG_CNTRST, BIT(0)); -} - -#define CAL_NUM_8821A 3 -#define MACBB_REG_NUM_8821A 8 -#define AFE_REG_NUM_8821A 4 -#define RF_REG_NUM_8821A 3 - -static void rtw8821a_iqk_backup_mac_bb(struct rtw_dev *rtwdev, - u32 *macbb_backup, - const u32 *backup_macbb_reg, - u32 macbb_num) -{ - u32 i; - - /* [31] = 0 --> Page C */ - rtw_write32_mask(rtwdev, REG_CCASEL, BIT(31), 0x0); - - /* save MACBB default value */ - for (i = 0; i < macbb_num; i++) - macbb_backup[i] = rtw_read32(rtwdev, backup_macbb_reg[i]); -} - -static void rtw8821a_iqk_backup_afe(struct rtw_dev *rtwdev, u32 *afe_backup, - const u32 *backup_afe_reg, u32 afe_num) -{ - u32 i; - - /* [31] = 0 --> Page C */ - rtw_write32_mask(rtwdev, REG_CCASEL, BIT(31), 0x0); - - /* Save AFE Parameters */ - for (i = 0; i < afe_num; i++) - afe_backup[i] = rtw_read32(rtwdev, backup_afe_reg[i]); -} - -static void rtw8821a_iqk_backup_rf(struct rtw_dev *rtwdev, u32 *rfa_backup, - const u32 *backup_rf_reg, u32 rf_num) -{ - u32 i; - - /* [31] = 0 --> Page C */ - rtw_write32_mask(rtwdev, REG_CCASEL, BIT(31), 0x0); - - /* Save RF Parameters */ - for (i = 0; i < rf_num; i++) - rfa_backup[i] = rtw_read_rf(rtwdev, RF_PATH_A, - backup_rf_reg[i], MASKDWORD); -} - -static void rtw8821a_iqk_restore_rf(struct rtw_dev *rtwdev, - const u32 *backup_rf_reg, - u32 *RF_backup, u32 rf_reg_num) -{ - u32 i; - - /* [31] = 0 --> Page C */ - rtw_write32_mask(rtwdev, REG_CCASEL, BIT(31), 0x0); - - for (i = 0; i < rf_reg_num; i++) - rtw_write_rf(rtwdev, RF_PATH_A, backup_rf_reg[i], - RFREG_MASK, RF_backup[i]); -} - -static void rtw8821a_iqk_restore_afe(struct rtw_dev *rtwdev, u32 *afe_backup, - const u32 *backup_afe_reg, u32 afe_num) -{ - u32 i; - - /* [31] = 0 --> Page C */ - rtw_write32_mask(rtwdev, REG_CCASEL, BIT(31), 0x0); - - /* Reload AFE Parameters */ - for (i = 0; i < afe_num; i++) - rtw_write32(rtwdev, backup_afe_reg[i], afe_backup[i]); - - /* [31] = 1 --> Page C1 */ - rtw_write32_mask(rtwdev, REG_CCASEL, BIT(31), 0x1); - - rtw_write32(rtwdev, 0xc80, 0x0); - rtw_write32(rtwdev, 0xc84, 0x0); - rtw_write32(rtwdev, 0xc88, 0x0); - rtw_write32(rtwdev, 0xc8c, 0x3c000000); - rtw_write32(rtwdev, REG_LSSI_WRITE_A, 0x00000080); - rtw_write32(rtwdev, 0xc94, 0x00000000); - rtw_write32(rtwdev, 0xcc4, 0x20040000); - rtw_write32(rtwdev, 0xcc8, 0x20000000); - rtw_write32(rtwdev, REG_RFECTL_A, 0x0); -} - -static void rtw8821a_iqk_restore_mac_bb(struct rtw_dev *rtwdev, - u32 *macbb_backup, - const u32 *backup_macbb_reg, - u32 macbb_num) -{ - u32 i; - - /* [31] = 0 --> Page C */ - rtw_write32_mask(rtwdev, REG_CCASEL, BIT(31), 0x0); - - /* Reload MacBB Parameters */ - for (i = 0; i < macbb_num; i++) - rtw_write32(rtwdev, backup_macbb_reg[i], macbb_backup[i]); -} - -static void rtw8821a_iqk_configure_mac(struct rtw_dev *rtwdev) -{ - /* [31] = 0 --> Page C */ - rtw_write32_mask(rtwdev, REG_CCASEL, BIT(31), 0x0); - - rtw_write8(rtwdev, REG_TXPAUSE, 0x3f); - rtw_write32_mask(rtwdev, REG_BCN_CTRL, - (BIT_EN_BCN_FUNCTION << 8) | BIT_EN_BCN_FUNCTION, 0x0); - - /* RX ante off */ - rtw_write8(rtwdev, REG_RXPSEL, 0x00); - - /* CCA off */ - rtw_write32_mask(rtwdev, REG_CCA2ND, 0xf, 0xc); - - /* CCK RX path off */ - rtw_write8(rtwdev, REG_CCK_RX + 3, 0xf); -} - -static void rtw8821a_iqk_rx_fill(struct rtw_dev *rtwdev, u8 path, - unsigned int rx_x, unsigned int rx_y) -{ - if (path != RF_PATH_A) - return; - - /* [31] = 0 --> Page C */ - rtw_write32_mask(rtwdev, REG_CCASEL, BIT(31), 0x0); - - rtw_write32_mask(rtwdev, REG_RX_IQC_AB_A, - 0x000003ff, rx_x >> 1); - rtw_write32_mask(rtwdev, REG_RX_IQC_AB_A, - 0x03ff0000, (rx_y >> 1) & 0x3ff); -} - -static void rtw8821a_iqk_tx_fill(struct rtw_dev *rtwdev, u8 path, - unsigned int tx_x, unsigned int tx_y) -{ - if (path != RF_PATH_A) - return; - - /* [31] = 1 --> Page C1 */ - rtw_write32_mask(rtwdev, REG_CCASEL, BIT(31), 0x1); - - rtw_write32(rtwdev, REG_LSSI_WRITE_A, 0x00000080); - rtw_write32(rtwdev, 0xcc4, 0x20040000); - rtw_write32(rtwdev, 0xcc8, 0x20000000); - rtw_write32_mask(rtwdev, 0xccc, 0x000007ff, tx_y); - rtw_write32_mask(rtwdev, 0xcd4, 0x000007ff, tx_x); -} - -static void rtw8821a_iqk(struct rtw_dev *rtwdev) -{ - u32 tx_fail, rx_fail, delay_count, iqk_ready, cal_retry, cal = 0; - int i, k, vdf_Y[3], vdf_X[3], tx_dt[3], ii, dx = 0, dy = 0; - int tx_average = 0, rx_average = 0, rx_iqk_loop = 0; - const struct rtw_efuse *efuse = &rtwdev->efuse; - int tx_x = 0, tx_y = 0, rx_x = 0, rx_y = 0; - const struct rtw_hal *hal = &rtwdev->hal; - bool tx0iqkok = false, rx0iqkok = false; - int rx_x_temp = 0, rx_y_temp = 0; - int rx_x0[2][CAL_NUM_8821A]; - int rx_y0[2][CAL_NUM_8821A]; - const u8 path = RF_PATH_A; - int tx_x0[CAL_NUM_8821A]; - int tx_y0[CAL_NUM_8821A]; - bool rx_finish1 = false; - bool rx_finish2 = false; - bool tx_finish = false; - bool vdf_enable; - - rtw_dbg(rtwdev, RTW_DBG_RFK, - "band_width = %d, ext_pa = %d, ext_pa_5g = %d\n", - hal->current_band_width, efuse->ext_pa_2g, efuse->ext_pa_5g); - - vdf_enable = hal->current_band_width == RTW_CHANNEL_WIDTH_80; - - while (cal < CAL_NUM_8821A) { - /* path-A LOK */ - /* [31] = 0 --> Page C */ - rtw_write32_mask(rtwdev, REG_CCASEL, BIT(31), 0x0); - - /* ========path-A AFE all on======== */ - /* Port 0 DAC/ADC on */ - rtw_write32(rtwdev, REG_AFE_PWR1_A, 0x77777777); - rtw_write32(rtwdev, REG_AFE_PWR2_A, 0x77777777); - - rtw_write32(rtwdev, REG_RX_WAIT_CCA_TX_CCK_RFON_A, 0x19791979); - - /* hardware 3-wire off */ - rtw_write32_mask(rtwdev, 0xc00, 0xf, 0x4); - - /* LOK setting */ - /* ====== LOK ====== */ - /* 1. DAC/ADC sampling rate (160 MHz) */ - rtw_write32_mask(rtwdev, 0xc5c, GENMASK(26, 24), 0x7); - - /* 2. LoK RF setting (at BW = 20M) */ - rtw_write_rf(rtwdev, path, RF_LUTWE, RFREG_MASK, 0x80002); - rtw_write_rf(rtwdev, path, RF_CFGCH, 0x00c00, 0x3); - rtw_write_rf(rtwdev, path, RF_MODE_TABLE_ADDR, RFREG_MASK, 0x20000); - rtw_write_rf(rtwdev, path, RF_MODE_TABLE_DATA0, RFREG_MASK, 0x0003f); - rtw_write_rf(rtwdev, path, RF_MODE_TABLE_DATA1, RFREG_MASK, 0xf3fc3); - - rtw_write_rf(rtwdev, path, 0x65, RFREG_MASK, 0x931d5); - rtw_write_rf(rtwdev, path, 0x8f, RFREG_MASK, 0x8a001); - rtw_write32(rtwdev, 0x90c, 0x00008000); - rtw_write32_mask(rtwdev, 0xc94, BIT(0), 0x1); - /* TX (X,Y) */ - rtw_write32(rtwdev, 0x978, 0x29002000); - /* RX (X,Y) */ - rtw_write32(rtwdev, 0x97c, 0xa9002000); - /* [0]:AGC_en, [15]:idac_K_Mask */ - rtw_write32(rtwdev, 0x984, 0x00462910); - - /* [31] = 1 --> Page C1 */ - rtw_write32_mask(rtwdev, REG_CCASEL, BIT(31), 0x1); - - if (efuse->ext_pa_5g) - rtw_write32(rtwdev, 0xc88, 0x821403f7); - else - rtw_write32(rtwdev, 0xc88, 0x821403f4); - - if (hal->current_band_type == RTW_BAND_5G) - rtw_write32(rtwdev, 0xc8c, 0x68163e96); - else - rtw_write32(rtwdev, 0xc8c, 0x28163e96); - - /* TX_Tone_idx[9:0], TxK_Mask[29] TX_Tone = 16 */ - rtw_write32(rtwdev, 0xc80, 0x18008c10); - /* RX_Tone_idx[9:0], RxK_Mask[29] */ - rtw_write32(rtwdev, 0xc84, 0x38008c10); - rtw_write32(rtwdev, REG_RFECTL_A, 0x00100000); - rtw_write32(rtwdev, 0x980, 0xfa000000); - rtw_write32(rtwdev, 0x980, 0xf8000000); - - mdelay(10); /* delay 10ms */ - rtw_write32(rtwdev, REG_RFECTL_A, 0x00000000); - - /* [31] = 0 --> Page C */ - rtw_write32_mask(rtwdev, REG_CCASEL, BIT(31), 0x0); - rtw_write_rf(rtwdev, path, 0x58, 0x7fe00, - rtw_read_rf(rtwdev, path, RF_DTXLOK, 0xffc00)); - - if (hal->current_band_width == RTW_CHANNEL_WIDTH_40) - rtw_write_rf(rtwdev, path, RF_CFGCH, RF18_BW_MASK, 0x1); - else if (hal->current_band_width == RTW_CHANNEL_WIDTH_80) - rtw_write_rf(rtwdev, path, RF_CFGCH, RF18_BW_MASK, 0x0); - - /* [31] = 1 --> Page C1 */ - rtw_write32_mask(rtwdev, REG_CCASEL, BIT(31), 0x1); - - /* 3. TX RF setting */ - /* [31] = 0 --> Page C */ - rtw_write32_mask(rtwdev, REG_CCASEL, BIT(31), 0x0); - rtw_write_rf(rtwdev, path, RF_LUTWE, RFREG_MASK, 0x80000); - rtw_write_rf(rtwdev, path, RF_MODE_TABLE_ADDR, RFREG_MASK, 0x20000); - rtw_write_rf(rtwdev, path, RF_MODE_TABLE_DATA0, RFREG_MASK, 0x0003f); - rtw_write_rf(rtwdev, path, RF_MODE_TABLE_DATA1, RFREG_MASK, 0xf3fc3); - - rtw_write_rf(rtwdev, path, 0x65, RFREG_MASK, 0x931d5); - rtw_write_rf(rtwdev, path, 0x8f, RFREG_MASK, 0x8a001); - rtw_write_rf(rtwdev, path, RF_LUTWE, RFREG_MASK, 0x00000); - rtw_write32(rtwdev, 0x90c, 0x00008000); - rtw_write32_mask(rtwdev, 0xc94, BIT(0), 0x1); - /* TX (X,Y) */ - rtw_write32(rtwdev, 0x978, 0x29002000); - /* RX (X,Y) */ - rtw_write32(rtwdev, 0x97c, 0xa9002000); - /* [0]:AGC_en, [15]:idac_K_Mask */ - rtw_write32(rtwdev, 0x984, 0x0046a910); - - /* [31] = 1 --> Page C1 */ - rtw_write32_mask(rtwdev, REG_CCASEL, BIT(31), 0x1); - - if (efuse->ext_pa_5g) - rtw_write32(rtwdev, 0xc88, 0x821403f7); - else - rtw_write32(rtwdev, 0xc88, 0x821403e3); - - if (hal->current_band_type == RTW_BAND_5G) - rtw_write32(rtwdev, 0xc8c, 0x40163e96); - else - rtw_write32(rtwdev, 0xc8c, 0x00163e96); - - if (vdf_enable) { - for (k = 0; k <= 2; k++) { - switch (k) { - case 0: - /* TX_Tone_idx[9:0], TxK_Mask[29] TX_Tone = 16 */ - rtw_write32(rtwdev, 0xc80, 0x18008c38); - /* RX_Tone_idx[9:0], RxK_Mask[29] */ - rtw_write32(rtwdev, 0xc84, 0x38008c38); - rtw_write32_mask(rtwdev, 0xce8, BIT(31), 0x0); - break; - case 1: - rtw_write32_mask(rtwdev, 0xc80, BIT(28), 0x0); - rtw_write32_mask(rtwdev, 0xc84, BIT(28), 0x0); - rtw_write32_mask(rtwdev, 0xce8, BIT(31), 0x0); - break; - case 2: - rtw_dbg(rtwdev, RTW_DBG_RFK, - "vdf_Y[1] = %x;;;vdf_Y[0] = %x\n", - vdf_Y[1] >> 21 & 0x00007ff, - vdf_Y[0] >> 21 & 0x00007ff); - - rtw_dbg(rtwdev, RTW_DBG_RFK, - "vdf_X[1] = %x;;;vdf_X[0] = %x\n", - vdf_X[1] >> 21 & 0x00007ff, - vdf_X[0] >> 21 & 0x00007ff); - - tx_dt[cal] = (vdf_Y[1] >> 20) - (vdf_Y[0] >> 20); - tx_dt[cal] = (16 * tx_dt[cal]) * 10000 / 15708; - tx_dt[cal] = (tx_dt[cal] >> 1) + (tx_dt[cal] & BIT(0)); - - /* TX_Tone_idx[9:0], TxK_Mask[29] TX_Tone = 16 */ - rtw_write32(rtwdev, 0xc80, 0x18008c20); - /* RX_Tone_idx[9:0], RxK_Mask[29] */ - rtw_write32(rtwdev, 0xc84, 0x38008c20); - rtw_write32_mask(rtwdev, 0xce8, BIT(31), 0x1); - rtw_write32_mask(rtwdev, 0xce8, 0x3fff0000, - tx_dt[cal] & 0x00003fff); - break; - } - - rtw_write32(rtwdev, REG_RFECTL_A, 0x00100000); - cal_retry = 0; - while (1) { - /* one shot */ - rtw_write32(rtwdev, 0x980, 0xfa000000); - rtw_write32(rtwdev, 0x980, 0xf8000000); - - mdelay(10); - - rtw_write32(rtwdev, REG_RFECTL_A, 0x00000000); - - delay_count = 0; - while (1) { - iqk_ready = rtw_read32_mask(rtwdev, 0xd00, BIT(10)); - - /* Originally: if (~iqk_ready || delay_count > 20) - * that looks like a typo so make it more explicit - */ - iqk_ready = true; - - if (iqk_ready || delay_count > 20) - break; - - mdelay(1); - delay_count++; - } - - if (delay_count < 20) { - /* ============TXIQK Check============== */ - tx_fail = rtw_read32_mask(rtwdev, 0xd00, BIT(12)); - - /* Originally: if (~tx_fail) { - * It looks like a typo, so make it more explicit. - */ - tx_fail = false; - - if (!tx_fail) { - rtw_write32(rtwdev, REG_RFECTL_A, 0x02000000); - vdf_X[k] = rtw_read32_mask(rtwdev, 0xd00, 0x07ff0000) << 21; - - rtw_write32(rtwdev, REG_RFECTL_A, 0x04000000); - vdf_Y[k] = rtw_read32_mask(rtwdev, 0xd00, 0x07ff0000) << 21; - - tx0iqkok = true; - break; - } - - rtw_write32_mask(rtwdev, 0xccc, 0x000007ff, 0x0); - rtw_write32_mask(rtwdev, 0xcd4, 0x000007ff, 0x200); - - tx0iqkok = false; - cal_retry++; - if (cal_retry == 10) - break; - - } else { /* If 20ms No Result, then cal_retry++ */ - tx0iqkok = false; - cal_retry++; - if (cal_retry == 10) - break; - } - } - } - - if (k == 3) { - tx_x0[cal] = vdf_X[k - 1]; - tx_y0[cal] = vdf_Y[k - 1]; - } - } else { - /* TX_Tone_idx[9:0], TxK_Mask[29] TX_Tone = 16 */ - rtw_write32(rtwdev, 0xc80, 0x18008c10); - /* RX_Tone_idx[9:0], RxK_Mask[29] */ - rtw_write32(rtwdev, 0xc84, 0x38008c10); - rtw_write32(rtwdev, 0xcb8, 0x00100000); - - cal_retry = 0; - while (1) { - /* one shot */ - rtw_write32(rtwdev, 0x980, 0xfa000000); - rtw_write32(rtwdev, 0x980, 0xf8000000); - - mdelay(10); - rtw_write32(rtwdev, REG_RFECTL_A, 0x00000000); - - delay_count = 0; - while (1) { - iqk_ready = rtw_read32_mask(rtwdev, 0xd00, BIT(10)); - - /* Originally: if (~iqk_ready || delay_count > 20) - * that looks like a typo so make it more explicit - */ - iqk_ready = true; - - if (iqk_ready || delay_count > 20) - break; - - mdelay(1); - delay_count++; - } - - if (delay_count < 20) { - /* ============TXIQK Check============== */ - tx_fail = rtw_read32_mask(rtwdev, 0xd00, BIT(12)); - - /* Originally: if (~tx_fail) { - * It looks like a typo, so make it more explicit. - */ - tx_fail = false; - - if (!tx_fail) { - rtw_write32(rtwdev, REG_RFECTL_A, 0x02000000); - tx_x0[cal] = rtw_read32_mask(rtwdev, 0xd00, 0x07ff0000) << 21; - - rtw_write32(rtwdev, REG_RFECTL_A, 0x04000000); - tx_y0[cal] = rtw_read32_mask(rtwdev, 0xd00, 0x07ff0000) << 21; - - tx0iqkok = true; - break; - } - - rtw_write32_mask(rtwdev, 0xccc, 0x000007ff, 0x0); - rtw_write32_mask(rtwdev, 0xcd4, 0x000007ff, 0x200); - - tx0iqkok = false; - cal_retry++; - if (cal_retry == 10) - break; - } else { /* If 20ms No Result, then cal_retry++ */ - tx0iqkok = false; - cal_retry++; - if (cal_retry == 10) - break; - } - } - } - - if (tx0iqkok == false) - break; /* TXK fail, Don't do RXK */ - - /* ====== RX IQK ====== */ - /* [31] = 0 --> Page C */ - rtw_write32_mask(rtwdev, REG_CCASEL, BIT(31), 0x0); - /* 1. RX RF setting */ - rtw_write_rf(rtwdev, path, RF_LUTWE, RFREG_MASK, 0x80000); - rtw_write_rf(rtwdev, path, RF_MODE_TABLE_ADDR, RFREG_MASK, 0x30000); - rtw_write_rf(rtwdev, path, RF_MODE_TABLE_DATA0, RFREG_MASK, 0x0002f); - rtw_write_rf(rtwdev, path, RF_MODE_TABLE_DATA1, RFREG_MASK, 0xfffbb); - rtw_write_rf(rtwdev, path, 0x8f, RFREG_MASK, 0x88001); - rtw_write_rf(rtwdev, path, 0x65, RFREG_MASK, 0x931d8); - rtw_write_rf(rtwdev, path, RF_LUTWE, RFREG_MASK, 0x00000); -///TODO: it makes no sense to shift this left by 21 every time you want to use it -/// just do it once - rtw_write32_mask(rtwdev, 0x978, 0x03FF8000, (tx_x0[cal]) >> 21 & 0x000007ff); - rtw_write32_mask(rtwdev, 0x978, 0x000007FF, (tx_y0[cal]) >> 21 & 0x000007ff); - rtw_write32_mask(rtwdev, 0x978, BIT(31), 0x1); - rtw_write32_mask(rtwdev, 0x97c, BIT(31), 0x0); - rtw_write32(rtwdev, 0x90c, 0x00008000); - rtw_write32(rtwdev, 0x984, 0x0046a911); - - /* [31] = 1 --> Page C1 */ - rtw_write32_mask(rtwdev, REG_CCASEL, BIT(31), 0x1); - /* TX_Tone_idx[9:0], TxK_Mask[29] TX_Tone = 16 */ - rtw_write32(rtwdev, 0xc80, 0x38008c10); - /* RX_Tone_idx[9:0], RxK_Mask[29] */ - rtw_write32(rtwdev, 0xc84, 0x18008c10); - rtw_write32(rtwdev, 0xc88, 0x02140119); - - if (rtw_hci_type(rtwdev) == RTW_HCI_TYPE_PCIE) { - rx_iqk_loop = 2; /* for 2% fail; */ - } else - rx_iqk_loop = 1; - - for (i = 0; i < rx_iqk_loop; i++) { - if (rtw_hci_type(rtwdev) == RTW_HCI_TYPE_PCIE) { - if (i == 0) - rtw_write32(rtwdev, 0xc8c, 0x28161100); /* Good */ - else - rtw_write32(rtwdev, 0xc8c, 0x28160d00); - } else { - rtw_write32(rtwdev, 0xc8c, 0x28160d00); - } - - rtw_write32(rtwdev, REG_RFECTL_A, 0x00100000); - - cal_retry = 0; - while (1) { - /* one shot */ - rtw_write32(rtwdev, 0x980, 0xfa000000); - rtw_write32(rtwdev, 0x980, 0xf8000000); - - mdelay(10); - - rtw_write32(rtwdev, REG_RFECTL_A, 0x00000000); - - delay_count = 0; - while (1) { - iqk_ready = rtw_read32_mask(rtwdev, 0xd00, BIT(10)); - - /* Originally: if (~iqk_ready || delay_count > 20) - * that looks like a typo so make it more explicit - */ - iqk_ready = true; - - if (iqk_ready || delay_count > 20) - break; - - mdelay(1); - delay_count++; - } - - if (delay_count < 20) { - /* ============RXIQK Check============== */ - rx_fail = rtw_read32_mask(rtwdev, 0xd00, BIT(11)); - if (rx_fail == 0) { - rtw_write32(rtwdev, REG_RFECTL_A, 0x06000000); - rx_x0[i][cal] = rtw_read32_mask(rtwdev, 0xd00, 0x07ff0000) << 21; - - rtw_write32(rtwdev, REG_RFECTL_A, 0x08000000); - rx_y0[i][cal] = rtw_read32_mask(rtwdev, 0xd00, 0x07ff0000) << 21; - - rx0iqkok = true; - break; - } - - rtw_write32_mask(rtwdev, REG_RX_IQC_AB_A, 0x000003ff, 0x200 >> 1); - rtw_write32_mask(rtwdev, REG_RX_IQC_AB_A, 0x03ff0000, 0x0 >> 1); - - rx0iqkok = false; - cal_retry++; - if (cal_retry == 10) - break; - } else { /* If 20ms No Result, then cal_retry++ */ - rx0iqkok = false; - cal_retry++; - if (cal_retry == 10) - break; - } - } - } - - if (tx0iqkok) - tx_average++; - if (rx0iqkok) - rx_average++; - - cal++; - } - - /* FillIQK Result */ - - if (tx_average == 0) - return; - - for (i = 0; i < tx_average; i++) - rtw_dbg(rtwdev, RTW_DBG_RFK, - "tx_x0[%d] = %x ;; tx_y0[%d] = %x\n", i, - tx_x0[i] >> 21 & 0x000007ff, i, - tx_y0[i] >> 21 & 0x000007ff); - - for (i = 0; i < tx_average; i++) { - for (ii = i + 1; ii < tx_average; ii++) { - dx = (tx_x0[i] >> 21) - (tx_x0[ii] >> 21); - - if (dx < 3 && dx > -3) { - dy = (tx_y0[i] >> 21) - (tx_y0[ii] >> 21); - - if (dy < 3 && dy > -3) { - tx_x = ((tx_x0[i] >> 21) + (tx_x0[ii] >> 21)) / 2; - tx_y = ((tx_y0[i] >> 21) + (tx_y0[ii] >> 21)) / 2; - - tx_finish = true; - break; - } - } - } - - if (tx_finish) - break; - } - - if (tx_finish) - rtw8821a_iqk_tx_fill(rtwdev, path, tx_x, tx_y); - else - rtw8821a_iqk_tx_fill(rtwdev, path, 0x200, 0x0); - - if (rx_average == 0) - return; - - for (i = 0; i < rx_average; i++) { - rtw_dbg(rtwdev, RTW_DBG_RFK, - "rx_x0[0][%d] = %x ;; rx_y0[0][%d] = %x\n", i, - rx_x0[0][i] >> 21 & 0x000007ff, i, - rx_y0[0][i] >> 21 & 0x000007ff); - - if (rx_iqk_loop == 2) - rtw_dbg(rtwdev, RTW_DBG_RFK, - "rx_x0[1][%d] = %x ;; rx_y0[1][%d] = %x\n", - i, rx_x0[1][i] >> 21 & 0x000007ff, i, - rx_y0[1][i] >> 21 & 0x000007ff); - } - - for (i = 0; i < rx_average; i++) { - for (ii = i + 1; ii < rx_average; ii++) { - dx = (rx_x0[0][i] >> 21) - (rx_x0[0][ii] >> 21); - - if (dx < 4 && dx > -4) { - dy = (rx_y0[0][i] >> 21) - (rx_y0[0][ii] >> 21); - - if (dy < 4 && dy > -4) { - rx_x_temp = ((rx_x0[0][i] >> 21) + (rx_x0[0][ii] >> 21)) / 2; - rx_y_temp = ((rx_y0[0][i] >> 21) + (rx_y0[0][ii] >> 21)) / 2; - - rx_finish1 = true; - break; - } - } - } - - if (rx_finish1) { - rx_x = rx_x_temp; - rx_y = rx_y_temp; - break; - } - } - - if (rx_iqk_loop == 2) { - for (i = 0; i < rx_average; i++) { - for (ii = i + 1; ii < rx_average; ii++) { - dx = (rx_x0[1][i] >> 21) - (rx_x0[1][ii] >> 21); - - if (dx < 4 && dx > -4) { - dy = (rx_y0[1][i] >> 21) - (rx_y0[1][ii] >> 21); - - if (dy < 4 && dy > -4) { - rx_x = ((rx_x0[1][i] >> 21) + (rx_x0[1][ii] >> 21)) / 2; - rx_y = ((rx_y0[1][i] >> 21) + (rx_y0[1][ii] >> 21)) / 2; - - rx_finish2 = true; - break; - } - } - } - - if (rx_finish2) - break; - } - - if (rx_finish1 && rx_finish2) { - rx_x = (rx_x + rx_x_temp) / 2; - rx_y = (rx_y + rx_y_temp) / 2; - } - } - - if (rx_finish1 || rx_finish2) - rtw8821a_iqk_rx_fill(rtwdev, path, rx_x, rx_y); - else - rtw8821a_iqk_rx_fill(rtwdev, path, 0x200, 0x0); -} - -static void rtw8821a_do_iqk(struct rtw_dev *rtwdev) -{ - static const u32 backup_macbb_reg[MACBB_REG_NUM_8821A] = { - 0x520, 0x550, 0x808, 0xa04, 0x90c, 0xc00, 0x838, 0x82c - }; - static const u32 backup_afe_reg[AFE_REG_NUM_8821A] = { - 0xc5c, 0xc60, 0xc64, 0xc68 - }; - static const u32 backup_rf_reg[RF_REG_NUM_8821A] = { - 0x65, 0x8f, 0x0 - }; - u32 macbb_backup[MACBB_REG_NUM_8821A]; - u32 afe_backup[AFE_REG_NUM_8821A]; - u32 rfa_backup[RF_REG_NUM_8821A]; - - rtw8821a_iqk_backup_mac_bb(rtwdev, macbb_backup, - backup_macbb_reg, MACBB_REG_NUM_8821A); - rtw8821a_iqk_backup_afe(rtwdev, afe_backup, - backup_afe_reg, AFE_REG_NUM_8821A); - rtw8821a_iqk_backup_rf(rtwdev, rfa_backup, - backup_rf_reg, RF_REG_NUM_8821A); - - rtw8821a_iqk_configure_mac(rtwdev); - - rtw8821a_iqk(rtwdev); - - rtw8821a_iqk_restore_rf(rtwdev, backup_rf_reg, - rfa_backup, RF_REG_NUM_8821A); - rtw8821a_iqk_restore_afe(rtwdev, afe_backup, - backup_afe_reg, AFE_REG_NUM_8821A); - rtw8821a_iqk_restore_mac_bb(rtwdev, macbb_backup, - backup_macbb_reg, MACBB_REG_NUM_8821A); -} - -static void rtw8812a_iqk_backup_rf(struct rtw_dev *rtwdev, u32 *rfa_backup, - u32 *rfb_backup, const u32 *backup_rf_reg, - u32 rf_num) -{ - u32 i; - - /* [31] = 0 --> Page C */ - rtw_write32_mask(rtwdev, REG_CCASEL, BIT(31), 0x0); - - /* Save RF Parameters */ - for (i = 0; i < rf_num; i++) { - rfa_backup[i] = rtw_read_rf(rtwdev, RF_PATH_A, - backup_rf_reg[i], MASKDWORD); - rfb_backup[i] = rtw_read_rf(rtwdev, RF_PATH_B, - backup_rf_reg[i], MASKDWORD); - } -} - -static void rtw8812a_iqk_restore_rf(struct rtw_dev *rtwdev, - enum rtw_rf_path path, - const u32 *backup_rf_reg, - u32 *RF_backup, u32 rf_reg_num) -{ - u32 i; - - /* [31] = 0 --> Page C */ - rtw_write32_mask(rtwdev, REG_CCASEL, BIT(31), 0x0); - - for (i = 0; i < rf_reg_num; i++) - rtw_write_rf(rtwdev, path, backup_rf_reg[i], - RFREG_MASK, RF_backup[i]); - - rtw_write_rf(rtwdev, path, RF_LUTWE, RFREG_MASK, 0); -} - -static void rtw8812a_iqk_restore_afe(struct rtw_dev *rtwdev, u32 *afe_backup, - const u32 *backup_afe_reg, u32 afe_num) -{ - u32 i; - - /* [31] = 0 --> Page C */ - rtw_write32_mask(rtwdev, REG_CCASEL, BIT(31), 0x0); + mdelay(10); + rtw_write32(rtwdev, REG_RFECTL_A, 0x00000000); - /* Reload AFE Parameters */ - for (i = 0; i < afe_num; i++) - rtw_write32(rtwdev, backup_afe_reg[i], afe_backup[i]); + /* [31] = 0 --> Page C */ + rtw_write32_mask(rtwdev, REG_CCASEL, BIT(31), 0x0); + rtw_write_rf(rtwdev, RF_PATH_A, RF_TXMOD, 0x7fe00, + rtw_read_rf(rtwdev, RF_PATH_A, RF_DTXLOK, 0xffc00)); - /* [31] = 1 --> Page C1 */ - rtw_write32_mask(rtwdev, REG_CCASEL, BIT(31), 0x1); + if (hal->current_band_width == RTW_CHANNEL_WIDTH_40) + rtw_write_rf(rtwdev, RF_PATH_A, RF_CFGCH, + RF18_BW_MASK, 0x1); + else if (hal->current_band_width == RTW_CHANNEL_WIDTH_80) + rtw_write_rf(rtwdev, RF_PATH_A, RF_CFGCH, + RF18_BW_MASK, 0x0); - rtw_write32(rtwdev, 0xc80, 0x0); - rtw_write32(rtwdev, 0xc84, 0x0); - rtw_write32(rtwdev, 0xc88, 0x0); - rtw_write32(rtwdev, 0xc8c, 0x3c000000); - rtw_write32_mask(rtwdev, REG_LSSI_WRITE_A, BIT(7), 1); - rtw_write32_mask(rtwdev, 0xcc4, BIT(18), 1); - rtw_write32_mask(rtwdev, 0xcc4, BIT(29), 1); - rtw_write32_mask(rtwdev, 0xcc8, BIT(29), 1); - - rtw_write32(rtwdev, 0xe80, 0x0); - rtw_write32(rtwdev, 0xe84, 0x0); - rtw_write32(rtwdev, 0xe88, 0x0); - rtw_write32(rtwdev, 0xe8c, 0x3c000000); - rtw_write32_mask(rtwdev, REG_LSSI_WRITE_B, BIT(7), 1); - rtw_write32_mask(rtwdev, 0xec4, BIT(18), 1); - rtw_write32_mask(rtwdev, 0xec4, BIT(29), 1); - rtw_write32_mask(rtwdev, 0xec8, BIT(29), 1); -} + /* [31] = 1 --> Page C1 */ + rtw_write32_mask(rtwdev, REG_CCASEL, BIT(31), 0x1); -static void rtw8812a_iqk_rx_fill(struct rtw_dev *rtwdev, enum rtw_rf_path path, - unsigned int rx_x, unsigned int rx_y) -{ - switch (path) { - case RF_PATH_A: { - /* [31] = 0 --> Page C */ - rtw_write32_mask(rtwdev, REG_CCASEL, BIT(31), 0x0); - if (rx_x >> 1 >= 0x112 || (rx_y >> 1 >= 0x12 && rx_y >> 1 <= 0x3ee)) { - rtw_write32_mask(rtwdev, REG_RX_IQC_AB_A, 0x000003ff, 0x100); - rtw_write32_mask(rtwdev, REG_RX_IQC_AB_A, 0x03ff0000, 0); - } else { - rtw_write32_mask(rtwdev, REG_RX_IQC_AB_A, 0x000003ff, rx_x >> 1); - rtw_write32_mask(rtwdev, REG_RX_IQC_AB_A, 0x03ff0000, rx_y >> 1); - } - rtw_dbg(rtwdev, RTW_DBG_RFK, - "rx_x = %x;;rx_y = %x ====>fill to IQC\n", - rx_x >> 1 & 0x000003ff, rx_y >> 1 & 0x000003ff); - rtw_dbg(rtwdev, RTW_DBG_RFK, "0xc10 = %x ====>fill to IQC\n", - rtw_read32(rtwdev, REG_RX_IQC_AB_A)); - } break; - case RF_PATH_B: { + /* 3. TX RF setting */ /* [31] = 0 --> Page C */ rtw_write32_mask(rtwdev, REG_CCASEL, BIT(31), 0x0); - if (rx_x >> 1 >= 0x112 || (rx_y >> 1 >= 0x12 && rx_y >> 1 <= 0x3ee)) { - rtw_write32_mask(rtwdev, REG_RX_IQC_AB_B, 0x000003ff, 0x100); - rtw_write32_mask(rtwdev, REG_RX_IQC_AB_B, 0x03ff0000, 0); - } else { - rtw_write32_mask(rtwdev, REG_RX_IQC_AB_B, 0x000003ff, rx_x >> 1); - rtw_write32_mask(rtwdev, REG_RX_IQC_AB_B, 0x03ff0000, rx_y >> 1); - } - rtw_dbg(rtwdev, RTW_DBG_RFK, - "rx_x = %x;;rx_y = %x ====>fill to IQC\n", - rx_x >> 1 & 0x000003ff, rx_y >> 1 & 0x000003ff); - rtw_dbg(rtwdev, RTW_DBG_RFK, "0xe10 = %x====>fill to IQC\n", - rtw_read32(rtwdev, REG_RX_IQC_AB_B)); - } break; - default: - break; - }; -} + rtw_write_rf(rtwdev, RF_PATH_A, RF_LUTWE, RFREG_MASK, 0x80000); + rtw_write_rf(rtwdev, RF_PATH_A, RF_MODE_TABLE_ADDR, RFREG_MASK, + 0x20000); + rtw_write_rf(rtwdev, RF_PATH_A, RF_MODE_TABLE_DATA0, RFREG_MASK, + 0x0003f); + rtw_write_rf(rtwdev, RF_PATH_A, RF_MODE_TABLE_DATA1, RFREG_MASK, + 0xf3fc3); + + rtw_write_rf(rtwdev, RF_PATH_A, RF_TXA_PREPAD, RFREG_MASK, 0x931d5); + rtw_write_rf(rtwdev, RF_PATH_A, RF_RXBB2, RFREG_MASK, 0x8a001); + rtw_write_rf(rtwdev, RF_PATH_A, RF_LUTWE, RFREG_MASK, 0x00000); + rtw_write32(rtwdev, REG_DAC_RSTB, 0x00008000); + rtw_write32_mask(rtwdev, REG_TXAGCIDX, BIT(0), 0x1); + /* TX (X,Y) */ + rtw_write32(rtwdev, REG_IQK_COM00, 0x29002000); + /* RX (X,Y) */ + rtw_write32(rtwdev, REG_IQK_COM32, 0xa9002000); + /* [0]:AGC_en, [15]:idac_K_Mask */ + rtw_write32(rtwdev, REG_IQK_COM96, 0x0046a910); -static void rtw8812a_iqk_tx_fill(struct rtw_dev *rtwdev, enum rtw_rf_path path, - unsigned int tx_x, unsigned int tx_y) -{ - switch (path) { - case RF_PATH_A: { - /* [31] = 1 --> Page C1 */ - rtw_write32_mask(rtwdev, REG_CCASEL, BIT(31), 0x1); - rtw_write32_mask(rtwdev, 0xc90, BIT(7), 0x1); - rtw_write32_mask(rtwdev, 0xcc4, BIT(18), 0x1); - rtw_write32_mask(rtwdev, 0xcc4, BIT(29), 0x1); - rtw_write32_mask(rtwdev, 0xcc8, BIT(29), 0x1); - rtw_write32_mask(rtwdev, 0xccc, 0x000007ff, tx_y); - rtw_write32_mask(rtwdev, 0xcd4, 0x000007ff, tx_x); - rtw_dbg(rtwdev, RTW_DBG_RFK, - "tx_x = %x;;tx_y = %x =====> fill to IQC\n", - tx_x & 0x000007ff, tx_y & 0x000007ff); - rtw_dbg(rtwdev, RTW_DBG_RFK, - "0xcd4 = %x;;0xccc = %x ====>fill to IQC\n", - rtw_read32_mask(rtwdev, 0xcd4, 0x000007ff), - rtw_read32_mask(rtwdev, 0xccc, 0x000007ff)); - } break; - case RF_PATH_B: { /* [31] = 1 --> Page C1 */ rtw_write32_mask(rtwdev, REG_CCASEL, BIT(31), 0x1); - rtw_write32_mask(rtwdev, 0xe90, BIT(7), 0x1); - rtw_write32_mask(rtwdev, 0xec4, BIT(18), 0x1); - rtw_write32_mask(rtwdev, 0xec4, BIT(29), 0x1); - rtw_write32_mask(rtwdev, 0xec8, BIT(29), 0x1); - rtw_write32_mask(rtwdev, 0xecc, 0x000007ff, tx_y); - rtw_write32_mask(rtwdev, 0xed4, 0x000007ff, tx_x); - rtw_dbg(rtwdev, RTW_DBG_RFK, - "tx_x = %x;;tx_y = %x =====> fill to IQC\n", - tx_x & 0x000007ff, tx_y & 0x000007ff); - rtw_dbg(rtwdev, RTW_DBG_RFK, - "0xed4 = %x;;0xecc = %x ====>fill to IQC\n", - rtw_read32_mask(rtwdev, 0xed4, 0x000007ff), - rtw_read32_mask(rtwdev, 0xecc, 0x000007ff)); - } break; - default: - break; - }; -} - -static void rtw8812a_iqk(struct rtw_dev *rtwdev) -{ - u8 tx0_average = 0, tx1_average = 0, rx0_average = 0, rx1_average = 0; - bool iqk0_ready = false, tx0_finish = false, rx0_finish = false; - bool iqk1_ready = false, tx1_finish = false, rx1_finish = false; - struct rtw_efuse *efuse = &rtwdev->efuse; - /* tx_iqc = [TX0_X, TX0_Y,TX1_X,TX1_Y]; for 3 times */ - int tx_iqc_temp[10][4], tx_iqc[4] = {}; - /* rx_iqc = [RX0_X, RX0_Y,RX1_X,RX1_Y]; for 3 times */ - int rx_iqc_temp[10][4], rx_iqc[4] = {}; - bool tx0_fail = true, rx0_fail = true; - bool tx1_fail = true, rx1_fail = true; - int i, ii, dx = 0, dy = 0; - u8 cal0_retry, cal1_retry; - u8 delay_count; - - /* [31] = 0 --> Page C */ - rtw_write32_mask(rtwdev, REG_CCASEL, BIT(31), 0x0); - - /* ========path-A AFE all on======== */ - /* Port 0 DAC/ADC on */ - rtw_write32(rtwdev, REG_AFE_PWR1_A, 0x77777777); - rtw_write32(rtwdev, REG_AFE_PWR2_A, 0x77777777); - - /* Port 1 DAC/ADC on */ - rtw_write32(rtwdev, REG_AFE_PWR1_B, 0x77777777); - rtw_write32(rtwdev, REG_AFE_PWR2_B, 0x77777777); - - rtw_write32(rtwdev, REG_RX_WAIT_CCA_TX_CCK_RFON_A, 0x19791979); - rtw_write32(rtwdev, REG_RX_WAIT_CCA_TX_CCK_RFON_B, 0x19791979); - - /* hardware 3-wire off */ - rtw_write32_mask(rtwdev, 0xc00, 0xf, 0x4); - rtw_write32_mask(rtwdev, 0xe00, 0xf, 0x4); - - /* DAC/ADC sampling rate (160 MHz) */ - rtw_write32_mask(rtwdev, 0xc5c, BIT(26) | BIT(25) | BIT(24), 0x7); - rtw_write32_mask(rtwdev, 0xe5c, BIT(26) | BIT(25) | BIT(24), 0x7); - - /* [31] = 0 --> Page C */ - rtw_write32_mask(rtwdev, REG_CCASEL, BIT(31), 0x0); - /* ====== path A TX IQK RF setting ====== */ - rtw_write_rf(rtwdev, RF_PATH_A, RF_LUTWE, RFREG_MASK, 0x80002); - rtw_write_rf(rtwdev, RF_PATH_A, RF_MODE_TABLE_ADDR, RFREG_MASK, 0x20000); - rtw_write_rf(rtwdev, RF_PATH_A, RF_MODE_TABLE_DATA0, RFREG_MASK, 0x3fffd); - rtw_write_rf(rtwdev, RF_PATH_A, RF_MODE_TABLE_DATA1, RFREG_MASK, 0xfe83f); - rtw_write_rf(rtwdev, RF_PATH_A, 0x65, RFREG_MASK, 0x931d5); - rtw_write_rf(rtwdev, RF_PATH_A, 0x8f, RFREG_MASK, 0x8a001); - - /* ====== path B TX IQK RF setting ====== */ - rtw_write_rf(rtwdev, RF_PATH_B, RF_LUTWE, RFREG_MASK, 0x80002); - rtw_write_rf(rtwdev, RF_PATH_B, RF_MODE_TABLE_ADDR, RFREG_MASK, 0x20000); - rtw_write_rf(rtwdev, RF_PATH_B, RF_MODE_TABLE_DATA0, RFREG_MASK, 0x3fffd); - rtw_write_rf(rtwdev, RF_PATH_B, RF_MODE_TABLE_DATA1, RFREG_MASK, 0xfe83f); - rtw_write_rf(rtwdev, RF_PATH_B, 0x65, RFREG_MASK, 0x931d5); - rtw_write_rf(rtwdev, RF_PATH_B, 0x8f, RFREG_MASK, 0x8a001); - - rtw_write32(rtwdev, 0x90c, 0x00008000); - rtw_write32_mask(rtwdev, 0xc94, BIT(0), 0x1); - rtw_write32_mask(rtwdev, 0xe94, BIT(0), 0x1); - rtw_write32(rtwdev, 0x978, 0x29002000); /* TX (X,Y) */ - rtw_write32(rtwdev, 0x97c, 0xa9002000); /* RX (X,Y) */ - rtw_write32(rtwdev, 0x984, 0x00462910); /* [0]:AGC_en, [15]:idac_K_Mask */ - /* [31] = 1 --> Page C1 */ - rtw_write32_mask(rtwdev, REG_CCASEL, BIT(31), 0x1); - - if (efuse->ext_pa_5g) { - if (efuse->rfe_option == 1) { - rtw_write32(rtwdev, 0xc88, 0x821403e3); - rtw_write32(rtwdev, 0xe88, 0x821403e3); - } else { - rtw_write32(rtwdev, 0xc88, 0x821403f7); - rtw_write32(rtwdev, 0xe88, 0x821403f7); - } - } else { - rtw_write32(rtwdev, 0xc88, 0x821403f1); - rtw_write32(rtwdev, 0xe88, 0x821403f1); - } - - if (rtwdev->hal.current_band_type == RTW_BAND_5G) { - rtw_write32(rtwdev, 0xc8c, 0x68163e96); - rtw_write32(rtwdev, 0xe8c, 0x68163e96); - } else { - rtw_write32(rtwdev, 0xc8c, 0x28163e96); - rtw_write32(rtwdev, 0xe8c, 0x28163e96); - - if (efuse->rfe_option == 3) { - if (efuse->ext_pa_2g) - rtw_write32(rtwdev, 0xc88, 0x821403e3); - else - rtw_write32(rtwdev, 0xc88, 0x821403f7); - } - } - - rtw_write32(rtwdev, 0xc80, 0x18008c10); /* TX_Tone_idx[9:0], TxK_Mask[29] TX_Tone = 16 */ - rtw_write32(rtwdev, 0xc84, 0x38008c10); /* RX_Tone_idx[9:0], RxK_Mask[29] */ - rtw_write32(rtwdev, 0xce8, 0x00000000); - rtw_write32(rtwdev, 0xe80, 0x18008c10); /* TX_Tone_idx[9:0], TxK_Mask[29] TX_Tone = 16 */ - rtw_write32(rtwdev, 0xe84, 0x38008c10); /* RX_Tone_idx[9:0], RxK_Mask[29] */ - rtw_write32(rtwdev, 0xee8, 0x00000000); - - cal0_retry = 0; - cal1_retry = 0; - while (1) { - /* one shot */ - rtw_write32(rtwdev, REG_RFECTL_A, 0x00100000); - rtw_write32(rtwdev, REG_RFECTL_B, 0x00100000); - rtw_write32(rtwdev, 0x980, 0xfa000000); - rtw_write32(rtwdev, 0x980, 0xf8000000); - - mdelay(10); - - rtw_write32(rtwdev, REG_RFECTL_A, 0x00000000); - rtw_write32(rtwdev, REG_RFECTL_B, 0x00000000); - - delay_count = 0; - while (1) { - if (!tx0_finish) - iqk0_ready = rtw_read32_mask(rtwdev, 0xd00, BIT(10)); - if (!tx1_finish) - iqk1_ready = rtw_read32_mask(rtwdev, 0xd40, BIT(10)); - if ((iqk0_ready && iqk1_ready) || delay_count > 20) - break; - - mdelay(1); - delay_count++; - } - - rtw_dbg(rtwdev, RTW_DBG_RFK, "TX delay_count = %d\n", delay_count); - - if (delay_count < 20) { /* If 20ms No Result, then cal_retry++ */ - /* ============TXIQK Check============== */ - tx0_fail = rtw_read32_mask(rtwdev, 0xd00, BIT(12)); - tx1_fail = rtw_read32_mask(rtwdev, 0xd40, BIT(12)); - - if (!(tx0_fail || tx0_finish)) { - rtw_write32(rtwdev, REG_RFECTL_A, 0x02000000); - tx_iqc_temp[tx0_average][0] = rtw_read32_mask(rtwdev, 0xd00, 0x07ff0000) << 21; - rtw_write32(rtwdev, REG_RFECTL_A, 0x04000000); - tx_iqc_temp[tx0_average][1] = rtw_read32_mask(rtwdev, 0xd00, 0x07ff0000) << 21; - - rtw_dbg(rtwdev, RTW_DBG_RFK, "tx_x0[%d] = %x ;; tx_y0[%d] = %x\n", - tx0_average, tx_iqc_temp[tx0_average][0] >> 21 & 0x000007ff, - tx0_average, tx_iqc_temp[tx0_average][1] >> 21 & 0x000007ff); - - tx0_average++; - } else { - cal0_retry++; - if (cal0_retry == 10) - break; - } - - if (!(tx1_fail || tx1_finish)) { - rtw_write32(rtwdev, REG_RFECTL_B, 0x02000000); - tx_iqc_temp[tx1_average][2] = rtw_read32_mask(rtwdev, 0xd40, 0x07ff0000) << 21; - rtw_write32(rtwdev, REG_RFECTL_B, 0x04000000); - tx_iqc_temp[tx1_average][3] = rtw_read32_mask(rtwdev, 0xd40, 0x07ff0000) << 21; - - rtw_dbg(rtwdev, RTW_DBG_RFK, - "tx_x1[%d] = %x ;; tx_y1[%d] = %x\n", - tx1_average, - tx_iqc_temp[tx1_average][2] >> 21 & 0x000007ff, - tx1_average, - tx_iqc_temp[tx1_average][3] >> 21 & 0x000007ff); - - tx1_average++; - } else { - cal1_retry++; - if (cal1_retry == 10) - break; - } - } else { - cal0_retry++; - cal1_retry++; - - rtw_dbg(rtwdev, RTW_DBG_RFK, - "delay 20ms TX IQK Not Ready!!!!!\n"); - - if (cal0_retry == 10) - break; - } - - if (tx0_average >= 2) { - for (i = 0; i < tx0_average; i++) { - for (ii = i + 1; ii < tx0_average; ii++) { - dx = (tx_iqc_temp[i][0] >> 21) - (tx_iqc_temp[ii][0] >> 21); - - if (dx < 4 && dx > -4) { - dy = (tx_iqc_temp[i][1] >> 21) - (tx_iqc_temp[ii][1] >> 21); - - if (dy < 4 && dy > -4) { - tx_iqc[0] = ((tx_iqc_temp[i][0] >> 21) + (tx_iqc_temp[ii][0] >> 21)) / 2; - tx_iqc[1] = ((tx_iqc_temp[i][1] >> 21) + (tx_iqc_temp[ii][1] >> 21)) / 2; - - rtw_dbg(rtwdev, RTW_DBG_RFK, "TXA_X = %x;;TXA_Y = %x\n", - tx_iqc[0] & 0x000007ff, tx_iqc[1] & 0x000007ff); - - tx0_finish = true; - } - } - } - } - } - - if (tx1_average >= 2) { - for (i = 0; i < tx1_average; i++) { - for (ii = i + 1; ii < tx1_average; ii++) { - dx = (tx_iqc_temp[i][2] >> 21) - (tx_iqc_temp[ii][2] >> 21); - - if (dx < 4 && dx > -4) { - dy = (tx_iqc_temp[i][3] >> 21) - (tx_iqc_temp[ii][3] >> 21); - - if (dy < 4 && dy > -4) { - tx_iqc[2] = ((tx_iqc_temp[i][2] >> 21) + (tx_iqc_temp[ii][2] >> 21)) / 2; - tx_iqc[3] = ((tx_iqc_temp[i][3] >> 21) + (tx_iqc_temp[ii][3] >> 21)) / 2; - - rtw_dbg(rtwdev, RTW_DBG_RFK, - "TXB_X = %x;;TXB_Y = %x\n", - tx_iqc[2] & 0x000007ff, - tx_iqc[3] & 0x000007ff); - - tx1_finish = true; - } - } - } - } - } - - rtw_dbg(rtwdev, RTW_DBG_RFK, - "tx0_average = %d, tx1_average = %d\n", - tx0_average, tx1_average); - rtw_dbg(rtwdev, RTW_DBG_RFK, - "tx0_finish = %d, tx1_finish = %d\n", - tx0_finish, tx1_finish); - if (tx0_finish && tx1_finish) - break; + if (efuse->ext_pa_5g) + rtw_write32(rtwdev, REG_OFDM0_XB_TX_IQ_IMBALANCE, + 0x821403f7); + else + rtw_write32(rtwdev, REG_OFDM0_XB_TX_IQ_IMBALANCE, + 0x821403e3); - if ((cal0_retry + tx0_average) >= 10 || - (cal1_retry + tx1_average) >= 10) - break; - } + if (hal->current_band_type == RTW_BAND_5G) + rtw_write32(rtwdev, REG_TSSI_TRK_SW, 0x40163e96); + else + rtw_write32(rtwdev, REG_TSSI_TRK_SW, 0x00163e96); - rtw_dbg(rtwdev, RTW_DBG_RFK, "TXA_cal_retry = %d\n", cal0_retry); - rtw_dbg(rtwdev, RTW_DBG_RFK, "TXB_cal_retry = %d\n", cal1_retry); + if (vdf_enable) + rtw8821a_iqk_tx_vdf_true(rtwdev, cal, &tx0iqkok, + tx_x0, tx_y0); + else + rtw8821a_iqk_tx_vdf_false(rtwdev, cal, &tx0iqkok, + tx_x0, tx_y0); - /* [31] = 0 --> Page C */ - rtw_write32_mask(rtwdev, REG_CCASEL, BIT(31), 0x0); - /* Load LOK */ - rtw_write_rf(rtwdev, RF_PATH_A, 0x58, 0x7fe00, - rtw_read_rf(rtwdev, RF_PATH_A, 0x8, 0xffc00)); - rtw_write_rf(rtwdev, RF_PATH_B, 0x58, 0x7fe00, - rtw_read_rf(rtwdev, RF_PATH_B, 0x8, 0xffc00)); - /* [31] = 1 --> Page C1 */ - rtw_write32_mask(rtwdev, REG_CCASEL, BIT(31), 0x1); + if (!tx0iqkok) + break; /* TXK fail, Don't do RXK */ - /* [31] = 0 --> Page C */ - rtw_write32_mask(rtwdev, REG_CCASEL, BIT(31), 0x0); - if (tx0_finish) { - /* ====== path A RX IQK RF setting====== */ + /* ====== RX IQK ====== */ + /* [31] = 0 --> Page C */ + rtw_write32_mask(rtwdev, REG_CCASEL, BIT(31), 0x0); + /* 1. RX RF setting */ rtw_write_rf(rtwdev, RF_PATH_A, RF_LUTWE, RFREG_MASK, 0x80000); - rtw_write_rf(rtwdev, RF_PATH_A, RF_MODE_TABLE_ADDR, RFREG_MASK, 0x30000); - rtw_write_rf(rtwdev, RF_PATH_A, RF_MODE_TABLE_DATA0, RFREG_MASK, 0x3f7ff); - rtw_write_rf(rtwdev, RF_PATH_A, RF_MODE_TABLE_DATA1, RFREG_MASK, 0xfe7bf); - rtw_write_rf(rtwdev, RF_PATH_A, 0x8f, RFREG_MASK, 0x88001); - rtw_write_rf(rtwdev, RF_PATH_A, 0x65, RFREG_MASK, 0x931d1); + rtw_write_rf(rtwdev, RF_PATH_A, RF_MODE_TABLE_ADDR, RFREG_MASK, + 0x30000); + rtw_write_rf(rtwdev, RF_PATH_A, RF_MODE_TABLE_DATA0, RFREG_MASK, + 0x0002f); + rtw_write_rf(rtwdev, RF_PATH_A, RF_MODE_TABLE_DATA1, RFREG_MASK, + 0xfffbb); + rtw_write_rf(rtwdev, RF_PATH_A, RF_RXBB2, RFREG_MASK, 0x88001); + rtw_write_rf(rtwdev, RF_PATH_A, RF_TXA_PREPAD, RFREG_MASK, 0x931d8); rtw_write_rf(rtwdev, RF_PATH_A, RF_LUTWE, RFREG_MASK, 0x00000); - } - if (tx1_finish) { - /* ====== path B RX IQK RF setting====== */ - rtw_write_rf(rtwdev, RF_PATH_B, RF_LUTWE, RFREG_MASK, 0x80000); - rtw_write_rf(rtwdev, RF_PATH_B, RF_MODE_TABLE_ADDR, RFREG_MASK, 0x30000); - rtw_write_rf(rtwdev, RF_PATH_B, RF_MODE_TABLE_DATA0, RFREG_MASK, 0x3f7ff); - rtw_write_rf(rtwdev, RF_PATH_B, RF_MODE_TABLE_DATA1, RFREG_MASK, 0xfe7bf); - rtw_write_rf(rtwdev, RF_PATH_B, 0x8f, RFREG_MASK, 0x88001); - rtw_write_rf(rtwdev, RF_PATH_B, 0x65, RFREG_MASK, 0x931d1); - rtw_write_rf(rtwdev, RF_PATH_B, RF_LUTWE, RFREG_MASK, 0x00000); - } - rtw_write32_mask(rtwdev, 0x978, BIT(31), 0x1); - rtw_write32_mask(rtwdev, 0x97c, BIT(31), 0x0); - rtw_write32(rtwdev, 0x90c, 0x00008000); + rtw_write32_mask(rtwdev, REG_IQK_COM00, 0x03FF8000, + (tx_x0[cal] >> 21) & 0x000007ff); + rtw_write32_mask(rtwdev, REG_IQK_COM00, 0x000007FF, + (tx_y0[cal] >> 21) & 0x000007ff); + rtw_write32_mask(rtwdev, REG_IQK_COM00, BIT(31), 0x1); + rtw_write32_mask(rtwdev, REG_IQK_COM00, BIT(31), 0x0); + rtw_write32(rtwdev, REG_DAC_RSTB, 0x00008000); + rtw_write32(rtwdev, REG_IQK_COM96, 0x0046a911); - if (rtwdev->hci.type == RTW_HCI_TYPE_PCIE) - rtw_write32(rtwdev, 0x984, 0x0046a911); - else - rtw_write32(rtwdev, 0x984, 0x0046a890); - - if (efuse->rfe_option == 1) { - rtw_write32(rtwdev, REG_RFE_PINMUX_A, 0x77777717); - rtw_write32(rtwdev, REG_RFE_INV_A, 0x00000077); - rtw_write32(rtwdev, REG_RFE_PINMUX_B, 0x77777717); - rtw_write32(rtwdev, REG_RFE_INV_B, 0x00000077); - } else { - rtw_write32(rtwdev, REG_RFE_PINMUX_A, 0x77777717); - rtw_write32(rtwdev, REG_RFE_INV_A, 0x02000077); - rtw_write32(rtwdev, REG_RFE_PINMUX_B, 0x77777717); - rtw_write32(rtwdev, REG_RFE_INV_B, 0x02000077); - } + /* [31] = 1 --> Page C1 */ + rtw_write32_mask(rtwdev, REG_CCASEL, BIT(31), 0x1); - /* [31] = 1 --> Page C1 */ - rtw_write32_mask(rtwdev, REG_CCASEL, BIT(31), 0x1); - if (tx0_finish) { /* TX_Tone_idx[9:0], TxK_Mask[29] TX_Tone = 16 */ - rtw_write32(rtwdev, 0xc80, 0x38008c10); + rtw_write32(rtwdev, REG_OFDM0_XA_TX_IQ_IMBALANCE, 0x38008c10); /* RX_Tone_idx[9:0], RxK_Mask[29] */ - rtw_write32(rtwdev, 0xc84, 0x18008c10); - rtw_write32(rtwdev, 0xc88, 0x82140119); - } - if (tx1_finish) { - /* TX_Tone_idx[9:0], TxK_Mask[29] TX_Tone = 16 */ - rtw_write32(rtwdev, 0xe80, 0x38008c10); - /* RX_Tone_idx[9:0], RxK_Mask[29] */ - rtw_write32(rtwdev, 0xe84, 0x18008c10); - rtw_write32(rtwdev, 0xe88, 0x82140119); - } - - cal0_retry = 0; - cal1_retry = 0; - while (1) { - /* one shot */ - /* [31] = 0 --> Page C */ - rtw_write32_mask(rtwdev, REG_CCASEL, BIT(31), 0x0); - if (tx0_finish) { - rtw_write32_mask(rtwdev, 0x978, 0x03FF8000, tx_iqc[0] & 0x000007ff); - rtw_write32_mask(rtwdev, 0x978, 0x000007FF, tx_iqc[1] & 0x000007ff); - /* [31] = 1 --> Page C1 */ - rtw_write32_mask(rtwdev, REG_CCASEL, BIT(31), 0x1); - if (efuse->rfe_option == 1) - rtw_write32(rtwdev, 0xc8c, 0x28161500); - else - rtw_write32(rtwdev, 0xc8c, 0x28160cc0); - rtw_write32(rtwdev, REG_RFECTL_A, 0x00300000); - rtw_write32(rtwdev, REG_RFECTL_A, 0x00100000); - mdelay(5); - rtw_write32(rtwdev, 0xc8c, 0x3c000000); - rtw_write32(rtwdev, REG_RFECTL_A, 0x00000000); - } - if (tx1_finish) { - /* [31] = 0 --> Page C */ - rtw_write32_mask(rtwdev, REG_CCASEL, BIT(31), 0x0); - rtw_write32_mask(rtwdev, 0x978, 0x03FF8000, tx_iqc[2] & 0x000007ff); - rtw_write32_mask(rtwdev, 0x978, 0x000007FF, tx_iqc[3] & 0x000007ff); - /* [31] = 1 --> Page C1 */ - rtw_write32_mask(rtwdev, REG_CCASEL, BIT(31), 0x1); - if (efuse->rfe_option == 1) - rtw_write32(rtwdev, 0xe8c, 0x28161500); - else - rtw_write32(rtwdev, 0xe8c, 0x28160ca0); - rtw_write32(rtwdev, REG_RFECTL_B, 0x00300000); - rtw_write32(rtwdev, REG_RFECTL_B, 0x00100000); - mdelay(5); - rtw_write32(rtwdev, 0xe8c, 0x3c000000); - rtw_write32(rtwdev, REG_RFECTL_B, 0x00000000); - } - - delay_count = 0; - while (1) { - if (!rx0_finish && tx0_finish) - iqk0_ready = rtw_read32_mask(rtwdev, 0xd00, BIT(10)); - if (!rx1_finish && tx1_finish) - iqk1_ready = rtw_read32_mask(rtwdev, 0xd40, BIT(10)); - if ((iqk0_ready && iqk1_ready) || delay_count > 20) - break; - - mdelay(1); - delay_count++; - } - - rtw_dbg(rtwdev, RTW_DBG_RFK, "RX delay_count = %d\n", - delay_count); - - if (delay_count < 20) { /* If 20ms No Result, then cal_retry++ */ - /* ============RXIQK Check============== */ - rx0_fail = rtw_read32_mask(rtwdev, 0xd00, BIT(11)); - rx1_fail = rtw_read32_mask(rtwdev, 0xd40, BIT(11)); - if (!(rx0_fail || rx0_finish) && tx0_finish) { - rtw_write32(rtwdev, REG_RFECTL_A, 0x06000000); - rx_iqc_temp[rx0_average][0] = rtw_read32_mask(rtwdev, 0xd00, 0x07ff0000) << 21; - rtw_write32(rtwdev, REG_RFECTL_A, 0x08000000); - rx_iqc_temp[rx0_average][1] = rtw_read32_mask(rtwdev, 0xd00, 0x07ff0000) << 21; - - rtw_dbg(rtwdev, RTW_DBG_RFK, - "rx_x0[%d] = %x ;; rx_y0[%d] = %x\n", - rx0_average, - (rx_iqc_temp[rx0_average][0]) >> 21 & 0x000007ff, - rx0_average, - (rx_iqc_temp[rx0_average][1]) >> 21 & 0x000007ff); - - rx0_average++; - } else { - rtw_dbg(rtwdev, RTW_DBG_RFK, - "1. RXA_cal_retry = %d\n", cal0_retry); - - cal0_retry++; - if (cal0_retry == 10) - break; - } - - if (!(rx1_fail || rx1_finish) && tx1_finish) { - rtw_write32(rtwdev, REG_RFECTL_B, 0x06000000); - rx_iqc_temp[rx1_average][2] = rtw_read32_mask(rtwdev, 0xd40, 0x07ff0000) << 21; - rtw_write32(rtwdev, REG_RFECTL_B, 0x08000000); - rx_iqc_temp[rx1_average][3] = rtw_read32_mask(rtwdev, 0xd40, 0x07ff0000) << 21; - - rtw_dbg(rtwdev, RTW_DBG_RFK, - "rx_x1[%d] = %x ;; rx_y1[%d] = %x\n", - rx1_average, - (rx_iqc_temp[rx1_average][2]) >> 21 & 0x000007ff, - rx1_average, - (rx_iqc_temp[rx1_average][3]) >> 21 & 0x000007ff); - - rx1_average++; - } else { - cal1_retry++; - if (cal1_retry == 10) - break; - } - } else { - rtw_dbg(rtwdev, RTW_DBG_RFK, - "2. RXA_cal_retry = %d\n", cal0_retry); + rtw_write32(rtwdev, REG_OFDM0_A_TX_AFE, 0x18008c10); + rtw_write32(rtwdev, REG_OFDM0_XB_TX_IQ_IMBALANCE, 0x02140119); - cal0_retry++; - cal1_retry++; + if (rtw_hci_type(rtwdev) == RTW_HCI_TYPE_PCIE) + rx_iqk_loop = 2; /* for 2% fail; */ + else + rx_iqk_loop = 1; - rtw_dbg(rtwdev, RTW_DBG_RFK, - "delay 20ms RX IQK Not Ready!!!!!\n"); + for (i = 0; i < rx_iqk_loop; i++) { + if (rtw_hci_type(rtwdev) == RTW_HCI_TYPE_PCIE && i == 0) + rtw_write32(rtwdev, REG_TSSI_TRK_SW, 0x28161100); /* Good */ + else + rtw_write32(rtwdev, REG_TSSI_TRK_SW, 0x28160d00); - if (cal0_retry == 10) - break; + rtw8821a_iqk_rx(rtwdev, cal, &rx0iqkok, + rx_x0[i], rx_y0[i]); } - rtw_dbg(rtwdev, RTW_DBG_RFK, "3. RXA_cal_retry = %d\n", - cal0_retry); - - if (rx0_average >= 2) { - for (i = 0; i < rx0_average; i++) { - for (ii = i + 1; ii < rx0_average; ii++) { - dx = (rx_iqc_temp[i][0] >> 21) - (rx_iqc_temp[ii][0] >> 21); - - if (dx < 4 && dx > -4) { - dy = (rx_iqc_temp[i][1] >> 21) - (rx_iqc_temp[ii][1] >> 21); - - if (dy < 4 && dy > -4) { - rx_iqc[0] = ((rx_iqc_temp[i][0] >> 21) + (rx_iqc_temp[ii][0] >> 21)) / 2; - rx_iqc[1] = ((rx_iqc_temp[i][1] >> 21) + (rx_iqc_temp[ii][1] >> 21)) / 2; - - rx0_finish = true; - - break; - } - } - } - } - } + if (tx0iqkok) + tx_average++; + if (rx0iqkok) + rx_average++; + } - if (rx1_average >= 2) { - for (i = 0; i < rx1_average; i++) { - for (ii = i + 1; ii < rx1_average; ii++) { - dx = (rx_iqc_temp[i][2] >> 21) - (rx_iqc_temp[ii][2] >> 21); + /* FillIQK Result */ - if (dx < 4 && dx > -4) { - dy = (rx_iqc_temp[i][3] >> 21) - (rx_iqc_temp[ii][3] >> 21); + if (tx_average == 0) + return; - if (dy < 4 && dy > -4) { - rx_iqc[2] = ((rx_iqc_temp[i][2] >> 21) + (rx_iqc_temp[ii][2] >> 21)) / 2; - rx_iqc[3] = ((rx_iqc_temp[i][3] >> 21) + (rx_iqc_temp[ii][3] >> 21)) / 2; + for (i = 0; i < tx_average; i++) + rtw_dbg(rtwdev, RTW_DBG_RFK, + "tx_x0[%d] = %x ;; tx_y0[%d] = %x\n", + i, (tx_x0[i] >> 21) & 0x000007ff, + i, (tx_y0[i] >> 21) & 0x000007ff); - rx1_finish = true; + if (rtw88xxa_iqk_finish(tx_average, 3, tx_x0, tx_y0, + &tx_x, &tx_y, true, true)) + rtw8821a_iqk_tx_fill(rtwdev, tx_x, tx_y); + else + rtw8821a_iqk_tx_fill(rtwdev, 0x200, 0x0); - break; - } - } - } - } - } + if (rx_average == 0) + return; + for (i = 0; i < rx_average; i++) { rtw_dbg(rtwdev, RTW_DBG_RFK, - "rx0_average = %d, rx1_average = %d\n", - rx0_average, rx1_average); - rtw_dbg(rtwdev, RTW_DBG_RFK, - "rx0_finish = %d, rx1_finish = %d\n", - rx0_finish, rx1_finish); - - if ((rx0_finish || !tx0_finish) && (rx1_finish || !tx1_finish)) - break; + "rx_x0[0][%d] = %x ;; rx_y0[0][%d] = %x\n", + i, (rx_x0[0][i] >> 21) & 0x000007ff, + i, (rx_y0[0][i] >> 21) & 0x000007ff); - if ((cal0_retry + rx0_average) >= 10 || - (cal1_retry + rx1_average) >= 10 || - rx0_average == 3 || rx1_average == 3) - break; + if (rx_iqk_loop == 2) + rtw_dbg(rtwdev, RTW_DBG_RFK, + "rx_x0[1][%d] = %x ;; rx_y0[1][%d] = %x\n", + i, (rx_x0[1][i] >> 21) & 0x000007ff, + i, (rx_y0[1][i] >> 21) & 0x000007ff); } - rtw_dbg(rtwdev, RTW_DBG_RFK, "RXA_cal_retry = %d\n", cal0_retry); - rtw_dbg(rtwdev, RTW_DBG_RFK, "RXB_cal_retry = %d\n", cal1_retry); - - /* FillIQK Result */ - rtw_dbg(rtwdev, RTW_DBG_RFK, "========Path_A =======\n"); - - if (tx0_finish) - rtw8812a_iqk_tx_fill(rtwdev, RF_PATH_A, tx_iqc[0], tx_iqc[1]); - else - rtw8812a_iqk_tx_fill(rtwdev, RF_PATH_A, 0x200, 0x0); + rx_finish1 = rtw88xxa_iqk_finish(rx_average, 4, rx_x0[0], rx_y0[0], + &rx_x_temp, &rx_y_temp, true, true); - if (rx0_finish) - rtw8812a_iqk_rx_fill(rtwdev, RF_PATH_A, rx_iqc[0], rx_iqc[1]); - else - rtw8812a_iqk_rx_fill(rtwdev, RF_PATH_A, 0x200, 0x0); + if (rx_finish1) { + rx_x = rx_x_temp; + rx_y = rx_y_temp; + } - rtw_dbg(rtwdev, RTW_DBG_RFK, "========Path_B =======\n"); + if (rx_iqk_loop == 2) { + rx_finish2 = rtw88xxa_iqk_finish(rx_average, 4, + rx_x0[1], rx_y0[1], + &rx_x, &rx_y, true, true); - if (tx1_finish) - rtw8812a_iqk_tx_fill(rtwdev, RF_PATH_B, tx_iqc[2], tx_iqc[3]); - else - rtw8812a_iqk_tx_fill(rtwdev, RF_PATH_B, 0x200, 0x0); + if (rx_finish1 && rx_finish2) { + rx_x = (rx_x + rx_x_temp) / 2; + rx_y = (rx_y + rx_y_temp) / 2; + } + } - if (rx1_finish) - rtw8812a_iqk_rx_fill(rtwdev, RF_PATH_B, rx_iqc[2], rx_iqc[3]); + if (rx_finish1 || rx_finish2) + rtw8821a_iqk_rx_fill(rtwdev, rx_x, rx_y); else - rtw8812a_iqk_rx_fill(rtwdev, RF_PATH_B, 0x200, 0x0); + rtw8821a_iqk_rx_fill(rtwdev, 0x200, 0x0); } -#define MACBB_REG_NUM_8812A 9 -#define AFE_REG_NUM_8812A 12 -#define RF_REG_NUM_8812A 3 - -static void rtw8812a_do_iqk(struct rtw_dev *rtwdev) +static void rtw8821a_do_iqk(struct rtw_dev *rtwdev) { - static const u32 backup_macbb_reg[MACBB_REG_NUM_8812A] = { - 0x520, 0x550, 0x808, 0xa04, 0x90c, 0xc00, 0xe00, 0x838, 0x82c + static const u32 backup_macbb_reg[MACBB_REG_NUM_8821A] = { + 0x520, 0x550, 0x808, 0xa04, 0x90c, 0xc00, 0x838, 0x82c }; - static const u32 backup_afe_reg[AFE_REG_NUM_8812A] = { - 0xc5c, 0xc60, 0xc64, 0xc68, 0xcb0, 0xcb4, - 0xe5c, 0xe60, 0xe64, 0xe68, 0xeb0, 0xeb4 + static const u32 backup_afe_reg[AFE_REG_NUM_8821A] = { + 0xc5c, 0xc60, 0xc64, 0xc68 }; - static const u32 backup_rf_reg[RF_REG_NUM_8812A] = { + static const u32 backup_rf_reg[RF_REG_NUM_8821A] = { 0x65, 0x8f, 0x0 }; - u32 macbb_backup[MACBB_REG_NUM_8812A] = {0}; - u32 afe_backup[AFE_REG_NUM_8812A] = {0}; - u32 rfa_backup[RF_REG_NUM_8812A] = {0}; - u32 rfb_backup[RF_REG_NUM_8812A] = {0}; - u32 reg_cb8, reg_eb8; - - rtw8821a_iqk_backup_mac_bb(rtwdev, macbb_backup, - backup_macbb_reg, MACBB_REG_NUM_8812A); - - rtw_write32_set(rtwdev, REG_CCASEL, BIT(31)); - reg_cb8 = rtw_read32(rtwdev, REG_RFECTL_A); - reg_eb8 = rtw_read32(rtwdev, REG_RFECTL_B); - rtw_write32_clr(rtwdev, REG_CCASEL, BIT(31)); - - rtw8821a_iqk_backup_afe(rtwdev, afe_backup, - backup_afe_reg, AFE_REG_NUM_8812A); - rtw8812a_iqk_backup_rf(rtwdev, rfa_backup, rfb_backup, - backup_rf_reg, RF_REG_NUM_8812A); - - rtw8821a_iqk_configure_mac(rtwdev); - - rtw8812a_iqk(rtwdev); + u32 macbb_backup[MACBB_REG_NUM_8821A]; + u32 afe_backup[AFE_REG_NUM_8821A]; + u32 rfa_backup[RF_REG_NUM_8821A]; - rtw8812a_iqk_restore_rf(rtwdev, RF_PATH_A, backup_rf_reg, - rfa_backup, RF_REG_NUM_8812A); - rtw8812a_iqk_restore_rf(rtwdev, RF_PATH_B, backup_rf_reg, - rfb_backup, RF_REG_NUM_8812A); + rtw88xxa_iqk_backup_mac_bb(rtwdev, macbb_backup, + backup_macbb_reg, MACBB_REG_NUM_8821A); + rtw88xxa_iqk_backup_afe(rtwdev, afe_backup, + backup_afe_reg, AFE_REG_NUM_8821A); + rtw8821a_iqk_backup_rf(rtwdev, rfa_backup, + backup_rf_reg, RF_REG_NUM_8821A); - rtw8812a_iqk_restore_afe(rtwdev, afe_backup, - backup_afe_reg, AFE_REG_NUM_8812A); + rtw88xxa_iqk_configure_mac(rtwdev); - rtw_write32_set(rtwdev, REG_CCASEL, BIT(31)); - rtw_write32(rtwdev, REG_RFECTL_A, reg_cb8); - rtw_write32(rtwdev, REG_RFECTL_B, reg_eb8); - rtw_write32_clr(rtwdev, REG_CCASEL, BIT(31)); + rtw8821a_iqk(rtwdev); - rtw8821a_iqk_restore_mac_bb(rtwdev, macbb_backup, - backup_macbb_reg, MACBB_REG_NUM_8812A); + rtw8821a_iqk_restore_rf(rtwdev, backup_rf_reg, + rfa_backup, RF_REG_NUM_8821A); + rtw8821a_iqk_restore_afe(rtwdev, afe_backup, + backup_afe_reg, AFE_REG_NUM_8821A); + rtw88xxa_iqk_restore_mac_bb(rtwdev, macbb_backup, + backup_macbb_reg, MACBB_REG_NUM_8821A); } static void rtw8821a_phy_calibration(struct rtw_dev *rtwdev) { - u8 channel = rtwdev->hal.current_channel; - - if (rtwdev->chip->id == RTW_CHIP_TYPE_8821A) { - rtw8821a_do_iqk(rtwdev); - } else { - rtw8812a_do_iqk(rtwdev); - - /* The official driver wants to do this after connecting - * but before first writing a new igi (phydm_get_new_igi). - * Here seems close enough. - */ - if (channel >= 36 && channel <= 64) - rtw_load_table(rtwdev, &rtw8812a_agc_diff_lb_tbl); - else if (channel >= 100) - rtw_load_table(rtwdev, &rtw8812a_agc_diff_hb_tbl); - } + rtw8821a_do_iqk(rtwdev); } -static void rtw8812a_do_lck(struct rtw_dev *rtwdev) +static void rtw8821a_pwr_track(struct rtw_dev *rtwdev) { - u32 cont_tx, lc_cal, i; - - cont_tx = rtw_read32_mask(rtwdev, REG_SINGLE_TONE_CONT_TX, 0x70000); - - lc_cal = rtw_read_rf(rtwdev, RF_PATH_A, RF_CFGCH, RFREG_MASK); - - if (!cont_tx) - rtw_write8(rtwdev, REG_TXPAUSE, 0xff); - - rtw_write_rf(rtwdev, RF_PATH_A, RF_LCK, BIT(14), 1); - - rtw_write_rf(rtwdev, RF_PATH_A, RF_CFGCH, 0x08000, 1); - - mdelay(150); - - for (i = 0; i < 5; i++) { - if (rtw_read_rf(rtwdev, RF_PATH_A, RF_CFGCH, 0x08000) != 1) - break; + struct rtw_dm_info *dm_info = &rtwdev->dm_info; - mdelay(10); + if (!dm_info->pwr_trk_triggered) { + rtw_write_rf(rtwdev, RF_PATH_A, RF_T_METER, + GENMASK(17, 16), 0x03); + dm_info->pwr_trk_triggered = true; + return; } - if (i == 5) - rtw_dbg(rtwdev, RTW_DBG_RFK, "LCK timed out\n"); - - rtw_write_rf(rtwdev, RF_PATH_A, RF_CFGCH, RFREG_MASK, lc_cal); - - rtw_write_rf(rtwdev, RF_PATH_A, RF_LCK, BIT(14), 0); - - if (!cont_tx) - rtw_write8(rtwdev, REG_TXPAUSE, 0); + rtw88xxa_phy_pwrtrack(rtwdev, NULL, rtw8821a_do_iqk); + dm_info->pwr_trk_triggered = false; +} - rtw_write_rf(rtwdev, RF_PATH_A, RF_CFGCH, RFREG_MASK, lc_cal); +static void rtw8821a_fill_txdesc_checksum(struct rtw_dev *rtwdev, + struct rtw_tx_pkt_info *pkt_info, + u8 *txdesc) +{ + fill_txdesc_checksum_common(txdesc, 16); } static void rtw8821a_coex_cfg_init(struct rtw_dev *rtwdev) @@ -3364,47 +748,44 @@ static void rtw8821a_coex_cfg_ant_switch(struct rtw_dev *rtwdev, u8 ctrl_type, case COEX_SET_ANT_INIT: rtw_write32_clr(rtwdev, REG_LED_CFG, BIT_DPDT_SEL_EN); rtw_write32_set(rtwdev, REG_LED_CFG, BIT_DPDT_WL_SEL); - rtw_write8_set(rtwdev, 0x765, 0x18); + rtw_write8_set(rtwdev, REG_GNT_BT, BIT_PTA_SW_CTL); - rtw_write8_mask(rtwdev, REG_RFE_CTRL8, BIT_MASK_RFE_SEL89, - share_ant ? PTA_CTRL_PIN : DPDT_CTRL_PIN); + rtw_write8(rtwdev, REG_RFE_CTRL8, + share_ant ? PTA_CTRL_PIN : DPDT_CTRL_PIN); rtw_write32_mask(rtwdev, REG_RFE_CTRL8, 0x30000000, 0x1); break; case COEX_SET_ANT_WONLY: rtw_write32_clr(rtwdev, REG_LED_CFG, BIT_DPDT_SEL_EN); rtw_write32_set(rtwdev, REG_LED_CFG, BIT_DPDT_WL_SEL); - rtw_write8_clr(rtwdev, 0x765, 0x18); + rtw_write8_clr(rtwdev, REG_GNT_BT, BIT_PTA_SW_CTL); - rtw_write8_mask(rtwdev, REG_RFE_CTRL8, - BIT_MASK_RFE_SEL89, DPDT_CTRL_PIN); + rtw_write8(rtwdev, REG_RFE_CTRL8, DPDT_CTRL_PIN); rtw_write32_mask(rtwdev, REG_RFE_CTRL8, 0x30000000, 0x1); break; case COEX_SET_ANT_2G: rtw_write32_clr(rtwdev, REG_LED_CFG, BIT_DPDT_SEL_EN); rtw_write32_set(rtwdev, REG_LED_CFG, BIT_DPDT_WL_SEL); - rtw_write8_clr(rtwdev, 0x765, 0x18); + rtw_write8_clr(rtwdev, REG_GNT_BT, BIT_PTA_SW_CTL); - rtw_write8_mask(rtwdev, REG_RFE_CTRL8, BIT_MASK_RFE_SEL89, - share_ant ? PTA_CTRL_PIN : DPDT_CTRL_PIN); + rtw_write8(rtwdev, REG_RFE_CTRL8, + share_ant ? PTA_CTRL_PIN : DPDT_CTRL_PIN); rtw_write32_mask(rtwdev, REG_RFE_CTRL8, 0x30000000, 0x1); break; case COEX_SET_ANT_5G: rtw_write32_clr(rtwdev, REG_LED_CFG, BIT_DPDT_SEL_EN); rtw_write32_set(rtwdev, REG_LED_CFG, BIT_DPDT_WL_SEL); - rtw_write8_set(rtwdev, 0x765, 0x18); + rtw_write8_set(rtwdev, REG_GNT_BT, BIT_PTA_SW_CTL); - rtw_write8_mask(rtwdev, REG_RFE_CTRL8, - BIT_MASK_RFE_SEL89, DPDT_CTRL_PIN); + rtw_write8(rtwdev, REG_RFE_CTRL8, DPDT_CTRL_PIN); rtw_write32_mask(rtwdev, REG_RFE_CTRL8, 0x30000000, share_ant ? 0x2 : 0x1); break; case COEX_SET_ANT_WOFF: rtw_write32_clr(rtwdev, REG_LED_CFG, BIT_DPDT_SEL_EN); rtw_write32_clr(rtwdev, REG_LED_CFG, BIT_DPDT_WL_SEL); - rtw_write8_set(rtwdev, 0x765, 0x18); + rtw_write8_set(rtwdev, REG_GNT_BT, BIT_PTA_SW_CTL); - rtw_write8_mask(rtwdev, REG_RFE_CTRL8, - BIT_MASK_RFE_SEL89, DPDT_CTRL_PIN); + rtw_write8(rtwdev, REG_RFE_CTRL8, DPDT_CTRL_PIN); rtw_write32_mask(rtwdev, REG_RFE_CTRL8, 0x30000000, share_ant ? 0x2 : 0x1); break; @@ -3416,10 +797,12 @@ static void rtw8821a_coex_cfg_ant_switch(struct rtw_dev *rtwdev, u8 ctrl_type, } static void rtw8821a_coex_cfg_gnt_fix(struct rtw_dev *rtwdev) -{} +{ +} static void rtw8821a_coex_cfg_gnt_debug(struct rtw_dev *rtwdev) -{} +{ +} static void rtw8821a_coex_cfg_rfe_type(struct rtw_dev *rtwdev) { @@ -3446,245 +829,50 @@ static void rtw8821a_coex_cfg_wl_tx_power(struct rtw_dev *rtwdev, u8 wl_pwr) } static void rtw8821a_coex_cfg_wl_rx_gain(struct rtw_dev *rtwdev, bool low_gain) -{} - -static void rtw8821a_pwrtrack_set(struct rtw_dev *rtwdev, u8 tx_rate, u8 path) -{ - static const u32 reg_txscale[2] = { REG_TXSCALE_A, REG_TXSCALE_B }; - struct rtw_dm_info *dm_info = &rtwdev->dm_info; - u8 cck_swing_idx, ofdm_swing_idx; - u8 pwr_tracking_limit; - - switch (tx_rate) { - case DESC_RATE1M ... DESC_RATE11M: - pwr_tracking_limit = 32; - break; - case DESC_RATE6M ... DESC_RATE48M: - case DESC_RATEMCS3 ... DESC_RATEMCS4: - case DESC_RATEMCS11 ... DESC_RATEMCS12: - case DESC_RATEVHT1SS_MCS3 ... DESC_RATEVHT1SS_MCS4: - case DESC_RATEVHT2SS_MCS3 ... DESC_RATEVHT2SS_MCS4: - pwr_tracking_limit = 30; - break; - case DESC_RATE54M: - case DESC_RATEMCS5 ... DESC_RATEMCS7: - case DESC_RATEMCS13 ... DESC_RATEMCS15: - case DESC_RATEVHT1SS_MCS5 ... DESC_RATEVHT1SS_MCS6: - case DESC_RATEVHT2SS_MCS5 ... DESC_RATEVHT2SS_MCS6: - pwr_tracking_limit = 28; - break; - case DESC_RATEMCS0 ... DESC_RATEMCS2: - case DESC_RATEMCS8 ... DESC_RATEMCS10: - case DESC_RATEVHT1SS_MCS0 ... DESC_RATEVHT1SS_MCS2: - case DESC_RATEVHT2SS_MCS0 ... DESC_RATEVHT2SS_MCS2: - pwr_tracking_limit = 34; - break; - case DESC_RATEVHT1SS_MCS7: - case DESC_RATEVHT2SS_MCS7: - pwr_tracking_limit = 26; - break; - default: - case DESC_RATEVHT1SS_MCS8: - case DESC_RATEVHT2SS_MCS8: - pwr_tracking_limit = 24; - break; - case DESC_RATEVHT1SS_MCS9: - case DESC_RATEVHT2SS_MCS9: - pwr_tracking_limit = 22; - break; - } - - cck_swing_idx = dm_info->delta_power_index[path] + dm_info->default_cck_index; - ofdm_swing_idx = dm_info->delta_power_index[path] + dm_info->default_ofdm_index; - - if (ofdm_swing_idx > pwr_tracking_limit) { - if (path == RF_PATH_A) - dm_info->txagc_remnant_cck = cck_swing_idx - pwr_tracking_limit; - dm_info->txagc_remnant_ofdm[path] = ofdm_swing_idx - pwr_tracking_limit; - - ofdm_swing_idx = pwr_tracking_limit; - } else if (ofdm_swing_idx == 0) { - if (path == RF_PATH_A) - dm_info->txagc_remnant_cck = cck_swing_idx; - dm_info->txagc_remnant_ofdm[path] = ofdm_swing_idx; - } else { - if (path == RF_PATH_A) - dm_info->txagc_remnant_cck = 0; - dm_info->txagc_remnant_ofdm[path] = 0; - } - - rtw_write32_mask(rtwdev, reg_txscale[path], GENMASK(31, 21), - rtw8821a_txscale_tbl[ofdm_swing_idx]); -} - -static void rtw8821a_phy_pwrtrack(struct rtw_dev *rtwdev) -{ - struct rtw_dm_info *dm_info = &rtwdev->dm_info; - struct rtw_hal *hal = &rtwdev->hal; - struct rtw_swing_table swing_table; - s8 remnant_pre[RTW_RF_PATH_MAX]; - u8 thermal_value, delta, path; - bool need_iqk; - - rtw_phy_config_swing_table(rtwdev, &swing_table); - - if (rtwdev->efuse.thermal_meter[0] == 0xff) { - pr_err_once("efuse thermal meter is 0xff\n"); - return; - } - - thermal_value = rtw_read_rf(rtwdev, RF_PATH_A, RF_T_METER, 0xfc00); - - rtw_phy_pwrtrack_avg(rtwdev, thermal_value, RF_PATH_A); - - need_iqk = rtw_phy_pwrtrack_need_iqk(rtwdev); - - if (rtwdev->chip->id == RTW_CHIP_TYPE_8812A) { - if (need_iqk) - rtw8812a_do_lck(rtwdev); - } - - if (dm_info->pwr_trk_init_trigger) - dm_info->pwr_trk_init_trigger = false; - else if (!rtw_phy_pwrtrack_thermal_changed(rtwdev, thermal_value, - RF_PATH_A)) - goto iqk; - - delta = rtw_phy_pwrtrack_get_delta(rtwdev, RF_PATH_A); - - for (path = RF_PATH_A; path < hal->rf_path_num; path++) { - remnant_pre[path] = dm_info->txagc_remnant_ofdm[path]; - - dm_info->delta_power_index[path] = - rtw_phy_pwrtrack_get_pwridx(rtwdev, &swing_table, path, - RF_PATH_A, delta); - - if (dm_info->delta_power_index[path] != - dm_info->delta_power_index_last[path]) { - dm_info->delta_power_index_last[path] = - dm_info->delta_power_index[path]; - - rtw8821a_pwrtrack_set(rtwdev, dm_info->tx_rate, path); - } - } - - for (path = RF_PATH_A; path < hal->rf_path_num; path++) { - if (remnant_pre[path] != dm_info->txagc_remnant_ofdm[path]) { - rtw_phy_set_tx_power_level(rtwdev, - hal->current_channel); - break; - } - } - -iqk: - if (need_iqk) - rtw8821a_do_iqk(rtwdev); -} - -static void rtw8821a_pwr_track(struct rtw_dev *rtwdev) -{ - struct rtw_dm_info *dm_info = &rtwdev->dm_info; - - if (!dm_info->pwr_trk_triggered) { - rtw_write_rf(rtwdev, RF_PATH_A, RF_T_METER, - GENMASK(17, 16), 0x03); - dm_info->pwr_trk_triggered = true; - return; - } - - rtw8821a_phy_pwrtrack(rtwdev); - dm_info->pwr_trk_triggered = false; -} - -static void rtw8821a_phy_cck_pd_set(struct rtw_dev *rtwdev, u8 new_lvl) -{ - static const u8 pd[CCK_PD_LV_MAX] = {0x40, 0x83, 0xcd, 0xdd, 0xed}; - struct rtw_dm_info *dm_info = &rtwdev->dm_info; - - /* Override rtw_phy_cck_pd_lv_link(). It implements something - * like type 2/3/4. We need type 1 here. - */ - if (rtw_is_assoc(rtwdev)) { - if (dm_info->min_rssi > 60) { - new_lvl = CCK_PD_LV3; - } else if (dm_info->min_rssi > 35) { - new_lvl = CCK_PD_LV2; - } else if (dm_info->min_rssi > 20) { - if (dm_info->cck_fa_avg > 500) - new_lvl = CCK_PD_LV2; - else if (dm_info->cck_fa_avg < 250) - new_lvl = CCK_PD_LV1; - else - return; - } else { - new_lvl = CCK_PD_LV1; - } - } - - rtw_dbg(rtwdev, RTW_DBG_PHY, "lv: (%d) -> (%d)\n", - dm_info->cck_pd_lv[RTW_CHANNEL_WIDTH_20][RF_PATH_A], new_lvl); - - if (dm_info->cck_pd_lv[RTW_CHANNEL_WIDTH_20][RF_PATH_A] == new_lvl) - return; - - dm_info->cck_fa_avg = CCK_FA_AVG_RESET; - dm_info->cck_pd_lv[RTW_CHANNEL_WIDTH_20][RF_PATH_A] = new_lvl; - - rtw_write8(rtwdev, 0xa0a, pd[new_lvl]); -} - -static void rtw8821a_fill_txdesc_checksum(struct rtw_dev *rtwdev, - struct rtw_tx_pkt_info *pkt_info, - u8 *txdesc) { - fill_txdesc_checksum_common(txdesc, 16); } -static const struct rtw_intf_phy_para usb2_param_8821a[] = { - {0xFFFF, 0x00, - RTW_IP_SEL_PHY, - RTW_INTF_PHY_CUT_ALL, - RTW_INTF_PHY_PLATFORM_ALL}, -}; - -static const struct rtw_intf_phy_para usb3_param_8821a[] = { - {0xFFFF, 0x0000, - RTW_IP_SEL_PHY, - RTW_INTF_PHY_CUT_ALL, - RTW_INTF_PHY_PLATFORM_ALL}, -}; - -static const struct rtw_intf_phy_para_table phy_para_table_8821a = { - .usb2_para = usb2_param_8821a, - .usb3_para = usb3_param_8821a, - .n_usb2_para = ARRAY_SIZE(usb2_param_8821a), - .n_usb3_para = ARRAY_SIZE(usb2_param_8821a), -}; - -static struct rtw_hw_reg rtw8821a_dig[] = { - [0] = { .addr = 0xc50, .mask = 0x7f }, - [1] = { .addr = 0xe50, .mask = 0x7f }, +static const struct rtw_chip_ops rtw8821a_ops = { + .power_on = rtw88xxa_power_on, + .power_off = rtw8821a_power_off, + .phy_set_param = NULL, + .read_efuse = rtw88xxa_read_efuse, + .query_phy_status = rtw8821a_query_phy_status, + .set_channel = rtw88xxa_set_channel, + .mac_init = NULL, + .read_rf = rtw88xxa_phy_read_rf, + .write_rf = rtw_phy_write_rf_reg_sipi, + .set_antenna = NULL, + .set_tx_power_index = rtw88xxa_set_tx_power_index, + .cfg_ldo25 = rtw8821a_cfg_ldo25, + .efuse_grant = rtw88xxa_efuse_grant, + .false_alarm_statistics = rtw88xxa_false_alarm_statistics, + .phy_calibration = rtw8821a_phy_calibration, + .cck_pd_set = rtw88xxa_phy_cck_pd_set, + .pwr_track = rtw8821a_pwr_track, + .config_bfee = NULL, + .set_gid_table = NULL, + .cfg_csi_rate = NULL, + .fill_txdesc_checksum = rtw8821a_fill_txdesc_checksum, + .coex_set_init = rtw8821a_coex_cfg_init, + .coex_set_ant_switch = rtw8821a_coex_cfg_ant_switch, + .coex_set_gnt_fix = rtw8821a_coex_cfg_gnt_fix, + .coex_set_gnt_debug = rtw8821a_coex_cfg_gnt_debug, + .coex_set_rfe_type = rtw8821a_coex_cfg_rfe_type, + .coex_set_wl_tx_power = rtw8821a_coex_cfg_wl_tx_power, + .coex_set_wl_rx_gain = rtw8821a_coex_cfg_wl_rx_gain, }; -static struct rtw_page_table page_table_8821a[] = { +static const struct rtw_page_table page_table_8821a[] = { /* hq_num, nq_num, lq_num, exq_num, gapq_num */ - {0, 0, 0, 0, 0}, /* unused by USB */ - {0, 0, 0, 0, 0}, /* unused by USB */ + {0, 0, 0, 0, 0}, /* SDIO */ + {0, 0, 0, 0, 0}, /* PCI */ {8, 0, 0, 0, 1}, /* 2 bulk out endpoints */ {8, 0, 8, 0, 1}, /* 3 bulk out endpoints */ {8, 0, 8, 4, 1}, /* 4 bulk out endpoints */ }; -static struct rtw_page_table page_table_8812a[] = { - /* hq_num, nq_num, lq_num, exq_num, gapq_num */ - {0, 0, 0, 0, 0}, /* unused by USB */ - {0, 0, 0, 0, 0}, /* unused by USB */ - {16, 0, 0, 0, 1}, /* 2 bulk out endpoints */ - {16, 0, 16, 0, 1}, /* 3 bulk out endpoints */ - {16, 0, 16, 0, 1}, /* 4 bulk out endpoints */ -}; - -static struct rtw_rqpn rqpn_table_8821a[] = { +static const struct rtw_rqpn rqpn_table_8821a[] = { {RTW_DMA_MAPPING_NORMAL, RTW_DMA_MAPPING_NORMAL, RTW_DMA_MAPPING_LOW, RTW_DMA_MAPPING_LOW, RTW_DMA_MAPPING_EXTRA, RTW_DMA_MAPPING_HIGH}, @@ -3706,7 +894,7 @@ static struct rtw_rqpn rqpn_table_8821a[] = { RTW_DMA_MAPPING_EXTRA, RTW_DMA_MAPPING_HIGH}, }; -static struct rtw_prioq_addrs prioq_addrs_8821a = { +static const struct rtw_prioq_addrs prioq_addrs_8821a = { .prio[RTW_DMA_MAPPING_EXTRA] = { .rsvd = REG_RQPN_NPQ + 2, .avail = REG_RQPN_NPQ + 3, }, @@ -3722,38 +910,17 @@ static struct rtw_prioq_addrs prioq_addrs_8821a = { .wsize = false, }; -static struct rtw_chip_ops rtw8821a_ops = { - .power_on = rtw8821a_power_on, - .power_off = rtw8821a_power_off, - .phy_set_param = NULL, - .read_efuse = rtw8821a_read_efuse, - .query_phy_status = rtw8821a_query_phy_status, - .set_channel = rtw8821a_set_channel, - .mac_init = NULL, - .read_rf = rtw8821a_phy_read_rf, - .write_rf = rtw_phy_write_rf_reg_sipi, - .set_antenna = NULL, - .set_tx_power_index = rtw8821a_set_tx_power_index, - .cfg_ldo25 = rtw8821a_cfg_ldo25, - .efuse_grant = rtw8821a_efuse_grant, - .false_alarm_statistics = rtw8821a_false_alarm_statistics, - .phy_calibration = rtw8821a_phy_calibration, - .cck_pd_set = rtw8821a_phy_cck_pd_set, - .pwr_track = rtw8821a_pwr_track, - .config_bfee = NULL, - .set_gid_table = NULL, - .cfg_csi_rate = NULL, - .fill_txdesc_checksum = rtw8821a_fill_txdesc_checksum, - .coex_set_init = rtw8821a_coex_cfg_init, - .coex_set_ant_switch = rtw8821a_coex_cfg_ant_switch, - .coex_set_gnt_fix = rtw8821a_coex_cfg_gnt_fix, - .coex_set_gnt_debug = rtw8821a_coex_cfg_gnt_debug, - .coex_set_rfe_type = rtw8821a_coex_cfg_rfe_type, - .coex_set_wl_tx_power = rtw8821a_coex_cfg_wl_tx_power, - .coex_set_wl_rx_gain = rtw8821a_coex_cfg_wl_rx_gain, +static const struct rtw_hw_reg rtw8821a_dig[] = { + [0] = { .addr = REG_RXIGI_A, .mask = 0x7f }, +}; + +static const struct rtw_rfe_def rtw8821a_rfe_defs[] = { + [0] = { .phy_pg_tbl = &rtw8821a_bb_pg_tbl, + .txpwr_lmt_tbl = &rtw8821a_txpwr_lmt_tbl, + .pwr_track_tbl = &rtw8821a_rtw_pwr_track_tbl, }, }; -///TODO +/* TODO */ /* rssi in percentage % (dbm = % - 100) */ static const u8 wl_rssi_step_8821a[] = {101, 45, 101, 40}; static const u8 bt_rssi_step_8821a[] = {101, 101, 101, 101}; @@ -3892,9 +1059,7 @@ static const struct coex_tdma_para tdma_nsant_8821a[] = { { {0x51, 0x10, 0x03, 0x10, 0x50} } }; -static const struct coex_5g_afh_map afh_5g_8821a[] = { {0, 0, 0} }; - -///TODO +/* TODO */ static const struct coex_rf_para rf_para_tx_8821a[] = { {0, 0, false, 7}, /* for normal */ {0, 20, false, 7}, /* for WL-CPT */ @@ -3915,23 +1080,7 @@ static const struct coex_rf_para rf_para_rx_8821a[] = { static_assert(ARRAY_SIZE(rf_para_tx_8821a) == ARRAY_SIZE(rf_para_rx_8821a)); -static const struct rtw_rfe_def rtw8821a_rfe_defs[] = { - [0] = { .phy_pg_tbl = &rtw8821a_bb_pg_tbl, - .txpwr_lmt_tbl = &rtw8821a_txpwr_lmt_tbl, - .pwr_track_tbl = &rtw8821a_rtw_pwr_track_tbl, }, -}; - -static const struct rtw_rfe_def rtw8812a_rfe_defs[] = { - [0] = { .phy_pg_tbl = &rtw8812a_bb_pg_tbl, - .txpwr_lmt_tbl = &rtw8812a_txpwr_lmt_tbl, - .pwr_track_tbl = &rtw8812a_rtw_pwr_track_tbl, }, - [1] = { .phy_pg_tbl = &rtw8812a_bb_pg_tbl, - .txpwr_lmt_tbl = &rtw8812a_txpwr_lmt_tbl, - .pwr_track_tbl = &rtw8812a_rtw_pwr_track_tbl, }, - [3] = { .phy_pg_tbl = &rtw8812a_bb_pg_rfe3_tbl, - .txpwr_lmt_tbl = &rtw8812a_txpwr_lmt_tbl, - .pwr_track_tbl = &rtw8812a_rtw_pwr_track_rfe3_tbl, }, -}; +static const struct coex_5g_afh_map afh_5g_8821a[] = { {0, 0, 0} }; static const struct rtw_reg_domain coex_info_hw_regs_8821a[] = { {0xCB0, MASKDWORD, RTW_REG_DOMAIN_MAC32}, @@ -3962,14 +1111,14 @@ const struct rtw_chip_info rtw8821a_hw_spec = { .ops = &rtw8821a_ops, .id = RTW_CHIP_TYPE_8821A, .fw_name = "rtw88/rtw8821a_fw.bin", - .wlan_cpu = RTW_WCPU_11N, ///TODO maybe RTW_WCPU_11N should be renamed to RTW_WCPU_8051 and RTW_WCPU_11AC to RTW_WCPU_3081 + .wlan_cpu = RTW_WCPU_11N, .tx_pkt_desc_sz = 40, .tx_buf_desc_sz = 16, .rx_pkt_desc_sz = 24, .rx_buf_desc_sz = 8, .phy_efuse_size = 512, .log_efuse_size = 512, - .ptct_efuse_size = 96 + 1,///TODO or just 18? + .ptct_efuse_size = 96 + 1, /* TODO or just 18? */ .txff_size = 65536, .rxff_size = 16128, .rsvd_drv_pg_num = 8, @@ -3989,7 +1138,7 @@ const struct rtw_chip_info rtw8821a_hw_spec = { .page_table = page_table_8821a, .rqpn_table = rqpn_table_8821a, .prioq_addrs = &prioq_addrs_8821a, - .intf_table = &phy_para_table_8821a, + .intf_table = NULL, .dig = rtw8821a_dig, .rf_sipi_addr = {REG_LSSI_WRITE_A, REG_LSSI_WRITE_B}, .ltecoex_addr = NULL, @@ -4005,8 +1154,6 @@ const struct rtw_chip_info rtw8821a_hw_spec = { .old_datarate_fb_limit = true, .usb_tx_agg_desc_num = 6, .iqk_threshold = 8, - // .bfer_su_max_num = 2, - // .bfer_mu_max_num = 1, .ampdu_density = IEEE80211_HT_MPDU_DENSITY_16, .max_scan_ie_len = IEEE80211_MAX_DATA_LEN, @@ -4043,94 +1190,8 @@ const struct rtw_chip_info rtw8821a_hw_spec = { }; EXPORT_SYMBOL(rtw8821a_hw_spec); -const struct rtw_chip_info rtw8812a_hw_spec = { - .ops = &rtw8821a_ops, - .id = RTW_CHIP_TYPE_8812A, - .fw_name = "rtw88/rtw8812a_fw.bin", - .wlan_cpu = RTW_WCPU_11N, - .tx_pkt_desc_sz = 40, - .tx_buf_desc_sz = 16, - .rx_pkt_desc_sz = 24, - .rx_buf_desc_sz = 8, - .phy_efuse_size = 512, - .log_efuse_size = 512, - .ptct_efuse_size = 96 + 1,///TODO or just 18? - .txff_size = 131072, - .rxff_size = 16128, - .rsvd_drv_pg_num = 9, - .txgi_factor = 1, - .is_pwr_by_rate_dec = true, - .max_power_index = 0x3f, - .csi_buf_pg_num = 0, - .band = RTW_BAND_2G | RTW_BAND_5G, - .page_size = 512, - .dig_min = 0x20, - .ht_supported = true, - .vht_supported = true, - .lps_deep_mode_supported = 0, - .sys_func_en = 0xFD, - .pwr_on_seq = card_enable_flow_8812a, - .pwr_off_seq = card_disable_flow_8812a, - .page_table = page_table_8812a, - .rqpn_table = rqpn_table_8821a, - .prioq_addrs = &prioq_addrs_8821a, - .intf_table = &phy_para_table_8821a, - .dig = rtw8821a_dig, - .rf_sipi_addr = {REG_LSSI_WRITE_A, REG_LSSI_WRITE_B}, - .ltecoex_addr = NULL, - .mac_tbl = &rtw8812a_mac_tbl, - .agc_tbl = &rtw8812a_agc_tbl, - .bb_tbl = &rtw8812a_bb_tbl, - .rf_tbl = {&rtw8812a_rf_a_tbl, &rtw8812a_rf_b_tbl}, - .rfe_defs = rtw8812a_rfe_defs, - .rfe_defs_size = ARRAY_SIZE(rtw8812a_rfe_defs), - .rx_ldpc = false, - .hw_feature_report = false, - .c2h_ra_report_size = 4, - .old_datarate_fb_limit = true, - .usb_tx_agg_desc_num = 1, - .iqk_threshold = 8, - // .bfer_su_max_num = 2, - // .bfer_mu_max_num = 1, - .ampdu_density = IEEE80211_HT_MPDU_DENSITY_16, - .max_scan_ie_len = IEEE80211_MAX_DATA_LEN, - - .coex_para_ver = 0, /* no coex code in 8812au driver */ - .bt_desired_ver = 0, - .scbd_support = false, - .new_scbd10_def = false, - .ble_hid_profile_support = false, - .wl_mimo_ps_support = false, - .pstdma_type = COEX_PSTDMA_FORCE_LPSOFF, - .bt_rssi_type = COEX_BTRSSI_RATIO, - .ant_isolation = 15, - .rssi_tolerance = 2, - .wl_rssi_step = wl_rssi_step_8821a, - .bt_rssi_step = bt_rssi_step_8821a, - .table_sant_num = 0, - .table_sant = NULL, - .table_nsant_num = 0, - .table_nsant = NULL, - .tdma_sant_num = 0, - .tdma_sant = NULL, - .tdma_nsant_num = 0, - .tdma_nsant = NULL, - .wl_rf_para_num = ARRAY_SIZE(rf_para_tx_8821a), - .wl_rf_para_tx = rf_para_tx_8821a, - .wl_rf_para_rx = rf_para_rx_8821a, - .bt_afh_span_bw20 = 0x20, - .bt_afh_span_bw40 = 0x30, - .afh_5g_num = 0, - .afh_5g = NULL, - - .coex_info_hw_regs_num = 0, - .coex_info_hw_regs = NULL, -}; -EXPORT_SYMBOL(rtw8812a_hw_spec); - MODULE_FIRMWARE("rtw88/rtw8821a_fw.bin"); -MODULE_FIRMWARE("rtw88/rtw8812a_fw.bin"); MODULE_AUTHOR("Realtek Corporation"); -MODULE_DESCRIPTION("Realtek 802.11ac wireless 8821a/8811a/8812a driver"); +MODULE_DESCRIPTION("Realtek 802.11ac wireless 8821a/8811a driver"); MODULE_LICENSE("Dual BSD/GPL"); diff --git a/rtw8821a.h b/rtw8821a.h index 6f2f293a..1b2e548f 100644 --- a/rtw8821a.h +++ b/rtw8821a.h @@ -1,383 +1,10 @@ /* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */ -/* Copyright(c) 2018-2019 Realtek Corporation +/* Copyright(c) 2024 Realtek Corporation */ #ifndef __RTW8821A_H__ #define __RTW8821A_H__ -#include - -struct rtw8821au_efuse { - u8 res4[48]; /* 0xd0 */ - u8 vid[2]; /* 0x100 */ - u8 pid[2]; - u8 res8[3]; - u8 mac_addr[ETH_ALEN]; /* 0x107 */ - u8 res9[243]; -}; - -struct rtw8812au_efuse { - u8 vid[2]; /* 0xd0 */ - u8 pid[2]; /* 0xd2 */ - u8 res0[3]; - u8 mac_addr[ETH_ALEN]; /* 0xd7 */ - u8 res1[291]; -}; - -struct rtw8821a_efuse { - __le16 rtl_id; - u8 res0[6]; /* 0x02 */ - u8 usb_mode; /* 0x08 */ - u8 res1[7]; /* 0x09 */ - - /* power index for four RF paths */ - struct rtw_txpwr_idx txpwr_idx_table[4]; - - u8 channel_plan; /* 0xb8 */ - u8 xtal_k; - u8 thermal_meter; - u8 iqk_lck; - u8 pa_type; /* 0xbc */ - u8 lna_type_2g; /* 0xbd */ - u8 res2; - u8 lna_type_5g; /* 0xbf */ - u8 res3; - u8 rf_board_option; /* 0xc1 */ - u8 rf_feature_option; - u8 rf_bt_setting; - u8 eeprom_version; - u8 eeprom_customer_id; /* 0xc5 */ - u8 tx_bb_swing_setting_2g; - u8 tx_bb_swing_setting_5g; - u8 tx_pwr_calibrate_rate; - u8 rf_antenna_option; /* 0xc9 */ - u8 rfe_option; - u8 country_code[2]; - u8 res4[3]; - union { - struct rtw8821au_efuse rtw8821au; - struct rtw8812au_efuse rtw8812au; - }; -} __packed; - -static_assert(sizeof(struct rtw8821a_efuse) == 512); - extern const struct rtw_chip_info rtw8821a_hw_spec; -extern const struct rtw_chip_info rtw8812a_hw_spec; - -#define BIT_FEN_USBA BIT(2) -#define BIT_FEN_PCIEA BIT(6) -#define WLAN_SLOT_TIME 0x09 -#define WLAN_PIFS_TIME 0x19 -#define WLAN_SIFS_CCK_CONT_TX 0xA -#define WLAN_SIFS_OFDM_CONT_TX 0xE -#define WLAN_SIFS_CCK_TRX 0x10 -#define WLAN_SIFS_OFDM_TRX 0x10 -#define WLAN_VO_TXOP_LIMIT 0x186 -#define WLAN_VI_TXOP_LIMIT 0x3BC -#define WLAN_RDG_NAV 0x05 -#define WLAN_TXOP_NAV 0x1B -#define WLAN_CCK_RX_TSF 0x30 -#define WLAN_OFDM_RX_TSF 0x30 -#define WLAN_TBTT_PROHIBIT 0x04 -#define WLAN_TBTT_HOLD_TIME 0x064 -#define WLAN_DRV_EARLY_INT 0x04 -#define WLAN_BCN_DMA_TIME 0x02 - -#define WLAN_RX_FILTER0 0x0FFFFFFF -#define WLAN_RX_FILTER2 0xFFFF -#define WLAN_RCR_CFG 0xE400220E -#define WLAN_RXPKT_MAX_SZ 12288 -#define WLAN_RXPKT_MAX_SZ_512 (WLAN_RXPKT_MAX_SZ >> 9) - -#define WLAN_AMPDU_MAX_TIME 0x70 -#define WLAN_RTS_LEN_TH 0xFF -#define WLAN_RTS_TX_TIME_TH 0x08 -#define WLAN_MAX_AGG_PKT_LIMIT 0x20 -#define WLAN_RTS_MAX_AGG_PKT_LIMIT 0x20 -#define FAST_EDCA_VO_TH 0x06 -#define FAST_EDCA_VI_TH 0x06 -#define FAST_EDCA_BE_TH 0x06 -#define FAST_EDCA_BK_TH 0x06 -#define WLAN_BAR_RETRY_LIMIT 0x01 -#define WLAN_RA_TRY_RATE_AGG_LIMIT 0x08 - -#define WLAN_TX_FUNC_CFG1 0x30 -#define WLAN_TX_FUNC_CFG2 0x30 -#define WLAN_MAC_OPT_NORM_FUNC1 0x98 -#define WLAN_MAC_OPT_LB_FUNC1 0x80 -#define WLAN_MAC_OPT_FUNC2 0xb0810041 - -#define WLAN_SIFS_CFG (WLAN_SIFS_CCK_CONT_TX | \ - (WLAN_SIFS_OFDM_CONT_TX << BIT_SHIFT_SIFS_OFDM_CTX) | \ - (WLAN_SIFS_CCK_TRX << BIT_SHIFT_SIFS_CCK_TRX) | \ - (WLAN_SIFS_OFDM_TRX << BIT_SHIFT_SIFS_OFDM_TRX)) - -#define WLAN_TBTT_TIME (WLAN_TBTT_PROHIBIT |\ - (WLAN_TBTT_HOLD_TIME << BIT_SHIFT_TBTT_HOLD_TIME_AP)) - -#define WLAN_NAV_CFG (WLAN_RDG_NAV | (WLAN_TXOP_NAV << 16)) -#define WLAN_RX_TSF_CFG (WLAN_CCK_RX_TSF | (WLAN_OFDM_RX_TSF) << 8) -#define WLAN_PRE_TXCNT_TIME_TH 0x1E4 - - -struct rtw8821a_phy_status_rpt { - /* DWORD 0*/ - u8 gain_trsw[2]; /*path-A and path-B {TRSW, gain[6:0] }*/ - u8 chl_num_lsb; /*@channel number[7:0]*/ -#ifdef __LITTLE_ENDIAN - u8 chl_num_msb : 2; /*@channel number[9:8]*/ - u8 sub_chnl : 4; /*sub-channel location[3:0]*/ - u8 r_rfmod : 2; /*RF mode[1:0]*/ -#else /*@_BIG_ENDIAN_ */ - u8 r_rfmod : 2; - u8 sub_chnl : 4; - u8 chl_num_msb : 2; -#endif - - /* @DWORD 1*/ - u8 pwdb_all; /*@CCK signal quality / OFDM pwdb all*/ - s8 cfosho[2]; /*@CCK AGC report and CCK_BB_Power*/ - /*OFDM path-A and path-B short CFO*/ -#ifdef __LITTLE_ENDIAN - u8 resvd_0 : 6; - u8 bt_rf_ch_msb : 2; /*@8812A:2'b0 8814A: bt rf channel keep[7:6]*/ -#else /*@_BIG_ENDIAN_*/ - u8 bt_rf_ch_msb : 2; - u8 resvd_0 : 6; -#endif - -/* @DWORD 2*/ -#ifdef __LITTLE_ENDIAN - u8 ant_div_sw_a : 1; /*@8812A: ant_div_sw_a 8814A: 1'b0*/ - u8 ant_div_sw_b : 1; /*@8812A: ant_div_sw_b 8814A: 1'b0*/ - u8 bt_rf_ch_lsb : 6; /*@8812A: 6'b0 8814A: bt rf channel keep[5:0]*/ -#else /*@_BIG_ENDIAN_ */ - u8 bt_rf_ch_lsb : 6; - u8 ant_div_sw_b : 1; - u8 ant_div_sw_a : 1; -#endif - s8 cfotail[2]; /*@DW2 byte 1 DW2 byte 2 path-A and path-B CFO tail*/ - u8 pcts_msk_rpt_0; /*PCTS mask report[7:0]*/ - u8 pcts_msk_rpt_1; /*PCTS mask report[15:8]*/ - - /* @DWORD 3*/ - s8 rxevm[2]; /*@DW3 byte 1 DW3 byte 2 stream 1 and stream 2 RX EVM*/ - s8 rxsnr[2]; /*@DW3 byte 3 DW4 byte 0 path-A and path-B RX SNR*/ - - /* @DWORD 4*/ - u8 pcts_msk_rpt_2; /*PCTS mask report[23:16]*/ -#ifdef __LITTLE_ENDIAN - u8 pcts_msk_rpt_3 : 6; /*PCTS mask report[29:24]*/ - u8 pcts_rpt_valid : 1; /*pcts_rpt_valid*/ - u8 resvd_1 : 1; /*@1'b0*/ -#else /*@_BIG_ENDIAN_*/ - u8 resvd_1 : 1; - u8 pcts_rpt_valid : 1; - u8 pcts_msk_rpt_3 : 6; -#endif - s8 rxevm_cd[2]; /*@8812A: 16'b0*/ - /*@8814A: stream 3 and stream 4 RX EVM*/ - /* @DWORD 5*/ - u8 csi_current[2]; /*@8812A: stream 1 and 2 CSI*/ - /*@8814A: path-C and path-D RX SNR*/ - u8 gain_trsw_cd[2]; /*path-C and path-D {TRSW, gain[6:0] }*/ - - /* @DWORD 6*/ - s8 sigevm; /*signal field EVM*/ -#ifdef __LITTLE_ENDIAN - u8 antidx_antc : 3; /*@8812A: 3'b0 8814A: antidx_antc[2:0]*/ - u8 antidx_antd : 3; /*@8812A: 3'b0 8814A: antidx_antd[2:0]*/ - u8 dpdt_ctrl_keep : 1; /*@8812A: 1'b0 8814A: dpdt_ctrl_keep*/ - u8 gnt_bt_keep : 1; /*@8812A: 1'b0 8814A: GNT_BT_keep*/ -#else /*@_BIG_ENDIAN_*/ - u8 gnt_bt_keep : 1; - u8 dpdt_ctrl_keep : 1; - u8 antidx_antd : 3; - u8 antidx_antc : 3; -#endif -#ifdef __LITTLE_ENDIAN - u8 antidx_anta : 3; /*@antidx_anta[2:0]*/ - u8 antidx_antb : 3; /*@antidx_antb[2:0]*/ - u8 hw_antsw_occur : 2; /*@1'b0*/ -#else /*@_BIG_ENDIAN_*/ - u8 hw_antsw_occur : 2; - u8 antidx_antb : 3; - u8 antidx_anta : 3; -#endif -}; - -#define REG_SYS_CTRL 0x000 -#define BIT_FEN_EN BIT(26) -#define REG_APS_FSMCO 0x04 -#define APS_FSMCO_MAC_ENABLE BIT(8) -#define APS_FSMCO_MAC_OFF BIT(9) -#define APS_FSMCO_HW_POWERDOWN BIT(15) -#define REG_ACLK_MON 0x3e -#define REG_RF_B_CTRL 0x76 -#define REG_HIMR0 0xb0 -#define REG_HISR0 0xb4 -#define REG_HIMR1 0xb8 -#define REG_HISR1 0xbc -#define HCI_TXDMA_EN BIT(0) -#define HCI_RXDMA_EN BIT(1) -#define TXDMA_EN BIT(2) -#define RXDMA_EN BIT(3) -#define PROTOCOL_EN BIT(4) -#define SCHEDULE_EN BIT(5) -#define MACTXEN BIT(6) -#define MACRXEN BIT(7) -#define ENSWBCN BIT(8) -#define ENSEC BIT(9) -#define CALTMR_EN BIT(10) /* 32k CAL TMR enable */ -#define REG_MSR 0x102 -#define REG_PBP 0x104 -#define PBP_RX_MASK 0x0f -#define PBP_TX_MASK 0xf0 -#define PBP_64 0x0 -#define PBP_128 0x1 -#define PBP_256 0x2 -#define PBP_512 0x3 -#define PBP_1024 0x4 -#define REG_LLT_INIT 0x01E0 -#define BIT_LLT_WRITE_ACCESS BIT(30) -#define REG_DWBCN1_CTRL 0x228 -#define REG_EARLY_MODE_CONTROL 0x2bc -#define REG_TXPKT_EMPTY 0x41a -#define REG_AMPDU_MAX_LENGTH 0x458 -#define REG_FAST_EDCA_CTRL 0x460 -#define REG_TX_RPT_CTRL 0x4ec -#define REG_TX_RPT_TIME 0x4f0 -#define REG_BCNTCFG 0x510 -#define REG_INIRTS_RATE_SEL 0x0480 -#define REG_HTSTFWT 0x800 -#define REG_CCK_RPT_FORMAT 0x804 -#define BIT_CCK_RPT_FORMAT BIT(16) -#define REG_RXPSEL 0x808 -#define BIT_RX_PSEL_RST (BIT(28) | BIT(29)) -#define REG_TXPSEL 0x80c -#define REG_RXCCAMSK 0x814 -#define REG_CCASEL 0x82c -#define REG_PDMFTH 0x830 -#define REG_BWINDICATION 0x834 -#define REG_CCA2ND 0x838 -#define REG_L1WT 0x83c -#define REG_L1PKWT 0x840 -#define REG_L1PKTH 0x848 -#define REG_MRC 0x850 -#define REG_CLKTRK 0x860 -#define REG_ADCCLK 0x8ac -#define REG_HSSI_READ 0x8b0 -#define REG_FPGA0_XCD_RF_PARA 0x8b4 -#define REG_ADC160 0x8c4 -#define REG_ADC40 0x8c8 -#define REG_CHFIR 0x8f0 -#define REG_ANTSEL_SW 0x900 -#define REG_SINGLE_TONE_CONT_TX 0x914 -#define REG_CDDTXP 0x93c -#define REG_TXPSEL1 0x940 -#define REG_ACBB0 0x948 -#define REG_ACBBRXFIR 0x94c -#define REG_ACGG2TBL 0x958 -#define REG_FAS 0x9a4 -#define REG_RXSB 0xa00 -#define REG_CCK_RX 0xa04 -#define REG_PWRTH 0xa08 -#define REG_CCA_FLTR 0xa20 -#define REG_TXSF2 0xa24 -#define REG_TXSF6 0xa28 -#define REG_FA_CCK 0xa5c -#define REG_RXDESC 0xa2c -#define REG_ENTXCCK 0xa80 -#define BTG_LNA 0xfc84 -#define WLG_LNA 0x7532 -#define REG_ENRXCCA 0xa84 -#define BTG_CCA 0x0e -#define WLG_CCA 0x12 -#define REG_PWRTH2 0xaa8 -#define REG_CSRATIO 0xaaa -#define REG_TXFILTER 0xaac -#define REG_CNTRST 0xb58 -#define REG_AGCTR_A 0xc08 -#define REG_RX_IQC_AB_A 0xc10 -#define REG_TXSCALE_A 0xc1c -#define BB_SWING_MASK GENMASK(31, 21) -#define REG_TXDFIR 0xc20 -#define REG_RXIGI_A 0xc50 -#define REG_TX_PWR_TRAINING_A 0xc54 -#define REG_AFE_PWR1_A 0xc60 -#define REG_AFE_PWR2_A 0xc64 -#define REG_RX_WAIT_CCA_TX_CCK_RFON_A 0xc68 -#define REG_LSSI_WRITE_A 0xc90 -#define REG_TXAGCIDX 0xc94 -#define REG_TRSW 0xca0 -#define REG_RFESEL0 0xcb0 -#define REG_RFE_PINMUX_A 0xcb0 -#define REG_RFESEL8 0xcb4 -#define REG_RFE_INV_A 0xcb4 -#define RFE_INV_MASK 0x3ff00000 -#define REG_RFECTL_A 0xcb8 -#define B_BTG_SWITCH BIT(16) -#define B_CTRL_SWITCH BIT(18) -#define B_WL_SWITCH (BIT(20) | BIT(22)) -#define B_WLG_SWITCH BIT(21) -#define B_WLA_SWITCH BIT(23) -#define REG_RFEINV 0xcbc -#define REG_PI_READ_A 0xd04 -#define REG_SI_READ_A 0xd08 -#define REG_PI_READ_B 0xd44 -#define REG_SI_READ_B 0xd48 -#define REG_AGCTR_B 0xe08 -#define REG_RX_IQC_AB_B 0xe10 -#define REG_TXSCALE_B 0xe1c -#define REG_RXIGI_B 0xe50 -#define REG_TX_PWR_TRAINING_B 0xe54 -#define REG_AFE_PWR1_B 0xe60 -#define REG_AFE_PWR2_B 0xe64 -#define REG_RX_WAIT_CCA_TX_CCK_RFON_B 0xe68 -#define REG_LSSI_WRITE_B 0xe90 -#define REG_RFE_PINMUX_B 0xeb0 -#define REG_RFE_INV_B 0xeb4 -#define REG_RFECTL_B 0xeb8 -#define REG_CRC_CCK 0xf04 -#define REG_CRC_OFDM 0xf14 -#define REG_CRC_HT 0xf10 -#define REG_CRC_VHT 0xf0c -#define REG_CCA_OFDM 0xf08 -#define REG_FA_OFDM 0xf48 -#define REG_CCA_CCK 0xfcc -#define REG_DMEM_CTRL 0x1080 -#define BIT_WL_RST BIT(16) -#define REG_ANTWT 0x1904 -#define REG_IQKFAILMSK 0x1bf0 -#define BIT_MASK_R_RFE_SEL_15 GENMASK(31, 28) -#define BIT_SDIO_INT BIT(18) -#define BT_CNT_ENABLE 0x1 -#define BIT_BCN_QUEUE BIT(3) -#define BCN_PRI_EN 0x1 -#define PTA_CTRL_PIN 0x66 -#define DPDT_CTRL_PIN 0x77 -#define ANTDIC_CTRL_PIN 0x88 -#define REG_CTRL_TYPE 0x67 -#define BIT_CTRL_TYPE1 BIT(5) -#define BIT_CTRL_TYPE2 BIT(4) -#define CTRL_TYPE_MASK GENMASK(15, 8) -#define REG_USB_HRPWM 0xfe58 - -#define RF18_BAND_MASK (BIT(16) | BIT(9) | BIT(8)) -#define RF18_BAND_2G (0) -#define RF18_BAND_5G (BIT(16) | BIT(8)) -#define RF18_CHANNEL_MASK (MASKBYTE0) -#define RF18_RFSI_MASK (BIT(18) | BIT(17)) -#define RF18_RFSI_GE (BIT(17)) -#define RF18_RFSI_GT (BIT(18)) -#define RF18_BW_MASK (BIT(11) | BIT(10)) -#define RF18_BW_20M (BIT(11) | BIT(10)) -#define RF18_BW_40M (BIT(10)) -#define RF18_BW_80M (0) -#define RF_MODE_TABLE_ADDR 0x30 -#define RF_MODE_TABLE_DATA0 0x31 -#define RF_MODE_TABLE_DATA1 0x32 -#define RF_LCK 0xb4 #endif diff --git a/rtw8821a_table.c b/rtw8821a_table.c index 82d004f0..c8fd8e33 100644 --- a/rtw8821a_table.c +++ b/rtw8821a_table.c @@ -1,5 +1,5 @@ // SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause -/* Copyright(c) 2018-2019 Realtek Corporation +/* Copyright(c) 2024 Realtek Corporation */ #include "main.h" @@ -1976,7 +1976,7 @@ static const struct rtw_pwr_seq_cmd trans_cardemu_to_act_8821a[] = { RTW_PWR_CUT_ALL_MSK, RTW_PWR_INTF_PCI_MSK, RTW_PWR_ADDR_MAC, - RTW_PWR_CMD_WRITE, BIT(0) , BIT(0)}, + RTW_PWR_CMD_WRITE, BIT(0), BIT(0)}, {0x0006, RTW_PWR_CUT_ALL_MSK, RTW_PWR_INTF_ALL_MSK, @@ -1986,7 +1986,7 @@ static const struct rtw_pwr_seq_cmd trans_cardemu_to_act_8821a[] = { RTW_PWR_CUT_ALL_MSK, RTW_PWR_INTF_PCI_MSK, RTW_PWR_ADDR_MAC, - RTW_PWR_CMD_WRITE, BIT(0) , 0}, + RTW_PWR_CMD_WRITE, BIT(0), 0}, {0x0006, RTW_PWR_CUT_ALL_MSK, RTW_PWR_INTF_ALL_MSK, @@ -2206,7 +2206,7 @@ static const struct rtw_pwr_seq_cmd trans_cardemu_to_carddis_8821a[] = { RTW_PWR_INTF_PCI_MSK, RTW_PWR_ADDR_MAC, RTW_PWR_CMD_WRITE, BIT(2), BIT(2)}, - {0x004A, + {0x004A, RTW_PWR_CUT_ALL_MSK, RTW_PWR_INTF_USB_MSK, RTW_PWR_ADDR_MAC, @@ -2233,18 +2233,18 @@ static const struct rtw_pwr_seq_cmd trans_cardemu_to_carddis_8821a[] = { RTW_PWR_CMD_END, 0, 0}, }; -const struct rtw_pwr_seq_cmd *card_enable_flow_8821a[] = { +const struct rtw_pwr_seq_cmd * const card_enable_flow_8821a[] = { trans_carddis_to_cardemu_8821a, trans_cardemu_to_act_8821a, NULL }; -const struct rtw_pwr_seq_cmd *enter_lps_flow_8821a[] = { +const struct rtw_pwr_seq_cmd * const enter_lps_flow_8821a[] = { trans_act_to_lps_8821a, NULL }; -const struct rtw_pwr_seq_cmd *card_disable_flow_8821a[] = { +const struct rtw_pwr_seq_cmd * const card_disable_flow_8821a[] = { trans_act_to_cardemu_8821a, trans_cardemu_to_carddis_8821a, NULL diff --git a/rtw8821a_table.h b/rtw8821a_table.h index 070ffdbc..90379ac7 100644 --- a/rtw8821a_table.h +++ b/rtw8821a_table.h @@ -1,5 +1,5 @@ /* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */ -/* Copyright(c) 2018-2019 Realtek Corporation +/* Copyright(c) 2024 Realtek Corporation */ #ifndef __RTW8821A_TABLE_H__ @@ -12,9 +12,9 @@ extern const struct rtw_table rtw8821a_bb_pg_tbl; extern const struct rtw_table rtw8821a_rf_a_tbl; extern const struct rtw_table rtw8821a_txpwr_lmt_tbl; -extern const struct rtw_pwr_seq_cmd *card_enable_flow_8821a[]; -extern const struct rtw_pwr_seq_cmd *enter_lps_flow_8821a[]; -extern const struct rtw_pwr_seq_cmd *card_disable_flow_8821a[]; +extern const struct rtw_pwr_seq_cmd * const card_enable_flow_8821a[]; +extern const struct rtw_pwr_seq_cmd * const enter_lps_flow_8821a[]; +extern const struct rtw_pwr_seq_cmd * const card_disable_flow_8821a[]; extern const struct rtw_pwr_track_tbl rtw8821a_rtw_pwr_track_tbl; diff --git a/rtw8821au.c b/rtw8821au.c index 3d3334df..a01744b6 100644 --- a/rtw8821au.c +++ b/rtw8821au.c @@ -1,5 +1,5 @@ // SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause -/* Copyright(c) 2018-2024 Realtek Corporation +/* Copyright(c) 2024 Realtek Corporation */ #include diff --git a/rtw8821c.c b/rtw8821c.c index 9b1aa402..9e4be8f4 100644 --- a/rtw8821c.c +++ b/rtw8821c.c @@ -1973,6 +1973,7 @@ const struct rtw_chip_info rtw8821c_hw_spec = { .usb_tx_agg_desc_num = 3, .hw_feature_report = true, .c2h_ra_report_size = 7, + .old_datarate_fb_limit = false, .ht_supported = true, .vht_supported = true, .lps_deep_mode_supported = BIT(LPS_DEEP_MODE_LCLK), diff --git a/rtw8821c.h b/rtw8821c.h index 91ed9214..7a33ebd6 100644 --- a/rtw8821c.h +++ b/rtw8821c.h @@ -214,19 +214,10 @@ extern const struct rtw_chip_info rtw8821c_hw_spec; #define BIT_FEN_EN BIT(26) #define REG_INIRTS_RATE_SEL 0x0480 #define REG_HTSTFWT 0x800 -#define REG_RXPSEL 0x808 -#define BIT_RX_PSEL_RST (BIT(28) | BIT(29)) -#define REG_TXPSEL 0x80c #define REG_RXCCAMSK 0x814 -#define REG_CCASEL 0x82c -#define REG_PDMFTH 0x830 -#define REG_CCA2ND 0x838 #define REG_L1WT 0x83c #define REG_L1PKWT 0x840 #define REG_MRC 0x850 -#define REG_CLKTRK 0x860 -#define REG_ADCCLK 0x8ac -#define REG_ADC160 0x8c4 #define REG_ADC40 0x8c8 #define REG_CHFIR 0x8f0 #define REG_CDDTXP 0x93c @@ -234,14 +225,11 @@ extern const struct rtw_chip_info rtw8821c_hw_spec; #define REG_ACBB0 0x948 #define REG_ACBBRXFIR 0x94c #define REG_ACGG2TBL 0x958 -#define REG_FAS 0x9a4 -#define REG_RXSB 0xa00 #define REG_ADCINI 0xa04 #define REG_PWRTH 0xa08 #define REG_CCA_FLTR 0xa20 #define REG_TXSF2 0xa24 #define REG_TXSF6 0xa28 -#define REG_FA_CCK 0xa5c #define REG_RXDESC 0xa2c #define REG_ENTXCCK 0xa80 #define BTG_LNA 0xfc84 @@ -252,12 +240,8 @@ extern const struct rtw_chip_info rtw8821c_hw_spec; #define REG_PWRTH2 0xaa8 #define REG_CSRATIO 0xaaa #define REG_TXFILTER 0xaac -#define REG_CNTRST 0xb58 #define REG_AGCTR_A 0xc08 -#define REG_TXSCALE_A 0xc1c #define REG_TXDFIR 0xc20 -#define REG_RXIGI_A 0xc50 -#define REG_TXAGCIDX 0xc94 #define REG_TRSW 0xca0 #define REG_RFESEL0 0xcb0 #define REG_RFESEL8 0xcb4 @@ -269,14 +253,6 @@ extern const struct rtw_chip_info rtw8821c_hw_spec; #define B_WLA_SWITCH BIT(23) #define REG_RFEINV 0xcbc #define REG_AGCTR_B 0xe08 -#define REG_RXIGI_B 0xe50 -#define REG_CRC_CCK 0xf04 -#define REG_CRC_OFDM 0xf14 -#define REG_CRC_HT 0xf10 -#define REG_CRC_VHT 0xf0c -#define REG_CCA_OFDM 0xf08 -#define REG_FA_OFDM 0xf48 -#define REG_CCA_CCK 0xfcc #define REG_DMEM_CTRL 0x1080 #define BIT_WL_RST BIT(16) #define REG_ANTWT 0x1904 diff --git a/rtw8822b.c b/rtw8822b.c index c5e27059..739809f4 100644 --- a/rtw8822b.c +++ b/rtw8822b.c @@ -2513,6 +2513,7 @@ const struct rtw_chip_info rtw8822b_hw_spec = { .usb_tx_agg_desc_num = 3, .hw_feature_report = true, .c2h_ra_report_size = 7, + .old_datarate_fb_limit = false, .ht_supported = true, .vht_supported = true, .lps_deep_mode_supported = BIT(LPS_DEEP_MODE_LCLK), diff --git a/rtw8822b.h b/rtw8822b.h index cf85e639..0514958f 100644 --- a/rtw8822b.h +++ b/rtw8822b.h @@ -151,21 +151,12 @@ _rtw_write32s_mask(struct rtw_dev *rtwdev, u32 addr, u32 mask, u32 data) #define RTW8822B_EDCCA_MAX 0x7f #define RTW8822B_EDCCA_SRC_DEF 1 #define REG_HTSTFWT 0x800 -#define REG_RXPSEL 0x808 -#define BIT_RX_PSEL_RST (BIT(28) | BIT(29)) -#define REG_TXPSEL 0x80c #define REG_RXCCAMSK 0x814 -#define REG_CCASEL 0x82c -#define REG_PDMFTH 0x830 -#define REG_CCA2ND 0x838 #define REG_L1WT 0x83c #define REG_L1PKWT 0x840 #define REG_MRC 0x850 -#define REG_CLKTRK 0x860 #define REG_EDCCA_POW_MA 0x8a0 #define BIT_MA_LEVEL GENMASK(1, 0) -#define REG_ADCCLK 0x8ac -#define REG_ADC160 0x8c4 #define REG_ADC40 0x8c8 #define REG_EDCCA_DECISION 0x8dc #define BIT_EDCCA_OPTION BIT(5) @@ -176,7 +167,6 @@ _rtw_write32s_mask(struct rtw_dev *rtwdev, u32 addr, u32 mask, u32 data) #define REG_ACBB0 0x948 #define REG_ACBBRXFIR 0x94c #define REG_ACGG2TBL 0x958 -#define REG_RXSB 0xa00 #define REG_ADCINI 0xa04 #define REG_TXSF2 0xa24 #define REG_TXSF6 0xa28 @@ -184,14 +174,12 @@ _rtw_write32s_mask(struct rtw_dev *rtwdev, u32 addr, u32 mask, u32 data) #define REG_ENTXCCK 0xa80 #define REG_AGCTR_A 0xc08 #define REG_TXDFIR 0xc20 -#define REG_RXIGI_A 0xc50 #define REG_TRSW 0xca0 #define REG_RFESEL0 0xcb0 #define REG_RFESEL8 0xcb4 #define REG_RFECTL 0xcb8 #define REG_RFEINV 0xcbc #define REG_AGCTR_B 0xe08 -#define REG_RXIGI_B 0xe50 #define REG_ANTWT 0x1904 #define REG_IQKFAILMSK 0x1bf0 diff --git a/rtw8822c.c b/rtw8822c.c index 11509adf..af6b7693 100644 --- a/rtw8822c.c +++ b/rtw8822c.c @@ -5333,6 +5333,7 @@ const struct rtw_chip_info rtw8822c_hw_spec = { .usb_tx_agg_desc_num = 3, .hw_feature_report = true, .c2h_ra_report_size = 7, + .old_datarate_fb_limit = false, .default_1ss_tx_path = BB_PATH_A, .path_div_supported = true, .ht_supported = true, diff --git a/rtw88xxa.c b/rtw88xxa.c new file mode 100644 index 00000000..f1162559 --- /dev/null +++ b/rtw88xxa.c @@ -0,0 +1,1995 @@ +// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause +/* Copyright(c) 2024 Realtek Corporation + */ + +#include +#include "main.h" +#include "coex.h" +#include "phy.h" +#include "rtw88xxa.h" +#include "mac.h" +#include "reg.h" +#include "sec.h" +#include "debug.h" +#include "bf.h" +#include "efuse.h" +#include "usb.h" + +void rtw88xxa_efuse_grant(struct rtw_dev *rtwdev, bool on) +{ + if (on) { + rtw_write8(rtwdev, REG_EFUSE_ACCESS, EFUSE_ACCESS_ON); + + rtw_write16_set(rtwdev, REG_SYS_FUNC_EN, BIT_FEN_ELDR); + rtw_write16_set(rtwdev, REG_SYS_CLKR, + BIT_LOADER_CLK_EN | BIT_ANA8M); + } else { + rtw_write8(rtwdev, REG_EFUSE_ACCESS, EFUSE_ACCESS_OFF); + } +} +EXPORT_SYMBOL(rtw88xxa_efuse_grant); + +static void rtw8812a_read_amplifier_type(struct rtw_dev *rtwdev) +{ + struct rtw_efuse *efuse = &rtwdev->efuse; + + efuse->ext_pa_2g = (efuse->pa_type_2g & BIT(5)) && + (efuse->pa_type_2g & BIT(4)); + efuse->ext_lna_2g = (efuse->lna_type_2g & BIT(7)) && + (efuse->lna_type_2g & BIT(3)); + + efuse->ext_pa_5g = (efuse->pa_type_5g & BIT(1)) && + (efuse->pa_type_5g & BIT(0)); + efuse->ext_lna_5g = (efuse->lna_type_5g & BIT(7)) && + (efuse->lna_type_5g & BIT(3)); + + /* For rtw_phy_cond2: */ + if (efuse->ext_pa_2g) { + u8 ext_type_pa_2g_a = u8_get_bits(efuse->lna_type_2g, BIT(2)); + u8 ext_type_pa_2g_b = u8_get_bits(efuse->lna_type_2g, BIT(6)); + + efuse->gpa_type = (ext_type_pa_2g_b << 2) | ext_type_pa_2g_a; + } + + if (efuse->ext_pa_5g) { + u8 ext_type_pa_5g_a = u8_get_bits(efuse->lna_type_5g, BIT(2)); + u8 ext_type_pa_5g_b = u8_get_bits(efuse->lna_type_5g, BIT(6)); + + efuse->apa_type = (ext_type_pa_5g_b << 2) | ext_type_pa_5g_a; + } + + if (efuse->ext_lna_2g) { + u8 ext_type_lna_2g_a = u8_get_bits(efuse->lna_type_2g, + BIT(1) | BIT(0)); + u8 ext_type_lna_2g_b = u8_get_bits(efuse->lna_type_2g, + BIT(5) | BIT(4)); + + efuse->glna_type = (ext_type_lna_2g_b << 2) | ext_type_lna_2g_a; + } + + if (efuse->ext_lna_5g) { + u8 ext_type_lna_5g_a = u8_get_bits(efuse->lna_type_5g, + BIT(1) | BIT(0)); + u8 ext_type_lna_5g_b = u8_get_bits(efuse->lna_type_5g, + BIT(5) | BIT(4)); + + efuse->alna_type = (ext_type_lna_5g_b << 2) | ext_type_lna_5g_a; + } +} + +static void rtw8812a_read_rfe_type(struct rtw_dev *rtwdev, + struct rtw88xxa_efuse *map) +{ + struct rtw_efuse *efuse = &rtwdev->efuse; + + if (map->rfe_option == 0xff) { + if (rtwdev->hci.type == RTW_HCI_TYPE_USB) + efuse->rfe_option = 0; + else if (rtwdev->hci.type == RTW_HCI_TYPE_PCIE) + efuse->rfe_option = 2; + else + efuse->rfe_option = 4; + } else if (map->rfe_option & BIT(7)) { + if (efuse->ext_lna_5g) { + if (efuse->ext_pa_5g) { + if (efuse->ext_lna_2g && efuse->ext_pa_2g) + efuse->rfe_option = 3; + else + efuse->rfe_option = 0; + } else { + efuse->rfe_option = 2; + } + } else { + efuse->rfe_option = 4; + } + } else { + efuse->rfe_option = map->rfe_option & 0x3f; + + /* Due to other customer already use incorrect EFUSE map for + * their product. We need to add workaround to prevent to + * modify spec and notify all customer to revise the IC 0xca + * content. + */ + if (efuse->rfe_option == 4 && + (efuse->ext_pa_5g || efuse->ext_pa_2g || + efuse->ext_lna_5g || efuse->ext_lna_2g)) { + if (rtwdev->hci.type == RTW_HCI_TYPE_USB) + efuse->rfe_option = 0; + else if (rtwdev->hci.type == RTW_HCI_TYPE_PCIE) + efuse->rfe_option = 2; + } + } +} + +static void rtw88xxa_read_usb_type(struct rtw_dev *rtwdev) +{ + struct rtw_efuse *efuse = &rtwdev->efuse; + struct rtw_hal *hal = &rtwdev->hal; + u8 antenna = 0; + u8 wmode = 0; + u8 val8, i; + + efuse->hw_cap.bw = BIT(RTW_CHANNEL_WIDTH_20) | + BIT(RTW_CHANNEL_WIDTH_40) | + BIT(RTW_CHANNEL_WIDTH_80); + efuse->hw_cap.ptcl = EFUSE_HW_CAP_PTCL_VHT; + + if (rtwdev->chip->id == RTW_CHIP_TYPE_8821A) + efuse->hw_cap.nss = 1; + else + efuse->hw_cap.nss = 2; + + if (rtwdev->chip->id == RTW_CHIP_TYPE_8821A) + goto print_hw_cap; + + for (i = 0; i < 2; i++) { + rtw_read8_physical_efuse(rtwdev, 1019 - i, &val8); + + antenna = u8_get_bits(val8, GENMASK(7, 5)); + if (antenna) + break; + antenna = u8_get_bits(val8, GENMASK(3, 1)); + if (antenna) + break; + } + + for (i = 0; i < 2; i++) { + rtw_read8_physical_efuse(rtwdev, 1021 - i, &val8); + + wmode = u8_get_bits(val8, GENMASK(3, 2)); + if (wmode) + break; + } + + if (antenna == 1) { + rtw_info(rtwdev, "This RTL8812AU says it is 1T1R.\n"); + + efuse->hw_cap.nss = 1; + hal->rf_type = RF_1T1R; + hal->rf_path_num = 1; + hal->rf_phy_num = 1; + hal->antenna_tx = BB_PATH_A; + hal->antenna_rx = BB_PATH_A; + } else { + /* Override rtw_chip_parameter_setup(). It detects 8812au as 1T1R. */ + efuse->hw_cap.nss = 2; + hal->rf_type = RF_2T2R; + hal->rf_path_num = 2; + hal->rf_phy_num = 2; + hal->antenna_tx = BB_PATH_AB; + hal->antenna_rx = BB_PATH_AB; + + if (antenna == 2 && wmode == 2) { + rtw_info(rtwdev, "This RTL8812AU says it can't do VHT.\n"); + + /* Can't be EFUSE_HW_CAP_IGNORE and can't be + * EFUSE_HW_CAP_PTCL_VHT, so make it 1. + */ + efuse->hw_cap.ptcl = 1; + efuse->hw_cap.bw &= ~BIT(RTW_CHANNEL_WIDTH_80); + } + } + +print_hw_cap: + rtw_dbg(rtwdev, RTW_DBG_EFUSE, + "hw cap: hci=0x%02x, bw=0x%02x, ptcl=0x%02x, ant_num=%d, nss=%d\n", + efuse->hw_cap.hci, efuse->hw_cap.bw, efuse->hw_cap.ptcl, + efuse->hw_cap.ant_num, efuse->hw_cap.nss); +} + +int rtw88xxa_read_efuse(struct rtw_dev *rtwdev, u8 *log_map) +{ + const struct rtw_chip_info *chip = rtwdev->chip; + struct rtw_efuse *efuse = &rtwdev->efuse; + struct rtw88xxa_efuse *map; + int i; + + if (chip->id == RTW_CHIP_TYPE_8812A) + rtwdev->hal.cut_version += 1; + + if (rtw_dbg_is_enabled(rtwdev, RTW_DBG_EFUSE)) + print_hex_dump(KERN_INFO, "", DUMP_PREFIX_OFFSET, 16, 1, + log_map, chip->log_efuse_size, true); + + map = (struct rtw88xxa_efuse *)log_map; + + efuse->rf_board_option = map->rf_board_option; + efuse->crystal_cap = map->xtal_k; + if (efuse->crystal_cap == 0xff) + efuse->crystal_cap = 0x20; + efuse->pa_type_2g = map->pa_type; + efuse->pa_type_5g = map->pa_type; + efuse->lna_type_2g = map->lna_type_2g; + efuse->lna_type_5g = map->lna_type_5g; + if (chip->id == RTW_CHIP_TYPE_8812A) { + rtw8812a_read_amplifier_type(rtwdev); + rtw8812a_read_rfe_type(rtwdev, map); + + efuse->usb_mode_switch = u8_get_bits(map->usb_mode, BIT(1)); + } + efuse->channel_plan = map->channel_plan; + efuse->country_code[0] = map->country_code[0]; + efuse->country_code[1] = map->country_code[1]; + efuse->bt_setting = map->rf_bt_setting; + efuse->regd = map->rf_board_option & 0x7; + efuse->thermal_meter[0] = map->thermal_meter; + efuse->thermal_meter[1] = map->thermal_meter; + efuse->thermal_meter_k = map->thermal_meter; + efuse->tx_bb_swing_setting_2g = map->tx_bb_swing_setting_2g; + efuse->tx_bb_swing_setting_5g = map->tx_bb_swing_setting_5g; + + rtw88xxa_read_usb_type(rtwdev); + + if (chip->id == RTW_CHIP_TYPE_8821A) + efuse->btcoex = rtw_read32_mask(rtwdev, REG_WL_BT_PWR_CTRL, + BIT_BT_FUNC_EN); + else + efuse->btcoex = (map->rf_board_option & 0xe0) == 0x20; + efuse->share_ant = !!(efuse->bt_setting & BIT(0)); + + /* No antenna diversity because it's disabled in the vendor driver */ + efuse->ant_div_cfg = 0; + + efuse->ant_div_type = map->rf_antenna_option; + if (efuse->ant_div_type == 0xff) + efuse->ant_div_type = 0x3; + + for (i = 0; i < 4; i++) + efuse->txpwr_idx_table[i] = map->txpwr_idx_table[i]; + + switch (rtw_hci_type(rtwdev)) { + case RTW_HCI_TYPE_USB: + if (chip->id == RTW_CHIP_TYPE_8821A) + ether_addr_copy(efuse->addr, map->rtw8821au.mac_addr); + else + ether_addr_copy(efuse->addr, map->rtw8812au.mac_addr); + break; + case RTW_HCI_TYPE_PCIE: + case RTW_HCI_TYPE_SDIO: + default: + /* unsupported now */ + return -EOPNOTSUPP; + } + + return 0; +} +EXPORT_SYMBOL(rtw88xxa_read_efuse); + +static void rtw88xxa_reset_8051(struct rtw_dev *rtwdev) +{ + const struct rtw_chip_info *chip = rtwdev->chip; + u8 val8; + + /* Reset MCU IO Wrapper */ + rtw_write8_clr(rtwdev, REG_RSV_CTRL, BIT(1)); + if (chip->id == RTW_CHIP_TYPE_8812A) + rtw_write8_clr(rtwdev, REG_RSV_CTRL + 1, BIT(3)); + else + rtw_write8_clr(rtwdev, REG_RSV_CTRL + 1, BIT(0)); + + val8 = rtw_read8(rtwdev, REG_SYS_FUNC_EN + 1); + rtw_write8(rtwdev, REG_SYS_FUNC_EN + 1, val8 & ~BIT(2)); + + /* Enable MCU IO Wrapper */ + rtw_write8_clr(rtwdev, REG_RSV_CTRL, BIT(1)); + if (chip->id == RTW_CHIP_TYPE_8812A) + rtw_write8_set(rtwdev, REG_RSV_CTRL + 1, BIT(3)); + else + rtw_write8_set(rtwdev, REG_RSV_CTRL + 1, BIT(0)); + + rtw_write8(rtwdev, REG_SYS_FUNC_EN + 1, val8 | BIT(2)); +} + +/* A lightweight deinit function */ +static void rtw88xxau_hw_reset(struct rtw_dev *rtwdev) +{ + u8 val8; + + if (!(rtw_read8(rtwdev, REG_MCUFW_CTRL) & BIT_RAM_DL_SEL)) + return; + + rtw88xxa_reset_8051(rtwdev); + rtw_write8(rtwdev, REG_MCUFW_CTRL, 0x00); + + /* before BB reset should do clock gated */ + rtw_write32_set(rtwdev, REG_FPGA0_XCD_RF_PARA, BIT(6)); + + /* reset BB */ + rtw_write8_clr(rtwdev, REG_SYS_FUNC_EN, BIT(0) | BIT(1)); + + /* reset RF */ + rtw_write8(rtwdev, REG_RF_CTRL, 0); + + /* reset TRX path */ + rtw_write16(rtwdev, REG_CR, 0); + + /* reset MAC, reg0x5[1], auto FSM off */ + rtw_write8_set(rtwdev, REG_APS_FSMCO + 1, APS_FSMCO_MAC_OFF >> 8); + + /* check if reg0x5[1] auto cleared */ + if (read_poll_timeout_atomic(rtw_read8, val8, + !(val8 & (APS_FSMCO_MAC_OFF >> 8)), + 1, 5000, false, + rtwdev, REG_APS_FSMCO + 1)) + rtw_err(rtwdev, "%s: timed out waiting for 0x5[1]\n", __func__); + + /* reg0x5[0], auto FSM on */ + val8 |= APS_FSMCO_MAC_ENABLE >> 8; + rtw_write8(rtwdev, REG_APS_FSMCO + 1, val8); + + rtw_write8_clr(rtwdev, REG_SYS_FUNC_EN + 1, BIT(4) | BIT(7)); + rtw_write8_set(rtwdev, REG_SYS_FUNC_EN + 1, BIT(4) | BIT(7)); +} + +static int rtw88xxau_init_power_on(struct rtw_dev *rtwdev) +{ + const struct rtw_chip_info *chip = rtwdev->chip; + u16 val16; + int ret; + + ret = rtw_pwr_seq_parser(rtwdev, chip->pwr_on_seq); + if (ret) { + rtw_err(rtwdev, "power on flow failed\n"); + return ret; + } + + rtw_write16(rtwdev, REG_CR, 0); + val16 = BIT_HCI_TXDMA_EN | BIT_HCI_RXDMA_EN | BIT_TXDMA_EN | + BIT_RXDMA_EN | BIT_PROTOCOL_EN | BIT_SCHEDULE_EN | + BIT_MAC_SEC_EN | BIT_32K_CAL_TMR_EN; + rtw_write16_set(rtwdev, REG_CR, val16); + + if (chip->id == RTW_CHIP_TYPE_8821A) { + if (rtw_read8(rtwdev, REG_SYS_CFG1 + 3) & BIT(0)) + rtw_write8_set(rtwdev, REG_LDO_SWR_CTRL, BIT(6)); + } + + return ret; +} + +static int rtw88xxa_llt_write(struct rtw_dev *rtwdev, u32 address, u32 data) +{ + u32 value = BIT_LLT_WRITE_ACCESS | (address << 8) | data; + int count = 0; + + rtw_write32(rtwdev, REG_LLT_INIT, value); + + do { + if (!rtw_read32_mask(rtwdev, REG_LLT_INIT, BIT(31) | BIT(30))) + break; + + if (count > 20) { + rtw_err(rtwdev, "Failed to poll write LLT done at %d!\n", + address); + return -EBUSY; + } + } while (++count); + + return 0; +} + +static int rtw88xxa_llt_init(struct rtw_dev *rtwdev, u32 boundary) +{ + u32 last_entry = 255; + int status = 0; + u32 i; + + for (i = 0; i < boundary - 1; i++) { + status = rtw88xxa_llt_write(rtwdev, i, i + 1); + if (status) + return status; + } + + status = rtw88xxa_llt_write(rtwdev, boundary - 1, 0xFF); + if (status) + return status; + + for (i = boundary; i < last_entry; i++) { + status = rtw88xxa_llt_write(rtwdev, i, i + 1); + if (status) + return status; + } + + status = rtw88xxa_llt_write(rtwdev, last_entry, boundary); + + return status; +} + +static void rtw88xxau_init_queue_reserved_page(struct rtw_dev *rtwdev) +{ + const struct rtw_chip_info *chip = rtwdev->chip; + struct rtw_fifo_conf *fifo = &rtwdev->fifo; + const struct rtw_page_table *pg_tbl = NULL; + u16 pubq_num; + u32 val32; + + switch (rtw_hci_type(rtwdev)) { + case RTW_HCI_TYPE_PCIE: + pg_tbl = &chip->page_table[1]; + break; + case RTW_HCI_TYPE_USB: + if (rtwdev->hci.bulkout_num == 2) + pg_tbl = &chip->page_table[2]; + else if (rtwdev->hci.bulkout_num == 3) + pg_tbl = &chip->page_table[3]; + else if (rtwdev->hci.bulkout_num == 4) + pg_tbl = &chip->page_table[4]; + break; + case RTW_HCI_TYPE_SDIO: + pg_tbl = &chip->page_table[0]; + break; + default: + break; + } + + pubq_num = fifo->acq_pg_num - pg_tbl->hq_num - pg_tbl->lq_num - + pg_tbl->nq_num - pg_tbl->exq_num - pg_tbl->gapq_num; + + val32 = BIT_RQPN_NE(pg_tbl->nq_num, pg_tbl->exq_num); + rtw_write32(rtwdev, REG_RQPN_NPQ, val32); + + val32 = BIT_RQPN_HLP(pg_tbl->hq_num, pg_tbl->lq_num, pubq_num); + rtw_write32(rtwdev, REG_RQPN, val32); +} + +static void rtw88xxau_init_tx_buffer_boundary(struct rtw_dev *rtwdev) +{ + struct rtw_fifo_conf *fifo = &rtwdev->fifo; + + rtw_write8(rtwdev, REG_BCNQ_BDNY, fifo->rsvd_boundary); + rtw_write8(rtwdev, REG_MGQ_BDNY, fifo->rsvd_boundary); + rtw_write8(rtwdev, REG_WMAC_LBK_BF_HD, fifo->rsvd_boundary); + rtw_write8(rtwdev, REG_TRXFF_BNDY, fifo->rsvd_boundary); + rtw_write8(rtwdev, REG_DWBCN0_CTRL + 1, fifo->rsvd_boundary); +} + +static int rtw88xxau_init_queue_priority(struct rtw_dev *rtwdev) +{ + const struct rtw_chip_info *chip = rtwdev->chip; + u8 bulkout_num = rtwdev->hci.bulkout_num; + const struct rtw_rqpn *rqpn = NULL; + u16 txdma_pq_map; + + switch (rtw_hci_type(rtwdev)) { + case RTW_HCI_TYPE_PCIE: + rqpn = &chip->rqpn_table[1]; + break; + case RTW_HCI_TYPE_USB: + if (bulkout_num == 2) + rqpn = &chip->rqpn_table[2]; + else if (bulkout_num == 3) + rqpn = &chip->rqpn_table[3]; + else if (bulkout_num == 4) + rqpn = &chip->rqpn_table[4]; + else + return -EINVAL; + break; + case RTW_HCI_TYPE_SDIO: + rqpn = &chip->rqpn_table[0]; + break; + default: + return -EINVAL; + } + + rtwdev->fifo.rqpn = rqpn; + + txdma_pq_map = rtw_read16(rtwdev, REG_TXDMA_PQ_MAP) & 0x7; + txdma_pq_map |= BIT_TXDMA_HIQ_MAP(rqpn->dma_map_hi); + txdma_pq_map |= BIT_TXDMA_MGQ_MAP(rqpn->dma_map_mg); + txdma_pq_map |= BIT_TXDMA_BKQ_MAP(rqpn->dma_map_bk); + txdma_pq_map |= BIT_TXDMA_BEQ_MAP(rqpn->dma_map_be); + txdma_pq_map |= BIT_TXDMA_VIQ_MAP(rqpn->dma_map_vi); + txdma_pq_map |= BIT_TXDMA_VOQ_MAP(rqpn->dma_map_vo); + rtw_write16(rtwdev, REG_TXDMA_PQ_MAP, txdma_pq_map); + + /* Packet in Hi Queue Tx immediately (No constraint for ATIM Period). */ + if (rtw_hci_type(rtwdev) == RTW_HCI_TYPE_USB && bulkout_num == 4) + rtw_write8(rtwdev, REG_HIQ_NO_LMT_EN, 0xff); + + return 0; +} + +static void rtw88xxa_init_wmac_setting(struct rtw_dev *rtwdev) +{ + rtw_write16(rtwdev, REG_RXFLTMAP0, 0xffff); + rtw_write16(rtwdev, REG_RXFLTMAP1, 0x0400); + rtw_write16(rtwdev, REG_RXFLTMAP2, 0xffff); + + rtw_write32(rtwdev, REG_MAR, 0xffffffff); + rtw_write32(rtwdev, REG_MAR + 4, 0xffffffff); +} + +static void rtw88xxa_init_adaptive_ctrl(struct rtw_dev *rtwdev) +{ + rtw_write32_mask(rtwdev, REG_RRSR, 0xfffff, 0xffff1); + rtw_write16(rtwdev, REG_RETRY_LIMIT, 0x3030); +} + +static void rtw88xxa_init_edca(struct rtw_dev *rtwdev) +{ + rtw_write16(rtwdev, REG_SPEC_SIFS, 0x100a); + rtw_write16(rtwdev, REG_MAC_SPEC_SIFS, 0x100a); + + rtw_write16(rtwdev, REG_SIFS, 0x100a); + rtw_write16(rtwdev, REG_SIFS + 2, 0x100a); + + rtw_write32(rtwdev, REG_EDCA_BE_PARAM, 0x005EA42B); + rtw_write32(rtwdev, REG_EDCA_BK_PARAM, 0x0000A44F); + rtw_write32(rtwdev, REG_EDCA_VI_PARAM, 0x005EA324); + rtw_write32(rtwdev, REG_EDCA_VO_PARAM, 0x002FA226); + + rtw_write8(rtwdev, REG_USTIME_TSF, 0x50); + rtw_write8(rtwdev, REG_USTIME_EDCA, 0x50); +} + +static void rtw88xxau_tx_aggregation(struct rtw_dev *rtwdev) +{ + const struct rtw_chip_info *chip = rtwdev->chip; + + rtw_write32_mask(rtwdev, REG_DWBCN0_CTRL, 0xf0, + chip->usb_tx_agg_desc_num); + + if (chip->id == RTW_CHIP_TYPE_8821A) + rtw_write8(rtwdev, REG_DWBCN1_CTRL, + chip->usb_tx_agg_desc_num << 1); +} + +static void rtw88xxa_init_beacon_parameters(struct rtw_dev *rtwdev) +{ + u16 val16; + + val16 = (BIT_DIS_TSF_UDT << 8) | BIT_DIS_TSF_UDT; + if (rtwdev->efuse.btcoex) + val16 |= BIT_EN_BCN_FUNCTION; + rtw_write16(rtwdev, REG_BCN_CTRL, val16); + + rtw_write32_mask(rtwdev, REG_TBTT_PROHIBIT, 0xfffff, WLAN_TBTT_TIME); + rtw_write8(rtwdev, REG_DRVERLYINT, 0x05); + rtw_write8(rtwdev, REG_BCNDMATIM, WLAN_BCN_DMA_TIME); + rtw_write16(rtwdev, REG_BCNTCFG, 0x4413); +} + +static void rtw88xxa_phy_bb_config(struct rtw_dev *rtwdev) +{ + u8 val8, crystal_cap; + + /* power on BB/RF domain */ + val8 = rtw_read8(rtwdev, REG_SYS_FUNC_EN); + val8 |= BIT_FEN_USBA; + rtw_write8(rtwdev, REG_SYS_FUNC_EN, val8); + + /* toggle BB reset */ + val8 |= BIT_FEN_BB_RSTB | BIT_FEN_BB_GLB_RST; + rtw_write8(rtwdev, REG_SYS_FUNC_EN, val8); + + rtw_write8(rtwdev, REG_RF_CTRL, + BIT_RF_EN | BIT_RF_RSTB | BIT_RF_SDM_RSTB); + rtw_write8(rtwdev, REG_RF_B_CTRL, + BIT_RF_EN | BIT_RF_RSTB | BIT_RF_SDM_RSTB); + + rtw_load_table(rtwdev, rtwdev->chip->bb_tbl); + rtw_load_table(rtwdev, rtwdev->chip->agc_tbl); + + crystal_cap = rtwdev->efuse.crystal_cap & 0x3F; + if (rtwdev->chip->id == RTW_CHIP_TYPE_8812A) + rtw_write32_mask(rtwdev, REG_AFE_CTRL3, 0x7FF80000, + crystal_cap | (crystal_cap << 6)); + else + rtw_write32_mask(rtwdev, REG_AFE_CTRL3, 0x00FFF000, + crystal_cap | (crystal_cap << 6)); +} + +static void rtw88xxa_phy_rf_config(struct rtw_dev *rtwdev) +{ + u8 rf_path; + + for (rf_path = 0; rf_path < rtwdev->hal.rf_path_num; rf_path++) + rtw_load_table(rtwdev, rtwdev->chip->rf_tbl[rf_path]); +} + +static void rtw8812a_config_1t(struct rtw_dev *rtwdev) +{ + /* BB OFDM RX Path_A */ + rtw_write32_mask(rtwdev, REG_RXPSEL, 0xff, 0x11); + + /* BB OFDM TX Path_A */ + rtw_write32_mask(rtwdev, REG_TXPSEL, MASKLWORD, 0x1111); + + /* BB CCK R/Rx Path_A */ + rtw_write32_mask(rtwdev, REG_CCK_RX, 0x0c000000, 0x0); + + /* MCS support */ + rtw_write32_mask(rtwdev, REG_RX_MCS_LIMIT, 0xc0000060, 0x4); + + /* RF Path_B HSSI OFF */ + rtw_write32_mask(rtwdev, REG_3WIRE_SWB, 0xf, 0x4); + + /* RF Path_B Power Down */ + rtw_write32_mask(rtwdev, REG_LSSI_WRITE_B, MASKDWORD, 0); + + /* ADDA Path_B OFF */ + rtw_write32_mask(rtwdev, REG_AFE_PWR1_B, MASKDWORD, 0); + rtw_write32_mask(rtwdev, REG_AFE_PWR2_B, MASKDWORD, 0); +} + +static const u32 rtw88xxa_txscale_tbl[] = { + 0x081, 0x088, 0x090, 0x099, 0x0a2, 0x0ac, 0x0b6, 0x0c0, 0x0cc, 0x0d8, + 0x0e5, 0x0f2, 0x101, 0x110, 0x120, 0x131, 0x143, 0x156, 0x16a, 0x180, + 0x197, 0x1af, 0x1c8, 0x1e3, 0x200, 0x21e, 0x23e, 0x261, 0x285, 0x2ab, + 0x2d3, 0x2fe, 0x32b, 0x35c, 0x38e, 0x3c4, 0x3fe +}; + +static u32 rtw88xxa_get_bb_swing(struct rtw_dev *rtwdev, u8 band, u8 path) +{ + static const u32 swing2setting[4] = {0x200, 0x16a, 0x101, 0x0b6}; + struct rtw_efuse *efuse = &rtwdev->efuse; + u8 tx_bb_swing; + + if (band == RTW_BAND_2G) + tx_bb_swing = efuse->tx_bb_swing_setting_2g; + else + tx_bb_swing = efuse->tx_bb_swing_setting_5g; + + if (path == RF_PATH_B) + tx_bb_swing >>= 2; + tx_bb_swing &= 0x3; + + return swing2setting[tx_bb_swing]; +} + +static u8 rtw88xxa_get_swing_index(struct rtw_dev *rtwdev) +{ + u32 swing, table_value; + u8 i; + + swing = rtw88xxa_get_bb_swing(rtwdev, rtwdev->hal.current_band_type, + RF_PATH_A); + + for (i = 0; i < ARRAY_SIZE(rtw88xxa_txscale_tbl); i++) { + table_value = rtw88xxa_txscale_tbl[i]; + if (swing == table_value) + return i; + } + + return 24; +} + +static void rtw88xxa_pwrtrack_init(struct rtw_dev *rtwdev) +{ + struct rtw_dm_info *dm_info = &rtwdev->dm_info; + u8 path; + + dm_info->default_ofdm_index = rtw88xxa_get_swing_index(rtwdev); + + if (rtwdev->chip->id == RTW_CHIP_TYPE_8821A) + dm_info->default_cck_index = 0; + else + dm_info->default_cck_index = 24; + + for (path = RF_PATH_A; path < rtwdev->hal.rf_path_num; path++) { + ewma_thermal_init(&dm_info->avg_thermal[path]); + dm_info->delta_power_index[path] = 0; + dm_info->delta_power_index_last[path] = 0; + } + + dm_info->pwr_trk_triggered = false; + dm_info->pwr_trk_init_trigger = true; + dm_info->thermal_meter_k = rtwdev->efuse.thermal_meter_k; +} + +void rtw88xxa_power_off(struct rtw_dev *rtwdev, + const struct rtw_pwr_seq_cmd *const *enter_lps_flow) +{ + struct rtw_usb *rtwusb = rtw_get_usb_priv(rtwdev); + enum usb_device_speed speed = rtwusb->udev->speed; + u16 ori_fsmc0; + u8 reg_cr; + + reg_cr = rtw_read8(rtwdev, REG_CR); + + /* Already powered off */ + if (reg_cr == 0 || reg_cr == 0xEA) + return; + + rtw_hci_stop(rtwdev); + + if (!rtwdev->efuse.btcoex) + rtw_write16_clr(rtwdev, REG_GPIO_MUXCFG, BIT_EN_SIC); + + /* set Reg 0xf008[3:4] to 2'11 to enable U1/U2 Mode in USB3.0. */ + if (speed == USB_SPEED_SUPER) + rtw_write8_set(rtwdev, REG_USB_MOD, 0x18); + + rtw_write32(rtwdev, REG_HISR0, 0xffffffff); + rtw_write32(rtwdev, REG_HISR1, 0xffffffff); + rtw_write32(rtwdev, REG_HIMR0, 0); + rtw_write32(rtwdev, REG_HIMR1, 0); + + if (rtwdev->efuse.btcoex) + rtw_coex_power_off_setting(rtwdev); + + ori_fsmc0 = rtw_read16(rtwdev, REG_APS_FSMCO); + rtw_write16(rtwdev, REG_APS_FSMCO, ori_fsmc0 & ~APS_FSMCO_HW_POWERDOWN); + + /* Stop Tx Report Timer. */ + rtw_write8_clr(rtwdev, REG_TX_RPT_CTRL, BIT(1)); + + /* Stop Rx */ + rtw_write8(rtwdev, REG_CR, 0); + + rtw_pwr_seq_parser(rtwdev, enter_lps_flow); + + if (rtw_read8(rtwdev, REG_MCUFW_CTRL) & BIT_RAM_DL_SEL) + rtw88xxa_reset_8051(rtwdev); + + rtw_write8_clr(rtwdev, REG_SYS_FUNC_EN + 1, BIT(2)); + rtw_write8(rtwdev, REG_MCUFW_CTRL, 0); + + rtw_pwr_seq_parser(rtwdev, rtwdev->chip->pwr_off_seq); + + if (ori_fsmc0 & APS_FSMCO_HW_POWERDOWN) + rtw_write16_set(rtwdev, REG_APS_FSMCO, APS_FSMCO_HW_POWERDOWN); + + clear_bit(RTW_FLAG_POWERON, rtwdev->flags); +} +EXPORT_SYMBOL(rtw88xxa_power_off); + +static void rtw88xxa_set_channel_bb_swing(struct rtw_dev *rtwdev, u8 band) +{ + rtw_write32_mask(rtwdev, REG_TXSCALE_A, BB_SWING_MASK, + rtw88xxa_get_bb_swing(rtwdev, band, RF_PATH_A)); + rtw_write32_mask(rtwdev, REG_TXSCALE_B, BB_SWING_MASK, + rtw88xxa_get_bb_swing(rtwdev, band, RF_PATH_B)); + rtw88xxa_pwrtrack_init(rtwdev); +} + +static void rtw8821a_set_ext_band_switch(struct rtw_dev *rtwdev, u8 band) +{ + rtw_write32_mask(rtwdev, REG_LED_CFG, BIT_DPDT_SEL_EN, 0); + rtw_write32_mask(rtwdev, REG_LED_CFG, BIT_DPDT_WL_SEL, 1); + rtw_write32_mask(rtwdev, REG_RFE_INV_A, 0xf, 7); + rtw_write32_mask(rtwdev, REG_RFE_INV_A, 0xf0, 7); + + if (band == RTW_BAND_2G) + rtw_write32_mask(rtwdev, REG_RFE_INV_A, BIT(29) | BIT(28), 1); + else + rtw_write32_mask(rtwdev, REG_RFE_INV_A, BIT(29) | BIT(28), 2); +} + +static void rtw8821a_phy_set_rfe_reg_24g(struct rtw_dev *rtwdev) +{ + struct rtw_efuse *efuse = &rtwdev->efuse; + + /* Turn off RF PA and LNA */ + + /* 0xCB0[15:12] = 0x7 (LNA_On)*/ + rtw_write32_mask(rtwdev, REG_RFE_PINMUX_A, 0xF000, 0x7); + /* 0xCB0[7:4] = 0x7 (PAPE_A)*/ + rtw_write32_mask(rtwdev, REG_RFE_PINMUX_A, 0xF0, 0x7); + + if (efuse->ext_lna_2g) { + /* Turn on 2.4G External LNA */ + rtw_write32_mask(rtwdev, REG_RFE_INV_A, BIT(20), 1); + rtw_write32_mask(rtwdev, REG_RFE_INV_A, BIT(22), 0); + rtw_write32_mask(rtwdev, REG_RFE_PINMUX_A, GENMASK(2, 0), 0x2); + rtw_write32_mask(rtwdev, REG_RFE_PINMUX_A, GENMASK(10, 8), 0x2); + } else { + /* Bypass 2.4G External LNA */ + rtw_write32_mask(rtwdev, REG_RFE_INV_A, BIT(20), 0); + rtw_write32_mask(rtwdev, REG_RFE_INV_A, BIT(22), 0); + rtw_write32_mask(rtwdev, REG_RFE_PINMUX_A, GENMASK(2, 0), 0x7); + rtw_write32_mask(rtwdev, REG_RFE_PINMUX_A, GENMASK(10, 8), 0x7); + } +} + +static void rtw8821a_phy_set_rfe_reg_5g(struct rtw_dev *rtwdev) +{ + /* Turn ON RF PA and LNA */ + + /* 0xCB0[15:12] = 0x7 (LNA_On)*/ + rtw_write32_mask(rtwdev, REG_RFE_PINMUX_A, 0xF000, 0x5); + /* 0xCB0[7:4] = 0x7 (PAPE_A)*/ + rtw_write32_mask(rtwdev, REG_RFE_PINMUX_A, 0xF0, 0x4); + + /* Bypass 2.4G External LNA */ + rtw_write32_mask(rtwdev, REG_RFE_INV_A, BIT(20), 0); + rtw_write32_mask(rtwdev, REG_RFE_INV_A, BIT(22), 0); + rtw_write32_mask(rtwdev, REG_RFE_PINMUX_A, GENMASK(2, 0), 0x7); + rtw_write32_mask(rtwdev, REG_RFE_PINMUX_A, GENMASK(10, 8), 0x7); +} + +static void rtw8812a_phy_set_rfe_reg_24g(struct rtw_dev *rtwdev) +{ + switch (rtwdev->efuse.rfe_option) { + case 0: + case 2: + rtw_write32(rtwdev, REG_RFE_PINMUX_A, 0x77777777); + rtw_write32(rtwdev, REG_RFE_PINMUX_B, 0x77777777); + rtw_write32_mask(rtwdev, REG_RFE_INV_A, RFE_INV_MASK, 0x000); + rtw_write32_mask(rtwdev, REG_RFE_INV_B, RFE_INV_MASK, 0x000); + break; + case 1: + if (rtwdev->efuse.btcoex) { + rtw_write32_mask(rtwdev, REG_RFE_PINMUX_A, 0xffffff, 0x777777); + rtw_write32(rtwdev, REG_RFE_PINMUX_B, 0x77777777); + rtw_write32_mask(rtwdev, REG_RFE_INV_A, 0x33f00000, 0x000); + rtw_write32_mask(rtwdev, REG_RFE_INV_B, RFE_INV_MASK, 0x000); + } else { + rtw_write32(rtwdev, REG_RFE_PINMUX_A, 0x77777777); + rtw_write32(rtwdev, REG_RFE_PINMUX_B, 0x77777777); + rtw_write32_mask(rtwdev, REG_RFE_INV_A, RFE_INV_MASK, 0x000); + rtw_write32_mask(rtwdev, REG_RFE_INV_B, RFE_INV_MASK, 0x000); + } + break; + case 3: + rtw_write32(rtwdev, REG_RFE_PINMUX_A, 0x54337770); + rtw_write32(rtwdev, REG_RFE_PINMUX_B, 0x54337770); + rtw_write32_mask(rtwdev, REG_RFE_INV_A, RFE_INV_MASK, 0x010); + rtw_write32_mask(rtwdev, REG_RFE_INV_B, RFE_INV_MASK, 0x010); + rtw_write32_mask(rtwdev, REG_ANTSEL_SW, 0x00000303, 0x1); + break; + case 4: + rtw_write32(rtwdev, REG_RFE_PINMUX_A, 0x77777777); + rtw_write32(rtwdev, REG_RFE_PINMUX_B, 0x77777777); + rtw_write32_mask(rtwdev, REG_RFE_INV_A, RFE_INV_MASK, 0x001); + rtw_write32_mask(rtwdev, REG_RFE_INV_B, RFE_INV_MASK, 0x001); + break; + case 5: + rtw_write8(rtwdev, REG_RFE_PINMUX_A + 2, 0x77); + rtw_write32(rtwdev, REG_RFE_PINMUX_B, 0x77777777); + rtw_write8_clr(rtwdev, REG_RFE_INV_A + 3, BIT(0)); + rtw_write32_mask(rtwdev, REG_RFE_INV_B, RFE_INV_MASK, 0x000); + break; + case 6: + rtw_write32(rtwdev, REG_RFE_PINMUX_A, 0x07772770); + rtw_write32(rtwdev, REG_RFE_PINMUX_B, 0x07772770); + rtw_write32(rtwdev, REG_RFE_INV_A, 0x00000077); + rtw_write32(rtwdev, REG_RFE_INV_B, 0x00000077); + break; + default: + break; + } +} + +static void rtw8812a_phy_set_rfe_reg_5g(struct rtw_dev *rtwdev) +{ + switch (rtwdev->efuse.rfe_option) { + case 0: + rtw_write32(rtwdev, REG_RFE_PINMUX_A, 0x77337717); + rtw_write32(rtwdev, REG_RFE_PINMUX_B, 0x77337717); + rtw_write32_mask(rtwdev, REG_RFE_INV_A, RFE_INV_MASK, 0x010); + rtw_write32_mask(rtwdev, REG_RFE_INV_B, RFE_INV_MASK, 0x010); + break; + case 1: + if (rtwdev->efuse.btcoex) { + rtw_write32_mask(rtwdev, REG_RFE_PINMUX_A, 0xffffff, 0x337717); + rtw_write32(rtwdev, REG_RFE_PINMUX_B, 0x77337717); + rtw_write32_mask(rtwdev, REG_RFE_INV_A, 0x33f00000, 0x000); + rtw_write32_mask(rtwdev, REG_RFE_INV_B, RFE_INV_MASK, 0x000); + } else { + rtw_write32(rtwdev, REG_RFE_PINMUX_A, 0x77337717); + rtw_write32(rtwdev, REG_RFE_PINMUX_B, 0x77337717); + rtw_write32_mask(rtwdev, REG_RFE_INV_A, RFE_INV_MASK, 0x000); + rtw_write32_mask(rtwdev, REG_RFE_INV_B, RFE_INV_MASK, 0x000); + } + break; + case 2: + case 4: + rtw_write32(rtwdev, REG_RFE_PINMUX_A, 0x77337777); + rtw_write32(rtwdev, REG_RFE_PINMUX_B, 0x77337777); + rtw_write32_mask(rtwdev, REG_RFE_INV_A, RFE_INV_MASK, 0x010); + rtw_write32_mask(rtwdev, REG_RFE_INV_B, RFE_INV_MASK, 0x010); + break; + case 3: + rtw_write32(rtwdev, REG_RFE_PINMUX_A, 0x54337717); + rtw_write32(rtwdev, REG_RFE_PINMUX_B, 0x54337717); + rtw_write32_mask(rtwdev, REG_RFE_INV_A, RFE_INV_MASK, 0x010); + rtw_write32_mask(rtwdev, REG_RFE_INV_B, RFE_INV_MASK, 0x010); + rtw_write32_mask(rtwdev, REG_ANTSEL_SW, 0x00000303, 0x1); + break; + case 5: + rtw_write8(rtwdev, REG_RFE_PINMUX_A + 2, 0x33); + rtw_write32(rtwdev, REG_RFE_PINMUX_B, 0x77337777); + rtw_write8_set(rtwdev, REG_RFE_INV_A + 3, BIT(0)); + rtw_write32_mask(rtwdev, REG_RFE_INV_B, RFE_INV_MASK, 0x010); + break; + case 6: + rtw_write32(rtwdev, REG_RFE_PINMUX_A, 0x07737717); + rtw_write32(rtwdev, REG_RFE_PINMUX_B, 0x07737717); + rtw_write32(rtwdev, REG_RFE_INV_A, 0x00000077); + rtw_write32(rtwdev, REG_RFE_INV_B, 0x00000077); + break; + default: + break; + } +} + +static void rtw88xxa_switch_band(struct rtw_dev *rtwdev, u8 new_band, u8 bw) +{ + const struct rtw_chip_info *chip = rtwdev->chip; + u16 basic_rates, reg_41a; + + /* 8811au one antenna module doesn't support antenna div, so driver must + * control antenna band, otherwise one of the band will have issue + */ + if (chip->id == RTW_CHIP_TYPE_8821A && !rtwdev->efuse.btcoex && + rtwdev->efuse.ant_div_cfg == 0) + rtw8821a_set_ext_band_switch(rtwdev, new_band); + + if (new_band == RTW_BAND_2G) { + rtw_write32_set(rtwdev, REG_RXPSEL, BIT_RX_PSEL_RST); + + if (chip->id == RTW_CHIP_TYPE_8821A) { + rtw8821a_phy_set_rfe_reg_24g(rtwdev); + + rtw_write32_mask(rtwdev, REG_TXSCALE_A, 0xf00, 0); + } else { + rtw_write32_mask(rtwdev, REG_BWINDICATION, 0x3, 0x1); + rtw_write32_mask(rtwdev, REG_PDMFTH, GENMASK(17, 13), 0x17); + + if (bw == RTW_CHANNEL_WIDTH_20 && + rtwdev->hal.rf_type == RF_1T1R && + !rtwdev->efuse.ext_lna_2g) + rtw_write32_mask(rtwdev, REG_PDMFTH, GENMASK(3, 1), 0x02); + else + rtw_write32_mask(rtwdev, REG_PDMFTH, GENMASK(3, 1), 0x04); + + rtw_write32_mask(rtwdev, REG_CCASEL, 0x3, 0); + + rtw8812a_phy_set_rfe_reg_24g(rtwdev); + } + + rtw_write32_mask(rtwdev, REG_TXPSEL, 0xf0, 0x1); + rtw_write32_mask(rtwdev, REG_CCK_RX, 0x0f000000, 0x1); + + basic_rates = BIT(DESC_RATE1M) | BIT(DESC_RATE2M) | + BIT(DESC_RATE5_5M) | BIT(DESC_RATE11M) | + BIT(DESC_RATE6M) | BIT(DESC_RATE12M) | + BIT(DESC_RATE24M); + rtw_write32_mask(rtwdev, REG_RRSR, 0xfffff, basic_rates); + + rtw_write8_clr(rtwdev, REG_CCK_CHECK, BIT_CHECK_CCK_EN); + } else { /* RTW_BAND_5G */ + if (chip->id == RTW_CHIP_TYPE_8821A) + rtw8821a_phy_set_rfe_reg_5g(rtwdev); + + rtw_write8_set(rtwdev, REG_CCK_CHECK, BIT_CHECK_CCK_EN); + + read_poll_timeout_atomic(rtw_read16, reg_41a, (reg_41a & 0x30) == 0x30, + 50, 2500, false, rtwdev, REG_TXPKT_EMPTY); + + rtw_write32_set(rtwdev, REG_RXPSEL, BIT_RX_PSEL_RST); + + if (chip->id == RTW_CHIP_TYPE_8821A) { + rtw_write32_mask(rtwdev, REG_TXSCALE_A, 0xf00, 1); + } else { + rtw_write32_mask(rtwdev, REG_BWINDICATION, 0x3, 0x2); + rtw_write32_mask(rtwdev, REG_PDMFTH, GENMASK(17, 13), 0x15); + rtw_write32_mask(rtwdev, REG_PDMFTH, GENMASK(3, 1), 0x04); + + rtw_write32_mask(rtwdev, REG_CCASEL, 0x3, 1); + + rtw8812a_phy_set_rfe_reg_5g(rtwdev); + } + + rtw_write32_mask(rtwdev, REG_TXPSEL, 0xf0, 0); + rtw_write32_mask(rtwdev, REG_CCK_RX, 0x0f000000, 0xf); + + basic_rates = BIT(DESC_RATE6M) | BIT(DESC_RATE12M) | + BIT(DESC_RATE24M); + rtw_write32_mask(rtwdev, REG_RRSR, 0xfffff, basic_rates); + } + + rtw88xxa_set_channel_bb_swing(rtwdev, new_band); +} + +int rtw88xxa_power_on(struct rtw_dev *rtwdev) +{ + struct rtw_usb *rtwusb = rtw_get_usb_priv(rtwdev); + const struct rtw_chip_info *chip = rtwdev->chip; + struct rtw_efuse *efuse = &rtwdev->efuse; + struct rtw_hal *hal = &rtwdev->hal; + int ret; + + if (test_bit(RTW_FLAG_POWERON, rtwdev->flags)) + return 0; + + /* Override rtw_chip_efuse_info_setup() */ + if (chip->id == RTW_CHIP_TYPE_8821A) + efuse->btcoex = rtw_read32_mask(rtwdev, REG_WL_BT_PWR_CTRL, + BIT_BT_FUNC_EN); + + /* Override rtw_chip_efuse_info_setup() */ + if (chip->id == RTW_CHIP_TYPE_8812A) + rtw8812a_read_amplifier_type(rtwdev); + + ret = rtw_hci_setup(rtwdev); + if (ret) { + rtw_err(rtwdev, "failed to setup hci\n"); + goto err; + } + + /* Revise for U2/U3 switch we can not update RF-A/B reset. + * Reset after MAC power on to prevent RF R/W error. + * Is it a right method? + */ + if (chip->id == RTW_CHIP_TYPE_8812A) { + rtw_write8(rtwdev, REG_RF_CTRL, 5); + rtw_write8(rtwdev, REG_RF_CTRL, 7); + rtw_write8(rtwdev, REG_RF_B_CTRL, 5); + rtw_write8(rtwdev, REG_RF_B_CTRL, 7); + } + + /* If HW didn't go through a complete de-initial procedure, + * it probably occurs some problem for double initial + * procedure. + */ + rtw88xxau_hw_reset(rtwdev); + + ret = rtw88xxau_init_power_on(rtwdev); + if (ret) { + rtw_err(rtwdev, "failed to power on\n"); + goto err; + } + + ret = rtw_set_trx_fifo_info(rtwdev); + if (ret) { + rtw_err(rtwdev, "failed to set trx fifo info\n"); + goto err; + } + + ret = rtw88xxa_llt_init(rtwdev, rtwdev->fifo.rsvd_boundary); + if (ret) { + rtw_err(rtwdev, "failed to init llt\n"); + goto err; + } + + rtw_write32_set(rtwdev, REG_TXDMA_OFFSET_CHK, BIT_DROP_DATA_EN); + + ret = rtw_wait_firmware_completion(rtwdev); + if (ret) { + rtw_err(rtwdev, "failed to wait firmware completion\n"); + goto err_off; + } + + ret = rtw_download_firmware(rtwdev, &rtwdev->fw); + if (ret) { + rtw_err(rtwdev, "failed to download firmware\n"); + goto err_off; + } + + rtw_write8(rtwdev, REG_HMETFR, 0xf); + + rtw_load_table(rtwdev, chip->mac_tbl); + + rtw88xxau_init_queue_reserved_page(rtwdev); + rtw88xxau_init_tx_buffer_boundary(rtwdev); + rtw88xxau_init_queue_priority(rtwdev); + + rtw_write16(rtwdev, REG_TRXFF_BNDY + 2, + chip->rxff_size - REPORT_BUF - 1); + + if (chip->id == RTW_CHIP_TYPE_8812A) + rtw_write8(rtwdev, REG_PBP, + u8_encode_bits(PBP_512, PBP_TX_MASK) | + u8_encode_bits(PBP_64, PBP_RX_MASK)); + + rtw_write8(rtwdev, REG_RX_DRVINFO_SZ, PHY_STATUS_SIZE); + + rtw_write32(rtwdev, REG_HIMR0, 0); + rtw_write32(rtwdev, REG_HIMR1, 0); + + rtw_write32_mask(rtwdev, REG_CR, 0x30000, 0x2); + + rtw88xxa_init_wmac_setting(rtwdev); + rtw88xxa_init_adaptive_ctrl(rtwdev); + rtw88xxa_init_edca(rtwdev); + + rtw_write8_set(rtwdev, REG_FWHW_TXQ_CTRL, BIT(7)); + rtw_write8(rtwdev, REG_ACKTO, 0x80); + + rtw88xxau_tx_aggregation(rtwdev); + + rtw88xxa_init_beacon_parameters(rtwdev); + rtw_write8(rtwdev, REG_BCN_MAX_ERR, 0xff); + + rtw_hci_interface_cfg(rtwdev); + + /* usb3 rx interval */ + rtw_write8(rtwdev, REG_USB3_RXITV, 0x01); + + /* burst length=4, set 0x3400 for burst length=2 */ + rtw_write16(rtwdev, REG_RXDMA_STATUS, 0x7400); + rtw_write8(rtwdev, REG_RXDMA_STATUS + 1, 0xf5); + + /* 0x456 = 0x70, sugguested by Zhilin */ + if (chip->id == RTW_CHIP_TYPE_8821A) + rtw_write8(rtwdev, REG_AMPDU_MAX_TIME, 0x5e); + else + rtw_write8(rtwdev, REG_AMPDU_MAX_TIME, 0x70); + + rtw_write32(rtwdev, REG_AMPDU_MAX_LENGTH, 0xffffffff); + rtw_write8(rtwdev, REG_USTIME_TSF, 0x50); + rtw_write8(rtwdev, REG_USTIME_EDCA, 0x50); + + if (rtwusb->udev->speed == USB_SPEED_SUPER) + /* Disable U1/U2 Mode to avoid 2.5G spur in USB3.0. */ + rtw_write8_clr(rtwdev, REG_USB_MOD, BIT(4) | BIT(3)); + + rtw_write8_set(rtwdev, REG_SINGLE_AMPDU_CTRL, BIT_EN_SINGLE_APMDU); + + /* for VHT packet length 11K */ + rtw_write8(rtwdev, REG_RX_PKT_LIMIT, 0x18); + + rtw_write8(rtwdev, REG_PIFS, 0x00); + + if (chip->id == RTW_CHIP_TYPE_8821A) { + /* 0x0a0a too small, it can't pass AC logo. change to 0x1f1f */ + rtw_write16(rtwdev, REG_MAX_AGGR_NUM, 0x1f1f); + rtw_write8(rtwdev, REG_FWHW_TXQ_CTRL, 0x80); + rtw_write32(rtwdev, REG_FAST_EDCA_CTRL, 0x03087777); + } else { + rtw_write16(rtwdev, REG_MAX_AGGR_NUM, 0x1f1f); + rtw_write8_clr(rtwdev, REG_FWHW_TXQ_CTRL, BIT(7)); + } + + /* to prevent mac is reseted by bus. */ + rtw_write8_set(rtwdev, REG_RSV_CTRL, BIT(5) | BIT(6)); + + /* ARFB table 9 for 11ac 5G 2SS */ + rtw_write32(rtwdev, REG_ARFR0, 0x00000010); + rtw_write32(rtwdev, REG_ARFRH0, 0xfffff000); + + /* ARFB table 10 for 11ac 5G 1SS */ + rtw_write32(rtwdev, REG_ARFR1_V1, 0x00000010); + rtw_write32(rtwdev, REG_ARFRH1_V1, 0x003ff000); + + /* ARFB table 11 for 11ac 24G 1SS */ + rtw_write32(rtwdev, REG_ARFR2_V1, 0x00000015); + rtw_write32(rtwdev, REG_ARFRH2_V1, 0x003ff000); + + /* ARFB table 12 for 11ac 24G 2SS */ + rtw_write32(rtwdev, REG_ARFR3_V1, 0x00000015); + rtw_write32(rtwdev, REG_ARFRH3_V1, 0xffcff000); + + rtw_write8_set(rtwdev, REG_CR, BIT_MACTXEN | BIT_MACRXEN); + + ///TODO: blinking controlled by mac80211 + if (rtwdev->chip->id == RTW_CHIP_TYPE_8821A) + rtw_write8(rtwdev, REG_LED_CFG + 2, BIT(1) | BIT(5)); + else + rtw_write8(rtwdev, REG_LED_CFG, BIT(1) | BIT(5)); + + rtw88xxa_phy_bb_config(rtwdev); + rtw88xxa_phy_rf_config(rtwdev); + + if (chip->id == RTW_CHIP_TYPE_8812A && hal->rf_path_num == 1) + rtw8812a_config_1t(rtwdev); + + rtw88xxa_switch_band(rtwdev, RTW_BAND_2G, RTW_CHANNEL_WIDTH_20); + + rtw_write32(rtwdev, RTW_SEC_CMD_REG, BIT(31) | BIT(30)); + + rtw_write8(rtwdev, REG_HWSEQ_CTRL, 0xff); + rtw_write32(rtwdev, REG_BAR_MODE_CTRL, 0x0201ffff); + rtw_write8(rtwdev, REG_NAV_CTRL + 2, 0); + + rtw_write8_clr(rtwdev, REG_GPIO_MUXCFG, BIT(5)); + + rtw_phy_init(rtwdev); + + rtw88xxa_pwrtrack_init(rtwdev); + + /* 0x4c6[3] 1: RTS BW = Data BW + * 0: RTS BW depends on CCA / secondary CCA result. + */ + rtw_write8_clr(rtwdev, REG_QUEUE_CTRL, BIT(3)); + + /* enable Tx report. */ + rtw_write8(rtwdev, REG_FWHW_TXQ_CTRL + 1, 0x0f); + + /* Pretx_en, for WEP/TKIP SEC */ + rtw_write8(rtwdev, REG_EARLY_MODE_CONTROL + 3, 0x01); + + rtw_write16(rtwdev, REG_TX_RPT_TIME, 0x3df0); + + /* Reset USB mode switch setting */ + rtw_write8(rtwdev, REG_SYS_SDIO_CTRL, 0x0); + rtw_write8(rtwdev, REG_ACLK_MON, 0x0); + + rtw_write8(rtwdev, REG_USB_HRPWM, 0); + + /* ack for xmit mgmt frames. */ + rtw_write32_set(rtwdev, REG_FWHW_TXQ_CTRL, BIT(12)); + + hal->cck_high_power = rtw_read32_mask(rtwdev, REG_CCK_RPT_FORMAT, + BIT_CCK_RPT_FORMAT); + + ret = rtw_hci_start(rtwdev); + if (ret) { + rtw_err(rtwdev, "failed to start hci\n"); + goto err_off; + } + + if (efuse->btcoex) { + rtw_coex_power_on_setting(rtwdev); + rtw_coex_init_hw_config(rtwdev, false); + } + + set_bit(RTW_FLAG_POWERON, rtwdev->flags); + + return 0; + +err_off: + chip->ops->power_off(rtwdev); + +err: + return ret; +} +EXPORT_SYMBOL(rtw88xxa_power_on); + +u32 rtw88xxa_phy_read_rf(struct rtw_dev *rtwdev, + enum rtw_rf_path rf_path, u32 addr, u32 mask) +{ + static const u32 pi_addr[2] = { REG_3WIRE_SWA, REG_3WIRE_SWB }; + static const u32 read_addr[2][2] = { + { REG_SI_READ_A, REG_SI_READ_B }, + { REG_PI_READ_A, REG_PI_READ_B } + }; + const struct rtw_chip_info *chip = rtwdev->chip; + const struct rtw_hal *hal = &rtwdev->hal; + bool set_cca, pi_mode; + u32 val; + + if (rf_path >= hal->rf_phy_num) { + rtw_err(rtwdev, "unsupported rf path (%d)\n", rf_path); + return INV_RF_DATA; + } + + /* CCA off to avoid reading the wrong value. + * Toggling CCA would affect RF 0x0, skip it. + */ + set_cca = addr != 0x0 && chip->id == RTW_CHIP_TYPE_8812A && + hal->cut_version != RTW_CHIP_VER_CUT_C; + + if (set_cca) + rtw_write32_set(rtwdev, REG_CCA2ND, BIT(3)); + + addr &= 0xff; + + pi_mode = rtw_read32_mask(rtwdev, pi_addr[rf_path], 0x4); + + rtw_write32_mask(rtwdev, REG_HSSI_READ, MASKBYTE0, addr); + + if (chip->id == RTW_CHIP_TYPE_8821A || + hal->cut_version == RTW_CHIP_VER_CUT_C) + udelay(20); + + val = rtw_read32_mask(rtwdev, read_addr[pi_mode][rf_path], mask); + + /* CCA on */ + if (set_cca) + rtw_write32_clr(rtwdev, REG_CCA2ND, BIT(3)); + + return val; +} +EXPORT_SYMBOL(rtw88xxa_phy_read_rf); + +static void rtw8812a_phy_fix_spur(struct rtw_dev *rtwdev, u8 channel, u8 bw) +{ + /* C cut Item12 ADC FIFO CLOCK */ + if (rtwdev->hal.cut_version == RTW_CHIP_VER_CUT_C) { + if (bw == RTW_CHANNEL_WIDTH_40 && channel == 11) + rtw_write32_mask(rtwdev, REG_ADCCLK, 0xC00, 0x3); + else + rtw_write32_mask(rtwdev, REG_ADCCLK, 0xC00, 0x2); + + /* A workaround to resolve 2480Mhz spur by setting ADC clock + * as 160M. + */ + if (bw == RTW_CHANNEL_WIDTH_20 && (channel == 13 || channel == 14)) { + rtw_write32_mask(rtwdev, REG_ADCCLK, 0x300, 0x3); + rtw_write32_mask(rtwdev, REG_ADC160, BIT(30), 1); + } else if (bw == RTW_CHANNEL_WIDTH_40 && channel == 11) { + rtw_write32_mask(rtwdev, REG_ADC160, BIT(30), 1); + } else if (bw != RTW_CHANNEL_WIDTH_80) { + rtw_write32_mask(rtwdev, REG_ADCCLK, 0x300, 0x2); + rtw_write32_mask(rtwdev, REG_ADC160, BIT(30), 0); + } + } else { + /* A workaround to resolve 2480Mhz spur by setting ADC clock + * as 160M. + */ + if (bw == RTW_CHANNEL_WIDTH_20 && (channel == 13 || channel == 14)) + rtw_write32_mask(rtwdev, REG_ADCCLK, 0x300, 0x3); + else if (channel <= 14) /* 2.4G only */ + rtw_write32_mask(rtwdev, REG_ADCCLK, 0x300, 0x2); + } +} + +static void rtw88xxa_switch_channel(struct rtw_dev *rtwdev, u8 channel, u8 bw) +{ + struct rtw_hal *hal = &rtwdev->hal; + u32 fc_area, rf_mod_ag; + u8 path; + + switch (channel) { + case 36 ... 48: + fc_area = 0x494; + break; + case 50 ... 64: + fc_area = 0x453; + break; + case 100 ... 116: + fc_area = 0x452; + break; + default: + if (channel >= 118) + fc_area = 0x412; + else + fc_area = 0x96a; + break; + } + + rtw_write32_mask(rtwdev, REG_CLKTRK, 0x1ffe0000, fc_area); + + for (path = 0; path < hal->rf_path_num; path++) { + switch (channel) { + case 36 ... 64: + rf_mod_ag = 0x101; + break; + case 100 ... 140: + rf_mod_ag = 0x301; + break; + default: + if (channel > 140) + rf_mod_ag = 0x501; + else + rf_mod_ag = 0x000; + break; + } + + rtw_write_rf(rtwdev, path, RF_CFGCH, + RF18_RFSI_MASK | RF18_BAND_MASK, rf_mod_ag); + + if (rtwdev->chip->id == RTW_CHIP_TYPE_8812A) + rtw8812a_phy_fix_spur(rtwdev, channel, bw); + + rtw_write_rf(rtwdev, path, RF_CFGCH, RF18_CHANNEL_MASK, channel); + } +} + +static void rtw88xxa_set_reg_bw(struct rtw_dev *rtwdev, u8 bw) +{ + u16 val16 = rtw_read16(rtwdev, REG_WMAC_TRXPTCL_CTL); + + val16 &= ~BIT_RFMOD; + if (bw == RTW_CHANNEL_WIDTH_80) + val16 |= BIT_RFMOD_80M; + else if (bw == RTW_CHANNEL_WIDTH_40) + val16 |= BIT_RFMOD_40M; + + rtw_write16(rtwdev, REG_WMAC_TRXPTCL_CTL, val16); +} + +static void rtw88xxa_post_set_bw_mode(struct rtw_dev *rtwdev, u8 channel, + u8 bw, u8 primary_chan_idx) +{ + struct rtw_hal *hal = &rtwdev->hal; + u8 txsc40 = 0, txsc20, txsc; + u8 reg_837, l1pkval; + + rtw88xxa_set_reg_bw(rtwdev, bw); + + txsc20 = primary_chan_idx; + if (bw == RTW_CHANNEL_WIDTH_80) { + if (txsc20 == RTW_SC_20_UPPER || txsc20 == RTW_SC_20_UPMOST) + txsc40 = RTW_SC_40_UPPER; + else + txsc40 = RTW_SC_40_LOWER; + } + + txsc = BIT_TXSC_20M(txsc20) | BIT_TXSC_40M(txsc40); + rtw_write8(rtwdev, REG_DATA_SC, txsc); + + reg_837 = rtw_read8(rtwdev, REG_BWINDICATION + 3); + + switch (bw) { + default: + case RTW_CHANNEL_WIDTH_20: + rtw_write32_mask(rtwdev, REG_ADCCLK, 0x003003C3, 0x00300200); + rtw_write32_mask(rtwdev, REG_ADC160, BIT(30), 0); + + if (hal->rf_type == RF_2T2R) + rtw_write32_mask(rtwdev, REG_L1PKTH, 0x03C00000, 7); + else + rtw_write32_mask(rtwdev, REG_L1PKTH, 0x03C00000, 8); + + break; + case RTW_CHANNEL_WIDTH_40: + rtw_write32_mask(rtwdev, REG_ADCCLK, 0x003003C3, 0x00300201); + rtw_write32_mask(rtwdev, REG_ADC160, BIT(30), 0); + rtw_write32_mask(rtwdev, REG_ADCCLK, 0x3C, txsc); + rtw_write32_mask(rtwdev, REG_CCA2ND, 0xf0000000, txsc); + + if (reg_837 & BIT(2)) { + l1pkval = 6; + } else { + if (hal->rf_type == RF_2T2R) + l1pkval = 7; + else + l1pkval = 8; + } + + rtw_write32_mask(rtwdev, REG_L1PKTH, 0x03C00000, l1pkval); + + if (txsc == RTW_SC_20_UPPER) + rtw_write32_set(rtwdev, REG_RXSB, BIT(4)); + else + rtw_write32_clr(rtwdev, REG_RXSB, BIT(4)); + + break; + case RTW_CHANNEL_WIDTH_80: + rtw_write32_mask(rtwdev, REG_ADCCLK, 0x003003C3, 0x00300202); + rtw_write32_mask(rtwdev, REG_ADC160, BIT(30), 1); + rtw_write32_mask(rtwdev, REG_ADCCLK, 0x3C, txsc); + rtw_write32_mask(rtwdev, REG_CCA2ND, 0xf0000000, txsc); + + if (reg_837 & BIT(2)) { + l1pkval = 5; + } else { + if (hal->rf_type == RF_2T2R) + l1pkval = 6; + else + l1pkval = 7; + } + + rtw_write32_mask(rtwdev, REG_L1PKTH, 0x03C00000, l1pkval); + + break; + } +} + +static void rtw88xxa_set_channel_rf(struct rtw_dev *rtwdev, u8 channel, u8 bw) +{ + u8 path; + + for (path = RF_PATH_A; path < rtwdev->hal.rf_path_num; path++) { + switch (bw) { + case RTW_CHANNEL_WIDTH_5: + case RTW_CHANNEL_WIDTH_10: + case RTW_CHANNEL_WIDTH_20: + default: + rtw_write_rf(rtwdev, path, RF_CFGCH, RF18_BW_MASK, 3); + break; + case RTW_CHANNEL_WIDTH_40: + rtw_write_rf(rtwdev, path, RF_CFGCH, RF18_BW_MASK, 1); + break; + case RTW_CHANNEL_WIDTH_80: + rtw_write_rf(rtwdev, path, RF_CFGCH, RF18_BW_MASK, 0); + break; + } + } +} + +void rtw88xxa_set_channel(struct rtw_dev *rtwdev, u8 channel, u8 bw, + u8 primary_chan_idx) +{ + u8 old_band, new_band; + + if (rtw_read8(rtwdev, REG_CCK_CHECK) & BIT_CHECK_CCK_EN) + old_band = RTW_BAND_5G; + else + old_band = RTW_BAND_2G; + + if (channel > 14) + new_band = RTW_BAND_5G; + else + new_band = RTW_BAND_2G; + + if (new_band != old_band) + rtw88xxa_switch_band(rtwdev, new_band, bw); + + rtw88xxa_switch_channel(rtwdev, channel, bw); + + rtw88xxa_post_set_bw_mode(rtwdev, channel, bw, primary_chan_idx); + + if (rtwdev->chip->id == RTW_CHIP_TYPE_8812A) + rtw8812a_phy_fix_spur(rtwdev, channel, bw); + + rtw88xxa_set_channel_rf(rtwdev, channel, bw); +} +EXPORT_SYMBOL(rtw88xxa_set_channel); + +void rtw88xxa_query_phy_status(struct rtw_dev *rtwdev, u8 *phy_status, + struct rtw_rx_pkt_stat *pkt_stat, + s8 (*cck_rx_pwr)(u8 lna_idx, u8 vga_idx)) +{ + struct rtw_dm_info *dm_info = &rtwdev->dm_info; + struct rtw_jaguar_phy_status_rpt *rpt; + u8 gain[RTW_RF_PATH_MAX], rssi, i; + s8 rx_pwr_db, power_a, power_b; + const s8 min_rx_power = -120; + u8 lna_idx, vga_idx; + + rpt = (struct rtw_jaguar_phy_status_rpt *)phy_status; + + if (pkt_stat->rate <= DESC_RATE11M) { + lna_idx = le32_get_bits(rpt->w1, RTW_JGRPHY_W1_AGC_RPT_LNA_IDX); + vga_idx = le32_get_bits(rpt->w1, RTW_JGRPHY_W1_AGC_RPT_VGA_IDX); + + rx_pwr_db = cck_rx_pwr(lna_idx, vga_idx); + + pkt_stat->rx_power[RF_PATH_A] = rx_pwr_db; + pkt_stat->rssi = rtw_phy_rf_power_2_rssi(pkt_stat->rx_power, 1); + dm_info->rssi[RF_PATH_A] = pkt_stat->rssi; + pkt_stat->bw = RTW_CHANNEL_WIDTH_20; + pkt_stat->signal_power = rx_pwr_db; + } else { /* OFDM rate */ + gain[RF_PATH_A] = le32_get_bits(rpt->w0, RTW_JGRPHY_W0_GAIN_A); + gain[RF_PATH_B] = le32_get_bits(rpt->w0, RTW_JGRPHY_W0_GAIN_B); + + for (i = RF_PATH_A; i < rtwdev->hal.rf_path_num; i++) { + pkt_stat->rx_power[i] = gain[i] - 110; + rssi = rtw_phy_rf_power_2_rssi(&pkt_stat->rx_power[i], 1); + dm_info->rssi[i] = rssi; + } + + pkt_stat->rssi = rtw_phy_rf_power_2_rssi(pkt_stat->rx_power, + rtwdev->hal.rf_path_num); + + power_a = pkt_stat->rx_power[RF_PATH_A]; + power_b = pkt_stat->rx_power[RF_PATH_B]; + if (rtwdev->hal.rf_path_num == 1) + power_b = power_a; + + pkt_stat->signal_power = max3(power_a, power_b, min_rx_power); + } +} +EXPORT_SYMBOL(rtw88xxa_query_phy_status); + +static void +rtw88xxa_set_tx_power_index_by_rate(struct rtw_dev *rtwdev, u8 path, + u8 rs, u32 *phy_pwr_idx) +{ + static const u32 offset_txagc[2] = { + REG_TX_AGC_A_CCK_11_CCK_1, REG_TX_AGC_B_CCK_11_CCK_1 + }; + u8 rate, rate_idx, pwr_index, shift; + struct rtw_hal *hal = &rtwdev->hal; + bool write_1ss_mcs9; + u32 mask; + int j; + + for (j = 0; j < rtw_rate_size[rs]; j++) { + rate = rtw_rate_section[rs][j]; + + pwr_index = hal->tx_pwr_tbl[path][rate]; + + shift = rate & 0x3; + *phy_pwr_idx |= ((u32)pwr_index << (shift * 8)); + + write_1ss_mcs9 = rate == DESC_RATEVHT1SS_MCS9 && + hal->rf_path_num == 1; + + if (write_1ss_mcs9) + mask = MASKLWORD; + else + mask = MASKDWORD; + + if (shift == 0x3 || write_1ss_mcs9) { + rate_idx = rate & 0xfc; + if (rate >= DESC_RATEVHT1SS_MCS0) + rate_idx -= 0x10; + + rtw_write32_mask(rtwdev, offset_txagc[path] + rate_idx, + mask, *phy_pwr_idx); + + *phy_pwr_idx = 0; + } + } +} + +static void rtw88xxa_tx_power_training(struct rtw_dev *rtwdev, u8 bw, + u8 channel, u8 path) +{ + static const u32 write_offset[] = { + REG_TX_PWR_TRAINING_A, REG_TX_PWR_TRAINING_B, + }; + u32 power_level, write_data; + u8 i; + + power_level = rtwdev->hal.tx_pwr_tbl[path][DESC_RATEMCS7]; + write_data = 0; + + for (i = 0; i < 3; i++) { + if (i == 0) + power_level -= 10; + else if (i == 1) + power_level -= 8; + else + power_level -= 6; + + write_data |= max_t(u32, power_level, 2) << (i * 8); + } + + rtw_write32_mask(rtwdev, write_offset[path], 0xffffff, write_data); +} + +void rtw88xxa_set_tx_power_index(struct rtw_dev *rtwdev) +{ + struct rtw_hal *hal = &rtwdev->hal; + u32 phy_pwr_idx = 0; + int rs, path; + + for (path = 0; path < hal->rf_path_num; path++) { + for (rs = 0; rs < RTW_RATE_SECTION_MAX; rs++) { + if (hal->rf_path_num == 1 && + (rs == RTW_RATE_SECTION_HT_2S || + rs == RTW_RATE_SECTION_VHT_2S)) + continue; + + if (test_bit(RTW_FLAG_SCANNING, rtwdev->flags) && + rs > RTW_RATE_SECTION_OFDM) + continue; + + if (hal->current_band_type == RTW_BAND_5G && + rs == RTW_RATE_SECTION_CCK) + continue; + + rtw88xxa_set_tx_power_index_by_rate(rtwdev, path, rs, + &phy_pwr_idx); + } + + rtw88xxa_tx_power_training(rtwdev, hal->current_band_width, + hal->current_channel, path); + } +} +EXPORT_SYMBOL(rtw88xxa_set_tx_power_index); + +void rtw88xxa_false_alarm_statistics(struct rtw_dev *rtwdev) +{ + struct rtw_dm_info *dm_info = &rtwdev->dm_info; + u32 cck_fa_cnt, ofdm_fa_cnt; + u32 crc32_cnt, cca32_cnt; + u32 cck_enable; + + cck_enable = rtw_read32(rtwdev, REG_RXPSEL) & BIT(28); + cck_fa_cnt = rtw_read16(rtwdev, REG_FA_CCK); + ofdm_fa_cnt = rtw_read16(rtwdev, REG_FA_OFDM); + + dm_info->cck_fa_cnt = cck_fa_cnt; + dm_info->ofdm_fa_cnt = ofdm_fa_cnt; + dm_info->total_fa_cnt = ofdm_fa_cnt; + if (cck_enable) + dm_info->total_fa_cnt += cck_fa_cnt; + + crc32_cnt = rtw_read32(rtwdev, REG_CRC_CCK); + dm_info->cck_ok_cnt = u32_get_bits(crc32_cnt, MASKLWORD); + dm_info->cck_err_cnt = u32_get_bits(crc32_cnt, MASKHWORD); + + crc32_cnt = rtw_read32(rtwdev, REG_CRC_OFDM); + dm_info->ofdm_ok_cnt = u32_get_bits(crc32_cnt, MASKLWORD); + dm_info->ofdm_err_cnt = u32_get_bits(crc32_cnt, MASKHWORD); + + crc32_cnt = rtw_read32(rtwdev, REG_CRC_HT); + dm_info->ht_ok_cnt = u32_get_bits(crc32_cnt, MASKLWORD); + dm_info->ht_err_cnt = u32_get_bits(crc32_cnt, MASKHWORD); + + crc32_cnt = rtw_read32(rtwdev, REG_CRC_VHT); + dm_info->vht_ok_cnt = u32_get_bits(crc32_cnt, MASKLWORD); + dm_info->vht_err_cnt = u32_get_bits(crc32_cnt, MASKHWORD); + + cca32_cnt = rtw_read32(rtwdev, REG_CCA_OFDM); + dm_info->ofdm_cca_cnt = u32_get_bits(cca32_cnt, MASKHWORD); + dm_info->total_cca_cnt = dm_info->ofdm_cca_cnt; + if (cck_enable) { + cca32_cnt = rtw_read32(rtwdev, REG_CCA_CCK); + dm_info->cck_cca_cnt = u32_get_bits(cca32_cnt, MASKLWORD); + dm_info->total_cca_cnt += dm_info->cck_cca_cnt; + } + + rtw_write32_set(rtwdev, REG_FAS, BIT(17)); + rtw_write32_clr(rtwdev, REG_FAS, BIT(17)); + rtw_write32_clr(rtwdev, REG_CCK0_FAREPORT, BIT(15)); + rtw_write32_set(rtwdev, REG_CCK0_FAREPORT, BIT(15)); + rtw_write32_set(rtwdev, REG_CNTRST, BIT(0)); + rtw_write32_clr(rtwdev, REG_CNTRST, BIT(0)); +} +EXPORT_SYMBOL(rtw88xxa_false_alarm_statistics); + +void rtw88xxa_iqk_backup_mac_bb(struct rtw_dev *rtwdev, + u32 *macbb_backup, + const u32 *backup_macbb_reg, + u32 macbb_num) +{ + u32 i; + + /* [31] = 0 --> Page C */ + rtw_write32_mask(rtwdev, REG_CCASEL, BIT(31), 0x0); + + /* save MACBB default value */ + for (i = 0; i < macbb_num; i++) + macbb_backup[i] = rtw_read32(rtwdev, backup_macbb_reg[i]); +} +EXPORT_SYMBOL(rtw88xxa_iqk_backup_mac_bb); + +void rtw88xxa_iqk_backup_afe(struct rtw_dev *rtwdev, u32 *afe_backup, + const u32 *backup_afe_reg, u32 afe_num) +{ + u32 i; + + /* [31] = 0 --> Page C */ + rtw_write32_mask(rtwdev, REG_CCASEL, BIT(31), 0x0); + + /* Save AFE Parameters */ + for (i = 0; i < afe_num; i++) + afe_backup[i] = rtw_read32(rtwdev, backup_afe_reg[i]); +} +EXPORT_SYMBOL(rtw88xxa_iqk_backup_afe); + +void rtw88xxa_iqk_restore_mac_bb(struct rtw_dev *rtwdev, + u32 *macbb_backup, + const u32 *backup_macbb_reg, + u32 macbb_num) +{ + u32 i; + + /* [31] = 0 --> Page C */ + rtw_write32_mask(rtwdev, REG_CCASEL, BIT(31), 0x0); + + /* Reload MacBB Parameters */ + for (i = 0; i < macbb_num; i++) + rtw_write32(rtwdev, backup_macbb_reg[i], macbb_backup[i]); +} +EXPORT_SYMBOL(rtw88xxa_iqk_restore_mac_bb); + +void rtw88xxa_iqk_configure_mac(struct rtw_dev *rtwdev) +{ + /* [31] = 0 --> Page C */ + rtw_write32_mask(rtwdev, REG_CCASEL, BIT(31), 0x0); + + rtw_write8(rtwdev, REG_TXPAUSE, 0x3f); + rtw_write32_mask(rtwdev, REG_BCN_CTRL, + (BIT_EN_BCN_FUNCTION << 8) | BIT_EN_BCN_FUNCTION, 0x0); + + /* RX ante off */ + rtw_write8(rtwdev, REG_RXPSEL, 0x00); + + /* CCA off */ + rtw_write32_mask(rtwdev, REG_CCA2ND, 0xf, 0xc); + + /* CCK RX path off */ + rtw_write8(rtwdev, REG_CCK_RX + 3, 0xf); +} +EXPORT_SYMBOL(rtw88xxa_iqk_configure_mac); + +bool rtw88xxa_iqk_finish(int average, int threshold, + int *x_temp, int *y_temp, int *x, int *y, + bool break_inner, bool break_outer) +{ + bool finish = false; + int i, ii, dx, dy; + + for (i = 0; i < average; i++) { + for (ii = i + 1; ii < average; ii++) { + dx = abs_diff(x_temp[i] >> 21, x_temp[ii] >> 21); + dy = abs_diff(y_temp[i] >> 21, y_temp[ii] >> 21); + + if (dx < threshold && dy < threshold) { + *x = ((x_temp[i] >> 21) + (x_temp[ii] >> 21)); + *y = ((y_temp[i] >> 21) + (y_temp[ii] >> 21)); + + *x /= 2; + *y /= 2; + + finish = true; + + if (break_inner) + break; + } + } + + if (finish && break_outer) + break; + } + + return finish; +} +EXPORT_SYMBOL(rtw88xxa_iqk_finish); + +static void rtw88xxa_pwrtrack_set(struct rtw_dev *rtwdev, u8 tx_rate, u8 path) +{ + static const u32 reg_txscale[2] = { REG_TXSCALE_A, REG_TXSCALE_B }; + struct rtw_dm_info *dm_info = &rtwdev->dm_info; + u8 cck_swing_idx, ofdm_swing_idx; + u8 pwr_tracking_limit; + + switch (tx_rate) { + case DESC_RATE1M ... DESC_RATE11M: + pwr_tracking_limit = 32; + break; + case DESC_RATE6M ... DESC_RATE48M: + case DESC_RATEMCS3 ... DESC_RATEMCS4: + case DESC_RATEMCS11 ... DESC_RATEMCS12: + case DESC_RATEVHT1SS_MCS3 ... DESC_RATEVHT1SS_MCS4: + case DESC_RATEVHT2SS_MCS3 ... DESC_RATEVHT2SS_MCS4: + pwr_tracking_limit = 30; + break; + case DESC_RATE54M: + case DESC_RATEMCS5 ... DESC_RATEMCS7: + case DESC_RATEMCS13 ... DESC_RATEMCS15: + case DESC_RATEVHT1SS_MCS5 ... DESC_RATEVHT1SS_MCS6: + case DESC_RATEVHT2SS_MCS5 ... DESC_RATEVHT2SS_MCS6: + pwr_tracking_limit = 28; + break; + case DESC_RATEMCS0 ... DESC_RATEMCS2: + case DESC_RATEMCS8 ... DESC_RATEMCS10: + case DESC_RATEVHT1SS_MCS0 ... DESC_RATEVHT1SS_MCS2: + case DESC_RATEVHT2SS_MCS0 ... DESC_RATEVHT2SS_MCS2: + pwr_tracking_limit = 34; + break; + case DESC_RATEVHT1SS_MCS7: + case DESC_RATEVHT2SS_MCS7: + pwr_tracking_limit = 26; + break; + default: + case DESC_RATEVHT1SS_MCS8: + case DESC_RATEVHT2SS_MCS8: + pwr_tracking_limit = 24; + break; + case DESC_RATEVHT1SS_MCS9: + case DESC_RATEVHT2SS_MCS9: + pwr_tracking_limit = 22; + break; + } + + cck_swing_idx = dm_info->delta_power_index[path] + dm_info->default_cck_index; + ofdm_swing_idx = dm_info->delta_power_index[path] + dm_info->default_ofdm_index; + + if (ofdm_swing_idx > pwr_tracking_limit) { + if (path == RF_PATH_A) + dm_info->txagc_remnant_cck = cck_swing_idx - pwr_tracking_limit; + dm_info->txagc_remnant_ofdm[path] = ofdm_swing_idx - pwr_tracking_limit; + + ofdm_swing_idx = pwr_tracking_limit; + } else if (ofdm_swing_idx == 0) { + if (path == RF_PATH_A) + dm_info->txagc_remnant_cck = cck_swing_idx; + dm_info->txagc_remnant_ofdm[path] = ofdm_swing_idx; + } else { + if (path == RF_PATH_A) + dm_info->txagc_remnant_cck = 0; + dm_info->txagc_remnant_ofdm[path] = 0; + } + + rtw_write32_mask(rtwdev, reg_txscale[path], GENMASK(31, 21), + rtw88xxa_txscale_tbl[ofdm_swing_idx]); +} + +void rtw88xxa_phy_pwrtrack(struct rtw_dev *rtwdev, + void (*do_lck)(struct rtw_dev *rtwdev), + void (*do_iqk)(struct rtw_dev *rtwdev)) +{ + struct rtw_dm_info *dm_info = &rtwdev->dm_info; + struct rtw_hal *hal = &rtwdev->hal; + struct rtw_swing_table swing_table; + s8 remnant_pre[RTW_RF_PATH_MAX]; + u8 thermal_value, delta, path; + bool need_iqk; + + rtw_phy_config_swing_table(rtwdev, &swing_table); + + if (rtwdev->efuse.thermal_meter[0] == 0xff) { + pr_err_once("efuse thermal meter is 0xff\n"); + return; + } + + thermal_value = rtw_read_rf(rtwdev, RF_PATH_A, RF_T_METER, 0xfc00); + + rtw_phy_pwrtrack_avg(rtwdev, thermal_value, RF_PATH_A); + + need_iqk = rtw_phy_pwrtrack_need_iqk(rtwdev); + + if (need_iqk && do_lck) + do_lck(rtwdev); + + if (dm_info->pwr_trk_init_trigger) + dm_info->pwr_trk_init_trigger = false; + else if (!rtw_phy_pwrtrack_thermal_changed(rtwdev, thermal_value, + RF_PATH_A)) + goto iqk; + + delta = rtw_phy_pwrtrack_get_delta(rtwdev, RF_PATH_A); + + for (path = RF_PATH_A; path < hal->rf_path_num; path++) { + remnant_pre[path] = dm_info->txagc_remnant_ofdm[path]; + + dm_info->delta_power_index[path] = + rtw_phy_pwrtrack_get_pwridx(rtwdev, &swing_table, path, + RF_PATH_A, delta); + + if (dm_info->delta_power_index[path] != + dm_info->delta_power_index_last[path]) { + dm_info->delta_power_index_last[path] = + dm_info->delta_power_index[path]; + + rtw88xxa_pwrtrack_set(rtwdev, dm_info->tx_rate, path); + } + } + + for (path = RF_PATH_A; path < hal->rf_path_num; path++) { + if (remnant_pre[path] != dm_info->txagc_remnant_ofdm[path]) { + rtw_phy_set_tx_power_level(rtwdev, + hal->current_channel); + break; + } + } + +iqk: + if (need_iqk) + do_iqk(rtwdev); +} +EXPORT_SYMBOL(rtw88xxa_phy_pwrtrack); + +void rtw88xxa_phy_cck_pd_set(struct rtw_dev *rtwdev, u8 new_lvl) +{ + static const u8 pd[CCK_PD_LV_MAX] = {0x40, 0x83, 0xcd, 0xdd, 0xed}; + struct rtw_dm_info *dm_info = &rtwdev->dm_info; + + /* Override rtw_phy_cck_pd_lv_link(). It implements something + * like type 2/3/4. We need type 1 here. + */ + if (rtw_is_assoc(rtwdev)) { + if (dm_info->min_rssi > 60) { + new_lvl = CCK_PD_LV3; + } else if (dm_info->min_rssi > 35) { + new_lvl = CCK_PD_LV2; + } else if (dm_info->min_rssi > 20) { + if (dm_info->cck_fa_avg > 500) + new_lvl = CCK_PD_LV2; + else if (dm_info->cck_fa_avg < 250) + new_lvl = CCK_PD_LV1; + else + return; + } else { + new_lvl = CCK_PD_LV1; + } + } + + rtw_dbg(rtwdev, RTW_DBG_PHY, "lv: (%d) -> (%d)\n", + dm_info->cck_pd_lv[RTW_CHANNEL_WIDTH_20][RF_PATH_A], new_lvl); + + if (dm_info->cck_pd_lv[RTW_CHANNEL_WIDTH_20][RF_PATH_A] == new_lvl) + return; + + dm_info->cck_fa_avg = CCK_FA_AVG_RESET; + dm_info->cck_pd_lv[RTW_CHANNEL_WIDTH_20][RF_PATH_A] = new_lvl; + + rtw_write8(rtwdev, REG_CCK_PD_TH, pd[new_lvl]); +} +EXPORT_SYMBOL(rtw88xxa_phy_cck_pd_set); + +MODULE_AUTHOR("Realtek Corporation"); +MODULE_DESCRIPTION("Realtek 802.11ac wireless 8821a/8811a/8812a common code"); +MODULE_LICENSE("Dual BSD/GPL"); diff --git a/rtw88xxa.h b/rtw88xxa.h new file mode 100644 index 00000000..09a45c1a --- /dev/null +++ b/rtw88xxa.h @@ -0,0 +1,175 @@ +/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */ +/* Copyright(c) 2024 Realtek Corporation + */ + +#ifndef __RTW88XXA_H__ +#define __RTW88XXA_H__ + +#include +#include "reg.h" + +struct rtw8821au_efuse { + u8 res4[48]; /* 0xd0 */ + u8 vid[2]; /* 0x100 */ + u8 pid[2]; + u8 res8[3]; + u8 mac_addr[ETH_ALEN]; /* 0x107 */ + u8 res9[243]; +} __packed; + +struct rtw8812au_efuse { + u8 vid[2]; /* 0xd0 */ + u8 pid[2]; /* 0xd2 */ + u8 res0[3]; + u8 mac_addr[ETH_ALEN]; /* 0xd7 */ + u8 res1[291]; +} __packed; + +struct rtw88xxa_efuse { + __le16 rtl_id; + u8 res0[6]; /* 0x02 */ + u8 usb_mode; /* 0x08 */ + u8 res1[7]; /* 0x09 */ + + /* power index for four RF paths */ + struct rtw_txpwr_idx txpwr_idx_table[4]; + + u8 channel_plan; /* 0xb8 */ + u8 xtal_k; + u8 thermal_meter; + u8 iqk_lck; + u8 pa_type; /* 0xbc */ + u8 lna_type_2g; /* 0xbd */ + u8 res2; + u8 lna_type_5g; /* 0xbf */ + u8 res3; + u8 rf_board_option; /* 0xc1 */ + u8 rf_feature_option; + u8 rf_bt_setting; + u8 eeprom_version; + u8 eeprom_customer_id; /* 0xc5 */ + u8 tx_bb_swing_setting_2g; + u8 tx_bb_swing_setting_5g; + u8 tx_pwr_calibrate_rate; + u8 rf_antenna_option; /* 0xc9 */ + u8 rfe_option; + u8 country_code[2]; + u8 res4[3]; + union { + struct rtw8821au_efuse rtw8821au; + struct rtw8812au_efuse rtw8812au; + }; +} __packed; + +static_assert(sizeof(struct rtw88xxa_efuse) == 512); + +#define WLAN_BCN_DMA_TIME 0x02 +#define WLAN_TBTT_PROHIBIT 0x04 +#define WLAN_TBTT_HOLD_TIME 0x064 +#define WLAN_TBTT_TIME (WLAN_TBTT_PROHIBIT |\ + (WLAN_TBTT_HOLD_TIME << BIT_SHIFT_TBTT_HOLD_TIME_AP)) + +struct rtw_jaguar_phy_status_rpt { + __le32 w0; + __le32 w1; + __le32 w2; + __le32 w3; + __le32 w4; + __le32 w5; + __le32 w6; +} __packed; + +#define RTW_JGRPHY_W0_GAIN_A GENMASK(6, 0) +#define RTW_JGRPHY_W0_TRSW_A BIT(7) +#define RTW_JGRPHY_W0_GAIN_B GENMASK(14, 8) +#define RTW_JGRPHY_W0_TRSW_B BIT(15) +#define RTW_JGRPHY_W0_CHL_NUM GENMASK(25, 16) +#define RTW_JGRPHY_W0_SUB_CHNL GENMASK(29, 26) +#define RTW_JGRPHY_W0_R_RFMOD GENMASK(31, 30) + +/* CCK: */ +#define RTW_JGRPHY_W1_SIG_QUAL GENMASK(7, 0) +#define RTW_JGRPHY_W1_AGC_RPT_VGA_IDX GENMASK(12, 8) +#define RTW_JGRPHY_W1_AGC_RPT_LNA_IDX GENMASK(15, 13) +#define RTW_JGRPHY_W1_BB_POWER GENMASK(23, 16) +/* OFDM: */ +#define RTW_JGRPHY_W1_PWDB_ALL GENMASK(7, 0) +#define RTW_JGRPHY_W1_CFO_SHORT_A GENMASK(15, 8) /* s8 */ +#define RTW_JGRPHY_W1_CFO_SHORT_B GENMASK(23, 16) /* s8 */ +#define RTW_JGRPHY_W1_BT_RF_CH_MSB GENMASK(31, 30) + +#define RTW_JGRPHY_W2_ANT_DIV_SW_A BIT(0) +#define RTW_JGRPHY_W2_ANT_DIV_SW_B BIT(1) +#define RTW_JGRPHY_W2_BT_RF_CH_LSB GENMASK(7, 2) +#define RTW_JGRPHY_W2_CFO_TAIL_A GENMASK(15, 8) /* s8 */ +#define RTW_JGRPHY_W2_CFO_TAIL_B GENMASK(23, 16) /* s8 */ +#define RTW_JGRPHY_W2_PCTS_MSK_RPT_0 GENMASK(31, 24) + +#define RTW_JGRPHY_W3_PCTS_MSK_RPT_1 GENMASK(7, 0) +/* Stream 1 and 2 RX EVM: */ +#define RTW_JGRPHY_W3_RXEVM_1 GENMASK(15, 8) /* s8 */ +#define RTW_JGRPHY_W3_RXEVM_2 GENMASK(23, 16) /* s8 */ +#define RTW_JGRPHY_W3_RXSNR_A GENMASK(31, 24) /* s8 */ + +#define RTW_JGRPHY_W4_RXSNR_B GENMASK(7, 0) /* s8 */ +#define RTW_JGRPHY_W4_PCTS_MSK_RPT_2 GENMASK(21, 8) +#define RTW_JGRPHY_W4_PCTS_RPT_VALID BIT(22) +#define RTW_JGRPHY_W4_RXEVM_3 GENMASK(31, 24) /* s8 */ + +#define RTW_JGRPHY_W5_RXEVM_4 GENMASK(7, 0) /* s8 */ +/* 8812a, stream 1 and 2 CSI: */ +#define RTW_JGRPHY_W5_CSI_CURRENT_1 GENMASK(15, 8) +#define RTW_JGRPHY_W5_CSI_CURRENT_2 GENMASK(23, 16) +/* 8814a: */ +#define RTW_JGRPHY_W5_RXSNR_C GENMASK(15, 8) /* s8 */ +#define RTW_JGRPHY_W5_RXSNR_D GENMASK(23, 16) /* s8 */ +#define RTW_JGRPHY_W5_GAIN_C GENMASK(30, 24) +#define RTW_JGRPHY_W5_TRSW_C BIT(31) + +#define RTW_JGRPHY_W6_GAIN_D GENMASK(6, 0) +#define RTW_JGRPHY_W6_TRSW_D BIT(7) +#define RTW_JGRPHY_W6_SIGEVM GENMASK(15, 8) /* s8 */ +#define RTW_JGRPHY_W6_ANTIDX_ANTC GENMASK(18, 16) +#define RTW_JGRPHY_W6_ANTIDX_ANTD GENMASK(21, 19) +#define RTW_JGRPHY_W6_DPDT_CTRL_KEEP BIT(22) +#define RTW_JGRPHY_W6_GNT_BT_KEEP BIT(23) +#define RTW_JGRPHY_W6_ANTIDX_ANTA GENMASK(26, 24) +#define RTW_JGRPHY_W6_ANTIDX_ANTB GENMASK(29, 27) +#define RTW_JGRPHY_W6_HW_ANTSW_OCCUR GENMASK(31, 30) + +#define RF18_BW_MASK (BIT(11) | BIT(10)) + +void rtw88xxa_efuse_grant(struct rtw_dev *rtwdev, bool on); +int rtw88xxa_read_efuse(struct rtw_dev *rtwdev, u8 *log_map); +void rtw88xxa_power_off(struct rtw_dev *rtwdev, + const struct rtw_pwr_seq_cmd *const *enter_lps_flow); +int rtw88xxa_power_on(struct rtw_dev *rtwdev); +u32 rtw88xxa_phy_read_rf(struct rtw_dev *rtwdev, + enum rtw_rf_path rf_path, u32 addr, u32 mask); +void rtw88xxa_set_channel(struct rtw_dev *rtwdev, u8 channel, u8 bw, + u8 primary_chan_idx); +void rtw88xxa_query_phy_status(struct rtw_dev *rtwdev, u8 *phy_status, + struct rtw_rx_pkt_stat *pkt_stat, + s8 (*cck_rx_pwr)(u8 lna_idx, u8 vga_idx)); +void rtw88xxa_set_tx_power_index(struct rtw_dev *rtwdev); +void rtw88xxa_false_alarm_statistics(struct rtw_dev *rtwdev); +void rtw88xxa_iqk_backup_mac_bb(struct rtw_dev *rtwdev, + u32 *macbb_backup, + const u32 *backup_macbb_reg, + u32 macbb_num); +void rtw88xxa_iqk_backup_afe(struct rtw_dev *rtwdev, u32 *afe_backup, + const u32 *backup_afe_reg, u32 afe_num); +void rtw88xxa_iqk_restore_mac_bb(struct rtw_dev *rtwdev, + u32 *macbb_backup, + const u32 *backup_macbb_reg, + u32 macbb_num); +void rtw88xxa_iqk_configure_mac(struct rtw_dev *rtwdev); +bool rtw88xxa_iqk_finish(int average, int threshold, + int *x_temp, int *y_temp, int *x, int *y, + bool break_inner, bool break_outer); +void rtw88xxa_phy_pwrtrack(struct rtw_dev *rtwdev, + void (*do_lck)(struct rtw_dev *rtwdev), + void (*do_iqk)(struct rtw_dev *rtwdev)); +void rtw88xxa_phy_cck_pd_set(struct rtw_dev *rtwdev, u8 new_lvl); + +#endif From 8a14dcac4b2112737ae7604c37fa0d826fed728b Mon Sep 17 00:00:00 2001 From: Bitterblue Smith Date: Sun, 13 Oct 2024 23:56:29 +0300 Subject: [PATCH 033/193] Fix indentation in rtw_get_rsvd_page_probe_req_location --- fw.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fw.c b/fw.c index 08713c13..20c0ccc5 100644 --- a/fw.c +++ b/fw.c @@ -1024,7 +1024,7 @@ static u8 rtw_get_rsvd_page_probe_req_location(struct rtw_dev *rtwdev, if (rsvd_pkt->type != RSVD_PROBE_REQ) continue; if ((!ssid && !rsvd_pkt->ssid) || - cfg80211_ssid_eq(rsvd_pkt->ssid, ssid)) + cfg80211_ssid_eq(rsvd_pkt->ssid, ssid)) location = rsvd_pkt->page; } From cef4643f9f4a91c16c68b2afa0bc1bf6be68d402 Mon Sep 17 00:00:00 2001 From: Bitterblue Smith Date: Sun, 13 Oct 2024 23:59:16 +0300 Subject: [PATCH 034/193] Undo change to rtw_fw_write_data_rsvd_page RTL8821AU, RTL8812AU, RTL8723DU work fine without this. --- fw.c | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/fw.c b/fw.c index 20c0ccc5..0a415223 100644 --- a/fw.c +++ b/fw.c @@ -1535,13 +1535,9 @@ int rtw_fw_write_data_rsvd_page(struct rtw_dev *rtwdev, u16 pg_addr, } restore: - if (rtw_chip_wcpu_11n(rtwdev)) { - rtw_write32_set(rtwdev, REG_DWBCN0_CTRL, BIT_BCN_VALID); - } else { - rsvd_pg_head = rtwdev->fifo.rsvd_boundary; - rtw_write16(rtwdev, REG_FIFOPAGE_CTRL_2, - rsvd_pg_head | BIT_BCN_VALID_V1); - } + rsvd_pg_head = rtwdev->fifo.rsvd_boundary; + rtw_write16(rtwdev, REG_FIFOPAGE_CTRL_2, + rsvd_pg_head | BIT_BCN_VALID_V1); if (rtw_hci_type(rtwdev) == RTW_HCI_TYPE_PCIE) rtw_write8(rtwdev, REG_FWHW_TXQ_CTRL + 2, bckp[1]); rtw_write8(rtwdev, REG_CR + 1, bckp[0]); From c7849992295f2cc4eaa70d7d46e8fdb845bad574 Mon Sep 17 00:00:00 2001 From: Bitterblue Smith Date: Mon, 14 Oct 2024 00:06:15 +0300 Subject: [PATCH 035/193] wifi: rtw88: Report the signal strength only if it's known RTL8821AU doesn't report the signal strength for many (any?) data frames. When the signal strength is not known, set RX_FLAG_NO_SIGNAL_VAL in order to avoid reporting a signal strength of 0. Signed-off-by: Bitterblue Smith --- rx.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/rx.c b/rx.c index b560c0b5..62c0b64e 100644 --- a/rx.c +++ b/rx.c @@ -263,10 +263,14 @@ static void rtw_rx_fill_rx_status(struct rtw_dev *rtwdev, /* What goes here? */ #endif - rx_status->signal = pkt_stat->signal_power; - for (path = 0; path < rtwdev->hal.rf_path_num; path++) { - rx_status->chains |= BIT(path); - rx_status->chain_signal[path] = pkt_stat->rx_power[path]; + if (pkt_stat->phy_status) { + rx_status->signal = pkt_stat->signal_power; + for (path = 0; path < rtwdev->hal.rf_path_num; path++) { + rx_status->chains |= BIT(path); + rx_status->chain_signal[path] = pkt_stat->rx_power[path]; + } + } else { + rx_status->flag |= RX_FLAG_NO_SIGNAL_VAL; } rtw_rx_addr_match(rtwdev, pkt_stat, hdr); From 1c0c8f3919e30753d535f6844f704c4aa0c2f3b8 Mon Sep 17 00:00:00 2001 From: Bitterblue Smith Date: Mon, 14 Oct 2024 00:07:57 +0300 Subject: [PATCH 036/193] usb: Delete register printing code This didn't need to be public after all. --- usb.c | 5 ----- 1 file changed, 5 deletions(-) diff --git a/usb.c b/usb.c index 45f6d08a..b8cdd2bd 100644 --- a/usb.c +++ b/usb.c @@ -125,11 +125,6 @@ static void rtw_usb_write(struct rtw_dev *rtwdev, u32 addr, u32 val, int len) int idx, ret; static int count; -#if 0 - if (addr < 0x1000 || addr > 0x1fff) - pr_err("rtw88_8821au write%d 0x%03x = %#x\n", len * 8, addr, val); -#endif - spin_lock_irqsave(&rtwusb->usb_lock, flags); idx = rtwusb->usb_data_index; From 03dac9e79b2f0cadbc85fc98f51aeec7cbd53edd Mon Sep 17 00:00:00 2001 From: Bitterblue Smith Date: Mon, 14 Oct 2024 00:09:38 +0300 Subject: [PATCH 037/193] Revert "wifi: rtw88: Limit the TX power for USB devices" This reverts commit 449bdbb0b0408170ad54baeff85eb7126f3383e5. It was a random thing to try to fix some bug. It didn't work. --- phy.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/phy.c b/phy.c index aa4248ab..71551cfc 100644 --- a/phy.c +++ b/phy.c @@ -2220,10 +2220,6 @@ rtw_phy_get_tx_power_index(struct rtw_dev *rtwdev, u8 rf_path, u8 rate, if (rtwdev->chip->en_dis_dpd) offset += rtw_phy_get_dis_dpd_by_rate_diff(rtwdev, rate); - /* USB may not have enough power. Allow only to decrease. */ - if (rtw_hci_type(rtwdev) == RTW_HCI_TYPE_USB) - offset = min_t(s8, offset, 0); - tx_power += offset + pwr_param.pwr_remnant; if (tx_power > rtwdev->chip->max_power_index) From dfb8bd08b0b4a62591a2a903d85e8c6e1248d004 Mon Sep 17 00:00:00 2001 From: Bitterblue Smith Date: Mon, 14 Oct 2024 00:10:59 +0300 Subject: [PATCH 038/193] Revert "rtw88: Add an additional check in rtw_rx_fill_rx_status()" This reverts commit 37c8025bfa1f0ef99a467e564528738b91254589. This was working around a bug that is now fixed: https://github.com/lwfinger/rtw88/commit/340625a80b85d5468730fdd38f918658656fd461 --- rx.c | 5 ----- 1 file changed, 5 deletions(-) diff --git a/rx.c b/rx.c index 62c0b64e..d67895e3 100644 --- a/rx.c +++ b/rx.c @@ -200,11 +200,6 @@ static void rtw_rx_fill_rx_status(struct rtw_dev *rtwdev, rtw_warn(rtwdev, "hw NULL in %s\n", __func__); return; } - if (!hw->conf.chandef.chan) { - rtw_warn(rtwdev, "hw->conf.chandef.chan NULL in %s\n", __func__); - return; - } - rx_status->freq = hw->conf.chandef.chan->center_freq; rx_status->band = hw->conf.chandef.chan->band; if (rtw_fw_feature_check(&rtwdev->fw, FW_FEATURE_SCAN_OFFLOAD) && From 247209b9bbce19487277531aebf5212df5e32b65 Mon Sep 17 00:00:00 2001 From: Bitterblue Smith Date: Mon, 14 Oct 2024 00:13:06 +0300 Subject: [PATCH 039/193] Revert "rtw88: Detect NULL for hw in rtw_rx_fill_rx_status()" This reverts commit d5af6c16d0731909679eedd481bd60648bd4d301. This was working around a bug that is now fixed: https://github.com/lwfinger/rtw88/commit/340625a80b85d5468730fdd38f918658656fd461 --- rx.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/rx.c b/rx.c index d67895e3..7e67dec0 100644 --- a/rx.c +++ b/rx.c @@ -196,10 +196,6 @@ static void rtw_rx_fill_rx_status(struct rtw_dev *rtwdev, u8 path; memset(rx_status, 0, sizeof(*rx_status)); - if (!hw) { - rtw_warn(rtwdev, "hw NULL in %s\n", __func__); - return; - } rx_status->freq = hw->conf.chandef.chan->center_freq; rx_status->band = hw->conf.chandef.chan->band; if (rtw_fw_feature_check(&rtwdev->fw, FW_FEATURE_SCAN_OFFLOAD) && From 6b4f6f6f73910b47fd9cca22efd3881c2fbaeca1 Mon Sep 17 00:00:00 2001 From: Zenm Chen Date: Wed, 16 Oct 2024 00:26:42 +0800 Subject: [PATCH 040/193] Update dkms.conf Fixes https://github.com/lwfinger/rtw88/issues/238 --- dkms.conf | 94 +++++++++++++++++++++++++++++-------------------------- 1 file changed, 49 insertions(+), 45 deletions(-) diff --git a/dkms.conf b/dkms.conf index 8c8efab4..c3a97fec 100644 --- a/dkms.conf +++ b/dkms.conf @@ -11,48 +11,52 @@ BUILT_MODULE_NAME[3]="rtw_8723de" BUILT_MODULE_NAME[4]="rtw_8723ds" BUILT_MODULE_NAME[5]="rtw_8723du" BUILT_MODULE_NAME[6]="rtw_8723x" -BUILT_MODULE_NAME[7]="rtw_8812au" -BUILT_MODULE_NAME[8]="rtw_8821a" -BUILT_MODULE_NAME[9]="rtw_8821au" -BUILT_MODULE_NAME[10]="rtw_8821c" -BUILT_MODULE_NAME[11]="rtw_8821ce" -BUILT_MODULE_NAME[12]="rtw_8821cs" -BUILT_MODULE_NAME[13]="rtw_8821cu" -BUILT_MODULE_NAME[14]="rtw_8822b" -BUILT_MODULE_NAME[15]="rtw_8822be" -BUILT_MODULE_NAME[16]="rtw_8822bs" -BUILT_MODULE_NAME[17]="rtw_8822bu" -BUILT_MODULE_NAME[18]="rtw_8822c" -BUILT_MODULE_NAME[19]="rtw_8822ce" -BUILT_MODULE_NAME[20]="rtw_8822cs" -BUILT_MODULE_NAME[21]="rtw_8822cu" -BUILT_MODULE_NAME[22]="rtw_core" -BUILT_MODULE_NAME[23]="rtw_pci" -BUILT_MODULE_NAME[24]="rtw_sdio" -BUILT_MODULE_NAME[25]="rtw_usb" -DEST_MODULE_LOCATION[0]="/updates/dkms" -DEST_MODULE_LOCATION[1]="/updates/dkms" -DEST_MODULE_LOCATION[2]="/updates/dkms" -DEST_MODULE_LOCATION[3]="/updates/dkms" -DEST_MODULE_LOCATION[4]="/updates/dkms" -DEST_MODULE_LOCATION[5]="/updates/dkms" -DEST_MODULE_LOCATION[6]="/updates/dkms" -DEST_MODULE_LOCATION[7]="/updates/dkms" -DEST_MODULE_LOCATION[8]="/updates/dkms" -DEST_MODULE_LOCATION[9]="/updates/dkms" -DEST_MODULE_LOCATION[10]="/updates/dkms" -DEST_MODULE_LOCATION[11]="/updates/dkms" -DEST_MODULE_LOCATION[12]="/updates/dkms" -DEST_MODULE_LOCATION[13]="/updates/dkms" -DEST_MODULE_LOCATION[14]="/updates/dkms" -DEST_MODULE_LOCATION[15]="/updates/dkms" -DEST_MODULE_LOCATION[16]="/updates/dkms" -DEST_MODULE_LOCATION[17]="/updates/dkms" -DEST_MODULE_LOCATION[18]="/updates/dkms" -DEST_MODULE_LOCATION[19]="/updates/dkms" -DEST_MODULE_LOCATION[20]="/updates/dkms" -DEST_MODULE_LOCATION[21]="/updates/dkms" -DEST_MODULE_LOCATION[22]="/updates/dkms" -DEST_MODULE_LOCATION[23]="/updates/dkms" -DEST_MODULE_LOCATION[24]="/updates/dkms" -DEST_MODULE_LOCATION[25]="/updates/dkms" +BUILT_MODULE_NAME[7]="rtw_8812a" +BUILT_MODULE_NAME[8]="rtw_8812au" +BUILT_MODULE_NAME[9]="rtw_8821a" +BUILT_MODULE_NAME[10]="rtw_8821au" +BUILT_MODULE_NAME[11]="rtw_8821c" +BUILT_MODULE_NAME[12]="rtw_8821ce" +BUILT_MODULE_NAME[13]="rtw_8821cs" +BUILT_MODULE_NAME[14]="rtw_8821cu" +BUILT_MODULE_NAME[15]="rtw_8822b" +BUILT_MODULE_NAME[16]="rtw_8822be" +BUILT_MODULE_NAME[17]="rtw_8822bs" +BUILT_MODULE_NAME[18]="rtw_8822bu" +BUILT_MODULE_NAME[19]="rtw_8822c" +BUILT_MODULE_NAME[20]="rtw_8822ce" +BUILT_MODULE_NAME[21]="rtw_8822cs" +BUILT_MODULE_NAME[22]="rtw_8822cu" +BUILT_MODULE_NAME[23]="rtw_88xxa" +BUILT_MODULE_NAME[24]="rtw_core" +BUILT_MODULE_NAME[25]="rtw_pci" +BUILT_MODULE_NAME[26]="rtw_sdio" +BUILT_MODULE_NAME[27]="rtw_usb" +DEST_MODULE_LOCATION[0]="/updates/dkms/rtw88" +DEST_MODULE_LOCATION[1]="/updates/dkms/rtw88" +DEST_MODULE_LOCATION[2]="/updates/dkms/rtw88" +DEST_MODULE_LOCATION[3]="/updates/dkms/rtw88" +DEST_MODULE_LOCATION[4]="/updates/dkms/rtw88" +DEST_MODULE_LOCATION[5]="/updates/dkms/rtw88" +DEST_MODULE_LOCATION[6]="/updates/dkms/rtw88" +DEST_MODULE_LOCATION[7]="/updates/dkms/rtw88" +DEST_MODULE_LOCATION[8]="/updates/dkms/rtw88" +DEST_MODULE_LOCATION[9]="/updates/dkms/rtw88" +DEST_MODULE_LOCATION[10]="/updates/dkms/rtw88" +DEST_MODULE_LOCATION[11]="/updates/dkms/rtw88" +DEST_MODULE_LOCATION[12]="/updates/dkms/rtw88" +DEST_MODULE_LOCATION[13]="/updates/dkms/rtw88" +DEST_MODULE_LOCATION[14]="/updates/dkms/rtw88" +DEST_MODULE_LOCATION[15]="/updates/dkms/rtw88" +DEST_MODULE_LOCATION[16]="/updates/dkms/rtw88" +DEST_MODULE_LOCATION[17]="/updates/dkms/rtw88" +DEST_MODULE_LOCATION[18]="/updates/dkms/rtw88" +DEST_MODULE_LOCATION[19]="/updates/dkms/rtw88" +DEST_MODULE_LOCATION[20]="/updates/dkms/rtw88" +DEST_MODULE_LOCATION[21]="/updates/dkms/rtw88" +DEST_MODULE_LOCATION[22]="/updates/dkms/rtw88" +DEST_MODULE_LOCATION[23]="/updates/dkms/rtw88" +DEST_MODULE_LOCATION[24]="/updates/dkms/rtw88" +DEST_MODULE_LOCATION[25]="/updates/dkms/rtw88" +DEST_MODULE_LOCATION[26]="/updates/dkms/rtw88" +DEST_MODULE_LOCATION[27]="/updates/dkms/rtw88" From c5478463fc992021d121823776f873b3bd1be9ea Mon Sep 17 00:00:00 2001 From: Zenm Chen Date: Wed, 16 Oct 2024 01:43:45 +0800 Subject: [PATCH 041/193] rtw88: Fix builds for kernels older than 6.6.0 Fixes https://github.com/lwfinger/rtw88/issues/237 --- main.h | 21 +++++++++++++++++++++ rx.c | 8 ++++++++ 2 files changed, 29 insertions(+) diff --git a/main.h b/main.h index acabf5fd..8b58d00b 100644 --- a/main.h +++ b/main.h @@ -33,6 +33,27 @@ #define RHEL_RELEASE_VERSION(a, b) a<<8 & b #endif +#if (LINUX_VERSION_CODE < KERNEL_VERSION(6, 6, 0)) +/** + * abs_diff - return absolute value of the difference between the arguments + * @a: the first argument + * @b: the second argument + * + * @a and @b have to be of the same type. With this restriction we compare + * signed to signed and unsigned to unsigned. The result is the subtraction + * the smaller of the two from the bigger, hence result is always a positive + * value. + * + * Return: an absolute value of the difference between the @a and @b. + */ +#define abs_diff(a, b) ({ \ + typeof(a) __a = (a); \ + typeof(b) __b = (b); \ + (void)(&__a == &__b); \ + __a > __b ? (__a - __b) : (__b - __a); \ +}) +#endif + #if LINUX_VERSION_CODE < KERNEL_VERSION(6, 8, 0) /** * cfg80211_ssid_eq - compare two SSIDs diff --git a/rx.c b/rx.c index 7e67dec0..06a94157 100644 --- a/rx.c +++ b/rx.c @@ -176,8 +176,16 @@ void rtw_update_rx_freq_from_ie(struct rtw_dev *rtwdev, struct sk_buff *skb, else goto fill_rx_status; +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(6, 4, 0)) channel_number = cfg80211_get_ies_channel_number(variable, ielen, NL80211_BAND_2GHZ); +#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 17, 0)) + channel_number = cfg80211_get_ies_channel_number(variable, ielen, + NL80211_BAND_2GHZ, 0); +#else + channel_number = -1; +#endif + if (channel_number != -1) channel = channel_number; From 2f2f1e5f1c45cca91cc9718e379a6a5600dd7ed5 Mon Sep 17 00:00:00 2001 From: morrownr <69053122+morrownr@users.noreply.github.com> Date: Sun, 20 Oct 2024 22:25:24 -0500 Subject: [PATCH 042/193] Update main.c to remove NL80211_FEATURE_ACTIVE_MONITOR This was added on May 10, 2024. It appears Larry was just trying to see if it would work. --- main.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/main.c b/main.c index 3a6ead45..eb3b42a9 100644 --- a/main.c +++ b/main.c @@ -2389,8 +2389,7 @@ int rtw_register_hw(struct rtw_dev *rtwdev, struct ieee80211_hw *hw) hw->wiphy->flags |= WIPHY_FLAG_SUPPORTS_TDLS | WIPHY_FLAG_TDLS_EXTERNAL_SETUP; - hw->wiphy->features |= NL80211_FEATURE_SCAN_RANDOM_MAC_ADDR | - NL80211_FEATURE_ACTIVE_MONITOR; + hw->wiphy->features |= NL80211_FEATURE_SCAN_RANDOM_MAC_ADDR; hw->wiphy->max_scan_ssids = RTW_SCAN_MAX_SSIDS; hw->wiphy->max_scan_ie_len = rtw_get_max_scan_ie_len(rtwdev); From 442e46c5f6471a1fd41e555be1da51f22915b9b9 Mon Sep 17 00:00:00 2001 From: Bitterblue Smith Date: Mon, 21 Oct 2024 13:28:52 +0300 Subject: [PATCH 043/193] usb: Add error message for alloc_skb Until the bug (https://github.com/lwfinger/rtw88/issues/205) is fixed. Signed-off-by: Bitterblue Smith --- usb.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/usb.c b/usb.c index b8cdd2bd..33d637c0 100644 --- a/usb.c +++ b/usb.c @@ -621,8 +621,10 @@ static void rtw_usb_rx_resubmit(struct rtw_usb *rtwusb, struct rx_usb_ctrl_block int error; rxcb->rx_skb = alloc_skb(RTW_USB_MAX_RECVBUF_SZ, GFP_ATOMIC); - if (!rxcb->rx_skb) + if (!rxcb->rx_skb) { + rtw_err(rtwdev, "failed to allocate rx_skb\n"); return; + } usb_fill_bulk_urb(rxcb->rx_urb, rtwusb->udev, usb_rcvbulkpipe(rtwusb->udev, rtwusb->pipe_in), From 4c11283c8e3d6c88035e1d09fe4260a9508f74aa Mon Sep 17 00:00:00 2001 From: Saad Ahmed <65092551+SaadAhmedGit@users.noreply.github.com> Date: Mon, 21 Oct 2024 20:41:09 +0500 Subject: [PATCH 044/193] Fix typo It likely meant "plain text" instead of "plain test" --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index d15615fd..3a693ea7 100644 --- a/README.md +++ b/README.md @@ -190,7 +190,7 @@ issue on this repository is **NOT** the place to report it. We have no idea about the internal workings of any of the chips, and the Realtek engineers who do will not read these issues. To reach them, send E-mail to [linux-wireless@vger.kernel.org](mailto:linux-wireless@vger.kernel.org). -Be sure to include a detailed description of any messages in the kernel logs and any steps that you have taken to analyze or fix the problem. If your description is not complete, you are unlikely to get the help you need. NOTE: E-mail sent to that mailing list MUST be plain test. HTML mail will be rejected. +Be sure to include a detailed description of any messages in the kernel logs and any steps that you have taken to analyze or fix the problem. If your description is not complete, you are unlikely to get the help you need. NOTE: E-mail sent to that mailing list MUST be plain text. HTML mail will be rejected. Start with this page for guidance: https://wireless.wiki.kernel.org/en/users/support From 80abfdd7f39638d65b68a1b716ea9f8472a9752c Mon Sep 17 00:00:00 2001 From: morrownr <69053122+morrownr@users.noreply.github.com> Date: Thu, 24 Oct 2024 10:22:29 -0500 Subject: [PATCH 045/193] Update rtw8822bu.c to add 4 new vid/pids and alphabetize the entries A patch to reflex this up needs to go to linux-wireless. --- rtw8822bu.c | 92 ++++++++++++++++++++++++++++------------------------- 1 file changed, 49 insertions(+), 43 deletions(-) diff --git a/rtw8822bu.c b/rtw8822bu.c index ab620a0b..20aa4564 100644 --- a/rtw8822bu.c +++ b/rtw8822bu.c @@ -1,5 +1,5 @@ // SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause -/* Copyright(c) 2018-2019 Realtek Corporation +/* Copyright(c) 2018-2024 Realtek Corporation */ #include @@ -9,64 +9,70 @@ #include "usb.h" static const struct usb_device_id rtw_8822bu_id_table[] = { - { USB_DEVICE_AND_INTERFACE_INFO(RTW_USB_VENDOR_ID_REALTEK, 0xb812, 0xff, 0xff, 0xff), - .driver_info = (kernel_ulong_t)&(rtw8822b_hw_spec) }, - { USB_DEVICE_AND_INTERFACE_INFO(RTW_USB_VENDOR_ID_REALTEK, 0xb82c, 0xff, 0xff, 0xff), - .driver_info = (kernel_ulong_t)&(rtw8822b_hw_spec) }, + { USB_DEVICE_AND_INTERFACE_INFO(RTW_USB_VENDOR_ID_REALTEK, 0xB812, 0xff, 0xff, 0xff), + .driver_info = (kernel_ulong_t)&(rtw8822b_hw_spec) }, /* Default ID for USB Single-function, WiFi only */ + { USB_DEVICE_AND_INTERFACE_INFO(RTW_USB_VENDOR_ID_REALTEK, 0xB81A, 0xff, 0xff, 0xff), + .driver_info = (kernel_ulong_t)&(rtw8822b_hw_spec) }, /* Default ID */ + { USB_DEVICE_AND_INTERFACE_INFO(RTW_USB_VENDOR_ID_REALTEK, 0xB82C, 0xff, 0xff, 0xff), + .driver_info = (kernel_ulong_t)&(rtw8822b_hw_spec) }, /* Default ID for USB multi-function */ { USB_DEVICE_AND_INTERFACE_INFO(RTW_USB_VENDOR_ID_REALTEK, 0x2102, 0xff, 0xff, 0xff), .driver_info = (kernel_ulong_t)&(rtw8822b_hw_spec) }, /* CCNC */ - { USB_DEVICE_AND_INTERFACE_INFO(0x7392, 0xb822, 0xff, 0xff, 0xff), - .driver_info = (kernel_ulong_t)&(rtw8822b_hw_spec) }, /* Edimax EW-7822ULC */ - { USB_DEVICE_AND_INTERFACE_INFO(0x7392, 0xc822, 0xff, 0xff, 0xff), - .driver_info = (kernel_ulong_t)&(rtw8822b_hw_spec) }, /* Edimax EW-7822UTC */ - { USB_DEVICE_AND_INTERFACE_INFO(0x7392, 0xd822, 0xff, 0xff, 0xff), - .driver_info = (kernel_ulong_t)&(rtw8822b_hw_spec) }, /* Edimax */ - { USB_DEVICE_AND_INTERFACE_INFO(0x7392, 0xe822, 0xff, 0xff, 0xff), - .driver_info = (kernel_ulong_t)&(rtw8822b_hw_spec) }, /* Edimax */ - { USB_DEVICE_AND_INTERFACE_INFO(0x7392, 0xf822, 0xff, 0xff, 0xff), - .driver_info = (kernel_ulong_t)&(rtw8822b_hw_spec) }, /* Edimax EW-7822UAD */ - { USB_DEVICE_AND_INTERFACE_INFO(RTW_USB_VENDOR_ID_REALTEK, 0xb81a, 0xff, 0xff, 0xff), - .driver_info = (kernel_ulong_t)&(rtw8822b_hw_spec) }, /* Default ID */ - { USB_DEVICE_AND_INTERFACE_INFO(0x0b05, 0x1841, 0xff, 0xff, 0xff), + { USB_DEVICE_AND_INTERFACE_INFO(0x04CA, 0x8602, 0xff, 0xff, 0xff), + .driver_info = (kernel_ulong_t)&(rtw8822b_hw_spec) }, /* LiteOn */ + { USB_DEVICE_AND_INTERFACE_INFO(0x056E, 0x4011, 0xff, 0xff, 0xff), + .driver_info = (kernel_ulong_t)&(rtw8822b_hw_spec) }, /* Elecom */ + { USB_DEVICE_AND_INTERFACE_INFO(0x0846, 0x9055, 0xff, 0xff, 0xff), + .driver_info = (kernel_ulong_t)&(rtw8822b_hw_spec) }, /* Netgear A6150 */ + { USB_DEVICE_AND_INTERFACE_INFO(0x0B05, 0x1841, 0xff, 0xff, 0xff), .driver_info = (kernel_ulong_t)&(rtw8822b_hw_spec) }, /* ASUS AC1300 USB-AC55 B1 */ - { USB_DEVICE_AND_INTERFACE_INFO(0x0b05, 0x184c, 0xff, 0xff, 0xff), + { USB_DEVICE_AND_INTERFACE_INFO(0x0B05, 0x184C, 0xff, 0xff, 0xff), .driver_info = (kernel_ulong_t)&(rtw8822b_hw_spec) }, /* ASUS U2 */ - { USB_DEVICE_AND_INTERFACE_INFO(0x0B05, 0x19aa, 0xff, 0xff, 0xff), - .driver_info = (kernel_ulong_t)&(rtw8822b_hw_spec) }, /* ASUS - USB-AC58 rev A1 */ { USB_DEVICE_AND_INTERFACE_INFO(0x0B05, 0x1870, 0xff, 0xff, 0xff), .driver_info = (kernel_ulong_t)&(rtw8822b_hw_spec) }, /* ASUS */ { USB_DEVICE_AND_INTERFACE_INFO(0x0B05, 0x1874, 0xff, 0xff, 0xff), .driver_info = (kernel_ulong_t)&(rtw8822b_hw_spec) }, /* ASUS */ - { USB_DEVICE_AND_INTERFACE_INFO(0x2001, 0x331e, 0xff, 0xff, 0xff), - .driver_info = (kernel_ulong_t)&(rtw8822b_hw_spec) }, /* Dlink - DWA-181 */ - { USB_DEVICE_AND_INTERFACE_INFO(0x2001, 0x331c, 0xff, 0xff, 0xff), - .driver_info = (kernel_ulong_t)&(rtw8822b_hw_spec) }, /* Dlink - DWA-182 - D1 */ - {USB_DEVICE_AND_INTERFACE_INFO(0x2001, 0x331f, 0xff, 0xff, 0xff), - .driver_info = (kernel_ulong_t)&(rtw8822b_hw_spec)}, /* Dlink - DWA-183 D Ver */ - { USB_DEVICE_AND_INTERFACE_INFO(0x13b1, 0x0043, 0xff, 0xff, 0xff), + { USB_DEVICE_AND_INTERFACE_INFO(0x0B05, 0x19AA, 0xff, 0xff, 0xff), + .driver_info = (kernel_ulong_t)&(rtw8822b_hw_spec) }, /* ASUS - USB-AC58 rev A1 */ + { USB_DEVICE_AND_INTERFACE_INFO(0x0E66, 0x0025, 0xff, 0xff, 0xff), + .driver_info = (kernel_ulong_t)&(rtw8822b_hw_spec) }, /* Hawking HW12ACU */ + { USB_DEVICE_AND_INTERFACE_INFO(0x13B1, 0x0043, 0xff, 0xff, 0xff), .driver_info = (kernel_ulong_t)&(rtw8822b_hw_spec) }, /* Linksys WUSB6400M */ - { USB_DEVICE_AND_INTERFACE_INFO(0x13b1, 0x0045, 0xff, 0xff, 0xff), + { USB_DEVICE_AND_INTERFACE_INFO(0x13B1, 0x0045, 0xff, 0xff, 0xff), .driver_info = (kernel_ulong_t)&(rtw8822b_hw_spec) }, /* Linksys WUSB3600 v2 */ - { USB_DEVICE_AND_INTERFACE_INFO(0x2357, 0x012d, 0xff, 0xff, 0xff), - .driver_info = (kernel_ulong_t)&(rtw8822b_hw_spec) }, /* TP-Link Archer T3U v1 */ - { USB_DEVICE_AND_INTERFACE_INFO(0x2357, 0x0138, 0xff, 0xff, 0xff), - .driver_info = (kernel_ulong_t)&(rtw8822b_hw_spec) }, /* TP-Link Archer T3U Plus v1 */ + { USB_DEVICE_AND_INTERFACE_INFO(0x2001, 0x331C, 0xff, 0xff, 0xff), + .driver_info = (kernel_ulong_t)&(rtw8822b_hw_spec) }, /* Dlink - DWA-182 - D1 */ + { USB_DEVICE_AND_INTERFACE_INFO(0x2001, 0x331E, 0xff, 0xff, 0xff), + .driver_info = (kernel_ulong_t)&(rtw8822b_hw_spec) }, /* Dlink - DWA-181 */ + { USB_DEVICE_AND_INTERFACE_INFO(0x2001, 0x331F, 0xff, 0xff, 0xff), + .driver_info = (kernel_ulong_t)&(rtw8822b_hw_spec) }, /* Dlink - DWA-183 - D */ + { USB_DEVICE_AND_INTERFACE_INFO(0x20F4, 0x805A, 0xff, 0xff, 0xff), + .driver_info = (kernel_ulong_t)&(rtw8822b_hw_spec) }, /* TRENDnet TEW-805UBH */ + { USB_DEVICE_AND_INTERFACE_INFO(0x20F4, 0x808A, 0xff, 0xff, 0xff), + .driver_info = (kernel_ulong_t)&(rtw8822b_hw_spec) }, /* TRENDnet TEW-808UBM */ { USB_DEVICE_AND_INTERFACE_INFO(0x2357, 0x0115, 0xff, 0xff, 0xff), .driver_info = (kernel_ulong_t)&(rtw8822b_hw_spec) }, /* TP-Link Archer T4U V3 */ - { USB_DEVICE_AND_INTERFACE_INFO(0x2357, 0x012e, 0xff, 0xff, 0xff), - .driver_info = (kernel_ulong_t)&(rtw8822b_hw_spec) }, /* TP-LINK */ { USB_DEVICE_AND_INTERFACE_INFO(0x2357, 0x0116, 0xff, 0xff, 0xff), .driver_info = (kernel_ulong_t)&(rtw8822b_hw_spec) }, /* TP-LINK */ { USB_DEVICE_AND_INTERFACE_INFO(0x2357, 0x0117, 0xff, 0xff, 0xff), .driver_info = (kernel_ulong_t)&(rtw8822b_hw_spec) }, /* TP-LINK */ - { USB_DEVICE_AND_INTERFACE_INFO(0x0846, 0x9055, 0xff, 0xff, 0xff), - .driver_info = (kernel_ulong_t)&(rtw8822b_hw_spec) }, /* Netgear A6150 */ - { USB_DEVICE_AND_INTERFACE_INFO(0x0e66, 0x0025, 0xff, 0xff, 0xff), - .driver_info = (kernel_ulong_t)&(rtw8822b_hw_spec) }, /* Hawking HW12ACU */ - { USB_DEVICE_AND_INTERFACE_INFO(0x04ca, 0x8602, 0xff, 0xff, 0xff), - .driver_info = (kernel_ulong_t)&(rtw8822b_hw_spec) }, /* LiteOn */ - { USB_DEVICE_AND_INTERFACE_INFO(0x20f4, 0x808a, 0xff, 0xff, 0xff), - .driver_info = (kernel_ulong_t)&(rtw8822b_hw_spec) }, /* TRENDnet TEW-808UBM */ + { USB_DEVICE_AND_INTERFACE_INFO(0x2357, 0x012D, 0xff, 0xff, 0xff), + .driver_info = (kernel_ulong_t)&(rtw8822b_hw_spec) }, /* TP-Link Archer T3U v1 */ + { USB_DEVICE_AND_INTERFACE_INFO(0x2357, 0x012E, 0xff, 0xff, 0xff), + .driver_info = (kernel_ulong_t)&(rtw8822b_hw_spec) }, /* TP-LINK */ + { USB_DEVICE_AND_INTERFACE_INFO(0x2357, 0x0138, 0xff, 0xff, 0xff), + .driver_info = (kernel_ulong_t)&(rtw8822b_hw_spec) }, /* TP-Link Archer T3U Plus v1 */ + { USB_DEVICE_AND_INTERFACE_INFO(0x2C4E, 0x0107, 0xff, 0xff, 0xff), + .driver_info = (kernel_ulong_t)&(rtw8822b_hw_spec) }, /* Mercusys MA30H */ + { USB_DEVICE_AND_INTERFACE_INFO(0x7392, 0xB822, 0xff, 0xff, 0xff), + .driver_info = (kernel_ulong_t)&(rtw8822b_hw_spec) }, /* Edimax EW-7822ULC */ + { USB_DEVICE_AND_INTERFACE_INFO(0x7392, 0xC822, 0xff, 0xff, 0xff), + .driver_info = (kernel_ulong_t)&(rtw8822b_hw_spec) }, /* Edimax EW-7822UTC */ + { USB_DEVICE_AND_INTERFACE_INFO(0x7392, 0xD822, 0xff, 0xff, 0xff), + .driver_info = (kernel_ulong_t)&(rtw8822b_hw_spec) }, /* Edimax */ + { USB_DEVICE_AND_INTERFACE_INFO(0x7392, 0xE822, 0xff, 0xff, 0xff), + .driver_info = (kernel_ulong_t)&(rtw8822b_hw_spec) }, /* Edimax */ + { USB_DEVICE_AND_INTERFACE_INFO(0x7392, 0xF822, 0xff, 0xff, 0xff), + .driver_info = (kernel_ulong_t)&(rtw8822b_hw_spec) }, /* Edimax EW-7822UAD */ {}, }; MODULE_DEVICE_TABLE(usb, rtw_8822bu_id_table); From 2c873db6cb3aae3a8c7ffe5638549d44a0cadb57 Mon Sep 17 00:00:00 2001 From: Bitterblue Smith Date: Thu, 31 Oct 2024 18:10:49 +0200 Subject: [PATCH 046/193] 8812au: Reduce RX aggregation size in USB 3 mode in 5 GHz Even though the official driver uses the same aggregation size and RX buffer size, when driven by rtw88 the chip frequently tries to aggregate more frames than will fit in 32768 bytes. This is because rtw88 advertises support for receiving AMSDU in AMPDU, so the AP sends larger frames. Somehow the chip doesn't calculate things right. Fixes https://github.com/lwfinger/rtw88/issues/229 Signed-off-by: Bitterblue Smith --- usb.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/usb.c b/usb.c index 33d637c0..faebc786 100644 --- a/usb.c +++ b/usb.c @@ -804,7 +804,7 @@ static void rtw_usb_dynamic_rx_agg_v2(struct rtw_dev *rtwdev, bool enable) u16 val16; if (rtwusb->udev->speed == USB_SPEED_SUPER) { - size = 0x7; + size = 0x6; timeout = 0x1a; } else { size = 0x5; From e9a6539a81a4ac1a539f510ded6a91c42efb7e2e Mon Sep 17 00:00:00 2001 From: Zenm Chen Date: Fri, 1 Nov 2024 18:44:20 +0800 Subject: [PATCH 047/193] Update blacklist-rtw88.conf blacklist rtw88_8812a.ko and rtw88_88xxa.ko which will be in the next kernel release. --- blacklist-rtw88.conf | 2 ++ 1 file changed, 2 insertions(+) diff --git a/blacklist-rtw88.conf b/blacklist-rtw88.conf index 820668cf..a2b19547 100644 --- a/blacklist-rtw88.conf +++ b/blacklist-rtw88.conf @@ -5,6 +5,7 @@ blacklist rtw88_8723de blacklist rtw88_8723ds blacklist rtw88_8723du blacklist rtw88_8723x +blacklist rtw88_8812a blacklist rtw88_8812au blacklist rtw88_8821a blacklist rtw88_8821au @@ -20,6 +21,7 @@ blacklist rtw88_8822c blacklist rtw88_8822ce blacklist rtw88_8822cs blacklist rtw88_8822cu +blacklist rtw88_88xxa blacklist rtw88_core blacklist rtw88_pci blacklist rtw88_sdio From 140da497c5890f874427df45ec4be636e41fb39b Mon Sep 17 00:00:00 2001 From: Bitterblue Smith Date: Fri, 1 Nov 2024 22:08:39 +0200 Subject: [PATCH 048/193] wifi: rtw88: Don't require TX report for null data during scans When connected to a network, something (wpa_supplicant? NetworkManager?) triggers a scan every five minutes. During these scans mac80211 transmits ~76 QoS Null frames, twice the number of available channels. Because these frames are marked with IEEE80211_TX_CTL_REQ_TX_STATUS, rtw88 asks the firmware to report the TX ACK status for each of these frames. Sometimes the RTL8821AU firmware can't process the TX status requests quickly enough, they add up, it only processes some of them, and it permanently messes up the internal sequence number assigned to each TX status report. Then the firmware marks every subsequent TX status report with the wrong number, so rtw88 ignores them and prints a warning instead of reporting the TX status back to mac80211. To fix this, avoid bombarding the firmware with TX report requests by ignoring IEEE80211_TX_CTL_REQ_TX_STATUS during scans if the frame being transmitted is a null data frame. Signed-off-by: Bitterblue Smith --- pci.c | 2 +- sdio.c | 2 +- tx.c | 15 ++++++++++++++- tx.h | 1 + usb.c | 2 +- 5 files changed, 18 insertions(+), 4 deletions(-) diff --git a/pci.c b/pci.c index e6bb7a2c..6545f3db 100644 --- a/pci.c +++ b/pci.c @@ -993,7 +993,7 @@ static void rtw_pci_tx_isr(struct rtw_dev *rtwdev, struct rtw_pci *rtwpci, info = IEEE80211_SKB_CB(skb); /* enqueue to wait for tx report */ - if (info->flags & IEEE80211_TX_CTL_REQ_TX_STATUS) { + if (rtw_tx_report_needed(rtwdev, skb)) { rtw_tx_report_enqueue(rtwdev, skb, tx_data->sn); continue; } diff --git a/sdio.c b/sdio.c index 7b053dbb..e0508e04 100644 --- a/sdio.c +++ b/sdio.c @@ -1193,7 +1193,7 @@ static void rtw_sdio_indicate_tx_status(struct rtw_dev *rtwdev, struct ieee80211_hw *hw = rtwdev->hw; /* enqueue to wait for tx report */ - if (info->flags & IEEE80211_TX_CTL_REQ_TX_STATUS) { + if (rtw_tx_report_needed(rtwdev, skb)) { rtw_tx_report_enqueue(rtwdev, skb, tx_data->sn); return; } diff --git a/tx.c b/tx.c index a5adcd60..27a5613b 100644 --- a/tx.c +++ b/tx.c @@ -216,6 +216,19 @@ void rtw_tx_report_purge_timer(void *cntx) spin_unlock_irqrestore(&tx_report->q_lock, flags); } +bool rtw_tx_report_needed(struct rtw_dev *rtwdev, struct sk_buff *skb) +{ + struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; + struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); + + if (test_bit(RTW_FLAG_SCANNING, rtwdev->flags) && + ieee80211_is_any_nullfunc(hdr->frame_control)) + return false; + + return !!(info->flags & IEEE80211_TX_CTL_REQ_TX_STATUS); +} +EXPORT_SYMBOL(rtw_tx_report_needed); + void rtw_tx_report_enqueue(struct rtw_dev *rtwdev, struct sk_buff *skb, u8 sn) { struct rtw_tx_report *tx_report = &rtwdev->tx_report; @@ -463,7 +476,7 @@ void rtw_tx_pkt_info_update(struct rtw_dev *rtwdev, bmc = is_broadcast_ether_addr(hdr->addr1) || is_multicast_ether_addr(hdr->addr1); - if (info->flags & IEEE80211_TX_CTL_REQ_TX_STATUS) + if (rtw_tx_report_needed(rtwdev, skb)) rtw_tx_report_enable(rtwdev, pkt_info); pkt_info->bmc = bmc; diff --git a/tx.h b/tx.h index d34cdeca..978b0060 100644 --- a/tx.h +++ b/tx.h @@ -97,6 +97,7 @@ void rtw_tx_pkt_info_update(struct rtw_dev *rtwdev, struct sk_buff *skb); void rtw_tx_fill_tx_desc(struct rtw_dev *rtwdev, struct rtw_tx_pkt_info *pkt_info, struct sk_buff *skb); +bool rtw_tx_report_needed(struct rtw_dev *rtwdev, struct sk_buff *skb); void rtw_tx_report_enqueue(struct rtw_dev *rtwdev, struct sk_buff *skb, u8 sn); void rtw_tx_report_handle(struct rtw_dev *rtwdev, struct sk_buff *skb, int src); void rtw_tx_rsvd_page_pkt_info_update(struct rtw_dev *rtwdev, diff --git a/usb.c b/usb.c index faebc786..3a85fad4 100644 --- a/usb.c +++ b/usb.c @@ -281,7 +281,7 @@ static void rtw_usb_write_port_tx_complete(struct urb *urb) skb_pull(skb, rtwdev->chip->tx_pkt_desc_sz); /* enqueue to wait for tx report */ - if (info->flags & IEEE80211_TX_CTL_REQ_TX_STATUS) { + if (rtw_tx_report_needed(rtwdev, skb)) { rtw_tx_report_enqueue(rtwdev, skb, tx_data->sn); continue; } From 96049d19d4ac0d7261b03baaa2f708908d50ac66 Mon Sep 17 00:00:00 2001 From: Portisch Date: Mon, 4 Nov 2024 10:05:12 +0100 Subject: [PATCH 049/193] 8812au: fix typo --- rtw8812au.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rtw8812au.c b/rtw8812au.c index 947e3e98..f2548f2f 100644 --- a/rtw8812au.c +++ b/rtw8812au.c @@ -19,7 +19,7 @@ static const struct usb_device_id rtw_8812au_id_table[] = { .driver_info = (kernel_ulong_t)&(rtw8812a_hw_spec) }, { USB_DEVICE_AND_INTERFACE_INFO(0x0409, 0x0408, 0xff, 0xff, 0xff), .driver_info = (kernel_ulong_t)&(rtw8812a_hw_spec) }, /* NEC */ - { USB_DEVICE_AND_INTERFACE_INFO(0x0411, 0x0408, 0xff, 0xff, 0xff), + { USB_DEVICE_AND_INTERFACE_INFO(0x0411, 0x025D, 0xff, 0xff, 0xff), .driver_info = (kernel_ulong_t)&(rtw8812a_hw_spec) }, /* Buffalo */ { USB_DEVICE_AND_INTERFACE_INFO(0x04bb, 0x0952, 0xff, 0xff, 0xff), .driver_info = (kernel_ulong_t)&(rtw8812a_hw_spec) }, /* I-O DATA */ From 93896b0a2e5907a7c951eb160ccbc8bae05f851e Mon Sep 17 00:00:00 2001 From: Bitterblue Smith Date: Wed, 6 Nov 2024 16:37:30 +0200 Subject: [PATCH 050/193] wifi: rtw88: usb: Rework the RX path This patch fixes two problems: 1. The USB driver uses four USB Request Blocks for RX. Before submitting one, it allocates a 32768 byte skb for the RX data. This allocation can fail, maybe due to temporary memory fragmentation. When the allocation fails, the corresponding URB is never submitted again. After four such allocation failures, all RX stops because the driver is not requesting data from the device anymore. 2. "iperf3 -c 192.168.0.1 -R --udp -b 0" shows about 40% of datagrams are lost. Many torrents don't download faster than 3 MiB/s, probably because the Bittorrent protocol uses UDP. This is somehow related to the use of skb_clone() in the RX path. Don't allocate a 32768 byte skb when submitting a USB Request Block (which happens very often). Instead preallocate 8 such skbs, and reuse them over and over. If all 8 are busy, allocate a new one. This is pretty rare. If the allocation fails, use a work to try again later. When there are enough free skbs again, free the excess skbs. Don't use skb_clone(). Instead allocate a new skb for each 802.11 frame received and copy the data from the big skb. These are much smaller than 32768 bytes, so the allocations are less likely to fail. If an allocation does fail, try it again. And finally, use WQ_BH for the RX workqueue. With a normal or high priority workqueue the skbs are processed too slowly when the system is even a little busy, like when opening a new page in a browser, and the driver runs out of free skbs and allocates a lot of new ones. This is more or less what the out-of-tree Realtek drivers do, except they use a tasklet instead of a BH workqueue. With this patch, "iperf3 -c 192.168.0.1 -R --udp -b 0" shows only 1-2% of datagrams are lost, and torrents can reach download speeds of 36 MiB/s. And RX doesn't stop anymore, of course. Closes: https://lore.kernel.org/linux-wireless/6e7ecb47-7ea0-433a-a19f-05f88a2edf6b@gmail.com/ Signed-off-by: Bitterblue Smith --- usb.c | 144 ++++++++++++++++++++++++++++++++++++++++++++++------------ usb.h | 6 +++ 2 files changed, 120 insertions(+), 30 deletions(-) diff --git a/usb.c b/usb.c index 3a85fad4..94de772d 100644 --- a/usb.c +++ b/usb.c @@ -549,53 +549,68 @@ static void rtw_usb_tx_kick_off(struct rtw_dev *rtwdev) queue_work(rtwusb->txwq, &rtwusb->tx_work); } +#if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 9, 0) static void rtw_usb_rx_handler(struct work_struct *work) { struct rtw_usb *rtwusb = container_of(work, struct rtw_usb, rx_work); +#else +static void rtw_usb_rx_handler(struct rtw_usb *rtwusb) +{ +#endif struct rtw_dev *rtwdev = rtwusb->rtwdev; const struct rtw_chip_info *chip = rtwdev->chip; u32 pkt_desc_sz = chip->rx_pkt_desc_sz; struct ieee80211_rx_status rx_status; u32 pkt_offset, next_pkt, urb_len; struct rtw_rx_pkt_stat pkt_stat; - struct sk_buff *next_skb; + struct sk_buff *rx_skb; struct sk_buff *skb; + u32 skb_len; u8 *rx_desc; int limit; for (limit = 0; limit < 200; limit++) { - skb = skb_dequeue(&rtwusb->rx_queue); - if (!skb) + rx_skb = skb_dequeue(&rtwusb->rx_queue); + if (!rx_skb) break; if (skb_queue_len(&rtwusb->rx_queue) >= RTW_USB_MAX_RXQ_LEN) { dev_dbg_ratelimited(rtwdev->dev, "failed to get rx_queue, overflow\n"); - dev_kfree_skb_any(skb); + dev_kfree_skb_any(rx_skb); continue; } - urb_len = skb->len; + urb_len = rx_skb->len; + rx_desc = rx_skb->data; do { - rx_desc = skb->data; rtw_rx_query_rx_desc(rtwdev, rx_desc, &pkt_stat, &rx_status); pkt_offset = pkt_desc_sz + pkt_stat.drv_info_sz + pkt_stat.shift; - next_pkt = round_up(pkt_stat.pkt_len + pkt_offset, 8); + skb_len = pkt_stat.pkt_len + pkt_offset; + if (skb_len > 12000) { + rtw_err(rtwdev, + "skipping RX URB, packet too big: %u\n", + skb_len); + break; + } - if (urb_len >= next_pkt + pkt_desc_sz) - next_skb = skb_clone(skb, GFP_KERNEL); - else - next_skb = NULL; + skb = alloc_skb(skb_len, GFP_ATOMIC); + if (!skb) { + rtw_err(rtwdev,/// TODO rtw_dbg + "failed to allocate RX skb of size %d\n", + skb_len); + continue; /* try again */ + } + + skb_put_data(skb, rx_desc, skb_len); if (pkt_stat.is_c2h) { - skb_trim(skb, pkt_stat.pkt_len + pkt_offset); rtw_fw_c2h_cmd_rx_irqsafe(rtwdev, pkt_offset, skb); } else { skb_pull(skb, pkt_offset); - skb_trim(skb, pkt_stat.pkt_len); rtw_update_rx_freq_for_invalid(rtwdev, skb, &rx_status, &pkt_stat); @@ -604,13 +619,22 @@ static void rtw_usb_rx_handler(struct work_struct *work) ieee80211_rx_irqsafe(rtwdev->hw, skb); } - skb = next_skb; - if (skb) - skb_pull(skb, next_pkt); + next_pkt = round_up(skb_len, 8); + rx_desc += next_pkt; + } while (rx_skb->data + urb_len > rx_desc + pkt_desc_sz); - urb_len -= next_pkt; - } while (skb); + if (skb_queue_len(&rtwusb->rx_free_queue) >= + RTW_USB_RX_SKB_NUM - RTW_USB_RXCB_NUM) { + rtw_err(rtwdev, "freeing excess RX skb\n"); + dev_kfree_skb_any(rx_skb); + } else { + skb_queue_tail(&rtwusb->rx_free_queue, rx_skb); + } } + + if (limit == 200) + rtw_err(rtwdev, "left %u frames in the rx queue for later\n", + skb_queue_len(&rtwusb->rx_queue)); } static void rtw_usb_read_port_complete(struct urb *urb); @@ -618,25 +642,62 @@ static void rtw_usb_read_port_complete(struct urb *urb); static void rtw_usb_rx_resubmit(struct rtw_usb *rtwusb, struct rx_usb_ctrl_block *rxcb) { struct rtw_dev *rtwdev = rtwusb->rtwdev; + struct sk_buff *rx_skb; + gfp_t priority = in_interrupt() ? GFP_ATOMIC : GFP_KERNEL; int error; - rxcb->rx_skb = alloc_skb(RTW_USB_MAX_RECVBUF_SZ, GFP_ATOMIC); - if (!rxcb->rx_skb) { - rtw_err(rtwdev, "failed to allocate rx_skb\n"); - return; + rx_skb = skb_dequeue(&rtwusb->rx_free_queue); + if (!rx_skb) { + rtw_err(rtwdev, "allocating new RX skb\n"); + + rx_skb = alloc_skb(RTW_USB_MAX_RECVBUF_SZ, priority); + } + + if (!rx_skb) { + rtw_err(rtwdev, "no free RX skb and alloc_skb failed\n"); + + goto try_later; } + rxcb->rx_skb = rx_skb; + + skb_reset_tail_pointer(rxcb->rx_skb); + rxcb->rx_skb->len = 0; + usb_fill_bulk_urb(rxcb->rx_urb, rtwusb->udev, usb_rcvbulkpipe(rtwusb->udev, rtwusb->pipe_in), rxcb->rx_skb->data, RTW_USB_MAX_RECVBUF_SZ, rtw_usb_read_port_complete, rxcb); - error = usb_submit_urb(rxcb->rx_urb, GFP_ATOMIC); + error = usb_submit_urb(rxcb->rx_urb, priority); if (error) { - kfree_skb(rxcb->rx_skb); + skb_queue_tail(&rtwusb->rx_free_queue, rxcb->rx_skb); + if (error != -ENODEV) - rtw_err(rtwdev, "Err sending rx data urb %d\n", - error); + rtw_err(rtwdev, "Err sending rx data urb %d\n", error); + + if (error == -ENOMEM) + goto try_later; + } + + return; + +try_later: + rxcb->rx_skb = NULL; + queue_work(rtwusb->rxwq, &rtwusb->rx_urb_work); +} + +static void rtw_usb_rx_resubmit_work(struct work_struct *work) +{ + struct rtw_usb *rtwusb = container_of(work, struct rtw_usb, rx_urb_work); + struct rx_usb_ctrl_block *rxcb; + int i; + + for (i = 0; i < RTW_USB_RXCB_NUM; i++) { + rxcb = &rtwusb->rx_cb[i]; + + if (!rxcb->rx_skb) + rtw_usb_rx_resubmit(rtwusb, rxcb); } } @@ -652,15 +713,20 @@ static void rtw_usb_read_port_complete(struct urb *urb) urb->actual_length < 24) { rtw_err(rtwdev, "failed to get urb length:%d\n", urb->actual_length); - if (skb) - dev_kfree_skb_any(skb); + skb_queue_tail(&rtwusb->rx_free_queue, skb); } else { skb_put(skb, urb->actual_length); skb_queue_tail(&rtwusb->rx_queue, skb); +#if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 9, 0) queue_work(rtwusb->rxwq, &rtwusb->rx_work); +#else + tasklet_schedule(&rtwusb->rx_tasklet); +#endif } rtw_usb_rx_resubmit(rtwusb, rxcb); } else { + skb_queue_tail(&rtwusb->rx_free_queue, skb); + switch (urb->status) { case -EINVAL: case -EPIPE: @@ -678,8 +744,6 @@ static void rtw_usb_read_port_complete(struct urb *urb) rtw_err(rtwdev, "status %d\n", urb->status); break; } - if (skb) - dev_kfree_skb_any(skb); } } @@ -869,16 +933,34 @@ static struct rtw_hci_ops rtw_usb_ops = { static int rtw_usb_init_rx(struct rtw_dev *rtwdev) { struct rtw_usb *rtwusb = rtw_get_usb_priv(rtwdev); + struct sk_buff *rx_skb; + int i; + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 9, 0) + rtwusb->rxwq = alloc_workqueue("rtw88_usb: rx wq", WQ_BH, 0); +#else + tasklet_init(&rtwusb->rx_tasklet, + (void(*)(unsigned long))rtw_usb_rx_handler, + (unsigned long)rtwusb); rtwusb->rxwq = create_singlethread_workqueue("rtw88_usb: rx wq"); +#endif if (!rtwusb->rxwq) { rtw_err(rtwdev, "failed to create RX work queue\n"); return -ENOMEM; } skb_queue_head_init(&rtwusb->rx_queue); + skb_queue_head_init(&rtwusb->rx_free_queue); INIT_WORK(&rtwusb->rx_work, rtw_usb_rx_handler); + INIT_WORK(&rtwusb->rx_urb_work, rtw_usb_rx_resubmit_work); + + for (i = 0; i < RTW_USB_RX_SKB_NUM; i++) { + rx_skb = alloc_skb(RTW_USB_MAX_RECVBUF_SZ, GFP_KERNEL); + if (rx_skb) + skb_queue_tail(&rtwusb->rx_free_queue, rx_skb); + } return 0; } @@ -903,6 +985,8 @@ static void rtw_usb_deinit_rx(struct rtw_dev *rtwdev) flush_workqueue(rtwusb->rxwq); destroy_workqueue(rtwusb->rxwq); + + skb_queue_purge(&rtwusb->rx_free_queue); } static int rtw_usb_init_tx(struct rtw_dev *rtwdev) diff --git a/usb.h b/usb.h index 86697a5c..ae0af4fd 100644 --- a/usb.h +++ b/usb.h @@ -38,6 +38,7 @@ #define RTW_USB_RXAGG_TIMEOUT 10 #define RTW_USB_RXCB_NUM 4 +#define RTW_USB_RX_SKB_NUM 8 #define RTW_USB_EP_MAX 4 @@ -75,13 +76,18 @@ struct rtw_usb { int qsel_to_ep[TX_DESC_QSEL_MAX]; struct workqueue_struct *txwq, *rxwq; +#if LINUX_VERSION_CODE < KERNEL_VERSION(6, 9, 0) + struct tasklet_struct rx_tasklet; // Can't use BH workqueue +#endif struct sk_buff_head tx_queue[RTW_USB_EP_MAX]; struct work_struct tx_work; struct rx_usb_ctrl_block rx_cb[RTW_USB_RXCB_NUM]; struct sk_buff_head rx_queue; + struct sk_buff_head rx_free_queue; struct work_struct rx_work; + struct work_struct rx_urb_work; }; static inline struct rtw_usb_tx_data *rtw_usb_get_tx_data(struct sk_buff *skb) From c99b65521313b2a33a8ec83e19a5116ce1fd87e1 Mon Sep 17 00:00:00 2001 From: Bitterblue Smith Date: Thu, 7 Nov 2024 16:57:56 +0200 Subject: [PATCH 051/193] Move C2H_ADAPTIVITY to the c2h workqueue It reads hardware registers, which is not "irqsafe" with USB. Relevant to RTL8822CU. Fixes 93896b0a2e5907a7c951eb160ccbc8bae05f851e. Signed-off-by: Bitterblue Smith --- fw.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/fw.c b/fw.c index 0a415223..72c7f5a8 100644 --- a/fw.c +++ b/fw.c @@ -336,6 +336,9 @@ void rtw_fw_c2h_cmd_handle(struct rtw_dev *rtwdev, struct sk_buff *skb) case C2H_RA_RPT: rtw_fw_ra_report_handle(rtwdev, c2h->payload, len); break; + case C2H_ADAPTIVITY: + rtw_fw_adaptivity_result(rtwdev, c2h->payload, len); + break; default: rtw_dbg(rtwdev, RTW_DBG_FW, "C2H 0x%x isn't handled\n", c2h->id); break; @@ -371,10 +374,6 @@ void rtw_fw_c2h_cmd_rx_irqsafe(struct rtw_dev *rtwdev, u32 pkt_offset, rtw_fw_scan_result(rtwdev, c2h->payload, len); dev_kfree_skb_any(skb); break; - case C2H_ADAPTIVITY: - rtw_fw_adaptivity_result(rtwdev, c2h->payload, len); - dev_kfree_skb_any(skb); - break; default: /* pass offset for further operation */ *((u32 *)skb->cb) = pkt_offset; From d027ff84e08f7a50b9a964621db7047ab67f7bc1 Mon Sep 17 00:00:00 2001 From: Bitterblue Smith Date: Thu, 7 Nov 2024 16:59:46 +0200 Subject: [PATCH 052/193] Don't initialise rx_work for kernels older than 6.9 It's not used. Fixes 93896b0a2e5907a7c951eb160ccbc8bae05f851e. Signed-off-by: Bitterblue Smith --- usb.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/usb.c b/usb.c index 94de772d..89b37226 100644 --- a/usb.c +++ b/usb.c @@ -953,7 +953,9 @@ static int rtw_usb_init_rx(struct rtw_dev *rtwdev) skb_queue_head_init(&rtwusb->rx_queue); skb_queue_head_init(&rtwusb->rx_free_queue); +#if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 9, 0) INIT_WORK(&rtwusb->rx_work, rtw_usb_rx_handler); +#endif INIT_WORK(&rtwusb->rx_urb_work, rtw_usb_rx_resubmit_work); for (i = 0; i < RTW_USB_RX_SKB_NUM; i++) { From 4a0d5478a798f2867e6adcdb9710e55ee696f5b2 Mon Sep 17 00:00:00 2001 From: Zenm Chen Date: Fri, 8 Nov 2024 11:23:17 +0800 Subject: [PATCH 053/193] Update rtw8822b_fw.bin to v30.20.0 This firmware was extracted from the vendor driver v5.13.1-30-g37e60b26a.20220819_COEX20220812-18317b7b. --- firmware/rtw8822b_fw.bin | Bin 150984 -> 161240 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/firmware/rtw8822b_fw.bin b/firmware/rtw8822b_fw.bin index 0934ffcc77a327285569d135f55b58e8902511b1..7ed1ab4845c960001aa51e2968bc2baf19008a55 100644 GIT binary patch literal 161240 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 VJ`{014=&ig=7Q^AM_l~he*-3>zKj3> literal 150984 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 From e1cd18ab8eb6a3e32f6470b2a8716af16c18d152 Mon Sep 17 00:00:00 2001 From: Zenm Chen Date: Fri, 8 Nov 2024 11:41:47 +0800 Subject: [PATCH 054/193] Add support for Mercusys MA30N / D-Link DWA-T185 rev. A1 These USB IDs were found in RinCat's repo. Link: https://github.com/RinCat/RTL88x2BU-Linux-Driver --- rtw8822bu.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/rtw8822bu.c b/rtw8822bu.c index 20aa4564..a746707d 100644 --- a/rtw8822bu.c +++ b/rtw8822bu.c @@ -45,6 +45,8 @@ static const struct usb_device_id rtw_8822bu_id_table[] = { .driver_info = (kernel_ulong_t)&(rtw8822b_hw_spec) }, /* Dlink - DWA-181 */ { USB_DEVICE_AND_INTERFACE_INFO(0x2001, 0x331F, 0xff, 0xff, 0xff), .driver_info = (kernel_ulong_t)&(rtw8822b_hw_spec) }, /* Dlink - DWA-183 - D */ + { USB_DEVICE_AND_INTERFACE_INFO(0x2001, 0x3322, 0xff, 0xff, 0xff), + .driver_info = (kernel_ulong_t)&(rtw8822b_hw_spec) }, /* Dlink - DWA-T185 rev. A1 */ { USB_DEVICE_AND_INTERFACE_INFO(0x20F4, 0x805A, 0xff, 0xff, 0xff), .driver_info = (kernel_ulong_t)&(rtw8822b_hw_spec) }, /* TRENDnet TEW-805UBH */ { USB_DEVICE_AND_INTERFACE_INFO(0x20F4, 0x808A, 0xff, 0xff, 0xff), @@ -63,6 +65,8 @@ static const struct usb_device_id rtw_8822bu_id_table[] = { .driver_info = (kernel_ulong_t)&(rtw8822b_hw_spec) }, /* TP-Link Archer T3U Plus v1 */ { USB_DEVICE_AND_INTERFACE_INFO(0x2C4E, 0x0107, 0xff, 0xff, 0xff), .driver_info = (kernel_ulong_t)&(rtw8822b_hw_spec) }, /* Mercusys MA30H */ + { USB_DEVICE_AND_INTERFACE_INFO(0x2C4E, 0x010a, 0xff, 0xff, 0xff), + .driver_info = (kernel_ulong_t)&(rtw8822b_hw_spec) }, /* Mercusys MA30N */ { USB_DEVICE_AND_INTERFACE_INFO(0x7392, 0xB822, 0xff, 0xff, 0xff), .driver_info = (kernel_ulong_t)&(rtw8822b_hw_spec) }, /* Edimax EW-7822ULC */ { USB_DEVICE_AND_INTERFACE_INFO(0x7392, 0xC822, 0xff, 0xff, 0xff), From c4929f7e647bf86bdc12b2a28a47b64b5e7c78b0 Mon Sep 17 00:00:00 2001 From: morrownr Date: Tue, 12 Nov 2024 11:57:46 -0600 Subject: [PATCH 055/193] add ID 7392:b822 for Edimax EW-7822ULC - rtw8812au --- rtw8812au.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/rtw8812au.c b/rtw8812au.c index f2548f2f..213aaa0d 100644 --- a/rtw8812au.c +++ b/rtw8812au.c @@ -77,6 +77,8 @@ static const struct usb_device_id rtw_8812au_id_table[] = { .driver_info = (kernel_ulong_t)&(rtw8812a_hw_spec) }, /* Tenda */ { USB_DEVICE_AND_INTERFACE_INFO(0x7392, 0xa822, 0xff, 0xff, 0xff), .driver_info = (kernel_ulong_t)&(rtw8812a_hw_spec) }, /* Edimax */ + { USB_DEVICE_AND_INTERFACE_INFO(0x7392, 0xb822, 0xff, 0xff, 0xff), + .driver_info = (kernel_ulong_t)&(rtw8812a_hw_spec) }, /* Edimax */ {}, }; MODULE_DEVICE_TABLE(usb, rtw_8812au_id_table); From 501934a4c14fc8ec3efe204a27af95f57dd16981 Mon Sep 17 00:00:00 2001 From: morrownr Date: Tue, 12 Nov 2024 13:00:11 -0600 Subject: [PATCH 056/193] revert ID 7392:b822 for Edimax EW-7822ULC - rtw8812au --- rtw8812au.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/rtw8812au.c b/rtw8812au.c index 213aaa0d..f2548f2f 100644 --- a/rtw8812au.c +++ b/rtw8812au.c @@ -77,8 +77,6 @@ static const struct usb_device_id rtw_8812au_id_table[] = { .driver_info = (kernel_ulong_t)&(rtw8812a_hw_spec) }, /* Tenda */ { USB_DEVICE_AND_INTERFACE_INFO(0x7392, 0xa822, 0xff, 0xff, 0xff), .driver_info = (kernel_ulong_t)&(rtw8812a_hw_spec) }, /* Edimax */ - { USB_DEVICE_AND_INTERFACE_INFO(0x7392, 0xb822, 0xff, 0xff, 0xff), - .driver_info = (kernel_ulong_t)&(rtw8812a_hw_spec) }, /* Edimax */ {}, }; MODULE_DEVICE_TABLE(usb, rtw_8812au_id_table); From 0ef5c8157a2d849ebd72cb26c2acc5934ca837f3 Mon Sep 17 00:00:00 2001 From: Bitterblue Smith Date: Sat, 16 Nov 2024 01:20:20 +0200 Subject: [PATCH 057/193] Revert "wifi: rtw88: Don't require TX report for null data during scans" This reverts commit 140da497c5890f874427df45ec4be636e41fb39b. This problem needs a bigger hammer. --- pci.c | 2 +- sdio.c | 2 +- tx.c | 15 +-------------- tx.h | 1 - usb.c | 2 +- 5 files changed, 4 insertions(+), 18 deletions(-) diff --git a/pci.c b/pci.c index 6545f3db..e6bb7a2c 100644 --- a/pci.c +++ b/pci.c @@ -993,7 +993,7 @@ static void rtw_pci_tx_isr(struct rtw_dev *rtwdev, struct rtw_pci *rtwpci, info = IEEE80211_SKB_CB(skb); /* enqueue to wait for tx report */ - if (rtw_tx_report_needed(rtwdev, skb)) { + if (info->flags & IEEE80211_TX_CTL_REQ_TX_STATUS) { rtw_tx_report_enqueue(rtwdev, skb, tx_data->sn); continue; } diff --git a/sdio.c b/sdio.c index e0508e04..7b053dbb 100644 --- a/sdio.c +++ b/sdio.c @@ -1193,7 +1193,7 @@ static void rtw_sdio_indicate_tx_status(struct rtw_dev *rtwdev, struct ieee80211_hw *hw = rtwdev->hw; /* enqueue to wait for tx report */ - if (rtw_tx_report_needed(rtwdev, skb)) { + if (info->flags & IEEE80211_TX_CTL_REQ_TX_STATUS) { rtw_tx_report_enqueue(rtwdev, skb, tx_data->sn); return; } diff --git a/tx.c b/tx.c index 27a5613b..a5adcd60 100644 --- a/tx.c +++ b/tx.c @@ -216,19 +216,6 @@ void rtw_tx_report_purge_timer(void *cntx) spin_unlock_irqrestore(&tx_report->q_lock, flags); } -bool rtw_tx_report_needed(struct rtw_dev *rtwdev, struct sk_buff *skb) -{ - struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; - struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); - - if (test_bit(RTW_FLAG_SCANNING, rtwdev->flags) && - ieee80211_is_any_nullfunc(hdr->frame_control)) - return false; - - return !!(info->flags & IEEE80211_TX_CTL_REQ_TX_STATUS); -} -EXPORT_SYMBOL(rtw_tx_report_needed); - void rtw_tx_report_enqueue(struct rtw_dev *rtwdev, struct sk_buff *skb, u8 sn) { struct rtw_tx_report *tx_report = &rtwdev->tx_report; @@ -476,7 +463,7 @@ void rtw_tx_pkt_info_update(struct rtw_dev *rtwdev, bmc = is_broadcast_ether_addr(hdr->addr1) || is_multicast_ether_addr(hdr->addr1); - if (rtw_tx_report_needed(rtwdev, skb)) + if (info->flags & IEEE80211_TX_CTL_REQ_TX_STATUS) rtw_tx_report_enable(rtwdev, pkt_info); pkt_info->bmc = bmc; diff --git a/tx.h b/tx.h index 978b0060..d34cdeca 100644 --- a/tx.h +++ b/tx.h @@ -97,7 +97,6 @@ void rtw_tx_pkt_info_update(struct rtw_dev *rtwdev, struct sk_buff *skb); void rtw_tx_fill_tx_desc(struct rtw_dev *rtwdev, struct rtw_tx_pkt_info *pkt_info, struct sk_buff *skb); -bool rtw_tx_report_needed(struct rtw_dev *rtwdev, struct sk_buff *skb); void rtw_tx_report_enqueue(struct rtw_dev *rtwdev, struct sk_buff *skb, u8 sn); void rtw_tx_report_handle(struct rtw_dev *rtwdev, struct sk_buff *skb, int src); void rtw_tx_rsvd_page_pkt_info_update(struct rtw_dev *rtwdev, diff --git a/usb.c b/usb.c index 89b37226..9dafc75f 100644 --- a/usb.c +++ b/usb.c @@ -281,7 +281,7 @@ static void rtw_usb_write_port_tx_complete(struct urb *urb) skb_pull(skb, rtwdev->chip->tx_pkt_desc_sz); /* enqueue to wait for tx report */ - if (rtw_tx_report_needed(rtwdev, skb)) { + if (info->flags & IEEE80211_TX_CTL_REQ_TX_STATUS) { rtw_tx_report_enqueue(rtwdev, skb, tx_data->sn); continue; } From 22f241226d5813d4062a656b0d844e62eb1fd715 Mon Sep 17 00:00:00 2001 From: Bitterblue Smith Date: Sat, 16 Nov 2024 01:26:50 +0200 Subject: [PATCH 058/193] wifi: rtw88: Ignore TX report sequence number from the older chips When connected to a network, wpa_supplicant triggers a scan every five minutes. During these scans mac80211 transmits many QoS Null frames in quick succession. Because these frames are marked with IEEE80211_TX_CTL_REQ_TX_STATUS, rtw88 asks the firmware to report the TX ACK status for each of these frames. Sometimes the firmware can't process the TX status requests quickly enough, they add up, it only processes some of them, and then marks every subsequent TX status report with the wrong number. This problem apparently happens only with the older RTL8723D, RTL8821A, RTL8812A, and probably RTL8703B chips. Ignore the TX report sequence number reported by these chips and match the reports with the requests in the order they come in. Also, initialise the members of struct rtw_chip_info in the order they are declared (more or less). Tested with RTL8821AU and RTL8723DU. Signed-off-by: Bitterblue Smith --- main.h | 1 + rtw8703b.c | 1 + rtw8723d.c | 15 ++++++++------- rtw8812a.c | 23 ++++++++++++----------- rtw8821a.c | 23 ++++++++++++----------- rtw8821c.c | 15 ++++++++------- rtw8822b.c | 17 +++++++++-------- rtw8822c.c | 23 ++++++++++++----------- tx.c | 2 +- 9 files changed, 64 insertions(+), 56 deletions(-) diff --git a/main.h b/main.h index 8b58d00b..11598e42 100644 --- a/main.h +++ b/main.h @@ -1342,6 +1342,7 @@ struct rtw_chip_info { bool hw_feature_report; u8 c2h_ra_report_size; bool old_datarate_fb_limit; + bool tx_report_sn; u8 default_1ss_tx_path; diff --git a/rtw8703b.c b/rtw8703b.c index c107e441..03ffe8e1 100644 --- a/rtw8703b.c +++ b/rtw8703b.c @@ -1981,6 +1981,7 @@ const struct rtw_chip_info rtw8703b_hw_spec = { .hw_feature_report = true, .c2h_ra_report_size = 7, .old_datarate_fb_limit = true, + .tx_report_sn = false, .path_div_supported = false, .ht_supported = true, diff --git a/rtw8723d.c b/rtw8723d.c index eeca31bf..2217f809 100644 --- a/rtw8723d.c +++ b/rtw8723d.c @@ -2126,26 +2126,29 @@ const struct rtw_chip_info rtw8723d_hw_spec = { .txff_size = 32768, .rxff_size = 16384, .rsvd_drv_pg_num = 8, - .txgi_factor = 1, - .is_pwr_by_rate_dec = true, - .max_power_index = 0x3f, - .csi_buf_pg_num = 0, .band = RTW_BAND_2G, .page_size = TX_PAGE_SIZE, + .csi_buf_pg_num = 0, .dig_min = 0x20, + .txgi_factor = 1, + .is_pwr_by_rate_dec = true, + .rx_ldpc = false, + .max_power_index = 0x3f, + .ampdu_density = IEEE80211_HT_MPDU_DENSITY_16, .usb_tx_agg_desc_num = 1, .hw_feature_report = true, .c2h_ra_report_size = 7, .old_datarate_fb_limit = true, + .tx_report_sn = false, .ht_supported = true, .vht_supported = false, .lps_deep_mode_supported = 0, .sys_func_en = 0xFD, .pwr_on_seq = card_enable_flow_8723d, .pwr_off_seq = card_disable_flow_8723d, - .page_table = page_table_8723d, .rqpn_table = rqpn_table_8723d, .prioq_addrs = &rtw8723x_common.prioq_addrs, + .page_table = page_table_8723d, .intf_table = &phy_para_table_8723d, .dig = rtw8723x_common.dig, .dig_cck = rtw8723x_common.dig_cck, @@ -2159,9 +2162,7 @@ const struct rtw_chip_info rtw8723d_hw_spec = { .rf_tbl = {&rtw8723d_rf_a_tbl}, .rfe_defs = rtw8723d_rfe_defs, .rfe_defs_size = ARRAY_SIZE(rtw8723d_rfe_defs), - .rx_ldpc = false, .iqk_threshold = 8, - .ampdu_density = IEEE80211_HT_MPDU_DENSITY_16, .max_scan_ie_len = IEEE80211_MAX_DATA_LEN, .coex_para_ver = 0x2007022f, diff --git a/rtw8812a.c b/rtw8812a.c index a6ab2dee..9d98117b 100644 --- a/rtw8812a.c +++ b/rtw8812a.c @@ -1028,22 +1028,29 @@ const struct rtw_chip_info rtw8812a_hw_spec = { .txff_size = 131072, .rxff_size = 16128, .rsvd_drv_pg_num = 9, - .txgi_factor = 1, - .is_pwr_by_rate_dec = true, - .max_power_index = 0x3f, - .csi_buf_pg_num = 0, .band = RTW_BAND_2G | RTW_BAND_5G, .page_size = 512, + .csi_buf_pg_num = 0, .dig_min = 0x20, + .txgi_factor = 1, + .is_pwr_by_rate_dec = true, + .rx_ldpc = false, + .max_power_index = 0x3f, + .ampdu_density = IEEE80211_HT_MPDU_DENSITY_16, + .usb_tx_agg_desc_num = 1, + .hw_feature_report = false, + .c2h_ra_report_size = 4, + .old_datarate_fb_limit = true, + .tx_report_sn = false, .ht_supported = true, .vht_supported = true, .lps_deep_mode_supported = 0, .sys_func_en = 0xFD, .pwr_on_seq = card_enable_flow_8812a, .pwr_off_seq = card_disable_flow_8812a, - .page_table = page_table_8812a, .rqpn_table = rqpn_table_8812a, .prioq_addrs = &prioq_addrs_8812a, + .page_table = page_table_8812a, .intf_table = NULL, .dig = rtw8812a_dig, .rf_sipi_addr = {REG_LSSI_WRITE_A, REG_LSSI_WRITE_B}, @@ -1054,13 +1061,7 @@ const struct rtw_chip_info rtw8812a_hw_spec = { .rf_tbl = {&rtw8812a_rf_a_tbl, &rtw8812a_rf_b_tbl}, .rfe_defs = rtw8812a_rfe_defs, .rfe_defs_size = ARRAY_SIZE(rtw8812a_rfe_defs), - .rx_ldpc = false, - .hw_feature_report = false, - .c2h_ra_report_size = 4, - .old_datarate_fb_limit = true, - .usb_tx_agg_desc_num = 1, .iqk_threshold = 8, - .ampdu_density = IEEE80211_HT_MPDU_DENSITY_16, .max_scan_ie_len = IEEE80211_MAX_DATA_LEN, .coex_para_ver = 0, /* no coex code in 8812au driver */ diff --git a/rtw8821a.c b/rtw8821a.c index db242c9a..2917478e 100644 --- a/rtw8821a.c +++ b/rtw8821a.c @@ -1122,22 +1122,29 @@ const struct rtw_chip_info rtw8821a_hw_spec = { .txff_size = 65536, .rxff_size = 16128, .rsvd_drv_pg_num = 8, - .txgi_factor = 1, - .is_pwr_by_rate_dec = true, - .max_power_index = 0x3f, - .csi_buf_pg_num = 0, .band = RTW_BAND_2G | RTW_BAND_5G, .page_size = 256, + .csi_buf_pg_num = 0, .dig_min = 0x20, + .txgi_factor = 1, + .is_pwr_by_rate_dec = true, + .rx_ldpc = false, + .max_power_index = 0x3f, + .ampdu_density = IEEE80211_HT_MPDU_DENSITY_16, + .usb_tx_agg_desc_num = 6, + .hw_feature_report = false, + .c2h_ra_report_size = 4, + .old_datarate_fb_limit = true, + .tx_report_sn = false, .ht_supported = true, .vht_supported = true, .lps_deep_mode_supported = 0, .sys_func_en = 0xFD, .pwr_on_seq = card_enable_flow_8821a, .pwr_off_seq = card_disable_flow_8821a, - .page_table = page_table_8821a, .rqpn_table = rqpn_table_8821a, .prioq_addrs = &prioq_addrs_8821a, + .page_table = page_table_8821a, .intf_table = NULL, .dig = rtw8821a_dig, .rf_sipi_addr = {REG_LSSI_WRITE_A, REG_LSSI_WRITE_B}, @@ -1148,13 +1155,7 @@ const struct rtw_chip_info rtw8821a_hw_spec = { .rf_tbl = {&rtw8821a_rf_a_tbl}, .rfe_defs = rtw8821a_rfe_defs, .rfe_defs_size = ARRAY_SIZE(rtw8821a_rfe_defs), - .rx_ldpc = false, - .hw_feature_report = false, - .c2h_ra_report_size = 4, - .old_datarate_fb_limit = true, - .usb_tx_agg_desc_num = 6, .iqk_threshold = 8, - .ampdu_density = IEEE80211_HT_MPDU_DENSITY_16, .max_scan_ie_len = IEEE80211_MAX_DATA_LEN, .coex_para_ver = 20190509, /* glcoex_ver_date_8821a_1ant */ diff --git a/rtw8821c.c b/rtw8821c.c index 9e4be8f4..c80cd4d1 100644 --- a/rtw8821c.c +++ b/rtw8821c.c @@ -1963,26 +1963,29 @@ const struct rtw_chip_info rtw8821c_hw_spec = { .txff_size = 65536, .rxff_size = 16384, .rsvd_drv_pg_num = 8, - .txgi_factor = 1, - .is_pwr_by_rate_dec = true, - .max_power_index = 0x3f, - .csi_buf_pg_num = 0, .band = RTW_BAND_2G | RTW_BAND_5G, .page_size = TX_PAGE_SIZE, + .csi_buf_pg_num = 0, .dig_min = 0x1c, + .txgi_factor = 1, + .is_pwr_by_rate_dec = true, + .rx_ldpc = false, + .max_power_index = 0x3f, + .ampdu_density = IEEE80211_HT_MPDU_DENSITY_2, .usb_tx_agg_desc_num = 3, .hw_feature_report = true, .c2h_ra_report_size = 7, .old_datarate_fb_limit = false, + .tx_report_sn = true, .ht_supported = true, .vht_supported = true, .lps_deep_mode_supported = BIT(LPS_DEEP_MODE_LCLK), .sys_func_en = 0xD8, .pwr_on_seq = card_enable_flow_8821c, .pwr_off_seq = card_disable_flow_8821c, - .page_table = page_table_8821c, .rqpn_table = rqpn_table_8821c, .prioq_addrs = &prioq_addrs_8821c, + .page_table = page_table_8821c, .intf_table = &phy_para_table_8821c, .dig = rtw8821c_dig, .rf_base_addr = {0x2800, 0x2c00}, @@ -1994,11 +1997,9 @@ const struct rtw_chip_info rtw8821c_hw_spec = { .rf_tbl = {&rtw8821c_rf_a_tbl}, .rfe_defs = rtw8821c_rfe_defs, .rfe_defs_size = ARRAY_SIZE(rtw8821c_rfe_defs), - .rx_ldpc = false, .iqk_threshold = 8, .bfer_su_max_num = 2, .bfer_mu_max_num = 1, - .ampdu_density = IEEE80211_HT_MPDU_DENSITY_2, .max_scan_ie_len = IEEE80211_MAX_DATA_LEN, .coex_para_ver = 0x19092746, diff --git a/rtw8822b.c b/rtw8822b.c index 739809f4..6da884c4 100644 --- a/rtw8822b.c +++ b/rtw8822b.c @@ -2503,26 +2503,30 @@ const struct rtw_chip_info rtw8822b_hw_spec = { .rxff_size = 24576, .fw_rxff_size = 12288, .rsvd_drv_pg_num = 8, - .txgi_factor = 1, - .is_pwr_by_rate_dec = true, - .max_power_index = 0x3f, - .csi_buf_pg_num = 0, .band = RTW_BAND_2G | RTW_BAND_5G, .page_size = TX_PAGE_SIZE, + .csi_buf_pg_num = 0, .dig_min = 0x1c, + .txgi_factor = 1, + .is_pwr_by_rate_dec = true, + .rx_ldpc = true, + .max_power_index = 0x3f, + .ampdu_density = IEEE80211_HT_MPDU_DENSITY_2, + .fw_fifo_addr = {0x780, 0x700, 0x780, 0x660, 0x650, 0x680}, .usb_tx_agg_desc_num = 3, .hw_feature_report = true, .c2h_ra_report_size = 7, .old_datarate_fb_limit = false, + .tx_report_sn = true, .ht_supported = true, .vht_supported = true, .lps_deep_mode_supported = BIT(LPS_DEEP_MODE_LCLK), .sys_func_en = 0xDC, .pwr_on_seq = card_enable_flow_8822b, .pwr_off_seq = card_disable_flow_8822b, - .page_table = page_table_8822b, .rqpn_table = rqpn_table_8822b, .prioq_addrs = &prioq_addrs_8822b, + .page_table = page_table_8822b, .intf_table = &phy_para_table_8822b, .dig = rtw8822b_dig, .dig_cck = NULL, @@ -2538,11 +2542,9 @@ const struct rtw_chip_info rtw8822b_hw_spec = { .iqk_threshold = 8, .bfer_su_max_num = 2, .bfer_mu_max_num = 1, - .rx_ldpc = true, .edcca_th = rtw8822b_edcca_th, .l2h_th_ini_cs = 10 + EDCCA_IGI_BASE, .l2h_th_ini_ad = -14 + EDCCA_IGI_BASE, - .ampdu_density = IEEE80211_HT_MPDU_DENSITY_2, .max_scan_ie_len = IEEE80211_MAX_DATA_LEN, .coex_para_ver = 0x20070206, @@ -2576,7 +2578,6 @@ const struct rtw_chip_info rtw8822b_hw_spec = { .coex_info_hw_regs_num = ARRAY_SIZE(coex_info_hw_regs_8822b), .coex_info_hw_regs = coex_info_hw_regs_8822b, - .fw_fifo_addr = {0x780, 0x700, 0x780, 0x660, 0x650, 0x680}, }; EXPORT_SYMBOL(rtw8822b_hw_spec); diff --git a/rtw8822c.c b/rtw8822c.c index af6b7693..21be6433 100644 --- a/rtw8822c.c +++ b/rtw8822c.c @@ -5323,17 +5323,23 @@ const struct rtw_chip_info rtw8822c_hw_spec = { .rxff_size = 24576, .fw_rxff_size = 12288, .rsvd_drv_pg_num = 16, - .txgi_factor = 2, - .is_pwr_by_rate_dec = false, - .max_power_index = 0x7f, - .csi_buf_pg_num = 50, .band = RTW_BAND_2G | RTW_BAND_5G, .page_size = TX_PAGE_SIZE, + .csi_buf_pg_num = 50, .dig_min = 0x20, + .txgi_factor = 2, + .is_pwr_by_rate_dec = false, + .rx_ldpc = true, + .tx_stbc = true, + .max_power_index = 0x7f, + .ampdu_density = IEEE80211_HT_MPDU_DENSITY_2, + .fw_fifo_addr = {0x780, 0x700, 0x780, 0x660, 0x650, 0x680}, + .fwcd_segs = &rtw8822c_fwcd_segs, .usb_tx_agg_desc_num = 3, .hw_feature_report = true, .c2h_ra_report_size = 7, .old_datarate_fb_limit = false, + .tx_report_sn = true, .default_1ss_tx_path = BB_PATH_A, .path_div_supported = true, .ht_supported = true, @@ -5342,9 +5348,9 @@ const struct rtw_chip_info rtw8822c_hw_spec = { .sys_func_en = 0xD8, .pwr_on_seq = card_enable_flow_8822c, .pwr_off_seq = card_disable_flow_8822c, - .page_table = page_table_8822c, .rqpn_table = rqpn_table_8822c, .prioq_addrs = &prioq_addrs_8822c, + .page_table = page_table_8822c, .intf_table = &phy_para_table_8822c, .dig = rtw8822c_dig, .dig_cck = NULL, @@ -5354,8 +5360,8 @@ const struct rtw_chip_info rtw8822c_hw_spec = { .mac_tbl = &rtw8822c_mac_tbl, .agc_tbl = &rtw8822c_agc_tbl, .bb_tbl = &rtw8822c_bb_tbl, - .rfk_init_tbl = &rtw8822c_array_mp_cal_init_tbl, .rf_tbl = {&rtw8822c_rf_b_tbl, &rtw8822c_rf_a_tbl}, + .rfk_init_tbl = &rtw8822c_array_mp_cal_init_tbl, .rfe_defs = rtw8822c_rfe_defs, .rfe_defs_size = ARRAY_SIZE(rtw8822c_rfe_defs), .en_dis_dpd = true, @@ -5364,12 +5370,9 @@ const struct rtw_chip_info rtw8822c_hw_spec = { .lck_threshold = 8, .bfer_su_max_num = 2, .bfer_mu_max_num = 1, - .rx_ldpc = true, - .tx_stbc = true, .edcca_th = rtw8822c_edcca_th, .l2h_th_ini_cs = 60, .l2h_th_ini_ad = 45, - .ampdu_density = IEEE80211_HT_MPDU_DENSITY_2, #ifdef CONFIG_PM .wow_fw_name = "rtw88/rtw8822c_wow_fw.bin", @@ -5408,8 +5411,6 @@ const struct rtw_chip_info rtw8822c_hw_spec = { .coex_info_hw_regs_num = ARRAY_SIZE(coex_info_hw_regs_8822c), .coex_info_hw_regs = coex_info_hw_regs_8822c, - .fw_fifo_addr = {0x780, 0x700, 0x780, 0x660, 0x650, 0x680}, - .fwcd_segs = &rtw8822c_fwcd_segs, }; EXPORT_SYMBOL(rtw8822c_hw_spec); diff --git a/tx.c b/tx.c index a5adcd60..a56c06e0 100644 --- a/tx.c +++ b/tx.c @@ -271,7 +271,7 @@ void rtw_tx_report_handle(struct rtw_dev *rtwdev, struct sk_buff *skb, int src) spin_lock_irqsave(&tx_report->q_lock, flags); skb_queue_walk_safe(&tx_report->queue, cur, tmp) { n = (u8 *)IEEE80211_SKB_CB(cur)->status.status_driver_data; - if (*n == sn) { + if (*n == sn || !rtwdev->chip->tx_report_sn) { __skb_unlink(cur, &tx_report->queue); rtw_tx_report_tx_status(rtwdev, cur, st == 0); break; From 2d2c2417b6b4fc0e5f7dfbc742b36cd29b356a62 Mon Sep 17 00:00:00 2001 From: Bitterblue Smith Date: Sat, 16 Nov 2024 01:40:48 +0200 Subject: [PATCH 059/193] 8812au, 8821au: Disable hardware-controlled LED blinking The next patch brings software-controlled blinking. Signed-off-by: Bitterblue Smith --- rtw88xxa.c | 6 ------ 1 file changed, 6 deletions(-) diff --git a/rtw88xxa.c b/rtw88xxa.c index f1162559..71e61b9c 100644 --- a/rtw88xxa.c +++ b/rtw88xxa.c @@ -1174,12 +1174,6 @@ int rtw88xxa_power_on(struct rtw_dev *rtwdev) rtw_write8_set(rtwdev, REG_CR, BIT_MACTXEN | BIT_MACRXEN); - ///TODO: blinking controlled by mac80211 - if (rtwdev->chip->id == RTW_CHIP_TYPE_8821A) - rtw_write8(rtwdev, REG_LED_CFG + 2, BIT(1) | BIT(5)); - else - rtw_write8(rtwdev, REG_LED_CFG, BIT(1) | BIT(5)); - rtw88xxa_phy_bb_config(rtwdev); rtw88xxa_phy_rf_config(rtwdev); From ce76fa323d563f047f65aad75362e0c40dae1a6d Mon Sep 17 00:00:00 2001 From: Bitterblue Smith Date: Sat, 16 Nov 2024 01:36:42 +0200 Subject: [PATCH 060/193] wifi: rtw88: Add support for LED blinking Register a struct led_classdev with the kernel's LED subsystem and create a throughput-based trigger for it. Then mac80211 makes the LED blink. Tested with Tenda U12 (RTL8812AU), Tenda U9 (RTL8811CU), TP-Link Archer T2U Nano (RTL8811AU), TP-Link Archer T3U Plus (RTL8812BU), Edimax EW-7611UCB (RTL8821AU), LM842 (RTL8822CU). Also tested with devices which don't have LEDs: the laptop's internal RTL8822CE and a no-name RTL8723DU. Signed-off-by: Bitterblue Smith --- main.c | 91 ++++++++++++++++++++++++++++++++++++++++++++++++++++-- main.h | 9 ++++++ reg.h | 12 +++++++ rtw8812a.c | 23 ++++++++++++++ rtw8821a.c | 32 +++++++++++++++++++ rtw8821c.c | 25 +++++++++++++++ rtw8822b.c | 25 +++++++++++++++ rtw8822c.c | 25 +++++++++++++++ 8 files changed, 240 insertions(+), 2 deletions(-) diff --git a/main.c b/main.c index eb3b42a9..fdab0a1a 100644 --- a/main.c +++ b/main.c @@ -2344,6 +2344,86 @@ void rtw_core_deinit(struct rtw_dev *rtwdev) } EXPORT_SYMBOL(rtw_core_deinit); +#ifdef CONFIG_LEDS_CLASS + +static int rtw_led_set_blocking(struct led_classdev *led, + enum led_brightness brightness) +{ + struct rtw_dev *rtwdev = container_of(led, struct rtw_dev, led_cdev); + + rtwdev->chip->ops->led_set(led, brightness); + + return 0; +} + +static void rtw_led_init(struct rtw_dev *rtwdev) +{ + static const struct ieee80211_tpt_blink rtw_tpt_blink[] = { + { .throughput = 0 * 1024, .blink_time = 334 }, + { .throughput = 1 * 1024, .blink_time = 260 }, + { .throughput = 5 * 1024, .blink_time = 220 }, + { .throughput = 10 * 1024, .blink_time = 190 }, + { .throughput = 20 * 1024, .blink_time = 170 }, + { .throughput = 50 * 1024, .blink_time = 150 }, + { .throughput = 70 * 1024, .blink_time = 130 }, + { .throughput = 100 * 1024, .blink_time = 110 }, + { .throughput = 200 * 1024, .blink_time = 80 }, + { .throughput = 300 * 1024, .blink_time = 50 }, + }; + struct led_classdev *led = &rtwdev->led_cdev; + int err; + + if (!rtwdev->chip->ops->led_set) + return; + + if (rtw_hci_type(rtwdev) == RTW_HCI_TYPE_USB) + led->brightness_set_blocking = rtw_led_set_blocking; + else + led->brightness_set = rtwdev->chip->ops->led_set; + + snprintf(rtwdev->led_name, sizeof(rtwdev->led_name), + "rtw88-%s", dev_name(rtwdev->dev)); + + led->name = rtwdev->led_name; + led->max_brightness = LED_ON; + led->default_trigger = + ieee80211_create_tpt_led_trigger(rtwdev->hw, + IEEE80211_TPT_LEDTRIG_FL_RADIO, + rtw_tpt_blink, + ARRAY_SIZE(rtw_tpt_blink)); + + err = led_classdev_register(rtwdev->dev, led); + if (err) { + rtw_warn(rtwdev, "Failed to register the LED, error %d\n", err); + return; + } + + rtwdev->led_registered = true; +} + +static void rtw_led_deinit(struct rtw_dev *rtwdev) +{ + struct led_classdev *led = &rtwdev->led_cdev; + + if (!rtwdev->led_registered) + return; + + rtwdev->chip->ops->led_set(led, LED_OFF); + led_classdev_unregister(led); +} + +#else + +static void rtw_led_init(struct rtw_dev *rtwdev) +{ +} + +static void rtw_led_deinit(struct rtw_dev *rtwdev) +{ +} + +#endif + int rtw_register_hw(struct rtw_dev *rtwdev, struct ieee80211_hw *hw) { bool sta_mode_only = rtwdev->hci.type == RTW_HCI_TYPE_SDIO; @@ -2419,16 +2499,18 @@ int rtw_register_hw(struct rtw_dev *rtwdev, struct ieee80211_hw *hw) return ret; } + rtw_led_init(rtwdev); + ret = ieee80211_register_hw(hw); if (ret) { rtw_err(rtwdev, "failed to register hw\n"); - return ret; + goto led_deinit; } ret = rtw_regd_hint(rtwdev); if (ret) { rtw_err(rtwdev, "failed to hint regd\n"); - return ret; + goto led_deinit; } rtw_debugfs_init(rtwdev); @@ -2437,6 +2519,10 @@ int rtw_register_hw(struct rtw_dev *rtwdev, struct ieee80211_hw *hw) rtwdev->bf_info.bfer_su_cnt = 0; return 0; + +led_deinit: + rtw_led_deinit(rtwdev); + return ret; } EXPORT_SYMBOL(rtw_register_hw); @@ -2447,6 +2533,7 @@ void rtw_unregister_hw(struct rtw_dev *rtwdev, struct ieee80211_hw *hw) ieee80211_unregister_hw(hw); rtw_unset_supported_band(hw, chip); rtw_debugfs_deinit(rtwdev); + rtw_led_deinit(rtwdev); } EXPORT_SYMBOL(rtw_unregister_hw); diff --git a/main.h b/main.h index 11598e42..2f6de491 100644 --- a/main.h +++ b/main.h @@ -1022,6 +1022,9 @@ struct rtw_chip_ops { bool is_tx2_path); void (*config_txrx_mode)(struct rtw_dev *rtwdev, u8 tx_path, u8 rx_path, bool is_tx2_path); +#ifdef CONFIG_LEDS_CLASS + void (*led_set)(struct led_classdev *led, enum led_brightness brightness); +#endif /* for USB/SDIO only */ void (*fill_txdesc_checksum)(struct rtw_dev *rtwdev, struct rtw_tx_pkt_info *pkt_info, @@ -2234,6 +2237,12 @@ struct rtw_dev { struct completion fw_scan_density; bool ap_active; +#ifdef CONFIG_MAC80211_LEDS + bool led_registered; + char led_name[32]; + struct led_classdev led_cdev; +#endif + /* hci related data, must be last */ u8 priv[] __aligned(sizeof(void *)); }; diff --git a/reg.h b/reg.h index e4d506cf..3edea4e7 100644 --- a/reg.h +++ b/reg.h @@ -78,7 +78,19 @@ #define BIT_PAPE_SEL_EN BIT(25) #define BIT_DPDT_WL_SEL BIT(24) #define BIT_DPDT_SEL_EN BIT(23) +#define BIT_GPIO13_14_WL_CTRL_EN BIT(22) +#define BIT_LED2_SV BIT(19) +#define BIT_LED2_CM GENMASK(18, 16) +#define BIT_LED1_SV BIT(11) +#define BIT_LED1_CM GENMASK(10, 8) +#define BIT_LED0_SV BIT(3) +#define BIT_LED0_CM GENMASK(2, 0) +#define BIT_LED_MODE_SW_CTRL 0 +#define BIT_LED_MODE_RX 6 +#define BIT_LED_MODE_TX 4 +#define BIT_LED_MODE_TRX 2 #define REG_LEDCFG2 0x004E +#define REG_GPIO_PIN_CTRL_2 0x0060 #define REG_PAD_CTRL1 0x0064 #define BIT_BT_BTG_SEL BIT(31) #define BIT_PAPE_WLBT_SEL BIT(29) diff --git a/rtw8812a.c b/rtw8812a.c index 9d98117b..dc019481 100644 --- a/rtw8812a.c +++ b/rtw8812a.c @@ -868,6 +868,26 @@ static void rtw8812a_pwr_track(struct rtw_dev *rtwdev) dm_info->pwr_trk_triggered = false; } +#ifdef CONFIG_LEDS_CLASS + +static void rtw8812a_led_set(struct led_classdev *led, + enum led_brightness brightness) +{ + struct rtw_dev *rtwdev = container_of(led, struct rtw_dev, led_cdev); + u8 ledcfg; + + ledcfg = rtw_read8(rtwdev, REG_LED_CFG); + ledcfg &= BIT(6) | BIT(4); + ledcfg |= BIT(5); + + if (brightness == LED_OFF) + ledcfg |= BIT(3); + + rtw_write8(rtwdev, REG_LED_CFG, ledcfg); +} + +#endif + static void rtw8812a_fill_txdesc_checksum(struct rtw_dev *rtwdev, struct rtw_tx_pkt_info *pkt_info, u8 *txdesc) @@ -916,6 +936,9 @@ static const struct rtw_chip_ops rtw8812a_ops = { .config_bfee = NULL, .set_gid_table = NULL, .cfg_csi_rate = NULL, +#ifdef CONFIG_LEDS_CLASS + .led_set = rtw8812a_led_set, +#endif .fill_txdesc_checksum = rtw8812a_fill_txdesc_checksum, .coex_set_init = rtw8812a_coex_cfg_init, .coex_set_ant_switch = NULL, diff --git a/rtw8821a.c b/rtw8821a.c index 2917478e..794e811e 100644 --- a/rtw8821a.c +++ b/rtw8821a.c @@ -706,6 +706,35 @@ static void rtw8821a_pwr_track(struct rtw_dev *rtwdev) dm_info->pwr_trk_triggered = false; } +#ifdef CONFIG_LEDS_CLASS + +static void rtw8821a_led_set(struct led_classdev *led, + enum led_brightness brightness) +{ + struct rtw_dev *rtwdev = container_of(led, struct rtw_dev, led_cdev); + u32 gpio8_cfg; + u8 ledcfg; + + if (brightness == LED_OFF) { + gpio8_cfg = rtw_read32(rtwdev, REG_GPIO_PIN_CTRL_2); + gpio8_cfg &= ~BIT(24); + gpio8_cfg |= BIT(16) | BIT(8); + rtw_write32(rtwdev, REG_GPIO_PIN_CTRL_2, gpio8_cfg); + } else { + ledcfg = rtw_read8(rtwdev, REG_LED_CFG + 2); + gpio8_cfg = rtw_read32(rtwdev, REG_GPIO_PIN_CTRL_2); + + ledcfg &= BIT(7) | BIT(6); + rtw_write8(rtwdev, REG_LED_CFG + 2, ledcfg); + + gpio8_cfg &= ~(BIT(24) | BIT(8)); + gpio8_cfg |= BIT(16); + rtw_write32(rtwdev, REG_GPIO_PIN_CTRL_2, gpio8_cfg); + } +} + +#endif + static void rtw8821a_fill_txdesc_checksum(struct rtw_dev *rtwdev, struct rtw_tx_pkt_info *pkt_info, u8 *txdesc) @@ -853,6 +882,9 @@ static const struct rtw_chip_ops rtw8821a_ops = { .config_bfee = NULL, .set_gid_table = NULL, .cfg_csi_rate = NULL, +#ifdef CONFIG_LEDS_CLASS + .led_set = rtw8821a_led_set, +#endif .fill_txdesc_checksum = rtw8821a_fill_txdesc_checksum, .coex_set_init = rtw8821a_coex_cfg_init, .coex_set_ant_switch = rtw8821a_coex_cfg_ant_switch, diff --git a/rtw8821c.c b/rtw8821c.c index c80cd4d1..b80f61bd 100644 --- a/rtw8821c.c +++ b/rtw8821c.c @@ -1207,6 +1207,28 @@ static void rtw8821c_phy_cck_pd_set(struct rtw_dev *rtwdev, u8 new_lvl) dm_info->cck_pd_default + new_lvl * 2); } +#ifdef CONFIG_LEDS_CLASS + +static void rtw8821c_led_set(struct led_classdev *led, + enum led_brightness brightness) +{ + struct rtw_dev *rtwdev = container_of(led, struct rtw_dev, led_cdev); + u32 ledcfg; + + ledcfg = rtw_read32(rtwdev, REG_LED_CFG); + u32p_replace_bits(&ledcfg, BIT_LED_MODE_SW_CTRL, BIT_LED2_CM); + ledcfg &= ~BIT_GPIO13_14_WL_CTRL_EN; + + if (brightness == LED_OFF) + ledcfg |= BIT_LED2_SV; + else + ledcfg &= ~BIT_LED2_SV; + + rtw_write32(rtwdev, REG_LED_CFG, ledcfg); +} + +#endif + static void rtw8821c_fill_txdesc_checksum(struct rtw_dev *rtwdev, struct rtw_tx_pkt_info *pkt_info, u8 *txdesc) @@ -1656,6 +1678,9 @@ static const struct rtw_chip_ops rtw8821c_ops = { .config_bfee = rtw8821c_bf_config_bfee, .set_gid_table = rtw_bf_set_gid_table, .cfg_csi_rate = rtw_bf_cfg_csi_rate, +#ifdef CONFIG_LEDS_CLASS + .led_set = rtw8821c_led_set, +#endif .fill_txdesc_checksum = rtw8821c_fill_txdesc_checksum, .coex_set_init = rtw8821c_coex_cfg_init, diff --git a/rtw8822b.c b/rtw8822b.c index 6da884c4..65c117ff 100644 --- a/rtw8822b.c +++ b/rtw8822b.c @@ -1566,6 +1566,28 @@ static void rtw8822b_adaptivity(struct rtw_dev *rtwdev) rtw_phy_set_edcca_th(rtwdev, l2h, h2l); } +#ifdef CONFIG_LEDS_CLASS + +static void rtw8822b_led_set(struct led_classdev *led, + enum led_brightness brightness) +{ + struct rtw_dev *rtwdev = container_of(led, struct rtw_dev, led_cdev); + u32 ledcfg; + + ledcfg = rtw_read32(rtwdev, REG_LED_CFG); + u32p_replace_bits(&ledcfg, BIT_LED_MODE_SW_CTRL, BIT_LED2_CM); + ledcfg &= ~BIT_GPIO13_14_WL_CTRL_EN; + + if (brightness == LED_OFF) + ledcfg |= BIT_LED2_SV; + else + ledcfg &= ~BIT_LED2_SV; + + rtw_write32(rtwdev, REG_LED_CFG, ledcfg); +} + +#endif + static void rtw8822b_fill_txdesc_checksum(struct rtw_dev *rtwdev, struct rtw_tx_pkt_info *pkt_info, u8 *txdesc) @@ -2146,6 +2168,9 @@ static const struct rtw_chip_ops rtw8822b_ops = { .cfg_csi_rate = rtw_bf_cfg_csi_rate, .adaptivity_init = rtw8822b_adaptivity_init, .adaptivity = rtw8822b_adaptivity, +#ifdef CONFIG_LEDS_CLASS + .led_set = rtw8822b_led_set, +#endif .fill_txdesc_checksum = rtw8822b_fill_txdesc_checksum, .coex_set_init = rtw8822b_coex_cfg_init, diff --git a/rtw8822c.c b/rtw8822c.c index 21be6433..545b91fe 100644 --- a/rtw8822c.c +++ b/rtw8822c.c @@ -4537,6 +4537,28 @@ static void rtw8822c_adaptivity(struct rtw_dev *rtwdev) rtw_phy_set_edcca_th(rtwdev, l2h, h2l); } +#ifdef CONFIG_LEDS_CLASS + +static void rtw8822c_led_set(struct led_classdev *led, + enum led_brightness brightness) +{ + struct rtw_dev *rtwdev = container_of(led, struct rtw_dev, led_cdev); + u32 ledcfg; + + ledcfg = rtw_read32(rtwdev, REG_LED_CFG); + u32p_replace_bits(&ledcfg, BIT_LED_MODE_SW_CTRL, BIT_LED2_CM); + ledcfg &= ~BIT_GPIO13_14_WL_CTRL_EN; + + if (brightness == LED_OFF) + ledcfg |= BIT_LED2_SV; + else + ledcfg &= ~BIT_LED2_SV; + + rtw_write32(rtwdev, REG_LED_CFG, ledcfg); +} + +#endif + static void rtw8822c_fill_txdesc_checksum(struct rtw_dev *rtwdev, struct rtw_tx_pkt_info *pkt_info, u8 *txdesc) @@ -4964,6 +4986,9 @@ static const struct rtw_chip_ops rtw8822c_ops = { .cfo_track = rtw8822c_cfo_track, .config_tx_path = rtw8822c_config_tx_path, .config_txrx_mode = rtw8822c_config_trx_mode, +#ifdef CONFIG_LEDS_CLASS + .led_set = rtw8822c_led_set, +#endif .fill_txdesc_checksum = rtw8822c_fill_txdesc_checksum, .coex_set_init = rtw8822c_coex_cfg_init, From beee28a47d6e27ff2996e311852f6d480fcd8cfe Mon Sep 17 00:00:00 2001 From: Zenm Chen Date: Sun, 17 Nov 2024 05:07:27 +0800 Subject: [PATCH 061/193] rtw88: Fix builds for kernels older than 5.14.0 --- main.h | 3 +++ 1 file changed, 3 insertions(+) diff --git a/main.h b/main.h index 2f6de491..37203f1d 100644 --- a/main.h +++ b/main.h @@ -27,6 +27,9 @@ #if LINUX_VERSION_CODE < KERNEL_VERSION(4, 8, 0) #include #endif +#if LINUX_VERSION_CODE < KERNEL_VERSION(5, 14, 0) +#include +#endif #if !defined(RHEL_RELEASE_CODE) #define RHEL_RELEASE_CODE 0 From ec2cee960ab7f6da916a2bca1b758a0c77da2670 Mon Sep 17 00:00:00 2001 From: Bitterblue Smith Date: Sat, 23 Nov 2024 00:22:20 +0200 Subject: [PATCH 062/193] Use #ifdef CONFIG_LEDS_CLASS instead of CONFIG_MAC80211_LEDS It was a mistake. Signed-off-by: Bitterblue Smith --- main.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/main.h b/main.h index 37203f1d..5d7120bd 100644 --- a/main.h +++ b/main.h @@ -2240,7 +2240,7 @@ struct rtw_dev { struct completion fw_scan_density; bool ap_active; -#ifdef CONFIG_MAC80211_LEDS +#ifdef CONFIG_LEDS_CLASS bool led_registered; char led_name[32]; struct led_classdev led_cdev; From 611874c62b1cf5ff487885284c369080857e8f9e Mon Sep 17 00:00:00 2001 From: morrownr <69053122+morrownr@users.noreply.github.com> Date: Tue, 26 Nov 2024 13:54:05 -0600 Subject: [PATCH 063/193] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 3a693ea7..dc6328ae 100644 --- a/README.md +++ b/README.md @@ -13,7 +13,7 @@ Compatible with **Linux kernel versions 5.4 and newer** as long as your distro h #### Supported Chipsets -- **USB** : RTW8812AU, RTW8821AU, RTW8811AU, RTW8822BU, RTW8812BU, RTW8822CU, RTW8821CU, RTW8811CU, RTW8723DU +- **USB** : RTW8812AU, RTW8821AU, RTW8811AU, RTW8822BU, RTW8812BU, RTW8822CU, RTW8812CU, RTW8821CU, RTW8811CU, RTW8723DU - **PCIe**: RTW8822BE, RTW8822CE, RTW8821CE, RTW8723DE - **SDIO**: RTW8822BS, RTW8822CS, RTW8821CS, RTW8723DS From 1c22482e9d62b52a57e48b7811c5e950c4697932 Mon Sep 17 00:00:00 2001 From: Bitterblue Smith Date: Tue, 10 Dec 2024 13:59:26 +0200 Subject: [PATCH 064/193] Fix compilation for Openwrt CC [M] /media/Standard/openwrt/openwrt-sdk-24.10.0-rc2-mediatek-filogic_gcc-13.3.0_musl.Linux-x86_64/build_dir/target-aarch64_cortex-a53_musl/linux-mediatek_filogic/rtw88-usb-2024.11.27~611874c6/usb.o /media/Standard/openwrt/openwrt-sdk-24.10.0-rc2-mediatek-filogic_gcc-13.3.0_musl.Linux-x86_64/build_dir/target-aarch64_cortex-a53_musl/linux-mediatek_filogic/rtw88-usb-2024.11.27~611874c6/usb.c: In function 'rtw_usb_init_rx': /media/Standard/openwrt/openwrt-sdk-24.10.0-rc2-mediatek-filogic_gcc-13.3.0_musl.Linux-x86_64/build_dir/target-aarch64_cortex-a53_musl/linux-mediatek_filogic/rtw88-usb-2024.11.27~611874c6/usb.c:943:22: error: cast between incompatible function types from 'void (*)(struct rtw_usb *)' to 'void (*)(long unsigned int)' [-Werror=cast-function-type] 943 | (void(*)(unsigned long))rtw_usb_rx_handler, | ^ cc1: all warnings being treated as errors Fixes https://github.com/lwfinger/rtw88/issues/253. Signed-off-by: Bitterblue Smith --- usb.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/usb.c b/usb.c index 9dafc75f..64c8a75c 100644 --- a/usb.c +++ b/usb.c @@ -554,8 +554,9 @@ static void rtw_usb_rx_handler(struct work_struct *work) { struct rtw_usb *rtwusb = container_of(work, struct rtw_usb, rx_work); #else -static void rtw_usb_rx_handler(struct rtw_usb *rtwusb) +static void rtw_usb_rx_handler(unsigned long shut_up_gcc) { + struct rtw_usb *rtwusb = (struct rtw_usb *)shut_up_gcc; #endif struct rtw_dev *rtwdev = rtwusb->rtwdev; const struct rtw_chip_info *chip = rtwdev->chip; @@ -939,8 +940,7 @@ static int rtw_usb_init_rx(struct rtw_dev *rtwdev) #if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 9, 0) rtwusb->rxwq = alloc_workqueue("rtw88_usb: rx wq", WQ_BH, 0); #else - tasklet_init(&rtwusb->rx_tasklet, - (void(*)(unsigned long))rtw_usb_rx_handler, + tasklet_init(&rtwusb->rx_tasklet, rtw_usb_rx_handler, (unsigned long)rtwusb); rtwusb->rxwq = create_singlethread_workqueue("rtw88_usb: rx wq"); From 74fe9b7f6913ea0e8f235826a1680012002c810c Mon Sep 17 00:00:00 2001 From: Bitterblue Smith Date: Tue, 10 Dec 2024 14:01:59 +0200 Subject: [PATCH 065/193] wifi: rtw88: Add USB PHY configuration Add some extra configuration for some versions of some chips. Currently only RTL8822BU version D-cut uses this. A user reported that some RTL8822BU was stuck in a loop disconnecting and reconnecting to USB. This patch fixes that. Fixes https://github.com/lwfinger/rtw88/issues/262. Signed-off-by: Bitterblue Smith --- usb.c | 67 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 67 insertions(+) diff --git a/usb.c b/usb.c index 64c8a75c..5b251093 100644 --- a/usb.c +++ b/usb.c @@ -1160,6 +1160,70 @@ static int rtw_usb_switch_mode(struct rtw_dev *rtwdev) return rtw_usb_switch_mode_new(rtwdev); } +#define USB_REG_PAGE 0xf4 +#define USB_PHY_PAGE0 0x9b +#define USB_PHY_PAGE1 0xbb + +static void rtw_usb_phy_write(struct rtw_dev *rtwdev, u16 addr, u16 data, + enum usb_device_speed speed) +{ + if (speed == USB_SPEED_SUPER) { + rtw_write8(rtwdev, 0xff0d, (u8)data); + rtw_write8(rtwdev, 0xff0e, (u8)(data >> 8)); + rtw_write8(rtwdev, 0xff0c, addr | BIT(7)); + } else if (speed == USB_SPEED_HIGH) { + rtw_write8(rtwdev, 0xfe41, (u8)data); + rtw_write8(rtwdev, 0xfe40, addr); + rtw_write8(rtwdev, 0xfe42, 0x81); + } +} + +static void rtw_usb_page_switch(struct rtw_dev *rtwdev, + enum usb_device_speed speed, u8 page) +{ + if (speed == USB_SPEED_SUPER) + return; + + rtw_usb_phy_write(rtwdev, USB_REG_PAGE, page, speed); +} + +static void rtw_usb_phy_cfg(struct rtw_dev *rtwdev, + enum usb_device_speed speed) +{ + const struct rtw_intf_phy_para *para = NULL; + u16 cut, offset; + + if (speed == USB_SPEED_SUPER) + para = rtwdev->chip->intf_table->usb3_para; + else if (speed == USB_SPEED_HIGH) + para = rtwdev->chip->intf_table->usb2_para; + + if (!para) + return; + + cut = BIT(0) << rtwdev->hal.cut_version; + + for ( ; para->offset != 0xffff; para++) { + if (!(para->cut_mask & cut)) + continue; + + offset = para->offset; + + if (para->ip_sel == RTW_IP_SEL_MAC) { + rtw_write8(rtwdev, offset, para->value); + } else { + if (offset > 0x100) + rtw_usb_page_switch(rtwdev, speed, USB_PHY_PAGE1); + else + rtw_usb_page_switch(rtwdev, speed, USB_PHY_PAGE0); + + offset &= 0xff; + + rtw_usb_phy_write(rtwdev, offset, para->value, speed); + } + } +} + int rtw_usb_probe(struct usb_interface *intf, const struct usb_device_id *id) { struct rtw_dev *rtwdev; @@ -1215,6 +1279,9 @@ int rtw_usb_probe(struct usb_interface *intf, const struct usb_device_id *id) goto err_destroy_rxwq; } + rtw_usb_phy_cfg(rtwdev, USB_SPEED_HIGH); + rtw_usb_phy_cfg(rtwdev, USB_SPEED_SUPER); + ret = rtw_usb_switch_mode(rtwdev); if (ret) { /* Not a fail, but we do need to skip rtw_register_hw. */ From cea0000d58b2eaaea7babeb1c4f614783ec8abff Mon Sep 17 00:00:00 2001 From: Bitterblue Smith Date: Tue, 10 Dec 2024 14:05:02 +0200 Subject: [PATCH 066/193] wifi: rtw88: Enable concurrent mode for all chips Theoretically all the chips support 1 AP + 1 STA interface combination. Enable it for testing. Signed-off-by: Bitterblue Smith --- main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/main.c b/main.c index fdab0a1a..ae645d03 100644 --- a/main.c +++ b/main.c @@ -2473,7 +2473,7 @@ int rtw_register_hw(struct rtw_dev *rtwdev, struct ieee80211_hw *hw) hw->wiphy->max_scan_ssids = RTW_SCAN_MAX_SSIDS; hw->wiphy->max_scan_ie_len = rtw_get_max_scan_ie_len(rtwdev); - if (!sta_mode_only && rtwdev->chip->id == RTW_CHIP_TYPE_8822C) { + if (!sta_mode_only) { hw->wiphy->iface_combinations = rtw_iface_combs; hw->wiphy->n_iface_combinations = ARRAY_SIZE(rtw_iface_combs); } From 4da3263ac20e4946798730db545df67b5e4a36bc Mon Sep 17 00:00:00 2001 From: Bitterblue Smith Date: Tue, 10 Dec 2024 14:08:55 +0200 Subject: [PATCH 067/193] wifi: rtw88: 8812a: Support RFE type 2 Someone has such a device: https://github.com/lwfinger/rtw88/issues/261 Signed-off-by: Bitterblue Smith --- rtw8812a.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/rtw8812a.c b/rtw8812a.c index dc019481..6bccd442 100644 --- a/rtw8812a.c +++ b/rtw8812a.c @@ -1008,6 +1008,9 @@ static const struct rtw_rfe_def rtw8812a_rfe_defs[] = { [1] = { .phy_pg_tbl = &rtw8812a_bb_pg_tbl, .txpwr_lmt_tbl = &rtw8812a_txpwr_lmt_tbl, .pwr_track_tbl = &rtw8812a_rtw_pwr_track_tbl, }, + [2] = { .phy_pg_tbl = &rtw8812a_bb_pg_tbl, + .txpwr_lmt_tbl = &rtw8812a_txpwr_lmt_tbl, + .pwr_track_tbl = &rtw8812a_rtw_pwr_track_tbl, }, [3] = { .phy_pg_tbl = &rtw8812a_bb_pg_rfe3_tbl, .txpwr_lmt_tbl = &rtw8812a_txpwr_lmt_tbl, .pwr_track_tbl = &rtw8812a_rtw_pwr_track_rfe3_tbl, }, From a80efdcc49a77801d93bf86dd9afe5f2f3dfec4b Mon Sep 17 00:00:00 2001 From: Bitterblue Smith Date: Tue, 10 Dec 2024 14:11:20 +0200 Subject: [PATCH 068/193] wifi: rtw88: (Re)Enable all interface modes for SDIO For testing AP mode. Maybe it works better now. Signed-off-by: Bitterblue Smith --- main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/main.c b/main.c index ae645d03..15557b03 100644 --- a/main.c +++ b/main.c @@ -2426,7 +2426,7 @@ static void rtw_led_deinit(struct rtw_dev *rtwdev) int rtw_register_hw(struct rtw_dev *rtwdev, struct ieee80211_hw *hw) { - bool sta_mode_only = rtwdev->hci.type == RTW_HCI_TYPE_SDIO; + bool sta_mode_only = false; /*rtwdev->hci.type == RTW_HCI_TYPE_SDIO;*/ struct rtw_hal *hal = &rtwdev->hal; int max_tx_headroom = 0; int ret; From 07ec7fc7c58c63106aba200ea7963094857f1e1a Mon Sep 17 00:00:00 2001 From: Bitterblue Smith Date: Tue, 10 Dec 2024 14:16:22 +0200 Subject: [PATCH 069/193] Add firmware v33.6.0 for RTL8814AU Signed-off-by: Bitterblue Smith --- firmware/rtw8814a_fw.bin | Bin 0 -> 68320 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 firmware/rtw8814a_fw.bin diff --git a/firmware/rtw8814a_fw.bin b/firmware/rtw8814a_fw.bin new file mode 100644 index 0000000000000000000000000000000000000000..e14924e12f88824a2ad06e4210a47e6614004392 GIT binary patch literal 68320 zcmdqK4R}=5wKu-cd?b@(NKQh40f7ujKt6&(`0%4zhY%2w0TF^CVmToRlgyk6A%tu6 zY8}B^?F|+X1SVj|nV?oeYwvA)X>0#Z6KuIk??tq&qJ10r&@eNBArq3ew$A%o`vrIlQo}t zMga-{(*Sb-|9A`P0Q?N_5#V#czhp7b&jG&zybJgU@c06h3D^#J7VvGrUclJWS|;~FEcZfdeLCcA75ND-v;L|!p!qKz_ni?!aN$h zh4_mqkb4y3W&qOCO&OV4<`LOBVs75Zd{$gMwKzX7Cr8ZAFj*|QIimSL|7NCZDN|j* zQ~ft<)*Z8E7LA>V|2eZ}6^*x!%gMgxJ3{sIZ_y1oIr%)L>Y83OUU6w9W@b7nn5PEd z25bgw1^gpmJK!iFCkNvO(7rdTe(igY>es%TR6l*67nx@tpdIiXKmhQAG0gKG;3{B@ zg?YXL*a|oR_&MMcK>Aqbak!GO74GeTp8#@X=9vIk5BRS772M48r~KhCb`-`w1#W{o z6&`>;6}GgZ4!{n;KEQVY)1GFYdjOxPuo>TdfL8$T0(3gPj{aosW9_jOfO`S0fJXq20^;%bw;}L$ zb+yM{06Yy?gFJ;i-$a&~R(tGzq`w33AmEGK+GDRGOiV|)qic^D04Bf@guMnBiSRst z9$`8_Iv@>@1;_;a1^Ep~2mHPOF2V@bdMpo+3rGXJ0$g4O90qg%@)4E+m?#y>miTmfhU>;&uq><1hK_yDg0g6OB?fMWn=7MQ>`0xv*3 z&e-^k#|(g9x3}KMqB)F3?*aX% zl>jS10G>L49$*Bd0n!OXv;|-Q7y&wf07wG_fQJuI2O6;9TMuZ2`y|G^7T+R_RV~8e zaT~fi-ZK^MV(yPW$yn1d3m^+XtCbGl@#w=npvirJ@xbXM{O=niK<%-o@O=v36ZoFM zw-w)3d}kreji~2GfPV$t0h+Vni~7)3W~@d0D)=7;)C2awKNnC8u+kUlt$-51RKQ%o zEWoXZyA|IRz_$v(Y(07}!VUm_1^6YP2ecJMTn6xEpw(#pGk2#U+<|&F0_p&@fEvIC zKsBHTINyvkY$~7xa4X=B+GAA+uSdT%03OCaB9^9y=Ty;j9`o=Vgv@yuU-+qAb6B?? z(_2SVd^{8QHwePv0z5i+3E1Oqxx@D-g0l2f^&AMth6cKBxlk5a%Kz%0N&Bm7?g3jvPpR|Eh9yY<1@58XMdb@GNaC06T$r77+?syj7(>EB3i zWy@}#yrH#ZL;1>T)v=uoTjSXcFb645JK!B%SbvF;VZ_#r4vSrm)HLr)iwr;~#hZbMH>ET8tnz4VVmbcd3suJ&?wwOgUaDwG>B6$biyB*~oJEaXKzG zWe;0dHbqnO-r*3%n70Un;Tl{t`o7cuI4(S zps&W-ax3p{D>WW1pr3^;YH@5qQRDc$^en8eYAsv5rDcnn8N;Y#=QOB}Bk)<& z+^mc#+zU4)Jyh?e##LJp%yHP%xVW0T>#Cb;>ZvGg2(XynZRKT`SR1#xTbduaosTB+ zRh2EYZfazpgO)mkt+8U(!%6YzcD9t00Q&#IS+~!9h$kqa-)nx5i?P)_la*E7tvV1^ zb$3&BOMTLhsk0(ApuB3u`ntwin$s)SFQ++|q`|7@VNFodXi1XE*vjhFO;rEv=4xcX zioCk1wqoyti0}?#fz0v)KSM=-c(z)H2TV zswCsmJEb2%KlCrE2%3s)Pvwz}PhTw@(gh?l@>3ClPM>B}HuxoR_;d!vhi#uhXGlvk znKCl;_|41~Ek@ETDBlb*f4tR@X37*T7AxY(Up)7AV|qp=TvO-XfhY{b#GB^ZGR@|^ z(c`Vf#j~&-5KtelLHnYPbQ6>dda4#*6&EuP&&V>Hl^E{Q;>?LuW~4KTV!mbkc&pX= zU;P$O)ly#HH8UQ+X@30XTjICQT5#L!va;Jt7v4T+;q7y8FP~TbmH17!*eJYg_U&b* zUs*Wsj`H}Oi{f8h6kl{#d~rN}%YvH`h4kfLnYZZ9_~N_2dUrg&BpzRiZl@6#5szo* z$4BMFM~m?>xf3T^@(L^?Ed}vW+40d6#4!^^%f#HV1@Up#_@o=+lj8AFBXh<~%(WDZ zw2q~a!g#!hmt-&)O5*XE^MOwM=35ucx~*&>P`ypXbY@9>{!Q^)ZYE62=G?Y$-tAvm zIJf+cuPnOrjzwR+^Ol?9x87{KZT5oO%i;^a5--0aj_}2IExLR0q9u3V4QV+ZH^<{6 z^5fZ~;yI(^;uv5WACng!VUFi#bKD8jJRmjJI@UUFECr5_kC~8bnK*K6!9?r0f=M@6 z3n$&c36Fk?r%cCh!KBGIP9<;Al&Q2Spf80dzQt3gm)yi-rc9eL^Jc6FjPamSI0`8B z^yvnM35z|5g%xAxxP(b;C&cj&*a}w5TA2^KOPjD$=n+n+t~ENV{&j;b?F6$RbU=7Y zpXxt_*j^rg$2IvWUn|O}7dnt{ypH^o@`unX4i9NHDrKM2DJ7jsr~f+aK?qYb%S*vk zW>Z-yy93w~u7sn4^$C=^Q=mF(SsOzC%({m8>w!7d-)fwAO@7LE2TJ=PJB@tV0{I6} z(pvVyH6d^4l(MNTr8T`MQ2?GsmWBOyMhdR;SvI?YO=I)fy-a40vTwqtxc%ts80wjZ zm`9l(?sCB`>=ouC9mSOkuM3}|zpl;i2ZqDTh_fQ0d{{Zy8w)=|?rY0>Mt4e=pFe8U z=rLn3(Z`RUFk#|E{7x*uoS#4c7VK?qyZ!dtX;){nEm%-iws0Z27hu0ruIzZCv?s*B z#1{%_?pMFyhhV|M9{QNGZ?({OyO73JAFQc|ye%i_7ym3C{`sH!S@RQCNB=6a3gCEyoeBVi9mhyC@bh4{W-uO^~ zEJm5zcH~H3Tj*%0Eo6I#S)M`K{iB6uT{W|mjKSo!dqxKS+Cl>LDg06^{K8U$V0LJc+h&)uDTzGdxh$*g`3KyG<9&V zQQaF4dIq$-4ur2$!#5nXp&liD4cz6by9sVeA0J}{|j`HUFw>{9n7q zKXi@Xs2iUDjzm1LZ5R&HI6kOKIC}t!}X4bKFo`VegA&! z#Sh>7&=U=QIO5n74d#n8C$YLa9V}Kjo5ifN|Eqaf)av$K8NZB=MLmm}mROcp_p>_d z?^)dhhk##pk;gS4ZYiiwZtL~*>t?4-@!F;2%l6dlTUcqN(8*DLg^b($#UG zBW2cKj~;_V6F`s5vRZ9zxmQ;R>P(@`FY{#~I*QZgI-aL%uofeiR%F6>D!m_7!^^!I zrDcx;PR_2ua<5gRv_u-Mcb`v$XuUhtN-aV8DU_B;CGoIi@22t6DSScH?xpk^CVP09 zO3aExi~zbxjj2k+=&p%blZeq@6SFQ6V;B}w4cgK$FkTZ=o`^}iCT2+@COr|;HCXTc z$0FeFtVXM}7I}$6oYbP~D7C1bx0PCy8bd8oVyH#Q7@{C8hFX-2AsW(Rs70wUgtt-} z&A9C;7*PKtVjS(yCR z0jYhYsJLp|vsG7pdxq+g+YPF#sa-k(iK$-hwM3cA9L||Rx%`7-<+=X-0iClF@{?Zv zr$}4qT>qNxEh4xoQr$&#$WwWu9|oRq$K{iKx~&D(p6I%O;O<18wCPA6Sk`y0|5*1V z(G&e?Ktx#-BR0>drm_uA=H9_erEwdTV-?T!e}LS-=6QGymn+;EZVOwt=p|j$emVZQ*nMtzEiV6K9Pf9#N0DC8*!0Yw$&X;hPzX%kTwP+nJkL z?ihWpzsk4l;<^60!Qmz86D18_hYhEwJ~jY}&VOeSb4gu_pVnKdP3ltWYw_uvaal$i zvkLWStsPjk1c8}PrgjDk(8BdT@(aLxeJ~ekl$dk|ZtX>$NW7&pWaK#(Us>C&$X2Mo zGSL4Tq^EC3IwL!fx&kq*Zm1@AgZOUFDO-o>wCVW*r#)iL zTIY$HrFi{Qvx^He_7oPIL*}sG(e2pf$U1F)k6FH{&v<^so&^giysbCj*ycFp$UL3F zW3u*|U)bdkHZjXAW9FWWy{8;H?#_9@MDxlyb&k|;u4p)G^Rf_gmW!tb$`=$2G4KWB zbc**4+Prf)HTuBeZWcXXieKU_R^#p70x>wS(}t5{bbcdY6zE3G0qlaJh@PtdzBt?mx=FMH`e{H}ZHe*8Z4(wgo=j!DiH$J3qn zoV>dn5~P3SahwfXN=N4I6L;n8%;0;6Ki6b!$b2{Bl+a=A$gu8o`~dW{M^E2XppT^! z9(P!sE4ua0d)}e?*g(1WkOL(pY7g`~{ek{U|CZxbYUx?~GIwR{OjBvq-?5;>)8U)9 z`T}8Z?_-wVC+LyOAg4MUC|TYxWVENF#-DMD+%UArZ(KW4;cunBepBVLbGCMjgPbl3 zvQgB@dQmS6BJu2|(a6tfE)ZK1D3AqrMQK~e7u_4UJJJar9*8~LZ4d>_q(E#b;mtWj zAXbkVD~GInw#tZG5(Foj__$-qJM~8bv2VS~@eMy0HWoeZc;<*b!Yp$qQXkN43B;ZO z@7WPXDP7ofQ&3r#|ugw>4;CzJdaX5p6b}woxG$lHM_VM-!wqkng1> ze@R&CqSVxSU#!WilWl>L&<>Pk>&_JoyOng{6MkAVux^5L$RWe?-B>l4Wj)VVHuQ|& zNQ|_)k*S`>nv*Sm;5$%ZR`5a?6J5 z{Wfq5{fuN-5Ob7q-u?8IrGEW%T6fB)D)mun19-P_I4n|>Ykj)rNwiwHM~gP_VXispR>E_kHEGS{J=1K&Du2iaJH1A|$m9;kTi_PcvJ6<; z?)M>ekoq$?SmiAQCElR+-r5d>tZUXwCge6_b~4QJX<5{lb$X@$clZ;bmKJ@+KGUxB zoyK8n9j$V|&Z6I70gc?GOvl2(_Ryh4N@l6R% z-=c8(YvNlIoc=K{wT!6C-Ls%4(BI|*NB8Z36w{{Y7MzQ(+(tY{)fN0b{i6svq|$m~ z8I>$re}??fqf`WAV=JqCn}$@ zU3nPXp^4;H+Kb4GuZ*wQc*SfdZq(EzRBUiO7yi=><324{pueFDs|LUYsP9sASQNYX zimAd;23%zi@;O7FSCO<*#`fyi~7ZOrL~L8IL;nO3j%tC z@T0UngHL(mE~|Su@9PSo@?ziZY}q<0;sXq^4j)we4ae z#X_W5sHUh-q>$S+jTvaTvK(p3)ih0sG%Y+0t23^vQQHvg7l*ZBXZ!adNo%bj+!dW$ z4|vPG1O`v?R9ZV8OQc!jElQ->#?xpmsa4Z3>^yT5X}0q;T3e_EG(v1>3G}>43H2$S zN^1?ZK}ofOr_vV-EqPKh^>Va)xzh3hZ4B5@YfAs!gB17h6v4q{-%u-vMyR}zDdj!K zYgbD|Icn_#RVnTGHcz9J$%eH4pp~53!Rby84tfqUt}~$Cr7>FYQQ1ceKPvyo_A%Nc z_Y599sJPhBQwdjF!nG&i+JA8QNB5|?*bwEi^VV2FFG?GT+K2*4_Tu=$r(*6Rs#3z( zP`&0tPbp#4BZ|ukno}vtX&ri%xT7l=6C3@5r#=#f1mcw77u156K6*;+O{qP|T}077 z?jp)n%40*x@vZWDw0_|n7qa~s8dEE%LsCW_dphF9o9x+9!S&pkO+20rtwByo$%aUC zukjr42AoFh1Oxy>kw%p zjQebUbLeZOjUhP%&3DRPka|SZ7X)GgY2)fAi`!zRrd--*aoseyr)+EAp^O6BR|UT4 z3QJw1M3QoaCHCHYUf-NGCZ5NN7D|d_ftB^cG@)~o=GhSdw)9JaeX7U4zlDY z;LZ2)(;h2&{x0xSW;ugN*%}v9Zgaqr?gK-LEC(sY`!4mQ(LpCI+^Fm=wsdt(bH^B3419j z(cD5#I-^RaeJNU-5#w-87&4o^@20uwE&+Oml5hc0Am6*?o)?_uVdU;$ zZg*&V|C-~wKwW#M_@ejumR}q{joRUh*>O6vqLf`ND?Qi0_5|nle3svv$bC-;yN{Io zDXrsYY=kc)QRwMSLB5t!iQ35 zo43Q&8EOm(Yu7l8>z0&q4TtNQxl&YAu_Yd@tX{rYTRZS|2V)(Fq=TK|iBvcCBEv(K z6t5pr^o!Sz{o$dbVd-P(s#FFU4kJu5oLGI+-zo3dp-;z5ETZ~?F}Z!h-%0t#b;=f` zbS@tTWA*K%w^7q^_g?ob>v zkV@!@VHHwzUfAWj{Yq&#*VSZ1(5&Q-qvUuqb7m>rJ4TvE+U2CXl<`yaXad@ymvk)| zO5L2Yb*^*$kAbIWaIQ-0mM>c4r!b=!uOJLwzGCNXpg4phZV%w`E*o?i&^H1PqH)4Y z$$gM^w~_SXn%D|IutGaVPB*|H=|PjwoXzo5O4{Q$xZ1+T8J_4v(A%tW2qJSTb4Hub zD3i}!U-U7b;EXre!x=?2vCYtqmV_ovM?T-g>98N2R*4CZO-R0xzkBEkv*OI zJZn1XMQPVxf_;B?zuiYPP4y*bFX3M{bU!pS_ORfz5KUmzs=PLTF7KJ17|!whS*jZ= zIPdetrL>a=58}K&UL%}BJ}xbv>mL=cZi+k2m+hDB5!yXA-h8eS z*y~*xqCWO*|HBu4^694Y6t0gobtUs{LcX2;%*t(HoiseA38lQ~FXA!h`oEr%r^z3e z^|6g_Q#%-TO8VI1*L;DtzU6(o$@YjRg%bAq7hts@P5Ra@gJ^S(0R67+hIv&D@nj7P zgR3T1+oi{ET~{rBH@+?4x4z4W--c^w2U=~vFY58vL<)iLHosuUFWThy*TkOn2O?vt z_3mR~eXI@bI_fuUqWHEhYRMP&ys#TRvKgr<_Fe4L-ZZ7G>#kp3F;>Q%uPkf}O<9J$ zVz*Ga-SNH1pG&Bn=;ca%>`9EnHb7gqAU_Aa&P?>fZunPmy|N;6#p}(SllOD^g7Phl zJ=4B0R{qiU&}>j3afFk7=DzI7`q=vcj8NeDv)Rjk_GwM5Bd~4mx8{ET(`V0Ri8Zme zc-%joedp5mKP@ZGtgI+qdd?i0xi*Kd2vlyvS$%9T?}5E&(}I8iI#`hCePD||+4x#b zXXYHm%#si-FQ>1#EyCB#46OkV#P`eRwG z!*=-I^Kq<3+b*Y73zhcp%q_yQtJREa02JCgjoP;Wn*Es%8mkA=*I zY(lTgDfH9q*TI3;)8lgbkWFZ6azQP zP{vq?`e;nw_3NQ$f78SuaZb+QTvleFpc8(y!@kh*^)Z_4l$4DLe>(FZenpaNTbSWg z=R2U6{ap*_gbI|q7nrtm)mPx@y{pDZ^n-`v>2(=f}^R%RKnn$)zW zVP$K4k*E;7ymvft(+0G2sV}ltG^IS4jEej3j?ddU}7FNbzHHn~e0!Res+Upm1P-R(2%6Wk{3Lbl`x&Et@AwNK~rMGyMi#1DhC zu9rYxiq#Myf2x#2a0LZ98}i^>Q#K#pr1nxhi$mz+po5|D%yMo#QQ70xRQjTs0vW@v zD>OByLDTv@tgK|GwgP%g?YxiD&yBav3v6@v9Wxst z|6}GYg%0j%Yufa<{5rzOpDh}uF-X14@)`Dh16K4Z+;cfcnRa86)~=;j8hI0B50V{9 zB1W76n0dYhB1!q1vIW_|{m{-sMzM!WAklR9KgMO0lET#9g=N*S-km_Pd`@)tf0fgG z&lHdQNZ+zPaO6Ik1Mf}g?w{yWderKsaIHs_9!>I=>*CKj!@2$+y_B2-rWyKSSWgtG z7dB;UybSem-qADViA3)w!~T#6Q+VF>>L)%yD~eKXl1{XK)96_1=XgU&r1RpeVy!Qd zvu+BXbw)nxW`I_5+}f<$<-i^qSkvrdn0r^yS2X)Z@En3uklmp)HT7H**~+AjaFTu| z(o~V8X&L|E)7Yarv7LHgKjNYJX9z9V*QuD}XVs^7~Ht>2T zjX2Fs<+Lc6q50F)6g`O)hUScFv&=6{&Wcut z@x7a781|g&f5S(sq+t)?*Pl*&YGG{22Ue%D?mXmhl#Qsg1&A-5>wgIA&~V;idJJf)VG1k&=+%eOn4%w^v^e6HoL})V?~H!`mS= zq!pg)p9el!I(zv=`$eK_8Z}ybXwR6s_GGL0IdML`JnRa&L&2eirS^-2t)Wmq=~`S> z`Gm{zSmy%A9fAxQqmOo8wBEfD=#1F0E2TQihIXLU58P;kozWpk>@*%<=1XlCv$$4> z4ZMm|ZN6@(>j#y=2HK$aOUJp3);qF#9*rH-tM;&x2D|>QJ%QdR31t*|qHBFQvM2g8pAx&#l%z^UegIC~{)4&60)#Zc z%9)_nPZa<16@#6*n|M6=RSOF@-1U@)dPL{+L?6WLIM=@}Nb|(##Q2@S?%XFfoa_H; z(13l{il9C=8}gnmgU+u>YS5`tfVQep>CFA|m3%u^BC9XD0sRU4EYQ6#x&Woip{Xu+ z$QLaOrXyq_%B%80?~78E@@ZG2luZ(avUbwRI<0cBJmg=j`TUEzKz-Ej%urv2B zp`lhR;nMdhws48lWUlw*I&MDue9<=o20r^}#@Ty|N<7h@1fGyPv1ge8TL4)0VfRIG z*~Oj;ZaKk~}=#&_+C@ewTxArCc0n@_(s`x-7pD@6uY3Z6ow z7L6T&7V#O+Tv+$I^gMK;Idu+d^Xyu?QeV{a-(pufk~DB?{~zo4qOvn=glyay)-CG{ zW6eHJmYoyL_pA1$R-$K>_iMCPjCLLi2=dVgcKqF*s5c;T-W8XV7NU8og{Y#D#u!$T zr77{kwvaJl#rl84PE_NIL_2Yk)R(kf)OfSd%&y#knWC)!G^XszNbtl*eYB1W%?;JY z2i9^~bn2X7RI@jvF|*=qSMrk!C03A@miomy(As_%r#b5YX)dpgw?WT$Gmp2yR_}W8 z_3Z^}JZYQ1oWH4Ek-==&t>1?Fr2y%aQ*!!sGf10EAunHXcM;vq&w$Tm8+e1x5)}G_ zJoTL}=_pRV8c&9W%9CN~*OW#dd)ZIgNgrv%um@~v=bA~laB>Xo9@+USI-gvw=^+UN zRMT~>lwl~Ode7?=3V)R7J~5MR=
SN8fuSKM9hkVBoJ8!)#Xf<*I%?|UKJ^c~?{ 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 c{+9_V8y{CfwkO}#EW9% Date: Wed, 11 Dec 2024 08:16:43 +0800 Subject: [PATCH 070/193] rtw88: Fix builds for kernel 6.13 --- mac80211.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/mac80211.c b/mac80211.c index 5a1d67d9..98a90cfb 100644 --- a/mac80211.c +++ b/mac80211.c @@ -988,8 +988,16 @@ static int rtw_ops_set_sar_specs(struct ieee80211_hw *hw, static void rtw_ops_sta_rc_update(struct ieee80211_hw *hw, struct ieee80211_vif *vif, +#if LINUX_VERSION_CODE < KERNEL_VERSION(6, 13, 0) struct ieee80211_sta *sta, u32 changed) +#else + struct ieee80211_link_sta *link_sta, + u32 changed) +#endif { +#if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 13, 0) + struct ieee80211_sta *sta = link_sta->sta; +#endif struct rtw_dev *rtwdev = hw->priv; struct rtw_sta_info *si = (struct rtw_sta_info *)sta->drv_priv; @@ -1037,7 +1045,11 @@ const struct ieee80211_ops rtw_ops = { .reconfig_complete = rtw_reconfig_complete, .hw_scan = rtw_ops_hw_scan, .cancel_hw_scan = rtw_ops_cancel_hw_scan, +#if LINUX_VERSION_CODE < KERNEL_VERSION(6, 13, 0) .sta_rc_update = rtw_ops_sta_rc_update, +#else + .link_sta_rc_update = rtw_ops_sta_rc_update, +#endif #if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 11, 0) .set_sar_specs = rtw_ops_set_sar_specs, #endif From 948a8bae411a0390a20f949835ed9773bc3faf45 Mon Sep 17 00:00:00 2001 From: Bitterblue Smith Date: Thu, 12 Dec 2024 17:49:49 +0200 Subject: [PATCH 071/193] Fix null pointer dereference with RTL8812AU/RTL8821AU Fixes 74fe9b7f6913ea0e8f235826a1680012002c810c. Fixes https://github.com/lwfinger/rtw88/issues/265. Signed-off-by: Bitterblue Smith --- usb.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/usb.c b/usb.c index 5b251093..62a81950 100644 --- a/usb.c +++ b/usb.c @@ -1193,6 +1193,9 @@ static void rtw_usb_phy_cfg(struct rtw_dev *rtwdev, const struct rtw_intf_phy_para *para = NULL; u16 cut, offset; + if (!rtwdev->chip->intf_table) + return; + if (speed == USB_SPEED_SUPER) para = rtwdev->chip->intf_table->usb3_para; else if (speed == USB_SPEED_HIGH) From 07a117dacb61ea85b184734cf646981e73400b82 Mon Sep 17 00:00:00 2001 From: Bitterblue Smith Date: Fri, 20 Dec 2024 01:53:25 +0200 Subject: [PATCH 072/193] Sync USB RX aggregation with upstream Signed-off-by: Bitterblue Smith --- usb.c | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/usb.c b/usb.c index 62a81950..e709b922 100644 --- a/usb.c +++ b/usb.c @@ -868,7 +868,10 @@ static void rtw_usb_dynamic_rx_agg_v2(struct rtw_dev *rtwdev, bool enable) u8 size, timeout; u16 val16; - if (rtwusb->udev->speed == USB_SPEED_SUPER) { + if (!enable) { + size = 0x0; + timeout = 0x1; + } else if (rtwusb->udev->speed == USB_SPEED_SUPER) { size = 0x6; timeout = 0x1a; } else { @@ -876,11 +879,6 @@ static void rtw_usb_dynamic_rx_agg_v2(struct rtw_dev *rtwdev, bool enable) timeout = 0x20; } - if (!enable) { - size = 0x0; - timeout = 0x1; - } - val16 = u16_encode_bits(size, BIT_RXDMA_AGG_PG_TH) | u16_encode_bits(timeout, BIT_DMA_AGG_TO_V1); From e2346efb196cc50aa49f30f29692f39b981003d1 Mon Sep 17 00:00:00 2001 From: Bitterblue Smith Date: Fri, 20 Dec 2024 01:55:15 +0200 Subject: [PATCH 073/193] Sync USB 3 switching with upstream Signed-off-by: Bitterblue Smith --- usb.c | 22 ++++++++++++++++------ 1 file changed, 16 insertions(+), 6 deletions(-) diff --git a/usb.c b/usb.c index e709b922..85f97d05 100644 --- a/usb.c +++ b/usb.c @@ -1069,7 +1069,7 @@ static int rtw_usb_switch_mode_old(struct rtw_dev *rtwdev) if ((hci_opt & (BIT(2) | BIT(3))) != BIT(3)) { rtw_write8(rtwdev, REG_HCI_OPT_CTRL, 0x8); rtw_write8(rtwdev, REG_SYS_SDIO_CTRL, 0x2); - rtw_write8(rtwdev, 0x3e, 0x1); + rtw_write8(rtwdev, REG_ACLK_MON, 0x1); rtw_write8(rtwdev, 0x3d, 0x3); /* usb disconnect */ rtw_write8(rtwdev, REG_SYS_PW_CTRL + 1, 0x80); @@ -1077,7 +1077,7 @@ static int rtw_usb_switch_mode_old(struct rtw_dev *rtwdev) } } else if (cur_speed == USB_SPEED_SUPER) { rtw_write8_clr(rtwdev, REG_SYS_SDIO_CTRL, BIT(1)); - rtw_write8_clr(rtwdev, 0x3e, BIT(0)); + rtw_write8_clr(rtwdev, REG_ACLK_MON, BIT(0)); } return 0; @@ -1132,12 +1132,22 @@ static int rtw_usb_switch_mode_new(struct rtw_dev *rtwdev) return 1; } +static bool rtw_usb3_chip_old(u8 chip_id) +{ + return chip_id == RTW_CHIP_TYPE_8812A; +} + +static bool rtw_usb3_chip_new(u8 chip_id) +{ + return chip_id == RTW_CHIP_TYPE_8822C || + chip_id == RTW_CHIP_TYPE_8822B; +} + static int rtw_usb_switch_mode(struct rtw_dev *rtwdev) { u8 id = rtwdev->chip->id; - if (id != RTW_CHIP_TYPE_8822C && id != RTW_CHIP_TYPE_8822B && - id != RTW_CHIP_TYPE_8812A) + if (!rtw_usb3_chip_new(id) && !rtw_usb3_chip_old(id)) return 0; if (!rtwdev->efuse.usb_mode_switch) { @@ -1152,9 +1162,9 @@ static int rtw_usb_switch_mode(struct rtw_dev *rtwdev) return 0; } - if (id == RTW_CHIP_TYPE_8812A) + if (rtw_usb3_chip_old(id)) return rtw_usb_switch_mode_old(rtwdev); - else /* RTL8822CU, RTL8822BU */ + else return rtw_usb_switch_mode_new(rtwdev); } From 5dad7e4018a5cd20c801ce54f9a616b22fc0652e Mon Sep 17 00:00:00 2001 From: Bitterblue Smith Date: Fri, 20 Dec 2024 01:56:34 +0200 Subject: [PATCH 074/193] Sync USB RX skb allocation and handling with upstream Signed-off-by: Bitterblue Smith --- usb.c | 72 +++++++++++++++++++++++++---------------------------------- 1 file changed, 31 insertions(+), 41 deletions(-) diff --git a/usb.c b/usb.c index 85f97d05..046073d8 100644 --- a/usb.c +++ b/usb.c @@ -7,6 +7,7 @@ #include #include "main.h" #include "debug.h" +#include "mac.h" #include "reg.h" #include "tx.h" #include "rx.h" @@ -559,14 +560,14 @@ static void rtw_usb_rx_handler(unsigned long shut_up_gcc) struct rtw_usb *rtwusb = (struct rtw_usb *)shut_up_gcc; #endif struct rtw_dev *rtwdev = rtwusb->rtwdev; - const struct rtw_chip_info *chip = rtwdev->chip; - u32 pkt_desc_sz = chip->rx_pkt_desc_sz; struct ieee80211_rx_status rx_status; - u32 pkt_offset, next_pkt, urb_len; struct rtw_rx_pkt_stat pkt_stat; struct sk_buff *rx_skb; struct sk_buff *skb; - u32 skb_len; + u32 pkt_desc_sz = rtwdev->chip->rx_pkt_desc_sz; + u32 max_skb_len = pkt_desc_sz + PHY_STATUS_SIZE * 8 + + IEEE80211_MAX_MPDU_LEN_VHT_11454; + u32 pkt_offset, next_pkt, skb_len; u8 *rx_desc; int limit; @@ -581,7 +582,6 @@ static void rtw_usb_rx_handler(unsigned long shut_up_gcc) continue; } - urb_len = rx_skb->len; rx_desc = rx_skb->data; do { @@ -591,19 +591,19 @@ static void rtw_usb_rx_handler(unsigned long shut_up_gcc) pkt_stat.shift; skb_len = pkt_stat.pkt_len + pkt_offset; - if (skb_len > 12000) { - rtw_err(rtwdev, - "skipping RX URB, packet too big: %u\n", + if (skb_len > max_skb_len) { + rtw_dbg(rtwdev, RTW_DBG_USB, + "skipping too big packet: %u\n", skb_len); - break; + goto skip_packet; } skb = alloc_skb(skb_len, GFP_ATOMIC); if (!skb) { - rtw_err(rtwdev,/// TODO rtw_dbg - "failed to allocate RX skb of size %d\n", + rtw_dbg(rtwdev, RTW_DBG_USB, + "failed to allocate RX skb of size %u\n", skb_len); - continue; /* try again */ + goto skip_packet; } skb_put_data(skb, rx_desc, skb_len); @@ -620,62 +620,52 @@ static void rtw_usb_rx_handler(unsigned long shut_up_gcc) ieee80211_rx_irqsafe(rtwdev->hw, skb); } +skip_packet: next_pkt = round_up(skb_len, 8); rx_desc += next_pkt; - } while (rx_skb->data + urb_len > rx_desc + pkt_desc_sz); + } while (rx_desc + pkt_desc_sz < rx_skb->data + rx_skb->len); - if (skb_queue_len(&rtwusb->rx_free_queue) >= - RTW_USB_RX_SKB_NUM - RTW_USB_RXCB_NUM) { - rtw_err(rtwdev, "freeing excess RX skb\n"); + if (skb_queue_len(&rtwusb->rx_free_queue) >= RTW_USB_RX_SKB_NUM) dev_kfree_skb_any(rx_skb); - } else { + else skb_queue_tail(&rtwusb->rx_free_queue, rx_skb); - } } - - if (limit == 200) - rtw_err(rtwdev, "left %u frames in the rx queue for later\n", - skb_queue_len(&rtwusb->rx_queue)); } static void rtw_usb_read_port_complete(struct urb *urb); -static void rtw_usb_rx_resubmit(struct rtw_usb *rtwusb, struct rx_usb_ctrl_block *rxcb) +static void rtw_usb_rx_resubmit(struct rtw_usb *rtwusb, + struct rx_usb_ctrl_block *rxcb, + gfp_t gfp) { struct rtw_dev *rtwdev = rtwusb->rtwdev; struct sk_buff *rx_skb; - gfp_t priority = in_interrupt() ? GFP_ATOMIC : GFP_KERNEL; int error; rx_skb = skb_dequeue(&rtwusb->rx_free_queue); - if (!rx_skb) { - rtw_err(rtwdev, "allocating new RX skb\n"); - - rx_skb = alloc_skb(RTW_USB_MAX_RECVBUF_SZ, priority); - } - - if (!rx_skb) { - rtw_err(rtwdev, "no free RX skb and alloc_skb failed\n"); + if (!rx_skb) + rx_skb = alloc_skb(RTW_USB_MAX_RECVBUF_SZ, gfp); + if (!rx_skb) goto try_later; - } - rxcb->rx_skb = rx_skb; + skb_reset_tail_pointer(rx_skb); + rx_skb->len = 0; - skb_reset_tail_pointer(rxcb->rx_skb); - rxcb->rx_skb->len = 0; + rxcb->rx_skb = rx_skb; usb_fill_bulk_urb(rxcb->rx_urb, rtwusb->udev, usb_rcvbulkpipe(rtwusb->udev, rtwusb->pipe_in), rxcb->rx_skb->data, RTW_USB_MAX_RECVBUF_SZ, rtw_usb_read_port_complete, rxcb); - error = usb_submit_urb(rxcb->rx_urb, priority); + error = usb_submit_urb(rxcb->rx_urb, gfp); if (error) { skb_queue_tail(&rtwusb->rx_free_queue, rxcb->rx_skb); if (error != -ENODEV) - rtw_err(rtwdev, "Err sending rx data urb %d\n", error); + rtw_err(rtwdev, "Err sending rx data urb %d\n", + error); if (error == -ENOMEM) goto try_later; @@ -698,7 +688,7 @@ static void rtw_usb_rx_resubmit_work(struct work_struct *work) rxcb = &rtwusb->rx_cb[i]; if (!rxcb->rx_skb) - rtw_usb_rx_resubmit(rtwusb, rxcb); + rtw_usb_rx_resubmit(rtwusb, rxcb, GFP_ATOMIC); } } @@ -724,7 +714,7 @@ static void rtw_usb_read_port_complete(struct urb *urb) tasklet_schedule(&rtwusb->rx_tasklet); #endif } - rtw_usb_rx_resubmit(rtwusb, rxcb); + rtw_usb_rx_resubmit(rtwusb, rxcb, GFP_ATOMIC); } else { skb_queue_tail(&rtwusb->rx_free_queue, skb); @@ -973,7 +963,7 @@ static void rtw_usb_setup_rx(struct rtw_dev *rtwdev) for (i = 0; i < RTW_USB_RXCB_NUM; i++) { struct rx_usb_ctrl_block *rxcb = &rtwusb->rx_cb[i]; - rtw_usb_rx_resubmit(rtwusb, rxcb); + rtw_usb_rx_resubmit(rtwusb, rxcb, GFP_KERNEL); } } From 5343fc63c54164b776ae70ff0eb45ba0ae7ac2ba Mon Sep 17 00:00:00 2001 From: Bitterblue Smith Date: Fri, 20 Dec 2024 01:05:07 +0200 Subject: [PATCH 075/193] wifi: rtw88: 8821a/8812a: Set ptct_efuse_size to 0 Some RTL8812AU devices fail to probe: [ 12.478774] rtw_8812au 1-1.3:1.0: failed to dump efuse logical map [ 12.487712] rtw_8812au 1-1.3:1.0: failed to setup chip efuse info [ 12.487742] rtw_8812au 1-1.3:1.0: failed to setup chip information [ 12.491077] rtw_8812au: probe of 1-1.3:1.0 failed with error -22 It turns out these chips don't need to "protect" any bytes at the end of the efuse. Signed-off-by: Bitterblue Smith --- rtw8812a.c | 2 +- rtw8821a.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/rtw8812a.c b/rtw8812a.c index 6bccd442..5f46456b 100644 --- a/rtw8812a.c +++ b/rtw8812a.c @@ -1050,7 +1050,7 @@ const struct rtw_chip_info rtw8812a_hw_spec = { .rx_buf_desc_sz = 8, .phy_efuse_size = 512, .log_efuse_size = 512, - .ptct_efuse_size = 96 + 1, /* TODO or just 18? */ + .ptct_efuse_size = 0, .txff_size = 131072, .rxff_size = 16128, .rsvd_drv_pg_num = 9, diff --git a/rtw8821a.c b/rtw8821a.c index 794e811e..0193e426 100644 --- a/rtw8821a.c +++ b/rtw8821a.c @@ -1150,7 +1150,7 @@ const struct rtw_chip_info rtw8821a_hw_spec = { .rx_buf_desc_sz = 8, .phy_efuse_size = 512, .log_efuse_size = 512, - .ptct_efuse_size = 96 + 1, /* TODO or just 18? */ + .ptct_efuse_size = 0, .txff_size = 65536, .rxff_size = 16128, .rsvd_drv_pg_num = 8, From c2e991543e6301250241c266c7cab5ec94e38142 Mon Sep 17 00:00:00 2001 From: Bitterblue Smith Date: Fri, 20 Dec 2024 01:18:37 +0200 Subject: [PATCH 076/193] wifi: rtw88: Delete rf_type member of struct rtw_sta_info It's not used for anything. Signed-off-by: Bitterblue Smith --- main.c | 13 ++++--------- main.h | 1 - 2 files changed, 4 insertions(+), 10 deletions(-) diff --git a/main.c b/main.c index 15557b03..a347b625 100644 --- a/main.c +++ b/main.c @@ -1232,7 +1232,6 @@ void rtw_update_sta_info(struct rtw_dev *rtwdev, struct rtw_sta_info *si, u8 wireless_set; u8 bw_mode; u8 rate_id; - u8 rf_type = RF_1T1R; u8 stbc_en = 0; u8 ldpc_en = 0; u8 tx_num = 1; @@ -1387,20 +1386,17 @@ void rtw_update_sta_info(struct rtw_dev *rtwdev, struct rtw_sta_info *si, } #if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 19, 0) - if (sta->deflink.vht_cap.vht_supported && ra_mask & 0xffc00000) { + if (sta->deflink.vht_cap.vht_supported && ra_mask & 0xffc00000) #else - if (sta->vht_cap.vht_supported && ra_mask & 0xffc00000) { + if (sta->vht_cap.vht_supported && ra_mask & 0xffc00000) #endif tx_num = 2; - rf_type = RF_2T2R; #if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 19, 0) - } else if (sta->deflink.ht_cap.ht_supported && ra_mask & 0xfff00000) { + else if (sta->deflink.ht_cap.ht_supported && ra_mask & 0xfff00000) #else - } else if (sta->ht_cap.ht_supported && ra_mask & 0xfff00000) { + else if (sta->ht_cap.ht_supported && ra_mask & 0xfff00000) #endif tx_num = 2; - rf_type = RF_2T2R; - } rate_id = get_rate_id(wireless_set, bw_mode, tx_num); @@ -1411,7 +1407,6 @@ void rtw_update_sta_info(struct rtw_dev *rtwdev, struct rtw_sta_info *si, si->bw_mode = bw_mode; si->stbc_en = stbc_en; si->ldpc_en = ldpc_en; - si->rf_type = rf_type; si->sgi_enable = is_support_sgi; si->vht_enable = is_vht_enable; si->ra_mask = ra_mask; diff --git a/main.h b/main.h index 5d7120bd..c73a0ecf 100644 --- a/main.h +++ b/main.h @@ -894,7 +894,6 @@ struct rtw_sta_info { u8 mac_id; u8 rate_id; enum rtw_bandwidth bw_mode; - enum rtw_rf_type rf_type; u8 stbc_en:2; u8 ldpc_en:2; bool sgi_enable; From d402e1012d0239fa8b65395ad9973a7d52507a8a Mon Sep 17 00:00:00 2001 From: Bitterblue Smith Date: Sat, 7 Dec 2024 02:03:15 +0200 Subject: [PATCH 077/193] wifi: rtw88: Don't run coex when the chip has no Bluetooth Add an early exit to most public functions in coex.c: if (!rtwdev->efuse.btcoex) return; It should not be necessary to run any of the coex code when the chip doesn't have Bluetooth. RTL8814AU has a problem when __rtw_coex_init_hw_config() runs. It calls rtw_coex_set_ant_path(), which calls rtw_coex_coex_ctrl_owner(). This function sets bit 26 of REG_SYS_SDIO_CTRL, which appears to turn off RF path C. That results in bad performance. Add the early exit to the other functions just for completeness. Tested with combo chips RTL8723DU, RTL8821AU, RTL8822CU, and wifi-only chips RTL8814AU, RTL8812AU, RTL8811AU, RTL8811CU, RTL8812BU. Signed-off-by: Bitterblue Smith --- coex.c | 78 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 78 insertions(+) diff --git a/coex.c b/coex.c index c929db1e..2091b6cd 100644 --- a/coex.c +++ b/coex.c @@ -370,6 +370,9 @@ void rtw_coex_write_scbd(struct rtw_dev *rtwdev, u16 bitpos, bool set) struct rtw_coex_stat *coex_stat = &coex->stat; u16 val = 0x2; + if (!rtwdev->efuse.btcoex) + return; + if (!chip->scbd_support) return; @@ -451,6 +454,9 @@ void rtw_coex_query_bt_info(struct rtw_dev *rtwdev) struct rtw_coex *coex = &rtwdev->coex; struct rtw_coex_stat *coex_stat = &coex->stat; + if (!rtwdev->efuse.btcoex) + return; + if (coex_stat->bt_disabled) return; @@ -2696,6 +2702,9 @@ static void __rtw_coex_init_hw_config(struct rtw_dev *rtwdev, bool wifi_only) struct rtw_coex *coex = &rtwdev->coex; struct rtw_coex_stat *coex_stat = &coex->stat; + if (!rtwdev->efuse.btcoex) + return; + rtw_dbg(rtwdev, RTW_DBG_COEX, "[BTCoex], %s()\n", __func__); rtw_coex_init_coex_var(rtwdev); @@ -2751,6 +2760,9 @@ void rtw_coex_power_on_setting(struct rtw_dev *rtwdev) struct rtw_coex *coex = &rtwdev->coex; u8 table_case = 1; + if (!rtwdev->efuse.btcoex) + return; + rtw_dbg(rtwdev, RTW_DBG_COEX, "[BTCoex], %s()\n", __func__); coex->stop_dm = true; @@ -2775,6 +2787,9 @@ EXPORT_SYMBOL(rtw_coex_power_on_setting); void rtw_coex_power_off_setting(struct rtw_dev *rtwdev) { + if (!rtwdev->efuse.btcoex) + return; + rtw_write16(rtwdev, REG_WIFI_BT_INFO, BIT_BT_INT_EN); } EXPORT_SYMBOL(rtw_coex_power_off_setting); @@ -2790,6 +2805,9 @@ void rtw_coex_ips_notify(struct rtw_dev *rtwdev, u8 type) struct rtw_coex *coex = &rtwdev->coex; struct rtw_coex_stat *coex_stat = &coex->stat; + if (!rtwdev->efuse.btcoex) + return; + if (coex->manual_control || coex->stop_dm) return; @@ -2819,6 +2837,9 @@ void rtw_coex_lps_notify(struct rtw_dev *rtwdev, u8 type) struct rtw_coex *coex = &rtwdev->coex; struct rtw_coex_stat *coex_stat = &coex->stat; + if (!rtwdev->efuse.btcoex) + return; + if (coex->manual_control || coex->stop_dm) return; @@ -2857,6 +2878,9 @@ void rtw_coex_scan_notify(struct rtw_dev *rtwdev, u8 type) struct rtw_coex *coex = &rtwdev->coex; struct rtw_coex_stat *coex_stat = &coex->stat; + if (!rtwdev->efuse.btcoex) + return; + if (coex->manual_control || coex->stop_dm) return; @@ -2894,6 +2918,9 @@ void rtw_coex_switchband_notify(struct rtw_dev *rtwdev, u8 type) { struct rtw_coex *coex = &rtwdev->coex; + if (!rtwdev->efuse.btcoex) + return; + if (coex->manual_control || coex->stop_dm) return; @@ -2921,6 +2948,9 @@ void rtw_coex_connect_notify(struct rtw_dev *rtwdev, u8 type) struct rtw_coex *coex = &rtwdev->coex; struct rtw_coex_stat *coex_stat = &coex->stat; + if (!rtwdev->efuse.btcoex) + return; + if (coex->manual_control || coex->stop_dm) return; @@ -2975,6 +3005,9 @@ void rtw_coex_media_status_notify(struct rtw_dev *rtwdev, u8 type) struct rtw_coex *coex = &rtwdev->coex; struct rtw_coex_stat *coex_stat = &coex->stat; + if (!rtwdev->efuse.btcoex) + return; + if (coex->manual_control || coex->stop_dm) return; @@ -3018,6 +3051,9 @@ void rtw_coex_bt_info_notify(struct rtw_dev *rtwdev, u8 *buf, u8 length) u8 i, rsp_source = 0, type; bool inq_page = false; + if (!rtwdev->efuse.btcoex) + return; + rsp_source = buf[0] & 0xf; if (rsp_source >= COEX_BTINFO_SRC_MAX) return; @@ -3287,6 +3323,9 @@ void rtw_coex_bt_hid_info_notify(struct rtw_dev *rtwdev, u8 *buf, u8 length) u8 sub_id = buf[2], gamehid_cnt = 0, handle, i; bool cur_game_hid_exist, complete; + if (!rtwdev->efuse.btcoex) + return; + if (!chip->wl_mimo_ps_support && (sub_id == COEX_BT_HIDINFO_LIST || sub_id == COEX_BT_HIDINFO_A)) return; @@ -3375,6 +3414,9 @@ void rtw_coex_query_bt_hid_list(struct rtw_dev *rtwdev) u8 i, handle; bool complete; + if (!rtwdev->efuse.btcoex) + return; + if (!chip->wl_mimo_ps_support || coex_stat->wl_under_ips || (coex_stat->wl_under_lps && !coex_stat->wl_force_lps_ctrl)) return; @@ -3408,6 +3450,9 @@ void rtw_coex_wl_fwdbginfo_notify(struct rtw_dev *rtwdev, u8 *buf, u8 length) u8 val; int i; + if (!rtwdev->efuse.btcoex) + return; + rtw_dbg(rtwdev, RTW_DBG_COEX, "[BTCoex], WiFi Fw Dbg info = %8ph (len = %d)\n", buf, length); @@ -3434,6 +3479,9 @@ void rtw_coex_wl_fwdbginfo_notify(struct rtw_dev *rtwdev, u8 *buf, u8 length) void rtw_coex_wl_status_change_notify(struct rtw_dev *rtwdev, u32 type) { + if (!rtwdev->efuse.btcoex) + return; + rtw_coex_run_coex(rtwdev, COEX_RSN_WLSTATUS); } @@ -3441,6 +3489,9 @@ void rtw_coex_wl_status_check(struct rtw_dev *rtwdev) { struct rtw_coex_stat *coex_stat = &rtwdev->coex.stat; + if (!rtwdev->efuse.btcoex) + return; + if ((coex_stat->wl_under_lps && !coex_stat->wl_force_lps_ctrl) || coex_stat->wl_under_ips) return; @@ -3454,6 +3505,9 @@ void rtw_coex_bt_relink_work(struct work_struct *work) coex.bt_relink_work.work); struct rtw_coex_stat *coex_stat = &rtwdev->coex.stat; + if (!rtwdev->efuse.btcoex) + return; + mutex_lock(&rtwdev->mutex); coex_stat->bt_setup_link = false; rtw_coex_run_coex(rtwdev, COEX_RSN_WLSTATUS); @@ -3466,6 +3520,9 @@ void rtw_coex_bt_reenable_work(struct work_struct *work) coex.bt_reenable_work.work); struct rtw_coex_stat *coex_stat = &rtwdev->coex.stat; + if (!rtwdev->efuse.btcoex) + return; + mutex_lock(&rtwdev->mutex); coex_stat->bt_reenable = false; mutex_unlock(&rtwdev->mutex); @@ -3478,6 +3535,9 @@ void rtw_coex_defreeze_work(struct work_struct *work) struct rtw_coex *coex = &rtwdev->coex; struct rtw_coex_stat *coex_stat = &rtwdev->coex.stat; + if (!rtwdev->efuse.btcoex) + return; + mutex_lock(&rtwdev->mutex); coex->freeze = false; coex_stat->wl_hi_pri_task1 = false; @@ -3491,6 +3551,9 @@ void rtw_coex_wl_remain_work(struct work_struct *work) coex.wl_remain_work.work); struct rtw_coex_stat *coex_stat = &rtwdev->coex.stat; + if (!rtwdev->efuse.btcoex) + return; + mutex_lock(&rtwdev->mutex); coex_stat->wl_gl_busy = test_bit(RTW_FLAG_BUSY_TRAFFIC, rtwdev->flags); rtw_coex_run_coex(rtwdev, COEX_RSN_WLSTATUS); @@ -3503,6 +3566,9 @@ void rtw_coex_bt_remain_work(struct work_struct *work) coex.bt_remain_work.work); struct rtw_coex_stat *coex_stat = &rtwdev->coex.stat; + if (!rtwdev->efuse.btcoex) + return; + mutex_lock(&rtwdev->mutex); coex_stat->bt_inq_remain = coex_stat->bt_inq_page; rtw_coex_run_coex(rtwdev, COEX_RSN_BTSTATUS); @@ -3515,6 +3581,9 @@ void rtw_coex_wl_connecting_work(struct work_struct *work) coex.wl_connecting_work.work); struct rtw_coex_stat *coex_stat = &rtwdev->coex.stat; + if (!rtwdev->efuse.btcoex) + return; + mutex_lock(&rtwdev->mutex); coex_stat->wl_connecting = false; rtw_dbg(rtwdev, RTW_DBG_COEX, "[BTCoex], WL connecting stop!!\n"); @@ -3528,6 +3597,9 @@ void rtw_coex_bt_multi_link_remain_work(struct work_struct *work) coex.bt_multi_link_remain_work.work); struct rtw_coex_stat *coex_stat = &rtwdev->coex.stat; + if (!rtwdev->efuse.btcoex) + return; + mutex_lock(&rtwdev->mutex); coex_stat->bt_multi_link_remain = false; mutex_unlock(&rtwdev->mutex); @@ -3539,6 +3611,9 @@ void rtw_coex_wl_ccklock_work(struct work_struct *work) coex.wl_ccklock_work.work); struct rtw_coex_stat *coex_stat = &rtwdev->coex.stat; + if (!rtwdev->efuse.btcoex) + return; + mutex_lock(&rtwdev->mutex); coex_stat->wl_cck_lock = false; mutex_unlock(&rtwdev->mutex); @@ -3934,6 +4009,9 @@ void rtw_coex_display_coex_info(struct rtw_dev *rtwdev, struct seq_file *m) u32 lte_coex = 0, bt_coex = 0; int i; + if (!rtwdev->efuse.btcoex) + return; + score_board_BW = rtw_coex_read_scbd(rtwdev); score_board_WB = coex_stat->score_board; wl_reg_6c0 = rtw_read32(rtwdev, REG_BT_COEX_TABLE0); From 1ab8828d5008f0f7740d69da5af1363df9b2fdd5 Mon Sep 17 00:00:00 2001 From: Bitterblue Smith Date: Tue, 3 Dec 2024 02:01:21 +0200 Subject: [PATCH 078/193] wifi: rtw88: Add some definitions for RTL8814AU Add 8814A chip type enum and various register definitions which will be used by the new driver. Signed-off-by: Bitterblue Smith --- main.h | 1 + reg.h | 43 +++++++++++++++++++++++++++++++++++++++---- 2 files changed, 40 insertions(+), 4 deletions(-) diff --git a/main.h b/main.h index c73a0ecf..c2799805 100644 --- a/main.h +++ b/main.h @@ -328,6 +328,7 @@ enum rtw_chip_type { RTW_CHIP_TYPE_8703B, RTW_CHIP_TYPE_8821A, RTW_CHIP_TYPE_8812A, + RTW_CHIP_TYPE_8814A, }; enum rtw_tx_queue_type { diff --git a/reg.h b/reg.h index 3edea4e7..43896dd4 100644 --- a/reg.h +++ b/reg.h @@ -8,6 +8,7 @@ #define REG_SYS_FUNC_EN 0x0002 #define BIT_FEN_EN_25_1 BIT(13) #define BIT_FEN_ELDR BIT(12) +#define BIT_FEN_PCIEA BIT(6) #define BIT_FEN_CPUEN BIT(2) #define BIT_FEN_USBA BIT(2) #define BIT_FEN_BB_GLB_RST BIT(1) @@ -39,6 +40,9 @@ #define BIT_RF_RSTB BIT(1) #define BIT_RF_EN BIT(0) +#define REG_RF_CTRL1 0x20 +#define REG_RF_CTRL2 0x21 + #define REG_AFE_CTRL1 0x0024 #define BIT_MAC_CLK_SEL (BIT(20) | BIT(21)) #define REG_EFUSE_CTRL 0x0030 @@ -110,6 +114,7 @@ #define BIT_SDIO_PAD_E5 BIT(18) #define REG_RF_B_CTRL 0x76 +#define REG_RF_CTRL3 0x76 #define REG_AFE_CTRL_4 0x0078 #define BIT_CK320M_AFE_EN BIT(4) @@ -602,6 +607,13 @@ #define REG_CCA2ND 0x0838 #define REG_L1PKTH 0x0848 #define REG_CLKTRK 0x0860 +#define REG_CSI_MASK_SETTING1 0x0874 +#define REG_NBI_SETTING 0x087c +#define BIT_NBI_ENABLE BIT(13) +#define REG_CSI_FIX_MASK0 0x0880 +#define REG_CSI_FIX_MASK1 0x0884 +#define REG_CSI_FIX_MASK6 0x0898 +#define REG_CSI_FIX_MASK7 0x089c #define REG_ADCCLK 0x08AC #define REG_HSSI_READ 0x08B0 #define REG_FPGA0_XCD_RF_PARA 0x08B4 @@ -610,7 +622,7 @@ #define REG_ANTSEL_SW 0x0900 #define REG_DAC_RSTB 0x090c #define REG_SINGLE_TONE_CONT_TX 0x0914 - +#define REG_AGC_TABLE 0x0958 #define REG_RFE_CTRL_E 0x0974 #define REG_2ND_CCA_CTRL 0x0976 #define REG_IQK_COM00 0x0978 @@ -622,8 +634,10 @@ #define REG_RXSB 0x0a00 #define REG_CCK_RX 0x0a04 #define REG_CCK_PD_TH 0x0a0a - -#define REG_CCK0_FAREPORT 0xa2c +#define REG_CCK0_TX_FILTER1 0x0a20 +#define REG_CCK0_TX_FILTER2 0x0a24 +#define REG_CCK0_DEBUG_PORT 0x0a28 +#define REG_CCK0_FAREPORT 0x0a2c #define BIT_CCK0_2RX BIT(18) #define BIT_CCK0_MRC BIT(22) #define REG_FA_CCK 0x0a5c @@ -646,6 +660,7 @@ #define REG_3WIRE_SWA 0x0c00 #define REG_RX_IQC_AB_A 0x0c10 +#define REG_RX_IQC_CD_A 0x0c14 #define REG_TXSCALE_A 0x0c1c #define BB_SWING_MASK GENMASK(31, 21) #define REG_TX_AGC_A_CCK_11_CCK_1 0xc20 @@ -673,7 +688,7 @@ #define REG_LSSI_WRITE_A 0x0c90 #define REG_PREDISTA 0x0c90 #define REG_TXAGCIDX 0x0c94 - +#define REG_TX_AGC_A 0x0c94 #define REG_RFE_PINMUX_A 0x0cb0 #define REG_RFE_INV_A 0x0cb4 #define REG_RFE_CTRL8 0x0cb4 @@ -682,6 +697,7 @@ #define DPDT_CTRL_PIN 0x77 #define RFE_INV_MASK 0x3ff00000 #define REG_RFECTL_A 0x0cb8 +#define REG_RFE_INV0 0x0cbc #define REG_RFE_INV8 0x0cbd #define BIT_MASK_RFE_INV89 GENMASK(1, 0) #define REG_RFE_INV16 0x0cbe @@ -702,6 +718,7 @@ #define REG_3WIRE_SWB 0x0e00 #define REG_RX_IQC_AB_B 0x0e10 +#define REG_RX_IQC_CD_B 0x0e14 #define REG_TXSCALE_B 0x0e1c #define REG_TX_AGC_B_CCK_11_CCK_1 0xe20 #define REG_TX_AGC_B_OFDM18_OFDM6 0xe24 @@ -728,6 +745,7 @@ #define REG_LSSI_WRITE_B 0x0e90 #define REG_PREDISTB 0x0e90 #define REG_INIDLYB 0x0e94 +#define REG_TX_AGC_B 0x0e94 #define REG_RFE_PINMUX_B 0x0eb0 #define REG_RFE_INV_B 0x0eb4 #define REG_RFECTL_B 0x0eb8 @@ -745,6 +763,8 @@ #define REG_FA_OFDM 0x0f48 #define REG_CCA_CCK 0x0fcc +#define REG_SYS_CFG3_8814A 0x1000 + #define REG_ANAPARSW_MAC_0 0x1010 #define BIT_CF_L_V2 GENMASK(29, 28) @@ -862,10 +882,25 @@ #define LTECOEX_WRITE_DATA REG_WL2LTECOEX_INDIRECT_ACCESS_WRITE_DATA_V1 #define LTECOEX_READ_DATA REG_WL2LTECOEX_INDIRECT_ACCESS_READ_DATA_V1 +#define REG_RX_IQC_AB_C 0x1810 +#define REG_RX_IQC_CD_C 0x1814 +#define REG_TXSCALE_C 0x181c +#define REG_CK_MONHC 0x185c +#define REG_AFE_PWR1_C 0x1860 #define REG_IGN_GNT_BT1 0x1860 +#define REG_TX_AGC_C 0x1894 +#define REG_RFE_PINMUX_C 0x18b4 #define REG_RFESEL_CTRL 0x1990 +#define REG_RX_IQC_AB_D 0x1a10 +#define REG_RX_IQC_CD_D 0x1a14 +#define REG_TXSCALE_D 0x1a1c +#define REG_CK_MONHD 0x1a5c +#define REG_AFE_PWR1_D 0x1a60 +#define REG_TX_AGC_D 0x1a94 +#define REG_RFE_PINMUX_D 0x1ab4 + #define REG_NOMASK_TXBT 0x1ca7 #define REG_ANAPAR 0x1c30 #define BIT_ANAPAR_BTPS BIT(22) From 8751b7ac946f1d07297e4dbd8069c972abbd05a4 Mon Sep 17 00:00:00 2001 From: Bitterblue Smith Date: Sat, 30 Nov 2024 00:06:46 +0200 Subject: [PATCH 079/193] wifi: rtw88: Fix rtw_mac_power_switch() for RTL8814AU rtw_mac_power_switch() checks bit 8 of REG_SYS_STATUS1 to see if the chip is powered on. This bit appears to be always on in the RTL8814AU, so ignore it. Signed-off-by: Bitterblue Smith --- mac.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/mac.c b/mac.c index cae9cca6..483b940a 100644 --- a/mac.c +++ b/mac.c @@ -291,7 +291,8 @@ static int rtw_mac_power_switch(struct rtw_dev *rtwdev, bool pwr_on) if (rtw_read8(rtwdev, REG_CR) == 0xea) cur_pwr = false; else if (rtw_hci_type(rtwdev) == RTW_HCI_TYPE_USB && - (rtw_read8(rtwdev, REG_SYS_STATUS1 + 1) & BIT(0))) + chip->id != RTW_CHIP_TYPE_8814A && + (rtw_read8(rtwdev, REG_SYS_STATUS1 + 1) & BIT(0))) cur_pwr = false; else cur_pwr = true; From 2c3cf07195f3b1c51c6f14b20d9e5c256fde11bc Mon Sep 17 00:00:00 2001 From: Bitterblue Smith Date: Sat, 30 Nov 2024 00:37:20 +0200 Subject: [PATCH 080/193] wifi: rtw88: Fix __rtw_download_firmware() for RTL8814AU Don't call ltecoex_read_reg() and ltecoex_reg_write() when the ltecoex_addr member of struct rtw_chip_info is NULL. The RTL8814AU doesn't have this feature. Signed-off-by: Bitterblue Smith --- mac.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/mac.c b/mac.c index 483b940a..5de16c75 100644 --- a/mac.c +++ b/mac.c @@ -785,7 +785,8 @@ static int __rtw_download_firmware(struct rtw_dev *rtwdev, if (!check_firmware_size(data, size)) return -EINVAL; - if (!ltecoex_read_reg(rtwdev, 0x38, <ecoex_bckp)) + if (rtwdev->chip->ltecoex_addr && + !ltecoex_read_reg(rtwdev, 0x38, <ecoex_bckp)) return -EBUSY; wlan_cpu_enable(rtwdev, false); @@ -803,7 +804,8 @@ static int __rtw_download_firmware(struct rtw_dev *rtwdev, wlan_cpu_enable(rtwdev, true); - if (!ltecoex_reg_write(rtwdev, 0x38, ltecoex_bckp)) { + if (rtwdev->chip->ltecoex_addr && + !ltecoex_reg_write(rtwdev, 0x38, ltecoex_bckp)) { ret = -EBUSY; goto dlfw_fail; } From a5f131c7c6edbfa7f02e3afb548f6ebb5b2281a7 Mon Sep 17 00:00:00 2001 From: Bitterblue Smith Date: Fri, 29 Nov 2024 23:47:44 +0200 Subject: [PATCH 081/193] wifi: rtw88: Fix download_firmware_validate() for RTL8814AU After the firmware is uploaded, download_firmware_validate() checks some bits in REG_MCUFW_CTRL to see if everything went okay. The RTL8814AU power on sequence sets bits 13 and 12 to 2, which this function does not expect, so it thinks the firmware upload failed. Make download_firmware_validate() ignore bits 13 and 12. Signed-off-by: Bitterblue Smith --- reg.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/reg.h b/reg.h index 43896dd4..9d62258e 100644 --- a/reg.h +++ b/reg.h @@ -135,6 +135,7 @@ #define BIT_SHIFT_ROM_PGE 16 #define BIT_FW_INIT_RDY BIT(15) #define BIT_FW_DW_RDY BIT(14) +#define BIT_CPU_CLK_SEL (BIT(12) | BIT(13)) #define BIT_RPWM_TOGGLE BIT(7) #define BIT_RAM_DL_SEL BIT(7) /* legacy only */ #define BIT_DMEM_CHKSUM_OK BIT(6) @@ -152,7 +153,7 @@ BIT_CHECK_SUM_OK) #define FW_READY_LEGACY (BIT_MCUFWDL_RDY | BIT_FWDL_CHK_RPT | \ BIT_WINTINI_RDY | BIT_RAM_DL_SEL) -#define FW_READY_MASK 0xffff +#define FW_READY_MASK (0xffff & ~BIT_CPU_CLK_SEL) #define REG_MCU_TST_CFG 0x84 #define VAL_FW_TRIGGER 0x1 From 8b4a85a5d5e24b77dfdf00853b40c3d8cae39b08 Mon Sep 17 00:00:00 2001 From: Bitterblue Smith Date: Sat, 30 Nov 2024 00:08:58 +0200 Subject: [PATCH 082/193] wifi: rtw88: Extend struct rtw_pwr_track_tbl for RTL8814AU Currently this struct has the members required for chips with 2 RF paths. Add more members to support chips with 4 RF paths, like the RTL8814AU. Signed-off-by: Bitterblue Smith --- main.h | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/main.h b/main.h index c2799805..3e7ae872 100644 --- a/main.h +++ b/main.h @@ -1270,14 +1270,26 @@ struct rtw_rfe_def { * For 2G there are cck rate and ofdm rate with different settings. */ struct rtw_pwr_track_tbl { + const u8 *pwrtrk_5gd_n[RTW_PWR_TRK_5G_NUM]; + const u8 *pwrtrk_5gd_p[RTW_PWR_TRK_5G_NUM]; + const u8 *pwrtrk_5gc_n[RTW_PWR_TRK_5G_NUM]; + const u8 *pwrtrk_5gc_p[RTW_PWR_TRK_5G_NUM]; const u8 *pwrtrk_5gb_n[RTW_PWR_TRK_5G_NUM]; const u8 *pwrtrk_5gb_p[RTW_PWR_TRK_5G_NUM]; const u8 *pwrtrk_5ga_n[RTW_PWR_TRK_5G_NUM]; const u8 *pwrtrk_5ga_p[RTW_PWR_TRK_5G_NUM]; + const u8 *pwrtrk_2gd_n; + const u8 *pwrtrk_2gd_p; + const u8 *pwrtrk_2gc_n; + const u8 *pwrtrk_2gc_p; const u8 *pwrtrk_2gb_n; const u8 *pwrtrk_2gb_p; const u8 *pwrtrk_2ga_n; const u8 *pwrtrk_2ga_p; + const u8 *pwrtrk_2g_cckd_n; + const u8 *pwrtrk_2g_cckd_p; + const u8 *pwrtrk_2g_cckc_n; + const u8 *pwrtrk_2g_cckc_p; const u8 *pwrtrk_2g_cckb_n; const u8 *pwrtrk_2g_cckb_p; const u8 *pwrtrk_2g_ccka_n; From 76585e684e54b96c5ae6857f7cd1441953a7f3dc Mon Sep 17 00:00:00 2001 From: Bitterblue Smith Date: Sat, 30 Nov 2024 00:13:20 +0200 Subject: [PATCH 083/193] wifi: rtw88: Extend rf_base_addr and rf_sipi_addr for RTL8814AU These members of struct rtw_chip_info each have a size of 2. Increase their size to 4, which is the number of RF paths the RTL8814AU has. This is required to read and write the RF registers of the RTL8814AU. Signed-off-by: Bitterblue Smith --- main.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/main.h b/main.h index 3e7ae872..9bdd90e2 100644 --- a/main.h +++ b/main.h @@ -1380,8 +1380,8 @@ struct rtw_chip_info { const struct rtw_hw_reg *dig; const struct rtw_hw_reg *dig_cck; - u32 rf_base_addr[2]; - u32 rf_sipi_addr[2]; + u32 rf_base_addr[RTW_RF_PATH_MAX]; + u32 rf_sipi_addr[RTW_RF_PATH_MAX]; const struct rtw_rf_sipi_addr *rf_sipi_read_addr; u8 fix_rf_phy_num; const struct rtw_ltecoex_addr *ltecoex_addr; From be29068e08605e16cc63e0204e6f143dd2b8dda0 Mon Sep 17 00:00:00 2001 From: Bitterblue Smith Date: Fri, 20 Dec 2024 01:26:46 +0200 Subject: [PATCH 084/193] wifi: rtw88: Extend rtw_fw_send_ra_info() for RTL8814AU The existing code is suitable for chips with up to 2 spatial streams. Inform the firmware about the rates it's allowed to use when transmitting 3 spatial streams. Signed-off-by: Bitterblue Smith --- fw.c | 14 ++++++++++++++ fw.h | 1 + 2 files changed, 15 insertions(+) diff --git a/fw.c b/fw.c index 72c7f5a8..2c760e35 100644 --- a/fw.c +++ b/fw.c @@ -743,6 +743,7 @@ void rtw_fw_send_ra_info(struct rtw_dev *rtwdev, struct rtw_sta_info *si) { u8 h2c_pkt[H2C_PKT_SIZE] = {0}; bool disable_pt = true; + u32 mask_hi; #if LINUX_VERSION_CODE < KERNEL_VERSION(5, 18, 0) bool reset_ra_mask = true; #endif @@ -766,6 +767,19 @@ void rtw_fw_send_ra_info(struct rtw_dev *rtwdev, struct rtw_sta_info *si) si->init_ra_lv = 0; rtw_fw_send_h2c_command(rtwdev, h2c_pkt); + + if (rtwdev->chip->rf_tbl[RF_PATH_C]) { + SET_H2C_CMD_ID_CLASS(h2c_pkt, H2C_CMD_RA_INFO_HI); + + mask_hi = si->ra_mask >> 32; + + SET_RA_INFO_RA_MASK0(h2c_pkt, (mask_hi & 0xff)); + SET_RA_INFO_RA_MASK1(h2c_pkt, (mask_hi & 0xff00) >> 8); + SET_RA_INFO_RA_MASK2(h2c_pkt, (mask_hi & 0xff0000) >> 16); + SET_RA_INFO_RA_MASK3(h2c_pkt, (mask_hi & 0xff000000) >> 24); + + rtw_fw_send_h2c_command(rtwdev, h2c_pkt); + } } void rtw_fw_media_status_report(struct rtw_dev *rtwdev, u8 mac_id, bool connect) diff --git a/fw.h b/fw.h index a42cea5f..6215edcc 100644 --- a/fw.h +++ b/fw.h @@ -558,6 +558,7 @@ static inline void rtw_h2c_pkt_set_header(u8 *h2c_pkt, u8 sub_id) #define H2C_CMD_DEFAULT_PORT 0x2c #define H2C_CMD_RA_INFO 0x40 #define H2C_CMD_RSSI_MONITOR 0x42 +#define H2C_CMD_RA_INFO_HI 0x46 #define H2C_CMD_BCN_FILTER_OFFLOAD_P0 0x56 #define H2C_CMD_BCN_FILTER_OFFLOAD_P1 0x57 #define H2C_CMD_WL_PHY_INFO 0x58 From a041e30222440739430872b7e57a267b80b0be6d Mon Sep 17 00:00:00 2001 From: Bitterblue Smith Date: Sun, 8 Dec 2024 01:02:23 +0200 Subject: [PATCH 085/193] wifi: rtw88: Extend TX power stuff for 3-4 spatial streams Although the RTL8814AU only has 3 spatial streams, maybe some other chip has 4. Correct the TX power index and TX power limit calculations for 3SS and 4SS HT/VHT rates. With this the RTL8814AU can set the TX power correctly. Signed-off-by: Bitterblue Smith --- main.h | 4 ++ phy.c | 139 +++++++++++++++++++++++++++++++++++------------------ phy.h | 4 ++ rtw8821c.c | 2 +- rtw8822b.c | 2 +- rtw8822c.c | 2 +- rtw88xxa.c | 2 +- 7 files changed, 104 insertions(+), 51 deletions(-) diff --git a/main.h b/main.h index 9bdd90e2..7fa68119 100644 --- a/main.h +++ b/main.h @@ -303,6 +303,10 @@ enum rtw_rate_section { RTW_RATE_SECTION_HT_2S, RTW_RATE_SECTION_VHT_1S, RTW_RATE_SECTION_VHT_2S, + RTW_RATE_SECTION_HT_3S, + RTW_RATE_SECTION_HT_4S, + RTW_RATE_SECTION_VHT_3S, + RTW_RATE_SECTION_VHT_4S, /* keep last */ RTW_RATE_SECTION_MAX, diff --git a/phy.c b/phy.c index 71551cfc..b7336302 100644 --- a/phy.c +++ b/phy.c @@ -84,10 +84,36 @@ u8 rtw_vht_2s_rates[] = { DESC_RATEVHT2SS_MCS6, DESC_RATEVHT2SS_MCS7, DESC_RATEVHT2SS_MCS8, DESC_RATEVHT2SS_MCS9 }; +u8 rtw_ht_3s_rates[] = { + DESC_RATEMCS16, DESC_RATEMCS17, DESC_RATEMCS18, + DESC_RATEMCS19, DESC_RATEMCS20, DESC_RATEMCS21, + DESC_RATEMCS22, DESC_RATEMCS23 +}; +u8 rtw_ht_4s_rates[] = { + DESC_RATEMCS24, DESC_RATEMCS25, DESC_RATEMCS26, + DESC_RATEMCS27, DESC_RATEMCS28, DESC_RATEMCS29, + DESC_RATEMCS30, DESC_RATEMCS31 +}; +u8 rtw_vht_3s_rates[] = { + DESC_RATEVHT3SS_MCS0, DESC_RATEVHT3SS_MCS1, + DESC_RATEVHT3SS_MCS2, DESC_RATEVHT3SS_MCS3, + DESC_RATEVHT3SS_MCS4, DESC_RATEVHT3SS_MCS5, + DESC_RATEVHT3SS_MCS6, DESC_RATEVHT3SS_MCS7, + DESC_RATEVHT3SS_MCS8, DESC_RATEVHT3SS_MCS9 +}; +u8 rtw_vht_4s_rates[] = { + DESC_RATEVHT4SS_MCS0, DESC_RATEVHT4SS_MCS1, + DESC_RATEVHT4SS_MCS2, DESC_RATEVHT4SS_MCS3, + DESC_RATEVHT4SS_MCS4, DESC_RATEVHT4SS_MCS5, + DESC_RATEVHT4SS_MCS6, DESC_RATEVHT4SS_MCS7, + DESC_RATEVHT4SS_MCS8, DESC_RATEVHT4SS_MCS9 +}; u8 *rtw_rate_section[RTW_RATE_SECTION_MAX] = { rtw_cck_rates, rtw_ofdm_rates, rtw_ht_1s_rates, rtw_ht_2s_rates, - rtw_vht_1s_rates, rtw_vht_2s_rates + rtw_vht_1s_rates, rtw_vht_2s_rates, + rtw_ht_3s_rates, rtw_ht_4s_rates, + rtw_vht_3s_rates, rtw_vht_4s_rates }; EXPORT_SYMBOL(rtw_rate_section); @@ -97,17 +123,14 @@ u8 rtw_rate_size[RTW_RATE_SECTION_MAX] = { ARRAY_SIZE(rtw_ht_1s_rates), ARRAY_SIZE(rtw_ht_2s_rates), ARRAY_SIZE(rtw_vht_1s_rates), - ARRAY_SIZE(rtw_vht_2s_rates) + ARRAY_SIZE(rtw_vht_2s_rates), + ARRAY_SIZE(rtw_ht_3s_rates), + ARRAY_SIZE(rtw_ht_4s_rates), + ARRAY_SIZE(rtw_vht_3s_rates), + ARRAY_SIZE(rtw_vht_4s_rates) }; EXPORT_SYMBOL(rtw_rate_size); -static const u8 rtw_cck_size = ARRAY_SIZE(rtw_cck_rates); -static const u8 rtw_ofdm_size = ARRAY_SIZE(rtw_ofdm_rates); -static const u8 rtw_ht_1s_size = ARRAY_SIZE(rtw_ht_1s_rates); -static const u8 rtw_ht_2s_size = ARRAY_SIZE(rtw_ht_2s_rates); -static const u8 rtw_vht_1s_size = ARRAY_SIZE(rtw_vht_1s_rates); -static const u8 rtw_vht_2s_size = ARRAY_SIZE(rtw_vht_2s_rates); - enum rtw_phy_band_type { PHY_BAND_2G = 0, PHY_BAND_5G = 1, @@ -1640,10 +1663,12 @@ static void rtw_xref_txpwr_lmt_by_rs(struct rtw_dev *rtwdev, u8 regd, u8 bw, u8 ch_idx) { u8 rs_idx, rs_ht, rs_vht; - u8 rs_cmp[2][2] = {{RTW_RATE_SECTION_HT_1S, RTW_RATE_SECTION_VHT_1S}, - {RTW_RATE_SECTION_HT_2S, RTW_RATE_SECTION_VHT_2S} }; + u8 rs_cmp[4][2] = {{RTW_RATE_SECTION_HT_1S, RTW_RATE_SECTION_VHT_1S}, + {RTW_RATE_SECTION_HT_2S, RTW_RATE_SECTION_VHT_2S}, + {RTW_RATE_SECTION_HT_3S, RTW_RATE_SECTION_VHT_3S}, + {RTW_RATE_SECTION_HT_4S, RTW_RATE_SECTION_VHT_4S} }; - for (rs_idx = 0; rs_idx < 2; rs_idx++) { + for (rs_idx = 0; rs_idx < 4; rs_idx++) { rs_ht = rs_cmp[rs_idx][0]; rs_vht = rs_cmp[rs_idx][1]; @@ -1973,10 +1998,10 @@ static u8 rtw_phy_get_2g_tx_power_index(struct rtw_dev *rtwdev, u8 rate, u8 group) { const struct rtw_chip_info *chip = rtwdev->chip; - u8 tx_power; - bool mcs_rate; - bool above_2ss; + bool above_2ss, above_3ss, above_4ss; u8 factor = chip->txgi_factor; + bool mcs_rate; + u8 tx_power; if (rate <= DESC_RATE11M) tx_power = pwr_idx_2g->cck_base[group]; @@ -1986,11 +2011,15 @@ static u8 rtw_phy_get_2g_tx_power_index(struct rtw_dev *rtwdev, if (rate >= DESC_RATE6M && rate <= DESC_RATE54M) tx_power += pwr_idx_2g->ht_1s_diff.ofdm * factor; - mcs_rate = (rate >= DESC_RATEMCS0 && rate <= DESC_RATEMCS15) || + mcs_rate = (rate >= DESC_RATEMCS0 && rate <= DESC_RATEMCS31) || (rate >= DESC_RATEVHT1SS_MCS0 && - rate <= DESC_RATEVHT2SS_MCS9); - above_2ss = (rate >= DESC_RATEMCS8 && rate <= DESC_RATEMCS15) || + rate <= DESC_RATEVHT4SS_MCS9); + above_2ss = (rate >= DESC_RATEMCS8 && rate <= DESC_RATEMCS31) || (rate >= DESC_RATEVHT2SS_MCS0); + above_3ss = (rate >= DESC_RATEMCS16 && rate <= DESC_RATEMCS31) || + (rate >= DESC_RATEVHT3SS_MCS0); + above_4ss = (rate >= DESC_RATEMCS24 && rate <= DESC_RATEMCS31) || + (rate >= DESC_RATEVHT4SS_MCS0); if (!mcs_rate) return tx_power; @@ -2003,11 +2032,19 @@ static u8 rtw_phy_get_2g_tx_power_index(struct rtw_dev *rtwdev, tx_power += pwr_idx_2g->ht_1s_diff.bw20 * factor; if (above_2ss) tx_power += pwr_idx_2g->ht_2s_diff.bw20 * factor; + if (above_3ss) + tx_power += pwr_idx_2g->ht_3s_diff.bw20 * factor; + if (above_4ss) + tx_power += pwr_idx_2g->ht_4s_diff.bw20 * factor; break; case RTW_CHANNEL_WIDTH_40: /* bw40 is the base power */ if (above_2ss) tx_power += pwr_idx_2g->ht_2s_diff.bw40 * factor; + if (above_3ss) + tx_power += pwr_idx_2g->ht_3s_diff.bw40 * factor; + if (above_4ss) + tx_power += pwr_idx_2g->ht_4s_diff.bw40 * factor; break; } @@ -2020,19 +2057,23 @@ static u8 rtw_phy_get_5g_tx_power_index(struct rtw_dev *rtwdev, u8 rate, u8 group) { const struct rtw_chip_info *chip = rtwdev->chip; - u8 tx_power; + bool above_2ss, above_3ss, above_4ss; + u8 factor = chip->txgi_factor; u8 upper, lower; bool mcs_rate; - bool above_2ss; - u8 factor = chip->txgi_factor; + u8 tx_power; tx_power = pwr_idx_5g->bw40_base[group]; - mcs_rate = (rate >= DESC_RATEMCS0 && rate <= DESC_RATEMCS15) || + mcs_rate = (rate >= DESC_RATEMCS0 && rate <= DESC_RATEMCS31) || (rate >= DESC_RATEVHT1SS_MCS0 && - rate <= DESC_RATEVHT2SS_MCS9); - above_2ss = (rate >= DESC_RATEMCS8 && rate <= DESC_RATEMCS15) || + rate <= DESC_RATEVHT4SS_MCS9); + above_2ss = (rate >= DESC_RATEMCS8 && rate <= DESC_RATEMCS31) || (rate >= DESC_RATEVHT2SS_MCS0); + above_3ss = (rate >= DESC_RATEMCS16 && rate <= DESC_RATEMCS31) || + (rate >= DESC_RATEVHT3SS_MCS0); + above_4ss = (rate >= DESC_RATEMCS24 && rate <= DESC_RATEMCS31) || + (rate >= DESC_RATEVHT4SS_MCS0); if (!mcs_rate) { tx_power += pwr_idx_5g->ht_1s_diff.ofdm * factor; @@ -2047,11 +2088,19 @@ static u8 rtw_phy_get_5g_tx_power_index(struct rtw_dev *rtwdev, tx_power += pwr_idx_5g->ht_1s_diff.bw20 * factor; if (above_2ss) tx_power += pwr_idx_5g->ht_2s_diff.bw20 * factor; + if (above_3ss) + tx_power += pwr_idx_5g->ht_3s_diff.bw20 * factor; + if (above_4ss) + tx_power += pwr_idx_5g->ht_4s_diff.bw20 * factor; break; case RTW_CHANNEL_WIDTH_40: /* bw40 is the base power */ if (above_2ss) tx_power += pwr_idx_5g->ht_2s_diff.bw40 * factor; + if (above_3ss) + tx_power += pwr_idx_5g->ht_3s_diff.bw40 * factor; + if (above_4ss) + tx_power += pwr_idx_5g->ht_4s_diff.bw40 * factor; break; case RTW_CHANNEL_WIDTH_80: /* the base idx of bw80 is the average of bw40+/bw40- */ @@ -2062,6 +2111,10 @@ static u8 rtw_phy_get_5g_tx_power_index(struct rtw_dev *rtwdev, tx_power += pwr_idx_5g->vht_1s_diff.bw80 * factor; if (above_2ss) tx_power += pwr_idx_5g->vht_2s_diff.bw80 * factor; + if (above_3ss) + tx_power += pwr_idx_5g->vht_3s_diff.bw80 * factor; + if (above_4ss) + tx_power += pwr_idx_5g->vht_4s_diff.bw80 * factor; break; } @@ -2079,10 +2132,18 @@ static u8 rtw_phy_rate_to_rate_section(u8 rate) return RTW_RATE_SECTION_HT_1S; else if (rate >= DESC_RATEMCS8 && rate <= DESC_RATEMCS15) return RTW_RATE_SECTION_HT_2S; + else if (rate >= DESC_RATEMCS16 && rate <= DESC_RATEMCS23) + return RTW_RATE_SECTION_HT_3S; + else if (rate >= DESC_RATEMCS24 && rate <= DESC_RATEMCS31) + return RTW_RATE_SECTION_HT_4S; else if (rate >= DESC_RATEVHT1SS_MCS0 && rate <= DESC_RATEVHT1SS_MCS9) return RTW_RATE_SECTION_VHT_1S; else if (rate >= DESC_RATEVHT2SS_MCS0 && rate <= DESC_RATEVHT2SS_MCS9) return RTW_RATE_SECTION_VHT_2S; + else if (rate >= DESC_RATEVHT3SS_MCS0 && rate <= DESC_RATEVHT3SS_MCS9) + return RTW_RATE_SECTION_VHT_3S; + else if (rate >= DESC_RATEVHT4SS_MCS0 && rate <= DESC_RATEVHT4SS_MCS9) + return RTW_RATE_SECTION_VHT_4S; else return RTW_RATE_SECTION_MAX; } @@ -2110,7 +2171,7 @@ static s8 rtw_phy_get_tx_power_limit(struct rtw_dev *rtwdev, u8 band, bw = RTW_CHANNEL_WIDTH_20; /* only 20/40M BW with ht */ - if (rs == RTW_RATE_SECTION_HT_1S || rs == RTW_RATE_SECTION_HT_2S) + if (rate >= DESC_RATEMCS0 && rate <= DESC_RATEMCS31) bw = min_t(u8, bw, RTW_CHANNEL_WIDTH_40); /* select min power limit among [20M BW ~ current BW] */ @@ -2300,7 +2361,7 @@ rtw_phy_tx_power_by_rate_config_by_path(struct rtw_hal *hal, u8 path, u8 base_idx, rate_idx; s8 base_2g, base_5g; - if (rs >= RTW_RATE_SECTION_VHT_1S) + if (size == 10) /* VHT rates */ base_idx = rates[size - 3]; else base_idx = rates[size - 1]; @@ -2317,28 +2378,12 @@ rtw_phy_tx_power_by_rate_config_by_path(struct rtw_hal *hal, u8 path, void rtw_phy_tx_power_by_rate_config(struct rtw_hal *hal) { - u8 path; + u8 path, rs; - for (path = 0; path < RTW_RF_PATH_MAX; path++) { - rtw_phy_tx_power_by_rate_config_by_path(hal, path, - RTW_RATE_SECTION_CCK, - rtw_cck_size, rtw_cck_rates); - rtw_phy_tx_power_by_rate_config_by_path(hal, path, - RTW_RATE_SECTION_OFDM, - rtw_ofdm_size, rtw_ofdm_rates); - rtw_phy_tx_power_by_rate_config_by_path(hal, path, - RTW_RATE_SECTION_HT_1S, - rtw_ht_1s_size, rtw_ht_1s_rates); - rtw_phy_tx_power_by_rate_config_by_path(hal, path, - RTW_RATE_SECTION_HT_2S, - rtw_ht_2s_size, rtw_ht_2s_rates); - rtw_phy_tx_power_by_rate_config_by_path(hal, path, - RTW_RATE_SECTION_VHT_1S, - rtw_vht_1s_size, rtw_vht_1s_rates); - rtw_phy_tx_power_by_rate_config_by_path(hal, path, - RTW_RATE_SECTION_VHT_2S, - rtw_vht_2s_size, rtw_vht_2s_rates); - } + for (path = 0; path < RTW_RF_PATH_MAX; path++) + for (rs = 0; rs < RTW_RATE_SECTION_MAX; rs++) + rtw_phy_tx_power_by_rate_config_by_path(hal, path, rs, + rtw_rate_size[rs], rtw_rate_section[rs]); } static void diff --git a/phy.h b/phy.h index ccfcbd3c..707576d0 100644 --- a/phy.h +++ b/phy.h @@ -13,6 +13,10 @@ extern u8 rtw_ht_1s_rates[]; extern u8 rtw_ht_2s_rates[]; extern u8 rtw_vht_1s_rates[]; extern u8 rtw_vht_2s_rates[]; +extern u8 rtw_ht_3s_rates[]; +extern u8 rtw_ht_4s_rates[]; +extern u8 rtw_vht_3s_rates[]; +extern u8 rtw_vht_4s_rates[]; extern u8 *rtw_rate_section[]; extern u8 rtw_rate_size[]; diff --git a/rtw8821c.c b/rtw8821c.c index b80f61bd..eb2c6d7d 100644 --- a/rtw8821c.c +++ b/rtw8821c.c @@ -709,7 +709,7 @@ static void rtw8821c_set_tx_power_index(struct rtw_dev *rtwdev) int rs, path; for (path = 0; path < hal->rf_path_num; path++) { - for (rs = 0; rs < RTW_RATE_SECTION_MAX; rs++) { + for (rs = 0; rs < RTW_RATE_SECTION_HT_3S; rs++) { if (rs == RTW_RATE_SECTION_HT_2S || rs == RTW_RATE_SECTION_VHT_2S) continue; diff --git a/rtw8822b.c b/rtw8822b.c index 65c117ff..982952b8 100644 --- a/rtw8822b.c +++ b/rtw8822b.c @@ -963,7 +963,7 @@ static void rtw8822b_set_tx_power_index(struct rtw_dev *rtwdev) int rs, path; for (path = 0; path < hal->rf_path_num; path++) { - for (rs = 0; rs < RTW_RATE_SECTION_MAX; rs++) + for (rs = 0; rs < RTW_RATE_SECTION_HT_3S; rs++) rtw8822b_set_tx_power_index_by_rate(rtwdev, path, rs); } } diff --git a/rtw8822c.c b/rtw8822c.c index 545b91fe..005a0c3d 100644 --- a/rtw8822c.c +++ b/rtw8822c.c @@ -2746,7 +2746,7 @@ static void rtw8822c_set_tx_power_index(struct rtw_dev *rtwdev) s8 diff_idx[4]; rtw8822c_set_write_tx_power_ref(rtwdev, pwr_ref_cck, pwr_ref_ofdm); - for (rs = 0; rs < RTW_RATE_SECTION_MAX; rs++) { + for (rs = 0; rs < RTW_RATE_SECTION_HT_3S; rs++) { for (j = 0; j < rtw_rate_size[rs]; j++) { rate = rtw_rate_section[rs][j]; pwr_a = hal->tx_pwr_tbl[RF_PATH_A][rate]; diff --git a/rtw88xxa.c b/rtw88xxa.c index 71e61b9c..08bbd847 100644 --- a/rtw88xxa.c +++ b/rtw88xxa.c @@ -1637,7 +1637,7 @@ void rtw88xxa_set_tx_power_index(struct rtw_dev *rtwdev) int rs, path; for (path = 0; path < hal->rf_path_num; path++) { - for (rs = 0; rs < RTW_RATE_SECTION_MAX; rs++) { + for (rs = 0; rs < RTW_RATE_SECTION_HT_3S; rs++) { if (hal->rf_path_num == 1 && (rs == RTW_RATE_SECTION_HT_2S || rs == RTW_RATE_SECTION_VHT_2S)) From c11b4778cbaa5d31e9e0f57daca1b94075f45d3e Mon Sep 17 00:00:00 2001 From: Bitterblue Smith Date: Fri, 20 Dec 2024 01:41:34 +0200 Subject: [PATCH 086/193] wifi: rtw88: Fix rtw_update_sta_info() for RTL8814AU This function tells the firmware what rates it can use. Put the 3SS and 4SS HT rates supported by the other station into the rate mask. Remove the 3SS and 4SS rates from the rate mask if the hardware only has 2 spatial streams. And finally, select the right rate ID (a parameter for the firmware) when the hardware has 3 spatial streams. Signed-off-by: Bitterblue Smith --- main.c | 25 ++++++++++++++----------- 1 file changed, 14 insertions(+), 11 deletions(-) diff --git a/main.c b/main.c index a347b625..18694588 100644 --- a/main.c +++ b/main.c @@ -1261,7 +1261,9 @@ void rtw_update_sta_info(struct rtw_dev *rtwdev, struct rtw_sta_info *si, ldpc_en = VHT_LDPC_EN; #if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 19, 0) } else if (sta->deflink.ht_cap.ht_supported) { - ra_mask |= (sta->deflink.ht_cap.mcs.rx_mask[1] << 20) | + ra_mask |= ((u64)sta->deflink.ht_cap.mcs.rx_mask[3] << 36) | + ((u64)sta->deflink.ht_cap.mcs.rx_mask[2] << 28) | + (sta->deflink.ht_cap.mcs.rx_mask[1] << 20) | (sta->deflink.ht_cap.mcs.rx_mask[0] << 12); if (sta->deflink.ht_cap.cap & IEEE80211_HT_CAP_RX_STBC) stbc_en = HT_STBC_EN; @@ -1269,7 +1271,9 @@ void rtw_update_sta_info(struct rtw_dev *rtwdev, struct rtw_sta_info *si, ldpc_en = HT_LDPC_EN; #else } else if (sta->ht_cap.ht_supported) { - ra_mask |= (sta->ht_cap.mcs.rx_mask[1] << 20) | + ra_mask |= ((u64)sta->ht_cap.mcs.rx_mask[3] << 36) | + ((u64)sta->ht_cap.mcs.rx_mask[2] << 28) | + (sta->ht_cap.mcs.rx_mask[1] << 20) | (sta->ht_cap.mcs.rx_mask[0] << 12); if (sta->ht_cap.cap & IEEE80211_HT_CAP_RX_STBC) stbc_en = HT_STBC_EN; @@ -1280,6 +1284,9 @@ void rtw_update_sta_info(struct rtw_dev *rtwdev, struct rtw_sta_info *si, if (efuse->hw_cap.nss == 1 || rtwdev->hal.txrx_1ss) ra_mask &= RA_MASK_VHT_RATES_1SS | RA_MASK_HT_RATES_1SS; + else if (efuse->hw_cap.nss == 2) + ra_mask &= RA_MASK_VHT_RATES_2SS | RA_MASK_HT_RATES_2SS | + RA_MASK_VHT_RATES_1SS | RA_MASK_HT_RATES_1SS; if (hal->current_band_type == RTW_BAND_5G) { #if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 19, 0) @@ -1386,17 +1393,13 @@ void rtw_update_sta_info(struct rtw_dev *rtwdev, struct rtw_sta_info *si, } #if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 19, 0) - if (sta->deflink.vht_cap.vht_supported && ra_mask & 0xffc00000) + if (sta->deflink.vht_cap.vht_supported || + sta->deflink.ht_cap.ht_supported) #else - if (sta->vht_cap.vht_supported && ra_mask & 0xffc00000) + if (sta->vht_cap.vht_supported || + sta->ht_cap.ht_supported) #endif - tx_num = 2; -#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 19, 0) - else if (sta->deflink.ht_cap.ht_supported && ra_mask & 0xfff00000) -#else - else if (sta->ht_cap.ht_supported && ra_mask & 0xfff00000) -#endif - tx_num = 2; + tx_num = efuse->hw_cap.nss; rate_id = get_rate_id(wireless_set, bw_mode, tx_num); From bccf1ee8507068d32d6b0a99832a133cd104c7f1 Mon Sep 17 00:00:00 2001 From: Bitterblue Smith Date: Sun, 8 Dec 2024 22:48:08 +0200 Subject: [PATCH 087/193] wifi: rtw88: Fix rtw_desc_to_mcsrate() to handle MCS16-31 This function translates the rate number reported by the hardware into something mac80211 can understand. It was ignoring the 3SS and 4SS HT rates. Signed-off-by: Bitterblue Smith --- util.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/util.c b/util.c index e222d3c0..ba02ba72 100644 --- a/util.c +++ b/util.c @@ -101,7 +101,7 @@ void rtw_desc_to_mcsrate(u16 rate, u8 *mcs, u8 *nss) *nss = 4; *mcs = rate - DESC_RATEVHT4SS_MCS0; } else if (rate >= DESC_RATEMCS0 && - rate <= DESC_RATEMCS15) { + rate <= DESC_RATEMCS31) { *mcs = rate - DESC_RATEMCS0; } } From 9cd350f67237e779ea8204307ebebbb8db3196a6 Mon Sep 17 00:00:00 2001 From: Bitterblue Smith Date: Sun, 8 Dec 2024 23:25:02 +0200 Subject: [PATCH 088/193] wifi: rtw88: Fix rtw_init_ht_cap() for RTL8814AU Set the RX mask and the highest RX rate according to the number of spatial streams the chip can receive. For RTL8814AU that is 3. Signed-off-by: Bitterblue Smith --- main.c | 17 ++++++----------- 1 file changed, 6 insertions(+), 11 deletions(-) diff --git a/main.c b/main.c index 18694588..3ec47919 100644 --- a/main.c +++ b/main.c @@ -1659,6 +1659,7 @@ static void rtw_init_ht_cap(struct rtw_dev *rtwdev, { const struct rtw_chip_info *chip = rtwdev->chip; struct rtw_efuse *efuse = &rtwdev->efuse; + int i; ht_cap->ht_supported = true; ht_cap->cap = 0; @@ -1678,17 +1679,11 @@ static void rtw_init_ht_cap(struct rtw_dev *rtwdev, ht_cap->ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K; ht_cap->ampdu_density = chip->ampdu_density; ht_cap->mcs.tx_params = IEEE80211_HT_MCS_TX_DEFINED; - if (efuse->hw_cap.nss > 1) { - ht_cap->mcs.rx_mask[0] = 0xFF; - ht_cap->mcs.rx_mask[1] = 0xFF; - ht_cap->mcs.rx_mask[4] = 0x01; - ht_cap->mcs.rx_highest = cpu_to_le16(300); - } else { - ht_cap->mcs.rx_mask[0] = 0xFF; - ht_cap->mcs.rx_mask[1] = 0x00; - ht_cap->mcs.rx_mask[4] = 0x01; - ht_cap->mcs.rx_highest = cpu_to_le16(150); - } + + for (i = 0; i < efuse->hw_cap.nss; i++) + ht_cap->mcs.rx_mask[i] = 0xFF; + ht_cap->mcs.rx_mask[4] = 0x01; + ht_cap->mcs.rx_highest = cpu_to_le16(150 * efuse->hw_cap.nss); } static void rtw_init_vht_cap(struct rtw_dev *rtwdev, From 9cd2105d3c63bc40dbac5cbc6d96965e01a6f1b9 Mon Sep 17 00:00:00 2001 From: Bitterblue Smith Date: Sun, 8 Dec 2024 23:28:25 +0200 Subject: [PATCH 089/193] wifi: rtw88: Fix rtw_init_vht_cap() for RTL8814AU Set the MCS maps and the highest rates according to the number of spatial streams the chip has. For RTL8814AU that is 3. Signed-off-by: Bitterblue Smith --- main.c | 23 +++++++++-------------- 1 file changed, 9 insertions(+), 14 deletions(-) diff --git a/main.c b/main.c index 3ec47919..d9407ac4 100644 --- a/main.c +++ b/main.c @@ -1690,8 +1690,9 @@ static void rtw_init_vht_cap(struct rtw_dev *rtwdev, struct ieee80211_sta_vht_cap *vht_cap) { struct rtw_efuse *efuse = &rtwdev->efuse; - u16 mcs_map; + u16 mcs_map = 0; __le16 highest; + int i; if (efuse->hw_cap.ptcl != EFUSE_HW_CAP_IGNORE && efuse->hw_cap.ptcl != EFUSE_HW_CAP_PTCL_VHT) @@ -1714,21 +1715,15 @@ static void rtw_init_vht_cap(struct rtw_dev *rtwdev, if (rtw_chip_has_rx_ldpc(rtwdev)) vht_cap->cap |= IEEE80211_VHT_CAP_RXLDPC; - mcs_map = IEEE80211_VHT_MCS_SUPPORT_0_9 << 0 | - IEEE80211_VHT_MCS_NOT_SUPPORTED << 4 | - IEEE80211_VHT_MCS_NOT_SUPPORTED << 6 | - IEEE80211_VHT_MCS_NOT_SUPPORTED << 8 | - IEEE80211_VHT_MCS_NOT_SUPPORTED << 10 | - IEEE80211_VHT_MCS_NOT_SUPPORTED << 12 | - IEEE80211_VHT_MCS_NOT_SUPPORTED << 14; - if (efuse->hw_cap.nss > 1) { - highest = cpu_to_le16(780); - mcs_map |= IEEE80211_VHT_MCS_SUPPORT_0_9 << 2; - } else { - highest = cpu_to_le16(390); - mcs_map |= IEEE80211_VHT_MCS_NOT_SUPPORTED << 2; + for (i = 0; i < 8; i++) { + if (i < efuse->hw_cap.nss) + mcs_map |= IEEE80211_VHT_MCS_SUPPORT_0_9 << (i * 2); + else + mcs_map |= IEEE80211_VHT_MCS_NOT_SUPPORTED << (i * 2); } + highest = cpu_to_le16(390 * efuse->hw_cap.nss); + vht_cap->vht_mcs.rx_mcs_map = cpu_to_le16(mcs_map); vht_cap->vht_mcs.tx_mcs_map = cpu_to_le16(mcs_map); vht_cap->vht_mcs.rx_highest = highest; From 99943643a933d520447e8649f6ceee89a255fc08 Mon Sep 17 00:00:00 2001 From: Bitterblue Smith Date: Mon, 9 Dec 2024 17:16:18 +0200 Subject: [PATCH 090/193] wifi: rtw88: Fix rtw_rx_phy_stat() for RTL8814AU Record statistics for the 3SS rates too. Signed-off-by: Bitterblue Smith --- main.h | 7 +++++++ rx.c | 6 ++++++ 2 files changed, 13 insertions(+) diff --git a/main.h b/main.h index 7fa68119..d5aa1261 100644 --- a/main.h +++ b/main.h @@ -522,6 +522,9 @@ enum rtw_evm { RTW_EVM_1SS, RTW_EVM_2SS_A, RTW_EVM_2SS_B, + RTW_EVM_3SS_A, + RTW_EVM_3SS_B, + RTW_EVM_3SS_C, /* keep it last */ RTW_EVM_NUM }; @@ -539,6 +542,10 @@ enum rtw_snr { RTW_SNR_2SS_B, RTW_SNR_2SS_C, RTW_SNR_2SS_D, + RTW_SNR_3SS_A, + RTW_SNR_3SS_B, + RTW_SNR_3SS_C, + RTW_SNR_3SS_D, /* keep it last */ RTW_SNR_NUM }; diff --git a/rx.c b/rx.c index 06a94157..123b47e4 100644 --- a/rx.c +++ b/rx.c @@ -73,6 +73,12 @@ static void rtw_rx_phy_stat(struct rtw_dev *rtwdev, rate_ss_evm = 2; evm_id = RTW_EVM_2SS_A; break; + case DESC_RATEMCS16...DESC_RATEMCS23: + case DESC_RATEVHT3SS_MCS0...DESC_RATEVHT3SS_MCS9: + rate_ss = 3; + rate_ss_evm = 3; + evm_id = RTW_EVM_3SS_A; + break; default: rtw_warn(rtwdev, "unknown pkt rate = %d\n", pkt_stat->rate); return; From 66b36888620b099088c9aae1888121109953617b Mon Sep 17 00:00:00 2001 From: Bitterblue Smith Date: Sat, 7 Dec 2024 03:02:03 +0200 Subject: [PATCH 091/193] wifi: rtw88: Extend rtw_debugfs_get_phy_info() for RTL8814AU Print information about the 3rd and 4th RF paths and about the 3rd spatial stream. Also, fix a small bug: don't show the average SNR and EVM for the OFDM and HT/VHT rates when the rate is actually CCK 11M. Signed-off-by: Bitterblue Smith --- debug.c | 37 ++++++++++++++++++++++++++----------- 1 file changed, 26 insertions(+), 11 deletions(-) diff --git a/debug.c b/debug.c index 364ec043..1adb03d1 100644 --- a/debug.c +++ b/debug.c @@ -654,10 +654,10 @@ static void rtw_print_rate(struct seq_file *m, u8 rate) case DESC_RATE6M...DESC_RATE54M: rtw_print_ofdm_rate_txt(m, rate); break; - case DESC_RATEMCS0...DESC_RATEMCS15: + case DESC_RATEMCS0...DESC_RATEMCS31: rtw_print_ht_rate_txt(m, rate); break; - case DESC_RATEVHT1SS_MCS0...DESC_RATEVHT2SS_MCS9: + case DESC_RATEVHT1SS_MCS0...DESC_RATEVHT4SS_MCS9: rtw_print_vht_rate_txt(m, rate); break; default: @@ -849,20 +849,28 @@ static int rtw_debugfs_get_phy_info(struct seq_file *m, void *v) last_cnt->num_qry_pkt[rate_id + 9]); } - seq_printf(m, "[RSSI(dBm)] = {%d, %d}\n", + seq_printf(m, "[RSSI(dBm)] = {%d, %d, %d, %d}\n", dm_info->rssi[RF_PATH_A] - 100, - dm_info->rssi[RF_PATH_B] - 100); - seq_printf(m, "[Rx EVM(dB)] = {-%d, -%d}\n", + dm_info->rssi[RF_PATH_B] - 100, + dm_info->rssi[RF_PATH_C] - 100, + dm_info->rssi[RF_PATH_D] - 100); + seq_printf(m, "[Rx EVM(dB)] = {-%d, -%d, -%d, -%d}\n", dm_info->rx_evm_dbm[RF_PATH_A], - dm_info->rx_evm_dbm[RF_PATH_B]); - seq_printf(m, "[Rx SNR] = {%d, %d}\n", + dm_info->rx_evm_dbm[RF_PATH_B], + dm_info->rx_evm_dbm[RF_PATH_C], + dm_info->rx_evm_dbm[RF_PATH_D]); + seq_printf(m, "[Rx SNR] = {%d, %d, %d, %d}\n", dm_info->rx_snr[RF_PATH_A], - dm_info->rx_snr[RF_PATH_B]); - seq_printf(m, "[CFO_tail(KHz)] = {%d, %d}\n", + dm_info->rx_snr[RF_PATH_B], + dm_info->rx_snr[RF_PATH_C], + dm_info->rx_snr[RF_PATH_D]); + seq_printf(m, "[CFO_tail(KHz)] = {%d, %d, %d, %d}\n", dm_info->cfo_tail[RF_PATH_A], - dm_info->cfo_tail[RF_PATH_B]); + dm_info->cfo_tail[RF_PATH_B], + dm_info->cfo_tail[RF_PATH_C], + dm_info->cfo_tail[RF_PATH_D]); - if (dm_info->curr_rx_rate >= DESC_RATE11M) { + if (dm_info->curr_rx_rate >= DESC_RATE6M) { seq_puts(m, "[Rx Average Status]:\n"); seq_printf(m, " * OFDM, EVM: {-%d}, SNR: {%d}\n", (u8)ewma_evm_read(&ewma_evm[RTW_EVM_OFDM]), @@ -875,6 +883,13 @@ static int rtw_debugfs_get_phy_info(struct seq_file *m, void *v) (u8)ewma_evm_read(&ewma_evm[RTW_EVM_2SS_B]), (u8)ewma_snr_read(&ewma_snr[RTW_SNR_2SS_A]), (u8)ewma_snr_read(&ewma_snr[RTW_SNR_2SS_B])); + seq_printf(m, " * 3SS, EVM: {-%d, -%d, -%d}, SNR: {%d, %d, %d}\n", + (u8)ewma_evm_read(&ewma_evm[RTW_EVM_3SS_A]), + (u8)ewma_evm_read(&ewma_evm[RTW_EVM_3SS_B]), + (u8)ewma_evm_read(&ewma_evm[RTW_EVM_3SS_C]), + (u8)ewma_snr_read(&ewma_snr[RTW_SNR_3SS_A]), + (u8)ewma_snr_read(&ewma_snr[RTW_SNR_3SS_B]), + (u8)ewma_snr_read(&ewma_snr[RTW_SNR_3SS_C])); } seq_puts(m, "[Rx Counter]:\n"); From 2868597436b96e375863ce3fa54ad7bf8a5ff028 Mon Sep 17 00:00:00 2001 From: Bitterblue Smith Date: Tue, 17 Dec 2024 23:27:47 +0200 Subject: [PATCH 092/193] wifi: rtw88: Extend rtw_debugfs_get_tx_pwr_tbl() for RTL8814AU Make it print the TX power details for RF paths C and D, and for 3SS and 4SS rates. Signed-off-by: Bitterblue Smith --- debug.c | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/debug.c b/debug.c index 1adb03d1..0efb5c19 100644 --- a/debug.c +++ b/debug.c @@ -708,20 +708,14 @@ static int rtw_debugfs_get_tx_pwr_tbl(struct seq_file *m, void *v) "path", "rate", "pwr", "base", "byr", "lmt", "sar", "rem"); mutex_lock(&hal->tx_power_mutex); - for (path = RF_PATH_A; path <= RF_PATH_B; path++) { + for (path = RF_PATH_A; path <= RF_PATH_D; path++) { /* there is no CCK rates used in 5G */ if (hal->current_band_type == RTW_BAND_5G) rate = DESC_RATE6M; else rate = DESC_RATE1M; - /* now, not support vht 3ss and vht 4ss*/ - for (; rate <= DESC_RATEVHT2SS_MCS9; rate++) { - /* now, not support ht 3ss and ht 4ss*/ - if (rate > DESC_RATEMCS15 && - rate < DESC_RATEVHT1SS_MCS0) - continue; - + for (; rate <= DESC_RATEVHT4SS_MCS9; rate++) { rtw_get_tx_power_params(rtwdev, path, rate, bw, ch, regd, &pwr_param); From 17e8cc634f37dd2122e0164dc6a819153a917f0b Mon Sep 17 00:00:00 2001 From: Bitterblue Smith Date: Fri, 13 Dec 2024 02:18:27 +0200 Subject: [PATCH 093/193] wifi: rtw88: Extend rtw_phy_config_swing_table() for RTL8814AU Select the TX power tracking tables for RF paths C and D as well. Signed-off-by: Bitterblue Smith --- phy.c | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/phy.c b/phy.c index b7336302..a4c51cd3 100644 --- a/phy.c +++ b/phy.c @@ -2466,32 +2466,56 @@ void rtw_phy_config_swing_table(struct rtw_dev *rtwdev, swing_table->n[RF_PATH_A] = tbl->pwrtrk_2g_ccka_n; swing_table->p[RF_PATH_B] = tbl->pwrtrk_2g_cckb_p; swing_table->n[RF_PATH_B] = tbl->pwrtrk_2g_cckb_n; + swing_table->p[RF_PATH_C] = tbl->pwrtrk_2g_cckc_p; + swing_table->n[RF_PATH_C] = tbl->pwrtrk_2g_cckc_n; + swing_table->p[RF_PATH_D] = tbl->pwrtrk_2g_cckd_p; + swing_table->n[RF_PATH_D] = tbl->pwrtrk_2g_cckd_n; } else { swing_table->p[RF_PATH_A] = tbl->pwrtrk_2ga_p; swing_table->n[RF_PATH_A] = tbl->pwrtrk_2ga_n; swing_table->p[RF_PATH_B] = tbl->pwrtrk_2gb_p; swing_table->n[RF_PATH_B] = tbl->pwrtrk_2gb_n; + swing_table->p[RF_PATH_C] = tbl->pwrtrk_2gc_p; + swing_table->n[RF_PATH_C] = tbl->pwrtrk_2gc_n; + swing_table->p[RF_PATH_D] = tbl->pwrtrk_2gd_p; + swing_table->n[RF_PATH_D] = tbl->pwrtrk_2gd_n; } } else if (IS_CH_5G_BAND_1(channel) || IS_CH_5G_BAND_2(channel)) { swing_table->p[RF_PATH_A] = tbl->pwrtrk_5ga_p[RTW_PWR_TRK_5G_1]; swing_table->n[RF_PATH_A] = tbl->pwrtrk_5ga_n[RTW_PWR_TRK_5G_1]; swing_table->p[RF_PATH_B] = tbl->pwrtrk_5gb_p[RTW_PWR_TRK_5G_1]; swing_table->n[RF_PATH_B] = tbl->pwrtrk_5gb_n[RTW_PWR_TRK_5G_1]; + swing_table->p[RF_PATH_C] = tbl->pwrtrk_5gc_p[RTW_PWR_TRK_5G_1]; + swing_table->n[RF_PATH_C] = tbl->pwrtrk_5gc_n[RTW_PWR_TRK_5G_1]; + swing_table->p[RF_PATH_D] = tbl->pwrtrk_5gd_p[RTW_PWR_TRK_5G_1]; + swing_table->n[RF_PATH_D] = tbl->pwrtrk_5gd_n[RTW_PWR_TRK_5G_1]; } else if (IS_CH_5G_BAND_3(channel)) { swing_table->p[RF_PATH_A] = tbl->pwrtrk_5ga_p[RTW_PWR_TRK_5G_2]; swing_table->n[RF_PATH_A] = tbl->pwrtrk_5ga_n[RTW_PWR_TRK_5G_2]; swing_table->p[RF_PATH_B] = tbl->pwrtrk_5gb_p[RTW_PWR_TRK_5G_2]; swing_table->n[RF_PATH_B] = tbl->pwrtrk_5gb_n[RTW_PWR_TRK_5G_2]; + swing_table->p[RF_PATH_C] = tbl->pwrtrk_5gc_p[RTW_PWR_TRK_5G_2]; + swing_table->n[RF_PATH_C] = tbl->pwrtrk_5gc_n[RTW_PWR_TRK_5G_2]; + swing_table->p[RF_PATH_D] = tbl->pwrtrk_5gd_p[RTW_PWR_TRK_5G_2]; + swing_table->n[RF_PATH_D] = tbl->pwrtrk_5gd_n[RTW_PWR_TRK_5G_2]; } else if (IS_CH_5G_BAND_4(channel)) { swing_table->p[RF_PATH_A] = tbl->pwrtrk_5ga_p[RTW_PWR_TRK_5G_3]; swing_table->n[RF_PATH_A] = tbl->pwrtrk_5ga_n[RTW_PWR_TRK_5G_3]; swing_table->p[RF_PATH_B] = tbl->pwrtrk_5gb_p[RTW_PWR_TRK_5G_3]; swing_table->n[RF_PATH_B] = tbl->pwrtrk_5gb_n[RTW_PWR_TRK_5G_3]; + swing_table->p[RF_PATH_C] = tbl->pwrtrk_5gc_p[RTW_PWR_TRK_5G_3]; + swing_table->n[RF_PATH_C] = tbl->pwrtrk_5gc_n[RTW_PWR_TRK_5G_3]; + swing_table->p[RF_PATH_D] = tbl->pwrtrk_5gd_p[RTW_PWR_TRK_5G_3]; + swing_table->n[RF_PATH_D] = tbl->pwrtrk_5gd_n[RTW_PWR_TRK_5G_3]; } else { swing_table->p[RF_PATH_A] = tbl->pwrtrk_2ga_p; swing_table->n[RF_PATH_A] = tbl->pwrtrk_2ga_n; swing_table->p[RF_PATH_B] = tbl->pwrtrk_2gb_p; swing_table->n[RF_PATH_B] = tbl->pwrtrk_2gb_n; + swing_table->p[RF_PATH_C] = tbl->pwrtrk_2gc_p; + swing_table->n[RF_PATH_C] = tbl->pwrtrk_2gc_n; + swing_table->p[RF_PATH_D] = tbl->pwrtrk_2gd_p; + swing_table->n[RF_PATH_D] = tbl->pwrtrk_2gd_n; } } EXPORT_SYMBOL(rtw_phy_config_swing_table); From fa8466fd6a871f17d49164d38025f6a695852fb7 Mon Sep 17 00:00:00 2001 From: Bitterblue Smith Date: Sat, 16 Nov 2024 02:01:11 +0200 Subject: [PATCH 094/193] wifi: rtw88: Add rtw8814a_table.c (part 1/2) This contains various tables for initialising the RTL8814A, plus TX power limits. Signed-off-by: Bitterblue Smith --- rtw8814a_table.c | 12551 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 12551 insertions(+) create mode 100644 rtw8814a_table.c diff --git a/rtw8814a_table.c b/rtw8814a_table.c new file mode 100644 index 00000000..907cbd03 --- /dev/null +++ b/rtw8814a_table.c @@ -0,0 +1,12551 @@ +// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause +/* Copyright(c) 2025 Realtek Corporation + */ + +#include "main.h" +#include "phy.h" +#include "rtw8814a_table.h" + +static const u32 rtw8814a_mac[] = { + 0x010, 0x0000007C, + 0x014, 0x000000DB, + 0x016, 0x00000002, + 0x073, 0x00000010, + 0x420, 0x00000080, + 0x421, 0x0000000F, + 0x428, 0x0000000A, + 0x429, 0x00000010, + 0x430, 0x00000000, + 0x431, 0x00000000, + 0x432, 0x00000000, + 0x433, 0x00000001, + 0x434, 0x00000004, + 0x435, 0x00000005, + 0x436, 0x00000007, + 0x437, 0x00000008, + 0x43C, 0x00000004, + 0x43D, 0x00000005, + 0x43E, 0x00000007, + 0x43F, 0x00000008, + 0x440, 0x0000005D, + 0x441, 0x00000001, + 0x442, 0x00000000, + 0x444, 0x00000010, + 0x445, 0x000000F0, + 0x446, 0x00000001, + 0x447, 0x000000FE, + 0x448, 0x00000000, + 0x449, 0x00000000, + 0x44A, 0x00000000, + 0x44B, 0x00000040, + 0x44C, 0x00000010, + 0x44D, 0x000000F0, + 0x44E, 0x0000003F, + 0x44F, 0x00000000, + 0x450, 0x00000000, + 0x451, 0x00000000, + 0x452, 0x00000000, + 0x453, 0x00000040, + 0x45E, 0x00000004, + 0x49C, 0x00000010, + 0x49D, 0x000000F0, + 0x49E, 0x00000000, + 0x49F, 0x00000006, + 0x4A0, 0x000000E0, + 0x4A1, 0x00000003, + 0x4A2, 0x00000000, + 0x4A3, 0x00000040, + 0x4A4, 0x00000015, + 0x4A5, 0x000000F0, + 0x4A6, 0x00000000, + 0x4A7, 0x00000006, + 0x4A8, 0x000000E0, + 0x4A9, 0x00000000, + 0x4AA, 0x00000000, + 0x4AB, 0x00000000, + 0x7DA, 0x00000008, + 0x1448, 0x00000006, + 0x144A, 0x00000006, + 0x144C, 0x00000006, + 0x144E, 0x00000006, + 0x4C8, 0x000000FF, + 0x4C9, 0x00000008, + 0x4CA, 0x0000003C, + 0x4CB, 0x0000003C, + 0x4CC, 0x000000FF, + 0x4CD, 0x000000FF, + 0x4CE, 0x00000001, + 0x4CF, 0x00000008, + 0x500, 0x00000026, + 0x501, 0x000000A2, + 0x502, 0x0000002F, + 0x503, 0x00000000, + 0x504, 0x00000028, + 0x505, 0x000000A3, + 0x506, 0x0000005E, + 0x507, 0x00000000, + 0x508, 0x0000002B, + 0x509, 0x000000A4, + 0x50A, 0x0000005E, + 0x50B, 0x00000000, + 0x50C, 0x0000004F, + 0x50D, 0x000000A4, + 0x50E, 0x00000000, + 0x50F, 0x00000000, + 0x512, 0x0000001C, + 0x514, 0x0000000A, + 0x516, 0x0000000A, + 0x521, 0x0000002F, + 0x525, 0x00000047, + 0x550, 0x00000010, + 0x551, 0x00000010, + 0x559, 0x00000002, + 0x55C, 0x00000064, + 0x55D, 0x000000FF, + 0x577, 0x00000003, + 0x5BE, 0x00000064, + 0x604, 0x00000001, + 0x605, 0x00000030, + 0x607, 0x00000001, + 0x608, 0x0000000E, + 0x609, 0x0000002A, + 0x60A, 0x00000000, + 0x60C, 0x00000018, + 0x60D, 0x00000050, + 0x6A0, 0x000000FF, + 0x6A1, 0x000000FF, + 0x6A2, 0x000000FF, + 0x6A3, 0x000000FF, + 0x6A4, 0x000000FF, + 0x6A5, 0x000000FF, + 0x6DE, 0x00000084, + 0x620, 0x000000FF, + 0x621, 0x000000FF, + 0x622, 0x000000FF, + 0x623, 0x000000FF, + 0x624, 0x000000FF, + 0x625, 0x000000FF, + 0x626, 0x000000FF, + 0x627, 0x000000FF, + 0x638, 0x00000064, + 0x63C, 0x0000000A, + 0x63D, 0x0000000A, + 0x63E, 0x0000000E, + 0x63F, 0x0000000E, + 0x640, 0x00000040, + 0x642, 0x00000040, + 0x643, 0x00000000, + 0x652, 0x000000C8, + 0x66E, 0x00000005, + 0x700, 0x00000021, + 0x701, 0x00000043, + 0x702, 0x00000065, + 0x703, 0x00000087, + 0x708, 0x00000021, + 0x709, 0x00000043, + 0x70A, 0x00000065, + 0x70B, 0x00000087, + 0x718, 0x00000040, + 0x7D5, 0x000000BC, + 0x7D8, 0x00000028, + 0x7D9, 0x00000000, + 0x7DA, 0x0000000B, +}; + +RTW_DECL_TABLE_PHY_COND(rtw8814a_mac, rtw_phy_cfg_mac); + +static const u32 rtw8814a_agc[] = { + 0x80000002, 0x00000000, 0x40000000, 0x00000000, + 0x81C, 0xFE000003, + 0x90000003, 0x00000000, 0x40000000, 0x00000000, + 0x81C, 0xFE000003, + 0x90000004, 0x00000000, 0x40000000, 0x00000000, + 0x81C, 0xFE000003, + 0x90000005, 0x00000000, 0x40000000, 0x00000000, + 0x81C, 0xFE000003, + 0x90000007, 0x00000000, 0x40000000, 0x00000000, + 0x81C, 0xFF000003, + 0x90000008, 0x00000000, 0x40000000, 0x00000000, + 0x81C, 0xFE000003, + 0x90000009, 0x00000000, 0x40000000, 0x00000000, + 0x81C, 0xFF000003, + 0x9000000a, 0x00000000, 0x40000000, 0x00000000, + 0x81C, 0xFE000003, + 0x9000000b, 0x00000000, 0x40000000, 0x00000000, + 0x81C, 0xFE000003, + 0xA0000000, 0x00000000, + 0x81C, 0xFF000003, + 0xB0000000, 0x00000000, + 0x80000001, 0x00000000, 0x40000000, 0x00000000, + 0x81C, 0xFE000003, + 0x81C, 0xFD020003, + 0x81C, 0xFC040003, + 0x81C, 0xFB060003, + 0x81C, 0xFA080003, + 0x81C, 0xF90A0003, + 0x81C, 0xF80C0003, + 0x81C, 0xF70E0003, + 0x81C, 0xF6100003, + 0x81C, 0xF5120003, + 0x81C, 0xF4140003, + 0x81C, 0xF3160003, + 0x81C, 0xF2180003, + 0x81C, 0xF11A0003, + 0x81C, 0xF01C0003, + 0x81C, 0xEF1E0003, + 0x81C, 0xEE200003, + 0x81C, 0xED220003, + 0x81C, 0xCF240003, + 0x81C, 0xCE260003, + 0x81C, 0xCD280003, + 0x81C, 0xCC2A0003, + 0x81C, 0xCB2C0003, + 0x81C, 0xCA2E0003, + 0x81C, 0xC9300003, + 0x81C, 0xC8320003, + 0x81C, 0xC7340003, + 0x81C, 0xC6360003, + 0x81C, 0xC5380003, + 0x81C, 0xC43A0003, + 0x81C, 0xA63C0003, + 0x81C, 0xA53E0003, + 0x81C, 0xA4400003, + 0x81C, 0xA3420003, + 0x81C, 0xA2440003, + 0x81C, 0xA1460003, + 0x81C, 0x86480003, + 0x81C, 0x854A0003, + 0x81C, 0x844C0003, + 0x81C, 0x834E0003, + 0x81C, 0x66500003, + 0x81C, 0x65520003, + 0x81C, 0x64540003, + 0x81C, 0x63560003, + 0x81C, 0x62580003, + 0x81C, 0x615A0003, + 0x81C, 0x435C0003, + 0x81C, 0x425E0003, + 0x81C, 0x41600003, + 0x81C, 0x27620003, + 0x81C, 0x26640003, + 0x81C, 0x25660003, + 0x81C, 0x24680003, + 0x81C, 0x236A0003, + 0x81C, 0x226C0003, + 0x81C, 0x216E0003, + 0x81C, 0x21700003, + 0x81C, 0x21720003, + 0x81C, 0x21740003, + 0x81C, 0x21760003, + 0x81C, 0x21780003, + 0x81C, 0x217A0003, + 0x81C, 0x217C0003, + 0x81C, 0x217E0003, + 0x90000002, 0x00000000, 0x40000000, 0x00000000, + 0x81C, 0xFF000003, + 0x81C, 0xFE020003, + 0x81C, 0xFD040003, + 0x81C, 0xFC060003, + 0x81C, 0xFB080003, + 0x81C, 0xFA0A0003, + 0x81C, 0xF90C0003, + 0x81C, 0xF80E0003, + 0x81C, 0xF7100003, + 0x81C, 0xF6120003, + 0x81C, 0xF5140003, + 0x81C, 0xF4160003, + 0x81C, 0xF3180003, + 0x81C, 0xF21A0003, + 0x81C, 0xF11C0003, + 0x81C, 0xF01E0003, + 0x81C, 0xEF200003, + 0x81C, 0xEE220003, + 0x81C, 0xED240003, + 0x81C, 0xEC260003, + 0x81C, 0xEB280003, + 0x81C, 0xEA2A0003, + 0x81C, 0xE92C0003, + 0x81C, 0xE82E0003, + 0x81C, 0xE7300003, + 0x81C, 0xE6320003, + 0x81C, 0xE5340003, + 0x81C, 0xE4360003, + 0x81C, 0xE3380003, + 0x81C, 0xC53A0003, + 0x81C, 0xC43C0003, + 0x81C, 0xC33E0003, + 0x81C, 0xC2400003, + 0x81C, 0xC1420003, + 0x81C, 0xA8440003, + 0x81C, 0xA7460003, + 0x81C, 0xA6480003, + 0x81C, 0xA54A0003, + 0x81C, 0xA44C0003, + 0x81C, 0xA34E0003, + 0x81C, 0xA2500003, + 0x81C, 0x65520003, + 0x81C, 0x64540003, + 0x81C, 0x63560003, + 0x81C, 0x62580003, + 0x81C, 0x615A0003, + 0x81C, 0x475C0003, + 0x81C, 0x465E0003, + 0x81C, 0x45600003, + 0x81C, 0x44620003, + 0x81C, 0x43640003, + 0x81C, 0x42660003, + 0x81C, 0x41680003, + 0x81C, 0x416A0003, + 0x81C, 0x416C0003, + 0x81C, 0x416E0003, + 0x81C, 0x41700003, + 0x81C, 0x41720003, + 0x81C, 0x41740003, + 0x81C, 0x41760003, + 0x81C, 0x41780003, + 0x81C, 0x417A0003, + 0x81C, 0x417C0003, + 0x81C, 0x417E0003, + 0x90000003, 0x00000000, 0x40000000, 0x00000000, + 0x81C, 0xFE000003, + 0x81C, 0xFD020003, + 0x81C, 0xFC040003, + 0x81C, 0xFB060003, + 0x81C, 0xFA080003, + 0x81C, 0xF90A0003, + 0x81C, 0xF80C0003, + 0x81C, 0xF70E0003, + 0x81C, 0xF6100003, + 0x81C, 0xF5120003, + 0x81C, 0xF4140003, + 0x81C, 0xF3160003, + 0x81C, 0xF2180003, + 0x81C, 0xF11A0003, + 0x81C, 0xF01C0003, + 0x81C, 0xEF1E0003, + 0x81C, 0xEE200003, + 0x81C, 0xED220003, + 0x81C, 0xEC240003, + 0x81C, 0xEB260003, + 0x81C, 0xEA280003, + 0x81C, 0xE92A0003, + 0x81C, 0xE82C0003, + 0x81C, 0xE72E0003, + 0x81C, 0xE6300003, + 0x81C, 0xE5320003, + 0x81C, 0xE4340003, + 0x81C, 0xE3360003, + 0x81C, 0xC6380003, + 0x81C, 0xC53A0003, + 0x81C, 0xC43C0003, + 0x81C, 0xC33E0003, + 0x81C, 0xC2400003, + 0x81C, 0xA9420003, + 0x81C, 0xA8440003, + 0x81C, 0xA7460003, + 0x81C, 0xA6480003, + 0x81C, 0xA54A0003, + 0x81C, 0xA44C0003, + 0x81C, 0xA34E0003, + 0x81C, 0x66500003, + 0x81C, 0x65520003, + 0x81C, 0x64540003, + 0x81C, 0x63560003, + 0x81C, 0x49580003, + 0x81C, 0x485A0003, + 0x81C, 0x475C0003, + 0x81C, 0x465E0003, + 0x81C, 0x45600003, + 0x81C, 0x44620003, + 0x81C, 0x43640003, + 0x81C, 0x42660003, + 0x81C, 0x41680003, + 0x81C, 0x416A0003, + 0x81C, 0x416C0003, + 0x81C, 0x416E0003, + 0x81C, 0x41700003, + 0x81C, 0x41720003, + 0x81C, 0x41740003, + 0x81C, 0x41760003, + 0x81C, 0x41780003, + 0x81C, 0x417A0003, + 0x81C, 0x417C0003, + 0x81C, 0x417E0003, + 0x90000004, 0x00000000, 0x40000000, 0x00000000, + 0x81C, 0xFF000003, + 0x81C, 0xFE020003, + 0x81C, 0xFD040003, + 0x81C, 0xFC060003, + 0x81C, 0xFB080003, + 0x81C, 0xFA0A0003, + 0x81C, 0xF90C0003, + 0x81C, 0xF80E0003, + 0x81C, 0xF7100003, + 0x81C, 0xF6120003, + 0x81C, 0xF5140003, + 0x81C, 0xF4160003, + 0x81C, 0xF3180003, + 0x81C, 0xF21A0003, + 0x81C, 0xF11C0003, + 0x81C, 0xF01E0003, + 0x81C, 0xEF200003, + 0x81C, 0xEE220003, + 0x81C, 0xED240003, + 0x81C, 0xEC260003, + 0x81C, 0xEB280003, + 0x81C, 0xEA2A0003, + 0x81C, 0xE92C0003, + 0x81C, 0xE82E0003, + 0x81C, 0xE7300003, + 0x81C, 0xE6320003, + 0x81C, 0xE5340003, + 0x81C, 0xE4360003, + 0x81C, 0xE3380003, + 0x81C, 0xC53A0003, + 0x81C, 0xC43C0003, + 0x81C, 0xC33E0003, + 0x81C, 0xC2400003, + 0x81C, 0xC1420003, + 0x81C, 0xA8440003, + 0x81C, 0xA7460003, + 0x81C, 0xA6480003, + 0x81C, 0xA54A0003, + 0x81C, 0xA44C0003, + 0x81C, 0xA34E0003, + 0x81C, 0xA2500003, + 0x81C, 0x65520003, + 0x81C, 0x64540003, + 0x81C, 0x63560003, + 0x81C, 0x62580003, + 0x81C, 0x615A0003, + 0x81C, 0x475C0003, + 0x81C, 0x465E0003, + 0x81C, 0x45600003, + 0x81C, 0x44620003, + 0x81C, 0x43640003, + 0x81C, 0x42660003, + 0x81C, 0x41680003, + 0x81C, 0x416A0003, + 0x81C, 0x416C0003, + 0x81C, 0x416E0003, + 0x81C, 0x41700003, + 0x81C, 0x41720003, + 0x81C, 0x41740003, + 0x81C, 0x41760003, + 0x81C, 0x41780003, + 0x81C, 0x417A0003, + 0x81C, 0x417C0003, + 0x81C, 0x417E0003, + 0x90000005, 0x00000000, 0x40000000, 0x00000000, + 0x81C, 0xFE000003, + 0x81C, 0xFD020003, + 0x81C, 0xFC040003, + 0x81C, 0xFB060003, + 0x81C, 0xFA080003, + 0x81C, 0xF90A0003, + 0x81C, 0xF80C0003, + 0x81C, 0xF70E0003, + 0x81C, 0xF6100003, + 0x81C, 0xF5120003, + 0x81C, 0xF4140003, + 0x81C, 0xF3160003, + 0x81C, 0xF2180003, + 0x81C, 0xF11A0003, + 0x81C, 0xF01C0003, + 0x81C, 0xEF1E0003, + 0x81C, 0xEE200003, + 0x81C, 0xED220003, + 0x81C, 0xEC240003, + 0x81C, 0xEB260003, + 0x81C, 0xEA280003, + 0x81C, 0xE92A0003, + 0x81C, 0xE82C0003, + 0x81C, 0xE72E0003, + 0x81C, 0xE6300003, + 0x81C, 0xE5320003, + 0x81C, 0xE4340003, + 0x81C, 0xE3360003, + 0x81C, 0xC6380003, + 0x81C, 0xC53A0003, + 0x81C, 0xC43C0003, + 0x81C, 0xC33E0003, + 0x81C, 0xC2400003, + 0x81C, 0xA9420003, + 0x81C, 0xA8440003, + 0x81C, 0xA7460003, + 0x81C, 0xA6480003, + 0x81C, 0xA54A0003, + 0x81C, 0xA44C0003, + 0x81C, 0xA34E0003, + 0x81C, 0x66500003, + 0x81C, 0x65520003, + 0x81C, 0x64540003, + 0x81C, 0x63560003, + 0x81C, 0x49580003, + 0x81C, 0x485A0003, + 0x81C, 0x475C0003, + 0x81C, 0x465E0003, + 0x81C, 0x45600003, + 0x81C, 0x44620003, + 0x81C, 0x43640003, + 0x81C, 0x42660003, + 0x81C, 0x41680003, + 0x81C, 0x416A0003, + 0x81C, 0x416C0003, + 0x81C, 0x416E0003, + 0x81C, 0x41700003, + 0x81C, 0x41720003, + 0x81C, 0x41740003, + 0x81C, 0x41760003, + 0x81C, 0x41780003, + 0x81C, 0x417A0003, + 0x81C, 0x417C0003, + 0x81C, 0x417E0003, + 0x90000007, 0x00000000, 0x40000000, 0x00000000, + 0x81C, 0xDF000003, + 0x81C, 0xDF020003, + 0x81C, 0xDF040003, + 0x81C, 0xDE060003, + 0x81C, 0xDD080003, + 0x81C, 0xDC0A0003, + 0x81C, 0xDB0C0003, + 0x81C, 0xDA0E0003, + 0x81C, 0xD9100003, + 0x81C, 0xD8120003, + 0x81C, 0xD7140003, + 0x81C, 0xD6160003, + 0x81C, 0xD5180003, + 0x81C, 0xD41A0003, + 0x81C, 0xD31C0003, + 0x81C, 0xD21E0003, + 0x81C, 0xD1200003, + 0x81C, 0xD0220003, + 0x81C, 0xCF240003, + 0x81C, 0xCE260003, + 0x81C, 0xCD280003, + 0x81C, 0xCC2A0003, + 0x81C, 0xCB2C0003, + 0x81C, 0xCA2E0003, + 0x81C, 0xC9300003, + 0x81C, 0xC8320003, + 0x81C, 0xC7340003, + 0x81C, 0xC6360003, + 0x81C, 0xC5380003, + 0x81C, 0xA73A0003, + 0x81C, 0xA63C0003, + 0x81C, 0xA53E0003, + 0x81C, 0xA4400003, + 0x81C, 0xA3420003, + 0x81C, 0xA2440003, + 0x81C, 0x87460003, + 0x81C, 0x86480003, + 0x81C, 0x854A0003, + 0x81C, 0x844C0003, + 0x81C, 0x834E0003, + 0x81C, 0x82500003, + 0x81C, 0x81520003, + 0x81C, 0x64540003, + 0x81C, 0x63560003, + 0x81C, 0x62580003, + 0x81C, 0x615A0003, + 0x81C, 0x445C0003, + 0x81C, 0x435E0003, + 0x81C, 0x42600003, + 0x81C, 0x41620003, + 0x81C, 0x27640003, + 0x81C, 0x26660003, + 0x81C, 0x25680003, + 0x81C, 0x246A0003, + 0x81C, 0x236C0003, + 0x81C, 0x226E0003, + 0x81C, 0x21700003, + 0x81C, 0x21720003, + 0x81C, 0x21740003, + 0x81C, 0x21760003, + 0x81C, 0x21780003, + 0x81C, 0x217A0003, + 0x81C, 0x217C0003, + 0x81C, 0x217E0003, + 0x90000008, 0x00000000, 0x40000000, 0x00000000, + 0x81C, 0xFF000003, + 0x81C, 0xFE020003, + 0x81C, 0xFD040003, + 0x81C, 0xFC060003, + 0x81C, 0xFB080003, + 0x81C, 0xFA0A0003, + 0x81C, 0xF90C0003, + 0x81C, 0xF80E0003, + 0x81C, 0xF7100003, + 0x81C, 0xF6120003, + 0x81C, 0xF5140003, + 0x81C, 0xF4160003, + 0x81C, 0xF3180003, + 0x81C, 0xF21A0003, + 0x81C, 0xF11C0003, + 0x81C, 0xF01E0003, + 0x81C, 0xEF200003, + 0x81C, 0xEE220003, + 0x81C, 0xED240003, + 0x81C, 0xEC260003, + 0x81C, 0xEB280003, + 0x81C, 0xEA2A0003, + 0x81C, 0xE92C0003, + 0x81C, 0xE82E0003, + 0x81C, 0xE7300003, + 0x81C, 0xE6320003, + 0x81C, 0xE5340003, + 0x81C, 0xE4360003, + 0x81C, 0xE3380003, + 0x81C, 0xC53A0003, + 0x81C, 0xC43C0003, + 0x81C, 0xC33E0003, + 0x81C, 0xC2400003, + 0x81C, 0xC1420003, + 0x81C, 0xA8440003, + 0x81C, 0xA7460003, + 0x81C, 0xA6480003, + 0x81C, 0xA54A0003, + 0x81C, 0xA44C0003, + 0x81C, 0xA34E0003, + 0x81C, 0xA2500003, + 0x81C, 0x65520003, + 0x81C, 0x64540003, + 0x81C, 0x63560003, + 0x81C, 0x62580003, + 0x81C, 0x615A0003, + 0x81C, 0x475C0003, + 0x81C, 0x465E0003, + 0x81C, 0x45600003, + 0x81C, 0x44620003, + 0x81C, 0x43640003, + 0x81C, 0x42660003, + 0x81C, 0x41680003, + 0x81C, 0x416A0003, + 0x81C, 0x416C0003, + 0x81C, 0x416E0003, + 0x81C, 0x41700003, + 0x81C, 0x41720003, + 0x81C, 0x41740003, + 0x81C, 0x41760003, + 0x81C, 0x41780003, + 0x81C, 0x417A0003, + 0x81C, 0x417C0003, + 0x81C, 0x417E0003, + 0x90000009, 0x00000000, 0x40000000, 0x00000000, + 0x81C, 0xDF000003, + 0x81C, 0xDF020003, + 0x81C, 0xDF040003, + 0x81C, 0xDE060003, + 0x81C, 0xDD080003, + 0x81C, 0xDC0A0003, + 0x81C, 0xDB0C0003, + 0x81C, 0xDA0E0003, + 0x81C, 0xD9100003, + 0x81C, 0xD8120003, + 0x81C, 0xD7140003, + 0x81C, 0xD6160003, + 0x81C, 0xD5180003, + 0x81C, 0xD41A0003, + 0x81C, 0xD31C0003, + 0x81C, 0xD21E0003, + 0x81C, 0xD1200003, + 0x81C, 0xD0220003, + 0x81C, 0xCF240003, + 0x81C, 0xCE260003, + 0x81C, 0xCD280003, + 0x81C, 0xCC2A0003, + 0x81C, 0xCB2C0003, + 0x81C, 0xCA2E0003, + 0x81C, 0xC9300003, + 0x81C, 0xC8320003, + 0x81C, 0xC7340003, + 0x81C, 0xC6360003, + 0x81C, 0xC5380003, + 0x81C, 0xA73A0003, + 0x81C, 0xA63C0003, + 0x81C, 0xA53E0003, + 0x81C, 0xA4400003, + 0x81C, 0xA3420003, + 0x81C, 0xA2440003, + 0x81C, 0x87460003, + 0x81C, 0x86480003, + 0x81C, 0x854A0003, + 0x81C, 0x844C0003, + 0x81C, 0x834E0003, + 0x81C, 0x82500003, + 0x81C, 0x81520003, + 0x81C, 0x64540003, + 0x81C, 0x63560003, + 0x81C, 0x62580003, + 0x81C, 0x615A0003, + 0x81C, 0x445C0003, + 0x81C, 0x435E0003, + 0x81C, 0x42600003, + 0x81C, 0x41620003, + 0x81C, 0x27640003, + 0x81C, 0x26660003, + 0x81C, 0x25680003, + 0x81C, 0x246A0003, + 0x81C, 0x236C0003, + 0x81C, 0x226E0003, + 0x81C, 0x21700003, + 0x81C, 0x21720003, + 0x81C, 0x21740003, + 0x81C, 0x21760003, + 0x81C, 0x21780003, + 0x81C, 0x217A0003, + 0x81C, 0x217C0003, + 0x81C, 0x217E0003, + 0x9000000a, 0x00000000, 0x40000000, 0x00000000, + 0x81C, 0xFE000003, + 0x81C, 0xFE020003, + 0x81C, 0xFD040003, + 0x81C, 0xFC060003, + 0x81C, 0xFB080003, + 0x81C, 0xFA0A0003, + 0x81C, 0xF90C0003, + 0x81C, 0xF80E0003, + 0x81C, 0xF7100003, + 0x81C, 0xF6120003, + 0x81C, 0xF5140003, + 0x81C, 0xF4160003, + 0x81C, 0xF3180003, + 0x81C, 0xF21A0003, + 0x81C, 0xF11C0003, + 0x81C, 0xF01E0003, + 0x81C, 0xEF200003, + 0x81C, 0xEE220003, + 0x81C, 0xED240003, + 0x81C, 0x0F260003, + 0x81C, 0x0E280003, + 0x81C, 0x0D2A0003, + 0x81C, 0x0C2C0003, + 0x81C, 0x0B2E0003, + 0x81C, 0x0A300003, + 0x81C, 0x09320003, + 0x81C, 0x08340003, + 0x81C, 0x07360003, + 0x81C, 0x06380003, + 0x81C, 0x053A0003, + 0x81C, 0x043C0003, + 0x81C, 0x033E0003, + 0x81C, 0x23400003, + 0x81C, 0x22420003, + 0x81C, 0xA8440003, + 0x81C, 0xA7460003, + 0x81C, 0xA6480003, + 0x81C, 0xA54A0003, + 0x81C, 0xA44C0003, + 0x81C, 0x684E0003, + 0x81C, 0x67500003, + 0x81C, 0x66520003, + 0x81C, 0x65540003, + 0x81C, 0x64560003, + 0x81C, 0x63580003, + 0x81C, 0x625A0003, + 0x81C, 0x615C0003, + 0x81C, 0x475E0003, + 0x81C, 0x46600003, + 0x81C, 0x45620003, + 0x81C, 0x44640003, + 0x81C, 0x43660003, + 0x81C, 0x42680003, + 0x81C, 0x416A0003, + 0x81C, 0x416C0003, + 0x81C, 0x416E0003, + 0x81C, 0x41700003, + 0x81C, 0x41720003, + 0x81C, 0x41740003, + 0x81C, 0x41760003, + 0x81C, 0x41780003, + 0x81C, 0x417A0003, + 0x81C, 0x417C0003, + 0x81C, 0x417E0003, + 0x9000000b, 0x00000000, 0x40000000, 0x00000000, + 0x81C, 0xFE000003, + 0x81C, 0xFE020003, + 0x81C, 0xFD040003, + 0x81C, 0xFC060003, + 0x81C, 0xFB080003, + 0x81C, 0xFA0A0003, + 0x81C, 0xF90C0003, + 0x81C, 0xF80E0003, + 0x81C, 0xF7100003, + 0x81C, 0xF6120003, + 0x81C, 0xF5140003, + 0x81C, 0xF4160003, + 0x81C, 0xF3180003, + 0x81C, 0xF21A0003, + 0x81C, 0xF11C0003, + 0x81C, 0xF01E0003, + 0x81C, 0xEF200003, + 0x81C, 0xEE220003, + 0x81C, 0xED240003, + 0x81C, 0xEC260003, + 0x81C, 0xEB280003, + 0x81C, 0xEA2A0003, + 0x81C, 0xE92C0003, + 0x81C, 0xE72E0003, + 0x81C, 0xE6300003, + 0x81C, 0xE5320003, + 0x81C, 0x08340003, + 0x81C, 0x07360003, + 0x81C, 0x06380003, + 0x81C, 0x053A0003, + 0x81C, 0x043C0003, + 0x81C, 0x033E0003, + 0x81C, 0x02400003, + 0x81C, 0xA9420003, + 0x81C, 0xA8440003, + 0x81C, 0xA7460003, + 0x81C, 0xA6480003, + 0x81C, 0xA54A0003, + 0x81C, 0x684C0003, + 0x81C, 0x674E0003, + 0x81C, 0x66500003, + 0x81C, 0x65520003, + 0x81C, 0x64540003, + 0x81C, 0x63560003, + 0x81C, 0x62580003, + 0x81C, 0x615A0003, + 0x81C, 0x475C0003, + 0x81C, 0x465E0003, + 0x81C, 0x45600003, + 0x81C, 0x44620003, + 0x81C, 0x43640003, + 0x81C, 0x42660003, + 0x81C, 0x41680003, + 0x81C, 0x416A0003, + 0x81C, 0x416C0003, + 0x81C, 0x416E0003, + 0x81C, 0x41700003, + 0x81C, 0x41720003, + 0x81C, 0x41740003, + 0x81C, 0x41760003, + 0x81C, 0x41780003, + 0x81C, 0x417A0003, + 0x81C, 0x417C0003, + 0x81C, 0x417E0003, + 0xA0000000, 0x00000000, + 0x81C, 0xFE000003, + 0x81C, 0xFD020003, + 0x81C, 0xFC040003, + 0x81C, 0xFB060003, + 0x81C, 0xFA080003, + 0x81C, 0xF90A0003, + 0x81C, 0xF80C0003, + 0x81C, 0xF70E0003, + 0x81C, 0xF6100003, + 0x81C, 0xF5120003, + 0x81C, 0xF4140003, + 0x81C, 0xF3160003, + 0x81C, 0xF2180003, + 0x81C, 0xF11A0003, + 0x81C, 0xF01C0003, + 0x81C, 0xEF1E0003, + 0x81C, 0xEE200003, + 0x81C, 0xED220003, + 0x81C, 0xCF240003, + 0x81C, 0xCE260003, + 0x81C, 0xCD280003, + 0x81C, 0xCC2A0003, + 0x81C, 0xCB2C0003, + 0x81C, 0xCA2E0003, + 0x81C, 0xC9300003, + 0x81C, 0xC8320003, + 0x81C, 0xC7340003, + 0x81C, 0xC6360003, + 0x81C, 0xC5380003, + 0x81C, 0xC43A0003, + 0x81C, 0xA63C0003, + 0x81C, 0xA53E0003, + 0x81C, 0xA4400003, + 0x81C, 0xA3420003, + 0x81C, 0xA2440003, + 0x81C, 0xA1460003, + 0x81C, 0x86480003, + 0x81C, 0x854A0003, + 0x81C, 0x844C0003, + 0x81C, 0x834E0003, + 0x81C, 0x66500003, + 0x81C, 0x65520003, + 0x81C, 0x64540003, + 0x81C, 0x63560003, + 0x81C, 0x62580003, + 0x81C, 0x615A0003, + 0x81C, 0x435C0003, + 0x81C, 0x425E0003, + 0x81C, 0x41600003, + 0x81C, 0x27620003, + 0x81C, 0x26640003, + 0x81C, 0x25660003, + 0x81C, 0x24680003, + 0x81C, 0x236A0003, + 0x81C, 0x226C0003, + 0x81C, 0x216E0003, + 0x81C, 0x21700003, + 0x81C, 0x21720003, + 0x81C, 0x21740003, + 0x81C, 0x21760003, + 0x81C, 0x21780003, + 0x81C, 0x217A0003, + 0x81C, 0x217C0003, + 0x81C, 0x217E0003, + 0xB0000000, 0x00000000, + 0x80000001, 0x00000000, 0x40000000, 0x00000000, + 0x81C, 0xF9000103, + 0x81C, 0xF8020103, + 0x81C, 0xF7040103, + 0x81C, 0xF6060103, + 0x81C, 0xF5080103, + 0x81C, 0xF40A0103, + 0x81C, 0xF30C0103, + 0x81C, 0xF20E0103, + 0x81C, 0xF1100103, + 0x81C, 0xF0120103, + 0x81C, 0xEF140103, + 0x81C, 0xEE160103, + 0x81C, 0xED180103, + 0x81C, 0xEC1A0103, + 0x81C, 0xEB1C0103, + 0x81C, 0xEA1E0103, + 0x81C, 0xE9200103, + 0x81C, 0xE8220103, + 0x81C, 0xE7240103, + 0x81C, 0xE6260103, + 0x81C, 0xE5280103, + 0x81C, 0xE42A0103, + 0x81C, 0xE32C0103, + 0x81C, 0xC32E0103, + 0x81C, 0xC2300103, + 0x81C, 0xC1320103, + 0x81C, 0xA5340103, + 0x81C, 0xA4360103, + 0x81C, 0xA3380103, + 0x81C, 0xA23A0103, + 0x81C, 0xA13C0103, + 0x81C, 0x843E0103, + 0x81C, 0x83400103, + 0x81C, 0x82420103, + 0x81C, 0x81440103, + 0x81C, 0x64460103, + 0x81C, 0x63480103, + 0x81C, 0x624A0103, + 0x81C, 0x614C0103, + 0x81C, 0x444E0103, + 0x81C, 0x43500103, + 0x81C, 0x42520103, + 0x81C, 0x41540103, + 0x81C, 0x25560103, + 0x81C, 0x24580103, + 0x81C, 0x235A0103, + 0x81C, 0x065C0103, + 0x81C, 0x055E0103, + 0x81C, 0x04600103, + 0x81C, 0x03620103, + 0x81C, 0x02640103, + 0x81C, 0x01660103, + 0x81C, 0x01680103, + 0x81C, 0x016A0103, + 0x81C, 0x016C0103, + 0x81C, 0x016E0103, + 0x81C, 0x01700103, + 0x81C, 0x01720103, + 0x81C, 0x01740103, + 0x81C, 0x01760103, + 0x81C, 0x01780103, + 0x81C, 0x017A0103, + 0x81C, 0x017C0103, + 0x81C, 0x017E0103, + 0x90000002, 0x00000000, 0x40000000, 0x00000000, + 0x81C, 0xF8000103, + 0x81C, 0xF7020103, + 0x81C, 0xF6040103, + 0x81C, 0xF5060103, + 0x81C, 0xF4080103, + 0x81C, 0xF30A0103, + 0x81C, 0xF20C0103, + 0x81C, 0xF10E0103, + 0x81C, 0xF0100103, + 0x81C, 0xEF120103, + 0x81C, 0xEE140103, + 0x81C, 0xED160103, + 0x81C, 0xEC180103, + 0x81C, 0xEB1A0103, + 0x81C, 0xEA1C0103, + 0x81C, 0xE91E0103, + 0x81C, 0xE8200103, + 0x81C, 0xE7220103, + 0x81C, 0xE6240103, + 0x81C, 0xE5260103, + 0x81C, 0xE4280103, + 0x81C, 0xE32A0103, + 0x81C, 0xE22C0103, + 0x81C, 0xE12E0103, + 0x81C, 0xA5300103, + 0x81C, 0xA4320103, + 0x81C, 0xA3340103, + 0x81C, 0xA2360103, + 0x81C, 0xA1380103, + 0x81C, 0x843A0103, + 0x81C, 0x833C0103, + 0x81C, 0x823E0103, + 0x81C, 0x81400103, + 0x81C, 0x64420103, + 0x81C, 0x63440103, + 0x81C, 0x62460103, + 0x81C, 0x61480103, + 0x81C, 0x454A0103, + 0x81C, 0x444C0103, + 0x81C, 0x434E0103, + 0x81C, 0x42500103, + 0x81C, 0x25520103, + 0x81C, 0x24540103, + 0x81C, 0x23560103, + 0x81C, 0x06580103, + 0x81C, 0x055A0103, + 0x81C, 0x045C0103, + 0x81C, 0x035E0103, + 0x81C, 0x02600103, + 0x81C, 0x01620103, + 0x81C, 0x01640103, + 0x81C, 0x01660103, + 0x81C, 0x01680103, + 0x81C, 0x016A0103, + 0x81C, 0x016C0103, + 0x81C, 0x016E0103, + 0x81C, 0x01700103, + 0x81C, 0x01720103, + 0x81C, 0x01740103, + 0x81C, 0x01760103, + 0x81C, 0x01780103, + 0x81C, 0x017A0103, + 0x81C, 0x017C0103, + 0x81C, 0x017E0103, + 0x90000003, 0x00000000, 0x40000000, 0x00000000, + 0x81C, 0xFC000103, + 0x81C, 0xFB020103, + 0x81C, 0xFA040103, + 0x81C, 0xF9060103, + 0x81C, 0xF8080103, + 0x81C, 0xF70A0103, + 0x81C, 0xF60C0103, + 0x81C, 0xF50E0103, + 0x81C, 0xF4100103, + 0x81C, 0xF3120103, + 0x81C, 0xF2140103, + 0x81C, 0xF1160103, + 0x81C, 0xF0180103, + 0x81C, 0xEF1A0103, + 0x81C, 0xEE1C0103, + 0x81C, 0xED1E0103, + 0x81C, 0xEC200103, + 0x81C, 0xEB220103, + 0x81C, 0xEA240103, + 0x81C, 0xE9260103, + 0x81C, 0xE8280103, + 0x81C, 0xE72A0103, + 0x81C, 0xE62C0103, + 0x81C, 0xE52E0103, + 0x81C, 0xE4300103, + 0x81C, 0xE3320103, + 0x81C, 0xE2340103, + 0x81C, 0xE1360103, + 0x81C, 0x87380103, + 0x81C, 0x863A0103, + 0x81C, 0x853C0103, + 0x81C, 0x843E0103, + 0x81C, 0x83400103, + 0x81C, 0x82420103, + 0x81C, 0x81440103, + 0x81C, 0x64460103, + 0x81C, 0x63480103, + 0x81C, 0x624A0103, + 0x81C, 0x464C0103, + 0x81C, 0x454E0103, + 0x81C, 0x44500103, + 0x81C, 0x43520103, + 0x81C, 0x26540103, + 0x81C, 0x25560103, + 0x81C, 0x24580103, + 0x81C, 0x075A0103, + 0x81C, 0x065C0103, + 0x81C, 0x055E0103, + 0x81C, 0x04600103, + 0x81C, 0x03620103, + 0x81C, 0x02640103, + 0x81C, 0x01660103, + 0x81C, 0x01680103, + 0x81C, 0x016A0103, + 0x81C, 0x016C0103, + 0x81C, 0x016E0103, + 0x81C, 0x01700103, + 0x81C, 0x01720103, + 0x81C, 0x01740103, + 0x81C, 0x01760103, + 0x81C, 0x01780103, + 0x81C, 0x017A0103, + 0x81C, 0x017C0103, + 0x81C, 0x017E0103, + 0x90000004, 0x00000000, 0x40000000, 0x00000000, + 0x81C, 0xF9000103, + 0x81C, 0xF8020103, + 0x81C, 0xF7040103, + 0x81C, 0xF6060103, + 0x81C, 0xF5080103, + 0x81C, 0xF40A0103, + 0x81C, 0xF30C0103, + 0x81C, 0xF20E0103, + 0x81C, 0xF1100103, + 0x81C, 0xF0120103, + 0x81C, 0xEF140103, + 0x81C, 0xEE160103, + 0x81C, 0xED180103, + 0x81C, 0xEC1A0103, + 0x81C, 0xEB1C0103, + 0x81C, 0xEA1E0103, + 0x81C, 0xE9200103, + 0x81C, 0xE8220103, + 0x81C, 0xE7240103, + 0x81C, 0xE6260103, + 0x81C, 0xE5280103, + 0x81C, 0xE42A0103, + 0x81C, 0xE32C0103, + 0x81C, 0xE22E0103, + 0x81C, 0xA6300103, + 0x81C, 0xA5320103, + 0x81C, 0xA4340103, + 0x81C, 0xA3360103, + 0x81C, 0xA2380103, + 0x81C, 0xA13A0103, + 0x81C, 0x843C0103, + 0x81C, 0x833E0103, + 0x81C, 0x82400103, + 0x81C, 0x81420103, + 0x81C, 0x64440103, + 0x81C, 0x63460103, + 0x81C, 0x62480103, + 0x81C, 0x614A0103, + 0x81C, 0x444C0103, + 0x81C, 0x434E0103, + 0x81C, 0x42500103, + 0x81C, 0x41520103, + 0x81C, 0x25540103, + 0x81C, 0x24560103, + 0x81C, 0x23580103, + 0x81C, 0x225A0103, + 0x81C, 0x055C0103, + 0x81C, 0x045E0103, + 0x81C, 0x03600103, + 0x81C, 0x02620103, + 0x81C, 0x01640103, + 0x81C, 0x01660103, + 0x81C, 0x01680103, + 0x81C, 0x016A0103, + 0x81C, 0x016C0103, + 0x81C, 0x016E0103, + 0x81C, 0x01700103, + 0x81C, 0x01720103, + 0x81C, 0x01740103, + 0x81C, 0x01760103, + 0x81C, 0x01780103, + 0x81C, 0x017A0103, + 0x81C, 0x017C0103, + 0x81C, 0x017E0103, + 0x90000005, 0x00000000, 0x40000000, 0x00000000, + 0x81C, 0xFD000103, + 0x81C, 0xFC020103, + 0x81C, 0xFB040103, + 0x81C, 0xFA060103, + 0x81C, 0xF9080103, + 0x81C, 0xF80A0103, + 0x81C, 0xF70C0103, + 0x81C, 0xF60E0103, + 0x81C, 0xF5100103, + 0x81C, 0xF4120103, + 0x81C, 0xF3140103, + 0x81C, 0xF2160103, + 0x81C, 0xF1180103, + 0x81C, 0xF01A0103, + 0x81C, 0xEF1C0103, + 0x81C, 0xEE1E0103, + 0x81C, 0xED200103, + 0x81C, 0xEC220103, + 0x81C, 0xEB240103, + 0x81C, 0xEA260103, + 0x81C, 0xE9280103, + 0x81C, 0xE82A0103, + 0x81C, 0xE72C0103, + 0x81C, 0xE62E0103, + 0x81C, 0xE5300103, + 0x81C, 0xE4320103, + 0x81C, 0xE3340103, + 0x81C, 0xE2360103, + 0x81C, 0xE1380103, + 0x81C, 0xA33A0103, + 0x81C, 0xA23C0103, + 0x81C, 0xA13E0103, + 0x81C, 0x84400103, + 0x81C, 0x83420103, + 0x81C, 0x82440103, + 0x81C, 0x81460103, + 0x81C, 0x64480103, + 0x81C, 0x634A0103, + 0x81C, 0x624C0103, + 0x81C, 0x614E0103, + 0x81C, 0x45500103, + 0x81C, 0x44520103, + 0x81C, 0x43540103, + 0x81C, 0x42560103, + 0x81C, 0x25580103, + 0x81C, 0x245A0103, + 0x81C, 0x235C0103, + 0x81C, 0x065E0103, + 0x81C, 0x05600103, + 0x81C, 0x04620103, + 0x81C, 0x03640103, + 0x81C, 0x02660103, + 0x81C, 0x01680103, + 0x81C, 0x016A0103, + 0x81C, 0x016C0103, + 0x81C, 0x016E0103, + 0x81C, 0x01700103, + 0x81C, 0x01720103, + 0x81C, 0x01740103, + 0x81C, 0x01760103, + 0x81C, 0x01780103, + 0x81C, 0x017A0103, + 0x81C, 0x017C0103, + 0x81C, 0x017E0103, + 0x90000006, 0x00000000, 0x40000000, 0x00000000, + 0x81C, 0xFA000103, + 0x81C, 0xF9020103, + 0x81C, 0xF8040103, + 0x81C, 0xF7060103, + 0x81C, 0xF6080103, + 0x81C, 0xF50A0103, + 0x81C, 0xF40C0103, + 0x81C, 0xF30E0103, + 0x81C, 0xF2100103, + 0x81C, 0xF1120103, + 0x81C, 0xF0140103, + 0x81C, 0xEF160103, + 0x81C, 0xEE180103, + 0x81C, 0xED1A0103, + 0x81C, 0xEC1C0103, + 0x81C, 0xEB1E0103, + 0x81C, 0xEA200103, + 0x81C, 0xE9220103, + 0x81C, 0xE8240103, + 0x81C, 0xE7260103, + 0x81C, 0xE6280103, + 0x81C, 0xE52A0103, + 0x81C, 0xE42C0103, + 0x81C, 0xE32E0103, + 0x81C, 0xE2300103, + 0x81C, 0xE1320103, + 0x81C, 0xA5340103, + 0x81C, 0xA4360103, + 0x81C, 0xA3380103, + 0x81C, 0xA23A0103, + 0x81C, 0xA13C0103, + 0x81C, 0x843E0103, + 0x81C, 0x83400103, + 0x81C, 0x82420103, + 0x81C, 0x81440103, + 0x81C, 0x64460103, + 0x81C, 0x63480103, + 0x81C, 0x624A0103, + 0x81C, 0x614C0103, + 0x81C, 0x454E0103, + 0x81C, 0x44500103, + 0x81C, 0x43520103, + 0x81C, 0x42540103, + 0x81C, 0x41560103, + 0x81C, 0x24580103, + 0x81C, 0x235A0103, + 0x81C, 0x225C0103, + 0x81C, 0x055E0103, + 0x81C, 0x04600103, + 0x81C, 0x03620103, + 0x81C, 0x02640103, + 0x81C, 0x01660103, + 0x81C, 0x01680103, + 0x81C, 0x016A0103, + 0x81C, 0x016C0103, + 0x81C, 0x016E0103, + 0x81C, 0x01700103, + 0x81C, 0x01720103, + 0x81C, 0x01740103, + 0x81C, 0x01760103, + 0x81C, 0x01780103, + 0x81C, 0x017A0103, + 0x81C, 0x017C0103, + 0x81C, 0x017E0103, + 0x90000007, 0x00000000, 0x40000000, 0x00000000, + 0x81C, 0xFF000103, + 0x81C, 0xFF020103, + 0x81C, 0xFE040103, + 0x81C, 0xFD060103, + 0x81C, 0xFC080103, + 0x81C, 0xFB0A0103, + 0x81C, 0xFA0C0103, + 0x81C, 0xF90E0103, + 0x81C, 0xF8100103, + 0x81C, 0xF7120103, + 0x81C, 0xF6140103, + 0x81C, 0xF5160103, + 0x81C, 0xF4180103, + 0x81C, 0xF31A0103, + 0x81C, 0xF21C0103, + 0x81C, 0xF11E0103, + 0x81C, 0xF0200103, + 0x81C, 0xEF220103, + 0x81C, 0xEE240103, + 0x81C, 0xED260103, + 0x81C, 0xEC280103, + 0x81C, 0xEB2A0103, + 0x81C, 0xEA2C0103, + 0x81C, 0xE92E0103, + 0x81C, 0xE8300103, + 0x81C, 0xE7320103, + 0x81C, 0xE6340103, + 0x81C, 0xE5360103, + 0x81C, 0xE4380103, + 0x81C, 0xE33A0103, + 0x81C, 0xA53C0103, + 0x81C, 0xA43E0103, + 0x81C, 0xA3400103, + 0x81C, 0xA2420103, + 0x81C, 0xA1440103, + 0x81C, 0x85460103, + 0x81C, 0x84480103, + 0x81C, 0x834A0103, + 0x81C, 0x824C0103, + 0x81C, 0x814E0103, + 0x81C, 0x64500103, + 0x81C, 0x63520103, + 0x81C, 0x62540103, + 0x81C, 0x44560103, + 0x81C, 0x43580103, + 0x81C, 0x425A0103, + 0x81C, 0x265C0103, + 0x81C, 0x255E0103, + 0x81C, 0x24600103, + 0x81C, 0x07620103, + 0x81C, 0x06640103, + 0x81C, 0x05660103, + 0x81C, 0x04680103, + 0x81C, 0x036A0103, + 0x81C, 0x026C0103, + 0x81C, 0x016E0103, + 0x81C, 0x01700103, + 0x81C, 0x01720103, + 0x81C, 0x01740103, + 0x81C, 0x01760103, + 0x81C, 0x01780103, + 0x81C, 0x017A0103, + 0x81C, 0x017C0103, + 0x81C, 0x017E0103, + 0x90000008, 0x00000000, 0x40000000, 0x00000000, + 0x81C, 0xF8000103, + 0x81C, 0xF7020103, + 0x81C, 0xF6040103, + 0x81C, 0xF5060103, + 0x81C, 0xF4080103, + 0x81C, 0xF30A0103, + 0x81C, 0xF20C0103, + 0x81C, 0xF10E0103, + 0x81C, 0xF0100103, + 0x81C, 0xEF120103, + 0x81C, 0xEE140103, + 0x81C, 0xED160103, + 0x81C, 0xEC180103, + 0x81C, 0xEB1A0103, + 0x81C, 0xEA1C0103, + 0x81C, 0xE91E0103, + 0x81C, 0xE8200103, + 0x81C, 0xE7220103, + 0x81C, 0xE6240103, + 0x81C, 0xE5260103, + 0x81C, 0xE4280103, + 0x81C, 0xE32A0103, + 0x81C, 0xE22C0103, + 0x81C, 0xE12E0103, + 0x81C, 0xA4300103, + 0x81C, 0xA3320103, + 0x81C, 0xA2340103, + 0x81C, 0xA1360103, + 0x81C, 0x85380103, + 0x81C, 0x843A0103, + 0x81C, 0x833C0103, + 0x81C, 0x823E0103, + 0x81C, 0x65400103, + 0x81C, 0x64420103, + 0x81C, 0x63440103, + 0x81C, 0x62460103, + 0x81C, 0x45480103, + 0x81C, 0x444A0103, + 0x81C, 0x434C0103, + 0x81C, 0x264E0103, + 0x81C, 0x25500103, + 0x81C, 0x24520103, + 0x81C, 0x08540103, + 0x81C, 0x07560103, + 0x81C, 0x06580103, + 0x81C, 0x055A0103, + 0x81C, 0x045C0103, + 0x81C, 0x035E0103, + 0x81C, 0x02600103, + 0x81C, 0x01620103, + 0x81C, 0x01640103, + 0x81C, 0x01660103, + 0x81C, 0x01680103, + 0x81C, 0x016A0103, + 0x81C, 0x016C0103, + 0x81C, 0x016E0103, + 0x81C, 0x01700103, + 0x81C, 0x01720103, + 0x81C, 0x01740103, + 0x81C, 0x01760103, + 0x81C, 0x01780103, + 0x81C, 0x017A0103, + 0x81C, 0x017C0103, + 0x81C, 0x017E0103, + 0x90000009, 0x00000000, 0x40000000, 0x00000000, + 0x81C, 0xFF000103, + 0x81C, 0xFF020103, + 0x81C, 0xFE040103, + 0x81C, 0xFD060103, + 0x81C, 0xFC080103, + 0x81C, 0xFB0A0103, + 0x81C, 0xFA0C0103, + 0x81C, 0xF90E0103, + 0x81C, 0xF8100103, + 0x81C, 0xF7120103, + 0x81C, 0xF6140103, + 0x81C, 0xF5160103, + 0x81C, 0xF4180103, + 0x81C, 0xF31A0103, + 0x81C, 0xF21C0103, + 0x81C, 0xF11E0103, + 0x81C, 0xF0200103, + 0x81C, 0xEF220103, + 0x81C, 0xEE240103, + 0x81C, 0xED260103, + 0x81C, 0xEC280103, + 0x81C, 0xEB2A0103, + 0x81C, 0xEA2C0103, + 0x81C, 0xE92E0103, + 0x81C, 0xE8300103, + 0x81C, 0xE7320103, + 0x81C, 0xE6340103, + 0x81C, 0xE5360103, + 0x81C, 0xE4380103, + 0x81C, 0xE33A0103, + 0x81C, 0xA53C0103, + 0x81C, 0xA43E0103, + 0x81C, 0xA3400103, + 0x81C, 0xA2420103, + 0x81C, 0xA1440103, + 0x81C, 0x85460103, + 0x81C, 0x84480103, + 0x81C, 0x834A0103, + 0x81C, 0x824C0103, + 0x81C, 0x814E0103, + 0x81C, 0x64500103, + 0x81C, 0x63520103, + 0x81C, 0x62540103, + 0x81C, 0x44560103, + 0x81C, 0x43580103, + 0x81C, 0x425A0103, + 0x81C, 0x265C0103, + 0x81C, 0x255E0103, + 0x81C, 0x24600103, + 0x81C, 0x07620103, + 0x81C, 0x06640103, + 0x81C, 0x05660103, + 0x81C, 0x04680103, + 0x81C, 0x036A0103, + 0x81C, 0x026C0103, + 0x81C, 0x016E0103, + 0x81C, 0x01700103, + 0x81C, 0x01720103, + 0x81C, 0x01740103, + 0x81C, 0x01760103, + 0x81C, 0x01780103, + 0x81C, 0x017A0103, + 0x81C, 0x017C0103, + 0x81C, 0x017E0103, + 0x9000000a, 0x00000000, 0x40000000, 0x00000000, + 0x81C, 0xF9000103, + 0x81C, 0xF8020103, + 0x81C, 0xF7040103, + 0x81C, 0xF6060103, + 0x81C, 0xF5080103, + 0x81C, 0xF40A0103, + 0x81C, 0xF30C0103, + 0x81C, 0xF20E0103, + 0x81C, 0xF1100103, + 0x81C, 0xF0120103, + 0x81C, 0xEF140103, + 0x81C, 0xEE160103, + 0x81C, 0xED180103, + 0x81C, 0xEC1A0103, + 0x81C, 0xEB1C0103, + 0x81C, 0xEA1E0103, + 0x81C, 0xE9200103, + 0x81C, 0xE8220103, + 0x81C, 0xE7240103, + 0x81C, 0xE6260103, + 0x81C, 0xE5280103, + 0x81C, 0xE42A0103, + 0x81C, 0xE32C0103, + 0x81C, 0xE22E0103, + 0x81C, 0xA6300103, + 0x81C, 0xA5320103, + 0x81C, 0xA4340103, + 0x81C, 0xA3360103, + 0x81C, 0xA2380103, + 0x81C, 0xA13A0103, + 0x81C, 0x843C0103, + 0x81C, 0x833E0103, + 0x81C, 0x82400103, + 0x81C, 0x81420103, + 0x81C, 0x64440103, + 0x81C, 0x63460103, + 0x81C, 0x62480103, + 0x81C, 0x614A0103, + 0x81C, 0x444C0103, + 0x81C, 0x434E0103, + 0x81C, 0x42500103, + 0x81C, 0x41520103, + 0x81C, 0x25540103, + 0x81C, 0x24560103, + 0x81C, 0x23580103, + 0x81C, 0x225A0103, + 0x81C, 0x055C0103, + 0x81C, 0x045E0103, + 0x81C, 0x03600103, + 0x81C, 0x02620103, + 0x81C, 0x01640103, + 0x81C, 0x01660103, + 0x81C, 0x01680103, + 0x81C, 0x016A0103, + 0x81C, 0x016C0103, + 0x81C, 0x016E0103, + 0x81C, 0x01700103, + 0x81C, 0x01720103, + 0x81C, 0x01740103, + 0x81C, 0x01760103, + 0x81C, 0x01780103, + 0x81C, 0x017A0103, + 0x81C, 0x017C0103, + 0x81C, 0x017E0103, + 0x9000000b, 0x00000000, 0x40000000, 0x00000000, + 0x81C, 0xFA000103, + 0x81C, 0xF9020103, + 0x81C, 0xF8040103, + 0x81C, 0xF7060103, + 0x81C, 0xF6080103, + 0x81C, 0xF50A0103, + 0x81C, 0xF40C0103, + 0x81C, 0xF30E0103, + 0x81C, 0xF2100103, + 0x81C, 0xF1120103, + 0x81C, 0xF0140103, + 0x81C, 0xEF160103, + 0x81C, 0xEE180103, + 0x81C, 0xED1A0103, + 0x81C, 0xCC1C0103, + 0x81C, 0xCB1E0103, + 0x81C, 0xCA200103, + 0x81C, 0xE9220103, + 0x81C, 0xE8240103, + 0x81C, 0xE7260103, + 0x81C, 0xE6280103, + 0x81C, 0xE42A0103, + 0x81C, 0xE32C0103, + 0x81C, 0xE22E0103, + 0x81C, 0xA7300103, + 0x81C, 0xA6320103, + 0x81C, 0xA5340103, + 0x81C, 0xA4360103, + 0x81C, 0xA3380103, + 0x81C, 0xA23A0103, + 0x81C, 0xA13C0103, + 0x81C, 0x843E0103, + 0x81C, 0x83400103, + 0x81C, 0x82420103, + 0x81C, 0x65440103, + 0x81C, 0x64460103, + 0x81C, 0x63480103, + 0x81C, 0x624A0103, + 0x81C, 0x614C0103, + 0x81C, 0x444E0103, + 0x81C, 0x43500103, + 0x81C, 0x42520103, + 0x81C, 0x41540103, + 0x81C, 0x24560103, + 0x81C, 0x23580103, + 0x81C, 0x055A0103, + 0x81C, 0x045C0103, + 0x81C, 0x035E0103, + 0x81C, 0x02600103, + 0x81C, 0x01620103, + 0x81C, 0x01640103, + 0x81C, 0x01660103, + 0x81C, 0x01680103, + 0x81C, 0x016A0103, + 0x81C, 0x016C0103, + 0x81C, 0x016E0103, + 0x81C, 0x01700103, + 0x81C, 0x01720103, + 0x81C, 0x01740103, + 0x81C, 0x01760103, + 0x81C, 0x01780103, + 0x81C, 0x017A0103, + 0x81C, 0x017C0103, + 0x81C, 0x017E0103, + 0xA0000000, 0x00000000, + 0x81C, 0xFF000103, + 0x81C, 0xFE020103, + 0x81C, 0xFD040103, + 0x81C, 0xFC060103, + 0x81C, 0xFB080103, + 0x81C, 0xFA0A0103, + 0x81C, 0xF90C0103, + 0x81C, 0xF80E0103, + 0x81C, 0xF7100103, + 0x81C, 0xF6120103, + 0x81C, 0xF5140103, + 0x81C, 0xF4160103, + 0x81C, 0xF3180103, + 0x81C, 0xF21A0103, + 0x81C, 0xF11C0103, + 0x81C, 0xF01E0103, + 0x81C, 0xEF200103, + 0x81C, 0xEE220103, + 0x81C, 0xED240103, + 0x81C, 0xEC260103, + 0x81C, 0xEB280103, + 0x81C, 0xEA2A0103, + 0x81C, 0xE92C0103, + 0x81C, 0xE82E0103, + 0x81C, 0xE7300103, + 0x81C, 0xE6320103, + 0x81C, 0xE5340103, + 0x81C, 0xE4360103, + 0x81C, 0xE3380103, + 0x81C, 0xE23A0103, + 0x81C, 0xE13C0103, + 0x81C, 0xA43E0103, + 0x81C, 0xA3400103, + 0x81C, 0xA2420103, + 0x81C, 0xA1440103, + 0x81C, 0x86460103, + 0x81C, 0x85480103, + 0x81C, 0x844A0103, + 0x81C, 0x834C0103, + 0x81C, 0x824E0103, + 0x81C, 0x81500103, + 0x81C, 0x64520103, + 0x81C, 0x63540103, + 0x81C, 0x62560103, + 0x81C, 0x61580103, + 0x81C, 0x435A0103, + 0x81C, 0x425C0103, + 0x81C, 0x415E0103, + 0x81C, 0x25600103, + 0x81C, 0x24620103, + 0x81C, 0x06640103, + 0x81C, 0x05660103, + 0x81C, 0x04680103, + 0x81C, 0x036A0103, + 0x81C, 0x026C0103, + 0x81C, 0x016E0103, + 0x81C, 0x01700103, + 0x81C, 0x01720103, + 0x81C, 0x01740103, + 0x81C, 0x01760103, + 0x81C, 0x01780103, + 0x81C, 0x017A0103, + 0x81C, 0x017C0103, + 0x81C, 0x017E0103, + 0xB0000000, 0x00000000, + 0x80000001, 0x00000000, 0x40000000, 0x00000000, + 0x81C, 0xFA000203, + 0x81C, 0xF9020203, + 0x81C, 0xF8040203, + 0x81C, 0xF7060203, + 0x81C, 0xF6080203, + 0x81C, 0xF50A0203, + 0x81C, 0xF40C0203, + 0x81C, 0xF30E0203, + 0x81C, 0xF2100203, + 0x81C, 0xF1120203, + 0x81C, 0xF0140203, + 0x81C, 0xEF160203, + 0x81C, 0xEE180203, + 0x81C, 0xED1A0203, + 0x81C, 0xEC1C0203, + 0x81C, 0xEB1E0203, + 0x81C, 0xEA200203, + 0x81C, 0xE9220203, + 0x81C, 0xE8240203, + 0x81C, 0xE7260203, + 0x81C, 0xE6280203, + 0x81C, 0xE52A0203, + 0x81C, 0xE42C0203, + 0x81C, 0xE32E0203, + 0x81C, 0xE2300203, + 0x81C, 0xE1320203, + 0x81C, 0xA5340203, + 0x81C, 0xA4360203, + 0x81C, 0xA3380203, + 0x81C, 0xA23A0203, + 0x81C, 0xA13C0203, + 0x81C, 0x843E0203, + 0x81C, 0x83400203, + 0x81C, 0x82420203, + 0x81C, 0x81440203, + 0x81C, 0x63460203, + 0x81C, 0x62480203, + 0x81C, 0x614A0203, + 0x81C, 0x464C0203, + 0x81C, 0x454E0203, + 0x81C, 0x44500203, + 0x81C, 0x43520203, + 0x81C, 0x42540203, + 0x81C, 0x41560203, + 0x81C, 0x24580203, + 0x81C, 0x235A0203, + 0x81C, 0x065C0203, + 0x81C, 0x055E0203, + 0x81C, 0x04600203, + 0x81C, 0x03620203, + 0x81C, 0x02640203, + 0x81C, 0x01660203, + 0x81C, 0x01680203, + 0x81C, 0x016A0203, + 0x81C, 0x016C0203, + 0x81C, 0x016E0203, + 0x81C, 0x01700203, + 0x81C, 0x01720203, + 0x81C, 0x01740203, + 0x81C, 0x01760203, + 0x81C, 0x01780203, + 0x81C, 0x017A0203, + 0x81C, 0x017C0203, + 0x81C, 0x017E0203, + 0x90000002, 0x00000000, 0x40000000, 0x00000000, + 0x81C, 0xF8000203, + 0x81C, 0xF7020203, + 0x81C, 0xF6040203, + 0x81C, 0xF5060203, + 0x81C, 0xF4080203, + 0x81C, 0xF30A0203, + 0x81C, 0xF20C0203, + 0x81C, 0xF10E0203, + 0x81C, 0xF0100203, + 0x81C, 0xEF120203, + 0x81C, 0xEE140203, + 0x81C, 0xED160203, + 0x81C, 0xEC180203, + 0x81C, 0xEB1A0203, + 0x81C, 0xEA1C0203, + 0x81C, 0xE91E0203, + 0x81C, 0xE8200203, + 0x81C, 0xE7220203, + 0x81C, 0xE6240203, + 0x81C, 0xE5260203, + 0x81C, 0xE4280203, + 0x81C, 0xE32A0203, + 0x81C, 0xE22C0203, + 0x81C, 0xE12E0203, + 0x81C, 0xA6300203, + 0x81C, 0xA5320203, + 0x81C, 0xA4340203, + 0x81C, 0xA3360203, + 0x81C, 0xA2380203, + 0x81C, 0x853A0203, + 0x81C, 0x843C0203, + 0x81C, 0x833E0203, + 0x81C, 0x82400203, + 0x81C, 0x81420203, + 0x81C, 0x64440203, + 0x81C, 0x63460203, + 0x81C, 0x62480203, + 0x81C, 0x614A0203, + 0x81C, 0x444C0203, + 0x81C, 0x434E0203, + 0x81C, 0x42500203, + 0x81C, 0x25520203, + 0x81C, 0x24540203, + 0x81C, 0x23560203, + 0x81C, 0x06580203, + 0x81C, 0x055A0203, + 0x81C, 0x045C0203, + 0x81C, 0x035E0203, + 0x81C, 0x02600203, + 0x81C, 0x01620203, + 0x81C, 0x01640203, + 0x81C, 0x01660203, + 0x81C, 0x01680203, + 0x81C, 0x016A0203, + 0x81C, 0x016C0203, + 0x81C, 0x016E0203, + 0x81C, 0x01700203, + 0x81C, 0x01720203, + 0x81C, 0x01740203, + 0x81C, 0x01760203, + 0x81C, 0x01780203, + 0x81C, 0x017A0203, + 0x81C, 0x017C0203, + 0x81C, 0x017E0203, + 0x90000003, 0x00000000, 0x40000000, 0x00000000, + 0x81C, 0xFC000203, + 0x81C, 0xFB020203, + 0x81C, 0xFA040203, + 0x81C, 0xF9060203, + 0x81C, 0xF8080203, + 0x81C, 0xF70A0203, + 0x81C, 0xF60C0203, + 0x81C, 0xF50E0203, + 0x81C, 0xF4100203, + 0x81C, 0xF3120203, + 0x81C, 0xF2140203, + 0x81C, 0xF1160203, + 0x81C, 0xF0180203, + 0x81C, 0xEF1A0203, + 0x81C, 0xEE1C0203, + 0x81C, 0xED1E0203, + 0x81C, 0xEC200203, + 0x81C, 0xEB220203, + 0x81C, 0xEA240203, + 0x81C, 0xE9260203, + 0x81C, 0xE8280203, + 0x81C, 0xE72A0203, + 0x81C, 0xE62C0203, + 0x81C, 0xE52E0203, + 0x81C, 0xE4300203, + 0x81C, 0xE3320203, + 0x81C, 0xE2340203, + 0x81C, 0xE1360203, + 0x81C, 0x87380203, + 0x81C, 0x863A0203, + 0x81C, 0x853C0203, + 0x81C, 0x843E0203, + 0x81C, 0x83400203, + 0x81C, 0x82420203, + 0x81C, 0x81440203, + 0x81C, 0x64460203, + 0x81C, 0x63480203, + 0x81C, 0x624A0203, + 0x81C, 0x474C0203, + 0x81C, 0x464E0203, + 0x81C, 0x45500203, + 0x81C, 0x44520203, + 0x81C, 0x43540203, + 0x81C, 0x42560203, + 0x81C, 0x24580203, + 0x81C, 0x235A0203, + 0x81C, 0x075C0203, + 0x81C, 0x065E0203, + 0x81C, 0x05600203, + 0x81C, 0x04620203, + 0x81C, 0x03640203, + 0x81C, 0x02660203, + 0x81C, 0x01680203, + 0x81C, 0x016A0203, + 0x81C, 0x016C0203, + 0x81C, 0x016E0203, + 0x81C, 0x01700203, + 0x81C, 0x01720203, + 0x81C, 0x01740203, + 0x81C, 0x01760203, + 0x81C, 0x01780203, + 0x81C, 0x017A0203, + 0x81C, 0x017C0203, + 0x81C, 0x017E0203, + 0x90000004, 0x00000000, 0x40000000, 0x00000000, + 0x81C, 0xF8000203, + 0x81C, 0xF7020203, + 0x81C, 0xF6040203, + 0x81C, 0xF5060203, + 0x81C, 0xF4080203, + 0x81C, 0xF30A0203, + 0x81C, 0xF20C0203, + 0x81C, 0xF10E0203, + 0x81C, 0xF0100203, + 0x81C, 0xEF120203, + 0x81C, 0xEE140203, + 0x81C, 0xED160203, + 0x81C, 0xEC180203, + 0x81C, 0xEB1A0203, + 0x81C, 0xEA1C0203, + 0x81C, 0xE91E0203, + 0x81C, 0xE8200203, + 0x81C, 0xE7220203, + 0x81C, 0xE6240203, + 0x81C, 0xE5260203, + 0x81C, 0xE4280203, + 0x81C, 0xE32A0203, + 0x81C, 0xE22C0203, + 0x81C, 0xE12E0203, + 0x81C, 0xA6300203, + 0x81C, 0xA5320203, + 0x81C, 0xA4340203, + 0x81C, 0xA3360203, + 0x81C, 0xA2380203, + 0x81C, 0xA13A0203, + 0x81C, 0x843C0203, + 0x81C, 0x833E0203, + 0x81C, 0x82400203, + 0x81C, 0x81420203, + 0x81C, 0x64440203, + 0x81C, 0x63460203, + 0x81C, 0x62480203, + 0x81C, 0x614A0203, + 0x81C, 0x444C0203, + 0x81C, 0x434E0203, + 0x81C, 0x42500203, + 0x81C, 0x41520203, + 0x81C, 0x25540203, + 0x81C, 0x24560203, + 0x81C, 0x23580203, + 0x81C, 0x065A0203, + 0x81C, 0x055C0203, + 0x81C, 0x045E0203, + 0x81C, 0x03600203, + 0x81C, 0x02620203, + 0x81C, 0x01640203, + 0x81C, 0x01660203, + 0x81C, 0x01680203, + 0x81C, 0x016A0203, + 0x81C, 0x016C0203, + 0x81C, 0x016E0203, + 0x81C, 0x01700203, + 0x81C, 0x01720203, + 0x81C, 0x01740203, + 0x81C, 0x01760203, + 0x81C, 0x01780203, + 0x81C, 0x017A0203, + 0x81C, 0x017C0203, + 0x81C, 0x017E0203, + 0x90000005, 0x00000000, 0x40000000, 0x00000000, + 0x81C, 0xFB000203, + 0x81C, 0xFA020203, + 0x81C, 0xF9040203, + 0x81C, 0xF8060203, + 0x81C, 0xF7080203, + 0x81C, 0xF60A0203, + 0x81C, 0xF50C0203, + 0x81C, 0xF40E0203, + 0x81C, 0xF3100203, + 0x81C, 0xF2120203, + 0x81C, 0xF1140203, + 0x81C, 0xF0160203, + 0x81C, 0xEF180203, + 0x81C, 0xEE1A0203, + 0x81C, 0xED1C0203, + 0x81C, 0xEC1E0203, + 0x81C, 0xEB200203, + 0x81C, 0xEA220203, + 0x81C, 0xE9240203, + 0x81C, 0xE8260203, + 0x81C, 0xE7280203, + 0x81C, 0xE62A0203, + 0x81C, 0xE52C0203, + 0x81C, 0xE42E0203, + 0x81C, 0xE3300203, + 0x81C, 0xE2320203, + 0x81C, 0xE1340203, + 0x81C, 0xA5360203, + 0x81C, 0xA4380203, + 0x81C, 0xA33A0203, + 0x81C, 0xA23C0203, + 0x81C, 0x843E0203, + 0x81C, 0x83400203, + 0x81C, 0x82420203, + 0x81C, 0x81440203, + 0x81C, 0x64460203, + 0x81C, 0x63480203, + 0x81C, 0x624A0203, + 0x81C, 0x614C0203, + 0x81C, 0x474E0203, + 0x81C, 0x46500203, + 0x81C, 0x45520203, + 0x81C, 0x44540203, + 0x81C, 0x43560203, + 0x81C, 0x25580203, + 0x81C, 0x245A0203, + 0x81C, 0x235C0203, + 0x81C, 0x075E0203, + 0x81C, 0x06600203, + 0x81C, 0x05620203, + 0x81C, 0x04640203, + 0x81C, 0x03660203, + 0x81C, 0x02680203, + 0x81C, 0x016A0203, + 0x81C, 0x016C0203, + 0x81C, 0x016E0203, + 0x81C, 0x01700203, + 0x81C, 0x01720203, + 0x81C, 0x01740203, + 0x81C, 0x01760203, + 0x81C, 0x01780203, + 0x81C, 0x017A0203, + 0x81C, 0x017C0203, + 0x81C, 0x017E0203, + 0x90000006, 0x00000000, 0x40000000, 0x00000000, + 0x81C, 0xFC000203, + 0x81C, 0xFB020203, + 0x81C, 0xFA040203, + 0x81C, 0xF9060203, + 0x81C, 0xF8080203, + 0x81C, 0xF70A0203, + 0x81C, 0xF60C0203, + 0x81C, 0xF50E0203, + 0x81C, 0xF4100203, + 0x81C, 0xF3120203, + 0x81C, 0xF2140203, + 0x81C, 0xF1160203, + 0x81C, 0xF0180203, + 0x81C, 0xEF1A0203, + 0x81C, 0xEE1C0203, + 0x81C, 0xED1E0203, + 0x81C, 0xEC200203, + 0x81C, 0xEB220203, + 0x81C, 0xEA240203, + 0x81C, 0xE9260203, + 0x81C, 0xE8280203, + 0x81C, 0xE72A0203, + 0x81C, 0xE62C0203, + 0x81C, 0xE52E0203, + 0x81C, 0xE4300203, + 0x81C, 0xE3320203, + 0x81C, 0xE2340203, + 0x81C, 0xE1360203, + 0x81C, 0xA5380203, + 0x81C, 0xA43A0203, + 0x81C, 0xA33C0203, + 0x81C, 0x853E0203, + 0x81C, 0x84400203, + 0x81C, 0x83420203, + 0x81C, 0x82440203, + 0x81C, 0x81460203, + 0x81C, 0x64480203, + 0x81C, 0x634A0203, + 0x81C, 0x624C0203, + 0x81C, 0x614E0203, + 0x81C, 0x46500203, + 0x81C, 0x45520203, + 0x81C, 0x44540203, + 0x81C, 0x43560203, + 0x81C, 0x25580203, + 0x81C, 0x245A0203, + 0x81C, 0x235C0203, + 0x81C, 0x075E0203, + 0x81C, 0x06600203, + 0x81C, 0x05620203, + 0x81C, 0x04640203, + 0x81C, 0x03660203, + 0x81C, 0x02680203, + 0x81C, 0x016A0203, + 0x81C, 0x016C0203, + 0x81C, 0x016E0203, + 0x81C, 0x01700203, + 0x81C, 0x01720203, + 0x81C, 0x01740203, + 0x81C, 0x01760203, + 0x81C, 0x01780203, + 0x81C, 0x017A0203, + 0x81C, 0x017C0203, + 0x81C, 0x017E0203, + 0x90000007, 0x00000000, 0x40000000, 0x00000000, + 0x81C, 0xFF000203, + 0x81C, 0xFF020203, + 0x81C, 0xFE040203, + 0x81C, 0xFD060203, + 0x81C, 0xFC080203, + 0x81C, 0xFB0A0203, + 0x81C, 0xFA0C0203, + 0x81C, 0xF90E0203, + 0x81C, 0xF8100203, + 0x81C, 0xF7120203, + 0x81C, 0xF6140203, + 0x81C, 0xF5160203, + 0x81C, 0xF4180203, + 0x81C, 0xF31A0203, + 0x81C, 0xF21C0203, + 0x81C, 0xF11E0203, + 0x81C, 0xF0200203, + 0x81C, 0xEF220203, + 0x81C, 0xEE240203, + 0x81C, 0xED260203, + 0x81C, 0xEC280203, + 0x81C, 0xEB2A0203, + 0x81C, 0xEA2C0203, + 0x81C, 0xE92E0203, + 0x81C, 0xE8300203, + 0x81C, 0xE7320203, + 0x81C, 0xE6340203, + 0x81C, 0xE5360203, + 0x81C, 0xE4380203, + 0x81C, 0xE33A0203, + 0x81C, 0xE23C0203, + 0x81C, 0xE13E0203, + 0x81C, 0xA4400203, + 0x81C, 0xA3420203, + 0x81C, 0xA2440203, + 0x81C, 0xA1460203, + 0x81C, 0x84480203, + 0x81C, 0x834A0203, + 0x81C, 0x824C0203, + 0x81C, 0x814E0203, + 0x81C, 0x64500203, + 0x81C, 0x63520203, + 0x81C, 0x62540203, + 0x81C, 0x61560203, + 0x81C, 0x45580203, + 0x81C, 0x445A0203, + 0x81C, 0x435C0203, + 0x81C, 0x425E0203, + 0x81C, 0x24600203, + 0x81C, 0x23620203, + 0x81C, 0x07640203, + 0x81C, 0x06660203, + 0x81C, 0x05680203, + 0x81C, 0x046A0203, + 0x81C, 0x036C0203, + 0x81C, 0x026E0203, + 0x81C, 0x01700203, + 0x81C, 0x01720203, + 0x81C, 0x01740203, + 0x81C, 0x01760203, + 0x81C, 0x01780203, + 0x81C, 0x017A0203, + 0x81C, 0x017C0203, + 0x81C, 0x017E0203, + 0x90000008, 0x00000000, 0x40000000, 0x00000000, + 0x81C, 0xF7000203, + 0x81C, 0xF6020203, + 0x81C, 0xF5040203, + 0x81C, 0xF4060203, + 0x81C, 0xF3080203, + 0x81C, 0xF20A0203, + 0x81C, 0xF10C0203, + 0x81C, 0xF00E0203, + 0x81C, 0xEF100203, + 0x81C, 0xEE120203, + 0x81C, 0xED140203, + 0x81C, 0xEC160203, + 0x81C, 0xEB180203, + 0x81C, 0xEA1A0203, + 0x81C, 0xE91C0203, + 0x81C, 0xE81E0203, + 0x81C, 0xE7200203, + 0x81C, 0xE6220203, + 0x81C, 0xE5240203, + 0x81C, 0xE4260203, + 0x81C, 0xE3280203, + 0x81C, 0xE22A0203, + 0x81C, 0xA62C0203, + 0x81C, 0xA52E0203, + 0x81C, 0xA4300203, + 0x81C, 0xA3320203, + 0x81C, 0xA2340203, + 0x81C, 0xA1360203, + 0x81C, 0x86380203, + 0x81C, 0x853A0203, + 0x81C, 0x843C0203, + 0x81C, 0x833E0203, + 0x81C, 0x65400203, + 0x81C, 0x64420203, + 0x81C, 0x63440203, + 0x81C, 0x46460203, + 0x81C, 0x45480203, + 0x81C, 0x444A0203, + 0x81C, 0x434C0203, + 0x81C, 0x264E0203, + 0x81C, 0x25500203, + 0x81C, 0x24520203, + 0x81C, 0x08540203, + 0x81C, 0x07560203, + 0x81C, 0x06580203, + 0x81C, 0x055A0203, + 0x81C, 0x045C0203, + 0x81C, 0x035E0203, + 0x81C, 0x02600203, + 0x81C, 0x01620203, + 0x81C, 0x01640203, + 0x81C, 0x01660203, + 0x81C, 0x01680203, + 0x81C, 0x016A0203, + 0x81C, 0x016C0203, + 0x81C, 0x016E0203, + 0x81C, 0x01700203, + 0x81C, 0x01720203, + 0x81C, 0x01740203, + 0x81C, 0x01760203, + 0x81C, 0x01780203, + 0x81C, 0x017A0203, + 0x81C, 0x017C0203, + 0x81C, 0x017E0203, + 0x90000009, 0x00000000, 0x40000000, 0x00000000, + 0x81C, 0xFF000203, + 0x81C, 0xFF020203, + 0x81C, 0xFE040203, + 0x81C, 0xFD060203, + 0x81C, 0xFC080203, + 0x81C, 0xFB0A0203, + 0x81C, 0xFA0C0203, + 0x81C, 0xF90E0203, + 0x81C, 0xF8100203, + 0x81C, 0xF7120203, + 0x81C, 0xF6140203, + 0x81C, 0xF5160203, + 0x81C, 0xF4180203, + 0x81C, 0xF31A0203, + 0x81C, 0xF21C0203, + 0x81C, 0xF11E0203, + 0x81C, 0xF0200203, + 0x81C, 0xEF220203, + 0x81C, 0xEE240203, + 0x81C, 0xED260203, + 0x81C, 0xEC280203, + 0x81C, 0xEB2A0203, + 0x81C, 0xEA2C0203, + 0x81C, 0xE92E0203, + 0x81C, 0xE8300203, + 0x81C, 0xE7320203, + 0x81C, 0xE6340203, + 0x81C, 0xE5360203, + 0x81C, 0xE4380203, + 0x81C, 0xE33A0203, + 0x81C, 0xE23C0203, + 0x81C, 0xE13E0203, + 0x81C, 0xA4400203, + 0x81C, 0xA3420203, + 0x81C, 0xA2440203, + 0x81C, 0xA1460203, + 0x81C, 0x84480203, + 0x81C, 0x834A0203, + 0x81C, 0x824C0203, + 0x81C, 0x814E0203, + 0x81C, 0x64500203, + 0x81C, 0x63520203, + 0x81C, 0x62540203, + 0x81C, 0x61560203, + 0x81C, 0x45580203, + 0x81C, 0x445A0203, + 0x81C, 0x435C0203, + 0x81C, 0x425E0203, + 0x81C, 0x24600203, + 0x81C, 0x23620203, + 0x81C, 0x07640203, + 0x81C, 0x06660203, + 0x81C, 0x05680203, + 0x81C, 0x046A0203, + 0x81C, 0x036C0203, + 0x81C, 0x026E0203, + 0x81C, 0x01700203, + 0x81C, 0x01720203, + 0x81C, 0x01740203, + 0x81C, 0x01760203, + 0x81C, 0x01780203, + 0x81C, 0x017A0203, + 0x81C, 0x017C0203, + 0x81C, 0x017E0203, + 0x9000000a, 0x00000000, 0x40000000, 0x00000000, + 0x81C, 0xF8000203, + 0x81C, 0xF7020203, + 0x81C, 0xF6040203, + 0x81C, 0xF5060203, + 0x81C, 0xF4080203, + 0x81C, 0xF30A0203, + 0x81C, 0xF20C0203, + 0x81C, 0xF10E0203, + 0x81C, 0xF0100203, + 0x81C, 0xEF120203, + 0x81C, 0xEE140203, + 0x81C, 0xED160203, + 0x81C, 0xEC180203, + 0x81C, 0xEB1A0203, + 0x81C, 0xEA1C0203, + 0x81C, 0xE91E0203, + 0x81C, 0xE8200203, + 0x81C, 0xE7220203, + 0x81C, 0xE6240203, + 0x81C, 0xE5260203, + 0x81C, 0xE4280203, + 0x81C, 0xE32A0203, + 0x81C, 0xE22C0203, + 0x81C, 0xE12E0203, + 0x81C, 0xA6300203, + 0x81C, 0xA5320203, + 0x81C, 0xA4340203, + 0x81C, 0xA3360203, + 0x81C, 0xA2380203, + 0x81C, 0xA13A0203, + 0x81C, 0x843C0203, + 0x81C, 0x833E0203, + 0x81C, 0x82400203, + 0x81C, 0x81420203, + 0x81C, 0x64440203, + 0x81C, 0x63460203, + 0x81C, 0x62480203, + 0x81C, 0x614A0203, + 0x81C, 0x444C0203, + 0x81C, 0x434E0203, + 0x81C, 0x42500203, + 0x81C, 0x41520203, + 0x81C, 0x25540203, + 0x81C, 0x24560203, + 0x81C, 0x23580203, + 0x81C, 0x065A0203, + 0x81C, 0x055C0203, + 0x81C, 0x045E0203, + 0x81C, 0x03600203, + 0x81C, 0x02620203, + 0x81C, 0x01640203, + 0x81C, 0x01660203, + 0x81C, 0x01680203, + 0x81C, 0x016A0203, + 0x81C, 0x016C0203, + 0x81C, 0x016E0203, + 0x81C, 0x01700203, + 0x81C, 0x01720203, + 0x81C, 0x01740203, + 0x81C, 0x01760203, + 0x81C, 0x01780203, + 0x81C, 0x017A0203, + 0x81C, 0x017C0203, + 0x81C, 0x017E0203, + 0x9000000b, 0x00000000, 0x40000000, 0x00000000, + 0x81C, 0xF9000203, + 0x81C, 0xF8020203, + 0x81C, 0xF7040203, + 0x81C, 0xF6060203, + 0x81C, 0xF5080203, + 0x81C, 0xF40A0203, + 0x81C, 0xF30C0203, + 0x81C, 0xF20E0203, + 0x81C, 0xF1100203, + 0x81C, 0xF0120203, + 0x81C, 0xEF140203, + 0x81C, 0xCE160203, + 0x81C, 0xCD180203, + 0x81C, 0xCC1A0203, + 0x81C, 0xCB1C0203, + 0x81C, 0xCA1E0203, + 0x81C, 0xC9200203, + 0x81C, 0xC8220203, + 0x81C, 0xC7240203, + 0x81C, 0xC6260203, + 0x81C, 0xC5280203, + 0x81C, 0xC42A0203, + 0x81C, 0xC32C0203, + 0x81C, 0xC22E0203, + 0x81C, 0xC1300203, + 0x81C, 0xA5320203, + 0x81C, 0xA4340203, + 0x81C, 0xA3360203, + 0x81C, 0xA2380203, + 0x81C, 0xA13A0203, + 0x81C, 0x853C0203, + 0x81C, 0x843E0203, + 0x81C, 0x83400203, + 0x81C, 0x82420203, + 0x81C, 0x81440203, + 0x81C, 0x64460203, + 0x81C, 0x63480203, + 0x81C, 0x624A0203, + 0x81C, 0x614C0203, + 0x81C, 0x444E0203, + 0x81C, 0x43500203, + 0x81C, 0x42520203, + 0x81C, 0x41540203, + 0x81C, 0x24560203, + 0x81C, 0x23580203, + 0x81C, 0x075A0203, + 0x81C, 0x065C0203, + 0x81C, 0x055E0203, + 0x81C, 0x04600203, + 0x81C, 0x03620203, + 0x81C, 0x02640203, + 0x81C, 0x01660203, + 0x81C, 0x01680203, + 0x81C, 0x016A0203, + 0x81C, 0x016C0203, + 0x81C, 0x016E0203, + 0x81C, 0x01700203, + 0x81C, 0x01720203, + 0x81C, 0x01740203, + 0x81C, 0x01760203, + 0x81C, 0x01780203, + 0x81C, 0x017A0203, + 0x81C, 0x017C0203, + 0x81C, 0x017E0203, + 0xA0000000, 0x00000000, + 0x81C, 0xFF000203, + 0x81C, 0xFF020203, + 0x81C, 0xFE040203, + 0x81C, 0xFD060203, + 0x81C, 0xFC080203, + 0x81C, 0xFB0A0203, + 0x81C, 0xFA0C0203, + 0x81C, 0xF90E0203, + 0x81C, 0xF8100203, + 0x81C, 0xF7120203, + 0x81C, 0xF6140203, + 0x81C, 0xF5160203, + 0x81C, 0xF4180203, + 0x81C, 0xF31A0203, + 0x81C, 0xF21C0203, + 0x81C, 0xF11E0203, + 0x81C, 0xF0200203, + 0x81C, 0xEF220203, + 0x81C, 0xEE240203, + 0x81C, 0xED260203, + 0x81C, 0xEC280203, + 0x81C, 0xEB2A0203, + 0x81C, 0xEA2C0203, + 0x81C, 0xE92E0203, + 0x81C, 0xE8300203, + 0x81C, 0xE7320203, + 0x81C, 0xE6340203, + 0x81C, 0xE5360203, + 0x81C, 0xE4380203, + 0x81C, 0xE33A0203, + 0x81C, 0xE23C0203, + 0x81C, 0xE13E0203, + 0x81C, 0xA4400203, + 0x81C, 0xA3420203, + 0x81C, 0xA2440203, + 0x81C, 0xA1460203, + 0x81C, 0x85480203, + 0x81C, 0x844A0203, + 0x81C, 0x834C0203, + 0x81C, 0x824E0203, + 0x81C, 0x81500203, + 0x81C, 0x64520203, + 0x81C, 0x63540203, + 0x81C, 0x62560203, + 0x81C, 0x61580203, + 0x81C, 0x445A0203, + 0x81C, 0x435C0203, + 0x81C, 0x425E0203, + 0x81C, 0x25600203, + 0x81C, 0x24620203, + 0x81C, 0x06640203, + 0x81C, 0x05660203, + 0x81C, 0x04680203, + 0x81C, 0x036A0203, + 0x81C, 0x026C0203, + 0x81C, 0x016E0203, + 0x81C, 0x01700203, + 0x81C, 0x01720203, + 0x81C, 0x01740203, + 0x81C, 0x01760203, + 0x81C, 0x01780203, + 0x81C, 0x017A0203, + 0x81C, 0x017C0203, + 0x81C, 0x017E0203, + 0xB0000000, 0x00000000, + 0x80000001, 0x00000000, 0x40000000, 0x00000000, + 0x81C, 0xF8000303, + 0x81C, 0xF7020303, + 0x81C, 0xF6040303, + 0x81C, 0xF5060303, + 0x81C, 0xF4080303, + 0x81C, 0xF30A0303, + 0x81C, 0xF20C0303, + 0x81C, 0xF10E0303, + 0x81C, 0xF0100303, + 0x81C, 0xEF120303, + 0x81C, 0xEE140303, + 0x81C, 0xED160303, + 0x81C, 0xEC180303, + 0x81C, 0xEB1A0303, + 0x81C, 0xEA1C0303, + 0x81C, 0xE91E0303, + 0x81C, 0xE8200303, + 0x81C, 0xE7220303, + 0x81C, 0xE6240303, + 0x81C, 0xE5260303, + 0x81C, 0xE4280303, + 0x81C, 0xE32A0303, + 0x81C, 0xE22C0303, + 0x81C, 0xE12E0303, + 0x81C, 0xA6300303, + 0x81C, 0xA5320303, + 0x81C, 0xA4340303, + 0x81C, 0xA3360303, + 0x81C, 0xA2380303, + 0x81C, 0xA13A0303, + 0x81C, 0x843C0303, + 0x81C, 0x833E0303, + 0x81C, 0x82400303, + 0x81C, 0x81420303, + 0x81C, 0x64440303, + 0x81C, 0x63460303, + 0x81C, 0x62480303, + 0x81C, 0x614A0303, + 0x81C, 0x454C0303, + 0x81C, 0x444E0303, + 0x81C, 0x43500303, + 0x81C, 0x42520303, + 0x81C, 0x41540303, + 0x81C, 0x24560303, + 0x81C, 0x23580303, + 0x81C, 0x065A0303, + 0x81C, 0x055C0303, + 0x81C, 0x045E0303, + 0x81C, 0x03600303, + 0x81C, 0x02620303, + 0x81C, 0x01640303, + 0x81C, 0x01660303, + 0x81C, 0x01680303, + 0x81C, 0x016A0303, + 0x81C, 0x016C0303, + 0x81C, 0x016E0303, + 0x81C, 0x01700303, + 0x81C, 0x01720303, + 0x81C, 0x01740303, + 0x81C, 0x01760303, + 0x81C, 0x01780303, + 0x81C, 0x017A0303, + 0x81C, 0x017C0303, + 0x81C, 0x017E0303, + 0x90000002, 0x00000000, 0x40000000, 0x00000000, + 0x81C, 0xF7000303, + 0x81C, 0xF6020303, + 0x81C, 0xF5040303, + 0x81C, 0xF4060303, + 0x81C, 0xF3080303, + 0x81C, 0xF20A0303, + 0x81C, 0xF10C0303, + 0x81C, 0xF00E0303, + 0x81C, 0xEF100303, + 0x81C, 0xEE120303, + 0x81C, 0xED140303, + 0x81C, 0xEC160303, + 0x81C, 0xEB180303, + 0x81C, 0xEA1A0303, + 0x81C, 0xE91C0303, + 0x81C, 0xE81E0303, + 0x81C, 0xE7200303, + 0x81C, 0xE6220303, + 0x81C, 0xE5240303, + 0x81C, 0xE4260303, + 0x81C, 0xE3280303, + 0x81C, 0xC32A0303, + 0x81C, 0xC22C0303, + 0x81C, 0xC12E0303, + 0x81C, 0xA5300303, + 0x81C, 0xA4320303, + 0x81C, 0xA3340303, + 0x81C, 0xA2360303, + 0x81C, 0xA1380303, + 0x81C, 0x853A0303, + 0x81C, 0x843C0303, + 0x81C, 0x833E0303, + 0x81C, 0x82400303, + 0x81C, 0x81420303, + 0x81C, 0x64440303, + 0x81C, 0x63460303, + 0x81C, 0x62480303, + 0x81C, 0x614A0303, + 0x81C, 0x454C0303, + 0x81C, 0x444E0303, + 0x81C, 0x43500303, + 0x81C, 0x25520303, + 0x81C, 0x24540303, + 0x81C, 0x23560303, + 0x81C, 0x06580303, + 0x81C, 0x055A0303, + 0x81C, 0x045C0303, + 0x81C, 0x035E0303, + 0x81C, 0x02600303, + 0x81C, 0x01620303, + 0x81C, 0x01640303, + 0x81C, 0x01660303, + 0x81C, 0x01680303, + 0x81C, 0x016A0303, + 0x81C, 0x016C0303, + 0x81C, 0x016E0303, + 0x81C, 0x01700303, + 0x81C, 0x01720303, + 0x81C, 0x01740303, + 0x81C, 0x01760303, + 0x81C, 0x01780303, + 0x81C, 0x017A0303, + 0x81C, 0x017C0303, + 0x81C, 0x017E0303, + 0x90000003, 0x00000000, 0x40000000, 0x00000000, + 0x81C, 0xF9000303, + 0x81C, 0xF8020303, + 0x81C, 0xF7040303, + 0x81C, 0xF6060303, + 0x81C, 0xF5080303, + 0x81C, 0xF40A0303, + 0x81C, 0xF30C0303, + 0x81C, 0xF20E0303, + 0x81C, 0xF1100303, + 0x81C, 0xF0120303, + 0x81C, 0xEF140303, + 0x81C, 0xEE160303, + 0x81C, 0xED180303, + 0x81C, 0xEC1A0303, + 0x81C, 0xEB1C0303, + 0x81C, 0xEA1E0303, + 0x81C, 0xE9200303, + 0x81C, 0xE8220303, + 0x81C, 0xE7240303, + 0x81C, 0xE6260303, + 0x81C, 0xE5280303, + 0x81C, 0xE42A0303, + 0x81C, 0xE32C0303, + 0x81C, 0xE22E0303, + 0x81C, 0xE1300303, + 0x81C, 0xA4320303, + 0x81C, 0xA3340303, + 0x81C, 0xA2360303, + 0x81C, 0xA1380303, + 0x81C, 0x853A0303, + 0x81C, 0x843C0303, + 0x81C, 0x833E0303, + 0x81C, 0x82400303, + 0x81C, 0x81420303, + 0x81C, 0x64440303, + 0x81C, 0x63460303, + 0x81C, 0x62480303, + 0x81C, 0x614A0303, + 0x81C, 0x444C0303, + 0x81C, 0x434E0303, + 0x81C, 0x42500303, + 0x81C, 0x25520303, + 0x81C, 0x24540303, + 0x81C, 0x23560303, + 0x81C, 0x07580303, + 0x81C, 0x065A0303, + 0x81C, 0x055C0303, + 0x81C, 0x045E0303, + 0x81C, 0x03600303, + 0x81C, 0x02620303, + 0x81C, 0x01640303, + 0x81C, 0x01660303, + 0x81C, 0x01680303, + 0x81C, 0x016A0303, + 0x81C, 0x016C0303, + 0x81C, 0x016E0303, + 0x81C, 0x01700303, + 0x81C, 0x01720303, + 0x81C, 0x01740303, + 0x81C, 0x01760303, + 0x81C, 0x01780303, + 0x81C, 0x017A0303, + 0x81C, 0x017C0303, + 0x81C, 0x017E0303, + 0x90000004, 0x00000000, 0x40000000, 0x00000000, + 0x81C, 0xF7000303, + 0x81C, 0xF6020303, + 0x81C, 0xF5040303, + 0x81C, 0xF4060303, + 0x81C, 0xF3080303, + 0x81C, 0xF20A0303, + 0x81C, 0xF10C0303, + 0x81C, 0xF00E0303, + 0x81C, 0xEF100303, + 0x81C, 0xEE120303, + 0x81C, 0xED140303, + 0x81C, 0xEC160303, + 0x81C, 0xEB180303, + 0x81C, 0xEA1A0303, + 0x81C, 0xE91C0303, + 0x81C, 0xE81E0303, + 0x81C, 0xE7200303, + 0x81C, 0xE6220303, + 0x81C, 0xE5240303, + 0x81C, 0xE4260303, + 0x81C, 0xE3280303, + 0x81C, 0xE22A0303, + 0x81C, 0xE12C0303, + 0x81C, 0xA72E0303, + 0x81C, 0xA6300303, + 0x81C, 0xA5320303, + 0x81C, 0xA4340303, + 0x81C, 0xA3360303, + 0x81C, 0xA2380303, + 0x81C, 0xA13A0303, + 0x81C, 0x843C0303, + 0x81C, 0x833E0303, + 0x81C, 0x82400303, + 0x81C, 0x81420303, + 0x81C, 0x64440303, + 0x81C, 0x63460303, + 0x81C, 0x62480303, + 0x81C, 0x614A0303, + 0x81C, 0x454C0303, + 0x81C, 0x444E0303, + 0x81C, 0x43500303, + 0x81C, 0x42520303, + 0x81C, 0x41540303, + 0x81C, 0x24560303, + 0x81C, 0x23580303, + 0x81C, 0x065A0303, + 0x81C, 0x055C0303, + 0x81C, 0x045E0303, + 0x81C, 0x03600303, + 0x81C, 0x02620303, + 0x81C, 0x01640303, + 0x81C, 0x01660303, + 0x81C, 0x01680303, + 0x81C, 0x016A0303, + 0x81C, 0x016C0303, + 0x81C, 0x016E0303, + 0x81C, 0x01700303, + 0x81C, 0x01720303, + 0x81C, 0x01740303, + 0x81C, 0x01760303, + 0x81C, 0x01780303, + 0x81C, 0x017A0303, + 0x81C, 0x017C0303, + 0x81C, 0x017E0303, + 0x90000005, 0x00000000, 0x40000000, 0x00000000, + 0x81C, 0xFB000303, + 0x81C, 0xFA020303, + 0x81C, 0xF9040303, + 0x81C, 0xF8060303, + 0x81C, 0xF7080303, + 0x81C, 0xF60A0303, + 0x81C, 0xF50C0303, + 0x81C, 0xF40E0303, + 0x81C, 0xF3100303, + 0x81C, 0xF2120303, + 0x81C, 0xF1140303, + 0x81C, 0xF0160303, + 0x81C, 0xEF180303, + 0x81C, 0xEE1A0303, + 0x81C, 0xED1C0303, + 0x81C, 0xEC1E0303, + 0x81C, 0xEB200303, + 0x81C, 0xEA220303, + 0x81C, 0xE9240303, + 0x81C, 0xE8260303, + 0x81C, 0xE7280303, + 0x81C, 0xE62A0303, + 0x81C, 0xE52C0303, + 0x81C, 0xE42E0303, + 0x81C, 0xE3300303, + 0x81C, 0xE2320303, + 0x81C, 0xE1340303, + 0x81C, 0xC2360303, + 0x81C, 0xC1380303, + 0x81C, 0xA33A0303, + 0x81C, 0xA23C0303, + 0x81C, 0x853E0303, + 0x81C, 0x84400303, + 0x81C, 0x83420303, + 0x81C, 0x66440303, + 0x81C, 0x65460303, + 0x81C, 0x64480303, + 0x81C, 0x634A0303, + 0x81C, 0x624C0303, + 0x81C, 0x614E0303, + 0x81C, 0x45500303, + 0x81C, 0x44520303, + 0x81C, 0x43540303, + 0x81C, 0x42560303, + 0x81C, 0x25580303, + 0x81C, 0x245A0303, + 0x81C, 0x235C0303, + 0x81C, 0x065E0303, + 0x81C, 0x05600303, + 0x81C, 0x04620303, + 0x81C, 0x03640303, + 0x81C, 0x02660303, + 0x81C, 0x01680303, + 0x81C, 0x016A0303, + 0x81C, 0x016C0303, + 0x81C, 0x016E0303, + 0x81C, 0x01700303, + 0x81C, 0x01720303, + 0x81C, 0x01740303, + 0x81C, 0x01760303, + 0x81C, 0x01780303, + 0x81C, 0x017A0303, + 0x81C, 0x017C0303, + 0x81C, 0x017E0303, + 0x90000006, 0x00000000, 0x40000000, 0x00000000, + 0x81C, 0xF9000303, + 0x81C, 0xF8020303, + 0x81C, 0xF7040303, + 0x81C, 0xF6060303, + 0x81C, 0xF5080303, + 0x81C, 0xF40A0303, + 0x81C, 0xF30C0303, + 0x81C, 0xF20E0303, + 0x81C, 0xF1100303, + 0x81C, 0xF0120303, + 0x81C, 0xEF140303, + 0x81C, 0xEE160303, + 0x81C, 0xED180303, + 0x81C, 0xEC1A0303, + 0x81C, 0xEB1C0303, + 0x81C, 0xEA1E0303, + 0x81C, 0xE9200303, + 0x81C, 0xE8220303, + 0x81C, 0xE7240303, + 0x81C, 0xE6260303, + 0x81C, 0xE5280303, + 0x81C, 0xE42A0303, + 0x81C, 0xE32C0303, + 0x81C, 0xE22E0303, + 0x81C, 0xE1300303, + 0x81C, 0xA6320303, + 0x81C, 0xA5340303, + 0x81C, 0xA4360303, + 0x81C, 0xA3380303, + 0x81C, 0xA23A0303, + 0x81C, 0xA13C0303, + 0x81C, 0x853E0303, + 0x81C, 0x84400303, + 0x81C, 0x83420303, + 0x81C, 0x82440303, + 0x81C, 0x81460303, + 0x81C, 0x64480303, + 0x81C, 0x634A0303, + 0x81C, 0x624C0303, + 0x81C, 0x614E0303, + 0x81C, 0x44500303, + 0x81C, 0x43520303, + 0x81C, 0x42540303, + 0x81C, 0x41560303, + 0x81C, 0x25580303, + 0x81C, 0x245A0303, + 0x81C, 0x235C0303, + 0x81C, 0x055E0303, + 0x81C, 0x04600303, + 0x81C, 0x03620303, + 0x81C, 0x02640303, + 0x81C, 0x01660303, + 0x81C, 0x01680303, + 0x81C, 0x016A0303, + 0x81C, 0x016C0303, + 0x81C, 0x016E0303, + 0x81C, 0x01700303, + 0x81C, 0x01720303, + 0x81C, 0x01740303, + 0x81C, 0x01760303, + 0x81C, 0x01780303, + 0x81C, 0x017A0303, + 0x81C, 0x017C0303, + 0x81C, 0x017E0303, + 0x90000007, 0x00000000, 0x40000000, 0x00000000, + 0x81C, 0xFE000303, + 0x81C, 0xFD020303, + 0x81C, 0xFC040303, + 0x81C, 0xFB060303, + 0x81C, 0xFA080303, + 0x81C, 0xF90A0303, + 0x81C, 0xF80C0303, + 0x81C, 0xF70E0303, + 0x81C, 0xF6100303, + 0x81C, 0xF5120303, + 0x81C, 0xF4140303, + 0x81C, 0xF3160303, + 0x81C, 0xF2180303, + 0x81C, 0xF11A0303, + 0x81C, 0xF01C0303, + 0x81C, 0xEF1E0303, + 0x81C, 0xEE200303, + 0x81C, 0xED220303, + 0x81C, 0xEC240303, + 0x81C, 0xEB260303, + 0x81C, 0xEA280303, + 0x81C, 0xE92A0303, + 0x81C, 0xE82C0303, + 0x81C, 0xE72E0303, + 0x81C, 0xE6300303, + 0x81C, 0xE5320303, + 0x81C, 0xE4340303, + 0x81C, 0xE3360303, + 0x81C, 0xC3380303, + 0x81C, 0xC23A0303, + 0x81C, 0xC13C0303, + 0x81C, 0xA43E0303, + 0x81C, 0xA3400303, + 0x81C, 0xA2420303, + 0x81C, 0xA1440303, + 0x81C, 0x85460303, + 0x81C, 0x84480303, + 0x81C, 0x834A0303, + 0x81C, 0x824C0303, + 0x81C, 0x814E0303, + 0x81C, 0x64500303, + 0x81C, 0x63520303, + 0x81C, 0x62540303, + 0x81C, 0x61560303, + 0x81C, 0x44580303, + 0x81C, 0x435A0303, + 0x81C, 0x425C0303, + 0x81C, 0x265E0303, + 0x81C, 0x25600303, + 0x81C, 0x24620303, + 0x81C, 0x06640303, + 0x81C, 0x05660303, + 0x81C, 0x04680303, + 0x81C, 0x036A0303, + 0x81C, 0x026C0303, + 0x81C, 0x016E0303, + 0x81C, 0x01700303, + 0x81C, 0x01720303, + 0x81C, 0x01740303, + 0x81C, 0x01760303, + 0x81C, 0x01780303, + 0x81C, 0x017A0303, + 0x81C, 0x017C0303, + 0x81C, 0x017E0303, + 0x90000008, 0x00000000, 0x40000000, 0x00000000, + 0x81C, 0xF7000303, + 0x81C, 0xF6020303, + 0x81C, 0xF5040303, + 0x81C, 0xF4060303, + 0x81C, 0xF3080303, + 0x81C, 0xF20A0303, + 0x81C, 0xF10C0303, + 0x81C, 0xF00E0303, + 0x81C, 0xEF100303, + 0x81C, 0xEE120303, + 0x81C, 0xED140303, + 0x81C, 0xEC160303, + 0x81C, 0xEB180303, + 0x81C, 0xEA1A0303, + 0x81C, 0xE91C0303, + 0x81C, 0xE81E0303, + 0x81C, 0xE7200303, + 0x81C, 0xE6220303, + 0x81C, 0xE5240303, + 0x81C, 0xE4260303, + 0x81C, 0xE3280303, + 0x81C, 0xE22A0303, + 0x81C, 0xA62C0303, + 0x81C, 0xA52E0303, + 0x81C, 0xA4300303, + 0x81C, 0xA3320303, + 0x81C, 0xA2340303, + 0x81C, 0x87360303, + 0x81C, 0x86380303, + 0x81C, 0x853A0303, + 0x81C, 0x843C0303, + 0x81C, 0x833E0303, + 0x81C, 0x66400303, + 0x81C, 0x65420303, + 0x81C, 0x64440303, + 0x81C, 0x45460303, + 0x81C, 0x44480303, + 0x81C, 0x434A0303, + 0x81C, 0x274C0303, + 0x81C, 0x264E0303, + 0x81C, 0x25500303, + 0x81C, 0x24520303, + 0x81C, 0x23540303, + 0x81C, 0x08560303, + 0x81C, 0x07580303, + 0x81C, 0x065A0303, + 0x81C, 0x055C0303, + 0x81C, 0x045E0303, + 0x81C, 0x03600303, + 0x81C, 0x02620303, + 0x81C, 0x01640303, + 0x81C, 0x01660303, + 0x81C, 0x01680303, + 0x81C, 0x016A0303, + 0x81C, 0x016C0303, + 0x81C, 0x016E0303, + 0x81C, 0x01700303, + 0x81C, 0x01720303, + 0x81C, 0x01740303, + 0x81C, 0x01760303, + 0x81C, 0x01780303, + 0x81C, 0x017A0303, + 0x81C, 0x017C0303, + 0x81C, 0x017E0303, + 0x90000009, 0x00000000, 0x40000000, 0x00000000, + 0x81C, 0xFE000303, + 0x81C, 0xFD020303, + 0x81C, 0xFC040303, + 0x81C, 0xFB060303, + 0x81C, 0xFA080303, + 0x81C, 0xF90A0303, + 0x81C, 0xF80C0303, + 0x81C, 0xF70E0303, + 0x81C, 0xF6100303, + 0x81C, 0xF5120303, + 0x81C, 0xF4140303, + 0x81C, 0xF3160303, + 0x81C, 0xF2180303, + 0x81C, 0xF11A0303, + 0x81C, 0xF01C0303, + 0x81C, 0xEF1E0303, + 0x81C, 0xEE200303, + 0x81C, 0xED220303, + 0x81C, 0xEC240303, + 0x81C, 0xEB260303, + 0x81C, 0xEA280303, + 0x81C, 0xE92A0303, + 0x81C, 0xE82C0303, + 0x81C, 0xE72E0303, + 0x81C, 0xE6300303, + 0x81C, 0xE5320303, + 0x81C, 0xE4340303, + 0x81C, 0xE3360303, + 0x81C, 0xC3380303, + 0x81C, 0xC23A0303, + 0x81C, 0xC13C0303, + 0x81C, 0xA43E0303, + 0x81C, 0xA3400303, + 0x81C, 0xA2420303, + 0x81C, 0xA1440303, + 0x81C, 0x85460303, + 0x81C, 0x84480303, + 0x81C, 0x834A0303, + 0x81C, 0x824C0303, + 0x81C, 0x814E0303, + 0x81C, 0x64500303, + 0x81C, 0x63520303, + 0x81C, 0x62540303, + 0x81C, 0x61560303, + 0x81C, 0x44580303, + 0x81C, 0x435A0303, + 0x81C, 0x425C0303, + 0x81C, 0x265E0303, + 0x81C, 0x25600303, + 0x81C, 0x24620303, + 0x81C, 0x06640303, + 0x81C, 0x05660303, + 0x81C, 0x04680303, + 0x81C, 0x036A0303, + 0x81C, 0x026C0303, + 0x81C, 0x016E0303, + 0x81C, 0x01700303, + 0x81C, 0x01720303, + 0x81C, 0x01740303, + 0x81C, 0x01760303, + 0x81C, 0x01780303, + 0x81C, 0x017A0303, + 0x81C, 0x017C0303, + 0x81C, 0x017E0303, + 0x9000000a, 0x00000000, 0x40000000, 0x00000000, + 0x81C, 0xF7000303, + 0x81C, 0xF6020303, + 0x81C, 0xF5040303, + 0x81C, 0xF4060303, + 0x81C, 0xF3080303, + 0x81C, 0xF20A0303, + 0x81C, 0xF10C0303, + 0x81C, 0xF00E0303, + 0x81C, 0xEF100303, + 0x81C, 0xEE120303, + 0x81C, 0xED140303, + 0x81C, 0xEC160303, + 0x81C, 0xEB180303, + 0x81C, 0xEA1A0303, + 0x81C, 0xE91C0303, + 0x81C, 0xE81E0303, + 0x81C, 0xE7200303, + 0x81C, 0xE6220303, + 0x81C, 0xE5240303, + 0x81C, 0xE4260303, + 0x81C, 0xE3280303, + 0x81C, 0xE22A0303, + 0x81C, 0xE12C0303, + 0x81C, 0xA72E0303, + 0x81C, 0xA6300303, + 0x81C, 0xA5320303, + 0x81C, 0xA4340303, + 0x81C, 0xA3360303, + 0x81C, 0xA2380303, + 0x81C, 0xA13A0303, + 0x81C, 0x843C0303, + 0x81C, 0x833E0303, + 0x81C, 0x82400303, + 0x81C, 0x81420303, + 0x81C, 0x64440303, + 0x81C, 0x63460303, + 0x81C, 0x62480303, + 0x81C, 0x614A0303, + 0x81C, 0x454C0303, + 0x81C, 0x444E0303, + 0x81C, 0x43500303, + 0x81C, 0x42520303, + 0x81C, 0x41540303, + 0x81C, 0x24560303, + 0x81C, 0x23580303, + 0x81C, 0x065A0303, + 0x81C, 0x055C0303, + 0x81C, 0x045E0303, + 0x81C, 0x03600303, + 0x81C, 0x02620303, + 0x81C, 0x01640303, + 0x81C, 0x01660303, + 0x81C, 0x01680303, + 0x81C, 0x016A0303, + 0x81C, 0x016C0303, + 0x81C, 0x016E0303, + 0x81C, 0x01700303, + 0x81C, 0x01720303, + 0x81C, 0x01740303, + 0x81C, 0x01760303, + 0x81C, 0x01780303, + 0x81C, 0x017A0303, + 0x81C, 0x017C0303, + 0x81C, 0x017E0303, + 0x9000000b, 0x00000000, 0x40000000, 0x00000000, + 0x81C, 0xF7000303, + 0x81C, 0xF6020303, + 0x81C, 0xF5040303, + 0x81C, 0xF4060303, + 0x81C, 0xF3080303, + 0x81C, 0xF20A0303, + 0x81C, 0xF10C0303, + 0x81C, 0xF00E0303, + 0x81C, 0xEF100303, + 0x81C, 0xEE120303, + 0x81C, 0xED140303, + 0x81C, 0xEC160303, + 0x81C, 0xEB180303, + 0x81C, 0xEA1A0303, + 0x81C, 0xAF1C0303, + 0x81C, 0xAE1E0303, + 0x81C, 0xAD200303, + 0x81C, 0xAC220303, + 0x81C, 0xAB240303, + 0x81C, 0xAA260303, + 0x81C, 0xC5280303, + 0x81C, 0xC42A0303, + 0x81C, 0xC32C0303, + 0x81C, 0xC22E0303, + 0x81C, 0xA5300303, + 0x81C, 0xA4320303, + 0x81C, 0xA3340303, + 0x81C, 0xA2360303, + 0x81C, 0xA1380303, + 0x81C, 0x853A0303, + 0x81C, 0x843C0303, + 0x81C, 0x833E0303, + 0x81C, 0x82400303, + 0x81C, 0x81420303, + 0x81C, 0x64440303, + 0x81C, 0x63460303, + 0x81C, 0x62480303, + 0x81C, 0x614A0303, + 0x81C, 0x444C0303, + 0x81C, 0x434E0303, + 0x81C, 0x42500303, + 0x81C, 0x41520303, + 0x81C, 0x25540303, + 0x81C, 0x24560303, + 0x81C, 0x06580303, + 0x81C, 0x055A0303, + 0x81C, 0x045C0303, + 0x81C, 0x035E0303, + 0x81C, 0x02600303, + 0x81C, 0x01620303, + 0x81C, 0x01640303, + 0x81C, 0x01660303, + 0x81C, 0x01680303, + 0x81C, 0x016A0303, + 0x81C, 0x016C0303, + 0x81C, 0x016E0303, + 0x81C, 0x01700303, + 0x81C, 0x01720303, + 0x81C, 0x01740303, + 0x81C, 0x01760303, + 0x81C, 0x01780303, + 0x81C, 0x017A0303, + 0x81C, 0x017C0303, + 0x81C, 0x017E0303, + 0xA0000000, 0x00000000, + 0x81C, 0xFD000303, + 0x81C, 0xFC020303, + 0x81C, 0xFB040303, + 0x81C, 0xFA060303, + 0x81C, 0xF9080303, + 0x81C, 0xF80A0303, + 0x81C, 0xF70C0303, + 0x81C, 0xF60E0303, + 0x81C, 0xF5100303, + 0x81C, 0xF4120303, + 0x81C, 0xF3140303, + 0x81C, 0xF2160303, + 0x81C, 0xF1180303, + 0x81C, 0xF01A0303, + 0x81C, 0xEF1C0303, + 0x81C, 0xEE1E0303, + 0x81C, 0xED200303, + 0x81C, 0xEC220303, + 0x81C, 0xEB240303, + 0x81C, 0xEA260303, + 0x81C, 0xE9280303, + 0x81C, 0xE82A0303, + 0x81C, 0xE72C0303, + 0x81C, 0xE62E0303, + 0x81C, 0xE5300303, + 0x81C, 0xE4320303, + 0x81C, 0xE3340303, + 0x81C, 0xE2360303, + 0x81C, 0xE1380303, + 0x81C, 0xA53A0303, + 0x81C, 0xA43C0303, + 0x81C, 0xA33E0303, + 0x81C, 0xA2400303, + 0x81C, 0xA1420303, + 0x81C, 0x87440303, + 0x81C, 0x86460303, + 0x81C, 0x85480303, + 0x81C, 0x844A0303, + 0x81C, 0x834C0303, + 0x81C, 0x824E0303, + 0x81C, 0x81500303, + 0x81C, 0x64520303, + 0x81C, 0x63540303, + 0x81C, 0x62560303, + 0x81C, 0x61580303, + 0x81C, 0x435A0303, + 0x81C, 0x425C0303, + 0x81C, 0x415E0303, + 0x81C, 0x07600303, + 0x81C, 0x06620303, + 0x81C, 0x05640303, + 0x81C, 0x04660303, + 0x81C, 0x03680303, + 0x81C, 0x026A0303, + 0x81C, 0x016C0303, + 0x81C, 0x016E0303, + 0x81C, 0x01700303, + 0x81C, 0x01720303, + 0x81C, 0x01740303, + 0x81C, 0x01760303, + 0x81C, 0x01780303, + 0x81C, 0x017A0303, + 0x81C, 0x017C0303, + 0x81C, 0x017E0303, + 0xB0000000, 0x00000000, + 0xC50, 0x00000022, + 0xC50, 0x00000020, + 0xE50, 0x00000022, + 0xE50, 0x00000020, + 0x1850, 0x00000022, + 0x1850, 0x00000020, + 0x1A50, 0x00000022, + 0x1A50, 0x00000020, +}; + +RTW_DECL_TABLE_PHY_COND(rtw8814a_agc, rtw_phy_cfg_agc); + +static const u32 rtw8814a_bb[] = { + 0x800, 0x9020D010, + 0x804, 0x08011280, + 0x808, 0x0E0282FF, + 0x80C, 0x1000002F, + 0x80000003, 0x00000000, 0x40000000, 0x00000000, + 0x810, 0x33303265, + 0xA0000000, 0x00000000, + 0x810, 0x33303265, + 0xB0000000, 0x00000000, + 0x814, 0x020C3D10, + 0x818, 0x04A10385, + 0x820, 0x00000000, + 0x824, 0x00033E40, + 0x828, 0x00000000, + 0x82C, 0x73985170, + 0x830, 0x79A0EA08, + 0x834, 0x042E708A, + 0x80000002, 0x00000000, 0x40000000, 0x00000000, + 0x838, 0x86667640, + 0x90000004, 0x00000000, 0x40000000, 0x00000000, + 0x838, 0x86667641, + 0x9000000a, 0x00000000, 0x40000000, 0x00000000, + 0x838, 0x86667641, + 0x9000000b, 0x00000000, 0x40000000, 0x00000000, + 0x838, 0x86667641, + 0xA0000000, 0x00000000, + 0x838, 0x86667640, + 0xB0000000, 0x00000000, + 0x83C, 0x9798B9B9, + 0x840, 0x17578F60, + 0x844, 0x4BBDFCDE, + 0x848, 0x5CD07F8B, + 0x84C, 0x6CFBF7B5, + 0x850, 0x28834706, + 0x854, 0x0001520C, + 0x858, 0x4060C000, + 0x85C, 0x74210368, + 0x860, 0x6929C321, + 0x864, 0x79727432, + 0x868, 0x8CA7A314, + 0x86C, 0x438C2878, + 0x870, 0x44444444, + 0x874, 0x21612C2E, + 0x878, 0x00003152, + 0x87C, 0x000FC000, + 0x8A0, 0x00000013, + 0x8A4, 0x7F7F7F7F, + 0x8A8, 0xA202033E, + 0x8AC, 0xF40F550A, + 0x8B0, 0x00000600, + 0x8B4, 0x000FC080, + 0x8B8, 0xEC0057FF, + 0x8BC, 0x8CA520C3, + 0x8C0, 0x3FF00020, + 0x8C4, 0x44C00000, + 0x80000009, 0x00000000, 0x40000000, 0x00000000, + 0x8C8, 0x80025969, + 0xA0000000, 0x00000000, + 0x8C8, 0x80025167, + 0xB0000000, 0x00000000, + 0x8CC, 0x08250492, + 0x8D0, 0x0000B800, + 0x8D4, 0x940008A0, + 0x8D8, 0x290B5612, + 0x8DC, 0x00000000, + 0x8E0, 0x32316407, + 0x8E4, 0x4A092925, + 0x8E8, 0xFFFFC42C, + 0x8EC, 0x99999999, + 0x8F0, 0x00009999, + 0x8F4, 0x00F80FA1, + 0x8F8, 0x400082C0, + 0x8FC, 0x00000000, + 0x900, 0x00400700, + 0x90C, 0x09004000, + 0x910, 0x0000FC00, + 0x914, 0xD6400404, + 0x918, 0x1C1028C0, + 0x91C, 0x64B11A1C, + 0x920, 0xE0767233, + 0x924, 0x055AA500, + 0x928, 0x4AB0E4E4, + 0x92C, 0xFFFE0000, + 0x930, 0xFFFFFFFE, + 0x934, 0x001FFFFF, + 0x938, 0x00008400, + 0x93C, 0x932C0642, + 0x940, 0x093E9360, + 0x944, 0x08000000, + 0x948, 0x04000000, + 0x950, 0x02010080, + 0x954, 0x86510080, + 0x960, 0x00000000, + 0x964, 0x00000000, + 0x968, 0x00000000, + 0x96C, 0x00000000, + 0x970, 0x801FFFFF, + 0x978, 0x00000000, + 0x97C, 0x00000000, + 0x980, 0x00000000, + 0x984, 0x00000000, + 0x988, 0x00000000, + 0x98C, 0x03440000, + 0x990, 0x27100000, + 0x994, 0xFFFF0100, + 0x998, 0xFFFFFF5C, + 0x99C, 0xFFFFFFFF, + 0x9A0, 0x000000FF, + 0x9A4, 0x00080080, + 0x9A8, 0x0C2F0000, + 0x9AC, 0x00560000, + 0x9B0, 0x81081008, + 0x9B4, 0x00000000, + 0x9B8, 0x01081008, + 0x9BC, 0x01081008, + 0x9D0, 0x00000000, + 0x9D4, 0x00000000, + 0x9D8, 0x00000000, + 0x9DC, 0x00000000, + 0x9E4, 0x00000002, + 0x9E8, 0x000022D5, + 0x9FC, 0xEFFFF7FF, + 0xB00, 0xE3100000, + 0xB04, 0x0000B000, + 0xB0C, 0x31EAA006, + 0xB5C, 0x41CFFFFF, + 0xC00, 0x00000007, + 0xC04, 0x00042020, + 0xC08, 0x80410231, + 0xC0C, 0x00000000, + 0xC10, 0x00000100, + 0xC14, 0x01000000, + 0xC1C, 0x40000053, + 0xC50, 0x00000020, + 0xC54, 0x00000000, + 0x80000002, 0x00000000, 0x40000000, 0x00000000, + 0xC58, 0x3C0A0C14, + 0x90000004, 0x00000000, 0x40000000, 0x00000000, + 0xC58, 0x3C0A0C14, + 0x9000000a, 0x00000000, 0x40000000, 0x00000000, + 0xC58, 0x3C0A0C14, + 0x9000000b, 0x00000000, 0x40000000, 0x00000000, + 0xC58, 0x3C0A0C14, + 0xA0000000, 0x00000000, + 0xC58, 0x3C020C14, + 0xB0000000, 0x00000000, + 0xC5C, 0x0D000058, + 0xC60, 0x1B800000, + 0xC60, 0x0B800001, + 0xC60, 0x05800002, + 0xC60, 0x07800003, + 0xC60, 0x1A800004, + 0xC60, 0x0B800005, + 0xC60, 0x05800006, + 0xC60, 0x0E800007, + 0xC60, 0x1A800008, + 0xC60, 0x0B800009, + 0xC60, 0x1580000A, + 0xC60, 0x0880000B, + 0xC60, 0x1A80000C, + 0xC60, 0x0B80000D, + 0xC60, 0x0580000E, + 0xC60, 0x0E80000F, + 0xC60, 0x1A800010, + 0xC60, 0x0B800011, + 0xC60, 0x15800012, + 0xC60, 0x08800013, + 0xC60, 0x1A800014, + 0xC60, 0x0B800015, + 0xC60, 0x05800016, + 0xC60, 0x07800017, + 0xC60, 0x1A800018, + 0xC60, 0x0B800019, + 0xC60, 0x1580001A, + 0xC60, 0x0880001B, + 0xC60, 0x1B80001C, + 0xC60, 0x0B80001D, + 0xC60, 0x0580001E, + 0xC60, 0x0780001F, + 0xC60, 0x1B800020, + 0xC60, 0x0B800021, + 0xC60, 0x05800022, + 0xC60, 0x07800023, + 0xC60, 0x1B800024, + 0xC60, 0x0B800025, + 0xC60, 0x05800026, + 0xC60, 0x07800027, + 0xC60, 0x1B800028, + 0xC60, 0x0B800029, + 0xC60, 0x0580002A, + 0xC60, 0x0780002B, + 0xC60, 0x1B800030, + 0xC60, 0x0B800031, + 0xC60, 0x05800032, + 0xC60, 0x00800033, + 0xC60, 0x1B800034, + 0xC60, 0x0B800035, + 0xC60, 0x05800036, + 0xC60, 0x00800037, + 0xC60, 0x1B800038, + 0xC60, 0x0B800039, + 0xC60, 0x0580003A, + 0xC60, 0x0E80803B, + 0xC94, 0x01000401, + 0xC98, 0x00188000, + 0xCA0, 0x00002929, + 0xCA4, 0x08040201, + 0xCA8, 0x80402010, + 0xCAC, 0x77777000, + 0xCB0, 0x54775477, + 0xCB4, 0x54775477, + 0xCB8, 0x00500000, + 0xCBC, 0x77700000, + 0xCC0, 0x00000010, + 0xCC8, 0x00000010, + 0xE00, 0x00000007, + 0xE04, 0x00042020, + 0xE08, 0x80410231, + 0xE0C, 0x00000000, + 0xE10, 0x00000100, + 0xE14, 0x01000000, + 0xE1C, 0x40000053, + 0xE50, 0x00000020, + 0xE54, 0x00000000, + 0x80000002, 0x00000000, 0x40000000, 0x00000000, + 0xE58, 0x3C0A0C14, + 0x90000004, 0x00000000, 0x40000000, 0x00000000, + 0xE58, 0x3C0A0C14, + 0x9000000a, 0x00000000, 0x40000000, 0x00000000, + 0xE58, 0x3C0A0C14, + 0x9000000b, 0x00000000, 0x40000000, 0x00000000, + 0xE58, 0x3C0A0C14, + 0xA0000000, 0x00000000, + 0xE58, 0x3C020C14, + 0xB0000000, 0x00000000, + 0xE5C, 0x0D000058, + 0xE60, 0x1B800000, + 0xE60, 0x0B800001, + 0xE60, 0x05800002, + 0xE60, 0x07800003, + 0xE60, 0x1A800004, + 0xE60, 0x0B800005, + 0xE60, 0x05800006, + 0xE60, 0x0E800007, + 0xE60, 0x1A800008, + 0xE60, 0x0B800009, + 0xE60, 0x1580000A, + 0xE60, 0x0880000B, + 0xE60, 0x1A80000C, + 0xE60, 0x0B80000D, + 0xE60, 0x0580000E, + 0xE60, 0x0E80000F, + 0xE60, 0x1A800010, + 0xE60, 0x0B800011, + 0xE60, 0x15800012, + 0xE60, 0x08800013, + 0xE60, 0x1A800014, + 0xE60, 0x0B800015, + 0xE60, 0x05800016, + 0xE60, 0x07800017, + 0xE60, 0x1A800018, + 0xE60, 0x0B800019, + 0xE60, 0x1580001A, + 0xE60, 0x0880001B, + 0xE60, 0x1B80001C, + 0xE60, 0x0B80001D, + 0xE60, 0x0580001E, + 0xE60, 0x0780001F, + 0xE60, 0x1B800020, + 0xE60, 0x0B800021, + 0xE60, 0x05800022, + 0xE60, 0x07800023, + 0xE60, 0x1B800024, + 0xE60, 0x0B800025, + 0xE60, 0x05800026, + 0xE60, 0x07800027, + 0xE60, 0x1B800028, + 0xE60, 0x0B800029, + 0xE60, 0x0580002A, + 0xE60, 0x0780002B, + 0xE60, 0x1B800030, + 0xE60, 0x0B800031, + 0xE60, 0x05800032, + 0xE60, 0x00800033, + 0xE60, 0x1B800034, + 0xE60, 0x0B800035, + 0xE60, 0x05800036, + 0xE60, 0x00800037, + 0xE60, 0x1B800038, + 0xE60, 0x0B800039, + 0xE60, 0x0580003A, + 0xE60, 0x0E80803B, + 0xE94, 0x01000401, + 0xE98, 0x00188000, + 0xEA0, 0x00002929, + 0xEA4, 0x08040201, + 0xEA8, 0x80402010, + 0xEAC, 0x77777000, + 0xEB0, 0x54775477, + 0xEB4, 0x54775477, + 0xEB8, 0x00500000, + 0xEBC, 0x77700000, + 0x1800, 0x00000007, + 0x1804, 0x00042020, + 0x1808, 0x80410231, + 0x180C, 0x00000000, + 0x1810, 0x00000100, + 0x1814, 0x01000000, + 0x181C, 0x40000053, + 0x1850, 0x00000020, + 0x1854, 0x00000000, + 0x80000002, 0x00000000, 0x40000000, 0x00000000, + 0x1858, 0x3C0A0C14, + 0x90000004, 0x00000000, 0x40000000, 0x00000000, + 0x1858, 0x3C0A0C14, + 0x9000000a, 0x00000000, 0x40000000, 0x00000000, + 0x1858, 0x3C0A0C14, + 0x9000000b, 0x00000000, 0x40000000, 0x00000000, + 0x1858, 0x3C0A0C14, + 0xA0000000, 0x00000000, + 0x1858, 0x3C020C14, + 0xB0000000, 0x00000000, + 0x185C, 0x0D000058, + 0x1860, 0x1B800000, + 0x1860, 0x0B800001, + 0x1860, 0x05800002, + 0x1860, 0x07800003, + 0x1860, 0x1A800004, + 0x1860, 0x0B800005, + 0x1860, 0x05800006, + 0x1860, 0x0E800007, + 0x1860, 0x1A800008, + 0x1860, 0x0B800009, + 0x1860, 0x1580000A, + 0x1860, 0x0880000B, + 0x1860, 0x1A80000C, + 0x1860, 0x0B80000D, + 0x1860, 0x0580000E, + 0x1860, 0x0E80000F, + 0x1860, 0x1A800010, + 0x1860, 0x0B800011, + 0x1860, 0x15800012, + 0x1860, 0x08800013, + 0x1860, 0x1A800014, + 0x1860, 0x0B800015, + 0x1860, 0x05800016, + 0x1860, 0x07800017, + 0x1860, 0x1A800018, + 0x1860, 0x0B800019, + 0x1860, 0x1580001A, + 0x1860, 0x0880001B, + 0x1860, 0x1B80001C, + 0x1860, 0x0B80001D, + 0x1860, 0x0580001E, + 0x1860, 0x0780001F, + 0x1860, 0x1B800020, + 0x1860, 0x0B800021, + 0x1860, 0x05800022, + 0x1860, 0x07800023, + 0x1860, 0x1B800024, + 0x1860, 0x0B800025, + 0x1860, 0x05800026, + 0x1860, 0x07800027, + 0x1860, 0x1B800028, + 0x1860, 0x0B800029, + 0x1860, 0x0580002A, + 0x1860, 0x0780002B, + 0x1860, 0x1B800030, + 0x1860, 0x0B800031, + 0x1860, 0x05800032, + 0x1860, 0x00800033, + 0x1860, 0x1B800034, + 0x1860, 0x0B800035, + 0x1860, 0x05800036, + 0x1860, 0x00800037, + 0x1860, 0x1B800038, + 0x1860, 0x0B800039, + 0x1860, 0x0580003A, + 0x1860, 0x0E80803B, + 0x1894, 0x01000401, + 0x1898, 0x00188000, + 0x18A0, 0x00002929, + 0x18A4, 0x08040201, + 0x18A8, 0x80402010, + 0x18AC, 0x77777000, + 0x18B0, 0x54775477, + 0x18B4, 0x54775477, + 0x18B8, 0x00500000, + 0x18BC, 0x77700000, + 0x1A00, 0x00000007, + 0x1A04, 0x00042020, + 0x1A08, 0x80410231, + 0x1A0C, 0x00000000, + 0x1A10, 0x00000100, + 0x1A14, 0x01000000, + 0x1A1C, 0x40000053, + 0x1A50, 0x00000020, + 0x1A54, 0x00000000, + 0x80000002, 0x00000000, 0x40000000, 0x00000000, + 0x1A58, 0x3C0A0C14, + 0x90000004, 0x00000000, 0x40000000, 0x00000000, + 0x1A58, 0x3C0A0C14, + 0x9000000a, 0x00000000, 0x40000000, 0x00000000, + 0x1A58, 0x3C0A0C14, + 0x9000000b, 0x00000000, 0x40000000, 0x00000000, + 0x1A58, 0x3C0A0C14, + 0xA0000000, 0x00000000, + 0x1A58, 0x3C020C14, + 0xB0000000, 0x00000000, + 0x1A5C, 0x0D000058, + 0x1A60, 0x1B800000, + 0x1A60, 0x0B800001, + 0x1A60, 0x05800002, + 0x1A60, 0x07800003, + 0x1A60, 0x1A800004, + 0x1A60, 0x0B800005, + 0x1A60, 0x05800006, + 0x1A60, 0x0E800007, + 0x1A60, 0x1A800008, + 0x1A60, 0x0B800009, + 0x1A60, 0x1580000A, + 0x1A60, 0x0880000B, + 0x1A60, 0x1A80000C, + 0x1A60, 0x0B80000D, + 0x1A60, 0x0580000E, + 0x1A60, 0x0E80000F, + 0x1A60, 0x1A800010, + 0x1A60, 0x0B800011, + 0x1A60, 0x15800012, + 0x1A60, 0x08800013, + 0x1A60, 0x1A800014, + 0x1A60, 0x0B800015, + 0x1A60, 0x05800016, + 0x1A60, 0x07800017, + 0x1A60, 0x1A800018, + 0x1A60, 0x0B800019, + 0x1A60, 0x1580001A, + 0x1A60, 0x0880001B, + 0x1A60, 0x1B80001C, + 0x1A60, 0x0B80001D, + 0x1A60, 0x0580001E, + 0x1A60, 0x0780001F, + 0x1A60, 0x1B800020, + 0x1A60, 0x0B800021, + 0x1A60, 0x05800022, + 0x1A60, 0x07800023, + 0x1A60, 0x1B800024, + 0x1A60, 0x0B800025, + 0x1A60, 0x05800026, + 0x1A60, 0x07800027, + 0x1A60, 0x1B800028, + 0x1A60, 0x0B800029, + 0x1A60, 0x0580002A, + 0x1A60, 0x0780002B, + 0x1A60, 0x1B800030, + 0x1A60, 0x0B800031, + 0x1A60, 0x05800032, + 0x1A60, 0x00800033, + 0x1A60, 0x1B800034, + 0x1A60, 0x0B800035, + 0x1A60, 0x05800036, + 0x1A60, 0x00800037, + 0x1A60, 0x1B800038, + 0x1A60, 0x0B800039, + 0x1A60, 0x0580003A, + 0x1A60, 0x0E80803B, + 0x1A94, 0x01000401, + 0x1A98, 0x00188000, + 0x1AA0, 0x00002929, + 0x1AA4, 0x08040201, + 0x1AA8, 0x80402010, + 0x1AAC, 0x77777000, + 0x1AB0, 0x54775477, + 0x1AB4, 0x54775477, + 0x1AB8, 0x00500000, + 0x1ABC, 0x77700000, + 0x1904, 0x00030000, + 0x1914, 0x00030000, + 0x1984, 0x03000000, + 0x1988, 0x00000087, + 0x198C, 0x00000007, + 0x1990, 0xFFAA5500, + 0x1994, 0x00000077, + 0x1998, 0x12801000, + 0x1998, 0x12801000, + 0x1998, 0x12801001, + 0x1998, 0x12801002, + 0x1998, 0x12801003, + 0x1998, 0x12801004, + 0x1998, 0x12801005, + 0x1998, 0x12801006, + 0x1998, 0x12801007, + 0x1998, 0x12801008, + 0x1998, 0x12801009, + 0x1998, 0x1280100A, + 0x1998, 0x1280100B, + 0x1998, 0x1280100C, + 0x1998, 0x1280100D, + 0x1998, 0x1280100E, + 0x1998, 0x1280100F, + 0x1998, 0x12801010, + 0x1998, 0x12801011, + 0x1998, 0x12801012, + 0x1998, 0x12801013, + 0x1998, 0x12801014, + 0x1998, 0x12801015, + 0x1998, 0x12801016, + 0x1998, 0x12801017, + 0x1998, 0x12801018, + 0x1998, 0x12801019, + 0x1998, 0x1280101A, + 0x1998, 0x1280101B, + 0x1998, 0x1280101C, + 0x1998, 0x1280101D, + 0x1998, 0x1280101E, + 0x1998, 0x1280101F, + 0x1998, 0x12801020, + 0x1998, 0x12801021, + 0x1998, 0x12801022, + 0x1998, 0x12801023, + 0x1998, 0x1280102C, + 0x1998, 0x1280102D, + 0x1998, 0x1280102E, + 0x1998, 0x1280102F, + 0x1998, 0x12801030, + 0x1998, 0x12801031, + 0x1998, 0x12801032, + 0x1998, 0x12801033, + 0x1998, 0x12801034, + 0x1998, 0x12801035, + 0x1998, 0x12801036, + 0x1998, 0x12801037, + 0x1998, 0x12801038, + 0x1998, 0x12801039, + 0x1998, 0x1280103A, + 0x1998, 0x1280103B, + 0x1998, 0x1280103C, + 0x1998, 0x1280103D, + 0x1998, 0x1280103E, + 0x1998, 0x1280103F, + 0x1998, 0x12801040, + 0x1998, 0x12801041, + 0x1998, 0x12801042, + 0x1998, 0x12801043, + 0x1998, 0x12801044, + 0x1998, 0x12801045, + 0x1998, 0x12801046, + 0x1998, 0x12801047, + 0x1998, 0x12801048, + 0x1998, 0x12801049, + 0x1998, 0x12801100, + 0x1998, 0x12801101, + 0x1998, 0x12801102, + 0x1998, 0x12801103, + 0x1998, 0x12801104, + 0x1998, 0x12801105, + 0x1998, 0x12801106, + 0x1998, 0x12801107, + 0x1998, 0x12801108, + 0x1998, 0x12801109, + 0x1998, 0x1280110A, + 0x1998, 0x1280110B, + 0x1998, 0x1280110C, + 0x1998, 0x1280110D, + 0x1998, 0x1280110E, + 0x1998, 0x1280110F, + 0x1998, 0x12801110, + 0x1998, 0x12801111, + 0x1998, 0x12801112, + 0x1998, 0x12801113, + 0x1998, 0x12801114, + 0x1998, 0x12801115, + 0x1998, 0x12801116, + 0x1998, 0x12801117, + 0x1998, 0x12801118, + 0x1998, 0x12801119, + 0x1998, 0x1280111A, + 0x1998, 0x1280111B, + 0x1998, 0x1280111C, + 0x1998, 0x1280111D, + 0x1998, 0x1280111E, + 0x1998, 0x1280111F, + 0x1998, 0x12801120, + 0x1998, 0x12801121, + 0x1998, 0x12801122, + 0x1998, 0x12801123, + 0x1998, 0x1280112C, + 0x1998, 0x1280112D, + 0x1998, 0x1280112E, + 0x1998, 0x1280112F, + 0x1998, 0x12801130, + 0x1998, 0x12801131, + 0x1998, 0x12801132, + 0x1998, 0x12801133, + 0x1998, 0x12801134, + 0x1998, 0x12801135, + 0x1998, 0x12801136, + 0x1998, 0x12801137, + 0x1998, 0x12801138, + 0x1998, 0x12801139, + 0x1998, 0x1280113A, + 0x1998, 0x1280113B, + 0x1998, 0x1280113C, + 0x1998, 0x1280113D, + 0x1998, 0x1280113E, + 0x1998, 0x1280113F, + 0x1998, 0x12801140, + 0x1998, 0x12801141, + 0x1998, 0x12801142, + 0x1998, 0x12801143, + 0x1998, 0x12801144, + 0x1998, 0x12801145, + 0x1998, 0x12801146, + 0x1998, 0x12801147, + 0x1998, 0x12801148, + 0x1998, 0x12801149, + 0x1998, 0x12801200, + 0x1998, 0x12801201, + 0x1998, 0x12801202, + 0x1998, 0x12801203, + 0x1998, 0x12801204, + 0x1998, 0x12801205, + 0x1998, 0x12801206, + 0x1998, 0x12801207, + 0x1998, 0x12801208, + 0x1998, 0x12801209, + 0x1998, 0x1280120A, + 0x1998, 0x1280120B, + 0x1998, 0x1280120C, + 0x1998, 0x1280120D, + 0x1998, 0x1280120E, + 0x1998, 0x1280120F, + 0x1998, 0x12801210, + 0x1998, 0x12801211, + 0x1998, 0x12801212, + 0x1998, 0x12801213, + 0x1998, 0x12801214, + 0x1998, 0x12801215, + 0x1998, 0x12801216, + 0x1998, 0x12801217, + 0x1998, 0x12801218, + 0x1998, 0x12801219, + 0x1998, 0x1280121A, + 0x1998, 0x1280121B, + 0x1998, 0x1280121C, + 0x1998, 0x1280121D, + 0x1998, 0x1280121E, + 0x1998, 0x1280121F, + 0x1998, 0x12801220, + 0x1998, 0x12801221, + 0x1998, 0x12801222, + 0x1998, 0x12801223, + 0x1998, 0x1280122C, + 0x1998, 0x1280122D, + 0x1998, 0x1280122E, + 0x1998, 0x1280122F, + 0x1998, 0x12801230, + 0x1998, 0x12801231, + 0x1998, 0x12801232, + 0x1998, 0x12801233, + 0x1998, 0x12801234, + 0x1998, 0x12801235, + 0x1998, 0x12801236, + 0x1998, 0x12801237, + 0x1998, 0x12801238, + 0x1998, 0x12801239, + 0x1998, 0x1280123A, + 0x1998, 0x1280123B, + 0x1998, 0x1280123C, + 0x1998, 0x1280123D, + 0x1998, 0x1280123E, + 0x1998, 0x1280123F, + 0x1998, 0x12801240, + 0x1998, 0x12801241, + 0x1998, 0x12801242, + 0x1998, 0x12801243, + 0x1998, 0x12801244, + 0x1998, 0x12801245, + 0x1998, 0x12801246, + 0x1998, 0x12801247, + 0x1998, 0x12801248, + 0x1998, 0x12801249, + 0x1998, 0x12801300, + 0x1998, 0x12801301, + 0x1998, 0x12801302, + 0x1998, 0x12801303, + 0x1998, 0x12801304, + 0x1998, 0x12801305, + 0x1998, 0x12801306, + 0x1998, 0x12801307, + 0x1998, 0x12801308, + 0x1998, 0x12801309, + 0x1998, 0x1280130A, + 0x1998, 0x1280130B, + 0x1998, 0x1280130C, + 0x1998, 0x1280130D, + 0x1998, 0x1280130E, + 0x1998, 0x1280130F, + 0x1998, 0x12801310, + 0x1998, 0x12801311, + 0x1998, 0x12801312, + 0x1998, 0x12801313, + 0x1998, 0x12801314, + 0x1998, 0x12801315, + 0x1998, 0x12801316, + 0x1998, 0x12801317, + 0x1998, 0x12801318, + 0x1998, 0x12801319, + 0x1998, 0x1280131A, + 0x1998, 0x1280131B, + 0x1998, 0x1280131C, + 0x1998, 0x1280131D, + 0x1998, 0x1280131E, + 0x1998, 0x1280131F, + 0x1998, 0x12801320, + 0x1998, 0x12801321, + 0x1998, 0x12801322, + 0x1998, 0x12801323, + 0x1998, 0x1280132C, + 0x1998, 0x1280132D, + 0x1998, 0x1280132E, + 0x1998, 0x1280132F, + 0x1998, 0x12801330, + 0x1998, 0x12801331, + 0x1998, 0x12801332, + 0x1998, 0x12801333, + 0x1998, 0x12801334, + 0x1998, 0x12801335, + 0x1998, 0x12801336, + 0x1998, 0x12801337, + 0x1998, 0x12801338, + 0x1998, 0x12801339, + 0x1998, 0x1280133A, + 0x1998, 0x1280133B, + 0x1998, 0x1280133C, + 0x1998, 0x1280133D, + 0x1998, 0x1280133E, + 0x1998, 0x1280133F, + 0x1998, 0x12801340, + 0x1998, 0x12801341, + 0x1998, 0x12801342, + 0x1998, 0x12801343, + 0x1998, 0x12801344, + 0x1998, 0x12801345, + 0x1998, 0x12801346, + 0x1998, 0x12801347, + 0x1998, 0x12801348, + 0x1998, 0x12801349, + 0x19D4, 0x88888888, + 0x19D8, 0x00000888, + 0xB00, 0xE3100100, + 0xB00, 0xE7100100, + 0xC60, 0x15808002, + 0xC60, 0x01808003, + 0xE60, 0x15808002, + 0xE60, 0x01808003, + 0x1860, 0x15808002, + 0x1860, 0x01808003, + 0x1A60, 0x15808002, + 0x1A60, 0x01808003, + 0xB00, 0xE3100100, + 0xC5C, 0x0D080058, + 0xE5C, 0x0D080058, + 0x185C, 0x0D080058, + 0x1A5C, 0x0D080058, + 0xC5C, 0x0D000058, + 0xE5C, 0x0D000058, + 0x185C, 0x0D000058, + 0x1A5C, 0x0D000058, + 0xC60, 0x05808002, + 0xC60, 0x0E808003, + 0xE60, 0x05808002, + 0xE60, 0x0E808003, + 0x1860, 0x05808002, + 0x1860, 0x0E808003, + 0x1A60, 0x05808002, + 0x1A60, 0x0E808003, + 0xB00, 0xE7100100, + 0xB00, 0xE3100100, + 0xB00, 0xE3100000, + 0x1C38, 0x00000002, + 0xA00, 0x00D047C8, + 0xA04, 0x46FF800C, + 0xA08, 0x8C838300, + 0xA0C, 0x2E7E000F, + 0xA10, 0x9500BB78, + 0xA14, 0x11144028, + 0xA18, 0x00881117, + 0xA1C, 0x89140F00, + 0xA20, 0x1A1B0030, + 0xA24, 0x090E1317, + 0xA28, 0x00000204, + 0xA2C, 0x00900000, + 0xA70, 0x101FFF00, + 0xA74, 0x00000128, + 0xA78, 0x00000900, + 0xA7C, 0x225B0606, + 0xA80, 0x218075B2, + 0xA84, 0x9C1F8C00, + 0x1B04, 0xE24628D2, + 0x1B10, 0x88010D46, + 0x1B14, 0x00000000, + 0x1B18, 0x00292903, + 0x1B00, 0xF8000000, + 0x1B00, 0xF800D000, + 0x1B00, 0xF801F000, + 0x1B1C, 0xA2123DB2, + 0x1B20, 0x07040001, + 0x1B24, 0x07060807, + 0x80000001, 0x00000000, 0x40000000, 0x00000000, + 0x1B28, 0xC0060324, + 0x90000002, 0x00000000, 0x40000000, 0x00000000, + 0x1B28, 0xC0060324, + 0x90000004, 0x00000000, 0x40000000, 0x00000000, + 0x1B28, 0xC0060324, + 0x90000003, 0x00000000, 0x40000000, 0x00000000, + 0x1B28, 0xC0060324, + 0x90000005, 0x00000000, 0x40000000, 0x00000000, + 0x1B28, 0xC0060324, + 0x90000006, 0x00000000, 0x40000000, 0x00000000, + 0x1B28, 0xC0060324, + 0x9000000a, 0x00000000, 0x40000000, 0x00000000, + 0x1B28, 0xC0060324, + 0x9000000b, 0x00000000, 0x40000000, 0x00000000, + 0x1B28, 0xC0060324, + 0xA0000000, 0x00000000, + 0x1B28, 0xC0060348, + 0xB0000000, 0x00000000, + 0x1B2C, 0x20000003, + 0x1B30, 0x20000000, + 0x1B38, 0x20000000, + 0x1B3C, 0x20000000, + 0x1BD4, 0x00000001, + 0x1B94, 0x80000000, + 0x1B34, 0x00000000, + 0x1B34, 0x00000002, + 0x1B34, 0x00000000, + 0x1B00, 0xF8000002, + 0x1B00, 0xF800D002, + 0x1B00, 0xF801F002, + 0x1B1C, 0xA2123DB2, + 0x1B20, 0x07040001, + 0x1B24, 0x07060807, + 0x80000001, 0x00000000, 0x40000000, 0x00000000, + 0x1B28, 0xC0060324, + 0x90000002, 0x00000000, 0x40000000, 0x00000000, + 0x1B28, 0xC0060324, + 0x90000004, 0x00000000, 0x40000000, 0x00000000, + 0x1B28, 0xC0060324, + 0x90000003, 0x00000000, 0x40000000, 0x00000000, + 0x1B28, 0xC0060324, + 0x90000005, 0x00000000, 0x40000000, 0x00000000, + 0x1B28, 0xC0060324, + 0x90000006, 0x00000000, 0x40000000, 0x00000000, + 0x1B28, 0xC0060324, + 0x9000000a, 0x00000000, 0x40000000, 0x00000000, + 0x1B28, 0xC0060324, + 0x9000000b, 0x00000000, 0x40000000, 0x00000000, + 0x1B28, 0xC0060324, + 0xA0000000, 0x00000000, + 0x1B28, 0xC0060348, + 0xB0000000, 0x00000000, + 0x1B2C, 0x20000003, + 0x1B30, 0x20000000, + 0x1B38, 0x20000000, + 0x1B3C, 0x20000000, + 0x1BD4, 0x00000001, + 0x1B94, 0x80000000, + 0x1B34, 0x00000000, + 0x1B34, 0x00000002, + 0x1B34, 0x00000000, + 0x1B00, 0xF8000004, + 0x1B00, 0xF800D004, + 0x1B00, 0xF801F004, + 0x1B1C, 0xA2123DB2, + 0x1B20, 0x07040001, + 0x1B24, 0x07060807, + 0x80000001, 0x00000000, 0x40000000, 0x00000000, + 0x1B28, 0xC0060324, + 0x90000002, 0x00000000, 0x40000000, 0x00000000, + 0x1B28, 0xC0060324, + 0x90000004, 0x00000000, 0x40000000, 0x00000000, + 0x1B28, 0xC0060324, + 0x90000003, 0x00000000, 0x40000000, 0x00000000, + 0x1B28, 0xC0060324, + 0x90000005, 0x00000000, 0x40000000, 0x00000000, + 0x1B28, 0xC0060324, + 0x90000006, 0x00000000, 0x40000000, 0x00000000, + 0x1B28, 0xC0060324, + 0x9000000a, 0x00000000, 0x40000000, 0x00000000, + 0x1B28, 0xC0060324, + 0x9000000b, 0x00000000, 0x40000000, 0x00000000, + 0x1B28, 0xC0060324, + 0xA0000000, 0x00000000, + 0x1B28, 0xC0060348, + 0xB0000000, 0x00000000, + 0x1B2C, 0x20000003, + 0x1B30, 0x20000000, + 0x1B38, 0x20000000, + 0x1B3C, 0x20000000, + 0x1BD4, 0x00000001, + 0x1B94, 0x80000000, + 0x1B34, 0x00000000, + 0x1B34, 0x00000002, + 0x1B34, 0x00000000, + 0x1B00, 0xF8000006, + 0x1B00, 0xF800D006, + 0x1B00, 0xF801F006, + 0x1B1C, 0xA2123DB2, + 0x1B20, 0x07040001, + 0x1B24, 0x07060807, + 0x80000001, 0x00000000, 0x40000000, 0x00000000, + 0x1B28, 0xC0060324, + 0x90000002, 0x00000000, 0x40000000, 0x00000000, + 0x1B28, 0xC0060324, + 0x90000004, 0x00000000, 0x40000000, 0x00000000, + 0x1B28, 0xC0060324, + 0x90000003, 0x00000000, 0x40000000, 0x00000000, + 0x1B28, 0xC0060324, + 0x90000005, 0x00000000, 0x40000000, 0x00000000, + 0x1B28, 0xC0060324, + 0x90000006, 0x00000000, 0x40000000, 0x00000000, + 0x1B28, 0xC0060324, + 0x9000000a, 0x00000000, 0x40000000, 0x00000000, + 0x1B28, 0xC0060324, + 0x9000000b, 0x00000000, 0x40000000, 0x00000000, + 0x1B28, 0xC0060324, + 0xA0000000, 0x00000000, + 0x1B28, 0xC0060348, + 0xB0000000, 0x00000000, + 0x1B2C, 0x20000003, + 0x1B30, 0x20000000, + 0x1B38, 0x20000000, + 0x1B3C, 0x20000000, + 0x1BD4, 0x00000001, + 0x1B94, 0x80000000, + 0x1B34, 0x00000000, + 0x1B34, 0x00000002, + 0x1B34, 0x00000000, + 0x1B00, 0xF8000000, + 0x1B80, 0x00000007, + 0x1B80, 0x09060005, + 0x1B80, 0x09060007, + 0x1B80, 0x0FFE0015, + 0x1B80, 0x0FFE0017, + 0x1B80, 0x00240025, + 0x1B80, 0x00240027, + 0x1B80, 0x00040035, + 0x1B80, 0x00040037, + 0x1B80, 0x05C00045, + 0x1B80, 0x05C00047, + 0x1B80, 0x00070055, + 0x1B80, 0x00070057, + 0x1B80, 0x64000065, + 0x1B80, 0x64000067, + 0x1B80, 0x00020075, + 0x1B80, 0x00020077, + 0x1B80, 0x00080085, + 0x1B80, 0x00080087, + 0x1B80, 0x80000095, + 0x1B80, 0x80000097, + 0x1B80, 0x090100A5, + 0x1B80, 0x090100A7, + 0x1B80, 0x0F0200B5, + 0x1B80, 0x0F0200B7, + 0x1B80, 0x002400C5, + 0x1B80, 0x002400C7, + 0x1B80, 0x000400D5, + 0x1B80, 0x000400D7, + 0x1B80, 0x05C000E5, + 0x1B80, 0x05C000E7, + 0x1B80, 0x000700F5, + 0x1B80, 0x000700F7, + 0x1B80, 0x64020105, + 0x1B80, 0x64020107, + 0x1B80, 0x00020115, + 0x1B80, 0x00020117, + 0x1B80, 0x00040125, + 0x1B80, 0x00040127, + 0x1B80, 0x4A000135, + 0x1B80, 0x4A000137, + 0x1B80, 0x4B040145, + 0x1B80, 0x4B040147, + 0x1B80, 0x85030155, + 0x1B80, 0x85030157, + 0x1B80, 0x40010165, + 0x1B80, 0x40010167, + 0x1B80, 0xE0290175, + 0x1B80, 0xE0290177, + 0x1B80, 0x00040185, + 0x1B80, 0x00040187, + 0x1B80, 0x4B050195, + 0x1B80, 0x4B050197, + 0x1B80, 0x860301A5, + 0x1B80, 0x860301A7, + 0x1B80, 0x400301B5, + 0x1B80, 0x400301B7, + 0x1B80, 0xE02901C5, + 0x1B80, 0xE02901C7, + 0x1B80, 0x000401D5, + 0x1B80, 0x000401D7, + 0x1B80, 0x4B0601E5, + 0x1B80, 0x4B0601E7, + 0x1B80, 0x870301F5, + 0x1B80, 0x870301F7, + 0x1B80, 0x40050205, + 0x1B80, 0x40050207, + 0x1B80, 0xE0290215, + 0x1B80, 0xE0290217, + 0x1B80, 0x00040225, + 0x1B80, 0x00040227, + 0x1B80, 0x4B070235, + 0x1B80, 0x4B070237, + 0x1B80, 0x88030245, + 0x1B80, 0x88030247, + 0x1B80, 0x40070255, + 0x1B80, 0x40070257, + 0x1B80, 0xE0290265, + 0x1B80, 0xE0290267, + 0x1B80, 0x4B000275, + 0x1B80, 0x4B000277, + 0x1B80, 0x30000285, + 0x1B80, 0x30000287, + 0x1B80, 0xFE100295, + 0x1B80, 0xFE100297, + 0x1B80, 0xFF1002A5, + 0x1B80, 0xFF1002A7, + 0x1B80, 0xE18602B5, + 0x1B80, 0xE18602B7, + 0x1B80, 0xF00A02C5, + 0x1B80, 0xF00A02C7, + 0x1B80, 0xF10A02D5, + 0x1B80, 0xF10A02D7, + 0x1B80, 0xF20A02E5, + 0x1B80, 0xF20A02E7, + 0x1B80, 0xF30802F5, + 0x1B80, 0xF30802F7, + 0x1B80, 0xF4070305, + 0x1B80, 0xF4070307, + 0x1B80, 0xF5060315, + 0x1B80, 0xF5060317, + 0x1B80, 0xF7060325, + 0x1B80, 0xF7060327, + 0x1B80, 0xF8050335, + 0x1B80, 0xF8050337, + 0x1B80, 0xF9040345, + 0x1B80, 0xF9040347, + 0x1B80, 0x00010355, + 0x1B80, 0x00010357, + 0x1B80, 0x303B0365, + 0x1B80, 0x303B0367, + 0x1B80, 0x30500375, + 0x1B80, 0x30500377, + 0x1B80, 0x305C0385, + 0x1B80, 0x305C0387, + 0x1B80, 0x31D50395, + 0x1B80, 0x31D50397, + 0x1B80, 0x31C503A5, + 0x1B80, 0x31C503A7, + 0x1B80, 0x4D0403B5, + 0x1B80, 0x4D0403B7, + 0x1B80, 0x2EF003C5, + 0x1B80, 0x2EF003C7, + 0x1B80, 0x000203D5, + 0x1B80, 0x000203D7, + 0x1B80, 0x208003E5, + 0x1B80, 0x208003E7, + 0x1B80, 0x000003F5, + 0x1B80, 0x000003F7, + 0x1B80, 0x4D000405, + 0x1B80, 0x4D000407, + 0x1B80, 0x55070415, + 0x1B80, 0x55070417, + 0x1B80, 0xE1230425, + 0x1B80, 0xE1230427, + 0x1B80, 0xE1230435, + 0x1B80, 0xE1230437, + 0x1B80, 0x4D040445, + 0x1B80, 0x4D040447, + 0x1B80, 0x20800455, + 0x1B80, 0x20800457, + 0x1B80, 0x84000465, + 0x1B80, 0x84000467, + 0x1B80, 0x4D000475, + 0x1B80, 0x4D000477, + 0x1B80, 0x550F0485, + 0x1B80, 0x550F0487, + 0x1B80, 0xE1230495, + 0x1B80, 0xE1230497, + 0x1B80, 0x4F0204A5, + 0x1B80, 0x4F0204A7, + 0x1B80, 0x4E0004B5, + 0x1B80, 0x4E0004B7, + 0x1B80, 0x530204C5, + 0x1B80, 0x530204C7, + 0x1B80, 0x520104D5, + 0x1B80, 0x520104D7, + 0x1B80, 0xE12704E5, + 0x1B80, 0xE12704E7, + 0x1B80, 0x000104F5, + 0x1B80, 0x000104F7, + 0x1B80, 0x5C720505, + 0x1B80, 0x5C720507, + 0x1B80, 0xE1320515, + 0x1B80, 0xE1320517, + 0x1B80, 0x54E50525, + 0x1B80, 0x54E50527, + 0x1B80, 0x54BF0535, + 0x1B80, 0x54BF0537, + 0x1B80, 0x54C50545, + 0x1B80, 0x54C50547, + 0x1B80, 0x54BE0555, + 0x1B80, 0x54BE0557, + 0x1B80, 0x54DF0565, + 0x1B80, 0x54DF0567, + 0x1B80, 0x0BA60575, + 0x1B80, 0x0BA60577, + 0x1B80, 0xF3130585, + 0x1B80, 0xF3130587, + 0x1B80, 0xF41E0595, + 0x1B80, 0xF41E0597, + 0x1B80, 0xF53C05A5, + 0x1B80, 0xF53C05A7, + 0x1B80, 0x000105B5, + 0x1B80, 0x000105B7, + 0x1B80, 0x620605C5, + 0x1B80, 0x620605C7, + 0x1B80, 0x600605D5, + 0x1B80, 0x600605D7, + 0x1B80, 0xE1A905E5, + 0x1B80, 0xE1A905E7, + 0x1B80, 0x0C0005F5, + 0x1B80, 0x0C0005F7, + 0x1B80, 0x5C720605, + 0x1B80, 0x5C720607, + 0x1B80, 0xE1320615, + 0x1B80, 0xE1320617, + 0x1B80, 0x5CF10625, + 0x1B80, 0x5CF10627, + 0x1B80, 0x0C010635, + 0x1B80, 0x0C010637, + 0x1B80, 0xF2020645, + 0x1B80, 0xF2020647, + 0x1B80, 0x30D60655, + 0x1B80, 0x30D60657, + 0x1B80, 0x0AC60665, + 0x1B80, 0x0AC60667, + 0x1B80, 0xE1B60675, + 0x1B80, 0xE1B60677, + 0x1B80, 0xE1580685, + 0x1B80, 0xE1580687, + 0x1B80, 0x54E50695, + 0x1B80, 0x54E50697, + 0x1B80, 0x000106A5, + 0x1B80, 0x000106A7, + 0x1B80, 0x560106B5, + 0x1B80, 0x560106B7, + 0x1B80, 0x5CE206C5, + 0x1B80, 0x5CE206C7, + 0x1B80, 0x0AE106D5, + 0x1B80, 0x0AE106D7, + 0x1B80, 0x630C06E5, + 0x1B80, 0x630C06E7, + 0x1B80, 0xE13F06F5, + 0x1B80, 0xE13F06F7, + 0x1B80, 0x00270705, + 0x1B80, 0x00270707, + 0x1B80, 0xE16C0715, + 0x1B80, 0xE16C0717, + 0x1B80, 0x00020725, + 0x1B80, 0x00020727, + 0x1B80, 0x002A0735, + 0x1B80, 0x002A0737, + 0x1B80, 0x07140745, + 0x1B80, 0x07140747, + 0x1B80, 0x00020755, + 0x1B80, 0x00020757, + 0x1B80, 0x30C30765, + 0x1B80, 0x30C30767, + 0x1B80, 0x56010775, + 0x1B80, 0x56010777, + 0x1B80, 0x5CE20785, + 0x1B80, 0x5CE20787, + 0x1B80, 0x0AE10795, + 0x1B80, 0x0AE10797, + 0x1B80, 0x631707A5, + 0x1B80, 0x631707A7, + 0x1B80, 0xE13F07B5, + 0x1B80, 0xE13F07B7, + 0x1B80, 0x002507C5, + 0x1B80, 0x002507C7, + 0x1B80, 0xE16C07D5, + 0x1B80, 0xE16C07D7, + 0x1B80, 0x000207E5, + 0x1B80, 0x000207E7, + 0x1B80, 0x630F07F5, + 0x1B80, 0x630F07F7, + 0x1B80, 0xE13F0805, + 0x1B80, 0xE13F0807, + 0x1B80, 0x63070815, + 0x1B80, 0x63070817, + 0x1B80, 0xE13F0825, + 0x1B80, 0xE13F0827, + 0x1B80, 0x07140835, + 0x1B80, 0x07140837, + 0x1B80, 0x56000845, + 0x1B80, 0x56000847, + 0x1B80, 0x5CF20855, + 0x1B80, 0x5CF20857, + 0x1B80, 0x0AF10865, + 0x1B80, 0x0AF10867, + 0x1B80, 0x07140875, + 0x1B80, 0x07140877, + 0x1B80, 0x07140885, + 0x1B80, 0x07140887, + 0x1B80, 0x630F0895, + 0x1B80, 0x630F0897, + 0x1B80, 0xE13F08A5, + 0x1B80, 0xE13F08A7, + 0x1B80, 0x631708B5, + 0x1B80, 0x631708B7, + 0x1B80, 0xE13F08C5, + 0x1B80, 0xE13F08C7, + 0x1B80, 0x002508D5, + 0x1B80, 0x002508D7, + 0x1B80, 0xE16C08E5, + 0x1B80, 0xE16C08E7, + 0x1B80, 0x000208F5, + 0x1B80, 0x000208F7, + 0x1B80, 0x30C30905, + 0x1B80, 0x30C30907, + 0x1B80, 0xE1A90915, + 0x1B80, 0xE1A90917, + 0x1B80, 0x62060925, + 0x1B80, 0x62060927, + 0x1B80, 0x60060935, + 0x1B80, 0x60060937, + 0x1B80, 0xE1160945, + 0x1B80, 0xE1160947, + 0x1B80, 0x54BE0955, + 0x1B80, 0x54BE0957, + 0x1B80, 0x56010965, + 0x1B80, 0x56010967, + 0x1B80, 0x5CE20975, + 0x1B80, 0x5CE20977, + 0x1B80, 0x0AE10985, + 0x1B80, 0x0AE10987, + 0x1B80, 0x633A0995, + 0x1B80, 0x633A0997, + 0x1B80, 0xE13F09A5, + 0x1B80, 0xE13F09A7, + 0x1B80, 0x633709B5, + 0x1B80, 0x633709B7, + 0x1B80, 0xE13F09C5, + 0x1B80, 0xE13F09C7, + 0x1B80, 0x632F09D5, + 0x1B80, 0x632F09D7, + 0x1B80, 0xE13F09E5, + 0x1B80, 0xE13F09E7, + 0x1B80, 0x632709F5, + 0x1B80, 0x632709F7, + 0x1B80, 0xE13F0A05, + 0x1B80, 0xE13F0A07, + 0x1B80, 0x631F0A15, + 0x1B80, 0x631F0A17, + 0x1B80, 0xE13F0A25, + 0x1B80, 0xE13F0A27, + 0x1B80, 0x63170A35, + 0x1B80, 0x63170A37, + 0x1B80, 0xE13F0A45, + 0x1B80, 0xE13F0A47, + 0x1B80, 0x630F0A55, + 0x1B80, 0x630F0A57, + 0x1B80, 0xE13F0A65, + 0x1B80, 0xE13F0A67, + 0x1B80, 0x63070A75, + 0x1B80, 0x63070A77, + 0x1B80, 0xE13F0A85, + 0x1B80, 0xE13F0A87, + 0x1B80, 0xE16C0A95, + 0x1B80, 0xE16C0A97, + 0x1B80, 0x56000AA5, + 0x1B80, 0x56000AA7, + 0x1B80, 0x5CF20AB5, + 0x1B80, 0x5CF20AB7, + 0x1B80, 0x0AF10AC5, + 0x1B80, 0x0AF10AC7, + 0x1B80, 0xF5040AD5, + 0x1B80, 0xF5040AD7, + 0x1B80, 0xE13F0AE5, + 0x1B80, 0xE13F0AE7, + 0x1B80, 0xE16C0AF5, + 0x1B80, 0xE16C0AF7, + 0x1B80, 0x30B30B05, + 0x1B80, 0x30B30B07, + 0x1B80, 0x07140B15, + 0x1B80, 0x07140B17, + 0x1B80, 0x07140B25, + 0x1B80, 0x07140B27, + 0x1B80, 0x630F0B35, + 0x1B80, 0x630F0B37, + 0x1B80, 0xE13F0B45, + 0x1B80, 0xE13F0B47, + 0x1B80, 0x63170B55, + 0x1B80, 0x63170B57, + 0x1B80, 0xE13F0B65, + 0x1B80, 0xE13F0B67, + 0x1B80, 0x631F0B75, + 0x1B80, 0x631F0B77, + 0x1B80, 0xE13F0B85, + 0x1B80, 0xE13F0B87, + 0x1B80, 0x63270B95, + 0x1B80, 0x63270B97, + 0x1B80, 0xE13F0BA5, + 0x1B80, 0xE13F0BA7, + 0x1B80, 0x632F0BB5, + 0x1B80, 0x632F0BB7, + 0x1B80, 0xE13F0BC5, + 0x1B80, 0xE13F0BC7, + 0x1B80, 0x63370BD5, + 0x1B80, 0x63370BD7, + 0x1B80, 0xE13F0BE5, + 0x1B80, 0xE13F0BE7, + 0x1B80, 0x633A0BF5, + 0x1B80, 0x633A0BF7, + 0x1B80, 0xE13F0C05, + 0x1B80, 0xE13F0C07, + 0x1B80, 0xF60B0C15, + 0x1B80, 0xF60B0C17, + 0x1B80, 0xF7170C25, + 0x1B80, 0xF7170C27, + 0x1B80, 0x4D300C35, + 0x1B80, 0x4D300C37, + 0x1B80, 0x57040C45, + 0x1B80, 0x57040C47, + 0x1B80, 0x57000C55, + 0x1B80, 0x57000C57, + 0x1B80, 0x96000C65, + 0x1B80, 0x96000C67, + 0x1B80, 0x57080C75, + 0x1B80, 0x57080C77, + 0x1B80, 0x57000C85, + 0x1B80, 0x57000C87, + 0x1B80, 0x95000C95, + 0x1B80, 0x95000C97, + 0x1B80, 0x4D000CA5, + 0x1B80, 0x4D000CA7, + 0x1B80, 0x6C070CB5, + 0x1B80, 0x6C070CB7, + 0x1B80, 0x00010CC5, + 0x1B80, 0x00010CC7, + 0x1B80, 0x00220CD5, + 0x1B80, 0x00220CD7, + 0x1B80, 0x06140CE5, + 0x1B80, 0x06140CE7, + 0x1B80, 0xE16C0CF5, + 0x1B80, 0xE16C0CF7, + 0x1B80, 0x00020D05, + 0x1B80, 0x00020D07, + 0x1B80, 0x00250D15, + 0x1B80, 0x00250D17, + 0x1B80, 0x06140D25, + 0x1B80, 0x06140D27, + 0x1B80, 0xE16C0D35, + 0x1B80, 0xE16C0D37, + 0x1B80, 0x00020D45, + 0x1B80, 0x00020D47, + 0x1B80, 0x00010D55, + 0x1B80, 0x00010D57, + 0x1B80, 0x00320D65, + 0x1B80, 0x00320D67, + 0x1B80, 0xE16C0D75, + 0x1B80, 0xE16C0D77, + 0x1B80, 0x00020D85, + 0x1B80, 0x00020D87, + 0x1B80, 0xE1860D95, + 0x1B80, 0xE1860D97, + 0x1B80, 0xE1B60DA5, + 0x1B80, 0xE1B60DA7, + 0x1B80, 0x5CD10DB5, + 0x1B80, 0x5CD10DB7, + 0x1B80, 0x673A0DC5, + 0x1B80, 0x673A0DC7, + 0x1B80, 0xE1230DD5, + 0x1B80, 0xE1230DD7, + 0x1B80, 0xF80B0DE5, + 0x1B80, 0xF80B0DE7, + 0x1B80, 0xF9110DF5, + 0x1B80, 0xF9110DF7, + 0x1B80, 0xE1580E05, + 0x1B80, 0xE1580E07, + 0x1B80, 0x67370E15, + 0x1B80, 0x67370E17, + 0x1B80, 0xE1580E25, + 0x1B80, 0xE1580E27, + 0x1B80, 0x672F0E35, + 0x1B80, 0x672F0E37, + 0x1B80, 0xE1580E45, + 0x1B80, 0xE1580E47, + 0x1B80, 0x67270E55, + 0x1B80, 0x67270E57, + 0x1B80, 0xE1580E65, + 0x1B80, 0xE1580E67, + 0x1B80, 0x671F0E75, + 0x1B80, 0x671F0E77, + 0x1B80, 0xE1580E85, + 0x1B80, 0xE1580E87, + 0x1B80, 0x67170E95, + 0x1B80, 0x67170E97, + 0x1B80, 0xE1580EA5, + 0x1B80, 0xE1580EA7, + 0x1B80, 0xF8020EB5, + 0x1B80, 0xF8020EB7, + 0x1B80, 0x30EE0EC5, + 0x1B80, 0x30EE0EC7, + 0x1B80, 0xE0D10ED5, + 0x1B80, 0xE0D10ED7, + 0x1B80, 0x670F0EE5, + 0x1B80, 0x670F0EE7, + 0x1B80, 0xE1580EF5, + 0x1B80, 0xE1580EF7, + 0x1B80, 0x67070F05, + 0x1B80, 0x67070F07, + 0x1B80, 0xE1580F15, + 0x1B80, 0xE1580F17, + 0x1B80, 0xF9020F25, + 0x1B80, 0xF9020F27, + 0x1B80, 0x30F50F35, + 0x1B80, 0x30F50F37, + 0x1B80, 0xE0CD0F45, + 0x1B80, 0xE0CD0F47, + 0x1B80, 0x06140F55, + 0x1B80, 0x06140F57, + 0x1B80, 0xE16C0F65, + 0x1B80, 0xE16C0F67, + 0x1B80, 0x5CF10F75, + 0x1B80, 0x5CF10F77, + 0x1B80, 0xE1580F85, + 0x1B80, 0xE1580F87, + 0x1B80, 0x06140F95, + 0x1B80, 0x06140F97, + 0x1B80, 0xE16C0FA5, + 0x1B80, 0xE16C0FA7, + 0x1B80, 0xF9020FB5, + 0x1B80, 0xF9020FB7, + 0x1B80, 0x30FF0FC5, + 0x1B80, 0x30FF0FC7, + 0x1B80, 0xE0CD0FD5, + 0x1B80, 0xE0CD0FD7, + 0x1B80, 0x31130FE5, + 0x1B80, 0x31130FE7, + 0x1B80, 0x670F0FF5, + 0x1B80, 0x670F0FF7, + 0x1B80, 0xE1581005, + 0x1B80, 0xE1581007, + 0x1B80, 0x67171015, + 0x1B80, 0x67171017, + 0x1B80, 0xE1581025, + 0x1B80, 0xE1581027, + 0x1B80, 0xF8021035, + 0x1B80, 0xF8021037, + 0x1B80, 0x31071045, + 0x1B80, 0x31071047, + 0x1B80, 0xE0D11055, + 0x1B80, 0xE0D11057, + 0x1B80, 0x31131065, + 0x1B80, 0x31131067, + 0x1B80, 0x670F1075, + 0x1B80, 0x670F1077, + 0x1B80, 0xE1581085, + 0x1B80, 0xE1581087, + 0x1B80, 0x671F1095, + 0x1B80, 0x671F1097, + 0x1B80, 0xE15810A5, + 0x1B80, 0xE15810A7, + 0x1B80, 0x672710B5, + 0x1B80, 0x672710B7, + 0x1B80, 0xE15810C5, + 0x1B80, 0xE15810C7, + 0x1B80, 0x672F10D5, + 0x1B80, 0x672F10D7, + 0x1B80, 0xE15810E5, + 0x1B80, 0xE15810E7, + 0x1B80, 0x673710F5, + 0x1B80, 0x673710F7, + 0x1B80, 0xE1581105, + 0x1B80, 0xE1581107, + 0x1B80, 0x673A1115, + 0x1B80, 0x673A1117, + 0x1B80, 0xE1581125, + 0x1B80, 0xE1581127, + 0x1B80, 0x4D101135, + 0x1B80, 0x4D101137, + 0x1B80, 0x30C41145, + 0x1B80, 0x30C41147, + 0x1B80, 0x00011155, + 0x1B80, 0x00011157, + 0x1B80, 0x6F241165, + 0x1B80, 0x6F241167, + 0x1B80, 0x6E401175, + 0x1B80, 0x6E401177, + 0x1B80, 0x6D001185, + 0x1B80, 0x6D001187, + 0x1B80, 0x55031195, + 0x1B80, 0x55031197, + 0x1B80, 0x312311A5, + 0x1B80, 0x312311A7, + 0x1B80, 0x6F1C11B5, + 0x1B80, 0x6F1C11B7, + 0x1B80, 0x6E4011C5, + 0x1B80, 0x6E4011C7, + 0x1B80, 0x550B11D5, + 0x1B80, 0x550B11D7, + 0x1B80, 0x312311E5, + 0x1B80, 0x312311E7, + 0x1B80, 0x061C11F5, + 0x1B80, 0x061C11F7, + 0x1B80, 0x54DE1205, + 0x1B80, 0x54DE1207, + 0x1B80, 0x06DC1215, + 0x1B80, 0x06DC1217, + 0x1B80, 0x55131225, + 0x1B80, 0x55131227, + 0x1B80, 0x74011235, + 0x1B80, 0x74011237, + 0x1B80, 0x74001245, + 0x1B80, 0x74001247, + 0x1B80, 0x8E001255, + 0x1B80, 0x8E001257, + 0x1B80, 0x00011265, + 0x1B80, 0x00011267, + 0x1B80, 0x57021275, + 0x1B80, 0x57021277, + 0x1B80, 0x57001285, + 0x1B80, 0x57001287, + 0x1B80, 0x97001295, + 0x1B80, 0x97001297, + 0x1B80, 0x000112A5, + 0x1B80, 0x000112A7, + 0x1B80, 0x54BF12B5, + 0x1B80, 0x54BF12B7, + 0x1B80, 0x54C112C5, + 0x1B80, 0x54C112C7, + 0x1B80, 0x54A212D5, + 0x1B80, 0x54A212D7, + 0x1B80, 0x54C012E5, + 0x1B80, 0x54C012E7, + 0x1B80, 0x54A112F5, + 0x1B80, 0x54A112F7, + 0x1B80, 0x54DF1305, + 0x1B80, 0x54DF1307, + 0x1B80, 0x00011315, + 0x1B80, 0x00011317, + 0x1B80, 0x55001325, + 0x1B80, 0x55001327, + 0x1B80, 0xE1231335, + 0x1B80, 0xE1231337, + 0x1B80, 0x54811345, + 0x1B80, 0x54811347, + 0x1B80, 0xE1231355, + 0x1B80, 0xE1231357, + 0x1B80, 0x54801365, + 0x1B80, 0x54801367, + 0x1B80, 0x002A1375, + 0x1B80, 0x002A1377, + 0x1B80, 0xE12B1385, + 0x1B80, 0xE12B1387, + 0x1B80, 0xE1231395, + 0x1B80, 0xE1231397, + 0x1B80, 0x548013A5, + 0x1B80, 0x548013A7, + 0x1B80, 0xE17213B5, + 0x1B80, 0xE17213B7, + 0x1B80, 0xBF3013C5, + 0x1B80, 0xBF3013C7, + 0x1B80, 0x000213D5, + 0x1B80, 0x000213D7, + 0x1B80, 0x302813E5, + 0x1B80, 0x302813E7, + 0x1B80, 0x4F7813F5, + 0x1B80, 0x4F7813F7, + 0x1B80, 0x4E001405, + 0x1B80, 0x4E001407, + 0x1B80, 0x53871415, + 0x1B80, 0x53871417, + 0x1B80, 0x52F11425, + 0x1B80, 0x52F11427, + 0x1B80, 0xE1161435, + 0x1B80, 0xE1161437, + 0x1B80, 0xE11B1445, + 0x1B80, 0xE11B1447, + 0x1B80, 0xE11F1455, + 0x1B80, 0xE11F1457, + 0x1B80, 0xE1271465, + 0x1B80, 0xE1271467, + 0x1B80, 0x54811475, + 0x1B80, 0x54811477, + 0x1B80, 0xE1161485, + 0x1B80, 0xE1161487, + 0x1B80, 0xE11B1495, + 0x1B80, 0xE11B1497, + 0x1B80, 0xE11F14A5, + 0x1B80, 0xE11F14A7, + 0x1B80, 0xE12714B5, + 0x1B80, 0xE12714B7, + 0x1B80, 0x548014C5, + 0x1B80, 0x548014C7, + 0x1B80, 0x002A14D5, + 0x1B80, 0x002A14D7, + 0x1B80, 0xE12B14E5, + 0x1B80, 0xE12B14E7, + 0x1B80, 0xE11614F5, + 0x1B80, 0xE11614F7, + 0x1B80, 0xE11B1505, + 0x1B80, 0xE11B1507, + 0x1B80, 0xE11F1515, + 0x1B80, 0xE11F1517, + 0x1B80, 0xE1271525, + 0x1B80, 0xE1271527, + 0x1B80, 0x54801535, + 0x1B80, 0x54801537, + 0x1B80, 0xE1721545, + 0x1B80, 0xE1721547, + 0x1B80, 0xBF171555, + 0x1B80, 0xBF171557, + 0x1B80, 0x00021565, + 0x1B80, 0x00021567, + 0x1B80, 0x30281575, + 0x1B80, 0x30281577, + 0x1B80, 0x06141585, + 0x1B80, 0x06141587, + 0x1B80, 0x73201595, + 0x1B80, 0x73201597, + 0x1B80, 0x720015A5, + 0x1B80, 0x720015A7, + 0x1B80, 0x710015B5, + 0x1B80, 0x710015B7, + 0x1B80, 0x550115C5, + 0x1B80, 0x550115C7, + 0x1B80, 0xE12315D5, + 0x1B80, 0xE12315D7, + 0x1B80, 0xE12715E5, + 0x1B80, 0xE12715E7, + 0x1B80, 0x548115F5, + 0x1B80, 0x548115F7, + 0x1B80, 0xE1231605, + 0x1B80, 0xE1231607, + 0x1B80, 0xE1271615, + 0x1B80, 0xE1271617, + 0x1B80, 0x54801625, + 0x1B80, 0x54801627, + 0x1B80, 0x002A1635, + 0x1B80, 0x002A1637, + 0x1B80, 0xE12B1645, + 0x1B80, 0xE12B1647, + 0x1B80, 0xE1231655, + 0x1B80, 0xE1231657, + 0x1B80, 0xE1271665, + 0x1B80, 0xE1271667, + 0x1B80, 0x54801675, + 0x1B80, 0x54801677, + 0x1B80, 0xE1721685, + 0x1B80, 0xE1721687, + 0x1B80, 0xBF031695, + 0x1B80, 0xBF031697, + 0x1B80, 0x000216A5, + 0x1B80, 0x000216A7, + 0x1B80, 0x302816B5, + 0x1B80, 0x302816B7, + 0x1B80, 0x54BF16C5, + 0x1B80, 0x54BF16C7, + 0x1B80, 0x54C516D5, + 0x1B80, 0x54C516D7, + 0x1B80, 0x050A16E5, + 0x1B80, 0x050A16E7, + 0x1B80, 0x071416F5, + 0x1B80, 0x071416F7, + 0x1B80, 0x54DF1705, + 0x1B80, 0x54DF1707, + 0x1B80, 0x00011715, + 0x1B80, 0x00011717, + 0x1B80, 0x54BF1725, + 0x1B80, 0x54BF1727, + 0x1B80, 0x54C01735, + 0x1B80, 0x54C01737, + 0x1B80, 0x54A31745, + 0x1B80, 0x54A31747, + 0x1B80, 0x54C11755, + 0x1B80, 0x54C11757, + 0x1B80, 0x54A41765, + 0x1B80, 0x54A41767, + 0x1B80, 0x4C831775, + 0x1B80, 0x4C831777, + 0x1B80, 0x4C031785, + 0x1B80, 0x4C031787, + 0x1B80, 0xBF0B1795, + 0x1B80, 0xBF0B1797, + 0x1B80, 0x54C217A5, + 0x1B80, 0x54C217A7, + 0x1B80, 0x54A417B5, + 0x1B80, 0x54A417B7, + 0x1B80, 0x4C8517C5, + 0x1B80, 0x4C8517C7, + 0x1B80, 0x4C0517D5, + 0x1B80, 0x4C0517D7, + 0x1B80, 0xBF0617E5, + 0x1B80, 0xBF0617E7, + 0x1B80, 0x54C117F5, + 0x1B80, 0x54C117F7, + 0x1B80, 0x54A31805, + 0x1B80, 0x54A31807, + 0x1B80, 0x4C861815, + 0x1B80, 0x4C861817, + 0x1B80, 0x4C061825, + 0x1B80, 0x4C061827, + 0x1B80, 0xBF011835, + 0x1B80, 0xBF011837, + 0x1B80, 0x54DF1845, + 0x1B80, 0x54DF1847, + 0x1B80, 0x00011855, + 0x1B80, 0x00011857, + 0x1B80, 0x00071865, + 0x1B80, 0x00071867, + 0x1B80, 0x54011875, + 0x1B80, 0x54011877, + 0x1B80, 0x00041885, + 0x1B80, 0x00041887, + 0x1B80, 0x56001895, + 0x1B80, 0x56001897, + 0x1B80, 0x5CF218A5, + 0x1B80, 0x5CF218A7, + 0x1B80, 0x630718B5, + 0x1B80, 0x630718B7, + 0x1B80, 0x620418C5, + 0x1B80, 0x620418C7, + 0x1B80, 0x610018D5, + 0x1B80, 0x610018D7, + 0x1B80, 0x670718E5, + 0x1B80, 0x670718E7, + 0x1B80, 0x660618F5, + 0x1B80, 0x660618F7, + 0x1B80, 0x6F201905, + 0x1B80, 0x6F201907, + 0x1B80, 0x6E001915, + 0x1B80, 0x6E001917, + 0x1B80, 0x6D001925, + 0x1B80, 0x6D001927, + 0x1B80, 0x6C031935, + 0x1B80, 0x6C031937, + 0x1B80, 0x73201945, + 0x1B80, 0x73201947, + 0x1B80, 0x72001955, + 0x1B80, 0x72001957, + 0x1B80, 0x71001965, + 0x1B80, 0x71001967, + 0x1B80, 0x7B201975, + 0x1B80, 0x7B201977, + 0x1B80, 0x7A001985, + 0x1B80, 0x7A001987, + 0x1B80, 0x79001995, + 0x1B80, 0x79001997, + 0x1B80, 0x7F2019A5, + 0x1B80, 0x7F2019A7, + 0x1B80, 0x7E0019B5, + 0x1B80, 0x7E0019B7, + 0x1B80, 0x7D0019C5, + 0x1B80, 0x7D0019C7, + 0x1B80, 0x090119D5, + 0x1B80, 0x090119D7, + 0x1B80, 0x0AC619E5, + 0x1B80, 0x0AC619E7, + 0x1B80, 0x0BA619F5, + 0x1B80, 0x0BA619F7, + 0x1B80, 0x0C011A05, + 0x1B80, 0x0C011A07, + 0x1B80, 0x0D021A15, + 0x1B80, 0x0D021A17, + 0x1B80, 0x0E041A25, + 0x1B80, 0x0E041A27, + 0x1B80, 0x0FFF1A35, + 0x1B80, 0x0FFF1A37, + 0x1B80, 0x4D041A45, + 0x1B80, 0x4D041A47, + 0x1B80, 0x28F81A55, + 0x1B80, 0x28F81A57, + 0x1B80, 0xE0001A65, + 0x1B80, 0xE0001A67, + 0x1B80, 0x4D001A75, + 0x1B80, 0x4D001A77, + 0x1B80, 0x00011A85, + 0x1B80, 0x00011A87, + 0x1B80, 0x4D041A95, + 0x1B80, 0x4D041A97, + 0x1B80, 0x2EF81AA5, + 0x1B80, 0x2EF81AA7, + 0x1B80, 0x00021AB5, + 0x1B80, 0x00021AB7, + 0x1B80, 0x23031AC5, + 0x1B80, 0x23031AC7, + 0x1B80, 0x00001AD5, + 0x1B80, 0x00001AD7, + 0x1B80, 0x23131AE5, + 0x1B80, 0x23131AE7, + 0x1B80, 0xE77F1AF5, + 0x1B80, 0xE77F1AF7, + 0x1B80, 0x232F1B05, + 0x1B80, 0x232F1B07, + 0x1B80, 0xEFBF1B15, + 0x1B80, 0xEFBF1B17, + 0x1B80, 0x2EF01B25, + 0x1B80, 0x2EF01B27, + 0x1B80, 0x00021B35, + 0x1B80, 0x00021B37, + 0x1B80, 0x4D001B45, + 0x1B80, 0x4D001B47, + 0x1B80, 0x00011B55, + 0x1B80, 0x00011B57, + 0x1B80, 0x4D041B65, + 0x1B80, 0x4D041B67, + 0x1B80, 0x2EF81B75, + 0x1B80, 0x2EF81B77, + 0x1B80, 0x00021B85, + 0x1B80, 0x00021B87, + 0x1B80, 0x23031B95, + 0x1B80, 0x23031B97, + 0x1B80, 0x00001BA5, + 0x1B80, 0x00001BA7, + 0x1B80, 0x23131BB5, + 0x1B80, 0x23131BB7, + 0x1B80, 0xE77F1BC5, + 0x1B80, 0xE77F1BC7, + 0x1B80, 0x232F1BD5, + 0x1B80, 0x232F1BD7, + 0x1B80, 0xE79F1BE5, + 0x1B80, 0xE79F1BE7, + 0x1B80, 0x2EF01BF5, + 0x1B80, 0x2EF01BF7, + 0x1B80, 0x00021C05, + 0x1B80, 0x00021C07, + 0x1B80, 0x28F81C15, + 0x1B80, 0x28F81C17, + 0x1B80, 0x80001C25, + 0x1B80, 0x80001C27, + 0x1B80, 0x4D001C35, + 0x1B80, 0x4D001C37, + 0x1B80, 0x00011C45, + 0x1B80, 0x00011C47, + 0x1B80, 0x00041C55, + 0x1B80, 0x00041C57, + 0x1B80, 0x6BC01C65, + 0x1B80, 0x6BC01C67, + 0x1B80, 0x4D041C75, + 0x1B80, 0x4D041C77, + 0x80000001, 0x00000000, 0x40000000, 0x00000000, + 0x1B80, 0x68241C85, + 0x1B80, 0x68241C87, + 0x90000002, 0x00000000, 0x40000000, 0x00000000, + 0x1B80, 0x68241C85, + 0x1B80, 0x68241C87, + 0x90000004, 0x00000000, 0x40000000, 0x00000000, + 0x1B80, 0x68241C85, + 0x1B80, 0x68241C87, + 0x90000003, 0x00000000, 0x40000000, 0x00000000, + 0x1B80, 0x68241C85, + 0x1B80, 0x68241C87, + 0x90000005, 0x00000000, 0x40000000, 0x00000000, + 0x1B80, 0x68241C85, + 0x1B80, 0x68241C87, + 0x90000006, 0x00000000, 0x40000000, 0x00000000, + 0x1B80, 0x68241C85, + 0x1B80, 0x68241C87, + 0x9000000a, 0x00000000, 0x40000000, 0x00000000, + 0x1B80, 0x68241C85, + 0x1B80, 0x68241C87, + 0x9000000b, 0x00000000, 0x40000000, 0x00000000, + 0x1B80, 0x68241C85, + 0x1B80, 0x68241C87, + 0xA0000000, 0x00000000, + 0x1B80, 0x68481C85, + 0x1B80, 0x68481C87, + 0xB0000000, 0x00000000, + 0x1B80, 0x66061C95, + 0x1B80, 0x66061C97, + 0x80000001, 0x00000000, 0x40000000, 0x00000000, + 0x1B80, 0x650C1CA5, + 0x1B80, 0x650C1CA7, + 0x90000002, 0x00000000, 0x40000000, 0x00000000, + 0x1B80, 0x650C1CA5, + 0x1B80, 0x650C1CA7, + 0x90000004, 0x00000000, 0x40000000, 0x00000000, + 0x1B80, 0x650C1CA5, + 0x1B80, 0x650C1CA7, + 0x90000003, 0x00000000, 0x40000000, 0x00000000, + 0x1B80, 0x650C1CA5, + 0x1B80, 0x650C1CA7, + 0x90000005, 0x00000000, 0x40000000, 0x00000000, + 0x1B80, 0x650C1CA5, + 0x1B80, 0x650C1CA7, + 0x90000006, 0x00000000, 0x40000000, 0x00000000, + 0x1B80, 0x650C1CA5, + 0x1B80, 0x650C1CA7, + 0x9000000a, 0x00000000, 0x40000000, 0x00000000, + 0x1B80, 0x650C1CA5, + 0x1B80, 0x650C1CA7, + 0x9000000b, 0x00000000, 0x40000000, 0x00000000, + 0x1B80, 0x650C1CA5, + 0x1B80, 0x650C1CA7, + 0xA0000000, 0x00000000, + 0x1B80, 0x65041CA5, + 0x1B80, 0x65041CA7, + 0xB0000000, 0x00000000, + 0x1B80, 0x64471CB5, + 0x1B80, 0x64471CB7, + 0x1B80, 0x23411CC5, + 0x1B80, 0x23411CC7, + 0x1B80, 0x100E1CD5, + 0x1B80, 0x100E1CD7, + 0x80000001, 0x00000000, 0x40000000, 0x00000000, + 0x1B80, 0x60101CE5, + 0x1B80, 0x60101CE7, + 0x90000002, 0x00000000, 0x40000000, 0x00000000, + 0x1B80, 0x60101CE5, + 0x1B80, 0x60101CE7, + 0x90000004, 0x00000000, 0x40000000, 0x00000000, + 0x1B80, 0x60101CE5, + 0x1B80, 0x60101CE7, + 0x90000003, 0x00000000, 0x40000000, 0x00000000, + 0x1B80, 0x60101CE5, + 0x1B80, 0x60101CE7, + 0x90000005, 0x00000000, 0x40000000, 0x00000000, + 0x1B80, 0x60101CE5, + 0x1B80, 0x60101CE7, + 0x90000006, 0x00000000, 0x40000000, 0x00000000, + 0x1B80, 0x60101CE5, + 0x1B80, 0x60101CE7, + 0x9000000a, 0x00000000, 0x40000000, 0x00000000, + 0x1B80, 0x60101CE5, + 0x1B80, 0x60101CE7, + 0x9000000b, 0x00000000, 0x40000000, 0x00000000, + 0x1B80, 0x60101CE5, + 0x1B80, 0x60101CE7, + 0xA0000000, 0x00000000, + 0x1B80, 0x60011CE5, + 0x1B80, 0x60011CE7, + 0xB0000000, 0x00000000, + 0x1B80, 0x23411CF5, + 0x1B80, 0x23411CF7, + 0x80000001, 0x00000000, 0x40000000, 0x00000000, + 0x1B80, 0x60811D05, + 0x1B80, 0x60811D07, + 0x90000002, 0x00000000, 0x40000000, 0x00000000, + 0x1B80, 0x60811D05, + 0x1B80, 0x60811D07, + 0x90000004, 0x00000000, 0x40000000, 0x00000000, + 0x1B80, 0x60811D05, + 0x1B80, 0x60811D07, + 0x90000003, 0x00000000, 0x40000000, 0x00000000, + 0x1B80, 0x60811D05, + 0x1B80, 0x60811D07, + 0x90000005, 0x00000000, 0x40000000, 0x00000000, + 0x1B80, 0x60811D05, + 0x1B80, 0x60811D07, + 0x90000006, 0x00000000, 0x40000000, 0x00000000, + 0x1B80, 0x60811D05, + 0x1B80, 0x60811D07, + 0x9000000a, 0x00000000, 0x40000000, 0x00000000, + 0x1B80, 0x60811D05, + 0x1B80, 0x60811D07, + 0x9000000b, 0x00000000, 0x40000000, 0x00000000, + 0x1B80, 0x60811D05, + 0x1B80, 0x60811D07, + 0xA0000000, 0x00000000, + 0x1B80, 0x60611D05, + 0x1B80, 0x60611D07, + 0xB0000000, 0x00000000, + 0x1B80, 0x23411D15, + 0x1B80, 0x23411D17, + 0x1B80, 0x70E11D25, + 0x1B80, 0x70E11D27, + 0x1B80, 0x4D001D35, + 0x1B80, 0x4D001D37, + 0x1B80, 0x00011D45, + 0x1B80, 0x00011D47, + 0x1B80, 0x00041D55, + 0x1B80, 0x00041D57, + 0x1B80, 0x6B401D65, + 0x1B80, 0x6B401D67, + 0x1B80, 0x4D041D75, + 0x1B80, 0x4D041D77, + 0x80000002, 0x00000000, 0x40000000, 0x00000000, + 0x1B80, 0x68241D85, + 0x1B80, 0x68241D87, + 0x90000004, 0x00000000, 0x40000000, 0x00000000, + 0x1B80, 0x68241D85, + 0x1B80, 0x68241D87, + 0x90000003, 0x00000000, 0x40000000, 0x00000000, + 0x1B80, 0x68241D85, + 0x1B80, 0x68241D87, + 0x90000005, 0x00000000, 0x40000000, 0x00000000, + 0x1B80, 0x68241D85, + 0x1B80, 0x68241D87, + 0x9000000a, 0x00000000, 0x40000000, 0x00000000, + 0x1B80, 0x68241D85, + 0x1B80, 0x68241D87, + 0x9000000b, 0x00000000, 0x40000000, 0x00000000, + 0x1B80, 0x68241D85, + 0x1B80, 0x68241D87, + 0xA0000000, 0x00000000, + 0x1B80, 0x68481D85, + 0x1B80, 0x68481D87, + 0xB0000000, 0x00000000, + 0x1B80, 0x66061D95, + 0x1B80, 0x66061D97, + 0x80000001, 0x00000000, 0x40000000, 0x00000000, + 0x1B80, 0x65081DA5, + 0x1B80, 0x65081DA7, + 0x90000002, 0x00000000, 0x40000000, 0x00000000, + 0x1B80, 0x65181DA5, + 0x1B80, 0x65181DA7, + 0x90000004, 0x00000000, 0x40000000, 0x00000000, + 0x1B80, 0x65181DA5, + 0x1B80, 0x65181DA7, + 0x90000003, 0x00000000, 0x40000000, 0x00000000, + 0x1B80, 0x65181DA5, + 0x1B80, 0x65181DA7, + 0x90000005, 0x00000000, 0x40000000, 0x00000000, + 0x1B80, 0x65181DA5, + 0x1B80, 0x65181DA7, + 0x90000006, 0x00000000, 0x40000000, 0x00000000, + 0x1B80, 0x65081DA5, + 0x1B80, 0x65081DA7, + 0x9000000a, 0x00000000, 0x40000000, 0x00000000, + 0x1B80, 0x65181DA5, + 0x1B80, 0x65181DA7, + 0x9000000b, 0x00000000, 0x40000000, 0x00000000, + 0x1B80, 0x65181DA5, + 0x1B80, 0x65181DA7, + 0xA0000000, 0x00000000, + 0x1B80, 0x65081DA5, + 0x1B80, 0x65081DA7, + 0xB0000000, 0x00000000, + 0x80000002, 0x00000000, 0x40000000, 0x00000000, + 0x1B80, 0x64481DB5, + 0x1B80, 0x64481DB7, + 0x90000004, 0x00000000, 0x40000000, 0x00000000, + 0x1B80, 0x64481DB5, + 0x1B80, 0x64481DB7, + 0x90000003, 0x00000000, 0x40000000, 0x00000000, + 0x1B80, 0x64481DB5, + 0x1B80, 0x64481DB7, + 0x90000005, 0x00000000, 0x40000000, 0x00000000, + 0x1B80, 0x64481DB5, + 0x1B80, 0x64481DB7, + 0x9000000a, 0x00000000, 0x40000000, 0x00000000, + 0x1B80, 0x64481DB5, + 0x1B80, 0x64481DB7, + 0x9000000b, 0x00000000, 0x40000000, 0x00000000, + 0x1B80, 0x64481DB5, + 0x1B80, 0x64481DB7, + 0xA0000000, 0x00000000, + 0x1B80, 0x64471DB5, + 0x1B80, 0x64471DB7, + 0xB0000000, 0x00000000, + 0x1B80, 0x23411DC5, + 0x1B80, 0x23411DC7, + 0x80000001, 0x00000000, 0x40000000, 0x00000000, + 0x1B80, 0x11E41DD5, + 0x1B80, 0x11E41DD7, + 0x90000002, 0x00000000, 0x40000000, 0x00000000, + 0x1B80, 0x11E81DD5, + 0x1B80, 0x11E81DD7, + 0x90000004, 0x00000000, 0x40000000, 0x00000000, + 0x1B80, 0x11E81DD5, + 0x1B80, 0x11E81DD7, + 0x90000003, 0x00000000, 0x40000000, 0x00000000, + 0x1B80, 0x11E81DD5, + 0x1B80, 0x11E81DD7, + 0x90000005, 0x00000000, 0x40000000, 0x00000000, + 0x1B80, 0x11E81DD5, + 0x1B80, 0x11E81DD7, + 0x90000006, 0x00000000, 0x40000000, 0x00000000, + 0x1B80, 0x11E41DD5, + 0x1B80, 0x11E41DD7, + 0x9000000a, 0x00000000, 0x40000000, 0x00000000, + 0x1B80, 0x11E81DD5, + 0x1B80, 0x11E81DD7, + 0x9000000b, 0x00000000, 0x40000000, 0x00000000, + 0x1B80, 0x11E81DD5, + 0x1B80, 0x11E81DD7, + 0xA0000000, 0x00000000, + 0x1B80, 0x11E41DD5, + 0x1B80, 0x11E41DD7, + 0xB0000000, 0x00000000, + 0x1B80, 0x60011DE5, + 0x1B80, 0x60011DE7, + 0x1B80, 0x23411DF5, + 0x1B80, 0x23411DF7, + 0x80000001, 0x00000000, 0x40000000, 0x00000000, + 0x1B80, 0x60E11E05, + 0x1B80, 0x60E11E07, + 0x90000002, 0x00000000, 0x40000000, 0x00000000, + 0x1B80, 0x61E11E05, + 0x1B80, 0x61E11E07, + 0x90000004, 0x00000000, 0x40000000, 0x00000000, + 0x1B80, 0x61E11E05, + 0x1B80, 0x61E11E07, + 0x90000003, 0x00000000, 0x40000000, 0x00000000, + 0x1B80, 0x61E11E05, + 0x1B80, 0x61E11E07, + 0x90000005, 0x00000000, 0x40000000, 0x00000000, + 0x1B80, 0x61E11E05, + 0x1B80, 0x61E11E07, + 0x90000006, 0x00000000, 0x40000000, 0x00000000, + 0x1B80, 0x60E11E05, + 0x1B80, 0x60E11E07, + 0x9000000a, 0x00000000, 0x40000000, 0x00000000, + 0x1B80, 0x61E11E05, + 0x1B80, 0x61E11E07, + 0x9000000b, 0x00000000, 0x40000000, 0x00000000, + 0x1B80, 0x61E11E05, + 0x1B80, 0x61E11E07, + 0xA0000000, 0x00000000, + 0x1B80, 0x60E11E05, + 0x1B80, 0x60E11E07, + 0xB0000000, 0x00000000, + 0x1B80, 0x23411E15, + 0x1B80, 0x23411E17, + 0x1B80, 0x70611E25, + 0x1B80, 0x70611E27, + 0x1B80, 0x4D001E35, + 0x1B80, 0x4D001E37, + 0x1B80, 0x00011E45, + 0x1B80, 0x00011E47, + 0x1B80, 0x00001E55, + 0x1B80, 0x00001E57, + 0x1B80, 0x00001E65, + 0x1B80, 0x00001E67, + 0x1B80, 0x00001E75, + 0x1B80, 0x00001E77, + 0x1B80, 0x00001E85, + 0x1B80, 0x00001E87, + 0x1B80, 0x00001E95, + 0x1B80, 0x00001E97, + 0x1B80, 0x00001EA5, + 0x1B80, 0x00001EA7, + 0x1B80, 0x00001EB5, + 0x1B80, 0x00001EB7, + 0x1B80, 0x00001EC5, + 0x1B80, 0x00001EC7, + 0x1B80, 0x00001ED5, + 0x1B80, 0x00001ED7, + 0x1B80, 0x00001EE5, + 0x1B80, 0x00001EE7, + 0x1B80, 0x00001EF5, + 0x1B80, 0x00001EF7, + 0x1B80, 0x00001F05, + 0x1B80, 0x00001F07, + 0x1B80, 0x00001F15, + 0x1B80, 0x00001F17, + 0x1B80, 0x00001F25, + 0x1B80, 0x00001F27, + 0x1B80, 0x00001F35, + 0x1B80, 0x00001F37, + 0x1B80, 0x00001F45, + 0x1B80, 0x00001F47, + 0x1B80, 0x00001F55, + 0x1B80, 0x00001F57, + 0x1B80, 0x00001F65, + 0x1B80, 0x00001F67, + 0x1B80, 0x00001F75, + 0x1B80, 0x00001F77, + 0x1B80, 0x00001F85, + 0x1B80, 0x00001F87, + 0x1B80, 0x00001F95, + 0x1B80, 0x00001F97, + 0x1B80, 0x00001FA5, + 0x1B80, 0x00001FA7, + 0x1B80, 0x00001FB5, + 0x1B80, 0x00001FB7, + 0x1B80, 0x00001FC5, + 0x1B80, 0x00001FC7, + 0x1B80, 0x00001FD5, + 0x1B80, 0x00001FD7, + 0x1B80, 0x00001FE5, + 0x1B80, 0x00001FE7, + 0x1B80, 0x00001FF5, + 0x1B80, 0x00001FF7, + 0x1B80, 0x00000006, + 0x1B80, 0x00000002, +}; + +RTW_DECL_TABLE_PHY_COND(rtw8814a_bb, rtw_phy_cfg_bb); + +static const struct rtw_phy_pg_cfg_pair rtw8814a_bb_pg[] = { + { 0, 0, 0, 0x00000c20, 0xffffffff, 0x34343434, }, + { 0, 0, 0, 0x00000c24, 0xffffffff, 0x34343434, }, + { 0, 0, 0, 0x00000c28, 0xffffffff, 0x30323434, }, + { 0, 0, 0, 0x00000c2c, 0xffffffff, 0x34343434, }, + { 0, 0, 0, 0x00000c30, 0xffffffff, 0x28303234, }, + { 0, 0, 1, 0x00000c34, 0xffffffff, 0x32323232, }, + { 0, 0, 1, 0x00000c38, 0xffffffff, 0x26283032, }, + { 0, 0, 2, 0x00000cd8, 0xffffffff, 0x30303030, }, + { 0, 0, 2, 0x00000cdc, 0xffffffff, 0x24262830, }, + { 0, 0, 0, 0x00000c3c, 0xffffffff, 0x34343434, }, + { 0, 0, 0, 0x00000c40, 0xffffffff, 0x28303234, }, + { 0, 0, 0, 0x00000c44, 0xffffffff, 0x32322426, }, + { 0, 0, 1, 0x00000c48, 0xffffffff, 0x30323232, }, + { 0, 0, 1, 0x00000c4c, 0xffffffff, 0x22242628, }, + { 0, 0, 2, 0x00000ce0, 0xffffffff, 0x30303030, }, + { 0, 0, 2, 0x00000ce4, 0xffffffff, 0x24262830, }, + { 0, 0, 2, 0x00000ce8, 0x0000ffff, 0x20222222, }, + { 0, 1, 0, 0x00000e20, 0xffffffff, 0x34343434, }, + { 0, 1, 0, 0x00000e24, 0xffffffff, 0x34343434, }, + { 0, 1, 0, 0x00000e28, 0xffffffff, 0x30323434, }, + { 0, 1, 0, 0x00000e2c, 0xffffffff, 0x34343434, }, + { 0, 1, 0, 0x00000e30, 0xffffffff, 0x28303234, }, + { 0, 1, 1, 0x00000e34, 0xffffffff, 0x32323232, }, + { 0, 1, 1, 0x00000e38, 0xffffffff, 0x26283032, }, + { 0, 1, 2, 0x00000ed8, 0xffffffff, 0x30303030, }, + { 0, 1, 2, 0x00000edc, 0xffffffff, 0x24262830, }, + { 0, 1, 0, 0x00000e3c, 0xffffffff, 0x34343434, }, + { 0, 1, 0, 0x00000e40, 0xffffffff, 0x28303234, }, + { 0, 1, 0, 0x00000e44, 0xffffffff, 0x32322426, }, + { 0, 1, 1, 0x00000e48, 0xffffffff, 0x30323232, }, + { 0, 1, 1, 0x00000e4c, 0xffffffff, 0x22242628, }, + { 0, 1, 2, 0x00000ee0, 0xffffffff, 0x30303030, }, + { 0, 1, 2, 0x00000ee4, 0xffffffff, 0x24262830, }, + { 0, 1, 2, 0x00000ee8, 0x0000ffff, 0x20222222, }, + { 0, 2, 0, 0x00001820, 0xffffffff, 0x34343434, }, + { 0, 2, 0, 0x00001824, 0xffffffff, 0x34343434, }, + { 0, 2, 0, 0x00001828, 0xffffffff, 0x30323434, }, + { 0, 2, 0, 0x0000182c, 0xffffffff, 0x34343434, }, + { 0, 2, 0, 0x00001830, 0xffffffff, 0x28303234, }, + { 0, 2, 1, 0x00001834, 0xffffffff, 0x32323232, }, + { 0, 2, 1, 0x00001838, 0xffffffff, 0x26283032, }, + { 0, 2, 2, 0x000018d8, 0xffffffff, 0x30303030, }, + { 0, 2, 2, 0x000018dc, 0xffffffff, 0x24262830, }, + { 0, 2, 0, 0x0000183c, 0xffffffff, 0x34343434, }, + { 0, 2, 0, 0x00001840, 0xffffffff, 0x28303234, }, + { 0, 2, 0, 0x00001844, 0xffffffff, 0x32322426, }, + { 0, 2, 1, 0x00001848, 0xffffffff, 0x30323232, }, + { 0, 2, 1, 0x0000184c, 0xffffffff, 0x22242628, }, + { 0, 2, 2, 0x000018e0, 0xffffffff, 0x30303030, }, + { 0, 2, 2, 0x000018e4, 0xffffffff, 0x24262830, }, + { 0, 2, 2, 0x000018e8, 0x0000ffff, 0x20222222, }, + { 0, 3, 0, 0x00001a20, 0xffffffff, 0x34343434, }, + { 0, 3, 0, 0x00001a24, 0xffffffff, 0x34343434, }, + { 0, 3, 0, 0x00001a28, 0xffffffff, 0x30323434, }, + { 0, 3, 0, 0x00001a2c, 0xffffffff, 0x34343434, }, + { 0, 3, 0, 0x00001a30, 0xffffffff, 0x28303234, }, + { 0, 3, 1, 0x00001a34, 0xffffffff, 0x32323232, }, + { 0, 3, 1, 0x00001a38, 0xffffffff, 0x26283032, }, + { 0, 3, 2, 0x00001ad8, 0xffffffff, 0x30303030, }, + { 0, 3, 2, 0x00001adc, 0xffffffff, 0x24262830, }, + { 0, 3, 0, 0x00001a3c, 0xffffffff, 0x34343434, }, + { 0, 3, 0, 0x00001a40, 0xffffffff, 0x28303234, }, + { 0, 3, 0, 0x00001a44, 0xffffffff, 0x32322426, }, + { 0, 3, 1, 0x00001a48, 0xffffffff, 0x30323232, }, + { 0, 3, 1, 0x00001a4c, 0xffffffff, 0x22242628, }, + { 0, 3, 2, 0x00001ae0, 0xffffffff, 0x30303030, }, + { 0, 3, 2, 0x00001ae4, 0xffffffff, 0x24262830, }, + { 0, 3, 2, 0x00001ae8, 0x0000ffff, 0x20222222, }, + { 1, 0, 0, 0x00000c24, 0xffffffff, 0x34343434, }, + { 1, 0, 0, 0x00000c28, 0xffffffff, 0x30323434, }, + { 1, 0, 0, 0x00000c2c, 0xffffffff, 0x34343434, }, + { 1, 0, 0, 0x00000c30, 0xffffffff, 0x28303234, }, + { 1, 0, 1, 0x00000c34, 0xffffffff, 0x32323232, }, + { 1, 0, 1, 0x00000c38, 0xffffffff, 0x26283032, }, + { 1, 0, 2, 0x00000cd8, 0xffffffff, 0x30303030, }, + { 1, 0, 2, 0x00000cdc, 0xffffffff, 0x24262830, }, + { 1, 0, 0, 0x00000c3c, 0xffffffff, 0x34343434, }, + { 1, 0, 0, 0x00000c40, 0xffffffff, 0x28303234, }, + { 1, 0, 0, 0x00000c44, 0xffffffff, 0x32322426, }, + { 1, 0, 1, 0x00000c48, 0xffffffff, 0x30323232, }, + { 1, 0, 1, 0x00000c4c, 0xffffffff, 0x22242628, }, + { 1, 0, 2, 0x00000ce0, 0xffffffff, 0x30303030, }, + { 1, 0, 2, 0x00000ce4, 0xffffffff, 0x24262830, }, + { 1, 0, 2, 0x00000ce8, 0x0000ffff, 0x20222222, }, + { 1, 1, 0, 0x00000e24, 0xffffffff, 0x34343434, }, + { 1, 1, 0, 0x00000e28, 0xffffffff, 0x30323434, }, + { 1, 1, 0, 0x00000e2c, 0xffffffff, 0x34343434, }, + { 1, 1, 0, 0x00000e30, 0xffffffff, 0x28303234, }, + { 1, 1, 1, 0x00000e34, 0xffffffff, 0x32323232, }, + { 1, 1, 1, 0x00000e38, 0xffffffff, 0x26283032, }, + { 1, 1, 2, 0x00000ed8, 0xffffffff, 0x30303030, }, + { 1, 1, 2, 0x00000edc, 0xffffffff, 0x24262830, }, + { 1, 1, 0, 0x00000e3c, 0xffffffff, 0x34343434, }, + { 1, 1, 0, 0x00000e40, 0xffffffff, 0x28303234, }, + { 1, 1, 0, 0x00000e44, 0xffffffff, 0x32322426, }, + { 1, 1, 1, 0x00000e48, 0xffffffff, 0x30323232, }, + { 1, 1, 1, 0x00000e4c, 0xffffffff, 0x22242628, }, + { 1, 1, 2, 0x00000ee0, 0xffffffff, 0x30303030, }, + { 1, 1, 2, 0x00000ee4, 0xffffffff, 0x24262830, }, + { 1, 1, 2, 0x00000ee8, 0x0000ffff, 0x20222222, }, + { 1, 2, 0, 0x00001824, 0xffffffff, 0x34343434, }, + { 1, 2, 0, 0x00001828, 0xffffffff, 0x30323434, }, + { 1, 2, 0, 0x0000182c, 0xffffffff, 0x34343434, }, + { 1, 2, 0, 0x00001830, 0xffffffff, 0x28303234, }, + { 1, 2, 1, 0x00001834, 0xffffffff, 0x32323232, }, + { 1, 2, 1, 0x00001838, 0xffffffff, 0x26283032, }, + { 1, 2, 2, 0x000018d8, 0xffffffff, 0x30303030, }, + { 1, 2, 2, 0x000018dc, 0xffffffff, 0x24262830, }, + { 1, 2, 0, 0x0000183c, 0xffffffff, 0x34343434, }, + { 1, 2, 0, 0x00001840, 0xffffffff, 0x28303234, }, + { 1, 2, 0, 0x00001844, 0xffffffff, 0x32322426, }, + { 1, 2, 1, 0x00001848, 0xffffffff, 0x30323232, }, + { 1, 2, 1, 0x0000184c, 0xffffffff, 0x22242628, }, + { 1, 2, 2, 0x000018e0, 0xffffffff, 0x30303030, }, + { 1, 2, 2, 0x000018e4, 0xffffffff, 0x24262830, }, + { 1, 2, 2, 0x000018e8, 0x0000ffff, 0x20222222, }, + { 1, 3, 0, 0x00001a24, 0xffffffff, 0x34343434, }, + { 1, 3, 0, 0x00001a28, 0xffffffff, 0x30323434, }, + { 1, 3, 0, 0x00001a2c, 0xffffffff, 0x34343434, }, + { 1, 3, 0, 0x00001a30, 0xffffffff, 0x28303234, }, + { 1, 3, 1, 0x00001a34, 0xffffffff, 0x32323232, }, + { 1, 3, 1, 0x00001a38, 0xffffffff, 0x26283032, }, + { 1, 3, 2, 0x00001ad8, 0xffffffff, 0x30303030, }, + { 1, 3, 2, 0x00001adc, 0xffffffff, 0x24262830, }, + { 1, 3, 0, 0x00001a3c, 0xffffffff, 0x34343434, }, + { 1, 3, 0, 0x00001a40, 0xffffffff, 0x28303234, }, + { 1, 3, 0, 0x00001a44, 0xffffffff, 0x32322426, }, + { 1, 3, 1, 0x00001a48, 0xffffffff, 0x30323232, }, + { 1, 3, 1, 0x00001a4c, 0xffffffff, 0x22242628, }, + { 1, 3, 2, 0x00001ae0, 0xffffffff, 0x30303030, }, + { 1, 3, 2, 0x00001ae4, 0xffffffff, 0x24262830, }, + { 1, 3, 2, 0x00001ae8, 0x0000ffff, 0x20222222, }, +}; + +RTW_DECL_TABLE_BB_PG(rtw8814a_bb_pg); + +static const struct rtw_phy_pg_cfg_pair rtw8814a_bb_pg_type0[] = { + { 0, 0, 0, 0x00000c20, 0xffffffff, 0x32323232, }, + { 0, 0, 0, 0x00000c24, 0xffffffff, 0x32323232, }, + { 0, 0, 0, 0x00000c28, 0xffffffff, 0x28303232, }, + { 0, 0, 0, 0x00000c2c, 0xffffffff, 0x32323232, }, + { 0, 0, 0, 0x00000c30, 0xffffffff, 0x26283032, }, + { 0, 0, 1, 0x00000c34, 0xffffffff, 0x30303030, }, + { 0, 0, 1, 0x00000c38, 0xffffffff, 0x24262830, }, + { 0, 0, 2, 0x00000cd8, 0xffffffff, 0x28282828, }, + { 0, 0, 2, 0x00000cdc, 0xffffffff, 0x22242628, }, + { 0, 0, 0, 0x00000c3c, 0xffffffff, 0x32323232, }, + { 0, 0, 0, 0x00000c40, 0xffffffff, 0x26283032, }, + { 0, 0, 0, 0x00000c44, 0xffffffff, 0x30302224, }, + { 0, 0, 1, 0x00000c48, 0xffffffff, 0x28303030, }, + { 0, 0, 1, 0x00000c4c, 0xffffffff, 0x20222426, }, + { 0, 0, 2, 0x00000ce0, 0xffffffff, 0x28282828, }, + { 0, 0, 2, 0x00000ce4, 0xffffffff, 0x22242628, }, + { 0, 0, 2, 0x00000ce8, 0x0000ffff, 0x18202020, }, + { 0, 1, 0, 0x00000e20, 0xffffffff, 0x32323232, }, + { 0, 1, 0, 0x00000e24, 0xffffffff, 0x32323232, }, + { 0, 1, 0, 0x00000e28, 0xffffffff, 0x28303232, }, + { 0, 1, 0, 0x00000e2c, 0xffffffff, 0x32323232, }, + { 0, 1, 0, 0x00000e30, 0xffffffff, 0x26283032, }, + { 0, 1, 1, 0x00000e34, 0xffffffff, 0x30303030, }, + { 0, 1, 1, 0x00000e38, 0xffffffff, 0x24262830, }, + { 0, 1, 2, 0x00000ed8, 0xffffffff, 0x28282828, }, + { 0, 1, 2, 0x00000edc, 0xffffffff, 0x22242628, }, + { 0, 1, 0, 0x00000e3c, 0xffffffff, 0x32323232, }, + { 0, 1, 0, 0x00000e40, 0xffffffff, 0x26283032, }, + { 0, 1, 0, 0x00000e44, 0xffffffff, 0x30302224, }, + { 0, 1, 1, 0x00000e48, 0xffffffff, 0x28303030, }, + { 0, 1, 1, 0x00000e4c, 0xffffffff, 0x20222426, }, + { 0, 1, 2, 0x00000ee0, 0xffffffff, 0x28282828, }, + { 0, 1, 2, 0x00000ee4, 0xffffffff, 0x22242628, }, + { 0, 1, 2, 0x00000ee8, 0x0000ffff, 0x18202020, }, + { 0, 2, 0, 0x00001820, 0xffffffff, 0x32323232, }, + { 0, 2, 0, 0x00001824, 0xffffffff, 0x32323232, }, + { 0, 2, 0, 0x00001828, 0xffffffff, 0x28303232, }, + { 0, 2, 0, 0x0000182c, 0xffffffff, 0x32323232, }, + { 0, 2, 0, 0x00001830, 0xffffffff, 0x26283032, }, + { 0, 2, 1, 0x00001834, 0xffffffff, 0x30303030, }, + { 0, 2, 1, 0x00001838, 0xffffffff, 0x24262830, }, + { 0, 2, 2, 0x000018d8, 0xffffffff, 0x28282828, }, + { 0, 2, 2, 0x000018dc, 0xffffffff, 0x22242628, }, + { 0, 2, 0, 0x0000183c, 0xffffffff, 0x32323232, }, + { 0, 2, 0, 0x00001840, 0xffffffff, 0x26283032, }, + { 0, 2, 0, 0x00001844, 0xffffffff, 0x30302224, }, + { 0, 2, 1, 0x00001848, 0xffffffff, 0x28303030, }, + { 0, 2, 1, 0x0000184c, 0xffffffff, 0x20222426, }, + { 0, 2, 2, 0x000018e0, 0xffffffff, 0x28282828, }, + { 0, 2, 2, 0x000018e4, 0xffffffff, 0x22242628, }, + { 0, 2, 2, 0x000018e8, 0x0000ffff, 0x18202020, }, + { 0, 3, 0, 0x00001a20, 0xffffffff, 0x32323232, }, + { 0, 3, 0, 0x00001a24, 0xffffffff, 0x32323232, }, + { 0, 3, 0, 0x00001a28, 0xffffffff, 0x28303232, }, + { 0, 3, 0, 0x00001a2c, 0xffffffff, 0x32323232, }, + { 0, 3, 0, 0x00001a30, 0xffffffff, 0x26283032, }, + { 0, 3, 1, 0x00001a34, 0xffffffff, 0x30303030, }, + { 0, 3, 1, 0x00001a38, 0xffffffff, 0x24262830, }, + { 0, 3, 2, 0x00001ad8, 0xffffffff, 0x28282828, }, + { 0, 3, 2, 0x00001adc, 0xffffffff, 0x22242628, }, + { 0, 3, 0, 0x00001a3c, 0xffffffff, 0x32323232, }, + { 0, 3, 0, 0x00001a40, 0xffffffff, 0x26283032, }, + { 0, 3, 0, 0x00001a44, 0xffffffff, 0x30302224, }, + { 0, 3, 1, 0x00001a48, 0xffffffff, 0x28303030, }, + { 0, 3, 1, 0x00001a4c, 0xffffffff, 0x20222426, }, + { 0, 3, 2, 0x00001ae0, 0xffffffff, 0x28282828, }, + { 0, 3, 2, 0x00001ae4, 0xffffffff, 0x22242628, }, + { 0, 3, 2, 0x00001ae8, 0x0000ffff, 0x18202020, }, + { 1, 0, 0, 0x00000c24, 0xffffffff, 0x32323232, }, + { 1, 0, 0, 0x00000c28, 0xffffffff, 0x28303232, }, + { 1, 0, 0, 0x00000c2c, 0xffffffff, 0x32323232, }, + { 1, 0, 0, 0x00000c30, 0xffffffff, 0x26283032, }, + { 1, 0, 1, 0x00000c34, 0xffffffff, 0x30303030, }, + { 1, 0, 1, 0x00000c38, 0xffffffff, 0x24262830, }, + { 1, 0, 2, 0x00000cd8, 0xffffffff, 0x28282828, }, + { 1, 0, 2, 0x00000cdc, 0xffffffff, 0x22242628, }, + { 1, 0, 0, 0x00000c3c, 0xffffffff, 0x32323232, }, + { 1, 0, 0, 0x00000c40, 0xffffffff, 0x26283032, }, + { 1, 0, 0, 0x00000c44, 0xffffffff, 0x30302224, }, + { 1, 0, 1, 0x00000c48, 0xffffffff, 0x28303030, }, + { 1, 0, 1, 0x00000c4c, 0xffffffff, 0x20222426, }, + { 1, 0, 2, 0x00000ce0, 0xffffffff, 0x28282828, }, + { 1, 0, 2, 0x00000ce4, 0xffffffff, 0x22242628, }, + { 1, 0, 2, 0x00000ce8, 0x0000ffff, 0x18202020, }, + { 1, 1, 0, 0x00000e24, 0xffffffff, 0x32323232, }, + { 1, 1, 0, 0x00000e28, 0xffffffff, 0x28303232, }, + { 1, 1, 0, 0x00000e2c, 0xffffffff, 0x32323232, }, + { 1, 1, 0, 0x00000e30, 0xffffffff, 0x26283032, }, + { 1, 1, 1, 0x00000e34, 0xffffffff, 0x30303030, }, + { 1, 1, 1, 0x00000e38, 0xffffffff, 0x24262830, }, + { 1, 1, 2, 0x00000ed8, 0xffffffff, 0x28282828, }, + { 1, 1, 2, 0x00000edc, 0xffffffff, 0x22242628, }, + { 1, 1, 0, 0x00000e3c, 0xffffffff, 0x32323232, }, + { 1, 1, 0, 0x00000e40, 0xffffffff, 0x26283032, }, + { 1, 1, 0, 0x00000e44, 0xffffffff, 0x30302224, }, + { 1, 1, 1, 0x00000e48, 0xffffffff, 0x28303030, }, + { 1, 1, 1, 0x00000e4c, 0xffffffff, 0x20222426, }, + { 1, 1, 2, 0x00000ee0, 0xffffffff, 0x28282828, }, + { 1, 1, 2, 0x00000ee4, 0xffffffff, 0x22242628, }, + { 1, 1, 2, 0x00000ee8, 0x0000ffff, 0x18202020, }, + { 1, 2, 0, 0x00001824, 0xffffffff, 0x32323232, }, + { 1, 2, 0, 0x00001828, 0xffffffff, 0x28303232, }, + { 1, 2, 0, 0x0000182c, 0xffffffff, 0x32323232, }, + { 1, 2, 0, 0x00001830, 0xffffffff, 0x26283032, }, + { 1, 2, 1, 0x00001834, 0xffffffff, 0x30303030, }, + { 1, 2, 1, 0x00001838, 0xffffffff, 0x24262830, }, + { 1, 2, 2, 0x000018d8, 0xffffffff, 0x28282828, }, + { 1, 2, 2, 0x000018dc, 0xffffffff, 0x22242628, }, + { 1, 2, 0, 0x0000183c, 0xffffffff, 0x32323232, }, + { 1, 2, 0, 0x00001840, 0xffffffff, 0x26283032, }, + { 1, 2, 0, 0x00001844, 0xffffffff, 0x30302224, }, + { 1, 2, 1, 0x00001848, 0xffffffff, 0x28303030, }, + { 1, 2, 1, 0x0000184c, 0xffffffff, 0x20222426, }, + { 1, 2, 2, 0x000018e0, 0xffffffff, 0x28282828, }, + { 1, 2, 2, 0x000018e4, 0xffffffff, 0x22242628, }, + { 1, 2, 2, 0x000018e8, 0x0000ffff, 0x18202020, }, + { 1, 3, 0, 0x00001a24, 0xffffffff, 0x32323232, }, + { 1, 3, 0, 0x00001a28, 0xffffffff, 0x28303232, }, + { 1, 3, 0, 0x00001a2c, 0xffffffff, 0x32323232, }, + { 1, 3, 0, 0x00001a30, 0xffffffff, 0x26283032, }, + { 1, 3, 1, 0x00001a34, 0xffffffff, 0x30303030, }, + { 1, 3, 1, 0x00001a38, 0xffffffff, 0x24262830, }, + { 1, 3, 2, 0x00001ad8, 0xffffffff, 0x28282828, }, + { 1, 3, 2, 0x00001adc, 0xffffffff, 0x22242628, }, + { 1, 3, 0, 0x00001a3c, 0xffffffff, 0x32323232, }, + { 1, 3, 0, 0x00001a40, 0xffffffff, 0x26283032, }, + { 1, 3, 0, 0x00001a44, 0xffffffff, 0x30302224, }, + { 1, 3, 1, 0x00001a48, 0xffffffff, 0x28303030, }, + { 1, 3, 1, 0x00001a4c, 0xffffffff, 0x20222426, }, + { 1, 3, 2, 0x00001ae0, 0xffffffff, 0x28282828, }, + { 1, 3, 2, 0x00001ae4, 0xffffffff, 0x22242628, }, + { 1, 3, 2, 0x00001ae8, 0x0000ffff, 0x18202020, }, +}; + +RTW_DECL_TABLE_BB_PG(rtw8814a_bb_pg_type0); + +static const struct rtw_phy_pg_cfg_pair rtw8814a_bb_pg_type2[] = { + { 0, 0, 0, 0x00000c20, 0xffffffff, 0x34343434, }, + { 0, 0, 0, 0x00000c24, 0xffffffff, 0x34343434, }, + { 0, 0, 0, 0x00000c28, 0xffffffff, 0x30323434, }, + { 0, 0, 0, 0x00000c2c, 0xffffffff, 0x34343434, }, + { 0, 0, 0, 0x00000c30, 0xffffffff, 0x28303234, }, + { 0, 0, 1, 0x00000c34, 0xffffffff, 0x32323232, }, + { 0, 0, 1, 0x00000c38, 0xffffffff, 0x26283032, }, + { 0, 0, 2, 0x00000cd8, 0xffffffff, 0x30303030, }, + { 0, 0, 2, 0x00000cdc, 0xffffffff, 0x24262830, }, + { 0, 0, 0, 0x00000c3c, 0xffffffff, 0x34343434, }, + { 0, 0, 0, 0x00000c40, 0xffffffff, 0x28303234, }, + { 0, 0, 0, 0x00000c44, 0xffffffff, 0x32322426, }, + { 0, 0, 1, 0x00000c48, 0xffffffff, 0x30323232, }, + { 0, 0, 1, 0x00000c4c, 0xffffffff, 0x22242628, }, + { 0, 0, 2, 0x00000ce0, 0xffffffff, 0x30303030, }, + { 0, 0, 2, 0x00000ce4, 0xffffffff, 0x24262830, }, + { 0, 0, 2, 0x00000ce8, 0x0000ffff, 0x20222222, }, + { 0, 1, 0, 0x00000e20, 0xffffffff, 0x34343434, }, + { 0, 1, 0, 0x00000e24, 0xffffffff, 0x34343434, }, + { 0, 1, 0, 0x00000e28, 0xffffffff, 0x30323434, }, + { 0, 1, 0, 0x00000e2c, 0xffffffff, 0x34343434, }, + { 0, 1, 0, 0x00000e30, 0xffffffff, 0x28303234, }, + { 0, 1, 1, 0x00000e34, 0xffffffff, 0x32323232, }, + { 0, 1, 1, 0x00000e38, 0xffffffff, 0x26283032, }, + { 0, 1, 2, 0x00000ed8, 0xffffffff, 0x30303030, }, + { 0, 1, 2, 0x00000edc, 0xffffffff, 0x24262830, }, + { 0, 1, 0, 0x00000e3c, 0xffffffff, 0x34343434, }, + { 0, 1, 0, 0x00000e40, 0xffffffff, 0x28303234, }, + { 0, 1, 0, 0x00000e44, 0xffffffff, 0x32322426, }, + { 0, 1, 1, 0x00000e48, 0xffffffff, 0x30323232, }, + { 0, 1, 1, 0x00000e4c, 0xffffffff, 0x22242628, }, + { 0, 1, 2, 0x00000ee0, 0xffffffff, 0x30303030, }, + { 0, 1, 2, 0x00000ee4, 0xffffffff, 0x24262830, }, + { 0, 1, 2, 0x00000ee8, 0x0000ffff, 0x20222222, }, + { 0, 2, 0, 0x00001820, 0xffffffff, 0x34343434, }, + { 0, 2, 0, 0x00001824, 0xffffffff, 0x34343434, }, + { 0, 2, 0, 0x00001828, 0xffffffff, 0x30323434, }, + { 0, 2, 0, 0x0000182c, 0xffffffff, 0x34343434, }, + { 0, 2, 0, 0x00001830, 0xffffffff, 0x28303234, }, + { 0, 2, 1, 0x00001834, 0xffffffff, 0x32323232, }, + { 0, 2, 1, 0x00001838, 0xffffffff, 0x26283032, }, + { 0, 2, 2, 0x000018d8, 0xffffffff, 0x30303030, }, + { 0, 2, 2, 0x000018dc, 0xffffffff, 0x24262830, }, + { 0, 2, 0, 0x0000183c, 0xffffffff, 0x34343434, }, + { 0, 2, 0, 0x00001840, 0xffffffff, 0x28303234, }, + { 0, 2, 0, 0x00001844, 0xffffffff, 0x32322426, }, + { 0, 2, 1, 0x00001848, 0xffffffff, 0x30323232, }, + { 0, 2, 1, 0x0000184c, 0xffffffff, 0x22242628, }, + { 0, 2, 2, 0x000018e0, 0xffffffff, 0x30303030, }, + { 0, 2, 2, 0x000018e4, 0xffffffff, 0x24262830, }, + { 0, 2, 2, 0x000018e8, 0x0000ffff, 0x20222222, }, + { 0, 3, 0, 0x00001a20, 0xffffffff, 0x34343434, }, + { 0, 3, 0, 0x00001a24, 0xffffffff, 0x34343434, }, + { 0, 3, 0, 0x00001a28, 0xffffffff, 0x30323434, }, + { 0, 3, 0, 0x00001a2c, 0xffffffff, 0x34343434, }, + { 0, 3, 0, 0x00001a30, 0xffffffff, 0x28303234, }, + { 0, 3, 1, 0x00001a34, 0xffffffff, 0x32323232, }, + { 0, 3, 1, 0x00001a38, 0xffffffff, 0x26283032, }, + { 0, 3, 2, 0x00001ad8, 0xffffffff, 0x30303030, }, + { 0, 3, 2, 0x00001adc, 0xffffffff, 0x24262830, }, + { 0, 3, 0, 0x00001a3c, 0xffffffff, 0x34343434, }, + { 0, 3, 0, 0x00001a40, 0xffffffff, 0x28303234, }, + { 0, 3, 0, 0x00001a44, 0xffffffff, 0x32322426, }, + { 0, 3, 1, 0x00001a48, 0xffffffff, 0x30323232, }, + { 0, 3, 1, 0x00001a4c, 0xffffffff, 0x22242628, }, + { 0, 3, 2, 0x00001ae0, 0xffffffff, 0x30303030, }, + { 0, 3, 2, 0x00001ae4, 0xffffffff, 0x24262830, }, + { 0, 3, 2, 0x00001ae8, 0x0000ffff, 0x20222222, }, + { 1, 0, 0, 0x00000c24, 0xffffffff, 0x34343434, }, + { 1, 0, 0, 0x00000c28, 0xffffffff, 0x30323434, }, + { 1, 0, 0, 0x00000c2c, 0xffffffff, 0x34343434, }, + { 1, 0, 0, 0x00000c30, 0xffffffff, 0x28303234, }, + { 1, 0, 1, 0x00000c34, 0xffffffff, 0x32323232, }, + { 1, 0, 1, 0x00000c38, 0xffffffff, 0x26283032, }, + { 1, 0, 2, 0x00000cd8, 0xffffffff, 0x30303030, }, + { 1, 0, 2, 0x00000cdc, 0xffffffff, 0x24262830, }, + { 1, 0, 0, 0x00000c3c, 0xffffffff, 0x34343434, }, + { 1, 0, 0, 0x00000c40, 0xffffffff, 0x28303234, }, + { 1, 0, 0, 0x00000c44, 0xffffffff, 0x32322426, }, + { 1, 0, 1, 0x00000c48, 0xffffffff, 0x30323232, }, + { 1, 0, 1, 0x00000c4c, 0xffffffff, 0x22242628, }, + { 1, 0, 2, 0x00000ce0, 0xffffffff, 0x30303030, }, + { 1, 0, 2, 0x00000ce4, 0xffffffff, 0x24262830, }, + { 1, 0, 2, 0x00000ce8, 0x0000ffff, 0x20222222, }, + { 1, 1, 0, 0x00000e24, 0xffffffff, 0x34343434, }, + { 1, 1, 0, 0x00000e28, 0xffffffff, 0x30323434, }, + { 1, 1, 0, 0x00000e2c, 0xffffffff, 0x34343434, }, + { 1, 1, 0, 0x00000e30, 0xffffffff, 0x28303234, }, + { 1, 1, 1, 0x00000e34, 0xffffffff, 0x32323232, }, + { 1, 1, 1, 0x00000e38, 0xffffffff, 0x26283032, }, + { 1, 1, 2, 0x00000ed8, 0xffffffff, 0x30303030, }, + { 1, 1, 2, 0x00000edc, 0xffffffff, 0x24262830, }, + { 1, 1, 0, 0x00000e3c, 0xffffffff, 0x34343434, }, + { 1, 1, 0, 0x00000e40, 0xffffffff, 0x28303234, }, + { 1, 1, 0, 0x00000e44, 0xffffffff, 0x32322426, }, + { 1, 1, 1, 0x00000e48, 0xffffffff, 0x30323232, }, + { 1, 1, 1, 0x00000e4c, 0xffffffff, 0x22242628, }, + { 1, 1, 2, 0x00000ee0, 0xffffffff, 0x30303030, }, + { 1, 1, 2, 0x00000ee4, 0xffffffff, 0x24262830, }, + { 1, 1, 2, 0x00000ee8, 0x0000ffff, 0x20222222, }, + { 1, 2, 0, 0x00001824, 0xffffffff, 0x34343434, }, + { 1, 2, 0, 0x00001828, 0xffffffff, 0x30323434, }, + { 1, 2, 0, 0x0000182c, 0xffffffff, 0x34343434, }, + { 1, 2, 0, 0x00001830, 0xffffffff, 0x28303234, }, + { 1, 2, 1, 0x00001834, 0xffffffff, 0x32323232, }, + { 1, 2, 1, 0x00001838, 0xffffffff, 0x26283032, }, + { 1, 2, 2, 0x000018d8, 0xffffffff, 0x30303030, }, + { 1, 2, 2, 0x000018dc, 0xffffffff, 0x24262830, }, + { 1, 2, 0, 0x0000183c, 0xffffffff, 0x34343434, }, + { 1, 2, 0, 0x00001840, 0xffffffff, 0x28303234, }, + { 1, 2, 0, 0x00001844, 0xffffffff, 0x32322426, }, + { 1, 2, 1, 0x00001848, 0xffffffff, 0x30323232, }, + { 1, 2, 1, 0x0000184c, 0xffffffff, 0x22242628, }, + { 1, 2, 2, 0x000018e0, 0xffffffff, 0x30303030, }, + { 1, 2, 2, 0x000018e4, 0xffffffff, 0x24262830, }, + { 1, 2, 2, 0x000018e8, 0x0000ffff, 0x20222222, }, + { 1, 3, 0, 0x00001a24, 0xffffffff, 0x34343434, }, + { 1, 3, 0, 0x00001a28, 0xffffffff, 0x30323434, }, + { 1, 3, 0, 0x00001a2c, 0xffffffff, 0x34343434, }, + { 1, 3, 0, 0x00001a30, 0xffffffff, 0x28303234, }, + { 1, 3, 1, 0x00001a34, 0xffffffff, 0x32323232, }, + { 1, 3, 1, 0x00001a38, 0xffffffff, 0x26283032, }, + { 1, 3, 2, 0x00001ad8, 0xffffffff, 0x30303030, }, + { 1, 3, 2, 0x00001adc, 0xffffffff, 0x24262830, }, + { 1, 3, 0, 0x00001a3c, 0xffffffff, 0x34343434, }, + { 1, 3, 0, 0x00001a40, 0xffffffff, 0x28303234, }, + { 1, 3, 0, 0x00001a44, 0xffffffff, 0x32322426, }, + { 1, 3, 1, 0x00001a48, 0xffffffff, 0x30323232, }, + { 1, 3, 1, 0x00001a4c, 0xffffffff, 0x22242628, }, + { 1, 3, 2, 0x00001ae0, 0xffffffff, 0x30303030, }, + { 1, 3, 2, 0x00001ae4, 0xffffffff, 0x24262830, }, + { 1, 3, 2, 0x00001ae8, 0x0000ffff, 0x20222222, }, +}; + +RTW_DECL_TABLE_BB_PG(rtw8814a_bb_pg_type2); + +static const struct rtw_phy_pg_cfg_pair rtw8814a_bb_pg_type3[] = { + { 0, 0, 0, 0x00000c20, 0xffffffff, 0x48484848, }, + { 0, 0, 0, 0x00000c24, 0xffffffff, 0x46464646, }, + { 0, 0, 0, 0x00000c28, 0xffffffff, 0x44464646, }, + { 0, 0, 0, 0x00000c2c, 0xffffffff, 0x46464646, }, + { 0, 0, 0, 0x00000c30, 0xffffffff, 0x42444646, }, + { 0, 0, 1, 0x00000c34, 0xffffffff, 0x46464646, }, + { 0, 0, 1, 0x00000c38, 0xffffffff, 0x42444646, }, + { 0, 0, 2, 0x00000cd8, 0xffffffff, 0x46464646, }, + { 0, 0, 2, 0x00000cdc, 0xffffffff, 0x42444646, }, + { 0, 0, 0, 0x00000c3c, 0xffffffff, 0x46464646, }, + { 0, 0, 0, 0x00000c40, 0xffffffff, 0x42444646, }, + { 0, 0, 0, 0x00000c44, 0xffffffff, 0x46463840, }, + { 0, 0, 1, 0x00000c48, 0xffffffff, 0x46464646, }, + { 0, 0, 1, 0x00000c4c, 0xffffffff, 0x38404244, }, + { 0, 0, 2, 0x00000ce0, 0xffffffff, 0x46464646, }, + { 0, 0, 2, 0x00000ce4, 0xffffffff, 0x42444646, }, + { 0, 0, 2, 0x00000ce8, 0x0000ffff, 0x38383840, }, + { 0, 1, 0, 0x00000e20, 0xffffffff, 0x48484848, }, + { 0, 1, 0, 0x00000e24, 0xffffffff, 0x46464646, }, + { 0, 1, 0, 0x00000e28, 0xffffffff, 0x44464646, }, + { 0, 1, 0, 0x00000e2c, 0xffffffff, 0x46464646, }, + { 0, 1, 0, 0x00000e30, 0xffffffff, 0x42444646, }, + { 0, 1, 1, 0x00000e34, 0xffffffff, 0x46464646, }, + { 0, 1, 1, 0x00000e38, 0xffffffff, 0x42444646, }, + { 0, 1, 2, 0x00000ed8, 0xffffffff, 0x46464646, }, + { 0, 1, 2, 0x00000edc, 0xffffffff, 0x42444646, }, + { 0, 1, 0, 0x00000e3c, 0xffffffff, 0x46464646, }, + { 0, 1, 0, 0x00000e40, 0xffffffff, 0x42444646, }, + { 0, 1, 0, 0x00000e44, 0xffffffff, 0x46463840, }, + { 0, 1, 1, 0x00000e48, 0xffffffff, 0x46464646, }, + { 0, 1, 1, 0x00000e4c, 0xffffffff, 0x38404244, }, + { 0, 1, 2, 0x00000ee0, 0xffffffff, 0x46464646, }, + { 0, 1, 2, 0x00000ee4, 0xffffffff, 0x42444646, }, + { 0, 1, 2, 0x00000ee8, 0x0000ffff, 0x38383840, }, + { 0, 2, 0, 0x00001820, 0xffffffff, 0x48484848, }, + { 0, 2, 0, 0x00001824, 0xffffffff, 0x46464646, }, + { 0, 2, 0, 0x00001828, 0xffffffff, 0x44464646, }, + { 0, 2, 0, 0x0000182c, 0xffffffff, 0x46464646, }, + { 0, 2, 0, 0x00001830, 0xffffffff, 0x42444646, }, + { 0, 2, 1, 0x00001834, 0xffffffff, 0x46464646, }, + { 0, 2, 1, 0x00001838, 0xffffffff, 0x42444646, }, + { 0, 2, 2, 0x000018d8, 0xffffffff, 0x46464646, }, + { 0, 2, 2, 0x000018dc, 0xffffffff, 0x42444646, }, + { 0, 2, 0, 0x0000183c, 0xffffffff, 0x46464646, }, + { 0, 2, 0, 0x00001840, 0xffffffff, 0x42444646, }, + { 0, 2, 0, 0x00001844, 0xffffffff, 0x46463840, }, + { 0, 2, 1, 0x00001848, 0xffffffff, 0x46464646, }, + { 0, 2, 1, 0x0000184c, 0xffffffff, 0x38404244, }, + { 0, 2, 2, 0x000018e0, 0xffffffff, 0x46464646, }, + { 0, 2, 2, 0x000018e4, 0xffffffff, 0x42444646, }, + { 0, 2, 2, 0x000018e8, 0x0000ffff, 0x38383840, }, + { 0, 3, 0, 0x00001a20, 0xffffffff, 0x48484848, }, + { 0, 3, 0, 0x00001a24, 0xffffffff, 0x46464646, }, + { 0, 3, 0, 0x00001a28, 0xffffffff, 0x44464646, }, + { 0, 3, 0, 0x00001a2c, 0xffffffff, 0x46464646, }, + { 0, 3, 0, 0x00001a30, 0xffffffff, 0x42444646, }, + { 0, 3, 1, 0x00001a34, 0xffffffff, 0x46464646, }, + { 0, 3, 1, 0x00001a38, 0xffffffff, 0x42444646, }, + { 0, 3, 2, 0x00001ad8, 0xffffffff, 0x46464646, }, + { 0, 3, 2, 0x00001adc, 0xffffffff, 0x42444646, }, + { 0, 3, 0, 0x00001a3c, 0xffffffff, 0x46464646, }, + { 0, 3, 0, 0x00001a40, 0xffffffff, 0x42444646, }, + { 0, 3, 0, 0x00001a44, 0xffffffff, 0x46463840, }, + { 0, 3, 1, 0x00001a48, 0xffffffff, 0x46464646, }, + { 0, 3, 1, 0x00001a4c, 0xffffffff, 0x38404244, }, + { 0, 3, 2, 0x00001ae0, 0xffffffff, 0x46464646, }, + { 0, 3, 2, 0x00001ae4, 0xffffffff, 0x42444646, }, + { 0, 3, 2, 0x00001ae8, 0x0000ffff, 0x38383840, }, + { 1, 0, 0, 0x00000c24, 0xffffffff, 0x46464646, }, + { 1, 0, 0, 0x00000c28, 0xffffffff, 0x44464646, }, + { 1, 0, 0, 0x00000c2c, 0xffffffff, 0x46464646, }, + { 1, 0, 0, 0x00000c30, 0xffffffff, 0x42444646, }, + { 1, 0, 1, 0x00000c34, 0xffffffff, 0x46464646, }, + { 1, 0, 1, 0x00000c38, 0xffffffff, 0x42444646, }, + { 1, 0, 2, 0x00000cd8, 0xffffffff, 0x46464646, }, + { 1, 0, 2, 0x00000cdc, 0xffffffff, 0x42444646, }, + { 1, 0, 0, 0x00000c3c, 0xffffffff, 0x46464646, }, + { 1, 0, 0, 0x00000c40, 0xffffffff, 0x42444646, }, + { 1, 0, 0, 0x00000c44, 0xffffffff, 0x46463840, }, + { 1, 0, 1, 0x00000c48, 0xffffffff, 0x46464646, }, + { 1, 0, 1, 0x00000c4c, 0xffffffff, 0x38404244, }, + { 1, 0, 2, 0x00000ce0, 0xffffffff, 0x46464646, }, + { 1, 0, 2, 0x00000ce4, 0xffffffff, 0x42444646, }, + { 1, 0, 2, 0x00000ce8, 0x0000ffff, 0x38383840, }, + { 1, 1, 0, 0x00000e24, 0xffffffff, 0x46464646, }, + { 1, 1, 0, 0x00000e28, 0xffffffff, 0x44464646, }, + { 1, 1, 0, 0x00000e2c, 0xffffffff, 0x46464646, }, + { 1, 1, 0, 0x00000e30, 0xffffffff, 0x42444646, }, + { 1, 1, 1, 0x00000e34, 0xffffffff, 0x46464646, }, + { 1, 1, 1, 0x00000e38, 0xffffffff, 0x42444646, }, + { 1, 1, 2, 0x00000ed8, 0xffffffff, 0x46464646, }, + { 1, 1, 2, 0x00000edc, 0xffffffff, 0x42444646, }, + { 1, 1, 0, 0x00000e3c, 0xffffffff, 0x46464646, }, + { 1, 1, 0, 0x00000e40, 0xffffffff, 0x42444646, }, + { 1, 1, 0, 0x00000e44, 0xffffffff, 0x46463840, }, + { 1, 1, 1, 0x00000e48, 0xffffffff, 0x46464646, }, + { 1, 1, 1, 0x00000e4c, 0xffffffff, 0x38404244, }, + { 1, 1, 2, 0x00000ee0, 0xffffffff, 0x46464646, }, + { 1, 1, 2, 0x00000ee4, 0xffffffff, 0x42444646, }, + { 1, 1, 2, 0x00000ee8, 0x0000ffff, 0x38383840, }, + { 1, 2, 0, 0x00001824, 0xffffffff, 0x46464646, }, + { 1, 2, 0, 0x00001828, 0xffffffff, 0x44464646, }, + { 1, 2, 0, 0x0000182c, 0xffffffff, 0x46464646, }, + { 1, 2, 0, 0x00001830, 0xffffffff, 0x42444646, }, + { 1, 2, 1, 0x00001834, 0xffffffff, 0x46464646, }, + { 1, 2, 1, 0x00001838, 0xffffffff, 0x42444646, }, + { 1, 2, 2, 0x000018d8, 0xffffffff, 0x46464646, }, + { 1, 2, 2, 0x000018dc, 0xffffffff, 0x42444646, }, + { 1, 2, 0, 0x0000183c, 0xffffffff, 0x46464646, }, + { 1, 2, 0, 0x00001840, 0xffffffff, 0x42444646, }, + { 1, 2, 0, 0x00001844, 0xffffffff, 0x46463840, }, + { 1, 2, 1, 0x00001848, 0xffffffff, 0x46464646, }, + { 1, 2, 1, 0x0000184c, 0xffffffff, 0x38404244, }, + { 1, 2, 2, 0x000018e0, 0xffffffff, 0x46464646, }, + { 1, 2, 2, 0x000018e4, 0xffffffff, 0x42444646, }, + { 1, 2, 2, 0x000018e8, 0x0000ffff, 0x38383840, }, + { 1, 3, 0, 0x00001a24, 0xffffffff, 0x46464646, }, + { 1, 3, 0, 0x00001a28, 0xffffffff, 0x44464646, }, + { 1, 3, 0, 0x00001a2c, 0xffffffff, 0x46464646, }, + { 1, 3, 0, 0x00001a30, 0xffffffff, 0x42444646, }, + { 1, 3, 1, 0x00001a34, 0xffffffff, 0x46464646, }, + { 1, 3, 1, 0x00001a38, 0xffffffff, 0x42444646, }, + { 1, 3, 2, 0x00001ad8, 0xffffffff, 0x46464646, }, + { 1, 3, 2, 0x00001adc, 0xffffffff, 0x42444646, }, + { 1, 3, 0, 0x00001a3c, 0xffffffff, 0x46464646, }, + { 1, 3, 0, 0x00001a40, 0xffffffff, 0x42444646, }, + { 1, 3, 0, 0x00001a44, 0xffffffff, 0x46463840, }, + { 1, 3, 1, 0x00001a48, 0xffffffff, 0x46464646, }, + { 1, 3, 1, 0x00001a4c, 0xffffffff, 0x38404244, }, + { 1, 3, 2, 0x00001ae0, 0xffffffff, 0x46464646, }, + { 1, 3, 2, 0x00001ae4, 0xffffffff, 0x42444646, }, + { 1, 3, 2, 0x00001ae8, 0x0000ffff, 0x38383840, }, +}; + +RTW_DECL_TABLE_BB_PG(rtw8814a_bb_pg_type3); + +static const struct rtw_phy_pg_cfg_pair rtw8814a_bb_pg_type4[] = { + { 0, 0, 0, 0x00000c20, 0xffffffff, 0x42424242, }, + { 0, 0, 0, 0x00000c24, 0xffffffff, 0x42424242, }, + { 0, 0, 0, 0x00000c28, 0xffffffff, 0x36384042, }, + { 0, 0, 0, 0x00000c2c, 0xffffffff, 0x42424242, }, + { 0, 0, 0, 0x00000c30, 0xffffffff, 0x34363840, }, + { 0, 0, 1, 0x00000c34, 0xffffffff, 0x42424242, }, + { 0, 0, 1, 0x00000c38, 0xffffffff, 0x34363840, }, + { 0, 0, 2, 0x00000cd8, 0xffffffff, 0x42424242, }, + { 0, 0, 2, 0x00000cdc, 0xffffffff, 0x34363840, }, + { 0, 0, 0, 0x00000c3c, 0xffffffff, 0x42424242, }, + { 0, 0, 0, 0x00000c40, 0xffffffff, 0x34363840, }, + { 0, 0, 0, 0x00000c44, 0xffffffff, 0x42423032, }, + { 0, 0, 1, 0x00000c48, 0xffffffff, 0x38404242, }, + { 0, 0, 1, 0x00000c4c, 0xffffffff, 0x30323436, }, + { 0, 0, 2, 0x00000ce0, 0xffffffff, 0x42424242, }, + { 0, 0, 2, 0x00000ce4, 0xffffffff, 0x34363840, }, + { 0, 0, 2, 0x00000ce8, 0x0000ffff, 0x30303032, }, + { 0, 1, 0, 0x00000e20, 0xffffffff, 0x42424242, }, + { 0, 1, 0, 0x00000e24, 0xffffffff, 0x42424242, }, + { 0, 1, 0, 0x00000e28, 0xffffffff, 0x36384042, }, + { 0, 1, 0, 0x00000e2c, 0xffffffff, 0x42424242, }, + { 0, 1, 0, 0x00000e30, 0xffffffff, 0x34363840, }, + { 0, 1, 1, 0x00000e34, 0xffffffff, 0x42424242, }, + { 0, 1, 1, 0x00000e38, 0xffffffff, 0x34363840, }, + { 0, 1, 2, 0x00000ed8, 0xffffffff, 0x42424242, }, + { 0, 1, 2, 0x00000edc, 0xffffffff, 0x34363840, }, + { 0, 1, 0, 0x00000e3c, 0xffffffff, 0x42424242, }, + { 0, 1, 0, 0x00000e40, 0xffffffff, 0x34363840, }, + { 0, 1, 0, 0x00000e44, 0xffffffff, 0x42423032, }, + { 0, 1, 1, 0x00000e48, 0xffffffff, 0x38404242, }, + { 0, 1, 1, 0x00000e4c, 0xffffffff, 0x30323436, }, + { 0, 1, 2, 0x00000ee0, 0xffffffff, 0x42424242, }, + { 0, 1, 2, 0x00000ee4, 0xffffffff, 0x34363840, }, + { 0, 1, 2, 0x00000ee8, 0x0000ffff, 0x30303032, }, + { 0, 2, 0, 0x00001820, 0xffffffff, 0x42424242, }, + { 0, 2, 0, 0x00001824, 0xffffffff, 0x42424242, }, + { 0, 2, 0, 0x00001828, 0xffffffff, 0x36384042, }, + { 0, 2, 0, 0x0000182c, 0xffffffff, 0x42424242, }, + { 0, 2, 0, 0x00001830, 0xffffffff, 0x34363840, }, + { 0, 2, 1, 0x00001834, 0xffffffff, 0x42424242, }, + { 0, 2, 1, 0x00001838, 0xffffffff, 0x34363840, }, + { 0, 2, 2, 0x000018d8, 0xffffffff, 0x42424242, }, + { 0, 2, 2, 0x000018dc, 0xffffffff, 0x34363840, }, + { 0, 2, 0, 0x0000183c, 0xffffffff, 0x42424242, }, + { 0, 2, 0, 0x00001840, 0xffffffff, 0x34363840, }, + { 0, 2, 0, 0x00001844, 0xffffffff, 0x42423032, }, + { 0, 2, 1, 0x00001848, 0xffffffff, 0x38404242, }, + { 0, 2, 1, 0x0000184c, 0xffffffff, 0x30323436, }, + { 0, 2, 2, 0x000018e0, 0xffffffff, 0x42424242, }, + { 0, 2, 2, 0x000018e4, 0xffffffff, 0x34363840, }, + { 0, 2, 2, 0x000018e8, 0x0000ffff, 0x30303032, }, + { 0, 3, 0, 0x00001a20, 0xffffffff, 0x42424242, }, + { 0, 3, 0, 0x00001a24, 0xffffffff, 0x42424242, }, + { 0, 3, 0, 0x00001a28, 0xffffffff, 0x36384042, }, + { 0, 3, 0, 0x00001a2c, 0xffffffff, 0x42424242, }, + { 0, 3, 0, 0x00001a30, 0xffffffff, 0x34363840, }, + { 0, 3, 1, 0x00001a34, 0xffffffff, 0x42424242, }, + { 0, 3, 1, 0x00001a38, 0xffffffff, 0x34363840, }, + { 0, 3, 2, 0x00001ad8, 0xffffffff, 0x42424242, }, + { 0, 3, 2, 0x00001adc, 0xffffffff, 0x34363840, }, + { 0, 3, 0, 0x00001a3c, 0xffffffff, 0x42424242, }, + { 0, 3, 0, 0x00001a40, 0xffffffff, 0x34363840, }, + { 0, 3, 0, 0x00001a44, 0xffffffff, 0x42423032, }, + { 0, 3, 1, 0x00001a48, 0xffffffff, 0x38404242, }, + { 0, 3, 1, 0x00001a4c, 0xffffffff, 0x30323436, }, + { 0, 3, 2, 0x00001ae0, 0xffffffff, 0x42424242, }, + { 0, 3, 2, 0x00001ae4, 0xffffffff, 0x34363840, }, + { 0, 3, 2, 0x00001ae8, 0x0000ffff, 0x30303032, }, + { 1, 0, 0, 0x00000c24, 0xffffffff, 0x42424242, }, + { 1, 0, 0, 0x00000c28, 0xffffffff, 0x36384042, }, + { 1, 0, 0, 0x00000c2c, 0xffffffff, 0x42424242, }, + { 1, 0, 0, 0x00000c30, 0xffffffff, 0x34363840, }, + { 1, 0, 1, 0x00000c34, 0xffffffff, 0x42424242, }, + { 1, 0, 1, 0x00000c38, 0xffffffff, 0x34363840, }, + { 1, 0, 2, 0x00000cd8, 0xffffffff, 0x42424242, }, + { 1, 0, 2, 0x00000cdc, 0xffffffff, 0x34363840, }, + { 1, 0, 0, 0x00000c3c, 0xffffffff, 0x42424242, }, + { 1, 0, 0, 0x00000c40, 0xffffffff, 0x34363840, }, + { 1, 0, 0, 0x00000c44, 0xffffffff, 0x42423032, }, + { 1, 0, 1, 0x00000c48, 0xffffffff, 0x38404242, }, + { 1, 0, 1, 0x00000c4c, 0xffffffff, 0x30323436, }, + { 1, 0, 2, 0x00000ce0, 0xffffffff, 0x42424242, }, + { 1, 0, 2, 0x00000ce4, 0xffffffff, 0x34363840, }, + { 1, 0, 2, 0x00000ce8, 0x0000ffff, 0x30303032, }, + { 1, 1, 0, 0x00000e24, 0xffffffff, 0x42424242, }, + { 1, 1, 0, 0x00000e28, 0xffffffff, 0x36384042, }, + { 1, 1, 0, 0x00000e2c, 0xffffffff, 0x42424242, }, + { 1, 1, 0, 0x00000e30, 0xffffffff, 0x34363840, }, + { 1, 1, 1, 0x00000e34, 0xffffffff, 0x42424242, }, + { 1, 1, 1, 0x00000e38, 0xffffffff, 0x34363840, }, + { 1, 1, 2, 0x00000ed8, 0xffffffff, 0x42424242, }, + { 1, 1, 2, 0x00000edc, 0xffffffff, 0x34363840, }, + { 1, 1, 0, 0x00000e3c, 0xffffffff, 0x42424242, }, + { 1, 1, 0, 0x00000e40, 0xffffffff, 0x34363840, }, + { 1, 1, 0, 0x00000e44, 0xffffffff, 0x42423032, }, + { 1, 1, 1, 0x00000e48, 0xffffffff, 0x38404242, }, + { 1, 1, 1, 0x00000e4c, 0xffffffff, 0x30323436, }, + { 1, 1, 2, 0x00000ee0, 0xffffffff, 0x42424242, }, + { 1, 1, 2, 0x00000ee4, 0xffffffff, 0x34363840, }, + { 1, 1, 2, 0x00000ee8, 0x0000ffff, 0x30303032, }, + { 1, 2, 0, 0x00001824, 0xffffffff, 0x42424242, }, + { 1, 2, 0, 0x00001828, 0xffffffff, 0x36384042, }, + { 1, 2, 0, 0x0000182c, 0xffffffff, 0x42424242, }, + { 1, 2, 0, 0x00001830, 0xffffffff, 0x34363840, }, + { 1, 2, 1, 0x00001834, 0xffffffff, 0x42424242, }, + { 1, 2, 1, 0x00001838, 0xffffffff, 0x34363840, }, + { 1, 2, 2, 0x000018d8, 0xffffffff, 0x42424242, }, + { 1, 2, 2, 0x000018dc, 0xffffffff, 0x34363840, }, + { 1, 2, 0, 0x0000183c, 0xffffffff, 0x42424242, }, + { 1, 2, 0, 0x00001840, 0xffffffff, 0x34363840, }, + { 1, 2, 0, 0x00001844, 0xffffffff, 0x42423032, }, + { 1, 2, 1, 0x00001848, 0xffffffff, 0x38404242, }, + { 1, 2, 1, 0x0000184c, 0xffffffff, 0x30323436, }, + { 1, 2, 2, 0x000018e0, 0xffffffff, 0x42424242, }, + { 1, 2, 2, 0x000018e4, 0xffffffff, 0x34363840, }, + { 1, 2, 2, 0x000018e8, 0x0000ffff, 0x30303032, }, + { 1, 3, 0, 0x00001a24, 0xffffffff, 0x42424242, }, + { 1, 3, 0, 0x00001a28, 0xffffffff, 0x36384042, }, + { 1, 3, 0, 0x00001a2c, 0xffffffff, 0x42424242, }, + { 1, 3, 0, 0x00001a30, 0xffffffff, 0x34363840, }, + { 1, 3, 1, 0x00001a34, 0xffffffff, 0x42424242, }, + { 1, 3, 1, 0x00001a38, 0xffffffff, 0x34363840, }, + { 1, 3, 2, 0x00001ad8, 0xffffffff, 0x42424242, }, + { 1, 3, 2, 0x00001adc, 0xffffffff, 0x34363840, }, + { 1, 3, 0, 0x00001a3c, 0xffffffff, 0x42424242, }, + { 1, 3, 0, 0x00001a40, 0xffffffff, 0x34363840, }, + { 1, 3, 0, 0x00001a44, 0xffffffff, 0x42423032, }, + { 1, 3, 1, 0x00001a48, 0xffffffff, 0x38404242, }, + { 1, 3, 1, 0x00001a4c, 0xffffffff, 0x30323436, }, + { 1, 3, 2, 0x00001ae0, 0xffffffff, 0x42424242, }, + { 1, 3, 2, 0x00001ae4, 0xffffffff, 0x34363840, }, + { 1, 3, 2, 0x00001ae8, 0x0000ffff, 0x30303032, }, +}; + +RTW_DECL_TABLE_BB_PG(rtw8814a_bb_pg_type4); + +static const struct rtw_phy_pg_cfg_pair rtw8814a_bb_pg_type5[] = { + { 0, 0, 0, 0x00000c20, 0xffffffff, 0x48484848, }, + { 0, 0, 0, 0x00000c24, 0xffffffff, 0x46464646, }, + { 0, 0, 0, 0x00000c28, 0xffffffff, 0x44464646, }, + { 0, 0, 0, 0x00000c2c, 0xffffffff, 0x46464646, }, + { 0, 0, 0, 0x00000c30, 0xffffffff, 0x42444646, }, + { 0, 0, 1, 0x00000c34, 0xffffffff, 0x44444444, }, + { 0, 0, 1, 0x00000c38, 0xffffffff, 0x40424444, }, + { 0, 0, 2, 0x00000cd8, 0xffffffff, 0x42424242, }, + { 0, 0, 2, 0x00000cdc, 0xffffffff, 0x38404242, }, + { 0, 0, 0, 0x00000c3c, 0xffffffff, 0x46464646, }, + { 0, 0, 0, 0x00000c40, 0xffffffff, 0x42444646, }, + { 0, 0, 0, 0x00000c44, 0xffffffff, 0x44444040, }, + { 0, 0, 1, 0x00000c48, 0xffffffff, 0x44444444, }, + { 0, 0, 1, 0x00000c4c, 0xffffffff, 0x38384042, }, + { 0, 0, 2, 0x00000ce0, 0xffffffff, 0x42424242, }, + { 0, 0, 2, 0x00000ce4, 0xffffffff, 0x38404242, }, + { 0, 0, 2, 0x00000ce8, 0x0000ffff, 0x20203636, }, + { 0, 1, 0, 0x00000e20, 0xffffffff, 0x48484848, }, + { 0, 1, 0, 0x00000e24, 0xffffffff, 0x46464646, }, + { 0, 1, 0, 0x00000e28, 0xffffffff, 0x44464646, }, + { 0, 1, 0, 0x00000e2c, 0xffffffff, 0x46464646, }, + { 0, 1, 0, 0x00000e30, 0xffffffff, 0x42444646, }, + { 0, 1, 1, 0x00000e34, 0xffffffff, 0x44444444, }, + { 0, 1, 1, 0x00000e38, 0xffffffff, 0x40424444, }, + { 0, 1, 2, 0x00000ed8, 0xffffffff, 0x42424242, }, + { 0, 1, 2, 0x00000edc, 0xffffffff, 0x38404242, }, + { 0, 1, 0, 0x00000e3c, 0xffffffff, 0x46464646, }, + { 0, 1, 0, 0x00000e40, 0xffffffff, 0x42444646, }, + { 0, 1, 0, 0x00000e44, 0xffffffff, 0x44444040, }, + { 0, 1, 1, 0x00000e48, 0xffffffff, 0x44444444, }, + { 0, 1, 1, 0x00000e4c, 0xffffffff, 0x38384042, }, + { 0, 1, 2, 0x00000ee0, 0xffffffff, 0x42424242, }, + { 0, 1, 2, 0x00000ee4, 0xffffffff, 0x38404242, }, + { 0, 1, 2, 0x00000ee8, 0x0000ffff, 0x20203636, }, + { 0, 2, 0, 0x00001820, 0xffffffff, 0x48484848, }, + { 0, 2, 0, 0x00001824, 0xffffffff, 0x46464646, }, + { 0, 2, 0, 0x00001828, 0xffffffff, 0x44464646, }, + { 0, 2, 0, 0x0000182c, 0xffffffff, 0x46464646, }, + { 0, 2, 0, 0x00001830, 0xffffffff, 0x42444646, }, + { 0, 2, 1, 0x00001834, 0xffffffff, 0x44444444, }, + { 0, 2, 1, 0x00001838, 0xffffffff, 0x40424444, }, + { 0, 2, 2, 0x000018d8, 0xffffffff, 0x42424242, }, + { 0, 2, 2, 0x000018dc, 0xffffffff, 0x38404242, }, + { 0, 2, 0, 0x0000183c, 0xffffffff, 0x46464646, }, + { 0, 2, 0, 0x00001840, 0xffffffff, 0x42444646, }, + { 0, 2, 0, 0x00001844, 0xffffffff, 0x44444040, }, + { 0, 2, 1, 0x00001848, 0xffffffff, 0x44444444, }, + { 0, 2, 1, 0x0000184c, 0xffffffff, 0x38384042, }, + { 0, 2, 2, 0x000018e0, 0xffffffff, 0x42424242, }, + { 0, 2, 2, 0x000018e4, 0xffffffff, 0x38404242, }, + { 0, 2, 2, 0x000018e8, 0x0000ffff, 0x20203636, }, + { 0, 3, 0, 0x00001a20, 0xffffffff, 0x48484848, }, + { 0, 3, 0, 0x00001a24, 0xffffffff, 0x46464646, }, + { 0, 3, 0, 0x00001a28, 0xffffffff, 0x44464646, }, + { 0, 3, 0, 0x00001a2c, 0xffffffff, 0x46464646, }, + { 0, 3, 0, 0x00001a30, 0xffffffff, 0x42444646, }, + { 0, 3, 1, 0x00001a34, 0xffffffff, 0x44444444, }, + { 0, 3, 1, 0x00001a38, 0xffffffff, 0x40424444, }, + { 0, 3, 2, 0x00001ad8, 0xffffffff, 0x42424242, }, + { 0, 3, 2, 0x00001adc, 0xffffffff, 0x38404242, }, + { 0, 3, 0, 0x00001a3c, 0xffffffff, 0x46464646, }, + { 0, 3, 0, 0x00001a40, 0xffffffff, 0x42444646, }, + { 0, 3, 0, 0x00001a44, 0xffffffff, 0x44444040, }, + { 0, 3, 1, 0x00001a48, 0xffffffff, 0x44444444, }, + { 0, 3, 1, 0x00001a4c, 0xffffffff, 0x38384042, }, + { 0, 3, 2, 0x00001ae0, 0xffffffff, 0x42424242, }, + { 0, 3, 2, 0x00001ae4, 0xffffffff, 0x38404242, }, + { 0, 3, 2, 0x00001ae8, 0x0000ffff, 0x20203636, }, + { 1, 0, 0, 0x00000c24, 0xffffffff, 0x46464646, }, + { 1, 0, 0, 0x00000c28, 0xffffffff, 0x44464646, }, + { 1, 0, 0, 0x00000c2c, 0xffffffff, 0x46464646, }, + { 1, 0, 0, 0x00000c30, 0xffffffff, 0x42444646, }, + { 1, 0, 1, 0x00000c34, 0xffffffff, 0x44444444, }, + { 1, 0, 1, 0x00000c38, 0xffffffff, 0x40424444, }, + { 1, 0, 2, 0x00000cd8, 0xffffffff, 0x42424242, }, + { 1, 0, 2, 0x00000cdc, 0xffffffff, 0x38404242, }, + { 1, 0, 0, 0x00000c3c, 0xffffffff, 0x46464646, }, + { 1, 0, 0, 0x00000c40, 0xffffffff, 0x42444646, }, + { 1, 0, 0, 0x00000c44, 0xffffffff, 0x44443840, }, + { 1, 0, 1, 0x00000c48, 0xffffffff, 0x44444444, }, + { 1, 0, 1, 0x00000c4c, 0xffffffff, 0x36384042, }, + { 1, 0, 2, 0x00000ce0, 0xffffffff, 0x42424242, }, + { 1, 0, 2, 0x00000ce4, 0xffffffff, 0x38404242, }, + { 1, 0, 2, 0x00000ce8, 0x0000ffff, 0x20203436, }, + { 1, 1, 0, 0x00000e24, 0xffffffff, 0x46464646, }, + { 1, 1, 0, 0x00000e28, 0xffffffff, 0x44464646, }, + { 1, 1, 0, 0x00000e2c, 0xffffffff, 0x46464646, }, + { 1, 1, 0, 0x00000e30, 0xffffffff, 0x42444646, }, + { 1, 1, 1, 0x00000e34, 0xffffffff, 0x44444444, }, + { 1, 1, 1, 0x00000e38, 0xffffffff, 0x40424444, }, + { 1, 1, 2, 0x00000ed8, 0xffffffff, 0x42424242, }, + { 1, 1, 2, 0x00000edc, 0xffffffff, 0x38404242, }, + { 1, 1, 0, 0x00000e3c, 0xffffffff, 0x46464646, }, + { 1, 1, 0, 0x00000e40, 0xffffffff, 0x42444646, }, + { 1, 1, 0, 0x00000e44, 0xffffffff, 0x44443840, }, + { 1, 1, 1, 0x00000e48, 0xffffffff, 0x44444444, }, + { 1, 1, 1, 0x00000e4c, 0xffffffff, 0x36384042, }, + { 1, 1, 2, 0x00000ee0, 0xffffffff, 0x42424242, }, + { 1, 1, 2, 0x00000ee4, 0xffffffff, 0x38404242, }, + { 1, 1, 2, 0x00000ee8, 0x0000ffff, 0x20203436, }, + { 1, 2, 0, 0x00001824, 0xffffffff, 0x46464646, }, + { 1, 2, 0, 0x00001828, 0xffffffff, 0x44464646, }, + { 1, 2, 0, 0x0000182c, 0xffffffff, 0x46464646, }, + { 1, 2, 0, 0x00001830, 0xffffffff, 0x42444646, }, + { 1, 2, 1, 0x00001834, 0xffffffff, 0x44444444, }, + { 1, 2, 1, 0x00001838, 0xffffffff, 0x40424444, }, + { 1, 2, 2, 0x000018d8, 0xffffffff, 0x42424242, }, + { 1, 2, 2, 0x000018dc, 0xffffffff, 0x38404242, }, + { 1, 2, 0, 0x0000183c, 0xffffffff, 0x46464646, }, + { 1, 2, 0, 0x00001840, 0xffffffff, 0x42444646, }, + { 1, 2, 0, 0x00001844, 0xffffffff, 0x44443840, }, + { 1, 2, 1, 0x00001848, 0xffffffff, 0x44444444, }, + { 1, 2, 1, 0x0000184c, 0xffffffff, 0x36384042, }, + { 1, 2, 2, 0x000018e0, 0xffffffff, 0x42424242, }, + { 1, 2, 2, 0x000018e4, 0xffffffff, 0x38404242, }, + { 1, 2, 2, 0x000018e8, 0x0000ffff, 0x20203436, }, + { 1, 3, 0, 0x00001a24, 0xffffffff, 0x46464646, }, + { 1, 3, 0, 0x00001a28, 0xffffffff, 0x44464646, }, + { 1, 3, 0, 0x00001a2c, 0xffffffff, 0x46464646, }, + { 1, 3, 0, 0x00001a30, 0xffffffff, 0x42444646, }, + { 1, 3, 1, 0x00001a34, 0xffffffff, 0x44444444, }, + { 1, 3, 1, 0x00001a38, 0xffffffff, 0x40424444, }, + { 1, 3, 2, 0x00001ad8, 0xffffffff, 0x42424242, }, + { 1, 3, 2, 0x00001adc, 0xffffffff, 0x38404242, }, + { 1, 3, 0, 0x00001a3c, 0xffffffff, 0x46464646, }, + { 1, 3, 0, 0x00001a40, 0xffffffff, 0x42444646, }, + { 1, 3, 0, 0x00001a44, 0xffffffff, 0x44443840, }, + { 1, 3, 1, 0x00001a48, 0xffffffff, 0x44444444, }, + { 1, 3, 1, 0x00001a4c, 0xffffffff, 0x36384042, }, + { 1, 3, 2, 0x00001ae0, 0xffffffff, 0x42424242, }, + { 1, 3, 2, 0x00001ae4, 0xffffffff, 0x38404242, }, + { 1, 3, 2, 0x00001ae8, 0x0000ffff, 0x20203436, }, +}; + +RTW_DECL_TABLE_BB_PG(rtw8814a_bb_pg_type5); + +static const struct rtw_phy_pg_cfg_pair rtw8814a_bb_pg_type7[] = { + { 0, 0, 0, 0x00000c20, 0xffffffff, 0x34343434, }, + { 0, 0, 0, 0x00000c24, 0xffffffff, 0x34343434, }, + { 0, 0, 0, 0x00000c28, 0xffffffff, 0x30323434, }, + { 0, 0, 0, 0x00000c2c, 0xffffffff, 0x34343434, }, + { 0, 0, 0, 0x00000c30, 0xffffffff, 0x28303234, }, + { 0, 0, 1, 0x00000c34, 0xffffffff, 0x34343434, }, + { 0, 0, 1, 0x00000c38, 0xffffffff, 0x28303234, }, + { 0, 0, 2, 0x00000cd8, 0xffffffff, 0x34343434, }, + { 0, 0, 2, 0x00000cdc, 0xffffffff, 0x28303234, }, + { 0, 0, 0, 0x00000c3c, 0xffffffff, 0x34343434, }, + { 0, 0, 0, 0x00000c40, 0xffffffff, 0x28303234, }, + { 0, 0, 0, 0x00000c44, 0xffffffff, 0x34342426, }, + { 0, 0, 1, 0x00000c48, 0xffffffff, 0x32343434, }, + { 0, 0, 1, 0x00000c4c, 0xffffffff, 0x24262830, }, + { 0, 0, 2, 0x00000ce0, 0xffffffff, 0x34343434, }, + { 0, 0, 2, 0x00000ce4, 0xffffffff, 0x28303234, }, + { 0, 0, 2, 0x00000ce8, 0x0000ffff, 0x24263434, }, + { 0, 1, 0, 0x00000e20, 0xffffffff, 0x34343434, }, + { 0, 1, 0, 0x00000e24, 0xffffffff, 0x34343434, }, + { 0, 1, 0, 0x00000e28, 0xffffffff, 0x30323434, }, + { 0, 1, 0, 0x00000e2c, 0xffffffff, 0x34343434, }, + { 0, 1, 0, 0x00000e30, 0xffffffff, 0x28303234, }, + { 0, 1, 1, 0x00000e34, 0xffffffff, 0x34343434, }, + { 0, 1, 1, 0x00000e38, 0xffffffff, 0x28303234, }, + { 0, 1, 2, 0x00000ed8, 0xffffffff, 0x34343434, }, + { 0, 1, 2, 0x00000edc, 0xffffffff, 0x28303234, }, + { 0, 1, 0, 0x00000e3c, 0xffffffff, 0x34343434, }, + { 0, 1, 0, 0x00000e40, 0xffffffff, 0x28303234, }, + { 0, 1, 0, 0x00000e44, 0xffffffff, 0x34342426, }, + { 0, 1, 1, 0x00000e48, 0xffffffff, 0x32343434, }, + { 0, 1, 1, 0x00000e4c, 0xffffffff, 0x24262830, }, + { 0, 1, 2, 0x00000ee0, 0xffffffff, 0x34343434, }, + { 0, 1, 2, 0x00000ee4, 0xffffffff, 0x28303234, }, + { 0, 1, 2, 0x00000ee8, 0x0000ffff, 0x24263434, }, + { 0, 2, 0, 0x00001820, 0xffffffff, 0x34343434, }, + { 0, 2, 0, 0x00001824, 0xffffffff, 0x34343434, }, + { 0, 2, 0, 0x00001828, 0xffffffff, 0x30323434, }, + { 0, 2, 0, 0x0000182c, 0xffffffff, 0x34343434, }, + { 0, 2, 0, 0x00001830, 0xffffffff, 0x28303234, }, + { 0, 2, 1, 0x00001834, 0xffffffff, 0x34343434, }, + { 0, 2, 1, 0x00001838, 0xffffffff, 0x28303234, }, + { 0, 2, 2, 0x000018d8, 0xffffffff, 0x34343434, }, + { 0, 2, 2, 0x000018dc, 0xffffffff, 0x28303234, }, + { 0, 2, 0, 0x0000183c, 0xffffffff, 0x34343434, }, + { 0, 2, 0, 0x00001840, 0xffffffff, 0x28303234, }, + { 0, 2, 0, 0x00001844, 0xffffffff, 0x34342426, }, + { 0, 2, 1, 0x00001848, 0xffffffff, 0x32343434, }, + { 0, 2, 1, 0x0000184c, 0xffffffff, 0x24262830, }, + { 0, 2, 2, 0x000018e0, 0xffffffff, 0x34343434, }, + { 0, 2, 2, 0x000018e4, 0xffffffff, 0x28303234, }, + { 0, 2, 2, 0x000018e8, 0x0000ffff, 0x24263434, }, + { 0, 3, 0, 0x00001a20, 0xffffffff, 0x34343434, }, + { 0, 3, 0, 0x00001a24, 0xffffffff, 0x34343434, }, + { 0, 3, 0, 0x00001a28, 0xffffffff, 0x30323434, }, + { 0, 3, 0, 0x00001a2c, 0xffffffff, 0x34343434, }, + { 0, 3, 0, 0x00001a30, 0xffffffff, 0x28303234, }, + { 0, 3, 1, 0x00001a34, 0xffffffff, 0x34343434, }, + { 0, 3, 1, 0x00001a38, 0xffffffff, 0x28303234, }, + { 0, 3, 2, 0x00001ad8, 0xffffffff, 0x34343434, }, + { 0, 3, 2, 0x00001adc, 0xffffffff, 0x28303234, }, + { 0, 3, 0, 0x00001a3c, 0xffffffff, 0x34343434, }, + { 0, 3, 0, 0x00001a40, 0xffffffff, 0x28303234, }, + { 0, 3, 0, 0x00001a44, 0xffffffff, 0x34342426, }, + { 0, 3, 1, 0x00001a48, 0xffffffff, 0x32343434, }, + { 0, 3, 1, 0x00001a4c, 0xffffffff, 0x24262830, }, + { 0, 3, 2, 0x00001ae0, 0xffffffff, 0x34343434, }, + { 0, 3, 2, 0x00001ae4, 0xffffffff, 0x28303234, }, + { 0, 3, 2, 0x00001ae8, 0x0000ffff, 0x24263434, }, + { 1, 0, 0, 0x00000c24, 0xffffffff, 0x34343434, }, + { 1, 0, 0, 0x00000c28, 0xffffffff, 0x30323434, }, + { 1, 0, 0, 0x00000c2c, 0xffffffff, 0x34343434, }, + { 1, 0, 0, 0x00000c30, 0xffffffff, 0x28303234, }, + { 1, 0, 1, 0x00000c34, 0xffffffff, 0x34343434, }, + { 1, 0, 1, 0x00000c38, 0xffffffff, 0x28303234, }, + { 1, 0, 2, 0x00000cd8, 0xffffffff, 0x34343434, }, + { 1, 0, 2, 0x00000cdc, 0xffffffff, 0x28303234, }, + { 1, 0, 0, 0x00000c3c, 0xffffffff, 0x34343434, }, + { 1, 0, 0, 0x00000c40, 0xffffffff, 0x28303234, }, + { 1, 0, 0, 0x00000c44, 0xffffffff, 0x34342426, }, + { 1, 0, 1, 0x00000c48, 0xffffffff, 0x32343434, }, + { 1, 0, 1, 0x00000c4c, 0xffffffff, 0x24262830, }, + { 1, 0, 2, 0x00000ce0, 0xffffffff, 0x34343434, }, + { 1, 0, 2, 0x00000ce4, 0xffffffff, 0x28303234, }, + { 1, 0, 2, 0x00000ce8, 0x0000ffff, 0x24263434, }, + { 1, 1, 0, 0x00000e24, 0xffffffff, 0x34343434, }, + { 1, 1, 0, 0x00000e28, 0xffffffff, 0x30323434, }, + { 1, 1, 0, 0x00000e2c, 0xffffffff, 0x34343434, }, + { 1, 1, 0, 0x00000e30, 0xffffffff, 0x28303234, }, + { 1, 1, 1, 0x00000e34, 0xffffffff, 0x34343434, }, + { 1, 1, 1, 0x00000e38, 0xffffffff, 0x28303234, }, + { 1, 1, 2, 0x00000ed8, 0xffffffff, 0x34343434, }, + { 1, 1, 2, 0x00000edc, 0xffffffff, 0x28303234, }, + { 1, 1, 0, 0x00000e3c, 0xffffffff, 0x34343434, }, + { 1, 1, 0, 0x00000e40, 0xffffffff, 0x28303234, }, + { 1, 1, 0, 0x00000e44, 0xffffffff, 0x34342426, }, + { 1, 1, 1, 0x00000e48, 0xffffffff, 0x32343434, }, + { 1, 1, 1, 0x00000e4c, 0xffffffff, 0x24262830, }, + { 1, 1, 2, 0x00000ee0, 0xffffffff, 0x34343434, }, + { 1, 1, 2, 0x00000ee4, 0xffffffff, 0x28303234, }, + { 1, 1, 2, 0x00000ee8, 0x0000ffff, 0x24263434, }, + { 1, 2, 0, 0x00001824, 0xffffffff, 0x34343434, }, + { 1, 2, 0, 0x00001828, 0xffffffff, 0x30323434, }, + { 1, 2, 0, 0x0000182c, 0xffffffff, 0x34343434, }, + { 1, 2, 0, 0x00001830, 0xffffffff, 0x28303234, }, + { 1, 2, 1, 0x00001834, 0xffffffff, 0x34343434, }, + { 1, 2, 1, 0x00001838, 0xffffffff, 0x28303234, }, + { 1, 2, 2, 0x000018d8, 0xffffffff, 0x34343434, }, + { 1, 2, 2, 0x000018dc, 0xffffffff, 0x28303234, }, + { 1, 2, 0, 0x0000183c, 0xffffffff, 0x34343434, }, + { 1, 2, 0, 0x00001840, 0xffffffff, 0x28303234, }, + { 1, 2, 0, 0x00001844, 0xffffffff, 0x34342426, }, + { 1, 2, 1, 0x00001848, 0xffffffff, 0x32343434, }, + { 1, 2, 1, 0x0000184c, 0xffffffff, 0x24262830, }, + { 1, 2, 2, 0x000018e0, 0xffffffff, 0x34343434, }, + { 1, 2, 2, 0x000018e4, 0xffffffff, 0x28303234, }, + { 1, 2, 2, 0x000018e8, 0x0000ffff, 0x24263434, }, + { 1, 3, 0, 0x00001a24, 0xffffffff, 0x34343434, }, + { 1, 3, 0, 0x00001a28, 0xffffffff, 0x30323434, }, + { 1, 3, 0, 0x00001a2c, 0xffffffff, 0x34343434, }, + { 1, 3, 0, 0x00001a30, 0xffffffff, 0x28303234, }, + { 1, 3, 1, 0x00001a34, 0xffffffff, 0x34343434, }, + { 1, 3, 1, 0x00001a38, 0xffffffff, 0x28303234, }, + { 1, 3, 2, 0x00001ad8, 0xffffffff, 0x34343434, }, + { 1, 3, 2, 0x00001adc, 0xffffffff, 0x28303234, }, + { 1, 3, 0, 0x00001a3c, 0xffffffff, 0x34343434, }, + { 1, 3, 0, 0x00001a40, 0xffffffff, 0x28303234, }, + { 1, 3, 0, 0x00001a44, 0xffffffff, 0x34342426, }, + { 1, 3, 1, 0x00001a48, 0xffffffff, 0x32343434, }, + { 1, 3, 1, 0x00001a4c, 0xffffffff, 0x24262830, }, + { 1, 3, 2, 0x00001ae0, 0xffffffff, 0x34343434, }, + { 1, 3, 2, 0x00001ae4, 0xffffffff, 0x28303234, }, + { 1, 3, 2, 0x00001ae8, 0x0000ffff, 0x24263434, }, +}; + +RTW_DECL_TABLE_BB_PG(rtw8814a_bb_pg_type7); + +static const struct rtw_phy_pg_cfg_pair rtw8814a_bb_pg_type8[] = { + { 0, 0, 0, 0x00000c20, 0xffffffff, 0x43434343, }, + { 0, 0, 0, 0x00000c24, 0xffffffff, 0x43434343, }, + { 0, 0, 0, 0x00000c28, 0xffffffff, 0x35373941, }, + { 0, 0, 0, 0x00000c2c, 0xffffffff, 0x43434343, }, + { 0, 0, 0, 0x00000c30, 0xffffffff, 0x33353739, }, + { 0, 0, 1, 0x00000c34, 0xffffffff, 0x43434343, }, + { 0, 0, 1, 0x00000c38, 0xffffffff, 0x31333537, }, + { 0, 0, 2, 0x00000cd8, 0xffffffff, 0x43434343, }, + { 0, 0, 2, 0x00000cdc, 0xffffffff, 0x29313335, }, + { 0, 0, 0, 0x00000c3c, 0xffffffff, 0x34343434, }, + { 0, 0, 0, 0x00000c40, 0xffffffff, 0x28303234, }, + { 0, 0, 0, 0x00000c44, 0xffffffff, 0x32322426, }, + { 0, 0, 1, 0x00000c48, 0xffffffff, 0x30323232, }, + { 0, 0, 1, 0x00000c4c, 0xffffffff, 0x22242628, }, + { 0, 0, 2, 0x00000ce0, 0xffffffff, 0x30303030, }, + { 0, 0, 2, 0x00000ce4, 0xffffffff, 0x24262830, }, + { 0, 0, 2, 0x00000ce8, 0x0000ffff, 0x20222222, }, + { 0, 1, 0, 0x00000e20, 0xffffffff, 0x43434343, }, + { 0, 1, 0, 0x00000e24, 0xffffffff, 0x43434343, }, + { 0, 1, 0, 0x00000e28, 0xffffffff, 0x35373941, }, + { 0, 1, 0, 0x00000e2c, 0xffffffff, 0x41434343, }, + { 0, 1, 0, 0x00000e30, 0xffffffff, 0x33353739, }, + { 0, 1, 1, 0x00000e34, 0xffffffff, 0x39414141, }, + { 0, 1, 1, 0x00000e38, 0xffffffff, 0x31333537, }, + { 0, 1, 2, 0x00000ed8, 0xffffffff, 0x37393939, }, + { 0, 1, 2, 0x00000edc, 0xffffffff, 0x29313335, }, + { 0, 1, 0, 0x00000e3c, 0xffffffff, 0x34343434, }, + { 0, 1, 0, 0x00000e40, 0xffffffff, 0x28303234, }, + { 0, 1, 0, 0x00000e44, 0xffffffff, 0x32322426, }, + { 0, 1, 1, 0x00000e48, 0xffffffff, 0x30323232, }, + { 0, 1, 1, 0x00000e4c, 0xffffffff, 0x22242628, }, + { 0, 1, 2, 0x00000ee0, 0xffffffff, 0x30303030, }, + { 0, 1, 2, 0x00000ee4, 0xffffffff, 0x24262830, }, + { 0, 1, 2, 0x00000ee8, 0x0000ffff, 0x20222222, }, + { 0, 2, 0, 0x00001820, 0xffffffff, 0x43434343, }, + { 0, 2, 0, 0x00001824, 0xffffffff, 0x43434343, }, + { 0, 2, 0, 0x00001828, 0xffffffff, 0x35373941, }, + { 0, 2, 0, 0x0000182c, 0xffffffff, 0x41434343, }, + { 0, 2, 0, 0x00001830, 0xffffffff, 0x33353739, }, + { 0, 2, 1, 0x00001834, 0xffffffff, 0x39414141, }, + { 0, 2, 1, 0x00001838, 0xffffffff, 0x31333537, }, + { 0, 2, 2, 0x000018d8, 0xffffffff, 0x37393939, }, + { 0, 2, 2, 0x000018dc, 0xffffffff, 0x29313335, }, + { 0, 2, 0, 0x0000183c, 0xffffffff, 0x34343434, }, + { 0, 2, 0, 0x00001840, 0xffffffff, 0x28303234, }, + { 0, 2, 0, 0x00001844, 0xffffffff, 0x32322426, }, + { 0, 2, 1, 0x00001848, 0xffffffff, 0x30323232, }, + { 0, 2, 1, 0x0000184c, 0xffffffff, 0x22242628, }, + { 0, 2, 2, 0x000018e0, 0xffffffff, 0x30303030, }, + { 0, 2, 2, 0x000018e4, 0xffffffff, 0x24262830, }, + { 0, 2, 2, 0x000018e8, 0x0000ffff, 0x20222222, }, + { 0, 3, 0, 0x00001a20, 0xffffffff, 0x43434343, }, + { 0, 3, 0, 0x00001a24, 0xffffffff, 0x43434343, }, + { 0, 3, 0, 0x00001a28, 0xffffffff, 0x35373941, }, + { 0, 3, 0, 0x00001a2c, 0xffffffff, 0x41434343, }, + { 0, 3, 0, 0x00001a30, 0xffffffff, 0x33353739, }, + { 0, 3, 1, 0x00001a34, 0xffffffff, 0x39414141, }, + { 0, 3, 1, 0x00001a38, 0xffffffff, 0x31333537, }, + { 0, 3, 2, 0x00001ad8, 0xffffffff, 0x37393939, }, + { 0, 3, 2, 0x00001adc, 0xffffffff, 0x29313335, }, + { 0, 3, 0, 0x00001a3c, 0xffffffff, 0x34343434, }, + { 0, 3, 0, 0x00001a40, 0xffffffff, 0x28303234, }, + { 0, 3, 0, 0x00001a44, 0xffffffff, 0x32322426, }, + { 0, 3, 1, 0x00001a48, 0xffffffff, 0x30323232, }, + { 0, 3, 1, 0x00001a4c, 0xffffffff, 0x22242628, }, + { 0, 3, 2, 0x00001ae0, 0xffffffff, 0x30303030, }, + { 0, 3, 2, 0x00001ae4, 0xffffffff, 0x24262830, }, + { 0, 3, 2, 0x00001ae8, 0x0000ffff, 0x20222222, }, + { 1, 0, 0, 0x00000c24, 0xffffffff, 0x46464646, }, + { 1, 0, 0, 0x00000c28, 0xffffffff, 0x39414345, }, + { 1, 0, 0, 0x00000c2c, 0xffffffff, 0x46464646, }, + { 1, 0, 0, 0x00000c30, 0xffffffff, 0x38404244, }, + { 1, 0, 1, 0x00000c34, 0xffffffff, 0x46464646, }, + { 1, 0, 1, 0x00000c38, 0xffffffff, 0x36384042, }, + { 1, 0, 2, 0x00000cd8, 0xffffffff, 0x46464646, }, + { 1, 0, 2, 0x00000cdc, 0xffffffff, 0x34363840, }, + { 1, 0, 0, 0x00000c3c, 0xffffffff, 0x46464646, }, + { 1, 0, 0, 0x00000c40, 0xffffffff, 0x38404244, }, + { 1, 0, 0, 0x00000c44, 0xffffffff, 0x46463738, }, + { 1, 0, 1, 0x00000c48, 0xffffffff, 0x42444646, }, + { 1, 0, 1, 0x00000c4c, 0xffffffff, 0x35373840, }, + { 1, 0, 2, 0x00000ce0, 0xffffffff, 0x46464646, }, + { 1, 0, 2, 0x00000ce4, 0xffffffff, 0x37394143, }, + { 1, 0, 2, 0x00000ce8, 0x0000ffff, 0x33333335, }, + { 1, 1, 0, 0x00000e24, 0xffffffff, 0x46464646, }, + { 1, 1, 0, 0x00000e28, 0xffffffff, 0x39414345, }, + { 1, 1, 0, 0x00000e2c, 0xffffffff, 0x46464646, }, + { 1, 1, 0, 0x00000e30, 0xffffffff, 0x38404244, }, + { 1, 1, 1, 0x00000e34, 0xffffffff, 0x46464646, }, + { 1, 1, 1, 0x00000e38, 0xffffffff, 0x36384042, }, + { 1, 1, 2, 0x00000ed8, 0xffffffff, 0x46464646, }, + { 1, 1, 2, 0x00000edc, 0xffffffff, 0x34363840, }, + { 1, 1, 0, 0x00000e3c, 0xffffffff, 0x46464646, }, + { 1, 1, 0, 0x00000e40, 0xffffffff, 0x38404244, }, + { 1, 1, 0, 0x00000e44, 0xffffffff, 0x46463738, }, + { 1, 1, 1, 0x00000e48, 0xffffffff, 0x42444646, }, + { 1, 1, 1, 0x00000e4c, 0xffffffff, 0x35373840, }, + { 1, 1, 2, 0x00000ee0, 0xffffffff, 0x46464646, }, + { 1, 1, 2, 0x00000ee4, 0xffffffff, 0x37394143, }, + { 1, 1, 2, 0x00000ee8, 0x0000ffff, 0x33333335, }, + { 1, 2, 0, 0x00001824, 0xffffffff, 0x46464646, }, + { 1, 2, 0, 0x00001828, 0xffffffff, 0x39414345, }, + { 1, 2, 0, 0x0000182c, 0xffffffff, 0x46464646, }, + { 1, 2, 0, 0x00001830, 0xffffffff, 0x38404244, }, + { 1, 2, 1, 0x00001834, 0xffffffff, 0x46464646, }, + { 1, 2, 1, 0x00001838, 0xffffffff, 0x36384042, }, + { 1, 2, 2, 0x000018d8, 0xffffffff, 0x46464646, }, + { 1, 2, 2, 0x000018dc, 0xffffffff, 0x34363840, }, + { 1, 2, 0, 0x0000183c, 0xffffffff, 0x46464646, }, + { 1, 2, 0, 0x00001840, 0xffffffff, 0x38404244, }, + { 1, 2, 0, 0x00001844, 0xffffffff, 0x46463738, }, + { 1, 2, 1, 0x00001848, 0xffffffff, 0x42444646, }, + { 1, 2, 1, 0x0000184c, 0xffffffff, 0x35373840, }, + { 1, 2, 2, 0x000018e0, 0xffffffff, 0x46464646, }, + { 1, 2, 2, 0x000018e4, 0xffffffff, 0x37394143, }, + { 1, 2, 2, 0x000018e8, 0x0000ffff, 0x33333335, }, + { 1, 3, 0, 0x00001a24, 0xffffffff, 0x46464646, }, + { 1, 3, 0, 0x00001a28, 0xffffffff, 0x39414345, }, + { 1, 3, 0, 0x00001a2c, 0xffffffff, 0x46464646, }, + { 1, 3, 0, 0x00001a30, 0xffffffff, 0x38404244, }, + { 1, 3, 1, 0x00001a34, 0xffffffff, 0x46464646, }, + { 1, 3, 1, 0x00001a38, 0xffffffff, 0x36384042, }, + { 1, 3, 2, 0x00001ad8, 0xffffffff, 0x46464646, }, + { 1, 3, 2, 0x00001adc, 0xffffffff, 0x34363840, }, + { 1, 3, 0, 0x00001a3c, 0xffffffff, 0x46464646, }, + { 1, 3, 0, 0x00001a40, 0xffffffff, 0x38404244, }, + { 1, 3, 0, 0x00001a44, 0xffffffff, 0x46463738, }, + { 1, 3, 1, 0x00001a48, 0xffffffff, 0x42444646, }, + { 1, 3, 1, 0x00001a4c, 0xffffffff, 0x35373840, }, + { 1, 3, 2, 0x00001ae0, 0xffffffff, 0x46464646, }, + { 1, 3, 2, 0x00001ae4, 0xffffffff, 0x37394143, }, + { 1, 3, 2, 0x00001ae8, 0x0000ffff, 0x33333335, }, +}; + +RTW_DECL_TABLE_BB_PG(rtw8814a_bb_pg_type8); + +static const u32 rtw8814a_rf_a[] = { + 0x018, 0x00013124, + 0x040, 0x00000C00, + 0x058, 0x00000F98, + 0x07F, 0x00068004, + 0x0B0, 0x000FFFFE, + 0x0B1, 0x0003FF48, + 0x0B2, 0x0006AA3F, + 0x0B3, 0x000FFC9A, + 0x0B4, 0x0000A78F, + 0x0B5, 0x00000A3F, + 0x0B6, 0x0000C09C, + 0x80000001, 0x00000000, 0x40000000, 0x00000000, + 0x0B7, 0x00030008, + 0x90000002, 0x00000000, 0x40000000, 0x00000000, + 0x0B7, 0x00030008, + 0x90000003, 0x00000000, 0x40000000, 0x00000000, + 0x0B7, 0x00030008, + 0x90000004, 0x00000000, 0x40000000, 0x00000000, + 0x0B7, 0x00030008, + 0x90000005, 0x00000000, 0x40000000, 0x00000000, + 0x0B7, 0x00030008, + 0x90000006, 0x00000000, 0x40000000, 0x00000000, + 0x0B7, 0x00030008, + 0x90000008, 0x00000000, 0x40000000, 0x00000000, + 0x0B7, 0x00030008, + 0x9000000a, 0x00000000, 0x40000000, 0x00000000, + 0x0B7, 0x00030008, + 0x9000000b, 0x00000000, 0x40000000, 0x00000000, + 0x0B7, 0x00030008, + 0xA0000000, 0x00000000, + 0x0B7, 0x0003000C, + 0xB0000000, 0x00000000, + 0x0B8, 0x0007400E, + 0x80000001, 0x00000000, 0x40000000, 0x00000000, + 0x0B9, 0x000FBF50, + 0x90000002, 0x00000000, 0x40000000, 0x00000000, + 0x0B9, 0x000FBF50, + 0x90000003, 0x00000000, 0x40000000, 0x00000000, + 0x0B9, 0x000FBF50, + 0x90000004, 0x00000000, 0x40000000, 0x00000000, + 0x0B9, 0x000FBF50, + 0x90000005, 0x00000000, 0x40000000, 0x00000000, + 0x0B9, 0x000FBF50, + 0x90000006, 0x00000000, 0x40000000, 0x00000000, + 0x0B9, 0x000FBF50, + 0x90000008, 0x00000000, 0x40000000, 0x00000000, + 0x0B9, 0x000FBF50, + 0x9000000a, 0x00000000, 0x40000000, 0x00000000, + 0x0B9, 0x000FBF50, + 0x9000000b, 0x00000000, 0x40000000, 0x00000000, + 0x0B9, 0x000FBF50, + 0xA0000000, 0x00000000, + 0x0B9, 0x000FBF50, + 0xB0000000, 0x00000000, + 0x0BA, 0x00050780, + 0x0BB, 0x00000000, + 0x0BC, 0x00040009, + 0x0BD, 0x00000000, + 0x0BE, 0x00000000, + 0x0BF, 0x00000000, + 0x0EF, 0x00020000, + 0x03E, 0x00000000, + 0x80000001, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00030000, + 0x90000006, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00030000, + 0xA0000000, 0x00000000, + 0x03F, 0x00030000, + 0xB0000000, 0x00000000, + 0x03E, 0x00020000, + 0x80000001, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00040000, + 0x90000006, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00040000, + 0xA0000000, 0x00000000, + 0x03F, 0x00040000, + 0xB0000000, 0x00000000, + 0x03E, 0x00040000, + 0x80000001, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00030000, + 0x90000006, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00030000, + 0xA0000000, 0x00000000, + 0x03F, 0x00030000, + 0xB0000000, 0x00000000, + 0x03E, 0x00060000, + 0x80000001, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00030000, + 0x90000006, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x00030000, + 0xA0000000, 0x00000000, + 0x03F, 0x00030000, + 0xB0000000, 0x00000000, + 0x0EF, 0x00000000, + 0x0EF, 0x00010000, + 0x03E, 0x00000000, + 0x03F, 0x00006800, + 0x03E, 0x00000080, + 0x03F, 0x00006000, + 0x03E, 0x00000100, + 0x03F, 0x00004800, + 0x03E, 0x00000180, + 0x03F, 0x00004000, + 0x03E, 0x00000200, + 0x03F, 0x00004000, + 0x03E, 0x00000280, + 0x03F, 0x00002800, + 0x03E, 0x00000300, + 0x03F, 0x00002800, + 0x03E, 0x00000380, + 0x03F, 0x00002000, + 0x0EF, 0x00000000, + 0x0EF, 0x00040000, + 0x03E, 0x00000000, + 0x03F, 0x000000BC, + 0x03E, 0x00000040, + 0x03F, 0x00000053, + 0x03E, 0x00000050, + 0x03F, 0x00000050, + 0x03E, 0x00000060, + 0x03F, 0x00000050, + 0x0EF, 0x00000000, + 0x0EF, 0x00000400, + 0x03E, 0x00000006, + 0x041, 0x000EE080, + 0x03E, 0x00000008, + 0x041, 0x000EE0C0, + 0x03E, 0x0000000A, + 0x041, 0x000EE100, + 0x03E, 0x0000000C, + 0x041, 0x000EE100, + 0x0EF, 0x00000000, + 0x018, 0x00000006, + 0x80000002, 0x00000000, 0x40000000, 0x00000000, + 0x086, 0x000E335A, + 0x087, 0x00079F80, + 0x90000003, 0x00000000, 0x40000000, 0x00000000, + 0x086, 0x000E335A, + 0x087, 0x00079F80, + 0x90000004, 0x00000000, 0x40000000, 0x00000000, + 0x086, 0x000E335A, + 0x087, 0x00079F80, + 0x90000005, 0x00000000, 0x40000000, 0x00000000, + 0x086, 0x000E335A, + 0x087, 0x00079F80, + 0x90000008, 0x00000000, 0x40000000, 0x00000000, + 0x086, 0x000E335A, + 0x087, 0x00079F80, + 0x9000000a, 0x00000000, 0x40000000, 0x00000000, + 0x086, 0x000E335A, + 0x087, 0x00079F80, + 0x9000000b, 0x00000000, 0x40000000, 0x00000000, + 0x086, 0x000E335A, + 0x087, 0x00079F80, + 0xA0000000, 0x00000000, + 0x086, 0x000E4B58, + 0x087, 0x00049F80, + 0xB0000000, 0x00000000, + 0x0DF, 0x00000008, + 0x0EF, 0x00002000, + 0x80000002, 0x00000000, 0x40000000, 0x00000000, + 0x03B, 0x0003F19B, + 0x03B, 0x00037A5B, + 0x03B, 0x0002A433, + 0x03B, 0x00027BD3, + 0x03B, 0x0001F80B, + 0x03B, 0x000179C3, + 0x90000003, 0x00000000, 0x40000000, 0x00000000, + 0x03B, 0x0003F19B, + 0x03B, 0x00037A5B, + 0x03B, 0x0002A433, + 0x03B, 0x00027BD3, + 0x03B, 0x0001F80B, + 0x03B, 0x000179C3, + 0x90000004, 0x00000000, 0x40000000, 0x00000000, + 0x03B, 0x0003F19B, + 0x03B, 0x00037A5B, + 0x03B, 0x0002A433, + 0x03B, 0x00027BD3, + 0x03B, 0x0001F80B, + 0x03B, 0x000179C3, + 0x90000005, 0x00000000, 0x40000000, 0x00000000, + 0x03B, 0x0003F19B, + 0x03B, 0x00037A5B, + 0x03B, 0x0002A433, + 0x03B, 0x00027BD3, + 0x03B, 0x0001F80B, + 0x03B, 0x000179C3, + 0x90000008, 0x00000000, 0x40000000, 0x00000000, + 0x03B, 0x0003F19B, + 0x03B, 0x00037A5B, + 0x03B, 0x0002A433, + 0x03B, 0x00027BD3, + 0x03B, 0x0001F80B, + 0x03B, 0x000179C3, + 0x9000000a, 0x00000000, 0x40000000, 0x00000000, + 0x03B, 0x0003F19B, + 0x03B, 0x00037A5B, + 0x03B, 0x0002A433, + 0x03B, 0x00027BD3, + 0x03B, 0x0001F80B, + 0x03B, 0x000179C3, + 0x9000000b, 0x00000000, 0x40000000, 0x00000000, + 0x03B, 0x0003F19B, + 0x03B, 0x00037A5B, + 0x03B, 0x0002A433, + 0x03B, 0x00027BD3, + 0x03B, 0x0001F80B, + 0x03B, 0x000179C3, + 0xA0000000, 0x00000000, + 0x03B, 0x0003F258, + 0x03B, 0x00030A58, + 0x03B, 0x0002FA58, + 0x03B, 0x00022590, + 0x03B, 0x0001FA50, + 0x03B, 0x00010248, + 0x03B, 0x00008240, + 0xB0000000, 0x00000000, + 0x0EF, 0x00000100, + 0x80000002, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x0000A0D0, + 0x034, 0x000090CD, + 0x034, 0x000080CA, + 0x034, 0x0000704D, + 0x034, 0x0000604A, + 0x034, 0x00005047, + 0x034, 0x0000400A, + 0x034, 0x00003007, + 0x034, 0x00002004, + 0x034, 0x00001001, + 0x034, 0x00000001, + 0x90000003, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x0000A0D0, + 0x034, 0x000090CD, + 0x034, 0x000080CA, + 0x034, 0x0000704D, + 0x034, 0x0000604A, + 0x034, 0x00005047, + 0x034, 0x0000400A, + 0x034, 0x00003007, + 0x034, 0x00002004, + 0x034, 0x00001001, + 0x034, 0x00000001, + 0x90000004, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x0000A0D0, + 0x034, 0x000090CD, + 0x034, 0x000080CA, + 0x034, 0x0000704D, + 0x034, 0x0000604A, + 0x034, 0x00005047, + 0x034, 0x0000400A, + 0x034, 0x00003007, + 0x034, 0x00002004, + 0x034, 0x00001001, + 0x034, 0x00000001, + 0x90000005, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x0000A0D0, + 0x034, 0x000090CD, + 0x034, 0x000080CA, + 0x034, 0x0000704D, + 0x034, 0x0000604A, + 0x034, 0x00005047, + 0x034, 0x0000400A, + 0x034, 0x00003007, + 0x034, 0x00002004, + 0x034, 0x00001001, + 0x034, 0x00000001, + 0x90000008, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x0000A0D0, + 0x034, 0x000090CD, + 0x034, 0x000080CA, + 0x034, 0x0000704D, + 0x034, 0x0000604A, + 0x034, 0x00005047, + 0x034, 0x0000400A, + 0x034, 0x00003007, + 0x034, 0x00002004, + 0x034, 0x00001001, + 0x034, 0x00000001, + 0x9000000a, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x0000A0D0, + 0x034, 0x000090CD, + 0x034, 0x000080CA, + 0x034, 0x0000704D, + 0x034, 0x0000604A, + 0x034, 0x00005047, + 0x034, 0x0000400A, + 0x034, 0x00003007, + 0x034, 0x00002004, + 0x034, 0x00001001, + 0x034, 0x00000001, + 0x9000000b, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x0000A0D0, + 0x034, 0x000090CD, + 0x034, 0x000080CA, + 0x034, 0x0000704D, + 0x034, 0x0000604A, + 0x034, 0x00005047, + 0x034, 0x0000400A, + 0x034, 0x00003007, + 0x034, 0x00002004, + 0x034, 0x00001001, + 0x034, 0x00000001, + 0xA0000000, 0x00000000, + 0x034, 0x0000ADF6, + 0x034, 0x00009DF3, + 0x034, 0x00008DF0, + 0x034, 0x00007DED, + 0x034, 0x00006DEA, + 0x034, 0x00005CED, + 0x034, 0x00004CEA, + 0x034, 0x000034EA, + 0x034, 0x000024E7, + 0x034, 0x0000146A, + 0x034, 0x0000006B, + 0xB0000000, 0x00000000, + 0x80000002, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x0000A0D0, + 0x034, 0x000090CD, + 0x034, 0x000080CA, + 0x034, 0x0000704D, + 0x034, 0x0000604A, + 0x034, 0x00005047, + 0x034, 0x0000400A, + 0x034, 0x00003007, + 0x034, 0x00002004, + 0x034, 0x00001001, + 0x034, 0x00000001, + 0x90000003, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x0000A0D0, + 0x034, 0x000090CD, + 0x034, 0x000080CA, + 0x034, 0x0000704D, + 0x034, 0x0000604A, + 0x034, 0x00005047, + 0x034, 0x0000400A, + 0x034, 0x00003007, + 0x034, 0x00002004, + 0x034, 0x00001001, + 0x034, 0x00000001, + 0x90000004, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x0000A0D0, + 0x034, 0x000090CD, + 0x034, 0x000080CA, + 0x034, 0x0000704D, + 0x034, 0x0000604A, + 0x034, 0x00005047, + 0x034, 0x0000400A, + 0x034, 0x00003007, + 0x034, 0x00002004, + 0x034, 0x00001001, + 0x034, 0x00000001, + 0x90000005, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x0000A0D0, + 0x034, 0x000090CD, + 0x034, 0x000080CA, + 0x034, 0x0000704D, + 0x034, 0x0000604A, + 0x034, 0x00005047, + 0x034, 0x0000400A, + 0x034, 0x00003007, + 0x034, 0x00002004, + 0x034, 0x00001001, + 0x034, 0x00000001, + 0x90000008, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x0000A0D0, + 0x034, 0x000090CD, + 0x034, 0x000080CA, + 0x034, 0x0000704D, + 0x034, 0x0000604A, + 0x034, 0x00005047, + 0x034, 0x0000400A, + 0x034, 0x00003007, + 0x034, 0x00002004, + 0x034, 0x00001001, + 0x034, 0x00000001, + 0x9000000a, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x0000A0D0, + 0x034, 0x000090CD, + 0x034, 0x000080CA, + 0x034, 0x0000704D, + 0x034, 0x0000604A, + 0x034, 0x00005047, + 0x034, 0x0000400A, + 0x034, 0x00003007, + 0x034, 0x00002004, + 0x034, 0x00001001, + 0x034, 0x00000001, + 0x9000000b, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x0000A0D0, + 0x034, 0x000090CD, + 0x034, 0x000080CA, + 0x034, 0x0000704D, + 0x034, 0x0000604A, + 0x034, 0x00005047, + 0x034, 0x0000400A, + 0x034, 0x00003007, + 0x034, 0x00002004, + 0x034, 0x00001001, + 0x034, 0x00000001, + 0xA0000000, 0x00000000, + 0x034, 0x0008ADF6, + 0x034, 0x00089DF3, + 0x034, 0x00088DF0, + 0x034, 0x00087DED, + 0x034, 0x00086DEA, + 0x034, 0x00085CED, + 0x034, 0x00084CEA, + 0x034, 0x000834EA, + 0x034, 0x000824E7, + 0x034, 0x0008146A, + 0x034, 0x0008006B, + 0xB0000000, 0x00000000, + 0x0EF, 0x00000000, + 0x0EF, 0x000020A2, + 0x0DF, 0x00000080, + 0x035, 0x00000192, + 0x035, 0x00008192, + 0x035, 0x00010192, + 0x036, 0x00000024, + 0x036, 0x00008024, + 0x036, 0x00010024, + 0x036, 0x00018024, + 0x0EF, 0x00000000, + 0x051, 0x00000C21, + 0x052, 0x000006D9, + 0x053, 0x000FC649, + 0x054, 0x0000017E, + 0x018, 0x0001012A, + 0x081, 0x0007FC00, + 0x089, 0x00050110, + 0x08A, 0x00043E50, + 0x08B, 0x0002E180, + 0x08C, 0x00093C3C, + 0x80000001, 0x00000000, 0x40000000, 0x00000000, + 0x085, 0x000F8000, + 0x90000006, 0x00000000, 0x40000000, 0x00000000, + 0x085, 0x000F8000, + 0xA0000000, 0x00000000, + 0x085, 0x000F8000, + 0xB0000000, 0x00000000, + 0x80000001, 0x00000000, 0x40000000, 0x00000000, + 0x08D, 0x000FFFF0, + 0x90000002, 0x00000000, 0x40000000, 0x00000000, + 0x08D, 0x000FFFF0, + 0x90000003, 0x00000000, 0x40000000, 0x00000000, + 0x08D, 0x000FFFF0, + 0x90000004, 0x00000000, 0x40000000, 0x00000000, + 0x08D, 0x000FFFF0, + 0x90000005, 0x00000000, 0x40000000, 0x00000000, + 0x08D, 0x000FFFF0, + 0x90000006, 0x00000000, 0x40000000, 0x00000000, + 0x08D, 0x000FFFF0, + 0x90000008, 0x00000000, 0x40000000, 0x00000000, + 0x08D, 0x000FFFF0, + 0x9000000a, 0x00000000, 0x40000000, 0x00000000, + 0x08D, 0x000FFFF0, + 0x9000000b, 0x00000000, 0x40000000, 0x00000000, + 0x08D, 0x000FFFF0, + 0xA0000000, 0x00000000, + 0x08D, 0x000FFFF0, + 0xB0000000, 0x00000000, + 0x0EF, 0x00001000, + 0x03A, 0x0000013C, + 0x03B, 0x00038023, + 0x80000001, 0x00000000, 0x40000000, 0x00000000, + 0x03C, 0x00024000, + 0x90000002, 0x00000000, 0x40000000, 0x00000000, + 0x03C, 0x00024000, + 0x90000003, 0x00000000, 0x40000000, 0x00000000, + 0x03C, 0x00000000, + 0x90000004, 0x00000000, 0x40000000, 0x00000000, + 0x03C, 0x00088000, + 0x90000005, 0x00000000, 0x40000000, 0x00000000, + 0x03C, 0x00000000, + 0x90000006, 0x00000000, 0x40000000, 0x00000000, + 0x03C, 0x00024000, + 0x90000007, 0x00000000, 0x40000000, 0x00000000, + 0x03C, 0x00000000, + 0x90000008, 0x00000000, 0x40000000, 0x00000000, + 0x03C, 0x00084000, + 0x90000009, 0x00000000, 0x40000000, 0x00000000, + 0x03C, 0x00000000, + 0x9000000a, 0x00000000, 0x40000000, 0x00000000, + 0x03C, 0x00088000, + 0x9000000b, 0x00000000, 0x40000000, 0x00000000, + 0x03C, 0x00088000, + 0xA0000000, 0x00000000, + 0x03C, 0x00028000, + 0xB0000000, 0x00000000, + 0x03A, 0x0000013C, + 0x03B, 0x00030023, + 0x03C, 0x00048000, + 0x03A, 0x0000013C, + 0x03B, 0x00028623, + 0x03C, 0x00000000, + 0x03A, 0x0000013C, + 0x03B, 0x00021633, + 0x03C, 0x00000000, + 0x03A, 0x0000013C, + 0x03B, 0x0001C633, + 0x03C, 0x00000000, + 0x03A, 0x0000013C, + 0x03B, 0x00010293, + 0x03C, 0x00000000, + 0x03A, 0x0000013C, + 0x03B, 0x00009593, + 0x03C, 0x00000000, + 0x03A, 0x00000148, + 0x80000008, 0x00000000, 0x40000000, 0x00000000, + 0x03B, 0x0000118B, + 0xA0000000, 0x00000000, + 0x03B, 0x0000078B, + 0xB0000000, 0x00000000, + 0x03C, 0x00000000, + 0x80000001, 0x00000000, 0x40000000, 0x00000000, + 0x03A, 0x0000013C, + 0x03B, 0x00078023, + 0x90000002, 0x00000000, 0x40000000, 0x00000000, + 0x03A, 0x0000013C, + 0x03B, 0x00078023, + 0x90000003, 0x00000000, 0x40000000, 0x00000000, + 0x03A, 0x0000013C, + 0x03B, 0x00078023, + 0x90000004, 0x00000000, 0x40000000, 0x00000000, + 0x03A, 0x0000013C, + 0x03B, 0x00078023, + 0x90000005, 0x00000000, 0x40000000, 0x00000000, + 0x03A, 0x0000013C, + 0x03B, 0x00078023, + 0x90000006, 0x00000000, 0x40000000, 0x00000000, + 0x03A, 0x0000013C, + 0x03B, 0x00078023, + 0x90000008, 0x00000000, 0x40000000, 0x00000000, + 0x03A, 0x0000013C, + 0x03B, 0x00078023, + 0x9000000a, 0x00000000, 0x40000000, 0x00000000, + 0x03A, 0x0000013C, + 0x03B, 0x00078023, + 0x9000000b, 0x00000000, 0x40000000, 0x00000000, + 0x03A, 0x0000013C, + 0x03B, 0x00078023, + 0xA0000000, 0x00000000, + 0x03A, 0x0000013C, + 0x03B, 0x00078023, + 0xB0000000, 0x00000000, + 0x80000001, 0x00000000, 0x40000000, 0x00000000, + 0x03C, 0x00024000, + 0x90000002, 0x00000000, 0x40000000, 0x00000000, + 0x03C, 0x000AC000, + 0x90000003, 0x00000000, 0x40000000, 0x00000000, + 0x03C, 0x00024000, + 0x90000004, 0x00000000, 0x40000000, 0x00000000, + 0x03C, 0x00088000, + 0x90000005, 0x00000000, 0x40000000, 0x00000000, + 0x03C, 0x00024000, + 0x90000006, 0x00000000, 0x40000000, 0x00000000, + 0x03C, 0x00024000, + 0x90000007, 0x00000000, 0x40000000, 0x00000000, + 0x03C, 0x00000000, + 0x90000008, 0x00000000, 0x40000000, 0x00000000, + 0x03C, 0x00040000, + 0x90000009, 0x00000000, 0x40000000, 0x00000000, + 0x03C, 0x00000000, + 0x9000000a, 0x00000000, 0x40000000, 0x00000000, + 0x03C, 0x00088000, + 0x9000000b, 0x00000000, 0x40000000, 0x00000000, + 0x03C, 0x00088000, + 0xA0000000, 0x00000000, + 0x03C, 0x0004C000, + 0xB0000000, 0x00000000, + 0x03A, 0x0000013C, + 0x03B, 0x00070023, + 0x03C, 0x00048000, + 0x03A, 0x0000013C, + 0x03B, 0x00068623, + 0x03C, 0x00000000, + 0x03A, 0x0000013C, + 0x03B, 0x00061633, + 0x03C, 0x00000000, + 0x03A, 0x0000013C, + 0x03B, 0x0005C633, + 0x03C, 0x00000000, + 0x03A, 0x0000013C, + 0x03B, 0x00050293, + 0x03C, 0x00000000, + 0x03A, 0x0000013C, + 0x03B, 0x00049593, + 0x03C, 0x00000000, + 0x03A, 0x00000148, + 0x80000008, 0x00000000, 0x40000000, 0x00000000, + 0x03B, 0x0004138B, + 0xA0000000, 0x00000000, + 0x03B, 0x0004078B, + 0xB0000000, 0x00000000, + 0x03C, 0x00000000, + 0x80000001, 0x00000000, 0x40000000, 0x00000000, + 0x03A, 0x0000013C, + 0x03B, 0x000B8023, + 0x90000002, 0x00000000, 0x40000000, 0x00000000, + 0x03A, 0x0000013C, + 0x03B, 0x000B8023, + 0x90000003, 0x00000000, 0x40000000, 0x00000000, + 0x03A, 0x0000013C, + 0x03B, 0x000B8023, + 0x90000004, 0x00000000, 0x40000000, 0x00000000, + 0x03A, 0x0000013C, + 0x03B, 0x000B8023, + 0x90000005, 0x00000000, 0x40000000, 0x00000000, + 0x03A, 0x0000013C, + 0x03B, 0x000B8023, + 0x90000006, 0x00000000, 0x40000000, 0x00000000, + 0x03A, 0x0000013C, + 0x03B, 0x000B8023, + 0x90000008, 0x00000000, 0x40000000, 0x00000000, + 0x03A, 0x0000013C, + 0x03B, 0x000B8023, + 0x9000000a, 0x00000000, 0x40000000, 0x00000000, + 0x03A, 0x0000013C, + 0x03B, 0x000B8023, + 0x9000000b, 0x00000000, 0x40000000, 0x00000000, + 0x03A, 0x0000013C, + 0x03B, 0x000B8023, + 0xA0000000, 0x00000000, + 0x03A, 0x0000013C, + 0x03B, 0x000B8023, + 0xB0000000, 0x00000000, + 0x80000001, 0x00000000, 0x40000000, 0x00000000, + 0x03C, 0x00084000, + 0x90000002, 0x00000000, 0x40000000, 0x00000000, + 0x03C, 0x0008C000, + 0x90000003, 0x00000000, 0x40000000, 0x00000000, + 0x03C, 0x00000000, + 0x90000004, 0x00000000, 0x40000000, 0x00000000, + 0x03C, 0x00084000, + 0x90000005, 0x00000000, 0x40000000, 0x00000000, + 0x03C, 0x00000000, + 0x90000006, 0x00000000, 0x40000000, 0x00000000, + 0x03C, 0x00084000, + 0x90000007, 0x00000000, 0x40000000, 0x00000000, + 0x03C, 0x00020000, + 0x90000008, 0x00000000, 0x40000000, 0x00000000, + 0x03C, 0x00060000, + 0x9000000a, 0x00000000, 0x40000000, 0x00000000, + 0x03C, 0x00084000, + 0x9000000b, 0x00000000, 0x40000000, 0x00000000, + 0x03C, 0x00084000, + 0xA0000000, 0x00000000, + 0x03C, 0x00004000, + 0xB0000000, 0x00000000, + 0x03A, 0x0000013C, + 0x03B, 0x000B0023, + 0x80000004, 0x00000000, 0x40000000, 0x00000000, + 0x03C, 0x00020000, + 0x9000000a, 0x00000000, 0x40000000, 0x00000000, + 0x03C, 0x00020000, + 0x9000000b, 0x00000000, 0x40000000, 0x00000000, + 0x03C, 0x00020000, + 0xA0000000, 0x00000000, + 0x03C, 0x00020000, + 0xB0000000, 0x00000000, + 0x03A, 0x0000013C, + 0x03B, 0x000A8623, + 0x03C, 0x00000000, + 0x03A, 0x0000013C, + 0x03B, 0x000A1633, + 0x03C, 0x00000000, + 0x03A, 0x0000013C, + 0x03B, 0x0009C633, + 0x03C, 0x00000000, + 0x03A, 0x0000013C, + 0x03B, 0x00090293, + 0x03C, 0x00000000, + 0x03A, 0x0000013C, + 0x03B, 0x00089593, + 0x03C, 0x00000000, + 0x03A, 0x00000148, + 0x80000008, 0x00000000, 0x40000000, 0x00000000, + 0x03B, 0x0008118B, + 0xA0000000, 0x00000000, + 0x03B, 0x0008078B, + 0xB0000000, 0x00000000, + 0x03C, 0x00000000, + 0x0EF, 0x00000000, + 0x0EF, 0x00000800, + 0x03B, 0x00000000, + 0x80000001, 0x00000000, 0x40000000, 0x00000000, + 0x03A, 0x00000803, + 0x90000002, 0x00000000, 0x40000000, 0x00000000, + 0x03A, 0x00000801, + 0x90000006, 0x00000000, 0x40000000, 0x00000000, + 0x03A, 0x00000803, + 0x90000007, 0x00000000, 0x40000000, 0x00000000, + 0x03A, 0x00001003, + 0x90000008, 0x00000000, 0x40000000, 0x00000000, + 0x03A, 0x00001003, + 0x90000009, 0x00000000, 0x40000000, 0x00000000, + 0x03A, 0x00001003, + 0xA0000000, 0x00000000, + 0x03A, 0x00000803, + 0xB0000000, 0x00000000, + 0x03B, 0x00040000, + 0x80000001, 0x00000000, 0x40000000, 0x00000000, + 0x03A, 0x00001000, + 0x90000002, 0x00000000, 0x40000000, 0x00000000, + 0x03A, 0x00001801, + 0x90000003, 0x00000000, 0x40000000, 0x00000000, + 0x03A, 0x00000003, + 0x90000005, 0x00000000, 0x40000000, 0x00000000, + 0x03A, 0x00000003, + 0x90000006, 0x00000000, 0x40000000, 0x00000000, + 0x03A, 0x00001000, + 0x90000007, 0x00000000, 0x40000000, 0x00000000, + 0x03A, 0x00000000, + 0x90000008, 0x00000000, 0x40000000, 0x00000000, + 0x03A, 0x00001001, + 0x90000009, 0x00000000, 0x40000000, 0x00000000, + 0x03A, 0x00000000, + 0xA0000000, 0x00000000, + 0x03A, 0x00001000, + 0xB0000000, 0x00000000, + 0x03B, 0x00080000, + 0x80000007, 0x00000000, 0x40000000, 0x00000000, + 0x03A, 0x00001802, + 0x90000009, 0x00000000, 0x40000000, 0x00000000, + 0x03A, 0x00000800, + 0xA0000000, 0x00000000, + 0x03A, 0x00001002, + 0xB0000000, 0x00000000, + 0x0EF, 0x00000000, + 0x80000001, 0x00000000, 0x40000000, 0x00000000, + 0x90000002, 0x00000000, 0x40000000, 0x00000000, + 0x90000003, 0x00000000, 0x40000000, 0x00000000, + 0x90000004, 0x00000000, 0x40000000, 0x00000000, + 0x90000005, 0x00000000, 0x40000000, 0x00000000, + 0x90000006, 0x00000000, 0x40000000, 0x00000000, + 0x90000008, 0x00000000, 0x40000000, 0x00000000, + 0x9000000a, 0x00000000, 0x40000000, 0x00000000, + 0x9000000b, 0x00000000, 0x40000000, 0x00000000, + 0xA0000000, 0x00000000, + 0xB0000000, 0x00000000, + 0x018, 0x00013124, + 0x0EF, 0x00000100, + 0x80000001, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x0004A1AD, + 0x034, 0x000491AA, + 0x034, 0x000481A7, + 0x034, 0x000470AA, + 0x034, 0x000460A7, + 0x034, 0x00045049, + 0x034, 0x00044046, + 0x034, 0x00043026, + 0x034, 0x00042009, + 0x034, 0x00041006, + 0x034, 0x00040003, + 0x90000002, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x0004A3EF, + 0x034, 0x000493AF, + 0x034, 0x000483AB, + 0x034, 0x0004718C, + 0x034, 0x00046189, + 0x034, 0x0004506D, + 0x034, 0x0004406A, + 0x034, 0x0004302C, + 0x034, 0x00042029, + 0x034, 0x00041026, + 0x034, 0x00040023, + 0x90000003, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x0004A3EF, + 0x034, 0x000493AF, + 0x034, 0x000483AB, + 0x034, 0x0004718C, + 0x034, 0x00046189, + 0x034, 0x0004506D, + 0x034, 0x0004406A, + 0x034, 0x0004302C, + 0x034, 0x00042029, + 0x034, 0x00041026, + 0x034, 0x00040023, + 0x90000004, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x0004A3EF, + 0x034, 0x000493AF, + 0x034, 0x000483AB, + 0x034, 0x0004718C, + 0x034, 0x00046189, + 0x034, 0x0004506D, + 0x034, 0x0004406A, + 0x034, 0x0004302C, + 0x034, 0x00042029, + 0x034, 0x00041026, + 0x034, 0x00040023, + 0x90000005, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x0004A3EF, + 0x034, 0x000493AF, + 0x034, 0x000483AB, + 0x034, 0x0004718C, + 0x034, 0x00046189, + 0x034, 0x0004506D, + 0x034, 0x0004406A, + 0x034, 0x0004302C, + 0x034, 0x00042029, + 0x034, 0x00041026, + 0x034, 0x00040023, + 0x90000008, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x0004A3F5, + 0x034, 0x000493F2, + 0x034, 0x000483B0, + 0x034, 0x00047370, + 0x034, 0x0004636D, + 0x034, 0x0004536A, + 0x034, 0x00044349, + 0x034, 0x0004316A, + 0x034, 0x00042167, + 0x034, 0x00041129, + 0x034, 0x00040049, + 0x9000000a, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x0004A3EF, + 0x034, 0x000493AF, + 0x034, 0x000483AB, + 0x034, 0x0004718C, + 0x034, 0x00046189, + 0x034, 0x0004506D, + 0x034, 0x0004406A, + 0x034, 0x0004302C, + 0x034, 0x00042029, + 0x034, 0x00041026, + 0x034, 0x00040023, + 0x9000000b, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x0004A3EF, + 0x034, 0x000493AF, + 0x034, 0x000483AB, + 0x034, 0x0004718C, + 0x034, 0x00046189, + 0x034, 0x0004506D, + 0x034, 0x0004406A, + 0x034, 0x0004302C, + 0x034, 0x00042029, + 0x034, 0x00041026, + 0x034, 0x00040023, + 0xA0000000, 0x00000000, + 0x034, 0x0004AFF1, + 0x034, 0x00049FEE, + 0x034, 0x00048FEB, + 0x034, 0x00047FE8, + 0x034, 0x00046DEA, + 0x034, 0x00045DE7, + 0x034, 0x00044CEA, + 0x034, 0x00043CE7, + 0x034, 0x00042C69, + 0x034, 0x00041C66, + 0x034, 0x00040C28, + 0xB0000000, 0x00000000, + 0x80000001, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x0002A1AD, + 0x034, 0x000291AA, + 0x034, 0x000281A7, + 0x034, 0x000270AA, + 0x034, 0x000260A7, + 0x034, 0x00025049, + 0x034, 0x00024046, + 0x034, 0x00023026, + 0x034, 0x00022009, + 0x034, 0x00021006, + 0x034, 0x00020003, + 0x90000002, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x0002A3EF, + 0x034, 0x000293AC, + 0x034, 0x0002838A, + 0x034, 0x0002718C, + 0x034, 0x00026189, + 0x034, 0x0002506D, + 0x034, 0x0002406A, + 0x034, 0x0002302C, + 0x034, 0x00022029, + 0x034, 0x00021026, + 0x034, 0x00020023, + 0x90000003, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x0002A3EF, + 0x034, 0x000293AC, + 0x034, 0x0002838A, + 0x034, 0x0002718C, + 0x034, 0x00026189, + 0x034, 0x0002506D, + 0x034, 0x0002406A, + 0x034, 0x0002302C, + 0x034, 0x00022029, + 0x034, 0x00021026, + 0x034, 0x00020023, + 0x90000004, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x0002A3EF, + 0x034, 0x000293AC, + 0x034, 0x0002838A, + 0x034, 0x0002718C, + 0x034, 0x00026189, + 0x034, 0x0002506D, + 0x034, 0x0002406A, + 0x034, 0x0002302C, + 0x034, 0x00022029, + 0x034, 0x00021026, + 0x034, 0x00020023, + 0x90000005, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x0002A3EF, + 0x034, 0x000293AC, + 0x034, 0x0002838A, + 0x034, 0x0002718C, + 0x034, 0x00026189, + 0x034, 0x0002506D, + 0x034, 0x0002406A, + 0x034, 0x0002302C, + 0x034, 0x00022029, + 0x034, 0x00021026, + 0x034, 0x00020023, + 0x90000008, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x0002A3F5, + 0x034, 0x000293F2, + 0x034, 0x000282F1, + 0x034, 0x000272B0, + 0x034, 0x000262AD, + 0x034, 0x000252AA, + 0x034, 0x000242A7, + 0x034, 0x000230EC, + 0x034, 0x000220E9, + 0x034, 0x0002106A, + 0x034, 0x00020067, + 0x9000000a, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x0002A3EF, + 0x034, 0x000293AC, + 0x034, 0x0002838A, + 0x034, 0x0002718C, + 0x034, 0x00026189, + 0x034, 0x0002506D, + 0x034, 0x0002406A, + 0x034, 0x0002302C, + 0x034, 0x00022029, + 0x034, 0x00021026, + 0x034, 0x00020023, + 0x9000000b, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x0002A3EF, + 0x034, 0x000293AC, + 0x034, 0x0002838A, + 0x034, 0x0002718C, + 0x034, 0x00026189, + 0x034, 0x0002506D, + 0x034, 0x0002406A, + 0x034, 0x0002302C, + 0x034, 0x00022029, + 0x034, 0x00021026, + 0x034, 0x00020023, + 0xA0000000, 0x00000000, + 0x034, 0x0002AFF1, + 0x034, 0x00029FEE, + 0x034, 0x00028FEB, + 0x034, 0x00027FE8, + 0x034, 0x00026DEA, + 0x034, 0x00025DE7, + 0x034, 0x00024CEA, + 0x034, 0x00023CE7, + 0x034, 0x00022C69, + 0x034, 0x00021C66, + 0x034, 0x00020C28, + 0xB0000000, 0x00000000, + 0x80000001, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x0000A3EC, + 0x034, 0x0000938C, + 0x034, 0x000081AD, + 0x034, 0x000071AA, + 0x034, 0x000061A7, + 0x034, 0x000050AA, + 0x034, 0x000040A7, + 0x034, 0x0000302C, + 0x034, 0x00002029, + 0x034, 0x0000100C, + 0x034, 0x00000009, + 0x90000002, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x0000A3EE, + 0x034, 0x000093AC, + 0x034, 0x0000838A, + 0x034, 0x0000718C, + 0x034, 0x00006189, + 0x034, 0x0000506D, + 0x034, 0x0000406A, + 0x034, 0x0000302C, + 0x034, 0x00002029, + 0x034, 0x00001026, + 0x034, 0x00000023, + 0x90000003, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x0000A3EE, + 0x034, 0x000093AC, + 0x034, 0x0000838A, + 0x034, 0x0000718C, + 0x034, 0x00006189, + 0x034, 0x0000506D, + 0x034, 0x0000406A, + 0x034, 0x0000302C, + 0x034, 0x00002029, + 0x034, 0x00001026, + 0x034, 0x00000023, + 0x90000004, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x0000A3EE, + 0x034, 0x000093AC, + 0x034, 0x0000838A, + 0x034, 0x0000718C, + 0x034, 0x00006189, + 0x034, 0x0000506D, + 0x034, 0x0000406A, + 0x034, 0x0000302C, + 0x034, 0x00002029, + 0x034, 0x00001026, + 0x034, 0x00000023, + 0x90000005, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x0000A3EE, + 0x034, 0x000093AC, + 0x034, 0x0000838A, + 0x034, 0x0000718C, + 0x034, 0x00006189, + 0x034, 0x0000506D, + 0x034, 0x0000406A, + 0x034, 0x0000302C, + 0x034, 0x00002029, + 0x034, 0x00001026, + 0x034, 0x00000023, + 0x90000008, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x0000A3F4, + 0x034, 0x000093F1, + 0x034, 0x000082B1, + 0x034, 0x000071D1, + 0x034, 0x000061CE, + 0x034, 0x000051CB, + 0x034, 0x000041C8, + 0x034, 0x000030CB, + 0x034, 0x000020C8, + 0x034, 0x00001087, + 0x034, 0x00000084, + 0x9000000a, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x0000A3EE, + 0x034, 0x000093AC, + 0x034, 0x0000838A, + 0x034, 0x0000718C, + 0x034, 0x00006189, + 0x034, 0x0000506D, + 0x034, 0x0000406A, + 0x034, 0x0000302C, + 0x034, 0x00002029, + 0x034, 0x00001026, + 0x034, 0x00000023, + 0x9000000b, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x0000A3EE, + 0x034, 0x000093AC, + 0x034, 0x0000838A, + 0x034, 0x0000718C, + 0x034, 0x00006189, + 0x034, 0x0000506D, + 0x034, 0x0000406A, + 0x034, 0x0000302C, + 0x034, 0x00002029, + 0x034, 0x00001026, + 0x034, 0x00000023, + 0xA0000000, 0x00000000, + 0x034, 0x0000AFF1, + 0x034, 0x00009FEE, + 0x034, 0x00008FEB, + 0x034, 0x00007FE8, + 0x034, 0x00006DEA, + 0x034, 0x00005DE7, + 0x034, 0x00004CEA, + 0x034, 0x00003CE7, + 0x034, 0x00002C69, + 0x034, 0x00001C66, + 0x034, 0x00000C28, + 0xB0000000, 0x00000000, + 0x80000001, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x000CA1AD, + 0x034, 0x000C91AA, + 0x034, 0x000C81A7, + 0x034, 0x000C70AA, + 0x034, 0x000C60A7, + 0x034, 0x000C5049, + 0x034, 0x000C4046, + 0x034, 0x000C3026, + 0x034, 0x000C2009, + 0x034, 0x000C1006, + 0x034, 0x000C0003, + 0x90000002, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x000CA3EF, + 0x034, 0x000C93AF, + 0x034, 0x000C83AB, + 0x034, 0x000C718C, + 0x034, 0x000C6189, + 0x034, 0x000C506D, + 0x034, 0x000C406A, + 0x034, 0x000C302C, + 0x034, 0x000C2029, + 0x034, 0x000C1026, + 0x034, 0x000C0023, + 0x90000003, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x000CA3EF, + 0x034, 0x000C93AF, + 0x034, 0x000C83AB, + 0x034, 0x000C718C, + 0x034, 0x000C6189, + 0x034, 0x000C506D, + 0x034, 0x000C406A, + 0x034, 0x000C302C, + 0x034, 0x000C2029, + 0x034, 0x000C1026, + 0x034, 0x000C0023, + 0x90000004, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x000CA3EF, + 0x034, 0x000C93AF, + 0x034, 0x000C83AB, + 0x034, 0x000C718C, + 0x034, 0x000C6189, + 0x034, 0x000C506D, + 0x034, 0x000C406A, + 0x034, 0x000C302C, + 0x034, 0x000C2029, + 0x034, 0x000C1026, + 0x034, 0x000C0023, + 0x90000005, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x000CA3EF, + 0x034, 0x000C93AF, + 0x034, 0x000C83AB, + 0x034, 0x000C718C, + 0x034, 0x000C6189, + 0x034, 0x000C506D, + 0x034, 0x000C406A, + 0x034, 0x000C302C, + 0x034, 0x000C2029, + 0x034, 0x000C1026, + 0x034, 0x000C0023, + 0x90000008, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x000CA3F5, + 0x034, 0x000C93F2, + 0x034, 0x000C83B0, + 0x034, 0x000C7370, + 0x034, 0x000C636D, + 0x034, 0x000C536A, + 0x034, 0x000C4349, + 0x034, 0x000C316A, + 0x034, 0x000C2167, + 0x034, 0x000C1129, + 0x034, 0x000C0049, + 0x9000000a, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x000CA3EF, + 0x034, 0x000C93AF, + 0x034, 0x000C83AB, + 0x034, 0x000C718C, + 0x034, 0x000C6189, + 0x034, 0x000C506D, + 0x034, 0x000C406A, + 0x034, 0x000C302C, + 0x034, 0x000C2029, + 0x034, 0x000C1026, + 0x034, 0x000C0023, + 0x9000000b, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x000CA3EF, + 0x034, 0x000C93AF, + 0x034, 0x000C83AB, + 0x034, 0x000C718C, + 0x034, 0x000C6189, + 0x034, 0x000C506D, + 0x034, 0x000C406A, + 0x034, 0x000C302C, + 0x034, 0x000C2029, + 0x034, 0x000C1026, + 0x034, 0x000C0023, + 0xA0000000, 0x00000000, + 0x034, 0x000CA794, + 0x034, 0x000C9791, + 0x034, 0x000C878E, + 0x034, 0x000C778B, + 0x034, 0x000C658D, + 0x034, 0x000C558A, + 0x034, 0x000C448D, + 0x034, 0x000C348A, + 0x034, 0x000C244C, + 0x034, 0x000C1449, + 0x034, 0x000C042B, + 0xB0000000, 0x00000000, + 0x80000001, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x000AA1AD, + 0x034, 0x000A91AA, + 0x034, 0x000A81A7, + 0x034, 0x000A70AA, + 0x034, 0x000A60A7, + 0x034, 0x000A5049, + 0x034, 0x000A4046, + 0x034, 0x000A3026, + 0x034, 0x000A2009, + 0x034, 0x000A1006, + 0x034, 0x000A0003, + 0x90000002, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x000AA3EF, + 0x034, 0x000A93AC, + 0x034, 0x000A838A, + 0x034, 0x000A718C, + 0x034, 0x000A6189, + 0x034, 0x000A506D, + 0x034, 0x000A406A, + 0x034, 0x000A302C, + 0x034, 0x000A2029, + 0x034, 0x000A1026, + 0x034, 0x000A0023, + 0x90000003, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x000AA3EF, + 0x034, 0x000A93AC, + 0x034, 0x000A838A, + 0x034, 0x000A718C, + 0x034, 0x000A6189, + 0x034, 0x000A506D, + 0x034, 0x000A406A, + 0x034, 0x000A302C, + 0x034, 0x000A2029, + 0x034, 0x000A1026, + 0x034, 0x000A0023, + 0x90000004, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x000AA3EF, + 0x034, 0x000A93AC, + 0x034, 0x000A838A, + 0x034, 0x000A718C, + 0x034, 0x000A6189, + 0x034, 0x000A506D, + 0x034, 0x000A406A, + 0x034, 0x000A302C, + 0x034, 0x000A2029, + 0x034, 0x000A1026, + 0x034, 0x000A0023, + 0x90000005, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x000AA3EF, + 0x034, 0x000A93AC, + 0x034, 0x000A838A, + 0x034, 0x000A718C, + 0x034, 0x000A6189, + 0x034, 0x000A506D, + 0x034, 0x000A406A, + 0x034, 0x000A302C, + 0x034, 0x000A2029, + 0x034, 0x000A1026, + 0x034, 0x000A0023, + 0x90000008, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x000AA3F5, + 0x034, 0x000A93F2, + 0x034, 0x000A82F1, + 0x034, 0x000A72B0, + 0x034, 0x000A62AD, + 0x034, 0x000A52AA, + 0x034, 0x000A42A7, + 0x034, 0x000A30EC, + 0x034, 0x000A20E9, + 0x034, 0x000A106A, + 0x034, 0x000A0067, + 0x9000000a, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x000AA3EF, + 0x034, 0x000A93AC, + 0x034, 0x000A838A, + 0x034, 0x000A718C, + 0x034, 0x000A6189, + 0x034, 0x000A506D, + 0x034, 0x000A406A, + 0x034, 0x000A302C, + 0x034, 0x000A2029, + 0x034, 0x000A1026, + 0x034, 0x000A0023, + 0x9000000b, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x000AA3EF, + 0x034, 0x000A93AC, + 0x034, 0x000A838A, + 0x034, 0x000A718C, + 0x034, 0x000A6189, + 0x034, 0x000A506D, + 0x034, 0x000A406A, + 0x034, 0x000A302C, + 0x034, 0x000A2029, + 0x034, 0x000A1026, + 0x034, 0x000A0023, + 0xA0000000, 0x00000000, + 0x034, 0x000AA794, + 0x034, 0x000A9791, + 0x034, 0x000A878E, + 0x034, 0x000A778B, + 0x034, 0x000A658D, + 0x034, 0x000A558A, + 0x034, 0x000A448D, + 0x034, 0x000A348A, + 0x034, 0x000A244C, + 0x034, 0x000A1449, + 0x034, 0x000A042B, + 0xB0000000, 0x00000000, + 0x80000001, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x0008A3EC, + 0x034, 0x0008938C, + 0x034, 0x000881AD, + 0x034, 0x000871AA, + 0x034, 0x000861A7, + 0x034, 0x000850AA, + 0x034, 0x000840A7, + 0x034, 0x0008302C, + 0x034, 0x00082029, + 0x034, 0x0008100C, + 0x034, 0x00080009, + 0x90000002, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x0008A3EE, + 0x034, 0x000893AC, + 0x034, 0x0008838A, + 0x034, 0x0008718C, + 0x034, 0x00086189, + 0x034, 0x0008506D, + 0x034, 0x0008406A, + 0x034, 0x0008302C, + 0x034, 0x00082029, + 0x034, 0x00081026, + 0x034, 0x00080023, + 0x90000003, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x0008A3EE, + 0x034, 0x000893AC, + 0x034, 0x0008838A, + 0x034, 0x0008718C, + 0x034, 0x00086189, + 0x034, 0x0008506D, + 0x034, 0x0008406A, + 0x034, 0x0008302C, + 0x034, 0x00082029, + 0x034, 0x00081026, + 0x034, 0x00080023, + 0x90000004, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x0008A3EE, + 0x034, 0x000893AC, + 0x034, 0x0008838A, + 0x034, 0x0008718C, + 0x034, 0x00086189, + 0x034, 0x0008506D, + 0x034, 0x0008406A, + 0x034, 0x0008302C, + 0x034, 0x00082029, + 0x034, 0x00081026, + 0x034, 0x00080023, + 0x90000005, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x0008A3EE, + 0x034, 0x000893AC, + 0x034, 0x0008838A, + 0x034, 0x0008718C, + 0x034, 0x00086189, + 0x034, 0x0008506D, + 0x034, 0x0008406A, + 0x034, 0x0008302C, + 0x034, 0x00082029, + 0x034, 0x00081026, + 0x034, 0x00080023, + 0x90000008, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x0008A3F4, + 0x034, 0x000893F1, + 0x034, 0x000882B1, + 0x034, 0x000871D1, + 0x034, 0x000861CE, + 0x034, 0x000851CB, + 0x034, 0x000841C8, + 0x034, 0x000830CB, + 0x034, 0x000820C8, + 0x034, 0x00081087, + 0x034, 0x00080084, + 0x9000000a, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x0008A3EE, + 0x034, 0x000893AC, + 0x034, 0x0008838A, + 0x034, 0x0008718C, + 0x034, 0x00086189, + 0x034, 0x0008506D, + 0x034, 0x0008406A, + 0x034, 0x0008302C, + 0x034, 0x00082029, + 0x034, 0x00081026, + 0x034, 0x00080023, + 0x9000000b, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x0008A3EE, + 0x034, 0x000893AC, + 0x034, 0x0008838A, + 0x034, 0x0008718C, + 0x034, 0x00086189, + 0x034, 0x0008506D, + 0x034, 0x0008406A, + 0x034, 0x0008302C, + 0x034, 0x00082029, + 0x034, 0x00081026, + 0x034, 0x00080023, + 0xA0000000, 0x00000000, + 0x034, 0x0008A794, + 0x034, 0x00089791, + 0x034, 0x0008878E, + 0x034, 0x0008778B, + 0x034, 0x0008658D, + 0x034, 0x0008558A, + 0x034, 0x0008448D, + 0x034, 0x0008348A, + 0x034, 0x0008244C, + 0x034, 0x00081449, + 0x034, 0x0008042B, + 0xB0000000, 0x00000000, + 0x0EF, 0x00000000, + 0x0DF, 0x00000001, + 0x018, 0x0001712A, + 0x0EF, 0x00000040, + 0x80000001, 0x00000000, 0x40000000, 0x00000000, + 0x035, 0x000006CC, + 0x035, 0x000086CC, + 0x035, 0x000106CC, + 0x035, 0x000206CC, + 0x035, 0x000286CC, + 0x035, 0x000306CC, + 0x035, 0x000406CC, + 0x035, 0x000486CC, + 0x035, 0x000506CC, + 0x035, 0x000806CC, + 0x035, 0x000886CC, + 0x035, 0x000906CC, + 0x035, 0x000A06CC, + 0x035, 0x000A86CC, + 0x035, 0x000B06CC, + 0x035, 0x000C06CC, + 0x035, 0x000C86CC, + 0x035, 0x000D06CC, + 0x90000002, 0x00000000, 0x40000000, 0x00000000, + 0x035, 0x000006CC, + 0x035, 0x000086CC, + 0x035, 0x000106CC, + 0x035, 0x000206CC, + 0x035, 0x000286CC, + 0x035, 0x000306CC, + 0x035, 0x000406CC, + 0x035, 0x000486CC, + 0x035, 0x000506CC, + 0x035, 0x000806CC, + 0x035, 0x000886CC, + 0x035, 0x000906CC, + 0x035, 0x000A06CC, + 0x035, 0x000A86CC, + 0x035, 0x000B06CC, + 0x035, 0x000C06CC, + 0x035, 0x000C86CC, + 0x035, 0x000D06CC, + 0x90000003, 0x00000000, 0x40000000, 0x00000000, + 0x035, 0x000006CC, + 0x035, 0x000086CC, + 0x035, 0x000106CC, + 0x035, 0x000206CC, + 0x035, 0x000286CC, + 0x035, 0x000306CC, + 0x035, 0x000406CC, + 0x035, 0x000486CC, + 0x035, 0x000506CC, + 0x035, 0x000806CC, + 0x035, 0x000886CC, + 0x035, 0x000906CC, + 0x035, 0x000A06CC, + 0x035, 0x000A86CC, + 0x035, 0x000B06CC, + 0x035, 0x000C06CC, + 0x035, 0x000C86CC, + 0x035, 0x000D06CC, + 0x90000004, 0x00000000, 0x40000000, 0x00000000, + 0x035, 0x000006CC, + 0x035, 0x000086CC, + 0x035, 0x000106CC, + 0x035, 0x000206CC, + 0x035, 0x000286CC, + 0x035, 0x000306CC, + 0x035, 0x000406CC, + 0x035, 0x000486CC, + 0x035, 0x000506CC, + 0x035, 0x000806CC, + 0x035, 0x000886CC, + 0x035, 0x000906CC, + 0x035, 0x000A06CC, + 0x035, 0x000A86CC, + 0x035, 0x000B06CC, + 0x035, 0x000C06CC, + 0x035, 0x000C86CC, + 0x035, 0x000D06CC, + 0x90000005, 0x00000000, 0x40000000, 0x00000000, + 0x035, 0x000006CC, + 0x035, 0x000086CC, + 0x035, 0x000106CC, + 0x035, 0x000206CC, + 0x035, 0x000286CC, + 0x035, 0x000306CC, + 0x035, 0x000406CC, + 0x035, 0x000486CC, + 0x035, 0x000506CC, + 0x035, 0x000806CC, + 0x035, 0x000886CC, + 0x035, 0x000906CC, + 0x035, 0x000A06CC, + 0x035, 0x000A86CC, + 0x035, 0x000B06CC, + 0x035, 0x000C06CC, + 0x035, 0x000C86CC, + 0x035, 0x000D06CC, + 0x90000008, 0x00000000, 0x40000000, 0x00000000, + 0x035, 0x000006CC, + 0x035, 0x000086CC, + 0x035, 0x000106CC, + 0x035, 0x000206CC, + 0x035, 0x000286CC, + 0x035, 0x000306CC, + 0x035, 0x000406CC, + 0x035, 0x000486CC, + 0x035, 0x000506CC, + 0x035, 0x000806CC, + 0x035, 0x000886CC, + 0x035, 0x000906CC, + 0x035, 0x000A06CC, + 0x035, 0x000A86CC, + 0x035, 0x000B06CC, + 0x035, 0x000C06CC, + 0x035, 0x000C86CC, + 0x035, 0x000D06CC, + 0x9000000a, 0x00000000, 0x40000000, 0x00000000, + 0x035, 0x000006CC, + 0x035, 0x000086CC, + 0x035, 0x000106CC, + 0x035, 0x000206CC, + 0x035, 0x000286CC, + 0x035, 0x000306CC, + 0x035, 0x000406CC, + 0x035, 0x000486CC, + 0x035, 0x000506CC, + 0x035, 0x000806CC, + 0x035, 0x000886CC, + 0x035, 0x000906CC, + 0x035, 0x000A06CC, + 0x035, 0x000A86CC, + 0x035, 0x000B06CC, + 0x035, 0x000C06CC, + 0x035, 0x000C86CC, + 0x035, 0x000D06CC, + 0x9000000b, 0x00000000, 0x40000000, 0x00000000, + 0x035, 0x000006CC, + 0x035, 0x000086CC, + 0x035, 0x000106CC, + 0x035, 0x000206CC, + 0x035, 0x000286CC, + 0x035, 0x000306CC, + 0x035, 0x000406CC, + 0x035, 0x000486CC, + 0x035, 0x000506CC, + 0x035, 0x000806CC, + 0x035, 0x000886CC, + 0x035, 0x000906CC, + 0x035, 0x000A06CC, + 0x035, 0x000A86CC, + 0x035, 0x000B06CC, + 0x035, 0x000C06CC, + 0x035, 0x000C86CC, + 0x035, 0x000D06CC, + 0xA0000000, 0x00000000, + 0x035, 0x00000747, + 0x035, 0x00008747, + 0x035, 0x00010747, + 0x035, 0x00020747, + 0x035, 0x00028747, + 0x035, 0x00030747, + 0x035, 0x00040747, + 0x035, 0x00048747, + 0x035, 0x00050747, + 0x035, 0x000805FB, + 0x035, 0x000885FB, + 0x035, 0x000905FB, + 0x035, 0x000A05FB, + 0x035, 0x000A85FB, + 0x035, 0x000B05FB, + 0x035, 0x000C05FB, + 0x035, 0x000C85FB, + 0x035, 0x000D05FB, + 0xB0000000, 0x00000000, + 0x0EF, 0x00000000, + 0x0DF, 0x00000001, + 0x018, 0x0001712A, + 0x0EF, 0x00000010, + 0x80000001, 0x00000000, 0x40000000, 0x00000000, + 0x036, 0x00000473, + 0x036, 0x00008473, + 0x036, 0x00010473, + 0x036, 0x00020473, + 0x036, 0x00028473, + 0x036, 0x00030473, + 0x036, 0x00040473, + 0x036, 0x00048473, + 0x036, 0x00050473, + 0x036, 0x00080473, + 0x036, 0x00088473, + 0x036, 0x00090473, + 0x036, 0x000A0473, + 0x036, 0x000A8473, + 0x036, 0x000B0473, + 0x036, 0x000C0473, + 0x036, 0x000C8473, + 0x036, 0x000D0473, + 0x90000002, 0x00000000, 0x40000000, 0x00000000, + 0x036, 0x00000475, + 0x036, 0x00008475, + 0x036, 0x00010475, + 0x036, 0x00020475, + 0x036, 0x00028475, + 0x036, 0x00030475, + 0x036, 0x00040475, + 0x036, 0x00048475, + 0x036, 0x00050475, + 0x036, 0x00080475, + 0x036, 0x00088475, + 0x036, 0x00090475, + 0x036, 0x000A0475, + 0x036, 0x000A8475, + 0x036, 0x000B0475, + 0x036, 0x000C0475, + 0x036, 0x000C8475, + 0x036, 0x000D0475, + 0x90000003, 0x00000000, 0x40000000, 0x00000000, + 0x036, 0x00000475, + 0x036, 0x00008475, + 0x036, 0x00010475, + 0x036, 0x00020475, + 0x036, 0x00028475, + 0x036, 0x00030475, + 0x036, 0x00040475, + 0x036, 0x00048475, + 0x036, 0x00050475, + 0x036, 0x00080475, + 0x036, 0x00088475, + 0x036, 0x00090475, + 0x036, 0x000A0475, + 0x036, 0x000A8475, + 0x036, 0x000B0475, + 0x036, 0x000C0475, + 0x036, 0x000C8475, + 0x036, 0x000D0475, + 0x90000004, 0x00000000, 0x40000000, 0x00000000, + 0x036, 0x00000475, + 0x036, 0x00008475, + 0x036, 0x00010475, + 0x036, 0x00020475, + 0x036, 0x00028475, + 0x036, 0x00030475, + 0x036, 0x00040475, + 0x036, 0x00048475, + 0x036, 0x00050475, + 0x036, 0x00080475, + 0x036, 0x00088475, + 0x036, 0x00090475, + 0x036, 0x000A0475, + 0x036, 0x000A8475, + 0x036, 0x000B0475, + 0x036, 0x000C0475, + 0x036, 0x000C8475, + 0x036, 0x000D0475, + 0x90000005, 0x00000000, 0x40000000, 0x00000000, + 0x036, 0x00000475, + 0x036, 0x00008475, + 0x036, 0x00010475, + 0x036, 0x00020475, + 0x036, 0x00028475, + 0x036, 0x00030475, + 0x036, 0x00040475, + 0x036, 0x00048475, + 0x036, 0x00050475, + 0x036, 0x00080475, + 0x036, 0x00088475, + 0x036, 0x00090475, + 0x036, 0x000A0475, + 0x036, 0x000A8475, + 0x036, 0x000B0475, + 0x036, 0x000C0475, + 0x036, 0x000C8475, + 0x036, 0x000D0475, + 0x90000008, 0x00000000, 0x40000000, 0x00000000, + 0x036, 0x00000475, + 0x036, 0x00008475, + 0x036, 0x00010475, + 0x036, 0x00020475, + 0x036, 0x00028475, + 0x036, 0x00030475, + 0x036, 0x00040475, + 0x036, 0x00048475, + 0x036, 0x00050475, + 0x036, 0x00080475, + 0x036, 0x00088475, + 0x036, 0x00090475, + 0x036, 0x000A0475, + 0x036, 0x000A8475, + 0x036, 0x000B0475, + 0x036, 0x000C0475, + 0x036, 0x000C8475, + 0x036, 0x000D0475, + 0x9000000a, 0x00000000, 0x40000000, 0x00000000, + 0x036, 0x00000475, + 0x036, 0x00008475, + 0x036, 0x00010475, + 0x036, 0x00020475, + 0x036, 0x00028475, + 0x036, 0x00030475, + 0x036, 0x00040475, + 0x036, 0x00048475, + 0x036, 0x00050475, + 0x036, 0x00080475, + 0x036, 0x00088475, + 0x036, 0x00090475, + 0x036, 0x000A0475, + 0x036, 0x000A8475, + 0x036, 0x000B0475, + 0x036, 0x000C0475, + 0x036, 0x000C8475, + 0x036, 0x000D0475, + 0x9000000b, 0x00000000, 0x40000000, 0x00000000, + 0x036, 0x00000475, + 0x036, 0x00008475, + 0x036, 0x00010475, + 0x036, 0x00020475, + 0x036, 0x00028475, + 0x036, 0x00030475, + 0x036, 0x00040475, + 0x036, 0x00048475, + 0x036, 0x00050475, + 0x036, 0x00080475, + 0x036, 0x00088475, + 0x036, 0x00090475, + 0x036, 0x000A0475, + 0x036, 0x000A8475, + 0x036, 0x000B0475, + 0x036, 0x000C0475, + 0x036, 0x000C8475, + 0x036, 0x000D0475, + 0xA0000000, 0x00000000, + 0x036, 0x00000473, + 0x036, 0x00008473, + 0x036, 0x00010473, + 0x036, 0x00020473, + 0x036, 0x00028473, + 0x036, 0x00030473, + 0x036, 0x00040473, + 0x036, 0x00048473, + 0x036, 0x00050473, + 0x036, 0x00080473, + 0x036, 0x00088473, + 0x036, 0x00090473, + 0x036, 0x000A0473, + 0x036, 0x000A8473, + 0x036, 0x000B0473, + 0x036, 0x000C0473, + 0x036, 0x000C8473, + 0x036, 0x000D0473, + 0xB0000000, 0x00000000, + 0x0EF, 0x00000000, + 0x80000001, 0x00000000, 0x40000000, 0x00000000, + 0x90000002, 0x00000000, 0x40000000, 0x00000000, + 0x90000003, 0x00000000, 0x40000000, 0x00000000, + 0x90000004, 0x00000000, 0x40000000, 0x00000000, + 0x90000005, 0x00000000, 0x40000000, 0x00000000, + 0x90000008, 0x00000000, 0x40000000, 0x00000000, + 0x9000000a, 0x00000000, 0x40000000, 0x00000000, + 0x9000000b, 0x00000000, 0x40000000, 0x00000000, + 0xA0000000, 0x00000000, + 0x0EF, 0x00000004, + 0x037, 0x00000000, + 0x038, 0x00005146, + 0x037, 0x00004000, + 0x038, 0x00005146, + 0x037, 0x00008000, + 0x038, 0x00005146, + 0x037, 0x00010000, + 0x038, 0x00005146, + 0x037, 0x00014000, + 0x038, 0x00005146, + 0x037, 0x00018000, + 0x038, 0x00004D4E, + 0x037, 0x0001C000, + 0x038, 0x00004D4E, + 0x037, 0x00020000, + 0x038, 0x00004D4E, + 0x037, 0x00024000, + 0x038, 0x000071C6, + 0x037, 0x00028000, + 0x038, 0x000071C6, + 0x037, 0x0002C000, + 0x038, 0x000071C6, + 0x037, 0x00030000, + 0x038, 0x000071CE, + 0x037, 0x00034000, + 0x038, 0x000071CE, + 0x037, 0x00038000, + 0x038, 0x00005126, + 0x037, 0x0003C000, + 0x038, 0x00005126, + 0x037, 0x00040000, + 0x038, 0x00005126, + 0x037, 0x00044000, + 0x038, 0x00005126, + 0x037, 0x00048000, + 0x038, 0x00005126, + 0x037, 0x00080000, + 0x038, 0x00005ECE, + 0x037, 0x00084000, + 0x038, 0x00005ECE, + 0x037, 0x00088000, + 0x038, 0x00005ECE, + 0x037, 0x00090000, + 0x038, 0x00005ECE, + 0x037, 0x00094000, + 0x038, 0x00005ECE, + 0x037, 0x00098000, + 0x038, 0x00005ECE, + 0x037, 0x0009C000, + 0x038, 0x00005ECE, + 0x037, 0x000A0000, + 0x038, 0x00005ECE, + 0x037, 0x000A4000, + 0x038, 0x00005ECE, + 0x037, 0x000A8000, + 0x038, 0x00005ECE, + 0x037, 0x000AC000, + 0x038, 0x00005ECE, + 0x037, 0x000B0000, + 0x038, 0x00005ECE, + 0x037, 0x000B4000, + 0x038, 0x00005ECE, + 0x037, 0x000B8000, + 0x038, 0x00005ECE, + 0x037, 0x000BC000, + 0x038, 0x00005ECE, + 0x037, 0x000C0000, + 0x038, 0x00005ECE, + 0x037, 0x000C4000, + 0x038, 0x00005ECE, + 0x037, 0x000C8000, + 0x038, 0x00005ECE, + 0x0EF, 0x00000000, + 0xB0000000, 0x00000000, + 0x0EF, 0x00000008, + 0x80000001, 0x00000000, 0x40000000, 0x00000000, + 0x90000002, 0x00000000, 0x40000000, 0x00000000, + 0x90000003, 0x00000000, 0x40000000, 0x00000000, + 0x90000004, 0x00000000, 0x40000000, 0x00000000, + 0x90000005, 0x00000000, 0x40000000, 0x00000000, + 0x90000008, 0x00000000, 0x40000000, 0x00000000, + 0x9000000a, 0x00000000, 0x40000000, 0x00000000, + 0x9000000b, 0x00000000, 0x40000000, 0x00000000, + 0xA0000000, 0x00000000, + 0x03C, 0x0000007D, + 0x03C, 0x0000047D, + 0x03C, 0x0000087D, + 0x03C, 0x0000107D, + 0x03C, 0x0000147D, + 0x03C, 0x0000187D, + 0xB0000000, 0x00000000, + 0x80000001, 0x00000000, 0x40000000, 0x00000000, + 0x03C, 0x0000027D, + 0x03C, 0x0000054A, + 0x03C, 0x00000821, + 0x03C, 0x0000127D, + 0x03C, 0x0000154A, + 0x03C, 0x00001821, + 0x03C, 0x0000227D, + 0x03C, 0x0000254A, + 0x03C, 0x00002821, + 0x90000002, 0x00000000, 0x40000000, 0x00000000, + 0x03C, 0x0000027D, + 0x03C, 0x0000054A, + 0x03C, 0x00000821, + 0x03C, 0x0000127D, + 0x03C, 0x0000154A, + 0x03C, 0x00001821, + 0x03C, 0x0000227D, + 0x03C, 0x0000254A, + 0x03C, 0x00002821, + 0x90000003, 0x00000000, 0x40000000, 0x00000000, + 0x03C, 0x0000027D, + 0x03C, 0x0000054A, + 0x03C, 0x00000821, + 0x03C, 0x0000127D, + 0x03C, 0x0000154A, + 0x03C, 0x00001821, + 0x03C, 0x0000227D, + 0x03C, 0x0000254A, + 0x03C, 0x00002821, + 0x90000004, 0x00000000, 0x40000000, 0x00000000, + 0x03C, 0x0000027D, + 0x03C, 0x0000054A, + 0x03C, 0x00000821, + 0x03C, 0x0000127D, + 0x03C, 0x0000154A, + 0x03C, 0x00001821, + 0x03C, 0x0000227D, + 0x03C, 0x0000254A, + 0x03C, 0x00002821, + 0x90000005, 0x00000000, 0x40000000, 0x00000000, + 0x03C, 0x0000027D, + 0x03C, 0x0000054A, + 0x03C, 0x00000821, + 0x03C, 0x0000127D, + 0x03C, 0x0000154A, + 0x03C, 0x00001821, + 0x03C, 0x0000227D, + 0x03C, 0x0000254A, + 0x03C, 0x00002821, + 0x90000008, 0x00000000, 0x40000000, 0x00000000, + 0x03C, 0x0000027D, + 0x03C, 0x0000054A, + 0x03C, 0x00000821, + 0x03C, 0x0000127D, + 0x03C, 0x0000154A, + 0x03C, 0x00001821, + 0x03C, 0x0000227D, + 0x03C, 0x0000254A, + 0x03C, 0x00002821, + 0x9000000a, 0x00000000, 0x40000000, 0x00000000, + 0x03C, 0x0000027D, + 0x03C, 0x0000054A, + 0x03C, 0x00000821, + 0x03C, 0x0000127D, + 0x03C, 0x0000154A, + 0x03C, 0x00001821, + 0x03C, 0x0000227D, + 0x03C, 0x0000254A, + 0x03C, 0x00002821, + 0x9000000b, 0x00000000, 0x40000000, 0x00000000, + 0x03C, 0x0000027D, + 0x03C, 0x0000054A, + 0x03C, 0x00000821, + 0x03C, 0x0000127D, + 0x03C, 0x0000154A, + 0x03C, 0x00001821, + 0x03C, 0x0000227D, + 0x03C, 0x0000254A, + 0x03C, 0x00002821, + 0xA0000000, 0x00000000, + 0x03C, 0x0000037E, + 0x03C, 0x00000575, + 0x03C, 0x00000971, + 0x03C, 0x0000127E, + 0x03C, 0x00001575, + 0x03C, 0x00001871, + 0x03C, 0x0000217E, + 0x03C, 0x00002575, + 0x03C, 0x00002871, + 0xB0000000, 0x00000000, + 0x0EF, 0x00000000, + 0x061, 0x000C0D47, + 0x062, 0x0000133C, + 0x80000001, 0x00000000, 0x40000000, 0x00000000, + 0x063, 0x000750E7, + 0x90000002, 0x00000000, 0x40000000, 0x00000000, + 0x063, 0x000750E7, + 0x90000003, 0x00000000, 0x40000000, 0x00000000, + 0x063, 0x000750E7, + 0x90000004, 0x00000000, 0x40000000, 0x00000000, + 0x063, 0x000750E7, + 0x90000005, 0x00000000, 0x40000000, 0x00000000, + 0x063, 0x000750E7, + 0x90000008, 0x00000000, 0x40000000, 0x00000000, + 0x063, 0x000750E7, + 0x9000000a, 0x00000000, 0x40000000, 0x00000000, + 0x063, 0x000750E7, + 0x9000000b, 0x00000000, 0x40000000, 0x00000000, + 0x063, 0x000750E7, + 0xA0000000, 0x00000000, + 0x063, 0x0007D0E7, + 0xB0000000, 0x00000000, + 0x064, 0x00014FEC, + 0x80000001, 0x00000000, 0x40000000, 0x00000000, + 0x065, 0x000920D0, + 0x90000002, 0x00000000, 0x40000000, 0x00000000, + 0x065, 0x000920D0, + 0x90000003, 0x00000000, 0x40000000, 0x00000000, + 0x065, 0x000920D0, + 0x90000004, 0x00000000, 0x40000000, 0x00000000, + 0x065, 0x000920D0, + 0x90000005, 0x00000000, 0x40000000, 0x00000000, + 0x065, 0x000920D0, + 0x90000008, 0x00000000, 0x40000000, 0x00000000, + 0x065, 0x000920D0, + 0x9000000a, 0x00000000, 0x40000000, 0x00000000, + 0x065, 0x000920D0, + 0x9000000b, 0x00000000, 0x40000000, 0x00000000, + 0x065, 0x000920D0, + 0xA0000000, 0x00000000, + 0x065, 0x000933FF, + 0xB0000000, 0x00000000, + 0x066, 0x00000040, + 0x057, 0x00050000, + 0x056, 0x00051DF0, + 0x80000001, 0x00000000, 0x40000000, 0x00000000, + 0x055, 0x00082061, + 0x90000002, 0x00000000, 0x40000000, 0x00000000, + 0x055, 0x00082061, + 0x90000003, 0x00000000, 0x40000000, 0x00000000, + 0x055, 0x00082061, + 0x90000004, 0x00000000, 0x40000000, 0x00000000, + 0x055, 0x00082061, + 0x90000005, 0x00000000, 0x40000000, 0x00000000, + 0x055, 0x00082061, + 0x90000008, 0x00000000, 0x40000000, 0x00000000, + 0x055, 0x00082061, + 0x9000000a, 0x00000000, 0x40000000, 0x00000000, + 0x055, 0x00082061, + 0x9000000b, 0x00000000, 0x40000000, 0x00000000, + 0x055, 0x00082061, + 0xA0000000, 0x00000000, + 0x055, 0x00082060, + 0xB0000000, 0x00000000, + 0x01C, 0x000739D2, + 0x80000001, 0x00000000, 0x40000000, 0x00000000, + 0x01F, 0x0002255C, + 0x90000004, 0x00000000, 0x40000000, 0x00000000, + 0x01F, 0x0002255C, + 0x9000000a, 0x00000000, 0x40000000, 0x00000000, + 0x01F, 0x0002255C, + 0x9000000b, 0x00000000, 0x40000000, 0x00000000, + 0x01F, 0x0002255C, + 0xA0000000, 0x00000000, + 0x01F, 0x0002255C, + 0xB0000000, 0x00000000, + 0x0B1, 0x0007FF48, + 0x80000001, 0x00000000, 0x40000000, 0x00000000, + 0x0C4, 0x00081700, + 0x90000002, 0x00000000, 0x40000000, 0x00000000, + 0x0C4, 0x00081700, + 0x90000003, 0x00000000, 0x40000000, 0x00000000, + 0x0C4, 0x00081700, + 0x90000004, 0x00000000, 0x40000000, 0x00000000, + 0x0C4, 0x00081700, + 0x90000005, 0x00000000, 0x40000000, 0x00000000, + 0x0C4, 0x00081700, + 0x90000006, 0x00000000, 0x40000000, 0x00000000, + 0x0C4, 0x00081700, + 0x90000008, 0x00000000, 0x40000000, 0x00000000, + 0x0C4, 0x00081700, + 0x9000000a, 0x00000000, 0x40000000, 0x00000000, + 0x0C4, 0x00081700, + 0x9000000b, 0x00000000, 0x40000000, 0x00000000, + 0x0C4, 0x00081700, + 0xA0000000, 0x00000000, + 0x0C4, 0x00083F00, + 0xB0000000, 0x00000000, + 0x018, 0x0001B126, + 0xFFE, 0x00000000, + 0xFFE, 0x00000000, + 0xFFE, 0x00000000, + 0x018, 0x00013126, + 0x018, 0x00013124, +}; + +RTW_DECL_TABLE_RF_RADIO(rtw8814a_rf_a, A); + +static const u32 rtw8814a_rf_b[] = { + 0x018, 0x00013124, + 0x040, 0x00000C00, + 0x058, 0x00000F98, + 0x07F, 0x00068004, + 0x018, 0x00000006, + 0x80000002, 0x00000000, 0x40000000, 0x00000000, + 0x086, 0x000E335A, + 0x087, 0x00079F80, + 0x90000003, 0x00000000, 0x40000000, 0x00000000, + 0x086, 0x000E335A, + 0x087, 0x00079F80, + 0x90000004, 0x00000000, 0x40000000, 0x00000000, + 0x086, 0x000E335A, + 0x087, 0x00079F80, + 0x90000005, 0x00000000, 0x40000000, 0x00000000, + 0x086, 0x000E335A, + 0x087, 0x00079F80, + 0x90000008, 0x00000000, 0x40000000, 0x00000000, + 0x086, 0x000E335A, + 0x087, 0x00079F80, + 0x9000000a, 0x00000000, 0x40000000, 0x00000000, + 0x086, 0x000E335A, + 0x087, 0x00079F80, + 0x9000000b, 0x00000000, 0x40000000, 0x00000000, + 0x086, 0x000E335A, + 0x087, 0x00079F80, + 0xA0000000, 0x00000000, + 0x086, 0x000E4B58, + 0x087, 0x00049F80, + 0xB0000000, 0x00000000, + 0x0DF, 0x00000008, + 0x0EF, 0x00002000, + 0x80000002, 0x00000000, 0x40000000, 0x00000000, + 0x03B, 0x0003F19B, + 0x03B, 0x00037A5B, + 0x03B, 0x0002A433, + 0x03B, 0x00027BD3, + 0x03B, 0x0001F80B, + 0x03B, 0x00017BC3, + 0x90000003, 0x00000000, 0x40000000, 0x00000000, + 0x03B, 0x0003F39B, + 0x03B, 0x00037A5B, + 0x03B, 0x0002A433, + 0x03B, 0x00027BD3, + 0x03B, 0x0001F80B, + 0x03B, 0x00017BC3, + 0x90000004, 0x00000000, 0x40000000, 0x00000000, + 0x03B, 0x0003F19B, + 0x03B, 0x00037A5B, + 0x03B, 0x0002A433, + 0x03B, 0x00027BD3, + 0x03B, 0x0001F80B, + 0x03B, 0x00017BC3, + 0x90000005, 0x00000000, 0x40000000, 0x00000000, + 0x03B, 0x0003F39B, + 0x03B, 0x00037A5B, + 0x03B, 0x0002A433, + 0x03B, 0x00027BD3, + 0x03B, 0x0001F80B, + 0x03B, 0x00017BC3, + 0x90000008, 0x00000000, 0x40000000, 0x00000000, + 0x03B, 0x0003F19B, + 0x03B, 0x00037A5B, + 0x03B, 0x0002A433, + 0x03B, 0x00027BD3, + 0x03B, 0x0001F80B, + 0x03B, 0x00017BC3, + 0x9000000a, 0x00000000, 0x40000000, 0x00000000, + 0x03B, 0x0003F19B, + 0x03B, 0x00037A5B, + 0x03B, 0x0002A433, + 0x03B, 0x00027BD3, + 0x03B, 0x0001F80B, + 0x03B, 0x00017BC3, + 0x9000000b, 0x00000000, 0x40000000, 0x00000000, + 0x03B, 0x0003F19B, + 0x03B, 0x00037A5B, + 0x03B, 0x0002A433, + 0x03B, 0x00027BD3, + 0x03B, 0x0001F80B, + 0x03B, 0x00017BC3, + 0xA0000000, 0x00000000, + 0x03B, 0x0003F258, + 0x03B, 0x00030A58, + 0x03B, 0x0002FA58, + 0x03B, 0x00022590, + 0x03B, 0x0001FA50, + 0x03B, 0x00010248, + 0x03B, 0x00008240, + 0xB0000000, 0x00000000, + 0x0EF, 0x00000100, + 0x80000002, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x0000A0D0, + 0x034, 0x000090CD, + 0x034, 0x000080CA, + 0x034, 0x0000704D, + 0x034, 0x0000604A, + 0x034, 0x00005047, + 0x034, 0x0000400A, + 0x034, 0x00003007, + 0x034, 0x00002004, + 0x034, 0x00001001, + 0x034, 0x00000001, + 0x90000003, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x0000A0D0, + 0x034, 0x000090CD, + 0x034, 0x000080CA, + 0x034, 0x0000704D, + 0x034, 0x0000604A, + 0x034, 0x00005047, + 0x034, 0x0000400A, + 0x034, 0x00003007, + 0x034, 0x00002004, + 0x034, 0x00001001, + 0x034, 0x00000001, + 0x90000004, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x0000A0D0, + 0x034, 0x000090CD, + 0x034, 0x000080CA, + 0x034, 0x0000704D, + 0x034, 0x0000604A, + 0x034, 0x00005047, + 0x034, 0x0000400A, + 0x034, 0x00003007, + 0x034, 0x00002004, + 0x034, 0x00001001, + 0x034, 0x00000001, + 0x90000005, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x0000A0D0, + 0x034, 0x000090CD, + 0x034, 0x000080CA, + 0x034, 0x0000704D, + 0x034, 0x0000604A, + 0x034, 0x00005047, + 0x034, 0x0000400A, + 0x034, 0x00003007, + 0x034, 0x00002004, + 0x034, 0x00001001, + 0x034, 0x00000001, + 0x90000008, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x0000A0D0, + 0x034, 0x000090CD, + 0x034, 0x000080CA, + 0x034, 0x0000704D, + 0x034, 0x0000604A, + 0x034, 0x00005047, + 0x034, 0x0000400A, + 0x034, 0x00003007, + 0x034, 0x00002004, + 0x034, 0x00001001, + 0x034, 0x00000001, + 0x9000000a, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x0000A0D0, + 0x034, 0x000090CD, + 0x034, 0x000080CA, + 0x034, 0x0000704D, + 0x034, 0x0000604A, + 0x034, 0x00005047, + 0x034, 0x0000400A, + 0x034, 0x00003007, + 0x034, 0x00002004, + 0x034, 0x00001001, + 0x034, 0x00000001, + 0x9000000b, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x0000A0D0, + 0x034, 0x000090CD, + 0x034, 0x000080CA, + 0x034, 0x0000704D, + 0x034, 0x0000604A, + 0x034, 0x00005047, + 0x034, 0x0000400A, + 0x034, 0x00003007, + 0x034, 0x00002004, + 0x034, 0x00001001, + 0x034, 0x00000001, + 0xA0000000, 0x00000000, + 0x034, 0x0000ADF6, + 0x034, 0x00009DF3, + 0x034, 0x00008DF0, + 0x034, 0x00007DED, + 0x034, 0x00006DEA, + 0x034, 0x00005CED, + 0x034, 0x00004CEA, + 0x034, 0x000034EA, + 0x034, 0x000024E7, + 0x034, 0x0000146A, + 0x034, 0x0000006B, + 0xB0000000, 0x00000000, + 0x80000002, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x0000A0D0, + 0x034, 0x000090CD, + 0x034, 0x000080CA, + 0x034, 0x0000704D, + 0x034, 0x0000604A, + 0x034, 0x00005047, + 0x034, 0x0000400A, + 0x034, 0x00003007, + 0x034, 0x00002004, + 0x034, 0x00001001, + 0x034, 0x00000001, + 0x90000003, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x0000A0D0, + 0x034, 0x000090CD, + 0x034, 0x000080CA, + 0x034, 0x0000704D, + 0x034, 0x0000604A, + 0x034, 0x00005047, + 0x034, 0x0000400A, + 0x034, 0x00003007, + 0x034, 0x00002004, + 0x034, 0x00001001, + 0x034, 0x00000001, + 0x90000004, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x0000A0D0, + 0x034, 0x000090CD, + 0x034, 0x000080CA, + 0x034, 0x0000704D, + 0x034, 0x0000604A, + 0x034, 0x00005047, + 0x034, 0x0000400A, + 0x034, 0x00003007, + 0x034, 0x00002004, + 0x034, 0x00001001, + 0x034, 0x00000001, + 0x90000005, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x0000A0D0, + 0x034, 0x000090CD, + 0x034, 0x000080CA, + 0x034, 0x0000704D, + 0x034, 0x0000604A, + 0x034, 0x00005047, + 0x034, 0x0000400A, + 0x034, 0x00003007, + 0x034, 0x00002004, + 0x034, 0x00001001, + 0x034, 0x00000001, + 0x90000008, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x0000A0D0, + 0x034, 0x000090CD, + 0x034, 0x000080CA, + 0x034, 0x0000704D, + 0x034, 0x0000604A, + 0x034, 0x00005047, + 0x034, 0x0000400A, + 0x034, 0x00003007, + 0x034, 0x00002004, + 0x034, 0x00001001, + 0x034, 0x00000001, + 0x9000000a, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x0000A0D0, + 0x034, 0x000090CD, + 0x034, 0x000080CA, + 0x034, 0x0000704D, + 0x034, 0x0000604A, + 0x034, 0x00005047, + 0x034, 0x0000400A, + 0x034, 0x00003007, + 0x034, 0x00002004, + 0x034, 0x00001001, + 0x034, 0x00000001, + 0x9000000b, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x0000A0D0, + 0x034, 0x000090CD, + 0x034, 0x000080CA, + 0x034, 0x0000704D, + 0x034, 0x0000604A, + 0x034, 0x00005047, + 0x034, 0x0000400A, + 0x034, 0x00003007, + 0x034, 0x00002004, + 0x034, 0x00001001, + 0x034, 0x00000001, + 0xA0000000, 0x00000000, + 0x034, 0x0008ADF6, + 0x034, 0x00089DF3, + 0x034, 0x00088DF0, + 0x034, 0x00087DED, + 0x034, 0x00086DEA, + 0x034, 0x00085CED, + 0x034, 0x00084CEA, + 0x034, 0x000834EA, + 0x034, 0x000824E7, + 0x034, 0x0008146A, + 0x034, 0x0008006B, + 0xB0000000, 0x00000000, + 0x0EF, 0x00000000, + 0x0EF, 0x000020A2, + 0x0DF, 0x00000080, + 0x035, 0x00000192, + 0x035, 0x00008192, + 0x035, 0x00010192, + 0x036, 0x00000024, + 0x036, 0x00008024, + 0x036, 0x00010024, + 0x036, 0x00018024, + 0x0EF, 0x00000000, + 0x051, 0x00000C21, + 0x052, 0x000006D9, + 0x053, 0x000FC649, + 0x054, 0x0000017E, + 0x018, 0x0001012A, + 0x081, 0x0007FC00, + 0x089, 0x00050110, + 0x08A, 0x00043E50, + 0x08B, 0x0002E180, + 0x08C, 0x00093C3C, + 0x80000001, 0x00000000, 0x40000000, 0x00000000, + 0x085, 0x000F8000, + 0x90000006, 0x00000000, 0x40000000, 0x00000000, + 0x085, 0x000F8000, + 0xA0000000, 0x00000000, + 0x085, 0x000F8000, + 0xB0000000, 0x00000000, + 0x08D, 0x000FFFF0, + 0x0EF, 0x00001000, + 0x03A, 0x0000013C, + 0x03B, 0x00038023, + 0x80000001, 0x00000000, 0x40000000, 0x00000000, + 0x03C, 0x00088000, + 0x90000002, 0x00000000, 0x40000000, 0x00000000, + 0x03C, 0x00084000, + 0x90000003, 0x00000000, 0x40000000, 0x00000000, + 0x03C, 0x00000000, + 0x90000004, 0x00000000, 0x40000000, 0x00000000, + 0x03C, 0x00088000, + 0x90000005, 0x00000000, 0x40000000, 0x00000000, + 0x03C, 0x00000000, + 0x90000006, 0x00000000, 0x40000000, 0x00000000, + 0x03C, 0x00088000, + 0x90000008, 0x00000000, 0x40000000, 0x00000000, + 0x03C, 0x00088000, + 0x9000000a, 0x00000000, 0x40000000, 0x00000000, + 0x03C, 0x00088000, + 0x9000000b, 0x00000000, 0x40000000, 0x00000000, + 0x03C, 0x00088000, + 0xA0000000, 0x00000000, + 0x03C, 0x00040000, + 0xB0000000, 0x00000000, + 0x03A, 0x0000013C, + 0x03B, 0x00030023, + 0x03C, 0x00048000, + 0x03A, 0x0000013C, + 0x03B, 0x00028623, + 0x03C, 0x00000000, + 0x03A, 0x0000013C, + 0x03B, 0x00021633, + 0x03C, 0x00000000, + 0x03A, 0x0000013C, + 0x03B, 0x0001C633, + 0x03C, 0x00000000, + 0x03A, 0x0000013C, + 0x03B, 0x00010293, + 0x03C, 0x00000000, + 0x03A, 0x0000013C, + 0x03B, 0x00009593, + 0x03C, 0x00000000, + 0x03A, 0x00000148, + 0x80000008, 0x00000000, 0x40000000, 0x00000000, + 0x03B, 0x00000F8B, + 0xA0000000, 0x00000000, + 0x03B, 0x0000078B, + 0xB0000000, 0x00000000, + 0x03C, 0x00000000, + 0x80000001, 0x00000000, 0x40000000, 0x00000000, + 0x03A, 0x0000013C, + 0x03B, 0x00078023, + 0x90000002, 0x00000000, 0x40000000, 0x00000000, + 0x03A, 0x0000013C, + 0x03B, 0x00078023, + 0x90000003, 0x00000000, 0x40000000, 0x00000000, + 0x03A, 0x0000013C, + 0x03B, 0x00078023, + 0x90000004, 0x00000000, 0x40000000, 0x00000000, + 0x03A, 0x0000013C, + 0x03B, 0x00078023, + 0x90000005, 0x00000000, 0x40000000, 0x00000000, + 0x03A, 0x0000013C, + 0x03B, 0x00078023, + 0x90000006, 0x00000000, 0x40000000, 0x00000000, + 0x03A, 0x0000013C, + 0x03B, 0x00078023, + 0x90000008, 0x00000000, 0x40000000, 0x00000000, + 0x03A, 0x0000013C, + 0x03B, 0x00078023, + 0x9000000a, 0x00000000, 0x40000000, 0x00000000, + 0x03A, 0x0000013C, + 0x03B, 0x00078023, + 0x9000000b, 0x00000000, 0x40000000, 0x00000000, + 0x03A, 0x0000013C, + 0x03B, 0x00078023, + 0xA0000000, 0x00000000, + 0x03A, 0x0000013C, + 0x03B, 0x00078023, + 0xB0000000, 0x00000000, + 0x80000001, 0x00000000, 0x40000000, 0x00000000, + 0x03C, 0x00020000, + 0x90000002, 0x00000000, 0x40000000, 0x00000000, + 0x03C, 0x00060000, + 0x90000003, 0x00000000, 0x40000000, 0x00000000, + 0x03C, 0x00000000, + 0x90000004, 0x00000000, 0x40000000, 0x00000000, + 0x03C, 0x00048000, + 0x90000005, 0x00000000, 0x40000000, 0x00000000, + 0x03C, 0x00048000, + 0x90000006, 0x00000000, 0x40000000, 0x00000000, + 0x03C, 0x00020000, + 0x90000007, 0x00000000, 0x40000000, 0x00000000, + 0x03C, 0x00000000, + 0x90000008, 0x00000000, 0x40000000, 0x00000000, + 0x03C, 0x00088000, + 0x90000009, 0x00000000, 0x40000000, 0x00000000, + 0x03C, 0x00000000, + 0x9000000a, 0x00000000, 0x40000000, 0x00000000, + 0x03C, 0x00048000, + 0x9000000b, 0x00000000, 0x40000000, 0x00000000, + 0x03C, 0x00048000, + 0xA0000000, 0x00000000, + 0x03C, 0x00020000, + 0xB0000000, 0x00000000, + 0x03A, 0x0000013C, + 0x03B, 0x00070023, + 0x03C, 0x00048000, + 0x03A, 0x0000013C, + 0x03B, 0x00068623, + 0x03C, 0x00000000, + 0x03A, 0x0000013C, + 0x03B, 0x00061633, + 0x03C, 0x00000000, + 0x03A, 0x0000013C, + 0x03B, 0x0005C633, + 0x03C, 0x00000000, + 0x03A, 0x0000013C, + 0x03B, 0x00050293, + 0x03C, 0x00000000, + 0x03A, 0x0000013C, + 0x03B, 0x00049593, + 0x03C, 0x00000000, + 0x03A, 0x00000148, + 0x03B, 0x0004078B, + 0x03C, 0x00000000, + 0x80000001, 0x00000000, 0x40000000, 0x00000000, + 0x03A, 0x0000013C, + 0x03B, 0x000B8023, + 0x90000002, 0x00000000, 0x40000000, 0x00000000, + 0x03A, 0x0000013C, + 0x03B, 0x000B8023, + 0x90000003, 0x00000000, 0x40000000, 0x00000000, + 0x03A, 0x0000013C, + 0x03B, 0x000B8023, + 0x90000004, 0x00000000, 0x40000000, 0x00000000, + 0x03A, 0x0000013C, + 0x03B, 0x000B8023, + 0x90000005, 0x00000000, 0x40000000, 0x00000000, + 0x03A, 0x0000013C, + 0x03B, 0x000B8023, + 0x90000006, 0x00000000, 0x40000000, 0x00000000, + 0x03A, 0x0000013C, + 0x03B, 0x000B8023, + 0x90000008, 0x00000000, 0x40000000, 0x00000000, + 0x03A, 0x0000013C, + 0x03B, 0x000B8023, + 0x9000000a, 0x00000000, 0x40000000, 0x00000000, + 0x03A, 0x0000013C, + 0x03B, 0x000B8023, + 0x9000000b, 0x00000000, 0x40000000, 0x00000000, + 0x03A, 0x0000013C, + 0x03B, 0x000B8023, + 0xA0000000, 0x00000000, + 0x03A, 0x0000013C, + 0x03B, 0x000B8023, + 0xB0000000, 0x00000000, + 0x80000001, 0x00000000, 0x40000000, 0x00000000, + 0x03C, 0x00048000, + 0x90000002, 0x00000000, 0x40000000, 0x00000000, + 0x03C, 0x00060000, + 0x90000003, 0x00000000, 0x40000000, 0x00000000, + 0x03C, 0x0004C000, + 0x90000004, 0x00000000, 0x40000000, 0x00000000, + 0x03C, 0x00044000, + 0x90000005, 0x00000000, 0x40000000, 0x00000000, + 0x03C, 0x0004C000, + 0x90000006, 0x00000000, 0x40000000, 0x00000000, + 0x03C, 0x00048000, + 0x90000007, 0x00000000, 0x40000000, 0x00000000, + 0x03C, 0x00000000, + 0x90000008, 0x00000000, 0x40000000, 0x00000000, + 0x03C, 0x00020000, + 0x90000009, 0x00000000, 0x40000000, 0x00000000, + 0x03C, 0x00004000, + 0x9000000a, 0x00000000, 0x40000000, 0x00000000, + 0x03C, 0x00044000, + 0x9000000b, 0x00000000, 0x40000000, 0x00000000, + 0x03C, 0x00044000, + 0xA0000000, 0x00000000, + 0x03C, 0x00020000, + 0xB0000000, 0x00000000, + 0x03A, 0x0000013C, + 0x03B, 0x000B0023, + 0x80000004, 0x00000000, 0x40000000, 0x00000000, + 0x03C, 0x00020000, + 0x9000000a, 0x00000000, 0x40000000, 0x00000000, + 0x03C, 0x00020000, + 0x9000000b, 0x00000000, 0x40000000, 0x00000000, + 0x03C, 0x00020000, + 0xA0000000, 0x00000000, + 0x03C, 0x00020000, + 0xB0000000, 0x00000000, + 0x03A, 0x0000013C, + 0x03B, 0x000A8623, + 0x03C, 0x00000000, + 0x03A, 0x0000013C, + 0x03B, 0x000A1633, + 0x03C, 0x00000000, + 0x03A, 0x0000013C, + 0x03B, 0x0009C633, + 0x03C, 0x00000000, + 0x03A, 0x0000013C, + 0x03B, 0x00090293, + 0x03C, 0x00000000, + 0x03A, 0x0000013C, + 0x03B, 0x00089593, + 0x03C, 0x00000000, + 0x03A, 0x00000148, + 0x80000008, 0x00000000, 0x40000000, 0x00000000, + 0x03B, 0x0008138B, + 0xA0000000, 0x00000000, + 0x03B, 0x0008078B, + 0xB0000000, 0x00000000, + 0x03C, 0x00000000, + 0x0EF, 0x00000000, + 0x0EF, 0x00000800, + 0x03B, 0x00000000, + 0x80000001, 0x00000000, 0x40000000, 0x00000000, + 0x03A, 0x00000803, + 0x90000006, 0x00000000, 0x40000000, 0x00000000, + 0x03A, 0x00000803, + 0x90000007, 0x00000000, 0x40000000, 0x00000000, + 0x03A, 0x00001003, + 0x90000008, 0x00000000, 0x40000000, 0x00000000, + 0x03A, 0x00001003, + 0x90000009, 0x00000000, 0x40000000, 0x00000000, + 0x03A, 0x00001003, + 0xA0000000, 0x00000000, + 0x03A, 0x00000803, + 0xB0000000, 0x00000000, + 0x03B, 0x00040000, + 0x80000001, 0x00000000, 0x40000000, 0x00000000, + 0x03A, 0x00001000, + 0x90000002, 0x00000000, 0x40000000, 0x00000000, + 0x03A, 0x00001001, + 0x90000003, 0x00000000, 0x40000000, 0x00000000, + 0x03A, 0x00000803, + 0x90000005, 0x00000000, 0x40000000, 0x00000000, + 0x03A, 0x00001003, + 0x90000006, 0x00000000, 0x40000000, 0x00000000, + 0x03A, 0x00001000, + 0x90000007, 0x00000000, 0x40000000, 0x00000000, + 0x03A, 0x00000000, + 0x90000008, 0x00000000, 0x40000000, 0x00000000, + 0x03A, 0x00000800, + 0x90000009, 0x00000000, 0x40000000, 0x00000000, + 0x03A, 0x00000800, + 0xA0000000, 0x00000000, + 0x03A, 0x00001000, + 0xB0000000, 0x00000000, + 0x03B, 0x00080000, + 0x80000003, 0x00000000, 0x40000000, 0x00000000, + 0x03A, 0x00000000, + 0x90000005, 0x00000000, 0x40000000, 0x00000000, + 0x03A, 0x00000000, + 0x90000007, 0x00000000, 0x40000000, 0x00000000, + 0x03A, 0x00001802, + 0x90000009, 0x00000000, 0x40000000, 0x00000000, + 0x03A, 0x00001802, + 0xA0000000, 0x00000000, + 0x03A, 0x00001002, + 0xB0000000, 0x00000000, + 0x0EF, 0x00000000, + 0x80000001, 0x00000000, 0x40000000, 0x00000000, + 0x90000002, 0x00000000, 0x40000000, 0x00000000, + 0x90000003, 0x00000000, 0x40000000, 0x00000000, + 0x90000004, 0x00000000, 0x40000000, 0x00000000, + 0x90000005, 0x00000000, 0x40000000, 0x00000000, + 0x90000006, 0x00000000, 0x40000000, 0x00000000, + 0x90000008, 0x00000000, 0x40000000, 0x00000000, + 0x9000000a, 0x00000000, 0x40000000, 0x00000000, + 0x9000000b, 0x00000000, 0x40000000, 0x00000000, + 0xA0000000, 0x00000000, + 0xB0000000, 0x00000000, + 0x018, 0x00013124, + 0x0EF, 0x00000100, + 0x80000001, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x0004A38C, + 0x034, 0x000491AD, + 0x034, 0x000481AA, + 0x034, 0x000471A7, + 0x034, 0x000460AA, + 0x034, 0x000450A7, + 0x034, 0x0004402C, + 0x034, 0x00043029, + 0x034, 0x0004200C, + 0x034, 0x00041009, + 0x034, 0x00040006, + 0x90000002, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x0004A38C, + 0x034, 0x00049389, + 0x034, 0x0004816D, + 0x034, 0x0004716A, + 0x034, 0x0004606D, + 0x034, 0x0004506A, + 0x034, 0x0004402C, + 0x034, 0x00043029, + 0x034, 0x00042026, + 0x034, 0x00041009, + 0x034, 0x00040006, + 0x90000003, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x0004A38B, + 0x034, 0x00049388, + 0x034, 0x0004818B, + 0x034, 0x00047188, + 0x034, 0x0004606D, + 0x034, 0x0004506A, + 0x034, 0x0004402C, + 0x034, 0x00043029, + 0x034, 0x00042026, + 0x034, 0x00041009, + 0x034, 0x00040006, + 0x90000004, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x0004A38C, + 0x034, 0x00049389, + 0x034, 0x0004816D, + 0x034, 0x0004716A, + 0x034, 0x0004606D, + 0x034, 0x0004506A, + 0x034, 0x0004402C, + 0x034, 0x00043029, + 0x034, 0x00042026, + 0x034, 0x00041009, + 0x034, 0x00040006, + 0x90000005, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x0004A38B, + 0x034, 0x00049388, + 0x034, 0x0004818B, + 0x034, 0x00047188, + 0x034, 0x0004606D, + 0x034, 0x0004506A, + 0x034, 0x0004402C, + 0x034, 0x00043029, + 0x034, 0x00042026, + 0x034, 0x00041009, + 0x034, 0x00040006, + 0x90000008, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x0004A3F5, + 0x034, 0x000493F3, + 0x034, 0x000483B2, + 0x034, 0x00047390, + 0x034, 0x0004638D, + 0x034, 0x0004538A, + 0x034, 0x00044387, + 0x034, 0x0004324A, + 0x034, 0x00042247, + 0x034, 0x0004104D, + 0x034, 0x0004004A, + 0x90000009, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x0004AFF7, + 0x034, 0x00049FF6, + 0x034, 0x00048FF3, + 0x034, 0x00047FF0, + 0x034, 0x00046FED, + 0x034, 0x00045FEA, + 0x034, 0x00044FE7, + 0x034, 0x00043DEA, + 0x034, 0x00042DE7, + 0x034, 0x00041DE4, + 0x034, 0x00040CE7, + 0x9000000a, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x0004A38C, + 0x034, 0x00049389, + 0x034, 0x0004816D, + 0x034, 0x0004716A, + 0x034, 0x0004606D, + 0x034, 0x0004506A, + 0x034, 0x0004402C, + 0x034, 0x00043029, + 0x034, 0x00042026, + 0x034, 0x00041009, + 0x034, 0x00040006, + 0x9000000b, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x0004A38C, + 0x034, 0x00049389, + 0x034, 0x0004816D, + 0x034, 0x0004716A, + 0x034, 0x0004606D, + 0x034, 0x0004506A, + 0x034, 0x0004402C, + 0x034, 0x00043029, + 0x034, 0x00042026, + 0x034, 0x00041009, + 0x034, 0x00040006, + 0xA0000000, 0x00000000, + 0x034, 0x0004AFF4, + 0x034, 0x00049FF1, + 0x034, 0x00048FEE, + 0x034, 0x00047FEB, + 0x034, 0x00046FE8, + 0x034, 0x00045DEA, + 0x034, 0x00044CED, + 0x034, 0x00043CEA, + 0x034, 0x00042C6C, + 0x034, 0x00041C69, + 0x034, 0x00040C2B, + 0xB0000000, 0x00000000, + 0x80000001, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x0002A38C, + 0x034, 0x000291AD, + 0x034, 0x000281AA, + 0x034, 0x000271A7, + 0x034, 0x000260AA, + 0x034, 0x000250A7, + 0x034, 0x0002402C, + 0x034, 0x00023029, + 0x034, 0x0002200C, + 0x034, 0x00021009, + 0x034, 0x00020006, + 0x90000002, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x0002A3EE, + 0x034, 0x000293AC, + 0x034, 0x00028389, + 0x034, 0x0002716D, + 0x034, 0x0002616A, + 0x034, 0x0002506D, + 0x034, 0x0002406A, + 0x034, 0x0002302C, + 0x034, 0x00022029, + 0x034, 0x00021026, + 0x034, 0x00020023, + 0x90000003, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x0002A3EF, + 0x034, 0x000293AD, + 0x034, 0x0002838A, + 0x034, 0x0002718C, + 0x034, 0x00026189, + 0x034, 0x0002506D, + 0x034, 0x0002406A, + 0x034, 0x0002302C, + 0x034, 0x00022029, + 0x034, 0x00021026, + 0x034, 0x00020023, + 0x90000004, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x0002A3EE, + 0x034, 0x000293AC, + 0x034, 0x00028389, + 0x034, 0x0002716D, + 0x034, 0x0002616A, + 0x034, 0x0002506D, + 0x034, 0x0002406A, + 0x034, 0x0002302C, + 0x034, 0x00022029, + 0x034, 0x00021026, + 0x034, 0x00020023, + 0x90000005, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x0002A3EF, + 0x034, 0x000293AD, + 0x034, 0x0002838A, + 0x034, 0x0002718C, + 0x034, 0x00026189, + 0x034, 0x0002506D, + 0x034, 0x0002406A, + 0x034, 0x0002302C, + 0x034, 0x00022029, + 0x034, 0x00021026, + 0x034, 0x00020023, + 0x90000008, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x0002A3F5, + 0x034, 0x000293F3, + 0x034, 0x000283D0, + 0x034, 0x00027371, + 0x034, 0x0002636E, + 0x034, 0x0002536B, + 0x034, 0x00024368, + 0x034, 0x0002332A, + 0x034, 0x00022327, + 0x034, 0x0002104C, + 0x034, 0x00020049, + 0x90000009, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x0002AFF7, + 0x034, 0x00029FF6, + 0x034, 0x00028FF3, + 0x034, 0x00027FF0, + 0x034, 0x00026FED, + 0x034, 0x00025FEA, + 0x034, 0x00024FE7, + 0x034, 0x00023DEA, + 0x034, 0x00022DE7, + 0x034, 0x00021DE4, + 0x034, 0x00020F25, + 0x9000000a, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x0002A3EE, + 0x034, 0x000293AC, + 0x034, 0x00028389, + 0x034, 0x0002716D, + 0x034, 0x0002616A, + 0x034, 0x0002506D, + 0x034, 0x0002406A, + 0x034, 0x0002302C, + 0x034, 0x00022029, + 0x034, 0x00021026, + 0x034, 0x00020023, + 0x9000000b, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x0002A3EE, + 0x034, 0x000293AC, + 0x034, 0x00028389, + 0x034, 0x0002716D, + 0x034, 0x0002616A, + 0x034, 0x0002506D, + 0x034, 0x0002406A, + 0x034, 0x0002302C, + 0x034, 0x00022029, + 0x034, 0x00021026, + 0x034, 0x00020023, + 0xA0000000, 0x00000000, + 0x034, 0x0002AFF4, + 0x034, 0x00029FF1, + 0x034, 0x00028FEE, + 0x034, 0x00027FEB, + 0x034, 0x00026FE8, + 0x034, 0x00025DEA, + 0x034, 0x00024CED, + 0x034, 0x00023CEA, + 0x034, 0x00022C6C, + 0x034, 0x00021C69, + 0x034, 0x00020C2B, + 0xB0000000, 0x00000000, + 0x80000001, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x0000A38C, + 0x034, 0x000091AD, + 0x034, 0x000081AA, + 0x034, 0x000071A7, + 0x034, 0x000060AA, + 0x034, 0x000050A7, + 0x034, 0x0000402C, + 0x034, 0x00003029, + 0x034, 0x00002026, + 0x034, 0x00001009, + 0x034, 0x00000006, + 0x90000002, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x0000A3EC, + 0x034, 0x000093AC, + 0x034, 0x000081EC, + 0x034, 0x0000716D, + 0x034, 0x0000616A, + 0x034, 0x0000506D, + 0x034, 0x0000404C, + 0x034, 0x0000302C, + 0x034, 0x00002029, + 0x034, 0x00001026, + 0x034, 0x00000023, + 0x90000003, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x0000A3EF, + 0x034, 0x000093AD, + 0x034, 0x0000838A, + 0x034, 0x0000718C, + 0x034, 0x00006189, + 0x034, 0x0000506D, + 0x034, 0x0000406A, + 0x034, 0x0000302C, + 0x034, 0x00002029, + 0x034, 0x00001026, + 0x034, 0x00000023, + 0x90000004, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x0000A3EC, + 0x034, 0x000093AC, + 0x034, 0x000081EC, + 0x034, 0x0000716D, + 0x034, 0x0000616A, + 0x034, 0x0000506D, + 0x034, 0x0000404C, + 0x034, 0x0000302C, + 0x034, 0x00002029, + 0x034, 0x00001026, + 0x034, 0x00000023, + 0x90000005, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x0000A3EF, + 0x034, 0x000093AD, + 0x034, 0x0000838A, + 0x034, 0x0000718C, + 0x034, 0x00006189, + 0x034, 0x0000506D, + 0x034, 0x0000406A, + 0x034, 0x0000302C, + 0x034, 0x00002029, + 0x034, 0x00001026, + 0x034, 0x00000023, + 0x90000008, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x0000A3F4, + 0x034, 0x000093F0, + 0x034, 0x000083AE, + 0x034, 0x00007350, + 0x034, 0x0000634D, + 0x034, 0x0000534A, + 0x034, 0x00004347, + 0x034, 0x0000312D, + 0x034, 0x0000212A, + 0x034, 0x00001127, + 0x034, 0x0000002A, + 0x90000009, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x0000AFF7, + 0x034, 0x00009FF4, + 0x034, 0x00008FF1, + 0x034, 0x00007FEE, + 0x034, 0x00006FEB, + 0x034, 0x00005FE8, + 0x034, 0x00004DEB, + 0x034, 0x00003DE8, + 0x034, 0x00002DE5, + 0x034, 0x00001C8B, + 0x034, 0x00000C88, + 0x9000000a, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x0000A3EC, + 0x034, 0x000093AC, + 0x034, 0x000081EC, + 0x034, 0x0000716D, + 0x034, 0x0000616A, + 0x034, 0x0000506D, + 0x034, 0x0000404C, + 0x034, 0x0000302C, + 0x034, 0x00002029, + 0x034, 0x00001026, + 0x034, 0x00000023, + 0x9000000b, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x0000A3EC, + 0x034, 0x000093AC, + 0x034, 0x000081EC, + 0x034, 0x0000716D, + 0x034, 0x0000616A, + 0x034, 0x0000506D, + 0x034, 0x0000404C, + 0x034, 0x0000302C, + 0x034, 0x00002029, + 0x034, 0x00001026, + 0x034, 0x00000023, + 0xA0000000, 0x00000000, + 0x034, 0x0000AFF4, + 0x034, 0x00009FF1, + 0x034, 0x00008FEE, + 0x034, 0x00007FEB, + 0x034, 0x00006FE8, + 0x034, 0x00005DEA, + 0x034, 0x00004CED, + 0x034, 0x00003CEA, + 0x034, 0x00002C6C, + 0x034, 0x00001C69, + 0x034, 0x00000C2B, + 0xB0000000, 0x00000000, + 0x80000001, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x000CA38C, + 0x034, 0x000C91AD, + 0x034, 0x000C81AA, + 0x034, 0x000C71A7, + 0x034, 0x000C60AA, + 0x034, 0x000C50A7, + 0x034, 0x000C402C, + 0x034, 0x000C3029, + 0x034, 0x000C200C, + 0x034, 0x000C1009, + 0x034, 0x000C0006, + 0x90000002, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x000CA38C, + 0x034, 0x000C9389, + 0x034, 0x000C816D, + 0x034, 0x000C716A, + 0x034, 0x000C606D, + 0x034, 0x000C506A, + 0x034, 0x000C402C, + 0x034, 0x000C3029, + 0x034, 0x000C2026, + 0x034, 0x000C1009, + 0x034, 0x000C0006, + 0x90000003, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x000CA38B, + 0x034, 0x000C9388, + 0x034, 0x000C818B, + 0x034, 0x000C7188, + 0x034, 0x000C606D, + 0x034, 0x000C506A, + 0x034, 0x000C402C, + 0x034, 0x000C3029, + 0x034, 0x000C2026, + 0x034, 0x000C1009, + 0x034, 0x000C0006, + 0x90000004, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x000CA38C, + 0x034, 0x000C9389, + 0x034, 0x000C816D, + 0x034, 0x000C716A, + 0x034, 0x000C606D, + 0x034, 0x000C506A, + 0x034, 0x000C402C, + 0x034, 0x000C3029, + 0x034, 0x000C2026, + 0x034, 0x000C1009, + 0x034, 0x000C0006, + 0x90000005, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x000CA38B, + 0x034, 0x000C9388, + 0x034, 0x000C818B, + 0x034, 0x000C7188, + 0x034, 0x000C606D, + 0x034, 0x000C506A, + 0x034, 0x000C402C, + 0x034, 0x000C3029, + 0x034, 0x000C2026, + 0x034, 0x000C1009, + 0x034, 0x000C0006, + 0x90000008, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x000CA3F5, + 0x034, 0x000C93F3, + 0x034, 0x000C83B2, + 0x034, 0x000C7390, + 0x034, 0x000C638D, + 0x034, 0x000C538A, + 0x034, 0x000C4387, + 0x034, 0x000C324A, + 0x034, 0x000C2247, + 0x034, 0x000C104D, + 0x034, 0x000C004A, + 0x90000009, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x000CAFF7, + 0x034, 0x000C9FF6, + 0x034, 0x000C8FF3, + 0x034, 0x000C7FF0, + 0x034, 0x000C6FED, + 0x034, 0x000C5FEA, + 0x034, 0x000C4FE7, + 0x034, 0x000C3DEA, + 0x034, 0x000C2DE7, + 0x034, 0x000C1DE4, + 0x034, 0x000C0CE7, + 0x9000000a, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x000CA38C, + 0x034, 0x000C9389, + 0x034, 0x000C816D, + 0x034, 0x000C716A, + 0x034, 0x000C606D, + 0x034, 0x000C506A, + 0x034, 0x000C402C, + 0x034, 0x000C3029, + 0x034, 0x000C2026, + 0x034, 0x000C1009, + 0x034, 0x000C0006, + 0x9000000b, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x000CA38C, + 0x034, 0x000C9389, + 0x034, 0x000C816D, + 0x034, 0x000C716A, + 0x034, 0x000C606D, + 0x034, 0x000C506A, + 0x034, 0x000C402C, + 0x034, 0x000C3029, + 0x034, 0x000C2026, + 0x034, 0x000C1009, + 0x034, 0x000C0006, + 0xA0000000, 0x00000000, + 0x034, 0x000CA794, + 0x034, 0x000C9791, + 0x034, 0x000C878E, + 0x034, 0x000C778B, + 0x034, 0x000C658D, + 0x034, 0x000C558A, + 0x034, 0x000C448D, + 0x034, 0x000C348A, + 0x034, 0x000C244C, + 0x034, 0x000C1449, + 0x034, 0x000C042B, + 0xB0000000, 0x00000000, + 0x80000001, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x000AA38C, + 0x034, 0x000A91AD, + 0x034, 0x000A81AA, + 0x034, 0x000A71A7, + 0x034, 0x000A60AA, + 0x034, 0x000A50A7, + 0x034, 0x000A402C, + 0x034, 0x000A3029, + 0x034, 0x000A200C, + 0x034, 0x000A1009, + 0x034, 0x000A0006, + 0x90000002, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x000AA3EE, + 0x034, 0x000A93AC, + 0x034, 0x000A8389, + 0x034, 0x000A716D, + 0x034, 0x000A616A, + 0x034, 0x000A506D, + 0x034, 0x000A406A, + 0x034, 0x000A302C, + 0x034, 0x000A2029, + 0x034, 0x000A1026, + 0x034, 0x000A0023, + 0x90000003, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x000AA3EF, + 0x034, 0x000A93AD, + 0x034, 0x000A838A, + 0x034, 0x000A718C, + 0x034, 0x000A6189, + 0x034, 0x000A506D, + 0x034, 0x000A406A, + 0x034, 0x000A302C, + 0x034, 0x000A2029, + 0x034, 0x000A1026, + 0x034, 0x000A0023, + 0x90000004, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x000AA3EE, + 0x034, 0x000A93AC, + 0x034, 0x000A8389, + 0x034, 0x000A716D, + 0x034, 0x000A616A, + 0x034, 0x000A506D, + 0x034, 0x000A406A, + 0x034, 0x000A302C, + 0x034, 0x000A2029, + 0x034, 0x000A1026, + 0x034, 0x000A0023, + 0x90000005, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x000AA3EF, + 0x034, 0x000A93AD, + 0x034, 0x000A838A, + 0x034, 0x000A718C, + 0x034, 0x000A6189, + 0x034, 0x000A506D, + 0x034, 0x000A406A, + 0x034, 0x000A302C, + 0x034, 0x000A2029, + 0x034, 0x000A1026, + 0x034, 0x000A0023, + 0x90000008, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x000AA3F5, + 0x034, 0x000A93F3, + 0x034, 0x000A83D0, + 0x034, 0x000A7371, + 0x034, 0x000A636E, + 0x034, 0x000A536B, + 0x034, 0x000A4368, + 0x034, 0x000A332A, + 0x034, 0x000A2327, + 0x034, 0x000A104C, + 0x034, 0x000A0049, + 0x90000009, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x000AAFF7, + 0x034, 0x000A9FF6, + 0x034, 0x000A8FF3, + 0x034, 0x000A7FF0, + 0x034, 0x000A6FED, + 0x034, 0x000A5FEA, + 0x034, 0x000A4FE7, + 0x034, 0x000A3DEA, + 0x034, 0x000A2DE7, + 0x034, 0x000A1DE4, + 0x034, 0x000A0F25, + 0x9000000a, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x000AA3EE, + 0x034, 0x000A93AC, + 0x034, 0x000A8389, + 0x034, 0x000A716D, + 0x034, 0x000A616A, + 0x034, 0x000A506D, + 0x034, 0x000A406A, + 0x034, 0x000A302C, + 0x034, 0x000A2029, + 0x034, 0x000A1026, + 0x034, 0x000A0023, + 0x9000000b, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x000AA3EE, + 0x034, 0x000A93AC, + 0x034, 0x000A8389, + 0x034, 0x000A716D, + 0x034, 0x000A616A, + 0x034, 0x000A506D, + 0x034, 0x000A406A, + 0x034, 0x000A302C, + 0x034, 0x000A2029, + 0x034, 0x000A1026, + 0x034, 0x000A0023, + 0xA0000000, 0x00000000, + 0x034, 0x000AA794, + 0x034, 0x000A9791, + 0x034, 0x000A878E, + 0x034, 0x000A778B, + 0x034, 0x000A658D, + 0x034, 0x000A558A, + 0x034, 0x000A448D, + 0x034, 0x000A348A, + 0x034, 0x000A244C, + 0x034, 0x000A1449, + 0x034, 0x000A042B, + 0xB0000000, 0x00000000, + 0x80000001, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x0008A38C, + 0x034, 0x000891AD, + 0x034, 0x000881AA, + 0x034, 0x000871A7, + 0x034, 0x000860AA, + 0x034, 0x000850A7, + 0x034, 0x0008402C, + 0x034, 0x00083029, + 0x034, 0x00082026, + 0x034, 0x00081009, + 0x034, 0x00080006, + 0x90000002, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x0008A3EC, + 0x034, 0x000893AC, + 0x034, 0x000881EC, + 0x034, 0x0008716D, + 0x034, 0x0008616A, + 0x034, 0x0008506D, + 0x034, 0x0008404C, + 0x034, 0x0008302C, + 0x034, 0x00082029, + 0x034, 0x00081026, + 0x034, 0x00080023, + 0x90000003, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x0008A3EF, + 0x034, 0x000893AD, + 0x034, 0x0008838A, + 0x034, 0x0008718C, + 0x034, 0x00086189, + 0x034, 0x0008506D, + 0x034, 0x0008406A, + 0x034, 0x0008302C, + 0x034, 0x00082029, + 0x034, 0x00081026, + 0x034, 0x00080023, + 0x90000004, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x0008A3EC, + 0x034, 0x000893AC, + 0x034, 0x000881EC, + 0x034, 0x0008716D, + 0x034, 0x0008616A, + 0x034, 0x0008506D, + 0x034, 0x0008404C, + 0x034, 0x0008302C, + 0x034, 0x00082029, + 0x034, 0x00081026, + 0x034, 0x00080023, + 0x90000005, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x0008A3EF, + 0x034, 0x000893AD, + 0x034, 0x0008838A, + 0x034, 0x0008718C, + 0x034, 0x00086189, + 0x034, 0x0008506D, + 0x034, 0x0008406A, + 0x034, 0x0008302C, + 0x034, 0x00082029, + 0x034, 0x00081026, + 0x034, 0x00080023, + 0x90000008, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x0008A3F4, + 0x034, 0x000893F0, + 0x034, 0x000883AE, + 0x034, 0x00087350, + 0x034, 0x0008634D, + 0x034, 0x0008534A, + 0x034, 0x00084347, + 0x034, 0x0008312D, + 0x034, 0x0008212A, + 0x034, 0x00081127, + 0x034, 0x0008002A, + 0x90000009, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x0008AFF7, + 0x034, 0x00089FF4, + 0x034, 0x00088FF1, + 0x034, 0x00087FEE, + 0x034, 0x00086FEB, + 0x034, 0x00085FE8, + 0x034, 0x00084DEB, + 0x034, 0x00083DE8, + 0x034, 0x00082DE5, + 0x034, 0x00081C8B, + 0x034, 0x00080C88, + 0x9000000a, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x0008A3EC, + 0x034, 0x000893AC, + 0x034, 0x000881EC, + 0x034, 0x0008716D, + 0x034, 0x0008616A, + 0x034, 0x0008506D, + 0x034, 0x0008404C, + 0x034, 0x0008302C, + 0x034, 0x00082029, + 0x034, 0x00081026, + 0x034, 0x00080023, + 0x9000000b, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x0008A3EC, + 0x034, 0x000893AC, + 0x034, 0x000881EC, + 0x034, 0x0008716D, + 0x034, 0x0008616A, + 0x034, 0x0008506D, + 0x034, 0x0008404C, + 0x034, 0x0008302C, + 0x034, 0x00082029, + 0x034, 0x00081026, + 0x034, 0x00080023, + 0xA0000000, 0x00000000, + 0x034, 0x0008A794, + 0x034, 0x00089791, + 0x034, 0x0008878E, + 0x034, 0x0008778B, + 0x034, 0x0008658D, + 0x034, 0x0008558A, + 0x034, 0x0008448D, + 0x034, 0x0008348A, + 0x034, 0x0008244C, + 0x034, 0x00081449, + 0x034, 0x0008042B, + 0xB0000000, 0x00000000, + 0x0EF, 0x00000000, + 0x80000001, 0x00000000, 0x40000000, 0x00000000, + 0x0DF, 0x00000001, + 0x90000002, 0x00000000, 0x40000000, 0x00000000, + 0x0DF, 0x00000001, + 0x90000003, 0x00000000, 0x40000000, 0x00000000, + 0x0DF, 0x00000001, + 0x90000004, 0x00000000, 0x40000000, 0x00000000, + 0x0DF, 0x00000001, + 0x90000005, 0x00000000, 0x40000000, 0x00000000, + 0x0DF, 0x00000001, + 0x90000008, 0x00000000, 0x40000000, 0x00000000, + 0x0DF, 0x00000001, + 0x9000000a, 0x00000000, 0x40000000, 0x00000000, + 0x0DF, 0x00000001, + 0x9000000b, 0x00000000, 0x40000000, 0x00000000, + 0x0DF, 0x00000001, + 0xA0000000, 0x00000000, + 0x0DF, 0x00000000, + 0xB0000000, 0x00000000, + 0x018, 0x0001712A, + 0x0EF, 0x00000040, + 0x80000001, 0x00000000, 0x40000000, 0x00000000, + 0x035, 0x000006CC, + 0x035, 0x000086CC, + 0x035, 0x000106CC, + 0x035, 0x000206CC, + 0x035, 0x000286CC, + 0x035, 0x000306CC, + 0x035, 0x000406CC, + 0x035, 0x000486CC, + 0x035, 0x000506CC, + 0x035, 0x000806CC, + 0x035, 0x000886CC, + 0x035, 0x000906CC, + 0x035, 0x000A06CC, + 0x035, 0x000A86CC, + 0x035, 0x000B06CC, + 0x035, 0x000C06CC, + 0x035, 0x000C86CC, + 0x035, 0x000D06CC, + 0x90000002, 0x00000000, 0x40000000, 0x00000000, + 0x035, 0x000006CC, + 0x035, 0x000086CC, + 0x035, 0x000106CC, + 0x035, 0x000206CC, + 0x035, 0x000286CC, + 0x035, 0x000306CC, + 0x035, 0x000406CC, + 0x035, 0x000486CC, + 0x035, 0x000506CC, + 0x035, 0x000806CC, + 0x035, 0x000886CC, + 0x035, 0x000906CC, + 0x035, 0x000A06CC, + 0x035, 0x000A86CC, + 0x035, 0x000B06CC, + 0x035, 0x000C06CC, + 0x035, 0x000C86CC, + 0x035, 0x000D06CC, + 0x90000003, 0x00000000, 0x40000000, 0x00000000, + 0x035, 0x000006CC, + 0x035, 0x000086CC, + 0x035, 0x000106CC, + 0x035, 0x000206CC, + 0x035, 0x000286CC, + 0x035, 0x000306CC, + 0x035, 0x000406CC, + 0x035, 0x000486CC, + 0x035, 0x000506CC, + 0x035, 0x000806CC, + 0x035, 0x000886CC, + 0x035, 0x000906CC, + 0x035, 0x000A06CC, + 0x035, 0x000A86CC, + 0x035, 0x000B06CC, + 0x035, 0x000C06CC, + 0x035, 0x000C86CC, + 0x035, 0x000D06CC, + 0x90000004, 0x00000000, 0x40000000, 0x00000000, + 0x035, 0x000006CC, + 0x035, 0x000086CC, + 0x035, 0x000106CC, + 0x035, 0x000206CC, + 0x035, 0x000286CC, + 0x035, 0x000306CC, + 0x035, 0x000406CC, + 0x035, 0x000486CC, + 0x035, 0x000506CC, + 0x035, 0x000806CC, + 0x035, 0x000886CC, + 0x035, 0x000906CC, + 0x035, 0x000A06CC, + 0x035, 0x000A86CC, + 0x035, 0x000B06CC, + 0x035, 0x000C06CC, + 0x035, 0x000C86CC, + 0x035, 0x000D06CC, + 0x90000005, 0x00000000, 0x40000000, 0x00000000, + 0x035, 0x000006CC, + 0x035, 0x000086CC, + 0x035, 0x000106CC, + 0x035, 0x000206CC, + 0x035, 0x000286CC, + 0x035, 0x000306CC, + 0x035, 0x000406CC, + 0x035, 0x000486CC, + 0x035, 0x000506CC, + 0x035, 0x000806CC, + 0x035, 0x000886CC, + 0x035, 0x000906CC, + 0x035, 0x000A06CC, + 0x035, 0x000A86CC, + 0x035, 0x000B06CC, + 0x035, 0x000C06CC, + 0x035, 0x000C86CC, + 0x035, 0x000D06CC, + 0x90000008, 0x00000000, 0x40000000, 0x00000000, + 0x035, 0x000006CC, + 0x035, 0x000086CC, + 0x035, 0x000106CC, + 0x035, 0x000206CC, + 0x035, 0x000286CC, + 0x035, 0x000306CC, + 0x035, 0x000406CC, + 0x035, 0x000486CC, + 0x035, 0x000506CC, + 0x035, 0x000806CC, + 0x035, 0x000886CC, + 0x035, 0x000906CC, + 0x035, 0x000A06CC, + 0x035, 0x000A86CC, + 0x035, 0x000B06CC, + 0x035, 0x000C06CC, + 0x035, 0x000C86CC, + 0x035, 0x000D06CC, + 0x9000000a, 0x00000000, 0x40000000, 0x00000000, + 0x035, 0x000006CC, + 0x035, 0x000086CC, + 0x035, 0x000106CC, + 0x035, 0x000206CC, + 0x035, 0x000286CC, + 0x035, 0x000306CC, + 0x035, 0x000406CC, + 0x035, 0x000486CC, + 0x035, 0x000506CC, + 0x035, 0x000806CC, + 0x035, 0x000886CC, + 0x035, 0x000906CC, + 0x035, 0x000A06CC, + 0x035, 0x000A86CC, + 0x035, 0x000B06CC, + 0x035, 0x000C06CC, + 0x035, 0x000C86CC, + 0x035, 0x000D06CC, + 0x9000000b, 0x00000000, 0x40000000, 0x00000000, + 0x035, 0x000006CC, + 0x035, 0x000086CC, + 0x035, 0x000106CC, + 0x035, 0x000206CC, + 0x035, 0x000286CC, + 0x035, 0x000306CC, + 0x035, 0x000406CC, + 0x035, 0x000486CC, + 0x035, 0x000506CC, + 0x035, 0x000806CC, + 0x035, 0x000886CC, + 0x035, 0x000906CC, + 0x035, 0x000A06CC, + 0x035, 0x000A86CC, + 0x035, 0x000B06CC, + 0x035, 0x000C06CC, + 0x035, 0x000C86CC, + 0x035, 0x000D06CC, + 0xA0000000, 0x00000000, + 0x035, 0x00000484, + 0x035, 0x00008484, + 0x035, 0x00010484, + 0x035, 0x00020584, + 0x035, 0x00028584, + 0x035, 0x00030584, + 0x035, 0x00040584, + 0x035, 0x00048584, + 0x035, 0x00050584, + 0x035, 0x000805FB, + 0x035, 0x000885FB, + 0x035, 0x000905FB, + 0x035, 0x000A05FB, + 0x035, 0x000A85FB, + 0x035, 0x000B05FB, + 0x035, 0x000C05FB, + 0x035, 0x000C85FB, + 0x035, 0x000D05FB, + 0xB0000000, 0x00000000, + 0x0EF, 0x00000000, + 0x80000001, 0x00000000, 0x40000000, 0x00000000, + 0x0DF, 0x00000001, + 0x90000002, 0x00000000, 0x40000000, 0x00000000, + 0x0DF, 0x00000001, + 0x90000003, 0x00000000, 0x40000000, 0x00000000, + 0x0DF, 0x00000001, + 0x90000004, 0x00000000, 0x40000000, 0x00000000, + 0x0DF, 0x00000001, + 0x90000005, 0x00000000, 0x40000000, 0x00000000, + 0x0DF, 0x00000001, + 0x90000008, 0x00000000, 0x40000000, 0x00000000, + 0x0DF, 0x00000001, + 0x9000000a, 0x00000000, 0x40000000, 0x00000000, + 0x0DF, 0x00000001, + 0x9000000b, 0x00000000, 0x40000000, 0x00000000, + 0x0DF, 0x00000001, + 0xA0000000, 0x00000000, + 0x0DF, 0x00000000, + 0xB0000000, 0x00000000, + 0x018, 0x0001712A, + 0x0EF, 0x00000010, + 0x80000001, 0x00000000, 0x40000000, 0x00000000, + 0x036, 0x00000473, + 0x036, 0x00008473, + 0x036, 0x00010473, + 0x036, 0x00020473, + 0x036, 0x00028473, + 0x036, 0x00030473, + 0x036, 0x00040473, + 0x036, 0x00048473, + 0x036, 0x00050473, + 0x036, 0x00080473, + 0x036, 0x00088473, + 0x036, 0x00090473, + 0x036, 0x000A0473, + 0x036, 0x000A8473, + 0x036, 0x000B0473, + 0x036, 0x000C0473, + 0x036, 0x000C8473, + 0x036, 0x000D0473, + 0x90000002, 0x00000000, 0x40000000, 0x00000000, + 0x036, 0x00000475, + 0x036, 0x00008475, + 0x036, 0x00010475, + 0x036, 0x00020475, + 0x036, 0x00028475, + 0x036, 0x00030475, + 0x036, 0x00040475, + 0x036, 0x00048475, + 0x036, 0x00050475, + 0x036, 0x00080475, + 0x036, 0x00088475, + 0x036, 0x00090475, + 0x036, 0x000A0475, + 0x036, 0x000A8475, + 0x036, 0x000B0475, + 0x036, 0x000C0475, + 0x036, 0x000C8475, + 0x036, 0x000D0475, + 0x90000003, 0x00000000, 0x40000000, 0x00000000, + 0x036, 0x00000475, + 0x036, 0x00008475, + 0x036, 0x00010475, + 0x036, 0x00020475, + 0x036, 0x00028475, + 0x036, 0x00030475, + 0x036, 0x00040475, + 0x036, 0x00048475, + 0x036, 0x00050475, + 0x036, 0x00080475, + 0x036, 0x00088475, + 0x036, 0x00090475, + 0x036, 0x000A0475, + 0x036, 0x000A8475, + 0x036, 0x000B0475, + 0x036, 0x000C0475, + 0x036, 0x000C8475, + 0x036, 0x000D0475, + 0x90000004, 0x00000000, 0x40000000, 0x00000000, + 0x036, 0x00000475, + 0x036, 0x00008475, + 0x036, 0x00010475, + 0x036, 0x00020475, + 0x036, 0x00028475, + 0x036, 0x00030475, + 0x036, 0x00040475, + 0x036, 0x00048475, + 0x036, 0x00050475, + 0x036, 0x00080475, + 0x036, 0x00088475, + 0x036, 0x00090475, + 0x036, 0x000A0475, + 0x036, 0x000A8475, + 0x036, 0x000B0475, + 0x036, 0x000C0475, + 0x036, 0x000C8475, + 0x036, 0x000D0475, + 0x90000005, 0x00000000, 0x40000000, 0x00000000, + 0x036, 0x00000475, + 0x036, 0x00008475, + 0x036, 0x00010475, + 0x036, 0x00020475, + 0x036, 0x00028475, + 0x036, 0x00030475, + 0x036, 0x00040475, + 0x036, 0x00048475, + 0x036, 0x00050475, + 0x036, 0x00080475, + 0x036, 0x00088475, + 0x036, 0x00090475, + 0x036, 0x000A0475, + 0x036, 0x000A8475, + 0x036, 0x000B0475, + 0x036, 0x000C0475, + 0x036, 0x000C8475, + 0x036, 0x000D0475, + 0x90000008, 0x00000000, 0x40000000, 0x00000000, + 0x036, 0x00000475, + 0x036, 0x00008475, + 0x036, 0x00010475, + 0x036, 0x00020475, + 0x036, 0x00028475, + 0x036, 0x00030475, + 0x036, 0x00040475, + 0x036, 0x00048475, + 0x036, 0x00050475, + 0x036, 0x00080475, + 0x036, 0x00088475, + 0x036, 0x00090475, + 0x036, 0x000A0475, + 0x036, 0x000A8475, + 0x036, 0x000B0475, + 0x036, 0x000C0475, + 0x036, 0x000C8475, + 0x036, 0x000D0475, + 0x9000000a, 0x00000000, 0x40000000, 0x00000000, + 0x036, 0x00000475, + 0x036, 0x00008475, + 0x036, 0x00010475, + 0x036, 0x00020475, + 0x036, 0x00028475, + 0x036, 0x00030475, + 0x036, 0x00040475, + 0x036, 0x00048475, + 0x036, 0x00050475, + 0x036, 0x00080475, + 0x036, 0x00088475, + 0x036, 0x00090475, + 0x036, 0x000A0475, + 0x036, 0x000A8475, + 0x036, 0x000B0475, + 0x036, 0x000C0475, + 0x036, 0x000C8475, + 0x036, 0x000D0475, + 0x9000000b, 0x00000000, 0x40000000, 0x00000000, + 0x036, 0x00000475, + 0x036, 0x00008475, + 0x036, 0x00010475, + 0x036, 0x00020475, + 0x036, 0x00028475, + 0x036, 0x00030475, + 0x036, 0x00040475, + 0x036, 0x00048475, + 0x036, 0x00050475, + 0x036, 0x00080475, + 0x036, 0x00088475, + 0x036, 0x00090475, + 0x036, 0x000A0475, + 0x036, 0x000A8475, + 0x036, 0x000B0475, + 0x036, 0x000C0475, + 0x036, 0x000C8475, + 0x036, 0x000D0475, + 0xA0000000, 0x00000000, + 0x036, 0x00000474, + 0x036, 0x00008474, + 0x036, 0x00010474, + 0x036, 0x00020474, + 0x036, 0x00028474, + 0x036, 0x00030474, + 0x036, 0x00040474, + 0x036, 0x00048474, + 0x036, 0x00050474, + 0x036, 0x00080474, + 0x036, 0x00088474, + 0x036, 0x00090474, + 0x036, 0x000A0474, + 0x036, 0x000A8474, + 0x036, 0x000B0474, + 0x036, 0x000C0474, + 0x036, 0x000C8474, + 0x036, 0x000D0474, + 0xB0000000, 0x00000000, + 0x0EF, 0x00000000, + 0x80000001, 0x00000000, 0x40000000, 0x00000000, + 0x90000002, 0x00000000, 0x40000000, 0x00000000, + 0x90000003, 0x00000000, 0x40000000, 0x00000000, + 0x90000004, 0x00000000, 0x40000000, 0x00000000, + 0x90000005, 0x00000000, 0x40000000, 0x00000000, + 0x90000008, 0x00000000, 0x40000000, 0x00000000, + 0x9000000a, 0x00000000, 0x40000000, 0x00000000, + 0x9000000b, 0x00000000, 0x40000000, 0x00000000, + 0xA0000000, 0x00000000, + 0x0EF, 0x00000004, + 0x037, 0x00000000, + 0x038, 0x0000514E, + 0x037, 0x00004000, + 0x038, 0x0000514E, + 0x037, 0x00008000, + 0x038, 0x0000514E, + 0x037, 0x00010000, + 0x038, 0x0000514E, + 0x037, 0x00014000, + 0x038, 0x0000514E, + 0x037, 0x00018000, + 0x038, 0x0000514E, + 0x037, 0x0001C000, + 0x038, 0x0000514E, + 0x037, 0x00020000, + 0x038, 0x0000514E, + 0x037, 0x00024000, + 0x038, 0x0000514E, + 0x037, 0x00028000, + 0x038, 0x0000514E, + 0x037, 0x0002C000, + 0x038, 0x0000714E, + 0x037, 0x00030000, + 0x038, 0x0000514E, + 0x037, 0x00034000, + 0x038, 0x0000514E, + 0x037, 0x00038000, + 0x038, 0x0000514E, + 0x037, 0x0003C000, + 0x038, 0x0000514E, + 0x037, 0x00040000, + 0x038, 0x0000514E, + 0x037, 0x00044000, + 0x038, 0x0000514E, + 0x037, 0x00048000, + 0x038, 0x0000514E, + 0x037, 0x00080000, + 0x038, 0x00005ECE, + 0x037, 0x00084000, + 0x038, 0x00005ECE, + 0x037, 0x00088000, + 0x038, 0x00005ECE, + 0x037, 0x00090000, + 0x038, 0x00005ECE, + 0x037, 0x00094000, + 0x038, 0x00005ECE, + 0x037, 0x00098000, + 0x038, 0x00005ECE, + 0x037, 0x0009C000, + 0x038, 0x00005ECE, + 0x037, 0x000A0000, + 0x038, 0x00005ECE, + 0x037, 0x000A4000, + 0x038, 0x00005ECE, + 0x037, 0x000A8000, + 0x038, 0x00005ECE, + 0x037, 0x000AC000, + 0x038, 0x00005ECE, + 0x037, 0x000B0000, + 0x038, 0x00005ECE, + 0x037, 0x000B4000, + 0x038, 0x00005ECE, + 0x037, 0x000B8000, + 0x038, 0x00005ECE, + 0x037, 0x000BC000, + 0x038, 0x00005ECE, + 0x037, 0x000C0000, + 0x038, 0x00005ECE, + 0x037, 0x000C4000, + 0x038, 0x00005ECE, + 0x037, 0x000C8000, + 0x038, 0x00005ECE, + 0x0EF, 0x00000000, + 0xB0000000, 0x00000000, + 0x0EF, 0x00000008, + 0x80000001, 0x00000000, 0x40000000, 0x00000000, + 0x90000002, 0x00000000, 0x40000000, 0x00000000, + 0x90000003, 0x00000000, 0x40000000, 0x00000000, + 0x90000004, 0x00000000, 0x40000000, 0x00000000, + 0x90000005, 0x00000000, 0x40000000, 0x00000000, + 0x90000008, 0x00000000, 0x40000000, 0x00000000, + 0x9000000a, 0x00000000, 0x40000000, 0x00000000, + 0x9000000b, 0x00000000, 0x40000000, 0x00000000, + 0xA0000000, 0x00000000, + 0x03C, 0x0000007D, + 0x03C, 0x0000047D, + 0x03C, 0x0000087D, + 0x03C, 0x0000107D, + 0x03C, 0x0000147D, + 0x03C, 0x0000187D, + 0xB0000000, 0x00000000, + 0x80000001, 0x00000000, 0x40000000, 0x00000000, + 0x03C, 0x0000027E, + 0x03C, 0x00000546, + 0x03C, 0x00000821, + 0x03C, 0x0000127E, + 0x03C, 0x00001546, + 0x03C, 0x00001821, + 0x03C, 0x0000227E, + 0x03C, 0x00002546, + 0x03C, 0x00002821, + 0x90000002, 0x00000000, 0x40000000, 0x00000000, + 0x03C, 0x0000027E, + 0x03C, 0x00000546, + 0x03C, 0x00000821, + 0x03C, 0x0000127E, + 0x03C, 0x00001546, + 0x03C, 0x00001821, + 0x03C, 0x0000227E, + 0x03C, 0x00002546, + 0x03C, 0x00002821, + 0x90000003, 0x00000000, 0x40000000, 0x00000000, + 0x03C, 0x0000027E, + 0x03C, 0x00000546, + 0x03C, 0x00000821, + 0x03C, 0x0000127E, + 0x03C, 0x00001546, + 0x03C, 0x00001821, + 0x03C, 0x0000227E, + 0x03C, 0x00002546, + 0x03C, 0x00002821, + 0x90000004, 0x00000000, 0x40000000, 0x00000000, + 0x03C, 0x0000027E, + 0x03C, 0x00000546, + 0x03C, 0x00000821, + 0x03C, 0x0000127E, + 0x03C, 0x00001546, + 0x03C, 0x00001821, + 0x03C, 0x0000227E, + 0x03C, 0x00002546, + 0x03C, 0x00002821, + 0x90000005, 0x00000000, 0x40000000, 0x00000000, + 0x03C, 0x0000027E, + 0x03C, 0x00000546, + 0x03C, 0x00000821, + 0x03C, 0x0000127E, + 0x03C, 0x00001546, + 0x03C, 0x00001821, + 0x03C, 0x0000227E, + 0x03C, 0x00002546, + 0x03C, 0x00002821, + 0x90000008, 0x00000000, 0x40000000, 0x00000000, + 0x03C, 0x0000027E, + 0x03C, 0x00000546, + 0x03C, 0x00000821, + 0x03C, 0x0000127E, + 0x03C, 0x00001546, + 0x03C, 0x00001821, + 0x03C, 0x0000227E, + 0x03C, 0x00002546, + 0x03C, 0x00002821, + 0x9000000a, 0x00000000, 0x40000000, 0x00000000, + 0x03C, 0x0000027E, + 0x03C, 0x00000546, + 0x03C, 0x00000821, + 0x03C, 0x0000127E, + 0x03C, 0x00001546, + 0x03C, 0x00001821, + 0x03C, 0x0000227E, + 0x03C, 0x00002546, + 0x03C, 0x00002821, + 0x9000000b, 0x00000000, 0x40000000, 0x00000000, + 0x03C, 0x0000027E, + 0x03C, 0x00000546, + 0x03C, 0x00000821, + 0x03C, 0x0000127E, + 0x03C, 0x00001546, + 0x03C, 0x00001821, + 0x03C, 0x0000227E, + 0x03C, 0x00002546, + 0x03C, 0x00002821, + 0xA0000000, 0x00000000, + 0x03C, 0x0000037E, + 0x03C, 0x00000575, + 0x03C, 0x00000971, + 0x03C, 0x0000127E, + 0x03C, 0x00001575, + 0x03C, 0x00001871, + 0x03C, 0x0000217E, + 0x03C, 0x00002575, + 0x03C, 0x00002871, + 0xB0000000, 0x00000000, + 0x0EF, 0x00000000, + 0x061, 0x000C0D47, + 0x062, 0x0000133C, + 0x80000001, 0x00000000, 0x40000000, 0x00000000, + 0x063, 0x000750E7, + 0x90000002, 0x00000000, 0x40000000, 0x00000000, + 0x063, 0x000750E7, + 0x90000003, 0x00000000, 0x40000000, 0x00000000, + 0x063, 0x000750E7, + 0x90000004, 0x00000000, 0x40000000, 0x00000000, + 0x063, 0x000750E7, + 0x90000005, 0x00000000, 0x40000000, 0x00000000, + 0x063, 0x000750E7, + 0x90000008, 0x00000000, 0x40000000, 0x00000000, + 0x063, 0x000750E7, + 0x9000000a, 0x00000000, 0x40000000, 0x00000000, + 0x063, 0x000750E7, + 0x9000000b, 0x00000000, 0x40000000, 0x00000000, + 0x063, 0x000750E7, + 0xA0000000, 0x00000000, + 0x063, 0x0007D0E7, + 0xB0000000, 0x00000000, + 0x064, 0x00014FEC, + 0x80000001, 0x00000000, 0x40000000, 0x00000000, + 0x065, 0x000920D0, + 0x90000002, 0x00000000, 0x40000000, 0x00000000, + 0x065, 0x000920D0, + 0x90000003, 0x00000000, 0x40000000, 0x00000000, + 0x065, 0x000920D0, + 0x90000004, 0x00000000, 0x40000000, 0x00000000, + 0x065, 0x000920D0, + 0x90000005, 0x00000000, 0x40000000, 0x00000000, + 0x065, 0x000920D0, + 0x90000008, 0x00000000, 0x40000000, 0x00000000, + 0x065, 0x000920D0, + 0x9000000a, 0x00000000, 0x40000000, 0x00000000, + 0x065, 0x000920D0, + 0x9000000b, 0x00000000, 0x40000000, 0x00000000, + 0x065, 0x000920D0, + 0xA0000000, 0x00000000, + 0x065, 0x000923FF, + 0xB0000000, 0x00000000, + 0x066, 0x00000040, + 0x057, 0x00050000, + 0x056, 0x00051DF0, + 0x80000001, 0x00000000, 0x40000000, 0x00000000, + 0x90000002, 0x00000000, 0x40000000, 0x00000000, + 0x90000003, 0x00000000, 0x40000000, 0x00000000, + 0x90000004, 0x00000000, 0x40000000, 0x00000000, + 0x90000005, 0x00000000, 0x40000000, 0x00000000, + 0x90000008, 0x00000000, 0x40000000, 0x00000000, + 0x9000000a, 0x00000000, 0x40000000, 0x00000000, + 0x9000000b, 0x00000000, 0x40000000, 0x00000000, + 0xA0000000, 0x00000000, + 0x055, 0x00082060, + 0xB0000000, 0x00000000, +}; + +RTW_DECL_TABLE_RF_RADIO(rtw8814a_rf_b, B); + +static const u32 rtw8814a_rf_c[] = { + 0x018, 0x00013124, + 0x040, 0x00000C00, + 0x058, 0x00000F98, + 0x07F, 0x00068004, + 0x018, 0x00000006, + 0x80000002, 0x00000000, 0x40000000, 0x00000000, + 0x086, 0x000E335A, + 0x087, 0x00079F80, + 0x90000003, 0x00000000, 0x40000000, 0x00000000, + 0x086, 0x000E335A, + 0x087, 0x00079F80, + 0x90000004, 0x00000000, 0x40000000, 0x00000000, + 0x086, 0x000E335A, + 0x087, 0x00079F80, + 0x90000005, 0x00000000, 0x40000000, 0x00000000, + 0x086, 0x000E335A, + 0x087, 0x00079F80, + 0x90000008, 0x00000000, 0x40000000, 0x00000000, + 0x086, 0x000E335A, + 0x087, 0x00079F80, + 0x9000000a, 0x00000000, 0x40000000, 0x00000000, + 0x086, 0x000E335A, + 0x087, 0x00079F80, + 0x9000000b, 0x00000000, 0x40000000, 0x00000000, + 0x086, 0x000E335A, + 0x087, 0x00079F80, + 0xA0000000, 0x00000000, + 0x086, 0x000E4B58, + 0x087, 0x00049F80, + 0xB0000000, 0x00000000, + 0x0DF, 0x00000008, + 0x0EF, 0x00002000, + 0x80000002, 0x00000000, 0x40000000, 0x00000000, + 0x03B, 0x0003F19B, + 0x03B, 0x00037A5B, + 0x03B, 0x0002A433, + 0x03B, 0x00027BD3, + 0x03B, 0x0001F80B, + 0x03B, 0x00017823, + 0x90000003, 0x00000000, 0x40000000, 0x00000000, + 0x03B, 0x0003F19B, + 0x03B, 0x00037A5B, + 0x03B, 0x0002A433, + 0x03B, 0x00027BD3, + 0x03B, 0x0001F80B, + 0x03B, 0x00017823, + 0x90000004, 0x00000000, 0x40000000, 0x00000000, + 0x03B, 0x0003F19B, + 0x03B, 0x00037A5B, + 0x03B, 0x0002A433, + 0x03B, 0x00027BD3, + 0x03B, 0x0001F80B, + 0x03B, 0x00017823, + 0x90000005, 0x00000000, 0x40000000, 0x00000000, + 0x03B, 0x0003F19B, + 0x03B, 0x00037A5B, + 0x03B, 0x0002A433, + 0x03B, 0x00027BD3, + 0x03B, 0x0001F80B, + 0x03B, 0x00017823, + 0x90000008, 0x00000000, 0x40000000, 0x00000000, + 0x03B, 0x0003F19B, + 0x03B, 0x00037A5B, + 0x03B, 0x0002A433, + 0x03B, 0x00027BD3, + 0x03B, 0x0001F80B, + 0x03B, 0x00017823, + 0x9000000a, 0x00000000, 0x40000000, 0x00000000, + 0x03B, 0x0003F19B, + 0x03B, 0x00037A5B, + 0x03B, 0x0002A433, + 0x03B, 0x00027BD3, + 0x03B, 0x0001F80B, + 0x03B, 0x00017823, + 0x9000000b, 0x00000000, 0x40000000, 0x00000000, + 0x03B, 0x0003F19B, + 0x03B, 0x00037A5B, + 0x03B, 0x0002A433, + 0x03B, 0x00027BD3, + 0x03B, 0x0001F80B, + 0x03B, 0x00017823, + 0xA0000000, 0x00000000, + 0x03B, 0x0003F258, + 0x03B, 0x00030A58, + 0x03B, 0x0002FA58, + 0x03B, 0x00022590, + 0x03B, 0x0001FA50, + 0x03B, 0x00010248, + 0x03B, 0x00008240, + 0xB0000000, 0x00000000, + 0x0EF, 0x00000100, + 0x80000002, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x0000A0D0, + 0x034, 0x000090CD, + 0x034, 0x000080CA, + 0x034, 0x0000704D, + 0x034, 0x0000604A, + 0x034, 0x00005047, + 0x034, 0x0000400A, + 0x034, 0x00003007, + 0x034, 0x00002004, + 0x034, 0x00001001, + 0x034, 0x00000001, + 0x90000003, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x0000A0D0, + 0x034, 0x000090CD, + 0x034, 0x000080CA, + 0x034, 0x0000704D, + 0x034, 0x0000604A, + 0x034, 0x00005047, + 0x034, 0x0000400A, + 0x034, 0x00003007, + 0x034, 0x00002004, + 0x034, 0x00001001, + 0x034, 0x00000001, + 0x90000004, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x0000A0D0, + 0x034, 0x000090CD, + 0x034, 0x000080CA, + 0x034, 0x0000704D, + 0x034, 0x0000604A, + 0x034, 0x00005047, + 0x034, 0x0000400A, + 0x034, 0x00003007, + 0x034, 0x00002004, + 0x034, 0x00001001, + 0x034, 0x00000001, + 0x90000005, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x0000A0D0, + 0x034, 0x000090CD, + 0x034, 0x000080CA, + 0x034, 0x0000704D, + 0x034, 0x0000604A, + 0x034, 0x00005047, + 0x034, 0x0000400A, + 0x034, 0x00003007, + 0x034, 0x00002004, + 0x034, 0x00001001, + 0x034, 0x00000001, + 0x90000008, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x0000A0D0, + 0x034, 0x000090CD, + 0x034, 0x000080CA, + 0x034, 0x0000704D, + 0x034, 0x0000604A, + 0x034, 0x00005047, + 0x034, 0x0000400A, + 0x034, 0x00003007, + 0x034, 0x00002004, + 0x034, 0x00001001, + 0x034, 0x00000001, + 0x9000000a, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x0000A0D0, + 0x034, 0x000090CD, + 0x034, 0x000080CA, + 0x034, 0x0000704D, + 0x034, 0x0000604A, + 0x034, 0x00005047, + 0x034, 0x0000400A, + 0x034, 0x00003007, + 0x034, 0x00002004, + 0x034, 0x00001001, + 0x034, 0x00000001, + 0x9000000b, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x0000A0D0, + 0x034, 0x000090CD, + 0x034, 0x000080CA, + 0x034, 0x0000704D, + 0x034, 0x0000604A, + 0x034, 0x00005047, + 0x034, 0x0000400A, + 0x034, 0x00003007, + 0x034, 0x00002004, + 0x034, 0x00001001, + 0x034, 0x00000001, + 0xA0000000, 0x00000000, + 0x034, 0x0000ADF6, + 0x034, 0x00009DF3, + 0x034, 0x00008DF0, + 0x034, 0x00007DED, + 0x034, 0x00006DEA, + 0x034, 0x00005CED, + 0x034, 0x00004CEA, + 0x034, 0x000034EA, + 0x034, 0x000024E7, + 0x034, 0x0000146A, + 0x034, 0x0000006B, + 0xB0000000, 0x00000000, + 0x80000002, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x0000A0D0, + 0x034, 0x000090CD, + 0x034, 0x000080CA, + 0x034, 0x0000704D, + 0x034, 0x0000604A, + 0x034, 0x00005047, + 0x034, 0x0000400A, + 0x034, 0x00003007, + 0x034, 0x00002004, + 0x034, 0x00001001, + 0x034, 0x00000001, + 0x90000003, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x0000A0D0, + 0x034, 0x000090CD, + 0x034, 0x000080CA, + 0x034, 0x0000704D, + 0x034, 0x0000604A, + 0x034, 0x00005047, + 0x034, 0x0000400A, + 0x034, 0x00003007, + 0x034, 0x00002004, + 0x034, 0x00001001, + 0x034, 0x00000001, + 0x90000004, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x0000A0D0, + 0x034, 0x000090CD, + 0x034, 0x000080CA, + 0x034, 0x0000704D, + 0x034, 0x0000604A, + 0x034, 0x00005047, + 0x034, 0x0000400A, + 0x034, 0x00003007, + 0x034, 0x00002004, + 0x034, 0x00001001, + 0x034, 0x00000001, + 0x90000005, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x0000A0D0, + 0x034, 0x000090CD, + 0x034, 0x000080CA, + 0x034, 0x0000704D, + 0x034, 0x0000604A, + 0x034, 0x00005047, + 0x034, 0x0000400A, + 0x034, 0x00003007, + 0x034, 0x00002004, + 0x034, 0x00001001, + 0x034, 0x00000001, + 0x90000008, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x0000A0D0, + 0x034, 0x000090CD, + 0x034, 0x000080CA, + 0x034, 0x0000704D, + 0x034, 0x0000604A, + 0x034, 0x00005047, + 0x034, 0x0000400A, + 0x034, 0x00003007, + 0x034, 0x00002004, + 0x034, 0x00001001, + 0x034, 0x00000001, + 0x9000000a, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x0000A0D0, + 0x034, 0x000090CD, + 0x034, 0x000080CA, + 0x034, 0x0000704D, + 0x034, 0x0000604A, + 0x034, 0x00005047, + 0x034, 0x0000400A, + 0x034, 0x00003007, + 0x034, 0x00002004, + 0x034, 0x00001001, + 0x034, 0x00000001, + 0x9000000b, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x0000A0D0, + 0x034, 0x000090CD, + 0x034, 0x000080CA, + 0x034, 0x0000704D, + 0x034, 0x0000604A, + 0x034, 0x00005047, + 0x034, 0x0000400A, + 0x034, 0x00003007, + 0x034, 0x00002004, + 0x034, 0x00001001, + 0x034, 0x00000001, + 0xA0000000, 0x00000000, + 0x034, 0x0008ADF6, + 0x034, 0x00089DF3, + 0x034, 0x00088DF0, + 0x034, 0x00087DED, + 0x034, 0x00086DEA, + 0x034, 0x00085CED, + 0x034, 0x00084CEA, + 0x034, 0x000834EA, + 0x034, 0x000824E7, + 0x034, 0x0008146A, + 0x034, 0x0008006B, + 0xB0000000, 0x00000000, + 0x0EF, 0x00000000, + 0x0EF, 0x000020A2, + 0x0DF, 0x00000080, + 0x035, 0x00000192, + 0x035, 0x00008192, + 0x035, 0x00010192, + 0x036, 0x00000024, + 0x036, 0x00008024, + 0x036, 0x00010024, + 0x036, 0x00018024, + 0x0EF, 0x00000000, + 0x051, 0x00000C21, + 0x052, 0x000006D9, + 0x053, 0x000FC649, + 0x054, 0x0000017E, + 0x018, 0x0001012A, + 0x081, 0x0007FC00, + 0x089, 0x00050110, + 0x08A, 0x00043E50, + 0x08B, 0x0002E180, + 0x08C, 0x00093C3C, + 0x80000001, 0x00000000, 0x40000000, 0x00000000, + 0x085, 0x000F8000, + 0x90000006, 0x00000000, 0x40000000, 0x00000000, + 0x085, 0x000F8000, + 0xA0000000, 0x00000000, + 0x085, 0x000F8000, + 0xB0000000, 0x00000000, + 0x80000001, 0x00000000, 0x40000000, 0x00000000, + 0x08D, 0x000FFFF0, + 0x90000002, 0x00000000, 0x40000000, 0x00000000, + 0x08D, 0x000FFFF0, + 0x90000003, 0x00000000, 0x40000000, 0x00000000, + 0x08D, 0x000FFFF0, + 0x90000004, 0x00000000, 0x40000000, 0x00000000, + 0x08D, 0x000FFFF0, + 0x90000005, 0x00000000, 0x40000000, 0x00000000, + 0x08D, 0x000FFFF0, + 0x90000006, 0x00000000, 0x40000000, 0x00000000, + 0x08D, 0x000FFFF0, + 0x90000008, 0x00000000, 0x40000000, 0x00000000, + 0x08D, 0x000FFFF0, + 0x9000000a, 0x00000000, 0x40000000, 0x00000000, + 0x08D, 0x000FFFF0, + 0x9000000b, 0x00000000, 0x40000000, 0x00000000, + 0x08D, 0x000FFFF0, + 0xA0000000, 0x00000000, + 0x08D, 0x000FFFF0, + 0xB0000000, 0x00000000, + 0x0EF, 0x00001000, + 0x03A, 0x0000013C, + 0x03B, 0x00038023, + 0x80000001, 0x00000000, 0x40000000, 0x00000000, + 0x03C, 0x0006C000, + 0x90000002, 0x00000000, 0x40000000, 0x00000000, + 0x03C, 0x000D4000, + 0x90000003, 0x00000000, 0x40000000, 0x00000000, + 0x03C, 0x00080000, + 0x90000004, 0x00000000, 0x40000000, 0x00000000, + 0x03C, 0x00088000, + 0x90000005, 0x00000000, 0x40000000, 0x00000000, + 0x03C, 0x00000000, + 0x90000006, 0x00000000, 0x40000000, 0x00000000, + 0x03C, 0x0006C000, + 0x90000007, 0x00000000, 0x40000000, 0x00000000, + 0x03C, 0x00000000, + 0x90000008, 0x00000000, 0x40000000, 0x00000000, + 0x03C, 0x0008C000, + 0x90000009, 0x00000000, 0x40000000, 0x00000000, + 0x03C, 0x00004000, + 0x9000000a, 0x00000000, 0x40000000, 0x00000000, + 0x03C, 0x00088000, + 0x9000000b, 0x00000000, 0x40000000, 0x00000000, + 0x03C, 0x00088000, + 0xA0000000, 0x00000000, + 0x03C, 0x000A0000, + 0xB0000000, 0x00000000, + 0x03A, 0x0000013C, + 0x03B, 0x00030023, + 0x03C, 0x00048000, + 0x03A, 0x0000013C, + 0x03B, 0x00028623, + 0x03C, 0x00000000, + 0x03A, 0x0000013C, + 0x03B, 0x00021633, + 0x03C, 0x00000000, + 0x03A, 0x0000013C, + 0x03B, 0x0001C633, + 0x03C, 0x00000000, + 0x03A, 0x0000013C, + 0x03B, 0x00010293, + 0x03C, 0x00000000, + 0x03A, 0x0000013C, + 0x03B, 0x00009593, + 0x03C, 0x00000000, + 0x03A, 0x00000148, + 0x80000008, 0x00000000, 0x40000000, 0x00000000, + 0x03B, 0x0000118B, + 0xA0000000, 0x00000000, + 0x03B, 0x0000078B, + 0xB0000000, 0x00000000, + 0x03C, 0x00000000, + 0x80000001, 0x00000000, 0x40000000, 0x00000000, + 0x03A, 0x0000013C, + 0x03B, 0x00078023, + 0x90000002, 0x00000000, 0x40000000, 0x00000000, + 0x03A, 0x0000013C, + 0x03B, 0x00078023, + 0x90000003, 0x00000000, 0x40000000, 0x00000000, + 0x03A, 0x0000013C, + 0x03B, 0x00078023, + 0x90000004, 0x00000000, 0x40000000, 0x00000000, + 0x03A, 0x0000013C, + 0x03B, 0x00078023, + 0x90000005, 0x00000000, 0x40000000, 0x00000000, + 0x03A, 0x0000013C, + 0x03B, 0x00078023, + 0x90000006, 0x00000000, 0x40000000, 0x00000000, + 0x03A, 0x0000013C, + 0x03B, 0x00078023, + 0x90000008, 0x00000000, 0x40000000, 0x00000000, + 0x03A, 0x0000013C, + 0x03B, 0x00078023, + 0x9000000a, 0x00000000, 0x40000000, 0x00000000, + 0x03A, 0x0000013C, + 0x03B, 0x00078023, + 0x9000000b, 0x00000000, 0x40000000, 0x00000000, + 0x03A, 0x0000013C, + 0x03B, 0x00078023, + 0xA0000000, 0x00000000, + 0x03A, 0x0000013C, + 0x03B, 0x00078023, + 0xB0000000, 0x00000000, + 0x80000001, 0x00000000, 0x40000000, 0x00000000, + 0x03C, 0x0004C000, + 0x90000002, 0x00000000, 0x40000000, 0x00000000, + 0x03C, 0x00084000, + 0x90000003, 0x00000000, 0x40000000, 0x00000000, + 0x03C, 0x00000000, + 0x90000004, 0x00000000, 0x40000000, 0x00000000, + 0x03C, 0x00080000, + 0x90000005, 0x00000000, 0x40000000, 0x00000000, + 0x03C, 0x00000000, + 0x90000006, 0x00000000, 0x40000000, 0x00000000, + 0x03C, 0x0004C000, + 0x90000007, 0x00000000, 0x40000000, 0x00000000, + 0x03C, 0x00000000, + 0x90000008, 0x00000000, 0x40000000, 0x00000000, + 0x03C, 0x000D0000, + 0x90000009, 0x00000000, 0x40000000, 0x00000000, + 0x03C, 0x00000000, + 0x9000000a, 0x00000000, 0x40000000, 0x00000000, + 0x03C, 0x00080000, + 0x9000000b, 0x00000000, 0x40000000, 0x00000000, + 0x03C, 0x00080000, + 0xA0000000, 0x00000000, + 0x03C, 0x00028000, + 0xB0000000, 0x00000000, + 0x03A, 0x0000013C, + 0x03B, 0x00070023, + 0x03C, 0x00048000, + 0x03A, 0x0000013C, + 0x03B, 0x00068623, + 0x03C, 0x00000000, + 0x03A, 0x0000013C, + 0x03B, 0x00061633, + 0x03C, 0x00000000, + 0x03A, 0x0000013C, + 0x03B, 0x0005C633, + 0x03C, 0x00000000, + 0x03A, 0x0000013C, + 0x03B, 0x00050293, + 0x03C, 0x00000000, + 0x03A, 0x0000013C, + 0x03B, 0x00049593, + 0x03C, 0x00000000, + 0x03A, 0x00000148, + 0x03B, 0x0004078B, + 0x03C, 0x00000000, + 0x80000001, 0x00000000, 0x40000000, 0x00000000, + 0x03A, 0x0000013C, + 0x03B, 0x000B8023, + 0x90000002, 0x00000000, 0x40000000, 0x00000000, + 0x03A, 0x0000013C, + 0x03B, 0x000B8023, + 0x90000003, 0x00000000, 0x40000000, 0x00000000, + 0x03A, 0x0000013C, + 0x03B, 0x000B8023, + 0x90000004, 0x00000000, 0x40000000, 0x00000000, + 0x03A, 0x0000013C, + 0x03B, 0x000B8023, + 0x90000005, 0x00000000, 0x40000000, 0x00000000, + 0x03A, 0x0000013C, + 0x03B, 0x000B8023, + 0x90000006, 0x00000000, 0x40000000, 0x00000000, + 0x03A, 0x0000013C, + 0x03B, 0x000B8023, + 0x90000008, 0x00000000, 0x40000000, 0x00000000, + 0x03A, 0x0000013C, + 0x03B, 0x000B8023, + 0x9000000a, 0x00000000, 0x40000000, 0x00000000, + 0x03A, 0x0000013C, + 0x03B, 0x000B8023, + 0x9000000b, 0x00000000, 0x40000000, 0x00000000, + 0x03A, 0x0000013C, + 0x03B, 0x000B8023, + 0xA0000000, 0x00000000, + 0x03A, 0x0000013C, + 0x03B, 0x000B8023, + 0xB0000000, 0x00000000, + 0x80000001, 0x00000000, 0x40000000, 0x00000000, + 0x03C, 0x00024000, + 0x90000002, 0x00000000, 0x40000000, 0x00000000, + 0x03C, 0x00060000, + 0x90000003, 0x00000000, 0x40000000, 0x00000000, + 0x03C, 0x00080000, + 0x90000004, 0x00000000, 0x40000000, 0x00000000, + 0x03C, 0x00024000, + 0x90000005, 0x00000000, 0x40000000, 0x00000000, + 0x03C, 0x00000000, + 0x90000006, 0x00000000, 0x40000000, 0x00000000, + 0x03C, 0x00024000, + 0x90000008, 0x00000000, 0x40000000, 0x00000000, + 0x03C, 0x00020000, + 0x90000009, 0x00000000, 0x40000000, 0x00000000, + 0x03C, 0x00000000, + 0x9000000a, 0x00000000, 0x40000000, 0x00000000, + 0x03C, 0x00024000, + 0x9000000b, 0x00000000, 0x40000000, 0x00000000, + 0x03C, 0x00024000, + 0xA0000000, 0x00000000, + 0x03C, 0x00020000, + 0xB0000000, 0x00000000, + 0x03A, 0x0000013C, + 0x03B, 0x000B0023, + 0x80000004, 0x00000000, 0x40000000, 0x00000000, + 0x03C, 0x00020000, + 0x9000000a, 0x00000000, 0x40000000, 0x00000000, + 0x03C, 0x00020000, + 0x9000000b, 0x00000000, 0x40000000, 0x00000000, + 0x03C, 0x00020000, + 0xA0000000, 0x00000000, + 0x03C, 0x00020000, + 0xB0000000, 0x00000000, + 0x03A, 0x0000013C, + 0x03B, 0x000A8623, + 0x03C, 0x00000000, + 0x03A, 0x0000013C, + 0x03B, 0x000A1633, + 0x03C, 0x00000000, + 0x03A, 0x0000013C, + 0x03B, 0x0009C633, + 0x03C, 0x00000000, + 0x03A, 0x0000013C, + 0x03B, 0x00090293, + 0x03C, 0x00000000, + 0x03A, 0x0000013C, + 0x03B, 0x00089593, + 0x03C, 0x00000000, + 0x03A, 0x00000148, + 0x80000008, 0x00000000, 0x40000000, 0x00000000, + 0x03B, 0x0008128B, + 0xA0000000, 0x00000000, + 0x03B, 0x0008078B, + 0xB0000000, 0x00000000, + 0x03C, 0x00000000, + 0x0EF, 0x00000000, + 0x0EF, 0x00000800, + 0x03B, 0x00000000, + 0x80000001, 0x00000000, 0x40000000, 0x00000000, + 0x03A, 0x00000803, + 0x90000002, 0x00000000, 0x40000000, 0x00000000, + 0x03A, 0x00000000, + 0x90000003, 0x00000000, 0x40000000, 0x00000000, + 0x03A, 0x00001803, + 0x90000005, 0x00000000, 0x40000000, 0x00000000, + 0x03A, 0x00001803, + 0x90000006, 0x00000000, 0x40000000, 0x00000000, + 0x03A, 0x00000803, + 0x90000007, 0x00000000, 0x40000000, 0x00000000, + 0x03A, 0x00001003, + 0x90000008, 0x00000000, 0x40000000, 0x00000000, + 0x03A, 0x00001003, + 0x90000009, 0x00000000, 0x40000000, 0x00000000, + 0x03A, 0x00001003, + 0xA0000000, 0x00000000, + 0x03A, 0x00000803, + 0xB0000000, 0x00000000, + 0x03B, 0x00040000, + 0x80000001, 0x00000000, 0x40000000, 0x00000000, + 0x03A, 0x00001000, + 0x90000002, 0x00000000, 0x40000000, 0x00000000, + 0x03A, 0x00000800, + 0x90000003, 0x00000000, 0x40000000, 0x00000000, + 0x03A, 0x00000803, + 0x90000005, 0x00000000, 0x40000000, 0x00000000, + 0x03A, 0x00000803, + 0x90000006, 0x00000000, 0x40000000, 0x00000000, + 0x03A, 0x00001000, + 0x90000007, 0x00000000, 0x40000000, 0x00000000, + 0x03A, 0x00000000, + 0x90000008, 0x00000000, 0x40000000, 0x00000000, + 0x03A, 0x00000000, + 0x90000009, 0x00000000, 0x40000000, 0x00000000, + 0x03A, 0x00000000, + 0xA0000000, 0x00000000, + 0x03A, 0x00001000, + 0xB0000000, 0x00000000, + 0x03B, 0x00080000, + 0x80000003, 0x00000000, 0x40000000, 0x00000000, + 0x03A, 0x00000000, + 0x90000005, 0x00000000, 0x40000000, 0x00000000, + 0x03A, 0x00000000, + 0x90000007, 0x00000000, 0x40000000, 0x00000000, + 0x03A, 0x00001802, + 0x90000009, 0x00000000, 0x40000000, 0x00000000, + 0x03A, 0x00001802, + 0xA0000000, 0x00000000, + 0x03A, 0x00001002, + 0xB0000000, 0x00000000, + 0x0EF, 0x00000000, + 0x80000001, 0x00000000, 0x40000000, 0x00000000, + 0x90000002, 0x00000000, 0x40000000, 0x00000000, + 0x90000003, 0x00000000, 0x40000000, 0x00000000, + 0x90000004, 0x00000000, 0x40000000, 0x00000000, + 0x90000005, 0x00000000, 0x40000000, 0x00000000, + 0x90000006, 0x00000000, 0x40000000, 0x00000000, + 0x90000008, 0x00000000, 0x40000000, 0x00000000, + 0x9000000a, 0x00000000, 0x40000000, 0x00000000, + 0x9000000b, 0x00000000, 0x40000000, 0x00000000, + 0xA0000000, 0x00000000, + 0xB0000000, 0x00000000, + 0x80000002, 0x00000000, 0x40000000, 0x00000000, + 0x018, 0x00013124, + 0x90000003, 0x00000000, 0x40000000, 0x00000000, + 0x018, 0x00013124, + 0x90000004, 0x00000000, 0x40000000, 0x00000000, + 0x018, 0x00013124, + 0x90000005, 0x00000000, 0x40000000, 0x00000000, + 0x018, 0x00013124, + 0x90000008, 0x00000000, 0x40000000, 0x00000000, + 0x018, 0x00013124, + 0x9000000a, 0x00000000, 0x40000000, 0x00000000, + 0x018, 0x00013124, + 0x9000000b, 0x00000000, 0x40000000, 0x00000000, + 0x018, 0x00013124, + 0xA0000000, 0x00000000, + 0x018, 0x00013124, + 0xB0000000, 0x00000000, + 0x0EF, 0x00000100, + 0x80000001, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x0004A38C, + 0x034, 0x000491AD, + 0x034, 0x000481AA, + 0x034, 0x000471A7, + 0x034, 0x000460AA, + 0x034, 0x000450A7, + 0x034, 0x0004402C, + 0x034, 0x00043029, + 0x034, 0x0004200C, + 0x034, 0x00041009, + 0x034, 0x00040006, + 0x90000002, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x0004A3EF, + 0x034, 0x000493AD, + 0x034, 0x0004838A, + 0x034, 0x0004718C, + 0x034, 0x00046189, + 0x034, 0x0004506D, + 0x034, 0x0004404C, + 0x034, 0x0004302C, + 0x034, 0x00042029, + 0x034, 0x00041026, + 0x034, 0x00040023, + 0x90000003, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x0004A3EF, + 0x034, 0x000493AD, + 0x034, 0x0004838A, + 0x034, 0x0004718C, + 0x034, 0x00046189, + 0x034, 0x0004506D, + 0x034, 0x0004404C, + 0x034, 0x0004302C, + 0x034, 0x00042029, + 0x034, 0x00041026, + 0x034, 0x00040023, + 0x90000004, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x0004A3EF, + 0x034, 0x000493AD, + 0x034, 0x0004838A, + 0x034, 0x0004718C, + 0x034, 0x00046189, + 0x034, 0x0004506D, + 0x034, 0x0004404C, + 0x034, 0x0004302C, + 0x034, 0x00042029, + 0x034, 0x00041026, + 0x034, 0x00040023, + 0x90000005, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x0004A3EF, + 0x034, 0x000493AD, + 0x034, 0x0004838A, + 0x034, 0x0004718C, + 0x034, 0x00046189, + 0x034, 0x0004506D, + 0x034, 0x0004404C, + 0x034, 0x0004302C, + 0x034, 0x00042029, + 0x034, 0x00041026, + 0x034, 0x00040023, + 0x90000008, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x0004A3F5, + 0x034, 0x000493F3, + 0x034, 0x00048393, + 0x034, 0x00047390, + 0x034, 0x0004638D, + 0x034, 0x0004538A, + 0x034, 0x00044387, + 0x034, 0x000430ED, + 0x034, 0x000420EA, + 0x034, 0x000410E7, + 0x034, 0x0004002D, + 0x90000009, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x0004AFF7, + 0x034, 0x00049FF6, + 0x034, 0x00048FF3, + 0x034, 0x00047FF0, + 0x034, 0x00046FED, + 0x034, 0x00045FEA, + 0x034, 0x00044FE7, + 0x034, 0x00043CD0, + 0x034, 0x00042CCD, + 0x034, 0x00041CCA, + 0x034, 0x00040CC7, + 0x9000000a, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x0004A3EF, + 0x034, 0x000493AD, + 0x034, 0x0004838A, + 0x034, 0x0004718C, + 0x034, 0x00046189, + 0x034, 0x0004506D, + 0x034, 0x0004404C, + 0x034, 0x0004302C, + 0x034, 0x00042029, + 0x034, 0x00041026, + 0x034, 0x00040023, + 0x9000000b, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x0004A3EF, + 0x034, 0x000493AD, + 0x034, 0x0004838A, + 0x034, 0x0004718C, + 0x034, 0x00046189, + 0x034, 0x0004506D, + 0x034, 0x0004404C, + 0x034, 0x0004302C, + 0x034, 0x00042029, + 0x034, 0x00041026, + 0x034, 0x00040023, + 0xA0000000, 0x00000000, + 0x034, 0x0004AFF4, + 0x034, 0x00049FF1, + 0x034, 0x00048FEE, + 0x034, 0x00047FEB, + 0x034, 0x00046FE8, + 0x034, 0x00045DEA, + 0x034, 0x00044CED, + 0x034, 0x00043CEA, + 0x034, 0x00042C6C, + 0x034, 0x00041C69, + 0x034, 0x00040C2B, + 0xB0000000, 0x00000000, + 0x80000001, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x0002A3EC, + 0x034, 0x0002938C, + 0x034, 0x000281AD, + 0x034, 0x000271AA, + 0x034, 0x000261A7, + 0x034, 0x000250AA, + 0x034, 0x000240A7, + 0x034, 0x0002302C, + 0x034, 0x00022029, + 0x034, 0x0002100C, + 0x034, 0x00020009, + 0x90000002, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x0002A3EC, + 0x034, 0x0002936D, + 0x034, 0x0002836A, + 0x034, 0x0002716D, + 0x034, 0x0002616A, + 0x034, 0x0002506D, + 0x034, 0x0002406A, + 0x034, 0x0002302C, + 0x034, 0x00022029, + 0x034, 0x00021026, + 0x034, 0x00020023, + 0x90000003, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x0002A3EC, + 0x034, 0x000293AC, + 0x034, 0x0002838A, + 0x034, 0x0002718C, + 0x034, 0x00026189, + 0x034, 0x0002506D, + 0x034, 0x0002406A, + 0x034, 0x0002302C, + 0x034, 0x00022029, + 0x034, 0x00021026, + 0x034, 0x00020023, + 0x90000004, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x0002A3EC, + 0x034, 0x0002936D, + 0x034, 0x0002836A, + 0x034, 0x0002716D, + 0x034, 0x0002616A, + 0x034, 0x0002506D, + 0x034, 0x0002406A, + 0x034, 0x0002302C, + 0x034, 0x00022029, + 0x034, 0x00021026, + 0x034, 0x00020023, + 0x90000005, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x0002A3EC, + 0x034, 0x000293AC, + 0x034, 0x0002838A, + 0x034, 0x0002718C, + 0x034, 0x00026189, + 0x034, 0x0002506D, + 0x034, 0x0002406A, + 0x034, 0x0002302C, + 0x034, 0x00022029, + 0x034, 0x00021026, + 0x034, 0x00020023, + 0x90000008, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x0002A3F5, + 0x034, 0x000293F3, + 0x034, 0x000282F2, + 0x034, 0x000272D0, + 0x034, 0x000262CD, + 0x034, 0x000252CA, + 0x034, 0x000242C7, + 0x034, 0x000230CD, + 0x034, 0x000220CA, + 0x034, 0x000210C7, + 0x034, 0x00020086, + 0x90000009, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x0002AFF7, + 0x034, 0x00029FF6, + 0x034, 0x00028FF3, + 0x034, 0x00027FF0, + 0x034, 0x00026FED, + 0x034, 0x00025FEA, + 0x034, 0x00024FE7, + 0x034, 0x00023DEA, + 0x034, 0x00022DE7, + 0x034, 0x00021DE4, + 0x034, 0x00020E44, + 0x9000000a, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x0002A3EC, + 0x034, 0x0002936D, + 0x034, 0x0002836A, + 0x034, 0x0002716D, + 0x034, 0x0002616A, + 0x034, 0x0002506D, + 0x034, 0x0002406A, + 0x034, 0x0002302C, + 0x034, 0x00022029, + 0x034, 0x00021026, + 0x034, 0x00020023, + 0x9000000b, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x0002A3EC, + 0x034, 0x0002936D, + 0x034, 0x0002836A, + 0x034, 0x0002716D, + 0x034, 0x0002616A, + 0x034, 0x0002506D, + 0x034, 0x0002406A, + 0x034, 0x0002302C, + 0x034, 0x00022029, + 0x034, 0x00021026, + 0x034, 0x00020023, + 0xA0000000, 0x00000000, + 0x034, 0x0002AFF4, + 0x034, 0x00029FF1, + 0x034, 0x00028FEE, + 0x034, 0x00027FEB, + 0x034, 0x00026FE8, + 0x034, 0x00025DEA, + 0x034, 0x00024CED, + 0x034, 0x00023CEA, + 0x034, 0x00022C6C, + 0x034, 0x00021C69, + 0x034, 0x00020C2B, + 0xB0000000, 0x00000000, + 0x80000001, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x0000A38C, + 0x034, 0x000091AD, + 0x034, 0x000081AA, + 0x034, 0x000071A7, + 0x034, 0x000060AA, + 0x034, 0x000050A7, + 0x034, 0x0000402C, + 0x034, 0x00003029, + 0x034, 0x0000200C, + 0x034, 0x00001009, + 0x034, 0x00000006, + 0x90000002, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x0000A3EE, + 0x034, 0x000093AB, + 0x034, 0x00008389, + 0x034, 0x0000718C, + 0x034, 0x00006189, + 0x034, 0x0000506D, + 0x034, 0x0000406A, + 0x034, 0x0000302C, + 0x034, 0x00002029, + 0x034, 0x00001026, + 0x034, 0x00000023, + 0x90000003, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x0000A3EE, + 0x034, 0x000093AB, + 0x034, 0x00008389, + 0x034, 0x0000718C, + 0x034, 0x00006189, + 0x034, 0x0000506D, + 0x034, 0x0000406A, + 0x034, 0x0000302C, + 0x034, 0x00002029, + 0x034, 0x00001026, + 0x034, 0x00000023, + 0x90000004, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x0000A3EE, + 0x034, 0x000093AB, + 0x034, 0x00008389, + 0x034, 0x0000718C, + 0x034, 0x00006189, + 0x034, 0x0000506D, + 0x034, 0x0000406A, + 0x034, 0x0000302C, + 0x034, 0x00002029, + 0x034, 0x00001026, + 0x034, 0x00000023, + 0x90000005, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x0000A3EE, + 0x034, 0x000093AB, + 0x034, 0x00008389, + 0x034, 0x0000718C, + 0x034, 0x00006189, + 0x034, 0x0000506D, + 0x034, 0x0000406A, + 0x034, 0x0000302C, + 0x034, 0x00002029, + 0x034, 0x00001026, + 0x034, 0x00000023, + 0x90000008, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x0000A3F5, + 0x034, 0x000093F1, + 0x034, 0x000083B0, + 0x034, 0x00007370, + 0x034, 0x0000636D, + 0x034, 0x0000536A, + 0x034, 0x00004367, + 0x034, 0x0000308E, + 0x034, 0x0000208B, + 0x034, 0x00001088, + 0x034, 0x00000085, + 0x90000009, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x0000AFF7, + 0x034, 0x00009FF5, + 0x034, 0x00008FF2, + 0x034, 0x00007FEF, + 0x034, 0x00006FEC, + 0x034, 0x00005FE9, + 0x034, 0x00004EAA, + 0x034, 0x00003EA7, + 0x034, 0x00002C70, + 0x034, 0x00001C6D, + 0x034, 0x00000C6A, + 0x9000000a, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x0000A3EE, + 0x034, 0x000093AB, + 0x034, 0x00008389, + 0x034, 0x0000718C, + 0x034, 0x00006189, + 0x034, 0x0000506D, + 0x034, 0x0000406A, + 0x034, 0x0000302C, + 0x034, 0x00002029, + 0x034, 0x00001026, + 0x034, 0x00000023, + 0x9000000b, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x0000A3EE, + 0x034, 0x000093AB, + 0x034, 0x00008389, + 0x034, 0x0000718C, + 0x034, 0x00006189, + 0x034, 0x0000506D, + 0x034, 0x0000406A, + 0x034, 0x0000302C, + 0x034, 0x00002029, + 0x034, 0x00001026, + 0x034, 0x00000023, + 0xA0000000, 0x00000000, + 0x034, 0x0000AFF4, + 0x034, 0x00009FF1, + 0x034, 0x00008FEE, + 0x034, 0x00007FEB, + 0x034, 0x00006FE8, + 0x034, 0x00005DEA, + 0x034, 0x00004CED, + 0x034, 0x00003CEA, + 0x034, 0x00002C6C, + 0x034, 0x00001C69, + 0x034, 0x00000C2B, + 0xB0000000, 0x00000000, + 0x80000001, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x000CA38C, + 0x034, 0x000C91AD, + 0x034, 0x000C81AA, + 0x034, 0x000C71A7, + 0x034, 0x000C60AA, + 0x034, 0x000C50A7, + 0x034, 0x000C402C, + 0x034, 0x000C3029, + 0x034, 0x000C200C, + 0x034, 0x000C1009, + 0x034, 0x000C0006, + 0x90000002, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x000CA3EF, + 0x034, 0x000C93AD, + 0x034, 0x000C838A, + 0x034, 0x000C718C, + 0x034, 0x000C6189, + 0x034, 0x000C506D, + 0x034, 0x000C404C, + 0x034, 0x000C302C, + 0x034, 0x000C2029, + 0x034, 0x000C1026, + 0x034, 0x000C0023, + 0x90000003, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x000CA3EF, + 0x034, 0x000C93AD, + 0x034, 0x000C838A, + 0x034, 0x000C718C, + 0x034, 0x000C6189, + 0x034, 0x000C506D, + 0x034, 0x000C404C, + 0x034, 0x000C302C, + 0x034, 0x000C2029, + 0x034, 0x000C1026, + 0x034, 0x000C0023, + 0x90000004, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x000CA3EF, + 0x034, 0x000C93AD, + 0x034, 0x000C838A, + 0x034, 0x000C718C, + 0x034, 0x000C6189, + 0x034, 0x000C506D, + 0x034, 0x000C404C, + 0x034, 0x000C302C, + 0x034, 0x000C2029, + 0x034, 0x000C1026, + 0x034, 0x000C0023, + 0x90000005, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x000CA3EF, + 0x034, 0x000C93AD, + 0x034, 0x000C838A, + 0x034, 0x000C718C, + 0x034, 0x000C6189, + 0x034, 0x000C506D, + 0x034, 0x000C404C, + 0x034, 0x000C302C, + 0x034, 0x000C2029, + 0x034, 0x000C1026, + 0x034, 0x000C0023, + 0x90000008, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x000CA3F5, + 0x034, 0x000C93F3, + 0x034, 0x000C8393, + 0x034, 0x000C7390, + 0x034, 0x000C638D, + 0x034, 0x000C538A, + 0x034, 0x000C4387, + 0x034, 0x000C30ED, + 0x034, 0x000C20EA, + 0x034, 0x000C10E7, + 0x034, 0x000C002D, + 0x90000009, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x000CAFF7, + 0x034, 0x000C9FF6, + 0x034, 0x000C8FF3, + 0x034, 0x000C7FF0, + 0x034, 0x000C6FED, + 0x034, 0x000C5FEA, + 0x034, 0x000C4FE7, + 0x034, 0x000C3CD0, + 0x034, 0x000C2CCD, + 0x034, 0x000C1CCA, + 0x034, 0x000C0CC7, + 0x9000000a, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x000CA3EF, + 0x034, 0x000C93AD, + 0x034, 0x000C838A, + 0x034, 0x000C718C, + 0x034, 0x000C6189, + 0x034, 0x000C506D, + 0x034, 0x000C404C, + 0x034, 0x000C302C, + 0x034, 0x000C2029, + 0x034, 0x000C1026, + 0x034, 0x000C0023, + 0x9000000b, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x000CA3EF, + 0x034, 0x000C93AD, + 0x034, 0x000C838A, + 0x034, 0x000C718C, + 0x034, 0x000C6189, + 0x034, 0x000C506D, + 0x034, 0x000C404C, + 0x034, 0x000C302C, + 0x034, 0x000C2029, + 0x034, 0x000C1026, + 0x034, 0x000C0023, + 0xA0000000, 0x00000000, + 0x034, 0x000CA794, + 0x034, 0x000C9791, + 0x034, 0x000C878E, + 0x034, 0x000C778B, + 0x034, 0x000C658D, + 0x034, 0x000C558A, + 0x034, 0x000C448D, + 0x034, 0x000C348A, + 0x034, 0x000C244C, + 0x034, 0x000C1449, + 0x034, 0x000C042B, + 0xB0000000, 0x00000000, + 0x80000001, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x000AA3EC, + 0x034, 0x000A938C, + 0x034, 0x000A81AD, + 0x034, 0x000A71AA, + 0x034, 0x000A61A7, + 0x034, 0x000A50AA, + 0x034, 0x000A40A7, + 0x034, 0x000A302C, + 0x034, 0x000A2029, + 0x034, 0x000A100C, + 0x034, 0x000A0009, + 0x90000002, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x000AA3EC, + 0x034, 0x000A936D, + 0x034, 0x000A836A, + 0x034, 0x000A716D, + 0x034, 0x000A616A, + 0x034, 0x000A506D, + 0x034, 0x000A406A, + 0x034, 0x000A302C, + 0x034, 0x000A2029, + 0x034, 0x000A1026, + 0x034, 0x000A0023, + 0x90000003, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x000AA3EC, + 0x034, 0x000A93AC, + 0x034, 0x000A838A, + 0x034, 0x000A718C, + 0x034, 0x000A6189, + 0x034, 0x000A506D, + 0x034, 0x000A406A, + 0x034, 0x000A302C, + 0x034, 0x000A2029, + 0x034, 0x000A1026, + 0x034, 0x000A0023, + 0x90000004, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x000AA3EC, + 0x034, 0x000A936D, + 0x034, 0x000A836A, + 0x034, 0x000A716D, + 0x034, 0x000A616A, + 0x034, 0x000A506D, + 0x034, 0x000A406A, + 0x034, 0x000A302C, + 0x034, 0x000A2029, + 0x034, 0x000A1026, + 0x034, 0x000A0023, + 0x90000005, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x000AA3EC, + 0x034, 0x000A93AC, + 0x034, 0x000A838A, + 0x034, 0x000A718C, + 0x034, 0x000A6189, + 0x034, 0x000A506D, + 0x034, 0x000A406A, + 0x034, 0x000A302C, + 0x034, 0x000A2029, + 0x034, 0x000A1026, + 0x034, 0x000A0023, + 0x90000008, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x000AA3F5, + 0x034, 0x000A93F3, + 0x034, 0x000A82F2, + 0x034, 0x000A72D0, + 0x034, 0x000A62CD, + 0x034, 0x000A52CA, + 0x034, 0x000A42C7, + 0x034, 0x000A30CD, + 0x034, 0x000A20CA, + 0x034, 0x000A10C7, + 0x034, 0x000A0086, + 0x90000009, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x000AAFF7, + 0x034, 0x000A9FF6, + 0x034, 0x000A8FF3, + 0x034, 0x000A7FF0, + 0x034, 0x000A6FED, + 0x034, 0x000A5FEA, + 0x034, 0x000A4FE7, + 0x034, 0x000A3DEA, + 0x034, 0x000A2DE7, + 0x034, 0x000A1DE4, + 0x034, 0x000A0E44, + 0x9000000a, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x000AA3EC, + 0x034, 0x000A936D, + 0x034, 0x000A836A, + 0x034, 0x000A716D, + 0x034, 0x000A616A, + 0x034, 0x000A506D, + 0x034, 0x000A406A, + 0x034, 0x000A302C, + 0x034, 0x000A2029, + 0x034, 0x000A1026, + 0x034, 0x000A0023, + 0x9000000b, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x000AA3EC, + 0x034, 0x000A936D, + 0x034, 0x000A836A, + 0x034, 0x000A716D, + 0x034, 0x000A616A, + 0x034, 0x000A506D, + 0x034, 0x000A406A, + 0x034, 0x000A302C, + 0x034, 0x000A2029, + 0x034, 0x000A1026, + 0x034, 0x000A0023, + 0xA0000000, 0x00000000, + 0x034, 0x000AA794, + 0x034, 0x000A9791, + 0x034, 0x000A878E, + 0x034, 0x000A778B, + 0x034, 0x000A658D, + 0x034, 0x000A558A, + 0x034, 0x000A448D, + 0x034, 0x000A348A, + 0x034, 0x000A244C, + 0x034, 0x000A1449, + 0x034, 0x000A042B, + 0xB0000000, 0x00000000, + 0x80000001, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x0008A38C, + 0x034, 0x000891AD, + 0x034, 0x000881AA, + 0x034, 0x000871A7, + 0x034, 0x000860AA, + 0x034, 0x000850A7, + 0x034, 0x0008402C, + 0x034, 0x00083029, + 0x034, 0x0008200C, + 0x034, 0x00081009, + 0x034, 0x00000006, + 0x90000002, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x0008A3EE, + 0x034, 0x000893AB, + 0x034, 0x00088389, + 0x034, 0x0008718C, + 0x034, 0x00086189, + 0x034, 0x0008506D, + 0x034, 0x0008406A, + 0x034, 0x0008302C, + 0x034, 0x00082029, + 0x034, 0x00081026, + 0x034, 0x00080023, + 0x90000003, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x0008A3EE, + 0x034, 0x000893AB, + 0x034, 0x00088389, + 0x034, 0x0008718C, + 0x034, 0x00086189, + 0x034, 0x0008506D, + 0x034, 0x0008406A, + 0x034, 0x0008302C, + 0x034, 0x00082029, + 0x034, 0x00081026, + 0x034, 0x00080023, + 0x90000004, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x0008A3EE, + 0x034, 0x000893AB, + 0x034, 0x00088389, + 0x034, 0x0008718C, + 0x034, 0x00086189, + 0x034, 0x0008506D, + 0x034, 0x0008406A, + 0x034, 0x0008302C, + 0x034, 0x00082029, + 0x034, 0x00081026, + 0x034, 0x00080023, + 0x90000005, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x0008A3EE, + 0x034, 0x000893AB, + 0x034, 0x00088389, + 0x034, 0x0008718C, + 0x034, 0x00086189, + 0x034, 0x0008506D, + 0x034, 0x0008406A, + 0x034, 0x0008302C, + 0x034, 0x00082029, + 0x034, 0x00081026, + 0x034, 0x00080023, + 0x90000008, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x0008A3F5, + 0x034, 0x000893F1, + 0x034, 0x000883B0, + 0x034, 0x00087370, + 0x034, 0x0008636D, + 0x034, 0x0008536A, + 0x034, 0x00084367, + 0x034, 0x0008308E, + 0x034, 0x0008208B, + 0x034, 0x00081088, + 0x034, 0x00080085, + 0x90000009, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x0008AFF7, + 0x034, 0x00089FF5, + 0x034, 0x00088FF2, + 0x034, 0x00087FEF, + 0x034, 0x00086FEC, + 0x034, 0x00085FE9, + 0x034, 0x00084EAA, + 0x034, 0x00083EA7, + 0x034, 0x00082C70, + 0x034, 0x00081C6D, + 0x034, 0x00080C6A, + 0x9000000a, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x0008A3EE, + 0x034, 0x000893AB, + 0x034, 0x00088389, + 0x034, 0x0008718C, + 0x034, 0x00086189, + 0x034, 0x0008506D, + 0x034, 0x0008406A, + 0x034, 0x0008302C, + 0x034, 0x00082029, + 0x034, 0x00081026, + 0x034, 0x00080023, + 0x9000000b, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x0008A3EE, + 0x034, 0x000893AB, + 0x034, 0x00088389, + 0x034, 0x0008718C, + 0x034, 0x00086189, + 0x034, 0x0008506D, + 0x034, 0x0008406A, + 0x034, 0x0008302C, + 0x034, 0x00082029, + 0x034, 0x00081026, + 0x034, 0x00080023, + 0xA0000000, 0x00000000, + 0x034, 0x0008A794, + 0x034, 0x00089791, + 0x034, 0x0008878E, + 0x034, 0x0008778B, + 0x034, 0x0008658D, + 0x034, 0x0008558A, + 0x034, 0x0008448D, + 0x034, 0x0008348A, + 0x034, 0x0008244C, + 0x034, 0x00081449, + 0x034, 0x0008042B, + 0xB0000000, 0x00000000, + 0x0EF, 0x00000000, + 0x80000001, 0x00000000, 0x40000000, 0x00000000, + 0x0DF, 0x00000001, + 0x90000002, 0x00000000, 0x40000000, 0x00000000, + 0x0DF, 0x00000001, + 0x90000003, 0x00000000, 0x40000000, 0x00000000, + 0x0DF, 0x00000001, + 0x90000004, 0x00000000, 0x40000000, 0x00000000, + 0x0DF, 0x00000001, + 0x90000005, 0x00000000, 0x40000000, 0x00000000, + 0x0DF, 0x00000001, + 0x90000008, 0x00000000, 0x40000000, 0x00000000, + 0x0DF, 0x00000001, + 0x9000000a, 0x00000000, 0x40000000, 0x00000000, + 0x0DF, 0x00000001, + 0x9000000b, 0x00000000, 0x40000000, 0x00000000, + 0x0DF, 0x00000001, + 0xA0000000, 0x00000000, + 0x0DF, 0x00000000, + 0xB0000000, 0x00000000, + 0x018, 0x0001712A, + 0x0EF, 0x00000040, + 0x80000001, 0x00000000, 0x40000000, 0x00000000, + 0x035, 0x000006CC, + 0x035, 0x000086CC, + 0x035, 0x000106CC, + 0x035, 0x000206CC, + 0x035, 0x000286CC, + 0x035, 0x000306CC, + 0x035, 0x000406CC, + 0x035, 0x000486CC, + 0x035, 0x000506CC, + 0x035, 0x000806CC, + 0x035, 0x000886CC, + 0x035, 0x000906CC, + 0x035, 0x000A06CC, + 0x035, 0x000A86CC, + 0x035, 0x000B06CC, + 0x035, 0x000C06CC, + 0x035, 0x000C86CC, + 0x035, 0x000D06CC, + 0x90000002, 0x00000000, 0x40000000, 0x00000000, + 0x035, 0x000006CC, + 0x035, 0x000086CC, + 0x035, 0x000106CC, + 0x035, 0x000206CC, + 0x035, 0x000286CC, + 0x035, 0x000306CC, + 0x035, 0x000406CC, + 0x035, 0x000486CC, + 0x035, 0x000506CC, + 0x035, 0x000806CC, + 0x035, 0x000886CC, + 0x035, 0x000906CC, + 0x035, 0x000A06CC, + 0x035, 0x000A86CC, + 0x035, 0x000B06CC, + 0x035, 0x000C06CC, + 0x035, 0x000C86CC, + 0x035, 0x000D06CC, + 0x90000003, 0x00000000, 0x40000000, 0x00000000, + 0x035, 0x000006CC, + 0x035, 0x000086CC, + 0x035, 0x000106CC, + 0x035, 0x000206CC, + 0x035, 0x000286CC, + 0x035, 0x000306CC, + 0x035, 0x000406CC, + 0x035, 0x000486CC, + 0x035, 0x000506CC, + 0x035, 0x000806CC, + 0x035, 0x000886CC, + 0x035, 0x000906CC, + 0x035, 0x000A06CC, + 0x035, 0x000A86CC, + 0x035, 0x000B06CC, + 0x035, 0x000C06CC, + 0x035, 0x000C86CC, + 0x035, 0x000D06CC, + 0x90000004, 0x00000000, 0x40000000, 0x00000000, + 0x035, 0x000006CC, + 0x035, 0x000086CC, + 0x035, 0x000106CC, + 0x035, 0x000206CC, + 0x035, 0x000286CC, + 0x035, 0x000306CC, + 0x035, 0x000406CC, + 0x035, 0x000486CC, + 0x035, 0x000506CC, + 0x035, 0x000806CC, + 0x035, 0x000886CC, + 0x035, 0x000906CC, + 0x035, 0x000A06CC, + 0x035, 0x000A86CC, + 0x035, 0x000B06CC, + 0x035, 0x000C06CC, + 0x035, 0x000C86CC, + 0x035, 0x000D06CC, + 0x90000005, 0x00000000, 0x40000000, 0x00000000, + 0x035, 0x000006CC, + 0x035, 0x000086CC, + 0x035, 0x000106CC, + 0x035, 0x000206CC, + 0x035, 0x000286CC, + 0x035, 0x000306CC, + 0x035, 0x000406CC, + 0x035, 0x000486CC, + 0x035, 0x000506CC, + 0x035, 0x000806CC, + 0x035, 0x000886CC, + 0x035, 0x000906CC, + 0x035, 0x000A06CC, + 0x035, 0x000A86CC, + 0x035, 0x000B06CC, + 0x035, 0x000C06CC, + 0x035, 0x000C86CC, + 0x035, 0x000D06CC, + 0x90000008, 0x00000000, 0x40000000, 0x00000000, + 0x035, 0x000006CC, + 0x035, 0x000086CC, + 0x035, 0x000106CC, + 0x035, 0x000206CC, + 0x035, 0x000286CC, + 0x035, 0x000306CC, + 0x035, 0x000406CC, + 0x035, 0x000486CC, + 0x035, 0x000506CC, + 0x035, 0x000806CC, + 0x035, 0x000886CC, + 0x035, 0x000906CC, + 0x035, 0x000A06CC, + 0x035, 0x000A86CC, + 0x035, 0x000B06CC, + 0x035, 0x000C06CC, + 0x035, 0x000C86CC, + 0x035, 0x000D06CC, + 0x9000000a, 0x00000000, 0x40000000, 0x00000000, + 0x035, 0x000006CC, + 0x035, 0x000086CC, + 0x035, 0x000106CC, + 0x035, 0x000206CC, + 0x035, 0x000286CC, + 0x035, 0x000306CC, + 0x035, 0x000406CC, + 0x035, 0x000486CC, + 0x035, 0x000506CC, + 0x035, 0x000806CC, + 0x035, 0x000886CC, + 0x035, 0x000906CC, + 0x035, 0x000A06CC, + 0x035, 0x000A86CC, + 0x035, 0x000B06CC, + 0x035, 0x000C06CC, + 0x035, 0x000C86CC, + 0x035, 0x000D06CC, + 0x9000000b, 0x00000000, 0x40000000, 0x00000000, + 0x035, 0x000006CC, + 0x035, 0x000086CC, + 0x035, 0x000106CC, + 0x035, 0x000206CC, + 0x035, 0x000286CC, + 0x035, 0x000306CC, + 0x035, 0x000406CC, + 0x035, 0x000486CC, + 0x035, 0x000506CC, + 0x035, 0x000806CC, + 0x035, 0x000886CC, + 0x035, 0x000906CC, + 0x035, 0x000A06CC, + 0x035, 0x000A86CC, + 0x035, 0x000B06CC, + 0x035, 0x000C06CC, + 0x035, 0x000C86CC, + 0x035, 0x000D06CC, + 0xA0000000, 0x00000000, + 0x035, 0x00000484, + 0x035, 0x00008484, + 0x035, 0x00010484, + 0x035, 0x00020584, + 0x035, 0x00028584, + 0x035, 0x00030584, + 0x035, 0x00040584, + 0x035, 0x00048584, + 0x035, 0x00050584, + 0x035, 0x000805FB, + 0x035, 0x000885FB, + 0x035, 0x000905FB, + 0x035, 0x000A05FB, + 0x035, 0x000A85FB, + 0x035, 0x000B05FB, + 0x035, 0x000C05FB, + 0x035, 0x000C85FB, + 0x035, 0x000D05FB, + 0xB0000000, 0x00000000, + 0x0EF, 0x00000000, + 0x80000001, 0x00000000, 0x40000000, 0x00000000, + 0x0DF, 0x00000001, + 0x90000002, 0x00000000, 0x40000000, 0x00000000, + 0x0DF, 0x00000001, + 0x90000003, 0x00000000, 0x40000000, 0x00000000, + 0x0DF, 0x00000001, + 0x90000004, 0x00000000, 0x40000000, 0x00000000, + 0x0DF, 0x00000001, + 0x90000005, 0x00000000, 0x40000000, 0x00000000, + 0x0DF, 0x00000001, + 0x90000008, 0x00000000, 0x40000000, 0x00000000, + 0x0DF, 0x00000001, + 0x9000000a, 0x00000000, 0x40000000, 0x00000000, + 0x0DF, 0x00000001, + 0x9000000b, 0x00000000, 0x40000000, 0x00000000, + 0x0DF, 0x00000001, + 0xA0000000, 0x00000000, + 0x0DF, 0x00000000, + 0xB0000000, 0x00000000, + 0x018, 0x0001712A, + 0x0EF, 0x00000010, + 0x80000001, 0x00000000, 0x40000000, 0x00000000, + 0x036, 0x00000473, + 0x036, 0x00008473, + 0x036, 0x00010473, + 0x036, 0x00020473, + 0x036, 0x00028473, + 0x036, 0x00030473, + 0x036, 0x00040473, + 0x036, 0x00048473, + 0x036, 0x00050473, + 0x036, 0x00080473, + 0x036, 0x00088473, + 0x036, 0x00090473, + 0x036, 0x000A0473, + 0x036, 0x000A8473, + 0x036, 0x000B0473, + 0x036, 0x000C0473, + 0x036, 0x000C8473, + 0x036, 0x000D0473, + 0x90000002, 0x00000000, 0x40000000, 0x00000000, + 0x036, 0x00000475, + 0x036, 0x00008475, + 0x036, 0x00010475, + 0x036, 0x00020475, + 0x036, 0x00028475, + 0x036, 0x00030475, + 0x036, 0x00040475, + 0x036, 0x00048475, + 0x036, 0x00050475, + 0x036, 0x00080475, + 0x036, 0x00088475, + 0x036, 0x00090475, + 0x036, 0x000A0475, + 0x036, 0x000A8475, + 0x036, 0x000B0475, + 0x036, 0x000C0475, + 0x036, 0x000C8475, + 0x036, 0x000D0475, + 0x90000003, 0x00000000, 0x40000000, 0x00000000, + 0x036, 0x00000475, + 0x036, 0x00008475, + 0x036, 0x00010475, + 0x036, 0x00020475, + 0x036, 0x00028475, + 0x036, 0x00030475, + 0x036, 0x00040475, + 0x036, 0x00048475, + 0x036, 0x00050475, + 0x036, 0x00080475, + 0x036, 0x00088475, + 0x036, 0x00090475, + 0x036, 0x000A0475, + 0x036, 0x000A8475, + 0x036, 0x000B0475, + 0x036, 0x000C0475, + 0x036, 0x000C8475, + 0x036, 0x000D0475, + 0x90000004, 0x00000000, 0x40000000, 0x00000000, + 0x036, 0x00000475, + 0x036, 0x00008475, + 0x036, 0x00010475, + 0x036, 0x00020475, + 0x036, 0x00028475, + 0x036, 0x00030475, + 0x036, 0x00040475, + 0x036, 0x00048475, + 0x036, 0x00050475, + 0x036, 0x00080475, + 0x036, 0x00088475, + 0x036, 0x00090475, + 0x036, 0x000A0475, + 0x036, 0x000A8475, + 0x036, 0x000B0475, + 0x036, 0x000C0475, + 0x036, 0x000C8475, + 0x036, 0x000D0475, + 0x90000005, 0x00000000, 0x40000000, 0x00000000, + 0x036, 0x00000475, + 0x036, 0x00008475, + 0x036, 0x00010475, + 0x036, 0x00020475, + 0x036, 0x00028475, + 0x036, 0x00030475, + 0x036, 0x00040475, + 0x036, 0x00048475, + 0x036, 0x00050475, + 0x036, 0x00080475, + 0x036, 0x00088475, + 0x036, 0x00090475, + 0x036, 0x000A0475, + 0x036, 0x000A8475, + 0x036, 0x000B0475, + 0x036, 0x000C0475, + 0x036, 0x000C8475, + 0x036, 0x000D0475, + 0x90000008, 0x00000000, 0x40000000, 0x00000000, + 0x036, 0x00000475, + 0x036, 0x00008475, + 0x036, 0x00010475, + 0x036, 0x00020475, + 0x036, 0x00028475, + 0x036, 0x00030475, + 0x036, 0x00040475, + 0x036, 0x00048475, + 0x036, 0x00050475, + 0x036, 0x00080475, + 0x036, 0x00088475, + 0x036, 0x00090475, + 0x036, 0x000A0475, + 0x036, 0x000A8475, + 0x036, 0x000B0475, + 0x036, 0x000C0475, + 0x036, 0x000C8475, + 0x036, 0x000D0475, + 0x9000000a, 0x00000000, 0x40000000, 0x00000000, + 0x036, 0x00000475, + 0x036, 0x00008475, + 0x036, 0x00010475, + 0x036, 0x00020475, + 0x036, 0x00028475, + 0x036, 0x00030475, + 0x036, 0x00040475, + 0x036, 0x00048475, + 0x036, 0x00050475, + 0x036, 0x00080475, + 0x036, 0x00088475, + 0x036, 0x00090475, + 0x036, 0x000A0475, + 0x036, 0x000A8475, + 0x036, 0x000B0475, + 0x036, 0x000C0475, + 0x036, 0x000C8475, + 0x036, 0x000D0475, + 0x9000000b, 0x00000000, 0x40000000, 0x00000000, + 0x036, 0x00000475, + 0x036, 0x00008475, + 0x036, 0x00010475, + 0x036, 0x00020475, + 0x036, 0x00028475, + 0x036, 0x00030475, + 0x036, 0x00040475, + 0x036, 0x00048475, + 0x036, 0x00050475, + 0x036, 0x00080475, + 0x036, 0x00088475, + 0x036, 0x00090475, + 0x036, 0x000A0475, + 0x036, 0x000A8475, + 0x036, 0x000B0475, + 0x036, 0x000C0475, + 0x036, 0x000C8475, + 0x036, 0x000D0475, + 0xA0000000, 0x00000000, + 0x036, 0x00000474, + 0x036, 0x00008474, + 0x036, 0x00010474, + 0x036, 0x00020474, + 0x036, 0x00028474, + 0x036, 0x00030474, + 0x036, 0x00040474, + 0x036, 0x00048474, + 0x036, 0x00050474, + 0x036, 0x00080474, + 0x036, 0x00088474, + 0x036, 0x00090474, + 0x036, 0x000A0474, + 0x036, 0x000A8474, + 0x036, 0x000B0474, + 0x036, 0x000C0474, + 0x036, 0x000C8474, + 0x036, 0x000D0474, + 0xB0000000, 0x00000000, + 0x0EF, 0x00000000, + 0x80000001, 0x00000000, 0x40000000, 0x00000000, + 0x90000002, 0x00000000, 0x40000000, 0x00000000, + 0x90000003, 0x00000000, 0x40000000, 0x00000000, + 0x90000004, 0x00000000, 0x40000000, 0x00000000, + 0x90000005, 0x00000000, 0x40000000, 0x00000000, + 0x90000008, 0x00000000, 0x40000000, 0x00000000, + 0x9000000a, 0x00000000, 0x40000000, 0x00000000, + 0x9000000b, 0x00000000, 0x40000000, 0x00000000, + 0xA0000000, 0x00000000, + 0x0EF, 0x00000004, + 0x037, 0x00000000, + 0x038, 0x0000514E, + 0x037, 0x00004000, + 0x038, 0x0000514E, + 0x037, 0x00008000, + 0x038, 0x0000514E, + 0x037, 0x00010000, + 0x038, 0x0000514E, + 0x037, 0x00014000, + 0x038, 0x0000514E, + 0x037, 0x00018000, + 0x038, 0x0000514E, + 0x037, 0x0001C000, + 0x038, 0x0000514E, + 0x037, 0x00020000, + 0x038, 0x0000514E, + 0x037, 0x00024000, + 0x038, 0x0000514E, + 0x037, 0x00028000, + 0x038, 0x0000514E, + 0x037, 0x0002C000, + 0x038, 0x0000714E, + 0x037, 0x00030000, + 0x038, 0x0000514E, + 0x037, 0x00034000, + 0x038, 0x0000514E, + 0x037, 0x00038000, + 0x038, 0x0000514E, + 0x037, 0x0003C000, + 0x038, 0x0000514E, + 0x037, 0x00040000, + 0x038, 0x0000514E, + 0x037, 0x00044000, + 0x038, 0x0000514E, + 0x037, 0x00048000, + 0x038, 0x0000514E, + 0x037, 0x00080000, + 0x038, 0x00005ECE, + 0x037, 0x00084000, + 0x038, 0x00005ECE, + 0x037, 0x00088000, + 0x038, 0x00005ECE, + 0x037, 0x00090000, + 0x038, 0x00005ECE, + 0x037, 0x00094000, + 0x038, 0x00005ECE, + 0x037, 0x00098000, + 0x038, 0x00005ECE, + 0x037, 0x0009C000, + 0x038, 0x00005ECE, + 0x037, 0x000A0000, + 0x038, 0x00005ECE, + 0x037, 0x000A4000, + 0x038, 0x00005ECE, + 0x037, 0x000A8000, + 0x038, 0x00005ECE, + 0x037, 0x000AC000, + 0x038, 0x00005ECE, + 0x037, 0x000B0000, + 0x038, 0x00005ECE, + 0x037, 0x000B4000, + 0x038, 0x00005ECE, + 0x037, 0x000B8000, + 0x038, 0x00005ECE, + 0x037, 0x000BC000, + 0x038, 0x00005ECE, + 0x037, 0x000C0000, + 0x038, 0x00005ECE, + 0x037, 0x000C4000, + 0x038, 0x00005ECE, + 0x037, 0x000C8000, + 0x038, 0x00005ECE, + 0x0EF, 0x00000000, + 0xB0000000, 0x00000000, + 0x0EF, 0x00000008, + 0x80000001, 0x00000000, 0x40000000, 0x00000000, + 0x90000002, 0x00000000, 0x40000000, 0x00000000, + 0x90000003, 0x00000000, 0x40000000, 0x00000000, + 0x90000004, 0x00000000, 0x40000000, 0x00000000, + 0x90000005, 0x00000000, 0x40000000, 0x00000000, + 0x90000008, 0x00000000, 0x40000000, 0x00000000, + 0x9000000a, 0x00000000, 0x40000000, 0x00000000, + 0x9000000b, 0x00000000, 0x40000000, 0x00000000, + 0xA0000000, 0x00000000, + 0x03C, 0x0000007D, + 0x03C, 0x0000047D, + 0x03C, 0x0000087D, + 0x03C, 0x0000107D, + 0x03C, 0x0000147D, + 0x03C, 0x0000187D, + 0xB0000000, 0x00000000, + 0x80000001, 0x00000000, 0x40000000, 0x00000000, + 0x03C, 0x0000027D, + 0x03C, 0x00000541, + 0x03C, 0x00000821, + 0x03C, 0x0000127D, + 0x03C, 0x00001541, + 0x03C, 0x00001821, + 0x03C, 0x0000227D, + 0x03C, 0x00002541, + 0x03C, 0x00002821, + 0x90000002, 0x00000000, 0x40000000, 0x00000000, + 0x03C, 0x0000027D, + 0x03C, 0x00000546, + 0x03C, 0x00000821, + 0x03C, 0x0000127D, + 0x03C, 0x00001546, + 0x03C, 0x00001821, + 0x03C, 0x0000227D, + 0x03C, 0x00002546, + 0x03C, 0x00002821, + 0x90000003, 0x00000000, 0x40000000, 0x00000000, + 0x03C, 0x0000027D, + 0x03C, 0x00000546, + 0x03C, 0x00000821, + 0x03C, 0x0000127D, + 0x03C, 0x00001546, + 0x03C, 0x00001821, + 0x03C, 0x0000227D, + 0x03C, 0x00002546, + 0x03C, 0x00002821, + 0x90000004, 0x00000000, 0x40000000, 0x00000000, + 0x03C, 0x0000027D, + 0x03C, 0x00000546, + 0x03C, 0x00000821, + 0x03C, 0x0000127D, + 0x03C, 0x00001546, + 0x03C, 0x00001821, + 0x03C, 0x0000227D, + 0x03C, 0x00002546, + 0x03C, 0x00002821, + 0x90000005, 0x00000000, 0x40000000, 0x00000000, + 0x03C, 0x0000027D, + 0x03C, 0x00000546, + 0x03C, 0x00000821, + 0x03C, 0x0000127D, + 0x03C, 0x00001546, + 0x03C, 0x00001821, + 0x03C, 0x0000227D, + 0x03C, 0x00002546, + 0x03C, 0x00002821, + 0x90000008, 0x00000000, 0x40000000, 0x00000000, + 0x03C, 0x0000027D, + 0x03C, 0x00000546, + 0x03C, 0x00000821, + 0x03C, 0x0000127D, + 0x03C, 0x00001546, + 0x03C, 0x00001821, + 0x03C, 0x0000227D, + 0x03C, 0x00002546, + 0x03C, 0x00002821, + 0x9000000a, 0x00000000, 0x40000000, 0x00000000, + 0x03C, 0x0000027D, + 0x03C, 0x00000546, + 0x03C, 0x00000821, + 0x03C, 0x0000127D, + 0x03C, 0x00001546, + 0x03C, 0x00001821, + 0x03C, 0x0000227D, + 0x03C, 0x00002546, + 0x03C, 0x00002821, + 0x9000000b, 0x00000000, 0x40000000, 0x00000000, + 0x03C, 0x0000027D, + 0x03C, 0x00000546, + 0x03C, 0x00000821, + 0x03C, 0x0000127D, + 0x03C, 0x00001546, + 0x03C, 0x00001821, + 0x03C, 0x0000227D, + 0x03C, 0x00002546, + 0x03C, 0x00002821, + 0xA0000000, 0x00000000, + 0x03C, 0x0000037E, + 0x03C, 0x00000575, + 0x03C, 0x00000971, + 0x03C, 0x0000127E, + 0x03C, 0x00001575, + 0x03C, 0x00001871, + 0x03C, 0x0000217E, + 0x03C, 0x00002575, + 0x03C, 0x00002871, + 0xB0000000, 0x00000000, + 0x0EF, 0x00000000, + 0x061, 0x000C0D47, + 0x062, 0x0000133C, + 0x80000001, 0x00000000, 0x40000000, 0x00000000, + 0x063, 0x000750E7, + 0x90000002, 0x00000000, 0x40000000, 0x00000000, + 0x063, 0x000750E7, + 0x90000003, 0x00000000, 0x40000000, 0x00000000, + 0x063, 0x000750E7, + 0x90000004, 0x00000000, 0x40000000, 0x00000000, + 0x063, 0x000750E7, + 0x90000005, 0x00000000, 0x40000000, 0x00000000, + 0x063, 0x000750E7, + 0x90000008, 0x00000000, 0x40000000, 0x00000000, + 0x063, 0x000750E7, + 0x9000000a, 0x00000000, 0x40000000, 0x00000000, + 0x063, 0x000750E7, + 0x9000000b, 0x00000000, 0x40000000, 0x00000000, + 0x063, 0x000750E7, + 0xA0000000, 0x00000000, + 0x063, 0x0007D0E7, + 0xB0000000, 0x00000000, + 0x064, 0x00014FEC, + 0x80000001, 0x00000000, 0x40000000, 0x00000000, + 0x065, 0x000920D0, + 0x90000002, 0x00000000, 0x40000000, 0x00000000, + 0x065, 0x000920D0, + 0x90000003, 0x00000000, 0x40000000, 0x00000000, + 0x065, 0x000920D0, + 0x90000004, 0x00000000, 0x40000000, 0x00000000, + 0x065, 0x000920D0, + 0x90000005, 0x00000000, 0x40000000, 0x00000000, + 0x065, 0x000920D0, + 0x90000008, 0x00000000, 0x40000000, 0x00000000, + 0x065, 0x000920D0, + 0x9000000a, 0x00000000, 0x40000000, 0x00000000, + 0x065, 0x000920D0, + 0x9000000b, 0x00000000, 0x40000000, 0x00000000, + 0x065, 0x000920D0, + 0xA0000000, 0x00000000, + 0x065, 0x000923FF, + 0xB0000000, 0x00000000, + 0x066, 0x00000040, + 0x057, 0x00050000, + 0x056, 0x00051DF0, + 0x80000001, 0x00000000, 0x40000000, 0x00000000, + 0x90000002, 0x00000000, 0x40000000, 0x00000000, + 0x90000003, 0x00000000, 0x40000000, 0x00000000, + 0x90000004, 0x00000000, 0x40000000, 0x00000000, + 0x90000005, 0x00000000, 0x40000000, 0x00000000, + 0x90000008, 0x00000000, 0x40000000, 0x00000000, + 0x9000000a, 0x00000000, 0x40000000, 0x00000000, + 0x9000000b, 0x00000000, 0x40000000, 0x00000000, + 0xA0000000, 0x00000000, + 0x055, 0x00082060, + 0xB0000000, 0x00000000, +}; + +RTW_DECL_TABLE_RF_RADIO(rtw8814a_rf_c, C); From 9a39196a62548618d1fd86ce91617f343ca930f4 Mon Sep 17 00:00:00 2001 From: Bitterblue Smith Date: Sat, 16 Nov 2024 02:05:00 +0200 Subject: [PATCH 095/193] wifi: rtw88: Add rtw8814a_table.c (part 2/2) Also add rtw8814a_table.h. Signed-off-by: Bitterblue Smith --- rtw8814a_table.c | 11379 +++++++++++++++++++++++++++++++++++++++++++++ rtw8814a_table.h | 40 + 2 files changed, 11419 insertions(+) create mode 100644 rtw8814a_table.h diff --git a/rtw8814a_table.c b/rtw8814a_table.c index 907cbd03..e065cb28 100644 --- a/rtw8814a_table.c +++ b/rtw8814a_table.c @@ -12549,3 +12549,11382 @@ static const u32 rtw8814a_rf_c[] = { }; RTW_DECL_TABLE_RF_RADIO(rtw8814a_rf_c, C); + +static const u32 rtw8814a_rf_d[] = { + 0x018, 0x00013124, + 0x040, 0x00000C00, + 0x058, 0x00000F98, + 0x07F, 0x00068004, + 0x018, 0x00000006, + 0x80000002, 0x00000000, 0x40000000, 0x00000000, + 0x086, 0x000E335A, + 0x087, 0x00079F80, + 0x90000003, 0x00000000, 0x40000000, 0x00000000, + 0x086, 0x000E335A, + 0x087, 0x00079F80, + 0x90000004, 0x00000000, 0x40000000, 0x00000000, + 0x086, 0x000E335A, + 0x087, 0x00079F80, + 0x90000005, 0x00000000, 0x40000000, 0x00000000, + 0x086, 0x000E335A, + 0x087, 0x00079F80, + 0x90000008, 0x00000000, 0x40000000, 0x00000000, + 0x086, 0x000E335A, + 0x087, 0x00079F80, + 0x9000000a, 0x00000000, 0x40000000, 0x00000000, + 0x086, 0x000E335A, + 0x087, 0x00079F80, + 0x9000000b, 0x00000000, 0x40000000, 0x00000000, + 0x086, 0x000E335A, + 0x087, 0x00079F80, + 0xA0000000, 0x00000000, + 0x086, 0x000E4B58, + 0x087, 0x00049F80, + 0xB0000000, 0x00000000, + 0x0DF, 0x00000008, + 0x0EF, 0x00002000, + 0x80000002, 0x00000000, 0x40000000, 0x00000000, + 0x03B, 0x0003F19B, + 0x03B, 0x00037A5B, + 0x03B, 0x0002A433, + 0x03B, 0x00027BD3, + 0x03B, 0x0001F80B, + 0x03B, 0x00017803, + 0x90000003, 0x00000000, 0x40000000, 0x00000000, + 0x03B, 0x0003F09B, + 0x03B, 0x00037A5B, + 0x03B, 0x0002A433, + 0x03B, 0x00027BD3, + 0x03B, 0x0001F80B, + 0x03B, 0x00017803, + 0x90000004, 0x00000000, 0x40000000, 0x00000000, + 0x03B, 0x0003F19B, + 0x03B, 0x00037A5B, + 0x03B, 0x0002A433, + 0x03B, 0x00027BD3, + 0x03B, 0x0001F80B, + 0x03B, 0x00017803, + 0x90000005, 0x00000000, 0x40000000, 0x00000000, + 0x03B, 0x0003F09B, + 0x03B, 0x00037A5B, + 0x03B, 0x0002A433, + 0x03B, 0x00027BD3, + 0x03B, 0x0001F80B, + 0x03B, 0x00017803, + 0x90000008, 0x00000000, 0x40000000, 0x00000000, + 0x03B, 0x0003F19B, + 0x03B, 0x00037A5B, + 0x03B, 0x0002A433, + 0x03B, 0x00027BD3, + 0x03B, 0x0001F80B, + 0x03B, 0x00017803, + 0x9000000a, 0x00000000, 0x40000000, 0x00000000, + 0x03B, 0x0003F19B, + 0x03B, 0x00037A5B, + 0x03B, 0x0002A433, + 0x03B, 0x00027BD3, + 0x03B, 0x0001F80B, + 0x03B, 0x00017803, + 0x9000000b, 0x00000000, 0x40000000, 0x00000000, + 0x03B, 0x0003F19B, + 0x03B, 0x00037A5B, + 0x03B, 0x0002A433, + 0x03B, 0x00027BD3, + 0x03B, 0x0001F80B, + 0x03B, 0x00017803, + 0xA0000000, 0x00000000, + 0x03B, 0x0003F258, + 0x03B, 0x00030A58, + 0x03B, 0x0002FA58, + 0x03B, 0x00022590, + 0x03B, 0x0001FA50, + 0x03B, 0x00010248, + 0x03B, 0x00008240, + 0xB0000000, 0x00000000, + 0x0EF, 0x00000100, + 0x80000002, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x0000A0D0, + 0x034, 0x000090CD, + 0x034, 0x000080CA, + 0x034, 0x0000704D, + 0x034, 0x0000604A, + 0x034, 0x00005047, + 0x034, 0x0000400A, + 0x034, 0x00003007, + 0x034, 0x00002004, + 0x034, 0x00001001, + 0x034, 0x00000001, + 0x90000003, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x0000A0D0, + 0x034, 0x000090CD, + 0x034, 0x000080CA, + 0x034, 0x0000704D, + 0x034, 0x0000604A, + 0x034, 0x00005047, + 0x034, 0x0000400A, + 0x034, 0x00003007, + 0x034, 0x00002004, + 0x034, 0x00001001, + 0x034, 0x00000001, + 0x90000004, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x0000A0D0, + 0x034, 0x000090CD, + 0x034, 0x000080CA, + 0x034, 0x0000704D, + 0x034, 0x0000604A, + 0x034, 0x00005047, + 0x034, 0x0000400A, + 0x034, 0x00003007, + 0x034, 0x00002004, + 0x034, 0x00001001, + 0x034, 0x00000001, + 0x90000005, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x0000A0D0, + 0x034, 0x000090CD, + 0x034, 0x000080CA, + 0x034, 0x0000704D, + 0x034, 0x0000604A, + 0x034, 0x00005047, + 0x034, 0x0000400A, + 0x034, 0x00003007, + 0x034, 0x00002004, + 0x034, 0x00001001, + 0x034, 0x00000001, + 0x90000008, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x0000A0D0, + 0x034, 0x000090CD, + 0x034, 0x000080CA, + 0x034, 0x0000704D, + 0x034, 0x0000604A, + 0x034, 0x00005047, + 0x034, 0x0000400A, + 0x034, 0x00003007, + 0x034, 0x00002004, + 0x034, 0x00001001, + 0x034, 0x00000001, + 0x9000000a, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x0000A0D0, + 0x034, 0x000090CD, + 0x034, 0x000080CA, + 0x034, 0x0000704D, + 0x034, 0x0000604A, + 0x034, 0x00005047, + 0x034, 0x0000400A, + 0x034, 0x00003007, + 0x034, 0x00002004, + 0x034, 0x00001001, + 0x034, 0x00000001, + 0x9000000b, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x0000A0D0, + 0x034, 0x000090CD, + 0x034, 0x000080CA, + 0x034, 0x0000704D, + 0x034, 0x0000604A, + 0x034, 0x00005047, + 0x034, 0x0000400A, + 0x034, 0x00003007, + 0x034, 0x00002004, + 0x034, 0x00001001, + 0x034, 0x00000001, + 0xA0000000, 0x00000000, + 0x034, 0x0000ADF6, + 0x034, 0x00009DF3, + 0x034, 0x00008DF0, + 0x034, 0x00007DED, + 0x034, 0x00006DEA, + 0x034, 0x00005CED, + 0x034, 0x00004CEA, + 0x034, 0x000034EA, + 0x034, 0x000024E7, + 0x034, 0x0000146A, + 0x034, 0x0000006B, + 0xB0000000, 0x00000000, + 0x80000002, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x0000A0D0, + 0x034, 0x000090CD, + 0x034, 0x000080CA, + 0x034, 0x0000704D, + 0x034, 0x0000604A, + 0x034, 0x00005047, + 0x034, 0x0000400A, + 0x034, 0x00003007, + 0x034, 0x00002004, + 0x034, 0x00001001, + 0x034, 0x00000001, + 0x90000003, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x0000A0D0, + 0x034, 0x000090CD, + 0x034, 0x000080CA, + 0x034, 0x0000704D, + 0x034, 0x0000604A, + 0x034, 0x00005047, + 0x034, 0x0000400A, + 0x034, 0x00003007, + 0x034, 0x00002004, + 0x034, 0x00001001, + 0x034, 0x00000001, + 0x90000004, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x0000A0D0, + 0x034, 0x000090CD, + 0x034, 0x000080CA, + 0x034, 0x0000704D, + 0x034, 0x0000604A, + 0x034, 0x00005047, + 0x034, 0x0000400A, + 0x034, 0x00003007, + 0x034, 0x00002004, + 0x034, 0x00001001, + 0x034, 0x00000001, + 0x90000005, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x0000A0D0, + 0x034, 0x000090CD, + 0x034, 0x000080CA, + 0x034, 0x0000704D, + 0x034, 0x0000604A, + 0x034, 0x00005047, + 0x034, 0x0000400A, + 0x034, 0x00003007, + 0x034, 0x00002004, + 0x034, 0x00001001, + 0x034, 0x00000001, + 0x90000008, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x0000A0D0, + 0x034, 0x000090CD, + 0x034, 0x000080CA, + 0x034, 0x0000704D, + 0x034, 0x0000604A, + 0x034, 0x00005047, + 0x034, 0x0000400A, + 0x034, 0x00003007, + 0x034, 0x00002004, + 0x034, 0x00001001, + 0x034, 0x00000001, + 0x9000000a, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x0000A0D0, + 0x034, 0x000090CD, + 0x034, 0x000080CA, + 0x034, 0x0000704D, + 0x034, 0x0000604A, + 0x034, 0x00005047, + 0x034, 0x0000400A, + 0x034, 0x00003007, + 0x034, 0x00002004, + 0x034, 0x00001001, + 0x034, 0x00000001, + 0x9000000b, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x0000A0D0, + 0x034, 0x000090CD, + 0x034, 0x000080CA, + 0x034, 0x0000704D, + 0x034, 0x0000604A, + 0x034, 0x00005047, + 0x034, 0x0000400A, + 0x034, 0x00003007, + 0x034, 0x00002004, + 0x034, 0x00001001, + 0x034, 0x00000001, + 0xA0000000, 0x00000000, + 0x034, 0x0008ADF6, + 0x034, 0x00089DF3, + 0x034, 0x00088DF0, + 0x034, 0x00087DED, + 0x034, 0x00086DEA, + 0x034, 0x00085CED, + 0x034, 0x00084CEA, + 0x034, 0x000834EA, + 0x034, 0x000824E7, + 0x034, 0x0008146A, + 0x034, 0x0008006B, + 0xB0000000, 0x00000000, + 0x0EF, 0x00000000, + 0x0EF, 0x000020A2, + 0x0DF, 0x00000080, + 0x035, 0x00000192, + 0x035, 0x00008192, + 0x035, 0x00010192, + 0x036, 0x00000024, + 0x036, 0x00008024, + 0x036, 0x00010024, + 0x036, 0x00018024, + 0x0EF, 0x00000000, + 0x051, 0x00000C21, + 0x052, 0x000006D9, + 0x053, 0x000FC649, + 0x054, 0x0000017E, + 0x018, 0x0001012A, + 0x081, 0x0007FC00, + 0x089, 0x00050110, + 0x08A, 0x00043E50, + 0x08B, 0x0002E180, + 0x08C, 0x00093C3C, + 0x80000001, 0x00000000, 0x40000000, 0x00000000, + 0x085, 0x000F8000, + 0x90000006, 0x00000000, 0x40000000, 0x00000000, + 0x085, 0x000F8000, + 0xA0000000, 0x00000000, + 0x085, 0x000F8000, + 0xB0000000, 0x00000000, + 0x80000001, 0x00000000, 0x40000000, 0x00000000, + 0x08D, 0x000FFFF0, + 0x90000002, 0x00000000, 0x40000000, 0x00000000, + 0x08D, 0x000FFFF0, + 0x90000003, 0x00000000, 0x40000000, 0x00000000, + 0x08D, 0x000FFFF0, + 0x90000004, 0x00000000, 0x40000000, 0x00000000, + 0x08D, 0x000FFFF0, + 0x90000005, 0x00000000, 0x40000000, 0x00000000, + 0x08D, 0x000FFFF0, + 0x90000006, 0x00000000, 0x40000000, 0x00000000, + 0x08D, 0x000FFFF0, + 0x90000008, 0x00000000, 0x40000000, 0x00000000, + 0x08D, 0x000FFFF0, + 0x9000000a, 0x00000000, 0x40000000, 0x00000000, + 0x08D, 0x000FFFF0, + 0x9000000b, 0x00000000, 0x40000000, 0x00000000, + 0x08D, 0x000FFFF0, + 0xA0000000, 0x00000000, + 0x08D, 0x000FFFF0, + 0xB0000000, 0x00000000, + 0x0EF, 0x00001000, + 0x80000001, 0x00000000, 0x40000000, 0x00000000, + 0x03A, 0x0000013C, + 0x03B, 0x00038023, + 0x90000002, 0x00000000, 0x40000000, 0x00000000, + 0x03A, 0x0000013C, + 0x03B, 0x00038023, + 0x90000003, 0x00000000, 0x40000000, 0x00000000, + 0x03A, 0x0000013C, + 0x03B, 0x00038023, + 0x90000004, 0x00000000, 0x40000000, 0x00000000, + 0x03A, 0x0000013C, + 0x03B, 0x00038023, + 0x90000005, 0x00000000, 0x40000000, 0x00000000, + 0x03A, 0x0000013C, + 0x03B, 0x00038023, + 0x90000006, 0x00000000, 0x40000000, 0x00000000, + 0x03A, 0x0000013C, + 0x03B, 0x00038023, + 0x90000008, 0x00000000, 0x40000000, 0x00000000, + 0x03A, 0x0000013C, + 0x03B, 0x00038023, + 0x9000000a, 0x00000000, 0x40000000, 0x00000000, + 0x03A, 0x0000013C, + 0x03B, 0x00038023, + 0x9000000b, 0x00000000, 0x40000000, 0x00000000, + 0x03A, 0x0000013C, + 0x03B, 0x00038023, + 0xA0000000, 0x00000000, + 0x03A, 0x0000013C, + 0x03B, 0x00038023, + 0xB0000000, 0x00000000, + 0x80000001, 0x00000000, 0x40000000, 0x00000000, + 0x03C, 0x00044000, + 0x90000002, 0x00000000, 0x40000000, 0x00000000, + 0x03C, 0x00048000, + 0x90000003, 0x00000000, 0x40000000, 0x00000000, + 0x03C, 0x00000000, + 0x90000004, 0x00000000, 0x40000000, 0x00000000, + 0x03C, 0x00088000, + 0x90000005, 0x00000000, 0x40000000, 0x00000000, + 0x03C, 0x00000000, + 0x90000006, 0x00000000, 0x40000000, 0x00000000, + 0x03C, 0x00044000, + 0x90000007, 0x00000000, 0x40000000, 0x00000000, + 0x03C, 0x00000000, + 0x90000008, 0x00000000, 0x40000000, 0x00000000, + 0x03C, 0x00088000, + 0x90000009, 0x00000000, 0x40000000, 0x00000000, + 0x03C, 0x00040000, + 0x9000000a, 0x00000000, 0x40000000, 0x00000000, + 0x03C, 0x00088000, + 0x9000000b, 0x00000000, 0x40000000, 0x00000000, + 0x03C, 0x00088000, + 0xA0000000, 0x00000000, + 0x03C, 0x00048000, + 0xB0000000, 0x00000000, + 0x03A, 0x0000013C, + 0x03B, 0x00030023, + 0x03C, 0x00048000, + 0x03A, 0x0000013C, + 0x03B, 0x00028623, + 0x03C, 0x00000000, + 0x03A, 0x0000013C, + 0x03B, 0x00021633, + 0x03C, 0x00000000, + 0x03A, 0x0000013C, + 0x03B, 0x0001C633, + 0x03C, 0x00000000, + 0x03A, 0x0000013C, + 0x03B, 0x00010293, + 0x03C, 0x00000000, + 0x03A, 0x0000013C, + 0x03B, 0x00009593, + 0x03C, 0x00000000, + 0x03A, 0x00000148, + 0x80000008, 0x00000000, 0x40000000, 0x00000000, + 0x03B, 0x00000F8B, + 0xA0000000, 0x00000000, + 0x03B, 0x0000078B, + 0xB0000000, 0x00000000, + 0x03C, 0x00000000, + 0x80000001, 0x00000000, 0x40000000, 0x00000000, + 0x03A, 0x0000013C, + 0x03B, 0x00078023, + 0x90000002, 0x00000000, 0x40000000, 0x00000000, + 0x03A, 0x0000013C, + 0x03B, 0x00078023, + 0x90000003, 0x00000000, 0x40000000, 0x00000000, + 0x03A, 0x0000013C, + 0x03B, 0x00078023, + 0x90000004, 0x00000000, 0x40000000, 0x00000000, + 0x03A, 0x0000013C, + 0x03B, 0x00078023, + 0x90000005, 0x00000000, 0x40000000, 0x00000000, + 0x03A, 0x0000013C, + 0x03B, 0x00078023, + 0x90000006, 0x00000000, 0x40000000, 0x00000000, + 0x03A, 0x0000013C, + 0x03B, 0x00078023, + 0x90000008, 0x00000000, 0x40000000, 0x00000000, + 0x03A, 0x0000013C, + 0x03B, 0x00078023, + 0x9000000a, 0x00000000, 0x40000000, 0x00000000, + 0x03A, 0x0000013C, + 0x03B, 0x00078023, + 0x9000000b, 0x00000000, 0x40000000, 0x00000000, + 0x03A, 0x0000013C, + 0x03B, 0x00078023, + 0xA0000000, 0x00000000, + 0x03A, 0x0000013C, + 0x03B, 0x00078023, + 0xB0000000, 0x00000000, + 0x80000001, 0x00000000, 0x40000000, 0x00000000, + 0x03C, 0x00020000, + 0x90000002, 0x00000000, 0x40000000, 0x00000000, + 0x03C, 0x00020000, + 0x90000003, 0x00000000, 0x40000000, 0x00000000, + 0x03C, 0x00000000, + 0x90000004, 0x00000000, 0x40000000, 0x00000000, + 0x03C, 0x00044000, + 0x90000005, 0x00000000, 0x40000000, 0x00000000, + 0x03C, 0x00000000, + 0x90000006, 0x00000000, 0x40000000, 0x00000000, + 0x03C, 0x00020000, + 0x90000007, 0x00000000, 0x40000000, 0x00000000, + 0x03C, 0x00000000, + 0x90000008, 0x00000000, 0x40000000, 0x00000000, + 0x03C, 0x00020000, + 0x90000009, 0x00000000, 0x40000000, 0x00000000, + 0x03C, 0x00000000, + 0x9000000a, 0x00000000, 0x40000000, 0x00000000, + 0x03C, 0x00044000, + 0x9000000b, 0x00000000, 0x40000000, 0x00000000, + 0x03C, 0x00044000, + 0xA0000000, 0x00000000, + 0x03C, 0x00024000, + 0xB0000000, 0x00000000, + 0x03A, 0x0000013C, + 0x03B, 0x00070023, + 0x03C, 0x00048000, + 0x03A, 0x0000013C, + 0x03B, 0x00068623, + 0x03C, 0x00000000, + 0x03A, 0x0000013C, + 0x03B, 0x00061633, + 0x03C, 0x00000000, + 0x03A, 0x0000013C, + 0x03B, 0x0005C633, + 0x03C, 0x00000000, + 0x03A, 0x0000013C, + 0x03B, 0x00050293, + 0x03C, 0x00000000, + 0x03A, 0x0000013C, + 0x03B, 0x00049593, + 0x03C, 0x00000000, + 0x03A, 0x00000148, + 0x80000008, 0x00000000, 0x40000000, 0x00000000, + 0x03B, 0x00040F8B, + 0xA0000000, 0x00000000, + 0x03B, 0x0004078B, + 0xB0000000, 0x00000000, + 0x03C, 0x00000000, + 0x80000001, 0x00000000, 0x40000000, 0x00000000, + 0x03A, 0x0000013C, + 0x03B, 0x000B8023, + 0x90000002, 0x00000000, 0x40000000, 0x00000000, + 0x03A, 0x0000013C, + 0x03B, 0x000B8023, + 0x90000003, 0x00000000, 0x40000000, 0x00000000, + 0x03A, 0x0000013C, + 0x03B, 0x000B8023, + 0x90000004, 0x00000000, 0x40000000, 0x00000000, + 0x03A, 0x0000013C, + 0x03B, 0x000B8023, + 0x90000005, 0x00000000, 0x40000000, 0x00000000, + 0x03A, 0x0000013C, + 0x03B, 0x000B8023, + 0x90000006, 0x00000000, 0x40000000, 0x00000000, + 0x03A, 0x0000013C, + 0x03B, 0x000B8023, + 0x90000008, 0x00000000, 0x40000000, 0x00000000, + 0x03A, 0x0000013C, + 0x03B, 0x000B8023, + 0x9000000a, 0x00000000, 0x40000000, 0x00000000, + 0x03A, 0x0000013C, + 0x03B, 0x000B8023, + 0x9000000b, 0x00000000, 0x40000000, 0x00000000, + 0x03A, 0x0000013C, + 0x03B, 0x000B8023, + 0xA0000000, 0x00000000, + 0x03A, 0x0000013C, + 0x03B, 0x000B8023, + 0xB0000000, 0x00000000, + 0x80000001, 0x00000000, 0x40000000, 0x00000000, + 0x03C, 0x00004000, + 0x90000002, 0x00000000, 0x40000000, 0x00000000, + 0x03C, 0x00060000, + 0x90000003, 0x00000000, 0x40000000, 0x00000000, + 0x03C, 0x00000000, + 0x90000004, 0x00000000, 0x40000000, 0x00000000, + 0x03C, 0x00024000, + 0x90000005, 0x00000000, 0x40000000, 0x00000000, + 0x03C, 0x00000000, + 0x90000006, 0x00000000, 0x40000000, 0x00000000, + 0x03C, 0x00004000, + 0x90000007, 0x00000000, 0x40000000, 0x00000000, + 0x03C, 0x00000000, + 0x90000008, 0x00000000, 0x40000000, 0x00000000, + 0x03C, 0x00060000, + 0x90000009, 0x00000000, 0x40000000, 0x00000000, + 0x03C, 0x00020000, + 0x9000000a, 0x00000000, 0x40000000, 0x00000000, + 0x03C, 0x00024000, + 0x9000000b, 0x00000000, 0x40000000, 0x00000000, + 0x03C, 0x00024000, + 0xA0000000, 0x00000000, + 0x03C, 0x00004000, + 0xB0000000, 0x00000000, + 0x03A, 0x0000013C, + 0x03B, 0x000B0023, + 0x80000004, 0x00000000, 0x40000000, 0x00000000, + 0x03C, 0x00020000, + 0x9000000a, 0x00000000, 0x40000000, 0x00000000, + 0x03C, 0x00020000, + 0x9000000b, 0x00000000, 0x40000000, 0x00000000, + 0x03C, 0x00020000, + 0xA0000000, 0x00000000, + 0x03C, 0x00020000, + 0xB0000000, 0x00000000, + 0x03A, 0x0000013C, + 0x03B, 0x000A8623, + 0x03C, 0x00000000, + 0x03A, 0x0000013C, + 0x03B, 0x000A1633, + 0x03C, 0x00000000, + 0x03A, 0x0000013C, + 0x03B, 0x0009C633, + 0x03C, 0x00000000, + 0x03A, 0x0000013C, + 0x03B, 0x00090293, + 0x03C, 0x00000000, + 0x03A, 0x0000013C, + 0x03B, 0x00089593, + 0x03C, 0x00000000, + 0x03A, 0x00000148, + 0x80000008, 0x00000000, 0x40000000, 0x00000000, + 0x03B, 0x0008138B, + 0xA0000000, 0x00000000, + 0x03B, 0x0008078B, + 0xB0000000, 0x00000000, + 0x03C, 0x00000000, + 0x0EF, 0x00000000, + 0x0EF, 0x00000800, + 0x03B, 0x00000000, + 0x80000001, 0x00000000, 0x40000000, 0x00000000, + 0x03A, 0x00000803, + 0x90000002, 0x00000000, 0x40000000, 0x00000000, + 0x03A, 0x00000803, + 0x90000003, 0x00000000, 0x40000000, 0x00000000, + 0x03A, 0x00000803, + 0x90000004, 0x00000000, 0x40000000, 0x00000000, + 0x03A, 0x00000803, + 0x90000005, 0x00000000, 0x40000000, 0x00000000, + 0x03A, 0x00000803, + 0x90000006, 0x00000000, 0x40000000, 0x00000000, + 0x03A, 0x00000803, + 0x90000007, 0x00000000, 0x40000000, 0x00000000, + 0x03A, 0x00001003, + 0x90000008, 0x00000000, 0x40000000, 0x00000000, + 0x03A, 0x00001003, + 0x90000009, 0x00000000, 0x40000000, 0x00000000, + 0x03A, 0x00001803, + 0x9000000a, 0x00000000, 0x40000000, 0x00000000, + 0x03A, 0x00000803, + 0x9000000b, 0x00000000, 0x40000000, 0x00000000, + 0x03A, 0x00000803, + 0xA0000000, 0x00000000, + 0x03A, 0x00000803, + 0xB0000000, 0x00000000, + 0x03B, 0x00040000, + 0x80000001, 0x00000000, 0x40000000, 0x00000000, + 0x03A, 0x00001000, + 0x90000002, 0x00000000, 0x40000000, 0x00000000, + 0x03A, 0x00001002, + 0x90000003, 0x00000000, 0x40000000, 0x00000000, + 0x03A, 0x00000000, + 0x90000004, 0x00000000, 0x40000000, 0x00000000, + 0x03A, 0x00001000, + 0x90000005, 0x00000000, 0x40000000, 0x00000000, + 0x03A, 0x00000001, + 0x90000006, 0x00000000, 0x40000000, 0x00000000, + 0x03A, 0x00001000, + 0x90000007, 0x00000000, 0x40000000, 0x00000000, + 0x03A, 0x00000000, + 0x90000008, 0x00000000, 0x40000000, 0x00000000, + 0x03A, 0x00000802, + 0x90000009, 0x00000000, 0x40000000, 0x00000000, + 0x03A, 0x00001803, + 0x9000000a, 0x00000000, 0x40000000, 0x00000000, + 0x03A, 0x00001000, + 0x9000000b, 0x00000000, 0x40000000, 0x00000000, + 0x03A, 0x00001000, + 0xA0000000, 0x00000000, + 0x03A, 0x00001000, + 0xB0000000, 0x00000000, + 0x03B, 0x00080000, + 0x80000007, 0x00000000, 0x40000000, 0x00000000, + 0x03A, 0x00001802, + 0x90000008, 0x00000000, 0x40000000, 0x00000000, + 0x03A, 0x00001000, + 0x90000009, 0x00000000, 0x40000000, 0x00000000, + 0x03A, 0x00000802, + 0xA0000000, 0x00000000, + 0x03A, 0x00001002, + 0xB0000000, 0x00000000, + 0x0EF, 0x00000000, + 0x80000001, 0x00000000, 0x40000000, 0x00000000, + 0x90000002, 0x00000000, 0x40000000, 0x00000000, + 0x90000003, 0x00000000, 0x40000000, 0x00000000, + 0x90000004, 0x00000000, 0x40000000, 0x00000000, + 0x90000005, 0x00000000, 0x40000000, 0x00000000, + 0x90000006, 0x00000000, 0x40000000, 0x00000000, + 0x90000008, 0x00000000, 0x40000000, 0x00000000, + 0x9000000a, 0x00000000, 0x40000000, 0x00000000, + 0x9000000b, 0x00000000, 0x40000000, 0x00000000, + 0xA0000000, 0x00000000, + 0xB0000000, 0x00000000, + 0x018, 0x00013124, + 0x0EF, 0x00000100, + 0x80000001, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x0004A3EB, + 0x034, 0x0004938B, + 0x034, 0x000481AC, + 0x034, 0x000471A9, + 0x034, 0x000460AC, + 0x034, 0x000450A9, + 0x034, 0x0004402E, + 0x034, 0x0004302B, + 0x034, 0x00042028, + 0x034, 0x0004100B, + 0x034, 0x00040008, + 0x90000002, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x0004A3AD, + 0x034, 0x0004938A, + 0x034, 0x0004818C, + 0x034, 0x00047189, + 0x034, 0x0004606D, + 0x034, 0x0004506A, + 0x034, 0x0004402C, + 0x034, 0x00043029, + 0x034, 0x00042026, + 0x034, 0x00041009, + 0x034, 0x00040006, + 0x90000003, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x0004A3AD, + 0x034, 0x0004938A, + 0x034, 0x0004818C, + 0x034, 0x00047189, + 0x034, 0x0004606D, + 0x034, 0x0004506A, + 0x034, 0x0004402C, + 0x034, 0x00043029, + 0x034, 0x00042026, + 0x034, 0x00041009, + 0x034, 0x00040006, + 0x90000004, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x0004A3AD, + 0x034, 0x0004938A, + 0x034, 0x0004818C, + 0x034, 0x00047189, + 0x034, 0x0004606D, + 0x034, 0x0004506A, + 0x034, 0x0004402C, + 0x034, 0x00043029, + 0x034, 0x00042026, + 0x034, 0x00041009, + 0x034, 0x00040006, + 0x90000005, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x0004A3AD, + 0x034, 0x0004938A, + 0x034, 0x0004818C, + 0x034, 0x00047189, + 0x034, 0x0004606D, + 0x034, 0x0004506A, + 0x034, 0x0004402C, + 0x034, 0x00043029, + 0x034, 0x00042026, + 0x034, 0x00041009, + 0x034, 0x00040006, + 0x90000008, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x0004A3F4, + 0x034, 0x000493D2, + 0x034, 0x000482D1, + 0x034, 0x000471F1, + 0x034, 0x000461EE, + 0x034, 0x000451EB, + 0x034, 0x000441E8, + 0x034, 0x0004314B, + 0x034, 0x00042148, + 0x034, 0x0004104B, + 0x034, 0x00040048, + 0x90000009, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x0004AFF7, + 0x034, 0x00049FF6, + 0x034, 0x00048FF3, + 0x034, 0x00047FF0, + 0x034, 0x00046FED, + 0x034, 0x00045FEA, + 0x034, 0x00044FE7, + 0x034, 0x00043CB1, + 0x034, 0x00042CAE, + 0x034, 0x00041CAB, + 0x034, 0x00040CA8, + 0x9000000a, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x0004A3AD, + 0x034, 0x0004938A, + 0x034, 0x0004818C, + 0x034, 0x00047189, + 0x034, 0x0004606D, + 0x034, 0x0004506A, + 0x034, 0x0004402C, + 0x034, 0x00043029, + 0x034, 0x00042026, + 0x034, 0x00041009, + 0x034, 0x00040006, + 0x9000000b, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x0004A3AD, + 0x034, 0x0004938A, + 0x034, 0x0004818C, + 0x034, 0x00047189, + 0x034, 0x0004606D, + 0x034, 0x0004506A, + 0x034, 0x0004402C, + 0x034, 0x00043029, + 0x034, 0x00042026, + 0x034, 0x00041009, + 0x034, 0x00040006, + 0xA0000000, 0x00000000, + 0x034, 0x0004AFF4, + 0x034, 0x00049FF1, + 0x034, 0x00048FEE, + 0x034, 0x00047FEB, + 0x034, 0x00046FE8, + 0x034, 0x00045DEA, + 0x034, 0x00044CED, + 0x034, 0x00043CEA, + 0x034, 0x00042C6C, + 0x034, 0x00041C69, + 0x034, 0x00040C2B, + 0xB0000000, 0x00000000, + 0x80000001, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x0002A3EE, + 0x034, 0x000293EB, + 0x034, 0x0002838B, + 0x034, 0x000271AC, + 0x034, 0x000261A9, + 0x034, 0x000250AC, + 0x034, 0x000240A9, + 0x034, 0x000230A6, + 0x034, 0x0002202C, + 0x034, 0x00021029, + 0x034, 0x00020026, + 0x90000002, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x0002A3AD, + 0x034, 0x0002938A, + 0x034, 0x0002818C, + 0x034, 0x00027189, + 0x034, 0x0002606D, + 0x034, 0x0002504C, + 0x034, 0x0002402C, + 0x034, 0x00023029, + 0x034, 0x00022026, + 0x034, 0x00021023, + 0x034, 0x00020006, + 0x90000003, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x0002A3AD, + 0x034, 0x0002938A, + 0x034, 0x0002818C, + 0x034, 0x00027189, + 0x034, 0x0002606D, + 0x034, 0x0002504C, + 0x034, 0x0002402C, + 0x034, 0x00023029, + 0x034, 0x00022026, + 0x034, 0x00021023, + 0x034, 0x00020006, + 0x90000004, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x0002A3AD, + 0x034, 0x0002938A, + 0x034, 0x0002818C, + 0x034, 0x00027189, + 0x034, 0x0002606D, + 0x034, 0x0002504C, + 0x034, 0x0002402C, + 0x034, 0x00023029, + 0x034, 0x00022026, + 0x034, 0x00021023, + 0x034, 0x00020006, + 0x90000005, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x0002A3AD, + 0x034, 0x0002938A, + 0x034, 0x0002818C, + 0x034, 0x00027189, + 0x034, 0x0002606D, + 0x034, 0x0002504C, + 0x034, 0x0002402C, + 0x034, 0x00023029, + 0x034, 0x00022026, + 0x034, 0x00021023, + 0x034, 0x00020006, + 0x90000008, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x0002A3F5, + 0x034, 0x000293D2, + 0x034, 0x000283CE, + 0x034, 0x00027290, + 0x034, 0x0002628D, + 0x034, 0x0002528A, + 0x034, 0x00024287, + 0x034, 0x0002308D, + 0x034, 0x0002208A, + 0x034, 0x00021087, + 0x034, 0x00020048, + 0x90000009, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x0002AFF7, + 0x034, 0x00029FF6, + 0x034, 0x00028FF3, + 0x034, 0x00027FF0, + 0x034, 0x00026FED, + 0x034, 0x00025FEA, + 0x034, 0x00024FE7, + 0x034, 0x00023DEA, + 0x034, 0x00022DE7, + 0x034, 0x00021DE4, + 0x034, 0x00020D48, + 0x9000000a, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x0002A3AD, + 0x034, 0x0002938A, + 0x034, 0x0002818C, + 0x034, 0x00027189, + 0x034, 0x0002606D, + 0x034, 0x0002504C, + 0x034, 0x0002402C, + 0x034, 0x00023029, + 0x034, 0x00022026, + 0x034, 0x00021023, + 0x034, 0x00020006, + 0x9000000b, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x0002A3AD, + 0x034, 0x0002938A, + 0x034, 0x0002818C, + 0x034, 0x00027189, + 0x034, 0x0002606D, + 0x034, 0x0002504C, + 0x034, 0x0002402C, + 0x034, 0x00023029, + 0x034, 0x00022026, + 0x034, 0x00021023, + 0x034, 0x00020006, + 0xA0000000, 0x00000000, + 0x034, 0x0002AFF4, + 0x034, 0x00029FF1, + 0x034, 0x00028FEE, + 0x034, 0x00027FEB, + 0x034, 0x00026FE8, + 0x034, 0x00025DEA, + 0x034, 0x00024CED, + 0x034, 0x00023CEA, + 0x034, 0x00022C6C, + 0x034, 0x00021C69, + 0x034, 0x00020C2B, + 0xB0000000, 0x00000000, + 0x80000001, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x0000A3EF, + 0x034, 0x000093EC, + 0x034, 0x0000838C, + 0x034, 0x000071AD, + 0x034, 0x000061AA, + 0x034, 0x000050AD, + 0x034, 0x000040AA, + 0x034, 0x0000306A, + 0x034, 0x0000202D, + 0x034, 0x0000102A, + 0x034, 0x00000027, + 0x90000002, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x0000A3EE, + 0x034, 0x000093AC, + 0x034, 0x0000838A, + 0x034, 0x0000718C, + 0x034, 0x00006189, + 0x034, 0x0000506D, + 0x034, 0x0000406A, + 0x034, 0x0000302C, + 0x034, 0x00002029, + 0x034, 0x00001026, + 0x034, 0x00000023, + 0x90000003, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x0000A3EE, + 0x034, 0x000093AC, + 0x034, 0x0000838A, + 0x034, 0x0000718C, + 0x034, 0x00006189, + 0x034, 0x0000506D, + 0x034, 0x0000406A, + 0x034, 0x0000302C, + 0x034, 0x00002029, + 0x034, 0x00001026, + 0x034, 0x00000023, + 0x90000004, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x0000A3EE, + 0x034, 0x000093AC, + 0x034, 0x0000838A, + 0x034, 0x0000718C, + 0x034, 0x00006189, + 0x034, 0x0000506D, + 0x034, 0x0000406A, + 0x034, 0x0000302C, + 0x034, 0x00002029, + 0x034, 0x00001026, + 0x034, 0x00000023, + 0x90000005, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x0000A3EE, + 0x034, 0x000093AC, + 0x034, 0x0000838A, + 0x034, 0x0000718C, + 0x034, 0x00006189, + 0x034, 0x0000506D, + 0x034, 0x0000406A, + 0x034, 0x0000302C, + 0x034, 0x00002029, + 0x034, 0x00001026, + 0x034, 0x00000023, + 0x90000008, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x0000A3F1, + 0x034, 0x000092B1, + 0x034, 0x000081CF, + 0x034, 0x00007170, + 0x034, 0x0000616D, + 0x034, 0x0000516A, + 0x034, 0x00004167, + 0x034, 0x0000302F, + 0x034, 0x0000202C, + 0x034, 0x00001029, + 0x034, 0x00000026, + 0x90000009, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x0000AFF7, + 0x034, 0x00009FF6, + 0x034, 0x00008FF3, + 0x034, 0x00007FF0, + 0x034, 0x00006FED, + 0x034, 0x00005FEA, + 0x034, 0x00004FE7, + 0x034, 0x00003EC7, + 0x034, 0x00002EC4, + 0x034, 0x00001D4B, + 0x034, 0x00000D48, + 0x9000000a, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x0000A3EE, + 0x034, 0x000093AC, + 0x034, 0x0000838A, + 0x034, 0x0000718C, + 0x034, 0x00006189, + 0x034, 0x0000506D, + 0x034, 0x0000406A, + 0x034, 0x0000302C, + 0x034, 0x00002029, + 0x034, 0x00001026, + 0x034, 0x00000023, + 0x9000000b, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x0000A3EE, + 0x034, 0x000093AC, + 0x034, 0x0000838A, + 0x034, 0x0000718C, + 0x034, 0x00006189, + 0x034, 0x0000506D, + 0x034, 0x0000406A, + 0x034, 0x0000302C, + 0x034, 0x00002029, + 0x034, 0x00001026, + 0x034, 0x00000023, + 0xA0000000, 0x00000000, + 0x034, 0x0000AFF4, + 0x034, 0x00009FF1, + 0x034, 0x00008FEE, + 0x034, 0x00007FEB, + 0x034, 0x00006FE8, + 0x034, 0x00005DEA, + 0x034, 0x00004CED, + 0x034, 0x00003CEA, + 0x034, 0x00002C6C, + 0x034, 0x00001C69, + 0x034, 0x00000C2B, + 0xB0000000, 0x00000000, + 0x80000001, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x000CA3EB, + 0x034, 0x000C938B, + 0x034, 0x000C81AC, + 0x034, 0x000C71A9, + 0x034, 0x000C60AC, + 0x034, 0x000C50A9, + 0x034, 0x000C402E, + 0x034, 0x000C302B, + 0x034, 0x000C2028, + 0x034, 0x000C100B, + 0x034, 0x000C0008, + 0x90000002, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x000CA3AD, + 0x034, 0x000C938A, + 0x034, 0x000C818C, + 0x034, 0x000C7189, + 0x034, 0x000C606D, + 0x034, 0x000C506A, + 0x034, 0x000C402C, + 0x034, 0x000C3029, + 0x034, 0x000C2026, + 0x034, 0x000C1009, + 0x034, 0x000C0006, + 0x90000003, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x000CA3AD, + 0x034, 0x000C938A, + 0x034, 0x000C818C, + 0x034, 0x000C7189, + 0x034, 0x000C606D, + 0x034, 0x000C506A, + 0x034, 0x000C402C, + 0x034, 0x000C3029, + 0x034, 0x000C2026, + 0x034, 0x000C1009, + 0x034, 0x000C0006, + 0x90000004, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x000CA3AD, + 0x034, 0x000C938A, + 0x034, 0x000C818C, + 0x034, 0x000C7189, + 0x034, 0x000C606D, + 0x034, 0x000C506A, + 0x034, 0x000C402C, + 0x034, 0x000C3029, + 0x034, 0x000C2026, + 0x034, 0x000C1009, + 0x034, 0x000C0006, + 0x90000005, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x000CA3AD, + 0x034, 0x000C938A, + 0x034, 0x000C818C, + 0x034, 0x000C7189, + 0x034, 0x000C606D, + 0x034, 0x000C506A, + 0x034, 0x000C402C, + 0x034, 0x000C3029, + 0x034, 0x000C2026, + 0x034, 0x000C1009, + 0x034, 0x000C0006, + 0x90000008, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x000CA3F4, + 0x034, 0x000C93D2, + 0x034, 0x000C82D1, + 0x034, 0x000C71F1, + 0x034, 0x000C61EE, + 0x034, 0x000C51EB, + 0x034, 0x000C41E8, + 0x034, 0x000C314B, + 0x034, 0x000C2148, + 0x034, 0x000C104B, + 0x034, 0x000C0048, + 0x90000009, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x000CAFF7, + 0x034, 0x000C9FF6, + 0x034, 0x000C8FF3, + 0x034, 0x000C7FF0, + 0x034, 0x000C6FED, + 0x034, 0x000C5FEA, + 0x034, 0x000C4FE7, + 0x034, 0x000C3CB1, + 0x034, 0x000C2CAE, + 0x034, 0x000C1CAB, + 0x034, 0x000C0CA8, + 0x9000000a, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x000CA3AD, + 0x034, 0x000C938A, + 0x034, 0x000C818C, + 0x034, 0x000C7189, + 0x034, 0x000C606D, + 0x034, 0x000C506A, + 0x034, 0x000C402C, + 0x034, 0x000C3029, + 0x034, 0x000C2026, + 0x034, 0x000C1009, + 0x034, 0x000C0006, + 0x9000000b, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x000CA3AD, + 0x034, 0x000C938A, + 0x034, 0x000C818C, + 0x034, 0x000C7189, + 0x034, 0x000C606D, + 0x034, 0x000C506A, + 0x034, 0x000C402C, + 0x034, 0x000C3029, + 0x034, 0x000C2026, + 0x034, 0x000C1009, + 0x034, 0x000C0006, + 0xA0000000, 0x00000000, + 0x034, 0x000CA794, + 0x034, 0x000C9791, + 0x034, 0x000C878E, + 0x034, 0x000C778B, + 0x034, 0x000C658D, + 0x034, 0x000C558A, + 0x034, 0x000C448D, + 0x034, 0x000C348A, + 0x034, 0x000C244C, + 0x034, 0x000C1449, + 0x034, 0x000C042B, + 0xB0000000, 0x00000000, + 0x80000001, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x000AA3EE, + 0x034, 0x000A93EB, + 0x034, 0x000A838B, + 0x034, 0x000A71AC, + 0x034, 0x000A61A9, + 0x034, 0x000A50AC, + 0x034, 0x000A40A9, + 0x034, 0x000A30A6, + 0x034, 0x000A202C, + 0x034, 0x000A1029, + 0x034, 0x000A0026, + 0x90000002, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x000AA3AD, + 0x034, 0x000A938A, + 0x034, 0x000A818C, + 0x034, 0x000A7189, + 0x034, 0x000A606D, + 0x034, 0x000A504C, + 0x034, 0x000A402C, + 0x034, 0x000A3029, + 0x034, 0x000A2026, + 0x034, 0x000A1023, + 0x034, 0x000A0006, + 0x90000003, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x000AA3AD, + 0x034, 0x000A938A, + 0x034, 0x000A818C, + 0x034, 0x000A7189, + 0x034, 0x000A606D, + 0x034, 0x000A504C, + 0x034, 0x000A402C, + 0x034, 0x000A3029, + 0x034, 0x000A2026, + 0x034, 0x000A1023, + 0x034, 0x000A0006, + 0x90000004, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x000AA3AD, + 0x034, 0x000A938A, + 0x034, 0x000A818C, + 0x034, 0x000A7189, + 0x034, 0x000A606D, + 0x034, 0x000A504C, + 0x034, 0x000A402C, + 0x034, 0x000A3029, + 0x034, 0x000A2026, + 0x034, 0x000A1023, + 0x034, 0x000A0006, + 0x90000005, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x000AA3AD, + 0x034, 0x000A938A, + 0x034, 0x000A818C, + 0x034, 0x000A7189, + 0x034, 0x000A606D, + 0x034, 0x000A504C, + 0x034, 0x000A402C, + 0x034, 0x000A3029, + 0x034, 0x000A2026, + 0x034, 0x000A1023, + 0x034, 0x000A0006, + 0x90000008, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x000AA3F5, + 0x034, 0x000A93D2, + 0x034, 0x000A83CE, + 0x034, 0x000A7290, + 0x034, 0x000A628D, + 0x034, 0x000A528A, + 0x034, 0x000A4287, + 0x034, 0x000A308D, + 0x034, 0x000A208A, + 0x034, 0x000A1087, + 0x034, 0x000A0048, + 0x90000009, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x000AAFF7, + 0x034, 0x000A9FF6, + 0x034, 0x000A8FF3, + 0x034, 0x000A7FF0, + 0x034, 0x000A6FED, + 0x034, 0x000A5FEA, + 0x034, 0x000A4FE7, + 0x034, 0x000A3DEA, + 0x034, 0x000A2DE7, + 0x034, 0x000A1DE4, + 0x034, 0x000A0D48, + 0x9000000a, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x000AA3AD, + 0x034, 0x000A938A, + 0x034, 0x000A818C, + 0x034, 0x000A7189, + 0x034, 0x000A606D, + 0x034, 0x000A504C, + 0x034, 0x000A402C, + 0x034, 0x000A3029, + 0x034, 0x000A2026, + 0x034, 0x000A1023, + 0x034, 0x000A0006, + 0x9000000b, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x000AA3AD, + 0x034, 0x000A938A, + 0x034, 0x000A818C, + 0x034, 0x000A7189, + 0x034, 0x000A606D, + 0x034, 0x000A504C, + 0x034, 0x000A402C, + 0x034, 0x000A3029, + 0x034, 0x000A2026, + 0x034, 0x000A1023, + 0x034, 0x000A0006, + 0xA0000000, 0x00000000, + 0x034, 0x000AA794, + 0x034, 0x000A9791, + 0x034, 0x000A878E, + 0x034, 0x000A778B, + 0x034, 0x000A658D, + 0x034, 0x000A558A, + 0x034, 0x000A448D, + 0x034, 0x000A348A, + 0x034, 0x000A244C, + 0x034, 0x000A1449, + 0x034, 0x000A042B, + 0xB0000000, 0x00000000, + 0x80000001, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x0008A3EF, + 0x034, 0x000893EC, + 0x034, 0x0008838C, + 0x034, 0x000871AD, + 0x034, 0x000861AA, + 0x034, 0x000850AD, + 0x034, 0x000840AA, + 0x034, 0x0008306A, + 0x034, 0x0008202D, + 0x034, 0x0008102A, + 0x034, 0x00080027, + 0x90000002, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x0008A3EE, + 0x034, 0x000893AC, + 0x034, 0x0008838A, + 0x034, 0x0008718C, + 0x034, 0x00086189, + 0x034, 0x0008506D, + 0x034, 0x0008406A, + 0x034, 0x0008302C, + 0x034, 0x00082029, + 0x034, 0x00081026, + 0x034, 0x00080023, + 0x90000003, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x0008A3EE, + 0x034, 0x000893AC, + 0x034, 0x0008838A, + 0x034, 0x0008718C, + 0x034, 0x00086189, + 0x034, 0x0008506D, + 0x034, 0x0008406A, + 0x034, 0x0008302C, + 0x034, 0x00082029, + 0x034, 0x00081026, + 0x034, 0x00080023, + 0x90000004, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x0008A3EE, + 0x034, 0x000893AC, + 0x034, 0x0008838A, + 0x034, 0x0008718C, + 0x034, 0x00086189, + 0x034, 0x0008506D, + 0x034, 0x0008406A, + 0x034, 0x0008302C, + 0x034, 0x00082029, + 0x034, 0x00081026, + 0x034, 0x00080023, + 0x90000005, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x0008A3EE, + 0x034, 0x000893AC, + 0x034, 0x0008838A, + 0x034, 0x0008718C, + 0x034, 0x00086189, + 0x034, 0x0008506D, + 0x034, 0x0008406A, + 0x034, 0x0008302C, + 0x034, 0x00082029, + 0x034, 0x00081026, + 0x034, 0x00080023, + 0x90000008, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x0008A3F1, + 0x034, 0x000892B1, + 0x034, 0x000881CF, + 0x034, 0x00087170, + 0x034, 0x0008616D, + 0x034, 0x0008516A, + 0x034, 0x00084167, + 0x034, 0x0008302F, + 0x034, 0x0008202C, + 0x034, 0x00081029, + 0x034, 0x00080026, + 0x90000009, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x0008AFF7, + 0x034, 0x00089FF6, + 0x034, 0x00088FF3, + 0x034, 0x00087FF0, + 0x034, 0x00086FED, + 0x034, 0x00085FEA, + 0x034, 0x00084FE7, + 0x034, 0x00083EC7, + 0x034, 0x00082EC4, + 0x034, 0x00081D4B, + 0x034, 0x00080D48, + 0x9000000a, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x0008A3EE, + 0x034, 0x000893AC, + 0x034, 0x0008838A, + 0x034, 0x0008718C, + 0x034, 0x00086189, + 0x034, 0x0008506D, + 0x034, 0x0008406A, + 0x034, 0x0008302C, + 0x034, 0x00082029, + 0x034, 0x00081026, + 0x034, 0x00080023, + 0x9000000b, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x0008A3EE, + 0x034, 0x000893AC, + 0x034, 0x0008838A, + 0x034, 0x0008718C, + 0x034, 0x00086189, + 0x034, 0x0008506D, + 0x034, 0x0008406A, + 0x034, 0x0008302C, + 0x034, 0x00082029, + 0x034, 0x00081026, + 0x034, 0x00080023, + 0xA0000000, 0x00000000, + 0x034, 0x0008A794, + 0x034, 0x00089791, + 0x034, 0x0008878E, + 0x034, 0x0008778B, + 0x034, 0x0008658D, + 0x034, 0x0008558A, + 0x034, 0x0008448D, + 0x034, 0x0008348A, + 0x034, 0x0008244C, + 0x034, 0x00081449, + 0x034, 0x0008042B, + 0xB0000000, 0x00000000, + 0x0EF, 0x00000000, + 0x80000001, 0x00000000, 0x40000000, 0x00000000, + 0x0DF, 0x00000001, + 0x90000002, 0x00000000, 0x40000000, 0x00000000, + 0x0DF, 0x00000001, + 0x90000003, 0x00000000, 0x40000000, 0x00000000, + 0x0DF, 0x00000001, + 0x90000004, 0x00000000, 0x40000000, 0x00000000, + 0x0DF, 0x00000001, + 0x90000005, 0x00000000, 0x40000000, 0x00000000, + 0x0DF, 0x00000001, + 0x90000008, 0x00000000, 0x40000000, 0x00000000, + 0x0DF, 0x00000001, + 0x9000000a, 0x00000000, 0x40000000, 0x00000000, + 0x0DF, 0x00000001, + 0x9000000b, 0x00000000, 0x40000000, 0x00000000, + 0x0DF, 0x00000001, + 0xA0000000, 0x00000000, + 0x0DF, 0x00000000, + 0xB0000000, 0x00000000, + 0x018, 0x0001712A, + 0x0EF, 0x00000040, + 0x80000001, 0x00000000, 0x40000000, 0x00000000, + 0x035, 0x000006CC, + 0x035, 0x000086CC, + 0x035, 0x000106CC, + 0x035, 0x000206CC, + 0x035, 0x000286CC, + 0x035, 0x000306CC, + 0x035, 0x000406CC, + 0x035, 0x000486CC, + 0x035, 0x000506CC, + 0x035, 0x000806CC, + 0x035, 0x000886CC, + 0x035, 0x000906CC, + 0x035, 0x000A06CC, + 0x035, 0x000A86CC, + 0x035, 0x000B06CC, + 0x035, 0x000C06CC, + 0x035, 0x000C86CC, + 0x035, 0x000D06CC, + 0x90000002, 0x00000000, 0x40000000, 0x00000000, + 0x035, 0x000006CC, + 0x035, 0x000086CC, + 0x035, 0x000106CC, + 0x035, 0x000206CC, + 0x035, 0x000286CC, + 0x035, 0x000306CC, + 0x035, 0x000406CC, + 0x035, 0x000486CC, + 0x035, 0x000506CC, + 0x035, 0x000806CC, + 0x035, 0x000886CC, + 0x035, 0x000906CC, + 0x035, 0x000A06CC, + 0x035, 0x000A86CC, + 0x035, 0x000B06CC, + 0x035, 0x000C06CC, + 0x035, 0x000C86CC, + 0x035, 0x000D06CC, + 0x90000003, 0x00000000, 0x40000000, 0x00000000, + 0x035, 0x000006CC, + 0x035, 0x000086CC, + 0x035, 0x000106CC, + 0x035, 0x000206CC, + 0x035, 0x000286CC, + 0x035, 0x000306CC, + 0x035, 0x000406CC, + 0x035, 0x000486CC, + 0x035, 0x000506CC, + 0x035, 0x000806CC, + 0x035, 0x000886CC, + 0x035, 0x000906CC, + 0x035, 0x000A06CC, + 0x035, 0x000A86CC, + 0x035, 0x000B06CC, + 0x035, 0x000C06CC, + 0x035, 0x000C86CC, + 0x035, 0x000D06CC, + 0x90000004, 0x00000000, 0x40000000, 0x00000000, + 0x035, 0x000006CC, + 0x035, 0x000086CC, + 0x035, 0x000106CC, + 0x035, 0x000206CC, + 0x035, 0x000286CC, + 0x035, 0x000306CC, + 0x035, 0x000406CC, + 0x035, 0x000486CC, + 0x035, 0x000506CC, + 0x035, 0x000806CC, + 0x035, 0x000886CC, + 0x035, 0x000906CC, + 0x035, 0x000A06CC, + 0x035, 0x000A86CC, + 0x035, 0x000B06CC, + 0x035, 0x000C06CC, + 0x035, 0x000C86CC, + 0x035, 0x000D06CC, + 0x90000005, 0x00000000, 0x40000000, 0x00000000, + 0x035, 0x000006CC, + 0x035, 0x000086CC, + 0x035, 0x000106CC, + 0x035, 0x000206CC, + 0x035, 0x000286CC, + 0x035, 0x000306CC, + 0x035, 0x000406CC, + 0x035, 0x000486CC, + 0x035, 0x000506CC, + 0x035, 0x000806CC, + 0x035, 0x000886CC, + 0x035, 0x000906CC, + 0x035, 0x000A06CC, + 0x035, 0x000A86CC, + 0x035, 0x000B06CC, + 0x035, 0x000C06CC, + 0x035, 0x000C86CC, + 0x035, 0x000D06CC, + 0x90000008, 0x00000000, 0x40000000, 0x00000000, + 0x035, 0x000006CC, + 0x035, 0x000086CC, + 0x035, 0x000106CC, + 0x035, 0x000206CC, + 0x035, 0x000286CC, + 0x035, 0x000306CC, + 0x035, 0x000406CC, + 0x035, 0x000486CC, + 0x035, 0x000506CC, + 0x035, 0x000806CC, + 0x035, 0x000886CC, + 0x035, 0x000906CC, + 0x035, 0x000A06CC, + 0x035, 0x000A86CC, + 0x035, 0x000B06CC, + 0x035, 0x000C06CC, + 0x035, 0x000C86CC, + 0x035, 0x000D06CC, + 0x9000000a, 0x00000000, 0x40000000, 0x00000000, + 0x035, 0x000006CC, + 0x035, 0x000086CC, + 0x035, 0x000106CC, + 0x035, 0x000206CC, + 0x035, 0x000286CC, + 0x035, 0x000306CC, + 0x035, 0x000406CC, + 0x035, 0x000486CC, + 0x035, 0x000506CC, + 0x035, 0x000806CC, + 0x035, 0x000886CC, + 0x035, 0x000906CC, + 0x035, 0x000A06CC, + 0x035, 0x000A86CC, + 0x035, 0x000B06CC, + 0x035, 0x000C06CC, + 0x035, 0x000C86CC, + 0x035, 0x000D06CC, + 0x9000000b, 0x00000000, 0x40000000, 0x00000000, + 0x035, 0x000006CC, + 0x035, 0x000086CC, + 0x035, 0x000106CC, + 0x035, 0x000206CC, + 0x035, 0x000286CC, + 0x035, 0x000306CC, + 0x035, 0x000406CC, + 0x035, 0x000486CC, + 0x035, 0x000506CC, + 0x035, 0x000806CC, + 0x035, 0x000886CC, + 0x035, 0x000906CC, + 0x035, 0x000A06CC, + 0x035, 0x000A86CC, + 0x035, 0x000B06CC, + 0x035, 0x000C06CC, + 0x035, 0x000C86CC, + 0x035, 0x000D06CC, + 0xA0000000, 0x00000000, + 0x035, 0x00000484, + 0x035, 0x00008484, + 0x035, 0x00010484, + 0x035, 0x00020584, + 0x035, 0x00028584, + 0x035, 0x00030584, + 0x035, 0x00040584, + 0x035, 0x00048584, + 0x035, 0x00050584, + 0x035, 0x000805FB, + 0x035, 0x000885FB, + 0x035, 0x000905FB, + 0x035, 0x000A05FB, + 0x035, 0x000A85FB, + 0x035, 0x000B05FB, + 0x035, 0x000C05FB, + 0x035, 0x000C85FB, + 0x035, 0x000D05FB, + 0xB0000000, 0x00000000, + 0x0EF, 0x00000000, + 0x80000001, 0x00000000, 0x40000000, 0x00000000, + 0x0DF, 0x00000001, + 0x90000002, 0x00000000, 0x40000000, 0x00000000, + 0x0DF, 0x00000001, + 0x90000003, 0x00000000, 0x40000000, 0x00000000, + 0x0DF, 0x00000001, + 0x90000004, 0x00000000, 0x40000000, 0x00000000, + 0x0DF, 0x00000001, + 0x90000005, 0x00000000, 0x40000000, 0x00000000, + 0x0DF, 0x00000001, + 0x90000008, 0x00000000, 0x40000000, 0x00000000, + 0x0DF, 0x00000001, + 0x9000000a, 0x00000000, 0x40000000, 0x00000000, + 0x0DF, 0x00000001, + 0x9000000b, 0x00000000, 0x40000000, 0x00000000, + 0x0DF, 0x00000001, + 0xA0000000, 0x00000000, + 0x0DF, 0x00000000, + 0xB0000000, 0x00000000, + 0x018, 0x0001712A, + 0x0EF, 0x00000010, + 0x80000001, 0x00000000, 0x40000000, 0x00000000, + 0x036, 0x00000473, + 0x036, 0x00008473, + 0x036, 0x00010473, + 0x036, 0x00020473, + 0x036, 0x00028473, + 0x036, 0x00030473, + 0x036, 0x00040473, + 0x036, 0x00048473, + 0x036, 0x00050473, + 0x036, 0x00080473, + 0x036, 0x00088473, + 0x036, 0x00090473, + 0x036, 0x000A0473, + 0x036, 0x000A8473, + 0x036, 0x000B0473, + 0x036, 0x000C0473, + 0x036, 0x000C8473, + 0x036, 0x000D0473, + 0x90000002, 0x00000000, 0x40000000, 0x00000000, + 0x036, 0x00000475, + 0x036, 0x00008475, + 0x036, 0x00010475, + 0x036, 0x00020475, + 0x036, 0x00028475, + 0x036, 0x00030475, + 0x036, 0x00040475, + 0x036, 0x00048475, + 0x036, 0x00050475, + 0x036, 0x00080475, + 0x036, 0x00088475, + 0x036, 0x00090475, + 0x036, 0x000A0475, + 0x036, 0x000A8475, + 0x036, 0x000B0475, + 0x036, 0x000C0475, + 0x036, 0x000C8475, + 0x036, 0x000D0475, + 0x90000003, 0x00000000, 0x40000000, 0x00000000, + 0x036, 0x00000475, + 0x036, 0x00008475, + 0x036, 0x00010475, + 0x036, 0x00020475, + 0x036, 0x00028475, + 0x036, 0x00030475, + 0x036, 0x00040475, + 0x036, 0x00048475, + 0x036, 0x00050475, + 0x036, 0x00080475, + 0x036, 0x00088475, + 0x036, 0x00090475, + 0x036, 0x000A0475, + 0x036, 0x000A8475, + 0x036, 0x000B0475, + 0x036, 0x000C0475, + 0x036, 0x000C8475, + 0x036, 0x000D0475, + 0x90000004, 0x00000000, 0x40000000, 0x00000000, + 0x036, 0x00000475, + 0x036, 0x00008475, + 0x036, 0x00010475, + 0x036, 0x00020475, + 0x036, 0x00028475, + 0x036, 0x00030475, + 0x036, 0x00040475, + 0x036, 0x00048475, + 0x036, 0x00050475, + 0x036, 0x00080475, + 0x036, 0x00088475, + 0x036, 0x00090475, + 0x036, 0x000A0475, + 0x036, 0x000A8475, + 0x036, 0x000B0475, + 0x036, 0x000C0475, + 0x036, 0x000C8475, + 0x036, 0x000D0475, + 0x90000005, 0x00000000, 0x40000000, 0x00000000, + 0x036, 0x00000475, + 0x036, 0x00008475, + 0x036, 0x00010475, + 0x036, 0x00020475, + 0x036, 0x00028475, + 0x036, 0x00030475, + 0x036, 0x00040475, + 0x036, 0x00048475, + 0x036, 0x00050475, + 0x036, 0x00080475, + 0x036, 0x00088475, + 0x036, 0x00090475, + 0x036, 0x000A0475, + 0x036, 0x000A8475, + 0x036, 0x000B0475, + 0x036, 0x000C0475, + 0x036, 0x000C8475, + 0x036, 0x000D0475, + 0x90000008, 0x00000000, 0x40000000, 0x00000000, + 0x036, 0x00000475, + 0x036, 0x00008475, + 0x036, 0x00010475, + 0x036, 0x00020475, + 0x036, 0x00028475, + 0x036, 0x00030475, + 0x036, 0x00040475, + 0x036, 0x00048475, + 0x036, 0x00050475, + 0x036, 0x00080475, + 0x036, 0x00088475, + 0x036, 0x00090475, + 0x036, 0x000A0475, + 0x036, 0x000A8475, + 0x036, 0x000B0475, + 0x036, 0x000C0475, + 0x036, 0x000C8475, + 0x036, 0x000D0475, + 0x9000000a, 0x00000000, 0x40000000, 0x00000000, + 0x036, 0x00000475, + 0x036, 0x00008475, + 0x036, 0x00010475, + 0x036, 0x00020475, + 0x036, 0x00028475, + 0x036, 0x00030475, + 0x036, 0x00040475, + 0x036, 0x00048475, + 0x036, 0x00050475, + 0x036, 0x00080475, + 0x036, 0x00088475, + 0x036, 0x00090475, + 0x036, 0x000A0475, + 0x036, 0x000A8475, + 0x036, 0x000B0475, + 0x036, 0x000C0475, + 0x036, 0x000C8475, + 0x036, 0x000D0475, + 0x9000000b, 0x00000000, 0x40000000, 0x00000000, + 0x036, 0x00000475, + 0x036, 0x00008475, + 0x036, 0x00010475, + 0x036, 0x00020475, + 0x036, 0x00028475, + 0x036, 0x00030475, + 0x036, 0x00040475, + 0x036, 0x00048475, + 0x036, 0x00050475, + 0x036, 0x00080475, + 0x036, 0x00088475, + 0x036, 0x00090475, + 0x036, 0x000A0475, + 0x036, 0x000A8475, + 0x036, 0x000B0475, + 0x036, 0x000C0475, + 0x036, 0x000C8475, + 0x036, 0x000D0475, + 0xA0000000, 0x00000000, + 0x036, 0x00000474, + 0x036, 0x00008474, + 0x036, 0x00010474, + 0x036, 0x00020474, + 0x036, 0x00028474, + 0x036, 0x00030474, + 0x036, 0x00040474, + 0x036, 0x00048474, + 0x036, 0x00050474, + 0x036, 0x00080474, + 0x036, 0x00088474, + 0x036, 0x00090474, + 0x036, 0x000A0474, + 0x036, 0x000A8474, + 0x036, 0x000B0474, + 0x036, 0x000C0474, + 0x036, 0x000C8474, + 0x036, 0x000D0474, + 0xB0000000, 0x00000000, + 0x0EF, 0x00000000, + 0x80000001, 0x00000000, 0x40000000, 0x00000000, + 0x90000002, 0x00000000, 0x40000000, 0x00000000, + 0x90000003, 0x00000000, 0x40000000, 0x00000000, + 0x90000004, 0x00000000, 0x40000000, 0x00000000, + 0x90000005, 0x00000000, 0x40000000, 0x00000000, + 0x90000008, 0x00000000, 0x40000000, 0x00000000, + 0x9000000a, 0x00000000, 0x40000000, 0x00000000, + 0x9000000b, 0x00000000, 0x40000000, 0x00000000, + 0xA0000000, 0x00000000, + 0x0EF, 0x00000004, + 0x037, 0x00000000, + 0x038, 0x0000514E, + 0x037, 0x00004000, + 0x038, 0x0000514E, + 0x037, 0x00008000, + 0x038, 0x0000514E, + 0x037, 0x00010000, + 0x038, 0x0000514E, + 0x037, 0x00014000, + 0x038, 0x0000514E, + 0x037, 0x00018000, + 0x038, 0x0000514E, + 0x037, 0x0001C000, + 0x038, 0x0000514E, + 0x037, 0x00020000, + 0x038, 0x0000514E, + 0x037, 0x00024000, + 0x038, 0x0000514E, + 0x037, 0x00028000, + 0x038, 0x0000514E, + 0x037, 0x0002C000, + 0x038, 0x0000714E, + 0x037, 0x00030000, + 0x038, 0x0000514E, + 0x037, 0x00034000, + 0x038, 0x0000514E, + 0x037, 0x00038000, + 0x038, 0x0000514E, + 0x037, 0x0003C000, + 0x038, 0x0000514E, + 0x037, 0x00040000, + 0x038, 0x0000514E, + 0x037, 0x00044000, + 0x038, 0x0000514E, + 0x037, 0x00048000, + 0x038, 0x0000514E, + 0x037, 0x00080000, + 0x038, 0x00005ECE, + 0x037, 0x00084000, + 0x038, 0x00005ECE, + 0x037, 0x00088000, + 0x038, 0x00005ECE, + 0x037, 0x00090000, + 0x038, 0x00005ECE, + 0x037, 0x00094000, + 0x038, 0x00005ECE, + 0x037, 0x00098000, + 0x038, 0x00005ECE, + 0x037, 0x0009C000, + 0x038, 0x00005ECE, + 0x037, 0x000A0000, + 0x038, 0x00005ECE, + 0x037, 0x000A4000, + 0x038, 0x00005ECE, + 0x037, 0x000A8000, + 0x038, 0x00005ECE, + 0x037, 0x000AC000, + 0x038, 0x00005ECE, + 0x037, 0x000B0000, + 0x038, 0x00005ECE, + 0x037, 0x000B4000, + 0x038, 0x00005ECE, + 0x037, 0x000B8000, + 0x038, 0x00005ECE, + 0x037, 0x000BC000, + 0x038, 0x00005ECE, + 0x037, 0x000C0000, + 0x038, 0x00005ECE, + 0x037, 0x000C4000, + 0x038, 0x00005ECE, + 0x037, 0x000C8000, + 0x038, 0x00005ECE, + 0x0EF, 0x00000000, + 0xB0000000, 0x00000000, + 0x0EF, 0x00000008, + 0x80000001, 0x00000000, 0x40000000, 0x00000000, + 0x90000002, 0x00000000, 0x40000000, 0x00000000, + 0x90000003, 0x00000000, 0x40000000, 0x00000000, + 0x90000004, 0x00000000, 0x40000000, 0x00000000, + 0x90000005, 0x00000000, 0x40000000, 0x00000000, + 0x90000008, 0x00000000, 0x40000000, 0x00000000, + 0x9000000a, 0x00000000, 0x40000000, 0x00000000, + 0x9000000b, 0x00000000, 0x40000000, 0x00000000, + 0xA0000000, 0x00000000, + 0x03C, 0x0000007D, + 0x03C, 0x0000047D, + 0x03C, 0x0000087D, + 0x03C, 0x0000107D, + 0x03C, 0x0000147D, + 0x03C, 0x0000187D, + 0xB0000000, 0x00000000, + 0x80000001, 0x00000000, 0x40000000, 0x00000000, + 0x03C, 0x00000275, + 0x03C, 0x00000542, + 0x03C, 0x00000821, + 0x03C, 0x00001275, + 0x03C, 0x00001542, + 0x03C, 0x00001821, + 0x03C, 0x00002275, + 0x03C, 0x00002542, + 0x03C, 0x00002821, + 0x90000002, 0x00000000, 0x40000000, 0x00000000, + 0x03C, 0x0000027F, + 0x03C, 0x00000542, + 0x03C, 0x00000821, + 0x03C, 0x0000127F, + 0x03C, 0x00001542, + 0x03C, 0x00001821, + 0x03C, 0x0000227F, + 0x03C, 0x00002542, + 0x03C, 0x00002821, + 0x90000003, 0x00000000, 0x40000000, 0x00000000, + 0x03C, 0x0000027F, + 0x03C, 0x00000542, + 0x03C, 0x00000821, + 0x03C, 0x0000127F, + 0x03C, 0x00001542, + 0x03C, 0x00001821, + 0x03C, 0x0000227F, + 0x03C, 0x00002542, + 0x03C, 0x00002821, + 0x90000004, 0x00000000, 0x40000000, 0x00000000, + 0x03C, 0x0000027F, + 0x03C, 0x00000542, + 0x03C, 0x00000821, + 0x03C, 0x0000127F, + 0x03C, 0x00001542, + 0x03C, 0x00001821, + 0x03C, 0x0000227F, + 0x03C, 0x00002542, + 0x03C, 0x00002821, + 0x90000005, 0x00000000, 0x40000000, 0x00000000, + 0x03C, 0x0000027F, + 0x03C, 0x00000542, + 0x03C, 0x00000821, + 0x03C, 0x0000127F, + 0x03C, 0x00001542, + 0x03C, 0x00001821, + 0x03C, 0x0000227F, + 0x03C, 0x00002542, + 0x03C, 0x00002821, + 0x90000008, 0x00000000, 0x40000000, 0x00000000, + 0x03C, 0x0000027F, + 0x03C, 0x00000542, + 0x03C, 0x00000821, + 0x03C, 0x0000127F, + 0x03C, 0x00001542, + 0x03C, 0x00001821, + 0x03C, 0x0000227F, + 0x03C, 0x00002542, + 0x03C, 0x00002821, + 0x9000000a, 0x00000000, 0x40000000, 0x00000000, + 0x03C, 0x0000027F, + 0x03C, 0x00000542, + 0x03C, 0x00000821, + 0x03C, 0x0000127F, + 0x03C, 0x00001542, + 0x03C, 0x00001821, + 0x03C, 0x0000227F, + 0x03C, 0x00002542, + 0x03C, 0x00002821, + 0x9000000b, 0x00000000, 0x40000000, 0x00000000, + 0x03C, 0x0000027F, + 0x03C, 0x00000542, + 0x03C, 0x00000821, + 0x03C, 0x0000127F, + 0x03C, 0x00001542, + 0x03C, 0x00001821, + 0x03C, 0x0000227F, + 0x03C, 0x00002542, + 0x03C, 0x00002821, + 0xA0000000, 0x00000000, + 0x03C, 0x0000037E, + 0x03C, 0x00000575, + 0x03C, 0x00000971, + 0x03C, 0x0000127E, + 0x03C, 0x00001575, + 0x03C, 0x00001871, + 0x03C, 0x0000217E, + 0x03C, 0x00002575, + 0x03C, 0x00002871, + 0xB0000000, 0x00000000, + 0x0EF, 0x00000000, + 0x061, 0x000C0D47, + 0x062, 0x0000133C, + 0x80000001, 0x00000000, 0x40000000, 0x00000000, + 0x063, 0x000750E7, + 0x90000002, 0x00000000, 0x40000000, 0x00000000, + 0x063, 0x000750E7, + 0x90000003, 0x00000000, 0x40000000, 0x00000000, + 0x063, 0x000750E7, + 0x90000004, 0x00000000, 0x40000000, 0x00000000, + 0x063, 0x000750E7, + 0x90000005, 0x00000000, 0x40000000, 0x00000000, + 0x063, 0x000750E7, + 0x90000008, 0x00000000, 0x40000000, 0x00000000, + 0x063, 0x000750E7, + 0x9000000a, 0x00000000, 0x40000000, 0x00000000, + 0x063, 0x000750E7, + 0x9000000b, 0x00000000, 0x40000000, 0x00000000, + 0x063, 0x000750E7, + 0xA0000000, 0x00000000, + 0x063, 0x0007D0E7, + 0xB0000000, 0x00000000, + 0x064, 0x00014FEC, + 0x80000001, 0x00000000, 0x40000000, 0x00000000, + 0x065, 0x000920D0, + 0x90000002, 0x00000000, 0x40000000, 0x00000000, + 0x065, 0x000920D0, + 0x90000003, 0x00000000, 0x40000000, 0x00000000, + 0x065, 0x000920D0, + 0x90000004, 0x00000000, 0x40000000, 0x00000000, + 0x065, 0x000920D0, + 0x90000005, 0x00000000, 0x40000000, 0x00000000, + 0x065, 0x000920D0, + 0x90000008, 0x00000000, 0x40000000, 0x00000000, + 0x065, 0x000920D0, + 0x9000000a, 0x00000000, 0x40000000, 0x00000000, + 0x065, 0x000920D0, + 0x9000000b, 0x00000000, 0x40000000, 0x00000000, + 0x065, 0x000920D0, + 0xA0000000, 0x00000000, + 0x065, 0x000923FF, + 0xB0000000, 0x00000000, + 0x066, 0x00000040, + 0x057, 0x00050000, + 0x056, 0x00051DF0, + 0x80000001, 0x00000000, 0x40000000, 0x00000000, + 0x90000002, 0x00000000, 0x40000000, 0x00000000, + 0x90000003, 0x00000000, 0x40000000, 0x00000000, + 0x90000004, 0x00000000, 0x40000000, 0x00000000, + 0x90000005, 0x00000000, 0x40000000, 0x00000000, + 0x90000008, 0x00000000, 0x40000000, 0x00000000, + 0x9000000a, 0x00000000, 0x40000000, 0x00000000, + 0x9000000b, 0x00000000, 0x40000000, 0x00000000, + 0xA0000000, 0x00000000, + 0x055, 0x00082060, + 0xB0000000, 0x00000000, +}; + +RTW_DECL_TABLE_RF_RADIO(rtw8814a_rf_d, D); + +static const struct rtw_txpwr_lmt_cfg_pair rtw8814a_txpwr_lmt[] = { + { 0, 0, 0, 0, 1, 36, }, + { 2, 0, 0, 0, 1, 32, }, + { 1, 0, 0, 0, 1, 32, }, + { 0, 0, 0, 0, 2, 36, }, + { 2, 0, 0, 0, 2, 32, }, + { 1, 0, 0, 0, 2, 32, }, + { 0, 0, 0, 0, 3, 36, }, + { 2, 0, 0, 0, 3, 32, }, + { 1, 0, 0, 0, 3, 32, }, + { 0, 0, 0, 0, 4, 36, }, + { 2, 0, 0, 0, 4, 32, }, + { 1, 0, 0, 0, 4, 32, }, + { 0, 0, 0, 0, 5, 36, }, + { 2, 0, 0, 0, 5, 32, }, + { 1, 0, 0, 0, 5, 32, }, + { 0, 0, 0, 0, 6, 36, }, + { 2, 0, 0, 0, 6, 32, }, + { 1, 0, 0, 0, 6, 32, }, + { 0, 0, 0, 0, 7, 36, }, + { 2, 0, 0, 0, 7, 32, }, + { 1, 0, 0, 0, 7, 32, }, + { 0, 0, 0, 0, 8, 36, }, + { 2, 0, 0, 0, 8, 32, }, + { 1, 0, 0, 0, 8, 32, }, + { 0, 0, 0, 0, 9, 36, }, + { 2, 0, 0, 0, 9, 32, }, + { 1, 0, 0, 0, 9, 32, }, + { 0, 0, 0, 0, 10, 36, }, + { 2, 0, 0, 0, 10, 32, }, + { 1, 0, 0, 0, 10, 32, }, + { 0, 0, 0, 0, 11, 36, }, + { 2, 0, 0, 0, 11, 32, }, + { 1, 0, 0, 0, 11, 32, }, + { 0, 0, 0, 0, 12, 63, }, + { 2, 0, 0, 0, 12, 32, }, + { 1, 0, 0, 0, 12, 32, }, + { 0, 0, 0, 0, 13, 63, }, + { 2, 0, 0, 0, 13, 32, }, + { 1, 0, 0, 0, 13, 32, }, + { 0, 0, 0, 0, 14, 63, }, + { 2, 0, 0, 0, 14, 63, }, + { 1, 0, 0, 0, 14, 32, }, + { 0, 0, 0, 1, 1, 34, }, + { 2, 0, 0, 1, 1, 32, }, + { 1, 0, 0, 1, 1, 32, }, + { 0, 0, 0, 1, 2, 36, }, + { 2, 0, 0, 1, 2, 32, }, + { 1, 0, 0, 1, 2, 32, }, + { 0, 0, 0, 1, 3, 36, }, + { 2, 0, 0, 1, 3, 32, }, + { 1, 0, 0, 1, 3, 32, }, + { 0, 0, 0, 1, 4, 36, }, + { 2, 0, 0, 1, 4, 32, }, + { 1, 0, 0, 1, 4, 32, }, + { 0, 0, 0, 1, 5, 36, }, + { 2, 0, 0, 1, 5, 32, }, + { 1, 0, 0, 1, 5, 32, }, + { 0, 0, 0, 1, 6, 36, }, + { 2, 0, 0, 1, 6, 32, }, + { 1, 0, 0, 1, 6, 32, }, + { 0, 0, 0, 1, 7, 36, }, + { 2, 0, 0, 1, 7, 32, }, + { 1, 0, 0, 1, 7, 32, }, + { 0, 0, 0, 1, 8, 36, }, + { 2, 0, 0, 1, 8, 32, }, + { 1, 0, 0, 1, 8, 32, }, + { 0, 0, 0, 1, 9, 36, }, + { 2, 0, 0, 1, 9, 32, }, + { 1, 0, 0, 1, 9, 32, }, + { 0, 0, 0, 1, 10, 36, }, + { 2, 0, 0, 1, 10, 32, }, + { 1, 0, 0, 1, 10, 32, }, + { 0, 0, 0, 1, 11, 32, }, + { 2, 0, 0, 1, 11, 32, }, + { 1, 0, 0, 1, 11, 32, }, + { 0, 0, 0, 1, 12, 63, }, + { 2, 0, 0, 1, 12, 32, }, + { 1, 0, 0, 1, 12, 32, }, + { 0, 0, 0, 1, 13, 63, }, + { 2, 0, 0, 1, 13, 32, }, + { 1, 0, 0, 1, 13, 32, }, + { 0, 0, 0, 1, 14, 63, }, + { 2, 0, 0, 1, 14, 63, }, + { 1, 0, 0, 1, 14, 63, }, + { 0, 0, 0, 2, 1, 34, }, + { 2, 0, 0, 2, 1, 32, }, + { 1, 0, 0, 2, 1, 32, }, + { 0, 0, 0, 2, 2, 36, }, + { 2, 0, 0, 2, 2, 32, }, + { 1, 0, 0, 2, 2, 32, }, + { 0, 0, 0, 2, 3, 36, }, + { 2, 0, 0, 2, 3, 32, }, + { 1, 0, 0, 2, 3, 32, }, + { 0, 0, 0, 2, 4, 36, }, + { 2, 0, 0, 2, 4, 32, }, + { 1, 0, 0, 2, 4, 32, }, + { 0, 0, 0, 2, 5, 36, }, + { 2, 0, 0, 2, 5, 32, }, + { 1, 0, 0, 2, 5, 32, }, + { 0, 0, 0, 2, 6, 36, }, + { 2, 0, 0, 2, 6, 32, }, + { 1, 0, 0, 2, 6, 32, }, + { 0, 0, 0, 2, 7, 36, }, + { 2, 0, 0, 2, 7, 32, }, + { 1, 0, 0, 2, 7, 32, }, + { 0, 0, 0, 2, 8, 36, }, + { 2, 0, 0, 2, 8, 32, }, + { 1, 0, 0, 2, 8, 32, }, + { 0, 0, 0, 2, 9, 36, }, + { 2, 0, 0, 2, 9, 32, }, + { 1, 0, 0, 2, 9, 32, }, + { 0, 0, 0, 2, 10, 36, }, + { 2, 0, 0, 2, 10, 32, }, + { 1, 0, 0, 2, 10, 32, }, + { 0, 0, 0, 2, 11, 32, }, + { 2, 0, 0, 2, 11, 32, }, + { 1, 0, 0, 2, 11, 32, }, + { 0, 0, 0, 2, 12, 63, }, + { 2, 0, 0, 2, 12, 32, }, + { 1, 0, 0, 2, 12, 32, }, + { 0, 0, 0, 2, 13, 63, }, + { 2, 0, 0, 2, 13, 32, }, + { 1, 0, 0, 2, 13, 32, }, + { 0, 0, 0, 2, 14, 63, }, + { 2, 0, 0, 2, 14, 63, }, + { 1, 0, 0, 2, 14, 63, }, + { 0, 0, 0, 3, 1, 32, }, + { 2, 0, 0, 3, 1, 30, }, + { 1, 0, 0, 3, 1, 30, }, + { 0, 0, 0, 3, 2, 34, }, + { 2, 0, 0, 3, 2, 30, }, + { 1, 0, 0, 3, 2, 30, }, + { 0, 0, 0, 3, 3, 34, }, + { 2, 0, 0, 3, 3, 30, }, + { 1, 0, 0, 3, 3, 30, }, + { 0, 0, 0, 3, 4, 34, }, + { 2, 0, 0, 3, 4, 30, }, + { 1, 0, 0, 3, 4, 30, }, + { 0, 0, 0, 3, 5, 34, }, + { 2, 0, 0, 3, 5, 30, }, + { 1, 0, 0, 3, 5, 30, }, + { 0, 0, 0, 3, 6, 34, }, + { 2, 0, 0, 3, 6, 30, }, + { 1, 0, 0, 3, 6, 30, }, + { 0, 0, 0, 3, 7, 34, }, + { 2, 0, 0, 3, 7, 30, }, + { 1, 0, 0, 3, 7, 30, }, + { 0, 0, 0, 3, 8, 34, }, + { 2, 0, 0, 3, 8, 30, }, + { 1, 0, 0, 3, 8, 30, }, + { 0, 0, 0, 3, 9, 34, }, + { 2, 0, 0, 3, 9, 30, }, + { 1, 0, 0, 3, 9, 30, }, + { 0, 0, 0, 3, 10, 34, }, + { 2, 0, 0, 3, 10, 30, }, + { 1, 0, 0, 3, 10, 30, }, + { 0, 0, 0, 3, 11, 30, }, + { 2, 0, 0, 3, 11, 30, }, + { 1, 0, 0, 3, 11, 30, }, + { 0, 0, 0, 3, 12, 63, }, + { 2, 0, 0, 3, 12, 30, }, + { 1, 0, 0, 3, 12, 30, }, + { 0, 0, 0, 3, 13, 63, }, + { 2, 0, 0, 3, 13, 30, }, + { 1, 0, 0, 3, 13, 30, }, + { 0, 0, 0, 3, 14, 63, }, + { 2, 0, 0, 3, 14, 63, }, + { 1, 0, 0, 3, 14, 63, }, + { 0, 0, 0, 6, 1, 30, }, + { 2, 0, 0, 6, 1, 28, }, + { 1, 0, 0, 6, 1, 28, }, + { 0, 0, 0, 6, 2, 32, }, + { 2, 0, 0, 6, 2, 28, }, + { 1, 0, 0, 6, 2, 28, }, + { 0, 0, 0, 6, 3, 32, }, + { 2, 0, 0, 6, 3, 28, }, + { 1, 0, 0, 6, 3, 28, }, + { 0, 0, 0, 6, 4, 32, }, + { 2, 0, 0, 6, 4, 28, }, + { 1, 0, 0, 6, 4, 28, }, + { 0, 0, 0, 6, 5, 32, }, + { 2, 0, 0, 6, 5, 28, }, + { 1, 0, 0, 6, 5, 28, }, + { 0, 0, 0, 6, 6, 32, }, + { 2, 0, 0, 6, 6, 28, }, + { 1, 0, 0, 6, 6, 28, }, + { 0, 0, 0, 6, 7, 32, }, + { 2, 0, 0, 6, 7, 28, }, + { 1, 0, 0, 6, 7, 28, }, + { 0, 0, 0, 6, 8, 32, }, + { 2, 0, 0, 6, 8, 28, }, + { 1, 0, 0, 6, 8, 28, }, + { 0, 0, 0, 6, 9, 32, }, + { 2, 0, 0, 6, 9, 28, }, + { 1, 0, 0, 6, 9, 28, }, + { 0, 0, 0, 6, 10, 32, }, + { 2, 0, 0, 6, 10, 28, }, + { 1, 0, 0, 6, 10, 28, }, + { 0, 0, 0, 6, 11, 28, }, + { 2, 0, 0, 6, 11, 28, }, + { 1, 0, 0, 6, 11, 28, }, + { 0, 0, 0, 6, 12, 63, }, + { 2, 0, 0, 6, 12, 28, }, + { 1, 0, 0, 6, 12, 28, }, + { 0, 0, 0, 6, 13, 63, }, + { 2, 0, 0, 6, 13, 28, }, + { 1, 0, 0, 6, 13, 28, }, + { 0, 0, 0, 6, 14, 63, }, + { 2, 0, 0, 6, 14, 63, }, + { 1, 0, 0, 6, 14, 63, }, + { 0, 0, 0, 7, 1, 28, }, + { 2, 0, 0, 7, 1, 26, }, + { 1, 0, 0, 7, 1, 26, }, + { 0, 0, 0, 7, 2, 30, }, + { 2, 0, 0, 7, 2, 26, }, + { 1, 0, 0, 7, 2, 26, }, + { 0, 0, 0, 7, 3, 30, }, + { 2, 0, 0, 7, 3, 26, }, + { 1, 0, 0, 7, 3, 26, }, + { 0, 0, 0, 7, 4, 30, }, + { 2, 0, 0, 7, 4, 26, }, + { 1, 0, 0, 7, 4, 26, }, + { 0, 0, 0, 7, 5, 30, }, + { 2, 0, 0, 7, 5, 26, }, + { 1, 0, 0, 7, 5, 26, }, + { 0, 0, 0, 7, 6, 30, }, + { 2, 0, 0, 7, 6, 26, }, + { 1, 0, 0, 7, 6, 26, }, + { 0, 0, 0, 7, 7, 30, }, + { 2, 0, 0, 7, 7, 26, }, + { 1, 0, 0, 7, 7, 26, }, + { 0, 0, 0, 7, 8, 30, }, + { 2, 0, 0, 7, 8, 26, }, + { 1, 0, 0, 7, 8, 26, }, + { 0, 0, 0, 7, 9, 30, }, + { 2, 0, 0, 7, 9, 26, }, + { 1, 0, 0, 7, 9, 26, }, + { 0, 0, 0, 7, 10, 30, }, + { 2, 0, 0, 7, 10, 26, }, + { 1, 0, 0, 7, 10, 26, }, + { 0, 0, 0, 7, 11, 26, }, + { 2, 0, 0, 7, 11, 26, }, + { 1, 0, 0, 7, 11, 26, }, + { 0, 0, 0, 7, 12, 63, }, + { 2, 0, 0, 7, 12, 26, }, + { 1, 0, 0, 7, 12, 26, }, + { 0, 0, 0, 7, 13, 63, }, + { 2, 0, 0, 7, 13, 26, }, + { 1, 0, 0, 7, 13, 26, }, + { 0, 0, 0, 7, 14, 63, }, + { 2, 0, 0, 7, 14, 63, }, + { 1, 0, 0, 7, 14, 63, }, + { 0, 0, 1, 2, 1, 63, }, + { 2, 0, 1, 2, 1, 63, }, + { 1, 0, 1, 2, 1, 63, }, + { 0, 0, 1, 2, 2, 63, }, + { 2, 0, 1, 2, 2, 63, }, + { 1, 0, 1, 2, 2, 63, }, + { 0, 0, 1, 2, 3, 32, }, + { 2, 0, 1, 2, 3, 32, }, + { 1, 0, 1, 2, 3, 32, }, + { 0, 0, 1, 2, 4, 36, }, + { 2, 0, 1, 2, 4, 32, }, + { 1, 0, 1, 2, 4, 32, }, + { 0, 0, 1, 2, 5, 36, }, + { 2, 0, 1, 2, 5, 32, }, + { 1, 0, 1, 2, 5, 32, }, + { 0, 0, 1, 2, 6, 36, }, + { 2, 0, 1, 2, 6, 32, }, + { 1, 0, 1, 2, 6, 32, }, + { 0, 0, 1, 2, 7, 36, }, + { 2, 0, 1, 2, 7, 32, }, + { 1, 0, 1, 2, 7, 32, }, + { 0, 0, 1, 2, 8, 36, }, + { 2, 0, 1, 2, 8, 32, }, + { 1, 0, 1, 2, 8, 32, }, + { 0, 0, 1, 2, 9, 36, }, + { 2, 0, 1, 2, 9, 32, }, + { 1, 0, 1, 2, 9, 32, }, + { 0, 0, 1, 2, 10, 36, }, + { 2, 0, 1, 2, 10, 32, }, + { 1, 0, 1, 2, 10, 32, }, + { 0, 0, 1, 2, 11, 32, }, + { 2, 0, 1, 2, 11, 32, }, + { 1, 0, 1, 2, 11, 32, }, + { 0, 0, 1, 2, 12, 63, }, + { 2, 0, 1, 2, 12, 32, }, + { 1, 0, 1, 2, 12, 32, }, + { 0, 0, 1, 2, 13, 63, }, + { 2, 0, 1, 2, 13, 32, }, + { 1, 0, 1, 2, 13, 32, }, + { 0, 0, 1, 2, 14, 63, }, + { 2, 0, 1, 2, 14, 63, }, + { 1, 0, 1, 2, 14, 63, }, + { 0, 0, 1, 3, 1, 63, }, + { 2, 0, 1, 3, 1, 63, }, + { 1, 0, 1, 3, 1, 63, }, + { 0, 0, 1, 3, 2, 63, }, + { 2, 0, 1, 3, 2, 63, }, + { 1, 0, 1, 3, 2, 63, }, + { 0, 0, 1, 3, 3, 30, }, + { 2, 0, 1, 3, 3, 30, }, + { 1, 0, 1, 3, 3, 30, }, + { 0, 0, 1, 3, 4, 34, }, + { 2, 0, 1, 3, 4, 30, }, + { 1, 0, 1, 3, 4, 30, }, + { 0, 0, 1, 3, 5, 34, }, + { 2, 0, 1, 3, 5, 30, }, + { 1, 0, 1, 3, 5, 30, }, + { 0, 0, 1, 3, 6, 34, }, + { 2, 0, 1, 3, 6, 30, }, + { 1, 0, 1, 3, 6, 30, }, + { 0, 0, 1, 3, 7, 34, }, + { 2, 0, 1, 3, 7, 30, }, + { 1, 0, 1, 3, 7, 30, }, + { 0, 0, 1, 3, 8, 34, }, + { 2, 0, 1, 3, 8, 30, }, + { 1, 0, 1, 3, 8, 30, }, + { 0, 0, 1, 3, 9, 34, }, + { 2, 0, 1, 3, 9, 30, }, + { 1, 0, 1, 3, 9, 30, }, + { 0, 0, 1, 3, 10, 34, }, + { 2, 0, 1, 3, 10, 30, }, + { 1, 0, 1, 3, 10, 30, }, + { 0, 0, 1, 3, 11, 30, }, + { 2, 0, 1, 3, 11, 30, }, + { 1, 0, 1, 3, 11, 30, }, + { 0, 0, 1, 3, 12, 63, }, + { 2, 0, 1, 3, 12, 30, }, + { 1, 0, 1, 3, 12, 30, }, + { 0, 0, 1, 3, 13, 63, }, + { 2, 0, 1, 3, 13, 30, }, + { 1, 0, 1, 3, 13, 30, }, + { 0, 0, 1, 3, 14, 63, }, + { 2, 0, 1, 3, 14, 63, }, + { 1, 0, 1, 3, 14, 63, }, + { 0, 0, 1, 6, 1, 63, }, + { 2, 0, 1, 6, 1, 63, }, + { 1, 0, 1, 6, 1, 63, }, + { 0, 0, 1, 6, 2, 63, }, + { 2, 0, 1, 6, 2, 63, }, + { 1, 0, 1, 6, 2, 63, }, + { 0, 0, 1, 6, 3, 28, }, + { 2, 0, 1, 6, 3, 28, }, + { 1, 0, 1, 6, 3, 28, }, + { 0, 0, 1, 6, 4, 32, }, + { 2, 0, 1, 6, 4, 28, }, + { 1, 0, 1, 6, 4, 28, }, + { 0, 0, 1, 6, 5, 32, }, + { 2, 0, 1, 6, 5, 28, }, + { 1, 0, 1, 6, 5, 28, }, + { 0, 0, 1, 6, 6, 32, }, + { 2, 0, 1, 6, 6, 28, }, + { 1, 0, 1, 6, 6, 28, }, + { 0, 0, 1, 6, 7, 32, }, + { 2, 0, 1, 6, 7, 28, }, + { 1, 0, 1, 6, 7, 28, }, + { 0, 0, 1, 6, 8, 32, }, + { 2, 0, 1, 6, 8, 28, }, + { 1, 0, 1, 6, 8, 28, }, + { 0, 0, 1, 6, 9, 32, }, + { 2, 0, 1, 6, 9, 28, }, + { 1, 0, 1, 6, 9, 28, }, + { 0, 0, 1, 6, 10, 32, }, + { 2, 0, 1, 6, 10, 28, }, + { 1, 0, 1, 6, 10, 28, }, + { 0, 0, 1, 6, 11, 28, }, + { 2, 0, 1, 6, 11, 28, }, + { 1, 0, 1, 6, 11, 28, }, + { 0, 0, 1, 6, 12, 63, }, + { 2, 0, 1, 6, 12, 28, }, + { 1, 0, 1, 6, 12, 28, }, + { 0, 0, 1, 6, 13, 63, }, + { 2, 0, 1, 6, 13, 28, }, + { 1, 0, 1, 6, 13, 28, }, + { 0, 0, 1, 6, 14, 63, }, + { 2, 0, 1, 6, 14, 63, }, + { 1, 0, 1, 6, 14, 63, }, + { 0, 0, 1, 7, 1, 63, }, + { 2, 0, 1, 7, 1, 63, }, + { 1, 0, 1, 7, 1, 63, }, + { 0, 0, 1, 7, 2, 63, }, + { 2, 0, 1, 7, 2, 63, }, + { 1, 0, 1, 7, 2, 63, }, + { 0, 0, 1, 7, 3, 26, }, + { 2, 0, 1, 7, 3, 26, }, + { 1, 0, 1, 7, 3, 26, }, + { 0, 0, 1, 7, 4, 30, }, + { 2, 0, 1, 7, 4, 26, }, + { 1, 0, 1, 7, 4, 26, }, + { 0, 0, 1, 7, 5, 30, }, + { 2, 0, 1, 7, 5, 26, }, + { 1, 0, 1, 7, 5, 26, }, + { 0, 0, 1, 7, 6, 30, }, + { 2, 0, 1, 7, 6, 26, }, + { 1, 0, 1, 7, 6, 26, }, + { 0, 0, 1, 7, 7, 30, }, + { 2, 0, 1, 7, 7, 26, }, + { 1, 0, 1, 7, 7, 26, }, + { 0, 0, 1, 7, 8, 30, }, + { 2, 0, 1, 7, 8, 26, }, + { 1, 0, 1, 7, 8, 26, }, + { 0, 0, 1, 7, 9, 30, }, + { 2, 0, 1, 7, 9, 26, }, + { 1, 0, 1, 7, 9, 26, }, + { 0, 0, 1, 7, 10, 30, }, + { 2, 0, 1, 7, 10, 26, }, + { 1, 0, 1, 7, 10, 26, }, + { 0, 0, 1, 7, 11, 26, }, + { 2, 0, 1, 7, 11, 26, }, + { 1, 0, 1, 7, 11, 26, }, + { 0, 0, 1, 7, 12, 63, }, + { 2, 0, 1, 7, 12, 26, }, + { 1, 0, 1, 7, 12, 26, }, + { 0, 0, 1, 7, 13, 63, }, + { 2, 0, 1, 7, 13, 26, }, + { 1, 0, 1, 7, 13, 26, }, + { 0, 0, 1, 7, 14, 63, }, + { 2, 0, 1, 7, 14, 63, }, + { 1, 0, 1, 7, 14, 63, }, + { 0, 1, 0, 1, 36, 30, }, + { 2, 1, 0, 1, 36, 32, }, + { 1, 1, 0, 1, 36, 32, }, + { 0, 1, 0, 1, 40, 30, }, + { 2, 1, 0, 1, 40, 32, }, + { 1, 1, 0, 1, 40, 32, }, + { 0, 1, 0, 1, 44, 30, }, + { 2, 1, 0, 1, 44, 32, }, + { 1, 1, 0, 1, 44, 32, }, + { 0, 1, 0, 1, 48, 30, }, + { 2, 1, 0, 1, 48, 32, }, + { 1, 1, 0, 1, 48, 32, }, + { 0, 1, 0, 1, 52, 36, }, + { 2, 1, 0, 1, 52, 32, }, + { 1, 1, 0, 1, 52, 32, }, + { 0, 1, 0, 1, 56, 34, }, + { 2, 1, 0, 1, 56, 32, }, + { 1, 1, 0, 1, 56, 32, }, + { 0, 1, 0, 1, 60, 32, }, + { 2, 1, 0, 1, 60, 32, }, + { 1, 1, 0, 1, 60, 32, }, + { 0, 1, 0, 1, 64, 28, }, + { 2, 1, 0, 1, 64, 32, }, + { 1, 1, 0, 1, 64, 32, }, + { 0, 1, 0, 1, 100, 30, }, + { 2, 1, 0, 1, 100, 32, }, + { 1, 1, 0, 1, 100, 32, }, + { 0, 1, 0, 1, 104, 30, }, + { 2, 1, 0, 1, 104, 32, }, + { 1, 1, 0, 1, 104, 32, }, + { 0, 1, 0, 1, 108, 32, }, + { 2, 1, 0, 1, 108, 32, }, + { 1, 1, 0, 1, 108, 32, }, + { 0, 1, 0, 1, 112, 34, }, + { 2, 1, 0, 1, 112, 32, }, + { 1, 1, 0, 1, 112, 32, }, + { 0, 1, 0, 1, 116, 34, }, + { 2, 1, 0, 1, 116, 32, }, + { 1, 1, 0, 1, 116, 32, }, + { 0, 1, 0, 1, 120, 36, }, + { 2, 1, 0, 1, 120, 32, }, + { 1, 1, 0, 1, 120, 32, }, + { 0, 1, 0, 1, 124, 34, }, + { 2, 1, 0, 1, 124, 32, }, + { 1, 1, 0, 1, 124, 32, }, + { 0, 1, 0, 1, 128, 32, }, + { 2, 1, 0, 1, 128, 32, }, + { 1, 1, 0, 1, 128, 32, }, + { 0, 1, 0, 1, 132, 30, }, + { 2, 1, 0, 1, 132, 32, }, + { 1, 1, 0, 1, 132, 32, }, + { 0, 1, 0, 1, 136, 30, }, + { 2, 1, 0, 1, 136, 32, }, + { 1, 1, 0, 1, 136, 32, }, + { 0, 1, 0, 1, 140, 28, }, + { 2, 1, 0, 1, 140, 32, }, + { 1, 1, 0, 1, 140, 32, }, + { 0, 1, 0, 1, 149, 36, }, + { 2, 1, 0, 1, 149, 32, }, + { 1, 1, 0, 1, 149, 63, }, + { 0, 1, 0, 1, 153, 36, }, + { 2, 1, 0, 1, 153, 32, }, + { 1, 1, 0, 1, 153, 63, }, + { 0, 1, 0, 1, 157, 36, }, + { 2, 1, 0, 1, 157, 32, }, + { 1, 1, 0, 1, 157, 63, }, + { 0, 1, 0, 1, 161, 36, }, + { 2, 1, 0, 1, 161, 32, }, + { 1, 1, 0, 1, 161, 63, }, + { 0, 1, 0, 1, 165, 36, }, + { 2, 1, 0, 1, 165, 32, }, + { 1, 1, 0, 1, 165, 63, }, + { 0, 1, 0, 2, 36, 30, }, + { 2, 1, 0, 2, 36, 32, }, + { 1, 1, 0, 2, 36, 32, }, + { 0, 1, 0, 2, 40, 30, }, + { 2, 1, 0, 2, 40, 32, }, + { 1, 1, 0, 2, 40, 32, }, + { 0, 1, 0, 2, 44, 30, }, + { 2, 1, 0, 2, 44, 32, }, + { 1, 1, 0, 2, 44, 32, }, + { 0, 1, 0, 2, 48, 30, }, + { 2, 1, 0, 2, 48, 32, }, + { 1, 1, 0, 2, 48, 32, }, + { 0, 1, 0, 2, 52, 36, }, + { 2, 1, 0, 2, 52, 32, }, + { 1, 1, 0, 2, 52, 32, }, + { 0, 1, 0, 2, 56, 34, }, + { 2, 1, 0, 2, 56, 32, }, + { 1, 1, 0, 2, 56, 32, }, + { 0, 1, 0, 2, 60, 32, }, + { 2, 1, 0, 2, 60, 32, }, + { 1, 1, 0, 2, 60, 32, }, + { 0, 1, 0, 2, 64, 28, }, + { 2, 1, 0, 2, 64, 32, }, + { 1, 1, 0, 2, 64, 32, }, + { 0, 1, 0, 2, 100, 30, }, + { 2, 1, 0, 2, 100, 32, }, + { 1, 1, 0, 2, 100, 32, }, + { 0, 1, 0, 2, 104, 30, }, + { 2, 1, 0, 2, 104, 32, }, + { 1, 1, 0, 2, 104, 32, }, + { 0, 1, 0, 2, 108, 32, }, + { 2, 1, 0, 2, 108, 32, }, + { 1, 1, 0, 2, 108, 32, }, + { 0, 1, 0, 2, 112, 34, }, + { 2, 1, 0, 2, 112, 32, }, + { 1, 1, 0, 2, 112, 32, }, + { 0, 1, 0, 2, 116, 34, }, + { 2, 1, 0, 2, 116, 32, }, + { 1, 1, 0, 2, 116, 32, }, + { 0, 1, 0, 2, 120, 36, }, + { 2, 1, 0, 2, 120, 32, }, + { 1, 1, 0, 2, 120, 32, }, + { 0, 1, 0, 2, 124, 34, }, + { 2, 1, 0, 2, 124, 32, }, + { 1, 1, 0, 2, 124, 32, }, + { 0, 1, 0, 2, 128, 32, }, + { 2, 1, 0, 2, 128, 32, }, + { 1, 1, 0, 2, 128, 32, }, + { 0, 1, 0, 2, 132, 30, }, + { 2, 1, 0, 2, 132, 32, }, + { 1, 1, 0, 2, 132, 32, }, + { 0, 1, 0, 2, 136, 30, }, + { 2, 1, 0, 2, 136, 32, }, + { 1, 1, 0, 2, 136, 32, }, + { 0, 1, 0, 2, 140, 28, }, + { 2, 1, 0, 2, 140, 32, }, + { 1, 1, 0, 2, 140, 32, }, + { 0, 1, 0, 2, 149, 36, }, + { 2, 1, 0, 2, 149, 32, }, + { 1, 1, 0, 2, 149, 63, }, + { 0, 1, 0, 2, 153, 36, }, + { 2, 1, 0, 2, 153, 32, }, + { 1, 1, 0, 2, 153, 63, }, + { 0, 1, 0, 2, 157, 36, }, + { 2, 1, 0, 2, 157, 32, }, + { 1, 1, 0, 2, 157, 63, }, + { 0, 1, 0, 2, 161, 36, }, + { 2, 1, 0, 2, 161, 32, }, + { 1, 1, 0, 2, 161, 63, }, + { 0, 1, 0, 2, 165, 36, }, + { 2, 1, 0, 2, 165, 32, }, + { 1, 1, 0, 2, 165, 63, }, + { 0, 1, 0, 3, 36, 28, }, + { 2, 1, 0, 3, 36, 30, }, + { 1, 1, 0, 3, 36, 30, }, + { 0, 1, 0, 3, 40, 28, }, + { 2, 1, 0, 3, 40, 30, }, + { 1, 1, 0, 3, 40, 30, }, + { 0, 1, 0, 3, 44, 28, }, + { 2, 1, 0, 3, 44, 30, }, + { 1, 1, 0, 3, 44, 30, }, + { 0, 1, 0, 3, 48, 28, }, + { 2, 1, 0, 3, 48, 30, }, + { 1, 1, 0, 3, 48, 30, }, + { 0, 1, 0, 3, 52, 34, }, + { 2, 1, 0, 3, 52, 30, }, + { 1, 1, 0, 3, 52, 30, }, + { 0, 1, 0, 3, 56, 32, }, + { 2, 1, 0, 3, 56, 30, }, + { 1, 1, 0, 3, 56, 30, }, + { 0, 1, 0, 3, 60, 30, }, + { 2, 1, 0, 3, 60, 30, }, + { 1, 1, 0, 3, 60, 30, }, + { 0, 1, 0, 3, 64, 26, }, + { 2, 1, 0, 3, 64, 30, }, + { 1, 1, 0, 3, 64, 30, }, + { 0, 1, 0, 3, 100, 28, }, + { 2, 1, 0, 3, 100, 30, }, + { 1, 1, 0, 3, 100, 30, }, + { 0, 1, 0, 3, 104, 28, }, + { 2, 1, 0, 3, 104, 30, }, + { 1, 1, 0, 3, 104, 30, }, + { 0, 1, 0, 3, 108, 30, }, + { 2, 1, 0, 3, 108, 30, }, + { 1, 1, 0, 3, 108, 30, }, + { 0, 1, 0, 3, 112, 32, }, + { 2, 1, 0, 3, 112, 30, }, + { 1, 1, 0, 3, 112, 30, }, + { 0, 1, 0, 3, 116, 32, }, + { 2, 1, 0, 3, 116, 30, }, + { 1, 1, 0, 3, 116, 30, }, + { 0, 1, 0, 3, 120, 34, }, + { 2, 1, 0, 3, 120, 30, }, + { 1, 1, 0, 3, 120, 30, }, + { 0, 1, 0, 3, 124, 32, }, + { 2, 1, 0, 3, 124, 30, }, + { 1, 1, 0, 3, 124, 30, }, + { 0, 1, 0, 3, 128, 30, }, + { 2, 1, 0, 3, 128, 30, }, + { 1, 1, 0, 3, 128, 30, }, + { 0, 1, 0, 3, 132, 28, }, + { 2, 1, 0, 3, 132, 30, }, + { 1, 1, 0, 3, 132, 30, }, + { 0, 1, 0, 3, 136, 28, }, + { 2, 1, 0, 3, 136, 30, }, + { 1, 1, 0, 3, 136, 30, }, + { 0, 1, 0, 3, 140, 26, }, + { 2, 1, 0, 3, 140, 30, }, + { 1, 1, 0, 3, 140, 30, }, + { 0, 1, 0, 3, 149, 34, }, + { 2, 1, 0, 3, 149, 30, }, + { 1, 1, 0, 3, 149, 63, }, + { 0, 1, 0, 3, 153, 34, }, + { 2, 1, 0, 3, 153, 30, }, + { 1, 1, 0, 3, 153, 63, }, + { 0, 1, 0, 3, 157, 34, }, + { 2, 1, 0, 3, 157, 30, }, + { 1, 1, 0, 3, 157, 63, }, + { 0, 1, 0, 3, 161, 34, }, + { 2, 1, 0, 3, 161, 30, }, + { 1, 1, 0, 3, 161, 63, }, + { 0, 1, 0, 3, 165, 34, }, + { 2, 1, 0, 3, 165, 30, }, + { 1, 1, 0, 3, 165, 63, }, + { 0, 1, 0, 6, 36, 26, }, + { 2, 1, 0, 6, 36, 28, }, + { 1, 1, 0, 6, 36, 28, }, + { 0, 1, 0, 6, 40, 26, }, + { 2, 1, 0, 6, 40, 28, }, + { 1, 1, 0, 6, 40, 28, }, + { 0, 1, 0, 6, 44, 26, }, + { 2, 1, 0, 6, 44, 28, }, + { 1, 1, 0, 6, 44, 28, }, + { 0, 1, 0, 6, 48, 26, }, + { 2, 1, 0, 6, 48, 28, }, + { 1, 1, 0, 6, 48, 28, }, + { 0, 1, 0, 6, 52, 32, }, + { 2, 1, 0, 6, 52, 28, }, + { 1, 1, 0, 6, 52, 28, }, + { 0, 1, 0, 6, 56, 30, }, + { 2, 1, 0, 6, 56, 28, }, + { 1, 1, 0, 6, 56, 28, }, + { 0, 1, 0, 6, 60, 28, }, + { 2, 1, 0, 6, 60, 28, }, + { 1, 1, 0, 6, 60, 28, }, + { 0, 1, 0, 6, 64, 24, }, + { 2, 1, 0, 6, 64, 28, }, + { 1, 1, 0, 6, 64, 28, }, + { 0, 1, 0, 6, 100, 26, }, + { 2, 1, 0, 6, 100, 28, }, + { 1, 1, 0, 6, 100, 28, }, + { 0, 1, 0, 6, 104, 26, }, + { 2, 1, 0, 6, 104, 28, }, + { 1, 1, 0, 6, 104, 28, }, + { 0, 1, 0, 6, 108, 28, }, + { 2, 1, 0, 6, 108, 28, }, + { 1, 1, 0, 6, 108, 28, }, + { 0, 1, 0, 6, 112, 30, }, + { 2, 1, 0, 6, 112, 28, }, + { 1, 1, 0, 6, 112, 28, }, + { 0, 1, 0, 6, 116, 30, }, + { 2, 1, 0, 6, 116, 28, }, + { 1, 1, 0, 6, 116, 28, }, + { 0, 1, 0, 6, 120, 32, }, + { 2, 1, 0, 6, 120, 28, }, + { 1, 1, 0, 6, 120, 28, }, + { 0, 1, 0, 6, 124, 30, }, + { 2, 1, 0, 6, 124, 28, }, + { 1, 1, 0, 6, 124, 28, }, + { 0, 1, 0, 6, 128, 28, }, + { 2, 1, 0, 6, 128, 28, }, + { 1, 1, 0, 6, 128, 28, }, + { 0, 1, 0, 6, 132, 26, }, + { 2, 1, 0, 6, 132, 28, }, + { 1, 1, 0, 6, 132, 28, }, + { 0, 1, 0, 6, 136, 26, }, + { 2, 1, 0, 6, 136, 28, }, + { 1, 1, 0, 6, 136, 28, }, + { 0, 1, 0, 6, 140, 24, }, + { 2, 1, 0, 6, 140, 28, }, + { 1, 1, 0, 6, 140, 28, }, + { 0, 1, 0, 6, 149, 32, }, + { 2, 1, 0, 6, 149, 28, }, + { 1, 1, 0, 6, 149, 63, }, + { 0, 1, 0, 6, 153, 32, }, + { 2, 1, 0, 6, 153, 28, }, + { 1, 1, 0, 6, 153, 63, }, + { 0, 1, 0, 6, 157, 32, }, + { 2, 1, 0, 6, 157, 28, }, + { 1, 1, 0, 6, 157, 63, }, + { 0, 1, 0, 6, 161, 32, }, + { 2, 1, 0, 6, 161, 28, }, + { 1, 1, 0, 6, 161, 63, }, + { 0, 1, 0, 6, 165, 32, }, + { 2, 1, 0, 6, 165, 28, }, + { 1, 1, 0, 6, 165, 63, }, + { 0, 1, 0, 7, 36, 24, }, + { 2, 1, 0, 7, 36, 26, }, + { 1, 1, 0, 7, 36, 26, }, + { 0, 1, 0, 7, 40, 24, }, + { 2, 1, 0, 7, 40, 26, }, + { 1, 1, 0, 7, 40, 26, }, + { 0, 1, 0, 7, 44, 24, }, + { 2, 1, 0, 7, 44, 26, }, + { 1, 1, 0, 7, 44, 26, }, + { 0, 1, 0, 7, 48, 24, }, + { 2, 1, 0, 7, 48, 26, }, + { 1, 1, 0, 7, 48, 26, }, + { 0, 1, 0, 7, 52, 30, }, + { 2, 1, 0, 7, 52, 26, }, + { 1, 1, 0, 7, 52, 26, }, + { 0, 1, 0, 7, 56, 28, }, + { 2, 1, 0, 7, 56, 26, }, + { 1, 1, 0, 7, 56, 26, }, + { 0, 1, 0, 7, 60, 26, }, + { 2, 1, 0, 7, 60, 26, }, + { 1, 1, 0, 7, 60, 26, }, + { 0, 1, 0, 7, 64, 22, }, + { 2, 1, 0, 7, 64, 26, }, + { 1, 1, 0, 7, 64, 26, }, + { 0, 1, 0, 7, 100, 24, }, + { 2, 1, 0, 7, 100, 26, }, + { 1, 1, 0, 7, 100, 26, }, + { 0, 1, 0, 7, 104, 24, }, + { 2, 1, 0, 7, 104, 26, }, + { 1, 1, 0, 7, 104, 26, }, + { 0, 1, 0, 7, 108, 26, }, + { 2, 1, 0, 7, 108, 26, }, + { 1, 1, 0, 7, 108, 26, }, + { 0, 1, 0, 7, 112, 28, }, + { 2, 1, 0, 7, 112, 26, }, + { 1, 1, 0, 7, 112, 26, }, + { 0, 1, 0, 7, 116, 28, }, + { 2, 1, 0, 7, 116, 26, }, + { 1, 1, 0, 7, 116, 26, }, + { 0, 1, 0, 7, 120, 30, }, + { 2, 1, 0, 7, 120, 26, }, + { 1, 1, 0, 7, 120, 26, }, + { 0, 1, 0, 7, 124, 28, }, + { 2, 1, 0, 7, 124, 26, }, + { 1, 1, 0, 7, 124, 26, }, + { 0, 1, 0, 7, 128, 26, }, + { 2, 1, 0, 7, 128, 26, }, + { 1, 1, 0, 7, 128, 26, }, + { 0, 1, 0, 7, 132, 24, }, + { 2, 1, 0, 7, 132, 26, }, + { 1, 1, 0, 7, 132, 26, }, + { 0, 1, 0, 7, 136, 24, }, + { 2, 1, 0, 7, 136, 26, }, + { 1, 1, 0, 7, 136, 26, }, + { 0, 1, 0, 7, 140, 22, }, + { 2, 1, 0, 7, 140, 26, }, + { 1, 1, 0, 7, 140, 26, }, + { 0, 1, 0, 7, 149, 30, }, + { 2, 1, 0, 7, 149, 26, }, + { 1, 1, 0, 7, 149, 63, }, + { 0, 1, 0, 7, 153, 30, }, + { 2, 1, 0, 7, 153, 26, }, + { 1, 1, 0, 7, 153, 63, }, + { 0, 1, 0, 7, 157, 30, }, + { 2, 1, 0, 7, 157, 26, }, + { 1, 1, 0, 7, 157, 63, }, + { 0, 1, 0, 7, 161, 30, }, + { 2, 1, 0, 7, 161, 26, }, + { 1, 1, 0, 7, 161, 63, }, + { 0, 1, 0, 7, 165, 30, }, + { 2, 1, 0, 7, 165, 26, }, + { 1, 1, 0, 7, 165, 63, }, + { 0, 1, 1, 2, 38, 30, }, + { 2, 1, 1, 2, 38, 32, }, + { 1, 1, 1, 2, 38, 32, }, + { 0, 1, 1, 2, 46, 30, }, + { 2, 1, 1, 2, 46, 32, }, + { 1, 1, 1, 2, 46, 32, }, + { 0, 1, 1, 2, 54, 32, }, + { 2, 1, 1, 2, 54, 32, }, + { 1, 1, 1, 2, 54, 32, }, + { 0, 1, 1, 2, 62, 32, }, + { 2, 1, 1, 2, 62, 32, }, + { 1, 1, 1, 2, 62, 32, }, + { 0, 1, 1, 2, 102, 28, }, + { 2, 1, 1, 2, 102, 32, }, + { 1, 1, 1, 2, 102, 32, }, + { 0, 1, 1, 2, 110, 32, }, + { 2, 1, 1, 2, 110, 32, }, + { 1, 1, 1, 2, 110, 32, }, + { 0, 1, 1, 2, 118, 36, }, + { 2, 1, 1, 2, 118, 32, }, + { 1, 1, 1, 2, 118, 32, }, + { 0, 1, 1, 2, 126, 34, }, + { 2, 1, 1, 2, 126, 32, }, + { 1, 1, 1, 2, 126, 32, }, + { 0, 1, 1, 2, 134, 32, }, + { 2, 1, 1, 2, 134, 32, }, + { 1, 1, 1, 2, 134, 32, }, + { 0, 1, 1, 2, 151, 36, }, + { 2, 1, 1, 2, 151, 32, }, + { 1, 1, 1, 2, 151, 63, }, + { 0, 1, 1, 2, 159, 36, }, + { 2, 1, 1, 2, 159, 32, }, + { 1, 1, 1, 2, 159, 63, }, + { 0, 1, 1, 3, 38, 28, }, + { 2, 1, 1, 3, 38, 30, }, + { 1, 1, 1, 3, 38, 30, }, + { 0, 1, 1, 3, 46, 28, }, + { 2, 1, 1, 3, 46, 30, }, + { 1, 1, 1, 3, 46, 30, }, + { 0, 1, 1, 3, 54, 30, }, + { 2, 1, 1, 3, 54, 30, }, + { 1, 1, 1, 3, 54, 30, }, + { 0, 1, 1, 3, 62, 30, }, + { 2, 1, 1, 3, 62, 30, }, + { 1, 1, 1, 3, 62, 30, }, + { 0, 1, 1, 3, 102, 26, }, + { 2, 1, 1, 3, 102, 30, }, + { 1, 1, 1, 3, 102, 30, }, + { 0, 1, 1, 3, 110, 30, }, + { 2, 1, 1, 3, 110, 30, }, + { 1, 1, 1, 3, 110, 30, }, + { 0, 1, 1, 3, 118, 34, }, + { 2, 1, 1, 3, 118, 30, }, + { 1, 1, 1, 3, 118, 30, }, + { 0, 1, 1, 3, 126, 32, }, + { 2, 1, 1, 3, 126, 30, }, + { 1, 1, 1, 3, 126, 30, }, + { 0, 1, 1, 3, 134, 30, }, + { 2, 1, 1, 3, 134, 30, }, + { 1, 1, 1, 3, 134, 30, }, + { 0, 1, 1, 3, 151, 34, }, + { 2, 1, 1, 3, 151, 30, }, + { 1, 1, 1, 3, 151, 63, }, + { 0, 1, 1, 3, 159, 34, }, + { 2, 1, 1, 3, 159, 30, }, + { 1, 1, 1, 3, 159, 63, }, + { 0, 1, 1, 6, 38, 26, }, + { 2, 1, 1, 6, 38, 28, }, + { 1, 1, 1, 6, 38, 28, }, + { 0, 1, 1, 6, 46, 26, }, + { 2, 1, 1, 6, 46, 28, }, + { 1, 1, 1, 6, 46, 28, }, + { 0, 1, 1, 6, 54, 28, }, + { 2, 1, 1, 6, 54, 28, }, + { 1, 1, 1, 6, 54, 28, }, + { 0, 1, 1, 6, 62, 28, }, + { 2, 1, 1, 6, 62, 28, }, + { 1, 1, 1, 6, 62, 28, }, + { 0, 1, 1, 6, 102, 24, }, + { 2, 1, 1, 6, 102, 28, }, + { 1, 1, 1, 6, 102, 28, }, + { 0, 1, 1, 6, 110, 28, }, + { 2, 1, 1, 6, 110, 28, }, + { 1, 1, 1, 6, 110, 28, }, + { 0, 1, 1, 6, 118, 32, }, + { 2, 1, 1, 6, 118, 28, }, + { 1, 1, 1, 6, 118, 28, }, + { 0, 1, 1, 6, 126, 30, }, + { 2, 1, 1, 6, 126, 28, }, + { 1, 1, 1, 6, 126, 28, }, + { 0, 1, 1, 6, 134, 28, }, + { 2, 1, 1, 6, 134, 28, }, + { 1, 1, 1, 6, 134, 28, }, + { 0, 1, 1, 6, 151, 32, }, + { 2, 1, 1, 6, 151, 28, }, + { 1, 1, 1, 6, 151, 63, }, + { 0, 1, 1, 6, 159, 32, }, + { 2, 1, 1, 6, 159, 28, }, + { 1, 1, 1, 6, 159, 63, }, + { 0, 1, 1, 7, 38, 24, }, + { 2, 1, 1, 7, 38, 26, }, + { 1, 1, 1, 7, 38, 26, }, + { 0, 1, 1, 7, 46, 24, }, + { 2, 1, 1, 7, 46, 26, }, + { 1, 1, 1, 7, 46, 26, }, + { 0, 1, 1, 7, 54, 26, }, + { 2, 1, 1, 7, 54, 26, }, + { 1, 1, 1, 7, 54, 26, }, + { 0, 1, 1, 7, 62, 26, }, + { 2, 1, 1, 7, 62, 26, }, + { 1, 1, 1, 7, 62, 26, }, + { 0, 1, 1, 7, 102, 22, }, + { 2, 1, 1, 7, 102, 26, }, + { 1, 1, 1, 7, 102, 26, }, + { 0, 1, 1, 7, 110, 26, }, + { 2, 1, 1, 7, 110, 26, }, + { 1, 1, 1, 7, 110, 26, }, + { 0, 1, 1, 7, 118, 30, }, + { 2, 1, 1, 7, 118, 26, }, + { 1, 1, 1, 7, 118, 26, }, + { 0, 1, 1, 7, 126, 28, }, + { 2, 1, 1, 7, 126, 26, }, + { 1, 1, 1, 7, 126, 26, }, + { 0, 1, 1, 7, 134, 26, }, + { 2, 1, 1, 7, 134, 26, }, + { 1, 1, 1, 7, 134, 26, }, + { 0, 1, 1, 7, 151, 30, }, + { 2, 1, 1, 7, 151, 26, }, + { 1, 1, 1, 7, 151, 63, }, + { 0, 1, 1, 7, 159, 30, }, + { 2, 1, 1, 7, 159, 26, }, + { 1, 1, 1, 7, 159, 63, }, + { 0, 1, 2, 4, 42, 30, }, + { 2, 1, 2, 4, 42, 32, }, + { 1, 1, 2, 4, 42, 32, }, + { 0, 1, 2, 4, 58, 28, }, + { 2, 1, 2, 4, 58, 32, }, + { 1, 1, 2, 4, 58, 32, }, + { 0, 1, 2, 4, 106, 30, }, + { 2, 1, 2, 4, 106, 32, }, + { 1, 1, 2, 4, 106, 32, }, + { 0, 1, 2, 4, 122, 34, }, + { 2, 1, 2, 4, 122, 32, }, + { 1, 1, 2, 4, 122, 32, }, + { 0, 1, 2, 4, 155, 36, }, + { 2, 1, 2, 4, 155, 32, }, + { 1, 1, 2, 4, 155, 63, }, + { 0, 1, 2, 5, 42, 28, }, + { 2, 1, 2, 5, 42, 30, }, + { 1, 1, 2, 5, 42, 30, }, + { 0, 1, 2, 5, 58, 26, }, + { 2, 1, 2, 5, 58, 30, }, + { 1, 1, 2, 5, 58, 30, }, + { 0, 1, 2, 5, 106, 28, }, + { 2, 1, 2, 5, 106, 30, }, + { 1, 1, 2, 5, 106, 30, }, + { 0, 1, 2, 5, 122, 32, }, + { 2, 1, 2, 5, 122, 30, }, + { 1, 1, 2, 5, 122, 30, }, + { 0, 1, 2, 5, 155, 34, }, + { 2, 1, 2, 5, 155, 30, }, + { 1, 1, 2, 5, 155, 63, }, + { 0, 1, 2, 8, 42, 26, }, + { 2, 1, 2, 8, 42, 28, }, + { 1, 1, 2, 8, 42, 28, }, + { 0, 1, 2, 8, 58, 24, }, + { 2, 1, 2, 8, 58, 28, }, + { 1, 1, 2, 8, 58, 28, }, + { 0, 1, 2, 8, 106, 26, }, + { 2, 1, 2, 8, 106, 28, }, + { 1, 1, 2, 8, 106, 28, }, + { 0, 1, 2, 8, 122, 30, }, + { 2, 1, 2, 8, 122, 28, }, + { 1, 1, 2, 8, 122, 28, }, + { 0, 1, 2, 8, 155, 32, }, + { 2, 1, 2, 8, 155, 28, }, + { 1, 1, 2, 8, 155, 63, }, + { 0, 1, 2, 9, 42, 24, }, + { 2, 1, 2, 9, 42, 26, }, + { 1, 1, 2, 9, 42, 26, }, + { 0, 1, 2, 9, 58, 22, }, + { 2, 1, 2, 9, 58, 26, }, + { 1, 1, 2, 9, 58, 26, }, + { 0, 1, 2, 9, 106, 24, }, + { 2, 1, 2, 9, 106, 26, }, + { 1, 1, 2, 9, 106, 26, }, + { 0, 1, 2, 9, 122, 28, }, + { 2, 1, 2, 9, 122, 26, }, + { 1, 1, 2, 9, 122, 26, }, + { 0, 1, 2, 9, 155, 30, }, + { 2, 1, 2, 9, 155, 26, }, + { 1, 1, 2, 9, 155, 63, }, +}; + +RTW_DECL_TABLE_TXPWR_LMT(rtw8814a_txpwr_lmt); + +static const struct rtw_txpwr_lmt_cfg_pair rtw8814a_txpwr_lmt_type0[] = { + { 0, 0, 0, 0, 1, 32, }, + { 2, 0, 0, 0, 1, 32, }, + { 1, 0, 0, 0, 1, 32, }, + { 0, 0, 0, 0, 2, 32, }, + { 2, 0, 0, 0, 2, 32, }, + { 1, 0, 0, 0, 2, 32, }, + { 0, 0, 0, 0, 3, 32, }, + { 2, 0, 0, 0, 3, 32, }, + { 1, 0, 0, 0, 3, 32, }, + { 0, 0, 0, 0, 4, 32, }, + { 2, 0, 0, 0, 4, 32, }, + { 1, 0, 0, 0, 4, 32, }, + { 0, 0, 0, 0, 5, 32, }, + { 2, 0, 0, 0, 5, 32, }, + { 1, 0, 0, 0, 5, 32, }, + { 0, 0, 0, 0, 6, 32, }, + { 2, 0, 0, 0, 6, 32, }, + { 1, 0, 0, 0, 6, 32, }, + { 0, 0, 0, 0, 7, 32, }, + { 2, 0, 0, 0, 7, 32, }, + { 1, 0, 0, 0, 7, 32, }, + { 0, 0, 0, 0, 8, 32, }, + { 2, 0, 0, 0, 8, 32, }, + { 1, 0, 0, 0, 8, 32, }, + { 0, 0, 0, 0, 9, 32, }, + { 2, 0, 0, 0, 9, 32, }, + { 1, 0, 0, 0, 9, 32, }, + { 0, 0, 0, 0, 10, 32, }, + { 2, 0, 0, 0, 10, 32, }, + { 1, 0, 0, 0, 10, 32, }, + { 0, 0, 0, 0, 11, 32, }, + { 2, 0, 0, 0, 11, 32, }, + { 1, 0, 0, 0, 11, 32, }, + { 0, 0, 0, 0, 12, 24, }, + { 2, 0, 0, 0, 12, 32, }, + { 1, 0, 0, 0, 12, 32, }, + { 0, 0, 0, 0, 13, 16, }, + { 2, 0, 0, 0, 13, 32, }, + { 1, 0, 0, 0, 13, 32, }, + { 0, 0, 0, 0, 14, 63, }, + { 2, 0, 0, 0, 14, 63, }, + { 1, 0, 0, 0, 14, 32, }, + { 0, 0, 0, 1, 1, 28, }, + { 2, 0, 0, 1, 1, 32, }, + { 1, 0, 0, 1, 1, 32, }, + { 0, 0, 0, 1, 2, 32, }, + { 2, 0, 0, 1, 2, 32, }, + { 1, 0, 0, 1, 2, 32, }, + { 0, 0, 0, 1, 3, 32, }, + { 2, 0, 0, 1, 3, 32, }, + { 1, 0, 0, 1, 3, 32, }, + { 0, 0, 0, 1, 4, 32, }, + { 2, 0, 0, 1, 4, 32, }, + { 1, 0, 0, 1, 4, 32, }, + { 0, 0, 0, 1, 5, 32, }, + { 2, 0, 0, 1, 5, 32, }, + { 1, 0, 0, 1, 5, 32, }, + { 0, 0, 0, 1, 6, 32, }, + { 2, 0, 0, 1, 6, 32, }, + { 1, 0, 0, 1, 6, 32, }, + { 0, 0, 0, 1, 7, 32, }, + { 2, 0, 0, 1, 7, 32, }, + { 1, 0, 0, 1, 7, 32, }, + { 0, 0, 0, 1, 8, 32, }, + { 2, 0, 0, 1, 8, 32, }, + { 1, 0, 0, 1, 8, 32, }, + { 0, 0, 0, 1, 9, 32, }, + { 2, 0, 0, 1, 9, 32, }, + { 1, 0, 0, 1, 9, 32, }, + { 0, 0, 0, 1, 10, 32, }, + { 2, 0, 0, 1, 10, 32, }, + { 1, 0, 0, 1, 10, 32, }, + { 0, 0, 0, 1, 11, 28, }, + { 2, 0, 0, 1, 11, 32, }, + { 1, 0, 0, 1, 11, 32, }, + { 0, 0, 0, 1, 12, 18, }, + { 2, 0, 0, 1, 12, 32, }, + { 1, 0, 0, 1, 12, 32, }, + { 0, 0, 0, 1, 13, 8, }, + { 2, 0, 0, 1, 13, 32, }, + { 1, 0, 0, 1, 13, 32, }, + { 0, 0, 0, 1, 14, 63, }, + { 2, 0, 0, 1, 14, 63, }, + { 1, 0, 0, 1, 14, 63, }, + { 0, 0, 0, 2, 1, 26, }, + { 2, 0, 0, 2, 1, 32, }, + { 1, 0, 0, 2, 1, 32, }, + { 0, 0, 0, 2, 2, 32, }, + { 2, 0, 0, 2, 2, 32, }, + { 1, 0, 0, 2, 2, 32, }, + { 0, 0, 0, 2, 3, 32, }, + { 2, 0, 0, 2, 3, 32, }, + { 1, 0, 0, 2, 3, 32, }, + { 0, 0, 0, 2, 4, 32, }, + { 2, 0, 0, 2, 4, 32, }, + { 1, 0, 0, 2, 4, 32, }, + { 0, 0, 0, 2, 5, 32, }, + { 2, 0, 0, 2, 5, 32, }, + { 1, 0, 0, 2, 5, 32, }, + { 0, 0, 0, 2, 6, 32, }, + { 2, 0, 0, 2, 6, 32, }, + { 1, 0, 0, 2, 6, 32, }, + { 0, 0, 0, 2, 7, 32, }, + { 2, 0, 0, 2, 7, 32, }, + { 1, 0, 0, 2, 7, 32, }, + { 0, 0, 0, 2, 8, 32, }, + { 2, 0, 0, 2, 8, 32, }, + { 1, 0, 0, 2, 8, 32, }, + { 0, 0, 0, 2, 9, 32, }, + { 2, 0, 0, 2, 9, 32, }, + { 1, 0, 0, 2, 9, 32, }, + { 0, 0, 0, 2, 10, 32, }, + { 2, 0, 0, 2, 10, 32, }, + { 1, 0, 0, 2, 10, 32, }, + { 0, 0, 0, 2, 11, 26, }, + { 2, 0, 0, 2, 11, 32, }, + { 1, 0, 0, 2, 11, 32, }, + { 0, 0, 0, 2, 12, 16, }, + { 2, 0, 0, 2, 12, 32, }, + { 1, 0, 0, 2, 12, 32, }, + { 0, 0, 0, 2, 13, 6, }, + { 2, 0, 0, 2, 13, 32, }, + { 1, 0, 0, 2, 13, 32, }, + { 0, 0, 0, 2, 14, 63, }, + { 2, 0, 0, 2, 14, 63, }, + { 1, 0, 0, 2, 14, 63, }, + { 0, 0, 0, 3, 1, 24, }, + { 2, 0, 0, 3, 1, 30, }, + { 1, 0, 0, 3, 1, 30, }, + { 0, 0, 0, 3, 2, 30, }, + { 2, 0, 0, 3, 2, 30, }, + { 1, 0, 0, 3, 2, 30, }, + { 0, 0, 0, 3, 3, 30, }, + { 2, 0, 0, 3, 3, 30, }, + { 1, 0, 0, 3, 3, 30, }, + { 0, 0, 0, 3, 4, 30, }, + { 2, 0, 0, 3, 4, 30, }, + { 1, 0, 0, 3, 4, 30, }, + { 0, 0, 0, 3, 5, 30, }, + { 2, 0, 0, 3, 5, 30, }, + { 1, 0, 0, 3, 5, 30, }, + { 0, 0, 0, 3, 6, 30, }, + { 2, 0, 0, 3, 6, 30, }, + { 1, 0, 0, 3, 6, 30, }, + { 0, 0, 0, 3, 7, 30, }, + { 2, 0, 0, 3, 7, 30, }, + { 1, 0, 0, 3, 7, 30, }, + { 0, 0, 0, 3, 8, 30, }, + { 2, 0, 0, 3, 8, 30, }, + { 1, 0, 0, 3, 8, 30, }, + { 0, 0, 0, 3, 9, 30, }, + { 2, 0, 0, 3, 9, 30, }, + { 1, 0, 0, 3, 9, 30, }, + { 0, 0, 0, 3, 10, 30, }, + { 2, 0, 0, 3, 10, 30, }, + { 1, 0, 0, 3, 10, 30, }, + { 0, 0, 0, 3, 11, 24, }, + { 2, 0, 0, 3, 11, 30, }, + { 1, 0, 0, 3, 11, 30, }, + { 0, 0, 0, 3, 12, 14, }, + { 2, 0, 0, 3, 12, 30, }, + { 1, 0, 0, 3, 12, 30, }, + { 0, 0, 0, 3, 13, 4, }, + { 2, 0, 0, 3, 13, 30, }, + { 1, 0, 0, 3, 13, 30, }, + { 0, 0, 0, 3, 14, 63, }, + { 2, 0, 0, 3, 14, 63, }, + { 1, 0, 0, 3, 14, 63, }, + { 0, 0, 0, 6, 1, 22, }, + { 2, 0, 0, 6, 1, 28, }, + { 1, 0, 0, 6, 1, 28, }, + { 0, 0, 0, 6, 2, 28, }, + { 2, 0, 0, 6, 2, 28, }, + { 1, 0, 0, 6, 2, 28, }, + { 0, 0, 0, 6, 3, 28, }, + { 2, 0, 0, 6, 3, 28, }, + { 1, 0, 0, 6, 3, 28, }, + { 0, 0, 0, 6, 4, 28, }, + { 2, 0, 0, 6, 4, 28, }, + { 1, 0, 0, 6, 4, 28, }, + { 0, 0, 0, 6, 5, 28, }, + { 2, 0, 0, 6, 5, 28, }, + { 1, 0, 0, 6, 5, 28, }, + { 0, 0, 0, 6, 6, 28, }, + { 2, 0, 0, 6, 6, 28, }, + { 1, 0, 0, 6, 6, 28, }, + { 0, 0, 0, 6, 7, 28, }, + { 2, 0, 0, 6, 7, 28, }, + { 1, 0, 0, 6, 7, 28, }, + { 0, 0, 0, 6, 8, 28, }, + { 2, 0, 0, 6, 8, 28, }, + { 1, 0, 0, 6, 8, 28, }, + { 0, 0, 0, 6, 9, 28, }, + { 2, 0, 0, 6, 9, 28, }, + { 1, 0, 0, 6, 9, 28, }, + { 0, 0, 0, 6, 10, 28, }, + { 2, 0, 0, 6, 10, 28, }, + { 1, 0, 0, 6, 10, 28, }, + { 0, 0, 0, 6, 11, 22, }, + { 2, 0, 0, 6, 11, 28, }, + { 1, 0, 0, 6, 11, 28, }, + { 0, 0, 0, 6, 12, 14, }, + { 2, 0, 0, 6, 12, 28, }, + { 1, 0, 0, 6, 12, 28, }, + { 0, 0, 0, 6, 13, 4, }, + { 2, 0, 0, 6, 13, 28, }, + { 1, 0, 0, 6, 13, 28, }, + { 0, 0, 0, 6, 14, 63, }, + { 2, 0, 0, 6, 14, 63, }, + { 1, 0, 0, 6, 14, 63, }, + { 0, 0, 0, 7, 1, 20, }, + { 2, 0, 0, 7, 1, 26, }, + { 1, 0, 0, 7, 1, 26, }, + { 0, 0, 0, 7, 2, 26, }, + { 2, 0, 0, 7, 2, 26, }, + { 1, 0, 0, 7, 2, 26, }, + { 0, 0, 0, 7, 3, 26, }, + { 2, 0, 0, 7, 3, 26, }, + { 1, 0, 0, 7, 3, 26, }, + { 0, 0, 0, 7, 4, 26, }, + { 2, 0, 0, 7, 4, 26, }, + { 1, 0, 0, 7, 4, 26, }, + { 0, 0, 0, 7, 5, 26, }, + { 2, 0, 0, 7, 5, 26, }, + { 1, 0, 0, 7, 5, 26, }, + { 0, 0, 0, 7, 6, 26, }, + { 2, 0, 0, 7, 6, 26, }, + { 1, 0, 0, 7, 6, 26, }, + { 0, 0, 0, 7, 7, 26, }, + { 2, 0, 0, 7, 7, 26, }, + { 1, 0, 0, 7, 7, 26, }, + { 0, 0, 0, 7, 8, 26, }, + { 2, 0, 0, 7, 8, 26, }, + { 1, 0, 0, 7, 8, 26, }, + { 0, 0, 0, 7, 9, 26, }, + { 2, 0, 0, 7, 9, 26, }, + { 1, 0, 0, 7, 9, 26, }, + { 0, 0, 0, 7, 10, 26, }, + { 2, 0, 0, 7, 10, 26, }, + { 1, 0, 0, 7, 10, 26, }, + { 0, 0, 0, 7, 11, 20, }, + { 2, 0, 0, 7, 11, 26, }, + { 1, 0, 0, 7, 11, 26, }, + { 0, 0, 0, 7, 12, 14, }, + { 2, 0, 0, 7, 12, 26, }, + { 1, 0, 0, 7, 12, 26, }, + { 0, 0, 0, 7, 13, 4, }, + { 2, 0, 0, 7, 13, 26, }, + { 1, 0, 0, 7, 13, 26, }, + { 0, 0, 0, 7, 14, 63, }, + { 2, 0, 0, 7, 14, 63, }, + { 1, 0, 0, 7, 14, 63, }, + { 0, 0, 1, 2, 1, 63, }, + { 2, 0, 1, 2, 1, 63, }, + { 1, 0, 1, 2, 1, 63, }, + { 0, 0, 1, 2, 2, 63, }, + { 2, 0, 1, 2, 2, 63, }, + { 1, 0, 1, 2, 2, 63, }, + { 0, 0, 1, 2, 3, 26, }, + { 2, 0, 1, 2, 3, 32, }, + { 1, 0, 1, 2, 3, 32, }, + { 0, 0, 1, 2, 4, 32, }, + { 2, 0, 1, 2, 4, 32, }, + { 1, 0, 1, 2, 4, 32, }, + { 0, 0, 1, 2, 5, 32, }, + { 2, 0, 1, 2, 5, 32, }, + { 1, 0, 1, 2, 5, 32, }, + { 0, 0, 1, 2, 6, 32, }, + { 2, 0, 1, 2, 6, 32, }, + { 1, 0, 1, 2, 6, 32, }, + { 0, 0, 1, 2, 7, 32, }, + { 2, 0, 1, 2, 7, 32, }, + { 1, 0, 1, 2, 7, 32, }, + { 0, 0, 1, 2, 8, 32, }, + { 2, 0, 1, 2, 8, 32, }, + { 1, 0, 1, 2, 8, 32, }, + { 0, 0, 1, 2, 9, 32, }, + { 2, 0, 1, 2, 9, 32, }, + { 1, 0, 1, 2, 9, 32, }, + { 0, 0, 1, 2, 10, 32, }, + { 2, 0, 1, 2, 10, 32, }, + { 1, 0, 1, 2, 10, 32, }, + { 0, 0, 1, 2, 11, 26, }, + { 2, 0, 1, 2, 11, 32, }, + { 1, 0, 1, 2, 11, 32, }, + { 0, 0, 1, 2, 12, 16, }, + { 2, 0, 1, 2, 12, 32, }, + { 1, 0, 1, 2, 12, 32, }, + { 0, 0, 1, 2, 13, 10, }, + { 2, 0, 1, 2, 13, 32, }, + { 1, 0, 1, 2, 13, 32, }, + { 0, 0, 1, 2, 14, 63, }, + { 2, 0, 1, 2, 14, 63, }, + { 1, 0, 1, 2, 14, 63, }, + { 0, 0, 1, 3, 1, 63, }, + { 2, 0, 1, 3, 1, 63, }, + { 1, 0, 1, 3, 1, 63, }, + { 0, 0, 1, 3, 2, 63, }, + { 2, 0, 1, 3, 2, 63, }, + { 1, 0, 1, 3, 2, 63, }, + { 0, 0, 1, 3, 3, 24, }, + { 2, 0, 1, 3, 3, 30, }, + { 1, 0, 1, 3, 3, 30, }, + { 0, 0, 1, 3, 4, 30, }, + { 2, 0, 1, 3, 4, 30, }, + { 1, 0, 1, 3, 4, 30, }, + { 0, 0, 1, 3, 5, 30, }, + { 2, 0, 1, 3, 5, 30, }, + { 1, 0, 1, 3, 5, 30, }, + { 0, 0, 1, 3, 6, 30, }, + { 2, 0, 1, 3, 6, 30, }, + { 1, 0, 1, 3, 6, 30, }, + { 0, 0, 1, 3, 7, 30, }, + { 2, 0, 1, 3, 7, 30, }, + { 1, 0, 1, 3, 7, 30, }, + { 0, 0, 1, 3, 8, 30, }, + { 2, 0, 1, 3, 8, 30, }, + { 1, 0, 1, 3, 8, 30, }, + { 0, 0, 1, 3, 9, 30, }, + { 2, 0, 1, 3, 9, 30, }, + { 1, 0, 1, 3, 9, 30, }, + { 0, 0, 1, 3, 10, 30, }, + { 2, 0, 1, 3, 10, 30, }, + { 1, 0, 1, 3, 10, 30, }, + { 0, 0, 1, 3, 11, 24, }, + { 2, 0, 1, 3, 11, 30, }, + { 1, 0, 1, 3, 11, 30, }, + { 0, 0, 1, 3, 12, 14, }, + { 2, 0, 1, 3, 12, 30, }, + { 1, 0, 1, 3, 12, 30, }, + { 0, 0, 1, 3, 13, 8, }, + { 2, 0, 1, 3, 13, 30, }, + { 1, 0, 1, 3, 13, 30, }, + { 0, 0, 1, 3, 14, 63, }, + { 2, 0, 1, 3, 14, 63, }, + { 1, 0, 1, 3, 14, 63, }, + { 0, 0, 1, 6, 1, 63, }, + { 2, 0, 1, 6, 1, 63, }, + { 1, 0, 1, 6, 1, 63, }, + { 0, 0, 1, 6, 2, 63, }, + { 2, 0, 1, 6, 2, 63, }, + { 1, 0, 1, 6, 2, 63, }, + { 0, 0, 1, 6, 3, 22, }, + { 2, 0, 1, 6, 3, 28, }, + { 1, 0, 1, 6, 3, 28, }, + { 0, 0, 1, 6, 4, 28, }, + { 2, 0, 1, 6, 4, 28, }, + { 1, 0, 1, 6, 4, 28, }, + { 0, 0, 1, 6, 5, 28, }, + { 2, 0, 1, 6, 5, 28, }, + { 1, 0, 1, 6, 5, 28, }, + { 0, 0, 1, 6, 6, 28, }, + { 2, 0, 1, 6, 6, 28, }, + { 1, 0, 1, 6, 6, 28, }, + { 0, 0, 1, 6, 7, 28, }, + { 2, 0, 1, 6, 7, 28, }, + { 1, 0, 1, 6, 7, 28, }, + { 0, 0, 1, 6, 8, 28, }, + { 2, 0, 1, 6, 8, 28, }, + { 1, 0, 1, 6, 8, 28, }, + { 0, 0, 1, 6, 9, 28, }, + { 2, 0, 1, 6, 9, 28, }, + { 1, 0, 1, 6, 9, 28, }, + { 0, 0, 1, 6, 10, 28, }, + { 2, 0, 1, 6, 10, 28, }, + { 1, 0, 1, 6, 10, 28, }, + { 0, 0, 1, 6, 11, 22, }, + { 2, 0, 1, 6, 11, 28, }, + { 1, 0, 1, 6, 11, 28, }, + { 0, 0, 1, 6, 12, 14, }, + { 2, 0, 1, 6, 12, 28, }, + { 1, 0, 1, 6, 12, 28, }, + { 0, 0, 1, 6, 13, 8, }, + { 2, 0, 1, 6, 13, 28, }, + { 1, 0, 1, 6, 13, 28, }, + { 0, 0, 1, 6, 14, 63, }, + { 2, 0, 1, 6, 14, 63, }, + { 1, 0, 1, 6, 14, 63, }, + { 0, 0, 1, 7, 1, 63, }, + { 2, 0, 1, 7, 1, 63, }, + { 1, 0, 1, 7, 1, 63, }, + { 0, 0, 1, 7, 2, 63, }, + { 2, 0, 1, 7, 2, 63, }, + { 1, 0, 1, 7, 2, 63, }, + { 0, 0, 1, 7, 3, 20, }, + { 2, 0, 1, 7, 3, 26, }, + { 1, 0, 1, 7, 3, 26, }, + { 0, 0, 1, 7, 4, 26, }, + { 2, 0, 1, 7, 4, 26, }, + { 1, 0, 1, 7, 4, 26, }, + { 0, 0, 1, 7, 5, 26, }, + { 2, 0, 1, 7, 5, 26, }, + { 1, 0, 1, 7, 5, 26, }, + { 0, 0, 1, 7, 6, 26, }, + { 2, 0, 1, 7, 6, 26, }, + { 1, 0, 1, 7, 6, 26, }, + { 0, 0, 1, 7, 7, 26, }, + { 2, 0, 1, 7, 7, 26, }, + { 1, 0, 1, 7, 7, 26, }, + { 0, 0, 1, 7, 8, 26, }, + { 2, 0, 1, 7, 8, 26, }, + { 1, 0, 1, 7, 8, 26, }, + { 0, 0, 1, 7, 9, 26, }, + { 2, 0, 1, 7, 9, 26, }, + { 1, 0, 1, 7, 9, 26, }, + { 0, 0, 1, 7, 10, 26, }, + { 2, 0, 1, 7, 10, 26, }, + { 1, 0, 1, 7, 10, 26, }, + { 0, 0, 1, 7, 11, 20, }, + { 2, 0, 1, 7, 11, 26, }, + { 1, 0, 1, 7, 11, 26, }, + { 0, 0, 1, 7, 12, 14, }, + { 2, 0, 1, 7, 12, 26, }, + { 1, 0, 1, 7, 12, 26, }, + { 0, 0, 1, 7, 13, 8, }, + { 2, 0, 1, 7, 13, 26, }, + { 1, 0, 1, 7, 13, 26, }, + { 0, 0, 1, 7, 14, 63, }, + { 2, 0, 1, 7, 14, 63, }, + { 1, 0, 1, 7, 14, 63, }, + { 0, 1, 0, 1, 36, 28, }, + { 2, 1, 0, 1, 36, 32, }, + { 1, 1, 0, 1, 36, 32, }, + { 0, 1, 0, 1, 40, 32, }, + { 2, 1, 0, 1, 40, 32, }, + { 1, 1, 0, 1, 40, 32, }, + { 0, 1, 0, 1, 44, 32, }, + { 2, 1, 0, 1, 44, 32, }, + { 1, 1, 0, 1, 44, 32, }, + { 0, 1, 0, 1, 48, 32, }, + { 2, 1, 0, 1, 48, 32, }, + { 1, 1, 0, 1, 48, 32, }, + { 0, 1, 0, 1, 52, 32, }, + { 2, 1, 0, 1, 52, 32, }, + { 1, 1, 0, 1, 52, 32, }, + { 0, 1, 0, 1, 56, 32, }, + { 2, 1, 0, 1, 56, 32, }, + { 1, 1, 0, 1, 56, 32, }, + { 0, 1, 0, 1, 60, 32, }, + { 2, 1, 0, 1, 60, 32, }, + { 1, 1, 0, 1, 60, 32, }, + { 0, 1, 0, 1, 64, 28, }, + { 2, 1, 0, 1, 64, 32, }, + { 1, 1, 0, 1, 64, 32, }, + { 0, 1, 0, 1, 100, 28, }, + { 2, 1, 0, 1, 100, 32, }, + { 1, 1, 0, 1, 100, 32, }, + { 0, 1, 0, 1, 104, 32, }, + { 2, 1, 0, 1, 104, 32, }, + { 1, 1, 0, 1, 104, 32, }, + { 0, 1, 0, 1, 108, 32, }, + { 2, 1, 0, 1, 108, 32, }, + { 1, 1, 0, 1, 108, 32, }, + { 0, 1, 0, 1, 112, 32, }, + { 2, 1, 0, 1, 112, 32, }, + { 1, 1, 0, 1, 112, 32, }, + { 0, 1, 0, 1, 116, 32, }, + { 2, 1, 0, 1, 116, 32, }, + { 1, 1, 0, 1, 116, 32, }, + { 0, 1, 0, 1, 120, 32, }, + { 2, 1, 0, 1, 120, 32, }, + { 1, 1, 0, 1, 120, 32, }, + { 0, 1, 0, 1, 124, 32, }, + { 2, 1, 0, 1, 124, 32, }, + { 1, 1, 0, 1, 124, 32, }, + { 0, 1, 0, 1, 128, 32, }, + { 2, 1, 0, 1, 128, 32, }, + { 1, 1, 0, 1, 128, 32, }, + { 0, 1, 0, 1, 132, 32, }, + { 2, 1, 0, 1, 132, 32, }, + { 1, 1, 0, 1, 132, 32, }, + { 0, 1, 0, 1, 136, 32, }, + { 2, 1, 0, 1, 136, 32, }, + { 1, 1, 0, 1, 136, 32, }, + { 0, 1, 0, 1, 140, 28, }, + { 2, 1, 0, 1, 140, 32, }, + { 1, 1, 0, 1, 140, 32, }, + { 0, 1, 0, 1, 149, 28, }, + { 2, 1, 0, 1, 149, 32, }, + { 1, 1, 0, 1, 149, 63, }, + { 0, 1, 0, 1, 153, 32, }, + { 2, 1, 0, 1, 153, 32, }, + { 1, 1, 0, 1, 153, 63, }, + { 0, 1, 0, 1, 157, 32, }, + { 2, 1, 0, 1, 157, 32, }, + { 1, 1, 0, 1, 157, 63, }, + { 0, 1, 0, 1, 161, 32, }, + { 2, 1, 0, 1, 161, 32, }, + { 1, 1, 0, 1, 161, 63, }, + { 0, 1, 0, 1, 165, 32, }, + { 2, 1, 0, 1, 165, 32, }, + { 1, 1, 0, 1, 165, 63, }, + { 0, 1, 0, 2, 36, 26, }, + { 2, 1, 0, 2, 36, 32, }, + { 1, 1, 0, 2, 36, 32, }, + { 0, 1, 0, 2, 40, 32, }, + { 2, 1, 0, 2, 40, 32, }, + { 1, 1, 0, 2, 40, 32, }, + { 0, 1, 0, 2, 44, 32, }, + { 2, 1, 0, 2, 44, 32, }, + { 1, 1, 0, 2, 44, 32, }, + { 0, 1, 0, 2, 48, 32, }, + { 2, 1, 0, 2, 48, 32, }, + { 1, 1, 0, 2, 48, 32, }, + { 0, 1, 0, 2, 52, 32, }, + { 2, 1, 0, 2, 52, 32, }, + { 1, 1, 0, 2, 52, 32, }, + { 0, 1, 0, 2, 56, 32, }, + { 2, 1, 0, 2, 56, 32, }, + { 1, 1, 0, 2, 56, 32, }, + { 0, 1, 0, 2, 60, 32, }, + { 2, 1, 0, 2, 60, 32, }, + { 1, 1, 0, 2, 60, 32, }, + { 0, 1, 0, 2, 64, 26, }, + { 2, 1, 0, 2, 64, 32, }, + { 1, 1, 0, 2, 64, 32, }, + { 0, 1, 0, 2, 100, 26, }, + { 2, 1, 0, 2, 100, 32, }, + { 1, 1, 0, 2, 100, 32, }, + { 0, 1, 0, 2, 104, 32, }, + { 2, 1, 0, 2, 104, 32, }, + { 1, 1, 0, 2, 104, 32, }, + { 0, 1, 0, 2, 108, 32, }, + { 2, 1, 0, 2, 108, 32, }, + { 1, 1, 0, 2, 108, 32, }, + { 0, 1, 0, 2, 112, 32, }, + { 2, 1, 0, 2, 112, 32, }, + { 1, 1, 0, 2, 112, 32, }, + { 0, 1, 0, 2, 116, 32, }, + { 2, 1, 0, 2, 116, 32, }, + { 1, 1, 0, 2, 116, 32, }, + { 0, 1, 0, 2, 120, 32, }, + { 2, 1, 0, 2, 120, 32, }, + { 1, 1, 0, 2, 120, 32, }, + { 0, 1, 0, 2, 124, 32, }, + { 2, 1, 0, 2, 124, 32, }, + { 1, 1, 0, 2, 124, 32, }, + { 0, 1, 0, 2, 128, 32, }, + { 2, 1, 0, 2, 128, 32, }, + { 1, 1, 0, 2, 128, 32, }, + { 0, 1, 0, 2, 132, 32, }, + { 2, 1, 0, 2, 132, 32, }, + { 1, 1, 0, 2, 132, 32, }, + { 0, 1, 0, 2, 136, 32, }, + { 2, 1, 0, 2, 136, 32, }, + { 1, 1, 0, 2, 136, 32, }, + { 0, 1, 0, 2, 140, 26, }, + { 2, 1, 0, 2, 140, 32, }, + { 1, 1, 0, 2, 140, 32, }, + { 0, 1, 0, 2, 149, 26, }, + { 2, 1, 0, 2, 149, 32, }, + { 1, 1, 0, 2, 149, 63, }, + { 0, 1, 0, 2, 153, 32, }, + { 2, 1, 0, 2, 153, 32, }, + { 1, 1, 0, 2, 153, 63, }, + { 0, 1, 0, 2, 157, 32, }, + { 2, 1, 0, 2, 157, 32, }, + { 1, 1, 0, 2, 157, 63, }, + { 0, 1, 0, 2, 161, 32, }, + { 2, 1, 0, 2, 161, 32, }, + { 1, 1, 0, 2, 161, 63, }, + { 0, 1, 0, 2, 165, 32, }, + { 2, 1, 0, 2, 165, 32, }, + { 1, 1, 0, 2, 165, 63, }, + { 0, 1, 0, 3, 36, 24, }, + { 2, 1, 0, 3, 36, 28, }, + { 1, 1, 0, 3, 36, 28, }, + { 0, 1, 0, 3, 40, 28, }, + { 2, 1, 0, 3, 40, 28, }, + { 1, 1, 0, 3, 40, 28, }, + { 0, 1, 0, 3, 44, 28, }, + { 2, 1, 0, 3, 44, 28, }, + { 1, 1, 0, 3, 44, 28, }, + { 0, 1, 0, 3, 48, 28, }, + { 2, 1, 0, 3, 48, 28, }, + { 1, 1, 0, 3, 48, 28, }, + { 0, 1, 0, 3, 52, 28, }, + { 2, 1, 0, 3, 52, 28, }, + { 1, 1, 0, 3, 52, 28, }, + { 0, 1, 0, 3, 56, 28, }, + { 2, 1, 0, 3, 56, 28, }, + { 1, 1, 0, 3, 56, 28, }, + { 0, 1, 0, 3, 60, 28, }, + { 2, 1, 0, 3, 60, 28, }, + { 1, 1, 0, 3, 60, 28, }, + { 0, 1, 0, 3, 64, 24, }, + { 2, 1, 0, 3, 64, 28, }, + { 1, 1, 0, 3, 64, 28, }, + { 0, 1, 0, 3, 100, 24, }, + { 2, 1, 0, 3, 100, 28, }, + { 1, 1, 0, 3, 100, 28, }, + { 0, 1, 0, 3, 104, 28, }, + { 2, 1, 0, 3, 104, 28, }, + { 1, 1, 0, 3, 104, 28, }, + { 0, 1, 0, 3, 108, 28, }, + { 2, 1, 0, 3, 108, 28, }, + { 1, 1, 0, 3, 108, 28, }, + { 0, 1, 0, 3, 112, 28, }, + { 2, 1, 0, 3, 112, 28, }, + { 1, 1, 0, 3, 112, 28, }, + { 0, 1, 0, 3, 116, 28, }, + { 2, 1, 0, 3, 116, 28, }, + { 1, 1, 0, 3, 116, 28, }, + { 0, 1, 0, 3, 120, 28, }, + { 2, 1, 0, 3, 120, 28, }, + { 1, 1, 0, 3, 120, 28, }, + { 0, 1, 0, 3, 124, 28, }, + { 2, 1, 0, 3, 124, 28, }, + { 1, 1, 0, 3, 124, 28, }, + { 0, 1, 0, 3, 128, 28, }, + { 2, 1, 0, 3, 128, 28, }, + { 1, 1, 0, 3, 128, 28, }, + { 0, 1, 0, 3, 132, 28, }, + { 2, 1, 0, 3, 132, 28, }, + { 1, 1, 0, 3, 132, 28, }, + { 0, 1, 0, 3, 136, 28, }, + { 2, 1, 0, 3, 136, 28, }, + { 1, 1, 0, 3, 136, 28, }, + { 0, 1, 0, 3, 140, 24, }, + { 2, 1, 0, 3, 140, 28, }, + { 1, 1, 0, 3, 140, 28, }, + { 0, 1, 0, 3, 149, 24, }, + { 2, 1, 0, 3, 149, 28, }, + { 1, 1, 0, 3, 149, 63, }, + { 0, 1, 0, 3, 153, 28, }, + { 2, 1, 0, 3, 153, 28, }, + { 1, 1, 0, 3, 153, 63, }, + { 0, 1, 0, 3, 157, 28, }, + { 2, 1, 0, 3, 157, 28, }, + { 1, 1, 0, 3, 157, 63, }, + { 0, 1, 0, 3, 161, 28, }, + { 2, 1, 0, 3, 161, 28, }, + { 1, 1, 0, 3, 161, 63, }, + { 0, 1, 0, 3, 165, 28, }, + { 2, 1, 0, 3, 165, 28, }, + { 1, 1, 0, 3, 165, 63, }, + { 0, 1, 0, 6, 36, 22, }, + { 2, 1, 0, 6, 36, 26, }, + { 1, 1, 0, 6, 36, 26, }, + { 0, 1, 0, 6, 40, 26, }, + { 2, 1, 0, 6, 40, 26, }, + { 1, 1, 0, 6, 40, 26, }, + { 0, 1, 0, 6, 44, 26, }, + { 2, 1, 0, 6, 44, 26, }, + { 1, 1, 0, 6, 44, 26, }, + { 0, 1, 0, 6, 48, 26, }, + { 2, 1, 0, 6, 48, 26, }, + { 1, 1, 0, 6, 48, 26, }, + { 0, 1, 0, 6, 52, 26, }, + { 2, 1, 0, 6, 52, 26, }, + { 1, 1, 0, 6, 52, 26, }, + { 0, 1, 0, 6, 56, 26, }, + { 2, 1, 0, 6, 56, 26, }, + { 1, 1, 0, 6, 56, 26, }, + { 0, 1, 0, 6, 60, 26, }, + { 2, 1, 0, 6, 60, 26, }, + { 1, 1, 0, 6, 60, 26, }, + { 0, 1, 0, 6, 64, 22, }, + { 2, 1, 0, 6, 64, 26, }, + { 1, 1, 0, 6, 64, 26, }, + { 0, 1, 0, 6, 100, 22, }, + { 2, 1, 0, 6, 100, 26, }, + { 1, 1, 0, 6, 100, 26, }, + { 0, 1, 0, 6, 104, 26, }, + { 2, 1, 0, 6, 104, 26, }, + { 1, 1, 0, 6, 104, 26, }, + { 0, 1, 0, 6, 108, 26, }, + { 2, 1, 0, 6, 108, 26, }, + { 1, 1, 0, 6, 108, 26, }, + { 0, 1, 0, 6, 112, 26, }, + { 2, 1, 0, 6, 112, 26, }, + { 1, 1, 0, 6, 112, 26, }, + { 0, 1, 0, 6, 116, 26, }, + { 2, 1, 0, 6, 116, 26, }, + { 1, 1, 0, 6, 116, 26, }, + { 0, 1, 0, 6, 120, 26, }, + { 2, 1, 0, 6, 120, 26, }, + { 1, 1, 0, 6, 120, 26, }, + { 0, 1, 0, 6, 124, 26, }, + { 2, 1, 0, 6, 124, 26, }, + { 1, 1, 0, 6, 124, 26, }, + { 0, 1, 0, 6, 128, 26, }, + { 2, 1, 0, 6, 128, 26, }, + { 1, 1, 0, 6, 128, 26, }, + { 0, 1, 0, 6, 132, 26, }, + { 2, 1, 0, 6, 132, 26, }, + { 1, 1, 0, 6, 132, 26, }, + { 0, 1, 0, 6, 136, 26, }, + { 2, 1, 0, 6, 136, 26, }, + { 1, 1, 0, 6, 136, 26, }, + { 0, 1, 0, 6, 140, 22, }, + { 2, 1, 0, 6, 140, 26, }, + { 1, 1, 0, 6, 140, 26, }, + { 0, 1, 0, 6, 149, 22, }, + { 2, 1, 0, 6, 149, 26, }, + { 1, 1, 0, 6, 149, 63, }, + { 0, 1, 0, 6, 153, 26, }, + { 2, 1, 0, 6, 153, 26, }, + { 1, 1, 0, 6, 153, 63, }, + { 0, 1, 0, 6, 157, 26, }, + { 2, 1, 0, 6, 157, 26, }, + { 1, 1, 0, 6, 157, 63, }, + { 0, 1, 0, 6, 161, 26, }, + { 2, 1, 0, 6, 161, 26, }, + { 1, 1, 0, 6, 161, 63, }, + { 0, 1, 0, 6, 165, 26, }, + { 2, 1, 0, 6, 165, 26, }, + { 1, 1, 0, 6, 165, 63, }, + { 0, 1, 0, 7, 36, 20, }, + { 2, 1, 0, 7, 36, 24, }, + { 1, 1, 0, 7, 36, 24, }, + { 0, 1, 0, 7, 40, 24, }, + { 2, 1, 0, 7, 40, 24, }, + { 1, 1, 0, 7, 40, 24, }, + { 0, 1, 0, 7, 44, 24, }, + { 2, 1, 0, 7, 44, 24, }, + { 1, 1, 0, 7, 44, 24, }, + { 0, 1, 0, 7, 48, 24, }, + { 2, 1, 0, 7, 48, 24, }, + { 1, 1, 0, 7, 48, 24, }, + { 0, 1, 0, 7, 52, 24, }, + { 2, 1, 0, 7, 52, 24, }, + { 1, 1, 0, 7, 52, 24, }, + { 0, 1, 0, 7, 56, 24, }, + { 2, 1, 0, 7, 56, 24, }, + { 1, 1, 0, 7, 56, 24, }, + { 0, 1, 0, 7, 60, 24, }, + { 2, 1, 0, 7, 60, 24, }, + { 1, 1, 0, 7, 60, 24, }, + { 0, 1, 0, 7, 64, 20, }, + { 2, 1, 0, 7, 64, 24, }, + { 1, 1, 0, 7, 64, 24, }, + { 0, 1, 0, 7, 100, 20, }, + { 2, 1, 0, 7, 100, 24, }, + { 1, 1, 0, 7, 100, 24, }, + { 0, 1, 0, 7, 104, 24, }, + { 2, 1, 0, 7, 104, 24, }, + { 1, 1, 0, 7, 104, 24, }, + { 0, 1, 0, 7, 108, 24, }, + { 2, 1, 0, 7, 108, 24, }, + { 1, 1, 0, 7, 108, 24, }, + { 0, 1, 0, 7, 112, 24, }, + { 2, 1, 0, 7, 112, 24, }, + { 1, 1, 0, 7, 112, 24, }, + { 0, 1, 0, 7, 116, 24, }, + { 2, 1, 0, 7, 116, 24, }, + { 1, 1, 0, 7, 116, 24, }, + { 0, 1, 0, 7, 120, 24, }, + { 2, 1, 0, 7, 120, 24, }, + { 1, 1, 0, 7, 120, 24, }, + { 0, 1, 0, 7, 124, 24, }, + { 2, 1, 0, 7, 124, 24, }, + { 1, 1, 0, 7, 124, 24, }, + { 0, 1, 0, 7, 128, 24, }, + { 2, 1, 0, 7, 128, 24, }, + { 1, 1, 0, 7, 128, 24, }, + { 0, 1, 0, 7, 132, 24, }, + { 2, 1, 0, 7, 132, 24, }, + { 1, 1, 0, 7, 132, 24, }, + { 0, 1, 0, 7, 136, 24, }, + { 2, 1, 0, 7, 136, 24, }, + { 1, 1, 0, 7, 136, 24, }, + { 0, 1, 0, 7, 140, 20, }, + { 2, 1, 0, 7, 140, 24, }, + { 1, 1, 0, 7, 140, 24, }, + { 0, 1, 0, 7, 149, 20, }, + { 2, 1, 0, 7, 149, 24, }, + { 1, 1, 0, 7, 149, 63, }, + { 0, 1, 0, 7, 153, 24, }, + { 2, 1, 0, 7, 153, 24, }, + { 1, 1, 0, 7, 153, 63, }, + { 0, 1, 0, 7, 157, 24, }, + { 2, 1, 0, 7, 157, 24, }, + { 1, 1, 0, 7, 157, 63, }, + { 0, 1, 0, 7, 161, 24, }, + { 2, 1, 0, 7, 161, 24, }, + { 1, 1, 0, 7, 161, 63, }, + { 0, 1, 0, 7, 165, 24, }, + { 2, 1, 0, 7, 165, 24, }, + { 1, 1, 0, 7, 165, 63, }, + { 0, 1, 1, 2, 38, 26, }, + { 2, 1, 1, 2, 38, 32, }, + { 1, 1, 1, 2, 38, 32, }, + { 0, 1, 1, 2, 46, 32, }, + { 2, 1, 1, 2, 46, 32, }, + { 1, 1, 1, 2, 46, 32, }, + { 0, 1, 1, 2, 54, 32, }, + { 2, 1, 1, 2, 54, 32, }, + { 1, 1, 1, 2, 54, 32, }, + { 0, 1, 1, 2, 62, 26, }, + { 2, 1, 1, 2, 62, 32, }, + { 1, 1, 1, 2, 62, 32, }, + { 0, 1, 1, 2, 102, 26, }, + { 2, 1, 1, 2, 102, 32, }, + { 1, 1, 1, 2, 102, 32, }, + { 0, 1, 1, 2, 110, 32, }, + { 2, 1, 1, 2, 110, 32, }, + { 1, 1, 1, 2, 110, 32, }, + { 0, 1, 1, 2, 118, 32, }, + { 2, 1, 1, 2, 118, 32, }, + { 1, 1, 1, 2, 118, 32, }, + { 0, 1, 1, 2, 126, 32, }, + { 2, 1, 1, 2, 126, 32, }, + { 1, 1, 1, 2, 126, 32, }, + { 0, 1, 1, 2, 134, 32, }, + { 2, 1, 1, 2, 134, 32, }, + { 1, 1, 1, 2, 134, 32, }, + { 0, 1, 1, 2, 151, 26, }, + { 2, 1, 1, 2, 151, 32, }, + { 1, 1, 1, 2, 151, 63, }, + { 0, 1, 1, 2, 159, 32, }, + { 2, 1, 1, 2, 159, 32, }, + { 1, 1, 1, 2, 159, 63, }, + { 0, 1, 1, 3, 38, 24, }, + { 2, 1, 1, 3, 38, 28, }, + { 1, 1, 1, 3, 38, 28, }, + { 0, 1, 1, 3, 46, 28, }, + { 2, 1, 1, 3, 46, 28, }, + { 1, 1, 1, 3, 46, 28, }, + { 0, 1, 1, 3, 54, 28, }, + { 2, 1, 1, 3, 54, 28, }, + { 1, 1, 1, 3, 54, 28, }, + { 0, 1, 1, 3, 62, 24, }, + { 2, 1, 1, 3, 62, 28, }, + { 1, 1, 1, 3, 62, 28, }, + { 0, 1, 1, 3, 102, 24, }, + { 2, 1, 1, 3, 102, 28, }, + { 1, 1, 1, 3, 102, 28, }, + { 0, 1, 1, 3, 110, 28, }, + { 2, 1, 1, 3, 110, 28, }, + { 1, 1, 1, 3, 110, 28, }, + { 0, 1, 1, 3, 118, 28, }, + { 2, 1, 1, 3, 118, 28, }, + { 1, 1, 1, 3, 118, 28, }, + { 0, 1, 1, 3, 126, 28, }, + { 2, 1, 1, 3, 126, 28, }, + { 1, 1, 1, 3, 126, 28, }, + { 0, 1, 1, 3, 134, 28, }, + { 2, 1, 1, 3, 134, 28, }, + { 1, 1, 1, 3, 134, 28, }, + { 0, 1, 1, 3, 151, 24, }, + { 2, 1, 1, 3, 151, 28, }, + { 1, 1, 1, 3, 151, 63, }, + { 0, 1, 1, 3, 159, 28, }, + { 2, 1, 1, 3, 159, 28, }, + { 1, 1, 1, 3, 159, 63, }, + { 0, 1, 1, 6, 38, 20, }, + { 2, 1, 1, 6, 38, 26, }, + { 1, 1, 1, 6, 38, 26, }, + { 0, 1, 1, 6, 46, 26, }, + { 2, 1, 1, 6, 46, 26, }, + { 1, 1, 1, 6, 46, 26, }, + { 0, 1, 1, 6, 54, 26, }, + { 2, 1, 1, 6, 54, 26, }, + { 1, 1, 1, 6, 54, 26, }, + { 0, 1, 1, 6, 62, 20, }, + { 2, 1, 1, 6, 62, 26, }, + { 1, 1, 1, 6, 62, 26, }, + { 0, 1, 1, 6, 102, 20, }, + { 2, 1, 1, 6, 102, 26, }, + { 1, 1, 1, 6, 102, 26, }, + { 0, 1, 1, 6, 110, 26, }, + { 2, 1, 1, 6, 110, 26, }, + { 1, 1, 1, 6, 110, 26, }, + { 0, 1, 1, 6, 118, 26, }, + { 2, 1, 1, 6, 118, 26, }, + { 1, 1, 1, 6, 118, 26, }, + { 0, 1, 1, 6, 126, 26, }, + { 2, 1, 1, 6, 126, 26, }, + { 1, 1, 1, 6, 126, 26, }, + { 0, 1, 1, 6, 134, 26, }, + { 2, 1, 1, 6, 134, 26, }, + { 1, 1, 1, 6, 134, 26, }, + { 0, 1, 1, 6, 151, 20, }, + { 2, 1, 1, 6, 151, 26, }, + { 1, 1, 1, 6, 151, 63, }, + { 0, 1, 1, 6, 159, 26, }, + { 2, 1, 1, 6, 159, 26, }, + { 1, 1, 1, 6, 159, 63, }, + { 0, 1, 1, 7, 38, 18, }, + { 2, 1, 1, 7, 38, 24, }, + { 1, 1, 1, 7, 38, 24, }, + { 0, 1, 1, 7, 46, 24, }, + { 2, 1, 1, 7, 46, 24, }, + { 1, 1, 1, 7, 46, 24, }, + { 0, 1, 1, 7, 54, 24, }, + { 2, 1, 1, 7, 54, 24, }, + { 1, 1, 1, 7, 54, 24, }, + { 0, 1, 1, 7, 62, 18, }, + { 2, 1, 1, 7, 62, 24, }, + { 1, 1, 1, 7, 62, 24, }, + { 0, 1, 1, 7, 102, 18, }, + { 2, 1, 1, 7, 102, 24, }, + { 1, 1, 1, 7, 102, 24, }, + { 0, 1, 1, 7, 110, 24, }, + { 2, 1, 1, 7, 110, 24, }, + { 1, 1, 1, 7, 110, 24, }, + { 0, 1, 1, 7, 118, 24, }, + { 2, 1, 1, 7, 118, 24, }, + { 1, 1, 1, 7, 118, 24, }, + { 0, 1, 1, 7, 126, 24, }, + { 2, 1, 1, 7, 126, 24, }, + { 1, 1, 1, 7, 126, 24, }, + { 0, 1, 1, 7, 134, 24, }, + { 2, 1, 1, 7, 134, 24, }, + { 1, 1, 1, 7, 134, 24, }, + { 0, 1, 1, 7, 151, 18, }, + { 2, 1, 1, 7, 151, 24, }, + { 1, 1, 1, 7, 151, 63, }, + { 0, 1, 1, 7, 159, 24, }, + { 2, 1, 1, 7, 159, 24, }, + { 1, 1, 1, 7, 159, 63, }, + { 0, 1, 2, 4, 42, 22, }, + { 2, 1, 2, 4, 42, 30, }, + { 1, 1, 2, 4, 42, 30, }, + { 0, 1, 2, 4, 58, 22, }, + { 2, 1, 2, 4, 58, 30, }, + { 1, 1, 2, 4, 58, 30, }, + { 0, 1, 2, 4, 106, 22, }, + { 2, 1, 2, 4, 106, 30, }, + { 1, 1, 2, 4, 106, 30, }, + { 0, 1, 2, 4, 122, 30, }, + { 2, 1, 2, 4, 122, 30, }, + { 1, 1, 2, 4, 122, 30, }, + { 0, 1, 2, 4, 155, 22, }, + { 2, 1, 2, 4, 155, 30, }, + { 1, 1, 2, 4, 155, 63, }, + { 0, 1, 2, 5, 42, 20, }, + { 2, 1, 2, 5, 42, 28, }, + { 1, 1, 2, 5, 42, 28, }, + { 0, 1, 2, 5, 58, 20, }, + { 2, 1, 2, 5, 58, 28, }, + { 1, 1, 2, 5, 58, 28, }, + { 0, 1, 2, 5, 106, 20, }, + { 2, 1, 2, 5, 106, 28, }, + { 1, 1, 2, 5, 106, 28, }, + { 0, 1, 2, 5, 122, 28, }, + { 2, 1, 2, 5, 122, 28, }, + { 1, 1, 2, 5, 122, 28, }, + { 0, 1, 2, 5, 155, 20, }, + { 2, 1, 2, 5, 155, 28, }, + { 1, 1, 2, 5, 155, 63, }, + { 0, 1, 2, 8, 42, 18, }, + { 2, 1, 2, 8, 42, 26, }, + { 1, 1, 2, 8, 42, 26, }, + { 0, 1, 2, 8, 58, 18, }, + { 2, 1, 2, 8, 58, 26, }, + { 1, 1, 2, 8, 58, 26, }, + { 0, 1, 2, 8, 106, 18, }, + { 2, 1, 2, 8, 106, 26, }, + { 1, 1, 2, 8, 106, 26, }, + { 0, 1, 2, 8, 122, 26, }, + { 2, 1, 2, 8, 122, 26, }, + { 1, 1, 2, 8, 122, 26, }, + { 0, 1, 2, 8, 155, 18, }, + { 2, 1, 2, 8, 155, 26, }, + { 1, 1, 2, 8, 155, 63, }, + { 0, 1, 2, 9, 42, 16, }, + { 2, 1, 2, 9, 42, 24, }, + { 1, 1, 2, 9, 42, 24, }, + { 0, 1, 2, 9, 58, 16, }, + { 2, 1, 2, 9, 58, 24, }, + { 1, 1, 2, 9, 58, 24, }, + { 0, 1, 2, 9, 106, 16, }, + { 2, 1, 2, 9, 106, 24, }, + { 1, 1, 2, 9, 106, 24, }, + { 0, 1, 2, 9, 122, 24, }, + { 2, 1, 2, 9, 122, 24, }, + { 1, 1, 2, 9, 122, 24, }, + { 0, 1, 2, 9, 155, 16, }, + { 2, 1, 2, 9, 155, 24, }, + { 1, 1, 2, 9, 155, 63, }, +}; + +RTW_DECL_TABLE_TXPWR_LMT(rtw8814a_txpwr_lmt_type0); + +static const struct rtw_txpwr_lmt_cfg_pair rtw8814a_txpwr_lmt_type1[] = { + { 0, 0, 0, 0, 1, 34, }, + { 2, 0, 0, 0, 1, 32, }, + { 1, 0, 0, 0, 1, 32, }, + { 0, 0, 0, 0, 2, 34, }, + { 2, 0, 0, 0, 2, 32, }, + { 1, 0, 0, 0, 2, 32, }, + { 0, 0, 0, 0, 3, 34, }, + { 2, 0, 0, 0, 3, 32, }, + { 1, 0, 0, 0, 3, 32, }, + { 0, 0, 0, 0, 4, 34, }, + { 2, 0, 0, 0, 4, 32, }, + { 1, 0, 0, 0, 4, 32, }, + { 0, 0, 0, 0, 5, 34, }, + { 2, 0, 0, 0, 5, 32, }, + { 1, 0, 0, 0, 5, 32, }, + { 0, 0, 0, 0, 6, 34, }, + { 2, 0, 0, 0, 6, 32, }, + { 1, 0, 0, 0, 6, 32, }, + { 0, 0, 0, 0, 7, 34, }, + { 2, 0, 0, 0, 7, 32, }, + { 1, 0, 0, 0, 7, 32, }, + { 0, 0, 0, 0, 8, 34, }, + { 2, 0, 0, 0, 8, 32, }, + { 1, 0, 0, 0, 8, 32, }, + { 0, 0, 0, 0, 9, 34, }, + { 2, 0, 0, 0, 9, 32, }, + { 1, 0, 0, 0, 9, 32, }, + { 0, 0, 0, 0, 10, 34, }, + { 2, 0, 0, 0, 10, 32, }, + { 1, 0, 0, 0, 10, 32, }, + { 0, 0, 0, 0, 11, 34, }, + { 2, 0, 0, 0, 11, 32, }, + { 1, 0, 0, 0, 11, 32, }, + { 0, 0, 0, 0, 12, 24, }, + { 2, 0, 0, 0, 12, 32, }, + { 1, 0, 0, 0, 12, 32, }, + { 0, 0, 0, 0, 13, 16, }, + { 2, 0, 0, 0, 13, 32, }, + { 1, 0, 0, 0, 13, 32, }, + { 0, 0, 0, 0, 14, 63, }, + { 2, 0, 0, 0, 14, 63, }, + { 1, 0, 0, 0, 14, 32, }, + { 0, 0, 0, 1, 1, 30, }, + { 2, 0, 0, 1, 1, 32, }, + { 1, 0, 0, 1, 1, 32, }, + { 0, 0, 0, 1, 2, 32, }, + { 2, 0, 0, 1, 2, 32, }, + { 1, 0, 0, 1, 2, 32, }, + { 0, 0, 0, 1, 3, 32, }, + { 2, 0, 0, 1, 3, 32, }, + { 1, 0, 0, 1, 3, 32, }, + { 0, 0, 0, 1, 4, 32, }, + { 2, 0, 0, 1, 4, 32, }, + { 1, 0, 0, 1, 4, 32, }, + { 0, 0, 0, 1, 5, 32, }, + { 2, 0, 0, 1, 5, 32, }, + { 1, 0, 0, 1, 5, 32, }, + { 0, 0, 0, 1, 6, 32, }, + { 2, 0, 0, 1, 6, 32, }, + { 1, 0, 0, 1, 6, 32, }, + { 0, 0, 0, 1, 7, 32, }, + { 2, 0, 0, 1, 7, 32, }, + { 1, 0, 0, 1, 7, 32, }, + { 0, 0, 0, 1, 8, 32, }, + { 2, 0, 0, 1, 8, 32, }, + { 1, 0, 0, 1, 8, 32, }, + { 0, 0, 0, 1, 9, 32, }, + { 2, 0, 0, 1, 9, 32, }, + { 1, 0, 0, 1, 9, 32, }, + { 0, 0, 0, 1, 10, 32, }, + { 2, 0, 0, 1, 10, 32, }, + { 1, 0, 0, 1, 10, 32, }, + { 0, 0, 0, 1, 11, 30, }, + { 2, 0, 0, 1, 11, 32, }, + { 1, 0, 0, 1, 11, 32, }, + { 0, 0, 0, 1, 12, 18, }, + { 2, 0, 0, 1, 12, 32, }, + { 1, 0, 0, 1, 12, 32, }, + { 0, 0, 0, 1, 13, 8, }, + { 2, 0, 0, 1, 13, 32, }, + { 1, 0, 0, 1, 13, 32, }, + { 0, 0, 0, 1, 14, 63, }, + { 2, 0, 0, 1, 14, 63, }, + { 1, 0, 0, 1, 14, 63, }, + { 0, 0, 0, 2, 1, 28, }, + { 2, 0, 0, 2, 1, 32, }, + { 1, 0, 0, 2, 1, 32, }, + { 0, 0, 0, 2, 2, 32, }, + { 2, 0, 0, 2, 2, 32, }, + { 1, 0, 0, 2, 2, 32, }, + { 0, 0, 0, 2, 3, 32, }, + { 2, 0, 0, 2, 3, 32, }, + { 1, 0, 0, 2, 3, 32, }, + { 0, 0, 0, 2, 4, 32, }, + { 2, 0, 0, 2, 4, 32, }, + { 1, 0, 0, 2, 4, 32, }, + { 0, 0, 0, 2, 5, 32, }, + { 2, 0, 0, 2, 5, 32, }, + { 1, 0, 0, 2, 5, 32, }, + { 0, 0, 0, 2, 6, 32, }, + { 2, 0, 0, 2, 6, 32, }, + { 1, 0, 0, 2, 6, 32, }, + { 0, 0, 0, 2, 7, 32, }, + { 2, 0, 0, 2, 7, 32, }, + { 1, 0, 0, 2, 7, 32, }, + { 0, 0, 0, 2, 8, 32, }, + { 2, 0, 0, 2, 8, 32, }, + { 1, 0, 0, 2, 8, 32, }, + { 0, 0, 0, 2, 9, 32, }, + { 2, 0, 0, 2, 9, 32, }, + { 1, 0, 0, 2, 9, 32, }, + { 0, 0, 0, 2, 10, 32, }, + { 2, 0, 0, 2, 10, 32, }, + { 1, 0, 0, 2, 10, 32, }, + { 0, 0, 0, 2, 11, 28, }, + { 2, 0, 0, 2, 11, 32, }, + { 1, 0, 0, 2, 11, 32, }, + { 0, 0, 0, 2, 12, 16, }, + { 2, 0, 0, 2, 12, 32, }, + { 1, 0, 0, 2, 12, 32, }, + { 0, 0, 0, 2, 13, 6, }, + { 2, 0, 0, 2, 13, 32, }, + { 1, 0, 0, 2, 13, 32, }, + { 0, 0, 0, 2, 14, 63, }, + { 2, 0, 0, 2, 14, 63, }, + { 1, 0, 0, 2, 14, 63, }, + { 0, 0, 0, 3, 1, 26, }, + { 2, 0, 0, 3, 1, 30, }, + { 1, 0, 0, 3, 1, 30, }, + { 0, 0, 0, 3, 2, 30, }, + { 2, 0, 0, 3, 2, 30, }, + { 1, 0, 0, 3, 2, 30, }, + { 0, 0, 0, 3, 3, 30, }, + { 2, 0, 0, 3, 3, 30, }, + { 1, 0, 0, 3, 3, 30, }, + { 0, 0, 0, 3, 4, 30, }, + { 2, 0, 0, 3, 4, 30, }, + { 1, 0, 0, 3, 4, 30, }, + { 0, 0, 0, 3, 5, 30, }, + { 2, 0, 0, 3, 5, 30, }, + { 1, 0, 0, 3, 5, 30, }, + { 0, 0, 0, 3, 6, 30, }, + { 2, 0, 0, 3, 6, 30, }, + { 1, 0, 0, 3, 6, 30, }, + { 0, 0, 0, 3, 7, 30, }, + { 2, 0, 0, 3, 7, 30, }, + { 1, 0, 0, 3, 7, 30, }, + { 0, 0, 0, 3, 8, 30, }, + { 2, 0, 0, 3, 8, 30, }, + { 1, 0, 0, 3, 8, 30, }, + { 0, 0, 0, 3, 9, 30, }, + { 2, 0, 0, 3, 9, 30, }, + { 1, 0, 0, 3, 9, 30, }, + { 0, 0, 0, 3, 10, 30, }, + { 2, 0, 0, 3, 10, 30, }, + { 1, 0, 0, 3, 10, 30, }, + { 0, 0, 0, 3, 11, 26, }, + { 2, 0, 0, 3, 11, 30, }, + { 1, 0, 0, 3, 11, 30, }, + { 0, 0, 0, 3, 12, 14, }, + { 2, 0, 0, 3, 12, 30, }, + { 1, 0, 0, 3, 12, 30, }, + { 0, 0, 0, 3, 13, 4, }, + { 2, 0, 0, 3, 13, 30, }, + { 1, 0, 0, 3, 13, 30, }, + { 0, 0, 0, 3, 14, 63, }, + { 2, 0, 0, 3, 14, 63, }, + { 1, 0, 0, 3, 14, 63, }, + { 0, 0, 0, 6, 1, 24, }, + { 2, 0, 0, 6, 1, 28, }, + { 1, 0, 0, 6, 1, 28, }, + { 0, 0, 0, 6, 2, 28, }, + { 2, 0, 0, 6, 2, 28, }, + { 1, 0, 0, 6, 2, 28, }, + { 0, 0, 0, 6, 3, 28, }, + { 2, 0, 0, 6, 3, 28, }, + { 1, 0, 0, 6, 3, 28, }, + { 0, 0, 0, 6, 4, 28, }, + { 2, 0, 0, 6, 4, 28, }, + { 1, 0, 0, 6, 4, 28, }, + { 0, 0, 0, 6, 5, 28, }, + { 2, 0, 0, 6, 5, 28, }, + { 1, 0, 0, 6, 5, 28, }, + { 0, 0, 0, 6, 6, 28, }, + { 2, 0, 0, 6, 6, 28, }, + { 1, 0, 0, 6, 6, 28, }, + { 0, 0, 0, 6, 7, 28, }, + { 2, 0, 0, 6, 7, 28, }, + { 1, 0, 0, 6, 7, 28, }, + { 0, 0, 0, 6, 8, 28, }, + { 2, 0, 0, 6, 8, 28, }, + { 1, 0, 0, 6, 8, 28, }, + { 0, 0, 0, 6, 9, 28, }, + { 2, 0, 0, 6, 9, 28, }, + { 1, 0, 0, 6, 9, 28, }, + { 0, 0, 0, 6, 10, 28, }, + { 2, 0, 0, 6, 10, 28, }, + { 1, 0, 0, 6, 10, 28, }, + { 0, 0, 0, 6, 11, 24, }, + { 2, 0, 0, 6, 11, 28, }, + { 1, 0, 0, 6, 11, 28, }, + { 0, 0, 0, 6, 12, 14, }, + { 2, 0, 0, 6, 12, 28, }, + { 1, 0, 0, 6, 12, 28, }, + { 0, 0, 0, 6, 13, 4, }, + { 2, 0, 0, 6, 13, 28, }, + { 1, 0, 0, 6, 13, 28, }, + { 0, 0, 0, 6, 14, 63, }, + { 2, 0, 0, 6, 14, 63, }, + { 1, 0, 0, 6, 14, 63, }, + { 0, 0, 0, 7, 1, 22, }, + { 2, 0, 0, 7, 1, 26, }, + { 1, 0, 0, 7, 1, 26, }, + { 0, 0, 0, 7, 2, 26, }, + { 2, 0, 0, 7, 2, 26, }, + { 1, 0, 0, 7, 2, 26, }, + { 0, 0, 0, 7, 3, 26, }, + { 2, 0, 0, 7, 3, 26, }, + { 1, 0, 0, 7, 3, 26, }, + { 0, 0, 0, 7, 4, 26, }, + { 2, 0, 0, 7, 4, 26, }, + { 1, 0, 0, 7, 4, 26, }, + { 0, 0, 0, 7, 5, 26, }, + { 2, 0, 0, 7, 5, 26, }, + { 1, 0, 0, 7, 5, 26, }, + { 0, 0, 0, 7, 6, 26, }, + { 2, 0, 0, 7, 6, 26, }, + { 1, 0, 0, 7, 6, 26, }, + { 0, 0, 0, 7, 7, 26, }, + { 2, 0, 0, 7, 7, 26, }, + { 1, 0, 0, 7, 7, 26, }, + { 0, 0, 0, 7, 8, 26, }, + { 2, 0, 0, 7, 8, 26, }, + { 1, 0, 0, 7, 8, 26, }, + { 0, 0, 0, 7, 9, 26, }, + { 2, 0, 0, 7, 9, 26, }, + { 1, 0, 0, 7, 9, 26, }, + { 0, 0, 0, 7, 10, 26, }, + { 2, 0, 0, 7, 10, 26, }, + { 1, 0, 0, 7, 10, 26, }, + { 0, 0, 0, 7, 11, 22, }, + { 2, 0, 0, 7, 11, 26, }, + { 1, 0, 0, 7, 11, 26, }, + { 0, 0, 0, 7, 12, 14, }, + { 2, 0, 0, 7, 12, 26, }, + { 1, 0, 0, 7, 12, 26, }, + { 0, 0, 0, 7, 13, 4, }, + { 2, 0, 0, 7, 13, 26, }, + { 1, 0, 0, 7, 13, 26, }, + { 0, 0, 0, 7, 14, 63, }, + { 2, 0, 0, 7, 14, 63, }, + { 1, 0, 0, 7, 14, 63, }, + { 0, 0, 1, 2, 1, 63, }, + { 2, 0, 1, 2, 1, 63, }, + { 1, 0, 1, 2, 1, 63, }, + { 0, 0, 1, 2, 2, 63, }, + { 2, 0, 1, 2, 2, 63, }, + { 1, 0, 1, 2, 2, 63, }, + { 0, 0, 1, 2, 3, 28, }, + { 2, 0, 1, 2, 3, 32, }, + { 1, 0, 1, 2, 3, 32, }, + { 0, 0, 1, 2, 4, 32, }, + { 2, 0, 1, 2, 4, 32, }, + { 1, 0, 1, 2, 4, 32, }, + { 0, 0, 1, 2, 5, 32, }, + { 2, 0, 1, 2, 5, 32, }, + { 1, 0, 1, 2, 5, 32, }, + { 0, 0, 1, 2, 6, 32, }, + { 2, 0, 1, 2, 6, 32, }, + { 1, 0, 1, 2, 6, 32, }, + { 0, 0, 1, 2, 7, 32, }, + { 2, 0, 1, 2, 7, 32, }, + { 1, 0, 1, 2, 7, 32, }, + { 0, 0, 1, 2, 8, 32, }, + { 2, 0, 1, 2, 8, 32, }, + { 1, 0, 1, 2, 8, 32, }, + { 0, 0, 1, 2, 9, 32, }, + { 2, 0, 1, 2, 9, 32, }, + { 1, 0, 1, 2, 9, 32, }, + { 0, 0, 1, 2, 10, 32, }, + { 2, 0, 1, 2, 10, 32, }, + { 1, 0, 1, 2, 10, 32, }, + { 0, 0, 1, 2, 11, 28, }, + { 2, 0, 1, 2, 11, 32, }, + { 1, 0, 1, 2, 11, 32, }, + { 0, 0, 1, 2, 12, 16, }, + { 2, 0, 1, 2, 12, 32, }, + { 1, 0, 1, 2, 12, 32, }, + { 0, 0, 1, 2, 13, 10, }, + { 2, 0, 1, 2, 13, 32, }, + { 1, 0, 1, 2, 13, 32, }, + { 0, 0, 1, 2, 14, 63, }, + { 2, 0, 1, 2, 14, 63, }, + { 1, 0, 1, 2, 14, 63, }, + { 0, 0, 1, 3, 1, 63, }, + { 2, 0, 1, 3, 1, 63, }, + { 1, 0, 1, 3, 1, 63, }, + { 0, 0, 1, 3, 2, 63, }, + { 2, 0, 1, 3, 2, 63, }, + { 1, 0, 1, 3, 2, 63, }, + { 0, 0, 1, 3, 3, 26, }, + { 2, 0, 1, 3, 3, 30, }, + { 1, 0, 1, 3, 3, 30, }, + { 0, 0, 1, 3, 4, 30, }, + { 2, 0, 1, 3, 4, 30, }, + { 1, 0, 1, 3, 4, 30, }, + { 0, 0, 1, 3, 5, 30, }, + { 2, 0, 1, 3, 5, 30, }, + { 1, 0, 1, 3, 5, 30, }, + { 0, 0, 1, 3, 6, 30, }, + { 2, 0, 1, 3, 6, 30, }, + { 1, 0, 1, 3, 6, 30, }, + { 0, 0, 1, 3, 7, 30, }, + { 2, 0, 1, 3, 7, 30, }, + { 1, 0, 1, 3, 7, 30, }, + { 0, 0, 1, 3, 8, 30, }, + { 2, 0, 1, 3, 8, 30, }, + { 1, 0, 1, 3, 8, 30, }, + { 0, 0, 1, 3, 9, 30, }, + { 2, 0, 1, 3, 9, 30, }, + { 1, 0, 1, 3, 9, 30, }, + { 0, 0, 1, 3, 10, 30, }, + { 2, 0, 1, 3, 10, 30, }, + { 1, 0, 1, 3, 10, 30, }, + { 0, 0, 1, 3, 11, 26, }, + { 2, 0, 1, 3, 11, 30, }, + { 1, 0, 1, 3, 11, 30, }, + { 0, 0, 1, 3, 12, 14, }, + { 2, 0, 1, 3, 12, 30, }, + { 1, 0, 1, 3, 12, 30, }, + { 0, 0, 1, 3, 13, 8, }, + { 2, 0, 1, 3, 13, 30, }, + { 1, 0, 1, 3, 13, 30, }, + { 0, 0, 1, 3, 14, 63, }, + { 2, 0, 1, 3, 14, 63, }, + { 1, 0, 1, 3, 14, 63, }, + { 0, 0, 1, 6, 1, 63, }, + { 2, 0, 1, 6, 1, 63, }, + { 1, 0, 1, 6, 1, 63, }, + { 0, 0, 1, 6, 2, 63, }, + { 2, 0, 1, 6, 2, 63, }, + { 1, 0, 1, 6, 2, 63, }, + { 0, 0, 1, 6, 3, 24, }, + { 2, 0, 1, 6, 3, 28, }, + { 1, 0, 1, 6, 3, 28, }, + { 0, 0, 1, 6, 4, 28, }, + { 2, 0, 1, 6, 4, 28, }, + { 1, 0, 1, 6, 4, 28, }, + { 0, 0, 1, 6, 5, 28, }, + { 2, 0, 1, 6, 5, 28, }, + { 1, 0, 1, 6, 5, 28, }, + { 0, 0, 1, 6, 6, 28, }, + { 2, 0, 1, 6, 6, 28, }, + { 1, 0, 1, 6, 6, 28, }, + { 0, 0, 1, 6, 7, 28, }, + { 2, 0, 1, 6, 7, 28, }, + { 1, 0, 1, 6, 7, 28, }, + { 0, 0, 1, 6, 8, 28, }, + { 2, 0, 1, 6, 8, 28, }, + { 1, 0, 1, 6, 8, 28, }, + { 0, 0, 1, 6, 9, 28, }, + { 2, 0, 1, 6, 9, 28, }, + { 1, 0, 1, 6, 9, 28, }, + { 0, 0, 1, 6, 10, 28, }, + { 2, 0, 1, 6, 10, 28, }, + { 1, 0, 1, 6, 10, 28, }, + { 0, 0, 1, 6, 11, 24, }, + { 2, 0, 1, 6, 11, 28, }, + { 1, 0, 1, 6, 11, 28, }, + { 0, 0, 1, 6, 12, 14, }, + { 2, 0, 1, 6, 12, 28, }, + { 1, 0, 1, 6, 12, 28, }, + { 0, 0, 1, 6, 13, 8, }, + { 2, 0, 1, 6, 13, 28, }, + { 1, 0, 1, 6, 13, 28, }, + { 0, 0, 1, 6, 14, 63, }, + { 2, 0, 1, 6, 14, 63, }, + { 1, 0, 1, 6, 14, 63, }, + { 0, 0, 1, 7, 1, 63, }, + { 2, 0, 1, 7, 1, 63, }, + { 1, 0, 1, 7, 1, 63, }, + { 0, 0, 1, 7, 2, 63, }, + { 2, 0, 1, 7, 2, 63, }, + { 1, 0, 1, 7, 2, 63, }, + { 0, 0, 1, 7, 3, 22, }, + { 2, 0, 1, 7, 3, 26, }, + { 1, 0, 1, 7, 3, 26, }, + { 0, 0, 1, 7, 4, 26, }, + { 2, 0, 1, 7, 4, 26, }, + { 1, 0, 1, 7, 4, 26, }, + { 0, 0, 1, 7, 5, 26, }, + { 2, 0, 1, 7, 5, 26, }, + { 1, 0, 1, 7, 5, 26, }, + { 0, 0, 1, 7, 6, 26, }, + { 2, 0, 1, 7, 6, 26, }, + { 1, 0, 1, 7, 6, 26, }, + { 0, 0, 1, 7, 7, 26, }, + { 2, 0, 1, 7, 7, 26, }, + { 1, 0, 1, 7, 7, 26, }, + { 0, 0, 1, 7, 8, 26, }, + { 2, 0, 1, 7, 8, 26, }, + { 1, 0, 1, 7, 8, 26, }, + { 0, 0, 1, 7, 9, 26, }, + { 2, 0, 1, 7, 9, 26, }, + { 1, 0, 1, 7, 9, 26, }, + { 0, 0, 1, 7, 10, 26, }, + { 2, 0, 1, 7, 10, 26, }, + { 1, 0, 1, 7, 10, 26, }, + { 0, 0, 1, 7, 11, 22, }, + { 2, 0, 1, 7, 11, 26, }, + { 1, 0, 1, 7, 11, 26, }, + { 0, 0, 1, 7, 12, 14, }, + { 2, 0, 1, 7, 12, 26, }, + { 1, 0, 1, 7, 12, 26, }, + { 0, 0, 1, 7, 13, 8, }, + { 2, 0, 1, 7, 13, 26, }, + { 1, 0, 1, 7, 13, 26, }, + { 0, 0, 1, 7, 14, 63, }, + { 2, 0, 1, 7, 14, 63, }, + { 1, 0, 1, 7, 14, 63, }, + { 0, 1, 0, 1, 36, 28, }, + { 2, 1, 0, 1, 36, 32, }, + { 1, 1, 0, 1, 36, 32, }, + { 0, 1, 0, 1, 40, 32, }, + { 2, 1, 0, 1, 40, 32, }, + { 1, 1, 0, 1, 40, 32, }, + { 0, 1, 0, 1, 44, 32, }, + { 2, 1, 0, 1, 44, 32, }, + { 1, 1, 0, 1, 44, 32, }, + { 0, 1, 0, 1, 48, 32, }, + { 2, 1, 0, 1, 48, 32, }, + { 1, 1, 0, 1, 48, 32, }, + { 0, 1, 0, 1, 52, 32, }, + { 2, 1, 0, 1, 52, 32, }, + { 1, 1, 0, 1, 52, 32, }, + { 0, 1, 0, 1, 56, 32, }, + { 2, 1, 0, 1, 56, 32, }, + { 1, 1, 0, 1, 56, 32, }, + { 0, 1, 0, 1, 60, 32, }, + { 2, 1, 0, 1, 60, 32, }, + { 1, 1, 0, 1, 60, 32, }, + { 0, 1, 0, 1, 64, 30, }, + { 2, 1, 0, 1, 64, 32, }, + { 1, 1, 0, 1, 64, 32, }, + { 0, 1, 0, 1, 100, 28, }, + { 2, 1, 0, 1, 100, 32, }, + { 1, 1, 0, 1, 100, 32, }, + { 0, 1, 0, 1, 104, 32, }, + { 2, 1, 0, 1, 104, 32, }, + { 1, 1, 0, 1, 104, 32, }, + { 0, 1, 0, 1, 108, 32, }, + { 2, 1, 0, 1, 108, 32, }, + { 1, 1, 0, 1, 108, 32, }, + { 0, 1, 0, 1, 112, 32, }, + { 2, 1, 0, 1, 112, 32, }, + { 1, 1, 0, 1, 112, 32, }, + { 0, 1, 0, 1, 116, 32, }, + { 2, 1, 0, 1, 116, 32, }, + { 1, 1, 0, 1, 116, 32, }, + { 0, 1, 0, 1, 120, 32, }, + { 2, 1, 0, 1, 120, 32, }, + { 1, 1, 0, 1, 120, 32, }, + { 0, 1, 0, 1, 124, 32, }, + { 2, 1, 0, 1, 124, 32, }, + { 1, 1, 0, 1, 124, 32, }, + { 0, 1, 0, 1, 128, 32, }, + { 2, 1, 0, 1, 128, 32, }, + { 1, 1, 0, 1, 128, 32, }, + { 0, 1, 0, 1, 132, 32, }, + { 2, 1, 0, 1, 132, 32, }, + { 1, 1, 0, 1, 132, 32, }, + { 0, 1, 0, 1, 136, 32, }, + { 2, 1, 0, 1, 136, 32, }, + { 1, 1, 0, 1, 136, 32, }, + { 0, 1, 0, 1, 140, 28, }, + { 2, 1, 0, 1, 140, 32, }, + { 1, 1, 0, 1, 140, 32, }, + { 0, 1, 0, 1, 149, 28, }, + { 2, 1, 0, 1, 149, 32, }, + { 1, 1, 0, 1, 149, 63, }, + { 0, 1, 0, 1, 153, 32, }, + { 2, 1, 0, 1, 153, 32, }, + { 1, 1, 0, 1, 153, 63, }, + { 0, 1, 0, 1, 157, 32, }, + { 2, 1, 0, 1, 157, 32, }, + { 1, 1, 0, 1, 157, 63, }, + { 0, 1, 0, 1, 161, 32, }, + { 2, 1, 0, 1, 161, 32, }, + { 1, 1, 0, 1, 161, 63, }, + { 0, 1, 0, 1, 165, 32, }, + { 2, 1, 0, 1, 165, 32, }, + { 1, 1, 0, 1, 165, 63, }, + { 0, 1, 0, 2, 36, 28, }, + { 2, 1, 0, 2, 36, 32, }, + { 1, 1, 0, 2, 36, 32, }, + { 0, 1, 0, 2, 40, 32, }, + { 2, 1, 0, 2, 40, 32, }, + { 1, 1, 0, 2, 40, 32, }, + { 0, 1, 0, 2, 44, 32, }, + { 2, 1, 0, 2, 44, 32, }, + { 1, 1, 0, 2, 44, 32, }, + { 0, 1, 0, 2, 48, 32, }, + { 2, 1, 0, 2, 48, 32, }, + { 1, 1, 0, 2, 48, 32, }, + { 0, 1, 0, 2, 52, 32, }, + { 2, 1, 0, 2, 52, 32, }, + { 1, 1, 0, 2, 52, 32, }, + { 0, 1, 0, 2, 56, 32, }, + { 2, 1, 0, 2, 56, 32, }, + { 1, 1, 0, 2, 56, 32, }, + { 0, 1, 0, 2, 60, 32, }, + { 2, 1, 0, 2, 60, 32, }, + { 1, 1, 0, 2, 60, 32, }, + { 0, 1, 0, 2, 64, 30, }, + { 2, 1, 0, 2, 64, 32, }, + { 1, 1, 0, 2, 64, 32, }, + { 0, 1, 0, 2, 100, 28, }, + { 2, 1, 0, 2, 100, 32, }, + { 1, 1, 0, 2, 100, 32, }, + { 0, 1, 0, 2, 104, 32, }, + { 2, 1, 0, 2, 104, 32, }, + { 1, 1, 0, 2, 104, 32, }, + { 0, 1, 0, 2, 108, 32, }, + { 2, 1, 0, 2, 108, 32, }, + { 1, 1, 0, 2, 108, 32, }, + { 0, 1, 0, 2, 112, 32, }, + { 2, 1, 0, 2, 112, 32, }, + { 1, 1, 0, 2, 112, 32, }, + { 0, 1, 0, 2, 116, 32, }, + { 2, 1, 0, 2, 116, 32, }, + { 1, 1, 0, 2, 116, 32, }, + { 0, 1, 0, 2, 120, 32, }, + { 2, 1, 0, 2, 120, 32, }, + { 1, 1, 0, 2, 120, 32, }, + { 0, 1, 0, 2, 124, 32, }, + { 2, 1, 0, 2, 124, 32, }, + { 1, 1, 0, 2, 124, 32, }, + { 0, 1, 0, 2, 128, 32, }, + { 2, 1, 0, 2, 128, 32, }, + { 1, 1, 0, 2, 128, 32, }, + { 0, 1, 0, 2, 132, 32, }, + { 2, 1, 0, 2, 132, 32, }, + { 1, 1, 0, 2, 132, 32, }, + { 0, 1, 0, 2, 136, 32, }, + { 2, 1, 0, 2, 136, 32, }, + { 1, 1, 0, 2, 136, 32, }, + { 0, 1, 0, 2, 140, 28, }, + { 2, 1, 0, 2, 140, 32, }, + { 1, 1, 0, 2, 140, 32, }, + { 0, 1, 0, 2, 149, 28, }, + { 2, 1, 0, 2, 149, 32, }, + { 1, 1, 0, 2, 149, 63, }, + { 0, 1, 0, 2, 153, 32, }, + { 2, 1, 0, 2, 153, 32, }, + { 1, 1, 0, 2, 153, 63, }, + { 0, 1, 0, 2, 157, 32, }, + { 2, 1, 0, 2, 157, 32, }, + { 1, 1, 0, 2, 157, 63, }, + { 0, 1, 0, 2, 161, 32, }, + { 2, 1, 0, 2, 161, 32, }, + { 1, 1, 0, 2, 161, 63, }, + { 0, 1, 0, 2, 165, 32, }, + { 2, 1, 0, 2, 165, 32, }, + { 1, 1, 0, 2, 165, 63, }, + { 0, 1, 0, 3, 36, 26, }, + { 2, 1, 0, 3, 36, 30, }, + { 1, 1, 0, 3, 36, 30, }, + { 0, 1, 0, 3, 40, 30, }, + { 2, 1, 0, 3, 40, 30, }, + { 1, 1, 0, 3, 40, 30, }, + { 0, 1, 0, 3, 44, 30, }, + { 2, 1, 0, 3, 44, 30, }, + { 1, 1, 0, 3, 44, 30, }, + { 0, 1, 0, 3, 48, 30, }, + { 2, 1, 0, 3, 48, 30, }, + { 1, 1, 0, 3, 48, 30, }, + { 0, 1, 0, 3, 52, 30, }, + { 2, 1, 0, 3, 52, 30, }, + { 1, 1, 0, 3, 52, 30, }, + { 0, 1, 0, 3, 56, 30, }, + { 2, 1, 0, 3, 56, 30, }, + { 1, 1, 0, 3, 56, 30, }, + { 0, 1, 0, 3, 60, 30, }, + { 2, 1, 0, 3, 60, 30, }, + { 1, 1, 0, 3, 60, 30, }, + { 0, 1, 0, 3, 64, 28, }, + { 2, 1, 0, 3, 64, 30, }, + { 1, 1, 0, 3, 64, 30, }, + { 0, 1, 0, 3, 100, 28, }, + { 2, 1, 0, 3, 100, 30, }, + { 1, 1, 0, 3, 100, 30, }, + { 0, 1, 0, 3, 104, 30, }, + { 2, 1, 0, 3, 104, 30, }, + { 1, 1, 0, 3, 104, 30, }, + { 0, 1, 0, 3, 108, 30, }, + { 2, 1, 0, 3, 108, 30, }, + { 1, 1, 0, 3, 108, 30, }, + { 0, 1, 0, 3, 112, 30, }, + { 2, 1, 0, 3, 112, 30, }, + { 1, 1, 0, 3, 112, 30, }, + { 0, 1, 0, 3, 116, 30, }, + { 2, 1, 0, 3, 116, 30, }, + { 1, 1, 0, 3, 116, 30, }, + { 0, 1, 0, 3, 120, 30, }, + { 2, 1, 0, 3, 120, 30, }, + { 1, 1, 0, 3, 120, 30, }, + { 0, 1, 0, 3, 124, 30, }, + { 2, 1, 0, 3, 124, 30, }, + { 1, 1, 0, 3, 124, 30, }, + { 0, 1, 0, 3, 128, 30, }, + { 2, 1, 0, 3, 128, 30, }, + { 1, 1, 0, 3, 128, 30, }, + { 0, 1, 0, 3, 132, 30, }, + { 2, 1, 0, 3, 132, 30, }, + { 1, 1, 0, 3, 132, 30, }, + { 0, 1, 0, 3, 136, 30, }, + { 2, 1, 0, 3, 136, 30, }, + { 1, 1, 0, 3, 136, 30, }, + { 0, 1, 0, 3, 140, 26, }, + { 2, 1, 0, 3, 140, 30, }, + { 1, 1, 0, 3, 140, 30, }, + { 0, 1, 0, 3, 149, 26, }, + { 2, 1, 0, 3, 149, 30, }, + { 1, 1, 0, 3, 149, 63, }, + { 0, 1, 0, 3, 153, 30, }, + { 2, 1, 0, 3, 153, 30, }, + { 1, 1, 0, 3, 153, 63, }, + { 0, 1, 0, 3, 157, 30, }, + { 2, 1, 0, 3, 157, 30, }, + { 1, 1, 0, 3, 157, 63, }, + { 0, 1, 0, 3, 161, 30, }, + { 2, 1, 0, 3, 161, 30, }, + { 1, 1, 0, 3, 161, 63, }, + { 0, 1, 0, 3, 165, 30, }, + { 2, 1, 0, 3, 165, 30, }, + { 1, 1, 0, 3, 165, 63, }, + { 0, 1, 0, 6, 36, 24, }, + { 2, 1, 0, 6, 36, 28, }, + { 1, 1, 0, 6, 36, 28, }, + { 0, 1, 0, 6, 40, 28, }, + { 2, 1, 0, 6, 40, 28, }, + { 1, 1, 0, 6, 40, 28, }, + { 0, 1, 0, 6, 44, 28, }, + { 2, 1, 0, 6, 44, 28, }, + { 1, 1, 0, 6, 44, 28, }, + { 0, 1, 0, 6, 48, 28, }, + { 2, 1, 0, 6, 48, 28, }, + { 1, 1, 0, 6, 48, 28, }, + { 0, 1, 0, 6, 52, 28, }, + { 2, 1, 0, 6, 52, 28, }, + { 1, 1, 0, 6, 52, 28, }, + { 0, 1, 0, 6, 56, 28, }, + { 2, 1, 0, 6, 56, 28, }, + { 1, 1, 0, 6, 56, 28, }, + { 0, 1, 0, 6, 60, 28, }, + { 2, 1, 0, 6, 60, 28, }, + { 1, 1, 0, 6, 60, 28, }, + { 0, 1, 0, 6, 64, 26, }, + { 2, 1, 0, 6, 64, 28, }, + { 1, 1, 0, 6, 64, 28, }, + { 0, 1, 0, 6, 100, 24, }, + { 2, 1, 0, 6, 100, 28, }, + { 1, 1, 0, 6, 100, 28, }, + { 0, 1, 0, 6, 104, 28, }, + { 2, 1, 0, 6, 104, 28, }, + { 1, 1, 0, 6, 104, 28, }, + { 0, 1, 0, 6, 108, 28, }, + { 2, 1, 0, 6, 108, 28, }, + { 1, 1, 0, 6, 108, 28, }, + { 0, 1, 0, 6, 112, 28, }, + { 2, 1, 0, 6, 112, 28, }, + { 1, 1, 0, 6, 112, 28, }, + { 0, 1, 0, 6, 116, 28, }, + { 2, 1, 0, 6, 116, 28, }, + { 1, 1, 0, 6, 116, 28, }, + { 0, 1, 0, 6, 120, 28, }, + { 2, 1, 0, 6, 120, 28, }, + { 1, 1, 0, 6, 120, 28, }, + { 0, 1, 0, 6, 124, 28, }, + { 2, 1, 0, 6, 124, 28, }, + { 1, 1, 0, 6, 124, 28, }, + { 0, 1, 0, 6, 128, 28, }, + { 2, 1, 0, 6, 128, 28, }, + { 1, 1, 0, 6, 128, 28, }, + { 0, 1, 0, 6, 132, 28, }, + { 2, 1, 0, 6, 132, 28, }, + { 1, 1, 0, 6, 132, 28, }, + { 0, 1, 0, 6, 136, 28, }, + { 2, 1, 0, 6, 136, 28, }, + { 1, 1, 0, 6, 136, 28, }, + { 0, 1, 0, 6, 140, 24, }, + { 2, 1, 0, 6, 140, 28, }, + { 1, 1, 0, 6, 140, 28, }, + { 0, 1, 0, 6, 149, 24, }, + { 2, 1, 0, 6, 149, 28, }, + { 1, 1, 0, 6, 149, 63, }, + { 0, 1, 0, 6, 153, 28, }, + { 2, 1, 0, 6, 153, 28, }, + { 1, 1, 0, 6, 153, 63, }, + { 0, 1, 0, 6, 157, 28, }, + { 2, 1, 0, 6, 157, 28, }, + { 1, 1, 0, 6, 157, 63, }, + { 0, 1, 0, 6, 161, 28, }, + { 2, 1, 0, 6, 161, 28, }, + { 1, 1, 0, 6, 161, 63, }, + { 0, 1, 0, 6, 165, 28, }, + { 2, 1, 0, 6, 165, 28, }, + { 1, 1, 0, 6, 165, 63, }, + { 0, 1, 0, 7, 36, 22, }, + { 2, 1, 0, 7, 36, 26, }, + { 1, 1, 0, 7, 36, 26, }, + { 0, 1, 0, 7, 40, 26, }, + { 2, 1, 0, 7, 40, 26, }, + { 1, 1, 0, 7, 40, 26, }, + { 0, 1, 0, 7, 44, 26, }, + { 2, 1, 0, 7, 44, 26, }, + { 1, 1, 0, 7, 44, 26, }, + { 0, 1, 0, 7, 48, 26, }, + { 2, 1, 0, 7, 48, 26, }, + { 1, 1, 0, 7, 48, 26, }, + { 0, 1, 0, 7, 52, 26, }, + { 2, 1, 0, 7, 52, 26, }, + { 1, 1, 0, 7, 52, 26, }, + { 0, 1, 0, 7, 56, 26, }, + { 2, 1, 0, 7, 56, 26, }, + { 1, 1, 0, 7, 56, 26, }, + { 0, 1, 0, 7, 60, 26, }, + { 2, 1, 0, 7, 60, 26, }, + { 1, 1, 0, 7, 60, 26, }, + { 0, 1, 0, 7, 64, 24, }, + { 2, 1, 0, 7, 64, 26, }, + { 1, 1, 0, 7, 64, 26, }, + { 0, 1, 0, 7, 100, 22, }, + { 2, 1, 0, 7, 100, 26, }, + { 1, 1, 0, 7, 100, 26, }, + { 0, 1, 0, 7, 104, 26, }, + { 2, 1, 0, 7, 104, 26, }, + { 1, 1, 0, 7, 104, 26, }, + { 0, 1, 0, 7, 108, 26, }, + { 2, 1, 0, 7, 108, 26, }, + { 1, 1, 0, 7, 108, 26, }, + { 0, 1, 0, 7, 112, 26, }, + { 2, 1, 0, 7, 112, 26, }, + { 1, 1, 0, 7, 112, 26, }, + { 0, 1, 0, 7, 116, 26, }, + { 2, 1, 0, 7, 116, 26, }, + { 1, 1, 0, 7, 116, 26, }, + { 0, 1, 0, 7, 120, 26, }, + { 2, 1, 0, 7, 120, 26, }, + { 1, 1, 0, 7, 120, 26, }, + { 0, 1, 0, 7, 124, 26, }, + { 2, 1, 0, 7, 124, 26, }, + { 1, 1, 0, 7, 124, 26, }, + { 0, 1, 0, 7, 128, 26, }, + { 2, 1, 0, 7, 128, 26, }, + { 1, 1, 0, 7, 128, 26, }, + { 0, 1, 0, 7, 132, 26, }, + { 2, 1, 0, 7, 132, 26, }, + { 1, 1, 0, 7, 132, 26, }, + { 0, 1, 0, 7, 136, 26, }, + { 2, 1, 0, 7, 136, 26, }, + { 1, 1, 0, 7, 136, 26, }, + { 0, 1, 0, 7, 140, 22, }, + { 2, 1, 0, 7, 140, 26, }, + { 1, 1, 0, 7, 140, 26, }, + { 0, 1, 0, 7, 149, 22, }, + { 2, 1, 0, 7, 149, 26, }, + { 1, 1, 0, 7, 149, 63, }, + { 0, 1, 0, 7, 153, 26, }, + { 2, 1, 0, 7, 153, 26, }, + { 1, 1, 0, 7, 153, 63, }, + { 0, 1, 0, 7, 157, 26, }, + { 2, 1, 0, 7, 157, 26, }, + { 1, 1, 0, 7, 157, 63, }, + { 0, 1, 0, 7, 161, 26, }, + { 2, 1, 0, 7, 161, 26, }, + { 1, 1, 0, 7, 161, 63, }, + { 0, 1, 0, 7, 165, 26, }, + { 2, 1, 0, 7, 165, 26, }, + { 1, 1, 0, 7, 165, 63, }, + { 0, 1, 1, 2, 38, 28, }, + { 2, 1, 1, 2, 38, 32, }, + { 1, 1, 1, 2, 38, 32, }, + { 0, 1, 1, 2, 46, 32, }, + { 2, 1, 1, 2, 46, 32, }, + { 1, 1, 1, 2, 46, 32, }, + { 0, 1, 1, 2, 54, 32, }, + { 2, 1, 1, 2, 54, 32, }, + { 1, 1, 1, 2, 54, 32, }, + { 0, 1, 1, 2, 62, 28, }, + { 2, 1, 1, 2, 62, 32, }, + { 1, 1, 1, 2, 62, 32, }, + { 0, 1, 1, 2, 102, 28, }, + { 2, 1, 1, 2, 102, 32, }, + { 1, 1, 1, 2, 102, 32, }, + { 0, 1, 1, 2, 110, 32, }, + { 2, 1, 1, 2, 110, 32, }, + { 1, 1, 1, 2, 110, 32, }, + { 0, 1, 1, 2, 118, 32, }, + { 2, 1, 1, 2, 118, 32, }, + { 1, 1, 1, 2, 118, 32, }, + { 0, 1, 1, 2, 126, 32, }, + { 2, 1, 1, 2, 126, 32, }, + { 1, 1, 1, 2, 126, 32, }, + { 0, 1, 1, 2, 134, 30, }, + { 2, 1, 1, 2, 134, 32, }, + { 1, 1, 1, 2, 134, 32, }, + { 0, 1, 1, 2, 151, 28, }, + { 2, 1, 1, 2, 151, 32, }, + { 1, 1, 1, 2, 151, 63, }, + { 0, 1, 1, 2, 159, 32, }, + { 2, 1, 1, 2, 159, 32, }, + { 1, 1, 1, 2, 159, 63, }, + { 0, 1, 1, 3, 38, 26, }, + { 2, 1, 1, 3, 38, 30, }, + { 1, 1, 1, 3, 38, 30, }, + { 0, 1, 1, 3, 46, 30, }, + { 2, 1, 1, 3, 46, 30, }, + { 1, 1, 1, 3, 46, 30, }, + { 0, 1, 1, 3, 54, 30, }, + { 2, 1, 1, 3, 54, 30, }, + { 1, 1, 1, 3, 54, 30, }, + { 0, 1, 1, 3, 62, 26, }, + { 2, 1, 1, 3, 62, 30, }, + { 1, 1, 1, 3, 62, 30, }, + { 0, 1, 1, 3, 102, 26, }, + { 2, 1, 1, 3, 102, 30, }, + { 1, 1, 1, 3, 102, 30, }, + { 0, 1, 1, 3, 110, 30, }, + { 2, 1, 1, 3, 110, 30, }, + { 1, 1, 1, 3, 110, 30, }, + { 0, 1, 1, 3, 118, 30, }, + { 2, 1, 1, 3, 118, 30, }, + { 1, 1, 1, 3, 118, 30, }, + { 0, 1, 1, 3, 126, 30, }, + { 2, 1, 1, 3, 126, 30, }, + { 1, 1, 1, 3, 126, 30, }, + { 0, 1, 1, 3, 134, 28, }, + { 2, 1, 1, 3, 134, 30, }, + { 1, 1, 1, 3, 134, 30, }, + { 0, 1, 1, 3, 151, 26, }, + { 2, 1, 1, 3, 151, 30, }, + { 1, 1, 1, 3, 151, 63, }, + { 0, 1, 1, 3, 159, 30, }, + { 2, 1, 1, 3, 159, 30, }, + { 1, 1, 1, 3, 159, 63, }, + { 0, 1, 1, 6, 38, 20, }, + { 2, 1, 1, 6, 38, 28, }, + { 1, 1, 1, 6, 38, 28, }, + { 0, 1, 1, 6, 46, 28, }, + { 2, 1, 1, 6, 46, 28, }, + { 1, 1, 1, 6, 46, 28, }, + { 0, 1, 1, 6, 54, 28, }, + { 2, 1, 1, 6, 54, 28, }, + { 1, 1, 1, 6, 54, 28, }, + { 0, 1, 1, 6, 62, 20, }, + { 2, 1, 1, 6, 62, 28, }, + { 1, 1, 1, 6, 62, 28, }, + { 0, 1, 1, 6, 102, 22, }, + { 2, 1, 1, 6, 102, 28, }, + { 1, 1, 1, 6, 102, 28, }, + { 0, 1, 1, 6, 110, 28, }, + { 2, 1, 1, 6, 110, 28, }, + { 1, 1, 1, 6, 110, 28, }, + { 0, 1, 1, 6, 118, 28, }, + { 2, 1, 1, 6, 118, 28, }, + { 1, 1, 1, 6, 118, 28, }, + { 0, 1, 1, 6, 126, 28, }, + { 2, 1, 1, 6, 126, 28, }, + { 1, 1, 1, 6, 126, 28, }, + { 0, 1, 1, 6, 134, 26, }, + { 2, 1, 1, 6, 134, 28, }, + { 1, 1, 1, 6, 134, 28, }, + { 0, 1, 1, 6, 151, 22, }, + { 2, 1, 1, 6, 151, 28, }, + { 1, 1, 1, 6, 151, 63, }, + { 0, 1, 1, 6, 159, 28, }, + { 2, 1, 1, 6, 159, 28, }, + { 1, 1, 1, 6, 159, 63, }, + { 0, 1, 1, 7, 38, 18, }, + { 2, 1, 1, 7, 38, 26, }, + { 1, 1, 1, 7, 38, 26, }, + { 0, 1, 1, 7, 46, 26, }, + { 2, 1, 1, 7, 46, 26, }, + { 1, 1, 1, 7, 46, 26, }, + { 0, 1, 1, 7, 54, 26, }, + { 2, 1, 1, 7, 54, 26, }, + { 1, 1, 1, 7, 54, 26, }, + { 0, 1, 1, 7, 62, 18, }, + { 2, 1, 1, 7, 62, 26, }, + { 1, 1, 1, 7, 62, 26, }, + { 0, 1, 1, 7, 102, 20, }, + { 2, 1, 1, 7, 102, 26, }, + { 1, 1, 1, 7, 102, 26, }, + { 0, 1, 1, 7, 110, 26, }, + { 2, 1, 1, 7, 110, 26, }, + { 1, 1, 1, 7, 110, 26, }, + { 0, 1, 1, 7, 118, 26, }, + { 2, 1, 1, 7, 118, 26, }, + { 1, 1, 1, 7, 118, 26, }, + { 0, 1, 1, 7, 126, 26, }, + { 2, 1, 1, 7, 126, 26, }, + { 1, 1, 1, 7, 126, 26, }, + { 0, 1, 1, 7, 134, 24, }, + { 2, 1, 1, 7, 134, 26, }, + { 1, 1, 1, 7, 134, 26, }, + { 0, 1, 1, 7, 151, 20, }, + { 2, 1, 1, 7, 151, 26, }, + { 1, 1, 1, 7, 151, 63, }, + { 0, 1, 1, 7, 159, 26, }, + { 2, 1, 1, 7, 159, 26, }, + { 1, 1, 1, 7, 159, 63, }, + { 0, 1, 2, 4, 42, 24, }, + { 2, 1, 2, 4, 42, 32, }, + { 1, 1, 2, 4, 42, 32, }, + { 0, 1, 2, 4, 58, 24, }, + { 2, 1, 2, 4, 58, 32, }, + { 1, 1, 2, 4, 58, 32, }, + { 0, 1, 2, 4, 106, 24, }, + { 2, 1, 2, 4, 106, 32, }, + { 1, 1, 2, 4, 106, 32, }, + { 0, 1, 2, 4, 122, 32, }, + { 2, 1, 2, 4, 122, 32, }, + { 1, 1, 2, 4, 122, 32, }, + { 0, 1, 2, 4, 155, 26, }, + { 2, 1, 2, 4, 155, 32, }, + { 1, 1, 2, 4, 155, 63, }, + { 0, 1, 2, 5, 42, 22, }, + { 2, 1, 2, 5, 42, 30, }, + { 1, 1, 2, 5, 42, 30, }, + { 0, 1, 2, 5, 58, 22, }, + { 2, 1, 2, 5, 58, 30, }, + { 1, 1, 2, 5, 58, 30, }, + { 0, 1, 2, 5, 106, 22, }, + { 2, 1, 2, 5, 106, 30, }, + { 1, 1, 2, 5, 106, 30, }, + { 0, 1, 2, 5, 122, 30, }, + { 2, 1, 2, 5, 122, 30, }, + { 1, 1, 2, 5, 122, 30, }, + { 0, 1, 2, 5, 155, 24, }, + { 2, 1, 2, 5, 155, 30, }, + { 1, 1, 2, 5, 155, 63, }, + { 0, 1, 2, 8, 42, 20, }, + { 2, 1, 2, 8, 42, 28, }, + { 1, 1, 2, 8, 42, 28, }, + { 0, 1, 2, 8, 58, 20, }, + { 2, 1, 2, 8, 58, 28, }, + { 1, 1, 2, 8, 58, 28, }, + { 0, 1, 2, 8, 106, 20, }, + { 2, 1, 2, 8, 106, 28, }, + { 1, 1, 2, 8, 106, 28, }, + { 0, 1, 2, 8, 122, 28, }, + { 2, 1, 2, 8, 122, 28, }, + { 1, 1, 2, 8, 122, 28, }, + { 0, 1, 2, 8, 155, 20, }, + { 2, 1, 2, 8, 155, 28, }, + { 1, 1, 2, 8, 155, 63, }, + { 0, 1, 2, 9, 42, 18, }, + { 2, 1, 2, 9, 42, 26, }, + { 1, 1, 2, 9, 42, 26, }, + { 0, 1, 2, 9, 58, 18, }, + { 2, 1, 2, 9, 58, 26, }, + { 1, 1, 2, 9, 58, 26, }, + { 0, 1, 2, 9, 106, 18, }, + { 2, 1, 2, 9, 106, 26, }, + { 1, 1, 2, 9, 106, 26, }, + { 0, 1, 2, 9, 122, 26, }, + { 2, 1, 2, 9, 122, 26, }, + { 1, 1, 2, 9, 122, 26, }, + { 0, 1, 2, 9, 155, 18, }, + { 2, 1, 2, 9, 155, 26, }, + { 1, 1, 2, 9, 155, 63, }, +}; + +RTW_DECL_TABLE_TXPWR_LMT(rtw8814a_txpwr_lmt_type1); + +static const struct rtw_txpwr_lmt_cfg_pair rtw8814a_txpwr_lmt_type2[] = { + { 0, 0, 0, 0, 1, 42, }, + { 2, 0, 0, 0, 1, 42, }, + { 1, 0, 0, 0, 1, 42, }, + { 0, 0, 0, 0, 2, 50, }, + { 2, 0, 0, 0, 2, 42, }, + { 1, 0, 0, 0, 2, 42, }, + { 0, 0, 0, 0, 3, 50, }, + { 2, 0, 0, 0, 3, 42, }, + { 1, 0, 0, 0, 3, 42, }, + { 0, 0, 0, 0, 4, 50, }, + { 2, 0, 0, 0, 4, 42, }, + { 1, 0, 0, 0, 4, 42, }, + { 0, 0, 0, 0, 5, 50, }, + { 2, 0, 0, 0, 5, 42, }, + { 1, 0, 0, 0, 5, 42, }, + { 0, 0, 0, 0, 6, 50, }, + { 2, 0, 0, 0, 6, 42, }, + { 1, 0, 0, 0, 6, 42, }, + { 0, 0, 0, 0, 7, 50, }, + { 2, 0, 0, 0, 7, 42, }, + { 1, 0, 0, 0, 7, 42, }, + { 0, 0, 0, 0, 8, 50, }, + { 2, 0, 0, 0, 8, 42, }, + { 1, 0, 0, 0, 8, 42, }, + { 0, 0, 0, 0, 9, 50, }, + { 2, 0, 0, 0, 9, 42, }, + { 1, 0, 0, 0, 9, 42, }, + { 0, 0, 0, 0, 10, 50, }, + { 2, 0, 0, 0, 10, 42, }, + { 1, 0, 0, 0, 10, 42, }, + { 0, 0, 0, 0, 11, 44, }, + { 2, 0, 0, 0, 11, 42, }, + { 1, 0, 0, 0, 11, 42, }, + { 0, 0, 0, 0, 12, 63, }, + { 2, 0, 0, 0, 12, 42, }, + { 1, 0, 0, 0, 12, 42, }, + { 0, 0, 0, 0, 13, 63, }, + { 2, 0, 0, 0, 13, 42, }, + { 1, 0, 0, 0, 13, 42, }, + { 0, 0, 0, 0, 14, 63, }, + { 2, 0, 0, 0, 14, 63, }, + { 1, 0, 0, 0, 14, 42, }, + { 0, 0, 0, 1, 1, 32, }, + { 2, 0, 0, 1, 1, 42, }, + { 1, 0, 0, 1, 1, 42, }, + { 0, 0, 0, 1, 2, 42, }, + { 2, 0, 0, 1, 2, 42, }, + { 1, 0, 0, 1, 2, 42, }, + { 0, 0, 0, 1, 3, 42, }, + { 2, 0, 0, 1, 3, 42, }, + { 1, 0, 0, 1, 3, 42, }, + { 0, 0, 0, 1, 4, 42, }, + { 2, 0, 0, 1, 4, 42, }, + { 1, 0, 0, 1, 4, 42, }, + { 0, 0, 0, 1, 5, 42, }, + { 2, 0, 0, 1, 5, 42, }, + { 1, 0, 0, 1, 5, 42, }, + { 0, 0, 0, 1, 6, 42, }, + { 2, 0, 0, 1, 6, 42, }, + { 1, 0, 0, 1, 6, 42, }, + { 0, 0, 0, 1, 7, 42, }, + { 2, 0, 0, 1, 7, 42, }, + { 1, 0, 0, 1, 7, 42, }, + { 0, 0, 0, 1, 8, 42, }, + { 2, 0, 0, 1, 8, 42, }, + { 1, 0, 0, 1, 8, 42, }, + { 0, 0, 0, 1, 9, 42, }, + { 2, 0, 0, 1, 9, 42, }, + { 1, 0, 0, 1, 9, 42, }, + { 0, 0, 0, 1, 10, 42, }, + { 2, 0, 0, 1, 10, 42, }, + { 1, 0, 0, 1, 10, 42, }, + { 0, 0, 0, 1, 11, 32, }, + { 2, 0, 0, 1, 11, 42, }, + { 1, 0, 0, 1, 11, 42, }, + { 0, 0, 0, 1, 12, 63, }, + { 2, 0, 0, 1, 12, 42, }, + { 1, 0, 0, 1, 12, 42, }, + { 0, 0, 0, 1, 13, 63, }, + { 2, 0, 0, 1, 13, 42, }, + { 1, 0, 0, 1, 13, 42, }, + { 0, 0, 0, 1, 14, 63, }, + { 2, 0, 0, 1, 14, 63, }, + { 1, 0, 0, 1, 14, 63, }, + { 0, 0, 0, 2, 1, 32, }, + { 2, 0, 0, 2, 1, 42, }, + { 1, 0, 0, 2, 1, 42, }, + { 0, 0, 0, 2, 2, 40, }, + { 2, 0, 0, 2, 2, 42, }, + { 1, 0, 0, 2, 2, 42, }, + { 0, 0, 0, 2, 3, 40, }, + { 2, 0, 0, 2, 3, 42, }, + { 1, 0, 0, 2, 3, 42, }, + { 0, 0, 0, 2, 4, 40, }, + { 2, 0, 0, 2, 4, 42, }, + { 1, 0, 0, 2, 4, 42, }, + { 0, 0, 0, 2, 5, 40, }, + { 2, 0, 0, 2, 5, 42, }, + { 1, 0, 0, 2, 5, 42, }, + { 0, 0, 0, 2, 6, 40, }, + { 2, 0, 0, 2, 6, 42, }, + { 1, 0, 0, 2, 6, 42, }, + { 0, 0, 0, 2, 7, 40, }, + { 2, 0, 0, 2, 7, 42, }, + { 1, 0, 0, 2, 7, 42, }, + { 0, 0, 0, 2, 8, 40, }, + { 2, 0, 0, 2, 8, 42, }, + { 1, 0, 0, 2, 8, 42, }, + { 0, 0, 0, 2, 9, 40, }, + { 2, 0, 0, 2, 9, 42, }, + { 1, 0, 0, 2, 9, 42, }, + { 0, 0, 0, 2, 10, 40, }, + { 2, 0, 0, 2, 10, 42, }, + { 1, 0, 0, 2, 10, 42, }, + { 0, 0, 0, 2, 11, 28, }, + { 2, 0, 0, 2, 11, 42, }, + { 1, 0, 0, 2, 11, 42, }, + { 0, 0, 0, 2, 12, 63, }, + { 2, 0, 0, 2, 12, 42, }, + { 1, 0, 0, 2, 12, 42, }, + { 0, 0, 0, 2, 13, 63, }, + { 2, 0, 0, 2, 13, 42, }, + { 1, 0, 0, 2, 13, 42, }, + { 0, 0, 0, 2, 14, 63, }, + { 2, 0, 0, 2, 14, 63, }, + { 1, 0, 0, 2, 14, 63, }, + { 0, 0, 0, 3, 1, 32, }, + { 2, 0, 0, 3, 1, 40, }, + { 1, 0, 0, 3, 1, 40, }, + { 0, 0, 0, 3, 2, 40, }, + { 2, 0, 0, 3, 2, 40, }, + { 1, 0, 0, 3, 2, 40, }, + { 0, 0, 0, 3, 3, 40, }, + { 2, 0, 0, 3, 3, 40, }, + { 1, 0, 0, 3, 3, 40, }, + { 0, 0, 0, 3, 4, 40, }, + { 2, 0, 0, 3, 4, 40, }, + { 1, 0, 0, 3, 4, 40, }, + { 0, 0, 0, 3, 5, 40, }, + { 2, 0, 0, 3, 5, 40, }, + { 1, 0, 0, 3, 5, 40, }, + { 0, 0, 0, 3, 6, 40, }, + { 2, 0, 0, 3, 6, 40, }, + { 1, 0, 0, 3, 6, 40, }, + { 0, 0, 0, 3, 7, 40, }, + { 2, 0, 0, 3, 7, 40, }, + { 1, 0, 0, 3, 7, 40, }, + { 0, 0, 0, 3, 8, 40, }, + { 2, 0, 0, 3, 8, 40, }, + { 1, 0, 0, 3, 8, 40, }, + { 0, 0, 0, 3, 9, 40, }, + { 2, 0, 0, 3, 9, 40, }, + { 1, 0, 0, 3, 9, 40, }, + { 0, 0, 0, 3, 10, 40, }, + { 2, 0, 0, 3, 10, 40, }, + { 1, 0, 0, 3, 10, 40, }, + { 0, 0, 0, 3, 11, 28, }, + { 2, 0, 0, 3, 11, 40, }, + { 1, 0, 0, 3, 11, 40, }, + { 0, 0, 0, 3, 12, 63, }, + { 2, 0, 0, 3, 12, 40, }, + { 1, 0, 0, 3, 12, 40, }, + { 0, 0, 0, 3, 13, 63, }, + { 2, 0, 0, 3, 13, 40, }, + { 1, 0, 0, 3, 13, 40, }, + { 0, 0, 0, 3, 14, 63, }, + { 2, 0, 0, 3, 14, 63, }, + { 1, 0, 0, 3, 14, 63, }, + { 0, 0, 0, 6, 1, 32, }, + { 2, 0, 0, 6, 1, 40, }, + { 1, 0, 0, 6, 1, 40, }, + { 0, 0, 0, 6, 2, 40, }, + { 2, 0, 0, 6, 2, 40, }, + { 1, 0, 0, 6, 2, 40, }, + { 0, 0, 0, 6, 3, 40, }, + { 2, 0, 0, 6, 3, 40, }, + { 1, 0, 0, 6, 3, 40, }, + { 0, 0, 0, 6, 4, 40, }, + { 2, 0, 0, 6, 4, 40, }, + { 1, 0, 0, 6, 4, 40, }, + { 0, 0, 0, 6, 5, 40, }, + { 2, 0, 0, 6, 5, 40, }, + { 1, 0, 0, 6, 5, 40, }, + { 0, 0, 0, 6, 6, 40, }, + { 2, 0, 0, 6, 6, 40, }, + { 1, 0, 0, 6, 6, 40, }, + { 0, 0, 0, 6, 7, 40, }, + { 2, 0, 0, 6, 7, 40, }, + { 1, 0, 0, 6, 7, 40, }, + { 0, 0, 0, 6, 8, 40, }, + { 2, 0, 0, 6, 8, 40, }, + { 1, 0, 0, 6, 8, 40, }, + { 0, 0, 0, 6, 9, 40, }, + { 2, 0, 0, 6, 9, 40, }, + { 1, 0, 0, 6, 9, 40, }, + { 0, 0, 0, 6, 10, 40, }, + { 2, 0, 0, 6, 10, 40, }, + { 1, 0, 0, 6, 10, 40, }, + { 0, 0, 0, 6, 11, 28, }, + { 2, 0, 0, 6, 11, 40, }, + { 1, 0, 0, 6, 11, 40, }, + { 0, 0, 0, 6, 12, 63, }, + { 2, 0, 0, 6, 12, 40, }, + { 1, 0, 0, 6, 12, 40, }, + { 0, 0, 0, 6, 13, 63, }, + { 2, 0, 0, 6, 13, 40, }, + { 1, 0, 0, 6, 13, 40, }, + { 0, 0, 0, 6, 14, 63, }, + { 2, 0, 0, 6, 14, 63, }, + { 1, 0, 0, 6, 14, 63, }, + { 0, 0, 0, 7, 1, 32, }, + { 2, 0, 0, 7, 1, 40, }, + { 1, 0, 0, 7, 1, 40, }, + { 0, 0, 0, 7, 2, 40, }, + { 2, 0, 0, 7, 2, 40, }, + { 1, 0, 0, 7, 2, 40, }, + { 0, 0, 0, 7, 3, 40, }, + { 2, 0, 0, 7, 3, 40, }, + { 1, 0, 0, 7, 3, 40, }, + { 0, 0, 0, 7, 4, 40, }, + { 2, 0, 0, 7, 4, 40, }, + { 1, 0, 0, 7, 4, 40, }, + { 0, 0, 0, 7, 5, 40, }, + { 2, 0, 0, 7, 5, 40, }, + { 1, 0, 0, 7, 5, 40, }, + { 0, 0, 0, 7, 6, 40, }, + { 2, 0, 0, 7, 6, 40, }, + { 1, 0, 0, 7, 6, 40, }, + { 0, 0, 0, 7, 7, 40, }, + { 2, 0, 0, 7, 7, 40, }, + { 1, 0, 0, 7, 7, 40, }, + { 0, 0, 0, 7, 8, 40, }, + { 2, 0, 0, 7, 8, 40, }, + { 1, 0, 0, 7, 8, 40, }, + { 0, 0, 0, 7, 9, 40, }, + { 2, 0, 0, 7, 9, 40, }, + { 1, 0, 0, 7, 9, 40, }, + { 0, 0, 0, 7, 10, 40, }, + { 2, 0, 0, 7, 10, 40, }, + { 1, 0, 0, 7, 10, 40, }, + { 0, 0, 0, 7, 11, 28, }, + { 2, 0, 0, 7, 11, 40, }, + { 1, 0, 0, 7, 11, 40, }, + { 0, 0, 0, 7, 12, 63, }, + { 2, 0, 0, 7, 12, 40, }, + { 1, 0, 0, 7, 12, 40, }, + { 0, 0, 0, 7, 13, 63, }, + { 2, 0, 0, 7, 13, 40, }, + { 1, 0, 0, 7, 13, 40, }, + { 0, 0, 0, 7, 14, 63, }, + { 2, 0, 0, 7, 14, 63, }, + { 1, 0, 0, 7, 14, 63, }, + { 0, 0, 1, 2, 1, 63, }, + { 2, 0, 1, 2, 1, 63, }, + { 1, 0, 1, 2, 1, 63, }, + { 0, 0, 1, 2, 2, 63, }, + { 2, 0, 1, 2, 2, 63, }, + { 1, 0, 1, 2, 2, 63, }, + { 0, 0, 1, 2, 3, 30, }, + { 2, 0, 1, 2, 3, 34, }, + { 1, 0, 1, 2, 3, 34, }, + { 0, 0, 1, 2, 4, 34, }, + { 2, 0, 1, 2, 4, 34, }, + { 1, 0, 1, 2, 4, 34, }, + { 0, 0, 1, 2, 5, 34, }, + { 2, 0, 1, 2, 5, 34, }, + { 1, 0, 1, 2, 5, 34, }, + { 0, 0, 1, 2, 6, 34, }, + { 2, 0, 1, 2, 6, 34, }, + { 1, 0, 1, 2, 6, 34, }, + { 0, 0, 1, 2, 7, 34, }, + { 2, 0, 1, 2, 7, 34, }, + { 1, 0, 1, 2, 7, 34, }, + { 0, 0, 1, 2, 8, 34, }, + { 2, 0, 1, 2, 8, 34, }, + { 1, 0, 1, 2, 8, 34, }, + { 0, 0, 1, 2, 9, 34, }, + { 2, 0, 1, 2, 9, 34, }, + { 1, 0, 1, 2, 9, 34, }, + { 0, 0, 1, 2, 10, 34, }, + { 2, 0, 1, 2, 10, 34, }, + { 1, 0, 1, 2, 10, 34, }, + { 0, 0, 1, 2, 11, 28, }, + { 2, 0, 1, 2, 11, 34, }, + { 1, 0, 1, 2, 11, 34, }, + { 0, 0, 1, 2, 12, 63, }, + { 2, 0, 1, 2, 12, 34, }, + { 1, 0, 1, 2, 12, 34, }, + { 0, 0, 1, 2, 13, 63, }, + { 2, 0, 1, 2, 13, 34, }, + { 1, 0, 1, 2, 13, 34, }, + { 0, 0, 1, 2, 14, 63, }, + { 2, 0, 1, 2, 14, 63, }, + { 1, 0, 1, 2, 14, 63, }, + { 0, 0, 1, 3, 1, 63, }, + { 2, 0, 1, 3, 1, 63, }, + { 1, 0, 1, 3, 1, 63, }, + { 0, 0, 1, 3, 2, 63, }, + { 2, 0, 1, 3, 2, 63, }, + { 1, 0, 1, 3, 2, 63, }, + { 0, 0, 1, 3, 3, 30, }, + { 2, 0, 1, 3, 3, 34, }, + { 1, 0, 1, 3, 3, 34, }, + { 0, 0, 1, 3, 4, 34, }, + { 2, 0, 1, 3, 4, 34, }, + { 1, 0, 1, 3, 4, 34, }, + { 0, 0, 1, 3, 5, 34, }, + { 2, 0, 1, 3, 5, 34, }, + { 1, 0, 1, 3, 5, 34, }, + { 0, 0, 1, 3, 6, 34, }, + { 2, 0, 1, 3, 6, 34, }, + { 1, 0, 1, 3, 6, 34, }, + { 0, 0, 1, 3, 7, 34, }, + { 2, 0, 1, 3, 7, 34, }, + { 1, 0, 1, 3, 7, 34, }, + { 0, 0, 1, 3, 8, 34, }, + { 2, 0, 1, 3, 8, 34, }, + { 1, 0, 1, 3, 8, 34, }, + { 0, 0, 1, 3, 9, 34, }, + { 2, 0, 1, 3, 9, 34, }, + { 1, 0, 1, 3, 9, 34, }, + { 0, 0, 1, 3, 10, 34, }, + { 2, 0, 1, 3, 10, 34, }, + { 1, 0, 1, 3, 10, 34, }, + { 0, 0, 1, 3, 11, 28, }, + { 2, 0, 1, 3, 11, 34, }, + { 1, 0, 1, 3, 11, 34, }, + { 0, 0, 1, 3, 12, 63, }, + { 2, 0, 1, 3, 12, 34, }, + { 1, 0, 1, 3, 12, 34, }, + { 0, 0, 1, 3, 13, 63, }, + { 2, 0, 1, 3, 13, 34, }, + { 1, 0, 1, 3, 13, 34, }, + { 0, 0, 1, 3, 14, 63, }, + { 2, 0, 1, 3, 14, 63, }, + { 1, 0, 1, 3, 14, 63, }, + { 0, 0, 1, 6, 1, 63, }, + { 2, 0, 1, 6, 1, 63, }, + { 1, 0, 1, 6, 1, 63, }, + { 0, 0, 1, 6, 2, 63, }, + { 2, 0, 1, 6, 2, 63, }, + { 1, 0, 1, 6, 2, 63, }, + { 0, 0, 1, 6, 3, 30, }, + { 2, 0, 1, 6, 3, 34, }, + { 1, 0, 1, 6, 3, 34, }, + { 0, 0, 1, 6, 4, 34, }, + { 2, 0, 1, 6, 4, 34, }, + { 1, 0, 1, 6, 4, 34, }, + { 0, 0, 1, 6, 5, 34, }, + { 2, 0, 1, 6, 5, 34, }, + { 1, 0, 1, 6, 5, 34, }, + { 0, 0, 1, 6, 6, 34, }, + { 2, 0, 1, 6, 6, 34, }, + { 1, 0, 1, 6, 6, 34, }, + { 0, 0, 1, 6, 7, 34, }, + { 2, 0, 1, 6, 7, 34, }, + { 1, 0, 1, 6, 7, 34, }, + { 0, 0, 1, 6, 8, 34, }, + { 2, 0, 1, 6, 8, 34, }, + { 1, 0, 1, 6, 8, 34, }, + { 0, 0, 1, 6, 9, 34, }, + { 2, 0, 1, 6, 9, 34, }, + { 1, 0, 1, 6, 9, 34, }, + { 0, 0, 1, 6, 10, 34, }, + { 2, 0, 1, 6, 10, 34, }, + { 1, 0, 1, 6, 10, 34, }, + { 0, 0, 1, 6, 11, 28, }, + { 2, 0, 1, 6, 11, 34, }, + { 1, 0, 1, 6, 11, 34, }, + { 0, 0, 1, 6, 12, 63, }, + { 2, 0, 1, 6, 12, 34, }, + { 1, 0, 1, 6, 12, 34, }, + { 0, 0, 1, 6, 13, 63, }, + { 2, 0, 1, 6, 13, 34, }, + { 1, 0, 1, 6, 13, 34, }, + { 0, 0, 1, 6, 14, 63, }, + { 2, 0, 1, 6, 14, 63, }, + { 1, 0, 1, 6, 14, 63, }, + { 0, 0, 1, 7, 1, 63, }, + { 2, 0, 1, 7, 1, 63, }, + { 1, 0, 1, 7, 1, 63, }, + { 0, 0, 1, 7, 2, 63, }, + { 2, 0, 1, 7, 2, 63, }, + { 1, 0, 1, 7, 2, 63, }, + { 0, 0, 1, 7, 3, 30, }, + { 2, 0, 1, 7, 3, 34, }, + { 1, 0, 1, 7, 3, 34, }, + { 0, 0, 1, 7, 4, 34, }, + { 2, 0, 1, 7, 4, 34, }, + { 1, 0, 1, 7, 4, 34, }, + { 0, 0, 1, 7, 5, 34, }, + { 2, 0, 1, 7, 5, 34, }, + { 1, 0, 1, 7, 5, 34, }, + { 0, 0, 1, 7, 6, 34, }, + { 2, 0, 1, 7, 6, 34, }, + { 1, 0, 1, 7, 6, 34, }, + { 0, 0, 1, 7, 7, 34, }, + { 2, 0, 1, 7, 7, 34, }, + { 1, 0, 1, 7, 7, 34, }, + { 0, 0, 1, 7, 8, 34, }, + { 2, 0, 1, 7, 8, 34, }, + { 1, 0, 1, 7, 8, 34, }, + { 0, 0, 1, 7, 9, 34, }, + { 2, 0, 1, 7, 9, 34, }, + { 1, 0, 1, 7, 9, 34, }, + { 0, 0, 1, 7, 10, 34, }, + { 2, 0, 1, 7, 10, 34, }, + { 1, 0, 1, 7, 10, 34, }, + { 0, 0, 1, 7, 11, 28, }, + { 2, 0, 1, 7, 11, 34, }, + { 1, 0, 1, 7, 11, 34, }, + { 0, 0, 1, 7, 12, 63, }, + { 2, 0, 1, 7, 12, 34, }, + { 1, 0, 1, 7, 12, 34, }, + { 0, 0, 1, 7, 13, 63, }, + { 2, 0, 1, 7, 13, 34, }, + { 1, 0, 1, 7, 13, 34, }, + { 0, 0, 1, 7, 14, 63, }, + { 2, 0, 1, 7, 14, 63, }, + { 1, 0, 1, 7, 14, 63, }, + { 0, 1, 0, 1, 36, 42, }, + { 2, 1, 0, 1, 36, 42, }, + { 1, 1, 0, 1, 36, 42, }, + { 0, 1, 0, 1, 40, 42, }, + { 2, 1, 0, 1, 40, 42, }, + { 1, 1, 0, 1, 40, 42, }, + { 0, 1, 0, 1, 44, 42, }, + { 2, 1, 0, 1, 44, 42, }, + { 1, 1, 0, 1, 44, 42, }, + { 0, 1, 0, 1, 48, 42, }, + { 2, 1, 0, 1, 48, 42, }, + { 1, 1, 0, 1, 48, 42, }, + { 0, 1, 0, 1, 52, 42, }, + { 2, 1, 0, 1, 52, 42, }, + { 1, 1, 0, 1, 52, 42, }, + { 0, 1, 0, 1, 56, 42, }, + { 2, 1, 0, 1, 56, 42, }, + { 1, 1, 0, 1, 56, 42, }, + { 0, 1, 0, 1, 60, 42, }, + { 2, 1, 0, 1, 60, 42, }, + { 1, 1, 0, 1, 60, 42, }, + { 0, 1, 0, 1, 64, 42, }, + { 2, 1, 0, 1, 64, 42, }, + { 1, 1, 0, 1, 64, 42, }, + { 0, 1, 0, 1, 100, 42, }, + { 2, 1, 0, 1, 100, 42, }, + { 1, 1, 0, 1, 100, 42, }, + { 0, 1, 0, 1, 104, 42, }, + { 2, 1, 0, 1, 104, 42, }, + { 1, 1, 0, 1, 104, 42, }, + { 0, 1, 0, 1, 108, 42, }, + { 2, 1, 0, 1, 108, 42, }, + { 1, 1, 0, 1, 108, 42, }, + { 0, 1, 0, 1, 112, 42, }, + { 2, 1, 0, 1, 112, 42, }, + { 1, 1, 0, 1, 112, 42, }, + { 0, 1, 0, 1, 116, 42, }, + { 2, 1, 0, 1, 116, 42, }, + { 1, 1, 0, 1, 116, 42, }, + { 0, 1, 0, 1, 120, 42, }, + { 2, 1, 0, 1, 120, 42, }, + { 1, 1, 0, 1, 120, 42, }, + { 0, 1, 0, 1, 124, 42, }, + { 2, 1, 0, 1, 124, 42, }, + { 1, 1, 0, 1, 124, 42, }, + { 0, 1, 0, 1, 128, 42, }, + { 2, 1, 0, 1, 128, 42, }, + { 1, 1, 0, 1, 128, 42, }, + { 0, 1, 0, 1, 132, 42, }, + { 2, 1, 0, 1, 132, 42, }, + { 1, 1, 0, 1, 132, 42, }, + { 0, 1, 0, 1, 136, 42, }, + { 2, 1, 0, 1, 136, 42, }, + { 1, 1, 0, 1, 136, 42, }, + { 0, 1, 0, 1, 140, 40, }, + { 2, 1, 0, 1, 140, 40, }, + { 1, 1, 0, 1, 140, 40, }, + { 0, 1, 0, 1, 149, 44, }, + { 2, 1, 0, 1, 149, 44, }, + { 1, 1, 0, 1, 149, 63, }, + { 0, 1, 0, 1, 153, 44, }, + { 2, 1, 0, 1, 153, 44, }, + { 1, 1, 0, 1, 153, 63, }, + { 0, 1, 0, 1, 157, 44, }, + { 2, 1, 0, 1, 157, 44, }, + { 1, 1, 0, 1, 157, 63, }, + { 0, 1, 0, 1, 161, 44, }, + { 2, 1, 0, 1, 161, 44, }, + { 1, 1, 0, 1, 161, 63, }, + { 0, 1, 0, 1, 165, 44, }, + { 2, 1, 0, 1, 165, 44, }, + { 1, 1, 0, 1, 165, 63, }, + { 0, 1, 0, 2, 36, 32, }, + { 2, 1, 0, 2, 36, 32, }, + { 1, 1, 0, 2, 36, 32, }, + { 0, 1, 0, 2, 40, 32, }, + { 2, 1, 0, 2, 40, 32, }, + { 1, 1, 0, 2, 40, 32, }, + { 0, 1, 0, 2, 44, 32, }, + { 2, 1, 0, 2, 44, 32, }, + { 1, 1, 0, 2, 44, 32, }, + { 0, 1, 0, 2, 48, 36, }, + { 2, 1, 0, 2, 48, 36, }, + { 1, 1, 0, 2, 48, 36, }, + { 0, 1, 0, 2, 52, 36, }, + { 2, 1, 0, 2, 52, 36, }, + { 1, 1, 0, 2, 52, 36, }, + { 0, 1, 0, 2, 56, 32, }, + { 2, 1, 0, 2, 56, 32, }, + { 1, 1, 0, 2, 56, 32, }, + { 0, 1, 0, 2, 60, 32, }, + { 2, 1, 0, 2, 60, 32, }, + { 1, 1, 0, 2, 60, 32, }, + { 0, 1, 0, 2, 64, 32, }, + { 2, 1, 0, 2, 64, 32, }, + { 1, 1, 0, 2, 64, 32, }, + { 0, 1, 0, 2, 100, 32, }, + { 2, 1, 0, 2, 100, 32, }, + { 1, 1, 0, 2, 100, 32, }, + { 0, 1, 0, 2, 104, 32, }, + { 2, 1, 0, 2, 104, 32, }, + { 1, 1, 0, 2, 104, 32, }, + { 0, 1, 0, 2, 108, 32, }, + { 2, 1, 0, 2, 108, 32, }, + { 1, 1, 0, 2, 108, 32, }, + { 0, 1, 0, 2, 112, 32, }, + { 2, 1, 0, 2, 112, 32, }, + { 1, 1, 0, 2, 112, 32, }, + { 0, 1, 0, 2, 116, 32, }, + { 2, 1, 0, 2, 116, 32, }, + { 1, 1, 0, 2, 116, 32, }, + { 0, 1, 0, 2, 120, 32, }, + { 2, 1, 0, 2, 120, 32, }, + { 1, 1, 0, 2, 120, 32, }, + { 0, 1, 0, 2, 124, 32, }, + { 2, 1, 0, 2, 124, 32, }, + { 1, 1, 0, 2, 124, 32, }, + { 0, 1, 0, 2, 128, 32, }, + { 2, 1, 0, 2, 128, 32, }, + { 1, 1, 0, 2, 128, 32, }, + { 0, 1, 0, 2, 132, 32, }, + { 2, 1, 0, 2, 132, 32, }, + { 1, 1, 0, 2, 132, 32, }, + { 0, 1, 0, 2, 136, 32, }, + { 2, 1, 0, 2, 136, 32, }, + { 1, 1, 0, 2, 136, 32, }, + { 0, 1, 0, 2, 140, 30, }, + { 2, 1, 0, 2, 140, 30, }, + { 1, 1, 0, 2, 140, 30, }, + { 0, 1, 0, 2, 149, 40, }, + { 2, 1, 0, 2, 149, 40, }, + { 1, 1, 0, 2, 149, 63, }, + { 0, 1, 0, 2, 153, 40, }, + { 2, 1, 0, 2, 153, 40, }, + { 1, 1, 0, 2, 153, 63, }, + { 0, 1, 0, 2, 157, 40, }, + { 2, 1, 0, 2, 157, 40, }, + { 1, 1, 0, 2, 157, 63, }, + { 0, 1, 0, 2, 161, 40, }, + { 2, 1, 0, 2, 161, 40, }, + { 1, 1, 0, 2, 161, 63, }, + { 0, 1, 0, 2, 165, 42, }, + { 2, 1, 0, 2, 165, 42, }, + { 1, 1, 0, 2, 165, 63, }, + { 0, 1, 0, 3, 36, 32, }, + { 2, 1, 0, 3, 36, 32, }, + { 1, 1, 0, 3, 36, 32, }, + { 0, 1, 0, 3, 40, 32, }, + { 2, 1, 0, 3, 40, 32, }, + { 1, 1, 0, 3, 40, 32, }, + { 0, 1, 0, 3, 44, 32, }, + { 2, 1, 0, 3, 44, 32, }, + { 1, 1, 0, 3, 44, 32, }, + { 0, 1, 0, 3, 48, 36, }, + { 2, 1, 0, 3, 48, 36, }, + { 1, 1, 0, 3, 48, 36, }, + { 0, 1, 0, 3, 52, 36, }, + { 2, 1, 0, 3, 52, 36, }, + { 1, 1, 0, 3, 52, 36, }, + { 0, 1, 0, 3, 56, 32, }, + { 2, 1, 0, 3, 56, 32, }, + { 1, 1, 0, 3, 56, 32, }, + { 0, 1, 0, 3, 60, 32, }, + { 2, 1, 0, 3, 60, 32, }, + { 1, 1, 0, 3, 60, 32, }, + { 0, 1, 0, 3, 64, 32, }, + { 2, 1, 0, 3, 64, 32, }, + { 1, 1, 0, 3, 64, 32, }, + { 0, 1, 0, 3, 100, 32, }, + { 2, 1, 0, 3, 100, 32, }, + { 1, 1, 0, 3, 100, 32, }, + { 0, 1, 0, 3, 104, 32, }, + { 2, 1, 0, 3, 104, 32, }, + { 1, 1, 0, 3, 104, 32, }, + { 0, 1, 0, 3, 108, 32, }, + { 2, 1, 0, 3, 108, 32, }, + { 1, 1, 0, 3, 108, 32, }, + { 0, 1, 0, 3, 112, 32, }, + { 2, 1, 0, 3, 112, 32, }, + { 1, 1, 0, 3, 112, 32, }, + { 0, 1, 0, 3, 116, 32, }, + { 2, 1, 0, 3, 116, 32, }, + { 1, 1, 0, 3, 116, 32, }, + { 0, 1, 0, 3, 120, 32, }, + { 2, 1, 0, 3, 120, 32, }, + { 1, 1, 0, 3, 120, 32, }, + { 0, 1, 0, 3, 124, 32, }, + { 2, 1, 0, 3, 124, 32, }, + { 1, 1, 0, 3, 124, 32, }, + { 0, 1, 0, 3, 128, 32, }, + { 2, 1, 0, 3, 128, 32, }, + { 1, 1, 0, 3, 128, 32, }, + { 0, 1, 0, 3, 132, 32, }, + { 2, 1, 0, 3, 132, 32, }, + { 1, 1, 0, 3, 132, 32, }, + { 0, 1, 0, 3, 136, 32, }, + { 2, 1, 0, 3, 136, 32, }, + { 1, 1, 0, 3, 136, 32, }, + { 0, 1, 0, 3, 140, 30, }, + { 2, 1, 0, 3, 140, 30, }, + { 1, 1, 0, 3, 140, 30, }, + { 0, 1, 0, 3, 149, 40, }, + { 2, 1, 0, 3, 149, 40, }, + { 1, 1, 0, 3, 149, 63, }, + { 0, 1, 0, 3, 153, 40, }, + { 2, 1, 0, 3, 153, 40, }, + { 1, 1, 0, 3, 153, 63, }, + { 0, 1, 0, 3, 157, 40, }, + { 2, 1, 0, 3, 157, 40, }, + { 1, 1, 0, 3, 157, 63, }, + { 0, 1, 0, 3, 161, 40, }, + { 2, 1, 0, 3, 161, 40, }, + { 1, 1, 0, 3, 161, 63, }, + { 0, 1, 0, 3, 165, 42, }, + { 2, 1, 0, 3, 165, 42, }, + { 1, 1, 0, 3, 165, 63, }, + { 0, 1, 0, 6, 36, 32, }, + { 2, 1, 0, 6, 36, 32, }, + { 1, 1, 0, 6, 36, 32, }, + { 0, 1, 0, 6, 40, 32, }, + { 2, 1, 0, 6, 40, 32, }, + { 1, 1, 0, 6, 40, 32, }, + { 0, 1, 0, 6, 44, 32, }, + { 2, 1, 0, 6, 44, 32, }, + { 1, 1, 0, 6, 44, 32, }, + { 0, 1, 0, 6, 48, 36, }, + { 2, 1, 0, 6, 48, 36, }, + { 1, 1, 0, 6, 48, 36, }, + { 0, 1, 0, 6, 52, 36, }, + { 2, 1, 0, 6, 52, 36, }, + { 1, 1, 0, 6, 52, 36, }, + { 0, 1, 0, 6, 56, 32, }, + { 2, 1, 0, 6, 56, 32, }, + { 1, 1, 0, 6, 56, 32, }, + { 0, 1, 0, 6, 60, 32, }, + { 2, 1, 0, 6, 60, 32, }, + { 1, 1, 0, 6, 60, 32, }, + { 0, 1, 0, 6, 64, 32, }, + { 2, 1, 0, 6, 64, 32, }, + { 1, 1, 0, 6, 64, 32, }, + { 0, 1, 0, 6, 100, 32, }, + { 2, 1, 0, 6, 100, 32, }, + { 1, 1, 0, 6, 100, 32, }, + { 0, 1, 0, 6, 104, 32, }, + { 2, 1, 0, 6, 104, 32, }, + { 1, 1, 0, 6, 104, 32, }, + { 0, 1, 0, 6, 108, 32, }, + { 2, 1, 0, 6, 108, 32, }, + { 1, 1, 0, 6, 108, 32, }, + { 0, 1, 0, 6, 112, 32, }, + { 2, 1, 0, 6, 112, 32, }, + { 1, 1, 0, 6, 112, 32, }, + { 0, 1, 0, 6, 116, 32, }, + { 2, 1, 0, 6, 116, 32, }, + { 1, 1, 0, 6, 116, 32, }, + { 0, 1, 0, 6, 120, 32, }, + { 2, 1, 0, 6, 120, 32, }, + { 1, 1, 0, 6, 120, 32, }, + { 0, 1, 0, 6, 124, 32, }, + { 2, 1, 0, 6, 124, 32, }, + { 1, 1, 0, 6, 124, 32, }, + { 0, 1, 0, 6, 128, 32, }, + { 2, 1, 0, 6, 128, 32, }, + { 1, 1, 0, 6, 128, 32, }, + { 0, 1, 0, 6, 132, 32, }, + { 2, 1, 0, 6, 132, 32, }, + { 1, 1, 0, 6, 132, 32, }, + { 0, 1, 0, 6, 136, 32, }, + { 2, 1, 0, 6, 136, 32, }, + { 1, 1, 0, 6, 136, 32, }, + { 0, 1, 0, 6, 140, 30, }, + { 2, 1, 0, 6, 140, 30, }, + { 1, 1, 0, 6, 140, 30, }, + { 0, 1, 0, 6, 149, 40, }, + { 2, 1, 0, 6, 149, 40, }, + { 1, 1, 0, 6, 149, 63, }, + { 0, 1, 0, 6, 153, 40, }, + { 2, 1, 0, 6, 153, 40, }, + { 1, 1, 0, 6, 153, 63, }, + { 0, 1, 0, 6, 157, 40, }, + { 2, 1, 0, 6, 157, 40, }, + { 1, 1, 0, 6, 157, 63, }, + { 0, 1, 0, 6, 161, 40, }, + { 2, 1, 0, 6, 161, 40, }, + { 1, 1, 0, 6, 161, 63, }, + { 0, 1, 0, 6, 165, 42, }, + { 2, 1, 0, 6, 165, 42, }, + { 1, 1, 0, 6, 165, 63, }, + { 0, 1, 0, 7, 36, 32, }, + { 2, 1, 0, 7, 36, 32, }, + { 1, 1, 0, 7, 36, 32, }, + { 0, 1, 0, 7, 40, 32, }, + { 2, 1, 0, 7, 40, 32, }, + { 1, 1, 0, 7, 40, 32, }, + { 0, 1, 0, 7, 44, 32, }, + { 2, 1, 0, 7, 44, 32, }, + { 1, 1, 0, 7, 44, 32, }, + { 0, 1, 0, 7, 48, 36, }, + { 2, 1, 0, 7, 48, 36, }, + { 1, 1, 0, 7, 48, 36, }, + { 0, 1, 0, 7, 52, 36, }, + { 2, 1, 0, 7, 52, 36, }, + { 1, 1, 0, 7, 52, 36, }, + { 0, 1, 0, 7, 56, 32, }, + { 2, 1, 0, 7, 56, 32, }, + { 1, 1, 0, 7, 56, 32, }, + { 0, 1, 0, 7, 60, 32, }, + { 2, 1, 0, 7, 60, 32, }, + { 1, 1, 0, 7, 60, 32, }, + { 0, 1, 0, 7, 64, 32, }, + { 2, 1, 0, 7, 64, 32, }, + { 1, 1, 0, 7, 64, 32, }, + { 0, 1, 0, 7, 100, 32, }, + { 2, 1, 0, 7, 100, 32, }, + { 1, 1, 0, 7, 100, 32, }, + { 0, 1, 0, 7, 104, 32, }, + { 2, 1, 0, 7, 104, 32, }, + { 1, 1, 0, 7, 104, 32, }, + { 0, 1, 0, 7, 108, 32, }, + { 2, 1, 0, 7, 108, 32, }, + { 1, 1, 0, 7, 108, 32, }, + { 0, 1, 0, 7, 112, 32, }, + { 2, 1, 0, 7, 112, 32, }, + { 1, 1, 0, 7, 112, 32, }, + { 0, 1, 0, 7, 116, 32, }, + { 2, 1, 0, 7, 116, 32, }, + { 1, 1, 0, 7, 116, 32, }, + { 0, 1, 0, 7, 120, 32, }, + { 2, 1, 0, 7, 120, 32, }, + { 1, 1, 0, 7, 120, 32, }, + { 0, 1, 0, 7, 124, 32, }, + { 2, 1, 0, 7, 124, 32, }, + { 1, 1, 0, 7, 124, 32, }, + { 0, 1, 0, 7, 128, 32, }, + { 2, 1, 0, 7, 128, 32, }, + { 1, 1, 0, 7, 128, 32, }, + { 0, 1, 0, 7, 132, 32, }, + { 2, 1, 0, 7, 132, 32, }, + { 1, 1, 0, 7, 132, 32, }, + { 0, 1, 0, 7, 136, 32, }, + { 2, 1, 0, 7, 136, 32, }, + { 1, 1, 0, 7, 136, 32, }, + { 0, 1, 0, 7, 140, 30, }, + { 2, 1, 0, 7, 140, 30, }, + { 1, 1, 0, 7, 140, 30, }, + { 0, 1, 0, 7, 149, 40, }, + { 2, 1, 0, 7, 149, 40, }, + { 1, 1, 0, 7, 149, 63, }, + { 0, 1, 0, 7, 153, 40, }, + { 2, 1, 0, 7, 153, 40, }, + { 1, 1, 0, 7, 153, 63, }, + { 0, 1, 0, 7, 157, 40, }, + { 2, 1, 0, 7, 157, 40, }, + { 1, 1, 0, 7, 157, 63, }, + { 0, 1, 0, 7, 161, 40, }, + { 2, 1, 0, 7, 161, 40, }, + { 1, 1, 0, 7, 161, 63, }, + { 0, 1, 0, 7, 165, 42, }, + { 2, 1, 0, 7, 165, 42, }, + { 1, 1, 0, 7, 165, 63, }, + { 0, 1, 1, 2, 38, 32, }, + { 2, 1, 1, 2, 38, 32, }, + { 1, 1, 1, 2, 38, 32, }, + { 0, 1, 1, 2, 46, 36, }, + { 2, 1, 1, 2, 46, 36, }, + { 1, 1, 1, 2, 46, 36, }, + { 0, 1, 1, 2, 54, 36, }, + { 2, 1, 1, 2, 54, 36, }, + { 1, 1, 1, 2, 54, 36, }, + { 0, 1, 1, 2, 62, 32, }, + { 2, 1, 1, 2, 62, 32, }, + { 1, 1, 1, 2, 62, 32, }, + { 0, 1, 1, 2, 102, 30, }, + { 2, 1, 1, 2, 102, 30, }, + { 1, 1, 1, 2, 102, 30, }, + { 0, 1, 1, 2, 110, 32, }, + { 2, 1, 1, 2, 110, 32, }, + { 1, 1, 1, 2, 110, 32, }, + { 0, 1, 1, 2, 118, 32, }, + { 2, 1, 1, 2, 118, 32, }, + { 1, 1, 1, 2, 118, 32, }, + { 0, 1, 1, 2, 126, 32, }, + { 2, 1, 1, 2, 126, 32, }, + { 1, 1, 1, 2, 126, 32, }, + { 0, 1, 1, 2, 134, 36, }, + { 2, 1, 1, 2, 134, 36, }, + { 1, 1, 1, 2, 134, 36, }, + { 0, 1, 1, 2, 151, 36, }, + { 2, 1, 1, 2, 151, 36, }, + { 1, 1, 1, 2, 151, 63, }, + { 0, 1, 1, 2, 159, 40, }, + { 2, 1, 1, 2, 159, 40, }, + { 1, 1, 1, 2, 159, 63, }, + { 0, 1, 1, 3, 38, 32, }, + { 2, 1, 1, 3, 38, 32, }, + { 1, 1, 1, 3, 38, 32, }, + { 0, 1, 1, 3, 46, 36, }, + { 2, 1, 1, 3, 46, 36, }, + { 1, 1, 1, 3, 46, 36, }, + { 0, 1, 1, 3, 54, 36, }, + { 2, 1, 1, 3, 54, 36, }, + { 1, 1, 1, 3, 54, 36, }, + { 0, 1, 1, 3, 62, 32, }, + { 2, 1, 1, 3, 62, 32, }, + { 1, 1, 1, 3, 62, 32, }, + { 0, 1, 1, 3, 102, 30, }, + { 2, 1, 1, 3, 102, 30, }, + { 1, 1, 1, 3, 102, 30, }, + { 0, 1, 1, 3, 110, 32, }, + { 2, 1, 1, 3, 110, 32, }, + { 1, 1, 1, 3, 110, 32, }, + { 0, 1, 1, 3, 118, 32, }, + { 2, 1, 1, 3, 118, 32, }, + { 1, 1, 1, 3, 118, 32, }, + { 0, 1, 1, 3, 126, 32, }, + { 2, 1, 1, 3, 126, 32, }, + { 1, 1, 1, 3, 126, 32, }, + { 0, 1, 1, 3, 134, 36, }, + { 2, 1, 1, 3, 134, 36, }, + { 1, 1, 1, 3, 134, 36, }, + { 0, 1, 1, 3, 151, 36, }, + { 2, 1, 1, 3, 151, 36, }, + { 1, 1, 1, 3, 151, 63, }, + { 0, 1, 1, 3, 159, 40, }, + { 2, 1, 1, 3, 159, 40, }, + { 1, 1, 1, 3, 159, 63, }, + { 0, 1, 1, 6, 38, 32, }, + { 2, 1, 1, 6, 38, 32, }, + { 1, 1, 1, 6, 38, 32, }, + { 0, 1, 1, 6, 46, 36, }, + { 2, 1, 1, 6, 46, 36, }, + { 1, 1, 1, 6, 46, 36, }, + { 0, 1, 1, 6, 54, 36, }, + { 2, 1, 1, 6, 54, 36, }, + { 1, 1, 1, 6, 54, 36, }, + { 0, 1, 1, 6, 62, 32, }, + { 2, 1, 1, 6, 62, 32, }, + { 1, 1, 1, 6, 62, 32, }, + { 0, 1, 1, 6, 102, 30, }, + { 2, 1, 1, 6, 102, 30, }, + { 1, 1, 1, 6, 102, 30, }, + { 0, 1, 1, 6, 110, 32, }, + { 2, 1, 1, 6, 110, 32, }, + { 1, 1, 1, 6, 110, 32, }, + { 0, 1, 1, 6, 118, 32, }, + { 2, 1, 1, 6, 118, 32, }, + { 1, 1, 1, 6, 118, 32, }, + { 0, 1, 1, 6, 126, 32, }, + { 2, 1, 1, 6, 126, 32, }, + { 1, 1, 1, 6, 126, 32, }, + { 0, 1, 1, 6, 134, 36, }, + { 2, 1, 1, 6, 134, 36, }, + { 1, 1, 1, 6, 134, 36, }, + { 0, 1, 1, 6, 151, 36, }, + { 2, 1, 1, 6, 151, 36, }, + { 1, 1, 1, 6, 151, 63, }, + { 0, 1, 1, 6, 159, 40, }, + { 2, 1, 1, 6, 159, 40, }, + { 1, 1, 1, 6, 159, 63, }, + { 0, 1, 1, 7, 38, 32, }, + { 2, 1, 1, 7, 38, 32, }, + { 1, 1, 1, 7, 38, 32, }, + { 0, 1, 1, 7, 46, 36, }, + { 2, 1, 1, 7, 46, 36, }, + { 1, 1, 1, 7, 46, 36, }, + { 0, 1, 1, 7, 54, 36, }, + { 2, 1, 1, 7, 54, 36, }, + { 1, 1, 1, 7, 54, 36, }, + { 0, 1, 1, 7, 62, 32, }, + { 2, 1, 1, 7, 62, 32, }, + { 1, 1, 1, 7, 62, 32, }, + { 0, 1, 1, 7, 102, 30, }, + { 2, 1, 1, 7, 102, 30, }, + { 1, 1, 1, 7, 102, 30, }, + { 0, 1, 1, 7, 110, 32, }, + { 2, 1, 1, 7, 110, 32, }, + { 1, 1, 1, 7, 110, 32, }, + { 0, 1, 1, 7, 118, 32, }, + { 2, 1, 1, 7, 118, 32, }, + { 1, 1, 1, 7, 118, 32, }, + { 0, 1, 1, 7, 126, 32, }, + { 2, 1, 1, 7, 126, 32, }, + { 1, 1, 1, 7, 126, 32, }, + { 0, 1, 1, 7, 134, 36, }, + { 2, 1, 1, 7, 134, 36, }, + { 1, 1, 1, 7, 134, 36, }, + { 0, 1, 1, 7, 151, 36, }, + { 2, 1, 1, 7, 151, 36, }, + { 1, 1, 1, 7, 151, 63, }, + { 0, 1, 1, 7, 159, 40, }, + { 2, 1, 1, 7, 159, 40, }, + { 1, 1, 1, 7, 159, 63, }, + { 0, 1, 2, 4, 42, 34, }, + { 2, 1, 2, 4, 42, 34, }, + { 1, 1, 2, 4, 42, 34, }, + { 0, 1, 2, 4, 58, 34, }, + { 2, 1, 2, 4, 58, 34, }, + { 1, 1, 2, 4, 58, 34, }, + { 0, 1, 2, 4, 106, 32, }, + { 2, 1, 2, 4, 106, 32, }, + { 1, 1, 2, 4, 106, 32, }, + { 0, 1, 2, 4, 122, 34, }, + { 2, 1, 2, 4, 122, 34, }, + { 1, 1, 2, 4, 122, 34, }, + { 0, 1, 2, 4, 155, 34, }, + { 2, 1, 2, 4, 155, 34, }, + { 1, 1, 2, 4, 155, 63, }, + { 0, 1, 2, 5, 42, 34, }, + { 2, 1, 2, 5, 42, 34, }, + { 1, 1, 2, 5, 42, 34, }, + { 0, 1, 2, 5, 58, 34, }, + { 2, 1, 2, 5, 58, 34, }, + { 1, 1, 2, 5, 58, 34, }, + { 0, 1, 2, 5, 106, 32, }, + { 2, 1, 2, 5, 106, 32, }, + { 1, 1, 2, 5, 106, 32, }, + { 0, 1, 2, 5, 122, 34, }, + { 2, 1, 2, 5, 122, 34, }, + { 1, 1, 2, 5, 122, 34, }, + { 0, 1, 2, 5, 155, 34, }, + { 2, 1, 2, 5, 155, 34, }, + { 1, 1, 2, 5, 155, 63, }, + { 0, 1, 2, 8, 42, 34, }, + { 2, 1, 2, 8, 42, 34, }, + { 1, 1, 2, 8, 42, 34, }, + { 0, 1, 2, 8, 58, 34, }, + { 2, 1, 2, 8, 58, 34, }, + { 1, 1, 2, 8, 58, 34, }, + { 0, 1, 2, 8, 106, 32, }, + { 2, 1, 2, 8, 106, 32, }, + { 1, 1, 2, 8, 106, 32, }, + { 0, 1, 2, 8, 122, 34, }, + { 2, 1, 2, 8, 122, 34, }, + { 1, 1, 2, 8, 122, 34, }, + { 0, 1, 2, 8, 155, 34, }, + { 2, 1, 2, 8, 155, 34, }, + { 1, 1, 2, 8, 155, 63, }, + { 0, 1, 2, 9, 42, 34, }, + { 2, 1, 2, 9, 42, 34, }, + { 1, 1, 2, 9, 42, 34, }, + { 0, 1, 2, 9, 58, 34, }, + { 2, 1, 2, 9, 58, 34, }, + { 1, 1, 2, 9, 58, 34, }, + { 0, 1, 2, 9, 106, 32, }, + { 2, 1, 2, 9, 106, 32, }, + { 1, 1, 2, 9, 106, 32, }, + { 0, 1, 2, 9, 122, 34, }, + { 2, 1, 2, 9, 122, 34, }, + { 1, 1, 2, 9, 122, 34, }, + { 0, 1, 2, 9, 155, 34, }, + { 2, 1, 2, 9, 155, 34, }, + { 1, 1, 2, 9, 155, 63, }, +}; + +RTW_DECL_TABLE_TXPWR_LMT(rtw8814a_txpwr_lmt_type2); + +static const struct rtw_txpwr_lmt_cfg_pair rtw8814a_txpwr_lmt_type3[] = { + { 0, 0, 0, 0, 1, 46, }, + { 2, 0, 0, 0, 1, 40, }, + { 1, 0, 0, 0, 1, 40, }, + { 0, 0, 0, 0, 2, 46, }, + { 2, 0, 0, 0, 2, 40, }, + { 1, 0, 0, 0, 2, 40, }, + { 0, 0, 0, 0, 3, 46, }, + { 2, 0, 0, 0, 3, 40, }, + { 1, 0, 0, 0, 3, 40, }, + { 0, 0, 0, 0, 4, 46, }, + { 2, 0, 0, 0, 4, 40, }, + { 1, 0, 0, 0, 4, 40, }, + { 0, 0, 0, 0, 5, 46, }, + { 2, 0, 0, 0, 5, 40, }, + { 1, 0, 0, 0, 5, 40, }, + { 0, 0, 0, 0, 6, 46, }, + { 2, 0, 0, 0, 6, 40, }, + { 1, 0, 0, 0, 6, 40, }, + { 0, 0, 0, 0, 7, 46, }, + { 2, 0, 0, 0, 7, 40, }, + { 1, 0, 0, 0, 7, 40, }, + { 0, 0, 0, 0, 8, 46, }, + { 2, 0, 0, 0, 8, 40, }, + { 1, 0, 0, 0, 8, 40, }, + { 0, 0, 0, 0, 9, 46, }, + { 2, 0, 0, 0, 9, 40, }, + { 1, 0, 0, 0, 9, 40, }, + { 0, 0, 0, 0, 10, 46, }, + { 2, 0, 0, 0, 10, 40, }, + { 1, 0, 0, 0, 10, 40, }, + { 0, 0, 0, 0, 11, 46, }, + { 2, 0, 0, 0, 11, 40, }, + { 1, 0, 0, 0, 11, 40, }, + { 0, 0, 0, 0, 12, 63, }, + { 2, 0, 0, 0, 12, 40, }, + { 1, 0, 0, 0, 12, 40, }, + { 0, 0, 0, 0, 13, 63, }, + { 2, 0, 0, 0, 13, 40, }, + { 1, 0, 0, 0, 13, 40, }, + { 0, 0, 0, 0, 14, 63, }, + { 2, 0, 0, 0, 14, 63, }, + { 1, 0, 0, 0, 14, 40, }, + { 0, 0, 0, 1, 1, 46, }, + { 2, 0, 0, 1, 1, 40, }, + { 1, 0, 0, 1, 1, 40, }, + { 0, 0, 0, 1, 2, 46, }, + { 2, 0, 0, 1, 2, 40, }, + { 1, 0, 0, 1, 2, 40, }, + { 0, 0, 0, 1, 3, 46, }, + { 2, 0, 0, 1, 3, 40, }, + { 1, 0, 0, 1, 3, 40, }, + { 0, 0, 0, 1, 4, 46, }, + { 2, 0, 0, 1, 4, 40, }, + { 1, 0, 0, 1, 4, 40, }, + { 0, 0, 0, 1, 5, 46, }, + { 2, 0, 0, 1, 5, 40, }, + { 1, 0, 0, 1, 5, 40, }, + { 0, 0, 0, 1, 6, 46, }, + { 2, 0, 0, 1, 6, 40, }, + { 1, 0, 0, 1, 6, 40, }, + { 0, 0, 0, 1, 7, 46, }, + { 2, 0, 0, 1, 7, 40, }, + { 1, 0, 0, 1, 7, 40, }, + { 0, 0, 0, 1, 8, 46, }, + { 2, 0, 0, 1, 8, 40, }, + { 1, 0, 0, 1, 8, 40, }, + { 0, 0, 0, 1, 9, 46, }, + { 2, 0, 0, 1, 9, 40, }, + { 1, 0, 0, 1, 9, 40, }, + { 0, 0, 0, 1, 10, 46, }, + { 2, 0, 0, 1, 10, 40, }, + { 1, 0, 0, 1, 10, 40, }, + { 0, 0, 0, 1, 11, 46, }, + { 2, 0, 0, 1, 11, 40, }, + { 1, 0, 0, 1, 11, 40, }, + { 0, 0, 0, 1, 12, 63, }, + { 2, 0, 0, 1, 12, 40, }, + { 1, 0, 0, 1, 12, 40, }, + { 0, 0, 0, 1, 13, 63, }, + { 2, 0, 0, 1, 13, 40, }, + { 1, 0, 0, 1, 13, 40, }, + { 0, 0, 0, 1, 14, 63, }, + { 2, 0, 0, 1, 14, 63, }, + { 1, 0, 0, 1, 14, 63, }, + { 0, 0, 0, 2, 1, 46, }, + { 2, 0, 0, 2, 1, 40, }, + { 1, 0, 0, 2, 1, 40, }, + { 0, 0, 0, 2, 2, 46, }, + { 2, 0, 0, 2, 2, 40, }, + { 1, 0, 0, 2, 2, 40, }, + { 0, 0, 0, 2, 3, 46, }, + { 2, 0, 0, 2, 3, 40, }, + { 1, 0, 0, 2, 3, 40, }, + { 0, 0, 0, 2, 4, 46, }, + { 2, 0, 0, 2, 4, 40, }, + { 1, 0, 0, 2, 4, 40, }, + { 0, 0, 0, 2, 5, 46, }, + { 2, 0, 0, 2, 5, 40, }, + { 1, 0, 0, 2, 5, 40, }, + { 0, 0, 0, 2, 6, 46, }, + { 2, 0, 0, 2, 6, 40, }, + { 1, 0, 0, 2, 6, 40, }, + { 0, 0, 0, 2, 7, 46, }, + { 2, 0, 0, 2, 7, 40, }, + { 1, 0, 0, 2, 7, 40, }, + { 0, 0, 0, 2, 8, 46, }, + { 2, 0, 0, 2, 8, 40, }, + { 1, 0, 0, 2, 8, 40, }, + { 0, 0, 0, 2, 9, 46, }, + { 2, 0, 0, 2, 9, 40, }, + { 1, 0, 0, 2, 9, 40, }, + { 0, 0, 0, 2, 10, 46, }, + { 2, 0, 0, 2, 10, 40, }, + { 1, 0, 0, 2, 10, 40, }, + { 0, 0, 0, 2, 11, 46, }, + { 2, 0, 0, 2, 11, 40, }, + { 1, 0, 0, 2, 11, 40, }, + { 0, 0, 0, 2, 12, 63, }, + { 2, 0, 0, 2, 12, 40, }, + { 1, 0, 0, 2, 12, 40, }, + { 0, 0, 0, 2, 13, 63, }, + { 2, 0, 0, 2, 13, 40, }, + { 1, 0, 0, 2, 13, 40, }, + { 0, 0, 0, 2, 14, 63, }, + { 2, 0, 0, 2, 14, 63, }, + { 1, 0, 0, 2, 14, 63, }, + { 0, 0, 0, 3, 1, 46, }, + { 2, 0, 0, 3, 1, 40, }, + { 1, 0, 0, 3, 1, 40, }, + { 0, 0, 0, 3, 2, 46, }, + { 2, 0, 0, 3, 2, 40, }, + { 1, 0, 0, 3, 2, 40, }, + { 0, 0, 0, 3, 3, 46, }, + { 2, 0, 0, 3, 3, 40, }, + { 1, 0, 0, 3, 3, 40, }, + { 0, 0, 0, 3, 4, 46, }, + { 2, 0, 0, 3, 4, 40, }, + { 1, 0, 0, 3, 4, 40, }, + { 0, 0, 0, 3, 5, 46, }, + { 2, 0, 0, 3, 5, 40, }, + { 1, 0, 0, 3, 5, 40, }, + { 0, 0, 0, 3, 6, 46, }, + { 2, 0, 0, 3, 6, 40, }, + { 1, 0, 0, 3, 6, 40, }, + { 0, 0, 0, 3, 7, 46, }, + { 2, 0, 0, 3, 7, 40, }, + { 1, 0, 0, 3, 7, 40, }, + { 0, 0, 0, 3, 8, 46, }, + { 2, 0, 0, 3, 8, 40, }, + { 1, 0, 0, 3, 8, 40, }, + { 0, 0, 0, 3, 9, 46, }, + { 2, 0, 0, 3, 9, 40, }, + { 1, 0, 0, 3, 9, 40, }, + { 0, 0, 0, 3, 10, 46, }, + { 2, 0, 0, 3, 10, 40, }, + { 1, 0, 0, 3, 10, 40, }, + { 0, 0, 0, 3, 11, 46, }, + { 2, 0, 0, 3, 11, 40, }, + { 1, 0, 0, 3, 11, 40, }, + { 0, 0, 0, 3, 12, 63, }, + { 2, 0, 0, 3, 12, 40, }, + { 1, 0, 0, 3, 12, 40, }, + { 0, 0, 0, 3, 13, 63, }, + { 2, 0, 0, 3, 13, 40, }, + { 1, 0, 0, 3, 13, 40, }, + { 0, 0, 0, 3, 14, 63, }, + { 2, 0, 0, 3, 14, 63, }, + { 1, 0, 0, 3, 14, 63, }, + { 0, 0, 0, 6, 1, 46, }, + { 2, 0, 0, 6, 1, 40, }, + { 1, 0, 0, 6, 1, 40, }, + { 0, 0, 0, 6, 2, 46, }, + { 2, 0, 0, 6, 2, 40, }, + { 1, 0, 0, 6, 2, 40, }, + { 0, 0, 0, 6, 3, 46, }, + { 2, 0, 0, 6, 3, 40, }, + { 1, 0, 0, 6, 3, 40, }, + { 0, 0, 0, 6, 4, 46, }, + { 2, 0, 0, 6, 4, 40, }, + { 1, 0, 0, 6, 4, 40, }, + { 0, 0, 0, 6, 5, 46, }, + { 2, 0, 0, 6, 5, 40, }, + { 1, 0, 0, 6, 5, 40, }, + { 0, 0, 0, 6, 6, 46, }, + { 2, 0, 0, 6, 6, 40, }, + { 1, 0, 0, 6, 6, 40, }, + { 0, 0, 0, 6, 7, 46, }, + { 2, 0, 0, 6, 7, 40, }, + { 1, 0, 0, 6, 7, 40, }, + { 0, 0, 0, 6, 8, 46, }, + { 2, 0, 0, 6, 8, 40, }, + { 1, 0, 0, 6, 8, 40, }, + { 0, 0, 0, 6, 9, 46, }, + { 2, 0, 0, 6, 9, 40, }, + { 1, 0, 0, 6, 9, 40, }, + { 0, 0, 0, 6, 10, 46, }, + { 2, 0, 0, 6, 10, 40, }, + { 1, 0, 0, 6, 10, 40, }, + { 0, 0, 0, 6, 11, 46, }, + { 2, 0, 0, 6, 11, 40, }, + { 1, 0, 0, 6, 11, 40, }, + { 0, 0, 0, 6, 12, 63, }, + { 2, 0, 0, 6, 12, 40, }, + { 1, 0, 0, 6, 12, 40, }, + { 0, 0, 0, 6, 13, 63, }, + { 2, 0, 0, 6, 13, 40, }, + { 1, 0, 0, 6, 13, 40, }, + { 0, 0, 0, 6, 14, 63, }, + { 2, 0, 0, 6, 14, 63, }, + { 1, 0, 0, 6, 14, 63, }, + { 0, 0, 0, 7, 1, 46, }, + { 2, 0, 0, 7, 1, 40, }, + { 1, 0, 0, 7, 1, 40, }, + { 0, 0, 0, 7, 2, 46, }, + { 2, 0, 0, 7, 2, 40, }, + { 1, 0, 0, 7, 2, 40, }, + { 0, 0, 0, 7, 3, 46, }, + { 2, 0, 0, 7, 3, 40, }, + { 1, 0, 0, 7, 3, 40, }, + { 0, 0, 0, 7, 4, 46, }, + { 2, 0, 0, 7, 4, 40, }, + { 1, 0, 0, 7, 4, 40, }, + { 0, 0, 0, 7, 5, 46, }, + { 2, 0, 0, 7, 5, 40, }, + { 1, 0, 0, 7, 5, 40, }, + { 0, 0, 0, 7, 6, 46, }, + { 2, 0, 0, 7, 6, 40, }, + { 1, 0, 0, 7, 6, 40, }, + { 0, 0, 0, 7, 7, 46, }, + { 2, 0, 0, 7, 7, 40, }, + { 1, 0, 0, 7, 7, 40, }, + { 0, 0, 0, 7, 8, 46, }, + { 2, 0, 0, 7, 8, 40, }, + { 1, 0, 0, 7, 8, 40, }, + { 0, 0, 0, 7, 9, 46, }, + { 2, 0, 0, 7, 9, 40, }, + { 1, 0, 0, 7, 9, 40, }, + { 0, 0, 0, 7, 10, 46, }, + { 2, 0, 0, 7, 10, 40, }, + { 1, 0, 0, 7, 10, 40, }, + { 0, 0, 0, 7, 11, 46, }, + { 2, 0, 0, 7, 11, 40, }, + { 1, 0, 0, 7, 11, 40, }, + { 0, 0, 0, 7, 12, 63, }, + { 2, 0, 0, 7, 12, 40, }, + { 1, 0, 0, 7, 12, 40, }, + { 0, 0, 0, 7, 13, 63, }, + { 2, 0, 0, 7, 13, 40, }, + { 1, 0, 0, 7, 13, 40, }, + { 0, 0, 0, 7, 14, 63, }, + { 2, 0, 0, 7, 14, 63, }, + { 1, 0, 0, 7, 14, 63, }, + { 0, 0, 1, 2, 1, 63, }, + { 2, 0, 1, 2, 1, 63, }, + { 1, 0, 1, 2, 1, 63, }, + { 0, 0, 1, 2, 2, 63, }, + { 2, 0, 1, 2, 2, 63, }, + { 1, 0, 1, 2, 2, 63, }, + { 0, 0, 1, 2, 3, 46, }, + { 2, 0, 1, 2, 3, 40, }, + { 1, 0, 1, 2, 3, 40, }, + { 0, 0, 1, 2, 4, 46, }, + { 2, 0, 1, 2, 4, 40, }, + { 1, 0, 1, 2, 4, 40, }, + { 0, 0, 1, 2, 5, 46, }, + { 2, 0, 1, 2, 5, 40, }, + { 1, 0, 1, 2, 5, 40, }, + { 0, 0, 1, 2, 6, 46, }, + { 2, 0, 1, 2, 6, 40, }, + { 1, 0, 1, 2, 6, 40, }, + { 0, 0, 1, 2, 7, 46, }, + { 2, 0, 1, 2, 7, 40, }, + { 1, 0, 1, 2, 7, 40, }, + { 0, 0, 1, 2, 8, 46, }, + { 2, 0, 1, 2, 8, 40, }, + { 1, 0, 1, 2, 8, 40, }, + { 0, 0, 1, 2, 9, 46, }, + { 2, 0, 1, 2, 9, 40, }, + { 1, 0, 1, 2, 9, 40, }, + { 0, 0, 1, 2, 10, 46, }, + { 2, 0, 1, 2, 10, 40, }, + { 1, 0, 1, 2, 10, 40, }, + { 0, 0, 1, 2, 11, 46, }, + { 2, 0, 1, 2, 11, 40, }, + { 1, 0, 1, 2, 11, 40, }, + { 0, 0, 1, 2, 12, 63, }, + { 2, 0, 1, 2, 12, 40, }, + { 1, 0, 1, 2, 12, 40, }, + { 0, 0, 1, 2, 13, 63, }, + { 2, 0, 1, 2, 13, 40, }, + { 1, 0, 1, 2, 13, 40, }, + { 0, 0, 1, 2, 14, 63, }, + { 2, 0, 1, 2, 14, 63, }, + { 1, 0, 1, 2, 14, 63, }, + { 0, 0, 1, 3, 1, 63, }, + { 2, 0, 1, 3, 1, 63, }, + { 1, 0, 1, 3, 1, 63, }, + { 0, 0, 1, 3, 2, 63, }, + { 2, 0, 1, 3, 2, 63, }, + { 1, 0, 1, 3, 2, 63, }, + { 0, 0, 1, 3, 3, 46, }, + { 2, 0, 1, 3, 3, 40, }, + { 1, 0, 1, 3, 3, 40, }, + { 0, 0, 1, 3, 4, 46, }, + { 2, 0, 1, 3, 4, 40, }, + { 1, 0, 1, 3, 4, 40, }, + { 0, 0, 1, 3, 5, 46, }, + { 2, 0, 1, 3, 5, 40, }, + { 1, 0, 1, 3, 5, 40, }, + { 0, 0, 1, 3, 6, 46, }, + { 2, 0, 1, 3, 6, 40, }, + { 1, 0, 1, 3, 6, 40, }, + { 0, 0, 1, 3, 7, 46, }, + { 2, 0, 1, 3, 7, 40, }, + { 1, 0, 1, 3, 7, 40, }, + { 0, 0, 1, 3, 8, 46, }, + { 2, 0, 1, 3, 8, 40, }, + { 1, 0, 1, 3, 8, 40, }, + { 0, 0, 1, 3, 9, 46, }, + { 2, 0, 1, 3, 9, 40, }, + { 1, 0, 1, 3, 9, 40, }, + { 0, 0, 1, 3, 10, 46, }, + { 2, 0, 1, 3, 10, 40, }, + { 1, 0, 1, 3, 10, 40, }, + { 0, 0, 1, 3, 11, 46, }, + { 2, 0, 1, 3, 11, 40, }, + { 1, 0, 1, 3, 11, 40, }, + { 0, 0, 1, 3, 12, 63, }, + { 2, 0, 1, 3, 12, 40, }, + { 1, 0, 1, 3, 12, 40, }, + { 0, 0, 1, 3, 13, 63, }, + { 2, 0, 1, 3, 13, 40, }, + { 1, 0, 1, 3, 13, 40, }, + { 0, 0, 1, 3, 14, 63, }, + { 2, 0, 1, 3, 14, 63, }, + { 1, 0, 1, 3, 14, 63, }, + { 0, 0, 1, 6, 1, 63, }, + { 2, 0, 1, 6, 1, 63, }, + { 1, 0, 1, 6, 1, 63, }, + { 0, 0, 1, 6, 2, 63, }, + { 2, 0, 1, 6, 2, 63, }, + { 1, 0, 1, 6, 2, 63, }, + { 0, 0, 1, 6, 3, 46, }, + { 2, 0, 1, 6, 3, 40, }, + { 1, 0, 1, 6, 3, 40, }, + { 0, 0, 1, 6, 4, 46, }, + { 2, 0, 1, 6, 4, 40, }, + { 1, 0, 1, 6, 4, 40, }, + { 0, 0, 1, 6, 5, 46, }, + { 2, 0, 1, 6, 5, 40, }, + { 1, 0, 1, 6, 5, 40, }, + { 0, 0, 1, 6, 6, 46, }, + { 2, 0, 1, 6, 6, 40, }, + { 1, 0, 1, 6, 6, 40, }, + { 0, 0, 1, 6, 7, 46, }, + { 2, 0, 1, 6, 7, 40, }, + { 1, 0, 1, 6, 7, 40, }, + { 0, 0, 1, 6, 8, 46, }, + { 2, 0, 1, 6, 8, 40, }, + { 1, 0, 1, 6, 8, 40, }, + { 0, 0, 1, 6, 9, 46, }, + { 2, 0, 1, 6, 9, 40, }, + { 1, 0, 1, 6, 9, 40, }, + { 0, 0, 1, 6, 10, 46, }, + { 2, 0, 1, 6, 10, 40, }, + { 1, 0, 1, 6, 10, 40, }, + { 0, 0, 1, 6, 11, 46, }, + { 2, 0, 1, 6, 11, 40, }, + { 1, 0, 1, 6, 11, 40, }, + { 0, 0, 1, 6, 12, 63, }, + { 2, 0, 1, 6, 12, 40, }, + { 1, 0, 1, 6, 12, 40, }, + { 0, 0, 1, 6, 13, 63, }, + { 2, 0, 1, 6, 13, 40, }, + { 1, 0, 1, 6, 13, 40, }, + { 0, 0, 1, 6, 14, 63, }, + { 2, 0, 1, 6, 14, 63, }, + { 1, 0, 1, 6, 14, 63, }, + { 0, 0, 1, 7, 1, 63, }, + { 2, 0, 1, 7, 1, 63, }, + { 1, 0, 1, 7, 1, 63, }, + { 0, 0, 1, 7, 2, 63, }, + { 2, 0, 1, 7, 2, 63, }, + { 1, 0, 1, 7, 2, 63, }, + { 0, 0, 1, 7, 3, 46, }, + { 2, 0, 1, 7, 3, 40, }, + { 1, 0, 1, 7, 3, 40, }, + { 0, 0, 1, 7, 4, 46, }, + { 2, 0, 1, 7, 4, 40, }, + { 1, 0, 1, 7, 4, 40, }, + { 0, 0, 1, 7, 5, 46, }, + { 2, 0, 1, 7, 5, 40, }, + { 1, 0, 1, 7, 5, 40, }, + { 0, 0, 1, 7, 6, 46, }, + { 2, 0, 1, 7, 6, 40, }, + { 1, 0, 1, 7, 6, 40, }, + { 0, 0, 1, 7, 7, 46, }, + { 2, 0, 1, 7, 7, 40, }, + { 1, 0, 1, 7, 7, 40, }, + { 0, 0, 1, 7, 8, 46, }, + { 2, 0, 1, 7, 8, 40, }, + { 1, 0, 1, 7, 8, 40, }, + { 0, 0, 1, 7, 9, 46, }, + { 2, 0, 1, 7, 9, 40, }, + { 1, 0, 1, 7, 9, 40, }, + { 0, 0, 1, 7, 10, 46, }, + { 2, 0, 1, 7, 10, 40, }, + { 1, 0, 1, 7, 10, 40, }, + { 0, 0, 1, 7, 11, 46, }, + { 2, 0, 1, 7, 11, 40, }, + { 1, 0, 1, 7, 11, 40, }, + { 0, 0, 1, 7, 12, 63, }, + { 2, 0, 1, 7, 12, 40, }, + { 1, 0, 1, 7, 12, 40, }, + { 0, 0, 1, 7, 13, 63, }, + { 2, 0, 1, 7, 13, 40, }, + { 1, 0, 1, 7, 13, 40, }, + { 0, 0, 1, 7, 14, 63, }, + { 2, 0, 1, 7, 14, 63, }, + { 1, 0, 1, 7, 14, 63, }, + { 0, 1, 0, 1, 36, 46, }, + { 2, 1, 0, 1, 36, 40, }, + { 1, 1, 0, 1, 36, 40, }, + { 0, 1, 0, 1, 40, 46, }, + { 2, 1, 0, 1, 40, 40, }, + { 1, 1, 0, 1, 40, 40, }, + { 0, 1, 0, 1, 44, 46, }, + { 2, 1, 0, 1, 44, 40, }, + { 1, 1, 0, 1, 44, 40, }, + { 0, 1, 0, 1, 48, 46, }, + { 2, 1, 0, 1, 48, 40, }, + { 1, 1, 0, 1, 48, 40, }, + { 0, 1, 0, 1, 52, 46, }, + { 2, 1, 0, 1, 52, 40, }, + { 1, 1, 0, 1, 52, 40, }, + { 0, 1, 0, 1, 56, 46, }, + { 2, 1, 0, 1, 56, 40, }, + { 1, 1, 0, 1, 56, 40, }, + { 0, 1, 0, 1, 60, 46, }, + { 2, 1, 0, 1, 60, 40, }, + { 1, 1, 0, 1, 60, 40, }, + { 0, 1, 0, 1, 64, 46, }, + { 2, 1, 0, 1, 64, 40, }, + { 1, 1, 0, 1, 64, 40, }, + { 0, 1, 0, 1, 100, 46, }, + { 2, 1, 0, 1, 100, 40, }, + { 1, 1, 0, 1, 100, 40, }, + { 0, 1, 0, 1, 104, 46, }, + { 2, 1, 0, 1, 104, 40, }, + { 1, 1, 0, 1, 104, 40, }, + { 0, 1, 0, 1, 108, 46, }, + { 2, 1, 0, 1, 108, 40, }, + { 1, 1, 0, 1, 108, 40, }, + { 0, 1, 0, 1, 112, 46, }, + { 2, 1, 0, 1, 112, 40, }, + { 1, 1, 0, 1, 112, 40, }, + { 0, 1, 0, 1, 116, 46, }, + { 2, 1, 0, 1, 116, 40, }, + { 1, 1, 0, 1, 116, 40, }, + { 0, 1, 0, 1, 120, 46, }, + { 2, 1, 0, 1, 120, 40, }, + { 1, 1, 0, 1, 120, 40, }, + { 0, 1, 0, 1, 124, 46, }, + { 2, 1, 0, 1, 124, 40, }, + { 1, 1, 0, 1, 124, 40, }, + { 0, 1, 0, 1, 128, 46, }, + { 2, 1, 0, 1, 128, 40, }, + { 1, 1, 0, 1, 128, 40, }, + { 0, 1, 0, 1, 132, 46, }, + { 2, 1, 0, 1, 132, 40, }, + { 1, 1, 0, 1, 132, 40, }, + { 0, 1, 0, 1, 136, 46, }, + { 2, 1, 0, 1, 136, 40, }, + { 1, 1, 0, 1, 136, 40, }, + { 0, 1, 0, 1, 140, 46, }, + { 2, 1, 0, 1, 140, 40, }, + { 1, 1, 0, 1, 140, 40, }, + { 0, 1, 0, 1, 149, 46, }, + { 2, 1, 0, 1, 149, 40, }, + { 1, 1, 0, 1, 149, 63, }, + { 0, 1, 0, 1, 153, 46, }, + { 2, 1, 0, 1, 153, 40, }, + { 1, 1, 0, 1, 153, 63, }, + { 0, 1, 0, 1, 157, 46, }, + { 2, 1, 0, 1, 157, 40, }, + { 1, 1, 0, 1, 157, 63, }, + { 0, 1, 0, 1, 161, 46, }, + { 2, 1, 0, 1, 161, 40, }, + { 1, 1, 0, 1, 161, 63, }, + { 0, 1, 0, 1, 165, 46, }, + { 2, 1, 0, 1, 165, 40, }, + { 1, 1, 0, 1, 165, 63, }, + { 0, 1, 0, 2, 36, 46, }, + { 2, 1, 0, 2, 36, 40, }, + { 1, 1, 0, 2, 36, 40, }, + { 0, 1, 0, 2, 40, 46, }, + { 2, 1, 0, 2, 40, 40, }, + { 1, 1, 0, 2, 40, 40, }, + { 0, 1, 0, 2, 44, 46, }, + { 2, 1, 0, 2, 44, 40, }, + { 1, 1, 0, 2, 44, 40, }, + { 0, 1, 0, 2, 48, 46, }, + { 2, 1, 0, 2, 48, 40, }, + { 1, 1, 0, 2, 48, 40, }, + { 0, 1, 0, 2, 52, 46, }, + { 2, 1, 0, 2, 52, 40, }, + { 1, 1, 0, 2, 52, 40, }, + { 0, 1, 0, 2, 56, 46, }, + { 2, 1, 0, 2, 56, 40, }, + { 1, 1, 0, 2, 56, 40, }, + { 0, 1, 0, 2, 60, 46, }, + { 2, 1, 0, 2, 60, 40, }, + { 1, 1, 0, 2, 60, 40, }, + { 0, 1, 0, 2, 64, 46, }, + { 2, 1, 0, 2, 64, 40, }, + { 1, 1, 0, 2, 64, 40, }, + { 0, 1, 0, 2, 100, 46, }, + { 2, 1, 0, 2, 100, 40, }, + { 1, 1, 0, 2, 100, 40, }, + { 0, 1, 0, 2, 104, 46, }, + { 2, 1, 0, 2, 104, 40, }, + { 1, 1, 0, 2, 104, 40, }, + { 0, 1, 0, 2, 108, 46, }, + { 2, 1, 0, 2, 108, 40, }, + { 1, 1, 0, 2, 108, 40, }, + { 0, 1, 0, 2, 112, 46, }, + { 2, 1, 0, 2, 112, 40, }, + { 1, 1, 0, 2, 112, 40, }, + { 0, 1, 0, 2, 116, 46, }, + { 2, 1, 0, 2, 116, 40, }, + { 1, 1, 0, 2, 116, 40, }, + { 0, 1, 0, 2, 120, 46, }, + { 2, 1, 0, 2, 120, 40, }, + { 1, 1, 0, 2, 120, 40, }, + { 0, 1, 0, 2, 124, 46, }, + { 2, 1, 0, 2, 124, 40, }, + { 1, 1, 0, 2, 124, 40, }, + { 0, 1, 0, 2, 128, 46, }, + { 2, 1, 0, 2, 128, 40, }, + { 1, 1, 0, 2, 128, 40, }, + { 0, 1, 0, 2, 132, 46, }, + { 2, 1, 0, 2, 132, 40, }, + { 1, 1, 0, 2, 132, 40, }, + { 0, 1, 0, 2, 136, 46, }, + { 2, 1, 0, 2, 136, 40, }, + { 1, 1, 0, 2, 136, 40, }, + { 0, 1, 0, 2, 140, 46, }, + { 2, 1, 0, 2, 140, 40, }, + { 1, 1, 0, 2, 140, 40, }, + { 0, 1, 0, 2, 149, 46, }, + { 2, 1, 0, 2, 149, 40, }, + { 1, 1, 0, 2, 149, 63, }, + { 0, 1, 0, 2, 153, 46, }, + { 2, 1, 0, 2, 153, 40, }, + { 1, 1, 0, 2, 153, 63, }, + { 0, 1, 0, 2, 157, 46, }, + { 2, 1, 0, 2, 157, 40, }, + { 1, 1, 0, 2, 157, 63, }, + { 0, 1, 0, 2, 161, 46, }, + { 2, 1, 0, 2, 161, 40, }, + { 1, 1, 0, 2, 161, 63, }, + { 0, 1, 0, 2, 165, 46, }, + { 2, 1, 0, 2, 165, 40, }, + { 1, 1, 0, 2, 165, 63, }, + { 0, 1, 0, 3, 36, 46, }, + { 2, 1, 0, 3, 36, 40, }, + { 1, 1, 0, 3, 36, 40, }, + { 0, 1, 0, 3, 40, 46, }, + { 2, 1, 0, 3, 40, 40, }, + { 1, 1, 0, 3, 40, 40, }, + { 0, 1, 0, 3, 44, 46, }, + { 2, 1, 0, 3, 44, 40, }, + { 1, 1, 0, 3, 44, 40, }, + { 0, 1, 0, 3, 48, 46, }, + { 2, 1, 0, 3, 48, 40, }, + { 1, 1, 0, 3, 48, 40, }, + { 0, 1, 0, 3, 52, 46, }, + { 2, 1, 0, 3, 52, 40, }, + { 1, 1, 0, 3, 52, 40, }, + { 0, 1, 0, 3, 56, 46, }, + { 2, 1, 0, 3, 56, 40, }, + { 1, 1, 0, 3, 56, 40, }, + { 0, 1, 0, 3, 60, 46, }, + { 2, 1, 0, 3, 60, 40, }, + { 1, 1, 0, 3, 60, 40, }, + { 0, 1, 0, 3, 64, 46, }, + { 2, 1, 0, 3, 64, 40, }, + { 1, 1, 0, 3, 64, 40, }, + { 0, 1, 0, 3, 100, 46, }, + { 2, 1, 0, 3, 100, 40, }, + { 1, 1, 0, 3, 100, 40, }, + { 0, 1, 0, 3, 104, 46, }, + { 2, 1, 0, 3, 104, 40, }, + { 1, 1, 0, 3, 104, 40, }, + { 0, 1, 0, 3, 108, 46, }, + { 2, 1, 0, 3, 108, 40, }, + { 1, 1, 0, 3, 108, 40, }, + { 0, 1, 0, 3, 112, 46, }, + { 2, 1, 0, 3, 112, 40, }, + { 1, 1, 0, 3, 112, 40, }, + { 0, 1, 0, 3, 116, 46, }, + { 2, 1, 0, 3, 116, 40, }, + { 1, 1, 0, 3, 116, 40, }, + { 0, 1, 0, 3, 120, 46, }, + { 2, 1, 0, 3, 120, 40, }, + { 1, 1, 0, 3, 120, 40, }, + { 0, 1, 0, 3, 124, 46, }, + { 2, 1, 0, 3, 124, 40, }, + { 1, 1, 0, 3, 124, 40, }, + { 0, 1, 0, 3, 128, 46, }, + { 2, 1, 0, 3, 128, 40, }, + { 1, 1, 0, 3, 128, 40, }, + { 0, 1, 0, 3, 132, 46, }, + { 2, 1, 0, 3, 132, 40, }, + { 1, 1, 0, 3, 132, 40, }, + { 0, 1, 0, 3, 136, 46, }, + { 2, 1, 0, 3, 136, 40, }, + { 1, 1, 0, 3, 136, 40, }, + { 0, 1, 0, 3, 140, 46, }, + { 2, 1, 0, 3, 140, 40, }, + { 1, 1, 0, 3, 140, 40, }, + { 0, 1, 0, 3, 149, 46, }, + { 2, 1, 0, 3, 149, 40, }, + { 1, 1, 0, 3, 149, 63, }, + { 0, 1, 0, 3, 153, 46, }, + { 2, 1, 0, 3, 153, 40, }, + { 1, 1, 0, 3, 153, 63, }, + { 0, 1, 0, 3, 157, 46, }, + { 2, 1, 0, 3, 157, 40, }, + { 1, 1, 0, 3, 157, 63, }, + { 0, 1, 0, 3, 161, 46, }, + { 2, 1, 0, 3, 161, 40, }, + { 1, 1, 0, 3, 161, 63, }, + { 0, 1, 0, 3, 165, 46, }, + { 2, 1, 0, 3, 165, 40, }, + { 1, 1, 0, 3, 165, 63, }, + { 0, 1, 0, 6, 36, 46, }, + { 2, 1, 0, 6, 36, 40, }, + { 1, 1, 0, 6, 36, 40, }, + { 0, 1, 0, 6, 40, 46, }, + { 2, 1, 0, 6, 40, 40, }, + { 1, 1, 0, 6, 40, 40, }, + { 0, 1, 0, 6, 44, 46, }, + { 2, 1, 0, 6, 44, 40, }, + { 1, 1, 0, 6, 44, 40, }, + { 0, 1, 0, 6, 48, 46, }, + { 2, 1, 0, 6, 48, 40, }, + { 1, 1, 0, 6, 48, 40, }, + { 0, 1, 0, 6, 52, 46, }, + { 2, 1, 0, 6, 52, 40, }, + { 1, 1, 0, 6, 52, 40, }, + { 0, 1, 0, 6, 56, 46, }, + { 2, 1, 0, 6, 56, 40, }, + { 1, 1, 0, 6, 56, 40, }, + { 0, 1, 0, 6, 60, 46, }, + { 2, 1, 0, 6, 60, 40, }, + { 1, 1, 0, 6, 60, 40, }, + { 0, 1, 0, 6, 64, 46, }, + { 2, 1, 0, 6, 64, 40, }, + { 1, 1, 0, 6, 64, 40, }, + { 0, 1, 0, 6, 100, 46, }, + { 2, 1, 0, 6, 100, 40, }, + { 1, 1, 0, 6, 100, 40, }, + { 0, 1, 0, 6, 104, 46, }, + { 2, 1, 0, 6, 104, 40, }, + { 1, 1, 0, 6, 104, 40, }, + { 0, 1, 0, 6, 108, 46, }, + { 2, 1, 0, 6, 108, 40, }, + { 1, 1, 0, 6, 108, 40, }, + { 0, 1, 0, 6, 112, 46, }, + { 2, 1, 0, 6, 112, 40, }, + { 1, 1, 0, 6, 112, 40, }, + { 0, 1, 0, 6, 116, 46, }, + { 2, 1, 0, 6, 116, 40, }, + { 1, 1, 0, 6, 116, 40, }, + { 0, 1, 0, 6, 120, 46, }, + { 2, 1, 0, 6, 120, 40, }, + { 1, 1, 0, 6, 120, 40, }, + { 0, 1, 0, 6, 124, 46, }, + { 2, 1, 0, 6, 124, 40, }, + { 1, 1, 0, 6, 124, 40, }, + { 0, 1, 0, 6, 128, 46, }, + { 2, 1, 0, 6, 128, 40, }, + { 1, 1, 0, 6, 128, 40, }, + { 0, 1, 0, 6, 132, 46, }, + { 2, 1, 0, 6, 132, 40, }, + { 1, 1, 0, 6, 132, 40, }, + { 0, 1, 0, 6, 136, 46, }, + { 2, 1, 0, 6, 136, 40, }, + { 1, 1, 0, 6, 136, 40, }, + { 0, 1, 0, 6, 140, 46, }, + { 2, 1, 0, 6, 140, 40, }, + { 1, 1, 0, 6, 140, 40, }, + { 0, 1, 0, 6, 149, 46, }, + { 2, 1, 0, 6, 149, 40, }, + { 1, 1, 0, 6, 149, 63, }, + { 0, 1, 0, 6, 153, 46, }, + { 2, 1, 0, 6, 153, 40, }, + { 1, 1, 0, 6, 153, 63, }, + { 0, 1, 0, 6, 157, 46, }, + { 2, 1, 0, 6, 157, 40, }, + { 1, 1, 0, 6, 157, 63, }, + { 0, 1, 0, 6, 161, 46, }, + { 2, 1, 0, 6, 161, 40, }, + { 1, 1, 0, 6, 161, 63, }, + { 0, 1, 0, 6, 165, 46, }, + { 2, 1, 0, 6, 165, 40, }, + { 1, 1, 0, 6, 165, 63, }, + { 0, 1, 0, 7, 36, 46, }, + { 2, 1, 0, 7, 36, 40, }, + { 1, 1, 0, 7, 36, 40, }, + { 0, 1, 0, 7, 40, 46, }, + { 2, 1, 0, 7, 40, 40, }, + { 1, 1, 0, 7, 40, 40, }, + { 0, 1, 0, 7, 44, 46, }, + { 2, 1, 0, 7, 44, 40, }, + { 1, 1, 0, 7, 44, 40, }, + { 0, 1, 0, 7, 48, 46, }, + { 2, 1, 0, 7, 48, 40, }, + { 1, 1, 0, 7, 48, 40, }, + { 0, 1, 0, 7, 52, 46, }, + { 2, 1, 0, 7, 52, 40, }, + { 1, 1, 0, 7, 52, 40, }, + { 0, 1, 0, 7, 56, 46, }, + { 2, 1, 0, 7, 56, 40, }, + { 1, 1, 0, 7, 56, 40, }, + { 0, 1, 0, 7, 60, 46, }, + { 2, 1, 0, 7, 60, 40, }, + { 1, 1, 0, 7, 60, 40, }, + { 0, 1, 0, 7, 64, 46, }, + { 2, 1, 0, 7, 64, 40, }, + { 1, 1, 0, 7, 64, 40, }, + { 0, 1, 0, 7, 100, 46, }, + { 2, 1, 0, 7, 100, 40, }, + { 1, 1, 0, 7, 100, 40, }, + { 0, 1, 0, 7, 104, 46, }, + { 2, 1, 0, 7, 104, 40, }, + { 1, 1, 0, 7, 104, 40, }, + { 0, 1, 0, 7, 108, 46, }, + { 2, 1, 0, 7, 108, 40, }, + { 1, 1, 0, 7, 108, 40, }, + { 0, 1, 0, 7, 112, 46, }, + { 2, 1, 0, 7, 112, 40, }, + { 1, 1, 0, 7, 112, 40, }, + { 0, 1, 0, 7, 116, 46, }, + { 2, 1, 0, 7, 116, 40, }, + { 1, 1, 0, 7, 116, 40, }, + { 0, 1, 0, 7, 120, 46, }, + { 2, 1, 0, 7, 120, 40, }, + { 1, 1, 0, 7, 120, 40, }, + { 0, 1, 0, 7, 124, 46, }, + { 2, 1, 0, 7, 124, 40, }, + { 1, 1, 0, 7, 124, 40, }, + { 0, 1, 0, 7, 128, 46, }, + { 2, 1, 0, 7, 128, 40, }, + { 1, 1, 0, 7, 128, 40, }, + { 0, 1, 0, 7, 132, 46, }, + { 2, 1, 0, 7, 132, 40, }, + { 1, 1, 0, 7, 132, 40, }, + { 0, 1, 0, 7, 136, 46, }, + { 2, 1, 0, 7, 136, 40, }, + { 1, 1, 0, 7, 136, 40, }, + { 0, 1, 0, 7, 140, 46, }, + { 2, 1, 0, 7, 140, 40, }, + { 1, 1, 0, 7, 140, 40, }, + { 0, 1, 0, 7, 149, 46, }, + { 2, 1, 0, 7, 149, 40, }, + { 1, 1, 0, 7, 149, 63, }, + { 0, 1, 0, 7, 153, 46, }, + { 2, 1, 0, 7, 153, 40, }, + { 1, 1, 0, 7, 153, 63, }, + { 0, 1, 0, 7, 157, 46, }, + { 2, 1, 0, 7, 157, 40, }, + { 1, 1, 0, 7, 157, 63, }, + { 0, 1, 0, 7, 161, 46, }, + { 2, 1, 0, 7, 161, 40, }, + { 1, 1, 0, 7, 161, 63, }, + { 0, 1, 0, 7, 165, 46, }, + { 2, 1, 0, 7, 165, 40, }, + { 1, 1, 0, 7, 165, 63, }, + { 0, 1, 1, 2, 38, 46, }, + { 2, 1, 1, 2, 38, 40, }, + { 1, 1, 1, 2, 38, 40, }, + { 0, 1, 1, 2, 46, 46, }, + { 2, 1, 1, 2, 46, 40, }, + { 1, 1, 1, 2, 46, 40, }, + { 0, 1, 1, 2, 54, 46, }, + { 2, 1, 1, 2, 54, 40, }, + { 1, 1, 1, 2, 54, 40, }, + { 0, 1, 1, 2, 62, 46, }, + { 2, 1, 1, 2, 62, 40, }, + { 1, 1, 1, 2, 62, 40, }, + { 0, 1, 1, 2, 102, 46, }, + { 2, 1, 1, 2, 102, 40, }, + { 1, 1, 1, 2, 102, 40, }, + { 0, 1, 1, 2, 110, 46, }, + { 2, 1, 1, 2, 110, 40, }, + { 1, 1, 1, 2, 110, 40, }, + { 0, 1, 1, 2, 118, 46, }, + { 2, 1, 1, 2, 118, 40, }, + { 1, 1, 1, 2, 118, 40, }, + { 0, 1, 1, 2, 126, 46, }, + { 2, 1, 1, 2, 126, 40, }, + { 1, 1, 1, 2, 126, 40, }, + { 0, 1, 1, 2, 134, 46, }, + { 2, 1, 1, 2, 134, 40, }, + { 1, 1, 1, 2, 134, 40, }, + { 0, 1, 1, 2, 151, 46, }, + { 2, 1, 1, 2, 151, 40, }, + { 1, 1, 1, 2, 151, 63, }, + { 0, 1, 1, 2, 159, 46, }, + { 2, 1, 1, 2, 159, 40, }, + { 1, 1, 1, 2, 159, 63, }, + { 0, 1, 1, 3, 38, 46, }, + { 2, 1, 1, 3, 38, 40, }, + { 1, 1, 1, 3, 38, 40, }, + { 0, 1, 1, 3, 46, 46, }, + { 2, 1, 1, 3, 46, 40, }, + { 1, 1, 1, 3, 46, 40, }, + { 0, 1, 1, 3, 54, 46, }, + { 2, 1, 1, 3, 54, 40, }, + { 1, 1, 1, 3, 54, 40, }, + { 0, 1, 1, 3, 62, 46, }, + { 2, 1, 1, 3, 62, 40, }, + { 1, 1, 1, 3, 62, 40, }, + { 0, 1, 1, 3, 102, 46, }, + { 2, 1, 1, 3, 102, 40, }, + { 1, 1, 1, 3, 102, 40, }, + { 0, 1, 1, 3, 110, 46, }, + { 2, 1, 1, 3, 110, 40, }, + { 1, 1, 1, 3, 110, 40, }, + { 0, 1, 1, 3, 118, 46, }, + { 2, 1, 1, 3, 118, 40, }, + { 1, 1, 1, 3, 118, 40, }, + { 0, 1, 1, 3, 126, 46, }, + { 2, 1, 1, 3, 126, 40, }, + { 1, 1, 1, 3, 126, 40, }, + { 0, 1, 1, 3, 134, 46, }, + { 2, 1, 1, 3, 134, 40, }, + { 1, 1, 1, 3, 134, 40, }, + { 0, 1, 1, 3, 151, 46, }, + { 2, 1, 1, 3, 151, 40, }, + { 1, 1, 1, 3, 151, 63, }, + { 0, 1, 1, 3, 159, 46, }, + { 2, 1, 1, 3, 159, 40, }, + { 1, 1, 1, 3, 159, 63, }, + { 0, 1, 1, 6, 38, 46, }, + { 2, 1, 1, 6, 38, 40, }, + { 1, 1, 1, 6, 38, 40, }, + { 0, 1, 1, 6, 46, 46, }, + { 2, 1, 1, 6, 46, 40, }, + { 1, 1, 1, 6, 46, 40, }, + { 0, 1, 1, 6, 54, 46, }, + { 2, 1, 1, 6, 54, 40, }, + { 1, 1, 1, 6, 54, 40, }, + { 0, 1, 1, 6, 62, 46, }, + { 2, 1, 1, 6, 62, 40, }, + { 1, 1, 1, 6, 62, 40, }, + { 0, 1, 1, 6, 102, 46, }, + { 2, 1, 1, 6, 102, 40, }, + { 1, 1, 1, 6, 102, 40, }, + { 0, 1, 1, 6, 110, 46, }, + { 2, 1, 1, 6, 110, 40, }, + { 1, 1, 1, 6, 110, 40, }, + { 0, 1, 1, 6, 118, 46, }, + { 2, 1, 1, 6, 118, 40, }, + { 1, 1, 1, 6, 118, 40, }, + { 0, 1, 1, 6, 126, 46, }, + { 2, 1, 1, 6, 126, 40, }, + { 1, 1, 1, 6, 126, 40, }, + { 0, 1, 1, 6, 134, 46, }, + { 2, 1, 1, 6, 134, 40, }, + { 1, 1, 1, 6, 134, 40, }, + { 0, 1, 1, 6, 151, 46, }, + { 2, 1, 1, 6, 151, 40, }, + { 1, 1, 1, 6, 151, 63, }, + { 0, 1, 1, 6, 159, 46, }, + { 2, 1, 1, 6, 159, 40, }, + { 1, 1, 1, 6, 159, 63, }, + { 0, 1, 1, 7, 38, 46, }, + { 2, 1, 1, 7, 38, 40, }, + { 1, 1, 1, 7, 38, 40, }, + { 0, 1, 1, 7, 46, 46, }, + { 2, 1, 1, 7, 46, 40, }, + { 1, 1, 1, 7, 46, 40, }, + { 0, 1, 1, 7, 54, 46, }, + { 2, 1, 1, 7, 54, 40, }, + { 1, 1, 1, 7, 54, 40, }, + { 0, 1, 1, 7, 62, 46, }, + { 2, 1, 1, 7, 62, 40, }, + { 1, 1, 1, 7, 62, 40, }, + { 0, 1, 1, 7, 102, 46, }, + { 2, 1, 1, 7, 102, 40, }, + { 1, 1, 1, 7, 102, 40, }, + { 0, 1, 1, 7, 110, 46, }, + { 2, 1, 1, 7, 110, 40, }, + { 1, 1, 1, 7, 110, 40, }, + { 0, 1, 1, 7, 118, 46, }, + { 2, 1, 1, 7, 118, 40, }, + { 1, 1, 1, 7, 118, 40, }, + { 0, 1, 1, 7, 126, 46, }, + { 2, 1, 1, 7, 126, 40, }, + { 1, 1, 1, 7, 126, 40, }, + { 0, 1, 1, 7, 134, 46, }, + { 2, 1, 1, 7, 134, 40, }, + { 1, 1, 1, 7, 134, 40, }, + { 0, 1, 1, 7, 151, 46, }, + { 2, 1, 1, 7, 151, 40, }, + { 1, 1, 1, 7, 151, 63, }, + { 0, 1, 1, 7, 159, 46, }, + { 2, 1, 1, 7, 159, 40, }, + { 1, 1, 1, 7, 159, 63, }, + { 0, 1, 2, 4, 42, 46, }, + { 2, 1, 2, 4, 42, 40, }, + { 1, 1, 2, 4, 42, 40, }, + { 0, 1, 2, 4, 58, 46, }, + { 2, 1, 2, 4, 58, 40, }, + { 1, 1, 2, 4, 58, 40, }, + { 0, 1, 2, 4, 106, 46, }, + { 2, 1, 2, 4, 106, 40, }, + { 1, 1, 2, 4, 106, 40, }, + { 0, 1, 2, 4, 122, 46, }, + { 2, 1, 2, 4, 122, 40, }, + { 1, 1, 2, 4, 122, 40, }, + { 0, 1, 2, 4, 155, 46, }, + { 2, 1, 2, 4, 155, 40, }, + { 1, 1, 2, 4, 155, 63, }, + { 0, 1, 2, 5, 42, 46, }, + { 2, 1, 2, 5, 42, 40, }, + { 1, 1, 2, 5, 42, 40, }, + { 0, 1, 2, 5, 58, 46, }, + { 2, 1, 2, 5, 58, 40, }, + { 1, 1, 2, 5, 58, 40, }, + { 0, 1, 2, 5, 106, 46, }, + { 2, 1, 2, 5, 106, 40, }, + { 1, 1, 2, 5, 106, 40, }, + { 0, 1, 2, 5, 122, 46, }, + { 2, 1, 2, 5, 122, 40, }, + { 1, 1, 2, 5, 122, 40, }, + { 0, 1, 2, 5, 155, 46, }, + { 2, 1, 2, 5, 155, 40, }, + { 1, 1, 2, 5, 155, 63, }, + { 0, 1, 2, 8, 42, 46, }, + { 2, 1, 2, 8, 42, 40, }, + { 1, 1, 2, 8, 42, 40, }, + { 0, 1, 2, 8, 58, 46, }, + { 2, 1, 2, 8, 58, 40, }, + { 1, 1, 2, 8, 58, 40, }, + { 0, 1, 2, 8, 106, 46, }, + { 2, 1, 2, 8, 106, 40, }, + { 1, 1, 2, 8, 106, 40, }, + { 0, 1, 2, 8, 122, 46, }, + { 2, 1, 2, 8, 122, 40, }, + { 1, 1, 2, 8, 122, 40, }, + { 0, 1, 2, 8, 155, 46, }, + { 2, 1, 2, 8, 155, 40, }, + { 1, 1, 2, 8, 155, 63, }, + { 0, 1, 2, 9, 42, 46, }, + { 2, 1, 2, 9, 42, 40, }, + { 1, 1, 2, 9, 42, 40, }, + { 0, 1, 2, 9, 58, 46, }, + { 2, 1, 2, 9, 58, 40, }, + { 1, 1, 2, 9, 58, 40, }, + { 0, 1, 2, 9, 106, 46, }, + { 2, 1, 2, 9, 106, 40, }, + { 1, 1, 2, 9, 106, 40, }, + { 0, 1, 2, 9, 122, 46, }, + { 2, 1, 2, 9, 122, 40, }, + { 1, 1, 2, 9, 122, 40, }, + { 0, 1, 2, 9, 155, 46, }, + { 2, 1, 2, 9, 155, 40, }, + { 1, 1, 2, 9, 155, 63, }, +}; + +RTW_DECL_TABLE_TXPWR_LMT(rtw8814a_txpwr_lmt_type3); + +static const struct rtw_txpwr_lmt_cfg_pair rtw8814a_txpwr_lmt_type5[] = { + { 0, 0, 0, 0, 1, 46, }, + { 2, 0, 0, 0, 1, 40, }, + { 1, 0, 0, 0, 1, 40, }, + { 0, 0, 0, 0, 2, 46, }, + { 2, 0, 0, 0, 2, 40, }, + { 1, 0, 0, 0, 2, 40, }, + { 0, 0, 0, 0, 3, 46, }, + { 2, 0, 0, 0, 3, 40, }, + { 1, 0, 0, 0, 3, 40, }, + { 0, 0, 0, 0, 4, 46, }, + { 2, 0, 0, 0, 4, 40, }, + { 1, 0, 0, 0, 4, 40, }, + { 0, 0, 0, 0, 5, 46, }, + { 2, 0, 0, 0, 5, 40, }, + { 1, 0, 0, 0, 5, 40, }, + { 0, 0, 0, 0, 6, 46, }, + { 2, 0, 0, 0, 6, 40, }, + { 1, 0, 0, 0, 6, 40, }, + { 0, 0, 0, 0, 7, 46, }, + { 2, 0, 0, 0, 7, 40, }, + { 1, 0, 0, 0, 7, 40, }, + { 0, 0, 0, 0, 8, 46, }, + { 2, 0, 0, 0, 8, 40, }, + { 1, 0, 0, 0, 8, 40, }, + { 0, 0, 0, 0, 9, 46, }, + { 2, 0, 0, 0, 9, 40, }, + { 1, 0, 0, 0, 9, 40, }, + { 0, 0, 0, 0, 10, 46, }, + { 2, 0, 0, 0, 10, 40, }, + { 1, 0, 0, 0, 10, 40, }, + { 0, 0, 0, 0, 11, 46, }, + { 2, 0, 0, 0, 11, 40, }, + { 1, 0, 0, 0, 11, 40, }, + { 0, 0, 0, 0, 12, 63, }, + { 2, 0, 0, 0, 12, 40, }, + { 1, 0, 0, 0, 12, 40, }, + { 0, 0, 0, 0, 13, 63, }, + { 2, 0, 0, 0, 13, 40, }, + { 1, 0, 0, 0, 13, 40, }, + { 0, 0, 0, 0, 14, 63, }, + { 2, 0, 0, 0, 14, 63, }, + { 1, 0, 0, 0, 14, 40, }, + { 0, 0, 0, 1, 1, 46, }, + { 2, 0, 0, 1, 1, 40, }, + { 1, 0, 0, 1, 1, 40, }, + { 0, 0, 0, 1, 2, 46, }, + { 2, 0, 0, 1, 2, 40, }, + { 1, 0, 0, 1, 2, 40, }, + { 0, 0, 0, 1, 3, 46, }, + { 2, 0, 0, 1, 3, 40, }, + { 1, 0, 0, 1, 3, 40, }, + { 0, 0, 0, 1, 4, 46, }, + { 2, 0, 0, 1, 4, 40, }, + { 1, 0, 0, 1, 4, 40, }, + { 0, 0, 0, 1, 5, 46, }, + { 2, 0, 0, 1, 5, 40, }, + { 1, 0, 0, 1, 5, 40, }, + { 0, 0, 0, 1, 6, 46, }, + { 2, 0, 0, 1, 6, 40, }, + { 1, 0, 0, 1, 6, 40, }, + { 0, 0, 0, 1, 7, 46, }, + { 2, 0, 0, 1, 7, 40, }, + { 1, 0, 0, 1, 7, 40, }, + { 0, 0, 0, 1, 8, 46, }, + { 2, 0, 0, 1, 8, 40, }, + { 1, 0, 0, 1, 8, 40, }, + { 0, 0, 0, 1, 9, 46, }, + { 2, 0, 0, 1, 9, 40, }, + { 1, 0, 0, 1, 9, 40, }, + { 0, 0, 0, 1, 10, 46, }, + { 2, 0, 0, 1, 10, 40, }, + { 1, 0, 0, 1, 10, 40, }, + { 0, 0, 0, 1, 11, 46, }, + { 2, 0, 0, 1, 11, 40, }, + { 1, 0, 0, 1, 11, 40, }, + { 0, 0, 0, 1, 12, 63, }, + { 2, 0, 0, 1, 12, 40, }, + { 1, 0, 0, 1, 12, 40, }, + { 0, 0, 0, 1, 13, 63, }, + { 2, 0, 0, 1, 13, 40, }, + { 1, 0, 0, 1, 13, 40, }, + { 0, 0, 0, 1, 14, 63, }, + { 2, 0, 0, 1, 14, 63, }, + { 1, 0, 0, 1, 14, 63, }, + { 0, 0, 0, 2, 1, 46, }, + { 2, 0, 0, 2, 1, 40, }, + { 1, 0, 0, 2, 1, 40, }, + { 0, 0, 0, 2, 2, 46, }, + { 2, 0, 0, 2, 2, 40, }, + { 1, 0, 0, 2, 2, 40, }, + { 0, 0, 0, 2, 3, 46, }, + { 2, 0, 0, 2, 3, 40, }, + { 1, 0, 0, 2, 3, 40, }, + { 0, 0, 0, 2, 4, 46, }, + { 2, 0, 0, 2, 4, 40, }, + { 1, 0, 0, 2, 4, 40, }, + { 0, 0, 0, 2, 5, 46, }, + { 2, 0, 0, 2, 5, 40, }, + { 1, 0, 0, 2, 5, 40, }, + { 0, 0, 0, 2, 6, 46, }, + { 2, 0, 0, 2, 6, 40, }, + { 1, 0, 0, 2, 6, 40, }, + { 0, 0, 0, 2, 7, 46, }, + { 2, 0, 0, 2, 7, 40, }, + { 1, 0, 0, 2, 7, 40, }, + { 0, 0, 0, 2, 8, 46, }, + { 2, 0, 0, 2, 8, 40, }, + { 1, 0, 0, 2, 8, 40, }, + { 0, 0, 0, 2, 9, 46, }, + { 2, 0, 0, 2, 9, 40, }, + { 1, 0, 0, 2, 9, 40, }, + { 0, 0, 0, 2, 10, 46, }, + { 2, 0, 0, 2, 10, 40, }, + { 1, 0, 0, 2, 10, 40, }, + { 0, 0, 0, 2, 11, 46, }, + { 2, 0, 0, 2, 11, 40, }, + { 1, 0, 0, 2, 11, 40, }, + { 0, 0, 0, 2, 12, 63, }, + { 2, 0, 0, 2, 12, 40, }, + { 1, 0, 0, 2, 12, 40, }, + { 0, 0, 0, 2, 13, 63, }, + { 2, 0, 0, 2, 13, 40, }, + { 1, 0, 0, 2, 13, 40, }, + { 0, 0, 0, 2, 14, 63, }, + { 2, 0, 0, 2, 14, 63, }, + { 1, 0, 0, 2, 14, 63, }, + { 0, 0, 0, 3, 1, 46, }, + { 2, 0, 0, 3, 1, 40, }, + { 1, 0, 0, 3, 1, 40, }, + { 0, 0, 0, 3, 2, 46, }, + { 2, 0, 0, 3, 2, 40, }, + { 1, 0, 0, 3, 2, 40, }, + { 0, 0, 0, 3, 3, 46, }, + { 2, 0, 0, 3, 3, 40, }, + { 1, 0, 0, 3, 3, 40, }, + { 0, 0, 0, 3, 4, 46, }, + { 2, 0, 0, 3, 4, 40, }, + { 1, 0, 0, 3, 4, 40, }, + { 0, 0, 0, 3, 5, 46, }, + { 2, 0, 0, 3, 5, 40, }, + { 1, 0, 0, 3, 5, 40, }, + { 0, 0, 0, 3, 6, 46, }, + { 2, 0, 0, 3, 6, 40, }, + { 1, 0, 0, 3, 6, 40, }, + { 0, 0, 0, 3, 7, 46, }, + { 2, 0, 0, 3, 7, 40, }, + { 1, 0, 0, 3, 7, 40, }, + { 0, 0, 0, 3, 8, 46, }, + { 2, 0, 0, 3, 8, 40, }, + { 1, 0, 0, 3, 8, 40, }, + { 0, 0, 0, 3, 9, 46, }, + { 2, 0, 0, 3, 9, 40, }, + { 1, 0, 0, 3, 9, 40, }, + { 0, 0, 0, 3, 10, 46, }, + { 2, 0, 0, 3, 10, 40, }, + { 1, 0, 0, 3, 10, 40, }, + { 0, 0, 0, 3, 11, 46, }, + { 2, 0, 0, 3, 11, 40, }, + { 1, 0, 0, 3, 11, 40, }, + { 0, 0, 0, 3, 12, 63, }, + { 2, 0, 0, 3, 12, 40, }, + { 1, 0, 0, 3, 12, 40, }, + { 0, 0, 0, 3, 13, 63, }, + { 2, 0, 0, 3, 13, 40, }, + { 1, 0, 0, 3, 13, 40, }, + { 0, 0, 0, 3, 14, 63, }, + { 2, 0, 0, 3, 14, 63, }, + { 1, 0, 0, 3, 14, 63, }, + { 0, 0, 0, 6, 1, 46, }, + { 2, 0, 0, 6, 1, 40, }, + { 1, 0, 0, 6, 1, 40, }, + { 0, 0, 0, 6, 2, 46, }, + { 2, 0, 0, 6, 2, 40, }, + { 1, 0, 0, 6, 2, 40, }, + { 0, 0, 0, 6, 3, 46, }, + { 2, 0, 0, 6, 3, 40, }, + { 1, 0, 0, 6, 3, 40, }, + { 0, 0, 0, 6, 4, 46, }, + { 2, 0, 0, 6, 4, 40, }, + { 1, 0, 0, 6, 4, 40, }, + { 0, 0, 0, 6, 5, 46, }, + { 2, 0, 0, 6, 5, 40, }, + { 1, 0, 0, 6, 5, 40, }, + { 0, 0, 0, 6, 6, 46, }, + { 2, 0, 0, 6, 6, 40, }, + { 1, 0, 0, 6, 6, 40, }, + { 0, 0, 0, 6, 7, 46, }, + { 2, 0, 0, 6, 7, 40, }, + { 1, 0, 0, 6, 7, 40, }, + { 0, 0, 0, 6, 8, 46, }, + { 2, 0, 0, 6, 8, 40, }, + { 1, 0, 0, 6, 8, 40, }, + { 0, 0, 0, 6, 9, 46, }, + { 2, 0, 0, 6, 9, 40, }, + { 1, 0, 0, 6, 9, 40, }, + { 0, 0, 0, 6, 10, 46, }, + { 2, 0, 0, 6, 10, 40, }, + { 1, 0, 0, 6, 10, 40, }, + { 0, 0, 0, 6, 11, 46, }, + { 2, 0, 0, 6, 11, 40, }, + { 1, 0, 0, 6, 11, 40, }, + { 0, 0, 0, 6, 12, 63, }, + { 2, 0, 0, 6, 12, 40, }, + { 1, 0, 0, 6, 12, 40, }, + { 0, 0, 0, 6, 13, 63, }, + { 2, 0, 0, 6, 13, 40, }, + { 1, 0, 0, 6, 13, 40, }, + { 0, 0, 0, 6, 14, 63, }, + { 2, 0, 0, 6, 14, 63, }, + { 1, 0, 0, 6, 14, 63, }, + { 0, 0, 0, 7, 1, 46, }, + { 2, 0, 0, 7, 1, 40, }, + { 1, 0, 0, 7, 1, 40, }, + { 0, 0, 0, 7, 2, 46, }, + { 2, 0, 0, 7, 2, 40, }, + { 1, 0, 0, 7, 2, 40, }, + { 0, 0, 0, 7, 3, 46, }, + { 2, 0, 0, 7, 3, 40, }, + { 1, 0, 0, 7, 3, 40, }, + { 0, 0, 0, 7, 4, 46, }, + { 2, 0, 0, 7, 4, 40, }, + { 1, 0, 0, 7, 4, 40, }, + { 0, 0, 0, 7, 5, 46, }, + { 2, 0, 0, 7, 5, 40, }, + { 1, 0, 0, 7, 5, 40, }, + { 0, 0, 0, 7, 6, 46, }, + { 2, 0, 0, 7, 6, 40, }, + { 1, 0, 0, 7, 6, 40, }, + { 0, 0, 0, 7, 7, 46, }, + { 2, 0, 0, 7, 7, 40, }, + { 1, 0, 0, 7, 7, 40, }, + { 0, 0, 0, 7, 8, 46, }, + { 2, 0, 0, 7, 8, 40, }, + { 1, 0, 0, 7, 8, 40, }, + { 0, 0, 0, 7, 9, 46, }, + { 2, 0, 0, 7, 9, 40, }, + { 1, 0, 0, 7, 9, 40, }, + { 0, 0, 0, 7, 10, 46, }, + { 2, 0, 0, 7, 10, 40, }, + { 1, 0, 0, 7, 10, 40, }, + { 0, 0, 0, 7, 11, 46, }, + { 2, 0, 0, 7, 11, 40, }, + { 1, 0, 0, 7, 11, 40, }, + { 0, 0, 0, 7, 12, 63, }, + { 2, 0, 0, 7, 12, 40, }, + { 1, 0, 0, 7, 12, 40, }, + { 0, 0, 0, 7, 13, 63, }, + { 2, 0, 0, 7, 13, 40, }, + { 1, 0, 0, 7, 13, 40, }, + { 0, 0, 0, 7, 14, 63, }, + { 2, 0, 0, 7, 14, 63, }, + { 1, 0, 0, 7, 14, 63, }, + { 0, 0, 1, 2, 1, 63, }, + { 2, 0, 1, 2, 1, 63, }, + { 1, 0, 1, 2, 1, 63, }, + { 0, 0, 1, 2, 2, 63, }, + { 2, 0, 1, 2, 2, 63, }, + { 1, 0, 1, 2, 2, 63, }, + { 0, 0, 1, 2, 3, 46, }, + { 2, 0, 1, 2, 3, 40, }, + { 1, 0, 1, 2, 3, 40, }, + { 0, 0, 1, 2, 4, 46, }, + { 2, 0, 1, 2, 4, 40, }, + { 1, 0, 1, 2, 4, 40, }, + { 0, 0, 1, 2, 5, 46, }, + { 2, 0, 1, 2, 5, 40, }, + { 1, 0, 1, 2, 5, 40, }, + { 0, 0, 1, 2, 6, 46, }, + { 2, 0, 1, 2, 6, 40, }, + { 1, 0, 1, 2, 6, 40, }, + { 0, 0, 1, 2, 7, 46, }, + { 2, 0, 1, 2, 7, 40, }, + { 1, 0, 1, 2, 7, 40, }, + { 0, 0, 1, 2, 8, 46, }, + { 2, 0, 1, 2, 8, 40, }, + { 1, 0, 1, 2, 8, 40, }, + { 0, 0, 1, 2, 9, 46, }, + { 2, 0, 1, 2, 9, 40, }, + { 1, 0, 1, 2, 9, 40, }, + { 0, 0, 1, 2, 10, 46, }, + { 2, 0, 1, 2, 10, 40, }, + { 1, 0, 1, 2, 10, 40, }, + { 0, 0, 1, 2, 11, 46, }, + { 2, 0, 1, 2, 11, 40, }, + { 1, 0, 1, 2, 11, 40, }, + { 0, 0, 1, 2, 12, 63, }, + { 2, 0, 1, 2, 12, 40, }, + { 1, 0, 1, 2, 12, 40, }, + { 0, 0, 1, 2, 13, 63, }, + { 2, 0, 1, 2, 13, 40, }, + { 1, 0, 1, 2, 13, 40, }, + { 0, 0, 1, 2, 14, 63, }, + { 2, 0, 1, 2, 14, 63, }, + { 1, 0, 1, 2, 14, 63, }, + { 0, 0, 1, 3, 1, 63, }, + { 2, 0, 1, 3, 1, 63, }, + { 1, 0, 1, 3, 1, 63, }, + { 0, 0, 1, 3, 2, 63, }, + { 2, 0, 1, 3, 2, 63, }, + { 1, 0, 1, 3, 2, 63, }, + { 0, 0, 1, 3, 3, 46, }, + { 2, 0, 1, 3, 3, 40, }, + { 1, 0, 1, 3, 3, 40, }, + { 0, 0, 1, 3, 4, 46, }, + { 2, 0, 1, 3, 4, 40, }, + { 1, 0, 1, 3, 4, 40, }, + { 0, 0, 1, 3, 5, 46, }, + { 2, 0, 1, 3, 5, 40, }, + { 1, 0, 1, 3, 5, 40, }, + { 0, 0, 1, 3, 6, 46, }, + { 2, 0, 1, 3, 6, 40, }, + { 1, 0, 1, 3, 6, 40, }, + { 0, 0, 1, 3, 7, 46, }, + { 2, 0, 1, 3, 7, 40, }, + { 1, 0, 1, 3, 7, 40, }, + { 0, 0, 1, 3, 8, 46, }, + { 2, 0, 1, 3, 8, 40, }, + { 1, 0, 1, 3, 8, 40, }, + { 0, 0, 1, 3, 9, 46, }, + { 2, 0, 1, 3, 9, 40, }, + { 1, 0, 1, 3, 9, 40, }, + { 0, 0, 1, 3, 10, 46, }, + { 2, 0, 1, 3, 10, 40, }, + { 1, 0, 1, 3, 10, 40, }, + { 0, 0, 1, 3, 11, 46, }, + { 2, 0, 1, 3, 11, 40, }, + { 1, 0, 1, 3, 11, 40, }, + { 0, 0, 1, 3, 12, 63, }, + { 2, 0, 1, 3, 12, 40, }, + { 1, 0, 1, 3, 12, 40, }, + { 0, 0, 1, 3, 13, 63, }, + { 2, 0, 1, 3, 13, 40, }, + { 1, 0, 1, 3, 13, 40, }, + { 0, 0, 1, 3, 14, 63, }, + { 2, 0, 1, 3, 14, 63, }, + { 1, 0, 1, 3, 14, 63, }, + { 0, 0, 1, 6, 1, 63, }, + { 2, 0, 1, 6, 1, 63, }, + { 1, 0, 1, 6, 1, 63, }, + { 0, 0, 1, 6, 2, 63, }, + { 2, 0, 1, 6, 2, 63, }, + { 1, 0, 1, 6, 2, 63, }, + { 0, 0, 1, 6, 3, 46, }, + { 2, 0, 1, 6, 3, 40, }, + { 1, 0, 1, 6, 3, 40, }, + { 0, 0, 1, 6, 4, 46, }, + { 2, 0, 1, 6, 4, 40, }, + { 1, 0, 1, 6, 4, 40, }, + { 0, 0, 1, 6, 5, 46, }, + { 2, 0, 1, 6, 5, 40, }, + { 1, 0, 1, 6, 5, 40, }, + { 0, 0, 1, 6, 6, 46, }, + { 2, 0, 1, 6, 6, 40, }, + { 1, 0, 1, 6, 6, 40, }, + { 0, 0, 1, 6, 7, 46, }, + { 2, 0, 1, 6, 7, 40, }, + { 1, 0, 1, 6, 7, 40, }, + { 0, 0, 1, 6, 8, 46, }, + { 2, 0, 1, 6, 8, 40, }, + { 1, 0, 1, 6, 8, 40, }, + { 0, 0, 1, 6, 9, 46, }, + { 2, 0, 1, 6, 9, 40, }, + { 1, 0, 1, 6, 9, 40, }, + { 0, 0, 1, 6, 10, 46, }, + { 2, 0, 1, 6, 10, 40, }, + { 1, 0, 1, 6, 10, 40, }, + { 0, 0, 1, 6, 11, 46, }, + { 2, 0, 1, 6, 11, 40, }, + { 1, 0, 1, 6, 11, 40, }, + { 0, 0, 1, 6, 12, 63, }, + { 2, 0, 1, 6, 12, 40, }, + { 1, 0, 1, 6, 12, 40, }, + { 0, 0, 1, 6, 13, 63, }, + { 2, 0, 1, 6, 13, 40, }, + { 1, 0, 1, 6, 13, 40, }, + { 0, 0, 1, 6, 14, 63, }, + { 2, 0, 1, 6, 14, 63, }, + { 1, 0, 1, 6, 14, 63, }, + { 0, 0, 1, 7, 1, 63, }, + { 2, 0, 1, 7, 1, 63, }, + { 1, 0, 1, 7, 1, 63, }, + { 0, 0, 1, 7, 2, 63, }, + { 2, 0, 1, 7, 2, 63, }, + { 1, 0, 1, 7, 2, 63, }, + { 0, 0, 1, 7, 3, 46, }, + { 2, 0, 1, 7, 3, 40, }, + { 1, 0, 1, 7, 3, 40, }, + { 0, 0, 1, 7, 4, 46, }, + { 2, 0, 1, 7, 4, 40, }, + { 1, 0, 1, 7, 4, 40, }, + { 0, 0, 1, 7, 5, 46, }, + { 2, 0, 1, 7, 5, 40, }, + { 1, 0, 1, 7, 5, 40, }, + { 0, 0, 1, 7, 6, 46, }, + { 2, 0, 1, 7, 6, 40, }, + { 1, 0, 1, 7, 6, 40, }, + { 0, 0, 1, 7, 7, 46, }, + { 2, 0, 1, 7, 7, 40, }, + { 1, 0, 1, 7, 7, 40, }, + { 0, 0, 1, 7, 8, 46, }, + { 2, 0, 1, 7, 8, 40, }, + { 1, 0, 1, 7, 8, 40, }, + { 0, 0, 1, 7, 9, 46, }, + { 2, 0, 1, 7, 9, 40, }, + { 1, 0, 1, 7, 9, 40, }, + { 0, 0, 1, 7, 10, 46, }, + { 2, 0, 1, 7, 10, 40, }, + { 1, 0, 1, 7, 10, 40, }, + { 0, 0, 1, 7, 11, 46, }, + { 2, 0, 1, 7, 11, 40, }, + { 1, 0, 1, 7, 11, 40, }, + { 0, 0, 1, 7, 12, 63, }, + { 2, 0, 1, 7, 12, 40, }, + { 1, 0, 1, 7, 12, 40, }, + { 0, 0, 1, 7, 13, 63, }, + { 2, 0, 1, 7, 13, 40, }, + { 1, 0, 1, 7, 13, 40, }, + { 0, 0, 1, 7, 14, 63, }, + { 2, 0, 1, 7, 14, 63, }, + { 1, 0, 1, 7, 14, 63, }, + { 0, 1, 0, 1, 36, 46, }, + { 2, 1, 0, 1, 36, 40, }, + { 1, 1, 0, 1, 36, 40, }, + { 0, 1, 0, 1, 40, 46, }, + { 2, 1, 0, 1, 40, 40, }, + { 1, 1, 0, 1, 40, 40, }, + { 0, 1, 0, 1, 44, 46, }, + { 2, 1, 0, 1, 44, 40, }, + { 1, 1, 0, 1, 44, 40, }, + { 0, 1, 0, 1, 48, 46, }, + { 2, 1, 0, 1, 48, 40, }, + { 1, 1, 0, 1, 48, 40, }, + { 0, 1, 0, 1, 52, 46, }, + { 2, 1, 0, 1, 52, 40, }, + { 1, 1, 0, 1, 52, 40, }, + { 0, 1, 0, 1, 56, 46, }, + { 2, 1, 0, 1, 56, 40, }, + { 1, 1, 0, 1, 56, 40, }, + { 0, 1, 0, 1, 60, 46, }, + { 2, 1, 0, 1, 60, 40, }, + { 1, 1, 0, 1, 60, 40, }, + { 0, 1, 0, 1, 64, 46, }, + { 2, 1, 0, 1, 64, 40, }, + { 1, 1, 0, 1, 64, 40, }, + { 0, 1, 0, 1, 100, 46, }, + { 2, 1, 0, 1, 100, 40, }, + { 1, 1, 0, 1, 100, 40, }, + { 0, 1, 0, 1, 104, 46, }, + { 2, 1, 0, 1, 104, 40, }, + { 1, 1, 0, 1, 104, 40, }, + { 0, 1, 0, 1, 108, 46, }, + { 2, 1, 0, 1, 108, 40, }, + { 1, 1, 0, 1, 108, 40, }, + { 0, 1, 0, 1, 112, 46, }, + { 2, 1, 0, 1, 112, 40, }, + { 1, 1, 0, 1, 112, 40, }, + { 0, 1, 0, 1, 116, 46, }, + { 2, 1, 0, 1, 116, 40, }, + { 1, 1, 0, 1, 116, 40, }, + { 0, 1, 0, 1, 120, 46, }, + { 2, 1, 0, 1, 120, 40, }, + { 1, 1, 0, 1, 120, 40, }, + { 0, 1, 0, 1, 124, 46, }, + { 2, 1, 0, 1, 124, 40, }, + { 1, 1, 0, 1, 124, 40, }, + { 0, 1, 0, 1, 128, 46, }, + { 2, 1, 0, 1, 128, 40, }, + { 1, 1, 0, 1, 128, 40, }, + { 0, 1, 0, 1, 132, 46, }, + { 2, 1, 0, 1, 132, 40, }, + { 1, 1, 0, 1, 132, 40, }, + { 0, 1, 0, 1, 136, 46, }, + { 2, 1, 0, 1, 136, 40, }, + { 1, 1, 0, 1, 136, 40, }, + { 0, 1, 0, 1, 140, 46, }, + { 2, 1, 0, 1, 140, 40, }, + { 1, 1, 0, 1, 140, 40, }, + { 0, 1, 0, 1, 149, 46, }, + { 2, 1, 0, 1, 149, 40, }, + { 1, 1, 0, 1, 149, 63, }, + { 0, 1, 0, 1, 153, 46, }, + { 2, 1, 0, 1, 153, 40, }, + { 1, 1, 0, 1, 153, 63, }, + { 0, 1, 0, 1, 157, 46, }, + { 2, 1, 0, 1, 157, 40, }, + { 1, 1, 0, 1, 157, 63, }, + { 0, 1, 0, 1, 161, 46, }, + { 2, 1, 0, 1, 161, 40, }, + { 1, 1, 0, 1, 161, 63, }, + { 0, 1, 0, 1, 165, 46, }, + { 2, 1, 0, 1, 165, 40, }, + { 1, 1, 0, 1, 165, 63, }, + { 0, 1, 0, 2, 36, 46, }, + { 2, 1, 0, 2, 36, 40, }, + { 1, 1, 0, 2, 36, 40, }, + { 0, 1, 0, 2, 40, 46, }, + { 2, 1, 0, 2, 40, 40, }, + { 1, 1, 0, 2, 40, 40, }, + { 0, 1, 0, 2, 44, 46, }, + { 2, 1, 0, 2, 44, 40, }, + { 1, 1, 0, 2, 44, 40, }, + { 0, 1, 0, 2, 48, 46, }, + { 2, 1, 0, 2, 48, 40, }, + { 1, 1, 0, 2, 48, 40, }, + { 0, 1, 0, 2, 52, 46, }, + { 2, 1, 0, 2, 52, 40, }, + { 1, 1, 0, 2, 52, 40, }, + { 0, 1, 0, 2, 56, 46, }, + { 2, 1, 0, 2, 56, 40, }, + { 1, 1, 0, 2, 56, 40, }, + { 0, 1, 0, 2, 60, 46, }, + { 2, 1, 0, 2, 60, 40, }, + { 1, 1, 0, 2, 60, 40, }, + { 0, 1, 0, 2, 64, 46, }, + { 2, 1, 0, 2, 64, 40, }, + { 1, 1, 0, 2, 64, 40, }, + { 0, 1, 0, 2, 100, 46, }, + { 2, 1, 0, 2, 100, 40, }, + { 1, 1, 0, 2, 100, 40, }, + { 0, 1, 0, 2, 104, 46, }, + { 2, 1, 0, 2, 104, 40, }, + { 1, 1, 0, 2, 104, 40, }, + { 0, 1, 0, 2, 108, 46, }, + { 2, 1, 0, 2, 108, 40, }, + { 1, 1, 0, 2, 108, 40, }, + { 0, 1, 0, 2, 112, 46, }, + { 2, 1, 0, 2, 112, 40, }, + { 1, 1, 0, 2, 112, 40, }, + { 0, 1, 0, 2, 116, 46, }, + { 2, 1, 0, 2, 116, 40, }, + { 1, 1, 0, 2, 116, 40, }, + { 0, 1, 0, 2, 120, 46, }, + { 2, 1, 0, 2, 120, 40, }, + { 1, 1, 0, 2, 120, 40, }, + { 0, 1, 0, 2, 124, 46, }, + { 2, 1, 0, 2, 124, 40, }, + { 1, 1, 0, 2, 124, 40, }, + { 0, 1, 0, 2, 128, 46, }, + { 2, 1, 0, 2, 128, 40, }, + { 1, 1, 0, 2, 128, 40, }, + { 0, 1, 0, 2, 132, 46, }, + { 2, 1, 0, 2, 132, 40, }, + { 1, 1, 0, 2, 132, 40, }, + { 0, 1, 0, 2, 136, 46, }, + { 2, 1, 0, 2, 136, 40, }, + { 1, 1, 0, 2, 136, 40, }, + { 0, 1, 0, 2, 140, 46, }, + { 2, 1, 0, 2, 140, 40, }, + { 1, 1, 0, 2, 140, 40, }, + { 0, 1, 0, 2, 149, 46, }, + { 2, 1, 0, 2, 149, 40, }, + { 1, 1, 0, 2, 149, 63, }, + { 0, 1, 0, 2, 153, 46, }, + { 2, 1, 0, 2, 153, 40, }, + { 1, 1, 0, 2, 153, 63, }, + { 0, 1, 0, 2, 157, 46, }, + { 2, 1, 0, 2, 157, 40, }, + { 1, 1, 0, 2, 157, 63, }, + { 0, 1, 0, 2, 161, 46, }, + { 2, 1, 0, 2, 161, 40, }, + { 1, 1, 0, 2, 161, 63, }, + { 0, 1, 0, 2, 165, 46, }, + { 2, 1, 0, 2, 165, 40, }, + { 1, 1, 0, 2, 165, 63, }, + { 0, 1, 0, 3, 36, 46, }, + { 2, 1, 0, 3, 36, 40, }, + { 1, 1, 0, 3, 36, 40, }, + { 0, 1, 0, 3, 40, 46, }, + { 2, 1, 0, 3, 40, 40, }, + { 1, 1, 0, 3, 40, 40, }, + { 0, 1, 0, 3, 44, 46, }, + { 2, 1, 0, 3, 44, 40, }, + { 1, 1, 0, 3, 44, 40, }, + { 0, 1, 0, 3, 48, 46, }, + { 2, 1, 0, 3, 48, 40, }, + { 1, 1, 0, 3, 48, 40, }, + { 0, 1, 0, 3, 52, 46, }, + { 2, 1, 0, 3, 52, 40, }, + { 1, 1, 0, 3, 52, 40, }, + { 0, 1, 0, 3, 56, 46, }, + { 2, 1, 0, 3, 56, 40, }, + { 1, 1, 0, 3, 56, 40, }, + { 0, 1, 0, 3, 60, 46, }, + { 2, 1, 0, 3, 60, 40, }, + { 1, 1, 0, 3, 60, 40, }, + { 0, 1, 0, 3, 64, 46, }, + { 2, 1, 0, 3, 64, 40, }, + { 1, 1, 0, 3, 64, 40, }, + { 0, 1, 0, 3, 100, 46, }, + { 2, 1, 0, 3, 100, 40, }, + { 1, 1, 0, 3, 100, 40, }, + { 0, 1, 0, 3, 104, 46, }, + { 2, 1, 0, 3, 104, 40, }, + { 1, 1, 0, 3, 104, 40, }, + { 0, 1, 0, 3, 108, 46, }, + { 2, 1, 0, 3, 108, 40, }, + { 1, 1, 0, 3, 108, 40, }, + { 0, 1, 0, 3, 112, 46, }, + { 2, 1, 0, 3, 112, 40, }, + { 1, 1, 0, 3, 112, 40, }, + { 0, 1, 0, 3, 116, 46, }, + { 2, 1, 0, 3, 116, 40, }, + { 1, 1, 0, 3, 116, 40, }, + { 0, 1, 0, 3, 120, 46, }, + { 2, 1, 0, 3, 120, 40, }, + { 1, 1, 0, 3, 120, 40, }, + { 0, 1, 0, 3, 124, 46, }, + { 2, 1, 0, 3, 124, 40, }, + { 1, 1, 0, 3, 124, 40, }, + { 0, 1, 0, 3, 128, 46, }, + { 2, 1, 0, 3, 128, 40, }, + { 1, 1, 0, 3, 128, 40, }, + { 0, 1, 0, 3, 132, 46, }, + { 2, 1, 0, 3, 132, 40, }, + { 1, 1, 0, 3, 132, 40, }, + { 0, 1, 0, 3, 136, 46, }, + { 2, 1, 0, 3, 136, 40, }, + { 1, 1, 0, 3, 136, 40, }, + { 0, 1, 0, 3, 140, 46, }, + { 2, 1, 0, 3, 140, 40, }, + { 1, 1, 0, 3, 140, 40, }, + { 0, 1, 0, 3, 149, 46, }, + { 2, 1, 0, 3, 149, 40, }, + { 1, 1, 0, 3, 149, 63, }, + { 0, 1, 0, 3, 153, 46, }, + { 2, 1, 0, 3, 153, 40, }, + { 1, 1, 0, 3, 153, 63, }, + { 0, 1, 0, 3, 157, 46, }, + { 2, 1, 0, 3, 157, 40, }, + { 1, 1, 0, 3, 157, 63, }, + { 0, 1, 0, 3, 161, 46, }, + { 2, 1, 0, 3, 161, 40, }, + { 1, 1, 0, 3, 161, 63, }, + { 0, 1, 0, 3, 165, 46, }, + { 2, 1, 0, 3, 165, 40, }, + { 1, 1, 0, 3, 165, 63, }, + { 0, 1, 0, 6, 36, 46, }, + { 2, 1, 0, 6, 36, 40, }, + { 1, 1, 0, 6, 36, 40, }, + { 0, 1, 0, 6, 40, 46, }, + { 2, 1, 0, 6, 40, 40, }, + { 1, 1, 0, 6, 40, 40, }, + { 0, 1, 0, 6, 44, 46, }, + { 2, 1, 0, 6, 44, 40, }, + { 1, 1, 0, 6, 44, 40, }, + { 0, 1, 0, 6, 48, 46, }, + { 2, 1, 0, 6, 48, 40, }, + { 1, 1, 0, 6, 48, 40, }, + { 0, 1, 0, 6, 52, 46, }, + { 2, 1, 0, 6, 52, 40, }, + { 1, 1, 0, 6, 52, 40, }, + { 0, 1, 0, 6, 56, 46, }, + { 2, 1, 0, 6, 56, 40, }, + { 1, 1, 0, 6, 56, 40, }, + { 0, 1, 0, 6, 60, 46, }, + { 2, 1, 0, 6, 60, 40, }, + { 1, 1, 0, 6, 60, 40, }, + { 0, 1, 0, 6, 64, 46, }, + { 2, 1, 0, 6, 64, 40, }, + { 1, 1, 0, 6, 64, 40, }, + { 0, 1, 0, 6, 100, 46, }, + { 2, 1, 0, 6, 100, 40, }, + { 1, 1, 0, 6, 100, 40, }, + { 0, 1, 0, 6, 104, 46, }, + { 2, 1, 0, 6, 104, 40, }, + { 1, 1, 0, 6, 104, 40, }, + { 0, 1, 0, 6, 108, 46, }, + { 2, 1, 0, 6, 108, 40, }, + { 1, 1, 0, 6, 108, 40, }, + { 0, 1, 0, 6, 112, 46, }, + { 2, 1, 0, 6, 112, 40, }, + { 1, 1, 0, 6, 112, 40, }, + { 0, 1, 0, 6, 116, 46, }, + { 2, 1, 0, 6, 116, 40, }, + { 1, 1, 0, 6, 116, 40, }, + { 0, 1, 0, 6, 120, 46, }, + { 2, 1, 0, 6, 120, 40, }, + { 1, 1, 0, 6, 120, 40, }, + { 0, 1, 0, 6, 124, 46, }, + { 2, 1, 0, 6, 124, 40, }, + { 1, 1, 0, 6, 124, 40, }, + { 0, 1, 0, 6, 128, 46, }, + { 2, 1, 0, 6, 128, 40, }, + { 1, 1, 0, 6, 128, 40, }, + { 0, 1, 0, 6, 132, 46, }, + { 2, 1, 0, 6, 132, 40, }, + { 1, 1, 0, 6, 132, 40, }, + { 0, 1, 0, 6, 136, 46, }, + { 2, 1, 0, 6, 136, 40, }, + { 1, 1, 0, 6, 136, 40, }, + { 0, 1, 0, 6, 140, 46, }, + { 2, 1, 0, 6, 140, 40, }, + { 1, 1, 0, 6, 140, 40, }, + { 0, 1, 0, 6, 149, 46, }, + { 2, 1, 0, 6, 149, 40, }, + { 1, 1, 0, 6, 149, 63, }, + { 0, 1, 0, 6, 153, 46, }, + { 2, 1, 0, 6, 153, 40, }, + { 1, 1, 0, 6, 153, 63, }, + { 0, 1, 0, 6, 157, 46, }, + { 2, 1, 0, 6, 157, 40, }, + { 1, 1, 0, 6, 157, 63, }, + { 0, 1, 0, 6, 161, 46, }, + { 2, 1, 0, 6, 161, 40, }, + { 1, 1, 0, 6, 161, 63, }, + { 0, 1, 0, 6, 165, 46, }, + { 2, 1, 0, 6, 165, 40, }, + { 1, 1, 0, 6, 165, 63, }, + { 0, 1, 0, 7, 36, 46, }, + { 2, 1, 0, 7, 36, 40, }, + { 1, 1, 0, 7, 36, 40, }, + { 0, 1, 0, 7, 40, 46, }, + { 2, 1, 0, 7, 40, 40, }, + { 1, 1, 0, 7, 40, 40, }, + { 0, 1, 0, 7, 44, 46, }, + { 2, 1, 0, 7, 44, 40, }, + { 1, 1, 0, 7, 44, 40, }, + { 0, 1, 0, 7, 48, 46, }, + { 2, 1, 0, 7, 48, 40, }, + { 1, 1, 0, 7, 48, 40, }, + { 0, 1, 0, 7, 52, 46, }, + { 2, 1, 0, 7, 52, 40, }, + { 1, 1, 0, 7, 52, 40, }, + { 0, 1, 0, 7, 56, 46, }, + { 2, 1, 0, 7, 56, 40, }, + { 1, 1, 0, 7, 56, 40, }, + { 0, 1, 0, 7, 60, 46, }, + { 2, 1, 0, 7, 60, 40, }, + { 1, 1, 0, 7, 60, 40, }, + { 0, 1, 0, 7, 64, 46, }, + { 2, 1, 0, 7, 64, 40, }, + { 1, 1, 0, 7, 64, 40, }, + { 0, 1, 0, 7, 100, 46, }, + { 2, 1, 0, 7, 100, 40, }, + { 1, 1, 0, 7, 100, 40, }, + { 0, 1, 0, 7, 104, 46, }, + { 2, 1, 0, 7, 104, 40, }, + { 1, 1, 0, 7, 104, 40, }, + { 0, 1, 0, 7, 108, 46, }, + { 2, 1, 0, 7, 108, 40, }, + { 1, 1, 0, 7, 108, 40, }, + { 0, 1, 0, 7, 112, 46, }, + { 2, 1, 0, 7, 112, 40, }, + { 1, 1, 0, 7, 112, 40, }, + { 0, 1, 0, 7, 116, 46, }, + { 2, 1, 0, 7, 116, 40, }, + { 1, 1, 0, 7, 116, 40, }, + { 0, 1, 0, 7, 120, 46, }, + { 2, 1, 0, 7, 120, 40, }, + { 1, 1, 0, 7, 120, 40, }, + { 0, 1, 0, 7, 124, 46, }, + { 2, 1, 0, 7, 124, 40, }, + { 1, 1, 0, 7, 124, 40, }, + { 0, 1, 0, 7, 128, 46, }, + { 2, 1, 0, 7, 128, 40, }, + { 1, 1, 0, 7, 128, 40, }, + { 0, 1, 0, 7, 132, 46, }, + { 2, 1, 0, 7, 132, 40, }, + { 1, 1, 0, 7, 132, 40, }, + { 0, 1, 0, 7, 136, 46, }, + { 2, 1, 0, 7, 136, 40, }, + { 1, 1, 0, 7, 136, 40, }, + { 0, 1, 0, 7, 140, 46, }, + { 2, 1, 0, 7, 140, 40, }, + { 1, 1, 0, 7, 140, 40, }, + { 0, 1, 0, 7, 149, 46, }, + { 2, 1, 0, 7, 149, 40, }, + { 1, 1, 0, 7, 149, 63, }, + { 0, 1, 0, 7, 153, 46, }, + { 2, 1, 0, 7, 153, 40, }, + { 1, 1, 0, 7, 153, 63, }, + { 0, 1, 0, 7, 157, 46, }, + { 2, 1, 0, 7, 157, 40, }, + { 1, 1, 0, 7, 157, 63, }, + { 0, 1, 0, 7, 161, 46, }, + { 2, 1, 0, 7, 161, 40, }, + { 1, 1, 0, 7, 161, 63, }, + { 0, 1, 0, 7, 165, 46, }, + { 2, 1, 0, 7, 165, 40, }, + { 1, 1, 0, 7, 165, 63, }, + { 0, 1, 1, 2, 38, 46, }, + { 2, 1, 1, 2, 38, 40, }, + { 1, 1, 1, 2, 38, 40, }, + { 0, 1, 1, 2, 46, 46, }, + { 2, 1, 1, 2, 46, 40, }, + { 1, 1, 1, 2, 46, 40, }, + { 0, 1, 1, 2, 54, 46, }, + { 2, 1, 1, 2, 54, 40, }, + { 1, 1, 1, 2, 54, 40, }, + { 0, 1, 1, 2, 62, 46, }, + { 2, 1, 1, 2, 62, 40, }, + { 1, 1, 1, 2, 62, 40, }, + { 0, 1, 1, 2, 102, 46, }, + { 2, 1, 1, 2, 102, 40, }, + { 1, 1, 1, 2, 102, 40, }, + { 0, 1, 1, 2, 110, 46, }, + { 2, 1, 1, 2, 110, 40, }, + { 1, 1, 1, 2, 110, 40, }, + { 0, 1, 1, 2, 118, 46, }, + { 2, 1, 1, 2, 118, 40, }, + { 1, 1, 1, 2, 118, 40, }, + { 0, 1, 1, 2, 126, 46, }, + { 2, 1, 1, 2, 126, 40, }, + { 1, 1, 1, 2, 126, 40, }, + { 0, 1, 1, 2, 134, 46, }, + { 2, 1, 1, 2, 134, 40, }, + { 1, 1, 1, 2, 134, 40, }, + { 0, 1, 1, 2, 151, 46, }, + { 2, 1, 1, 2, 151, 40, }, + { 1, 1, 1, 2, 151, 63, }, + { 0, 1, 1, 2, 159, 46, }, + { 2, 1, 1, 2, 159, 40, }, + { 1, 1, 1, 2, 159, 63, }, + { 0, 1, 1, 3, 38, 46, }, + { 2, 1, 1, 3, 38, 40, }, + { 1, 1, 1, 3, 38, 40, }, + { 0, 1, 1, 3, 46, 46, }, + { 2, 1, 1, 3, 46, 40, }, + { 1, 1, 1, 3, 46, 40, }, + { 0, 1, 1, 3, 54, 46, }, + { 2, 1, 1, 3, 54, 40, }, + { 1, 1, 1, 3, 54, 40, }, + { 0, 1, 1, 3, 62, 46, }, + { 2, 1, 1, 3, 62, 40, }, + { 1, 1, 1, 3, 62, 40, }, + { 0, 1, 1, 3, 102, 46, }, + { 2, 1, 1, 3, 102, 40, }, + { 1, 1, 1, 3, 102, 40, }, + { 0, 1, 1, 3, 110, 46, }, + { 2, 1, 1, 3, 110, 40, }, + { 1, 1, 1, 3, 110, 40, }, + { 0, 1, 1, 3, 118, 46, }, + { 2, 1, 1, 3, 118, 40, }, + { 1, 1, 1, 3, 118, 40, }, + { 0, 1, 1, 3, 126, 46, }, + { 2, 1, 1, 3, 126, 40, }, + { 1, 1, 1, 3, 126, 40, }, + { 0, 1, 1, 3, 134, 46, }, + { 2, 1, 1, 3, 134, 40, }, + { 1, 1, 1, 3, 134, 40, }, + { 0, 1, 1, 3, 151, 46, }, + { 2, 1, 1, 3, 151, 40, }, + { 1, 1, 1, 3, 151, 63, }, + { 0, 1, 1, 3, 159, 46, }, + { 2, 1, 1, 3, 159, 40, }, + { 1, 1, 1, 3, 159, 63, }, + { 0, 1, 1, 6, 38, 46, }, + { 2, 1, 1, 6, 38, 40, }, + { 1, 1, 1, 6, 38, 40, }, + { 0, 1, 1, 6, 46, 46, }, + { 2, 1, 1, 6, 46, 40, }, + { 1, 1, 1, 6, 46, 40, }, + { 0, 1, 1, 6, 54, 46, }, + { 2, 1, 1, 6, 54, 40, }, + { 1, 1, 1, 6, 54, 40, }, + { 0, 1, 1, 6, 62, 46, }, + { 2, 1, 1, 6, 62, 40, }, + { 1, 1, 1, 6, 62, 40, }, + { 0, 1, 1, 6, 102, 46, }, + { 2, 1, 1, 6, 102, 40, }, + { 1, 1, 1, 6, 102, 40, }, + { 0, 1, 1, 6, 110, 46, }, + { 2, 1, 1, 6, 110, 40, }, + { 1, 1, 1, 6, 110, 40, }, + { 0, 1, 1, 6, 118, 46, }, + { 2, 1, 1, 6, 118, 40, }, + { 1, 1, 1, 6, 118, 40, }, + { 0, 1, 1, 6, 126, 46, }, + { 2, 1, 1, 6, 126, 40, }, + { 1, 1, 1, 6, 126, 40, }, + { 0, 1, 1, 6, 134, 46, }, + { 2, 1, 1, 6, 134, 40, }, + { 1, 1, 1, 6, 134, 40, }, + { 0, 1, 1, 6, 151, 46, }, + { 2, 1, 1, 6, 151, 40, }, + { 1, 1, 1, 6, 151, 63, }, + { 0, 1, 1, 6, 159, 46, }, + { 2, 1, 1, 6, 159, 40, }, + { 1, 1, 1, 6, 159, 63, }, + { 0, 1, 1, 7, 38, 46, }, + { 2, 1, 1, 7, 38, 40, }, + { 1, 1, 1, 7, 38, 40, }, + { 0, 1, 1, 7, 46, 46, }, + { 2, 1, 1, 7, 46, 40, }, + { 1, 1, 1, 7, 46, 40, }, + { 0, 1, 1, 7, 54, 46, }, + { 2, 1, 1, 7, 54, 40, }, + { 1, 1, 1, 7, 54, 40, }, + { 0, 1, 1, 7, 62, 46, }, + { 2, 1, 1, 7, 62, 40, }, + { 1, 1, 1, 7, 62, 40, }, + { 0, 1, 1, 7, 102, 46, }, + { 2, 1, 1, 7, 102, 40, }, + { 1, 1, 1, 7, 102, 40, }, + { 0, 1, 1, 7, 110, 46, }, + { 2, 1, 1, 7, 110, 40, }, + { 1, 1, 1, 7, 110, 40, }, + { 0, 1, 1, 7, 118, 46, }, + { 2, 1, 1, 7, 118, 40, }, + { 1, 1, 1, 7, 118, 40, }, + { 0, 1, 1, 7, 126, 46, }, + { 2, 1, 1, 7, 126, 40, }, + { 1, 1, 1, 7, 126, 40, }, + { 0, 1, 1, 7, 134, 46, }, + { 2, 1, 1, 7, 134, 40, }, + { 1, 1, 1, 7, 134, 40, }, + { 0, 1, 1, 7, 151, 46, }, + { 2, 1, 1, 7, 151, 40, }, + { 1, 1, 1, 7, 151, 63, }, + { 0, 1, 1, 7, 159, 46, }, + { 2, 1, 1, 7, 159, 40, }, + { 1, 1, 1, 7, 159, 63, }, + { 0, 1, 2, 4, 42, 46, }, + { 2, 1, 2, 4, 42, 40, }, + { 1, 1, 2, 4, 42, 40, }, + { 0, 1, 2, 4, 58, 46, }, + { 2, 1, 2, 4, 58, 40, }, + { 1, 1, 2, 4, 58, 40, }, + { 0, 1, 2, 4, 106, 46, }, + { 2, 1, 2, 4, 106, 40, }, + { 1, 1, 2, 4, 106, 40, }, + { 0, 1, 2, 4, 122, 46, }, + { 2, 1, 2, 4, 122, 40, }, + { 1, 1, 2, 4, 122, 40, }, + { 0, 1, 2, 4, 155, 46, }, + { 2, 1, 2, 4, 155, 40, }, + { 1, 1, 2, 4, 155, 63, }, + { 0, 1, 2, 5, 42, 46, }, + { 2, 1, 2, 5, 42, 40, }, + { 1, 1, 2, 5, 42, 40, }, + { 0, 1, 2, 5, 58, 46, }, + { 2, 1, 2, 5, 58, 40, }, + { 1, 1, 2, 5, 58, 40, }, + { 0, 1, 2, 5, 106, 46, }, + { 2, 1, 2, 5, 106, 40, }, + { 1, 1, 2, 5, 106, 40, }, + { 0, 1, 2, 5, 122, 46, }, + { 2, 1, 2, 5, 122, 40, }, + { 1, 1, 2, 5, 122, 40, }, + { 0, 1, 2, 5, 155, 46, }, + { 2, 1, 2, 5, 155, 40, }, + { 1, 1, 2, 5, 155, 63, }, + { 0, 1, 2, 8, 42, 46, }, + { 2, 1, 2, 8, 42, 40, }, + { 1, 1, 2, 8, 42, 40, }, + { 0, 1, 2, 8, 58, 46, }, + { 2, 1, 2, 8, 58, 40, }, + { 1, 1, 2, 8, 58, 40, }, + { 0, 1, 2, 8, 106, 46, }, + { 2, 1, 2, 8, 106, 40, }, + { 1, 1, 2, 8, 106, 40, }, + { 0, 1, 2, 8, 122, 46, }, + { 2, 1, 2, 8, 122, 40, }, + { 1, 1, 2, 8, 122, 40, }, + { 0, 1, 2, 8, 155, 46, }, + { 2, 1, 2, 8, 155, 40, }, + { 1, 1, 2, 8, 155, 63, }, + { 0, 1, 2, 9, 42, 46, }, + { 2, 1, 2, 9, 42, 40, }, + { 1, 1, 2, 9, 42, 40, }, + { 0, 1, 2, 9, 58, 46, }, + { 2, 1, 2, 9, 58, 40, }, + { 1, 1, 2, 9, 58, 40, }, + { 0, 1, 2, 9, 106, 46, }, + { 2, 1, 2, 9, 106, 40, }, + { 1, 1, 2, 9, 106, 40, }, + { 0, 1, 2, 9, 122, 46, }, + { 2, 1, 2, 9, 122, 40, }, + { 1, 1, 2, 9, 122, 40, }, + { 0, 1, 2, 9, 155, 46, }, + { 2, 1, 2, 9, 155, 40, }, + { 1, 1, 2, 9, 155, 63, }, +}; + +RTW_DECL_TABLE_TXPWR_LMT(rtw8814a_txpwr_lmt_type5); + +static const struct rtw_txpwr_lmt_cfg_pair rtw8814a_txpwr_lmt_type7[] = { + { 0, 0, 0, 0, 1, 44, }, + { 2, 0, 0, 0, 1, 32, }, + { 1, 0, 0, 0, 1, 32, }, + { 0, 0, 0, 0, 2, 52, }, + { 2, 0, 0, 0, 2, 32, }, + { 1, 0, 0, 0, 2, 32, }, + { 0, 0, 0, 0, 3, 52, }, + { 2, 0, 0, 0, 3, 32, }, + { 1, 0, 0, 0, 3, 32, }, + { 0, 0, 0, 0, 4, 52, }, + { 2, 0, 0, 0, 4, 32, }, + { 1, 0, 0, 0, 4, 32, }, + { 0, 0, 0, 0, 5, 52, }, + { 2, 0, 0, 0, 5, 32, }, + { 1, 0, 0, 0, 5, 32, }, + { 0, 0, 0, 0, 6, 52, }, + { 2, 0, 0, 0, 6, 32, }, + { 1, 0, 0, 0, 6, 32, }, + { 0, 0, 0, 0, 7, 52, }, + { 2, 0, 0, 0, 7, 32, }, + { 1, 0, 0, 0, 7, 32, }, + { 0, 0, 0, 0, 8, 52, }, + { 2, 0, 0, 0, 8, 32, }, + { 1, 0, 0, 0, 8, 32, }, + { 0, 0, 0, 0, 9, 52, }, + { 2, 0, 0, 0, 9, 32, }, + { 1, 0, 0, 0, 9, 32, }, + { 0, 0, 0, 0, 10, 52, }, + { 2, 0, 0, 0, 10, 32, }, + { 1, 0, 0, 0, 10, 32, }, + { 0, 0, 0, 0, 11, 44, }, + { 2, 0, 0, 0, 11, 32, }, + { 1, 0, 0, 0, 11, 32, }, + { 0, 0, 0, 0, 12, 63, }, + { 2, 0, 0, 0, 12, 32, }, + { 1, 0, 0, 0, 12, 32, }, + { 0, 0, 0, 0, 13, 63, }, + { 2, 0, 0, 0, 13, 32, }, + { 1, 0, 0, 0, 13, 32, }, + { 0, 0, 0, 0, 14, 63, }, + { 2, 0, 0, 0, 14, 63, }, + { 1, 0, 0, 0, 14, 32, }, + { 0, 0, 0, 1, 1, 38, }, + { 2, 0, 0, 1, 1, 32, }, + { 1, 0, 0, 1, 1, 32, }, + { 0, 0, 0, 1, 2, 46, }, + { 2, 0, 0, 1, 2, 32, }, + { 1, 0, 0, 1, 2, 32, }, + { 0, 0, 0, 1, 3, 46, }, + { 2, 0, 0, 1, 3, 32, }, + { 1, 0, 0, 1, 3, 32, }, + { 0, 0, 0, 1, 4, 46, }, + { 2, 0, 0, 1, 4, 32, }, + { 1, 0, 0, 1, 4, 32, }, + { 0, 0, 0, 1, 5, 46, }, + { 2, 0, 0, 1, 5, 32, }, + { 1, 0, 0, 1, 5, 32, }, + { 0, 0, 0, 1, 6, 46, }, + { 2, 0, 0, 1, 6, 32, }, + { 1, 0, 0, 1, 6, 32, }, + { 0, 0, 0, 1, 7, 46, }, + { 2, 0, 0, 1, 7, 32, }, + { 1, 0, 0, 1, 7, 32, }, + { 0, 0, 0, 1, 8, 46, }, + { 2, 0, 0, 1, 8, 32, }, + { 1, 0, 0, 1, 8, 32, }, + { 0, 0, 0, 1, 9, 46, }, + { 2, 0, 0, 1, 9, 32, }, + { 1, 0, 0, 1, 9, 32, }, + { 0, 0, 0, 1, 10, 46, }, + { 2, 0, 0, 1, 10, 32, }, + { 1, 0, 0, 1, 10, 32, }, + { 0, 0, 0, 1, 11, 38, }, + { 2, 0, 0, 1, 11, 32, }, + { 1, 0, 0, 1, 11, 32, }, + { 0, 0, 0, 1, 12, 63, }, + { 2, 0, 0, 1, 12, 32, }, + { 1, 0, 0, 1, 12, 32, }, + { 0, 0, 0, 1, 13, 63, }, + { 2, 0, 0, 1, 13, 32, }, + { 1, 0, 0, 1, 13, 32, }, + { 0, 0, 0, 1, 14, 63, }, + { 2, 0, 0, 1, 14, 63, }, + { 1, 0, 0, 1, 14, 63, }, + { 0, 0, 0, 2, 1, 34, }, + { 2, 0, 0, 2, 1, 32, }, + { 1, 0, 0, 2, 1, 32, }, + { 0, 0, 0, 2, 2, 46, }, + { 2, 0, 0, 2, 2, 32, }, + { 1, 0, 0, 2, 2, 32, }, + { 0, 0, 0, 2, 3, 46, }, + { 2, 0, 0, 2, 3, 32, }, + { 1, 0, 0, 2, 3, 32, }, + { 0, 0, 0, 2, 4, 46, }, + { 2, 0, 0, 2, 4, 32, }, + { 1, 0, 0, 2, 4, 32, }, + { 0, 0, 0, 2, 5, 46, }, + { 2, 0, 0, 2, 5, 32, }, + { 1, 0, 0, 2, 5, 32, }, + { 0, 0, 0, 2, 6, 46, }, + { 2, 0, 0, 2, 6, 32, }, + { 1, 0, 0, 2, 6, 32, }, + { 0, 0, 0, 2, 7, 46, }, + { 2, 0, 0, 2, 7, 32, }, + { 1, 0, 0, 2, 7, 32, }, + { 0, 0, 0, 2, 8, 46, }, + { 2, 0, 0, 2, 8, 32, }, + { 1, 0, 0, 2, 8, 32, }, + { 0, 0, 0, 2, 9, 46, }, + { 2, 0, 0, 2, 9, 32, }, + { 1, 0, 0, 2, 9, 32, }, + { 0, 0, 0, 2, 10, 46, }, + { 2, 0, 0, 2, 10, 32, }, + { 1, 0, 0, 2, 10, 32, }, + { 0, 0, 0, 2, 11, 34, }, + { 2, 0, 0, 2, 11, 32, }, + { 1, 0, 0, 2, 11, 32, }, + { 0, 0, 0, 2, 12, 63, }, + { 2, 0, 0, 2, 12, 32, }, + { 1, 0, 0, 2, 12, 32, }, + { 0, 0, 0, 2, 13, 63, }, + { 2, 0, 0, 2, 13, 32, }, + { 1, 0, 0, 2, 13, 32, }, + { 0, 0, 0, 2, 14, 63, }, + { 2, 0, 0, 2, 14, 63, }, + { 1, 0, 0, 2, 14, 63, }, + { 0, 0, 0, 3, 1, 32, }, + { 2, 0, 0, 3, 1, 30, }, + { 1, 0, 0, 3, 1, 30, }, + { 0, 0, 0, 3, 2, 44, }, + { 2, 0, 0, 3, 2, 30, }, + { 1, 0, 0, 3, 2, 30, }, + { 0, 0, 0, 3, 3, 44, }, + { 2, 0, 0, 3, 3, 30, }, + { 1, 0, 0, 3, 3, 30, }, + { 0, 0, 0, 3, 4, 44, }, + { 2, 0, 0, 3, 4, 30, }, + { 1, 0, 0, 3, 4, 30, }, + { 0, 0, 0, 3, 5, 44, }, + { 2, 0, 0, 3, 5, 30, }, + { 1, 0, 0, 3, 5, 30, }, + { 0, 0, 0, 3, 6, 44, }, + { 2, 0, 0, 3, 6, 30, }, + { 1, 0, 0, 3, 6, 30, }, + { 0, 0, 0, 3, 7, 44, }, + { 2, 0, 0, 3, 7, 30, }, + { 1, 0, 0, 3, 7, 30, }, + { 0, 0, 0, 3, 8, 44, }, + { 2, 0, 0, 3, 8, 30, }, + { 1, 0, 0, 3, 8, 30, }, + { 0, 0, 0, 3, 9, 44, }, + { 2, 0, 0, 3, 9, 30, }, + { 1, 0, 0, 3, 9, 30, }, + { 0, 0, 0, 3, 10, 44, }, + { 2, 0, 0, 3, 10, 30, }, + { 1, 0, 0, 3, 10, 30, }, + { 0, 0, 0, 3, 11, 32, }, + { 2, 0, 0, 3, 11, 30, }, + { 1, 0, 0, 3, 11, 30, }, + { 0, 0, 0, 3, 12, 63, }, + { 2, 0, 0, 3, 12, 30, }, + { 1, 0, 0, 3, 12, 30, }, + { 0, 0, 0, 3, 13, 63, }, + { 2, 0, 0, 3, 13, 30, }, + { 1, 0, 0, 3, 13, 30, }, + { 0, 0, 0, 3, 14, 63, }, + { 2, 0, 0, 3, 14, 63, }, + { 1, 0, 0, 3, 14, 63, }, + { 0, 0, 0, 6, 1, 30, }, + { 2, 0, 0, 6, 1, 28, }, + { 1, 0, 0, 6, 1, 28, }, + { 0, 0, 0, 6, 2, 42, }, + { 2, 0, 0, 6, 2, 28, }, + { 1, 0, 0, 6, 2, 28, }, + { 0, 0, 0, 6, 3, 42, }, + { 2, 0, 0, 6, 3, 28, }, + { 1, 0, 0, 6, 3, 28, }, + { 0, 0, 0, 6, 4, 42, }, + { 2, 0, 0, 6, 4, 28, }, + { 1, 0, 0, 6, 4, 28, }, + { 0, 0, 0, 6, 5, 42, }, + { 2, 0, 0, 6, 5, 28, }, + { 1, 0, 0, 6, 5, 28, }, + { 0, 0, 0, 6, 6, 42, }, + { 2, 0, 0, 6, 6, 28, }, + { 1, 0, 0, 6, 6, 28, }, + { 0, 0, 0, 6, 7, 42, }, + { 2, 0, 0, 6, 7, 28, }, + { 1, 0, 0, 6, 7, 28, }, + { 0, 0, 0, 6, 8, 42, }, + { 2, 0, 0, 6, 8, 28, }, + { 1, 0, 0, 6, 8, 28, }, + { 0, 0, 0, 6, 9, 42, }, + { 2, 0, 0, 6, 9, 28, }, + { 1, 0, 0, 6, 9, 28, }, + { 0, 0, 0, 6, 10, 42, }, + { 2, 0, 0, 6, 10, 28, }, + { 1, 0, 0, 6, 10, 28, }, + { 0, 0, 0, 6, 11, 30, }, + { 2, 0, 0, 6, 11, 28, }, + { 1, 0, 0, 6, 11, 28, }, + { 0, 0, 0, 6, 12, 63, }, + { 2, 0, 0, 6, 12, 28, }, + { 1, 0, 0, 6, 12, 28, }, + { 0, 0, 0, 6, 13, 63, }, + { 2, 0, 0, 6, 13, 28, }, + { 1, 0, 0, 6, 13, 28, }, + { 0, 0, 0, 6, 14, 63, }, + { 2, 0, 0, 6, 14, 63, }, + { 1, 0, 0, 6, 14, 63, }, + { 0, 0, 0, 7, 1, 28, }, + { 2, 0, 0, 7, 1, 26, }, + { 1, 0, 0, 7, 1, 26, }, + { 0, 0, 0, 7, 2, 40, }, + { 2, 0, 0, 7, 2, 26, }, + { 1, 0, 0, 7, 2, 26, }, + { 0, 0, 0, 7, 3, 40, }, + { 2, 0, 0, 7, 3, 26, }, + { 1, 0, 0, 7, 3, 26, }, + { 0, 0, 0, 7, 4, 40, }, + { 2, 0, 0, 7, 4, 26, }, + { 1, 0, 0, 7, 4, 26, }, + { 0, 0, 0, 7, 5, 40, }, + { 2, 0, 0, 7, 5, 26, }, + { 1, 0, 0, 7, 5, 26, }, + { 0, 0, 0, 7, 6, 40, }, + { 2, 0, 0, 7, 6, 26, }, + { 1, 0, 0, 7, 6, 26, }, + { 0, 0, 0, 7, 7, 40, }, + { 2, 0, 0, 7, 7, 26, }, + { 1, 0, 0, 7, 7, 26, }, + { 0, 0, 0, 7, 8, 40, }, + { 2, 0, 0, 7, 8, 26, }, + { 1, 0, 0, 7, 8, 26, }, + { 0, 0, 0, 7, 9, 40, }, + { 2, 0, 0, 7, 9, 26, }, + { 1, 0, 0, 7, 9, 26, }, + { 0, 0, 0, 7, 10, 40, }, + { 2, 0, 0, 7, 10, 26, }, + { 1, 0, 0, 7, 10, 26, }, + { 0, 0, 0, 7, 11, 28, }, + { 2, 0, 0, 7, 11, 26, }, + { 1, 0, 0, 7, 11, 26, }, + { 0, 0, 0, 7, 12, 63, }, + { 2, 0, 0, 7, 12, 26, }, + { 1, 0, 0, 7, 12, 26, }, + { 0, 0, 0, 7, 13, 63, }, + { 2, 0, 0, 7, 13, 26, }, + { 1, 0, 0, 7, 13, 26, }, + { 0, 0, 0, 7, 14, 63, }, + { 2, 0, 0, 7, 14, 63, }, + { 1, 0, 0, 7, 14, 63, }, + { 0, 0, 1, 2, 1, 63, }, + { 2, 0, 1, 2, 1, 63, }, + { 1, 0, 1, 2, 1, 63, }, + { 0, 0, 1, 2, 2, 63, }, + { 2, 0, 1, 2, 2, 63, }, + { 1, 0, 1, 2, 2, 63, }, + { 0, 0, 1, 2, 3, 36, }, + { 2, 0, 1, 2, 3, 32, }, + { 1, 0, 1, 2, 3, 32, }, + { 0, 0, 1, 2, 4, 40, }, + { 2, 0, 1, 2, 4, 32, }, + { 1, 0, 1, 2, 4, 32, }, + { 0, 0, 1, 2, 5, 40, }, + { 2, 0, 1, 2, 5, 32, }, + { 1, 0, 1, 2, 5, 32, }, + { 0, 0, 1, 2, 6, 40, }, + { 2, 0, 1, 2, 6, 32, }, + { 1, 0, 1, 2, 6, 32, }, + { 0, 0, 1, 2, 7, 40, }, + { 2, 0, 1, 2, 7, 32, }, + { 1, 0, 1, 2, 7, 32, }, + { 0, 0, 1, 2, 8, 40, }, + { 2, 0, 1, 2, 8, 32, }, + { 1, 0, 1, 2, 8, 32, }, + { 0, 0, 1, 2, 9, 40, }, + { 2, 0, 1, 2, 9, 32, }, + { 1, 0, 1, 2, 9, 32, }, + { 0, 0, 1, 2, 10, 40, }, + { 2, 0, 1, 2, 10, 32, }, + { 1, 0, 1, 2, 10, 32, }, + { 0, 0, 1, 2, 11, 34, }, + { 2, 0, 1, 2, 11, 32, }, + { 1, 0, 1, 2, 11, 32, }, + { 0, 0, 1, 2, 12, 63, }, + { 2, 0, 1, 2, 12, 32, }, + { 1, 0, 1, 2, 12, 32, }, + { 0, 0, 1, 2, 13, 63, }, + { 2, 0, 1, 2, 13, 32, }, + { 1, 0, 1, 2, 13, 32, }, + { 0, 0, 1, 2, 14, 63, }, + { 2, 0, 1, 2, 14, 63, }, + { 1, 0, 1, 2, 14, 63, }, + { 0, 0, 1, 3, 1, 63, }, + { 2, 0, 1, 3, 1, 63, }, + { 1, 0, 1, 3, 1, 63, }, + { 0, 0, 1, 3, 2, 63, }, + { 2, 0, 1, 3, 2, 63, }, + { 1, 0, 1, 3, 2, 63, }, + { 0, 0, 1, 3, 3, 34, }, + { 2, 0, 1, 3, 3, 30, }, + { 1, 0, 1, 3, 3, 30, }, + { 0, 0, 1, 3, 4, 38, }, + { 2, 0, 1, 3, 4, 30, }, + { 1, 0, 1, 3, 4, 30, }, + { 0, 0, 1, 3, 5, 38, }, + { 2, 0, 1, 3, 5, 30, }, + { 1, 0, 1, 3, 5, 30, }, + { 0, 0, 1, 3, 6, 38, }, + { 2, 0, 1, 3, 6, 30, }, + { 1, 0, 1, 3, 6, 30, }, + { 0, 0, 1, 3, 7, 38, }, + { 2, 0, 1, 3, 7, 30, }, + { 1, 0, 1, 3, 7, 30, }, + { 0, 0, 1, 3, 8, 38, }, + { 2, 0, 1, 3, 8, 30, }, + { 1, 0, 1, 3, 8, 30, }, + { 0, 0, 1, 3, 9, 38, }, + { 2, 0, 1, 3, 9, 30, }, + { 1, 0, 1, 3, 9, 30, }, + { 0, 0, 1, 3, 10, 38, }, + { 2, 0, 1, 3, 10, 30, }, + { 1, 0, 1, 3, 10, 30, }, + { 0, 0, 1, 3, 11, 32, }, + { 2, 0, 1, 3, 11, 30, }, + { 1, 0, 1, 3, 11, 30, }, + { 0, 0, 1, 3, 12, 63, }, + { 2, 0, 1, 3, 12, 30, }, + { 1, 0, 1, 3, 12, 30, }, + { 0, 0, 1, 3, 13, 63, }, + { 2, 0, 1, 3, 13, 30, }, + { 1, 0, 1, 3, 13, 30, }, + { 0, 0, 1, 3, 14, 63, }, + { 2, 0, 1, 3, 14, 63, }, + { 1, 0, 1, 3, 14, 63, }, + { 0, 0, 1, 6, 1, 63, }, + { 2, 0, 1, 6, 1, 63, }, + { 1, 0, 1, 6, 1, 63, }, + { 0, 0, 1, 6, 2, 63, }, + { 2, 0, 1, 6, 2, 63, }, + { 1, 0, 1, 6, 2, 63, }, + { 0, 0, 1, 6, 3, 32, }, + { 2, 0, 1, 6, 3, 28, }, + { 1, 0, 1, 6, 3, 28, }, + { 0, 0, 1, 6, 4, 36, }, + { 2, 0, 1, 6, 4, 28, }, + { 1, 0, 1, 6, 4, 28, }, + { 0, 0, 1, 6, 5, 36, }, + { 2, 0, 1, 6, 5, 28, }, + { 1, 0, 1, 6, 5, 28, }, + { 0, 0, 1, 6, 6, 36, }, + { 2, 0, 1, 6, 6, 28, }, + { 1, 0, 1, 6, 6, 28, }, + { 0, 0, 1, 6, 7, 36, }, + { 2, 0, 1, 6, 7, 28, }, + { 1, 0, 1, 6, 7, 28, }, + { 0, 0, 1, 6, 8, 36, }, + { 2, 0, 1, 6, 8, 28, }, + { 1, 0, 1, 6, 8, 28, }, + { 0, 0, 1, 6, 9, 36, }, + { 2, 0, 1, 6, 9, 28, }, + { 1, 0, 1, 6, 9, 28, }, + { 0, 0, 1, 6, 10, 36, }, + { 2, 0, 1, 6, 10, 28, }, + { 1, 0, 1, 6, 10, 28, }, + { 0, 0, 1, 6, 11, 30, }, + { 2, 0, 1, 6, 11, 28, }, + { 1, 0, 1, 6, 11, 28, }, + { 0, 0, 1, 6, 12, 63, }, + { 2, 0, 1, 6, 12, 28, }, + { 1, 0, 1, 6, 12, 28, }, + { 0, 0, 1, 6, 13, 63, }, + { 2, 0, 1, 6, 13, 28, }, + { 1, 0, 1, 6, 13, 28, }, + { 0, 0, 1, 6, 14, 63, }, + { 2, 0, 1, 6, 14, 63, }, + { 1, 0, 1, 6, 14, 63, }, + { 0, 0, 1, 7, 1, 63, }, + { 2, 0, 1, 7, 1, 63, }, + { 1, 0, 1, 7, 1, 63, }, + { 0, 0, 1, 7, 2, 63, }, + { 2, 0, 1, 7, 2, 63, }, + { 1, 0, 1, 7, 2, 63, }, + { 0, 0, 1, 7, 3, 32, }, + { 2, 0, 1, 7, 3, 26, }, + { 1, 0, 1, 7, 3, 26, }, + { 0, 0, 1, 7, 4, 36, }, + { 2, 0, 1, 7, 4, 26, }, + { 1, 0, 1, 7, 4, 26, }, + { 0, 0, 1, 7, 5, 36, }, + { 2, 0, 1, 7, 5, 26, }, + { 1, 0, 1, 7, 5, 26, }, + { 0, 0, 1, 7, 6, 36, }, + { 2, 0, 1, 7, 6, 26, }, + { 1, 0, 1, 7, 6, 26, }, + { 0, 0, 1, 7, 7, 36, }, + { 2, 0, 1, 7, 7, 26, }, + { 1, 0, 1, 7, 7, 26, }, + { 0, 0, 1, 7, 8, 36, }, + { 2, 0, 1, 7, 8, 26, }, + { 1, 0, 1, 7, 8, 26, }, + { 0, 0, 1, 7, 9, 36, }, + { 2, 0, 1, 7, 9, 26, }, + { 1, 0, 1, 7, 9, 26, }, + { 0, 0, 1, 7, 10, 36, }, + { 2, 0, 1, 7, 10, 26, }, + { 1, 0, 1, 7, 10, 26, }, + { 0, 0, 1, 7, 11, 30, }, + { 2, 0, 1, 7, 11, 26, }, + { 1, 0, 1, 7, 11, 26, }, + { 0, 0, 1, 7, 12, 63, }, + { 2, 0, 1, 7, 12, 26, }, + { 1, 0, 1, 7, 12, 26, }, + { 0, 0, 1, 7, 13, 63, }, + { 2, 0, 1, 7, 13, 26, }, + { 1, 0, 1, 7, 13, 26, }, + { 0, 0, 1, 7, 14, 63, }, + { 2, 0, 1, 7, 14, 63, }, + { 1, 0, 1, 7, 14, 63, }, + { 0, 1, 0, 1, 36, 38, }, + { 2, 1, 0, 1, 36, 32, }, + { 1, 1, 0, 1, 36, 32, }, + { 0, 1, 0, 1, 40, 38, }, + { 2, 1, 0, 1, 40, 32, }, + { 1, 1, 0, 1, 40, 32, }, + { 0, 1, 0, 1, 44, 38, }, + { 2, 1, 0, 1, 44, 32, }, + { 1, 1, 0, 1, 44, 32, }, + { 0, 1, 0, 1, 48, 38, }, + { 2, 1, 0, 1, 48, 32, }, + { 1, 1, 0, 1, 48, 32, }, + { 0, 1, 0, 1, 52, 38, }, + { 2, 1, 0, 1, 52, 32, }, + { 1, 1, 0, 1, 52, 32, }, + { 0, 1, 0, 1, 56, 38, }, + { 2, 1, 0, 1, 56, 32, }, + { 1, 1, 0, 1, 56, 32, }, + { 0, 1, 0, 1, 60, 38, }, + { 2, 1, 0, 1, 60, 32, }, + { 1, 1, 0, 1, 60, 32, }, + { 0, 1, 0, 1, 64, 38, }, + { 2, 1, 0, 1, 64, 32, }, + { 1, 1, 0, 1, 64, 32, }, + { 0, 1, 0, 1, 100, 36, }, + { 2, 1, 0, 1, 100, 32, }, + { 1, 1, 0, 1, 100, 32, }, + { 0, 1, 0, 1, 104, 36, }, + { 2, 1, 0, 1, 104, 32, }, + { 1, 1, 0, 1, 104, 32, }, + { 0, 1, 0, 1, 108, 36, }, + { 2, 1, 0, 1, 108, 32, }, + { 1, 1, 0, 1, 108, 32, }, + { 0, 1, 0, 1, 112, 36, }, + { 2, 1, 0, 1, 112, 32, }, + { 1, 1, 0, 1, 112, 32, }, + { 0, 1, 0, 1, 116, 36, }, + { 2, 1, 0, 1, 116, 32, }, + { 1, 1, 0, 1, 116, 32, }, + { 0, 1, 0, 1, 120, 36, }, + { 2, 1, 0, 1, 120, 32, }, + { 1, 1, 0, 1, 120, 32, }, + { 0, 1, 0, 1, 124, 36, }, + { 2, 1, 0, 1, 124, 32, }, + { 1, 1, 0, 1, 124, 32, }, + { 0, 1, 0, 1, 128, 36, }, + { 2, 1, 0, 1, 128, 32, }, + { 1, 1, 0, 1, 128, 32, }, + { 0, 1, 0, 1, 132, 36, }, + { 2, 1, 0, 1, 132, 32, }, + { 1, 1, 0, 1, 132, 32, }, + { 0, 1, 0, 1, 136, 36, }, + { 2, 1, 0, 1, 136, 32, }, + { 1, 1, 0, 1, 136, 32, }, + { 0, 1, 0, 1, 140, 36, }, + { 2, 1, 0, 1, 140, 32, }, + { 1, 1, 0, 1, 140, 32, }, + { 0, 1, 0, 1, 149, 36, }, + { 2, 1, 0, 1, 149, 32, }, + { 1, 1, 0, 1, 149, 63, }, + { 0, 1, 0, 1, 153, 36, }, + { 2, 1, 0, 1, 153, 32, }, + { 1, 1, 0, 1, 153, 63, }, + { 0, 1, 0, 1, 157, 36, }, + { 2, 1, 0, 1, 157, 32, }, + { 1, 1, 0, 1, 157, 63, }, + { 0, 1, 0, 1, 161, 36, }, + { 2, 1, 0, 1, 161, 32, }, + { 1, 1, 0, 1, 161, 63, }, + { 0, 1, 0, 1, 165, 36, }, + { 2, 1, 0, 1, 165, 32, }, + { 1, 1, 0, 1, 165, 63, }, + { 0, 1, 0, 2, 36, 36, }, + { 2, 1, 0, 2, 36, 32, }, + { 1, 1, 0, 2, 36, 32, }, + { 0, 1, 0, 2, 40, 36, }, + { 2, 1, 0, 2, 40, 32, }, + { 1, 1, 0, 2, 40, 32, }, + { 0, 1, 0, 2, 44, 36, }, + { 2, 1, 0, 2, 44, 32, }, + { 1, 1, 0, 2, 44, 32, }, + { 0, 1, 0, 2, 48, 36, }, + { 2, 1, 0, 2, 48, 32, }, + { 1, 1, 0, 2, 48, 32, }, + { 0, 1, 0, 2, 52, 36, }, + { 2, 1, 0, 2, 52, 32, }, + { 1, 1, 0, 2, 52, 32, }, + { 0, 1, 0, 2, 56, 36, }, + { 2, 1, 0, 2, 56, 32, }, + { 1, 1, 0, 2, 56, 32, }, + { 0, 1, 0, 2, 60, 36, }, + { 2, 1, 0, 2, 60, 32, }, + { 1, 1, 0, 2, 60, 32, }, + { 0, 1, 0, 2, 64, 36, }, + { 2, 1, 0, 2, 64, 32, }, + { 1, 1, 0, 2, 64, 32, }, + { 0, 1, 0, 2, 100, 36, }, + { 2, 1, 0, 2, 100, 32, }, + { 1, 1, 0, 2, 100, 32, }, + { 0, 1, 0, 2, 104, 36, }, + { 2, 1, 0, 2, 104, 32, }, + { 1, 1, 0, 2, 104, 32, }, + { 0, 1, 0, 2, 108, 36, }, + { 2, 1, 0, 2, 108, 32, }, + { 1, 1, 0, 2, 108, 32, }, + { 0, 1, 0, 2, 112, 36, }, + { 2, 1, 0, 2, 112, 32, }, + { 1, 1, 0, 2, 112, 32, }, + { 0, 1, 0, 2, 116, 36, }, + { 2, 1, 0, 2, 116, 32, }, + { 1, 1, 0, 2, 116, 32, }, + { 0, 1, 0, 2, 120, 36, }, + { 2, 1, 0, 2, 120, 32, }, + { 1, 1, 0, 2, 120, 32, }, + { 0, 1, 0, 2, 124, 36, }, + { 2, 1, 0, 2, 124, 32, }, + { 1, 1, 0, 2, 124, 32, }, + { 0, 1, 0, 2, 128, 36, }, + { 2, 1, 0, 2, 128, 32, }, + { 1, 1, 0, 2, 128, 32, }, + { 0, 1, 0, 2, 132, 36, }, + { 2, 1, 0, 2, 132, 32, }, + { 1, 1, 0, 2, 132, 32, }, + { 0, 1, 0, 2, 136, 36, }, + { 2, 1, 0, 2, 136, 32, }, + { 1, 1, 0, 2, 136, 32, }, + { 0, 1, 0, 2, 140, 34, }, + { 2, 1, 0, 2, 140, 32, }, + { 1, 1, 0, 2, 140, 32, }, + { 0, 1, 0, 2, 149, 32, }, + { 2, 1, 0, 2, 149, 32, }, + { 1, 1, 0, 2, 149, 63, }, + { 0, 1, 0, 2, 153, 38, }, + { 2, 1, 0, 2, 153, 32, }, + { 1, 1, 0, 2, 153, 63, }, + { 0, 1, 0, 2, 157, 38, }, + { 2, 1, 0, 2, 157, 32, }, + { 1, 1, 0, 2, 157, 63, }, + { 0, 1, 0, 2, 161, 38, }, + { 2, 1, 0, 2, 161, 32, }, + { 1, 1, 0, 2, 161, 63, }, + { 0, 1, 0, 2, 165, 38, }, + { 2, 1, 0, 2, 165, 32, }, + { 1, 1, 0, 2, 165, 63, }, + { 0, 1, 0, 3, 36, 34, }, + { 2, 1, 0, 3, 36, 30, }, + { 1, 1, 0, 3, 36, 30, }, + { 0, 1, 0, 3, 40, 34, }, + { 2, 1, 0, 3, 40, 30, }, + { 1, 1, 0, 3, 40, 30, }, + { 0, 1, 0, 3, 44, 34, }, + { 2, 1, 0, 3, 44, 30, }, + { 1, 1, 0, 3, 44, 30, }, + { 0, 1, 0, 3, 48, 34, }, + { 2, 1, 0, 3, 48, 30, }, + { 1, 1, 0, 3, 48, 30, }, + { 0, 1, 0, 3, 52, 34, }, + { 2, 1, 0, 3, 52, 30, }, + { 1, 1, 0, 3, 52, 30, }, + { 0, 1, 0, 3, 56, 34, }, + { 2, 1, 0, 3, 56, 30, }, + { 1, 1, 0, 3, 56, 30, }, + { 0, 1, 0, 3, 60, 34, }, + { 2, 1, 0, 3, 60, 30, }, + { 1, 1, 0, 3, 60, 30, }, + { 0, 1, 0, 3, 64, 34, }, + { 2, 1, 0, 3, 64, 30, }, + { 1, 1, 0, 3, 64, 30, }, + { 0, 1, 0, 3, 100, 34, }, + { 2, 1, 0, 3, 100, 30, }, + { 1, 1, 0, 3, 100, 30, }, + { 0, 1, 0, 3, 104, 34, }, + { 2, 1, 0, 3, 104, 30, }, + { 1, 1, 0, 3, 104, 30, }, + { 0, 1, 0, 3, 108, 34, }, + { 2, 1, 0, 3, 108, 30, }, + { 1, 1, 0, 3, 108, 30, }, + { 0, 1, 0, 3, 112, 34, }, + { 2, 1, 0, 3, 112, 30, }, + { 1, 1, 0, 3, 112, 30, }, + { 0, 1, 0, 3, 116, 34, }, + { 2, 1, 0, 3, 116, 30, }, + { 1, 1, 0, 3, 116, 30, }, + { 0, 1, 0, 3, 120, 34, }, + { 2, 1, 0, 3, 120, 30, }, + { 1, 1, 0, 3, 120, 30, }, + { 0, 1, 0, 3, 124, 34, }, + { 2, 1, 0, 3, 124, 30, }, + { 1, 1, 0, 3, 124, 30, }, + { 0, 1, 0, 3, 128, 34, }, + { 2, 1, 0, 3, 128, 30, }, + { 1, 1, 0, 3, 128, 30, }, + { 0, 1, 0, 3, 132, 34, }, + { 2, 1, 0, 3, 132, 30, }, + { 1, 1, 0, 3, 132, 30, }, + { 0, 1, 0, 3, 136, 34, }, + { 2, 1, 0, 3, 136, 30, }, + { 1, 1, 0, 3, 136, 30, }, + { 0, 1, 0, 3, 140, 32, }, + { 2, 1, 0, 3, 140, 30, }, + { 1, 1, 0, 3, 140, 30, }, + { 0, 1, 0, 3, 149, 30, }, + { 2, 1, 0, 3, 149, 30, }, + { 1, 1, 0, 3, 149, 63, }, + { 0, 1, 0, 3, 153, 36, }, + { 2, 1, 0, 3, 153, 30, }, + { 1, 1, 0, 3, 153, 63, }, + { 0, 1, 0, 3, 157, 36, }, + { 2, 1, 0, 3, 157, 30, }, + { 1, 1, 0, 3, 157, 63, }, + { 0, 1, 0, 3, 161, 36, }, + { 2, 1, 0, 3, 161, 30, }, + { 1, 1, 0, 3, 161, 63, }, + { 0, 1, 0, 3, 165, 36, }, + { 2, 1, 0, 3, 165, 30, }, + { 1, 1, 0, 3, 165, 63, }, + { 0, 1, 0, 6, 36, 32, }, + { 2, 1, 0, 6, 36, 28, }, + { 1, 1, 0, 6, 36, 28, }, + { 0, 1, 0, 6, 40, 32, }, + { 2, 1, 0, 6, 40, 28, }, + { 1, 1, 0, 6, 40, 28, }, + { 0, 1, 0, 6, 44, 32, }, + { 2, 1, 0, 6, 44, 28, }, + { 1, 1, 0, 6, 44, 28, }, + { 0, 1, 0, 6, 48, 32, }, + { 2, 1, 0, 6, 48, 28, }, + { 1, 1, 0, 6, 48, 28, }, + { 0, 1, 0, 6, 52, 32, }, + { 2, 1, 0, 6, 52, 28, }, + { 1, 1, 0, 6, 52, 28, }, + { 0, 1, 0, 6, 56, 32, }, + { 2, 1, 0, 6, 56, 28, }, + { 1, 1, 0, 6, 56, 28, }, + { 0, 1, 0, 6, 60, 32, }, + { 2, 1, 0, 6, 60, 28, }, + { 1, 1, 0, 6, 60, 28, }, + { 0, 1, 0, 6, 64, 32, }, + { 2, 1, 0, 6, 64, 28, }, + { 1, 1, 0, 6, 64, 28, }, + { 0, 1, 0, 6, 100, 32, }, + { 2, 1, 0, 6, 100, 28, }, + { 1, 1, 0, 6, 100, 28, }, + { 0, 1, 0, 6, 104, 32, }, + { 2, 1, 0, 6, 104, 28, }, + { 1, 1, 0, 6, 104, 28, }, + { 0, 1, 0, 6, 108, 32, }, + { 2, 1, 0, 6, 108, 28, }, + { 1, 1, 0, 6, 108, 28, }, + { 0, 1, 0, 6, 112, 32, }, + { 2, 1, 0, 6, 112, 28, }, + { 1, 1, 0, 6, 112, 28, }, + { 0, 1, 0, 6, 116, 32, }, + { 2, 1, 0, 6, 116, 28, }, + { 1, 1, 0, 6, 116, 28, }, + { 0, 1, 0, 6, 120, 32, }, + { 2, 1, 0, 6, 120, 28, }, + { 1, 1, 0, 6, 120, 28, }, + { 0, 1, 0, 6, 124, 32, }, + { 2, 1, 0, 6, 124, 28, }, + { 1, 1, 0, 6, 124, 28, }, + { 0, 1, 0, 6, 128, 32, }, + { 2, 1, 0, 6, 128, 28, }, + { 1, 1, 0, 6, 128, 28, }, + { 0, 1, 0, 6, 132, 32, }, + { 2, 1, 0, 6, 132, 28, }, + { 1, 1, 0, 6, 132, 28, }, + { 0, 1, 0, 6, 136, 32, }, + { 2, 1, 0, 6, 136, 28, }, + { 1, 1, 0, 6, 136, 28, }, + { 0, 1, 0, 6, 140, 30, }, + { 2, 1, 0, 6, 140, 28, }, + { 1, 1, 0, 6, 140, 28, }, + { 0, 1, 0, 6, 149, 28, }, + { 2, 1, 0, 6, 149, 28, }, + { 1, 1, 0, 6, 149, 63, }, + { 0, 1, 0, 6, 153, 34, }, + { 2, 1, 0, 6, 153, 28, }, + { 1, 1, 0, 6, 153, 63, }, + { 0, 1, 0, 6, 157, 34, }, + { 2, 1, 0, 6, 157, 28, }, + { 1, 1, 0, 6, 157, 63, }, + { 0, 1, 0, 6, 161, 34, }, + { 2, 1, 0, 6, 161, 28, }, + { 1, 1, 0, 6, 161, 63, }, + { 0, 1, 0, 6, 165, 34, }, + { 2, 1, 0, 6, 165, 28, }, + { 1, 1, 0, 6, 165, 63, }, + { 0, 1, 0, 7, 36, 30, }, + { 2, 1, 0, 7, 36, 26, }, + { 1, 1, 0, 7, 36, 26, }, + { 0, 1, 0, 7, 40, 30, }, + { 2, 1, 0, 7, 40, 26, }, + { 1, 1, 0, 7, 40, 26, }, + { 0, 1, 0, 7, 44, 30, }, + { 2, 1, 0, 7, 44, 26, }, + { 1, 1, 0, 7, 44, 26, }, + { 0, 1, 0, 7, 48, 30, }, + { 2, 1, 0, 7, 48, 26, }, + { 1, 1, 0, 7, 48, 26, }, + { 0, 1, 0, 7, 52, 30, }, + { 2, 1, 0, 7, 52, 26, }, + { 1, 1, 0, 7, 52, 26, }, + { 0, 1, 0, 7, 56, 30, }, + { 2, 1, 0, 7, 56, 26, }, + { 1, 1, 0, 7, 56, 26, }, + { 0, 1, 0, 7, 60, 30, }, + { 2, 1, 0, 7, 60, 26, }, + { 1, 1, 0, 7, 60, 26, }, + { 0, 1, 0, 7, 64, 30, }, + { 2, 1, 0, 7, 64, 26, }, + { 1, 1, 0, 7, 64, 26, }, + { 0, 1, 0, 7, 100, 30, }, + { 2, 1, 0, 7, 100, 26, }, + { 1, 1, 0, 7, 100, 26, }, + { 0, 1, 0, 7, 104, 30, }, + { 2, 1, 0, 7, 104, 26, }, + { 1, 1, 0, 7, 104, 26, }, + { 0, 1, 0, 7, 108, 30, }, + { 2, 1, 0, 7, 108, 26, }, + { 1, 1, 0, 7, 108, 26, }, + { 0, 1, 0, 7, 112, 30, }, + { 2, 1, 0, 7, 112, 26, }, + { 1, 1, 0, 7, 112, 26, }, + { 0, 1, 0, 7, 116, 30, }, + { 2, 1, 0, 7, 116, 26, }, + { 1, 1, 0, 7, 116, 26, }, + { 0, 1, 0, 7, 120, 30, }, + { 2, 1, 0, 7, 120, 26, }, + { 1, 1, 0, 7, 120, 26, }, + { 0, 1, 0, 7, 124, 30, }, + { 2, 1, 0, 7, 124, 26, }, + { 1, 1, 0, 7, 124, 26, }, + { 0, 1, 0, 7, 128, 30, }, + { 2, 1, 0, 7, 128, 26, }, + { 1, 1, 0, 7, 128, 26, }, + { 0, 1, 0, 7, 132, 30, }, + { 2, 1, 0, 7, 132, 26, }, + { 1, 1, 0, 7, 132, 26, }, + { 0, 1, 0, 7, 136, 30, }, + { 2, 1, 0, 7, 136, 26, }, + { 1, 1, 0, 7, 136, 26, }, + { 0, 1, 0, 7, 140, 28, }, + { 2, 1, 0, 7, 140, 26, }, + { 1, 1, 0, 7, 140, 26, }, + { 0, 1, 0, 7, 149, 26, }, + { 2, 1, 0, 7, 149, 26, }, + { 1, 1, 0, 7, 149, 63, }, + { 0, 1, 0, 7, 153, 32, }, + { 2, 1, 0, 7, 153, 26, }, + { 1, 1, 0, 7, 153, 63, }, + { 0, 1, 0, 7, 157, 32, }, + { 2, 1, 0, 7, 157, 26, }, + { 1, 1, 0, 7, 157, 63, }, + { 0, 1, 0, 7, 161, 32, }, + { 2, 1, 0, 7, 161, 26, }, + { 1, 1, 0, 7, 161, 63, }, + { 0, 1, 0, 7, 165, 32, }, + { 2, 1, 0, 7, 165, 26, }, + { 1, 1, 0, 7, 165, 63, }, + { 0, 1, 1, 2, 38, 32, }, + { 2, 1, 1, 2, 38, 32, }, + { 1, 1, 1, 2, 38, 32, }, + { 0, 1, 1, 2, 46, 32, }, + { 2, 1, 1, 2, 46, 32, }, + { 1, 1, 1, 2, 46, 32, }, + { 0, 1, 1, 2, 54, 32, }, + { 2, 1, 1, 2, 54, 32, }, + { 1, 1, 1, 2, 54, 32, }, + { 0, 1, 1, 2, 62, 30, }, + { 2, 1, 1, 2, 62, 32, }, + { 1, 1, 1, 2, 62, 32, }, + { 0, 1, 1, 2, 102, 30, }, + { 2, 1, 1, 2, 102, 32, }, + { 1, 1, 1, 2, 102, 32, }, + { 0, 1, 1, 2, 110, 38, }, + { 2, 1, 1, 2, 110, 32, }, + { 1, 1, 1, 2, 110, 32, }, + { 0, 1, 1, 2, 118, 38, }, + { 2, 1, 1, 2, 118, 32, }, + { 1, 1, 1, 2, 118, 32, }, + { 0, 1, 1, 2, 126, 38, }, + { 2, 1, 1, 2, 126, 32, }, + { 1, 1, 1, 2, 126, 32, }, + { 0, 1, 1, 2, 134, 38, }, + { 2, 1, 1, 2, 134, 32, }, + { 1, 1, 1, 2, 134, 32, }, + { 0, 1, 1, 2, 151, 32, }, + { 2, 1, 1, 2, 151, 32, }, + { 1, 1, 1, 2, 151, 63, }, + { 0, 1, 1, 2, 159, 32, }, + { 2, 1, 1, 2, 159, 32, }, + { 1, 1, 1, 2, 159, 63, }, + { 0, 1, 1, 3, 38, 30, }, + { 2, 1, 1, 3, 38, 30, }, + { 1, 1, 1, 3, 38, 30, }, + { 0, 1, 1, 3, 46, 30, }, + { 2, 1, 1, 3, 46, 30, }, + { 1, 1, 1, 3, 46, 30, }, + { 0, 1, 1, 3, 54, 30, }, + { 2, 1, 1, 3, 54, 30, }, + { 1, 1, 1, 3, 54, 30, }, + { 0, 1, 1, 3, 62, 28, }, + { 2, 1, 1, 3, 62, 30, }, + { 1, 1, 1, 3, 62, 30, }, + { 0, 1, 1, 3, 102, 28, }, + { 2, 1, 1, 3, 102, 30, }, + { 1, 1, 1, 3, 102, 30, }, + { 0, 1, 1, 3, 110, 36, }, + { 2, 1, 1, 3, 110, 30, }, + { 1, 1, 1, 3, 110, 30, }, + { 0, 1, 1, 3, 118, 36, }, + { 2, 1, 1, 3, 118, 30, }, + { 1, 1, 1, 3, 118, 30, }, + { 0, 1, 1, 3, 126, 36, }, + { 2, 1, 1, 3, 126, 30, }, + { 1, 1, 1, 3, 126, 30, }, + { 0, 1, 1, 3, 134, 36, }, + { 2, 1, 1, 3, 134, 30, }, + { 1, 1, 1, 3, 134, 30, }, + { 0, 1, 1, 3, 151, 30, }, + { 2, 1, 1, 3, 151, 30, }, + { 1, 1, 1, 3, 151, 63, }, + { 0, 1, 1, 3, 159, 30, }, + { 2, 1, 1, 3, 159, 30, }, + { 1, 1, 1, 3, 159, 63, }, + { 0, 1, 1, 6, 38, 28, }, + { 2, 1, 1, 6, 38, 28, }, + { 1, 1, 1, 6, 38, 28, }, + { 0, 1, 1, 6, 46, 28, }, + { 2, 1, 1, 6, 46, 28, }, + { 1, 1, 1, 6, 46, 28, }, + { 0, 1, 1, 6, 54, 28, }, + { 2, 1, 1, 6, 54, 28, }, + { 1, 1, 1, 6, 54, 28, }, + { 0, 1, 1, 6, 62, 26, }, + { 2, 1, 1, 6, 62, 28, }, + { 1, 1, 1, 6, 62, 28, }, + { 0, 1, 1, 6, 102, 26, }, + { 2, 1, 1, 6, 102, 28, }, + { 1, 1, 1, 6, 102, 28, }, + { 0, 1, 1, 6, 110, 34, }, + { 2, 1, 1, 6, 110, 28, }, + { 1, 1, 1, 6, 110, 28, }, + { 0, 1, 1, 6, 118, 34, }, + { 2, 1, 1, 6, 118, 28, }, + { 1, 1, 1, 6, 118, 28, }, + { 0, 1, 1, 6, 126, 34, }, + { 2, 1, 1, 6, 126, 28, }, + { 1, 1, 1, 6, 126, 28, }, + { 0, 1, 1, 6, 134, 34, }, + { 2, 1, 1, 6, 134, 28, }, + { 1, 1, 1, 6, 134, 28, }, + { 0, 1, 1, 6, 151, 28, }, + { 2, 1, 1, 6, 151, 28, }, + { 1, 1, 1, 6, 151, 63, }, + { 0, 1, 1, 6, 159, 28, }, + { 2, 1, 1, 6, 159, 28, }, + { 1, 1, 1, 6, 159, 63, }, + { 0, 1, 1, 7, 38, 26, }, + { 2, 1, 1, 7, 38, 26, }, + { 1, 1, 1, 7, 38, 26, }, + { 0, 1, 1, 7, 46, 26, }, + { 2, 1, 1, 7, 46, 26, }, + { 1, 1, 1, 7, 46, 26, }, + { 0, 1, 1, 7, 54, 26, }, + { 2, 1, 1, 7, 54, 26, }, + { 1, 1, 1, 7, 54, 26, }, + { 0, 1, 1, 7, 62, 24, }, + { 2, 1, 1, 7, 62, 26, }, + { 1, 1, 1, 7, 62, 26, }, + { 0, 1, 1, 7, 102, 24, }, + { 2, 1, 1, 7, 102, 26, }, + { 1, 1, 1, 7, 102, 26, }, + { 0, 1, 1, 7, 110, 32, }, + { 2, 1, 1, 7, 110, 26, }, + { 1, 1, 1, 7, 110, 26, }, + { 0, 1, 1, 7, 118, 32, }, + { 2, 1, 1, 7, 118, 26, }, + { 1, 1, 1, 7, 118, 26, }, + { 0, 1, 1, 7, 126, 32, }, + { 2, 1, 1, 7, 126, 26, }, + { 1, 1, 1, 7, 126, 26, }, + { 0, 1, 1, 7, 134, 32, }, + { 2, 1, 1, 7, 134, 26, }, + { 1, 1, 1, 7, 134, 26, }, + { 0, 1, 1, 7, 151, 26, }, + { 2, 1, 1, 7, 151, 26, }, + { 1, 1, 1, 7, 151, 63, }, + { 0, 1, 1, 7, 159, 26, }, + { 2, 1, 1, 7, 159, 26, }, + { 1, 1, 1, 7, 159, 63, }, + { 0, 1, 2, 4, 42, 26, }, + { 2, 1, 2, 4, 42, 32, }, + { 1, 1, 2, 4, 42, 32, }, + { 0, 1, 2, 4, 58, 26, }, + { 2, 1, 2, 4, 58, 32, }, + { 1, 1, 2, 4, 58, 32, }, + { 0, 1, 2, 4, 106, 28, }, + { 2, 1, 2, 4, 106, 32, }, + { 1, 1, 2, 4, 106, 32, }, + { 0, 1, 2, 4, 122, 28, }, + { 2, 1, 2, 4, 122, 32, }, + { 1, 1, 2, 4, 122, 32, }, + { 0, 1, 2, 4, 155, 28, }, + { 2, 1, 2, 4, 155, 32, }, + { 1, 1, 2, 4, 155, 63, }, + { 0, 1, 2, 5, 42, 24, }, + { 2, 1, 2, 5, 42, 30, }, + { 1, 1, 2, 5, 42, 30, }, + { 0, 1, 2, 5, 58, 24, }, + { 2, 1, 2, 5, 58, 30, }, + { 1, 1, 2, 5, 58, 30, }, + { 0, 1, 2, 5, 106, 26, }, + { 2, 1, 2, 5, 106, 30, }, + { 1, 1, 2, 5, 106, 30, }, + { 0, 1, 2, 5, 122, 26, }, + { 2, 1, 2, 5, 122, 30, }, + { 1, 1, 2, 5, 122, 30, }, + { 0, 1, 2, 5, 155, 26, }, + { 2, 1, 2, 5, 155, 30, }, + { 1, 1, 2, 5, 155, 63, }, + { 0, 1, 2, 8, 42, 22, }, + { 2, 1, 2, 8, 42, 28, }, + { 1, 1, 2, 8, 42, 28, }, + { 0, 1, 2, 8, 58, 22, }, + { 2, 1, 2, 8, 58, 28, }, + { 1, 1, 2, 8, 58, 28, }, + { 0, 1, 2, 8, 106, 24, }, + { 2, 1, 2, 8, 106, 28, }, + { 1, 1, 2, 8, 106, 28, }, + { 0, 1, 2, 8, 122, 24, }, + { 2, 1, 2, 8, 122, 28, }, + { 1, 1, 2, 8, 122, 28, }, + { 0, 1, 2, 8, 155, 24, }, + { 2, 1, 2, 8, 155, 28, }, + { 1, 1, 2, 8, 155, 63, }, + { 0, 1, 2, 9, 42, 20, }, + { 2, 1, 2, 9, 42, 26, }, + { 1, 1, 2, 9, 42, 26, }, + { 0, 1, 2, 9, 58, 20, }, + { 2, 1, 2, 9, 58, 26, }, + { 1, 1, 2, 9, 58, 26, }, + { 0, 1, 2, 9, 106, 22, }, + { 2, 1, 2, 9, 106, 26, }, + { 1, 1, 2, 9, 106, 26, }, + { 0, 1, 2, 9, 122, 22, }, + { 2, 1, 2, 9, 122, 26, }, + { 1, 1, 2, 9, 122, 26, }, + { 0, 1, 2, 9, 155, 22, }, + { 2, 1, 2, 9, 155, 26, }, + { 1, 1, 2, 9, 155, 63, }, +}; + +RTW_DECL_TABLE_TXPWR_LMT(rtw8814a_txpwr_lmt_type7); + +static const struct rtw_txpwr_lmt_cfg_pair rtw8814a_txpwr_lmt_type8[] = { + { 0, 0, 0, 0, 1, 46, }, + { 2, 0, 0, 0, 1, 46, }, + { 1, 0, 0, 0, 1, 46, }, + { 0, 0, 0, 0, 2, 46, }, + { 2, 0, 0, 0, 2, 46, }, + { 1, 0, 0, 0, 2, 46, }, + { 0, 0, 0, 0, 3, 46, }, + { 2, 0, 0, 0, 3, 46, }, + { 1, 0, 0, 0, 3, 46, }, + { 0, 0, 0, 0, 4, 46, }, + { 2, 0, 0, 0, 4, 46, }, + { 1, 0, 0, 0, 4, 46, }, + { 0, 0, 0, 0, 5, 46, }, + { 2, 0, 0, 0, 5, 46, }, + { 1, 0, 0, 0, 5, 46, }, + { 0, 0, 0, 0, 6, 46, }, + { 2, 0, 0, 0, 6, 46, }, + { 1, 0, 0, 0, 6, 46, }, + { 0, 0, 0, 0, 7, 46, }, + { 2, 0, 0, 0, 7, 46, }, + { 1, 0, 0, 0, 7, 46, }, + { 0, 0, 0, 0, 8, 46, }, + { 2, 0, 0, 0, 8, 46, }, + { 1, 0, 0, 0, 8, 46, }, + { 0, 0, 0, 0, 9, 46, }, + { 2, 0, 0, 0, 9, 46, }, + { 1, 0, 0, 0, 9, 46, }, + { 0, 0, 0, 0, 10, 46, }, + { 2, 0, 0, 0, 10, 46, }, + { 1, 0, 0, 0, 10, 46, }, + { 0, 0, 0, 0, 11, 46, }, + { 2, 0, 0, 0, 11, 46, }, + { 1, 0, 0, 0, 11, 46, }, + { 0, 0, 0, 0, 12, 63, }, + { 2, 0, 0, 0, 12, 46, }, + { 1, 0, 0, 0, 12, 46, }, + { 0, 0, 0, 0, 13, 63, }, + { 2, 0, 0, 0, 13, 46, }, + { 1, 0, 0, 0, 13, 46, }, + { 0, 0, 0, 0, 14, 63, }, + { 2, 0, 0, 0, 14, 63, }, + { 1, 0, 0, 0, 14, 46, }, + { 0, 0, 0, 1, 1, 46, }, + { 2, 0, 0, 1, 1, 46, }, + { 1, 0, 0, 1, 1, 46, }, + { 0, 0, 0, 1, 2, 46, }, + { 2, 0, 0, 1, 2, 46, }, + { 1, 0, 0, 1, 2, 46, }, + { 0, 0, 0, 1, 3, 46, }, + { 2, 0, 0, 1, 3, 46, }, + { 1, 0, 0, 1, 3, 46, }, + { 0, 0, 0, 1, 4, 46, }, + { 2, 0, 0, 1, 4, 46, }, + { 1, 0, 0, 1, 4, 46, }, + { 0, 0, 0, 1, 5, 46, }, + { 2, 0, 0, 1, 5, 46, }, + { 1, 0, 0, 1, 5, 46, }, + { 0, 0, 0, 1, 6, 46, }, + { 2, 0, 0, 1, 6, 46, }, + { 1, 0, 0, 1, 6, 46, }, + { 0, 0, 0, 1, 7, 46, }, + { 2, 0, 0, 1, 7, 46, }, + { 1, 0, 0, 1, 7, 46, }, + { 0, 0, 0, 1, 8, 46, }, + { 2, 0, 0, 1, 8, 46, }, + { 1, 0, 0, 1, 8, 46, }, + { 0, 0, 0, 1, 9, 46, }, + { 2, 0, 0, 1, 9, 46, }, + { 1, 0, 0, 1, 9, 46, }, + { 0, 0, 0, 1, 10, 46, }, + { 2, 0, 0, 1, 10, 46, }, + { 1, 0, 0, 1, 10, 46, }, + { 0, 0, 0, 1, 11, 46, }, + { 2, 0, 0, 1, 11, 46, }, + { 1, 0, 0, 1, 11, 46, }, + { 0, 0, 0, 1, 12, 63, }, + { 2, 0, 0, 1, 12, 46, }, + { 1, 0, 0, 1, 12, 46, }, + { 0, 0, 0, 1, 13, 63, }, + { 2, 0, 0, 1, 13, 46, }, + { 1, 0, 0, 1, 13, 46, }, + { 0, 0, 0, 1, 14, 63, }, + { 2, 0, 0, 1, 14, 63, }, + { 1, 0, 0, 1, 14, 46, }, + { 0, 0, 0, 2, 1, 46, }, + { 2, 0, 0, 2, 1, 46, }, + { 1, 0, 0, 2, 1, 46, }, + { 0, 0, 0, 2, 2, 46, }, + { 2, 0, 0, 2, 2, 46, }, + { 1, 0, 0, 2, 2, 46, }, + { 0, 0, 0, 2, 3, 46, }, + { 2, 0, 0, 2, 3, 46, }, + { 1, 0, 0, 2, 3, 46, }, + { 0, 0, 0, 2, 4, 46, }, + { 2, 0, 0, 2, 4, 46, }, + { 1, 0, 0, 2, 4, 46, }, + { 0, 0, 0, 2, 5, 46, }, + { 2, 0, 0, 2, 5, 46, }, + { 1, 0, 0, 2, 5, 46, }, + { 0, 0, 0, 2, 6, 46, }, + { 2, 0, 0, 2, 6, 46, }, + { 1, 0, 0, 2, 6, 46, }, + { 0, 0, 0, 2, 7, 46, }, + { 2, 0, 0, 2, 7, 46, }, + { 1, 0, 0, 2, 7, 46, }, + { 0, 0, 0, 2, 8, 46, }, + { 2, 0, 0, 2, 8, 46, }, + { 1, 0, 0, 2, 8, 46, }, + { 0, 0, 0, 2, 9, 46, }, + { 2, 0, 0, 2, 9, 46, }, + { 1, 0, 0, 2, 9, 46, }, + { 0, 0, 0, 2, 10, 46, }, + { 2, 0, 0, 2, 10, 46, }, + { 1, 0, 0, 2, 10, 46, }, + { 0, 0, 0, 2, 11, 46, }, + { 2, 0, 0, 2, 11, 46, }, + { 1, 0, 0, 2, 11, 46, }, + { 0, 0, 0, 2, 12, 63, }, + { 2, 0, 0, 2, 12, 46, }, + { 1, 0, 0, 2, 12, 46, }, + { 0, 0, 0, 2, 13, 63, }, + { 2, 0, 0, 2, 13, 46, }, + { 1, 0, 0, 2, 13, 46, }, + { 0, 0, 0, 2, 14, 63, }, + { 2, 0, 0, 2, 14, 63, }, + { 1, 0, 0, 2, 14, 46, }, + { 0, 0, 0, 3, 1, 46, }, + { 2, 0, 0, 3, 1, 46, }, + { 1, 0, 0, 3, 1, 46, }, + { 0, 0, 0, 3, 2, 46, }, + { 2, 0, 0, 3, 2, 46, }, + { 1, 0, 0, 3, 2, 46, }, + { 0, 0, 0, 3, 3, 46, }, + { 2, 0, 0, 3, 3, 46, }, + { 1, 0, 0, 3, 3, 46, }, + { 0, 0, 0, 3, 4, 46, }, + { 2, 0, 0, 3, 4, 46, }, + { 1, 0, 0, 3, 4, 46, }, + { 0, 0, 0, 3, 5, 46, }, + { 2, 0, 0, 3, 5, 46, }, + { 1, 0, 0, 3, 5, 46, }, + { 0, 0, 0, 3, 6, 46, }, + { 2, 0, 0, 3, 6, 46, }, + { 1, 0, 0, 3, 6, 46, }, + { 0, 0, 0, 3, 7, 46, }, + { 2, 0, 0, 3, 7, 46, }, + { 1, 0, 0, 3, 7, 46, }, + { 0, 0, 0, 3, 8, 46, }, + { 2, 0, 0, 3, 8, 46, }, + { 1, 0, 0, 3, 8, 46, }, + { 0, 0, 0, 3, 9, 46, }, + { 2, 0, 0, 3, 9, 46, }, + { 1, 0, 0, 3, 9, 46, }, + { 0, 0, 0, 3, 10, 46, }, + { 2, 0, 0, 3, 10, 46, }, + { 1, 0, 0, 3, 10, 46, }, + { 0, 0, 0, 3, 11, 46, }, + { 2, 0, 0, 3, 11, 46, }, + { 1, 0, 0, 3, 11, 46, }, + { 0, 0, 0, 3, 12, 63, }, + { 2, 0, 0, 3, 12, 46, }, + { 1, 0, 0, 3, 12, 46, }, + { 0, 0, 0, 3, 13, 63, }, + { 2, 0, 0, 3, 13, 46, }, + { 1, 0, 0, 3, 13, 46, }, + { 0, 0, 0, 3, 14, 63, }, + { 2, 0, 0, 3, 14, 63, }, + { 1, 0, 0, 3, 14, 46, }, + { 0, 0, 0, 6, 1, 46, }, + { 2, 0, 0, 6, 1, 46, }, + { 1, 0, 0, 6, 1, 46, }, + { 0, 0, 0, 6, 2, 46, }, + { 2, 0, 0, 6, 2, 46, }, + { 1, 0, 0, 6, 2, 46, }, + { 0, 0, 0, 6, 3, 46, }, + { 2, 0, 0, 6, 3, 46, }, + { 1, 0, 0, 6, 3, 46, }, + { 0, 0, 0, 6, 4, 46, }, + { 2, 0, 0, 6, 4, 46, }, + { 1, 0, 0, 6, 4, 46, }, + { 0, 0, 0, 6, 5, 46, }, + { 2, 0, 0, 6, 5, 46, }, + { 1, 0, 0, 6, 5, 46, }, + { 0, 0, 0, 6, 6, 46, }, + { 2, 0, 0, 6, 6, 46, }, + { 1, 0, 0, 6, 6, 46, }, + { 0, 0, 0, 6, 7, 46, }, + { 2, 0, 0, 6, 7, 46, }, + { 1, 0, 0, 6, 7, 46, }, + { 0, 0, 0, 6, 8, 46, }, + { 2, 0, 0, 6, 8, 46, }, + { 1, 0, 0, 6, 8, 46, }, + { 0, 0, 0, 6, 9, 46, }, + { 2, 0, 0, 6, 9, 46, }, + { 1, 0, 0, 6, 9, 46, }, + { 0, 0, 0, 6, 10, 46, }, + { 2, 0, 0, 6, 10, 46, }, + { 1, 0, 0, 6, 10, 46, }, + { 0, 0, 0, 6, 11, 46, }, + { 2, 0, 0, 6, 11, 46, }, + { 1, 0, 0, 6, 11, 46, }, + { 0, 0, 0, 6, 12, 63, }, + { 2, 0, 0, 6, 12, 46, }, + { 1, 0, 0, 6, 12, 46, }, + { 0, 0, 0, 6, 13, 63, }, + { 2, 0, 0, 6, 13, 46, }, + { 1, 0, 0, 6, 13, 46, }, + { 0, 0, 0, 6, 14, 63, }, + { 2, 0, 0, 6, 14, 63, }, + { 1, 0, 0, 6, 14, 46, }, + { 0, 0, 0, 7, 1, 46, }, + { 2, 0, 0, 7, 1, 46, }, + { 1, 0, 0, 7, 1, 46, }, + { 0, 0, 0, 7, 2, 46, }, + { 2, 0, 0, 7, 2, 46, }, + { 1, 0, 0, 7, 2, 46, }, + { 0, 0, 0, 7, 3, 46, }, + { 2, 0, 0, 7, 3, 46, }, + { 1, 0, 0, 7, 3, 46, }, + { 0, 0, 0, 7, 4, 46, }, + { 2, 0, 0, 7, 4, 46, }, + { 1, 0, 0, 7, 4, 46, }, + { 0, 0, 0, 7, 5, 46, }, + { 2, 0, 0, 7, 5, 46, }, + { 1, 0, 0, 7, 5, 46, }, + { 0, 0, 0, 7, 6, 46, }, + { 2, 0, 0, 7, 6, 46, }, + { 1, 0, 0, 7, 6, 46, }, + { 0, 0, 0, 7, 7, 46, }, + { 2, 0, 0, 7, 7, 46, }, + { 1, 0, 0, 7, 7, 46, }, + { 0, 0, 0, 7, 8, 46, }, + { 2, 0, 0, 7, 8, 46, }, + { 1, 0, 0, 7, 8, 46, }, + { 0, 0, 0, 7, 9, 46, }, + { 2, 0, 0, 7, 9, 46, }, + { 1, 0, 0, 7, 9, 46, }, + { 0, 0, 0, 7, 10, 46, }, + { 2, 0, 0, 7, 10, 46, }, + { 1, 0, 0, 7, 10, 46, }, + { 0, 0, 0, 7, 11, 46, }, + { 2, 0, 0, 7, 11, 46, }, + { 1, 0, 0, 7, 11, 46, }, + { 0, 0, 0, 7, 12, 63, }, + { 2, 0, 0, 7, 12, 46, }, + { 1, 0, 0, 7, 12, 46, }, + { 0, 0, 0, 7, 13, 63, }, + { 2, 0, 0, 7, 13, 46, }, + { 1, 0, 0, 7, 13, 46, }, + { 0, 0, 0, 7, 14, 63, }, + { 2, 0, 0, 7, 14, 63, }, + { 1, 0, 0, 7, 14, 46, }, + { 0, 0, 1, 2, 1, 63, }, + { 2, 0, 1, 2, 1, 63, }, + { 1, 0, 1, 2, 1, 63, }, + { 0, 0, 1, 2, 2, 63, }, + { 2, 0, 1, 2, 2, 63, }, + { 1, 0, 1, 2, 2, 63, }, + { 0, 0, 1, 2, 3, 30, }, + { 2, 0, 1, 2, 3, 34, }, + { 1, 0, 1, 2, 3, 34, }, + { 0, 0, 1, 2, 4, 34, }, + { 2, 0, 1, 2, 4, 34, }, + { 1, 0, 1, 2, 4, 34, }, + { 0, 0, 1, 2, 5, 34, }, + { 2, 0, 1, 2, 5, 34, }, + { 1, 0, 1, 2, 5, 34, }, + { 0, 0, 1, 2, 6, 34, }, + { 2, 0, 1, 2, 6, 34, }, + { 1, 0, 1, 2, 6, 34, }, + { 0, 0, 1, 2, 7, 34, }, + { 2, 0, 1, 2, 7, 34, }, + { 1, 0, 1, 2, 7, 34, }, + { 0, 0, 1, 2, 8, 34, }, + { 2, 0, 1, 2, 8, 34, }, + { 1, 0, 1, 2, 8, 34, }, + { 0, 0, 1, 2, 9, 34, }, + { 2, 0, 1, 2, 9, 34, }, + { 1, 0, 1, 2, 9, 34, }, + { 0, 0, 1, 2, 10, 34, }, + { 2, 0, 1, 2, 10, 34, }, + { 1, 0, 1, 2, 10, 34, }, + { 0, 0, 1, 2, 11, 28, }, + { 2, 0, 1, 2, 11, 34, }, + { 1, 0, 1, 2, 11, 34, }, + { 0, 0, 1, 2, 12, 63, }, + { 2, 0, 1, 2, 12, 34, }, + { 1, 0, 1, 2, 12, 34, }, + { 0, 0, 1, 2, 13, 63, }, + { 2, 0, 1, 2, 13, 34, }, + { 1, 0, 1, 2, 13, 34, }, + { 0, 0, 1, 2, 14, 63, }, + { 2, 0, 1, 2, 14, 63, }, + { 1, 0, 1, 2, 14, 63, }, + { 0, 0, 1, 3, 1, 63, }, + { 2, 0, 1, 3, 1, 63, }, + { 1, 0, 1, 3, 1, 63, }, + { 0, 0, 1, 3, 2, 63, }, + { 2, 0, 1, 3, 2, 63, }, + { 1, 0, 1, 3, 2, 63, }, + { 0, 0, 1, 3, 3, 30, }, + { 2, 0, 1, 3, 3, 34, }, + { 1, 0, 1, 3, 3, 34, }, + { 0, 0, 1, 3, 4, 34, }, + { 2, 0, 1, 3, 4, 34, }, + { 1, 0, 1, 3, 4, 34, }, + { 0, 0, 1, 3, 5, 34, }, + { 2, 0, 1, 3, 5, 34, }, + { 1, 0, 1, 3, 5, 34, }, + { 0, 0, 1, 3, 6, 34, }, + { 2, 0, 1, 3, 6, 34, }, + { 1, 0, 1, 3, 6, 34, }, + { 0, 0, 1, 3, 7, 34, }, + { 2, 0, 1, 3, 7, 34, }, + { 1, 0, 1, 3, 7, 34, }, + { 0, 0, 1, 3, 8, 34, }, + { 2, 0, 1, 3, 8, 34, }, + { 1, 0, 1, 3, 8, 34, }, + { 0, 0, 1, 3, 9, 34, }, + { 2, 0, 1, 3, 9, 34, }, + { 1, 0, 1, 3, 9, 34, }, + { 0, 0, 1, 3, 10, 34, }, + { 2, 0, 1, 3, 10, 34, }, + { 1, 0, 1, 3, 10, 34, }, + { 0, 0, 1, 3, 11, 28, }, + { 2, 0, 1, 3, 11, 34, }, + { 1, 0, 1, 3, 11, 34, }, + { 0, 0, 1, 3, 12, 63, }, + { 2, 0, 1, 3, 12, 34, }, + { 1, 0, 1, 3, 12, 34, }, + { 0, 0, 1, 3, 13, 63, }, + { 2, 0, 1, 3, 13, 34, }, + { 1, 0, 1, 3, 13, 34, }, + { 0, 0, 1, 3, 14, 63, }, + { 2, 0, 1, 3, 14, 63, }, + { 1, 0, 1, 3, 14, 63, }, + { 0, 0, 1, 6, 1, 63, }, + { 2, 0, 1, 6, 1, 63, }, + { 1, 0, 1, 6, 1, 63, }, + { 0, 0, 1, 6, 2, 63, }, + { 2, 0, 1, 6, 2, 63, }, + { 1, 0, 1, 6, 2, 63, }, + { 0, 0, 1, 6, 3, 30, }, + { 2, 0, 1, 6, 3, 34, }, + { 1, 0, 1, 6, 3, 34, }, + { 0, 0, 1, 6, 4, 34, }, + { 2, 0, 1, 6, 4, 34, }, + { 1, 0, 1, 6, 4, 34, }, + { 0, 0, 1, 6, 5, 34, }, + { 2, 0, 1, 6, 5, 34, }, + { 1, 0, 1, 6, 5, 34, }, + { 0, 0, 1, 6, 6, 34, }, + { 2, 0, 1, 6, 6, 34, }, + { 1, 0, 1, 6, 6, 34, }, + { 0, 0, 1, 6, 7, 34, }, + { 2, 0, 1, 6, 7, 34, }, + { 1, 0, 1, 6, 7, 34, }, + { 0, 0, 1, 6, 8, 34, }, + { 2, 0, 1, 6, 8, 34, }, + { 1, 0, 1, 6, 8, 34, }, + { 0, 0, 1, 6, 9, 34, }, + { 2, 0, 1, 6, 9, 34, }, + { 1, 0, 1, 6, 9, 34, }, + { 0, 0, 1, 6, 10, 34, }, + { 2, 0, 1, 6, 10, 34, }, + { 1, 0, 1, 6, 10, 34, }, + { 0, 0, 1, 6, 11, 28, }, + { 2, 0, 1, 6, 11, 34, }, + { 1, 0, 1, 6, 11, 34, }, + { 0, 0, 1, 6, 12, 63, }, + { 2, 0, 1, 6, 12, 34, }, + { 1, 0, 1, 6, 12, 34, }, + { 0, 0, 1, 6, 13, 63, }, + { 2, 0, 1, 6, 13, 34, }, + { 1, 0, 1, 6, 13, 34, }, + { 0, 0, 1, 6, 14, 63, }, + { 2, 0, 1, 6, 14, 63, }, + { 1, 0, 1, 6, 14, 63, }, + { 0, 0, 1, 7, 1, 63, }, + { 2, 0, 1, 7, 1, 63, }, + { 1, 0, 1, 7, 1, 63, }, + { 0, 0, 1, 7, 2, 63, }, + { 2, 0, 1, 7, 2, 63, }, + { 1, 0, 1, 7, 2, 63, }, + { 0, 0, 1, 7, 3, 30, }, + { 2, 0, 1, 7, 3, 34, }, + { 1, 0, 1, 7, 3, 34, }, + { 0, 0, 1, 7, 4, 34, }, + { 2, 0, 1, 7, 4, 34, }, + { 1, 0, 1, 7, 4, 34, }, + { 0, 0, 1, 7, 5, 34, }, + { 2, 0, 1, 7, 5, 34, }, + { 1, 0, 1, 7, 5, 34, }, + { 0, 0, 1, 7, 6, 34, }, + { 2, 0, 1, 7, 6, 34, }, + { 1, 0, 1, 7, 6, 34, }, + { 0, 0, 1, 7, 7, 34, }, + { 2, 0, 1, 7, 7, 34, }, + { 1, 0, 1, 7, 7, 34, }, + { 0, 0, 1, 7, 8, 34, }, + { 2, 0, 1, 7, 8, 34, }, + { 1, 0, 1, 7, 8, 34, }, + { 0, 0, 1, 7, 9, 34, }, + { 2, 0, 1, 7, 9, 34, }, + { 1, 0, 1, 7, 9, 34, }, + { 0, 0, 1, 7, 10, 34, }, + { 2, 0, 1, 7, 10, 34, }, + { 1, 0, 1, 7, 10, 34, }, + { 0, 0, 1, 7, 11, 28, }, + { 2, 0, 1, 7, 11, 34, }, + { 1, 0, 1, 7, 11, 34, }, + { 0, 0, 1, 7, 12, 63, }, + { 2, 0, 1, 7, 12, 34, }, + { 1, 0, 1, 7, 12, 34, }, + { 0, 0, 1, 7, 13, 63, }, + { 2, 0, 1, 7, 13, 34, }, + { 1, 0, 1, 7, 13, 34, }, + { 0, 0, 1, 7, 14, 63, }, + { 2, 0, 1, 7, 14, 63, }, + { 1, 0, 1, 7, 14, 63, }, + { 0, 1, 0, 1, 36, 46, }, + { 2, 1, 0, 1, 36, 46, }, + { 1, 1, 0, 1, 36, 46, }, + { 0, 1, 0, 1, 40, 46, }, + { 2, 1, 0, 1, 40, 46, }, + { 1, 1, 0, 1, 40, 46, }, + { 0, 1, 0, 1, 44, 46, }, + { 2, 1, 0, 1, 44, 46, }, + { 1, 1, 0, 1, 44, 46, }, + { 0, 1, 0, 1, 48, 46, }, + { 2, 1, 0, 1, 48, 46, }, + { 1, 1, 0, 1, 48, 46, }, + { 0, 1, 0, 1, 52, 46, }, + { 2, 1, 0, 1, 52, 46, }, + { 1, 1, 0, 1, 52, 46, }, + { 0, 1, 0, 1, 56, 46, }, + { 2, 1, 0, 1, 56, 46, }, + { 1, 1, 0, 1, 56, 46, }, + { 0, 1, 0, 1, 60, 46, }, + { 2, 1, 0, 1, 60, 46, }, + { 1, 1, 0, 1, 60, 46, }, + { 0, 1, 0, 1, 64, 46, }, + { 2, 1, 0, 1, 64, 46, }, + { 1, 1, 0, 1, 64, 46, }, + { 0, 1, 0, 1, 100, 46, }, + { 2, 1, 0, 1, 100, 46, }, + { 1, 1, 0, 1, 100, 46, }, + { 0, 1, 0, 1, 104, 46, }, + { 2, 1, 0, 1, 104, 46, }, + { 1, 1, 0, 1, 104, 46, }, + { 0, 1, 0, 1, 108, 46, }, + { 2, 1, 0, 1, 108, 46, }, + { 1, 1, 0, 1, 108, 46, }, + { 0, 1, 0, 1, 112, 46, }, + { 2, 1, 0, 1, 112, 46, }, + { 1, 1, 0, 1, 112, 46, }, + { 0, 1, 0, 1, 116, 46, }, + { 2, 1, 0, 1, 116, 46, }, + { 1, 1, 0, 1, 116, 46, }, + { 0, 1, 0, 1, 120, 46, }, + { 2, 1, 0, 1, 120, 46, }, + { 1, 1, 0, 1, 120, 46, }, + { 0, 1, 0, 1, 124, 46, }, + { 2, 1, 0, 1, 124, 46, }, + { 1, 1, 0, 1, 124, 46, }, + { 0, 1, 0, 1, 128, 46, }, + { 2, 1, 0, 1, 128, 46, }, + { 1, 1, 0, 1, 128, 46, }, + { 0, 1, 0, 1, 132, 46, }, + { 2, 1, 0, 1, 132, 46, }, + { 1, 1, 0, 1, 132, 46, }, + { 0, 1, 0, 1, 136, 46, }, + { 2, 1, 0, 1, 136, 46, }, + { 1, 1, 0, 1, 136, 46, }, + { 0, 1, 0, 1, 140, 46, }, + { 2, 1, 0, 1, 140, 46, }, + { 1, 1, 0, 1, 140, 46, }, + { 0, 1, 0, 1, 149, 46, }, + { 2, 1, 0, 1, 149, 46, }, + { 1, 1, 0, 1, 149, 63, }, + { 0, 1, 0, 1, 153, 46, }, + { 2, 1, 0, 1, 153, 46, }, + { 1, 1, 0, 1, 153, 63, }, + { 0, 1, 0, 1, 157, 46, }, + { 2, 1, 0, 1, 157, 46, }, + { 1, 1, 0, 1, 157, 63, }, + { 0, 1, 0, 1, 161, 46, }, + { 2, 1, 0, 1, 161, 46, }, + { 1, 1, 0, 1, 161, 63, }, + { 0, 1, 0, 1, 165, 46, }, + { 2, 1, 0, 1, 165, 46, }, + { 1, 1, 0, 1, 165, 63, }, + { 0, 1, 0, 2, 36, 46, }, + { 2, 1, 0, 2, 36, 46, }, + { 1, 1, 0, 2, 36, 46, }, + { 0, 1, 0, 2, 40, 46, }, + { 2, 1, 0, 2, 40, 46, }, + { 1, 1, 0, 2, 40, 46, }, + { 0, 1, 0, 2, 44, 46, }, + { 2, 1, 0, 2, 44, 46, }, + { 1, 1, 0, 2, 44, 46, }, + { 0, 1, 0, 2, 48, 46, }, + { 2, 1, 0, 2, 48, 46, }, + { 1, 1, 0, 2, 48, 46, }, + { 0, 1, 0, 2, 52, 46, }, + { 2, 1, 0, 2, 52, 46, }, + { 1, 1, 0, 2, 52, 46, }, + { 0, 1, 0, 2, 56, 46, }, + { 2, 1, 0, 2, 56, 46, }, + { 1, 1, 0, 2, 56, 46, }, + { 0, 1, 0, 2, 60, 46, }, + { 2, 1, 0, 2, 60, 46, }, + { 1, 1, 0, 2, 60, 46, }, + { 0, 1, 0, 2, 64, 46, }, + { 2, 1, 0, 2, 64, 46, }, + { 1, 1, 0, 2, 64, 46, }, + { 0, 1, 0, 2, 100, 46, }, + { 2, 1, 0, 2, 100, 46, }, + { 1, 1, 0, 2, 100, 46, }, + { 0, 1, 0, 2, 104, 46, }, + { 2, 1, 0, 2, 104, 46, }, + { 1, 1, 0, 2, 104, 46, }, + { 0, 1, 0, 2, 108, 46, }, + { 2, 1, 0, 2, 108, 46, }, + { 1, 1, 0, 2, 108, 46, }, + { 0, 1, 0, 2, 112, 46, }, + { 2, 1, 0, 2, 112, 46, }, + { 1, 1, 0, 2, 112, 46, }, + { 0, 1, 0, 2, 116, 46, }, + { 2, 1, 0, 2, 116, 46, }, + { 1, 1, 0, 2, 116, 46, }, + { 0, 1, 0, 2, 120, 46, }, + { 2, 1, 0, 2, 120, 46, }, + { 1, 1, 0, 2, 120, 46, }, + { 0, 1, 0, 2, 124, 46, }, + { 2, 1, 0, 2, 124, 46, }, + { 1, 1, 0, 2, 124, 46, }, + { 0, 1, 0, 2, 128, 46, }, + { 2, 1, 0, 2, 128, 46, }, + { 1, 1, 0, 2, 128, 46, }, + { 0, 1, 0, 2, 132, 46, }, + { 2, 1, 0, 2, 132, 46, }, + { 1, 1, 0, 2, 132, 46, }, + { 0, 1, 0, 2, 136, 46, }, + { 2, 1, 0, 2, 136, 46, }, + { 1, 1, 0, 2, 136, 46, }, + { 0, 1, 0, 2, 140, 46, }, + { 2, 1, 0, 2, 140, 46, }, + { 1, 1, 0, 2, 140, 46, }, + { 0, 1, 0, 2, 149, 46, }, + { 2, 1, 0, 2, 149, 46, }, + { 1, 1, 0, 2, 149, 63, }, + { 0, 1, 0, 2, 153, 46, }, + { 2, 1, 0, 2, 153, 46, }, + { 1, 1, 0, 2, 153, 63, }, + { 0, 1, 0, 2, 157, 46, }, + { 2, 1, 0, 2, 157, 46, }, + { 1, 1, 0, 2, 157, 63, }, + { 0, 1, 0, 2, 161, 46, }, + { 2, 1, 0, 2, 161, 46, }, + { 1, 1, 0, 2, 161, 63, }, + { 0, 1, 0, 2, 165, 46, }, + { 2, 1, 0, 2, 165, 46, }, + { 1, 1, 0, 2, 165, 63, }, + { 0, 1, 0, 3, 36, 46, }, + { 2, 1, 0, 3, 36, 46, }, + { 1, 1, 0, 3, 36, 46, }, + { 0, 1, 0, 3, 40, 46, }, + { 2, 1, 0, 3, 40, 46, }, + { 1, 1, 0, 3, 40, 46, }, + { 0, 1, 0, 3, 44, 46, }, + { 2, 1, 0, 3, 44, 46, }, + { 1, 1, 0, 3, 44, 46, }, + { 0, 1, 0, 3, 48, 46, }, + { 2, 1, 0, 3, 48, 46, }, + { 1, 1, 0, 3, 48, 46, }, + { 0, 1, 0, 3, 52, 46, }, + { 2, 1, 0, 3, 52, 46, }, + { 1, 1, 0, 3, 52, 46, }, + { 0, 1, 0, 3, 56, 46, }, + { 2, 1, 0, 3, 56, 46, }, + { 1, 1, 0, 3, 56, 46, }, + { 0, 1, 0, 3, 60, 46, }, + { 2, 1, 0, 3, 60, 46, }, + { 1, 1, 0, 3, 60, 46, }, + { 0, 1, 0, 3, 64, 46, }, + { 2, 1, 0, 3, 64, 46, }, + { 1, 1, 0, 3, 64, 46, }, + { 0, 1, 0, 3, 100, 46, }, + { 2, 1, 0, 3, 100, 46, }, + { 1, 1, 0, 3, 100, 46, }, + { 0, 1, 0, 3, 104, 46, }, + { 2, 1, 0, 3, 104, 46, }, + { 1, 1, 0, 3, 104, 46, }, + { 0, 1, 0, 3, 108, 46, }, + { 2, 1, 0, 3, 108, 46, }, + { 1, 1, 0, 3, 108, 46, }, + { 0, 1, 0, 3, 112, 46, }, + { 2, 1, 0, 3, 112, 46, }, + { 1, 1, 0, 3, 112, 46, }, + { 0, 1, 0, 3, 116, 46, }, + { 2, 1, 0, 3, 116, 46, }, + { 1, 1, 0, 3, 116, 46, }, + { 0, 1, 0, 3, 120, 46, }, + { 2, 1, 0, 3, 120, 46, }, + { 1, 1, 0, 3, 120, 46, }, + { 0, 1, 0, 3, 124, 46, }, + { 2, 1, 0, 3, 124, 46, }, + { 1, 1, 0, 3, 124, 46, }, + { 0, 1, 0, 3, 128, 46, }, + { 2, 1, 0, 3, 128, 46, }, + { 1, 1, 0, 3, 128, 46, }, + { 0, 1, 0, 3, 132, 46, }, + { 2, 1, 0, 3, 132, 46, }, + { 1, 1, 0, 3, 132, 46, }, + { 0, 1, 0, 3, 136, 46, }, + { 2, 1, 0, 3, 136, 46, }, + { 1, 1, 0, 3, 136, 46, }, + { 0, 1, 0, 3, 140, 46, }, + { 2, 1, 0, 3, 140, 46, }, + { 1, 1, 0, 3, 140, 46, }, + { 0, 1, 0, 3, 149, 46, }, + { 2, 1, 0, 3, 149, 46, }, + { 1, 1, 0, 3, 149, 63, }, + { 0, 1, 0, 3, 153, 46, }, + { 2, 1, 0, 3, 153, 46, }, + { 1, 1, 0, 3, 153, 63, }, + { 0, 1, 0, 3, 157, 46, }, + { 2, 1, 0, 3, 157, 46, }, + { 1, 1, 0, 3, 157, 63, }, + { 0, 1, 0, 3, 161, 46, }, + { 2, 1, 0, 3, 161, 46, }, + { 1, 1, 0, 3, 161, 63, }, + { 0, 1, 0, 3, 165, 46, }, + { 2, 1, 0, 3, 165, 46, }, + { 1, 1, 0, 3, 165, 63, }, + { 0, 1, 0, 6, 36, 46, }, + { 2, 1, 0, 6, 36, 46, }, + { 1, 1, 0, 6, 36, 46, }, + { 0, 1, 0, 6, 40, 46, }, + { 2, 1, 0, 6, 40, 46, }, + { 1, 1, 0, 6, 40, 46, }, + { 0, 1, 0, 6, 44, 46, }, + { 2, 1, 0, 6, 44, 46, }, + { 1, 1, 0, 6, 44, 46, }, + { 0, 1, 0, 6, 48, 46, }, + { 2, 1, 0, 6, 48, 46, }, + { 1, 1, 0, 6, 48, 46, }, + { 0, 1, 0, 6, 52, 46, }, + { 2, 1, 0, 6, 52, 46, }, + { 1, 1, 0, 6, 52, 46, }, + { 0, 1, 0, 6, 56, 46, }, + { 2, 1, 0, 6, 56, 46, }, + { 1, 1, 0, 6, 56, 46, }, + { 0, 1, 0, 6, 60, 46, }, + { 2, 1, 0, 6, 60, 46, }, + { 1, 1, 0, 6, 60, 46, }, + { 0, 1, 0, 6, 64, 46, }, + { 2, 1, 0, 6, 64, 46, }, + { 1, 1, 0, 6, 64, 46, }, + { 0, 1, 0, 6, 100, 46, }, + { 2, 1, 0, 6, 100, 46, }, + { 1, 1, 0, 6, 100, 46, }, + { 0, 1, 0, 6, 104, 46, }, + { 2, 1, 0, 6, 104, 46, }, + { 1, 1, 0, 6, 104, 46, }, + { 0, 1, 0, 6, 108, 46, }, + { 2, 1, 0, 6, 108, 46, }, + { 1, 1, 0, 6, 108, 46, }, + { 0, 1, 0, 6, 112, 46, }, + { 2, 1, 0, 6, 112, 46, }, + { 1, 1, 0, 6, 112, 46, }, + { 0, 1, 0, 6, 116, 46, }, + { 2, 1, 0, 6, 116, 46, }, + { 1, 1, 0, 6, 116, 46, }, + { 0, 1, 0, 6, 120, 46, }, + { 2, 1, 0, 6, 120, 46, }, + { 1, 1, 0, 6, 120, 46, }, + { 0, 1, 0, 6, 124, 46, }, + { 2, 1, 0, 6, 124, 46, }, + { 1, 1, 0, 6, 124, 46, }, + { 0, 1, 0, 6, 128, 46, }, + { 2, 1, 0, 6, 128, 46, }, + { 1, 1, 0, 6, 128, 46, }, + { 0, 1, 0, 6, 132, 46, }, + { 2, 1, 0, 6, 132, 46, }, + { 1, 1, 0, 6, 132, 46, }, + { 0, 1, 0, 6, 136, 46, }, + { 2, 1, 0, 6, 136, 46, }, + { 1, 1, 0, 6, 136, 46, }, + { 0, 1, 0, 6, 140, 46, }, + { 2, 1, 0, 6, 140, 46, }, + { 1, 1, 0, 6, 140, 46, }, + { 0, 1, 0, 6, 149, 46, }, + { 2, 1, 0, 6, 149, 46, }, + { 1, 1, 0, 6, 149, 63, }, + { 0, 1, 0, 6, 153, 46, }, + { 2, 1, 0, 6, 153, 46, }, + { 1, 1, 0, 6, 153, 63, }, + { 0, 1, 0, 6, 157, 46, }, + { 2, 1, 0, 6, 157, 46, }, + { 1, 1, 0, 6, 157, 63, }, + { 0, 1, 0, 6, 161, 46, }, + { 2, 1, 0, 6, 161, 46, }, + { 1, 1, 0, 6, 161, 63, }, + { 0, 1, 0, 6, 165, 46, }, + { 2, 1, 0, 6, 165, 46, }, + { 1, 1, 0, 6, 165, 63, }, + { 0, 1, 0, 7, 36, 46, }, + { 2, 1, 0, 7, 36, 46, }, + { 1, 1, 0, 7, 36, 46, }, + { 0, 1, 0, 7, 40, 46, }, + { 2, 1, 0, 7, 40, 46, }, + { 1, 1, 0, 7, 40, 46, }, + { 0, 1, 0, 7, 44, 46, }, + { 2, 1, 0, 7, 44, 46, }, + { 1, 1, 0, 7, 44, 46, }, + { 0, 1, 0, 7, 48, 46, }, + { 2, 1, 0, 7, 48, 46, }, + { 1, 1, 0, 7, 48, 46, }, + { 0, 1, 0, 7, 52, 46, }, + { 2, 1, 0, 7, 52, 46, }, + { 1, 1, 0, 7, 52, 46, }, + { 0, 1, 0, 7, 56, 46, }, + { 2, 1, 0, 7, 56, 46, }, + { 1, 1, 0, 7, 56, 46, }, + { 0, 1, 0, 7, 60, 46, }, + { 2, 1, 0, 7, 60, 46, }, + { 1, 1, 0, 7, 60, 46, }, + { 0, 1, 0, 7, 64, 46, }, + { 2, 1, 0, 7, 64, 46, }, + { 1, 1, 0, 7, 64, 46, }, + { 0, 1, 0, 7, 100, 46, }, + { 2, 1, 0, 7, 100, 46, }, + { 1, 1, 0, 7, 100, 46, }, + { 0, 1, 0, 7, 104, 46, }, + { 2, 1, 0, 7, 104, 46, }, + { 1, 1, 0, 7, 104, 46, }, + { 0, 1, 0, 7, 108, 46, }, + { 2, 1, 0, 7, 108, 46, }, + { 1, 1, 0, 7, 108, 46, }, + { 0, 1, 0, 7, 112, 46, }, + { 2, 1, 0, 7, 112, 46, }, + { 1, 1, 0, 7, 112, 46, }, + { 0, 1, 0, 7, 116, 46, }, + { 2, 1, 0, 7, 116, 46, }, + { 1, 1, 0, 7, 116, 46, }, + { 0, 1, 0, 7, 120, 46, }, + { 2, 1, 0, 7, 120, 46, }, + { 1, 1, 0, 7, 120, 46, }, + { 0, 1, 0, 7, 124, 46, }, + { 2, 1, 0, 7, 124, 46, }, + { 1, 1, 0, 7, 124, 46, }, + { 0, 1, 0, 7, 128, 46, }, + { 2, 1, 0, 7, 128, 46, }, + { 1, 1, 0, 7, 128, 46, }, + { 0, 1, 0, 7, 132, 46, }, + { 2, 1, 0, 7, 132, 46, }, + { 1, 1, 0, 7, 132, 46, }, + { 0, 1, 0, 7, 136, 46, }, + { 2, 1, 0, 7, 136, 46, }, + { 1, 1, 0, 7, 136, 46, }, + { 0, 1, 0, 7, 140, 46, }, + { 2, 1, 0, 7, 140, 46, }, + { 1, 1, 0, 7, 140, 46, }, + { 0, 1, 0, 7, 149, 46, }, + { 2, 1, 0, 7, 149, 46, }, + { 1, 1, 0, 7, 149, 63, }, + { 0, 1, 0, 7, 153, 46, }, + { 2, 1, 0, 7, 153, 46, }, + { 1, 1, 0, 7, 153, 63, }, + { 0, 1, 0, 7, 157, 46, }, + { 2, 1, 0, 7, 157, 46, }, + { 1, 1, 0, 7, 157, 63, }, + { 0, 1, 0, 7, 161, 46, }, + { 2, 1, 0, 7, 161, 46, }, + { 1, 1, 0, 7, 161, 63, }, + { 0, 1, 0, 7, 165, 46, }, + { 2, 1, 0, 7, 165, 46, }, + { 1, 1, 0, 7, 165, 63, }, + { 0, 1, 1, 2, 38, 46, }, + { 2, 1, 1, 2, 38, 46, }, + { 1, 1, 1, 2, 38, 46, }, + { 0, 1, 1, 2, 46, 46, }, + { 2, 1, 1, 2, 46, 46, }, + { 1, 1, 1, 2, 46, 46, }, + { 0, 1, 1, 2, 54, 46, }, + { 2, 1, 1, 2, 54, 46, }, + { 1, 1, 1, 2, 54, 46, }, + { 0, 1, 1, 2, 62, 46, }, + { 2, 1, 1, 2, 62, 46, }, + { 1, 1, 1, 2, 62, 46, }, + { 0, 1, 1, 2, 102, 46, }, + { 2, 1, 1, 2, 102, 46, }, + { 1, 1, 1, 2, 102, 46, }, + { 0, 1, 1, 2, 110, 46, }, + { 2, 1, 1, 2, 110, 46, }, + { 1, 1, 1, 2, 110, 46, }, + { 0, 1, 1, 2, 118, 46, }, + { 2, 1, 1, 2, 118, 46, }, + { 1, 1, 1, 2, 118, 46, }, + { 0, 1, 1, 2, 126, 46, }, + { 2, 1, 1, 2, 126, 46, }, + { 1, 1, 1, 2, 126, 46, }, + { 0, 1, 1, 2, 134, 46, }, + { 2, 1, 1, 2, 134, 46, }, + { 1, 1, 1, 2, 134, 46, }, + { 0, 1, 1, 2, 151, 46, }, + { 2, 1, 1, 2, 151, 46, }, + { 1, 1, 1, 2, 151, 63, }, + { 0, 1, 1, 2, 159, 46, }, + { 2, 1, 1, 2, 159, 46, }, + { 1, 1, 1, 2, 159, 63, }, + { 0, 1, 1, 3, 38, 46, }, + { 2, 1, 1, 3, 38, 46, }, + { 1, 1, 1, 3, 38, 46, }, + { 0, 1, 1, 3, 46, 46, }, + { 2, 1, 1, 3, 46, 46, }, + { 1, 1, 1, 3, 46, 46, }, + { 0, 1, 1, 3, 54, 46, }, + { 2, 1, 1, 3, 54, 46, }, + { 1, 1, 1, 3, 54, 46, }, + { 0, 1, 1, 3, 62, 46, }, + { 2, 1, 1, 3, 62, 46, }, + { 1, 1, 1, 3, 62, 46, }, + { 0, 1, 1, 3, 102, 46, }, + { 2, 1, 1, 3, 102, 46, }, + { 1, 1, 1, 3, 102, 46, }, + { 0, 1, 1, 3, 110, 46, }, + { 2, 1, 1, 3, 110, 46, }, + { 1, 1, 1, 3, 110, 46, }, + { 0, 1, 1, 3, 118, 46, }, + { 2, 1, 1, 3, 118, 46, }, + { 1, 1, 1, 3, 118, 46, }, + { 0, 1, 1, 3, 126, 46, }, + { 2, 1, 1, 3, 126, 46, }, + { 1, 1, 1, 3, 126, 46, }, + { 0, 1, 1, 3, 134, 46, }, + { 2, 1, 1, 3, 134, 46, }, + { 1, 1, 1, 3, 134, 46, }, + { 0, 1, 1, 3, 151, 46, }, + { 2, 1, 1, 3, 151, 46, }, + { 1, 1, 1, 3, 151, 63, }, + { 0, 1, 1, 3, 159, 46, }, + { 2, 1, 1, 3, 159, 46, }, + { 1, 1, 1, 3, 159, 63, }, + { 0, 1, 1, 6, 38, 46, }, + { 2, 1, 1, 6, 38, 46, }, + { 1, 1, 1, 6, 38, 46, }, + { 0, 1, 1, 6, 46, 46, }, + { 2, 1, 1, 6, 46, 46, }, + { 1, 1, 1, 6, 46, 46, }, + { 0, 1, 1, 6, 54, 46, }, + { 2, 1, 1, 6, 54, 46, }, + { 1, 1, 1, 6, 54, 46, }, + { 0, 1, 1, 6, 62, 46, }, + { 2, 1, 1, 6, 62, 46, }, + { 1, 1, 1, 6, 62, 46, }, + { 0, 1, 1, 6, 102, 46, }, + { 2, 1, 1, 6, 102, 46, }, + { 1, 1, 1, 6, 102, 46, }, + { 0, 1, 1, 6, 110, 46, }, + { 2, 1, 1, 6, 110, 46, }, + { 1, 1, 1, 6, 110, 46, }, + { 0, 1, 1, 6, 118, 46, }, + { 2, 1, 1, 6, 118, 46, }, + { 1, 1, 1, 6, 118, 46, }, + { 0, 1, 1, 6, 126, 46, }, + { 2, 1, 1, 6, 126, 46, }, + { 1, 1, 1, 6, 126, 46, }, + { 0, 1, 1, 6, 134, 46, }, + { 2, 1, 1, 6, 134, 46, }, + { 1, 1, 1, 6, 134, 46, }, + { 0, 1, 1, 6, 151, 46, }, + { 2, 1, 1, 6, 151, 46, }, + { 1, 1, 1, 6, 151, 63, }, + { 0, 1, 1, 6, 159, 46, }, + { 2, 1, 1, 6, 159, 46, }, + { 1, 1, 1, 6, 159, 63, }, + { 0, 1, 1, 7, 38, 46, }, + { 2, 1, 1, 7, 38, 46, }, + { 1, 1, 1, 7, 38, 46, }, + { 0, 1, 1, 7, 46, 46, }, + { 2, 1, 1, 7, 46, 46, }, + { 1, 1, 1, 7, 46, 46, }, + { 0, 1, 1, 7, 54, 46, }, + { 2, 1, 1, 7, 54, 46, }, + { 1, 1, 1, 7, 54, 46, }, + { 0, 1, 1, 7, 62, 46, }, + { 2, 1, 1, 7, 62, 46, }, + { 1, 1, 1, 7, 62, 46, }, + { 0, 1, 1, 7, 102, 46, }, + { 2, 1, 1, 7, 102, 46, }, + { 1, 1, 1, 7, 102, 46, }, + { 0, 1, 1, 7, 110, 46, }, + { 2, 1, 1, 7, 110, 46, }, + { 1, 1, 1, 7, 110, 46, }, + { 0, 1, 1, 7, 118, 46, }, + { 2, 1, 1, 7, 118, 46, }, + { 1, 1, 1, 7, 118, 46, }, + { 0, 1, 1, 7, 126, 46, }, + { 2, 1, 1, 7, 126, 46, }, + { 1, 1, 1, 7, 126, 46, }, + { 0, 1, 1, 7, 134, 46, }, + { 2, 1, 1, 7, 134, 46, }, + { 1, 1, 1, 7, 134, 46, }, + { 0, 1, 1, 7, 151, 46, }, + { 2, 1, 1, 7, 151, 46, }, + { 1, 1, 1, 7, 151, 63, }, + { 0, 1, 1, 7, 159, 46, }, + { 2, 1, 1, 7, 159, 46, }, + { 1, 1, 1, 7, 159, 63, }, + { 0, 1, 2, 4, 42, 46, }, + { 2, 1, 2, 4, 42, 46, }, + { 1, 1, 2, 4, 42, 46, }, + { 0, 1, 2, 4, 58, 46, }, + { 2, 1, 2, 4, 58, 46, }, + { 1, 1, 2, 4, 58, 46, }, + { 0, 1, 2, 4, 106, 46, }, + { 2, 1, 2, 4, 106, 46, }, + { 1, 1, 2, 4, 106, 46, }, + { 0, 1, 2, 4, 122, 46, }, + { 2, 1, 2, 4, 122, 46, }, + { 1, 1, 2, 4, 122, 46, }, + { 0, 1, 2, 4, 155, 46, }, + { 2, 1, 2, 4, 155, 46, }, + { 1, 1, 2, 4, 155, 63, }, + { 0, 1, 2, 5, 42, 46, }, + { 2, 1, 2, 5, 42, 46, }, + { 1, 1, 2, 5, 42, 46, }, + { 0, 1, 2, 5, 58, 46, }, + { 2, 1, 2, 5, 58, 46, }, + { 1, 1, 2, 5, 58, 46, }, + { 0, 1, 2, 5, 106, 46, }, + { 2, 1, 2, 5, 106, 46, }, + { 1, 1, 2, 5, 106, 46, }, + { 0, 1, 2, 5, 122, 46, }, + { 2, 1, 2, 5, 122, 46, }, + { 1, 1, 2, 5, 122, 46, }, + { 0, 1, 2, 5, 155, 46, }, + { 2, 1, 2, 5, 155, 46, }, + { 1, 1, 2, 5, 155, 63, }, + { 0, 1, 2, 8, 42, 46, }, + { 2, 1, 2, 8, 42, 46, }, + { 1, 1, 2, 8, 42, 46, }, + { 0, 1, 2, 8, 58, 46, }, + { 2, 1, 2, 8, 58, 46, }, + { 1, 1, 2, 8, 58, 46, }, + { 0, 1, 2, 8, 106, 46, }, + { 2, 1, 2, 8, 106, 46, }, + { 1, 1, 2, 8, 106, 46, }, + { 0, 1, 2, 8, 122, 46, }, + { 2, 1, 2, 8, 122, 46, }, + { 1, 1, 2, 8, 122, 46, }, + { 0, 1, 2, 8, 155, 46, }, + { 2, 1, 2, 8, 155, 46, }, + { 1, 1, 2, 8, 155, 63, }, + { 0, 1, 2, 9, 42, 46, }, + { 2, 1, 2, 9, 42, 46, }, + { 1, 1, 2, 9, 42, 46, }, + { 0, 1, 2, 9, 58, 46, }, + { 2, 1, 2, 9, 58, 46, }, + { 1, 1, 2, 9, 58, 46, }, + { 0, 1, 2, 9, 106, 46, }, + { 2, 1, 2, 9, 106, 46, }, + { 1, 1, 2, 9, 106, 46, }, + { 0, 1, 2, 9, 122, 46, }, + { 2, 1, 2, 9, 122, 46, }, + { 1, 1, 2, 9, 122, 46, }, + { 0, 1, 2, 9, 155, 46, }, + { 2, 1, 2, 9, 155, 46, }, + { 1, 1, 2, 9, 155, 63, }, +}; + +RTW_DECL_TABLE_TXPWR_LMT(rtw8814a_txpwr_lmt_type8); + +static const u8 +rtw8814a_pwrtrk_5gd_n[RTW_PWR_TRK_5G_NUM][RTW_PWR_TRK_TBL_SZ] = { + {0, 1, 1, 2, 3, 3, 4, 5, 5, 6, 7, 7, 8, 9, 9, 10, 11, + 11, 12, 13, 13, 14, 15, 15, 16, 17, 17, 18, 19, 19}, + {0, 1, 1, 2, 2, 3, 4, 4, 5, 6, 6, 7, 7, 8, 9, 9, 10, 10, + 11, 12, 12, 13, 13, 14, 15, 15, 16, 17, 17, 18}, + {0, 1, 1, 2, 3, 3, 4, 5, 5, 6, 6, 7, 8, 8, 9, 10, 10, + 11, 12, 12, 13, 14, 14, 15, 16, 16, 17, 17, 18, 19}, +}; + +static const u8 +rtw8814a_pwrtrk_5gd_p[RTW_PWR_TRK_5G_NUM][RTW_PWR_TRK_TBL_SZ] = { + {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, + 17, 18, 19, 20, 21, 22, 23, 24, 25, 25, 25, 25, 25}, + {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, + 17, 17, 18, 19, 20, 21, 22, 23, 24, 25, 25, 25, 25}, + {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, + 17, 17, 18, 19, 20, 21, 22, 23, 24, 25, 25, 25, 25}, +}; + +static const u8 +rtw8814a_pwrtrk_5gc_n[RTW_PWR_TRK_5G_NUM][RTW_PWR_TRK_TBL_SZ] = { + {0, 1, 1, 2, 2, 3, 4, 4, 5, 5, 6, 7, 7, 8, 8, 9, 10, 10, + 11, 12, 13, 14, 15, 15, 15, 15, 16, 16, 17, 18}, + {0, 1, 1, 2, 3, 3, 4, 5, 6, 6, 7, 8, 8, 9, 10, 10, 11, + 12, 12, 13, 14, 15, 15, 16, 17, 17, 18, 19, 19, 20}, + {0, 1, 1, 2, 3, 4, 4, 5, 6, 6, 7, 8, 8, 9, 10, 11, 11, + 12, 13, 13, 14, 14, 15, 16, 17, 18, 18, 19, 20, 20}, +}; + +static const u8 +rtw8814a_pwrtrk_5gc_p[RTW_PWR_TRK_5G_NUM][RTW_PWR_TRK_TBL_SZ] = { + {0, 1, 2, 3, 4, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, + 16, 16, 17, 18, 19, 20, 21, 21, 22, 23, 24, 25, 25}, + {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, + 17, 17, 18, 19, 20, 21, 22, 23, 24, 24, 25, 25, 25}, + {0, 1, 2, 3, 4, 5, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, + 16, 16, 17, 18, 19, 20, 21, 22, 23, 23, 24, 25, 25}, +}; + +static const u8 +rtw8814a_pwrtrk_5gb_n[RTW_PWR_TRK_5G_NUM][RTW_PWR_TRK_TBL_SZ] = { + {0, 1, 1, 2, 2, 3, 4, 4, 5, 5, 6, 7, 7, 8, 8, 9, 10, 10, + 11, 11, 12, 13, 13, 14, 14, 15, 15, 16, 17, 17}, + {0, 1, 1, 2, 3, 3, 4, 5, 6, 6, 7, 8, 8, 9, 10, 10, 11, + 12, 12, 13, 14, 15, 15, 16, 17, 17, 18, 19, 19, 20}, + {0, 1, 1, 2, 3, 4, 4, 5, 6, 6, 7, 8, 8, 9, 10, 11, 11, + 12, 13, 13, 14, 14, 15, 16, 17, 18, 18, 19, 20, 20}, +}; + +static const u8 +rtw8814a_pwrtrk_5gb_p[RTW_PWR_TRK_5G_NUM][RTW_PWR_TRK_TBL_SZ] = { + {0, 1, 2, 3, 3, 4, 5, 6, 7, 8, 8, 9, 10, 11, 12, 13, 14, + 15, 15, 16, 17, 18, 18, 19, 20, 21, 22, 23, 23, 24}, + {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, + 17, 18, 18, 19, 20, 21, 22, 23, 24, 25, 25, 25, 25}, + {0, 1, 2, 3, 4, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, + 16, 16, 17, 18, 19, 20, 20, 21, 22, 23, 24, 25, 25}, +}; + +static const u8 +rtw8814a_pwrtrk_5ga_n[RTW_PWR_TRK_5G_NUM][RTW_PWR_TRK_TBL_SZ] = { + {0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, + 8, 9, 9, 10, 11, 11, 11, 11, 12, 12, 13, 13, 14}, + {0, 1, 1, 2, 3, 4, 4, 5, 6, 6, 7, 8, 9, 9, 10, 11, 11, + 12, 13, 14, 14, 15, 16, 16, 17, 18, 19, 19, 20, 21}, + {0, 1, 1, 2, 3, 3, 4, 5, 5, 6, 6, 7, 8, 8, 9, 10, 10, + 11, 12, 12, 13, 14, 14, 15, 16, 16, 17, 17, 18, 19}, +}; + +static const u8 +rtw8814a_pwrtrk_5ga_p[RTW_PWR_TRK_5G_NUM][RTW_PWR_TRK_TBL_SZ] = { + {0, 1, 2, 2, 3, 4, 5, 6, 7, 7, 8, 9, 10, 11, 12, 12, 13, + 14, 15, 16, 16, 17, 18, 19, 20, 21, 21, 22, 23, 24}, + {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, + 17, 18, 19, 20, 21, 22, 23, 23, 24, 25, 25, 25, 25}, + {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, + 17, 17, 18, 19, 20, 21, 22, 23, 24, 25, 25, 25, 25}, +}; + +static const u8 rtw8814a_pwrtrk_2gd_n[RTW_PWR_TRK_TBL_SZ] = { + 0, 0, 1, 1, 2, 2, 3, 3, 3, 4, 4, 5, 5, 6, 6, 6, 7, + 7, 8, 8, 9, 9, 9, 10, 10, 11, 11, 12, 12, 12 +}; + +static const u8 rtw8814a_pwrtrk_2gd_p[RTW_PWR_TRK_TBL_SZ] = { + 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 4, 5, 5, 6, 6, 7, 7, + 8, 8, 9, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13 +}; + +static const u8 rtw8814a_pwrtrk_2gc_n[RTW_PWR_TRK_TBL_SZ] = { + 0, 0, 1, 1, 2, 2, 2, 3, 3, 4, 4, 5, 5, 5, 6, 6, 7, + 7, 7, 8, 8, 9, 9, 10, 10, 10, 11, 11, 12, 12 +}; + +static const u8 rtw8814a_pwrtrk_2gc_p[RTW_PWR_TRK_TBL_SZ] = { + 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 4, 5, 5, 6, 6, 7, 7, + 8, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 12, 13 +}; + +static const u8 rtw8814a_pwrtrk_2gb_n[RTW_PWR_TRK_TBL_SZ] = { + 0, 0, 1, 1, 2, 2, 3, 3, 3, 4, 4, 5, 5, 5, 6, 6, 7, + 7, 8, 8, 8, 9, 9, 10, 10, 11, 11, 11, 12, 12 +}; + +static const u8 rtw8814a_pwrtrk_2gb_p[RTW_PWR_TRK_TBL_SZ] = { + 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 4, 5, 5, 6, 6, 7, 7, + 8, 8, 9, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13 +}; + +static const u8 rtw8814a_pwrtrk_2ga_n[RTW_PWR_TRK_TBL_SZ] = { + 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 4, 5, 5, 6, 6, 7, 7, + 7, 8, 8, 9, 9, 10, 10, 11, 11, 11, 12, 12, 13 +}; + +static const u8 rtw8814a_pwrtrk_2ga_p[RTW_PWR_TRK_TBL_SZ] = { + 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, + 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13, 14, 14 +}; + +static const u8 rtw8814a_pwrtrk_2g_cck_d_n[RTW_PWR_TRK_TBL_SZ] = { + 0, 0, 1, 1, 2, 2, 3, 3, 3, 4, 4, 5, 5, 5, 6, 6, 7, + 7, 8, 8, 8, 9, 9, 10, 10, 10, 11, 11, 12, 12 +}; + +static const u8 rtw8814a_pwrtrk_2g_cck_d_p[RTW_PWR_TRK_TBL_SZ] = { + 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 4, 5, 5, 6, 6, 7, 7, + 8, 8, 9, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13 +}; + +static const u8 rtw8814a_pwrtrk_2g_cck_c_n[RTW_PWR_TRK_TBL_SZ] = { + 0, 0, 1, 1, 2, 2, 2, 3, 3, 4, 4, 4, 5, 5, 6, 6, 6, + 7, 7, 8, 8, 8, 9, 9, 10, 10, 10, 11, 11, 12 +}; + +static const u8 rtw8814a_pwrtrk_2g_cck_c_p[RTW_PWR_TRK_TBL_SZ] = { + 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 4, 5, 5, 6, 6, 7, 7, + 7, 8, 8, 9, 9, 10, 10, 11, 11, 11, 12, 12, 13 +}; + +static const u8 rtw8814a_pwrtrk_2g_cck_b_n[RTW_PWR_TRK_TBL_SZ] = { + 0, 0, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 5, 5, 5, 6, + 6, 6, 7, 7, 8, 8, 8, 9, 9, 10, 10, 10, 11, 11 +}; + +static const u8 rtw8814a_pwrtrk_2g_cck_b_p[RTW_PWR_TRK_TBL_SZ] = { + 0, 0, 1, 1, 2, 2, 3, 3, 3, 4, 4, 5, 5, 6, 6, 6, 7, + 7, 8, 8, 9, 9, 9, 10, 10, 11, 11, 12, 12, 12 +}; + +static const u8 rtw8814a_pwrtrk_2g_cck_a_n[RTW_PWR_TRK_TBL_SZ] = { + 0, 0, 1, 1, 2, 2, 3, 3, 3, 4, 4, 5, 5, 5, 6, 6, 7, + 7, 8, 8, 8, 9, 9, 10, 10, 11, 11, 11, 12, 12 +}; + +static const u8 rtw8814a_pwrtrk_2g_cck_a_p[RTW_PWR_TRK_TBL_SZ] = { + 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 7, + 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13, 14 +}; + +const struct rtw_pwr_track_tbl rtw8814a_rtw_pwrtrk_tbl = { + .pwrtrk_5gd_n[RTW_PWR_TRK_5G_1] = rtw8814a_pwrtrk_5gd_n[RTW_PWR_TRK_5G_1], + .pwrtrk_5gd_n[RTW_PWR_TRK_5G_2] = rtw8814a_pwrtrk_5gd_n[RTW_PWR_TRK_5G_2], + .pwrtrk_5gd_n[RTW_PWR_TRK_5G_3] = rtw8814a_pwrtrk_5gd_n[RTW_PWR_TRK_5G_3], + .pwrtrk_5gd_p[RTW_PWR_TRK_5G_1] = rtw8814a_pwrtrk_5gd_p[RTW_PWR_TRK_5G_1], + .pwrtrk_5gd_p[RTW_PWR_TRK_5G_2] = rtw8814a_pwrtrk_5gd_p[RTW_PWR_TRK_5G_2], + .pwrtrk_5gd_p[RTW_PWR_TRK_5G_3] = rtw8814a_pwrtrk_5gd_p[RTW_PWR_TRK_5G_3], + .pwrtrk_5gc_n[RTW_PWR_TRK_5G_1] = rtw8814a_pwrtrk_5gc_n[RTW_PWR_TRK_5G_1], + .pwrtrk_5gc_n[RTW_PWR_TRK_5G_2] = rtw8814a_pwrtrk_5gc_n[RTW_PWR_TRK_5G_2], + .pwrtrk_5gc_n[RTW_PWR_TRK_5G_3] = rtw8814a_pwrtrk_5gc_n[RTW_PWR_TRK_5G_3], + .pwrtrk_5gc_p[RTW_PWR_TRK_5G_1] = rtw8814a_pwrtrk_5gc_p[RTW_PWR_TRK_5G_1], + .pwrtrk_5gc_p[RTW_PWR_TRK_5G_2] = rtw8814a_pwrtrk_5gc_p[RTW_PWR_TRK_5G_2], + .pwrtrk_5gc_p[RTW_PWR_TRK_5G_3] = rtw8814a_pwrtrk_5gc_p[RTW_PWR_TRK_5G_3], + .pwrtrk_5gb_n[RTW_PWR_TRK_5G_1] = rtw8814a_pwrtrk_5gb_n[RTW_PWR_TRK_5G_1], + .pwrtrk_5gb_n[RTW_PWR_TRK_5G_2] = rtw8814a_pwrtrk_5gb_n[RTW_PWR_TRK_5G_2], + .pwrtrk_5gb_n[RTW_PWR_TRK_5G_3] = rtw8814a_pwrtrk_5gb_n[RTW_PWR_TRK_5G_3], + .pwrtrk_5gb_p[RTW_PWR_TRK_5G_1] = rtw8814a_pwrtrk_5gb_p[RTW_PWR_TRK_5G_1], + .pwrtrk_5gb_p[RTW_PWR_TRK_5G_2] = rtw8814a_pwrtrk_5gb_p[RTW_PWR_TRK_5G_2], + .pwrtrk_5gb_p[RTW_PWR_TRK_5G_3] = rtw8814a_pwrtrk_5gb_p[RTW_PWR_TRK_5G_3], + .pwrtrk_5ga_n[RTW_PWR_TRK_5G_1] = rtw8814a_pwrtrk_5ga_n[RTW_PWR_TRK_5G_1], + .pwrtrk_5ga_n[RTW_PWR_TRK_5G_2] = rtw8814a_pwrtrk_5ga_n[RTW_PWR_TRK_5G_2], + .pwrtrk_5ga_n[RTW_PWR_TRK_5G_3] = rtw8814a_pwrtrk_5ga_n[RTW_PWR_TRK_5G_3], + .pwrtrk_5ga_p[RTW_PWR_TRK_5G_1] = rtw8814a_pwrtrk_5ga_p[RTW_PWR_TRK_5G_1], + .pwrtrk_5ga_p[RTW_PWR_TRK_5G_2] = rtw8814a_pwrtrk_5ga_p[RTW_PWR_TRK_5G_2], + .pwrtrk_5ga_p[RTW_PWR_TRK_5G_3] = rtw8814a_pwrtrk_5ga_p[RTW_PWR_TRK_5G_3], + .pwrtrk_2gd_n = rtw8814a_pwrtrk_2gd_n, + .pwrtrk_2gd_p = rtw8814a_pwrtrk_2gd_p, + .pwrtrk_2gc_n = rtw8814a_pwrtrk_2gc_n, + .pwrtrk_2gc_p = rtw8814a_pwrtrk_2gc_p, + .pwrtrk_2gb_n = rtw8814a_pwrtrk_2gb_n, + .pwrtrk_2gb_p = rtw8814a_pwrtrk_2gb_p, + .pwrtrk_2ga_n = rtw8814a_pwrtrk_2ga_n, + .pwrtrk_2ga_p = rtw8814a_pwrtrk_2ga_p, + .pwrtrk_2g_cckd_n = rtw8814a_pwrtrk_2g_cck_d_n, + .pwrtrk_2g_cckd_p = rtw8814a_pwrtrk_2g_cck_d_p, + .pwrtrk_2g_cckc_n = rtw8814a_pwrtrk_2g_cck_c_n, + .pwrtrk_2g_cckc_p = rtw8814a_pwrtrk_2g_cck_c_p, + .pwrtrk_2g_cckb_n = rtw8814a_pwrtrk_2g_cck_b_n, + .pwrtrk_2g_cckb_p = rtw8814a_pwrtrk_2g_cck_b_p, + .pwrtrk_2g_ccka_n = rtw8814a_pwrtrk_2g_cck_a_n, + .pwrtrk_2g_ccka_p = rtw8814a_pwrtrk_2g_cck_a_p, +}; + +static const u8 +rtw8814a_pwrtrk_type0_5gd_n[RTW_PWR_TRK_5G_NUM][RTW_PWR_TRK_TBL_SZ] = { + {0, 0, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, + 8, 9, 9, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10}, + {0, 0, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, + 8, 9, 9, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10}, + {0, 0, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, + 8, 9, 9, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10}, +}; + +static const u8 +rtw8814a_pwrtrk_type0_5gd_p[RTW_PWR_TRK_5G_NUM][RTW_PWR_TRK_TBL_SZ] = { + {0, 0, 1, 1, 2, 3, 3, 4, 5, 5, 6, 6, 7, 8, 8, 9, 10, 10, + 11, 11, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12}, + {0, 0, 1, 1, 2, 3, 3, 4, 5, 5, 6, 6, 7, 8, 8, 9, 10, 10, + 11, 11, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12}, + {0, 0, 1, 1, 2, 3, 3, 4, 5, 5, 6, 6, 7, 8, 8, 9, 10, 10, + 11, 11, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12}, +}; + +static const u8 +rtw8814a_pwrtrk_type0_5gc_n[RTW_PWR_TRK_5G_NUM][RTW_PWR_TRK_TBL_SZ] = { + {0, 0, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, + 8, 9, 9, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10}, + {0, 0, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, + 8, 9, 9, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10}, + {0, 0, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, + 8, 9, 9, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10}, +}; + +static const u8 +rtw8814a_pwrtrk_type0_5gc_p[RTW_PWR_TRK_5G_NUM][RTW_PWR_TRK_TBL_SZ] = { + {0, 0, 1, 1, 2, 3, 3, 4, 5, 5, 6, 6, 7, 8, 8, 9, 10, 10, + 11, 11, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12}, + {0, 0, 1, 1, 2, 3, 3, 4, 5, 5, 6, 6, 7, 8, 8, 9, 10, 10, + 11, 11, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12}, + {0, 0, 1, 1, 2, 3, 3, 4, 5, 5, 6, 6, 7, 8, 8, 9, 10, 10, + 11, 11, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12}, +}; + +static const u8 +rtw8814a_pwrtrk_type0_5gb_n[RTW_PWR_TRK_5G_NUM][RTW_PWR_TRK_TBL_SZ] = { + {0, 0, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, + 8, 9, 9, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10}, + {0, 0, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, + 8, 9, 9, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10}, + {0, 0, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, + 8, 9, 9, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10}, +}; + +static const u8 +rtw8814a_pwrtrk_type0_5gb_p[RTW_PWR_TRK_5G_NUM][RTW_PWR_TRK_TBL_SZ] = { + {0, 0, 1, 1, 2, 3, 3, 4, 5, 5, 6, 6, 7, 8, 8, 9, 10, 10, + 11, 11, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12}, + {0, 0, 1, 1, 2, 3, 3, 4, 5, 5, 6, 6, 7, 8, 8, 9, 10, 10, + 11, 11, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12}, + {0, 0, 1, 1, 2, 3, 3, 4, 5, 5, 6, 6, 7, 8, 8, 9, 10, 10, + 11, 11, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12}, +}; + +static const u8 +rtw8814a_pwrtrk_type0_5ga_n[RTW_PWR_TRK_5G_NUM][RTW_PWR_TRK_TBL_SZ] = { + {0, 0, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, + 8, 9, 9, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10}, + {0, 0, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, + 8, 9, 9, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10}, + {0, 0, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, + 8, 9, 9, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10}, +}; + +static const u8 +rtw8814a_pwrtrk_type0_5ga_p[RTW_PWR_TRK_5G_NUM][RTW_PWR_TRK_TBL_SZ] = { + {0, 0, 1, 1, 2, 3, 3, 4, 5, 5, 6, 6, 7, 8, 8, 9, 10, 10, + 11, 11, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12}, + {0, 0, 1, 1, 2, 3, 3, 4, 5, 5, 6, 6, 7, 8, 8, 9, 10, 10, + 11, 11, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12}, + {0, 0, 1, 1, 2, 3, 3, 4, 5, 5, 6, 6, 7, 8, 8, 9, 10, 10, + 11, 11, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12}, +}; + +static const u8 rtw8814a_pwrtrk_type0_2gd_n[RTW_PWR_TRK_TBL_SZ] = { + 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 5, 6, 7, 7, + 7, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9 +}; + +static const u8 rtw8814a_pwrtrk_type0_2gd_p[RTW_PWR_TRK_TBL_SZ] = { + 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, + 8, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9 +}; + +static const u8 rtw8814a_pwrtrk_type0_2gc_n[RTW_PWR_TRK_TBL_SZ] = { + 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 5, 6, 7, 7, + 7, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9 +}; + +static const u8 rtw8814a_pwrtrk_type0_2gc_p[RTW_PWR_TRK_TBL_SZ] = { + 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, + 8, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9 +}; + +static const u8 rtw8814a_pwrtrk_type0_2gb_n[RTW_PWR_TRK_TBL_SZ] = { + 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 5, 6, 7, 7, + 7, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9 +}; + +static const u8 rtw8814a_pwrtrk_type0_2gb_p[RTW_PWR_TRK_TBL_SZ] = { + 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, + 8, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9 +}; + +static const u8 rtw8814a_pwrtrk_type0_2ga_n[RTW_PWR_TRK_TBL_SZ] = { + 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 5, 6, 7, 7, + 7, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9 +}; + +static const u8 rtw8814a_pwrtrk_type0_2ga_p[RTW_PWR_TRK_TBL_SZ] = { + 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, + 8, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9 +}; + +static const u8 rtw8814a_pwrtrk_type0_2g_cck_d_n[RTW_PWR_TRK_TBL_SZ] = { + 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 5, 6, 7, 7, + 7, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9 +}; + +static const u8 rtw8814a_pwrtrk_type0_2g_cck_d_p[RTW_PWR_TRK_TBL_SZ] = { + 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, + 8, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9 +}; + +static const u8 rtw8814a_pwrtrk_type0_2g_cck_c_n[RTW_PWR_TRK_TBL_SZ] = { + 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 5, 6, 7, 7, + 7, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9 +}; + +static const u8 rtw8814a_pwrtrk_type0_2g_cck_c_p[RTW_PWR_TRK_TBL_SZ] = { + 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, + 8, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9 +}; + +static const u8 rtw8814a_pwrtrk_type0_2g_cck_b_n[RTW_PWR_TRK_TBL_SZ] = { + 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 5, 6, 7, 7, + 7, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9 +}; + +static const u8 rtw8814a_pwrtrk_type0_2g_cck_b_p[RTW_PWR_TRK_TBL_SZ] = { + 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, + 8, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9 +}; + +static const u8 rtw8814a_pwrtrk_type0_2g_cck_a_n[RTW_PWR_TRK_TBL_SZ] = { + 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 5, 6, 7, 7, + 7, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9 +}; + +static const u8 rtw8814a_pwrtrk_type0_2g_cck_a_p[RTW_PWR_TRK_TBL_SZ] = { + 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, + 8, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9 +}; + +const struct rtw_pwr_track_tbl rtw8814a_rtw_pwrtrk_type0_tbl = { + .pwrtrk_5gd_n[RTW_PWR_TRK_5G_1] = rtw8814a_pwrtrk_type0_5gd_n[RTW_PWR_TRK_5G_1], + .pwrtrk_5gd_n[RTW_PWR_TRK_5G_2] = rtw8814a_pwrtrk_type0_5gd_n[RTW_PWR_TRK_5G_2], + .pwrtrk_5gd_n[RTW_PWR_TRK_5G_3] = rtw8814a_pwrtrk_type0_5gd_n[RTW_PWR_TRK_5G_3], + .pwrtrk_5gd_p[RTW_PWR_TRK_5G_1] = rtw8814a_pwrtrk_type0_5gd_p[RTW_PWR_TRK_5G_1], + .pwrtrk_5gd_p[RTW_PWR_TRK_5G_2] = rtw8814a_pwrtrk_type0_5gd_p[RTW_PWR_TRK_5G_2], + .pwrtrk_5gd_p[RTW_PWR_TRK_5G_3] = rtw8814a_pwrtrk_type0_5gd_p[RTW_PWR_TRK_5G_3], + .pwrtrk_5gc_n[RTW_PWR_TRK_5G_1] = rtw8814a_pwrtrk_type0_5gc_n[RTW_PWR_TRK_5G_1], + .pwrtrk_5gc_n[RTW_PWR_TRK_5G_2] = rtw8814a_pwrtrk_type0_5gc_n[RTW_PWR_TRK_5G_2], + .pwrtrk_5gc_n[RTW_PWR_TRK_5G_3] = rtw8814a_pwrtrk_type0_5gc_n[RTW_PWR_TRK_5G_3], + .pwrtrk_5gc_p[RTW_PWR_TRK_5G_1] = rtw8814a_pwrtrk_type0_5gc_p[RTW_PWR_TRK_5G_1], + .pwrtrk_5gc_p[RTW_PWR_TRK_5G_2] = rtw8814a_pwrtrk_type0_5gc_p[RTW_PWR_TRK_5G_2], + .pwrtrk_5gc_p[RTW_PWR_TRK_5G_3] = rtw8814a_pwrtrk_type0_5gc_p[RTW_PWR_TRK_5G_3], + .pwrtrk_5gb_n[RTW_PWR_TRK_5G_1] = rtw8814a_pwrtrk_type0_5gb_n[RTW_PWR_TRK_5G_1], + .pwrtrk_5gb_n[RTW_PWR_TRK_5G_2] = rtw8814a_pwrtrk_type0_5gb_n[RTW_PWR_TRK_5G_2], + .pwrtrk_5gb_n[RTW_PWR_TRK_5G_3] = rtw8814a_pwrtrk_type0_5gb_n[RTW_PWR_TRK_5G_3], + .pwrtrk_5gb_p[RTW_PWR_TRK_5G_1] = rtw8814a_pwrtrk_type0_5gb_p[RTW_PWR_TRK_5G_1], + .pwrtrk_5gb_p[RTW_PWR_TRK_5G_2] = rtw8814a_pwrtrk_type0_5gb_p[RTW_PWR_TRK_5G_2], + .pwrtrk_5gb_p[RTW_PWR_TRK_5G_3] = rtw8814a_pwrtrk_type0_5gb_p[RTW_PWR_TRK_5G_3], + .pwrtrk_5ga_n[RTW_PWR_TRK_5G_1] = rtw8814a_pwrtrk_type0_5ga_n[RTW_PWR_TRK_5G_1], + .pwrtrk_5ga_n[RTW_PWR_TRK_5G_2] = rtw8814a_pwrtrk_type0_5ga_n[RTW_PWR_TRK_5G_2], + .pwrtrk_5ga_n[RTW_PWR_TRK_5G_3] = rtw8814a_pwrtrk_type0_5ga_n[RTW_PWR_TRK_5G_3], + .pwrtrk_5ga_p[RTW_PWR_TRK_5G_1] = rtw8814a_pwrtrk_type0_5ga_p[RTW_PWR_TRK_5G_1], + .pwrtrk_5ga_p[RTW_PWR_TRK_5G_2] = rtw8814a_pwrtrk_type0_5ga_p[RTW_PWR_TRK_5G_2], + .pwrtrk_5ga_p[RTW_PWR_TRK_5G_3] = rtw8814a_pwrtrk_type0_5ga_p[RTW_PWR_TRK_5G_3], + .pwrtrk_2gd_n = rtw8814a_pwrtrk_type0_2gd_n, + .pwrtrk_2gd_p = rtw8814a_pwrtrk_type0_2gd_p, + .pwrtrk_2gc_n = rtw8814a_pwrtrk_type0_2gc_n, + .pwrtrk_2gc_p = rtw8814a_pwrtrk_type0_2gc_p, + .pwrtrk_2gb_n = rtw8814a_pwrtrk_type0_2gb_n, + .pwrtrk_2gb_p = rtw8814a_pwrtrk_type0_2gb_p, + .pwrtrk_2ga_n = rtw8814a_pwrtrk_type0_2ga_n, + .pwrtrk_2ga_p = rtw8814a_pwrtrk_type0_2ga_p, + .pwrtrk_2g_cckd_n = rtw8814a_pwrtrk_type0_2g_cck_d_n, + .pwrtrk_2g_cckd_p = rtw8814a_pwrtrk_type0_2g_cck_d_p, + .pwrtrk_2g_cckc_n = rtw8814a_pwrtrk_type0_2g_cck_c_n, + .pwrtrk_2g_cckc_p = rtw8814a_pwrtrk_type0_2g_cck_c_p, + .pwrtrk_2g_cckb_n = rtw8814a_pwrtrk_type0_2g_cck_b_n, + .pwrtrk_2g_cckb_p = rtw8814a_pwrtrk_type0_2g_cck_b_p, + .pwrtrk_2g_ccka_n = rtw8814a_pwrtrk_type0_2g_cck_a_n, + .pwrtrk_2g_ccka_p = rtw8814a_pwrtrk_type0_2g_cck_a_p, +}; + +static const u8 +rtw8814a_pwrtrk_type2_5gd_n[RTW_PWR_TRK_5G_NUM][RTW_PWR_TRK_TBL_SZ] = { + {0, 1, 2, 3, 4, 5, 6, 7, 7, 8, 9, 10, 10, 11, 11, 12, 12, + 12, 13, 14, 15, 15, 16, 16, 16, 16, 16, 16, 16, 16}, + {0, 1, 2, 3, 4, 5, 5, 6, 6, 7, 8, 9, 9, 10, 10, 10, 10, + 11, 11, 12, 12, 13, 14, 15, 16, 16, 16, 16, 16, 16}, + {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 9, 10, 10, 11, 11, 11, 12, + 12, 13, 14, 14, 15, 15, 15, 15, 15, 15, 15, 15, 15}, +}; + +static const u8 +rtw8814a_pwrtrk_type2_5gd_p[RTW_PWR_TRK_5G_NUM][RTW_PWR_TRK_TBL_SZ] = { + {0, 0, 1, 2, 3, 4, 5, 6, 7, 8, 8, 9, 10, 11, 12, 13, 14, + 15, 16, 17, 18, 19, 20, 21, 22, 22, 22, 22, 22, 22}, + {0, 1, 2, 3, 4, 4, 5, 6, 7, 7, 8, 9, 10, 11, 12, 13, 14, + 15, 16, 17, 18, 19, 20, 21, 22, 22, 22, 22, 22, 22}, + {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, + 17, 18, 19, 20, 21, 22, 23, 23, 23, 23, 23, 23, 23}, +}; + +static const u8 +rtw8814a_pwrtrk_type2_5gc_n[RTW_PWR_TRK_5G_NUM][RTW_PWR_TRK_TBL_SZ] = { + {0, 1, 2, 3, 3, 4, 5, 6, 7, 7, 8, 9, 10, 10, 11, 11, 12, + 12, 13, 14, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15}, + {0, 1, 2, 3, 4, 5, 5, 6, 7, 8, 9, 9, 10, 10, 11, 11, 12, + 13, 13, 14, 14, 15, 15, 15, 15, 15, 15, 15, 15, 15}, + {0, 1, 2, 3, 4, 4, 5, 6, 6, 7, 8, 8, 9, 9, 10, 11, 11, + 12, 12, 13, 13, 13, 14, 14, 14, 14, 14, 14, 14, 14}, +}; + +static const u8 +rtw8814a_pwrtrk_type2_5gc_p[RTW_PWR_TRK_5G_NUM][RTW_PWR_TRK_TBL_SZ] = { + {0, 1, 2, 3, 4, 5, 6, 6, 7, 8, 9, 10, 11, 11, 12, 13, 14, + 15, 16, 17, 18, 19, 20, 21, 21, 21, 21, 21, 21, 21}, + {0, 1, 2, 3, 4, 5, 6, 6, 7, 8, 8, 9, 10, 11, 12, 13, 14, + 15, 16, 17, 18, 19, 20, 20, 20, 21, 21, 21, 21, 21}, + {0, 1, 2, 3, 3, 4, 5, 6, 7, 7, 8, 9, 10, 11, 12, 13, 14, + 15, 16, 17, 18, 19, 20, 21, 21, 21, 21, 21, 21, 21}, +}; + +static const u8 +rtw8814a_pwrtrk_type2_5gb_n[RTW_PWR_TRK_5G_NUM][RTW_PWR_TRK_TBL_SZ] = { + {0, 1, 2, 2, 3, 4, 5, 6, 7, 8, 9, 10, 10, 10, 11, 12, 13, + 13, 13, 14, 14, 14, 15, 15, 15, 15, 15, 15, 15, 15}, + {0, 1, 2, 3, 4, 5, 5, 6, 7, 8, 9, 9, 10, 10, 11, 11, 12, + 13, 13, 14, 14, 15, 15, 15, 15, 15, 15, 15, 15, 15}, + {0, 1, 2, 3, 4, 4, 5, 6, 6, 7, 8, 8, 9, 9, 10, 11, 11, + 12, 12, 13, 13, 13, 14, 14, 14, 14, 14, 14, 14, 14}, +}; + +static const u8 +rtw8814a_pwrtrk_type2_5gb_p[RTW_PWR_TRK_5G_NUM][RTW_PWR_TRK_TBL_SZ] = { + {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 11, 12, 13, 14, 15, + 16, 17, 18, 19, 20, 21, 21, 21, 21, 21, 21, 21, 21}, + {0, 0, 1, 2, 3, 4, 5, 6, 6, 7, 8, 9, 10, 10, 11, 12, 13, + 14, 15, 16, 17, 18, 19, 20, 20, 20, 20, 20, 20, 20}, + {0, 1, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 11, 12, 13, 14, + 15, 16, 17, 18, 19, 20, 21, 21, 21, 21, 21, 21, 21}, +}; + +static const u8 +rtw8814a_pwrtrk_type2_5ga_n[RTW_PWR_TRK_5G_NUM][RTW_PWR_TRK_TBL_SZ] = { + {0, 1, 2, 3, 4, 5, 5, 6, 7, 7, 8, 9, 10, 10, 11, 11, 11, + 12, 13, 13, 13, 13, 14, 15, 15, 15, 15, 15, 15, 15}, + {0, 1, 2, 3, 3, 4, 5, 6, 7, 8, 8, 9, 10, 10, 11, 12, 12, + 12, 13, 13, 13, 14, 14, 14, 14, 14, 14, 14, 14, 14}, + {0, 1, 2, 3, 4, 4, 5, 6, 7, 7, 8, 9, 10, 11, 11, 11, 12, + 12, 12, 12, 12, 13, 13, 13, 13, 13, 13, 13, 13, 13}, +}; + +static const u8 +rtw8814a_pwrtrk_type2_5ga_p[RTW_PWR_TRK_5G_NUM][RTW_PWR_TRK_TBL_SZ] = { + {0, 1, 2, 3, 4, 5, 5, 6, 7, 8, 9, 10, 10, 11, 12, 13, 14, + 15, 15, 16, 17, 18, 18, 19, 19, 20, 20, 20, 20, 20}, + {0, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 10, 11, 12, 13, 14, + 15, 16, 16, 17, 18, 19, 20, 20, 20, 20, 20, 20, 20}, + {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 11, 12, 13, 14, 15, + 15, 16, 17, 18, 19, 19, 20, 20, 20, 20, 20, 20, 20}, +}; + +static const u8 rtw8814a_pwrtrk_type2_2gd_n[RTW_PWR_TRK_TBL_SZ] = { + 0, 0, 1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 4, 5, 5, 5, + 6, 6, 7, 8, 9, 10, 11, 11, 11, 11, 11, 11, 11 +}; + +static const u8 rtw8814a_pwrtrk_type2_2gd_p[RTW_PWR_TRK_TBL_SZ] = { + 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 6, 6, 7, 7, 8, 9, 9, 10, + 10, 11, 12, 12, 13, 14, 14, 14, 14, 14, 14, 14 +}; + +static const u8 rtw8814a_pwrtrk_type2_2gc_n[RTW_PWR_TRK_TBL_SZ] = { + 0, 1, 1, 2, 2, 3, 3, 4, 5, 6, 6, 6, 7, 7, 8, 8, 9, 10, + 10, 11, 12, 12, 13, 13, 13, 13, 14, 14, 14, 14 +}; + +static const u8 rtw8814a_pwrtrk_type2_2gc_p[RTW_PWR_TRK_TBL_SZ] = { + 0, 1, 1, 2, 3, 3, 4, 4, 4, 5, 5, 6, 7, 8, 8, 9, 10, 10, + 11, 12, 13, 13, 14, 14, 14, 14, 14, 14, 14, 14 +}; + +static const u8 rtw8814a_pwrtrk_type2_2gb_n[RTW_PWR_TRK_TBL_SZ] = { + 0, 1, 1, 2, 2, 3, 3, 4, 5, 5, 6, 6, 7, 7, 8, 8, 8, + 9, 9, 10, 10, 11, 11, 12, 12, 12, 13, 14, 14, 14 +}; + +static const u8 rtw8814a_pwrtrk_type2_2gb_p[RTW_PWR_TRK_TBL_SZ] = { + 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 6, 6, 7, 8, 8, 9, 9, 10, + 10, 11, 12, 12, 13, 13, 13, 13, 13, 14, 14, 14 +}; + +static const u8 rtw8814a_pwrtrk_type2_2ga_n[RTW_PWR_TRK_TBL_SZ] = { + 0, 0, 1, 2, 2, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 9, 9, 9, + 10, 11, 11, 12, 12, 13, 13, 13, 13, 13, 13, 13 +}; + +static const u8 rtw8814a_pwrtrk_type2_2ga_p[RTW_PWR_TRK_TBL_SZ] = { + 0, 1, 1, 2, 3, 3, 4, 4, 4, 5, 6, 6, 7, 7, 8, 8, 9, 10, + 11, 12, 12, 13, 13, 14, 14, 14, 14, 14, 14, 14 +}; + +static const u8 rtw8814a_pwrtrk_type2_2g_cck_d_n[RTW_PWR_TRK_TBL_SZ] = { + 0, 1, 1, 2, 3, 3, 3, 4, 4, 4, 5, 5, 5, 6, 6, 7, 8, + 9, 9, 9, 9, 9, 9, 10, 10, 11, 11, 12, 12, 12 +}; + +static const u8 rtw8814a_pwrtrk_type2_2g_cck_d_p[RTW_PWR_TRK_TBL_SZ] = { + 0, 1, 1, 1, 2, 3, 3, 4, 4, 5, 6, 6, 7, 8, 8, 9, 10, 10, + 10, 11, 12, 12, 13, 14, 14, 14, 14, 14, 14, 14 +}; + +static const u8 rtw8814a_pwrtrk_type2_2g_cck_c_n[RTW_PWR_TRK_TBL_SZ] = { + 0, 0, 1, 2, 2, 3, 4, 5, 5, 6, 6, 6, 6, 7, 8, 9, 9, 10, + 10, 11, 11, 11, 12, 13, 13, 13, 13, 13, 13, 13 +}; + +static const u8 rtw8814a_pwrtrk_type2_2g_cck_c_p[RTW_PWR_TRK_TBL_SZ] = { + 0, 0, 1, 1, 2, 2, 3, 3, 4, 5, 5, 6, 7, 7, 8, 9, 9, 10, + 10, 11, 12, 12, 13, 13, 13, 13, 13, 13, 13, 13 +}; + +static const u8 rtw8814a_pwrtrk_type2_2g_cck_b_n[RTW_PWR_TRK_TBL_SZ] = { + 0, 1, 1, 2, 2, 2, 3, 3, 4, 5, 6, 6, 7, 7, 8, 8, 9, 10, + 10, 10, 11, 11, 12, 12, 12, 12, 12, 12, 12, 12 +}; + +static const u8 rtw8814a_pwrtrk_type2_2g_cck_b_p[RTW_PWR_TRK_TBL_SZ] = { + 0, 1, 1, 1, 2, 3, 3, 4, 4, 5, 5, 6, 7, 8, 8, 9, 9, 10, + 10, 11, 12, 12, 13, 13, 13, 13, 13, 13, 13, 13 +}; + +static const u8 rtw8814a_pwrtrk_type2_2g_cck_a_n[RTW_PWR_TRK_TBL_SZ] = { + 0, 1, 2, 2, 3, 4, 4, 4, 5, 5, 6, 6, 7, 8, 9, 9, 9, 9, + 10, 10, 11, 11, 11, 12, 12, 12, 12, 12, 12, 12 +}; + +static const u8 rtw8814a_pwrtrk_type2_2g_cck_a_p[RTW_PWR_TRK_TBL_SZ] = { + 0, 0, 1, 2, 2, 3, 3, 4, 5, 5, 6, 7, 8, 9, 9, 10, 10, + 11, 11, 12, 12, 12, 13, 13, 13, 13, 13, 13, 13, 13 +}; + +const struct rtw_pwr_track_tbl rtw8814a_rtw_pwrtrk_type2_tbl = { + .pwrtrk_5gd_n[RTW_PWR_TRK_5G_1] = rtw8814a_pwrtrk_type2_5gd_n[RTW_PWR_TRK_5G_1], + .pwrtrk_5gd_n[RTW_PWR_TRK_5G_2] = rtw8814a_pwrtrk_type2_5gd_n[RTW_PWR_TRK_5G_2], + .pwrtrk_5gd_n[RTW_PWR_TRK_5G_3] = rtw8814a_pwrtrk_type2_5gd_n[RTW_PWR_TRK_5G_3], + .pwrtrk_5gd_p[RTW_PWR_TRK_5G_1] = rtw8814a_pwrtrk_type2_5gd_p[RTW_PWR_TRK_5G_1], + .pwrtrk_5gd_p[RTW_PWR_TRK_5G_2] = rtw8814a_pwrtrk_type2_5gd_p[RTW_PWR_TRK_5G_2], + .pwrtrk_5gd_p[RTW_PWR_TRK_5G_3] = rtw8814a_pwrtrk_type2_5gd_p[RTW_PWR_TRK_5G_3], + .pwrtrk_5gc_n[RTW_PWR_TRK_5G_1] = rtw8814a_pwrtrk_type2_5gc_n[RTW_PWR_TRK_5G_1], + .pwrtrk_5gc_n[RTW_PWR_TRK_5G_2] = rtw8814a_pwrtrk_type2_5gc_n[RTW_PWR_TRK_5G_2], + .pwrtrk_5gc_n[RTW_PWR_TRK_5G_3] = rtw8814a_pwrtrk_type2_5gc_n[RTW_PWR_TRK_5G_3], + .pwrtrk_5gc_p[RTW_PWR_TRK_5G_1] = rtw8814a_pwrtrk_type2_5gc_p[RTW_PWR_TRK_5G_1], + .pwrtrk_5gc_p[RTW_PWR_TRK_5G_2] = rtw8814a_pwrtrk_type2_5gc_p[RTW_PWR_TRK_5G_2], + .pwrtrk_5gc_p[RTW_PWR_TRK_5G_3] = rtw8814a_pwrtrk_type2_5gc_p[RTW_PWR_TRK_5G_3], + .pwrtrk_5gb_n[RTW_PWR_TRK_5G_1] = rtw8814a_pwrtrk_type2_5gb_n[RTW_PWR_TRK_5G_1], + .pwrtrk_5gb_n[RTW_PWR_TRK_5G_2] = rtw8814a_pwrtrk_type2_5gb_n[RTW_PWR_TRK_5G_2], + .pwrtrk_5gb_n[RTW_PWR_TRK_5G_3] = rtw8814a_pwrtrk_type2_5gb_n[RTW_PWR_TRK_5G_3], + .pwrtrk_5gb_p[RTW_PWR_TRK_5G_1] = rtw8814a_pwrtrk_type2_5gb_p[RTW_PWR_TRK_5G_1], + .pwrtrk_5gb_p[RTW_PWR_TRK_5G_2] = rtw8814a_pwrtrk_type2_5gb_p[RTW_PWR_TRK_5G_2], + .pwrtrk_5gb_p[RTW_PWR_TRK_5G_3] = rtw8814a_pwrtrk_type2_5gb_p[RTW_PWR_TRK_5G_3], + .pwrtrk_5ga_n[RTW_PWR_TRK_5G_1] = rtw8814a_pwrtrk_type2_5ga_n[RTW_PWR_TRK_5G_1], + .pwrtrk_5ga_n[RTW_PWR_TRK_5G_2] = rtw8814a_pwrtrk_type2_5ga_n[RTW_PWR_TRK_5G_2], + .pwrtrk_5ga_n[RTW_PWR_TRK_5G_3] = rtw8814a_pwrtrk_type2_5ga_n[RTW_PWR_TRK_5G_3], + .pwrtrk_5ga_p[RTW_PWR_TRK_5G_1] = rtw8814a_pwrtrk_type2_5ga_p[RTW_PWR_TRK_5G_1], + .pwrtrk_5ga_p[RTW_PWR_TRK_5G_2] = rtw8814a_pwrtrk_type2_5ga_p[RTW_PWR_TRK_5G_2], + .pwrtrk_5ga_p[RTW_PWR_TRK_5G_3] = rtw8814a_pwrtrk_type2_5ga_p[RTW_PWR_TRK_5G_3], + .pwrtrk_2gd_n = rtw8814a_pwrtrk_type2_2gd_n, + .pwrtrk_2gd_p = rtw8814a_pwrtrk_type2_2gd_p, + .pwrtrk_2gc_n = rtw8814a_pwrtrk_type2_2gc_n, + .pwrtrk_2gc_p = rtw8814a_pwrtrk_type2_2gc_p, + .pwrtrk_2gb_n = rtw8814a_pwrtrk_type2_2gb_n, + .pwrtrk_2gb_p = rtw8814a_pwrtrk_type2_2gb_p, + .pwrtrk_2ga_n = rtw8814a_pwrtrk_type2_2ga_n, + .pwrtrk_2ga_p = rtw8814a_pwrtrk_type2_2ga_p, + .pwrtrk_2g_cckd_n = rtw8814a_pwrtrk_type2_2g_cck_d_n, + .pwrtrk_2g_cckd_p = rtw8814a_pwrtrk_type2_2g_cck_d_p, + .pwrtrk_2g_cckc_n = rtw8814a_pwrtrk_type2_2g_cck_c_n, + .pwrtrk_2g_cckc_p = rtw8814a_pwrtrk_type2_2g_cck_c_p, + .pwrtrk_2g_cckb_n = rtw8814a_pwrtrk_type2_2g_cck_b_n, + .pwrtrk_2g_cckb_p = rtw8814a_pwrtrk_type2_2g_cck_b_p, + .pwrtrk_2g_ccka_n = rtw8814a_pwrtrk_type2_2g_cck_a_n, + .pwrtrk_2g_ccka_p = rtw8814a_pwrtrk_type2_2g_cck_a_p, +}; + +static const u8 +rtw8814a_pwrtrk_type5_5gd_n[RTW_PWR_TRK_5G_NUM][RTW_PWR_TRK_TBL_SZ] = { + {0, 3, 3, 3, 4, 6, 6, 7, 7, 8, 9, 10, 11, 12, 13, 13, 14, + 14, 14, 14, 14, 15, 15, 15, 15, 15, 15, 15, 15, 15}, + {0, 4, 5, 6, 7, 7, 8, 7, 8, 10, 11, 12, 12, 13, 13, 14, 14, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15}, + {0, 5, 5, 6, 7, 8, 9, 9, 10, 11, 12, 13, 13, 14, 15, 15, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16}, +}; + +static const u8 +rtw8814a_pwrtrk_type5_5gd_p[RTW_PWR_TRK_5G_NUM][RTW_PWR_TRK_TBL_SZ] = { + {0, 0, 0, 1, 2, 2, 3, 4, 5, 5, 6, 7, 9, 10, 10, 11, 12, + 12, 12, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13}, + {0, 0, 0, 1, 1, 1, 2, 3, 4, 5, 6, 7, 8, 8, 9, 11, 12, + 12, 13, 13, 13, 13, 13, 14, 14, 14, 14, 14, 14, 14}, + {0, 0, 0, 1, 1, 2, 2, 3, 5, 7, 8, 9, 10, 11, 12, 13, 13, + 13, 13, 13, 13, 14, 14, 14, 14, 14, 14, 14, 14, 14}, +}; + +static const u8 +rtw8814a_pwrtrk_type5_5gc_n[RTW_PWR_TRK_5G_NUM][RTW_PWR_TRK_TBL_SZ] = { + {0, 1, 1, 2, 3, 3, 4, 6, 7, 7, 8, 9, 9, 9, 10, 10, 10, + 10, 11, 11, 11, 11, 11, 12, 12, 12, 12, 12, 12, 12}, + {0, 1, 2, 3, 3, 7, 7, 8, 8, 9, 11, 12, 12, 13, 14, 14, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15}, + {0, 0, 1, 2, 3, 4, 5, 7, 8, 8, 10, 11, 12, 12, 13, 13, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14}, +}; + +static const u8 +rtw8814a_pwrtrk_type5_5gc_p[RTW_PWR_TRK_5G_NUM][RTW_PWR_TRK_TBL_SZ] = { + {0, 0, 0, 1, 1, 2, 2, 3, 4, 5, 6, 6, 7, 8, 9, 11, 11, + 11, 11, 11, 11, 12, 12, 12, 12, 12, 13, 13, 13, 13}, + {0, 0, 1, 2, 3, 3, 5, 5, 6, 8, 8, 9, 10, 11, 13, 13, 13, + 13, 13, 13, 13, 14, 14, 14, 14, 14, 14, 14, 14, 14}, + {0, 0, 1, 2, 3, 4, 4, 5, 7, 8, 9, 9, 10, 11, 12, 12, 12, + 12, 13, 13, 13, 13, 13, 13, 14, 14, 14, 14, 14, 14}, +}; + +static const u8 +rtw8814a_pwrtrk_type5_5gb_n[RTW_PWR_TRK_5G_NUM][RTW_PWR_TRK_TBL_SZ] = { + {0, 1, 1, 2, 2, 2, 3, 4, 5, 6, 7, 9, 10, 10, 10, 10, 10, + 10, 11, 11, 11, 11, 11, 12, 12, 12, 12, 12, 12, 12}, + {0, 1, 2, 3, 3, 7, 7, 8, 8, 9, 11, 12, 12, 13, 14, 14, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15}, + {0, 0, 1, 2, 3, 4, 5, 7, 8, 8, 10, 11, 12, 12, 13, 13, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14}, +}; + +static const u8 +rtw8814a_pwrtrk_type5_5gb_p[RTW_PWR_TRK_5G_NUM][RTW_PWR_TRK_TBL_SZ] = { + {0, 1, 1, 1, 2, 2, 4, 5, 6, 6, 7, 8, 9, 10, 11, 11, 11, + 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12}, + {0, 0, 0, 2, 3, 4, 5, 6, 8, 8, 9, 9, 11, 12, 13, 13, 13, + 13, 13, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14}, + {0, 0, 0, 1, 2, 3, 3, 4, 6, 7, 8, 9, 10, 11, 12, 12, 12, + 12, 13, 13, 13, 13, 13, 13, 14, 14, 14, 14, 14, 14}, +}; + +static const u8 +rtw8814a_pwrtrk_type5_5ga_n[RTW_PWR_TRK_5G_NUM][RTW_PWR_TRK_TBL_SZ] = { + {0, 0, 0, 1, 2, 3, 3, 3, 4, 5, 6, 6, 7, 8, 8, 9, 10, 10, + 10, 11, 11, 11, 11, 11, 11, 12, 12, 12, 12, 12}, + {0, 2, 3, 4, 5, 7, 7, 8, 9, 10, 12, 13, 14, 15, 16, 17, 17, + 17, 17, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18}, + {0, 1, 2, 3, 3, 4, 6, 7, 8, 8, 10, 11, 11, 12, 13, 13, 13, + 13, 13, 13, 13, 14, 14, 14, 14, 14, 14, 14, 14, 14}, +}; + +static const u8 +rtw8814a_pwrtrk_type5_5ga_p[RTW_PWR_TRK_5G_NUM][RTW_PWR_TRK_TBL_SZ] = { + {0, 1, 1, 3, 3, 3, 5, 5, 6, 6, 8, 8, 9, 10, 11, 11, 11, + 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12}, + {0, 1, 2, 3, 4, 4, 5, 6, 7, 8, 8, 9, 11, 12, 13, 14, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15}, + {0, 0, 1, 3, 3, 4, 5, 5, 6, 7, 7, 8, 10, 10, 11, 11, 11, + 11, 12, 12, 12, 12, 12, 13, 13, 13, 13, 13, 13, 13}, +}; + +static const u8 rtw8814a_pwrtrk_type5_2gd_n[RTW_PWR_TRK_TBL_SZ] = { + 0, 1, 2, 2, 3, 4, 4, 5, 6, 6, 7, 7, 7, 8, 9, 9, 9, + 9, 9, 10, 10, 10, 10, 10, 10, 11, 11, 11, 11, 11 +}; + +static const u8 rtw8814a_pwrtrk_type5_2gd_p[RTW_PWR_TRK_TBL_SZ] = { + 0, 1, 1, 2, 2, 2, 3, 4, 4, 5, 6, 6, 7, 7, 8, 8, + 8, 8, 8, 9, 9, 9, 9, 9, 9, 10, 10, 10, 10, 10 +}; + +static const u8 rtw8814a_pwrtrk_type5_2gc_n[RTW_PWR_TRK_TBL_SZ] = { + 0, 1, 2, 2, 3, 4, 4, 5, 6, 6, 7, 8, 8, 9, 10, 10, 10, + 10, 10, 10, 11, 11, 11, 11, 11, 12, 12, 12, 12, 12 +}; + +static const u8 rtw8814a_pwrtrk_type5_2gc_p[RTW_PWR_TRK_TBL_SZ] = { + 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 8, 8, 9, 9, 9, + 9, 9, 10, 10, 10, 10, 10, 11, 11, 11, 11, 11, 11 +}; + +static const u8 rtw8814a_pwrtrk_type5_2gb_n[RTW_PWR_TRK_TBL_SZ] = { + 0, 1, 2, 2, 3, 4, 4, 5, 6, 6, 7, 7, 8, 9, 10, 10, 10, + 10, 10, 11, 11, 11, 11, 11, 12, 12, 12, 12, 12, 12 +}; + +static const u8 rtw8814a_pwrtrk_type5_2gb_p[RTW_PWR_TRK_TBL_SZ] = { + 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 8, 9, 9, 9, 9, + 9, 9, 10, 10, 10, 10, 10, 11, 11, 11, 11, 11, 11 +}; + +static const u8 rtw8814a_pwrtrk_type5_2ga_n[RTW_PWR_TRK_TBL_SZ] = { + 0, 1, 2, 2, 3, 4, 5, 5, 6, 7, 7, 8, 8, 9, 10, 10, 10, + 10, 11, 11, 11, 11, 111, 12, 12, 12, 12, 12, 12, 12 +}; + +static const u8 rtw8814a_pwrtrk_type5_2ga_p[RTW_PWR_TRK_TBL_SZ] = { + 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 6, 7, 8, 8, 9, 9, 9, + 9, 9, 10, 10, 10, 10, 10, 10, 10, 10, 11, 11, 11 +}; + +static const u8 rtw8814a_pwrtrk_type5_2g_cck_d_n[RTW_PWR_TRK_TBL_SZ] = { + 0, 1, 2, 2, 3, 4, 5, 5, 6, 7, 7, 8, 8, 8, 9, 9, 9, 9, + 10, 10, 10, 10, 10, 11, 11, 10, 11, 11, 11, 11 +}; + +static const u8 rtw8814a_pwrtrk_type5_2g_cck_d_p[RTW_PWR_TRK_TBL_SZ] = { + 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 7, 7, 8, 8, 8, + 9, 9, 9, 9, 9, 10, 10, 10, 10, 10, 10, 10, 10 +}; + +static const u8 rtw8814a_pwrtrk_type5_2g_cck_c_n[RTW_PWR_TRK_TBL_SZ] = { + 0, 2, 3, 4, 4, 5, 6, 6, 7, 8, 8, 8, 8, 9, 10, 10, 10, + 10, 11, 11, 11, 11, 11, 11, 12, 12, 12, 12, 12, 12 +}; + +static const u8 rtw8814a_pwrtrk_type5_2g_cck_c_p[RTW_PWR_TRK_TBL_SZ] = { + 0, 0, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 7, 7, 8, 8, 8, + 9, 9, 9, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10 +}; + +static const u8 rtw8814a_pwrtrk_type5_2g_cck_b_n[RTW_PWR_TRK_TBL_SZ] = { + 0, 2, 3, 4, 4, 5, 6, 6, 6, 7, 7, 8, 8, 9, 10, 10, 10, + 10, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11 +}; + +static const u8 rtw8814a_pwrtrk_type5_2g_cck_b_p[RTW_PWR_TRK_TBL_SZ] = { + 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 7, 7, 8, 8, 8, + 9, 9, 9, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10 +}; + +static const u8 rtw8814a_pwrtrk_type5_2g_cck_a_n[RTW_PWR_TRK_TBL_SZ] = { + 0, 1, 2, 2, 3, 4, 5, 5, 6, 7, 7, 8, 8, 9, 9, 9, 9, 10, + 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10 +}; + +static const u8 rtw8814a_pwrtrk_type5_2g_cck_a_p[RTW_PWR_TRK_TBL_SZ] = { + 0, 1, 1, 2, 2, 2, 3, 4, 4, 5, 6, 7, 8, 8, 9, 9, 9, + 9, 9, 9, 9, 10, 10, 10, 10, 10, 10, 10, 10, 10 +}; + +const struct rtw_pwr_track_tbl rtw8814a_rtw_pwrtrk_type5_tbl = { + .pwrtrk_5gd_n[RTW_PWR_TRK_5G_1] = rtw8814a_pwrtrk_type5_5gd_n[RTW_PWR_TRK_5G_1], + .pwrtrk_5gd_n[RTW_PWR_TRK_5G_2] = rtw8814a_pwrtrk_type5_5gd_n[RTW_PWR_TRK_5G_2], + .pwrtrk_5gd_n[RTW_PWR_TRK_5G_3] = rtw8814a_pwrtrk_type5_5gd_n[RTW_PWR_TRK_5G_3], + .pwrtrk_5gd_p[RTW_PWR_TRK_5G_1] = rtw8814a_pwrtrk_type5_5gd_p[RTW_PWR_TRK_5G_1], + .pwrtrk_5gd_p[RTW_PWR_TRK_5G_2] = rtw8814a_pwrtrk_type5_5gd_p[RTW_PWR_TRK_5G_2], + .pwrtrk_5gd_p[RTW_PWR_TRK_5G_3] = rtw8814a_pwrtrk_type5_5gd_p[RTW_PWR_TRK_5G_3], + .pwrtrk_5gc_n[RTW_PWR_TRK_5G_1] = rtw8814a_pwrtrk_type5_5gc_n[RTW_PWR_TRK_5G_1], + .pwrtrk_5gc_n[RTW_PWR_TRK_5G_2] = rtw8814a_pwrtrk_type5_5gc_n[RTW_PWR_TRK_5G_2], + .pwrtrk_5gc_n[RTW_PWR_TRK_5G_3] = rtw8814a_pwrtrk_type5_5gc_n[RTW_PWR_TRK_5G_3], + .pwrtrk_5gc_p[RTW_PWR_TRK_5G_1] = rtw8814a_pwrtrk_type5_5gc_p[RTW_PWR_TRK_5G_1], + .pwrtrk_5gc_p[RTW_PWR_TRK_5G_2] = rtw8814a_pwrtrk_type5_5gc_p[RTW_PWR_TRK_5G_2], + .pwrtrk_5gc_p[RTW_PWR_TRK_5G_3] = rtw8814a_pwrtrk_type5_5gc_p[RTW_PWR_TRK_5G_3], + .pwrtrk_5gb_n[RTW_PWR_TRK_5G_1] = rtw8814a_pwrtrk_type5_5gb_n[RTW_PWR_TRK_5G_1], + .pwrtrk_5gb_n[RTW_PWR_TRK_5G_2] = rtw8814a_pwrtrk_type5_5gb_n[RTW_PWR_TRK_5G_2], + .pwrtrk_5gb_n[RTW_PWR_TRK_5G_3] = rtw8814a_pwrtrk_type5_5gb_n[RTW_PWR_TRK_5G_3], + .pwrtrk_5gb_p[RTW_PWR_TRK_5G_1] = rtw8814a_pwrtrk_type5_5gb_p[RTW_PWR_TRK_5G_1], + .pwrtrk_5gb_p[RTW_PWR_TRK_5G_2] = rtw8814a_pwrtrk_type5_5gb_p[RTW_PWR_TRK_5G_2], + .pwrtrk_5gb_p[RTW_PWR_TRK_5G_3] = rtw8814a_pwrtrk_type5_5gb_p[RTW_PWR_TRK_5G_3], + .pwrtrk_5ga_n[RTW_PWR_TRK_5G_1] = rtw8814a_pwrtrk_type5_5ga_n[RTW_PWR_TRK_5G_1], + .pwrtrk_5ga_n[RTW_PWR_TRK_5G_2] = rtw8814a_pwrtrk_type5_5ga_n[RTW_PWR_TRK_5G_2], + .pwrtrk_5ga_n[RTW_PWR_TRK_5G_3] = rtw8814a_pwrtrk_type5_5ga_n[RTW_PWR_TRK_5G_3], + .pwrtrk_5ga_p[RTW_PWR_TRK_5G_1] = rtw8814a_pwrtrk_type5_5ga_p[RTW_PWR_TRK_5G_1], + .pwrtrk_5ga_p[RTW_PWR_TRK_5G_2] = rtw8814a_pwrtrk_type5_5ga_p[RTW_PWR_TRK_5G_2], + .pwrtrk_5ga_p[RTW_PWR_TRK_5G_3] = rtw8814a_pwrtrk_type5_5ga_p[RTW_PWR_TRK_5G_3], + .pwrtrk_2gd_n = rtw8814a_pwrtrk_type5_2gd_n, + .pwrtrk_2gd_p = rtw8814a_pwrtrk_type5_2gd_p, + .pwrtrk_2gc_n = rtw8814a_pwrtrk_type5_2gc_n, + .pwrtrk_2gc_p = rtw8814a_pwrtrk_type5_2gc_p, + .pwrtrk_2gb_n = rtw8814a_pwrtrk_type5_2gb_n, + .pwrtrk_2gb_p = rtw8814a_pwrtrk_type5_2gb_p, + .pwrtrk_2ga_n = rtw8814a_pwrtrk_type5_2ga_n, + .pwrtrk_2ga_p = rtw8814a_pwrtrk_type5_2ga_p, + .pwrtrk_2g_cckd_n = rtw8814a_pwrtrk_type5_2g_cck_d_n, + .pwrtrk_2g_cckd_p = rtw8814a_pwrtrk_type5_2g_cck_d_p, + .pwrtrk_2g_cckc_n = rtw8814a_pwrtrk_type5_2g_cck_c_n, + .pwrtrk_2g_cckc_p = rtw8814a_pwrtrk_type5_2g_cck_c_p, + .pwrtrk_2g_cckb_n = rtw8814a_pwrtrk_type5_2g_cck_b_n, + .pwrtrk_2g_cckb_p = rtw8814a_pwrtrk_type5_2g_cck_b_p, + .pwrtrk_2g_ccka_n = rtw8814a_pwrtrk_type5_2g_cck_a_n, + .pwrtrk_2g_ccka_p = rtw8814a_pwrtrk_type5_2g_cck_a_p, +}; + +static const u8 +rtw8814a_pwrtrk_type7_5gd_n[RTW_PWR_TRK_5G_NUM][RTW_PWR_TRK_TBL_SZ] = { + {0, 0, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, + 8, 9, 9, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10}, + {0, 0, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, + 8, 9, 9, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10}, + {0, 0, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, + 8, 9, 9, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10}, +}; + +static const u8 +rtw8814a_pwrtrk_type7_5gd_p[RTW_PWR_TRK_5G_NUM][RTW_PWR_TRK_TBL_SZ] = { + {0, 0, 1, 1, 2, 3, 3, 4, 5, 5, 6, 6, 7, 8, 8, 9, 10, 10, + 11, 11, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12}, + {0, 0, 1, 1, 2, 3, 3, 4, 5, 5, 6, 6, 7, 8, 8, 9, 10, 10, + 11, 11, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12}, + {0, 0, 1, 1, 2, 3, 3, 4, 5, 5, 6, 6, 7, 8, 8, 9, 10, 10, + 11, 11, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12}, +}; + +static const u8 +rtw8814a_pwrtrk_type7_5gc_n[RTW_PWR_TRK_5G_NUM][RTW_PWR_TRK_TBL_SZ] = { + {0, 0, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, + 8, 9, 9, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10}, + {0, 0, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, + 8, 9, 9, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10}, + {0, 0, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, + 8, 9, 9, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10}, +}; + +static const u8 +rtw8814a_pwrtrk_type7_5gc_p[RTW_PWR_TRK_5G_NUM][RTW_PWR_TRK_TBL_SZ] = { + {0, 0, 1, 1, 2, 3, 3, 4, 5, 5, 6, 6, 7, 8, 8, 9, 10, 10, + 11, 11, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12}, + {0, 0, 1, 1, 2, 3, 3, 4, 5, 5, 6, 6, 7, 8, 8, 9, 10, 10, + 11, 11, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12}, + {0, 0, 1, 1, 2, 3, 3, 4, 5, 5, 6, 6, 7, 8, 8, 9, 10, 10, + 11, 11, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12}, +}; + +static const u8 +rtw8814a_pwrtrk_type7_5gb_n[RTW_PWR_TRK_5G_NUM][RTW_PWR_TRK_TBL_SZ] = { + {0, 0, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, + 8, 9, 9, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10}, + {0, 0, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, + 8, 9, 9, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10}, + {0, 0, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, + 8, 9, 9, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10}, +}; + +static const u8 +rtw8814a_pwrtrk_type7_5gb_p[RTW_PWR_TRK_5G_NUM][RTW_PWR_TRK_TBL_SZ] = { + {0, 0, 1, 1, 2, 3, 3, 4, 5, 5, 6, 6, 7, 8, 8, 9, 10, 10, + 11, 11, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12}, + {0, 0, 1, 1, 2, 3, 3, 4, 5, 5, 6, 6, 7, 8, 8, 9, 10, 10, + 11, 11, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12}, + {0, 0, 1, 1, 2, 3, 3, 4, 5, 5, 6, 6, 7, 8, 8, 9, 10, 10, + 11, 11, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12}, +}; + +static const u8 +rtw8814a_pwrtrk_type7_5ga_n[RTW_PWR_TRK_5G_NUM][RTW_PWR_TRK_TBL_SZ] = { + {0, 0, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, + 8, 9, 9, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10}, + {0, 0, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, + 8, 9, 9, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10}, + {0, 0, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, + 8, 9, 9, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10}, +}; + +static const u8 +rtw8814a_pwrtrk_type7_5ga_p[RTW_PWR_TRK_5G_NUM][RTW_PWR_TRK_TBL_SZ] = { + {0, 0, 1, 1, 2, 3, 3, 4, 5, 5, 6, 6, 7, 8, 8, 9, 10, 10, + 11, 11, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12}, + {0, 0, 1, 1, 2, 3, 3, 4, 5, 5, 6, 6, 7, 8, 8, 9, 10, 10, + 11, 11, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12}, + {0, 0, 1, 1, 2, 3, 3, 4, 5, 5, 6, 6, 7, 8, 8, 9, 10, 10, + 11, 11, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12}, +}; + +static const u8 rtw8814a_pwrtrk_type7_2gd_n[RTW_PWR_TRK_TBL_SZ] = { + 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 5, 6, 7, 7, + 7, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9 +}; + +static const u8 rtw8814a_pwrtrk_type7_2gd_p[RTW_PWR_TRK_TBL_SZ] = { + 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, + 8, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9 +}; + +static const u8 rtw8814a_pwrtrk_type7_2gc_n[RTW_PWR_TRK_TBL_SZ] = { + 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 5, 6, 7, 7, + 7, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9 +}; + +static const u8 rtw8814a_pwrtrk_type7_2gc_p[RTW_PWR_TRK_TBL_SZ] = { + 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, + 8, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9 +}; + +static const u8 rtw8814a_pwrtrk_type7_2gb_n[RTW_PWR_TRK_TBL_SZ] = { + 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 5, 6, 7, 7, + 7, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9 +}; + +static const u8 rtw8814a_pwrtrk_type7_2gb_p[RTW_PWR_TRK_TBL_SZ] = { + 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, + 8, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9 +}; + +static const u8 rtw8814a_pwrtrk_type7_2ga_n[RTW_PWR_TRK_TBL_SZ] = { + 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 5, 6, 7, 7, + 7, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9 +}; + +static const u8 rtw8814a_pwrtrk_type7_2ga_p[RTW_PWR_TRK_TBL_SZ] = { + 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, + 8, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9 +}; + +static const u8 rtw8814a_pwrtrk_type7_2g_cck_d_n[RTW_PWR_TRK_TBL_SZ] = { + 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 5, 6, 7, 7, + 7, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9 +}; + +static const u8 rtw8814a_pwrtrk_type7_2g_cck_d_p[RTW_PWR_TRK_TBL_SZ] = { + 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, + 8, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9 +}; + +static const u8 rtw8814a_pwrtrk_type7_2g_cck_c_n[RTW_PWR_TRK_TBL_SZ] = { + 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 5, 6, 7, 7, + 7, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9 +}; + +static const u8 rtw8814a_pwrtrk_type7_2g_cck_c_p[RTW_PWR_TRK_TBL_SZ] = { + 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, + 8, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9 +}; + +static const u8 rtw8814a_pwrtrk_type7_2g_cck_b_n[RTW_PWR_TRK_TBL_SZ] = { + 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 5, 6, 7, 7, + 7, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9 +}; + +static const u8 rtw8814a_pwrtrk_type7_2g_cck_b_p[RTW_PWR_TRK_TBL_SZ] = { + 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, + 8, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9 +}; + +static const u8 rtw8814a_pwrtrk_type7_2g_cck_a_n[RTW_PWR_TRK_TBL_SZ] = { + 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 5, 6, 7, 7, + 7, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9 +}; + +static const u8 rtw8814a_pwrtrk_type7_2g_cck_a_p[RTW_PWR_TRK_TBL_SZ] = { + 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, + 8, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9 +}; + +const struct rtw_pwr_track_tbl rtw8814a_rtw_pwrtrk_type7_tbl = { + .pwrtrk_5gd_n[RTW_PWR_TRK_5G_1] = rtw8814a_pwrtrk_type7_5gd_n[RTW_PWR_TRK_5G_1], + .pwrtrk_5gd_n[RTW_PWR_TRK_5G_2] = rtw8814a_pwrtrk_type7_5gd_n[RTW_PWR_TRK_5G_2], + .pwrtrk_5gd_n[RTW_PWR_TRK_5G_3] = rtw8814a_pwrtrk_type7_5gd_n[RTW_PWR_TRK_5G_3], + .pwrtrk_5gd_p[RTW_PWR_TRK_5G_1] = rtw8814a_pwrtrk_type7_5gd_p[RTW_PWR_TRK_5G_1], + .pwrtrk_5gd_p[RTW_PWR_TRK_5G_2] = rtw8814a_pwrtrk_type7_5gd_p[RTW_PWR_TRK_5G_2], + .pwrtrk_5gd_p[RTW_PWR_TRK_5G_3] = rtw8814a_pwrtrk_type7_5gd_p[RTW_PWR_TRK_5G_3], + .pwrtrk_5gc_n[RTW_PWR_TRK_5G_1] = rtw8814a_pwrtrk_type7_5gc_n[RTW_PWR_TRK_5G_1], + .pwrtrk_5gc_n[RTW_PWR_TRK_5G_2] = rtw8814a_pwrtrk_type7_5gc_n[RTW_PWR_TRK_5G_2], + .pwrtrk_5gc_n[RTW_PWR_TRK_5G_3] = rtw8814a_pwrtrk_type7_5gc_n[RTW_PWR_TRK_5G_3], + .pwrtrk_5gc_p[RTW_PWR_TRK_5G_1] = rtw8814a_pwrtrk_type7_5gc_p[RTW_PWR_TRK_5G_1], + .pwrtrk_5gc_p[RTW_PWR_TRK_5G_2] = rtw8814a_pwrtrk_type7_5gc_p[RTW_PWR_TRK_5G_2], + .pwrtrk_5gc_p[RTW_PWR_TRK_5G_3] = rtw8814a_pwrtrk_type7_5gc_p[RTW_PWR_TRK_5G_3], + .pwrtrk_5gb_n[RTW_PWR_TRK_5G_1] = rtw8814a_pwrtrk_type7_5gb_n[RTW_PWR_TRK_5G_1], + .pwrtrk_5gb_n[RTW_PWR_TRK_5G_2] = rtw8814a_pwrtrk_type7_5gb_n[RTW_PWR_TRK_5G_2], + .pwrtrk_5gb_n[RTW_PWR_TRK_5G_3] = rtw8814a_pwrtrk_type7_5gb_n[RTW_PWR_TRK_5G_3], + .pwrtrk_5gb_p[RTW_PWR_TRK_5G_1] = rtw8814a_pwrtrk_type7_5gb_p[RTW_PWR_TRK_5G_1], + .pwrtrk_5gb_p[RTW_PWR_TRK_5G_2] = rtw8814a_pwrtrk_type7_5gb_p[RTW_PWR_TRK_5G_2], + .pwrtrk_5gb_p[RTW_PWR_TRK_5G_3] = rtw8814a_pwrtrk_type7_5gb_p[RTW_PWR_TRK_5G_3], + .pwrtrk_5ga_n[RTW_PWR_TRK_5G_1] = rtw8814a_pwrtrk_type7_5ga_n[RTW_PWR_TRK_5G_1], + .pwrtrk_5ga_n[RTW_PWR_TRK_5G_2] = rtw8814a_pwrtrk_type7_5ga_n[RTW_PWR_TRK_5G_2], + .pwrtrk_5ga_n[RTW_PWR_TRK_5G_3] = rtw8814a_pwrtrk_type7_5ga_n[RTW_PWR_TRK_5G_3], + .pwrtrk_5ga_p[RTW_PWR_TRK_5G_1] = rtw8814a_pwrtrk_type7_5ga_p[RTW_PWR_TRK_5G_1], + .pwrtrk_5ga_p[RTW_PWR_TRK_5G_2] = rtw8814a_pwrtrk_type7_5ga_p[RTW_PWR_TRK_5G_2], + .pwrtrk_5ga_p[RTW_PWR_TRK_5G_3] = rtw8814a_pwrtrk_type7_5ga_p[RTW_PWR_TRK_5G_3], + .pwrtrk_2gd_n = rtw8814a_pwrtrk_type7_2gd_n, + .pwrtrk_2gd_p = rtw8814a_pwrtrk_type7_2gd_p, + .pwrtrk_2gc_n = rtw8814a_pwrtrk_type7_2gc_n, + .pwrtrk_2gc_p = rtw8814a_pwrtrk_type7_2gc_p, + .pwrtrk_2gb_n = rtw8814a_pwrtrk_type7_2gb_n, + .pwrtrk_2gb_p = rtw8814a_pwrtrk_type7_2gb_p, + .pwrtrk_2ga_n = rtw8814a_pwrtrk_type7_2ga_n, + .pwrtrk_2ga_p = rtw8814a_pwrtrk_type7_2ga_p, + .pwrtrk_2g_cckd_n = rtw8814a_pwrtrk_type7_2g_cck_d_n, + .pwrtrk_2g_cckd_p = rtw8814a_pwrtrk_type7_2g_cck_d_p, + .pwrtrk_2g_cckc_n = rtw8814a_pwrtrk_type7_2g_cck_c_n, + .pwrtrk_2g_cckc_p = rtw8814a_pwrtrk_type7_2g_cck_c_p, + .pwrtrk_2g_cckb_n = rtw8814a_pwrtrk_type7_2g_cck_b_n, + .pwrtrk_2g_cckb_p = rtw8814a_pwrtrk_type7_2g_cck_b_p, + .pwrtrk_2g_ccka_n = rtw8814a_pwrtrk_type7_2g_cck_a_n, + .pwrtrk_2g_ccka_p = rtw8814a_pwrtrk_type7_2g_cck_a_p, +}; + +static const u8 +rtw8814a_pwrtrk_type8_5gd_n[RTW_PWR_TRK_5G_NUM][RTW_PWR_TRK_TBL_SZ] = { + {0, 1, 2, 3, 4, 4, 6, 7, 7, 8, 8, 9, 10, 10, 11, 11, 12, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13}, + {0, 1, 2, 3, 4, 4, 6, 7, 7, 8, 9, 9, 10, 10, 11, 11, 12, + 12, 12, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13}, + {0, 1, 2, 3, 4, 4, 5, 6, 6, 7, 7, 8, 8, 8, 9, 10, 10, + 10, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11}, +}; + +static const u8 +rtw8814a_pwrtrk_type8_5gd_p[RTW_PWR_TRK_5G_NUM][RTW_PWR_TRK_TBL_SZ] = { + {0, 0, 1, 2, 4, 4, 5, 6, 7, 8, 9, 10, 11, 12, 14, 14, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15}, + {0, 0, 1, 2, 3, 5, 5, 6, 6, 7, 8, 9, 10, 11, 12, 13, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14}, + {0, 0, 1, 2, 3, 4, 5, 6, 6, 7, 8, 9, 10, 11, 12, 13, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14}, +}; + +static const u8 +rtw8814a_pwrtrk_type8_5gc_n[RTW_PWR_TRK_5G_NUM][RTW_PWR_TRK_TBL_SZ] = { + {0, 1, 2, 4, 4, 5, 6, 7, 7, 8, 8, 9, 9, 10, 11, 11, 12, + 12, 12, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13}, + {0, 1, 2, 3, 4, 5, 6, 7, 7, 8, 9, 9, 10, 10, 10, 11, 11, + 12, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13}, + {0, 1, 2, 3, 4, 4, 5, 6, 7, 7, 8, 8, 9, 10, 10, 11, 11, + 11, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12}, +}; + +static const u8 +rtw8814a_pwrtrk_type8_5gc_p[RTW_PWR_TRK_5G_NUM][RTW_PWR_TRK_TBL_SZ] = { + {0, 0, 1, 2, 4, 4, 5, 6, 7, 7, 8, 9, 10, 11, 12, 13, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14}, + {0, 0, 1, 3, 4, 4, 5, 6, 7, 7, 8, 10, 11, 12, 13, 14, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15}, + {0, 0, 1, 2, 4, 5, 5, 6, 6, 7, 7, 9, 10, 11, 12, 13, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14}, +}; + +static const u8 +rtw8814a_pwrtrk_type8_5gb_n[RTW_PWR_TRK_5G_NUM][RTW_PWR_TRK_TBL_SZ] = { + {0, 1, 2, 3, 4, 4, 5, 6, 7, 7, 8, 8, 9, 9, 10, 11, 11, + 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12}, + {0, 1, 2, 3, 4, 5, 6, 7, 7, 8, 9, 9, 10, 10, 10, 11, 11, + 12, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13}, + {0, 1, 2, 3, 4, 4, 5, 6, 7, 7, 8, 8, 9, 10, 10, 11, 11, + 11, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12}, +}; + +static const u8 +rtw8814a_pwrtrk_type8_5gb_p[RTW_PWR_TRK_5G_NUM][RTW_PWR_TRK_TBL_SZ] = { + {0, 0, 1, 2, 3, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14}, + {0, 0, 1, 2, 3, 4, 5, 5, 6, 7, 8, 10, 11, 11, 13, 13, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14}, + {0, 0, 1, 2, 3, 4, 4, 5, 6, 7, 8, 10, 10, 11, 13, 13, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14}, +}; + +static const u8 +rtw8814a_pwrtrk_type8_5ga_n[RTW_PWR_TRK_5G_NUM][RTW_PWR_TRK_TBL_SZ] = { + {0, 1, 2, 3, 4, 4, 5, 6, 6, 7, 8, 8, 9, 9, 10, 11, 11, + 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12}, + {0, 1, 2, 3, 4, 5, 5, 6, 7, 8, 9, 9, 10, 10, 10, 11, 11, + 12, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13}, + {0, 1, 2, 3, 4, 4, 5, 6, 7, 7, 8, 9, 10, 10, 10, 11, 12, + 12, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13}, +}; + +static const u8 +rtw8814a_pwrtrk_type8_5ga_p[RTW_PWR_TRK_5G_NUM][RTW_PWR_TRK_TBL_SZ] = { + {0, 0, 1, 2, 3, 3, 4, 5, 6, 7, 7, 9, 10, 11, 12, 13, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14}, + {0, 0, 1, 2, 3, 4, 5, 5, 6, 7, 8, 9, 10, 11, 12, 13, 13, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14}, + {0, 0, 1, 2, 3, 3, 4, 4, 6, 7, 7, 9, 10, 11, 12, 13, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14}, +}; + +static const u8 rtw8814a_pwrtrk_type8_2gd_n[RTW_PWR_TRK_TBL_SZ] = { + 0, 0, 1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 4, 5, 5, 5, + 6, 6, 7, 8, 9, 10, 11, 11, 11, 11, 11, 11, 11 +}; + +static const u8 rtw8814a_pwrtrk_type8_2gd_p[RTW_PWR_TRK_TBL_SZ] = { + 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 6, 6, 7, 7, 8, 9, 9, 10, + 10, 11, 12, 12, 13, 14, 14, 14, 14, 14, 14, 14 +}; + +static const u8 rtw8814a_pwrtrk_type8_2gc_n[RTW_PWR_TRK_TBL_SZ] = { + 0, 1, 1, 2, 2, 3, 3, 4, 5, 6, 6, 6, 7, 7, 8, 8, 9, 10, + 10, 11, 12, 12, 13, 13, 13, 13, 14, 14, 14, 14 +}; + +static const u8 rtw8814a_pwrtrk_type8_2gc_p[RTW_PWR_TRK_TBL_SZ] = { + 0, 1, 1, 2, 3, 3, 4, 4, 4, 5, 5, 6, 7, 8, 8, 9, 10, 10, + 11, 12, 13, 13, 14, 14, 14, 14, 14, 14, 14, 14 +}; + +static const u8 rtw8814a_pwrtrk_type8_2gb_n[RTW_PWR_TRK_TBL_SZ] = { + 0, 1, 1, 2, 2, 3, 3, 4, 5, 5, 6, 6, 7, 7, 8, 8, 8, + 9, 9, 10, 10, 11, 11, 12, 12, 12, 13, 14, 14, 14 +}; + +static const u8 rtw8814a_pwrtrk_type8_2gb_p[RTW_PWR_TRK_TBL_SZ] = { + 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 6, 6, 7, 8, 8, 9, 9, 10, + 10, 11, 12, 12, 13, 13, 13, 13, 13, 14, 14, 14 +}; + +static const u8 rtw8814a_pwrtrk_type8_2ga_n[RTW_PWR_TRK_TBL_SZ] = { + 0, 0, 1, 2, 2, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 9, 9, 9, + 10, 11, 11, 12, 12, 13, 13, 13, 13, 13, 13, 13 +}; + +static const u8 rtw8814a_pwrtrk_type8_2ga_p[RTW_PWR_TRK_TBL_SZ] = { + 0, 1, 1, 2, 3, 3, 4, 4, 4, 5, 6, 6, 7, 7, 8, 8, 9, 10, + 11, 12, 12, 13, 13, 14, 14, 14, 14, 14, 14, 14 +}; + +static const u8 rtw8814a_pwrtrk_type8_2g_cck_d_n[RTW_PWR_TRK_TBL_SZ] = { + 0, 1, 1, 2, 3, 3, 3, 4, 4, 4, 5, 5, 5, 6, 6, 7, 8, + 9, 9, 9, 9, 9, 9, 10, 10, 11, 11, 12, 12, 12 +}; + +static const u8 rtw8814a_pwrtrk_type8_2g_cck_d_p[RTW_PWR_TRK_TBL_SZ] = { + 0, 1, 1, 1, 2, 3, 3, 4, 4, 5, 6, 6, 7, 8, 8, 9, 10, 10, + 10, 11, 12, 12, 13, 14, 14, 14, 14, 14, 14, 14 +}; + +static const u8 rtw8814a_pwrtrk_type8_2g_cck_c_n[RTW_PWR_TRK_TBL_SZ] = { + 0, 0, 1, 2, 2, 3, 4, 5, 5, 6, 6, 6, 6, 7, 8, 9, 9, 10, + 10, 11, 11, 11, 12, 13, 13, 13, 13, 13, 13, 13 +}; + +static const u8 rtw8814a_pwrtrk_type8_2g_cck_c_p[RTW_PWR_TRK_TBL_SZ] = { + 0, 0, 1, 1, 2, 2, 3, 3, 4, 5, 5, 6, 7, 7, 8, 9, 9, 10, + 10, 11, 12, 12, 13, 13, 13, 13, 13, 13, 13, 13 +}; + +static const u8 rtw8814a_pwrtrk_type8_2g_cck_b_n[RTW_PWR_TRK_TBL_SZ] = { + 0, 1, 1, 2, 2, 2, 3, 3, 4, 5, 6, 6, 7, 7, 8, 8, 9, 10, + 10, 10, 11, 11, 12, 12, 12, 12, 12, 12, 12, 12 +}; + +static const u8 rtw8814a_pwrtrk_type8_2g_cck_b_p[RTW_PWR_TRK_TBL_SZ] = { + 0, 1, 1, 1, 2, 3, 3, 4, 4, 5, 5, 6, 7, 8, 8, 9, 9, 10, + 10, 11, 12, 12, 13, 13, 13, 13, 13, 13, 13, 13 +}; + +static const u8 rtw8814a_pwrtrk_type8_2g_cck_a_n[RTW_PWR_TRK_TBL_SZ] = { + 0, 1, 2, 2, 3, 4, 4, 4, 5, 5, 6, 6, 7, 8, 9, 9, 9, 9, + 10, 10, 11, 11, 11, 12, 12, 12, 12, 12, 12, 12 +}; + +static const u8 rtw8814a_pwrtrk_type8_2g_cck_a_p[RTW_PWR_TRK_TBL_SZ] = { + 0, 0, 1, 2, 2, 3, 3, 4, 5, 5, 6, 7, 8, 9, 9, 10, 10, + 11, 11, 12, 12, 12, 13, 13, 13, 13, 13, 13, 13, 13 +}; + +const struct rtw_pwr_track_tbl rtw8814a_rtw_pwrtrk_type8_tbl = { + .pwrtrk_5gd_n[RTW_PWR_TRK_5G_1] = rtw8814a_pwrtrk_type8_5gd_n[RTW_PWR_TRK_5G_1], + .pwrtrk_5gd_n[RTW_PWR_TRK_5G_2] = rtw8814a_pwrtrk_type8_5gd_n[RTW_PWR_TRK_5G_2], + .pwrtrk_5gd_n[RTW_PWR_TRK_5G_3] = rtw8814a_pwrtrk_type8_5gd_n[RTW_PWR_TRK_5G_3], + .pwrtrk_5gd_p[RTW_PWR_TRK_5G_1] = rtw8814a_pwrtrk_type8_5gd_p[RTW_PWR_TRK_5G_1], + .pwrtrk_5gd_p[RTW_PWR_TRK_5G_2] = rtw8814a_pwrtrk_type8_5gd_p[RTW_PWR_TRK_5G_2], + .pwrtrk_5gd_p[RTW_PWR_TRK_5G_3] = rtw8814a_pwrtrk_type8_5gd_p[RTW_PWR_TRK_5G_3], + .pwrtrk_5gc_n[RTW_PWR_TRK_5G_1] = rtw8814a_pwrtrk_type8_5gc_n[RTW_PWR_TRK_5G_1], + .pwrtrk_5gc_n[RTW_PWR_TRK_5G_2] = rtw8814a_pwrtrk_type8_5gc_n[RTW_PWR_TRK_5G_2], + .pwrtrk_5gc_n[RTW_PWR_TRK_5G_3] = rtw8814a_pwrtrk_type8_5gc_n[RTW_PWR_TRK_5G_3], + .pwrtrk_5gc_p[RTW_PWR_TRK_5G_1] = rtw8814a_pwrtrk_type8_5gc_p[RTW_PWR_TRK_5G_1], + .pwrtrk_5gc_p[RTW_PWR_TRK_5G_2] = rtw8814a_pwrtrk_type8_5gc_p[RTW_PWR_TRK_5G_2], + .pwrtrk_5gc_p[RTW_PWR_TRK_5G_3] = rtw8814a_pwrtrk_type8_5gc_p[RTW_PWR_TRK_5G_3], + .pwrtrk_5gb_n[RTW_PWR_TRK_5G_1] = rtw8814a_pwrtrk_type8_5gb_n[RTW_PWR_TRK_5G_1], + .pwrtrk_5gb_n[RTW_PWR_TRK_5G_2] = rtw8814a_pwrtrk_type8_5gb_n[RTW_PWR_TRK_5G_2], + .pwrtrk_5gb_n[RTW_PWR_TRK_5G_3] = rtw8814a_pwrtrk_type8_5gb_n[RTW_PWR_TRK_5G_3], + .pwrtrk_5gb_p[RTW_PWR_TRK_5G_1] = rtw8814a_pwrtrk_type8_5gb_p[RTW_PWR_TRK_5G_1], + .pwrtrk_5gb_p[RTW_PWR_TRK_5G_2] = rtw8814a_pwrtrk_type8_5gb_p[RTW_PWR_TRK_5G_2], + .pwrtrk_5gb_p[RTW_PWR_TRK_5G_3] = rtw8814a_pwrtrk_type8_5gb_p[RTW_PWR_TRK_5G_3], + .pwrtrk_5ga_n[RTW_PWR_TRK_5G_1] = rtw8814a_pwrtrk_type8_5ga_n[RTW_PWR_TRK_5G_1], + .pwrtrk_5ga_n[RTW_PWR_TRK_5G_2] = rtw8814a_pwrtrk_type8_5ga_n[RTW_PWR_TRK_5G_2], + .pwrtrk_5ga_n[RTW_PWR_TRK_5G_3] = rtw8814a_pwrtrk_type8_5ga_n[RTW_PWR_TRK_5G_3], + .pwrtrk_5ga_p[RTW_PWR_TRK_5G_1] = rtw8814a_pwrtrk_type8_5ga_p[RTW_PWR_TRK_5G_1], + .pwrtrk_5ga_p[RTW_PWR_TRK_5G_2] = rtw8814a_pwrtrk_type8_5ga_p[RTW_PWR_TRK_5G_2], + .pwrtrk_5ga_p[RTW_PWR_TRK_5G_3] = rtw8814a_pwrtrk_type8_5ga_p[RTW_PWR_TRK_5G_3], + .pwrtrk_2gd_n = rtw8814a_pwrtrk_type8_2gd_n, + .pwrtrk_2gd_p = rtw8814a_pwrtrk_type8_2gd_p, + .pwrtrk_2gc_n = rtw8814a_pwrtrk_type8_2gc_n, + .pwrtrk_2gc_p = rtw8814a_pwrtrk_type8_2gc_p, + .pwrtrk_2gb_n = rtw8814a_pwrtrk_type8_2gb_n, + .pwrtrk_2gb_p = rtw8814a_pwrtrk_type8_2gb_p, + .pwrtrk_2ga_n = rtw8814a_pwrtrk_type8_2ga_n, + .pwrtrk_2ga_p = rtw8814a_pwrtrk_type8_2ga_p, + .pwrtrk_2g_cckd_n = rtw8814a_pwrtrk_type8_2g_cck_d_n, + .pwrtrk_2g_cckd_p = rtw8814a_pwrtrk_type8_2g_cck_d_p, + .pwrtrk_2g_cckc_n = rtw8814a_pwrtrk_type8_2g_cck_c_n, + .pwrtrk_2g_cckc_p = rtw8814a_pwrtrk_type8_2g_cck_c_p, + .pwrtrk_2g_cckb_n = rtw8814a_pwrtrk_type8_2g_cck_b_n, + .pwrtrk_2g_cckb_p = rtw8814a_pwrtrk_type8_2g_cck_b_p, + .pwrtrk_2g_ccka_n = rtw8814a_pwrtrk_type8_2g_cck_a_n, + .pwrtrk_2g_ccka_p = rtw8814a_pwrtrk_type8_2g_cck_a_p, +}; + +static const struct rtw_pwr_seq_cmd init_power_on_8814a[] = { + {0x10c2, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_USB_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, BIT(1), BIT(1)}, + {0xFFFF, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_ALL_MSK, + 0, + RTW_PWR_CMD_END, 0, 0}, +}; + +static const struct rtw_pwr_seq_cmd trans_carddis_to_cardemu_8814a[] = { + {0x0012, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_ALL_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, BIT(6), BIT(6)}, + {0x0015, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_ALL_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, BIT(5), 0}, + {0x0015, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_ALL_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, BIT(6), 0}, + {0x0023, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_ALL_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, BIT(4), 0}, + {0x0046, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_ALL_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, 0xFF, 0x00}, + {0x0062, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_ALL_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, 0xFF, 0x00}, + {0x0005, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_PCI_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, BIT(2), 0}, + {0x0005, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_ALL_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, BIT(3), 0}, + {0x0301, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_PCI_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, 0xFF, 0}, + {0x0071, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_PCI_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, BIT(2), 0}, + {0xFFFF, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_ALL_MSK, + 0, + RTW_PWR_CMD_END, 0, 0}, +}; + +static const struct rtw_pwr_seq_cmd trans_cardemu_to_act_8814a[] = { + {0x0005, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_ALL_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, BIT(2), 0}, + {0x0006, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_ALL_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_POLLING, BIT(1), BIT(1)}, + {0x0005, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_ALL_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, BIT(3), 0}, + {0x00F0, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_ALL_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, BIT(7), 0}, + {0x0081, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_ALL_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, 0x30, 0x20}, + {0x0005, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_ALL_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, BIT(0), BIT(0)}, + {0x0005, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_ALL_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_POLLING, BIT(0), 0}, + {0xFFFF, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_ALL_MSK, + 0, + RTW_PWR_CMD_END, 0, 0}, +}; + +static const struct rtw_pwr_seq_cmd trans_act_to_cardemu_8814a[] = { + {0x0c00, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_ALL_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, 0xFF, 0x04}, + {0x0e00, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_ALL_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, 0xFF, 0x04}, + {0x1002, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_ALL_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, BIT(0), 0}, + {0x0002, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_ALL_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_DELAY, 1, RTW_PWR_DELAY_US}, + {0x1002, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_PCI_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, BIT(1), 0}, + {0x001F, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_ALL_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, 0xFF, 0}, + {0x0007, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_ALL_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, 0xFF, 0x28}, + {0x0008, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_USB_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, 0x02, 0}, + {0x0066, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_USB_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, BIT(7), 0}, + {0x0041, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_USB_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, BIT(4), 0}, + {0x0042, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_USB_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, BIT(1), 0}, + {0x004e, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_USB_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, BIT(5), BIT(5)}, + {0x0041, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_USB_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, BIT(0), 0}, + {0x0005, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_ALL_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, BIT(1), BIT(1)}, + {0x0005, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_ALL_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_POLLING, BIT(1), 0}, + {0xFFFF, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_ALL_MSK, + 0, + RTW_PWR_CMD_END, 0, 0}, +}; + +static const struct rtw_pwr_seq_cmd trans_cardemu_to_carddis_8814a[] = { + {0x0003, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_ALL_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, BIT(2), 0}, + {0x0080, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_ALL_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, 0xFF, 0x01}, + {0x0081, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_ALL_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, 0xFF, 0x30}, + {0x0045, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_ALL_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, 0xFF, 0x00}, + {0x0046, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_ALL_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, 0xFF, 0xff}, + {0x0047, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_ALL_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, 0xFF, 0}, + {0x0015, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_ALL_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, BIT(6), BIT(6)}, + {0x0015, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_ALL_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, BIT(5), BIT(5)}, + {0x0012, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_ALL_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, BIT(6), 0}, + {0x0023, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_ALL_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, BIT(4), BIT(4)}, + {0x0008, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_ALL_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, BIT(1), 0}, + {0x0007, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_ALL_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, 0xFF, 0x20}, + {0x001f, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_ALL_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, BIT(1), 0}, + {0x0020, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_ALL_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, BIT(1), 0}, + {0x0021, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_ALL_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, BIT(1), 0}, + {0x0076, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_ALL_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, BIT(1), 0}, + {0x0091, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_ALL_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, 0xA0, 0xA0}, + {0x0070, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_ALL_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, BIT(3), BIT(3)}, + {0x0005, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_ALL_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, BIT(3), BIT(3)}, + {0xFFFF, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_ALL_MSK, + 0, + RTW_PWR_CMD_END, 0, 0}, +}; + +const struct rtw_pwr_seq_cmd *card_enable_flow_8814a[] = { + init_power_on_8814a, + trans_carddis_to_cardemu_8814a, + trans_cardemu_to_act_8814a, + NULL +}; + +const struct rtw_pwr_seq_cmd *card_disable_flow_8814a[] = { + trans_act_to_cardemu_8814a, + trans_cardemu_to_carddis_8814a, + NULL +}; diff --git a/rtw8814a_table.h b/rtw8814a_table.h new file mode 100644 index 00000000..8a63ee00 --- /dev/null +++ b/rtw8814a_table.h @@ -0,0 +1,40 @@ +/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */ +/* Copyright(c) 2025 Realtek Corporation + */ + +#ifndef __RTW8814A_TABLE_H__ +#define __RTW8814A_TABLE_H__ + +extern const struct rtw_table rtw8814a_mac_tbl; +extern const struct rtw_table rtw8814a_agc_tbl; +extern const struct rtw_table rtw8814a_bb_tbl; +extern const struct rtw_table rtw8814a_bb_pg_tbl; +extern const struct rtw_table rtw8814a_bb_pg_type0_tbl; +extern const struct rtw_table rtw8814a_bb_pg_type2_tbl; +extern const struct rtw_table rtw8814a_bb_pg_type3_tbl; +extern const struct rtw_table rtw8814a_bb_pg_type4_tbl; +extern const struct rtw_table rtw8814a_bb_pg_type5_tbl; +extern const struct rtw_table rtw8814a_bb_pg_type7_tbl; +extern const struct rtw_table rtw8814a_bb_pg_type8_tbl; +extern const struct rtw_table rtw8814a_rf_a_tbl; +extern const struct rtw_table rtw8814a_rf_b_tbl; +extern const struct rtw_table rtw8814a_rf_c_tbl; +extern const struct rtw_table rtw8814a_rf_d_tbl; +extern const struct rtw_table rtw8814a_txpwr_lmt_tbl; +extern const struct rtw_table rtw8814a_txpwr_lmt_type0_tbl; +extern const struct rtw_table rtw8814a_txpwr_lmt_type1_tbl; +extern const struct rtw_table rtw8814a_txpwr_lmt_type2_tbl; +extern const struct rtw_table rtw8814a_txpwr_lmt_type3_tbl; +extern const struct rtw_table rtw8814a_txpwr_lmt_type5_tbl; +extern const struct rtw_table rtw8814a_txpwr_lmt_type7_tbl; +extern const struct rtw_table rtw8814a_txpwr_lmt_type8_tbl; +extern const struct rtw_pwr_track_tbl rtw8814a_rtw_pwrtrk_tbl; +extern const struct rtw_pwr_track_tbl rtw8814a_rtw_pwrtrk_type0_tbl; +extern const struct rtw_pwr_track_tbl rtw8814a_rtw_pwrtrk_type2_tbl; +extern const struct rtw_pwr_track_tbl rtw8814a_rtw_pwrtrk_type5_tbl; +extern const struct rtw_pwr_track_tbl rtw8814a_rtw_pwrtrk_type7_tbl; +extern const struct rtw_pwr_track_tbl rtw8814a_rtw_pwrtrk_type8_tbl; +extern const struct rtw_pwr_seq_cmd *card_disable_flow_8814a[]; +extern const struct rtw_pwr_seq_cmd *card_enable_flow_8814a[]; + +#endif From 7fe2d8ca61ae8f014486a73881ef03a8e8bdb42a Mon Sep 17 00:00:00 2001 From: Bitterblue Smith Date: Sat, 16 Nov 2024 02:07:22 +0200 Subject: [PATCH 096/193] wifi: rtw88: Add rtw8814a.{c,h} These contain all the logic for the RTL8814A chip. Signed-off-by: Bitterblue Smith --- rtw8814a.c | 2201 ++++++++++++++++++++++++++++++++++++++++++++++++++++ rtw8814a.h | 64 ++ 2 files changed, 2265 insertions(+) create mode 100644 rtw8814a.c create mode 100644 rtw8814a.h diff --git a/rtw8814a.c b/rtw8814a.c new file mode 100644 index 00000000..ac5fd43c --- /dev/null +++ b/rtw8814a.c @@ -0,0 +1,2201 @@ +// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause +/* Copyright(c) 2025 Realtek Corporation + */ + +#include +#include "main.h" +#include "coex.h" +#include "tx.h" +#include "phy.h" +#include "rtw8814a.h" +#include "rtw8814a_table.h" +#include "rtw88xxa.h" +#include "reg.h" +#include "debug.h" +#include "efuse.h" +#include "regd.h" +#include "usb.h" + +static void rtw8814a_efuse_grant(struct rtw_dev *rtwdev, bool on) +{ + if (on) { + rtw_write8(rtwdev, REG_EFUSE_ACCESS, EFUSE_ACCESS_ON); + + rtw_write16_set(rtwdev, REG_SYS_FUNC_EN, BIT_FEN_ELDR); + rtw_write16_set(rtwdev, REG_SYS_CLKR, + BIT_LOADER_CLK_EN | BIT_ANA8M); + } else { + rtw_write8(rtwdev, REG_EFUSE_ACCESS, EFUSE_ACCESS_OFF); + } +} + +static void rtw8814a_read_rfe_type(struct rtw_dev *rtwdev) +{ + struct rtw_efuse *efuse = &rtwdev->efuse; + + if (!(efuse->rfe_option & BIT(7))) + return; + + if (rtw_hci_type(rtwdev) == RTW_HCI_TYPE_PCIE) + efuse->rfe_option = 0; + else if (rtw_hci_type(rtwdev) == RTW_HCI_TYPE_USB) + efuse->rfe_option = 1; +} + +static void rtw8814a_read_amplifier_type(struct rtw_dev *rtwdev) +{ + struct rtw_efuse *efuse = &rtwdev->efuse; + + switch (efuse->rfe_option) { + case 1: + /* Internal 2G */ + efuse->pa_type_2g = 0; + efuse->lna_type_2g = 0; + /* External 5G */ + efuse->pa_type_5g = BIT(0); + efuse->lna_type_5g = BIT(3); + break; + case 2 ... 5: + /* External everything */ + efuse->pa_type_2g = BIT(4); + efuse->lna_type_2g = BIT(3); + efuse->pa_type_5g = BIT(0); + efuse->lna_type_5g = BIT(3); + break; + case 6: + efuse->lna_type_5g = BIT(3); + break; + default: + break; + } +} + +static void rtw8814a_read_rf_type(struct rtw_dev *rtwdev, + struct rtw8814a_efuse *map) +{ + struct rtw_usb *rtwusb = rtw_get_usb_priv(rtwdev); + struct rtw_hal *hal = &rtwdev->hal; + + switch (map->trx_antenna_option) { + case 0xff: /* 4T4R */ + case 0xee: /* 3T3R */ + if (rtw_hci_type(rtwdev) == RTW_HCI_TYPE_USB && + rtwusb->udev->speed != USB_SPEED_SUPER) + hal->rf_type = RF_2T2R; + else + hal->rf_type = RF_3T3R; + + break; + case 0x66: /* 2T2R */ + case 0x6f: /* 2T4R */ + default: + hal->rf_type = RF_2T2R; + break; + } + + hal->rf_path_num = 4; + hal->rf_phy_num = 4; + + if (hal->rf_type == RF_3T3R) { + hal->antenna_rx = BB_PATH_ABC; + hal->antenna_tx = BB_PATH_ABC; + } else { + hal->antenna_rx = BB_PATH_AB; + hal->antenna_tx = BB_PATH_AB; + } +} + +static void rtw8814a_init_hwcap(struct rtw_dev *rtwdev) +{ + struct rtw_efuse *efuse = &rtwdev->efuse; + struct rtw_hal *hal = &rtwdev->hal; + + efuse->hw_cap.bw = BIT(RTW_CHANNEL_WIDTH_20) | + BIT(RTW_CHANNEL_WIDTH_40) | + BIT(RTW_CHANNEL_WIDTH_80); + efuse->hw_cap.ptcl = EFUSE_HW_CAP_PTCL_VHT; + + if (hal->rf_type == RF_3T3R) + efuse->hw_cap.nss = 3; + else + efuse->hw_cap.nss = 2; + + rtw_dbg(rtwdev, RTW_DBG_EFUSE, + "hw cap: hci=0x%02x, bw=0x%02x, ptcl=0x%02x, ant_num=%d, nss=%d\n", + efuse->hw_cap.hci, efuse->hw_cap.bw, efuse->hw_cap.ptcl, + efuse->hw_cap.ant_num, efuse->hw_cap.nss); +} + +static int rtw8814a_read_efuse(struct rtw_dev *rtwdev, u8 *log_map) +{ + struct rtw_efuse *efuse = &rtwdev->efuse; + struct rtw8814a_efuse *map; + int i; + + if (rtw_dbg_is_enabled(rtwdev, RTW_DBG_EFUSE)) + print_hex_dump(KERN_INFO, "", DUMP_PREFIX_OFFSET, 16, 1, + log_map, rtwdev->chip->log_efuse_size, true); + + map = (struct rtw8814a_efuse *)log_map; + + efuse->usb_mode_switch = u8_get_bits(map->usb_mode, BIT(4)); + efuse->rfe_option = map->rfe_option; + efuse->rf_board_option = map->rf_board_option; + efuse->crystal_cap = map->xtal_k; + efuse->channel_plan = map->channel_plan; + efuse->country_code[0] = map->country_code[0]; + efuse->country_code[1] = map->country_code[1]; + efuse->bt_setting = map->rf_bt_setting; + efuse->regd = map->rf_board_option & 0x7; + efuse->thermal_meter[RF_PATH_A] = map->thermal_meter; + efuse->thermal_meter_k = map->thermal_meter; + efuse->tx_bb_swing_setting_2g = map->tx_bb_swing_setting_2g; + efuse->tx_bb_swing_setting_5g = map->tx_bb_swing_setting_5g; + + rtw8814a_read_rfe_type(rtwdev); + rtw8814a_read_amplifier_type(rtwdev); + + /* Override rtw_chip_parameter_setup() */ + rtw8814a_read_rf_type(rtwdev, map); + + rtw8814a_init_hwcap(rtwdev); + + for (i = 0; i < 4; i++) + efuse->txpwr_idx_table[i] = map->txpwr_idx_table[i]; + + switch (rtw_hci_type(rtwdev)) { + case RTW_HCI_TYPE_USB: + ether_addr_copy(efuse->addr, map->u.mac_addr); + break; + case RTW_HCI_TYPE_PCIE: + case RTW_HCI_TYPE_SDIO: + default: + /* unsupported now */ + return -EOPNOTSUPP; + } + + return 0; +} + +static void rtw8814a_init_rfe_reg(struct rtw_dev *rtwdev) +{ + u8 rfe_option = rtwdev->efuse.rfe_option; + + if (rfe_option == 2 || rfe_option == 1) { + rtw_write32_mask(rtwdev, 0x1994, 0xf, 0xf); + rtw_write8_set(rtwdev, REG_GPIO_MUXCFG + 2, 0xf0); + } else if (rfe_option == 0) { + rtw_write32_mask(rtwdev, 0x1994, 0xf, 0xf); + rtw_write8_set(rtwdev, REG_GPIO_MUXCFG + 2, 0xc0); + } +} + +#define RTW_TXSCALE_SIZE 37 +static const u32 rtw8814a_txscale_tbl[RTW_TXSCALE_SIZE] = { + 0x081, 0x088, 0x090, 0x099, 0x0a2, 0x0ac, 0x0b6, 0x0c0, 0x0cc, 0x0d8, + 0x0e5, 0x0f2, 0x101, 0x110, 0x120, 0x131, 0x143, 0x156, 0x16a, 0x180, + 0x197, 0x1af, 0x1c8, 0x1e3, 0x200, 0x21e, 0x23e, 0x261, 0x285, 0x2ab, + 0x2d3, 0x2fe, 0x32b, 0x35c, 0x38e, 0x3c4, 0x3fe +}; + +static u32 rtw8814a_get_bb_swing(struct rtw_dev *rtwdev, u8 band, u8 rf_path) +{ + static const u32 swing2setting[4] = {0x200, 0x16a, 0x101, 0x0b6}; + struct rtw_efuse *efuse = &rtwdev->efuse; + u8 tx_bb_swing; + + if (band == RTW_BAND_2G) + tx_bb_swing = efuse->tx_bb_swing_setting_2g; + else + tx_bb_swing = efuse->tx_bb_swing_setting_5g; + + tx_bb_swing >>= 2 * rf_path; + tx_bb_swing &= 0x3; + + return swing2setting[tx_bb_swing]; +} + +static u8 rtw8814a_get_swing_index(struct rtw_dev *rtwdev) +{ + u32 swing, table_value; + u8 i; + + swing = rtw8814a_get_bb_swing(rtwdev, rtwdev->hal.current_band_type, + RF_PATH_A); + + for (i = 0; i < ARRAY_SIZE(rtw8814a_txscale_tbl); i++) { + table_value = rtw8814a_txscale_tbl[i]; + if (swing == table_value) + return i; + } + + return 24; +} + +static void rtw8814a_pwrtrack_init(struct rtw_dev *rtwdev) +{ + struct rtw_dm_info *dm_info = &rtwdev->dm_info; + u8 path; + + dm_info->default_ofdm_index = rtw8814a_get_swing_index(rtwdev); + + for (path = RF_PATH_A; path < rtwdev->hal.rf_path_num; path++) { + ewma_thermal_init(&dm_info->avg_thermal[path]); + dm_info->delta_power_index[path] = 0; + dm_info->delta_power_index_last[path] = 0; + } + dm_info->pwr_trk_triggered = false; + dm_info->pwr_trk_init_trigger = true; + dm_info->thermal_meter_k = rtwdev->efuse.thermal_meter_k; +} + +static void rtw8814a_config_trx_path(struct rtw_dev *rtwdev) +{ + /* RX CCK disable 2R CCA */ + rtw_write32_clr(rtwdev, REG_CCK0_FAREPORT, + BIT_CCK0_2RX | BIT_CCK0_MRC); + /* pathB tx on, path A/C/D tx off */ + rtw_write32_mask(rtwdev, REG_CCK_RX, 0xf0000000, 0x4); + /* pathB rx */ + rtw_write32_mask(rtwdev, REG_CCK_RX, 0x0f000000, 0x5); +} + +static void rtw8814a_config_cck_rx_antenna_init(struct rtw_dev *rtwdev) +{ + /* CCK 2R CCA parameters */ + + /* Disable Ant diversity */ + rtw_write32_mask(rtwdev, REG_RXSB, BIT(15), 0x0); + /* Concurrent CCA at LSB & USB */ + rtw_write32_mask(rtwdev, 0xa70, BIT(7), 0); + /* RX path diversity enable */ + rtw_write32_mask(rtwdev, 0xa74, BIT(8), 0); + /* r_en_mrc_antsel */ + rtw_write32_mask(rtwdev, 0xa14, BIT(7), 0); + /* MBC weighting */ + rtw_write32_mask(rtwdev, 0xa20, BIT(5) | BIT(4), 1); + /* 2R CCA only */ + rtw_write32_mask(rtwdev, 0xa84, BIT(28), 1); +} + +static void rtw8814a_phy_set_param(struct rtw_dev *rtwdev) +{ + u32 crystal_cap, val32; + u8 val8, rf_path; + + /* power on BB/RF domain */ + if (rtw_hci_type(rtwdev) == RTW_HCI_TYPE_USB) + rtw_write8_set(rtwdev, REG_SYS_FUNC_EN, BIT_FEN_USBA); + else if (rtw_hci_type(rtwdev) == RTW_HCI_TYPE_PCIE) + rtw_write8_set(rtwdev, REG_SYS_FUNC_EN, BIT_FEN_PCIEA); + + rtw_write8_set(rtwdev, REG_SYS_CFG3_8814A + 2, + BIT_FEN_BB_GLB_RST | BIT_FEN_BB_RSTB); + + /* Power on RF paths A..D */ + val8 = BIT_RF_EN | BIT_RF_RSTB | BIT_RF_SDM_RSTB; + rtw_write8(rtwdev, REG_RF_CTRL, val8); + rtw_write8(rtwdev, REG_RF_CTRL1, val8); + rtw_write8(rtwdev, REG_RF_CTRL2, val8); + rtw_write8(rtwdev, REG_RF_CTRL3, val8); + + rtw_load_table(rtwdev, rtwdev->chip->bb_tbl); + rtw_load_table(rtwdev, rtwdev->chip->agc_tbl); + + crystal_cap = rtwdev->efuse.crystal_cap & 0x3F; + crystal_cap |= crystal_cap << 6; + rtw_write32_mask(rtwdev, REG_AFE_CTRL3, 0x07ff8000, crystal_cap); + + rtw8814a_config_trx_path(rtwdev); + + for (rf_path = 0; rf_path < rtwdev->hal.rf_path_num; rf_path++) + rtw_load_table(rtwdev, rtwdev->chip->rf_tbl[rf_path]); + + val32 = rtw_read_rf(rtwdev, RF_PATH_A, RF_RCK1, RFREG_MASK); + rtw_write_rf(rtwdev, RF_PATH_B, RF_RCK1, RFREG_MASK, val32); + rtw_write_rf(rtwdev, RF_PATH_C, RF_RCK1, RFREG_MASK, val32); + rtw_write_rf(rtwdev, RF_PATH_D, RF_RCK1, RFREG_MASK, val32); + + rtw_write32_set(rtwdev, REG_RXPSEL, BIT_RX_PSEL_RST); + + rtw_write8(rtwdev, REG_HWSEQ_CTRL, 0xFF); + + rtw_write32(rtwdev, REG_BAR_MODE_CTRL, 0x0201ffff); + + rtw_write8(rtwdev, REG_MISC_CTRL, BIT_DIS_SECOND_CCA); + + rtw_write8(rtwdev, REG_NAV_CTRL + 2, 0); + + rtw_write8_clr(rtwdev, REG_GPIO_MUXCFG, BIT(5)); + + rtw8814a_config_cck_rx_antenna_init(rtwdev); + + rtw_phy_init(rtwdev); + rtw8814a_pwrtrack_init(rtwdev); + + rtw8814a_init_rfe_reg(rtwdev); + + rtw_write8_clr(rtwdev, REG_QUEUE_CTRL, BIT(3)); + + rtw_write8(rtwdev, REG_NAV_CTRL + 2, 235); + + /* enable Tx report. */ + rtw_write8(rtwdev, REG_FWHW_TXQ_CTRL + 1, 0x0F); + + if (rtw_hci_type(rtwdev) == RTW_HCI_TYPE_USB) { + /* Reset USB mode switch setting */ + rtw_write8(rtwdev, REG_SYS_SDIO_CTRL, 0x0); + rtw_write8(rtwdev, REG_ACLK_MON, 0x0); + } +} + +static int rtw8814a_mac_init(struct rtw_dev *rtwdev) +{ + struct rtw_usb *rtwusb = rtw_get_usb_priv(rtwdev); + + rtw_write16(rtwdev, REG_CR, + MAC_TRX_ENABLE | BIT_MAC_SEC_EN | BIT_32K_CAL_TMR_EN); + + rtw_load_table(rtwdev, rtwdev->chip->mac_tbl); + + rtw_write8(rtwdev, REG_AUTO_LLT_V1 + 3, + rtwdev->chip->usb_tx_agg_desc_num << 1); + + rtw_write32(rtwdev, REG_HIMR0, 0); + rtw_write32(rtwdev, REG_HIMR1, 0); + + rtw_write32_mask(rtwdev, REG_RRSR, 0xfffff, 0xfffff); + + rtw_write16(rtwdev, REG_RETRY_LIMIT, 0x3030); + + rtw_write16(rtwdev, REG_RXFLTMAP0, 0xffff); + rtw_write16(rtwdev, REG_RXFLTMAP1, 0x0400); + rtw_write16(rtwdev, REG_RXFLTMAP2, 0xffff); + + rtw_write8(rtwdev, REG_MAX_AGGR_NUM, 0x36); + rtw_write8(rtwdev, REG_MAX_AGGR_NUM + 1, 0x36); + + /* Set Spec SIFS (used in NAV) */ + rtw_write16(rtwdev, REG_SPEC_SIFS, 0x100a); + rtw_write16(rtwdev, REG_MAC_SPEC_SIFS, 0x100a); + + /* Set SIFS for CCK */ + rtw_write16(rtwdev, REG_SIFS, 0x100a); + + /* Set SIFS for OFDM */ + rtw_write16(rtwdev, REG_SIFS + 2, 0x100a); + + /* TXOP */ + rtw_write32(rtwdev, REG_EDCA_BE_PARAM, 0x005EA42B); + rtw_write32(rtwdev, REG_EDCA_BK_PARAM, 0x0000A44F); + rtw_write32(rtwdev, REG_EDCA_VI_PARAM, 0x005EA324); + rtw_write32(rtwdev, REG_EDCA_VO_PARAM, 0x002FA226); + + rtw_write8_set(rtwdev, REG_FWHW_TXQ_CTRL, BIT(7)); + + rtw_write8(rtwdev, REG_ACKTO, 0x80); + + rtw_write16(rtwdev, REG_BCN_CTRL, + BIT_DIS_TSF_UDT | (BIT_DIS_TSF_UDT << 8)); + rtw_write32_mask(rtwdev, REG_TBTT_PROHIBIT, 0xfffff, WLAN_TBTT_TIME); + rtw_write8(rtwdev, REG_DRVERLYINT, 0x05); + rtw_write8(rtwdev, REG_BCNDMATIM, WLAN_BCN_DMA_TIME); + rtw_write16(rtwdev, REG_BCNTCFG, 0x4413); + rtw_write8(rtwdev, REG_BCN_MAX_ERR, 0xFF); + + rtw_write32(rtwdev, REG_FAST_EDCA_VOVI_SETTING, 0x08070807); + rtw_write32(rtwdev, REG_FAST_EDCA_BEBK_SETTING, 0x08070807); + + if (rtw_hci_type(rtwdev) == RTW_HCI_TYPE_USB && + rtwusb->udev->speed == USB_SPEED_SUPER) { + /* Disable U1/U2 Mode to avoid 2.5G spur in USB3.0. */ + rtw_write8_clr(rtwdev, REG_USB_MOD, BIT(4) | BIT(3)); + /* To avoid usb 3.0 H2C fail. */ + rtw_write16(rtwdev, 0xf002, 0); + + rtw_write8_clr(rtwdev, REG_SW_AMPDU_BURST_MODE_CTRL, + BIT_PRE_TX_CMD); + } + + return 0; +} + +static void rtw8814a_set_rfe_reg_24g(struct rtw_dev *rtwdev) +{ + switch (rtwdev->efuse.rfe_option) { + case 2: + rtw_write32(rtwdev, REG_RFE_PINMUX_A, 0x72707270); + rtw_write32(rtwdev, REG_RFE_PINMUX_B, 0x72707270); + rtw_write32(rtwdev, REG_RFE_PINMUX_C, 0x72707270); + rtw_write32(rtwdev, REG_RFE_PINMUX_D, 0x77707770); + + rtw_write32_mask(rtwdev, 0x1ABC, 0x0ff00000, 0x72); + + break; + case 1: + rtw_write32(rtwdev, REG_RFE_PINMUX_A, 0x77777777); + rtw_write32(rtwdev, REG_RFE_PINMUX_B, 0x77777777); + rtw_write32(rtwdev, REG_RFE_PINMUX_C, 0x77777777); + rtw_write32(rtwdev, REG_RFE_PINMUX_D, 0x77777777); + + rtw_write32_mask(rtwdev, 0x1ABC, 0x0ff00000, 0x77); + + break; + case 0: + default: + rtw_write32(rtwdev, REG_RFE_PINMUX_A, 0x77777777); + rtw_write32(rtwdev, REG_RFE_PINMUX_B, 0x77777777); + rtw_write32(rtwdev, REG_RFE_PINMUX_C, 0x77777777); + /* Is it not necessary to set REG_RFE_PINMUX_D ? */ + + rtw_write32_mask(rtwdev, 0x1ABC, 0x0ff00000, 0x77); + + break; + } +} + +static void rtw8814a_set_rfe_reg_5g(struct rtw_dev *rtwdev) +{ + switch (rtwdev->efuse.rfe_option) { + case 2: + rtw_write32(rtwdev, REG_RFE_PINMUX_A, 0x37173717); + rtw_write32(rtwdev, REG_RFE_PINMUX_B, 0x37173717); + rtw_write32(rtwdev, REG_RFE_PINMUX_C, 0x37173717); + rtw_write32(rtwdev, REG_RFE_PINMUX_D, 0x77177717); + + rtw_write32_mask(rtwdev, 0x1ABC, 0x0ff00000, 0x37); + + break; + case 1: + rtw_write32(rtwdev, REG_RFE_PINMUX_A, 0x33173317); + rtw_write32(rtwdev, REG_RFE_PINMUX_B, 0x33173317); + rtw_write32(rtwdev, REG_RFE_PINMUX_C, 0x33173317); + rtw_write32(rtwdev, REG_RFE_PINMUX_D, 0x77177717); + + rtw_write32_mask(rtwdev, 0x1ABC, 0x0ff00000, 0x33); + + break; + case 0: + default: + rtw_write32(rtwdev, REG_RFE_PINMUX_A, 0x54775477); + rtw_write32(rtwdev, REG_RFE_PINMUX_B, 0x54775477); + rtw_write32(rtwdev, REG_RFE_PINMUX_C, 0x54775477); + rtw_write32(rtwdev, REG_RFE_PINMUX_D, 0x54775477); + + rtw_write32_mask(rtwdev, 0x1ABC, 0x0ff00000, 0x54); + + break; + } +} + +static void rtw8814a_set_channel_bb_swing(struct rtw_dev *rtwdev, u8 band) +{ + rtw_write32_mask(rtwdev, REG_TXSCALE_A, BB_SWING_MASK, + rtw8814a_get_bb_swing(rtwdev, band, RF_PATH_A)); + rtw_write32_mask(rtwdev, REG_TXSCALE_B, BB_SWING_MASK, + rtw8814a_get_bb_swing(rtwdev, band, RF_PATH_B)); + rtw_write32_mask(rtwdev, REG_TXSCALE_C, BB_SWING_MASK, + rtw8814a_get_bb_swing(rtwdev, band, RF_PATH_C)); + rtw_write32_mask(rtwdev, REG_TXSCALE_D, BB_SWING_MASK, + rtw8814a_get_bb_swing(rtwdev, band, RF_PATH_D)); + rtw8814a_pwrtrack_init(rtwdev); +} + +static void rtw8814a_set_bw_reg_adc(struct rtw_dev *rtwdev, u8 bw) +{ + u32 adc = 0; + + if (bw == RTW_CHANNEL_WIDTH_20) + adc = 0; + else if (bw == RTW_CHANNEL_WIDTH_40) + adc = 1; + else if (bw == RTW_CHANNEL_WIDTH_80) + adc = 2; + + rtw_write32_mask(rtwdev, REG_ADCCLK, BIT(1) | BIT(0), adc); +} + +static void rtw8814a_set_bw_reg_agc(struct rtw_dev *rtwdev, u8 new_band, u8 bw) +{ + u32 agc = 7; + + if (bw == RTW_CHANNEL_WIDTH_20) { + agc = 6; + } else if (bw == RTW_CHANNEL_WIDTH_40) { + if (new_band == RTW_BAND_5G) + agc = 8; + else + agc = 7; + } else if (bw == RTW_CHANNEL_WIDTH_80) { + agc = 3; + } + + rtw_write32_mask(rtwdev, REG_CCASEL, 0xf000, agc); +} + +static void rtw8814a_switch_band(struct rtw_dev *rtwdev, u8 new_band, u8 bw) +{ + /* Clear 0x1000[16], When this bit is set to 0, CCK and OFDM + * are disabled, and clock are gated. Otherwise, CCK and OFDM + * are enabled. + */ + rtw_write8_clr(rtwdev, REG_SYS_CFG3_8814A + 2, BIT_FEN_BB_RSTB); + + if (new_band == RTW_BAND_2G) { + rtw_write32_mask(rtwdev, REG_AGC_TABLE, 0x1f, 0); + + rtw8814a_set_rfe_reg_24g(rtwdev); + + rtw_write32_mask(rtwdev, REG_TXPSEL, 0xf0, 0x2); + rtw_write32_mask(rtwdev, REG_CCK_RX, 0x0f000000, 0x5); + + rtw_write32_mask(rtwdev, REG_RXPSEL, BIT_RX_PSEL_RST, 0x3); + + rtw_write8(rtwdev, REG_CCK_CHECK, 0); + + rtw_write32_mask(rtwdev, 0xa80, BIT(18), 0); + } else { + rtw_write8(rtwdev, REG_CCK_CHECK, BIT_CHECK_CCK_EN); + + /* Enable CCK Tx function, even when CCK is off */ + rtw_write32_mask(rtwdev, 0xa80, BIT(18), 1); + + rtw8814a_set_rfe_reg_5g(rtwdev); + + rtw_write32_mask(rtwdev, REG_TXPSEL, 0xf0, 0x0); + rtw_write32_mask(rtwdev, REG_CCK_RX, 0x0f000000, 0xf); + + rtw_write32_mask(rtwdev, REG_RXPSEL, BIT_RX_PSEL_RST, 0x2); + } + + rtw8814a_set_channel_bb_swing(rtwdev, new_band); + + rtw8814a_set_bw_reg_adc(rtwdev, bw); + rtw8814a_set_bw_reg_agc(rtwdev, new_band, bw); + + rtw_write8_set(rtwdev, REG_SYS_CFG3_8814A + 2, BIT_FEN_BB_RSTB); +} + +static void rtw8814a_switch_channel(struct rtw_dev *rtwdev, u8 channel) +{ + struct rtw_hal *hal = &rtwdev->hal; + u32 fc_area, rf_mod_ag, cfgch; + u8 path; + + switch (channel) { + case 36 ... 48: + fc_area = 0x494; + break; + case 50 ... 64: + fc_area = 0x453; + break; + case 100 ... 116: + fc_area = 0x452; + break; + default: + if (channel >= 118) + fc_area = 0x412; + else + fc_area = 0x96a; + break; + } + + rtw_write32_mask(rtwdev, REG_CLKTRK, 0x1ffe0000, fc_area); + + for (path = 0; path < hal->rf_path_num; path++) { + switch (channel) { + case 36 ... 64: + rf_mod_ag = 0x101; + break; + case 100 ... 140: + rf_mod_ag = 0x301; + break; + default: + if (channel > 140) + rf_mod_ag = 0x501; + else + rf_mod_ag = 0x000; + break; + } + + cfgch = (rf_mod_ag << 8) | channel; + + rtw_write_rf(rtwdev, path, RF_CFGCH, + RF18_RFSI_MASK | RF18_BAND_MASK | RF18_CHANNEL_MASK, cfgch); + } + + switch (channel) { + case 36 ... 64: + rtw_write32_mask(rtwdev, REG_AGC_TABLE, 0x1f, 1); + break; + case 100 ... 144: + rtw_write32_mask(rtwdev, REG_AGC_TABLE, 0x1f, 2); + break; + default: + if (channel >= 149) + rtw_write32_mask(rtwdev, REG_AGC_TABLE, 0x1f, 3); + + break; + } +} + +static void rtw8814a_24g_cck_tx_dfir(struct rtw_dev *rtwdev, u8 channel) +{ + if (channel >= 1 && channel <= 11) { + rtw_write32(rtwdev, REG_CCK0_TX_FILTER1, 0x1a1b0030); + rtw_write32(rtwdev, REG_CCK0_TX_FILTER2, 0x090e1317); + rtw_write32(rtwdev, REG_CCK0_DEBUG_PORT, 0x00000204); + } else if (channel >= 12 && channel <= 13) { + rtw_write32(rtwdev, REG_CCK0_TX_FILTER1, 0x1a1b0030); + rtw_write32(rtwdev, REG_CCK0_TX_FILTER2, 0x090e1217); + rtw_write32(rtwdev, REG_CCK0_DEBUG_PORT, 0x00000305); + } else if (channel == 14) { + rtw_write32(rtwdev, REG_CCK0_TX_FILTER1, 0x1a1b0030); + rtw_write32(rtwdev, REG_CCK0_TX_FILTER2, 0x00000E17); + rtw_write32(rtwdev, REG_CCK0_DEBUG_PORT, 0x00000000); + } +} + +static void rtw8814a_set_bw_reg_mac(struct rtw_dev *rtwdev, u8 bw) +{ + u16 val16 = rtw_read16(rtwdev, REG_WMAC_TRXPTCL_CTL); + + val16 &= ~BIT_RFMOD; + if (bw == RTW_CHANNEL_WIDTH_80) + val16 |= BIT_RFMOD_80M; + else if (bw == RTW_CHANNEL_WIDTH_40) + val16 |= BIT_RFMOD_40M; + + rtw_write16(rtwdev, REG_WMAC_TRXPTCL_CTL, val16); +} + +static void rtw8814a_set_bw_rf(struct rtw_dev *rtwdev, u8 bw) +{ + u8 path; + + for (path = RF_PATH_A; path < rtwdev->hal.rf_path_num; path++) { + switch (bw) { + case RTW_CHANNEL_WIDTH_5: + case RTW_CHANNEL_WIDTH_10: + case RTW_CHANNEL_WIDTH_20: + default: + rtw_write_rf(rtwdev, path, RF_CFGCH, RF18_BW_MASK, 3); + break; + case RTW_CHANNEL_WIDTH_40: + rtw_write_rf(rtwdev, path, RF_CFGCH, RF18_BW_MASK, 1); + break; + case RTW_CHANNEL_WIDTH_80: + rtw_write_rf(rtwdev, path, RF_CFGCH, RF18_BW_MASK, 0); + break; + } + } +} + +static void rtw8814a_adc_clk(struct rtw_dev *rtwdev) +{ + + static const u32 rxiqc_reg[2][4] = { + { REG_RX_IQC_AB_A, REG_RX_IQC_AB_B, + REG_RX_IQC_AB_C, REG_RX_IQC_AB_D }, + { REG_RX_IQC_CD_A, REG_RX_IQC_CD_B, + REG_RX_IQC_CD_C, REG_RX_IQC_CD_D } + }; + u32 bb_reg_8fc, bb_reg_808, rxiqc[4]; + u32 i = 0, mac_active = 1; + u8 mac_reg_522; + + if (rtwdev->hal.cut_version != RTW_CHIP_VER_CUT_A) + return; + + /* 1 Step1. MAC TX pause */ + mac_reg_522 = rtw_read8(rtwdev, REG_TXPAUSE); + bb_reg_8fc = rtw_read32(rtwdev, 0x8fc); + bb_reg_808 = rtw_read32(rtwdev, REG_RXPSEL); + rtw_write8(rtwdev, REG_TXPAUSE, 0x3f); + + /* 1 Step 2. Backup rxiqc & rxiqc = 0 */ + for (i = 0; i < 4; i++) { + rxiqc[i] = rtw_read32(rtwdev, rxiqc_reg[0][i]); + rtw_write32(rtwdev, rxiqc_reg[0][i], 0x0); + rtw_write32(rtwdev, rxiqc_reg[1][i], 0x0); + } + rtw_write32_mask(rtwdev, 0xa14, 0x00000300, 0x3); + i = 0; + + /* 1 Step 3. Monitor MAC IDLE */ + rtw_write32(rtwdev, 0x8fc, 0x0); + while (mac_active) { + mac_active = rtw_read32(rtwdev, 0xfa0) & 0x803e0008; + i++; + if (i > 1000) + break; + } + + /* 1 Step 4. ADC clk flow */ + rtw_write8(rtwdev, REG_RXPSEL, 0x11); + rtw_write32_mask(rtwdev, REG_DAC_RSTB, BIT(13), 0x1); + rtw_write8_mask(rtwdev, REG_GNT_BT, BIT(2) | BIT(1), 0x3); + rtw_write32_mask(rtwdev, REG_CCK_RPT_FORMAT, BIT(2), 0x1); + + /* 0xc1c/0xe1c/0x181c/0x1a1c[4] must=1 to ensure table can be + * written when bbrstb=0 + * 0xc60/0xe60/0x1860/0x1a60[15] always = 1 after this line + * 0xc60/0xe60/0x1860/0x1a60[14] always = 0 bcz its error in A-cut + */ + + /* power_off/clk_off @ anapar_state=idle mode */ + rtw_write32(rtwdev, REG_AFE_PWR1_A, 0x15800002); + rtw_write32(rtwdev, REG_AFE_PWR1_A, 0x01808003); + rtw_write32(rtwdev, REG_AFE_PWR1_B, 0x15800002); + rtw_write32(rtwdev, REG_AFE_PWR1_B, 0x01808003); + rtw_write32(rtwdev, REG_AFE_PWR1_C, 0x15800002); + rtw_write32(rtwdev, REG_AFE_PWR1_C, 0x01808003); + rtw_write32(rtwdev, REG_AFE_PWR1_D, 0x15800002); + rtw_write32(rtwdev, REG_AFE_PWR1_D, 0x01808003); + + rtw_write8_mask(rtwdev, REG_GNT_BT, BIT(2), 0x0); + rtw_write32_mask(rtwdev, REG_CCK_RPT_FORMAT, BIT(2), 0x0); + /* [19] = 1 to turn off ADC */ + rtw_write32(rtwdev, REG_CK_MONHA, 0x0D080058); + rtw_write32(rtwdev, REG_CK_MONHB, 0x0D080058); + rtw_write32(rtwdev, REG_CK_MONHC, 0x0D080058); + rtw_write32(rtwdev, REG_CK_MONHD, 0x0D080058); + + /* power_on/clk_off */ + /* [19] = 0 to turn on ADC */ + rtw_write32(rtwdev, REG_CK_MONHA, 0x0D000058); + rtw_write32(rtwdev, REG_CK_MONHB, 0x0D000058); + rtw_write32(rtwdev, REG_CK_MONHC, 0x0D000058); + rtw_write32(rtwdev, REG_CK_MONHD, 0x0D000058); + + /* power_on/clk_on @ anapar_state=BT mode */ + rtw_write32(rtwdev, REG_AFE_PWR1_A, 0x05808032); + rtw_write32(rtwdev, REG_AFE_PWR1_B, 0x05808032); + rtw_write32(rtwdev, REG_AFE_PWR1_C, 0x05808032); + rtw_write32(rtwdev, REG_AFE_PWR1_D, 0x05808032); + rtw_write8_mask(rtwdev, REG_GNT_BT, BIT(2), 0x1); + rtw_write32_mask(rtwdev, REG_CCK_RPT_FORMAT, BIT(2), 0x1); + + /* recover original setting @ anapar_state=BT mode */ + rtw_write32(rtwdev, REG_AFE_PWR1_A, 0x05808032); + rtw_write32(rtwdev, REG_AFE_PWR1_B, 0x05808032); + rtw_write32(rtwdev, REG_AFE_PWR1_C, 0x05808032); + rtw_write32(rtwdev, REG_AFE_PWR1_D, 0x05808032); + + rtw_write32(rtwdev, REG_AFE_PWR1_A, 0x05800002); + rtw_write32(rtwdev, REG_AFE_PWR1_A, 0x07808003); + rtw_write32(rtwdev, REG_AFE_PWR1_B, 0x05800002); + rtw_write32(rtwdev, REG_AFE_PWR1_B, 0x07808003); + rtw_write32(rtwdev, REG_AFE_PWR1_C, 0x05800002); + rtw_write32(rtwdev, REG_AFE_PWR1_C, 0x07808003); + rtw_write32(rtwdev, REG_AFE_PWR1_D, 0x05800002); + rtw_write32(rtwdev, REG_AFE_PWR1_D, 0x07808003); + + rtw_write8_mask(rtwdev, REG_GNT_BT, BIT(2) | BIT(1), 0x0); + rtw_write32_mask(rtwdev, REG_CCK_RPT_FORMAT, BIT(2), 0x0); + rtw_write32_mask(rtwdev, REG_DAC_RSTB, BIT(13), 0x0); + + /* 1 Step 5. Recover MAC TX & IQC */ + rtw_write8(rtwdev, REG_TXPAUSE, mac_reg_522); + rtw_write32(rtwdev, 0x8fc, bb_reg_8fc); + rtw_write32(rtwdev, REG_RXPSEL, bb_reg_808); + for (i = 0; i < 4; i++) { + rtw_write32(rtwdev, rxiqc_reg[0][i], rxiqc[i]); + rtw_write32(rtwdev, rxiqc_reg[1][i], 0x01000000); + } + rtw_write32_mask(rtwdev, 0xa14, 0x00000300, 0x0); +} + +static void rtw8814a_spur_calibration_ch140(struct rtw_dev *rtwdev, u8 channel) +{ + struct rtw_hal *hal = &rtwdev->hal; + + /* Add for 8814AE module ch140 MP Rx */ + if (channel == 140) { + if (hal->ch_param[0] == 0) + hal->ch_param[0] = rtw_read32(rtwdev, REG_CCASEL); + if (hal->ch_param[1] == 0) + hal->ch_param[1] = rtw_read32(rtwdev, REG_PDMFTH); + + rtw_write32(rtwdev, REG_CCASEL, 0x75438170); + rtw_write32(rtwdev, REG_PDMFTH, 0x79a18a0a); + } else { + if (rtw_read32(rtwdev, REG_CCASEL) == 0x75438170 && + hal->ch_param[0] != 0) + rtw_write32(rtwdev, REG_CCASEL, hal->ch_param[0]); + + if (rtw_read32(rtwdev, REG_PDMFTH) == 0x79a18a0a && + hal->ch_param[1] != 0) + rtw_write32(rtwdev, REG_PDMFTH, hal->ch_param[1]); + + hal->ch_param[0] = rtw_read32(rtwdev, REG_CCASEL); + hal->ch_param[1] = rtw_read32(rtwdev, REG_PDMFTH); + } +} + +static void rtw8814a_set_nbi_reg(struct rtw_dev *rtwdev, u32 tone_idx) +{ + /* tone_idx X 10 */ + static const u32 nbi_128[] = { + 25, 55, 85, 115, 135, + 155, 185, 205, 225, 245, + 265, 285, 305, 335, 355, + 375, 395, 415, 435, 455, + 485, 505, 525, 555, 585, 615, 635 + }; + u32 reg_idx = 0; + u32 i; + + for (i = 0; i < ARRAY_SIZE(nbi_128); i++) { + if (tone_idx < nbi_128[i]) { + reg_idx = i + 1; + break; + } + } + + rtw_write32_mask(rtwdev, REG_NBI_SETTING, 0xfc000, reg_idx); +} + +static void rtw8814a_nbi_setting(struct rtw_dev *rtwdev, u32 ch, u32 f_intf) +{ + u32 fc, int_distance, tone_idx; + + fc = 2412 + (ch - 1) * 5; + int_distance = abs_diff(fc, f_intf); + + /* 10 * (int_distance / 0.3125) */ + tone_idx = int_distance << 5; + + rtw8814a_set_nbi_reg(rtwdev, tone_idx); + + rtw_write32_mask(rtwdev, REG_NBI_SETTING, BIT_NBI_ENABLE, 1); +} + +static void rtw8814a_spur_nbi_setting(struct rtw_dev *rtwdev) +{ + u8 primary_channel = rtwdev->hal.primary_channel; + u8 rfe_type = rtwdev->efuse.rfe_option; + + if (rfe_type != 0 && rfe_type != 1 && rfe_type != 6 && rfe_type != 7) + return; + + if (primary_channel == 14) + rtw8814a_nbi_setting(rtwdev, primary_channel, 2480); + else if (primary_channel >= 4 && primary_channel <= 8) + rtw8814a_nbi_setting(rtwdev, primary_channel, 2440); + else + rtw_write32_mask(rtwdev, REG_NBI_SETTING, BIT_NBI_ENABLE, 0); +} + +/* A workaround to eliminate the 5280 MHz & 5600 MHz & 5760 MHz spur of 8814A */ +static void rtw8814a_spur_calibration(struct rtw_dev *rtwdev, u8 channel, u8 bw) +{ + u8 rfe_type = rtwdev->efuse.rfe_option; + bool reset_nbi_csi = true; + + if (rfe_type == 0) { + switch (bw) { + case RTW_CHANNEL_WIDTH_40: + if (channel == 54 || channel == 118) { + rtw_write32_mask(rtwdev, REG_NBI_SETTING, + 0x000fe000, 0x3e >> 1); + rtw_write32_mask(rtwdev, REG_CSI_MASK_SETTING1, + BIT(0), 1); + rtw_write32(rtwdev, REG_CSI_FIX_MASK0, 0); + rtw_write32_mask(rtwdev, REG_CSI_FIX_MASK1, + BIT(0), 1); + rtw_write32(rtwdev, REG_CSI_FIX_MASK6, 0); + rtw_write32(rtwdev, REG_CSI_FIX_MASK7, 0); + + reset_nbi_csi = false; + } else if (channel == 151) { + rtw_write32_mask(rtwdev, REG_NBI_SETTING, + 0x000fe000, 0x1e >> 1); + rtw_write32_mask(rtwdev, REG_CSI_MASK_SETTING1, + BIT(0), 1); + rtw_write32_mask(rtwdev, REG_CSI_FIX_MASK0, + BIT(16), 1); + rtw_write32(rtwdev, REG_CSI_FIX_MASK1, 0); + rtw_write32(rtwdev, REG_CSI_FIX_MASK6, 0); + rtw_write32(rtwdev, REG_CSI_FIX_MASK7, 0); + + reset_nbi_csi = false; + } + break; + case RTW_CHANNEL_WIDTH_80: + if (channel == 58 || channel == 122) { + rtw_write32_mask(rtwdev, REG_NBI_SETTING, + 0x000fe000, 0x3a >> 1); + rtw_write32_mask(rtwdev, REG_CSI_MASK_SETTING1, + BIT(0), 1); + rtw_write32(rtwdev, REG_CSI_FIX_MASK0, 0); + rtw_write32(rtwdev, REG_CSI_FIX_MASK1, 0); + rtw_write32(rtwdev, REG_CSI_FIX_MASK6, 0); + rtw_write32_mask(rtwdev, REG_CSI_FIX_MASK7, + BIT(0), 1); + + reset_nbi_csi = false; + } else if (channel == 155) { + rtw_write32_mask(rtwdev, REG_NBI_SETTING, + 0x000fe000, 0x5a >> 1); + rtw_write32_mask(rtwdev, REG_CSI_MASK_SETTING1, + BIT(0), 1); + rtw_write32(rtwdev, REG_CSI_FIX_MASK0, 0); + rtw_write32(rtwdev, REG_CSI_FIX_MASK1, 0); + rtw_write32_mask(rtwdev, REG_CSI_FIX_MASK6, + BIT(16), 1); + rtw_write32(rtwdev, REG_CSI_FIX_MASK7, 0); + + reset_nbi_csi = false; + } + break; + case RTW_CHANNEL_WIDTH_20: + if (channel == 153) { + rtw_write32_mask(rtwdev, REG_NBI_SETTING, + 0x000fe000, 0x1e >> 1); + rtw_write32_mask(rtwdev, REG_CSI_MASK_SETTING1, + BIT(0), 1); + rtw_write32(rtwdev, REG_CSI_FIX_MASK0, 0); + rtw_write32(rtwdev, REG_CSI_FIX_MASK1, 0); + rtw_write32(rtwdev, REG_CSI_FIX_MASK6, 0); + rtw_write32_mask(rtwdev, REG_CSI_FIX_MASK7, + BIT(16), 1); + + reset_nbi_csi = false; + } + + rtw8814a_spur_calibration_ch140(rtwdev, channel); + break; + default: + break; + } + } else if (rfe_type == 1 || rfe_type == 2) { + switch (bw) { + case RTW_CHANNEL_WIDTH_20: + if (channel == 153) { + rtw_write32_mask(rtwdev, REG_NBI_SETTING, + 0x000fe000, 0x1E >> 1); + rtw_write32_mask(rtwdev, REG_CSI_MASK_SETTING1, + BIT(0), 1); + rtw_write32(rtwdev, REG_CSI_FIX_MASK0, 0); + rtw_write32(rtwdev, REG_CSI_FIX_MASK1, 0); + rtw_write32(rtwdev, REG_CSI_FIX_MASK6, 0); + rtw_write32_mask(rtwdev, REG_CSI_FIX_MASK7, + BIT(16), 1); + + reset_nbi_csi = false; + } + break; + case RTW_CHANNEL_WIDTH_40: + if (channel == 151) { + rtw_write32_mask(rtwdev, REG_NBI_SETTING, + 0x000fe000, 0x1e >> 1); + rtw_write32_mask(rtwdev, REG_CSI_MASK_SETTING1, + BIT(0), 1); + rtw_write32_mask(rtwdev, REG_CSI_FIX_MASK0, + BIT(16), 1); + rtw_write32(rtwdev, REG_CSI_FIX_MASK1, 0); + rtw_write32(rtwdev, REG_CSI_FIX_MASK6, 0); + rtw_write32(rtwdev, REG_CSI_FIX_MASK7, 0); + + reset_nbi_csi = false; + } + break; + case RTW_CHANNEL_WIDTH_80: + if (channel == 155) { + rtw_write32_mask(rtwdev, REG_NBI_SETTING, + 0x000fe000, 0x5a >> 1); + rtw_write32_mask(rtwdev, REG_CSI_MASK_SETTING1, + BIT(0), 1); + rtw_write32(rtwdev, REG_CSI_FIX_MASK0, 0); + rtw_write32(rtwdev, REG_CSI_FIX_MASK1, 0); + rtw_write32_mask(rtwdev, REG_CSI_FIX_MASK6, + BIT(16), 1); + rtw_write32(rtwdev, REG_CSI_FIX_MASK7, 0); + + reset_nbi_csi = false; + } + break; + default: + break; + } + } + + if (reset_nbi_csi) { + rtw_write32_mask(rtwdev, REG_NBI_SETTING, + 0x000fe000, 0xfc >> 1); + rtw_write32_mask(rtwdev, REG_CSI_MASK_SETTING1, BIT(0), 0); + rtw_write32(rtwdev, REG_CSI_FIX_MASK0, 0); + rtw_write32(rtwdev, REG_CSI_FIX_MASK1, 0); + rtw_write32(rtwdev, REG_CSI_FIX_MASK6, 0); + rtw_write32(rtwdev, REG_CSI_FIX_MASK7, 0); + } + + rtw8814a_spur_nbi_setting(rtwdev); +} + +static void rtw8814a_set_bw_mode(struct rtw_dev *rtwdev, u8 new_band, + u8 channel, u8 bw, u8 primary_chan_idx) +{ + u8 txsc40 = 0, txsc20, txsc; + + rtw8814a_set_bw_reg_mac(rtwdev, bw); + + txsc20 = primary_chan_idx; + if (bw == RTW_CHANNEL_WIDTH_80) { + if (txsc20 == RTW_SC_20_UPPER || txsc20 == RTW_SC_20_UPMOST) + txsc40 = RTW_SC_40_UPPER; + else + txsc40 = RTW_SC_40_LOWER; + } + + txsc = BIT_TXSC_20M(txsc20) | BIT_TXSC_40M(txsc40); + rtw_write8(rtwdev, REG_DATA_SC, txsc); + + rtw8814a_set_bw_reg_adc(rtwdev, bw); + rtw8814a_set_bw_reg_agc(rtwdev, new_band, bw); + + if (bw == RTW_CHANNEL_WIDTH_80) { + rtw_write32_mask(rtwdev, REG_ADCCLK, 0x3c, txsc); + } else if (bw == RTW_CHANNEL_WIDTH_40) { + rtw_write32_mask(rtwdev, REG_ADCCLK, 0x3c, txsc); + + if (txsc == RTW_SC_20_UPPER) + rtw_write32_set(rtwdev, REG_RXSB, BIT(4)); + else + rtw_write32_clr(rtwdev, REG_RXSB, BIT(4)); + } + + rtw8814a_set_bw_rf(rtwdev, bw); + + rtw8814a_adc_clk(rtwdev); + + rtw8814a_spur_calibration(rtwdev, channel, bw); +} + +static void rtw8814a_set_channel(struct rtw_dev *rtwdev, u8 channel, u8 bw, + u8 primary_chan_idx) +{ + u8 old_band, new_band; + + if (rtw_read8(rtwdev, REG_CCK_CHECK) & BIT_CHECK_CCK_EN) + old_band = RTW_BAND_5G; + else + old_band = RTW_BAND_2G; + + if (channel > 14) + new_band = RTW_BAND_5G; + else + new_band = RTW_BAND_2G; + + if (new_band != old_band) + rtw8814a_switch_band(rtwdev, new_band, bw); + + rtw8814a_switch_channel(rtwdev, channel); + + rtw8814a_24g_cck_tx_dfir(rtwdev, channel); + + rtw8814a_set_bw_mode(rtwdev, new_band, channel, bw, primary_chan_idx); +} + +static s8 rtw8814a_cck_rx_pwr(u8 lna_idx, u8 vga_idx) +{ + s8 rx_pwr_all = 0; + + switch (lna_idx) { + case 7: + rx_pwr_all = -38 - 2 * vga_idx; + break; + case 5: + rx_pwr_all = -28 - 2 * vga_idx; + break; + case 3: + rx_pwr_all = -8 - 2 * vga_idx; + break; + case 2: + rx_pwr_all = -1 - 2 * vga_idx; + break; + default: + break; + } + + return rx_pwr_all; +} + +static void rtw8814a_query_phy_status(struct rtw_dev *rtwdev, u8 *phy_status, + struct rtw_rx_pkt_stat *pkt_stat) +{ + struct rtw_dm_info *dm_info = &rtwdev->dm_info; + struct rtw_jaguar_phy_status_rpt *rpt; + u8 gain[RTW_RF_PATH_MAX], rssi, i; + s8 rx_pwr_db, middle1, middle2; + s8 snr[RTW_RF_PATH_MAX]; + s8 evm[RTW_RF_PATH_MAX]; + u8 rfmode, subchannel; + u8 lna, vga; + s8 cfo[2]; + + rpt = (struct rtw_jaguar_phy_status_rpt *)phy_status; + + pkt_stat->bw = RTW_CHANNEL_WIDTH_20; + + if (pkt_stat->rate <= DESC_RATE11M) { + lna = le32_get_bits(rpt->w1, RTW_JGRPHY_W1_AGC_RPT_LNA_IDX); + vga = le32_get_bits(rpt->w1, RTW_JGRPHY_W1_AGC_RPT_VGA_IDX); + + rx_pwr_db = rtw8814a_cck_rx_pwr(lna, vga); + + pkt_stat->rx_power[RF_PATH_A] = rx_pwr_db; + pkt_stat->rssi = rtw_phy_rf_power_2_rssi(pkt_stat->rx_power, 1); + dm_info->rssi[RF_PATH_A] = pkt_stat->rssi; + pkt_stat->signal_power = rx_pwr_db; + } else { /* OFDM rate */ + gain[RF_PATH_A] = le32_get_bits(rpt->w0, RTW_JGRPHY_W0_GAIN_A); + gain[RF_PATH_B] = le32_get_bits(rpt->w0, RTW_JGRPHY_W0_GAIN_B); + gain[RF_PATH_C] = le32_get_bits(rpt->w5, RTW_JGRPHY_W5_GAIN_C); + gain[RF_PATH_D] = le32_get_bits(rpt->w6, RTW_JGRPHY_W6_GAIN_D); + + snr[RF_PATH_A] = le32_get_bits(rpt->w3, RTW_JGRPHY_W3_RXSNR_A); + snr[RF_PATH_B] = le32_get_bits(rpt->w4, RTW_JGRPHY_W4_RXSNR_B); + snr[RF_PATH_C] = le32_get_bits(rpt->w5, RTW_JGRPHY_W5_RXSNR_C); + snr[RF_PATH_D] = le32_get_bits(rpt->w5, RTW_JGRPHY_W5_RXSNR_D); + + evm[RF_PATH_A] = le32_get_bits(rpt->w3, RTW_JGRPHY_W3_RXEVM_1); + evm[RF_PATH_B] = le32_get_bits(rpt->w3, RTW_JGRPHY_W3_RXEVM_2); + evm[RF_PATH_C] = le32_get_bits(rpt->w4, RTW_JGRPHY_W4_RXEVM_3); + evm[RF_PATH_D] = le32_get_bits(rpt->w5, RTW_JGRPHY_W5_RXEVM_4); + + if (pkt_stat->rate <= DESC_RATE54M) + evm[RF_PATH_A] = le32_get_bits(rpt->w6, + RTW_JGRPHY_W6_SIGEVM); + + for (i = RF_PATH_A; i < RTW_RF_PATH_MAX; i++) { + pkt_stat->rx_power[i] = gain[i] - 110; + + rssi = rtw_phy_rf_power_2_rssi(&pkt_stat->rx_power[i], 1); + dm_info->rssi[i] = rssi; + + pkt_stat->rx_snr[i] = snr[i]; + dm_info->rx_snr[i] = snr[i] >> 1; + + pkt_stat->rx_evm[i] = evm[i]; + evm[i] = max_t(s8, -127, evm[i]); + dm_info->rx_evm_dbm[i] = abs(evm[i]) >> 1; + } + + rssi = rtw_phy_rf_power_2_rssi(pkt_stat->rx_power, + RTW_RF_PATH_MAX); + pkt_stat->rssi = rssi; + + /* When power saving is enabled the hardware sometimes + * reports unbelievably high gain for paths A and C + * (e.g. one frame 64 68 68 72, the next frame 106 66 88 72, + * the next 66 66 68 72), so use the second lowest gain + * instead of the highest. + */ + middle1 = max(min(gain[RF_PATH_A], gain[RF_PATH_B]), + min(gain[RF_PATH_C], gain[RF_PATH_D])); + middle2 = min(max(gain[RF_PATH_A], gain[RF_PATH_B]), + max(gain[RF_PATH_C], gain[RF_PATH_D])); + rx_pwr_db = min(middle1, middle2); + rx_pwr_db -= 110; + pkt_stat->signal_power = rx_pwr_db; + + rfmode = le32_get_bits(rpt->w0, RTW_JGRPHY_W0_R_RFMOD); + subchannel = le32_get_bits(rpt->w0, RTW_JGRPHY_W0_SUB_CHNL); + + if (rfmode == 1 && subchannel == 0) { + pkt_stat->bw = RTW_CHANNEL_WIDTH_40; + } else if (rfmode == 2) { + if (subchannel == 0) + pkt_stat->bw = RTW_CHANNEL_WIDTH_80; + else if (subchannel == 9 || subchannel == 10) + pkt_stat->bw = RTW_CHANNEL_WIDTH_40; + } + + cfo[RF_PATH_A] = le32_get_bits(rpt->w2, RTW_JGRPHY_W2_CFO_TAIL_A); + cfo[RF_PATH_B] = le32_get_bits(rpt->w2, RTW_JGRPHY_W2_CFO_TAIL_B); + + for (i = RF_PATH_A; i < 2; i++) { + pkt_stat->cfo_tail[i] = cfo[i]; + dm_info->cfo_tail[i] = (cfo[i] * 5) >> 1; + } + } +} + +static void +rtw8814a_set_tx_power_index_by_rate(struct rtw_dev *rtwdev, u8 path, u8 rs) +{ + struct rtw_hal *hal = &rtwdev->hal; + u32 txagc_table_wd; + u8 rate, pwr_index; + int j; + + for (j = 0; j < rtw_rate_size[rs]; j++) { + rate = rtw_rate_section[rs][j]; + + pwr_index = hal->tx_pwr_tbl[path][rate] + 2; + if (pwr_index > rtwdev->chip->max_power_index) + pwr_index = rtwdev->chip->max_power_index; + + txagc_table_wd = 0x00801000; + txagc_table_wd |= (pwr_index << 24) | (path << 8) | rate; + + rtw_write32(rtwdev, 0x1998, txagc_table_wd); + + /* first time to turn on the txagc table + * second to write the addr0 + */ + if (rate == DESC_RATE1M) + rtw_write32(rtwdev, 0x1998, txagc_table_wd); + } +} + +static void rtw8814a_set_tx_power_index(struct rtw_dev *rtwdev) +{ + struct rtw_hal *hal = &rtwdev->hal; + int path; + + for (path = 0; path < hal->rf_path_num; path++) { + if (hal->current_band_type == RTW_BAND_2G) + rtw8814a_set_tx_power_index_by_rate(rtwdev, path, + RTW_RATE_SECTION_CCK); + + rtw8814a_set_tx_power_index_by_rate(rtwdev, path, + RTW_RATE_SECTION_OFDM); + + if (test_bit(RTW_FLAG_SCANNING, rtwdev->flags)) + continue; + + rtw8814a_set_tx_power_index_by_rate(rtwdev, path, + RTW_RATE_SECTION_HT_1S); + rtw8814a_set_tx_power_index_by_rate(rtwdev, path, + RTW_RATE_SECTION_VHT_1S); + + rtw8814a_set_tx_power_index_by_rate(rtwdev, path, + RTW_RATE_SECTION_HT_2S); + rtw8814a_set_tx_power_index_by_rate(rtwdev, path, + RTW_RATE_SECTION_VHT_2S); + + rtw8814a_set_tx_power_index_by_rate(rtwdev, path, + RTW_RATE_SECTION_HT_3S); + rtw8814a_set_tx_power_index_by_rate(rtwdev, path, + RTW_RATE_SECTION_VHT_3S); + } +} + +static void rtw8814a_cfg_ldo25(struct rtw_dev *rtwdev, bool enable) +{ +} + +static void rtw8814a_false_alarm_statistics(struct rtw_dev *rtwdev) +{ + struct rtw_dm_info *dm_info = &rtwdev->dm_info; + u32 cck_fa_cnt, ofdm_fa_cnt; + u32 crc32_cnt, cca32_cnt; + u32 cck_enable; + + cck_enable = rtw_read32(rtwdev, REG_RXPSEL) & BIT(28); + cck_fa_cnt = rtw_read16(rtwdev, REG_FA_CCK); + ofdm_fa_cnt = rtw_read16(rtwdev, REG_FA_OFDM); + + dm_info->cck_fa_cnt = cck_fa_cnt; + dm_info->ofdm_fa_cnt = ofdm_fa_cnt; + dm_info->total_fa_cnt = ofdm_fa_cnt; + if (cck_enable) + dm_info->total_fa_cnt += cck_fa_cnt; + + crc32_cnt = rtw_read32(rtwdev, REG_CRC_CCK); + dm_info->cck_ok_cnt = u32_get_bits(crc32_cnt, MASKLWORD); + dm_info->cck_err_cnt = u32_get_bits(crc32_cnt, MASKHWORD); + + crc32_cnt = rtw_read32(rtwdev, REG_CRC_OFDM); + dm_info->ofdm_ok_cnt = u32_get_bits(crc32_cnt, MASKLWORD); + dm_info->ofdm_err_cnt = u32_get_bits(crc32_cnt, MASKHWORD); + + crc32_cnt = rtw_read32(rtwdev, REG_CRC_HT); + dm_info->ht_ok_cnt = u32_get_bits(crc32_cnt, MASKLWORD); + dm_info->ht_err_cnt = u32_get_bits(crc32_cnt, MASKHWORD); + + crc32_cnt = rtw_read32(rtwdev, REG_CRC_VHT); + dm_info->vht_ok_cnt = u32_get_bits(crc32_cnt, MASKLWORD); + dm_info->vht_err_cnt = u32_get_bits(crc32_cnt, MASKHWORD); + + cca32_cnt = rtw_read32(rtwdev, REG_CCA_OFDM); + dm_info->ofdm_cca_cnt = u32_get_bits(cca32_cnt, MASKHWORD); + dm_info->total_cca_cnt = dm_info->ofdm_cca_cnt; + if (cck_enable) { + cca32_cnt = rtw_read32(rtwdev, REG_CCA_CCK); + dm_info->cck_cca_cnt = u32_get_bits(cca32_cnt, MASKLWORD); + dm_info->total_cca_cnt += dm_info->cck_cca_cnt; + } + + rtw_write32_set(rtwdev, REG_FAS, BIT(17)); + rtw_write32_clr(rtwdev, REG_FAS, BIT(17)); + rtw_write32_clr(rtwdev, REG_CCK0_FAREPORT, BIT(15)); + rtw_write32_set(rtwdev, REG_CCK0_FAREPORT, BIT(15)); + rtw_write32_set(rtwdev, REG_CNTRST, BIT(0)); + rtw_write32_clr(rtwdev, REG_CNTRST, BIT(0)); +} + +#define MAC_REG_NUM_8814 2 +#define BB_REG_NUM_8814 14 +#define RF_REG_NUM_8814 1 + +static void rtw8814a_iqk_backup_mac_bb(struct rtw_dev *rtwdev, + u32 *mac_backup, u32 *bb_backup, + const u32 *mac_regs, + const u32 *bb_regs) +{ + u32 i; + + /* save MACBB default value */ + for (i = 0; i < MAC_REG_NUM_8814; i++) + mac_backup[i] = rtw_read32(rtwdev, mac_regs[i]); + + for (i = 0; i < BB_REG_NUM_8814; i++) + bb_backup[i] = rtw_read32(rtwdev, bb_regs[i]); +} + +static void rtw8814a_iqk_backup_rf(struct rtw_dev *rtwdev, + u32 rf_backup[][4], const u32 *rf_regs) +{ + u32 i; + + /* Save RF Parameters */ + for (i = 0; i < RF_REG_NUM_8814; i++) { + rf_backup[i][RF_PATH_A] = rtw_read_rf(rtwdev, RF_PATH_A, + rf_regs[i], RFREG_MASK); + rf_backup[i][RF_PATH_B] = rtw_read_rf(rtwdev, RF_PATH_B, + rf_regs[i], RFREG_MASK); + rf_backup[i][RF_PATH_C] = rtw_read_rf(rtwdev, RF_PATH_C, + rf_regs[i], RFREG_MASK); + rf_backup[i][RF_PATH_D] = rtw_read_rf(rtwdev, RF_PATH_D, + rf_regs[i], RFREG_MASK); + } +} + +static void rtw8814a_iqk_afe_setting(struct rtw_dev *rtwdev, bool do_iqk) +{ + if (do_iqk) { + /* IQK AFE setting RX_WAIT_CCA mode */ + rtw_write32(rtwdev, REG_AFE_PWR1_A, 0x0e808003); + rtw_write32(rtwdev, REG_AFE_PWR1_B, 0x0e808003); + rtw_write32(rtwdev, REG_AFE_PWR1_C, 0x0e808003); + rtw_write32(rtwdev, REG_AFE_PWR1_D, 0x0e808003); + } else { + rtw_write32(rtwdev, REG_AFE_PWR1_A, 0x07808003); + rtw_write32(rtwdev, REG_AFE_PWR1_B, 0x07808003); + rtw_write32(rtwdev, REG_AFE_PWR1_C, 0x07808003); + rtw_write32(rtwdev, REG_AFE_PWR1_D, 0x07808003); + } + + rtw_write32_mask(rtwdev, REG_DAC_RSTB, BIT(13), 0x1); + + rtw_write8_set(rtwdev, REG_GNT_BT, BIT(2) | BIT(1)); + rtw_write8_clr(rtwdev, REG_GNT_BT, BIT(2) | BIT(1)); + + rtw_write32_set(rtwdev, REG_CCK_RPT_FORMAT, BIT(2)); + rtw_write32_clr(rtwdev, REG_CCK_RPT_FORMAT, BIT(2)); +} + +static void rtw8814a_iqk_restore_mac_bb(struct rtw_dev *rtwdev, + u32 *mac_backup, u32 *bb_backup, + const u32 *mac_regs, + const u32 *bb_regs) +{ + u32 i; + + /* Reload MacBB Parameters */ + for (i = 0; i < MAC_REG_NUM_8814; i++) + rtw_write32(rtwdev, mac_regs[i], mac_backup[i]); + + for (i = 0; i < BB_REG_NUM_8814; i++) + rtw_write32(rtwdev, bb_regs[i], bb_backup[i]); +} + +static void rtw8814a_iqk_restore_rf(struct rtw_dev *rtwdev, + const u32 rf_backup[][4], + const u32 *rf_regs) +{ + u32 i; + + rtw_write_rf(rtwdev, RF_PATH_A, RF_LUTWE, RFREG_MASK, 0x0); + rtw_write_rf(rtwdev, RF_PATH_B, RF_LUTWE, RFREG_MASK, 0x0); + rtw_write_rf(rtwdev, RF_PATH_C, RF_LUTWE, RFREG_MASK, 0x0); + rtw_write_rf(rtwdev, RF_PATH_D, RF_LUTWE, RFREG_MASK, 0x0); + + rtw_write_rf(rtwdev, RF_PATH_A, RF_RXBB2, RFREG_MASK, 0x88001); + rtw_write_rf(rtwdev, RF_PATH_B, RF_RXBB2, RFREG_MASK, 0x88001); + rtw_write_rf(rtwdev, RF_PATH_C, RF_RXBB2, RFREG_MASK, 0x88001); + rtw_write_rf(rtwdev, RF_PATH_D, RF_RXBB2, RFREG_MASK, 0x88001); + + for (i = 0; i < RF_REG_NUM_8814; i++) { + rtw_write_rf(rtwdev, RF_PATH_A, rf_regs[i], + RFREG_MASK, rf_backup[i][RF_PATH_A]); + rtw_write_rf(rtwdev, RF_PATH_B, rf_regs[i], + RFREG_MASK, rf_backup[i][RF_PATH_B]); + rtw_write_rf(rtwdev, RF_PATH_C, rf_regs[i], + RFREG_MASK, rf_backup[i][RF_PATH_C]); + rtw_write_rf(rtwdev, RF_PATH_D, rf_regs[i], + RFREG_MASK, rf_backup[i][RF_PATH_D]); + } +} + +static void rtw8814a_iqk_reset_nctl(struct rtw_dev *rtwdev) +{ + rtw_write32(rtwdev, 0x1b00, 0xf8000000); + rtw_write32(rtwdev, 0x1b80, 0x00000006); + + rtw_write32(rtwdev, 0x1b00, 0xf8000000); + rtw_write32(rtwdev, 0x1b80, 0x00000002); +} + +static void rtw8814a_iqk_configure_mac(struct rtw_dev *rtwdev) +{ + rtw_write8(rtwdev, REG_TXPAUSE, 0x3f); + rtw_write32_clr(rtwdev, REG_BCN_CTRL, + (BIT_EN_BCN_FUNCTION << 8) | BIT_EN_BCN_FUNCTION); + + /* RX ante off */ + rtw_write8(rtwdev, REG_RXPSEL, 0x00); + /* CCA off */ + rtw_write32_mask(rtwdev, REG_CCA2ND, 0xf, 0xe); + /* CCK RX path off */ + rtw_write32_set(rtwdev, 0xa14, BIT(9) | BIT(8)); + rtw_write32(rtwdev, REG_RFE_PINMUX_A, 0x77777777); + rtw_write32(rtwdev, REG_RFE_PINMUX_B, 0x77777777); + rtw_write32(rtwdev, REG_RFE_PINMUX_C, 0x77777777); + rtw_write32(rtwdev, REG_RFE_PINMUX_D, 0x77777777); + rtw_write32_mask(rtwdev, 0x1abc, 0x0ff00000, 0x77); + rtw_write32_mask(rtwdev, 0x910, BIT(23) | BIT(22), 0x0); + + rtw_write32_mask(rtwdev, REG_RFE_INV0, 0xf, 0x0); +} + +static void rtw8814a_lok_one_shot(struct rtw_dev *rtwdev, u8 path) +{ + u32 lok_temp1, lok_temp2; + bool lok_ready; + u8 ii; + + /* ADC Clock source */ + rtw_write32_mask(rtwdev, REG_FAS, BIT(21) | BIT(20), path); + /* LOK: CMD ID = 0 + * {0xf8000011, 0xf8000021, 0xf8000041, 0xf8000081} + */ + rtw_write32(rtwdev, 0x1b00, 0xf8000001 | (BIT(path) << 4)); + + usleep_range(1000, 1100); + + if (read_poll_timeout(!rtw_read32_mask, lok_ready, lok_ready, + 1000, 10000, false, + rtwdev, 0x1b00, BIT(0))) { + rtw_dbg(rtwdev, RTW_DBG_RFK, "==>S%d LOK timed out\n", path); + + rtw8814a_iqk_reset_nctl(rtwdev); + + rtw_write_rf(rtwdev, path, RF_DTXLOK, RFREG_MASK, 0x08400); + + return; + } + + rtw_write32(rtwdev, 0x1b00, 0xf8000000 | (path << 1)); + rtw_write32(rtwdev, 0x1bd4, 0x003f0001); + + lok_temp2 = rtw_read32_mask(rtwdev, 0x1bfc, 0x003e0000); + lok_temp2 = (lok_temp2 + 0x10) & 0x1f; + + lok_temp1 = rtw_read32_mask(rtwdev, 0x1bfc, 0x0000003e); + lok_temp1 = (lok_temp1 + 0x10) & 0x1f; + + for (ii = 1; ii < 5; ii++) { + lok_temp1 += (lok_temp1 & BIT(4 - ii)) << (ii * 2); + lok_temp2 += (lok_temp2 & BIT(4 - ii)) << (ii * 2); + } + + rtw_dbg(rtwdev, RTW_DBG_RFK, + "path %d lok_temp1 = %#x, lok_temp2 = %#x\n", + path, lok_temp1 >> 4, lok_temp2 >> 4); + + rtw_write_rf(rtwdev, path, RF_DTXLOK, 0x07c00, lok_temp1 >> 4); + rtw_write_rf(rtwdev, path, RF_DTXLOK, 0xf8000, lok_temp2 >> 4); +} + +static void rtw8814a_iqk_tx_one_shot(struct rtw_dev *rtwdev, u8 path, + u32 *tx_matrix, bool *tx_ok) +{ + u8 bw = rtwdev->hal.current_band_width; + u8 cal_retry; + u32 iqk_cmd; + + for (cal_retry = 0; cal_retry < 4; cal_retry++) { + rtw_write32_mask(rtwdev, REG_FAS, BIT(21) | BIT(20), path); + + iqk_cmd = 0xf8000001 | ((bw + 3) << 8) | (BIT(path) << 4); + + rtw_dbg(rtwdev, RTW_DBG_RFK, "TXK_Trigger = %#x\n", iqk_cmd); + + rtw_write32(rtwdev, 0x1b00, iqk_cmd); + + msleep(10); + + if (read_poll_timeout(!rtw_read32_mask, *tx_ok, *tx_ok, + 1000, 20000, false, + rtwdev, 0x1b00, BIT(0))) { + rtw_dbg(rtwdev, RTW_DBG_RFK, + "tx iqk S%d timed out\n", path); + + rtw8814a_iqk_reset_nctl(rtwdev); + } else { + *tx_ok = !rtw_read32_mask(rtwdev, 0x1b08, BIT(26)); + + if (*tx_ok) + break; + } + } + + rtw_dbg(rtwdev, RTW_DBG_RFK, "S%d tx ==> 0x1b00 = 0x%x\n", + path, rtw_read32(rtwdev, 0x1b00)); + rtw_dbg(rtwdev, RTW_DBG_RFK, "S%d tx ==> 0x1b08 = 0x%x\n", + path, rtw_read32(rtwdev, 0x1b08)); + rtw_dbg(rtwdev, RTW_DBG_RFK, "S%d tx ==> cal_retry = %x\n", + path, cal_retry); + + rtw_write32(rtwdev, 0x1b00, 0xf8000000 | (path << 1)); + + if (*tx_ok) { + *tx_matrix = rtw_read32(rtwdev, 0x1b38); + + rtw_dbg(rtwdev, RTW_DBG_RFK, "S%d_IQC = 0x%x\n", + path, *tx_matrix); + } +} + +static void rtw8814a_iqk_rx_one_shot(struct rtw_dev *rtwdev, u8 path, + u32 *tx_matrix, bool *tx_ok) +{ + static const u16 iqk_apply[RTW_RF_PATH_MAX] = { + REG_TXAGCIDX, REG_TX_AGC_B, REG_TX_AGC_C, REG_TX_AGC_D + }; + u8 band = rtwdev->hal.current_band_type; + u8 bw = rtwdev->hal.current_band_width; + u32 rx_matrix; + u8 cal_retry; + u32 iqk_cmd; + bool rx_ok; + + for (cal_retry = 0; cal_retry < 4; cal_retry++) { + rtw_write32_mask(rtwdev, REG_FAS, BIT(21) | BIT(20), path); + + if (band == RTW_BAND_2G) { + rtw_write_rf(rtwdev, path, RF_LUTDBG, BIT(11), 0x1); + rtw_write_rf(rtwdev, path, RF_GAINTX, 0xfffff, 0x51ce1); + + switch (path) { + case 0: + case 1: + rtw_write32(rtwdev, REG_RFE_PINMUX_B, + 0x54775477); + break; + case 2: + rtw_write32(rtwdev, REG_RFE_PINMUX_C, + 0x54775477); + break; + case 3: + rtw_write32(rtwdev, 0x1abc, 0x75400000); + rtw_write32(rtwdev, REG_RFE_PINMUX_D, + 0x77777777); + break; + } + } + + iqk_cmd = 0xf8000001 | ((9 - bw) << 8) | (BIT(path) << 4); + + rtw_dbg(rtwdev, RTW_DBG_RFK, "RXK_Trigger = 0x%x\n", iqk_cmd); + + rtw_write32(rtwdev, 0x1b00, iqk_cmd); + + msleep(10); + + if (read_poll_timeout(!rtw_read32_mask, rx_ok, rx_ok, + 1000, 20000, false, + rtwdev, 0x1b00, BIT(0))) { + rtw_dbg(rtwdev, RTW_DBG_RFK, + "rx iqk S%d timed out\n", path); + + rtw8814a_iqk_reset_nctl(rtwdev); + } else { + rx_ok = !rtw_read32_mask(rtwdev, 0x1b08, BIT(26)); + + if (rx_ok) + break; + } + } + + rtw_dbg(rtwdev, RTW_DBG_RFK, "S%d rx ==> 0x1b00 = 0x%x\n", + path, rtw_read32(rtwdev, 0x1b00)); + rtw_dbg(rtwdev, RTW_DBG_RFK, "S%d rx ==> 0x1b08 = 0x%x\n", + path, rtw_read32(rtwdev, 0x1b08)); + rtw_dbg(rtwdev, RTW_DBG_RFK, "S%d rx ==> cal_retry = %x\n", + path, cal_retry); + + rtw_write32(rtwdev, 0x1b00, 0xf8000000 | (path << 1)); + + if (rx_ok) { + rtw_write32(rtwdev, 0x1b3c, 0x20000000); + rx_matrix = rtw_read32(rtwdev, 0x1b3c); + + rtw_dbg(rtwdev, RTW_DBG_RFK, "S%d_IQC = 0x%x\n", + path, rx_matrix); + } + + if (*tx_ok) + rtw_write32(rtwdev, 0x1b38, *tx_matrix); + else + rtw_write32_mask(rtwdev, iqk_apply[path], BIT(0), 0x0); + + if (!rx_ok) + rtw_write32_mask(rtwdev, iqk_apply[path], + BIT(11) | BIT(10), 0x0); + + if (band == RTW_BAND_2G) + rtw_write_rf(rtwdev, path, RF_LUTDBG, BIT(11), 0x0); +} + +static void rtw8814a_iqk(struct rtw_dev *rtwdev) +{ + u8 band = rtwdev->hal.current_band_type; + u8 bw = rtwdev->hal.current_band_width; + u32 tx_matrix[RTW_RF_PATH_MAX]; + bool tx_ok[RTW_RF_PATH_MAX]; + u8 path; + + rtw_dbg(rtwdev, RTW_DBG_RFK, "IQK band = %d GHz bw = %d MHz\n", + band == RTW_BAND_2G ? 2 : 5, (1 << (bw + 1)) * 10); + + rtw_write_rf(rtwdev, RF_PATH_A, RF_TXMOD, BIT(19), 0x1); + rtw_write_rf(rtwdev, RF_PATH_B, RF_TXMOD, BIT(19), 0x1); + rtw_write_rf(rtwdev, RF_PATH_C, RF_TXMOD, BIT(19), 0x1); + rtw_write_rf(rtwdev, RF_PATH_D, RF_TXMOD, BIT(19), 0x1); + + rtw_write32_mask(rtwdev, REG_TXAGCIDX, + (BIT(11) | BIT(10) | BIT(0)), 0x401); + rtw_write32_mask(rtwdev, REG_TX_AGC_B, + (BIT(11) | BIT(10) | BIT(0)), 0x401); + rtw_write32_mask(rtwdev, REG_TX_AGC_C, + (BIT(11) | BIT(10) | BIT(0)), 0x401); + rtw_write32_mask(rtwdev, REG_TX_AGC_D, + (BIT(11) | BIT(10) | BIT(0)), 0x401); + + if (band == RTW_BAND_5G) + rtw_write32(rtwdev, 0x1b00, 0xf8000ff1); + else + rtw_write32(rtwdev, 0x1b00, 0xf8000ef1); + + usleep_range(1000, 1100); + + rtw_write32(rtwdev, 0x810, 0x20101063); + rtw_write32(rtwdev, REG_DAC_RSTB, 0x0B00C000); + + for (path = RF_PATH_A; path < RTW_RF_PATH_MAX; path++) + rtw8814a_lok_one_shot(rtwdev, path); + + for (path = RF_PATH_A; path < RTW_RF_PATH_MAX; path++) + rtw8814a_iqk_tx_one_shot(rtwdev, path, + &tx_matrix[path], &tx_ok[path]); + + for (path = RF_PATH_A; path < RTW_RF_PATH_MAX; path++) + rtw8814a_iqk_rx_one_shot(rtwdev, path, + &tx_matrix[path], &tx_ok[path]); +} + +static void rtw8814a_do_iqk(struct rtw_dev *rtwdev) +{ + + static const u32 backup_mac_reg[MAC_REG_NUM_8814] = {0x520, 0x550}; + static const u32 backup_bb_reg[BB_REG_NUM_8814] = { + 0xa14, 0x808, 0x838, 0x90c, 0x810, 0xcb0, 0xeb0, + 0x18b4, 0x1ab4, 0x1abc, 0x9a4, 0x764, 0xcbc, 0x910 + }; + static const u32 backup_rf_reg[RF_REG_NUM_8814] = {0x0}; + u32 rf_backup[RF_REG_NUM_8814][RTW_RF_PATH_MAX]; + u32 mac_backup[MAC_REG_NUM_8814]; + u32 bb_backup[BB_REG_NUM_8814]; + + rtw8814a_iqk_backup_mac_bb(rtwdev, mac_backup, bb_backup, + backup_mac_reg, backup_bb_reg); + rtw8814a_iqk_afe_setting(rtwdev, true); + rtw8814a_iqk_backup_rf(rtwdev, rf_backup, backup_rf_reg); + rtw8814a_iqk_configure_mac(rtwdev); + rtw8814a_iqk(rtwdev); + rtw8814a_iqk_reset_nctl(rtwdev); /* for 3-wire to BB use */ + rtw8814a_iqk_afe_setting(rtwdev, false); + rtw8814a_iqk_restore_mac_bb(rtwdev, mac_backup, bb_backup, + backup_mac_reg, backup_bb_reg); + rtw8814a_iqk_restore_rf(rtwdev, rf_backup, backup_rf_reg); +} + +static void rtw8814a_phy_calibration(struct rtw_dev *rtwdev) +{ + rtw8814a_do_iqk(rtwdev); +} + +static void rtw8814a_coex_cfg_init(struct rtw_dev *rtwdev) +{ +} + +static void rtw8814a_coex_cfg_gnt_fix(struct rtw_dev *rtwdev) +{ +} + +static void rtw8814a_coex_cfg_gnt_debug(struct rtw_dev *rtwdev) +{ +} + +static void rtw8814a_coex_cfg_rfe_type(struct rtw_dev *rtwdev) +{ +} + +static void rtw8814a_coex_cfg_wl_tx_power(struct rtw_dev *rtwdev, u8 wl_pwr) +{ +} + +static void rtw8814a_coex_cfg_wl_rx_gain(struct rtw_dev *rtwdev, bool low_gain) +{ +} + +static void rtw8814a_txagc_swing_offset(struct rtw_dev *rtwdev, u8 path, + u8 tx_pwr_idx_offset, + s8 *txagc_idx, u8 *swing_idx) +{ + struct rtw_dm_info *dm_info = &rtwdev->dm_info; + u8 swing_upper_bound = dm_info->default_ofdm_index + 10; + s8 delta_pwr_idx = dm_info->delta_power_index[path]; + u8 swing_index = dm_info->default_ofdm_index; + u8 max_tx_pwr_idx_offset = 0xf; + u8 swing_lower_bound = 0; + s8 agc_index = 0; + + tx_pwr_idx_offset = min_t(u8, tx_pwr_idx_offset, max_tx_pwr_idx_offset); + + if (delta_pwr_idx >= 0) { + if (delta_pwr_idx <= tx_pwr_idx_offset) { + agc_index = delta_pwr_idx; + swing_index = dm_info->default_ofdm_index; + } else if (delta_pwr_idx > tx_pwr_idx_offset) { + agc_index = tx_pwr_idx_offset; + swing_index = dm_info->default_ofdm_index + + delta_pwr_idx - tx_pwr_idx_offset; + swing_index = min_t(u8, swing_index, swing_upper_bound); + } + } else { + if (dm_info->default_ofdm_index > abs(delta_pwr_idx)) + swing_index = + dm_info->default_ofdm_index + delta_pwr_idx; + else + swing_index = swing_lower_bound; + swing_index = max_t(u8, swing_index, swing_lower_bound); + + agc_index = 0; + } + + if (swing_index >= RTW_TXSCALE_SIZE) { + rtw_warn(rtwdev, "swing index overflow\n"); + swing_index = RTW_TXSCALE_SIZE - 1; + } + *txagc_idx = agc_index; + *swing_idx = swing_index; +} + +static void rtw8814a_pwrtrack_set_pwr(struct rtw_dev *rtwdev, u8 path, + u8 pwr_idx_offset) +{ + static const u32 txagc_reg[RTW_RF_PATH_MAX] = { + REG_TX_AGC_A, REG_TX_AGC_B, REG_TX_AGC_C, REG_TX_AGC_D + }; + static const u32 txscale_reg[RTW_RF_PATH_MAX] = { + REG_TXSCALE_A, REG_TXSCALE_B, REG_TXSCALE_C, REG_TXSCALE_D + }; + s8 txagc_idx; + u8 swing_idx; + + rtw8814a_txagc_swing_offset(rtwdev, path, pwr_idx_offset, + &txagc_idx, &swing_idx); + rtw_write32_mask(rtwdev, txagc_reg[path], GENMASK(29, 25), + txagc_idx); + rtw_write32_mask(rtwdev, txscale_reg[path], BB_SWING_MASK, + rtw8814a_txscale_tbl[swing_idx]); +} + +static void rtw8814a_pwrtrack_set(struct rtw_dev *rtwdev, u8 path) +{ + u8 max_pwr_idx = rtwdev->chip->max_power_index; + u8 band_width = rtwdev->hal.current_band_width; + u8 channel = rtwdev->hal.current_channel; + u8 tx_rate = rtwdev->dm_info.tx_rate; + u8 regd = rtw_regd_get(rtwdev); + u8 pwr_idx_offset, tx_pwr_idx; + + tx_pwr_idx = rtw_phy_get_tx_power_index(rtwdev, path, tx_rate, + band_width, channel, regd); + + tx_pwr_idx = min_t(u8, tx_pwr_idx, max_pwr_idx); + + pwr_idx_offset = max_pwr_idx - tx_pwr_idx; + + rtw8814a_pwrtrack_set_pwr(rtwdev, path, pwr_idx_offset); +} + +static void rtw8814a_phy_pwrtrack_path(struct rtw_dev *rtwdev, + struct rtw_swing_table *swing_table, + u8 path) +{ + struct rtw_dm_info *dm_info = &rtwdev->dm_info; + u8 power_idx_cur, power_idx_last; + u8 delta; + + /* 8814A only has one thermal meter at PATH A */ + delta = rtw_phy_pwrtrack_get_delta(rtwdev, RF_PATH_A); + + power_idx_last = dm_info->delta_power_index[path]; + power_idx_cur = rtw_phy_pwrtrack_get_pwridx(rtwdev, swing_table, + path, RF_PATH_A, delta); + + /* if delta of power indexes are the same, just skip */ + if (power_idx_cur == power_idx_last) + return; + + dm_info->delta_power_index[path] = power_idx_cur; + rtw8814a_pwrtrack_set(rtwdev, path); +} + +static void rtw8814a_phy_pwrtrack(struct rtw_dev *rtwdev) +{ + struct rtw_dm_info *dm_info = &rtwdev->dm_info; + struct rtw_swing_table swing_table; + u8 thermal_value, path; + + rtw_phy_config_swing_table(rtwdev, &swing_table); + + if (rtwdev->efuse.thermal_meter[RF_PATH_A] == 0xff) + return; + + thermal_value = rtw_read_rf(rtwdev, RF_PATH_A, RF_T_METER, 0xfc00); + + rtw_phy_pwrtrack_avg(rtwdev, thermal_value, RF_PATH_A); + + if (dm_info->pwr_trk_init_trigger) + dm_info->pwr_trk_init_trigger = false; + else if (!rtw_phy_pwrtrack_thermal_changed(rtwdev, thermal_value, + RF_PATH_A)) + goto iqk; + + for (path = RF_PATH_A; path < rtwdev->hal.rf_path_num; path++) + rtw8814a_phy_pwrtrack_path(rtwdev, &swing_table, path); + +iqk: + if (rtw_phy_pwrtrack_need_iqk(rtwdev)) + rtw8814a_do_iqk(rtwdev); +} + +static void rtw8814a_pwr_track(struct rtw_dev *rtwdev) +{ + struct rtw_dm_info *dm_info = &rtwdev->dm_info; + + if (!dm_info->pwr_trk_triggered) { + rtw_write_rf(rtwdev, RF_PATH_A, RF_T_METER, + GENMASK(17, 16), 0x03); + dm_info->pwr_trk_triggered = true; + return; + } + + rtw8814a_phy_pwrtrack(rtwdev); + dm_info->pwr_trk_triggered = false; +} + +static void rtw8814a_phy_cck_pd_set(struct rtw_dev *rtwdev, u8 new_lvl) +{ + static const u8 pd[CCK_PD_LV_MAX] = {0x40, 0x83, 0xcd, 0xdd, 0xed}; + struct rtw_dm_info *dm_info = &rtwdev->dm_info; + + /* Override rtw_phy_cck_pd_lv_link(). It implements something + * like type 2/3/4. We need type 1 here. + */ + if (rtw_is_assoc(rtwdev)) { + if (dm_info->min_rssi > 60) { + new_lvl = CCK_PD_LV3; + } else if (dm_info->min_rssi > 35) { + new_lvl = CCK_PD_LV2; + } else if (dm_info->min_rssi > 20) { + if (dm_info->cck_fa_avg > 500) + new_lvl = CCK_PD_LV2; + else if (dm_info->cck_fa_avg < 250) + new_lvl = CCK_PD_LV1; + else + return; + } else { + new_lvl = CCK_PD_LV1; + } + } + + rtw_dbg(rtwdev, RTW_DBG_PHY, "lv: (%d) -> (%d)\n", + dm_info->cck_pd_lv[RTW_CHANNEL_WIDTH_20][RF_PATH_A], new_lvl); + + if (dm_info->cck_pd_lv[RTW_CHANNEL_WIDTH_20][RF_PATH_A] == new_lvl) + return; + + dm_info->cck_fa_avg = CCK_FA_AVG_RESET; + dm_info->cck_pd_lv[RTW_CHANNEL_WIDTH_20][RF_PATH_A] = new_lvl; + + rtw_write8(rtwdev, REG_CCK_PD_TH, pd[new_lvl]); +} + +#ifdef CONFIG_LEDS_CLASS + +static void rtw8814a_led_set(struct led_classdev *led, + enum led_brightness brightness) +{ + struct rtw_dev *rtwdev = container_of(led, struct rtw_dev, led_cdev); + u32 led_gpio_cfg; + + led_gpio_cfg = rtw_read32(rtwdev, REG_GPIO_PIN_CTRL_2); + led_gpio_cfg |= BIT(16) | BIT(17) | BIT(21) | BIT(22); + + if (brightness == LED_OFF) { + led_gpio_cfg |= BIT(8) | BIT(9) | BIT(13) | BIT(14); + } else { + led_gpio_cfg &= ~(BIT(8) | BIT(9) | BIT(13) | BIT(14)); + led_gpio_cfg &= ~(BIT(0) | BIT(1) | BIT(5) | BIT(6)); + } + + rtw_write32(rtwdev, REG_GPIO_PIN_CTRL_2, led_gpio_cfg); +} + +#endif + +static void rtw8814a_fill_txdesc_checksum(struct rtw_dev *rtwdev, + struct rtw_tx_pkt_info *pkt_info, + u8 *txdesc) +{ + size_t words = 32 / 2; /* calculate the first 32 bytes (16 words) */ + + fill_txdesc_checksum_common(txdesc, words); +} + +static const struct rtw_hw_reg rtw8814a_dig[] = { + [0] = { .addr = 0xc50, .mask = 0x7f }, + [1] = { .addr = 0xe50, .mask = 0x7f }, + [2] = { .addr = 0x1850, .mask = 0x7f }, + [3] = { .addr = 0x1a50, .mask = 0x7f }, +}; + +static const struct rtw_page_table page_table_8814a[] = { + /* SDIO */ + {0, 0, 0, 0, 0}, /* hq nq lq exq gapq */ + /* PCIE */ + {32, 32, 32, 32, 0}, + /* USB, 2 bulk out */ + {32, 32, 32, 32, 0}, + /* USB, 3 bulk out */ + {32, 32, 32, 32, 0}, + /* USB, 4 bulk out */ + {32, 32, 32, 32, 0}, +}; + +static const struct rtw_rqpn rqpn_table_8814a[] = { + /* SDIO */ + {RTW_DMA_MAPPING_NORMAL, RTW_DMA_MAPPING_NORMAL, /* vo vi */ + RTW_DMA_MAPPING_LOW, RTW_DMA_MAPPING_LOW, /* be bk */ + RTW_DMA_MAPPING_EXTRA, RTW_DMA_MAPPING_HIGH}, /* mg hi */ + /* PCIE */ + {RTW_DMA_MAPPING_HIGH, RTW_DMA_MAPPING_NORMAL, + RTW_DMA_MAPPING_LOW, RTW_DMA_MAPPING_LOW, + RTW_DMA_MAPPING_EXTRA, RTW_DMA_MAPPING_HIGH}, + /* USB, 2 bulk out */ + {RTW_DMA_MAPPING_HIGH, RTW_DMA_MAPPING_HIGH, + RTW_DMA_MAPPING_NORMAL, RTW_DMA_MAPPING_NORMAL, + RTW_DMA_MAPPING_HIGH, RTW_DMA_MAPPING_HIGH}, + /* USB, 3 bulk out */ + {RTW_DMA_MAPPING_HIGH, RTW_DMA_MAPPING_NORMAL, + RTW_DMA_MAPPING_LOW, RTW_DMA_MAPPING_LOW, + RTW_DMA_MAPPING_HIGH, RTW_DMA_MAPPING_HIGH}, + /* USB, 4 bulk out */ + {RTW_DMA_MAPPING_HIGH, RTW_DMA_MAPPING_NORMAL, + RTW_DMA_MAPPING_LOW, RTW_DMA_MAPPING_LOW, + RTW_DMA_MAPPING_HIGH, RTW_DMA_MAPPING_HIGH}, +}; + +static const struct rtw_prioq_addrs prioq_addrs_8814a = { + .prio[RTW_DMA_MAPPING_EXTRA] = { + .rsvd = REG_FIFOPAGE_INFO_4, .avail = REG_FIFOPAGE_INFO_4 + 2, + }, + .prio[RTW_DMA_MAPPING_LOW] = { + .rsvd = REG_FIFOPAGE_INFO_2, .avail = REG_FIFOPAGE_INFO_2 + 2, + }, + .prio[RTW_DMA_MAPPING_NORMAL] = { + .rsvd = REG_FIFOPAGE_INFO_3, .avail = REG_FIFOPAGE_INFO_3 + 2, + }, + .prio[RTW_DMA_MAPPING_HIGH] = { + .rsvd = REG_FIFOPAGE_INFO_1, .avail = REG_FIFOPAGE_INFO_1 + 2, + }, + .wsize = true, +}; + +static const struct rtw_chip_ops rtw8814a_ops = { + .power_on = rtw_power_on, + .power_off = rtw_power_off, + .phy_set_param = rtw8814a_phy_set_param, + .read_efuse = rtw8814a_read_efuse, + .query_phy_status = rtw8814a_query_phy_status, + .set_channel = rtw8814a_set_channel, + .mac_init = rtw8814a_mac_init, + .read_rf = rtw_phy_read_rf, + .write_rf = rtw_phy_write_rf_reg_sipi, + .set_tx_power_index = rtw8814a_set_tx_power_index, + .set_antenna = NULL, + .cfg_ldo25 = rtw8814a_cfg_ldo25, + .efuse_grant = rtw8814a_efuse_grant, + .false_alarm_statistics = rtw8814a_false_alarm_statistics, + .phy_calibration = rtw8814a_phy_calibration, + .cck_pd_set = rtw8814a_phy_cck_pd_set, + .pwr_track = rtw8814a_pwr_track, + .config_bfee = NULL, + .set_gid_table = NULL, + .cfg_csi_rate = NULL, +#ifdef CONFIG_LEDS_CLASS + .led_set = rtw8814a_led_set, +#endif + .fill_txdesc_checksum = rtw8814a_fill_txdesc_checksum, + + .coex_set_init = rtw8814a_coex_cfg_init, + .coex_set_ant_switch = NULL, + .coex_set_gnt_fix = rtw8814a_coex_cfg_gnt_fix, + .coex_set_gnt_debug = rtw8814a_coex_cfg_gnt_debug, + .coex_set_rfe_type = rtw8814a_coex_cfg_rfe_type, + .coex_set_wl_tx_power = rtw8814a_coex_cfg_wl_tx_power, + .coex_set_wl_rx_gain = rtw8814a_coex_cfg_wl_rx_gain, +}; + +/* rssi in percentage % (dbm = % - 100) */ +static const u8 wl_rssi_step_8814a[] = {60, 50, 44, 30}; +static const u8 bt_rssi_step_8814a[] = {30, 30, 30, 30}; + +/* wl_tx_dec_power, bt_tx_dec_power, wl_rx_gain, bt_rx_lna_constrain */ +static const struct coex_rf_para rf_para_tx_8814a[] = { + {0, 0, false, 7}, /* for normal */ + {0, 16, false, 7}, /* for WL-CPT */ + {4, 0, true, 1}, + {3, 6, true, 1}, + {2, 9, true, 1}, + {1, 13, true, 1} +}; + +static const struct coex_rf_para rf_para_rx_8814a[] = { + {0, 0, false, 7}, /* for normal */ + {0, 16, false, 7}, /* for WL-CPT */ + {4, 0, true, 1}, + {3, 6, true, 1}, + {2, 9, true, 1}, + {1, 13, true, 1} +}; + +static_assert(ARRAY_SIZE(rf_para_tx_8814a) == ARRAY_SIZE(rf_para_rx_8814a)); + +static const struct rtw_rfe_def rtw8814a_rfe_defs[] = { + [1] = { .phy_pg_tbl = &rtw8814a_bb_pg_tbl, + .txpwr_lmt_tbl = &rtw8814a_txpwr_lmt_type1_tbl, + .pwr_track_tbl = &rtw8814a_rtw_pwrtrk_tbl }, +}; + +const struct rtw_chip_info rtw8814a_hw_spec = { + .ops = &rtw8814a_ops, + .id = RTW_CHIP_TYPE_8814A, + .fw_name = "rtw88/rtw8814a_fw.bin", + .wlan_cpu = RTW_WCPU_11AC, + .tx_pkt_desc_sz = 40, + .tx_buf_desc_sz = 16, + .rx_pkt_desc_sz = 24, + .rx_buf_desc_sz = 8, + .phy_efuse_size = 1024, + .log_efuse_size = 512, + .ptct_efuse_size = 0, + .txff_size = (2048 - 10) * TX_PAGE_SIZE, + .rxff_size = 23552, + .rsvd_drv_pg_num = 8, + .band = RTW_BAND_2G | RTW_BAND_5G, + .page_size = TX_PAGE_SIZE, + .csi_buf_pg_num = 0, + .dig_min = 0x1c, + .txgi_factor = 1, + .is_pwr_by_rate_dec = true, + .rx_ldpc = true, + .max_power_index = 0x3f, + .ampdu_density = IEEE80211_HT_MPDU_DENSITY_2, + .usb_tx_agg_desc_num = 3, + .hw_feature_report = false, + .c2h_ra_report_size = 6, + .old_datarate_fb_limit = false, + .tx_report_sn = true, + .ht_supported = true, + .vht_supported = true, + .lps_deep_mode_supported = 0, + .sys_func_en = 0xDC, + .pwr_on_seq = card_enable_flow_8814a, + .pwr_off_seq = card_disable_flow_8814a, + .rqpn_table = rqpn_table_8814a, + .prioq_addrs = &prioq_addrs_8814a, + .page_table = page_table_8814a, + .intf_table = NULL, + .dig = rtw8814a_dig, + .dig_cck = NULL, + .rf_base_addr = {0x2800, 0x2c00, 0x3800, 0x3c00}, + .rf_sipi_addr = {0xc90, 0xe90, 0x1890, 0x1a90}, + .ltecoex_addr = NULL, + .mac_tbl = &rtw8814a_mac_tbl, + .agc_tbl = &rtw8814a_agc_tbl, + .bb_tbl = &rtw8814a_bb_tbl, + .rf_tbl = {&rtw8814a_rf_a_tbl, &rtw8814a_rf_b_tbl, + &rtw8814a_rf_c_tbl, &rtw8814a_rf_d_tbl}, + .rfe_defs = rtw8814a_rfe_defs, + .rfe_defs_size = ARRAY_SIZE(rtw8814a_rfe_defs), + .iqk_threshold = 8, + .max_scan_ie_len = IEEE80211_MAX_DATA_LEN, + + .coex_para_ver = 0, + .bt_desired_ver = 0, + .scbd_support = false, + .new_scbd10_def = false, + .ble_hid_profile_support = false, + .wl_mimo_ps_support = false, + .pstdma_type = COEX_PSTDMA_FORCE_LPSOFF, + .bt_rssi_type = COEX_BTRSSI_RATIO, + .ant_isolation = 15, + .rssi_tolerance = 2, + .wl_rssi_step = wl_rssi_step_8814a, + .bt_rssi_step = bt_rssi_step_8814a, + .table_sant_num = 0, + .table_sant = NULL, + .table_nsant_num = 0, + .table_nsant = NULL, + .tdma_sant_num = 0, + .tdma_sant = NULL, + .tdma_nsant_num = 0, + .tdma_nsant = NULL, + .wl_rf_para_num = ARRAY_SIZE(rf_para_tx_8814a), + .wl_rf_para_tx = rf_para_tx_8814a, + .wl_rf_para_rx = rf_para_rx_8814a, + .bt_afh_span_bw20 = 0x24, + .bt_afh_span_bw40 = 0x36, + .afh_5g_num = 0, + .afh_5g = NULL, + .coex_info_hw_regs_num = 0, + .coex_info_hw_regs = NULL, +}; +EXPORT_SYMBOL(rtw8814a_hw_spec); + +MODULE_FIRMWARE("rtw88/rtw8814a_fw.bin"); + +MODULE_AUTHOR("Realtek Corporation"); +MODULE_DESCRIPTION("Realtek 802.11ac wireless 8814a driver"); +MODULE_LICENSE("Dual BSD/GPL"); diff --git a/rtw8814a.h b/rtw8814a.h new file mode 100644 index 00000000..f0ccb332 --- /dev/null +++ b/rtw8814a.h @@ -0,0 +1,64 @@ +/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */ +/* Copyright(c) 2025 Realtek Corporation + */ + +#ifndef __RTW8814A_H__ +#define __RTW8814A_H__ + +#define RF_RCK1 0x1c + +struct rtw8814au_efuse { + u8 vid[2]; /* 0xd0 */ + u8 pid[2]; /* 0xd2 */ + u8 res[4]; /* 0xd0 */ + u8 mac_addr[ETH_ALEN]; /* 0xd8 */ +} __packed; + +struct rtw8814ae_efuse { + u8 mac_addr[ETH_ALEN]; /* 0xd0 */ + u8 vid[2]; /* 0xd6 */ + u8 did[2]; /* 0xd8 */ + u8 svid[2]; /* 0xda */ + u8 smid[2]; /* 0xdc */ +} __packed; + +struct rtw8814a_efuse { + __le16 rtl_id; + u8 res0[0x0c]; + u8 usb_mode; /* 0x0e */ + u8 res1; + + /* power index for four RF paths */ + struct rtw_txpwr_idx txpwr_idx_table[4]; + + u8 channel_plan; /* 0xb8 */ + u8 xtal_k; /* 0xb9 */ + u8 thermal_meter; /* 0xba */ + u8 iqk_lck; /* 0xbb */ + u8 pa_type; /* 0xbc */ + u8 lna_type_2g[2]; /* 0xbd */ + u8 lna_type_5g[2]; /* 0xbf */ + u8 rf_board_option; /* 0xc1 */ + u8 res2; + u8 rf_bt_setting; /* 0xc3 */ + u8 eeprom_version; /* 0xc4 */ + u8 eeprom_customer_id; /* 0xc5 */ + u8 tx_bb_swing_setting_2g; /* 0xc6 */ + u8 tx_bb_swing_setting_5g; /* 0xc7 */ + u8 res3; + u8 trx_antenna_option; /* 0xc9 */ + u8 rfe_option; /* 0xca */ + u8 country_code[2]; /* 0xcb */ + u8 res4[3]; + union { + struct rtw8814au_efuse u; + struct rtw8814ae_efuse e; + }; + u8 res5[0x122]; /* 0xde */ +} __packed; + +static_assert(sizeof(struct rtw8814a_efuse) == 512); + +extern const struct rtw_chip_info rtw8814a_hw_spec; + +#endif From d878d4bf744d26a7c3a9cb48bf3f0172b5f8f502 Mon Sep 17 00:00:00 2001 From: Bitterblue Smith Date: Sun, 17 Nov 2024 21:13:55 +0200 Subject: [PATCH 097/193] wifi: rtw88: Add rtw8814au.c This is the entry point for the new module rtw88_8814au. Signed-off-by: Bitterblue Smith --- rtw8814au.c | 54 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 54 insertions(+) create mode 100644 rtw8814au.c diff --git a/rtw8814au.c b/rtw8814au.c new file mode 100644 index 00000000..afe045fb --- /dev/null +++ b/rtw8814au.c @@ -0,0 +1,54 @@ +// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause +/* Copyright(c) 2025 Realtek Corporation + */ + +#include +#include +#include "main.h" +#include "rtw8814a.h" +#include "usb.h" + +static const struct usb_device_id rtw_8814au_id_table[] = { + { USB_DEVICE_AND_INTERFACE_INFO(RTW_USB_VENDOR_ID_REALTEK, 0x8813, 0xff, 0xff, 0xff), + .driver_info = (kernel_ulong_t)&(rtw8814a_hw_spec) }, + { USB_DEVICE_AND_INTERFACE_INFO(0x056e, 0x400b, 0xff, 0xff, 0xff), + .driver_info = (kernel_ulong_t)&(rtw8814a_hw_spec) }, + { USB_DEVICE_AND_INTERFACE_INFO(0x056e, 0x400d, 0xff, 0xff, 0xff), + .driver_info = (kernel_ulong_t)&(rtw8814a_hw_spec) }, + { USB_DEVICE_AND_INTERFACE_INFO(0x0846, 0x9054, 0xff, 0xff, 0xff), + .driver_info = (kernel_ulong_t)&(rtw8814a_hw_spec) }, + { USB_DEVICE_AND_INTERFACE_INFO(0x0b05, 0x1817, 0xff, 0xff, 0xff), + .driver_info = (kernel_ulong_t)&(rtw8814a_hw_spec) }, + { USB_DEVICE_AND_INTERFACE_INFO(0x0b05, 0x1852, 0xff, 0xff, 0xff), + .driver_info = (kernel_ulong_t)&(rtw8814a_hw_spec) }, + { USB_DEVICE_AND_INTERFACE_INFO(0x0b05, 0x1853, 0xff, 0xff, 0xff), + .driver_info = (kernel_ulong_t)&(rtw8814a_hw_spec) }, + { USB_DEVICE_AND_INTERFACE_INFO(0x0e66, 0x0026, 0xff, 0xff, 0xff), + .driver_info = (kernel_ulong_t)&(rtw8814a_hw_spec) }, + { USB_DEVICE_AND_INTERFACE_INFO(0x2001, 0x331a, 0xff, 0xff, 0xff), + .driver_info = (kernel_ulong_t)&(rtw8814a_hw_spec) }, + { USB_DEVICE_AND_INTERFACE_INFO(0x20f4, 0x809a, 0xff, 0xff, 0xff), + .driver_info = (kernel_ulong_t)&(rtw8814a_hw_spec) }, + { USB_DEVICE_AND_INTERFACE_INFO(0x20f4, 0x809b, 0xff, 0xff, 0xff), + .driver_info = (kernel_ulong_t)&(rtw8814a_hw_spec) }, + { USB_DEVICE_AND_INTERFACE_INFO(0x2357, 0x0106, 0xff, 0xff, 0xff), + .driver_info = (kernel_ulong_t)&(rtw8814a_hw_spec) }, + { USB_DEVICE_AND_INTERFACE_INFO(0x7392, 0xa834, 0xff, 0xff, 0xff), + .driver_info = (kernel_ulong_t)&(rtw8814a_hw_spec) }, + { USB_DEVICE_AND_INTERFACE_INFO(0x7392, 0xa833, 0xff, 0xff, 0xff), + .driver_info = (kernel_ulong_t)&(rtw8814a_hw_spec) }, + {}, +}; +MODULE_DEVICE_TABLE(usb, rtw_8814au_id_table); + +static struct usb_driver rtw_8814au_driver = { + .name = "rtw_8814au", + .id_table = rtw_8814au_id_table, + .probe = rtw_usb_probe, + .disconnect = rtw_usb_disconnect, +}; +module_usb_driver(rtw_8814au_driver); + +MODULE_AUTHOR("Bitterblue Smith "); +MODULE_DESCRIPTION("Realtek 802.11ac wireless 8814au driver"); +MODULE_LICENSE("Dual BSD/GPL"); From 2df73c8f05cd4b63a547c66d0df6f812c3c52ed8 Mon Sep 17 00:00:00 2001 From: Bitterblue Smith Date: Mon, 9 Dec 2024 21:15:10 +0200 Subject: [PATCH 098/193] wifi: rtw88: usb: Enable RX aggregation for RTL8814AU Let the chip transfer several frames in a single USB Request Block. This is supposed to improve the RX speed. It can use the same code used for RTL8822CU, RTL8822BU, and RTL8821CU. Signed-off-by: Bitterblue Smith --- usb.c | 1 + 1 file changed, 1 insertion(+) diff --git a/usb.c b/usb.c index 046073d8..323423e0 100644 --- a/usb.c +++ b/usb.c @@ -882,6 +882,7 @@ static void rtw_usb_dynamic_rx_agg(struct rtw_dev *rtwdev, bool enable) case RTW_CHIP_TYPE_8822C: case RTW_CHIP_TYPE_8822B: case RTW_CHIP_TYPE_8821C: + case RTW_CHIP_TYPE_8814A: rtw_usb_dynamic_rx_agg_v1(rtwdev, enable); break; case RTW_CHIP_TYPE_8821A: From 3b3e18da69a9d55f33ddd77083a8c49c0da47272 Mon Sep 17 00:00:00 2001 From: Bitterblue Smith Date: Fri, 29 Nov 2024 22:53:45 +0200 Subject: [PATCH 099/193] wifi: rtw88: usb: Enable switching the RTL8814AU to USB 3 The Realtek wifi 5 devices which support USB 3 are weird: when first plugged in, they pretend to be USB 2. The driver needs to send some commands to the device, which make it disappear and come back as a USB 3 device. The method used to switch the RTL8812AU also works for the RTL8814AU. Signed-off-by: Bitterblue Smith --- usb.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/usb.c b/usb.c index 323423e0..92f4c064 100644 --- a/usb.c +++ b/usb.c @@ -1125,7 +1125,8 @@ static int rtw_usb_switch_mode_new(struct rtw_dev *rtwdev) static bool rtw_usb3_chip_old(u8 chip_id) { - return chip_id == RTW_CHIP_TYPE_8812A; + return chip_id == RTW_CHIP_TYPE_8812A || + chip_id == RTW_CHIP_TYPE_8814A; } static bool rtw_usb3_chip_new(u8 chip_id) From d47126fc5e7ab6e30bf0199b9736820319359579 Mon Sep 17 00:00:00 2001 From: Bitterblue Smith Date: Fri, 20 Dec 2024 02:08:17 +0200 Subject: [PATCH 100/193] wifi: rtw88: Set AMPDU factor to hardware Tell the chip the maximum AMPDU size supported by the AP. This greatly improves the TX speed of RTL8814AU in the 2.4 GHz band. Before: ~90 Mbps. After: ~300 Mbps. Add this configuration for all the chips, even if it only has an effect on RTL8814AU in my tests. Surely they all need this. Signed-off-by: Bitterblue Smith --- mac80211.c | 2 ++ main.c | 40 ++++++++++++++++++++++++++++++++++++++++ main.h | 3 +++ rtw8703b.c | 1 + rtw8723d.c | 1 + rtw8723x.c | 8 ++++++++ rtw8723x.h | 6 ++++++ rtw8812a.c | 11 +++++++++++ rtw8814a.c | 8 ++++++++ rtw8821a.c | 11 +++++++++++ rtw8821c.c | 6 ++++++ rtw8822b.c | 6 ++++++ rtw8822c.c | 6 ++++++ 13 files changed, 109 insertions(+) diff --git a/mac80211.c b/mac80211.c index 98a90cfb..f7c6e0a8 100644 --- a/mac80211.c +++ b/mac80211.c @@ -413,6 +413,8 @@ static void rtw_ops_bss_info_changed(struct ieee80211_hw *hw, if (rtw_bf_support) rtw_bf_assoc(rtwdev, vif, conf); + rtw_set_ampdu_factor(rtwdev, vif, conf); + rtw_fw_beacon_filter_config(rtwdev, true, vif); } else { rtw_leave_lps(rtwdev); diff --git a/main.c b/main.c index d9407ac4..09a3bd9b 100644 --- a/main.c +++ b/main.c @@ -2651,6 +2651,46 @@ void rtw_core_enable_beacon(struct rtw_dev *rtwdev, bool enable) } } +void rtw_set_ampdu_factor(struct rtw_dev *rtwdev, struct ieee80211_vif *vif, + struct ieee80211_bss_conf *bss_conf) +{ + const struct rtw_chip_ops *ops = rtwdev->chip->ops; + struct ieee80211_sta *sta; + u8 factor = 0xff; + + if (!ops->set_ampdu_factor) + return; + + rcu_read_lock(); + + sta = ieee80211_find_sta(vif, bss_conf->bssid); + if (!sta) { + rcu_read_unlock(); + rtw_warn(rtwdev, "%s: failed to find station %pM\n", + __func__, bss_conf->bssid); + return; + } + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 19, 0) + if (sta->deflink.vht_cap.vht_supported) + factor = u32_get_bits(sta->deflink.vht_cap.cap, + IEEE80211_VHT_CAP_MAX_A_MPDU_LENGTH_EXPONENT_MASK); + else if (sta->deflink.ht_cap.ht_supported) + factor = sta->deflink.ht_cap.ampdu_factor; +#else + if (sta->vht_cap.vht_supported) + factor = u32_get_bits(sta->vht_cap.cap, + IEEE80211_VHT_CAP_MAX_A_MPDU_LENGTH_EXPONENT_MASK); + else if (sta->ht_cap.ht_supported) + factor = sta->ht_cap.ampdu_factor; +#endif + + rcu_read_unlock(); + + if (factor != 0xff) + ops->set_ampdu_factor(rtwdev, factor); +} + MODULE_AUTHOR("Realtek Corporation"); MODULE_DESCRIPTION("Realtek 802.11ac wireless core module"); MODULE_LICENSE("Dual BSD/GPL"); diff --git a/main.h b/main.h index d5aa1261..8648c884 100644 --- a/main.h +++ b/main.h @@ -1014,6 +1014,7 @@ struct rtw_chip_ops { u32 antenna_rx); void (*cfg_ldo25)(struct rtw_dev *rtwdev, bool enable); void (*efuse_grant)(struct rtw_dev *rtwdev, bool enable); + void (*set_ampdu_factor)(struct rtw_dev *rtwdev, u8 factor); void (*false_alarm_statistics)(struct rtw_dev *rtwdev); void (*phy_calibration)(struct rtw_dev *rtwdev); void (*dpk_track)(struct rtw_dev *rtwdev); @@ -2418,6 +2419,8 @@ void rtw_update_channel(struct rtw_dev *rtwdev, u8 center_channel, void rtw_core_port_switch(struct rtw_dev *rtwdev, struct ieee80211_vif *vif); bool rtw_core_check_sta_active(struct rtw_dev *rtwdev); void rtw_core_enable_beacon(struct rtw_dev *rtwdev, bool enable); +void rtw_set_ampdu_factor(struct rtw_dev *rtwdev, struct ieee80211_vif *vif, + struct ieee80211_bss_conf *bss_conf); #if LINUX_VERSION_CODE < KERNEL_VERSION(6, 8, 0) static inline bool rtw_ssid_equal(struct cfg80211_ssid *a, struct cfg80211_ssid *b) diff --git a/rtw8703b.c b/rtw8703b.c index 03ffe8e1..8e0de023 100644 --- a/rtw8703b.c +++ b/rtw8703b.c @@ -1919,6 +1919,7 @@ static const struct rtw_chip_ops rtw8703b_ops = { .set_antenna = NULL, .cfg_ldo25 = rtw8723x_cfg_ldo25, .efuse_grant = rtw8723x_efuse_grant, + .set_ampdu_factor = rtw8723x_set_ampdu_factor, .false_alarm_statistics = rtw8723x_false_alarm_statistics, .phy_calibration = rtw8703b_phy_calibration, .dpk_track = NULL, diff --git a/rtw8723d.c b/rtw8723d.c index 2217f809..fb887ec0 100644 --- a/rtw8723d.c +++ b/rtw8723d.c @@ -1404,6 +1404,7 @@ static const struct rtw_chip_ops rtw8723d_ops = { .set_antenna = NULL, .cfg_ldo25 = rtw8723x_cfg_ldo25, .efuse_grant = rtw8723x_efuse_grant, + .set_ampdu_factor = rtw8723x_set_ampdu_factor, .false_alarm_statistics = rtw8723x_false_alarm_statistics, .phy_calibration = rtw8723d_phy_calibration, .cck_pd_set = rtw8723d_phy_cck_pd_set, diff --git a/rtw8723x.c b/rtw8723x.c index 69f73cb5..3129493d 100644 --- a/rtw8723x.c +++ b/rtw8723x.c @@ -374,6 +374,13 @@ static void __rtw8723x_efuse_grant(struct rtw_dev *rtwdev, bool on) } } +static void __rtw8723x_set_ampdu_factor(struct rtw_dev *rtwdev, u8 factor) +{ + factor = min_t(u8, factor, IEEE80211_HT_MAX_AMPDU_32K); + + rtw_write32(rtwdev, REG_AMPDU_MAX_LENGTH, (8192 << factor) - 1); +} + static void __rtw8723x_false_alarm_statistics(struct rtw_dev *rtwdev) { struct rtw_dm_info *dm_info = &rtwdev->dm_info; @@ -704,6 +711,7 @@ const struct rtw8723x_common rtw8723x_common = { .cfg_ldo25 = __rtw8723x_cfg_ldo25, .set_tx_power_index = __rtw8723x_set_tx_power_index, .efuse_grant = __rtw8723x_efuse_grant, + .set_ampdu_factor = __rtw8723x_set_ampdu_factor, .false_alarm_statistics = __rtw8723x_false_alarm_statistics, .iqk_backup_regs = __rtw8723x_iqk_backup_regs, .iqk_restore_regs = __rtw8723x_iqk_restore_regs, diff --git a/rtw8723x.h b/rtw8723x.h index e93bfce9..f19d4055 100644 --- a/rtw8723x.h +++ b/rtw8723x.h @@ -140,6 +140,7 @@ struct rtw8723x_common { void (*cfg_ldo25)(struct rtw_dev *rtwdev, bool enable); void (*set_tx_power_index)(struct rtw_dev *rtwdev); void (*efuse_grant)(struct rtw_dev *rtwdev, bool on); + void (*set_ampdu_factor)(struct rtw_dev *rtwdev, u8 factor); void (*false_alarm_statistics)(struct rtw_dev *rtwdev); void (*iqk_backup_regs)(struct rtw_dev *rtwdev, struct rtw8723x_iqk_backup_regs *backup); @@ -398,6 +399,11 @@ static inline void rtw8723x_efuse_grant(struct rtw_dev *rtwdev, bool on) rtw8723x_common.efuse_grant(rtwdev, on); } +static inline void rtw8723x_set_ampdu_factor(struct rtw_dev *rtwdev, u8 factor) +{ + rtw8723x_common.set_ampdu_factor(rtwdev, factor); +} + static inline void rtw8723x_false_alarm_statistics(struct rtw_dev *rtwdev) { rtw8723x_common.false_alarm_statistics(rtwdev); diff --git a/rtw8812a.c b/rtw8812a.c index 5f46456b..56faf725 100644 --- a/rtw8812a.c +++ b/rtw8812a.c @@ -78,6 +78,16 @@ static void rtw8812a_cfg_ldo25(struct rtw_dev *rtwdev, bool enable) { } +static void rtw8812a_set_ampdu_factor(struct rtw_dev *rtwdev, u8 factor) +{ + u32 len; + + factor = min_t(u8, factor, IEEE80211_VHT_MAX_AMPDU_128K); + len = BIT(31) | ((8192 << factor) - 1); + + rtw_write32(rtwdev, REG_AMPDU_MAX_LENGTH, len); +} + static void rtw8812a_do_lck(struct rtw_dev *rtwdev) { u32 cont_tx, lc_cal, i; @@ -929,6 +939,7 @@ static const struct rtw_chip_ops rtw8812a_ops = { .set_tx_power_index = rtw88xxa_set_tx_power_index, .cfg_ldo25 = rtw8812a_cfg_ldo25, .efuse_grant = rtw88xxa_efuse_grant, + .set_ampdu_factor = rtw8812a_set_ampdu_factor, .false_alarm_statistics = rtw88xxa_false_alarm_statistics, .phy_calibration = rtw8812a_phy_calibration, .cck_pd_set = rtw88xxa_phy_cck_pd_set, diff --git a/rtw8814a.c b/rtw8814a.c index ac5fd43c..b6b65c3a 100644 --- a/rtw8814a.c +++ b/rtw8814a.c @@ -1288,6 +1288,13 @@ static void rtw8814a_cfg_ldo25(struct rtw_dev *rtwdev, bool enable) { } +static void rtw8814a_set_ampdu_factor(struct rtw_dev *rtwdev, u8 factor) +{ + factor = min_t(u8, factor, IEEE80211_VHT_MAX_AMPDU_256K); + + rtw_write32(rtwdev, REG_AMPDU_MAX_LENGTH, (8192 << factor) - 1); +} + static void rtw8814a_false_alarm_statistics(struct rtw_dev *rtwdev) { struct rtw_dm_info *dm_info = &rtwdev->dm_info; @@ -2056,6 +2063,7 @@ static const struct rtw_chip_ops rtw8814a_ops = { .set_antenna = NULL, .cfg_ldo25 = rtw8814a_cfg_ldo25, .efuse_grant = rtw8814a_efuse_grant, + .set_ampdu_factor = rtw8814a_set_ampdu_factor, .false_alarm_statistics = rtw8814a_false_alarm_statistics, .phy_calibration = rtw8814a_phy_calibration, .cck_pd_set = rtw8814a_phy_cck_pd_set, diff --git a/rtw8821a.c b/rtw8821a.c index 0193e426..02d4f595 100644 --- a/rtw8821a.c +++ b/rtw8821a.c @@ -49,6 +49,16 @@ static void rtw8821a_cfg_ldo25(struct rtw_dev *rtwdev, bool enable) { } +static void rtw8821a_set_ampdu_factor(struct rtw_dev *rtwdev, u8 factor) +{ + u32 len; + + factor = min_t(u8, factor, IEEE80211_VHT_MAX_AMPDU_64K); + len = BIT(31) | ((8192 << factor) - 1); + + rtw_write32(rtwdev, REG_AMPDU_MAX_LENGTH, len); +} + #define CAL_NUM_8821A 3 #define MACBB_REG_NUM_8821A 8 #define AFE_REG_NUM_8821A 4 @@ -875,6 +885,7 @@ static const struct rtw_chip_ops rtw8821a_ops = { .set_tx_power_index = rtw88xxa_set_tx_power_index, .cfg_ldo25 = rtw8821a_cfg_ldo25, .efuse_grant = rtw88xxa_efuse_grant, + .set_ampdu_factor = rtw8821a_set_ampdu_factor, .false_alarm_statistics = rtw88xxa_false_alarm_statistics, .phy_calibration = rtw8821a_phy_calibration, .cck_pd_set = rtw88xxa_phy_cck_pd_set, diff --git a/rtw8821c.c b/rtw8821c.c index eb2c6d7d..2551d2af 100644 --- a/rtw8821c.c +++ b/rtw8821c.c @@ -718,6 +718,11 @@ static void rtw8821c_set_tx_power_index(struct rtw_dev *rtwdev) } } +static void rtw8821c_set_ampdu_factor(struct rtw_dev *rtwdev, u8 factor) +{ + rtw_write32(rtwdev, REG_AMPDU_MAX_LENGTH, (8192 << factor) - 1); +} + static void rtw8821c_false_alarm_statistics(struct rtw_dev *rtwdev) { struct rtw_dm_info *dm_info = &rtwdev->dm_info; @@ -1671,6 +1676,7 @@ static const struct rtw_chip_ops rtw8821c_ops = { .set_antenna = NULL, .set_tx_power_index = rtw8821c_set_tx_power_index, .cfg_ldo25 = rtw8821c_cfg_ldo25, + .set_ampdu_factor = rtw8821c_set_ampdu_factor, .false_alarm_statistics = rtw8821c_false_alarm_statistics, .phy_calibration = rtw8821c_phy_calibration, .cck_pd_set = rtw8821c_phy_cck_pd_set, diff --git a/rtw8822b.c b/rtw8822b.c index 982952b8..72251d3e 100644 --- a/rtw8822b.c +++ b/rtw8822b.c @@ -1016,6 +1016,11 @@ static void rtw8822b_cfg_ldo25(struct rtw_dev *rtwdev, bool enable) rtw_write8(rtwdev, REG_LDO_EFUSE_CTRL + 3, ldo_pwr); } +static void rtw8822b_set_ampdu_factor(struct rtw_dev *rtwdev, u8 factor) +{ + rtw_write32(rtwdev, REG_AMPDU_MAX_LENGTH, (8192 << factor) - 1); +} + static void rtw8822b_false_alarm_statistics(struct rtw_dev *rtwdev) { struct rtw_dm_info *dm_info = &rtwdev->dm_info; @@ -2160,6 +2165,7 @@ static const struct rtw_chip_ops rtw8822b_ops = { .set_tx_power_index = rtw8822b_set_tx_power_index, .set_antenna = rtw8822b_set_antenna, .cfg_ldo25 = rtw8822b_cfg_ldo25, + .set_ampdu_factor = rtw8822b_set_ampdu_factor, .false_alarm_statistics = rtw8822b_false_alarm_statistics, .phy_calibration = rtw8822b_phy_calibration, .pwr_track = rtw8822b_pwr_track, diff --git a/rtw8822c.c b/rtw8822c.c index 005a0c3d..e1466440 100644 --- a/rtw8822c.c +++ b/rtw8822c.c @@ -2809,6 +2809,11 @@ static void rtw8822c_cfg_ldo25(struct rtw_dev *rtwdev, bool enable) rtw_write8(rtwdev, REG_ANAPARLDO_POW_MAC, ldo_pwr); } +static void rtw8822c_set_ampdu_factor(struct rtw_dev *rtwdev, u8 factor) +{ + rtw_write32(rtwdev, REG_AMPDU_MAX_LENGTH, (8192 << factor) - 1); +} + static void rtw8822c_false_alarm_statistics(struct rtw_dev *rtwdev) { struct rtw_dm_info *dm_info = &rtwdev->dm_info; @@ -4972,6 +4977,7 @@ static const struct rtw_chip_ops rtw8822c_ops = { .set_tx_power_index = rtw8822c_set_tx_power_index, .set_antenna = rtw8822c_set_antenna, .cfg_ldo25 = rtw8822c_cfg_ldo25, + .set_ampdu_factor = rtw8822c_set_ampdu_factor, .false_alarm_statistics = rtw8822c_false_alarm_statistics, .dpk_track = rtw8822c_dpk_track, .phy_calibration = rtw8822c_phy_calibration, From 0ea621284e271f315442007d1cfa1fb6bad98874 Mon Sep 17 00:00:00 2001 From: Bitterblue Smith Date: Fri, 20 Dec 2024 02:19:50 +0200 Subject: [PATCH 101/193] Compile the new rtw_8814au module Signed-off-by: Bitterblue Smith --- Makefile | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/Makefile b/Makefile index 0aa40893..a063ab49 100644 --- a/Makefile +++ b/Makefile @@ -110,6 +110,12 @@ rtw_88xxa-objs := rtw88xxa.o obj-m += rtw_8821au.o rtw_8821au-objs := rtw8821au.o +obj-m += rtw_8814a.o +rtw_8814a-objs := rtw8814a.o rtw8814a_table.o + +obj-m += rtw_8814au.o +rtw_8814au-objs := rtw8814au.o + obj-m += rtw_8821c.o rtw_8821c-objs := rtw8821c.o rtw8821c_table.o From 6a579872dba31ebf108dc645040639ae16a3f6c2 Mon Sep 17 00:00:00 2001 From: Zenm Chen Date: Fri, 20 Dec 2024 10:36:39 +0800 Subject: [PATCH 102/193] Update dkms.conf --- dkms.conf | 42 +++++++++++++++++++++++------------------- 1 file changed, 23 insertions(+), 19 deletions(-) diff --git a/dkms.conf b/dkms.conf index c3a97fec..e5fcf1fb 100644 --- a/dkms.conf +++ b/dkms.conf @@ -13,25 +13,27 @@ BUILT_MODULE_NAME[5]="rtw_8723du" BUILT_MODULE_NAME[6]="rtw_8723x" BUILT_MODULE_NAME[7]="rtw_8812a" BUILT_MODULE_NAME[8]="rtw_8812au" -BUILT_MODULE_NAME[9]="rtw_8821a" -BUILT_MODULE_NAME[10]="rtw_8821au" -BUILT_MODULE_NAME[11]="rtw_8821c" -BUILT_MODULE_NAME[12]="rtw_8821ce" -BUILT_MODULE_NAME[13]="rtw_8821cs" -BUILT_MODULE_NAME[14]="rtw_8821cu" -BUILT_MODULE_NAME[15]="rtw_8822b" -BUILT_MODULE_NAME[16]="rtw_8822be" -BUILT_MODULE_NAME[17]="rtw_8822bs" -BUILT_MODULE_NAME[18]="rtw_8822bu" -BUILT_MODULE_NAME[19]="rtw_8822c" -BUILT_MODULE_NAME[20]="rtw_8822ce" -BUILT_MODULE_NAME[21]="rtw_8822cs" -BUILT_MODULE_NAME[22]="rtw_8822cu" -BUILT_MODULE_NAME[23]="rtw_88xxa" -BUILT_MODULE_NAME[24]="rtw_core" -BUILT_MODULE_NAME[25]="rtw_pci" -BUILT_MODULE_NAME[26]="rtw_sdio" -BUILT_MODULE_NAME[27]="rtw_usb" +BUILT_MODULE_NAME[9]="rtw_8814a" +BUILT_MODULE_NAME[10]="rtw_8814au" +BUILT_MODULE_NAME[11]="rtw_8821a" +BUILT_MODULE_NAME[12]="rtw_8821au" +BUILT_MODULE_NAME[13]="rtw_8821c" +BUILT_MODULE_NAME[14]="rtw_8821ce" +BUILT_MODULE_NAME[15]="rtw_8821cs" +BUILT_MODULE_NAME[16]="rtw_8821cu" +BUILT_MODULE_NAME[17]="rtw_8822b" +BUILT_MODULE_NAME[18]="rtw_8822be" +BUILT_MODULE_NAME[19]="rtw_8822bs" +BUILT_MODULE_NAME[20]="rtw_8822bu" +BUILT_MODULE_NAME[21]="rtw_8822c" +BUILT_MODULE_NAME[22]="rtw_8822ce" +BUILT_MODULE_NAME[23]="rtw_8822cs" +BUILT_MODULE_NAME[24]="rtw_8822cu" +BUILT_MODULE_NAME[25]="rtw_88xxa" +BUILT_MODULE_NAME[26]="rtw_core" +BUILT_MODULE_NAME[27]="rtw_pci" +BUILT_MODULE_NAME[28]="rtw_sdio" +BUILT_MODULE_NAME[29]="rtw_usb" DEST_MODULE_LOCATION[0]="/updates/dkms/rtw88" DEST_MODULE_LOCATION[1]="/updates/dkms/rtw88" DEST_MODULE_LOCATION[2]="/updates/dkms/rtw88" @@ -60,3 +62,5 @@ DEST_MODULE_LOCATION[24]="/updates/dkms/rtw88" DEST_MODULE_LOCATION[25]="/updates/dkms/rtw88" DEST_MODULE_LOCATION[26]="/updates/dkms/rtw88" DEST_MODULE_LOCATION[27]="/updates/dkms/rtw88" +DEST_MODULE_LOCATION[28]="/updates/dkms/rtw88" +DEST_MODULE_LOCATION[29]="/updates/dkms/rtw88" From d046e7636ba04fcc85d0a9d0aff9aadceed50494 Mon Sep 17 00:00:00 2001 From: Zenm Chen Date: Fri, 20 Dec 2024 10:39:33 +0800 Subject: [PATCH 103/193] Update Makefile --- Makefile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Makefile b/Makefile index a063ab49..802629f4 100644 --- a/Makefile +++ b/Makefile @@ -3,9 +3,9 @@ KVER ?= $(if $(KERNELRELEASE),$(KERNELRELEASE),$(shell uname -r)) KSRC ?= $(if $(KERNEL_SRC),$(KERNEL_SRC),/lib/modules/$(KVER)/build) FIRMWAREDIR := /lib/firmware/rtw88 MODLIST := rtw_8723cs rtw_8723de rtw_8723ds rtw_8723du \ - rtw_8812au rtw_8821au rtw_8821ce rtw_8821cs rtw_8821cu \ + rtw_8812au rtw_8814au rtw_8821au rtw_8821ce rtw_8821cs rtw_8821cu \ rtw_8822be rtw_8822bs rtw_8822bu rtw_8822ce rtw_8822cs rtw_8822cu \ - rtw_8703b rtw_8723d rtw_8821a rtw_8812a rtw_8821c rtw_8822b rtw_8822c \ + rtw_8703b rtw_8723d rtw_8821a rtw_8812a rtw_8814a rtw_8821c rtw_8822b rtw_8822c \ rtw_8723x rtw_88xxa rtw_pci rtw_sdio rtw_usb rtw_core # Handle the move of the entire rtw88 tree ifneq ("","$(wildcard /lib/modules/$(KVER)/kernel/drivers/net/wireless/realtek)") From 8a5fc2984e41b2e306629deca88f95a265f62268 Mon Sep 17 00:00:00 2001 From: morrownr <69053122+morrownr@users.noreply.github.com> Date: Sat, 21 Dec 2024 11:11:21 -0600 Subject: [PATCH 104/193] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index dc6328ae..f5163a9c 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,7 @@ # rtw88 downstream 🐧 ### This is a downstream repo for the Linux in-kernel rtw88 series of drivers for Realtek WiFi 5 chips. -🌟 **Up-to-Date Drivers**: The code in this repo stays in sync with the `wireless-next` repository, with additional changes to accommodate kernel API changes over time. The current repo matches the kernel as of March 5, 2024. +🌟 **Up-to-Date Drivers**: The code in this repo stays in sync with the `wireless-next` repository, with additional changes to accommodate kernel API changes over time. 📌 **Note**: The `wireless-next` repo contains the code set for the ***next*** kernel version. If kernel 6.X is out, kernel mainline repo is on 6.X+1-rcY, and `wireless-next` targets kernel 6.X+2 material. From a4909c0f0775d45fa9adbe00e464c863d260561a Mon Sep 17 00:00:00 2001 From: morrownr <69053122+morrownr@users.noreply.github.com> Date: Sat, 21 Dec 2024 11:17:53 -0600 Subject: [PATCH 105/193] Update README.md --- README.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index f5163a9c..ff720876 100644 --- a/README.md +++ b/README.md @@ -13,7 +13,8 @@ Compatible with **Linux kernel versions 5.4 and newer** as long as your distro h #### Supported Chipsets -- **USB** : RTW8812AU, RTW8821AU, RTW8811AU, RTW8822BU, RTW8812BU, RTW8822CU, RTW8812CU, RTW8821CU, RTW8811CU, RTW8723DU +- **USB** : RTW8814AU, RTW8812AU, RTW8821AU, RTW8811AU, RTW8822BU, RTW8812BU +- **USB** : RTW8822CU, RTW8812CU, RTW8821CU, RTW8811CU, RTW8723DU - **PCIe**: RTW8822BE, RTW8822CE, RTW8821CE, RTW8723DE - **SDIO**: RTW8822BS, RTW8822CS, RTW8821CS, RTW8723DS From 85c8e30fea1ec9221ba95208364270fe234701ac Mon Sep 17 00:00:00 2001 From: morrownr <69053122+morrownr@users.noreply.github.com> Date: Mon, 23 Dec 2024 11:16:26 -0600 Subject: [PATCH 106/193] Update README.md --- README.md | 21 ++++++++++++--------- 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/README.md b/README.md index ff720876..d40f244b 100644 --- a/README.md +++ b/README.md @@ -1,14 +1,15 @@ # rtw88 downstream 🐧 -### This is a downstream repo for the Linux in-kernel rtw88 series of drivers for Realtek WiFi 5 chips. +### This is a downstream repo with a primary purpose of supporting development, testing and maintenance for the Realtek rtw88 series of WiFi 5 drivers in the Linux kernel. -🌟 **Up-to-Date Drivers**: The code in this repo stays in sync with the `wireless-next` repository, with additional changes to accommodate kernel API changes over time. +The most recent addition to this repo is the driver for the rtw8814au chipset. Testing is needed so if you have an adapter based on the rtw8814au chipset, please test and report. + +🌟 The code in this repo stays in sync with the `wireless-next` repository, with additional changes to accommodate kernel API changes over time. 📌 **Note**: The `wireless-next` repo contains the code set for the ***next*** kernel version. If kernel 6.X is out, kernel mainline repo is on 6.X+1-rcY, and `wireless-next` targets kernel 6.X+2 material. --- -### Compatibility - +## Compatibility Compatible with **Linux kernel versions 5.4 and newer** as long as your distro hasn't modified any kernel APIs. RHEL and all distros based on RHEL will have modified kernel APIs and are unlikely to be compatible with this driver. @@ -18,6 +19,7 @@ Compatible with **Linux kernel versions 5.4 and newer** as long as your distro h - **PCIe**: RTW8822BE, RTW8822CE, RTW8821CE, RTW8723DE - **SDIO**: RTW8822BS, RTW8822CS, RTW8821CS, RTW8723DS +--- ## Issues 🚨 Report problems in Issues after you have checked the [FAQ](#faq) at bottom of this README. @@ -119,6 +121,8 @@ sudo mokutil --reset - In the MOK managerment screen, select reset MOK list. - Reboot then retry from the step `make sign-install`. +--- + ## Important Information Below is important information for using this driver. @@ -160,10 +164,7 @@ options <>= The available options for rtw_pci are disable_msi and disable_aspm. The available options for rtw_core are disable_lps_deep, support_bf, and debug_mask. ---- - -## Kernel Updates 🔄 - +### 5. Kernel Updates 🔄 When your kernel updates, run: ```bash cd ~/rtw88 @@ -177,7 +178,9 @@ make ``` sudo make install ``` -💡 **Remember, every new kernel requires this step - no exceptions**. If the kernel update means that you have no network, skip the 'git pull' and build the driver as it is, but run `git pull` once you have connectivity, and rebuild if any updates were pulled. +💡 **Remember, every newly installed kernel requires this step - no exceptions**. If the kernel update means that you have no network, skip the 'git pull' and build the driver as it is, but run `git pull` once you have connectivity, and rebuild if any updates were pulled. + +--- ## FAQ From 4a959cbfae896bb18d2b0303bf4a884cc2dd3a5a Mon Sep 17 00:00:00 2001 From: morrownr <69053122+morrownr@users.noreply.github.com> Date: Mon, 23 Dec 2024 18:47:49 -0600 Subject: [PATCH 107/193] Update README.md --- README.md | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index d40f244b..73524f57 100644 --- a/README.md +++ b/README.md @@ -152,7 +152,7 @@ sudo modprobe rtw_8723de # This loads the module # Only a single modprobe call is required to load. ``` -### 4. Option Configuration 📝 +### 4. Driver Parameter Configuration (options) 📝 ```bash sudo nano /etc/modprobe.d/.conf ``` @@ -161,6 +161,13 @@ There, enter the line below: ```bash options <>= ``` + +The available parameter (option) for USB devices is + +switch_usb_mode= + +Set to N to disable switching to USB 3 mode to avoid potential interference in the 2.4 GHz band (default: Y) (bool). This parameter (options) applies to the USB 3 capable devices: RTL8814AU, RTL8822CU, RTL8812CU, RTL8822BU, RTL8812BU, and RTL8812AU. It's okay to leave the parameter on even when plugging the device into a USB 2 port because it will try to switch to USB 3 mode only once. + The available options for rtw_pci are disable_msi and disable_aspm. The available options for rtw_core are disable_lps_deep, support_bf, and debug_mask. From e15c59e8fd8361258747a898d7b2f86344bb33fb Mon Sep 17 00:00:00 2001 From: Bitterblue Smith Date: Tue, 24 Dec 2024 17:44:06 +0200 Subject: [PATCH 108/193] wifi: rtw88: 8814au: Don't ask for TX report for management frames Unlike every other chip supported by rtw88, RTL8814AU doesn't provide TX reports for frames sent through the management queue. This is not a big problem in station mode. It just results in "rtw_8814au 2-4:1.0: failed to get tx report from firmware" when connecting to a network but the connection works. But in AP mode clients can't connect at all. Something really wants those TX reports in AP mode. One way to fix it is to ignore IEEE80211_TX_CTL_REQ_TX_STATUS when transmitting management frames and the chip type is RTL8814AU. Signed-off-by: Bitterblue Smith --- usb.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/usb.c b/usb.c index 92f4c064..6034c9c1 100644 --- a/usb.c +++ b/usb.c @@ -267,6 +267,7 @@ static void rtw_usb_write_port_tx_complete(struct urb *urb) struct rtw_usb_txcb *txcb = urb->context; struct rtw_dev *rtwdev = txcb->rtwdev; struct ieee80211_hw *hw = rtwdev->hw; + struct ieee80211_hdr *hdr; while (true) { struct sk_buff *skb = skb_dequeue(&txcb->tx_ack_queue); @@ -281,8 +282,12 @@ static void rtw_usb_write_port_tx_complete(struct urb *urb) skb_pull(skb, rtwdev->chip->tx_pkt_desc_sz); + hdr = (struct ieee80211_hdr *)skb->data; + /* enqueue to wait for tx report */ - if (info->flags & IEEE80211_TX_CTL_REQ_TX_STATUS) { + if ((info->flags & IEEE80211_TX_CTL_REQ_TX_STATUS) && + !(rtwdev->chip->id == RTW_CHIP_TYPE_8814A && + ieee80211_is_mgmt(hdr->frame_control))) { rtw_tx_report_enqueue(rtwdev, skb, tx_data->sn); continue; } From 8d474dbc75f3cbbfa9b58ec3099acaddb5dad73c Mon Sep 17 00:00:00 2001 From: morrownr <69053122+morrownr@users.noreply.github.com> Date: Tue, 24 Dec 2024 15:32:46 -0600 Subject: [PATCH 109/193] Update README.md --- README.md | 33 ++++++++++++++++++++++++++------- 1 file changed, 26 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index 73524f57..ac0719ce 100644 --- a/README.md +++ b/README.md @@ -153,23 +153,42 @@ sudo modprobe rtw_8723de # This loads the module ``` ### 4. Driver Parameter Configuration (options) 📝 + +Example for chipset RTL8814AU and driver name rtw_8814au: + +Note: the driver names in the rtw88 in the Linux Mainline kernel are slightly different: rtw88_8814au + ```bash -sudo nano /etc/modprobe.d/.conf +sudo nano /etc/modprobe.d/rtw_8814au.conf ``` -There, enter the line below: +Note: Change rtw_8814au in the above to the name of the driver you wish to modify. + +In the empty file, paste the following: + ```bash -options <>= +options rtw_8814au switch_usb_mode=N + ``` -The available parameter (option) for USB devices is +See below for an explanation of the above parameter and for information about other parameters. + +The available parameter (option) for USB 3 devices is: switch_usb_mode= -Set to N to disable switching to USB 3 mode to avoid potential interference in the 2.4 GHz band (default: Y) (bool). This parameter (options) applies to the USB 3 capable devices: RTL8814AU, RTL8822CU, RTL8812CU, RTL8822BU, RTL8812BU, and RTL8812AU. It's okay to leave the parameter on even when plugging the device into a USB 2 port because it will try to switch to USB 3 mode only once. +Set to N to disable switching to USB 3 mode to avoid potential interference in the 2.4 GHz band (default: Y) (bool). This parameter (option) applies to the USB 3 capable devices: RTL8814AU (rtw_8814au), RTL8822CU (rtw_8822cu), RTL8812CU (rtw_8822cu), RTL8822BU (rtw_8822bu), RTL8812BU (rtw_8822bu), and RTL8812AU (rtw_8812au). It's okay to leave the parameter on even when plugging the device into a USB 2 port because it will try to switch to USB 3 mode only once. + +The available options for rtw_pci are: + +disable_msi +disable_aspm + +The available options for rtw_core are: -The available options for rtw_pci are disable_msi and disable_aspm. -The available options for rtw_core are disable_lps_deep, support_bf, and debug_mask. +disable_lps_deep +support_bf +debug_mask ### 5. Kernel Updates 🔄 When your kernel updates, run: From da3f5dd1d7b61a7baacfa64172bfdc9481117b70 Mon Sep 17 00:00:00 2001 From: Ping-Ke Shih Date: Thu, 12 Dec 2024 13:42:03 +0800 Subject: [PATCH 110/193] wifi: rtw88: add __packed attribute to efuse layout struct The layout struct of efuse should not do address alignment by compiler. Otherwise it leads unexpected layout and size for certain arch suc as arm. In x86-64, the results are identical before and after this patch. Also adjust bit-field to prevent over adjacent byte to avoid warning: rtw88/rtw8822b.h:66:1: note: offset of packed bit-field `res2` has changed in GCC 4.4 66 | } __packed; | ^ Reported-by: kernel test robot Closes: https://lore.kernel.org/oe-kbuild-all/202412120131.qk0x6OhE-lkp@intel.com/ Signed-off-by: Ping-Ke Shih Link: https://patch.msgid.link/20241212054203.135046-1-pkshih@realtek.com --- main.h | 4 ++-- rtw8723x.h | 8 ++++---- rtw8821c.h | 9 +++++---- rtw8822b.h | 9 +++++---- rtw8822c.h | 9 +++++---- 5 files changed, 21 insertions(+), 18 deletions(-) diff --git a/main.h b/main.h index 8648c884..39d64bdd 100644 --- a/main.h +++ b/main.h @@ -659,12 +659,12 @@ struct rtw_5g_txpwr_idx { struct rtw_5g_vht_ns_pwr_idx_diff vht_2s_diff; struct rtw_5g_vht_ns_pwr_idx_diff vht_3s_diff; struct rtw_5g_vht_ns_pwr_idx_diff vht_4s_diff; -}; +} __packed; struct rtw_txpwr_idx { struct rtw_2g_txpwr_idx pwr_idx_2g; struct rtw_5g_txpwr_idx pwr_idx_5g; -}; +} __packed; struct rtw_channel_params { u8 center_chan; diff --git a/rtw8723x.h b/rtw8723x.h index f19d4055..5d756c49 100644 --- a/rtw8723x.h +++ b/rtw8723x.h @@ -47,7 +47,7 @@ struct rtw8723xe_efuse { u8 device_id[2]; u8 sub_vendor_id[2]; u8 sub_device_id[2]; -}; +} __packed; struct rtw8723xu_efuse { u8 res4[48]; /* 0xd0 */ @@ -56,12 +56,12 @@ struct rtw8723xu_efuse { u8 usb_option; /* 0x104 */ u8 res5[2]; /* 0x105 */ u8 mac_addr[ETH_ALEN]; /* 0x107 */ -}; +} __packed; struct rtw8723xs_efuse { u8 res4[0x4a]; /* 0xd0 */ u8 mac_addr[ETH_ALEN]; /* 0x11a */ -}; +} __packed; struct rtw8723x_efuse { __le16 rtl_id; @@ -96,7 +96,7 @@ struct rtw8723x_efuse { struct rtw8723xu_efuse u; struct rtw8723xs_efuse s; }; -}; +} __packed; #define RTW8723X_IQK_ADDA_REG_NUM 16 #define RTW8723X_IQK_MAC8_REG_NUM 3 diff --git a/rtw8821c.h b/rtw8821c.h index 7a33ebd6..954e93c8 100644 --- a/rtw8821c.h +++ b/rtw8821c.h @@ -27,7 +27,7 @@ struct rtw8821cu_efuse { u8 res11[0xcf]; u8 package_type; /* 0x1fb */ u8 res12[0x4]; -}; +} __packed; struct rtw8821ce_efuse { u8 mac_addr[ETH_ALEN]; /* 0xd0 */ @@ -47,7 +47,8 @@ struct rtw8821ce_efuse { u8 ltr_en:1; u8 res1:2; u8 obff:2; - u8 res2:3; + u8 res2_1:1; + u8 res2_2:2; u8 obff_cap:2; u8 res3:4; u8 res4[3]; @@ -63,7 +64,7 @@ struct rtw8821ce_efuse { u8 res6:1; u8 port_t_power_on_value:5; u8 res7; -}; +} __packed; struct rtw8821cs_efuse { u8 res4[0x4a]; /* 0xd0 */ @@ -101,7 +102,7 @@ struct rtw8821c_efuse { struct rtw8821cu_efuse u; struct rtw8821cs_efuse s; }; -}; +} __packed; static inline void _rtw_write32s_mask(struct rtw_dev *rtwdev, u32 addr, u32 mask, u32 data) diff --git a/rtw8822b.h b/rtw8822b.h index 0514958f..9fca9ba6 100644 --- a/rtw8822b.h +++ b/rtw8822b.h @@ -27,7 +27,7 @@ struct rtw8822bu_efuse { u8 res11[0xcf]; u8 package_type; /* 0x1fb */ u8 res12[0x4]; -}; +} __packed; struct rtw8822be_efuse { u8 mac_addr[ETH_ALEN]; /* 0xd0 */ @@ -47,7 +47,8 @@ struct rtw8822be_efuse { u8 ltr_en:1; u8 res1:2; u8 obff:2; - u8 res2:3; + u8 res2_1:1; + u8 res2_2:2; u8 obff_cap:2; u8 res3:4; u8 res4[3]; @@ -63,7 +64,7 @@ struct rtw8822be_efuse { u8 res6:1; u8 port_t_power_on_value:5; u8 res7; -}; +} __packed; struct rtw8822bs_efuse { u8 res4[0x4a]; /* 0xd0 */ @@ -103,7 +104,7 @@ struct rtw8822b_efuse { struct rtw8822bu_efuse u; struct rtw8822bs_efuse s; }; -}; +} __packed; static inline void _rtw_write32s_mask(struct rtw_dev *rtwdev, u32 addr, u32 mask, u32 data) diff --git a/rtw8822c.h b/rtw8822c.h index e2b383d6..fc62b67a 100644 --- a/rtw8822c.h +++ b/rtw8822c.h @@ -14,7 +14,7 @@ struct rtw8822cu_efuse { u8 res1[3]; u8 mac_addr[ETH_ALEN]; /* 0x157 */ u8 res2[0x3d]; -}; +} __packed; struct rtw8822cs_efuse { u8 res0[0x4a]; /* 0x120 */ @@ -39,7 +39,8 @@ struct rtw8822ce_efuse { u8 ltr_en:1; u8 res1:2; u8 obff:2; - u8 res2:3; + u8 res2_1:1; + u8 res2_2:2; u8 obff_cap:2; u8 res3:4; u8 class_code[3]; @@ -55,7 +56,7 @@ struct rtw8822ce_efuse { u8 res6:1; u8 port_t_power_on_value:5; u8 res7; -}; +} __packed; struct rtw8822c_efuse { __le16 rtl_id; @@ -102,7 +103,7 @@ struct rtw8822c_efuse { struct rtw8822cu_efuse u; struct rtw8822cs_efuse s; }; -}; +} __packed; enum rtw8822c_dpk_agc_phase { RTW_DPK_GAIN_CHECK, From df537a4d7247a915e4e35a40c9a2a304bfd01790 Mon Sep 17 00:00:00 2001 From: morrownr <69053122+morrownr@users.noreply.github.com> Date: Sun, 29 Dec 2024 14:02:15 -0600 Subject: [PATCH 111/193] Update README.md --- README.md | 22 ++++++++++++++-------- 1 file changed, 14 insertions(+), 8 deletions(-) diff --git a/README.md b/README.md index ac0719ce..f939161c 100644 --- a/README.md +++ b/README.md @@ -195,15 +195,26 @@ When your kernel updates, run: ```bash cd ~/rtw88 ``` +Change the above to the location where you downloaded the driver if necessary. + ``` git pull ``` ``` make ``` + +Secureboot disabled: + ``` sudo make install ``` + +Secureboot enabled: + +See section `Installation with SecureBoot for All Distros`. + + 💡 **Remember, every newly installed kernel requires this step - no exceptions**. If the kernel update means that you have no network, skip the 'git pull' and build the driver as it is, but run `git pull` once you have connectivity, and rebuild if any updates were pulled. --- @@ -231,22 +242,17 @@ Ubuntu often modifies kernel APIs, which can cause build issues. You'll need to --- -### Q3: How do I update the driver after a kernel update? -You will need to pull the latest code from this repository and recompile the driver. [Follow the steps in the Maintenance section](#kernel-updates-). - ---- - -### Q4: Is Secure Boot supported? +### Q3: Is Secure Boot supported? Yes, this repository provides a way to sign the kernel modules to be compatible with Secure Boot. [Check out the Installation with SecureBoot section](#installation-with-secureboot-). --- -### Q5: My card isn't listed. Can I request a feature? +### Q4: My card isn't listed. Can I request a feature? For feature requests like supporting a new card, you should reach out to Realtek engineers via E-mail at [linux-wireless@vger.kernel.org](mailto:linux-wireless@vger.kernel.org). --- -### Q6: How to remove this driver if it doesn't work as expected? +### Q5: How to remove this driver if it doesn't work as expected? Run this command in the rtw88 source directory and then the rtw88 driver will be unloaded and removed. `sudo make uninstall` From 2fbf72599d05145124edb0530e1786109215320c Mon Sep 17 00:00:00 2001 From: Bitterblue Smith Date: Wed, 1 Jan 2025 17:25:45 +0200 Subject: [PATCH 112/193] Revert "wifi: rtw88: Don't run coex when the chip has no Bluetooth" This reverts commit d402e1012d0239fa8b65395ad9973a7d52507a8a. It broke RTL8812BU (TP-Link Archer T3U Plus). Even though that device doesn't have Bluetooth, it needs parts of the coex initialisation: rtw_coex_set_gnt_bt(rtwdev, COEX_GNT_SET_SW_LOW); rtw_coex_set_gnt_wl(rtwdev, COEX_GNT_SET_SW_HIGH); from rtw_coex_set_ant_path(). Otherwise it can't connect. --- coex.c | 78 ---------------------------------------------------------- 1 file changed, 78 deletions(-) diff --git a/coex.c b/coex.c index 2091b6cd..c929db1e 100644 --- a/coex.c +++ b/coex.c @@ -370,9 +370,6 @@ void rtw_coex_write_scbd(struct rtw_dev *rtwdev, u16 bitpos, bool set) struct rtw_coex_stat *coex_stat = &coex->stat; u16 val = 0x2; - if (!rtwdev->efuse.btcoex) - return; - if (!chip->scbd_support) return; @@ -454,9 +451,6 @@ void rtw_coex_query_bt_info(struct rtw_dev *rtwdev) struct rtw_coex *coex = &rtwdev->coex; struct rtw_coex_stat *coex_stat = &coex->stat; - if (!rtwdev->efuse.btcoex) - return; - if (coex_stat->bt_disabled) return; @@ -2702,9 +2696,6 @@ static void __rtw_coex_init_hw_config(struct rtw_dev *rtwdev, bool wifi_only) struct rtw_coex *coex = &rtwdev->coex; struct rtw_coex_stat *coex_stat = &coex->stat; - if (!rtwdev->efuse.btcoex) - return; - rtw_dbg(rtwdev, RTW_DBG_COEX, "[BTCoex], %s()\n", __func__); rtw_coex_init_coex_var(rtwdev); @@ -2760,9 +2751,6 @@ void rtw_coex_power_on_setting(struct rtw_dev *rtwdev) struct rtw_coex *coex = &rtwdev->coex; u8 table_case = 1; - if (!rtwdev->efuse.btcoex) - return; - rtw_dbg(rtwdev, RTW_DBG_COEX, "[BTCoex], %s()\n", __func__); coex->stop_dm = true; @@ -2787,9 +2775,6 @@ EXPORT_SYMBOL(rtw_coex_power_on_setting); void rtw_coex_power_off_setting(struct rtw_dev *rtwdev) { - if (!rtwdev->efuse.btcoex) - return; - rtw_write16(rtwdev, REG_WIFI_BT_INFO, BIT_BT_INT_EN); } EXPORT_SYMBOL(rtw_coex_power_off_setting); @@ -2805,9 +2790,6 @@ void rtw_coex_ips_notify(struct rtw_dev *rtwdev, u8 type) struct rtw_coex *coex = &rtwdev->coex; struct rtw_coex_stat *coex_stat = &coex->stat; - if (!rtwdev->efuse.btcoex) - return; - if (coex->manual_control || coex->stop_dm) return; @@ -2837,9 +2819,6 @@ void rtw_coex_lps_notify(struct rtw_dev *rtwdev, u8 type) struct rtw_coex *coex = &rtwdev->coex; struct rtw_coex_stat *coex_stat = &coex->stat; - if (!rtwdev->efuse.btcoex) - return; - if (coex->manual_control || coex->stop_dm) return; @@ -2878,9 +2857,6 @@ void rtw_coex_scan_notify(struct rtw_dev *rtwdev, u8 type) struct rtw_coex *coex = &rtwdev->coex; struct rtw_coex_stat *coex_stat = &coex->stat; - if (!rtwdev->efuse.btcoex) - return; - if (coex->manual_control || coex->stop_dm) return; @@ -2918,9 +2894,6 @@ void rtw_coex_switchband_notify(struct rtw_dev *rtwdev, u8 type) { struct rtw_coex *coex = &rtwdev->coex; - if (!rtwdev->efuse.btcoex) - return; - if (coex->manual_control || coex->stop_dm) return; @@ -2948,9 +2921,6 @@ void rtw_coex_connect_notify(struct rtw_dev *rtwdev, u8 type) struct rtw_coex *coex = &rtwdev->coex; struct rtw_coex_stat *coex_stat = &coex->stat; - if (!rtwdev->efuse.btcoex) - return; - if (coex->manual_control || coex->stop_dm) return; @@ -3005,9 +2975,6 @@ void rtw_coex_media_status_notify(struct rtw_dev *rtwdev, u8 type) struct rtw_coex *coex = &rtwdev->coex; struct rtw_coex_stat *coex_stat = &coex->stat; - if (!rtwdev->efuse.btcoex) - return; - if (coex->manual_control || coex->stop_dm) return; @@ -3051,9 +3018,6 @@ void rtw_coex_bt_info_notify(struct rtw_dev *rtwdev, u8 *buf, u8 length) u8 i, rsp_source = 0, type; bool inq_page = false; - if (!rtwdev->efuse.btcoex) - return; - rsp_source = buf[0] & 0xf; if (rsp_source >= COEX_BTINFO_SRC_MAX) return; @@ -3323,9 +3287,6 @@ void rtw_coex_bt_hid_info_notify(struct rtw_dev *rtwdev, u8 *buf, u8 length) u8 sub_id = buf[2], gamehid_cnt = 0, handle, i; bool cur_game_hid_exist, complete; - if (!rtwdev->efuse.btcoex) - return; - if (!chip->wl_mimo_ps_support && (sub_id == COEX_BT_HIDINFO_LIST || sub_id == COEX_BT_HIDINFO_A)) return; @@ -3414,9 +3375,6 @@ void rtw_coex_query_bt_hid_list(struct rtw_dev *rtwdev) u8 i, handle; bool complete; - if (!rtwdev->efuse.btcoex) - return; - if (!chip->wl_mimo_ps_support || coex_stat->wl_under_ips || (coex_stat->wl_under_lps && !coex_stat->wl_force_lps_ctrl)) return; @@ -3450,9 +3408,6 @@ void rtw_coex_wl_fwdbginfo_notify(struct rtw_dev *rtwdev, u8 *buf, u8 length) u8 val; int i; - if (!rtwdev->efuse.btcoex) - return; - rtw_dbg(rtwdev, RTW_DBG_COEX, "[BTCoex], WiFi Fw Dbg info = %8ph (len = %d)\n", buf, length); @@ -3479,9 +3434,6 @@ void rtw_coex_wl_fwdbginfo_notify(struct rtw_dev *rtwdev, u8 *buf, u8 length) void rtw_coex_wl_status_change_notify(struct rtw_dev *rtwdev, u32 type) { - if (!rtwdev->efuse.btcoex) - return; - rtw_coex_run_coex(rtwdev, COEX_RSN_WLSTATUS); } @@ -3489,9 +3441,6 @@ void rtw_coex_wl_status_check(struct rtw_dev *rtwdev) { struct rtw_coex_stat *coex_stat = &rtwdev->coex.stat; - if (!rtwdev->efuse.btcoex) - return; - if ((coex_stat->wl_under_lps && !coex_stat->wl_force_lps_ctrl) || coex_stat->wl_under_ips) return; @@ -3505,9 +3454,6 @@ void rtw_coex_bt_relink_work(struct work_struct *work) coex.bt_relink_work.work); struct rtw_coex_stat *coex_stat = &rtwdev->coex.stat; - if (!rtwdev->efuse.btcoex) - return; - mutex_lock(&rtwdev->mutex); coex_stat->bt_setup_link = false; rtw_coex_run_coex(rtwdev, COEX_RSN_WLSTATUS); @@ -3520,9 +3466,6 @@ void rtw_coex_bt_reenable_work(struct work_struct *work) coex.bt_reenable_work.work); struct rtw_coex_stat *coex_stat = &rtwdev->coex.stat; - if (!rtwdev->efuse.btcoex) - return; - mutex_lock(&rtwdev->mutex); coex_stat->bt_reenable = false; mutex_unlock(&rtwdev->mutex); @@ -3535,9 +3478,6 @@ void rtw_coex_defreeze_work(struct work_struct *work) struct rtw_coex *coex = &rtwdev->coex; struct rtw_coex_stat *coex_stat = &rtwdev->coex.stat; - if (!rtwdev->efuse.btcoex) - return; - mutex_lock(&rtwdev->mutex); coex->freeze = false; coex_stat->wl_hi_pri_task1 = false; @@ -3551,9 +3491,6 @@ void rtw_coex_wl_remain_work(struct work_struct *work) coex.wl_remain_work.work); struct rtw_coex_stat *coex_stat = &rtwdev->coex.stat; - if (!rtwdev->efuse.btcoex) - return; - mutex_lock(&rtwdev->mutex); coex_stat->wl_gl_busy = test_bit(RTW_FLAG_BUSY_TRAFFIC, rtwdev->flags); rtw_coex_run_coex(rtwdev, COEX_RSN_WLSTATUS); @@ -3566,9 +3503,6 @@ void rtw_coex_bt_remain_work(struct work_struct *work) coex.bt_remain_work.work); struct rtw_coex_stat *coex_stat = &rtwdev->coex.stat; - if (!rtwdev->efuse.btcoex) - return; - mutex_lock(&rtwdev->mutex); coex_stat->bt_inq_remain = coex_stat->bt_inq_page; rtw_coex_run_coex(rtwdev, COEX_RSN_BTSTATUS); @@ -3581,9 +3515,6 @@ void rtw_coex_wl_connecting_work(struct work_struct *work) coex.wl_connecting_work.work); struct rtw_coex_stat *coex_stat = &rtwdev->coex.stat; - if (!rtwdev->efuse.btcoex) - return; - mutex_lock(&rtwdev->mutex); coex_stat->wl_connecting = false; rtw_dbg(rtwdev, RTW_DBG_COEX, "[BTCoex], WL connecting stop!!\n"); @@ -3597,9 +3528,6 @@ void rtw_coex_bt_multi_link_remain_work(struct work_struct *work) coex.bt_multi_link_remain_work.work); struct rtw_coex_stat *coex_stat = &rtwdev->coex.stat; - if (!rtwdev->efuse.btcoex) - return; - mutex_lock(&rtwdev->mutex); coex_stat->bt_multi_link_remain = false; mutex_unlock(&rtwdev->mutex); @@ -3611,9 +3539,6 @@ void rtw_coex_wl_ccklock_work(struct work_struct *work) coex.wl_ccklock_work.work); struct rtw_coex_stat *coex_stat = &rtwdev->coex.stat; - if (!rtwdev->efuse.btcoex) - return; - mutex_lock(&rtwdev->mutex); coex_stat->wl_cck_lock = false; mutex_unlock(&rtwdev->mutex); @@ -4009,9 +3934,6 @@ void rtw_coex_display_coex_info(struct rtw_dev *rtwdev, struct seq_file *m) u32 lte_coex = 0, bt_coex = 0; int i; - if (!rtwdev->efuse.btcoex) - return; - score_board_BW = rtw_coex_read_scbd(rtwdev); score_board_WB = coex_stat->score_board; wl_reg_6c0 = rtw_read32(rtwdev, REG_BT_COEX_TABLE0); From 22dc11c8e19f654642ee4ff98adf4a41cd098fe5 Mon Sep 17 00:00:00 2001 From: Bitterblue Smith Date: Wed, 1 Jan 2025 17:31:00 +0200 Subject: [PATCH 113/193] 8814a: Make path C work again Needed after 2fbf72599d05145124edb0530e1786109215320c. Signed-off-by: Bitterblue Smith --- rtw8814a.c | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/rtw8814a.c b/rtw8814a.c index b6b65c3a..7ffb6985 100644 --- a/rtw8814a.c +++ b/rtw8814a.c @@ -1752,6 +1752,16 @@ static void rtw8814a_coex_cfg_init(struct rtw_dev *rtwdev) { } +static void rtw8814a_coex_cfg_ant_switch(struct rtw_dev *rtwdev, u8 ctrl_type, + u8 pos_type) +{ + /* Override rtw_coex_coex_ctrl_owner(). RF path C does not + * function when BIT_LTE_MUX_CTRL_PATH is set. + */ + rtw_write8_clr(rtwdev, REG_SYS_SDIO_CTRL + 3, + BIT_LTE_MUX_CTRL_PATH >> 24); +} + static void rtw8814a_coex_cfg_gnt_fix(struct rtw_dev *rtwdev) { } @@ -1762,6 +1772,11 @@ static void rtw8814a_coex_cfg_gnt_debug(struct rtw_dev *rtwdev) static void rtw8814a_coex_cfg_rfe_type(struct rtw_dev *rtwdev) { + struct rtw_coex *coex = &rtwdev->coex; + struct rtw_coex_rfe *coex_rfe = &coex->rfe; + + /* Only needed to make rtw8814a_coex_cfg_ant_switch() run. */ + coex_rfe->ant_switch_exist = true; } static void rtw8814a_coex_cfg_wl_tx_power(struct rtw_dev *rtwdev, u8 wl_pwr) @@ -2077,7 +2092,7 @@ static const struct rtw_chip_ops rtw8814a_ops = { .fill_txdesc_checksum = rtw8814a_fill_txdesc_checksum, .coex_set_init = rtw8814a_coex_cfg_init, - .coex_set_ant_switch = NULL, + .coex_set_ant_switch = rtw8814a_coex_cfg_ant_switch, .coex_set_gnt_fix = rtw8814a_coex_cfg_gnt_fix, .coex_set_gnt_debug = rtw8814a_coex_cfg_gnt_debug, .coex_set_rfe_type = rtw8814a_coex_cfg_rfe_type, From 1cc700d11f6826867972a2b1283bf11c37cdf498 Mon Sep 17 00:00:00 2001 From: Bitterblue Smith Date: Mon, 6 Jan 2025 17:30:46 +0200 Subject: [PATCH 114/193] wifi: rtw88: Use brightness_set_blocking for SDIO as well It seems SDIO needs this too, not just USB. https://github.com/lwfinger/rtw88/issues/283 Signed-off-by: Bitterblue Smith --- main.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/main.c b/main.c index 09a3bd9b..ffcc75c4 100644 --- a/main.c +++ b/main.c @@ -2364,10 +2364,10 @@ static void rtw_led_init(struct rtw_dev *rtwdev) if (!rtwdev->chip->ops->led_set) return; - if (rtw_hci_type(rtwdev) == RTW_HCI_TYPE_USB) - led->brightness_set_blocking = rtw_led_set_blocking; - else + if (rtw_hci_type(rtwdev) == RTW_HCI_TYPE_PCIE) led->brightness_set = rtwdev->chip->ops->led_set; + else + led->brightness_set_blocking = rtw_led_set_blocking; snprintf(rtwdev->led_name, sizeof(rtwdev->led_name), "rtw88-%s", dev_name(rtwdev->dev)); From 386382ace137f5209e8e83a4cf2e044bf52e8b38 Mon Sep 17 00:00:00 2001 From: Bitterblue Smith Date: Tue, 7 Jan 2025 20:24:57 +0200 Subject: [PATCH 115/193] wifi: rtw88: usb: Prevent TX URB use after free The TX URB is freed in rtw_usb_write_port() right after usb_submit_urb() but the completion functions rtw_usb_write_port_tx_complete() and rtw_usb_write_port_complete() use the URB some time later. URBs are reference counted and in my tests this URB's reference count reaches 0 only after the completion functions return, but still, it's not correct. Free the URB when it's not needed anymore, at the end of the completion functions. Signed-off-by: Bitterblue Smith --- usb.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/usb.c b/usb.c index 6034c9c1..273bdf25 100644 --- a/usb.c +++ b/usb.c @@ -303,6 +303,7 @@ static void rtw_usb_write_port_tx_complete(struct urb *urb) } kfree(txcb); + usb_free_urb(urb); } static int qsel_to_ep(struct rtw_usb *rtwusb, unsigned int qsel) @@ -335,8 +336,6 @@ static int rtw_usb_write_port(struct rtw_dev *rtwdev, u8 qsel, struct sk_buff *s urb->transfer_flags |= URB_ZERO_PACKET; ret = usb_submit_urb(urb, GFP_ATOMIC); - usb_free_urb(urb); - return ret; } @@ -447,6 +446,7 @@ static void rtw_usb_write_port_complete(struct urb *urb) struct sk_buff *skb = urb->context; dev_kfree_skb_any(skb); + usb_free_urb(urb); } static int rtw_usb_write_data(struct rtw_dev *rtwdev, From 58638cb909377bed524ac9aad0ce7cefc1a037da Mon Sep 17 00:00:00 2001 From: morrownr <69053122+morrownr@users.noreply.github.com> Date: Sun, 12 Jan 2025 12:46:11 -0600 Subject: [PATCH 116/193] Update README.md --- README.md | 28 +++------------------------- 1 file changed, 3 insertions(+), 25 deletions(-) diff --git a/README.md b/README.md index f939161c..53f2e47d 100644 --- a/README.md +++ b/README.md @@ -221,38 +221,16 @@ See section `Installation with SecureBoot for All Distros`. ## FAQ -Below is a set Frequently Asked Questions when using this repository. +Below are some Frequently Asked Questions: --- -### Q1: My driver builds and loads correctly, but fails to work properly. Can you help me? -When you have problems where the driver builds and loads correctly, but it fails to work, a GitHub -issue on this repository is **NOT** the place to report it. - -We have no idea about the internal workings of any of the chips, and the Realtek engineers who do will not read these issues. To reach them, send E-mail to [linux-wireless@vger.kernel.org](mailto:linux-wireless@vger.kernel.org). - -Be sure to include a detailed description of any messages in the kernel logs and any steps that you have taken to analyze or fix the problem. If your description is not complete, you are unlikely to get the help you need. NOTE: E-mail sent to that mailing list MUST be plain text. HTML mail will be rejected. - -Start with this page for guidance: https://wireless.wiki.kernel.org/en/users/support - ---- - -### Q2: I'm using Ubuntu, and the build failed. What do I do? -Ubuntu often modifies kernel APIs, which can cause build issues. You'll need to manually adjust the source code or look for solutions specific to your distribution. We cannot support these types of issues. - ---- - -### Q3: Is Secure Boot supported? +### Q1: Is Secure Boot supported? Yes, this repository provides a way to sign the kernel modules to be compatible with Secure Boot. [Check out the Installation with SecureBoot section](#installation-with-secureboot-). --- -### Q4: My card isn't listed. Can I request a feature? -For feature requests like supporting a new card, you should reach out to Realtek engineers via E-mail at [linux-wireless@vger.kernel.org](mailto:linux-wireless@vger.kernel.org). - ---- - -### Q5: How to remove this driver if it doesn't work as expected? +### Q2: How to remove this driver if it doesn't work as expected? Run this command in the rtw88 source directory and then the rtw88 driver will be unloaded and removed. `sudo make uninstall` From 9c92a4f3bf947016b7c339f9e9f2644df220e25e Mon Sep 17 00:00:00 2001 From: Fiona Klute Date: Mon, 6 Jan 2025 15:54:34 +0200 Subject: [PATCH 117/193] wifi: rtw88: sdio: Fix disconnection after beacon loss This is the equivalent of commit 28818b4d871b ("wifi: rtw88: usb: Fix disconnection after beacon loss") for SDIO chips. Tested on Pinephone (RTL8723CS), random disconnections became rare, instead of a frequent nuisance. Cc: stable@vger.kernel.org Signed-off-by: Fiona Klute Tested-by: Vasily Khoruzhick # Tested on Pinebook Acked-by: Ping-Ke Shih Signed-off-by: Ping-Ke Shih Link: https://patch.msgid.link/20250106135434.35936-1-fiona.klute@gmx.de --- sdio.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/sdio.c b/sdio.c index 7b053dbb..dc22bb76 100644 --- a/sdio.c +++ b/sdio.c @@ -1192,6 +1192,8 @@ static void rtw_sdio_indicate_tx_status(struct rtw_dev *rtwdev, struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); struct ieee80211_hw *hw = rtwdev->hw; + skb_pull(skb, rtwdev->chip->tx_pkt_desc_sz); + /* enqueue to wait for tx report */ if (info->flags & IEEE80211_TX_CTL_REQ_TX_STATUS) { rtw_tx_report_enqueue(rtwdev, skb, tx_data->sn); From c56536cfa522b42cfa73c2c4332000e6aa5bcf97 Mon Sep 17 00:00:00 2001 From: Bitterblue Smith Date: Mon, 20 Jan 2025 22:24:05 +0200 Subject: [PATCH 118/193] wifi: rtw88: Fix RX aggregation settings for RTL8723DS Use the same RX aggregation size and timeout used by the out-of-tree RTL8723DS driver. Also set mystery bit 31 of REG_RXDMA_AGG_PG_TH. This improves the RX speed from ~44 Mbps to ~67 Mbps. Signed-off-by: Bitterblue Smith --- sdio.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/sdio.c b/sdio.c index dc22bb76..3b53fd86 100644 --- a/sdio.c +++ b/sdio.c @@ -677,12 +677,20 @@ static void rtw_sdio_enable_rx_aggregation(struct rtw_dev *rtwdev) { u8 size, timeout; - if (rtw_chip_wcpu_11n(rtwdev)) { + switch (rtwdev->chip->id) { + case RTW_CHIP_TYPE_8703B: size = 0x6; timeout = 0x6; - } else { + break; + case RTW_CHIP_TYPE_8723D: + size = 0xa; + timeout = 0x3; + rtw_write8_set(rtwdev, REG_RXDMA_AGG_PG_TH + 3, BIT(7)); + break; + default: size = 0xff; timeout = 0x1; + break; } /* Make the firmware honor the size limit configured below */ From 501b12e22da68eedb84d84e61339c8987a2c3fbb Mon Sep 17 00:00:00 2001 From: Bitterblue Smith Date: Tue, 21 Jan 2025 17:52:45 +0200 Subject: [PATCH 119/193] wifi: rtw88: Don't use static local variable in rtw8821c_set_tx_power_index_by_rate Some users want to plug two identical USB devices at the same time. This static variable could theoretically cause them to use incorrect TX power values. Move the variable to the caller and pass a pointer to it to rtw8821c_set_tx_power_index_by_rate(). Signed-off-by: Bitterblue Smith --- rtw8821c.c | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/rtw8821c.c b/rtw8821c.c index 2551d2af..4ff4a4a2 100644 --- a/rtw8821c.c +++ b/rtw8821c.c @@ -681,11 +681,11 @@ static void query_phy_status(struct rtw_dev *rtwdev, u8 *phy_status, } static void -rtw8821c_set_tx_power_index_by_rate(struct rtw_dev *rtwdev, u8 path, u8 rs) +rtw8821c_set_tx_power_index_by_rate(struct rtw_dev *rtwdev, u8 path, + u8 rs, u32 *phy_pwr_idx) { struct rtw_hal *hal = &rtwdev->hal; static const u32 offset_txagc[2] = {0x1d00, 0x1d80}; - static u32 phy_pwr_idx; u8 rate, rate_idx, pwr_index, shift; int j; @@ -693,12 +693,12 @@ rtw8821c_set_tx_power_index_by_rate(struct rtw_dev *rtwdev, u8 path, u8 rs) rate = rtw_rate_section[rs][j]; pwr_index = hal->tx_pwr_tbl[path][rate]; shift = rate & 0x3; - phy_pwr_idx |= ((u32)pwr_index << (shift * 8)); + *phy_pwr_idx |= ((u32)pwr_index << (shift * 8)); if (shift == 0x3 || rate == DESC_RATEVHT1SS_MCS9) { rate_idx = rate & 0xfc; rtw_write32(rtwdev, offset_txagc[path] + rate_idx, - phy_pwr_idx); - phy_pwr_idx = 0; + *phy_pwr_idx); + *phy_pwr_idx = 0; } } } @@ -706,6 +706,7 @@ rtw8821c_set_tx_power_index_by_rate(struct rtw_dev *rtwdev, u8 path, u8 rs) static void rtw8821c_set_tx_power_index(struct rtw_dev *rtwdev) { struct rtw_hal *hal = &rtwdev->hal; + u32 phy_pwr_idx = 0; int rs, path; for (path = 0; path < hal->rf_path_num; path++) { @@ -713,7 +714,8 @@ static void rtw8821c_set_tx_power_index(struct rtw_dev *rtwdev) if (rs == RTW_RATE_SECTION_HT_2S || rs == RTW_RATE_SECTION_VHT_2S) continue; - rtw8821c_set_tx_power_index_by_rate(rtwdev, path, rs); + rtw8821c_set_tx_power_index_by_rate(rtwdev, path, rs, + &phy_pwr_idx); } } } From 21a3fa7ec11a0cbb3be14145f45cdca35c3d3217 Mon Sep 17 00:00:00 2001 From: Bitterblue Smith Date: Tue, 21 Jan 2025 17:48:56 +0200 Subject: [PATCH 120/193] wifi: rtw88: Don't use static local variable in rtw8822b_set_tx_power_index_by_rate Some users want to plug two identical USB devices at the same time. This static variable could theoretically cause them to use incorrect TX power values. Move the variable to the caller and pass a pointer to it to rtw8822b_set_tx_power_index_by_rate(). Signed-off-by: Bitterblue Smith --- rtw8822b.c | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/rtw8822b.c b/rtw8822b.c index 72251d3e..900699e2 100644 --- a/rtw8822b.c +++ b/rtw8822b.c @@ -935,11 +935,11 @@ static void query_phy_status(struct rtw_dev *rtwdev, u8 *phy_status, } static void -rtw8822b_set_tx_power_index_by_rate(struct rtw_dev *rtwdev, u8 path, u8 rs) +rtw8822b_set_tx_power_index_by_rate(struct rtw_dev *rtwdev, u8 path, + u8 rs, u32 *phy_pwr_idx) { struct rtw_hal *hal = &rtwdev->hal; static const u32 offset_txagc[2] = {0x1d00, 0x1d80}; - static u32 phy_pwr_idx; u8 rate, rate_idx, pwr_index, shift; int j; @@ -947,12 +947,12 @@ rtw8822b_set_tx_power_index_by_rate(struct rtw_dev *rtwdev, u8 path, u8 rs) rate = rtw_rate_section[rs][j]; pwr_index = hal->tx_pwr_tbl[path][rate]; shift = rate & 0x3; - phy_pwr_idx |= ((u32)pwr_index << (shift * 8)); + *phy_pwr_idx |= ((u32)pwr_index << (shift * 8)); if (shift == 0x3) { rate_idx = rate & 0xfc; rtw_write32(rtwdev, offset_txagc[path] + rate_idx, - phy_pwr_idx); - phy_pwr_idx = 0; + *phy_pwr_idx); + *phy_pwr_idx = 0; } } } @@ -960,11 +960,13 @@ rtw8822b_set_tx_power_index_by_rate(struct rtw_dev *rtwdev, u8 path, u8 rs) static void rtw8822b_set_tx_power_index(struct rtw_dev *rtwdev) { struct rtw_hal *hal = &rtwdev->hal; + u32 phy_pwr_idx = 0; int rs, path; for (path = 0; path < hal->rf_path_num; path++) { for (rs = 0; rs < RTW_RATE_SECTION_HT_3S; rs++) - rtw8822b_set_tx_power_index_by_rate(rtwdev, path, rs); + rtw8822b_set_tx_power_index_by_rate(rtwdev, path, rs, + &phy_pwr_idx); } } From 2a0cfe779dbc03f4c17155ef087587d526aa49f0 Mon Sep 17 00:00:00 2001 From: Bitterblue Smith Date: Fri, 31 Jan 2025 23:24:39 +0200 Subject: [PATCH 121/193] wifi: rtw88: Handle RTL8723D with blank efuse Use default values for TX power, antenna configuration, and crystal cap if the chip's efuse is missing these things. RTL8723D can use the same default values as RTL8703B, so simply move the code from rtl8703b_read_efuse() to __rtl8723x_read_efuse(). Link: https://github.com/lwfinger/rtw88/issues/157 Signed-off-by: Bitterblue Smith --- rtw8703b.c | 60 ------------------------------------------------------ rtw8723x.c | 59 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 59 insertions(+), 60 deletions(-) diff --git a/rtw8703b.c b/rtw8703b.c index 8e0de023..52ff178d 100644 --- a/rtw8703b.c +++ b/rtw8703b.c @@ -520,15 +520,6 @@ static const struct rtw_rqpn rqpn_table_8703b[] = { RTW_DMA_MAPPING_EXTRA, RTW_DMA_MAPPING_HIGH}, }; -/* Default power index table for RTL8703B, used if EFUSE does not - * contain valid data. Replaces EFUSE data from offset 0x10 (start of - * txpwr_idx_table). - */ -static const u8 rtw8703b_txpwr_idx_table[] = { - 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, - 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x02 -}; - static void try_mac_from_devicetree(struct rtw_dev *rtwdev) { struct device_node *node = rtwdev->dev->of_node; @@ -555,15 +546,9 @@ static void try_mac_from_devicetree(struct rtw_dev *rtwdev) } } -#define DBG_EFUSE_FIX(rtwdev, name) \ - rtw_dbg(rtwdev, RTW_DBG_EFUSE, "Fixed invalid EFUSE value: " \ - # name "=0x%x\n", rtwdev->efuse.name) - static int rtw8703b_read_efuse(struct rtw_dev *rtwdev, u8 *log_map) { struct rtw_efuse *efuse = &rtwdev->efuse; - u8 *pwr = (u8 *)efuse->txpwr_idx_table; - bool valid = false; int ret; ret = rtw8723x_read_efuse(rtwdev, log_map); @@ -573,51 +558,6 @@ static int rtw8703b_read_efuse(struct rtw_dev *rtwdev, u8 *log_map) if (!is_valid_ether_addr(efuse->addr)) try_mac_from_devicetree(rtwdev); - /* If TX power index table in EFUSE is invalid, fall back to - * built-in table. - */ - for (int i = 0; i < ARRAY_SIZE(rtw8703b_txpwr_idx_table); i++) - if (pwr[i] != 0xff) { - valid = true; - break; - } - if (!valid) { - for (int i = 0; i < ARRAY_SIZE(rtw8703b_txpwr_idx_table); i++) - pwr[i] = rtw8703b_txpwr_idx_table[i]; - rtw_dbg(rtwdev, RTW_DBG_EFUSE, - "Replaced invalid EFUSE TX power index table."); - rtw8723x_debug_txpwr_limit(rtwdev, - efuse->txpwr_idx_table, 2); - } - - /* Override invalid antenna settings. */ - if (efuse->bt_setting == 0xff) { - /* shared antenna */ - efuse->bt_setting |= BIT(0); - /* RF path A */ - efuse->bt_setting &= ~BIT(6); - DBG_EFUSE_FIX(rtwdev, bt_setting); - } - - /* Override invalid board options: The coex code incorrectly - * assumes that if bits 6 & 7 are set the board doesn't - * support coex. Regd is also derived from rf_board_option and - * should be 0 if there's no valid data. - */ - if (efuse->rf_board_option == 0xff) { - efuse->regd = 0; - efuse->rf_board_option &= GENMASK(5, 0); - DBG_EFUSE_FIX(rtwdev, rf_board_option); - } - - /* Override invalid crystal cap setting, default comes from - * vendor driver. Chip specific. - */ - if (efuse->crystal_cap == 0xff) { - efuse->crystal_cap = 0x20; - DBG_EFUSE_FIX(rtwdev, crystal_cap); - } - return 0; } diff --git a/rtw8723x.c b/rtw8723x.c index 3129493d..e2127d33 100644 --- a/rtw8723x.c +++ b/rtw8723x.c @@ -69,6 +69,9 @@ static void __rtw8723x_lck(struct rtw_dev *rtwdev) #define DBG_EFUSE_2BYTE(rtwdev, map, name) \ rtw_dbg(rtwdev, RTW_DBG_EFUSE, # name "=0x%02x%02x\n", \ (map)->name[0], (map)->name[1]) +#define DBG_EFUSE_FIX(rtwdev, name) \ + rtw_dbg(rtwdev, RTW_DBG_EFUSE, "Fixed invalid EFUSE value: " \ + # name "=0x%x\n", rtwdev->efuse.name) static void rtw8723xe_efuse_debug(struct rtw_dev *rtwdev, struct rtw8723x_efuse *map) @@ -238,10 +241,21 @@ static void rtw8723xs_efuse_parsing(struct rtw_efuse *efuse, ether_addr_copy(efuse->addr, map->s.mac_addr); } +/* Default power index table for RTL8703B/RTL8723D, used if EFUSE does + * not contain valid data. Replaces EFUSE data from offset 0x10 (start + * of txpwr_idx_table). + */ +static const u8 rtw8723x_txpwr_idx_table[] = { + 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, + 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x02 +}; + static int __rtw8723x_read_efuse(struct rtw_dev *rtwdev, u8 *log_map) { struct rtw_efuse *efuse = &rtwdev->efuse; + u8 *pwr = (u8 *)efuse->txpwr_idx_table; struct rtw8723x_efuse *map; + bool valid = false; int i; map = (struct rtw8723x_efuse *)log_map; @@ -279,6 +293,51 @@ static int __rtw8723x_read_efuse(struct rtw_dev *rtwdev, u8 *log_map) return -EOPNOTSUPP; } + /* If TX power index table in EFUSE is invalid, fall back to + * built-in table. + */ + for (i = 0; i < ARRAY_SIZE(rtw8723x_txpwr_idx_table); i++) + if (pwr[i] != 0xff) { + valid = true; + break; + } + if (!valid) { + for (i = 0; i < ARRAY_SIZE(rtw8723x_txpwr_idx_table); i++) + pwr[i] = rtw8723x_txpwr_idx_table[i]; + rtw_dbg(rtwdev, RTW_DBG_EFUSE, + "Replaced invalid EFUSE TX power index table."); + rtw8723x_debug_txpwr_limit(rtwdev, + efuse->txpwr_idx_table, 2); + } + + /* Override invalid antenna settings. */ + if (efuse->bt_setting == 0xff) { + /* shared antenna */ + efuse->bt_setting |= BIT(0); + /* RF path A */ + efuse->bt_setting &= ~BIT(6); + DBG_EFUSE_FIX(rtwdev, bt_setting); + } + + /* Override invalid board options: The coex code incorrectly + * assumes that if bits 6 & 7 are set the board doesn't + * support coex. Regd is also derived from rf_board_option and + * should be 0 if there's no valid data. + */ + if (efuse->rf_board_option == 0xff) { + efuse->regd = 0; + efuse->rf_board_option &= GENMASK(5, 0); + DBG_EFUSE_FIX(rtwdev, rf_board_option); + } + + /* Override invalid crystal cap setting, default comes from + * vendor driver. Chip specific. + */ + if (efuse->crystal_cap == 0xff) { + efuse->crystal_cap = 0x20; + DBG_EFUSE_FIX(rtwdev, crystal_cap); + } + return 0; } From b6aa1915a233bf6d2e7dacbfd114f6e6994f4daa Mon Sep 17 00:00:00 2001 From: Zenm Chen Date: Mon, 20 Jan 2025 22:43:04 +0800 Subject: [PATCH 122/193] Update README.md --- README.md | 111 +++++++++++++++++++++++++----------------------------- 1 file changed, 52 insertions(+), 59 deletions(-) diff --git a/README.md b/README.md index 53f2e47d..f21e35a3 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,7 @@ # rtw88 downstream 🐧 ### This is a downstream repo with a primary purpose of supporting development, testing and maintenance for the Realtek rtw88 series of WiFi 5 drivers in the Linux kernel. -The most recent addition to this repo is the driver for the rtw8814au chipset. Testing is needed so if you have an adapter based on the rtw8814au chipset, please test and report. +The most recent addition to this repo is the driver for the RTL8814AU chipset. Testing is needed so if you have an adapter based on the RTL8814AU chipset, please test and report. 🌟 The code in this repo stays in sync with the `wireless-next` repository, with additional changes to accommodate kernel API changes over time. @@ -14,10 +14,10 @@ Compatible with **Linux kernel versions 5.4 and newer** as long as your distro h #### Supported Chipsets -- **USB** : RTW8814AU, RTW8812AU, RTW8821AU, RTW8811AU, RTW8822BU, RTW8812BU -- **USB** : RTW8822CU, RTW8812CU, RTW8821CU, RTW8811CU, RTW8723DU -- **PCIe**: RTW8822BE, RTW8822CE, RTW8821CE, RTW8723DE -- **SDIO**: RTW8822BS, RTW8822CS, RTW8821CS, RTW8723DS +- **PCIe**: RTL8723DE, RTL8821CE, RTL8822BE, RTL8822CE +- **SDIO**: RTL8723CS, RTL8723DS, RTL8821CS, RTL8822BS, RTL8822CS +- **USB** : RTL8723DU, RTL8811AU, RTL8811CU, RTL8812AU, RTL8812BU, RTL8812CU +- **USB** : RTL8814AU, RTL8821AU, RTL8821CU, RTL8822BU, RTL8822CU --- @@ -25,6 +25,7 @@ Compatible with **Linux kernel versions 5.4 and newer** as long as your distro h Report problems in Issues after you have checked the [FAQ](#faq) at bottom of this README. ⚠️ If you see a line such as: + `make[1]: *** /lib/modules/5.17.5-300.fc36.x86_64/build: No such file or directory.` **Stop.** This indicates **you have NOT installed the kernel headers.** @@ -41,15 +42,15 @@ Below are prerequisites for common Linux distributions __before__ you do a [basi sudo apt update && sudo apt upgrade ``` ```bash -sudo apt install make gcc linux-headers-$(uname -r) build-essential git +sudo apt install linux-headers-$(uname -r) build-essential git ``` #### Fedora ```bash -sudo dnf install kernel-headers kernel-devel +sudo dnf update ``` ```bash -sudo dnf group install "C Development Tools and Libraries" +sudo dnf install kernel-devel git ``` #### openSUSE @@ -59,21 +60,19 @@ sudo zypper install make gcc kernel-devel kernel-default-devel git libopenssl-de #### Arch ```bash -git clone https://aur.archlinux.org/rtw88-dkms-git.git +sudo pacman -Syu ``` ```bash -cd rtw88-dkms-git -``` -```bash -makepkg -sri +sudo pacman -Sy base-devel git linux-firmware ``` +Remember to install the corresponding [kernel headers](https://archlinux.org/packages/?q=Headers+and+scripts+for+building+modules) which is also needed for compilation. #### Raspberry Pi OS ```bash sudo apt update && sudo apt upgrade ``` ```bash -sudo apt install -y raspberrypi-kernel-headers build-essential bc git +sudo apt install -y raspberrypi-kernel-headers build-essential git ``` --- @@ -91,6 +90,21 @@ make ```bash sudo make install ``` +```bash +sudo make install_fw +``` +--- + +### Basic Installation for Arch-based Distros 🛠 +```bash +git clone https://aur.archlinux.org/rtw88-dkms-git.git +``` +```bash +cd rtw88-dkms-git +``` +```bash +makepkg -si +``` --- ### Installation with SecureBoot for All Distros 🔒 @@ -104,6 +118,9 @@ cd rtw88 make ``` ```bash +sudo make install_fw +``` +```bash sudo make sign-install ``` You will be prompted a password, **please keep it in mind and use it in next steps.** @@ -111,7 +128,7 @@ You will be prompted a password, **please keep it in mind and use it in next ste Reboot to activate the new installed module, then in the MOK managerment screen: 1. Select "Enroll key" and enroll the key created by above sign-install step 2. When promted, enter the password you entered when create sign key. -3. If you enter wrong password, your computer won't not bebootable. In this case, +3. If you enter wrong password, your computer won't be bootable. In this case, use the BOOT menu from your BIOS, to boot into your OS then do below steps: ```bash sudo mokutil --reset @@ -152,45 +169,7 @@ sudo modprobe rtw_8723de # This loads the module # Only a single modprobe call is required to load. ``` -### 4. Driver Parameter Configuration (options) 📝 - -Example for chipset RTL8814AU and driver name rtw_8814au: - -Note: the driver names in the rtw88 in the Linux Mainline kernel are slightly different: rtw88_8814au - -```bash -sudo nano /etc/modprobe.d/rtw_8814au.conf -``` - -Note: Change rtw_8814au in the above to the name of the driver you wish to modify. - -In the empty file, paste the following: - -```bash -options rtw_8814au switch_usb_mode=N - -``` - -See below for an explanation of the above parameter and for information about other parameters. - -The available parameter (option) for USB 3 devices is: - -switch_usb_mode= - -Set to N to disable switching to USB 3 mode to avoid potential interference in the 2.4 GHz band (default: Y) (bool). This parameter (option) applies to the USB 3 capable devices: RTL8814AU (rtw_8814au), RTL8822CU (rtw_8822cu), RTL8812CU (rtw_8822cu), RTL8822BU (rtw_8822bu), RTL8812BU (rtw_8822bu), and RTL8812AU (rtw_8812au). It's okay to leave the parameter on even when plugging the device into a USB 2 port because it will try to switch to USB 3 mode only once. - -The available options for rtw_pci are: - -disable_msi -disable_aspm - -The available options for rtw_core are: - -disable_lps_deep -support_bf -debug_mask - -### 5. Kernel Updates 🔄 +### 4. Kernel Updates 🔄 When your kernel updates, run: ```bash cd ~/rtw88 @@ -204,15 +183,13 @@ git pull make ``` -Secureboot disabled: - ``` sudo make install +or +sudo make sign-install ``` -Secureboot enabled: -See section `Installation with SecureBoot for All Distros`. 💡 **Remember, every newly installed kernel requires this step - no exceptions**. If the kernel update means that you have no network, skip the 'git pull' and build the driver as it is, but run `git pull` once you have connectivity, and rebuild if any updates were pulled. @@ -226,7 +203,7 @@ Below are some Frequently Asked Questions: --- ### Q1: Is Secure Boot supported? -Yes, this repository provides a way to sign the kernel modules to be compatible with Secure Boot. [Check out the Installation with SecureBoot section](#installation-with-secureboot-). +Yes, this repository provides a way to sign the kernel modules to be compatible with Secure Boot. [Check out the Installation with SecureBoot section](#installation-with-secureboot-for-all-distros-). --- @@ -235,4 +212,20 @@ Run this command in the rtw88 source directory and then the rtw88 driver will be `sudo make uninstall` +For Arch-based distro users, run + +`sudo pacman -Rn rtw88-dkms-git` + +--- + +### Q3: My wifi adapter is plugged in an USB 3 port, how can I keep it in USB 2 mode to avoid potential interference in 2.4 GHz band? +The module `rtw_usb` has a parameter named `switch_usb_mode` which can enable or disable USB mode switching, setting it to "N" will keep your adapter in USB 2 mode. You can simply run the command below, unplug the adapter, reboot your computer, replug the adapter back and then your adapter will be in USB 2 mode. + +`sudo sh -c 'echo options rtw_usb switch_usb_mode=N > /etc/modprobe.d/rtw88.conf'` + +--- + +### Q4: My wifi adapter still doesn't work after installing this driver and `lsusb` shows it is in CD-ROM mode, what should I do? +Install `usb_modeswitch` which can switch your adapter from CD-ROM mode to Wi-Fi mode and then your wifi adapter should be in Wi-Fi mode after reboot. +--- From 2f5b4cbe42644301ed4e7aa2934e23d7c9addb0c Mon Sep 17 00:00:00 2001 From: Zenm Chen Date: Thu, 23 Jan 2025 03:12:29 +0800 Subject: [PATCH 123/193] Improve firmware handling Changes in this commit: 1. Rename the variable "FIRMWAREDIR" to "FWDIR". 2. Don't install firmware every time "sudo make install" is executed. 3. If /lib/firmware/rtw88 doesn't exist, install the firmware to /lib/firmware/rtw88 directly. 4. If /lib/firmware/rtw88 exists and the firmware inside is not compressed, install the firmware without compression. 5. If /lib/firmware/rtw88 exists and the firmware inside is compressed, use the same method to compress the firmware before installation. --- Makefile | 21 +++++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-) diff --git a/Makefile b/Makefile index 802629f4..5cdd0b80 100644 --- a/Makefile +++ b/Makefile @@ -1,7 +1,7 @@ SHELL := /bin/sh KVER ?= $(if $(KERNELRELEASE),$(KERNELRELEASE),$(shell uname -r)) KSRC ?= $(if $(KERNEL_SRC),$(KERNEL_SRC),/lib/modules/$(KVER)/build) -FIRMWAREDIR := /lib/firmware/rtw88 +FWDIR := /lib/firmware/rtw88 MODLIST := rtw_8723cs rtw_8723de rtw_8723ds rtw_8723du \ rtw_8812au rtw_8814au rtw_8821au rtw_8821ce rtw_8821cs rtw_8821cu \ rtw_8822be rtw_8822bs rtw_8822bu rtw_8822ce rtw_8822cs rtw_8822cu \ @@ -184,7 +184,6 @@ all: install: all @install -D -m 644 -t $(MODDESTDIR) *.ko - @install -D -m 644 -t $(FIRMWAREDIR) firmware/*.bin @install -D -m 644 -t /etc/modprobe.d blacklist-rtw88.conf ifeq ($(COMPRESS_GZIP), y) @@ -200,6 +199,24 @@ endif @depmod $(DEPMOD_ARGS) -a $(KVER) @echo "The rtw88 drivers and firmware files were installed successfully." +install_fw: +ifeq ($(wildcard $(FWDIR)), ) + @install -Dvm 644 -t $(FWDIR) firmware/*.bin +else + @cp -r firmware tmp +ifneq ($(wildcard $(FWDIR)/*.zst), ) + @zstd -fq --rm tmp/*.bin +endif +ifneq ($(wildcard $(FWDIR)/*.xz), ) + @xz -f -C crc32 tmp/*.bin +endif +ifneq ($(wildcard $(FWDIR)/*.gz), ) + @gzip -f tmp/*.bin +endif + @install -Dvm 644 -t $(FWDIR) tmp/* + @rm -rf tmp +endif + uninstall: @for mod in $(MODLIST); do \ rmmod -s $$mod || true; \ From d9e0ac7bda5fdfcd2bea2a7a7b1eaf1b60ca2ae1 Mon Sep 17 00:00:00 2001 From: Bitterblue Smith Date: Fri, 7 Feb 2025 16:22:41 +0200 Subject: [PATCH 124/193] Revert "wifi: rtw88: usb: Prevent TX URB use after free" This reverts commit 386382ace137f5209e8e83a4cf2e044bf52e8b38. Apparently it causes problems: https://github.com/lwfinger/rtw88/issues/305 --- usb.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/usb.c b/usb.c index 273bdf25..6034c9c1 100644 --- a/usb.c +++ b/usb.c @@ -303,7 +303,6 @@ static void rtw_usb_write_port_tx_complete(struct urb *urb) } kfree(txcb); - usb_free_urb(urb); } static int qsel_to_ep(struct rtw_usb *rtwusb, unsigned int qsel) @@ -336,6 +335,8 @@ static int rtw_usb_write_port(struct rtw_dev *rtwdev, u8 qsel, struct sk_buff *s urb->transfer_flags |= URB_ZERO_PACKET; ret = usb_submit_urb(urb, GFP_ATOMIC); + usb_free_urb(urb); + return ret; } @@ -446,7 +447,6 @@ static void rtw_usb_write_port_complete(struct urb *urb) struct sk_buff *skb = urb->context; dev_kfree_skb_any(skb); - usb_free_urb(urb); } static int rtw_usb_write_data(struct rtw_dev *rtwdev, From d5a1a15625d45221c4b5bed0e4c1e16f7c620051 Mon Sep 17 00:00:00 2001 From: Bitterblue Smith Date: Tue, 11 Feb 2025 21:39:45 +0200 Subject: [PATCH 125/193] Add untested rtw8814ae.c for RTL8814AE cards It should work with the current pci.c code. Signed-off-by: Bitterblue Smith --- Makefile | 7 ++++++- README.md | 2 ++ dkms.conf | 42 ++++++++++++++++++++++-------------------- rtw8814ae.c | 31 +++++++++++++++++++++++++++++++ 4 files changed, 61 insertions(+), 21 deletions(-) create mode 100644 rtw8814ae.c diff --git a/Makefile b/Makefile index 5cdd0b80..8a606e2d 100644 --- a/Makefile +++ b/Makefile @@ -3,7 +3,7 @@ KVER ?= $(if $(KERNELRELEASE),$(KERNELRELEASE),$(shell uname -r)) KSRC ?= $(if $(KERNEL_SRC),$(KERNEL_SRC),/lib/modules/$(KVER)/build) FWDIR := /lib/firmware/rtw88 MODLIST := rtw_8723cs rtw_8723de rtw_8723ds rtw_8723du \ - rtw_8812au rtw_8814au rtw_8821au rtw_8821ce rtw_8821cs rtw_8821cu \ + rtw_8812au rtw_8814ae rtw_8814au rtw_8821au rtw_8821ce rtw_8821cs rtw_8821cu \ rtw_8822be rtw_8822bs rtw_8822bu rtw_8822ce rtw_8822cs rtw_8822cu \ rtw_8703b rtw_8723d rtw_8821a rtw_8812a rtw_8814a rtw_8821c rtw_8822b rtw_8822c \ rtw_8723x rtw_88xxa rtw_pci rtw_sdio rtw_usb rtw_core @@ -116,6 +116,11 @@ rtw_8814a-objs := rtw8814a.o rtw8814a_table.o obj-m += rtw_8814au.o rtw_8814au-objs := rtw8814au.o +ifeq ($(CONFIG_PCI), y) +obj-m += rtw_8814ae.o +rtw_8814ae-objs := rtw8814ae.o +endif + obj-m += rtw_8821c.o rtw_8821c-objs := rtw8821c.o rtw8821c_table.o diff --git a/README.md b/README.md index f21e35a3..8e3438a6 100644 --- a/README.md +++ b/README.md @@ -3,6 +3,8 @@ The most recent addition to this repo is the driver for the RTL8814AU chipset. Testing is needed so if you have an adapter based on the RTL8814AU chipset, please test and report. +Update: There is now also a driver for RTL8814AE PCIe cards, ID 10ec:8813. lspci may call it RTL8813AE, same thing. This is completely untested. Please test and report if you still have this card. + 🌟 The code in this repo stays in sync with the `wireless-next` repository, with additional changes to accommodate kernel API changes over time. 📌 **Note**: The `wireless-next` repo contains the code set for the ***next*** kernel version. If kernel 6.X is out, kernel mainline repo is on 6.X+1-rcY, and `wireless-next` targets kernel 6.X+2 material. diff --git a/dkms.conf b/dkms.conf index e5fcf1fb..30005053 100644 --- a/dkms.conf +++ b/dkms.conf @@ -14,26 +14,27 @@ BUILT_MODULE_NAME[6]="rtw_8723x" BUILT_MODULE_NAME[7]="rtw_8812a" BUILT_MODULE_NAME[8]="rtw_8812au" BUILT_MODULE_NAME[9]="rtw_8814a" -BUILT_MODULE_NAME[10]="rtw_8814au" -BUILT_MODULE_NAME[11]="rtw_8821a" -BUILT_MODULE_NAME[12]="rtw_8821au" -BUILT_MODULE_NAME[13]="rtw_8821c" -BUILT_MODULE_NAME[14]="rtw_8821ce" -BUILT_MODULE_NAME[15]="rtw_8821cs" -BUILT_MODULE_NAME[16]="rtw_8821cu" -BUILT_MODULE_NAME[17]="rtw_8822b" -BUILT_MODULE_NAME[18]="rtw_8822be" -BUILT_MODULE_NAME[19]="rtw_8822bs" -BUILT_MODULE_NAME[20]="rtw_8822bu" -BUILT_MODULE_NAME[21]="rtw_8822c" -BUILT_MODULE_NAME[22]="rtw_8822ce" -BUILT_MODULE_NAME[23]="rtw_8822cs" -BUILT_MODULE_NAME[24]="rtw_8822cu" -BUILT_MODULE_NAME[25]="rtw_88xxa" -BUILT_MODULE_NAME[26]="rtw_core" -BUILT_MODULE_NAME[27]="rtw_pci" -BUILT_MODULE_NAME[28]="rtw_sdio" -BUILT_MODULE_NAME[29]="rtw_usb" +BUILT_MODULE_NAME[10]="rtw_8814ae" +BUILT_MODULE_NAME[11]="rtw_8814au" +BUILT_MODULE_NAME[12]="rtw_8821a" +BUILT_MODULE_NAME[13]="rtw_8821au" +BUILT_MODULE_NAME[14]="rtw_8821c" +BUILT_MODULE_NAME[15]="rtw_8821ce" +BUILT_MODULE_NAME[16]="rtw_8821cs" +BUILT_MODULE_NAME[17]="rtw_8821cu" +BUILT_MODULE_NAME[18]="rtw_8822b" +BUILT_MODULE_NAME[19]="rtw_8822be" +BUILT_MODULE_NAME[20]="rtw_8822bs" +BUILT_MODULE_NAME[21]="rtw_8822bu" +BUILT_MODULE_NAME[22]="rtw_8822c" +BUILT_MODULE_NAME[23]="rtw_8822ce" +BUILT_MODULE_NAME[24]="rtw_8822cs" +BUILT_MODULE_NAME[25]="rtw_8822cu" +BUILT_MODULE_NAME[26]="rtw_88xxa" +BUILT_MODULE_NAME[27]="rtw_core" +BUILT_MODULE_NAME[28]="rtw_pci" +BUILT_MODULE_NAME[29]="rtw_sdio" +BUILT_MODULE_NAME[30]="rtw_usb" DEST_MODULE_LOCATION[0]="/updates/dkms/rtw88" DEST_MODULE_LOCATION[1]="/updates/dkms/rtw88" DEST_MODULE_LOCATION[2]="/updates/dkms/rtw88" @@ -64,3 +65,4 @@ DEST_MODULE_LOCATION[26]="/updates/dkms/rtw88" DEST_MODULE_LOCATION[27]="/updates/dkms/rtw88" DEST_MODULE_LOCATION[28]="/updates/dkms/rtw88" DEST_MODULE_LOCATION[29]="/updates/dkms/rtw88" +DEST_MODULE_LOCATION[30]="/updates/dkms/rtw88" diff --git a/rtw8814ae.c b/rtw8814ae.c new file mode 100644 index 00000000..51a87584 --- /dev/null +++ b/rtw8814ae.c @@ -0,0 +1,31 @@ +// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause +/* Copyright(c) 2025 Realtek Corporation + */ + +#include +#include +#include "pci.h" +#include "rtw8814a.h" + +static const struct pci_device_id rtw_8814ae_id_table[] = { + { + PCI_DEVICE(PCI_VENDOR_ID_REALTEK, 0x8813), + .driver_data = (kernel_ulong_t)&rtw8814a_hw_spec + }, + {} +}; +MODULE_DEVICE_TABLE(pci, rtw_8814ae_id_table); + +static struct pci_driver rtw_8814ae_driver = { + .name = "rtw_8814ae", + .id_table = rtw_8814ae_id_table, + .probe = rtw_pci_probe, + .remove = rtw_pci_remove, + .driver.pm = &rtw_pm_ops, + .shutdown = rtw_pci_shutdown, +}; +module_pci_driver(rtw_8814ae_driver); + +MODULE_AUTHOR("Realtek Corporation"); +MODULE_DESCRIPTION("Realtek 802.11ac wireless 8814ae driver"); +MODULE_LICENSE("Dual BSD/GPL"); From e32c796572ee22ae172411fe5c1183921eca498e Mon Sep 17 00:00:00 2001 From: Bitterblue Smith Date: Tue, 11 Feb 2025 22:54:58 +0200 Subject: [PATCH 126/193] wifi: rtw88: pci: Avoid null pointer dereference with RTL8814AE RTL8814AE is still untested, I just remembered this problem. Signed-off-by: Bitterblue Smith --- pci.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/pci.c b/pci.c index e6bb7a2c..2560e696 100644 --- a/pci.c +++ b/pci.c @@ -1461,6 +1461,9 @@ static void rtw_pci_phy_cfg(struct rtw_dev *rtwdev) int i; int ret; + if (!chip->intf_table) + return; + cut = BIT(0) << rtwdev->hal.cut_version; for (i = 0; i < chip->intf_table->n_gen1_para; i++) { From 4f35223f89cd1d4f5775b0fdf4c60b0f316b6266 Mon Sep 17 00:00:00 2001 From: Bitterblue Smith Date: Fri, 14 Feb 2025 17:25:49 +0200 Subject: [PATCH 127/193] Revert "wifi: rtw88: pci: Avoid null pointer dereference with RTL8814AE" This reverts commit e32c796572ee22ae172411fe5c1183921eca498e. The function is supposed to call rtw_pci_link_cfg() even if intf_table is null. Signed-off-by: Bitterblue Smith --- pci.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/pci.c b/pci.c index 2560e696..e6bb7a2c 100644 --- a/pci.c +++ b/pci.c @@ -1461,9 +1461,6 @@ static void rtw_pci_phy_cfg(struct rtw_dev *rtwdev) int i; int ret; - if (!chip->intf_table) - return; - cut = BIT(0) << rtwdev->hal.cut_version; for (i = 0; i < chip->intf_table->n_gen1_para; i++) { From 27e716ab7687f1392bd1504a92e4146ac4f86d46 Mon Sep 17 00:00:00 2001 From: Bitterblue Smith Date: Fri, 14 Feb 2025 17:31:12 +0200 Subject: [PATCH 128/193] 8814a: Add empty intf_table Avoid null pointer dereference in rtw_pci_phy_cfg(). Signed-off-by: Bitterblue Smith --- rtw8814a.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/rtw8814a.c b/rtw8814a.c index 7ffb6985..2d57e389 100644 --- a/rtw8814a.c +++ b/rtw8814a.c @@ -2005,6 +2005,8 @@ static void rtw8814a_fill_txdesc_checksum(struct rtw_dev *rtwdev, fill_txdesc_checksum_common(txdesc, words); } +static const struct rtw_intf_phy_para_table phy_para_table_8814a = {}; + static const struct rtw_hw_reg rtw8814a_dig[] = { [0] = { .addr = 0xc50, .mask = 0x7f }, [1] = { .addr = 0xe50, .mask = 0x7f }, @@ -2169,7 +2171,7 @@ const struct rtw_chip_info rtw8814a_hw_spec = { .rqpn_table = rqpn_table_8814a, .prioq_addrs = &prioq_addrs_8814a, .page_table = page_table_8814a, - .intf_table = NULL, + .intf_table = &phy_para_table_8814a, .dig = rtw8814a_dig, .dig_cck = NULL, .rf_base_addr = {0x2800, 0x2c00, 0x3800, 0x3c00}, From 75838f9a7797159f285fed33bb8c7886c292e0cf Mon Sep 17 00:00:00 2001 From: Bitterblue Smith Date: Fri, 14 Feb 2025 17:35:00 +0200 Subject: [PATCH 129/193] wifi: rtw88: 8821a/8812a: Add empty intf_table Avoid null pointer dereference in rtw_pci_phy_cfg(). Signed-off-by: Bitterblue Smith --- rtw8812a.c | 4 +++- rtw8821a.c | 4 +++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/rtw8812a.c b/rtw8812a.c index 56faf725..94e59bd2 100644 --- a/rtw8812a.c +++ b/rtw8812a.c @@ -1007,6 +1007,8 @@ static const struct rtw_prioq_addrs prioq_addrs_8812a = { .wsize = false, }; +static const struct rtw_intf_phy_para_table phy_para_table_8812a = {}; + static const struct rtw_hw_reg rtw8812a_dig[] = { [0] = { .addr = REG_RXIGI_A, .mask = 0x7f }, [1] = { .addr = REG_RXIGI_B, .mask = 0x7f }, @@ -1088,7 +1090,7 @@ const struct rtw_chip_info rtw8812a_hw_spec = { .rqpn_table = rqpn_table_8812a, .prioq_addrs = &prioq_addrs_8812a, .page_table = page_table_8812a, - .intf_table = NULL, + .intf_table = &phy_para_table_8812a, .dig = rtw8812a_dig, .rf_sipi_addr = {REG_LSSI_WRITE_A, REG_LSSI_WRITE_B}, .ltecoex_addr = NULL, diff --git a/rtw8821a.c b/rtw8821a.c index 02d4f595..501b2a00 100644 --- a/rtw8821a.c +++ b/rtw8821a.c @@ -953,6 +953,8 @@ static const struct rtw_prioq_addrs prioq_addrs_8821a = { .wsize = false, }; +static const struct rtw_intf_phy_para_table phy_para_table_8821a = {}; + static const struct rtw_hw_reg rtw8821a_dig[] = { [0] = { .addr = REG_RXIGI_A, .mask = 0x7f }, }; @@ -1188,7 +1190,7 @@ const struct rtw_chip_info rtw8821a_hw_spec = { .rqpn_table = rqpn_table_8821a, .prioq_addrs = &prioq_addrs_8821a, .page_table = page_table_8821a, - .intf_table = NULL, + .intf_table = &phy_para_table_8821a, .dig = rtw8821a_dig, .rf_sipi_addr = {REG_LSSI_WRITE_A, REG_LSSI_WRITE_B}, .ltecoex_addr = NULL, From 96c97fcd157bd9d8ffe85e136fe7b5943d44759c Mon Sep 17 00:00:00 2001 From: Bitterblue Smith Date: Sun, 16 Feb 2025 00:37:01 +0200 Subject: [PATCH 130/193] Revert "wifi: rtw88: 8814au: Don't ask for TX report for management frames" This reverts commit e15c59e8fd8361258747a898d7b2f86344bb33fb. The commit message is wrong: the chip can provide TX reports for management frames if it's configured to do so. --- usb.c | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/usb.c b/usb.c index 6034c9c1..92f4c064 100644 --- a/usb.c +++ b/usb.c @@ -267,7 +267,6 @@ static void rtw_usb_write_port_tx_complete(struct urb *urb) struct rtw_usb_txcb *txcb = urb->context; struct rtw_dev *rtwdev = txcb->rtwdev; struct ieee80211_hw *hw = rtwdev->hw; - struct ieee80211_hdr *hdr; while (true) { struct sk_buff *skb = skb_dequeue(&txcb->tx_ack_queue); @@ -282,12 +281,8 @@ static void rtw_usb_write_port_tx_complete(struct urb *urb) skb_pull(skb, rtwdev->chip->tx_pkt_desc_sz); - hdr = (struct ieee80211_hdr *)skb->data; - /* enqueue to wait for tx report */ - if ((info->flags & IEEE80211_TX_CTL_REQ_TX_STATUS) && - !(rtwdev->chip->id == RTW_CHIP_TYPE_8814A && - ieee80211_is_mgmt(hdr->frame_control))) { + if (info->flags & IEEE80211_TX_CTL_REQ_TX_STATUS) { rtw_tx_report_enqueue(rtwdev, skb, tx_data->sn); continue; } From 48ef2fa065fdf8c92d9c932b30ac5a8f85a04775 Mon Sep 17 00:00:00 2001 From: Bitterblue Smith Date: Sun, 16 Feb 2025 00:40:46 +0200 Subject: [PATCH 131/193] 8814a: Enable TX reports for the management queue Needed for AP mode. Signed-off-by: Bitterblue Smith --- rtw8814a.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rtw8814a.c b/rtw8814a.c index 2d57e389..67910ad1 100644 --- a/rtw8814a.c +++ b/rtw8814a.c @@ -340,7 +340,7 @@ static void rtw8814a_phy_set_param(struct rtw_dev *rtwdev) rtw_write8(rtwdev, REG_NAV_CTRL + 2, 235); /* enable Tx report. */ - rtw_write8(rtwdev, REG_FWHW_TXQ_CTRL + 1, 0x0F); + rtw_write8(rtwdev, REG_FWHW_TXQ_CTRL + 1, 0x1F); if (rtw_hci_type(rtwdev) == RTW_HCI_TYPE_USB) { /* Reset USB mode switch setting */ From 4350be0a08c89e894195007fbf5db02cf8acbcdf Mon Sep 17 00:00:00 2001 From: Bitterblue Smith Date: Sun, 16 Feb 2025 16:22:49 +0200 Subject: [PATCH 132/193] 8814a: Support RFE type 0 Theoretically this is the RFE type used in PCI devices. Signed-off-by: Bitterblue Smith --- rtw8814a.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/rtw8814a.c b/rtw8814a.c index 67910ad1..c1bd4eed 100644 --- a/rtw8814a.c +++ b/rtw8814a.c @@ -2128,6 +2128,9 @@ static const struct coex_rf_para rf_para_rx_8814a[] = { static_assert(ARRAY_SIZE(rf_para_tx_8814a) == ARRAY_SIZE(rf_para_rx_8814a)); static const struct rtw_rfe_def rtw8814a_rfe_defs[] = { + [0] = { .phy_pg_tbl = &rtw8814a_bb_pg_type0_tbl, + .txpwr_lmt_tbl = &rtw8814a_txpwr_lmt_type0_tbl, + .pwr_track_tbl = &rtw8814a_rtw_pwrtrk_type0_tbl }, [1] = { .phy_pg_tbl = &rtw8814a_bb_pg_tbl, .txpwr_lmt_tbl = &rtw8814a_txpwr_lmt_type1_tbl, .pwr_track_tbl = &rtw8814a_rtw_pwrtrk_tbl }, From fdbc4b3bd6c87b3e16b963ba00c824bf7316e0c0 Mon Sep 17 00:00:00 2001 From: Bitterblue Smith Date: Sun, 16 Feb 2025 16:23:37 +0200 Subject: [PATCH 133/193] 8814a: Support LPS deep (PCI only) This is probably correct. Signed-off-by: Bitterblue Smith --- rtw8814a.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rtw8814a.c b/rtw8814a.c index c1bd4eed..5d10b5b8 100644 --- a/rtw8814a.c +++ b/rtw8814a.c @@ -2167,7 +2167,7 @@ const struct rtw_chip_info rtw8814a_hw_spec = { .tx_report_sn = true, .ht_supported = true, .vht_supported = true, - .lps_deep_mode_supported = 0, + .lps_deep_mode_supported = BIT(LPS_DEEP_MODE_LCLK), .sys_func_en = 0xDC, .pwr_on_seq = card_enable_flow_8814a, .pwr_off_seq = card_disable_flow_8814a, From 95baebeceaedad549b7eef06b524395d73ead66a Mon Sep 17 00:00:00 2001 From: Bitterblue Smith Date: Tue, 18 Feb 2025 13:56:20 +0200 Subject: [PATCH 134/193] 8814a: Don't reject PCI Also use the USB TX aggregation setting only for USB. Signed-off-by: Bitterblue Smith --- rtw8814a.c | 7 +++++-- rtw8814a.h | 2 +- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/rtw8814a.c b/rtw8814a.c index 5d10b5b8..b8cd1090 100644 --- a/rtw8814a.c +++ b/rtw8814a.c @@ -168,6 +168,8 @@ static int rtw8814a_read_efuse(struct rtw_dev *rtwdev, u8 *log_map) ether_addr_copy(efuse->addr, map->u.mac_addr); break; case RTW_HCI_TYPE_PCIE: + ether_addr_copy(efuse->addr, map->e.mac_addr); + break; case RTW_HCI_TYPE_SDIO: default: /* unsupported now */ @@ -358,8 +360,9 @@ static int rtw8814a_mac_init(struct rtw_dev *rtwdev) rtw_load_table(rtwdev, rtwdev->chip->mac_tbl); - rtw_write8(rtwdev, REG_AUTO_LLT_V1 + 3, - rtwdev->chip->usb_tx_agg_desc_num << 1); + if (rtw_hci_type(rtwdev) == RTW_HCI_TYPE_USB) + rtw_write8(rtwdev, REG_AUTO_LLT_V1 + 3, + rtwdev->chip->usb_tx_agg_desc_num << 1); rtw_write32(rtwdev, REG_HIMR0, 0); rtw_write32(rtwdev, REG_HIMR1, 0); diff --git a/rtw8814a.h b/rtw8814a.h index f0ccb332..622fcc58 100644 --- a/rtw8814a.h +++ b/rtw8814a.h @@ -10,7 +10,7 @@ struct rtw8814au_efuse { u8 vid[2]; /* 0xd0 */ u8 pid[2]; /* 0xd2 */ - u8 res[4]; /* 0xd0 */ + u8 res[4]; /* 0xd4 */ u8 mac_addr[ETH_ALEN]; /* 0xd8 */ } __packed; From bd8b1668b96a9d7848c0909f017b2e3eb87ad2b3 Mon Sep 17 00:00:00 2001 From: Bitterblue Smith Date: Wed, 19 Feb 2025 23:12:11 +0200 Subject: [PATCH 135/193] 8814a: Add rtw8814ae_enable_rf_1_2v() for PCI Some missing initialisation for PCI. Signed-off-by: Bitterblue Smith --- reg.h | 2 ++ rtw8814a.c | 30 ++++++++++++++++++++++++++++++ 2 files changed, 32 insertions(+) diff --git a/reg.h b/reg.h index 9d62258e..81d0aec0 100644 --- a/reg.h +++ b/reg.h @@ -77,6 +77,8 @@ #define BIT_BT_PTA_EN BIT(5) #define BIT_WLRFE_4_5_EN BIT(2) +#define REG_GPIO_PIN_CTRL 0x0044 + #define REG_LED_CFG 0x004C #define BIT_LNAON_SEL_EN BIT(26) #define BIT_PAPE_SEL_EN BIT(25) diff --git a/rtw8814a.c b/rtw8814a.c index b8cd1090..1d8d29a7 100644 --- a/rtw8814a.c +++ b/rtw8814a.c @@ -351,6 +351,34 @@ static void rtw8814a_phy_set_param(struct rtw_dev *rtwdev) } } +static void rtw8814ae_enable_rf_1_2v(struct rtw_dev *rtwdev) +{ + /* This is for fullsize card, because GPIO7 there is floating. + * We should pull GPIO7 high to enable RF 1.2V Switch Power Supply + */ + + /* 1. set 0x40[1:0] to 0, BIT_GPIOSEL=0, select pin as GPIO */ + rtw_write8_clr(rtwdev, REG_GPIO_MUXCFG, BIT(1) | BIT(0)); + + /* 2. set 0x44[31] to 0 + * mode=0: data port; + * mode=1 and BIT_GPIO_IO_SEL=0: interrupt mode; + */ + rtw_write8_clr(rtwdev, REG_GPIO_PIN_CTRL + 3, BIT(7)); + + /* 3. data mode + * 3.1 set 0x44[23] to 1 + * sel=0: input; + * sel=1: output; + */ + rtw_write8_set(rtwdev, REG_GPIO_PIN_CTRL + 2, BIT(7)); + + /* 3.2 set 0x44[15] to 1 + * output high value; + */ + rtw_write8_set(rtwdev, REG_GPIO_PIN_CTRL + 1, BIT(7)); +} + static int rtw8814a_mac_init(struct rtw_dev *rtwdev) { struct rtw_usb *rtwusb = rtw_get_usb_priv(rtwdev); @@ -418,6 +446,8 @@ static int rtw8814a_mac_init(struct rtw_dev *rtwdev) rtw_write8_clr(rtwdev, REG_SW_AMPDU_BURST_MODE_CTRL, BIT_PRE_TX_CMD); + } else if (rtw_hci_type(rtwdev) == RTW_HCI_TYPE_PCIE) { + rtw8814ae_enable_rf_1_2v(rtwdev); } return 0; From 19e8a6766602cab25a07dcfb6b063f11a7f39885 Mon Sep 17 00:00:00 2001 From: Zenm Chen Date: Sun, 16 Feb 2025 14:17:25 +0800 Subject: [PATCH 136/193] Makefile: Add JOBS variable --- Makefile | 3 ++- README.md | 8 +++++--- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/Makefile b/Makefile index 8a606e2d..4d1ee25e 100644 --- a/Makefile +++ b/Makefile @@ -2,6 +2,7 @@ SHELL := /bin/sh KVER ?= $(if $(KERNELRELEASE),$(KERNELRELEASE),$(shell uname -r)) KSRC ?= $(if $(KERNEL_SRC),$(KERNEL_SRC),/lib/modules/$(KVER)/build) FWDIR := /lib/firmware/rtw88 +JOBS ?= $(shell nproc --ignore=1) MODLIST := rtw_8723cs rtw_8723de rtw_8723ds rtw_8723du \ rtw_8812au rtw_8814ae rtw_8814au rtw_8821au rtw_8821ce rtw_8821cs rtw_8821cu \ rtw_8822be rtw_8822bs rtw_8822bu rtw_8822ce rtw_8822cs rtw_8822cu \ @@ -185,7 +186,7 @@ rtw_usb-objs := usb.o ccflags-y += -D__CHECK_ENDIAN__ all: - $(MAKE) -j`nproc` -C $(KSRC) M=$$PWD modules + $(MAKE) -j$(JOBS) -C $(KSRC) M=$$PWD modules install: all @install -D -m 644 -t $(MODDESTDIR) *.ko diff --git a/README.md b/README.md index 8e3438a6..bece8b86 100644 --- a/README.md +++ b/README.md @@ -198,9 +198,7 @@ sudo make sign-install --- -## FAQ - -Below are some Frequently Asked Questions: +## Q&A --- @@ -231,3 +229,7 @@ The module `rtw_usb` has a parameter named `switch_usb_mode` which can enable or Install `usb_modeswitch` which can switch your adapter from CD-ROM mode to Wi-Fi mode and then your wifi adapter should be in Wi-Fi mode after reboot. --- + +### Q5: My computer becomes very slow while building the driver, any idea to avoid that? +Run `make JOBS=x` instead, `x` is the number of compilation jobs that will be executed simultaneously, you can adjust it according to the CPU cores available on your machine. + From 1ced71daf20b478fa0f7858e5ac8d752d1ac7ecc Mon Sep 17 00:00:00 2001 From: Bitterblue Smith Date: Thu, 20 Feb 2025 22:49:16 +0200 Subject: [PATCH 137/193] 8814a: Fix (?) TX queue mapping for PCI This is what the official driver does. Signed-off-by: Bitterblue Smith --- rtw8814a.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rtw8814a.c b/rtw8814a.c index 1d8d29a7..a0f07b9a 100644 --- a/rtw8814a.c +++ b/rtw8814a.c @@ -2068,7 +2068,7 @@ static const struct rtw_rqpn rqpn_table_8814a[] = { /* PCIE */ {RTW_DMA_MAPPING_HIGH, RTW_DMA_MAPPING_NORMAL, RTW_DMA_MAPPING_LOW, RTW_DMA_MAPPING_LOW, - RTW_DMA_MAPPING_EXTRA, RTW_DMA_MAPPING_HIGH}, + RTW_DMA_MAPPING_HIGH, RTW_DMA_MAPPING_HIGH}, /* USB, 2 bulk out */ {RTW_DMA_MAPPING_HIGH, RTW_DMA_MAPPING_HIGH, RTW_DMA_MAPPING_NORMAL, RTW_DMA_MAPPING_NORMAL, From 1e45f24253a51b528dcbd87cc2e39368879a1997 Mon Sep 17 00:00:00 2001 From: morrownr <69053122+morrownr@users.noreply.github.com> Date: Thu, 20 Feb 2025 15:34:46 -0600 Subject: [PATCH 138/193] Update README.md add rtl8814ae to README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index bece8b86..02fa2610 100644 --- a/README.md +++ b/README.md @@ -16,7 +16,7 @@ Compatible with **Linux kernel versions 5.4 and newer** as long as your distro h #### Supported Chipsets -- **PCIe**: RTL8723DE, RTL8821CE, RTL8822BE, RTL8822CE +- **PCIe**: RTL8723DE, RTL8821CE, RTL8822BE, RTL8822CE, RTL8814au - **SDIO**: RTL8723CS, RTL8723DS, RTL8821CS, RTL8822BS, RTL8822CS - **USB** : RTL8723DU, RTL8811AU, RTL8811CU, RTL8812AU, RTL8812BU, RTL8812CU - **USB** : RTL8814AU, RTL8821AU, RTL8821CU, RTL8822BU, RTL8822CU From ec139f1c8fb42cfb51b6415bfa39a0488738c2bf Mon Sep 17 00:00:00 2001 From: morrownr <69053122+morrownr@users.noreply.github.com> Date: Thu, 20 Feb 2025 15:36:01 -0600 Subject: [PATCH 139/193] Update README.md fix add RTL8814AE to README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 02fa2610..fd561dd2 100644 --- a/README.md +++ b/README.md @@ -16,7 +16,7 @@ Compatible with **Linux kernel versions 5.4 and newer** as long as your distro h #### Supported Chipsets -- **PCIe**: RTL8723DE, RTL8821CE, RTL8822BE, RTL8822CE, RTL8814au +- **PCIe**: RTL8723DE, RTL8821CE, RTL8822BE, RTL8822CE, RTL8814AE - **SDIO**: RTL8723CS, RTL8723DS, RTL8821CS, RTL8822BS, RTL8822CS - **USB** : RTL8723DU, RTL8811AU, RTL8811CU, RTL8812AU, RTL8812BU, RTL8812CU - **USB** : RTL8814AU, RTL8821AU, RTL8821CU, RTL8822BU, RTL8822CU From dd5df33fc26f04705acf3e8b1ac70f3db6cdc008 Mon Sep 17 00:00:00 2001 From: Bitterblue Smith Date: Mon, 24 Feb 2025 01:03:26 +0200 Subject: [PATCH 140/193] 8814a: Force the antenna b to wifi (PCI only) Maybe this is needed too. Signed-off-by: Bitterblue Smith --- rtw8814a.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/rtw8814a.c b/rtw8814a.c index a0f07b9a..b1bb790c 100644 --- a/rtw8814a.c +++ b/rtw8814a.c @@ -448,6 +448,12 @@ static int rtw8814a_mac_init(struct rtw_dev *rtwdev) BIT_PRE_TX_CMD); } else if (rtw_hci_type(rtwdev) == RTW_HCI_TYPE_PCIE) { rtw8814ae_enable_rf_1_2v(rtwdev); + + /* Force the antenna b to wifi. */ + rtw_write8_set(rtwdev, REG_PAD_CTRL1, BIT(2)); + rtw_write8_set(rtwdev, REG_PAD_CTRL1 + 1, BIT(0)); + rtw_write8_set(rtwdev, REG_LED_CFG + 3, + (BIT(27) | BIT_DPDT_WL_SEL) >> 24); } return 0; From 6ca4faca0e5cfeeecd522eb07b605a2bb890cd88 Mon Sep 17 00:00:00 2001 From: Bitterblue Smith Date: Tue, 4 Mar 2025 20:57:27 +0200 Subject: [PATCH 141/193] README: RTL8814AE is not untested anymore Signed-off-by: Bitterblue Smith --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index fd561dd2..e997696c 100644 --- a/README.md +++ b/README.md @@ -3,7 +3,7 @@ The most recent addition to this repo is the driver for the RTL8814AU chipset. Testing is needed so if you have an adapter based on the RTL8814AU chipset, please test and report. -Update: There is now also a driver for RTL8814AE PCIe cards, ID 10ec:8813. lspci may call it RTL8813AE, same thing. This is completely untested. Please test and report if you still have this card. +Update: There is now also a driver for RTL8814AE PCIe cards, ID 10ec:8813. lspci may call it RTL8813AE, same thing. Please test and report if you still have this card. 🌟 The code in this repo stays in sync with the `wireless-next` repository, with additional changes to accommodate kernel API changes over time. From db366e448744079eb2030f9f1c5eb6fd55fcd41c Mon Sep 17 00:00:00 2001 From: Ryan Wild Date: Thu, 13 Mar 2025 14:45:52 +0900 Subject: [PATCH 142/193] Makefile: update secure boot CN The secure boot CN is updated to be less ambiguous. --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 4d1ee25e..63c5f002 100644 --- a/Makefile +++ b/Makefile @@ -238,7 +238,7 @@ clean: sign: ifeq ($(NO_SKIP_SIGN), y) - @openssl req -new -x509 -newkey rsa:2048 -keyout MOK.priv -outform DER -out MOK.der -nodes -days 36500 -subj "/CN=Custom MOK/" + @openssl req -new -x509 -newkey rsa:2048 -keyout MOK.priv -outform DER -out MOK.der -nodes -days 36500 -subj "/CN=rtw88 driver key/" @mokutil --import MOK.der else echo "Skipping key creation" From dbe1e0fd2f4ad1ef8a66803ab52b21c7f1aef714 Mon Sep 17 00:00:00 2001 From: Rohan Barar Date: Fri, 21 Feb 2025 21:59:07 +1100 Subject: [PATCH 143/193] README: Add dkms instructions --- README.md | 74 ++++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 73 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index e997696c..5d5993ee 100644 --- a/README.md +++ b/README.md @@ -78,6 +78,79 @@ sudo apt install -y raspberrypi-kernel-headers build-essential git ``` --- + +### Installation Using DKMS 🔄 +Using DKMS (Dynamic Kernel Module Support) ensures that the `rtw88` kernel modules are automatically rebuilt and re-signed whenever the Linux kernel is updated on systems with secure boot enabled. Without DKMS, these drivers would stop working after each kernel update, requiring manual re-compilation and re-signing. DKMS should be available through your distribution’s package manager. You can learn more about DKMS [here](https://github.com/dell/dkms). + +__Installation Process__ +1. Install `dkms` and all its required dependencies using your preferred package manager. +2. Create a new Machine Owner Key (MOK). + 1. Generate a private RSA key. + + ```bash + sudo openssl genrsa -out /var/lib/dkms/mok.key 2048 + ``` + + 2. Generate an X.509 certificate from the private key. + + ```bash + sudo openssl req -new -x509 -key /var/lib/dkms/mok.key -outform DER -out /var/lib/dkms/mok.pub -nodes -days 36500 -subj "/CN=DKMS Kernel Module Signing Key/" + ``` + + 3. Enroll the certificate. + + ```bash + sudo mokutil --import /var/lib/dkms/mok.pub + ``` + + Note: At this point, you will be requested to enter a password. Remember this password and re-enter it after rebooting your system in order to enrol your new MOK into your system's UEFI. + + 4. Verify the new MOK was enrolled. + + ```bash + mokutil --list-enrolled + ``` + +3. Clone the `rtw88` GitHub repository to `/usr/src`. + + ```bash + cd /usr/src && sudo git clone https://github.com/lwfinger/rtw88.git rtw88-0.6 + ``` + +4. Add `rtw88` to `dkms`. + + ```bash + sudo dkms add -m rtw88 -v 0.6 + ``` + +5. Build and sign `rtw88` using your new MOK. + + ```bash + sudo dkms build -m rtw88 -v 0.6 + ``` + +6. Install `rtw88`. + + ```bash + sudo dkms install -m rtw88 -v 0.6 + ``` + +7. Verify `rtw88` was installed. + + ```bash + dkms status + ``` + +__Uninstallation Process__ +```bash +sudo dkms remove -m rtw88 -v 0.6 --all # Remove rtw88 from dkms +sudo rm -r /var/lib/dkms/rtw88 # Remove rtw88 dkms build files (if they exist) +sudo make -C /usr/src/rtw88-0.6 uninstall # Run uninstall target in Makefile +sudo rm -r /usr/src/rtw88-0.6 # Remove cloned source code directory +``` + +--- + ### Basic Installation for All Distros 🛠 ```bash @@ -232,4 +305,3 @@ Install `usb_modeswitch` which can switch your adapter from CD-ROM mode to Wi-Fi ### Q5: My computer becomes very slow while building the driver, any idea to avoid that? Run `make JOBS=x` instead, `x` is the number of compilation jobs that will be executed simultaneously, you can adjust it according to the CPU cores available on your machine. - From f3d32fe08681cf8d5ef7133c067ce201f7ebf3ba Mon Sep 17 00:00:00 2001 From: Bitterblue Smith Date: Fri, 14 Mar 2025 15:52:52 +0200 Subject: [PATCH 144/193] Sync rtw_fw_send_ra_info with the kernel Signed-off-by: Bitterblue Smith --- fw.c | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/fw.c b/fw.c index 2c760e35..1c916f9d 100644 --- a/fw.c +++ b/fw.c @@ -768,18 +768,19 @@ void rtw_fw_send_ra_info(struct rtw_dev *rtwdev, struct rtw_sta_info *si) rtw_fw_send_h2c_command(rtwdev, h2c_pkt); - if (rtwdev->chip->rf_tbl[RF_PATH_C]) { - SET_H2C_CMD_ID_CLASS(h2c_pkt, H2C_CMD_RA_INFO_HI); + if (rtwdev->chip->id != RTW_CHIP_TYPE_8814A) + return; - mask_hi = si->ra_mask >> 32; + SET_H2C_CMD_ID_CLASS(h2c_pkt, H2C_CMD_RA_INFO_HI); - SET_RA_INFO_RA_MASK0(h2c_pkt, (mask_hi & 0xff)); - SET_RA_INFO_RA_MASK1(h2c_pkt, (mask_hi & 0xff00) >> 8); - SET_RA_INFO_RA_MASK2(h2c_pkt, (mask_hi & 0xff0000) >> 16); - SET_RA_INFO_RA_MASK3(h2c_pkt, (mask_hi & 0xff000000) >> 24); + mask_hi = si->ra_mask >> 32; - rtw_fw_send_h2c_command(rtwdev, h2c_pkt); - } + SET_RA_INFO_RA_MASK0(h2c_pkt, (mask_hi & 0xff)); + SET_RA_INFO_RA_MASK1(h2c_pkt, (mask_hi & 0xff00) >> 8); + SET_RA_INFO_RA_MASK2(h2c_pkt, (mask_hi & 0xff0000) >> 16); + SET_RA_INFO_RA_MASK3(h2c_pkt, (mask_hi & 0xff000000) >> 24); + + rtw_fw_send_h2c_command(rtwdev, h2c_pkt); } void rtw_fw_media_status_report(struct rtw_dev *rtwdev, u8 mac_id, bool connect) From f2ec7053aa5bbbcafca1c13454df2f7b6ff41045 Mon Sep 17 00:00:00 2001 From: Bitterblue Smith Date: Fri, 14 Mar 2025 22:04:42 +0200 Subject: [PATCH 145/193] Sync rtw_debugfs_get_tx_pwr_tbl Signed-off-by: Bitterblue Smith --- debug.c | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/debug.c b/debug.c index 0efb5c19..b67d69b0 100644 --- a/debug.c +++ b/debug.c @@ -692,9 +692,11 @@ static int rtw_debugfs_get_tx_pwr_tbl(struct seq_file *m, void *v) { struct rtw_debugfs_priv *debugfs_priv = m->private; struct rtw_dev *rtwdev = debugfs_priv->rtwdev; + struct rtw_power_params pwr_param = {0}; struct rtw_hal *hal = &rtwdev->hal; + u8 nss = rtwdev->efuse.hw_cap.nss; u8 path, rate, bw, ch, regd; - struct rtw_power_params pwr_param = {0}; + u8 max_ht_rate, max_rate; mutex_lock(&rtwdev->mutex); bw = hal->current_band_width; @@ -707,15 +709,25 @@ static int rtw_debugfs_get_tx_pwr_tbl(struct seq_file *m, void *v) seq_printf(m, "%-4s %-10s %-9s %-9s (%-4s %-4s %-4s) %-4s\n", "path", "rate", "pwr", "base", "byr", "lmt", "sar", "rem"); + max_ht_rate = DESC_RATEMCS0 + nss * 8 - 1; + + if (rtwdev->chip->vht_supported) + max_rate = DESC_RATEVHT1SS_MCS0 + nss * 10 - 1; + else + max_rate = max_ht_rate; + mutex_lock(&hal->tx_power_mutex); - for (path = RF_PATH_A; path <= RF_PATH_D; path++) { + for (path = RF_PATH_A; path < hal->rf_path_num; path++) { /* there is no CCK rates used in 5G */ if (hal->current_band_type == RTW_BAND_5G) rate = DESC_RATE6M; else rate = DESC_RATE1M; - for (; rate <= DESC_RATEVHT4SS_MCS9; rate++) { + for (; rate <= max_rate; rate++) { + if (rate > max_ht_rate && rate <= DESC_RATEMCS31) + continue; + rtw_get_tx_power_params(rtwdev, path, rate, bw, ch, regd, &pwr_param); From 9d95f0d583a1a6bcd55993ecfe3f896a020b1005 Mon Sep 17 00:00:00 2001 From: Bitterblue Smith Date: Fri, 14 Mar 2025 22:05:38 +0200 Subject: [PATCH 146/193] Sync __rtw_build_rsvd_page_from_vifs Signed-off-by: Bitterblue Smith --- fw.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/fw.c b/fw.c index 1c916f9d..73bbdea4 100644 --- a/fw.c +++ b/fw.c @@ -1646,13 +1646,13 @@ static int __rtw_build_rsvd_page_from_vifs(struct rtw_dev *rtwdev) static u8 *rtw_build_rsvd_page(struct rtw_dev *rtwdev, u32 *size) { - struct ieee80211_hw *hw = rtwdev->hw; const struct rtw_chip_info *chip = rtwdev->chip; - struct sk_buff *iter; + struct ieee80211_hw *hw = rtwdev->hw; struct rtw_rsvd_page *rsvd_pkt; - u32 page = 0; - u8 total_page = 0; + struct sk_buff *iter; u16 page_size, page_margin, tx_desc_sz; + u8 total_page = 0; + u32 page = 0; u8 *buf; int ret; From 0a4d010b858239fb946563452cf2e9162caafa71 Mon Sep 17 00:00:00 2001 From: Bitterblue Smith Date: Fri, 14 Mar 2025 22:07:33 +0200 Subject: [PATCH 147/193] Sync _rtw_hw_scan_update_probe_req Signed-off-by: Bitterblue Smith --- fw.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/fw.c b/fw.c index 73bbdea4..c3d021ba 100644 --- a/fw.c +++ b/fw.c @@ -2058,13 +2058,13 @@ static int _rtw_hw_scan_update_probe_req(struct rtw_dev *rtwdev, u8 num_probes, { const struct rtw_chip_info *chip = rtwdev->chip; struct sk_buff *skb, *tmp; - u8 page_offset = 1, *buf; - u16 page_size = chip->page_size; u16 pg_addr = rtwdev->fifo.rsvd_h2c_info_addr, loc; - u16 buf_offset = page_size * page_offset; u8 tx_desc_sz = chip->tx_pkt_desc_sz; - u8 page_cnt, pages; + u16 page_size = chip->page_size; + u8 page_offset = 1, *buf; + u16 buf_offset = page_size * page_offset; unsigned int pkt_len; + u8 page_cnt, pages; int ret; if (rtw_fw_feature_ext_check(&rtwdev->fw, FW_FEATURE_EXT_OLD_PAGE_NUM)) From 2343395d307fd4702e10286c0372070045d3806b Mon Sep 17 00:00:00 2001 From: Bitterblue Smith Date: Fri, 14 Mar 2025 22:07:59 +0200 Subject: [PATCH 148/193] Sync rtw_mac_power_switch Signed-off-by: Bitterblue Smith --- mac.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/mac.c b/mac.c index 5de16c75..0491f501 100644 --- a/mac.c +++ b/mac.c @@ -291,8 +291,8 @@ static int rtw_mac_power_switch(struct rtw_dev *rtwdev, bool pwr_on) if (rtw_read8(rtwdev, REG_CR) == 0xea) cur_pwr = false; else if (rtw_hci_type(rtwdev) == RTW_HCI_TYPE_USB && - chip->id != RTW_CHIP_TYPE_8814A && - (rtw_read8(rtwdev, REG_SYS_STATUS1 + 1) & BIT(0))) + chip->id != RTW_CHIP_TYPE_8814A && + (rtw_read8(rtwdev, REG_SYS_STATUS1 + 1) & BIT(0))) cur_pwr = false; else cur_pwr = true; From 953ee064b39b6748edefcfcecc7d708c95b8638f Mon Sep 17 00:00:00 2001 From: Bitterblue Smith Date: Fri, 14 Mar 2025 22:08:27 +0200 Subject: [PATCH 149/193] Sync rtw_c2h_ra_rpt Signed-off-by: Bitterblue Smith --- fw.h | 1 - 1 file changed, 1 deletion(-) diff --git a/fw.h b/fw.h index 6215edcc..54035eda 100644 --- a/fw.h +++ b/fw.h @@ -93,7 +93,6 @@ struct rtw_c2h_ra_rpt { u8 byte4; u8 ra_ratio; u8 bw; - u8 txcls_rate; } __packed; #define RTW_C2H_RA_RPT_RATE GENMASK(6, 0) From 639abfbd3eb5c6582b810f56686249eca7f6a0b0 Mon Sep 17 00:00:00 2001 From: Bitterblue Smith Date: Fri, 14 Mar 2025 22:14:04 +0200 Subject: [PATCH 150/193] Constify structs and arrays Signed-off-by: Bitterblue Smith --- main.c | 4 ++-- main.h | 2 +- pci.c | 4 ++-- phy.c | 48 ++++++++++++++++++++++++++++++------------------ phy.h | 24 ++++++++++++------------ rtw8814a_table.c | 4 ++-- rtw8814a_table.h | 4 ++-- sdio.c | 2 +- usb.c | 2 +- 9 files changed, 53 insertions(+), 41 deletions(-) diff --git a/main.c b/main.c index ffcc75c4..03b5d42d 100644 --- a/main.c +++ b/main.c @@ -137,7 +137,7 @@ u16 rtw_desc_to_bitrate(u8 desc_rate) return rate.bitrate; } -static struct ieee80211_supported_band rtw_band_2ghz = { +static const struct ieee80211_supported_band rtw_band_2ghz = { .band = NL80211_BAND_2GHZ, .channels = rtw_channeltable_2g, @@ -150,7 +150,7 @@ static struct ieee80211_supported_band rtw_band_2ghz = { .vht_cap = {0}, }; -static struct ieee80211_supported_band rtw_band_5ghz = { +static const struct ieee80211_supported_band rtw_band_5ghz = { .band = NL80211_BAND_5GHZ, .channels = rtw_channeltable_5g, diff --git a/main.h b/main.h index 39d64bdd..20fb2e14 100644 --- a/main.h +++ b/main.h @@ -198,7 +198,7 @@ enum rtw_hci_type { }; struct rtw_hci { - struct rtw_hci_ops *ops; + const struct rtw_hci_ops *ops; enum rtw_hci_type type; u32 rpwm_addr; diff --git a/pci.c b/pci.c index e6bb7a2c..cd8f2035 100644 --- a/pci.c +++ b/pci.c @@ -20,7 +20,7 @@ module_param_named(disable_aspm, rtw_pci_disable_aspm, bool, 0644); MODULE_PARM_DESC(disable_msi, "Set Y to disable MSI interrupt support"); MODULE_PARM_DESC(disable_aspm, "Set Y to disable PCI ASPM support"); -static u32 rtw_pci_tx_queue_idx_addr[] = { +static const u32 rtw_pci_tx_queue_idx_addr[] = { [RTW_TX_QUEUE_BK] = RTK_PCI_TXBD_IDX_BKQ, [RTW_TX_QUEUE_BE] = RTK_PCI_TXBD_IDX_BEQ, [RTW_TX_QUEUE_VI] = RTK_PCI_TXBD_IDX_VIQ, @@ -1591,7 +1591,7 @@ static void rtw_pci_destroy(struct rtw_dev *rtwdev, struct pci_dev *pdev) rtw_pci_io_unmapping(rtwdev, pdev); } -static struct rtw_hci_ops rtw_pci_ops = { +static const struct rtw_hci_ops rtw_pci_ops = { .tx_write = rtw_pci_tx_write, .tx_kick_off = rtw_pci_tx_kick_off, .flush_queues = rtw_pci_flush_queues, diff --git a/phy.c b/phy.c index a4c51cd3..e3b4ca7e 100644 --- a/phy.c +++ b/phy.c @@ -54,61 +54,71 @@ static const u32 db_invert_table[12][8] = { 1995262315, 2511886432U, 3162277660U, 3981071706U} }; -u8 rtw_cck_rates[] = { DESC_RATE1M, DESC_RATE2M, DESC_RATE5_5M, DESC_RATE11M }; -u8 rtw_ofdm_rates[] = { +const u8 rtw_cck_rates[] = { DESC_RATE1M, DESC_RATE2M, DESC_RATE5_5M, DESC_RATE11M }; + +const u8 rtw_ofdm_rates[] = { DESC_RATE6M, DESC_RATE9M, DESC_RATE12M, DESC_RATE18M, DESC_RATE24M, DESC_RATE36M, DESC_RATE48M, DESC_RATE54M }; -u8 rtw_ht_1s_rates[] = { + +const u8 rtw_ht_1s_rates[] = { DESC_RATEMCS0, DESC_RATEMCS1, DESC_RATEMCS2, DESC_RATEMCS3, DESC_RATEMCS4, DESC_RATEMCS5, DESC_RATEMCS6, DESC_RATEMCS7 }; -u8 rtw_ht_2s_rates[] = { + +const u8 rtw_ht_2s_rates[] = { DESC_RATEMCS8, DESC_RATEMCS9, DESC_RATEMCS10, DESC_RATEMCS11, DESC_RATEMCS12, DESC_RATEMCS13, DESC_RATEMCS14, DESC_RATEMCS15 }; -u8 rtw_vht_1s_rates[] = { + +const u8 rtw_vht_1s_rates[] = { DESC_RATEVHT1SS_MCS0, DESC_RATEVHT1SS_MCS1, DESC_RATEVHT1SS_MCS2, DESC_RATEVHT1SS_MCS3, DESC_RATEVHT1SS_MCS4, DESC_RATEVHT1SS_MCS5, DESC_RATEVHT1SS_MCS6, DESC_RATEVHT1SS_MCS7, DESC_RATEVHT1SS_MCS8, DESC_RATEVHT1SS_MCS9 }; -u8 rtw_vht_2s_rates[] = { + +const u8 rtw_vht_2s_rates[] = { DESC_RATEVHT2SS_MCS0, DESC_RATEVHT2SS_MCS1, DESC_RATEVHT2SS_MCS2, DESC_RATEVHT2SS_MCS3, DESC_RATEVHT2SS_MCS4, DESC_RATEVHT2SS_MCS5, DESC_RATEVHT2SS_MCS6, DESC_RATEVHT2SS_MCS7, DESC_RATEVHT2SS_MCS8, DESC_RATEVHT2SS_MCS9 }; -u8 rtw_ht_3s_rates[] = { + +const u8 rtw_ht_3s_rates[] = { DESC_RATEMCS16, DESC_RATEMCS17, DESC_RATEMCS18, DESC_RATEMCS19, DESC_RATEMCS20, DESC_RATEMCS21, DESC_RATEMCS22, DESC_RATEMCS23 }; -u8 rtw_ht_4s_rates[] = { + +const u8 rtw_ht_4s_rates[] = { DESC_RATEMCS24, DESC_RATEMCS25, DESC_RATEMCS26, DESC_RATEMCS27, DESC_RATEMCS28, DESC_RATEMCS29, DESC_RATEMCS30, DESC_RATEMCS31 }; -u8 rtw_vht_3s_rates[] = { + +const u8 rtw_vht_3s_rates[] = { DESC_RATEVHT3SS_MCS0, DESC_RATEVHT3SS_MCS1, DESC_RATEVHT3SS_MCS2, DESC_RATEVHT3SS_MCS3, DESC_RATEVHT3SS_MCS4, DESC_RATEVHT3SS_MCS5, DESC_RATEVHT3SS_MCS6, DESC_RATEVHT3SS_MCS7, DESC_RATEVHT3SS_MCS8, DESC_RATEVHT3SS_MCS9 }; -u8 rtw_vht_4s_rates[] = { + +const u8 rtw_vht_4s_rates[] = { DESC_RATEVHT4SS_MCS0, DESC_RATEVHT4SS_MCS1, DESC_RATEVHT4SS_MCS2, DESC_RATEVHT4SS_MCS3, DESC_RATEVHT4SS_MCS4, DESC_RATEVHT4SS_MCS5, DESC_RATEVHT4SS_MCS6, DESC_RATEVHT4SS_MCS7, DESC_RATEVHT4SS_MCS8, DESC_RATEVHT4SS_MCS9 }; -u8 *rtw_rate_section[RTW_RATE_SECTION_MAX] = { + +const u8 * const rtw_rate_section[RTW_RATE_SECTION_NUM] = { rtw_cck_rates, rtw_ofdm_rates, rtw_ht_1s_rates, rtw_ht_2s_rates, rtw_vht_1s_rates, rtw_vht_2s_rates, @@ -117,7 +127,7 @@ u8 *rtw_rate_section[RTW_RATE_SECTION_MAX] = { }; EXPORT_SYMBOL(rtw_rate_section); -u8 rtw_rate_size[RTW_RATE_SECTION_MAX] = { +const u8 rtw_rate_size[RTW_RATE_SECTION_NUM] = { ARRAY_SIZE(rtw_cck_rates), ARRAY_SIZE(rtw_ofdm_rates), ARRAY_SIZE(rtw_ht_1s_rates), @@ -1662,11 +1672,13 @@ rtw_xref_5g_txpwr_lmt(struct rtw_dev *rtwdev, u8 regd, static void rtw_xref_txpwr_lmt_by_rs(struct rtw_dev *rtwdev, u8 regd, u8 bw, u8 ch_idx) { + static const u8 rs_cmp[4][2] = { + {RTW_RATE_SECTION_HT_1S, RTW_RATE_SECTION_VHT_1S}, + {RTW_RATE_SECTION_HT_2S, RTW_RATE_SECTION_VHT_2S}, + {RTW_RATE_SECTION_HT_3S, RTW_RATE_SECTION_VHT_3S}, + {RTW_RATE_SECTION_HT_4S, RTW_RATE_SECTION_VHT_4S} + }; u8 rs_idx, rs_ht, rs_vht; - u8 rs_cmp[4][2] = {{RTW_RATE_SECTION_HT_1S, RTW_RATE_SECTION_VHT_1S}, - {RTW_RATE_SECTION_HT_2S, RTW_RATE_SECTION_VHT_2S}, - {RTW_RATE_SECTION_HT_3S, RTW_RATE_SECTION_VHT_3S}, - {RTW_RATE_SECTION_HT_4S, RTW_RATE_SECTION_VHT_4S} }; for (rs_idx = 0; rs_idx < 4; rs_idx++) { rs_ht = rs_cmp[rs_idx][0]; @@ -2295,7 +2307,7 @@ static void rtw_phy_set_tx_power_index_by_rs(struct rtw_dev *rtwdev, { struct rtw_hal *hal = &rtwdev->hal; u8 regd = rtw_regd_get(rtwdev); - u8 *rates; + const u8 *rates; u8 size; u8 rate; u8 pwr_idx; @@ -2355,7 +2367,7 @@ EXPORT_SYMBOL(rtw_phy_set_tx_power_level); static void rtw_phy_tx_power_by_rate_config_by_path(struct rtw_hal *hal, u8 path, - u8 rs, u8 size, u8 *rates) + u8 rs, u8 size, const u8 *rates) { u8 rate; u8 base_idx, rate_idx; diff --git a/phy.h b/phy.h index 707576d0..c9e6b869 100644 --- a/phy.h +++ b/phy.h @@ -7,18 +7,18 @@ #include "debug.h" -extern u8 rtw_cck_rates[]; -extern u8 rtw_ofdm_rates[]; -extern u8 rtw_ht_1s_rates[]; -extern u8 rtw_ht_2s_rates[]; -extern u8 rtw_vht_1s_rates[]; -extern u8 rtw_vht_2s_rates[]; -extern u8 rtw_ht_3s_rates[]; -extern u8 rtw_ht_4s_rates[]; -extern u8 rtw_vht_3s_rates[]; -extern u8 rtw_vht_4s_rates[]; -extern u8 *rtw_rate_section[]; -extern u8 rtw_rate_size[]; +extern const u8 rtw_cck_rates[]; +extern const u8 rtw_ofdm_rates[]; +extern const u8 rtw_ht_1s_rates[]; +extern const u8 rtw_ht_2s_rates[]; +extern const u8 rtw_vht_1s_rates[]; +extern const u8 rtw_vht_2s_rates[]; +extern const u8 rtw_ht_3s_rates[]; +extern const u8 rtw_ht_4s_rates[]; +extern const u8 rtw_vht_3s_rates[]; +extern const u8 rtw_vht_4s_rates[]; +extern const u8 * const rtw_rate_section[]; +extern const u8 rtw_rate_size[]; void rtw_phy_init(struct rtw_dev *rtwdev); void rtw_phy_dynamic_mechanism(struct rtw_dev *rtwdev); diff --git a/rtw8814a_table.c b/rtw8814a_table.c index e065cb28..b9ce51a0 100644 --- a/rtw8814a_table.c +++ b/rtw8814a_table.c @@ -23916,14 +23916,14 @@ static const struct rtw_pwr_seq_cmd trans_cardemu_to_carddis_8814a[] = { RTW_PWR_CMD_END, 0, 0}, }; -const struct rtw_pwr_seq_cmd *card_enable_flow_8814a[] = { +const struct rtw_pwr_seq_cmd * const card_enable_flow_8814a[] = { init_power_on_8814a, trans_carddis_to_cardemu_8814a, trans_cardemu_to_act_8814a, NULL }; -const struct rtw_pwr_seq_cmd *card_disable_flow_8814a[] = { +const struct rtw_pwr_seq_cmd * const card_disable_flow_8814a[] = { trans_act_to_cardemu_8814a, trans_cardemu_to_carddis_8814a, NULL diff --git a/rtw8814a_table.h b/rtw8814a_table.h index 8a63ee00..69fb87e3 100644 --- a/rtw8814a_table.h +++ b/rtw8814a_table.h @@ -34,7 +34,7 @@ extern const struct rtw_pwr_track_tbl rtw8814a_rtw_pwrtrk_type2_tbl; extern const struct rtw_pwr_track_tbl rtw8814a_rtw_pwrtrk_type5_tbl; extern const struct rtw_pwr_track_tbl rtw8814a_rtw_pwrtrk_type7_tbl; extern const struct rtw_pwr_track_tbl rtw8814a_rtw_pwrtrk_type8_tbl; -extern const struct rtw_pwr_seq_cmd *card_disable_flow_8814a[]; -extern const struct rtw_pwr_seq_cmd *card_enable_flow_8814a[]; +extern const struct rtw_pwr_seq_cmd * const card_disable_flow_8814a[]; +extern const struct rtw_pwr_seq_cmd * const card_enable_flow_8814a[]; #endif diff --git a/sdio.c b/sdio.c index 3b53fd86..94f8f300 100644 --- a/sdio.c +++ b/sdio.c @@ -1155,7 +1155,7 @@ static void rtw_sdio_declaim(struct rtw_dev *rtwdev, sdio_release_host(sdio_func); } -static struct rtw_hci_ops rtw_sdio_ops = { +static const struct rtw_hci_ops rtw_sdio_ops = { .tx_write = rtw_sdio_tx_write, .tx_kick_off = rtw_sdio_tx_kick_off, .setup = rtw_sdio_setup, diff --git a/usb.c b/usb.c index 92f4c064..a770acc4 100644 --- a/usb.c +++ b/usb.c @@ -898,7 +898,7 @@ static void rtw_usb_dynamic_rx_agg(struct rtw_dev *rtwdev, bool enable) } } -static struct rtw_hci_ops rtw_usb_ops = { +static const struct rtw_hci_ops rtw_usb_ops = { .tx_write = rtw_usb_tx_write, .tx_kick_off = rtw_usb_tx_kick_off, .setup = rtw_usb_setup, From 7b222f93ee7994aba38aa9ff2355732f10442d96 Mon Sep 17 00:00:00 2001 From: Bitterblue Smith Date: Fri, 14 Mar 2025 22:20:53 +0200 Subject: [PATCH 151/193] Sync struct rtw_rate_section Signed-off-by: Bitterblue Smith --- main.h | 13 +++++++------ phy.c | 22 +++++++++++----------- rtw8821c.c | 2 +- rtw8822b.c | 2 +- rtw8822c.c | 2 +- rtw88xxa.c | 2 +- sar.c | 2 +- 7 files changed, 23 insertions(+), 22 deletions(-) diff --git a/main.h b/main.h index 20fb2e14..66fb4994 100644 --- a/main.h +++ b/main.h @@ -303,13 +303,14 @@ enum rtw_rate_section { RTW_RATE_SECTION_HT_2S, RTW_RATE_SECTION_VHT_1S, RTW_RATE_SECTION_VHT_2S, + __RTW_RATE_SECTION_2SS_MAX = RTW_RATE_SECTION_VHT_2S, RTW_RATE_SECTION_HT_3S, RTW_RATE_SECTION_HT_4S, RTW_RATE_SECTION_VHT_3S, RTW_RATE_SECTION_VHT_4S, /* keep last */ - RTW_RATE_SECTION_MAX, + RTW_RATE_SECTION_NUM, }; enum rtw_wireless_set { @@ -2090,7 +2091,7 @@ union rtw_sar_cfg { struct rtw_sar { enum rtw_sar_sources src; - union rtw_sar_cfg cfg[RTW_RF_PATH_MAX][RTW_RATE_SECTION_MAX]; + union rtw_sar_cfg cfg[RTW_RF_PATH_MAX][RTW_RATE_SECTION_NUM]; }; struct rtw_hal { @@ -2134,16 +2135,16 @@ struct rtw_hal { s8 tx_pwr_by_rate_offset_5g[RTW_RF_PATH_MAX] [DESC_RATE_MAX]; s8 tx_pwr_by_rate_base_2g[RTW_RF_PATH_MAX] - [RTW_RATE_SECTION_MAX]; + [RTW_RATE_SECTION_NUM]; s8 tx_pwr_by_rate_base_5g[RTW_RF_PATH_MAX] - [RTW_RATE_SECTION_MAX]; + [RTW_RATE_SECTION_NUM]; s8 tx_pwr_limit_2g[RTW_REGD_MAX] [RTW_CHANNEL_WIDTH_MAX] - [RTW_RATE_SECTION_MAX] + [RTW_RATE_SECTION_NUM] [RTW_MAX_CHANNEL_NUM_2G]; s8 tx_pwr_limit_5g[RTW_REGD_MAX] [RTW_CHANNEL_WIDTH_MAX] - [RTW_RATE_SECTION_MAX] + [RTW_RATE_SECTION_NUM] [RTW_MAX_CHANNEL_NUM_5G]; s8 tx_pwr_tbl[RTW_RF_PATH_MAX] [DESC_RATE_MAX]; diff --git a/phy.c b/phy.c index e3b4ca7e..d95a0ef2 100644 --- a/phy.c +++ b/phy.c @@ -1628,7 +1628,7 @@ static void rtw_phy_set_tx_power_limit(struct rtw_dev *rtwdev, u8 regd, u8 band, ch_idx = rtw_channel_to_idx(band, ch); if (regd >= RTW_REGD_MAX || bw >= RTW_CHANNEL_WIDTH_MAX || - rs >= RTW_RATE_SECTION_MAX || ch_idx < 0) { + rs >= RTW_RATE_SECTION_NUM || ch_idx < 0) { WARN(1, "wrong txpwr_lmt regd=%u, band=%u bw=%u, rs=%u, ch_idx=%u, pwr_limit=%d\n", regd, band, bw, rs, ch_idx, pwr_limit); @@ -1737,7 +1737,7 @@ rtw_cfg_txpwr_lmt_by_alt(struct rtw_dev *rtwdev, u8 regd, u8 regd_alt) u8 bw, rs; for (bw = 0; bw < RTW_CHANNEL_WIDTH_MAX; bw++) - for (rs = 0; rs < RTW_RATE_SECTION_MAX; rs++) + for (rs = 0; rs < RTW_RATE_SECTION_NUM; rs++) __cfg_txpwr_lmt_by_alt(&rtwdev->hal, regd, regd_alt, bw, rs); } @@ -2133,7 +2133,7 @@ static u8 rtw_phy_get_5g_tx_power_index(struct rtw_dev *rtwdev, return tx_power; } -/* return RTW_RATE_SECTION_MAX to indicate rate is invalid */ +/* return RTW_RATE_SECTION_NUM to indicate rate is invalid */ static u8 rtw_phy_rate_to_rate_section(u8 rate) { if (rate >= DESC_RATE1M && rate <= DESC_RATE11M) @@ -2157,7 +2157,7 @@ static u8 rtw_phy_rate_to_rate_section(u8 rate) else if (rate >= DESC_RATEVHT4SS_MCS0 && rate <= DESC_RATEVHT4SS_MCS9) return RTW_RATE_SECTION_VHT_4S; else - return RTW_RATE_SECTION_MAX; + return RTW_RATE_SECTION_NUM; } static s8 rtw_phy_get_tx_power_limit(struct rtw_dev *rtwdev, u8 band, @@ -2175,7 +2175,7 @@ static s8 rtw_phy_get_tx_power_limit(struct rtw_dev *rtwdev, u8 band, if (regd > RTW_REGD_WW) return power_limit; - if (rs == RTW_RATE_SECTION_MAX) + if (rs == RTW_RATE_SECTION_NUM) goto err; /* only 20M BW with cck and ofdm */ @@ -2220,7 +2220,7 @@ static s8 rtw_phy_get_tx_power_sar(struct rtw_dev *rtwdev, u8 sar_band, .rs = rs, }; - if (rs == RTW_RATE_SECTION_MAX) + if (rs == RTW_RATE_SECTION_NUM) goto err; return rtw_query_sar(rtwdev, &arg); @@ -2314,7 +2314,7 @@ static void rtw_phy_set_tx_power_index_by_rs(struct rtw_dev *rtwdev, u8 bw; int i; - if (rs >= RTW_RATE_SECTION_MAX) + if (rs >= RTW_RATE_SECTION_NUM) return; rates = rtw_rate_section[rs]; @@ -2345,7 +2345,7 @@ static void rtw_phy_set_tx_power_level_by_path(struct rtw_dev *rtwdev, else rs = RTW_RATE_SECTION_OFDM; - for (; rs < RTW_RATE_SECTION_MAX; rs++) + for (; rs < RTW_RATE_SECTION_NUM; rs++) rtw_phy_set_tx_power_index_by_rs(rtwdev, ch, path, rs); } @@ -2393,7 +2393,7 @@ void rtw_phy_tx_power_by_rate_config(struct rtw_hal *hal) u8 path, rs; for (path = 0; path < RTW_RF_PATH_MAX; path++) - for (rs = 0; rs < RTW_RATE_SECTION_MAX; rs++) + for (rs = 0; rs < RTW_RATE_SECTION_NUM; rs++) rtw_phy_tx_power_by_rate_config_by_path(hal, path, rs, rtw_rate_size[rs], rtw_rate_section[rs]); } @@ -2424,7 +2424,7 @@ void rtw_phy_tx_power_limit_config(struct rtw_hal *hal) for (regd = 0; regd < RTW_REGD_MAX; regd++) for (bw = 0; bw < RTW_CHANNEL_WIDTH_MAX; bw++) - for (rs = 0; rs < RTW_RATE_SECTION_MAX; rs++) + for (rs = 0; rs < RTW_RATE_SECTION_NUM; rs++) __rtw_phy_tx_power_limit_config(hal, regd, bw, rs); } @@ -2460,7 +2460,7 @@ void rtw_phy_init_tx_power(struct rtw_dev *rtwdev) /* init tx power limit */ for (regd = 0; regd < RTW_REGD_MAX; regd++) for (bw = 0; bw < RTW_CHANNEL_WIDTH_MAX; bw++) - for (rs = 0; rs < RTW_RATE_SECTION_MAX; rs++) + for (rs = 0; rs < RTW_RATE_SECTION_NUM; rs++) rtw_phy_init_tx_power_limit(rtwdev, regd, bw, rs); } diff --git a/rtw8821c.c b/rtw8821c.c index 4ff4a4a2..32ba6f80 100644 --- a/rtw8821c.c +++ b/rtw8821c.c @@ -710,7 +710,7 @@ static void rtw8821c_set_tx_power_index(struct rtw_dev *rtwdev) int rs, path; for (path = 0; path < hal->rf_path_num; path++) { - for (rs = 0; rs < RTW_RATE_SECTION_HT_3S; rs++) { + for (rs = 0; rs <= __RTW_RATE_SECTION_2SS_MAX; rs++) { if (rs == RTW_RATE_SECTION_HT_2S || rs == RTW_RATE_SECTION_VHT_2S) continue; diff --git a/rtw8822b.c b/rtw8822b.c index 900699e2..80c55dae 100644 --- a/rtw8822b.c +++ b/rtw8822b.c @@ -964,7 +964,7 @@ static void rtw8822b_set_tx_power_index(struct rtw_dev *rtwdev) int rs, path; for (path = 0; path < hal->rf_path_num; path++) { - for (rs = 0; rs < RTW_RATE_SECTION_HT_3S; rs++) + for (rs = 0; rs <= __RTW_RATE_SECTION_2SS_MAX; rs++) rtw8822b_set_tx_power_index_by_rate(rtwdev, path, rs, &phy_pwr_idx); } diff --git a/rtw8822c.c b/rtw8822c.c index e1466440..ec62a73b 100644 --- a/rtw8822c.c +++ b/rtw8822c.c @@ -2746,7 +2746,7 @@ static void rtw8822c_set_tx_power_index(struct rtw_dev *rtwdev) s8 diff_idx[4]; rtw8822c_set_write_tx_power_ref(rtwdev, pwr_ref_cck, pwr_ref_ofdm); - for (rs = 0; rs < RTW_RATE_SECTION_HT_3S; rs++) { + for (rs = 0; rs <= __RTW_RATE_SECTION_2SS_MAX; rs++) { for (j = 0; j < rtw_rate_size[rs]; j++) { rate = rtw_rate_section[rs][j]; pwr_a = hal->tx_pwr_tbl[RF_PATH_A][rate]; diff --git a/rtw88xxa.c b/rtw88xxa.c index 08bbd847..0fa94327 100644 --- a/rtw88xxa.c +++ b/rtw88xxa.c @@ -1637,7 +1637,7 @@ void rtw88xxa_set_tx_power_index(struct rtw_dev *rtwdev) int rs, path; for (path = 0; path < hal->rf_path_num; path++) { - for (rs = 0; rs < RTW_RATE_SECTION_HT_3S; rs++) { + for (rs = 0; rs <= __RTW_RATE_SECTION_2SS_MAX; rs++) { if (hal->rf_path_num == 1 && (rs == RTW_RATE_SECTION_HT_2S || rs == RTW_RATE_SECTION_VHT_2S)) diff --git a/sar.c b/sar.c index 745f5bec..5b35cee8 100644 --- a/sar.c +++ b/sar.c @@ -99,7 +99,7 @@ int rtw_set_sar_specs(struct rtw_dev *rtwdev, power, BIT(RTW_COMMON_SAR_FCT)); for (j = 0; j < RTW_RF_PATH_MAX; j++) { - for (k = 0; k < RTW_RATE_SECTION_MAX; k++) { + for (k = 0; k < RTW_RATE_SECTION_NUM; k++) { arg = (struct rtw_sar_arg){ .sar_band = idx, .path = j, From e490c45c9b0fc009ab0ce0bc28a454fe6884da42 Mon Sep 17 00:00:00 2001 From: Bitterblue Smith Date: Fri, 14 Mar 2025 22:21:50 +0200 Subject: [PATCH 152/193] Sync rtw_usb_phy_cfg Signed-off-by: Bitterblue Smith --- reg.h | 10 ++++++++++ usb.c | 20 +++++++++----------- 2 files changed, 19 insertions(+), 11 deletions(-) diff --git a/reg.h b/reg.h index 81d0aec0..f8bf7d3e 100644 --- a/reg.h +++ b/reg.h @@ -921,7 +921,17 @@ #define REG_USB_MOD 0xf008 #define REG_USB3_RXITV 0xf050 +#define REG_USB2_PHY_ADR 0xfe40 +#define REG_USB2_PHY_DAT 0xfe41 +#define REG_USB2_PHY_CMD 0xfe42 +#define BIT_USB2_PHY_CMD_TRG 0x81 #define REG_USB_HRPWM 0xfe58 +#define REG_USB3_PHY_ADR 0xff0c +#define REG_USB3_PHY_DAT_L 0xff0d +#define REG_USB3_PHY_DAT_H 0xff0e +#define BIT_USB3_PHY_ADR_WR BIT(7) +#define BIT_USB3_PHY_ADR_RD BIT(6) +#define BIT_USB3_PHY_ADR_MASK GENMASK(5, 0) #define RF_MODE 0x00 #define RF_MODOPT 0x01 diff --git a/usb.c b/usb.c index a770acc4..4bd6d58b 100644 --- a/usb.c +++ b/usb.c @@ -1164,17 +1164,17 @@ static int rtw_usb_switch_mode(struct rtw_dev *rtwdev) #define USB_PHY_PAGE0 0x9b #define USB_PHY_PAGE1 0xbb -static void rtw_usb_phy_write(struct rtw_dev *rtwdev, u16 addr, u16 data, +static void rtw_usb_phy_write(struct rtw_dev *rtwdev, u8 addr, u16 data, enum usb_device_speed speed) { if (speed == USB_SPEED_SUPER) { - rtw_write8(rtwdev, 0xff0d, (u8)data); - rtw_write8(rtwdev, 0xff0e, (u8)(data >> 8)); - rtw_write8(rtwdev, 0xff0c, addr | BIT(7)); + rtw_write8(rtwdev, REG_USB3_PHY_DAT_L, data & 0xff); + rtw_write8(rtwdev, REG_USB3_PHY_DAT_H, data >> 8); + rtw_write8(rtwdev, REG_USB3_PHY_ADR, addr | BIT_USB3_PHY_ADR_WR); } else if (speed == USB_SPEED_HIGH) { - rtw_write8(rtwdev, 0xfe41, (u8)data); - rtw_write8(rtwdev, 0xfe40, addr); - rtw_write8(rtwdev, 0xfe42, 0x81); + rtw_write8(rtwdev, REG_USB2_PHY_DAT, data); + rtw_write8(rtwdev, REG_USB2_PHY_ADR, addr); + rtw_write8(rtwdev, REG_USB2_PHY_CMD, BIT_USB2_PHY_CMD_TRG); } } @@ -1191,7 +1191,7 @@ static void rtw_usb_phy_cfg(struct rtw_dev *rtwdev, enum usb_device_speed speed) { const struct rtw_intf_phy_para *para = NULL; - u16 cut, offset; + u16 offset; if (!rtwdev->chip->intf_table) return; @@ -1204,10 +1204,8 @@ static void rtw_usb_phy_cfg(struct rtw_dev *rtwdev, if (!para) return; - cut = BIT(0) << rtwdev->hal.cut_version; - for ( ; para->offset != 0xffff; para++) { - if (!(para->cut_mask & cut)) + if (!(para->cut_mask & BIT(rtwdev->hal.cut_version))) continue; offset = para->offset; From 0a0daf200ff19705d52e74b328aa71f953e4612f Mon Sep 17 00:00:00 2001 From: Bitterblue Smith Date: Fri, 14 Mar 2025 22:22:36 +0200 Subject: [PATCH 153/193] Sync rtw8822bu.c Signed-off-by: Bitterblue Smith --- rtw8822bu.c | 102 ++++++++++++++++++++++++++-------------------------- 1 file changed, 51 insertions(+), 51 deletions(-) diff --git a/rtw8822bu.c b/rtw8822bu.c index a746707d..572d1f31 100644 --- a/rtw8822bu.c +++ b/rtw8822bu.c @@ -1,5 +1,5 @@ // SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause -/* Copyright(c) 2018-2024 Realtek Corporation +/* Copyright(c) 2018-2019 Realtek Corporation */ #include @@ -9,74 +9,74 @@ #include "usb.h" static const struct usb_device_id rtw_8822bu_id_table[] = { - { USB_DEVICE_AND_INTERFACE_INFO(RTW_USB_VENDOR_ID_REALTEK, 0xB812, 0xff, 0xff, 0xff), - .driver_info = (kernel_ulong_t)&(rtw8822b_hw_spec) }, /* Default ID for USB Single-function, WiFi only */ - { USB_DEVICE_AND_INTERFACE_INFO(RTW_USB_VENDOR_ID_REALTEK, 0xB81A, 0xff, 0xff, 0xff), - .driver_info = (kernel_ulong_t)&(rtw8822b_hw_spec) }, /* Default ID */ - { USB_DEVICE_AND_INTERFACE_INFO(RTW_USB_VENDOR_ID_REALTEK, 0xB82C, 0xff, 0xff, 0xff), - .driver_info = (kernel_ulong_t)&(rtw8822b_hw_spec) }, /* Default ID for USB multi-function */ + { USB_DEVICE_AND_INTERFACE_INFO(RTW_USB_VENDOR_ID_REALTEK, 0xb812, 0xff, 0xff, 0xff), + .driver_info = (kernel_ulong_t)&(rtw8822b_hw_spec) }, + { USB_DEVICE_AND_INTERFACE_INFO(RTW_USB_VENDOR_ID_REALTEK, 0xb82c, 0xff, 0xff, 0xff), + .driver_info = (kernel_ulong_t)&(rtw8822b_hw_spec) }, { USB_DEVICE_AND_INTERFACE_INFO(RTW_USB_VENDOR_ID_REALTEK, 0x2102, 0xff, 0xff, 0xff), .driver_info = (kernel_ulong_t)&(rtw8822b_hw_spec) }, /* CCNC */ - { USB_DEVICE_AND_INTERFACE_INFO(0x04CA, 0x8602, 0xff, 0xff, 0xff), - .driver_info = (kernel_ulong_t)&(rtw8822b_hw_spec) }, /* LiteOn */ - { USB_DEVICE_AND_INTERFACE_INFO(0x056E, 0x4011, 0xff, 0xff, 0xff), - .driver_info = (kernel_ulong_t)&(rtw8822b_hw_spec) }, /* Elecom */ - { USB_DEVICE_AND_INTERFACE_INFO(0x0846, 0x9055, 0xff, 0xff, 0xff), - .driver_info = (kernel_ulong_t)&(rtw8822b_hw_spec) }, /* Netgear A6150 */ - { USB_DEVICE_AND_INTERFACE_INFO(0x0B05, 0x1841, 0xff, 0xff, 0xff), + { USB_DEVICE_AND_INTERFACE_INFO(0x7392, 0xb822, 0xff, 0xff, 0xff), + .driver_info = (kernel_ulong_t)&(rtw8822b_hw_spec) }, /* Edimax EW-7822ULC */ + { USB_DEVICE_AND_INTERFACE_INFO(0x7392, 0xc822, 0xff, 0xff, 0xff), + .driver_info = (kernel_ulong_t)&(rtw8822b_hw_spec) }, /* Edimax EW-7822UTC */ + { USB_DEVICE_AND_INTERFACE_INFO(0x7392, 0xd822, 0xff, 0xff, 0xff), + .driver_info = (kernel_ulong_t)&(rtw8822b_hw_spec) }, /* Edimax */ + { USB_DEVICE_AND_INTERFACE_INFO(0x7392, 0xe822, 0xff, 0xff, 0xff), + .driver_info = (kernel_ulong_t)&(rtw8822b_hw_spec) }, /* Edimax */ + { USB_DEVICE_AND_INTERFACE_INFO(0x7392, 0xf822, 0xff, 0xff, 0xff), + .driver_info = (kernel_ulong_t)&(rtw8822b_hw_spec) }, /* Edimax EW-7822UAD */ + { USB_DEVICE_AND_INTERFACE_INFO(RTW_USB_VENDOR_ID_REALTEK, 0xb81a, 0xff, 0xff, 0xff), + .driver_info = (kernel_ulong_t)&(rtw8822b_hw_spec) }, /* Default ID */ + { USB_DEVICE_AND_INTERFACE_INFO(0x0b05, 0x1841, 0xff, 0xff, 0xff), .driver_info = (kernel_ulong_t)&(rtw8822b_hw_spec) }, /* ASUS AC1300 USB-AC55 B1 */ - { USB_DEVICE_AND_INTERFACE_INFO(0x0B05, 0x184C, 0xff, 0xff, 0xff), + { USB_DEVICE_AND_INTERFACE_INFO(0x0b05, 0x184c, 0xff, 0xff, 0xff), .driver_info = (kernel_ulong_t)&(rtw8822b_hw_spec) }, /* ASUS U2 */ + { USB_DEVICE_AND_INTERFACE_INFO(0x0B05, 0x19aa, 0xff, 0xff, 0xff), + .driver_info = (kernel_ulong_t)&(rtw8822b_hw_spec) }, /* ASUS - USB-AC58 rev A1 */ { USB_DEVICE_AND_INTERFACE_INFO(0x0B05, 0x1870, 0xff, 0xff, 0xff), .driver_info = (kernel_ulong_t)&(rtw8822b_hw_spec) }, /* ASUS */ { USB_DEVICE_AND_INTERFACE_INFO(0x0B05, 0x1874, 0xff, 0xff, 0xff), .driver_info = (kernel_ulong_t)&(rtw8822b_hw_spec) }, /* ASUS */ - { USB_DEVICE_AND_INTERFACE_INFO(0x0B05, 0x19AA, 0xff, 0xff, 0xff), - .driver_info = (kernel_ulong_t)&(rtw8822b_hw_spec) }, /* ASUS - USB-AC58 rev A1 */ - { USB_DEVICE_AND_INTERFACE_INFO(0x0E66, 0x0025, 0xff, 0xff, 0xff), - .driver_info = (kernel_ulong_t)&(rtw8822b_hw_spec) }, /* Hawking HW12ACU */ - { USB_DEVICE_AND_INTERFACE_INFO(0x13B1, 0x0043, 0xff, 0xff, 0xff), + { USB_DEVICE_AND_INTERFACE_INFO(0x2001, 0x331e, 0xff, 0xff, 0xff), + .driver_info = (kernel_ulong_t)&(rtw8822b_hw_spec) }, /* Dlink - DWA-181 */ + { USB_DEVICE_AND_INTERFACE_INFO(0x2001, 0x331c, 0xff, 0xff, 0xff), + .driver_info = (kernel_ulong_t)&(rtw8822b_hw_spec) }, /* Dlink - DWA-182 - D1 */ + {USB_DEVICE_AND_INTERFACE_INFO(0x2001, 0x331f, 0xff, 0xff, 0xff), + .driver_info = (kernel_ulong_t)&(rtw8822b_hw_spec)}, /* Dlink - DWA-183 D Ver */ + { USB_DEVICE_AND_INTERFACE_INFO(0x13b1, 0x0043, 0xff, 0xff, 0xff), .driver_info = (kernel_ulong_t)&(rtw8822b_hw_spec) }, /* Linksys WUSB6400M */ - { USB_DEVICE_AND_INTERFACE_INFO(0x13B1, 0x0045, 0xff, 0xff, 0xff), + { USB_DEVICE_AND_INTERFACE_INFO(0x13b1, 0x0045, 0xff, 0xff, 0xff), .driver_info = (kernel_ulong_t)&(rtw8822b_hw_spec) }, /* Linksys WUSB3600 v2 */ - { USB_DEVICE_AND_INTERFACE_INFO(0x2001, 0x331C, 0xff, 0xff, 0xff), - .driver_info = (kernel_ulong_t)&(rtw8822b_hw_spec) }, /* Dlink - DWA-182 - D1 */ - { USB_DEVICE_AND_INTERFACE_INFO(0x2001, 0x331E, 0xff, 0xff, 0xff), - .driver_info = (kernel_ulong_t)&(rtw8822b_hw_spec) }, /* Dlink - DWA-181 */ - { USB_DEVICE_AND_INTERFACE_INFO(0x2001, 0x331F, 0xff, 0xff, 0xff), - .driver_info = (kernel_ulong_t)&(rtw8822b_hw_spec) }, /* Dlink - DWA-183 - D */ - { USB_DEVICE_AND_INTERFACE_INFO(0x2001, 0x3322, 0xff, 0xff, 0xff), - .driver_info = (kernel_ulong_t)&(rtw8822b_hw_spec) }, /* Dlink - DWA-T185 rev. A1 */ - { USB_DEVICE_AND_INTERFACE_INFO(0x20F4, 0x805A, 0xff, 0xff, 0xff), - .driver_info = (kernel_ulong_t)&(rtw8822b_hw_spec) }, /* TRENDnet TEW-805UBH */ - { USB_DEVICE_AND_INTERFACE_INFO(0x20F4, 0x808A, 0xff, 0xff, 0xff), - .driver_info = (kernel_ulong_t)&(rtw8822b_hw_spec) }, /* TRENDnet TEW-808UBM */ + { USB_DEVICE_AND_INTERFACE_INFO(0x2357, 0x012d, 0xff, 0xff, 0xff), + .driver_info = (kernel_ulong_t)&(rtw8822b_hw_spec) }, /* TP-Link Archer T3U v1 */ + { USB_DEVICE_AND_INTERFACE_INFO(0x2357, 0x0138, 0xff, 0xff, 0xff), + .driver_info = (kernel_ulong_t)&(rtw8822b_hw_spec) }, /* TP-Link Archer T3U Plus v1 */ { USB_DEVICE_AND_INTERFACE_INFO(0x2357, 0x0115, 0xff, 0xff, 0xff), .driver_info = (kernel_ulong_t)&(rtw8822b_hw_spec) }, /* TP-Link Archer T4U V3 */ + { USB_DEVICE_AND_INTERFACE_INFO(0x2357, 0x012e, 0xff, 0xff, 0xff), + .driver_info = (kernel_ulong_t)&(rtw8822b_hw_spec) }, /* TP-LINK */ { USB_DEVICE_AND_INTERFACE_INFO(0x2357, 0x0116, 0xff, 0xff, 0xff), .driver_info = (kernel_ulong_t)&(rtw8822b_hw_spec) }, /* TP-LINK */ { USB_DEVICE_AND_INTERFACE_INFO(0x2357, 0x0117, 0xff, 0xff, 0xff), .driver_info = (kernel_ulong_t)&(rtw8822b_hw_spec) }, /* TP-LINK */ - { USB_DEVICE_AND_INTERFACE_INFO(0x2357, 0x012D, 0xff, 0xff, 0xff), - .driver_info = (kernel_ulong_t)&(rtw8822b_hw_spec) }, /* TP-Link Archer T3U v1 */ - { USB_DEVICE_AND_INTERFACE_INFO(0x2357, 0x012E, 0xff, 0xff, 0xff), - .driver_info = (kernel_ulong_t)&(rtw8822b_hw_spec) }, /* TP-LINK */ - { USB_DEVICE_AND_INTERFACE_INFO(0x2357, 0x0138, 0xff, 0xff, 0xff), - .driver_info = (kernel_ulong_t)&(rtw8822b_hw_spec) }, /* TP-Link Archer T3U Plus v1 */ - { USB_DEVICE_AND_INTERFACE_INFO(0x2C4E, 0x0107, 0xff, 0xff, 0xff), + { USB_DEVICE_AND_INTERFACE_INFO(0x0846, 0x9055, 0xff, 0xff, 0xff), + .driver_info = (kernel_ulong_t)&(rtw8822b_hw_spec) }, /* Netgear A6150 */ + { USB_DEVICE_AND_INTERFACE_INFO(0x0e66, 0x0025, 0xff, 0xff, 0xff), + .driver_info = (kernel_ulong_t)&(rtw8822b_hw_spec) }, /* Hawking HW12ACU */ + { USB_DEVICE_AND_INTERFACE_INFO(0x04ca, 0x8602, 0xff, 0xff, 0xff), + .driver_info = (kernel_ulong_t)&(rtw8822b_hw_spec) }, /* LiteOn */ + { USB_DEVICE_AND_INTERFACE_INFO(0x20f4, 0x808a, 0xff, 0xff, 0xff), + .driver_info = (kernel_ulong_t)&(rtw8822b_hw_spec) }, /* TRENDnet TEW-808UBM */ + { USB_DEVICE_AND_INTERFACE_INFO(0x20f4, 0x805a, 0xff, 0xff, 0xff), + .driver_info = (kernel_ulong_t)&(rtw8822b_hw_spec) }, /* TRENDnet TEW-805UBH */ + { USB_DEVICE_AND_INTERFACE_INFO(0x056e, 0x4011, 0xff, 0xff, 0xff), + .driver_info = (kernel_ulong_t)&(rtw8822b_hw_spec) }, /* ELECOM WDB-867DU3S */ + { USB_DEVICE_AND_INTERFACE_INFO(0x2c4e, 0x0107, 0xff, 0xff, 0xff), .driver_info = (kernel_ulong_t)&(rtw8822b_hw_spec) }, /* Mercusys MA30H */ - { USB_DEVICE_AND_INTERFACE_INFO(0x2C4E, 0x010a, 0xff, 0xff, 0xff), + { USB_DEVICE_AND_INTERFACE_INFO(0x2c4e, 0x010a, 0xff, 0xff, 0xff), .driver_info = (kernel_ulong_t)&(rtw8822b_hw_spec) }, /* Mercusys MA30N */ - { USB_DEVICE_AND_INTERFACE_INFO(0x7392, 0xB822, 0xff, 0xff, 0xff), - .driver_info = (kernel_ulong_t)&(rtw8822b_hw_spec) }, /* Edimax EW-7822ULC */ - { USB_DEVICE_AND_INTERFACE_INFO(0x7392, 0xC822, 0xff, 0xff, 0xff), - .driver_info = (kernel_ulong_t)&(rtw8822b_hw_spec) }, /* Edimax EW-7822UTC */ - { USB_DEVICE_AND_INTERFACE_INFO(0x7392, 0xD822, 0xff, 0xff, 0xff), - .driver_info = (kernel_ulong_t)&(rtw8822b_hw_spec) }, /* Edimax */ - { USB_DEVICE_AND_INTERFACE_INFO(0x7392, 0xE822, 0xff, 0xff, 0xff), - .driver_info = (kernel_ulong_t)&(rtw8822b_hw_spec) }, /* Edimax */ - { USB_DEVICE_AND_INTERFACE_INFO(0x7392, 0xF822, 0xff, 0xff, 0xff), - .driver_info = (kernel_ulong_t)&(rtw8822b_hw_spec) }, /* Edimax EW-7822UAD */ + { USB_DEVICE_AND_INTERFACE_INFO(0x2001, 0x3322, 0xff, 0xff, 0xff), + .driver_info = (kernel_ulong_t)&(rtw8822b_hw_spec) }, /* D-Link DWA-T185 rev. A1 */ {}, }; MODULE_DEVICE_TABLE(usb, rtw_8822bu_id_table); From fc834dcc2bf86b266b260d2e56b20b92800407e6 Mon Sep 17 00:00:00 2001 From: Bitterblue Smith Date: Fri, 14 Mar 2025 22:26:04 +0200 Subject: [PATCH 154/193] Sync the LED support Signed-off-by: Bitterblue Smith --- Makefile | 2 ++ main.c | 81 +----------------------------------------------------- main.h | 4 --- rtw8812a.c | 6 ---- rtw8814a.c | 4 --- rtw8821a.c | 6 ---- rtw8821c.c | 6 ---- rtw8822b.c | 6 ---- rtw8822c.c | 6 ---- 9 files changed, 3 insertions(+), 118 deletions(-) diff --git a/Makefile b/Makefile index 63c5f002..bfc3a8ff 100644 --- a/Makefile +++ b/Makefile @@ -43,12 +43,14 @@ EXTRA_CFLAGS += -DCONFIG_RTW88_8821CE=1 EXTRA_CFLAGS += -DCONFIG_RTW88_8822CE=1 EXTRA_CFLAGS += -DCONFIG_RTW88_8723DE=1 endif +EXTRA_CFLAGS += -DCONFIG_RTW88_LEDS=1 EXTRA_CFLAGS += -DCONFIG_RTW88_DEBUG=1 EXTRA_CFLAGS += -DCONFIG_RTW88_DEBUGFS=1 #EXTRA_CFLAGS += -DCONFIG_RTW88_REGD_USER_REG_HINTS obj-m += rtw_core.o rtw_core-objs += main.o \ + led.o \ mac80211.o \ util.o \ debug.o \ diff --git a/main.c b/main.c index 03b5d42d..6e7bb981 100644 --- a/main.c +++ b/main.c @@ -19,6 +19,7 @@ #include "bf.h" #include "sar.h" #include "sdio.h" +#include "led.h" bool rtw_disable_lps_deep_mode; EXPORT_SYMBOL(rtw_disable_lps_deep_mode); @@ -2332,86 +2333,6 @@ void rtw_core_deinit(struct rtw_dev *rtwdev) } EXPORT_SYMBOL(rtw_core_deinit); -#ifdef CONFIG_LEDS_CLASS - -static int rtw_led_set_blocking(struct led_classdev *led, - enum led_brightness brightness) -{ - struct rtw_dev *rtwdev = container_of(led, struct rtw_dev, led_cdev); - - rtwdev->chip->ops->led_set(led, brightness); - - return 0; -} - -static void rtw_led_init(struct rtw_dev *rtwdev) -{ - static const struct ieee80211_tpt_blink rtw_tpt_blink[] = { - { .throughput = 0 * 1024, .blink_time = 334 }, - { .throughput = 1 * 1024, .blink_time = 260 }, - { .throughput = 5 * 1024, .blink_time = 220 }, - { .throughput = 10 * 1024, .blink_time = 190 }, - { .throughput = 20 * 1024, .blink_time = 170 }, - { .throughput = 50 * 1024, .blink_time = 150 }, - { .throughput = 70 * 1024, .blink_time = 130 }, - { .throughput = 100 * 1024, .blink_time = 110 }, - { .throughput = 200 * 1024, .blink_time = 80 }, - { .throughput = 300 * 1024, .blink_time = 50 }, - }; - struct led_classdev *led = &rtwdev->led_cdev; - int err; - - if (!rtwdev->chip->ops->led_set) - return; - - if (rtw_hci_type(rtwdev) == RTW_HCI_TYPE_PCIE) - led->brightness_set = rtwdev->chip->ops->led_set; - else - led->brightness_set_blocking = rtw_led_set_blocking; - - snprintf(rtwdev->led_name, sizeof(rtwdev->led_name), - "rtw88-%s", dev_name(rtwdev->dev)); - - led->name = rtwdev->led_name; - led->max_brightness = LED_ON; - led->default_trigger = - ieee80211_create_tpt_led_trigger(rtwdev->hw, - IEEE80211_TPT_LEDTRIG_FL_RADIO, - rtw_tpt_blink, - ARRAY_SIZE(rtw_tpt_blink)); - - err = led_classdev_register(rtwdev->dev, led); - if (err) { - rtw_warn(rtwdev, "Failed to register the LED, error %d\n", err); - return; - } - - rtwdev->led_registered = true; -} - -static void rtw_led_deinit(struct rtw_dev *rtwdev) -{ - struct led_classdev *led = &rtwdev->led_cdev; - - if (!rtwdev->led_registered) - return; - - rtwdev->chip->ops->led_set(led, LED_OFF); - led_classdev_unregister(led); -} - -#else - -static void rtw_led_init(struct rtw_dev *rtwdev) -{ -} - -static void rtw_led_deinit(struct rtw_dev *rtwdev) -{ -} - -#endif - int rtw_register_hw(struct rtw_dev *rtwdev, struct ieee80211_hw *hw) { bool sta_mode_only = false; /*rtwdev->hci.type == RTW_HCI_TYPE_SDIO;*/ diff --git a/main.h b/main.h index 66fb4994..12e302c7 100644 --- a/main.h +++ b/main.h @@ -1038,9 +1038,7 @@ struct rtw_chip_ops { bool is_tx2_path); void (*config_txrx_mode)(struct rtw_dev *rtwdev, u8 tx_path, u8 rx_path, bool is_tx2_path); -#ifdef CONFIG_LEDS_CLASS void (*led_set)(struct led_classdev *led, enum led_brightness brightness); -#endif /* for USB/SDIO only */ void (*fill_txdesc_checksum)(struct rtw_dev *rtwdev, struct rtw_tx_pkt_info *pkt_info, @@ -2265,11 +2263,9 @@ struct rtw_dev { struct completion fw_scan_density; bool ap_active; -#ifdef CONFIG_LEDS_CLASS bool led_registered; char led_name[32]; struct led_classdev led_cdev; -#endif /* hci related data, must be last */ u8 priv[] __aligned(sizeof(void *)); diff --git a/rtw8812a.c b/rtw8812a.c index 94e59bd2..41f17859 100644 --- a/rtw8812a.c +++ b/rtw8812a.c @@ -878,8 +878,6 @@ static void rtw8812a_pwr_track(struct rtw_dev *rtwdev) dm_info->pwr_trk_triggered = false; } -#ifdef CONFIG_LEDS_CLASS - static void rtw8812a_led_set(struct led_classdev *led, enum led_brightness brightness) { @@ -896,8 +894,6 @@ static void rtw8812a_led_set(struct led_classdev *led, rtw_write8(rtwdev, REG_LED_CFG, ledcfg); } -#endif - static void rtw8812a_fill_txdesc_checksum(struct rtw_dev *rtwdev, struct rtw_tx_pkt_info *pkt_info, u8 *txdesc) @@ -947,9 +943,7 @@ static const struct rtw_chip_ops rtw8812a_ops = { .config_bfee = NULL, .set_gid_table = NULL, .cfg_csi_rate = NULL, -#ifdef CONFIG_LEDS_CLASS .led_set = rtw8812a_led_set, -#endif .fill_txdesc_checksum = rtw8812a_fill_txdesc_checksum, .coex_set_init = rtw8812a_coex_cfg_init, .coex_set_ant_switch = NULL, diff --git a/rtw8814a.c b/rtw8814a.c index b1bb790c..e954c041 100644 --- a/rtw8814a.c +++ b/rtw8814a.c @@ -2012,8 +2012,6 @@ static void rtw8814a_phy_cck_pd_set(struct rtw_dev *rtwdev, u8 new_lvl) rtw_write8(rtwdev, REG_CCK_PD_TH, pd[new_lvl]); } -#ifdef CONFIG_LEDS_CLASS - static void rtw8814a_led_set(struct led_classdev *led, enum led_brightness brightness) { @@ -2033,8 +2031,6 @@ static void rtw8814a_led_set(struct led_classdev *led, rtw_write32(rtwdev, REG_GPIO_PIN_CTRL_2, led_gpio_cfg); } -#endif - static void rtw8814a_fill_txdesc_checksum(struct rtw_dev *rtwdev, struct rtw_tx_pkt_info *pkt_info, u8 *txdesc) diff --git a/rtw8821a.c b/rtw8821a.c index 501b2a00..b9716669 100644 --- a/rtw8821a.c +++ b/rtw8821a.c @@ -716,8 +716,6 @@ static void rtw8821a_pwr_track(struct rtw_dev *rtwdev) dm_info->pwr_trk_triggered = false; } -#ifdef CONFIG_LEDS_CLASS - static void rtw8821a_led_set(struct led_classdev *led, enum led_brightness brightness) { @@ -743,8 +741,6 @@ static void rtw8821a_led_set(struct led_classdev *led, } } -#endif - static void rtw8821a_fill_txdesc_checksum(struct rtw_dev *rtwdev, struct rtw_tx_pkt_info *pkt_info, u8 *txdesc) @@ -893,9 +889,7 @@ static const struct rtw_chip_ops rtw8821a_ops = { .config_bfee = NULL, .set_gid_table = NULL, .cfg_csi_rate = NULL, -#ifdef CONFIG_LEDS_CLASS .led_set = rtw8821a_led_set, -#endif .fill_txdesc_checksum = rtw8821a_fill_txdesc_checksum, .coex_set_init = rtw8821a_coex_cfg_init, .coex_set_ant_switch = rtw8821a_coex_cfg_ant_switch, diff --git a/rtw8821c.c b/rtw8821c.c index 32ba6f80..8704c1bf 100644 --- a/rtw8821c.c +++ b/rtw8821c.c @@ -1214,8 +1214,6 @@ static void rtw8821c_phy_cck_pd_set(struct rtw_dev *rtwdev, u8 new_lvl) dm_info->cck_pd_default + new_lvl * 2); } -#ifdef CONFIG_LEDS_CLASS - static void rtw8821c_led_set(struct led_classdev *led, enum led_brightness brightness) { @@ -1234,8 +1232,6 @@ static void rtw8821c_led_set(struct led_classdev *led, rtw_write32(rtwdev, REG_LED_CFG, ledcfg); } -#endif - static void rtw8821c_fill_txdesc_checksum(struct rtw_dev *rtwdev, struct rtw_tx_pkt_info *pkt_info, u8 *txdesc) @@ -1686,9 +1682,7 @@ static const struct rtw_chip_ops rtw8821c_ops = { .config_bfee = rtw8821c_bf_config_bfee, .set_gid_table = rtw_bf_set_gid_table, .cfg_csi_rate = rtw_bf_cfg_csi_rate, -#ifdef CONFIG_LEDS_CLASS .led_set = rtw8821c_led_set, -#endif .fill_txdesc_checksum = rtw8821c_fill_txdesc_checksum, .coex_set_init = rtw8821c_coex_cfg_init, diff --git a/rtw8822b.c b/rtw8822b.c index 80c55dae..3d3c4a4e 100644 --- a/rtw8822b.c +++ b/rtw8822b.c @@ -1573,8 +1573,6 @@ static void rtw8822b_adaptivity(struct rtw_dev *rtwdev) rtw_phy_set_edcca_th(rtwdev, l2h, h2l); } -#ifdef CONFIG_LEDS_CLASS - static void rtw8822b_led_set(struct led_classdev *led, enum led_brightness brightness) { @@ -1593,8 +1591,6 @@ static void rtw8822b_led_set(struct led_classdev *led, rtw_write32(rtwdev, REG_LED_CFG, ledcfg); } -#endif - static void rtw8822b_fill_txdesc_checksum(struct rtw_dev *rtwdev, struct rtw_tx_pkt_info *pkt_info, u8 *txdesc) @@ -2176,9 +2172,7 @@ static const struct rtw_chip_ops rtw8822b_ops = { .cfg_csi_rate = rtw_bf_cfg_csi_rate, .adaptivity_init = rtw8822b_adaptivity_init, .adaptivity = rtw8822b_adaptivity, -#ifdef CONFIG_LEDS_CLASS .led_set = rtw8822b_led_set, -#endif .fill_txdesc_checksum = rtw8822b_fill_txdesc_checksum, .coex_set_init = rtw8822b_coex_cfg_init, diff --git a/rtw8822c.c b/rtw8822c.c index ec62a73b..72f13722 100644 --- a/rtw8822c.c +++ b/rtw8822c.c @@ -4542,8 +4542,6 @@ static void rtw8822c_adaptivity(struct rtw_dev *rtwdev) rtw_phy_set_edcca_th(rtwdev, l2h, h2l); } -#ifdef CONFIG_LEDS_CLASS - static void rtw8822c_led_set(struct led_classdev *led, enum led_brightness brightness) { @@ -4562,8 +4560,6 @@ static void rtw8822c_led_set(struct led_classdev *led, rtw_write32(rtwdev, REG_LED_CFG, ledcfg); } -#endif - static void rtw8822c_fill_txdesc_checksum(struct rtw_dev *rtwdev, struct rtw_tx_pkt_info *pkt_info, u8 *txdesc) @@ -4992,9 +4988,7 @@ static const struct rtw_chip_ops rtw8822c_ops = { .cfo_track = rtw8822c_cfo_track, .config_tx_path = rtw8822c_config_tx_path, .config_txrx_mode = rtw8822c_config_trx_mode, -#ifdef CONFIG_LEDS_CLASS .led_set = rtw8822c_led_set, -#endif .fill_txdesc_checksum = rtw8822c_fill_txdesc_checksum, .coex_set_init = rtw8822c_coex_cfg_init, From 2ad1e9a21af44d32ae9c3d31470f277733b74e70 Mon Sep 17 00:00:00 2001 From: Bitterblue Smith Date: Fri, 14 Mar 2025 22:27:25 +0200 Subject: [PATCH 155/193] Sync check_positive Signed-off-by: Bitterblue Smith --- phy.c | 25 +++++++++++++------------ 1 file changed, 13 insertions(+), 12 deletions(-) diff --git a/phy.c b/phy.c index d95a0ef2..88664662 100644 --- a/phy.c +++ b/phy.c @@ -1149,22 +1149,23 @@ static bool check_positive(struct rtw_dev *rtwdev, struct rtw_phy_cond cond, if (rtwdev->chip->id == RTW_CHIP_TYPE_8812A || rtwdev->chip->id == RTW_CHIP_TYPE_8821A) { - if (cond.rfe & 0x0f) { - if ((cond.rfe & drv_cond.rfe) != cond.rfe) - return false; + if (!(cond.rfe & 0x0f)) + return true; - if ((cond.rfe & BIT(0)) && cond2.type_glna != drv_cond2.type_glna) - return false; + if ((cond.rfe & drv_cond.rfe) != cond.rfe) + return false; - if ((cond.rfe & BIT(1)) && cond2.type_gpa != drv_cond2.type_gpa) - return false; + if ((cond.rfe & BIT(0)) && cond2.type_glna != drv_cond2.type_glna) + return false; - if ((cond.rfe & BIT(2)) && cond2.type_alna != drv_cond2.type_alna) - return false; + if ((cond.rfe & BIT(1)) && cond2.type_gpa != drv_cond2.type_gpa) + return false; - if ((cond.rfe & BIT(3)) && cond2.type_apa != drv_cond2.type_apa) - return false; - } + if ((cond.rfe & BIT(2)) && cond2.type_alna != drv_cond2.type_alna) + return false; + + if ((cond.rfe & BIT(3)) && cond2.type_apa != drv_cond2.type_apa) + return false; } else { if (cond.rfe != drv_cond.rfe) return false; From d862b100d9e833ac8714b299a95c80b96bd964bd Mon Sep 17 00:00:00 2001 From: Bitterblue Smith Date: Fri, 14 Mar 2025 22:29:00 +0200 Subject: [PATCH 156/193] RTL8703B fixes Signed-off-by: Bitterblue Smith --- rtw8703b.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/rtw8703b.c b/rtw8703b.c index 52ff178d..7a80291f 100644 --- a/rtw8703b.c +++ b/rtw8703b.c @@ -858,7 +858,7 @@ static void rtw8703b_set_channel_bb(struct rtw_dev *rtwdev, u8 channel, u8 bw, rtw_write32_mask(rtwdev, REG_FPGA0_RFMOD, BIT_MASK_RFMOD, 0x0); rtw_write32_mask(rtwdev, REG_FPGA1_RFMOD, BIT_MASK_RFMOD, 0x0); rtw_write32_mask(rtwdev, REG_OFDM0_TX_PSD_NOISE, - GENMASK(31, 20), 0x0); + GENMASK(31, 30), 0x0); rtw_write32(rtwdev, REG_BBRX_DFIR, 0x4A880000); rtw_write32(rtwdev, REG_OFDM0_A_TX_AFE, 0x19F60000); break; @@ -1153,9 +1153,9 @@ static u8 rtw8703b_iqk_rx_path(struct rtw_dev *rtwdev, rtw_write32(rtwdev, REG_RXIQK_TONE_A_11N, 0x38008c1c); rtw_write32(rtwdev, REG_TX_IQK_TONE_B, 0x38008c1c); rtw_write32(rtwdev, REG_RX_IQK_TONE_B, 0x38008c1c); - rtw_write32(rtwdev, REG_TXIQK_PI_A_11N, 0x8216000f); + rtw_write32(rtwdev, REG_TXIQK_PI_A_11N, 0x8214030f); rtw_write32(rtwdev, REG_RXIQK_PI_A_11N, 0x28110000); - rtw_write32(rtwdev, REG_TXIQK_PI_B, 0x28110000); + rtw_write32(rtwdev, REG_TXIQK_PI_B, 0x82110000); rtw_write32(rtwdev, REG_RXIQK_PI_B, 0x28110000); /* LOK setting */ @@ -1327,7 +1327,7 @@ void rtw8703b_iqk_fill_a_matrix(struct rtw_dev *rtwdev, const s32 result[]) return; tmp_rx_iqi |= FIELD_PREP(BIT_MASK_RXIQ_S1_X, result[IQK_S1_RX_X]); - tmp_rx_iqi |= FIELD_PREP(BIT_MASK_RXIQ_S1_Y1, result[IQK_S1_RX_X]); + tmp_rx_iqi |= FIELD_PREP(BIT_MASK_RXIQ_S1_Y1, result[IQK_S1_RX_Y]); rtw_write32(rtwdev, REG_A_RXIQI, tmp_rx_iqi); rtw_write32_mask(rtwdev, REG_RXIQK_MATRIX_LSB_11N, BIT_MASK_RXIQ_S1_Y2, BIT_SET_RXIQ_S1_Y2(result[IQK_S1_RX_Y])); From b1ff8c5d5d4d49d846eb6d15d8c9ec9fdd4a4c88 Mon Sep 17 00:00:00 2001 From: Bitterblue Smith Date: Fri, 14 Mar 2025 22:29:51 +0200 Subject: [PATCH 157/193] Sync rtw8812au.c Signed-off-by: Bitterblue Smith --- rtw8812au.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rtw8812au.c b/rtw8812au.c index f2548f2f..e18995f4 100644 --- a/rtw8812au.c +++ b/rtw8812au.c @@ -19,7 +19,7 @@ static const struct usb_device_id rtw_8812au_id_table[] = { .driver_info = (kernel_ulong_t)&(rtw8812a_hw_spec) }, { USB_DEVICE_AND_INTERFACE_INFO(0x0409, 0x0408, 0xff, 0xff, 0xff), .driver_info = (kernel_ulong_t)&(rtw8812a_hw_spec) }, /* NEC */ - { USB_DEVICE_AND_INTERFACE_INFO(0x0411, 0x025D, 0xff, 0xff, 0xff), + { USB_DEVICE_AND_INTERFACE_INFO(0x0411, 0x025d, 0xff, 0xff, 0xff), .driver_info = (kernel_ulong_t)&(rtw8812a_hw_spec) }, /* Buffalo */ { USB_DEVICE_AND_INTERFACE_INFO(0x04bb, 0x0952, 0xff, 0xff, 0xff), .driver_info = (kernel_ulong_t)&(rtw8812a_hw_spec) }, /* I-O DATA */ From e7960104170dd166f1a41785e728e4e52059009b Mon Sep 17 00:00:00 2001 From: Bitterblue Smith Date: Fri, 14 Mar 2025 22:32:40 +0200 Subject: [PATCH 158/193] Sync RTL8814A code Signed-off-by: Bitterblue Smith --- reg.h | 27 +++++++- rtw8814a.c | 190 ++++++++++++++++++++++++++-------------------------- rtw8814a.h | 2 - rtw8814ae.c | 2 +- 4 files changed, 121 insertions(+), 100 deletions(-) diff --git a/reg.h b/reg.h index f8bf7d3e..08e94949 100644 --- a/reg.h +++ b/reg.h @@ -40,8 +40,8 @@ #define BIT_RF_RSTB BIT(1) #define BIT_RF_EN BIT(0) -#define REG_RF_CTRL1 0x20 -#define REG_RF_CTRL2 0x21 +#define REG_RF_CTRL1 0x0020 +#define REG_RF_CTRL2 0x0021 #define REG_AFE_CTRL1 0x0024 #define BIT_MAC_CLK_SEL (BIT(20) | BIT(21)) @@ -116,7 +116,7 @@ #define BIT_SDIO_PAD_E5 BIT(18) #define REG_RF_B_CTRL 0x76 -#define REG_RF_CTRL3 0x76 +#define REG_RF_CTRL3 0x0076 #define REG_AFE_CTRL_4 0x0078 #define BIT_CK320M_AFE_EN BIT(4) @@ -622,8 +622,11 @@ #define REG_FPGA0_XCD_RF_PARA 0x08B4 #define REG_RX_MCS_LIMIT 0x08BC #define REG_ADC160 0x08C4 +#define REG_DBGSEL 0x08fc #define REG_ANTSEL_SW 0x0900 #define REG_DAC_RSTB 0x090c +#define REG_PSD 0x0910 +#define BIT_PSD_INI GENMASK(23, 22) #define REG_SINGLE_TONE_CONT_TX 0x0914 #define REG_AGC_TABLE 0x0958 #define REG_RFE_CTRL_E 0x0974 @@ -635,8 +638,14 @@ #define REG_FAS 0x09a4 #define REG_RXSB 0x0a00 +#define BIT_RXSB_ANA_DIV BIT(15) #define REG_CCK_RX 0x0a04 #define REG_CCK_PD_TH 0x0a0a +#define REG_PRECTRL 0x0a14 +#define BIT_DIS_CO_PATHSEL BIT(7) +#define BIT_IQ_WGT GENMASK(9, 8) +#define REG_CCA_MF 0x0a20 +#define BIT_MBC_WIN GENMASK(5, 4) #define REG_CCK0_TX_FILTER1 0x0a20 #define REG_CCK0_TX_FILTER2 0x0a24 #define REG_CCK0_DEBUG_PORT 0x0a28 @@ -659,6 +668,13 @@ #define DIS_DPD_RATEVHT2SS_MCS1 BIT(9) #define DIS_DPD_RATEALL GENMASK(9, 0) +#define REG_CCA 0x0a70 +#define BIT_CCA_CO BIT(7) +#define REG_ANTSEL 0x0a74 +#define BIT_ANT_BYCO BIT(8) +#define REG_CCKTX 0x0a84 +#define BIT_CMB_CCA_2R BIT(28) + #define REG_CNTRST 0x0b58 #define REG_3WIRE_SWA 0x0c00 @@ -764,6 +780,7 @@ #define REG_CRC_HT 0x0f10 #define REG_CRC_OFDM 0x0f14 #define REG_FA_OFDM 0x0f48 +#define REG_DBGRPT 0x0fa0 #define REG_CCA_CCK 0x0fcc #define REG_SYS_CFG3_8814A 0x1000 @@ -895,6 +912,7 @@ #define REG_RFE_PINMUX_C 0x18b4 #define REG_RFESEL_CTRL 0x1990 +#define REG_AGC_TBL 0x1998 #define REG_RX_IQC_AB_D 0x1a10 #define REG_RX_IQC_CD_D 0x1a14 @@ -903,6 +921,8 @@ #define REG_AFE_PWR1_D 0x1a60 #define REG_TX_AGC_D 0x1a94 #define REG_RFE_PINMUX_D 0x1ab4 +#define REG_RFE_INVSEL_D 0x1abc +#define BIT_RFE_SELSW0_D GENMASK(27, 20) #define REG_NOMASK_TXBT 0x1ca7 #define REG_ANAPAR 0x1c30 @@ -943,6 +963,7 @@ #define RF18_BAND_MASK (BIT(16) | BIT(9) | BIT(8)) #define RF18_CHANNEL_MASK (MASKBYTE0) #define RF18_RFSI_MASK (BIT(18) | BIT(17)) +#define RF_RCK1_V1 0x1c #define RF_RCK 0x1d #define RF_MODE_TABLE_ADDR 0x30 #define RF_MODE_TABLE_DATA0 0x31 diff --git a/rtw8814a.c b/rtw8814a.c index e954c041..c1b0dda4 100644 --- a/rtw8814a.c +++ b/rtw8814a.c @@ -267,17 +267,17 @@ static void rtw8814a_config_cck_rx_antenna_init(struct rtw_dev *rtwdev) /* CCK 2R CCA parameters */ /* Disable Ant diversity */ - rtw_write32_mask(rtwdev, REG_RXSB, BIT(15), 0x0); + rtw_write32_mask(rtwdev, REG_RXSB, BIT_RXSB_ANA_DIV, 0x0); /* Concurrent CCA at LSB & USB */ - rtw_write32_mask(rtwdev, 0xa70, BIT(7), 0); + rtw_write32_mask(rtwdev, REG_CCA, BIT_CCA_CO, 0); /* RX path diversity enable */ - rtw_write32_mask(rtwdev, 0xa74, BIT(8), 0); + rtw_write32_mask(rtwdev, REG_ANTSEL, BIT_ANT_BYCO, 0); /* r_en_mrc_antsel */ - rtw_write32_mask(rtwdev, 0xa14, BIT(7), 0); + rtw_write32_mask(rtwdev, REG_PRECTRL, BIT_DIS_CO_PATHSEL, 0); /* MBC weighting */ - rtw_write32_mask(rtwdev, 0xa20, BIT(5) | BIT(4), 1); + rtw_write32_mask(rtwdev, REG_CCA_MF, BIT_MBC_WIN, 1); /* 2R CCA only */ - rtw_write32_mask(rtwdev, 0xa84, BIT(28), 1); + rtw_write32_mask(rtwdev, REG_CCKTX, BIT_CMB_CCA_2R, 1); } static void rtw8814a_phy_set_param(struct rtw_dev *rtwdev) @@ -313,10 +313,10 @@ static void rtw8814a_phy_set_param(struct rtw_dev *rtwdev) for (rf_path = 0; rf_path < rtwdev->hal.rf_path_num; rf_path++) rtw_load_table(rtwdev, rtwdev->chip->rf_tbl[rf_path]); - val32 = rtw_read_rf(rtwdev, RF_PATH_A, RF_RCK1, RFREG_MASK); - rtw_write_rf(rtwdev, RF_PATH_B, RF_RCK1, RFREG_MASK, val32); - rtw_write_rf(rtwdev, RF_PATH_C, RF_RCK1, RFREG_MASK, val32); - rtw_write_rf(rtwdev, RF_PATH_D, RF_RCK1, RFREG_MASK, val32); + val32 = rtw_read_rf(rtwdev, RF_PATH_A, RF_RCK1_V1, RFREG_MASK); + rtw_write_rf(rtwdev, RF_PATH_B, RF_RCK1_V1, RFREG_MASK, val32); + rtw_write_rf(rtwdev, RF_PATH_C, RF_RCK1_V1, RFREG_MASK, val32); + rtw_write_rf(rtwdev, RF_PATH_D, RF_RCK1_V1, RFREG_MASK, val32); rtw_write32_set(rtwdev, REG_RXPSEL, BIT_RX_PSEL_RST); @@ -468,7 +468,8 @@ static void rtw8814a_set_rfe_reg_24g(struct rtw_dev *rtwdev) rtw_write32(rtwdev, REG_RFE_PINMUX_C, 0x72707270); rtw_write32(rtwdev, REG_RFE_PINMUX_D, 0x77707770); - rtw_write32_mask(rtwdev, 0x1ABC, 0x0ff00000, 0x72); + rtw_write32_mask(rtwdev, REG_RFE_INVSEL_D, + BIT_RFE_SELSW0_D, 0x72); break; case 1: @@ -477,7 +478,8 @@ static void rtw8814a_set_rfe_reg_24g(struct rtw_dev *rtwdev) rtw_write32(rtwdev, REG_RFE_PINMUX_C, 0x77777777); rtw_write32(rtwdev, REG_RFE_PINMUX_D, 0x77777777); - rtw_write32_mask(rtwdev, 0x1ABC, 0x0ff00000, 0x77); + rtw_write32_mask(rtwdev, REG_RFE_INVSEL_D, + BIT_RFE_SELSW0_D, 0x77); break; case 0: @@ -487,7 +489,8 @@ static void rtw8814a_set_rfe_reg_24g(struct rtw_dev *rtwdev) rtw_write32(rtwdev, REG_RFE_PINMUX_C, 0x77777777); /* Is it not necessary to set REG_RFE_PINMUX_D ? */ - rtw_write32_mask(rtwdev, 0x1ABC, 0x0ff00000, 0x77); + rtw_write32_mask(rtwdev, REG_RFE_INVSEL_D, + BIT_RFE_SELSW0_D, 0x77); break; } @@ -502,7 +505,8 @@ static void rtw8814a_set_rfe_reg_5g(struct rtw_dev *rtwdev) rtw_write32(rtwdev, REG_RFE_PINMUX_C, 0x37173717); rtw_write32(rtwdev, REG_RFE_PINMUX_D, 0x77177717); - rtw_write32_mask(rtwdev, 0x1ABC, 0x0ff00000, 0x37); + rtw_write32_mask(rtwdev, REG_RFE_INVSEL_D, + BIT_RFE_SELSW0_D, 0x37); break; case 1: @@ -511,7 +515,8 @@ static void rtw8814a_set_rfe_reg_5g(struct rtw_dev *rtwdev) rtw_write32(rtwdev, REG_RFE_PINMUX_C, 0x33173317); rtw_write32(rtwdev, REG_RFE_PINMUX_D, 0x77177717); - rtw_write32_mask(rtwdev, 0x1ABC, 0x0ff00000, 0x33); + rtw_write32_mask(rtwdev, REG_RFE_INVSEL_D, + BIT_RFE_SELSW0_D, 0x33); break; case 0: @@ -521,7 +526,8 @@ static void rtw8814a_set_rfe_reg_5g(struct rtw_dev *rtwdev) rtw_write32(rtwdev, REG_RFE_PINMUX_C, 0x54775477); rtw_write32(rtwdev, REG_RFE_PINMUX_D, 0x54775477); - rtw_write32_mask(rtwdev, 0x1ABC, 0x0ff00000, 0x54); + rtw_write32_mask(rtwdev, REG_RFE_INVSEL_D, + BIT_RFE_SELSW0_D, 0x54); break; } @@ -732,7 +738,6 @@ static void rtw8814a_set_bw_rf(struct rtw_dev *rtwdev, u8 bw) static void rtw8814a_adc_clk(struct rtw_dev *rtwdev) { - static const u32 rxiqc_reg[2][4] = { { REG_RX_IQC_AB_A, REG_RX_IQC_AB_B, REG_RX_IQC_AB_C, REG_RX_IQC_AB_D }, @@ -748,7 +753,7 @@ static void rtw8814a_adc_clk(struct rtw_dev *rtwdev) /* 1 Step1. MAC TX pause */ mac_reg_522 = rtw_read8(rtwdev, REG_TXPAUSE); - bb_reg_8fc = rtw_read32(rtwdev, 0x8fc); + bb_reg_8fc = rtw_read32(rtwdev, REG_DBGSEL); bb_reg_808 = rtw_read32(rtwdev, REG_RXPSEL); rtw_write8(rtwdev, REG_TXPAUSE, 0x3f); @@ -758,13 +763,13 @@ static void rtw8814a_adc_clk(struct rtw_dev *rtwdev) rtw_write32(rtwdev, rxiqc_reg[0][i], 0x0); rtw_write32(rtwdev, rxiqc_reg[1][i], 0x0); } - rtw_write32_mask(rtwdev, 0xa14, 0x00000300, 0x3); + rtw_write32_mask(rtwdev, REG_PRECTRL, BIT_IQ_WGT, 0x3); i = 0; /* 1 Step 3. Monitor MAC IDLE */ - rtw_write32(rtwdev, 0x8fc, 0x0); + rtw_write32(rtwdev, REG_DBGSEL, 0x0); while (mac_active) { - mac_active = rtw_read32(rtwdev, 0xfa0) & 0x803e0008; + mac_active = rtw_read32(rtwdev, REG_DBGRPT) & 0x803e0008; i++; if (i > 1000) break; @@ -836,13 +841,13 @@ static void rtw8814a_adc_clk(struct rtw_dev *rtwdev) /* 1 Step 5. Recover MAC TX & IQC */ rtw_write8(rtwdev, REG_TXPAUSE, mac_reg_522); - rtw_write32(rtwdev, 0x8fc, bb_reg_8fc); + rtw_write32(rtwdev, REG_DBGSEL, bb_reg_8fc); rtw_write32(rtwdev, REG_RXPSEL, bb_reg_808); for (i = 0; i < 4; i++) { rtw_write32(rtwdev, rxiqc_reg[0][i], rxiqc[i]); rtw_write32(rtwdev, rxiqc_reg[1][i], 0x01000000); } - rtw_write32_mask(rtwdev, 0xa14, 0x00000300, 0x0); + rtw_write32_mask(rtwdev, REG_PRECTRL, BIT_IQ_WGT, 0x0); } static void rtw8814a_spur_calibration_ch140(struct rtw_dev *rtwdev, u8 channel) @@ -1280,13 +1285,13 @@ rtw8814a_set_tx_power_index_by_rate(struct rtw_dev *rtwdev, u8 path, u8 rs) txagc_table_wd = 0x00801000; txagc_table_wd |= (pwr_index << 24) | (path << 8) | rate; - rtw_write32(rtwdev, 0x1998, txagc_table_wd); + rtw_write32(rtwdev, REG_AGC_TBL, txagc_table_wd); /* first time to turn on the txagc table * second to write the addr0 */ if (rate == DESC_RATE1M) - rtw_write32(rtwdev, 0x1998, txagc_table_wd); + rtw_write32(rtwdev, REG_AGC_TBL, txagc_table_wd); } } @@ -1508,13 +1513,13 @@ static void rtw8814a_iqk_configure_mac(struct rtw_dev *rtwdev) /* CCA off */ rtw_write32_mask(rtwdev, REG_CCA2ND, 0xf, 0xe); /* CCK RX path off */ - rtw_write32_set(rtwdev, 0xa14, BIT(9) | BIT(8)); + rtw_write32_set(rtwdev, REG_PRECTRL, BIT_IQ_WGT); rtw_write32(rtwdev, REG_RFE_PINMUX_A, 0x77777777); rtw_write32(rtwdev, REG_RFE_PINMUX_B, 0x77777777); rtw_write32(rtwdev, REG_RFE_PINMUX_C, 0x77777777); rtw_write32(rtwdev, REG_RFE_PINMUX_D, 0x77777777); - rtw_write32_mask(rtwdev, 0x1abc, 0x0ff00000, 0x77); - rtw_write32_mask(rtwdev, 0x910, BIT(23) | BIT(22), 0x0); + rtw_write32_mask(rtwdev, REG_RFE_INVSEL_D, BIT_RFE_SELSW0_D, 0x77); + rtw_write32_mask(rtwdev, REG_PSD, BIT_PSD_INI, 0x0); rtw_write32_mask(rtwdev, REG_RFE_INV0, 0xf, 0x0); } @@ -1584,7 +1589,7 @@ static void rtw8814a_iqk_tx_one_shot(struct rtw_dev *rtwdev, u8 path, rtw_write32(rtwdev, 0x1b00, iqk_cmd); - msleep(10); + usleep_range(10000, 11000); if (read_poll_timeout(!rtw_read32_mask, *tx_ok, *tx_ok, 1000, 20000, false, @@ -1649,7 +1654,7 @@ static void rtw8814a_iqk_rx_one_shot(struct rtw_dev *rtwdev, u8 path, 0x54775477); break; case 3: - rtw_write32(rtwdev, 0x1abc, 0x75400000); + rtw_write32(rtwdev, REG_RFE_INVSEL_D, 0x75400000); rtw_write32(rtwdev, REG_RFE_PINMUX_D, 0x77777777); break; @@ -1662,7 +1667,7 @@ static void rtw8814a_iqk_rx_one_shot(struct rtw_dev *rtwdev, u8 path, rtw_write32(rtwdev, 0x1b00, iqk_cmd); - msleep(10); + usleep_range(10000, 11000); if (read_poll_timeout(!rtw_read32_mask, rx_ok, rx_ok, 1000, 20000, false, @@ -1758,7 +1763,6 @@ static void rtw8814a_iqk(struct rtw_dev *rtwdev) static void rtw8814a_do_iqk(struct rtw_dev *rtwdev) { - static const u32 backup_mac_reg[MAC_REG_NUM_8814] = {0x520, 0x550}; static const u32 backup_bb_reg[BB_REG_NUM_8814] = { 0xa14, 0x808, 0x838, 0x90c, 0x810, 0xcb0, 0xeb0, @@ -2040,26 +2044,38 @@ static void rtw8814a_fill_txdesc_checksum(struct rtw_dev *rtwdev, fill_txdesc_checksum_common(txdesc, words); } -static const struct rtw_intf_phy_para_table phy_para_table_8814a = {}; - -static const struct rtw_hw_reg rtw8814a_dig[] = { - [0] = { .addr = 0xc50, .mask = 0x7f }, - [1] = { .addr = 0xe50, .mask = 0x7f }, - [2] = { .addr = 0x1850, .mask = 0x7f }, - [3] = { .addr = 0x1a50, .mask = 0x7f }, -}; +static const struct rtw_chip_ops rtw8814a_ops = { + .power_on = rtw_power_on, + .power_off = rtw_power_off, + .phy_set_param = rtw8814a_phy_set_param, + .read_efuse = rtw8814a_read_efuse, + .query_phy_status = rtw8814a_query_phy_status, + .set_channel = rtw8814a_set_channel, + .mac_init = rtw8814a_mac_init, + .read_rf = rtw_phy_read_rf, + .write_rf = rtw_phy_write_rf_reg_sipi, + .set_tx_power_index = rtw8814a_set_tx_power_index, + .set_antenna = NULL, + .cfg_ldo25 = rtw8814a_cfg_ldo25, + .efuse_grant = rtw8814a_efuse_grant, + .set_ampdu_factor = rtw8814a_set_ampdu_factor, + .false_alarm_statistics = rtw8814a_false_alarm_statistics, + .phy_calibration = rtw8814a_phy_calibration, + .cck_pd_set = rtw8814a_phy_cck_pd_set, + .pwr_track = rtw8814a_pwr_track, + .config_bfee = NULL, + .set_gid_table = NULL, + .cfg_csi_rate = NULL, + .led_set = rtw8814a_led_set, + .fill_txdesc_checksum = rtw8814a_fill_txdesc_checksum, -static const struct rtw_page_table page_table_8814a[] = { - /* SDIO */ - {0, 0, 0, 0, 0}, /* hq nq lq exq gapq */ - /* PCIE */ - {32, 32, 32, 32, 0}, - /* USB, 2 bulk out */ - {32, 32, 32, 32, 0}, - /* USB, 3 bulk out */ - {32, 32, 32, 32, 0}, - /* USB, 4 bulk out */ - {32, 32, 32, 32, 0}, + .coex_set_init = rtw8814a_coex_cfg_init, + .coex_set_ant_switch = rtw8814a_coex_cfg_ant_switch, + .coex_set_gnt_fix = rtw8814a_coex_cfg_gnt_fix, + .coex_set_gnt_debug = rtw8814a_coex_cfg_gnt_debug, + .coex_set_rfe_type = rtw8814a_coex_cfg_rfe_type, + .coex_set_wl_tx_power = rtw8814a_coex_cfg_wl_tx_power, + .coex_set_wl_rx_gain = rtw8814a_coex_cfg_wl_rx_gain, }; static const struct rtw_rqpn rqpn_table_8814a[] = { @@ -2101,40 +2117,35 @@ static const struct rtw_prioq_addrs prioq_addrs_8814a = { .wsize = true, }; -static const struct rtw_chip_ops rtw8814a_ops = { - .power_on = rtw_power_on, - .power_off = rtw_power_off, - .phy_set_param = rtw8814a_phy_set_param, - .read_efuse = rtw8814a_read_efuse, - .query_phy_status = rtw8814a_query_phy_status, - .set_channel = rtw8814a_set_channel, - .mac_init = rtw8814a_mac_init, - .read_rf = rtw_phy_read_rf, - .write_rf = rtw_phy_write_rf_reg_sipi, - .set_tx_power_index = rtw8814a_set_tx_power_index, - .set_antenna = NULL, - .cfg_ldo25 = rtw8814a_cfg_ldo25, - .efuse_grant = rtw8814a_efuse_grant, - .set_ampdu_factor = rtw8814a_set_ampdu_factor, - .false_alarm_statistics = rtw8814a_false_alarm_statistics, - .phy_calibration = rtw8814a_phy_calibration, - .cck_pd_set = rtw8814a_phy_cck_pd_set, - .pwr_track = rtw8814a_pwr_track, - .config_bfee = NULL, - .set_gid_table = NULL, - .cfg_csi_rate = NULL, -#ifdef CONFIG_LEDS_CLASS - .led_set = rtw8814a_led_set, -#endif - .fill_txdesc_checksum = rtw8814a_fill_txdesc_checksum, +static const struct rtw_page_table page_table_8814a[] = { + /* SDIO */ + {0, 0, 0, 0, 0}, /* hq nq lq exq gapq */ + /* PCIE */ + {32, 32, 32, 32, 0}, + /* USB, 2 bulk out */ + {32, 32, 32, 32, 0}, + /* USB, 3 bulk out */ + {32, 32, 32, 32, 0}, + /* USB, 4 bulk out */ + {32, 32, 32, 32, 0}, +}; - .coex_set_init = rtw8814a_coex_cfg_init, - .coex_set_ant_switch = rtw8814a_coex_cfg_ant_switch, - .coex_set_gnt_fix = rtw8814a_coex_cfg_gnt_fix, - .coex_set_gnt_debug = rtw8814a_coex_cfg_gnt_debug, - .coex_set_rfe_type = rtw8814a_coex_cfg_rfe_type, - .coex_set_wl_tx_power = rtw8814a_coex_cfg_wl_tx_power, - .coex_set_wl_rx_gain = rtw8814a_coex_cfg_wl_rx_gain, +static const struct rtw_intf_phy_para_table phy_para_table_8814a = {}; + +static const struct rtw_hw_reg rtw8814a_dig[] = { + [0] = { .addr = 0xc50, .mask = 0x7f }, + [1] = { .addr = 0xe50, .mask = 0x7f }, + [2] = { .addr = 0x1850, .mask = 0x7f }, + [3] = { .addr = 0x1a50, .mask = 0x7f }, +}; + +static const struct rtw_rfe_def rtw8814a_rfe_defs[] = { + [0] = { .phy_pg_tbl = &rtw8814a_bb_pg_type0_tbl, + .txpwr_lmt_tbl = &rtw8814a_txpwr_lmt_type0_tbl, + .pwr_track_tbl = &rtw8814a_rtw_pwrtrk_type0_tbl }, + [1] = { .phy_pg_tbl = &rtw8814a_bb_pg_tbl, + .txpwr_lmt_tbl = &rtw8814a_txpwr_lmt_type1_tbl, + .pwr_track_tbl = &rtw8814a_rtw_pwrtrk_tbl }, }; /* rssi in percentage % (dbm = % - 100) */ @@ -2162,15 +2173,6 @@ static const struct coex_rf_para rf_para_rx_8814a[] = { static_assert(ARRAY_SIZE(rf_para_tx_8814a) == ARRAY_SIZE(rf_para_rx_8814a)); -static const struct rtw_rfe_def rtw8814a_rfe_defs[] = { - [0] = { .phy_pg_tbl = &rtw8814a_bb_pg_type0_tbl, - .txpwr_lmt_tbl = &rtw8814a_txpwr_lmt_type0_tbl, - .pwr_track_tbl = &rtw8814a_rtw_pwrtrk_type0_tbl }, - [1] = { .phy_pg_tbl = &rtw8814a_bb_pg_tbl, - .txpwr_lmt_tbl = &rtw8814a_txpwr_lmt_type1_tbl, - .pwr_track_tbl = &rtw8814a_rtw_pwrtrk_tbl }, -}; - const struct rtw_chip_info rtw8814a_hw_spec = { .ops = &rtw8814a_ops, .id = RTW_CHIP_TYPE_8814A, @@ -2259,6 +2261,6 @@ EXPORT_SYMBOL(rtw8814a_hw_spec); MODULE_FIRMWARE("rtw88/rtw8814a_fw.bin"); -MODULE_AUTHOR("Realtek Corporation"); +MODULE_AUTHOR("Bitterblue Smith "); MODULE_DESCRIPTION("Realtek 802.11ac wireless 8814a driver"); MODULE_LICENSE("Dual BSD/GPL"); diff --git a/rtw8814a.h b/rtw8814a.h index 622fcc58..c57c7c8f 100644 --- a/rtw8814a.h +++ b/rtw8814a.h @@ -5,8 +5,6 @@ #ifndef __RTW8814A_H__ #define __RTW8814A_H__ -#define RF_RCK1 0x1c - struct rtw8814au_efuse { u8 vid[2]; /* 0xd0 */ u8 pid[2]; /* 0xd2 */ diff --git a/rtw8814ae.c b/rtw8814ae.c index 51a87584..54d2e20a 100644 --- a/rtw8814ae.c +++ b/rtw8814ae.c @@ -26,6 +26,6 @@ static struct pci_driver rtw_8814ae_driver = { }; module_pci_driver(rtw_8814ae_driver); -MODULE_AUTHOR("Realtek Corporation"); +MODULE_AUTHOR("Bitterblue Smith "); MODULE_DESCRIPTION("Realtek 802.11ac wireless 8814ae driver"); MODULE_LICENSE("Dual BSD/GPL"); From 4a23d4142ad01e3cf8533bdf9ea77017e2c55bb2 Mon Sep 17 00:00:00 2001 From: Bitterblue Smith Date: Fri, 14 Mar 2025 22:33:17 +0200 Subject: [PATCH 159/193] Sync rtw_desc_to_mcsrate Signed-off-by: Bitterblue Smith --- util.c | 1 + 1 file changed, 1 insertion(+) diff --git a/util.c b/util.c index ba02ba72..66819f69 100644 --- a/util.c +++ b/util.c @@ -102,6 +102,7 @@ void rtw_desc_to_mcsrate(u16 rate, u8 *mcs, u8 *nss) *mcs = rate - DESC_RATEVHT4SS_MCS0; } else if (rate >= DESC_RATEMCS0 && rate <= DESC_RATEMCS31) { + *nss = 0; *mcs = rate - DESC_RATEMCS0; } } From b5abd319a64ed1847242045cd8689d18f84fdfe5 Mon Sep 17 00:00:00 2001 From: Bitterblue Smith Date: Fri, 14 Mar 2025 22:33:51 +0200 Subject: [PATCH 160/193] Sync rtw_phy_store_tx_power_by_rate Signed-off-by: Bitterblue Smith --- phy.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/phy.c b/phy.c index 88664662..8d184a8b 100644 --- a/phy.c +++ b/phy.c @@ -1560,10 +1560,8 @@ static void rtw_phy_store_tx_power_by_rate(struct rtw_dev *rtwdev, rate = rates[i]; if (band == PHY_BAND_2G) hal->tx_pwr_by_rate_offset_2g[rfpath][rate] = offset; - else if (band == PHY_BAND_5G) - hal->tx_pwr_by_rate_offset_5g[rfpath][rate] = offset; else - continue; + hal->tx_pwr_by_rate_offset_5g[rfpath][rate] = offset; } } From dd5ee7d259d0d836773cbba90d128366b107bbf6 Mon Sep 17 00:00:00 2001 From: Bitterblue Smith Date: Fri, 14 Mar 2025 22:37:24 +0200 Subject: [PATCH 161/193] Sync random stuff Signed-off-by: Bitterblue Smith --- main.c | 3 ++- main.h | 4 ++-- rtw8703b.c | 1 - rtw8723d.c | 19 +++++++++---------- rtw8812a.c | 32 +++++++++++++++----------------- rtw8814a.c | 2 +- rtw8821a.c | 28 +++++++++++++--------------- rtw8821c.c | 16 ++++++++-------- rtw8822b.c | 18 +++++++++--------- rtw8822c.c | 24 ++++++++++++------------ tx.c | 2 +- 11 files changed, 72 insertions(+), 77 deletions(-) diff --git a/main.c b/main.c index 6e7bb981..94c304c9 100644 --- a/main.c +++ b/main.c @@ -2359,7 +2359,8 @@ int rtw_register_hw(struct rtw_dev *rtwdev, struct ieee80211_hw *hw) ieee80211_hw_set(hw, SUPPORTS_PS); ieee80211_hw_set(hw, SUPPORTS_DYNAMIC_PS); ieee80211_hw_set(hw, SUPPORT_FAST_XMIT); - ieee80211_hw_set(hw, SUPPORTS_AMSDU_IN_AMPDU); + if (rtwdev->chip->amsdu_in_ampdu) + ieee80211_hw_set(hw, SUPPORTS_AMSDU_IN_AMPDU); ieee80211_hw_set(hw, HAS_RATE_CONTROL); ieee80211_hw_set(hw, TX_AMSDU); ieee80211_hw_set(hw, SINGLE_SCAN_ON_ALL_BANDS); diff --git a/main.h b/main.h index 12e302c7..b2369e57 100644 --- a/main.h +++ b/main.h @@ -1250,8 +1250,8 @@ enum rtw_rfe_fem { struct rtw_rfe_def { const struct rtw_table *phy_pg_tbl; const struct rtw_table *txpwr_lmt_tbl; - const struct rtw_table *agc_btg_tbl; const struct rtw_pwr_track_tbl *pwr_track_tbl; + const struct rtw_table *agc_btg_tbl; }; #define RTW_DEF_RFE(chip, bb_pg, pwrlmt, track) { \ @@ -1367,11 +1367,11 @@ struct rtw_chip_info { u16 fw_fifo_addr[RTW_FW_FIFO_MAX]; const struct rtw_fwcd_segs *fwcd_segs; + bool amsdu_in_ampdu; u8 usb_tx_agg_desc_num; bool hw_feature_report; u8 c2h_ra_report_size; bool old_datarate_fb_limit; - bool tx_report_sn; u8 default_1ss_tx_path; diff --git a/rtw8703b.c b/rtw8703b.c index 7a80291f..dff5b2fe 100644 --- a/rtw8703b.c +++ b/rtw8703b.c @@ -1922,7 +1922,6 @@ const struct rtw_chip_info rtw8703b_hw_spec = { .hw_feature_report = true, .c2h_ra_report_size = 7, .old_datarate_fb_limit = true, - .tx_report_sn = false, .path_div_supported = false, .ht_supported = true, diff --git a/rtw8723d.c b/rtw8723d.c index fb887ec0..5acddd80 100644 --- a/rtw8723d.c +++ b/rtw8723d.c @@ -444,7 +444,7 @@ static u8 rtw8723d_iqk_check_tx_failed(struct rtw_dev *rtwdev, rtw_read32(rtwdev, REG_IQK_RES_TX), rtw_read32(rtwdev, REG_IQK_RES_TY)); rtw_dbg(rtwdev, RTW_DBG_RFK, - "[IQK] 0xe90(before IQK)= 0x%x, 0xe98(afer IQK) = 0x%x\n", + "[IQK] 0xe90(before IQK)= 0x%x, 0xe98(after IQK) = 0x%x\n", rtw_read32(rtwdev, 0xe90), rtw_read32(rtwdev, 0xe98)); @@ -472,7 +472,7 @@ static u8 rtw8723d_iqk_check_rx_failed(struct rtw_dev *rtwdev, rtw_read32(rtwdev, REG_IQK_RES_RY)); rtw_dbg(rtwdev, RTW_DBG_RFK, - "[IQK] 0xea0(before IQK)= 0x%x, 0xea8(afer IQK) = 0x%x\n", + "[IQK] 0xea0(before IQK)= 0x%x, 0xea8(after IQK) = 0x%x\n", rtw_read32(rtwdev, 0xea0), rtw_read32(rtwdev, 0xea8)); @@ -2127,29 +2127,26 @@ const struct rtw_chip_info rtw8723d_hw_spec = { .txff_size = 32768, .rxff_size = 16384, .rsvd_drv_pg_num = 8, - .band = RTW_BAND_2G, - .page_size = TX_PAGE_SIZE, - .csi_buf_pg_num = 0, - .dig_min = 0x20, .txgi_factor = 1, .is_pwr_by_rate_dec = true, - .rx_ldpc = false, .max_power_index = 0x3f, - .ampdu_density = IEEE80211_HT_MPDU_DENSITY_16, + .csi_buf_pg_num = 0, + .band = RTW_BAND_2G, + .page_size = TX_PAGE_SIZE, + .dig_min = 0x20, .usb_tx_agg_desc_num = 1, .hw_feature_report = true, .c2h_ra_report_size = 7, .old_datarate_fb_limit = true, - .tx_report_sn = false, .ht_supported = true, .vht_supported = false, .lps_deep_mode_supported = 0, .sys_func_en = 0xFD, .pwr_on_seq = card_enable_flow_8723d, .pwr_off_seq = card_disable_flow_8723d, + .page_table = page_table_8723d, .rqpn_table = rqpn_table_8723d, .prioq_addrs = &rtw8723x_common.prioq_addrs, - .page_table = page_table_8723d, .intf_table = &phy_para_table_8723d, .dig = rtw8723x_common.dig, .dig_cck = rtw8723x_common.dig_cck, @@ -2163,7 +2160,9 @@ const struct rtw_chip_info rtw8723d_hw_spec = { .rf_tbl = {&rtw8723d_rf_a_tbl}, .rfe_defs = rtw8723d_rfe_defs, .rfe_defs_size = ARRAY_SIZE(rtw8723d_rfe_defs), + .rx_ldpc = false, .iqk_threshold = 8, + .ampdu_density = IEEE80211_HT_MPDU_DENSITY_16, .max_scan_ie_len = IEEE80211_MAX_DATA_LEN, .coex_para_ver = 0x2007022f, diff --git a/rtw8812a.c b/rtw8812a.c index 41f17859..34e052dd 100644 --- a/rtw8812a.c +++ b/rtw8812a.c @@ -295,11 +295,11 @@ static void rtw8812a_iqk(struct rtw_dev *rtwdev) bool iqk0_ready = false, tx0_finish = false, rx0_finish = false; bool iqk1_ready = false, tx1_finish = false, rx1_finish = false; u8 tx0_avg = 0, tx1_avg = 0, rx0_avg = 0, rx1_avg = 0; + int tx_x0 = 0, tx_y0 = 0, tx_x1 = 0, tx_y1 = 0; + int rx_x0 = 0, rx_y0 = 0, rx_x1 = 0, rx_y1 = 0; struct rtw_efuse *efuse = &rtwdev->efuse; bool tx0_fail = true, rx0_fail = true; bool tx1_fail = true, rx1_fail = true; - int tx_x0, tx_y0, tx_x1, tx_y1; - int rx_x0, rx_y0, rx_x1, rx_y1; u8 cal0_retry, cal1_retry; u8 delay_count; @@ -1001,8 +1001,6 @@ static const struct rtw_prioq_addrs prioq_addrs_8812a = { .wsize = false, }; -static const struct rtw_intf_phy_para_table phy_para_table_8812a = {}; - static const struct rtw_hw_reg rtw8812a_dig[] = { [0] = { .addr = REG_RXIGI_A, .mask = 0x7f }, [1] = { .addr = REG_RXIGI_B, .mask = 0x7f }, @@ -1061,30 +1059,23 @@ const struct rtw_chip_info rtw8812a_hw_spec = { .txff_size = 131072, .rxff_size = 16128, .rsvd_drv_pg_num = 9, - .band = RTW_BAND_2G | RTW_BAND_5G, - .page_size = 512, - .csi_buf_pg_num = 0, - .dig_min = 0x20, .txgi_factor = 1, .is_pwr_by_rate_dec = true, - .rx_ldpc = false, .max_power_index = 0x3f, - .ampdu_density = IEEE80211_HT_MPDU_DENSITY_16, - .usb_tx_agg_desc_num = 1, - .hw_feature_report = false, - .c2h_ra_report_size = 4, - .old_datarate_fb_limit = true, - .tx_report_sn = false, + .csi_buf_pg_num = 0, + .band = RTW_BAND_2G | RTW_BAND_5G, + .page_size = 512, + .dig_min = 0x20, .ht_supported = true, .vht_supported = true, .lps_deep_mode_supported = 0, .sys_func_en = 0xFD, .pwr_on_seq = card_enable_flow_8812a, .pwr_off_seq = card_disable_flow_8812a, + .page_table = page_table_8812a, .rqpn_table = rqpn_table_8812a, .prioq_addrs = &prioq_addrs_8812a, - .page_table = page_table_8812a, - .intf_table = &phy_para_table_8812a, + .intf_table = NULL, .dig = rtw8812a_dig, .rf_sipi_addr = {REG_LSSI_WRITE_A, REG_LSSI_WRITE_B}, .ltecoex_addr = NULL, @@ -1094,7 +1085,14 @@ const struct rtw_chip_info rtw8812a_hw_spec = { .rf_tbl = {&rtw8812a_rf_a_tbl, &rtw8812a_rf_b_tbl}, .rfe_defs = rtw8812a_rfe_defs, .rfe_defs_size = ARRAY_SIZE(rtw8812a_rfe_defs), + .rx_ldpc = false, + .amsdu_in_ampdu = true, + .hw_feature_report = false, + .c2h_ra_report_size = 4, + .old_datarate_fb_limit = true, + .usb_tx_agg_desc_num = 1, .iqk_threshold = 8, + .ampdu_density = IEEE80211_HT_MPDU_DENSITY_16, .max_scan_ie_len = IEEE80211_MAX_DATA_LEN, .coex_para_ver = 0, /* no coex code in 8812au driver */ diff --git a/rtw8814a.c b/rtw8814a.c index c1b0dda4..51644439 100644 --- a/rtw8814a.c +++ b/rtw8814a.c @@ -2197,11 +2197,11 @@ const struct rtw_chip_info rtw8814a_hw_spec = { .rx_ldpc = true, .max_power_index = 0x3f, .ampdu_density = IEEE80211_HT_MPDU_DENSITY_2, + .amsdu_in_ampdu = false, .usb_tx_agg_desc_num = 3, .hw_feature_report = false, .c2h_ra_report_size = 6, .old_datarate_fb_limit = false, - .tx_report_sn = true, .ht_supported = true, .vht_supported = true, .lps_deep_mode_supported = BIT(LPS_DEEP_MODE_LCLK), diff --git a/rtw8821a.c b/rtw8821a.c index b9716669..fa4b1a53 100644 --- a/rtw8821a.c +++ b/rtw8821a.c @@ -947,8 +947,6 @@ static const struct rtw_prioq_addrs prioq_addrs_8821a = { .wsize = false, }; -static const struct rtw_intf_phy_para_table phy_para_table_8821a = {}; - static const struct rtw_hw_reg rtw8821a_dig[] = { [0] = { .addr = REG_RXIGI_A, .mask = 0x7f }, }; @@ -1161,30 +1159,23 @@ const struct rtw_chip_info rtw8821a_hw_spec = { .txff_size = 65536, .rxff_size = 16128, .rsvd_drv_pg_num = 8, - .band = RTW_BAND_2G | RTW_BAND_5G, - .page_size = 256, - .csi_buf_pg_num = 0, - .dig_min = 0x20, .txgi_factor = 1, .is_pwr_by_rate_dec = true, - .rx_ldpc = false, .max_power_index = 0x3f, - .ampdu_density = IEEE80211_HT_MPDU_DENSITY_16, - .usb_tx_agg_desc_num = 6, - .hw_feature_report = false, - .c2h_ra_report_size = 4, - .old_datarate_fb_limit = true, - .tx_report_sn = false, + .csi_buf_pg_num = 0, + .band = RTW_BAND_2G | RTW_BAND_5G, + .page_size = 256, + .dig_min = 0x20, .ht_supported = true, .vht_supported = true, .lps_deep_mode_supported = 0, .sys_func_en = 0xFD, .pwr_on_seq = card_enable_flow_8821a, .pwr_off_seq = card_disable_flow_8821a, + .page_table = page_table_8821a, .rqpn_table = rqpn_table_8821a, .prioq_addrs = &prioq_addrs_8821a, - .page_table = page_table_8821a, - .intf_table = &phy_para_table_8821a, + .intf_table = NULL, .dig = rtw8821a_dig, .rf_sipi_addr = {REG_LSSI_WRITE_A, REG_LSSI_WRITE_B}, .ltecoex_addr = NULL, @@ -1194,7 +1185,14 @@ const struct rtw_chip_info rtw8821a_hw_spec = { .rf_tbl = {&rtw8821a_rf_a_tbl}, .rfe_defs = rtw8821a_rfe_defs, .rfe_defs_size = ARRAY_SIZE(rtw8821a_rfe_defs), + .rx_ldpc = false, + .amsdu_in_ampdu = true, + .hw_feature_report = false, + .c2h_ra_report_size = 4, + .old_datarate_fb_limit = true, + .usb_tx_agg_desc_num = 6, .iqk_threshold = 8, + .ampdu_density = IEEE80211_HT_MPDU_DENSITY_16, .max_scan_ie_len = IEEE80211_MAX_DATA_LEN, .coex_para_ver = 20190509, /* glcoex_ver_date_8821a_1ant */ diff --git a/rtw8821c.c b/rtw8821c.c index 8704c1bf..97e081dd 100644 --- a/rtw8821c.c +++ b/rtw8821c.c @@ -1990,29 +1990,27 @@ const struct rtw_chip_info rtw8821c_hw_spec = { .txff_size = 65536, .rxff_size = 16384, .rsvd_drv_pg_num = 8, - .band = RTW_BAND_2G | RTW_BAND_5G, - .page_size = TX_PAGE_SIZE, - .csi_buf_pg_num = 0, - .dig_min = 0x1c, .txgi_factor = 1, .is_pwr_by_rate_dec = true, - .rx_ldpc = false, .max_power_index = 0x3f, - .ampdu_density = IEEE80211_HT_MPDU_DENSITY_2, + .csi_buf_pg_num = 0, + .band = RTW_BAND_2G | RTW_BAND_5G, + .page_size = TX_PAGE_SIZE, + .dig_min = 0x1c, + .amsdu_in_ampdu = true, .usb_tx_agg_desc_num = 3, .hw_feature_report = true, .c2h_ra_report_size = 7, .old_datarate_fb_limit = false, - .tx_report_sn = true, .ht_supported = true, .vht_supported = true, .lps_deep_mode_supported = BIT(LPS_DEEP_MODE_LCLK), .sys_func_en = 0xD8, .pwr_on_seq = card_enable_flow_8821c, .pwr_off_seq = card_disable_flow_8821c, + .page_table = page_table_8821c, .rqpn_table = rqpn_table_8821c, .prioq_addrs = &prioq_addrs_8821c, - .page_table = page_table_8821c, .intf_table = &phy_para_table_8821c, .dig = rtw8821c_dig, .rf_base_addr = {0x2800, 0x2c00}, @@ -2024,9 +2022,11 @@ const struct rtw_chip_info rtw8821c_hw_spec = { .rf_tbl = {&rtw8821c_rf_a_tbl}, .rfe_defs = rtw8821c_rfe_defs, .rfe_defs_size = ARRAY_SIZE(rtw8821c_rfe_defs), + .rx_ldpc = false, .iqk_threshold = 8, .bfer_su_max_num = 2, .bfer_mu_max_num = 1, + .ampdu_density = IEEE80211_HT_MPDU_DENSITY_2, .max_scan_ie_len = IEEE80211_MAX_DATA_LEN, .coex_para_ver = 0x19092746, diff --git a/rtw8822b.c b/rtw8822b.c index 3d3c4a4e..d631c7ad 100644 --- a/rtw8822b.c +++ b/rtw8822b.c @@ -2530,30 +2530,27 @@ const struct rtw_chip_info rtw8822b_hw_spec = { .rxff_size = 24576, .fw_rxff_size = 12288, .rsvd_drv_pg_num = 8, - .band = RTW_BAND_2G | RTW_BAND_5G, - .page_size = TX_PAGE_SIZE, - .csi_buf_pg_num = 0, - .dig_min = 0x1c, .txgi_factor = 1, .is_pwr_by_rate_dec = true, - .rx_ldpc = true, .max_power_index = 0x3f, - .ampdu_density = IEEE80211_HT_MPDU_DENSITY_2, - .fw_fifo_addr = {0x780, 0x700, 0x780, 0x660, 0x650, 0x680}, + .csi_buf_pg_num = 0, + .band = RTW_BAND_2G | RTW_BAND_5G, + .page_size = TX_PAGE_SIZE, + .dig_min = 0x1c, + .amsdu_in_ampdu = true, .usb_tx_agg_desc_num = 3, .hw_feature_report = true, .c2h_ra_report_size = 7, .old_datarate_fb_limit = false, - .tx_report_sn = true, .ht_supported = true, .vht_supported = true, .lps_deep_mode_supported = BIT(LPS_DEEP_MODE_LCLK), .sys_func_en = 0xDC, .pwr_on_seq = card_enable_flow_8822b, .pwr_off_seq = card_disable_flow_8822b, + .page_table = page_table_8822b, .rqpn_table = rqpn_table_8822b, .prioq_addrs = &prioq_addrs_8822b, - .page_table = page_table_8822b, .intf_table = &phy_para_table_8822b, .dig = rtw8822b_dig, .dig_cck = NULL, @@ -2569,9 +2566,11 @@ const struct rtw_chip_info rtw8822b_hw_spec = { .iqk_threshold = 8, .bfer_su_max_num = 2, .bfer_mu_max_num = 1, + .rx_ldpc = true, .edcca_th = rtw8822b_edcca_th, .l2h_th_ini_cs = 10 + EDCCA_IGI_BASE, .l2h_th_ini_ad = -14 + EDCCA_IGI_BASE, + .ampdu_density = IEEE80211_HT_MPDU_DENSITY_2, .max_scan_ie_len = IEEE80211_MAX_DATA_LEN, .coex_para_ver = 0x20070206, @@ -2605,6 +2604,7 @@ const struct rtw_chip_info rtw8822b_hw_spec = { .coex_info_hw_regs_num = ARRAY_SIZE(coex_info_hw_regs_8822b), .coex_info_hw_regs = coex_info_hw_regs_8822b, + .fw_fifo_addr = {0x780, 0x700, 0x780, 0x660, 0x650, 0x680}, }; EXPORT_SYMBOL(rtw8822b_hw_spec); diff --git a/rtw8822c.c b/rtw8822c.c index 72f13722..910bd36b 100644 --- a/rtw8822c.c +++ b/rtw8822c.c @@ -5348,23 +5348,18 @@ const struct rtw_chip_info rtw8822c_hw_spec = { .rxff_size = 24576, .fw_rxff_size = 12288, .rsvd_drv_pg_num = 16, - .band = RTW_BAND_2G | RTW_BAND_5G, - .page_size = TX_PAGE_SIZE, - .csi_buf_pg_num = 50, - .dig_min = 0x20, .txgi_factor = 2, .is_pwr_by_rate_dec = false, - .rx_ldpc = true, - .tx_stbc = true, .max_power_index = 0x7f, - .ampdu_density = IEEE80211_HT_MPDU_DENSITY_2, - .fw_fifo_addr = {0x780, 0x700, 0x780, 0x660, 0x650, 0x680}, - .fwcd_segs = &rtw8822c_fwcd_segs, + .csi_buf_pg_num = 50, + .band = RTW_BAND_2G | RTW_BAND_5G, + .page_size = TX_PAGE_SIZE, + .dig_min = 0x20, + .amsdu_in_ampdu = true, .usb_tx_agg_desc_num = 3, .hw_feature_report = true, .c2h_ra_report_size = 7, .old_datarate_fb_limit = false, - .tx_report_sn = true, .default_1ss_tx_path = BB_PATH_A, .path_div_supported = true, .ht_supported = true, @@ -5373,9 +5368,9 @@ const struct rtw_chip_info rtw8822c_hw_spec = { .sys_func_en = 0xD8, .pwr_on_seq = card_enable_flow_8822c, .pwr_off_seq = card_disable_flow_8822c, + .page_table = page_table_8822c, .rqpn_table = rqpn_table_8822c, .prioq_addrs = &prioq_addrs_8822c, - .page_table = page_table_8822c, .intf_table = &phy_para_table_8822c, .dig = rtw8822c_dig, .dig_cck = NULL, @@ -5385,8 +5380,8 @@ const struct rtw_chip_info rtw8822c_hw_spec = { .mac_tbl = &rtw8822c_mac_tbl, .agc_tbl = &rtw8822c_agc_tbl, .bb_tbl = &rtw8822c_bb_tbl, - .rf_tbl = {&rtw8822c_rf_b_tbl, &rtw8822c_rf_a_tbl}, .rfk_init_tbl = &rtw8822c_array_mp_cal_init_tbl, + .rf_tbl = {&rtw8822c_rf_b_tbl, &rtw8822c_rf_a_tbl}, .rfe_defs = rtw8822c_rfe_defs, .rfe_defs_size = ARRAY_SIZE(rtw8822c_rfe_defs), .en_dis_dpd = true, @@ -5395,9 +5390,12 @@ const struct rtw_chip_info rtw8822c_hw_spec = { .lck_threshold = 8, .bfer_su_max_num = 2, .bfer_mu_max_num = 1, + .rx_ldpc = true, + .tx_stbc = true, .edcca_th = rtw8822c_edcca_th, .l2h_th_ini_cs = 60, .l2h_th_ini_ad = 45, + .ampdu_density = IEEE80211_HT_MPDU_DENSITY_2, #ifdef CONFIG_PM .wow_fw_name = "rtw88/rtw8822c_wow_fw.bin", @@ -5436,6 +5434,8 @@ const struct rtw_chip_info rtw8822c_hw_spec = { .coex_info_hw_regs_num = ARRAY_SIZE(coex_info_hw_regs_8822c), .coex_info_hw_regs = coex_info_hw_regs_8822c, + .fw_fifo_addr = {0x780, 0x700, 0x780, 0x660, 0x650, 0x680}, + .fwcd_segs = &rtw8822c_fwcd_segs, }; EXPORT_SYMBOL(rtw8822c_hw_spec); diff --git a/tx.c b/tx.c index a56c06e0..aff17874 100644 --- a/tx.c +++ b/tx.c @@ -271,7 +271,7 @@ void rtw_tx_report_handle(struct rtw_dev *rtwdev, struct sk_buff *skb, int src) spin_lock_irqsave(&tx_report->q_lock, flags); skb_queue_walk_safe(&tx_report->queue, cur, tmp) { n = (u8 *)IEEE80211_SKB_CB(cur)->status.status_driver_data; - if (*n == sn || !rtwdev->chip->tx_report_sn) { + if (*n == sn || rtw_chip_wcpu_11n(rtwdev)) { __skb_unlink(cur, &tx_report->queue); rtw_tx_report_tx_status(rtwdev, cur, st == 0); break; From cfcc33a807b94de22c6dd0520b94547034fdfadd Mon Sep 17 00:00:00 2001 From: Zenm Chen Date: Sat, 15 Mar 2025 15:37:31 +0800 Subject: [PATCH 162/193] Add missing led.c and led.h This also fixes a minor mistake in README.md. --- README.md | 2 +- led.c | 73 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ led.h | 25 +++++++++++++++++++ 3 files changed, 99 insertions(+), 1 deletion(-) create mode 100644 led.c create mode 100644 led.h diff --git a/README.md b/README.md index 5d5993ee..b8d847fb 100644 --- a/README.md +++ b/README.md @@ -24,7 +24,7 @@ Compatible with **Linux kernel versions 5.4 and newer** as long as your distro h --- ## Issues 🚨 -Report problems in Issues after you have checked the [FAQ](#faq) at bottom of this README. +Report problems in Issues after you have checked the [Q&A](#qa) at bottom of this README. ⚠️ If you see a line such as: diff --git a/led.c b/led.c new file mode 100644 index 00000000..25aa6cba --- /dev/null +++ b/led.c @@ -0,0 +1,73 @@ +// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause +/* Copyright(c) 2025 Realtek Corporation + */ + +#include "main.h" +#include "debug.h" +#include "led.h" + +static int rtw_led_set_blocking(struct led_classdev *led, + enum led_brightness brightness) +{ + struct rtw_dev *rtwdev = container_of(led, struct rtw_dev, led_cdev); + + rtwdev->chip->ops->led_set(led, brightness); + + return 0; +} + +void rtw_led_init(struct rtw_dev *rtwdev) +{ + static const struct ieee80211_tpt_blink rtw_tpt_blink[] = { + { .throughput = 0 * 1024, .blink_time = 334 }, + { .throughput = 1 * 1024, .blink_time = 260 }, + { .throughput = 5 * 1024, .blink_time = 220 }, + { .throughput = 10 * 1024, .blink_time = 190 }, + { .throughput = 20 * 1024, .blink_time = 170 }, + { .throughput = 50 * 1024, .blink_time = 150 }, + { .throughput = 70 * 1024, .blink_time = 130 }, + { .throughput = 100 * 1024, .blink_time = 110 }, + { .throughput = 200 * 1024, .blink_time = 80 }, + { .throughput = 300 * 1024, .blink_time = 50 }, + }; + struct led_classdev *led = &rtwdev->led_cdev; + int err; + + if (!rtwdev->chip->ops->led_set) + return; + + if (rtw_hci_type(rtwdev) == RTW_HCI_TYPE_PCIE) + led->brightness_set = rtwdev->chip->ops->led_set; + else + led->brightness_set_blocking = rtw_led_set_blocking; + + snprintf(rtwdev->led_name, sizeof(rtwdev->led_name), + "rtw88-%s", dev_name(rtwdev->dev)); + + led->name = rtwdev->led_name; + led->max_brightness = LED_ON; + led->default_trigger = + ieee80211_create_tpt_led_trigger(rtwdev->hw, + IEEE80211_TPT_LEDTRIG_FL_RADIO, + rtw_tpt_blink, + ARRAY_SIZE(rtw_tpt_blink)); + + err = led_classdev_register(rtwdev->dev, led); + if (err) { + rtw_warn(rtwdev, "Failed to register the LED, error %d\n", err); + return; + } + + rtwdev->led_registered = true; +} + +void rtw_led_deinit(struct rtw_dev *rtwdev) +{ + struct led_classdev *led = &rtwdev->led_cdev; + + if (!rtwdev->led_registered) + return; + + rtwdev->chip->ops->led_set(led, LED_OFF); + led_classdev_unregister(led); +} diff --git a/led.h b/led.h new file mode 100644 index 00000000..fa64002b --- /dev/null +++ b/led.h @@ -0,0 +1,25 @@ +/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */ +/* Copyright(c) 2025 Realtek Corporation + */ + +#ifndef __RTW_LED_H +#define __RTW_LED_H + +#ifdef CONFIG_RTW88_LEDS + +void rtw_led_init(struct rtw_dev *rtwdev); +void rtw_led_deinit(struct rtw_dev *rtwdev); + +#else + +static inline void rtw_led_init(struct rtw_dev *rtwdev) +{ +} + +static inline void rtw_led_deinit(struct rtw_dev *rtwdev) +{ +} + +#endif + +#endif From 11d29443525eca394e69d8adab065dc33cce23d6 Mon Sep 17 00:00:00 2001 From: Bitterblue Smith Date: Sat, 15 Mar 2025 22:55:53 +0200 Subject: [PATCH 163/193] Mitigate beacon loss with RTL8814A as well For https://github.com/lwfinger/rtw88/issues/270#issuecomment-2710960678 Maybe it helps a little. Signed-off-by: Bitterblue Smith --- phy.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/phy.c b/phy.c index 8d184a8b..9103cb6b 100644 --- a/phy.c +++ b/phy.c @@ -519,11 +519,12 @@ static void rtw_phy_dig(struct rtw_dev *rtwdev) { struct rtw_dm_info *dm_info = &rtwdev->dm_info; u8 upper_bound, lower_bound; - u8 pre_igi, cur_igi; + u8 chip = rtwdev->chip->id; u16 fa_th[3], fa_cnt; - u8 level; - u8 step[3]; + u8 pre_igi, cur_igi; bool linked; + u8 step[3]; + u8 level; if (test_bit(RTW_FLAG_DIG_DISABLE, rtwdev->flags)) return; @@ -568,8 +569,9 @@ static void rtw_phy_dig(struct rtw_dev *rtwdev) /* Mitigate beacon loss and connectivity issues, mainly (only?) * in the 5 GHz band */ - if (rtwdev->chip->id == RTW_CHIP_TYPE_8812A && rtwdev->beacon_loss && - linked && dm_info->total_fa_cnt < DIG_PERF_FA_TH_EXTRA_HIGH) + if ((chip == RTW_CHIP_TYPE_8812A || chip == RTW_CHIP_TYPE_8814A) && + rtwdev->beacon_loss && linked && + dm_info->total_fa_cnt < DIG_PERF_FA_TH_EXTRA_HIGH) cur_igi = DIG_CVRG_MIN; if (cur_igi != pre_igi) From 0f261f9b06fe403637dd33a5ecbc992c9b92d67f Mon Sep 17 00:00:00 2001 From: Zenm Chen Date: Mon, 31 Mar 2025 11:06:17 +0800 Subject: [PATCH 164/193] Add support for TP-LINK Archer T2UB Nano --- rtw8821cu.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/rtw8821cu.c b/rtw8821cu.c index a019f408..0566d6ae 100644 --- a/rtw8821cu.c +++ b/rtw8821cu.c @@ -37,6 +37,8 @@ static const struct usb_device_id rtw_8821cu_id_table[] = { .driver_info = (kernel_ulong_t)&(rtw8821c_hw_spec) }, /* Edimax */ { USB_DEVICE_AND_INTERFACE_INFO(0x7392, 0xd811, 0xff, 0xff, 0xff), .driver_info = (kernel_ulong_t)&(rtw8821c_hw_spec) }, /* Edimax */ + { USB_DEVICE_AND_INTERFACE_INFO(0x2357, 0x013c, 0xff, 0xff, 0xff), + .driver_info = (kernel_ulong_t)&(rtw8821c_hw_spec) }, /* TP-LINK Archer T2UB Nano */ {}, }; MODULE_DEVICE_TABLE(usb, rtw_8821cu_id_table); From 9fee632533e1abd12e9660a160a2580161afadb6 Mon Sep 17 00:00:00 2001 From: Bitterblue Smith Date: Sun, 20 Apr 2025 02:08:39 +0300 Subject: [PATCH 165/193] wifi: rtw88: usb: Reduce control message timeout to 500 ms RTL8811AU stops responding during the firmware download on some systems: [ 809.256440] rtw_8821au 5-2.1:1.0: Firmware version 42.4.0, H2C version 0 [ 812.759142] rtw_8821au 5-2.1:1.0 wlp48s0f4u2u1: renamed from wlan0 [ 837.315388] rtw_8821au 1-4:1.0: write register 0x1ef4 failed with -110 [ 867.524259] rtw_8821au 1-4:1.0: write register 0x1ef8 failed with -110 [ 868.930976] rtw_8821au 5-2.1:1.0 wlp48s0f4u2u1: entered promiscuous mode [ 897.730952] rtw_8821au 1-4:1.0: write register 0x1efc failed with -110 Each write takes 30 seconds to fail because that's the timeout currently used for control messages in rtw_usb_write(). In this scenario the firmware download takes at least 2000 seconds. Because this is done from the USB probe function, the long delay makes other things in the system hang. Reduce the timeout to 500 ms. Link: https://github.com/lwfinger/rtw88/issues/344 Signed-off-by: Bitterblue Smith --- usb.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/usb.c b/usb.c index 4bd6d58b..74b32532 100644 --- a/usb.c +++ b/usb.c @@ -139,7 +139,7 @@ static void rtw_usb_write(struct rtw_dev *rtwdev, u32 addr, u32 val, int len) ret = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), RTW_USB_CMD_REQ, RTW_USB_CMD_WRITE, - addr, 0, data, len, 30000); + addr, 0, data, len, 500); if (ret < 0 && ret != -ENODEV && count++ < 4) rtw_err(rtwdev, "write register 0x%x failed with %d\n", addr, ret); From efc617d6f2a8ec5c6ea0720dbeac9af4349c6f2d Mon Sep 17 00:00:00 2001 From: Bitterblue Smith Date: Tue, 22 Apr 2025 23:50:23 +0300 Subject: [PATCH 166/193] wifi: rtw88: usb: Upload the firmware in bigger chunks TODO: RTL8723DU needs 254 bytes For https://github.com/lwfinger/rtw88/issues/344. Signed-off-by: Bitterblue Smith --- hci.h | 8 ++++++++ mac.c | 11 +++++++---- mac.h | 2 ++ pci.c | 2 ++ sdio.c | 2 ++ usb.c | 49 +++++++++++++++++++++++++++++++++++++++++++++++++ 6 files changed, 70 insertions(+), 4 deletions(-) diff --git a/hci.h b/hci.h index 96aeda26..d4bee9c3 100644 --- a/hci.h +++ b/hci.h @@ -19,6 +19,8 @@ struct rtw_hci_ops { void (*link_ps)(struct rtw_dev *rtwdev, bool enter); void (*interface_cfg)(struct rtw_dev *rtwdev); void (*dynamic_rx_agg)(struct rtw_dev *rtwdev, bool enable); + void (*write_firmware_page)(struct rtw_dev *rtwdev, u32 page, + const u8 *data, u32 size); int (*write_data_rsvd_page)(struct rtw_dev *rtwdev, u8 *buf, u32 size); int (*write_data_h2c)(struct rtw_dev *rtwdev, u8 *buf, u32 size); @@ -79,6 +81,12 @@ static inline void rtw_hci_dynamic_rx_agg(struct rtw_dev *rtwdev, bool enable) rtwdev->hci.ops->dynamic_rx_agg(rtwdev, enable); } +static inline void rtw_hci_write_firmware_page(struct rtw_dev *rtwdev, u32 page, + const u8 *data, u32 size) +{ + rtwdev->hci.ops->write_firmware_page(rtwdev, page, data, size); +} + static inline int rtw_hci_write_data_rsvd_page(struct rtw_dev *rtwdev, u8 *buf, u32 size) { diff --git a/mac.c b/mac.c index 0491f501..f66d1b30 100644 --- a/mac.c +++ b/mac.c @@ -856,8 +856,8 @@ static void en_download_firmware_legacy(struct rtw_dev *rtwdev, bool en) } } -static void -write_firmware_page(struct rtw_dev *rtwdev, u32 page, const u8 *data, u32 size) +void rtw_write_firmware_page(struct rtw_dev *rtwdev, u32 page, + const u8 *data, u32 size) { u32 val32; u32 block_nr; @@ -887,6 +887,7 @@ write_firmware_page(struct rtw_dev *rtwdev, u32 page, const u8 *data, u32 size) rtw_write32(rtwdev, write_addr, le32_to_cpu(remain_data)); } } +EXPORT_SYMBOL(rtw_write_firmware_page); static int download_firmware_legacy(struct rtw_dev *rtwdev, const u8 *data, u32 size) @@ -904,11 +905,13 @@ download_firmware_legacy(struct rtw_dev *rtwdev, const u8 *data, u32 size) rtw_write8_set(rtwdev, REG_MCUFW_CTRL, BIT_FWDL_CHK_RPT); for (page = 0; page < total_page; page++) { - write_firmware_page(rtwdev, page, data, DLFW_PAGE_SIZE_LEGACY); + rtw_hci_write_firmware_page(rtwdev, page, data, + DLFW_PAGE_SIZE_LEGACY); data += DLFW_PAGE_SIZE_LEGACY; } if (last_page_size) - write_firmware_page(rtwdev, page, data, last_page_size); + rtw_hci_write_firmware_page(rtwdev, page, data, + last_page_size); if (!check_hw_ready(rtwdev, REG_MCUFW_CTRL, BIT_FWDL_CHK_RPT, 1)) { rtw_err(rtwdev, "failed to check download firmware report\n"); diff --git a/mac.h b/mac.h index 6905e274..e92b1483 100644 --- a/mac.h +++ b/mac.h @@ -34,6 +34,8 @@ int rtw_pwr_seq_parser(struct rtw_dev *rtwdev, const struct rtw_pwr_seq_cmd * const *cmd_seq); int rtw_mac_power_on(struct rtw_dev *rtwdev); void rtw_mac_power_off(struct rtw_dev *rtwdev); +void rtw_write_firmware_page(struct rtw_dev *rtwdev, u32 page, + const u8 *data, u32 size); int rtw_download_firmware(struct rtw_dev *rtwdev, struct rtw_fw_state *fw); int rtw_mac_init(struct rtw_dev *rtwdev); void rtw_mac_flush_queues(struct rtw_dev *rtwdev, u32 queues, bool drop); diff --git a/pci.c b/pci.c index cd8f2035..8b0d9617 100644 --- a/pci.c +++ b/pci.c @@ -12,6 +12,7 @@ #include "fw.h" #include "ps.h" #include "debug.h" +#include "mac.h" static bool rtw_disable_msi; static bool rtw_pci_disable_aspm; @@ -1602,6 +1603,7 @@ static const struct rtw_hci_ops rtw_pci_ops = { .link_ps = rtw_pci_link_ps, .interface_cfg = rtw_pci_interface_cfg, .dynamic_rx_agg = NULL, + .write_firmware_page = rtw_write_firmware_page, .read8 = rtw_pci_read8, .read16 = rtw_pci_read16, diff --git a/sdio.c b/sdio.c index 94f8f300..579e0f66 100644 --- a/sdio.c +++ b/sdio.c @@ -10,6 +10,7 @@ #include #include #include "main.h" +#include "mac.h" #include "debug.h" #include "fw.h" #include "ps.h" @@ -1165,6 +1166,7 @@ static const struct rtw_hci_ops rtw_sdio_ops = { .link_ps = rtw_sdio_link_ps, .interface_cfg = rtw_sdio_interface_cfg, .dynamic_rx_agg = NULL, + .write_firmware_page = rtw_write_firmware_page, .read8 = rtw_sdio_read8, .read16 = rtw_sdio_read16, diff --git a/usb.c b/usb.c index 74b32532..b9fcc3bc 100644 --- a/usb.c +++ b/usb.c @@ -165,6 +165,54 @@ static void rtw_usb_write32(struct rtw_dev *rtwdev, u32 addr, u32 val) rtw_usb_write(rtwdev, addr, val, 4); } +static void rtw_usb_write_block(struct rtw_dev *rtwdev, u32 addr, + u8 *data, u32 len) +{ + struct rtw_usb *rtwusb = (struct rtw_usb *)rtwdev->priv; + struct usb_device *udev = rtwusb->udev; + int ret; + + ret = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), + RTW_USB_CMD_REQ, RTW_USB_CMD_WRITE, + addr, 0, (void *)data, len, 500); + if (ret < 0 && ret != -ENODEV) + rtw_err(rtwdev, "write register 0x%x len %d failed with %d\n", + addr, len, ret); +} + +static void rtw_usb_write_firmware_page(struct rtw_dev *rtwdev, u32 page, + const u8 *data, u32 size) +{ + u32 addr = FW_8192C_START_ADDRESS; + u8 *data_dup, *buf; + u32 n; + + data_dup = kmemdup(data, size, GFP_KERNEL); + if (!data_dup) + return; + + buf = data_dup; + + rtw_write32_mask(rtwdev, REG_MCUFW_CTRL, BIT_ROM_PGE, page); + + while (size > 0) { + if (size >= 196) + n = 196; + else if (size >= 8) + n = 8; + else + n = 1; + + rtw_usb_write_block(rtwdev, addr, buf, n); + + addr += n; + buf += n; + size -= n; + } + + kfree(data_dup); +} + static int dma_mapping_to_ep(enum rtw_dma_mapping dma_mapping) { switch (dma_mapping) { @@ -908,6 +956,7 @@ static const struct rtw_hci_ops rtw_usb_ops = { .link_ps = rtw_usb_link_ps, .interface_cfg = rtw_usb_interface_cfg, .dynamic_rx_agg = rtw_usb_dynamic_rx_agg, + .write_firmware_page = rtw_usb_write_firmware_page, .write8 = rtw_usb_write8, .write16 = rtw_usb_write16, From bbc08b8a2c25479ef9ecaa6e77054d4cb7ea9c4d Mon Sep 17 00:00:00 2001 From: Bitterblue Smith Date: Thu, 24 Apr 2025 18:17:43 +0300 Subject: [PATCH 167/193] wifi: rtw88: Transmit EAPOL frames at the lowest rate It may help when connecting to distant access points. For https://github.com/lwfinger/rtw88/issues/346. Signed-off-by: Bitterblue Smith --- tx.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/tx.c b/tx.c index aff17874..79c27a41 100644 --- a/tx.c +++ b/tx.c @@ -425,6 +425,9 @@ static void rtw_tx_data_pkt_info_update(struct rtw_dev *rtwdev, pkt_info->stbc = stbc; pkt_info->ldpc = ldpc; + if (skb->protocol == cpu_to_be16(ETH_P_PAE)) + rtw_tx_pkt_info_update_rate(rtwdev, pkt_info, skb, true); + fix_rate = dm_info->fix_rate; if (fix_rate < DESC_RATE_MAX) { pkt_info->rate = fix_rate; From 9c44629201f629de772b98449249b0d92912022d Mon Sep 17 00:00:00 2001 From: Bitterblue Smith Date: Thu, 24 Apr 2025 19:43:57 +0300 Subject: [PATCH 168/193] wifi: rtw88: usb: Discard packets smaller than FCS_LEN Avoid triggering the WARNING in ieee80211_rx_monitor(). For https://github.com/lwfinger/rtw88/issues/343. Signed-off-by: Bitterblue Smith --- usb.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/usb.c b/usb.c index b9fcc3bc..14b92302 100644 --- a/usb.c +++ b/usb.c @@ -646,6 +646,13 @@ static void rtw_usb_rx_handler(unsigned long shut_up_gcc) goto skip_packet; } + if (pkt_stat.pkt_len <= FCS_LEN) { + rtw_dbg(rtwdev, RTW_DBG_USB, + "skipping too small packet: %u + %u\n", + pkt_offset, pkt_stat.pkt_len); + goto skip_packet; + } + skb = alloc_skb(skb_len, GFP_ATOMIC); if (!skb) { rtw_dbg(rtwdev, RTW_DBG_USB, From e5928708f6edf86d1fcdcf8b2207580aae6a81c0 Mon Sep 17 00:00:00 2001 From: Bitterblue Smith Date: Tue, 29 Apr 2025 01:27:48 +0300 Subject: [PATCH 169/193] Revert "wifi: rtw88: usb: Discard packets smaller than FCS_LEN" This reverts commit 9c44629201f629de772b98449249b0d92912022d. That was not well thought through. Some messages from the firmware are also discarded. Signed-off-by: Bitterblue Smith --- usb.c | 7 ------- 1 file changed, 7 deletions(-) diff --git a/usb.c b/usb.c index 14b92302..b9fcc3bc 100644 --- a/usb.c +++ b/usb.c @@ -646,13 +646,6 @@ static void rtw_usb_rx_handler(unsigned long shut_up_gcc) goto skip_packet; } - if (pkt_stat.pkt_len <= FCS_LEN) { - rtw_dbg(rtwdev, RTW_DBG_USB, - "skipping too small packet: %u + %u\n", - pkt_offset, pkt_stat.pkt_len); - goto skip_packet; - } - skb = alloc_skb(skb_len, GFP_ATOMIC); if (!skb) { rtw_dbg(rtwdev, RTW_DBG_USB, From a1ffefc8dd4c394c388d245bf3376d354da89f0f Mon Sep 17 00:00:00 2001 From: Bitterblue Smith Date: Tue, 29 Apr 2025 01:41:03 +0300 Subject: [PATCH 170/193] wifi: rtw88: usb: Discard packets smaller than FCS_LEN Avoid triggering the WARNING in ieee80211_rx_monitor(). For https://github.com/lwfinger/rtw88/issues/343. Signed-off-by: Bitterblue Smith --- usb.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/usb.c b/usb.c index b9fcc3bc..1970ee46 100644 --- a/usb.c +++ b/usb.c @@ -646,6 +646,13 @@ static void rtw_usb_rx_handler(unsigned long shut_up_gcc) goto skip_packet; } + if (pkt_stat.pkt_len <= FCS_LEN && !pkt_stat.is_c2h) { + rtw_dbg(rtwdev, RTW_DBG_USB, + "skipping too small packet: %u + %u\n", + pkt_offset, pkt_stat.pkt_len); + goto skip_packet; + } + skb = alloc_skb(skb_len, GFP_ATOMIC); if (!skb) { rtw_dbg(rtwdev, RTW_DBG_USB, From 159893f003548a14b093a5325dde35cc583e35bb Mon Sep 17 00:00:00 2001 From: Bitterblue Smith Date: Sat, 3 May 2025 00:56:12 +0300 Subject: [PATCH 171/193] wifi: rtw88: Maybe fix the random "error beacon valid" for USB All the USB devices have a problem in AP mode: uploading the updated beacon to the chip's reserved page can randomly fail: [34996.474304] rtw88_8723du 1-2:1.2: error beacon valid [34996.474788] rtw88_8723du 1-2:1.2: failed to download drv rsvd page [34999.956369] rtw88_8723du 1-2:1.2: error beacon valid [34999.956846] rtw88_8723du 1-2:1.2: failed to download drv rsvd page [34999.956855] rtw88_8723du 1-2:1.2: failed to download beacon [35017.978296] rtw88_8723du 1-2:1.2: error beacon valid [35017.978805] rtw88_8723du 1-2:1.2: failed to download drv rsvd page [35017.978823] rtw88_8723du 1-2:1.2: failed to download beacon [35023.200395] rtw88_8723du 1-2:1.2: error beacon valid [35023.200869] rtw88_8723du 1-2:1.2: failed to download drv rsvd page [35023.200875] rtw88_8723du 1-2:1.2: failed to download beacon [35478.680547] rtw88_8723du 1-2:1.2: error beacon valid [35478.681023] rtw88_8723du 1-2:1.2: failed to download drv rsvd page It appears to be caused by some missing magic in rtw_fw_write_data_rsvd_page(). Signed-off-by: Bitterblue Smith --- fw.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/fw.c b/fw.c index c3d021ba..35cadb14 100644 --- a/fw.c +++ b/fw.c @@ -1497,7 +1497,7 @@ void rtw_add_rsvd_page_sta(struct rtw_dev *rtwdev, int rtw_fw_write_data_rsvd_page(struct rtw_dev *rtwdev, u16 pg_addr, u8 *buf, u32 size) { - u8 bckp[2]; + u8 bckp[3]; u8 val; u16 rsvd_pg_head; u32 bcn_valid_addr; @@ -1509,6 +1509,8 @@ int rtw_fw_write_data_rsvd_page(struct rtw_dev *rtwdev, u16 pg_addr, if (!size) return -EINVAL; + bckp[2] = rtw_read8(rtwdev, REG_BCN_CTRL); + if (rtw_chip_wcpu_11n(rtwdev)) { rtw_write32_set(rtwdev, REG_DWBCN0_CTRL, BIT_BCN_VALID); } else { @@ -1522,6 +1524,9 @@ int rtw_fw_write_data_rsvd_page(struct rtw_dev *rtwdev, u16 pg_addr, val |= BIT_ENSWBCN >> 8; rtw_write8(rtwdev, REG_CR + 1, val); + rtw_write8(rtwdev, REG_BCN_CTRL, + (bckp[2] & ~BIT_EN_BCN_FUNCTION) | BIT_DIS_TSF_UDT); + if (rtw_hci_type(rtwdev) == RTW_HCI_TYPE_PCIE) { val = rtw_read8(rtwdev, REG_FWHW_TXQ_CTRL + 2); bckp[1] = val; @@ -1552,6 +1557,7 @@ int rtw_fw_write_data_rsvd_page(struct rtw_dev *rtwdev, u16 pg_addr, rsvd_pg_head = rtwdev->fifo.rsvd_boundary; rtw_write16(rtwdev, REG_FIFOPAGE_CTRL_2, rsvd_pg_head | BIT_BCN_VALID_V1); + rtw_write8(rtwdev, REG_BCN_CTRL, bckp[2]); if (rtw_hci_type(rtwdev) == RTW_HCI_TYPE_PCIE) rtw_write8(rtwdev, REG_FWHW_TXQ_CTRL + 2, bckp[1]); rtw_write8(rtwdev, REG_CR + 1, bckp[0]); From 395e90cad29dd816351b6b4d570e46ce0481e6d3 Mon Sep 17 00:00:00 2001 From: Zenm Chen Date: Fri, 2 May 2025 13:13:13 +0800 Subject: [PATCH 172/193] Update README.md 1. Refine the dkms installation instructions. 2. Stop teaching users to install the driver on a system with Secure Boot Enabled via make. 3. Refine the instructions to load/unload the driver. 4. Add the instructions to update the driver installed via DKMS. 5. Remove Q1 and Q5 in Q&A which are not useful. --- README.md | 254 +++++++++++++++++++++--------------------------------- 1 file changed, 100 insertions(+), 154 deletions(-) diff --git a/README.md b/README.md index b8d847fb..1159b391 100644 --- a/README.md +++ b/README.md @@ -16,7 +16,7 @@ Compatible with **Linux kernel versions 5.4 and newer** as long as your distro h #### Supported Chipsets -- **PCIe**: RTL8723DE, RTL8821CE, RTL8822BE, RTL8822CE, RTL8814AE +- **PCIe**: RTL8723DE, RTL8814AE, RTL8821CE, RTL8822BE, RTL8822CE - **SDIO**: RTL8723CS, RTL8723DS, RTL8821CS, RTL8822BS, RTL8822CS - **USB** : RTL8723DU, RTL8811AU, RTL8811CU, RTL8812AU, RTL8812BU, RTL8812CU - **USB** : RTL8814AU, RTL8821AU, RTL8821CU, RTL8822BU, RTL8822CU @@ -37,14 +37,14 @@ Use the following instructions for that step. ## Installation Guide ### Prerequisites 📋 -Below are prerequisites for common Linux distributions __before__ you do a [basic installation](#basic-installation-for-all-distros-) or [installation with SecureBoot](#installation-with-secureboot-for-all-distros-): +Below are prerequisites for common Linux distributions __before__ installing this driver. #### Ubuntu ```bash sudo apt update && sudo apt upgrade ``` ```bash -sudo apt install linux-headers-$(uname -r) build-essential git +sudo apt install linux-headers-generic build-essential git ``` #### Fedora @@ -80,78 +80,45 @@ sudo apt install -y raspberrypi-kernel-headers build-essential git --- ### Installation Using DKMS 🔄 -Using DKMS (Dynamic Kernel Module Support) ensures that the `rtw88` kernel modules are automatically rebuilt and re-signed whenever the Linux kernel is updated on systems with secure boot enabled. Without DKMS, these drivers would stop working after each kernel update, requiring manual re-compilation and re-signing. DKMS should be available through your distribution’s package manager. You can learn more about DKMS [here](https://github.com/dell/dkms). +It's highly recommended to install this driver via DKMS especially Secure Boot is enabled on your machine. Using DKMS (Dynamic Kernel Module Support) ensures that the `rtw88` kernel modules are automatically rebuilt and re-signed whenever the Linux kernel is updated. Without DKMS, these drivers would stop working after each kernel update, requiring manual re-compilation and re-signing. DKMS should be available through your distribution’s package manager. You can learn more about DKMS [here](https://github.com/dell/dkms). -__Installation Process__ 1. Install `dkms` and all its required dependencies using your preferred package manager. -2. Create a new Machine Owner Key (MOK). - 1. Generate a private RSA key. - ```bash - sudo openssl genrsa -out /var/lib/dkms/mok.key 2048 - ``` +2. Clone the `rtw88` GitHub repository + ``` + git clone https://github.com/lwfinger/rtw88 + ``` + +3. Build, sign and install the rtw88 driver + ``` + cd rtw88 + ``` + ``` + sudo dkms install $PWD + ``` + +4. Install the firmware necessary for the rtw88 driver + ``` + sudo make install_fw + ``` + +5. Enroll the MOK (Machine Owner Key), this is needed **ONLY IF** Secure Boot is enabled on your machine. + ``` + sudo mokutil --import /var/lib/dkms/mok.pub + ``` + For Ubuntu-based distro users, run this command instead + ``` + sudo mokutil --import /var/lib/shim-signed/mok/MOK.der + ``` + + Note: At this point, you will be requested to enter a password. Remember this password and re-enter it after rebooting your system in order to enroll your new MOK into your system's UEFI. Please see [this tutorial](https://github.com/dell/dkms?tab=readme-ov-file#secure-boot) for more details. - 2. Generate an X.509 certificate from the private key. - - ```bash - sudo openssl req -new -x509 -key /var/lib/dkms/mok.key -outform DER -out /var/lib/dkms/mok.pub -nodes -days 36500 -subj "/CN=DKMS Kernel Module Signing Key/" - ``` - - 3. Enroll the certificate. - - ```bash - sudo mokutil --import /var/lib/dkms/mok.pub - ``` - - Note: At this point, you will be requested to enter a password. Remember this password and re-enter it after rebooting your system in order to enrol your new MOK into your system's UEFI. - - 4. Verify the new MOK was enrolled. - - ```bash - mokutil --list-enrolled - ``` - -3. Clone the `rtw88` GitHub repository to `/usr/src`. - - ```bash - cd /usr/src && sudo git clone https://github.com/lwfinger/rtw88.git rtw88-0.6 - ``` - -4. Add `rtw88` to `dkms`. - - ```bash - sudo dkms add -m rtw88 -v 0.6 - ``` - -5. Build and sign `rtw88` using your new MOK. - - ```bash - sudo dkms build -m rtw88 -v 0.6 - ``` - -6. Install `rtw88`. - - ```bash - sudo dkms install -m rtw88 -v 0.6 - ``` - -7. Verify `rtw88` was installed. - - ```bash - dkms status - ``` - -__Uninstallation Process__ -```bash -sudo dkms remove -m rtw88 -v 0.6 --all # Remove rtw88 from dkms -sudo rm -r /var/lib/dkms/rtw88 # Remove rtw88 dkms build files (if they exist) -sudo make -C /usr/src/rtw88-0.6 uninstall # Run uninstall target in Makefile -sudo rm -r /usr/src/rtw88-0.6 # Remove cloned source code directory -``` --- -### Basic Installation for All Distros 🛠 +### Installation Using make🛠 + +You will need to rebuild and reinstall the driver manually after each kernel updates if you choose this way to install the driver. This method is **NOT RECOMMENDED** for systems with Secure Boot enabled. ```bash git clone https://github.com/lwfinger/rtw88 @@ -170,7 +137,10 @@ sudo make install_fw ``` --- -### Basic Installation for Arch-based Distros 🛠 +### Installation for Arch-based Distros 🛠 + +This is the best way for Arch-based distro users to install this driver, one more step is required after running `makepkg -si` if Secure Boot is enabled on your machine: Enroll the MOK. Please see the step 5 in [Installation Using DKMS](#installation-using-dkms-) for details. + ```bash git clone https://aur.archlinux.org/rtw88-dkms-git.git ``` @@ -180,128 +150,104 @@ cd rtw88-dkms-git ```bash makepkg -si ``` ---- -### Installation with SecureBoot for All Distros 🔒 - -```bash -git clone https://github.com/lwfinger/rtw88 -``` -```bash -cd rtw88 -``` -```bash -make -``` -```bash -sudo make install_fw -``` -```bash -sudo make sign-install -``` -You will be prompted a password, **please keep it in mind and use it in next steps.** - -Reboot to activate the new installed module, then in the MOK managerment screen: -1. Select "Enroll key" and enroll the key created by above sign-install step -2. When promted, enter the password you entered when create sign key. -3. If you enter wrong password, your computer won't be bootable. In this case, - use the BOOT menu from your BIOS, to boot into your OS then do below steps: -```bash -sudo mokutil --reset -``` -- Restart your computer. -- Use BOOT menu from BIOS to boot into your OS. -- In the MOK managerment screen, select reset MOK list. -- Reboot then retry from the step `make sign-install`. - --- ## Important Information Below is important information for using this driver. ### 1. Blacklisting 🚫 -A file called `blacklist-rtw88.conf` will be installed into `/etc/modprobe.d` when you run `sudo make install`. It will blacklist all in-kernel rtw88 drivers, however, it will not blacklist out-of-kernel vendor drivers. You will need to uninstall any out-of-kernel vendor drivers that you have installed that may conflict. `blacklist-rtw88.conf` will be removed when you run `sudo make uninstall`. +A file called `rtw88.conf` will be installed into `/etc/modprobe.d`. It will blacklist all in-kernel rtw88 drivers, however, it will not blacklist out-of-kernel vendor drivers. You will need to uninstall any out-of-kernel vendor drivers that you have installed that may conflict. ### 2. Recovery Problems After Sleep/Hibernation 🛌 -Some BIOSs have trouble changing power state from D3hot to D0. If you have this problem, then: +Some BIOSs have trouble changing power state from D3hot to D0. If you have this problem, run ``` bash -sudo cp suspend_rtw8822be /usr/lib/systemd/system-sleep/. +sudo cp reload_rtw88.sh /usr/lib/systemd/system-sleep/ ``` That script will unload the driver before sleep or hibernation, and reload it following resumption. -If you have some device other than the 8822be, edit the script before copying it. - -### 3. How to Disable/Enable a Kernel Module 🪛 - ```bash -sudo modprobe -r rtw_8723de # This unloads the module -sudo modprobe -r rtw_core - -# Due to some pecularities in the modprobe utility, two steps are required. +### 3. How To Load/Unload Kernel Modules (aka Drivers)🪛 -sudo modprobe rtw_8723de # This loads the module +The kernel modules for RTL8821CU are used to demonstrate here, you need to change the module name according to the chip that your Wi-Fi adapter uses. -# Only a single modprobe call is required to load. +This unloads the modules for RTL8821CU, due to some pecularities in the modprobe utility, two steps are required. If you are not sure the names of the loaded modules for your Wi-Fi adapter, run `lsmod | grep -i rtw` ``` +sudo modprobe -r rtw_8821cu +sudo modprobe -r rtw_core -### 4. Kernel Updates 🔄 -When your kernel updates, run: -```bash -cd ~/rtw88 +# This command will show nothing because the modules for RTL8821CU were unloaded. +lsmod | grep -i rtw ``` -Change the above to the location where you downloaded the driver if necessary. +This loads the modules for RTL8821CU, only a single modprobe call is required. ``` -git pull -``` -``` -make -``` +sudo modprobe rtw_8821cu -``` -sudo make install -or -sudo make sign-install +# This command will show that the modules for RTL8821CU were loaded. +lsmod | grep -i rtw +rtw_8821cu 16384 0 +rtw_usb 36864 1 rtw_8821cu +rtw_8821c 98304 1 rtw_8821cu +rtw_core 294912 2 rtw_usb,rtw_8821c +mac80211 1220608 2 rtw_usb,rtw_core +cfg80211 1064960 2 rtw_core,mac80211 ``` +### 4. How To Update The Driver Installed via DKMS +1. Remove the installed rtw88 drivers completely, please see [Q1](#q1-how-to-remove-this-driver-if-it-doesnt-work-as-expected) in Q&A for details. +2. Run this command in the rtw88 source directory to pull the latest code + ``` + git pull + ``` -💡 **Remember, every newly installed kernel requires this step - no exceptions**. If the kernel update means that you have no network, skip the 'git pull' and build the driver as it is, but run `git pull` once you have connectivity, and rebuild if any updates were pulled. - +3. Build, sign, install the rtw88 driver from the latest code + ``` + sudo dkms install $PWD + ``` --- ## Q&A ---- - -### Q1: Is Secure Boot supported? -Yes, this repository provides a way to sign the kernel modules to be compatible with Secure Boot. [Check out the Installation with SecureBoot section](#installation-with-secureboot-for-all-distros-). +### Q1: How to remove this driver if it doesn't work as expected? ---- +For users who installed this driver via DKMS, run +``` +sudo dkms remove rtw88/0.6 --all +``` +``` +sudo rm -rf /var/lib/dkms/rtw88 +``` +``` +sudo rm -rf /usr/src/rtw88-0.6 +``` +``` +sudo rm -f /etc/modprobe.d/rtw88.conf +``` -### Q2: How to remove this driver if it doesn't work as expected? -Run this command in the rtw88 source directory and then the rtw88 driver will be unloaded and removed. +For users who installed this driver via `make`, run this command in the rtw88 source directory and then the rtw88 driver will be unloaded and removed. -`sudo make uninstall` +``` +sudo make uninstall +``` For Arch-based distro users, run -`sudo pacman -Rn rtw88-dkms-git` - ---- - -### Q3: My wifi adapter is plugged in an USB 3 port, how can I keep it in USB 2 mode to avoid potential interference in 2.4 GHz band? -The module `rtw_usb` has a parameter named `switch_usb_mode` which can enable or disable USB mode switching, setting it to "N" will keep your adapter in USB 2 mode. You can simply run the command below, unplug the adapter, reboot your computer, replug the adapter back and then your adapter will be in USB 2 mode. - -`sudo sh -c 'echo options rtw_usb switch_usb_mode=N > /etc/modprobe.d/rtw88.conf'` - ---- +``` +sudo pacman -Rn rtw88-dkms-git +``` -### Q4: My wifi adapter still doesn't work after installing this driver and `lsusb` shows it is in CD-ROM mode, what should I do? -Install `usb_modeswitch` which can switch your adapter from CD-ROM mode to Wi-Fi mode and then your wifi adapter should be in Wi-Fi mode after reboot. +### Q2: My Wi-Fi adapter is plugged in an USB 3 port, how can I keep it in USB 2 mode to avoid potential interference in 2.4 GHz band? +The module `rtw_usb` has a parameter named `switch_usb_mode` which can enable or disable USB mode switching, setting it to "n" will keep your adapter in USB 2 mode. ---- +Steps: +1. Open /etc/modprobe.d/rtw88.conf with your preferred editor. +2. Change `switch_usb_mode=y` to `switch_usb_mode=n` in line 7. +3. Unplug the Wi-Fi adapter. +4. Reboot (or [unload the rtw88 drivers](#3-how-to-loadunload-kernel-modules-aka-drivers)) +5. Plug your Wi-Fi adapter back. -### Q5: My computer becomes very slow while building the driver, any idea to avoid that? -Run `make JOBS=x` instead, `x` is the number of compilation jobs that will be executed simultaneously, you can adjust it according to the CPU cores available on your machine. +### Q3: My Wi-Fi adapter still doesn't work after installing this driver and `lsusb` shows it is in CD-ROM mode, what should I do? +Install `usb_modeswitch` which can switch your adapter from CD-ROM mode to Wi-Fi mode and then your Wi-Fi adapter should be in Wi-Fi mode after reboot. From 8436e5aaba1b4de7ea74a7041a06799bf0931bbd Mon Sep 17 00:00:00 2001 From: Zenm Chen Date: Tue, 6 May 2025 16:33:48 +0800 Subject: [PATCH 173/193] Rename blacklist-rtw88.conf to rtw88.conf 1. Rename blacklist-rtw88.conf to rtw88.conf 2. Blacklist the in-kernel rtw88 drivers for 8814AE/8814AU. 3. Add config entries for all the module parameters available. 4. Enable flags which are useful for debugging by default. --- Makefile | 4 ++-- dkms/post_install.sh | 2 +- blacklist-rtw88.conf => rtw88.conf | 19 +++++++++++++++++++ 3 files changed, 22 insertions(+), 3 deletions(-) rename blacklist-rtw88.conf => rtw88.conf (60%) diff --git a/Makefile b/Makefile index bfc3a8ff..caeb78e9 100644 --- a/Makefile +++ b/Makefile @@ -192,7 +192,7 @@ all: install: all @install -D -m 644 -t $(MODDESTDIR) *.ko - @install -D -m 644 -t /etc/modprobe.d blacklist-rtw88.conf + @install -D -m 644 -t /etc/modprobe.d rtw88.conf ifeq ($(COMPRESS_GZIP), y) @gzip -f $(MODDESTDIR)/*.ko @@ -230,7 +230,7 @@ uninstall: rmmod -s $$mod || true; \ done @rm -vf $(MODDESTDIR)/rtw_*.ko* - @rm -vf /etc/modprobe.d/blacklist-rtw88.conf + @rm -vf /etc/modprobe.d/rtw88.conf @depmod $(DEPMOD_ARGS) @echo "The rtw88 drivers were removed successfully." diff --git a/dkms/post_install.sh b/dkms/post_install.sh index 40703bec..ee6221cf 100755 --- a/dkms/post_install.sh +++ b/dkms/post_install.sh @@ -1,5 +1,5 @@ #! /bin/sh -install -D -m 644 -t /etc/modprobe.d blacklist-rtw88.conf +install -D -m 644 -t /etc/modprobe.d rtw88.conf exit 0 diff --git a/blacklist-rtw88.conf b/rtw88.conf similarity index 60% rename from blacklist-rtw88.conf rename to rtw88.conf index a2b19547..66930bad 100644 --- a/blacklist-rtw88.conf +++ b/rtw88.conf @@ -1,3 +1,19 @@ +# +# Configuration file for the out-of-kernel rtw88 drivers +# +# Link: https://github.com/lwfinger/rtw88 +# + +options rtw_usb switch_usb_mode=y + +options rtw_pci disable_msi=n +options rtw_pci disable_aspm=n + +options rtw_core debug_mask=0x80021 +options rtw_core disable_lps_deep=n +options rtw_core support_bf=y + +# Blacklist the in-kernel rtw88 drivers blacklist rtw88_8703b blacklist rtw88_8723cs blacklist rtw88_8723d @@ -7,6 +23,9 @@ blacklist rtw88_8723du blacklist rtw88_8723x blacklist rtw88_8812a blacklist rtw88_8812au +blacklist rtw88_8814a +blacklist rtw88_8814ae +blacklist rtw88_8814au blacklist rtw88_8821a blacklist rtw88_8821au blacklist rtw88_8821c From a8a60ab3c515636b39af1e3ebfbfe261179dfa4d Mon Sep 17 00:00:00 2001 From: Zenm Chen Date: Tue, 6 May 2025 19:22:41 +0800 Subject: [PATCH 174/193] Add reload_rtw88.sh If users encounter a recovery problem after sleep/hibernation, they can copy this script to /usr/lib/systemd/system-sleep/. It will unload/reload the rtw88 drivers on suspend/resume automatically. --- reload_rtw88.sh | 41 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) create mode 100755 reload_rtw88.sh diff --git a/reload_rtw88.sh b/reload_rtw88.sh new file mode 100755 index 00000000..4681b92a --- /dev/null +++ b/reload_rtw88.sh @@ -0,0 +1,41 @@ +#! /bin/sh +# +# Script to unload/reload the rtw88 driver on suspend/resume +# + +# A full list of the rtw88 drivers +FULLMOD="rtw_8723cs rtw_8723de rtw_8723ds rtw_8723du \ + rtw_8812au rtw_8814ae rtw_8814au rtw_8821au rtw_8821ce rtw_8821cs rtw_8821cu \ + rtw_8822be rtw_8822bs rtw_8822bu rtw_8822ce rtw_8822cs rtw_8822cu \ + rtw_8703b rtw_8723d rtw_8821a rtw_8812a rtw_8814a rtw_8821c rtw_8822b rtw_8822c \ + rtw_8723x rtw_88xxa rtw_pci rtw_sdio rtw_usb rtw_core" + +# Before sleep/hibernation, save a list of the loaded rtw88 drivers to /RTW88_LOADEDMOD +# and unload all the rtw88 drivers. +if [ "${1}" == "pre" ]; then + LOADEDMOD=$(lsmod | grep "^rtw_.....[a-z]" | cut -d ' ' -f 1) + if [ ! -z "$LOADEDMOD" -a "$LOADEDMOD" != " " ]; then + echo $LOADEDMOD > /RTW88_LOADEDMOD + fi + + for mod in $FULLMOD + do + rmmod -s $mod || true + done + +# When Resuming, load the modules saved in /RTW88_LOADEDMOD and then remove /RTW88_LOADEDMOD +# Not sure why Larry makes the system sleep for 15s before loading the modules. +elif [ "${1}" == "post" ]; then + if [ -r /RTW88_LOADEDMOD ]; then + sleep 15 + LOADEDMOD=$(cat /RTW88_LOADEDMOD) + for mod in $LOADEDMOD + do + modprobe $mod + done + rm -f /RTW88_LOADEDMOD + fi + +else + echo "Usage: ./reload_rtw88.sh [pre|post]" +fi From 960c823e52325a2de875ef07cc8a56cde061da1a Mon Sep 17 00:00:00 2001 From: Zenm Chen Date: Tue, 6 May 2025 19:47:37 +0800 Subject: [PATCH 175/193] Revert "Add support for TP-LINK Archer T2UB Nano" The USB ID "2357:013c" does not seem to exist, so remove it. --- rtw8821cu.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/rtw8821cu.c b/rtw8821cu.c index 0566d6ae..a019f408 100644 --- a/rtw8821cu.c +++ b/rtw8821cu.c @@ -37,8 +37,6 @@ static const struct usb_device_id rtw_8821cu_id_table[] = { .driver_info = (kernel_ulong_t)&(rtw8821c_hw_spec) }, /* Edimax */ { USB_DEVICE_AND_INTERFACE_INFO(0x7392, 0xd811, 0xff, 0xff, 0xff), .driver_info = (kernel_ulong_t)&(rtw8821c_hw_spec) }, /* Edimax */ - { USB_DEVICE_AND_INTERFACE_INFO(0x2357, 0x013c, 0xff, 0xff, 0xff), - .driver_info = (kernel_ulong_t)&(rtw8821c_hw_spec) }, /* TP-LINK Archer T2UB Nano */ {}, }; MODULE_DEVICE_TABLE(usb, rtw_8821cu_id_table); From cc1aa51962e3d5a629d24416e8222c935e41128d Mon Sep 17 00:00:00 2001 From: Zenm Chen Date: Wed, 7 May 2025 02:38:19 +0800 Subject: [PATCH 176/193] Makefile: Replace EXTRA_CFLAGS with ccflags-y EXTRA_CFLAGS is no longer supported since kernel 6.15, so replace it with ccflags-y. These 7 lines have no effect, remove them also. > ifeq ($(CONFIG_PCI), y) > EXTRA_CFLAGS += -DCONFIG_RTW88_8822BE=1 > EXTRA_CFLAGS += -DCONFIG_RTW88_8821CE=1 > EXTRA_CFLAGS += -DCONFIG_RTW88_8822CE=1 > EXTRA_CFLAGS += -DCONFIG_RTW88_8723DE=1 > endif > #EXTRA_CFLAGS += -DCONFIG_RTW88_REGD_USER_REG_HINTS --- Makefile | 18 +++++------------- 1 file changed, 5 insertions(+), 13 deletions(-) diff --git a/Makefile b/Makefile index caeb78e9..a606c8f9 100644 --- a/Makefile +++ b/Makefile @@ -36,17 +36,11 @@ ifeq ("","$(wildcard MOK.der)") NO_SKIP_SIGN := y endif -EXTRA_CFLAGS += -O2 -std=gnu11 -Wno-declaration-after-statement -ifeq ($(CONFIG_PCI), y) -EXTRA_CFLAGS += -DCONFIG_RTW88_8822BE=1 -EXTRA_CFLAGS += -DCONFIG_RTW88_8821CE=1 -EXTRA_CFLAGS += -DCONFIG_RTW88_8822CE=1 -EXTRA_CFLAGS += -DCONFIG_RTW88_8723DE=1 -endif -EXTRA_CFLAGS += -DCONFIG_RTW88_LEDS=1 -EXTRA_CFLAGS += -DCONFIG_RTW88_DEBUG=1 -EXTRA_CFLAGS += -DCONFIG_RTW88_DEBUGFS=1 -#EXTRA_CFLAGS += -DCONFIG_RTW88_REGD_USER_REG_HINTS +ccflags-y += -O2 -std=gnu11 -Wno-declaration-after-statement +ccflags-y += -DCONFIG_RTW88_LEDS=1 +ccflags-y += -DCONFIG_RTW88_DEBUG=1 +ccflags-y += -DCONFIG_RTW88_DEBUGFS=1 +ccflags-y += -D__CHECK_ENDIAN__ obj-m += rtw_core.o rtw_core-objs += main.o \ @@ -185,8 +179,6 @@ endif obj-m += rtw_usb.o rtw_usb-objs := usb.o -ccflags-y += -D__CHECK_ENDIAN__ - all: $(MAKE) -j$(JOBS) -C $(KSRC) M=$$PWD modules From 461b696b51317ba4ca585a4ddb32f2e72cd4efc9 Mon Sep 17 00:00:00 2001 From: Kees Cook Date: Mon, 10 Mar 2025 15:22:58 -0700 Subject: [PATCH 177/193] wifi: rtw88: Add __nonstring annotations for unterminated strings When a character array without a terminating NUL character has a static initializer, GCC 15's -Wunterminated-string-initialization will only warn if the array lacks the "nonstring" attribute[1]. Mark the arrays with __nonstring to and correctly identify the char array as "not a C string" and thereby eliminate the warning. Link: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=117178 [1] Cc: Ping-Ke Shih Cc: Johannes Berg Cc: linux-wireless@vger.kernel.org Signed-off-by: Kees Cook Signed-off-by: Ping-Ke Shih Link: https://patch.msgid.link/20250310222257.work.866-kees@kernel.org --- main.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/main.h b/main.h index b2369e57..3aa2ce01 100644 --- a/main.h +++ b/main.h @@ -972,7 +972,7 @@ struct rtw_vif { }; struct rtw_regulatory { - char alpha2[2]; + char alpha2[2] __nonstring; u8 txpwr_regd_2g; u8 txpwr_regd_5g; }; From a58632608dcd50e172da1ec87e14ebb0f8de2b30 Mon Sep 17 00:00:00 2001 From: Bitterblue Smith Date: Thu, 26 Jun 2025 21:34:17 +0300 Subject: [PATCH 178/193] wifi: rtw88: fix the 'para' buffer size to avoid reading out of bounds Set the size to 6 instead of 2, since 'para' array is passed to 'rtw_fw_bt_wifi_control(rtwdev, para[0], ¶[1])', which reads 5 bytes: void rtw_fw_bt_wifi_control(struct rtw_dev *rtwdev, u8 op_code, u8 *data) { ... SET_BT_WIFI_CONTROL_DATA1(h2c_pkt, *data); SET_BT_WIFI_CONTROL_DATA2(h2c_pkt, *(data + 1)); ... SET_BT_WIFI_CONTROL_DATA5(h2c_pkt, *(data + 4)); Detected using the static analysis tool - Svace. Fixes: 4136214 ("rtw88: add BT co-existence support") Signed-off-by: Alexey Kodanev Signed-off-by: Ping-Ke Shih Link: https://patch.msgid.link/20250513121304.124141-1-aleksei.kodanev@bell-sw.com --- coex.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/coex.c b/coex.c index c929db1e..64904278 100644 --- a/coex.c +++ b/coex.c @@ -309,7 +309,7 @@ static void rtw_coex_tdma_timer_base(struct rtw_dev *rtwdev, u8 type) { struct rtw_coex *coex = &rtwdev->coex; struct rtw_coex_stat *coex_stat = &coex->stat; - u8 para[2] = {0}; + u8 para[6] = {}; u8 times; u16 tbtt_interval = coex_stat->wl_beacon_interval; From 2e289b16f2c0f16475fea8354d7e528f2466dbef Mon Sep 17 00:00:00 2001 From: Bitterblue Smith Date: Thu, 26 Jun 2025 21:40:10 +0300 Subject: [PATCH 179/193] wifi: rtw88: pci: add PCI Express error handling Sometimes PCIe Advanced Error Reporting(AER), like bad TLP or Data link protocol error, happens due to unstable pci signal or no response from PCI host. pcieport 0000:00:00.0: AER: Multiple Corrected error message received from 0000:00:00.0 pcieport 0000:00:00.0: AER: PCIe Bus Error: severity=Corrected, type=Physical Layer, (Receiver ID) pcieport 0000:00:00.0: AER: device [14c3:6786] error status/mask=000000c1/00006000 pcieport 0000:00:00.0: AER: [ 0] RxErr (First) pcieport 0000:00:00.0: AER: [ 6] BadTLP pcieport 0000:00:00.0: AER: [ 7] BadDLLP pcieport 0000:00:00.0: AER: Corrected error message received from 0000:00:00.0 pcieport 0000:00:00.0: AER: found no error details for 0000:00:00.0 pcieport 0000:00:00.0: AER: Multiple Corrected error message received from 0000:00:00.0 pcieport 0000:00:00.0: AER: found no error details for 0000:00:00.0 pcieport 0000:00:00.0: AER: Multiple Corrected error message received from 0000:00:00.0 pcieport 0000:00:00.0: AER: found no error details for 0000:00:00.0 Setup callback function to call SER function to reset driver to recover from these states Signed-off-by: Chin-Yen Lee Signed-off-by: Ping-Ke Shih Link: https://patch.msgid.link/20250523062711.27213-2-pkshih@realtek.com --- main.c | 1 + pci.c | 37 +++++++++++++++++++++++++++++++++++++ pci.h | 1 + rtw8723de.c | 1 + rtw8821ce.c | 1 + rtw8822be.c | 1 + rtw8822ce.c | 1 + 7 files changed, 43 insertions(+) diff --git a/main.c b/main.c index 94c304c9..1da07c4d 100644 --- a/main.c +++ b/main.c @@ -647,6 +647,7 @@ void rtw_fw_recovery(struct rtw_dev *rtwdev) if (!test_bit(RTW_FLAG_RESTARTING, rtwdev->flags)) ieee80211_queue_work(rtwdev->hw, &rtwdev->fw_recovery_work); } +EXPORT_SYMBOL(rtw_fw_recovery); static void __fw_recovery_work(struct rtw_dev *rtwdev) { diff --git a/pci.c b/pci.c index 8b0d9617..85b9aebe 100644 --- a/pci.c +++ b/pci.c @@ -1726,6 +1726,43 @@ static void rtw_pci_napi_deinit(struct rtw_dev *rtwdev) #endif } +static pci_ers_result_t rtw_pci_io_err_detected(struct pci_dev *pdev, + pci_channel_state_t state) +{ + struct net_device *netdev = pci_get_drvdata(pdev); + + netif_device_detach(netdev); + + return PCI_ERS_RESULT_NEED_RESET; +} + +static pci_ers_result_t rtw_pci_io_slot_reset(struct pci_dev *pdev) +{ + struct ieee80211_hw *hw = pci_get_drvdata(pdev); + struct rtw_dev *rtwdev = hw->priv; + + rtw_fw_recovery(rtwdev); + + return PCI_ERS_RESULT_RECOVERED; +} + +static void rtw_pci_io_resume(struct pci_dev *pdev) +{ + struct net_device *netdev = pci_get_drvdata(pdev); + + /* ack any pending wake events, disable PME */ + pci_enable_wake(pdev, PCI_D0, 0); + + netif_device_attach(netdev); +} + +const struct pci_error_handlers rtw_pci_err_handler = { + .error_detected = rtw_pci_io_err_detected, + .slot_reset = rtw_pci_io_slot_reset, + .resume = rtw_pci_io_resume, +}; +EXPORT_SYMBOL(rtw_pci_err_handler); + int rtw_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id) { diff --git a/pci.h b/pci.h index c2134484..1a81f10f 100644 --- a/pci.h +++ b/pci.h @@ -235,6 +235,7 @@ struct rtw_pci { }; extern const struct dev_pm_ops rtw_pm_ops; +extern const struct pci_error_handlers rtw_pci_err_handler; int rtw_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id); void rtw_pci_remove(struct pci_dev *pdev); diff --git a/rtw8723de.c b/rtw8723de.c index abbaafa3..cb672571 100644 --- a/rtw8723de.c +++ b/rtw8723de.c @@ -23,6 +23,7 @@ static struct pci_driver rtw_8723de_driver = { .remove = rtw_pci_remove, .driver.pm = &rtw_pm_ops, .shutdown = rtw_pci_shutdown, + .err_handler = &rtw_pci_err_handler, }; module_pci_driver(rtw_8723de_driver); diff --git a/rtw8821ce.c b/rtw8821ce.c index f3d971fe..6e2c8548 100644 --- a/rtw8821ce.c +++ b/rtw8821ce.c @@ -27,6 +27,7 @@ static struct pci_driver rtw_8821ce_driver = { .remove = rtw_pci_remove, .driver.pm = &rtw_pm_ops, .shutdown = rtw_pci_shutdown, + .err_handler = &rtw_pci_err_handler, }; module_pci_driver(rtw_8821ce_driver); diff --git a/rtw8822be.c b/rtw8822be.c index 49949507..e5426452 100644 --- a/rtw8822be.c +++ b/rtw8822be.c @@ -23,6 +23,7 @@ static struct pci_driver rtw_8822be_driver = { .remove = rtw_pci_remove, .driver.pm = &rtw_pm_ops, .shutdown = rtw_pci_shutdown, + .err_handler = &rtw_pci_err_handler, }; module_pci_driver(rtw_8822be_driver); diff --git a/rtw8822ce.c b/rtw8822ce.c index e26c6bc8..8f6cac0b 100644 --- a/rtw8822ce.c +++ b/rtw8822ce.c @@ -27,6 +27,7 @@ static struct pci_driver rtw_8822ce_driver = { .remove = rtw_pci_remove, .driver.pm = &rtw_pm_ops, .shutdown = rtw_pci_shutdown, + .err_handler = &rtw_pci_err_handler, }; module_pci_driver(rtw_8822ce_driver); From 739b5a28f106fe513f32664cd69607481fd1cd11 Mon Sep 17 00:00:00 2001 From: Bitterblue Smith Date: Thu, 26 Jun 2025 21:41:30 +0300 Subject: [PATCH 180/193] wifi: rtw88: rtw8822bu VID/PID for BUFFALO WI-U2-866DM Add VID/PID 0411/03d1 for recently released BUFFALO WI-U2-866DM USB WiFi adapter. Signed-off-by: Yuuki NAGAO Acked-by: Ping-Ke Shih Signed-off-by: Ping-Ke Shih Link: https://patch.msgid.link/20250503003227.6673-1-wf.yn386@gmail.com --- rtw8822bu.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/rtw8822bu.c b/rtw8822bu.c index 572d1f31..ab50b3c4 100644 --- a/rtw8822bu.c +++ b/rtw8822bu.c @@ -77,6 +77,8 @@ static const struct usb_device_id rtw_8822bu_id_table[] = { .driver_info = (kernel_ulong_t)&(rtw8822b_hw_spec) }, /* Mercusys MA30N */ { USB_DEVICE_AND_INTERFACE_INFO(0x2001, 0x3322, 0xff, 0xff, 0xff), .driver_info = (kernel_ulong_t)&(rtw8822b_hw_spec) }, /* D-Link DWA-T185 rev. A1 */ + { USB_DEVICE_AND_INTERFACE_INFO(0x0411, 0x03d1, 0xff, 0xff, 0xff), + .driver_info = (kernel_ulong_t)&(rtw8822b_hw_spec) }, /* BUFFALO WI-U2-866DM */ {}, }; MODULE_DEVICE_TABLE(usb, rtw_8822bu_id_table); From a5b2764a63ffaac65f09f15748c2d808bc24a468 Mon Sep 17 00:00:00 2001 From: Bitterblue Smith Date: Thu, 26 Jun 2025 21:42:46 +0300 Subject: [PATCH 181/193] wifi: rtw88: do not ignore hardware read error during DPK In 'rtw8822c_dpk_cal_coef1()', do not ignore error returned by 'check_hw_ready()' but issue a warning to denote possible DPK issue. Compile tested only. Found by Linux Verification Center (linuxtesting.org) with SVACE. Fixes: 5227c2e ("rtw88: 8822c: add SW DPK support") Suggested-by: Ping-Ke Shih Signed-off-by: Dmitry Antipov Signed-off-by: Ping-Ke Shih Link: https://patch.msgid.link/20250415090720.194048-1-dmantipov@yandex.ru --- rtw8822c.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/rtw8822c.c b/rtw8822c.c index 910bd36b..24d1e92e 100644 --- a/rtw8822c.c +++ b/rtw8822c.c @@ -3956,7 +3956,8 @@ static void rtw8822c_dpk_cal_coef1(struct rtw_dev *rtwdev) rtw_write32(rtwdev, REG_NCTL0, 0x00001148); rtw_write32(rtwdev, REG_NCTL0, 0x00001149); - check_hw_ready(rtwdev, 0x2d9c, MASKBYTE0, 0x55); + if (!check_hw_ready(rtwdev, 0x2d9c, MASKBYTE0, 0x55)) + rtw_warn(rtwdev, "DPK stuck, performance may be suboptimal"); rtw_write8(rtwdev, 0x1b10, 0x0); rtw_write32_mask(rtwdev, REG_NCTL0, BIT_SUBPAGE, 0x0000000c); From 4897e014284ba5ec2a270e6a323ce07f1f0374b9 Mon Sep 17 00:00:00 2001 From: Bitterblue Smith Date: Thu, 26 Jun 2025 21:44:08 +0300 Subject: [PATCH 182/193] wifi: rtw88: sdio: map mgmt frames to queue TX_DESC_QSEL_MGMT The rtw88-sdio do not work in AP mode due to the lack of TX status report for management frames. Map the management frames to queue TX_DESC_QSEL_MGMT, which enables the chip to generate TX reports for these frames Tested-on: rtl8723ds Fixes: 65371a3 ("wifi: rtw88: sdio: Add HCI implementation for SDIO based chipsets") Signed-off-by: Zhen XIN Reviewed-by: Martin Blumenstingl Signed-off-by: Ping-Ke Shih Link: https://patch.msgid.link/20250410154217.1849977-3-zhen.xin@nokia-sbell.com --- sdio.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/sdio.c b/sdio.c index 579e0f66..06871e8a 100644 --- a/sdio.c +++ b/sdio.c @@ -727,10 +727,7 @@ static u8 rtw_sdio_get_tx_qsel(struct rtw_dev *rtwdev, struct sk_buff *skb, case RTW_TX_QUEUE_H2C: return TX_DESC_QSEL_H2C; case RTW_TX_QUEUE_MGMT: - if (rtw_chip_wcpu_11n(rtwdev)) - return TX_DESC_QSEL_HIGH; - else - return TX_DESC_QSEL_MGMT; + return TX_DESC_QSEL_MGMT; case RTW_TX_QUEUE_HI0: return TX_DESC_QSEL_HIGH; default: From aae30be9f6499f2613d1d2397a44d30927a642ad Mon Sep 17 00:00:00 2001 From: Bitterblue Smith Date: Thu, 26 Jun 2025 21:44:59 +0300 Subject: [PATCH 183/193] wifi: rtw88: sdio: call rtw_sdio_indicate_tx_status unconditionally The rtw88-sdio do not work in AP mode due to the lack of TX status report for management frames. Make the invocation of rtw_sdio_indicate_tx_status unconditional and cover all packet queues Tested-on: rtl8723ds Fixes: 65371a3 ("wifi: rtw88: sdio: Add HCI implementation for SDIO based chipsets") Signed-off-by: Zhen XIN Reviewed-by: Martin Blumenstingl Signed-off-by: Ping-Ke Shih Link: https://patch.msgid.link/20250410154217.1849977-2-zhen.xin@nokia-sbell.com --- sdio.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/sdio.c b/sdio.c index 06871e8a..761c5fe6 100644 --- a/sdio.c +++ b/sdio.c @@ -1234,10 +1234,7 @@ static void rtw_sdio_process_tx_queue(struct rtw_dev *rtwdev, return; } - if (queue <= RTW_TX_QUEUE_VO) - rtw_sdio_indicate_tx_status(rtwdev, skb); - else - dev_kfree_skb_any(skb); + rtw_sdio_indicate_tx_status(rtwdev, skb); } static void rtw_sdio_tx_handler(struct work_struct *work) From 0371dbdf80c6a57d30b7233ebc181f44514dd0fa Mon Sep 17 00:00:00 2001 From: Bitterblue Smith Date: Thu, 26 Jun 2025 21:50:49 +0300 Subject: [PATCH 184/193] wifi: rtw88: Fix the module names printed in dmesg The rtw88 module names all start with the "rtw88_" prefix, but the messages in dmesg mostly use the "rtw_" prefix. The messages from rtw88_8723cs don't even have the underscore. Use the KBUILD_MODNAME macro in every driver. This ensures that the messages in dmesg will always use the module name. Before: Mar 17 15:54:19 ideapad2 kernel: rtw_8814au 2-4:1.0: Firmware version 33.6.0, H2C version 6 After: Mar 17 16:33:35 ideapad2 kernel: rtw88_8814au 2-4:1.0: Firmware version 33.6.0, H2C version 6 Signed-off-by: Bitterblue Smith Signed-off-by: Ping-Ke Shih Link: https://patch.msgid.link/29cd29ba-bc51-4d5b-ad48-a43c6ce72d56@gmail.com Note that in this repository the prefix is actually "rtw_", to distinguish from the built-in modules. --- rtw8723cs.c | 2 +- rtw8723de.c | 2 +- rtw8723ds.c | 2 +- rtw8723du.c | 2 +- rtw8812au.c | 2 +- rtw8814ae.c | 2 +- rtw8814au.c | 2 +- rtw8821au.c | 2 +- rtw8821ce.c | 2 +- rtw8821cs.c | 2 +- rtw8821cu.c | 2 +- rtw8822be.c | 2 +- rtw8822bs.c | 2 +- rtw8822bu.c | 2 +- rtw8822ce.c | 2 +- rtw8822cs.c | 2 +- rtw8822cu.c | 2 +- 17 files changed, 17 insertions(+), 17 deletions(-) diff --git a/rtw8723cs.c b/rtw8723cs.c index 1e8dcae0..9d8a92d2 100644 --- a/rtw8723cs.c +++ b/rtw8723cs.c @@ -19,7 +19,7 @@ static const struct sdio_device_id rtw_8723cs_id_table[] = { MODULE_DEVICE_TABLE(sdio, rtw_8723cs_id_table); static struct sdio_driver rtw_8723cs_driver = { - .name = "rtw8723cs", + .name = KBUILD_MODNAME, .id_table = rtw_8723cs_id_table, .probe = rtw_sdio_probe, .remove = rtw_sdio_remove, diff --git a/rtw8723de.c b/rtw8723de.c index cb672571..c6d0c88e 100644 --- a/rtw8723de.c +++ b/rtw8723de.c @@ -17,7 +17,7 @@ static const struct pci_device_id rtw_8723de_id_table[] = { MODULE_DEVICE_TABLE(pci, rtw_8723de_id_table); static struct pci_driver rtw_8723de_driver = { - .name = "rtw_8723de", + .name = KBUILD_MODNAME, .id_table = rtw_8723de_id_table, .probe = rtw_pci_probe, .remove = rtw_pci_remove, diff --git a/rtw8723ds.c b/rtw8723ds.c index f1ffffe4..4913262c 100644 --- a/rtw8723ds.c +++ b/rtw8723ds.c @@ -25,7 +25,7 @@ static const struct sdio_device_id rtw_8723ds_id_table[] = { MODULE_DEVICE_TABLE(sdio, rtw_8723ds_id_table); static struct sdio_driver rtw_8723ds_driver = { - .name = "rtw_8723ds", + .name = KBUILD_MODNAME, .probe = rtw_sdio_probe, .remove = rtw_sdio_remove, .id_table = rtw_8723ds_id_table, diff --git a/rtw8723du.c b/rtw8723du.c index 322a805d..b661a26e 100644 --- a/rtw8723du.c +++ b/rtw8723du.c @@ -24,7 +24,7 @@ static int rtw8723du_probe(struct usb_interface *intf, } static struct usb_driver rtw_8723du_driver = { - .name = "rtw_8723du", + .name = KBUILD_MODNAME, .id_table = rtw_8723du_id_table, .probe = rtw8723du_probe, .disconnect = rtw_usb_disconnect, diff --git a/rtw8812au.c b/rtw8812au.c index e18995f4..dfea8967 100644 --- a/rtw8812au.c +++ b/rtw8812au.c @@ -82,7 +82,7 @@ static const struct usb_device_id rtw_8812au_id_table[] = { MODULE_DEVICE_TABLE(usb, rtw_8812au_id_table); static struct usb_driver rtw_8812au_driver = { - .name = "rtw_8812au", + .name = KBUILD_MODNAME, .id_table = rtw_8812au_id_table, .probe = rtw_usb_probe, .disconnect = rtw_usb_disconnect, diff --git a/rtw8814ae.c b/rtw8814ae.c index 54d2e20a..c7436f1c 100644 --- a/rtw8814ae.c +++ b/rtw8814ae.c @@ -17,7 +17,7 @@ static const struct pci_device_id rtw_8814ae_id_table[] = { MODULE_DEVICE_TABLE(pci, rtw_8814ae_id_table); static struct pci_driver rtw_8814ae_driver = { - .name = "rtw_8814ae", + .name = KBUILD_MODNAME, .id_table = rtw_8814ae_id_table, .probe = rtw_pci_probe, .remove = rtw_pci_remove, diff --git a/rtw8814au.c b/rtw8814au.c index afe045fb..1a0886ec 100644 --- a/rtw8814au.c +++ b/rtw8814au.c @@ -42,7 +42,7 @@ static const struct usb_device_id rtw_8814au_id_table[] = { MODULE_DEVICE_TABLE(usb, rtw_8814au_id_table); static struct usb_driver rtw_8814au_driver = { - .name = "rtw_8814au", + .name = KBUILD_MODNAME, .id_table = rtw_8814au_id_table, .probe = rtw_usb_probe, .disconnect = rtw_usb_disconnect, diff --git a/rtw8821au.c b/rtw8821au.c index a01744b6..28c281b3 100644 --- a/rtw8821au.c +++ b/rtw8821au.c @@ -66,7 +66,7 @@ static const struct usb_device_id rtw_8821au_id_table[] = { MODULE_DEVICE_TABLE(usb, rtw_8821au_id_table); static struct usb_driver rtw_8821au_driver = { - .name = "rtw_8821au", + .name = KBUILD_MODNAME, .id_table = rtw_8821au_id_table, .probe = rtw_usb_probe, .disconnect = rtw_usb_disconnect, diff --git a/rtw8821ce.c b/rtw8821ce.c index 6e2c8548..52a19cb1 100644 --- a/rtw8821ce.c +++ b/rtw8821ce.c @@ -21,7 +21,7 @@ static const struct pci_device_id rtw_8821ce_id_table[] = { MODULE_DEVICE_TABLE(pci, rtw_8821ce_id_table); static struct pci_driver rtw_8821ce_driver = { - .name = "rtw_8821ce", + .name = KBUILD_MODNAME, .id_table = rtw_8821ce_id_table, .probe = rtw_pci_probe, .remove = rtw_pci_remove, diff --git a/rtw8821cs.c b/rtw8821cs.c index 649f41ba..968d273c 100644 --- a/rtw8821cs.c +++ b/rtw8821cs.c @@ -20,7 +20,7 @@ static const struct sdio_device_id rtw_8821cs_id_table[] = { MODULE_DEVICE_TABLE(sdio, rtw_8821cs_id_table); static struct sdio_driver rtw_8821cs_driver = { - .name = "rtw_8821cs", + .name = KBUILD_MODNAME, .probe = rtw_sdio_probe, .remove = rtw_sdio_remove, .id_table = rtw_8821cs_id_table, diff --git a/rtw8821cu.c b/rtw8821cu.c index a019f408..7a0fffc3 100644 --- a/rtw8821cu.c +++ b/rtw8821cu.c @@ -48,7 +48,7 @@ static int rtw_8821cu_probe(struct usb_interface *intf, } static struct usb_driver rtw_8821cu_driver = { - .name = "rtw_8821cu", + .name = KBUILD_MODNAME, .id_table = rtw_8821cu_id_table, .probe = rtw_8821cu_probe, .disconnect = rtw_usb_disconnect, diff --git a/rtw8822be.c b/rtw8822be.c index e5426452..dda597d7 100644 --- a/rtw8822be.c +++ b/rtw8822be.c @@ -17,7 +17,7 @@ static const struct pci_device_id rtw_8822be_id_table[] = { MODULE_DEVICE_TABLE(pci, rtw_8822be_id_table); static struct pci_driver rtw_8822be_driver = { - .name = "rtw_8822be", + .name = KBUILD_MODNAME, .id_table = rtw_8822be_id_table, .probe = rtw_pci_probe, .remove = rtw_pci_remove, diff --git a/rtw8822bs.c b/rtw8822bs.c index 1ddef81d..ac1fca55 100644 --- a/rtw8822bs.c +++ b/rtw8822bs.c @@ -20,7 +20,7 @@ static const struct sdio_device_id rtw_8822bs_id_table[] = { MODULE_DEVICE_TABLE(sdio, rtw_8822bs_id_table); static struct sdio_driver rtw_8822bs_driver = { - .name = "rtw_8822bs", + .name = KBUILD_MODNAME, .probe = rtw_sdio_probe, .remove = rtw_sdio_remove, .id_table = rtw_8822bs_id_table, diff --git a/rtw8822bu.c b/rtw8822bu.c index ab50b3c4..44e28e58 100644 --- a/rtw8822bu.c +++ b/rtw8822bu.c @@ -90,7 +90,7 @@ static int rtw8822bu_probe(struct usb_interface *intf, } static struct usb_driver rtw_8822bu_driver = { - .name = "rtw_8822bu", + .name = KBUILD_MODNAME, .id_table = rtw_8822bu_id_table, .probe = rtw8822bu_probe, .disconnect = rtw_usb_disconnect, diff --git a/rtw8822ce.c b/rtw8822ce.c index 8f6cac0b..7ae95415 100644 --- a/rtw8822ce.c +++ b/rtw8822ce.c @@ -21,7 +21,7 @@ static const struct pci_device_id rtw_8822ce_id_table[] = { MODULE_DEVICE_TABLE(pci, rtw_8822ce_id_table); static struct pci_driver rtw_8822ce_driver = { - .name = "rtw_8822ce", + .name = KBUILD_MODNAME, .id_table = rtw_8822ce_id_table, .probe = rtw_pci_probe, .remove = rtw_pci_remove, diff --git a/rtw8822cs.c b/rtw8822cs.c index 5d68b9aa..d9a9eb85 100644 --- a/rtw8822cs.c +++ b/rtw8822cs.c @@ -20,7 +20,7 @@ static const struct sdio_device_id rtw_8822cs_id_table[] = { MODULE_DEVICE_TABLE(sdio, rtw_8822cs_id_table); static struct sdio_driver rtw_8822cs_driver = { - .name = "rtw_8822cs", + .name = KBUILD_MODNAME, .probe = rtw_sdio_probe, .remove = rtw_sdio_remove, .id_table = rtw_8822cs_id_table, diff --git a/rtw8822cu.c b/rtw8822cu.c index 157d5102..324fd5c8 100644 --- a/rtw8822cu.c +++ b/rtw8822cu.c @@ -32,7 +32,7 @@ static int rtw8822cu_probe(struct usb_interface *intf, } static struct usb_driver rtw_8822cu_driver = { - .name = "rtw_8822cu", + .name = KBUILD_MODNAME, .id_table = rtw_8822cu_id_table, .probe = rtw8822cu_probe, .disconnect = rtw_usb_disconnect, From 3d182de48fa49de96940d85d041a1996b19e3bdb Mon Sep 17 00:00:00 2001 From: Bitterblue Smith Date: Thu, 26 Jun 2025 21:59:52 +0300 Subject: [PATCH 185/193] wifi: rtw88: Rename the RTW_WCPU_11{AC,N} enums The RTW_WCPU_11AC and RTW_WCPU_11N enums are used to identify two types of microcontrollers used in Realtek chips, but these names are misleading. The "11AC" type was also used in 11n devices (e.g. RTL8733BU, not supported by rtw88), and the "11N" type was also used in 11ac devices (RTL8821AU, RTL8812AU). Rename RTW_WCPU_11AC to RTW_WCPU_3081 and RTW_WCPU_11N to RTW_WCPU_8051. (8051 is well known. It's less clear what 3081 is, but the out of tree drivers use this name.) Signed-off-by: Bitterblue Smith Signed-off-by: Ping-Ke Shih Link: https://patch.msgid.link/bfb1099c-db52-4b25-b111-17ab712e9404@gmail.com --- fw.c | 8 ++++---- mac.c | 22 +++++++++++----------- main.c | 2 +- main.h | 12 ++++++------ pci.c | 12 ++++++------ rtw8703b.c | 2 +- rtw8723d.c | 2 +- rtw8812a.c | 2 +- rtw8814a.c | 2 +- rtw8821a.c | 2 +- rtw8821c.c | 2 +- rtw8822b.c | 2 +- rtw8822c.c | 2 +- sdio.c | 8 ++++---- tx.c | 2 +- 15 files changed, 41 insertions(+), 41 deletions(-) diff --git a/fw.c b/fw.c index 35cadb14..bf66f06e 100644 --- a/fw.c +++ b/fw.c @@ -525,7 +525,7 @@ rtw_fw_send_general_info(struct rtw_dev *rtwdev) u8 h2c_pkt[H2C_PKT_SIZE] = {0}; u16 total_size = H2C_PKT_HDR_SIZE + 4; - if (rtw_chip_wcpu_11n(rtwdev)) + if (rtw_chip_wcpu_8051(rtwdev)) return; rtw_h2c_pkt_set_header(h2c_pkt, H2C_PKT_GENERAL_INFO); @@ -548,7 +548,7 @@ rtw_fw_send_phydm_info(struct rtw_dev *rtwdev) u16 total_size = H2C_PKT_HDR_SIZE + 8; u8 fw_rf_type = 0; - if (rtw_chip_wcpu_11n(rtwdev)) + if (rtw_chip_wcpu_8051(rtwdev)) return; if (hal->rf_type == RF_1T1R) @@ -1511,7 +1511,7 @@ int rtw_fw_write_data_rsvd_page(struct rtw_dev *rtwdev, u16 pg_addr, bckp[2] = rtw_read8(rtwdev, REG_BCN_CTRL); - if (rtw_chip_wcpu_11n(rtwdev)) { + if (rtw_chip_wcpu_8051(rtwdev)) { rtw_write32_set(rtwdev, REG_DWBCN0_CTRL, BIT_BCN_VALID); } else { pg_addr &= BIT_MASK_BCN_HEAD_1_V1; @@ -1540,7 +1540,7 @@ int rtw_fw_write_data_rsvd_page(struct rtw_dev *rtwdev, u16 pg_addr, goto restore; } - if (rtw_chip_wcpu_11n(rtwdev)) { + if (rtw_chip_wcpu_8051(rtwdev)) { bcn_valid_addr = REG_DWBCN0_CTRL; bcn_valid_mask = BIT_BCN_VALID; } else { diff --git a/mac.c b/mac.c index f66d1b30..011b81c8 100644 --- a/mac.c +++ b/mac.c @@ -41,7 +41,7 @@ void rtw_set_channel_mac(struct rtw_dev *rtwdev, u8 channel, u8 bw, } rtw_write32(rtwdev, REG_WMAC_TRXPTCL_CTL, value32); - if (rtw_chip_wcpu_11n(rtwdev)) + if (rtw_chip_wcpu_8051(rtwdev)) return; value32 = rtw_read32(rtwdev, REG_AFE_CTRL1) & ~(BIT_MAC_CLK_SEL); @@ -67,7 +67,7 @@ static int rtw_mac_pre_system_cfg(struct rtw_dev *rtwdev) rtw_write8(rtwdev, REG_RSV_CTRL, 0); - if (rtw_chip_wcpu_11n(rtwdev)) { + if (rtw_chip_wcpu_8051(rtwdev)) { if (rtw_read32(rtwdev, REG_SYS_CFG1) & BIT_LDO) rtw_write8(rtwdev, REG_LDO_SWR_CTRL, LDO_SEL); else @@ -278,7 +278,7 @@ static int rtw_mac_power_switch(struct rtw_dev *rtwdev, bool pwr_on) bool cur_pwr; int ret; - if (rtw_chip_wcpu_11ac(rtwdev)) { + if (rtw_chip_wcpu_3081(rtwdev)) { rpwm = rtw_read8(rtwdev, rtwdev->hci.rpwm_addr); /* Check FW still exist or not */ @@ -369,7 +369,7 @@ static int __rtw_mac_init_system_cfg_legacy(struct rtw_dev *rtwdev) static int rtw_mac_init_system_cfg(struct rtw_dev *rtwdev) { - if (rtw_chip_wcpu_11n(rtwdev)) + if (rtw_chip_wcpu_8051(rtwdev)) return __rtw_mac_init_system_cfg_legacy(rtwdev); return __rtw_mac_init_system_cfg(rtwdev); @@ -981,7 +981,7 @@ static int __rtw_download_firmware_legacy(struct rtw_dev *rtwdev, static int _rtw_download_firmware(struct rtw_dev *rtwdev, struct rtw_fw_state *fw) { - if (rtw_chip_wcpu_11n(rtwdev)) + if (rtw_chip_wcpu_8051(rtwdev)) return __rtw_download_firmware_legacy(rtwdev, fw); return __rtw_download_firmware(rtwdev, fw); @@ -1122,7 +1122,7 @@ static int txdma_queue_mapping(struct rtw_dev *rtwdev) rtw_write8(rtwdev, REG_CR, 0); rtw_write8(rtwdev, REG_CR, MAC_TRX_ENABLE); - if (rtw_chip_wcpu_11ac(rtwdev)) + if (rtw_chip_wcpu_3081(rtwdev)) rtw_write32(rtwdev, REG_H2CQ_CSR, BIT_H2CQ_FULL); if (rtw_hci_type(rtwdev) == RTW_HCI_TYPE_SDIO) { @@ -1145,7 +1145,7 @@ int rtw_set_trx_fifo_info(struct rtw_dev *rtwdev) /* config rsvd page num */ fifo->rsvd_drv_pg_num = chip->rsvd_drv_pg_num; fifo->txff_pg_num = chip->txff_size / chip->page_size; - if (rtw_chip_wcpu_11n(rtwdev)) + if (rtw_chip_wcpu_8051(rtwdev)) fifo->rsvd_pg_num = fifo->rsvd_drv_pg_num; else fifo->rsvd_pg_num = fifo->rsvd_drv_pg_num + @@ -1163,7 +1163,7 @@ int rtw_set_trx_fifo_info(struct rtw_dev *rtwdev) fifo->rsvd_boundary = fifo->txff_pg_num - fifo->rsvd_pg_num; cur_pg_addr = fifo->txff_pg_num; - if (rtw_chip_wcpu_11ac(rtwdev)) { + if (rtw_chip_wcpu_3081(rtwdev)) { cur_pg_addr -= csi_buf_pg_num; fifo->rsvd_csibuf_addr = cur_pg_addr; cur_pg_addr -= RSVD_PG_FW_TXBUF_NUM; @@ -1292,7 +1292,7 @@ static int priority_queue_cfg(struct rtw_dev *rtwdev) pubq_num = fifo->acq_pg_num - pg_tbl->hq_num - pg_tbl->lq_num - pg_tbl->nq_num - pg_tbl->exq_num - pg_tbl->gapq_num; - if (rtw_chip_wcpu_11n(rtwdev)) + if (rtw_chip_wcpu_8051(rtwdev)) return __priority_queue_cfg_legacy(rtwdev, pg_tbl, pubq_num); else return __priority_queue_cfg(rtwdev, pg_tbl, pubq_num); @@ -1308,7 +1308,7 @@ static int init_h2c(struct rtw_dev *rtwdev) u32 h2cq_free; u32 wp, rp; - if (rtw_chip_wcpu_11n(rtwdev)) + if (rtw_chip_wcpu_8051(rtwdev)) return 0; h2cq_addr = fifo->rsvd_h2cq_addr << TX_PAGE_SIZE_SHIFT; @@ -1375,7 +1375,7 @@ static int rtw_drv_info_cfg(struct rtw_dev *rtwdev) u8 value8; rtw_write8(rtwdev, REG_RX_DRVINFO_SZ, PHY_STATUS_SIZE); - if (rtw_chip_wcpu_11ac(rtwdev)) { + if (rtw_chip_wcpu_3081(rtwdev)) { value8 = rtw_read8(rtwdev, REG_TRXFF_BNDY + 1); value8 &= 0xF0; /* For rxdesc len = 0 issue */ diff --git a/main.c b/main.c index 1da07c4d..1f4fa510 100644 --- a/main.c +++ b/main.c @@ -1873,7 +1873,7 @@ static void __update_firmware_info_legacy(struct rtw_dev *rtwdev, static void update_firmware_info(struct rtw_dev *rtwdev, struct rtw_fw_state *fw) { - if (rtw_chip_wcpu_11n(rtwdev)) + if (rtw_chip_wcpu_8051(rtwdev)) __update_firmware_info_legacy(rtwdev, fw); else __update_firmware_info(rtwdev, fw); diff --git a/main.h b/main.h index 3aa2ce01..e978f339 100644 --- a/main.h +++ b/main.h @@ -1310,8 +1310,8 @@ struct rtw_pwr_track_tbl { }; enum rtw_wlan_cpu { - RTW_WCPU_11AC, - RTW_WCPU_11N, + RTW_WCPU_3081, + RTW_WCPU_8051, }; enum rtw_fw_fifo_sel { @@ -2304,14 +2304,14 @@ static inline void rtw_chip_efuse_grant_off(struct rtw_dev *rtwdev) rtwdev->chip->ops->efuse_grant(rtwdev, false); } -static inline bool rtw_chip_wcpu_11n(struct rtw_dev *rtwdev) +static inline bool rtw_chip_wcpu_8051(struct rtw_dev *rtwdev) { - return rtwdev->chip->wlan_cpu == RTW_WCPU_11N; + return rtwdev->chip->wlan_cpu == RTW_WCPU_8051; } -static inline bool rtw_chip_wcpu_11ac(struct rtw_dev *rtwdev) +static inline bool rtw_chip_wcpu_3081(struct rtw_dev *rtwdev) { - return rtwdev->chip->wlan_cpu == RTW_WCPU_11AC; + return rtwdev->chip->wlan_cpu == RTW_WCPU_3081; } static inline bool rtw_chip_has_rx_ldpc(struct rtw_dev *rtwdev) diff --git a/pci.c b/pci.c index 85b9aebe..d1b1be10 100644 --- a/pci.c +++ b/pci.c @@ -405,7 +405,7 @@ static void rtw_pci_reset_buf_desc(struct rtw_dev *rtwdev) dma = rtwpci->tx_rings[RTW_TX_QUEUE_BCN].r.dma; rtw_write32(rtwdev, RTK_PCI_TXBD_DESA_BCNQ, dma); - if (!rtw_chip_wcpu_11n(rtwdev)) { + if (!rtw_chip_wcpu_8051(rtwdev)) { len = rtwpci->tx_rings[RTW_TX_QUEUE_H2C].r.len; dma = rtwpci->tx_rings[RTW_TX_QUEUE_H2C].r.dma; rtwpci->tx_rings[RTW_TX_QUEUE_H2C].r.rp = 0; @@ -467,7 +467,7 @@ static void rtw_pci_reset_buf_desc(struct rtw_dev *rtwdev) rtw_write32(rtwdev, RTK_PCI_TXBD_RWPTR_CLR, 0xffffffff); /* reset H2C Queue index in a single write */ - if (rtw_chip_wcpu_11ac(rtwdev)) + if (rtw_chip_wcpu_3081(rtwdev)) rtw_write32_set(rtwdev, RTK_PCI_TXBD_H2CQ_CSR, BIT_CLR_H2CQ_HOST_IDX | BIT_CLR_H2CQ_HW_IDX); } @@ -487,7 +487,7 @@ static void rtw_pci_enable_interrupt(struct rtw_dev *rtwdev, rtw_write32(rtwdev, RTK_PCI_HIMR0, rtwpci->irq_mask[0] & ~imr0_unmask); rtw_write32(rtwdev, RTK_PCI_HIMR1, rtwpci->irq_mask[1]); - if (rtw_chip_wcpu_11ac(rtwdev)) + if (rtw_chip_wcpu_3081(rtwdev)) rtw_write32(rtwdev, RTK_PCI_HIMR3, rtwpci->irq_mask[3]); rtwpci->irq_enabled = true; @@ -507,7 +507,7 @@ static void rtw_pci_disable_interrupt(struct rtw_dev *rtwdev, rtw_write32(rtwdev, RTK_PCI_HIMR0, 0); rtw_write32(rtwdev, RTK_PCI_HIMR1, 0); - if (rtw_chip_wcpu_11ac(rtwdev)) + if (rtw_chip_wcpu_3081(rtwdev)) rtw_write32(rtwdev, RTK_PCI_HIMR3, 0); rtwpci->irq_enabled = false; @@ -1125,7 +1125,7 @@ static void rtw_pci_irq_recognized(struct rtw_dev *rtwdev, irq_status[0] = rtw_read32(rtwdev, RTK_PCI_HISR0); irq_status[1] = rtw_read32(rtwdev, RTK_PCI_HISR1); - if (rtw_chip_wcpu_11ac(rtwdev)) + if (rtw_chip_wcpu_3081(rtwdev)) irq_status[3] = rtw_read32(rtwdev, RTK_PCI_HISR3); else irq_status[3] = 0; @@ -1134,7 +1134,7 @@ static void rtw_pci_irq_recognized(struct rtw_dev *rtwdev, irq_status[3] &= rtwpci->irq_mask[3]; rtw_write32(rtwdev, RTK_PCI_HISR0, irq_status[0]); rtw_write32(rtwdev, RTK_PCI_HISR1, irq_status[1]); - if (rtw_chip_wcpu_11ac(rtwdev)) + if (rtw_chip_wcpu_3081(rtwdev)) rtw_write32(rtwdev, RTK_PCI_HISR3, irq_status[3]); spin_unlock_irqrestore(&rtwpci->hwirq_lock, flags); diff --git a/rtw8703b.c b/rtw8703b.c index dff5b2fe..4466b463 100644 --- a/rtw8703b.c +++ b/rtw8703b.c @@ -1897,7 +1897,7 @@ const struct rtw_chip_info rtw8703b_hw_spec = { .id = RTW_CHIP_TYPE_8703B, .fw_name = "rtw88/rtw8703b_fw.bin", - .wlan_cpu = RTW_WCPU_11N, + .wlan_cpu = RTW_WCPU_8051, .tx_pkt_desc_sz = 40, .tx_buf_desc_sz = 16, .rx_pkt_desc_sz = 24, diff --git a/rtw8723d.c b/rtw8723d.c index 5acddd80..1db0473f 100644 --- a/rtw8723d.c +++ b/rtw8723d.c @@ -2116,7 +2116,7 @@ const struct rtw_chip_info rtw8723d_hw_spec = { .ops = &rtw8723d_ops, .id = RTW_CHIP_TYPE_8723D, .fw_name = "rtw88/rtw8723d_fw.bin", - .wlan_cpu = RTW_WCPU_11N, + .wlan_cpu = RTW_WCPU_8051, .tx_pkt_desc_sz = 40, .tx_buf_desc_sz = 16, .rx_pkt_desc_sz = 24, diff --git a/rtw8812a.c b/rtw8812a.c index 34e052dd..c0b4af96 100644 --- a/rtw8812a.c +++ b/rtw8812a.c @@ -1048,7 +1048,7 @@ const struct rtw_chip_info rtw8812a_hw_spec = { .ops = &rtw8812a_ops, .id = RTW_CHIP_TYPE_8812A, .fw_name = "rtw88/rtw8812a_fw.bin", - .wlan_cpu = RTW_WCPU_11N, + .wlan_cpu = RTW_WCPU_8051, .tx_pkt_desc_sz = 40, .tx_buf_desc_sz = 16, .rx_pkt_desc_sz = 24, diff --git a/rtw8814a.c b/rtw8814a.c index 51644439..8046bf06 100644 --- a/rtw8814a.c +++ b/rtw8814a.c @@ -2177,7 +2177,7 @@ const struct rtw_chip_info rtw8814a_hw_spec = { .ops = &rtw8814a_ops, .id = RTW_CHIP_TYPE_8814A, .fw_name = "rtw88/rtw8814a_fw.bin", - .wlan_cpu = RTW_WCPU_11AC, + .wlan_cpu = RTW_WCPU_3081, .tx_pkt_desc_sz = 40, .tx_buf_desc_sz = 16, .rx_pkt_desc_sz = 24, diff --git a/rtw8821a.c b/rtw8821a.c index fa4b1a53..89b2bd13 100644 --- a/rtw8821a.c +++ b/rtw8821a.c @@ -1148,7 +1148,7 @@ const struct rtw_chip_info rtw8821a_hw_spec = { .ops = &rtw8821a_ops, .id = RTW_CHIP_TYPE_8821A, .fw_name = "rtw88/rtw8821a_fw.bin", - .wlan_cpu = RTW_WCPU_11N, + .wlan_cpu = RTW_WCPU_8051, .tx_pkt_desc_sz = 40, .tx_buf_desc_sz = 16, .rx_pkt_desc_sz = 24, diff --git a/rtw8821c.c b/rtw8821c.c index 97e081dd..d0bd6e70 100644 --- a/rtw8821c.c +++ b/rtw8821c.c @@ -1979,7 +1979,7 @@ const struct rtw_chip_info rtw8821c_hw_spec = { .ops = &rtw8821c_ops, .id = RTW_CHIP_TYPE_8821C, .fw_name = "rtw88/rtw8821c_fw.bin", - .wlan_cpu = RTW_WCPU_11AC, + .wlan_cpu = RTW_WCPU_3081, .tx_pkt_desc_sz = 48, .tx_buf_desc_sz = 16, .rx_pkt_desc_sz = 24, diff --git a/rtw8822b.c b/rtw8822b.c index d631c7ad..b72f622e 100644 --- a/rtw8822b.c +++ b/rtw8822b.c @@ -2518,7 +2518,7 @@ const struct rtw_chip_info rtw8822b_hw_spec = { .ops = &rtw8822b_ops, .id = RTW_CHIP_TYPE_8822B, .fw_name = "rtw88/rtw8822b_fw.bin", - .wlan_cpu = RTW_WCPU_11AC, + .wlan_cpu = RTW_WCPU_3081, .tx_pkt_desc_sz = 48, .tx_buf_desc_sz = 16, .rx_pkt_desc_sz = 24, diff --git a/rtw8822c.c b/rtw8822c.c index 24d1e92e..cef20a70 100644 --- a/rtw8822c.c +++ b/rtw8822c.c @@ -5337,7 +5337,7 @@ const struct rtw_chip_info rtw8822c_hw_spec = { .ops = &rtw8822c_ops, .id = RTW_CHIP_TYPE_8822C, .fw_name = "rtw88/rtw8822c_fw.bin", - .wlan_cpu = RTW_WCPU_11AC, + .wlan_cpu = RTW_WCPU_3081, .tx_pkt_desc_sz = 48, .tx_buf_desc_sz = 16, .rx_pkt_desc_sz = 24, diff --git a/sdio.c b/sdio.c index 761c5fe6..0d76b2d2 100644 --- a/sdio.c +++ b/sdio.c @@ -547,7 +547,7 @@ static int rtw_sdio_check_free_txpg(struct rtw_dev *rtwdev, u8 queue, { unsigned int pages_free, pages_needed; - if (rtw_chip_wcpu_11n(rtwdev)) { + if (rtw_chip_wcpu_8051(rtwdev)) { u32 free_txpg; free_txpg = rtw_sdio_read32(rtwdev, REG_SDIO_FREE_TXPG); @@ -1028,7 +1028,7 @@ static void rtw_sdio_rx_isr(struct rtw_dev *rtwdev) u32 rx_len, hisr, total_rx_bytes = 0; do { - if (rtw_chip_wcpu_11n(rtwdev)) + if (rtw_chip_wcpu_8051(rtwdev)) rx_len = rtw_read16(rtwdev, REG_SDIO_RX0_REQ_LEN); else rx_len = rtw_read32(rtwdev, REG_SDIO_RX0_REQ_LEN); @@ -1040,7 +1040,7 @@ static void rtw_sdio_rx_isr(struct rtw_dev *rtwdev) total_rx_bytes += rx_len; - if (rtw_chip_wcpu_11n(rtwdev)) { + if (rtw_chip_wcpu_8051(rtwdev)) { /* Stop if no more RX requests are pending, even if * rx_len could be greater than zero in the next * iteration. This is needed because the RX buffer may @@ -1052,7 +1052,7 @@ static void rtw_sdio_rx_isr(struct rtw_dev *rtwdev) */ hisr = rtw_read32(rtwdev, REG_SDIO_HISR); } else { - /* RTW_WCPU_11AC chips have improved hardware or + /* RTW_WCPU_3081 chips have improved hardware or * firmware and can use rx_len unconditionally. */ hisr = REG_SDIO_HISR_RX_REQUEST; diff --git a/tx.c b/tx.c index 79c27a41..9f090a8b 100644 --- a/tx.c +++ b/tx.c @@ -271,7 +271,7 @@ void rtw_tx_report_handle(struct rtw_dev *rtwdev, struct sk_buff *skb, int src) spin_lock_irqsave(&tx_report->q_lock, flags); skb_queue_walk_safe(&tx_report->queue, cur, tmp) { n = (u8 *)IEEE80211_SKB_CB(cur)->status.status_driver_data; - if (*n == sn || rtw_chip_wcpu_11n(rtwdev)) { + if (*n == sn || rtw_chip_wcpu_8051(rtwdev)) { __skb_unlink(cur, &tx_report->queue); rtw_tx_report_tx_status(rtwdev, cur, st == 0); break; From 901057059d03da0fa3dad0330d64a2cc08e501c2 Mon Sep 17 00:00:00 2001 From: Bitterblue Smith Date: Thu, 26 Jun 2025 22:01:53 +0300 Subject: [PATCH 186/193] wifi: rtw88: usb: Remove redundant 'flush_workqueue()' calls 'destroy_workqueue()' already drains the queue before destroying it, so there is no need to flush it explicitly. Remove the redundant 'flush_workqueue()' calls. This was generated with coccinelle: @@ expression E; @@ - flush_workqueue(E); destroy_workqueue(E); Signed-off-by: Chen Ni Signed-off-by: Ping-Ke Shih Link: https://patch.msgid.link/20250324080303.408084-1-nichen@iscas.ac.cn --- usb.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/usb.c b/usb.c index 1970ee46..ffb3af11 100644 --- a/usb.c +++ b/usb.c @@ -1030,7 +1030,6 @@ static void rtw_usb_deinit_rx(struct rtw_dev *rtwdev) skb_queue_purge(&rtwusb->rx_queue); - flush_workqueue(rtwusb->rxwq); destroy_workqueue(rtwusb->rxwq); skb_queue_purge(&rtwusb->rx_free_queue); @@ -1062,7 +1061,6 @@ static void rtw_usb_deinit_tx(struct rtw_dev *rtwdev) #if LINUX_VERSION_CODE < KERNEL_VERSION(6, 13, 0) rtw_usb_tx_queue_purge(rtwusb); #endif - flush_workqueue(rtwusb->txwq); destroy_workqueue(rtwusb->txwq); #if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 13, 0) rtw_usb_tx_queue_purge(rtwusb); From 8a1dcc136608e5eb40ba72137693497f50cff83c Mon Sep 17 00:00:00 2001 From: Bitterblue Smith Date: Thu, 26 Jun 2025 22:06:16 +0300 Subject: [PATCH 187/193] wifi: rtw88: usb: Upload the firmware in bigger chunks (update) Update to the version of the patch that went into the kernel. Upstream commit 80fe0bc1659c0ccc79d082e426fa376be5df9c04. Signed-off-by: Bitterblue Smith --- usb.c | 46 ++++++++++++++++++++++++++-------------------- 1 file changed, 26 insertions(+), 20 deletions(-) diff --git a/usb.c b/usb.c index ffb3af11..cd5334ea 100644 --- a/usb.c +++ b/usb.c @@ -165,27 +165,24 @@ static void rtw_usb_write32(struct rtw_dev *rtwdev, u32 addr, u32 val) rtw_usb_write(rtwdev, addr, val, 4); } -static void rtw_usb_write_block(struct rtw_dev *rtwdev, u32 addr, - u8 *data, u32 len) -{ - struct rtw_usb *rtwusb = (struct rtw_usb *)rtwdev->priv; - struct usb_device *udev = rtwusb->udev; - int ret; - - ret = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), - RTW_USB_CMD_REQ, RTW_USB_CMD_WRITE, - addr, 0, (void *)data, len, 500); - if (ret < 0 && ret != -ENODEV) - rtw_err(rtwdev, "write register 0x%x len %d failed with %d\n", - addr, len, ret); -} - static void rtw_usb_write_firmware_page(struct rtw_dev *rtwdev, u32 page, const u8 *data, u32 size) { - u32 addr = FW_8192C_START_ADDRESS; + struct rtw_usb *rtwusb = rtw_get_usb_priv(rtwdev); + struct usb_device *udev = rtwusb->udev; + u32 addr = FW_START_ADDR_LEGACY; u8 *data_dup, *buf; - u32 n; + u32 n, block_size; + int ret; + + switch (rtwdev->chip->id) { + case RTW_CHIP_TYPE_8723D: + block_size = 254; + break; + default: + block_size = 196; + break; + } data_dup = kmemdup(data, size, GFP_KERNEL); if (!data_dup) @@ -196,14 +193,23 @@ static void rtw_usb_write_firmware_page(struct rtw_dev *rtwdev, u32 page, rtw_write32_mask(rtwdev, REG_MCUFW_CTRL, BIT_ROM_PGE, page); while (size > 0) { - if (size >= 196) - n = 196; + if (size >= block_size) + n = block_size; else if (size >= 8) n = 8; else n = 1; - rtw_usb_write_block(rtwdev, addr, buf, n); + ret = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), + RTW_USB_CMD_REQ, RTW_USB_CMD_WRITE, + addr, 0, buf, n, 500); + if (ret != n) { + if (ret != -ENODEV) + rtw_err(rtwdev, + "write 0x%x len %d failed: %d\n", + addr, n, ret); + break; + } addr += n; buf += n; From 7e74b621f77f9523e8d5344048d15f3890afa651 Mon Sep 17 00:00:00 2001 From: Bitterblue Smith Date: Thu, 26 Jun 2025 22:09:37 +0300 Subject: [PATCH 188/193] Delete sta_mode_only check It was already deactivated before. Signed-off-by: Bitterblue Smith --- main.c | 20 +++++++------------- 1 file changed, 7 insertions(+), 13 deletions(-) diff --git a/main.c b/main.c index 1f4fa510..8a8bef5b 100644 --- a/main.c +++ b/main.c @@ -2336,7 +2336,6 @@ EXPORT_SYMBOL(rtw_core_deinit); int rtw_register_hw(struct rtw_dev *rtwdev, struct ieee80211_hw *hw) { - bool sta_mode_only = false; /*rtwdev->hci.type == RTW_HCI_TYPE_SDIO;*/ struct rtw_hal *hal = &rtwdev->hal; int max_tx_headroom = 0; int ret; @@ -2366,14 +2365,11 @@ int rtw_register_hw(struct rtw_dev *rtwdev, struct ieee80211_hw *hw) ieee80211_hw_set(hw, TX_AMSDU); ieee80211_hw_set(hw, SINGLE_SCAN_ON_ALL_BANDS); - if (sta_mode_only) - hw->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION); - else - hw->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) | - BIT(NL80211_IFTYPE_AP) | - BIT(NL80211_IFTYPE_ADHOC) | - BIT(NL80211_IFTYPE_P2P_CLIENT) | - BIT(NL80211_IFTYPE_P2P_GO); + hw->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) | + BIT(NL80211_IFTYPE_AP) | + BIT(NL80211_IFTYPE_ADHOC) | + BIT(NL80211_IFTYPE_P2P_CLIENT) | + BIT(NL80211_IFTYPE_P2P_GO); hw->wiphy->available_antennas_tx = hal->antenna_tx; hw->wiphy->available_antennas_rx = hal->antenna_rx; @@ -2384,10 +2380,8 @@ int rtw_register_hw(struct rtw_dev *rtwdev, struct ieee80211_hw *hw) hw->wiphy->max_scan_ssids = RTW_SCAN_MAX_SSIDS; hw->wiphy->max_scan_ie_len = rtw_get_max_scan_ie_len(rtwdev); - if (!sta_mode_only) { - hw->wiphy->iface_combinations = rtw_iface_combs; - hw->wiphy->n_iface_combinations = ARRAY_SIZE(rtw_iface_combs); - } + hw->wiphy->iface_combinations = rtw_iface_combs; + hw->wiphy->n_iface_combinations = ARRAY_SIZE(rtw_iface_combs); wiphy_ext_feature_set(hw->wiphy, NL80211_EXT_FEATURE_CAN_REPLACE_PTK0); wiphy_ext_feature_set(hw->wiphy, NL80211_EXT_FEATURE_SCAN_RANDOM_SN); From 9086ff26ec82615ee491c6567b79c23fe0f53f11 Mon Sep 17 00:00:00 2001 From: Bitterblue Smith Date: Thu, 26 Jun 2025 22:13:36 +0300 Subject: [PATCH 189/193] Sync set_ampdu_factor stuff To match the version that went into the kernel. Signed-off-by: Bitterblue Smith --- rtw8703b.c | 2 +- rtw8723d.c | 2 +- rtw8723x.c | 8 -------- rtw8723x.h | 6 ------ rtw8812a.c | 12 +----------- rtw8814a.c | 5 ++++- rtw8821a.c | 12 +----------- rtw8821c.c | 7 +------ rtw8822b.c | 7 +------ rtw8822c.c | 7 +------ 10 files changed, 11 insertions(+), 57 deletions(-) diff --git a/rtw8703b.c b/rtw8703b.c index 4466b463..22dc6ca1 100644 --- a/rtw8703b.c +++ b/rtw8703b.c @@ -1859,7 +1859,7 @@ static const struct rtw_chip_ops rtw8703b_ops = { .set_antenna = NULL, .cfg_ldo25 = rtw8723x_cfg_ldo25, .efuse_grant = rtw8723x_efuse_grant, - .set_ampdu_factor = rtw8723x_set_ampdu_factor, + .set_ampdu_factor = NULL, .false_alarm_statistics = rtw8723x_false_alarm_statistics, .phy_calibration = rtw8703b_phy_calibration, .dpk_track = NULL, diff --git a/rtw8723d.c b/rtw8723d.c index 1db0473f..bf69f5b0 100644 --- a/rtw8723d.c +++ b/rtw8723d.c @@ -1404,7 +1404,7 @@ static const struct rtw_chip_ops rtw8723d_ops = { .set_antenna = NULL, .cfg_ldo25 = rtw8723x_cfg_ldo25, .efuse_grant = rtw8723x_efuse_grant, - .set_ampdu_factor = rtw8723x_set_ampdu_factor, + .set_ampdu_factor = NULL, .false_alarm_statistics = rtw8723x_false_alarm_statistics, .phy_calibration = rtw8723d_phy_calibration, .cck_pd_set = rtw8723d_phy_cck_pd_set, diff --git a/rtw8723x.c b/rtw8723x.c index e2127d33..4c77963f 100644 --- a/rtw8723x.c +++ b/rtw8723x.c @@ -433,13 +433,6 @@ static void __rtw8723x_efuse_grant(struct rtw_dev *rtwdev, bool on) } } -static void __rtw8723x_set_ampdu_factor(struct rtw_dev *rtwdev, u8 factor) -{ - factor = min_t(u8, factor, IEEE80211_HT_MAX_AMPDU_32K); - - rtw_write32(rtwdev, REG_AMPDU_MAX_LENGTH, (8192 << factor) - 1); -} - static void __rtw8723x_false_alarm_statistics(struct rtw_dev *rtwdev) { struct rtw_dm_info *dm_info = &rtwdev->dm_info; @@ -770,7 +763,6 @@ const struct rtw8723x_common rtw8723x_common = { .cfg_ldo25 = __rtw8723x_cfg_ldo25, .set_tx_power_index = __rtw8723x_set_tx_power_index, .efuse_grant = __rtw8723x_efuse_grant, - .set_ampdu_factor = __rtw8723x_set_ampdu_factor, .false_alarm_statistics = __rtw8723x_false_alarm_statistics, .iqk_backup_regs = __rtw8723x_iqk_backup_regs, .iqk_restore_regs = __rtw8723x_iqk_restore_regs, diff --git a/rtw8723x.h b/rtw8723x.h index 5d756c49..a99af527 100644 --- a/rtw8723x.h +++ b/rtw8723x.h @@ -140,7 +140,6 @@ struct rtw8723x_common { void (*cfg_ldo25)(struct rtw_dev *rtwdev, bool enable); void (*set_tx_power_index)(struct rtw_dev *rtwdev); void (*efuse_grant)(struct rtw_dev *rtwdev, bool on); - void (*set_ampdu_factor)(struct rtw_dev *rtwdev, u8 factor); void (*false_alarm_statistics)(struct rtw_dev *rtwdev); void (*iqk_backup_regs)(struct rtw_dev *rtwdev, struct rtw8723x_iqk_backup_regs *backup); @@ -399,11 +398,6 @@ static inline void rtw8723x_efuse_grant(struct rtw_dev *rtwdev, bool on) rtw8723x_common.efuse_grant(rtwdev, on); } -static inline void rtw8723x_set_ampdu_factor(struct rtw_dev *rtwdev, u8 factor) -{ - rtw8723x_common.set_ampdu_factor(rtwdev, factor); -} - static inline void rtw8723x_false_alarm_statistics(struct rtw_dev *rtwdev) { rtw8723x_common.false_alarm_statistics(rtwdev); diff --git a/rtw8812a.c b/rtw8812a.c index c0b4af96..03b44163 100644 --- a/rtw8812a.c +++ b/rtw8812a.c @@ -78,16 +78,6 @@ static void rtw8812a_cfg_ldo25(struct rtw_dev *rtwdev, bool enable) { } -static void rtw8812a_set_ampdu_factor(struct rtw_dev *rtwdev, u8 factor) -{ - u32 len; - - factor = min_t(u8, factor, IEEE80211_VHT_MAX_AMPDU_128K); - len = BIT(31) | ((8192 << factor) - 1); - - rtw_write32(rtwdev, REG_AMPDU_MAX_LENGTH, len); -} - static void rtw8812a_do_lck(struct rtw_dev *rtwdev) { u32 cont_tx, lc_cal, i; @@ -935,7 +925,7 @@ static const struct rtw_chip_ops rtw8812a_ops = { .set_tx_power_index = rtw88xxa_set_tx_power_index, .cfg_ldo25 = rtw8812a_cfg_ldo25, .efuse_grant = rtw88xxa_efuse_grant, - .set_ampdu_factor = rtw8812a_set_ampdu_factor, + .set_ampdu_factor = NULL, .false_alarm_statistics = rtw88xxa_false_alarm_statistics, .phy_calibration = rtw8812a_phy_calibration, .cck_pd_set = rtw88xxa_phy_cck_pd_set, diff --git a/rtw8814a.c b/rtw8814a.c index 8046bf06..4a1f850d 100644 --- a/rtw8814a.c +++ b/rtw8814a.c @@ -1332,6 +1332,9 @@ static void rtw8814a_cfg_ldo25(struct rtw_dev *rtwdev, bool enable) { } +/* Without this RTL8814A sends too many frames and (some?) 11n AP + * can't handle it, resulting in low TX speed. Other chips seem fine. + */ static void rtw8814a_set_ampdu_factor(struct rtw_dev *rtwdev, u8 factor) { factor = min_t(u8, factor, IEEE80211_VHT_MAX_AMPDU_256K); @@ -2197,7 +2200,7 @@ const struct rtw_chip_info rtw8814a_hw_spec = { .rx_ldpc = true, .max_power_index = 0x3f, .ampdu_density = IEEE80211_HT_MPDU_DENSITY_2, - .amsdu_in_ampdu = false, + .amsdu_in_ampdu = false, /* RX speed is better without AMSDU */ .usb_tx_agg_desc_num = 3, .hw_feature_report = false, .c2h_ra_report_size = 6, diff --git a/rtw8821a.c b/rtw8821a.c index 89b2bd13..1d02ea40 100644 --- a/rtw8821a.c +++ b/rtw8821a.c @@ -49,16 +49,6 @@ static void rtw8821a_cfg_ldo25(struct rtw_dev *rtwdev, bool enable) { } -static void rtw8821a_set_ampdu_factor(struct rtw_dev *rtwdev, u8 factor) -{ - u32 len; - - factor = min_t(u8, factor, IEEE80211_VHT_MAX_AMPDU_64K); - len = BIT(31) | ((8192 << factor) - 1); - - rtw_write32(rtwdev, REG_AMPDU_MAX_LENGTH, len); -} - #define CAL_NUM_8821A 3 #define MACBB_REG_NUM_8821A 8 #define AFE_REG_NUM_8821A 4 @@ -881,7 +871,7 @@ static const struct rtw_chip_ops rtw8821a_ops = { .set_tx_power_index = rtw88xxa_set_tx_power_index, .cfg_ldo25 = rtw8821a_cfg_ldo25, .efuse_grant = rtw88xxa_efuse_grant, - .set_ampdu_factor = rtw8821a_set_ampdu_factor, + .set_ampdu_factor = NULL, .false_alarm_statistics = rtw88xxa_false_alarm_statistics, .phy_calibration = rtw8821a_phy_calibration, .cck_pd_set = rtw88xxa_phy_cck_pd_set, diff --git a/rtw8821c.c b/rtw8821c.c index d0bd6e70..0ad4241f 100644 --- a/rtw8821c.c +++ b/rtw8821c.c @@ -720,11 +720,6 @@ static void rtw8821c_set_tx_power_index(struct rtw_dev *rtwdev) } } -static void rtw8821c_set_ampdu_factor(struct rtw_dev *rtwdev, u8 factor) -{ - rtw_write32(rtwdev, REG_AMPDU_MAX_LENGTH, (8192 << factor) - 1); -} - static void rtw8821c_false_alarm_statistics(struct rtw_dev *rtwdev) { struct rtw_dm_info *dm_info = &rtwdev->dm_info; @@ -1674,7 +1669,7 @@ static const struct rtw_chip_ops rtw8821c_ops = { .set_antenna = NULL, .set_tx_power_index = rtw8821c_set_tx_power_index, .cfg_ldo25 = rtw8821c_cfg_ldo25, - .set_ampdu_factor = rtw8821c_set_ampdu_factor, + .set_ampdu_factor = NULL, .false_alarm_statistics = rtw8821c_false_alarm_statistics, .phy_calibration = rtw8821c_phy_calibration, .cck_pd_set = rtw8821c_phy_cck_pd_set, diff --git a/rtw8822b.c b/rtw8822b.c index b72f622e..9c31c859 100644 --- a/rtw8822b.c +++ b/rtw8822b.c @@ -1018,11 +1018,6 @@ static void rtw8822b_cfg_ldo25(struct rtw_dev *rtwdev, bool enable) rtw_write8(rtwdev, REG_LDO_EFUSE_CTRL + 3, ldo_pwr); } -static void rtw8822b_set_ampdu_factor(struct rtw_dev *rtwdev, u8 factor) -{ - rtw_write32(rtwdev, REG_AMPDU_MAX_LENGTH, (8192 << factor) - 1); -} - static void rtw8822b_false_alarm_statistics(struct rtw_dev *rtwdev) { struct rtw_dm_info *dm_info = &rtwdev->dm_info; @@ -2163,7 +2158,7 @@ static const struct rtw_chip_ops rtw8822b_ops = { .set_tx_power_index = rtw8822b_set_tx_power_index, .set_antenna = rtw8822b_set_antenna, .cfg_ldo25 = rtw8822b_cfg_ldo25, - .set_ampdu_factor = rtw8822b_set_ampdu_factor, + .set_ampdu_factor = NULL, .false_alarm_statistics = rtw8822b_false_alarm_statistics, .phy_calibration = rtw8822b_phy_calibration, .pwr_track = rtw8822b_pwr_track, diff --git a/rtw8822c.c b/rtw8822c.c index cef20a70..f813ce10 100644 --- a/rtw8822c.c +++ b/rtw8822c.c @@ -2809,11 +2809,6 @@ static void rtw8822c_cfg_ldo25(struct rtw_dev *rtwdev, bool enable) rtw_write8(rtwdev, REG_ANAPARLDO_POW_MAC, ldo_pwr); } -static void rtw8822c_set_ampdu_factor(struct rtw_dev *rtwdev, u8 factor) -{ - rtw_write32(rtwdev, REG_AMPDU_MAX_LENGTH, (8192 << factor) - 1); -} - static void rtw8822c_false_alarm_statistics(struct rtw_dev *rtwdev) { struct rtw_dm_info *dm_info = &rtwdev->dm_info; @@ -4974,7 +4969,7 @@ static const struct rtw_chip_ops rtw8822c_ops = { .set_tx_power_index = rtw8822c_set_tx_power_index, .set_antenna = rtw8822c_set_antenna, .cfg_ldo25 = rtw8822c_cfg_ldo25, - .set_ampdu_factor = rtw8822c_set_ampdu_factor, + .set_ampdu_factor = NULL, .false_alarm_statistics = rtw8822c_false_alarm_statistics, .dpk_track = rtw8822c_dpk_track, .phy_calibration = rtw8822c_phy_calibration, From cdd78f90ea4ca74463674296c580149e9c547d3d Mon Sep 17 00:00:00 2001 From: Bitterblue Smith Date: Thu, 26 Jun 2025 22:14:23 +0300 Subject: [PATCH 190/193] Sync SDIO RX aggregation stuff To match the version that went into the kernel. Signed-off-by: Bitterblue Smith --- sdio.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/sdio.c b/sdio.c index 0d76b2d2..bc8fc165 100644 --- a/sdio.c +++ b/sdio.c @@ -680,6 +680,8 @@ static void rtw_sdio_enable_rx_aggregation(struct rtw_dev *rtwdev) switch (rtwdev->chip->id) { case RTW_CHIP_TYPE_8703B: + case RTW_CHIP_TYPE_8821A: + case RTW_CHIP_TYPE_8812A: size = 0x6; timeout = 0x6; break; From b89af8cd40d9528b0cdb9a6251efe49d8a69bfc6 Mon Sep 17 00:00:00 2001 From: Bitterblue Smith Date: Thu, 26 Jun 2025 22:19:38 +0300 Subject: [PATCH 191/193] wifi: rtw88: sdio: Remove redundant 'flush_workqueue()' calls 'destroy_workqueue()' already drains the queue before destroying it, so there is no need to flush it explicitly. Remove the redundant 'flush_workqueue()' calls. This was generated with coccinelle: @@ expression E; @@ - flush_workqueue(E); destroy_workqueue(E); Signed-off-by: Chen Ni Signed-off-by: Ping-Ke Shih Link: https://patch.msgid.link/20250324075910.407999-1-nichen@iscas.ac.cn --- sdio.c | 1 - 1 file changed, 1 deletion(-) diff --git a/sdio.c b/sdio.c index bc8fc165..8635dc94 100644 --- a/sdio.c +++ b/sdio.c @@ -1309,7 +1309,6 @@ static void rtw_sdio_deinit_tx(struct rtw_dev *rtwdev) skb_queue_purge(&rtwsdio->tx_queue[i]); #endif - flush_workqueue(rtwsdio->txwq); destroy_workqueue(rtwsdio->txwq); kfree(rtwsdio->tx_handler_data); From fa96fd4c014fa528d1fa50318e97aa71bf4f473c Mon Sep 17 00:00:00 2001 From: Bitterblue Smith Date: Sun, 13 Jul 2025 19:20:30 +0300 Subject: [PATCH 192/193] wifi: rtw88: Fix macid assigned to TDLS station When working in station mode, a TDLS peer is assigned macid 0, even though 0 was already assigned to the AP. This causes the connection with the AP to stop working after the TDLS connection is torn down. Assign the next available macid to TDLS peers, same as client stations in AP mode. https://github.com/lwfinger/rtw88/issues/198#issuecomment-3067033013 Signed-off-by: Bitterblue Smith --- main.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/main.c b/main.c index 8a8bef5b..dcd04c02 100644 --- a/main.c +++ b/main.c @@ -355,7 +355,7 @@ int rtw_sta_add(struct rtw_dev *rtwdev, struct ieee80211_sta *sta, struct rtw_vif *rtwvif = (struct rtw_vif *)vif->drv_priv; int i; - if (vif->type == NL80211_IFTYPE_STATION) { + if (vif->type == NL80211_IFTYPE_STATION && !sta->tdls) { si->mac_id = rtwvif->mac_id; } else { si->mac_id = rtw_acquire_macid(rtwdev); @@ -392,7 +392,7 @@ void rtw_sta_remove(struct rtw_dev *rtwdev, struct ieee80211_sta *sta, cancel_work_sync(&si->rc_work); - if (vif->type != NL80211_IFTYPE_STATION) + if (vif->type != NL80211_IFTYPE_STATION || sta->tdls) rtw_release_macid(rtwdev, si->mac_id); if (fw_exist) rtw_fw_media_status_report(rtwdev, si->mac_id, false); From 549f33c361a2569733ba73e47d7e3986ca7e55d6 Mon Sep 17 00:00:00 2001 From: Bitterblue Smith Date: Tue, 29 Jul 2025 18:35:37 +0300 Subject: [PATCH 193/193] wifi: rtw88: Lock rtwdev->mutex before setting the LED Some users report that the LED blinking breaks AP mode somehow. Most likely the LED code and the dynamic mechanism are trying to access the hardware registers at the same time. Lock rtwdev->mutex before setting the LED and unlock it after to prevent this. Link: https://github.com/lwfinger/rtw88/issues/305 Signed-off-by: Bitterblue Smith --- led.c | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/led.c b/led.c index 25aa6cba..7f9ace35 100644 --- a/led.c +++ b/led.c @@ -6,13 +6,23 @@ #include "debug.h" #include "led.h" -static int rtw_led_set_blocking(struct led_classdev *led, - enum led_brightness brightness) +static void rtw_led_set(struct led_classdev *led, + enum led_brightness brightness) { struct rtw_dev *rtwdev = container_of(led, struct rtw_dev, led_cdev); + mutex_lock(&rtwdev->mutex); + rtwdev->chip->ops->led_set(led, brightness); + mutex_unlock(&rtwdev->mutex); +} + +static int rtw_led_set_blocking(struct led_classdev *led, + enum led_brightness brightness) +{ + rtw_led_set(led, brightness); + return 0; } @@ -37,7 +47,7 @@ void rtw_led_init(struct rtw_dev *rtwdev) return; if (rtw_hci_type(rtwdev) == RTW_HCI_TYPE_PCIE) - led->brightness_set = rtwdev->chip->ops->led_set; + led->brightness_set = rtw_led_set; else led->brightness_set_blocking = rtw_led_set_blocking;