Path: blob/master/drivers/net/wireless/realtek/rtw88/rtw8812a.c
25924 views
// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause1/* Copyright(c) 2024 Realtek Corporation2*/34#include "main.h"5#include "coex.h"6#include "phy.h"7#include "reg.h"8#include "rtw88xxa.h"9#include "rtw8812a.h"10#include "rtw8812a_table.h"11#include "tx.h"1213static void rtw8812a_power_off(struct rtw_dev *rtwdev)14{15rtw88xxa_power_off(rtwdev, enter_lps_flow_8812a);16}1718static s8 rtw8812a_cck_rx_pwr(u8 lna_idx, u8 vga_idx)19{20s8 rx_pwr_all = 0;2122switch (lna_idx) {23case 7:24if (vga_idx <= 27)25rx_pwr_all = -94 + 2 * (27 - vga_idx);26else27rx_pwr_all = -94;28break;29case 6:30rx_pwr_all = -42 + 2 * (2 - vga_idx);31break;32case 5:33rx_pwr_all = -36 + 2 * (7 - vga_idx);34break;35case 4:36rx_pwr_all = -30 + 2 * (7 - vga_idx);37break;38case 3:39rx_pwr_all = -18 + 2 * (7 - vga_idx);40break;41case 2:42rx_pwr_all = 2 * (5 - vga_idx);43break;44case 1:45rx_pwr_all = 14 - 2 * vga_idx;46break;47case 0:48rx_pwr_all = 20 - 2 * vga_idx;49break;50default:51break;52}5354return rx_pwr_all;55}5657static void rtw8812a_query_phy_status(struct rtw_dev *rtwdev, u8 *phy_status,58struct rtw_rx_pkt_stat *pkt_stat)59{60rtw88xxa_query_phy_status(rtwdev, phy_status, pkt_stat,61rtw8812a_cck_rx_pwr);6263if (pkt_stat->rate >= DESC_RATE6M)64return;6566if (rtwdev->hal.cck_high_power)67return;6869if (pkt_stat->rssi >= 80)70pkt_stat->rssi = ((pkt_stat->rssi - 80) << 1) +71((pkt_stat->rssi - 80) >> 1) + 80;72else if (pkt_stat->rssi <= 78 && pkt_stat->rssi >= 20)73pkt_stat->rssi += 3;74}7576static void rtw8812a_cfg_ldo25(struct rtw_dev *rtwdev, bool enable)77{78}7980static void rtw8812a_do_lck(struct rtw_dev *rtwdev)81{82u32 cont_tx, lc_cal, i;8384cont_tx = rtw_read32_mask(rtwdev, REG_SINGLE_TONE_CONT_TX, 0x70000);8586lc_cal = rtw_read_rf(rtwdev, RF_PATH_A, RF_CFGCH, RFREG_MASK);8788if (!cont_tx)89rtw_write8(rtwdev, REG_TXPAUSE, 0xff);9091rtw_write_rf(rtwdev, RF_PATH_A, RF_LCK, BIT(14), 1);9293rtw_write_rf(rtwdev, RF_PATH_A, RF_CFGCH, 0x08000, 1);9495mdelay(150);9697for (i = 0; i < 5; i++) {98if (rtw_read_rf(rtwdev, RF_PATH_A, RF_CFGCH, 0x08000) != 1)99break;100101mdelay(10);102}103104if (i == 5)105rtw_dbg(rtwdev, RTW_DBG_RFK, "LCK timed out\n");106107rtw_write_rf(rtwdev, RF_PATH_A, RF_CFGCH, RFREG_MASK, lc_cal);108109rtw_write_rf(rtwdev, RF_PATH_A, RF_LCK, BIT(14), 0);110111if (!cont_tx)112rtw_write8(rtwdev, REG_TXPAUSE, 0);113114rtw_write_rf(rtwdev, RF_PATH_A, RF_CFGCH, RFREG_MASK, lc_cal);115}116117static void rtw8812a_iqk_backup_rf(struct rtw_dev *rtwdev, u32 *rfa_backup,118u32 *rfb_backup, const u32 *backup_rf_reg,119u32 rf_num)120{121u32 i;122123/* [31] = 0 --> Page C */124rtw_write32_mask(rtwdev, REG_CCASEL, BIT(31), 0x0);125126/* Save RF Parameters */127for (i = 0; i < rf_num; i++) {128rfa_backup[i] = rtw_read_rf(rtwdev, RF_PATH_A,129backup_rf_reg[i], MASKDWORD);130rfb_backup[i] = rtw_read_rf(rtwdev, RF_PATH_B,131backup_rf_reg[i], MASKDWORD);132}133}134135static void rtw8812a_iqk_restore_rf(struct rtw_dev *rtwdev,136enum rtw_rf_path path,137const u32 *backup_rf_reg,138u32 *RF_backup, u32 rf_reg_num)139{140u32 i;141142/* [31] = 0 --> Page C */143rtw_write32_mask(rtwdev, REG_CCASEL, BIT(31), 0x0);144145for (i = 0; i < rf_reg_num; i++)146rtw_write_rf(rtwdev, path, backup_rf_reg[i],147RFREG_MASK, RF_backup[i]);148149rtw_write_rf(rtwdev, path, RF_LUTWE, RFREG_MASK, 0);150}151152static void rtw8812a_iqk_restore_afe(struct rtw_dev *rtwdev, u32 *afe_backup,153const u32 *backup_afe_reg, u32 afe_num)154{155u32 i;156157/* [31] = 0 --> Page C */158rtw_write32_mask(rtwdev, REG_CCASEL, BIT(31), 0x0);159160/* Reload AFE Parameters */161for (i = 0; i < afe_num; i++)162rtw_write32(rtwdev, backup_afe_reg[i], afe_backup[i]);163164/* [31] = 1 --> Page C1 */165rtw_write32_mask(rtwdev, REG_CCASEL, BIT(31), 0x1);166167rtw_write32(rtwdev, REG_OFDM0_XA_TX_IQ_IMBALANCE, 0x0);168rtw_write32(rtwdev, REG_OFDM0_A_TX_AFE, 0x0);169rtw_write32(rtwdev, REG_OFDM0_XB_TX_IQ_IMBALANCE, 0x0);170rtw_write32(rtwdev, REG_TSSI_TRK_SW, 0x3c000000);171rtw_write32_mask(rtwdev, REG_LSSI_WRITE_A, BIT(7), 1);172rtw_write32_mask(rtwdev, REG_IQK_DPD_CFG, BIT(18), 1);173rtw_write32_mask(rtwdev, REG_IQK_DPD_CFG, BIT(29), 1);174rtw_write32_mask(rtwdev, REG_CFG_PMPD, BIT(29), 1);175176rtw_write32(rtwdev, REG_TXTONEB, 0x0);177rtw_write32(rtwdev, REG_RXTONEB, 0x0);178rtw_write32(rtwdev, REG_TXPITMB, 0x0);179rtw_write32(rtwdev, REG_RXPITMB, 0x3c000000);180rtw_write32_mask(rtwdev, REG_LSSI_WRITE_B, BIT(7), 1);181rtw_write32_mask(rtwdev, REG_BPBDB, BIT(18), 1);182rtw_write32_mask(rtwdev, REG_BPBDB, BIT(29), 1);183rtw_write32_mask(rtwdev, REG_PHYTXONB, BIT(29), 1);184}185186static void rtw8812a_iqk_rx_fill(struct rtw_dev *rtwdev, enum rtw_rf_path path,187unsigned int rx_x, unsigned int rx_y)188{189switch (path) {190case RF_PATH_A:191/* [31] = 0 --> Page C */192rtw_write32_mask(rtwdev, REG_CCASEL, BIT(31), 0x0);193if (rx_x >> 1 >= 0x112 ||194(rx_y >> 1 >= 0x12 && rx_y >> 1 <= 0x3ee)) {195rtw_write32_mask(rtwdev, REG_RX_IQC_AB_A,1960x000003ff, 0x100);197rtw_write32_mask(rtwdev, REG_RX_IQC_AB_A,1980x03ff0000, 0);199} else {200rtw_write32_mask(rtwdev, REG_RX_IQC_AB_A,2010x000003ff, rx_x >> 1);202rtw_write32_mask(rtwdev, REG_RX_IQC_AB_A,2030x03ff0000, rx_y >> 1);204}205rtw_dbg(rtwdev, RTW_DBG_RFK,206"rx_x = %x;;rx_y = %x ====>fill to IQC\n",207rx_x >> 1 & 0x000003ff, rx_y >> 1 & 0x000003ff);208rtw_dbg(rtwdev, RTW_DBG_RFK, "0xc10 = %x ====>fill to IQC\n",209rtw_read32(rtwdev, REG_RX_IQC_AB_A));210break;211case RF_PATH_B:212/* [31] = 0 --> Page C */213rtw_write32_mask(rtwdev, REG_CCASEL, BIT(31), 0x0);214if (rx_x >> 1 >= 0x112 ||215(rx_y >> 1 >= 0x12 && rx_y >> 1 <= 0x3ee)) {216rtw_write32_mask(rtwdev, REG_RX_IQC_AB_B,2170x000003ff, 0x100);218rtw_write32_mask(rtwdev, REG_RX_IQC_AB_B,2190x03ff0000, 0);220} else {221rtw_write32_mask(rtwdev, REG_RX_IQC_AB_B,2220x000003ff, rx_x >> 1);223rtw_write32_mask(rtwdev, REG_RX_IQC_AB_B,2240x03ff0000, rx_y >> 1);225}226rtw_dbg(rtwdev, RTW_DBG_RFK,227"rx_x = %x;;rx_y = %x ====>fill to IQC\n",228rx_x >> 1 & 0x000003ff, rx_y >> 1 & 0x000003ff);229rtw_dbg(rtwdev, RTW_DBG_RFK, "0xe10 = %x====>fill to IQC\n",230rtw_read32(rtwdev, REG_RX_IQC_AB_B));231break;232default:233break;234}235}236237static void rtw8812a_iqk_tx_fill(struct rtw_dev *rtwdev, enum rtw_rf_path path,238unsigned int tx_x, unsigned int tx_y)239{240switch (path) {241case RF_PATH_A:242/* [31] = 1 --> Page C1 */243rtw_write32_mask(rtwdev, REG_CCASEL, BIT(31), 0x1);244rtw_write32_mask(rtwdev, REG_PREDISTA, BIT(7), 0x1);245rtw_write32_mask(rtwdev, REG_IQK_DPD_CFG, BIT(18), 0x1);246rtw_write32_mask(rtwdev, REG_IQK_DPD_CFG, BIT(29), 0x1);247rtw_write32_mask(rtwdev, REG_CFG_PMPD, BIT(29), 0x1);248rtw_write32_mask(rtwdev, REG_IQC_Y, 0x000007ff, tx_y);249rtw_write32_mask(rtwdev, REG_IQC_X, 0x000007ff, tx_x);250rtw_dbg(rtwdev, RTW_DBG_RFK,251"tx_x = %x;;tx_y = %x =====> fill to IQC\n",252tx_x & 0x000007ff, tx_y & 0x000007ff);253rtw_dbg(rtwdev, RTW_DBG_RFK,254"0xcd4 = %x;;0xccc = %x ====>fill to IQC\n",255rtw_read32_mask(rtwdev, REG_IQC_X, 0x000007ff),256rtw_read32_mask(rtwdev, REG_IQC_Y, 0x000007ff));257break;258case RF_PATH_B:259/* [31] = 1 --> Page C1 */260rtw_write32_mask(rtwdev, REG_CCASEL, BIT(31), 0x1);261rtw_write32_mask(rtwdev, REG_PREDISTB, BIT(7), 0x1);262rtw_write32_mask(rtwdev, REG_BPBDB, BIT(18), 0x1);263rtw_write32_mask(rtwdev, REG_BPBDB, BIT(29), 0x1);264rtw_write32_mask(rtwdev, REG_PHYTXONB, BIT(29), 0x1);265rtw_write32_mask(rtwdev, REG_IQKYB, 0x000007ff, tx_y);266rtw_write32_mask(rtwdev, REG_IQKXB, 0x000007ff, tx_x);267rtw_dbg(rtwdev, RTW_DBG_RFK,268"tx_x = %x;;tx_y = %x =====> fill to IQC\n",269tx_x & 0x000007ff, tx_y & 0x000007ff);270rtw_dbg(rtwdev, RTW_DBG_RFK,271"0xed4 = %x;;0xecc = %x ====>fill to IQC\n",272rtw_read32_mask(rtwdev, REG_IQKXB, 0x000007ff),273rtw_read32_mask(rtwdev, REG_IQKYB, 0x000007ff));274break;275default:276break;277}278}279280static void rtw8812a_iqk(struct rtw_dev *rtwdev)281{282int tx_x0_temp[10], tx_y0_temp[10], tx_x1_temp[10], tx_y1_temp[10];283int rx_x0_temp[10], rx_y0_temp[10], rx_x1_temp[10], rx_y1_temp[10];284bool iqk0_ready = false, tx0_finish = false, rx0_finish = false;285bool iqk1_ready = false, tx1_finish = false, rx1_finish = false;286u8 tx0_avg = 0, tx1_avg = 0, rx0_avg = 0, rx1_avg = 0;287int tx_x0 = 0, tx_y0 = 0, tx_x1 = 0, tx_y1 = 0;288int rx_x0 = 0, rx_y0 = 0, rx_x1 = 0, rx_y1 = 0;289struct rtw_efuse *efuse = &rtwdev->efuse;290bool tx0_fail = true, rx0_fail = true;291bool tx1_fail = true, rx1_fail = true;292u8 cal0_retry, cal1_retry;293u8 delay_count;294295/* [31] = 0 --> Page C */296rtw_write32_mask(rtwdev, REG_CCASEL, BIT(31), 0x0);297298/* ========path-A AFE all on======== */299/* Port 0 DAC/ADC on */300rtw_write32(rtwdev, REG_AFE_PWR1_A, 0x77777777);301rtw_write32(rtwdev, REG_AFE_PWR2_A, 0x77777777);302303/* Port 1 DAC/ADC on */304rtw_write32(rtwdev, REG_AFE_PWR1_B, 0x77777777);305rtw_write32(rtwdev, REG_AFE_PWR2_B, 0x77777777);306307rtw_write32(rtwdev, REG_RX_WAIT_CCA_TX_CCK_RFON_A, 0x19791979);308rtw_write32(rtwdev, REG_RX_WAIT_CCA_TX_CCK_RFON_B, 0x19791979);309310/* hardware 3-wire off */311rtw_write32_mask(rtwdev, REG_3WIRE_SWA, 0xf, 0x4);312rtw_write32_mask(rtwdev, REG_3WIRE_SWB, 0xf, 0x4);313314/* DAC/ADC sampling rate (160 MHz) */315rtw_write32_mask(rtwdev, REG_CK_MONHA, GENMASK(26, 24), 0x7);316rtw_write32_mask(rtwdev, REG_CK_MONHB, GENMASK(26, 24), 0x7);317318/* [31] = 0 --> Page C */319rtw_write32_mask(rtwdev, REG_CCASEL, BIT(31), 0x0);320/* ====== path A TX IQK RF setting ====== */321rtw_write_rf(rtwdev, RF_PATH_A, RF_LUTWE, RFREG_MASK, 0x80002);322rtw_write_rf(rtwdev, RF_PATH_A, RF_MODE_TABLE_ADDR, RFREG_MASK, 0x20000);323rtw_write_rf(rtwdev, RF_PATH_A, RF_MODE_TABLE_DATA0, RFREG_MASK, 0x3fffd);324rtw_write_rf(rtwdev, RF_PATH_A, RF_MODE_TABLE_DATA1, RFREG_MASK, 0xfe83f);325rtw_write_rf(rtwdev, RF_PATH_A, RF_TXA_PREPAD, RFREG_MASK, 0x931d5);326rtw_write_rf(rtwdev, RF_PATH_A, RF_RXBB2, RFREG_MASK, 0x8a001);327328/* ====== path B TX IQK RF setting ====== */329rtw_write_rf(rtwdev, RF_PATH_B, RF_LUTWE, RFREG_MASK, 0x80002);330rtw_write_rf(rtwdev, RF_PATH_B, RF_MODE_TABLE_ADDR, RFREG_MASK, 0x20000);331rtw_write_rf(rtwdev, RF_PATH_B, RF_MODE_TABLE_DATA0, RFREG_MASK, 0x3fffd);332rtw_write_rf(rtwdev, RF_PATH_B, RF_MODE_TABLE_DATA1, RFREG_MASK, 0xfe83f);333rtw_write_rf(rtwdev, RF_PATH_B, RF_TXA_PREPAD, RFREG_MASK, 0x931d5);334rtw_write_rf(rtwdev, RF_PATH_B, RF_RXBB2, RFREG_MASK, 0x8a001);335336rtw_write32(rtwdev, REG_DAC_RSTB, 0x00008000);337rtw_write32_mask(rtwdev, REG_TXAGCIDX, BIT(0), 0x1);338rtw_write32_mask(rtwdev, REG_INIDLYB, BIT(0), 0x1);339rtw_write32(rtwdev, REG_IQK_COM00, 0x29002000); /* TX (X,Y) */340rtw_write32(rtwdev, REG_IQK_COM32, 0xa9002000); /* RX (X,Y) */341rtw_write32(rtwdev, REG_IQK_COM96, 0x00462910); /* [0]:AGC_en, [15]:idac_K_Mask */342/* [31] = 1 --> Page C1 */343rtw_write32_mask(rtwdev, REG_CCASEL, BIT(31), 0x1);344345if (efuse->ext_pa_5g) {346if (efuse->rfe_option == 1) {347rtw_write32(rtwdev, REG_OFDM0_XB_TX_IQ_IMBALANCE, 0x821403e3);348rtw_write32(rtwdev, REG_TXPITMB, 0x821403e3);349} else {350rtw_write32(rtwdev, REG_OFDM0_XB_TX_IQ_IMBALANCE, 0x821403f7);351rtw_write32(rtwdev, REG_TXPITMB, 0x821403f7);352}353} else {354rtw_write32(rtwdev, REG_OFDM0_XB_TX_IQ_IMBALANCE, 0x821403f1);355rtw_write32(rtwdev, REG_TXPITMB, 0x821403f1);356}357358if (rtwdev->hal.current_band_type == RTW_BAND_5G) {359rtw_write32(rtwdev, REG_TSSI_TRK_SW, 0x68163e96);360rtw_write32(rtwdev, REG_RXPITMB, 0x68163e96);361} else {362rtw_write32(rtwdev, REG_TSSI_TRK_SW, 0x28163e96);363rtw_write32(rtwdev, REG_RXPITMB, 0x28163e96);364365if (efuse->rfe_option == 3) {366if (efuse->ext_pa_2g)367rtw_write32(rtwdev, REG_OFDM0_XB_TX_IQ_IMBALANCE,3680x821403e3);369else370rtw_write32(rtwdev, REG_OFDM0_XB_TX_IQ_IMBALANCE,3710x821403f7);372}373}374375/* TX_Tone_idx[9:0], TxK_Mask[29] TX_Tone = 16 */376rtw_write32(rtwdev, REG_OFDM0_XA_TX_IQ_IMBALANCE, 0x18008c10);377/* RX_Tone_idx[9:0], RxK_Mask[29] */378rtw_write32(rtwdev, REG_OFDM0_A_TX_AFE, 0x38008c10);379rtw_write32(rtwdev, REG_INTPO_SETA, 0x00000000);380/* TX_Tone_idx[9:0], TxK_Mask[29] TX_Tone = 16 */381rtw_write32(rtwdev, REG_TXTONEB, 0x18008c10);382/* RX_Tone_idx[9:0], RxK_Mask[29] */383rtw_write32(rtwdev, REG_RXTONEB, 0x38008c10);384rtw_write32(rtwdev, REG_INTPO_SETB, 0x00000000);385386cal0_retry = 0;387cal1_retry = 0;388while (1) {389/* one shot */390rtw_write32(rtwdev, REG_RFECTL_A, 0x00100000);391rtw_write32(rtwdev, REG_RFECTL_B, 0x00100000);392rtw_write32(rtwdev, REG_IQK_COM64, 0xfa000000);393rtw_write32(rtwdev, REG_IQK_COM64, 0xf8000000);394395mdelay(10);396397rtw_write32(rtwdev, REG_RFECTL_A, 0x00000000);398rtw_write32(rtwdev, REG_RFECTL_B, 0x00000000);399400for (delay_count = 0; delay_count < 20; delay_count++) {401if (!tx0_finish)402iqk0_ready = rtw_read32_mask(rtwdev,403REG_IQKA_END,404BIT(10));405if (!tx1_finish)406iqk1_ready = rtw_read32_mask(rtwdev,407REG_IQKB_END,408BIT(10));409if (iqk0_ready && iqk1_ready)410break;411412mdelay(1);413}414415rtw_dbg(rtwdev, RTW_DBG_RFK, "TX delay_count = %d\n",416delay_count);417418if (delay_count < 20) { /* If 20ms No Result, then cal_retry++ */419/* ============TXIQK Check============== */420tx0_fail = rtw_read32_mask(rtwdev, REG_IQKA_END, BIT(12));421tx1_fail = rtw_read32_mask(rtwdev, REG_IQKB_END, BIT(12));422423if (!(tx0_fail || tx0_finish)) {424rtw_write32(rtwdev, REG_RFECTL_A, 0x02000000);425tx_x0_temp[tx0_avg] = rtw_read32_mask(rtwdev,426REG_IQKA_END,4270x07ff0000);428rtw_write32(rtwdev, REG_RFECTL_A, 0x04000000);429tx_y0_temp[tx0_avg] = rtw_read32_mask(rtwdev,430REG_IQKA_END,4310x07ff0000);432433rtw_dbg(rtwdev, RTW_DBG_RFK,434"tx_x0[%d] = %x ;; tx_y0[%d] = %x\n",435tx0_avg, tx_x0_temp[tx0_avg],436tx0_avg, tx_y0_temp[tx0_avg]);437438tx_x0_temp[tx0_avg] <<= 21;439tx_y0_temp[tx0_avg] <<= 21;440441tx0_avg++;442} else {443cal0_retry++;444if (cal0_retry == 10)445break;446}447448if (!(tx1_fail || tx1_finish)) {449rtw_write32(rtwdev, REG_RFECTL_B, 0x02000000);450tx_x1_temp[tx1_avg] = rtw_read32_mask(rtwdev,451REG_IQKB_END,4520x07ff0000);453rtw_write32(rtwdev, REG_RFECTL_B, 0x04000000);454tx_y1_temp[tx1_avg] = rtw_read32_mask(rtwdev,455REG_IQKB_END,4560x07ff0000);457458rtw_dbg(rtwdev, RTW_DBG_RFK,459"tx_x1[%d] = %x ;; tx_y1[%d] = %x\n",460tx1_avg, tx_x1_temp[tx1_avg],461tx1_avg, tx_y1_temp[tx1_avg]);462463tx_x1_temp[tx1_avg] <<= 21;464tx_y1_temp[tx1_avg] <<= 21;465466tx1_avg++;467} else {468cal1_retry++;469if (cal1_retry == 10)470break;471}472} else {473cal0_retry++;474cal1_retry++;475476rtw_dbg(rtwdev, RTW_DBG_RFK,477"delay 20ms TX IQK Not Ready!!!!!\n");478479if (cal0_retry == 10)480break;481}482483if (tx0_avg >= 2)484tx0_finish = rtw88xxa_iqk_finish(tx0_avg, 4,485tx_x0_temp, tx_y0_temp, &tx_x0, &tx_y0,486false, false);487488if (tx1_avg >= 2)489tx1_finish = rtw88xxa_iqk_finish(tx1_avg, 4,490tx_x1_temp, tx_y1_temp, &tx_x1, &tx_y1,491false, false);492493rtw_dbg(rtwdev, RTW_DBG_RFK,494"tx0_average = %d, tx1_average = %d\n",495tx0_avg, tx1_avg);496rtw_dbg(rtwdev, RTW_DBG_RFK,497"tx0_finish = %d, tx1_finish = %d\n",498tx0_finish, tx1_finish);499500if (tx0_finish && tx1_finish)501break;502503if ((cal0_retry + tx0_avg) >= 10 ||504(cal1_retry + tx1_avg) >= 10)505break;506}507508rtw_dbg(rtwdev, RTW_DBG_RFK, "TXA_cal_retry = %d\n", cal0_retry);509rtw_dbg(rtwdev, RTW_DBG_RFK, "TXB_cal_retry = %d\n", cal1_retry);510511/* [31] = 0 --> Page C */512rtw_write32_mask(rtwdev, REG_CCASEL, BIT(31), 0x0);513/* Load LOK */514rtw_write_rf(rtwdev, RF_PATH_A, RF_TXMOD, 0x7fe00,515rtw_read_rf(rtwdev, RF_PATH_A, RF_DTXLOK, 0xffc00));516rtw_write_rf(rtwdev, RF_PATH_B, RF_TXMOD, 0x7fe00,517rtw_read_rf(rtwdev, RF_PATH_B, RF_DTXLOK, 0xffc00));518/* [31] = 1 --> Page C1 */519rtw_write32_mask(rtwdev, REG_CCASEL, BIT(31), 0x1);520521/* [31] = 0 --> Page C */522rtw_write32_mask(rtwdev, REG_CCASEL, BIT(31), 0x0);523if (tx0_finish) {524/* ====== path A RX IQK RF setting====== */525rtw_write_rf(rtwdev, RF_PATH_A, RF_LUTWE, RFREG_MASK, 0x80000);526rtw_write_rf(rtwdev, RF_PATH_A, RF_MODE_TABLE_ADDR, RFREG_MASK,5270x30000);528rtw_write_rf(rtwdev, RF_PATH_A, RF_MODE_TABLE_DATA0, RFREG_MASK,5290x3f7ff);530rtw_write_rf(rtwdev, RF_PATH_A, RF_MODE_TABLE_DATA1, RFREG_MASK,5310xfe7bf);532rtw_write_rf(rtwdev, RF_PATH_A, RF_RXBB2, RFREG_MASK, 0x88001);533rtw_write_rf(rtwdev, RF_PATH_A, RF_TXA_PREPAD, RFREG_MASK, 0x931d1);534rtw_write_rf(rtwdev, RF_PATH_A, RF_LUTWE, RFREG_MASK, 0x00000);535}536if (tx1_finish) {537/* ====== path B RX IQK RF setting====== */538rtw_write_rf(rtwdev, RF_PATH_B, RF_LUTWE, RFREG_MASK, 0x80000);539rtw_write_rf(rtwdev, RF_PATH_B, RF_MODE_TABLE_ADDR, RFREG_MASK,5400x30000);541rtw_write_rf(rtwdev, RF_PATH_B, RF_MODE_TABLE_DATA0, RFREG_MASK,5420x3f7ff);543rtw_write_rf(rtwdev, RF_PATH_B, RF_MODE_TABLE_DATA1, RFREG_MASK,5440xfe7bf);545rtw_write_rf(rtwdev, RF_PATH_B, RF_RXBB2, RFREG_MASK, 0x88001);546rtw_write_rf(rtwdev, RF_PATH_B, RF_TXA_PREPAD, RFREG_MASK, 0x931d1);547rtw_write_rf(rtwdev, RF_PATH_B, RF_LUTWE, RFREG_MASK, 0x00000);548}549550rtw_write32_mask(rtwdev, REG_IQK_COM00, BIT(31), 0x1);551rtw_write32_mask(rtwdev, REG_IQK_COM00, BIT(31), 0x0);552rtw_write32(rtwdev, REG_DAC_RSTB, 0x00008000);553554if (rtwdev->hci.type == RTW_HCI_TYPE_PCIE)555rtw_write32(rtwdev, REG_IQK_COM96, 0x0046a911);556else557rtw_write32(rtwdev, REG_IQK_COM96, 0x0046a890);558559if (efuse->rfe_option == 1) {560rtw_write32(rtwdev, REG_RFE_PINMUX_A, 0x77777717);561rtw_write32(rtwdev, REG_RFE_INV_A, 0x00000077);562rtw_write32(rtwdev, REG_RFE_PINMUX_B, 0x77777717);563rtw_write32(rtwdev, REG_RFE_INV_B, 0x00000077);564} else {565rtw_write32(rtwdev, REG_RFE_PINMUX_A, 0x77777717);566rtw_write32(rtwdev, REG_RFE_INV_A, 0x02000077);567rtw_write32(rtwdev, REG_RFE_PINMUX_B, 0x77777717);568rtw_write32(rtwdev, REG_RFE_INV_B, 0x02000077);569}570571/* [31] = 1 --> Page C1 */572rtw_write32_mask(rtwdev, REG_CCASEL, BIT(31), 0x1);573574if (tx0_finish) {575/* TX_Tone_idx[9:0], TxK_Mask[29] TX_Tone = 16 */576rtw_write32(rtwdev, REG_OFDM0_XA_TX_IQ_IMBALANCE, 0x38008c10);577/* RX_Tone_idx[9:0], RxK_Mask[29] */578rtw_write32(rtwdev, REG_OFDM0_A_TX_AFE, 0x18008c10);579rtw_write32(rtwdev, REG_OFDM0_XB_TX_IQ_IMBALANCE, 0x82140119);580}581if (tx1_finish) {582/* TX_Tone_idx[9:0], TxK_Mask[29] TX_Tone = 16 */583rtw_write32(rtwdev, REG_TXTONEB, 0x38008c10);584/* RX_Tone_idx[9:0], RxK_Mask[29] */585rtw_write32(rtwdev, REG_RXTONEB, 0x18008c10);586rtw_write32(rtwdev, REG_TXPITMB, 0x82140119);587}588589cal0_retry = 0;590cal1_retry = 0;591while (1) {592/* one shot */593/* [31] = 0 --> Page C */594rtw_write32_mask(rtwdev, REG_CCASEL, BIT(31), 0x0);595596if (tx0_finish) {597rtw_write32_mask(rtwdev, REG_IQK_COM00, 0x03FF8000,598tx_x0 & 0x000007ff);599rtw_write32_mask(rtwdev, REG_IQK_COM00, 0x000007FF,600tx_y0 & 0x000007ff);601/* [31] = 1 --> Page C1 */602rtw_write32_mask(rtwdev, REG_CCASEL, BIT(31), 0x1);603if (efuse->rfe_option == 1)604rtw_write32(rtwdev, REG_TSSI_TRK_SW, 0x28161500);605else606rtw_write32(rtwdev, REG_TSSI_TRK_SW, 0x28160cc0);607rtw_write32(rtwdev, REG_RFECTL_A, 0x00300000);608rtw_write32(rtwdev, REG_RFECTL_A, 0x00100000);609mdelay(5);610rtw_write32(rtwdev, REG_TSSI_TRK_SW, 0x3c000000);611rtw_write32(rtwdev, REG_RFECTL_A, 0x00000000);612}613614if (tx1_finish) {615/* [31] = 0 --> Page C */616rtw_write32_mask(rtwdev, REG_CCASEL, BIT(31), 0x0);617rtw_write32_mask(rtwdev, REG_IQK_COM00, 0x03FF8000,618tx_x1 & 0x000007ff);619rtw_write32_mask(rtwdev, REG_IQK_COM00, 0x000007FF,620tx_y1 & 0x000007ff);621/* [31] = 1 --> Page C1 */622rtw_write32_mask(rtwdev, REG_CCASEL, BIT(31), 0x1);623if (efuse->rfe_option == 1)624rtw_write32(rtwdev, REG_RXPITMB, 0x28161500);625else626rtw_write32(rtwdev, REG_RXPITMB, 0x28160ca0);627rtw_write32(rtwdev, REG_RFECTL_B, 0x00300000);628rtw_write32(rtwdev, REG_RFECTL_B, 0x00100000);629mdelay(5);630rtw_write32(rtwdev, REG_RXPITMB, 0x3c000000);631rtw_write32(rtwdev, REG_RFECTL_B, 0x00000000);632}633634for (delay_count = 0; delay_count < 20; delay_count++) {635if (!rx0_finish && tx0_finish)636iqk0_ready = rtw_read32_mask(rtwdev,637REG_IQKA_END,638BIT(10));639if (!rx1_finish && tx1_finish)640iqk1_ready = rtw_read32_mask(rtwdev,641REG_IQKB_END,642BIT(10));643if (iqk0_ready && iqk1_ready)644break;645646mdelay(1);647}648649rtw_dbg(rtwdev, RTW_DBG_RFK, "RX delay_count = %d\n",650delay_count);651652if (delay_count < 20) { /* If 20ms No Result, then cal_retry++ */653/* ============RXIQK Check============== */654rx0_fail = rtw_read32_mask(rtwdev, REG_IQKA_END, BIT(11));655rx1_fail = rtw_read32_mask(rtwdev, REG_IQKB_END, BIT(11));656657if (!(rx0_fail || rx0_finish) && tx0_finish) {658rtw_write32(rtwdev, REG_RFECTL_A, 0x06000000);659rx_x0_temp[rx0_avg] = rtw_read32_mask(rtwdev,660REG_IQKA_END,6610x07ff0000);662rtw_write32(rtwdev, REG_RFECTL_A, 0x08000000);663rx_y0_temp[rx0_avg] = rtw_read32_mask(rtwdev,664REG_IQKA_END,6650x07ff0000);666667rtw_dbg(rtwdev, RTW_DBG_RFK,668"rx_x0[%d] = %x ;; rx_y0[%d] = %x\n",669rx0_avg, rx_x0_temp[rx0_avg],670rx0_avg, rx_y0_temp[rx0_avg]);671672rx_x0_temp[rx0_avg] <<= 21;673rx_y0_temp[rx0_avg] <<= 21;674675rx0_avg++;676} else {677rtw_dbg(rtwdev, RTW_DBG_RFK,678"1. RXA_cal_retry = %d\n", cal0_retry);679680cal0_retry++;681if (cal0_retry == 10)682break;683}684685if (!(rx1_fail || rx1_finish) && tx1_finish) {686rtw_write32(rtwdev, REG_RFECTL_B, 0x06000000);687rx_x1_temp[rx1_avg] = rtw_read32_mask(rtwdev,688REG_IQKB_END,6890x07ff0000);690rtw_write32(rtwdev, REG_RFECTL_B, 0x08000000);691rx_y1_temp[rx1_avg] = rtw_read32_mask(rtwdev,692REG_IQKB_END,6930x07ff0000);694695rtw_dbg(rtwdev, RTW_DBG_RFK,696"rx_x1[%d] = %x ;; rx_y1[%d] = %x\n",697rx1_avg, rx_x1_temp[rx1_avg],698rx1_avg, rx_y1_temp[rx1_avg]);699700rx_x1_temp[rx1_avg] <<= 21;701rx_y1_temp[rx1_avg] <<= 21;702703rx1_avg++;704} else {705cal1_retry++;706if (cal1_retry == 10)707break;708}709} else {710rtw_dbg(rtwdev, RTW_DBG_RFK,711"2. RXA_cal_retry = %d\n", cal0_retry);712713cal0_retry++;714cal1_retry++;715716rtw_dbg(rtwdev, RTW_DBG_RFK,717"delay 20ms RX IQK Not Ready!!!!!\n");718719if (cal0_retry == 10)720break;721}722723rtw_dbg(rtwdev, RTW_DBG_RFK, "3. RXA_cal_retry = %d\n",724cal0_retry);725726if (rx0_avg >= 2)727rx0_finish = rtw88xxa_iqk_finish(rx0_avg, 4,728rx_x0_temp, rx_y0_temp,729&rx_x0, &rx_y0,730true, false);731732if (rx1_avg >= 2)733rx1_finish = rtw88xxa_iqk_finish(rx1_avg, 4,734rx_x1_temp, rx_y1_temp,735&rx_x1, &rx_y1,736true, false);737738rtw_dbg(rtwdev, RTW_DBG_RFK,739"rx0_average = %d, rx1_average = %d\n",740rx0_avg, rx1_avg);741rtw_dbg(rtwdev, RTW_DBG_RFK,742"rx0_finish = %d, rx1_finish = %d\n",743rx0_finish, rx1_finish);744745if ((rx0_finish || !tx0_finish) && (rx1_finish || !tx1_finish))746break;747748if ((cal0_retry + rx0_avg) >= 10 ||749(cal1_retry + rx1_avg) >= 10 ||750rx0_avg == 3 || rx1_avg == 3)751break;752}753754rtw_dbg(rtwdev, RTW_DBG_RFK, "RXA_cal_retry = %d\n", cal0_retry);755rtw_dbg(rtwdev, RTW_DBG_RFK, "RXB_cal_retry = %d\n", cal1_retry);756757/* FillIQK Result */758rtw_dbg(rtwdev, RTW_DBG_RFK, "========Path_A =======\n");759760if (tx0_finish)761rtw8812a_iqk_tx_fill(rtwdev, RF_PATH_A, tx_x0, tx_y0);762else763rtw8812a_iqk_tx_fill(rtwdev, RF_PATH_A, 0x200, 0x0);764765if (rx0_finish)766rtw8812a_iqk_rx_fill(rtwdev, RF_PATH_A, rx_x0, rx_y0);767else768rtw8812a_iqk_rx_fill(rtwdev, RF_PATH_A, 0x200, 0x0);769770rtw_dbg(rtwdev, RTW_DBG_RFK, "========Path_B =======\n");771772if (tx1_finish)773rtw8812a_iqk_tx_fill(rtwdev, RF_PATH_B, tx_x1, tx_y1);774else775rtw8812a_iqk_tx_fill(rtwdev, RF_PATH_B, 0x200, 0x0);776777if (rx1_finish)778rtw8812a_iqk_rx_fill(rtwdev, RF_PATH_B, rx_x1, rx_y1);779else780rtw8812a_iqk_rx_fill(rtwdev, RF_PATH_B, 0x200, 0x0);781}782783#define MACBB_REG_NUM_8812A 9784#define AFE_REG_NUM_8812A 12785#define RF_REG_NUM_8812A 3786787static void rtw8812a_do_iqk(struct rtw_dev *rtwdev)788{789static const u32 backup_macbb_reg[MACBB_REG_NUM_8812A] = {7900x520, 0x550, 0x808, 0xa04, 0x90c, 0xc00, 0xe00, 0x838, 0x82c791};792static const u32 backup_afe_reg[AFE_REG_NUM_8812A] = {7930xc5c, 0xc60, 0xc64, 0xc68, 0xcb0, 0xcb4,7940xe5c, 0xe60, 0xe64, 0xe68, 0xeb0, 0xeb4795};796static const u32 backup_rf_reg[RF_REG_NUM_8812A] = {7970x65, 0x8f, 0x0798};799u32 macbb_backup[MACBB_REG_NUM_8812A] = {};800u32 afe_backup[AFE_REG_NUM_8812A] = {};801u32 rfa_backup[RF_REG_NUM_8812A] = {};802u32 rfb_backup[RF_REG_NUM_8812A] = {};803u32 reg_cb8, reg_eb8;804805rtw88xxa_iqk_backup_mac_bb(rtwdev, macbb_backup,806backup_macbb_reg, MACBB_REG_NUM_8812A);807808rtw_write32_set(rtwdev, REG_CCASEL, BIT(31));809reg_cb8 = rtw_read32(rtwdev, REG_RFECTL_A);810reg_eb8 = rtw_read32(rtwdev, REG_RFECTL_B);811rtw_write32_clr(rtwdev, REG_CCASEL, BIT(31));812813rtw88xxa_iqk_backup_afe(rtwdev, afe_backup,814backup_afe_reg, AFE_REG_NUM_8812A);815rtw8812a_iqk_backup_rf(rtwdev, rfa_backup, rfb_backup,816backup_rf_reg, RF_REG_NUM_8812A);817818rtw88xxa_iqk_configure_mac(rtwdev);819820rtw8812a_iqk(rtwdev);821822rtw8812a_iqk_restore_rf(rtwdev, RF_PATH_A, backup_rf_reg,823rfa_backup, RF_REG_NUM_8812A);824rtw8812a_iqk_restore_rf(rtwdev, RF_PATH_B, backup_rf_reg,825rfb_backup, RF_REG_NUM_8812A);826827rtw8812a_iqk_restore_afe(rtwdev, afe_backup,828backup_afe_reg, AFE_REG_NUM_8812A);829830rtw_write32_set(rtwdev, REG_CCASEL, BIT(31));831rtw_write32(rtwdev, REG_RFECTL_A, reg_cb8);832rtw_write32(rtwdev, REG_RFECTL_B, reg_eb8);833rtw_write32_clr(rtwdev, REG_CCASEL, BIT(31));834835rtw88xxa_iqk_restore_mac_bb(rtwdev, macbb_backup,836backup_macbb_reg, MACBB_REG_NUM_8812A);837}838839static void rtw8812a_phy_calibration(struct rtw_dev *rtwdev)840{841u8 channel = rtwdev->hal.current_channel;842843rtw8812a_do_iqk(rtwdev);844845/* The official driver wants to do this after connecting846* but before first writing a new igi (phydm_get_new_igi).847* Here seems close enough.848*/849if (channel >= 36 && channel <= 64)850rtw_load_table(rtwdev, &rtw8812a_agc_diff_lb_tbl);851else if (channel >= 100)852rtw_load_table(rtwdev, &rtw8812a_agc_diff_hb_tbl);853}854855static void rtw8812a_pwr_track(struct rtw_dev *rtwdev)856{857struct rtw_dm_info *dm_info = &rtwdev->dm_info;858859if (!dm_info->pwr_trk_triggered) {860rtw_write_rf(rtwdev, RF_PATH_A, RF_T_METER,861GENMASK(17, 16), 0x03);862dm_info->pwr_trk_triggered = true;863return;864}865866rtw88xxa_phy_pwrtrack(rtwdev, rtw8812a_do_lck, rtw8812a_do_iqk);867dm_info->pwr_trk_triggered = false;868}869870static void rtw8812a_led_set(struct led_classdev *led,871enum led_brightness brightness)872{873struct rtw_dev *rtwdev = container_of(led, struct rtw_dev, led_cdev);874u8 ledcfg;875876ledcfg = rtw_read8(rtwdev, REG_LED_CFG);877ledcfg &= BIT(6) | BIT(4);878ledcfg |= BIT(5);879880if (brightness == LED_OFF)881ledcfg |= BIT(3);882883rtw_write8(rtwdev, REG_LED_CFG, ledcfg);884}885886static void rtw8812a_fill_txdesc_checksum(struct rtw_dev *rtwdev,887struct rtw_tx_pkt_info *pkt_info,888u8 *txdesc)889{890fill_txdesc_checksum_common(txdesc, 16);891}892893static void rtw8812a_coex_cfg_init(struct rtw_dev *rtwdev)894{895}896897static void rtw8812a_coex_cfg_gnt_fix(struct rtw_dev *rtwdev)898{899}900901static void rtw8821a_coex_cfg_rfe_type(struct rtw_dev *rtwdev)902{903}904905static void rtw8821a_coex_cfg_wl_tx_power(struct rtw_dev *rtwdev, u8 wl_pwr)906{907}908909static void rtw8821a_coex_cfg_wl_rx_gain(struct rtw_dev *rtwdev, bool low_gain)910{911}912913static const struct rtw_chip_ops rtw8812a_ops = {914.power_on = rtw88xxa_power_on,915.power_off = rtw8812a_power_off,916.phy_set_param = NULL,917.read_efuse = rtw88xxa_read_efuse,918.query_phy_status = rtw8812a_query_phy_status,919.set_channel = rtw88xxa_set_channel,920.mac_init = NULL,921.mac_postinit = NULL,922.read_rf = rtw88xxa_phy_read_rf,923.write_rf = rtw_phy_write_rf_reg_sipi,924.set_antenna = NULL,925.set_tx_power_index = rtw88xxa_set_tx_power_index,926.cfg_ldo25 = rtw8812a_cfg_ldo25,927.efuse_grant = rtw88xxa_efuse_grant,928.set_ampdu_factor = NULL,929.false_alarm_statistics = rtw88xxa_false_alarm_statistics,930.phy_calibration = rtw8812a_phy_calibration,931.cck_pd_set = rtw88xxa_phy_cck_pd_set,932.pwr_track = rtw8812a_pwr_track,933.config_bfee = NULL,934.set_gid_table = NULL,935.cfg_csi_rate = NULL,936.led_set = rtw8812a_led_set,937.fill_txdesc_checksum = rtw8812a_fill_txdesc_checksum,938.coex_set_init = rtw8812a_coex_cfg_init,939.coex_set_ant_switch = NULL,940.coex_set_gnt_fix = rtw8812a_coex_cfg_gnt_fix,941.coex_set_gnt_debug = NULL,942.coex_set_rfe_type = rtw8821a_coex_cfg_rfe_type,943.coex_set_wl_tx_power = rtw8821a_coex_cfg_wl_tx_power,944.coex_set_wl_rx_gain = rtw8821a_coex_cfg_wl_rx_gain,945};946947static const struct rtw_page_table page_table_8812a[] = {948/* hq_num, nq_num, lq_num, exq_num, gapq_num */949{0, 0, 0, 0, 0}, /* SDIO */950{0, 0, 0, 0, 0}, /* PCI */951{16, 0, 0, 0, 1}, /* 2 bulk out endpoints */952{16, 0, 16, 0, 1}, /* 3 bulk out endpoints */953{16, 0, 16, 0, 1}, /* 4 bulk out endpoints */954};955956static const struct rtw_rqpn rqpn_table_8812a[] = {957{RTW_DMA_MAPPING_NORMAL, RTW_DMA_MAPPING_NORMAL,958RTW_DMA_MAPPING_LOW, RTW_DMA_MAPPING_LOW,959RTW_DMA_MAPPING_EXTRA, RTW_DMA_MAPPING_HIGH},960961{RTW_DMA_MAPPING_NORMAL, RTW_DMA_MAPPING_NORMAL,962RTW_DMA_MAPPING_LOW, RTW_DMA_MAPPING_LOW,963RTW_DMA_MAPPING_EXTRA, RTW_DMA_MAPPING_HIGH},964965{RTW_DMA_MAPPING_HIGH, RTW_DMA_MAPPING_HIGH,966RTW_DMA_MAPPING_NORMAL, RTW_DMA_MAPPING_NORMAL,967RTW_DMA_MAPPING_HIGH, RTW_DMA_MAPPING_HIGH},968969{RTW_DMA_MAPPING_HIGH, RTW_DMA_MAPPING_NORMAL,970RTW_DMA_MAPPING_LOW, RTW_DMA_MAPPING_LOW,971RTW_DMA_MAPPING_HIGH, RTW_DMA_MAPPING_HIGH},972973{RTW_DMA_MAPPING_NORMAL, RTW_DMA_MAPPING_NORMAL,974RTW_DMA_MAPPING_LOW, RTW_DMA_MAPPING_LOW,975RTW_DMA_MAPPING_EXTRA, RTW_DMA_MAPPING_HIGH},976};977978static const struct rtw_prioq_addrs prioq_addrs_8812a = {979.prio[RTW_DMA_MAPPING_EXTRA] = {980.rsvd = REG_RQPN_NPQ + 2, .avail = REG_RQPN_NPQ + 3,981},982.prio[RTW_DMA_MAPPING_LOW] = {983.rsvd = REG_RQPN + 1, .avail = REG_FIFOPAGE_CTRL_2 + 1,984},985.prio[RTW_DMA_MAPPING_NORMAL] = {986.rsvd = REG_RQPN_NPQ, .avail = REG_RQPN_NPQ + 1,987},988.prio[RTW_DMA_MAPPING_HIGH] = {989.rsvd = REG_RQPN, .avail = REG_FIFOPAGE_CTRL_2,990},991.wsize = false,992};993994static const struct rtw_hw_reg rtw8812a_dig[] = {995[0] = { .addr = REG_RXIGI_A, .mask = 0x7f },996[1] = { .addr = REG_RXIGI_B, .mask = 0x7f },997};998999static const struct rtw_rfe_def rtw8812a_rfe_defs[] = {1000[0] = { .phy_pg_tbl = &rtw8812a_bb_pg_tbl,1001.txpwr_lmt_tbl = &rtw8812a_txpwr_lmt_tbl,1002.pwr_track_tbl = &rtw8812a_rtw_pwr_track_tbl, },1003[1] = { .phy_pg_tbl = &rtw8812a_bb_pg_tbl,1004.txpwr_lmt_tbl = &rtw8812a_txpwr_lmt_tbl,1005.pwr_track_tbl = &rtw8812a_rtw_pwr_track_tbl, },1006[2] = { .phy_pg_tbl = &rtw8812a_bb_pg_tbl,1007.txpwr_lmt_tbl = &rtw8812a_txpwr_lmt_tbl,1008.pwr_track_tbl = &rtw8812a_rtw_pwr_track_tbl, },1009[3] = { .phy_pg_tbl = &rtw8812a_bb_pg_rfe3_tbl,1010.txpwr_lmt_tbl = &rtw8812a_txpwr_lmt_tbl,1011.pwr_track_tbl = &rtw8812a_rtw_pwr_track_rfe3_tbl, },1012};10131014static const u8 wl_rssi_step_8812a[] = {101, 45, 101, 40};1015static const u8 bt_rssi_step_8812a[] = {101, 101, 101, 101};10161017static const struct coex_rf_para rf_para_tx_8812a[] = {1018{0, 0, false, 7}, /* for normal */1019{0, 20, false, 7}, /* for WL-CPT */1020{8, 17, true, 4},1021{7, 18, true, 4},1022{6, 19, true, 4},1023{5, 20, true, 4}1024};10251026static const struct coex_rf_para rf_para_rx_8812a[] = {1027{0, 0, false, 7}, /* for normal */1028{0, 20, false, 7}, /* for WL-CPT */1029{3, 24, true, 5},1030{2, 26, true, 5},1031{1, 27, true, 5},1032{0, 28, true, 5}1033};10341035static_assert(ARRAY_SIZE(rf_para_tx_8812a) == ARRAY_SIZE(rf_para_rx_8812a));10361037const struct rtw_chip_info rtw8812a_hw_spec = {1038.ops = &rtw8812a_ops,1039.id = RTW_CHIP_TYPE_8812A,1040.fw_name = "rtw88/rtw8812a_fw.bin",1041.wlan_cpu = RTW_WCPU_8051,1042.tx_pkt_desc_sz = 40,1043.tx_buf_desc_sz = 16,1044.rx_pkt_desc_sz = 24,1045.rx_buf_desc_sz = 8,1046.phy_efuse_size = 512,1047.log_efuse_size = 512,1048.ptct_efuse_size = 0,1049.txff_size = 131072,1050.rxff_size = 16128,1051.rsvd_drv_pg_num = 9,1052.txgi_factor = 1,1053.is_pwr_by_rate_dec = true,1054.max_power_index = 0x3f,1055.csi_buf_pg_num = 0,1056.band = RTW_BAND_2G | RTW_BAND_5G,1057.page_size = 512,1058.dig_min = 0x20,1059.ht_supported = true,1060.vht_supported = true,1061.lps_deep_mode_supported = 0,1062.sys_func_en = 0xFD,1063.pwr_on_seq = card_enable_flow_8812a,1064.pwr_off_seq = card_disable_flow_8812a,1065.page_table = page_table_8812a,1066.rqpn_table = rqpn_table_8812a,1067.prioq_addrs = &prioq_addrs_8812a,1068.intf_table = NULL,1069.dig = rtw8812a_dig,1070.rf_sipi_addr = {REG_LSSI_WRITE_A, REG_LSSI_WRITE_B},1071.ltecoex_addr = NULL,1072.mac_tbl = &rtw8812a_mac_tbl,1073.agc_tbl = &rtw8812a_agc_tbl,1074.bb_tbl = &rtw8812a_bb_tbl,1075.rf_tbl = {&rtw8812a_rf_a_tbl, &rtw8812a_rf_b_tbl},1076.rfe_defs = rtw8812a_rfe_defs,1077.rfe_defs_size = ARRAY_SIZE(rtw8812a_rfe_defs),1078.rx_ldpc = false,1079.amsdu_in_ampdu = true,1080.hw_feature_report = false,1081.c2h_ra_report_size = 4,1082.old_datarate_fb_limit = true,1083.usb_tx_agg_desc_num = 1,1084.iqk_threshold = 8,1085.ampdu_density = IEEE80211_HT_MPDU_DENSITY_16,1086.max_scan_ie_len = IEEE80211_MAX_DATA_LEN,10871088.coex_para_ver = 0, /* no coex code in 8812au driver */1089.bt_desired_ver = 0,1090.scbd_support = false,1091.new_scbd10_def = false,1092.ble_hid_profile_support = false,1093.wl_mimo_ps_support = false,1094.pstdma_type = COEX_PSTDMA_FORCE_LPSOFF,1095.bt_rssi_type = COEX_BTRSSI_RATIO,1096.ant_isolation = 15,1097.rssi_tolerance = 2,1098.wl_rssi_step = wl_rssi_step_8812a,1099.bt_rssi_step = bt_rssi_step_8812a,1100.table_sant_num = 0,1101.table_sant = NULL,1102.table_nsant_num = 0,1103.table_nsant = NULL,1104.tdma_sant_num = 0,1105.tdma_sant = NULL,1106.tdma_nsant_num = 0,1107.tdma_nsant = NULL,1108.wl_rf_para_num = ARRAY_SIZE(rf_para_tx_8812a),1109.wl_rf_para_tx = rf_para_tx_8812a,1110.wl_rf_para_rx = rf_para_rx_8812a,1111.bt_afh_span_bw20 = 0x20,1112.bt_afh_span_bw40 = 0x30,1113.afh_5g_num = 0,1114.afh_5g = NULL,1115.coex_info_hw_regs_num = 0,1116.coex_info_hw_regs = NULL,1117};1118EXPORT_SYMBOL(rtw8812a_hw_spec);11191120MODULE_FIRMWARE("rtw88/rtw8812a_fw.bin");11211122MODULE_AUTHOR("Realtek Corporation");1123MODULE_DESCRIPTION("Realtek 802.11ac wireless 8812a driver");1124MODULE_LICENSE("Dual BSD/GPL");112511261127