From 3b71b340ffe8479eda3edd39ff5575467cb608dd Mon Sep 17 00:00:00 2001 From: Rudi Heitbaum Date: Sun, 13 Oct 2024 11:38:10 +0000 Subject: [PATCH 1/5] linux: wifi: rtw88: Add support for RTL8821AU and RTL8812AU https://patchwork.kernel.org/project/linux-wireless/cover/d2870a44-9b91-4090-9a25-873eb62997f5@gmail.com/ --- packages/linux/package.mk | 6 +- ...8-Shared-module-for-rtw8723x-devices.patch | 2324 +++ ...tw88-Debug-output-for-rtw8723x-EFUSE.patch | 231 + ...rtw88-Add-definitions-for-8703b-chip.patch | 106 + .../0011-6.10-wifi-rtw88-Add-rtw8703b.c.patch | 2132 +++ ...usb-Further-limit-the-TX-aggregation.patch | 164 + ...tw88-usb-Simplify-rtw_usb_write_data.patch | 51 + ...upport-USB-3-with-RTL8822CU-RTL8822B.patch | 303 + ...w88-8703b-Fix-reported-RX-band-width.patch | 36 + ...-Parse-channel-from-IE-to-correct-in.patch | 168 + ...nit-RX-burst-length-according-to-USB.patch | 81 + ...pdate-the-RX-stats-after-every-frame.patch | 36 + ...ifi-rtw88-usb-Support-RX-aggregation.patch | 123 + ...e-USB-RX-aggregation-for-8822c-8822b.patch | 182 + ...tweak-CCK-TX-filter-setting-for-SRRC.patch | 156 + ...fine-power-parameters-for-RFE-type-5.patch | 52 + ...dd-to-check-if-debug-mask-is-enabled.patch | 46 + ...-debug-information-in-abnormal-state.patch | 234 + ...w88-Constify-some-arrays-and-structs.patch | 392 + ...-the-RX-descriptor-with-a-single-fun.patch | 582 + ...-support-for-RTL8821AU-and-RTL8812AU.patch | 14203 ++++++++++++++++ 21 files changed, 21605 insertions(+), 3 deletions(-) create mode 100644 packages/linux/patches/rtlwifi/6.10/0008-6.10-wifi-rtw88-Shared-module-for-rtw8723x-devices.patch create mode 100644 packages/linux/patches/rtlwifi/6.10/0009-6.10-wifi-rtw88-Debug-output-for-rtw8723x-EFUSE.patch create mode 100644 packages/linux/patches/rtlwifi/6.10/0010-6.10-wifi-rtw88-Add-definitions-for-8703b-chip.patch create mode 100644 packages/linux/patches/rtlwifi/6.10/0011-6.10-wifi-rtw88-Add-rtw8703b.c.patch create mode 100644 packages/linux/patches/rtlwifi/6.11/0013-6.11-wifi-rtw88-usb-Further-limit-the-TX-aggregation.patch create mode 100644 packages/linux/patches/rtlwifi/6.11/0014-6.11-wifi-rtw88-usb-Simplify-rtw_usb_write_data.patch create mode 100644 packages/linux/patches/rtlwifi/6.12/0001-6.12-wifi-rtw88-usb-Support-USB-3-with-RTL8822CU-RTL8822B.patch create mode 100644 packages/linux/patches/rtlwifi/6.12/0002-6.12-wifi-rtw88-8703b-Fix-reported-RX-band-width.patch create mode 100644 packages/linux/patches/rtlwifi/6.12/0003-6.12-wifi-rtw88-8822c-Parse-channel-from-IE-to-correct-in.patch create mode 100644 packages/linux/patches/rtlwifi/6.12/0004-6.12-wifi-rtw88-usb-Init-RX-burst-length-according-to-USB.patch create mode 100644 packages/linux/patches/rtlwifi/6.12/0005-6.12-wifi-rtw88-usb-Update-the-RX-stats-after-every-frame.patch create mode 100644 packages/linux/patches/rtlwifi/6.12/0006-6.12-wifi-rtw88-usb-Support-RX-aggregation.patch create mode 100644 packages/linux/patches/rtlwifi/6.12/0007-6.12-wifi-rtw88-Enable-USB-RX-aggregation-for-8822c-8822b.patch create mode 100644 packages/linux/patches/rtlwifi/6.9/0008-wifi-rtw88-8821c-tweak-CCK-TX-filter-setting-for-SRRC.patch create mode 100644 packages/linux/patches/rtlwifi/6.9/0009-wifi-rtw88-8822ce-refine-power-parameters-for-RFE-type-5.patch create mode 100644 packages/linux/patches/rtlwifi/6.9/0010-wifi-rtw88-debug-add-to-check-if-debug-mask-is-enabled.patch create mode 100644 packages/linux/patches/rtlwifi/6.9/0011-wifi-rtw88-dump-firmware-debug-information-in-abnormal-state.patch create mode 100644 packages/linux/patches/rtlwifi/after-6.12/0001-wifi-rtw88-Constify-some-arrays-and-structs.patch create mode 100644 packages/linux/patches/rtlwifi/after-6.12/0002-wifi-rtw88-Parse-the-RX-descriptor-with-a-single-fun.patch create mode 100644 packages/linux/patches/rtlwifi/after-6.12/0003-wifi-rtw88-Add-support-for-RTL8821AU-and-RTL8812AU.patch diff --git a/packages/linux/package.mk b/packages/linux/package.mk index 7f26d11cb6..4939c44209 100644 --- a/packages/linux/package.mk +++ b/packages/linux/package.mk @@ -20,20 +20,20 @@ case "${LINUX}" in PKG_SHA256="" PKG_URL="https://github.com/torvalds/linux/archive/${PKG_VERSION}.tar.gz" PKG_SOURCE_NAME="linux-${LINUX}-${PKG_VERSION}.tar.gz" - PKG_PATCH_DIRS="default" + PKG_PATCH_DIRS="default rtlwifi/6.12 rtlwifi/after-6.12" ;; raspberrypi) PKG_VERSION="3edaa3875fbeb0b2effd77c62baabf2933efc6ef" # 6.6.54 PKG_SHA256="97a9055a9f76d501b93948a6956e28eafd26d69ec75327326e54b220b504fd37" PKG_URL="https://github.com/raspberrypi/linux/archive/${PKG_VERSION}.tar.gz" PKG_SOURCE_NAME="linux-${LINUX}-${PKG_VERSION}.tar.gz" - PKG_PATCH_DIRS="raspberrypi rtlwifi/6.9 rtlwifi/6.10 rtlwifi/6.11" + PKG_PATCH_DIRS="raspberrypi rtlwifi/6.9 rtlwifi/6.10 rtlwifi/6.11 rtlwifi/6.12 rtlwifi/after-6.12" ;; *) PKG_VERSION="6.11" PKG_SHA256="55d2c6c025ebc27810c748d66325dd5bc601e8d32f8581d9e77673529bdacb2e" PKG_URL="https://www.kernel.org/pub/linux/kernel/v${PKG_VERSION/.*/}.x/${PKG_NAME}-${PKG_VERSION}.tar.xz" - PKG_PATCH_DIRS="default" + PKG_PATCH_DIRS="default rtlwifi/6.12 rtlwifi/after-6.12" ;; esac diff --git a/packages/linux/patches/rtlwifi/6.10/0008-6.10-wifi-rtw88-Shared-module-for-rtw8723x-devices.patch b/packages/linux/patches/rtlwifi/6.10/0008-6.10-wifi-rtw88-Shared-module-for-rtw8723x-devices.patch new file mode 100644 index 0000000000..f3b0f9d7ec --- /dev/null +++ b/packages/linux/patches/rtlwifi/6.10/0008-6.10-wifi-rtw88-Shared-module-for-rtw8723x-devices.patch @@ -0,0 +1,2324 @@ +From ff88b74882669e8b1931730b2401dbc2bece1355 Mon Sep 17 00:00:00 2001 +From: Fiona Klute +Date: Mon, 11 Mar 2024 11:37:05 +0100 +Subject: [PATCH] wifi: rtw88: Shared module for rtw8723x devices + +The already supported 8723d chip is very similar to 8703b/8723cs, +split code that can be shared into a new module. The spec definition +tables are combined into a struct so we only need one EXPORT_SYMBOL +for them all. + +Acked-by: Ping-Ke Shih +Tested-by: Pavel Machek +Signed-off-by: Fiona Klute +Signed-off-by: Kalle Valo +Link: https://msgid.link/20240311103735.615541-2-fiona.klute@gmx.de +--- + drivers/net/wireless/realtek/rtw88/Kconfig | 4 + + drivers/net/wireless/realtek/rtw88/Makefile | 3 + + drivers/net/wireless/realtek/rtw88/rtw8723d.c | 673 ++---------------- + drivers/net/wireless/realtek/rtw88/rtw8723d.h | 269 +------ + drivers/net/wireless/realtek/rtw88/rtw8723x.c | 562 +++++++++++++++ + drivers/net/wireless/realtek/rtw88/rtw8723x.h | 496 +++++++++++++ + 6 files changed, 1107 insertions(+), 900 deletions(-) + create mode 100644 drivers/net/wireless/realtek/rtw88/rtw8723x.c + create mode 100644 drivers/net/wireless/realtek/rtw88/rtw8723x.h + +diff --git a/drivers/net/wireless/realtek/rtw88/Kconfig b/drivers/net/wireless/realtek/rtw88/Kconfig +index cffad1c012499e..07b5b2f6eef704 100644 +--- a/drivers/net/wireless/realtek/rtw88/Kconfig ++++ b/drivers/net/wireless/realtek/rtw88/Kconfig +@@ -28,8 +28,12 @@ config RTW88_8822B + config RTW88_8822C + tristate + ++config RTW88_8723X ++ tristate ++ + config RTW88_8723D + tristate ++ select RTW88_8723X + + config RTW88_8821C + tristate +diff --git a/drivers/net/wireless/realtek/rtw88/Makefile b/drivers/net/wireless/realtek/rtw88/Makefile +index fd212c09d88a9e..22516c984608f3 100644 +--- a/drivers/net/wireless/realtek/rtw88/Makefile ++++ b/drivers/net/wireless/realtek/rtw88/Makefile +@@ -44,6 +44,9 @@ rtw88_8822cs-objs := rtw8822cs.o + obj-$(CONFIG_RTW88_8822CU) += rtw88_8822cu.o + rtw88_8822cu-objs := rtw8822cu.o + ++obj-$(CONFIG_RTW88_8723X) += rtw88_8723x.o ++rtw88_8723x-objs := rtw8723x.o ++ + obj-$(CONFIG_RTW88_8723D) += rtw88_8723d.o + rtw88_8723d-objs := rtw8723d.o rtw8723d_table.o + +diff --git a/drivers/net/wireless/realtek/rtw88/rtw8723d.c b/drivers/net/wireless/realtek/rtw88/rtw8723d.c +index c575476a002079..f8df4c84d39f73 100644 +--- a/drivers/net/wireless/realtek/rtw88/rtw8723d.c ++++ b/drivers/net/wireless/realtek/rtw88/rtw8723d.c +@@ -9,36 +9,13 @@ + #include "tx.h" + #include "rx.h" + #include "phy.h" ++#include "rtw8723x.h" + #include "rtw8723d.h" + #include "rtw8723d_table.h" + #include "mac.h" + #include "reg.h" + #include "debug.h" + +-static const struct rtw_hw_reg rtw8723d_txagc[] = { +- [DESC_RATE1M] = { .addr = 0xe08, .mask = 0x0000ff00 }, +- [DESC_RATE2M] = { .addr = 0x86c, .mask = 0x0000ff00 }, +- [DESC_RATE5_5M] = { .addr = 0x86c, .mask = 0x00ff0000 }, +- [DESC_RATE11M] = { .addr = 0x86c, .mask = 0xff000000 }, +- [DESC_RATE6M] = { .addr = 0xe00, .mask = 0x000000ff }, +- [DESC_RATE9M] = { .addr = 0xe00, .mask = 0x0000ff00 }, +- [DESC_RATE12M] = { .addr = 0xe00, .mask = 0x00ff0000 }, +- [DESC_RATE18M] = { .addr = 0xe00, .mask = 0xff000000 }, +- [DESC_RATE24M] = { .addr = 0xe04, .mask = 0x000000ff }, +- [DESC_RATE36M] = { .addr = 0xe04, .mask = 0x0000ff00 }, +- [DESC_RATE48M] = { .addr = 0xe04, .mask = 0x00ff0000 }, +- [DESC_RATE54M] = { .addr = 0xe04, .mask = 0xff000000 }, +- [DESC_RATEMCS0] = { .addr = 0xe10, .mask = 0x000000ff }, +- [DESC_RATEMCS1] = { .addr = 0xe10, .mask = 0x0000ff00 }, +- [DESC_RATEMCS2] = { .addr = 0xe10, .mask = 0x00ff0000 }, +- [DESC_RATEMCS3] = { .addr = 0xe10, .mask = 0xff000000 }, +- [DESC_RATEMCS4] = { .addr = 0xe14, .mask = 0x000000ff }, +- [DESC_RATEMCS5] = { .addr = 0xe14, .mask = 0x0000ff00 }, +- [DESC_RATEMCS6] = { .addr = 0xe14, .mask = 0x00ff0000 }, +- [DESC_RATEMCS7] = { .addr = 0xe14, .mask = 0xff000000 }, +-}; +- +-#define WLAN_TXQ_RPT_EN 0x1F + #define WLAN_SLOT_TIME 0x09 + #define WLAN_RL_VAL 0x3030 + #define WLAN_BAR_VAL 0x0201ffff +@@ -65,34 +42,6 @@ static const struct rtw_hw_reg rtw8723d_txagc[] = { + #define WLAN_LTR_CTRL1 0xCB004010 + #define WLAN_LTR_CTRL2 0x01233425 + +-static void rtw8723d_lck(struct rtw_dev *rtwdev) +-{ +- u32 lc_cal; +- u8 val_ctx, rf_val; +- int ret; +- +- val_ctx = rtw_read8(rtwdev, REG_CTX); +- if ((val_ctx & BIT_MASK_CTX_TYPE) != 0) +- rtw_write8(rtwdev, REG_CTX, val_ctx & ~BIT_MASK_CTX_TYPE); +- else +- rtw_write8(rtwdev, REG_TXPAUSE, 0xFF); +- lc_cal = rtw_read_rf(rtwdev, RF_PATH_A, RF_CFGCH, RFREG_MASK); +- +- rtw_write_rf(rtwdev, RF_PATH_A, RF_CFGCH, RFREG_MASK, lc_cal | BIT_LCK); +- +- ret = read_poll_timeout(rtw_read_rf, rf_val, rf_val != 0x1, +- 10000, 1000000, false, +- rtwdev, RF_PATH_A, RF_CFGCH, BIT_LCK); +- if (ret) +- rtw_warn(rtwdev, "failed to poll LCK status bit\n"); +- +- rtw_write_rf(rtwdev, RF_PATH_A, RF_CFGCH, RFREG_MASK, lc_cal); +- if ((val_ctx & BIT_MASK_CTX_TYPE) != 0) +- rtw_write8(rtwdev, REG_CTX, val_ctx); +- else +- rtw_write8(rtwdev, REG_TXPAUSE, 0x00); +-} +- + static const u32 rtw8723d_ofdm_swing_table[] = { + 0x0b40002d, 0x0c000030, 0x0cc00033, 0x0d800036, 0x0e400039, 0x0f00003c, + 0x10000040, 0x11000044, 0x12000048, 0x1300004c, 0x14400051, 0x15800056, +@@ -196,7 +145,7 @@ static void rtw8723d_phy_set_param(struct rtw_dev *rtwdev) + + rtw_write16_set(rtwdev, REG_TXDMA_OFFSET_CHK, BIT_DROP_DATA_EN); + +- rtw8723d_lck(rtwdev); ++ rtw8723x_lck(rtwdev); + + rtw_write32_mask(rtwdev, REG_OFDM0_XAAGC1, MASKBYTE0, 0x50); + rtw_write32_mask(rtwdev, REG_OFDM0_XAAGC1, MASKBYTE0, 0x20); +@@ -204,67 +153,6 @@ static void rtw8723d_phy_set_param(struct rtw_dev *rtwdev) + rtw8723d_pwrtrack_init(rtwdev); + } + +-static void rtw8723de_efuse_parsing(struct rtw_efuse *efuse, +- struct rtw8723d_efuse *map) +-{ +- ether_addr_copy(efuse->addr, map->e.mac_addr); +-} +- +-static void rtw8723du_efuse_parsing(struct rtw_efuse *efuse, +- struct rtw8723d_efuse *map) +-{ +- ether_addr_copy(efuse->addr, map->u.mac_addr); +-} +- +-static void rtw8723ds_efuse_parsing(struct rtw_efuse *efuse, +- struct rtw8723d_efuse *map) +-{ +- ether_addr_copy(efuse->addr, map->s.mac_addr); +-} +- +-static int rtw8723d_read_efuse(struct rtw_dev *rtwdev, u8 *log_map) +-{ +- struct rtw_efuse *efuse = &rtwdev->efuse; +- struct rtw8723d_efuse *map; +- int i; +- +- map = (struct rtw8723d_efuse *)log_map; +- +- efuse->rfe_option = 0; +- efuse->rf_board_option = map->rf_board_option; +- efuse->crystal_cap = map->xtal_k; +- efuse->pa_type_2g = map->pa_type; +- efuse->lna_type_2g = map->lna_type_2g[0]; +- 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_k = map->thermal_meter; +- efuse->afe = map->afe; +- +- 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_PCIE: +- rtw8723de_efuse_parsing(efuse, map); +- break; +- case RTW_HCI_TYPE_USB: +- rtw8723du_efuse_parsing(efuse, map); +- break; +- case RTW_HCI_TYPE_SDIO: +- rtw8723ds_efuse_parsing(efuse, map); +- break; +- default: +- /* unsupported now */ +- return -ENOTSUPP; +- } +- +- return 0; +-} +- + static void query_phy_status_page0(struct rtw_dev *rtwdev, u8 *phy_status, + struct rtw_rx_pkt_stat *pkt_stat) + { +@@ -540,297 +428,11 @@ static void rtw8723d_set_channel(struct rtw_dev *rtwdev, u8 channel, u8 bw, + rtw8723d_set_channel_bb(rtwdev, channel, bw, primary_chan_idx); + } + +-#define BIT_CFENDFORM BIT(9) +-#define BIT_WMAC_TCR_ERR0 BIT(12) +-#define BIT_WMAC_TCR_ERR1 BIT(13) +-#define BIT_TCR_CFG (BIT_CFENDFORM | BIT_WMAC_TCR_ERR0 | \ +- BIT_WMAC_TCR_ERR1) +-#define WLAN_RX_FILTER0 0xFFFF +-#define WLAN_RX_FILTER1 0x400 +-#define WLAN_RX_FILTER2 0xFFFF +-#define WLAN_RCR_CFG 0x700060CE +- +-static int rtw8723d_mac_init(struct rtw_dev *rtwdev) +-{ +- rtw_write8(rtwdev, REG_FWHW_TXQ_CTRL + 1, WLAN_TXQ_RPT_EN); +- rtw_write32(rtwdev, REG_TCR, BIT_TCR_CFG); +- +- rtw_write16(rtwdev, REG_RXFLTMAP0, WLAN_RX_FILTER0); +- rtw_write16(rtwdev, REG_RXFLTMAP1, WLAN_RX_FILTER1); +- rtw_write16(rtwdev, REG_RXFLTMAP2, WLAN_RX_FILTER2); +- rtw_write32(rtwdev, REG_RCR, WLAN_RCR_CFG); +- +- rtw_write32(rtwdev, REG_INT_MIG, 0); +- rtw_write32(rtwdev, REG_MCUTST_1, 0x0); +- +- rtw_write8(rtwdev, REG_MISC_CTRL, BIT_DIS_SECOND_CCA); +- rtw_write8(rtwdev, REG_2ND_CCA_CTRL, 0); +- +- return 0; +-} +- + static void rtw8723d_shutdown(struct rtw_dev *rtwdev) + { + rtw_write16_set(rtwdev, REG_HCI_OPT_CTRL, BIT_USB_SUS_DIS); + } + +-static void rtw8723d_cfg_ldo25(struct rtw_dev *rtwdev, bool enable) +-{ +- u8 ldo_pwr; +- +- ldo_pwr = rtw_read8(rtwdev, REG_LDO_EFUSE_CTRL + 3); +- if (enable) { +- ldo_pwr &= ~BIT_MASK_LDO25_VOLTAGE; +- ldo_pwr |= (BIT_LDO25_VOLTAGE_V25 << 4) | BIT_LDO25_EN; +- } else { +- ldo_pwr &= ~BIT_LDO25_EN; +- } +- rtw_write8(rtwdev, REG_LDO_EFUSE_CTRL + 3, ldo_pwr); +-} +- +-static void +-rtw8723d_set_tx_power_index_by_rate(struct rtw_dev *rtwdev, u8 path, u8 rs) +-{ +- struct rtw_hal *hal = &rtwdev->hal; +- const struct rtw_hw_reg *txagc; +- 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]; +- +- if (rate >= ARRAY_SIZE(rtw8723d_txagc)) { +- rtw_warn(rtwdev, "rate 0x%x isn't supported\n", rate); +- continue; +- } +- txagc = &rtw8723d_txagc[rate]; +- if (!txagc->addr) { +- rtw_warn(rtwdev, "rate 0x%x isn't defined\n", rate); +- continue; +- } +- +- rtw_write32_mask(rtwdev, txagc->addr, txagc->mask, pwr_index); +- } +-} +- +-static void rtw8723d_set_tx_power_index(struct rtw_dev *rtwdev) +-{ +- struct rtw_hal *hal = &rtwdev->hal; +- int rs, path; +- +- for (path = 0; path < hal->rf_path_num; path++) { +- for (rs = 0; rs <= RTW_RATE_SECTION_HT_1S; rs++) +- rtw8723d_set_tx_power_index_by_rate(rtwdev, path, rs); +- } +-} +- +-static void rtw8723d_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 rtw8723d_false_alarm_statistics(struct rtw_dev *rtwdev) +-{ +- struct rtw_dm_info *dm_info = &rtwdev->dm_info; +- u32 cck_fa_cnt; +- u32 ofdm_fa_cnt; +- u32 crc32_cnt; +- u32 val32; +- +- /* hold counter */ +- rtw_write32_mask(rtwdev, REG_OFDM_FA_HOLDC_11N, BIT_MASK_OFDM_FA_KEEP, 1); +- rtw_write32_mask(rtwdev, REG_OFDM_FA_RSTD_11N, BIT_MASK_OFDM_FA_KEEP1, 1); +- rtw_write32_mask(rtwdev, REG_CCK_FA_RST_11N, BIT_MASK_CCK_CNT_KEEP, 1); +- rtw_write32_mask(rtwdev, REG_CCK_FA_RST_11N, BIT_MASK_CCK_FA_KEEP, 1); +- +- cck_fa_cnt = rtw_read32_mask(rtwdev, REG_CCK_FA_LSB_11N, MASKBYTE0); +- cck_fa_cnt += rtw_read32_mask(rtwdev, REG_CCK_FA_MSB_11N, MASKBYTE3) << 8; +- +- val32 = rtw_read32(rtwdev, REG_OFDM_FA_TYPE1_11N); +- ofdm_fa_cnt = u32_get_bits(val32, BIT_MASK_OFDM_FF_CNT); +- ofdm_fa_cnt += u32_get_bits(val32, BIT_MASK_OFDM_SF_CNT); +- val32 = rtw_read32(rtwdev, REG_OFDM_FA_TYPE2_11N); +- dm_info->ofdm_cca_cnt = u32_get_bits(val32, BIT_MASK_OFDM_CCA_CNT); +- ofdm_fa_cnt += u32_get_bits(val32, BIT_MASK_OFDM_PF_CNT); +- val32 = rtw_read32(rtwdev, REG_OFDM_FA_TYPE3_11N); +- ofdm_fa_cnt += u32_get_bits(val32, BIT_MASK_OFDM_RI_CNT); +- ofdm_fa_cnt += u32_get_bits(val32, BIT_MASK_OFDM_CRC_CNT); +- val32 = rtw_read32(rtwdev, REG_OFDM_FA_TYPE4_11N); +- ofdm_fa_cnt += u32_get_bits(val32, BIT_MASK_OFDM_MNS_CNT); +- +- dm_info->cck_fa_cnt = cck_fa_cnt; +- dm_info->ofdm_fa_cnt = ofdm_fa_cnt; +- dm_info->total_fa_cnt = cck_fa_cnt + ofdm_fa_cnt; +- +- dm_info->cck_err_cnt = rtw_read32(rtwdev, REG_IGI_C_11N); +- dm_info->cck_ok_cnt = rtw_read32(rtwdev, REG_IGI_D_11N); +- crc32_cnt = rtw_read32(rtwdev, REG_OFDM_CRC32_CNT_11N); +- dm_info->ofdm_err_cnt = u32_get_bits(crc32_cnt, BIT_MASK_OFDM_LCRC_ERR); +- dm_info->ofdm_ok_cnt = u32_get_bits(crc32_cnt, BIT_MASK_OFDM_LCRC_OK); +- crc32_cnt = rtw_read32(rtwdev, REG_HT_CRC32_CNT_11N); +- dm_info->ht_err_cnt = u32_get_bits(crc32_cnt, BIT_MASK_HT_CRC_ERR); +- dm_info->ht_ok_cnt = u32_get_bits(crc32_cnt, BIT_MASK_HT_CRC_OK); +- dm_info->vht_err_cnt = 0; +- dm_info->vht_ok_cnt = 0; +- +- val32 = rtw_read32(rtwdev, REG_CCK_CCA_CNT_11N); +- dm_info->cck_cca_cnt = (u32_get_bits(val32, BIT_MASK_CCK_FA_MSB) << 8) | +- u32_get_bits(val32, BIT_MASK_CCK_FA_LSB); +- dm_info->total_cca_cnt = dm_info->cck_cca_cnt + dm_info->ofdm_cca_cnt; +- +- /* reset counter */ +- rtw_write32_mask(rtwdev, REG_OFDM_FA_RSTC_11N, BIT_MASK_OFDM_FA_RST, 1); +- rtw_write32_mask(rtwdev, REG_OFDM_FA_RSTC_11N, BIT_MASK_OFDM_FA_RST, 0); +- rtw_write32_mask(rtwdev, REG_OFDM_FA_RSTD_11N, BIT_MASK_OFDM_FA_RST1, 1); +- rtw_write32_mask(rtwdev, REG_OFDM_FA_RSTD_11N, BIT_MASK_OFDM_FA_RST1, 0); +- rtw_write32_mask(rtwdev, REG_OFDM_FA_HOLDC_11N, BIT_MASK_OFDM_FA_KEEP, 0); +- rtw_write32_mask(rtwdev, REG_OFDM_FA_RSTD_11N, BIT_MASK_OFDM_FA_KEEP1, 0); +- rtw_write32_mask(rtwdev, REG_CCK_FA_RST_11N, BIT_MASK_CCK_CNT_KPEN, 0); +- rtw_write32_mask(rtwdev, REG_CCK_FA_RST_11N, BIT_MASK_CCK_CNT_KPEN, 2); +- rtw_write32_mask(rtwdev, REG_CCK_FA_RST_11N, BIT_MASK_CCK_FA_KPEN, 0); +- rtw_write32_mask(rtwdev, REG_CCK_FA_RST_11N, BIT_MASK_CCK_FA_KPEN, 2); +- rtw_write32_mask(rtwdev, REG_PAGE_F_RST_11N, BIT_MASK_F_RST_ALL, 1); +- rtw_write32_mask(rtwdev, REG_PAGE_F_RST_11N, BIT_MASK_F_RST_ALL, 0); +-} +- +-static const u32 iqk_adda_regs[] = { +- 0x85c, 0xe6c, 0xe70, 0xe74, 0xe78, 0xe7c, 0xe80, 0xe84, 0xe88, 0xe8c, +- 0xed0, 0xed4, 0xed8, 0xedc, 0xee0, 0xeec +-}; +- +-static const u32 iqk_mac8_regs[] = {0x522, 0x550, 0x551}; +-static const u32 iqk_mac32_regs[] = {0x40}; +- +-static const u32 iqk_bb_regs[] = { +- 0xc04, 0xc08, 0x874, 0xb68, 0xb6c, 0x870, 0x860, 0x864, 0xa04 +-}; +- +-#define IQK_ADDA_REG_NUM ARRAY_SIZE(iqk_adda_regs) +-#define IQK_MAC8_REG_NUM ARRAY_SIZE(iqk_mac8_regs) +-#define IQK_MAC32_REG_NUM ARRAY_SIZE(iqk_mac32_regs) +-#define IQK_BB_REG_NUM ARRAY_SIZE(iqk_bb_regs) +- +-struct iqk_backup_regs { +- u32 adda[IQK_ADDA_REG_NUM]; +- u8 mac8[IQK_MAC8_REG_NUM]; +- u32 mac32[IQK_MAC32_REG_NUM]; +- u32 bb[IQK_BB_REG_NUM]; +- +- u32 lte_path; +- u32 lte_gnt; +- +- u32 bb_sel_btg; +- u8 btg_sel; +- +- u8 igia; +- u8 igib; +-}; +- +-static void rtw8723d_iqk_backup_regs(struct rtw_dev *rtwdev, +- struct iqk_backup_regs *backup) +-{ +- int i; +- +- for (i = 0; i < IQK_ADDA_REG_NUM; i++) +- backup->adda[i] = rtw_read32(rtwdev, iqk_adda_regs[i]); +- +- for (i = 0; i < IQK_MAC8_REG_NUM; i++) +- backup->mac8[i] = rtw_read8(rtwdev, iqk_mac8_regs[i]); +- for (i = 0; i < IQK_MAC32_REG_NUM; i++) +- backup->mac32[i] = rtw_read32(rtwdev, iqk_mac32_regs[i]); +- +- for (i = 0; i < IQK_BB_REG_NUM; i++) +- backup->bb[i] = rtw_read32(rtwdev, iqk_bb_regs[i]); +- +- backup->igia = rtw_read32_mask(rtwdev, REG_OFDM0_XAAGC1, MASKBYTE0); +- backup->igib = rtw_read32_mask(rtwdev, REG_OFDM0_XBAGC1, MASKBYTE0); +- +- backup->bb_sel_btg = rtw_read32(rtwdev, REG_BB_SEL_BTG); +-} +- +-static void rtw8723d_iqk_restore_regs(struct rtw_dev *rtwdev, +- const struct iqk_backup_regs *backup) +-{ +- int i; +- +- for (i = 0; i < IQK_ADDA_REG_NUM; i++) +- rtw_write32(rtwdev, iqk_adda_regs[i], backup->adda[i]); +- +- for (i = 0; i < IQK_MAC8_REG_NUM; i++) +- rtw_write8(rtwdev, iqk_mac8_regs[i], backup->mac8[i]); +- for (i = 0; i < IQK_MAC32_REG_NUM; i++) +- rtw_write32(rtwdev, iqk_mac32_regs[i], backup->mac32[i]); +- +- for (i = 0; i < IQK_BB_REG_NUM; i++) +- rtw_write32(rtwdev, iqk_bb_regs[i], backup->bb[i]); +- +- rtw_write32_mask(rtwdev, REG_OFDM0_XAAGC1, MASKBYTE0, 0x50); +- rtw_write32_mask(rtwdev, REG_OFDM0_XAAGC1, MASKBYTE0, backup->igia); +- +- rtw_write32_mask(rtwdev, REG_OFDM0_XBAGC1, MASKBYTE0, 0x50); +- rtw_write32_mask(rtwdev, REG_OFDM0_XBAGC1, MASKBYTE0, backup->igib); +- +- rtw_write32(rtwdev, REG_TXIQK_TONE_A_11N, 0x01008c00); +- rtw_write32(rtwdev, REG_RXIQK_TONE_A_11N, 0x01008c00); +-} +- +-static void rtw8723d_iqk_backup_path_ctrl(struct rtw_dev *rtwdev, +- struct iqk_backup_regs *backup) +-{ +- backup->btg_sel = rtw_read8(rtwdev, REG_BTG_SEL); +- rtw_dbg(rtwdev, RTW_DBG_RFK, "[IQK] original 0x67 = 0x%x\n", +- backup->btg_sel); +-} +- +-static void rtw8723d_iqk_config_path_ctrl(struct rtw_dev *rtwdev) +-{ +- rtw_write32_mask(rtwdev, REG_PAD_CTRL1, BIT_BT_BTG_SEL, 0x1); +- rtw_dbg(rtwdev, RTW_DBG_RFK, "[IQK] set 0x67 = 0x%x\n", +- rtw_read32_mask(rtwdev, REG_PAD_CTRL1, MASKBYTE3)); +-} +- +-static void rtw8723d_iqk_restore_path_ctrl(struct rtw_dev *rtwdev, +- const struct iqk_backup_regs *backup) +-{ +- rtw_write8(rtwdev, REG_BTG_SEL, backup->btg_sel); +- rtw_dbg(rtwdev, RTW_DBG_RFK, "[IQK] restore 0x67 = 0x%x\n", +- rtw_read32_mask(rtwdev, REG_PAD_CTRL1, MASKBYTE3)); +-} +- +-static void rtw8723d_iqk_backup_lte_path_gnt(struct rtw_dev *rtwdev, +- struct iqk_backup_regs *backup) +-{ +- backup->lte_path = rtw_read32(rtwdev, REG_LTECOEX_PATH_CONTROL); +- rtw_write32(rtwdev, REG_LTECOEX_CTRL, 0x800f0038); +- mdelay(1); +- backup->lte_gnt = rtw_read32(rtwdev, REG_LTECOEX_READ_DATA); +- rtw_dbg(rtwdev, RTW_DBG_RFK, "[IQK] OriginalGNT = 0x%x\n", +- backup->lte_gnt); +-} +- +-static void rtw8723d_iqk_config_lte_path_gnt(struct rtw_dev *rtwdev) +-{ +- rtw_write32(rtwdev, REG_LTECOEX_WRITE_DATA, 0x0000ff00); +- rtw_write32(rtwdev, REG_LTECOEX_CTRL, 0xc0020038); +- rtw_write32_mask(rtwdev, REG_LTECOEX_PATH_CONTROL, BIT_LTE_MUX_CTRL_PATH, 0x1); +-} +- +-static void rtw8723d_iqk_restore_lte_path_gnt(struct rtw_dev *rtwdev, +- const struct iqk_backup_regs *bak) +-{ +- rtw_write32(rtwdev, REG_LTECOEX_WRITE_DATA, bak->lte_gnt); +- rtw_write32(rtwdev, REG_LTECOEX_CTRL, 0xc00f0038); +- rtw_write32(rtwdev, REG_LTECOEX_PATH_CONTROL, bak->lte_path); +-} +- + struct rtw_8723d_iqk_cfg { + const char *name; + u32 val_bb_sel_btg; +@@ -930,6 +532,8 @@ static u8 rtw8723d_iqk_check_rx_failed(struct rtw_dev *rtwdev, + return 0; + } + ++#define IQK_LTE_WRITE_VAL_8723D 0x0000ff00 ++ + static void rtw8723d_iqk_one_shot(struct rtw_dev *rtwdev, bool tx, + const struct rtw_8723d_iqk_cfg *iqk_cfg) + { +@@ -937,7 +541,7 @@ static void rtw8723d_iqk_one_shot(struct rtw_dev *rtwdev, bool tx, + + /* enter IQK mode */ + rtw_write32_mask(rtwdev, REG_FPGA0_IQK_11N, BIT_MASK_IQK_MOD, EN_IQK); +- rtw8723d_iqk_config_lte_path_gnt(rtwdev); ++ rtw8723x_iqk_config_lte_path_gnt(rtwdev, IQK_LTE_WRITE_VAL_8723D); + + rtw_write32(rtwdev, REG_LTECOEX_CTRL, 0x800f0054); + mdelay(1); +@@ -959,9 +563,9 @@ static void rtw8723d_iqk_one_shot(struct rtw_dev *rtwdev, bool tx, + + static void rtw8723d_iqk_txrx_path_post(struct rtw_dev *rtwdev, + const struct rtw_8723d_iqk_cfg *iqk_cfg, +- const struct iqk_backup_regs *backup) ++ const struct rtw8723x_iqk_backup_regs *backup) + { +- rtw8723d_iqk_restore_lte_path_gnt(rtwdev, backup); ++ rtw8723x_iqk_restore_lte_path_gnt(rtwdev, backup); + rtw_write32(rtwdev, REG_BB_SEL_BTG, backup->bb_sel_btg); + + /* leave IQK mode */ +@@ -974,7 +578,7 @@ static void rtw8723d_iqk_txrx_path_post(struct rtw_dev *rtwdev, + + static u8 rtw8723d_iqk_tx_path(struct rtw_dev *rtwdev, + const struct rtw_8723d_iqk_cfg *iqk_cfg, +- const struct iqk_backup_regs *backup) ++ const struct rtw8723x_iqk_backup_regs *backup) + { + u8 status; + +@@ -1033,7 +637,7 @@ static u8 rtw8723d_iqk_tx_path(struct rtw_dev *rtwdev, + + static u8 rtw8723d_iqk_rx_path(struct rtw_dev *rtwdev, + const struct rtw_8723d_iqk_cfg *iqk_cfg, +- const struct iqk_backup_regs *backup) ++ const struct rtw8723x_iqk_backup_regs *backup) + { + u32 tx_x, tx_y; + u8 status; +@@ -1220,14 +824,6 @@ void rtw8723d_iqk_fill_s0_matrix(struct rtw_dev *rtwdev, const s32 result[]) + result[IQK_S0_RX_Y]); + } + +-static void rtw8723d_iqk_path_adda_on(struct rtw_dev *rtwdev) +-{ +- int i; +- +- for (i = 0; i < IQK_ADDA_REG_NUM; i++) +- rtw_write32(rtwdev, iqk_adda_regs[i], 0x03c00016); +-} +- + static void rtw8723d_iqk_config_mac(struct rtw_dev *rtwdev) + { + rtw_write8(rtwdev, REG_TXPAUSE, 0xff); +@@ -1245,70 +841,14 @@ void rtw8723d_iqk_rf_standby(struct rtw_dev *rtwdev, enum rtw_rf_path path) + rtw_write32_mask(rtwdev, REG_FPGA0_IQK_11N, BIT_MASK_IQK_MOD, EN_IQK); + } + +-static +-bool rtw8723d_iqk_similarity_cmp(struct rtw_dev *rtwdev, s32 result[][IQK_NR], +- u8 c1, u8 c2) +-{ +- u32 i, j, diff; +- u32 bitmap = 0; +- u8 candidate[PATH_NR] = {IQK_ROUND_INVALID, IQK_ROUND_INVALID}; +- bool ret = true; +- +- s32 tmp1, tmp2; +- +- for (i = 0; i < IQK_NR; i++) { +- tmp1 = iqkxy_to_s32(result[c1][i]); +- tmp2 = iqkxy_to_s32(result[c2][i]); +- +- diff = abs(tmp1 - tmp2); +- +- if (diff <= MAX_TOLERANCE) +- continue; +- +- if ((i == IQK_S1_RX_X || i == IQK_S0_RX_X) && !bitmap) { +- if (result[c1][i] + result[c1][i + 1] == 0) +- candidate[i / IQK_SX_NR] = c2; +- else if (result[c2][i] + result[c2][i + 1] == 0) +- candidate[i / IQK_SX_NR] = c1; +- else +- bitmap |= BIT(i); +- } else { +- bitmap |= BIT(i); +- } +- } +- +- if (bitmap != 0) +- goto check_sim; +- +- for (i = 0; i < PATH_NR; i++) { +- if (candidate[i] == IQK_ROUND_INVALID) +- continue; +- +- for (j = i * IQK_SX_NR; j < i * IQK_SX_NR + 2; j++) +- result[IQK_ROUND_HYBRID][j] = result[candidate[i]][j]; +- ret = false; +- } +- +- return ret; +- +-check_sim: +- for (i = 0; i < IQK_NR; i++) { +- j = i & ~1; /* 2 bits are a pair for IQ[X, Y] */ +- if (bitmap & GENMASK(j + 1, j)) +- continue; +- +- result[IQK_ROUND_HYBRID][i] = result[c1][i]; +- } +- +- return false; +-} ++#define ADDA_ON_VAL_8723D 0x03c00016 + + static +-void rtw8723d_iqk_precfg_path(struct rtw_dev *rtwdev, enum rtw8723d_path path) ++void rtw8723d_iqk_precfg_path(struct rtw_dev *rtwdev, enum rtw8723x_path path) + { + if (path == PATH_S0) { + rtw8723d_iqk_rf_standby(rtwdev, RF_PATH_A); +- rtw8723d_iqk_path_adda_on(rtwdev); ++ rtw8723x_iqk_path_adda_on(rtwdev, ADDA_ON_VAL_8723D); + } + + rtw_write32_mask(rtwdev, REG_FPGA0_IQK_11N, BIT_MASK_IQK_MOD, EN_IQK); +@@ -1317,13 +857,13 @@ void rtw8723d_iqk_precfg_path(struct rtw_dev *rtwdev, enum rtw8723d_path path) + + if (path == PATH_S1) { + rtw8723d_iqk_rf_standby(rtwdev, RF_PATH_B); +- rtw8723d_iqk_path_adda_on(rtwdev); ++ rtw8723x_iqk_path_adda_on(rtwdev, ADDA_ON_VAL_8723D); + } + } + + static + void rtw8723d_iqk_one_round(struct rtw_dev *rtwdev, s32 result[][IQK_NR], u8 t, +- const struct iqk_backup_regs *backup) ++ const struct rtw8723x_iqk_backup_regs *backup) + { + u32 i; + u8 s1_ok, s0_ok; +@@ -1331,7 +871,7 @@ void rtw8723d_iqk_one_round(struct rtw_dev *rtwdev, s32 result[][IQK_NR], u8 t, + rtw_dbg(rtwdev, RTW_DBG_RFK, + "[IQK] IQ Calibration for 1T1R_S0/S1 for %d times\n", t); + +- rtw8723d_iqk_path_adda_on(rtwdev); ++ rtw8723x_iqk_path_adda_on(rtwdev, ADDA_ON_VAL_8723D); + rtw8723d_iqk_config_mac(rtwdev); + rtw_write32_mask(rtwdev, REG_CCK_ANT_SEL_11N, 0x0f000000, 0xf); + rtw_write32(rtwdev, REG_BB_RX_PATH_11N, 0x03a05611); +@@ -1427,7 +967,7 @@ static void rtw8723d_phy_calibration(struct rtw_dev *rtwdev) + { + struct rtw_dm_info *dm_info = &rtwdev->dm_info; + s32 result[IQK_ROUND_SIZE][IQK_NR]; +- struct iqk_backup_regs backup; ++ struct rtw8723x_iqk_backup_regs backup; + u8 i, j; + u8 final_candidate = IQK_ROUND_INVALID; + bool good; +@@ -1436,23 +976,23 @@ static void rtw8723d_phy_calibration(struct rtw_dev *rtwdev) + + memset(result, 0, sizeof(result)); + +- rtw8723d_iqk_backup_path_ctrl(rtwdev, &backup); +- rtw8723d_iqk_backup_lte_path_gnt(rtwdev, &backup); +- rtw8723d_iqk_backup_regs(rtwdev, &backup); ++ rtw8723x_iqk_backup_path_ctrl(rtwdev, &backup); ++ rtw8723x_iqk_backup_lte_path_gnt(rtwdev, &backup); ++ rtw8723x_iqk_backup_regs(rtwdev, &backup); + + for (i = IQK_ROUND_0; i <= IQK_ROUND_2; i++) { +- rtw8723d_iqk_config_path_ctrl(rtwdev); +- rtw8723d_iqk_config_lte_path_gnt(rtwdev); ++ rtw8723x_iqk_config_path_ctrl(rtwdev); ++ rtw8723x_iqk_config_lte_path_gnt(rtwdev, IQK_LTE_WRITE_VAL_8723D); + + rtw8723d_iqk_one_round(rtwdev, result, i, &backup); + + if (i > IQK_ROUND_0) +- rtw8723d_iqk_restore_regs(rtwdev, &backup); +- rtw8723d_iqk_restore_lte_path_gnt(rtwdev, &backup); +- rtw8723d_iqk_restore_path_ctrl(rtwdev, &backup); ++ rtw8723x_iqk_restore_regs(rtwdev, &backup); ++ rtw8723x_iqk_restore_lte_path_gnt(rtwdev, &backup); ++ rtw8723x_iqk_restore_path_ctrl(rtwdev, &backup); + + for (j = IQK_ROUND_0; j < i; j++) { +- good = rtw8723d_iqk_similarity_cmp(rtwdev, result, j, i); ++ good = rtw8723x_iqk_similarity_cmp(rtwdev, result, j, i); + + if (good) { + final_candidate = j; +@@ -1546,26 +1086,6 @@ static void rtw8723d_phy_cck_pd_set(struct rtw_dev *rtwdev, u8 new_lvl) + } + + /* for coex */ +-static void rtw8723d_coex_cfg_init(struct rtw_dev *rtwdev) +-{ +- /* enable TBTT nterrupt */ +- rtw_write8_set(rtwdev, REG_BCN_CTRL, BIT_EN_BCN_FUNCTION); +- +- /* BT report packet sample rate */ +- /* 0x790[5:0]=0x5 */ +- rtw_write8_mask(rtwdev, REG_BT_TDMA_TIME, BIT_MASK_SAMPLE_RATE, 0x5); +- +- /* enable BT counter statistics */ +- rtw_write8(rtwdev, REG_BT_STAT_CTRL, 0x1); +- +- /* enable PTA (3-wire function form BT side) */ +- rtw_write32_set(rtwdev, REG_GPIO_MUXCFG, BIT_BT_PTA_EN); +- rtw_write32_set(rtwdev, REG_GPIO_MUXCFG, BIT_PO_BT_PTA_PINS); +- +- /* enable PTA (tx/rx signal form WiFi side) */ +- rtw_write8_set(rtwdev, REG_QUEUE_CTRL, BIT_PTA_WL_TX_EN); +-} +- + static void rtw8723d_coex_cfg_gnt_fix(struct rtw_dev *rtwdev) + { + } +@@ -1671,39 +1191,6 @@ static void rtw8723d_coex_cfg_wl_rx_gain(struct rtw_dev *rtwdev, bool low_gain) + } + } + +-static u8 rtw8723d_pwrtrack_get_limit_ofdm(struct rtw_dev *rtwdev) +-{ +- struct rtw_dm_info *dm_info = &rtwdev->dm_info; +- u8 tx_rate = dm_info->tx_rate; +- u8 limit_ofdm = 30; +- +- switch (tx_rate) { +- case DESC_RATE1M...DESC_RATE5_5M: +- case DESC_RATE11M: +- break; +- case DESC_RATE6M...DESC_RATE48M: +- limit_ofdm = 36; +- break; +- case DESC_RATE54M: +- limit_ofdm = 34; +- break; +- case DESC_RATEMCS0...DESC_RATEMCS2: +- limit_ofdm = 38; +- break; +- case DESC_RATEMCS3...DESC_RATEMCS4: +- limit_ofdm = 36; +- break; +- case DESC_RATEMCS5...DESC_RATEMCS7: +- limit_ofdm = 34; +- break; +- default: +- rtw_warn(rtwdev, "pwrtrack unhandled tx_rate 0x%x\n", tx_rate); +- break; +- } +- +- return limit_ofdm; +-} +- + static void rtw8723d_set_iqk_matrix_by_result(struct rtw_dev *rtwdev, + u32 ofdm_swing, u8 rf_path) + { +@@ -1845,7 +1332,7 @@ static void rtw8723d_pwrtrack_set(struct rtw_dev *rtwdev, u8 path) + s8 final_ofdm_swing_index; + s8 final_cck_swing_index; + +- limit_ofdm = rtw8723d_pwrtrack_get_limit_ofdm(rtwdev); ++ limit_ofdm = rtw8723x_pwrtrack_get_limit_ofdm(rtwdev); + + final_ofdm_swing_index = RTW_DEF_OFDM_SWING_INDEX + + dm_info->delta_power_index[path]; +@@ -1873,26 +1360,6 @@ static void rtw8723d_pwrtrack_set(struct rtw_dev *rtwdev, u8 path) + rtw_phy_set_tx_power_level(rtwdev, hal->current_channel); + } + +-static void rtw8723d_pwrtrack_set_xtal(struct rtw_dev *rtwdev, u8 therm_path, +- u8 delta) +-{ +- struct rtw_dm_info *dm_info = &rtwdev->dm_info; +- const struct rtw_pwr_track_tbl *tbl = rtwdev->chip->pwr_track_tbl; +- const s8 *pwrtrk_xtal; +- s8 xtal_cap; +- +- if (dm_info->thermal_avg[therm_path] > +- rtwdev->efuse.thermal_meter[therm_path]) +- pwrtrk_xtal = tbl->pwrtrk_xtal_p; +- else +- pwrtrk_xtal = tbl->pwrtrk_xtal_n; +- +- xtal_cap = rtwdev->efuse.crystal_cap & 0x3F; +- xtal_cap = clamp_t(s8, xtal_cap + pwrtrk_xtal[delta], 0, 0x3F); +- rtw_write32_mask(rtwdev, REG_AFE_CTRL3, BIT_MASK_XTAL, +- xtal_cap | (xtal_cap << 6)); +-} +- + static void rtw8723d_phy_pwrtrack(struct rtw_dev *rtwdev) + { + struct rtw_dm_info *dm_info = &rtwdev->dm_info; +@@ -1912,7 +1379,7 @@ static void rtw8723d_phy_pwrtrack(struct rtw_dev *rtwdev) + do_iqk = rtw_phy_pwrtrack_need_iqk(rtwdev); + + if (do_iqk) +- rtw8723d_lck(rtwdev); ++ rtw8723x_lck(rtwdev); + + if (dm_info->pwr_trk_init_trigger) + dm_info->pwr_trk_init_trigger = false; +@@ -1937,7 +1404,7 @@ static void rtw8723d_phy_pwrtrack(struct rtw_dev *rtwdev) + rtw8723d_pwrtrack_set(rtwdev, path); + } + +- rtw8723d_pwrtrack_set_xtal(rtwdev, RF_PATH_A, delta); ++ rtw8723x_pwrtrack_set_xtal(rtwdev, RF_PATH_A, delta); + + iqk: + if (do_iqk) +@@ -1963,49 +1430,29 @@ static void rtw8723d_pwr_track(struct rtw_dev *rtwdev) + dm_info->pwr_trk_triggered = false; + } + +-static void rtw8723d_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) */ +- __le16 chksum = 0; +- __le16 *data = (__le16 *)(txdesc); +- struct rtw_tx_desc *tx_desc = (struct rtw_tx_desc *)txdesc; +- +- le32p_replace_bits(&tx_desc->w7, 0, RTW_TX_DESC_W7_TXDESC_CHECKSUM); +- +- while (words--) +- chksum ^= *data++; +- +- chksum = ~chksum; +- +- le32p_replace_bits(&tx_desc->w7, __le16_to_cpu(chksum), +- RTW_TX_DESC_W7_TXDESC_CHECKSUM); +-} +- + static struct rtw_chip_ops rtw8723d_ops = { + .phy_set_param = rtw8723d_phy_set_param, +- .read_efuse = rtw8723d_read_efuse, ++ .read_efuse = rtw8723x_read_efuse, + .query_rx_desc = rtw8723d_query_rx_desc, + .set_channel = rtw8723d_set_channel, +- .mac_init = rtw8723d_mac_init, ++ .mac_init = rtw8723x_mac_init, + .shutdown = rtw8723d_shutdown, + .read_rf = rtw_phy_read_rf_sipi, + .write_rf = rtw_phy_write_rf_reg_sipi, +- .set_tx_power_index = rtw8723d_set_tx_power_index, ++ .set_tx_power_index = rtw8723x_set_tx_power_index, + .set_antenna = NULL, +- .cfg_ldo25 = rtw8723d_cfg_ldo25, +- .efuse_grant = rtw8723d_efuse_grant, +- .false_alarm_statistics = rtw8723d_false_alarm_statistics, ++ .cfg_ldo25 = rtw8723x_cfg_ldo25, ++ .efuse_grant = rtw8723x_efuse_grant, ++ .false_alarm_statistics = rtw8723x_false_alarm_statistics, + .phy_calibration = rtw8723d_phy_calibration, + .cck_pd_set = rtw8723d_phy_cck_pd_set, + .pwr_track = rtw8723d_pwr_track, + .config_bfee = NULL, + .set_gid_table = NULL, + .cfg_csi_rate = NULL, +- .fill_txdesc_checksum = rtw8723d_fill_txdesc_checksum, ++ .fill_txdesc_checksum = rtw8723x_fill_txdesc_checksum, + +- .coex_set_init = rtw8723d_coex_cfg_init, ++ .coex_set_init = rtw8723x_coex_cfg_init, + .coex_set_ant_switch = NULL, + .coex_set_gnt_fix = rtw8723d_coex_cfg_gnt_fix, + .coex_set_gnt_debug = rtw8723d_coex_cfg_gnt_debug, +@@ -2592,22 +2039,6 @@ static const struct rtw_rqpn rqpn_table_8723d[] = { + RTW_DMA_MAPPING_EXTRA, RTW_DMA_MAPPING_HIGH}, + }; + +-static const struct rtw_prioq_addrs prioq_addrs_8723d = { +- .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_intf_phy_para pcie_gen1_param_8723d[] = { + {0x0008, 0x4a22, + RTW_IP_SEL_PHY, +@@ -2628,28 +2059,6 @@ static const struct rtw_intf_phy_para_table phy_para_table_8723d = { + .n_gen1_para = ARRAY_SIZE(pcie_gen1_param_8723d), + }; + +-static const struct rtw_hw_reg rtw8723d_dig[] = { +- [0] = { .addr = 0xc50, .mask = 0x7f }, +- [1] = { .addr = 0xc50, .mask = 0x7f }, +-}; +- +-static const struct rtw_hw_reg rtw8723d_dig_cck[] = { +- [0] = { .addr = 0xa0c, .mask = 0x3f00 }, +-}; +- +-static const struct rtw_rf_sipi_addr rtw8723d_rf_sipi_addr[] = { +- [RF_PATH_A] = { .hssi_1 = 0x820, .lssi_read = 0x8a0, +- .hssi_2 = 0x824, .lssi_read_pi = 0x8b8}, +- [RF_PATH_B] = { .hssi_1 = 0x828, .lssi_read = 0x8a4, +- .hssi_2 = 0x82c, .lssi_read_pi = 0x8bc}, +-}; +- +-static const struct rtw_ltecoex_addr rtw8723d_ltecoex_addr = { +- .ctrl = REG_LTECOEX_CTRL, +- .wdata = REG_LTECOEX_WRITE_DATA, +- .rdata = REG_LTECOEX_READ_DATA, +-}; +- + static const struct rtw_rfe_def rtw8723d_rfe_defs[] = { + [0] = { .phy_pg_tbl = &rtw8723d_bb_pg_tbl, + .txpwr_lmt_tbl = &rtw8723d_txpwr_lmt_tbl,}, +@@ -2770,14 +2179,14 @@ const struct rtw_chip_info rtw8723d_hw_spec = { + .pwr_off_seq = card_disable_flow_8723d, + .page_table = page_table_8723d, + .rqpn_table = rqpn_table_8723d, +- .prioq_addrs = &prioq_addrs_8723d, ++ .prioq_addrs = &rtw8723x_common.prioq_addrs, + .intf_table = &phy_para_table_8723d, +- .dig = rtw8723d_dig, +- .dig_cck = rtw8723d_dig_cck, ++ .dig = rtw8723x_common.dig, ++ .dig_cck = rtw8723x_common.dig_cck, + .rf_sipi_addr = {0x840, 0x844}, +- .rf_sipi_read_addr = rtw8723d_rf_sipi_addr, ++ .rf_sipi_read_addr = rtw8723x_common.rf_sipi_addr, + .fix_rf_phy_num = 2, +- .ltecoex_addr = &rtw8723d_ltecoex_addr, ++ .ltecoex_addr = &rtw8723x_common.ltecoex_addr, + .mac_tbl = &rtw8723d_mac_tbl, + .agc_tbl = &rtw8723d_agc_tbl, + .bb_tbl = &rtw8723d_bb_tbl, +diff --git a/drivers/net/wireless/realtek/rtw88/rtw8723d.h b/drivers/net/wireless/realtek/rtw88/rtw8723d.h +index 2434e2480cbe27..fba06c9f480e55 100644 +--- a/drivers/net/wireless/realtek/rtw88/rtw8723d.h ++++ b/drivers/net/wireless/realtek/rtw88/rtw8723d.h +@@ -5,90 +5,7 @@ + #ifndef __RTW8723D_H__ + #define __RTW8723D_H__ + +-enum rtw8723d_path { +- PATH_S1, +- PATH_S0, +- PATH_NR, +-}; +- +-enum rtw8723d_iqk_round { +- IQK_ROUND_0, +- IQK_ROUND_1, +- IQK_ROUND_2, +- IQK_ROUND_HYBRID, +- IQK_ROUND_SIZE, +- IQK_ROUND_INVALID = 0xff, +-}; +- +-enum rtw8723d_iqk_result { +- IQK_S1_TX_X, +- IQK_S1_TX_Y, +- IQK_S1_RX_X, +- IQK_S1_RX_Y, +- IQK_S0_TX_X, +- IQK_S0_TX_Y, +- IQK_S0_RX_X, +- IQK_S0_RX_Y, +- IQK_NR, +- IQK_SX_NR = IQK_NR / PATH_NR, +-}; +- +-struct rtw8723de_efuse { +- u8 mac_addr[ETH_ALEN]; /* 0xd0 */ +- u8 vender_id[2]; +- u8 device_id[2]; +- u8 sub_vender_id[2]; +- u8 sub_device_id[2]; +-}; +- +-struct rtw8723du_efuse { +- u8 res4[48]; /* 0xd0 */ +- u8 vender_id[2]; /* 0x100 */ +- u8 product_id[2]; /* 0x102 */ +- u8 usb_option; /* 0x104 */ +- u8 res5[2]; /* 0x105 */ +- u8 mac_addr[ETH_ALEN]; /* 0x107 */ +-}; +- +-struct rtw8723ds_efuse { +- u8 res4[0x4a]; /* 0xd0 */ +- u8 mac_addr[ETH_ALEN]; /* 0x11a */ +-}; +- +-struct rtw8723d_efuse { +- __le16 rtl_id; +- u8 rsvd[2]; +- u8 afe; +- u8 rsvd1[11]; +- +- /* 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[2]; /* 0xbd */ +- u8 lna_type_5g[2]; +- u8 rf_board_option; +- u8 rf_feature_option; +- u8 rf_bt_setting; +- u8 eeprom_version; +- u8 eeprom_customer_id; +- u8 tx_bb_swing_setting_2g; +- u8 res_c7; +- u8 tx_pwr_calibrate_rate; +- u8 rf_antenna_option; /* 0xc9 */ +- u8 rfe_option; +- u8 country_code[2]; +- u8 res[3]; +- union { +- struct rtw8723de_efuse e; +- struct rtw8723du_efuse u; +- struct rtw8723ds_efuse s; +- }; +-}; ++#include "rtw8723x.h" + + extern const struct rtw_chip_info rtw8723d_hw_spec; + +@@ -114,193 +31,9 @@ extern const struct rtw_chip_info rtw8723d_hw_spec; + #define GET_PHY_STAT_P1_RXSNR_A(phy_stat) \ + le32_get_bits(*((__le32 *)(phy_stat) + 0x06), GENMASK(7, 0)) + +-static inline s32 iqkxy_to_s32(s32 val) +-{ +- /* val is Q10.8 */ +- return sign_extend32(val, 9); +-} +- +-static inline s32 iqk_mult(s32 x, s32 y, s32 *ext) +-{ +- /* x, y and return value are Q10.8 */ +- s32 t; +- +- t = x * y; +- if (ext) +- *ext = (t >> 7) & 0x1; /* Q.16 --> Q.9; get LSB of Q.9 */ +- +- return (t >> 8); /* Q.16 --> Q.8 */ +-} +- +-#define OFDM_SWING_A(swing) FIELD_GET(GENMASK(9, 0), swing) +-#define OFDM_SWING_B(swing) FIELD_GET(GENMASK(15, 10), swing) +-#define OFDM_SWING_C(swing) FIELD_GET(GENMASK(21, 16), swing) +-#define OFDM_SWING_D(swing) FIELD_GET(GENMASK(31, 22), swing) + #define RTW_DEF_OFDM_SWING_INDEX 28 + #define RTW_DEF_CCK_SWING_INDEX 28 + +-#define MAX_TOLERANCE 5 +-#define IQK_TX_X_ERR 0x142 +-#define IQK_TX_Y_ERR 0x42 +-#define IQK_RX_X_UPPER 0x11a +-#define IQK_RX_X_LOWER 0xe6 +-#define IQK_RX_Y_LMT 0x1a +-#define IQK_TX_OK BIT(0) +-#define IQK_RX_OK BIT(1) +-#define PATH_IQK_RETRY 2 +- +-#define SPUR_THRES 0x16 + #define CCK_DFIR_NR 3 +-#define DIS_3WIRE 0xccf000c0 +-#define EN_3WIRE 0xccc000c0 +-#define START_PSD 0x400000 +-#define FREQ_CH13 0xfccd +-#define FREQ_CH14 0xff9a +-#define RFCFGCH_CHANNEL_MASK GENMASK(7, 0) +-#define RFCFGCH_BW_MASK (BIT(11) | BIT(10)) +-#define RFCFGCH_BW_20M (BIT(11) | BIT(10)) +-#define RFCFGCH_BW_40M BIT(10) +-#define BIT_MASK_RFMOD BIT(0) +-#define BIT_LCK BIT(15) +- +-#define REG_GPIO_INTM 0x0048 +-#define REG_BTG_SEL 0x0067 +-#define BIT_MASK_BTG_WL BIT(7) +-#define REG_LTECOEX_PATH_CONTROL 0x0070 +-#define REG_LTECOEX_CTRL 0x07c0 +-#define REG_LTECOEX_WRITE_DATA 0x07c4 +-#define REG_LTECOEX_READ_DATA 0x07c8 +-#define REG_PSDFN 0x0808 +-#define REG_BB_PWR_SAV1_11N 0x0874 +-#define REG_ANA_PARAM1 0x0880 +-#define REG_ANALOG_P4 0x088c +-#define REG_PSDRPT 0x08b4 +-#define REG_FPGA1_RFMOD 0x0900 +-#define REG_BB_SEL_BTG 0x0948 +-#define REG_BBRX_DFIR 0x0954 +-#define BIT_MASK_RXBB_DFIR GENMASK(27, 24) +-#define BIT_RXBB_DFIR_EN BIT(19) +-#define REG_CCK0_SYS 0x0a00 +-#define BIT_CCK_SIDE_BAND BIT(4) +-#define REG_CCK_ANT_SEL_11N 0x0a04 +-#define REG_PWRTH 0x0a08 +-#define REG_CCK_FA_RST_11N 0x0a2c +-#define BIT_MASK_CCK_CNT_KEEP BIT(12) +-#define BIT_MASK_CCK_CNT_EN BIT(13) +-#define BIT_MASK_CCK_CNT_KPEN (BIT_MASK_CCK_CNT_KEEP | BIT_MASK_CCK_CNT_EN) +-#define BIT_MASK_CCK_FA_KEEP BIT(14) +-#define BIT_MASK_CCK_FA_EN BIT(15) +-#define BIT_MASK_CCK_FA_KPEN (BIT_MASK_CCK_FA_KEEP | BIT_MASK_CCK_FA_EN) +-#define REG_CCK_FA_LSB_11N 0x0a5c +-#define REG_CCK_FA_MSB_11N 0x0a58 +-#define REG_CCK_CCA_CNT_11N 0x0a60 +-#define BIT_MASK_CCK_FA_MSB GENMASK(7, 0) +-#define BIT_MASK_CCK_FA_LSB GENMASK(15, 8) +-#define REG_PWRTH2 0x0aa8 +-#define REG_CSRATIO 0x0aaa +-#define REG_OFDM_FA_HOLDC_11N 0x0c00 +-#define BIT_MASK_OFDM_FA_KEEP BIT(31) +-#define REG_BB_RX_PATH_11N 0x0c04 +-#define REG_TRMUX_11N 0x0c08 +-#define REG_OFDM_FA_RSTC_11N 0x0c0c +-#define BIT_MASK_OFDM_FA_RST BIT(31) +-#define REG_A_RXIQI 0x0c14 +-#define BIT_MASK_RXIQ_S1_X 0x000003FF +-#define BIT_MASK_RXIQ_S1_Y1 0x0000FC00 +-#define BIT_SET_RXIQ_S1_Y1(y) ((y) & 0x3F) +-#define REG_OFDM0_RXDSP 0x0c40 +-#define BIT_MASK_RXDSP GENMASK(28, 24) +-#define BIT_EN_RXDSP BIT(9) +-#define REG_OFDM_0_ECCA_THRESHOLD 0x0c4c +-#define BIT_MASK_OFDM0_EXT_A BIT(31) +-#define BIT_MASK_OFDM0_EXT_C BIT(29) +-#define BIT_MASK_OFDM0_EXTS (BIT(31) | BIT(29) | BIT(28)) +-#define BIT_SET_OFDM0_EXTS(a, c, d) (((a) << 31) | ((c) << 29) | ((d) << 28)) +-#define REG_OFDM0_XAAGC1 0x0c50 +-#define REG_OFDM0_XBAGC1 0x0c58 +-#define REG_AGCRSSI 0x0c78 +-#define REG_OFDM_0_XA_TX_IQ_IMBALANCE 0x0c80 +-#define BIT_MASK_TXIQ_ELM_A 0x03ff +-#define BIT_SET_TXIQ_ELM_ACD(a, c, d) (((d) << 22) | (((c) & 0x3F) << 16) | \ +- ((a) & 0x03ff)) +-#define BIT_MASK_TXIQ_ELM_C GENMASK(21, 16) +-#define BIT_SET_TXIQ_ELM_C2(c) ((c) & 0x3F) +-#define BIT_MASK_TXIQ_ELM_D GENMASK(31, 22) +-#define REG_TXIQK_MATRIXA_LSB2_11N 0x0c94 +-#define BIT_SET_TXIQ_ELM_C1(c) (((c) & 0x000003C0) >> 6) +-#define REG_RXIQK_MATRIX_LSB_11N 0x0ca0 +-#define BIT_MASK_RXIQ_S1_Y2 0xF0000000 +-#define BIT_SET_RXIQ_S1_Y2(y) (((y) >> 6) & 0xF) +-#define REG_TXIQ_AB_S0 0x0cd0 +-#define BIT_MASK_TXIQ_A_S0 0x000007FE +-#define BIT_MASK_TXIQ_A_EXT_S0 BIT(0) +-#define BIT_MASK_TXIQ_B_S0 0x0007E000 +-#define REG_TXIQ_CD_S0 0x0cd4 +-#define BIT_MASK_TXIQ_C_S0 0x000007FE +-#define BIT_MASK_TXIQ_C_EXT_S0 BIT(0) +-#define BIT_MASK_TXIQ_D_S0 GENMASK(22, 13) +-#define BIT_MASK_TXIQ_D_EXT_S0 BIT(12) +-#define REG_RXIQ_AB_S0 0x0cd8 +-#define BIT_MASK_RXIQ_X_S0 0x000003FF +-#define BIT_MASK_RXIQ_Y_S0 0x003FF000 +-#define REG_OFDM_FA_TYPE1_11N 0x0cf0 +-#define BIT_MASK_OFDM_FF_CNT GENMASK(15, 0) +-#define BIT_MASK_OFDM_SF_CNT GENMASK(31, 16) +-#define REG_OFDM_FA_RSTD_11N 0x0d00 +-#define BIT_MASK_OFDM_FA_RST1 BIT(27) +-#define BIT_MASK_OFDM_FA_KEEP1 BIT(31) +-#define REG_CTX 0x0d03 +-#define BIT_MASK_CTX_TYPE GENMASK(6, 4) +-#define REG_OFDM1_CFOTRK 0x0d2c +-#define BIT_EN_CFOTRK BIT(28) +-#define REG_OFDM1_CSI1 0x0d40 +-#define REG_OFDM1_CSI2 0x0d44 +-#define REG_OFDM1_CSI3 0x0d48 +-#define REG_OFDM1_CSI4 0x0d4c +-#define REG_OFDM_FA_TYPE2_11N 0x0da0 +-#define BIT_MASK_OFDM_CCA_CNT GENMASK(15, 0) +-#define BIT_MASK_OFDM_PF_CNT GENMASK(31, 16) +-#define REG_OFDM_FA_TYPE3_11N 0x0da4 +-#define BIT_MASK_OFDM_RI_CNT GENMASK(15, 0) +-#define BIT_MASK_OFDM_CRC_CNT GENMASK(31, 16) +-#define REG_OFDM_FA_TYPE4_11N 0x0da8 +-#define BIT_MASK_OFDM_MNS_CNT GENMASK(15, 0) +-#define REG_FPGA0_IQK_11N 0x0e28 +-#define BIT_MASK_IQK_MOD 0xffffff00 +-#define EN_IQK 0x808000 +-#define RST_IQK 0x000000 +-#define REG_TXIQK_TONE_A_11N 0x0e30 +-#define REG_RXIQK_TONE_A_11N 0x0e34 +-#define REG_TXIQK_PI_A_11N 0x0e38 +-#define REG_RXIQK_PI_A_11N 0x0e3c +-#define REG_TXIQK_11N 0x0e40 +-#define BIT_SET_TXIQK_11N(x, y) (0x80007C00 | ((x) << 16) | (y)) +-#define REG_RXIQK_11N 0x0e44 +-#define REG_IQK_AGC_PTS_11N 0x0e48 +-#define REG_IQK_AGC_RSP_11N 0x0e4c +-#define REG_TX_IQK_TONE_B 0x0e50 +-#define REG_RX_IQK_TONE_B 0x0e54 +-#define REG_IQK_RES_TX 0x0e94 +-#define BIT_MASK_RES_TX GENMASK(25, 16) +-#define REG_IQK_RES_TY 0x0e9c +-#define BIT_MASK_RES_TY GENMASK(25, 16) +-#define REG_IQK_RES_RX 0x0ea4 +-#define BIT_MASK_RES_RX GENMASK(25, 16) +-#define REG_IQK_RES_RY 0x0eac +-#define BIT_IQK_TX_FAIL BIT(28) +-#define BIT_IQK_RX_FAIL BIT(27) +-#define BIT_IQK_DONE BIT(26) +-#define BIT_MASK_RES_RY GENMASK(25, 16) +-#define REG_PAGE_F_RST_11N 0x0f14 +-#define BIT_MASK_F_RST_ALL BIT(16) +-#define REG_IGI_C_11N 0x0f84 +-#define REG_IGI_D_11N 0x0f88 +-#define REG_HT_CRC32_CNT_11N 0x0f90 +-#define BIT_MASK_HT_CRC_OK GENMASK(15, 0) +-#define BIT_MASK_HT_CRC_ERR GENMASK(31, 16) +-#define REG_OFDM_CRC32_CNT_11N 0x0f94 +-#define BIT_MASK_OFDM_LCRC_OK GENMASK(15, 0) +-#define BIT_MASK_OFDM_LCRC_ERR GENMASK(31, 16) +-#define REG_HT_CRC32_CNT_11N_AGG 0x0fb8 + + #endif +diff --git a/drivers/net/wireless/realtek/rtw88/rtw8723x.c b/drivers/net/wireless/realtek/rtw88/rtw8723x.c +new file mode 100644 +index 00000000000000..c23650c5a20080 +--- /dev/null ++++ b/drivers/net/wireless/realtek/rtw88/rtw8723x.c +@@ -0,0 +1,562 @@ ++// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause ++/* Copyright 2024 Fiona Klute ++ * ++ * Based on code originally in rtw8723d.[ch], ++ * Copyright(c) 2018-2019 Realtek Corporation ++ */ ++ ++#include "main.h" ++#include "debug.h" ++#include "phy.h" ++#include "reg.h" ++#include "tx.h" ++#include "rtw8723x.h" ++ ++static const struct rtw_hw_reg rtw8723x_txagc[] = { ++ [DESC_RATE1M] = { .addr = 0xe08, .mask = 0x0000ff00 }, ++ [DESC_RATE2M] = { .addr = 0x86c, .mask = 0x0000ff00 }, ++ [DESC_RATE5_5M] = { .addr = 0x86c, .mask = 0x00ff0000 }, ++ [DESC_RATE11M] = { .addr = 0x86c, .mask = 0xff000000 }, ++ [DESC_RATE6M] = { .addr = 0xe00, .mask = 0x000000ff }, ++ [DESC_RATE9M] = { .addr = 0xe00, .mask = 0x0000ff00 }, ++ [DESC_RATE12M] = { .addr = 0xe00, .mask = 0x00ff0000 }, ++ [DESC_RATE18M] = { .addr = 0xe00, .mask = 0xff000000 }, ++ [DESC_RATE24M] = { .addr = 0xe04, .mask = 0x000000ff }, ++ [DESC_RATE36M] = { .addr = 0xe04, .mask = 0x0000ff00 }, ++ [DESC_RATE48M] = { .addr = 0xe04, .mask = 0x00ff0000 }, ++ [DESC_RATE54M] = { .addr = 0xe04, .mask = 0xff000000 }, ++ [DESC_RATEMCS0] = { .addr = 0xe10, .mask = 0x000000ff }, ++ [DESC_RATEMCS1] = { .addr = 0xe10, .mask = 0x0000ff00 }, ++ [DESC_RATEMCS2] = { .addr = 0xe10, .mask = 0x00ff0000 }, ++ [DESC_RATEMCS3] = { .addr = 0xe10, .mask = 0xff000000 }, ++ [DESC_RATEMCS4] = { .addr = 0xe14, .mask = 0x000000ff }, ++ [DESC_RATEMCS5] = { .addr = 0xe14, .mask = 0x0000ff00 }, ++ [DESC_RATEMCS6] = { .addr = 0xe14, .mask = 0x00ff0000 }, ++ [DESC_RATEMCS7] = { .addr = 0xe14, .mask = 0xff000000 }, ++}; ++ ++static void __rtw8723x_lck(struct rtw_dev *rtwdev) ++{ ++ u32 lc_cal; ++ u8 val_ctx, rf_val; ++ int ret; ++ ++ val_ctx = rtw_read8(rtwdev, REG_CTX); ++ if ((val_ctx & BIT_MASK_CTX_TYPE) != 0) ++ rtw_write8(rtwdev, REG_CTX, val_ctx & ~BIT_MASK_CTX_TYPE); ++ else ++ rtw_write8(rtwdev, REG_TXPAUSE, 0xFF); ++ lc_cal = rtw_read_rf(rtwdev, RF_PATH_A, RF_CFGCH, RFREG_MASK); ++ ++ rtw_write_rf(rtwdev, RF_PATH_A, RF_CFGCH, RFREG_MASK, lc_cal | BIT_LCK); ++ ++ ret = read_poll_timeout(rtw_read_rf, rf_val, rf_val != 0x1, ++ 10000, 1000000, false, ++ rtwdev, RF_PATH_A, RF_CFGCH, BIT_LCK); ++ if (ret) ++ rtw_warn(rtwdev, "failed to poll LCK status bit\n"); ++ ++ rtw_write_rf(rtwdev, RF_PATH_A, RF_CFGCH, RFREG_MASK, lc_cal); ++ if ((val_ctx & BIT_MASK_CTX_TYPE) != 0) ++ rtw_write8(rtwdev, REG_CTX, val_ctx); ++ else ++ rtw_write8(rtwdev, REG_TXPAUSE, 0x00); ++} ++ ++static void rtw8723xe_efuse_parsing(struct rtw_efuse *efuse, ++ struct rtw8723x_efuse *map) ++{ ++ ether_addr_copy(efuse->addr, map->e.mac_addr); ++} ++ ++static void rtw8723xu_efuse_parsing(struct rtw_efuse *efuse, ++ struct rtw8723x_efuse *map) ++{ ++ ether_addr_copy(efuse->addr, map->u.mac_addr); ++} ++ ++static void rtw8723xs_efuse_parsing(struct rtw_efuse *efuse, ++ struct rtw8723x_efuse *map) ++{ ++ ether_addr_copy(efuse->addr, map->s.mac_addr); ++} ++ ++static int __rtw8723x_read_efuse(struct rtw_dev *rtwdev, u8 *log_map) ++{ ++ struct rtw_efuse *efuse = &rtwdev->efuse; ++ struct rtw8723x_efuse *map; ++ int i; ++ ++ map = (struct rtw8723x_efuse *)log_map; ++ ++ efuse->rfe_option = 0; ++ efuse->rf_board_option = map->rf_board_option; ++ efuse->crystal_cap = map->xtal_k; ++ efuse->pa_type_2g = map->pa_type; ++ efuse->lna_type_2g = map->lna_type_2g[0]; ++ 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_k = map->thermal_meter; ++ efuse->afe = map->afe; ++ ++ 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_PCIE: ++ rtw8723xe_efuse_parsing(efuse, map); ++ break; ++ case RTW_HCI_TYPE_USB: ++ rtw8723xu_efuse_parsing(efuse, map); ++ break; ++ case RTW_HCI_TYPE_SDIO: ++ rtw8723xs_efuse_parsing(efuse, map); ++ break; ++ default: ++ /* unsupported now */ ++ return -EOPNOTSUPP; ++ } ++ ++ return 0; ++} ++ ++#define BIT_CFENDFORM BIT(9) ++#define BIT_WMAC_TCR_ERR0 BIT(12) ++#define BIT_WMAC_TCR_ERR1 BIT(13) ++#define BIT_TCR_CFG (BIT_CFENDFORM | BIT_WMAC_TCR_ERR0 | \ ++ BIT_WMAC_TCR_ERR1) ++#define WLAN_RX_FILTER0 0xFFFF ++#define WLAN_RX_FILTER1 0x400 ++#define WLAN_RX_FILTER2 0xFFFF ++#define WLAN_RCR_CFG 0x700060CE ++ ++static int __rtw8723x_mac_init(struct rtw_dev *rtwdev) ++{ ++ rtw_write8(rtwdev, REG_FWHW_TXQ_CTRL + 1, WLAN_TXQ_RPT_EN); ++ rtw_write32(rtwdev, REG_TCR, BIT_TCR_CFG); ++ ++ rtw_write16(rtwdev, REG_RXFLTMAP0, WLAN_RX_FILTER0); ++ rtw_write16(rtwdev, REG_RXFLTMAP1, WLAN_RX_FILTER1); ++ rtw_write16(rtwdev, REG_RXFLTMAP2, WLAN_RX_FILTER2); ++ rtw_write32(rtwdev, REG_RCR, WLAN_RCR_CFG); ++ ++ rtw_write32(rtwdev, REG_INT_MIG, 0); ++ rtw_write32(rtwdev, REG_MCUTST_1, 0x0); ++ ++ rtw_write8(rtwdev, REG_MISC_CTRL, BIT_DIS_SECOND_CCA); ++ rtw_write8(rtwdev, REG_2ND_CCA_CTRL, 0); ++ ++ return 0; ++} ++ ++static void __rtw8723x_cfg_ldo25(struct rtw_dev *rtwdev, bool enable) ++{ ++ u8 ldo_pwr; ++ ++ ldo_pwr = rtw_read8(rtwdev, REG_LDO_EFUSE_CTRL + 3); ++ if (enable) { ++ ldo_pwr &= ~BIT_MASK_LDO25_VOLTAGE; ++ ldo_pwr |= (BIT_LDO25_VOLTAGE_V25 << 4) | BIT_LDO25_EN; ++ } else { ++ ldo_pwr &= ~BIT_LDO25_EN; ++ } ++ rtw_write8(rtwdev, REG_LDO_EFUSE_CTRL + 3, ldo_pwr); ++} ++ ++static void ++rtw8723x_set_tx_power_index_by_rate(struct rtw_dev *rtwdev, u8 path, u8 rs) ++{ ++ struct rtw_hal *hal = &rtwdev->hal; ++ const struct rtw_hw_reg *txagc; ++ 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]; ++ ++ if (rate >= ARRAY_SIZE(rtw8723x_txagc)) { ++ rtw_warn(rtwdev, "rate 0x%x isn't supported\n", rate); ++ continue; ++ } ++ txagc = &rtw8723x_txagc[rate]; ++ if (!txagc->addr) { ++ rtw_warn(rtwdev, "rate 0x%x isn't defined\n", rate); ++ continue; ++ } ++ ++ rtw_write32_mask(rtwdev, txagc->addr, txagc->mask, pwr_index); ++ } ++} ++ ++static void __rtw8723x_set_tx_power_index(struct rtw_dev *rtwdev) ++{ ++ struct rtw_hal *hal = &rtwdev->hal; ++ int rs, path; ++ ++ for (path = 0; path < hal->rf_path_num; path++) { ++ for (rs = 0; rs <= RTW_RATE_SECTION_HT_1S; rs++) ++ rtw8723x_set_tx_power_index_by_rate(rtwdev, path, rs); ++ } ++} ++ ++static void __rtw8723x_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 __rtw8723x_false_alarm_statistics(struct rtw_dev *rtwdev) ++{ ++ struct rtw_dm_info *dm_info = &rtwdev->dm_info; ++ u32 cck_fa_cnt; ++ u32 ofdm_fa_cnt; ++ u32 crc32_cnt; ++ u32 val32; ++ ++ /* hold counter */ ++ rtw_write32_mask(rtwdev, REG_OFDM_FA_HOLDC_11N, BIT_MASK_OFDM_FA_KEEP, 1); ++ rtw_write32_mask(rtwdev, REG_OFDM_FA_RSTD_11N, BIT_MASK_OFDM_FA_KEEP1, 1); ++ rtw_write32_mask(rtwdev, REG_CCK_FA_RST_11N, BIT_MASK_CCK_CNT_KEEP, 1); ++ rtw_write32_mask(rtwdev, REG_CCK_FA_RST_11N, BIT_MASK_CCK_FA_KEEP, 1); ++ ++ cck_fa_cnt = rtw_read32_mask(rtwdev, REG_CCK_FA_LSB_11N, MASKBYTE0); ++ cck_fa_cnt += rtw_read32_mask(rtwdev, REG_CCK_FA_MSB_11N, MASKBYTE3) << 8; ++ ++ val32 = rtw_read32(rtwdev, REG_OFDM_FA_TYPE1_11N); ++ ofdm_fa_cnt = u32_get_bits(val32, BIT_MASK_OFDM_FF_CNT); ++ ofdm_fa_cnt += u32_get_bits(val32, BIT_MASK_OFDM_SF_CNT); ++ val32 = rtw_read32(rtwdev, REG_OFDM_FA_TYPE2_11N); ++ dm_info->ofdm_cca_cnt = u32_get_bits(val32, BIT_MASK_OFDM_CCA_CNT); ++ ofdm_fa_cnt += u32_get_bits(val32, BIT_MASK_OFDM_PF_CNT); ++ val32 = rtw_read32(rtwdev, REG_OFDM_FA_TYPE3_11N); ++ ofdm_fa_cnt += u32_get_bits(val32, BIT_MASK_OFDM_RI_CNT); ++ ofdm_fa_cnt += u32_get_bits(val32, BIT_MASK_OFDM_CRC_CNT); ++ val32 = rtw_read32(rtwdev, REG_OFDM_FA_TYPE4_11N); ++ ofdm_fa_cnt += u32_get_bits(val32, BIT_MASK_OFDM_MNS_CNT); ++ ++ dm_info->cck_fa_cnt = cck_fa_cnt; ++ dm_info->ofdm_fa_cnt = ofdm_fa_cnt; ++ dm_info->total_fa_cnt = cck_fa_cnt + ofdm_fa_cnt; ++ ++ dm_info->cck_err_cnt = rtw_read32(rtwdev, REG_IGI_C_11N); ++ dm_info->cck_ok_cnt = rtw_read32(rtwdev, REG_IGI_D_11N); ++ crc32_cnt = rtw_read32(rtwdev, REG_OFDM_CRC32_CNT_11N); ++ dm_info->ofdm_err_cnt = u32_get_bits(crc32_cnt, BIT_MASK_OFDM_LCRC_ERR); ++ dm_info->ofdm_ok_cnt = u32_get_bits(crc32_cnt, BIT_MASK_OFDM_LCRC_OK); ++ crc32_cnt = rtw_read32(rtwdev, REG_HT_CRC32_CNT_11N); ++ dm_info->ht_err_cnt = u32_get_bits(crc32_cnt, BIT_MASK_HT_CRC_ERR); ++ dm_info->ht_ok_cnt = u32_get_bits(crc32_cnt, BIT_MASK_HT_CRC_OK); ++ dm_info->vht_err_cnt = 0; ++ dm_info->vht_ok_cnt = 0; ++ ++ val32 = rtw_read32(rtwdev, REG_CCK_CCA_CNT_11N); ++ dm_info->cck_cca_cnt = (u32_get_bits(val32, BIT_MASK_CCK_FA_MSB) << 8) | ++ u32_get_bits(val32, BIT_MASK_CCK_FA_LSB); ++ dm_info->total_cca_cnt = dm_info->cck_cca_cnt + dm_info->ofdm_cca_cnt; ++ ++ /* reset counter */ ++ rtw_write32_mask(rtwdev, REG_OFDM_FA_RSTC_11N, BIT_MASK_OFDM_FA_RST, 1); ++ rtw_write32_mask(rtwdev, REG_OFDM_FA_RSTC_11N, BIT_MASK_OFDM_FA_RST, 0); ++ rtw_write32_mask(rtwdev, REG_OFDM_FA_RSTD_11N, BIT_MASK_OFDM_FA_RST1, 1); ++ rtw_write32_mask(rtwdev, REG_OFDM_FA_RSTD_11N, BIT_MASK_OFDM_FA_RST1, 0); ++ rtw_write32_mask(rtwdev, REG_OFDM_FA_HOLDC_11N, BIT_MASK_OFDM_FA_KEEP, 0); ++ rtw_write32_mask(rtwdev, REG_OFDM_FA_RSTD_11N, BIT_MASK_OFDM_FA_KEEP1, 0); ++ rtw_write32_mask(rtwdev, REG_CCK_FA_RST_11N, BIT_MASK_CCK_CNT_KPEN, 0); ++ rtw_write32_mask(rtwdev, REG_CCK_FA_RST_11N, BIT_MASK_CCK_CNT_KPEN, 2); ++ rtw_write32_mask(rtwdev, REG_CCK_FA_RST_11N, BIT_MASK_CCK_FA_KPEN, 0); ++ rtw_write32_mask(rtwdev, REG_CCK_FA_RST_11N, BIT_MASK_CCK_FA_KPEN, 2); ++ rtw_write32_mask(rtwdev, REG_PAGE_F_RST_11N, BIT_MASK_F_RST_ALL, 1); ++ rtw_write32_mask(rtwdev, REG_PAGE_F_RST_11N, BIT_MASK_F_RST_ALL, 0); ++} ++ ++/* IQK (IQ calibration) */ ++ ++static ++void __rtw8723x_iqk_backup_regs(struct rtw_dev *rtwdev, ++ struct rtw8723x_iqk_backup_regs *backup) ++{ ++ int i; ++ ++ for (i = 0; i < RTW8723X_IQK_ADDA_REG_NUM; i++) ++ backup->adda[i] = rtw_read32(rtwdev, ++ rtw8723x_common.iqk_adda_regs[i]); ++ ++ for (i = 0; i < RTW8723X_IQK_MAC8_REG_NUM; i++) ++ backup->mac8[i] = rtw_read8(rtwdev, ++ rtw8723x_common.iqk_mac8_regs[i]); ++ for (i = 0; i < RTW8723X_IQK_MAC32_REG_NUM; i++) ++ backup->mac32[i] = rtw_read32(rtwdev, ++ rtw8723x_common.iqk_mac32_regs[i]); ++ ++ for (i = 0; i < RTW8723X_IQK_BB_REG_NUM; i++) ++ backup->bb[i] = rtw_read32(rtwdev, ++ rtw8723x_common.iqk_bb_regs[i]); ++ ++ backup->igia = rtw_read32_mask(rtwdev, REG_OFDM0_XAAGC1, MASKBYTE0); ++ backup->igib = rtw_read32_mask(rtwdev, REG_OFDM0_XBAGC1, MASKBYTE0); ++ ++ backup->bb_sel_btg = rtw_read32(rtwdev, REG_BB_SEL_BTG); ++} ++ ++static ++void __rtw8723x_iqk_restore_regs(struct rtw_dev *rtwdev, ++ const struct rtw8723x_iqk_backup_regs *backup) ++{ ++ int i; ++ ++ for (i = 0; i < RTW8723X_IQK_ADDA_REG_NUM; i++) ++ rtw_write32(rtwdev, rtw8723x_common.iqk_adda_regs[i], ++ backup->adda[i]); ++ ++ for (i = 0; i < RTW8723X_IQK_MAC8_REG_NUM; i++) ++ rtw_write8(rtwdev, rtw8723x_common.iqk_mac8_regs[i], ++ backup->mac8[i]); ++ for (i = 0; i < RTW8723X_IQK_MAC32_REG_NUM; i++) ++ rtw_write32(rtwdev, rtw8723x_common.iqk_mac32_regs[i], ++ backup->mac32[i]); ++ ++ for (i = 0; i < RTW8723X_IQK_BB_REG_NUM; i++) ++ rtw_write32(rtwdev, rtw8723x_common.iqk_bb_regs[i], ++ backup->bb[i]); ++ ++ rtw_write32_mask(rtwdev, REG_OFDM0_XAAGC1, MASKBYTE0, 0x50); ++ rtw_write32_mask(rtwdev, REG_OFDM0_XAAGC1, MASKBYTE0, backup->igia); ++ ++ rtw_write32_mask(rtwdev, REG_OFDM0_XBAGC1, MASKBYTE0, 0x50); ++ rtw_write32_mask(rtwdev, REG_OFDM0_XBAGC1, MASKBYTE0, backup->igib); ++ ++ rtw_write32(rtwdev, REG_TXIQK_TONE_A_11N, 0x01008c00); ++ rtw_write32(rtwdev, REG_RXIQK_TONE_A_11N, 0x01008c00); ++} ++ ++static ++bool __rtw8723x_iqk_similarity_cmp(struct rtw_dev *rtwdev, ++ s32 result[][IQK_NR], ++ u8 c1, u8 c2) ++{ ++ u32 i, j, diff; ++ u32 bitmap = 0; ++ u8 candidate[PATH_NR] = {IQK_ROUND_INVALID, IQK_ROUND_INVALID}; ++ bool ret = true; ++ ++ s32 tmp1, tmp2; ++ ++ for (i = 0; i < IQK_NR; i++) { ++ tmp1 = iqkxy_to_s32(result[c1][i]); ++ tmp2 = iqkxy_to_s32(result[c2][i]); ++ ++ diff = abs(tmp1 - tmp2); ++ ++ if (diff <= MAX_TOLERANCE) ++ continue; ++ ++ if ((i == IQK_S1_RX_X || i == IQK_S0_RX_X) && !bitmap) { ++ if (result[c1][i] + result[c1][i + 1] == 0) ++ candidate[i / IQK_SX_NR] = c2; ++ else if (result[c2][i] + result[c2][i + 1] == 0) ++ candidate[i / IQK_SX_NR] = c1; ++ else ++ bitmap |= BIT(i); ++ } else { ++ bitmap |= BIT(i); ++ } ++ } ++ ++ if (bitmap != 0) ++ goto check_sim; ++ ++ for (i = 0; i < PATH_NR; i++) { ++ if (candidate[i] == IQK_ROUND_INVALID) ++ continue; ++ ++ for (j = i * IQK_SX_NR; j < i * IQK_SX_NR + 2; j++) ++ result[IQK_ROUND_HYBRID][j] = result[candidate[i]][j]; ++ ret = false; ++ } ++ ++ return ret; ++ ++check_sim: ++ for (i = 0; i < IQK_NR; i++) { ++ j = i & ~1; /* 2 bits are a pair for IQ[X, Y] */ ++ if (bitmap & GENMASK(j + 1, j)) ++ continue; ++ ++ result[IQK_ROUND_HYBRID][i] = result[c1][i]; ++ } ++ ++ return false; ++} ++ ++static u8 __rtw8723x_pwrtrack_get_limit_ofdm(struct rtw_dev *rtwdev) ++{ ++ struct rtw_dm_info *dm_info = &rtwdev->dm_info; ++ u8 tx_rate = dm_info->tx_rate; ++ u8 limit_ofdm = 30; ++ ++ switch (tx_rate) { ++ case DESC_RATE1M...DESC_RATE5_5M: ++ case DESC_RATE11M: ++ break; ++ case DESC_RATE6M...DESC_RATE48M: ++ limit_ofdm = 36; ++ break; ++ case DESC_RATE54M: ++ limit_ofdm = 34; ++ break; ++ case DESC_RATEMCS0...DESC_RATEMCS2: ++ limit_ofdm = 38; ++ break; ++ case DESC_RATEMCS3...DESC_RATEMCS4: ++ limit_ofdm = 36; ++ break; ++ case DESC_RATEMCS5...DESC_RATEMCS7: ++ limit_ofdm = 34; ++ break; ++ default: ++ rtw_warn(rtwdev, "pwrtrack unhandled tx_rate 0x%x\n", tx_rate); ++ break; ++ } ++ ++ return limit_ofdm; ++} ++ ++static ++void __rtw8723x_pwrtrack_set_xtal(struct rtw_dev *rtwdev, u8 therm_path, ++ u8 delta) ++{ ++ struct rtw_dm_info *dm_info = &rtwdev->dm_info; ++ const struct rtw_pwr_track_tbl *tbl = rtwdev->chip->pwr_track_tbl; ++ const s8 *pwrtrk_xtal; ++ s8 xtal_cap; ++ ++ if (dm_info->thermal_avg[therm_path] > ++ rtwdev->efuse.thermal_meter[therm_path]) ++ pwrtrk_xtal = tbl->pwrtrk_xtal_p; ++ else ++ pwrtrk_xtal = tbl->pwrtrk_xtal_n; ++ ++ xtal_cap = rtwdev->efuse.crystal_cap & 0x3F; ++ xtal_cap = clamp_t(s8, xtal_cap + pwrtrk_xtal[delta], 0, 0x3F); ++ rtw_write32_mask(rtwdev, REG_AFE_CTRL3, BIT_MASK_XTAL, ++ xtal_cap | (xtal_cap << 6)); ++} ++ ++static ++void __rtw8723x_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) */ ++ __le16 chksum = 0; ++ __le16 *data = (__le16 *)(txdesc); ++ struct rtw_tx_desc *tx_desc = (struct rtw_tx_desc *)txdesc; ++ ++ le32p_replace_bits(&tx_desc->w7, 0, RTW_TX_DESC_W7_TXDESC_CHECKSUM); ++ ++ while (words--) ++ chksum ^= *data++; ++ ++ chksum = ~chksum; ++ ++ le32p_replace_bits(&tx_desc->w7, __le16_to_cpu(chksum), ++ RTW_TX_DESC_W7_TXDESC_CHECKSUM); ++} ++ ++static void __rtw8723x_coex_cfg_init(struct rtw_dev *rtwdev) ++{ ++ /* enable TBTT nterrupt */ ++ rtw_write8_set(rtwdev, REG_BCN_CTRL, BIT_EN_BCN_FUNCTION); ++ ++ /* BT report packet sample rate */ ++ /* 0x790[5:0]=0x5 */ ++ rtw_write8_mask(rtwdev, REG_BT_TDMA_TIME, BIT_MASK_SAMPLE_RATE, 0x5); ++ ++ /* enable BT counter statistics */ ++ rtw_write8(rtwdev, REG_BT_STAT_CTRL, 0x1); ++ ++ /* enable PTA (3-wire function form BT side) */ ++ rtw_write32_set(rtwdev, REG_GPIO_MUXCFG, BIT_BT_PTA_EN); ++ rtw_write32_set(rtwdev, REG_GPIO_MUXCFG, BIT_PO_BT_PTA_PINS); ++ ++ /* enable PTA (tx/rx signal form WiFi side) */ ++ rtw_write8_set(rtwdev, REG_QUEUE_CTRL, BIT_PTA_WL_TX_EN); ++} ++ ++const struct rtw8723x_common rtw8723x_common = { ++ .iqk_adda_regs = { ++ 0x85c, 0xe6c, 0xe70, 0xe74, 0xe78, 0xe7c, 0xe80, 0xe84, ++ 0xe88, 0xe8c, 0xed0, 0xed4, 0xed8, 0xedc, 0xee0, 0xeec ++ }, ++ .iqk_mac8_regs = {0x522, 0x550, 0x551}, ++ .iqk_mac32_regs = {0x40}, ++ .iqk_bb_regs = { ++ 0xc04, 0xc08, 0x874, 0xb68, 0xb6c, 0x870, 0x860, 0x864, 0xa04 ++ }, ++ ++ .ltecoex_addr = { ++ .ctrl = REG_LTECOEX_CTRL, ++ .wdata = REG_LTECOEX_WRITE_DATA, ++ .rdata = REG_LTECOEX_READ_DATA, ++ }, ++ .rf_sipi_addr = { ++ [RF_PATH_A] = { .hssi_1 = 0x820, .lssi_read = 0x8a0, ++ .hssi_2 = 0x824, .lssi_read_pi = 0x8b8}, ++ [RF_PATH_B] = { .hssi_1 = 0x828, .lssi_read = 0x8a4, ++ .hssi_2 = 0x82c, .lssi_read_pi = 0x8bc}, ++ }, ++ .dig = { ++ [0] = { .addr = 0xc50, .mask = 0x7f }, ++ [1] = { .addr = 0xc50, .mask = 0x7f }, ++ }, ++ .dig_cck = { ++ [0] = { .addr = 0xa0c, .mask = 0x3f00 }, ++ }, ++ .prioq_addrs = { ++ .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, ++ }, ++ ++ .lck = __rtw8723x_lck, ++ .read_efuse = __rtw8723x_read_efuse, ++ .mac_init = __rtw8723x_mac_init, ++ .cfg_ldo25 = __rtw8723x_cfg_ldo25, ++ .set_tx_power_index = __rtw8723x_set_tx_power_index, ++ .efuse_grant = __rtw8723x_efuse_grant, ++ .false_alarm_statistics = __rtw8723x_false_alarm_statistics, ++ .iqk_backup_regs = __rtw8723x_iqk_backup_regs, ++ .iqk_restore_regs = __rtw8723x_iqk_restore_regs, ++ .iqk_similarity_cmp = __rtw8723x_iqk_similarity_cmp, ++ .pwrtrack_get_limit_ofdm = __rtw8723x_pwrtrack_get_limit_ofdm, ++ .pwrtrack_set_xtal = __rtw8723x_pwrtrack_set_xtal, ++ .coex_cfg_init = __rtw8723x_coex_cfg_init, ++ .fill_txdesc_checksum = __rtw8723x_fill_txdesc_checksum, ++}; ++EXPORT_SYMBOL(rtw8723x_common); ++ ++MODULE_AUTHOR("Realtek Corporation"); ++MODULE_AUTHOR("Fiona Klute "); ++MODULE_DESCRIPTION("Common functions for Realtek 802.11n wireless 8723x drivers"); ++MODULE_LICENSE("Dual BSD/GPL"); +diff --git a/drivers/net/wireless/realtek/rtw88/rtw8723x.h b/drivers/net/wireless/realtek/rtw88/rtw8723x.h +new file mode 100644 +index 00000000000000..cace285fc03397 +--- /dev/null ++++ b/drivers/net/wireless/realtek/rtw88/rtw8723x.h +@@ -0,0 +1,496 @@ ++/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */ ++/* Copyright 2024 Fiona Klute ++ * ++ * Based on code originally in rtw8723d.[ch], ++ * Copyright(c) 2018-2019 Realtek Corporation ++ */ ++ ++#ifndef __RTW8723X_H__ ++#define __RTW8723X_H__ ++ ++#include "main.h" ++#include "debug.h" ++#include "phy.h" ++#include "reg.h" ++ ++enum rtw8723x_path { ++ PATH_S1, ++ PATH_S0, ++ PATH_NR, ++}; ++ ++enum rtw8723x_iqk_round { ++ IQK_ROUND_0, ++ IQK_ROUND_1, ++ IQK_ROUND_2, ++ IQK_ROUND_HYBRID, ++ IQK_ROUND_SIZE, ++ IQK_ROUND_INVALID = 0xff, ++}; ++ ++enum rtw8723x_iqk_result { ++ IQK_S1_TX_X, ++ IQK_S1_TX_Y, ++ IQK_S1_RX_X, ++ IQK_S1_RX_Y, ++ IQK_S0_TX_X, ++ IQK_S0_TX_Y, ++ IQK_S0_RX_X, ++ IQK_S0_RX_Y, ++ IQK_NR, ++ IQK_SX_NR = IQK_NR / PATH_NR, ++}; ++ ++struct rtw8723xe_efuse { ++ u8 mac_addr[ETH_ALEN]; /* 0xd0 */ ++ u8 vendor_id[2]; ++ u8 device_id[2]; ++ u8 sub_vendor_id[2]; ++ u8 sub_device_id[2]; ++}; ++ ++struct rtw8723xu_efuse { ++ u8 res4[48]; /* 0xd0 */ ++ u8 vendor_id[2]; /* 0x100 */ ++ u8 product_id[2]; /* 0x102 */ ++ u8 usb_option; /* 0x104 */ ++ u8 res5[2]; /* 0x105 */ ++ u8 mac_addr[ETH_ALEN]; /* 0x107 */ ++}; ++ ++struct rtw8723xs_efuse { ++ u8 res4[0x4a]; /* 0xd0 */ ++ u8 mac_addr[ETH_ALEN]; /* 0x11a */ ++}; ++ ++struct rtw8723x_efuse { ++ __le16 rtl_id; ++ u8 rsvd[2]; ++ u8 afe; ++ u8 rsvd1[11]; ++ ++ /* 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[2]; /* 0xbd */ ++ u8 lna_type_5g[2]; ++ u8 rf_board_option; ++ u8 rf_feature_option; ++ u8 rf_bt_setting; ++ u8 eeprom_version; ++ u8 eeprom_customer_id; ++ u8 tx_bb_swing_setting_2g; ++ u8 res_c7; ++ u8 tx_pwr_calibrate_rate; ++ u8 rf_antenna_option; /* 0xc9 */ ++ u8 rfe_option; ++ u8 country_code[2]; ++ u8 res[3]; ++ union { ++ struct rtw8723xe_efuse e; ++ struct rtw8723xu_efuse u; ++ struct rtw8723xs_efuse s; ++ }; ++}; ++ ++#define RTW8723X_IQK_ADDA_REG_NUM 16 ++#define RTW8723X_IQK_MAC8_REG_NUM 3 ++#define RTW8723X_IQK_MAC32_REG_NUM 1 ++#define RTW8723X_IQK_BB_REG_NUM 9 ++ ++struct rtw8723x_iqk_backup_regs { ++ u32 adda[RTW8723X_IQK_ADDA_REG_NUM]; ++ u8 mac8[RTW8723X_IQK_MAC8_REG_NUM]; ++ u32 mac32[RTW8723X_IQK_MAC32_REG_NUM]; ++ u32 bb[RTW8723X_IQK_BB_REG_NUM]; ++ ++ u32 lte_path; ++ u32 lte_gnt; ++ ++ u32 bb_sel_btg; ++ u8 btg_sel; ++ ++ u8 igia; ++ u8 igib; ++}; ++ ++struct rtw8723x_common { ++ /* registers that must be backed up before IQK and restored after */ ++ u32 iqk_adda_regs[RTW8723X_IQK_ADDA_REG_NUM]; ++ u32 iqk_mac8_regs[RTW8723X_IQK_MAC8_REG_NUM]; ++ u32 iqk_mac32_regs[RTW8723X_IQK_MAC32_REG_NUM]; ++ u32 iqk_bb_regs[RTW8723X_IQK_BB_REG_NUM]; ++ ++ /* chip register definitions */ ++ struct rtw_ltecoex_addr ltecoex_addr; ++ struct rtw_rf_sipi_addr rf_sipi_addr[2]; ++ struct rtw_hw_reg dig[2]; ++ struct rtw_hw_reg dig_cck[1]; ++ struct rtw_prioq_addrs prioq_addrs; ++ ++ /* common functions */ ++ void (*lck)(struct rtw_dev *rtwdev); ++ int (*read_efuse)(struct rtw_dev *rtwdev, u8 *log_map); ++ int (*mac_init)(struct rtw_dev *rtwdev); ++ 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 (*false_alarm_statistics)(struct rtw_dev *rtwdev); ++ void (*iqk_backup_regs)(struct rtw_dev *rtwdev, ++ struct rtw8723x_iqk_backup_regs *backup); ++ void (*iqk_restore_regs)(struct rtw_dev *rtwdev, ++ const struct rtw8723x_iqk_backup_regs *backup); ++ bool (*iqk_similarity_cmp)(struct rtw_dev *rtwdev, s32 result[][IQK_NR], ++ u8 c1, u8 c2); ++ u8 (*pwrtrack_get_limit_ofdm)(struct rtw_dev *rtwdev); ++ void (*pwrtrack_set_xtal)(struct rtw_dev *rtwdev, u8 therm_path, ++ u8 delta); ++ void (*coex_cfg_init)(struct rtw_dev *rtwdev); ++ void (*fill_txdesc_checksum)(struct rtw_dev *rtwdev, ++ struct rtw_tx_pkt_info *pkt_info, ++ u8 *txdesc); ++}; ++ ++extern const struct rtw8723x_common rtw8723x_common; ++ ++#define PATH_IQK_RETRY 2 ++#define MAX_TOLERANCE 5 ++#define IQK_TX_X_ERR 0x142 ++#define IQK_TX_Y_ERR 0x42 ++#define IQK_RX_X_UPPER 0x11a ++#define IQK_RX_X_LOWER 0xe6 ++#define IQK_RX_Y_LMT 0x1a ++#define IQK_TX_OK BIT(0) ++#define IQK_RX_OK BIT(1) ++ ++#define WLAN_TXQ_RPT_EN 0x1F ++ ++#define SPUR_THRES 0x16 ++#define DIS_3WIRE 0xccf000c0 ++#define EN_3WIRE 0xccc000c0 ++#define START_PSD 0x400000 ++#define FREQ_CH13 0xfccd ++#define FREQ_CH14 0xff9a ++#define RFCFGCH_CHANNEL_MASK GENMASK(7, 0) ++#define RFCFGCH_BW_MASK (BIT(11) | BIT(10)) ++#define RFCFGCH_BW_20M (BIT(11) | BIT(10)) ++#define RFCFGCH_BW_40M BIT(10) ++#define BIT_MASK_RFMOD BIT(0) ++#define BIT_LCK BIT(15) ++ ++#define REG_GPIO_INTM 0x0048 ++#define REG_BTG_SEL 0x0067 ++#define BIT_MASK_BTG_WL BIT(7) ++#define REG_LTECOEX_PATH_CONTROL 0x0070 ++#define REG_LTECOEX_CTRL 0x07c0 ++#define REG_LTECOEX_WRITE_DATA 0x07c4 ++#define REG_LTECOEX_READ_DATA 0x07c8 ++#define REG_PSDFN 0x0808 ++#define REG_BB_PWR_SAV1_11N 0x0874 ++#define REG_ANA_PARAM1 0x0880 ++#define REG_ANALOG_P4 0x088c ++#define REG_PSDRPT 0x08b4 ++#define REG_FPGA1_RFMOD 0x0900 ++#define REG_BB_SEL_BTG 0x0948 ++#define REG_BBRX_DFIR 0x0954 ++#define BIT_MASK_RXBB_DFIR GENMASK(27, 24) ++#define BIT_RXBB_DFIR_EN BIT(19) ++#define REG_CCK0_SYS 0x0a00 ++#define BIT_CCK_SIDE_BAND BIT(4) ++#define REG_CCK_ANT_SEL_11N 0x0a04 ++#define REG_PWRTH 0x0a08 ++#define REG_CCK_FA_RST_11N 0x0a2c ++#define BIT_MASK_CCK_CNT_KEEP BIT(12) ++#define BIT_MASK_CCK_CNT_EN BIT(13) ++#define BIT_MASK_CCK_CNT_KPEN (BIT_MASK_CCK_CNT_KEEP | BIT_MASK_CCK_CNT_EN) ++#define BIT_MASK_CCK_FA_KEEP BIT(14) ++#define BIT_MASK_CCK_FA_EN BIT(15) ++#define BIT_MASK_CCK_FA_KPEN (BIT_MASK_CCK_FA_KEEP | BIT_MASK_CCK_FA_EN) ++#define REG_CCK_FA_LSB_11N 0x0a5c ++#define REG_CCK_FA_MSB_11N 0x0a58 ++#define REG_CCK_CCA_CNT_11N 0x0a60 ++#define BIT_MASK_CCK_FA_MSB GENMASK(7, 0) ++#define BIT_MASK_CCK_FA_LSB GENMASK(15, 8) ++#define REG_PWRTH2 0x0aa8 ++#define REG_CSRATIO 0x0aaa ++#define REG_OFDM_FA_HOLDC_11N 0x0c00 ++#define BIT_MASK_OFDM_FA_KEEP BIT(31) ++#define REG_BB_RX_PATH_11N 0x0c04 ++#define REG_TRMUX_11N 0x0c08 ++#define REG_OFDM_FA_RSTC_11N 0x0c0c ++#define BIT_MASK_OFDM_FA_RST BIT(31) ++#define REG_A_RXIQI 0x0c14 ++#define BIT_MASK_RXIQ_S1_X 0x000003FF ++#define BIT_MASK_RXIQ_S1_Y1 0x0000FC00 ++#define BIT_SET_RXIQ_S1_Y1(y) ((y) & 0x3F) ++#define REG_OFDM0_RXDSP 0x0c40 ++#define BIT_MASK_RXDSP GENMASK(28, 24) ++#define BIT_EN_RXDSP BIT(9) ++#define REG_OFDM_0_ECCA_THRESHOLD 0x0c4c ++#define BIT_MASK_OFDM0_EXT_A BIT(31) ++#define BIT_MASK_OFDM0_EXT_C BIT(29) ++#define BIT_MASK_OFDM0_EXTS (BIT(31) | BIT(29) | BIT(28)) ++#define BIT_SET_OFDM0_EXTS(a, c, d) (((a) << 31) | ((c) << 29) | ((d) << 28)) ++#define REG_OFDM0_XAAGC1 0x0c50 ++#define REG_OFDM0_XBAGC1 0x0c58 ++#define REG_AGCRSSI 0x0c78 ++#define REG_OFDM_0_XA_TX_IQ_IMBALANCE 0x0c80 ++#define BIT_MASK_TXIQ_ELM_A 0x03ff ++#define BIT_SET_TXIQ_ELM_ACD(a, c, d) (((d) << 22) | (((c) & 0x3F) << 16) | \ ++ ((a) & 0x03ff)) ++#define BIT_MASK_TXIQ_ELM_C GENMASK(21, 16) ++#define BIT_SET_TXIQ_ELM_C2(c) ((c) & 0x3F) ++#define BIT_MASK_TXIQ_ELM_D GENMASK(31, 22) ++#define REG_TXIQK_MATRIXA_LSB2_11N 0x0c94 ++#define BIT_SET_TXIQ_ELM_C1(c) (((c) & 0x000003C0) >> 6) ++#define REG_RXIQK_MATRIX_LSB_11N 0x0ca0 ++#define BIT_MASK_RXIQ_S1_Y2 0xF0000000 ++#define BIT_SET_RXIQ_S1_Y2(y) (((y) >> 6) & 0xF) ++#define REG_TXIQ_AB_S0 0x0cd0 ++#define BIT_MASK_TXIQ_A_S0 0x000007FE ++#define BIT_MASK_TXIQ_A_EXT_S0 BIT(0) ++#define BIT_MASK_TXIQ_B_S0 0x0007E000 ++#define REG_TXIQ_CD_S0 0x0cd4 ++#define BIT_MASK_TXIQ_C_S0 0x000007FE ++#define BIT_MASK_TXIQ_C_EXT_S0 BIT(0) ++#define BIT_MASK_TXIQ_D_S0 GENMASK(22, 13) ++#define BIT_MASK_TXIQ_D_EXT_S0 BIT(12) ++#define REG_RXIQ_AB_S0 0x0cd8 ++#define BIT_MASK_RXIQ_X_S0 0x000003FF ++#define BIT_MASK_RXIQ_Y_S0 0x003FF000 ++#define REG_OFDM_FA_TYPE1_11N 0x0cf0 ++#define BIT_MASK_OFDM_FF_CNT GENMASK(15, 0) ++#define BIT_MASK_OFDM_SF_CNT GENMASK(31, 16) ++#define REG_OFDM_FA_RSTD_11N 0x0d00 ++#define BIT_MASK_OFDM_FA_RST1 BIT(27) ++#define BIT_MASK_OFDM_FA_KEEP1 BIT(31) ++#define REG_CTX 0x0d03 ++#define BIT_MASK_CTX_TYPE GENMASK(6, 4) ++#define REG_OFDM1_CFOTRK 0x0d2c ++#define BIT_EN_CFOTRK BIT(28) ++#define REG_OFDM1_CSI1 0x0d40 ++#define REG_OFDM1_CSI2 0x0d44 ++#define REG_OFDM1_CSI3 0x0d48 ++#define REG_OFDM1_CSI4 0x0d4c ++#define REG_OFDM_FA_TYPE2_11N 0x0da0 ++#define BIT_MASK_OFDM_CCA_CNT GENMASK(15, 0) ++#define BIT_MASK_OFDM_PF_CNT GENMASK(31, 16) ++#define REG_OFDM_FA_TYPE3_11N 0x0da4 ++#define BIT_MASK_OFDM_RI_CNT GENMASK(15, 0) ++#define BIT_MASK_OFDM_CRC_CNT GENMASK(31, 16) ++#define REG_OFDM_FA_TYPE4_11N 0x0da8 ++#define BIT_MASK_OFDM_MNS_CNT GENMASK(15, 0) ++#define REG_FPGA0_IQK_11N 0x0e28 ++#define BIT_MASK_IQK_MOD 0xffffff00 ++#define EN_IQK 0x808000 ++#define RST_IQK 0x000000 ++#define REG_TXIQK_TONE_A_11N 0x0e30 ++#define REG_RXIQK_TONE_A_11N 0x0e34 ++#define REG_TXIQK_PI_A_11N 0x0e38 ++#define REG_RXIQK_PI_A_11N 0x0e3c ++#define REG_TXIQK_11N 0x0e40 ++#define BIT_SET_TXIQK_11N(x, y) (0x80007C00 | ((x) << 16) | (y)) ++#define REG_RXIQK_11N 0x0e44 ++#define REG_IQK_AGC_PTS_11N 0x0e48 ++#define REG_IQK_AGC_RSP_11N 0x0e4c ++#define REG_TX_IQK_TONE_B 0x0e50 ++#define REG_RX_IQK_TONE_B 0x0e54 ++#define REG_IQK_RES_TX 0x0e94 ++#define BIT_MASK_RES_TX GENMASK(25, 16) ++#define REG_IQK_RES_TY 0x0e9c ++#define BIT_MASK_RES_TY GENMASK(25, 16) ++#define REG_IQK_RES_RX 0x0ea4 ++#define BIT_MASK_RES_RX GENMASK(25, 16) ++#define REG_IQK_RES_RY 0x0eac ++#define BIT_IQK_TX_FAIL BIT(28) ++#define BIT_IQK_RX_FAIL BIT(27) ++#define BIT_IQK_DONE BIT(26) ++#define BIT_MASK_RES_RY GENMASK(25, 16) ++#define REG_PAGE_F_RST_11N 0x0f14 ++#define BIT_MASK_F_RST_ALL BIT(16) ++#define REG_IGI_C_11N 0x0f84 ++#define REG_IGI_D_11N 0x0f88 ++#define REG_HT_CRC32_CNT_11N 0x0f90 ++#define BIT_MASK_HT_CRC_OK GENMASK(15, 0) ++#define BIT_MASK_HT_CRC_ERR GENMASK(31, 16) ++#define REG_OFDM_CRC32_CNT_11N 0x0f94 ++#define BIT_MASK_OFDM_LCRC_OK GENMASK(15, 0) ++#define BIT_MASK_OFDM_LCRC_ERR GENMASK(31, 16) ++#define REG_HT_CRC32_CNT_11N_AGG 0x0fb8 ++ ++#define OFDM_SWING_A(swing) FIELD_GET(GENMASK(9, 0), swing) ++#define OFDM_SWING_B(swing) FIELD_GET(GENMASK(15, 10), swing) ++#define OFDM_SWING_C(swing) FIELD_GET(GENMASK(21, 16), swing) ++#define OFDM_SWING_D(swing) FIELD_GET(GENMASK(31, 22), swing) ++ ++static inline s32 iqkxy_to_s32(s32 val) ++{ ++ /* val is Q10.8 */ ++ return sign_extend32(val, 9); ++} ++ ++static inline s32 iqk_mult(s32 x, s32 y, s32 *ext) ++{ ++ /* x, y and return value are Q10.8 */ ++ s32 t; ++ ++ t = x * y; ++ if (ext) ++ *ext = (t >> 7) & 0x1; /* Q.16 --> Q.9; get LSB of Q.9 */ ++ ++ return (t >> 8); /* Q.16 --> Q.8 */ ++} ++ ++static inline void rtw8723x_lck(struct rtw_dev *rtwdev) ++{ ++ rtw8723x_common.lck(rtwdev); ++} ++ ++static inline int rtw8723x_read_efuse(struct rtw_dev *rtwdev, u8 *log_map) ++{ ++ return rtw8723x_common.read_efuse(rtwdev, log_map); ++} ++ ++static inline int rtw8723x_mac_init(struct rtw_dev *rtwdev) ++{ ++ return rtw8723x_common.mac_init(rtwdev); ++} ++ ++static inline void rtw8723x_cfg_ldo25(struct rtw_dev *rtwdev, bool enable) ++{ ++ rtw8723x_common.cfg_ldo25(rtwdev, enable); ++} ++ ++static inline void rtw8723x_set_tx_power_index(struct rtw_dev *rtwdev) ++{ ++ rtw8723x_common.set_tx_power_index(rtwdev); ++} ++ ++static inline void rtw8723x_efuse_grant(struct rtw_dev *rtwdev, bool on) ++{ ++ rtw8723x_common.efuse_grant(rtwdev, on); ++} ++ ++static inline void rtw8723x_false_alarm_statistics(struct rtw_dev *rtwdev) ++{ ++ rtw8723x_common.false_alarm_statistics(rtwdev); ++} ++ ++static inline ++void rtw8723x_iqk_backup_regs(struct rtw_dev *rtwdev, ++ struct rtw8723x_iqk_backup_regs *backup) ++{ ++ rtw8723x_common.iqk_backup_regs(rtwdev, backup); ++} ++ ++static inline ++void rtw8723x_iqk_restore_regs(struct rtw_dev *rtwdev, ++ const struct rtw8723x_iqk_backup_regs *backup) ++{ ++ rtw8723x_common.iqk_restore_regs(rtwdev, backup); ++} ++ ++static inline ++bool rtw8723x_iqk_similarity_cmp(struct rtw_dev *rtwdev, s32 result[][IQK_NR], ++ u8 c1, u8 c2) ++{ ++ return rtw8723x_common.iqk_similarity_cmp(rtwdev, result, c1, c2); ++} ++ ++static inline u8 rtw8723x_pwrtrack_get_limit_ofdm(struct rtw_dev *rtwdev) ++{ ++ return rtw8723x_common.pwrtrack_get_limit_ofdm(rtwdev); ++} ++ ++static inline ++void rtw8723x_pwrtrack_set_xtal(struct rtw_dev *rtwdev, u8 therm_path, ++ u8 delta) ++{ ++ rtw8723x_common.pwrtrack_set_xtal(rtwdev, therm_path, delta); ++} ++ ++static inline void rtw8723x_coex_cfg_init(struct rtw_dev *rtwdev) ++{ ++ rtw8723x_common.coex_cfg_init(rtwdev); ++} ++ ++static inline ++void rtw8723x_fill_txdesc_checksum(struct rtw_dev *rtwdev, ++ struct rtw_tx_pkt_info *pkt_info, ++ u8 *txdesc) ++{ ++ rtw8723x_common.fill_txdesc_checksum(rtwdev, pkt_info, txdesc); ++} ++ ++/* IQK helper functions, defined as inline so they can be shared ++ * without needing an EXPORT_SYMBOL each. ++ */ ++static inline void ++rtw8723x_iqk_backup_path_ctrl(struct rtw_dev *rtwdev, ++ struct rtw8723x_iqk_backup_regs *backup) ++{ ++ backup->btg_sel = rtw_read8(rtwdev, REG_BTG_SEL); ++ rtw_dbg(rtwdev, RTW_DBG_RFK, "[IQK] original 0x67 = 0x%x\n", ++ backup->btg_sel); ++} ++ ++static inline void rtw8723x_iqk_config_path_ctrl(struct rtw_dev *rtwdev) ++{ ++ rtw_write32_mask(rtwdev, REG_PAD_CTRL1, BIT_BT_BTG_SEL, 0x1); ++ rtw_dbg(rtwdev, RTW_DBG_RFK, "[IQK] set 0x67 = 0x%x\n", ++ rtw_read32_mask(rtwdev, REG_PAD_CTRL1, MASKBYTE3)); ++} ++ ++static inline void ++rtw8723x_iqk_restore_path_ctrl(struct rtw_dev *rtwdev, ++ const struct rtw8723x_iqk_backup_regs *backup) ++{ ++ rtw_write8(rtwdev, REG_BTG_SEL, backup->btg_sel); ++ rtw_dbg(rtwdev, RTW_DBG_RFK, "[IQK] restore 0x67 = 0x%x\n", ++ rtw_read32_mask(rtwdev, REG_PAD_CTRL1, MASKBYTE3)); ++} ++ ++static inline void ++rtw8723x_iqk_backup_lte_path_gnt(struct rtw_dev *rtwdev, ++ struct rtw8723x_iqk_backup_regs *backup) ++{ ++ backup->lte_path = rtw_read32(rtwdev, REG_LTECOEX_PATH_CONTROL); ++ rtw_write32(rtwdev, REG_LTECOEX_CTRL, 0x800f0038); ++ mdelay(1); ++ backup->lte_gnt = rtw_read32(rtwdev, REG_LTECOEX_READ_DATA); ++ rtw_dbg(rtwdev, RTW_DBG_RFK, "[IQK] OriginalGNT = 0x%x\n", ++ backup->lte_gnt); ++} ++ ++static inline void ++rtw8723x_iqk_config_lte_path_gnt(struct rtw_dev *rtwdev, ++ u32 write_data) ++{ ++ rtw_write32(rtwdev, REG_LTECOEX_WRITE_DATA, write_data); ++ rtw_write32(rtwdev, REG_LTECOEX_CTRL, 0xc0020038); ++ rtw_write32_mask(rtwdev, REG_LTECOEX_PATH_CONTROL, ++ BIT_LTE_MUX_CTRL_PATH, 0x1); ++} ++ ++static inline void ++rtw8723x_iqk_restore_lte_path_gnt(struct rtw_dev *rtwdev, ++ const struct rtw8723x_iqk_backup_regs *bak) ++{ ++ rtw_write32(rtwdev, REG_LTECOEX_WRITE_DATA, bak->lte_gnt); ++ rtw_write32(rtwdev, REG_LTECOEX_CTRL, 0xc00f0038); ++ rtw_write32(rtwdev, REG_LTECOEX_PATH_CONTROL, bak->lte_path); ++} ++ ++/* set all ADDA registers to the given value */ ++static inline void rtw8723x_iqk_path_adda_on(struct rtw_dev *rtwdev, u32 value) ++{ ++ for (int i = 0; i < RTW8723X_IQK_ADDA_REG_NUM; i++) ++ rtw_write32(rtwdev, rtw8723x_common.iqk_adda_regs[i], value); ++} ++ ++#endif /* __RTW8723X_H__ */ diff --git a/packages/linux/patches/rtlwifi/6.10/0009-6.10-wifi-rtw88-Debug-output-for-rtw8723x-EFUSE.patch b/packages/linux/patches/rtlwifi/6.10/0009-6.10-wifi-rtw88-Debug-output-for-rtw8723x-EFUSE.patch new file mode 100644 index 0000000000..e4c869b89e --- /dev/null +++ b/packages/linux/patches/rtlwifi/6.10/0009-6.10-wifi-rtw88-Debug-output-for-rtw8723x-EFUSE.patch @@ -0,0 +1,231 @@ +From da2abdcdbbb8c498fcfb2bc88ba56028bccdbc8a Mon Sep 17 00:00:00 2001 +From: Fiona Klute +Date: Mon, 11 Mar 2024 11:37:06 +0100 +Subject: [PATCH] wifi: rtw88: Debug output for rtw8723x EFUSE + +Some 8703b chips contain invalid EFUSE data, getting detailed +information is critical when analyzing issues caused by that. + +Acked-by: Ping-Ke Shih +Tested-by: Pavel Machek +Signed-off-by: Fiona Klute +Signed-off-by: Kalle Valo +Link: https://msgid.link/20240311103735.615541-3-fiona.klute@gmx.de +--- + drivers/net/wireless/realtek/rtw88/rtw8723x.c | 159 ++++++++++++++++++ + drivers/net/wireless/realtek/rtw88/rtw8723x.h | 11 ++ + 2 files changed, 170 insertions(+) + +diff --git a/drivers/net/wireless/realtek/rtw88/rtw8723x.c b/drivers/net/wireless/realtek/rtw88/rtw8723x.c +index c23650c5a20080..0d0b6c2cb9aa19 100644 +--- a/drivers/net/wireless/realtek/rtw88/rtw8723x.c ++++ b/drivers/net/wireless/realtek/rtw88/rtw8723x.c +@@ -63,6 +63,163 @@ static void __rtw8723x_lck(struct rtw_dev *rtwdev) + rtw_write8(rtwdev, REG_TXPAUSE, 0x00); + } + ++#define DBG_EFUSE_VAL(rtwdev, map, name) \ ++ rtw_dbg(rtwdev, RTW_DBG_EFUSE, # name "=0x%02x\n", \ ++ (map)->name) ++#define DBG_EFUSE_2BYTE(rtwdev, map, name) \ ++ rtw_dbg(rtwdev, RTW_DBG_EFUSE, # name "=0x%02x%02x\n", \ ++ (map)->name[0], (map)->name[1]) ++ ++static void rtw8723xe_efuse_debug(struct rtw_dev *rtwdev, ++ struct rtw8723x_efuse *map) ++{ ++ rtw_dbg(rtwdev, RTW_DBG_EFUSE, "mac_addr=%pM\n", map->e.mac_addr); ++ DBG_EFUSE_2BYTE(rtwdev, map, e.vendor_id); ++ DBG_EFUSE_2BYTE(rtwdev, map, e.device_id); ++ DBG_EFUSE_2BYTE(rtwdev, map, e.sub_vendor_id); ++ DBG_EFUSE_2BYTE(rtwdev, map, e.sub_device_id); ++} ++ ++static void rtw8723xu_efuse_debug(struct rtw_dev *rtwdev, ++ struct rtw8723x_efuse *map) ++{ ++ DBG_EFUSE_2BYTE(rtwdev, map, u.vendor_id); ++ DBG_EFUSE_2BYTE(rtwdev, map, u.product_id); ++ DBG_EFUSE_VAL(rtwdev, map, u.usb_option); ++ rtw_dbg(rtwdev, RTW_DBG_EFUSE, "mac_addr=%pM\n", map->u.mac_addr); ++} ++ ++static void rtw8723xs_efuse_debug(struct rtw_dev *rtwdev, ++ struct rtw8723x_efuse *map) ++{ ++ rtw_dbg(rtwdev, RTW_DBG_EFUSE, "mac_addr=%pM\n", map->s.mac_addr); ++} ++ ++static void __rtw8723x_debug_txpwr_limit(struct rtw_dev *rtwdev, ++ struct rtw_txpwr_idx *table, ++ int tx_path_count) ++{ ++ if (!rtw_dbg_is_enabled(rtwdev, RTW_DBG_EFUSE)) ++ return; ++ ++ rtw_dbg(rtwdev, RTW_DBG_EFUSE, ++ "Power index table (2.4G):\n"); ++ /* CCK base */ ++ rtw_dbg(rtwdev, RTW_DBG_EFUSE, "CCK base\n"); ++ rtw_dbg(rtwdev, RTW_DBG_EFUSE, "RF G0 G1 G2 G3 G4 G5\n"); ++ for (int i = 0; i < tx_path_count; i++) ++ rtw_dbg(rtwdev, RTW_DBG_EFUSE, ++ "[%c]: %3u %3u %3u %3u %3u %3u\n", ++ 'A' + i, ++ table[i].pwr_idx_2g.cck_base[0], ++ table[i].pwr_idx_2g.cck_base[1], ++ table[i].pwr_idx_2g.cck_base[2], ++ table[i].pwr_idx_2g.cck_base[3], ++ table[i].pwr_idx_2g.cck_base[4], ++ table[i].pwr_idx_2g.cck_base[5]); ++ /* CCK diff */ ++ rtw_dbg(rtwdev, RTW_DBG_EFUSE, "CCK diff\n"); ++ rtw_dbg(rtwdev, RTW_DBG_EFUSE, "RF 1S 2S 3S 4S\n"); ++ for (int i = 0; i < tx_path_count; i++) ++ rtw_dbg(rtwdev, RTW_DBG_EFUSE, ++ "[%c]: %2d %2d %2d %2d\n", ++ 'A' + i, 0 /* no diff for 1S */, ++ table[i].pwr_idx_2g.ht_2s_diff.cck, ++ table[i].pwr_idx_2g.ht_3s_diff.cck, ++ table[i].pwr_idx_2g.ht_4s_diff.cck); ++ /* BW40-1S base */ ++ rtw_dbg(rtwdev, RTW_DBG_EFUSE, "BW40-1S base\n"); ++ rtw_dbg(rtwdev, RTW_DBG_EFUSE, "RF G0 G1 G2 G3 G4\n"); ++ for (int i = 0; i < tx_path_count; i++) ++ rtw_dbg(rtwdev, RTW_DBG_EFUSE, ++ "[%c]: %3u %3u %3u %3u %3u\n", ++ 'A' + i, ++ table[i].pwr_idx_2g.bw40_base[0], ++ table[i].pwr_idx_2g.bw40_base[1], ++ table[i].pwr_idx_2g.bw40_base[2], ++ table[i].pwr_idx_2g.bw40_base[3], ++ table[i].pwr_idx_2g.bw40_base[4]); ++ /* OFDM diff */ ++ rtw_dbg(rtwdev, RTW_DBG_EFUSE, "OFDM diff\n"); ++ rtw_dbg(rtwdev, RTW_DBG_EFUSE, "RF 1S 2S 3S 4S\n"); ++ for (int i = 0; i < tx_path_count; i++) ++ rtw_dbg(rtwdev, RTW_DBG_EFUSE, ++ "[%c]: %2d %2d %2d %2d\n", ++ 'A' + i, ++ table[i].pwr_idx_2g.ht_1s_diff.ofdm, ++ table[i].pwr_idx_2g.ht_2s_diff.ofdm, ++ table[i].pwr_idx_2g.ht_3s_diff.ofdm, ++ table[i].pwr_idx_2g.ht_4s_diff.ofdm); ++ /* BW20 diff */ ++ rtw_dbg(rtwdev, RTW_DBG_EFUSE, "BW20 diff\n"); ++ rtw_dbg(rtwdev, RTW_DBG_EFUSE, "RF 1S 2S 3S 4S\n"); ++ for (int i = 0; i < tx_path_count; i++) ++ rtw_dbg(rtwdev, RTW_DBG_EFUSE, ++ "[%c]: %2d %2d %2d %2d\n", ++ 'A' + i, ++ table[i].pwr_idx_2g.ht_1s_diff.bw20, ++ table[i].pwr_idx_2g.ht_2s_diff.bw20, ++ table[i].pwr_idx_2g.ht_3s_diff.bw20, ++ table[i].pwr_idx_2g.ht_4s_diff.bw20); ++ /* BW40 diff */ ++ rtw_dbg(rtwdev, RTW_DBG_EFUSE, "BW40 diff\n"); ++ rtw_dbg(rtwdev, RTW_DBG_EFUSE, "RF 1S 2S 3S 4S\n"); ++ for (int i = 0; i < tx_path_count; i++) ++ rtw_dbg(rtwdev, RTW_DBG_EFUSE, ++ "[%c]: %2d %2d %2d %2d\n", ++ 'A' + i, 0 /* no diff for 1S */, ++ table[i].pwr_idx_2g.ht_2s_diff.bw40, ++ table[i].pwr_idx_2g.ht_3s_diff.bw40, ++ table[i].pwr_idx_2g.ht_4s_diff.bw40); ++} ++ ++static void efuse_debug_dump(struct rtw_dev *rtwdev, ++ struct rtw8723x_efuse *map) ++{ ++ if (!rtw_dbg_is_enabled(rtwdev, RTW_DBG_EFUSE)) ++ return; ++ ++ rtw_dbg(rtwdev, RTW_DBG_EFUSE, "EFUSE raw logical map:\n"); ++ print_hex_dump(KERN_DEBUG, "", DUMP_PREFIX_OFFSET, 16, 1, ++ (u8 *)map, sizeof(struct rtw8723x_efuse), false); ++ rtw_dbg(rtwdev, RTW_DBG_EFUSE, "Parsed rtw8723x EFUSE data:\n"); ++ DBG_EFUSE_VAL(rtwdev, map, rtl_id); ++ DBG_EFUSE_VAL(rtwdev, map, afe); ++ rtw8723x_debug_txpwr_limit(rtwdev, map->txpwr_idx_table, 4); ++ DBG_EFUSE_VAL(rtwdev, map, channel_plan); ++ DBG_EFUSE_VAL(rtwdev, map, xtal_k); ++ DBG_EFUSE_VAL(rtwdev, map, thermal_meter); ++ DBG_EFUSE_VAL(rtwdev, map, iqk_lck); ++ DBG_EFUSE_VAL(rtwdev, map, pa_type); ++ DBG_EFUSE_2BYTE(rtwdev, map, lna_type_2g); ++ DBG_EFUSE_2BYTE(rtwdev, map, lna_type_5g); ++ DBG_EFUSE_VAL(rtwdev, map, rf_board_option); ++ DBG_EFUSE_VAL(rtwdev, map, rf_feature_option); ++ DBG_EFUSE_VAL(rtwdev, map, rf_bt_setting); ++ DBG_EFUSE_VAL(rtwdev, map, eeprom_version); ++ DBG_EFUSE_VAL(rtwdev, map, eeprom_customer_id); ++ DBG_EFUSE_VAL(rtwdev, map, tx_bb_swing_setting_2g); ++ DBG_EFUSE_VAL(rtwdev, map, tx_pwr_calibrate_rate); ++ DBG_EFUSE_VAL(rtwdev, map, rf_antenna_option); ++ DBG_EFUSE_VAL(rtwdev, map, rfe_option); ++ DBG_EFUSE_2BYTE(rtwdev, map, country_code); ++ ++ switch (rtw_hci_type(rtwdev)) { ++ case RTW_HCI_TYPE_PCIE: ++ rtw8723xe_efuse_debug(rtwdev, map); ++ break; ++ case RTW_HCI_TYPE_USB: ++ rtw8723xu_efuse_debug(rtwdev, map); ++ break; ++ case RTW_HCI_TYPE_SDIO: ++ rtw8723xs_efuse_debug(rtwdev, map); ++ break; ++ default: ++ /* unsupported now */ ++ break; ++ } ++} ++ + static void rtw8723xe_efuse_parsing(struct rtw_efuse *efuse, + struct rtw8723x_efuse *map) + { +@@ -88,6 +245,7 @@ static int __rtw8723x_read_efuse(struct rtw_dev *rtwdev, u8 *log_map) + int i; + + map = (struct rtw8723x_efuse *)log_map; ++ efuse_debug_dump(rtwdev, map); + + efuse->rfe_option = 0; + efuse->rf_board_option = map->rf_board_option; +@@ -553,6 +711,7 @@ const struct rtw8723x_common rtw8723x_common = { + .pwrtrack_set_xtal = __rtw8723x_pwrtrack_set_xtal, + .coex_cfg_init = __rtw8723x_coex_cfg_init, + .fill_txdesc_checksum = __rtw8723x_fill_txdesc_checksum, ++ .debug_txpwr_limit = __rtw8723x_debug_txpwr_limit, + }; + EXPORT_SYMBOL(rtw8723x_common); + +diff --git a/drivers/net/wireless/realtek/rtw88/rtw8723x.h b/drivers/net/wireless/realtek/rtw88/rtw8723x.h +index cace285fc03397..d6dfee5a1806e2 100644 +--- a/drivers/net/wireless/realtek/rtw88/rtw8723x.h ++++ b/drivers/net/wireless/realtek/rtw88/rtw8723x.h +@@ -154,6 +154,9 @@ struct rtw8723x_common { + void (*fill_txdesc_checksum)(struct rtw_dev *rtwdev, + struct rtw_tx_pkt_info *pkt_info, + u8 *txdesc); ++ void (*debug_txpwr_limit)(struct rtw_dev *rtwdev, ++ struct rtw_txpwr_idx *table, ++ int tx_path_count); + }; + + extern const struct rtw8723x_common rtw8723x_common; +@@ -346,6 +349,14 @@ static inline s32 iqk_mult(s32 x, s32 y, s32 *ext) + return (t >> 8); /* Q.16 --> Q.8 */ + } + ++static inline ++void rtw8723x_debug_txpwr_limit(struct rtw_dev *rtwdev, ++ struct rtw_txpwr_idx *table, ++ int tx_path_count) ++{ ++ rtw8723x_common.debug_txpwr_limit(rtwdev, table, tx_path_count); ++} ++ + static inline void rtw8723x_lck(struct rtw_dev *rtwdev) + { + rtw8723x_common.lck(rtwdev); diff --git a/packages/linux/patches/rtlwifi/6.10/0010-6.10-wifi-rtw88-Add-definitions-for-8703b-chip.patch b/packages/linux/patches/rtlwifi/6.10/0010-6.10-wifi-rtw88-Add-definitions-for-8703b-chip.patch new file mode 100644 index 0000000000..72035689a5 --- /dev/null +++ b/packages/linux/patches/rtlwifi/6.10/0010-6.10-wifi-rtw88-Add-definitions-for-8703b-chip.patch @@ -0,0 +1,106 @@ +From 9bb762b3a957faffb4ba596165525521c07ad2eb Mon Sep 17 00:00:00 2001 +From: Fiona Klute +Date: Mon, 11 Mar 2024 11:37:07 +0100 +Subject: [PATCH] wifi: rtw88: Add definitions for 8703b chip + +default_cck_index is used in power track, the rx_cck_agc_report_type +for RX PHY status. GET_RX_DESC_BW is an RX descriptor field not used +by the other chip drivers. + +Acked-by: Ping-Ke Shih +Tested-by: Pavel Machek +Signed-off-by: Fiona Klute +Signed-off-by: Kalle Valo +Link: https://msgid.link/20240311103735.615541-4-fiona.klute@gmx.de +--- + drivers/net/wireless/realtek/rtw88/main.h | 3 +++ + drivers/net/wireless/realtek/rtw88/rtw8723x.h | 11 +++++++++++ + drivers/net/wireless/realtek/rtw88/rx.h | 2 ++ + 3 files changed, 16 insertions(+) + +diff --git a/drivers/net/wireless/realtek/rtw88/main.h b/drivers/net/wireless/realtek/rtw88/main.h +index e14d1da43940fa..49894331f7b495 100644 +--- a/drivers/net/wireless/realtek/rtw88/main.h ++++ b/drivers/net/wireless/realtek/rtw88/main.h +@@ -187,6 +187,7 @@ enum rtw_chip_type { + RTW_CHIP_TYPE_8822C, + RTW_CHIP_TYPE_8723D, + RTW_CHIP_TYPE_8821C, ++ RTW_CHIP_TYPE_8703B, + }; + + enum rtw_tx_queue_type { +@@ -1700,11 +1701,13 @@ struct rtw_dm_info { + s8 delta_power_index[RTW_RF_PATH_MAX]; + s8 delta_power_index_last[RTW_RF_PATH_MAX]; + u8 default_ofdm_index; ++ u8 default_cck_index; + bool pwr_trk_triggered; + bool pwr_trk_init_trigger; + struct ewma_thermal avg_thermal[RTW_RF_PATH_MAX]; + s8 txagc_remnant_cck; + s8 txagc_remnant_ofdm; ++ u8 rx_cck_agc_report_type; + + /* backup dack results for each path and I/Q */ + u32 dack_adck[RTW_RF_PATH_MAX]; +diff --git a/drivers/net/wireless/realtek/rtw88/rtw8723x.h b/drivers/net/wireless/realtek/rtw88/rtw8723x.h +index d6dfee5a1806e2..e93bfce994bf82 100644 +--- a/drivers/net/wireless/realtek/rtw88/rtw8723x.h ++++ b/drivers/net/wireless/realtek/rtw88/rtw8723x.h +@@ -165,6 +165,8 @@ extern const struct rtw8723x_common rtw8723x_common; + #define MAX_TOLERANCE 5 + #define IQK_TX_X_ERR 0x142 + #define IQK_TX_Y_ERR 0x42 ++#define IQK_RX_X_ERR 0x132 ++#define IQK_RX_Y_ERR 0x36 + #define IQK_RX_X_UPPER 0x11a + #define IQK_RX_X_LOWER 0xe6 + #define IQK_RX_Y_LMT 0x1a +@@ -177,6 +179,10 @@ extern const struct rtw8723x_common rtw8723x_common; + #define DIS_3WIRE 0xccf000c0 + #define EN_3WIRE 0xccc000c0 + #define START_PSD 0x400000 ++#define FREQ_CH5 0xfccd ++#define FREQ_CH6 0xfc4d ++#define FREQ_CH7 0xffcd ++#define FREQ_CH8 0xff4d + #define FREQ_CH13 0xfccd + #define FREQ_CH14 0xff9a + #define RFCFGCH_CHANNEL_MASK GENMASK(7, 0) +@@ -239,10 +245,13 @@ extern const struct rtw8723x_common rtw8723x_common; + #define BIT_MASK_OFDM0_EXT_C BIT(29) + #define BIT_MASK_OFDM0_EXTS (BIT(31) | BIT(29) | BIT(28)) + #define BIT_SET_OFDM0_EXTS(a, c, d) (((a) << 31) | ((c) << 29) | ((d) << 28)) ++#define BIT_MASK_OFDM0_EXTS_B (BIT(27) | BIT(25) | BIT(24)) ++#define BIT_SET_OFDM0_EXTS_B(a, c, d) (((a) << 27) | ((c) << 25) | ((d) << 24)) + #define REG_OFDM0_XAAGC1 0x0c50 + #define REG_OFDM0_XBAGC1 0x0c58 + #define REG_AGCRSSI 0x0c78 + #define REG_OFDM_0_XA_TX_IQ_IMBALANCE 0x0c80 ++#define REG_OFDM_0_XB_TX_IQ_IMBALANCE 0x0c88 + #define BIT_MASK_TXIQ_ELM_A 0x03ff + #define BIT_SET_TXIQ_ELM_ACD(a, c, d) (((d) << 22) | (((c) & 0x3F) << 16) | \ + ((a) & 0x03ff)) +@@ -303,6 +312,8 @@ extern const struct rtw8723x_common rtw8723x_common; + #define REG_IQK_AGC_RSP_11N 0x0e4c + #define REG_TX_IQK_TONE_B 0x0e50 + #define REG_RX_IQK_TONE_B 0x0e54 ++#define REG_TXIQK_PI_B 0x0e58 ++#define REG_RXIQK_PI_B 0x0e5c + #define REG_IQK_RES_TX 0x0e94 + #define BIT_MASK_RES_TX GENMASK(25, 16) + #define REG_IQK_RES_TY 0x0e9c +diff --git a/drivers/net/wireless/realtek/rtw88/rx.h b/drivers/net/wireless/realtek/rtw88/rx.h +index 3342e37612813a..d3668c4efc24d5 100644 +--- a/drivers/net/wireless/realtek/rtw88/rx.h ++++ b/drivers/net/wireless/realtek/rtw88/rx.h +@@ -40,6 +40,8 @@ enum rtw_rx_desc_enc { + 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(31, 24))) + + void rtw_rx_stats(struct rtw_dev *rtwdev, struct ieee80211_vif *vif, + struct sk_buff *skb); diff --git a/packages/linux/patches/rtlwifi/6.10/0011-6.10-wifi-rtw88-Add-rtw8703b.c.patch b/packages/linux/patches/rtlwifi/6.10/0011-6.10-wifi-rtw88-Add-rtw8703b.c.patch new file mode 100644 index 0000000000..8476c24e9c --- /dev/null +++ b/packages/linux/patches/rtlwifi/6.10/0011-6.10-wifi-rtw88-Add-rtw8703b.c.patch @@ -0,0 +1,2132 @@ +From 61a486bcd7820ddaa4adc110bfa96f0b3ec3fd8c Mon Sep 17 00:00:00 2001 +From: Fiona Klute +Date: Mon, 11 Mar 2024 11:37:09 +0100 +Subject: [PATCH] wifi: rtw88: Add rtw8703b.c + +This is the main source for the new rtw88_8703b chip driver. + +Acked-by: Ping-Ke Shih +Tested-by: Pavel Machek +Signed-off-by: Fiona Klute +Signed-off-by: Kalle Valo +Link: https://msgid.link/20240311103735.615541-6-fiona.klute@gmx.de +--- + drivers/net/wireless/realtek/rtw88/rtw8703b.c | 2109 +++++++++++++++++ + 1 file changed, 2109 insertions(+) + create mode 100644 drivers/net/wireless/realtek/rtw88/rtw8703b.c + +diff --git a/drivers/net/wireless/realtek/rtw88/rtw8703b.c b/drivers/net/wireless/realtek/rtw88/rtw8703b.c +new file mode 100644 +index 00000000000000..8919f9e11f0378 +--- /dev/null ++++ b/drivers/net/wireless/realtek/rtw88/rtw8703b.c +@@ -0,0 +1,2109 @@ ++// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause ++/* Copyright Fiona Klute */ ++ ++#include ++#include "main.h" ++#include "coex.h" ++#include "debug.h" ++#include "mac.h" ++#include "phy.h" ++#include "reg.h" ++#include "rx.h" ++#include "rtw8703b.h" ++#include "rtw8703b_tables.h" ++#include "rtw8723x.h" ++ ++#define BIT_MASK_TXQ_INIT (BIT(7)) ++#define WLAN_RL_VAL 0x3030 ++/* disable BAR */ ++#define WLAN_BAR_VAL 0x0201ffff ++#define WLAN_PIFS_VAL 0 ++#define WLAN_RX_PKT_LIMIT 0x18 ++#define WLAN_SLOT_TIME 0x09 ++#define WLAN_SPEC_SIFS 0x100a ++#define WLAN_MAX_AGG_NR 0x1f ++#define WLAN_AMPDU_MAX_TIME 0x70 ++ ++/* unit is 32us */ ++#define TBTT_PROHIBIT_SETUP_TIME 0x04 ++#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, \ ++ RTW_PWR_INTF_ALL_MSK, \ ++ 0, \ ++ RTW_PWR_CMD_END, 0, 0 ++ ++/* rssi in percentage % (dbm = % - 100) */ ++/* These are used to select simple signal quality levels, might need ++ * tweaking. Same for rf_para tables below. ++ */ ++static const u8 wl_rssi_step_8703b[] = {60, 50, 44, 30}; ++static const u8 bt_rssi_step_8703b[] = {30, 30, 30, 30}; ++static const struct coex_5g_afh_map afh_5g_8703b[] = { {0, 0, 0} }; ++ ++/* Actually decreasing wifi TX power/RX gain isn't implemented in ++ * rtw8703b, but hopefully adjusting the BT side helps. ++ */ ++static const struct coex_rf_para rf_para_tx_8703b[] = { ++ {0, 0, false, 7}, /* for normal */ ++ {0, 10, false, 7}, /* for WL-CPT */ ++ {1, 0, true, 4}, ++ {1, 2, true, 4}, ++ {1, 10, true, 4}, ++ {1, 15, true, 4} ++}; ++ ++static const struct coex_rf_para rf_para_rx_8703b[] = { ++ {0, 0, false, 7}, /* for normal */ ++ {0, 10, false, 7}, /* for WL-CPT */ ++ {1, 0, true, 5}, ++ {1, 2, true, 5}, ++ {1, 10, true, 5}, ++ {1, 15, true, 5} ++}; ++ ++static const u32 rtw8703b_ofdm_swing_table[] = { ++ 0x0b40002d, /* 0, -15.0dB */ ++ 0x0c000030, /* 1, -14.5dB */ ++ 0x0cc00033, /* 2, -14.0dB */ ++ 0x0d800036, /* 3, -13.5dB */ ++ 0x0e400039, /* 4, -13.0dB */ ++ 0x0f00003c, /* 5, -12.5dB */ ++ 0x10000040, /* 6, -12.0dB */ ++ 0x11000044, /* 7, -11.5dB */ ++ 0x12000048, /* 8, -11.0dB */ ++ 0x1300004c, /* 9, -10.5dB */ ++ 0x14400051, /* 10, -10.0dB */ ++ 0x15800056, /* 11, -9.5dB */ ++ 0x16c0005b, /* 12, -9.0dB */ ++ 0x18000060, /* 13, -8.5dB */ ++ 0x19800066, /* 14, -8.0dB */ ++ 0x1b00006c, /* 15, -7.5dB */ ++ 0x1c800072, /* 16, -7.0dB */ ++ 0x1e400079, /* 17, -6.5dB */ ++ 0x20000080, /* 18, -6.0dB */ ++ 0x22000088, /* 19, -5.5dB */ ++ 0x24000090, /* 20, -5.0dB */ ++ 0x26000098, /* 21, -4.5dB */ ++ 0x288000a2, /* 22, -4.0dB */ ++ 0x2ac000ab, /* 23, -3.5dB */ ++ 0x2d4000b5, /* 24, -3.0dB */ ++ 0x300000c0, /* 25, -2.5dB */ ++ 0x32c000cb, /* 26, -2.0dB */ ++ 0x35c000d7, /* 27, -1.5dB */ ++ 0x390000e4, /* 28, -1.0dB */ ++ 0x3c8000f2, /* 29, -0.5dB */ ++ 0x40000100, /* 30, +0dB */ ++ 0x43c0010f, /* 31, +0.5dB */ ++ 0x47c0011f, /* 32, +1.0dB */ ++ 0x4c000130, /* 33, +1.5dB */ ++ 0x50800142, /* 34, +2.0dB */ ++ 0x55400155, /* 35, +2.5dB */ ++ 0x5a400169, /* 36, +3.0dB */ ++ 0x5fc0017f, /* 37, +3.5dB */ ++ 0x65400195, /* 38, +4.0dB */ ++ 0x6b8001ae, /* 39, +4.5dB */ ++ 0x71c001c7, /* 40, +5.0dB */ ++ 0x788001e2, /* 41, +5.5dB */ ++ 0x7f8001fe /* 42, +6.0dB */ ++}; ++ ++static const u32 rtw8703b_cck_pwr_regs[] = { ++ 0x0a22, 0x0a23, 0x0a24, 0x0a25, 0x0a26, 0x0a27, 0x0a28, 0x0a29, ++ 0x0a9a, 0x0a9b, 0x0a9c, 0x0a9d, 0x0aa0, 0x0aa1, 0x0aa2, 0x0aa3, ++}; ++ ++static const u8 rtw8703b_cck_swing_table[][16] = { ++ {0x44, 0x42, 0x3C, 0x33, 0x28, 0x1C, 0x13, 0x0B, 0x05, 0x02, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*-16dB*/ ++ {0x48, 0x46, 0x3F, 0x36, 0x2A, 0x1E, 0x14, 0x0B, 0x05, 0x02, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*-15.5dB*/ ++ {0x4D, 0x4A, 0x43, 0x39, 0x2C, 0x20, 0x15, 0x0C, 0x06, 0x02, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*-15dB*/ ++ {0x51, 0x4F, 0x47, 0x3C, 0x2F, 0x22, 0x16, 0x0D, 0x06, 0x02, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*-14.5dB*/ ++ {0x56, 0x53, 0x4B, 0x40, 0x32, 0x24, 0x17, 0x0E, 0x06, 0x02, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*-14dB*/ ++ {0x5B, 0x58, 0x50, 0x43, 0x35, 0x26, 0x19, 0x0E, 0x07, 0x02, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*-13.5dB*/ ++ {0x60, 0x5D, 0x54, 0x47, 0x38, 0x28, 0x1A, 0x0F, 0x07, 0x02, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*-13dB*/ ++ {0x66, 0x63, 0x59, 0x4C, 0x3B, 0x2B, 0x1C, 0x10, 0x08, 0x02, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*-12.5dB*/ ++ {0x6C, 0x69, 0x5F, 0x50, 0x3F, 0x2D, 0x1E, 0x11, 0x08, 0x03, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*-12dB*/ ++ {0x73, 0x6F, 0x64, 0x55, 0x42, 0x30, 0x1F, 0x12, 0x08, 0x03, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*-11.5dB*/ ++ {0x79, 0x76, 0x6A, 0x5A, 0x46, 0x33, 0x21, 0x13, 0x09, 0x03, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*-11dB*/ ++ {0x81, 0x7C, 0x71, 0x5F, 0x4A, 0x36, 0x23, 0x14, 0x0A, 0x03, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*-10.5dB*/ ++ {0x88, 0x84, 0x77, 0x65, 0x4F, 0x39, 0x25, 0x15, 0x0A, 0x03, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*-10dB*/ ++ {0x90, 0x8C, 0x7E, 0x6B, 0x54, 0x3C, 0x27, 0x17, 0x0B, 0x03, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*-9.5dB*/ ++ {0x99, 0x94, 0x86, 0x71, 0x58, 0x40, 0x2A, 0x18, 0x0B, 0x04, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*-9dB*/ ++ {0xA2, 0x9D, 0x8E, 0x78, 0x5E, 0x43, 0x2C, 0x19, 0x0C, 0x04, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*-8.5dB*/ ++ {0xAC, 0xA6, 0x96, 0x7F, 0x63, 0x47, 0x2F, 0x1B, 0x0D, 0x04, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*-8dB*/ ++ {0xB6, 0xB0, 0x9F, 0x87, 0x69, 0x4C, 0x32, 0x1D, 0x0D, 0x04, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*-7.5dB*/ ++ {0xC1, 0xBA, 0xA8, 0x8F, 0x6F, 0x50, 0x35, 0x1E, 0x0E, 0x04, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*-7dB*/ ++ {0xCC, 0xC5, 0xB2, 0x97, 0x76, 0x55, 0x38, 0x20, 0x0F, 0x05, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*-6.5dB*/ ++ {0xD8, 0xD1, 0xBD, 0xA0, 0x7D, 0x5A, 0x3B, 0x22, 0x10, 0x05, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00} /*-6dB*/ ++}; ++ ++#define RTW_OFDM_SWING_TABLE_SIZE ARRAY_SIZE(rtw8703b_ofdm_swing_table) ++#define RTW_CCK_SWING_TABLE_SIZE ARRAY_SIZE(rtw8703b_cck_swing_table) ++ ++static const struct rtw_pwr_seq_cmd trans_pre_enable_8703b[] = { ++ /* set up external crystal (XTAL) */ ++ {REG_PAD_CTRL1 + 2, ++ RTW_PWR_CUT_ALL_MSK, ++ RTW_PWR_INTF_ALL_MSK, ++ RTW_PWR_ADDR_MAC, ++ RTW_PWR_CMD_WRITE, BIT(7), BIT(7)}, ++ /* set CLK_REQ to high active */ ++ {0x0069, ++ RTW_PWR_CUT_ALL_MSK, ++ RTW_PWR_INTF_ALL_MSK, ++ RTW_PWR_ADDR_MAC, ++ RTW_PWR_CMD_WRITE, BIT(5), BIT(5)}, ++ /* unlock ISO/CLK/power control register */ ++ {REG_RSV_CTRL, ++ RTW_PWR_CUT_ALL_MSK, ++ RTW_PWR_INTF_ALL_MSK, ++ RTW_PWR_ADDR_MAC, ++ RTW_PWR_CMD_WRITE, 0xff, 0}, ++ {TRANS_SEQ_END}, ++}; ++ ++static const struct rtw_pwr_seq_cmd trans_carddis_to_cardemu_8703b[] = { ++ {0x0005, ++ RTW_PWR_CUT_ALL_MSK, ++ RTW_PWR_INTF_ALL_MSK, ++ RTW_PWR_ADDR_MAC, ++ RTW_PWR_CMD_WRITE, BIT(7), 0}, ++ {TRANS_SEQ_END}, ++}; ++ ++static const struct rtw_pwr_seq_cmd trans_cardemu_to_carddis_8703b[] = { ++ {0x0023, ++ RTW_PWR_CUT_ALL_MSK, ++ RTW_PWR_INTF_SDIO_MSK, ++ RTW_PWR_ADDR_MAC, ++ RTW_PWR_CMD_WRITE, BIT(4), BIT(4)}, ++ {0x0007, ++ RTW_PWR_CUT_ALL_MSK, ++ RTW_PWR_INTF_SDIO_MSK | RTW_PWR_INTF_USB_MSK, ++ RTW_PWR_ADDR_MAC, ++ RTW_PWR_CMD_WRITE, 0xFF, 0x20}, ++ {0x0006, ++ RTW_PWR_CUT_ALL_MSK, ++ RTW_PWR_INTF_ALL_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(7), BIT(7)}, ++ {TRANS_SEQ_END}, ++}; ++ ++static const struct rtw_pwr_seq_cmd trans_cardemu_to_act_8703b[] = { ++ {0x0020, ++ RTW_PWR_CUT_ALL_MSK, ++ RTW_PWR_INTF_USB_MSK | RTW_PWR_INTF_SDIO_MSK, ++ RTW_PWR_ADDR_MAC, ++ RTW_PWR_CMD_WRITE, BIT(0), BIT(0)}, ++ {0x0067, ++ RTW_PWR_CUT_ALL_MSK, ++ RTW_PWR_INTF_USB_MSK | RTW_PWR_INTF_SDIO_MSK, ++ RTW_PWR_ADDR_MAC, ++ RTW_PWR_CMD_WRITE, BIT(4), 0}, ++ {0x0001, ++ RTW_PWR_CUT_ALL_MSK, ++ RTW_PWR_INTF_USB_MSK | RTW_PWR_INTF_SDIO_MSK, ++ RTW_PWR_ADDR_MAC, ++ RTW_PWR_CMD_DELAY, 1, RTW_PWR_DELAY_MS}, ++ {0x0000, ++ RTW_PWR_CUT_ALL_MSK, ++ RTW_PWR_INTF_USB_MSK | RTW_PWR_INTF_SDIO_MSK, ++ RTW_PWR_ADDR_MAC, ++ RTW_PWR_CMD_WRITE, BIT(5), 0}, ++ {0x0005, ++ RTW_PWR_CUT_ALL_MSK, ++ RTW_PWR_INTF_ALL_MSK, ++ RTW_PWR_ADDR_MAC, ++ RTW_PWR_CMD_WRITE, (BIT(4) | BIT(3) | BIT(2)), 0}, ++ {0x0075, ++ RTW_PWR_CUT_ALL_MSK, ++ RTW_PWR_INTF_PCI_MSK, ++ RTW_PWR_ADDR_MAC, ++ RTW_PWR_CMD_WRITE, BIT(0), BIT(0)}, ++ {0x0004, ++ RTW_PWR_CUT_ALL_MSK, ++ RTW_PWR_INTF_PCI_MSK, ++ RTW_PWR_ADDR_MAC, ++ RTW_PWR_CMD_WRITE, BIT(3), BIT(3)}, ++ {0x0004, ++ RTW_PWR_CUT_ALL_MSK, ++ RTW_PWR_INTF_PCI_MSK, ++ RTW_PWR_ADDR_MAC, ++ RTW_PWR_CMD_WRITE, BIT(3), 0}, ++ /* wait for power ready */ ++ {0x0006, ++ RTW_PWR_CUT_ALL_MSK, ++ RTW_PWR_INTF_ALL_MSK, ++ RTW_PWR_ADDR_MAC, ++ RTW_PWR_CMD_POLLING, BIT(1), BIT(1)}, ++ {0x0075, ++ RTW_PWR_CUT_ALL_MSK, ++ RTW_PWR_INTF_PCI_MSK, ++ RTW_PWR_ADDR_MAC, ++ RTW_PWR_CMD_WRITE, BIT(0), 0}, ++ {0x0006, ++ 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_WRITE, BIT(7), 0}, ++ {0x0005, ++ RTW_PWR_CUT_ALL_MSK, ++ RTW_PWR_INTF_ALL_MSK, ++ RTW_PWR_ADDR_MAC, ++ RTW_PWR_CMD_WRITE, (BIT(4) | BIT(3)), 0}, ++ {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}, ++ {0x0010, ++ RTW_PWR_CUT_ALL_MSK, ++ RTW_PWR_INTF_ALL_MSK, ++ RTW_PWR_ADDR_MAC, ++ RTW_PWR_CMD_WRITE, BIT(6), BIT(6)}, ++ {0x0049, ++ RTW_PWR_CUT_ALL_MSK, ++ RTW_PWR_INTF_ALL_MSK, ++ RTW_PWR_ADDR_MAC, ++ RTW_PWR_CMD_WRITE, BIT(1), BIT(1)}, ++ {0x0063, ++ RTW_PWR_CUT_ALL_MSK, ++ RTW_PWR_INTF_ALL_MSK, ++ RTW_PWR_ADDR_MAC, ++ RTW_PWR_CMD_WRITE, BIT(1), BIT(1)}, ++ {0x0062, ++ RTW_PWR_CUT_ALL_MSK, ++ RTW_PWR_INTF_ALL_MSK, ++ RTW_PWR_ADDR_MAC, ++ RTW_PWR_CMD_WRITE, BIT(1), 0}, ++ {0x0058, ++ RTW_PWR_CUT_ALL_MSK, ++ RTW_PWR_INTF_ALL_MSK, ++ RTW_PWR_ADDR_MAC, ++ RTW_PWR_CMD_WRITE, BIT(0), BIT(0)}, ++ {0x005A, ++ RTW_PWR_CUT_ALL_MSK, ++ RTW_PWR_INTF_ALL_MSK, ++ RTW_PWR_ADDR_MAC, ++ RTW_PWR_CMD_WRITE, BIT(1), BIT(1)}, ++ {0x0068, ++ RTW_PWR_CUT_TEST_MSK, ++ RTW_PWR_INTF_ALL_MSK, ++ RTW_PWR_ADDR_MAC, ++ RTW_PWR_CMD_WRITE, BIT(3), BIT(3)}, ++ {0x0069, ++ RTW_PWR_CUT_ALL_MSK, ++ RTW_PWR_INTF_ALL_MSK, ++ RTW_PWR_ADDR_MAC, ++ RTW_PWR_CMD_WRITE, BIT(6), BIT(6)}, ++ {TRANS_SEQ_END}, ++}; ++ ++static const struct rtw_pwr_seq_cmd trans_act_to_cardemu_8703b[] = { ++ {0x001f, ++ RTW_PWR_CUT_ALL_MSK, ++ RTW_PWR_INTF_ALL_MSK, ++ RTW_PWR_ADDR_MAC, ++ RTW_PWR_CMD_WRITE, 0xff, 0}, ++ {0x0049, ++ RTW_PWR_CUT_ALL_MSK, ++ RTW_PWR_INTF_ALL_MSK, ++ RTW_PWR_ADDR_MAC, ++ RTW_PWR_CMD_WRITE, BIT(1), 0}, ++ {0x0006, ++ 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_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}, ++ {0x0010, ++ RTW_PWR_CUT_ALL_MSK, ++ RTW_PWR_INTF_ALL_MSK, ++ RTW_PWR_ADDR_MAC, ++ RTW_PWR_CMD_WRITE, BIT(6), 0}, ++ {0x0000, ++ RTW_PWR_CUT_ALL_MSK, ++ RTW_PWR_INTF_USB_MSK | RTW_PWR_INTF_SDIO_MSK, ++ RTW_PWR_ADDR_MAC, ++ RTW_PWR_CMD_WRITE, BIT(5), BIT(5)}, ++ {0x0020, ++ RTW_PWR_CUT_ALL_MSK, ++ RTW_PWR_INTF_USB_MSK | RTW_PWR_INTF_SDIO_MSK, ++ RTW_PWR_ADDR_MAC, ++ RTW_PWR_CMD_WRITE, BIT(0), 0}, ++ {TRANS_SEQ_END}, ++}; ++ ++static const struct rtw_pwr_seq_cmd trans_act_to_reset_mcu_8703b[] = { ++ {REG_SYS_FUNC_EN + 1, ++ RTW_PWR_CUT_ALL_MSK, ++ RTW_PWR_INTF_SDIO_MSK, ++ RTW_PWR_ADDR_MAC, ++ RTW_PWR_CMD_WRITE, BIT_FEN_CPUEN, 0}, ++ /* reset MCU ready */ ++ {REG_MCUFW_CTRL, ++ RTW_PWR_CUT_ALL_MSK, ++ RTW_PWR_INTF_SDIO_MSK, ++ RTW_PWR_ADDR_MAC, ++ RTW_PWR_CMD_WRITE, 0xff, 0}, ++ /* reset MCU IO wrapper */ ++ {REG_RSV_CTRL + 1, ++ RTW_PWR_CUT_ALL_MSK, ++ RTW_PWR_INTF_SDIO_MSK, ++ RTW_PWR_ADDR_MAC, ++ RTW_PWR_CMD_WRITE, BIT(0), 0}, ++ {REG_RSV_CTRL + 1, ++ RTW_PWR_CUT_ALL_MSK, ++ RTW_PWR_INTF_SDIO_MSK, ++ RTW_PWR_ADDR_MAC, ++ RTW_PWR_CMD_WRITE, BIT(0), 1}, ++ {TRANS_SEQ_END}, ++}; ++ ++static const struct rtw_pwr_seq_cmd trans_act_to_lps_8703b[] = { ++ {0x0301, ++ RTW_PWR_CUT_ALL_MSK, ++ RTW_PWR_INTF_ALL_MSK, ++ RTW_PWR_ADDR_MAC, ++ RTW_PWR_CMD_WRITE, 0xff, 0xff}, ++ {0x0522, ++ RTW_PWR_CUT_ALL_MSK, ++ RTW_PWR_INTF_ALL_MSK, ++ RTW_PWR_ADDR_MAC, ++ RTW_PWR_CMD_WRITE, 0xff, 0xff}, ++ {0x05f8, ++ RTW_PWR_CUT_ALL_MSK, ++ RTW_PWR_INTF_ALL_MSK, ++ RTW_PWR_ADDR_MAC, ++ RTW_PWR_CMD_POLLING, 0xff, 0}, ++ {0x05f9, ++ RTW_PWR_CUT_ALL_MSK, ++ RTW_PWR_INTF_ALL_MSK, ++ RTW_PWR_ADDR_MAC, ++ RTW_PWR_CMD_POLLING, 0xff, 0}, ++ {0x05fa, ++ RTW_PWR_CUT_ALL_MSK, ++ RTW_PWR_INTF_ALL_MSK, ++ RTW_PWR_ADDR_MAC, ++ RTW_PWR_CMD_POLLING, 0xff, 0}, ++ {0x05fb, ++ RTW_PWR_CUT_ALL_MSK, ++ RTW_PWR_INTF_ALL_MSK, ++ RTW_PWR_ADDR_MAC, ++ RTW_PWR_CMD_POLLING, 0xff, 0}, ++ {0x0002, ++ 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, 0, RTW_PWR_DELAY_US}, ++ {0x0002, ++ RTW_PWR_CUT_ALL_MSK, ++ RTW_PWR_INTF_ALL_MSK, ++ RTW_PWR_ADDR_MAC, ++ RTW_PWR_CMD_WRITE, BIT(1), 0}, ++ {0x0100, ++ RTW_PWR_CUT_ALL_MSK, ++ RTW_PWR_INTF_ALL_MSK, ++ RTW_PWR_ADDR_MAC, ++ RTW_PWR_CMD_WRITE, 0xff, 0x03}, ++ {0x0101, ++ RTW_PWR_CUT_ALL_MSK, ++ RTW_PWR_INTF_ALL_MSK, ++ RTW_PWR_ADDR_MAC, ++ RTW_PWR_CMD_WRITE, BIT(1), 0}, ++ {0x0093, ++ RTW_PWR_CUT_ALL_MSK, ++ RTW_PWR_INTF_SDIO_MSK, ++ RTW_PWR_ADDR_MAC, ++ RTW_PWR_CMD_WRITE, 0xff, 0}, ++ {0x0553, ++ RTW_PWR_CUT_ALL_MSK, ++ RTW_PWR_INTF_ALL_MSK, ++ RTW_PWR_ADDR_MAC, ++ RTW_PWR_CMD_WRITE, BIT(5), BIT(5)}, ++ {TRANS_SEQ_END}, ++}; ++ ++static const struct rtw_pwr_seq_cmd *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[] = { ++ trans_act_to_lps_8703b, ++ trans_act_to_reset_mcu_8703b, ++ trans_act_to_cardemu_8703b, ++ trans_cardemu_to_carddis_8703b, ++ NULL ++}; ++ ++static const struct rtw_rfe_def rtw8703b_rfe_defs[] = { ++ [0] = { .phy_pg_tbl = &rtw8703b_bb_pg_tbl, ++ .txpwr_lmt_tbl = &rtw8703b_txpwr_lmt_tbl,}, ++}; ++ ++static const struct rtw_page_table page_table_8703b[] = { ++ {12, 2, 2, 0, 1}, ++ {12, 2, 2, 0, 1}, ++ {12, 2, 2, 0, 1}, ++ {12, 2, 2, 0, 1}, ++ {12, 2, 2, 0, 1}, ++}; ++ ++static const struct rtw_rqpn rqpn_table_8703b[] = { ++ {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_NORMAL, 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_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}, ++}; ++ ++/* 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; ++ struct rtw_efuse *efuse = &rtwdev->efuse; ++ int ret; ++ ++ if (node) { ++ ret = of_get_mac_address(node, efuse->addr); ++ if (ret == 0) { ++ rtw_dbg(rtwdev, RTW_DBG_EFUSE, ++ "got wifi mac address from DT: %pM\n", ++ efuse->addr); ++ } ++ } ++} ++ ++#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); ++ if (ret != 0) ++ return ret; ++ ++ 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; ++} ++ ++static void rtw8703b_pwrtrack_init(struct rtw_dev *rtwdev) ++{ ++ struct rtw_dm_info *dm_info = &rtwdev->dm_info; ++ u8 path; ++ ++ /* TODO: The vendor driver selects these using tables in ++ * halrf_powertracking_ce.c, functions are called ++ * get_swing_index and get_cck_swing_index. There the current ++ * fixed values are only the defaults in case no match is ++ * found. ++ */ ++ dm_info->default_ofdm_index = 30; ++ dm_info->default_cck_index = 20; ++ ++ 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->pwr_trk_triggered = false; ++ dm_info->pwr_trk_init_trigger = true; ++ dm_info->thermal_meter_k = rtwdev->efuse.thermal_meter_k; ++ dm_info->txagc_remnant_cck = 0; ++ dm_info->txagc_remnant_ofdm = 0; ++} ++ ++static void rtw8703b_phy_set_param(struct rtw_dev *rtwdev) ++{ ++ u8 xtal_cap = rtwdev->efuse.crystal_cap & 0x3F; ++ ++ /* power on BB/RF domain */ ++ rtw_write16_set(rtwdev, REG_SYS_FUNC_EN, ++ BIT_FEN_EN_25_1 | BIT_FEN_BB_GLB_RST | BIT_FEN_BB_RSTB); ++ rtw_write8_set(rtwdev, REG_RF_CTRL, ++ BIT_RF_EN | BIT_RF_RSTB | BIT_RF_SDM_RSTB); ++ rtw_write_rf(rtwdev, RF_PATH_A, RF_WLINT, RFREG_MASK, 0x0780); ++ rtw_write8(rtwdev, REG_AFE_CTRL1 + 1, 0x80); ++ ++ rtw_phy_load_tables(rtwdev); ++ ++ rtw_write32_clr(rtwdev, REG_RCR, BIT_RCR_ADF); ++ /* 0xff is from vendor driver, rtw8723d uses ++ * BIT_HIQ_NO_LMT_EN_ROOT. Comment in vendor driver: "Packet ++ * in Hi Queue Tx immediately". I wonder if setting all bits ++ * is really necessary. ++ */ ++ rtw_write8_set(rtwdev, REG_HIQ_NO_LMT_EN, 0xff); ++ rtw_write16_set(rtwdev, REG_AFE_CTRL_4, BIT_CK320M_AFE_EN | BIT_EN_SYN); ++ ++ rtw_write32_mask(rtwdev, REG_AFE_CTRL3, BIT_MASK_XTAL, ++ xtal_cap | (xtal_cap << 6)); ++ rtw_write32_set(rtwdev, REG_FPGA0_RFMOD, BIT_CCKEN | BIT_OFDMEN); ++ ++ /* Init EDCA */ ++ rtw_write16(rtwdev, REG_SPEC_SIFS, WLAN_SPEC_SIFS); ++ rtw_write16(rtwdev, REG_MAC_SPEC_SIFS, WLAN_SPEC_SIFS); ++ rtw_write16(rtwdev, REG_SIFS, WLAN_SPEC_SIFS); /* CCK */ ++ rtw_write16(rtwdev, REG_SIFS + 2, WLAN_SPEC_SIFS); /* OFDM */ ++ /* TXOP */ ++ rtw_write32(rtwdev, REG_EDCA_VO_PARAM, 0x002FA226); ++ rtw_write32(rtwdev, REG_EDCA_VI_PARAM, 0x005EA324); ++ rtw_write32(rtwdev, REG_EDCA_BE_PARAM, 0x005EA42B); ++ rtw_write32(rtwdev, REG_EDCA_BK_PARAM, 0x0000A44F); ++ ++ /* Init retry */ ++ rtw_write8(rtwdev, REG_ACKTO, 0x40); ++ ++ /* Set up RX aggregation. sdio.c also sets DMA mode, but not ++ * the burst parameters. ++ */ ++ rtw_write8(rtwdev, REG_RXDMA_MODE, ++ BIT_DMA_MODE | ++ FIELD_PREP_CONST(BIT_MASK_AGG_BURST_NUM, AGG_BURST_NUM) | ++ FIELD_PREP_CONST(BIT_MASK_AGG_BURST_SIZE, AGG_BURST_SIZE)); ++ ++ /* Init beacon parameters */ ++ rtw_write8(rtwdev, REG_BCN_CTRL, ++ BIT_DIS_TSF_UDT | BIT_EN_BCN_FUNCTION | BIT_EN_TXBCN_RPT); ++ rtw_write8(rtwdev, REG_TBTT_PROHIBIT, TBTT_PROHIBIT_SETUP_TIME); ++ rtw_write8(rtwdev, REG_TBTT_PROHIBIT + 1, ++ TBTT_PROHIBIT_HOLD_TIME_STOP_BCN & 0xFF); ++ rtw_write8(rtwdev, REG_TBTT_PROHIBIT + 2, ++ (rtw_read8(rtwdev, REG_TBTT_PROHIBIT + 2) & 0xF0) ++ | (TBTT_PROHIBIT_HOLD_TIME_STOP_BCN >> 8)); ++ ++ /* configure packet burst */ ++ rtw_write8_set(rtwdev, REG_SINGLE_AMPDU_CTRL, BIT_EN_SINGLE_APMDU); ++ rtw_write8(rtwdev, REG_RX_PKT_LIMIT, WLAN_RX_PKT_LIMIT); ++ rtw_write8(rtwdev, REG_MAX_AGGR_NUM, WLAN_MAX_AGG_NR); ++ rtw_write8(rtwdev, REG_PIFS, WLAN_PIFS_VAL); ++ rtw_write8_clr(rtwdev, REG_FWHW_TXQ_CTRL, BIT_MASK_TXQ_INIT); ++ rtw_write8(rtwdev, REG_AMPDU_MAX_TIME, WLAN_AMPDU_MAX_TIME); ++ ++ rtw_write8(rtwdev, REG_SLOT, WLAN_SLOT_TIME); ++ rtw_write16(rtwdev, REG_RETRY_LIMIT, WLAN_RL_VAL); ++ rtw_write32(rtwdev, REG_BAR_MODE_CTRL, WLAN_BAR_VAL); ++ rtw_write16(rtwdev, REG_ATIMWND, 0x2); ++ ++ rtw_phy_init(rtwdev); ++ ++ if (rtw_read32_mask(rtwdev, REG_BB_AMP, BIT_MASK_RX_LNA) != 0) { ++ rtwdev->dm_info.rx_cck_agc_report_type = 1; ++ } else { ++ rtwdev->dm_info.rx_cck_agc_report_type = 0; ++ rtw_warn(rtwdev, "unexpected cck agc report type"); ++ } ++ ++ rtw8723x_lck(rtwdev); ++ ++ rtw_write32_mask(rtwdev, REG_OFDM0_XAAGC1, MASKBYTE0, 0x50); ++ rtw_write32_mask(rtwdev, REG_OFDM0_XAAGC1, MASKBYTE0, 0x20); ++ ++ rtw8703b_pwrtrack_init(rtwdev); ++} ++ ++static bool rtw8703b_check_spur_ov_thres(struct rtw_dev *rtwdev, ++ u32 freq, u32 thres) ++{ ++ bool ret = false; ++ ++ rtw_write32(rtwdev, REG_ANALOG_P4, DIS_3WIRE); ++ rtw_write32(rtwdev, REG_PSDFN, freq); ++ rtw_write32(rtwdev, REG_PSDFN, START_PSD | freq); ++ ++ msleep(30); ++ if (rtw_read32(rtwdev, REG_PSDRPT) >= thres) ++ ret = true; ++ ++ rtw_write32(rtwdev, REG_PSDFN, freq); ++ rtw_write32(rtwdev, REG_ANALOG_P4, EN_3WIRE); ++ ++ return ret; ++} ++ ++static void rtw8703b_cfg_notch(struct rtw_dev *rtwdev, u8 channel, bool notch) ++{ ++ if (!notch) { ++ rtw_write32_mask(rtwdev, REG_OFDM0_RXDSP, BIT_MASK_RXDSP, 0x1f); ++ rtw_write32_mask(rtwdev, REG_OFDM0_RXDSP, BIT_EN_RXDSP, 0x0); ++ rtw_write32(rtwdev, REG_OFDM1_CSI1, 0x00000000); ++ rtw_write32(rtwdev, REG_OFDM1_CSI2, 0x00000000); ++ rtw_write32(rtwdev, REG_OFDM1_CSI3, 0x00000000); ++ rtw_write32(rtwdev, REG_OFDM1_CSI4, 0x00000000); ++ rtw_write32_mask(rtwdev, REG_OFDM1_CFOTRK, BIT_EN_CFOTRK, 0x0); ++ return; ++ } ++ ++ switch (channel) { ++ case 5: ++ fallthrough; ++ case 13: ++ rtw_write32_mask(rtwdev, REG_OFDM0_RXDSP, BIT_MASK_RXDSP, 0xb); ++ rtw_write32_mask(rtwdev, REG_OFDM0_RXDSP, BIT_EN_RXDSP, 0x1); ++ rtw_write32(rtwdev, REG_OFDM1_CSI1, 0x06000000); ++ rtw_write32(rtwdev, REG_OFDM1_CSI2, 0x00000000); ++ rtw_write32(rtwdev, REG_OFDM1_CSI3, 0x00000000); ++ rtw_write32(rtwdev, REG_OFDM1_CSI4, 0x00000000); ++ rtw_write32_mask(rtwdev, REG_OFDM1_CFOTRK, BIT_EN_CFOTRK, 0x1); ++ break; ++ case 6: ++ rtw_write32_mask(rtwdev, REG_OFDM0_RXDSP, BIT_MASK_RXDSP, 0x4); ++ rtw_write32_mask(rtwdev, REG_OFDM0_RXDSP, BIT_EN_RXDSP, 0x1); ++ rtw_write32(rtwdev, REG_OFDM1_CSI1, 0x00000600); ++ rtw_write32(rtwdev, REG_OFDM1_CSI2, 0x00000000); ++ rtw_write32(rtwdev, REG_OFDM1_CSI3, 0x00000000); ++ rtw_write32(rtwdev, REG_OFDM1_CSI4, 0x00000000); ++ rtw_write32_mask(rtwdev, REG_OFDM1_CFOTRK, BIT_EN_CFOTRK, 0x1); ++ break; ++ case 7: ++ rtw_write32_mask(rtwdev, REG_OFDM0_RXDSP, BIT_MASK_RXDSP, 0x3); ++ rtw_write32_mask(rtwdev, REG_OFDM0_RXDSP, BIT_EN_RXDSP, 0x1); ++ rtw_write32(rtwdev, REG_OFDM1_CSI1, 0x00000000); ++ rtw_write32(rtwdev, REG_OFDM1_CSI2, 0x00000000); ++ rtw_write32(rtwdev, REG_OFDM1_CSI3, 0x00000000); ++ rtw_write32(rtwdev, REG_OFDM1_CSI4, 0x06000000); ++ rtw_write32_mask(rtwdev, REG_OFDM1_CFOTRK, BIT_EN_CFOTRK, 0x1); ++ break; ++ case 8: ++ rtw_write32_mask(rtwdev, REG_OFDM0_RXDSP, BIT_MASK_RXDSP, 0xa); ++ rtw_write32_mask(rtwdev, REG_OFDM0_RXDSP, BIT_EN_RXDSP, 0x1); ++ rtw_write32(rtwdev, REG_OFDM1_CSI1, 0x00000000); ++ rtw_write32(rtwdev, REG_OFDM1_CSI2, 0x00000000); ++ rtw_write32(rtwdev, REG_OFDM1_CSI3, 0x00000000); ++ rtw_write32(rtwdev, REG_OFDM1_CSI4, 0x00000380); ++ rtw_write32_mask(rtwdev, REG_OFDM1_CFOTRK, BIT_EN_CFOTRK, 0x1); ++ break; ++ case 14: ++ rtw_write32_mask(rtwdev, REG_OFDM0_RXDSP, BIT_MASK_RXDSP, 0x5); ++ rtw_write32_mask(rtwdev, REG_OFDM0_RXDSP, BIT_EN_RXDSP, 0x1); ++ rtw_write32(rtwdev, REG_OFDM1_CSI1, 0x00000000); ++ rtw_write32(rtwdev, REG_OFDM1_CSI2, 0x00000000); ++ rtw_write32(rtwdev, REG_OFDM1_CSI3, 0x00000000); ++ rtw_write32(rtwdev, REG_OFDM1_CSI4, 0x00180000); ++ rtw_write32_mask(rtwdev, REG_OFDM1_CFOTRK, BIT_EN_CFOTRK, 0x1); ++ break; ++ default: ++ rtw_warn(rtwdev, ++ "Bug: Notch filter enable called for channel %u!", ++ channel); ++ rtw_write32_mask(rtwdev, REG_OFDM0_RXDSP, BIT_EN_RXDSP, 0x0); ++ rtw_write32_mask(rtwdev, REG_OFDM1_CFOTRK, BIT_EN_CFOTRK, 0x0); ++ break; ++ } ++} ++ ++static void rtw8703b_spur_cal(struct rtw_dev *rtwdev, u8 channel) ++{ ++ bool notch; ++ u32 freq; ++ ++ if (channel == 5) { ++ freq = FREQ_CH5; ++ } else if (channel == 6) { ++ freq = FREQ_CH6; ++ } else if (channel == 7) { ++ freq = FREQ_CH7; ++ } else if (channel == 8) { ++ freq = FREQ_CH8; ++ } else if (channel == 13) { ++ freq = FREQ_CH13; ++ } else if (channel == 14) { ++ freq = FREQ_CH14; ++ } else { ++ rtw8703b_cfg_notch(rtwdev, channel, false); ++ return; ++ } ++ ++ notch = rtw8703b_check_spur_ov_thres(rtwdev, freq, SPUR_THRES); ++ rtw8703b_cfg_notch(rtwdev, channel, notch); ++} ++ ++static void rtw8703b_set_channel_rf(struct rtw_dev *rtwdev, u8 channel, u8 bw) ++{ ++ u32 rf_cfgch_a; ++ u32 rf_cfgch_b; ++ /* default value for 20M */ ++ u32 rf_rck = 0x00000C08; ++ ++ rf_cfgch_a = rtw_read_rf(rtwdev, RF_PATH_A, RF_CFGCH, RFREG_MASK); ++ rf_cfgch_b = rtw_read_rf(rtwdev, RF_PATH_B, RF_CFGCH, RFREG_MASK); ++ ++ rf_cfgch_a &= ~RFCFGCH_CHANNEL_MASK; ++ rf_cfgch_b &= ~RFCFGCH_CHANNEL_MASK; ++ rf_cfgch_a |= (channel & RFCFGCH_CHANNEL_MASK); ++ rf_cfgch_b |= (channel & RFCFGCH_CHANNEL_MASK); ++ ++ rf_cfgch_a &= ~RFCFGCH_BW_MASK; ++ switch (bw) { ++ case RTW_CHANNEL_WIDTH_20: ++ rf_cfgch_a |= RFCFGCH_BW_20M; ++ break; ++ case RTW_CHANNEL_WIDTH_40: ++ rf_cfgch_a |= RFCFGCH_BW_40M; ++ rf_rck = 0x00000C4C; ++ break; ++ default: ++ break; ++ } ++ ++ rtw_write_rf(rtwdev, RF_PATH_A, RF_CFGCH, RFREG_MASK, rf_cfgch_a); ++ rtw_write_rf(rtwdev, RF_PATH_B, RF_CFGCH, RFREG_MASK, rf_cfgch_b); ++ ++ rtw_write_rf(rtwdev, RF_PATH_A, RF_RCK1, RFREG_MASK, rf_rck); ++ rtw8703b_spur_cal(rtwdev, channel); ++} ++ ++#define CCK_DFIR_NR_8703B 2 ++static const struct rtw_backup_info cck_dfir_cfg[][CCK_DFIR_NR_8703B] = { ++ [0] = { ++ { .len = 4, .reg = REG_CCK_TXSF2, .val = 0x5A7DA0BD }, ++ { .len = 4, .reg = REG_CCK_DBG, .val = 0x0000223B }, ++ }, ++ [1] = { ++ { .len = 4, .reg = REG_CCK_TXSF2, .val = 0x00000000 }, ++ { .len = 4, .reg = REG_CCK_DBG, .val = 0x00000000 }, ++ }, ++}; ++ ++static void rtw8703b_set_channel_bb(struct rtw_dev *rtwdev, u8 channel, u8 bw, ++ u8 primary_ch_idx) ++{ ++ const struct rtw_backup_info *cck_dfir; ++ int i; ++ ++ cck_dfir = channel <= 13 ? cck_dfir_cfg[0] : cck_dfir_cfg[1]; ++ ++ for (i = 0; i < CCK_DFIR_NR_8703B; i++, cck_dfir++) ++ rtw_write32(rtwdev, cck_dfir->reg, cck_dfir->val); ++ ++ switch (bw) { ++ case RTW_CHANNEL_WIDTH_20: ++ 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); ++ rtw_write32(rtwdev, REG_BBRX_DFIR, 0x4A880000); ++ rtw_write32(rtwdev, REG_OFDM0_A_TX_AFE, 0x19F60000); ++ break; ++ case RTW_CHANNEL_WIDTH_40: ++ rtw_write32_mask(rtwdev, REG_FPGA0_RFMOD, BIT_MASK_RFMOD, 0x1); ++ rtw_write32_mask(rtwdev, REG_FPGA1_RFMOD, BIT_MASK_RFMOD, 0x1); ++ rtw_write32(rtwdev, REG_BBRX_DFIR, 0x40100000); ++ rtw_write32(rtwdev, REG_OFDM0_A_TX_AFE, 0x51F60000); ++ rtw_write32_mask(rtwdev, REG_CCK0_SYS, BIT_CCK_SIDE_BAND, ++ primary_ch_idx == RTW_SC_20_UPPER ? 1 : 0); ++ rtw_write32_mask(rtwdev, REG_OFDM_FA_RSTD_11N, 0xC00, ++ primary_ch_idx == RTW_SC_20_UPPER ? 2 : 1); ++ ++ rtw_write32_mask(rtwdev, REG_BB_PWR_SAV5_11N, GENMASK(27, 26), ++ primary_ch_idx == RTW_SC_20_UPPER ? 1 : 2); ++ break; ++ default: ++ break; ++ } ++} ++ ++static void rtw8703b_set_channel(struct rtw_dev *rtwdev, u8 channel, ++ u8 bw, u8 primary_chan_idx) ++{ ++ rtw8703b_set_channel_rf(rtwdev, channel, bw); ++ rtw_set_channel_mac(rtwdev, channel, bw, primary_chan_idx); ++ rtw8703b_set_channel_bb(rtwdev, channel, bw, primary_chan_idx); ++} ++ ++/* Not all indices are valid, based on available data. None of the ++ * known valid values are positive, so use 0x7f as "invalid". ++ */ ++#define LNA_IDX_INVALID 0x7f ++static const s8 lna_gain_table[16] = { ++ -2, LNA_IDX_INVALID, LNA_IDX_INVALID, LNA_IDX_INVALID, ++ -6, LNA_IDX_INVALID, LNA_IDX_INVALID, -19, ++ -32, LNA_IDX_INVALID, -36, -42, ++ LNA_IDX_INVALID, LNA_IDX_INVALID, LNA_IDX_INVALID, -48, ++}; ++ ++static s8 get_cck_rx_pwr(struct rtw_dev *rtwdev, u8 lna_idx, u8 vga_idx) ++{ ++ s8 lna_gain = 0; ++ ++ if (lna_idx < ARRAY_SIZE(lna_gain_table)) ++ lna_gain = lna_gain_table[lna_idx]; ++ ++ if (lna_gain >= 0) { ++ rtw_warn(rtwdev, "incorrect lna index (%d)\n", lna_idx); ++ return -120; ++ } ++ ++ return lna_gain - 2 * vga_idx; ++} ++ ++static void query_phy_status_cck(struct rtw_dev *rtwdev, u8 *phy_raw, ++ struct rtw_rx_pkt_stat *pkt_stat) ++{ ++ struct phy_status_8703b *phy_status = (struct phy_status_8703b *)phy_raw; ++ u8 vga_idx = phy_status->cck_agc_rpt_ofdm_cfosho_a & VGA_BITS; ++ u8 lna_idx = phy_status->cck_agc_rpt_ofdm_cfosho_a & LNA_L_BITS; ++ s8 rx_power; ++ ++ if (rtwdev->dm_info.rx_cck_agc_report_type == 1) ++ lna_idx = FIELD_PREP(BIT_LNA_H_MASK, ++ phy_status->cck_rpt_b_ofdm_cfosho_b & LNA_H_BIT) ++ | FIELD_PREP(BIT_LNA_L_MASK, lna_idx); ++ else ++ lna_idx = FIELD_PREP(BIT_LNA_L_MASK, lna_idx); ++ rx_power = get_cck_rx_pwr(rtwdev, lna_idx, vga_idx); ++ ++ pkt_stat->rx_power[RF_PATH_A] = rx_power; ++ pkt_stat->rssi = rtw_phy_rf_power_2_rssi(pkt_stat->rx_power, 1); ++ rtwdev->dm_info.rssi[RF_PATH_A] = pkt_stat->rssi; ++ pkt_stat->signal_power = rx_power; ++} ++ ++static void query_phy_status_ofdm(struct rtw_dev *rtwdev, u8 *phy_raw, ++ struct rtw_rx_pkt_stat *pkt_stat) ++{ ++ struct phy_status_8703b *phy_status = (struct phy_status_8703b *)phy_raw; ++ struct rtw_dm_info *dm_info = &rtwdev->dm_info; ++ s8 val_s8; ++ ++ val_s8 = phy_status->path_agc[RF_PATH_A].gain & 0x3F; ++ pkt_stat->rx_power[RF_PATH_A] = (val_s8 * 2) - 110; ++ pkt_stat->rssi = rtw_phy_rf_power_2_rssi(pkt_stat->rx_power, 1); ++ pkt_stat->rx_snr[RF_PATH_A] = (s8)(phy_status->path_rxsnr[RF_PATH_A] / 2); ++ ++ /* signal power reported by HW */ ++ val_s8 = phy_status->cck_sig_qual_ofdm_pwdb_all >> 1; ++ pkt_stat->signal_power = (val_s8 & 0x7f) - 110; ++ ++ pkt_stat->rx_evm[RF_PATH_A] = phy_status->stream_rxevm[RF_PATH_A]; ++ pkt_stat->cfo_tail[RF_PATH_A] = phy_status->path_cfotail[RF_PATH_A]; ++ ++ dm_info->curr_rx_rate = pkt_stat->rate; ++ dm_info->rssi[RF_PATH_A] = pkt_stat->rssi; ++ dm_info->rx_snr[RF_PATH_A] = pkt_stat->rx_snr[RF_PATH_A] >> 1; ++ /* convert to KHz (used only for debugfs) */ ++ dm_info->cfo_tail[RF_PATH_A] = (pkt_stat->cfo_tail[RF_PATH_A] * 5) >> 1; ++ ++ /* (EVM value as s8 / 2) is dbm, should usually be in -33 to 0 ++ * range. rx_evm_dbm needs the absolute (positive) value. ++ */ ++ val_s8 = (s8)pkt_stat->rx_evm[RF_PATH_A]; ++ val_s8 = clamp_t(s8, -val_s8 >> 1, 0, 64); ++ val_s8 &= 0x3F; /* 64->0: second path of 1SS rate is 64 */ ++ dm_info->rx_evm_dbm[RF_PATH_A] = val_s8; ++} ++ ++static void query_phy_status(struct rtw_dev *rtwdev, u8 *phy_status, ++ struct rtw_rx_pkt_stat *pkt_stat) ++{ ++ if (pkt_stat->rate <= DESC_RATE11M) ++ query_phy_status_cck(rtwdev, phy_status, pkt_stat); ++ else ++ 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 ++void rtw8703b_iqk_config_mac(struct rtw_dev *rtwdev, ++ const struct rtw8723x_iqk_backup_regs *backup) ++{ ++ rtw_write8(rtwdev, rtw8723x_common.iqk_mac8_regs[0], 0x3F); ++ for (int i = 1; i < RTW8723X_IQK_MAC8_REG_NUM; i++) ++ rtw_write8(rtwdev, rtw8723x_common.iqk_mac8_regs[i], ++ backup->mac8[i] & (~BIT(3))); ++} ++ ++#define IQK_LTE_WRITE_VAL_8703B 0x00007700 ++#define IQK_DELAY_TIME_8703B 4 ++ ++static void rtw8703b_iqk_one_shot(struct rtw_dev *rtwdev, bool tx) ++{ ++ u32 regval; ++ ktime_t t; ++ s64 dur; ++ int ret; ++ ++ /* enter IQK mode */ ++ rtw_write32_mask(rtwdev, REG_FPGA0_IQK_11N, BIT_MASK_IQK_MOD, EN_IQK); ++ rtw8723x_iqk_config_lte_path_gnt(rtwdev, IQK_LTE_WRITE_VAL_8703B); ++ ++ /* One shot, LOK & IQK */ ++ rtw_write32(rtwdev, REG_IQK_AGC_PTS_11N, 0xf9000000); ++ rtw_write32(rtwdev, REG_IQK_AGC_PTS_11N, 0xf8000000); ++ ++ t = ktime_get(); ++ msleep(IQK_DELAY_TIME_8703B); ++ ret = read_poll_timeout(rtw_read32, regval, regval != 0, 1000, ++ 100000, false, rtwdev, ++ REG_IQK_RDY); ++ dur = ktime_us_delta(ktime_get(), t); ++ ++ if (ret) ++ rtw_warn(rtwdev, "[IQK] %s timed out after %lldus!\n", ++ tx ? "TX" : "RX", dur); ++ else ++ rtw_dbg(rtwdev, RTW_DBG_RFK, ++ "[IQK] %s done after %lldus\n", ++ tx ? "TX" : "RX", dur); ++} ++ ++static void rtw8703b_iqk_txrx_path_post(struct rtw_dev *rtwdev, ++ const struct rtw8723x_iqk_backup_regs *backup) ++{ ++ rtw8723x_iqk_restore_lte_path_gnt(rtwdev, backup); ++ rtw_write32(rtwdev, REG_BB_SEL_BTG, backup->bb_sel_btg); ++ ++ /* leave IQK mode */ ++ rtw_write32_mask(rtwdev, REG_FPGA0_IQK_11N, BIT_MASK_IQK_MOD, RST_IQK); ++ rtw_write_rf(rtwdev, RF_PATH_A, RF_LUTDBG, 0x800, 0x0); ++} ++ ++static u8 rtw8703b_iqk_check_tx_failed(struct rtw_dev *rtwdev) ++{ ++ s32 tx_x, tx_y; ++ u32 tx_fail; ++ ++ rtw_dbg(rtwdev, RTW_DBG_RFK, "[IQK] 0xeac = 0x%x\n", ++ rtw_read32(rtwdev, REG_IQK_RES_RY)); ++ rtw_dbg(rtwdev, RTW_DBG_RFK, "[IQK] 0xe94 = 0x%x, 0xe9c = 0x%x\n", ++ 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(after IQK) = 0x%x\n", ++ rtw_read32(rtwdev, REG_IQK_RDY), ++ rtw_read32(rtwdev, 0xe98)); ++ ++ tx_fail = rtw_read32_mask(rtwdev, REG_IQK_RES_RY, BIT_IQK_TX_FAIL); ++ tx_x = rtw_read32_mask(rtwdev, REG_IQK_RES_TX, BIT_MASK_RES_TX); ++ tx_y = rtw_read32_mask(rtwdev, REG_IQK_RES_TY, BIT_MASK_RES_TY); ++ ++ if (!tx_fail && tx_x != IQK_TX_X_ERR && tx_y != IQK_TX_Y_ERR) ++ return IQK_TX_OK; ++ ++ rtw_dbg(rtwdev, RTW_DBG_RFK, "[IQK] A TX IQK failed\n"); ++ ++ return 0; ++} ++ ++static u8 rtw8703b_iqk_check_rx_failed(struct rtw_dev *rtwdev) ++{ ++ s32 rx_x, rx_y; ++ u32 rx_fail; ++ ++ rtw_dbg(rtwdev, RTW_DBG_RFK, "[IQK] 0xea4 = 0x%x, 0xeac = 0x%x\n", ++ rtw_read32(rtwdev, REG_IQK_RES_RX), ++ rtw_read32(rtwdev, REG_IQK_RES_RY)); ++ ++ rtw_dbg(rtwdev, RTW_DBG_RFK, ++ "[IQK] 0xea0(before IQK) = 0x%x, 0xea8(after IQK) = 0x%x\n", ++ rtw_read32(rtwdev, 0xea0), ++ rtw_read32(rtwdev, 0xea8)); ++ ++ rx_fail = rtw_read32_mask(rtwdev, REG_IQK_RES_RY, BIT_IQK_RX_FAIL); ++ rx_x = rtw_read32_mask(rtwdev, REG_IQK_RES_RX, BIT_MASK_RES_RX); ++ rx_y = rtw_read32_mask(rtwdev, REG_IQK_RES_RY, BIT_MASK_RES_RY); ++ rx_y = abs(iqkxy_to_s32(rx_y)); ++ ++ if (!rx_fail && rx_x != IQK_RX_X_ERR && rx_y != IQK_RX_Y_ERR && ++ rx_x < IQK_RX_X_UPPER && rx_x > IQK_RX_X_LOWER && ++ rx_y < IQK_RX_Y_LMT) ++ return IQK_RX_OK; ++ ++ rtw_dbg(rtwdev, RTW_DBG_RFK, "[IQK] A RX IQK failed\n"); ++ ++ return 0; ++} ++ ++static u8 rtw8703b_iqk_tx_path(struct rtw_dev *rtwdev, ++ const struct rtw8723x_iqk_backup_regs *backup) ++{ ++ u8 status; ++ ++ rtw_dbg(rtwdev, RTW_DBG_RFK, "[IQK] path A TX IQK!\n"); ++ ++ /* IQK setting */ ++ rtw_write32(rtwdev, REG_TXIQK_11N, 0x01007c00); ++ rtw_write32(rtwdev, REG_RXIQK_11N, 0x01004800); ++ rtw_write32(rtwdev, REG_TXIQK_TONE_A_11N, 0x18008c1c); ++ 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, 0x8214030f); ++ rtw_write32(rtwdev, REG_RXIQK_PI_A_11N, 0x28110000); ++ rtw_write32(rtwdev, REG_TXIQK_PI_B, 0x82110000); ++ rtw_write32(rtwdev, REG_RXIQK_PI_B, 0x28110000); ++ ++ /* LO calibration setting */ ++ rtw_write32(rtwdev, REG_IQK_AGC_RSP_11N, 0x00462911); ++ ++ /* leave IQK mode */ ++ rtw_write32_mask(rtwdev, REG_FPGA0_IQK_11N, 0xffffff00, 0x000000); ++ ++ /* PA, PAD setting */ ++ rtw_write_rf(rtwdev, RF_PATH_A, RF_LUTDBG, 0x800, 0x1); ++ rtw_write_rf(rtwdev, RF_PATH_A, 0x55, 0x7f, 0x7); ++ rtw_write_rf(rtwdev, RF_PATH_A, 0x7f, RFREG_MASK, 0xd400); ++ ++ rtw8703b_iqk_one_shot(rtwdev, true); ++ status = rtw8703b_iqk_check_tx_failed(rtwdev); ++ ++ rtw8703b_iqk_txrx_path_post(rtwdev, backup); ++ ++ return status; ++} ++ ++static u8 rtw8703b_iqk_rx_path(struct rtw_dev *rtwdev, ++ const struct rtw8723x_iqk_backup_regs *backup) ++{ ++ u8 status; ++ u32 tx_x, tx_y; ++ ++ rtw_dbg(rtwdev, RTW_DBG_RFK, "[IQK] path A RX IQK step 1!\n"); ++ rtw_dbg(rtwdev, RTW_DBG_RFK, "[IQK] 0x67 @A RX IQK1 = 0x%x\n", ++ rtw_read32_mask(rtwdev, REG_PAD_CTRL1, MASKBYTE3)); ++ rtw_write32(rtwdev, REG_BB_SEL_BTG, 0x99000000); ++ ++ /* disable IQC mode */ ++ rtw_write32_mask(rtwdev, REG_FPGA0_IQK_11N, BIT_MASK_IQK_MOD, RST_IQK); ++ ++ /* IQK setting */ ++ rtw_write32(rtwdev, REG_TXIQK_11N, 0x01007c00); ++ rtw_write32(rtwdev, REG_RXIQK_11N, 0x01004800); ++ ++ /* path IQK setting */ ++ rtw_write32(rtwdev, REG_TXIQK_TONE_A_11N, 0x18008c1c); ++ 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_RXIQK_PI_A_11N, 0x28110000); ++ rtw_write32(rtwdev, REG_TXIQK_PI_B, 0x28110000); ++ rtw_write32(rtwdev, REG_RXIQK_PI_B, 0x28110000); ++ ++ /* LOK setting */ ++ rtw_write32(rtwdev, REG_IQK_AGC_RSP_11N, 0x0046a911); ++ ++ /* RX IQK mode */ ++ rtw_write_rf(rtwdev, RF_PATH_A, RF_LUTWE, 0x80000, 0x1); ++ rtw_write_rf(rtwdev, RF_PATH_A, 0x30, RFREG_MASK, 0x30000); ++ rtw_write_rf(rtwdev, RF_PATH_A, 0x31, RFREG_MASK, 0x00007); ++ rtw_write_rf(rtwdev, RF_PATH_A, 0x32, RFREG_MASK, 0x57db7); ++ ++ rtw8703b_iqk_one_shot(rtwdev, true); ++ /* leave IQK mode */ ++ rtw_write32_mask(rtwdev, REG_FPGA0_IQK_11N, 0xffffff00, 0x000000); ++ status = rtw8703b_iqk_check_tx_failed(rtwdev); ++ ++ if (!status) ++ goto restore; ++ ++ /* second round */ ++ tx_x = rtw_read32_mask(rtwdev, REG_IQK_RES_TX, BIT_MASK_RES_TX); ++ tx_y = rtw_read32_mask(rtwdev, REG_IQK_RES_TY, BIT_MASK_RES_TY); ++ ++ rtw_write32(rtwdev, REG_TXIQK_11N, BIT_SET_TXIQK_11N(tx_x, tx_y)); ++ rtw_dbg(rtwdev, RTW_DBG_RFK, "[IQK] 0xe40 = 0x%x u4tmp = 0x%x\n", ++ rtw_read32(rtwdev, REG_TXIQK_11N), ++ BIT_SET_TXIQK_11N(tx_x, tx_y)); ++ ++ rtw_dbg(rtwdev, RTW_DBG_RFK, "[IQK] path A RX IQK step 2!\n"); ++ rtw_dbg(rtwdev, RTW_DBG_RFK, "[IQK] 0x67 @A RX IQK 2 = 0x%x\n", ++ rtw_read32_mask(rtwdev, REG_PAD_CTRL1, MASKBYTE3)); ++ ++ /* IQK setting */ ++ rtw_write32(rtwdev, REG_RXIQK_11N, 0x01004800); ++ rtw_write32(rtwdev, REG_TXIQK_TONE_A_11N, 0x38008c1c); ++ rtw_write32(rtwdev, REG_RXIQK_TONE_A_11N, 0x18008c1c); ++ 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, 0x82110000); ++ rtw_write32(rtwdev, REG_RXIQK_PI_A_11N, 0x28160c1f); ++ rtw_write32(rtwdev, REG_TXIQK_PI_B, 0x82110000); ++ rtw_write32(rtwdev, REG_RXIQK_PI_B, 0x28110000); ++ ++ /* LO calibration setting */ ++ rtw_write32(rtwdev, REG_IQK_AGC_RSP_11N, 0x0046a8d1); ++ ++ /* leave IQK mode */ ++ rtw_write32_mask(rtwdev, REG_FPGA0_IQK_11N, 0xffffff00, 0x000000); ++ /* modify RX IQK mode table */ ++ rtw_write_rf(rtwdev, RF_PATH_A, RF_LUTWE, 0x80000, 0x1); ++ /* RF_RCK_OS, RF_TXPA_G1, RF_TXPA_G2 */ ++ rtw_write_rf(rtwdev, RF_PATH_A, 0x30, RFREG_MASK, 0x30000); ++ rtw_write_rf(rtwdev, RF_PATH_A, 0x31, RFREG_MASK, 0x00007); ++ rtw_write_rf(rtwdev, RF_PATH_A, 0x32, RFREG_MASK, 0xf7d77); ++ ++ /* PA, PAD setting */ ++ rtw_write_rf(rtwdev, RF_PATH_A, RF_LUTDBG, 0x800, 0x1); ++ rtw_write_rf(rtwdev, RF_PATH_A, 0x55, 0x7f, 0x5); ++ ++ rtw8703b_iqk_one_shot(rtwdev, false); ++ status |= rtw8703b_iqk_check_rx_failed(rtwdev); ++ ++restore: ++ rtw8703b_iqk_txrx_path_post(rtwdev, backup); ++ ++ return status; ++} ++ ++static ++void rtw8703b_iqk_one_round(struct rtw_dev *rtwdev, s32 result[][IQK_NR], u8 t, ++ const struct rtw8723x_iqk_backup_regs *backup) ++{ ++ u32 i; ++ u8 a_ok; ++ ++ rtw_dbg(rtwdev, RTW_DBG_RFK, ++ "[IQK] IQ Calibration for 1T1R_S0/S1 for %d times\n", t); ++ ++ rtw8723x_iqk_path_adda_on(rtwdev, ADDA_ON_VAL_8703B); ++ rtw8703b_iqk_config_mac(rtwdev, backup); ++ rtw_write32_mask(rtwdev, REG_CCK_ANT_SEL_11N, 0x0f000000, 0xf); ++ rtw_write32(rtwdev, REG_BB_RX_PATH_11N, 0x03a05600); ++ rtw_write32(rtwdev, REG_TRMUX_11N, 0x000800e4); ++ rtw_write32(rtwdev, REG_BB_PWR_SAV1_11N, 0x25204000); ++ ++ for (i = 0; i < PATH_IQK_RETRY; i++) { ++ a_ok = rtw8703b_iqk_tx_path(rtwdev, backup); ++ if (a_ok == IQK_TX_OK) { ++ rtw_dbg(rtwdev, RTW_DBG_RFK, ++ "[IQK] path A TX IQK success!\n"); ++ result[t][IQK_S1_TX_X] = ++ rtw_read32_mask(rtwdev, REG_IQK_RES_TX, ++ BIT_MASK_RES_TX); ++ result[t][IQK_S1_TX_Y] = ++ rtw_read32_mask(rtwdev, REG_IQK_RES_TY, ++ BIT_MASK_RES_TY); ++ break; ++ } ++ ++ rtw_dbg(rtwdev, RTW_DBG_RFK, "[IQK] path A TX IQK fail!\n"); ++ result[t][IQK_S1_TX_X] = 0x100; ++ result[t][IQK_S1_TX_Y] = 0x0; ++ } ++ ++ for (i = 0; i < PATH_IQK_RETRY; i++) { ++ a_ok = rtw8703b_iqk_rx_path(rtwdev, backup); ++ if (a_ok == (IQK_TX_OK | IQK_RX_OK)) { ++ rtw_dbg(rtwdev, RTW_DBG_RFK, ++ "[IQK] path A RX IQK success!\n"); ++ result[t][IQK_S1_RX_X] = ++ rtw_read32_mask(rtwdev, REG_IQK_RES_RX, ++ BIT_MASK_RES_RX); ++ result[t][IQK_S1_RX_Y] = ++ rtw_read32_mask(rtwdev, REG_IQK_RES_RY, ++ BIT_MASK_RES_RY); ++ break; ++ } ++ ++ rtw_dbg(rtwdev, RTW_DBG_RFK, "[IQK] path A RX IQK fail!\n"); ++ result[t][IQK_S1_RX_X] = 0x100; ++ result[t][IQK_S1_RX_Y] = 0x0; ++ } ++ ++ if (a_ok == 0x0) ++ rtw_dbg(rtwdev, RTW_DBG_RFK, "[IQK] path A IQK fail!\n"); ++ ++ rtw_write32_mask(rtwdev, REG_FPGA0_IQK_11N, BIT_MASK_IQK_MOD, RST_IQK); ++ mdelay(1); ++} ++ ++static ++void rtw8703b_iqk_fill_a_matrix(struct rtw_dev *rtwdev, const s32 result[]) ++{ ++ u32 tmp_rx_iqi = 0x40000100 & GENMASK(31, 16); ++ s32 tx1_a, tx1_a_ext; ++ s32 tx1_c, tx1_c_ext; ++ s32 oldval_1; ++ s32 x, y; ++ ++ if (result[IQK_S1_TX_X] == 0) ++ return; ++ ++ oldval_1 = rtw_read32_mask(rtwdev, REG_OFDM_0_XA_TX_IQ_IMBALANCE, ++ BIT_MASK_TXIQ_ELM_D); ++ ++ x = iqkxy_to_s32(result[IQK_S1_TX_X]); ++ tx1_a = iqk_mult(x, oldval_1, &tx1_a_ext); ++ rtw_write32_mask(rtwdev, REG_OFDM_0_XA_TX_IQ_IMBALANCE, ++ BIT_MASK_TXIQ_ELM_A, tx1_a); ++ rtw_write32_mask(rtwdev, REG_OFDM_0_ECCA_THRESHOLD, ++ BIT_MASK_OFDM0_EXT_A, tx1_a_ext); ++ ++ y = iqkxy_to_s32(result[IQK_S1_TX_Y]); ++ tx1_c = iqk_mult(y, oldval_1, &tx1_c_ext); ++ rtw_write32_mask(rtwdev, REG_TXIQK_MATRIXA_LSB2_11N, MASKH4BITS, ++ BIT_SET_TXIQ_ELM_C1(tx1_c)); ++ rtw_write32_mask(rtwdev, REG_OFDM_0_XA_TX_IQ_IMBALANCE, ++ BIT_MASK_TXIQ_ELM_C, BIT_SET_TXIQ_ELM_C2(tx1_c)); ++ rtw_write32_mask(rtwdev, REG_OFDM_0_ECCA_THRESHOLD, ++ BIT_MASK_OFDM0_EXT_C, tx1_c_ext); ++ ++ rtw_dbg(rtwdev, RTW_DBG_RFK, ++ "[IQK] X = 0x%x, TX1_A = 0x%x, oldval_1 0x%x\n", ++ x, tx1_a, oldval_1); ++ rtw_dbg(rtwdev, RTW_DBG_RFK, ++ "[IQK] Y = 0x%x, TX1_C = 0x%x\n", y, tx1_c); ++ ++ if (result[IQK_S1_RX_X] == 0) ++ 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]); ++ 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])); ++} ++ ++static void rtw8703b_phy_calibration(struct rtw_dev *rtwdev) ++{ ++ /* For some reason path A is called S1 and B S0 in shared ++ * rtw88 calibration data. ++ */ ++ struct rtw_dm_info *dm_info = &rtwdev->dm_info; ++ struct rtw8723x_iqk_backup_regs backup; ++ u8 final_candidate = IQK_ROUND_INVALID; ++ s32 result[IQK_ROUND_SIZE][IQK_NR]; ++ bool good; ++ u8 i, j; ++ ++ rtw_dbg(rtwdev, RTW_DBG_RFK, "[IQK] Start!\n"); ++ ++ memset(result, 0, sizeof(result)); ++ ++ rtw8723x_iqk_backup_path_ctrl(rtwdev, &backup); ++ rtw8723x_iqk_backup_lte_path_gnt(rtwdev, &backup); ++ rtw8723x_iqk_backup_regs(rtwdev, &backup); ++ ++ for (i = IQK_ROUND_0; i <= IQK_ROUND_2; i++) { ++ rtw8723x_iqk_config_path_ctrl(rtwdev); ++ rtw8723x_iqk_config_lte_path_gnt(rtwdev, IQK_LTE_WRITE_VAL_8703B); ++ ++ rtw8703b_iqk_one_round(rtwdev, result, i, &backup); ++ ++ rtw_dbg(rtwdev, RTW_DBG_RFK, ++ "[IQK] back to BB mode, load original values!\n"); ++ if (i > IQK_ROUND_0) ++ rtw8723x_iqk_restore_regs(rtwdev, &backup); ++ rtw8723x_iqk_restore_lte_path_gnt(rtwdev, &backup); ++ rtw8723x_iqk_restore_path_ctrl(rtwdev, &backup); ++ ++ for (j = IQK_ROUND_0; j < i; j++) { ++ good = rtw8723x_iqk_similarity_cmp(rtwdev, result, j, i); ++ ++ if (good) { ++ final_candidate = j; ++ rtw_dbg(rtwdev, RTW_DBG_RFK, ++ "[IQK] cmp %d:%d final_candidate is %x\n", ++ j, i, final_candidate); ++ goto iqk_done; ++ } ++ } ++ } ++ ++ if (final_candidate == IQK_ROUND_INVALID) { ++ s32 reg_tmp = 0; ++ ++ for (i = 0; i < IQK_NR; i++) ++ reg_tmp += result[IQK_ROUND_HYBRID][i]; ++ ++ if (reg_tmp != 0) { ++ final_candidate = IQK_ROUND_HYBRID; ++ } else { ++ WARN(1, "IQK failed\n"); ++ goto out; ++ } ++ } ++ ++iqk_done: ++ /* only path A is calibrated in rtl8703b */ ++ rtw8703b_iqk_fill_a_matrix(rtwdev, result[final_candidate]); ++ ++ dm_info->iqk.result.s1_x = result[final_candidate][IQK_S1_TX_X]; ++ dm_info->iqk.result.s1_y = result[final_candidate][IQK_S1_TX_Y]; ++ dm_info->iqk.result.s0_x = result[final_candidate][IQK_S0_TX_X]; ++ dm_info->iqk.result.s0_y = result[final_candidate][IQK_S0_TX_Y]; ++ dm_info->iqk.done = true; ++ ++out: ++ rtw_write32(rtwdev, REG_BB_SEL_BTG, backup.bb_sel_btg); ++ ++ rtw_dbg(rtwdev, RTW_DBG_RFK, "[IQK] final_candidate is %x\n", ++ final_candidate); ++ ++ for (i = IQK_ROUND_0; i < IQK_ROUND_SIZE; i++) ++ rtw_dbg(rtwdev, RTW_DBG_RFK, ++ "[IQK] Result %u: rege94_s1=%x rege9c_s1=%x regea4_s1=%x regeac_s1=%x rege94_s0=%x rege9c_s0=%x regea4_s0=%x regeac_s0=%x %s\n", ++ i, ++ result[i][0], result[i][1], result[i][2], result[i][3], ++ result[i][4], result[i][5], result[i][6], result[i][7], ++ final_candidate == i ? "(final candidate)" : ""); ++ ++ rtw_dbg(rtwdev, RTW_DBG_RFK, ++ "[IQK] 0xc80 = 0x%x 0xc94 = 0x%x 0xc14 = 0x%x 0xca0 = 0x%x\n", ++ rtw_read32(rtwdev, REG_OFDM_0_XA_TX_IQ_IMBALANCE), ++ rtw_read32(rtwdev, REG_TXIQK_MATRIXA_LSB2_11N), ++ rtw_read32(rtwdev, REG_A_RXIQI), ++ rtw_read32(rtwdev, REG_RXIQK_MATRIX_LSB_11N)); ++ rtw_dbg(rtwdev, RTW_DBG_RFK, ++ "[IQK] 0xcd0 = 0x%x 0xcd4 = 0x%x 0xcd8 = 0x%x\n", ++ rtw_read32(rtwdev, REG_TXIQ_AB_S0), ++ rtw_read32(rtwdev, REG_TXIQ_CD_S0), ++ rtw_read32(rtwdev, REG_RXIQ_AB_S0)); ++ ++ rtw_dbg(rtwdev, RTW_DBG_RFK, "[IQK] Finished.\n"); ++} ++ ++static void rtw8703b_set_iqk_matrix_by_result(struct rtw_dev *rtwdev, ++ u32 ofdm_swing, u8 rf_path) ++{ ++ struct rtw_dm_info *dm_info = &rtwdev->dm_info; ++ s32 ele_A, ele_D, ele_C; ++ s32 ele_A_ext, ele_C_ext, ele_D_ext; ++ s32 iqk_result_x; ++ s32 iqk_result_y; ++ s32 value32; ++ ++ switch (rf_path) { ++ default: ++ case RF_PATH_A: ++ iqk_result_x = dm_info->iqk.result.s1_x; ++ iqk_result_y = dm_info->iqk.result.s1_y; ++ break; ++ case RF_PATH_B: ++ iqk_result_x = dm_info->iqk.result.s0_x; ++ iqk_result_y = dm_info->iqk.result.s0_y; ++ break; ++ } ++ ++ /* new element D */ ++ ele_D = OFDM_SWING_D(ofdm_swing); ++ iqk_mult(iqk_result_x, ele_D, &ele_D_ext); ++ /* new element A */ ++ iqk_result_x = iqkxy_to_s32(iqk_result_x); ++ ele_A = iqk_mult(iqk_result_x, ele_D, &ele_A_ext); ++ /* new element C */ ++ iqk_result_y = iqkxy_to_s32(iqk_result_y); ++ ele_C = iqk_mult(iqk_result_y, ele_D, &ele_C_ext); ++ ++ switch (rf_path) { ++ case RF_PATH_A: ++ default: ++ /* write new elements A, C, D, and element B is always 0 */ ++ value32 = BIT_SET_TXIQ_ELM_ACD(ele_A, ele_C, ele_D); ++ rtw_write32(rtwdev, REG_OFDM_0_XA_TX_IQ_IMBALANCE, value32); ++ value32 = BIT_SET_TXIQ_ELM_C1(ele_C); ++ rtw_write32_mask(rtwdev, REG_TXIQK_MATRIXA_LSB2_11N, MASKH4BITS, ++ value32); ++ value32 = rtw_read32(rtwdev, REG_OFDM_0_ECCA_THRESHOLD); ++ value32 &= ~BIT_MASK_OFDM0_EXTS; ++ value32 |= BIT_SET_OFDM0_EXTS(ele_A_ext, ele_C_ext, ele_D_ext); ++ rtw_write32(rtwdev, REG_OFDM_0_ECCA_THRESHOLD, value32); ++ break; ++ ++ case RF_PATH_B: ++ /* write new elements A, C, D, and element B is always 0 */ ++ value32 = BIT_SET_TXIQ_ELM_ACD(ele_A, ele_C, ele_D); ++ rtw_write32(rtwdev, REG_OFDM_0_XB_TX_IQ_IMBALANCE, value32); ++ value32 = BIT_SET_TXIQ_ELM_C1(ele_C); ++ rtw_write32_mask(rtwdev, REG_TXIQK_MATRIXB_LSB2_11N, MASKH4BITS, ++ value32); ++ value32 = rtw_read32(rtwdev, REG_OFDM_0_ECCA_THRESHOLD); ++ value32 &= ~BIT_MASK_OFDM0_EXTS_B; ++ value32 |= BIT_SET_OFDM0_EXTS_B(ele_A_ext, ele_C_ext, ele_D_ext); ++ rtw_write32(rtwdev, REG_OFDM_0_ECCA_THRESHOLD, value32); ++ break; ++ } ++} ++ ++static void rtw8703b_set_iqk_matrix(struct rtw_dev *rtwdev, s8 ofdm_index, ++ u8 rf_path) ++{ ++ struct rtw_dm_info *dm_info = &rtwdev->dm_info; ++ s32 value32; ++ u32 ofdm_swing; ++ ++ ofdm_index = clamp_t(s8, ofdm_index, 0, RTW_OFDM_SWING_TABLE_SIZE - 1); ++ ++ ofdm_swing = rtw8703b_ofdm_swing_table[ofdm_index]; ++ ++ if (dm_info->iqk.done) { ++ rtw8703b_set_iqk_matrix_by_result(rtwdev, ofdm_swing, rf_path); ++ return; ++ } ++ ++ switch (rf_path) { ++ case RF_PATH_A: ++ default: ++ rtw_write32(rtwdev, REG_OFDM_0_XA_TX_IQ_IMBALANCE, ofdm_swing); ++ rtw_write32_mask(rtwdev, REG_TXIQK_MATRIXA_LSB2_11N, MASKH4BITS, ++ 0x00); ++ ++ value32 = rtw_read32(rtwdev, REG_OFDM_0_ECCA_THRESHOLD); ++ value32 &= ~BIT_MASK_OFDM0_EXTS; ++ rtw_write32(rtwdev, REG_OFDM_0_ECCA_THRESHOLD, value32); ++ break; ++ ++ case RF_PATH_B: ++ rtw_write32(rtwdev, REG_OFDM_0_XB_TX_IQ_IMBALANCE, ofdm_swing); ++ rtw_write32_mask(rtwdev, REG_TXIQK_MATRIXB_LSB2_11N, MASKH4BITS, ++ 0x00); ++ ++ value32 = rtw_read32(rtwdev, REG_OFDM_0_ECCA_THRESHOLD); ++ value32 &= ~BIT_MASK_OFDM0_EXTS_B; ++ rtw_write32(rtwdev, REG_OFDM_0_ECCA_THRESHOLD, value32); ++ break; ++ } ++} ++ ++static void rtw8703b_pwrtrack_set_ofdm_pwr(struct rtw_dev *rtwdev, s8 swing_idx, ++ s8 txagc_idx) ++{ ++ struct rtw_dm_info *dm_info = &rtwdev->dm_info; ++ ++ dm_info->txagc_remnant_ofdm = txagc_idx; ++ ++ /* Only path A is calibrated for rtl8703b */ ++ rtw8703b_set_iqk_matrix(rtwdev, swing_idx, RF_PATH_A); ++} ++ ++static void rtw8703b_pwrtrack_set_cck_pwr(struct rtw_dev *rtwdev, s8 swing_idx, ++ s8 txagc_idx) ++{ ++ struct rtw_dm_info *dm_info = &rtwdev->dm_info; ++ ++ dm_info->txagc_remnant_cck = txagc_idx; ++ ++ swing_idx = clamp_t(s8, swing_idx, 0, RTW_CCK_SWING_TABLE_SIZE - 1); ++ ++ BUILD_BUG_ON(ARRAY_SIZE(rtw8703b_cck_pwr_regs) ++ != ARRAY_SIZE(rtw8703b_cck_swing_table[0])); ++ ++ for (int i = 0; i < ARRAY_SIZE(rtw8703b_cck_pwr_regs); i++) ++ rtw_write8(rtwdev, rtw8703b_cck_pwr_regs[i], ++ rtw8703b_cck_swing_table[swing_idx][i]); ++} ++ ++static void rtw8703b_pwrtrack_set(struct rtw_dev *rtwdev, u8 path) ++{ ++ struct rtw_dm_info *dm_info = &rtwdev->dm_info; ++ struct rtw_hal *hal = &rtwdev->hal; ++ u8 limit_ofdm; ++ u8 limit_cck = 21; ++ s8 final_ofdm_swing_index; ++ s8 final_cck_swing_index; ++ ++ limit_ofdm = rtw8723x_pwrtrack_get_limit_ofdm(rtwdev); ++ ++ final_ofdm_swing_index = dm_info->default_ofdm_index + ++ dm_info->delta_power_index[path]; ++ final_cck_swing_index = dm_info->default_cck_index + ++ dm_info->delta_power_index[path]; ++ ++ if (final_ofdm_swing_index > limit_ofdm) ++ rtw8703b_pwrtrack_set_ofdm_pwr(rtwdev, limit_ofdm, ++ final_ofdm_swing_index - limit_ofdm); ++ else if (final_ofdm_swing_index < 0) ++ rtw8703b_pwrtrack_set_ofdm_pwr(rtwdev, 0, ++ final_ofdm_swing_index); ++ else ++ rtw8703b_pwrtrack_set_ofdm_pwr(rtwdev, final_ofdm_swing_index, 0); ++ ++ if (final_cck_swing_index > limit_cck) ++ rtw8703b_pwrtrack_set_cck_pwr(rtwdev, limit_cck, ++ final_cck_swing_index - limit_cck); ++ else if (final_cck_swing_index < 0) ++ rtw8703b_pwrtrack_set_cck_pwr(rtwdev, 0, ++ final_cck_swing_index); ++ else ++ rtw8703b_pwrtrack_set_cck_pwr(rtwdev, final_cck_swing_index, 0); ++ ++ rtw_phy_set_tx_power_level(rtwdev, hal->current_channel); ++} ++ ++static void rtw8703b_phy_pwrtrack(struct rtw_dev *rtwdev) ++{ ++ struct rtw_dm_info *dm_info = &rtwdev->dm_info; ++ struct rtw_swing_table swing_table; ++ u8 thermal_value, delta, path; ++ bool do_iqk = false; ++ ++ rtw_phy_config_swing_table(rtwdev, &swing_table); ++ ++ if (rtwdev->efuse.thermal_meter[0] == 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); ++ ++ do_iqk = rtw_phy_pwrtrack_need_iqk(rtwdev); ++ ++ if (do_iqk) ++ rtw8723x_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); ++ ++ delta = min_t(u8, delta, RTW_PWR_TRK_TBL_SZ - 1); ++ ++ for (path = 0; path < rtwdev->hal.rf_path_num; path++) { ++ s8 delta_cur, delta_last; ++ ++ delta_last = dm_info->delta_power_index[path]; ++ delta_cur = rtw_phy_pwrtrack_get_pwridx(rtwdev, &swing_table, ++ path, RF_PATH_A, delta); ++ if (delta_last == delta_cur) ++ continue; ++ ++ dm_info->delta_power_index[path] = delta_cur; ++ rtw8703b_pwrtrack_set(rtwdev, path); ++ } ++ ++ rtw8723x_pwrtrack_set_xtal(rtwdev, RF_PATH_A, delta); ++ ++iqk: ++ if (do_iqk) ++ rtw8703b_phy_calibration(rtwdev); ++} ++ ++static void rtw8703b_pwr_track(struct rtw_dev *rtwdev) ++{ ++ struct rtw_efuse *efuse = &rtwdev->efuse; ++ struct rtw_dm_info *dm_info = &rtwdev->dm_info; ++ ++ if (efuse->power_track_type != 0) { ++ rtw_warn(rtwdev, "unsupported power track type"); ++ return; ++ } ++ ++ 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; ++ } ++ ++ rtw8703b_phy_pwrtrack(rtwdev); ++ dm_info->pwr_trk_triggered = false; ++} ++ ++static void rtw8703b_coex_set_gnt_fix(struct rtw_dev *rtwdev) ++{ ++} ++ ++static void rtw8703b_coex_set_gnt_debug(struct rtw_dev *rtwdev) ++{ ++} ++ ++static void rtw8703b_coex_set_rfe_type(struct rtw_dev *rtwdev) ++{ ++ struct rtw_coex *coex = &rtwdev->coex; ++ struct rtw_coex_rfe *coex_rfe = &coex->rfe; ++ ++ coex_rfe->rfe_module_type = rtwdev->efuse.rfe_option; ++ coex_rfe->ant_switch_polarity = 0; ++ coex_rfe->ant_switch_exist = false; ++ coex_rfe->ant_switch_with_bt = false; ++ coex_rfe->ant_switch_diversity = false; ++ coex_rfe->wlg_at_btg = true; ++ ++ /* disable LTE coex on wifi side */ ++ rtw_coex_write_indirect_reg(rtwdev, LTE_COEX_CTRL, BIT_LTE_COEX_EN, 0x0); ++ rtw_coex_write_indirect_reg(rtwdev, LTE_WL_TRX_CTRL, MASKLWORD, 0xffff); ++ rtw_coex_write_indirect_reg(rtwdev, LTE_BT_TRX_CTRL, MASKLWORD, 0xffff); ++} ++ ++static void rtw8703b_coex_set_wl_tx_power(struct rtw_dev *rtwdev, u8 wl_pwr) ++{ ++} ++ ++static void rtw8703b_coex_set_wl_rx_gain(struct rtw_dev *rtwdev, bool low_gain) ++{ ++} ++ ++static const u8 rtw8703b_pwrtrk_2gb_n[] = { ++ 0, 0, 1, 2, 2, 3, 3, 4, 4, 4, 4, 5, 5, 6, 6, ++ 7, 7, 7, 7, 8, 8, 9, 9, 10, 10, 10, 11, 11, 11, 11 ++}; ++ ++static const u8 rtw8703b_pwrtrk_2gb_p[] = { ++ 0, 1, 2, 3, 3, 4, 4, 4, 4, 5, 5, 6, 7, 7, 7, ++ 8, 8, 9, 9, 10, 10, 11, 11, 12, 13, 13, 14, 14, 15, 15 ++}; ++ ++static const u8 rtw8703b_pwrtrk_2ga_n[] = { ++ 0, 0, 1, 2, 2, 3, 3, 4, 4, 4, 4, 5, 5, 6, 6, ++ 7, 7, 7, 7, 8, 8, 9, 9, 10, 10, 10, 11, 11, 11, 11 ++}; ++ ++static const u8 rtw8703b_pwrtrk_2ga_p[] = { ++ 0, 1, 2, 3, 3, 4, 4, 4, 4, 5, 5, 6, 7, 7, 7, ++ 8, 8, 9, 9, 10, 10, 11, 11, 12, 13, 13, 14, 14, 15, 15 ++}; ++ ++static const u8 rtw8703b_pwrtrk_2g_cck_b_n[] = { ++ 0, 0, 1, 2, 2, 3, 3, 4, 4, 4, 4, 5, 5, 6, 6, ++ 7, 7, 7, 7, 8, 8, 9, 9, 10, 10, 10, 11, 11, 11, 11 ++}; ++ ++static const u8 rtw8703b_pwrtrk_2g_cck_b_p[] = { ++ 0, 0, 1, 1, 2, 3, 3, 3, 4, 4, 4, 5, 6, 6, 6, ++ 7, 7, 8, 8, 8, 9, 10, 10, 10, 11, 11, 12, 12, 13, 13 ++}; ++ ++static const u8 rtw8703b_pwrtrk_2g_cck_a_n[] = { ++ 0, 0, 1, 2, 2, 3, 3, 4, 4, 4, 4, 5, 5, 6, 6, ++ 7, 7, 7, 7, 8, 8, 9, 9, 10, 10, 10, 11, 11, 11, 11 ++}; ++ ++static const u8 rtw8703b_pwrtrk_2g_cck_a_p[] = { ++ 0, 0, 1, 1, 2, 3, 3, 3, 4, 4, 4, 5, 6, 6, 6, ++ 7, 7, 8, 8, 8, 9, 10, 10, 10, 11, 11, 12, 12, 13, 13 ++}; ++ ++static const s8 rtw8703b_pwrtrk_xtal_n[] = { ++ 0, 0, 0, -1, -1, -1, -1, -2, -2, -2, -3, -3, -3, -3, -3, ++ -4, -2, -2, -1, -1, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1 ++}; ++ ++static const s8 rtw8703b_pwrtrk_xtal_p[] = { ++ 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 1, 0, -1, -1, -1, ++ -2, -3, -7, -9, -10, -11, -14, -16, -18, -20, -22, -24, -26, -28, -30 ++}; ++ ++static const struct rtw_pwr_track_tbl rtw8703b_rtw_pwr_track_tbl = { ++ .pwrtrk_2gb_n = rtw8703b_pwrtrk_2gb_n, ++ .pwrtrk_2gb_p = rtw8703b_pwrtrk_2gb_p, ++ .pwrtrk_2ga_n = rtw8703b_pwrtrk_2ga_n, ++ .pwrtrk_2ga_p = rtw8703b_pwrtrk_2ga_p, ++ .pwrtrk_2g_cckb_n = rtw8703b_pwrtrk_2g_cck_b_n, ++ .pwrtrk_2g_cckb_p = rtw8703b_pwrtrk_2g_cck_b_p, ++ .pwrtrk_2g_ccka_n = rtw8703b_pwrtrk_2g_cck_a_n, ++ .pwrtrk_2g_ccka_p = rtw8703b_pwrtrk_2g_cck_a_p, ++ .pwrtrk_xtal_n = rtw8703b_pwrtrk_xtal_n, ++ .pwrtrk_xtal_p = rtw8703b_pwrtrk_xtal_p, ++}; ++ ++/* Shared-Antenna Coex Table */ ++static const struct coex_table_para table_sant_8703b[] = { ++ {0xffffffff, 0xffffffff}, /* case-0 */ ++ {0x55555555, 0x55555555}, ++ {0x66555555, 0x66555555}, ++ {0xaaaaaaaa, 0xaaaaaaaa}, ++ {0x5a5a5a5a, 0x5a5a5a5a}, ++ {0xfafafafa, 0xfafafafa}, /* case-5 */ ++ {0x6a5a5555, 0xaaaaaaaa}, ++ {0x6a5a56aa, 0x6a5a56aa}, ++ {0x6a5a5a5a, 0x6a5a5a5a}, ++ {0x66555555, 0x5a5a5a5a}, ++ {0x66555555, 0x6a5a5a5a}, /* case-10 */ ++ {0x66555555, 0x6a5a5aaa}, ++ {0x66555555, 0x5a5a5aaa}, ++ {0x66555555, 0x6aaa5aaa}, ++ {0x66555555, 0xaaaa5aaa}, ++ {0x66555555, 0xaaaaaaaa}, /* case-15 */ ++ {0xffff55ff, 0xfafafafa}, ++ {0xffff55ff, 0x6afa5afa}, ++ {0xaaffffaa, 0xfafafafa}, ++ {0xaa5555aa, 0x5a5a5a5a}, ++ {0xaa5555aa, 0x6a5a5a5a}, /* case-20 */ ++ {0xaa5555aa, 0xaaaaaaaa}, ++ {0xffffffff, 0x5a5a5a5a}, ++ {0xffffffff, 0x5a5a5a5a}, ++ {0xffffffff, 0x55555555}, ++ {0xffffffff, 0x5a5a5aaa}, /* case-25 */ ++ {0x55555555, 0x5a5a5a5a}, ++ {0x55555555, 0xaaaaaaaa}, ++ {0x55555555, 0x6a5a6a5a}, ++ {0x66556655, 0x66556655}, ++ {0x66556aaa, 0x6a5a6aaa}, /* case-30 */ ++ {0xffffffff, 0x5aaa5aaa}, ++ {0x56555555, 0x5a5a5aaa}, ++}; ++ ++/* Shared-Antenna TDMA */ ++static const struct coex_tdma_para tdma_sant_8703b[] = { ++ { {0x00, 0x00, 0x00, 0x00, 0x00} }, /* case-0 */ ++ { {0x61, 0x45, 0x03, 0x11, 0x11} }, /* case-1 */ ++ { {0x61, 0x3a, 0x03, 0x11, 0x11} }, ++ { {0x61, 0x30, 0x03, 0x11, 0x11} }, ++ { {0x61, 0x20, 0x03, 0x11, 0x11} }, ++ { {0x61, 0x10, 0x03, 0x11, 0x11} }, /* case-5 */ ++ { {0x61, 0x45, 0x03, 0x11, 0x10} }, ++ { {0x61, 0x3a, 0x03, 0x11, 0x10} }, ++ { {0x61, 0x30, 0x03, 0x11, 0x10} }, ++ { {0x61, 0x20, 0x03, 0x11, 0x10} }, ++ { {0x61, 0x10, 0x03, 0x11, 0x10} }, /* case-10 */ ++ { {0x61, 0x08, 0x03, 0x11, 0x14} }, ++ { {0x61, 0x08, 0x03, 0x10, 0x14} }, ++ { {0x51, 0x08, 0x03, 0x10, 0x54} }, ++ { {0x51, 0x08, 0x03, 0x10, 0x55} }, ++ { {0x51, 0x08, 0x07, 0x10, 0x54} }, /* case-15 */ ++ { {0x51, 0x45, 0x03, 0x10, 0x50} }, ++ { {0x51, 0x3a, 0x03, 0x10, 0x50} }, ++ { {0x51, 0x30, 0x03, 0x10, 0x50} }, ++ { {0x51, 0x20, 0x03, 0x10, 0x50} }, ++ { {0x51, 0x10, 0x03, 0x10, 0x50} }, /* case-20 */ ++ { {0x51, 0x4a, 0x03, 0x10, 0x50} }, ++ { {0x51, 0x0c, 0x03, 0x10, 0x54} }, ++ { {0x55, 0x08, 0x03, 0x10, 0x54} }, ++ { {0x65, 0x10, 0x03, 0x11, 0x10} }, ++ { {0x51, 0x10, 0x03, 0x10, 0x51} }, /* case-25 */ ++ { {0x51, 0x08, 0x03, 0x10, 0x50} }, ++ { {0x61, 0x08, 0x03, 0x11, 0x11} }, ++}; ++ ++static struct rtw_chip_ops rtw8703b_ops = { ++ .mac_init = rtw8723x_mac_init, ++ .dump_fw_crash = NULL, ++ .shutdown = NULL, ++ .read_efuse = rtw8703b_read_efuse, ++ .phy_set_param = rtw8703b_phy_set_param, ++ .set_channel = rtw8703b_set_channel, ++ .query_rx_desc = rtw8703b_query_rx_desc, ++ .read_rf = rtw_phy_read_rf_sipi, ++ .write_rf = rtw_phy_write_rf_reg_sipi, ++ .set_tx_power_index = rtw8723x_set_tx_power_index, ++ .set_antenna = NULL, ++ .cfg_ldo25 = rtw8723x_cfg_ldo25, ++ .efuse_grant = rtw8723x_efuse_grant, ++ .false_alarm_statistics = rtw8723x_false_alarm_statistics, ++ .phy_calibration = rtw8703b_phy_calibration, ++ .dpk_track = NULL, ++ /* 8723d uses REG_CSRATIO to set dm_info.cck_pd_default, which ++ * is used in its cck_pd_set function. According to comments ++ * in the vendor driver code it doesn't exist in this chip ++ * generation, only 0xa0a ("ODM_CCK_PD_THRESH", which is only ++ * *written* to). ++ */ ++ .cck_pd_set = NULL, ++ .pwr_track = rtw8703b_pwr_track, ++ .config_bfee = NULL, ++ .set_gid_table = NULL, ++ .cfg_csi_rate = NULL, ++ .adaptivity_init = NULL, ++ .adaptivity = NULL, ++ .cfo_init = NULL, ++ .cfo_track = NULL, ++ .config_tx_path = NULL, ++ .config_txrx_mode = NULL, ++ .fill_txdesc_checksum = rtw8723x_fill_txdesc_checksum, ++ ++ /* for coex */ ++ .coex_set_init = rtw8723x_coex_cfg_init, ++ .coex_set_ant_switch = NULL, ++ .coex_set_gnt_fix = rtw8703b_coex_set_gnt_fix, ++ .coex_set_gnt_debug = rtw8703b_coex_set_gnt_debug, ++ .coex_set_rfe_type = rtw8703b_coex_set_rfe_type, ++ .coex_set_wl_tx_power = rtw8703b_coex_set_wl_tx_power, ++ .coex_set_wl_rx_gain = rtw8703b_coex_set_wl_rx_gain, ++}; ++ ++const struct rtw_chip_info rtw8703b_hw_spec = { ++ .ops = &rtw8703b_ops, ++ .id = RTW_CHIP_TYPE_8703B, ++ ++ .fw_name = "rtw88/rtw8703b_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 = 256, ++ .log_efuse_size = 512, ++ .ptct_efuse_size = 15, ++ .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, ++ .tx_stbc = false, ++ .max_power_index = 0x3f, ++ .ampdu_density = IEEE80211_HT_MPDU_DENSITY_16, ++ ++ .path_div_supported = false, ++ .ht_supported = true, ++ .vht_supported = false, ++ .lps_deep_mode_supported = 0, ++ ++ .sys_func_en = 0xFD, ++ .pwr_on_seq = card_enable_flow_8703b, ++ .pwr_off_seq = card_disable_flow_8703b, ++ .rqpn_table = rqpn_table_8703b, ++ .prioq_addrs = &rtw8723x_common.prioq_addrs, ++ .page_table = page_table_8703b, ++ /* used only in pci.c, not needed for SDIO devices */ ++ .intf_table = NULL, ++ ++ .dig = rtw8723x_common.dig, ++ .dig_cck = rtw8723x_common.dig_cck, ++ ++ .rf_sipi_addr = {0x840, 0x844}, ++ .rf_sipi_read_addr = rtw8723x_common.rf_sipi_addr, ++ .fix_rf_phy_num = 2, ++ .ltecoex_addr = &rtw8723x_common.ltecoex_addr, ++ ++ .mac_tbl = &rtw8703b_mac_tbl, ++ .agc_tbl = &rtw8703b_agc_tbl, ++ .bb_tbl = &rtw8703b_bb_tbl, ++ .rf_tbl = {&rtw8703b_rf_a_tbl}, ++ ++ .rfe_defs = rtw8703b_rfe_defs, ++ .rfe_defs_size = ARRAY_SIZE(rtw8703b_rfe_defs), ++ ++ .iqk_threshold = 8, ++ .pwr_track_tbl = &rtw8703b_rtw_pwr_track_tbl, ++ ++ /* WOWLAN firmware exists, but not implemented yet */ ++ .wow_fw_name = "rtw88/rtw8703b_wow_fw.bin", ++ .wowlan_stub = NULL, ++ .max_scan_ie_len = IEEE80211_MAX_DATA_LEN, ++ ++ /* Vendor driver has a time-based format, converted from ++ * 20180330 ++ */ ++ .coex_para_ver = 0x0133ed6a, ++ .bt_desired_ver = 0x1c, ++ .scbd_support = true, ++ .new_scbd10_def = true, ++ .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, ++ .bt_rssi_step = bt_rssi_step_8703b, ++ .wl_rssi_step = wl_rssi_step_8703b, ++ /* sant -> shared antenna, nsant -> non-shared antenna ++ * Not sure if 8703b versions with non-shard antenna even exist. ++ */ ++ .table_sant_num = ARRAY_SIZE(table_sant_8703b), ++ .table_sant = table_sant_8703b, ++ .table_nsant_num = 0, ++ .table_nsant = NULL, ++ .tdma_sant_num = ARRAY_SIZE(tdma_sant_8703b), ++ .tdma_sant = tdma_sant_8703b, ++ .tdma_nsant_num = 0, ++ .tdma_nsant = NULL, ++ .wl_rf_para_num = ARRAY_SIZE(rf_para_tx_8703b), ++ .wl_rf_para_tx = rf_para_tx_8703b, ++ .wl_rf_para_rx = rf_para_rx_8703b, ++ .bt_afh_span_bw20 = 0x20, ++ .bt_afh_span_bw40 = 0x30, ++ .afh_5g_num = ARRAY_SIZE(afh_5g_8703b), ++ .afh_5g = afh_5g_8703b, ++ /* REG_BTG_SEL doesn't seem to have a counterpart in the ++ * vendor driver. Mathematically it's REG_PAD_CTRL1 + 3. ++ * ++ * It is used in the cardemu_to_act power sequence by though ++ * (by address, 0x0067), comment: "0x67[0] = 0 to disable ++ * BT_GPS_SEL pins" That seems to fit. ++ */ ++ .btg_reg = NULL, ++ /* These registers are used to read (and print) from if ++ * CONFIG_RTW88_DEBUGFS is enabled. ++ */ ++ .coex_info_hw_regs_num = 0, ++ .coex_info_hw_regs = NULL, ++}; ++EXPORT_SYMBOL(rtw8703b_hw_spec); ++ ++MODULE_FIRMWARE("rtw88/rtw8703b_fw.bin"); ++MODULE_FIRMWARE("rtw88/rtw8703b_wow_fw.bin"); ++ ++MODULE_AUTHOR("Fiona Klute "); ++MODULE_DESCRIPTION("Realtek 802.11n wireless 8703b driver"); ++MODULE_LICENSE("Dual BSD/GPL"); diff --git a/packages/linux/patches/rtlwifi/6.11/0013-6.11-wifi-rtw88-usb-Further-limit-the-TX-aggregation.patch b/packages/linux/patches/rtlwifi/6.11/0013-6.11-wifi-rtw88-usb-Further-limit-the-TX-aggregation.patch new file mode 100644 index 0000000000..ed8c0296ce --- /dev/null +++ b/packages/linux/patches/rtlwifi/6.11/0013-6.11-wifi-rtw88-usb-Further-limit-the-TX-aggregation.patch @@ -0,0 +1,164 @@ +From d7dd13ea54af8496aca2762a758d817d6813e81c Mon Sep 17 00:00:00 2001 +From: Bitterblue Smith +Date: Sun, 16 Jun 2024 22:27:34 +0300 +Subject: [PATCH] wifi: rtw88: usb: Further limit the TX aggregation + +Currently the number of frames sent to the chip in a single USB Request +Block is limited only by the size of the TX buffer, which is 20 KiB. +Testing reveals that as many as 13 frames get aggregated. This is more +than what any of the chips would like to receive. RTL8822CU, RTL8822BU, +and RTL8821CU want at most 3 frames, and RTL8723DU wants only 1 frame +per URB. + +RTL8723DU in particular reliably malfunctions during a speed test if it +receives more than 1 frame per URB. All traffic seems to stop. Pinging +the AP no longer works. + +Fix this problem by limiting the number of frames sent to the chip in a +single URB according to what each chip likes. + +Also configure RTL8822CU, RTL8822BU, and RTL8821CU to expect 3 frames +per URB. + +RTL8703B may or may not be found in USB devices. Declare that it wants +only 1 frame per URB, just in case. + +Tested with RTL8723DU and RTL8811CU. + +Cc: stable@vger.kernel.org +Signed-off-by: Bitterblue Smith +Acked-by: Ping-Ke Shih +Signed-off-by: Ping-Ke Shih +Link: https://patch.msgid.link/cb46ea35-7e59-4742-9c1f-01ceeaad36fb@gmail.com +--- + drivers/net/wireless/realtek/rtw88/mac.c | 9 +++++++++ + drivers/net/wireless/realtek/rtw88/main.h | 2 ++ + drivers/net/wireless/realtek/rtw88/reg.h | 1 + + drivers/net/wireless/realtek/rtw88/rtw8703b.c | 1 + + drivers/net/wireless/realtek/rtw88/rtw8723d.c | 1 + + drivers/net/wireless/realtek/rtw88/rtw8821c.c | 1 + + drivers/net/wireless/realtek/rtw88/rtw8822b.c | 1 + + drivers/net/wireless/realtek/rtw88/rtw8822c.c | 1 + + drivers/net/wireless/realtek/rtw88/usb.c | 4 +++- + 9 files changed, 20 insertions(+), 1 deletion(-) + +diff --git a/drivers/net/wireless/realtek/rtw88/mac.c b/drivers/net/wireless/realtek/rtw88/mac.c +index 0dba8aae771603..564f5988ee82a7 100644 +--- a/drivers/net/wireless/realtek/rtw88/mac.c ++++ b/drivers/net/wireless/realtek/rtw88/mac.c +@@ -1201,6 +1201,15 @@ static int __priority_queue_cfg(struct rtw_dev *rtwdev, + rtw_write16(rtwdev, REG_FIFOPAGE_CTRL_2 + 2, fifo->rsvd_boundary); + rtw_write16(rtwdev, REG_BCNQ1_BDNY_V1, fifo->rsvd_boundary); + rtw_write32(rtwdev, REG_RXFF_BNDY, chip->rxff_size - C2H_PKT_BUF - 1); ++ ++ if (rtwdev->hci.type == RTW_HCI_TYPE_USB) { ++ rtw_write8_mask(rtwdev, REG_AUTO_LLT_V1, BIT_MASK_BLK_DESC_NUM, ++ chip->usb_tx_agg_desc_num); ++ ++ rtw_write8(rtwdev, REG_AUTO_LLT_V1 + 3, chip->usb_tx_agg_desc_num); ++ rtw_write8_set(rtwdev, REG_TXDMA_OFFSET_CHK + 1, BIT(1)); ++ } ++ + rtw_write8_set(rtwdev, REG_AUTO_LLT_V1, BIT_AUTO_INIT_LLT_V1); + + if (!check_hw_ready(rtwdev, REG_AUTO_LLT_V1, BIT_AUTO_INIT_LLT_V1, 0)) +diff --git a/drivers/net/wireless/realtek/rtw88/main.h b/drivers/net/wireless/realtek/rtw88/main.h +index 49894331f7b495..49a3fd4fb7dcdc 100644 +--- a/drivers/net/wireless/realtek/rtw88/main.h ++++ b/drivers/net/wireless/realtek/rtw88/main.h +@@ -1197,6 +1197,8 @@ struct rtw_chip_info { + u16 fw_fifo_addr[RTW_FW_FIFO_MAX]; + const struct rtw_fwcd_segs *fwcd_segs; + ++ u8 usb_tx_agg_desc_num; ++ + u8 default_1ss_tx_path; + + bool path_div_supported; +diff --git a/drivers/net/wireless/realtek/rtw88/reg.h b/drivers/net/wireless/realtek/rtw88/reg.h +index b122f226924be5..02ef9a77316b48 100644 +--- a/drivers/net/wireless/realtek/rtw88/reg.h ++++ b/drivers/net/wireless/realtek/rtw88/reg.h +@@ -270,6 +270,7 @@ + #define BIT_MASK_BCN_HEAD_1_V1 0xfff + #define REG_AUTO_LLT_V1 0x0208 + #define BIT_AUTO_INIT_LLT_V1 BIT(0) ++#define BIT_MASK_BLK_DESC_NUM GENMASK(7, 4) + #define REG_DWBCN0_CTRL 0x0208 + #define BIT_BCN_VALID BIT(16) + #define REG_TXDMA_OFFSET_CHK 0x020C +diff --git a/drivers/net/wireless/realtek/rtw88/rtw8703b.c b/drivers/net/wireless/realtek/rtw88/rtw8703b.c +index 8919f9e11f0378..222608de33cdec 100644 +--- a/drivers/net/wireless/realtek/rtw88/rtw8703b.c ++++ b/drivers/net/wireless/realtek/rtw88/rtw8703b.c +@@ -2013,6 +2013,7 @@ const struct rtw_chip_info rtw8703b_hw_spec = { + .tx_stbc = false, + .max_power_index = 0x3f, + .ampdu_density = IEEE80211_HT_MPDU_DENSITY_16, ++ .usb_tx_agg_desc_num = 1, /* Not sure if this chip has USB interface */ + + .path_div_supported = false, + .ht_supported = true, +diff --git a/drivers/net/wireless/realtek/rtw88/rtw8723d.c b/drivers/net/wireless/realtek/rtw88/rtw8723d.c +index f8df4c84d39f73..3fba4054d45f49 100644 +--- a/drivers/net/wireless/realtek/rtw88/rtw8723d.c ++++ b/drivers/net/wireless/realtek/rtw88/rtw8723d.c +@@ -2171,6 +2171,7 @@ const struct rtw_chip_info rtw8723d_hw_spec = { + .band = RTW_BAND_2G, + .page_size = TX_PAGE_SIZE, + .dig_min = 0x20, ++ .usb_tx_agg_desc_num = 1, + .ht_supported = true, + .vht_supported = false, + .lps_deep_mode_supported = 0, +diff --git a/drivers/net/wireless/realtek/rtw88/rtw8821c.c b/drivers/net/wireless/realtek/rtw88/rtw8821c.c +index fe5d8e18835093..526e8de77b3e82 100644 +--- a/drivers/net/wireless/realtek/rtw88/rtw8821c.c ++++ b/drivers/net/wireless/realtek/rtw88/rtw8821c.c +@@ -2008,6 +2008,7 @@ const struct rtw_chip_info rtw8821c_hw_spec = { + .band = RTW_BAND_2G | RTW_BAND_5G, + .page_size = TX_PAGE_SIZE, + .dig_min = 0x1c, ++ .usb_tx_agg_desc_num = 3, + .ht_supported = true, + .vht_supported = true, + .lps_deep_mode_supported = BIT(LPS_DEEP_MODE_LCLK), +diff --git a/drivers/net/wireless/realtek/rtw88/rtw8822b.c b/drivers/net/wireless/realtek/rtw88/rtw8822b.c +index 3017a9760da8dc..2456ff24281801 100644 +--- a/drivers/net/wireless/realtek/rtw88/rtw8822b.c ++++ b/drivers/net/wireless/realtek/rtw88/rtw8822b.c +@@ -2548,6 +2548,7 @@ const struct rtw_chip_info rtw8822b_hw_spec = { + .band = RTW_BAND_2G | RTW_BAND_5G, + .page_size = TX_PAGE_SIZE, + .dig_min = 0x1c, ++ .usb_tx_agg_desc_num = 3, + .ht_supported = true, + .vht_supported = true, + .lps_deep_mode_supported = BIT(LPS_DEEP_MODE_LCLK), +diff --git a/drivers/net/wireless/realtek/rtw88/rtw8822c.c b/drivers/net/wireless/realtek/rtw88/rtw8822c.c +index cd965edc29cea3..62376d1cca22fc 100644 +--- a/drivers/net/wireless/realtek/rtw88/rtw8822c.c ++++ b/drivers/net/wireless/realtek/rtw88/rtw8822c.c +@@ -5366,6 +5366,7 @@ const struct rtw_chip_info rtw8822c_hw_spec = { + .band = RTW_BAND_2G | RTW_BAND_5G, + .page_size = TX_PAGE_SIZE, + .dig_min = 0x20, ++ .usb_tx_agg_desc_num = 3, + .default_1ss_tx_path = BB_PATH_A, + .path_div_supported = true, + .ht_supported = true, +diff --git a/drivers/net/wireless/realtek/rtw88/usb.c b/drivers/net/wireless/realtek/rtw88/usb.c +index d204d138afe298..057c0ffbe94472 100644 +--- a/drivers/net/wireless/realtek/rtw88/usb.c ++++ b/drivers/net/wireless/realtek/rtw88/usb.c +@@ -379,7 +379,9 @@ static bool rtw_usb_tx_agg_skb(struct rtw_usb *rtwusb, struct sk_buff_head *list + + skb_iter = skb_peek(list); + +- if (skb_iter && skb_iter->len + skb_head->len <= RTW_USB_MAX_XMITBUF_SZ) ++ if (skb_iter && ++ skb_iter->len + skb_head->len <= RTW_USB_MAX_XMITBUF_SZ && ++ agg_num < rtwdev->chip->usb_tx_agg_desc_num) + __skb_unlink(skb_iter, list); + else + skb_iter = NULL; diff --git a/packages/linux/patches/rtlwifi/6.11/0014-6.11-wifi-rtw88-usb-Simplify-rtw_usb_write_data.patch b/packages/linux/patches/rtlwifi/6.11/0014-6.11-wifi-rtw88-usb-Simplify-rtw_usb_write_data.patch new file mode 100644 index 0000000000..e4f035833e --- /dev/null +++ b/packages/linux/patches/rtlwifi/6.11/0014-6.11-wifi-rtw88-usb-Simplify-rtw_usb_write_data.patch @@ -0,0 +1,51 @@ +From a892f6ffbec7a1a25c639534bee62200418242f9 Mon Sep 17 00:00:00 2001 +From: Bitterblue Smith +Date: Fri, 3 May 2024 13:53:28 +0300 +Subject: [PATCH] wifi: rtw88: usb: Simplify rtw_usb_write_data + +The skb created in this function always has the same headroom, +the chip's TX descriptor size. (pkt_info->offset is set by +rtw_usb_write_data_rsvd_page() to chip->tx_pkt_desc_sz.) Use +chip->tx_pkt_desc_sz directly. + +Signed-off-by: Bitterblue Smith +Tested-by: Larry Finger +Signed-off-by: Ping-Ke Shih +Link: https://msgid.link/2479507e-3946-492f-857e-83e54969aad2@gmail.com +--- + drivers/net/wireless/realtek/rtw88/usb.c | 12 +++++------- + 1 file changed, 5 insertions(+), 7 deletions(-) + +diff --git a/drivers/net/wireless/realtek/rtw88/usb.c b/drivers/net/wireless/realtek/rtw88/usb.c +index a0188511099a1b..90afeefe002f37 100644 +--- a/drivers/net/wireless/realtek/rtw88/usb.c ++++ b/drivers/net/wireless/realtek/rtw88/usb.c +@@ -433,23 +433,21 @@ static int rtw_usb_write_data(struct rtw_dev *rtwdev, + { + const struct rtw_chip_info *chip = rtwdev->chip; + struct sk_buff *skb; +- unsigned int desclen, headsize, size; ++ unsigned int size; + u8 qsel; + int ret = 0; + + size = pkt_info->tx_pkt_size; + qsel = pkt_info->qsel; +- desclen = chip->tx_pkt_desc_sz; +- headsize = pkt_info->offset ? pkt_info->offset : desclen; + +- skb = dev_alloc_skb(headsize + size); ++ skb = dev_alloc_skb(chip->tx_pkt_desc_sz + size); + if (unlikely(!skb)) + return -ENOMEM; + +- skb_reserve(skb, headsize); ++ skb_reserve(skb, chip->tx_pkt_desc_sz); + skb_put_data(skb, buf, size); +- skb_push(skb, headsize); +- memset(skb->data, 0, headsize); ++ skb_push(skb, chip->tx_pkt_desc_sz); ++ memset(skb->data, 0, chip->tx_pkt_desc_sz); + rtw_tx_fill_tx_desc(pkt_info, skb); + rtw_tx_fill_txdesc_checksum(rtwdev, pkt_info, skb->data); + diff --git a/packages/linux/patches/rtlwifi/6.12/0001-6.12-wifi-rtw88-usb-Support-USB-3-with-RTL8822CU-RTL8822B.patch b/packages/linux/patches/rtlwifi/6.12/0001-6.12-wifi-rtw88-usb-Support-USB-3-with-RTL8822CU-RTL8822B.patch new file mode 100644 index 0000000000..6091e6a612 --- /dev/null +++ b/packages/linux/patches/rtlwifi/6.12/0001-6.12-wifi-rtw88-usb-Support-USB-3-with-RTL8822CU-RTL8822B.patch @@ -0,0 +1,303 @@ +From 3c64d161a450d62330ad79d2b5f92c115b11622d Mon Sep 17 00:00:00 2001 +From: Bitterblue Smith +Date: Thu, 11 Jul 2024 01:11:33 +0300 +Subject: [PATCH 1/7] wifi: rtw88: usb: Support USB 3 with RTL8822CU/RTL8822BU + +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. + +Implement the required commands in rtw88. + +When a USB 3 device is plugged into a USB 2 port, rtw88 will try to +switch it to USB 3 mode only once. The device will disappear and come +back still in USB 2 mode, of course. + +Some people experience heavy interference in the 2.4 GHz band in +USB 3 mode, so add a module parameter switch_usb_mode with the +default value 1 to let people disable the switching. + +Signed-off-by: Bitterblue Smith +Acked-by: Ping-Ke Shih +Signed-off-by: Ping-Ke Shih +Link: https://patch.msgid.link/77906c62-5674-426f-bde1-1b2a12a0339d@gmail.com +--- + drivers/net/wireless/realtek/rtw88/debug.h | 1 + + drivers/net/wireless/realtek/rtw88/main.h | 2 + + drivers/net/wireless/realtek/rtw88/reg.h | 11 +++ + drivers/net/wireless/realtek/rtw88/rtw8822b.c | 1 + + drivers/net/wireless/realtek/rtw88/rtw8822b.h | 4 +- + drivers/net/wireless/realtek/rtw88/rtw8822c.c | 1 + + drivers/net/wireless/realtek/rtw88/rtw8822c.h | 24 +++--- + drivers/net/wireless/realtek/rtw88/usb.c | 84 +++++++++++++++++++ + 8 files changed, 116 insertions(+), 12 deletions(-) + +diff --git a/drivers/net/wireless/realtek/rtw88/debug.h b/drivers/net/wireless/realtek/rtw88/debug.h +index eb69006c463e..9a1e0e85a13c 100644 +--- a/drivers/net/wireless/realtek/rtw88/debug.h ++++ b/drivers/net/wireless/realtek/rtw88/debug.h +@@ -25,6 +25,7 @@ enum rtw_debug_mask { + RTW_DBG_HW_SCAN = 0x00010000, + RTW_DBG_STATE = 0x00020000, + RTW_DBG_SDIO = 0x00040000, ++ RTW_DBG_USB = 0x00080000, + + RTW_DBG_UNEXP = 0x80000000, + RTW_DBG_ALL = 0xffffffff +diff --git a/drivers/net/wireless/realtek/rtw88/main.h b/drivers/net/wireless/realtek/rtw88/main.h +index 49a3fd4fb7dc..9d21637cf5d5 100644 +--- a/drivers/net/wireless/realtek/rtw88/main.h ++++ b/drivers/net/wireless/realtek/rtw88/main.h +@@ -1785,6 +1785,8 @@ struct rtw_efuse { + bool share_ant; + u8 bt_setting; + ++ u8 usb_mode_switch; ++ + struct { + u8 hci; + u8 bw; +diff --git a/drivers/net/wireless/realtek/rtw88/reg.h b/drivers/net/wireless/realtek/rtw88/reg.h +index 02ef9a77316b..e7b24465f549 100644 +--- a/drivers/net/wireless/realtek/rtw88/reg.h ++++ b/drivers/net/wireless/realtek/rtw88/reg.h +@@ -15,6 +15,7 @@ + #define BIT_WLOCK_1C_B6 BIT(5) + #define REG_SYS_PW_CTRL 0x0004 + #define BIT_PFM_WOWL BIT(3) ++#define BIT_APFM_OFFMAC BIT(9) + #define REG_SYS_CLK_CTRL 0x0008 + #define BIT_CPU_CLK_EN BIT(14) + +@@ -133,6 +134,14 @@ + #define REG_PMC_DBG_CTRL1 0xa8 + #define BITS_PMC_BT_IQK_STS GENMASK(22, 21) + ++#define REG_PAD_CTRL2 0x00C4 ++#define BIT_RSM_EN_V1 BIT(16) ++#define BIT_NO_PDN_CHIPOFF_V1 BIT(17) ++#define BIT_MASK_USB23_SW_MODE_V1 GENMASK(19, 18) ++#define BIT_USB3_USB2_TRANSITION BIT(20) ++#define BIT_USB_MODE_U2 1 ++#define BIT_USB_MODE_U3 2 ++ + #define REG_EFUSE_ACCESS 0x00CF + #define EFUSE_ACCESS_ON 0x69 + #define EFUSE_ACCESS_OFF 0x00 +@@ -568,6 +577,8 @@ + #define BIT_WL_SECURITY_CLK BIT(15) + #define BIT_DDMA_EN BIT(8) + ++#define REG_SW_MDIO 0x10C0 ++ + #define REG_H2C_PKT_READADDR 0x10D0 + #define REG_H2C_PKT_WRITEADDR 0x10D4 + #define REG_FW_DBG6 0x10F8 +diff --git a/drivers/net/wireless/realtek/rtw88/rtw8822b.c b/drivers/net/wireless/realtek/rtw88/rtw8822b.c +index 2456ff242818..6edb17aea90e 100644 +--- a/drivers/net/wireless/realtek/rtw88/rtw8822b.c ++++ b/drivers/net/wireless/realtek/rtw88/rtw8822b.c +@@ -46,6 +46,7 @@ static int rtw8822b_read_efuse(struct rtw_dev *rtwdev, u8 *log_map) + + map = (struct rtw8822b_efuse *)log_map; + ++ efuse->usb_mode_switch = u8_get_bits(map->usb_mode, BIT(7)); + efuse->rfe_option = map->rfe_option; + efuse->rf_board_option = map->rf_board_option; + efuse->crystal_cap = map->xtal_k; +diff --git a/drivers/net/wireless/realtek/rtw88/rtw8822b.h b/drivers/net/wireless/realtek/rtw88/rtw8822b.h +index 2dc3a6660f06..cf85e63966a1 100644 +--- a/drivers/net/wireless/realtek/rtw88/rtw8822b.h ++++ b/drivers/net/wireless/realtek/rtw88/rtw8822b.h +@@ -72,7 +72,9 @@ struct rtw8822bs_efuse { + + struct rtw8822b_efuse { + __le16 rtl_id; +- u8 res0[0x0e]; ++ u8 res0[4]; ++ u8 usb_mode; ++ u8 res1[0x09]; + + /* power index for four RF paths */ + struct rtw_txpwr_idx txpwr_idx_table[4]; +diff --git a/drivers/net/wireless/realtek/rtw88/rtw8822c.c b/drivers/net/wireless/realtek/rtw88/rtw8822c.c +index 62376d1cca22..bc807b13e9ce 100644 +--- a/drivers/net/wireless/realtek/rtw88/rtw8822c.c ++++ b/drivers/net/wireless/realtek/rtw88/rtw8822c.c +@@ -49,6 +49,7 @@ static int rtw8822c_read_efuse(struct rtw_dev *rtwdev, u8 *log_map) + + map = (struct rtw8822c_efuse *)log_map; + ++ efuse->usb_mode_switch = u8_get_bits(map->usb_mode, BIT(7)); + efuse->rfe_option = map->rfe_option; + efuse->rf_board_option = map->rf_board_option; + efuse->crystal_cap = map->xtal_k & XCAP_MASK; +diff --git a/drivers/net/wireless/realtek/rtw88/rtw8822c.h b/drivers/net/wireless/realtek/rtw88/rtw8822c.h +index 1bc0e7f5d6bb..e2b383d633cd 100644 +--- a/drivers/net/wireless/realtek/rtw88/rtw8822c.h ++++ b/drivers/net/wireless/realtek/rtw88/rtw8822c.h +@@ -59,16 +59,18 @@ struct rtw8822ce_efuse { + + struct rtw8822c_efuse { + __le16 rtl_id; +- u8 res0[0x0e]; ++ u8 res0[4]; ++ u8 usb_mode; ++ u8 res1[0x09]; + + /* power index for four RF paths */ + struct rtw_txpwr_idx txpwr_idx_table[4]; + + u8 channel_plan; /* 0xb8 */ + u8 xtal_k; +- u8 res1; ++ u8 res2; + u8 iqk_lck; +- u8 res2[5]; /* 0xbc */ ++ u8 res3[5]; /* 0xbc */ + u8 rf_board_option; + u8 rf_feature_option; + u8 rf_bt_setting; +@@ -80,21 +82,21 @@ struct rtw8822c_efuse { + u8 rf_antenna_option; /* 0xc9 */ + u8 rfe_option; + u8 country_code[2]; +- u8 res3[3]; ++ u8 res4[3]; + u8 path_a_thermal; /* 0xd0 */ + u8 path_b_thermal; +- u8 res4[2]; ++ u8 res5[2]; + u8 rx_gain_gap_2g_ofdm; +- u8 res5; +- u8 rx_gain_gap_2g_cck; + u8 res6; +- u8 rx_gain_gap_5gl; ++ u8 rx_gain_gap_2g_cck; + u8 res7; +- u8 rx_gain_gap_5gm; ++ u8 rx_gain_gap_5gl; + u8 res8; +- u8 rx_gain_gap_5gh; ++ u8 rx_gain_gap_5gm; + u8 res9; +- u8 res10[0x42]; ++ u8 rx_gain_gap_5gh; ++ u8 res10; ++ u8 res11[0x42]; + union { + struct rtw8822ce_efuse e; + struct rtw8822cu_efuse u; +diff --git a/drivers/net/wireless/realtek/rtw88/usb.c b/drivers/net/wireless/realtek/rtw88/usb.c +index a55ca5a24227..251a5726f3ee 100644 +--- a/drivers/net/wireless/realtek/rtw88/usb.c ++++ b/drivers/net/wireless/realtek/rtw88/usb.c +@@ -14,6 +14,11 @@ + #include "ps.h" + #include "usb.h" + ++static bool rtw_switch_usb_mode = true; ++module_param_named(switch_usb_mode, rtw_switch_usb_mode, bool, 0644); ++MODULE_PARM_DESC(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)"); ++ + #define RTW_USB_MAX_RXQ_LEN 512 + + struct rtw_usb_txcb { +@@ -841,6 +846,77 @@ static void rtw_usb_intf_deinit(struct rtw_dev *rtwdev, + usb_set_intfdata(intf, NULL); + } + ++static int rtw_usb_switch_mode_new(struct rtw_dev *rtwdev) ++{ ++ enum usb_device_speed cur_speed; ++ u8 id = rtwdev->chip->id; ++ bool can_switch; ++ u32 pad_ctrl2; ++ ++ if (rtw_read8(rtwdev, REG_SYS_CFG2 + 3) == 0x20) ++ cur_speed = USB_SPEED_SUPER; ++ else ++ cur_speed = USB_SPEED_HIGH; ++ ++ if (cur_speed == USB_SPEED_SUPER) ++ return 0; ++ ++ pad_ctrl2 = rtw_read32(rtwdev, REG_PAD_CTRL2); ++ ++ can_switch = !!(pad_ctrl2 & (BIT_MASK_USB23_SW_MODE_V1 | ++ BIT_USB3_USB2_TRANSITION)); ++ ++ if (!can_switch) { ++ rtw_dbg(rtwdev, RTW_DBG_USB, ++ "Switching to USB 3 mode unsupported by the chip\n"); ++ return 0; ++ } ++ ++ /* At this point cur_speed is USB_SPEED_HIGH. If we already tried ++ * to switch don't try again - it's a USB 2 port. ++ */ ++ if (u32_get_bits(pad_ctrl2, BIT_MASK_USB23_SW_MODE_V1) == BIT_USB_MODE_U3) ++ return 0; ++ ++ /* Enable IO wrapper timeout */ ++ if (id == RTW_CHIP_TYPE_8822B || id == RTW_CHIP_TYPE_8821C) ++ rtw_write8_clr(rtwdev, REG_SW_MDIO + 3, BIT(0)); ++ ++ u32p_replace_bits(&pad_ctrl2, BIT_USB_MODE_U3, BIT_MASK_USB23_SW_MODE_V1); ++ pad_ctrl2 |= BIT_RSM_EN_V1; ++ ++ rtw_write32(rtwdev, REG_PAD_CTRL2, pad_ctrl2); ++ rtw_write8(rtwdev, REG_PAD_CTRL2 + 1, 4); ++ ++ rtw_write16_set(rtwdev, REG_SYS_PW_CTRL, BIT_APFM_OFFMAC); ++ usleep_range(1000, 1001); ++ rtw_write32_set(rtwdev, REG_PAD_CTRL2, BIT_NO_PDN_CHIPOFF_V1); ++ ++ return 1; ++} ++ ++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) ++ return 0; ++ ++ if (!rtwdev->efuse.usb_mode_switch) { ++ rtw_dbg(rtwdev, RTW_DBG_USB, ++ "Switching to USB 3 mode disabled by chip's efuse\n"); ++ return 0; ++ } ++ ++ if (!rtw_switch_usb_mode) { ++ rtw_dbg(rtwdev, RTW_DBG_USB, ++ "Switching to USB 3 mode disabled by module parameter\n"); ++ return 0; ++ } ++ ++ return rtw_usb_switch_mode_new(rtwdev); ++} ++ + int rtw_usb_probe(struct usb_interface *intf, const struct usb_device_id *id) + { + struct rtw_dev *rtwdev; +@@ -896,6 +972,14 @@ int rtw_usb_probe(struct usb_interface *intf, const struct usb_device_id *id) + goto err_destroy_rxwq; + } + ++ ret = rtw_usb_switch_mode(rtwdev); ++ if (ret) { ++ /* Not a fail, but we do need to skip rtw_register_hw. */ ++ rtw_dbg(rtwdev, RTW_DBG_USB, "switching to USB 3 mode\n"); ++ ret = 0; ++ goto err_destroy_rxwq; ++ } ++ + ret = rtw_register_hw(rtwdev, rtwdev->hw); + if (ret) { + rtw_err(rtwdev, "failed to register hw\n"); +-- +2.43.0 + diff --git a/packages/linux/patches/rtlwifi/6.12/0002-6.12-wifi-rtw88-8703b-Fix-reported-RX-band-width.patch b/packages/linux/patches/rtlwifi/6.12/0002-6.12-wifi-rtw88-8703b-Fix-reported-RX-band-width.patch new file mode 100644 index 0000000000..e369a89285 --- /dev/null +++ b/packages/linux/patches/rtlwifi/6.12/0002-6.12-wifi-rtw88-8703b-Fix-reported-RX-band-width.patch @@ -0,0 +1,36 @@ +From aefa7a3a7cbe6c7de08fd7a7447c797a97c2e0cf Mon Sep 17 00:00:00 2001 +From: Bitterblue Smith +Date: Tue, 23 Jul 2024 22:32:59 +0300 +Subject: [PATCH 2/7] wifi: rtw88: 8703b: Fix reported RX band width + +The definition of GET_RX_DESC_BW is incorrect. Fix it according to the +GET_RX_STATUS_DESC_BW_8703B macro from the official driver. + +Tested only with RTL8812AU, which uses the same bits. + +Cc: stable@vger.kernel.org +Fixes: 9bb762b3a957 ("wifi: rtw88: Add definitions for 8703b chip") +Signed-off-by: Bitterblue Smith +Tested-by: Fiona Klute +Signed-off-by: Ping-Ke Shih +Link: https://patch.msgid.link/1cfed9d5-4304-4b96-84c5-c347f59fedb9@gmail.com +--- + drivers/net/wireless/realtek/rtw88/rx.h | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/net/wireless/realtek/rtw88/rx.h b/drivers/net/wireless/realtek/rtw88/rx.h +index d3668c4efc24..8a072dd3d73c 100644 +--- a/drivers/net/wireless/realtek/rtw88/rx.h ++++ b/drivers/net/wireless/realtek/rtw88/rx.h +@@ -41,7 +41,7 @@ enum rtw_rx_desc_enc { + #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(31, 24))) ++ (le32_get_bits(*((__le32 *)(rxdesc) + 0x04), GENMASK(5, 4))) + + void rtw_rx_stats(struct rtw_dev *rtwdev, struct ieee80211_vif *vif, + struct sk_buff *skb); +-- +2.43.0 + diff --git a/packages/linux/patches/rtlwifi/6.12/0003-6.12-wifi-rtw88-8822c-Parse-channel-from-IE-to-correct-in.patch b/packages/linux/patches/rtlwifi/6.12/0003-6.12-wifi-rtw88-8822c-Parse-channel-from-IE-to-correct-in.patch new file mode 100644 index 0000000000..b3f01e5bf6 --- /dev/null +++ b/packages/linux/patches/rtlwifi/6.12/0003-6.12-wifi-rtw88-8822c-Parse-channel-from-IE-to-correct-in.patch @@ -0,0 +1,168 @@ +From c1ca6ece1a989240c04f9a77230592cc92ff823c Mon Sep 17 00:00:00 2001 +From: Po-Hao Huang +Date: Wed, 24 Jul 2024 13:05:01 +0800 +Subject: [PATCH 3/7] wifi: rtw88: 8822c: Parse channel from IE to correct + invalid hardware reports + +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 +--- + drivers/net/wireless/realtek/rtw88/main.h | 1 + + drivers/net/wireless/realtek/rtw88/pci.c | 1 + + drivers/net/wireless/realtek/rtw88/rtw8822c.c | 7 ++-- + drivers/net/wireless/realtek/rtw88/rx.c | 41 +++++++++++++++++++ + drivers/net/wireless/realtek/rtw88/rx.h | 13 ++++++ + drivers/net/wireless/realtek/rtw88/sdio.c | 1 + + drivers/net/wireless/realtek/rtw88/usb.c | 2 + + 7 files changed, 63 insertions(+), 3 deletions(-) + +diff --git a/drivers/net/wireless/realtek/rtw88/main.h b/drivers/net/wireless/realtek/rtw88/main.h +index 9d21637cf5d5..37912dded128 100644 +--- a/drivers/net/wireless/realtek/rtw88/main.h ++++ b/drivers/net/wireless/realtek/rtw88/main.h +@@ -622,6 +622,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/drivers/net/wireless/realtek/rtw88/pci.c b/drivers/net/wireless/realtek/rtw88/pci.c +index a5b9d6c7be37..5d0580da13fb 100644 +--- a/drivers/net/wireless/realtek/rtw88/pci.c ++++ b/drivers/net/wireless/realtek/rtw88/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/drivers/net/wireless/realtek/rtw88/rtw8822c.c b/drivers/net/wireless/realtek/rtw88/rtw8822c.c +index bc807b13e9ce..96a233079e02 100644 +--- a/drivers/net/wireless/realtek/rtw88/rtw8822c.c ++++ b/drivers/net/wireless/realtek/rtw88/rtw8822c.c +@@ -2576,9 +2576,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/drivers/net/wireless/realtek/rtw88/rx.c b/drivers/net/wireless/realtek/rtw88/rx.c +index 84aedabdf285..66f9419588cf 100644 +--- a/drivers/net/wireless/realtek/rtw88/rx.c ++++ b/drivers/net/wireless/realtek/rtw88/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/drivers/net/wireless/realtek/rtw88/rx.h b/drivers/net/wireless/realtek/rtw88/rx.h +index 8a072dd3d73c..9f0019112987 100644 +--- a/drivers/net/wireless/realtek/rtw88/rx.h ++++ b/drivers/net/wireless/realtek/rtw88/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/drivers/net/wireless/realtek/rtw88/sdio.c b/drivers/net/wireless/realtek/rtw88/sdio.c +index 0cae5746f540..763aa8212a4b 100644 +--- a/drivers/net/wireless/realtek/rtw88/sdio.c ++++ b/drivers/net/wireless/realtek/rtw88/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/drivers/net/wireless/realtek/rtw88/usb.c b/drivers/net/wireless/realtek/rtw88/usb.c +index 251a5726f3ee..9145c11a063e 100644 +--- a/drivers/net/wireless/realtek/rtw88/usb.c ++++ b/drivers/net/wireless/realtek/rtw88/usb.c +@@ -579,6 +579,8 @@ static void rtw_usb_rx_handler(struct work_struct *work) + + skb_put(skb, pkt_stat.pkt_len); + skb_reserve(skb, pkt_offset); ++ ++ rtw_update_rx_freq_for_invalid(rtwdev, skb, &rx_status, &pkt_stat); + memcpy(skb->cb, &rx_status, sizeof(rx_status)); + ieee80211_rx_irqsafe(rtwdev->hw, skb); + } +-- +2.43.0 + diff --git a/packages/linux/patches/rtlwifi/6.12/0004-6.12-wifi-rtw88-usb-Init-RX-burst-length-according-to-USB.patch b/packages/linux/patches/rtlwifi/6.12/0004-6.12-wifi-rtw88-usb-Init-RX-burst-length-according-to-USB.patch new file mode 100644 index 0000000000..9182801008 --- /dev/null +++ b/packages/linux/patches/rtlwifi/6.12/0004-6.12-wifi-rtw88-usb-Init-RX-burst-length-according-to-USB.patch @@ -0,0 +1,81 @@ +From 93523589d4dae8567b471743e8c6a88bf80750c4 Mon Sep 17 00:00:00 2001 +From: Bitterblue Smith +Date: Thu, 8 Aug 2024 01:19:36 +0300 +Subject: [PATCH 4/7] wifi: rtw88: usb: Init RX burst length according to USB + speed + +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 +--- + drivers/net/wireless/realtek/rtw88/reg.h | 6 ++++++ + drivers/net/wireless/realtek/rtw88/usb.c | 23 ++++++++++++++++++++++- + 2 files changed, 28 insertions(+), 1 deletion(-) + +diff --git a/drivers/net/wireless/realtek/rtw88/reg.h b/drivers/net/wireless/realtek/rtw88/reg.h +index e7b24465f549..4d9b8668e8b0 100644 +--- a/drivers/net/wireless/realtek/rtw88/reg.h ++++ b/drivers/net/wireless/realtek/rtw88/reg.h +@@ -322,6 +322,12 @@ + #define REG_RXDMA_DPR 0x028C + #define REG_RXDMA_MODE 0x0290 + #define BIT_DMA_MODE BIT(1) ++#define BIT_DMA_BURST_CNT GENMASK(3, 2) ++#define BIT_DMA_BURST_SIZE GENMASK(5, 4) ++#define BIT_DMA_BURST_SIZE_64 2 ++#define BIT_DMA_BURST_SIZE_512 1 ++#define BIT_DMA_BURST_SIZE_1024 0 ++ + #define REG_RXPKTNUM 0x02B0 + + #define REG_INT_MIG 0x0304 +diff --git a/drivers/net/wireless/realtek/rtw88/usb.c b/drivers/net/wireless/realtek/rtw88/usb.c +index 9145c11a063e..1c40d46a7eb4 100644 +--- a/drivers/net/wireless/realtek/rtw88/usb.c ++++ b/drivers/net/wireless/realtek/rtw88/usb.c +@@ -720,9 +720,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 = { +-- +2.43.0 + diff --git a/packages/linux/patches/rtlwifi/6.12/0005-6.12-wifi-rtw88-usb-Update-the-RX-stats-after-every-frame.patch b/packages/linux/patches/rtlwifi/6.12/0005-6.12-wifi-rtw88-usb-Update-the-RX-stats-after-every-frame.patch new file mode 100644 index 0000000000..add2d9da6f --- /dev/null +++ b/packages/linux/patches/rtlwifi/6.12/0005-6.12-wifi-rtw88-usb-Update-the-RX-stats-after-every-frame.patch @@ -0,0 +1,36 @@ +From 7198cca8f07045773f92befd8861bb5b3f8bd83d Mon Sep 17 00:00:00 2001 +From: Bitterblue Smith +Date: Thu, 8 Aug 2024 01:20:36 +0300 +Subject: [PATCH 5/7] wifi: rtw88: usb: Update the RX stats after every frame + +Update the number of received unicast data frames and bytes every time +a frame is received. This is what the PCI and SDIO drivers do. + +This has an influence on the power saving, bluetooth coexistence, and +(in a future patch) the use of RX aggregation. + +Tested with RTL8822CU, RTL8811CU, and RTL8723DU. + +Tested-by: Sascha Hauer +Signed-off-by: Bitterblue Smith +Signed-off-by: Ping-Ke Shih +Link: https://patch.msgid.link/75a2ca52-8f01-45c5-926f-d3a68ae3b284@gmail.com +--- + drivers/net/wireless/realtek/rtw88/usb.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/drivers/net/wireless/realtek/rtw88/usb.c b/drivers/net/wireless/realtek/rtw88/usb.c +index 1c40d46a7eb4..10f1d724370e 100644 +--- a/drivers/net/wireless/realtek/rtw88/usb.c ++++ b/drivers/net/wireless/realtek/rtw88/usb.c +@@ -581,6 +581,7 @@ static void rtw_usb_rx_handler(struct work_struct *work) + 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); + memcpy(skb->cb, &rx_status, sizeof(rx_status)); + ieee80211_rx_irqsafe(rtwdev->hw, skb); + } +-- +2.43.0 + diff --git a/packages/linux/patches/rtlwifi/6.12/0006-6.12-wifi-rtw88-usb-Support-RX-aggregation.patch b/packages/linux/patches/rtlwifi/6.12/0006-6.12-wifi-rtw88-usb-Support-RX-aggregation.patch new file mode 100644 index 0000000000..b42de702b3 --- /dev/null +++ b/packages/linux/patches/rtlwifi/6.12/0006-6.12-wifi-rtw88-usb-Support-RX-aggregation.patch @@ -0,0 +1,123 @@ +From 8e07253c6c1c00d2dc5fc8937f3ab15c23be5367 Mon Sep 17 00:00:00 2001 +From: Bitterblue Smith +Date: Thu, 8 Aug 2024 01:21:36 +0300 +Subject: [PATCH 6/7] wifi: rtw88: usb: Support RX aggregation + +The chips can be configured to aggregate several frames into a single +USB transfer. Modify rtw_usb_rx_handler() to support this case. + +RX aggregation improves the RX speed of RTL8811CU on certain ARM +systems, like the NanoPi NEO Core2. It also improves the RX speed of +RTL8822CU on some x86_64 systems. + +Currently none of the chips are configured to aggregate frames. + +Tested with RTL8822CU, RTL8811CU, and RTL8723DU. + +Reviewed-by: Sascha Hauer +Tested-by: Sascha Hauer +Signed-off-by: Bitterblue Smith +Signed-off-by: Ping-Ke Shih +Link: https://patch.msgid.link/f845826d-de71-492d-9a22-e48c07989a1f@gmail.com +--- + drivers/net/wireless/realtek/rtw88/usb.c | 61 ++++++++++++++++-------- + 1 file changed, 40 insertions(+), 21 deletions(-) + +diff --git a/drivers/net/wireless/realtek/rtw88/usb.c b/drivers/net/wireless/realtek/rtw88/usb.c +index 10f1d724370e..64d68366812c 100644 +--- a/drivers/net/wireless/realtek/rtw88/usb.c ++++ b/drivers/net/wireless/realtek/rtw88/usb.c +@@ -546,11 +546,12 @@ static void rtw_usb_rx_handler(struct work_struct *work) + struct rtw_usb *rtwusb = container_of(work, struct rtw_usb, rx_work); + struct rtw_dev *rtwdev = rtwusb->rtwdev; + const struct rtw_chip_info *chip = rtwdev->chip; +- struct rtw_rx_pkt_stat pkt_stat; ++ 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 *skb; +- u32 pkt_desc_sz = chip->rx_pkt_desc_sz; +- u32 pkt_offset; + u8 *rx_desc; + int limit; + +@@ -559,31 +560,48 @@ static void rtw_usb_rx_handler(struct work_struct *work) + if (!skb) + break; + +- rx_desc = skb->data; +- chip->ops->query_rx_desc(rtwdev, rx_desc, &pkt_stat, +- &rx_status); +- pkt_offset = pkt_desc_sz + pkt_stat.drv_info_sz + +- pkt_stat.shift; +- +- if (pkt_stat.is_c2h) { +- skb_put(skb, pkt_stat.pkt_len + pkt_offset); +- rtw_fw_c2h_cmd_rx_irqsafe(rtwdev, pkt_offset, skb); +- continue; +- } +- + 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); + continue; + } + +- skb_put(skb, pkt_stat.pkt_len); +- skb_reserve(skb, pkt_offset); ++ urb_len = skb->len; ++ ++ do { ++ rx_desc = skb->data; ++ chip->ops->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); ++ ++ 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); ++ 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); ++ rtw_rx_stats(rtwdev, pkt_stat.vif, skb); ++ memcpy(skb->cb, &rx_status, sizeof(rx_status)); ++ ieee80211_rx_irqsafe(rtwdev->hw, skb); ++ } ++ ++ skb = next_skb; ++ if (skb) ++ skb_pull(skb, next_pkt); + +- 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); ++ urb_len -= next_pkt; ++ } while (skb); + } + } + +@@ -627,6 +645,7 @@ static void rtw_usb_read_port_complete(struct urb *urb) + if (skb) + dev_kfree_skb_any(skb); + } else { ++ skb_put(skb, urb->actual_length); + skb_queue_tail(&rtwusb->rx_queue, skb); + queue_work(rtwusb->rxwq, &rtwusb->rx_work); + } +-- +2.43.0 + diff --git a/packages/linux/patches/rtlwifi/6.12/0007-6.12-wifi-rtw88-Enable-USB-RX-aggregation-for-8822c-8822b.patch b/packages/linux/patches/rtlwifi/6.12/0007-6.12-wifi-rtw88-Enable-USB-RX-aggregation-for-8822c-8822b.patch new file mode 100644 index 0000000000..12757ddbdb --- /dev/null +++ b/packages/linux/patches/rtlwifi/6.12/0007-6.12-wifi-rtw88-Enable-USB-RX-aggregation-for-8822c-8822b.patch @@ -0,0 +1,182 @@ +From 3e36db62ff52667d63497da45b6cae4cd8382721 Mon Sep 17 00:00:00 2001 +From: Bitterblue Smith +Date: Thu, 8 Aug 2024 01:23:06 +0300 +Subject: [PATCH 7/7] wifi: rtw88: Enable USB RX aggregation for + 8822c/8822b/8821c + +Enable USB RX aggregation when there is at least 1 Mbps RX or TX +traffic, otherwise disable it. + +USB RX aggregation improves the RX speed of RTL8811CU on certain ARM +systems, like the NanoPi NEO Core2. Before: 28 Mbps, after: 231 Mbps. + +It also improves the RX speed of RTL8822CU on some x86_64 systems. +Before: ~200 Mbps, after: ~300 Mbps. + +The official drivers for these chips use the same logic for SDIO, but +for some reason the SDIO driver in rtw88 always enables RX aggregation, +so this patch only toggles aggregation for USB devices. + +RTL8703B is likely not found in USB devices, and RTL8723DU doesn't like +aggregation. + +Tested-by: Sascha Hauer +Signed-off-by: Bitterblue Smith +Signed-off-by: Ping-Ke Shih +Link: https://patch.msgid.link/b4c0d54c-6755-4b0f-9dd7-f9196fd74b68@gmail.com +--- + drivers/net/wireless/realtek/rtw88/hci.h | 7 ++++ + drivers/net/wireless/realtek/rtw88/main.c | 13 +++++--- + drivers/net/wireless/realtek/rtw88/pci.c | 1 + + drivers/net/wireless/realtek/rtw88/sdio.c | 1 + + drivers/net/wireless/realtek/rtw88/usb.c | 40 +++++++++++++++++++++++ + 5 files changed, 58 insertions(+), 4 deletions(-) + +diff --git a/drivers/net/wireless/realtek/rtw88/hci.h b/drivers/net/wireless/realtek/rtw88/hci.h +index 830d7532f2a3..96aeda26014e 100644 +--- a/drivers/net/wireless/realtek/rtw88/hci.h ++++ b/drivers/net/wireless/realtek/rtw88/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/drivers/net/wireless/realtek/rtw88/main.c b/drivers/net/wireless/realtek/rtw88/main.c +index 7ab7a988b123..22b39b3acc6c 100644 +--- a/drivers/net/wireless/realtek/rtw88/main.c ++++ b/drivers/net/wireless/realtek/rtw88/main.c +@@ -212,6 +212,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); ++ u32 tx_unicast_mbps, rx_unicast_mbps; + bool ps_active; + + mutex_lock(&rtwdev->mutex); +@@ -236,10 +237,11 @@ static void rtw_watch_dog_work(struct work_struct *work) + else + ps_active = false; + +- ewma_tp_add(&stats->tx_ewma_tp, +- (u32)(stats->tx_unicast >> RTW_TP_SHIFT)); +- ewma_tp_add(&stats->rx_ewma_tp, +- (u32)(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_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); + +@@ -259,6 +261,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/drivers/net/wireless/realtek/rtw88/pci.c b/drivers/net/wireless/realtek/rtw88/pci.c +index 5d0580da13fb..0b9b8807af2c 100644 +--- a/drivers/net/wireless/realtek/rtw88/pci.c ++++ b/drivers/net/wireless/realtek/rtw88/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/drivers/net/wireless/realtek/rtw88/sdio.c b/drivers/net/wireless/realtek/rtw88/sdio.c +index 763aa8212a4b..21d0754dd7f6 100644 +--- a/drivers/net/wireless/realtek/rtw88/sdio.c ++++ b/drivers/net/wireless/realtek/rtw88/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/drivers/net/wireless/realtek/rtw88/usb.c b/drivers/net/wireless/realtek/rtw88/usb.c +index 64d68366812c..e83ab6fb83f5 100644 +--- a/drivers/net/wireless/realtek/rtw88/usb.c ++++ b/drivers/net/wireless/realtek/rtw88/usb.c +@@ -766,6 +766,45 @@ 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_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)); ++ ++ 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(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_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, +@@ -775,6 +814,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, +-- +2.43.0 + diff --git a/packages/linux/patches/rtlwifi/6.9/0008-wifi-rtw88-8821c-tweak-CCK-TX-filter-setting-for-SRRC.patch b/packages/linux/patches/rtlwifi/6.9/0008-wifi-rtw88-8821c-tweak-CCK-TX-filter-setting-for-SRRC.patch new file mode 100644 index 0000000000..975efdd07a --- /dev/null +++ b/packages/linux/patches/rtlwifi/6.9/0008-wifi-rtw88-8821c-tweak-CCK-TX-filter-setting-for-SRRC.patch @@ -0,0 +1,156 @@ +From 14a5b11532e850e7a748cbb4c74ac5c5abf18211 Mon Sep 17 00:00:00 2001 +From: Zong-Zhe Yang +Date: Wed, 4 Oct 2023 16:50:51 +0800 +Subject: [PATCH] wifi: rtw88: 8821c: tweak CCK TX filter setting for SRRC + regulation + +Since new criterion released by SRRC (State Radio Regulatory Commission, +China) is stricter, we have adjusted TX power limit tables for it. But, +due to RTL8821C HW characteristic, we still need to use specific parameter +in CCK TX filter when set channel to avoid violations in some corner cases. + +Signed-off-by: Zong-Zhe Yang +Signed-off-by: Ping-Ke Shih +Signed-off-by: Kalle Valo +Link: https://lore.kernel.org/r/20231004085051.205683-6-pkshih@realtek.com +--- + drivers/net/wireless/realtek/rtw88/regd.c | 8 +++ + drivers/net/wireless/realtek/rtw88/regd.h | 2 + + drivers/net/wireless/realtek/rtw88/rtw8821c.c | 67 +++++++++++++++++++ + drivers/net/wireless/realtek/rtw88/rtw8821c.h | 1 + + 4 files changed, 78 insertions(+) + +diff --git a/drivers/net/wireless/realtek/rtw88/regd.c b/drivers/net/wireless/realtek/rtw88/regd.c +index 124fc7ae6a1476..7f3b2ea3f2a560 100644 +--- a/drivers/net/wireless/realtek/rtw88/regd.c ++++ b/drivers/net/wireless/realtek/rtw88/regd.c +@@ -502,6 +502,14 @@ u8 rtw_regd_get(struct rtw_dev *rtwdev) + } + EXPORT_SYMBOL(rtw_regd_get); + ++bool rtw_regd_srrc(struct rtw_dev *rtwdev) ++{ ++ struct rtw_regd *regd = &rtwdev->regd; ++ ++ return rtw_reg_match(regd->regulatory, "CN"); ++} ++EXPORT_SYMBOL(rtw_regd_srrc); ++ + struct rtw_regd_alternative_t { + bool set; + u8 alt; +diff --git a/drivers/net/wireless/realtek/rtw88/regd.h b/drivers/net/wireless/realtek/rtw88/regd.h +index 34cb13d0cd9ebc..3c5a6fd8e6ddd8 100644 +--- a/drivers/net/wireless/realtek/rtw88/regd.h ++++ b/drivers/net/wireless/realtek/rtw88/regd.h +@@ -68,4 +68,6 @@ int rtw_regd_init(struct rtw_dev *rtwdev); + int rtw_regd_hint(struct rtw_dev *rtwdev); + u8 rtw_regd_get(struct rtw_dev *rtwdev); + bool rtw_regd_has_alt(u8 regd, u8 *regd_alt); ++bool rtw_regd_srrc(struct rtw_dev *rtwdev); ++ + #endif +diff --git a/drivers/net/wireless/realtek/rtw88/rtw8821c.c b/drivers/net/wireless/realtek/rtw88/rtw8821c.c +index adf224618a2a6f..429bb420b0563e 100644 +--- a/drivers/net/wireless/realtek/rtw88/rtw8821c.c ++++ b/drivers/net/wireless/realtek/rtw88/rtw8821c.c +@@ -381,6 +381,65 @@ static void rtw8821c_set_channel_rxdfir(struct rtw_dev *rtwdev, u8 bw) + } + } + ++static void rtw8821c_cck_tx_filter_srrc(struct rtw_dev *rtwdev, u8 channel, u8 bw) ++{ ++ struct rtw_hal *hal = &rtwdev->hal; ++ ++ if (channel == 14) { ++ rtw_write32_mask(rtwdev, REG_CCA_FLTR, MASKHWORD, 0xe82c); ++ rtw_write32_mask(rtwdev, REG_TXSF2, MASKDWORD, 0x0000b81c); ++ rtw_write32_mask(rtwdev, REG_TXSF6, MASKLWORD, 0x0000); ++ rtw_write32_mask(rtwdev, REG_TXFILTER, MASKDWORD, 0x00003667); ++ ++ rtw_write_rf(rtwdev, RF_PATH_A, RF_LUTWE2, RFREG_MASK, 0x00002); ++ rtw_write_rf(rtwdev, RF_PATH_A, RF_LUTWA, RFREG_MASK, 0x0001e); ++ rtw_write_rf(rtwdev, RF_PATH_A, RF_LUTWD0, RFREG_MASK, 0x00000); ++ rtw_write_rf(rtwdev, RF_PATH_A, RF_LUTWA, RFREG_MASK, 0x0001c); ++ rtw_write_rf(rtwdev, RF_PATH_A, RF_LUTWD0, RFREG_MASK, 0x00000); ++ rtw_write_rf(rtwdev, RF_PATH_A, RF_LUTWA, RFREG_MASK, 0x0000e); ++ rtw_write_rf(rtwdev, RF_PATH_A, RF_LUTWD0, RFREG_MASK, 0x00000); ++ rtw_write_rf(rtwdev, RF_PATH_A, RF_LUTWA, RFREG_MASK, 0x0000c); ++ rtw_write_rf(rtwdev, RF_PATH_A, RF_LUTWD0, RFREG_MASK, 0x00000); ++ rtw_write_rf(rtwdev, RF_PATH_A, RF_LUTWE2, RFREG_MASK, 0x00000); ++ } else if (channel == 13 || ++ (channel == 11 && bw == RTW_CHANNEL_WIDTH_40)) { ++ rtw_write32_mask(rtwdev, REG_CCA_FLTR, MASKHWORD, 0xf8fe); ++ rtw_write32_mask(rtwdev, REG_TXSF2, MASKDWORD, 0x64b80c1c); ++ rtw_write32_mask(rtwdev, REG_TXSF6, MASKLWORD, 0x8810); ++ rtw_write32_mask(rtwdev, REG_TXFILTER, MASKDWORD, 0x01235667); ++ ++ rtw_write_rf(rtwdev, RF_PATH_A, RF_LUTWE2, RFREG_MASK, 0x00002); ++ rtw_write_rf(rtwdev, RF_PATH_A, RF_LUTWA, RFREG_MASK, 0x0001e); ++ rtw_write_rf(rtwdev, RF_PATH_A, RF_LUTWD0, RFREG_MASK, 0x00027); ++ rtw_write_rf(rtwdev, RF_PATH_A, RF_LUTWA, RFREG_MASK, 0x0001c); ++ rtw_write_rf(rtwdev, RF_PATH_A, RF_LUTWD0, RFREG_MASK, 0x00027); ++ rtw_write_rf(rtwdev, RF_PATH_A, RF_LUTWA, RFREG_MASK, 0x0000e); ++ rtw_write_rf(rtwdev, RF_PATH_A, RF_LUTWD0, RFREG_MASK, 0x00029); ++ rtw_write_rf(rtwdev, RF_PATH_A, RF_LUTWA, RFREG_MASK, 0x0000c); ++ rtw_write_rf(rtwdev, RF_PATH_A, RF_LUTWD0, RFREG_MASK, 0x00026); ++ rtw_write_rf(rtwdev, RF_PATH_A, RF_LUTWE2, RFREG_MASK, 0x00000); ++ } else { ++ rtw_write32_mask(rtwdev, REG_CCA_FLTR, MASKHWORD, 0xe82c); ++ rtw_write32_mask(rtwdev, REG_TXSF2, MASKDWORD, ++ hal->ch_param[0]); ++ rtw_write32_mask(rtwdev, REG_TXSF6, MASKLWORD, ++ hal->ch_param[1] & MASKLWORD); ++ rtw_write32_mask(rtwdev, REG_TXFILTER, MASKDWORD, ++ hal->ch_param[2]); ++ ++ rtw_write_rf(rtwdev, RF_PATH_A, RF_LUTWE2, RFREG_MASK, 0x00002); ++ rtw_write_rf(rtwdev, RF_PATH_A, RF_LUTWA, RFREG_MASK, 0x0001e); ++ rtw_write_rf(rtwdev, RF_PATH_A, RF_LUTWD0, RFREG_MASK, 0x00000); ++ rtw_write_rf(rtwdev, RF_PATH_A, RF_LUTWA, RFREG_MASK, 0x0001c); ++ rtw_write_rf(rtwdev, RF_PATH_A, RF_LUTWD0, RFREG_MASK, 0x00000); ++ rtw_write_rf(rtwdev, RF_PATH_A, RF_LUTWA, RFREG_MASK, 0x0000e); ++ rtw_write_rf(rtwdev, RF_PATH_A, RF_LUTWD0, RFREG_MASK, 0x00000); ++ rtw_write_rf(rtwdev, RF_PATH_A, RF_LUTWA, RFREG_MASK, 0x0000c); ++ rtw_write_rf(rtwdev, RF_PATH_A, RF_LUTWD0, RFREG_MASK, 0x00000); ++ rtw_write_rf(rtwdev, RF_PATH_A, RF_LUTWE2, RFREG_MASK, 0x00000); ++ } ++} ++ + static void rtw8821c_set_channel_bb(struct rtw_dev *rtwdev, u8 channel, u8 bw, + u8 primary_ch_idx) + { +@@ -395,6 +454,13 @@ static void rtw8821c_set_channel_bb(struct rtw_dev *rtwdev, u8 channel, u8 bw, + + rtw_write32_mask(rtwdev, REG_TXSCALE_A, 0xf00, 0x0); + rtw_write32_mask(rtwdev, REG_CLKTRK, 0x1ffe0000, 0x96a); ++ ++ if (rtw_regd_srrc(rtwdev)) { ++ rtw8821c_cck_tx_filter_srrc(rtwdev, channel, bw); ++ goto set_bw; ++ } ++ ++ /* CCK TX filter parameters for default case */ + if (channel == 14) { + rtw_write32_mask(rtwdev, REG_TXSF2, MASKDWORD, 0x0000b81c); + rtw_write32_mask(rtwdev, REG_TXSF6, MASKLWORD, 0x0000); +@@ -430,6 +496,7 @@ static void rtw8821c_set_channel_bb(struct rtw_dev *rtwdev, u8 channel, u8 bw, + rtw_write32_mask(rtwdev, REG_CLKTRK, 0x1ffe0000, 0x412); + } + ++set_bw: + switch (bw) { + case RTW_CHANNEL_WIDTH_20: + default: +diff --git a/drivers/net/wireless/realtek/rtw88/rtw8821c.h b/drivers/net/wireless/realtek/rtw88/rtw8821c.h +index fcff31688c453a..91ed921407bbe7 100644 +--- a/drivers/net/wireless/realtek/rtw88/rtw8821c.h ++++ b/drivers/net/wireless/realtek/rtw88/rtw8821c.h +@@ -238,6 +238,7 @@ extern const struct rtw_chip_info rtw8821c_hw_spec; + #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 diff --git a/packages/linux/patches/rtlwifi/6.9/0009-wifi-rtw88-8822ce-refine-power-parameters-for-RFE-type-5.patch b/packages/linux/patches/rtlwifi/6.9/0009-wifi-rtw88-8822ce-refine-power-parameters-for-RFE-type-5.patch new file mode 100644 index 0000000000..32bd7cb44a --- /dev/null +++ b/packages/linux/patches/rtlwifi/6.9/0009-wifi-rtw88-8822ce-refine-power-parameters-for-RFE-type-5.patch @@ -0,0 +1,52 @@ +From 8d101b15f86dae41fcf1afe448d5a52c1956c465 Mon Sep 17 00:00:00 2001 +From: Ping-Ke Shih +Date: Wed, 3 Jan 2024 15:01:55 +0800 +Subject: [PATCH] wifi: rtw88: 8822ce: refine power parameters for RFE type 5 + +Refine the power parameters for better step response especially at high +current ramp case that is caused by power inductor variation. + +Signed-off-by: Ping-Ke Shih +Signed-off-by: Kalle Valo +Link: https://msgid.link/20240103070155.119488-1-pkshih@realtek.com +--- + drivers/net/wireless/realtek/rtw88/pci.c | 4 ++++ + drivers/net/wireless/realtek/rtw88/reg.h | 3 +++ + 2 files changed, 7 insertions(+) + +diff --git a/drivers/net/wireless/realtek/rtw88/pci.c b/drivers/net/wireless/realtek/rtw88/pci.c +index 2bfc0e822b8d0b..9986a4cb37eb2b 100644 +--- a/drivers/net/wireless/realtek/rtw88/pci.c ++++ b/drivers/net/wireless/realtek/rtw88/pci.c +@@ -1450,6 +1450,7 @@ static void rtw_pci_phy_cfg(struct rtw_dev *rtwdev) + { + struct rtw_pci *rtwpci = (struct rtw_pci *)rtwdev->priv; + const struct rtw_chip_info *chip = rtwdev->chip; ++ struct rtw_efuse *efuse = &rtwdev->efuse; + struct pci_dev *pdev = rtwpci->pdev; + const struct rtw_intf_phy_para *para; + u16 cut; +@@ -1498,6 +1499,9 @@ static void rtw_pci_phy_cfg(struct rtw_dev *rtwdev) + rtw_err(rtwdev, "failed to set PCI cap, ret = %d\n", + ret); + } ++ ++ if (chip->id == RTW_CHIP_TYPE_8822C && efuse->rfe_option == 5) ++ rtw_write32_mask(rtwdev, REG_ANAPARSW_MAC_0, BIT_CF_L_V2, 0x1); + } + + static int __maybe_unused rtw_pci_suspend(struct device *dev) +diff --git a/drivers/net/wireless/realtek/rtw88/reg.h b/drivers/net/wireless/realtek/rtw88/reg.h +index 1634f03784f171..b122f226924be5 100644 +--- a/drivers/net/wireless/realtek/rtw88/reg.h ++++ b/drivers/net/wireless/realtek/rtw88/reg.h +@@ -557,6 +557,9 @@ + #define REG_RFE_INV16 0x0cbe + #define BIT_RFE_BUF_EN BIT(3) + ++#define REG_ANAPARSW_MAC_0 0x1010 ++#define BIT_CF_L_V2 GENMASK(29, 28) ++ + #define REG_ANAPAR_XTAL_0 0x1040 + #define BIT_XCAP_0 GENMASK(23, 10) + #define REG_CPU_DMEM_CON 0x1080 diff --git a/packages/linux/patches/rtlwifi/6.9/0010-wifi-rtw88-debug-add-to-check-if-debug-mask-is-enabled.patch b/packages/linux/patches/rtlwifi/6.9/0010-wifi-rtw88-debug-add-to-check-if-debug-mask-is-enabled.patch new file mode 100644 index 0000000000..94de3f7490 --- /dev/null +++ b/packages/linux/patches/rtlwifi/6.9/0010-wifi-rtw88-debug-add-to-check-if-debug-mask-is-enabled.patch @@ -0,0 +1,46 @@ +From 1926a27299db00239d6bdc4c3f2bd3f842277d0d Mon Sep 17 00:00:00 2001 +From: Chin-Yen Lee +Date: Mon, 16 Oct 2023 13:35:53 +0800 +Subject: [PATCH] wifi: rtw88: debug: add to check if debug mask is enabled + +The coming dump function for FW malfunction will add a function to +dump registers to reflect status. However, if we are not debugging +the mechanism, we don't print anything, so avoid reading registers by +checking debug mask to reduce IO. + +Signed-off-by: Chin-Yen Lee +Signed-off-by: Ping-Ke Shih +Signed-off-by: Kalle Valo +Link: https://lore.kernel.org/r/20231016053554.744180-2-pkshih@realtek.com +--- + drivers/net/wireless/realtek/rtw88/debug.h | 12 ++++++++++++ + 1 file changed, 12 insertions(+) + +diff --git a/drivers/net/wireless/realtek/rtw88/debug.h b/drivers/net/wireless/realtek/rtw88/debug.h +index a9149c6c2b48c5..a03ced11bbe042 100644 +--- a/drivers/net/wireless/realtek/rtw88/debug.h ++++ b/drivers/net/wireless/realtek/rtw88/debug.h +@@ -48,11 +48,23 @@ void __rtw_dbg(struct rtw_dev *rtwdev, enum rtw_debug_mask mask, + + #define rtw_dbg(rtwdev, a...) __rtw_dbg(rtwdev, ##a) + ++static inline bool rtw_dbg_is_enabled(struct rtw_dev *rtwdev, ++ enum rtw_debug_mask mask) ++{ ++ return !!(rtw_debug_mask & mask); ++} ++ + #else + + static inline void rtw_dbg(struct rtw_dev *rtwdev, enum rtw_debug_mask mask, + const char *fmt, ...) {} + ++static inline bool rtw_dbg_is_enabled(struct rtw_dev *rtwdev, ++ enum rtw_debug_mask mask) ++{ ++ return false; ++} ++ + #endif /* CONFIG_RTW88_DEBUG */ + + #define rtw_info(rtwdev, a...) dev_info(rtwdev->dev, ##a) diff --git a/packages/linux/patches/rtlwifi/6.9/0011-wifi-rtw88-dump-firmware-debug-information-in-abnormal-state.patch b/packages/linux/patches/rtlwifi/6.9/0011-wifi-rtw88-dump-firmware-debug-information-in-abnormal-state.patch new file mode 100644 index 0000000000..30c227fdb9 --- /dev/null +++ b/packages/linux/patches/rtlwifi/6.9/0011-wifi-rtw88-dump-firmware-debug-information-in-abnormal-state.patch @@ -0,0 +1,234 @@ +From 20907fc069976fcf972239b7b253cf7c59c08a14 Mon Sep 17 00:00:00 2001 +From: Chin-Yen Lee +Date: Mon, 16 Oct 2023 13:35:54 +0800 +Subject: [PATCH] wifi: rtw88: dump firmware debug information in abnormal + state + +Sometimes firmware may enter strange state or infinite +loop due to unknown bug, and then it will lead critical +function fail, such as sending H2C command or changing +power mode. In these abnormal states, we add more debug +information, including hardware register status, to help +further investigation. + +Signed-off-by: Chin-Yen Lee +Signed-off-by: Ping-Ke Shih +Signed-off-by: Kalle Valo +Link: https://lore.kernel.org/r/20231016053554.744180-3-pkshih@realtek.com +--- + drivers/net/wireless/realtek/rtw88/fw.c | 74 +++++++++++++++++++++++ + drivers/net/wireless/realtek/rtw88/fw.h | 3 + + drivers/net/wireless/realtek/rtw88/main.h | 6 ++ + drivers/net/wireless/realtek/rtw88/ps.c | 2 + + drivers/net/wireless/realtek/rtw88/reg.h | 23 +++++++ + 5 files changed, 108 insertions(+) + +diff --git a/drivers/net/wireless/realtek/rtw88/fw.c b/drivers/net/wireless/realtek/rtw88/fw.c +index a1b674e3caaa3c..acd78311c8c4a1 100644 +--- a/drivers/net/wireless/realtek/rtw88/fw.c ++++ b/drivers/net/wireless/realtek/rtw88/fw.c +@@ -17,6 +17,79 @@ + #include "phy.h" + #include "mac.h" + ++static const struct rtw_hw_reg_desc fw_h2c_regs[] = { ++ {REG_FWIMR, MASKDWORD, "FWIMR"}, ++ {REG_FWIMR, BIT_FS_H2CCMD_INT_EN, "FWIMR enable"}, ++ {REG_FWISR, MASKDWORD, "FWISR"}, ++ {REG_FWISR, BIT_FS_H2CCMD_INT, "FWISR enable"}, ++ {REG_HMETFR, BIT_INT_BOX_ALL, "BoxBitMap"}, ++ {REG_HMEBOX0, MASKDWORD, "MSG 0"}, ++ {REG_HMEBOX0_EX, MASKDWORD, "MSG_EX 0"}, ++ {REG_HMEBOX1, MASKDWORD, "MSG 1"}, ++ {REG_HMEBOX1_EX, MASKDWORD, "MSG_EX 1"}, ++ {REG_HMEBOX2, MASKDWORD, "MSG 2"}, ++ {REG_HMEBOX2_EX, MASKDWORD, "MSG_EX 2"}, ++ {REG_HMEBOX3, MASKDWORD, "MSG 3"}, ++ {REG_HMEBOX3_EX, MASKDWORD, "MSG_EX 3"}, ++ {REG_FT1IMR, MASKDWORD, "FT1IMR"}, ++ {REG_FT1IMR, BIT_FS_H2C_CMD_OK_INT_EN, "FT1IMR enable"}, ++ {REG_FT1ISR, MASKDWORD, "FT1ISR"}, ++ {REG_FT1ISR, BIT_FS_H2C_CMD_OK_INT, "FT1ISR enable "}, ++}; ++ ++static const struct rtw_hw_reg_desc fw_c2h_regs[] = { ++ {REG_FWIMR, MASKDWORD, "FWIMR"}, ++ {REG_FWIMR, BIT_FS_H2CCMD_INT_EN, "CPWM"}, ++ {REG_FWIMR, BIT_FS_HRCV_INT_EN, "HRECV"}, ++ {REG_FWISR, MASKDWORD, "FWISR"}, ++ {REG_FWISR, BIT_FS_H2CCMD_INT, "CPWM"}, ++ {REG_FWISR, BIT_FS_HRCV_INT, "HRECV"}, ++ {REG_CPWM, MASKDWORD, "REG_CPWM"}, ++}; ++ ++static const struct rtw_hw_reg_desc fw_core_regs[] = { ++ {REG_ARFR2_V1, MASKDWORD, "EPC"}, ++ {REG_ARFRH2_V1, MASKDWORD, "BADADDR"}, ++ {REG_ARFR3_V1, MASKDWORD, "CAUSE"}, ++ {REG_ARFR3_V1, BIT_EXC_CODE, "ExcCode"}, ++ {REG_ARFRH3_V1, MASKDWORD, "Status"}, ++ {REG_ARFR4, MASKDWORD, "SP"}, ++ {REG_ARFRH4, MASKDWORD, "RA"}, ++ {REG_FW_DBG6, MASKDWORD, "DBG 6"}, ++ {REG_FW_DBG7, MASKDWORD, "DBG 7"}, ++}; ++ ++static void _rtw_fw_dump_dbg_info(struct rtw_dev *rtwdev, ++ const struct rtw_hw_reg_desc regs[], u32 size) ++{ ++ const struct rtw_hw_reg_desc *reg; ++ u32 val; ++ int i; ++ ++ for (i = 0; i < size; i++) { ++ reg = ®s[i]; ++ val = rtw_read32_mask(rtwdev, reg->addr, reg->mask); ++ ++ rtw_dbg(rtwdev, RTW_DBG_FW, "[%s]addr:0x%x mask:0x%x value:0x%x\n", ++ reg->desc, reg->addr, reg->mask, val); ++ } ++} ++ ++void rtw_fw_dump_dbg_info(struct rtw_dev *rtwdev) ++{ ++ int i; ++ ++ if (!rtw_dbg_is_enabled(rtwdev, RTW_DBG_FW)) ++ return; ++ ++ _rtw_fw_dump_dbg_info(rtwdev, fw_h2c_regs, ARRAY_SIZE(fw_h2c_regs)); ++ _rtw_fw_dump_dbg_info(rtwdev, fw_c2h_regs, ARRAY_SIZE(fw_c2h_regs)); ++ for (i = 0 ; i < RTW_DEBUG_DUMP_TIMES; i++) { ++ rtw_dbg(rtwdev, RTW_DBG_FW, "Firmware Coredump %dth\n", i + 1); ++ _rtw_fw_dump_dbg_info(rtwdev, fw_core_regs, ARRAY_SIZE(fw_core_regs)); ++ } ++} ++ + static void rtw_fw_c2h_cmd_handle_ext(struct rtw_dev *rtwdev, + struct sk_buff *skb) + { +@@ -349,6 +422,7 @@ static void rtw_fw_send_h2c_command_register(struct rtw_dev *rtwdev, + + if (ret) { + rtw_err(rtwdev, "failed to send h2c command\n"); ++ rtw_fw_dump_dbg_info(rtwdev); + return; + } + +diff --git a/drivers/net/wireless/realtek/rtw88/fw.h b/drivers/net/wireless/realtek/rtw88/fw.h +index 43ccdf9965ac46..84e47c71ea1255 100644 +--- a/drivers/net/wireless/realtek/rtw88/fw.h ++++ b/drivers/net/wireless/realtek/rtw88/fw.h +@@ -44,6 +44,8 @@ + #define RTW_OLD_PROBE_PG_CNT 2 + #define RTW_PROBE_PG_CNT 4 + ++#define RTW_DEBUG_DUMP_TIMES 10 ++ + enum rtw_c2h_cmd_id { + C2H_CCX_TX_RPT = 0x03, + C2H_BT_INFO = 0x09, +@@ -808,6 +810,7 @@ static inline bool rtw_fw_feature_ext_check(struct rtw_fw_state *fw, + return !!(fw->feature_ext & feature); + } + ++void rtw_fw_dump_dbg_info(struct rtw_dev *rtwdev); + void rtw_fw_c2h_cmd_rx_irqsafe(struct rtw_dev *rtwdev, u32 pkt_offset, + struct sk_buff *skb); + void rtw_fw_c2h_cmd_handle(struct rtw_dev *rtwdev, struct sk_buff *skb); +diff --git a/drivers/net/wireless/realtek/rtw88/main.h b/drivers/net/wireless/realtek/rtw88/main.h +index 86dc1516effade..b6bfd4c02e2db3 100644 +--- a/drivers/net/wireless/realtek/rtw88/main.h ++++ b/drivers/net/wireless/realtek/rtw88/main.h +@@ -524,6 +524,12 @@ struct rtw_hw_reg { + u32 mask; + }; + ++struct rtw_hw_reg_desc { ++ u32 addr; ++ u32 mask; ++ const char *desc; ++}; ++ + struct rtw_ltecoex_addr { + u32 ctrl; + u32 wdata; +diff --git a/drivers/net/wireless/realtek/rtw88/ps.c b/drivers/net/wireless/realtek/rtw88/ps.c +index 07e8cbd436cd81..add5a20b84320f 100644 +--- a/drivers/net/wireless/realtek/rtw88/ps.c ++++ b/drivers/net/wireless/realtek/rtw88/ps.c +@@ -104,6 +104,7 @@ void rtw_power_mode_change(struct rtw_dev *rtwdev, bool enter) + */ + WARN(1, "firmware failed to ack driver for %s Deep Power mode\n", + enter ? "entering" : "leaving"); ++ rtw_fw_dump_dbg_info(rtwdev); + } + } + EXPORT_SYMBOL(rtw_power_mode_change); +@@ -164,6 +165,7 @@ static void rtw_fw_leave_lps_check(struct rtw_dev *rtwdev) + if (ret) { + rtw_write32_clr(rtwdev, REG_TCR, BIT_PWRMGT_HWDATA_EN); + rtw_warn(rtwdev, "firmware failed to leave lps state\n"); ++ rtw_fw_dump_dbg_info(rtwdev); + } + } + +diff --git a/drivers/net/wireless/realtek/rtw88/reg.h b/drivers/net/wireless/realtek/rtw88/reg.h +index 7c6c11d50ff30f..1634f03784f171 100644 +--- a/drivers/net/wireless/realtek/rtw88/reg.h ++++ b/drivers/net/wireless/realtek/rtw88/reg.h +@@ -224,12 +224,25 @@ + #define REG_RXFF_BNDY 0x011C + #define REG_FE1IMR 0x0120 + #define BIT_FS_RXDONE BIT(16) ++#define REG_CPWM 0x012C ++#define REG_FWIMR 0x0130 ++#define BIT_FS_H2CCMD_INT_EN BIT(4) ++#define BIT_FS_HRCV_INT_EN BIT(5) ++#define REG_FWISR 0x0134 ++#define BIT_FS_H2CCMD_INT BIT(4) ++#define BIT_FS_HRCV_INT BIT(5) + #define REG_PKTBUF_DBG_CTRL 0x0140 + #define REG_C2HEVT 0x01A0 + #define REG_MCUTST_1 0x01C0 + #define REG_MCUTST_II 0x01C4 + #define REG_WOWLAN_WAKE_REASON 0x01C7 + #define REG_HMETFR 0x01CC ++#define BIT_INT_BOX0 BIT(0) ++#define BIT_INT_BOX1 BIT(1) ++#define BIT_INT_BOX2 BIT(2) ++#define BIT_INT_BOX3 BIT(3) ++#define BIT_INT_BOX_ALL (BIT_INT_BOX0 | BIT_INT_BOX1 | BIT_INT_BOX2 | \ ++ BIT_INT_BOX3) + #define REG_HMEBOX0 0x01D0 + #define REG_HMEBOX1 0x01D4 + #define REG_HMEBOX2 0x01D8 +@@ -338,6 +351,11 @@ + #define BIT_EN_GNT_BT_AWAKE BIT(3) + #define BIT_EN_EOF_V1 BIT(2) + #define REG_DATA_SC 0x0483 ++#define REG_ARFR2_V1 0x048C ++#define REG_ARFRH2_V1 0x0490 ++#define REG_ARFR3_V1 0x0494 ++#define BIT_EXC_CODE GENMASK(6, 2) ++#define REG_ARFRH3_V1 0x0498 + #define REG_ARFR4 0x049C + #define BIT_WL_RFK BIT(0) + #define REG_ARFRH4 0x04A0 +@@ -548,11 +566,16 @@ + + #define REG_H2C_PKT_READADDR 0x10D0 + #define REG_H2C_PKT_WRITEADDR 0x10D4 ++#define REG_FW_DBG6 0x10F8 + #define REG_FW_DBG7 0x10FC + #define FW_KEY_MASK 0xffffff00 + + #define REG_CR_EXT 0x1100 + ++#define REG_FT1IMR 0x1138 ++#define BIT_FS_H2C_CMD_OK_INT_EN BIT(25) ++#define REG_FT1ISR 0x113c ++#define BIT_FS_H2C_CMD_OK_INT BIT(25) + #define REG_DDMA_CH0SA 0x1200 + #define REG_DDMA_CH0DA 0x1204 + #define REG_DDMA_CH0CTRL 0x1208 diff --git a/packages/linux/patches/rtlwifi/after-6.12/0001-wifi-rtw88-Constify-some-arrays-and-structs.patch b/packages/linux/patches/rtlwifi/after-6.12/0001-wifi-rtw88-Constify-some-arrays-and-structs.patch new file mode 100644 index 0000000000..ac87eb73e0 --- /dev/null +++ b/packages/linux/patches/rtlwifi/after-6.12/0001-wifi-rtw88-Constify-some-arrays-and-structs.patch @@ -0,0 +1,392 @@ +From aadcf641c25806859aae90fa4c77d34039306046 Mon Sep 17 00:00:00 2001 +From: Bitterblue Smith +Date: Wed, 18 Sep 2024 01:53:55 +0300 +Subject: [PATCH 1/2] wifi: rtw88: Constify some arrays and structs + +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 +--- + drivers/net/wireless/realtek/rtw88/fw.c | 2 +- + drivers/net/wireless/realtek/rtw88/mac.c | 4 ++-- + drivers/net/wireless/realtek/rtw88/main.h | 8 +++---- + drivers/net/wireless/realtek/rtw88/phy.c | 2 +- + drivers/net/wireless/realtek/rtw88/rtw8703b.c | 6 ++--- + drivers/net/wireless/realtek/rtw88/rtw8723d.c | 6 ++--- + drivers/net/wireless/realtek/rtw88/rtw8821c.c | 22 +++++++++---------- + drivers/net/wireless/realtek/rtw88/rtw8822b.c | 10 ++++----- + drivers/net/wireless/realtek/rtw88/rtw8822c.c | 10 ++++----- + 9 files changed, 35 insertions(+), 35 deletions(-) + +diff --git a/drivers/net/wireless/realtek/rtw88/fw.c b/drivers/net/wireless/realtek/rtw88/fw.c +index ab7d414d0ba6..1b97d33b3db5 100644 +--- a/drivers/net/wireless/realtek/rtw88/fw.c ++++ b/drivers/net/wireless/realtek/rtw88/fw.c +@@ -267,7 +267,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/drivers/net/wireless/realtek/rtw88/mac.c b/drivers/net/wireless/realtek/rtw88/mac.c +index 564f5988ee82..e5abcc20b63c 100644 +--- a/drivers/net/wireless/realtek/rtw88/mac.c ++++ b/drivers/net/wireless/realtek/rtw88/mac.c +@@ -228,7 +228,7 @@ static int rtw_sub_pwr_seq_parser(struct rtw_dev *rtwdev, u8 intf_mask, + } + + static 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; +@@ -271,7 +271,7 @@ static int rtw_pwr_seq_parser(struct rtw_dev *rtwdev, + 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/drivers/net/wireless/realtek/rtw88/main.h b/drivers/net/wireless/realtek/rtw88/main.h +index 37912dded128..4f79165fdf79 100644 +--- a/drivers/net/wireless/realtek/rtw88/main.h ++++ b/drivers/net/wireless/realtek/rtw88/main.h +@@ -1167,7 +1167,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; +@@ -1209,8 +1209,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; +@@ -1242,7 +1242,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/drivers/net/wireless/realtek/rtw88/phy.c b/drivers/net/wireless/realtek/rtw88/phy.c +index 37ef80c9091d..d57a2aabd89b 100644 +--- a/drivers/net/wireless/realtek/rtw88/phy.c ++++ b/drivers/net/wireless/realtek/rtw88/phy.c +@@ -123,7 +123,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/drivers/net/wireless/realtek/rtw88/rtw8703b.c b/drivers/net/wireless/realtek/rtw88/rtw8703b.c +index 222608de33cd..e3ac748ad646 100644 +--- a/drivers/net/wireless/realtek/rtw88/rtw8703b.c ++++ b/drivers/net/wireless/realtek/rtw88/rtw8703b.c +@@ -481,14 +481,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, +@@ -1941,7 +1941,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 = { + .mac_init = rtw8723x_mac_init, + .dump_fw_crash = NULL, + .shutdown = NULL, +diff --git a/drivers/net/wireless/realtek/rtw88/rtw8723d.c b/drivers/net/wireless/realtek/rtw88/rtw8723d.c +index 3fba4054d45f..7f33e141e646 100644 +--- a/drivers/net/wireless/realtek/rtw88/rtw8723d.c ++++ b/drivers/net/wireless/realtek/rtw88/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 = { + .phy_set_param = rtw8723d_phy_set_param, + .read_efuse = rtw8723x_read_efuse, + .query_rx_desc = rtw8723d_query_rx_desc, +@@ -1788,7 +1788,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 +@@ -2004,7 +2004,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/drivers/net/wireless/realtek/rtw88/rtw8821c.c b/drivers/net/wireless/realtek/rtw88/rtw8821c.c +index 526e8de77b3e..9d21c4b1450e 100644 +--- a/drivers/net/wireless/realtek/rtw88/rtw8821c.c ++++ b/drivers/net/wireless/realtek/rtw88/rtw8821c.c +@@ -1254,7 +1254,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, +@@ -1292,7 +1292,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, +@@ -1396,7 +1396,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, +@@ -1454,7 +1454,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, +@@ -1567,13 +1567,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 +@@ -1629,7 +1629,7 @@ static const struct rtw_rfe_def rtw8821c_rfe_defs[] = { + [6] = RTW_DEF_RFE(8821c, 0, 0), + }; + +-static struct rtw_hw_reg rtw8821c_dig[] = { ++static const struct rtw_hw_reg rtw8821c_dig[] = { + [0] = { .addr = 0xc50, .mask = 0x7f }, + }; + +@@ -1639,7 +1639,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}, +@@ -1648,7 +1648,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, +@@ -1667,7 +1667,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, + }, +@@ -1683,7 +1683,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 = { + .phy_set_param = rtw8821c_phy_set_param, + .read_efuse = rtw8821c_read_efuse, + .query_rx_desc = rtw8821c_query_rx_desc, +diff --git a/drivers/net/wireless/realtek/rtw88/rtw8822b.c b/drivers/net/wireless/realtek/rtw88/rtw8822b.c +index 6edb17aea90e..650585086e8f 100644 +--- a/drivers/net/wireless/realtek/rtw88/rtw8822b.c ++++ b/drivers/net/wireless/realtek/rtw88/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 +@@ -2156,7 +2156,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, + }, +@@ -2172,7 +2172,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 = { + .phy_set_param = rtw8822b_phy_set_param, + .read_efuse = rtw8822b_read_efuse, + .query_rx_desc = rtw8822b_query_rx_desc, +@@ -2521,7 +2521,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/drivers/net/wireless/realtek/rtw88/rtw8822c.c b/drivers/net/wireless/realtek/rtw88/rtw8822c.c +index 96a233079e02..d6c5d0a3ea20 100644 +--- a/drivers/net/wireless/realtek/rtw88/rtw8822c.c ++++ b/drivers/net/wireless/realtek/rtw88/rtw8822c.c +@@ -4872,13 +4872,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 +@@ -4970,7 +4970,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, + }, +@@ -4986,7 +4986,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 = { + .phy_set_param = rtw8822c_phy_set_param, + .read_efuse = rtw8822c_read_efuse, + .query_rx_desc = rtw8822c_query_rx_desc, +@@ -5299,7 +5299,7 @@ static const struct rtw_pwr_track_tbl rtw8822c_rtw_pwr_track_tbl = { + .pwrtrk_2g_ccka_p = rtw8822c_pwrtrk_2g_cck_a_p, + }; + +-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 + }, +-- +2.43.0 + diff --git a/packages/linux/patches/rtlwifi/after-6.12/0002-wifi-rtw88-Parse-the-RX-descriptor-with-a-single-fun.patch b/packages/linux/patches/rtlwifi/after-6.12/0002-wifi-rtw88-Parse-the-RX-descriptor-with-a-single-fun.patch new file mode 100644 index 0000000000..eb49507d4f --- /dev/null +++ b/packages/linux/patches/rtlwifi/after-6.12/0002-wifi-rtw88-Parse-the-RX-descriptor-with-a-single-fun.patch @@ -0,0 +1,582 @@ +From f54ea3b5f3c12efda28da7541af17c89c66de15b Mon Sep 17 00:00:00 2001 +From: Bitterblue Smith +Date: Fri, 20 Sep 2024 22:27:30 +0300 +Subject: [PATCH 2/2] wifi: rtw88: Parse the RX descriptor with a single + function + +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 +--- + drivers/net/wireless/realtek/rtw88/main.h | 5 +- + drivers/net/wireless/realtek/rtw88/pci.c | 2 +- + drivers/net/wireless/realtek/rtw88/rtw8703b.c | 56 +-------------- + drivers/net/wireless/realtek/rtw88/rtw8723d.c | 43 +----------- + drivers/net/wireless/realtek/rtw88/rtw8821c.c | 43 +----------- + drivers/net/wireless/realtek/rtw88/rtw8822b.c | 43 +----------- + drivers/net/wireless/realtek/rtw88/rtw8822c.c | 44 +----------- + drivers/net/wireless/realtek/rtw88/rx.c | 70 +++++++++++++++++-- + drivers/net/wireless/realtek/rtw88/rx.h | 64 ++++++++--------- + drivers/net/wireless/realtek/rtw88/sdio.c | 3 +- + drivers/net/wireless/realtek/rtw88/usb.c | 4 +- + 11 files changed, 106 insertions(+), 271 deletions(-) + +diff --git a/drivers/net/wireless/realtek/rtw88/main.h b/drivers/net/wireless/realtek/rtw88/main.h +index 4f79165fdf79..7b5546284489 100644 +--- a/drivers/net/wireless/realtek/rtw88/main.h ++++ b/drivers/net/wireless/realtek/rtw88/main.h +@@ -848,9 +848,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/drivers/net/wireless/realtek/rtw88/pci.c b/drivers/net/wireless/realtek/rtw88/pci.c +index 0b9b8807af2c..f71e41d6f97c 100644 +--- a/drivers/net/wireless/realtek/rtw88/pci.c ++++ b/drivers/net/wireless/realtek/rtw88/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/drivers/net/wireless/realtek/rtw88/rtw8703b.c b/drivers/net/wireless/realtek/rtw88/rtw8703b.c +index e3ac748ad646..77399b8dd8cd 100644 +--- a/drivers/net/wireless/realtek/rtw88/rtw8703b.c ++++ b/drivers/net/wireless/realtek/rtw88/rtw8703b.c +@@ -29,9 +29,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, \ +@@ -1032,57 +1029,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 +@@ -1948,7 +1894,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/drivers/net/wireless/realtek/rtw88/rtw8723d.c b/drivers/net/wireless/realtek/rtw88/rtw8723d.c +index 7f33e141e646..86a5e2497641 100644 +--- a/drivers/net/wireless/realtek/rtw88/rtw8723d.c ++++ b/drivers/net/wireless/realtek/rtw88/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) + { +@@ -1433,7 +1392,7 @@ static void rtw8723d_pwr_track(struct rtw_dev *rtwdev) + static const struct rtw_chip_ops rtw8723d_ops = { + .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/drivers/net/wireless/realtek/rtw88/rtw8821c.c b/drivers/net/wireless/realtek/rtw88/rtw8821c.c +index 9d21c4b1450e..66c79956e8e5 100644 +--- a/drivers/net/wireless/realtek/rtw88/rtw8821c.c ++++ b/drivers/net/wireless/realtek/rtw88/rtw8821c.c +@@ -679,47 +679,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) + { +@@ -1686,7 +1645,7 @@ static const struct rtw_prioq_addrs prioq_addrs_8821c = { + static const struct rtw_chip_ops rtw8821c_ops = { + .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/drivers/net/wireless/realtek/rtw88/rtw8822b.c b/drivers/net/wireless/realtek/rtw88/rtw8822b.c +index 650585086e8f..24f76a36f23e 100644 +--- a/drivers/net/wireless/realtek/rtw88/rtw8822b.c ++++ b/drivers/net/wireless/realtek/rtw88/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) + { +@@ -2175,7 +2134,7 @@ static const struct rtw_prioq_addrs prioq_addrs_8822b = { + static const struct rtw_chip_ops rtw8822b_ops = { + .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/drivers/net/wireless/realtek/rtw88/rtw8822c.c b/drivers/net/wireless/realtek/rtw88/rtw8822c.c +index d6c5d0a3ea20..b5046dc10990 100644 +--- a/drivers/net/wireless/realtek/rtw88/rtw8822c.c ++++ b/drivers/net/wireless/realtek/rtw88/rtw8822c.c +@@ -2688,48 +2688,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) +@@ -4989,7 +4947,7 @@ static const struct rtw_prioq_addrs prioq_addrs_8822c = { + static const struct rtw_chip_ops rtw8822c_ops = { + .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/drivers/net/wireless/realtek/rtw88/rx.c b/drivers/net/wireless/realtek/rtw88/rx.c +index 66f9419588cf..1de93fc9efe9 100644 +--- a/drivers/net/wireless/realtek/rtw88/rx.c ++++ b/drivers/net/wireless/realtek/rtw88/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; +@@ -242,5 +241,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/drivers/net/wireless/realtek/rtw88/rx.h b/drivers/net/wireless/realtek/rtw88/rx.h +index 9f0019112987..6b7dee245c0a 100644 +--- a/drivers/net/wireless/realtek/rtw88/rx.h ++++ b/drivers/net/wireless/realtek/rtw88/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/drivers/net/wireless/realtek/rtw88/sdio.c b/drivers/net/wireless/realtek/rtw88/sdio.c +index 21d0754dd7f6..601b30070f53 100644 +--- a/drivers/net/wireless/realtek/rtw88/sdio.c ++++ b/drivers/net/wireless/realtek/rtw88/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/drivers/net/wireless/realtek/rtw88/usb.c b/drivers/net/wireless/realtek/rtw88/usb.c +index e83ab6fb83f5..2641059d3561 100644 +--- a/drivers/net/wireless/realtek/rtw88/usb.c ++++ b/drivers/net/wireless/realtek/rtw88/usb.c +@@ -570,8 +570,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; + +-- +2.43.0 + diff --git a/packages/linux/patches/rtlwifi/after-6.12/0003-wifi-rtw88-Add-support-for-RTL8821AU-and-RTL8812AU.patch b/packages/linux/patches/rtlwifi/after-6.12/0003-wifi-rtw88-Add-support-for-RTL8821AU-and-RTL8812AU.patch new file mode 100644 index 0000000000..0b9ce59ed7 --- /dev/null +++ b/packages/linux/patches/rtlwifi/after-6.12/0003-wifi-rtw88-Add-support-for-RTL8821AU-and-RTL8812AU.patch @@ -0,0 +1,14203 @@ +From mboxrd@z Thu Jan 1 00:00:00 1970 +Received: from mail-wm1-f48.google.com (mail-wm1-f48.google.com [209.85.128.48]) + (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) + (No client certificate requested) + by smtp.subspace.kernel.org (Postfix) with ESMTPS id 1AB351CF7A0 + for ; Fri, 11 Oct 2024 20:31:03 +0000 (UTC) +Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.128.48 +ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; + t=1728678665; cv=none; b=J8DpUX6X+OSIdJ3QI0+3Gsa3xajaPevit3+pG+FtiCUqK3riB/ej7wApCOqELLEy4sgZNRXc7gkPddTzzduxq7uVogIEJjbajjswDm1HEdwbgdath1q0DbwfikIjIUpM4ZhT24bQEo/jtLMDri0aiWSN6HsmmFw7LLg35SvqKtA= +ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; + s=arc-20240116; t=1728678665; c=relaxed/simple; + bh=vVX7/CXVwBuUkY3LwqqoZmbnjuNWo+uG/k7NFKUYv7k=; + h=Message-ID:Date:MIME-Version:To:Cc:From:Subject:Content-Type; b=ii98dgNUhl3y6NvJgM2NhxtkzD8gn2cHO4sHQWU2XmXGQBKp49hlMOgRsHT1vC7dc9DECMI3Z5SZkhTXyjgyEfrQTlybGplpAmprO8RGyDZYXpzfAYu/FOynI23nywrA8BxReZAEBHZPoDFxkzN7/e+etrVD9FKBZzZBd2BvQDU= +ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=WVNzta0J; arc=none smtp.client-ip=209.85.128.48 +Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com +Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com +Authentication-Results: smtp.subspace.kernel.org; + dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="WVNzta0J" +Received: by mail-wm1-f48.google.com with SMTP id 5b1f17b1804b1-42f6bec84b5so22111495e9.1 + for ; Fri, 11 Oct 2024 13:31:03 -0700 (PDT) +DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; + d=gmail.com; s=20230601; t=1728678662; x=1729283462; darn=vger.kernel.org; + h=content-transfer-encoding:subject:from:cc:to:content-language + :user-agent:mime-version:date:message-id:from:to:cc:subject:date + :message-id:reply-to; + bh=XrNhLYtQGPO0E3mXuEnsVbFS0W5qSpYweCCAmuJ0iGE=; + b=WVNzta0JG8y4GhPr/Tn8V1ZgWyYHQuvB0r1cuOmxSu2CPbBGde21JcemVovmUeILcI + QB9/pa3m1yjRT8WERH9HJfJ7tGbsU0yYdaWcE00dGKRh0qjhzgVrayJXTHzg4dhXZZLb + uPw31EkybCiyrZ/Cw37USIwdZXSddk8tIpxi8Cw5sYsymorr3cMOyHGhrKUdmVJeoH29 + DQsr1S+o0N6leVOp/UI4v9JLGN6WqCNh/QT/WDHxLU5NaPN9o5/4flQLaWoWNwdsjWpf + r+R0a3X7rhkwlFz0aR6KX3KypLykxoWmFX3+Y6Q9SEYA2Hv8nLh8JoCjxSEln3kwNSGo + sBBw== +X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; + d=1e100.net; s=20230601; t=1728678662; x=1729283462; + h=content-transfer-encoding:subject:from:cc:to:content-language + :user-agent:mime-version:date:message-id:x-gm-message-state:from:to + :cc:subject:date:message-id:reply-to; + bh=XrNhLYtQGPO0E3mXuEnsVbFS0W5qSpYweCCAmuJ0iGE=; + b=Z7eiDZaQzRZgAawjujfz7T5DPQkIseHOenpOTHo5j0OX8/HrTNUQMGU0SSqGrS0/6u + IdsFVs6GFjjeUXRXjPqG4nBZrk0SXAb2k52J9+aRF+qUP1lGMdLUFR4aUie+so8h6rzM + sL3QHY/3/1xpwq47wAOzs3u+JlrBlhT2X0ULd/5EA5f+K7idMRAQ3cTU2o6ZsBgYvhcr + s7O8IIWQhrDEjU3LDyjxfEC6o9EL/wmyZJu/MJud0W4N4EPymGAFcWKtcSX5BOcd1Lg8 + WhjTJWUxMtUMaKnvaT202oIExBe6ZoOuu/e/P9VPIZEmrDcHj375s7RlxFIOEhbvPoCV + BYVA== +X-Gm-Message-State: AOJu0Yw9Fm6UZ/2XlOigI13YQNWAXNUVBC+yxCOyNVVzhcRQyrqDkA5w + BCAWOYNEYMQulWLC3XMR9O/A61kVxNLcGRPbukPn4vOqaDJ+AsshS7zkiQ== +X-Google-Smtp-Source: AGHT+IE7P5Ra+RBU6KSJDZtiz5Ga0emWMBUIiU8mKEfdD/ujUoUaZVPmXO6au9d+OKptXvKjiKo6UQ== +X-Received: by 2002:a05:600c:350f:b0:42e:d4a2:ce67 with SMTP id 5b1f17b1804b1-4311dee8073mr36094905e9.17.1728678662147; + Fri, 11 Oct 2024 13:31:02 -0700 (PDT) +Received: from [192.168.0.50] ([79.113.150.231]) + by smtp.gmail.com with ESMTPSA id 5b1f17b1804b1-431183062b5sm50274985e9.26.2024.10.11.13.31.00 + (version=TLS1_3 cipher=TLS_AES_128_GCM_SHA256 bits=128/128); + Fri, 11 Oct 2024 13:31:01 -0700 (PDT) +Message-ID: +Date: Fri, 11 Oct 2024 23:31:00 +0300 +Precedence: bulk +X-Mailing-List: linux-wireless@vger.kernel.org +List-Id: +List-Subscribe: +List-Unsubscribe: +MIME-Version: 1.0 +User-Agent: Mozilla Thunderbird +Content-Language: en-US +To: "linux-wireless@vger.kernel.org" +Cc: Ping-Ke Shih +From: Bitterblue Smith +Subject: [PATCH v2 00/22] wifi: rtw88: Add support for RTL8821AU and RTL8812AU +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 7bit + +Patches 1..15 prepare things, patches 16..21 add the new files, +and patch 22 enables their compilation. + +There are five new modules: rtw88_88xxa, which contains shared code, +rtw88_8821a and rtw88_8812a, which contain code specific to each chip, +rtw88_8821au, and rtw88_8812au. + +More device IDs will be added later because they are not my patches +and I assume they won't need (as m)any revisions. 22 patches is already +a lot. + +Also to be added later: USB 3 support for RTL8812AU and RX aggregation +for both chips. + +Compared to v1, the code is split into three modules instead of having +it all in a single one. + +Bitterblue Smith (22): + wifi: rtw88: Add some definitions for RTL8821AU/RTL8812AU + wifi: rtw88: Dump the HW features only for some chips + wifi: rtw88: Allow different C2H RA report sizes + wifi: rtw88: Extend the init table parsing for RTL8812AU + wifi: rtw88: Allow rtw_chip_info.ltecoex_addr to be NULL + wifi: rtw88: Let each driver control the power on/off process + wifi: rtw88: Enable data rate fallback for older chips + wifi: rtw88: Make txagc_remnant_ofdm an array + wifi: rtw88: Support TX page sizes bigger than 128 + wifi: rtw88: Move pwr_track_tbl to struct rtw_rfe_def + wifi: rtw88: usb: Set pkt_info.ls for the reserved page + wifi: rtw88: Detect beacon loss with chips other than 8822c + wifi: rtw88: coex: Support chips without a scoreboard + wifi: rtw88: 8821a: Regularly ask for BT info updates + wifi: rtw88: 8812a: Mitigate beacon loss + wifi: rtw88: Add rtw8812a_table.{c,h} + wifi: rtw88: Add rtw8821a_table.{c,h} + wifi: rtw88: Add rtw88xxa.{c,h} + wifi: rtw88: Add rtw8821a.{c,h} + wifi: rtw88: Add rtw8812a.{c,h} + wifi: rtw88: Add rtw8821au.c and rtw8812au.c + wifi: rtw88: Enable the new RTL8821AU/RTL8812AU drivers + + drivers/net/wireless/realtek/rtw88/Kconfig | 33 + + drivers/net/wireless/realtek/rtw88/Makefile | 15 + + drivers/net/wireless/realtek/rtw88/coex.c | 37 +- + drivers/net/wireless/realtek/rtw88/coex.h | 11 + + drivers/net/wireless/realtek/rtw88/debug.c | 2 +- + drivers/net/wireless/realtek/rtw88/fw.c | 34 +- + drivers/net/wireless/realtek/rtw88/fw.h | 18 +- + drivers/net/wireless/realtek/rtw88/mac.c | 13 +- + drivers/net/wireless/realtek/rtw88/mac.h | 3 + + drivers/net/wireless/realtek/rtw88/main.c | 35 +- + drivers/net/wireless/realtek/rtw88/main.h | 39 +- + drivers/net/wireless/realtek/rtw88/pci.c | 2 +- + drivers/net/wireless/realtek/rtw88/phy.c | 75 +- + drivers/net/wireless/realtek/rtw88/reg.h | 174 + + drivers/net/wireless/realtek/rtw88/rtw8703b.c | 21 +- + drivers/net/wireless/realtek/rtw88/rtw8723d.c | 21 +- + drivers/net/wireless/realtek/rtw88/rtw8723x.c | 3 +- + drivers/net/wireless/realtek/rtw88/rtw8812a.c | 1102 +++++++ + drivers/net/wireless/realtek/rtw88/rtw8812a.h | 10 + + .../wireless/realtek/rtw88/rtw8812a_table.c | 2812 +++++++++++++++++ + .../wireless/realtek/rtw88/rtw8812a_table.h | 26 + + .../net/wireless/realtek/rtw88/rtw8812au.c | 28 + + drivers/net/wireless/realtek/rtw88/rtw8821a.c | 1197 +++++++ + drivers/net/wireless/realtek/rtw88/rtw8821a.h | 10 + + .../wireless/realtek/rtw88/rtw8821a_table.c | 2350 ++++++++++++++ + .../wireless/realtek/rtw88/rtw8821a_table.h | 21 + + .../net/wireless/realtek/rtw88/rtw8821au.c | 28 + + drivers/net/wireless/realtek/rtw88/rtw8821c.c | 22 +- + drivers/net/wireless/realtek/rtw88/rtw8821c.h | 24 - + drivers/net/wireless/realtek/rtw88/rtw8822b.c | 20 +- + drivers/net/wireless/realtek/rtw88/rtw8822b.h | 12 - + drivers/net/wireless/realtek/rtw88/rtw8822c.c | 28 +- + drivers/net/wireless/realtek/rtw88/rtw88xxa.c | 1989 ++++++++++++ + drivers/net/wireless/realtek/rtw88/rtw88xxa.h | 175 + + drivers/net/wireless/realtek/rtw88/sdio.c | 2 +- + drivers/net/wireless/realtek/rtw88/tx.c | 6 +- + drivers/net/wireless/realtek/rtw88/tx.h | 4 +- + drivers/net/wireless/realtek/rtw88/usb.c | 5 +- + 38 files changed, 10272 insertions(+), 135 deletions(-) + create mode 100644 drivers/net/wireless/realtek/rtw88/rtw8812a.c + create mode 100644 drivers/net/wireless/realtek/rtw88/rtw8812a.h + create mode 100644 drivers/net/wireless/realtek/rtw88/rtw8812a_table.c + create mode 100644 drivers/net/wireless/realtek/rtw88/rtw8812a_table.h + create mode 100644 drivers/net/wireless/realtek/rtw88/rtw8812au.c + create mode 100644 drivers/net/wireless/realtek/rtw88/rtw8821a.c + create mode 100644 drivers/net/wireless/realtek/rtw88/rtw8821a.h + create mode 100644 drivers/net/wireless/realtek/rtw88/rtw8821a_table.c + create mode 100644 drivers/net/wireless/realtek/rtw88/rtw8821a_table.h + create mode 100644 drivers/net/wireless/realtek/rtw88/rtw8821au.c + create mode 100644 drivers/net/wireless/realtek/rtw88/rtw88xxa.c + create mode 100644 drivers/net/wireless/realtek/rtw88/rtw88xxa.h + +-- +2.46.0 + + +From mboxrd@z Thu Jan 1 00:00:00 1970 +Received: from mail-wm1-f50.google.com (mail-wm1-f50.google.com [209.85.128.50]) + (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) + (No client certificate requested) + by smtp.subspace.kernel.org (Postfix) with ESMTPS id A6CE41991DB + for ; Fri, 11 Oct 2024 20:44:31 +0000 (UTC) +Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.128.50 +ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; + t=1728679473; cv=none; b=TfstTo02wcv0BBcivfIUkiLygzRd0TPp7MZOvU9qA4PmYj1uVqtk8GXio8eNqrZdkijRnczZy/Kplusk79UE0hvD12TI6FrXvFSWLNQfDM2D8Q6yqF8bUv3BpXjSCh4f7Up90+bVr+cHGGvqcUg8NaWFlVj5FgkSdgnkKIjW/is= +ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; + s=arc-20240116; t=1728679473; c=relaxed/simple; + bh=zMkqOzFN0AzlMf6q+PM9fWJRZqkdQxeI9yezKr0N72U=; + h=Message-ID:Date:MIME-Version:Subject:From:To:Cc:References: + In-Reply-To:Content-Type; b=UGXWdgGh5Eq2rG2n/XzFLaSXopcV5cqL1NeCUF51/vIjhopgMy/a8NF0uRPmJwvPOmc0BcgVwDchr2zOg5jDPmxngrsYPBVXAc2h1F36S1QAD+Jxpxcqh5KQ+Y3nZR9M9vPOeTdX3LImw/s0fGhlpgQKZPQu3GKULZkz7PZ2dDA= +ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=UGvsuUa9; arc=none smtp.client-ip=209.85.128.50 +Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com +Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com +Authentication-Results: smtp.subspace.kernel.org; + dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="UGvsuUa9" +Received: by mail-wm1-f50.google.com with SMTP id 5b1f17b1804b1-4311ac1994dso14943615e9.1 + for ; Fri, 11 Oct 2024 13:44:31 -0700 (PDT) +DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; + d=gmail.com; s=20230601; t=1728679470; x=1729284270; darn=vger.kernel.org; + h=content-transfer-encoding:in-reply-to:content-language:references + :cc:to:from:subject:user-agent:mime-version:date:message-id:from:to + :cc:subject:date:message-id:reply-to; + bh=6fiRozuzIXBG82ud0imjiJaxs/QORhmb+QGmMgySLHQ=; + b=UGvsuUa99kR1AAi90NrvlYLpstHKfQhjDeM+BRQ5yuG3wk55GHAbO19KzwiFI0gUDG + bKdpK0R6XyiIkbpcZPakTatZf6dnyZsufj39PH61hqNpbINFIKeXgaPHW/REwNNdH+HO + uxRD5xsGJvBDSosQuvxlpvYs/iGFi6uw6lOa8DEVXTnVZwnGtBHHHOut8bXm7Y9yNbs2 + DBLjwJ8zqrBdTBmWXsMc8DXYSxLpA8Hua8GBtS7e08QQZrm84t+KMT71vcfThERGR3VV + 4uhcHx3Kiixycp8vn/LmDRiL0ok7iJcejhQa7ZmFBWZuSHd3wwPfu/1CQJjAFU5zLUYr + lB/A== +X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; + d=1e100.net; s=20230601; t=1728679470; x=1729284270; + h=content-transfer-encoding:in-reply-to:content-language:references + :cc:to:from:subject:user-agent:mime-version:date:message-id + :x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; + bh=6fiRozuzIXBG82ud0imjiJaxs/QORhmb+QGmMgySLHQ=; + b=bVEYdEYdYprPRhwoY/vCo576NsaYygX26zpd5DoAkd5HvzRL3UhKjoXkwgsU6GlqTg + LR1Jm96BaShsSYNve1uk27AagtgZ759PvsN2E5LVPHtQoKAnRTgNE525Id3yWuH/C7S3 + jwtjqMJEICRNDNW6TQe5luYaqaO7OUUkR/3b6RlczdaRgCOpeWFwKnS5WcngN4DeG3hi + qd/eAW9oR8vtBczszclbLQN1RlqBzHVdoApAI1aERIYi0XJ76kZSKdTIBVPEJqHobj5X + zB87ew4ud3BCXlq9RjRuZn6WaT+T5jLwr8WQ+y49YXWlgYYTa9CKDjU9WFHr6LkWWaTJ + sh5A== +X-Gm-Message-State: AOJu0YwDlOI9U4ireDTRHwENEATVeO5IVj/9e5bGnueDcEp7PxumkPxc + WY0mNnqcrumD3pjtDMoAObyizZ2Zc+LtZQspbI7RVcLdHwjuDlqRWda+kQ== +X-Google-Smtp-Source: AGHT+IG1LkpfSa59fyq07xPcKLVR59sCHy0y89XJH3UVT8srvDvOHSrC5ak5/g8AtaqXD9RWUMgaeg== +X-Received: by 2002:a05:600c:5248:b0:42c:bae0:f05b with SMTP id 5b1f17b1804b1-4311deae1a9mr33383695e9.1.1728679469679; + Fri, 11 Oct 2024 13:44:29 -0700 (PDT) +Received: from [192.168.0.50] ([79.113.150.231]) + by smtp.gmail.com with ESMTPSA id ffacd0b85a97d-37d4b6a8911sm4689469f8f.14.2024.10.11.13.44.28 + (version=TLS1_3 cipher=TLS_AES_128_GCM_SHA256 bits=128/128); + Fri, 11 Oct 2024 13:44:29 -0700 (PDT) +Message-ID: +Date: Fri, 11 Oct 2024 23:44:26 +0300 +Precedence: bulk +X-Mailing-List: linux-wireless@vger.kernel.org +List-Id: +List-Subscribe: +List-Unsubscribe: +MIME-Version: 1.0 +User-Agent: Mozilla Thunderbird +Subject: [PATCH v2 01/22] wifi: rtw88: Add some definitions for + RTL8821AU/RTL8812AU +From: Bitterblue Smith +To: "linux-wireless@vger.kernel.org" +Cc: Ping-Ke Shih +References: +Content-Language: en-US +In-Reply-To: +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 7bit + +Add 8821A and 8812A chip type enums. + +Add cck_high_power member to struct rtw_hal. This will be used to +calculate the RX signal strength of RTL8812AU. + +Add various register definitions which will be used by the new drivers. + +Move some existing register definitions from rtw8821c.h and rtw8822b.h. +They were duplicated in those headers and will also be used by the new +drivers. + +Signed-off-by: Bitterblue Smith +--- +v2: + - Add register definitions. + - Move some common definitions from rtw8821c.h and rtw8822b.h. +--- + drivers/net/wireless/realtek/rtw88/main.h | 3 + + drivers/net/wireless/realtek/rtw88/reg.h | 174 ++++++++++++++++++ + drivers/net/wireless/realtek/rtw88/rtw8821c.h | 24 --- + drivers/net/wireless/realtek/rtw88/rtw8822b.h | 12 -- + 4 files changed, 177 insertions(+), 36 deletions(-) + +diff --git a/drivers/net/wireless/realtek/rtw88/main.h b/drivers/net/wireless/realtek/rtw88/main.h +index 05cfb235f272..a2bef559cfb8 100644 +--- a/drivers/net/wireless/realtek/rtw88/main.h ++++ b/drivers/net/wireless/realtek/rtw88/main.h +@@ -189,6 +189,8 @@ enum rtw_chip_type { + RTW_CHIP_TYPE_8723D, + RTW_CHIP_TYPE_8821C, + RTW_CHIP_TYPE_8703B, ++ RTW_CHIP_TYPE_8821A, ++ RTW_CHIP_TYPE_8812A, + }; + + enum rtw_tx_queue_type { +@@ -1934,6 +1936,7 @@ struct rtw_hal { + u32 antenna_rx; + u8 bfee_sts_cap; + bool txrx_1ss; ++ bool cck_high_power; + + /* protect tx power section */ + struct mutex tx_power_mutex; +diff --git a/drivers/net/wireless/realtek/rtw88/reg.h b/drivers/net/wireless/realtek/rtw88/reg.h +index 4d9b8668e8b0..e4d506cf9c33 100644 +--- a/drivers/net/wireless/realtek/rtw88/reg.h ++++ b/drivers/net/wireless/realtek/rtw88/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/drivers/net/wireless/realtek/rtw88/rtw8821c.h b/drivers/net/wireless/realtek/rtw88/rtw8821c.h +index 91ed921407bb..7a33ebd612ed 100644 +--- a/drivers/net/wireless/realtek/rtw88/rtw8821c.h ++++ b/drivers/net/wireless/realtek/rtw88/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/drivers/net/wireless/realtek/rtw88/rtw8822b.h b/drivers/net/wireless/realtek/rtw88/rtw8822b.h +index cf85e63966a1..0514958fb57c 100644 +--- a/drivers/net/wireless/realtek/rtw88/rtw8822b.h ++++ b/drivers/net/wireless/realtek/rtw88/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 + +-- +2.46.0 + + +From mboxrd@z Thu Jan 1 00:00:00 1970 +Received: from mail-wm1-f45.google.com (mail-wm1-f45.google.com [209.85.128.45]) + (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) + (No client certificate requested) + by smtp.subspace.kernel.org (Postfix) with ESMTPS id F3C61198850 + for ; Fri, 11 Oct 2024 20:45:37 +0000 (UTC) +Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.128.45 +ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; + t=1728679539; cv=none; b=jLOM+E+qf8hEiBjQ/iWuS4GuA4cLIY1wW481k9osw8jdCSwstcF5LkEtKX5oA9K1kJBPbHFZcCRGXR5hg30BQ1MTHQiDVvfudYEQrr68Kr80wWf71tdUX5TFXZkd+GFnLh0K/IBlMbLwSN471kVBSZTDMWQLCk+J6VrU7CZxs9M= +ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; + s=arc-20240116; t=1728679539; c=relaxed/simple; + bh=hydkE4cokygQbWTW3MfiVswcoo7uY41ll4Lkq1t1ItY=; + h=Message-ID:Date:MIME-Version:Subject:From:To:Cc:References: + In-Reply-To:Content-Type; b=LlPxSVOwBTGCTwGa3xIpZxuZsWUfyqsQlCkkt2hQXdPzsS4nAMeldHAAgk8CDfIrcmx4fc0Ana4cX/8lpTo1akv5x3Y2XlF/ZZFN7JffRSD/sI9j/8CiW8LMxPq+uJ7XQWFP5J9mHTgx1YIVnsyHLV9q3wRaVgWDwRzVqRmbcy4= +ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=l0QEIi88; arc=none smtp.client-ip=209.85.128.45 +Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com +Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com +Authentication-Results: smtp.subspace.kernel.org; + dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="l0QEIi88" +Received: by mail-wm1-f45.google.com with SMTP id 5b1f17b1804b1-43055b43604so22107225e9.3 + for ; Fri, 11 Oct 2024 13:45:37 -0700 (PDT) +DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; + d=gmail.com; s=20230601; t=1728679536; x=1729284336; darn=vger.kernel.org; + h=content-transfer-encoding:in-reply-to:content-language:references + :cc:to:from:subject:user-agent:mime-version:date:message-id:from:to + :cc:subject:date:message-id:reply-to; + bh=JTLdt4BxksjHi8NKFiwPHAaByB092+AM07DTNccjOQU=; + b=l0QEIi88SK2EQI6Kv6m0i3wr/XVs6ayZeSk32oukD1keQRvbDj+58x11TVkztozzSl + r+fWCNbzfOqk4Z+9ZrPcfaAaYLch4JobOvQXwld/Fwp4iomQ+lQqY1hpEAeV3ESasiH0 + sZ7co2vuZvP8lkBPYpn1x7L5A+QN7mZh6BhfVLvOozHFT8renFuawaCh+G/LYqhX3Rau + +LA+EObi3v6V3dQGYusfRh77yHzk+Jc60OJYFOVUa8HGBwtvy9LMaArjRFvctuykQMqC + 4pLOFzFLyy8AyjlZXicScBWqPO2tslSX4zXsHKy+7YOEsJG/3pvQ9vfRYf0+HVcTekDt + kxRw== +X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; + d=1e100.net; s=20230601; t=1728679536; x=1729284336; + h=content-transfer-encoding:in-reply-to:content-language:references + :cc:to:from:subject:user-agent:mime-version:date:message-id + :x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; + bh=JTLdt4BxksjHi8NKFiwPHAaByB092+AM07DTNccjOQU=; + b=l2b19vXmh9dTCBABpidUee3ap9iNIhecvEuo9NqP7u8ETGCm4L+DmD0KqnjMkHugGx + bSRzrnGn9P+GhwzVBHy23WKNqnko0H2Jrge9act0+FwlgYgwwPksVNVUW/hEQmsNcW3p + b/2vy+FnwhXe4q5eLuuwP4jx5x157xNAROhFidOCajExwXpRNEwE8OiGwAcqRFCYpHuH + qWXqwAPEglMwhEq9ra0XcYDIQie8XZbXj90b0ZYY4JpE87UgiT22tu5+Jnoz8ztYgTHf + pxx2AZ6tuOmuCTX2W35dQfThgmoh4FZt8vNV190jVB02x+IXA6aN8CwcBYeWhIIVckth + GjzQ== +X-Gm-Message-State: AOJu0YzTu4Fwj/LeukOQD9rOrqZh5dVEOT8e573QCt5tBbv5p9ilcZta + 3cRpFhXbsxdR5p0LSmqzCnS+Szcmgo67IaNBjDuHeCotfvNZNmQLM1tkeA== +X-Google-Smtp-Source: AGHT+IGjgVGDwb7YREdQLWJrGU4N683mJD0kZbO+LFjgQIHZmkQ8ThYSvmmt2WSw7NtPkyjekLS+Bw== +X-Received: by 2002:a05:600c:3ba9:b0:42c:b6e4:e3aa with SMTP id 5b1f17b1804b1-4311deae9ccmr36410375e9.5.1728679536211; + Fri, 11 Oct 2024 13:45:36 -0700 (PDT) +Received: from [192.168.0.50] ([79.113.150.231]) + by smtp.gmail.com with ESMTPSA id ffacd0b85a97d-37d4b6a881bsm4723272f8f.16.2024.10.11.13.45.35 + (version=TLS1_3 cipher=TLS_AES_128_GCM_SHA256 bits=128/128); + Fri, 11 Oct 2024 13:45:35 -0700 (PDT) +Message-ID: <709c69ad-d272-4738-a443-cf57e54841ee@gmail.com> +Date: Fri, 11 Oct 2024 23:45:34 +0300 +Precedence: bulk +X-Mailing-List: linux-wireless@vger.kernel.org +List-Id: +List-Subscribe: +List-Unsubscribe: +MIME-Version: 1.0 +User-Agent: Mozilla Thunderbird +Subject: [PATCH v2 02/22] wifi: rtw88: Dump the HW features only for some + chips +From: Bitterblue Smith +To: "linux-wireless@vger.kernel.org" +Cc: Ping-Ke Shih +References: +Content-Language: en-US +In-Reply-To: +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 7bit + +RTL8821AU and RTL8812AU don't support this. They hit the "failed to read +hw feature report" error. + +Signed-off-by: Bitterblue Smith +--- + v2: + - Return instead of printing hw_cap. +--- + drivers/net/wireless/realtek/rtw88/main.c | 3 +++ + drivers/net/wireless/realtek/rtw88/main.h | 1 + + drivers/net/wireless/realtek/rtw88/rtw8703b.c | 1 + + drivers/net/wireless/realtek/rtw88/rtw8723d.c | 1 + + drivers/net/wireless/realtek/rtw88/rtw8821c.c | 1 + + drivers/net/wireless/realtek/rtw88/rtw8822b.c | 1 + + drivers/net/wireless/realtek/rtw88/rtw8822c.c | 1 + + 7 files changed, 9 insertions(+) + +diff --git a/drivers/net/wireless/realtek/rtw88/main.c b/drivers/net/wireless/realtek/rtw88/main.c +index bbdef38c7e34..942266324ca4 100644 +--- a/drivers/net/wireless/realtek/rtw88/main.c ++++ b/drivers/net/wireless/realtek/rtw88/main.c +@@ -1917,6 +1917,9 @@ static int rtw_dump_hw_feature(struct rtw_dev *rtwdev) + u8 bw; + int i; + ++ if (!rtwdev->chip->hw_feature_report) ++ return 0; ++ + id = rtw_read8(rtwdev, REG_C2HEVT); + if (id != C2H_HW_FEATURE_REPORT) { + rtw_err(rtwdev, "failed to read hw feature report\n"); +diff --git a/drivers/net/wireless/realtek/rtw88/main.h b/drivers/net/wireless/realtek/rtw88/main.h +index a2bef559cfb8..58c7c6a178a8 100644 +--- a/drivers/net/wireless/realtek/rtw88/main.h ++++ b/drivers/net/wireless/realtek/rtw88/main.h +@@ -1200,6 +1200,7 @@ struct rtw_chip_info { + const struct rtw_fwcd_segs *fwcd_segs; + + u8 usb_tx_agg_desc_num; ++ bool hw_feature_report; + + u8 default_1ss_tx_path; + +diff --git a/drivers/net/wireless/realtek/rtw88/rtw8703b.c b/drivers/net/wireless/realtek/rtw88/rtw8703b.c +index 77399b8dd8cd..01ac07ac68c8 100644 +--- a/drivers/net/wireless/realtek/rtw88/rtw8703b.c ++++ b/drivers/net/wireless/realtek/rtw88/rtw8703b.c +@@ -1960,6 +1960,7 @@ const struct rtw_chip_info rtw8703b_hw_spec = { + .max_power_index = 0x3f, + .ampdu_density = IEEE80211_HT_MPDU_DENSITY_16, + .usb_tx_agg_desc_num = 1, /* Not sure if this chip has USB interface */ ++ .hw_feature_report = true, + + .path_div_supported = false, + .ht_supported = true, +diff --git a/drivers/net/wireless/realtek/rtw88/rtw8723d.c b/drivers/net/wireless/realtek/rtw88/rtw8723d.c +index 86a5e2497641..bf87c92087da 100644 +--- a/drivers/net/wireless/realtek/rtw88/rtw8723d.c ++++ b/drivers/net/wireless/realtek/rtw88/rtw8723d.c +@@ -2131,6 +2131,7 @@ const struct rtw_chip_info rtw8723d_hw_spec = { + .page_size = TX_PAGE_SIZE, + .dig_min = 0x20, + .usb_tx_agg_desc_num = 1, ++ .hw_feature_report = true, + .ht_supported = true, + .vht_supported = false, + .lps_deep_mode_supported = 0, +diff --git a/drivers/net/wireless/realtek/rtw88/rtw8821c.c b/drivers/net/wireless/realtek/rtw88/rtw8821c.c +index 66c79956e8e5..44ef2e246724 100644 +--- a/drivers/net/wireless/realtek/rtw88/rtw8821c.c ++++ b/drivers/net/wireless/realtek/rtw88/rtw8821c.c +@@ -1968,6 +1968,7 @@ const struct rtw_chip_info rtw8821c_hw_spec = { + .page_size = TX_PAGE_SIZE, + .dig_min = 0x1c, + .usb_tx_agg_desc_num = 3, ++ .hw_feature_report = true, + .ht_supported = true, + .vht_supported = true, + .lps_deep_mode_supported = BIT(LPS_DEEP_MODE_LCLK), +diff --git a/drivers/net/wireless/realtek/rtw88/rtw8822b.c b/drivers/net/wireless/realtek/rtw88/rtw8822b.c +index 24f76a36f23e..9b7c383f37fe 100644 +--- a/drivers/net/wireless/realtek/rtw88/rtw8822b.c ++++ b/drivers/net/wireless/realtek/rtw88/rtw8822b.c +@@ -2509,6 +2509,7 @@ const struct rtw_chip_info rtw8822b_hw_spec = { + .page_size = TX_PAGE_SIZE, + .dig_min = 0x1c, + .usb_tx_agg_desc_num = 3, ++ .hw_feature_report = true, + .ht_supported = true, + .vht_supported = true, + .lps_deep_mode_supported = BIT(LPS_DEEP_MODE_LCLK), +diff --git a/drivers/net/wireless/realtek/rtw88/rtw8822c.c b/drivers/net/wireless/realtek/rtw88/rtw8822c.c +index da74e66bda84..063c65c269fe 100644 +--- a/drivers/net/wireless/realtek/rtw88/rtw8822c.c ++++ b/drivers/net/wireless/realtek/rtw88/rtw8822c.c +@@ -5329,6 +5329,7 @@ const struct rtw_chip_info rtw8822c_hw_spec = { + .page_size = TX_PAGE_SIZE, + .dig_min = 0x20, + .usb_tx_agg_desc_num = 3, ++ .hw_feature_report = true, + .default_1ss_tx_path = BB_PATH_A, + .path_div_supported = true, + .ht_supported = true, +-- +2.46.0 + + +From mboxrd@z Thu Jan 1 00:00:00 1970 +Received: from mail-wm1-f54.google.com (mail-wm1-f54.google.com [209.85.128.54]) + (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) + (No client certificate requested) + by smtp.subspace.kernel.org (Postfix) with ESMTPS id 6525B1D150D + for ; Fri, 11 Oct 2024 20:47:16 +0000 (UTC) +Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.128.54 +ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; + t=1728679638; cv=none; b=FgH5LmWLNZa1i1+ILRxg38Ee2CYAkYDWguVphMM0TVqR9mb51DO+wtZhS1/RIQVQ/C7/WJafyk1c/et70VtwrzGj48IS+VJPr/o2WN9pMCUKMvGvEl3j+qwjktLyQHdgGaBrwetqG2rPLH2Yl8JppfNWgOhXMokYt6UrEEzG9KM= +ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; + s=arc-20240116; t=1728679638; c=relaxed/simple; + bh=F92qKwvqZOuuBUoSUxYtgmTQdG2AEnSkkN47wv9wto0=; + h=Message-ID:Date:MIME-Version:Subject:From:To:Cc:References: + In-Reply-To:Content-Type; b=utVJn3geFogW7cPhrCyKC+ecKhW/aROiSOXM5QMElcKZEBwGdWIMiaHBkDDIT0T5TKu7kgXH8iolcVudvS3zYkKcWqmNrZuy4JThHSpMlfa61B4PRwZpRCgtRxBKUrgYdgi4VkMsVdEe2TR0TLZ0K065NB7MGB49CckZC91ADtE= +ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=JE2Bxk2K; arc=none smtp.client-ip=209.85.128.54 +Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com +Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com +Authentication-Results: smtp.subspace.kernel.org; + dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="JE2Bxk2K" +Received: by mail-wm1-f54.google.com with SMTP id 5b1f17b1804b1-4305724c12eso17727935e9.1 + for ; Fri, 11 Oct 2024 13:47:16 -0700 (PDT) +DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; + d=gmail.com; s=20230601; t=1728679635; x=1729284435; darn=vger.kernel.org; + h=content-transfer-encoding:in-reply-to:content-language:references + :cc:to:from:subject:user-agent:mime-version:date:message-id:from:to + :cc:subject:date:message-id:reply-to; + bh=ahf0ozfYo3EHA4be3vBc5t8WrWCZxRHi+3687Xn9lMQ=; + b=JE2Bxk2KFGa/xJeogh3fNuzNW/PD8d55XjvVvruRkTALNufpcPiP+lDvkp2dgPOvGS + zAI9V9uOyl3+uzcnBey3aiVZMzHn/allh86K0Gpn2OIHmw4kWlgQxwkIreFmrZcMEzGz + CvFW2nYV+Uo1/0XnVuLFvz9247mlxuY5c05XzGnaYA91NaQi3z/Py38kQ5+t1MN0PsLO + aIuBxJBqUJkR9paJa9Xo+0/qfjYHS5o5MNUChXDAn9OV9FJklN61GLhxaksReUE7qMGo + UfJWgY4sibUqq6NeSRDFUHPFq6VKJ/EuqMozf+xSMSK/2t6YcmA38iPg6Bu3U4aMoDBD + NYvQ== +X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; + d=1e100.net; s=20230601; t=1728679635; x=1729284435; + h=content-transfer-encoding:in-reply-to:content-language:references + :cc:to:from:subject:user-agent:mime-version:date:message-id + :x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; + bh=ahf0ozfYo3EHA4be3vBc5t8WrWCZxRHi+3687Xn9lMQ=; + b=xBFo7qo56Rv1DUKMK2zEZui07VRWK+R6x/o93Qf2Qz9U13w0U5wt7uk3dXb2PP+Gug + vjIL/ps8nch7My6Xakj4vPhisafMu3Pqy4wgr/0IuZj+7sjKbhUesr3aywjRu70nYXlM + GOUSPL2KsY3DoLC6glvm02IV0Zzp8JuG5OCWP/HSTEKeEf36nt3Q4fjYNps/eWFqZ8YA + HBWK9/195fU+TzyTy4fxatq+rcuqIl/P8hwOkcKAKB6Dl0NndC0BZmKyc5CT4k8Avv1Z + josSYPb8P7tXoDVc0/OIMFfoX9FrDcRMAnxuGLY2Gz9wwqdOZnFDPsZaHiRsUL7tAEra + 15Ug== +X-Gm-Message-State: AOJu0YyRCNh3lmdb64yoPlPrDooFNHib3KxZ9+/gLds+55KpTdd+v4Qs + QUiEZHs9qJTXtk+HuFnzcEN+FIenxLXrJkin7S1VwsTowHT6RLPs72DspQ== +X-Google-Smtp-Source: AGHT+IHQdTtulLfe1iUFcZEHz75uvspLJfu33+PcXGwaCpkyuyAZFa3owG+A/xbL1lpBZhvTQyu1UQ== +X-Received: by 2002:a05:600c:1c9d:b0:430:57f1:d6d with SMTP id 5b1f17b1804b1-431255d5099mr5227945e9.1.1728679634423; + Fri, 11 Oct 2024 13:47:14 -0700 (PDT) +Received: from [192.168.0.50] ([79.113.150.231]) + by smtp.gmail.com with ESMTPSA id 5b1f17b1804b1-431182ff785sm50581675e9.13.2024.10.11.13.47.13 + (version=TLS1_3 cipher=TLS_AES_128_GCM_SHA256 bits=128/128); + Fri, 11 Oct 2024 13:47:14 -0700 (PDT) +Message-ID: <9bbe0502-dabb-4a95-b201-505dfc9ab688@gmail.com> +Date: Fri, 11 Oct 2024 23:47:13 +0300 +Precedence: bulk +X-Mailing-List: linux-wireless@vger.kernel.org +List-Id: +List-Subscribe: +List-Unsubscribe: +MIME-Version: 1.0 +User-Agent: Mozilla Thunderbird +Subject: [PATCH v2 03/22] wifi: rtw88: Allow different C2H RA report sizes +From: Bitterblue Smith +To: "linux-wireless@vger.kernel.org" +Cc: Ping-Ke Shih +References: +Content-Language: en-US +In-Reply-To: +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 7bit + +The RTL8821AU and RTL8812AU have smaller RA report size, only 4 bytes. +Avoid the "invalid ra report c2h length" error. + +Signed-off-by: Bitterblue Smith +--- +v2: + - Use a struct and u8_get_bits() to access the RA report C2H. + - Use offsetofend, a solution already accepted in rtl8xxxu. +--- + drivers/net/wireless/realtek/rtw88/fw.c | 21 +++++++++++++------ + drivers/net/wireless/realtek/rtw88/fw.h | 18 ++++++++++++---- + drivers/net/wireless/realtek/rtw88/main.h | 1 + + drivers/net/wireless/realtek/rtw88/rtw8703b.c | 1 + + drivers/net/wireless/realtek/rtw88/rtw8723d.c | 1 + + drivers/net/wireless/realtek/rtw88/rtw8821c.c | 1 + + drivers/net/wireless/realtek/rtw88/rtw8822b.c | 1 + + drivers/net/wireless/realtek/rtw88/rtw8822c.c | 1 + + 8 files changed, 35 insertions(+), 10 deletions(-) + +diff --git a/drivers/net/wireless/realtek/rtw88/fw.c b/drivers/net/wireless/realtek/rtw88/fw.c +index 813c12148819..168e19187ba7 100644 +--- a/drivers/net/wireless/realtek/rtw88/fw.c ++++ b/drivers/net/wireless/realtek/rtw88/fw.c +@@ -139,25 +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); +- bw = GET_RA_REPORT_BW(ra_data->payload); ++ 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 = si->bw_mode; + + if (rate < DESC_RATEMCS0) { + si->ra_report.txrate.legacy = rtw_desc_to_bitrate(rate); +@@ -197,14 +202,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 < 7, "invalid ra report c2h length\n")) ++ 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/drivers/net/wireless/realtek/rtw88/fw.h b/drivers/net/wireless/realtek/rtw88/fw.h +index e999c24e4634..d0971d774948 100644 +--- a/drivers/net/wireless/realtek/rtw88/fw.h ++++ b/drivers/net/wireless/realtek/rtw88/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/drivers/net/wireless/realtek/rtw88/main.h b/drivers/net/wireless/realtek/rtw88/main.h +index 58c7c6a178a8..6161db5fcba6 100644 +--- a/drivers/net/wireless/realtek/rtw88/main.h ++++ b/drivers/net/wireless/realtek/rtw88/main.h +@@ -1201,6 +1201,7 @@ struct rtw_chip_info { + + u8 usb_tx_agg_desc_num; + bool hw_feature_report; ++ u8 c2h_ra_report_size; + + u8 default_1ss_tx_path; + +diff --git a/drivers/net/wireless/realtek/rtw88/rtw8703b.c b/drivers/net/wireless/realtek/rtw88/rtw8703b.c +index 01ac07ac68c8..23125a62e74f 100644 +--- a/drivers/net/wireless/realtek/rtw88/rtw8703b.c ++++ b/drivers/net/wireless/realtek/rtw88/rtw8703b.c +@@ -1961,6 +1961,7 @@ const struct rtw_chip_info rtw8703b_hw_spec = { + .ampdu_density = IEEE80211_HT_MPDU_DENSITY_16, + .usb_tx_agg_desc_num = 1, /* Not sure if this chip has USB interface */ + .hw_feature_report = true, ++ .c2h_ra_report_size = 7, + + .path_div_supported = false, + .ht_supported = true, +diff --git a/drivers/net/wireless/realtek/rtw88/rtw8723d.c b/drivers/net/wireless/realtek/rtw88/rtw8723d.c +index bf87c92087da..6a9115775faf 100644 +--- a/drivers/net/wireless/realtek/rtw88/rtw8723d.c ++++ b/drivers/net/wireless/realtek/rtw88/rtw8723d.c +@@ -2132,6 +2132,7 @@ const struct rtw_chip_info rtw8723d_hw_spec = { + .dig_min = 0x20, + .usb_tx_agg_desc_num = 1, + .hw_feature_report = true, ++ .c2h_ra_report_size = 7, + .ht_supported = true, + .vht_supported = false, + .lps_deep_mode_supported = 0, +diff --git a/drivers/net/wireless/realtek/rtw88/rtw8821c.c b/drivers/net/wireless/realtek/rtw88/rtw8821c.c +index 44ef2e246724..6cb7e9aaa437 100644 +--- a/drivers/net/wireless/realtek/rtw88/rtw8821c.c ++++ b/drivers/net/wireless/realtek/rtw88/rtw8821c.c +@@ -1969,6 +1969,7 @@ const struct rtw_chip_info rtw8821c_hw_spec = { + .dig_min = 0x1c, + .usb_tx_agg_desc_num = 3, + .hw_feature_report = true, ++ .c2h_ra_report_size = 7, + .ht_supported = true, + .vht_supported = true, + .lps_deep_mode_supported = BIT(LPS_DEEP_MODE_LCLK), +diff --git a/drivers/net/wireless/realtek/rtw88/rtw8822b.c b/drivers/net/wireless/realtek/rtw88/rtw8822b.c +index 9b7c383f37fe..48aefe3722ec 100644 +--- a/drivers/net/wireless/realtek/rtw88/rtw8822b.c ++++ b/drivers/net/wireless/realtek/rtw88/rtw8822b.c +@@ -2510,6 +2510,7 @@ const struct rtw_chip_info rtw8822b_hw_spec = { + .dig_min = 0x1c, + .usb_tx_agg_desc_num = 3, + .hw_feature_report = true, ++ .c2h_ra_report_size = 7, + .ht_supported = true, + .vht_supported = true, + .lps_deep_mode_supported = BIT(LPS_DEEP_MODE_LCLK), +diff --git a/drivers/net/wireless/realtek/rtw88/rtw8822c.c b/drivers/net/wireless/realtek/rtw88/rtw8822c.c +index 063c65c269fe..25933a54e863 100644 +--- a/drivers/net/wireless/realtek/rtw88/rtw8822c.c ++++ b/drivers/net/wireless/realtek/rtw88/rtw8822c.c +@@ -5330,6 +5330,7 @@ const struct rtw_chip_info rtw8822c_hw_spec = { + .dig_min = 0x20, + .usb_tx_agg_desc_num = 3, + .hw_feature_report = true, ++ .c2h_ra_report_size = 7, + .default_1ss_tx_path = BB_PATH_A, + .path_div_supported = true, + .ht_supported = true, +-- +2.46.0 + + +From mboxrd@z Thu Jan 1 00:00:00 1970 +Received: from mail-wm1-f44.google.com (mail-wm1-f44.google.com [209.85.128.44]) + (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) + (No client certificate requested) + by smtp.subspace.kernel.org (Postfix) with ESMTPS id 7768E199231 + for ; Fri, 11 Oct 2024 20:48:01 +0000 (UTC) +Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.128.44 +ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; + t=1728679683; cv=none; b=d2PghgVWuGtMCHbf7jSbXW2O+vz1w8+nquqWHWNLw1OJiicm/q4XlHpZGsBGISyhDem5Ti50dZen2HDYU8ryNFjuLOgM7x1n/f2sZF/dj7i8SrVUsflz+M3wsWXd4uX+g0DFt8Vd0UMSPG4R3jr5MfpiuJ5rlg8mZPwVjygmuCM= +ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; + s=arc-20240116; t=1728679683; c=relaxed/simple; + bh=jsJ+21SFe18ja5qxJlNAsOmJZ5M3j+/L5i3dWiJ7Zow=; + h=Message-ID:Date:MIME-Version:Subject:From:To:Cc:References: + In-Reply-To:Content-Type; b=np8RbjQJZMk8WCwYLUTZj9RXlxIyjlB/Y0NSNNnTArA64R8+0/w+yxmrpGw8eUxEVaFVQJdMzOExMBUvhJJD6W6he/bk/fM5yk0twEyO7Dtmmx7NiHWRWY7oZltL1G/6II4wFQ1XAup9BRxVFFuwawaFhsBtlZttAwsv5+88zkI= +ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=ggu1o+dS; arc=none smtp.client-ip=209.85.128.44 +Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com +Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com +Authentication-Results: smtp.subspace.kernel.org; + dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="ggu1o+dS" +Received: by mail-wm1-f44.google.com with SMTP id 5b1f17b1804b1-43124843b04so3540525e9.2 + for ; Fri, 11 Oct 2024 13:48:01 -0700 (PDT) +DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; + d=gmail.com; s=20230601; t=1728679680; x=1729284480; darn=vger.kernel.org; + h=content-transfer-encoding:in-reply-to:content-language:references + :cc:to:from:subject:user-agent:mime-version:date:message-id:from:to + :cc:subject:date:message-id:reply-to; + bh=FzAtkfQs3Nt7HFrIuM4sG6958ejpbG9Udaxil4BShcM=; + b=ggu1o+dS0ARFpmDx+3AZwMGTig6HeuJbdFXyVoxcpK5W7Md4HlWIr5baW3dju+ksUU + wmgt/Ec0wIMpjqKHtjkxHx5PGhUNBb17bpdgwZVX3/3+WROwtEvada1FDVIUMn40VgOm + ZL9NMKo6aZc+lzmxjGPtEWXmz8dHbn1aVeUHv5S1yUwSytfYHD+3rcs5kPLfFzPn4hXS + bHPvlHYxIUkSbn2kZGjTRstsexn5XqMZPqQaHeOKgWruEolzzccslPOUAWq18xVSVDsy + 9Zbjqtv0N2aVFvlW/afg+9Atoewg+ZoGPsZSGRFluS9PkMgX1EiEwn2CrlGbxOmR/g/o + Lyqw== +X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; + d=1e100.net; s=20230601; t=1728679680; x=1729284480; + h=content-transfer-encoding:in-reply-to:content-language:references + :cc:to:from:subject:user-agent:mime-version:date:message-id + :x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; + bh=FzAtkfQs3Nt7HFrIuM4sG6958ejpbG9Udaxil4BShcM=; + b=VDAUBhS9A2NLq3wThi/SnHFirqhwNQZMwWX/a6TTk6hZ2Cgq12P7s2JXRDNx3NEEJs + GqRfbj+iHRkxZ1mwKPBow+lDafV5RzYOnjWTM/KrZrTUoQ8X1dxbn4Y8vya/RZmdaun9 + NCAD2yHRkj6UqyD7uO5Or5vQUY47J/i4l+myXKJ2zzL72q/dG+mVTjDwybbBtyw7Fl49 + CVQqPDwp7USDkgRGYNR0un/qZY9sPL2ZrfwFUPk8Y0HAdXi5UPu/bEMzfvKG6woANYLt + ZhGN/eXsMZC+QDomncC5LahxDXVak7ZaSjnS/0pTbdf8HEXbsnfndgwlgMcXkBocUJJf + L0UA== +X-Gm-Message-State: AOJu0YycGfGAAqA/7lDveeNF1wB/VozOjSElbLLu9sZgd9nxZ3Gxngjp + rJAtOPxcS+1Ckj9Uuf61R1uNkn0onwHd9omCsYbclaOGAb9qs0C0HuHIDA== +X-Google-Smtp-Source: AGHT+IHUqgRelhBEdi6XXZfAam8neVN7MlnGOlzZNQ41/aw4L/eD5k8kcn7in7TsoqeuyKTVlYNZsw== +X-Received: by 2002:a05:600c:4507:b0:42c:ac9f:b505 with SMTP id 5b1f17b1804b1-4311df56c63mr30032295e9.31.1728679679694; + Fri, 11 Oct 2024 13:47:59 -0700 (PDT) +Received: from [192.168.0.50] ([79.113.150.231]) + by smtp.gmail.com with ESMTPSA id 5b1f17b1804b1-431182ffc75sm50291605e9.17.2024.10.11.13.47.58 + (version=TLS1_3 cipher=TLS_AES_128_GCM_SHA256 bits=128/128); + Fri, 11 Oct 2024 13:47:58 -0700 (PDT) +Message-ID: <25058b20-8001-4ebd-bd9b-932dff9710d0@gmail.com> +Date: Fri, 11 Oct 2024 23:47:57 +0300 +Precedence: bulk +X-Mailing-List: linux-wireless@vger.kernel.org +List-Id: +List-Subscribe: +List-Unsubscribe: +MIME-Version: 1.0 +User-Agent: Mozilla Thunderbird +Subject: [PATCH v2 04/22] wifi: rtw88: Extend the init table parsing for + RTL8812AU +From: Bitterblue Smith +To: "linux-wireless@vger.kernel.org" +Cc: Ping-Ke Shih +References: +Content-Language: en-US +In-Reply-To: +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 7bit + +The chips supported so far only use the first condition, and so the +parsing code ignores the second condition. RTL8812AU's init tables use +the second condition also. Make the parsing code check it. + +Signed-off-by: Bitterblue Smith +--- +v2: + - Initialise structs with {} instead of {0}. +--- + drivers/net/wireless/realtek/rtw88/main.h | 15 ++++++ + drivers/net/wireless/realtek/rtw88/phy.c | 61 ++++++++++++++++++++--- + 2 files changed, 68 insertions(+), 8 deletions(-) + +diff --git a/drivers/net/wireless/realtek/rtw88/main.h b/drivers/net/wireless/realtek/rtw88/main.h +index 6161db5fcba6..297da821704b 100644 +--- a/drivers/net/wireless/realtek/rtw88/main.h ++++ b/drivers/net/wireless/realtek/rtw88/main.h +@@ -1835,6 +1835,20 @@ struct rtw_phy_cond { + #define BRANCH_ENDIF 3 + }; + ++struct rtw_phy_cond2 { ++#ifdef __LITTLE_ENDIAN ++ u8 type_glna; ++ u8 type_gpa; ++ u8 type_alna; ++ u8 type_apa; ++#else ++ u8 type_apa; ++ u8 type_alna; ++ u8 type_gpa; ++ u8 type_glna; ++#endif ++}; ++ + struct rtw_fifo_conf { + /* tx fifo information */ + u16 rsvd_boundary; +@@ -1916,6 +1930,7 @@ struct rtw_hal { + u8 oem_id; + u8 pkg_type; + struct rtw_phy_cond phy_cond; ++ struct rtw_phy_cond2 phy_cond2; + bool rfe_btg; + + u8 ps_mode; +diff --git a/drivers/net/wireless/realtek/rtw88/phy.c b/drivers/net/wireless/realtek/rtw88/phy.c +index d57a2aabd89b..dda212a721ca 100644 +--- a/drivers/net/wireless/realtek/rtw88/phy.c ++++ b/drivers/net/wireless/realtek/rtw88/phy.c +@@ -18,7 +18,10 @@ struct phy_cfg_pair { + }; + + union phy_table_tile { +- struct rtw_phy_cond cond; ++ struct { ++ struct rtw_phy_cond cond; ++ struct rtw_phy_cond2 cond2; ++ } __packed; + struct phy_cfg_pair cfg; + }; + +@@ -1041,7 +1044,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_cond cond = {}; ++ struct rtw_phy_cond2 cond2 = {}; + + cond.cut = hal->cut_version ? hal->cut_version : 15; + cond.pkg = pkg ? pkg : 15; +@@ -1061,15 +1065,34 @@ void rtw_phy_setup_phy_cond(struct rtw_dev *rtwdev, u32 pkg) + break; + } + ++ if (rtwdev->chip->id == RTW_CHIP_TYPE_8812A || ++ rtwdev->chip->id == RTW_CHIP_TYPE_8821A) { ++ cond.rfe = 0; ++ cond.rfe |= efuse->ext_lna_2g; ++ cond.rfe |= efuse->ext_pa_2g << 1; ++ cond.rfe |= efuse->ext_lna_5g << 2; ++ cond.rfe |= efuse->ext_pa_5g << 3; ++ cond.rfe |= efuse->btcoex << 4; ++ ++ cond2.type_alna = efuse->alna_type; ++ cond2.type_glna = efuse->glna_type; ++ cond2.type_apa = efuse->apa_type; ++ cond2.type_gpa = efuse->gpa_type; ++ } ++ + hal->phy_cond = cond; ++ hal->phy_cond2 = cond2; + +- rtw_dbg(rtwdev, RTW_DBG_PHY, "phy cond=0x%08x\n", *((u32 *)&hal->phy_cond)); ++ rtw_dbg(rtwdev, RTW_DBG_PHY, "phy cond=0x%08x cond2=0x%08x\n", ++ *((u32 *)&hal->phy_cond), *((u32 *)&hal->phy_cond2)); + } + +-static bool check_positive(struct rtw_dev *rtwdev, struct rtw_phy_cond cond) ++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; ++ struct rtw_phy_cond2 drv_cond2 = hal->phy_cond2; + + if (cond.cut && cond.cut != drv_cond.cut) + return false; +@@ -1080,8 +1103,28 @@ static bool check_positive(struct rtw_dev *rtwdev, struct rtw_phy_cond cond) + if (cond.intf && cond.intf != drv_cond.intf) + return false; + +- if (cond.rfe != drv_cond.rfe) +- return false; ++ 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 & BIT(0)) && cond2.type_glna != drv_cond2.type_glna) ++ return false; ++ ++ if ((cond.rfe & BIT(1)) && cond2.type_gpa != drv_cond2.type_gpa) ++ 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; ++ } + + return true; + } +@@ -1090,7 +1133,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_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)); +@@ -1109,11 +1153,12 @@ void rtw_parse_tbl_phy_cond(struct rtw_dev *rtwdev, const struct rtw_table *tbl) + case BRANCH_ELIF: + default: + pos_cond = p->cond; ++ pos_cond2 = p->cond2; + break; + } + } else if (p->cond.neg) { + if (!is_skipped) { +- if (check_positive(rtwdev, pos_cond)) { ++ if (check_positive(rtwdev, pos_cond, pos_cond2)) { + is_matched = true; + is_skipped = true; + } else { +-- +2.46.0 + + +From mboxrd@z Thu Jan 1 00:00:00 1970 +Received: from mail-wm1-f53.google.com (mail-wm1-f53.google.com [209.85.128.53]) + (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) + (No client certificate requested) + by smtp.subspace.kernel.org (Postfix) with ESMTPS id 4834B199231 + for ; Fri, 11 Oct 2024 20:48:34 +0000 (UTC) +Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.128.53 +ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; + t=1728679716; cv=none; b=gZq3FcForsrspEj3to79EDdmtqOFgh2hGkBafoTLoJwxxSNdMx9UEoHmqjASctn6Ld8fgcp6FRl4SVfbUHIR1jTZwuCW08ORqurs/zb1YJ0cT6SaUR08hX8zypHUlq3IrmsaFH9feubsd8Afv8epr24Cr5dZi5n3MxHRavljb3o= +ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; + s=arc-20240116; t=1728679716; c=relaxed/simple; + bh=KuiZSuQw/EKItmGgkfbfeArDeOsG6zsacK1JyEkvGcA=; + h=Message-ID:Date:MIME-Version:Subject:From:To:Cc:References: + In-Reply-To:Content-Type; b=aUTQVCfQUhvE3p3gbRTrpv3NBeK1UIAAtrCotBXC9+FUhhrdp2G96Jioeha8DKrr6YRdiYURd61GXeEOqaekxGkHyJpeu7Rfv5tFjogcbDRhdTWX3Fsvj7xZfx7Ub5rxGeazEqLev9PEzYxEMBgn0KhoZbTT4aVlqglf2/fI6Mc= +ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=BQz4OpXC; arc=none smtp.client-ip=209.85.128.53 +Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com +Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com +Authentication-Results: smtp.subspace.kernel.org; + dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="BQz4OpXC" +Received: by mail-wm1-f53.google.com with SMTP id 5b1f17b1804b1-43118c9a955so17458035e9.3 + for ; Fri, 11 Oct 2024 13:48:34 -0700 (PDT) +DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; + d=gmail.com; s=20230601; t=1728679713; x=1729284513; darn=vger.kernel.org; + h=content-transfer-encoding:in-reply-to:content-language:references + :cc:to:from:subject:user-agent:mime-version:date:message-id:from:to + :cc:subject:date:message-id:reply-to; + bh=tN/yQNtjPjLE8WyClrMj2SdwBcaYVAAqYPfU0KY/CnI=; + b=BQz4OpXCCIKSiFn9USPoAD6jXS0maJNqPmMVE0GRKVwiIS5boIajkK86H9fSGXGd0L + 4Am+ymAZl/PgwUQQU9q+EB+IZoyQlPK61zGceIQehDN/wd1WPr6C02ticl21HodbIzPs + DLBSSp40kJHUX+k/x1oYy1GrTjbQdw4bL3lasP8JfgXOUcQd/9xpytT/6LieNfYX1DcX + VlupSwPeZdaznv3JE3/AyAClAWy48Egs3DHxpjXfF53R6Ce/0ruW64g+M3GEG2CM776i + fR5MkRpPOp+9yZEMb8g7lYL7LS7H7zvR0VWf7dJ1iZ9svJVaEaVT6OIZBZrmafbjyBE7 + puew== +X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; + d=1e100.net; s=20230601; t=1728679713; x=1729284513; + h=content-transfer-encoding:in-reply-to:content-language:references + :cc:to:from:subject:user-agent:mime-version:date:message-id + :x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; + bh=tN/yQNtjPjLE8WyClrMj2SdwBcaYVAAqYPfU0KY/CnI=; + b=J8x6dOxtXsQri8v8Cw9kABLThrun5qXvinGHXPGe+KO0f+j9eD58RntZeeM0EtY849 + Fs7VBO4zI+t08pYqmfWv/vmoHUJf6HKxIMKo7AL5oKEyixteuFlbiaUGhRh2ClzZYvQg + iLTvXW8K7G4NR1GkFIdpO2Vn1YAfCrTiIK11FWKfeu5zT5r9KZPRoIeiKeiOFZJAOjlg + Isu/KErZCINsIthZ8kRwslvBA3v9eEE5E81wg9TUBYuLSZnVCtwrSckNbpY9SrKyWkWm + zPwURe5JpTgOIdj/Vxd0P23qyX0Sbt4KZ9Iyiz8pBphl8rT3jylQJgrX8GyMsq0YR2yC + m0oQ== +X-Gm-Message-State: AOJu0YxQRk24nUNpSBccAlHLW0NDqHT5LmWl106MA6bnblsIiLJlL201 + vStKOlF/GBUZZ2cD20/Dfvg9C/qGAIYdhN22y5zpvP0bJ8bN6V+0jQgMHA== +X-Google-Smtp-Source: AGHT+IF4LA/JfykD6N36n9C9XtoxvUWSFCiOHNfcHGJGTmcb0jRkgGwPuGwCgVDQyRz4pTZHn1aJpA== +X-Received: by 2002:adf:f38b:0:b0:37d:3541:5643 with SMTP id ffacd0b85a97d-37d552cb091mr2473611f8f.51.1728679713260; + Fri, 11 Oct 2024 13:48:33 -0700 (PDT) +Received: from [192.168.0.50] ([79.113.150.231]) + by smtp.gmail.com with ESMTPSA id ffacd0b85a97d-37d4b79fa0asm4709544f8f.83.2024.10.11.13.48.31 + (version=TLS1_3 cipher=TLS_AES_128_GCM_SHA256 bits=128/128); + Fri, 11 Oct 2024 13:48:32 -0700 (PDT) +Message-ID: +Date: Fri, 11 Oct 2024 23:48:31 +0300 +Precedence: bulk +X-Mailing-List: linux-wireless@vger.kernel.org +List-Id: +List-Subscribe: +List-Unsubscribe: +MIME-Version: 1.0 +User-Agent: Mozilla Thunderbird +Subject: [PATCH v2 05/22] wifi: rtw88: Allow rtw_chip_info.ltecoex_addr to be + NULL +From: Bitterblue Smith +To: "linux-wireless@vger.kernel.org" +Cc: Ping-Ke Shih +References: +Content-Language: en-US +In-Reply-To: +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 7bit + +RTL8821A doesn't have this. Trying to use it results in error messages, +so don't try if ltecoex_addr is NULL. + +Signed-off-by: Bitterblue Smith +--- +v2: + - No change. +--- + drivers/net/wireless/realtek/rtw88/coex.c | 14 +++++++++++--- + 1 file changed, 11 insertions(+), 3 deletions(-) + +diff --git a/drivers/net/wireless/realtek/rtw88/coex.c b/drivers/net/wireless/realtek/rtw88/coex.c +index a99776af56c2..13096fa7025c 100644 +--- a/drivers/net/wireless/realtek/rtw88/coex.c ++++ b/drivers/net/wireless/realtek/rtw88/coex.c +@@ -950,12 +950,18 @@ static void rtw_coex_coex_ctrl_owner(struct rtw_dev *rtwdev, bool wifi_control) + + static void rtw_coex_set_gnt_bt(struct rtw_dev *rtwdev, u8 state) + { ++ if (!rtwdev->chip->ltecoex_addr) ++ return; ++ + rtw_coex_write_indirect_reg(rtwdev, LTE_COEX_CTRL, 0xc000, state); + rtw_coex_write_indirect_reg(rtwdev, LTE_COEX_CTRL, 0x0c00, state); + } + + static void rtw_coex_set_gnt_wl(struct rtw_dev *rtwdev, u8 state) + { ++ if (!rtwdev->chip->ltecoex_addr) ++ return; ++ + rtw_coex_write_indirect_reg(rtwdev, LTE_COEX_CTRL, 0x3000, state); + rtw_coex_write_indirect_reg(rtwdev, LTE_COEX_CTRL, 0x0300, state); + } +@@ -3904,7 +3910,7 @@ void rtw_coex_display_coex_info(struct rtw_dev *rtwdev, struct seq_file *m) + u8 sys_lte; + u16 score_board_WB, score_board_BW; + u32 wl_reg_6c0, wl_reg_6c4, wl_reg_6c8, wl_reg_778, wl_reg_6cc; +- u32 lte_coex, bt_coex; ++ u32 lte_coex = 0, bt_coex = 0; + int i; + + score_board_BW = rtw_coex_read_scbd(rtwdev); +@@ -3916,8 +3922,10 @@ void rtw_coex_display_coex_info(struct rtw_dev *rtwdev, struct seq_file *m) + wl_reg_778 = rtw_read8(rtwdev, REG_BT_STAT_CTRL); + + sys_lte = rtw_read8(rtwdev, 0x73); +- lte_coex = rtw_coex_read_indirect_reg(rtwdev, 0x38); +- bt_coex = rtw_coex_read_indirect_reg(rtwdev, 0x54); ++ if (rtwdev->chip->ltecoex_addr) { ++ lte_coex = rtw_coex_read_indirect_reg(rtwdev, 0x38); ++ bt_coex = rtw_coex_read_indirect_reg(rtwdev, 0x54); ++ } + + if (!coex_stat->wl_under_ips && + (!coex_stat->wl_under_lps || coex_stat->wl_force_lps_ctrl) && +-- +2.46.0 + + +From mboxrd@z Thu Jan 1 00:00:00 1970 +Received: from mail-lf1-f45.google.com (mail-lf1-f45.google.com [209.85.167.45]) + (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) + (No client certificate requested) + by smtp.subspace.kernel.org (Postfix) with ESMTPS id E8B31199231 + for ; Fri, 11 Oct 2024 20:49:06 +0000 (UTC) +Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.167.45 +ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; + t=1728679748; cv=none; b=nmkzcW8222KJs1q/hA9GbMDpH4mDR7oaUmFt1EWQrMllY3uk6ltLmV+Lj6+t0MfZOvsxGZ+mvoSCQu7TozmDW3PO09ebfglmODcAOw/SV04d0Z+IvjZxtzlLpDfF+p6sHfsAE37DqUkYkh88qLuCQdksfCfHh0Rc2Xkkrl1SnOo= +ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; + s=arc-20240116; t=1728679748; c=relaxed/simple; + bh=5IZuFdUS8nT4TFD+R78zwIaw/wlSQazyDAs1ibbebfs=; + h=Message-ID:Date:MIME-Version:Subject:From:To:Cc:References: + In-Reply-To:Content-Type; b=YPXeSNOpyXnJ5RTIA03npBtlPzhgPZeH+bHI1YDmcRrKsmi2XMHzh1t6jCvKXOoU1goIEwCMBXfvtBrNZGjf0X5J9e2inFlJMgmfVE0AZmEW0lCfs+sRwldeUJjoZYSw4gvJhT8xEjzl/TMJ68gzqlrOUEiJKQD+/NpC/JOdv2o= +ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=DzRks+wq; arc=none smtp.client-ip=209.85.167.45 +Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com +Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com +Authentication-Results: smtp.subspace.kernel.org; + dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="DzRks+wq" +Received: by mail-lf1-f45.google.com with SMTP id 2adb3069b0e04-5398cc2fcb7so3062791e87.1 + for ; Fri, 11 Oct 2024 13:49:06 -0700 (PDT) +DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; + d=gmail.com; s=20230601; t=1728679745; x=1729284545; darn=vger.kernel.org; + h=content-transfer-encoding:in-reply-to:content-language:references + :cc:to:from:subject:user-agent:mime-version:date:message-id:from:to + :cc:subject:date:message-id:reply-to; + bh=NaXSZna2SQcr7U1lzCdV9egJSJOc6ncq0WP0zM+96aM=; + b=DzRks+wq6JKSyXjOlF1xw97QU/RWSUixQPzO4eKcPuoDcGlJHtKkpezVNw37FdB0bl + +7OMIDhtKKEfYbIpuYYK1H/X9pWDcmOzkmOdKWxkaYZkmqaijCDwc+I49Ka7nGQ7Q/OX + rHgZl28vrxNw1YxNLB89Deo7Vypgjhl9PJgaA7HLKFhF4r91s3mTVFid9XNUr1y7I3Nj + 1WbkwlSZYjgaR8GBG19NCXF0H6POJIIBFuEPnnUAiQIWQ6wah9k7XPBtgk2J7zz8Egbh + QE20t9nQMk72y6Fu9XcHf7jMNoFmDCpMB0wjGGi5VkJkdKpIadM4wWtnx/MzKGTg/7nd + I+zA== +X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; + d=1e100.net; s=20230601; t=1728679745; x=1729284545; + h=content-transfer-encoding:in-reply-to:content-language:references + :cc:to:from:subject:user-agent:mime-version:date:message-id + :x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; + bh=NaXSZna2SQcr7U1lzCdV9egJSJOc6ncq0WP0zM+96aM=; + b=wnkEqBI1ndU8JoZLeSmlaUY7bdVy25sjgT2w3QKkhwoPiDBESDcY0h+8XB4prQO2ZA + dh+CJf36vxxSEauwGN0e6Q5Z5hkRb/Y1d1bW1aqhKAcxgW34zU1ddZ7KE0Qof4S1S50Q + 1O2+jl8XI0KhbGX5AHl1wMdcPyoLJiQ4tSu+GTnLoVi0bEdAgBsIfzIXJmD4iekBnwcv + kfR7eCecFOuonlqlLYq9XB7x4r1F02hldXLDCIzWeGFLZSRNbAdYBbBLLjqqMGXFDdZv + NUhd9EA4k6JtME0f50dG1PzokuCPPzxM8tmhlH7uYfo+502m2gCC1J0e73MgnIzRUaTS + VScA== +X-Gm-Message-State: AOJu0Yw2yIu7bfTfpEhIMBW5MThQmNuNTpbD6QxifrgiTm4vZ9lIVbKz + JIsvAlv84cd7JoP8f/IOj91d/idFIRRtgt/5Gcf5Y3CGSYBlZtJAvwpp9Q== +X-Google-Smtp-Source: AGHT+IE81iGC1mgIF9dFX7LKX8QJgsURB429CacsbVaVUiBs25GlhYRKxEOvvq5oW4pKMIL3A9T9Gg== +X-Received: by 2002:a05:6512:3b06:b0:536:553f:3eed with SMTP id 2adb3069b0e04-539da3c6e5fmr2505553e87.23.1728679744468; + Fri, 11 Oct 2024 13:49:04 -0700 (PDT) +Received: from [192.168.0.50] ([79.113.150.231]) + by smtp.gmail.com with ESMTPSA id ffacd0b85a97d-37d4b6bd382sm4706619f8f.43.2024.10.11.13.49.03 + (version=TLS1_3 cipher=TLS_AES_128_GCM_SHA256 bits=128/128); + Fri, 11 Oct 2024 13:49:04 -0700 (PDT) +Message-ID: +Date: Fri, 11 Oct 2024 23:49:02 +0300 +Precedence: bulk +X-Mailing-List: linux-wireless@vger.kernel.org +List-Id: +List-Subscribe: +List-Unsubscribe: +MIME-Version: 1.0 +User-Agent: Mozilla Thunderbird +Subject: [PATCH v2 06/22] wifi: rtw88: Let each driver control the power + on/off process +From: Bitterblue Smith +To: "linux-wireless@vger.kernel.org" +Cc: Ping-Ke Shih +References: +Content-Language: en-US +In-Reply-To: +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 7bit + +RTL8821AU and RTL8812AU have to do some things differently, so let +them have full control. + +The other chips use the same functions as before. + +Signed-off-by: Bitterblue Smith +--- +v2: + - No change. +--- + drivers/net/wireless/realtek/rtw88/coex.c | 3 +++ + drivers/net/wireless/realtek/rtw88/mac.c | 11 +++++++---- + drivers/net/wireless/realtek/rtw88/mac.h | 3 +++ + drivers/net/wireless/realtek/rtw88/main.c | 13 ++++++++----- + drivers/net/wireless/realtek/rtw88/main.h | 5 +++++ + drivers/net/wireless/realtek/rtw88/rtw8703b.c | 2 ++ + drivers/net/wireless/realtek/rtw88/rtw8723d.c | 2 ++ + drivers/net/wireless/realtek/rtw88/rtw8821c.c | 2 ++ + drivers/net/wireless/realtek/rtw88/rtw8822b.c | 2 ++ + drivers/net/wireless/realtek/rtw88/rtw8822c.c | 2 ++ + 10 files changed, 36 insertions(+), 9 deletions(-) + +diff --git a/drivers/net/wireless/realtek/rtw88/coex.c b/drivers/net/wireless/realtek/rtw88/coex.c +index 13096fa7025c..8c5aec744f3c 100644 +--- a/drivers/net/wireless/realtek/rtw88/coex.c ++++ b/drivers/net/wireless/realtek/rtw88/coex.c +@@ -2753,16 +2753,19 @@ void rtw_coex_power_on_setting(struct rtw_dev *rtwdev) + rtw_write8(rtwdev, 0xff1a, 0x0); + rtw_coex_set_gnt_debug(rtwdev); + } ++EXPORT_SYMBOL(rtw_coex_power_on_setting); + + void rtw_coex_power_off_setting(struct rtw_dev *rtwdev) + { + rtw_write16(rtwdev, REG_WIFI_BT_INFO, BIT_BT_INT_EN); + } ++EXPORT_SYMBOL(rtw_coex_power_off_setting); + + void rtw_coex_init_hw_config(struct rtw_dev *rtwdev, bool wifi_only) + { + __rtw_coex_init_hw_config(rtwdev, wifi_only); + } ++EXPORT_SYMBOL(rtw_coex_init_hw_config); + + void rtw_coex_ips_notify(struct rtw_dev *rtwdev, u8 type) + { +diff --git a/drivers/net/wireless/realtek/rtw88/mac.c b/drivers/net/wireless/realtek/rtw88/mac.c +index e5abcc20b63c..daf23ccf6378 100644 +--- a/drivers/net/wireless/realtek/rtw88/mac.c ++++ b/drivers/net/wireless/realtek/rtw88/mac.c +@@ -227,8 +227,8 @@ static int rtw_sub_pwr_seq_parser(struct rtw_dev *rtwdev, u8 intf_mask, + return 0; + } + +-static int rtw_pwr_seq_parser(struct rtw_dev *rtwdev, +- const struct rtw_pwr_seq_cmd * const *cmd_seq) ++int rtw_pwr_seq_parser(struct rtw_dev *rtwdev, ++ const struct rtw_pwr_seq_cmd * const *cmd_seq) + { + u8 cut_mask; + u8 intf_mask; +@@ -267,6 +267,7 @@ static int rtw_pwr_seq_parser(struct rtw_dev *rtwdev, + + return 0; + } ++EXPORT_SYMBOL(rtw_pwr_seq_parser); + + static int rtw_mac_power_switch(struct rtw_dev *rtwdev, bool pwr_on) + { +@@ -994,6 +995,7 @@ int rtw_download_firmware(struct rtw_dev *rtwdev, struct rtw_fw_state *fw) + + return 0; + } ++EXPORT_SYMBOL(rtw_download_firmware); + + static u32 get_priority_queues(struct rtw_dev *rtwdev, u32 queues) + { +@@ -1127,7 +1129,7 @@ static int txdma_queue_mapping(struct rtw_dev *rtwdev) + return 0; + } + +-static int set_trx_fifo_info(struct rtw_dev *rtwdev) ++int rtw_set_trx_fifo_info(struct rtw_dev *rtwdev) + { + const struct rtw_chip_info *chip = rtwdev->chip; + struct rtw_fifo_conf *fifo = &rtwdev->fifo; +@@ -1179,6 +1181,7 @@ static int set_trx_fifo_info(struct rtw_dev *rtwdev) + + return 0; + } ++EXPORT_SYMBOL(rtw_set_trx_fifo_info); + + static int __priority_queue_cfg(struct rtw_dev *rtwdev, + const struct rtw_page_table *pg_tbl, +@@ -1256,7 +1259,7 @@ static int priority_queue_cfg(struct rtw_dev *rtwdev) + u16 pubq_num; + int ret; + +- ret = set_trx_fifo_info(rtwdev); ++ ret = rtw_set_trx_fifo_info(rtwdev); + if (ret) + return ret; + +diff --git a/drivers/net/wireless/realtek/rtw88/mac.h b/drivers/net/wireless/realtek/rtw88/mac.h +index 58c3dccc14bb..6905e2747372 100644 +--- a/drivers/net/wireless/realtek/rtw88/mac.h ++++ b/drivers/net/wireless/realtek/rtw88/mac.h +@@ -30,11 +30,14 @@ + + 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 * 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); + int rtw_mac_init(struct rtw_dev *rtwdev); + void rtw_mac_flush_queues(struct rtw_dev *rtwdev, u32 queues, bool drop); ++int rtw_set_trx_fifo_info(struct rtw_dev *rtwdev); + int rtw_ddma_to_fw_fifo(struct rtw_dev *rtwdev, u32 ocp_src, u32 size); + + static inline void rtw_mac_flush_all_queues(struct rtw_dev *rtwdev, bool drop) +diff --git a/drivers/net/wireless/realtek/rtw88/main.c b/drivers/net/wireless/realtek/rtw88/main.c +index 942266324ca4..e6f985a92019 100644 +--- a/drivers/net/wireless/realtek/rtw88/main.c ++++ b/drivers/net/wireless/realtek/rtw88/main.c +@@ -1309,7 +1309,7 @@ void rtw_update_sta_info(struct rtw_dev *rtwdev, struct rtw_sta_info *si, + rtw_fw_send_ra_info(rtwdev, si, reset_ra_mask); + } + +-static int rtw_wait_firmware_completion(struct rtw_dev *rtwdev) ++int rtw_wait_firmware_completion(struct rtw_dev *rtwdev) + { + const struct rtw_chip_info *chip = rtwdev->chip; + struct rtw_fw_state *fw; +@@ -1329,6 +1329,7 @@ static int rtw_wait_firmware_completion(struct rtw_dev *rtwdev) + + return ret; + } ++EXPORT_SYMBOL(rtw_wait_firmware_completion); + + static enum rtw_lps_deep_mode rtw_update_lps_deep_mode(struct rtw_dev *rtwdev, + struct rtw_fw_state *fw) +@@ -1350,7 +1351,7 @@ static enum rtw_lps_deep_mode rtw_update_lps_deep_mode(struct rtw_dev *rtwdev, + return LPS_DEEP_MODE_NONE; + } + +-static int rtw_power_on(struct rtw_dev *rtwdev) ++int rtw_power_on(struct rtw_dev *rtwdev) + { + const struct rtw_chip_info *chip = rtwdev->chip; + struct rtw_fw_state *fw = &rtwdev->fw; +@@ -1413,6 +1414,7 @@ static int rtw_power_on(struct rtw_dev *rtwdev) + err: + return ret; + } ++EXPORT_SYMBOL(rtw_power_on); + + void rtw_core_fw_scan_notify(struct rtw_dev *rtwdev, bool start) + { +@@ -1485,7 +1487,7 @@ int rtw_core_start(struct rtw_dev *rtwdev) + { + int ret; + +- ret = rtw_power_on(rtwdev); ++ ret = rtwdev->chip->ops->power_on(rtwdev); + if (ret) + return ret; + +@@ -1505,12 +1507,13 @@ int rtw_core_start(struct rtw_dev *rtwdev) + return 0; + } + +-static void rtw_power_off(struct rtw_dev *rtwdev) ++void rtw_power_off(struct rtw_dev *rtwdev) + { + rtw_hci_stop(rtwdev); + rtw_coex_power_off_setting(rtwdev); + rtw_mac_power_off(rtwdev); + } ++EXPORT_SYMBOL(rtw_power_off); + + void rtw_core_stop(struct rtw_dev *rtwdev) + { +@@ -1535,7 +1538,7 @@ void rtw_core_stop(struct rtw_dev *rtwdev) + + mutex_lock(&rtwdev->mutex); + +- rtw_power_off(rtwdev); ++ rtwdev->chip->ops->power_off(rtwdev); + } + + static void rtw_init_ht_cap(struct rtw_dev *rtwdev, +diff --git a/drivers/net/wireless/realtek/rtw88/main.h b/drivers/net/wireless/realtek/rtw88/main.h +index 297da821704b..af4876327837 100644 +--- a/drivers/net/wireless/realtek/rtw88/main.h ++++ b/drivers/net/wireless/realtek/rtw88/main.h +@@ -843,6 +843,8 @@ struct rtw_regd { + }; + + struct rtw_chip_ops { ++ int (*power_on)(struct rtw_dev *rtwdev); ++ void (*power_off)(struct rtw_dev *rtwdev); + int (*mac_init)(struct rtw_dev *rtwdev); + int (*dump_fw_crash)(struct rtw_dev *rtwdev); + void (*shutdown)(struct rtw_dev *rtwdev); +@@ -2209,6 +2211,7 @@ void rtw_core_scan_start(struct rtw_dev *rtwdev, struct rtw_vif *rtwvif, + void rtw_core_scan_complete(struct rtw_dev *rtwdev, struct ieee80211_vif *vif, + bool hw_scan); + int rtw_core_start(struct rtw_dev *rtwdev); ++void rtw_power_off(struct rtw_dev *rtwdev); + void rtw_core_stop(struct rtw_dev *rtwdev); + int rtw_chip_info_setup(struct rtw_dev *rtwdev); + int rtw_core_init(struct rtw_dev *rtwdev); +@@ -2223,6 +2226,8 @@ int rtw_sta_add(struct rtw_dev *rtwdev, struct ieee80211_sta *sta, + void rtw_sta_remove(struct rtw_dev *rtwdev, struct ieee80211_sta *sta, + bool fw_exist); + void rtw_fw_recovery(struct rtw_dev *rtwdev); ++int rtw_wait_firmware_completion(struct rtw_dev *rtwdev); ++int rtw_power_on(struct rtw_dev *rtwdev); + void rtw_core_fw_scan_notify(struct rtw_dev *rtwdev, bool start); + int rtw_dump_fw(struct rtw_dev *rtwdev, const u32 ocp_src, u32 size, + u32 fwcd_item); +diff --git a/drivers/net/wireless/realtek/rtw88/rtw8703b.c b/drivers/net/wireless/realtek/rtw88/rtw8703b.c +index 23125a62e74f..97dbc77f037a 100644 +--- a/drivers/net/wireless/realtek/rtw88/rtw8703b.c ++++ b/drivers/net/wireless/realtek/rtw88/rtw8703b.c +@@ -1888,6 +1888,8 @@ static const struct coex_tdma_para tdma_sant_8703b[] = { + }; + + static const struct rtw_chip_ops rtw8703b_ops = { ++ .power_on = rtw_power_on, ++ .power_off = rtw_power_off, + .mac_init = rtw8723x_mac_init, + .dump_fw_crash = NULL, + .shutdown = NULL, +diff --git a/drivers/net/wireless/realtek/rtw88/rtw8723d.c b/drivers/net/wireless/realtek/rtw88/rtw8723d.c +index 6a9115775faf..f6a08b06f853 100644 +--- a/drivers/net/wireless/realtek/rtw88/rtw8723d.c ++++ b/drivers/net/wireless/realtek/rtw88/rtw8723d.c +@@ -1390,6 +1390,8 @@ static void rtw8723d_pwr_track(struct rtw_dev *rtwdev) + } + + 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, + .read_efuse = rtw8723x_read_efuse, + .query_phy_status = query_phy_status, +diff --git a/drivers/net/wireless/realtek/rtw88/rtw8821c.c b/drivers/net/wireless/realtek/rtw88/rtw8821c.c +index 6cb7e9aaa437..e17d0193ca6f 100644 +--- a/drivers/net/wireless/realtek/rtw88/rtw8821c.c ++++ b/drivers/net/wireless/realtek/rtw88/rtw8821c.c +@@ -1643,6 +1643,8 @@ static const struct rtw_prioq_addrs prioq_addrs_8821c = { + }; + + 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, + .read_efuse = rtw8821c_read_efuse, + .query_phy_status = query_phy_status, +diff --git a/drivers/net/wireless/realtek/rtw88/rtw8822b.c b/drivers/net/wireless/realtek/rtw88/rtw8822b.c +index 48aefe3722ec..7360ce0a193e 100644 +--- a/drivers/net/wireless/realtek/rtw88/rtw8822b.c ++++ b/drivers/net/wireless/realtek/rtw88/rtw8822b.c +@@ -2132,6 +2132,8 @@ static const struct rtw_prioq_addrs prioq_addrs_8822b = { + }; + + 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, + .read_efuse = rtw8822b_read_efuse, + .query_phy_status = query_phy_status, +diff --git a/drivers/net/wireless/realtek/rtw88/rtw8822c.c b/drivers/net/wireless/realtek/rtw88/rtw8822c.c +index 25933a54e863..17d4d9bddd83 100644 +--- a/drivers/net/wireless/realtek/rtw88/rtw8822c.c ++++ b/drivers/net/wireless/realtek/rtw88/rtw8822c.c +@@ -4947,6 +4947,8 @@ static const struct rtw_prioq_addrs prioq_addrs_8822c = { + }; + + 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, + .read_efuse = rtw8822c_read_efuse, + .query_phy_status = query_phy_status, +-- +2.46.0 + + +From mboxrd@z Thu Jan 1 00:00:00 1970 +Received: from mail-lf1-f49.google.com (mail-lf1-f49.google.com [209.85.167.49]) + (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) + (No client certificate requested) + by smtp.subspace.kernel.org (Postfix) with ESMTPS id C86E5199231 + for ; Fri, 11 Oct 2024 20:49:37 +0000 (UTC) +Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.167.49 +ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; + t=1728679779; cv=none; b=sXImku6KZ1frAAB4WSzcuaqQOJcqI+E1wle6ashJbl/YnNsSY9C3eC6ljDZGD4by8rtEk/IB2jqKIUePD6gVCT5S+UPQmLboBhAmIdyT3Zj746+GqEPHS9fC6bI+xwR1udf2wykWom1tvluMV1K0PFpS1TAJh5pfyeftRvUVpCE= +ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; + s=arc-20240116; t=1728679779; c=relaxed/simple; + bh=ZR1otjwyQcsAiVDZby/9yS02124ZFbvIW8lo6jkmLv0=; + h=Message-ID:Date:MIME-Version:Subject:From:To:Cc:References: + In-Reply-To:Content-Type; b=W4HJNu5YNRsHE5XhDg640Tbnh2eoPrroO3t/GrkFEljdXjkxf415bDY5CHOFgzsNJsdspc1D01Fs+jgXMKhkSRGKiDmpD5eaPCYxvWjjRGiq0WPriiTfNABGaAkS9c1h+gEyZkU0ttR2Xe+3ij08KtR7QUoyFHVgS1DRNd7ol4s= +ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=h5Zqy/5n; arc=none smtp.client-ip=209.85.167.49 +Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com +Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com +Authentication-Results: smtp.subspace.kernel.org; + dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="h5Zqy/5n" +Received: by mail-lf1-f49.google.com with SMTP id 2adb3069b0e04-539e5c15fd3so195919e87.3 + for ; Fri, 11 Oct 2024 13:49:37 -0700 (PDT) +DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; + d=gmail.com; s=20230601; t=1728679776; x=1729284576; darn=vger.kernel.org; + h=content-transfer-encoding:in-reply-to:content-language:references + :cc:to:from:subject:user-agent:mime-version:date:message-id:from:to + :cc:subject:date:message-id:reply-to; + bh=NN7Ak9ORNH/OGUqM97NWUI9Uzxb48T4Fo89ac4YOvfk=; + b=h5Zqy/5noZ7wLvKkU8ltZCJARoMGzRgYIz+6lVm6d7dOo7Uxu9mcjsoYgnWvy6XdcG + aR0/3PHwBgU2YPKwuQxzoNzKag42o+8C95h0GKdSvZjKFycWmb9qr6sgfaoH75xLxGck + EqZKIjAGzYeqfOjCU/ph8C98BTqM8ELdGB81pJvruJXrWcJWeYuvdNeMpXjam1KuN3yw + pIGE1hbbTOf+AmfjqPTmDLhxe3LBxtFjYkpnH8QsXtKb5XeDw2kDZ7C9ZppnKf5hiJTb + 9sRbiWITpK36P4W64+xD8g+UUIsTZsiiAoj2PbqzfIXb+FhLIWzLZi5jpEJFBNxQDhXk + wjiw== +X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; + d=1e100.net; s=20230601; t=1728679776; x=1729284576; + h=content-transfer-encoding:in-reply-to:content-language:references + :cc:to:from:subject:user-agent:mime-version:date:message-id + :x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; + bh=NN7Ak9ORNH/OGUqM97NWUI9Uzxb48T4Fo89ac4YOvfk=; + b=HSXPcj2v9xU6WMelVxGECY1dfHvRTsZKcViNQcM+hB+TK0BXzxlnWBcF5DzKj6NwUT + 1mlvAopdwyxYuZlEPbdPhroXiZ1IrrhHuVg3sQkZAKcwQUrUTe3rMws7lHa6pzUpwN8v + 65tOQS5N5mTLOIXW3BOcyG3GyJnJ5gE5K5G8VsKS3V9aR7jRx2T+HHgmgkxBqWYx6PsF + XSyHFOd0ezzYj4PdnbmRbeOYeRRVsoN9G7JI5RYkgbp3hnfphc+jdVJmzbosDAQOB8NO + owa4EUVL1/P/E6LJDKIuIVeOr7+L+OoBdG85kUDA+18MQLyqmVgaCQay2Qs/xuhQ2oBz + cSrQ== +X-Gm-Message-State: AOJu0YzgoMFD3JB/KTeHSOoUpYTvRd81Fq9hq84BKiCEHsKX9AxjXU4a + FrH48o1DAzEfRtEOwRKOtc+jUmpIBeuDrQtNjU9Bh5RBXgTc1aZBsjGC3w== +X-Google-Smtp-Source: AGHT+IHR0FaJDxaVPLvW6/wAtk3kGQbE3pFNsFBvi/3qYR3/5TT96LLQoDuiLxQUh1tNK/hXVnFcQQ== +X-Received: by 2002:ac2:51c7:0:b0:539:e454:942e with SMTP id 2adb3069b0e04-539e45495c3mr941990e87.16.1728679775504; + Fri, 11 Oct 2024 13:49:35 -0700 (PDT) +Received: from [192.168.0.50] ([79.113.150.231]) + by smtp.gmail.com with ESMTPSA id 5b1f17b1804b1-430ccf51c69sm82740665e9.28.2024.10.11.13.49.34 + (version=TLS1_3 cipher=TLS_AES_128_GCM_SHA256 bits=128/128); + Fri, 11 Oct 2024 13:49:35 -0700 (PDT) +Message-ID: <21dbccaf-82e2-48aa-9b11-dc217ca76309@gmail.com> +Date: Fri, 11 Oct 2024 23:49:34 +0300 +Precedence: bulk +X-Mailing-List: linux-wireless@vger.kernel.org +List-Id: +List-Subscribe: +List-Unsubscribe: +MIME-Version: 1.0 +User-Agent: Mozilla Thunderbird +Subject: [PATCH v2 07/22] wifi: rtw88: Enable data rate fallback for older + chips +From: Bitterblue Smith +To: "linux-wireless@vger.kernel.org" +Cc: Ping-Ke Shih +References: +Content-Language: en-US +In-Reply-To: +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 7bit + +RTL8811AU fails to perform the 4-way handshake when the AP is too far +because it transmits the EAPOL frames at MCS9 and when that doesn't +work it retries 48 times with the same rate, to no avail. + +Retrying 48 times with the same rate seems pointless. Set the +appropriate field in the TX descriptor to allow it to use lower rates +when retrying. + +Set it for RTL8723D and RTL8703B because they interpret this field the +same way as RTL8811A. + +The newer RTL8822C, RTL8822B, RTL8821C seem to interpret this field in +the TX descriptor differently, so leave it alone for those chips. + +Tested with RTL8811AU and RTL8723DU. + +Signed-off-by: Bitterblue Smith +--- +v2: + - Initialise old_datarate_fb_limit for every chip. +--- + drivers/net/wireless/realtek/rtw88/fw.c | 2 +- + drivers/net/wireless/realtek/rtw88/main.h | 1 + + drivers/net/wireless/realtek/rtw88/pci.c | 2 +- + drivers/net/wireless/realtek/rtw88/rtw8703b.c | 1 + + drivers/net/wireless/realtek/rtw88/rtw8723d.c | 1 + + drivers/net/wireless/realtek/rtw88/rtw8821c.c | 1 + + drivers/net/wireless/realtek/rtw88/rtw8822b.c | 1 + + drivers/net/wireless/realtek/rtw88/rtw8822c.c | 1 + + drivers/net/wireless/realtek/rtw88/sdio.c | 2 +- + drivers/net/wireless/realtek/rtw88/tx.c | 6 +++++- + drivers/net/wireless/realtek/rtw88/tx.h | 4 +++- + drivers/net/wireless/realtek/rtw88/usb.c | 4 ++-- + 12 files changed, 19 insertions(+), 7 deletions(-) + +diff --git a/drivers/net/wireless/realtek/rtw88/fw.c b/drivers/net/wireless/realtek/rtw88/fw.c +index 168e19187ba7..19de5ba555a9 100644 +--- a/drivers/net/wireless/realtek/rtw88/fw.c ++++ b/drivers/net/wireless/realtek/rtw88/fw.c +@@ -1290,7 +1290,7 @@ static void rtw_fill_rsvd_page_desc(struct rtw_dev *rtwdev, struct sk_buff *skb, + rtw_tx_rsvd_page_pkt_info_update(rtwdev, &pkt_info, skb, type); + pkt_desc = skb_push(skb, chip->tx_pkt_desc_sz); + memset(pkt_desc, 0, chip->tx_pkt_desc_sz); +- rtw_tx_fill_tx_desc(&pkt_info, skb); ++ rtw_tx_fill_tx_desc(rtwdev, &pkt_info, skb); + } + + static inline u8 rtw_len_to_page(unsigned int len, u8 page_size) +diff --git a/drivers/net/wireless/realtek/rtw88/main.h b/drivers/net/wireless/realtek/rtw88/main.h +index af4876327837..64bc43cdd209 100644 +--- a/drivers/net/wireless/realtek/rtw88/main.h ++++ b/drivers/net/wireless/realtek/rtw88/main.h +@@ -1204,6 +1204,7 @@ struct rtw_chip_info { + u8 usb_tx_agg_desc_num; + bool hw_feature_report; + u8 c2h_ra_report_size; ++ bool old_datarate_fb_limit; + + u8 default_1ss_tx_path; + +diff --git a/drivers/net/wireless/realtek/rtw88/pci.c b/drivers/net/wireless/realtek/rtw88/pci.c +index f71e41d6f97c..0ecaefc4c83d 100644 +--- a/drivers/net/wireless/realtek/rtw88/pci.c ++++ b/drivers/net/wireless/realtek/rtw88/pci.c +@@ -824,7 +824,7 @@ static int rtw_pci_tx_write_data(struct rtw_dev *rtwdev, + pkt_desc = skb_push(skb, chip->tx_pkt_desc_sz); + memset(pkt_desc, 0, tx_pkt_desc_sz); + pkt_info->qsel = rtw_pci_get_tx_qsel(skb, queue); +- rtw_tx_fill_tx_desc(pkt_info, skb); ++ rtw_tx_fill_tx_desc(rtwdev, pkt_info, skb); + dma = dma_map_single(&rtwpci->pdev->dev, skb->data, skb->len, + DMA_TO_DEVICE); + if (dma_mapping_error(&rtwpci->pdev->dev, dma)) +diff --git a/drivers/net/wireless/realtek/rtw88/rtw8703b.c b/drivers/net/wireless/realtek/rtw88/rtw8703b.c +index 97dbc77f037a..f6f6635b46e1 100644 +--- a/drivers/net/wireless/realtek/rtw88/rtw8703b.c ++++ b/drivers/net/wireless/realtek/rtw88/rtw8703b.c +@@ -1964,6 +1964,7 @@ const struct rtw_chip_info rtw8703b_hw_spec = { + .usb_tx_agg_desc_num = 1, /* Not sure if this chip has USB interface */ + .hw_feature_report = true, + .c2h_ra_report_size = 7, ++ .old_datarate_fb_limit = true, + + .path_div_supported = false, + .ht_supported = true, +diff --git a/drivers/net/wireless/realtek/rtw88/rtw8723d.c b/drivers/net/wireless/realtek/rtw88/rtw8723d.c +index f6a08b06f853..a0bf37a58632 100644 +--- a/drivers/net/wireless/realtek/rtw88/rtw8723d.c ++++ b/drivers/net/wireless/realtek/rtw88/rtw8723d.c +@@ -2135,6 +2135,7 @@ const struct rtw_chip_info rtw8723d_hw_spec = { + .usb_tx_agg_desc_num = 1, + .hw_feature_report = true, + .c2h_ra_report_size = 7, ++ .old_datarate_fb_limit = true, + .ht_supported = true, + .vht_supported = false, + .lps_deep_mode_supported = 0, +diff --git a/drivers/net/wireless/realtek/rtw88/rtw8821c.c b/drivers/net/wireless/realtek/rtw88/rtw8821c.c +index e17d0193ca6f..39dc8244f744 100644 +--- a/drivers/net/wireless/realtek/rtw88/rtw8821c.c ++++ b/drivers/net/wireless/realtek/rtw88/rtw8821c.c +@@ -1972,6 +1972,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/drivers/net/wireless/realtek/rtw88/rtw8822b.c b/drivers/net/wireless/realtek/rtw88/rtw8822b.c +index 7360ce0a193e..419eb14c5467 100644 +--- a/drivers/net/wireless/realtek/rtw88/rtw8822b.c ++++ b/drivers/net/wireless/realtek/rtw88/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/drivers/net/wireless/realtek/rtw88/rtw8822c.c b/drivers/net/wireless/realtek/rtw88/rtw8822c.c +index 17d4d9bddd83..56085f220fcd 100644 +--- a/drivers/net/wireless/realtek/rtw88/rtw8822c.c ++++ b/drivers/net/wireless/realtek/rtw88/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/drivers/net/wireless/realtek/rtw88/sdio.c b/drivers/net/wireless/realtek/rtw88/sdio.c +index f0b06ed8f76d..799230eb5f16 100644 +--- a/drivers/net/wireless/realtek/rtw88/sdio.c ++++ b/drivers/net/wireless/realtek/rtw88/sdio.c +@@ -864,7 +864,7 @@ static void rtw_sdio_tx_skb_prepare(struct rtw_dev *rtwdev, + + pkt_info->qsel = rtw_sdio_get_tx_qsel(rtwdev, skb, queue); + +- rtw_tx_fill_tx_desc(pkt_info, skb); ++ rtw_tx_fill_tx_desc(rtwdev, pkt_info, skb); + rtw_tx_fill_txdesc_checksum(rtwdev, pkt_info, pkt_desc); + } + +diff --git a/drivers/net/wireless/realtek/rtw88/tx.c b/drivers/net/wireless/realtek/rtw88/tx.c +index dae7ca148865..6ed470dd6f22 100644 +--- a/drivers/net/wireless/realtek/rtw88/tx.c ++++ b/drivers/net/wireless/realtek/rtw88/tx.c +@@ -32,7 +32,8 @@ void rtw_tx_stats(struct rtw_dev *rtwdev, struct ieee80211_vif *vif, + } + } + +-void rtw_tx_fill_tx_desc(struct rtw_tx_pkt_info *pkt_info, 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) + { + struct rtw_tx_desc *tx_desc = (struct rtw_tx_desc *)skb->data; + bool more_data = false; +@@ -67,6 +68,9 @@ void rtw_tx_fill_tx_desc(struct rtw_tx_pkt_info *pkt_info, struct sk_buff *skb) + + tx_desc->w4 = le32_encode_bits(pkt_info->rate, RTW_TX_DESC_W4_DATARATE); + ++ if (rtwdev->chip->old_datarate_fb_limit) ++ tx_desc->w4 |= le32_encode_bits(0x1f, RTW_TX_DESC_W4_DATARATE_FB_LIMIT); ++ + tx_desc->w5 = le32_encode_bits(pkt_info->short_gi, RTW_TX_DESC_W5_DATA_SHORT) | + le32_encode_bits(pkt_info->bw, RTW_TX_DESC_W5_DATA_BW) | + le32_encode_bits(pkt_info->ldpc, RTW_TX_DESC_W5_DATA_LDPC) | +diff --git a/drivers/net/wireless/realtek/rtw88/tx.h b/drivers/net/wireless/realtek/rtw88/tx.h +index 3d544fd7f60f..d34cdeca16f1 100644 +--- a/drivers/net/wireless/realtek/rtw88/tx.h ++++ b/drivers/net/wireless/realtek/rtw88/tx.h +@@ -44,6 +44,7 @@ struct rtw_tx_desc { + #define RTW_TX_DESC_W3_NAVUSEHDR BIT(15) + #define RTW_TX_DESC_W3_MAX_AGG_NUM GENMASK(21, 17) + #define RTW_TX_DESC_W4_DATARATE GENMASK(6, 0) ++#define RTW_TX_DESC_W4_DATARATE_FB_LIMIT GENMASK(12, 8) + #define RTW_TX_DESC_W4_RTSRATE GENMASK(28, 24) + #define RTW_TX_DESC_W5_DATA_SHORT BIT(4) + #define RTW_TX_DESC_W5_DATA_BW GENMASK(6, 5) +@@ -94,7 +95,8 @@ void rtw_tx_pkt_info_update(struct rtw_dev *rtwdev, + struct rtw_tx_pkt_info *pkt_info, + struct ieee80211_sta *sta, + struct sk_buff *skb); +-void rtw_tx_fill_tx_desc(struct rtw_tx_pkt_info *pkt_info, 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); + 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/drivers/net/wireless/realtek/rtw88/usb.c b/drivers/net/wireless/realtek/rtw88/usb.c +index ba314d90ab3f..a3d2b40ec67b 100644 +--- a/drivers/net/wireless/realtek/rtw88/usb.c ++++ b/drivers/net/wireless/realtek/rtw88/usb.c +@@ -458,7 +458,7 @@ static int rtw_usb_write_data(struct rtw_dev *rtwdev, + skb_put_data(skb, buf, size); + skb_push(skb, chip->tx_pkt_desc_sz); + memset(skb->data, 0, chip->tx_pkt_desc_sz); +- rtw_tx_fill_tx_desc(pkt_info, skb); ++ rtw_tx_fill_tx_desc(rtwdev, pkt_info, skb); + rtw_tx_fill_txdesc_checksum(rtwdev, pkt_info, skb->data); + + ret = rtw_usb_write_port(rtwdev, qsel, skb, +@@ -525,7 +525,7 @@ static int rtw_usb_tx_write(struct rtw_dev *rtwdev, + pkt_desc = skb_push(skb, chip->tx_pkt_desc_sz); + memset(pkt_desc, 0, chip->tx_pkt_desc_sz); + ep = qsel_to_ep(rtwusb, pkt_info->qsel); +- rtw_tx_fill_tx_desc(pkt_info, skb); ++ rtw_tx_fill_tx_desc(rtwdev, pkt_info, skb); + rtw_tx_fill_txdesc_checksum(rtwdev, pkt_info, skb->data); + tx_data = rtw_usb_get_tx_data(skb); + tx_data->sn = pkt_info->sn; +-- +2.46.0 + + +From mboxrd@z Thu Jan 1 00:00:00 1970 +Received: from mail-wm1-f51.google.com (mail-wm1-f51.google.com [209.85.128.51]) + (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) + (No client certificate requested) + by smtp.subspace.kernel.org (Postfix) with ESMTPS id E9F4E1CFECE + for ; Fri, 11 Oct 2024 20:50:07 +0000 (UTC) +Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.128.51 +ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; + t=1728679809; cv=none; b=u8HU0Hy99Z0Yk0u2h4Ph7vMcdOrfUZFjy7hFtOVjvAW1r4Bq71Zul7kFSDLTo8+yCeAXbIE01nLhUYgAaaDAj0irvTdvWRc43rHCFPS4F5qsRUBVPy2QwgBDJxbyn0dxdAupwgLGe6Mm2UEnpqUVUwUEnbxMKRluQm5EvtIzZs0= +ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; + s=arc-20240116; t=1728679809; c=relaxed/simple; + bh=zAhYgTa37cJvLLXlV12fDr0sO+eXXdiIVez7Neb0Hu8=; + h=Message-ID:Date:MIME-Version:Subject:From:To:Cc:References: + In-Reply-To:Content-Type; b=eP97K4nRT4zknF6YrfTVgzLVwiIfm1jHNQx+5h15U7vaPnj9QlG/SJSPUEeqT6fmtkcEGMir2eaFcTdj57rGbouUJmhom/SUAvJoM5aVrdlGSS4MpdqspU42xKYzx5XKV4gEcCkgpnD4Wul9phfXooMRj49i8IPuOUP3YsdvILQ= +ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=lIGjJEZw; arc=none smtp.client-ip=209.85.128.51 +Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com +Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com +Authentication-Results: smtp.subspace.kernel.org; + dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="lIGjJEZw" +Received: by mail-wm1-f51.google.com with SMTP id 5b1f17b1804b1-43058268d91so21402495e9.0 + for ; Fri, 11 Oct 2024 13:50:07 -0700 (PDT) +DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; + d=gmail.com; s=20230601; t=1728679806; x=1729284606; darn=vger.kernel.org; + h=content-transfer-encoding:in-reply-to:content-language:references + :cc:to:from:subject:user-agent:mime-version:date:message-id:from:to + :cc:subject:date:message-id:reply-to; + bh=HRjyqKwSN/TcZYSbXj0ckwT6zaigwXZxioktj5K45Ws=; + b=lIGjJEZwtAwz2xHTGAirNDLIYv/zw1fcXmBhmXMv5k1azIMxonjYhX6yhJMOh0nC4a + SV/e+xABc5QyyOqqzsnu9qHfwB0juInpzg1SIcTziweo/lmYjhsCuyIctDPztMUnBz4t + SJ3K208zRN+5do2DdKGNNPlicTez84H+gu3JqX5pY+dHEaYT8Xa8v/0hUPmesROMMPYx + eyHsKxWzQ/S6G7eai8PEQ9gwusLWt7ja8oLAQ6JotipUGGpM9DbeBVJKCdGkVE0Ud6UF + 61UtcwLL4AK0/sMhskJeXbFszD+vaA+Jc2eBAosZ2VhPZwS36hEE04NQVEhhyC7lAUGx + iWyA== +X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; + d=1e100.net; s=20230601; t=1728679806; x=1729284606; + h=content-transfer-encoding:in-reply-to:content-language:references + :cc:to:from:subject:user-agent:mime-version:date:message-id + :x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; + bh=HRjyqKwSN/TcZYSbXj0ckwT6zaigwXZxioktj5K45Ws=; + b=jYBGaxRo5x2U/KWHYV108nKNr2z6UQUTiJ56rj86IeJDF2ECjbyAcdBs4WBkpNnubw + +6y76spGE/+y4Lw0HHghj76UkLzw9kSQVoR/Niua/ctI6SbTZvGEadfQ628GMVoCw1jk + GBfCjt2puTgiayW12TYDurfStzkoX/QneEc/Y9/hdw5tejpT/5ibuNbMYGUq08a//KYc + xiSTn5RuBrfEWp683a2rdeO2FWcnxLXeWuEuyPVYoyogm9Ssxw0V9MUE4HSSnjjjek79 + x9msH3ZO0LbYhly7fY+ghXXRZfVyThc4ZqgOQl9YdTMaRYQ5KRrtN4Pk+r0HrLYHCfPz + mUqw== +X-Gm-Message-State: AOJu0YzjTmJ8oeDVmnymeUZgqvHQ0GrvTV3FpbzH6QtUZtreG0YL6Gte + t3Mxr6YaWsDC5qRpNVcBQsabJuVjl4jkn6KJ9Bsl98sA9TSM5jaAgN9S7A== +X-Google-Smtp-Source: AGHT+IFUwz19wTYZPP0tAGGpIOgva5CS5V7MzZCvSomR+xk5n16Gs4ma1XJzSxz5JNswB0p3Lhqf/g== +X-Received: by 2002:a05:600c:470e:b0:42c:acb0:dda5 with SMTP id 5b1f17b1804b1-4311dea3c39mr34916965e9.1.1728679806205; + Fri, 11 Oct 2024 13:50:06 -0700 (PDT) +Received: from [192.168.0.50] ([79.113.150.231]) + by smtp.gmail.com with ESMTPSA id 5b1f17b1804b1-4311835d78fsm50237785e9.43.2024.10.11.13.50.05 + (version=TLS1_3 cipher=TLS_AES_128_GCM_SHA256 bits=128/128); + Fri, 11 Oct 2024 13:50:05 -0700 (PDT) +Message-ID: <371b587a-b7ee-4a1d-9a45-4a3f583b3bde@gmail.com> +Date: Fri, 11 Oct 2024 23:50:05 +0300 +Precedence: bulk +X-Mailing-List: linux-wireless@vger.kernel.org +List-Id: +List-Subscribe: +List-Unsubscribe: +MIME-Version: 1.0 +User-Agent: Mozilla Thunderbird +Subject: [PATCH v2 08/22] wifi: rtw88: Make txagc_remnant_ofdm an array +From: Bitterblue Smith +To: "linux-wireless@vger.kernel.org" +Cc: Ping-Ke Shih +References: +Content-Language: en-US +In-Reply-To: +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 7bit + +txagc_remnant_ofdm member of struct rtw_dm_info should be different for +each RF path, so make it an array of size RTW_RF_PATH_MAX (4). + +Until now all the chips using this had only one RF path, but RTL8812AU +has two, and RTL8814AU has four. + +Signed-off-by: Bitterblue Smith +--- +v2: + - No change. +--- + drivers/net/wireless/realtek/rtw88/main.h | 2 +- + drivers/net/wireless/realtek/rtw88/phy.c | 4 ++-- + drivers/net/wireless/realtek/rtw88/rtw8703b.c | 4 ++-- + drivers/net/wireless/realtek/rtw88/rtw8723d.c | 4 ++-- + 4 files changed, 7 insertions(+), 7 deletions(-) + +diff --git a/drivers/net/wireless/realtek/rtw88/main.h b/drivers/net/wireless/realtek/rtw88/main.h +index 64bc43cdd209..45f0e8fff453 100644 +--- a/drivers/net/wireless/realtek/rtw88/main.h ++++ b/drivers/net/wireless/realtek/rtw88/main.h +@@ -1715,7 +1715,7 @@ struct rtw_dm_info { + bool pwr_trk_init_trigger; + struct ewma_thermal avg_thermal[RTW_RF_PATH_MAX]; + s8 txagc_remnant_cck; +- s8 txagc_remnant_ofdm; ++ s8 txagc_remnant_ofdm[RTW_RF_PATH_MAX]; + u8 rx_cck_agc_report_type; + + /* backup dack results for each path and I/Q */ +diff --git a/drivers/net/wireless/realtek/rtw88/phy.c b/drivers/net/wireless/realtek/rtw88/phy.c +index dda212a721ca..5fbacb7ce499 100644 +--- a/drivers/net/wireless/realtek/rtw88/phy.c ++++ b/drivers/net/wireless/realtek/rtw88/phy.c +@@ -2170,8 +2170,8 @@ void rtw_get_tx_power_params(struct rtw_dev *rtwdev, u8 path, u8 rate, u8 bw, + + *limit = rtw_phy_get_tx_power_limit(rtwdev, band, bw, path, + rate, ch, regd); +- *remnant = (rate <= DESC_RATE11M ? dm_info->txagc_remnant_cck : +- dm_info->txagc_remnant_ofdm); ++ *remnant = rate <= DESC_RATE11M ? dm_info->txagc_remnant_cck : ++ dm_info->txagc_remnant_ofdm[path]; + *sar = rtw_phy_get_tx_power_sar(rtwdev, hal->sar_band, path, rate); + } + +diff --git a/drivers/net/wireless/realtek/rtw88/rtw8703b.c b/drivers/net/wireless/realtek/rtw88/rtw8703b.c +index f6f6635b46e1..dec0cec4ca22 100644 +--- a/drivers/net/wireless/realtek/rtw88/rtw8703b.c ++++ b/drivers/net/wireless/realtek/rtw88/rtw8703b.c +@@ -637,7 +637,7 @@ static void rtw8703b_pwrtrack_init(struct rtw_dev *rtwdev) + dm_info->pwr_trk_init_trigger = true; + dm_info->thermal_meter_k = rtwdev->efuse.thermal_meter_k; + dm_info->txagc_remnant_cck = 0; +- dm_info->txagc_remnant_ofdm = 0; ++ dm_info->txagc_remnant_ofdm[RF_PATH_A] = 0; + } + + static void rtw8703b_phy_set_param(struct rtw_dev *rtwdev) +@@ -1589,7 +1589,7 @@ static void rtw8703b_pwrtrack_set_ofdm_pwr(struct rtw_dev *rtwdev, s8 swing_idx, + { + struct rtw_dm_info *dm_info = &rtwdev->dm_info; + +- dm_info->txagc_remnant_ofdm = txagc_idx; ++ dm_info->txagc_remnant_ofdm[RF_PATH_A] = txagc_idx; + + /* Only path A is calibrated for rtl8703b */ + rtw8703b_set_iqk_matrix(rtwdev, swing_idx, RF_PATH_A); +diff --git a/drivers/net/wireless/realtek/rtw88/rtw8723d.c b/drivers/net/wireless/realtek/rtw88/rtw8723d.c +index a0bf37a58632..1d99bb89ef1d 100644 +--- a/drivers/net/wireless/realtek/rtw88/rtw8723d.c ++++ b/drivers/net/wireless/realtek/rtw88/rtw8723d.c +@@ -79,7 +79,7 @@ static void rtw8723d_pwrtrack_init(struct rtw_dev *rtwdev) + dm_info->pwr_trk_init_trigger = true; + dm_info->thermal_meter_k = rtwdev->efuse.thermal_meter_k; + dm_info->txagc_remnant_cck = 0; +- dm_info->txagc_remnant_ofdm = 0; ++ dm_info->txagc_remnant_ofdm[RF_PATH_A] = 0; + } + + static void rtw8723d_phy_set_param(struct rtw_dev *rtwdev) +@@ -1265,7 +1265,7 @@ static void rtw8723d_pwrtrack_set_ofdm_pwr(struct rtw_dev *rtwdev, s8 swing_idx, + { + struct rtw_dm_info *dm_info = &rtwdev->dm_info; + +- dm_info->txagc_remnant_ofdm = txagc_idx; ++ dm_info->txagc_remnant_ofdm[RF_PATH_A] = txagc_idx; + + rtw8723d_set_iqk_matrix(rtwdev, swing_idx, RF_PATH_A); + rtw8723d_set_iqk_matrix(rtwdev, swing_idx, RF_PATH_B); +-- +2.46.0 + + +From mboxrd@z Thu Jan 1 00:00:00 1970 +Received: from mail-wm1-f54.google.com (mail-wm1-f54.google.com [209.85.128.54]) + (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) + (No client certificate requested) + by smtp.subspace.kernel.org (Postfix) with ESMTPS id E7F96199231 + for ; Fri, 11 Oct 2024 20:50:42 +0000 (UTC) +Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.128.54 +ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; + t=1728679844; cv=none; b=RnwMAj1Hi0coZ+t1OYqfpqi7ixeEVWQ6XptQOfpWlv7YV15aUGAPZIVnUQS7KZ6ztHkOt4W2O0s62vkBbX1depGNV5OcQxQ0EHR1z71I61/5wWjExQDqJHUUiuqCok89+9nz3ytNxyIsQJI1mmhGdiwDNugLd5gq18I2DFQxco0= +ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; + s=arc-20240116; t=1728679844; c=relaxed/simple; + bh=wD4kh0h+Vv2D1tU6eDk36d1nV3BxQ/nIx3hEMZsCw+M=; + h=Message-ID:Date:MIME-Version:Subject:From:To:Cc:References: + In-Reply-To:Content-Type; b=YuwxWG77OMxhtdho8dZj/mEO3Smltrxvcp0orGEFlb5PCo+38yo1jFHdlbLuXdkUDF7mtw/zFLaSpt02lW6l48Mxk+tiHRZJaK6J9XkiDXFzhSU2WFvipw9LocXTeOnd/GpwclJhBB5WkqLgnV87sEhLmLJnhJ+Fd53VwNNPaSc= +ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=JHZq1VC0; arc=none smtp.client-ip=209.85.128.54 +Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com +Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com +Authentication-Results: smtp.subspace.kernel.org; + dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="JHZq1VC0" +Received: by mail-wm1-f54.google.com with SMTP id 5b1f17b1804b1-42f6bec84b5so22209285e9.1 + for ; Fri, 11 Oct 2024 13:50:42 -0700 (PDT) +DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; + d=gmail.com; s=20230601; t=1728679841; x=1729284641; darn=vger.kernel.org; + h=content-transfer-encoding:in-reply-to:content-language:references + :cc:to:from:subject:user-agent:mime-version:date:message-id:from:to + :cc:subject:date:message-id:reply-to; + bh=4lWOpTIAqn07eSNq8Zzh9/5GfXDgd0p7kF8WG8BH6ys=; + b=JHZq1VC0WKSdKTcsCujuOIdz4h42pME9lEeDblvd91BFN6L+2BXrYVzt1PXw0WwrLS + jrBNYkyS8SQt18jzQbjGswlXnHdo2px5UdeD3oF1AUe5l3vcoMfFmqABWTlfRXotpjSO + ywc/FSENERb4StkSpHu5Jwl1lRyiRPgAxxMgQ+VYVcN6M+b1IjmG3xoVUGgyAunIHIwb + P349zCoQqB1tKDezSfl/9QZDR8yS7flo26CqFhBs3TBRjSuvNmxEKcppCN6uLvOGGEzW + 4Zh1w6fbO5DZAulEo8YZO7cpns5UN+sP2N3C/WYViUty90s014DqP2xmcQgCJIyyl4h4 + Ni7A== +X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; + d=1e100.net; s=20230601; t=1728679841; x=1729284641; + h=content-transfer-encoding:in-reply-to:content-language:references + :cc:to:from:subject:user-agent:mime-version:date:message-id + :x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; + bh=4lWOpTIAqn07eSNq8Zzh9/5GfXDgd0p7kF8WG8BH6ys=; + b=Q8aCxXxcG/t/TndfD/VwpfYhwL2+9V2MtUcLvaNZLZIQuJp6CUly0NuWW1bAI5ZN4o + 1JLUVYgTNS9bmKFD5Opa/3Ciqez5KibzAZ/8mUjV7jFVLZbOgtzaZAhwJczpKZt9nMU5 + Kp7FPtBrJkaXSbffBn5E/cbkDnU4pemr+b4b5YNYvOe2Wwc9K7l72ahn2vKPBTbfKUar + PH1XKZ4K3wNcgutjVAf9OJYaNb22z/k5kNij5hEBDuBmoX1bccDuNP+y6aSgALpvYfpw + 4I9OaohCwfOe0AbejqfjosC97Y3UiwJyyKvoB0aES+3Xi0xbXbfEkansIeu2wetGatur + 7qNQ== +X-Gm-Message-State: AOJu0Yzq4abbWVBWmHdTK3NSbWIWUV/9aV9/F17/d1RmfkLb9jeE7gBy + /JwE1WNRLy5mXA5nVeoXK5ATVMtCl1h92wUtm0+133bu4JQLGhKF2TwGWg== +X-Google-Smtp-Source: AGHT+IFv5ciRmkievYZJduFZ6maJhlQiFOjI+/ejbwjyMvvMLYJndKpI4Q1vHvf3F9NXMbjdXdpivw== +X-Received: by 2002:a05:600c:4f07:b0:426:5fbc:f319 with SMTP id 5b1f17b1804b1-4311df55cffmr30435825e9.33.1728679841183; + Fri, 11 Oct 2024 13:50:41 -0700 (PDT) +Received: from [192.168.0.50] ([79.113.150.231]) + by smtp.gmail.com with ESMTPSA id 5b1f17b1804b1-431183062b5sm50588045e9.26.2024.10.11.13.50.40 + (version=TLS1_3 cipher=TLS_AES_128_GCM_SHA256 bits=128/128); + Fri, 11 Oct 2024 13:50:40 -0700 (PDT) +Message-ID: <5dfb2493-cd39-4c89-be22-9b04f21610a4@gmail.com> +Date: Fri, 11 Oct 2024 23:50:40 +0300 +Precedence: bulk +X-Mailing-List: linux-wireless@vger.kernel.org +List-Id: +List-Subscribe: +List-Unsubscribe: +MIME-Version: 1.0 +User-Agent: Mozilla Thunderbird +Subject: [PATCH v2 09/22] wifi: rtw88: Support TX page sizes bigger than 128 +From: Bitterblue Smith +To: "linux-wireless@vger.kernel.org" +Cc: Ping-Ke Shih +References: +Content-Language: en-US +In-Reply-To: +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 7bit + +All the chips supported so far have a TX page size of 128 bytes. + +Change the type of the page_size member of struct rtw_chip_info from u8 +to u16 in order to support RTL8821AU (page size of 256 bytes) and +RTL8812AU (page size of 512 bytes). Also change the types of several +related variables and function parameters from u8 to u16. + +The TX page size is used, among other things, to construct the beacon, +null data, QOS null data, and PS poll templates which are uploaded to +the chip's reserved page. Each template needs to be aligned on a +multiple of the TX page size. Power saving can't work if the TX page +size is wrong. + +Signed-off-by: Bitterblue Smith +--- +v2: + - No change. +--- + drivers/net/wireless/realtek/rtw88/debug.c | 2 +- + drivers/net/wireless/realtek/rtw88/fw.c | 11 ++++++----- + drivers/net/wireless/realtek/rtw88/mac.c | 2 +- + drivers/net/wireless/realtek/rtw88/main.h | 2 +- + 4 files changed, 9 insertions(+), 8 deletions(-) + +diff --git a/drivers/net/wireless/realtek/rtw88/debug.c b/drivers/net/wireless/realtek/rtw88/debug.c +index c26a6905fd15..364ec0436d0f 100644 +--- a/drivers/net/wireless/realtek/rtw88/debug.c ++++ b/drivers/net/wireless/realtek/rtw88/debug.c +@@ -308,7 +308,7 @@ static int rtw_debugfs_get_rsvd_page(struct seq_file *m, void *v) + { + struct rtw_debugfs_priv *debugfs_priv = m->private; + struct rtw_dev *rtwdev = debugfs_priv->rtwdev; +- u8 page_size = rtwdev->chip->page_size; ++ u16 page_size = rtwdev->chip->page_size; + u32 buf_size = debugfs_priv->rsvd_page.page_num * page_size; + u32 offset = debugfs_priv->rsvd_page.page_offset * page_size; + u8 *buf; +diff --git a/drivers/net/wireless/realtek/rtw88/fw.c b/drivers/net/wireless/realtek/rtw88/fw.c +index 19de5ba555a9..95258b9597bb 100644 +--- a/drivers/net/wireless/realtek/rtw88/fw.c ++++ b/drivers/net/wireless/realtek/rtw88/fw.c +@@ -1293,13 +1293,13 @@ static void rtw_fill_rsvd_page_desc(struct rtw_dev *rtwdev, struct sk_buff *skb, + rtw_tx_fill_tx_desc(rtwdev, &pkt_info, skb); + } + +-static inline u8 rtw_len_to_page(unsigned int len, u8 page_size) ++static inline u8 rtw_len_to_page(unsigned int len, u16 page_size) + { + return DIV_ROUND_UP(len, page_size); + } + +-static void rtw_rsvd_page_list_to_buf(struct rtw_dev *rtwdev, u8 page_size, +- u8 page_margin, u32 page, u8 *buf, ++static void rtw_rsvd_page_list_to_buf(struct rtw_dev *rtwdev, u16 page_size, ++ u16 page_margin, u32 page, u8 *buf, + struct rtw_rsvd_page *rsvd_pkt) + { + struct sk_buff *skb = rsvd_pkt->skb; +@@ -1607,7 +1607,7 @@ static u8 *rtw_build_rsvd_page(struct rtw_dev *rtwdev, u32 *size) + struct rtw_rsvd_page *rsvd_pkt; + u32 page = 0; + u8 total_page = 0; +- u8 page_size, page_margin, tx_desc_sz; ++ u16 page_size, page_margin, tx_desc_sz; + u8 *buf; + int ret; + +@@ -2013,7 +2013,8 @@ 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, page_size = chip->page_size; ++ 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; +diff --git a/drivers/net/wireless/realtek/rtw88/mac.c b/drivers/net/wireless/realtek/rtw88/mac.c +index daf23ccf6378..cae9cca6dca3 100644 +--- a/drivers/net/wireless/realtek/rtw88/mac.c ++++ b/drivers/net/wireless/realtek/rtw88/mac.c +@@ -1138,7 +1138,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 >> 7; ++ fifo->txff_pg_num = chip->txff_size / chip->page_size; + if (rtw_chip_wcpu_11n(rtwdev)) + fifo->rsvd_pg_num = fifo->rsvd_drv_pg_num; + else +diff --git a/drivers/net/wireless/realtek/rtw88/main.h b/drivers/net/wireless/realtek/rtw88/main.h +index 45f0e8fff453..ef82e60d5c19 100644 +--- a/drivers/net/wireless/realtek/rtw88/main.h ++++ b/drivers/net/wireless/realtek/rtw88/main.h +@@ -1187,7 +1187,7 @@ struct rtw_chip_info { + u32 fw_rxff_size; + u16 rsvd_drv_pg_num; + u8 band; +- u8 page_size; ++ u16 page_size; + u8 csi_buf_pg_num; + u8 dig_max; + u8 dig_min; +-- +2.46.0 + + +From mboxrd@z Thu Jan 1 00:00:00 1970 +Received: from mail-wm1-f52.google.com (mail-wm1-f52.google.com [209.85.128.52]) + (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) + (No client certificate requested) + by smtp.subspace.kernel.org (Postfix) with ESMTPS id CAA5E199231 + for ; Fri, 11 Oct 2024 20:51:09 +0000 (UTC) +Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.128.52 +ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; + t=1728679871; cv=none; b=cQGQVk4WfW3ClK1F9cUy2WTJTr4otM/5+9m+gTG7Ng19OJwA2hh41DtW9JPNQpJbOh4Dfu/MIuwUJqca2+N/LVGfj0ezt38iCIBrSW0B77HjI3mEnbm8262edh0F3ax+CTXKyGf8iSItDqtsGnfydNJozMONnWH6R9QlfBlttOw= +ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; + s=arc-20240116; t=1728679871; c=relaxed/simple; + bh=jyZY1332C7rqu8g5dA8yVuV9oeXi2TpxlFsMphF1Fw8=; + h=Message-ID:Date:MIME-Version:Subject:From:To:Cc:References: + In-Reply-To:Content-Type; b=FtChlw68ce0EokVa4VBo/tWiGDSjoifb/ZT37DU+GO6E7Xy7XVwcwp1SVcoI0fon0D5MhIiQ55Vd/UtOGJF+jwzXU1ML6/3kSi3sEhoGlobARkeUoG4TxxBInHp583aPasS8PvyVrqLDFE8neWbzgYPL2ia7lZxqrgxEl2K+Y3Q= +ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=FAz9AClH; arc=none smtp.client-ip=209.85.128.52 +Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com +Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com +Authentication-Results: smtp.subspace.kernel.org; + dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="FAz9AClH" +Received: by mail-wm1-f52.google.com with SMTP id 5b1f17b1804b1-43117917eb9so19051835e9.0 + for ; Fri, 11 Oct 2024 13:51:09 -0700 (PDT) +DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; + d=gmail.com; s=20230601; t=1728679868; x=1729284668; darn=vger.kernel.org; + h=content-transfer-encoding:in-reply-to:content-language:references + :cc:to:from:subject:user-agent:mime-version:date:message-id:from:to + :cc:subject:date:message-id:reply-to; + bh=4kWRdu/STBd0MrSxEe3PtZg2A5l7/bKnXWiH9jWHZfw=; + b=FAz9AClHM6HmYVR+1nfplUcHp1ykZyevxWGKxSxAu/JgsLRux3h0hGT3RYILMRQlpr + 1EjXWrDv7UFyiZg82ntpTZZuzpX5EEInpq4gFe+srmbuOWT1oJk1hF32rCIDh8oqI8fO + d4QMfmzmqJN1OQ0gHTX3MCWGH17EoeqA3Tb0K1Ls8hKx4CEizGtIl9h+6Qr0Xxknotov + IdCdXT5neX6wsft5uJL0IB171b2JPBc2nofr9gG7fj4Y67rvpDiz+xOuqhwL/IQuB9Hm + cHFlSq5r1JXX5SsqeNgkKVBvF8eSmXEOl628guWqLDvIk17shHBfj7hq7z/UTgQLlg1p + 1EjQ== +X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; + d=1e100.net; s=20230601; t=1728679868; x=1729284668; + h=content-transfer-encoding:in-reply-to:content-language:references + :cc:to:from:subject:user-agent:mime-version:date:message-id + :x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; + bh=4kWRdu/STBd0MrSxEe3PtZg2A5l7/bKnXWiH9jWHZfw=; + b=hMKCpGrCb31PTlvqJ7WiATkDgoXYjvejSr441rlizFsve+eUmaC55TcK3uNs7mam30 + /0Lw9sEsx4NeVfHoUvHuW7SFu1P4B9s0zkfCBC4mGKJTUC19PwImFBgp4D8RhbNA3J/+ + lScm4y7+ptdfl9ZUIB8JMjSStAYEeZ/1UAg0eS8wa/x+wh9bE+DtBTT6QhcCkCY8QnJk + CgYiT4claZGHDuHrOdhu2maGPWkJh6M+QTiwNYk/12QxR9lpnxc2dfJ6XkAv2K113fCI + DckRXPEwS1grmxZStja/pnBZRAPLw71/xsjNbgj+BueH6um/5ktwtEPWuzbW4EGdTmku + PpLQ== +X-Gm-Message-State: AOJu0YzZ07yfhOl7mWeepbyQGGk0xUz9Mh+jsIUJtzcgm+ZVg//uriMi + fT32EcssjHYHdWfboXHCtRiYdTj89aL9uvGOjFK/lQEdJ9wCfE6vWHqr2w== +X-Google-Smtp-Source: AGHT+IFLllswb6flrogZ7gZ4Z8AonRh9g3MegD/UvA3dGs9z8x6YkxlVj39vBJ3ney98KFHmurM+RA== +X-Received: by 2002:a05:600c:470e:b0:430:5356:ac8e with SMTP id 5b1f17b1804b1-4311dea3938mr36507805e9.5.1728679867906; + Fri, 11 Oct 2024 13:51:07 -0700 (PDT) +Received: from [192.168.0.50] ([79.113.150.231]) + by smtp.gmail.com with ESMTPSA id 5b1f17b1804b1-430ccf1f797sm83758535e9.4.2024.10.11.13.51.07 + (version=TLS1_3 cipher=TLS_AES_128_GCM_SHA256 bits=128/128); + Fri, 11 Oct 2024 13:51:07 -0700 (PDT) +Message-ID: <46e4f978-7dc3-447b-a744-a4ea7654ab5b@gmail.com> +Date: Fri, 11 Oct 2024 23:51:06 +0300 +Precedence: bulk +X-Mailing-List: linux-wireless@vger.kernel.org +List-Id: +List-Subscribe: +List-Unsubscribe: +MIME-Version: 1.0 +User-Agent: Mozilla Thunderbird +Subject: [PATCH v2 10/22] wifi: rtw88: Move pwr_track_tbl to struct + rtw_rfe_def +From: Bitterblue Smith +To: "linux-wireless@vger.kernel.org" +Cc: Ping-Ke Shih +References: +Content-Language: en-US +In-Reply-To: +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 7bit + +RTL8812AU uses one set of TX power tracking tables for RFE 3, and +another set for everything else. + +Move pwr_track_tbl from struct rtw_chip_info to struct rtw_rfe_def in +order to load the right set of tables for each RFE (RF front end) type. + +Signed-off-by: Bitterblue Smith +--- +v2: + - No change. +--- + drivers/net/wireless/realtek/rtw88/main.h | 8 ++++--- + drivers/net/wireless/realtek/rtw88/phy.c | 3 ++- + drivers/net/wireless/realtek/rtw88/rtw8703b.c | 12 +++++----- + drivers/net/wireless/realtek/rtw88/rtw8723d.c | 12 +++++----- + drivers/net/wireless/realtek/rtw88/rtw8723x.c | 3 ++- + drivers/net/wireless/realtek/rtw88/rtw8821c.c | 17 +++++++------- + drivers/net/wireless/realtek/rtw88/rtw8822b.c | 15 ++++++------ + drivers/net/wireless/realtek/rtw88/rtw8822c.c | 23 +++++++++---------- + 8 files changed, 47 insertions(+), 46 deletions(-) + +diff --git a/drivers/net/wireless/realtek/rtw88/main.h b/drivers/net/wireless/realtek/rtw88/main.h +index ef82e60d5c19..072d09a7d313 100644 +--- a/drivers/net/wireless/realtek/rtw88/main.h ++++ b/drivers/net/wireless/realtek/rtw88/main.h +@@ -1100,16 +1100,19 @@ 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; + }; + +-#define RTW_DEF_RFE(chip, bb_pg, pwrlmt) { \ ++#define RTW_DEF_RFE(chip, bb_pg, pwrlmt, track) { \ + .phy_pg_tbl = &rtw ## chip ## _bb_pg_type ## bb_pg ## _tbl, \ + .txpwr_lmt_tbl = &rtw ## chip ## _txpwr_lmt_type ## pwrlmt ## _tbl, \ ++ .pwr_track_tbl = &rtw ## chip ## _pwr_track_type ## track ## _tbl, \ + } + +-#define RTW_DEF_RFE_EXT(chip, bb_pg, pwrlmt, btg) { \ ++#define RTW_DEF_RFE_EXT(chip, bb_pg, pwrlmt, track, btg) { \ + .phy_pg_tbl = &rtw ## chip ## _bb_pg_type ## bb_pg ## _tbl, \ + .txpwr_lmt_tbl = &rtw ## chip ## _txpwr_lmt_type ## pwrlmt ## _tbl, \ ++ .pwr_track_tbl = &rtw ## chip ## _pwr_track_type ## track ## _tbl, \ + .agc_btg_tbl = &rtw ## chip ## _agc_btg_type ## btg ## _tbl, \ + } + +@@ -1243,7 +1246,6 @@ struct rtw_chip_info { + u16 dpd_ratemask; + u8 iqk_threshold; + u8 lck_threshold; +- const struct rtw_pwr_track_tbl *pwr_track_tbl; + + u8 bfer_su_max_num; + u8 bfer_mu_max_num; +diff --git a/drivers/net/wireless/realtek/rtw88/phy.c b/drivers/net/wireless/realtek/rtw88/phy.c +index 5fbacb7ce499..db2aa0b8c327 100644 +--- a/drivers/net/wireless/realtek/rtw88/phy.c ++++ b/drivers/net/wireless/realtek/rtw88/phy.c +@@ -2385,7 +2385,8 @@ void rtw_phy_init_tx_power(struct rtw_dev *rtwdev) + void rtw_phy_config_swing_table(struct rtw_dev *rtwdev, + struct rtw_swing_table *swing_table) + { +- const struct rtw_pwr_track_tbl *tbl = rtwdev->chip->pwr_track_tbl; ++ const struct rtw_rfe_def *rfe_def = rtw_get_rfe_def(rtwdev); ++ const struct rtw_pwr_track_tbl *tbl = rfe_def->pwr_track_tbl; + u8 channel = rtwdev->hal.current_channel; + + if (IS_CH_2G_BAND(channel)) { +diff --git a/drivers/net/wireless/realtek/rtw88/rtw8703b.c b/drivers/net/wireless/realtek/rtw88/rtw8703b.c +index dec0cec4ca22..a19b94d022ee 100644 +--- a/drivers/net/wireless/realtek/rtw88/rtw8703b.c ++++ b/drivers/net/wireless/realtek/rtw88/rtw8703b.c +@@ -493,11 +493,6 @@ static const struct rtw_pwr_seq_cmd * const card_disable_flow_8703b[] = { + NULL + }; + +-static const struct rtw_rfe_def rtw8703b_rfe_defs[] = { +- [0] = { .phy_pg_tbl = &rtw8703b_bb_pg_tbl, +- .txpwr_lmt_tbl = &rtw8703b_txpwr_lmt_tbl,}, +-}; +- + static const struct rtw_page_table page_table_8703b[] = { + {12, 2, 2, 0, 1}, + {12, 2, 2, 0, 1}, +@@ -1818,6 +1813,12 @@ static const struct rtw_pwr_track_tbl rtw8703b_rtw_pwr_track_tbl = { + .pwrtrk_xtal_p = rtw8703b_pwrtrk_xtal_p, + }; + ++static const struct rtw_rfe_def rtw8703b_rfe_defs[] = { ++ [0] = { .phy_pg_tbl = &rtw8703b_bb_pg_tbl, ++ .txpwr_lmt_tbl = &rtw8703b_txpwr_lmt_tbl, ++ .pwr_track_tbl = &rtw8703b_rtw_pwr_track_tbl, }, ++}; ++ + /* Shared-Antenna Coex Table */ + static const struct coex_table_para table_sant_8703b[] = { + {0xffffffff, 0xffffffff}, /* case-0 */ +@@ -1997,7 +1998,6 @@ const struct rtw_chip_info rtw8703b_hw_spec = { + .rfe_defs_size = ARRAY_SIZE(rtw8703b_rfe_defs), + + .iqk_threshold = 8, +- .pwr_track_tbl = &rtw8703b_rtw_pwr_track_tbl, + + /* WOWLAN firmware exists, but not implemented yet */ + .wow_fw_name = "rtw88/rtw8703b_wow_fw.bin", +diff --git a/drivers/net/wireless/realtek/rtw88/rtw8723d.c b/drivers/net/wireless/realtek/rtw88/rtw8723d.c +index 1d99bb89ef1d..eeca31bf71f1 100644 +--- a/drivers/net/wireless/realtek/rtw88/rtw8723d.c ++++ b/drivers/net/wireless/realtek/rtw88/rtw8723d.c +@@ -2020,11 +2020,6 @@ static const struct rtw_intf_phy_para_table phy_para_table_8723d = { + .n_gen1_para = ARRAY_SIZE(pcie_gen1_param_8723d), + }; + +-static const struct rtw_rfe_def rtw8723d_rfe_defs[] = { +- [0] = { .phy_pg_tbl = &rtw8723d_bb_pg_tbl, +- .txpwr_lmt_tbl = &rtw8723d_txpwr_lmt_tbl,}, +-}; +- + static const u8 rtw8723d_pwrtrk_2gb_n[] = { + 0, 0, 1, 1, 1, 2, 2, 3, 4, 4, 4, 4, 5, 5, 5, + 6, 6, 7, 7, 8, 8, 8, 9, 9, 9, 10, 10, 10, 10, 10 +@@ -2088,6 +2083,12 @@ static const struct rtw_pwr_track_tbl rtw8723d_rtw_pwr_track_tbl = { + .pwrtrk_xtal_n = rtw8723d_pwrtrk_xtal_n, + }; + ++static const struct rtw_rfe_def rtw8723d_rfe_defs[] = { ++ [0] = { .phy_pg_tbl = &rtw8723d_bb_pg_tbl, ++ .txpwr_lmt_tbl = &rtw8723d_txpwr_lmt_tbl, ++ .pwr_track_tbl = &rtw8723d_rtw_pwr_track_tbl, }, ++}; ++ + static const struct rtw_reg_domain coex_info_hw_regs_8723d[] = { + {0x948, MASKDWORD, RTW_REG_DOMAIN_MAC32}, + {0x67, BIT(7), RTW_REG_DOMAIN_MAC8}, +@@ -2159,7 +2160,6 @@ const struct rtw_chip_info rtw8723d_hw_spec = { + .rfe_defs = rtw8723d_rfe_defs, + .rfe_defs_size = ARRAY_SIZE(rtw8723d_rfe_defs), + .rx_ldpc = false, +- .pwr_track_tbl = &rtw8723d_rtw_pwr_track_tbl, + .iqk_threshold = 8, + .ampdu_density = IEEE80211_HT_MPDU_DENSITY_16, + .max_scan_ie_len = IEEE80211_MAX_DATA_LEN, +diff --git a/drivers/net/wireless/realtek/rtw88/rtw8723x.c b/drivers/net/wireless/realtek/rtw88/rtw8723x.c +index 0d0b6c2cb9aa..69f73cb5b4cd 100644 +--- a/drivers/net/wireless/realtek/rtw88/rtw8723x.c ++++ b/drivers/net/wireless/realtek/rtw88/rtw8723x.c +@@ -595,7 +595,8 @@ void __rtw8723x_pwrtrack_set_xtal(struct rtw_dev *rtwdev, u8 therm_path, + u8 delta) + { + struct rtw_dm_info *dm_info = &rtwdev->dm_info; +- const struct rtw_pwr_track_tbl *tbl = rtwdev->chip->pwr_track_tbl; ++ const struct rtw_rfe_def *rfe_def = rtw_get_rfe_def(rtwdev); ++ const struct rtw_pwr_track_tbl *tbl = rfe_def->pwr_track_tbl; + const s8 *pwrtrk_xtal; + s8 xtal_cap; + +diff --git a/drivers/net/wireless/realtek/rtw88/rtw8821c.c b/drivers/net/wireless/realtek/rtw88/rtw8821c.c +index 39dc8244f744..0270225b9c20 100644 +--- a/drivers/net/wireless/realtek/rtw88/rtw8821c.c ++++ b/drivers/net/wireless/realtek/rtw88/rtw8821c.c +@@ -1581,13 +1581,6 @@ static const struct rtw_intf_phy_para_table phy_para_table_8821c = { + .n_gen2_para = ARRAY_SIZE(pcie_gen2_param_8821c), + }; + +-static const struct rtw_rfe_def rtw8821c_rfe_defs[] = { +- [0] = RTW_DEF_RFE(8821c, 0, 0), +- [2] = RTW_DEF_RFE_EXT(8821c, 0, 0, 2), +- [4] = RTW_DEF_RFE_EXT(8821c, 0, 0, 2), +- [6] = RTW_DEF_RFE(8821c, 0, 0), +-}; +- + static const struct rtw_hw_reg rtw8821c_dig[] = { + [0] = { .addr = 0xc50, .mask = 0x7f }, + }; +@@ -1899,7 +1892,7 @@ static const u8 rtw8821c_pwrtrk_2g_cck_a_p[] = { + 5, 6, 6, 7, 7, 7, 8, 8, 9, 9, 9, 9, 9, 9 + }; + +-static const struct rtw_pwr_track_tbl rtw8821c_rtw_pwr_track_tbl = { ++static const struct rtw_pwr_track_tbl rtw8821c_pwr_track_type0_tbl = { + .pwrtrk_5gb_n[0] = rtw8821c_pwrtrk_5gb_n[0], + .pwrtrk_5gb_n[1] = rtw8821c_pwrtrk_5gb_n[1], + .pwrtrk_5gb_n[2] = rtw8821c_pwrtrk_5gb_n[2], +@@ -1922,6 +1915,13 @@ static const struct rtw_pwr_track_tbl rtw8821c_rtw_pwr_track_tbl = { + .pwrtrk_2g_ccka_p = rtw8821c_pwrtrk_2g_cck_a_p, + }; + ++static const struct rtw_rfe_def rtw8821c_rfe_defs[] = { ++ [0] = RTW_DEF_RFE(8821c, 0, 0, 0), ++ [2] = RTW_DEF_RFE_EXT(8821c, 0, 0, 0, 2), ++ [4] = RTW_DEF_RFE_EXT(8821c, 0, 0, 0, 2), ++ [6] = RTW_DEF_RFE(8821c, 0, 0, 0), ++}; ++ + static const struct rtw_reg_domain coex_info_hw_regs_8821c[] = { + {0xCB0, MASKDWORD, RTW_REG_DOMAIN_MAC32}, + {0xCB4, MASKDWORD, RTW_REG_DOMAIN_MAC32}, +@@ -1994,7 +1994,6 @@ const struct rtw_chip_info rtw8821c_hw_spec = { + .rfe_defs = rtw8821c_rfe_defs, + .rfe_defs_size = ARRAY_SIZE(rtw8821c_rfe_defs), + .rx_ldpc = false, +- .pwr_track_tbl = &rtw8821c_rtw_pwr_track_tbl, + .iqk_threshold = 8, + .bfer_su_max_num = 2, + .bfer_mu_max_num = 1, +diff --git a/drivers/net/wireless/realtek/rtw88/rtw8822b.c b/drivers/net/wireless/realtek/rtw88/rtw8822b.c +index 419eb14c5467..739809f4cab5 100644 +--- a/drivers/net/wireless/realtek/rtw88/rtw8822b.c ++++ b/drivers/net/wireless/realtek/rtw88/rtw8822b.c +@@ -2072,12 +2072,6 @@ static const struct rtw_intf_phy_para_table phy_para_table_8822b = { + .n_gen2_para = ARRAY_SIZE(pcie_gen2_param_8822b), + }; + +-static const struct rtw_rfe_def rtw8822b_rfe_defs[] = { +- [2] = RTW_DEF_RFE(8822b, 2, 2), +- [3] = RTW_DEF_RFE(8822b, 3, 0), +- [5] = RTW_DEF_RFE(8822b, 5, 5), +-}; +- + static const struct rtw_hw_reg rtw8822b_dig[] = { + [0] = { .addr = 0xc50, .mask = 0x7f }, + [1] = { .addr = 0xe50, .mask = 0x7f }, +@@ -2432,7 +2426,7 @@ static const u8 rtw8822b_pwrtrk_2g_cck_a_p[RTW_PWR_TRK_TBL_SZ] = { + 10, 11, 11, 12, 12, 13, 13, 14, 14, 15 + }; + +-static const struct rtw_pwr_track_tbl rtw8822b_rtw_pwr_track_tbl = { ++static const struct rtw_pwr_track_tbl rtw8822b_pwr_track_type0_tbl = { + .pwrtrk_5gb_n[RTW_PWR_TRK_5G_1] = rtw8822b_pwrtrk_5gb_n[RTW_PWR_TRK_5G_1], + .pwrtrk_5gb_n[RTW_PWR_TRK_5G_2] = rtw8822b_pwrtrk_5gb_n[RTW_PWR_TRK_5G_2], + .pwrtrk_5gb_n[RTW_PWR_TRK_5G_3] = rtw8822b_pwrtrk_5gb_n[RTW_PWR_TRK_5G_3], +@@ -2455,6 +2449,12 @@ static const struct rtw_pwr_track_tbl rtw8822b_rtw_pwr_track_tbl = { + .pwrtrk_2g_ccka_p = rtw8822b_pwrtrk_2g_cck_a_p, + }; + ++static const struct rtw_rfe_def rtw8822b_rfe_defs[] = { ++ [2] = RTW_DEF_RFE(8822b, 2, 2, 0), ++ [3] = RTW_DEF_RFE(8822b, 3, 0, 0), ++ [5] = RTW_DEF_RFE(8822b, 5, 5, 0), ++}; ++ + static const struct rtw_reg_domain coex_info_hw_regs_8822b[] = { + {0xcb0, MASKDWORD, RTW_REG_DOMAIN_MAC32}, + {0xcb4, MASKDWORD, RTW_REG_DOMAIN_MAC32}, +@@ -2535,7 +2535,6 @@ const struct rtw_chip_info rtw8822b_hw_spec = { + .rf_tbl = {&rtw8822b_rf_a_tbl, &rtw8822b_rf_b_tbl}, + .rfe_defs = rtw8822b_rfe_defs, + .rfe_defs_size = ARRAY_SIZE(rtw8822b_rfe_defs), +- .pwr_track_tbl = &rtw8822b_rtw_pwr_track_tbl, + .iqk_threshold = 8, + .bfer_su_max_num = 2, + .bfer_mu_max_num = 1, +diff --git a/drivers/net/wireless/realtek/rtw88/rtw8822c.c b/drivers/net/wireless/realtek/rtw88/rtw8822c.c +index 56085f220fcd..af6b76937f1d 100644 +--- a/drivers/net/wireless/realtek/rtw88/rtw8822c.c ++++ b/drivers/net/wireless/realtek/rtw88/rtw8822c.c +@@ -4883,16 +4883,6 @@ static const struct rtw_intf_phy_para_table phy_para_table_8822c = { + .n_gen2_para = ARRAY_SIZE(pcie_gen2_param_8822c), + }; + +-static const struct rtw_rfe_def rtw8822c_rfe_defs[] = { +- [0] = RTW_DEF_RFE(8822c, 0, 0), +- [1] = RTW_DEF_RFE(8822c, 0, 0), +- [2] = RTW_DEF_RFE(8822c, 0, 0), +- [3] = RTW_DEF_RFE(8822c, 0, 0), +- [4] = RTW_DEF_RFE(8822c, 0, 0), +- [5] = RTW_DEF_RFE(8822c, 0, 5), +- [6] = RTW_DEF_RFE(8822c, 0, 0), +-}; +- + static const struct rtw_hw_reg rtw8822c_dig[] = { + [0] = { .addr = 0x1d70, .mask = 0x7f }, + [1] = { .addr = 0x1d70, .mask = 0x7f00 }, +@@ -5238,7 +5228,7 @@ static const u8 rtw8822c_pwrtrk_2g_cck_a_p[RTW_PWR_TRK_TBL_SZ] = { + 18, 18, 19, 20, 21, 22, 23, 24, 24, 25 + }; + +-static const struct rtw_pwr_track_tbl rtw8822c_rtw_pwr_track_tbl = { ++static const struct rtw_pwr_track_tbl rtw8822c_pwr_track_type0_tbl = { + .pwrtrk_5gb_n[RTW_PWR_TRK_5G_1] = rtw8822c_pwrtrk_5gb_n[RTW_PWR_TRK_5G_1], + .pwrtrk_5gb_n[RTW_PWR_TRK_5G_2] = rtw8822c_pwrtrk_5gb_n[RTW_PWR_TRK_5G_2], + .pwrtrk_5gb_n[RTW_PWR_TRK_5G_3] = rtw8822c_pwrtrk_5gb_n[RTW_PWR_TRK_5G_3], +@@ -5261,6 +5251,16 @@ static const struct rtw_pwr_track_tbl rtw8822c_rtw_pwr_track_tbl = { + .pwrtrk_2g_ccka_p = rtw8822c_pwrtrk_2g_cck_a_p, + }; + ++static const struct rtw_rfe_def rtw8822c_rfe_defs[] = { ++ [0] = RTW_DEF_RFE(8822c, 0, 0, 0), ++ [1] = RTW_DEF_RFE(8822c, 0, 0, 0), ++ [2] = RTW_DEF_RFE(8822c, 0, 0, 0), ++ [3] = RTW_DEF_RFE(8822c, 0, 0, 0), ++ [4] = RTW_DEF_RFE(8822c, 0, 0, 0), ++ [5] = RTW_DEF_RFE(8822c, 0, 5, 0), ++ [6] = RTW_DEF_RFE(8822c, 0, 0, 0), ++}; ++ + static const struct rtw_hw_reg_offset rtw8822c_edcca_th[] = { + [EDCCA_TH_L2H_IDX] = { + {.addr = 0x84c, .mask = MASKBYTE2}, .offset = 0x80 +@@ -5360,7 +5360,6 @@ const struct rtw_chip_info rtw8822c_hw_spec = { + .rfe_defs_size = ARRAY_SIZE(rtw8822c_rfe_defs), + .en_dis_dpd = true, + .dpd_ratemask = DIS_DPD_RATEALL, +- .pwr_track_tbl = &rtw8822c_rtw_pwr_track_tbl, + .iqk_threshold = 8, + .lck_threshold = 8, + .bfer_su_max_num = 2, +-- +2.46.0 + + +From mboxrd@z Thu Jan 1 00:00:00 1970 +Received: from mail-wm1-f49.google.com (mail-wm1-f49.google.com [209.85.128.49]) + (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) + (No client certificate requested) + by smtp.subspace.kernel.org (Postfix) with ESMTPS id C57FE199231 + for ; Fri, 11 Oct 2024 20:51:46 +0000 (UTC) +Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.128.49 +ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; + t=1728679908; cv=none; b=hhl4MsnnBIgKyMdME2sCz3CLF+mLR0Plcjd1SKa3jB4iW6WhDVqZCYTs/HRxr0WZNxZFUr2VqZlvnvnhGZiFaPGSLgaaRxPx1obOrJ0vivzzYEJoIJ8zP00+ZkajeCROchQMTiU9LW8cRWDputHY951WkKDY0x6Z1g7hKZsXFRc= +ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; + s=arc-20240116; t=1728679908; c=relaxed/simple; + bh=UbA0TywvskXxF+9DKZ6GT/p+Dk/aH8lTYhVcGSQYuEc=; + h=Message-ID:Date:MIME-Version:Subject:From:To:Cc:References: + In-Reply-To:Content-Type; b=ulSbVPWzKw8DkcaaA266TVrSJ4a36cEdzWUkJ/KyeP+xWbTTcoFDYpK5kIJgZuAnemv1VwEMrceE373emauqGLfyY1im9S/dRYwU22v3uN3IVmWkSJKyEhPfUQWx0WfkWuh9O54wbpXtwifhs0zgY9f1JQTy/gdna5Y1WhG18rI= +ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=m3J8iLRX; arc=none smtp.client-ip=209.85.128.49 +Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com +Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com +Authentication-Results: smtp.subspace.kernel.org; + dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="m3J8iLRX" +Received: by mail-wm1-f49.google.com with SMTP id 5b1f17b1804b1-431126967d6so20545975e9.0 + for ; Fri, 11 Oct 2024 13:51:46 -0700 (PDT) +DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; + d=gmail.com; s=20230601; t=1728679905; x=1729284705; darn=vger.kernel.org; + h=content-transfer-encoding:in-reply-to:content-language:references + :cc:to:from:subject:user-agent:mime-version:date:message-id:from:to + :cc:subject:date:message-id:reply-to; + bh=N4gHsOWopAUyOMIcj4ZxnrWi4bRy89tHLLOXtaS3+Rg=; + b=m3J8iLRXMJg425bKhKx/cd9LBjYRQ7PrVjniUCRSHdqh7bVQ38CFiHpgRkHMXSwZ5g + jb3loE2dzVrFwSTkvZV7Q9TGBnWkUgf2r0GCnE5yn/ncBwusFrdewyU/xN578X4O605H + LYSdCQinPG/WbNNz1XfN8upKM+4g5XH0+PnJTQDSglC9Gezo3LpYHHmU3nkahLvrp0cX + 4dZuym3KD4FOwQ6XRqJcmj86pW200V2yXWejyWn5y3WKGNEjJhpjer/f9p3kMAfO4fxQ + zIGDDdR+ecUSVCK2Mz2qEYoMvgcaS81chZuYAVHBsQeqfBfRROdNldlKSqbxqR090jpS + 2Q0w== +X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; + d=1e100.net; s=20230601; t=1728679905; x=1729284705; + h=content-transfer-encoding:in-reply-to:content-language:references + :cc:to:from:subject:user-agent:mime-version:date:message-id + :x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; + bh=N4gHsOWopAUyOMIcj4ZxnrWi4bRy89tHLLOXtaS3+Rg=; + b=NXNVbOP9G20c/VkjOYSof5MhEM2TIWiRB4BP2q8TJKzYUh8/Q+q+yvg4l1cSj4twpz + zgAVIb3OjwQHIjvLnloOoJmR/q+Ox74IbNgwiqbKywBjmeCGTHmU66T5+J3KvcZ2hEkF + tNkRZNhjNiUaiiRGVYtUwsiQd7XjR6m52RGvlM+LFbHkkCKXSPli/wmyAU/hDM58YLwh + NYKLJT5KZqPcQK8dMke+UrsLl2fteupfP2jKcs3ewVxzpL0TAfC7IvFGDw4gooZwNe+N + L5P0n/K4yVK6Ouymzm8S2mOHWqugn3oe/nAPPDm52ssYihsgV5gznNC5b/4KATgO+FBk + RReg== +X-Gm-Message-State: AOJu0YyskV7DXC/Twt8l43zTuJ8mY6Lxbq7Wn1LUGjxdCAHVd6Pp+G2X + wv5SCmJLO+k7HmGs9EQXi0iUqgPguLagFG3om11VmAyZN/LWOak8ZuTqkw== +X-Google-Smtp-Source: AGHT+IGxhE1Cl1RmgUmVjjxB8DRIEcLHSK6wwj7AvB7m71FhU1F5ULTT6EKp3iCiW7/RsIjzrA3R9Q== +X-Received: by 2002:a05:600c:510d:b0:42c:bd4d:e8ba with SMTP id 5b1f17b1804b1-4311ded1c9dmr29928245e9.8.1728679905051; + Fri, 11 Oct 2024 13:51:45 -0700 (PDT) +Received: from [192.168.0.50] ([79.113.150.231]) + by smtp.gmail.com with ESMTPSA id 5b1f17b1804b1-430d748d421sm83211375e9.42.2024.10.11.13.51.43 + (version=TLS1_3 cipher=TLS_AES_128_GCM_SHA256 bits=128/128); + Fri, 11 Oct 2024 13:51:44 -0700 (PDT) +Message-ID: <92c49ebb-0408-48e7-9025-566ada0197b0@gmail.com> +Date: Fri, 11 Oct 2024 23:51:43 +0300 +Precedence: bulk +X-Mailing-List: linux-wireless@vger.kernel.org +List-Id: +List-Subscribe: +List-Unsubscribe: +MIME-Version: 1.0 +User-Agent: Mozilla Thunderbird +Subject: [PATCH v2 11/22] wifi: rtw88: usb: Set pkt_info.ls for the reserved + page +From: Bitterblue Smith +To: "linux-wireless@vger.kernel.org" +Cc: Ping-Ke Shih +References: +Content-Language: en-US +In-Reply-To: +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 7bit + +"ls" meaning "last segment". Without this RTL8812AU can't upload the +reserved page in USB 2 mode. (Somehow it's fine in USB 3 mode.) + +Signed-off-by: Bitterblue Smith +--- +v2: + - No change. +--- + drivers/net/wireless/realtek/rtw88/usb.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/drivers/net/wireless/realtek/rtw88/usb.c b/drivers/net/wireless/realtek/rtw88/usb.c +index a3d2b40ec67b..6fa3c37205f5 100644 +--- a/drivers/net/wireless/realtek/rtw88/usb.c ++++ b/drivers/net/wireless/realtek/rtw88/usb.c +@@ -478,6 +478,7 @@ static int rtw_usb_write_data_rsvd_page(struct rtw_dev *rtwdev, u8 *buf, + pkt_info.tx_pkt_size = size; + pkt_info.qsel = TX_DESC_QSEL_BEACON; + pkt_info.offset = chip->tx_pkt_desc_sz; ++ pkt_info.ls = true; + + return rtw_usb_write_data(rtwdev, &pkt_info, buf); + } +-- +2.46.0 + + +From mboxrd@z Thu Jan 1 00:00:00 1970 +Received: from mail-wr1-f50.google.com (mail-wr1-f50.google.com [209.85.221.50]) + (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) + (No client certificate requested) + by smtp.subspace.kernel.org (Postfix) with ESMTPS id ED3011D151F + for ; Fri, 11 Oct 2024 20:52:16 +0000 (UTC) +Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.221.50 +ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; + t=1728679938; cv=none; b=JGLOq4iIRfelsKUezE6yT/gh8o/Krx+ygKamXp8kRNEWmm7uzhJrpiTloZ6ZNdq33fGk095ZFkFzCoM89mtBFM4DVryxqg8NXgyKYBWKweSaj7YMyZc2L7SUtzdQXZrr7u5/7UkgkyaRrxMezkVLCjSQU2/vToXBidCnpKUfReU= +ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; + s=arc-20240116; t=1728679938; c=relaxed/simple; + bh=HlFUS57sNR9PPpSArrDhNs9SnDsLMQFc9/BKQfqrOHo=; + h=Message-ID:Date:MIME-Version:Subject:From:To:Cc:References: + In-Reply-To:Content-Type; b=qnZwdZjBlG56JNuBMdcWBNdHuNZav6GjCa+jzTYZ+IfjZ/6MQaFFnU8sCqEo+zvcGuV/49RydbxfjjV+RljNSCsxxDQBS5bQyMjR6OF2bT9OkUO49tJUy90DPxolMFLbGRjYBJabh5MFXatPs/EcuHKZf9j9CXfU2szqslU53Uw= +ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=EzJG37kM; arc=none smtp.client-ip=209.85.221.50 +Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com +Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com +Authentication-Results: smtp.subspace.kernel.org; + dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="EzJG37kM" +Received: by mail-wr1-f50.google.com with SMTP id ffacd0b85a97d-37d41894a32so1577734f8f.1 + for ; Fri, 11 Oct 2024 13:52:16 -0700 (PDT) +DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; + d=gmail.com; s=20230601; t=1728679935; x=1729284735; darn=vger.kernel.org; + h=content-transfer-encoding:in-reply-to:content-language:references + :cc:to:from:subject:user-agent:mime-version:date:message-id:from:to + :cc:subject:date:message-id:reply-to; + bh=e+bLQzUj6BJjH3Gvj1ZoTxcYyUw2gto/CjkJZSUvgnU=; + b=EzJG37kMJTkRPWrd/FM3PIQhYJZrj0BGAH//fELS0TytghIs3fH3JjCNrENYi6XE4F + 7hmzb2+P6QFF8/Cf8eK+cyNHJIsvlmIAvxHkoPsMHGtRzHgpKsBuhxqnt0ToixU5mOIE + m0cljCrI1iLWa4ZiTP+cHFQIol1qBPVpMCPz0z7rnMZFNnPm2eejazzTn0xnJMdXlZYi + ynxquQB+PZO/qCp8pfO1QAqK3ICzQJThtGLUHJVYF4HV1Ea2mGj0kgybFcH/Pd9N+4aV + /Y9a3VICpwvnhISgI2Rh0A00tXPUvL6MH9WjBSyRLEKy5qBfRyAUpzT0LQdIz124T5Lu + ECeQ== +X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; + d=1e100.net; s=20230601; t=1728679935; x=1729284735; + h=content-transfer-encoding:in-reply-to:content-language:references + :cc:to:from:subject:user-agent:mime-version:date:message-id + :x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; + bh=e+bLQzUj6BJjH3Gvj1ZoTxcYyUw2gto/CjkJZSUvgnU=; + b=xSO519jX8aecZc5qyAQVyBY/pjQFjlSqtZ4hzSmEQGUP8EgQde3E5Fw91QaubUOfeV + Ijs5deoG0wA+YxWNrDRSPUdJ+ncWyh3TRvIgn9krusWMHDaibsJ0edSL9xehXxQqtjvu + tCvicdBBt7GQ9BhCqs8tl6y3ylyrZXhYlxyeB1vo/q5cpoRcPXH4TapPx7dFwa6FvZbX + MaAcghvp0VdKN/doRee6YulE/GsJTq5ssvZnudj7L/bZPK47uZe4+qghCgNPkLG8rEWY + 5vxYil/aou5TdeZU/x+lvNXRc3QW3NvGJ2PvhhMnLVbqtJivlmyPChEw7f8dLPgLrwxg + bXMw== +X-Gm-Message-State: AOJu0YwSpxzSFRHvtd0z8XYFJSqVevdgWazwLuuttz5VJP1kPDOO2Eof + PjPq1xHIEzLnQkmOMrGN0ovuHpKVIwuGiv3p20ZFC6Izo3vHhddy3FWBWw== +X-Google-Smtp-Source: AGHT+IF5Bd495GoXMO2ThsFKzwIQkR/rfo0NwD0kEhhh+Wp0Q/PxZe7TWmpOK/L+W0Gjckv5mF/kgQ== +X-Received: by 2002:adf:cf03:0:b0:37c:c9bc:1be6 with SMTP id ffacd0b85a97d-37d48194896mr6585668f8f.16.1728679935246; + Fri, 11 Oct 2024 13:52:15 -0700 (PDT) +Received: from [192.168.0.50] ([79.113.150.231]) + by smtp.gmail.com with ESMTPSA id 5b1f17b1804b1-430ccf45e3bsm82969205e9.15.2024.10.11.13.52.13 + (version=TLS1_3 cipher=TLS_AES_128_GCM_SHA256 bits=128/128); + Fri, 11 Oct 2024 13:52:14 -0700 (PDT) +Message-ID: +Date: Fri, 11 Oct 2024 23:52:13 +0300 +Precedence: bulk +X-Mailing-List: linux-wireless@vger.kernel.org +List-Id: +List-Subscribe: +List-Unsubscribe: +MIME-Version: 1.0 +User-Agent: Mozilla Thunderbird +Subject: [PATCH v2 12/22] wifi: rtw88: Detect beacon loss with chips other + than 8822c +From: Bitterblue Smith +To: "linux-wireless@vger.kernel.org" +Cc: Ping-Ke Shih +References: +Content-Language: en-US +In-Reply-To: +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 7bit + +The driver is supposed to avoid entering LPS (power saving) when there +is beacon loss, but only RTL8822C detects the beacon loss (because it +has beacon filtering in the firmware). + +Detect beacon loss with the other chips by checking if we received less +than half the expected number of beacons in the last 2-second interval. + +This gets rid of the occasional "failed to get tx report from firmware" +warnings with RTL8821AU. It may also avoid some disconnections. + +Signed-off-by: Bitterblue Smith +--- +v2: + - Move beacon loss checking to separate function. + - Move variable declaration to the top. +--- + drivers/net/wireless/realtek/rtw88/main.c | 18 ++++++++++++++++++ + 1 file changed, 18 insertions(+) + +diff --git a/drivers/net/wireless/realtek/rtw88/main.c b/drivers/net/wireless/realtek/rtw88/main.c +index e6f985a92019..65d20ad02667 100644 +--- a/drivers/net/wireless/realtek/rtw88/main.c ++++ b/drivers/net/wireless/realtek/rtw88/main.c +@@ -202,6 +202,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 + */ +@@ -212,6 +227,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; + +@@ -270,6 +286,8 @@ static void rtw_watch_dog_work(struct work_struct *work) + */ + rtw_iterate_vifs(rtwdev, rtw_vif_watch_dog_iter, &data); + ++ 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 + * lps, because fw does not handle the overlapped beacon interval +-- +2.46.0 + + +From mboxrd@z Thu Jan 1 00:00:00 1970 +Received: from mail-wm1-f41.google.com (mail-wm1-f41.google.com [209.85.128.41]) + (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) + (No client certificate requested) + by smtp.subspace.kernel.org (Postfix) with ESMTPS id 839AB199231 + for ; Fri, 11 Oct 2024 20:53:01 +0000 (UTC) +Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.128.41 +ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; + t=1728679983; cv=none; b=QOD8kgjFWHIIEoSyOI5kGMhSffps5/qfG3u8gPJ4BMFiIlda/F1BdEzbeJhLfT+5OFN/8zBqHZeOWImkGi0612exdUoxsW6U8p/uNRWyThtCb0a1UxdIKHyRcOjiFKUdTNlesYVHldKuDQDscl19yeYy4ygHGfWKdD5A6EwBaY0= +ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; + s=arc-20240116; t=1728679983; c=relaxed/simple; + bh=R+EYqRAS4lq5erX55FzfU31qPxPT8FI3bC9B+T8HOdg=; + h=Message-ID:Date:MIME-Version:Subject:From:To:Cc:References: + In-Reply-To:Content-Type; b=ROdqmv/TqeJLvCC06X+M1ncu02354FDt+BlvibkOkkBpGJTBeSC5gz3fPD9QXohq2XR7P7E6/TjQSirZ5sPKssBXkoFnISNo36MG/UlU749Ef/jt+4OTfHQdub3J5ceoog104u+DgXDldGEwDrlTlVphUQo6JotLHAS7mEJtisE= +ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=aL3xUbiR; arc=none smtp.client-ip=209.85.128.41 +Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com +Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com +Authentication-Results: smtp.subspace.kernel.org; + dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="aL3xUbiR" +Received: by mail-wm1-f41.google.com with SMTP id 5b1f17b1804b1-43115b31366so20855325e9.3 + for ; Fri, 11 Oct 2024 13:53:01 -0700 (PDT) +DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; + d=gmail.com; s=20230601; t=1728679980; x=1729284780; darn=vger.kernel.org; + h=content-transfer-encoding:in-reply-to:content-language:references + :cc:to:from:subject:user-agent:mime-version:date:message-id:from:to + :cc:subject:date:message-id:reply-to; + bh=cM4uzy8R8NGb2a4b5C0gzPLbc4dyoM4yonUjKcNSTHA=; + b=aL3xUbiRCykFM8G/j5r94zhH58QT97VENeoXBXA6o55/hIDoje87zx/HQs8jYLq2Pi + ApLb1SocQkXcXiraqvFya5W7iNWMorhy1N24/EdQ4IoHLhp/fKrSuN8C2q+tV0Bsu6vt + 6lzS2zmZQd8yLAKS7ye0nh4VcQ11y/btGTMfglIXAJ+nUnSQmTQtE1AoarIkSFlMr8yD + THoa1+qUsJAQCtJNuT6LeD0ZJVoIPHxpIQqGQr1pkP8+z9hPN2RkWbfSPdhCwuEVz+mb + rVVhexjrbgS9qONXU9vJR61pSB8OeN7jK6xCtZV3ZjSa/xVupx+qi3uf7ELbRSVAzVS6 + ArvQ== +X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; + d=1e100.net; s=20230601; t=1728679980; x=1729284780; + h=content-transfer-encoding:in-reply-to:content-language:references + :cc:to:from:subject:user-agent:mime-version:date:message-id + :x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; + bh=cM4uzy8R8NGb2a4b5C0gzPLbc4dyoM4yonUjKcNSTHA=; + b=vya1LXZeqQ4dfxEHD/xyDTCHL9skZVNJOzA85NWvWlj/7dPEDHMk2CQO+BnkQZd0aw + cCS7/rRF1ViLIVy1nFbilixbphXsG271cdswE2/FAbpWucRV2Bym1S8XYTmOm1sQ6Sd6 + UhiCWGk0QFR2xwoMXN81B0LC88uCJL9r2QC8Gw6YHjAaJzM9yEmg7kGq/aZPk+3mrPfN + RzpBFGS0KZBjJI18/MJjuU7z6uoHzrW1MKj657SN0RRrRFVVY7XkX4n/v+YbuoPvo+Hh + a6vbTwEDq1LuBoeQ6v9i371jMU0fJiBrWnEBFe4728jzhQ7sZ/A1I2tixUYU+nmjRSFK + QHEg== +X-Gm-Message-State: AOJu0YwtmqQ0t/filcxvrj0BHZlD9Vo4VPF3l5e+HoSBsT6IZCJRAhKr + N7InwrlrceK56uaKleyZSbH4zPdXAXTJ95aZc+ksrCg1+bYcK472H70V7w== +X-Google-Smtp-Source: AGHT+IF8DYTmqXZbALRL0RFrDzwGAg/V5aBPGDRNpltn+WakIfeMwSCjoIzLsxqW4FhmZLyAwFUxPg== +X-Received: by 2002:a05:600c:4e8e:b0:42b:8a35:1acf with SMTP id 5b1f17b1804b1-4311df1e45cmr31787145e9.25.1728679979678; + Fri, 11 Oct 2024 13:52:59 -0700 (PDT) +Received: from [192.168.0.50] ([79.113.150.231]) + by smtp.gmail.com with ESMTPSA id ffacd0b85a97d-37d4b6bd399sm4704226f8f.26.2024.10.11.13.52.58 + (version=TLS1_3 cipher=TLS_AES_128_GCM_SHA256 bits=128/128); + Fri, 11 Oct 2024 13:52:58 -0700 (PDT) +Message-ID: +Date: Fri, 11 Oct 2024 23:52:57 +0300 +Precedence: bulk +X-Mailing-List: linux-wireless@vger.kernel.org +List-Id: +List-Subscribe: +List-Unsubscribe: +MIME-Version: 1.0 +User-Agent: Mozilla Thunderbird +Subject: [PATCH v2 13/22] wifi: rtw88: coex: Support chips without a + scoreboard +From: Bitterblue Smith +To: "linux-wireless@vger.kernel.org" +Cc: Ping-Ke Shih +References: +Content-Language: en-US +In-Reply-To: +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 7bit + +All the chips currently supported have a "scoreboard": the chip keeps +track of certain things related to bluetooth, for example, whether +bluetooth is active. The information can be read from register 0xaa. + +RTL8821AU doesn't have this. Implement bluetooth activity detection in +rtw_coex_monitor_bt_enable() based on the bluetooth TX/RX counters. + +This is mostly important for RTL8811AU, the version of RTL8821AU without +bluetooth. Without this change, the driver thinks bluetooth is active +and the wifi speeds are low. + +Signed-off-by: Bitterblue Smith +--- +v2: + - No change. +--- + drivers/net/wireless/realtek/rtw88/coex.c | 18 ++++++++++++++++++ + drivers/net/wireless/realtek/rtw88/main.h | 1 + + 2 files changed, 19 insertions(+) + +diff --git a/drivers/net/wireless/realtek/rtw88/coex.c b/drivers/net/wireless/realtek/rtw88/coex.c +index 8c5aec744f3c..8f2b472589db 100644 +--- a/drivers/net/wireless/realtek/rtw88/coex.c ++++ b/drivers/net/wireless/realtek/rtw88/coex.c +@@ -494,11 +494,29 @@ static void rtw_coex_monitor_bt_enable(struct rtw_dev *rtwdev) + struct rtw_coex_stat *coex_stat = &coex->stat; + struct rtw_coex_dm *coex_dm = &coex->dm; + bool bt_disabled = false; ++ bool bt_active = true; + u16 score_board; + + if (chip->scbd_support) { + score_board = rtw_coex_read_scbd(rtwdev); + bt_disabled = !(score_board & COEX_SCBD_ONOFF); ++ } else { ++ if (coex_stat->hi_pri_tx == 0 && coex_stat->hi_pri_rx == 0 && ++ coex_stat->lo_pri_tx == 0 && coex_stat->lo_pri_rx == 0) ++ bt_active = false; ++ ++ if (coex_stat->hi_pri_tx == 0xffff && coex_stat->hi_pri_rx == 0xffff && ++ coex_stat->lo_pri_tx == 0xffff && coex_stat->lo_pri_rx == 0xffff) ++ bt_active = false; ++ ++ if (bt_active) { ++ coex_stat->bt_disable_cnt = 0; ++ bt_disabled = false; ++ } else { ++ coex_stat->bt_disable_cnt++; ++ if (coex_stat->bt_disable_cnt >= 10) ++ bt_disabled = true; ++ } + } + + if (coex_stat->bt_disabled != bt_disabled) { +diff --git a/drivers/net/wireless/realtek/rtw88/main.h b/drivers/net/wireless/realtek/rtw88/main.h +index 072d09a7d313..545e91d6f4c1 100644 +--- a/drivers/net/wireless/realtek/rtw88/main.h ++++ b/drivers/net/wireless/realtek/rtw88/main.h +@@ -1494,6 +1494,7 @@ struct rtw_coex_stat { + u8 bt_hid_slot; + u8 bt_a2dp_bitpool; + u8 bt_iqk_state; ++ u8 bt_disable_cnt; + + u16 wl_beacon_interval; + u8 wl_noisy_level; +-- +2.46.0 + + +From mboxrd@z Thu Jan 1 00:00:00 1970 +Received: from mail-wm1-f44.google.com (mail-wm1-f44.google.com [209.85.128.44]) + (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) + (No client certificate requested) + by smtp.subspace.kernel.org (Postfix) with ESMTPS id 3CAC5199231 + for ; Fri, 11 Oct 2024 20:53:33 +0000 (UTC) +Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.128.44 +ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; + t=1728680014; cv=none; b=kbCOAZE9qDNXT3/oYkKBQbTqcKj3I0Z6awx2j7xsWqJrjGUSBTOPFOZ8ewuyRBhiAPxDA6YYC2dq7OucL8w3IxTdqCg95FEQ0FfjyYtHu0BS31VyucOuTHvcomL0LtgT5Vh03cK63J8vGN+mfz4r+jlByfekMQqIlbh/1X+uXsM= +ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; + s=arc-20240116; t=1728680014; c=relaxed/simple; + bh=Yh3QND2ONKRRpAr7unW0BFy/q1zwLJJUteuEt/ESh50=; + h=Message-ID:Date:MIME-Version:Subject:From:To:Cc:References: + In-Reply-To:Content-Type; b=j9m08d3MlIotWxrIh1F1R0m7aLdY3OITgS9hqIpjJVt/yH5WJRfTVHR0B1c0nw9rg+hzHWHSSEza//yd9ZYDyzmYPVfWTpuX/oOQXQ0EWMX0W5GXZlZnyUe2r4xSSJycd7AxHaDATh3tFHRwu5ajT7XutTPWqmJzBMt3EleRpNg= +ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=GWxLreDk; arc=none smtp.client-ip=209.85.128.44 +Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com +Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com +Authentication-Results: smtp.subspace.kernel.org; + dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="GWxLreDk" +Received: by mail-wm1-f44.google.com with SMTP id 5b1f17b1804b1-43115887867so16112325e9.0 + for ; Fri, 11 Oct 2024 13:53:33 -0700 (PDT) +DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; + d=gmail.com; s=20230601; t=1728680011; x=1729284811; darn=vger.kernel.org; + h=content-transfer-encoding:in-reply-to:content-language:references + :cc:to:from:subject:user-agent:mime-version:date:message-id:from:to + :cc:subject:date:message-id:reply-to; + bh=Jb2eulFW0qQPVkTTkL64Ef4nlQZ1RCYh9+vd/7IThWo=; + b=GWxLreDkoFHVE8PSS0fDI69rvSKXYALY7vI9CE7W/fY11LnKMOt8ksmRHfyURRuolv + mb6jgNobaMEUin8WbDrLKwPkqnldCSL3AMPD7GjXijUeayIWHhrIRcC2Ij/UHMYzWZuH + 8yA3Corv0ie9aqD7vwU6GhdeUuaftVOk6L5CVzRR2zhNfLeSI1c0t0l1syzIGN2WqGU3 + BXu3bjBNXPnJmvhNq3+qMFfNM9RbRWbD3NsdZqaLwyo+XGZ7iu6lFh7lRD45Pn+/rJG1 + 3FnDM10VxawmNKpyMu0kEuITtHMm9QFw8IbuNwoWA6ZEquq9Q26B38HtbJ9+mAOLsdje + q5WA== +X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; + d=1e100.net; s=20230601; t=1728680011; x=1729284811; + h=content-transfer-encoding:in-reply-to:content-language:references + :cc:to:from:subject:user-agent:mime-version:date:message-id + :x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; + bh=Jb2eulFW0qQPVkTTkL64Ef4nlQZ1RCYh9+vd/7IThWo=; + b=r2VhSUVeT7g093MICQh+3rY3lRXkAl04DsQItqlAb7ZUxDhhSgdQKaFTRriEJph5oz + mVSh873c0ChMTye6U9Ronp87uSAuT+i8TQk/HxYwLhCkJD7qfdXDm9wjiMTCmSJC5J7l + lEtoTVR7dM6FjdP5DF6DrIKGfUrtlsTuXC9XJsZYdUmKMIfbzmRGkCQql24pmWoXxWPL + 0e/8dY8YCoDTYZXTRL/Y2HvSzd32rAVmMTuVSz7h1su99jIlwMT3uTPAkqabI1uLDrks + nyMZFGcLA+WLB4106ptswr7AZwv+cjphxIOuFQwWLiLFe0Z238fUgGTwGHN7CfrHqOhy + g6GQ== +X-Gm-Message-State: AOJu0YyMUmFbSXBNDEMvoeJdS/o1RFMTtbq5SVg7+Ag2OUsZ3RSuT4zb + HQ8WBjrh8x/9049To5EEwdHeb/s2LjighIeO4e9knBTa1PVlo+lQhZpH5g== +X-Google-Smtp-Source: AGHT+IEI+hximSFP5bM0qvg1eFlw3YtkrxgCRDf+g59usmGPWurFN83UMlMmstt329VnFSKCzv+IFA== +X-Received: by 2002:a05:600c:1c9f:b0:42c:ba81:117c with SMTP id 5b1f17b1804b1-4311d8914ecmr32904655e9.6.1728680011520; + Fri, 11 Oct 2024 13:53:31 -0700 (PDT) +Received: from [192.168.0.50] ([79.113.150.231]) + by smtp.gmail.com with ESMTPSA id 5b1f17b1804b1-431183062b5sm50630905e9.26.2024.10.11.13.53.29 + (version=TLS1_3 cipher=TLS_AES_128_GCM_SHA256 bits=128/128); + Fri, 11 Oct 2024 13:53:30 -0700 (PDT) +Message-ID: <99aeae82-64a2-41e7-8755-9b5973d796da@gmail.com> +Date: Fri, 11 Oct 2024 23:53:29 +0300 +Precedence: bulk +X-Mailing-List: linux-wireless@vger.kernel.org +List-Id: +List-Subscribe: +List-Unsubscribe: +MIME-Version: 1.0 +User-Agent: Mozilla Thunderbird +Subject: [PATCH v2 14/22] wifi: rtw88: 8821a: Regularly ask for BT info + updates +From: Bitterblue Smith +To: "linux-wireless@vger.kernel.org" +Cc: Ping-Ke Shih +References: +Content-Language: en-US +In-Reply-To: +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 7bit + +The RTL8821AU firmware sends C2H_BT_INFO by itself when bluetooth +headphones are connected, but not when they are disconnected. This leads +to the coexistence code still using the A2DP algorithm long after the +headphones are disconnected, which means the wifi speeds are much lower +than they should be. Work around this by asking for updates every two +seconds if the chip is RTL8821AU. + +Signed-off-by: Bitterblue Smith +--- +v2: + - Move the logic to a separate function and add a comment about it. +--- + drivers/net/wireless/realtek/rtw88/coex.c | 2 +- + drivers/net/wireless/realtek/rtw88/coex.h | 11 +++++++++++ + drivers/net/wireless/realtek/rtw88/main.c | 1 + + 3 files changed, 13 insertions(+), 1 deletion(-) + +diff --git a/drivers/net/wireless/realtek/rtw88/coex.c b/drivers/net/wireless/realtek/rtw88/coex.c +index 8f2b472589db..c929db1e53ca 100644 +--- a/drivers/net/wireless/realtek/rtw88/coex.c ++++ b/drivers/net/wireless/realtek/rtw88/coex.c +@@ -446,7 +446,7 @@ static void rtw_coex_check_rfk(struct rtw_dev *rtwdev) + } + } + +-static void rtw_coex_query_bt_info(struct rtw_dev *rtwdev) ++void rtw_coex_query_bt_info(struct rtw_dev *rtwdev) + { + struct rtw_coex *coex = &rtwdev->coex; + struct rtw_coex_stat *coex_stat = &coex->stat; +diff --git a/drivers/net/wireless/realtek/rtw88/coex.h b/drivers/net/wireless/realtek/rtw88/coex.h +index 57cf29da9ea4..c398be8391f7 100644 +--- a/drivers/net/wireless/realtek/rtw88/coex.h ++++ b/drivers/net/wireless/realtek/rtw88/coex.h +@@ -384,6 +384,7 @@ u32 rtw_coex_read_indirect_reg(struct rtw_dev *rtwdev, u16 addr); + void rtw_coex_write_indirect_reg(struct rtw_dev *rtwdev, u16 addr, + u32 mask, u32 val); + void rtw_coex_write_scbd(struct rtw_dev *rtwdev, u16 bitpos, bool set); ++void rtw_coex_query_bt_info(struct rtw_dev *rtwdev); + + void rtw_coex_bt_relink_work(struct work_struct *work); + void rtw_coex_bt_reenable_work(struct work_struct *work); +@@ -419,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/drivers/net/wireless/realtek/rtw88/main.c b/drivers/net/wireless/realtek/rtw88/main.c +index 65d20ad02667..e91530ed05a0 100644 +--- a/drivers/net/wireless/realtek/rtw88/main.c ++++ b/drivers/net/wireless/realtek/rtw88/main.c +@@ -274,6 +274,7 @@ static void rtw_watch_dog_work(struct work_struct *work) + rtw_leave_lps(rtwdev); + rtw_coex_wl_status_check(rtwdev); + rtw_coex_query_bt_hid_list(rtwdev); ++ rtw_coex_active_query_bt_info(rtwdev); + + rtw_phy_dynamic_mechanism(rtwdev); + +-- +2.46.0 + + +From mboxrd@z Thu Jan 1 00:00:00 1970 +Received: from mail-wm1-f42.google.com (mail-wm1-f42.google.com [209.85.128.42]) + (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) + (No client certificate requested) + by smtp.subspace.kernel.org (Postfix) with ESMTPS id E7CD9199231 + for ; Fri, 11 Oct 2024 20:54:11 +0000 (UTC) +Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.128.42 +ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; + t=1728680053; cv=none; b=drG9T1BSQvC9B0Vn6qAlCTBKCFuYEfY4Vdz2bdgvqWYz1POYc+4u7CewFRcuSiu+noUwa2tCGs1OrSiNq5fGrdHgAwAZJXEa3s5Z11ON4QStMguunfBmYoO00bwimvc/EHRnvAJNyv2hoDrvI3g/8QWSaIXSkkjZtFvrwvPAFeM= +ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; + s=arc-20240116; t=1728680053; c=relaxed/simple; + bh=mEmcWvGlSD91BMxg+Ysc8LAb2lNyAzUGJGh3c1DAE4g=; + h=Message-ID:Date:MIME-Version:Subject:From:To:Cc:References: + In-Reply-To:Content-Type; b=iFJQ4l10LgFyAKvHObq7JIk6J6/kDMV259u46BH+8RjF1rV6FSzktRkFf7K1FH4y7461UU7VpuduBjqYRggbtdmGFPNM0iMxZG3YciQO9UER+yHtY8jW1o1uyWLs8PR/8Gajm8avT6pQ+uHKVOrlJDIuCHgAJN1dkWdQLTqgotU= +ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=j3AZ9HNR; arc=none smtp.client-ip=209.85.128.42 +Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com +Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com +Authentication-Results: smtp.subspace.kernel.org; + dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="j3AZ9HNR" +Received: by mail-wm1-f42.google.com with SMTP id 5b1f17b1804b1-43058268d91so21422135e9.0 + for ; Fri, 11 Oct 2024 13:54:11 -0700 (PDT) +DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; + d=gmail.com; s=20230601; t=1728680050; x=1729284850; darn=vger.kernel.org; + h=content-transfer-encoding:in-reply-to:content-language:references + :cc:to:from:subject:user-agent:mime-version:date:message-id:from:to + :cc:subject:date:message-id:reply-to; + bh=NsAlEDexyNtIT3M8EZfMXluGWdnroVr4LIgIIYeep3k=; + b=j3AZ9HNRnpKDVCoxXUQKtxqKhNhqNTERLr4NHE5p9+oAmTAA6GxBq8A6d3O1kEahj3 + /JSDdCisYKfPsn6BiLldf+ZxoSUWhFlaIgEADrYkpyKrHKzqPTB25orAgWvGIdqs51g/ + 3LnGSKP/rtLkKZdI4nT5oW7ZCt0VzCg4eapy8uwFeaKeSyMzXQAVlc7VbvgkJ8SLgsvc + IknDzpN2Nq4XYynWuoaWBlxisG2Aoqch8vhG/3xk7q2D97OGUGfXYuUa+XRvgiTXsLxh + Hwx6VQfZKAkz9pcHixTMxgH2wDMmBb3F+uqUCWolYlpxC0kdc3EfUfEkoE40aLqbzHSx + pFIA== +X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; + d=1e100.net; s=20230601; t=1728680050; x=1729284850; + h=content-transfer-encoding:in-reply-to:content-language:references + :cc:to:from:subject:user-agent:mime-version:date:message-id + :x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; + bh=NsAlEDexyNtIT3M8EZfMXluGWdnroVr4LIgIIYeep3k=; + b=EwWg4Nn2BIegg8RKI9j+ECzH4KFSlld0zKvm+4BGSKVaZYNRutkcuJa4oBvzx9h6n7 + xIigUyfhfRMumrE55tiuSkebmi7EqMdsOCcUdooKoUmHetI0Vo07g1AWa5NjhMz4M/pc + 2iV599ym8fqyWIZQK4UYJnnmdnloaQlblEqIFZNOos3WBvKKfb+d+5xc9nDwKLU6+vaa + BzwbfTizCX8QE3Z5bf2jrhF1O3Q/2UyphS+K5IOeFGOZPsWwqn2e6g/HxuDlzvh9k6C/ + 2lJODCEvJQCzzcQj2HT99rG4m3zMhuxh03d7JT4avjJo4a6+Ydk8jYU/OqIScy41zCYM + efcA== +X-Gm-Message-State: AOJu0YwrOeLb6imOPYq045JefPiwfLEZ+UZP7eePuZIny/qRy7QECskE + DTaucBMeT0WUjWYsonvpiTh4EUFPyOa9hSlpBFcI+XRk4eX876JFyOuaTw== +X-Google-Smtp-Source: AGHT+IHFfpvvWI8UvynXeuNC9gOg21Hi44BjXHC4TnfhalZf94X0X/BKpLKdSuyV3ZlxiZPlqHg/rA== +X-Received: by 2002:a05:600c:470e:b0:42c:b3e5:f688 with SMTP id 5b1f17b1804b1-4311dea3d0cmr29358745e9.4.1728680050180; + Fri, 11 Oct 2024 13:54:10 -0700 (PDT) +Received: from [192.168.0.50] ([79.113.150.231]) + by smtp.gmail.com with ESMTPSA id 5b1f17b1804b1-430ccf51c69sm82807695e9.28.2024.10.11.13.54.08 + (version=TLS1_3 cipher=TLS_AES_128_GCM_SHA256 bits=128/128); + Fri, 11 Oct 2024 13:54:09 -0700 (PDT) +Message-ID: <0cb6b0b0-5ee9-42e7-97ac-deb630bd4bd0@gmail.com> +Date: Fri, 11 Oct 2024 23:54:08 +0300 +Precedence: bulk +X-Mailing-List: linux-wireless@vger.kernel.org +List-Id: +List-Subscribe: +List-Unsubscribe: +MIME-Version: 1.0 +User-Agent: Mozilla Thunderbird +Subject: [PATCH v2 15/22] wifi: rtw88: 8812a: Mitigate beacon loss +From: Bitterblue Smith +To: "linux-wireless@vger.kernel.org" +Cc: Ping-Ke Shih +References: +Content-Language: en-US +In-Reply-To: +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 7bit + +The RTL8812AU has a reception problem, maybe only in the 5 GHz band. +Sometimes, in some positions, it stops receiving anything even though +the distance to the AP is only ~3 meters and there are no obstacles. +Moving it a few centimeters fixes it. + +Switch the initial gain to maximum coverage when there is beacon loss. +This only helps sometimes. This is similar to what the official driver +does. + +Signed-off-by: Bitterblue Smith +--- +v2: + - No change. +--- + drivers/net/wireless/realtek/rtw88/phy.c | 7 +++++++ + 1 file changed, 7 insertions(+) + +diff --git a/drivers/net/wireless/realtek/rtw88/phy.c b/drivers/net/wireless/realtek/rtw88/phy.c +index db2aa0b8c327..7ee3da82e44d 100644 +--- a/drivers/net/wireless/realtek/rtw88/phy.c ++++ b/drivers/net/wireless/realtek/rtw88/phy.c +@@ -530,6 +530,13 @@ static void rtw_phy_dig(struct rtw_dev *rtwdev) + */ + rtw_phy_dig_recorder(dm_info, cur_igi, fa_cnt); + ++ /* 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) ++ cur_igi = DIG_CVRG_MIN; ++ + if (cur_igi != pre_igi) + rtw_phy_dig_write(rtwdev, cur_igi); + } +-- +2.46.0 + + +From mboxrd@z Thu Jan 1 00:00:00 1970 +Received: from mail-wm1-f47.google.com (mail-wm1-f47.google.com [209.85.128.47]) + (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) + (No client certificate requested) + by smtp.subspace.kernel.org (Postfix) with ESMTPS id 7631A1D1727 + for ; Fri, 11 Oct 2024 20:54:45 +0000 (UTC) +Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.128.47 +ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; + t=1728680090; cv=none; b=hQvuTOEfEbNY8VaLCzYEq6n3l9lYmKG6XWnQ9+nUfJBt1wl4poA5UPDPB0y8p1hKjn+xEEdkPptm31F3HgYChYlXZkMfnNQH3oSRKlE97F/CHCbhGzf1hnrs1UxLI5relPOYZ8FiTm2jGTX0lUv2OWJ8qixYrPohmSfS7g/wj2M= +ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; + s=arc-20240116; t=1728680090; c=relaxed/simple; + bh=u/lU8z1xJzqNjnCPBPRi6xjvLwba9q1swGoNB8n8hTY=; + h=Message-ID:Date:MIME-Version:Subject:From:To:Cc:References: + In-Reply-To:Content-Type; b=mkA6pNUuxJpbniOAZww4Fou6tdBoRqBVnYqIPaSHtAFti0bvrEK+w8UU5erlX488PEAmdV3nyHH1dfaSPULmaqOVCzmjjR1FnNoOvB3CxIDNa32F1nRjw8RLNe8arBtwxSY8cXHYRe5jRQBoaby/OCd/Kt/X/ffWpnO4Ex8bStA= +ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=hPp+dmsO; arc=none smtp.client-ip=209.85.128.47 +Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com +Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com +Authentication-Results: smtp.subspace.kernel.org; + dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="hPp+dmsO" +Received: by mail-wm1-f47.google.com with SMTP id 5b1f17b1804b1-43111cff9d3so18047935e9.1 + for ; Fri, 11 Oct 2024 13:54:45 -0700 (PDT) +DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; + d=gmail.com; s=20230601; t=1728680084; x=1729284884; darn=vger.kernel.org; + h=content-transfer-encoding:in-reply-to:content-language:references + :cc:to:from:subject:user-agent:mime-version:date:message-id:from:to + :cc:subject:date:message-id:reply-to; + bh=pELiXWMTrTNVnPSZlRoJputgRxlkn0iN0iJRdLtcbU0=; + b=hPp+dmsOYrrqR+RkvqMGfNl+Wh6f3O16B2bG38IZDhgc7et+sEYwq7xG71nYCza8Td + O/NngOFk/GY2bcVtlYuEAr49f9bm8Wqu62eA/S9qhvJKSuuPDIJazKXk81ucP6PL67C1 + 1nwjphwksInnvXXDF365m52Rl3HFl6BINMfVvBfkt3UN+fpGpEUaXIYm8S4ouLxTfpfp + Ep9ck7Snrog37CMyX5Yj1zHM7xymVEFINSjilFfbhRrY0ItPRL/tb4QmxBoSRuF2y11g + 8qG0hWiNTXgoCecO2LwycB5uTB1h3zQr9+VrL7Zn34myt4lT165T0dmcG7IX13OgtqaE + Nn6g== +X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; + d=1e100.net; s=20230601; t=1728680084; x=1729284884; + h=content-transfer-encoding:in-reply-to:content-language:references + :cc:to:from:subject:user-agent:mime-version:date:message-id + :x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; + bh=pELiXWMTrTNVnPSZlRoJputgRxlkn0iN0iJRdLtcbU0=; + b=AD5pLizCWpoME+Dijgu/uWllYSHND35ZwDdsJufNFD87HfxEo9FHcD0PcXsvezCRC/ + /aaBRSKy5BczGXWlgkSuxVE2kUZ2sSeQn4CbStaEa0e9ClPLai7Dicvp/wsZMYu+NlCL + JchcHg2klIyIVCQ97UPsv3Q4cemMY6/gbdIYqRXSr3iUoc4vDBOoy3UJpmvs74hjMcmn + jBRT2uy42xH+LcDYoU6tO47+9iXY/NgccwtpJ/bM75eyAxYODViMsLkWBPPlyMOxCnS3 + qZ+aQ9s3NohPK+DBulo62JvZyE4mycBpMGb17lJV3mAQV8qozClilBDpOqiH0hiwrqcw + IS9g== +X-Gm-Message-State: AOJu0YyWwwtTQNrjcvqC/V01dQv7xu0935LKRlOm/ONjI4QaDt2/Zijc + 5AXRZ2jKfGY1uwnpNKykvvM/xXz8ZxyF2TaYoowVSmQ1R+d2+iqj7KCGTA== +X-Google-Smtp-Source: AGHT+IHgjDbP6uERTdks9vjL2UgwPml6sgY5ptyu6TCpP092kE4aOlLJh2oHO9t+M3lPRcRNxfvICw== +X-Received: by 2002:a05:600c:c0d:b0:42f:7e87:3438 with SMTP id 5b1f17b1804b1-4311de0041fmr29100625e9.0.1728680083129; + Fri, 11 Oct 2024 13:54:43 -0700 (PDT) +Received: from [192.168.0.50] ([79.113.150.231]) + by smtp.gmail.com with ESMTPSA id 5b1f17b1804b1-4311835687bsm51168095e9.34.2024.10.11.13.54.41 + (version=TLS1_3 cipher=TLS_AES_128_GCM_SHA256 bits=128/128); + Fri, 11 Oct 2024 13:54:42 -0700 (PDT) +Message-ID: <5ec06119-9c5c-4d02-8497-d057f9bedb4c@gmail.com> +Date: Fri, 11 Oct 2024 23:54:41 +0300 +Precedence: bulk +X-Mailing-List: linux-wireless@vger.kernel.org +List-Id: +List-Subscribe: +List-Unsubscribe: +MIME-Version: 1.0 +User-Agent: Mozilla Thunderbird +Subject: [PATCH v2 16/22] wifi: rtw88: Add rtw8812a_table.{c,h} +From: Bitterblue Smith +To: "linux-wireless@vger.kernel.org" +Cc: Ping-Ke Shih +References: +Content-Language: en-US +In-Reply-To: +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 7bit + +These contain various arrays for initialising RTL8812AU. Also TX power +limits. + +Signed-off-by: Bitterblue Smith +--- +v2: + - Constify card_enable_flow_8812a, enter_lps_flow_8812a, + card_disable_flow_8812a. + - Fix copyright year. +--- + .../wireless/realtek/rtw88/rtw8812a_table.c | 2812 +++++++++++++++++ + .../wireless/realtek/rtw88/rtw8812a_table.h | 26 + + 2 files changed, 2838 insertions(+) + create mode 100644 drivers/net/wireless/realtek/rtw88/rtw8812a_table.c + create mode 100644 drivers/net/wireless/realtek/rtw88/rtw8812a_table.h + +diff --git a/drivers/net/wireless/realtek/rtw88/rtw8812a_table.c b/drivers/net/wireless/realtek/rtw88/rtw8812a_table.c +new file mode 100644 +index 000000000000..048efbbd49ed +--- /dev/null ++++ b/drivers/net/wireless/realtek/rtw88/rtw8812a_table.c +@@ -0,0 +1,2812 @@ ++// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause ++/* Copyright(c) 2024 Realtek Corporation ++ */ ++ ++#include "main.h" ++#include "phy.h" ++#include "rtw8812a_table.h" ++ ++static const u32 rtw8812a_mac[] = { ++ 0x010, 0x0000000C, ++ 0x80000200, 0x00000000, 0x40000000, 0x00000000, ++ 0x011, 0x00000066, ++ 0xA0000000, 0x00000000, ++ 0x011, 0x0000005A, ++ 0xB0000000, 0x00000000, ++ 0x025, 0x0000000F, ++ 0x072, 0x00000000, ++ 0x420, 0x00000080, ++ 0x428, 0x0000000A, ++ 0x429, 0x00000010, ++ 0x430, 0x00000000, ++ 0x431, 0x00000000, ++ 0x432, 0x00000000, ++ 0x433, 0x00000001, ++ 0x434, 0x00000002, ++ 0x435, 0x00000003, ++ 0x436, 0x00000005, ++ 0x437, 0x00000007, ++ 0x438, 0x00000000, ++ 0x439, 0x00000000, ++ 0x43A, 0x00000000, ++ 0x43B, 0x00000001, ++ 0x43C, 0x00000002, ++ 0x43D, 0x00000003, ++ 0x43E, 0x00000005, ++ 0x43F, 0x00000007, ++ 0x440, 0x0000005D, ++ 0x441, 0x00000001, ++ 0x442, 0x00000000, ++ 0x444, 0x00000010, ++ 0x445, 0x00000000, ++ 0x446, 0x00000000, ++ 0x447, 0x00000000, ++ 0x448, 0x00000000, ++ 0x449, 0x000000F0, ++ 0x44A, 0x0000000F, ++ 0x44B, 0x0000003E, ++ 0x44C, 0x00000010, ++ 0x44D, 0x00000000, ++ 0x44E, 0x00000000, ++ 0x44F, 0x00000000, ++ 0x450, 0x00000000, ++ 0x451, 0x000000F0, ++ 0x452, 0x0000000F, ++ 0x453, 0x00000000, ++ 0x45B, 0x00000080, ++ 0x460, 0x00000066, ++ 0x461, 0x00000066, ++ 0x4C8, 0x000000FF, ++ 0x4C9, 0x00000008, ++ 0x4CC, 0x000000FF, ++ 0x4CD, 0x000000FF, ++ 0x4CE, 0x00000001, ++ 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, ++ 0x525, 0x0000004F, ++ 0x550, 0x00000010, ++ 0x551, 0x00000010, ++ 0x559, 0x00000002, ++ 0x55C, 0x00000050, ++ 0x55D, 0x000000FF, ++ 0x604, 0x00000009, ++ 0x605, 0x00000030, ++ 0x607, 0x00000003, ++ 0x608, 0x0000000E, ++ 0x609, 0x0000002A, ++ 0x620, 0x000000FF, ++ 0x621, 0x000000FF, ++ 0x622, 0x000000FF, ++ 0x623, 0x000000FF, ++ 0x624, 0x000000FF, ++ 0x625, 0x000000FF, ++ 0x626, 0x000000FF, ++ 0x627, 0x000000FF, ++ 0x638, 0x00000050, ++ 0x63C, 0x0000000A, ++ 0x63D, 0x0000000A, ++ 0x63E, 0x0000000E, ++ 0x63F, 0x0000000E, ++ 0x640, 0x00000080, ++ 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, ++}; ++ ++RTW_DECL_TABLE_PHY_COND(rtw8812a_mac, rtw_phy_cfg_mac); ++ ++static const u32 rtw8812a_agc[] = { ++ 0x80000001, 0x00000000, 0x40000000, 0x00000000, ++ 0x81C, 0xFC000001, ++ 0x81C, 0xFB020001, ++ 0x81C, 0xFA040001, ++ 0x81C, 0xF9060001, ++ 0x81C, 0xF8080001, ++ 0x81C, 0xF70A0001, ++ 0x81C, 0xF60C0001, ++ 0x81C, 0xF50E0001, ++ 0x81C, 0xF4100001, ++ 0x81C, 0xF3120001, ++ 0x81C, 0xF2140001, ++ 0x81C, 0xF1160001, ++ 0x81C, 0xF0180001, ++ 0x81C, 0xEF1A0001, ++ 0x81C, 0xEE1C0001, ++ 0x81C, 0xED1E0001, ++ 0x81C, 0xEC200001, ++ 0x81C, 0xEB220001, ++ 0x81C, 0xEA240001, ++ 0x81C, 0xCD260001, ++ 0x81C, 0xCC280001, ++ 0x81C, 0xCB2A0001, ++ 0x81C, 0xCA2C0001, ++ 0x81C, 0xC92E0001, ++ 0x81C, 0xC8300001, ++ 0x81C, 0xA6320001, ++ 0x81C, 0xA5340001, ++ 0x81C, 0xA4360001, ++ 0x81C, 0xA3380001, ++ 0x81C, 0xA23A0001, ++ 0x81C, 0x883C0001, ++ 0x81C, 0x873E0001, ++ 0x81C, 0x86400001, ++ 0x81C, 0x85420001, ++ 0x81C, 0x84440001, ++ 0x81C, 0x83460001, ++ 0x81C, 0x82480001, ++ 0x81C, 0x814A0001, ++ 0x81C, 0x484C0001, ++ 0x81C, 0x474E0001, ++ 0x81C, 0x46500001, ++ 0x81C, 0x45520001, ++ 0x81C, 0x44540001, ++ 0x81C, 0x43560001, ++ 0x81C, 0x42580001, ++ 0x81C, 0x415A0001, ++ 0x81C, 0x255C0001, ++ 0x81C, 0x245E0001, ++ 0x81C, 0x23600001, ++ 0x81C, 0x22620001, ++ 0x81C, 0x21640001, ++ 0x81C, 0x21660001, ++ 0x81C, 0x21680001, ++ 0x81C, 0x216A0001, ++ 0x81C, 0x216C0001, ++ 0x81C, 0x216E0001, ++ 0x81C, 0x21700001, ++ 0x81C, 0x21720001, ++ 0x81C, 0x21740001, ++ 0x81C, 0x21760001, ++ 0x81C, 0x21780001, ++ 0x81C, 0x217A0001, ++ 0x81C, 0x217C0001, ++ 0x81C, 0x217E0001, ++ 0x90000001, 0x00000005, 0x40000000, 0x00000000, ++ 0x81C, 0xF9000001, ++ 0x81C, 0xF8020001, ++ 0x81C, 0xF7040001, ++ 0x81C, 0xF6060001, ++ 0x81C, 0xF5080001, ++ 0x81C, 0xF40A0001, ++ 0x81C, 0xF30C0001, ++ 0x81C, 0xF20E0001, ++ 0x81C, 0xF1100001, ++ 0x81C, 0xF0120001, ++ 0x81C, 0xEF140001, ++ 0x81C, 0xEE160001, ++ 0x81C, 0xED180001, ++ 0x81C, 0xEC1A0001, ++ 0x81C, 0xEB1C0001, ++ 0x81C, 0xEA1E0001, ++ 0x81C, 0xCD200001, ++ 0x81C, 0xCC220001, ++ 0x81C, 0xCB240001, ++ 0x81C, 0xCA260001, ++ 0x81C, 0xC9280001, ++ 0x81C, 0xC82A0001, ++ 0x81C, 0xC72C0001, ++ 0x81C, 0xC62E0001, ++ 0x81C, 0xA5300001, ++ 0x81C, 0xA4320001, ++ 0x81C, 0xA3340001, ++ 0x81C, 0xA2360001, ++ 0x81C, 0x88380001, ++ 0x81C, 0x873A0001, ++ 0x81C, 0x863C0001, ++ 0x81C, 0x853E0001, ++ 0x81C, 0x84400001, ++ 0x81C, 0x83420001, ++ 0x81C, 0x82440001, ++ 0x81C, 0x81460001, ++ 0x81C, 0x48480001, ++ 0x81C, 0x474A0001, ++ 0x81C, 0x464C0001, ++ 0x81C, 0x454E0001, ++ 0x81C, 0x44500001, ++ 0x81C, 0x43520001, ++ 0x81C, 0x42540001, ++ 0x81C, 0x41560001, ++ 0x81C, 0x25580001, ++ 0x81C, 0x245A0001, ++ 0x81C, 0x235C0001, ++ 0x81C, 0x225E0001, ++ 0x81C, 0x21600001, ++ 0x81C, 0x21620001, ++ 0x81C, 0x21640001, ++ 0x81C, 0x21660001, ++ 0x81C, 0x21680001, ++ 0x81C, 0x216A0001, ++ 0x81C, 0x236C0001, ++ 0x81C, 0x226E0001, ++ 0x81C, 0x21700001, ++ 0x81C, 0x21720001, ++ 0x81C, 0x21740001, ++ 0x81C, 0x21760001, ++ 0x81C, 0x21780001, ++ 0x81C, 0x217A0001, ++ 0x81C, 0x217C0001, ++ 0x81C, 0x217E0001, ++ 0xA0000000, 0x00000000, ++ 0x81C, 0xFF000001, ++ 0x81C, 0xFF020001, ++ 0x81C, 0xFF040001, ++ 0x81C, 0xFF060001, ++ 0x81C, 0xFF080001, ++ 0x81C, 0xFE0A0001, ++ 0x81C, 0xFD0C0001, ++ 0x81C, 0xFC0E0001, ++ 0x81C, 0xFB100001, ++ 0x81C, 0xFA120001, ++ 0x81C, 0xF9140001, ++ 0x81C, 0xF8160001, ++ 0x81C, 0xF7180001, ++ 0x81C, 0xF61A0001, ++ 0x81C, 0xF51C0001, ++ 0x81C, 0xF41E0001, ++ 0x81C, 0xF3200001, ++ 0x81C, 0xF2220001, ++ 0x81C, 0xF1240001, ++ 0x81C, 0xF0260001, ++ 0x81C, 0xEF280001, ++ 0x81C, 0xEE2A0001, ++ 0x81C, 0xED2C0001, ++ 0x81C, 0xEC2E0001, ++ 0x81C, 0xEB300001, ++ 0x81C, 0xEA320001, ++ 0x81C, 0xE9340001, ++ 0x81C, 0xE8360001, ++ 0x81C, 0xE7380001, ++ 0x81C, 0xE63A0001, ++ 0x81C, 0xE53C0001, ++ 0x81C, 0xC73E0001, ++ 0x81C, 0xC6400001, ++ 0x81C, 0xC5420001, ++ 0x81C, 0xC4440001, ++ 0x81C, 0xC3460001, ++ 0x81C, 0xC2480001, ++ 0x81C, 0xC14A0001, ++ 0x81C, 0xA74C0001, ++ 0x81C, 0xA64E0001, ++ 0x81C, 0xA5500001, ++ 0x81C, 0xA4520001, ++ 0x81C, 0xA3540001, ++ 0x81C, 0xA2560001, ++ 0x81C, 0xA1580001, ++ 0x81C, 0x675A0001, ++ 0x81C, 0x665C0001, ++ 0x81C, 0x655E0001, ++ 0x81C, 0x64600001, ++ 0x81C, 0x63620001, ++ 0x81C, 0x48640001, ++ 0x81C, 0x47660001, ++ 0x81C, 0x46680001, ++ 0x81C, 0x456A0001, ++ 0x81C, 0x446C0001, ++ 0x81C, 0x436E0001, ++ 0x81C, 0x42700001, ++ 0x81C, 0x41720001, ++ 0x81C, 0x41740001, ++ 0x81C, 0x41760001, ++ 0x81C, 0x41780001, ++ 0x81C, 0x417A0001, ++ 0x81C, 0x417C0001, ++ 0x81C, 0x417E0001, ++ 0xB0000000, 0x00000000, ++ 0x80000004, 0x00000000, 0x40000000, 0x00000000, ++ 0x81C, 0xFC800001, ++ 0x81C, 0xFB820001, ++ 0x81C, 0xFA840001, ++ 0x81C, 0xF9860001, ++ 0x81C, 0xF8880001, ++ 0x81C, 0xF78A0001, ++ 0x81C, 0xF68C0001, ++ 0x81C, 0xF58E0001, ++ 0x81C, 0xF4900001, ++ 0x81C, 0xF3920001, ++ 0x81C, 0xF2940001, ++ 0x81C, 0xF1960001, ++ 0x81C, 0xF0980001, ++ 0x81C, 0xEF9A0001, ++ 0x81C, 0xEE9C0001, ++ 0x81C, 0xED9E0001, ++ 0x81C, 0xECA00001, ++ 0x81C, 0xEBA20001, ++ 0x81C, 0xEAA40001, ++ 0x81C, 0xE9A60001, ++ 0x81C, 0xE8A80001, ++ 0x81C, 0xE7AA0001, ++ 0x81C, 0xE6AC0001, ++ 0x81C, 0xE5AE0001, ++ 0x81C, 0xE4B00001, ++ 0x81C, 0xE3B20001, ++ 0x81C, 0xA8B40001, ++ 0x81C, 0xA7B60001, ++ 0x81C, 0xA6B80001, ++ 0x81C, 0xA5BA0001, ++ 0x81C, 0xA4BC0001, ++ 0x81C, 0xA3BE0001, ++ 0x81C, 0xA2C00001, ++ 0x81C, 0xA1C20001, ++ 0x81C, 0x68C40001, ++ 0x81C, 0x67C60001, ++ 0x81C, 0x66C80001, ++ 0x81C, 0x65CA0001, ++ 0x81C, 0x64CC0001, ++ 0x81C, 0x47CE0001, ++ 0x81C, 0x46D00001, ++ 0x81C, 0x45D20001, ++ 0x81C, 0x44D40001, ++ 0x81C, 0x43D60001, ++ 0x81C, 0x42D80001, ++ 0x81C, 0x08DA0001, ++ 0x81C, 0x07DC0001, ++ 0x81C, 0x06DE0001, ++ 0x81C, 0x05E00001, ++ 0x81C, 0x04E20001, ++ 0x81C, 0x03E40001, ++ 0x81C, 0x02E60001, ++ 0x81C, 0x01E80001, ++ 0x81C, 0x01EA0001, ++ 0x81C, 0x01EC0001, ++ 0x81C, 0x01EE0001, ++ 0x81C, 0x01F00001, ++ 0x81C, 0x01F20001, ++ 0x81C, 0x01F40001, ++ 0x81C, 0x01F60001, ++ 0x81C, 0x01F80001, ++ 0x81C, 0x01FA0001, ++ 0x81C, 0x01FC0001, ++ 0x81C, 0x01FE0001, ++ 0xA0000000, 0x00000000, ++ 0x81C, 0xFF800001, ++ 0x81C, 0xFF820001, ++ 0x81C, 0xFF840001, ++ 0x81C, 0xFE860001, ++ 0x81C, 0xFD880001, ++ 0x81C, 0xFC8A0001, ++ 0x81C, 0xFB8C0001, ++ 0x81C, 0xFA8E0001, ++ 0x81C, 0xF9900001, ++ 0x81C, 0xF8920001, ++ 0x81C, 0xF7940001, ++ 0x81C, 0xF6960001, ++ 0x81C, 0xF5980001, ++ 0x81C, 0xF49A0001, ++ 0x81C, 0xF39C0001, ++ 0x81C, 0xF29E0001, ++ 0x81C, 0xF1A00001, ++ 0x81C, 0xF0A20001, ++ 0x81C, 0xEFA40001, ++ 0x81C, 0xEEA60001, ++ 0x81C, 0xEDA80001, ++ 0x81C, 0xECAA0001, ++ 0x81C, 0xEBAC0001, ++ 0x81C, 0xEAAE0001, ++ 0x81C, 0xE9B00001, ++ 0x81C, 0xE8B20001, ++ 0x81C, 0xE7B40001, ++ 0x81C, 0xE6B60001, ++ 0x81C, 0xE5B80001, ++ 0x81C, 0xE4BA0001, ++ 0x81C, 0xE3BC0001, ++ 0x81C, 0xA8BE0001, ++ 0x81C, 0xA7C00001, ++ 0x81C, 0xA6C20001, ++ 0x81C, 0xA5C40001, ++ 0x81C, 0xA4C60001, ++ 0x81C, 0xA3C80001, ++ 0x81C, 0xA2CA0001, ++ 0x81C, 0xA1CC0001, ++ 0x81C, 0x68CE0001, ++ 0x81C, 0x67D00001, ++ 0x81C, 0x66D20001, ++ 0x81C, 0x65D40001, ++ 0x81C, 0x64D60001, ++ 0x81C, 0x47D80001, ++ 0x81C, 0x46DA0001, ++ 0x81C, 0x45DC0001, ++ 0x81C, 0x44DE0001, ++ 0x81C, 0x43E00001, ++ 0x81C, 0x42E20001, ++ 0x81C, 0x08E40001, ++ 0x81C, 0x07E60001, ++ 0x81C, 0x06E80001, ++ 0x81C, 0x05EA0001, ++ 0x81C, 0x04EC0001, ++ 0x81C, 0x03EE0001, ++ 0x81C, 0x02F00001, ++ 0x81C, 0x01F20001, ++ 0x81C, 0x01F40001, ++ 0x81C, 0x01F60001, ++ 0x81C, 0x01F80001, ++ 0x81C, 0x01FA0001, ++ 0x81C, 0x01FC0001, ++ 0x81C, 0x01FE0001, ++ 0xB0000000, 0x00000000, ++ 0xC50, 0x00000022, ++ 0xC50, 0x00000020, ++ 0xE50, 0x00000022, ++ 0xE50, 0x00000020, ++}; ++ ++RTW_DECL_TABLE_PHY_COND(rtw8812a_agc, rtw_phy_cfg_agc); ++ ++static const u32 rtw8812a_agc_diff_lb[] = { ++ 0x80000004, 0x00000000, 0x40000000, 0x00000000, ++ 0x81C, 0x47CE0001, ++ 0x81C, 0x46D00001, ++ 0x81C, 0x45D20001, ++ 0x81C, 0x44D40001, ++ 0x81C, 0x43D60001, ++ 0x81C, 0x42D80001, ++ 0x81C, 0x08DA0001, ++ 0x81C, 0x07DC0001, ++ 0x81C, 0x06DE0001, ++ 0x81C, 0x05E00001, ++ 0x81C, 0x04E20001, ++ 0x81C, 0x03E40001, ++ 0x81C, 0x02E60001, ++ 0xA0000000, 0x00000000, ++ 0x81C, 0x47D80001, ++ 0x81C, 0x46DA0001, ++ 0x81C, 0x45DC0001, ++ 0x81C, 0x44DE0001, ++ 0x81C, 0x43E00001, ++ 0x81C, 0x42E20001, ++ 0x81C, 0x08E40001, ++ 0x81C, 0x07E60001, ++ 0x81C, 0x06E80001, ++ 0x81C, 0x05EA0001, ++ 0x81C, 0x04EC0001, ++ 0x81C, 0x03EE0001, ++ 0x81C, 0x02F00001, ++ 0xB0000000, 0x00000000, ++}; ++ ++RTW_DECL_TABLE_PHY_COND(rtw8812a_agc_diff_lb, rtw_phy_cfg_agc); ++ ++static const u32 rtw8812a_agc_diff_hb[] = { ++ 0x80000004, 0x00000000, 0x40000000, 0x00000000, ++ 0x81C, 0x45CE0001, ++ 0x81C, 0x44D00001, ++ 0x81C, 0x43D20001, ++ 0x81C, 0x42D40001, ++ 0x81C, 0x08D60001, ++ 0x81C, 0x07D80001, ++ 0x81C, 0x06DA0001, ++ 0x81C, 0x05DC0001, ++ 0x81C, 0x04DE0001, ++ 0x81C, 0x03E00001, ++ 0x81C, 0x02E20001, ++ 0x81C, 0x01E40001, ++ 0x81C, 0x01E60001, ++ 0xA0000000, 0x00000000, ++ 0x81C, 0x45D80001, ++ 0x81C, 0x44DA0001, ++ 0x81C, 0x43DC0001, ++ 0x81C, 0x42DE0001, ++ 0x81C, 0x08E00001, ++ 0x81C, 0x07E20001, ++ 0x81C, 0x06E40001, ++ 0x81C, 0x05E60001, ++ 0x81C, 0x04E80001, ++ 0x81C, 0x03EA0001, ++ 0x81C, 0x02EC0001, ++ 0x81C, 0x01EE0001, ++ 0x81C, 0x01F00001, ++ 0xB0000000, 0x00000000, ++}; ++ ++RTW_DECL_TABLE_PHY_COND(rtw8812a_agc_diff_hb, rtw_phy_cfg_agc); ++ ++static const u32 rtw8812a_bb[] = { ++ 0x800, 0x8020D010, ++ 0x804, 0x080112E0, ++ 0x808, 0x0E028233, ++ 0x80C, 0x12131113, ++ 0x810, 0x20101263, ++ 0x814, 0x020C3D10, ++ 0x818, 0x03A00385, ++ 0x820, 0x00000000, ++ 0x824, 0x00030FE0, ++ 0x828, 0x00000000, ++ 0x82C, 0x002083DD, ++ 0x830, 0x2EAAEEB8, ++ 0x834, 0x0037A706, ++ 0x838, 0x06C89B44, ++ 0x83C, 0x0000095B, ++ 0x840, 0xC0000001, ++ 0x844, 0x40003CDE, ++ 0x848, 0x6210FF8B, ++ 0x84C, 0x6CFDFFB8, ++ 0x850, 0x28874706, ++ 0x854, 0x0001520C, ++ 0x858, 0x8060E000, ++ 0x85C, 0x74210168, ++ 0x860, 0x6929C321, ++ 0x864, 0x79727432, ++ 0x868, 0x8CA7A314, ++ 0x86C, 0x338C2878, ++ 0x870, 0x03333333, ++ 0x874, 0x31602C2E, ++ 0x878, 0x00003152, ++ 0x87C, 0x000FC000, ++ 0x8A0, 0x00000013, ++ 0x8A4, 0x7F7F7F7F, ++ 0x8A8, 0xA202033E, ++ 0x8AC, 0x0FF0FA0A, ++ 0x8B0, 0x00000600, ++ 0x8B4, 0x000FC080, ++ 0x8B8, 0x6C10D7FF, ++ 0x8BC, 0x4CA520A3, ++ 0x8C0, 0x27F00020, ++ 0x8C4, 0x00000000, ++ 0x8C8, 0x00012D69, ++ 0x8CC, 0x08248492, ++ 0x8D0, 0x0000B800, ++ 0x8DC, 0x00000000, ++ 0x8D4, 0x940008A0, ++ 0x8D8, 0x290B5612, ++ 0x8F8, 0x400002C0, ++ 0x8FC, 0x00000000, ++ 0x900, 0x00000701, ++ 0x90C, 0x00000000, ++ 0x910, 0x0000FC00, ++ 0x914, 0x00000404, ++ 0x918, 0x1C1028C0, ++ 0x91C, 0x64B11A1C, ++ 0x920, 0xE0767233, ++ 0x924, 0x055AA500, ++ 0x928, 0x00000004, ++ 0x92C, 0xFFFE0000, ++ 0x930, 0xFFFFFFFE, ++ 0x934, 0x001FFFFF, ++ 0x960, 0x00000000, ++ 0x964, 0x00000000, ++ 0x968, 0x00000000, ++ 0x96C, 0x00000000, ++ 0x970, 0x801FFFFF, ++ 0x978, 0x00000000, ++ 0x97C, 0x00000000, ++ 0x980, 0x00000000, ++ 0x984, 0x00000000, ++ 0x988, 0x00000000, ++ 0x990, 0x27100000, ++ 0x994, 0xFFFF0100, ++ 0x998, 0xFFFFFF5C, ++ 0x99C, 0xFFFFFFFF, ++ 0x9A0, 0x000000FF, ++ 0x9A4, 0x00080080, ++ 0x9A8, 0x00000000, ++ 0x9AC, 0x00000000, ++ 0x9B0, 0x81081008, ++ 0x9B4, 0x00000000, ++ 0x9B8, 0x01081008, ++ 0x9BC, 0x01081008, ++ 0x9D0, 0x00000000, ++ 0x9D4, 0x00000000, ++ 0x9D8, 0x00000000, ++ 0x9DC, 0x00000000, ++ 0x9E4, 0x00000003, ++ 0x9E8, 0x000002D5, ++ 0xA00, 0x00D047C8, ++ 0xA04, 0x01FF000C, ++ 0xA08, 0x8C838300, ++ 0xA0C, 0x2E7F000F, ++ 0xA10, 0x9500BB78, ++ 0xA14, 0x11144028, ++ 0xA18, 0x00881117, ++ 0xA1C, 0x89140F00, ++ 0xA20, 0x1A1B0000, ++ 0xA24, 0x090E1217, ++ 0xA28, 0x00000305, ++ 0xA2C, 0x00900000, ++ 0xA70, 0x101FFF00, ++ 0xA74, 0x00000008, ++ 0xA78, 0x00000900, ++ 0xA7C, 0x225B0606, ++ 0xA80, 0x218075B2, ++ 0xA84, 0x001F8C80, ++ 0xB00, 0x03100000, ++ 0xB04, 0x0000B000, ++ 0xB08, 0xAE0201EB, ++ 0xB0C, 0x01003207, ++ 0xB10, 0x00009807, ++ 0xB14, 0x01000000, ++ 0xB18, 0x00000002, ++ 0xB1C, 0x00000002, ++ 0xB20, 0x0000001F, ++ 0xB24, 0x03020100, ++ 0xB28, 0x07060504, ++ 0xB2C, 0x0B0A0908, ++ 0xB30, 0x0F0E0D0C, ++ 0xB34, 0x13121110, ++ 0xB38, 0x17161514, ++ 0xB3C, 0x0000003A, ++ 0xB40, 0x00000000, ++ 0xB44, 0x00000000, ++ 0xB48, 0x13000032, ++ 0xB4C, 0x48080000, ++ 0xB50, 0x00000000, ++ 0xB54, 0x00000000, ++ 0xB58, 0x00000000, ++ 0xB5C, 0x00000000, ++ 0xC00, 0x00000007, ++ 0xC04, 0x00042020, ++ 0xC08, 0x80410231, ++ 0xC0C, 0x00000000, ++ 0xC10, 0x00000100, ++ 0xC14, 0x01000000, ++ 0xC1C, 0x40000003, ++ 0xC20, 0x12121212, ++ 0xC24, 0x12121212, ++ 0xC28, 0x12121212, ++ 0xC2C, 0x12121212, ++ 0xC30, 0x12121212, ++ 0xC34, 0x12121212, ++ 0xC38, 0x12121212, ++ 0xC3C, 0x12121212, ++ 0xC40, 0x12121212, ++ 0xC44, 0x12121212, ++ 0xC48, 0x12121212, ++ 0xC4C, 0x12121212, ++ 0xC50, 0x00000020, ++ 0xC54, 0x0008121C, ++ 0xC58, 0x30000C1C, ++ 0xC5C, 0x00000058, ++ 0xC60, 0x34344443, ++ 0xC64, 0x07003333, ++ 0x80000008, 0x00000000, 0x40000000, 0x00000000, ++ 0xC68, 0x59791979, ++ 0x90000008, 0x05000000, 0x40000000, 0x00000000, ++ 0xC68, 0x59791979, ++ 0x90000002, 0x00000000, 0x40000000, 0x00000000, ++ 0xC68, 0x59791979, ++ 0x90000004, 0x00000000, 0x40000000, 0x00000000, ++ 0xC68, 0x59791979, ++ 0x90000001, 0x00000000, 0x40000000, 0x00000000, ++ 0xC68, 0x59791979, ++ 0x90000001, 0x00000005, 0x40000000, 0x00000000, ++ 0xC68, 0x59791979, ++ 0xA0000000, 0x00000000, ++ 0xC68, 0x59799979, ++ 0xB0000000, 0x00000000, ++ 0xC6C, 0x59795979, ++ 0xC70, 0x19795979, ++ 0xC74, 0x19795979, ++ 0xC78, 0x19791979, ++ 0xC7C, 0x19791979, ++ 0xC80, 0x19791979, ++ 0xC84, 0x19791979, ++ 0xC94, 0x0100005C, ++ 0xC98, 0x00000000, ++ 0xC9C, 0x00000000, ++ 0xCA0, 0x00000029, ++ 0xCA4, 0x08040201, ++ 0xCA8, 0x80402010, ++ 0xCB0, 0x77547777, ++ 0xCB4, 0x00000077, ++ 0xCB8, 0x00508242, ++ 0xE00, 0x00000007, ++ 0xE04, 0x00042020, ++ 0xE08, 0x80410231, ++ 0xE0C, 0x00000000, ++ 0xE10, 0x00000100, ++ 0xE14, 0x01000000, ++ 0xE1C, 0x40000003, ++ 0xE20, 0x12121212, ++ 0xE24, 0x12121212, ++ 0xE28, 0x12121212, ++ 0xE2C, 0x12121212, ++ 0xE30, 0x12121212, ++ 0xE34, 0x12121212, ++ 0xE38, 0x12121212, ++ 0xE3C, 0x12121212, ++ 0xE40, 0x12121212, ++ 0xE44, 0x12121212, ++ 0xE48, 0x12121212, ++ 0xE4C, 0x12121212, ++ 0xE50, 0x00000020, ++ 0xE54, 0x0008121C, ++ 0xE58, 0x30000C1C, ++ 0xE5C, 0x00000058, ++ 0xE60, 0x34344443, ++ 0xE64, 0x07003333, ++ 0xE68, 0x59791979, ++ 0xE6C, 0x59795979, ++ 0xE70, 0x19795979, ++ 0xE74, 0x19795979, ++ 0xE78, 0x19791979, ++ 0xE7C, 0x19791979, ++ 0xE80, 0x19791979, ++ 0xE84, 0x19791979, ++ 0xE94, 0x0100005C, ++ 0xE98, 0x00000000, ++ 0xE9C, 0x00000000, ++ 0xEA0, 0x00000029, ++ 0xEA4, 0x08040201, ++ 0xEA8, 0x80402010, ++ 0xEB0, 0x77547777, ++ 0xEB4, 0x00000077, ++ 0xEB8, 0x00508242, ++}; ++ ++RTW_DECL_TABLE_PHY_COND(rtw8812a_bb, rtw_phy_cfg_bb); ++ ++static const struct rtw_phy_pg_cfg_pair rtw8812a_bb_pg[] = { ++ { 0, 0, 0, 0x00000c20, 0xffffffff, 0x34363840, }, ++ { 0, 0, 0, 0x00000c24, 0xffffffff, 0x42424444, }, ++ { 0, 0, 0, 0x00000c28, 0xffffffff, 0x30323638, }, ++ { 0, 0, 0, 0x00000c2c, 0xffffffff, 0x40424444, }, ++ { 0, 0, 0, 0x00000c30, 0xffffffff, 0x28303236, }, ++ { 0, 0, 1, 0x00000c34, 0xffffffff, 0x38404242, }, ++ { 0, 0, 1, 0x00000c38, 0xffffffff, 0x26283034, }, ++ { 0, 0, 0, 0x00000c3c, 0xffffffff, 0x40424444, }, ++ { 0, 0, 0, 0x00000c40, 0xffffffff, 0x28303236, }, ++ { 0, 0, 0, 0x00000c44, 0xffffffff, 0x42422426, }, ++ { 0, 0, 1, 0x00000c48, 0xffffffff, 0x30343840, }, ++ { 0, 0, 1, 0x00000c4c, 0xffffffff, 0x22242628, }, ++ { 0, 1, 0, 0x00000e20, 0xffffffff, 0x34363840, }, ++ { 0, 1, 0, 0x00000e24, 0xffffffff, 0x42424444, }, ++ { 0, 1, 0, 0x00000e28, 0xffffffff, 0x30323638, }, ++ { 0, 1, 0, 0x00000e2c, 0xffffffff, 0x40424444, }, ++ { 0, 1, 0, 0x00000e30, 0xffffffff, 0x28303236, }, ++ { 0, 1, 1, 0x00000e34, 0xffffffff, 0x38404242, }, ++ { 0, 1, 1, 0x00000e38, 0xffffffff, 0x26283034, }, ++ { 0, 1, 0, 0x00000e3c, 0xffffffff, 0x40424444, }, ++ { 0, 1, 0, 0x00000e40, 0xffffffff, 0x28303236, }, ++ { 0, 1, 0, 0x00000e44, 0xffffffff, 0x42422426, }, ++ { 0, 1, 1, 0x00000e48, 0xffffffff, 0x30343840, }, ++ { 0, 1, 1, 0x00000e4c, 0xffffffff, 0x22242628, }, ++ { 1, 0, 0, 0x00000c24, 0xffffffff, 0x42424444, }, ++ { 1, 0, 0, 0x00000c28, 0xffffffff, 0x30323640, }, ++ { 1, 0, 0, 0x00000c2c, 0xffffffff, 0x40424444, }, ++ { 1, 0, 0, 0x00000c30, 0xffffffff, 0x28303236, }, ++ { 1, 0, 1, 0x00000c34, 0xffffffff, 0x38404242, }, ++ { 1, 0, 1, 0x00000c38, 0xffffffff, 0x26283034, }, ++ { 1, 0, 0, 0x00000c3c, 0xffffffff, 0x40424444, }, ++ { 1, 0, 0, 0x00000c40, 0xffffffff, 0x28303236, }, ++ { 1, 0, 0, 0x00000c44, 0xffffffff, 0x42422426, }, ++ { 1, 0, 1, 0x00000c48, 0xffffffff, 0x30343840, }, ++ { 1, 0, 1, 0x00000c4c, 0xffffffff, 0x22242628, }, ++ { 1, 1, 0, 0x00000e24, 0xffffffff, 0x42424444, }, ++ { 1, 1, 0, 0x00000e28, 0xffffffff, 0x30323640, }, ++ { 1, 1, 0, 0x00000e2c, 0xffffffff, 0x40424444, }, ++ { 1, 1, 0, 0x00000e30, 0xffffffff, 0x28303236, }, ++ { 1, 1, 1, 0x00000e34, 0xffffffff, 0x38404242, }, ++ { 1, 1, 1, 0x00000e38, 0xffffffff, 0x26283034, }, ++ { 1, 1, 0, 0x00000e3c, 0xffffffff, 0x40424444, }, ++ { 1, 1, 0, 0x00000e40, 0xffffffff, 0x28303236, }, ++ { 1, 1, 0, 0x00000e44, 0xffffffff, 0x42422426, }, ++ { 1, 1, 1, 0x00000e48, 0xffffffff, 0x30343840, }, ++ { 1, 1, 1, 0x00000e4c, 0xffffffff, 0x22242628, }, ++}; ++ ++RTW_DECL_TABLE_BB_PG(rtw8812a_bb_pg); ++ ++static const struct rtw_phy_pg_cfg_pair rtw8812a_bb_pg_rfe3[] = { ++ { 0, 0, 0, 0x00000c20, 0xffffffff, 0x34343434, }, ++ { 0, 0, 0, 0x00000c24, 0xffffffff, 0x32323232, }, ++ { 0, 0, 0, 0x00000c28, 0xffffffff, 0x28303232, }, ++ { 0, 0, 0, 0x00000c2c, 0xffffffff, 0x32323232, }, ++ { 0, 0, 0, 0x00000c30, 0xffffffff, 0x28303232, }, ++ { 0, 0, 1, 0x00000c34, 0xffffffff, 0x32323232, }, ++ { 0, 0, 1, 0x00000c38, 0xffffffff, 0x26283032, }, ++ { 0, 0, 0, 0x00000c3c, 0xffffffff, 0x32323232, }, ++ { 0, 0, 0, 0x00000c40, 0xffffffff, 0x28303232, }, ++ { 0, 0, 0, 0x00000c44, 0xffffffff, 0x32322426, }, ++ { 0, 0, 1, 0x00000c48, 0xffffffff, 0x32323232, }, ++ { 0, 0, 1, 0x00000c4c, 0xffffffff, 0x24262830, }, ++ { 0, 1, 0, 0x00000e20, 0xffffffff, 0x34343434, }, ++ { 0, 1, 0, 0x00000e24, 0xffffffff, 0x32323232, }, ++ { 0, 1, 0, 0x00000e28, 0xffffffff, 0x28303232, }, ++ { 0, 1, 0, 0x00000e2c, 0xffffffff, 0x32323232, }, ++ { 0, 1, 0, 0x00000e30, 0xffffffff, 0x28303232, }, ++ { 0, 1, 1, 0x00000e34, 0xffffffff, 0x32323232, }, ++ { 0, 1, 1, 0x00000e38, 0xffffffff, 0x26283032, }, ++ { 0, 1, 0, 0x00000e3c, 0xffffffff, 0x32323232, }, ++ { 0, 1, 0, 0x00000e40, 0xffffffff, 0x28303232, }, ++ { 0, 1, 0, 0x00000e44, 0xffffffff, 0x32322426, }, ++ { 0, 1, 1, 0x00000e48, 0xffffffff, 0x32323232, }, ++ { 0, 1, 1, 0x00000e4c, 0xffffffff, 0x24262830, }, ++ { 1, 0, 0, 0x00000c24, 0xffffffff, 0x32323232, }, ++ { 1, 0, 0, 0x00000c28, 0xffffffff, 0x28303232, }, ++ { 1, 0, 0, 0x00000c2c, 0xffffffff, 0x32323232, }, ++ { 1, 0, 0, 0x00000c30, 0xffffffff, 0x24262830, }, ++ { 1, 0, 1, 0x00000c34, 0xffffffff, 0x32323232, }, ++ { 1, 0, 1, 0x00000c38, 0xffffffff, 0x24262830, }, ++ { 1, 0, 0, 0x00000c3c, 0xffffffff, 0x32323232, }, ++ { 1, 0, 0, 0x00000c40, 0xffffffff, 0x24262830, }, ++ { 1, 0, 0, 0x00000c44, 0xffffffff, 0x32322222, }, ++ { 1, 0, 1, 0x00000c48, 0xffffffff, 0x28303232, }, ++ { 1, 0, 1, 0x00000c4c, 0xffffffff, 0x22222426, }, ++ { 1, 1, 0, 0x00000e24, 0xffffffff, 0x32323232, }, ++ { 1, 1, 0, 0x00000e28, 0xffffffff, 0x28303232, }, ++ { 1, 1, 0, 0x00000e2c, 0xffffffff, 0x32323232, }, ++ { 1, 1, 0, 0x00000e30, 0xffffffff, 0x24262830, }, ++ { 1, 1, 1, 0x00000e34, 0xffffffff, 0x32323232, }, ++ { 1, 1, 1, 0x00000e38, 0xffffffff, 0x24262830, }, ++ { 1, 1, 0, 0x00000e3c, 0xffffffff, 0x32323232, }, ++ { 1, 1, 0, 0x00000e40, 0xffffffff, 0x24262830, }, ++ { 1, 1, 0, 0x00000e44, 0xffffffff, 0x32322222, }, ++ { 1, 1, 1, 0x00000e48, 0xffffffff, 0x28303232, }, ++ { 1, 1, 1, 0x00000e4c, 0xffffffff, 0x22222426, }, ++}; ++ ++RTW_DECL_TABLE_BB_PG(rtw8812a_bb_pg_rfe3); ++ ++static const u32 rtw8812a_rf_a[] = { ++ 0x000, 0x00010000, ++ 0x018, 0x0001712A, ++ 0x056, 0x00051CF2, ++ 0x066, 0x00040000, ++ 0x01E, 0x00080000, ++ 0x089, 0x00000080, ++ 0x80000001, 0x00000000, 0x40000000, 0x00000000, ++ 0x086, 0x00014B3A, ++ 0x90000001, 0x00000005, 0x40000000, 0x00000000, ++ 0x086, 0x00014B3A, ++ 0xA0000000, 0x00000000, ++ 0x086, 0x00014B38, ++ 0xB0000000, 0x00000000, ++ 0x80000004, 0x00000000, 0x40000000, 0x00000000, ++ 0x08B, 0x00080180, ++ 0xA0000000, 0x00000000, ++ 0x08B, 0x00087180, ++ 0xB0000000, 0x00000000, ++ 0x0B1, 0x0001FC1A, ++ 0x0B3, 0x000F0810, ++ 0x0B4, 0x0001A78D, ++ 0x0BA, 0x00086180, ++ 0x018, 0x00000006, ++ 0x0EF, 0x00002000, ++ 0x80000001, 0x00000000, 0x40000000, 0x00000000, ++ 0x03B, 0x0003F218, ++ 0x03B, 0x00030A58, ++ 0x03B, 0x0002FA58, ++ 0x03B, 0x00022590, ++ 0x03B, 0x0001FA50, ++ 0x03B, 0x00010248, ++ 0x03B, 0x00008240, ++ 0x90000001, 0x00000005, 0x40000000, 0x00000000, ++ 0x03B, 0x0003F218, ++ 0x03B, 0x00030A58, ++ 0x03B, 0x0002FA58, ++ 0x03B, 0x00022590, ++ 0x03B, 0x0001FA50, ++ 0x03B, 0x00010248, ++ 0x03B, 0x00008240, ++ 0xA0000000, 0x00000000, ++ 0x03B, 0x00038A58, ++ 0x03B, 0x00037A58, ++ 0x03B, 0x0002A590, ++ 0x03B, 0x00027A50, ++ 0x03B, 0x00018248, ++ 0x03B, 0x00010240, ++ 0x03B, 0x00008240, ++ 0xB0000000, 0x00000000, ++ 0x0EF, 0x00000100, ++ 0x80000002, 0x00000000, 0x40000000, 0x00000000, ++ 0x034, 0x0000A4EE, ++ 0x034, 0x00009076, ++ 0x034, 0x00008073, ++ 0x034, 0x00007070, ++ 0x034, 0x0000606D, ++ 0x034, 0x0000506A, ++ 0x034, 0x00004049, ++ 0x034, 0x00003046, ++ 0x034, 0x00002028, ++ 0x034, 0x00001025, ++ 0x034, 0x00000022, ++ 0xA0000000, 0x00000000, ++ 0x034, 0x0000ADF4, ++ 0x034, 0x00009DF1, ++ 0x034, 0x00008DEE, ++ 0x034, 0x00007DEB, ++ 0x034, 0x00006DE8, ++ 0x034, 0x00005DE5, ++ 0x034, 0x00004DE2, ++ 0x034, 0x00003CE6, ++ 0x034, 0x000024E7, ++ 0x034, 0x000014E4, ++ 0x034, 0x000004E1, ++ 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, ++ 0x0EF, 0x00000002, ++ 0x008, 0x00008400, ++ 0x018, 0x0001712A, ++ 0x0EF, 0x00001000, ++ 0x03A, 0x00000080, ++ 0x03B, 0x0003A02C, ++ 0x03C, 0x00004000, ++ 0x03A, 0x00000400, ++ 0x03B, 0x0003202C, ++ 0x03C, 0x00010000, ++ 0x03A, 0x000000A0, ++ 0x03B, 0x0002B064, ++ 0x03C, 0x00004000, ++ 0x03A, 0x000000D8, ++ 0x03B, 0x00023070, ++ 0x03C, 0x00004000, ++ 0x03A, 0x00000468, ++ 0x03B, 0x0001B870, ++ 0x03C, 0x00010000, ++ 0x03A, 0x00000098, ++ 0x03B, 0x00012085, ++ 0x03C, 0x000E4000, ++ 0x03A, 0x00000418, ++ 0x03B, 0x0000A080, ++ 0x03C, 0x000F0000, ++ 0x03A, 0x00000418, ++ 0x03B, 0x00002080, ++ 0x03C, 0x00010000, ++ 0x03A, 0x00000080, ++ 0x03B, 0x0007A02C, ++ 0x03C, 0x00004000, ++ 0x03A, 0x00000400, ++ 0x03B, 0x0007202C, ++ 0x03C, 0x00010000, ++ 0x03A, 0x000000A0, ++ 0x03B, 0x0006B064, ++ 0x03C, 0x00004000, ++ 0x03A, 0x000000D8, ++ 0x03B, 0x00063070, ++ 0x03C, 0x00004000, ++ 0x03A, 0x00000468, ++ 0x03B, 0x0005B870, ++ 0x03C, 0x00010000, ++ 0x03A, 0x00000098, ++ 0x03B, 0x00052085, ++ 0x03C, 0x000E4000, ++ 0x03A, 0x00000418, ++ 0x03B, 0x0004A080, ++ 0x03C, 0x000F0000, ++ 0x03A, 0x00000418, ++ 0x03B, 0x00042080, ++ 0x03C, 0x00010000, ++ 0x03A, 0x00000080, ++ 0x03B, 0x000BA02C, ++ 0x03C, 0x00004000, ++ 0x03A, 0x00000400, ++ 0x03B, 0x000B202C, ++ 0x03C, 0x00010000, ++ 0x03A, 0x000000A0, ++ 0x03B, 0x000AB064, ++ 0x03C, 0x00004000, ++ 0x03A, 0x000000D8, ++ 0x03B, 0x000A3070, ++ 0x03C, 0x00004000, ++ 0x03A, 0x00000468, ++ 0x03B, 0x0009B870, ++ 0x03C, 0x00010000, ++ 0x03A, 0x00000098, ++ 0x03B, 0x00092085, ++ 0x03C, 0x000E4000, ++ 0x03A, 0x00000418, ++ 0x03B, 0x0008A080, ++ 0x03C, 0x000F0000, ++ 0x03A, 0x00000418, ++ 0x03B, 0x00082080, ++ 0x03C, 0x00010000, ++ 0x0EF, 0x00001100, ++ 0x80000008, 0x00000000, 0x40000000, 0x00000000, ++ 0x034, 0x0004A0B2, ++ 0x034, 0x000490AF, ++ 0x034, 0x00048070, ++ 0x034, 0x0004706D, ++ 0x034, 0x00046050, ++ 0x034, 0x0004504D, ++ 0x034, 0x0004404A, ++ 0x034, 0x00043047, ++ 0x034, 0x0004200A, ++ 0x034, 0x00041007, ++ 0x034, 0x00040004, ++ 0x90000008, 0x05000000, 0x40000000, 0x00000000, ++ 0x034, 0x0004A0B2, ++ 0x034, 0x000490AF, ++ 0x034, 0x00048070, ++ 0x034, 0x0004706D, ++ 0x034, 0x0004604D, ++ 0x034, 0x0004504A, ++ 0x034, 0x00044047, ++ 0x034, 0x00043044, ++ 0x034, 0x00042007, ++ 0x034, 0x00041004, ++ 0x034, 0x00040001, ++ 0xA0000000, 0x00000000, ++ 0x034, 0x0004ADF5, ++ 0x034, 0x00049DF2, ++ 0x034, 0x00048DEF, ++ 0x034, 0x00047DEC, ++ 0x034, 0x00046DE9, ++ 0x034, 0x00045DE6, ++ 0x034, 0x00044DE3, ++ 0x034, 0x000438C8, ++ 0x034, 0x000428C5, ++ 0x034, 0x000418C2, ++ 0x034, 0x000408C0, ++ 0xB0000000, 0x00000000, ++ 0x80000008, 0x00000000, 0x40000000, 0x00000000, ++ 0x034, 0x0002A0B2, ++ 0x034, 0x000290AF, ++ 0x034, 0x00028070, ++ 0x034, 0x0002706D, ++ 0x034, 0x00026050, ++ 0x034, 0x0002504D, ++ 0x034, 0x0002404A, ++ 0x034, 0x00023047, ++ 0x034, 0x0002200A, ++ 0x034, 0x00021007, ++ 0x034, 0x00020004, ++ 0x90000008, 0x05000000, 0x40000000, 0x00000000, ++ 0x034, 0x0002A0B4, ++ 0x034, 0x000290B1, ++ 0x034, 0x00028072, ++ 0x034, 0x0002706F, ++ 0x034, 0x0002604F, ++ 0x034, 0x0002504C, ++ 0x034, 0x00024049, ++ 0x034, 0x00023046, ++ 0x034, 0x00022009, ++ 0x034, 0x00021006, ++ 0x034, 0x00020003, ++ 0xA0000000, 0x00000000, ++ 0x034, 0x0002ADF5, ++ 0x034, 0x00029DF2, ++ 0x034, 0x00028DEF, ++ 0x034, 0x00027DEC, ++ 0x034, 0x00026DE9, ++ 0x034, 0x00025DE6, ++ 0x034, 0x00024DE3, ++ 0x034, 0x000238C8, ++ 0x034, 0x000228C5, ++ 0x034, 0x000218C2, ++ 0x034, 0x000208C0, ++ 0xB0000000, 0x00000000, ++ 0x80000008, 0x00000000, 0x40000000, 0x00000000, ++ 0x034, 0x0000A0B2, ++ 0x034, 0x000090AF, ++ 0x034, 0x00008070, ++ 0x034, 0x0000706D, ++ 0x034, 0x00006050, ++ 0x034, 0x0000504D, ++ 0x034, 0x0000404A, ++ 0x034, 0x00003047, ++ 0x034, 0x0000200A, ++ 0x034, 0x00001007, ++ 0x034, 0x00000004, ++ 0x90000008, 0x05000000, 0x40000000, 0x00000000, ++ 0x034, 0x0000A0B2, ++ 0x034, 0x000090AF, ++ 0x034, 0x00008070, ++ 0x034, 0x0000706D, ++ 0x034, 0x0000604D, ++ 0x034, 0x0000504A, ++ 0x034, 0x00004047, ++ 0x034, 0x00003044, ++ 0x034, 0x00002007, ++ 0x034, 0x00001004, ++ 0x034, 0x00000001, ++ 0xA0000000, 0x00000000, ++ 0x034, 0x0000AFF7, ++ 0x034, 0x00009DF7, ++ 0x034, 0x00008DF4, ++ 0x034, 0x00007DF1, ++ 0x034, 0x00006DEE, ++ 0x034, 0x00005DEB, ++ 0x034, 0x00004DE8, ++ 0x034, 0x000038CC, ++ 0x034, 0x000028C9, ++ 0x034, 0x000018C6, ++ 0x034, 0x000008C3, ++ 0xB0000000, 0x00000000, ++ 0x0EF, 0x00000000, ++ 0x80000008, 0x00000000, 0x40000000, 0x00000000, ++ 0x018, 0x0001712A, ++ 0x0EF, 0x00000040, ++ 0x035, 0x000001D4, ++ 0x035, 0x000081D4, ++ 0x035, 0x000101D4, ++ 0x035, 0x000201B4, ++ 0x035, 0x000281B4, ++ 0x035, 0x000301B4, ++ 0x035, 0x000401B4, ++ 0x035, 0x000481B4, ++ 0x035, 0x000501B4, ++ 0x90000008, 0x05000000, 0x40000000, 0x00000000, ++ 0x018, 0x0001712A, ++ 0x0EF, 0x00000040, ++ 0x035, 0x000001D4, ++ 0x035, 0x000081D4, ++ 0x035, 0x000101D4, ++ 0x035, 0x000201B4, ++ 0x035, 0x000281B4, ++ 0x035, 0x000301B4, ++ 0x035, 0x000401B4, ++ 0x035, 0x000481B4, ++ 0x035, 0x000501B4, ++ 0xA0000000, 0x00000000, ++ 0x018, 0x0001712A, ++ 0x0EF, 0x00000040, ++ 0x035, 0x00000188, ++ 0x035, 0x00008147, ++ 0x035, 0x00010147, ++ 0x035, 0x000201D7, ++ 0x035, 0x000281D7, ++ 0x035, 0x000301D7, ++ 0x035, 0x000401D8, ++ 0x035, 0x000481D8, ++ 0x035, 0x000501D8, ++ 0xB0000000, 0x00000000, ++ 0x0EF, 0x00000000, ++ 0x80000008, 0x00000000, 0x40000000, 0x00000000, ++ 0x018, 0x0001712A, ++ 0x0EF, 0x00000010, ++ 0x036, 0x00004BFB, ++ 0x036, 0x0000CBFB, ++ 0x036, 0x00014BFB, ++ 0x036, 0x0001CBFB, ++ 0x036, 0x00024F4B, ++ 0x036, 0x0002CF4B, ++ 0x036, 0x00034F4B, ++ 0x036, 0x0003CF4B, ++ 0x036, 0x00044F4B, ++ 0x036, 0x0004CF4B, ++ 0x036, 0x00054F4B, ++ 0x036, 0x0005CF4B, ++ 0x90000008, 0x05000000, 0x40000000, 0x00000000, ++ 0x018, 0x0001712A, ++ 0x0EF, 0x00000010, ++ 0x036, 0x00004BFB, ++ 0x036, 0x0000CBFB, ++ 0x036, 0x00014BFB, ++ 0x036, 0x0001CBFB, ++ 0x036, 0x00024F4B, ++ 0x036, 0x0002CF4B, ++ 0x036, 0x00034F4B, ++ 0x036, 0x0003CF4B, ++ 0x036, 0x00044F4B, ++ 0x036, 0x0004CF4B, ++ 0x036, 0x00054F4B, ++ 0x036, 0x0005CF4B, ++ 0xA0000000, 0x00000000, ++ 0x018, 0x0001712A, ++ 0x0EF, 0x00000010, ++ 0x036, 0x00084EB4, ++ 0x036, 0x0008CC35, ++ 0x036, 0x00094C35, ++ 0x036, 0x0009CC35, ++ 0x036, 0x000A4C35, ++ 0x036, 0x000ACC35, ++ 0x036, 0x000B4C35, ++ 0x036, 0x000BCC35, ++ 0x036, 0x000C4C34, ++ 0x036, 0x000CCC35, ++ 0x036, 0x000D4C35, ++ 0x036, 0x000DCC35, ++ 0xB0000000, 0x00000000, ++ 0x0EF, 0x00000000, ++ 0x0EF, 0x00000008, ++ 0x80000008, 0x00000000, 0x40000000, 0x00000000, ++ 0x03C, 0x000002CC, ++ 0x03C, 0x00000522, ++ 0x03C, 0x00000902, ++ 0x90000008, 0x05000000, 0x40000000, 0x00000000, ++ 0x03C, 0x000002CC, ++ 0x03C, 0x00000522, ++ 0x03C, 0x00000902, ++ 0xA0000000, 0x00000000, ++ 0x03C, 0x000002A8, ++ 0x03C, 0x000005A2, ++ 0x03C, 0x00000880, ++ 0xB0000000, 0x00000000, ++ 0x0EF, 0x00000000, ++ 0x018, 0x0001712A, ++ 0x0EF, 0x00000002, ++ 0x0DF, 0x00000080, ++ 0x01F, 0x00000064, ++ 0x80000008, 0x00000000, 0x40000000, 0x00000000, ++ 0x061, 0x000FDD43, ++ 0x062, 0x00038F4B, ++ 0x063, 0x00032117, ++ 0x064, 0x000194AC, ++ 0x065, 0x000931D1, ++ 0x90000008, 0x05000000, 0x40000000, 0x00000000, ++ 0x061, 0x000FDD43, ++ 0x062, 0x00038F4B, ++ 0x063, 0x00032117, ++ 0x064, 0x000194AC, ++ 0x065, 0x000931D2, ++ 0xA0000000, 0x00000000, ++ 0x061, 0x000E5D53, ++ 0x062, 0x00038FCD, ++ 0x063, 0x000114EB, ++ 0x064, 0x000196AC, ++ 0x065, 0x000911D7, ++ 0xB0000000, 0x00000000, ++ 0x008, 0x00008400, ++ 0x01C, 0x000739D2, ++ 0x0B4, 0x0001E78D, ++ 0x018, 0x0001F12A, ++ 0xFFE, 0x00000000, ++ 0xFFE, 0x00000000, ++ 0xFFE, 0x00000000, ++ 0xFFE, 0x00000000, ++ 0x0B4, 0x0001A78D, ++ 0x018, 0x0001712A, ++}; ++ ++RTW_DECL_TABLE_RF_RADIO(rtw8812a_rf_a, A); ++ ++static const u32 rtw8812a_rf_b[] = { ++ 0x056, 0x00051CF2, ++ 0x066, 0x00040000, ++ 0x089, 0x00000080, ++ 0x80000001, 0x00000000, 0x40000000, 0x00000000, ++ 0x086, 0x00014B3A, ++ 0x90000001, 0x00000005, 0x40000000, 0x00000000, ++ 0x086, 0x00014B3A, ++ 0xA0000000, 0x00000000, ++ 0x086, 0x00014B38, ++ 0xB0000000, 0x00000000, ++ 0x80000004, 0x00000000, 0x40000000, 0x00000000, ++ 0x08B, 0x00080180, ++ 0xA0000000, 0x00000000, ++ 0x08B, 0x00087180, ++ 0xB0000000, 0x00000000, ++ 0x018, 0x00000006, ++ 0x0EF, 0x00002000, ++ 0x80000001, 0x00000000, 0x40000000, 0x00000000, ++ 0x03B, 0x0003F218, ++ 0x03B, 0x00030A58, ++ 0x03B, 0x0002FA58, ++ 0x03B, 0x00022590, ++ 0x03B, 0x0001FA50, ++ 0x03B, 0x00010248, ++ 0x03B, 0x00008240, ++ 0x90000001, 0x00000005, 0x40000000, 0x00000000, ++ 0x03B, 0x0003F218, ++ 0x03B, 0x00030A58, ++ 0x03B, 0x0002FA58, ++ 0x03B, 0x00022590, ++ 0x03B, 0x0001FA50, ++ 0x03B, 0x00010248, ++ 0x03B, 0x00008240, ++ 0xA0000000, 0x00000000, ++ 0x03B, 0x00038A58, ++ 0x03B, 0x00037A58, ++ 0x03B, 0x0002A590, ++ 0x03B, 0x00027A50, ++ 0x03B, 0x00018248, ++ 0x03B, 0x00010240, ++ 0x03B, 0x00008240, ++ 0xB0000000, 0x00000000, ++ 0x0EF, 0x00000100, ++ 0x80000002, 0x00000000, 0x40000000, 0x00000000, ++ 0x034, 0x0000A4EE, ++ 0x034, 0x00009076, ++ 0x034, 0x00008073, ++ 0x034, 0x00007070, ++ 0x034, 0x0000606D, ++ 0x034, 0x0000506A, ++ 0x034, 0x00004049, ++ 0x034, 0x00003046, ++ 0x034, 0x00002028, ++ 0x034, 0x00001025, ++ 0x034, 0x00000022, ++ 0xA0000000, 0x00000000, ++ 0x034, 0x0000ADF4, ++ 0x034, 0x00009DF1, ++ 0x034, 0x00008DEE, ++ 0x034, 0x00007DEB, ++ 0x034, 0x00006DE8, ++ 0x034, 0x00005DE5, ++ 0x034, 0x00004DE2, ++ 0x034, 0x00003CE6, ++ 0x034, 0x000024E7, ++ 0x034, 0x000014E4, ++ 0x034, 0x000004E1, ++ 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, ++ 0x0EF, 0x00000002, ++ 0x008, 0x00008400, ++ 0x018, 0x0001712A, ++ 0x0EF, 0x00001000, ++ 0x03A, 0x00000080, ++ 0x03B, 0x0003A02C, ++ 0x03C, 0x00004000, ++ 0x03A, 0x00000400, ++ 0x03B, 0x0003202C, ++ 0x03C, 0x00010000, ++ 0x03A, 0x000000A0, ++ 0x03B, 0x0002B064, ++ 0x03C, 0x00004000, ++ 0x03A, 0x000000D8, ++ 0x03B, 0x00023070, ++ 0x03C, 0x00004000, ++ 0x03A, 0x00000468, ++ 0x03B, 0x0001B870, ++ 0x03C, 0x00010000, ++ 0x03A, 0x00000098, ++ 0x03B, 0x00012085, ++ 0x03C, 0x000E4000, ++ 0x03A, 0x00000418, ++ 0x03B, 0x0000A080, ++ 0x03C, 0x000F0000, ++ 0x03A, 0x00000418, ++ 0x03B, 0x00002080, ++ 0x03C, 0x00010000, ++ 0x03A, 0x00000080, ++ 0x03B, 0x0007A02C, ++ 0x03C, 0x00004000, ++ 0x03A, 0x00000400, ++ 0x03B, 0x0007202C, ++ 0x03C, 0x00010000, ++ 0x03A, 0x000000A0, ++ 0x03B, 0x0006B064, ++ 0x03C, 0x00004000, ++ 0x03A, 0x000000D8, ++ 0x03B, 0x00063070, ++ 0x03C, 0x00004000, ++ 0x03A, 0x00000468, ++ 0x03B, 0x0005B870, ++ 0x03C, 0x00010000, ++ 0x03A, 0x00000098, ++ 0x03B, 0x00052085, ++ 0x03C, 0x000E4000, ++ 0x03A, 0x00000418, ++ 0x03B, 0x0004A080, ++ 0x03C, 0x000F0000, ++ 0x03A, 0x00000418, ++ 0x03B, 0x00042080, ++ 0x03C, 0x00010000, ++ 0x03A, 0x00000080, ++ 0x03B, 0x000BA02C, ++ 0x03C, 0x00004000, ++ 0x03A, 0x00000400, ++ 0x03B, 0x000B202C, ++ 0x03C, 0x00010000, ++ 0x03A, 0x000000A0, ++ 0x03B, 0x000AB064, ++ 0x03C, 0x00004000, ++ 0x03A, 0x000000D8, ++ 0x03B, 0x000A3070, ++ 0x03C, 0x00004000, ++ 0x03A, 0x00000468, ++ 0x03B, 0x0009B870, ++ 0x03C, 0x00010000, ++ 0x03A, 0x00000098, ++ 0x03B, 0x00092085, ++ 0x03C, 0x000E4000, ++ 0x03A, 0x00000418, ++ 0x03B, 0x0008A080, ++ 0x03C, 0x000F0000, ++ 0x03A, 0x00000418, ++ 0x03B, 0x00082080, ++ 0x03C, 0x00010000, ++ 0x0EF, 0x00001100, ++ 0x80000008, 0x00000000, 0x40000000, 0x00000000, ++ 0x034, 0x0004A0B2, ++ 0x034, 0x000490AF, ++ 0x034, 0x00048070, ++ 0x034, 0x0004706D, ++ 0x034, 0x00046050, ++ 0x034, 0x0004504D, ++ 0x034, 0x0004404A, ++ 0x034, 0x00043047, ++ 0x034, 0x0004200A, ++ 0x034, 0x00041007, ++ 0x034, 0x00040004, ++ 0x90000008, 0x05000000, 0x40000000, 0x00000000, ++ 0x034, 0x0004A0B1, ++ 0x034, 0x000490AE, ++ 0x034, 0x0004806F, ++ 0x034, 0x0004706C, ++ 0x034, 0x0004604C, ++ 0x034, 0x00045049, ++ 0x034, 0x00044046, ++ 0x034, 0x00043043, ++ 0x034, 0x00042006, ++ 0x034, 0x00041003, ++ 0x034, 0x00040000, ++ 0xA0000000, 0x00000000, ++ 0x034, 0x0004ADF5, ++ 0x034, 0x00049DF2, ++ 0x034, 0x00048DEF, ++ 0x034, 0x00047DEC, ++ 0x034, 0x00046DE9, ++ 0x034, 0x00045DE6, ++ 0x034, 0x00044DE3, ++ 0x034, 0x000438C8, ++ 0x034, 0x000428C5, ++ 0x034, 0x000418C2, ++ 0x034, 0x000408C0, ++ 0xB0000000, 0x00000000, ++ 0x80000008, 0x00000000, 0x40000000, 0x00000000, ++ 0x034, 0x0002A0B2, ++ 0x034, 0x000290AF, ++ 0x034, 0x00028070, ++ 0x034, 0x0002706D, ++ 0x034, 0x00026050, ++ 0x034, 0x0002504D, ++ 0x034, 0x0002404A, ++ 0x034, 0x00023047, ++ 0x034, 0x0002200A, ++ 0x034, 0x00021007, ++ 0x034, 0x00020004, ++ 0x90000008, 0x05000000, 0x40000000, 0x00000000, ++ 0x034, 0x0002A0B3, ++ 0x034, 0x000290B0, ++ 0x034, 0x00028071, ++ 0x034, 0x0002706E, ++ 0x034, 0x0002604E, ++ 0x034, 0x0002504B, ++ 0x034, 0x00024048, ++ 0x034, 0x00023045, ++ 0x034, 0x00022008, ++ 0x034, 0x00021005, ++ 0x034, 0x00020002, ++ 0xA0000000, 0x00000000, ++ 0x034, 0x0002ADF5, ++ 0x034, 0x00029DF2, ++ 0x034, 0x00028DEF, ++ 0x034, 0x00027DEC, ++ 0x034, 0x00026DE9, ++ 0x034, 0x00025DE6, ++ 0x034, 0x00024DE3, ++ 0x034, 0x000238C8, ++ 0x034, 0x000228C5, ++ 0x034, 0x000218C2, ++ 0x034, 0x000208C0, ++ 0xB0000000, 0x00000000, ++ 0x80000008, 0x00000000, 0x40000000, 0x00000000, ++ 0x034, 0x0000A0B2, ++ 0x034, 0x000090AF, ++ 0x034, 0x00008070, ++ 0x034, 0x0000706D, ++ 0x034, 0x00006050, ++ 0x034, 0x0000504D, ++ 0x034, 0x0000404A, ++ 0x034, 0x00003047, ++ 0x034, 0x0000200A, ++ 0x034, 0x00001007, ++ 0x034, 0x00000004, ++ 0x90000008, 0x05000000, 0x40000000, 0x00000000, ++ 0x034, 0x0000A0B3, ++ 0x034, 0x000090B0, ++ 0x034, 0x00008070, ++ 0x034, 0x0000706D, ++ 0x034, 0x0000604D, ++ 0x034, 0x0000504A, ++ 0x034, 0x00004047, ++ 0x034, 0x00003044, ++ 0x034, 0x00002007, ++ 0x034, 0x00001004, ++ 0x034, 0x00000001, ++ 0xA0000000, 0x00000000, ++ 0x034, 0x0000AFF7, ++ 0x034, 0x00009DF7, ++ 0x034, 0x00008DF4, ++ 0x034, 0x00007DF1, ++ 0x034, 0x00006DEE, ++ 0x034, 0x00005DEB, ++ 0x034, 0x00004DE8, ++ 0x034, 0x000038CC, ++ 0x034, 0x000028C9, ++ 0x034, 0x000018C6, ++ 0x034, 0x000008C3, ++ 0xB0000000, 0x00000000, ++ 0x0EF, 0x00000000, ++ 0x80000008, 0x00000000, 0x40000000, 0x00000000, ++ 0x018, 0x0001712A, ++ 0x0EF, 0x00000040, ++ 0x035, 0x000001C5, ++ 0x035, 0x000081C5, ++ 0x035, 0x000101C5, ++ 0x035, 0x00020174, ++ 0x035, 0x00028174, ++ 0x035, 0x00030174, ++ 0x035, 0x00040185, ++ 0x035, 0x00048185, ++ 0x035, 0x00050185, ++ 0x0EF, 0x00000000, ++ 0x90000008, 0x05000000, 0x40000000, 0x00000000, ++ 0x018, 0x0001712A, ++ 0x0EF, 0x00000040, ++ 0x035, 0x000001C5, ++ 0x035, 0x000081C5, ++ 0x035, 0x000101C5, ++ 0x035, 0x00020174, ++ 0x035, 0x00028174, ++ 0x035, 0x00030174, ++ 0x035, 0x00040185, ++ 0x035, 0x00048185, ++ 0x035, 0x00050185, ++ 0x0EF, 0x00000000, ++ 0xA0000000, 0x00000000, ++ 0x018, 0x0001712A, ++ 0x0EF, 0x00000040, ++ 0x035, 0x00000188, ++ 0x035, 0x00008147, ++ 0x035, 0x00010147, ++ 0x035, 0x000201D7, ++ 0x035, 0x000281D7, ++ 0x035, 0x000301D7, ++ 0x035, 0x000401D8, ++ 0x035, 0x000481D8, ++ 0x035, 0x000501D8, ++ 0x0EF, 0x00000000, ++ 0xB0000000, 0x00000000, ++ 0x80000008, 0x00000000, 0x40000000, 0x00000000, ++ 0x018, 0x0001712A, ++ 0x0EF, 0x00000010, ++ 0x036, 0x00005B8B, ++ 0x036, 0x0000DB8B, ++ 0x036, 0x00015B8B, ++ 0x036, 0x0001DB8B, ++ 0x036, 0x000262DB, ++ 0x036, 0x0002E2DB, ++ 0x036, 0x000362DB, ++ 0x036, 0x0003E2DB, ++ 0x036, 0x0004553B, ++ 0x036, 0x0004D53B, ++ 0x036, 0x0005553B, ++ 0x036, 0x0005D53B, ++ 0x90000008, 0x05000000, 0x40000000, 0x00000000, ++ 0x018, 0x0001712A, ++ 0x0EF, 0x00000010, ++ 0x036, 0x00005B8B, ++ 0x036, 0x0000DB8B, ++ 0x036, 0x00015B8B, ++ 0x036, 0x0001DB8B, ++ 0x036, 0x000262DB, ++ 0x036, 0x0002E2DB, ++ 0x036, 0x000362DB, ++ 0x036, 0x0003E2DB, ++ 0x036, 0x0004553B, ++ 0x036, 0x0004D53B, ++ 0x036, 0x0005553B, ++ 0x036, 0x0005D53B, ++ 0xA0000000, 0x00000000, ++ 0x018, 0x0001712A, ++ 0x0EF, 0x00000010, ++ 0x036, 0x00084EB4, ++ 0x036, 0x0008CC35, ++ 0x036, 0x00094C35, ++ 0x036, 0x0009CC35, ++ 0x036, 0x000A4C35, ++ 0x036, 0x000ACC35, ++ 0x036, 0x000B4C35, ++ 0x036, 0x000BCC35, ++ 0x036, 0x000C4C34, ++ 0x036, 0x000CCC35, ++ 0x036, 0x000D4C35, ++ 0x036, 0x000DCC35, ++ 0xB0000000, 0x00000000, ++ 0x0EF, 0x00000000, ++ 0x0EF, 0x00000008, ++ 0x80000008, 0x00000000, 0x40000000, 0x00000000, ++ 0x03C, 0x000002DC, ++ 0x03C, 0x00000524, ++ 0x03C, 0x00000902, ++ 0x90000008, 0x05000000, 0x40000000, 0x00000000, ++ 0x03C, 0x000002DC, ++ 0x03C, 0x00000524, ++ 0x03C, 0x00000902, ++ 0xA0000000, 0x00000000, ++ 0x03C, 0x000002A8, ++ 0x03C, 0x000005A2, ++ 0x03C, 0x00000880, ++ 0xB0000000, 0x00000000, ++ 0x0EF, 0x00000000, ++ 0x018, 0x0001712A, ++ 0x0EF, 0x00000002, ++ 0x0DF, 0x00000080, ++ 0x80000008, 0x00000000, 0x40000000, 0x00000000, ++ 0x061, 0x000EAC43, ++ 0x062, 0x00038F47, ++ 0x063, 0x00031157, ++ 0x064, 0x0001C4AC, ++ 0x065, 0x000931D1, ++ 0x90000008, 0x05000000, 0x40000000, 0x00000000, ++ 0x061, 0x000EAC43, ++ 0x062, 0x00038F47, ++ 0x063, 0x00031157, ++ 0x064, 0x0001C4AC, ++ 0x065, 0x000931D2, ++ 0x90000002, 0x00000000, 0x40000000, 0x00000000, ++ 0x061, 0x000EAC43, ++ 0x062, 0x00038F47, ++ 0x063, 0x00031157, ++ 0x064, 0x0001C4AC, ++ 0x065, 0x000931D1, ++ 0xA0000000, 0x00000000, ++ 0x061, 0x000E5D53, ++ 0x062, 0x00038FCD, ++ 0x063, 0x000114EB, ++ 0x064, 0x000196AC, ++ 0x065, 0x000911D7, ++ 0xB0000000, 0x00000000, ++ 0x008, 0x00008400, ++}; ++ ++RTW_DECL_TABLE_RF_RADIO(rtw8812a_rf_b, B); ++ ++static const struct rtw_txpwr_lmt_cfg_pair rtw8812a_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, 32, }, ++ { 1, 0, 0, 3, 1, 32, }, ++ { 0, 0, 0, 3, 2, 34, }, ++ { 2, 0, 0, 3, 2, 32, }, ++ { 1, 0, 0, 3, 2, 32, }, ++ { 0, 0, 0, 3, 3, 34, }, ++ { 2, 0, 0, 3, 3, 32, }, ++ { 1, 0, 0, 3, 3, 32, }, ++ { 0, 0, 0, 3, 4, 34, }, ++ { 2, 0, 0, 3, 4, 32, }, ++ { 1, 0, 0, 3, 4, 32, }, ++ { 0, 0, 0, 3, 5, 34, }, ++ { 2, 0, 0, 3, 5, 32, }, ++ { 1, 0, 0, 3, 5, 32, }, ++ { 0, 0, 0, 3, 6, 34, }, ++ { 2, 0, 0, 3, 6, 32, }, ++ { 1, 0, 0, 3, 6, 32, }, ++ { 0, 0, 0, 3, 7, 34, }, ++ { 2, 0, 0, 3, 7, 32, }, ++ { 1, 0, 0, 3, 7, 32, }, ++ { 0, 0, 0, 3, 8, 34, }, ++ { 2, 0, 0, 3, 8, 32, }, ++ { 1, 0, 0, 3, 8, 32, }, ++ { 0, 0, 0, 3, 9, 34, }, ++ { 2, 0, 0, 3, 9, 32, }, ++ { 1, 0, 0, 3, 9, 32, }, ++ { 0, 0, 0, 3, 10, 34, }, ++ { 2, 0, 0, 3, 10, 32, }, ++ { 1, 0, 0, 3, 10, 32, }, ++ { 0, 0, 0, 3, 11, 30, }, ++ { 2, 0, 0, 3, 11, 32, }, ++ { 1, 0, 0, 3, 11, 32, }, ++ { 0, 0, 0, 3, 12, 63, }, ++ { 2, 0, 0, 3, 12, 32, }, ++ { 1, 0, 0, 3, 12, 32, }, ++ { 0, 0, 0, 3, 13, 63, }, ++ { 2, 0, 0, 3, 13, 32, }, ++ { 1, 0, 0, 3, 13, 32, }, ++ { 0, 0, 0, 3, 14, 63, }, ++ { 2, 0, 0, 3, 14, 63, }, ++ { 1, 0, 0, 3, 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, 32, }, ++ { 1, 0, 1, 3, 12, 32, }, ++ { 0, 0, 1, 3, 13, 63, }, ++ { 2, 0, 1, 3, 13, 32, }, ++ { 1, 0, 1, 3, 13, 32, }, ++ { 0, 0, 1, 3, 14, 63, }, ++ { 2, 0, 1, 3, 14, 63, }, ++ { 1, 0, 1, 3, 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, 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, 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, }, ++}; ++ ++RTW_DECL_TABLE_TXPWR_LMT(rtw8812a_txpwr_lmt); ++ ++static const struct rtw_pwr_seq_cmd trans_carddis_to_cardemu_8812a[] = { ++ {0x0012, ++ RTW_PWR_CUT_ALL_MSK, ++ RTW_PWR_INTF_ALL_MSK, ++ RTW_PWR_ADDR_MAC, ++ RTW_PWR_CMD_WRITE, BIT(0), BIT(0)}, ++ {0x0014, ++ RTW_PWR_CUT_ALL_MSK, ++ RTW_PWR_INTF_ALL_MSK, ++ RTW_PWR_ADDR_MAC, ++ RTW_PWR_CMD_WRITE, 0x80, 0}, ++ {0x0015, ++ RTW_PWR_CUT_ALL_MSK, ++ RTW_PWR_INTF_ALL_MSK, ++ RTW_PWR_ADDR_MAC, ++ RTW_PWR_CMD_WRITE, 0x01, 0}, ++ {0x0023, ++ RTW_PWR_CUT_ALL_MSK, ++ RTW_PWR_INTF_ALL_MSK, ++ RTW_PWR_ADDR_MAC, ++ RTW_PWR_CMD_WRITE, 0x10, 0}, ++ {0x0046, ++ RTW_PWR_CUT_ALL_MSK, ++ RTW_PWR_INTF_ALL_MSK, ++ RTW_PWR_ADDR_MAC, ++ RTW_PWR_CMD_WRITE, 0xFF, 0x00}, ++ {0x0043, ++ 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}, ++ {0x0003, ++ RTW_PWR_CUT_ALL_MSK, ++ RTW_PWR_INTF_ALL_MSK, ++ RTW_PWR_ADDR_MAC, ++ RTW_PWR_CMD_WRITE, BIT(2), BIT(2)}, ++ {0x0301, ++ RTW_PWR_CUT_ALL_MSK, ++ RTW_PWR_INTF_PCI_MSK, ++ RTW_PWR_ADDR_MAC, ++ RTW_PWR_CMD_WRITE, 0xFF, 0}, ++ {0x0024, ++ RTW_PWR_CUT_ALL_MSK, ++ RTW_PWR_INTF_USB_MSK, ++ RTW_PWR_ADDR_MAC, ++ RTW_PWR_CMD_WRITE, BIT(1), BIT(1)}, ++ {0x0028, ++ RTW_PWR_CUT_ALL_MSK, ++ RTW_PWR_INTF_USB_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}, ++}; ++ ++static const struct rtw_pwr_seq_cmd trans_cardemu_to_act_8812a[] = { ++ {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_PCI_MSK, ++ RTW_PWR_ADDR_MAC, ++ RTW_PWR_CMD_WRITE, BIT(7), 0}, ++ {0x0005, ++ RTW_PWR_CUT_ALL_MSK, ++ RTW_PWR_INTF_ALL_MSK, ++ RTW_PWR_ADDR_MAC, ++ RTW_PWR_CMD_WRITE, BIT(3), 0}, ++ {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}, ++ {0x0024, ++ RTW_PWR_CUT_ALL_MSK, ++ RTW_PWR_INTF_USB_MSK, ++ RTW_PWR_ADDR_MAC, ++ RTW_PWR_CMD_WRITE, BIT(1), 0}, ++ {0x0028, ++ RTW_PWR_CUT_ALL_MSK, ++ RTW_PWR_INTF_USB_MSK, ++ RTW_PWR_ADDR_MAC, ++ RTW_PWR_CMD_WRITE, BIT(3), 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_lps_8812a[] = { ++ {0x0301, ++ RTW_PWR_CUT_ALL_MSK, ++ RTW_PWR_INTF_PCI_MSK, ++ RTW_PWR_ADDR_MAC, ++ RTW_PWR_CMD_WRITE, 0xFF, 0xFF}, ++ {0x0522, ++ RTW_PWR_CUT_ALL_MSK, ++ RTW_PWR_INTF_ALL_MSK, ++ RTW_PWR_ADDR_MAC, ++ RTW_PWR_CMD_WRITE, 0xFF, 0x7F}, ++ {0x05F8, ++ RTW_PWR_CUT_ALL_MSK, ++ RTW_PWR_INTF_ALL_MSK, ++ RTW_PWR_ADDR_MAC, ++ RTW_PWR_CMD_POLLING, 0xFF, 0}, ++ {0x05F9, ++ RTW_PWR_CUT_ALL_MSK, ++ RTW_PWR_INTF_ALL_MSK, ++ RTW_PWR_ADDR_MAC, ++ RTW_PWR_CMD_POLLING, 0xFF, 0}, ++ {0x05FA, ++ RTW_PWR_CUT_ALL_MSK, ++ RTW_PWR_INTF_ALL_MSK, ++ RTW_PWR_ADDR_MAC, ++ RTW_PWR_CMD_POLLING, 0xFF, 0}, ++ {0x05FB, ++ RTW_PWR_CUT_ALL_MSK, ++ RTW_PWR_INTF_ALL_MSK, ++ RTW_PWR_ADDR_MAC, ++ RTW_PWR_CMD_POLLING, 0xFF, 0}, ++ {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}, ++ {0x0002, ++ 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, 0, RTW_PWR_DELAY_US}, ++ {0x0002, ++ RTW_PWR_CUT_ALL_MSK, ++ RTW_PWR_INTF_USB_MSK, ++ RTW_PWR_ADDR_MAC, ++ RTW_PWR_CMD_WRITE, BIT(1), 0}, ++ {0x0100, ++ RTW_PWR_CUT_ALL_MSK, ++ RTW_PWR_INTF_ALL_MSK, ++ RTW_PWR_ADDR_MAC, ++ RTW_PWR_CMD_WRITE, 0xFF, 0x03}, ++ {0x0101, ++ RTW_PWR_CUT_ALL_MSK, ++ RTW_PWR_INTF_ALL_MSK, ++ RTW_PWR_ADDR_MAC, ++ RTW_PWR_CMD_WRITE, BIT(1), 0}, ++ {0x0553, ++ RTW_PWR_CUT_ALL_MSK, ++ RTW_PWR_INTF_ALL_MSK, ++ RTW_PWR_ADDR_MAC, ++ RTW_PWR_CMD_WRITE, BIT(5), BIT(5)}, ++ {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_8812a[] = { ++ {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}, ++ {0x0002, ++ 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, 0, RTW_PWR_DELAY_US}, ++ {0x0002, ++ RTW_PWR_CUT_ALL_MSK, ++ RTW_PWR_INTF_PCI_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, 0x2A}, ++ {0x0008, ++ RTW_PWR_CUT_ALL_MSK, ++ RTW_PWR_INTF_USB_MSK, ++ RTW_PWR_ADDR_MAC, ++ RTW_PWR_CMD_WRITE, 0x02, 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_8812a[] = { ++ {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, 0x05}, ++ {0x0042, ++ RTW_PWR_CUT_ALL_MSK, ++ RTW_PWR_INTF_USB_MSK, ++ RTW_PWR_ADDR_MAC, ++ RTW_PWR_CMD_WRITE, 0xF0, 0xcc}, ++ {0x0042, ++ RTW_PWR_CUT_ALL_MSK, ++ RTW_PWR_INTF_PCI_MSK, ++ RTW_PWR_ADDR_MAC, ++ RTW_PWR_CMD_WRITE, 0xF0, 0xEC}, ++ {0x0043, ++ RTW_PWR_CUT_ALL_MSK, ++ RTW_PWR_INTF_ALL_MSK, ++ RTW_PWR_ADDR_MAC, ++ RTW_PWR_CMD_WRITE, 0xFF, 0x07}, ++ {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}, ++ {0x0014, ++ RTW_PWR_CUT_ALL_MSK, ++ RTW_PWR_INTF_ALL_MSK, ++ RTW_PWR_ADDR_MAC, ++ RTW_PWR_CMD_WRITE, 0x80, BIT(7)}, ++ {0x0015, ++ RTW_PWR_CUT_ALL_MSK, ++ RTW_PWR_INTF_ALL_MSK, ++ RTW_PWR_ADDR_MAC, ++ RTW_PWR_CMD_WRITE, 0x01, BIT(0)}, ++ {0x0012, ++ RTW_PWR_CUT_ALL_MSK, ++ RTW_PWR_INTF_ALL_MSK, ++ RTW_PWR_ADDR_MAC, ++ RTW_PWR_CMD_WRITE, 0x01, 0}, ++ {0x0023, ++ RTW_PWR_CUT_ALL_MSK, ++ RTW_PWR_INTF_ALL_MSK, ++ RTW_PWR_ADDR_MAC, ++ RTW_PWR_CMD_WRITE, 0x10, BIT(4)}, ++ {0x0008, ++ RTW_PWR_CUT_ALL_MSK, ++ RTW_PWR_INTF_USB_MSK, ++ RTW_PWR_ADDR_MAC, ++ RTW_PWR_CMD_WRITE, 0x02, 0}, ++ {0x0007, ++ RTW_PWR_CUT_ALL_MSK, ++ RTW_PWR_INTF_USB_MSK, ++ RTW_PWR_ADDR_MAC, ++ RTW_PWR_CMD_WRITE, 0xFF, 0x20}, ++ {0x001f, ++ RTW_PWR_CUT_ALL_MSK, ++ RTW_PWR_INTF_USB_MSK, ++ RTW_PWR_ADDR_MAC, ++ RTW_PWR_CMD_WRITE, BIT(1), 0}, ++ {0x0076, ++ RTW_PWR_CUT_ALL_MSK, ++ RTW_PWR_INTF_USB_MSK, ++ RTW_PWR_ADDR_MAC, ++ RTW_PWR_CMD_WRITE, BIT(1), 0}, ++ {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 * const card_enable_flow_8812a[] = { ++ trans_carddis_to_cardemu_8812a, ++ trans_cardemu_to_act_8812a, ++ NULL ++}; ++ ++const struct rtw_pwr_seq_cmd * const enter_lps_flow_8812a[] = { ++ trans_act_to_lps_8812a, ++ NULL ++}; ++ ++const struct rtw_pwr_seq_cmd * const card_disable_flow_8812a[] = { ++ trans_act_to_cardemu_8812a, ++ trans_cardemu_to_carddis_8812a, ++ NULL ++}; ++ ++static const u8 rtw8812a_pwrtrk_5gb_n[][RTW_PWR_TRK_TBL_SZ] = { ++ {0, 1, 1, 2, 2, 3, 4, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, ++ 12, 13, 13, 14, 14, 14, 14, 14, 14}, ++ {0, 1, 1, 2, 2, 3, 4, 4, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, ++ 12, 13, 13, 14, 14, 14, 14, 14, 14}, ++ {0, 1, 1, 2, 2, 3, 4, 5, 6, 6, 7, 8, 8, 9, 10, 10, 11, 11, 12, 12, 13, ++ 13, 14, 14, 15, 16, 16, 16, 16, 16}, ++}; ++ ++static const u8 rtw8812a_pwrtrk_5gb_p[][RTW_PWR_TRK_TBL_SZ] = { ++ {0, 1, 1, 2, 2, 3, 3, 4, 5, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 11, ++ 11, 11, 11, 11, 11, 11, 11, 11, 11}, ++ {0, 1, 1, 2, 3, 3, 4, 5, 5, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 11, ++ 11, 11, 11, 11, 11, 11, 11, 11, 11}, ++ {0, 1, 1, 2, 3, 3, 4, 5, 6, 7, 7, 8, 8, 9, 9, 10, 11, 11, 11, 11, 11, ++ 11, 11, 11, 11, 11, 11, 11, 11, 11}, ++}; ++ ++static const u8 rtw8812a_pwrtrk_5ga_n[][RTW_PWR_TRK_TBL_SZ] = { ++ {0, 1, 1, 2, 2, 3, 4, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, ++ 12, 13, 13, 14, 15, 15, 15, 15, 15}, ++ {0, 1, 1, 2, 2, 3, 4, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, ++ 12, 13, 13, 14, 15, 15, 15, 15, 15}, ++ {0, 1, 1, 2, 2, 3, 4, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, ++ 12, 13, 13, 14, 15, 15, 15, 15, 15}, ++}; ++ ++static const u8 rtw8812a_pwrtrk_5ga_p[][RTW_PWR_TRK_TBL_SZ] = { ++ {0, 1, 1, 2, 2, 3, 4, 5, 6, 7, 7, 8, 8, 9, 10, 11, 11, 11, 11, 11, 11, ++ 11, 11, 11, 11, 11, 11, 11, 11, 11}, ++ {0, 1, 1, 2, 3, 3, 4, 5, 6, 7, 7, 8, 8, 9, 10, 11, 11, 11, 11, 11, 11, ++ 11, 11, 11, 11, 11, 11, 11, 11, 11}, ++ {0, 1, 1, 2, 3, 3, 4, 5, 6, 7, 7, 8, 8, 9, 10, 11, 11, 12, 12, 11, 11, ++ 11, 11, 11, 11, 11, 11, 11, 11, 11}, ++}; ++ ++static const u8 rtw8812a_pwrtrk_2gb_n[] = { ++ 0, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 5, 5, 5, 6, 6, ++ 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 11, 11, 11, 11 ++}; ++ ++static const u8 rtw8812a_pwrtrk_2gb_p[] = { ++ 0, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 4, 5, 5, 5, 6, ++ 6, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7 ++}; ++ ++static const u8 rtw8812a_pwrtrk_2ga_n[] = { ++ 0, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 4, 5, 5, 5, 6, ++ 6, 6, 7, 7, 7, 8, 8, 9, 10, 10, 10, 10, 10, 10 ++}; ++ ++static const u8 rtw8812a_pwrtrk_2ga_p[] = { ++ 0, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 4, 5, 5, 5, 6, ++ 6, 6, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7 ++}; ++ ++static const u8 rtw8812a_pwrtrk_2g_cck_b_n[] = { ++ 0, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 5, 5, 5, 6, 6, ++ 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 11, 11, 11, 11 ++}; ++ ++static const u8 rtw8812a_pwrtrk_2g_cck_b_p[] = { ++ 0, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 4, 5, 5, 5, 6, ++ 6, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7 ++}; ++ ++static const u8 rtw8812a_pwrtrk_2g_cck_a_n[] = { ++ 0, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 4, 5, 5, 5, 6, ++ 6, 6, 7, 7, 7, 8, 8, 9, 10, 10, 10, 10, 10, 10 ++}; ++ ++static const u8 rtw8812a_pwrtrk_2g_cck_a_p[] = { ++ 0, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 4, 5, 5, 5, 6, ++ 6, 6, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7 ++}; ++ ++const struct rtw_pwr_track_tbl rtw8812a_rtw_pwr_track_tbl = { ++ .pwrtrk_5gb_n[0] = rtw8812a_pwrtrk_5gb_n[0], ++ .pwrtrk_5gb_n[1] = rtw8812a_pwrtrk_5gb_n[1], ++ .pwrtrk_5gb_n[2] = rtw8812a_pwrtrk_5gb_n[2], ++ .pwrtrk_5gb_p[0] = rtw8812a_pwrtrk_5gb_p[0], ++ .pwrtrk_5gb_p[1] = rtw8812a_pwrtrk_5gb_p[1], ++ .pwrtrk_5gb_p[2] = rtw8812a_pwrtrk_5gb_p[2], ++ .pwrtrk_5ga_n[0] = rtw8812a_pwrtrk_5ga_n[0], ++ .pwrtrk_5ga_n[1] = rtw8812a_pwrtrk_5ga_n[1], ++ .pwrtrk_5ga_n[2] = rtw8812a_pwrtrk_5ga_n[2], ++ .pwrtrk_5ga_p[0] = rtw8812a_pwrtrk_5ga_p[0], ++ .pwrtrk_5ga_p[1] = rtw8812a_pwrtrk_5ga_p[1], ++ .pwrtrk_5ga_p[2] = rtw8812a_pwrtrk_5ga_p[2], ++ .pwrtrk_2gb_n = rtw8812a_pwrtrk_2gb_n, ++ .pwrtrk_2gb_p = rtw8812a_pwrtrk_2gb_p, ++ .pwrtrk_2ga_n = rtw8812a_pwrtrk_2ga_n, ++ .pwrtrk_2ga_p = rtw8812a_pwrtrk_2ga_p, ++ .pwrtrk_2g_cckb_n = rtw8812a_pwrtrk_2g_cck_b_n, ++ .pwrtrk_2g_cckb_p = rtw8812a_pwrtrk_2g_cck_b_p, ++ .pwrtrk_2g_ccka_n = rtw8812a_pwrtrk_2g_cck_a_n, ++ .pwrtrk_2g_ccka_p = rtw8812a_pwrtrk_2g_cck_a_p, ++}; ++ ++static const u8 rtw8812a_pwrtrk_rfe3_5gb_n[][RTW_PWR_TRK_TBL_SZ] = { ++ {0, 1, 1, 2, 3, 3, 4, 5, 5, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 12, 13, ++ 13, 14, 15, 16, 16, 17, 17, 18, 18}, ++ {0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 6, 7, 8, 8, 9, 9, 10, 10, 11, 11, 11, ++ 12, 14, 13, 13, 14, 14, 14, 15, 15}, ++ {0, 1, 1, 2, 2, 3, 4, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, ++ 12, 13, 13, 14, 14, 15, 15, 16, 16}, ++}; ++ ++static const u8 rtw8812a_pwrtrk_rfe3_5gb_p[][RTW_PWR_TRK_TBL_SZ] = { ++ {0, 1, 1, 2, 3, 3, 4, 5, 6, 7, 7, 8, 9, 9, 10, 10, 11, 11, 11, 11, 11, ++ 11, 11, 11, 11, 11, 11, 11, 11, 11}, ++ {0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 6, 7, 8, 8, 9, 9, 10, 10, 11, 11, 11, ++ 11, 11, 11, 11, 11, 11, 11, 11, 11}, ++ {0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 6, 6, 7, 7, 8, 9, 10, 10, 11, 11, 11, ++ 11, 11, 11, 11, 11, 11, 11, 11, 11}, ++}; ++ ++static const u8 rtw8812a_pwrtrk_rfe3_5ga_n[][RTW_PWR_TRK_TBL_SZ] = { ++ {0, 1, 1, 2, 3, 3, 4, 5, 5, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, ++ 13, 14, 15, 16, 16, 17, 17, 18, 18}, ++ {0, 1, 1, 2, 3, 3, 4, 4, 5, 6, 6, 7, 7, 8, 9, 9, 10, 10, 11, 11, 12, ++ 12, 13, 13, 14, 15, 16, 16, 17, 17}, ++ {0, 1, 1, 2, 3, 3, 4, 4, 5, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 12, 13, ++ 13, 14, 14, 15, 15, 16, 17, 18, 18}, ++}; ++ ++static const u8 rtw8812a_pwrtrk_rfe3_5ga_p[][RTW_PWR_TRK_TBL_SZ] = { ++ {0, 1, 1, 2, 2, 3, 4, 5, 6, 7, 7, 8, 9, 9, 10, 10, 11, 11, 11, 11, 11, ++ 11, 11, 11, 11, 11, 11, 11, 11, 11}, ++ {0, 1, 2, 3, 4, 4, 5, 5, 6, 7, 7, 8, 9, 9, 10, 11, 11, 11, 11, 11, 11, ++ 11, 11, 11, 11, 11, 11, 11, 11, 11}, ++ {0, 1, 2, 3, 4, 4, 5, 5, 6, 7, 7, 8, 9, 9, 10, 11, 11, 11, 11, 11, 11, ++ 11, 11, 11, 11, 11, 11, 11, 11, 11}, ++}; ++ ++static const u8 rtw8812a_pwrtrk_rfe3_2gb_n[] = { ++ 0, 1, 1, 2, 2, 3, 3, 4, 4, 4, 5, 5, 6, 6, 6, 7, ++ 7, 7, 8, 8, 9, 9, 10, 11, 12, 12, 13, 14, 15, 15 ++}; ++ ++static const u8 rtw8812a_pwrtrk_rfe3_2gb_p[] = { ++ 0, 1, 1, 2, 2, 2, 2, 3, 3, 3, 4, 4, 5, 5, 5, 6, ++ 6, 7, 7, 8, 9, 10, 10, 10, 10, 11, 11, 11, 11, 11 ++}; ++ ++static const u8 rtw8812a_pwrtrk_rfe3_2ga_n[] = { ++ 0, 1, 1, 2, 2, 3, 4, 5, 6, 6, 6, 7, 7, 8, 8, 9, ++ 10, 10, 11, 11, 12, 12, 13, 13, 13, 13, 14, 14, 15, 15 ++}; ++ ++static const u8 rtw8812a_pwrtrk_rfe3_2ga_p[] = { ++ 0, 0, 1, 1, 1, 2, 2, 3, 3, 4, 4, 4, 5, 5, 5, 6, ++ 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 11, 11, 11 ++}; ++ ++static const u8 rtw8812a_pwrtrk_rfe3_2g_cck_b_n[] = { ++ 0, 1, 1, 2, 2, 3, 3, 4, 4, 4, 5, 5, 6, 6, 6, 7, ++ 7, 7, 8, 8, 9, 9, 10, 11, 12, 12, 13, 14, 15, 15 ++}; ++ ++static const u8 rtw8812a_pwrtrk_rfe3_2g_cck_b_p[] = { ++ 0, 1, 1, 2, 2, 2, 2, 3, 3, 3, 4, 4, 5, 5, 5, 6, ++ 6, 7, 7, 8, 9, 10, 10, 10, 10, 11, 11, 11, 11, 11 ++}; ++ ++static const u8 rtw8812a_pwrtrk_rfe3_2g_cck_a_n[] = { ++ 0, 1, 1, 2, 2, 3, 4, 5, 6, 6, 6, 7, 7, 8, 8, 9, ++ 10, 10, 11, 11, 12, 12, 13, 13, 13, 13, 14, 14, 15, 15 ++}; ++ ++static const u8 rtw8812a_pwrtrk_rfe3_2g_cck_a_p[] = { ++ 0, 0, 1, 1, 1, 2, 2, 3, 3, 4, 4, 4, 5, 5, 5, 6, ++ 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 11, 11, 11 ++}; ++ ++const struct rtw_pwr_track_tbl rtw8812a_rtw_pwr_track_rfe3_tbl = { ++ .pwrtrk_5gb_n[0] = rtw8812a_pwrtrk_rfe3_5gb_n[0], ++ .pwrtrk_5gb_n[1] = rtw8812a_pwrtrk_rfe3_5gb_n[1], ++ .pwrtrk_5gb_n[2] = rtw8812a_pwrtrk_rfe3_5gb_n[2], ++ .pwrtrk_5gb_p[0] = rtw8812a_pwrtrk_rfe3_5gb_p[0], ++ .pwrtrk_5gb_p[1] = rtw8812a_pwrtrk_rfe3_5gb_p[1], ++ .pwrtrk_5gb_p[2] = rtw8812a_pwrtrk_rfe3_5gb_p[2], ++ .pwrtrk_5ga_n[0] = rtw8812a_pwrtrk_rfe3_5ga_n[0], ++ .pwrtrk_5ga_n[1] = rtw8812a_pwrtrk_rfe3_5ga_n[1], ++ .pwrtrk_5ga_n[2] = rtw8812a_pwrtrk_rfe3_5ga_n[2], ++ .pwrtrk_5ga_p[0] = rtw8812a_pwrtrk_rfe3_5ga_p[0], ++ .pwrtrk_5ga_p[1] = rtw8812a_pwrtrk_rfe3_5ga_p[1], ++ .pwrtrk_5ga_p[2] = rtw8812a_pwrtrk_rfe3_5ga_p[2], ++ .pwrtrk_2gb_n = rtw8812a_pwrtrk_rfe3_2gb_n, ++ .pwrtrk_2gb_p = rtw8812a_pwrtrk_rfe3_2gb_p, ++ .pwrtrk_2ga_n = rtw8812a_pwrtrk_rfe3_2ga_n, ++ .pwrtrk_2ga_p = rtw8812a_pwrtrk_rfe3_2ga_p, ++ .pwrtrk_2g_cckb_n = rtw8812a_pwrtrk_rfe3_2g_cck_b_n, ++ .pwrtrk_2g_cckb_p = rtw8812a_pwrtrk_rfe3_2g_cck_b_p, ++ .pwrtrk_2g_ccka_n = rtw8812a_pwrtrk_rfe3_2g_cck_a_n, ++ .pwrtrk_2g_ccka_p = rtw8812a_pwrtrk_rfe3_2g_cck_a_p, ++}; +diff --git a/drivers/net/wireless/realtek/rtw88/rtw8812a_table.h b/drivers/net/wireless/realtek/rtw88/rtw8812a_table.h +new file mode 100644 +index 000000000000..f7ab5e4cf059 +--- /dev/null ++++ b/drivers/net/wireless/realtek/rtw88/rtw8812a_table.h +@@ -0,0 +1,26 @@ ++/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */ ++/* Copyright(c) 2024 Realtek Corporation ++ */ ++ ++#ifndef __RTW8812A_TABLE_H__ ++#define __RTW8812A_TABLE_H__ ++ ++extern const struct rtw_table rtw8812a_mac_tbl; ++extern const struct rtw_table rtw8812a_agc_tbl; ++extern const struct rtw_table rtw8812a_agc_diff_lb_tbl; ++extern const struct rtw_table rtw8812a_agc_diff_hb_tbl; ++extern const struct rtw_table rtw8812a_bb_tbl; ++extern const struct rtw_table rtw8812a_bb_pg_tbl; ++extern const struct rtw_table rtw8812a_bb_pg_rfe3_tbl; ++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 * 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; ++ ++#endif +-- +2.46.0 + + +From mboxrd@z Thu Jan 1 00:00:00 1970 +Received: from mail-wm1-f47.google.com (mail-wm1-f47.google.com [209.85.128.47]) + (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) + (No client certificate requested) + by smtp.subspace.kernel.org (Postfix) with ESMTPS id 50B33199231 + for ; Fri, 11 Oct 2024 20:55:15 +0000 (UTC) +Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.128.47 +ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; + t=1728680119; cv=none; b=OSK69k8heucPQjQmvWL7J3ICBw4xpv6HhX3GpNOVPmfPwlZObEboC+q9JiodHB+VYdyo7q4Qrh7YOak0RnPxTMqhk0VXWkTwgZV1/eZDwAlKcv57wkHZ35CoH5fdMUviIPwucr6T4PQKhoJldzL/udwKTZ8OWtvUm84kRJB++Nk= +ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; + s=arc-20240116; t=1728680119; c=relaxed/simple; + bh=1BRHkkquUo0S6r419N+xn0bXIR031N7f+25PwdtIPf8=; + h=Message-ID:Date:MIME-Version:Subject:From:To:Cc:References: + In-Reply-To:Content-Type; b=nddbXx6sBFuKwLwJVD2k/RcfCph/bRY6T9b8lmOsJtw0bPZyY/aZsBNZFO5uvFm+T6mkws02ZMjYMOXnDl5ufEStyAL0bssNeYB7InL3YUS410CXJT9DYoi7SqB/LA4cAJxV2w2OhAVTUpjm0dUFpYaIWinhSfdzJE0DK2bAnJ0= +ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=Bq/VfCcY; arc=none smtp.client-ip=209.85.128.47 +Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com +Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com +Authentication-Results: smtp.subspace.kernel.org; + dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="Bq/VfCcY" +Received: by mail-wm1-f47.google.com with SMTP id 5b1f17b1804b1-4311ac1994dso14997435e9.1 + for ; Fri, 11 Oct 2024 13:55:15 -0700 (PDT) +DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; + d=gmail.com; s=20230601; t=1728680114; x=1729284914; darn=vger.kernel.org; + h=content-transfer-encoding:in-reply-to:content-language:references + :cc:to:from:subject:user-agent:mime-version:date:message-id:from:to + :cc:subject:date:message-id:reply-to; + bh=fk3cCQ1xBgMFb++lgcAzN+vsz5X/4SKReAqNMBCX03E=; + b=Bq/VfCcYU0N36X2aT19CUAqRhbOOHXgrVGxVKu+mRHNB8d0jcvgGsIaC46Z9v7bDIl + 8S4pOPCGZioGha9xJ1nTG8N+0Trvv93DfkFNjLKOlbwXuo+iHq9qpuKQA6WawKpFGZAD + L/gBVMdwwp0rug7N0B3GpugapVGaQwAWDPBCsMINkS7vSt1tqMjkf7uKJjHMQtChrzLF + KwnAcRgk1s7JGUX5B3tRY38PgovXnL5aG3Kd8RpafMAvD5lW41puVgeXk3lKXp6+EjIe + 54Ujq5liHJUZN/OcTcMZH1Y+/xhLIOJSFHxdR1ysZF1aMoOwewLAQK/OAQd+NqD/MUgv + DhPA== +X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; + d=1e100.net; s=20230601; t=1728680114; x=1729284914; + h=content-transfer-encoding:in-reply-to:content-language:references + :cc:to:from:subject:user-agent:mime-version:date:message-id + :x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; + bh=fk3cCQ1xBgMFb++lgcAzN+vsz5X/4SKReAqNMBCX03E=; + b=Xuo9qK627tSAo7QgC3EFUW3Angg3amj93ZCMs2oKZMS67JuiRdGPcOMQZEzBBaoTUH + 1HcmeaAq+dqwEo5bExJN5zgWDZYzlXQ57ezA8YcLTQ7urFPThGa8yOLevuJYp9lkCtl8 + aWttVQnLcALXLhghwavi2G1JkEZi03XQoKgYIBGy3Fm1h2m62K7rGj2BpOt+jGtQfZ5D + mjDKRCtkoTEphmz/+RbpgifIGheITMDYYPuaa17a8mCOkX7Uopqh9enDRa6QSPJcZzz9 + A/Hn8KHVkUnj/Wi7Ne/IA1Am9LZaHO+QlTozeuJDrm129GOXza/n/aMxb+MDwhDDZuri + qUng== +X-Gm-Message-State: AOJu0YzadmOCmhkPlL65Xvj+rwzV8m0fFStGhHYIP/0MiA0CxQIJdGV+ + SGdVtbp7LtLhh0V8YnCyTKQ8CDbYAinG5gS0oWCpZAVoXgcGCMnZofa3Ig== +X-Google-Smtp-Source: AGHT+IEo8pQiGQ1Irbj+V8cxOWCRq6LNzsj2iCKmpFHDbQNwZl9kkpOi4YzOu4NimoDX5FKxW6DS+Q== +X-Received: by 2002:adf:f98a:0:b0:37d:4aa5:eaed with SMTP id ffacd0b85a97d-37d5529ad5fmr2758088f8f.41.1728680112951; + Fri, 11 Oct 2024 13:55:12 -0700 (PDT) +Received: from [192.168.0.50] ([79.113.150.231]) + by smtp.gmail.com with ESMTPSA id ffacd0b85a97d-37d4b79f9d9sm4711869f8f.77.2024.10.11.13.55.12 + (version=TLS1_3 cipher=TLS_AES_128_GCM_SHA256 bits=128/128); + Fri, 11 Oct 2024 13:55:12 -0700 (PDT) +Message-ID: <8a449697-3353-4249-aadb-c2f997c767e2@gmail.com> +Date: Fri, 11 Oct 2024 23:55:11 +0300 +Precedence: bulk +X-Mailing-List: linux-wireless@vger.kernel.org +List-Id: +List-Subscribe: +List-Unsubscribe: +MIME-Version: 1.0 +User-Agent: Mozilla Thunderbird +Subject: [PATCH v2 17/22] wifi: rtw88: Add rtw8821a_table.{c,h} +From: Bitterblue Smith +To: "linux-wireless@vger.kernel.org" +Cc: Ping-Ke Shih +References: +Content-Language: en-US +In-Reply-To: +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 7bit + +These contain various arrays for initialising RTL8821AU. Also TX power +limits. + +Signed-off-by: Bitterblue Smith +--- +v2: + - Constify card_enable_flow_8821a, enter_lps_flow_8821a, + card_disable_flow_8821a. + - Fix copyright year. +--- + .../wireless/realtek/rtw88/rtw8821a_table.c | 2350 +++++++++++++++++ + .../wireless/realtek/rtw88/rtw8821a_table.h | 21 + + 2 files changed, 2371 insertions(+) + create mode 100644 drivers/net/wireless/realtek/rtw88/rtw8821a_table.c + create mode 100644 drivers/net/wireless/realtek/rtw88/rtw8821a_table.h + +diff --git a/drivers/net/wireless/realtek/rtw88/rtw8821a_table.c b/drivers/net/wireless/realtek/rtw88/rtw8821a_table.c +new file mode 100644 +index 000000000000..c8fd8e331f69 +--- /dev/null ++++ b/drivers/net/wireless/realtek/rtw88/rtw8821a_table.c +@@ -0,0 +1,2350 @@ ++// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause ++/* Copyright(c) 2024 Realtek Corporation ++ */ ++ ++#include "main.h" ++#include "phy.h" ++#include "rtw8821a_table.h" ++ ++static const u32 rtw8821a_mac[] = { ++ 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, 0x00000000, ++ 0x446, 0x00000000, ++ 0x447, 0x00000000, ++ 0x448, 0x00000000, ++ 0x449, 0x000000F0, ++ 0x44A, 0x0000000F, ++ 0x44B, 0x0000003E, ++ 0x44C, 0x00000010, ++ 0x44D, 0x00000000, ++ 0x44E, 0x00000000, ++ 0x44F, 0x00000000, ++ 0x450, 0x00000000, ++ 0x451, 0x000000F0, ++ 0x452, 0x0000000F, ++ 0x453, 0x00000000, ++ 0x456, 0x0000005E, ++ 0x460, 0x00000066, ++ 0x461, 0x00000066, ++ 0x4C8, 0x0000003F, ++ 0x4C9, 0x000000FF, ++ 0x4CC, 0x000000FF, ++ 0x4CD, 0x000000FF, ++ 0x4CE, 0x00000001, ++ 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, ++ 0x525, 0x0000004F, ++ 0x550, 0x00000010, ++ 0x551, 0x00000010, ++ 0x559, 0x00000002, ++ 0x55C, 0x00000050, ++ 0x55D, 0x000000FF, ++ 0x605, 0x00000030, ++ 0x607, 0x00000007, ++ 0x608, 0x0000000E, ++ 0x609, 0x0000002A, ++ 0x620, 0x000000FF, ++ 0x621, 0x000000FF, ++ 0x622, 0x000000FF, ++ 0x623, 0x000000FF, ++ 0x624, 0x000000FF, ++ 0x625, 0x000000FF, ++ 0x626, 0x000000FF, ++ 0x627, 0x000000FF, ++ 0x638, 0x00000050, ++ 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, ++}; ++ ++RTW_DECL_TABLE_PHY_COND(rtw8821a_mac, rtw_phy_cfg_mac); ++ ++static const u32 rtw8821a_agc[] = { ++ 0x81C, 0xBF000001, ++ 0x81C, 0xBF020001, ++ 0x81C, 0xBF040001, ++ 0x81C, 0xBF060001, ++ 0x81C, 0xBE080001, ++ 0x81C, 0xBD0A0001, ++ 0x81C, 0xBC0C0001, ++ 0x81C, 0xBA0E0001, ++ 0x81C, 0xB9100001, ++ 0x81C, 0xB8120001, ++ 0x81C, 0xB7140001, ++ 0x81C, 0xB6160001, ++ 0x81C, 0xB5180001, ++ 0x81C, 0xB41A0001, ++ 0x81C, 0xB31C0001, ++ 0x81C, 0xB21E0001, ++ 0x81C, 0xB1200001, ++ 0x81C, 0xB0220001, ++ 0x81C, 0xAF240001, ++ 0x81C, 0xAE260001, ++ 0x81C, 0xAD280001, ++ 0x81C, 0xAC2A0001, ++ 0x81C, 0xAB2C0001, ++ 0x81C, 0xAA2E0001, ++ 0x81C, 0xA9300001, ++ 0x81C, 0xA8320001, ++ 0x81C, 0xA7340001, ++ 0x81C, 0xA6360001, ++ 0x81C, 0xA5380001, ++ 0x81C, 0xA43A0001, ++ 0x81C, 0x683C0001, ++ 0x81C, 0x673E0001, ++ 0x81C, 0x66400001, ++ 0x81C, 0x65420001, ++ 0x81C, 0x64440001, ++ 0x81C, 0x63460001, ++ 0x81C, 0x62480001, ++ 0x81C, 0x614A0001, ++ 0x81C, 0x474C0001, ++ 0x81C, 0x464E0001, ++ 0x81C, 0x45500001, ++ 0x81C, 0x44520001, ++ 0x81C, 0x43540001, ++ 0x81C, 0x42560001, ++ 0x81C, 0x41580001, ++ 0x81C, 0x285A0001, ++ 0x81C, 0x275C0001, ++ 0x81C, 0x265E0001, ++ 0x81C, 0x25600001, ++ 0x81C, 0x24620001, ++ 0x81C, 0x0A640001, ++ 0x81C, 0x09660001, ++ 0x81C, 0x08680001, ++ 0x81C, 0x076A0001, ++ 0x81C, 0x066C0001, ++ 0x81C, 0x056E0001, ++ 0x81C, 0x04700001, ++ 0x81C, 0x03720001, ++ 0x81C, 0x02740001, ++ 0x81C, 0x01760001, ++ 0x81C, 0x01780001, ++ 0x81C, 0x017A0001, ++ 0x81C, 0x017C0001, ++ 0x81C, 0x017E0001, ++ 0x8000020c, 0x00000000, 0x40000000, 0x00000000, ++ 0x81C, 0xFB000101, ++ 0x81C, 0xFA020101, ++ 0x81C, 0xF9040101, ++ 0x81C, 0xF8060101, ++ 0x81C, 0xF7080101, ++ 0x81C, 0xF60A0101, ++ 0x81C, 0xF50C0101, ++ 0x81C, 0xF40E0101, ++ 0x81C, 0xF3100101, ++ 0x81C, 0xF2120101, ++ 0x81C, 0xF1140101, ++ 0x81C, 0xF0160101, ++ 0x81C, 0xEF180101, ++ 0x81C, 0xEE1A0101, ++ 0x81C, 0xED1C0101, ++ 0x81C, 0xEC1E0101, ++ 0x81C, 0xEB200101, ++ 0x81C, 0xEA220101, ++ 0x81C, 0xE9240101, ++ 0x81C, 0xE8260101, ++ 0x81C, 0xE7280101, ++ 0x81C, 0xE62A0101, ++ 0x81C, 0xE52C0101, ++ 0x81C, 0xE42E0101, ++ 0x81C, 0xE3300101, ++ 0x81C, 0xA5320101, ++ 0x81C, 0xA4340101, ++ 0x81C, 0xA3360101, ++ 0x81C, 0x87380101, ++ 0x81C, 0x863A0101, ++ 0x81C, 0x853C0101, ++ 0x81C, 0x843E0101, ++ 0x81C, 0x69400101, ++ 0x81C, 0x68420101, ++ 0x81C, 0x67440101, ++ 0x81C, 0x66460101, ++ 0x81C, 0x49480101, ++ 0x81C, 0x484A0101, ++ 0x81C, 0x474C0101, ++ 0x81C, 0x2A4E0101, ++ 0x81C, 0x29500101, ++ 0x81C, 0x28520101, ++ 0x81C, 0x27540101, ++ 0x81C, 0x26560101, ++ 0x81C, 0x25580101, ++ 0x81C, 0x245A0101, ++ 0x81C, 0x235C0101, ++ 0x81C, 0x055E0101, ++ 0x81C, 0x04600101, ++ 0x81C, 0x03620101, ++ 0x81C, 0x02640101, ++ 0x81C, 0x01660101, ++ 0x81C, 0x01680101, ++ 0x81C, 0x016A0101, ++ 0x81C, 0x016C0101, ++ 0x81C, 0x016E0101, ++ 0x81C, 0x01700101, ++ 0x81C, 0x01720101, ++ 0x9000040c, 0x00000000, 0x40000000, 0x00000000, ++ 0x81C, 0xFB000101, ++ 0x81C, 0xFA020101, ++ 0x81C, 0xF9040101, ++ 0x81C, 0xF8060101, ++ 0x81C, 0xF7080101, ++ 0x81C, 0xF60A0101, ++ 0x81C, 0xF50C0101, ++ 0x81C, 0xF40E0101, ++ 0x81C, 0xF3100101, ++ 0x81C, 0xF2120101, ++ 0x81C, 0xF1140101, ++ 0x81C, 0xF0160101, ++ 0x81C, 0xEF180101, ++ 0x81C, 0xEE1A0101, ++ 0x81C, 0xED1C0101, ++ 0x81C, 0xEC1E0101, ++ 0x81C, 0xEB200101, ++ 0x81C, 0xEA220101, ++ 0x81C, 0xE9240101, ++ 0x81C, 0xE8260101, ++ 0x81C, 0xE7280101, ++ 0x81C, 0xE62A0101, ++ 0x81C, 0xE52C0101, ++ 0x81C, 0xE42E0101, ++ 0x81C, 0xE3300101, ++ 0x81C, 0xA5320101, ++ 0x81C, 0xA4340101, ++ 0x81C, 0xA3360101, ++ 0x81C, 0x87380101, ++ 0x81C, 0x863A0101, ++ 0x81C, 0x853C0101, ++ 0x81C, 0x843E0101, ++ 0x81C, 0x69400101, ++ 0x81C, 0x68420101, ++ 0x81C, 0x67440101, ++ 0x81C, 0x66460101, ++ 0x81C, 0x49480101, ++ 0x81C, 0x484A0101, ++ 0x81C, 0x474C0101, ++ 0x81C, 0x2A4E0101, ++ 0x81C, 0x29500101, ++ 0x81C, 0x28520101, ++ 0x81C, 0x27540101, ++ 0x81C, 0x26560101, ++ 0x81C, 0x25580101, ++ 0x81C, 0x245A0101, ++ 0x81C, 0x235C0101, ++ 0x81C, 0x055E0101, ++ 0x81C, 0x04600101, ++ 0x81C, 0x03620101, ++ 0x81C, 0x02640101, ++ 0x81C, 0x01660101, ++ 0x81C, 0x01680101, ++ 0x81C, 0x016A0101, ++ 0x81C, 0x016C0101, ++ 0x81C, 0x016E0101, ++ 0x81C, 0x01700101, ++ 0x81C, 0x01720101, ++ 0xA0000000, 0x00000000, ++ 0x81C, 0xFF000101, ++ 0x81C, 0xFF020101, ++ 0x81C, 0xFE040101, ++ 0x81C, 0xFD060101, ++ 0x81C, 0xFC080101, ++ 0x81C, 0xFD0A0101, ++ 0x81C, 0xFC0C0101, ++ 0x81C, 0xFB0E0101, ++ 0x81C, 0xFA100101, ++ 0x81C, 0xF9120101, ++ 0x81C, 0xF8140101, ++ 0x81C, 0xF7160101, ++ 0x81C, 0xF6180101, ++ 0x81C, 0xF51A0101, ++ 0x81C, 0xF41C0101, ++ 0x81C, 0xF31E0101, ++ 0x81C, 0xF2200101, ++ 0x81C, 0xF1220101, ++ 0x81C, 0xF0240101, ++ 0x81C, 0xEF260101, ++ 0x81C, 0xEE280101, ++ 0x81C, 0xED2A0101, ++ 0x81C, 0xEC2C0101, ++ 0x81C, 0xEB2E0101, ++ 0x81C, 0xEA300101, ++ 0x81C, 0xE9320101, ++ 0x81C, 0xE8340101, ++ 0x81C, 0xE7360101, ++ 0x81C, 0xE6380101, ++ 0x81C, 0xE53A0101, ++ 0x81C, 0xE43C0101, ++ 0x81C, 0xE33E0101, ++ 0x81C, 0xA5400101, ++ 0x81C, 0xA4420101, ++ 0x81C, 0xA3440101, ++ 0x81C, 0x87460101, ++ 0x81C, 0x86480101, ++ 0x81C, 0x854A0101, ++ 0x81C, 0x844C0101, ++ 0x81C, 0x694E0101, ++ 0x81C, 0x68500101, ++ 0x81C, 0x67520101, ++ 0x81C, 0x66540101, ++ 0x81C, 0x49560101, ++ 0x81C, 0x48580101, ++ 0x81C, 0x475A0101, ++ 0x81C, 0x2A5C0101, ++ 0x81C, 0x295E0101, ++ 0x81C, 0x28600101, ++ 0x81C, 0x27620101, ++ 0x81C, 0x26640101, ++ 0x81C, 0x25660101, ++ 0x81C, 0x24680101, ++ 0x81C, 0x236A0101, ++ 0x81C, 0x056C0101, ++ 0x81C, 0x046E0101, ++ 0x81C, 0x03700101, ++ 0x81C, 0x02720101, ++ 0xB0000000, 0x00000000, ++ 0x81C, 0x01740101, ++ 0x81C, 0x01760101, ++ 0x81C, 0x01780101, ++ 0x81C, 0x017A0101, ++ 0x81C, 0x017C0101, ++ 0x81C, 0x017E0101, ++ 0xC50, 0x00000022, ++ 0xC50, 0x00000020, ++}; ++ ++RTW_DECL_TABLE_PHY_COND(rtw8821a_agc, rtw_phy_cfg_agc); ++ ++static const u32 rtw8821a_bb[] = { ++ 0x800, 0x0020D090, ++ 0x804, 0x080112E0, ++ 0x808, 0x0E028211, ++ 0x80C, 0x92131111, ++ 0x810, 0x20101261, ++ 0x814, 0x020C3D10, ++ 0x818, 0x03A00385, ++ 0x820, 0x00000000, ++ 0x824, 0x00030FE0, ++ 0x828, 0x00000000, ++ 0x82C, 0x002081DD, ++ 0x830, 0x2AAAEEC8, ++ 0x834, 0x0037A706, ++ 0x838, 0x06489B44, ++ 0x83C, 0x0000095B, ++ 0x840, 0xC0000001, ++ 0x844, 0x40003CDE, ++ 0x848, 0x62103F8B, ++ 0x84C, 0x6CFDFFB8, ++ 0x850, 0x28874706, ++ 0x854, 0x0001520C, ++ 0x858, 0x8060E000, ++ 0x85C, 0x74210168, ++ 0x860, 0x6929C321, ++ 0x864, 0x79727432, ++ 0x868, 0x8CA7A314, ++ 0x86C, 0x888C2878, ++ 0x870, 0x08888888, ++ 0x874, 0x31612C2E, ++ 0x878, 0x00000152, ++ 0x87C, 0x000FD000, ++ 0x8A0, 0x00000013, ++ 0x8A4, 0x7F7F7F7F, ++ 0x8A8, 0xA2000338, ++ 0x8AC, 0x0FF0FA0A, ++ 0x8B4, 0x000FC080, ++ 0x8B8, 0x6C10D7FF, ++ 0x8BC, 0x0CA52090, ++ 0x8C0, 0x1BF00020, ++ 0x8C4, 0x00000000, ++ 0x8C8, 0x00013169, ++ 0x8CC, 0x08248492, ++ 0x8D4, 0x940008A0, ++ 0x8D8, 0x290B5612, ++ 0x8F8, 0x400002C0, ++ 0x8FC, 0x00000000, ++ 0x900, 0x00000700, ++ 0x90C, 0x00000000, ++ 0x910, 0x0000FC00, ++ 0x914, 0x00000404, ++ 0x918, 0x1C1028C0, ++ 0x91C, 0x64B11A1C, ++ 0x920, 0xE0767233, ++ 0x924, 0x055AA500, ++ 0x928, 0x00000004, ++ 0x92C, 0xFFFE0000, ++ 0x930, 0xFFFFFFFE, ++ 0x934, 0x001FFFFF, ++ 0x960, 0x00000000, ++ 0x964, 0x00000000, ++ 0x968, 0x00000000, ++ 0x96C, 0x00000000, ++ 0x970, 0x801FFFFF, ++ 0x974, 0x000003FF, ++ 0x978, 0x00000000, ++ 0x97C, 0x00000000, ++ 0x980, 0x00000000, ++ 0x984, 0x00000000, ++ 0x988, 0x00000000, ++ 0x990, 0x27100000, ++ 0x994, 0xFFFF0100, ++ 0x998, 0xFFFFFF5C, ++ 0x99C, 0xFFFFFFFF, ++ 0x9A0, 0x000000FF, ++ 0x9A4, 0x00480080, ++ 0x9A8, 0x00000000, ++ 0x9AC, 0x00000000, ++ 0x9B0, 0x81081008, ++ 0x9B4, 0x01081008, ++ 0x9B8, 0x01081008, ++ 0x9BC, 0x01081008, ++ 0x9D0, 0x00000000, ++ 0x9D4, 0x00000000, ++ 0x9D8, 0x00000000, ++ 0x9DC, 0x00000000, ++ 0x9E0, 0x00005D00, ++ 0x9E4, 0x00000003, ++ 0x9E8, 0x00000001, ++ 0xA00, 0x00D047C8, ++ 0xA04, 0x01FF800C, ++ 0xA08, 0x8C8A8300, ++ 0xA0C, 0x2E68000F, ++ 0xA10, 0x9500BB78, ++ 0xA14, 0x11144028, ++ 0xA18, 0x00881117, ++ 0xA1C, 0x89140F00, ++ 0xA20, 0x1A1B0000, ++ 0xA24, 0x090E1317, ++ 0xA28, 0x00000204, ++ 0xA2C, 0x00900000, ++ 0xA70, 0x101FFF00, ++ 0xA74, 0x00000008, ++ 0xA78, 0x00000900, ++ 0xA7C, 0x225B0606, ++ 0xA80, 0x21805490, ++ 0xA84, 0x001F0000, ++ 0XB00, 0x03100040, ++ 0XB04, 0x0000B000, ++ 0XB08, 0xAE0201EB, ++ 0XB0C, 0x01003207, ++ 0XB10, 0x00009807, ++ 0XB14, 0x01000000, ++ 0XB18, 0x00000002, ++ 0XB1C, 0x00000002, ++ 0XB20, 0x0000001F, ++ 0XB24, 0x03020100, ++ 0XB28, 0x07060504, ++ 0XB2C, 0x0B0A0908, ++ 0XB30, 0x0F0E0D0C, ++ 0XB34, 0x13121110, ++ 0XB38, 0x17161514, ++ 0XB3C, 0x0000003A, ++ 0XB40, 0x00000000, ++ 0XB44, 0x00000000, ++ 0XB48, 0x13000032, ++ 0XB4C, 0x48080000, ++ 0XB50, 0x00000000, ++ 0XB54, 0x00000000, ++ 0XB58, 0x00000000, ++ 0XB5C, 0x00000000, ++ 0xC00, 0x00000007, ++ 0xC04, 0x00042020, ++ 0xC08, 0x80410231, ++ 0xC0C, 0x00000000, ++ 0xC10, 0x00000100, ++ 0xC14, 0x01000000, ++ 0xC1C, 0x40000003, ++ 0xC20, 0x2C2C2C2C, ++ 0xC24, 0x30303030, ++ 0xC28, 0x30303030, ++ 0xC2C, 0x2C2C2C2C, ++ 0xC30, 0x2C2C2C2C, ++ 0xC34, 0x2C2C2C2C, ++ 0xC38, 0x2C2C2C2C, ++ 0xC3C, 0x2A2A2A2A, ++ 0xC40, 0x2A2A2A2A, ++ 0xC44, 0x2A2A2A2A, ++ 0xC48, 0x2A2A2A2A, ++ 0xC4C, 0x2A2A2A2A, ++ 0xC50, 0x00000020, ++ 0xC54, 0x001C1208, ++ 0xC58, 0x30000C1C, ++ 0xC5C, 0x00000058, ++ 0xC60, 0x34344443, ++ 0xC64, 0x07003333, ++ 0xC68, 0x19791979, ++ 0xC6C, 0x19791979, ++ 0xC70, 0x19791979, ++ 0xC74, 0x19791979, ++ 0xC78, 0x19791979, ++ 0xC7C, 0x19791979, ++ 0xC80, 0x19791979, ++ 0xC84, 0x19791979, ++ 0xC94, 0x0100005C, ++ 0xC98, 0x00000000, ++ 0xC9C, 0x00000000, ++ 0xCA0, 0x00000029, ++ 0xCA4, 0x08040201, ++ 0xCA8, 0x80402010, ++ 0xCB0, 0x77775747, ++ 0xCB4, 0x10000077, ++ 0xCB8, 0x00508240, ++}; ++ ++RTW_DECL_TABLE_PHY_COND(rtw8821a_bb, rtw_phy_cfg_bb); ++ ++static const struct rtw_phy_pg_cfg_pair rtw8821a_bb_pg[] = { ++ { 0, 0, 0, 0x00000c20, 0xffffffff, 0x32343638, }, ++ { 0, 0, 0, 0x00000c24, 0xffffffff, 0x36363838, }, ++ { 0, 0, 0, 0x00000c28, 0xffffffff, 0x28303234, }, ++ { 0, 0, 0, 0x00000c2c, 0xffffffff, 0x34363838, }, ++ { 0, 0, 0, 0x00000c30, 0xffffffff, 0x26283032, }, ++ { 0, 0, 0, 0x00000c3c, 0xffffffff, 0x32343636, }, ++ { 0, 0, 0, 0x00000c40, 0xffffffff, 0x24262830, }, ++ { 0, 0, 0, 0x00000c44, 0x0000ffff, 0x00002022, }, ++ { 1, 0, 0, 0x00000c24, 0xffffffff, 0x34343636, }, ++ { 1, 0, 0, 0x00000c28, 0xffffffff, 0x26283032, }, ++ { 1, 0, 0, 0x00000c2c, 0xffffffff, 0x32343636, }, ++ { 1, 0, 0, 0x00000c30, 0xffffffff, 0x24262830, }, ++ { 1, 0, 0, 0x00000c3c, 0xffffffff, 0x32343636, }, ++ { 1, 0, 0, 0x00000c40, 0xffffffff, 0x24262830, }, ++ { 1, 0, 0, 0x00000c44, 0x0000ffff, 0x00002022, }, ++}; ++ ++RTW_DECL_TABLE_BB_PG(rtw8821a_bb_pg); ++ ++static const u32 rtw8821a_rf_a[] = { ++ 0x018, 0x0001712A, ++ 0x056, 0x00051CF2, ++ 0x066, 0x00040000, ++ 0x000, 0x00010000, ++ 0x01E, 0x00080000, ++ 0x082, 0x00000830, ++ 0x083, 0x00021800, ++ 0x084, 0x00028000, ++ 0x085, 0x00048000, ++ 0x80000111, 0x00000000, 0x40000000, 0x00000000, ++ 0x086, 0x0009483A, ++ 0xA0000000, 0x00000000, ++ 0x086, 0x00094838, ++ 0xB0000000, 0x00000000, ++ 0x087, 0x00044980, ++ 0x088, 0x00048000, ++ 0x089, 0x0000D480, ++ 0x08A, 0x00042240, ++ 0x08B, 0x000F0380, ++ 0x08C, 0x00090000, ++ 0x08D, 0x00022852, ++ 0x08E, 0x00065540, ++ 0x08F, 0x00088001, ++ 0x0EF, 0x00020000, ++ 0x03E, 0x00000380, ++ 0x03F, 0x00090018, ++ 0x03E, 0x00020380, ++ 0x03F, 0x000A0018, ++ 0x03E, 0x00040308, ++ 0x03F, 0x000A0018, ++ 0x03E, 0x00060018, ++ 0x03F, 0x000A0018, ++ 0x0EF, 0x00000000, ++ 0x018, 0x0001712A, ++ 0x089, 0x00000080, ++ 0x08B, 0x00080180, ++ 0x0EF, 0x00001000, ++ 0x03A, 0x00000244, ++ 0x03B, 0x00038027, ++ 0x03C, 0x00082000, ++ 0x03A, 0x00000244, ++ 0x03B, 0x00030113, ++ 0x03C, 0x00082000, ++ 0x03A, 0x0000014C, ++ 0x03B, 0x00028027, ++ 0x03C, 0x00082000, ++ 0x03A, 0x000000CC, ++ 0x03B, 0x00027027, ++ 0x03C, 0x00042000, ++ 0x03A, 0x0000014C, ++ 0x03B, 0x0001F913, ++ 0x03C, 0x00042000, ++ 0x03A, 0x0000010C, ++ 0x03B, 0x00017F10, ++ 0x03C, 0x00012000, ++ 0x03A, 0x000000D0, ++ 0x03B, 0x00008027, ++ 0x03C, 0x000CA000, ++ 0x03A, 0x00000244, ++ 0x03B, 0x00078027, ++ 0x03C, 0x00082000, ++ 0x03A, 0x00000244, ++ 0x03B, 0x00070113, ++ 0x03C, 0x00082000, ++ 0x03A, 0x0000014C, ++ 0x03B, 0x00068027, ++ 0x03C, 0x00082000, ++ 0x03A, 0x000000CC, ++ 0x03B, 0x00067027, ++ 0x03C, 0x00042000, ++ 0x03A, 0x0000014C, ++ 0x03B, 0x0005F913, ++ 0x03C, 0x00042000, ++ 0x03A, 0x0000010C, ++ 0x03B, 0x00057F10, ++ 0x03C, 0x00012000, ++ 0x03A, 0x000000D0, ++ 0x03B, 0x00048027, ++ 0x03C, 0x000CA000, ++ 0x03A, 0x00000244, ++ 0x03B, 0x000B8027, ++ 0x03C, 0x00082000, ++ 0x03A, 0x00000244, ++ 0x03B, 0x000B0113, ++ 0x03C, 0x00082000, ++ 0x03A, 0x0000014C, ++ 0x03B, 0x000A8027, ++ 0x03C, 0x00082000, ++ 0x03A, 0x000000CC, ++ 0x03B, 0x000A7027, ++ 0x03C, 0x00042000, ++ 0x03A, 0x0000014C, ++ 0x03B, 0x0009F913, ++ 0x03C, 0x00042000, ++ 0x03A, 0x0000010C, ++ 0x03B, 0x00097F10, ++ 0x03C, 0x00012000, ++ 0x03A, 0x000000D0, ++ 0x03B, 0x00088027, ++ 0x03C, 0x000CA000, ++ 0x0EF, 0x00000000, ++ 0x0EF, 0x00001100, ++ 0x80000111, 0x00000000, 0x40000000, 0x00000000, ++ 0x034, 0x0004ADF3, ++ 0x034, 0x00049DF0, ++ 0x90000110, 0x00000000, 0x40000000, 0x00000000, ++ 0x034, 0x0004ADF3, ++ 0x034, 0x00049DF0, ++ 0x90000210, 0x00000000, 0x40000000, 0x00000000, ++ 0x034, 0x0004ADF5, ++ 0x034, 0x00049DF2, ++ 0x9000020c, 0x00000000, 0x40000000, 0x00000000, ++ 0x034, 0x0004A0F3, ++ 0x034, 0x000490B1, ++ 0x9000040c, 0x00000000, 0x40000000, 0x00000000, ++ 0x034, 0x0004A0F3, ++ 0x034, 0x000490B1, ++ 0x90000200, 0x00000000, 0x40000000, 0x00000000, ++ 0x034, 0x0004ADF5, ++ 0x034, 0x00049DF2, ++ 0x90000410, 0x00000000, 0x40000000, 0x00000000, ++ 0x034, 0x0004ADF3, ++ 0x034, 0x00049DF0, ++ 0xA0000000, 0x00000000, ++ 0x034, 0x0004ADF7, ++ 0x034, 0x00049DF3, ++ 0xB0000000, 0x00000000, ++ 0x80000111, 0x00000000, 0x40000000, 0x00000000, ++ 0x034, 0x00048DED, ++ 0x034, 0x00047DEA, ++ 0x034, 0x00046DE7, ++ 0x034, 0x00045CE9, ++ 0x034, 0x00044CE6, ++ 0x034, 0x000438C6, ++ 0x034, 0x00042886, ++ 0x034, 0x00041486, ++ 0x034, 0x00040447, ++ 0x90000110, 0x00000000, 0x40000000, 0x00000000, ++ 0x034, 0x00048DED, ++ 0x034, 0x00047DEA, ++ 0x034, 0x00046DE7, ++ 0x034, 0x00045CE9, ++ 0x034, 0x00044CE6, ++ 0x034, 0x000438C6, ++ 0x034, 0x00042886, ++ 0x034, 0x00041486, ++ 0x034, 0x00040447, ++ 0x9000020c, 0x00000000, 0x40000000, 0x00000000, ++ 0x034, 0x000480AE, ++ 0x034, 0x000470AB, ++ 0x034, 0x0004608B, ++ 0x034, 0x00045069, ++ 0x034, 0x00044048, ++ 0x034, 0x00043045, ++ 0x034, 0x00042026, ++ 0x034, 0x00041023, ++ 0x034, 0x00040002, ++ 0x9000040c, 0x00000000, 0x40000000, 0x00000000, ++ 0x034, 0x000480AE, ++ 0x034, 0x000470AB, ++ 0x034, 0x0004608B, ++ 0x034, 0x00045069, ++ 0x034, 0x00044048, ++ 0x034, 0x00043045, ++ 0x034, 0x00042026, ++ 0x034, 0x00041023, ++ 0x034, 0x00040002, ++ 0x90000410, 0x00000000, 0x40000000, 0x00000000, ++ 0x034, 0x00048DED, ++ 0x034, 0x00047DEA, ++ 0x034, 0x00046DE7, ++ 0x034, 0x00045CE9, ++ 0x034, 0x00044CE6, ++ 0x034, 0x000438C6, ++ 0x034, 0x00042886, ++ 0x034, 0x00041486, ++ 0x034, 0x00040447, ++ 0xA0000000, 0x00000000, ++ 0x034, 0x00048DEF, ++ 0x034, 0x00047DEC, ++ 0x034, 0x00046DE9, ++ 0x034, 0x00045CCB, ++ 0x034, 0x0004488D, ++ 0x034, 0x0004348D, ++ 0x034, 0x0004248A, ++ 0x034, 0x0004108D, ++ 0x034, 0x0004008A, ++ 0xB0000000, 0x00000000, ++ 0x80000210, 0x00000000, 0x40000000, 0x00000000, ++ 0x034, 0x0002ADF4, ++ 0x9000020c, 0x00000000, 0x40000000, 0x00000000, ++ 0x034, 0x0002A0F3, ++ 0x9000040c, 0x00000000, 0x40000000, 0x00000000, ++ 0x034, 0x0002A0F3, ++ 0x90000200, 0x00000000, 0x40000000, 0x00000000, ++ 0x034, 0x0002ADF4, ++ 0xA0000000, 0x00000000, ++ 0x034, 0x0002ADF7, ++ 0xB0000000, 0x00000000, ++ 0x80000111, 0x00000000, 0x40000000, 0x00000000, ++ 0x034, 0x00029DF4, ++ 0x90000110, 0x00000000, 0x40000000, 0x00000000, ++ 0x034, 0x00029DF4, ++ 0x90000210, 0x00000000, 0x40000000, 0x00000000, ++ 0x034, 0x00029DF1, ++ 0x9000020c, 0x00000000, 0x40000000, 0x00000000, ++ 0x034, 0x000290F0, ++ 0x9000040c, 0x00000000, 0x40000000, 0x00000000, ++ 0x034, 0x000290F0, ++ 0x90000200, 0x00000000, 0x40000000, 0x00000000, ++ 0x034, 0x00029DF1, ++ 0x90000410, 0x00000000, 0x40000000, 0x00000000, ++ 0x034, 0x00029DF4, ++ 0xA0000000, 0x00000000, ++ 0x034, 0x00029DF2, ++ 0xB0000000, 0x00000000, ++ 0x80000111, 0x00000000, 0x40000000, 0x00000000, ++ 0x034, 0x00028DF1, ++ 0x034, 0x00027DEE, ++ 0x034, 0x00026DEB, ++ 0x034, 0x00025CEC, ++ 0x034, 0x00024CE9, ++ 0x034, 0x000238CA, ++ 0x034, 0x00022889, ++ 0x034, 0x00021489, ++ 0x034, 0x0002044A, ++ 0x90000110, 0x00000000, 0x40000000, 0x00000000, ++ 0x034, 0x00028DF1, ++ 0x034, 0x00027DEE, ++ 0x034, 0x00026DEB, ++ 0x034, 0x00025CEC, ++ 0x034, 0x00024CE9, ++ 0x034, 0x000238CA, ++ 0x034, 0x00022889, ++ 0x034, 0x00021489, ++ 0x034, 0x0002044A, ++ 0x9000020c, 0x00000000, 0x40000000, 0x00000000, ++ 0x034, 0x000280AF, ++ 0x034, 0x000270AC, ++ 0x034, 0x0002608B, ++ 0x034, 0x00025069, ++ 0x034, 0x00024048, ++ 0x034, 0x00023045, ++ 0x034, 0x00022026, ++ 0x034, 0x00021023, ++ 0x034, 0x00020002, ++ 0x9000040c, 0x00000000, 0x40000000, 0x00000000, ++ 0x034, 0x000280AF, ++ 0x034, 0x000270AC, ++ 0x034, 0x0002608B, ++ 0x034, 0x00025069, ++ 0x034, 0x00024048, ++ 0x034, 0x00023045, ++ 0x034, 0x00022026, ++ 0x034, 0x00021023, ++ 0x034, 0x00020002, ++ 0x90000410, 0x00000000, 0x40000000, 0x00000000, ++ 0x034, 0x00028DF1, ++ 0x034, 0x00027DEE, ++ 0x034, 0x00026DEB, ++ 0x034, 0x00025CEC, ++ 0x034, 0x00024CE9, ++ 0x034, 0x000238CA, ++ 0x034, 0x00022889, ++ 0x034, 0x00021489, ++ 0x034, 0x0002044A, ++ 0xA0000000, 0x00000000, ++ 0x034, 0x00028DEE, ++ 0x034, 0x00027DEB, ++ 0x034, 0x00026CCD, ++ 0x034, 0x00025CCA, ++ 0x034, 0x0002488C, ++ 0x034, 0x0002384C, ++ 0x034, 0x00022849, ++ 0x034, 0x00021449, ++ 0x034, 0x0002004D, ++ 0xB0000000, 0x00000000, ++ 0x8000020c, 0x00000000, 0x40000000, 0x00000000, ++ 0x034, 0x0000A0D7, ++ 0x034, 0x000090D3, ++ 0x034, 0x000080B1, ++ 0x034, 0x000070AE, ++ 0x9000040c, 0x00000000, 0x40000000, 0x00000000, ++ 0x034, 0x0000A0D7, ++ 0x034, 0x000090D3, ++ 0x034, 0x000080B1, ++ 0x034, 0x000070AE, ++ 0xA0000000, 0x00000000, ++ 0x034, 0x0000ADF7, ++ 0x034, 0x00009DF4, ++ 0x034, 0x00008DF1, ++ 0x034, 0x00007DEE, ++ 0xB0000000, 0x00000000, ++ 0x80000111, 0x00000000, 0x40000000, 0x00000000, ++ 0x034, 0x00006DEB, ++ 0x034, 0x00005CEC, ++ 0x034, 0x00004CE9, ++ 0x034, 0x000038CA, ++ 0x034, 0x00002889, ++ 0x034, 0x00001489, ++ 0x034, 0x0000044A, ++ 0x90000110, 0x00000000, 0x40000000, 0x00000000, ++ 0x034, 0x00006DEB, ++ 0x034, 0x00005CEC, ++ 0x034, 0x00004CE9, ++ 0x034, 0x000038CA, ++ 0x034, 0x00002889, ++ 0x034, 0x00001489, ++ 0x034, 0x0000044A, ++ 0x9000020c, 0x00000000, 0x40000000, 0x00000000, ++ 0x034, 0x0000608D, ++ 0x034, 0x0000506B, ++ 0x034, 0x0000404A, ++ 0x034, 0x00003047, ++ 0x034, 0x00002044, ++ 0x034, 0x00001025, ++ 0x034, 0x00000004, ++ 0x9000040c, 0x00000000, 0x40000000, 0x00000000, ++ 0x034, 0x0000608D, ++ 0x034, 0x0000506B, ++ 0x034, 0x0000404A, ++ 0x034, 0x00003047, ++ 0x034, 0x00002044, ++ 0x034, 0x00001025, ++ 0x034, 0x00000004, ++ 0x90000410, 0x00000000, 0x40000000, 0x00000000, ++ 0x034, 0x00006DEB, ++ 0x034, 0x00005CEC, ++ 0x034, 0x00004CE9, ++ 0x034, 0x000038CA, ++ 0x034, 0x00002889, ++ 0x034, 0x00001489, ++ 0x034, 0x0000044A, ++ 0xA0000000, 0x00000000, ++ 0x034, 0x00006DCD, ++ 0x034, 0x00005CCD, ++ 0x034, 0x00004CCA, ++ 0x034, 0x0000388C, ++ 0x034, 0x00002888, ++ 0x034, 0x00001488, ++ 0x034, 0x00000486, ++ 0xB0000000, 0x00000000, ++ 0x0EF, 0x00000000, ++ 0x018, 0x0001712A, ++ 0x0EF, 0x00000040, ++ 0x80000111, 0x00000000, 0x40000000, 0x00000000, ++ 0x035, 0x00000187, ++ 0x035, 0x00008187, ++ 0x035, 0x00010187, ++ 0x035, 0x00020188, ++ 0x035, 0x00028188, ++ 0x035, 0x00030188, ++ 0x035, 0x00040188, ++ 0x035, 0x00048188, ++ 0x035, 0x00050188, ++ 0x90000110, 0x00000000, 0x40000000, 0x00000000, ++ 0x035, 0x00000187, ++ 0x035, 0x00008187, ++ 0x035, 0x00010187, ++ 0x035, 0x00020188, ++ 0x035, 0x00028188, ++ 0x035, 0x00030188, ++ 0x035, 0x00040188, ++ 0x035, 0x00048188, ++ 0x035, 0x00050188, ++ 0x90000210, 0x00000000, 0x40000000, 0x00000000, ++ 0x035, 0x00000128, ++ 0x035, 0x00008128, ++ 0x035, 0x00010128, ++ 0x035, 0x000201C8, ++ 0x035, 0x000281C8, ++ 0x035, 0x000301C8, ++ 0x035, 0x000401C8, ++ 0x035, 0x000481C8, ++ 0x035, 0x000501C8, ++ 0x9000040c, 0x00000000, 0x40000000, 0x00000000, ++ 0x035, 0x00000145, ++ 0x035, 0x00008145, ++ 0x035, 0x00010145, ++ 0x035, 0x00020196, ++ 0x035, 0x00028196, ++ 0x035, 0x00030196, ++ 0x035, 0x000401C7, ++ 0x035, 0x000481C7, ++ 0x035, 0x000501C7, ++ 0x90000200, 0x00000000, 0x40000000, 0x00000000, ++ 0x035, 0x00000128, ++ 0x035, 0x00008128, ++ 0x035, 0x00010128, ++ 0x035, 0x000201C8, ++ 0x035, 0x000281C8, ++ 0x035, 0x000301C8, ++ 0x035, 0x000401C8, ++ 0x035, 0x000481C8, ++ 0x035, 0x000501C8, ++ 0x90000410, 0x00000000, 0x40000000, 0x00000000, ++ 0x035, 0x00000187, ++ 0x035, 0x00008187, ++ 0x035, 0x00010187, ++ 0x035, 0x00020188, ++ 0x035, 0x00028188, ++ 0x035, 0x00030188, ++ 0x035, 0x00040188, ++ 0x035, 0x00048188, ++ 0x035, 0x00050188, ++ 0xA0000000, 0x00000000, ++ 0x035, 0x00000145, ++ 0x035, 0x00008145, ++ 0x035, 0x00010145, ++ 0x035, 0x00020196, ++ 0x035, 0x00028196, ++ 0x035, 0x00030196, ++ 0x035, 0x000401C7, ++ 0x035, 0x000481C7, ++ 0x035, 0x000501C7, ++ 0xB0000000, 0x00000000, ++ 0x0EF, 0x00000000, ++ 0x018, 0x0001712A, ++ 0x0EF, 0x00000010, ++ 0x80000111, 0x00000000, 0x40000000, 0x00000000, ++ 0x036, 0x00085733, ++ 0x036, 0x0008D733, ++ 0x036, 0x00095733, ++ 0x036, 0x0009D733, ++ 0x036, 0x000A64B4, ++ 0x036, 0x000AE4B4, ++ 0x036, 0x000B64B4, ++ 0x036, 0x000BE4B4, ++ 0x036, 0x000C64B4, ++ 0x036, 0x000CE4B4, ++ 0x036, 0x000D64B4, ++ 0x036, 0x000DE4B4, ++ 0x90000110, 0x00000000, 0x40000000, 0x00000000, ++ 0x036, 0x00085733, ++ 0x036, 0x0008D733, ++ 0x036, 0x00095733, ++ 0x036, 0x0009D733, ++ 0x036, 0x000A64B4, ++ 0x036, 0x000AE4B4, ++ 0x036, 0x000B64B4, ++ 0x036, 0x000BE4B4, ++ 0x036, 0x000C64B4, ++ 0x036, 0x000CE4B4, ++ 0x036, 0x000D64B4, ++ 0x036, 0x000DE4B4, ++ 0x90000210, 0x00000000, 0x40000000, 0x00000000, ++ 0x036, 0x000063B5, ++ 0x036, 0x0000E3B5, ++ 0x036, 0x000163B5, ++ 0x036, 0x0001E3B5, ++ 0x036, 0x000263B5, ++ 0x036, 0x0002E3B5, ++ 0x036, 0x000363B5, ++ 0x036, 0x0003E3B5, ++ 0x036, 0x000463B5, ++ 0x036, 0x0004E3B5, ++ 0x036, 0x000563B5, ++ 0x036, 0x0005E3B5, ++ 0x9000040c, 0x00000000, 0x40000000, 0x00000000, ++ 0x036, 0x000056B3, ++ 0x036, 0x0000D6B3, ++ 0x036, 0x000156B3, ++ 0x036, 0x0001D6B3, ++ 0x036, 0x00026634, ++ 0x036, 0x0002E634, ++ 0x036, 0x00036634, ++ 0x036, 0x0003E634, ++ 0x036, 0x000467B4, ++ 0x036, 0x0004E7B4, ++ 0x036, 0x000567B4, ++ 0x036, 0x0005E7B4, ++ 0x90000200, 0x00000000, 0x40000000, 0x00000000, ++ 0x036, 0x000063B5, ++ 0x036, 0x0000E3B5, ++ 0x036, 0x000163B5, ++ 0x036, 0x0001E3B5, ++ 0x036, 0x000263B5, ++ 0x036, 0x0002E3B5, ++ 0x036, 0x000363B5, ++ 0x036, 0x0003E3B5, ++ 0x036, 0x000463B5, ++ 0x036, 0x0004E3B5, ++ 0x036, 0x000563B5, ++ 0x036, 0x0005E3B5, ++ 0x90000410, 0x00000000, 0x40000000, 0x00000000, ++ 0x036, 0x00085733, ++ 0x036, 0x0008D733, ++ 0x036, 0x00095733, ++ 0x036, 0x0009D733, ++ 0x036, 0x000A64B4, ++ 0x036, 0x000AE4B4, ++ 0x036, 0x000B64B4, ++ 0x036, 0x000BE4B4, ++ 0x036, 0x000C64B4, ++ 0x036, 0x000CE4B4, ++ 0x036, 0x000D64B4, ++ 0x036, 0x000DE4B4, ++ 0xA0000000, 0x00000000, ++ 0x036, 0x000056B3, ++ 0x036, 0x0000D6B3, ++ 0x036, 0x000156B3, ++ 0x036, 0x0001D6B3, ++ 0x036, 0x00026634, ++ 0x036, 0x0002E634, ++ 0x036, 0x00036634, ++ 0x036, 0x0003E634, ++ 0x036, 0x000467B4, ++ 0x036, 0x0004E7B4, ++ 0x036, 0x000567B4, ++ 0x036, 0x0005E7B4, ++ 0xB0000000, 0x00000000, ++ 0x0EF, 0x00000000, ++ 0x0EF, 0x00000008, ++ 0x80000111, 0x00000000, 0x40000000, 0x00000000, ++ 0x03C, 0x000001C8, ++ 0x03C, 0x00000492, ++ 0x90000110, 0x00000000, 0x40000000, 0x00000000, ++ 0x03C, 0x000001C8, ++ 0x03C, 0x00000492, ++ 0x90000210, 0x00000000, 0x40000000, 0x00000000, ++ 0x03C, 0x000001B6, ++ 0x03C, 0x00000492, ++ 0x9000040c, 0x00000000, 0x40000000, 0x00000000, ++ 0x03C, 0x0000022A, ++ 0x03C, 0x00000594, ++ 0x90000200, 0x00000000, 0x40000000, 0x00000000, ++ 0x03C, 0x000001B6, ++ 0x03C, 0x00000492, ++ 0x90000410, 0x00000000, 0x40000000, 0x00000000, ++ 0x03C, 0x000001C8, ++ 0x03C, 0x00000492, ++ 0xA0000000, 0x00000000, ++ 0x03C, 0x0000022A, ++ 0x03C, 0x00000594, ++ 0xB0000000, 0x00000000, ++ 0x80000111, 0x00000000, 0x40000000, 0x00000000, ++ 0x03C, 0x00000800, ++ 0x90000110, 0x00000000, 0x40000000, 0x00000000, ++ 0x03C, 0x00000800, ++ 0x90000210, 0x00000000, 0x40000000, 0x00000000, ++ 0x03C, 0x00000800, ++ 0x9000020c, 0x00000000, 0x40000000, 0x00000000, ++ 0x03C, 0x00000820, ++ 0x9000040c, 0x00000000, 0x40000000, 0x00000000, ++ 0x03C, 0x00000820, ++ 0x90000200, 0x00000000, 0x40000000, 0x00000000, ++ 0x03C, 0x00000800, ++ 0x90000410, 0x00000000, 0x40000000, 0x00000000, ++ 0x03C, 0x00000800, ++ 0xA0000000, 0x00000000, ++ 0x03C, 0x00000900, ++ 0xB0000000, 0x00000000, ++ 0x0EF, 0x00000000, ++ 0x018, 0x0001712A, ++ 0x0EF, 0x00000002, ++ 0x80000111, 0x00000000, 0x40000000, 0x00000000, ++ 0x008, 0x0004E400, ++ 0x90000110, 0x00000000, 0x40000000, 0x00000000, ++ 0x008, 0x0004E400, ++ 0x90000210, 0x00000000, 0x40000000, 0x00000000, ++ 0x008, 0x00002000, ++ 0x9000020c, 0x00000000, 0x40000000, 0x00000000, ++ 0x008, 0x00002000, ++ 0x9000040c, 0x00000000, 0x40000000, 0x00000000, ++ 0x008, 0x00002000, ++ 0x90000200, 0x00000000, 0x40000000, 0x00000000, ++ 0x008, 0x00002000, ++ 0x90000410, 0x00000000, 0x40000000, 0x00000000, ++ 0x008, 0x0004E400, ++ 0xA0000000, 0x00000000, ++ 0x008, 0x00002000, ++ 0xB0000000, 0x00000000, ++ 0x0EF, 0x00000000, ++ 0x0DF, 0x000000C0, ++ 0x01F, 0x00000064, ++ 0x80000111, 0x00000000, 0x40000000, 0x00000000, ++ 0x058, 0x000A7284, ++ 0x059, 0x000600EC, ++ 0x90000110, 0x00000000, 0x40000000, 0x00000000, ++ 0x058, 0x000A7284, ++ 0x059, 0x000600EC, ++ 0x9000020c, 0x00000000, 0x40000000, 0x00000000, ++ 0x058, 0x00081184, ++ 0x059, 0x0006016C, ++ 0x9000040c, 0x00000000, 0x40000000, 0x00000000, ++ 0x058, 0x00081184, ++ 0x059, 0x0006016C, ++ 0x90000200, 0x00000000, 0x40000000, 0x00000000, ++ 0x058, 0x00081184, ++ 0x059, 0x0006016C, ++ 0x90000410, 0x00000000, 0x40000000, 0x00000000, ++ 0x058, 0x000A7284, ++ 0x059, 0x000600EC, ++ 0xA0000000, 0x00000000, ++ 0x058, 0x00081184, ++ 0x059, 0x0006016C, ++ 0xB0000000, 0x00000000, ++ 0x80000111, 0x00000000, 0x40000000, 0x00000000, ++ 0x061, 0x000E8D73, ++ 0x062, 0x00093FC5, ++ 0x90000110, 0x00000000, 0x40000000, 0x00000000, ++ 0x061, 0x000E8D73, ++ 0x062, 0x00093FC5, ++ 0x90000210, 0x00000000, 0x40000000, 0x00000000, ++ 0x061, 0x000EFD83, ++ 0x062, 0x00093FCC, ++ 0x9000040c, 0x00000000, 0x40000000, 0x00000000, ++ 0x061, 0x000EAD53, ++ 0x062, 0x00093BC4, ++ 0x90000200, 0x00000000, 0x40000000, 0x00000000, ++ 0x061, 0x000EFD83, ++ 0x062, 0x00093FCC, ++ 0x90000410, 0x00000000, 0x40000000, 0x00000000, ++ 0x061, 0x000E8D73, ++ 0x062, 0x00093FC5, ++ 0xA0000000, 0x00000000, ++ 0x061, 0x000EAD53, ++ 0x062, 0x00093BC4, ++ 0xB0000000, 0x00000000, ++ 0x80000111, 0x00000000, 0x40000000, 0x00000000, ++ 0x063, 0x000110E9, ++ 0x90000110, 0x00000000, 0x40000000, 0x00000000, ++ 0x063, 0x000110E9, ++ 0x90000210, 0x00000000, 0x40000000, 0x00000000, ++ 0x063, 0x000110EB, ++ 0x9000020c, 0x00000000, 0x40000000, 0x00000000, ++ 0x063, 0x000110E9, ++ 0x9000040c, 0x00000000, 0x40000000, 0x00000000, ++ 0x063, 0x000110E9, ++ 0x90000200, 0x00000000, 0x40000000, 0x00000000, ++ 0x063, 0x000110EB, ++ 0x90000410, 0x00000000, 0x40000000, 0x00000000, ++ 0x063, 0x000110E9, ++ 0xA0000000, 0x00000000, ++ 0x063, 0x000714E9, ++ 0xB0000000, 0x00000000, ++ 0x80000111, 0x00000000, 0x40000000, 0x00000000, ++ 0x064, 0x0001C27C, ++ 0x90000110, 0x00000000, 0x40000000, 0x00000000, ++ 0x064, 0x0001C27C, ++ 0x90000210, 0x00000000, 0x40000000, 0x00000000, ++ 0x064, 0x0001C27C, ++ 0x9000040c, 0x00000000, 0x40000000, 0x00000000, ++ 0x064, 0x0001C67C, ++ 0x90000200, 0x00000000, 0x40000000, 0x00000000, ++ 0x064, 0x0001C27C, ++ 0x90000410, 0x00000000, 0x40000000, 0x00000000, ++ 0x064, 0x0001C27C, ++ 0xA0000000, 0x00000000, ++ 0x064, 0x0001C67C, ++ 0xB0000000, 0x00000000, ++ 0x80000111, 0x00000000, 0x40000000, 0x00000000, ++ 0x065, 0x00091016, ++ 0x90000110, 0x00000000, 0x40000000, 0x00000000, ++ 0x065, 0x00091016, ++ 0x90000210, 0x00000000, 0x40000000, 0x00000000, ++ 0x065, 0x00093016, ++ 0x9000020c, 0x00000000, 0x40000000, 0x00000000, ++ 0x065, 0x00093015, ++ 0x9000040c, 0x00000000, 0x40000000, 0x00000000, ++ 0x065, 0x00093015, ++ 0x90000200, 0x00000000, 0x40000000, 0x00000000, ++ 0x065, 0x00093016, ++ 0xA0000000, 0x00000000, ++ 0x065, 0x00091016, ++ 0xB0000000, 0x00000000, ++ 0x018, 0x00000006, ++ 0x0EF, 0x00002000, ++ 0x03B, 0x0003824B, ++ 0x03B, 0x0003024B, ++ 0x03B, 0x0002844B, ++ 0x03B, 0x00020F4B, ++ 0x03B, 0x00018F4B, ++ 0x03B, 0x000104B2, ++ 0x03B, 0x00008049, ++ 0x03B, 0x00000148, ++ 0x03B, 0x0007824B, ++ 0x03B, 0x0007024B, ++ 0x03B, 0x0006824B, ++ 0x03B, 0x00060F4B, ++ 0x03B, 0x00058F4B, ++ 0x03B, 0x000504B2, ++ 0x03B, 0x00048049, ++ 0x03B, 0x00040148, ++ 0x0EF, 0x00000000, ++ 0x0EF, 0x00000100, ++ 0x034, 0x0000ADF3, ++ 0x034, 0x00009DF0, ++ 0x034, 0x00008D70, ++ 0x034, 0x00007D6D, ++ 0x034, 0x00006CEE, ++ 0x034, 0x00005CCC, ++ 0x034, 0x000044EC, ++ 0x034, 0x000034AC, ++ 0x034, 0x0000246D, ++ 0x034, 0x0000106F, ++ 0x034, 0x0000006C, ++ 0x0EF, 0x00000000, ++ 0x0ED, 0x00000010, ++ 0x044, 0x0000ADF2, ++ 0x044, 0x00009DEF, ++ 0x044, 0x00008DEC, ++ 0x044, 0x00007DE9, ++ 0x044, 0x00006CEC, ++ 0x044, 0x00005CE9, ++ 0x044, 0x000044EC, ++ 0x044, 0x000034E9, ++ 0x044, 0x0000246C, ++ 0x044, 0x00001469, ++ 0x044, 0x0000006C, ++ 0x0ED, 0x00000000, ++ 0x0ED, 0x00000001, ++ 0x040, 0x00038DA7, ++ 0x040, 0x000300C2, ++ 0x040, 0x000288E2, ++ 0x040, 0x000200B8, ++ 0x040, 0x000188A5, ++ 0x040, 0x00010FBC, ++ 0x040, 0x00008F71, ++ 0x040, 0x00000240, ++ 0x0ED, 0x00000000, ++ 0x0EF, 0x000020A2, ++ 0x0DF, 0x00000080, ++ 0x035, 0x00000120, ++ 0x035, 0x00008120, ++ 0x035, 0x00010120, ++ 0x036, 0x00000085, ++ 0x036, 0x00008085, ++ 0x036, 0x00010085, ++ 0x036, 0x00018085, ++ 0x0EF, 0x00000000, ++ 0x051, 0x00000C31, ++ 0x052, 0x00000622, ++ 0x053, 0x000FC70B, ++ 0x054, 0x0000017E, ++ 0x056, 0x00051DF3, ++ 0x051, 0x00000C01, ++ 0x052, 0x000006D6, ++ 0x053, 0x000FC649, ++ 0x070, 0x00049661, ++ 0x071, 0x0007843E, ++ 0x072, 0x00000382, ++ 0x074, 0x00051400, ++ 0x035, 0x00000160, ++ 0x035, 0x00008160, ++ 0x035, 0x00010160, ++ 0x036, 0x00000124, ++ 0x036, 0x00008124, ++ 0x036, 0x00010124, ++ 0x036, 0x00018124, ++ 0x0ED, 0x0000000C, ++ 0x045, 0x00000140, ++ 0x045, 0x00008140, ++ 0x045, 0x00010140, ++ 0x046, 0x00000124, ++ 0x046, 0x00008124, ++ 0x046, 0x00010124, ++ 0x046, 0x00018124, ++ 0x0DF, 0x00000088, ++ 0x0B3, 0x000F0E18, ++ 0x0B4, 0x0001214C, ++ 0x0B7, 0x0003000C, ++ 0x01C, 0x000539D2, ++ 0x0C4, 0x000AFE00, ++ 0x018, 0x0001F12A, ++ 0xFFE, 0x00000000, ++ 0xFFE, 0x00000000, ++ 0x018, 0x0001712A, ++}; ++ ++RTW_DECL_TABLE_RF_RADIO(rtw8821a_rf_a, A); ++ ++static const struct rtw_txpwr_lmt_cfg_pair rtw8821a_txpwr_lmt[] = { ++ { 0, 0, 0, 0, 1, 32, }, ++ { 2, 0, 0, 0, 1, 28, }, ++ { 1, 0, 0, 0, 1, 32, }, ++ { 0, 0, 0, 0, 2, 32, }, ++ { 2, 0, 0, 0, 2, 28, }, ++ { 1, 0, 0, 0, 2, 32, }, ++ { 0, 0, 0, 0, 3, 36, }, ++ { 2, 0, 0, 0, 3, 28, }, ++ { 1, 0, 0, 0, 3, 32, }, ++ { 0, 0, 0, 0, 4, 36, }, ++ { 2, 0, 0, 0, 4, 28, }, ++ { 1, 0, 0, 0, 4, 32, }, ++ { 0, 0, 0, 0, 5, 36, }, ++ { 2, 0, 0, 0, 5, 28, }, ++ { 1, 0, 0, 0, 5, 32, }, ++ { 0, 0, 0, 0, 6, 36, }, ++ { 2, 0, 0, 0, 6, 28, }, ++ { 1, 0, 0, 0, 6, 32, }, ++ { 0, 0, 0, 0, 7, 36, }, ++ { 2, 0, 0, 0, 7, 28, }, ++ { 1, 0, 0, 0, 7, 32, }, ++ { 0, 0, 0, 0, 8, 36, }, ++ { 2, 0, 0, 0, 8, 28, }, ++ { 1, 0, 0, 0, 8, 32, }, ++ { 0, 0, 0, 0, 9, 32, }, ++ { 2, 0, 0, 0, 9, 28, }, ++ { 1, 0, 0, 0, 9, 32, }, ++ { 0, 0, 0, 0, 10, 32, }, ++ { 2, 0, 0, 0, 10, 28, }, ++ { 1, 0, 0, 0, 10, 32, }, ++ { 0, 0, 0, 0, 11, 32, }, ++ { 2, 0, 0, 0, 11, 28, }, ++ { 1, 0, 0, 0, 11, 32, }, ++ { 0, 0, 0, 0, 12, 28, }, ++ { 2, 0, 0, 0, 12, 28, }, ++ { 1, 0, 0, 0, 12, 32, }, ++ { 0, 0, 0, 0, 13, 26, }, ++ { 2, 0, 0, 0, 13, 28, }, ++ { 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, 30, }, ++ { 1, 0, 0, 1, 1, 32, }, ++ { 0, 0, 0, 1, 2, 30, }, ++ { 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, 30, }, ++ { 2, 0, 0, 1, 9, 32, }, ++ { 1, 0, 0, 1, 9, 32, }, ++ { 0, 0, 0, 1, 10, 30, }, ++ { 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, 26, }, ++ { 2, 0, 0, 1, 12, 32, }, ++ { 1, 0, 0, 1, 12, 32, }, ++ { 0, 0, 0, 1, 13, 24, }, ++ { 2, 0, 0, 1, 13, 30, }, ++ { 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, 26, }, ++ { 1, 0, 0, 2, 1, 32, }, ++ { 0, 0, 0, 2, 2, 26, }, ++ { 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, 26, }, ++ { 2, 0, 0, 2, 9, 32, }, ++ { 1, 0, 0, 2, 9, 32, }, ++ { 0, 0, 0, 2, 10, 26, }, ++ { 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, 26, }, ++ { 2, 0, 0, 2, 12, 32, }, ++ { 1, 0, 0, 2, 12, 32, }, ++ { 0, 0, 0, 2, 13, 24, }, ++ { 2, 0, 0, 2, 13, 26, }, ++ { 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, 30, }, ++ { 2, 0, 0, 3, 1, 32, }, ++ { 1, 0, 0, 3, 1, 32, }, ++ { 0, 0, 0, 3, 2, 32, }, ++ { 2, 0, 0, 3, 2, 32, }, ++ { 1, 0, 0, 3, 2, 32, }, ++ { 0, 0, 0, 3, 3, 32, }, ++ { 2, 0, 0, 3, 3, 32, }, ++ { 1, 0, 0, 3, 3, 32, }, ++ { 0, 0, 0, 3, 4, 32, }, ++ { 2, 0, 0, 3, 4, 32, }, ++ { 1, 0, 0, 3, 4, 32, }, ++ { 0, 0, 0, 3, 5, 32, }, ++ { 2, 0, 0, 3, 5, 32, }, ++ { 1, 0, 0, 3, 5, 32, }, ++ { 0, 0, 0, 3, 6, 32, }, ++ { 2, 0, 0, 3, 6, 32, }, ++ { 1, 0, 0, 3, 6, 32, }, ++ { 0, 0, 0, 3, 7, 32, }, ++ { 2, 0, 0, 3, 7, 32, }, ++ { 1, 0, 0, 3, 7, 32, }, ++ { 0, 0, 0, 3, 8, 32, }, ++ { 2, 0, 0, 3, 8, 32, }, ++ { 1, 0, 0, 3, 8, 32, }, ++ { 0, 0, 0, 3, 9, 32, }, ++ { 2, 0, 0, 3, 9, 32, }, ++ { 1, 0, 0, 3, 9, 32, }, ++ { 0, 0, 0, 3, 10, 32, }, ++ { 2, 0, 0, 3, 10, 32, }, ++ { 1, 0, 0, 3, 10, 32, }, ++ { 0, 0, 0, 3, 11, 30, }, ++ { 2, 0, 0, 3, 11, 32, }, ++ { 1, 0, 0, 3, 11, 32, }, ++ { 0, 0, 0, 3, 12, 63, }, ++ { 2, 0, 0, 3, 12, 32, }, ++ { 1, 0, 0, 3, 12, 32, }, ++ { 0, 0, 0, 3, 13, 63, }, ++ { 2, 0, 0, 3, 13, 32, }, ++ { 1, 0, 0, 3, 13, 32, }, ++ { 0, 0, 0, 3, 14, 63, }, ++ { 2, 0, 0, 3, 14, 63, }, ++ { 1, 0, 0, 3, 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, 26, }, ++ { 1, 0, 1, 2, 3, 32, }, ++ { 0, 0, 1, 2, 4, 26, }, ++ { 2, 0, 1, 2, 4, 32, }, ++ { 1, 0, 1, 2, 4, 32, }, ++ { 0, 0, 1, 2, 5, 26, }, ++ { 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, 26, }, ++ { 2, 0, 1, 2, 9, 32, }, ++ { 1, 0, 1, 2, 9, 32, }, ++ { 0, 0, 1, 2, 10, 24, }, ++ { 2, 0, 1, 2, 10, 32, }, ++ { 1, 0, 1, 2, 10, 32, }, ++ { 0, 0, 1, 2, 11, 22, }, ++ { 2, 0, 1, 2, 11, 26, }, ++ { 1, 0, 1, 2, 11, 32, }, ++ { 0, 0, 1, 2, 12, 63, }, ++ { 2, 0, 1, 2, 12, 63, }, ++ { 1, 0, 1, 2, 12, 63, }, ++ { 0, 0, 1, 2, 13, 63, }, ++ { 2, 0, 1, 2, 13, 63, }, ++ { 1, 0, 1, 2, 13, 63, }, ++ { 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, 32, }, ++ { 2, 0, 1, 3, 4, 30, }, ++ { 1, 0, 1, 3, 4, 30, }, ++ { 0, 0, 1, 3, 5, 32, }, ++ { 2, 0, 1, 3, 5, 30, }, ++ { 1, 0, 1, 3, 5, 30, }, ++ { 0, 0, 1, 3, 6, 32, }, ++ { 2, 0, 1, 3, 6, 30, }, ++ { 1, 0, 1, 3, 6, 30, }, ++ { 0, 0, 1, 3, 7, 32, }, ++ { 2, 0, 1, 3, 7, 30, }, ++ { 1, 0, 1, 3, 7, 30, }, ++ { 0, 0, 1, 3, 8, 32, }, ++ { 2, 0, 1, 3, 8, 30, }, ++ { 1, 0, 1, 3, 8, 30, }, ++ { 0, 0, 1, 3, 9, 32, }, ++ { 2, 0, 1, 3, 9, 30, }, ++ { 1, 0, 1, 3, 9, 30, }, ++ { 0, 0, 1, 3, 10, 32, }, ++ { 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, 32, }, ++ { 1, 0, 1, 3, 12, 32, }, ++ { 0, 0, 1, 3, 13, 63, }, ++ { 2, 0, 1, 3, 13, 32, }, ++ { 1, 0, 1, 3, 13, 32, }, ++ { 0, 0, 1, 3, 14, 63, }, ++ { 2, 0, 1, 3, 14, 63, }, ++ { 1, 0, 1, 3, 14, 63, }, ++ { 0, 1, 0, 1, 36, 32, }, ++ { 2, 1, 0, 1, 36, 30, }, ++ { 1, 1, 0, 1, 36, 30, }, ++ { 0, 1, 0, 1, 40, 32, }, ++ { 2, 1, 0, 1, 40, 30, }, ++ { 1, 1, 0, 1, 40, 30, }, ++ { 0, 1, 0, 1, 44, 32, }, ++ { 2, 1, 0, 1, 44, 30, }, ++ { 1, 1, 0, 1, 44, 30, }, ++ { 0, 1, 0, 1, 48, 32, }, ++ { 2, 1, 0, 1, 48, 30, }, ++ { 1, 1, 0, 1, 48, 30, }, ++ { 0, 1, 0, 1, 52, 32, }, ++ { 2, 1, 0, 1, 52, 30, }, ++ { 1, 1, 0, 1, 52, 30, }, ++ { 0, 1, 0, 1, 56, 32, }, ++ { 2, 1, 0, 1, 56, 30, }, ++ { 1, 1, 0, 1, 56, 30, }, ++ { 0, 1, 0, 1, 60, 32, }, ++ { 2, 1, 0, 1, 60, 30, }, ++ { 1, 1, 0, 1, 60, 30, }, ++ { 0, 1, 0, 1, 64, 32, }, ++ { 2, 1, 0, 1, 64, 30, }, ++ { 1, 1, 0, 1, 64, 30, }, ++ { 0, 1, 0, 1, 100, 32, }, ++ { 2, 1, 0, 1, 100, 30, }, ++ { 1, 1, 0, 1, 100, 30, }, ++ { 0, 1, 0, 1, 104, 32, }, ++ { 2, 1, 0, 1, 104, 30, }, ++ { 1, 1, 0, 1, 104, 30, }, ++ { 0, 1, 0, 1, 108, 32, }, ++ { 2, 1, 0, 1, 108, 30, }, ++ { 1, 1, 0, 1, 108, 30, }, ++ { 0, 1, 0, 1, 112, 32, }, ++ { 2, 1, 0, 1, 112, 30, }, ++ { 1, 1, 0, 1, 112, 30, }, ++ { 0, 1, 0, 1, 116, 32, }, ++ { 2, 1, 0, 1, 116, 30, }, ++ { 1, 1, 0, 1, 116, 30, }, ++ { 0, 1, 0, 1, 120, 32, }, ++ { 2, 1, 0, 1, 120, 30, }, ++ { 1, 1, 0, 1, 120, 30, }, ++ { 0, 1, 0, 1, 124, 32, }, ++ { 2, 1, 0, 1, 124, 30, }, ++ { 1, 1, 0, 1, 124, 30, }, ++ { 0, 1, 0, 1, 128, 32, }, ++ { 2, 1, 0, 1, 128, 30, }, ++ { 1, 1, 0, 1, 128, 30, }, ++ { 0, 1, 0, 1, 132, 32, }, ++ { 2, 1, 0, 1, 132, 30, }, ++ { 1, 1, 0, 1, 132, 30, }, ++ { 0, 1, 0, 1, 136, 32, }, ++ { 2, 1, 0, 1, 136, 30, }, ++ { 1, 1, 0, 1, 136, 30, }, ++ { 0, 1, 0, 1, 140, 32, }, ++ { 2, 1, 0, 1, 140, 30, }, ++ { 1, 1, 0, 1, 140, 30, }, ++ { 0, 1, 0, 1, 149, 32, }, ++ { 2, 1, 0, 1, 149, 30, }, ++ { 1, 1, 0, 1, 149, 63, }, ++ { 0, 1, 0, 1, 153, 32, }, ++ { 2, 1, 0, 1, 153, 30, }, ++ { 1, 1, 0, 1, 153, 63, }, ++ { 0, 1, 0, 1, 157, 32, }, ++ { 2, 1, 0, 1, 157, 30, }, ++ { 1, 1, 0, 1, 157, 63, }, ++ { 0, 1, 0, 1, 161, 32, }, ++ { 2, 1, 0, 1, 161, 30, }, ++ { 1, 1, 0, 1, 161, 63, }, ++ { 0, 1, 0, 1, 165, 32, }, ++ { 2, 1, 0, 1, 165, 30, }, ++ { 1, 1, 0, 1, 165, 63, }, ++ { 0, 1, 0, 2, 36, 32, }, ++ { 2, 1, 0, 2, 36, 30, }, ++ { 1, 1, 0, 2, 36, 30, }, ++ { 0, 1, 0, 2, 40, 32, }, ++ { 2, 1, 0, 2, 40, 30, }, ++ { 1, 1, 0, 2, 40, 30, }, ++ { 0, 1, 0, 2, 44, 32, }, ++ { 2, 1, 0, 2, 44, 30, }, ++ { 1, 1, 0, 2, 44, 30, }, ++ { 0, 1, 0, 2, 48, 32, }, ++ { 2, 1, 0, 2, 48, 30, }, ++ { 1, 1, 0, 2, 48, 30, }, ++ { 0, 1, 0, 2, 52, 32, }, ++ { 2, 1, 0, 2, 52, 30, }, ++ { 1, 1, 0, 2, 52, 30, }, ++ { 0, 1, 0, 2, 56, 32, }, ++ { 2, 1, 0, 2, 56, 30, }, ++ { 1, 1, 0, 2, 56, 30, }, ++ { 0, 1, 0, 2, 60, 32, }, ++ { 2, 1, 0, 2, 60, 30, }, ++ { 1, 1, 0, 2, 60, 30, }, ++ { 0, 1, 0, 2, 64, 32, }, ++ { 2, 1, 0, 2, 64, 30, }, ++ { 1, 1, 0, 2, 64, 30, }, ++ { 0, 1, 0, 2, 100, 32, }, ++ { 2, 1, 0, 2, 100, 30, }, ++ { 1, 1, 0, 2, 100, 30, }, ++ { 0, 1, 0, 2, 104, 32, }, ++ { 2, 1, 0, 2, 104, 30, }, ++ { 1, 1, 0, 2, 104, 30, }, ++ { 0, 1, 0, 2, 108, 32, }, ++ { 2, 1, 0, 2, 108, 30, }, ++ { 1, 1, 0, 2, 108, 30, }, ++ { 0, 1, 0, 2, 112, 32, }, ++ { 2, 1, 0, 2, 112, 30, }, ++ { 1, 1, 0, 2, 112, 30, }, ++ { 0, 1, 0, 2, 116, 32, }, ++ { 2, 1, 0, 2, 116, 30, }, ++ { 1, 1, 0, 2, 116, 30, }, ++ { 0, 1, 0, 2, 120, 32, }, ++ { 2, 1, 0, 2, 120, 30, }, ++ { 1, 1, 0, 2, 120, 30, }, ++ { 0, 1, 0, 2, 124, 32, }, ++ { 2, 1, 0, 2, 124, 30, }, ++ { 1, 1, 0, 2, 124, 30, }, ++ { 0, 1, 0, 2, 128, 32, }, ++ { 2, 1, 0, 2, 128, 30, }, ++ { 1, 1, 0, 2, 128, 30, }, ++ { 0, 1, 0, 2, 132, 32, }, ++ { 2, 1, 0, 2, 132, 30, }, ++ { 1, 1, 0, 2, 132, 30, }, ++ { 0, 1, 0, 2, 136, 32, }, ++ { 2, 1, 0, 2, 136, 30, }, ++ { 1, 1, 0, 2, 136, 30, }, ++ { 0, 1, 0, 2, 140, 32, }, ++ { 2, 1, 0, 2, 140, 30, }, ++ { 1, 1, 0, 2, 140, 30, }, ++ { 0, 1, 0, 2, 149, 32, }, ++ { 2, 1, 0, 2, 149, 30, }, ++ { 1, 1, 0, 2, 149, 63, }, ++ { 0, 1, 0, 2, 153, 32, }, ++ { 2, 1, 0, 2, 153, 30, }, ++ { 1, 1, 0, 2, 153, 63, }, ++ { 0, 1, 0, 2, 157, 32, }, ++ { 2, 1, 0, 2, 157, 30, }, ++ { 1, 1, 0, 2, 157, 63, }, ++ { 0, 1, 0, 2, 161, 32, }, ++ { 2, 1, 0, 2, 161, 30, }, ++ { 1, 1, 0, 2, 161, 63, }, ++ { 0, 1, 0, 2, 165, 32, }, ++ { 2, 1, 0, 2, 165, 30, }, ++ { 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, 1, 2, 38, 26, }, ++ { 2, 1, 1, 2, 38, 30, }, ++ { 1, 1, 1, 2, 38, 30, }, ++ { 0, 1, 1, 2, 46, 32, }, ++ { 2, 1, 1, 2, 46, 30, }, ++ { 1, 1, 1, 2, 46, 30, }, ++ { 0, 1, 1, 2, 54, 32, }, ++ { 2, 1, 1, 2, 54, 30, }, ++ { 1, 1, 1, 2, 54, 30, }, ++ { 0, 1, 1, 2, 62, 24, }, ++ { 2, 1, 1, 2, 62, 30, }, ++ { 1, 1, 1, 2, 62, 30, }, ++ { 0, 1, 1, 2, 102, 24, }, ++ { 2, 1, 1, 2, 102, 30, }, ++ { 1, 1, 1, 2, 102, 30, }, ++ { 0, 1, 1, 2, 110, 32, }, ++ { 2, 1, 1, 2, 110, 30, }, ++ { 1, 1, 1, 2, 110, 30, }, ++ { 0, 1, 1, 2, 118, 32, }, ++ { 2, 1, 1, 2, 118, 30, }, ++ { 1, 1, 1, 2, 118, 30, }, ++ { 0, 1, 1, 2, 126, 32, }, ++ { 2, 1, 1, 2, 126, 30, }, ++ { 1, 1, 1, 2, 126, 30, }, ++ { 0, 1, 1, 2, 134, 32, }, ++ { 2, 1, 1, 2, 134, 30, }, ++ { 1, 1, 1, 2, 134, 30, }, ++ { 0, 1, 1, 2, 151, 30, }, ++ { 2, 1, 1, 2, 151, 30, }, ++ { 1, 1, 1, 2, 151, 63, }, ++ { 0, 1, 1, 2, 159, 32, }, ++ { 2, 1, 1, 2, 159, 30, }, ++ { 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, 2, 4, 42, 22, }, ++ { 2, 1, 2, 4, 42, 30, }, ++ { 1, 1, 2, 4, 42, 30, }, ++ { 0, 1, 2, 4, 58, 20, }, ++ { 2, 1, 2, 4, 58, 30, }, ++ { 1, 1, 2, 4, 58, 30, }, ++ { 0, 1, 2, 4, 106, 20, }, ++ { 2, 1, 2, 4, 106, 30, }, ++ { 1, 1, 2, 4, 106, 30, }, ++ { 0, 1, 2, 4, 122, 20, }, ++ { 2, 1, 2, 4, 122, 30, }, ++ { 1, 1, 2, 4, 122, 30, }, ++ { 0, 1, 2, 4, 155, 28, }, ++ { 2, 1, 2, 4, 155, 30, }, ++ { 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, }, ++}; ++ ++RTW_DECL_TABLE_TXPWR_LMT(rtw8821a_txpwr_lmt); ++ ++static const struct rtw_pwr_seq_cmd trans_carddis_to_cardemu_8821a[] = { ++ {0x0005, ++ RTW_PWR_CUT_ALL_MSK, ++ RTW_PWR_INTF_ALL_MSK, ++ RTW_PWR_ADDR_MAC, ++ RTW_PWR_CMD_WRITE, BIT(3) | BIT(7), 0}, ++ {0x0086, ++ RTW_PWR_CUT_ALL_MSK, ++ RTW_PWR_INTF_SDIO_MSK, ++ RTW_PWR_ADDR_SDIO, ++ RTW_PWR_CMD_WRITE, BIT(0), 0}, ++ {0x0086, ++ RTW_PWR_CUT_ALL_MSK, ++ RTW_PWR_INTF_SDIO_MSK, ++ RTW_PWR_ADDR_SDIO, ++ RTW_PWR_CMD_POLLING, BIT(1), BIT(1)}, ++ {0x004A, ++ 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(3) | BIT(4), 0}, ++ {0x0023, ++ RTW_PWR_CUT_ALL_MSK, ++ RTW_PWR_INTF_SDIO_MSK, ++ RTW_PWR_ADDR_MAC, ++ RTW_PWR_CMD_WRITE, BIT(4), 0}, ++ {0x0301, ++ RTW_PWR_CUT_ALL_MSK, ++ RTW_PWR_INTF_PCI_MSK, ++ RTW_PWR_ADDR_MAC, ++ RTW_PWR_CMD_WRITE, 0xFF, 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_8821a[] = { ++ {0x0020, ++ RTW_PWR_CUT_ALL_MSK, ++ RTW_PWR_INTF_USB_MSK | RTW_PWR_INTF_SDIO_MSK, ++ RTW_PWR_ADDR_MAC, ++ RTW_PWR_CMD_WRITE, BIT(0), BIT(0)}, ++ {0x0067, ++ RTW_PWR_CUT_ALL_MSK, ++ RTW_PWR_INTF_USB_MSK | RTW_PWR_INTF_SDIO_MSK, ++ RTW_PWR_ADDR_MAC, ++ RTW_PWR_CMD_WRITE, BIT(4), 0}, ++ {0x0001, ++ RTW_PWR_CUT_ALL_MSK, ++ RTW_PWR_INTF_USB_MSK | RTW_PWR_INTF_SDIO_MSK, ++ RTW_PWR_ADDR_MAC, ++ RTW_PWR_CMD_DELAY, 1, RTW_PWR_DELAY_MS}, ++ {0x0000, ++ RTW_PWR_CUT_ALL_MSK, ++ RTW_PWR_INTF_USB_MSK | RTW_PWR_INTF_SDIO_MSK, ++ RTW_PWR_ADDR_MAC, ++ RTW_PWR_CMD_WRITE, BIT(5), 0}, ++ {0x0005, ++ RTW_PWR_CUT_ALL_MSK, ++ RTW_PWR_INTF_ALL_MSK, ++ RTW_PWR_ADDR_MAC, ++ RTW_PWR_CMD_WRITE, BIT(4) | BIT(3) | BIT(2), 0}, ++ {0x0075, ++ RTW_PWR_CUT_ALL_MSK, ++ RTW_PWR_INTF_PCI_MSK, ++ RTW_PWR_ADDR_MAC, ++ RTW_PWR_CMD_WRITE, BIT(0), BIT(0)}, ++ {0x0006, ++ RTW_PWR_CUT_ALL_MSK, ++ RTW_PWR_INTF_ALL_MSK, ++ RTW_PWR_ADDR_MAC, ++ RTW_PWR_CMD_POLLING, BIT(1), BIT(1)}, ++ {0x0075, ++ RTW_PWR_CUT_ALL_MSK, ++ RTW_PWR_INTF_PCI_MSK, ++ RTW_PWR_ADDR_MAC, ++ RTW_PWR_CMD_WRITE, BIT(0), 0}, ++ {0x0006, ++ 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_WRITE, BIT(7), 0}, ++ {0x0005, ++ RTW_PWR_CUT_ALL_MSK, ++ RTW_PWR_INTF_ALL_MSK, ++ RTW_PWR_ADDR_MAC, ++ RTW_PWR_CMD_WRITE, BIT(4) | BIT(3), 0}, ++ {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}, ++ {0x004F, ++ RTW_PWR_CUT_ALL_MSK, ++ RTW_PWR_INTF_ALL_MSK, ++ RTW_PWR_ADDR_MAC, ++ RTW_PWR_CMD_WRITE, BIT(0), BIT(0)}, ++ {0x0067, ++ RTW_PWR_CUT_ALL_MSK, ++ RTW_PWR_INTF_ALL_MSK, ++ RTW_PWR_ADDR_MAC, ++ RTW_PWR_CMD_WRITE, BIT(5) | BIT(4), BIT(5) | BIT(4)}, ++ {0x0025, ++ RTW_PWR_CUT_ALL_MSK, ++ RTW_PWR_INTF_ALL_MSK, ++ RTW_PWR_ADDR_MAC, ++ RTW_PWR_CMD_WRITE, BIT(6), 0}, ++ {0x0049, ++ RTW_PWR_CUT_ALL_MSK, ++ RTW_PWR_INTF_ALL_MSK, ++ RTW_PWR_ADDR_MAC, ++ RTW_PWR_CMD_WRITE, BIT(1), BIT(1)}, ++ {0x0063, ++ RTW_PWR_CUT_ALL_MSK, ++ RTW_PWR_INTF_ALL_MSK, ++ RTW_PWR_ADDR_MAC, ++ RTW_PWR_CMD_WRITE, BIT(1), BIT(1)}, ++ {0x0062, ++ RTW_PWR_CUT_ALL_MSK, ++ RTW_PWR_INTF_ALL_MSK, ++ RTW_PWR_ADDR_MAC, ++ RTW_PWR_CMD_WRITE, BIT(1), 0}, ++ {0x0058, ++ RTW_PWR_CUT_ALL_MSK, ++ RTW_PWR_INTF_ALL_MSK, ++ RTW_PWR_ADDR_MAC, ++ RTW_PWR_CMD_WRITE, BIT(0), BIT(0)}, ++ {0x005A, ++ RTW_PWR_CUT_ALL_MSK, ++ RTW_PWR_INTF_ALL_MSK, ++ RTW_PWR_ADDR_MAC, ++ RTW_PWR_CMD_WRITE, BIT(1), BIT(1)}, ++ {0x002E, ++ RTW_PWR_CUT_ALL_MSK, ++ RTW_PWR_INTF_ALL_MSK, ++ RTW_PWR_ADDR_MAC, ++ RTW_PWR_CMD_WRITE, 0xFF, 0x82}, ++ {0x0010, ++ RTW_PWR_CUT_ALL_MSK, ++ RTW_PWR_INTF_ALL_MSK, ++ RTW_PWR_ADDR_MAC, ++ RTW_PWR_CMD_WRITE, BIT(6), BIT(6)}, ++ {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_lps_8821a[] = { ++ {0x0301, ++ RTW_PWR_CUT_ALL_MSK, ++ RTW_PWR_INTF_PCI_MSK, ++ RTW_PWR_ADDR_MAC, ++ RTW_PWR_CMD_WRITE, 0xFF, 0xFF}, ++ {0x0522, ++ RTW_PWR_CUT_ALL_MSK, ++ RTW_PWR_INTF_ALL_MSK, ++ RTW_PWR_ADDR_MAC, ++ RTW_PWR_CMD_WRITE, 0xFF, 0xFF}, ++ {0x05F8, ++ RTW_PWR_CUT_ALL_MSK, ++ RTW_PWR_INTF_ALL_MSK, ++ RTW_PWR_ADDR_MAC, ++ RTW_PWR_CMD_POLLING, 0xFF, 0}, ++ {0x05F9, ++ RTW_PWR_CUT_ALL_MSK, ++ RTW_PWR_INTF_ALL_MSK, ++ RTW_PWR_ADDR_MAC, ++ RTW_PWR_CMD_POLLING, 0xFF, 0}, ++ {0x05FA, ++ RTW_PWR_CUT_ALL_MSK, ++ RTW_PWR_INTF_ALL_MSK, ++ RTW_PWR_ADDR_MAC, ++ RTW_PWR_CMD_POLLING, 0xFF, 0}, ++ {0x05FB, ++ RTW_PWR_CUT_ALL_MSK, ++ RTW_PWR_INTF_ALL_MSK, ++ RTW_PWR_ADDR_MAC, ++ RTW_PWR_CMD_POLLING, 0xFF, 0}, ++ {0x0002, ++ 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, 0, RTW_PWR_DELAY_US}, ++ {0x0002, ++ RTW_PWR_CUT_ALL_MSK, ++ RTW_PWR_INTF_ALL_MSK, ++ RTW_PWR_ADDR_MAC, ++ RTW_PWR_CMD_WRITE, BIT(1), 0}, ++ {0x0100, ++ RTW_PWR_CUT_ALL_MSK, ++ RTW_PWR_INTF_ALL_MSK, ++ RTW_PWR_ADDR_MAC, ++ RTW_PWR_CMD_WRITE, 0xFF, 0x03}, ++ {0x0101, ++ RTW_PWR_CUT_ALL_MSK, ++ RTW_PWR_INTF_ALL_MSK, ++ RTW_PWR_ADDR_MAC, ++ RTW_PWR_CMD_WRITE, BIT(1), 0}, ++ {0x0093, ++ RTW_PWR_CUT_ALL_MSK, ++ RTW_PWR_INTF_SDIO_MSK, ++ RTW_PWR_ADDR_MAC, ++ RTW_PWR_CMD_WRITE, 0xFF, 0x00}, ++ {0x0553, ++ RTW_PWR_CUT_ALL_MSK, ++ RTW_PWR_INTF_ALL_MSK, ++ RTW_PWR_ADDR_MAC, ++ RTW_PWR_CMD_WRITE, BIT(5), BIT(5)}, ++ {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_8821a[] = { ++ {0x001F, ++ RTW_PWR_CUT_ALL_MSK, ++ RTW_PWR_INTF_ALL_MSK, ++ RTW_PWR_ADDR_MAC, ++ RTW_PWR_CMD_WRITE, 0xFF, 0}, ++ {0x004F, ++ RTW_PWR_CUT_ALL_MSK, ++ RTW_PWR_INTF_ALL_MSK, ++ RTW_PWR_ADDR_MAC, ++ RTW_PWR_CMD_WRITE, BIT(0), 0}, ++ {0x0049, ++ RTW_PWR_CUT_ALL_MSK, ++ RTW_PWR_INTF_ALL_MSK, ++ RTW_PWR_ADDR_MAC, ++ RTW_PWR_CMD_WRITE, BIT(1), 0}, ++ {0x0006, ++ RTW_PWR_CUT_ALL_MSK, ++ RTW_PWR_INTF_USB_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_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}, ++ {0x0000, ++ RTW_PWR_CUT_ALL_MSK, ++ RTW_PWR_INTF_USB_MSK | RTW_PWR_INTF_SDIO_MSK, ++ RTW_PWR_ADDR_MAC, ++ RTW_PWR_CMD_WRITE, BIT(5), BIT(5)}, ++ {0x0020, ++ RTW_PWR_CUT_ALL_MSK, ++ RTW_PWR_INTF_USB_MSK | RTW_PWR_INTF_SDIO_MSK, ++ RTW_PWR_ADDR_MAC, ++ RTW_PWR_CMD_WRITE, 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_cardemu_to_carddis_8821a[] = { ++ {0x0007, ++ RTW_PWR_CUT_ALL_MSK, ++ RTW_PWR_INTF_SDIO_MSK, ++ RTW_PWR_ADDR_MAC, ++ RTW_PWR_CMD_WRITE, 0xFF, 0x20}, ++ {0x0005, ++ RTW_PWR_CUT_ALL_MSK, ++ RTW_PWR_INTF_USB_MSK | RTW_PWR_INTF_SDIO_MSK, ++ RTW_PWR_ADDR_MAC, ++ RTW_PWR_CMD_WRITE, BIT(3) | BIT(4), BIT(3)}, ++ {0x0005, ++ RTW_PWR_CUT_ALL_MSK, ++ RTW_PWR_INTF_PCI_MSK, ++ RTW_PWR_ADDR_MAC, ++ RTW_PWR_CMD_WRITE, BIT(2), BIT(2)}, ++ {0x004A, ++ RTW_PWR_CUT_ALL_MSK, ++ RTW_PWR_INTF_USB_MSK, ++ RTW_PWR_ADDR_MAC, ++ RTW_PWR_CMD_WRITE, BIT(0), 1}, ++ {0x0023, ++ RTW_PWR_CUT_ALL_MSK, ++ RTW_PWR_INTF_SDIO_MSK, ++ RTW_PWR_ADDR_MAC, ++ RTW_PWR_CMD_WRITE, BIT(4), BIT(4)}, ++ {0x0086, ++ RTW_PWR_CUT_ALL_MSK, ++ RTW_PWR_INTF_SDIO_MSK, ++ RTW_PWR_ADDR_SDIO, ++ RTW_PWR_CMD_WRITE, BIT(0), BIT(0)}, ++ {0x0086, ++ RTW_PWR_CUT_ALL_MSK, ++ RTW_PWR_INTF_SDIO_MSK, ++ RTW_PWR_ADDR_SDIO, ++ 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}, ++}; ++ ++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 * const enter_lps_flow_8821a[] = { ++ trans_act_to_lps_8821a, ++ NULL ++}; ++ ++const struct rtw_pwr_seq_cmd * const card_disable_flow_8821a[] = { ++ trans_act_to_cardemu_8821a, ++ trans_cardemu_to_carddis_8821a, ++ NULL ++}; ++ ++static const u8 rtw8821a_pwrtrk_5gb_n[][RTW_PWR_TRK_TBL_SZ] = { ++ {0, 0, 1, 2, 3, 3, 4, 5, 6, 6, 7, 8, 9, 9, 10, 11, 12, 12, 13, 14, 15, ++ 15, 16, 16, 16, 16, 16, 16, 16, 16}, ++ {0, 0, 1, 2, 3, 3, 4, 5, 6, 6, 7, 8, 9, 9, 10, 11, 12, 12, 13, 14, 15, ++ 15, 16, 16, 16, 16, 16, 16, 16, 16}, ++ {0, 0, 1, 2, 3, 3, 4, 5, 6, 6, 7, 8, 9, 9, 10, 11, 12, 12, 13, 14, 15, ++ 15, 16, 16, 16, 16, 16, 16, 16, 16}, ++}; ++ ++static const u8 rtw8821a_pwrtrk_5gb_p[][RTW_PWR_TRK_TBL_SZ] = { ++ {0, 0, 1, 2, 3, 3, 4, 5, 6, 6, 7, 8, 9, 9, 10, 11, 12, 12, 13, 14, 15, ++ 15, 16, 16, 16, 16, 16, 16, 16, 16}, ++ {0, 0, 1, 2, 3, 3, 4, 5, 6, 6, 7, 8, 9, 9, 10, 11, 12, 12, 13, 14, 15, ++ 15, 16, 16, 16, 16, 16, 16, 16, 16}, ++ {0, 0, 1, 2, 3, 3, 4, 5, 6, 6, 7, 8, 9, 9, 10, 11, 12, 12, 13, 14, 15, ++ 15, 16, 16, 16, 16, 16, 16, 16, 16}, ++}; ++ ++static const u8 rtw8821a_pwrtrk_5ga_n[][RTW_PWR_TRK_TBL_SZ] = { ++ {0, 0, 1, 2, 3, 3, 4, 5, 6, 6, 7, 8, 9, 9, 10, 11, 12, 12, 13, 14, 15, ++ 15, 16, 16, 16, 16, 16, 16, 16, 16}, ++ {0, 0, 1, 2, 3, 3, 4, 5, 6, 6, 7, 8, 9, 9, 10, 11, 12, 12, 13, 14, 15, ++ 15, 16, 16, 16, 16, 16, 16, 16, 16}, ++ {0, 0, 1, 2, 3, 3, 4, 5, 6, 6, 7, 8, 9, 9, 10, 11, 12, 12, 13, 14, 15, ++ 15, 16, 16, 16, 16, 16, 16, 16, 16}, ++}; ++ ++static const u8 rtw8821a_pwrtrk_5ga_p[][RTW_PWR_TRK_TBL_SZ] = { ++ {0, 0, 1, 2, 3, 3, 4, 5, 6, 6, 7, 8, 9, 9, 10, 11, 12, 12, 13, 14, 15, ++ 15, 16, 16, 16, 16, 16, 16, 16, 16}, ++ {0, 0, 1, 2, 3, 3, 4, 5, 6, 6, 7, 8, 9, 9, 10, 11, 12, 12, 13, 14, 15, ++ 15, 16, 16, 16, 16, 16, 16, 16, 16}, ++ {0, 0, 1, 2, 3, 3, 4, 5, 6, 6, 7, 8, 9, 9, 10, 11, 12, 12, 13, 14, 15, ++ 15, 16, 16, 16, 16, 16, 16, 16, 16}, ++}; ++ ++static const u8 rtw8821a_pwrtrk_2gb_n[] = { ++ 0, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 4, 5, 5, 5, 6, ++ 6, 6, 7, 7, 7, 8, 8, 8, 9, 9, 9, 10, 10, 10 ++}; ++ ++static const u8 rtw8821a_pwrtrk_2gb_p[] = { ++ 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, 12, 12, 12, 12 ++}; ++ ++static const u8 rtw8821a_pwrtrk_2ga_n[] = { ++ 0, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 4, 5, 5, 5, 6, ++ 6, 6, 7, 7, 7, 8, 8, 8, 9, 9, 9, 10, 10, 10 ++}; ++ ++static const u8 rtw8821a_pwrtrk_2ga_p[] = { ++ 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, 12, 12, 12, 12 ++}; ++ ++static const u8 rtw8821a_pwrtrk_2g_cck_b_n[] = { ++ 0, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 4, 5, 5, 5, 6, ++ 6, 6, 7, 7, 7, 8, 8, 8, 9, 9, 9, 10, 10, 10 ++}; ++ ++static const u8 rtw8821a_pwrtrk_2g_cck_b_p[] = { ++ 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, 12, 12, 12, 12 ++}; ++ ++static const u8 rtw8821a_pwrtrk_2g_cck_a_n[] = { ++ 0, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 4, 5, 5, 5, 6, ++ 6, 6, 7, 7, 7, 8, 8, 8, 9, 9, 9, 10, 10, 10 ++}; ++ ++static const u8 rtw8821a_pwrtrk_2g_cck_a_p[] = { ++ 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, 12, 12, 12, 12 ++}; ++ ++const struct rtw_pwr_track_tbl rtw8821a_rtw_pwr_track_tbl = { ++ .pwrtrk_5gb_n[0] = rtw8821a_pwrtrk_5gb_n[0], ++ .pwrtrk_5gb_n[1] = rtw8821a_pwrtrk_5gb_n[1], ++ .pwrtrk_5gb_n[2] = rtw8821a_pwrtrk_5gb_n[2], ++ .pwrtrk_5gb_p[0] = rtw8821a_pwrtrk_5gb_p[0], ++ .pwrtrk_5gb_p[1] = rtw8821a_pwrtrk_5gb_p[1], ++ .pwrtrk_5gb_p[2] = rtw8821a_pwrtrk_5gb_p[2], ++ .pwrtrk_5ga_n[0] = rtw8821a_pwrtrk_5ga_n[0], ++ .pwrtrk_5ga_n[1] = rtw8821a_pwrtrk_5ga_n[1], ++ .pwrtrk_5ga_n[2] = rtw8821a_pwrtrk_5ga_n[2], ++ .pwrtrk_5ga_p[0] = rtw8821a_pwrtrk_5ga_p[0], ++ .pwrtrk_5ga_p[1] = rtw8821a_pwrtrk_5ga_p[1], ++ .pwrtrk_5ga_p[2] = rtw8821a_pwrtrk_5ga_p[2], ++ .pwrtrk_2gb_n = rtw8821a_pwrtrk_2gb_n, ++ .pwrtrk_2gb_p = rtw8821a_pwrtrk_2gb_p, ++ .pwrtrk_2ga_n = rtw8821a_pwrtrk_2ga_n, ++ .pwrtrk_2ga_p = rtw8821a_pwrtrk_2ga_p, ++ .pwrtrk_2g_cckb_n = rtw8821a_pwrtrk_2g_cck_b_n, ++ .pwrtrk_2g_cckb_p = rtw8821a_pwrtrk_2g_cck_b_p, ++ .pwrtrk_2g_ccka_n = rtw8821a_pwrtrk_2g_cck_a_n, ++ .pwrtrk_2g_ccka_p = rtw8821a_pwrtrk_2g_cck_a_p, ++}; +diff --git a/drivers/net/wireless/realtek/rtw88/rtw8821a_table.h b/drivers/net/wireless/realtek/rtw88/rtw8821a_table.h +new file mode 100644 +index 000000000000..90379ac7a817 +--- /dev/null ++++ b/drivers/net/wireless/realtek/rtw88/rtw8821a_table.h +@@ -0,0 +1,21 @@ ++/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */ ++/* Copyright(c) 2024 Realtek Corporation ++ */ ++ ++#ifndef __RTW8821A_TABLE_H__ ++#define __RTW8821A_TABLE_H__ ++ ++extern const struct rtw_table rtw8821a_mac_tbl; ++extern const struct rtw_table rtw8821a_agc_tbl; ++extern const struct rtw_table rtw8821a_bb_tbl; ++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 * 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; ++ ++#endif +-- +2.46.0 + + +From mboxrd@z Thu Jan 1 00:00:00 1970 +Received: from mail-ed1-f54.google.com (mail-ed1-f54.google.com [209.85.208.54]) + (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) + (No client certificate requested) + by smtp.subspace.kernel.org (Postfix) with ESMTPS id 9E0CB1D14EE + for ; Fri, 11 Oct 2024 20:56:08 +0000 (UTC) +Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.208.54 +ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; + t=1728680172; cv=none; b=EfzdlJVCcLySyMj4UEes7tctgiLBxiTTsv/5NpOUAw7GfzoDWUNXEghmJFGpqgMU8MOZYftGyGY7m48icRgrLOfZwkt7IMoAvJufuC9UTv1kW0VtsTK8Tr11JElbLak8y243GoPaN2E9eXfNkdBpci06ZhYNxEFuSpvTiQv94+E= +ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; + s=arc-20240116; t=1728680172; c=relaxed/simple; + bh=M4p0H/zx32zsDG4df6zQQgs3ytz2LULfcht9EF6ss10=; + h=Message-ID:Date:MIME-Version:Subject:From:To:Cc:References: + In-Reply-To:Content-Type; b=RL8z2JIyo9sz8vg4bQkx/qCBU0SVLLeenhT3oji7tG3PK3ZfMFDJf1hCE7qg7uBvOMnVDuf7CtJsawhhPstc20M3W5YSPFA+51juo0G661cbzPYao6fL9g4Fmx1fkpSTSstbBJC6xOvoNnBCag9e8Ofk3iINP0ntdKafGBbAlHY= +ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=H7Fx01N5; arc=none smtp.client-ip=209.85.208.54 +Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com +Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com +Authentication-Results: smtp.subspace.kernel.org; + dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="H7Fx01N5" +Received: by mail-ed1-f54.google.com with SMTP id 4fb4d7f45d1cf-5c94dd7e1c0so1253719a12.0 + for ; Fri, 11 Oct 2024 13:56:08 -0700 (PDT) +DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; + d=gmail.com; s=20230601; t=1728680167; x=1729284967; darn=vger.kernel.org; + h=content-transfer-encoding:in-reply-to:content-language:references + :cc:to:from:subject:user-agent:mime-version:date:message-id:from:to + :cc:subject:date:message-id:reply-to; + bh=tLgaqCLvVhpCQV2fobwfYQnvSK9xJpUsliN5Xab6SAs=; + b=H7Fx01N54GwaVIPe5v+odmKKlwl9Cta+J6zvNqwrDFr6o0CpQKnVQs/LcbG4rVnhOW + 6Mh3+3uSVIm2wMrWs2CRgS0oLH2HSTlfgPhu9k5Skr9OqPimaMgMIdTdQTsXgKOeNbtv + 7Jbr8znwF8ktew51x3zw+NVP0NwvXOCExFRolG5fNkQAjSvTjPc9SNm7+Ty2DQ7x2cRH + jXIylks1Ccya7v+BQ727FXFWef9DQizPwm3v7MVn8VqlY/Fv35gm/0JH8js00QAtGV8p + EWxSKMyJIFl7N+7oiftp9ifIJDGJBA9DO29BBJuc3QEM0p7nPyui5t1EpNFsNzE1N9f6 + +siQ== +X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; + d=1e100.net; s=20230601; t=1728680167; x=1729284967; + h=content-transfer-encoding:in-reply-to:content-language:references + :cc:to:from:subject:user-agent:mime-version:date:message-id + :x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; + bh=tLgaqCLvVhpCQV2fobwfYQnvSK9xJpUsliN5Xab6SAs=; + b=aekN0VjF4eWH+5TsQAyWO6vJvHDucPyZVYFJYhtiQcd7k8bq+TrpLRgxUWZubrHRBy + 5mrSaD4RmuaRfGORujPtIn3CfWXwAxC53GBKV1zvkDqEbxt7u7wByDnNDwGGC3QWZYXh + Xoracmu+dsSQll4BPGtlS50jVt/8aoqSbw1zOYpDWu38ZH3LBMZaqFJseQ1QE4BqfYRw + GP5XoSwVdg3iPUZAmMbd+V/3XCbNeW1sS4nblV/PZkV7j3W5qhvbi5q7+rRobBeYX6dZ + LedST5ckkXRDwsKfwoda+5WNc5rGnqEsjKHJMUZrrpbDM3YFSGawDSqeYexhIsfzFTG6 + qozA== +X-Gm-Message-State: AOJu0YwfP5R6humBFU2rNBeJ5PVLXMlqO/NcV6FbRWwIuK6PEAGeONri + 3dWUogWInx15Jhb/FVFZYO73lICOe8y0c9X473rW83zL7cc95MrY6t+B/w== +X-Google-Smtp-Source: AGHT+IHpOCjYOWW8IvJ7AKodz6NkKV9dH97KzINFVgC7cqwvOX4vqzVGpLOKnky9B3lwVvT4HzeWvg== +X-Received: by 2002:a05:6402:42c7:b0:5c9:346c:6055 with SMTP id 4fb4d7f45d1cf-5c95ac09923mr506309a12.2.1728680166116; + Fri, 11 Oct 2024 13:56:06 -0700 (PDT) +Received: from [192.168.0.50] ([79.113.150.231]) + by smtp.gmail.com with ESMTPSA id 4fb4d7f45d1cf-5c93711ba52sm2241309a12.26.2024.10.11.13.56.04 + (version=TLS1_3 cipher=TLS_AES_128_GCM_SHA256 bits=128/128); + Fri, 11 Oct 2024 13:56:05 -0700 (PDT) +Message-ID: +Date: Fri, 11 Oct 2024 23:56:04 +0300 +Precedence: bulk +X-Mailing-List: linux-wireless@vger.kernel.org +List-Id: +List-Subscribe: +List-Unsubscribe: +MIME-Version: 1.0 +User-Agent: Mozilla Thunderbird +Subject: [PATCH v2 18/22] wifi: rtw88: Add rtw88xxa.{c,h} +From: Bitterblue Smith +To: "linux-wireless@vger.kernel.org" +Cc: Ping-Ke Shih +References: +Content-Language: en-US +In-Reply-To: +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 7bit + +These contain code shared by both RTL8821AU and RTL8812AU chips. + +Signed-off-by: Bitterblue Smith +--- +v2: + - Rename rtw8821a.{c,h} to rtw88xxa.{c,h}. + - Rename functions to use the "rtw88xxa" prefix. + - Rename struct rtw8821a_efuse to rtw88xxa_efuse. + - Keep only the common code in this patch. The rest is in the next + two patches now. + - Fix copyright year. + - Print hw_cap in rtw88xxa_read_usb_type. + - Use pointer to rtwdev->efuse in rtw88xxa_get_bb_swing instead of + making a copy of the struct. + - Make rtw88xxa_get_swing_index return 24 instead of 0 by default. + - Use new register definitions. + - Delete rtw8821a_query_rx_desc. Use the new rtw_rx_query_rx_desc + function instead. + - Use u32_get_bits instead of FIELD_GET in + rtw88xxa_false_alarm_statistics. + - Use existing bit definitions for REG_CR bits instead of creating new + ones. + - Use existing name of REG_CCK0_FAREPORT instead of adding a new name. + - Delete unnecessary braces and semicolons in switch statements. + - Initialise arrays with {} instead of {0}. + - Empty functions should have the braces on separate lines. + - Include reg.h in rtw88xxa.h. + - Make struct rtw8821au_efuse and rtw8812au_efuse __packed. + - Delete most macros from rtw88xxa.h. Some were moved to reg.h, some + were unused (inherited from rtw8821c.h). + - Fix some indentation. + - Use the correct IQK function for 8812au in the tx power tracking. + v1 was accidentally using the IQK function meant for 8821au. + - Rename struct rtw8821a_phy_status_rpt to rtw_jaguar_phy_status_rpt. + It's shared by RTL8821AU and RTL8812AU, and maybe RTL8814AU in the + future. These are all "Jaguar" chips. + - Make struct rtw_jaguar_phy_status_rpt __packed. + - Access struct rtw_jaguar_phy_status_rpt with le32_get_bits instead + of bit fields. + +8821au, 8812au: Make the LED blink - temporary, just for me +--- + drivers/net/wireless/realtek/rtw88/rtw88xxa.c | 1989 +++++++++++++++++ + drivers/net/wireless/realtek/rtw88/rtw88xxa.h | 175 ++ + 2 files changed, 2164 insertions(+) + create mode 100644 drivers/net/wireless/realtek/rtw88/rtw88xxa.c + create mode 100644 drivers/net/wireless/realtek/rtw88/rtw88xxa.h + +diff --git a/drivers/net/wireless/realtek/rtw88/rtw88xxa.c b/drivers/net/wireless/realtek/rtw88/rtw88xxa.c +new file mode 100644 +index 000000000000..71e61b9c0bec +--- /dev/null ++++ b/drivers/net/wireless/realtek/rtw88/rtw88xxa.c +@@ -0,0 +1,1989 @@ ++// 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); ++ ++ 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/drivers/net/wireless/realtek/rtw88/rtw88xxa.h b/drivers/net/wireless/realtek/rtw88/rtw88xxa.h +new file mode 100644 +index 000000000000..09a45c1a4129 +--- /dev/null ++++ b/drivers/net/wireless/realtek/rtw88/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 +-- +2.46.0 + + +From mboxrd@z Thu Jan 1 00:00:00 1970 +Received: from mail-ej1-f52.google.com (mail-ej1-f52.google.com [209.85.218.52]) + (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) + (No client certificate requested) + by smtp.subspace.kernel.org (Postfix) with ESMTPS id A8799199231 + for ; Fri, 11 Oct 2024 20:56:49 +0000 (UTC) +Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.218.52 +ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; + t=1728680212; cv=none; b=PJ3agr1ZIndTg/jmlwetCM7kDzPD99S2LonukzYzEWNoma1Zu7B3ctW4H2fJJyIWMz76A79yKqoQ7MFN1Z57HKLMy/NBa4FUshSYis+6h58bhn7XyH6nAS28s2yHB+rx3d/oBrIcl++UT45/ADAXhv6v9nBknQwlwv+3EEH9Ml0= +ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; + s=arc-20240116; t=1728680212; c=relaxed/simple; + bh=8fuL+DUO2GlNeLu3qHCpDIG6oNAZaU7yqp87OYKmCnE=; + h=Message-ID:Date:MIME-Version:Subject:From:To:Cc:References: + In-Reply-To:Content-Type; b=SyTaqZuIno4UpfZmnVjLRBKd/EWeVSeNpVagwIntCaoqElC60wA4kXYnou6xmgMpFYhlvFfP2TtUpSMaWyJeeRcF5Cc5ClpxghORnuJFzjDvClIsZtLs+1WKl8iEU1e8HZ33s9736+KNUnWzc1J6NhgbDE0Xz0xTk5CDbBdRCHM= +ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=UxIAOTjA; arc=none smtp.client-ip=209.85.218.52 +Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com +Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com +Authentication-Results: smtp.subspace.kernel.org; + dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="UxIAOTjA" +Received: by mail-ej1-f52.google.com with SMTP id a640c23a62f3a-a9951fba3b4so383269966b.1 + for ; Fri, 11 Oct 2024 13:56:49 -0700 (PDT) +DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; + d=gmail.com; s=20230601; t=1728680208; x=1729285008; darn=vger.kernel.org; + h=content-transfer-encoding:in-reply-to:content-language:references + :cc:to:from:subject:user-agent:mime-version:date:message-id:from:to + :cc:subject:date:message-id:reply-to; + bh=+S55F+rXFrB9Ji6LBhnP0L04yKbgk3kWNwqnE+811pI=; + b=UxIAOTjAQg/dEsjRuy3s1hYpeHOl6acj72ZlO4nZmHW/77LEoanQJcUds78GQx9W1/ + UtYkoUuuuNNZdjKbqgJlTSTKqGpPUrtQTHUzfbLsEIgTdj2DFj2/L0HR/er9ywcYpYll + TfmE5dOgB7llgh3PD1Sfm5g2NvKMJ37rFk3HlzEsgudjQcGi9FLrM5rmqegEdZigF2ig + BnLW8zOp8Uib5bN8reglWNB6VoB0A/FJbSQbmfi1+7AJt6FPmcehf5GxSwabLClefyi+ + SemMjVWmR0qL7v5RqAOl2lSB6vnPvB3269R4IsyKyToCxLlrhO/FTlaLADqounPv3dKc + bgqA== +X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; + d=1e100.net; s=20230601; t=1728680208; x=1729285008; + h=content-transfer-encoding:in-reply-to:content-language:references + :cc:to:from:subject:user-agent:mime-version:date:message-id + :x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; + bh=+S55F+rXFrB9Ji6LBhnP0L04yKbgk3kWNwqnE+811pI=; + b=YF5eNPuZ2k/ReGexuGjq4IotS9SkH2J1FzDt7cIvxQ4JfibK2x8GDq9m0EM8QXI2jg + h9qkbHYUVKun6TK/KTziMAzHWNcZYJFb7g844oyrg4XfDe6luXw4fhZEu75v0zfSHKlF + VbFaJE8boyV2aQIIOm9PyOY3xHLaN4YTvnnQAxZmhchPEqkjhti4xClGysUJUFCRxwE1 + K9aPKEZPGXRoEaVQL7EYHb8FvYn5kaRADjtD/Svb2DT6MzJpYBbSDtoyr3DLB/BkefNJ + gTUdUZR5pMREuSh6auZAxPGZS4mTZRKgRHcjV6VXrvwKBPs9TyzI3xzN1kPelVH17xBi + YfCQ== +X-Gm-Message-State: AOJu0YwaOK+/jup4wZqkEmPvJt2lM0WKF+yXsAj9dGInFqFjCrIwoKjl + U0LIKsfhLebKkK7ujSl1S3XE7NsKAKekJRRWLFNtHFxsZAxkOjmMQyP+9g== +X-Google-Smtp-Source: AGHT+IE314ZBVfD6QBHTyesnV3xilfJNoIwiXtsBnkI9E51WkfIMZoBZ3HpK4t6Z6r2lzAujaX5Kvg== +X-Received: by 2002:a17:907:6eac:b0:a99:529d:8199 with SMTP id a640c23a62f3a-a99b9754a81mr274667666b.62.1728680207674; + Fri, 11 Oct 2024 13:56:47 -0700 (PDT) +Received: from [192.168.0.50] ([79.113.150.231]) + by smtp.gmail.com with ESMTPSA id a640c23a62f3a-a99a7f5b09fsm251487266b.91.2024.10.11.13.56.46 + (version=TLS1_3 cipher=TLS_AES_128_GCM_SHA256 bits=128/128); + Fri, 11 Oct 2024 13:56:47 -0700 (PDT) +Message-ID: <352e980c-96fe-43ba-8a4a-0c546d1dfd47@gmail.com> +Date: Fri, 11 Oct 2024 23:56:46 +0300 +Precedence: bulk +X-Mailing-List: linux-wireless@vger.kernel.org +List-Id: +List-Subscribe: +List-Unsubscribe: +MIME-Version: 1.0 +User-Agent: Mozilla Thunderbird +Subject: [PATCH v2 19/22] wifi: rtw88: Add rtw8821a.{c,h} +From: Bitterblue Smith +To: "linux-wireless@vger.kernel.org" +Cc: Ping-Ke Shih +References: +Content-Language: en-US +In-Reply-To: +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 7bit + +These contain code specific to RTL8821AU. + +Signed-off-by: Bitterblue Smith +--- +v2: + - Patch is new in v2. + - All of this used to be in patch 18/20 in v1. + - Use "k < 3" instead of "k <= 2" in the IQK code. + - Replace some while loops with for loops in the IQK code. + - Use rtw_write8 instead of rtw_write8_mask in + rtw8821a_coex_cfg_ant_switch. The mask was 0xff. + - Constify structs/arrays. +--- + drivers/net/wireless/realtek/rtw88/rtw8821a.c | 1197 +++++++++++++++++ + drivers/net/wireless/realtek/rtw88/rtw8821a.h | 10 + + 2 files changed, 1207 insertions(+) + create mode 100644 drivers/net/wireless/realtek/rtw88/rtw8821a.c + create mode 100644 drivers/net/wireless/realtek/rtw88/rtw8821a.h + +diff --git a/drivers/net/wireless/realtek/rtw88/rtw8821a.c b/drivers/net/wireless/realtek/rtw88/rtw8821a.c +new file mode 100644 +index 000000000000..d1c2394c1391 +--- /dev/null ++++ b/drivers/net/wireless/realtek/rtw88/rtw8821a.c +@@ -0,0 +1,1197 @@ ++// 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 "rtw8821a.h" ++#include "rtw8821a_table.h" ++#include "tx.h" ++ ++static void rtw8821a_power_off(struct rtw_dev *rtwdev) ++{ ++ rtw88xxa_power_off(rtwdev, enter_lps_flow_8821a); ++} ++ ++static s8 rtw8821a_cck_rx_pwr(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 void rtw8821a_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, ++ rtw8821a_cck_rx_pwr); ++} ++ ++static void rtw8821a_cfg_ldo25(struct rtw_dev *rtwdev, bool enable) ++{ ++} ++ ++#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_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, 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_iqk_rx_fill(struct rtw_dev *rtwdev, ++ unsigned int rx_x, unsigned int rx_y) ++{ ++ /* [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, ++ unsigned int tx_x, unsigned int tx_y) ++{ ++ /* [31] = 1 --> Page C1 */ ++ rtw_write32_mask(rtwdev, REG_CCASEL, BIT(31), 0x1); ++ ++ 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); ++} ++ ++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]) ++{ ++ u32 cal_retry, delay_count, iqk_ready, tx_fail; ++ int tx_dt[3], vdf_y[3], vdf_x[3]; ++ int k; ++ ++ 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); ++ ++ 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; ++ } ++ ++ rtw_write32(rtwdev, REG_RFECTL_A, 0x00100000); ++ ++ 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); ++ ++ mdelay(10); ++ ++ rtw_write32(rtwdev, REG_RFECTL_A, 0x00000000); ++ ++ for (delay_count = 0; delay_count < 20; delay_count++) { ++ iqk_ready = rtw_read32_mask(rtwdev, ++ REG_IQKA_END, ++ 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) ++ break; ++ ++ mdelay(1); ++ } ++ ++ 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_write32_mask(rtwdev, REG_IQC_Y, ++ 0x000007ff, 0x0); ++ rtw_write32_mask(rtwdev, REG_IQC_X, ++ 0x000007ff, 0x200); ++ } ++ ++ *tx0iqkok = false; ++ } ++ } ++ ++ if (k == 3) { ++ tx_x0[cal] = vdf_x[k - 1]; ++ tx_y0[cal] = vdf_y[k - 1]; ++ } ++} ++ ++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 cal_retry, delay_count, iqk_ready, tx_fail; ++ ++ /* 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); ++ ++ 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); ++ ++ mdelay(10); ++ rtw_write32(rtwdev, REG_RFECTL_A, 0x00000000); ++ ++ for (delay_count = 0; delay_count < 20; delay_count++) { ++ iqk_ready = rtw_read32_mask(rtwdev, REG_IQKA_END, 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) ++ break; ++ ++ mdelay(1); ++ } ++ ++ 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); ++ tx_x0[cal] = rtw_read32_mask(rtwdev, REG_IQKA_END, ++ 0x07ff0000); ++ tx_x0[cal] <<= 21; ++ ++ rtw_write32(rtwdev, REG_RFECTL_A, 0x04000000); ++ tx_y0[cal] = rtw_read32_mask(rtwdev, REG_IQKA_END, ++ 0x07ff0000); ++ tx_y0[cal] <<= 21; ++ ++ *tx0iqkok = true; ++ break; ++ } ++ ++ rtw_write32_mask(rtwdev, REG_IQC_Y, 0x000007ff, 0x0); ++ rtw_write32_mask(rtwdev, REG_IQC_X, 0x000007ff, 0x200); ++ } ++ ++ *tx0iqkok = false; ++ } ++} ++ ++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]) ++{ ++ u32 cal_retry, delay_count, iqk_ready, rx_fail; ++ ++ rtw_write32(rtwdev, REG_RFECTL_A, 0x00100000); ++ ++ 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); ++ ++ mdelay(10); ++ ++ rtw_write32(rtwdev, REG_RFECTL_A, 0x00000000); ++ ++ for (delay_count = 0; delay_count < 20; delay_count++) { ++ iqk_ready = rtw_read32_mask(rtwdev, REG_IQKA_END, 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) ++ break; ++ ++ mdelay(1); ++ } ++ ++ 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; ++ ++ rtw_write32(rtwdev, REG_RFECTL_A, 0x08000000); ++ rx_y0[cal] = rtw_read32_mask(rtwdev, REG_IQKA_END, ++ 0x07ff0000); ++ rx_y0[cal] <<= 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; ++ } ++} ++ ++static void rtw8821a_iqk(struct rtw_dev *rtwdev) ++{ ++ 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_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; ++ ++ for (cal = 0; cal < CAL_NUM_8821A; cal++) { ++ /* 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, REG_3WIRE_SWA, 0xf, 0x4); ++ ++ /* LOK setting */ ++ ++ /* 1. DAC/ADC sampling rate (160 MHz) */ ++ rtw_write32_mask(rtwdev, REG_CK_MONHA, GENMASK(26, 24), 0x7); ++ ++ /* 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); ++ ++ /* [31] = 1 --> Page C1 */ ++ rtw_write32_mask(rtwdev, REG_CCASEL, BIT(31), 0x1); ++ ++ 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); ++ ++ 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); ++ ++ /* 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); ++ ++ mdelay(10); ++ rtw_write32(rtwdev, REG_RFECTL_A, 0x00000000); ++ ++ /* [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)); ++ ++ 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); ++ ++ /* [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, 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); ++ ++ /* [31] = 1 --> Page C1 */ ++ rtw_write32_mask(rtwdev, REG_CCASEL, BIT(31), 0x1); ++ ++ 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 (hal->current_band_type == RTW_BAND_5G) ++ rtw_write32(rtwdev, REG_TSSI_TRK_SW, 0x40163e96); ++ else ++ rtw_write32(rtwdev, REG_TSSI_TRK_SW, 0x00163e96); ++ ++ 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); ++ ++ if (!tx0iqkok) ++ 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, 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, ++ 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); ++ ++ 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); ++ ++ /* [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, 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, 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 && i == 0) ++ rtw_write32(rtwdev, REG_TSSI_TRK_SW, 0x28161100); /* Good */ ++ else ++ rtw_write32(rtwdev, REG_TSSI_TRK_SW, 0x28160d00); ++ ++ rtw8821a_iqk_rx(rtwdev, cal, &rx0iqkok, ++ rx_x0[i], rx_y0[i]); ++ } ++ ++ if (tx0iqkok) ++ tx_average++; ++ if (rx0iqkok) ++ rx_average++; ++ } ++ ++ /* 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); ++ ++ 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); ++ ++ 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); ++ } ++ ++ rx_finish1 = rtw88xxa_iqk_finish(rx_average, 4, rx_x0[0], rx_y0[0], ++ &rx_x_temp, &rx_y_temp, true, true); ++ ++ if (rx_finish1) { ++ rx_x = rx_x_temp; ++ rx_y = rx_y_temp; ++ } ++ ++ 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 (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, rx_x, rx_y); ++ else ++ rtw8821a_iqk_rx_fill(rtwdev, 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]; ++ ++ 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); ++ ++ rtw88xxa_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); ++ rtw88xxa_iqk_restore_mac_bb(rtwdev, macbb_backup, ++ backup_macbb_reg, MACBB_REG_NUM_8821A); ++} ++ ++static void rtw8821a_phy_calibration(struct rtw_dev *rtwdev) ++{ ++ 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; ++ } ++ ++ rtw88xxa_phy_pwrtrack(rtwdev, NULL, rtw8821a_do_iqk); ++ dm_info->pwr_trk_triggered = false; ++} ++ ++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) ++{ ++ u8 val8; ++ ++ /* BT report packet sample rate */ ++ rtw_write8_mask(rtwdev, REG_BT_TDMA_TIME, BIT_MASK_SAMPLE_RATE, 0x5); ++ ++ val8 = BIT_STATIS_BT_EN; ++ if (rtwdev->efuse.share_ant) ++ val8 |= BIT_R_GRANTALL_WLMASK; ++ rtw_write8(rtwdev, REG_BT_COEX_ENH_INTR_CTRL, val8); ++ ++ /* enable BT counter statistics */ ++ rtw_write8(rtwdev, REG_BT_STAT_CTRL, 0x3); ++ ++ /* enable PTA */ ++ rtw_write32_set(rtwdev, REG_GPIO_MUXCFG, BIT_BT_PTA_EN); ++} ++ ++static void rtw8821a_coex_cfg_ant_switch(struct rtw_dev *rtwdev, u8 ctrl_type, ++ u8 pos_type) ++{ ++ bool share_ant = rtwdev->efuse.share_ant; ++ struct rtw_coex *coex = &rtwdev->coex; ++ struct rtw_coex_dm *coex_dm = &coex->dm; ++ u32 phase = coex_dm->cur_ant_pos_type; ++ ++ if (!rtwdev->efuse.btcoex) ++ return; ++ ++ switch (phase) { ++ case COEX_SET_ANT_POWERON: ++ 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, REG_GNT_BT, BIT_PTA_SW_CTL); ++ ++ 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, REG_GNT_BT, BIT_PTA_SW_CTL); ++ ++ 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, REG_GNT_BT, BIT_PTA_SW_CTL); ++ ++ 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, REG_GNT_BT, BIT_PTA_SW_CTL); ++ ++ 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, REG_GNT_BT, BIT_PTA_SW_CTL); ++ ++ rtw_write8(rtwdev, REG_RFE_CTRL8, DPDT_CTRL_PIN); ++ rtw_write32_mask(rtwdev, REG_RFE_CTRL8, 0x30000000, ++ share_ant ? 0x2 : 0x1); ++ break; ++ default: ++ rtw_warn(rtwdev, "%s: not handling phase %d\n", ++ __func__, phase); ++ break; ++ } ++} ++ ++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) ++{ ++ struct rtw_coex *coex = &rtwdev->coex; ++ struct rtw_coex_rfe *coex_rfe = &coex->rfe; ++ ++ coex_rfe->ant_switch_exist = true; ++} ++ ++static void rtw8821a_coex_cfg_wl_tx_power(struct rtw_dev *rtwdev, u8 wl_pwr) ++{ ++ struct rtw_coex *coex = &rtwdev->coex; ++ struct rtw_coex_dm *coex_dm = &coex->dm; ++ struct rtw_efuse *efuse = &rtwdev->efuse; ++ bool share_ant = efuse->share_ant; ++ ++ if (share_ant) ++ return; ++ ++ if (wl_pwr == coex_dm->cur_wl_pwr_lvl) ++ return; ++ ++ coex_dm->cur_wl_pwr_lvl = wl_pwr; ++} ++ ++static void rtw8821a_coex_cfg_wl_rx_gain(struct rtw_dev *rtwdev, bool low_gain) ++{ ++} ++ ++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 const struct rtw_page_table page_table_8821a[] = { ++ /* hq_num, nq_num, lq_num, exq_num, gapq_num */ ++ {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 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}, ++ ++ {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_8821a = { ++ .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 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 */ ++/* 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}; ++ ++/* table_sant_8821a, table_nsant_8821a, tdma_sant_8821a, and tdma_nsant_8821a ++ * are copied from rtw8821c.c because the 8821au driver's tables are not ++ * compatible with the coex code in rtw88. ++ * ++ * tdma case 112 (A2DP) byte 0 had to be modified from 0x61 to 0x51, ++ * otherwise the firmware gets confused after pausing the music: ++ * rtw_8821au 1-2:1.2: [BTCoex], Bt_info[1], len=7, data=[81 00 0a 01 00 00] ++ * - 81 means PAN (personal area network) when it should be 4x (A2DP) ++ * The music is not smooth with the PAN algorithm. ++ */ ++ ++/* Shared-Antenna Coex Table */ ++static const struct coex_table_para table_sant_8821a[] = { ++ {0x55555555, 0x55555555}, /* case-0 */ ++ {0x55555555, 0x55555555}, ++ {0x66555555, 0x66555555}, ++ {0xaaaaaaaa, 0xaaaaaaaa}, ++ {0x5a5a5a5a, 0x5a5a5a5a}, ++ {0xfafafafa, 0xfafafafa}, /* case-5 */ ++ {0x6a5a5555, 0xaaaaaaaa}, ++ {0x6a5a56aa, 0x6a5a56aa}, ++ {0x6a5a5a5a, 0x6a5a5a5a}, ++ {0x66555555, 0x5a5a5a5a}, ++ {0x66555555, 0x6a5a5a5a}, /* case-10 */ ++ {0x66555555, 0xaaaaaaaa}, ++ {0x66555555, 0x6a5a5aaa}, ++ {0x66555555, 0x6aaa6aaa}, ++ {0x66555555, 0x6a5a5aaa}, ++ {0x66555555, 0xaaaaaaaa}, /* case-15 */ ++ {0xffff55ff, 0xfafafafa}, ++ {0xffff55ff, 0x6afa5afa}, ++ {0xaaffffaa, 0xfafafafa}, ++ {0xaa5555aa, 0x5a5a5a5a}, ++ {0xaa5555aa, 0x6a5a5a5a}, /* case-20 */ ++ {0xaa5555aa, 0xaaaaaaaa}, ++ {0xffffffff, 0x55555555}, ++ {0xffffffff, 0x5a5a5a5a}, ++ {0xffffffff, 0x5a5a5a5a}, ++ {0xffffffff, 0x5a5a5aaa}, /* case-25 */ ++ {0x55555555, 0x5a5a5a5a}, ++ {0x55555555, 0xaaaaaaaa}, ++ {0x66555555, 0x6a5a6a5a}, ++ {0x66556655, 0x66556655}, ++ {0x66556aaa, 0x6a5a6aaa}, /* case-30 */ ++ {0xffffffff, 0x5aaa5aaa}, ++ {0x56555555, 0x5a5a5aaa} ++}; ++ ++/* Non-Shared-Antenna Coex Table */ ++static const struct coex_table_para table_nsant_8821a[] = { ++ {0xffffffff, 0xffffffff}, /* case-100 */ ++ {0xffff55ff, 0xfafafafa}, ++ {0x66555555, 0x66555555}, ++ {0xaaaaaaaa, 0xaaaaaaaa}, ++ {0x5a5a5a5a, 0x5a5a5a5a}, ++ {0xffffffff, 0xffffffff}, /* case-105 */ ++ {0x5afa5afa, 0x5afa5afa}, ++ {0x55555555, 0xfafafafa}, ++ {0x66555555, 0xfafafafa}, ++ {0x66555555, 0x5a5a5a5a}, ++ {0x66555555, 0x6a5a5a5a}, /* case-110 */ ++ {0x66555555, 0xaaaaaaaa}, ++ {0xffff55ff, 0xfafafafa}, ++ {0xffff55ff, 0x5afa5afa}, ++ {0xffff55ff, 0xaaaaaaaa}, ++ {0xffff55ff, 0xffff55ff}, /* case-115 */ ++ {0xaaffffaa, 0x5afa5afa}, ++ {0xaaffffaa, 0xaaaaaaaa}, ++ {0xffffffff, 0xfafafafa}, ++ {0xffff55ff, 0xfafafafa}, ++ {0xffffffff, 0xaaaaaaaa}, /* case-120 */ ++ {0xffff55ff, 0x5afa5afa}, ++ {0xffff55ff, 0x5afa5afa}, ++ {0x55ff55ff, 0x55ff55ff} ++}; ++ ++/* Shared-Antenna TDMA */ ++static const struct coex_tdma_para tdma_sant_8821a[] = { ++ { {0x00, 0x00, 0x00, 0x00, 0x00} }, /* case-0 */ ++ { {0x61, 0x45, 0x03, 0x11, 0x11} }, /* case-1 */ ++ { {0x61, 0x3a, 0x03, 0x11, 0x11} }, ++ { {0x61, 0x35, 0x03, 0x11, 0x11} }, ++ { {0x61, 0x20, 0x03, 0x11, 0x11} }, ++ { {0x61, 0x3a, 0x03, 0x11, 0x11} }, /* case-5 */ ++ { {0x61, 0x45, 0x03, 0x11, 0x10} }, ++ { {0x61, 0x35, 0x03, 0x11, 0x10} }, ++ { {0x61, 0x30, 0x03, 0x11, 0x10} }, ++ { {0x61, 0x20, 0x03, 0x11, 0x10} }, ++ { {0x61, 0x10, 0x03, 0x11, 0x10} }, /* case-10 */ ++ { {0x61, 0x08, 0x03, 0x11, 0x15} }, ++ { {0x61, 0x08, 0x03, 0x10, 0x14} }, ++ { {0x51, 0x08, 0x03, 0x10, 0x54} }, ++ { {0x51, 0x08, 0x03, 0x10, 0x55} }, ++ { {0x51, 0x08, 0x07, 0x10, 0x54} }, /* case-15 */ ++ { {0x51, 0x45, 0x03, 0x10, 0x50} }, ++ { {0x51, 0x3a, 0x03, 0x11, 0x50} }, ++ { {0x51, 0x30, 0x03, 0x10, 0x50} }, ++ { {0x51, 0x21, 0x03, 0x10, 0x50} }, ++ { {0x51, 0x10, 0x03, 0x10, 0x50} }, /* case-20 */ ++ { {0x51, 0x4a, 0x03, 0x10, 0x50} }, ++ { {0x51, 0x08, 0x03, 0x30, 0x54} }, ++ { {0x55, 0x08, 0x03, 0x10, 0x54} }, ++ { {0x65, 0x10, 0x03, 0x11, 0x10} }, ++ { {0x51, 0x10, 0x03, 0x10, 0x51} }, /* case-25 */ ++ { {0x51, 0x21, 0x03, 0x10, 0x50} }, ++ { {0x61, 0x08, 0x03, 0x11, 0x11} } ++}; ++ ++/* Non-Shared-Antenna TDMA */ ++static const struct coex_tdma_para tdma_nsant_8821a[] = { ++ { {0x00, 0x00, 0x00, 0x40, 0x00} }, /* case-100 */ ++ { {0x61, 0x45, 0x03, 0x11, 0x11} }, ++ { {0x61, 0x25, 0x03, 0x11, 0x11} }, ++ { {0x61, 0x35, 0x03, 0x11, 0x11} }, ++ { {0x61, 0x20, 0x03, 0x11, 0x11} }, ++ { {0x61, 0x10, 0x03, 0x11, 0x11} }, /* case-105 */ ++ { {0x61, 0x45, 0x03, 0x11, 0x10} }, ++ { {0x61, 0x30, 0x03, 0x11, 0x10} }, ++ { {0x61, 0x30, 0x03, 0x11, 0x10} }, ++ { {0x61, 0x20, 0x03, 0x11, 0x10} }, ++ { {0x61, 0x10, 0x03, 0x11, 0x10} }, /* case-110 */ ++ { {0x61, 0x10, 0x03, 0x11, 0x11} }, ++ { {0x51, 0x08, 0x03, 0x10, 0x14} }, /* a2dp high rssi */ ++ { {0x51, 0x08, 0x03, 0x10, 0x54} }, /* a2dp not high rssi */ ++ { {0x51, 0x08, 0x03, 0x10, 0x55} }, ++ { {0x51, 0x08, 0x07, 0x10, 0x54} }, /* case-115 */ ++ { {0x51, 0x45, 0x03, 0x10, 0x50} }, ++ { {0x51, 0x3a, 0x03, 0x10, 0x50} }, ++ { {0x51, 0x30, 0x03, 0x10, 0x50} }, ++ { {0x51, 0x21, 0x03, 0x10, 0x50} }, ++ { {0x51, 0x21, 0x03, 0x10, 0x50} }, /* case-120 */ ++ { {0x51, 0x10, 0x03, 0x10, 0x50} } ++}; ++ ++/* TODO */ ++static const struct coex_rf_para rf_para_tx_8821a[] = { ++ {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_8821a[] = { ++ {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_8821a) == ARRAY_SIZE(rf_para_rx_8821a)); ++ ++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}, ++ {0xCB4, MASKDWORD, RTW_REG_DOMAIN_MAC32}, ++ {0xCBA, MASKBYTE0, RTW_REG_DOMAIN_MAC8}, ++ {0, 0, RTW_REG_DOMAIN_NL}, ++ {0x430, MASKDWORD, RTW_REG_DOMAIN_MAC32}, ++ {0x434, MASKDWORD, RTW_REG_DOMAIN_MAC32}, ++ {0x42a, MASKLWORD, RTW_REG_DOMAIN_MAC16}, ++ {0x426, MASKBYTE0, RTW_REG_DOMAIN_MAC8}, ++ {0x45e, BIT(3), RTW_REG_DOMAIN_MAC8}, ++ {0x454, MASKLWORD, RTW_REG_DOMAIN_MAC16}, ++ {0, 0, RTW_REG_DOMAIN_NL}, ++ {0x4c, BIT(24) | BIT(23), RTW_REG_DOMAIN_MAC32}, ++ {0x64, BIT(0), RTW_REG_DOMAIN_MAC8}, ++ {0x4c6, BIT(4), RTW_REG_DOMAIN_MAC8}, ++ {0x40, BIT(5), RTW_REG_DOMAIN_MAC8}, ++ {0x1, RFREG_MASK, RTW_REG_DOMAIN_RF_A}, ++ {0, 0, RTW_REG_DOMAIN_NL}, ++ {0x550, MASKDWORD, RTW_REG_DOMAIN_MAC32}, ++ {0x522, MASKBYTE0, RTW_REG_DOMAIN_MAC8}, ++ {0x953, BIT(1), RTW_REG_DOMAIN_MAC8}, ++ {0xc50, MASKBYTE0, RTW_REG_DOMAIN_MAC8}, ++ {0x60A, MASKBYTE0, RTW_REG_DOMAIN_MAC8}, ++}; ++ ++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, ++ .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 = 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, ++ .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, ++ .intf_table = NULL, ++ .dig = rtw8821a_dig, ++ .rf_sipi_addr = {REG_LSSI_WRITE_A, REG_LSSI_WRITE_B}, ++ .ltecoex_addr = NULL, ++ .mac_tbl = &rtw8821a_mac_tbl, ++ .agc_tbl = &rtw8821a_agc_tbl, ++ .bb_tbl = &rtw8821a_bb_tbl, ++ .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 */ ++ .bt_desired_ver = 0x62, /* But for 2 ant it's 0x5c */ ++ .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 = 10, ++ .rssi_tolerance = 2, ++ .wl_rssi_step = wl_rssi_step_8821a, ++ .bt_rssi_step = bt_rssi_step_8821a, ++ .table_sant_num = ARRAY_SIZE(table_sant_8821a), ++ .table_sant = table_sant_8821a, ++ .table_nsant_num = ARRAY_SIZE(table_nsant_8821a), ++ .table_nsant = table_nsant_8821a, ++ .tdma_sant_num = ARRAY_SIZE(tdma_sant_8821a), ++ .tdma_sant = tdma_sant_8821a, ++ .tdma_nsant_num = ARRAY_SIZE(tdma_nsant_8821a), ++ .tdma_nsant = tdma_nsant_8821a, ++ .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 = ARRAY_SIZE(afh_5g_8821a), ++ .afh_5g = afh_5g_8821a, ++ ++ .coex_info_hw_regs_num = ARRAY_SIZE(coex_info_hw_regs_8821a), ++ .coex_info_hw_regs = coex_info_hw_regs_8821a, ++}; ++EXPORT_SYMBOL(rtw8821a_hw_spec); ++ ++MODULE_FIRMWARE("rtw88/rtw8821a_fw.bin"); ++ ++MODULE_AUTHOR("Realtek Corporation"); ++MODULE_DESCRIPTION("Realtek 802.11ac wireless 8821a/8811a driver"); ++MODULE_LICENSE("Dual BSD/GPL"); +diff --git a/drivers/net/wireless/realtek/rtw88/rtw8821a.h b/drivers/net/wireless/realtek/rtw88/rtw8821a.h +new file mode 100644 +index 000000000000..1b2e548f7234 +--- /dev/null ++++ b/drivers/net/wireless/realtek/rtw88/rtw8821a.h +@@ -0,0 +1,10 @@ ++/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */ ++/* Copyright(c) 2024 Realtek Corporation ++ */ ++ ++#ifndef __RTW8821A_H__ ++#define __RTW8821A_H__ ++ ++extern const struct rtw_chip_info rtw8821a_hw_spec; ++ ++#endif +-- +2.46.0 + + +From mboxrd@z Thu Jan 1 00:00:00 1970 +Received: from mail-ed1-f49.google.com (mail-ed1-f49.google.com [209.85.208.49]) + (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) + (No client certificate requested) + by smtp.subspace.kernel.org (Postfix) with ESMTPS id 79625199231 + for ; Fri, 11 Oct 2024 20:57:17 +0000 (UTC) +Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.208.49 +ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; + t=1728680240; cv=none; b=fG3Kr4U/WVvKZRsu4TLDv1xhUovJd6n8XLw0HB9J+MDnnN12bEGazlqlXMrAHMsf8P9CweswbU/oq6/Sg241pT+FJyqT6zfGSvQHy7+7YzpWkhojwQSZNt9vSCLDgzJfKEYJhLxOqk740o2ZR0fjy0wUo2NEXv9JPyP+ZOEz0qQ= +ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; + s=arc-20240116; t=1728680240; c=relaxed/simple; + bh=yNuQ6HcJRKGHehovjLc6CCTTjiMninZ4LwpdMJP5rrU=; + h=Message-ID:Date:MIME-Version:Subject:From:To:Cc:References: + In-Reply-To:Content-Type; b=FCLpPr4qVEy0PtngyqJoUhB/k7RXGV9kgWQIfvoRnhkcCV+Ptb8ImG6pdNI55y0yIJCOePTJYhKzD0Jb8RRTeGayjF4pUHlscTdzm9ZBmltCDF7DOJSP1REqaPzJZxzlbpwWiQR0QTlB5ktlTbK7HIBjsb8nAOPT2MJQanqW2XU= +ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=T88sMF0o; arc=none smtp.client-ip=209.85.208.49 +Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com +Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com +Authentication-Results: smtp.subspace.kernel.org; + dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="T88sMF0o" +Received: by mail-ed1-f49.google.com with SMTP id 4fb4d7f45d1cf-5c9362c26d8so3887749a12.1 + for ; Fri, 11 Oct 2024 13:57:17 -0700 (PDT) +DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; + d=gmail.com; s=20230601; t=1728680236; x=1729285036; darn=vger.kernel.org; + h=content-transfer-encoding:in-reply-to:content-language:references + :cc:to:from:subject:user-agent:mime-version:date:message-id:from:to + :cc:subject:date:message-id:reply-to; + bh=STDFFU6PegzE5NQcPlbTKRovJQCgxIj+pkMoEjJB2VM=; + b=T88sMF0oErq+yhkRMe1Yb8vcO2OpGjZND8howMeJgFn/sE4OAP0MEKzybsiNIcsEht + sWdnpnWNUdloktPpfF8I115uxQcIgwIA1zqvrSkvG1/rC5uPKCq1MxZCXxO7whQcVVkY + pnemsr2T/Sv9Pv5w7jWlRCvpTRwiu7AZiDOaTwLcSXUTcqF2+T7A+Da8O1vmDXQ4ZnvL + vcTYafPy/nS9gEK7f/htMdkhrGFMJrDHLDeJEMJWMLNbnf8JB9vqzT2OHwlctDZWEStt + cyk3wuzTCqcfntCcWnz7eT21K/EpBWhHm7ozukiAAwI/GhztPyGk0aUvhM6EvI6WimXy + jz8A== +X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; + d=1e100.net; s=20230601; t=1728680236; x=1729285036; + h=content-transfer-encoding:in-reply-to:content-language:references + :cc:to:from:subject:user-agent:mime-version:date:message-id + :x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; + bh=STDFFU6PegzE5NQcPlbTKRovJQCgxIj+pkMoEjJB2VM=; + b=VfWbJ/HNXFpYyqEN3dfYVYHNgkHNMJkwaGCXDUCVy88Rr15vuXRsF9sQ38nxD7jtAO + 5yYSTnoSx37WNxjGzFVVhU4PidX93cd8/yMa3rTfbc9TJpuaAIgY+5aVHjuuMnFUrN04 + z9Ggc8zeTfrRbdvqgqG6SDrj9Gim1lIR+2bpQuXJFxgxgU6EKippQdJwHCjF6sTVkqHi + YcAhJovkJZhSXmuBdM4sjOX7XrEQ2u9B56SLvg3e1J3gmXZWDRzoqtnRPn8IjVF7Nfe1 + U0nzlgXln7v4NuaHrV7//GvVReOkXm17V0ZS6zbprsrP/ngRU6RJgMuF9XRaKxXzIhut + Uqjg== +X-Gm-Message-State: AOJu0YzFmQEwLHC99o6UsqUbpNMhY0840kxqkHtzrzbLz8wfW0X/kcbA + Bko3Tj1qbpL2eT9VHGQr1krQAqElidtrvKxg+lhYCkyZK7kotCz3OIpKcA== +X-Google-Smtp-Source: AGHT+IEEfBkmGYxqnp7kduLPQB8CNTiBQ9temdvqKaAMBEdsAOPqJum8oEyjPX8cYAByBLWrGlACQQ== +X-Received: by 2002:a17:906:4fd1:b0:a99:4e74:52aa with SMTP id a640c23a62f3a-a99b89f3f6bmr345341066b.33.1728680235350; + Fri, 11 Oct 2024 13:57:15 -0700 (PDT) +Received: from [192.168.0.50] ([79.113.150.231]) + by smtp.gmail.com with ESMTPSA id a640c23a62f3a-a99a7f35f4fsm250938766b.88.2024.10.11.13.57.14 + (version=TLS1_3 cipher=TLS_AES_128_GCM_SHA256 bits=128/128); + Fri, 11 Oct 2024 13:57:14 -0700 (PDT) +Message-ID: +Date: Fri, 11 Oct 2024 23:57:14 +0300 +Precedence: bulk +X-Mailing-List: linux-wireless@vger.kernel.org +List-Id: +List-Subscribe: +List-Unsubscribe: +MIME-Version: 1.0 +User-Agent: Mozilla Thunderbird +Subject: [PATCH v2 20/22] wifi: rtw88: Add rtw8812a.{c,h} +From: Bitterblue Smith +To: "linux-wireless@vger.kernel.org" +Cc: Ping-Ke Shih +References: +Content-Language: en-US +In-Reply-To: +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 7bit + +These contain code specific to RTL8812AU. + +Signed-off-by: Bitterblue Smith +--- +v2: + - Patch is new in v2. + - All of this used to be in patch 18/20 in v1. + - Replace some while loops with for loops in the IQK code. + - Constify structs/arrays. +--- + drivers/net/wireless/realtek/rtw88/rtw8812a.c | 1102 +++++++++++++++++ + drivers/net/wireless/realtek/rtw88/rtw8812a.h | 10 + + 2 files changed, 1112 insertions(+) + create mode 100644 drivers/net/wireless/realtek/rtw88/rtw8812a.c + create mode 100644 drivers/net/wireless/realtek/rtw88/rtw8812a.h + +diff --git a/drivers/net/wireless/realtek/rtw88/rtw8812a.c b/drivers/net/wireless/realtek/rtw88/rtw8812a.c +new file mode 100644 +index 000000000000..e2c0ca98cc84 +--- /dev/null ++++ b/drivers/net/wireless/realtek/rtw88/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/drivers/net/wireless/realtek/rtw88/rtw8812a.h b/drivers/net/wireless/realtek/rtw88/rtw8812a.h +new file mode 100644 +index 000000000000..82dab59e341d +--- /dev/null ++++ b/drivers/net/wireless/realtek/rtw88/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 +-- +2.46.0 + + +From mboxrd@z Thu Jan 1 00:00:00 1970 +Received: from mail-ej1-f48.google.com (mail-ej1-f48.google.com [209.85.218.48]) + (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) + (No client certificate requested) + by smtp.subspace.kernel.org (Postfix) with ESMTPS id 6DECE199231 + for ; Fri, 11 Oct 2024 20:57:53 +0000 (UTC) +Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.218.48 +ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; + t=1728680275; cv=none; b=IL13ehqYqfIrHSRltvXQ+voS1GYoM64XSnzxQxJxF7BhPaFvZ5hllhbn8cGzgmMtk9OlHADQrLDHxDjc9HBJNiw6pdCfk0VVCA1oZmeGDGGHP5GRTvslhMK/ESa+1VaShmCHkSlulj/J3Dw7ftaVoxAF8poIWy9ps9XN4D0wKqU= +ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; + s=arc-20240116; t=1728680275; c=relaxed/simple; + bh=ziWm2+ngaUoQT2C8x0Sl5HMBA7tf02WN1FTi9LBXcBo=; + h=Message-ID:Date:MIME-Version:Subject:From:To:Cc:References: + In-Reply-To:Content-Type; b=It/O1up+O8l0KLTibU/PzQNfshnkpFBp/WVsUhdTnHJB/AS/hnhkAU1tMUYInVXk6zikljFn0Kop33i7tA4fpWOzbnTTOhGVzDOCdKRYko4D5eGFAEx/oowzkjBD353I1AGQcyAspsZr+UOuFlnnIthx0WpR7u7vexvLJ77Bl7s= +ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=RJ/DmrZ9; arc=none smtp.client-ip=209.85.218.48 +Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com +Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com +Authentication-Results: smtp.subspace.kernel.org; + dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="RJ/DmrZ9" +Received: by mail-ej1-f48.google.com with SMTP id a640c23a62f3a-a993302fa02so379848166b.0 + for ; Fri, 11 Oct 2024 13:57:53 -0700 (PDT) +DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; + d=gmail.com; s=20230601; t=1728680272; x=1729285072; darn=vger.kernel.org; + h=content-transfer-encoding:in-reply-to:content-language:references + :cc:to:from:subject:user-agent:mime-version:date:message-id:from:to + :cc:subject:date:message-id:reply-to; + bh=C+ZsDva5wM9plswRg48jz0bzrVmsuPe+/kH9kb+DaJs=; + b=RJ/DmrZ9Gw88uRlnknILkMZB4ODSyyRBWHG7A+vLLc5wp+D94h8cUFb+A/6aAzlwv3 + TTN2eJqWfN9a2FlDbJE+8sUNqUXJOpG6c8HvWPNRD2M0uUKPP5NVaiPr9BGdFimBIcAO + cLjDxppK7NHo+ynktu6lxRPJbcO1I87ru1+p3/3FMWb8zCwpTzJoG50OHN9aPYqfVcTt + KzJL5alPZ1UMHlQmXRnqL9lBzJaMEVffENpBjRntIqx+RaSFP4883PH3NApum0FMmFQS + 9WRQUYJQEUtbIv/hg+bO1zg08fv3Oq0VjCV+aq0VUGxGCkZrrk49yo6gH8BLZoFgIT1F + w86A== +X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; + d=1e100.net; s=20230601; t=1728680272; x=1729285072; + h=content-transfer-encoding:in-reply-to:content-language:references + :cc:to:from:subject:user-agent:mime-version:date:message-id + :x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; + bh=C+ZsDva5wM9plswRg48jz0bzrVmsuPe+/kH9kb+DaJs=; + b=NF2YUufUEbiI98qWgj1TvQYuxYkLHmUll6FfypMcBM8J7ZZDoDDhBC2RMAAJz8kUAC + DpmS4N5WSiZNV1RRnW8uo4hHrILVYxIC2/GSaRlgZP2s1OLCC1sb4sl70q+jsaJuhx0b + +I/vcQ06rnK6S1H7dtMMYMBqjPwW43+MC9oyo4JHfpRI8q46Jm3P/kQHtZva9C1AXQTo + Sd1LMpLvOn8cSoHAJ73niwAncVwp2nlD7wu3ghPzIS3AnevIu5QRu+QO2gUDrnofh63z + iofxNUUYte3osSaXwa64iNffSvI5LiIODtpQyfW3hMxcr9KQuiIRrGCn89Ga7XVOvzzS + hWsw== +X-Gm-Message-State: AOJu0YzSkuCOzO7cwV1PxmaLoijyEX20iR4v+KqslrUgt9yscZd7jxMf + gHbN5HRc6I9tXDViZGjPbEICcUVaAP81znbe9eehpXsfONNnJU2Z4z54iw== +X-Google-Smtp-Source: AGHT+IFHF2UU0xm3Vr/FU3QCq4gwTj+sr7LapY4uXJKYNrJjku4PdqYyQU6QpRq9Y9MV5kHsl/YzhA== +X-Received: by 2002:a17:907:7ba4:b0:a99:76cb:cedd with SMTP id a640c23a62f3a-a99b9303b4fmr287565466b.9.1728680271582; + Fri, 11 Oct 2024 13:57:51 -0700 (PDT) +Received: from [192.168.0.50] ([79.113.150.231]) + by smtp.gmail.com with ESMTPSA id a640c23a62f3a-a99dfa32196sm35814266b.160.2024.10.11.13.57.50 + (version=TLS1_3 cipher=TLS_AES_128_GCM_SHA256 bits=128/128); + Fri, 11 Oct 2024 13:57:51 -0700 (PDT) +Message-ID: <45604f31-a992-4188-b8c6-2d8e43981d77@gmail.com> +Date: Fri, 11 Oct 2024 23:57:50 +0300 +Precedence: bulk +X-Mailing-List: linux-wireless@vger.kernel.org +List-Id: +List-Subscribe: +List-Unsubscribe: +MIME-Version: 1.0 +User-Agent: Mozilla Thunderbird +Subject: [PATCH v2 21/22] wifi: rtw88: Add rtw8821au.c and rtw8812au.c +From: Bitterblue Smith +To: "linux-wireless@vger.kernel.org" +Cc: Ping-Ke Shih +References: +Content-Language: en-US +In-Reply-To: +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 7bit + +These are the entry points for the new modules rtw88_8821au +(RTL8821AU/RTL8811AU) and rtw88_8812au (RTL8812AU). + +Signed-off-by: Bitterblue Smith +--- +v2: + - Fix copyright year. + - Include the correct header rtw8812a.h in rtw8812au.c. +--- + .../net/wireless/realtek/rtw88/rtw8812au.c | 28 +++++++++++++++++++ + .../net/wireless/realtek/rtw88/rtw8821au.c | 28 +++++++++++++++++++ + 2 files changed, 56 insertions(+) + create mode 100644 drivers/net/wireless/realtek/rtw88/rtw8812au.c + create mode 100644 drivers/net/wireless/realtek/rtw88/rtw8821au.c + +diff --git a/drivers/net/wireless/realtek/rtw88/rtw8812au.c b/drivers/net/wireless/realtek/rtw88/rtw8812au.c +new file mode 100644 +index 000000000000..4da69590a423 +--- /dev/null ++++ b/drivers/net/wireless/realtek/rtw88/rtw8812au.c +@@ -0,0 +1,28 @@ ++// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause ++/* Copyright(c) 2024 Realtek Corporation ++ */ ++ ++#include ++#include ++#include "main.h" ++#include "rtw8812a.h" ++#include "usb.h" ++ ++static const struct usb_device_id rtw_8812au_id_table[] = { ++ { USB_DEVICE_AND_INTERFACE_INFO(0x2604, 0x0012, 0xff, 0xff, 0xff), ++ .driver_info = (kernel_ulong_t)&(rtw8812a_hw_spec) }, ++ {}, ++}; ++MODULE_DEVICE_TABLE(usb, rtw_8812au_id_table); ++ ++static struct usb_driver rtw_8812au_driver = { ++ .name = "rtw_8812au", ++ .id_table = rtw_8812au_id_table, ++ .probe = rtw_usb_probe, ++ .disconnect = rtw_usb_disconnect, ++}; ++module_usb_driver(rtw_8812au_driver); ++ ++MODULE_AUTHOR("Bitterblue Smith "); ++MODULE_DESCRIPTION("Realtek 802.11ac wireless 8812au driver"); ++MODULE_LICENSE("Dual BSD/GPL"); +diff --git a/drivers/net/wireless/realtek/rtw88/rtw8821au.c b/drivers/net/wireless/realtek/rtw88/rtw8821au.c +new file mode 100644 +index 000000000000..730018773e1c +--- /dev/null ++++ b/drivers/net/wireless/realtek/rtw88/rtw8821au.c +@@ -0,0 +1,28 @@ ++// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause ++/* Copyright(c) 2024 Realtek Corporation ++ */ ++ ++#include ++#include ++#include "main.h" ++#include "rtw8821a.h" ++#include "usb.h" ++ ++static const struct usb_device_id rtw_8821au_id_table[] = { ++ { USB_DEVICE_AND_INTERFACE_INFO(0x2357, 0x011e, 0xff, 0xff, 0xff), ++ .driver_info = (kernel_ulong_t)&(rtw8821a_hw_spec) }, ++ {}, ++}; ++MODULE_DEVICE_TABLE(usb, rtw_8821au_id_table); ++ ++static struct usb_driver rtw_8821au_driver = { ++ .name = "rtw_8821au", ++ .id_table = rtw_8821au_id_table, ++ .probe = rtw_usb_probe, ++ .disconnect = rtw_usb_disconnect, ++}; ++module_usb_driver(rtw_8821au_driver); ++ ++MODULE_AUTHOR("Bitterblue Smith "); ++MODULE_DESCRIPTION("Realtek 802.11ac wireless 8821au/8811au driver"); ++MODULE_LICENSE("Dual BSD/GPL"); +-- +2.46.0 + + +From mboxrd@z Thu Jan 1 00:00:00 1970 +Received: from mail-wm1-f50.google.com (mail-wm1-f50.google.com [209.85.128.50]) + (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) + (No client certificate requested) + by smtp.subspace.kernel.org (Postfix) with ESMTPS id 4E724199231 + for ; Fri, 11 Oct 2024 20:59:36 +0000 (UTC) +Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.128.50 +ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; + t=1728680378; cv=none; b=fWMSdUTxWC9zyxmDMdaYnDkp0SZRS6drzP5LR8Sc5P2mkNclR3jpHlKSInW7sT/6VdF5DS9kyJUxz/UVksaBCAbdEXZ4eeMlogbRsBG2bHACWRrCHXZgZAVaa9pNxGRAmkCXnpmcxikd4ULM5Tq8iaFt2Tk/gx/itRWJdM9+75I= +ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; + s=arc-20240116; t=1728680378; c=relaxed/simple; + bh=+aLtGxgwyXoTf272H31YNlH81842EMaVZoqPheZDjFE=; + h=Message-ID:Date:MIME-Version:Subject:From:To:Cc:References: + In-Reply-To:Content-Type; b=bJvKm5h58SCP0IlEqkAW7QTlWbDpKPygO6IDshYqyvZ7eigd6hG9wv2nzj+oCzWp7QKeXhcD1RhdL5FL9gDSK5h/qnC/k/vvqwNUkhnbJz4CCtdGenmB2fMbv8zkGF7GDTKqO1vBcAs5AtyDSo7nAMWiIyrk3Iwqm0lwfuAIWKU= +ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=Ck3RhPHH; arc=none smtp.client-ip=209.85.128.50 +Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com +Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com +Authentication-Results: smtp.subspace.kernel.org; + dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="Ck3RhPHH" +Received: by mail-wm1-f50.google.com with SMTP id 5b1f17b1804b1-4311d972e3eso8578975e9.3 + for ; Fri, 11 Oct 2024 13:59:36 -0700 (PDT) +DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; + d=gmail.com; s=20230601; t=1728680375; x=1729285175; darn=vger.kernel.org; + h=content-transfer-encoding:in-reply-to:content-language:references + :cc:to:from:subject:user-agent:mime-version:date:message-id:from:to + :cc:subject:date:message-id:reply-to; + bh=C64T1OkBHMwFqAILNUVhJMwuGbathbTE0nynqHuRkSU=; + b=Ck3RhPHHJjqdeZtO/EknCIdehpO4V8dZI5Jghmozy+UNLxYWMimD4x1euQzuqmYOge + No9aYY9LcSliHH6mwtsj9nrmhJCnjwsQPq7WMqN6W/aE3+DZOJ+uCH/YHg3XuESt2V7G + uitb6hrmQzK5fSva5y0KZT6t7yAXCuKOkDGGL2oss++WgxutEzCtDrVIJLb3hKeS3Jjz + p5XVTyH4yJkA0l2dVdlU4amQ2FLCJwasj4RScXveE22sq0rzTIoz/kBcbIsziCynfjTQ + B7eisPwwQcWc5q1fzL/vALLN+IKJfop7ThK1jqjUKRCv5KfjwZAofbyj3JOfx/Rcn9kd + dpDw== +X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; + d=1e100.net; s=20230601; t=1728680375; x=1729285175; + h=content-transfer-encoding:in-reply-to:content-language:references + :cc:to:from:subject:user-agent:mime-version:date:message-id + :x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; + bh=C64T1OkBHMwFqAILNUVhJMwuGbathbTE0nynqHuRkSU=; + b=cy3MBKkZrzshOK42SeJYna0n58ThkUz7MgSV7787/EUHIGJBADawgM5WOItq6MLX0F + wKD9EfRlDQrO2JnFYacBNJAIyO6iA9rK1PMZCgouWD+HkOQPbUFvk+C8khqM2WKGWcqK + qraUgXsPqgZmnIiCjQ1lDYOVh56sH8dN3aW3JxMG3glCLI7txzy2FhQOwvIA0mtRm03e + ONY9Ex5WpgeotCfK1Qpr4zJ5s4vF43NNj7HonzxpyfF9nV9Qa16uwU0edg54TqbVFOBq + DqiHJLY2zgSgiLrefR6mRLdRn7AX6dHb+A2lZFhs9+uXNViYzzMCgGScug4ue/hkxl47 + tDkQ== +X-Gm-Message-State: AOJu0YyRUt3BhVcqVbx3e3yWsKGGgbJBfAf4f/9aYvD4qEP3+kgVp1BD + jSFac00KMNieJuQ9KgUz6xcYoAvHPV7BLPDQKlZAQ75SLg2r27Fc5nMH4g== +X-Google-Smtp-Source: AGHT+IETAgTYU0OFJvPzgIFFLrrCKnXsWgK27KzVQ/e0Su5yi+jCSvzj8UsSKoNibaP7jjMTvO3yPg== +X-Received: by 2002:a05:600c:1d20:b0:42b:af5a:109 with SMTP id 5b1f17b1804b1-4312560903cmr5562025e9.24.1728680374545; + Fri, 11 Oct 2024 13:59:34 -0700 (PDT) +Received: from [192.168.0.50] ([79.113.150.231]) + by smtp.gmail.com with ESMTPSA id 5b1f17b1804b1-431182ffc51sm51000965e9.15.2024.10.11.13.59.33 + (version=TLS1_3 cipher=TLS_AES_128_GCM_SHA256 bits=128/128); + Fri, 11 Oct 2024 13:59:34 -0700 (PDT) +Message-ID: <144dc024-e82b-464a-8182-4b051c009cd8@gmail.com> +Date: Fri, 11 Oct 2024 23:59:32 +0300 +Precedence: bulk +X-Mailing-List: linux-wireless@vger.kernel.org +List-Id: +List-Subscribe: +List-Unsubscribe: +MIME-Version: 1.0 +User-Agent: Mozilla Thunderbird +Subject: [PATCH v2 22/22] wifi: rtw88: Enable the new RTL8821AU/RTL8812AU + drivers +From: Bitterblue Smith +To: "linux-wireless@vger.kernel.org" +Cc: Ping-Ke Shih , Zenm Chen , + Christian Hewitt , Nick Morrow +References: +Content-Language: en-US +In-Reply-To: +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 7bit + +These are older Wifi 5 chips. RTL8821AU is 1x1, with or without +Bluetooth. RTL8812AU is 2x2, without Bluetooth. + +Beamforming is not implemented. It looks like these chips need a +different implementation than what is in bf.c. + +Speed tests with RTL8821AU: 137 Mbps download, 144 Mbps upload. +Speed tests with RTL8812AU: 344 Mbps download, 387 Mbps upload. + +Station mode and AP mode were tested. + +Bluetooth coexistence works. I used my Bluetooth headphones for +several days, listening to music and watching videos. There is only +a problem with the wifi speeds with one router: + +With ISP's HG6544C router: +Official driver: 3/5 Mbps. +rtw88: a bit more, but not steady at all. Not enough to watch a 1080p +Youtube video. + +With my D-Link Eagle R32 router running Openwrt, on the same channel: +Official driver: 6/10 Mbps. +rtw88: download starts around 30, climbs to 50 / upload is 10 Mbps. +I can watch a 1080p Youtube video. + +The music doesn't cut out during any speed tests. + +I also tested transferring files to and from my phone. I don't have +other types of Bluetooth devices to test. + +Signed-off-by: Bitterblue Smith +--- +v2: + - Add more information to the commit message. + - Add the new rtw88_88xxa and rtw88_8812a modules. +--- + drivers/net/wireless/realtek/rtw88/Kconfig | 33 +++++++++++++++++++++ + drivers/net/wireless/realtek/rtw88/Makefile | 15 ++++++++++ + 2 files changed, 48 insertions(+) + +diff --git a/drivers/net/wireless/realtek/rtw88/Kconfig b/drivers/net/wireless/realtek/rtw88/Kconfig +index 02b0d698413b..2e6fc696d220 100644 +--- a/drivers/net/wireless/realtek/rtw88/Kconfig ++++ b/drivers/net/wireless/realtek/rtw88/Kconfig +@@ -43,6 +43,17 @@ config RTW88_8723D + config RTW88_8821C + tristate + ++config RTW88_88XXA ++ tristate ++ ++config RTW88_8821A ++ tristate ++ select RTW88_88XXA ++ ++config RTW88_8812A ++ tristate ++ select RTW88_88XXA ++ + config RTW88_8822BE + tristate "Realtek 8822BE PCI wireless network adapter" + depends on PCI +@@ -189,6 +200,28 @@ config RTW88_8821CU + + 802.11ac USB wireless network adapter + ++config RTW88_8821AU ++ tristate "Realtek 8821AU USB wireless network adapter" ++ depends on USB ++ select RTW88_CORE ++ select RTW88_USB ++ select RTW88_8821A ++ help ++ Select this option will enable support for 8821AU chipset ++ ++ 802.11ac USB wireless network adapter ++ ++config RTW88_8812AU ++ tristate "Realtek 8812AU USB wireless network adapter" ++ depends on USB ++ select RTW88_CORE ++ select RTW88_USB ++ select RTW88_8812A ++ help ++ Select this option will enable support for 8812AU chipset ++ ++ 802.11ac USB wireless network adapter ++ + config RTW88_DEBUG + bool "Realtek rtw88 debug support" + depends on RTW88_CORE +diff --git a/drivers/net/wireless/realtek/rtw88/Makefile b/drivers/net/wireless/realtek/rtw88/Makefile +index 8f47359b4380..f0b49f5a8a5a 100644 +--- a/drivers/net/wireless/realtek/rtw88/Makefile ++++ b/drivers/net/wireless/realtek/rtw88/Makefile +@@ -77,6 +77,21 @@ rtw88_8821cs-objs := rtw8821cs.o + obj-$(CONFIG_RTW88_8821CU) += rtw88_8821cu.o + rtw88_8821cu-objs := rtw8821cu.o + ++obj-$(CONFIG_RTW88_88XXA) += rtw88_88xxa.o ++rtw88_88xxa-objs := rtw88xxa.o ++ ++obj-$(CONFIG_RTW88_8821A) += rtw88_8821a.o ++rtw88_8821a-objs := rtw8821a.o rtw8821a_table.o ++ ++obj-$(CONFIG_RTW88_8812A) += rtw88_8812a.o ++rtw88_8812a-objs := rtw8812a.o rtw8812a_table.o ++ ++obj-$(CONFIG_RTW88_8821AU) += rtw88_8821au.o ++rtw88_8821au-objs := rtw8821au.o ++ ++obj-$(CONFIG_RTW88_8812AU) += rtw88_8812au.o ++rtw88_8812au-objs := rtw8812au.o ++ + obj-$(CONFIG_RTW88_PCI) += rtw88_pci.o + rtw88_pci-objs := pci.o + +-- +2.46.0 + + From 9e7a10ab126f79a653c84ea7ebe332bed59d2db1 Mon Sep 17 00:00:00 2001 From: Rudi Heitbaum Date: Sun, 13 Oct 2024 13:53:08 +0000 Subject: [PATCH 2/5] linux: enable kernel based RTW88_8821AU and RTW88_8812AU --- projects/Allwinner/linux/linux.aarch64.conf | 5 +++++ projects/Allwinner/linux/linux.arm.conf | 5 +++++ projects/Amlogic/linux/linux.aarch64.conf | 7 +++++++ projects/Generic/linux/linux.x86_64.conf | 5 +++++ projects/NXP/devices/iMX6/linux/linux.arm.conf | 5 +++++ projects/NXP/devices/iMX8/linux/linux.aarch64.conf | 5 +++++ projects/RPi/devices/RPi/linux/linux.arm.conf | 6 ++++++ projects/RPi/devices/RPi2/linux/linux.arm.conf | 6 ++++++ projects/RPi/devices/RPi4/linux/linux.aarch64.conf | 6 ++++++ projects/RPi/devices/RPi5/linux/linux.aarch64.conf | 6 ++++++ .../Rockchip/devices/RK3288/linux/default/linux.arm.conf | 5 +++++ .../devices/RK3328/linux/default/linux.aarch64.conf | 5 +++++ .../devices/RK3399/linux/default/linux.aarch64.conf | 5 +++++ projects/Samsung/linux/linux.arm.conf | 5 +++++ 14 files changed, 76 insertions(+) diff --git a/projects/Allwinner/linux/linux.aarch64.conf b/projects/Allwinner/linux/linux.aarch64.conf index 9dde09405b..84c2cf639e 100644 --- a/projects/Allwinner/linux/linux.aarch64.conf +++ b/projects/Allwinner/linux/linux.aarch64.conf @@ -2274,6 +2274,9 @@ CONFIG_RTW88_8723X=m CONFIG_RTW88_8703B=m CONFIG_RTW88_8723D=m CONFIG_RTW88_8821C=m +CONFIG_RTW88_88XXA=m +CONFIG_RTW88_8821A=m +CONFIG_RTW88_8812A=m CONFIG_RTW88_8822BS=m CONFIG_RTW88_8822BU=m CONFIG_RTW88_8822CS=m @@ -2283,6 +2286,8 @@ CONFIG_RTW88_8723CS=m CONFIG_RTW88_8723DU=m CONFIG_RTW88_8821CS=m CONFIG_RTW88_8821CU=m +CONFIG_RTW88_8821AU=m +CONFIG_RTW88_8812AU=m # CONFIG_RTW88_DEBUG is not set # CONFIG_RTW88_DEBUGFS is not set # CONFIG_RTW89 is not set diff --git a/projects/Allwinner/linux/linux.arm.conf b/projects/Allwinner/linux/linux.arm.conf index 7fda64d7e1..deb6ed3fac 100644 --- a/projects/Allwinner/linux/linux.arm.conf +++ b/projects/Allwinner/linux/linux.arm.conf @@ -2114,6 +2114,9 @@ CONFIG_RTW88_8723X=m CONFIG_RTW88_8703B=m CONFIG_RTW88_8723D=m CONFIG_RTW88_8821C=m +CONFIG_RTW88_88XXA=m +CONFIG_RTW88_8821A=m +CONFIG_RTW88_8812A=m CONFIG_RTW88_8822BS=m CONFIG_RTW88_8822BU=m CONFIG_RTW88_8822CS=m @@ -2123,6 +2126,8 @@ CONFIG_RTW88_8723CS=m CONFIG_RTW88_8723DU=m CONFIG_RTW88_8821CS=m CONFIG_RTW88_8821CU=m +CONFIG_RTW88_8821AU=m +CONFIG_RTW88_8812AU=m # CONFIG_RTW88_DEBUG is not set # CONFIG_RTW88_DEBUGFS is not set # CONFIG_RTW89 is not set diff --git a/projects/Amlogic/linux/linux.aarch64.conf b/projects/Amlogic/linux/linux.aarch64.conf index f188b58d36..b28d59daf6 100644 --- a/projects/Amlogic/linux/linux.aarch64.conf +++ b/projects/Amlogic/linux/linux.aarch64.conf @@ -2481,8 +2481,12 @@ CONFIG_RTW88_SDIO=m CONFIG_RTW88_USB=m CONFIG_RTW88_8822B=m CONFIG_RTW88_8822C=m +CONFIG_RTW88_8723X=m CONFIG_RTW88_8723D=m CONFIG_RTW88_8821C=m +CONFIG_RTW88_88XXA=m +CONFIG_RTW88_8821A=m +CONFIG_RTW88_8812A=m # CONFIG_RTW88_8822BE is not set CONFIG_RTW88_8822BS=m CONFIG_RTW88_8822BU=m @@ -2491,10 +2495,13 @@ CONFIG_RTW88_8822CS=m CONFIG_RTW88_8822CU=m # CONFIG_RTW88_8723DE is not set # CONFIG_RTW88_8723DS is not set +# CONFIG_RTW88_8723CS is not set CONFIG_RTW88_8723DU=m # CONFIG_RTW88_8821CE is not set CONFIG_RTW88_8821CS=m CONFIG_RTW88_8821CU=m +CONFIG_RTW88_8821AU=m +CONFIG_RTW88_8812AU=m # CONFIG_RTW88_DEBUG is not set # CONFIG_RTW88_DEBUGFS is not set # CONFIG_RTW89 is not set diff --git a/projects/Generic/linux/linux.x86_64.conf b/projects/Generic/linux/linux.x86_64.conf index 0126151d62..7ced5d7f09 100644 --- a/projects/Generic/linux/linux.x86_64.conf +++ b/projects/Generic/linux/linux.x86_64.conf @@ -2709,6 +2709,9 @@ CONFIG_RTW88_8822C=m CONFIG_RTW88_8723X=m CONFIG_RTW88_8723D=m CONFIG_RTW88_8821C=m +CONFIG_RTW88_88XXA=m +CONFIG_RTW88_8821A=m +CONFIG_RTW88_8812A=m CONFIG_RTW88_8822BE=m # CONFIG_RTW88_8822BS is not set CONFIG_RTW88_8822BU=m @@ -2722,6 +2725,8 @@ CONFIG_RTW88_8723DU=m CONFIG_RTW88_8821CE=m # CONFIG_RTW88_8821CS is not set CONFIG_RTW88_8821CU=m +CONFIG_RTW88_8821AU=m +CONFIG_RTW88_8812AU=m # CONFIG_RTW88_DEBUG is not set # CONFIG_RTW88_DEBUGFS is not set CONFIG_RTW89=m diff --git a/projects/NXP/devices/iMX6/linux/linux.arm.conf b/projects/NXP/devices/iMX6/linux/linux.arm.conf index 0505442212..f3952c717c 100644 --- a/projects/NXP/devices/iMX6/linux/linux.arm.conf +++ b/projects/NXP/devices/iMX6/linux/linux.arm.conf @@ -2473,6 +2473,9 @@ CONFIG_RTW88_8822C=m CONFIG_RTW88_8723X=m CONFIG_RTW88_8723D=m CONFIG_RTW88_8821C=m +CONFIG_RTW88_88XXA=m +CONFIG_RTW88_8821A=m +CONFIG_RTW88_8812A=m # CONFIG_RTW88_8822BE is not set # CONFIG_RTW88_8822BS is not set CONFIG_RTW88_8822BU=m @@ -2486,6 +2489,8 @@ CONFIG_RTW88_8723DU=m # CONFIG_RTW88_8821CE is not set # CONFIG_RTW88_8821CS is not set CONFIG_RTW88_8821CU=m +CONFIG_RTW88_8821AU=m +CONFIG_RTW88_8812AU=m # CONFIG_RTW88_DEBUG is not set # CONFIG_RTW88_DEBUGFS is not set # CONFIG_RTW89 is not set diff --git a/projects/NXP/devices/iMX8/linux/linux.aarch64.conf b/projects/NXP/devices/iMX8/linux/linux.aarch64.conf index 1506fb9303..9b9ec2f9f1 100644 --- a/projects/NXP/devices/iMX8/linux/linux.aarch64.conf +++ b/projects/NXP/devices/iMX8/linux/linux.aarch64.conf @@ -2498,6 +2498,9 @@ CONFIG_RTW88_8822C=m CONFIG_RTW88_8723X=m CONFIG_RTW88_8723D=m CONFIG_RTW88_8821C=m +CONFIG_RTW88_88XXA=m +CONFIG_RTW88_8821A=m +CONFIG_RTW88_8812A=m # CONFIG_RTW88_8822BE is not set # CONFIG_RTW88_8822BS is not set CONFIG_RTW88_8822BU=m @@ -2511,6 +2514,8 @@ CONFIG_RTW88_8723DU=m # CONFIG_RTW88_8821CE is not set # CONFIG_RTW88_8821CS is not set CONFIG_RTW88_8821CU=m +CONFIG_RTW88_8821AU=m +CONFIG_RTW88_8812AU=m # CONFIG_RTW88_DEBUG is not set # CONFIG_RTW88_DEBUGFS is not set # CONFIG_RTW89 is not set diff --git a/projects/RPi/devices/RPi/linux/linux.arm.conf b/projects/RPi/devices/RPi/linux/linux.arm.conf index f64d521147..f82c02c292 100644 --- a/projects/RPi/devices/RPi/linux/linux.arm.conf +++ b/projects/RPi/devices/RPi/linux/linux.arm.conf @@ -1750,8 +1750,12 @@ CONFIG_RTW88_CORE=m CONFIG_RTW88_USB=m CONFIG_RTW88_8822B=m CONFIG_RTW88_8822C=m +CONFIG_RTW88_8723X=m CONFIG_RTW88_8723D=m CONFIG_RTW88_8821C=m +CONFIG_RTW88_88XXA=m +CONFIG_RTW88_8821A=m +CONFIG_RTW88_8812A=m # CONFIG_RTW88_8822BS is not set CONFIG_RTW88_8822BU=m # CONFIG_RTW88_8822CS is not set @@ -1760,6 +1764,8 @@ CONFIG_RTW88_8822CU=m CONFIG_RTW88_8723DU=m # CONFIG_RTW88_8821CS is not set CONFIG_RTW88_8821CU=m +CONFIG_RTW88_8821AU=m +CONFIG_RTW88_8812AU=m # CONFIG_RTW88_DEBUG is not set # CONFIG_RTW88_DEBUGFS is not set # CONFIG_RTW89 is not set diff --git a/projects/RPi/devices/RPi2/linux/linux.arm.conf b/projects/RPi/devices/RPi2/linux/linux.arm.conf index a6a86c5948..dbd38884f0 100644 --- a/projects/RPi/devices/RPi2/linux/linux.arm.conf +++ b/projects/RPi/devices/RPi2/linux/linux.arm.conf @@ -1977,8 +1977,12 @@ CONFIG_RTW88_CORE=m CONFIG_RTW88_USB=m CONFIG_RTW88_8822B=m CONFIG_RTW88_8822C=m +CONFIG_RTW88_8723X=m CONFIG_RTW88_8723D=m CONFIG_RTW88_8821C=m +CONFIG_RTW88_88XXA=m +CONFIG_RTW88_8821A=m +CONFIG_RTW88_8812A=m # CONFIG_RTW88_8822BS is not set CONFIG_RTW88_8822BU=m # CONFIG_RTW88_8822CS is not set @@ -1987,6 +1991,8 @@ CONFIG_RTW88_8822CU=m CONFIG_RTW88_8723DU=m # CONFIG_RTW88_8821CS is not set CONFIG_RTW88_8821CU=m +CONFIG_RTW88_8821AU=m +CONFIG_RTW88_8812AU=m # CONFIG_RTW88_DEBUG is not set # CONFIG_RTW88_DEBUGFS is not set # CONFIG_RTW89 is not set diff --git a/projects/RPi/devices/RPi4/linux/linux.aarch64.conf b/projects/RPi/devices/RPi4/linux/linux.aarch64.conf index 743bd2bcd6..7d91f4bb50 100644 --- a/projects/RPi/devices/RPi4/linux/linux.aarch64.conf +++ b/projects/RPi/devices/RPi4/linux/linux.aarch64.conf @@ -2517,8 +2517,12 @@ CONFIG_RTW88_CORE=m CONFIG_RTW88_USB=m CONFIG_RTW88_8822B=m CONFIG_RTW88_8822C=m +CONFIG_RTW88_8723X=m CONFIG_RTW88_8723D=m CONFIG_RTW88_8821C=m +CONFIG_RTW88_88XXA=m +CONFIG_RTW88_8821A=m +CONFIG_RTW88_8812A=m # CONFIG_RTW88_8822BE is not set # CONFIG_RTW88_8822BS is not set CONFIG_RTW88_8822BU=m @@ -2531,6 +2535,8 @@ CONFIG_RTW88_8723DU=m # CONFIG_RTW88_8821CE is not set # CONFIG_RTW88_8821CS is not set CONFIG_RTW88_8821CU=m +CONFIG_RTW88_8821AU=m +CONFIG_RTW88_8812AU=m # CONFIG_RTW88_DEBUG is not set # CONFIG_RTW88_DEBUGFS is not set # CONFIG_RTW89 is not set diff --git a/projects/RPi/devices/RPi5/linux/linux.aarch64.conf b/projects/RPi/devices/RPi5/linux/linux.aarch64.conf index 01d35eec55..e08e01dfe7 100644 --- a/projects/RPi/devices/RPi5/linux/linux.aarch64.conf +++ b/projects/RPi/devices/RPi5/linux/linux.aarch64.conf @@ -2526,8 +2526,12 @@ CONFIG_RTW88_CORE=m CONFIG_RTW88_USB=m CONFIG_RTW88_8822B=m CONFIG_RTW88_8822C=m +CONFIG_RTW88_8723X=m CONFIG_RTW88_8723D=m CONFIG_RTW88_8821C=m +CONFIG_RTW88_88XXA=m +CONFIG_RTW88_8821A=m +CONFIG_RTW88_8812A=m # CONFIG_RTW88_8822BE is not set # CONFIG_RTW88_8822BS is not set CONFIG_RTW88_8822BU=m @@ -2540,6 +2544,8 @@ CONFIG_RTW88_8723DU=m # CONFIG_RTW88_8821CE is not set # CONFIG_RTW88_8821CS is not set CONFIG_RTW88_8821CU=m +CONFIG_RTW88_8821AU=m +CONFIG_RTW88_8812AU=m # CONFIG_RTW88_DEBUG is not set # CONFIG_RTW88_DEBUGFS is not set # CONFIG_RTW89 is not set diff --git a/projects/Rockchip/devices/RK3288/linux/default/linux.arm.conf b/projects/Rockchip/devices/RK3288/linux/default/linux.arm.conf index a5732ab12b..e8ea70100e 100644 --- a/projects/Rockchip/devices/RK3288/linux/default/linux.arm.conf +++ b/projects/Rockchip/devices/RK3288/linux/default/linux.arm.conf @@ -2227,6 +2227,9 @@ CONFIG_RTW88_8822C=m CONFIG_RTW88_8723X=m CONFIG_RTW88_8723D=m CONFIG_RTW88_8821C=m +CONFIG_RTW88_88XXA=m +CONFIG_RTW88_8821A=m +CONFIG_RTW88_8812A=m # CONFIG_RTW88_8822BS is not set CONFIG_RTW88_8822BU=m # CONFIG_RTW88_8822CS is not set @@ -2236,6 +2239,8 @@ CONFIG_RTW88_8822CU=m CONFIG_RTW88_8723DU=m # CONFIG_RTW88_8821CS is not set CONFIG_RTW88_8821CU=m +CONFIG_RTW88_8821AU=m +CONFIG_RTW88_8812AU=m # CONFIG_RTW88_DEBUG is not set # CONFIG_RTW88_DEBUGFS is not set # CONFIG_RTW89 is not set diff --git a/projects/Rockchip/devices/RK3328/linux/default/linux.aarch64.conf b/projects/Rockchip/devices/RK3328/linux/default/linux.aarch64.conf index e8a6a6ac98..596a1a57cb 100644 --- a/projects/Rockchip/devices/RK3328/linux/default/linux.aarch64.conf +++ b/projects/Rockchip/devices/RK3328/linux/default/linux.aarch64.conf @@ -2257,6 +2257,9 @@ CONFIG_RTW88_8822C=m CONFIG_RTW88_8723X=m CONFIG_RTW88_8723D=m CONFIG_RTW88_8821C=m +CONFIG_RTW88_88XXA=m +CONFIG_RTW88_8821A=m +CONFIG_RTW88_8812A=m # CONFIG_RTW88_8822BS is not set CONFIG_RTW88_8822BU=m # CONFIG_RTW88_8822CS is not set @@ -2266,6 +2269,8 @@ CONFIG_RTW88_8822CU=m CONFIG_RTW88_8723DU=m # CONFIG_RTW88_8821CS is not set CONFIG_RTW88_8821CU=m +CONFIG_RTW88_8821AU=m +CONFIG_RTW88_8812AU=m # CONFIG_RTW88_DEBUG is not set # CONFIG_RTW88_DEBUGFS is not set # CONFIG_RTW89 is not set diff --git a/projects/Rockchip/devices/RK3399/linux/default/linux.aarch64.conf b/projects/Rockchip/devices/RK3399/linux/default/linux.aarch64.conf index 3724fbf8aa..3f8b8b7e35 100644 --- a/projects/Rockchip/devices/RK3399/linux/default/linux.aarch64.conf +++ b/projects/Rockchip/devices/RK3399/linux/default/linux.aarch64.conf @@ -2656,6 +2656,9 @@ CONFIG_RTW88_8822C=m CONFIG_RTW88_8723X=m CONFIG_RTW88_8723D=m CONFIG_RTW88_8821C=m +CONFIG_RTW88_88XXA=m +CONFIG_RTW88_8821A=m +CONFIG_RTW88_8812A=m CONFIG_RTW88_8822BE=m # CONFIG_RTW88_8822BS is not set CONFIG_RTW88_8822BU=m @@ -2669,6 +2672,8 @@ CONFIG_RTW88_8723DU=m CONFIG_RTW88_8821CE=m # CONFIG_RTW88_8821CS is not set CONFIG_RTW88_8821CU=m +CONFIG_RTW88_8821AU=m +CONFIG_RTW88_8812AU=m # CONFIG_RTW88_DEBUG is not set # CONFIG_RTW88_DEBUGFS is not set # CONFIG_RTW89 is not set diff --git a/projects/Samsung/linux/linux.arm.conf b/projects/Samsung/linux/linux.arm.conf index 7aacc7135c..178ab1b77e 100644 --- a/projects/Samsung/linux/linux.arm.conf +++ b/projects/Samsung/linux/linux.arm.conf @@ -2017,6 +2017,9 @@ CONFIG_RTW88_8822C=m CONFIG_RTW88_8723X=m CONFIG_RTW88_8723D=m CONFIG_RTW88_8821C=m +CONFIG_RTW88_88XXA=m +CONFIG_RTW88_8821A=m +CONFIG_RTW88_8812A=m # CONFIG_RTW88_8822BS is not set CONFIG_RTW88_8822BU=m # CONFIG_RTW88_8822CS is not set @@ -2026,6 +2029,8 @@ CONFIG_RTW88_8822CU=m CONFIG_RTW88_8723DU=m # CONFIG_RTW88_8821CS is not set CONFIG_RTW88_8821CU=m +CONFIG_RTW88_8821AU=m +CONFIG_RTW88_8812AU=m # CONFIG_RTW88_DEBUG is not set # CONFIG_RTW88_DEBUGFS is not set # CONFIG_RTW89 is not set From 8cd86853eac7049650822c86871cfbc2bdc917ff Mon Sep 17 00:00:00 2001 From: Rudi Heitbaum Date: Sun, 13 Oct 2024 13:56:47 +0000 Subject: [PATCH 3/5] distro: drop RTL8812AU as now in-kernel --- distributions/LibreELEC/options | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/distributions/LibreELEC/options b/distributions/LibreELEC/options index 33002f49c9..e67a751713 100644 --- a/distributions/LibreELEC/options +++ b/distributions/LibreELEC/options @@ -64,7 +64,7 @@ # for a list of additional drivers see packages/linux-drivers # Space separated list is supported, # e.g. ADDITIONAL_DRIVERS="DRIVER1 DRIVER2" - ADDITIONAL_DRIVERS="RTL8812AU" + ADDITIONAL_DRIVERS="" # Default size of system partition, in MB, eg. 512 SYSTEM_SIZE=512 From 476bfc4e0199b1631a5d63b577a87239936658fa Mon Sep 17 00:00:00 2001 From: Rudi Heitbaum Date: Sun, 13 Oct 2024 13:58:43 +0000 Subject: [PATCH 4/5] RTL8812AU: drop package --- packages/linux-drivers/RTL8812AU/package.mk | 29 --------------------- 1 file changed, 29 deletions(-) delete mode 100644 packages/linux-drivers/RTL8812AU/package.mk diff --git a/packages/linux-drivers/RTL8812AU/package.mk b/packages/linux-drivers/RTL8812AU/package.mk deleted file mode 100644 index 077d832f0e..0000000000 --- a/packages/linux-drivers/RTL8812AU/package.mk +++ /dev/null @@ -1,29 +0,0 @@ -# SPDX-License-Identifier: GPL-2.0-or-later -# Copyright (C) 2009-2016 Stephan Raue (stephan@openelec.tv) -# Copyright (C) 2018-present Team LibreELEC (https://libreelec.tv) - -PKG_NAME="RTL8812AU" -PKG_VERSION="63cf0b4584aa8878b0fe8ab38017f31c319bde3d" -PKG_SHA256="b4056ffd11707f9be3fd3ac2c9215c9d4315edac7a592790bb69fbb50ec49340" -PKG_LICENSE="GPL" -PKG_SITE="https://github.com/aircrack-ng/rtl8812au" -PKG_URL="https://github.com/aircrack-ng/rtl8812au/archive/${PKG_VERSION}.tar.gz" -PKG_LONGDESC="Realtek RTL8812AU Linux driver" -PKG_IS_KERNEL_PKG="yes" - -pre_make_target() { - unset LDFLAGS -} - -make_target() { - make V=1 \ - ARCH=${TARGET_KERNEL_ARCH} \ - KSRC=$(kernel_path) \ - CROSS_COMPILE=${TARGET_KERNEL_PREFIX} \ - CONFIG_POWER_SAVING=n -} - -makeinstall_target() { - mkdir -p ${INSTALL}/$(get_full_module_dir)/${PKG_NAME} - cp *.ko ${INSTALL}/$(get_full_module_dir)/${PKG_NAME} -} From 42435953f61ad35e870b64ef1a2cb5db7f890974 Mon Sep 17 00:00:00 2001 From: Rudi Heitbaum Date: Sat, 19 Oct 2024 12:32:06 +0000 Subject: [PATCH 5/5] linux: wifi: rtw88: drop patch backported to 6.6.57 and 6.11.4 --- ...w88-8703b-Fix-reported-RX-band-width.patch | 36 ------------------- 1 file changed, 36 deletions(-) delete mode 100644 packages/linux/patches/rtlwifi/6.12/0002-6.12-wifi-rtw88-8703b-Fix-reported-RX-band-width.patch diff --git a/packages/linux/patches/rtlwifi/6.12/0002-6.12-wifi-rtw88-8703b-Fix-reported-RX-band-width.patch b/packages/linux/patches/rtlwifi/6.12/0002-6.12-wifi-rtw88-8703b-Fix-reported-RX-band-width.patch deleted file mode 100644 index e369a89285..0000000000 --- a/packages/linux/patches/rtlwifi/6.12/0002-6.12-wifi-rtw88-8703b-Fix-reported-RX-band-width.patch +++ /dev/null @@ -1,36 +0,0 @@ -From aefa7a3a7cbe6c7de08fd7a7447c797a97c2e0cf Mon Sep 17 00:00:00 2001 -From: Bitterblue Smith -Date: Tue, 23 Jul 2024 22:32:59 +0300 -Subject: [PATCH 2/7] wifi: rtw88: 8703b: Fix reported RX band width - -The definition of GET_RX_DESC_BW is incorrect. Fix it according to the -GET_RX_STATUS_DESC_BW_8703B macro from the official driver. - -Tested only with RTL8812AU, which uses the same bits. - -Cc: stable@vger.kernel.org -Fixes: 9bb762b3a957 ("wifi: rtw88: Add definitions for 8703b chip") -Signed-off-by: Bitterblue Smith -Tested-by: Fiona Klute -Signed-off-by: Ping-Ke Shih -Link: https://patch.msgid.link/1cfed9d5-4304-4b96-84c5-c347f59fedb9@gmail.com ---- - drivers/net/wireless/realtek/rtw88/rx.h | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/drivers/net/wireless/realtek/rtw88/rx.h b/drivers/net/wireless/realtek/rtw88/rx.h -index d3668c4efc24..8a072dd3d73c 100644 ---- a/drivers/net/wireless/realtek/rtw88/rx.h -+++ b/drivers/net/wireless/realtek/rtw88/rx.h -@@ -41,7 +41,7 @@ enum rtw_rx_desc_enc { - #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(31, 24))) -+ (le32_get_bits(*((__le32 *)(rxdesc) + 0x04), GENMASK(5, 4))) - - void rtw_rx_stats(struct rtw_dev *rtwdev, struct ieee80211_vif *vif, - struct sk_buff *skb); --- -2.43.0 -