1*a0ccc12fSBjoern A. Zeeb // SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause 2*a0ccc12fSBjoern A. Zeeb /* Copyright(c) 2024 Realtek Corporation 3*a0ccc12fSBjoern A. Zeeb */ 4*a0ccc12fSBjoern A. Zeeb 5*a0ccc12fSBjoern A. Zeeb #include "main.h" 6*a0ccc12fSBjoern A. Zeeb #include "coex.h" 7*a0ccc12fSBjoern A. Zeeb #include "phy.h" 8*a0ccc12fSBjoern A. Zeeb #include "reg.h" 9*a0ccc12fSBjoern A. Zeeb #include "rtw88xxa.h" 10*a0ccc12fSBjoern A. Zeeb #include "rtw8812a.h" 11*a0ccc12fSBjoern A. Zeeb #include "rtw8812a_table.h" 12*a0ccc12fSBjoern A. Zeeb #include "tx.h" 13*a0ccc12fSBjoern A. Zeeb 14*a0ccc12fSBjoern A. Zeeb static void rtw8812a_power_off(struct rtw_dev *rtwdev) 15*a0ccc12fSBjoern A. Zeeb { 16*a0ccc12fSBjoern A. Zeeb rtw88xxa_power_off(rtwdev, enter_lps_flow_8812a); 17*a0ccc12fSBjoern A. Zeeb } 18*a0ccc12fSBjoern A. Zeeb 19*a0ccc12fSBjoern A. Zeeb static s8 rtw8812a_cck_rx_pwr(u8 lna_idx, u8 vga_idx) 20*a0ccc12fSBjoern A. Zeeb { 21*a0ccc12fSBjoern A. Zeeb s8 rx_pwr_all = 0; 22*a0ccc12fSBjoern A. Zeeb 23*a0ccc12fSBjoern A. Zeeb switch (lna_idx) { 24*a0ccc12fSBjoern A. Zeeb case 7: 25*a0ccc12fSBjoern A. Zeeb if (vga_idx <= 27) 26*a0ccc12fSBjoern A. Zeeb rx_pwr_all = -94 + 2 * (27 - vga_idx); 27*a0ccc12fSBjoern A. Zeeb else 28*a0ccc12fSBjoern A. Zeeb rx_pwr_all = -94; 29*a0ccc12fSBjoern A. Zeeb break; 30*a0ccc12fSBjoern A. Zeeb case 6: 31*a0ccc12fSBjoern A. Zeeb rx_pwr_all = -42 + 2 * (2 - vga_idx); 32*a0ccc12fSBjoern A. Zeeb break; 33*a0ccc12fSBjoern A. Zeeb case 5: 34*a0ccc12fSBjoern A. Zeeb rx_pwr_all = -36 + 2 * (7 - vga_idx); 35*a0ccc12fSBjoern A. Zeeb break; 36*a0ccc12fSBjoern A. Zeeb case 4: 37*a0ccc12fSBjoern A. Zeeb rx_pwr_all = -30 + 2 * (7 - vga_idx); 38*a0ccc12fSBjoern A. Zeeb break; 39*a0ccc12fSBjoern A. Zeeb case 3: 40*a0ccc12fSBjoern A. Zeeb rx_pwr_all = -18 + 2 * (7 - vga_idx); 41*a0ccc12fSBjoern A. Zeeb break; 42*a0ccc12fSBjoern A. Zeeb case 2: 43*a0ccc12fSBjoern A. Zeeb rx_pwr_all = 2 * (5 - vga_idx); 44*a0ccc12fSBjoern A. Zeeb break; 45*a0ccc12fSBjoern A. Zeeb case 1: 46*a0ccc12fSBjoern A. Zeeb rx_pwr_all = 14 - 2 * vga_idx; 47*a0ccc12fSBjoern A. Zeeb break; 48*a0ccc12fSBjoern A. Zeeb case 0: 49*a0ccc12fSBjoern A. Zeeb rx_pwr_all = 20 - 2 * vga_idx; 50*a0ccc12fSBjoern A. Zeeb break; 51*a0ccc12fSBjoern A. Zeeb default: 52*a0ccc12fSBjoern A. Zeeb break; 53*a0ccc12fSBjoern A. Zeeb } 54*a0ccc12fSBjoern A. Zeeb 55*a0ccc12fSBjoern A. Zeeb return rx_pwr_all; 56*a0ccc12fSBjoern A. Zeeb } 57*a0ccc12fSBjoern A. Zeeb 58*a0ccc12fSBjoern A. Zeeb static void rtw8812a_query_phy_status(struct rtw_dev *rtwdev, u8 *phy_status, 59*a0ccc12fSBjoern A. Zeeb struct rtw_rx_pkt_stat *pkt_stat) 60*a0ccc12fSBjoern A. Zeeb { 61*a0ccc12fSBjoern A. Zeeb rtw88xxa_query_phy_status(rtwdev, phy_status, pkt_stat, 62*a0ccc12fSBjoern A. Zeeb rtw8812a_cck_rx_pwr); 63*a0ccc12fSBjoern A. Zeeb 64*a0ccc12fSBjoern A. Zeeb if (pkt_stat->rate >= DESC_RATE6M) 65*a0ccc12fSBjoern A. Zeeb return; 66*a0ccc12fSBjoern A. Zeeb 67*a0ccc12fSBjoern A. Zeeb if (rtwdev->hal.cck_high_power) 68*a0ccc12fSBjoern A. Zeeb return; 69*a0ccc12fSBjoern A. Zeeb 70*a0ccc12fSBjoern A. Zeeb if (pkt_stat->rssi >= 80) 71*a0ccc12fSBjoern A. Zeeb pkt_stat->rssi = ((pkt_stat->rssi - 80) << 1) + 72*a0ccc12fSBjoern A. Zeeb ((pkt_stat->rssi - 80) >> 1) + 80; 73*a0ccc12fSBjoern A. Zeeb else if (pkt_stat->rssi <= 78 && pkt_stat->rssi >= 20) 74*a0ccc12fSBjoern A. Zeeb pkt_stat->rssi += 3; 75*a0ccc12fSBjoern A. Zeeb } 76*a0ccc12fSBjoern A. Zeeb 77*a0ccc12fSBjoern A. Zeeb static void rtw8812a_cfg_ldo25(struct rtw_dev *rtwdev, bool enable) 78*a0ccc12fSBjoern A. Zeeb { 79*a0ccc12fSBjoern A. Zeeb } 80*a0ccc12fSBjoern A. Zeeb 81*a0ccc12fSBjoern A. Zeeb static void rtw8812a_do_lck(struct rtw_dev *rtwdev) 82*a0ccc12fSBjoern A. Zeeb { 83*a0ccc12fSBjoern A. Zeeb u32 cont_tx, lc_cal, i; 84*a0ccc12fSBjoern A. Zeeb 85*a0ccc12fSBjoern A. Zeeb cont_tx = rtw_read32_mask(rtwdev, REG_SINGLE_TONE_CONT_TX, 0x70000); 86*a0ccc12fSBjoern A. Zeeb 87*a0ccc12fSBjoern A. Zeeb lc_cal = rtw_read_rf(rtwdev, RF_PATH_A, RF_CFGCH, RFREG_MASK); 88*a0ccc12fSBjoern A. Zeeb 89*a0ccc12fSBjoern A. Zeeb if (!cont_tx) 90*a0ccc12fSBjoern A. Zeeb rtw_write8(rtwdev, REG_TXPAUSE, 0xff); 91*a0ccc12fSBjoern A. Zeeb 92*a0ccc12fSBjoern A. Zeeb rtw_write_rf(rtwdev, RF_PATH_A, RF_LCK, BIT(14), 1); 93*a0ccc12fSBjoern A. Zeeb 94*a0ccc12fSBjoern A. Zeeb rtw_write_rf(rtwdev, RF_PATH_A, RF_CFGCH, 0x08000, 1); 95*a0ccc12fSBjoern A. Zeeb 96*a0ccc12fSBjoern A. Zeeb mdelay(150); 97*a0ccc12fSBjoern A. Zeeb 98*a0ccc12fSBjoern A. Zeeb for (i = 0; i < 5; i++) { 99*a0ccc12fSBjoern A. Zeeb if (rtw_read_rf(rtwdev, RF_PATH_A, RF_CFGCH, 0x08000) != 1) 100*a0ccc12fSBjoern A. Zeeb break; 101*a0ccc12fSBjoern A. Zeeb 102*a0ccc12fSBjoern A. Zeeb mdelay(10); 103*a0ccc12fSBjoern A. Zeeb } 104*a0ccc12fSBjoern A. Zeeb 105*a0ccc12fSBjoern A. Zeeb if (i == 5) 106*a0ccc12fSBjoern A. Zeeb rtw_dbg(rtwdev, RTW_DBG_RFK, "LCK timed out\n"); 107*a0ccc12fSBjoern A. Zeeb 108*a0ccc12fSBjoern A. Zeeb rtw_write_rf(rtwdev, RF_PATH_A, RF_CFGCH, RFREG_MASK, lc_cal); 109*a0ccc12fSBjoern A. Zeeb 110*a0ccc12fSBjoern A. Zeeb rtw_write_rf(rtwdev, RF_PATH_A, RF_LCK, BIT(14), 0); 111*a0ccc12fSBjoern A. Zeeb 112*a0ccc12fSBjoern A. Zeeb if (!cont_tx) 113*a0ccc12fSBjoern A. Zeeb rtw_write8(rtwdev, REG_TXPAUSE, 0); 114*a0ccc12fSBjoern A. Zeeb 115*a0ccc12fSBjoern A. Zeeb rtw_write_rf(rtwdev, RF_PATH_A, RF_CFGCH, RFREG_MASK, lc_cal); 116*a0ccc12fSBjoern A. Zeeb } 117*a0ccc12fSBjoern A. Zeeb 118*a0ccc12fSBjoern A. Zeeb static void rtw8812a_iqk_backup_rf(struct rtw_dev *rtwdev, u32 *rfa_backup, 119*a0ccc12fSBjoern A. Zeeb u32 *rfb_backup, const u32 *backup_rf_reg, 120*a0ccc12fSBjoern A. Zeeb u32 rf_num) 121*a0ccc12fSBjoern A. Zeeb { 122*a0ccc12fSBjoern A. Zeeb u32 i; 123*a0ccc12fSBjoern A. Zeeb 124*a0ccc12fSBjoern A. Zeeb /* [31] = 0 --> Page C */ 125*a0ccc12fSBjoern A. Zeeb rtw_write32_mask(rtwdev, REG_CCASEL, BIT(31), 0x0); 126*a0ccc12fSBjoern A. Zeeb 127*a0ccc12fSBjoern A. Zeeb /* Save RF Parameters */ 128*a0ccc12fSBjoern A. Zeeb for (i = 0; i < rf_num; i++) { 129*a0ccc12fSBjoern A. Zeeb rfa_backup[i] = rtw_read_rf(rtwdev, RF_PATH_A, 130*a0ccc12fSBjoern A. Zeeb backup_rf_reg[i], MASKDWORD); 131*a0ccc12fSBjoern A. Zeeb rfb_backup[i] = rtw_read_rf(rtwdev, RF_PATH_B, 132*a0ccc12fSBjoern A. Zeeb backup_rf_reg[i], MASKDWORD); 133*a0ccc12fSBjoern A. Zeeb } 134*a0ccc12fSBjoern A. Zeeb } 135*a0ccc12fSBjoern A. Zeeb 136*a0ccc12fSBjoern A. Zeeb static void rtw8812a_iqk_restore_rf(struct rtw_dev *rtwdev, 137*a0ccc12fSBjoern A. Zeeb enum rtw_rf_path path, 138*a0ccc12fSBjoern A. Zeeb const u32 *backup_rf_reg, 139*a0ccc12fSBjoern A. Zeeb u32 *RF_backup, u32 rf_reg_num) 140*a0ccc12fSBjoern A. Zeeb { 141*a0ccc12fSBjoern A. Zeeb u32 i; 142*a0ccc12fSBjoern A. Zeeb 143*a0ccc12fSBjoern A. Zeeb /* [31] = 0 --> Page C */ 144*a0ccc12fSBjoern A. Zeeb rtw_write32_mask(rtwdev, REG_CCASEL, BIT(31), 0x0); 145*a0ccc12fSBjoern A. Zeeb 146*a0ccc12fSBjoern A. Zeeb for (i = 0; i < rf_reg_num; i++) 147*a0ccc12fSBjoern A. Zeeb rtw_write_rf(rtwdev, path, backup_rf_reg[i], 148*a0ccc12fSBjoern A. Zeeb RFREG_MASK, RF_backup[i]); 149*a0ccc12fSBjoern A. Zeeb 150*a0ccc12fSBjoern A. Zeeb rtw_write_rf(rtwdev, path, RF_LUTWE, RFREG_MASK, 0); 151*a0ccc12fSBjoern A. Zeeb } 152*a0ccc12fSBjoern A. Zeeb 153*a0ccc12fSBjoern A. Zeeb static void rtw8812a_iqk_restore_afe(struct rtw_dev *rtwdev, u32 *afe_backup, 154*a0ccc12fSBjoern A. Zeeb const u32 *backup_afe_reg, u32 afe_num) 155*a0ccc12fSBjoern A. Zeeb { 156*a0ccc12fSBjoern A. Zeeb u32 i; 157*a0ccc12fSBjoern A. Zeeb 158*a0ccc12fSBjoern A. Zeeb /* [31] = 0 --> Page C */ 159*a0ccc12fSBjoern A. Zeeb rtw_write32_mask(rtwdev, REG_CCASEL, BIT(31), 0x0); 160*a0ccc12fSBjoern A. Zeeb 161*a0ccc12fSBjoern A. Zeeb /* Reload AFE Parameters */ 162*a0ccc12fSBjoern A. Zeeb for (i = 0; i < afe_num; i++) 163*a0ccc12fSBjoern A. Zeeb rtw_write32(rtwdev, backup_afe_reg[i], afe_backup[i]); 164*a0ccc12fSBjoern A. Zeeb 165*a0ccc12fSBjoern A. Zeeb /* [31] = 1 --> Page C1 */ 166*a0ccc12fSBjoern A. Zeeb rtw_write32_mask(rtwdev, REG_CCASEL, BIT(31), 0x1); 167*a0ccc12fSBjoern A. Zeeb 168*a0ccc12fSBjoern A. Zeeb rtw_write32(rtwdev, REG_OFDM0_XA_TX_IQ_IMBALANCE, 0x0); 169*a0ccc12fSBjoern A. Zeeb rtw_write32(rtwdev, REG_OFDM0_A_TX_AFE, 0x0); 170*a0ccc12fSBjoern A. Zeeb rtw_write32(rtwdev, REG_OFDM0_XB_TX_IQ_IMBALANCE, 0x0); 171*a0ccc12fSBjoern A. Zeeb rtw_write32(rtwdev, REG_TSSI_TRK_SW, 0x3c000000); 172*a0ccc12fSBjoern A. Zeeb rtw_write32_mask(rtwdev, REG_LSSI_WRITE_A, BIT(7), 1); 173*a0ccc12fSBjoern A. Zeeb rtw_write32_mask(rtwdev, REG_IQK_DPD_CFG, BIT(18), 1); 174*a0ccc12fSBjoern A. Zeeb rtw_write32_mask(rtwdev, REG_IQK_DPD_CFG, BIT(29), 1); 175*a0ccc12fSBjoern A. Zeeb rtw_write32_mask(rtwdev, REG_CFG_PMPD, BIT(29), 1); 176*a0ccc12fSBjoern A. Zeeb 177*a0ccc12fSBjoern A. Zeeb rtw_write32(rtwdev, REG_TXTONEB, 0x0); 178*a0ccc12fSBjoern A. Zeeb rtw_write32(rtwdev, REG_RXTONEB, 0x0); 179*a0ccc12fSBjoern A. Zeeb rtw_write32(rtwdev, REG_TXPITMB, 0x0); 180*a0ccc12fSBjoern A. Zeeb rtw_write32(rtwdev, REG_RXPITMB, 0x3c000000); 181*a0ccc12fSBjoern A. Zeeb rtw_write32_mask(rtwdev, REG_LSSI_WRITE_B, BIT(7), 1); 182*a0ccc12fSBjoern A. Zeeb rtw_write32_mask(rtwdev, REG_BPBDB, BIT(18), 1); 183*a0ccc12fSBjoern A. Zeeb rtw_write32_mask(rtwdev, REG_BPBDB, BIT(29), 1); 184*a0ccc12fSBjoern A. Zeeb rtw_write32_mask(rtwdev, REG_PHYTXONB, BIT(29), 1); 185*a0ccc12fSBjoern A. Zeeb } 186*a0ccc12fSBjoern A. Zeeb 187*a0ccc12fSBjoern A. Zeeb static void rtw8812a_iqk_rx_fill(struct rtw_dev *rtwdev, enum rtw_rf_path path, 188*a0ccc12fSBjoern A. Zeeb unsigned int rx_x, unsigned int rx_y) 189*a0ccc12fSBjoern A. Zeeb { 190*a0ccc12fSBjoern A. Zeeb switch (path) { 191*a0ccc12fSBjoern A. Zeeb case RF_PATH_A: 192*a0ccc12fSBjoern A. Zeeb /* [31] = 0 --> Page C */ 193*a0ccc12fSBjoern A. Zeeb rtw_write32_mask(rtwdev, REG_CCASEL, BIT(31), 0x0); 194*a0ccc12fSBjoern A. Zeeb if (rx_x >> 1 >= 0x112 || 195*a0ccc12fSBjoern A. Zeeb (rx_y >> 1 >= 0x12 && rx_y >> 1 <= 0x3ee)) { 196*a0ccc12fSBjoern A. Zeeb rtw_write32_mask(rtwdev, REG_RX_IQC_AB_A, 197*a0ccc12fSBjoern A. Zeeb 0x000003ff, 0x100); 198*a0ccc12fSBjoern A. Zeeb rtw_write32_mask(rtwdev, REG_RX_IQC_AB_A, 199*a0ccc12fSBjoern A. Zeeb 0x03ff0000, 0); 200*a0ccc12fSBjoern A. Zeeb } else { 201*a0ccc12fSBjoern A. Zeeb rtw_write32_mask(rtwdev, REG_RX_IQC_AB_A, 202*a0ccc12fSBjoern A. Zeeb 0x000003ff, rx_x >> 1); 203*a0ccc12fSBjoern A. Zeeb rtw_write32_mask(rtwdev, REG_RX_IQC_AB_A, 204*a0ccc12fSBjoern A. Zeeb 0x03ff0000, rx_y >> 1); 205*a0ccc12fSBjoern A. Zeeb } 206*a0ccc12fSBjoern A. Zeeb rtw_dbg(rtwdev, RTW_DBG_RFK, 207*a0ccc12fSBjoern A. Zeeb "rx_x = %x;;rx_y = %x ====>fill to IQC\n", 208*a0ccc12fSBjoern A. Zeeb rx_x >> 1 & 0x000003ff, rx_y >> 1 & 0x000003ff); 209*a0ccc12fSBjoern A. Zeeb rtw_dbg(rtwdev, RTW_DBG_RFK, "0xc10 = %x ====>fill to IQC\n", 210*a0ccc12fSBjoern A. Zeeb rtw_read32(rtwdev, REG_RX_IQC_AB_A)); 211*a0ccc12fSBjoern A. Zeeb break; 212*a0ccc12fSBjoern A. Zeeb case RF_PATH_B: 213*a0ccc12fSBjoern A. Zeeb /* [31] = 0 --> Page C */ 214*a0ccc12fSBjoern A. Zeeb rtw_write32_mask(rtwdev, REG_CCASEL, BIT(31), 0x0); 215*a0ccc12fSBjoern A. Zeeb if (rx_x >> 1 >= 0x112 || 216*a0ccc12fSBjoern A. Zeeb (rx_y >> 1 >= 0x12 && rx_y >> 1 <= 0x3ee)) { 217*a0ccc12fSBjoern A. Zeeb rtw_write32_mask(rtwdev, REG_RX_IQC_AB_B, 218*a0ccc12fSBjoern A. Zeeb 0x000003ff, 0x100); 219*a0ccc12fSBjoern A. Zeeb rtw_write32_mask(rtwdev, REG_RX_IQC_AB_B, 220*a0ccc12fSBjoern A. Zeeb 0x03ff0000, 0); 221*a0ccc12fSBjoern A. Zeeb } else { 222*a0ccc12fSBjoern A. Zeeb rtw_write32_mask(rtwdev, REG_RX_IQC_AB_B, 223*a0ccc12fSBjoern A. Zeeb 0x000003ff, rx_x >> 1); 224*a0ccc12fSBjoern A. Zeeb rtw_write32_mask(rtwdev, REG_RX_IQC_AB_B, 225*a0ccc12fSBjoern A. Zeeb 0x03ff0000, rx_y >> 1); 226*a0ccc12fSBjoern A. Zeeb } 227*a0ccc12fSBjoern A. Zeeb rtw_dbg(rtwdev, RTW_DBG_RFK, 228*a0ccc12fSBjoern A. Zeeb "rx_x = %x;;rx_y = %x ====>fill to IQC\n", 229*a0ccc12fSBjoern A. Zeeb rx_x >> 1 & 0x000003ff, rx_y >> 1 & 0x000003ff); 230*a0ccc12fSBjoern A. Zeeb rtw_dbg(rtwdev, RTW_DBG_RFK, "0xe10 = %x====>fill to IQC\n", 231*a0ccc12fSBjoern A. Zeeb rtw_read32(rtwdev, REG_RX_IQC_AB_B)); 232*a0ccc12fSBjoern A. Zeeb break; 233*a0ccc12fSBjoern A. Zeeb default: 234*a0ccc12fSBjoern A. Zeeb break; 235*a0ccc12fSBjoern A. Zeeb } 236*a0ccc12fSBjoern A. Zeeb } 237*a0ccc12fSBjoern A. Zeeb 238*a0ccc12fSBjoern A. Zeeb static void rtw8812a_iqk_tx_fill(struct rtw_dev *rtwdev, enum rtw_rf_path path, 239*a0ccc12fSBjoern A. Zeeb unsigned int tx_x, unsigned int tx_y) 240*a0ccc12fSBjoern A. Zeeb { 241*a0ccc12fSBjoern A. Zeeb switch (path) { 242*a0ccc12fSBjoern A. Zeeb case RF_PATH_A: 243*a0ccc12fSBjoern A. Zeeb /* [31] = 1 --> Page C1 */ 244*a0ccc12fSBjoern A. Zeeb rtw_write32_mask(rtwdev, REG_CCASEL, BIT(31), 0x1); 245*a0ccc12fSBjoern A. Zeeb rtw_write32_mask(rtwdev, REG_PREDISTA, BIT(7), 0x1); 246*a0ccc12fSBjoern A. Zeeb rtw_write32_mask(rtwdev, REG_IQK_DPD_CFG, BIT(18), 0x1); 247*a0ccc12fSBjoern A. Zeeb rtw_write32_mask(rtwdev, REG_IQK_DPD_CFG, BIT(29), 0x1); 248*a0ccc12fSBjoern A. Zeeb rtw_write32_mask(rtwdev, REG_CFG_PMPD, BIT(29), 0x1); 249*a0ccc12fSBjoern A. Zeeb rtw_write32_mask(rtwdev, REG_IQC_Y, 0x000007ff, tx_y); 250*a0ccc12fSBjoern A. Zeeb rtw_write32_mask(rtwdev, REG_IQC_X, 0x000007ff, tx_x); 251*a0ccc12fSBjoern A. Zeeb rtw_dbg(rtwdev, RTW_DBG_RFK, 252*a0ccc12fSBjoern A. Zeeb "tx_x = %x;;tx_y = %x =====> fill to IQC\n", 253*a0ccc12fSBjoern A. Zeeb tx_x & 0x000007ff, tx_y & 0x000007ff); 254*a0ccc12fSBjoern A. Zeeb rtw_dbg(rtwdev, RTW_DBG_RFK, 255*a0ccc12fSBjoern A. Zeeb "0xcd4 = %x;;0xccc = %x ====>fill to IQC\n", 256*a0ccc12fSBjoern A. Zeeb rtw_read32_mask(rtwdev, REG_IQC_X, 0x000007ff), 257*a0ccc12fSBjoern A. Zeeb rtw_read32_mask(rtwdev, REG_IQC_Y, 0x000007ff)); 258*a0ccc12fSBjoern A. Zeeb break; 259*a0ccc12fSBjoern A. Zeeb case RF_PATH_B: 260*a0ccc12fSBjoern A. Zeeb /* [31] = 1 --> Page C1 */ 261*a0ccc12fSBjoern A. Zeeb rtw_write32_mask(rtwdev, REG_CCASEL, BIT(31), 0x1); 262*a0ccc12fSBjoern A. Zeeb rtw_write32_mask(rtwdev, REG_PREDISTB, BIT(7), 0x1); 263*a0ccc12fSBjoern A. Zeeb rtw_write32_mask(rtwdev, REG_BPBDB, BIT(18), 0x1); 264*a0ccc12fSBjoern A. Zeeb rtw_write32_mask(rtwdev, REG_BPBDB, BIT(29), 0x1); 265*a0ccc12fSBjoern A. Zeeb rtw_write32_mask(rtwdev, REG_PHYTXONB, BIT(29), 0x1); 266*a0ccc12fSBjoern A. Zeeb rtw_write32_mask(rtwdev, REG_IQKYB, 0x000007ff, tx_y); 267*a0ccc12fSBjoern A. Zeeb rtw_write32_mask(rtwdev, REG_IQKXB, 0x000007ff, tx_x); 268*a0ccc12fSBjoern A. Zeeb rtw_dbg(rtwdev, RTW_DBG_RFK, 269*a0ccc12fSBjoern A. Zeeb "tx_x = %x;;tx_y = %x =====> fill to IQC\n", 270*a0ccc12fSBjoern A. Zeeb tx_x & 0x000007ff, tx_y & 0x000007ff); 271*a0ccc12fSBjoern A. Zeeb rtw_dbg(rtwdev, RTW_DBG_RFK, 272*a0ccc12fSBjoern A. Zeeb "0xed4 = %x;;0xecc = %x ====>fill to IQC\n", 273*a0ccc12fSBjoern A. Zeeb rtw_read32_mask(rtwdev, REG_IQKXB, 0x000007ff), 274*a0ccc12fSBjoern A. Zeeb rtw_read32_mask(rtwdev, REG_IQKYB, 0x000007ff)); 275*a0ccc12fSBjoern A. Zeeb break; 276*a0ccc12fSBjoern A. Zeeb default: 277*a0ccc12fSBjoern A. Zeeb break; 278*a0ccc12fSBjoern A. Zeeb } 279*a0ccc12fSBjoern A. Zeeb } 280*a0ccc12fSBjoern A. Zeeb 281*a0ccc12fSBjoern A. Zeeb static void rtw8812a_iqk(struct rtw_dev *rtwdev) 282*a0ccc12fSBjoern A. Zeeb { 283*a0ccc12fSBjoern A. Zeeb int tx_x0_temp[10], tx_y0_temp[10], tx_x1_temp[10], tx_y1_temp[10]; 284*a0ccc12fSBjoern A. Zeeb int rx_x0_temp[10], rx_y0_temp[10], rx_x1_temp[10], rx_y1_temp[10]; 285*a0ccc12fSBjoern A. Zeeb bool iqk0_ready = false, tx0_finish = false, rx0_finish = false; 286*a0ccc12fSBjoern A. Zeeb bool iqk1_ready = false, tx1_finish = false, rx1_finish = false; 287*a0ccc12fSBjoern A. Zeeb u8 tx0_avg = 0, tx1_avg = 0, rx0_avg = 0, rx1_avg = 0; 288*a0ccc12fSBjoern A. Zeeb int tx_x0 = 0, tx_y0 = 0, tx_x1 = 0, tx_y1 = 0; 289*a0ccc12fSBjoern A. Zeeb int rx_x0 = 0, rx_y0 = 0, rx_x1 = 0, rx_y1 = 0; 290*a0ccc12fSBjoern A. Zeeb struct rtw_efuse *efuse = &rtwdev->efuse; 291*a0ccc12fSBjoern A. Zeeb bool tx0_fail = true, rx0_fail = true; 292*a0ccc12fSBjoern A. Zeeb bool tx1_fail = true, rx1_fail = true; 293*a0ccc12fSBjoern A. Zeeb u8 cal0_retry, cal1_retry; 294*a0ccc12fSBjoern A. Zeeb u8 delay_count; 295*a0ccc12fSBjoern A. Zeeb 296*a0ccc12fSBjoern A. Zeeb /* [31] = 0 --> Page C */ 297*a0ccc12fSBjoern A. Zeeb rtw_write32_mask(rtwdev, REG_CCASEL, BIT(31), 0x0); 298*a0ccc12fSBjoern A. Zeeb 299*a0ccc12fSBjoern A. Zeeb /* ========path-A AFE all on======== */ 300*a0ccc12fSBjoern A. Zeeb /* Port 0 DAC/ADC on */ 301*a0ccc12fSBjoern A. Zeeb rtw_write32(rtwdev, REG_AFE_PWR1_A, 0x77777777); 302*a0ccc12fSBjoern A. Zeeb rtw_write32(rtwdev, REG_AFE_PWR2_A, 0x77777777); 303*a0ccc12fSBjoern A. Zeeb 304*a0ccc12fSBjoern A. Zeeb /* Port 1 DAC/ADC on */ 305*a0ccc12fSBjoern A. Zeeb rtw_write32(rtwdev, REG_AFE_PWR1_B, 0x77777777); 306*a0ccc12fSBjoern A. Zeeb rtw_write32(rtwdev, REG_AFE_PWR2_B, 0x77777777); 307*a0ccc12fSBjoern A. Zeeb 308*a0ccc12fSBjoern A. Zeeb rtw_write32(rtwdev, REG_RX_WAIT_CCA_TX_CCK_RFON_A, 0x19791979); 309*a0ccc12fSBjoern A. Zeeb rtw_write32(rtwdev, REG_RX_WAIT_CCA_TX_CCK_RFON_B, 0x19791979); 310*a0ccc12fSBjoern A. Zeeb 311*a0ccc12fSBjoern A. Zeeb /* hardware 3-wire off */ 312*a0ccc12fSBjoern A. Zeeb rtw_write32_mask(rtwdev, REG_3WIRE_SWA, 0xf, 0x4); 313*a0ccc12fSBjoern A. Zeeb rtw_write32_mask(rtwdev, REG_3WIRE_SWB, 0xf, 0x4); 314*a0ccc12fSBjoern A. Zeeb 315*a0ccc12fSBjoern A. Zeeb /* DAC/ADC sampling rate (160 MHz) */ 316*a0ccc12fSBjoern A. Zeeb rtw_write32_mask(rtwdev, REG_CK_MONHA, GENMASK(26, 24), 0x7); 317*a0ccc12fSBjoern A. Zeeb rtw_write32_mask(rtwdev, REG_CK_MONHB, GENMASK(26, 24), 0x7); 318*a0ccc12fSBjoern A. Zeeb 319*a0ccc12fSBjoern A. Zeeb /* [31] = 0 --> Page C */ 320*a0ccc12fSBjoern A. Zeeb rtw_write32_mask(rtwdev, REG_CCASEL, BIT(31), 0x0); 321*a0ccc12fSBjoern A. Zeeb /* ====== path A TX IQK RF setting ====== */ 322*a0ccc12fSBjoern A. Zeeb rtw_write_rf(rtwdev, RF_PATH_A, RF_LUTWE, RFREG_MASK, 0x80002); 323*a0ccc12fSBjoern A. Zeeb rtw_write_rf(rtwdev, RF_PATH_A, RF_MODE_TABLE_ADDR, RFREG_MASK, 0x20000); 324*a0ccc12fSBjoern A. Zeeb rtw_write_rf(rtwdev, RF_PATH_A, RF_MODE_TABLE_DATA0, RFREG_MASK, 0x3fffd); 325*a0ccc12fSBjoern A. Zeeb rtw_write_rf(rtwdev, RF_PATH_A, RF_MODE_TABLE_DATA1, RFREG_MASK, 0xfe83f); 326*a0ccc12fSBjoern A. Zeeb rtw_write_rf(rtwdev, RF_PATH_A, RF_TXA_PREPAD, RFREG_MASK, 0x931d5); 327*a0ccc12fSBjoern A. Zeeb rtw_write_rf(rtwdev, RF_PATH_A, RF_RXBB2, RFREG_MASK, 0x8a001); 328*a0ccc12fSBjoern A. Zeeb 329*a0ccc12fSBjoern A. Zeeb /* ====== path B TX IQK RF setting ====== */ 330*a0ccc12fSBjoern A. Zeeb rtw_write_rf(rtwdev, RF_PATH_B, RF_LUTWE, RFREG_MASK, 0x80002); 331*a0ccc12fSBjoern A. Zeeb rtw_write_rf(rtwdev, RF_PATH_B, RF_MODE_TABLE_ADDR, RFREG_MASK, 0x20000); 332*a0ccc12fSBjoern A. Zeeb rtw_write_rf(rtwdev, RF_PATH_B, RF_MODE_TABLE_DATA0, RFREG_MASK, 0x3fffd); 333*a0ccc12fSBjoern A. Zeeb rtw_write_rf(rtwdev, RF_PATH_B, RF_MODE_TABLE_DATA1, RFREG_MASK, 0xfe83f); 334*a0ccc12fSBjoern A. Zeeb rtw_write_rf(rtwdev, RF_PATH_B, RF_TXA_PREPAD, RFREG_MASK, 0x931d5); 335*a0ccc12fSBjoern A. Zeeb rtw_write_rf(rtwdev, RF_PATH_B, RF_RXBB2, RFREG_MASK, 0x8a001); 336*a0ccc12fSBjoern A. Zeeb 337*a0ccc12fSBjoern A. Zeeb rtw_write32(rtwdev, REG_DAC_RSTB, 0x00008000); 338*a0ccc12fSBjoern A. Zeeb rtw_write32_mask(rtwdev, REG_TXAGCIDX, BIT(0), 0x1); 339*a0ccc12fSBjoern A. Zeeb rtw_write32_mask(rtwdev, REG_INIDLYB, BIT(0), 0x1); 340*a0ccc12fSBjoern A. Zeeb rtw_write32(rtwdev, REG_IQK_COM00, 0x29002000); /* TX (X,Y) */ 341*a0ccc12fSBjoern A. Zeeb rtw_write32(rtwdev, REG_IQK_COM32, 0xa9002000); /* RX (X,Y) */ 342*a0ccc12fSBjoern A. Zeeb rtw_write32(rtwdev, REG_IQK_COM96, 0x00462910); /* [0]:AGC_en, [15]:idac_K_Mask */ 343*a0ccc12fSBjoern A. Zeeb /* [31] = 1 --> Page C1 */ 344*a0ccc12fSBjoern A. Zeeb rtw_write32_mask(rtwdev, REG_CCASEL, BIT(31), 0x1); 345*a0ccc12fSBjoern A. Zeeb 346*a0ccc12fSBjoern A. Zeeb if (efuse->ext_pa_5g) { 347*a0ccc12fSBjoern A. Zeeb if (efuse->rfe_option == 1) { 348*a0ccc12fSBjoern A. Zeeb rtw_write32(rtwdev, REG_OFDM0_XB_TX_IQ_IMBALANCE, 0x821403e3); 349*a0ccc12fSBjoern A. Zeeb rtw_write32(rtwdev, REG_TXPITMB, 0x821403e3); 350*a0ccc12fSBjoern A. Zeeb } else { 351*a0ccc12fSBjoern A. Zeeb rtw_write32(rtwdev, REG_OFDM0_XB_TX_IQ_IMBALANCE, 0x821403f7); 352*a0ccc12fSBjoern A. Zeeb rtw_write32(rtwdev, REG_TXPITMB, 0x821403f7); 353*a0ccc12fSBjoern A. Zeeb } 354*a0ccc12fSBjoern A. Zeeb } else { 355*a0ccc12fSBjoern A. Zeeb rtw_write32(rtwdev, REG_OFDM0_XB_TX_IQ_IMBALANCE, 0x821403f1); 356*a0ccc12fSBjoern A. Zeeb rtw_write32(rtwdev, REG_TXPITMB, 0x821403f1); 357*a0ccc12fSBjoern A. Zeeb } 358*a0ccc12fSBjoern A. Zeeb 359*a0ccc12fSBjoern A. Zeeb if (rtwdev->hal.current_band_type == RTW_BAND_5G) { 360*a0ccc12fSBjoern A. Zeeb rtw_write32(rtwdev, REG_TSSI_TRK_SW, 0x68163e96); 361*a0ccc12fSBjoern A. Zeeb rtw_write32(rtwdev, REG_RXPITMB, 0x68163e96); 362*a0ccc12fSBjoern A. Zeeb } else { 363*a0ccc12fSBjoern A. Zeeb rtw_write32(rtwdev, REG_TSSI_TRK_SW, 0x28163e96); 364*a0ccc12fSBjoern A. Zeeb rtw_write32(rtwdev, REG_RXPITMB, 0x28163e96); 365*a0ccc12fSBjoern A. Zeeb 366*a0ccc12fSBjoern A. Zeeb if (efuse->rfe_option == 3) { 367*a0ccc12fSBjoern A. Zeeb if (efuse->ext_pa_2g) 368*a0ccc12fSBjoern A. Zeeb rtw_write32(rtwdev, REG_OFDM0_XB_TX_IQ_IMBALANCE, 369*a0ccc12fSBjoern A. Zeeb 0x821403e3); 370*a0ccc12fSBjoern A. Zeeb else 371*a0ccc12fSBjoern A. Zeeb rtw_write32(rtwdev, REG_OFDM0_XB_TX_IQ_IMBALANCE, 372*a0ccc12fSBjoern A. Zeeb 0x821403f7); 373*a0ccc12fSBjoern A. Zeeb } 374*a0ccc12fSBjoern A. Zeeb } 375*a0ccc12fSBjoern A. Zeeb 376*a0ccc12fSBjoern A. Zeeb /* TX_Tone_idx[9:0], TxK_Mask[29] TX_Tone = 16 */ 377*a0ccc12fSBjoern A. Zeeb rtw_write32(rtwdev, REG_OFDM0_XA_TX_IQ_IMBALANCE, 0x18008c10); 378*a0ccc12fSBjoern A. Zeeb /* RX_Tone_idx[9:0], RxK_Mask[29] */ 379*a0ccc12fSBjoern A. Zeeb rtw_write32(rtwdev, REG_OFDM0_A_TX_AFE, 0x38008c10); 380*a0ccc12fSBjoern A. Zeeb rtw_write32(rtwdev, REG_INTPO_SETA, 0x00000000); 381*a0ccc12fSBjoern A. Zeeb /* TX_Tone_idx[9:0], TxK_Mask[29] TX_Tone = 16 */ 382*a0ccc12fSBjoern A. Zeeb rtw_write32(rtwdev, REG_TXTONEB, 0x18008c10); 383*a0ccc12fSBjoern A. Zeeb /* RX_Tone_idx[9:0], RxK_Mask[29] */ 384*a0ccc12fSBjoern A. Zeeb rtw_write32(rtwdev, REG_RXTONEB, 0x38008c10); 385*a0ccc12fSBjoern A. Zeeb rtw_write32(rtwdev, REG_INTPO_SETB, 0x00000000); 386*a0ccc12fSBjoern A. Zeeb 387*a0ccc12fSBjoern A. Zeeb cal0_retry = 0; 388*a0ccc12fSBjoern A. Zeeb cal1_retry = 0; 389*a0ccc12fSBjoern A. Zeeb while (1) { 390*a0ccc12fSBjoern A. Zeeb /* one shot */ 391*a0ccc12fSBjoern A. Zeeb rtw_write32(rtwdev, REG_RFECTL_A, 0x00100000); 392*a0ccc12fSBjoern A. Zeeb rtw_write32(rtwdev, REG_RFECTL_B, 0x00100000); 393*a0ccc12fSBjoern A. Zeeb rtw_write32(rtwdev, REG_IQK_COM64, 0xfa000000); 394*a0ccc12fSBjoern A. Zeeb rtw_write32(rtwdev, REG_IQK_COM64, 0xf8000000); 395*a0ccc12fSBjoern A. Zeeb 396*a0ccc12fSBjoern A. Zeeb mdelay(10); 397*a0ccc12fSBjoern A. Zeeb 398*a0ccc12fSBjoern A. Zeeb rtw_write32(rtwdev, REG_RFECTL_A, 0x00000000); 399*a0ccc12fSBjoern A. Zeeb rtw_write32(rtwdev, REG_RFECTL_B, 0x00000000); 400*a0ccc12fSBjoern A. Zeeb 401*a0ccc12fSBjoern A. Zeeb for (delay_count = 0; delay_count < 20; delay_count++) { 402*a0ccc12fSBjoern A. Zeeb if (!tx0_finish) 403*a0ccc12fSBjoern A. Zeeb iqk0_ready = rtw_read32_mask(rtwdev, 404*a0ccc12fSBjoern A. Zeeb REG_IQKA_END, 405*a0ccc12fSBjoern A. Zeeb BIT(10)); 406*a0ccc12fSBjoern A. Zeeb if (!tx1_finish) 407*a0ccc12fSBjoern A. Zeeb iqk1_ready = rtw_read32_mask(rtwdev, 408*a0ccc12fSBjoern A. Zeeb REG_IQKB_END, 409*a0ccc12fSBjoern A. Zeeb BIT(10)); 410*a0ccc12fSBjoern A. Zeeb if (iqk0_ready && iqk1_ready) 411*a0ccc12fSBjoern A. Zeeb break; 412*a0ccc12fSBjoern A. Zeeb 413*a0ccc12fSBjoern A. Zeeb mdelay(1); 414*a0ccc12fSBjoern A. Zeeb } 415*a0ccc12fSBjoern A. Zeeb 416*a0ccc12fSBjoern A. Zeeb rtw_dbg(rtwdev, RTW_DBG_RFK, "TX delay_count = %d\n", 417*a0ccc12fSBjoern A. Zeeb delay_count); 418*a0ccc12fSBjoern A. Zeeb 419*a0ccc12fSBjoern A. Zeeb if (delay_count < 20) { /* If 20ms No Result, then cal_retry++ */ 420*a0ccc12fSBjoern A. Zeeb /* ============TXIQK Check============== */ 421*a0ccc12fSBjoern A. Zeeb tx0_fail = rtw_read32_mask(rtwdev, REG_IQKA_END, BIT(12)); 422*a0ccc12fSBjoern A. Zeeb tx1_fail = rtw_read32_mask(rtwdev, REG_IQKB_END, BIT(12)); 423*a0ccc12fSBjoern A. Zeeb 424*a0ccc12fSBjoern A. Zeeb if (!(tx0_fail || tx0_finish)) { 425*a0ccc12fSBjoern A. Zeeb rtw_write32(rtwdev, REG_RFECTL_A, 0x02000000); 426*a0ccc12fSBjoern A. Zeeb tx_x0_temp[tx0_avg] = rtw_read32_mask(rtwdev, 427*a0ccc12fSBjoern A. Zeeb REG_IQKA_END, 428*a0ccc12fSBjoern A. Zeeb 0x07ff0000); 429*a0ccc12fSBjoern A. Zeeb rtw_write32(rtwdev, REG_RFECTL_A, 0x04000000); 430*a0ccc12fSBjoern A. Zeeb tx_y0_temp[tx0_avg] = rtw_read32_mask(rtwdev, 431*a0ccc12fSBjoern A. Zeeb REG_IQKA_END, 432*a0ccc12fSBjoern A. Zeeb 0x07ff0000); 433*a0ccc12fSBjoern A. Zeeb 434*a0ccc12fSBjoern A. Zeeb rtw_dbg(rtwdev, RTW_DBG_RFK, 435*a0ccc12fSBjoern A. Zeeb "tx_x0[%d] = %x ;; tx_y0[%d] = %x\n", 436*a0ccc12fSBjoern A. Zeeb tx0_avg, tx_x0_temp[tx0_avg], 437*a0ccc12fSBjoern A. Zeeb tx0_avg, tx_y0_temp[tx0_avg]); 438*a0ccc12fSBjoern A. Zeeb 439*a0ccc12fSBjoern A. Zeeb tx_x0_temp[tx0_avg] <<= 21; 440*a0ccc12fSBjoern A. Zeeb tx_y0_temp[tx0_avg] <<= 21; 441*a0ccc12fSBjoern A. Zeeb 442*a0ccc12fSBjoern A. Zeeb tx0_avg++; 443*a0ccc12fSBjoern A. Zeeb } else { 444*a0ccc12fSBjoern A. Zeeb cal0_retry++; 445*a0ccc12fSBjoern A. Zeeb if (cal0_retry == 10) 446*a0ccc12fSBjoern A. Zeeb break; 447*a0ccc12fSBjoern A. Zeeb } 448*a0ccc12fSBjoern A. Zeeb 449*a0ccc12fSBjoern A. Zeeb if (!(tx1_fail || tx1_finish)) { 450*a0ccc12fSBjoern A. Zeeb rtw_write32(rtwdev, REG_RFECTL_B, 0x02000000); 451*a0ccc12fSBjoern A. Zeeb tx_x1_temp[tx1_avg] = rtw_read32_mask(rtwdev, 452*a0ccc12fSBjoern A. Zeeb REG_IQKB_END, 453*a0ccc12fSBjoern A. Zeeb 0x07ff0000); 454*a0ccc12fSBjoern A. Zeeb rtw_write32(rtwdev, REG_RFECTL_B, 0x04000000); 455*a0ccc12fSBjoern A. Zeeb tx_y1_temp[tx1_avg] = rtw_read32_mask(rtwdev, 456*a0ccc12fSBjoern A. Zeeb REG_IQKB_END, 457*a0ccc12fSBjoern A. Zeeb 0x07ff0000); 458*a0ccc12fSBjoern A. Zeeb 459*a0ccc12fSBjoern A. Zeeb rtw_dbg(rtwdev, RTW_DBG_RFK, 460*a0ccc12fSBjoern A. Zeeb "tx_x1[%d] = %x ;; tx_y1[%d] = %x\n", 461*a0ccc12fSBjoern A. Zeeb tx1_avg, tx_x1_temp[tx1_avg], 462*a0ccc12fSBjoern A. Zeeb tx1_avg, tx_y1_temp[tx1_avg]); 463*a0ccc12fSBjoern A. Zeeb 464*a0ccc12fSBjoern A. Zeeb tx_x1_temp[tx1_avg] <<= 21; 465*a0ccc12fSBjoern A. Zeeb tx_y1_temp[tx1_avg] <<= 21; 466*a0ccc12fSBjoern A. Zeeb 467*a0ccc12fSBjoern A. Zeeb tx1_avg++; 468*a0ccc12fSBjoern A. Zeeb } else { 469*a0ccc12fSBjoern A. Zeeb cal1_retry++; 470*a0ccc12fSBjoern A. Zeeb if (cal1_retry == 10) 471*a0ccc12fSBjoern A. Zeeb break; 472*a0ccc12fSBjoern A. Zeeb } 473*a0ccc12fSBjoern A. Zeeb } else { 474*a0ccc12fSBjoern A. Zeeb cal0_retry++; 475*a0ccc12fSBjoern A. Zeeb cal1_retry++; 476*a0ccc12fSBjoern A. Zeeb 477*a0ccc12fSBjoern A. Zeeb rtw_dbg(rtwdev, RTW_DBG_RFK, 478*a0ccc12fSBjoern A. Zeeb "delay 20ms TX IQK Not Ready!!!!!\n"); 479*a0ccc12fSBjoern A. Zeeb 480*a0ccc12fSBjoern A. Zeeb if (cal0_retry == 10) 481*a0ccc12fSBjoern A. Zeeb break; 482*a0ccc12fSBjoern A. Zeeb } 483*a0ccc12fSBjoern A. Zeeb 484*a0ccc12fSBjoern A. Zeeb if (tx0_avg >= 2) 485*a0ccc12fSBjoern A. Zeeb tx0_finish = rtw88xxa_iqk_finish(tx0_avg, 4, 486*a0ccc12fSBjoern A. Zeeb tx_x0_temp, tx_y0_temp, &tx_x0, &tx_y0, 487*a0ccc12fSBjoern A. Zeeb false, false); 488*a0ccc12fSBjoern A. Zeeb 489*a0ccc12fSBjoern A. Zeeb if (tx1_avg >= 2) 490*a0ccc12fSBjoern A. Zeeb tx1_finish = rtw88xxa_iqk_finish(tx1_avg, 4, 491*a0ccc12fSBjoern A. Zeeb tx_x1_temp, tx_y1_temp, &tx_x1, &tx_y1, 492*a0ccc12fSBjoern A. Zeeb false, false); 493*a0ccc12fSBjoern A. Zeeb 494*a0ccc12fSBjoern A. Zeeb rtw_dbg(rtwdev, RTW_DBG_RFK, 495*a0ccc12fSBjoern A. Zeeb "tx0_average = %d, tx1_average = %d\n", 496*a0ccc12fSBjoern A. Zeeb tx0_avg, tx1_avg); 497*a0ccc12fSBjoern A. Zeeb rtw_dbg(rtwdev, RTW_DBG_RFK, 498*a0ccc12fSBjoern A. Zeeb "tx0_finish = %d, tx1_finish = %d\n", 499*a0ccc12fSBjoern A. Zeeb tx0_finish, tx1_finish); 500*a0ccc12fSBjoern A. Zeeb 501*a0ccc12fSBjoern A. Zeeb if (tx0_finish && tx1_finish) 502*a0ccc12fSBjoern A. Zeeb break; 503*a0ccc12fSBjoern A. Zeeb 504*a0ccc12fSBjoern A. Zeeb if ((cal0_retry + tx0_avg) >= 10 || 505*a0ccc12fSBjoern A. Zeeb (cal1_retry + tx1_avg) >= 10) 506*a0ccc12fSBjoern A. Zeeb break; 507*a0ccc12fSBjoern A. Zeeb } 508*a0ccc12fSBjoern A. Zeeb 509*a0ccc12fSBjoern A. Zeeb rtw_dbg(rtwdev, RTW_DBG_RFK, "TXA_cal_retry = %d\n", cal0_retry); 510*a0ccc12fSBjoern A. Zeeb rtw_dbg(rtwdev, RTW_DBG_RFK, "TXB_cal_retry = %d\n", cal1_retry); 511*a0ccc12fSBjoern A. Zeeb 512*a0ccc12fSBjoern A. Zeeb /* [31] = 0 --> Page C */ 513*a0ccc12fSBjoern A. Zeeb rtw_write32_mask(rtwdev, REG_CCASEL, BIT(31), 0x0); 514*a0ccc12fSBjoern A. Zeeb /* Load LOK */ 515*a0ccc12fSBjoern A. Zeeb rtw_write_rf(rtwdev, RF_PATH_A, RF_TXMOD, 0x7fe00, 516*a0ccc12fSBjoern A. Zeeb rtw_read_rf(rtwdev, RF_PATH_A, RF_DTXLOK, 0xffc00)); 517*a0ccc12fSBjoern A. Zeeb rtw_write_rf(rtwdev, RF_PATH_B, RF_TXMOD, 0x7fe00, 518*a0ccc12fSBjoern A. Zeeb rtw_read_rf(rtwdev, RF_PATH_B, RF_DTXLOK, 0xffc00)); 519*a0ccc12fSBjoern A. Zeeb /* [31] = 1 --> Page C1 */ 520*a0ccc12fSBjoern A. Zeeb rtw_write32_mask(rtwdev, REG_CCASEL, BIT(31), 0x1); 521*a0ccc12fSBjoern A. Zeeb 522*a0ccc12fSBjoern A. Zeeb /* [31] = 0 --> Page C */ 523*a0ccc12fSBjoern A. Zeeb rtw_write32_mask(rtwdev, REG_CCASEL, BIT(31), 0x0); 524*a0ccc12fSBjoern A. Zeeb if (tx0_finish) { 525*a0ccc12fSBjoern A. Zeeb /* ====== path A RX IQK RF setting====== */ 526*a0ccc12fSBjoern A. Zeeb rtw_write_rf(rtwdev, RF_PATH_A, RF_LUTWE, RFREG_MASK, 0x80000); 527*a0ccc12fSBjoern A. Zeeb rtw_write_rf(rtwdev, RF_PATH_A, RF_MODE_TABLE_ADDR, RFREG_MASK, 528*a0ccc12fSBjoern A. Zeeb 0x30000); 529*a0ccc12fSBjoern A. Zeeb rtw_write_rf(rtwdev, RF_PATH_A, RF_MODE_TABLE_DATA0, RFREG_MASK, 530*a0ccc12fSBjoern A. Zeeb 0x3f7ff); 531*a0ccc12fSBjoern A. Zeeb rtw_write_rf(rtwdev, RF_PATH_A, RF_MODE_TABLE_DATA1, RFREG_MASK, 532*a0ccc12fSBjoern A. Zeeb 0xfe7bf); 533*a0ccc12fSBjoern A. Zeeb rtw_write_rf(rtwdev, RF_PATH_A, RF_RXBB2, RFREG_MASK, 0x88001); 534*a0ccc12fSBjoern A. Zeeb rtw_write_rf(rtwdev, RF_PATH_A, RF_TXA_PREPAD, RFREG_MASK, 0x931d1); 535*a0ccc12fSBjoern A. Zeeb rtw_write_rf(rtwdev, RF_PATH_A, RF_LUTWE, RFREG_MASK, 0x00000); 536*a0ccc12fSBjoern A. Zeeb } 537*a0ccc12fSBjoern A. Zeeb if (tx1_finish) { 538*a0ccc12fSBjoern A. Zeeb /* ====== path B RX IQK RF setting====== */ 539*a0ccc12fSBjoern A. Zeeb rtw_write_rf(rtwdev, RF_PATH_B, RF_LUTWE, RFREG_MASK, 0x80000); 540*a0ccc12fSBjoern A. Zeeb rtw_write_rf(rtwdev, RF_PATH_B, RF_MODE_TABLE_ADDR, RFREG_MASK, 541*a0ccc12fSBjoern A. Zeeb 0x30000); 542*a0ccc12fSBjoern A. Zeeb rtw_write_rf(rtwdev, RF_PATH_B, RF_MODE_TABLE_DATA0, RFREG_MASK, 543*a0ccc12fSBjoern A. Zeeb 0x3f7ff); 544*a0ccc12fSBjoern A. Zeeb rtw_write_rf(rtwdev, RF_PATH_B, RF_MODE_TABLE_DATA1, RFREG_MASK, 545*a0ccc12fSBjoern A. Zeeb 0xfe7bf); 546*a0ccc12fSBjoern A. Zeeb rtw_write_rf(rtwdev, RF_PATH_B, RF_RXBB2, RFREG_MASK, 0x88001); 547*a0ccc12fSBjoern A. Zeeb rtw_write_rf(rtwdev, RF_PATH_B, RF_TXA_PREPAD, RFREG_MASK, 0x931d1); 548*a0ccc12fSBjoern A. Zeeb rtw_write_rf(rtwdev, RF_PATH_B, RF_LUTWE, RFREG_MASK, 0x00000); 549*a0ccc12fSBjoern A. Zeeb } 550*a0ccc12fSBjoern A. Zeeb 551*a0ccc12fSBjoern A. Zeeb rtw_write32_mask(rtwdev, REG_IQK_COM00, BIT(31), 0x1); 552*a0ccc12fSBjoern A. Zeeb rtw_write32_mask(rtwdev, REG_IQK_COM00, BIT(31), 0x0); 553*a0ccc12fSBjoern A. Zeeb rtw_write32(rtwdev, REG_DAC_RSTB, 0x00008000); 554*a0ccc12fSBjoern A. Zeeb 555*a0ccc12fSBjoern A. Zeeb if (rtwdev->hci.type == RTW_HCI_TYPE_PCIE) 556*a0ccc12fSBjoern A. Zeeb rtw_write32(rtwdev, REG_IQK_COM96, 0x0046a911); 557*a0ccc12fSBjoern A. Zeeb else 558*a0ccc12fSBjoern A. Zeeb rtw_write32(rtwdev, REG_IQK_COM96, 0x0046a890); 559*a0ccc12fSBjoern A. Zeeb 560*a0ccc12fSBjoern A. Zeeb if (efuse->rfe_option == 1) { 561*a0ccc12fSBjoern A. Zeeb rtw_write32(rtwdev, REG_RFE_PINMUX_A, 0x77777717); 562*a0ccc12fSBjoern A. Zeeb rtw_write32(rtwdev, REG_RFE_INV_A, 0x00000077); 563*a0ccc12fSBjoern A. Zeeb rtw_write32(rtwdev, REG_RFE_PINMUX_B, 0x77777717); 564*a0ccc12fSBjoern A. Zeeb rtw_write32(rtwdev, REG_RFE_INV_B, 0x00000077); 565*a0ccc12fSBjoern A. Zeeb } else { 566*a0ccc12fSBjoern A. Zeeb rtw_write32(rtwdev, REG_RFE_PINMUX_A, 0x77777717); 567*a0ccc12fSBjoern A. Zeeb rtw_write32(rtwdev, REG_RFE_INV_A, 0x02000077); 568*a0ccc12fSBjoern A. Zeeb rtw_write32(rtwdev, REG_RFE_PINMUX_B, 0x77777717); 569*a0ccc12fSBjoern A. Zeeb rtw_write32(rtwdev, REG_RFE_INV_B, 0x02000077); 570*a0ccc12fSBjoern A. Zeeb } 571*a0ccc12fSBjoern A. Zeeb 572*a0ccc12fSBjoern A. Zeeb /* [31] = 1 --> Page C1 */ 573*a0ccc12fSBjoern A. Zeeb rtw_write32_mask(rtwdev, REG_CCASEL, BIT(31), 0x1); 574*a0ccc12fSBjoern A. Zeeb 575*a0ccc12fSBjoern A. Zeeb if (tx0_finish) { 576*a0ccc12fSBjoern A. Zeeb /* TX_Tone_idx[9:0], TxK_Mask[29] TX_Tone = 16 */ 577*a0ccc12fSBjoern A. Zeeb rtw_write32(rtwdev, REG_OFDM0_XA_TX_IQ_IMBALANCE, 0x38008c10); 578*a0ccc12fSBjoern A. Zeeb /* RX_Tone_idx[9:0], RxK_Mask[29] */ 579*a0ccc12fSBjoern A. Zeeb rtw_write32(rtwdev, REG_OFDM0_A_TX_AFE, 0x18008c10); 580*a0ccc12fSBjoern A. Zeeb rtw_write32(rtwdev, REG_OFDM0_XB_TX_IQ_IMBALANCE, 0x82140119); 581*a0ccc12fSBjoern A. Zeeb } 582*a0ccc12fSBjoern A. Zeeb if (tx1_finish) { 583*a0ccc12fSBjoern A. Zeeb /* TX_Tone_idx[9:0], TxK_Mask[29] TX_Tone = 16 */ 584*a0ccc12fSBjoern A. Zeeb rtw_write32(rtwdev, REG_TXTONEB, 0x38008c10); 585*a0ccc12fSBjoern A. Zeeb /* RX_Tone_idx[9:0], RxK_Mask[29] */ 586*a0ccc12fSBjoern A. Zeeb rtw_write32(rtwdev, REG_RXTONEB, 0x18008c10); 587*a0ccc12fSBjoern A. Zeeb rtw_write32(rtwdev, REG_TXPITMB, 0x82140119); 588*a0ccc12fSBjoern A. Zeeb } 589*a0ccc12fSBjoern A. Zeeb 590*a0ccc12fSBjoern A. Zeeb cal0_retry = 0; 591*a0ccc12fSBjoern A. Zeeb cal1_retry = 0; 592*a0ccc12fSBjoern A. Zeeb while (1) { 593*a0ccc12fSBjoern A. Zeeb /* one shot */ 594*a0ccc12fSBjoern A. Zeeb /* [31] = 0 --> Page C */ 595*a0ccc12fSBjoern A. Zeeb rtw_write32_mask(rtwdev, REG_CCASEL, BIT(31), 0x0); 596*a0ccc12fSBjoern A. Zeeb 597*a0ccc12fSBjoern A. Zeeb if (tx0_finish) { 598*a0ccc12fSBjoern A. Zeeb rtw_write32_mask(rtwdev, REG_IQK_COM00, 0x03FF8000, 599*a0ccc12fSBjoern A. Zeeb tx_x0 & 0x000007ff); 600*a0ccc12fSBjoern A. Zeeb rtw_write32_mask(rtwdev, REG_IQK_COM00, 0x000007FF, 601*a0ccc12fSBjoern A. Zeeb tx_y0 & 0x000007ff); 602*a0ccc12fSBjoern A. Zeeb /* [31] = 1 --> Page C1 */ 603*a0ccc12fSBjoern A. Zeeb rtw_write32_mask(rtwdev, REG_CCASEL, BIT(31), 0x1); 604*a0ccc12fSBjoern A. Zeeb if (efuse->rfe_option == 1) 605*a0ccc12fSBjoern A. Zeeb rtw_write32(rtwdev, REG_TSSI_TRK_SW, 0x28161500); 606*a0ccc12fSBjoern A. Zeeb else 607*a0ccc12fSBjoern A. Zeeb rtw_write32(rtwdev, REG_TSSI_TRK_SW, 0x28160cc0); 608*a0ccc12fSBjoern A. Zeeb rtw_write32(rtwdev, REG_RFECTL_A, 0x00300000); 609*a0ccc12fSBjoern A. Zeeb rtw_write32(rtwdev, REG_RFECTL_A, 0x00100000); 610*a0ccc12fSBjoern A. Zeeb mdelay(5); 611*a0ccc12fSBjoern A. Zeeb rtw_write32(rtwdev, REG_TSSI_TRK_SW, 0x3c000000); 612*a0ccc12fSBjoern A. Zeeb rtw_write32(rtwdev, REG_RFECTL_A, 0x00000000); 613*a0ccc12fSBjoern A. Zeeb } 614*a0ccc12fSBjoern A. Zeeb 615*a0ccc12fSBjoern A. Zeeb if (tx1_finish) { 616*a0ccc12fSBjoern A. Zeeb /* [31] = 0 --> Page C */ 617*a0ccc12fSBjoern A. Zeeb rtw_write32_mask(rtwdev, REG_CCASEL, BIT(31), 0x0); 618*a0ccc12fSBjoern A. Zeeb rtw_write32_mask(rtwdev, REG_IQK_COM00, 0x03FF8000, 619*a0ccc12fSBjoern A. Zeeb tx_x1 & 0x000007ff); 620*a0ccc12fSBjoern A. Zeeb rtw_write32_mask(rtwdev, REG_IQK_COM00, 0x000007FF, 621*a0ccc12fSBjoern A. Zeeb tx_y1 & 0x000007ff); 622*a0ccc12fSBjoern A. Zeeb /* [31] = 1 --> Page C1 */ 623*a0ccc12fSBjoern A. Zeeb rtw_write32_mask(rtwdev, REG_CCASEL, BIT(31), 0x1); 624*a0ccc12fSBjoern A. Zeeb if (efuse->rfe_option == 1) 625*a0ccc12fSBjoern A. Zeeb rtw_write32(rtwdev, REG_RXPITMB, 0x28161500); 626*a0ccc12fSBjoern A. Zeeb else 627*a0ccc12fSBjoern A. Zeeb rtw_write32(rtwdev, REG_RXPITMB, 0x28160ca0); 628*a0ccc12fSBjoern A. Zeeb rtw_write32(rtwdev, REG_RFECTL_B, 0x00300000); 629*a0ccc12fSBjoern A. Zeeb rtw_write32(rtwdev, REG_RFECTL_B, 0x00100000); 630*a0ccc12fSBjoern A. Zeeb mdelay(5); 631*a0ccc12fSBjoern A. Zeeb rtw_write32(rtwdev, REG_RXPITMB, 0x3c000000); 632*a0ccc12fSBjoern A. Zeeb rtw_write32(rtwdev, REG_RFECTL_B, 0x00000000); 633*a0ccc12fSBjoern A. Zeeb } 634*a0ccc12fSBjoern A. Zeeb 635*a0ccc12fSBjoern A. Zeeb for (delay_count = 0; delay_count < 20; delay_count++) { 636*a0ccc12fSBjoern A. Zeeb if (!rx0_finish && tx0_finish) 637*a0ccc12fSBjoern A. Zeeb iqk0_ready = rtw_read32_mask(rtwdev, 638*a0ccc12fSBjoern A. Zeeb REG_IQKA_END, 639*a0ccc12fSBjoern A. Zeeb BIT(10)); 640*a0ccc12fSBjoern A. Zeeb if (!rx1_finish && tx1_finish) 641*a0ccc12fSBjoern A. Zeeb iqk1_ready = rtw_read32_mask(rtwdev, 642*a0ccc12fSBjoern A. Zeeb REG_IQKB_END, 643*a0ccc12fSBjoern A. Zeeb BIT(10)); 644*a0ccc12fSBjoern A. Zeeb if (iqk0_ready && iqk1_ready) 645*a0ccc12fSBjoern A. Zeeb break; 646*a0ccc12fSBjoern A. Zeeb 647*a0ccc12fSBjoern A. Zeeb mdelay(1); 648*a0ccc12fSBjoern A. Zeeb } 649*a0ccc12fSBjoern A. Zeeb 650*a0ccc12fSBjoern A. Zeeb rtw_dbg(rtwdev, RTW_DBG_RFK, "RX delay_count = %d\n", 651*a0ccc12fSBjoern A. Zeeb delay_count); 652*a0ccc12fSBjoern A. Zeeb 653*a0ccc12fSBjoern A. Zeeb if (delay_count < 20) { /* If 20ms No Result, then cal_retry++ */ 654*a0ccc12fSBjoern A. Zeeb /* ============RXIQK Check============== */ 655*a0ccc12fSBjoern A. Zeeb rx0_fail = rtw_read32_mask(rtwdev, REG_IQKA_END, BIT(11)); 656*a0ccc12fSBjoern A. Zeeb rx1_fail = rtw_read32_mask(rtwdev, REG_IQKB_END, BIT(11)); 657*a0ccc12fSBjoern A. Zeeb 658*a0ccc12fSBjoern A. Zeeb if (!(rx0_fail || rx0_finish) && tx0_finish) { 659*a0ccc12fSBjoern A. Zeeb rtw_write32(rtwdev, REG_RFECTL_A, 0x06000000); 660*a0ccc12fSBjoern A. Zeeb rx_x0_temp[rx0_avg] = rtw_read32_mask(rtwdev, 661*a0ccc12fSBjoern A. Zeeb REG_IQKA_END, 662*a0ccc12fSBjoern A. Zeeb 0x07ff0000); 663*a0ccc12fSBjoern A. Zeeb rtw_write32(rtwdev, REG_RFECTL_A, 0x08000000); 664*a0ccc12fSBjoern A. Zeeb rx_y0_temp[rx0_avg] = rtw_read32_mask(rtwdev, 665*a0ccc12fSBjoern A. Zeeb REG_IQKA_END, 666*a0ccc12fSBjoern A. Zeeb 0x07ff0000); 667*a0ccc12fSBjoern A. Zeeb 668*a0ccc12fSBjoern A. Zeeb rtw_dbg(rtwdev, RTW_DBG_RFK, 669*a0ccc12fSBjoern A. Zeeb "rx_x0[%d] = %x ;; rx_y0[%d] = %x\n", 670*a0ccc12fSBjoern A. Zeeb rx0_avg, rx_x0_temp[rx0_avg], 671*a0ccc12fSBjoern A. Zeeb rx0_avg, rx_y0_temp[rx0_avg]); 672*a0ccc12fSBjoern A. Zeeb 673*a0ccc12fSBjoern A. Zeeb rx_x0_temp[rx0_avg] <<= 21; 674*a0ccc12fSBjoern A. Zeeb rx_y0_temp[rx0_avg] <<= 21; 675*a0ccc12fSBjoern A. Zeeb 676*a0ccc12fSBjoern A. Zeeb rx0_avg++; 677*a0ccc12fSBjoern A. Zeeb } else { 678*a0ccc12fSBjoern A. Zeeb rtw_dbg(rtwdev, RTW_DBG_RFK, 679*a0ccc12fSBjoern A. Zeeb "1. RXA_cal_retry = %d\n", cal0_retry); 680*a0ccc12fSBjoern A. Zeeb 681*a0ccc12fSBjoern A. Zeeb cal0_retry++; 682*a0ccc12fSBjoern A. Zeeb if (cal0_retry == 10) 683*a0ccc12fSBjoern A. Zeeb break; 684*a0ccc12fSBjoern A. Zeeb } 685*a0ccc12fSBjoern A. Zeeb 686*a0ccc12fSBjoern A. Zeeb if (!(rx1_fail || rx1_finish) && tx1_finish) { 687*a0ccc12fSBjoern A. Zeeb rtw_write32(rtwdev, REG_RFECTL_B, 0x06000000); 688*a0ccc12fSBjoern A. Zeeb rx_x1_temp[rx1_avg] = rtw_read32_mask(rtwdev, 689*a0ccc12fSBjoern A. Zeeb REG_IQKB_END, 690*a0ccc12fSBjoern A. Zeeb 0x07ff0000); 691*a0ccc12fSBjoern A. Zeeb rtw_write32(rtwdev, REG_RFECTL_B, 0x08000000); 692*a0ccc12fSBjoern A. Zeeb rx_y1_temp[rx1_avg] = rtw_read32_mask(rtwdev, 693*a0ccc12fSBjoern A. Zeeb REG_IQKB_END, 694*a0ccc12fSBjoern A. Zeeb 0x07ff0000); 695*a0ccc12fSBjoern A. Zeeb 696*a0ccc12fSBjoern A. Zeeb rtw_dbg(rtwdev, RTW_DBG_RFK, 697*a0ccc12fSBjoern A. Zeeb "rx_x1[%d] = %x ;; rx_y1[%d] = %x\n", 698*a0ccc12fSBjoern A. Zeeb rx1_avg, rx_x1_temp[rx1_avg], 699*a0ccc12fSBjoern A. Zeeb rx1_avg, rx_y1_temp[rx1_avg]); 700*a0ccc12fSBjoern A. Zeeb 701*a0ccc12fSBjoern A. Zeeb rx_x1_temp[rx1_avg] <<= 21; 702*a0ccc12fSBjoern A. Zeeb rx_y1_temp[rx1_avg] <<= 21; 703*a0ccc12fSBjoern A. Zeeb 704*a0ccc12fSBjoern A. Zeeb rx1_avg++; 705*a0ccc12fSBjoern A. Zeeb } else { 706*a0ccc12fSBjoern A. Zeeb cal1_retry++; 707*a0ccc12fSBjoern A. Zeeb if (cal1_retry == 10) 708*a0ccc12fSBjoern A. Zeeb break; 709*a0ccc12fSBjoern A. Zeeb } 710*a0ccc12fSBjoern A. Zeeb } else { 711*a0ccc12fSBjoern A. Zeeb rtw_dbg(rtwdev, RTW_DBG_RFK, 712*a0ccc12fSBjoern A. Zeeb "2. RXA_cal_retry = %d\n", cal0_retry); 713*a0ccc12fSBjoern A. Zeeb 714*a0ccc12fSBjoern A. Zeeb cal0_retry++; 715*a0ccc12fSBjoern A. Zeeb cal1_retry++; 716*a0ccc12fSBjoern A. Zeeb 717*a0ccc12fSBjoern A. Zeeb rtw_dbg(rtwdev, RTW_DBG_RFK, 718*a0ccc12fSBjoern A. Zeeb "delay 20ms RX IQK Not Ready!!!!!\n"); 719*a0ccc12fSBjoern A. Zeeb 720*a0ccc12fSBjoern A. Zeeb if (cal0_retry == 10) 721*a0ccc12fSBjoern A. Zeeb break; 722*a0ccc12fSBjoern A. Zeeb } 723*a0ccc12fSBjoern A. Zeeb 724*a0ccc12fSBjoern A. Zeeb rtw_dbg(rtwdev, RTW_DBG_RFK, "3. RXA_cal_retry = %d\n", 725*a0ccc12fSBjoern A. Zeeb cal0_retry); 726*a0ccc12fSBjoern A. Zeeb 727*a0ccc12fSBjoern A. Zeeb if (rx0_avg >= 2) 728*a0ccc12fSBjoern A. Zeeb rx0_finish = rtw88xxa_iqk_finish(rx0_avg, 4, 729*a0ccc12fSBjoern A. Zeeb rx_x0_temp, rx_y0_temp, 730*a0ccc12fSBjoern A. Zeeb &rx_x0, &rx_y0, 731*a0ccc12fSBjoern A. Zeeb true, false); 732*a0ccc12fSBjoern A. Zeeb 733*a0ccc12fSBjoern A. Zeeb if (rx1_avg >= 2) 734*a0ccc12fSBjoern A. Zeeb rx1_finish = rtw88xxa_iqk_finish(rx1_avg, 4, 735*a0ccc12fSBjoern A. Zeeb rx_x1_temp, rx_y1_temp, 736*a0ccc12fSBjoern A. Zeeb &rx_x1, &rx_y1, 737*a0ccc12fSBjoern A. Zeeb true, false); 738*a0ccc12fSBjoern A. Zeeb 739*a0ccc12fSBjoern A. Zeeb rtw_dbg(rtwdev, RTW_DBG_RFK, 740*a0ccc12fSBjoern A. Zeeb "rx0_average = %d, rx1_average = %d\n", 741*a0ccc12fSBjoern A. Zeeb rx0_avg, rx1_avg); 742*a0ccc12fSBjoern A. Zeeb rtw_dbg(rtwdev, RTW_DBG_RFK, 743*a0ccc12fSBjoern A. Zeeb "rx0_finish = %d, rx1_finish = %d\n", 744*a0ccc12fSBjoern A. Zeeb rx0_finish, rx1_finish); 745*a0ccc12fSBjoern A. Zeeb 746*a0ccc12fSBjoern A. Zeeb if ((rx0_finish || !tx0_finish) && (rx1_finish || !tx1_finish)) 747*a0ccc12fSBjoern A. Zeeb break; 748*a0ccc12fSBjoern A. Zeeb 749*a0ccc12fSBjoern A. Zeeb if ((cal0_retry + rx0_avg) >= 10 || 750*a0ccc12fSBjoern A. Zeeb (cal1_retry + rx1_avg) >= 10 || 751*a0ccc12fSBjoern A. Zeeb rx0_avg == 3 || rx1_avg == 3) 752*a0ccc12fSBjoern A. Zeeb break; 753*a0ccc12fSBjoern A. Zeeb } 754*a0ccc12fSBjoern A. Zeeb 755*a0ccc12fSBjoern A. Zeeb rtw_dbg(rtwdev, RTW_DBG_RFK, "RXA_cal_retry = %d\n", cal0_retry); 756*a0ccc12fSBjoern A. Zeeb rtw_dbg(rtwdev, RTW_DBG_RFK, "RXB_cal_retry = %d\n", cal1_retry); 757*a0ccc12fSBjoern A. Zeeb 758*a0ccc12fSBjoern A. Zeeb /* FillIQK Result */ 759*a0ccc12fSBjoern A. Zeeb rtw_dbg(rtwdev, RTW_DBG_RFK, "========Path_A =======\n"); 760*a0ccc12fSBjoern A. Zeeb 761*a0ccc12fSBjoern A. Zeeb if (tx0_finish) 762*a0ccc12fSBjoern A. Zeeb rtw8812a_iqk_tx_fill(rtwdev, RF_PATH_A, tx_x0, tx_y0); 763*a0ccc12fSBjoern A. Zeeb else 764*a0ccc12fSBjoern A. Zeeb rtw8812a_iqk_tx_fill(rtwdev, RF_PATH_A, 0x200, 0x0); 765*a0ccc12fSBjoern A. Zeeb 766*a0ccc12fSBjoern A. Zeeb if (rx0_finish) 767*a0ccc12fSBjoern A. Zeeb rtw8812a_iqk_rx_fill(rtwdev, RF_PATH_A, rx_x0, rx_y0); 768*a0ccc12fSBjoern A. Zeeb else 769*a0ccc12fSBjoern A. Zeeb rtw8812a_iqk_rx_fill(rtwdev, RF_PATH_A, 0x200, 0x0); 770*a0ccc12fSBjoern A. Zeeb 771*a0ccc12fSBjoern A. Zeeb rtw_dbg(rtwdev, RTW_DBG_RFK, "========Path_B =======\n"); 772*a0ccc12fSBjoern A. Zeeb 773*a0ccc12fSBjoern A. Zeeb if (tx1_finish) 774*a0ccc12fSBjoern A. Zeeb rtw8812a_iqk_tx_fill(rtwdev, RF_PATH_B, tx_x1, tx_y1); 775*a0ccc12fSBjoern A. Zeeb else 776*a0ccc12fSBjoern A. Zeeb rtw8812a_iqk_tx_fill(rtwdev, RF_PATH_B, 0x200, 0x0); 777*a0ccc12fSBjoern A. Zeeb 778*a0ccc12fSBjoern A. Zeeb if (rx1_finish) 779*a0ccc12fSBjoern A. Zeeb rtw8812a_iqk_rx_fill(rtwdev, RF_PATH_B, rx_x1, rx_y1); 780*a0ccc12fSBjoern A. Zeeb else 781*a0ccc12fSBjoern A. Zeeb rtw8812a_iqk_rx_fill(rtwdev, RF_PATH_B, 0x200, 0x0); 782*a0ccc12fSBjoern A. Zeeb } 783*a0ccc12fSBjoern A. Zeeb 784*a0ccc12fSBjoern A. Zeeb #define MACBB_REG_NUM_8812A 9 785*a0ccc12fSBjoern A. Zeeb #define AFE_REG_NUM_8812A 12 786*a0ccc12fSBjoern A. Zeeb #define RF_REG_NUM_8812A 3 787*a0ccc12fSBjoern A. Zeeb 788*a0ccc12fSBjoern A. Zeeb static void rtw8812a_do_iqk(struct rtw_dev *rtwdev) 789*a0ccc12fSBjoern A. Zeeb { 790*a0ccc12fSBjoern A. Zeeb static const u32 backup_macbb_reg[MACBB_REG_NUM_8812A] = { 791*a0ccc12fSBjoern A. Zeeb 0x520, 0x550, 0x808, 0xa04, 0x90c, 0xc00, 0xe00, 0x838, 0x82c 792*a0ccc12fSBjoern A. Zeeb }; 793*a0ccc12fSBjoern A. Zeeb static const u32 backup_afe_reg[AFE_REG_NUM_8812A] = { 794*a0ccc12fSBjoern A. Zeeb 0xc5c, 0xc60, 0xc64, 0xc68, 0xcb0, 0xcb4, 795*a0ccc12fSBjoern A. Zeeb 0xe5c, 0xe60, 0xe64, 0xe68, 0xeb0, 0xeb4 796*a0ccc12fSBjoern A. Zeeb }; 797*a0ccc12fSBjoern A. Zeeb static const u32 backup_rf_reg[RF_REG_NUM_8812A] = { 798*a0ccc12fSBjoern A. Zeeb 0x65, 0x8f, 0x0 799*a0ccc12fSBjoern A. Zeeb }; 800*a0ccc12fSBjoern A. Zeeb u32 macbb_backup[MACBB_REG_NUM_8812A] = {}; 801*a0ccc12fSBjoern A. Zeeb u32 afe_backup[AFE_REG_NUM_8812A] = {}; 802*a0ccc12fSBjoern A. Zeeb u32 rfa_backup[RF_REG_NUM_8812A] = {}; 803*a0ccc12fSBjoern A. Zeeb u32 rfb_backup[RF_REG_NUM_8812A] = {}; 804*a0ccc12fSBjoern A. Zeeb u32 reg_cb8, reg_eb8; 805*a0ccc12fSBjoern A. Zeeb 806*a0ccc12fSBjoern A. Zeeb rtw88xxa_iqk_backup_mac_bb(rtwdev, macbb_backup, 807*a0ccc12fSBjoern A. Zeeb backup_macbb_reg, MACBB_REG_NUM_8812A); 808*a0ccc12fSBjoern A. Zeeb 809*a0ccc12fSBjoern A. Zeeb rtw_write32_set(rtwdev, REG_CCASEL, BIT(31)); 810*a0ccc12fSBjoern A. Zeeb reg_cb8 = rtw_read32(rtwdev, REG_RFECTL_A); 811*a0ccc12fSBjoern A. Zeeb reg_eb8 = rtw_read32(rtwdev, REG_RFECTL_B); 812*a0ccc12fSBjoern A. Zeeb rtw_write32_clr(rtwdev, REG_CCASEL, BIT(31)); 813*a0ccc12fSBjoern A. Zeeb 814*a0ccc12fSBjoern A. Zeeb rtw88xxa_iqk_backup_afe(rtwdev, afe_backup, 815*a0ccc12fSBjoern A. Zeeb backup_afe_reg, AFE_REG_NUM_8812A); 816*a0ccc12fSBjoern A. Zeeb rtw8812a_iqk_backup_rf(rtwdev, rfa_backup, rfb_backup, 817*a0ccc12fSBjoern A. Zeeb backup_rf_reg, RF_REG_NUM_8812A); 818*a0ccc12fSBjoern A. Zeeb 819*a0ccc12fSBjoern A. Zeeb rtw88xxa_iqk_configure_mac(rtwdev); 820*a0ccc12fSBjoern A. Zeeb 821*a0ccc12fSBjoern A. Zeeb rtw8812a_iqk(rtwdev); 822*a0ccc12fSBjoern A. Zeeb 823*a0ccc12fSBjoern A. Zeeb rtw8812a_iqk_restore_rf(rtwdev, RF_PATH_A, backup_rf_reg, 824*a0ccc12fSBjoern A. Zeeb rfa_backup, RF_REG_NUM_8812A); 825*a0ccc12fSBjoern A. Zeeb rtw8812a_iqk_restore_rf(rtwdev, RF_PATH_B, backup_rf_reg, 826*a0ccc12fSBjoern A. Zeeb rfb_backup, RF_REG_NUM_8812A); 827*a0ccc12fSBjoern A. Zeeb 828*a0ccc12fSBjoern A. Zeeb rtw8812a_iqk_restore_afe(rtwdev, afe_backup, 829*a0ccc12fSBjoern A. Zeeb backup_afe_reg, AFE_REG_NUM_8812A); 830*a0ccc12fSBjoern A. Zeeb 831*a0ccc12fSBjoern A. Zeeb rtw_write32_set(rtwdev, REG_CCASEL, BIT(31)); 832*a0ccc12fSBjoern A. Zeeb rtw_write32(rtwdev, REG_RFECTL_A, reg_cb8); 833*a0ccc12fSBjoern A. Zeeb rtw_write32(rtwdev, REG_RFECTL_B, reg_eb8); 834*a0ccc12fSBjoern A. Zeeb rtw_write32_clr(rtwdev, REG_CCASEL, BIT(31)); 835*a0ccc12fSBjoern A. Zeeb 836*a0ccc12fSBjoern A. Zeeb rtw88xxa_iqk_restore_mac_bb(rtwdev, macbb_backup, 837*a0ccc12fSBjoern A. Zeeb backup_macbb_reg, MACBB_REG_NUM_8812A); 838*a0ccc12fSBjoern A. Zeeb } 839*a0ccc12fSBjoern A. Zeeb 840*a0ccc12fSBjoern A. Zeeb static void rtw8812a_phy_calibration(struct rtw_dev *rtwdev) 841*a0ccc12fSBjoern A. Zeeb { 842*a0ccc12fSBjoern A. Zeeb u8 channel = rtwdev->hal.current_channel; 843*a0ccc12fSBjoern A. Zeeb 844*a0ccc12fSBjoern A. Zeeb rtw8812a_do_iqk(rtwdev); 845*a0ccc12fSBjoern A. Zeeb 846*a0ccc12fSBjoern A. Zeeb /* The official driver wants to do this after connecting 847*a0ccc12fSBjoern A. Zeeb * but before first writing a new igi (phydm_get_new_igi). 848*a0ccc12fSBjoern A. Zeeb * Here seems close enough. 849*a0ccc12fSBjoern A. Zeeb */ 850*a0ccc12fSBjoern A. Zeeb if (channel >= 36 && channel <= 64) 851*a0ccc12fSBjoern A. Zeeb rtw_load_table(rtwdev, &rtw8812a_agc_diff_lb_tbl); 852*a0ccc12fSBjoern A. Zeeb else if (channel >= 100) 853*a0ccc12fSBjoern A. Zeeb rtw_load_table(rtwdev, &rtw8812a_agc_diff_hb_tbl); 854*a0ccc12fSBjoern A. Zeeb } 855*a0ccc12fSBjoern A. Zeeb 856*a0ccc12fSBjoern A. Zeeb static void rtw8812a_pwr_track(struct rtw_dev *rtwdev) 857*a0ccc12fSBjoern A. Zeeb { 858*a0ccc12fSBjoern A. Zeeb struct rtw_dm_info *dm_info = &rtwdev->dm_info; 859*a0ccc12fSBjoern A. Zeeb 860*a0ccc12fSBjoern A. Zeeb if (!dm_info->pwr_trk_triggered) { 861*a0ccc12fSBjoern A. Zeeb rtw_write_rf(rtwdev, RF_PATH_A, RF_T_METER, 862*a0ccc12fSBjoern A. Zeeb GENMASK(17, 16), 0x03); 863*a0ccc12fSBjoern A. Zeeb dm_info->pwr_trk_triggered = true; 864*a0ccc12fSBjoern A. Zeeb return; 865*a0ccc12fSBjoern A. Zeeb } 866*a0ccc12fSBjoern A. Zeeb 867*a0ccc12fSBjoern A. Zeeb rtw88xxa_phy_pwrtrack(rtwdev, rtw8812a_do_lck, rtw8812a_do_iqk); 868*a0ccc12fSBjoern A. Zeeb dm_info->pwr_trk_triggered = false; 869*a0ccc12fSBjoern A. Zeeb } 870*a0ccc12fSBjoern A. Zeeb 871*a0ccc12fSBjoern A. Zeeb static void rtw8812a_led_set(struct led_classdev *led, 872*a0ccc12fSBjoern A. Zeeb enum led_brightness brightness) 873*a0ccc12fSBjoern A. Zeeb { 874*a0ccc12fSBjoern A. Zeeb struct rtw_dev *rtwdev = container_of(led, struct rtw_dev, led_cdev); 875*a0ccc12fSBjoern A. Zeeb u8 ledcfg; 876*a0ccc12fSBjoern A. Zeeb 877*a0ccc12fSBjoern A. Zeeb ledcfg = rtw_read8(rtwdev, REG_LED_CFG); 878*a0ccc12fSBjoern A. Zeeb ledcfg &= BIT(6) | BIT(4); 879*a0ccc12fSBjoern A. Zeeb ledcfg |= BIT(5); 880*a0ccc12fSBjoern A. Zeeb 881*a0ccc12fSBjoern A. Zeeb if (brightness == LED_OFF) 882*a0ccc12fSBjoern A. Zeeb ledcfg |= BIT(3); 883*a0ccc12fSBjoern A. Zeeb 884*a0ccc12fSBjoern A. Zeeb rtw_write8(rtwdev, REG_LED_CFG, ledcfg); 885*a0ccc12fSBjoern A. Zeeb } 886*a0ccc12fSBjoern A. Zeeb 887*a0ccc12fSBjoern A. Zeeb static void rtw8812a_fill_txdesc_checksum(struct rtw_dev *rtwdev, 888*a0ccc12fSBjoern A. Zeeb struct rtw_tx_pkt_info *pkt_info, 889*a0ccc12fSBjoern A. Zeeb u8 *txdesc) 890*a0ccc12fSBjoern A. Zeeb { 891*a0ccc12fSBjoern A. Zeeb fill_txdesc_checksum_common(txdesc, 16); 892*a0ccc12fSBjoern A. Zeeb } 893*a0ccc12fSBjoern A. Zeeb 894*a0ccc12fSBjoern A. Zeeb static void rtw8812a_coex_cfg_init(struct rtw_dev *rtwdev) 895*a0ccc12fSBjoern A. Zeeb { 896*a0ccc12fSBjoern A. Zeeb } 897*a0ccc12fSBjoern A. Zeeb 898*a0ccc12fSBjoern A. Zeeb static void rtw8812a_coex_cfg_gnt_fix(struct rtw_dev *rtwdev) 899*a0ccc12fSBjoern A. Zeeb { 900*a0ccc12fSBjoern A. Zeeb } 901*a0ccc12fSBjoern A. Zeeb 902*a0ccc12fSBjoern A. Zeeb static void rtw8821a_coex_cfg_rfe_type(struct rtw_dev *rtwdev) 903*a0ccc12fSBjoern A. Zeeb { 904*a0ccc12fSBjoern A. Zeeb } 905*a0ccc12fSBjoern A. Zeeb 906*a0ccc12fSBjoern A. Zeeb static void rtw8821a_coex_cfg_wl_tx_power(struct rtw_dev *rtwdev, u8 wl_pwr) 907*a0ccc12fSBjoern A. Zeeb { 908*a0ccc12fSBjoern A. Zeeb } 909*a0ccc12fSBjoern A. Zeeb 910*a0ccc12fSBjoern A. Zeeb static void rtw8821a_coex_cfg_wl_rx_gain(struct rtw_dev *rtwdev, bool low_gain) 911*a0ccc12fSBjoern A. Zeeb { 912*a0ccc12fSBjoern A. Zeeb } 913*a0ccc12fSBjoern A. Zeeb 914*a0ccc12fSBjoern A. Zeeb static const struct rtw_chip_ops rtw8812a_ops = { 915*a0ccc12fSBjoern A. Zeeb .power_on = rtw88xxa_power_on, 916*a0ccc12fSBjoern A. Zeeb .power_off = rtw8812a_power_off, 917*a0ccc12fSBjoern A. Zeeb .phy_set_param = NULL, 918*a0ccc12fSBjoern A. Zeeb .read_efuse = rtw88xxa_read_efuse, 919*a0ccc12fSBjoern A. Zeeb .query_phy_status = rtw8812a_query_phy_status, 920*a0ccc12fSBjoern A. Zeeb .set_channel = rtw88xxa_set_channel, 921*a0ccc12fSBjoern A. Zeeb .mac_init = NULL, 922*a0ccc12fSBjoern A. Zeeb .read_rf = rtw88xxa_phy_read_rf, 923*a0ccc12fSBjoern A. Zeeb .write_rf = rtw_phy_write_rf_reg_sipi, 924*a0ccc12fSBjoern A. Zeeb .set_antenna = NULL, 925*a0ccc12fSBjoern A. Zeeb .set_tx_power_index = rtw88xxa_set_tx_power_index, 926*a0ccc12fSBjoern A. Zeeb .cfg_ldo25 = rtw8812a_cfg_ldo25, 927*a0ccc12fSBjoern A. Zeeb .efuse_grant = rtw88xxa_efuse_grant, 928*a0ccc12fSBjoern A. Zeeb .false_alarm_statistics = rtw88xxa_false_alarm_statistics, 929*a0ccc12fSBjoern A. Zeeb .phy_calibration = rtw8812a_phy_calibration, 930*a0ccc12fSBjoern A. Zeeb .cck_pd_set = rtw88xxa_phy_cck_pd_set, 931*a0ccc12fSBjoern A. Zeeb .pwr_track = rtw8812a_pwr_track, 932*a0ccc12fSBjoern A. Zeeb .config_bfee = NULL, 933*a0ccc12fSBjoern A. Zeeb .set_gid_table = NULL, 934*a0ccc12fSBjoern A. Zeeb .cfg_csi_rate = NULL, 935*a0ccc12fSBjoern A. Zeeb .led_set = rtw8812a_led_set, 936*a0ccc12fSBjoern A. Zeeb .fill_txdesc_checksum = rtw8812a_fill_txdesc_checksum, 937*a0ccc12fSBjoern A. Zeeb .coex_set_init = rtw8812a_coex_cfg_init, 938*a0ccc12fSBjoern A. Zeeb .coex_set_ant_switch = NULL, 939*a0ccc12fSBjoern A. Zeeb .coex_set_gnt_fix = rtw8812a_coex_cfg_gnt_fix, 940*a0ccc12fSBjoern A. Zeeb .coex_set_gnt_debug = NULL, 941*a0ccc12fSBjoern A. Zeeb .coex_set_rfe_type = rtw8821a_coex_cfg_rfe_type, 942*a0ccc12fSBjoern A. Zeeb .coex_set_wl_tx_power = rtw8821a_coex_cfg_wl_tx_power, 943*a0ccc12fSBjoern A. Zeeb .coex_set_wl_rx_gain = rtw8821a_coex_cfg_wl_rx_gain, 944*a0ccc12fSBjoern A. Zeeb }; 945*a0ccc12fSBjoern A. Zeeb 946*a0ccc12fSBjoern A. Zeeb static const struct rtw_page_table page_table_8812a[] = { 947*a0ccc12fSBjoern A. Zeeb /* hq_num, nq_num, lq_num, exq_num, gapq_num */ 948*a0ccc12fSBjoern A. Zeeb {0, 0, 0, 0, 0}, /* SDIO */ 949*a0ccc12fSBjoern A. Zeeb {0, 0, 0, 0, 0}, /* PCI */ 950*a0ccc12fSBjoern A. Zeeb {16, 0, 0, 0, 1}, /* 2 bulk out endpoints */ 951*a0ccc12fSBjoern A. Zeeb {16, 0, 16, 0, 1}, /* 3 bulk out endpoints */ 952*a0ccc12fSBjoern A. Zeeb {16, 0, 16, 0, 1}, /* 4 bulk out endpoints */ 953*a0ccc12fSBjoern A. Zeeb }; 954*a0ccc12fSBjoern A. Zeeb 955*a0ccc12fSBjoern A. Zeeb static const struct rtw_rqpn rqpn_table_8812a[] = { 956*a0ccc12fSBjoern A. Zeeb {RTW_DMA_MAPPING_NORMAL, RTW_DMA_MAPPING_NORMAL, 957*a0ccc12fSBjoern A. Zeeb RTW_DMA_MAPPING_LOW, RTW_DMA_MAPPING_LOW, 958*a0ccc12fSBjoern A. Zeeb RTW_DMA_MAPPING_EXTRA, RTW_DMA_MAPPING_HIGH}, 959*a0ccc12fSBjoern A. Zeeb 960*a0ccc12fSBjoern A. Zeeb {RTW_DMA_MAPPING_NORMAL, RTW_DMA_MAPPING_NORMAL, 961*a0ccc12fSBjoern A. Zeeb RTW_DMA_MAPPING_LOW, RTW_DMA_MAPPING_LOW, 962*a0ccc12fSBjoern A. Zeeb RTW_DMA_MAPPING_EXTRA, RTW_DMA_MAPPING_HIGH}, 963*a0ccc12fSBjoern A. Zeeb 964*a0ccc12fSBjoern A. Zeeb {RTW_DMA_MAPPING_HIGH, RTW_DMA_MAPPING_HIGH, 965*a0ccc12fSBjoern A. Zeeb RTW_DMA_MAPPING_NORMAL, RTW_DMA_MAPPING_NORMAL, 966*a0ccc12fSBjoern A. Zeeb RTW_DMA_MAPPING_HIGH, RTW_DMA_MAPPING_HIGH}, 967*a0ccc12fSBjoern A. Zeeb 968*a0ccc12fSBjoern A. Zeeb {RTW_DMA_MAPPING_HIGH, RTW_DMA_MAPPING_NORMAL, 969*a0ccc12fSBjoern A. Zeeb RTW_DMA_MAPPING_LOW, RTW_DMA_MAPPING_LOW, 970*a0ccc12fSBjoern A. Zeeb RTW_DMA_MAPPING_HIGH, RTW_DMA_MAPPING_HIGH}, 971*a0ccc12fSBjoern A. Zeeb 972*a0ccc12fSBjoern A. Zeeb {RTW_DMA_MAPPING_NORMAL, RTW_DMA_MAPPING_NORMAL, 973*a0ccc12fSBjoern A. Zeeb RTW_DMA_MAPPING_LOW, RTW_DMA_MAPPING_LOW, 974*a0ccc12fSBjoern A. Zeeb RTW_DMA_MAPPING_EXTRA, RTW_DMA_MAPPING_HIGH}, 975*a0ccc12fSBjoern A. Zeeb }; 976*a0ccc12fSBjoern A. Zeeb 977*a0ccc12fSBjoern A. Zeeb static const struct rtw_prioq_addrs prioq_addrs_8812a = { 978*a0ccc12fSBjoern A. Zeeb .prio[RTW_DMA_MAPPING_EXTRA] = { 979*a0ccc12fSBjoern A. Zeeb .rsvd = REG_RQPN_NPQ + 2, .avail = REG_RQPN_NPQ + 3, 980*a0ccc12fSBjoern A. Zeeb }, 981*a0ccc12fSBjoern A. Zeeb .prio[RTW_DMA_MAPPING_LOW] = { 982*a0ccc12fSBjoern A. Zeeb .rsvd = REG_RQPN + 1, .avail = REG_FIFOPAGE_CTRL_2 + 1, 983*a0ccc12fSBjoern A. Zeeb }, 984*a0ccc12fSBjoern A. Zeeb .prio[RTW_DMA_MAPPING_NORMAL] = { 985*a0ccc12fSBjoern A. Zeeb .rsvd = REG_RQPN_NPQ, .avail = REG_RQPN_NPQ + 1, 986*a0ccc12fSBjoern A. Zeeb }, 987*a0ccc12fSBjoern A. Zeeb .prio[RTW_DMA_MAPPING_HIGH] = { 988*a0ccc12fSBjoern A. Zeeb .rsvd = REG_RQPN, .avail = REG_FIFOPAGE_CTRL_2, 989*a0ccc12fSBjoern A. Zeeb }, 990*a0ccc12fSBjoern A. Zeeb .wsize = false, 991*a0ccc12fSBjoern A. Zeeb }; 992*a0ccc12fSBjoern A. Zeeb 993*a0ccc12fSBjoern A. Zeeb static const struct rtw_hw_reg rtw8812a_dig[] = { 994*a0ccc12fSBjoern A. Zeeb [0] = { .addr = REG_RXIGI_A, .mask = 0x7f }, 995*a0ccc12fSBjoern A. Zeeb [1] = { .addr = REG_RXIGI_B, .mask = 0x7f }, 996*a0ccc12fSBjoern A. Zeeb }; 997*a0ccc12fSBjoern A. Zeeb 998*a0ccc12fSBjoern A. Zeeb static const struct rtw_rfe_def rtw8812a_rfe_defs[] = { 999*a0ccc12fSBjoern A. Zeeb [0] = { .phy_pg_tbl = &rtw8812a_bb_pg_tbl, 1000*a0ccc12fSBjoern A. Zeeb .txpwr_lmt_tbl = &rtw8812a_txpwr_lmt_tbl, 1001*a0ccc12fSBjoern A. Zeeb .pwr_track_tbl = &rtw8812a_rtw_pwr_track_tbl, }, 1002*a0ccc12fSBjoern A. Zeeb [1] = { .phy_pg_tbl = &rtw8812a_bb_pg_tbl, 1003*a0ccc12fSBjoern A. Zeeb .txpwr_lmt_tbl = &rtw8812a_txpwr_lmt_tbl, 1004*a0ccc12fSBjoern A. Zeeb .pwr_track_tbl = &rtw8812a_rtw_pwr_track_tbl, }, 1005*a0ccc12fSBjoern A. Zeeb [2] = { .phy_pg_tbl = &rtw8812a_bb_pg_tbl, 1006*a0ccc12fSBjoern A. Zeeb .txpwr_lmt_tbl = &rtw8812a_txpwr_lmt_tbl, 1007*a0ccc12fSBjoern A. Zeeb .pwr_track_tbl = &rtw8812a_rtw_pwr_track_tbl, }, 1008*a0ccc12fSBjoern A. Zeeb [3] = { .phy_pg_tbl = &rtw8812a_bb_pg_rfe3_tbl, 1009*a0ccc12fSBjoern A. Zeeb .txpwr_lmt_tbl = &rtw8812a_txpwr_lmt_tbl, 1010*a0ccc12fSBjoern A. Zeeb .pwr_track_tbl = &rtw8812a_rtw_pwr_track_rfe3_tbl, }, 1011*a0ccc12fSBjoern A. Zeeb }; 1012*a0ccc12fSBjoern A. Zeeb 1013*a0ccc12fSBjoern A. Zeeb static const u8 wl_rssi_step_8812a[] = {101, 45, 101, 40}; 1014*a0ccc12fSBjoern A. Zeeb static const u8 bt_rssi_step_8812a[] = {101, 101, 101, 101}; 1015*a0ccc12fSBjoern A. Zeeb 1016*a0ccc12fSBjoern A. Zeeb static const struct coex_rf_para rf_para_tx_8812a[] = { 1017*a0ccc12fSBjoern A. Zeeb {0, 0, false, 7}, /* for normal */ 1018*a0ccc12fSBjoern A. Zeeb {0, 20, false, 7}, /* for WL-CPT */ 1019*a0ccc12fSBjoern A. Zeeb {8, 17, true, 4}, 1020*a0ccc12fSBjoern A. Zeeb {7, 18, true, 4}, 1021*a0ccc12fSBjoern A. Zeeb {6, 19, true, 4}, 1022*a0ccc12fSBjoern A. Zeeb {5, 20, true, 4} 1023*a0ccc12fSBjoern A. Zeeb }; 1024*a0ccc12fSBjoern A. Zeeb 1025*a0ccc12fSBjoern A. Zeeb static const struct coex_rf_para rf_para_rx_8812a[] = { 1026*a0ccc12fSBjoern A. Zeeb {0, 0, false, 7}, /* for normal */ 1027*a0ccc12fSBjoern A. Zeeb {0, 20, false, 7}, /* for WL-CPT */ 1028*a0ccc12fSBjoern A. Zeeb {3, 24, true, 5}, 1029*a0ccc12fSBjoern A. Zeeb {2, 26, true, 5}, 1030*a0ccc12fSBjoern A. Zeeb {1, 27, true, 5}, 1031*a0ccc12fSBjoern A. Zeeb {0, 28, true, 5} 1032*a0ccc12fSBjoern A. Zeeb }; 1033*a0ccc12fSBjoern A. Zeeb 1034*a0ccc12fSBjoern A. Zeeb static_assert(ARRAY_SIZE(rf_para_tx_8812a) == ARRAY_SIZE(rf_para_rx_8812a)); 1035*a0ccc12fSBjoern A. Zeeb 1036*a0ccc12fSBjoern A. Zeeb const struct rtw_chip_info rtw8812a_hw_spec = { 1037*a0ccc12fSBjoern A. Zeeb .ops = &rtw8812a_ops, 1038*a0ccc12fSBjoern A. Zeeb .id = RTW_CHIP_TYPE_8812A, 1039*a0ccc12fSBjoern A. Zeeb .fw_name = "rtw88/rtw8812a_fw.bin", 1040*a0ccc12fSBjoern A. Zeeb .wlan_cpu = RTW_WCPU_11N, 1041*a0ccc12fSBjoern A. Zeeb .tx_pkt_desc_sz = 40, 1042*a0ccc12fSBjoern A. Zeeb .tx_buf_desc_sz = 16, 1043*a0ccc12fSBjoern A. Zeeb .rx_pkt_desc_sz = 24, 1044*a0ccc12fSBjoern A. Zeeb .rx_buf_desc_sz = 8, 1045*a0ccc12fSBjoern A. Zeeb .phy_efuse_size = 512, 1046*a0ccc12fSBjoern A. Zeeb .log_efuse_size = 512, 1047*a0ccc12fSBjoern A. Zeeb .ptct_efuse_size = 0, 1048*a0ccc12fSBjoern A. Zeeb .txff_size = 131072, 1049*a0ccc12fSBjoern A. Zeeb .rxff_size = 16128, 1050*a0ccc12fSBjoern A. Zeeb .rsvd_drv_pg_num = 9, 1051*a0ccc12fSBjoern A. Zeeb .txgi_factor = 1, 1052*a0ccc12fSBjoern A. Zeeb .is_pwr_by_rate_dec = true, 1053*a0ccc12fSBjoern A. Zeeb .max_power_index = 0x3f, 1054*a0ccc12fSBjoern A. Zeeb .csi_buf_pg_num = 0, 1055*a0ccc12fSBjoern A. Zeeb .band = RTW_BAND_2G | RTW_BAND_5G, 1056*a0ccc12fSBjoern A. Zeeb .page_size = 512, 1057*a0ccc12fSBjoern A. Zeeb .dig_min = 0x20, 1058*a0ccc12fSBjoern A. Zeeb .ht_supported = true, 1059*a0ccc12fSBjoern A. Zeeb .vht_supported = true, 1060*a0ccc12fSBjoern A. Zeeb .lps_deep_mode_supported = 0, 1061*a0ccc12fSBjoern A. Zeeb .sys_func_en = 0xFD, 1062*a0ccc12fSBjoern A. Zeeb .pwr_on_seq = card_enable_flow_8812a, 1063*a0ccc12fSBjoern A. Zeeb .pwr_off_seq = card_disable_flow_8812a, 1064*a0ccc12fSBjoern A. Zeeb .page_table = page_table_8812a, 1065*a0ccc12fSBjoern A. Zeeb .rqpn_table = rqpn_table_8812a, 1066*a0ccc12fSBjoern A. Zeeb .prioq_addrs = &prioq_addrs_8812a, 1067*a0ccc12fSBjoern A. Zeeb .intf_table = NULL, 1068*a0ccc12fSBjoern A. Zeeb .dig = rtw8812a_dig, 1069*a0ccc12fSBjoern A. Zeeb .rf_sipi_addr = {REG_LSSI_WRITE_A, REG_LSSI_WRITE_B}, 1070*a0ccc12fSBjoern A. Zeeb .ltecoex_addr = NULL, 1071*a0ccc12fSBjoern A. Zeeb .mac_tbl = &rtw8812a_mac_tbl, 1072*a0ccc12fSBjoern A. Zeeb .agc_tbl = &rtw8812a_agc_tbl, 1073*a0ccc12fSBjoern A. Zeeb .bb_tbl = &rtw8812a_bb_tbl, 1074*a0ccc12fSBjoern A. Zeeb .rf_tbl = {&rtw8812a_rf_a_tbl, &rtw8812a_rf_b_tbl}, 1075*a0ccc12fSBjoern A. Zeeb .rfe_defs = rtw8812a_rfe_defs, 1076*a0ccc12fSBjoern A. Zeeb .rfe_defs_size = ARRAY_SIZE(rtw8812a_rfe_defs), 1077*a0ccc12fSBjoern A. Zeeb .rx_ldpc = false, 1078*a0ccc12fSBjoern A. Zeeb .hw_feature_report = false, 1079*a0ccc12fSBjoern A. Zeeb .c2h_ra_report_size = 4, 1080*a0ccc12fSBjoern A. Zeeb .old_datarate_fb_limit = true, 1081*a0ccc12fSBjoern A. Zeeb .usb_tx_agg_desc_num = 1, 1082*a0ccc12fSBjoern A. Zeeb .iqk_threshold = 8, 1083*a0ccc12fSBjoern A. Zeeb .ampdu_density = IEEE80211_HT_MPDU_DENSITY_16, 1084*a0ccc12fSBjoern A. Zeeb .max_scan_ie_len = IEEE80211_MAX_DATA_LEN, 1085*a0ccc12fSBjoern A. Zeeb 1086*a0ccc12fSBjoern A. Zeeb .coex_para_ver = 0, /* no coex code in 8812au driver */ 1087*a0ccc12fSBjoern A. Zeeb .bt_desired_ver = 0, 1088*a0ccc12fSBjoern A. Zeeb .scbd_support = false, 1089*a0ccc12fSBjoern A. Zeeb .new_scbd10_def = false, 1090*a0ccc12fSBjoern A. Zeeb .ble_hid_profile_support = false, 1091*a0ccc12fSBjoern A. Zeeb .wl_mimo_ps_support = false, 1092*a0ccc12fSBjoern A. Zeeb .pstdma_type = COEX_PSTDMA_FORCE_LPSOFF, 1093*a0ccc12fSBjoern A. Zeeb .bt_rssi_type = COEX_BTRSSI_RATIO, 1094*a0ccc12fSBjoern A. Zeeb .ant_isolation = 15, 1095*a0ccc12fSBjoern A. Zeeb .rssi_tolerance = 2, 1096*a0ccc12fSBjoern A. Zeeb .wl_rssi_step = wl_rssi_step_8812a, 1097*a0ccc12fSBjoern A. Zeeb .bt_rssi_step = bt_rssi_step_8812a, 1098*a0ccc12fSBjoern A. Zeeb .table_sant_num = 0, 1099*a0ccc12fSBjoern A. Zeeb .table_sant = NULL, 1100*a0ccc12fSBjoern A. Zeeb .table_nsant_num = 0, 1101*a0ccc12fSBjoern A. Zeeb .table_nsant = NULL, 1102*a0ccc12fSBjoern A. Zeeb .tdma_sant_num = 0, 1103*a0ccc12fSBjoern A. Zeeb .tdma_sant = NULL, 1104*a0ccc12fSBjoern A. Zeeb .tdma_nsant_num = 0, 1105*a0ccc12fSBjoern A. Zeeb .tdma_nsant = NULL, 1106*a0ccc12fSBjoern A. Zeeb .wl_rf_para_num = ARRAY_SIZE(rf_para_tx_8812a), 1107*a0ccc12fSBjoern A. Zeeb .wl_rf_para_tx = rf_para_tx_8812a, 1108*a0ccc12fSBjoern A. Zeeb .wl_rf_para_rx = rf_para_rx_8812a, 1109*a0ccc12fSBjoern A. Zeeb .bt_afh_span_bw20 = 0x20, 1110*a0ccc12fSBjoern A. Zeeb .bt_afh_span_bw40 = 0x30, 1111*a0ccc12fSBjoern A. Zeeb .afh_5g_num = 0, 1112*a0ccc12fSBjoern A. Zeeb .afh_5g = NULL, 1113*a0ccc12fSBjoern A. Zeeb .coex_info_hw_regs_num = 0, 1114*a0ccc12fSBjoern A. Zeeb .coex_info_hw_regs = NULL, 1115*a0ccc12fSBjoern A. Zeeb }; 1116*a0ccc12fSBjoern A. Zeeb EXPORT_SYMBOL(rtw8812a_hw_spec); 1117*a0ccc12fSBjoern A. Zeeb 1118*a0ccc12fSBjoern A. Zeeb MODULE_FIRMWARE("rtw88/rtw8812a_fw.bin"); 1119*a0ccc12fSBjoern A. Zeeb 1120*a0ccc12fSBjoern A. Zeeb MODULE_AUTHOR("Realtek Corporation"); 1121*a0ccc12fSBjoern A. Zeeb MODULE_DESCRIPTION("Realtek 802.11ac wireless 8812a driver"); 1122*a0ccc12fSBjoern A. Zeeb MODULE_LICENSE("Dual BSD/GPL"); 1123