1*b870b9d3SBitterblue Smith // SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause 2*b870b9d3SBitterblue Smith /* Copyright(c) 2024 Realtek Corporation 3*b870b9d3SBitterblue Smith */ 4*b870b9d3SBitterblue Smith 5*b870b9d3SBitterblue Smith #include <linux/usb.h> 6*b870b9d3SBitterblue Smith #include "main.h" 7*b870b9d3SBitterblue Smith #include "coex.h" 8*b870b9d3SBitterblue Smith #include "phy.h" 9*b870b9d3SBitterblue Smith #include "rtw88xxa.h" 10*b870b9d3SBitterblue Smith #include "mac.h" 11*b870b9d3SBitterblue Smith #include "reg.h" 12*b870b9d3SBitterblue Smith #include "sec.h" 13*b870b9d3SBitterblue Smith #include "debug.h" 14*b870b9d3SBitterblue Smith #include "bf.h" 15*b870b9d3SBitterblue Smith #include "efuse.h" 16*b870b9d3SBitterblue Smith #include "usb.h" 17*b870b9d3SBitterblue Smith 18*b870b9d3SBitterblue Smith void rtw88xxa_efuse_grant(struct rtw_dev *rtwdev, bool on) 19*b870b9d3SBitterblue Smith { 20*b870b9d3SBitterblue Smith if (on) { 21*b870b9d3SBitterblue Smith rtw_write8(rtwdev, REG_EFUSE_ACCESS, EFUSE_ACCESS_ON); 22*b870b9d3SBitterblue Smith 23*b870b9d3SBitterblue Smith rtw_write16_set(rtwdev, REG_SYS_FUNC_EN, BIT_FEN_ELDR); 24*b870b9d3SBitterblue Smith rtw_write16_set(rtwdev, REG_SYS_CLKR, 25*b870b9d3SBitterblue Smith BIT_LOADER_CLK_EN | BIT_ANA8M); 26*b870b9d3SBitterblue Smith } else { 27*b870b9d3SBitterblue Smith rtw_write8(rtwdev, REG_EFUSE_ACCESS, EFUSE_ACCESS_OFF); 28*b870b9d3SBitterblue Smith } 29*b870b9d3SBitterblue Smith } 30*b870b9d3SBitterblue Smith EXPORT_SYMBOL(rtw88xxa_efuse_grant); 31*b870b9d3SBitterblue Smith 32*b870b9d3SBitterblue Smith static void rtw8812a_read_amplifier_type(struct rtw_dev *rtwdev) 33*b870b9d3SBitterblue Smith { 34*b870b9d3SBitterblue Smith struct rtw_efuse *efuse = &rtwdev->efuse; 35*b870b9d3SBitterblue Smith 36*b870b9d3SBitterblue Smith efuse->ext_pa_2g = (efuse->pa_type_2g & BIT(5)) && 37*b870b9d3SBitterblue Smith (efuse->pa_type_2g & BIT(4)); 38*b870b9d3SBitterblue Smith efuse->ext_lna_2g = (efuse->lna_type_2g & BIT(7)) && 39*b870b9d3SBitterblue Smith (efuse->lna_type_2g & BIT(3)); 40*b870b9d3SBitterblue Smith 41*b870b9d3SBitterblue Smith efuse->ext_pa_5g = (efuse->pa_type_5g & BIT(1)) && 42*b870b9d3SBitterblue Smith (efuse->pa_type_5g & BIT(0)); 43*b870b9d3SBitterblue Smith efuse->ext_lna_5g = (efuse->lna_type_5g & BIT(7)) && 44*b870b9d3SBitterblue Smith (efuse->lna_type_5g & BIT(3)); 45*b870b9d3SBitterblue Smith 46*b870b9d3SBitterblue Smith /* For rtw_phy_cond2: */ 47*b870b9d3SBitterblue Smith if (efuse->ext_pa_2g) { 48*b870b9d3SBitterblue Smith u8 ext_type_pa_2g_a = u8_get_bits(efuse->lna_type_2g, BIT(2)); 49*b870b9d3SBitterblue Smith u8 ext_type_pa_2g_b = u8_get_bits(efuse->lna_type_2g, BIT(6)); 50*b870b9d3SBitterblue Smith 51*b870b9d3SBitterblue Smith efuse->gpa_type = (ext_type_pa_2g_b << 2) | ext_type_pa_2g_a; 52*b870b9d3SBitterblue Smith } 53*b870b9d3SBitterblue Smith 54*b870b9d3SBitterblue Smith if (efuse->ext_pa_5g) { 55*b870b9d3SBitterblue Smith u8 ext_type_pa_5g_a = u8_get_bits(efuse->lna_type_5g, BIT(2)); 56*b870b9d3SBitterblue Smith u8 ext_type_pa_5g_b = u8_get_bits(efuse->lna_type_5g, BIT(6)); 57*b870b9d3SBitterblue Smith 58*b870b9d3SBitterblue Smith efuse->apa_type = (ext_type_pa_5g_b << 2) | ext_type_pa_5g_a; 59*b870b9d3SBitterblue Smith } 60*b870b9d3SBitterblue Smith 61*b870b9d3SBitterblue Smith if (efuse->ext_lna_2g) { 62*b870b9d3SBitterblue Smith u8 ext_type_lna_2g_a = u8_get_bits(efuse->lna_type_2g, 63*b870b9d3SBitterblue Smith BIT(1) | BIT(0)); 64*b870b9d3SBitterblue Smith u8 ext_type_lna_2g_b = u8_get_bits(efuse->lna_type_2g, 65*b870b9d3SBitterblue Smith BIT(5) | BIT(4)); 66*b870b9d3SBitterblue Smith 67*b870b9d3SBitterblue Smith efuse->glna_type = (ext_type_lna_2g_b << 2) | ext_type_lna_2g_a; 68*b870b9d3SBitterblue Smith } 69*b870b9d3SBitterblue Smith 70*b870b9d3SBitterblue Smith if (efuse->ext_lna_5g) { 71*b870b9d3SBitterblue Smith u8 ext_type_lna_5g_a = u8_get_bits(efuse->lna_type_5g, 72*b870b9d3SBitterblue Smith BIT(1) | BIT(0)); 73*b870b9d3SBitterblue Smith u8 ext_type_lna_5g_b = u8_get_bits(efuse->lna_type_5g, 74*b870b9d3SBitterblue Smith BIT(5) | BIT(4)); 75*b870b9d3SBitterblue Smith 76*b870b9d3SBitterblue Smith efuse->alna_type = (ext_type_lna_5g_b << 2) | ext_type_lna_5g_a; 77*b870b9d3SBitterblue Smith } 78*b870b9d3SBitterblue Smith } 79*b870b9d3SBitterblue Smith 80*b870b9d3SBitterblue Smith static void rtw8812a_read_rfe_type(struct rtw_dev *rtwdev, 81*b870b9d3SBitterblue Smith struct rtw88xxa_efuse *map) 82*b870b9d3SBitterblue Smith { 83*b870b9d3SBitterblue Smith struct rtw_efuse *efuse = &rtwdev->efuse; 84*b870b9d3SBitterblue Smith 85*b870b9d3SBitterblue Smith if (map->rfe_option == 0xff) { 86*b870b9d3SBitterblue Smith if (rtwdev->hci.type == RTW_HCI_TYPE_USB) 87*b870b9d3SBitterblue Smith efuse->rfe_option = 0; 88*b870b9d3SBitterblue Smith else if (rtwdev->hci.type == RTW_HCI_TYPE_PCIE) 89*b870b9d3SBitterblue Smith efuse->rfe_option = 2; 90*b870b9d3SBitterblue Smith else 91*b870b9d3SBitterblue Smith efuse->rfe_option = 4; 92*b870b9d3SBitterblue Smith } else if (map->rfe_option & BIT(7)) { 93*b870b9d3SBitterblue Smith if (efuse->ext_lna_5g) { 94*b870b9d3SBitterblue Smith if (efuse->ext_pa_5g) { 95*b870b9d3SBitterblue Smith if (efuse->ext_lna_2g && efuse->ext_pa_2g) 96*b870b9d3SBitterblue Smith efuse->rfe_option = 3; 97*b870b9d3SBitterblue Smith else 98*b870b9d3SBitterblue Smith efuse->rfe_option = 0; 99*b870b9d3SBitterblue Smith } else { 100*b870b9d3SBitterblue Smith efuse->rfe_option = 2; 101*b870b9d3SBitterblue Smith } 102*b870b9d3SBitterblue Smith } else { 103*b870b9d3SBitterblue Smith efuse->rfe_option = 4; 104*b870b9d3SBitterblue Smith } 105*b870b9d3SBitterblue Smith } else { 106*b870b9d3SBitterblue Smith efuse->rfe_option = map->rfe_option & 0x3f; 107*b870b9d3SBitterblue Smith 108*b870b9d3SBitterblue Smith /* Due to other customer already use incorrect EFUSE map for 109*b870b9d3SBitterblue Smith * their product. We need to add workaround to prevent to 110*b870b9d3SBitterblue Smith * modify spec and notify all customer to revise the IC 0xca 111*b870b9d3SBitterblue Smith * content. 112*b870b9d3SBitterblue Smith */ 113*b870b9d3SBitterblue Smith if (efuse->rfe_option == 4 && 114*b870b9d3SBitterblue Smith (efuse->ext_pa_5g || efuse->ext_pa_2g || 115*b870b9d3SBitterblue Smith efuse->ext_lna_5g || efuse->ext_lna_2g)) { 116*b870b9d3SBitterblue Smith if (rtwdev->hci.type == RTW_HCI_TYPE_USB) 117*b870b9d3SBitterblue Smith efuse->rfe_option = 0; 118*b870b9d3SBitterblue Smith else if (rtwdev->hci.type == RTW_HCI_TYPE_PCIE) 119*b870b9d3SBitterblue Smith efuse->rfe_option = 2; 120*b870b9d3SBitterblue Smith } 121*b870b9d3SBitterblue Smith } 122*b870b9d3SBitterblue Smith } 123*b870b9d3SBitterblue Smith 124*b870b9d3SBitterblue Smith static void rtw88xxa_read_usb_type(struct rtw_dev *rtwdev) 125*b870b9d3SBitterblue Smith { 126*b870b9d3SBitterblue Smith struct rtw_efuse *efuse = &rtwdev->efuse; 127*b870b9d3SBitterblue Smith struct rtw_hal *hal = &rtwdev->hal; 128*b870b9d3SBitterblue Smith u8 antenna = 0; 129*b870b9d3SBitterblue Smith u8 wmode = 0; 130*b870b9d3SBitterblue Smith u8 val8, i; 131*b870b9d3SBitterblue Smith 132*b870b9d3SBitterblue Smith efuse->hw_cap.bw = BIT(RTW_CHANNEL_WIDTH_20) | 133*b870b9d3SBitterblue Smith BIT(RTW_CHANNEL_WIDTH_40) | 134*b870b9d3SBitterblue Smith BIT(RTW_CHANNEL_WIDTH_80); 135*b870b9d3SBitterblue Smith efuse->hw_cap.ptcl = EFUSE_HW_CAP_PTCL_VHT; 136*b870b9d3SBitterblue Smith 137*b870b9d3SBitterblue Smith if (rtwdev->chip->id == RTW_CHIP_TYPE_8821A) 138*b870b9d3SBitterblue Smith efuse->hw_cap.nss = 1; 139*b870b9d3SBitterblue Smith else 140*b870b9d3SBitterblue Smith efuse->hw_cap.nss = 2; 141*b870b9d3SBitterblue Smith 142*b870b9d3SBitterblue Smith if (rtwdev->chip->id == RTW_CHIP_TYPE_8821A) 143*b870b9d3SBitterblue Smith goto print_hw_cap; 144*b870b9d3SBitterblue Smith 145*b870b9d3SBitterblue Smith for (i = 0; i < 2; i++) { 146*b870b9d3SBitterblue Smith rtw_read8_physical_efuse(rtwdev, 1019 - i, &val8); 147*b870b9d3SBitterblue Smith 148*b870b9d3SBitterblue Smith antenna = u8_get_bits(val8, GENMASK(7, 5)); 149*b870b9d3SBitterblue Smith if (antenna) 150*b870b9d3SBitterblue Smith break; 151*b870b9d3SBitterblue Smith antenna = u8_get_bits(val8, GENMASK(3, 1)); 152*b870b9d3SBitterblue Smith if (antenna) 153*b870b9d3SBitterblue Smith break; 154*b870b9d3SBitterblue Smith } 155*b870b9d3SBitterblue Smith 156*b870b9d3SBitterblue Smith for (i = 0; i < 2; i++) { 157*b870b9d3SBitterblue Smith rtw_read8_physical_efuse(rtwdev, 1021 - i, &val8); 158*b870b9d3SBitterblue Smith 159*b870b9d3SBitterblue Smith wmode = u8_get_bits(val8, GENMASK(3, 2)); 160*b870b9d3SBitterblue Smith if (wmode) 161*b870b9d3SBitterblue Smith break; 162*b870b9d3SBitterblue Smith } 163*b870b9d3SBitterblue Smith 164*b870b9d3SBitterblue Smith if (antenna == 1) { 165*b870b9d3SBitterblue Smith rtw_info(rtwdev, "This RTL8812AU says it is 1T1R.\n"); 166*b870b9d3SBitterblue Smith 167*b870b9d3SBitterblue Smith efuse->hw_cap.nss = 1; 168*b870b9d3SBitterblue Smith hal->rf_type = RF_1T1R; 169*b870b9d3SBitterblue Smith hal->rf_path_num = 1; 170*b870b9d3SBitterblue Smith hal->rf_phy_num = 1; 171*b870b9d3SBitterblue Smith hal->antenna_tx = BB_PATH_A; 172*b870b9d3SBitterblue Smith hal->antenna_rx = BB_PATH_A; 173*b870b9d3SBitterblue Smith } else { 174*b870b9d3SBitterblue Smith /* Override rtw_chip_parameter_setup(). It detects 8812au as 1T1R. */ 175*b870b9d3SBitterblue Smith efuse->hw_cap.nss = 2; 176*b870b9d3SBitterblue Smith hal->rf_type = RF_2T2R; 177*b870b9d3SBitterblue Smith hal->rf_path_num = 2; 178*b870b9d3SBitterblue Smith hal->rf_phy_num = 2; 179*b870b9d3SBitterblue Smith hal->antenna_tx = BB_PATH_AB; 180*b870b9d3SBitterblue Smith hal->antenna_rx = BB_PATH_AB; 181*b870b9d3SBitterblue Smith 182*b870b9d3SBitterblue Smith if (antenna == 2 && wmode == 2) { 183*b870b9d3SBitterblue Smith rtw_info(rtwdev, "This RTL8812AU says it can't do VHT.\n"); 184*b870b9d3SBitterblue Smith 185*b870b9d3SBitterblue Smith /* Can't be EFUSE_HW_CAP_IGNORE and can't be 186*b870b9d3SBitterblue Smith * EFUSE_HW_CAP_PTCL_VHT, so make it 1. 187*b870b9d3SBitterblue Smith */ 188*b870b9d3SBitterblue Smith efuse->hw_cap.ptcl = 1; 189*b870b9d3SBitterblue Smith efuse->hw_cap.bw &= ~BIT(RTW_CHANNEL_WIDTH_80); 190*b870b9d3SBitterblue Smith } 191*b870b9d3SBitterblue Smith } 192*b870b9d3SBitterblue Smith 193*b870b9d3SBitterblue Smith print_hw_cap: 194*b870b9d3SBitterblue Smith rtw_dbg(rtwdev, RTW_DBG_EFUSE, 195*b870b9d3SBitterblue Smith "hw cap: hci=0x%02x, bw=0x%02x, ptcl=0x%02x, ant_num=%d, nss=%d\n", 196*b870b9d3SBitterblue Smith efuse->hw_cap.hci, efuse->hw_cap.bw, efuse->hw_cap.ptcl, 197*b870b9d3SBitterblue Smith efuse->hw_cap.ant_num, efuse->hw_cap.nss); 198*b870b9d3SBitterblue Smith } 199*b870b9d3SBitterblue Smith 200*b870b9d3SBitterblue Smith int rtw88xxa_read_efuse(struct rtw_dev *rtwdev, u8 *log_map) 201*b870b9d3SBitterblue Smith { 202*b870b9d3SBitterblue Smith const struct rtw_chip_info *chip = rtwdev->chip; 203*b870b9d3SBitterblue Smith struct rtw_efuse *efuse = &rtwdev->efuse; 204*b870b9d3SBitterblue Smith struct rtw88xxa_efuse *map; 205*b870b9d3SBitterblue Smith int i; 206*b870b9d3SBitterblue Smith 207*b870b9d3SBitterblue Smith if (chip->id == RTW_CHIP_TYPE_8812A) 208*b870b9d3SBitterblue Smith rtwdev->hal.cut_version += 1; 209*b870b9d3SBitterblue Smith 210*b870b9d3SBitterblue Smith if (rtw_dbg_is_enabled(rtwdev, RTW_DBG_EFUSE)) 211*b870b9d3SBitterblue Smith print_hex_dump(KERN_INFO, "", DUMP_PREFIX_OFFSET, 16, 1, 212*b870b9d3SBitterblue Smith log_map, chip->log_efuse_size, true); 213*b870b9d3SBitterblue Smith 214*b870b9d3SBitterblue Smith map = (struct rtw88xxa_efuse *)log_map; 215*b870b9d3SBitterblue Smith 216*b870b9d3SBitterblue Smith efuse->rf_board_option = map->rf_board_option; 217*b870b9d3SBitterblue Smith efuse->crystal_cap = map->xtal_k; 218*b870b9d3SBitterblue Smith if (efuse->crystal_cap == 0xff) 219*b870b9d3SBitterblue Smith efuse->crystal_cap = 0x20; 220*b870b9d3SBitterblue Smith efuse->pa_type_2g = map->pa_type; 221*b870b9d3SBitterblue Smith efuse->pa_type_5g = map->pa_type; 222*b870b9d3SBitterblue Smith efuse->lna_type_2g = map->lna_type_2g; 223*b870b9d3SBitterblue Smith efuse->lna_type_5g = map->lna_type_5g; 224*b870b9d3SBitterblue Smith if (chip->id == RTW_CHIP_TYPE_8812A) { 225*b870b9d3SBitterblue Smith rtw8812a_read_amplifier_type(rtwdev); 226*b870b9d3SBitterblue Smith rtw8812a_read_rfe_type(rtwdev, map); 227*b870b9d3SBitterblue Smith 228*b870b9d3SBitterblue Smith efuse->usb_mode_switch = u8_get_bits(map->usb_mode, BIT(1)); 229*b870b9d3SBitterblue Smith } 230*b870b9d3SBitterblue Smith efuse->channel_plan = map->channel_plan; 231*b870b9d3SBitterblue Smith efuse->country_code[0] = map->country_code[0]; 232*b870b9d3SBitterblue Smith efuse->country_code[1] = map->country_code[1]; 233*b870b9d3SBitterblue Smith efuse->bt_setting = map->rf_bt_setting; 234*b870b9d3SBitterblue Smith efuse->regd = map->rf_board_option & 0x7; 235*b870b9d3SBitterblue Smith efuse->thermal_meter[0] = map->thermal_meter; 236*b870b9d3SBitterblue Smith efuse->thermal_meter[1] = map->thermal_meter; 237*b870b9d3SBitterblue Smith efuse->thermal_meter_k = map->thermal_meter; 238*b870b9d3SBitterblue Smith efuse->tx_bb_swing_setting_2g = map->tx_bb_swing_setting_2g; 239*b870b9d3SBitterblue Smith efuse->tx_bb_swing_setting_5g = map->tx_bb_swing_setting_5g; 240*b870b9d3SBitterblue Smith 241*b870b9d3SBitterblue Smith rtw88xxa_read_usb_type(rtwdev); 242*b870b9d3SBitterblue Smith 243*b870b9d3SBitterblue Smith if (chip->id == RTW_CHIP_TYPE_8821A) 244*b870b9d3SBitterblue Smith efuse->btcoex = rtw_read32_mask(rtwdev, REG_WL_BT_PWR_CTRL, 245*b870b9d3SBitterblue Smith BIT_BT_FUNC_EN); 246*b870b9d3SBitterblue Smith else 247*b870b9d3SBitterblue Smith efuse->btcoex = (map->rf_board_option & 0xe0) == 0x20; 248*b870b9d3SBitterblue Smith efuse->share_ant = !!(efuse->bt_setting & BIT(0)); 249*b870b9d3SBitterblue Smith 250*b870b9d3SBitterblue Smith /* No antenna diversity because it's disabled in the vendor driver */ 251*b870b9d3SBitterblue Smith efuse->ant_div_cfg = 0; 252*b870b9d3SBitterblue Smith 253*b870b9d3SBitterblue Smith efuse->ant_div_type = map->rf_antenna_option; 254*b870b9d3SBitterblue Smith if (efuse->ant_div_type == 0xff) 255*b870b9d3SBitterblue Smith efuse->ant_div_type = 0x3; 256*b870b9d3SBitterblue Smith 257*b870b9d3SBitterblue Smith for (i = 0; i < 4; i++) 258*b870b9d3SBitterblue Smith efuse->txpwr_idx_table[i] = map->txpwr_idx_table[i]; 259*b870b9d3SBitterblue Smith 260*b870b9d3SBitterblue Smith switch (rtw_hci_type(rtwdev)) { 261*b870b9d3SBitterblue Smith case RTW_HCI_TYPE_USB: 262*b870b9d3SBitterblue Smith if (chip->id == RTW_CHIP_TYPE_8821A) 263*b870b9d3SBitterblue Smith ether_addr_copy(efuse->addr, map->rtw8821au.mac_addr); 264*b870b9d3SBitterblue Smith else 265*b870b9d3SBitterblue Smith ether_addr_copy(efuse->addr, map->rtw8812au.mac_addr); 266*b870b9d3SBitterblue Smith break; 267*b870b9d3SBitterblue Smith case RTW_HCI_TYPE_PCIE: 268*b870b9d3SBitterblue Smith case RTW_HCI_TYPE_SDIO: 269*b870b9d3SBitterblue Smith default: 270*b870b9d3SBitterblue Smith /* unsupported now */ 271*b870b9d3SBitterblue Smith return -EOPNOTSUPP; 272*b870b9d3SBitterblue Smith } 273*b870b9d3SBitterblue Smith 274*b870b9d3SBitterblue Smith return 0; 275*b870b9d3SBitterblue Smith } 276*b870b9d3SBitterblue Smith EXPORT_SYMBOL(rtw88xxa_read_efuse); 277*b870b9d3SBitterblue Smith 278*b870b9d3SBitterblue Smith static void rtw88xxa_reset_8051(struct rtw_dev *rtwdev) 279*b870b9d3SBitterblue Smith { 280*b870b9d3SBitterblue Smith const struct rtw_chip_info *chip = rtwdev->chip; 281*b870b9d3SBitterblue Smith u8 val8; 282*b870b9d3SBitterblue Smith 283*b870b9d3SBitterblue Smith /* Reset MCU IO Wrapper */ 284*b870b9d3SBitterblue Smith rtw_write8_clr(rtwdev, REG_RSV_CTRL, BIT(1)); 285*b870b9d3SBitterblue Smith if (chip->id == RTW_CHIP_TYPE_8812A) 286*b870b9d3SBitterblue Smith rtw_write8_clr(rtwdev, REG_RSV_CTRL + 1, BIT(3)); 287*b870b9d3SBitterblue Smith else 288*b870b9d3SBitterblue Smith rtw_write8_clr(rtwdev, REG_RSV_CTRL + 1, BIT(0)); 289*b870b9d3SBitterblue Smith 290*b870b9d3SBitterblue Smith val8 = rtw_read8(rtwdev, REG_SYS_FUNC_EN + 1); 291*b870b9d3SBitterblue Smith rtw_write8(rtwdev, REG_SYS_FUNC_EN + 1, val8 & ~BIT(2)); 292*b870b9d3SBitterblue Smith 293*b870b9d3SBitterblue Smith /* Enable MCU IO Wrapper */ 294*b870b9d3SBitterblue Smith rtw_write8_clr(rtwdev, REG_RSV_CTRL, BIT(1)); 295*b870b9d3SBitterblue Smith if (chip->id == RTW_CHIP_TYPE_8812A) 296*b870b9d3SBitterblue Smith rtw_write8_set(rtwdev, REG_RSV_CTRL + 1, BIT(3)); 297*b870b9d3SBitterblue Smith else 298*b870b9d3SBitterblue Smith rtw_write8_set(rtwdev, REG_RSV_CTRL + 1, BIT(0)); 299*b870b9d3SBitterblue Smith 300*b870b9d3SBitterblue Smith rtw_write8(rtwdev, REG_SYS_FUNC_EN + 1, val8 | BIT(2)); 301*b870b9d3SBitterblue Smith } 302*b870b9d3SBitterblue Smith 303*b870b9d3SBitterblue Smith /* A lightweight deinit function */ 304*b870b9d3SBitterblue Smith static void rtw88xxau_hw_reset(struct rtw_dev *rtwdev) 305*b870b9d3SBitterblue Smith { 306*b870b9d3SBitterblue Smith u8 val8; 307*b870b9d3SBitterblue Smith 308*b870b9d3SBitterblue Smith if (!(rtw_read8(rtwdev, REG_MCUFW_CTRL) & BIT_RAM_DL_SEL)) 309*b870b9d3SBitterblue Smith return; 310*b870b9d3SBitterblue Smith 311*b870b9d3SBitterblue Smith rtw88xxa_reset_8051(rtwdev); 312*b870b9d3SBitterblue Smith rtw_write8(rtwdev, REG_MCUFW_CTRL, 0x00); 313*b870b9d3SBitterblue Smith 314*b870b9d3SBitterblue Smith /* before BB reset should do clock gated */ 315*b870b9d3SBitterblue Smith rtw_write32_set(rtwdev, REG_FPGA0_XCD_RF_PARA, BIT(6)); 316*b870b9d3SBitterblue Smith 317*b870b9d3SBitterblue Smith /* reset BB */ 318*b870b9d3SBitterblue Smith rtw_write8_clr(rtwdev, REG_SYS_FUNC_EN, BIT(0) | BIT(1)); 319*b870b9d3SBitterblue Smith 320*b870b9d3SBitterblue Smith /* reset RF */ 321*b870b9d3SBitterblue Smith rtw_write8(rtwdev, REG_RF_CTRL, 0); 322*b870b9d3SBitterblue Smith 323*b870b9d3SBitterblue Smith /* reset TRX path */ 324*b870b9d3SBitterblue Smith rtw_write16(rtwdev, REG_CR, 0); 325*b870b9d3SBitterblue Smith 326*b870b9d3SBitterblue Smith /* reset MAC, reg0x5[1], auto FSM off */ 327*b870b9d3SBitterblue Smith rtw_write8_set(rtwdev, REG_APS_FSMCO + 1, APS_FSMCO_MAC_OFF >> 8); 328*b870b9d3SBitterblue Smith 329*b870b9d3SBitterblue Smith /* check if reg0x5[1] auto cleared */ 330*b870b9d3SBitterblue Smith if (read_poll_timeout_atomic(rtw_read8, val8, 331*b870b9d3SBitterblue Smith !(val8 & (APS_FSMCO_MAC_OFF >> 8)), 332*b870b9d3SBitterblue Smith 1, 5000, false, 333*b870b9d3SBitterblue Smith rtwdev, REG_APS_FSMCO + 1)) 334*b870b9d3SBitterblue Smith rtw_err(rtwdev, "%s: timed out waiting for 0x5[1]\n", __func__); 335*b870b9d3SBitterblue Smith 336*b870b9d3SBitterblue Smith /* reg0x5[0], auto FSM on */ 337*b870b9d3SBitterblue Smith val8 |= APS_FSMCO_MAC_ENABLE >> 8; 338*b870b9d3SBitterblue Smith rtw_write8(rtwdev, REG_APS_FSMCO + 1, val8); 339*b870b9d3SBitterblue Smith 340*b870b9d3SBitterblue Smith rtw_write8_clr(rtwdev, REG_SYS_FUNC_EN + 1, BIT(4) | BIT(7)); 341*b870b9d3SBitterblue Smith rtw_write8_set(rtwdev, REG_SYS_FUNC_EN + 1, BIT(4) | BIT(7)); 342*b870b9d3SBitterblue Smith } 343*b870b9d3SBitterblue Smith 344*b870b9d3SBitterblue Smith static int rtw88xxau_init_power_on(struct rtw_dev *rtwdev) 345*b870b9d3SBitterblue Smith { 346*b870b9d3SBitterblue Smith const struct rtw_chip_info *chip = rtwdev->chip; 347*b870b9d3SBitterblue Smith u16 val16; 348*b870b9d3SBitterblue Smith int ret; 349*b870b9d3SBitterblue Smith 350*b870b9d3SBitterblue Smith ret = rtw_pwr_seq_parser(rtwdev, chip->pwr_on_seq); 351*b870b9d3SBitterblue Smith if (ret) { 352*b870b9d3SBitterblue Smith rtw_err(rtwdev, "power on flow failed\n"); 353*b870b9d3SBitterblue Smith return ret; 354*b870b9d3SBitterblue Smith } 355*b870b9d3SBitterblue Smith 356*b870b9d3SBitterblue Smith rtw_write16(rtwdev, REG_CR, 0); 357*b870b9d3SBitterblue Smith val16 = BIT_HCI_TXDMA_EN | BIT_HCI_RXDMA_EN | BIT_TXDMA_EN | 358*b870b9d3SBitterblue Smith BIT_RXDMA_EN | BIT_PROTOCOL_EN | BIT_SCHEDULE_EN | 359*b870b9d3SBitterblue Smith BIT_MAC_SEC_EN | BIT_32K_CAL_TMR_EN; 360*b870b9d3SBitterblue Smith rtw_write16_set(rtwdev, REG_CR, val16); 361*b870b9d3SBitterblue Smith 362*b870b9d3SBitterblue Smith if (chip->id == RTW_CHIP_TYPE_8821A) { 363*b870b9d3SBitterblue Smith if (rtw_read8(rtwdev, REG_SYS_CFG1 + 3) & BIT(0)) 364*b870b9d3SBitterblue Smith rtw_write8_set(rtwdev, REG_LDO_SWR_CTRL, BIT(6)); 365*b870b9d3SBitterblue Smith } 366*b870b9d3SBitterblue Smith 367*b870b9d3SBitterblue Smith return ret; 368*b870b9d3SBitterblue Smith } 369*b870b9d3SBitterblue Smith 370*b870b9d3SBitterblue Smith static int rtw88xxa_llt_write(struct rtw_dev *rtwdev, u32 address, u32 data) 371*b870b9d3SBitterblue Smith { 372*b870b9d3SBitterblue Smith u32 value = BIT_LLT_WRITE_ACCESS | (address << 8) | data; 373*b870b9d3SBitterblue Smith int count = 0; 374*b870b9d3SBitterblue Smith 375*b870b9d3SBitterblue Smith rtw_write32(rtwdev, REG_LLT_INIT, value); 376*b870b9d3SBitterblue Smith 377*b870b9d3SBitterblue Smith do { 378*b870b9d3SBitterblue Smith if (!rtw_read32_mask(rtwdev, REG_LLT_INIT, BIT(31) | BIT(30))) 379*b870b9d3SBitterblue Smith break; 380*b870b9d3SBitterblue Smith 381*b870b9d3SBitterblue Smith if (count > 20) { 382*b870b9d3SBitterblue Smith rtw_err(rtwdev, "Failed to poll write LLT done at %d!\n", 383*b870b9d3SBitterblue Smith address); 384*b870b9d3SBitterblue Smith return -EBUSY; 385*b870b9d3SBitterblue Smith } 386*b870b9d3SBitterblue Smith } while (++count); 387*b870b9d3SBitterblue Smith 388*b870b9d3SBitterblue Smith return 0; 389*b870b9d3SBitterblue Smith } 390*b870b9d3SBitterblue Smith 391*b870b9d3SBitterblue Smith static int rtw88xxa_llt_init(struct rtw_dev *rtwdev, u32 boundary) 392*b870b9d3SBitterblue Smith { 393*b870b9d3SBitterblue Smith u32 last_entry = 255; 394*b870b9d3SBitterblue Smith int status = 0; 395*b870b9d3SBitterblue Smith u32 i; 396*b870b9d3SBitterblue Smith 397*b870b9d3SBitterblue Smith for (i = 0; i < boundary - 1; i++) { 398*b870b9d3SBitterblue Smith status = rtw88xxa_llt_write(rtwdev, i, i + 1); 399*b870b9d3SBitterblue Smith if (status) 400*b870b9d3SBitterblue Smith return status; 401*b870b9d3SBitterblue Smith } 402*b870b9d3SBitterblue Smith 403*b870b9d3SBitterblue Smith status = rtw88xxa_llt_write(rtwdev, boundary - 1, 0xFF); 404*b870b9d3SBitterblue Smith if (status) 405*b870b9d3SBitterblue Smith return status; 406*b870b9d3SBitterblue Smith 407*b870b9d3SBitterblue Smith for (i = boundary; i < last_entry; i++) { 408*b870b9d3SBitterblue Smith status = rtw88xxa_llt_write(rtwdev, i, i + 1); 409*b870b9d3SBitterblue Smith if (status) 410*b870b9d3SBitterblue Smith return status; 411*b870b9d3SBitterblue Smith } 412*b870b9d3SBitterblue Smith 413*b870b9d3SBitterblue Smith status = rtw88xxa_llt_write(rtwdev, last_entry, boundary); 414*b870b9d3SBitterblue Smith 415*b870b9d3SBitterblue Smith return status; 416*b870b9d3SBitterblue Smith } 417*b870b9d3SBitterblue Smith 418*b870b9d3SBitterblue Smith static void rtw88xxau_init_queue_reserved_page(struct rtw_dev *rtwdev) 419*b870b9d3SBitterblue Smith { 420*b870b9d3SBitterblue Smith const struct rtw_chip_info *chip = rtwdev->chip; 421*b870b9d3SBitterblue Smith struct rtw_fifo_conf *fifo = &rtwdev->fifo; 422*b870b9d3SBitterblue Smith const struct rtw_page_table *pg_tbl = NULL; 423*b870b9d3SBitterblue Smith u16 pubq_num; 424*b870b9d3SBitterblue Smith u32 val32; 425*b870b9d3SBitterblue Smith 426*b870b9d3SBitterblue Smith switch (rtw_hci_type(rtwdev)) { 427*b870b9d3SBitterblue Smith case RTW_HCI_TYPE_PCIE: 428*b870b9d3SBitterblue Smith pg_tbl = &chip->page_table[1]; 429*b870b9d3SBitterblue Smith break; 430*b870b9d3SBitterblue Smith case RTW_HCI_TYPE_USB: 431*b870b9d3SBitterblue Smith if (rtwdev->hci.bulkout_num == 2) 432*b870b9d3SBitterblue Smith pg_tbl = &chip->page_table[2]; 433*b870b9d3SBitterblue Smith else if (rtwdev->hci.bulkout_num == 3) 434*b870b9d3SBitterblue Smith pg_tbl = &chip->page_table[3]; 435*b870b9d3SBitterblue Smith else if (rtwdev->hci.bulkout_num == 4) 436*b870b9d3SBitterblue Smith pg_tbl = &chip->page_table[4]; 437*b870b9d3SBitterblue Smith break; 438*b870b9d3SBitterblue Smith case RTW_HCI_TYPE_SDIO: 439*b870b9d3SBitterblue Smith pg_tbl = &chip->page_table[0]; 440*b870b9d3SBitterblue Smith break; 441*b870b9d3SBitterblue Smith default: 442*b870b9d3SBitterblue Smith break; 443*b870b9d3SBitterblue Smith } 444*b870b9d3SBitterblue Smith 445*b870b9d3SBitterblue Smith pubq_num = fifo->acq_pg_num - pg_tbl->hq_num - pg_tbl->lq_num - 446*b870b9d3SBitterblue Smith pg_tbl->nq_num - pg_tbl->exq_num - pg_tbl->gapq_num; 447*b870b9d3SBitterblue Smith 448*b870b9d3SBitterblue Smith val32 = BIT_RQPN_NE(pg_tbl->nq_num, pg_tbl->exq_num); 449*b870b9d3SBitterblue Smith rtw_write32(rtwdev, REG_RQPN_NPQ, val32); 450*b870b9d3SBitterblue Smith 451*b870b9d3SBitterblue Smith val32 = BIT_RQPN_HLP(pg_tbl->hq_num, pg_tbl->lq_num, pubq_num); 452*b870b9d3SBitterblue Smith rtw_write32(rtwdev, REG_RQPN, val32); 453*b870b9d3SBitterblue Smith } 454*b870b9d3SBitterblue Smith 455*b870b9d3SBitterblue Smith static void rtw88xxau_init_tx_buffer_boundary(struct rtw_dev *rtwdev) 456*b870b9d3SBitterblue Smith { 457*b870b9d3SBitterblue Smith struct rtw_fifo_conf *fifo = &rtwdev->fifo; 458*b870b9d3SBitterblue Smith 459*b870b9d3SBitterblue Smith rtw_write8(rtwdev, REG_BCNQ_BDNY, fifo->rsvd_boundary); 460*b870b9d3SBitterblue Smith rtw_write8(rtwdev, REG_MGQ_BDNY, fifo->rsvd_boundary); 461*b870b9d3SBitterblue Smith rtw_write8(rtwdev, REG_WMAC_LBK_BF_HD, fifo->rsvd_boundary); 462*b870b9d3SBitterblue Smith rtw_write8(rtwdev, REG_TRXFF_BNDY, fifo->rsvd_boundary); 463*b870b9d3SBitterblue Smith rtw_write8(rtwdev, REG_DWBCN0_CTRL + 1, fifo->rsvd_boundary); 464*b870b9d3SBitterblue Smith } 465*b870b9d3SBitterblue Smith 466*b870b9d3SBitterblue Smith static int rtw88xxau_init_queue_priority(struct rtw_dev *rtwdev) 467*b870b9d3SBitterblue Smith { 468*b870b9d3SBitterblue Smith const struct rtw_chip_info *chip = rtwdev->chip; 469*b870b9d3SBitterblue Smith u8 bulkout_num = rtwdev->hci.bulkout_num; 470*b870b9d3SBitterblue Smith const struct rtw_rqpn *rqpn = NULL; 471*b870b9d3SBitterblue Smith u16 txdma_pq_map; 472*b870b9d3SBitterblue Smith 473*b870b9d3SBitterblue Smith switch (rtw_hci_type(rtwdev)) { 474*b870b9d3SBitterblue Smith case RTW_HCI_TYPE_PCIE: 475*b870b9d3SBitterblue Smith rqpn = &chip->rqpn_table[1]; 476*b870b9d3SBitterblue Smith break; 477*b870b9d3SBitterblue Smith case RTW_HCI_TYPE_USB: 478*b870b9d3SBitterblue Smith if (bulkout_num == 2) 479*b870b9d3SBitterblue Smith rqpn = &chip->rqpn_table[2]; 480*b870b9d3SBitterblue Smith else if (bulkout_num == 3) 481*b870b9d3SBitterblue Smith rqpn = &chip->rqpn_table[3]; 482*b870b9d3SBitterblue Smith else if (bulkout_num == 4) 483*b870b9d3SBitterblue Smith rqpn = &chip->rqpn_table[4]; 484*b870b9d3SBitterblue Smith else 485*b870b9d3SBitterblue Smith return -EINVAL; 486*b870b9d3SBitterblue Smith break; 487*b870b9d3SBitterblue Smith case RTW_HCI_TYPE_SDIO: 488*b870b9d3SBitterblue Smith rqpn = &chip->rqpn_table[0]; 489*b870b9d3SBitterblue Smith break; 490*b870b9d3SBitterblue Smith default: 491*b870b9d3SBitterblue Smith return -EINVAL; 492*b870b9d3SBitterblue Smith } 493*b870b9d3SBitterblue Smith 494*b870b9d3SBitterblue Smith rtwdev->fifo.rqpn = rqpn; 495*b870b9d3SBitterblue Smith 496*b870b9d3SBitterblue Smith txdma_pq_map = rtw_read16(rtwdev, REG_TXDMA_PQ_MAP) & 0x7; 497*b870b9d3SBitterblue Smith txdma_pq_map |= BIT_TXDMA_HIQ_MAP(rqpn->dma_map_hi); 498*b870b9d3SBitterblue Smith txdma_pq_map |= BIT_TXDMA_MGQ_MAP(rqpn->dma_map_mg); 499*b870b9d3SBitterblue Smith txdma_pq_map |= BIT_TXDMA_BKQ_MAP(rqpn->dma_map_bk); 500*b870b9d3SBitterblue Smith txdma_pq_map |= BIT_TXDMA_BEQ_MAP(rqpn->dma_map_be); 501*b870b9d3SBitterblue Smith txdma_pq_map |= BIT_TXDMA_VIQ_MAP(rqpn->dma_map_vi); 502*b870b9d3SBitterblue Smith txdma_pq_map |= BIT_TXDMA_VOQ_MAP(rqpn->dma_map_vo); 503*b870b9d3SBitterblue Smith rtw_write16(rtwdev, REG_TXDMA_PQ_MAP, txdma_pq_map); 504*b870b9d3SBitterblue Smith 505*b870b9d3SBitterblue Smith /* Packet in Hi Queue Tx immediately (No constraint for ATIM Period). */ 506*b870b9d3SBitterblue Smith if (rtw_hci_type(rtwdev) == RTW_HCI_TYPE_USB && bulkout_num == 4) 507*b870b9d3SBitterblue Smith rtw_write8(rtwdev, REG_HIQ_NO_LMT_EN, 0xff); 508*b870b9d3SBitterblue Smith 509*b870b9d3SBitterblue Smith return 0; 510*b870b9d3SBitterblue Smith } 511*b870b9d3SBitterblue Smith 512*b870b9d3SBitterblue Smith static void rtw88xxa_init_wmac_setting(struct rtw_dev *rtwdev) 513*b870b9d3SBitterblue Smith { 514*b870b9d3SBitterblue Smith rtw_write16(rtwdev, REG_RXFLTMAP0, 0xffff); 515*b870b9d3SBitterblue Smith rtw_write16(rtwdev, REG_RXFLTMAP1, 0x0400); 516*b870b9d3SBitterblue Smith rtw_write16(rtwdev, REG_RXFLTMAP2, 0xffff); 517*b870b9d3SBitterblue Smith 518*b870b9d3SBitterblue Smith rtw_write32(rtwdev, REG_MAR, 0xffffffff); 519*b870b9d3SBitterblue Smith rtw_write32(rtwdev, REG_MAR + 4, 0xffffffff); 520*b870b9d3SBitterblue Smith } 521*b870b9d3SBitterblue Smith 522*b870b9d3SBitterblue Smith static void rtw88xxa_init_adaptive_ctrl(struct rtw_dev *rtwdev) 523*b870b9d3SBitterblue Smith { 524*b870b9d3SBitterblue Smith rtw_write32_mask(rtwdev, REG_RRSR, 0xfffff, 0xffff1); 525*b870b9d3SBitterblue Smith rtw_write16(rtwdev, REG_RETRY_LIMIT, 0x3030); 526*b870b9d3SBitterblue Smith } 527*b870b9d3SBitterblue Smith 528*b870b9d3SBitterblue Smith static void rtw88xxa_init_edca(struct rtw_dev *rtwdev) 529*b870b9d3SBitterblue Smith { 530*b870b9d3SBitterblue Smith rtw_write16(rtwdev, REG_SPEC_SIFS, 0x100a); 531*b870b9d3SBitterblue Smith rtw_write16(rtwdev, REG_MAC_SPEC_SIFS, 0x100a); 532*b870b9d3SBitterblue Smith 533*b870b9d3SBitterblue Smith rtw_write16(rtwdev, REG_SIFS, 0x100a); 534*b870b9d3SBitterblue Smith rtw_write16(rtwdev, REG_SIFS + 2, 0x100a); 535*b870b9d3SBitterblue Smith 536*b870b9d3SBitterblue Smith rtw_write32(rtwdev, REG_EDCA_BE_PARAM, 0x005EA42B); 537*b870b9d3SBitterblue Smith rtw_write32(rtwdev, REG_EDCA_BK_PARAM, 0x0000A44F); 538*b870b9d3SBitterblue Smith rtw_write32(rtwdev, REG_EDCA_VI_PARAM, 0x005EA324); 539*b870b9d3SBitterblue Smith rtw_write32(rtwdev, REG_EDCA_VO_PARAM, 0x002FA226); 540*b870b9d3SBitterblue Smith 541*b870b9d3SBitterblue Smith rtw_write8(rtwdev, REG_USTIME_TSF, 0x50); 542*b870b9d3SBitterblue Smith rtw_write8(rtwdev, REG_USTIME_EDCA, 0x50); 543*b870b9d3SBitterblue Smith } 544*b870b9d3SBitterblue Smith 545*b870b9d3SBitterblue Smith static void rtw88xxau_tx_aggregation(struct rtw_dev *rtwdev) 546*b870b9d3SBitterblue Smith { 547*b870b9d3SBitterblue Smith const struct rtw_chip_info *chip = rtwdev->chip; 548*b870b9d3SBitterblue Smith 549*b870b9d3SBitterblue Smith rtw_write32_mask(rtwdev, REG_DWBCN0_CTRL, 0xf0, 550*b870b9d3SBitterblue Smith chip->usb_tx_agg_desc_num); 551*b870b9d3SBitterblue Smith 552*b870b9d3SBitterblue Smith if (chip->id == RTW_CHIP_TYPE_8821A) 553*b870b9d3SBitterblue Smith rtw_write8(rtwdev, REG_DWBCN1_CTRL, 554*b870b9d3SBitterblue Smith chip->usb_tx_agg_desc_num << 1); 555*b870b9d3SBitterblue Smith } 556*b870b9d3SBitterblue Smith 557*b870b9d3SBitterblue Smith static void rtw88xxa_init_beacon_parameters(struct rtw_dev *rtwdev) 558*b870b9d3SBitterblue Smith { 559*b870b9d3SBitterblue Smith u16 val16; 560*b870b9d3SBitterblue Smith 561*b870b9d3SBitterblue Smith val16 = (BIT_DIS_TSF_UDT << 8) | BIT_DIS_TSF_UDT; 562*b870b9d3SBitterblue Smith if (rtwdev->efuse.btcoex) 563*b870b9d3SBitterblue Smith val16 |= BIT_EN_BCN_FUNCTION; 564*b870b9d3SBitterblue Smith rtw_write16(rtwdev, REG_BCN_CTRL, val16); 565*b870b9d3SBitterblue Smith 566*b870b9d3SBitterblue Smith rtw_write32_mask(rtwdev, REG_TBTT_PROHIBIT, 0xfffff, WLAN_TBTT_TIME); 567*b870b9d3SBitterblue Smith rtw_write8(rtwdev, REG_DRVERLYINT, 0x05); 568*b870b9d3SBitterblue Smith rtw_write8(rtwdev, REG_BCNDMATIM, WLAN_BCN_DMA_TIME); 569*b870b9d3SBitterblue Smith rtw_write16(rtwdev, REG_BCNTCFG, 0x4413); 570*b870b9d3SBitterblue Smith } 571*b870b9d3SBitterblue Smith 572*b870b9d3SBitterblue Smith static void rtw88xxa_phy_bb_config(struct rtw_dev *rtwdev) 573*b870b9d3SBitterblue Smith { 574*b870b9d3SBitterblue Smith u8 val8, crystal_cap; 575*b870b9d3SBitterblue Smith 576*b870b9d3SBitterblue Smith /* power on BB/RF domain */ 577*b870b9d3SBitterblue Smith val8 = rtw_read8(rtwdev, REG_SYS_FUNC_EN); 578*b870b9d3SBitterblue Smith val8 |= BIT_FEN_USBA; 579*b870b9d3SBitterblue Smith rtw_write8(rtwdev, REG_SYS_FUNC_EN, val8); 580*b870b9d3SBitterblue Smith 581*b870b9d3SBitterblue Smith /* toggle BB reset */ 582*b870b9d3SBitterblue Smith val8 |= BIT_FEN_BB_RSTB | BIT_FEN_BB_GLB_RST; 583*b870b9d3SBitterblue Smith rtw_write8(rtwdev, REG_SYS_FUNC_EN, val8); 584*b870b9d3SBitterblue Smith 585*b870b9d3SBitterblue Smith rtw_write8(rtwdev, REG_RF_CTRL, 586*b870b9d3SBitterblue Smith BIT_RF_EN | BIT_RF_RSTB | BIT_RF_SDM_RSTB); 587*b870b9d3SBitterblue Smith rtw_write8(rtwdev, REG_RF_B_CTRL, 588*b870b9d3SBitterblue Smith BIT_RF_EN | BIT_RF_RSTB | BIT_RF_SDM_RSTB); 589*b870b9d3SBitterblue Smith 590*b870b9d3SBitterblue Smith rtw_load_table(rtwdev, rtwdev->chip->bb_tbl); 591*b870b9d3SBitterblue Smith rtw_load_table(rtwdev, rtwdev->chip->agc_tbl); 592*b870b9d3SBitterblue Smith 593*b870b9d3SBitterblue Smith crystal_cap = rtwdev->efuse.crystal_cap & 0x3F; 594*b870b9d3SBitterblue Smith if (rtwdev->chip->id == RTW_CHIP_TYPE_8812A) 595*b870b9d3SBitterblue Smith rtw_write32_mask(rtwdev, REG_AFE_CTRL3, 0x7FF80000, 596*b870b9d3SBitterblue Smith crystal_cap | (crystal_cap << 6)); 597*b870b9d3SBitterblue Smith else 598*b870b9d3SBitterblue Smith rtw_write32_mask(rtwdev, REG_AFE_CTRL3, 0x00FFF000, 599*b870b9d3SBitterblue Smith crystal_cap | (crystal_cap << 6)); 600*b870b9d3SBitterblue Smith } 601*b870b9d3SBitterblue Smith 602*b870b9d3SBitterblue Smith static void rtw88xxa_phy_rf_config(struct rtw_dev *rtwdev) 603*b870b9d3SBitterblue Smith { 604*b870b9d3SBitterblue Smith u8 rf_path; 605*b870b9d3SBitterblue Smith 606*b870b9d3SBitterblue Smith for (rf_path = 0; rf_path < rtwdev->hal.rf_path_num; rf_path++) 607*b870b9d3SBitterblue Smith rtw_load_table(rtwdev, rtwdev->chip->rf_tbl[rf_path]); 608*b870b9d3SBitterblue Smith } 609*b870b9d3SBitterblue Smith 610*b870b9d3SBitterblue Smith static void rtw8812a_config_1t(struct rtw_dev *rtwdev) 611*b870b9d3SBitterblue Smith { 612*b870b9d3SBitterblue Smith /* BB OFDM RX Path_A */ 613*b870b9d3SBitterblue Smith rtw_write32_mask(rtwdev, REG_RXPSEL, 0xff, 0x11); 614*b870b9d3SBitterblue Smith 615*b870b9d3SBitterblue Smith /* BB OFDM TX Path_A */ 616*b870b9d3SBitterblue Smith rtw_write32_mask(rtwdev, REG_TXPSEL, MASKLWORD, 0x1111); 617*b870b9d3SBitterblue Smith 618*b870b9d3SBitterblue Smith /* BB CCK R/Rx Path_A */ 619*b870b9d3SBitterblue Smith rtw_write32_mask(rtwdev, REG_CCK_RX, 0x0c000000, 0x0); 620*b870b9d3SBitterblue Smith 621*b870b9d3SBitterblue Smith /* MCS support */ 622*b870b9d3SBitterblue Smith rtw_write32_mask(rtwdev, REG_RX_MCS_LIMIT, 0xc0000060, 0x4); 623*b870b9d3SBitterblue Smith 624*b870b9d3SBitterblue Smith /* RF Path_B HSSI OFF */ 625*b870b9d3SBitterblue Smith rtw_write32_mask(rtwdev, REG_3WIRE_SWB, 0xf, 0x4); 626*b870b9d3SBitterblue Smith 627*b870b9d3SBitterblue Smith /* RF Path_B Power Down */ 628*b870b9d3SBitterblue Smith rtw_write32_mask(rtwdev, REG_LSSI_WRITE_B, MASKDWORD, 0); 629*b870b9d3SBitterblue Smith 630*b870b9d3SBitterblue Smith /* ADDA Path_B OFF */ 631*b870b9d3SBitterblue Smith rtw_write32_mask(rtwdev, REG_AFE_PWR1_B, MASKDWORD, 0); 632*b870b9d3SBitterblue Smith rtw_write32_mask(rtwdev, REG_AFE_PWR2_B, MASKDWORD, 0); 633*b870b9d3SBitterblue Smith } 634*b870b9d3SBitterblue Smith 635*b870b9d3SBitterblue Smith static const u32 rtw88xxa_txscale_tbl[] = { 636*b870b9d3SBitterblue Smith 0x081, 0x088, 0x090, 0x099, 0x0a2, 0x0ac, 0x0b6, 0x0c0, 0x0cc, 0x0d8, 637*b870b9d3SBitterblue Smith 0x0e5, 0x0f2, 0x101, 0x110, 0x120, 0x131, 0x143, 0x156, 0x16a, 0x180, 638*b870b9d3SBitterblue Smith 0x197, 0x1af, 0x1c8, 0x1e3, 0x200, 0x21e, 0x23e, 0x261, 0x285, 0x2ab, 639*b870b9d3SBitterblue Smith 0x2d3, 0x2fe, 0x32b, 0x35c, 0x38e, 0x3c4, 0x3fe 640*b870b9d3SBitterblue Smith }; 641*b870b9d3SBitterblue Smith 642*b870b9d3SBitterblue Smith static u32 rtw88xxa_get_bb_swing(struct rtw_dev *rtwdev, u8 band, u8 path) 643*b870b9d3SBitterblue Smith { 644*b870b9d3SBitterblue Smith static const u32 swing2setting[4] = {0x200, 0x16a, 0x101, 0x0b6}; 645*b870b9d3SBitterblue Smith struct rtw_efuse *efuse = &rtwdev->efuse; 646*b870b9d3SBitterblue Smith u8 tx_bb_swing; 647*b870b9d3SBitterblue Smith 648*b870b9d3SBitterblue Smith if (band == RTW_BAND_2G) 649*b870b9d3SBitterblue Smith tx_bb_swing = efuse->tx_bb_swing_setting_2g; 650*b870b9d3SBitterblue Smith else 651*b870b9d3SBitterblue Smith tx_bb_swing = efuse->tx_bb_swing_setting_5g; 652*b870b9d3SBitterblue Smith 653*b870b9d3SBitterblue Smith if (path == RF_PATH_B) 654*b870b9d3SBitterblue Smith tx_bb_swing >>= 2; 655*b870b9d3SBitterblue Smith tx_bb_swing &= 0x3; 656*b870b9d3SBitterblue Smith 657*b870b9d3SBitterblue Smith return swing2setting[tx_bb_swing]; 658*b870b9d3SBitterblue Smith } 659*b870b9d3SBitterblue Smith 660*b870b9d3SBitterblue Smith static u8 rtw88xxa_get_swing_index(struct rtw_dev *rtwdev) 661*b870b9d3SBitterblue Smith { 662*b870b9d3SBitterblue Smith u32 swing, table_value; 663*b870b9d3SBitterblue Smith u8 i; 664*b870b9d3SBitterblue Smith 665*b870b9d3SBitterblue Smith swing = rtw88xxa_get_bb_swing(rtwdev, rtwdev->hal.current_band_type, 666*b870b9d3SBitterblue Smith RF_PATH_A); 667*b870b9d3SBitterblue Smith 668*b870b9d3SBitterblue Smith for (i = 0; i < ARRAY_SIZE(rtw88xxa_txscale_tbl); i++) { 669*b870b9d3SBitterblue Smith table_value = rtw88xxa_txscale_tbl[i]; 670*b870b9d3SBitterblue Smith if (swing == table_value) 671*b870b9d3SBitterblue Smith return i; 672*b870b9d3SBitterblue Smith } 673*b870b9d3SBitterblue Smith 674*b870b9d3SBitterblue Smith return 24; 675*b870b9d3SBitterblue Smith } 676*b870b9d3SBitterblue Smith 677*b870b9d3SBitterblue Smith static void rtw88xxa_pwrtrack_init(struct rtw_dev *rtwdev) 678*b870b9d3SBitterblue Smith { 679*b870b9d3SBitterblue Smith struct rtw_dm_info *dm_info = &rtwdev->dm_info; 680*b870b9d3SBitterblue Smith u8 path; 681*b870b9d3SBitterblue Smith 682*b870b9d3SBitterblue Smith dm_info->default_ofdm_index = rtw88xxa_get_swing_index(rtwdev); 683*b870b9d3SBitterblue Smith 684*b870b9d3SBitterblue Smith if (rtwdev->chip->id == RTW_CHIP_TYPE_8821A) 685*b870b9d3SBitterblue Smith dm_info->default_cck_index = 0; 686*b870b9d3SBitterblue Smith else 687*b870b9d3SBitterblue Smith dm_info->default_cck_index = 24; 688*b870b9d3SBitterblue Smith 689*b870b9d3SBitterblue Smith for (path = RF_PATH_A; path < rtwdev->hal.rf_path_num; path++) { 690*b870b9d3SBitterblue Smith ewma_thermal_init(&dm_info->avg_thermal[path]); 691*b870b9d3SBitterblue Smith dm_info->delta_power_index[path] = 0; 692*b870b9d3SBitterblue Smith dm_info->delta_power_index_last[path] = 0; 693*b870b9d3SBitterblue Smith } 694*b870b9d3SBitterblue Smith 695*b870b9d3SBitterblue Smith dm_info->pwr_trk_triggered = false; 696*b870b9d3SBitterblue Smith dm_info->pwr_trk_init_trigger = true; 697*b870b9d3SBitterblue Smith dm_info->thermal_meter_k = rtwdev->efuse.thermal_meter_k; 698*b870b9d3SBitterblue Smith } 699*b870b9d3SBitterblue Smith 700*b870b9d3SBitterblue Smith void rtw88xxa_power_off(struct rtw_dev *rtwdev, 701*b870b9d3SBitterblue Smith const struct rtw_pwr_seq_cmd *const *enter_lps_flow) 702*b870b9d3SBitterblue Smith { 703*b870b9d3SBitterblue Smith struct rtw_usb *rtwusb = rtw_get_usb_priv(rtwdev); 704*b870b9d3SBitterblue Smith enum usb_device_speed speed = rtwusb->udev->speed; 705*b870b9d3SBitterblue Smith u16 ori_fsmc0; 706*b870b9d3SBitterblue Smith u8 reg_cr; 707*b870b9d3SBitterblue Smith 708*b870b9d3SBitterblue Smith reg_cr = rtw_read8(rtwdev, REG_CR); 709*b870b9d3SBitterblue Smith 710*b870b9d3SBitterblue Smith /* Already powered off */ 711*b870b9d3SBitterblue Smith if (reg_cr == 0 || reg_cr == 0xEA) 712*b870b9d3SBitterblue Smith return; 713*b870b9d3SBitterblue Smith 714*b870b9d3SBitterblue Smith rtw_hci_stop(rtwdev); 715*b870b9d3SBitterblue Smith 716*b870b9d3SBitterblue Smith if (!rtwdev->efuse.btcoex) 717*b870b9d3SBitterblue Smith rtw_write16_clr(rtwdev, REG_GPIO_MUXCFG, BIT_EN_SIC); 718*b870b9d3SBitterblue Smith 719*b870b9d3SBitterblue Smith /* set Reg 0xf008[3:4] to 2'11 to enable U1/U2 Mode in USB3.0. */ 720*b870b9d3SBitterblue Smith if (speed == USB_SPEED_SUPER) 721*b870b9d3SBitterblue Smith rtw_write8_set(rtwdev, REG_USB_MOD, 0x18); 722*b870b9d3SBitterblue Smith 723*b870b9d3SBitterblue Smith rtw_write32(rtwdev, REG_HISR0, 0xffffffff); 724*b870b9d3SBitterblue Smith rtw_write32(rtwdev, REG_HISR1, 0xffffffff); 725*b870b9d3SBitterblue Smith rtw_write32(rtwdev, REG_HIMR0, 0); 726*b870b9d3SBitterblue Smith rtw_write32(rtwdev, REG_HIMR1, 0); 727*b870b9d3SBitterblue Smith 728*b870b9d3SBitterblue Smith if (rtwdev->efuse.btcoex) 729*b870b9d3SBitterblue Smith rtw_coex_power_off_setting(rtwdev); 730*b870b9d3SBitterblue Smith 731*b870b9d3SBitterblue Smith ori_fsmc0 = rtw_read16(rtwdev, REG_APS_FSMCO); 732*b870b9d3SBitterblue Smith rtw_write16(rtwdev, REG_APS_FSMCO, ori_fsmc0 & ~APS_FSMCO_HW_POWERDOWN); 733*b870b9d3SBitterblue Smith 734*b870b9d3SBitterblue Smith /* Stop Tx Report Timer. */ 735*b870b9d3SBitterblue Smith rtw_write8_clr(rtwdev, REG_TX_RPT_CTRL, BIT(1)); 736*b870b9d3SBitterblue Smith 737*b870b9d3SBitterblue Smith /* Stop Rx */ 738*b870b9d3SBitterblue Smith rtw_write8(rtwdev, REG_CR, 0); 739*b870b9d3SBitterblue Smith 740*b870b9d3SBitterblue Smith rtw_pwr_seq_parser(rtwdev, enter_lps_flow); 741*b870b9d3SBitterblue Smith 742*b870b9d3SBitterblue Smith if (rtw_read8(rtwdev, REG_MCUFW_CTRL) & BIT_RAM_DL_SEL) 743*b870b9d3SBitterblue Smith rtw88xxa_reset_8051(rtwdev); 744*b870b9d3SBitterblue Smith 745*b870b9d3SBitterblue Smith rtw_write8_clr(rtwdev, REG_SYS_FUNC_EN + 1, BIT(2)); 746*b870b9d3SBitterblue Smith rtw_write8(rtwdev, REG_MCUFW_CTRL, 0); 747*b870b9d3SBitterblue Smith 748*b870b9d3SBitterblue Smith rtw_pwr_seq_parser(rtwdev, rtwdev->chip->pwr_off_seq); 749*b870b9d3SBitterblue Smith 750*b870b9d3SBitterblue Smith if (ori_fsmc0 & APS_FSMCO_HW_POWERDOWN) 751*b870b9d3SBitterblue Smith rtw_write16_set(rtwdev, REG_APS_FSMCO, APS_FSMCO_HW_POWERDOWN); 752*b870b9d3SBitterblue Smith 753*b870b9d3SBitterblue Smith clear_bit(RTW_FLAG_POWERON, rtwdev->flags); 754*b870b9d3SBitterblue Smith } 755*b870b9d3SBitterblue Smith EXPORT_SYMBOL(rtw88xxa_power_off); 756*b870b9d3SBitterblue Smith 757*b870b9d3SBitterblue Smith static void rtw88xxa_set_channel_bb_swing(struct rtw_dev *rtwdev, u8 band) 758*b870b9d3SBitterblue Smith { 759*b870b9d3SBitterblue Smith rtw_write32_mask(rtwdev, REG_TXSCALE_A, BB_SWING_MASK, 760*b870b9d3SBitterblue Smith rtw88xxa_get_bb_swing(rtwdev, band, RF_PATH_A)); 761*b870b9d3SBitterblue Smith rtw_write32_mask(rtwdev, REG_TXSCALE_B, BB_SWING_MASK, 762*b870b9d3SBitterblue Smith rtw88xxa_get_bb_swing(rtwdev, band, RF_PATH_B)); 763*b870b9d3SBitterblue Smith rtw88xxa_pwrtrack_init(rtwdev); 764*b870b9d3SBitterblue Smith } 765*b870b9d3SBitterblue Smith 766*b870b9d3SBitterblue Smith static void rtw8821a_set_ext_band_switch(struct rtw_dev *rtwdev, u8 band) 767*b870b9d3SBitterblue Smith { 768*b870b9d3SBitterblue Smith rtw_write32_mask(rtwdev, REG_LED_CFG, BIT_DPDT_SEL_EN, 0); 769*b870b9d3SBitterblue Smith rtw_write32_mask(rtwdev, REG_LED_CFG, BIT_DPDT_WL_SEL, 1); 770*b870b9d3SBitterblue Smith rtw_write32_mask(rtwdev, REG_RFE_INV_A, 0xf, 7); 771*b870b9d3SBitterblue Smith rtw_write32_mask(rtwdev, REG_RFE_INV_A, 0xf0, 7); 772*b870b9d3SBitterblue Smith 773*b870b9d3SBitterblue Smith if (band == RTW_BAND_2G) 774*b870b9d3SBitterblue Smith rtw_write32_mask(rtwdev, REG_RFE_INV_A, BIT(29) | BIT(28), 1); 775*b870b9d3SBitterblue Smith else 776*b870b9d3SBitterblue Smith rtw_write32_mask(rtwdev, REG_RFE_INV_A, BIT(29) | BIT(28), 2); 777*b870b9d3SBitterblue Smith } 778*b870b9d3SBitterblue Smith 779*b870b9d3SBitterblue Smith static void rtw8821a_phy_set_rfe_reg_24g(struct rtw_dev *rtwdev) 780*b870b9d3SBitterblue Smith { 781*b870b9d3SBitterblue Smith struct rtw_efuse *efuse = &rtwdev->efuse; 782*b870b9d3SBitterblue Smith 783*b870b9d3SBitterblue Smith /* Turn off RF PA and LNA */ 784*b870b9d3SBitterblue Smith 785*b870b9d3SBitterblue Smith /* 0xCB0[15:12] = 0x7 (LNA_On)*/ 786*b870b9d3SBitterblue Smith rtw_write32_mask(rtwdev, REG_RFE_PINMUX_A, 0xF000, 0x7); 787*b870b9d3SBitterblue Smith /* 0xCB0[7:4] = 0x7 (PAPE_A)*/ 788*b870b9d3SBitterblue Smith rtw_write32_mask(rtwdev, REG_RFE_PINMUX_A, 0xF0, 0x7); 789*b870b9d3SBitterblue Smith 790*b870b9d3SBitterblue Smith if (efuse->ext_lna_2g) { 791*b870b9d3SBitterblue Smith /* Turn on 2.4G External LNA */ 792*b870b9d3SBitterblue Smith rtw_write32_mask(rtwdev, REG_RFE_INV_A, BIT(20), 1); 793*b870b9d3SBitterblue Smith rtw_write32_mask(rtwdev, REG_RFE_INV_A, BIT(22), 0); 794*b870b9d3SBitterblue Smith rtw_write32_mask(rtwdev, REG_RFE_PINMUX_A, GENMASK(2, 0), 0x2); 795*b870b9d3SBitterblue Smith rtw_write32_mask(rtwdev, REG_RFE_PINMUX_A, GENMASK(10, 8), 0x2); 796*b870b9d3SBitterblue Smith } else { 797*b870b9d3SBitterblue Smith /* Bypass 2.4G External LNA */ 798*b870b9d3SBitterblue Smith rtw_write32_mask(rtwdev, REG_RFE_INV_A, BIT(20), 0); 799*b870b9d3SBitterblue Smith rtw_write32_mask(rtwdev, REG_RFE_INV_A, BIT(22), 0); 800*b870b9d3SBitterblue Smith rtw_write32_mask(rtwdev, REG_RFE_PINMUX_A, GENMASK(2, 0), 0x7); 801*b870b9d3SBitterblue Smith rtw_write32_mask(rtwdev, REG_RFE_PINMUX_A, GENMASK(10, 8), 0x7); 802*b870b9d3SBitterblue Smith } 803*b870b9d3SBitterblue Smith } 804*b870b9d3SBitterblue Smith 805*b870b9d3SBitterblue Smith static void rtw8821a_phy_set_rfe_reg_5g(struct rtw_dev *rtwdev) 806*b870b9d3SBitterblue Smith { 807*b870b9d3SBitterblue Smith /* Turn ON RF PA and LNA */ 808*b870b9d3SBitterblue Smith 809*b870b9d3SBitterblue Smith /* 0xCB0[15:12] = 0x7 (LNA_On)*/ 810*b870b9d3SBitterblue Smith rtw_write32_mask(rtwdev, REG_RFE_PINMUX_A, 0xF000, 0x5); 811*b870b9d3SBitterblue Smith /* 0xCB0[7:4] = 0x7 (PAPE_A)*/ 812*b870b9d3SBitterblue Smith rtw_write32_mask(rtwdev, REG_RFE_PINMUX_A, 0xF0, 0x4); 813*b870b9d3SBitterblue Smith 814*b870b9d3SBitterblue Smith /* Bypass 2.4G External LNA */ 815*b870b9d3SBitterblue Smith rtw_write32_mask(rtwdev, REG_RFE_INV_A, BIT(20), 0); 816*b870b9d3SBitterblue Smith rtw_write32_mask(rtwdev, REG_RFE_INV_A, BIT(22), 0); 817*b870b9d3SBitterblue Smith rtw_write32_mask(rtwdev, REG_RFE_PINMUX_A, GENMASK(2, 0), 0x7); 818*b870b9d3SBitterblue Smith rtw_write32_mask(rtwdev, REG_RFE_PINMUX_A, GENMASK(10, 8), 0x7); 819*b870b9d3SBitterblue Smith } 820*b870b9d3SBitterblue Smith 821*b870b9d3SBitterblue Smith static void rtw8812a_phy_set_rfe_reg_24g(struct rtw_dev *rtwdev) 822*b870b9d3SBitterblue Smith { 823*b870b9d3SBitterblue Smith switch (rtwdev->efuse.rfe_option) { 824*b870b9d3SBitterblue Smith case 0: 825*b870b9d3SBitterblue Smith case 2: 826*b870b9d3SBitterblue Smith rtw_write32(rtwdev, REG_RFE_PINMUX_A, 0x77777777); 827*b870b9d3SBitterblue Smith rtw_write32(rtwdev, REG_RFE_PINMUX_B, 0x77777777); 828*b870b9d3SBitterblue Smith rtw_write32_mask(rtwdev, REG_RFE_INV_A, RFE_INV_MASK, 0x000); 829*b870b9d3SBitterblue Smith rtw_write32_mask(rtwdev, REG_RFE_INV_B, RFE_INV_MASK, 0x000); 830*b870b9d3SBitterblue Smith break; 831*b870b9d3SBitterblue Smith case 1: 832*b870b9d3SBitterblue Smith if (rtwdev->efuse.btcoex) { 833*b870b9d3SBitterblue Smith rtw_write32_mask(rtwdev, REG_RFE_PINMUX_A, 0xffffff, 0x777777); 834*b870b9d3SBitterblue Smith rtw_write32(rtwdev, REG_RFE_PINMUX_B, 0x77777777); 835*b870b9d3SBitterblue Smith rtw_write32_mask(rtwdev, REG_RFE_INV_A, 0x33f00000, 0x000); 836*b870b9d3SBitterblue Smith rtw_write32_mask(rtwdev, REG_RFE_INV_B, RFE_INV_MASK, 0x000); 837*b870b9d3SBitterblue Smith } else { 838*b870b9d3SBitterblue Smith rtw_write32(rtwdev, REG_RFE_PINMUX_A, 0x77777777); 839*b870b9d3SBitterblue Smith rtw_write32(rtwdev, REG_RFE_PINMUX_B, 0x77777777); 840*b870b9d3SBitterblue Smith rtw_write32_mask(rtwdev, REG_RFE_INV_A, RFE_INV_MASK, 0x000); 841*b870b9d3SBitterblue Smith rtw_write32_mask(rtwdev, REG_RFE_INV_B, RFE_INV_MASK, 0x000); 842*b870b9d3SBitterblue Smith } 843*b870b9d3SBitterblue Smith break; 844*b870b9d3SBitterblue Smith case 3: 845*b870b9d3SBitterblue Smith rtw_write32(rtwdev, REG_RFE_PINMUX_A, 0x54337770); 846*b870b9d3SBitterblue Smith rtw_write32(rtwdev, REG_RFE_PINMUX_B, 0x54337770); 847*b870b9d3SBitterblue Smith rtw_write32_mask(rtwdev, REG_RFE_INV_A, RFE_INV_MASK, 0x010); 848*b870b9d3SBitterblue Smith rtw_write32_mask(rtwdev, REG_RFE_INV_B, RFE_INV_MASK, 0x010); 849*b870b9d3SBitterblue Smith rtw_write32_mask(rtwdev, REG_ANTSEL_SW, 0x00000303, 0x1); 850*b870b9d3SBitterblue Smith break; 851*b870b9d3SBitterblue Smith case 4: 852*b870b9d3SBitterblue Smith rtw_write32(rtwdev, REG_RFE_PINMUX_A, 0x77777777); 853*b870b9d3SBitterblue Smith rtw_write32(rtwdev, REG_RFE_PINMUX_B, 0x77777777); 854*b870b9d3SBitterblue Smith rtw_write32_mask(rtwdev, REG_RFE_INV_A, RFE_INV_MASK, 0x001); 855*b870b9d3SBitterblue Smith rtw_write32_mask(rtwdev, REG_RFE_INV_B, RFE_INV_MASK, 0x001); 856*b870b9d3SBitterblue Smith break; 857*b870b9d3SBitterblue Smith case 5: 858*b870b9d3SBitterblue Smith rtw_write8(rtwdev, REG_RFE_PINMUX_A + 2, 0x77); 859*b870b9d3SBitterblue Smith rtw_write32(rtwdev, REG_RFE_PINMUX_B, 0x77777777); 860*b870b9d3SBitterblue Smith rtw_write8_clr(rtwdev, REG_RFE_INV_A + 3, BIT(0)); 861*b870b9d3SBitterblue Smith rtw_write32_mask(rtwdev, REG_RFE_INV_B, RFE_INV_MASK, 0x000); 862*b870b9d3SBitterblue Smith break; 863*b870b9d3SBitterblue Smith case 6: 864*b870b9d3SBitterblue Smith rtw_write32(rtwdev, REG_RFE_PINMUX_A, 0x07772770); 865*b870b9d3SBitterblue Smith rtw_write32(rtwdev, REG_RFE_PINMUX_B, 0x07772770); 866*b870b9d3SBitterblue Smith rtw_write32(rtwdev, REG_RFE_INV_A, 0x00000077); 867*b870b9d3SBitterblue Smith rtw_write32(rtwdev, REG_RFE_INV_B, 0x00000077); 868*b870b9d3SBitterblue Smith break; 869*b870b9d3SBitterblue Smith default: 870*b870b9d3SBitterblue Smith break; 871*b870b9d3SBitterblue Smith } 872*b870b9d3SBitterblue Smith } 873*b870b9d3SBitterblue Smith 874*b870b9d3SBitterblue Smith static void rtw8812a_phy_set_rfe_reg_5g(struct rtw_dev *rtwdev) 875*b870b9d3SBitterblue Smith { 876*b870b9d3SBitterblue Smith switch (rtwdev->efuse.rfe_option) { 877*b870b9d3SBitterblue Smith case 0: 878*b870b9d3SBitterblue Smith rtw_write32(rtwdev, REG_RFE_PINMUX_A, 0x77337717); 879*b870b9d3SBitterblue Smith rtw_write32(rtwdev, REG_RFE_PINMUX_B, 0x77337717); 880*b870b9d3SBitterblue Smith rtw_write32_mask(rtwdev, REG_RFE_INV_A, RFE_INV_MASK, 0x010); 881*b870b9d3SBitterblue Smith rtw_write32_mask(rtwdev, REG_RFE_INV_B, RFE_INV_MASK, 0x010); 882*b870b9d3SBitterblue Smith break; 883*b870b9d3SBitterblue Smith case 1: 884*b870b9d3SBitterblue Smith if (rtwdev->efuse.btcoex) { 885*b870b9d3SBitterblue Smith rtw_write32_mask(rtwdev, REG_RFE_PINMUX_A, 0xffffff, 0x337717); 886*b870b9d3SBitterblue Smith rtw_write32(rtwdev, REG_RFE_PINMUX_B, 0x77337717); 887*b870b9d3SBitterblue Smith rtw_write32_mask(rtwdev, REG_RFE_INV_A, 0x33f00000, 0x000); 888*b870b9d3SBitterblue Smith rtw_write32_mask(rtwdev, REG_RFE_INV_B, RFE_INV_MASK, 0x000); 889*b870b9d3SBitterblue Smith } else { 890*b870b9d3SBitterblue Smith rtw_write32(rtwdev, REG_RFE_PINMUX_A, 0x77337717); 891*b870b9d3SBitterblue Smith rtw_write32(rtwdev, REG_RFE_PINMUX_B, 0x77337717); 892*b870b9d3SBitterblue Smith rtw_write32_mask(rtwdev, REG_RFE_INV_A, RFE_INV_MASK, 0x000); 893*b870b9d3SBitterblue Smith rtw_write32_mask(rtwdev, REG_RFE_INV_B, RFE_INV_MASK, 0x000); 894*b870b9d3SBitterblue Smith } 895*b870b9d3SBitterblue Smith break; 896*b870b9d3SBitterblue Smith case 2: 897*b870b9d3SBitterblue Smith case 4: 898*b870b9d3SBitterblue Smith rtw_write32(rtwdev, REG_RFE_PINMUX_A, 0x77337777); 899*b870b9d3SBitterblue Smith rtw_write32(rtwdev, REG_RFE_PINMUX_B, 0x77337777); 900*b870b9d3SBitterblue Smith rtw_write32_mask(rtwdev, REG_RFE_INV_A, RFE_INV_MASK, 0x010); 901*b870b9d3SBitterblue Smith rtw_write32_mask(rtwdev, REG_RFE_INV_B, RFE_INV_MASK, 0x010); 902*b870b9d3SBitterblue Smith break; 903*b870b9d3SBitterblue Smith case 3: 904*b870b9d3SBitterblue Smith rtw_write32(rtwdev, REG_RFE_PINMUX_A, 0x54337717); 905*b870b9d3SBitterblue Smith rtw_write32(rtwdev, REG_RFE_PINMUX_B, 0x54337717); 906*b870b9d3SBitterblue Smith rtw_write32_mask(rtwdev, REG_RFE_INV_A, RFE_INV_MASK, 0x010); 907*b870b9d3SBitterblue Smith rtw_write32_mask(rtwdev, REG_RFE_INV_B, RFE_INV_MASK, 0x010); 908*b870b9d3SBitterblue Smith rtw_write32_mask(rtwdev, REG_ANTSEL_SW, 0x00000303, 0x1); 909*b870b9d3SBitterblue Smith break; 910*b870b9d3SBitterblue Smith case 5: 911*b870b9d3SBitterblue Smith rtw_write8(rtwdev, REG_RFE_PINMUX_A + 2, 0x33); 912*b870b9d3SBitterblue Smith rtw_write32(rtwdev, REG_RFE_PINMUX_B, 0x77337777); 913*b870b9d3SBitterblue Smith rtw_write8_set(rtwdev, REG_RFE_INV_A + 3, BIT(0)); 914*b870b9d3SBitterblue Smith rtw_write32_mask(rtwdev, REG_RFE_INV_B, RFE_INV_MASK, 0x010); 915*b870b9d3SBitterblue Smith break; 916*b870b9d3SBitterblue Smith case 6: 917*b870b9d3SBitterblue Smith rtw_write32(rtwdev, REG_RFE_PINMUX_A, 0x07737717); 918*b870b9d3SBitterblue Smith rtw_write32(rtwdev, REG_RFE_PINMUX_B, 0x07737717); 919*b870b9d3SBitterblue Smith rtw_write32(rtwdev, REG_RFE_INV_A, 0x00000077); 920*b870b9d3SBitterblue Smith rtw_write32(rtwdev, REG_RFE_INV_B, 0x00000077); 921*b870b9d3SBitterblue Smith break; 922*b870b9d3SBitterblue Smith default: 923*b870b9d3SBitterblue Smith break; 924*b870b9d3SBitterblue Smith } 925*b870b9d3SBitterblue Smith } 926*b870b9d3SBitterblue Smith 927*b870b9d3SBitterblue Smith static void rtw88xxa_switch_band(struct rtw_dev *rtwdev, u8 new_band, u8 bw) 928*b870b9d3SBitterblue Smith { 929*b870b9d3SBitterblue Smith const struct rtw_chip_info *chip = rtwdev->chip; 930*b870b9d3SBitterblue Smith u16 basic_rates, reg_41a; 931*b870b9d3SBitterblue Smith 932*b870b9d3SBitterblue Smith /* 8811au one antenna module doesn't support antenna div, so driver must 933*b870b9d3SBitterblue Smith * control antenna band, otherwise one of the band will have issue 934*b870b9d3SBitterblue Smith */ 935*b870b9d3SBitterblue Smith if (chip->id == RTW_CHIP_TYPE_8821A && !rtwdev->efuse.btcoex && 936*b870b9d3SBitterblue Smith rtwdev->efuse.ant_div_cfg == 0) 937*b870b9d3SBitterblue Smith rtw8821a_set_ext_band_switch(rtwdev, new_band); 938*b870b9d3SBitterblue Smith 939*b870b9d3SBitterblue Smith if (new_band == RTW_BAND_2G) { 940*b870b9d3SBitterblue Smith rtw_write32_set(rtwdev, REG_RXPSEL, BIT_RX_PSEL_RST); 941*b870b9d3SBitterblue Smith 942*b870b9d3SBitterblue Smith if (chip->id == RTW_CHIP_TYPE_8821A) { 943*b870b9d3SBitterblue Smith rtw8821a_phy_set_rfe_reg_24g(rtwdev); 944*b870b9d3SBitterblue Smith 945*b870b9d3SBitterblue Smith rtw_write32_mask(rtwdev, REG_TXSCALE_A, 0xf00, 0); 946*b870b9d3SBitterblue Smith } else { 947*b870b9d3SBitterblue Smith rtw_write32_mask(rtwdev, REG_BWINDICATION, 0x3, 0x1); 948*b870b9d3SBitterblue Smith rtw_write32_mask(rtwdev, REG_PDMFTH, GENMASK(17, 13), 0x17); 949*b870b9d3SBitterblue Smith 950*b870b9d3SBitterblue Smith if (bw == RTW_CHANNEL_WIDTH_20 && 951*b870b9d3SBitterblue Smith rtwdev->hal.rf_type == RF_1T1R && 952*b870b9d3SBitterblue Smith !rtwdev->efuse.ext_lna_2g) 953*b870b9d3SBitterblue Smith rtw_write32_mask(rtwdev, REG_PDMFTH, GENMASK(3, 1), 0x02); 954*b870b9d3SBitterblue Smith else 955*b870b9d3SBitterblue Smith rtw_write32_mask(rtwdev, REG_PDMFTH, GENMASK(3, 1), 0x04); 956*b870b9d3SBitterblue Smith 957*b870b9d3SBitterblue Smith rtw_write32_mask(rtwdev, REG_CCASEL, 0x3, 0); 958*b870b9d3SBitterblue Smith 959*b870b9d3SBitterblue Smith rtw8812a_phy_set_rfe_reg_24g(rtwdev); 960*b870b9d3SBitterblue Smith } 961*b870b9d3SBitterblue Smith 962*b870b9d3SBitterblue Smith rtw_write32_mask(rtwdev, REG_TXPSEL, 0xf0, 0x1); 963*b870b9d3SBitterblue Smith rtw_write32_mask(rtwdev, REG_CCK_RX, 0x0f000000, 0x1); 964*b870b9d3SBitterblue Smith 965*b870b9d3SBitterblue Smith basic_rates = BIT(DESC_RATE1M) | BIT(DESC_RATE2M) | 966*b870b9d3SBitterblue Smith BIT(DESC_RATE5_5M) | BIT(DESC_RATE11M) | 967*b870b9d3SBitterblue Smith BIT(DESC_RATE6M) | BIT(DESC_RATE12M) | 968*b870b9d3SBitterblue Smith BIT(DESC_RATE24M); 969*b870b9d3SBitterblue Smith rtw_write32_mask(rtwdev, REG_RRSR, 0xfffff, basic_rates); 970*b870b9d3SBitterblue Smith 971*b870b9d3SBitterblue Smith rtw_write8_clr(rtwdev, REG_CCK_CHECK, BIT_CHECK_CCK_EN); 972*b870b9d3SBitterblue Smith } else { /* RTW_BAND_5G */ 973*b870b9d3SBitterblue Smith if (chip->id == RTW_CHIP_TYPE_8821A) 974*b870b9d3SBitterblue Smith rtw8821a_phy_set_rfe_reg_5g(rtwdev); 975*b870b9d3SBitterblue Smith 976*b870b9d3SBitterblue Smith rtw_write8_set(rtwdev, REG_CCK_CHECK, BIT_CHECK_CCK_EN); 977*b870b9d3SBitterblue Smith 978*b870b9d3SBitterblue Smith read_poll_timeout_atomic(rtw_read16, reg_41a, (reg_41a & 0x30) == 0x30, 979*b870b9d3SBitterblue Smith 50, 2500, false, rtwdev, REG_TXPKT_EMPTY); 980*b870b9d3SBitterblue Smith 981*b870b9d3SBitterblue Smith rtw_write32_set(rtwdev, REG_RXPSEL, BIT_RX_PSEL_RST); 982*b870b9d3SBitterblue Smith 983*b870b9d3SBitterblue Smith if (chip->id == RTW_CHIP_TYPE_8821A) { 984*b870b9d3SBitterblue Smith rtw_write32_mask(rtwdev, REG_TXSCALE_A, 0xf00, 1); 985*b870b9d3SBitterblue Smith } else { 986*b870b9d3SBitterblue Smith rtw_write32_mask(rtwdev, REG_BWINDICATION, 0x3, 0x2); 987*b870b9d3SBitterblue Smith rtw_write32_mask(rtwdev, REG_PDMFTH, GENMASK(17, 13), 0x15); 988*b870b9d3SBitterblue Smith rtw_write32_mask(rtwdev, REG_PDMFTH, GENMASK(3, 1), 0x04); 989*b870b9d3SBitterblue Smith 990*b870b9d3SBitterblue Smith rtw_write32_mask(rtwdev, REG_CCASEL, 0x3, 1); 991*b870b9d3SBitterblue Smith 992*b870b9d3SBitterblue Smith rtw8812a_phy_set_rfe_reg_5g(rtwdev); 993*b870b9d3SBitterblue Smith } 994*b870b9d3SBitterblue Smith 995*b870b9d3SBitterblue Smith rtw_write32_mask(rtwdev, REG_TXPSEL, 0xf0, 0); 996*b870b9d3SBitterblue Smith rtw_write32_mask(rtwdev, REG_CCK_RX, 0x0f000000, 0xf); 997*b870b9d3SBitterblue Smith 998*b870b9d3SBitterblue Smith basic_rates = BIT(DESC_RATE6M) | BIT(DESC_RATE12M) | 999*b870b9d3SBitterblue Smith BIT(DESC_RATE24M); 1000*b870b9d3SBitterblue Smith rtw_write32_mask(rtwdev, REG_RRSR, 0xfffff, basic_rates); 1001*b870b9d3SBitterblue Smith } 1002*b870b9d3SBitterblue Smith 1003*b870b9d3SBitterblue Smith rtw88xxa_set_channel_bb_swing(rtwdev, new_band); 1004*b870b9d3SBitterblue Smith } 1005*b870b9d3SBitterblue Smith 1006*b870b9d3SBitterblue Smith int rtw88xxa_power_on(struct rtw_dev *rtwdev) 1007*b870b9d3SBitterblue Smith { 1008*b870b9d3SBitterblue Smith struct rtw_usb *rtwusb = rtw_get_usb_priv(rtwdev); 1009*b870b9d3SBitterblue Smith const struct rtw_chip_info *chip = rtwdev->chip; 1010*b870b9d3SBitterblue Smith struct rtw_efuse *efuse = &rtwdev->efuse; 1011*b870b9d3SBitterblue Smith struct rtw_hal *hal = &rtwdev->hal; 1012*b870b9d3SBitterblue Smith int ret; 1013*b870b9d3SBitterblue Smith 1014*b870b9d3SBitterblue Smith if (test_bit(RTW_FLAG_POWERON, rtwdev->flags)) 1015*b870b9d3SBitterblue Smith return 0; 1016*b870b9d3SBitterblue Smith 1017*b870b9d3SBitterblue Smith /* Override rtw_chip_efuse_info_setup() */ 1018*b870b9d3SBitterblue Smith if (chip->id == RTW_CHIP_TYPE_8821A) 1019*b870b9d3SBitterblue Smith efuse->btcoex = rtw_read32_mask(rtwdev, REG_WL_BT_PWR_CTRL, 1020*b870b9d3SBitterblue Smith BIT_BT_FUNC_EN); 1021*b870b9d3SBitterblue Smith 1022*b870b9d3SBitterblue Smith /* Override rtw_chip_efuse_info_setup() */ 1023*b870b9d3SBitterblue Smith if (chip->id == RTW_CHIP_TYPE_8812A) 1024*b870b9d3SBitterblue Smith rtw8812a_read_amplifier_type(rtwdev); 1025*b870b9d3SBitterblue Smith 1026*b870b9d3SBitterblue Smith ret = rtw_hci_setup(rtwdev); 1027*b870b9d3SBitterblue Smith if (ret) { 1028*b870b9d3SBitterblue Smith rtw_err(rtwdev, "failed to setup hci\n"); 1029*b870b9d3SBitterblue Smith goto err; 1030*b870b9d3SBitterblue Smith } 1031*b870b9d3SBitterblue Smith 1032*b870b9d3SBitterblue Smith /* Revise for U2/U3 switch we can not update RF-A/B reset. 1033*b870b9d3SBitterblue Smith * Reset after MAC power on to prevent RF R/W error. 1034*b870b9d3SBitterblue Smith * Is it a right method? 1035*b870b9d3SBitterblue Smith */ 1036*b870b9d3SBitterblue Smith if (chip->id == RTW_CHIP_TYPE_8812A) { 1037*b870b9d3SBitterblue Smith rtw_write8(rtwdev, REG_RF_CTRL, 5); 1038*b870b9d3SBitterblue Smith rtw_write8(rtwdev, REG_RF_CTRL, 7); 1039*b870b9d3SBitterblue Smith rtw_write8(rtwdev, REG_RF_B_CTRL, 5); 1040*b870b9d3SBitterblue Smith rtw_write8(rtwdev, REG_RF_B_CTRL, 7); 1041*b870b9d3SBitterblue Smith } 1042*b870b9d3SBitterblue Smith 1043*b870b9d3SBitterblue Smith /* If HW didn't go through a complete de-initial procedure, 1044*b870b9d3SBitterblue Smith * it probably occurs some problem for double initial 1045*b870b9d3SBitterblue Smith * procedure. 1046*b870b9d3SBitterblue Smith */ 1047*b870b9d3SBitterblue Smith rtw88xxau_hw_reset(rtwdev); 1048*b870b9d3SBitterblue Smith 1049*b870b9d3SBitterblue Smith ret = rtw88xxau_init_power_on(rtwdev); 1050*b870b9d3SBitterblue Smith if (ret) { 1051*b870b9d3SBitterblue Smith rtw_err(rtwdev, "failed to power on\n"); 1052*b870b9d3SBitterblue Smith goto err; 1053*b870b9d3SBitterblue Smith } 1054*b870b9d3SBitterblue Smith 1055*b870b9d3SBitterblue Smith ret = rtw_set_trx_fifo_info(rtwdev); 1056*b870b9d3SBitterblue Smith if (ret) { 1057*b870b9d3SBitterblue Smith rtw_err(rtwdev, "failed to set trx fifo info\n"); 1058*b870b9d3SBitterblue Smith goto err; 1059*b870b9d3SBitterblue Smith } 1060*b870b9d3SBitterblue Smith 1061*b870b9d3SBitterblue Smith ret = rtw88xxa_llt_init(rtwdev, rtwdev->fifo.rsvd_boundary); 1062*b870b9d3SBitterblue Smith if (ret) { 1063*b870b9d3SBitterblue Smith rtw_err(rtwdev, "failed to init llt\n"); 1064*b870b9d3SBitterblue Smith goto err; 1065*b870b9d3SBitterblue Smith } 1066*b870b9d3SBitterblue Smith 1067*b870b9d3SBitterblue Smith rtw_write32_set(rtwdev, REG_TXDMA_OFFSET_CHK, BIT_DROP_DATA_EN); 1068*b870b9d3SBitterblue Smith 1069*b870b9d3SBitterblue Smith ret = rtw_wait_firmware_completion(rtwdev); 1070*b870b9d3SBitterblue Smith if (ret) { 1071*b870b9d3SBitterblue Smith rtw_err(rtwdev, "failed to wait firmware completion\n"); 1072*b870b9d3SBitterblue Smith goto err_off; 1073*b870b9d3SBitterblue Smith } 1074*b870b9d3SBitterblue Smith 1075*b870b9d3SBitterblue Smith ret = rtw_download_firmware(rtwdev, &rtwdev->fw); 1076*b870b9d3SBitterblue Smith if (ret) { 1077*b870b9d3SBitterblue Smith rtw_err(rtwdev, "failed to download firmware\n"); 1078*b870b9d3SBitterblue Smith goto err_off; 1079*b870b9d3SBitterblue Smith } 1080*b870b9d3SBitterblue Smith 1081*b870b9d3SBitterblue Smith rtw_write8(rtwdev, REG_HMETFR, 0xf); 1082*b870b9d3SBitterblue Smith 1083*b870b9d3SBitterblue Smith rtw_load_table(rtwdev, chip->mac_tbl); 1084*b870b9d3SBitterblue Smith 1085*b870b9d3SBitterblue Smith rtw88xxau_init_queue_reserved_page(rtwdev); 1086*b870b9d3SBitterblue Smith rtw88xxau_init_tx_buffer_boundary(rtwdev); 1087*b870b9d3SBitterblue Smith rtw88xxau_init_queue_priority(rtwdev); 1088*b870b9d3SBitterblue Smith 1089*b870b9d3SBitterblue Smith rtw_write16(rtwdev, REG_TRXFF_BNDY + 2, 1090*b870b9d3SBitterblue Smith chip->rxff_size - REPORT_BUF - 1); 1091*b870b9d3SBitterblue Smith 1092*b870b9d3SBitterblue Smith if (chip->id == RTW_CHIP_TYPE_8812A) 1093*b870b9d3SBitterblue Smith rtw_write8(rtwdev, REG_PBP, 1094*b870b9d3SBitterblue Smith u8_encode_bits(PBP_512, PBP_TX_MASK) | 1095*b870b9d3SBitterblue Smith u8_encode_bits(PBP_64, PBP_RX_MASK)); 1096*b870b9d3SBitterblue Smith 1097*b870b9d3SBitterblue Smith rtw_write8(rtwdev, REG_RX_DRVINFO_SZ, PHY_STATUS_SIZE); 1098*b870b9d3SBitterblue Smith 1099*b870b9d3SBitterblue Smith rtw_write32(rtwdev, REG_HIMR0, 0); 1100*b870b9d3SBitterblue Smith rtw_write32(rtwdev, REG_HIMR1, 0); 1101*b870b9d3SBitterblue Smith 1102*b870b9d3SBitterblue Smith rtw_write32_mask(rtwdev, REG_CR, 0x30000, 0x2); 1103*b870b9d3SBitterblue Smith 1104*b870b9d3SBitterblue Smith rtw88xxa_init_wmac_setting(rtwdev); 1105*b870b9d3SBitterblue Smith rtw88xxa_init_adaptive_ctrl(rtwdev); 1106*b870b9d3SBitterblue Smith rtw88xxa_init_edca(rtwdev); 1107*b870b9d3SBitterblue Smith 1108*b870b9d3SBitterblue Smith rtw_write8_set(rtwdev, REG_FWHW_TXQ_CTRL, BIT(7)); 1109*b870b9d3SBitterblue Smith rtw_write8(rtwdev, REG_ACKTO, 0x80); 1110*b870b9d3SBitterblue Smith 1111*b870b9d3SBitterblue Smith rtw88xxau_tx_aggregation(rtwdev); 1112*b870b9d3SBitterblue Smith 1113*b870b9d3SBitterblue Smith rtw88xxa_init_beacon_parameters(rtwdev); 1114*b870b9d3SBitterblue Smith rtw_write8(rtwdev, REG_BCN_MAX_ERR, 0xff); 1115*b870b9d3SBitterblue Smith 1116*b870b9d3SBitterblue Smith rtw_hci_interface_cfg(rtwdev); 1117*b870b9d3SBitterblue Smith 1118*b870b9d3SBitterblue Smith /* usb3 rx interval */ 1119*b870b9d3SBitterblue Smith rtw_write8(rtwdev, REG_USB3_RXITV, 0x01); 1120*b870b9d3SBitterblue Smith 1121*b870b9d3SBitterblue Smith /* burst length=4, set 0x3400 for burst length=2 */ 1122*b870b9d3SBitterblue Smith rtw_write16(rtwdev, REG_RXDMA_STATUS, 0x7400); 1123*b870b9d3SBitterblue Smith rtw_write8(rtwdev, REG_RXDMA_STATUS + 1, 0xf5); 1124*b870b9d3SBitterblue Smith 1125*b870b9d3SBitterblue Smith /* 0x456 = 0x70, sugguested by Zhilin */ 1126*b870b9d3SBitterblue Smith if (chip->id == RTW_CHIP_TYPE_8821A) 1127*b870b9d3SBitterblue Smith rtw_write8(rtwdev, REG_AMPDU_MAX_TIME, 0x5e); 1128*b870b9d3SBitterblue Smith else 1129*b870b9d3SBitterblue Smith rtw_write8(rtwdev, REG_AMPDU_MAX_TIME, 0x70); 1130*b870b9d3SBitterblue Smith 1131*b870b9d3SBitterblue Smith rtw_write32(rtwdev, REG_AMPDU_MAX_LENGTH, 0xffffffff); 1132*b870b9d3SBitterblue Smith rtw_write8(rtwdev, REG_USTIME_TSF, 0x50); 1133*b870b9d3SBitterblue Smith rtw_write8(rtwdev, REG_USTIME_EDCA, 0x50); 1134*b870b9d3SBitterblue Smith 1135*b870b9d3SBitterblue Smith if (rtwusb->udev->speed == USB_SPEED_SUPER) 1136*b870b9d3SBitterblue Smith /* Disable U1/U2 Mode to avoid 2.5G spur in USB3.0. */ 1137*b870b9d3SBitterblue Smith rtw_write8_clr(rtwdev, REG_USB_MOD, BIT(4) | BIT(3)); 1138*b870b9d3SBitterblue Smith 1139*b870b9d3SBitterblue Smith rtw_write8_set(rtwdev, REG_SINGLE_AMPDU_CTRL, BIT_EN_SINGLE_APMDU); 1140*b870b9d3SBitterblue Smith 1141*b870b9d3SBitterblue Smith /* for VHT packet length 11K */ 1142*b870b9d3SBitterblue Smith rtw_write8(rtwdev, REG_RX_PKT_LIMIT, 0x18); 1143*b870b9d3SBitterblue Smith 1144*b870b9d3SBitterblue Smith rtw_write8(rtwdev, REG_PIFS, 0x00); 1145*b870b9d3SBitterblue Smith 1146*b870b9d3SBitterblue Smith if (chip->id == RTW_CHIP_TYPE_8821A) { 1147*b870b9d3SBitterblue Smith /* 0x0a0a too small, it can't pass AC logo. change to 0x1f1f */ 1148*b870b9d3SBitterblue Smith rtw_write16(rtwdev, REG_MAX_AGGR_NUM, 0x1f1f); 1149*b870b9d3SBitterblue Smith rtw_write8(rtwdev, REG_FWHW_TXQ_CTRL, 0x80); 1150*b870b9d3SBitterblue Smith rtw_write32(rtwdev, REG_FAST_EDCA_CTRL, 0x03087777); 1151*b870b9d3SBitterblue Smith } else { 1152*b870b9d3SBitterblue Smith rtw_write16(rtwdev, REG_MAX_AGGR_NUM, 0x1f1f); 1153*b870b9d3SBitterblue Smith rtw_write8_clr(rtwdev, REG_FWHW_TXQ_CTRL, BIT(7)); 1154*b870b9d3SBitterblue Smith } 1155*b870b9d3SBitterblue Smith 1156*b870b9d3SBitterblue Smith /* to prevent mac is reseted by bus. */ 1157*b870b9d3SBitterblue Smith rtw_write8_set(rtwdev, REG_RSV_CTRL, BIT(5) | BIT(6)); 1158*b870b9d3SBitterblue Smith 1159*b870b9d3SBitterblue Smith /* ARFB table 9 for 11ac 5G 2SS */ 1160*b870b9d3SBitterblue Smith rtw_write32(rtwdev, REG_ARFR0, 0x00000010); 1161*b870b9d3SBitterblue Smith rtw_write32(rtwdev, REG_ARFRH0, 0xfffff000); 1162*b870b9d3SBitterblue Smith 1163*b870b9d3SBitterblue Smith /* ARFB table 10 for 11ac 5G 1SS */ 1164*b870b9d3SBitterblue Smith rtw_write32(rtwdev, REG_ARFR1_V1, 0x00000010); 1165*b870b9d3SBitterblue Smith rtw_write32(rtwdev, REG_ARFRH1_V1, 0x003ff000); 1166*b870b9d3SBitterblue Smith 1167*b870b9d3SBitterblue Smith /* ARFB table 11 for 11ac 24G 1SS */ 1168*b870b9d3SBitterblue Smith rtw_write32(rtwdev, REG_ARFR2_V1, 0x00000015); 1169*b870b9d3SBitterblue Smith rtw_write32(rtwdev, REG_ARFRH2_V1, 0x003ff000); 1170*b870b9d3SBitterblue Smith 1171*b870b9d3SBitterblue Smith /* ARFB table 12 for 11ac 24G 2SS */ 1172*b870b9d3SBitterblue Smith rtw_write32(rtwdev, REG_ARFR3_V1, 0x00000015); 1173*b870b9d3SBitterblue Smith rtw_write32(rtwdev, REG_ARFRH3_V1, 0xffcff000); 1174*b870b9d3SBitterblue Smith 1175*b870b9d3SBitterblue Smith rtw_write8_set(rtwdev, REG_CR, BIT_MACTXEN | BIT_MACRXEN); 1176*b870b9d3SBitterblue Smith 1177*b870b9d3SBitterblue Smith rtw88xxa_phy_bb_config(rtwdev); 1178*b870b9d3SBitterblue Smith rtw88xxa_phy_rf_config(rtwdev); 1179*b870b9d3SBitterblue Smith 1180*b870b9d3SBitterblue Smith if (chip->id == RTW_CHIP_TYPE_8812A && hal->rf_path_num == 1) 1181*b870b9d3SBitterblue Smith rtw8812a_config_1t(rtwdev); 1182*b870b9d3SBitterblue Smith 1183*b870b9d3SBitterblue Smith rtw88xxa_switch_band(rtwdev, RTW_BAND_2G, RTW_CHANNEL_WIDTH_20); 1184*b870b9d3SBitterblue Smith 1185*b870b9d3SBitterblue Smith rtw_write32(rtwdev, RTW_SEC_CMD_REG, BIT(31) | BIT(30)); 1186*b870b9d3SBitterblue Smith 1187*b870b9d3SBitterblue Smith rtw_write8(rtwdev, REG_HWSEQ_CTRL, 0xff); 1188*b870b9d3SBitterblue Smith rtw_write32(rtwdev, REG_BAR_MODE_CTRL, 0x0201ffff); 1189*b870b9d3SBitterblue Smith rtw_write8(rtwdev, REG_NAV_CTRL + 2, 0); 1190*b870b9d3SBitterblue Smith 1191*b870b9d3SBitterblue Smith rtw_write8_clr(rtwdev, REG_GPIO_MUXCFG, BIT(5)); 1192*b870b9d3SBitterblue Smith 1193*b870b9d3SBitterblue Smith rtw_phy_init(rtwdev); 1194*b870b9d3SBitterblue Smith 1195*b870b9d3SBitterblue Smith rtw88xxa_pwrtrack_init(rtwdev); 1196*b870b9d3SBitterblue Smith 1197*b870b9d3SBitterblue Smith /* 0x4c6[3] 1: RTS BW = Data BW 1198*b870b9d3SBitterblue Smith * 0: RTS BW depends on CCA / secondary CCA result. 1199*b870b9d3SBitterblue Smith */ 1200*b870b9d3SBitterblue Smith rtw_write8_clr(rtwdev, REG_QUEUE_CTRL, BIT(3)); 1201*b870b9d3SBitterblue Smith 1202*b870b9d3SBitterblue Smith /* enable Tx report. */ 1203*b870b9d3SBitterblue Smith rtw_write8(rtwdev, REG_FWHW_TXQ_CTRL + 1, 0x0f); 1204*b870b9d3SBitterblue Smith 1205*b870b9d3SBitterblue Smith /* Pretx_en, for WEP/TKIP SEC */ 1206*b870b9d3SBitterblue Smith rtw_write8(rtwdev, REG_EARLY_MODE_CONTROL + 3, 0x01); 1207*b870b9d3SBitterblue Smith 1208*b870b9d3SBitterblue Smith rtw_write16(rtwdev, REG_TX_RPT_TIME, 0x3df0); 1209*b870b9d3SBitterblue Smith 1210*b870b9d3SBitterblue Smith /* Reset USB mode switch setting */ 1211*b870b9d3SBitterblue Smith rtw_write8(rtwdev, REG_SYS_SDIO_CTRL, 0x0); 1212*b870b9d3SBitterblue Smith rtw_write8(rtwdev, REG_ACLK_MON, 0x0); 1213*b870b9d3SBitterblue Smith 1214*b870b9d3SBitterblue Smith rtw_write8(rtwdev, REG_USB_HRPWM, 0); 1215*b870b9d3SBitterblue Smith 1216*b870b9d3SBitterblue Smith /* ack for xmit mgmt frames. */ 1217*b870b9d3SBitterblue Smith rtw_write32_set(rtwdev, REG_FWHW_TXQ_CTRL, BIT(12)); 1218*b870b9d3SBitterblue Smith 1219*b870b9d3SBitterblue Smith hal->cck_high_power = rtw_read32_mask(rtwdev, REG_CCK_RPT_FORMAT, 1220*b870b9d3SBitterblue Smith BIT_CCK_RPT_FORMAT); 1221*b870b9d3SBitterblue Smith 1222*b870b9d3SBitterblue Smith ret = rtw_hci_start(rtwdev); 1223*b870b9d3SBitterblue Smith if (ret) { 1224*b870b9d3SBitterblue Smith rtw_err(rtwdev, "failed to start hci\n"); 1225*b870b9d3SBitterblue Smith goto err_off; 1226*b870b9d3SBitterblue Smith } 1227*b870b9d3SBitterblue Smith 1228*b870b9d3SBitterblue Smith if (efuse->btcoex) { 1229*b870b9d3SBitterblue Smith rtw_coex_power_on_setting(rtwdev); 1230*b870b9d3SBitterblue Smith rtw_coex_init_hw_config(rtwdev, false); 1231*b870b9d3SBitterblue Smith } 1232*b870b9d3SBitterblue Smith 1233*b870b9d3SBitterblue Smith set_bit(RTW_FLAG_POWERON, rtwdev->flags); 1234*b870b9d3SBitterblue Smith 1235*b870b9d3SBitterblue Smith return 0; 1236*b870b9d3SBitterblue Smith 1237*b870b9d3SBitterblue Smith err_off: 1238*b870b9d3SBitterblue Smith chip->ops->power_off(rtwdev); 1239*b870b9d3SBitterblue Smith 1240*b870b9d3SBitterblue Smith err: 1241*b870b9d3SBitterblue Smith return ret; 1242*b870b9d3SBitterblue Smith } 1243*b870b9d3SBitterblue Smith EXPORT_SYMBOL(rtw88xxa_power_on); 1244*b870b9d3SBitterblue Smith 1245*b870b9d3SBitterblue Smith u32 rtw88xxa_phy_read_rf(struct rtw_dev *rtwdev, 1246*b870b9d3SBitterblue Smith enum rtw_rf_path rf_path, u32 addr, u32 mask) 1247*b870b9d3SBitterblue Smith { 1248*b870b9d3SBitterblue Smith static const u32 pi_addr[2] = { REG_3WIRE_SWA, REG_3WIRE_SWB }; 1249*b870b9d3SBitterblue Smith static const u32 read_addr[2][2] = { 1250*b870b9d3SBitterblue Smith { REG_SI_READ_A, REG_SI_READ_B }, 1251*b870b9d3SBitterblue Smith { REG_PI_READ_A, REG_PI_READ_B } 1252*b870b9d3SBitterblue Smith }; 1253*b870b9d3SBitterblue Smith const struct rtw_chip_info *chip = rtwdev->chip; 1254*b870b9d3SBitterblue Smith const struct rtw_hal *hal = &rtwdev->hal; 1255*b870b9d3SBitterblue Smith bool set_cca, pi_mode; 1256*b870b9d3SBitterblue Smith u32 val; 1257*b870b9d3SBitterblue Smith 1258*b870b9d3SBitterblue Smith if (rf_path >= hal->rf_phy_num) { 1259*b870b9d3SBitterblue Smith rtw_err(rtwdev, "unsupported rf path (%d)\n", rf_path); 1260*b870b9d3SBitterblue Smith return INV_RF_DATA; 1261*b870b9d3SBitterblue Smith } 1262*b870b9d3SBitterblue Smith 1263*b870b9d3SBitterblue Smith /* CCA off to avoid reading the wrong value. 1264*b870b9d3SBitterblue Smith * Toggling CCA would affect RF 0x0, skip it. 1265*b870b9d3SBitterblue Smith */ 1266*b870b9d3SBitterblue Smith set_cca = addr != 0x0 && chip->id == RTW_CHIP_TYPE_8812A && 1267*b870b9d3SBitterblue Smith hal->cut_version != RTW_CHIP_VER_CUT_C; 1268*b870b9d3SBitterblue Smith 1269*b870b9d3SBitterblue Smith if (set_cca) 1270*b870b9d3SBitterblue Smith rtw_write32_set(rtwdev, REG_CCA2ND, BIT(3)); 1271*b870b9d3SBitterblue Smith 1272*b870b9d3SBitterblue Smith addr &= 0xff; 1273*b870b9d3SBitterblue Smith 1274*b870b9d3SBitterblue Smith pi_mode = rtw_read32_mask(rtwdev, pi_addr[rf_path], 0x4); 1275*b870b9d3SBitterblue Smith 1276*b870b9d3SBitterblue Smith rtw_write32_mask(rtwdev, REG_HSSI_READ, MASKBYTE0, addr); 1277*b870b9d3SBitterblue Smith 1278*b870b9d3SBitterblue Smith if (chip->id == RTW_CHIP_TYPE_8821A || 1279*b870b9d3SBitterblue Smith hal->cut_version == RTW_CHIP_VER_CUT_C) 1280*b870b9d3SBitterblue Smith udelay(20); 1281*b870b9d3SBitterblue Smith 1282*b870b9d3SBitterblue Smith val = rtw_read32_mask(rtwdev, read_addr[pi_mode][rf_path], mask); 1283*b870b9d3SBitterblue Smith 1284*b870b9d3SBitterblue Smith /* CCA on */ 1285*b870b9d3SBitterblue Smith if (set_cca) 1286*b870b9d3SBitterblue Smith rtw_write32_clr(rtwdev, REG_CCA2ND, BIT(3)); 1287*b870b9d3SBitterblue Smith 1288*b870b9d3SBitterblue Smith return val; 1289*b870b9d3SBitterblue Smith } 1290*b870b9d3SBitterblue Smith EXPORT_SYMBOL(rtw88xxa_phy_read_rf); 1291*b870b9d3SBitterblue Smith 1292*b870b9d3SBitterblue Smith static void rtw8812a_phy_fix_spur(struct rtw_dev *rtwdev, u8 channel, u8 bw) 1293*b870b9d3SBitterblue Smith { 1294*b870b9d3SBitterblue Smith /* C cut Item12 ADC FIFO CLOCK */ 1295*b870b9d3SBitterblue Smith if (rtwdev->hal.cut_version == RTW_CHIP_VER_CUT_C) { 1296*b870b9d3SBitterblue Smith if (bw == RTW_CHANNEL_WIDTH_40 && channel == 11) 1297*b870b9d3SBitterblue Smith rtw_write32_mask(rtwdev, REG_ADCCLK, 0xC00, 0x3); 1298*b870b9d3SBitterblue Smith else 1299*b870b9d3SBitterblue Smith rtw_write32_mask(rtwdev, REG_ADCCLK, 0xC00, 0x2); 1300*b870b9d3SBitterblue Smith 1301*b870b9d3SBitterblue Smith /* A workaround to resolve 2480Mhz spur by setting ADC clock 1302*b870b9d3SBitterblue Smith * as 160M. 1303*b870b9d3SBitterblue Smith */ 1304*b870b9d3SBitterblue Smith if (bw == RTW_CHANNEL_WIDTH_20 && (channel == 13 || channel == 14)) { 1305*b870b9d3SBitterblue Smith rtw_write32_mask(rtwdev, REG_ADCCLK, 0x300, 0x3); 1306*b870b9d3SBitterblue Smith rtw_write32_mask(rtwdev, REG_ADC160, BIT(30), 1); 1307*b870b9d3SBitterblue Smith } else if (bw == RTW_CHANNEL_WIDTH_40 && channel == 11) { 1308*b870b9d3SBitterblue Smith rtw_write32_mask(rtwdev, REG_ADC160, BIT(30), 1); 1309*b870b9d3SBitterblue Smith } else if (bw != RTW_CHANNEL_WIDTH_80) { 1310*b870b9d3SBitterblue Smith rtw_write32_mask(rtwdev, REG_ADCCLK, 0x300, 0x2); 1311*b870b9d3SBitterblue Smith rtw_write32_mask(rtwdev, REG_ADC160, BIT(30), 0); 1312*b870b9d3SBitterblue Smith } 1313*b870b9d3SBitterblue Smith } else { 1314*b870b9d3SBitterblue Smith /* A workaround to resolve 2480Mhz spur by setting ADC clock 1315*b870b9d3SBitterblue Smith * as 160M. 1316*b870b9d3SBitterblue Smith */ 1317*b870b9d3SBitterblue Smith if (bw == RTW_CHANNEL_WIDTH_20 && (channel == 13 || channel == 14)) 1318*b870b9d3SBitterblue Smith rtw_write32_mask(rtwdev, REG_ADCCLK, 0x300, 0x3); 1319*b870b9d3SBitterblue Smith else if (channel <= 14) /* 2.4G only */ 1320*b870b9d3SBitterblue Smith rtw_write32_mask(rtwdev, REG_ADCCLK, 0x300, 0x2); 1321*b870b9d3SBitterblue Smith } 1322*b870b9d3SBitterblue Smith } 1323*b870b9d3SBitterblue Smith 1324*b870b9d3SBitterblue Smith static void rtw88xxa_switch_channel(struct rtw_dev *rtwdev, u8 channel, u8 bw) 1325*b870b9d3SBitterblue Smith { 1326*b870b9d3SBitterblue Smith struct rtw_hal *hal = &rtwdev->hal; 1327*b870b9d3SBitterblue Smith u32 fc_area, rf_mod_ag; 1328*b870b9d3SBitterblue Smith u8 path; 1329*b870b9d3SBitterblue Smith 1330*b870b9d3SBitterblue Smith switch (channel) { 1331*b870b9d3SBitterblue Smith case 36 ... 48: 1332*b870b9d3SBitterblue Smith fc_area = 0x494; 1333*b870b9d3SBitterblue Smith break; 1334*b870b9d3SBitterblue Smith case 50 ... 64: 1335*b870b9d3SBitterblue Smith fc_area = 0x453; 1336*b870b9d3SBitterblue Smith break; 1337*b870b9d3SBitterblue Smith case 100 ... 116: 1338*b870b9d3SBitterblue Smith fc_area = 0x452; 1339*b870b9d3SBitterblue Smith break; 1340*b870b9d3SBitterblue Smith default: 1341*b870b9d3SBitterblue Smith if (channel >= 118) 1342*b870b9d3SBitterblue Smith fc_area = 0x412; 1343*b870b9d3SBitterblue Smith else 1344*b870b9d3SBitterblue Smith fc_area = 0x96a; 1345*b870b9d3SBitterblue Smith break; 1346*b870b9d3SBitterblue Smith } 1347*b870b9d3SBitterblue Smith 1348*b870b9d3SBitterblue Smith rtw_write32_mask(rtwdev, REG_CLKTRK, 0x1ffe0000, fc_area); 1349*b870b9d3SBitterblue Smith 1350*b870b9d3SBitterblue Smith for (path = 0; path < hal->rf_path_num; path++) { 1351*b870b9d3SBitterblue Smith switch (channel) { 1352*b870b9d3SBitterblue Smith case 36 ... 64: 1353*b870b9d3SBitterblue Smith rf_mod_ag = 0x101; 1354*b870b9d3SBitterblue Smith break; 1355*b870b9d3SBitterblue Smith case 100 ... 140: 1356*b870b9d3SBitterblue Smith rf_mod_ag = 0x301; 1357*b870b9d3SBitterblue Smith break; 1358*b870b9d3SBitterblue Smith default: 1359*b870b9d3SBitterblue Smith if (channel > 140) 1360*b870b9d3SBitterblue Smith rf_mod_ag = 0x501; 1361*b870b9d3SBitterblue Smith else 1362*b870b9d3SBitterblue Smith rf_mod_ag = 0x000; 1363*b870b9d3SBitterblue Smith break; 1364*b870b9d3SBitterblue Smith } 1365*b870b9d3SBitterblue Smith 1366*b870b9d3SBitterblue Smith rtw_write_rf(rtwdev, path, RF_CFGCH, 1367*b870b9d3SBitterblue Smith RF18_RFSI_MASK | RF18_BAND_MASK, rf_mod_ag); 1368*b870b9d3SBitterblue Smith 1369*b870b9d3SBitterblue Smith if (rtwdev->chip->id == RTW_CHIP_TYPE_8812A) 1370*b870b9d3SBitterblue Smith rtw8812a_phy_fix_spur(rtwdev, channel, bw); 1371*b870b9d3SBitterblue Smith 1372*b870b9d3SBitterblue Smith rtw_write_rf(rtwdev, path, RF_CFGCH, RF18_CHANNEL_MASK, channel); 1373*b870b9d3SBitterblue Smith } 1374*b870b9d3SBitterblue Smith } 1375*b870b9d3SBitterblue Smith 1376*b870b9d3SBitterblue Smith static void rtw88xxa_set_reg_bw(struct rtw_dev *rtwdev, u8 bw) 1377*b870b9d3SBitterblue Smith { 1378*b870b9d3SBitterblue Smith u16 val16 = rtw_read16(rtwdev, REG_WMAC_TRXPTCL_CTL); 1379*b870b9d3SBitterblue Smith 1380*b870b9d3SBitterblue Smith val16 &= ~BIT_RFMOD; 1381*b870b9d3SBitterblue Smith if (bw == RTW_CHANNEL_WIDTH_80) 1382*b870b9d3SBitterblue Smith val16 |= BIT_RFMOD_80M; 1383*b870b9d3SBitterblue Smith else if (bw == RTW_CHANNEL_WIDTH_40) 1384*b870b9d3SBitterblue Smith val16 |= BIT_RFMOD_40M; 1385*b870b9d3SBitterblue Smith 1386*b870b9d3SBitterblue Smith rtw_write16(rtwdev, REG_WMAC_TRXPTCL_CTL, val16); 1387*b870b9d3SBitterblue Smith } 1388*b870b9d3SBitterblue Smith 1389*b870b9d3SBitterblue Smith static void rtw88xxa_post_set_bw_mode(struct rtw_dev *rtwdev, u8 channel, 1390*b870b9d3SBitterblue Smith u8 bw, u8 primary_chan_idx) 1391*b870b9d3SBitterblue Smith { 1392*b870b9d3SBitterblue Smith struct rtw_hal *hal = &rtwdev->hal; 1393*b870b9d3SBitterblue Smith u8 txsc40 = 0, txsc20, txsc; 1394*b870b9d3SBitterblue Smith u8 reg_837, l1pkval; 1395*b870b9d3SBitterblue Smith 1396*b870b9d3SBitterblue Smith rtw88xxa_set_reg_bw(rtwdev, bw); 1397*b870b9d3SBitterblue Smith 1398*b870b9d3SBitterblue Smith txsc20 = primary_chan_idx; 1399*b870b9d3SBitterblue Smith if (bw == RTW_CHANNEL_WIDTH_80) { 1400*b870b9d3SBitterblue Smith if (txsc20 == RTW_SC_20_UPPER || txsc20 == RTW_SC_20_UPMOST) 1401*b870b9d3SBitterblue Smith txsc40 = RTW_SC_40_UPPER; 1402*b870b9d3SBitterblue Smith else 1403*b870b9d3SBitterblue Smith txsc40 = RTW_SC_40_LOWER; 1404*b870b9d3SBitterblue Smith } 1405*b870b9d3SBitterblue Smith 1406*b870b9d3SBitterblue Smith txsc = BIT_TXSC_20M(txsc20) | BIT_TXSC_40M(txsc40); 1407*b870b9d3SBitterblue Smith rtw_write8(rtwdev, REG_DATA_SC, txsc); 1408*b870b9d3SBitterblue Smith 1409*b870b9d3SBitterblue Smith reg_837 = rtw_read8(rtwdev, REG_BWINDICATION + 3); 1410*b870b9d3SBitterblue Smith 1411*b870b9d3SBitterblue Smith switch (bw) { 1412*b870b9d3SBitterblue Smith default: 1413*b870b9d3SBitterblue Smith case RTW_CHANNEL_WIDTH_20: 1414*b870b9d3SBitterblue Smith rtw_write32_mask(rtwdev, REG_ADCCLK, 0x003003C3, 0x00300200); 1415*b870b9d3SBitterblue Smith rtw_write32_mask(rtwdev, REG_ADC160, BIT(30), 0); 1416*b870b9d3SBitterblue Smith 1417*b870b9d3SBitterblue Smith if (hal->rf_type == RF_2T2R) 1418*b870b9d3SBitterblue Smith rtw_write32_mask(rtwdev, REG_L1PKTH, 0x03C00000, 7); 1419*b870b9d3SBitterblue Smith else 1420*b870b9d3SBitterblue Smith rtw_write32_mask(rtwdev, REG_L1PKTH, 0x03C00000, 8); 1421*b870b9d3SBitterblue Smith 1422*b870b9d3SBitterblue Smith break; 1423*b870b9d3SBitterblue Smith case RTW_CHANNEL_WIDTH_40: 1424*b870b9d3SBitterblue Smith rtw_write32_mask(rtwdev, REG_ADCCLK, 0x003003C3, 0x00300201); 1425*b870b9d3SBitterblue Smith rtw_write32_mask(rtwdev, REG_ADC160, BIT(30), 0); 1426*b870b9d3SBitterblue Smith rtw_write32_mask(rtwdev, REG_ADCCLK, 0x3C, txsc); 1427*b870b9d3SBitterblue Smith rtw_write32_mask(rtwdev, REG_CCA2ND, 0xf0000000, txsc); 1428*b870b9d3SBitterblue Smith 1429*b870b9d3SBitterblue Smith if (reg_837 & BIT(2)) { 1430*b870b9d3SBitterblue Smith l1pkval = 6; 1431*b870b9d3SBitterblue Smith } else { 1432*b870b9d3SBitterblue Smith if (hal->rf_type == RF_2T2R) 1433*b870b9d3SBitterblue Smith l1pkval = 7; 1434*b870b9d3SBitterblue Smith else 1435*b870b9d3SBitterblue Smith l1pkval = 8; 1436*b870b9d3SBitterblue Smith } 1437*b870b9d3SBitterblue Smith 1438*b870b9d3SBitterblue Smith rtw_write32_mask(rtwdev, REG_L1PKTH, 0x03C00000, l1pkval); 1439*b870b9d3SBitterblue Smith 1440*b870b9d3SBitterblue Smith if (txsc == RTW_SC_20_UPPER) 1441*b870b9d3SBitterblue Smith rtw_write32_set(rtwdev, REG_RXSB, BIT(4)); 1442*b870b9d3SBitterblue Smith else 1443*b870b9d3SBitterblue Smith rtw_write32_clr(rtwdev, REG_RXSB, BIT(4)); 1444*b870b9d3SBitterblue Smith 1445*b870b9d3SBitterblue Smith break; 1446*b870b9d3SBitterblue Smith case RTW_CHANNEL_WIDTH_80: 1447*b870b9d3SBitterblue Smith rtw_write32_mask(rtwdev, REG_ADCCLK, 0x003003C3, 0x00300202); 1448*b870b9d3SBitterblue Smith rtw_write32_mask(rtwdev, REG_ADC160, BIT(30), 1); 1449*b870b9d3SBitterblue Smith rtw_write32_mask(rtwdev, REG_ADCCLK, 0x3C, txsc); 1450*b870b9d3SBitterblue Smith rtw_write32_mask(rtwdev, REG_CCA2ND, 0xf0000000, txsc); 1451*b870b9d3SBitterblue Smith 1452*b870b9d3SBitterblue Smith if (reg_837 & BIT(2)) { 1453*b870b9d3SBitterblue Smith l1pkval = 5; 1454*b870b9d3SBitterblue Smith } else { 1455*b870b9d3SBitterblue Smith if (hal->rf_type == RF_2T2R) 1456*b870b9d3SBitterblue Smith l1pkval = 6; 1457*b870b9d3SBitterblue Smith else 1458*b870b9d3SBitterblue Smith l1pkval = 7; 1459*b870b9d3SBitterblue Smith } 1460*b870b9d3SBitterblue Smith 1461*b870b9d3SBitterblue Smith rtw_write32_mask(rtwdev, REG_L1PKTH, 0x03C00000, l1pkval); 1462*b870b9d3SBitterblue Smith 1463*b870b9d3SBitterblue Smith break; 1464*b870b9d3SBitterblue Smith } 1465*b870b9d3SBitterblue Smith } 1466*b870b9d3SBitterblue Smith 1467*b870b9d3SBitterblue Smith static void rtw88xxa_set_channel_rf(struct rtw_dev *rtwdev, u8 channel, u8 bw) 1468*b870b9d3SBitterblue Smith { 1469*b870b9d3SBitterblue Smith u8 path; 1470*b870b9d3SBitterblue Smith 1471*b870b9d3SBitterblue Smith for (path = RF_PATH_A; path < rtwdev->hal.rf_path_num; path++) { 1472*b870b9d3SBitterblue Smith switch (bw) { 1473*b870b9d3SBitterblue Smith case RTW_CHANNEL_WIDTH_5: 1474*b870b9d3SBitterblue Smith case RTW_CHANNEL_WIDTH_10: 1475*b870b9d3SBitterblue Smith case RTW_CHANNEL_WIDTH_20: 1476*b870b9d3SBitterblue Smith default: 1477*b870b9d3SBitterblue Smith rtw_write_rf(rtwdev, path, RF_CFGCH, RF18_BW_MASK, 3); 1478*b870b9d3SBitterblue Smith break; 1479*b870b9d3SBitterblue Smith case RTW_CHANNEL_WIDTH_40: 1480*b870b9d3SBitterblue Smith rtw_write_rf(rtwdev, path, RF_CFGCH, RF18_BW_MASK, 1); 1481*b870b9d3SBitterblue Smith break; 1482*b870b9d3SBitterblue Smith case RTW_CHANNEL_WIDTH_80: 1483*b870b9d3SBitterblue Smith rtw_write_rf(rtwdev, path, RF_CFGCH, RF18_BW_MASK, 0); 1484*b870b9d3SBitterblue Smith break; 1485*b870b9d3SBitterblue Smith } 1486*b870b9d3SBitterblue Smith } 1487*b870b9d3SBitterblue Smith } 1488*b870b9d3SBitterblue Smith 1489*b870b9d3SBitterblue Smith void rtw88xxa_set_channel(struct rtw_dev *rtwdev, u8 channel, u8 bw, 1490*b870b9d3SBitterblue Smith u8 primary_chan_idx) 1491*b870b9d3SBitterblue Smith { 1492*b870b9d3SBitterblue Smith u8 old_band, new_band; 1493*b870b9d3SBitterblue Smith 1494*b870b9d3SBitterblue Smith if (rtw_read8(rtwdev, REG_CCK_CHECK) & BIT_CHECK_CCK_EN) 1495*b870b9d3SBitterblue Smith old_band = RTW_BAND_5G; 1496*b870b9d3SBitterblue Smith else 1497*b870b9d3SBitterblue Smith old_band = RTW_BAND_2G; 1498*b870b9d3SBitterblue Smith 1499*b870b9d3SBitterblue Smith if (channel > 14) 1500*b870b9d3SBitterblue Smith new_band = RTW_BAND_5G; 1501*b870b9d3SBitterblue Smith else 1502*b870b9d3SBitterblue Smith new_band = RTW_BAND_2G; 1503*b870b9d3SBitterblue Smith 1504*b870b9d3SBitterblue Smith if (new_band != old_band) 1505*b870b9d3SBitterblue Smith rtw88xxa_switch_band(rtwdev, new_band, bw); 1506*b870b9d3SBitterblue Smith 1507*b870b9d3SBitterblue Smith rtw88xxa_switch_channel(rtwdev, channel, bw); 1508*b870b9d3SBitterblue Smith 1509*b870b9d3SBitterblue Smith rtw88xxa_post_set_bw_mode(rtwdev, channel, bw, primary_chan_idx); 1510*b870b9d3SBitterblue Smith 1511*b870b9d3SBitterblue Smith if (rtwdev->chip->id == RTW_CHIP_TYPE_8812A) 1512*b870b9d3SBitterblue Smith rtw8812a_phy_fix_spur(rtwdev, channel, bw); 1513*b870b9d3SBitterblue Smith 1514*b870b9d3SBitterblue Smith rtw88xxa_set_channel_rf(rtwdev, channel, bw); 1515*b870b9d3SBitterblue Smith } 1516*b870b9d3SBitterblue Smith EXPORT_SYMBOL(rtw88xxa_set_channel); 1517*b870b9d3SBitterblue Smith 1518*b870b9d3SBitterblue Smith void rtw88xxa_query_phy_status(struct rtw_dev *rtwdev, u8 *phy_status, 1519*b870b9d3SBitterblue Smith struct rtw_rx_pkt_stat *pkt_stat, 1520*b870b9d3SBitterblue Smith s8 (*cck_rx_pwr)(u8 lna_idx, u8 vga_idx)) 1521*b870b9d3SBitterblue Smith { 1522*b870b9d3SBitterblue Smith struct rtw_dm_info *dm_info = &rtwdev->dm_info; 1523*b870b9d3SBitterblue Smith struct rtw_jaguar_phy_status_rpt *rpt; 1524*b870b9d3SBitterblue Smith u8 gain[RTW_RF_PATH_MAX], rssi, i; 1525*b870b9d3SBitterblue Smith s8 rx_pwr_db, power_a, power_b; 1526*b870b9d3SBitterblue Smith const s8 min_rx_power = -120; 1527*b870b9d3SBitterblue Smith u8 lna_idx, vga_idx; 1528*b870b9d3SBitterblue Smith 1529*b870b9d3SBitterblue Smith rpt = (struct rtw_jaguar_phy_status_rpt *)phy_status; 1530*b870b9d3SBitterblue Smith 1531*b870b9d3SBitterblue Smith if (pkt_stat->rate <= DESC_RATE11M) { 1532*b870b9d3SBitterblue Smith lna_idx = le32_get_bits(rpt->w1, RTW_JGRPHY_W1_AGC_RPT_LNA_IDX); 1533*b870b9d3SBitterblue Smith vga_idx = le32_get_bits(rpt->w1, RTW_JGRPHY_W1_AGC_RPT_VGA_IDX); 1534*b870b9d3SBitterblue Smith 1535*b870b9d3SBitterblue Smith rx_pwr_db = cck_rx_pwr(lna_idx, vga_idx); 1536*b870b9d3SBitterblue Smith 1537*b870b9d3SBitterblue Smith pkt_stat->rx_power[RF_PATH_A] = rx_pwr_db; 1538*b870b9d3SBitterblue Smith pkt_stat->rssi = rtw_phy_rf_power_2_rssi(pkt_stat->rx_power, 1); 1539*b870b9d3SBitterblue Smith dm_info->rssi[RF_PATH_A] = pkt_stat->rssi; 1540*b870b9d3SBitterblue Smith pkt_stat->bw = RTW_CHANNEL_WIDTH_20; 1541*b870b9d3SBitterblue Smith pkt_stat->signal_power = rx_pwr_db; 1542*b870b9d3SBitterblue Smith } else { /* OFDM rate */ 1543*b870b9d3SBitterblue Smith gain[RF_PATH_A] = le32_get_bits(rpt->w0, RTW_JGRPHY_W0_GAIN_A); 1544*b870b9d3SBitterblue Smith gain[RF_PATH_B] = le32_get_bits(rpt->w0, RTW_JGRPHY_W0_GAIN_B); 1545*b870b9d3SBitterblue Smith 1546*b870b9d3SBitterblue Smith for (i = RF_PATH_A; i < rtwdev->hal.rf_path_num; i++) { 1547*b870b9d3SBitterblue Smith pkt_stat->rx_power[i] = gain[i] - 110; 1548*b870b9d3SBitterblue Smith rssi = rtw_phy_rf_power_2_rssi(&pkt_stat->rx_power[i], 1); 1549*b870b9d3SBitterblue Smith dm_info->rssi[i] = rssi; 1550*b870b9d3SBitterblue Smith } 1551*b870b9d3SBitterblue Smith 1552*b870b9d3SBitterblue Smith pkt_stat->rssi = rtw_phy_rf_power_2_rssi(pkt_stat->rx_power, 1553*b870b9d3SBitterblue Smith rtwdev->hal.rf_path_num); 1554*b870b9d3SBitterblue Smith 1555*b870b9d3SBitterblue Smith power_a = pkt_stat->rx_power[RF_PATH_A]; 1556*b870b9d3SBitterblue Smith power_b = pkt_stat->rx_power[RF_PATH_B]; 1557*b870b9d3SBitterblue Smith if (rtwdev->hal.rf_path_num == 1) 1558*b870b9d3SBitterblue Smith power_b = power_a; 1559*b870b9d3SBitterblue Smith 1560*b870b9d3SBitterblue Smith pkt_stat->signal_power = max3(power_a, power_b, min_rx_power); 1561*b870b9d3SBitterblue Smith } 1562*b870b9d3SBitterblue Smith } 1563*b870b9d3SBitterblue Smith EXPORT_SYMBOL(rtw88xxa_query_phy_status); 1564*b870b9d3SBitterblue Smith 1565*b870b9d3SBitterblue Smith static void 1566*b870b9d3SBitterblue Smith rtw88xxa_set_tx_power_index_by_rate(struct rtw_dev *rtwdev, u8 path, 1567*b870b9d3SBitterblue Smith u8 rs, u32 *phy_pwr_idx) 1568*b870b9d3SBitterblue Smith { 1569*b870b9d3SBitterblue Smith static const u32 offset_txagc[2] = { 1570*b870b9d3SBitterblue Smith REG_TX_AGC_A_CCK_11_CCK_1, REG_TX_AGC_B_CCK_11_CCK_1 1571*b870b9d3SBitterblue Smith }; 1572*b870b9d3SBitterblue Smith u8 rate, rate_idx, pwr_index, shift; 1573*b870b9d3SBitterblue Smith struct rtw_hal *hal = &rtwdev->hal; 1574*b870b9d3SBitterblue Smith bool write_1ss_mcs9; 1575*b870b9d3SBitterblue Smith u32 mask; 1576*b870b9d3SBitterblue Smith int j; 1577*b870b9d3SBitterblue Smith 1578*b870b9d3SBitterblue Smith for (j = 0; j < rtw_rate_size[rs]; j++) { 1579*b870b9d3SBitterblue Smith rate = rtw_rate_section[rs][j]; 1580*b870b9d3SBitterblue Smith 1581*b870b9d3SBitterblue Smith pwr_index = hal->tx_pwr_tbl[path][rate]; 1582*b870b9d3SBitterblue Smith 1583*b870b9d3SBitterblue Smith shift = rate & 0x3; 1584*b870b9d3SBitterblue Smith *phy_pwr_idx |= ((u32)pwr_index << (shift * 8)); 1585*b870b9d3SBitterblue Smith 1586*b870b9d3SBitterblue Smith write_1ss_mcs9 = rate == DESC_RATEVHT1SS_MCS9 && 1587*b870b9d3SBitterblue Smith hal->rf_path_num == 1; 1588*b870b9d3SBitterblue Smith 1589*b870b9d3SBitterblue Smith if (write_1ss_mcs9) 1590*b870b9d3SBitterblue Smith mask = MASKLWORD; 1591*b870b9d3SBitterblue Smith else 1592*b870b9d3SBitterblue Smith mask = MASKDWORD; 1593*b870b9d3SBitterblue Smith 1594*b870b9d3SBitterblue Smith if (shift == 0x3 || write_1ss_mcs9) { 1595*b870b9d3SBitterblue Smith rate_idx = rate & 0xfc; 1596*b870b9d3SBitterblue Smith if (rate >= DESC_RATEVHT1SS_MCS0) 1597*b870b9d3SBitterblue Smith rate_idx -= 0x10; 1598*b870b9d3SBitterblue Smith 1599*b870b9d3SBitterblue Smith rtw_write32_mask(rtwdev, offset_txagc[path] + rate_idx, 1600*b870b9d3SBitterblue Smith mask, *phy_pwr_idx); 1601*b870b9d3SBitterblue Smith 1602*b870b9d3SBitterblue Smith *phy_pwr_idx = 0; 1603*b870b9d3SBitterblue Smith } 1604*b870b9d3SBitterblue Smith } 1605*b870b9d3SBitterblue Smith } 1606*b870b9d3SBitterblue Smith 1607*b870b9d3SBitterblue Smith static void rtw88xxa_tx_power_training(struct rtw_dev *rtwdev, u8 bw, 1608*b870b9d3SBitterblue Smith u8 channel, u8 path) 1609*b870b9d3SBitterblue Smith { 1610*b870b9d3SBitterblue Smith static const u32 write_offset[] = { 1611*b870b9d3SBitterblue Smith REG_TX_PWR_TRAINING_A, REG_TX_PWR_TRAINING_B, 1612*b870b9d3SBitterblue Smith }; 1613*b870b9d3SBitterblue Smith u32 power_level, write_data; 1614*b870b9d3SBitterblue Smith u8 i; 1615*b870b9d3SBitterblue Smith 1616*b870b9d3SBitterblue Smith power_level = rtwdev->hal.tx_pwr_tbl[path][DESC_RATEMCS7]; 1617*b870b9d3SBitterblue Smith write_data = 0; 1618*b870b9d3SBitterblue Smith 1619*b870b9d3SBitterblue Smith for (i = 0; i < 3; i++) { 1620*b870b9d3SBitterblue Smith if (i == 0) 1621*b870b9d3SBitterblue Smith power_level -= 10; 1622*b870b9d3SBitterblue Smith else if (i == 1) 1623*b870b9d3SBitterblue Smith power_level -= 8; 1624*b870b9d3SBitterblue Smith else 1625*b870b9d3SBitterblue Smith power_level -= 6; 1626*b870b9d3SBitterblue Smith 1627*b870b9d3SBitterblue Smith write_data |= max_t(u32, power_level, 2) << (i * 8); 1628*b870b9d3SBitterblue Smith } 1629*b870b9d3SBitterblue Smith 1630*b870b9d3SBitterblue Smith rtw_write32_mask(rtwdev, write_offset[path], 0xffffff, write_data); 1631*b870b9d3SBitterblue Smith } 1632*b870b9d3SBitterblue Smith 1633*b870b9d3SBitterblue Smith void rtw88xxa_set_tx_power_index(struct rtw_dev *rtwdev) 1634*b870b9d3SBitterblue Smith { 1635*b870b9d3SBitterblue Smith struct rtw_hal *hal = &rtwdev->hal; 1636*b870b9d3SBitterblue Smith u32 phy_pwr_idx = 0; 1637*b870b9d3SBitterblue Smith int rs, path; 1638*b870b9d3SBitterblue Smith 1639*b870b9d3SBitterblue Smith for (path = 0; path < hal->rf_path_num; path++) { 1640*b870b9d3SBitterblue Smith for (rs = 0; rs < RTW_RATE_SECTION_MAX; rs++) { 1641*b870b9d3SBitterblue Smith if (hal->rf_path_num == 1 && 1642*b870b9d3SBitterblue Smith (rs == RTW_RATE_SECTION_HT_2S || 1643*b870b9d3SBitterblue Smith rs == RTW_RATE_SECTION_VHT_2S)) 1644*b870b9d3SBitterblue Smith continue; 1645*b870b9d3SBitterblue Smith 1646*b870b9d3SBitterblue Smith if (test_bit(RTW_FLAG_SCANNING, rtwdev->flags) && 1647*b870b9d3SBitterblue Smith rs > RTW_RATE_SECTION_OFDM) 1648*b870b9d3SBitterblue Smith continue; 1649*b870b9d3SBitterblue Smith 1650*b870b9d3SBitterblue Smith if (hal->current_band_type == RTW_BAND_5G && 1651*b870b9d3SBitterblue Smith rs == RTW_RATE_SECTION_CCK) 1652*b870b9d3SBitterblue Smith continue; 1653*b870b9d3SBitterblue Smith 1654*b870b9d3SBitterblue Smith rtw88xxa_set_tx_power_index_by_rate(rtwdev, path, rs, 1655*b870b9d3SBitterblue Smith &phy_pwr_idx); 1656*b870b9d3SBitterblue Smith } 1657*b870b9d3SBitterblue Smith 1658*b870b9d3SBitterblue Smith rtw88xxa_tx_power_training(rtwdev, hal->current_band_width, 1659*b870b9d3SBitterblue Smith hal->current_channel, path); 1660*b870b9d3SBitterblue Smith } 1661*b870b9d3SBitterblue Smith } 1662*b870b9d3SBitterblue Smith EXPORT_SYMBOL(rtw88xxa_set_tx_power_index); 1663*b870b9d3SBitterblue Smith 1664*b870b9d3SBitterblue Smith void rtw88xxa_false_alarm_statistics(struct rtw_dev *rtwdev) 1665*b870b9d3SBitterblue Smith { 1666*b870b9d3SBitterblue Smith struct rtw_dm_info *dm_info = &rtwdev->dm_info; 1667*b870b9d3SBitterblue Smith u32 cck_fa_cnt, ofdm_fa_cnt; 1668*b870b9d3SBitterblue Smith u32 crc32_cnt, cca32_cnt; 1669*b870b9d3SBitterblue Smith u32 cck_enable; 1670*b870b9d3SBitterblue Smith 1671*b870b9d3SBitterblue Smith cck_enable = rtw_read32(rtwdev, REG_RXPSEL) & BIT(28); 1672*b870b9d3SBitterblue Smith cck_fa_cnt = rtw_read16(rtwdev, REG_FA_CCK); 1673*b870b9d3SBitterblue Smith ofdm_fa_cnt = rtw_read16(rtwdev, REG_FA_OFDM); 1674*b870b9d3SBitterblue Smith 1675*b870b9d3SBitterblue Smith dm_info->cck_fa_cnt = cck_fa_cnt; 1676*b870b9d3SBitterblue Smith dm_info->ofdm_fa_cnt = ofdm_fa_cnt; 1677*b870b9d3SBitterblue Smith dm_info->total_fa_cnt = ofdm_fa_cnt; 1678*b870b9d3SBitterblue Smith if (cck_enable) 1679*b870b9d3SBitterblue Smith dm_info->total_fa_cnt += cck_fa_cnt; 1680*b870b9d3SBitterblue Smith 1681*b870b9d3SBitterblue Smith crc32_cnt = rtw_read32(rtwdev, REG_CRC_CCK); 1682*b870b9d3SBitterblue Smith dm_info->cck_ok_cnt = u32_get_bits(crc32_cnt, MASKLWORD); 1683*b870b9d3SBitterblue Smith dm_info->cck_err_cnt = u32_get_bits(crc32_cnt, MASKHWORD); 1684*b870b9d3SBitterblue Smith 1685*b870b9d3SBitterblue Smith crc32_cnt = rtw_read32(rtwdev, REG_CRC_OFDM); 1686*b870b9d3SBitterblue Smith dm_info->ofdm_ok_cnt = u32_get_bits(crc32_cnt, MASKLWORD); 1687*b870b9d3SBitterblue Smith dm_info->ofdm_err_cnt = u32_get_bits(crc32_cnt, MASKHWORD); 1688*b870b9d3SBitterblue Smith 1689*b870b9d3SBitterblue Smith crc32_cnt = rtw_read32(rtwdev, REG_CRC_HT); 1690*b870b9d3SBitterblue Smith dm_info->ht_ok_cnt = u32_get_bits(crc32_cnt, MASKLWORD); 1691*b870b9d3SBitterblue Smith dm_info->ht_err_cnt = u32_get_bits(crc32_cnt, MASKHWORD); 1692*b870b9d3SBitterblue Smith 1693*b870b9d3SBitterblue Smith crc32_cnt = rtw_read32(rtwdev, REG_CRC_VHT); 1694*b870b9d3SBitterblue Smith dm_info->vht_ok_cnt = u32_get_bits(crc32_cnt, MASKLWORD); 1695*b870b9d3SBitterblue Smith dm_info->vht_err_cnt = u32_get_bits(crc32_cnt, MASKHWORD); 1696*b870b9d3SBitterblue Smith 1697*b870b9d3SBitterblue Smith cca32_cnt = rtw_read32(rtwdev, REG_CCA_OFDM); 1698*b870b9d3SBitterblue Smith dm_info->ofdm_cca_cnt = u32_get_bits(cca32_cnt, MASKHWORD); 1699*b870b9d3SBitterblue Smith dm_info->total_cca_cnt = dm_info->ofdm_cca_cnt; 1700*b870b9d3SBitterblue Smith if (cck_enable) { 1701*b870b9d3SBitterblue Smith cca32_cnt = rtw_read32(rtwdev, REG_CCA_CCK); 1702*b870b9d3SBitterblue Smith dm_info->cck_cca_cnt = u32_get_bits(cca32_cnt, MASKLWORD); 1703*b870b9d3SBitterblue Smith dm_info->total_cca_cnt += dm_info->cck_cca_cnt; 1704*b870b9d3SBitterblue Smith } 1705*b870b9d3SBitterblue Smith 1706*b870b9d3SBitterblue Smith rtw_write32_set(rtwdev, REG_FAS, BIT(17)); 1707*b870b9d3SBitterblue Smith rtw_write32_clr(rtwdev, REG_FAS, BIT(17)); 1708*b870b9d3SBitterblue Smith rtw_write32_clr(rtwdev, REG_CCK0_FAREPORT, BIT(15)); 1709*b870b9d3SBitterblue Smith rtw_write32_set(rtwdev, REG_CCK0_FAREPORT, BIT(15)); 1710*b870b9d3SBitterblue Smith rtw_write32_set(rtwdev, REG_CNTRST, BIT(0)); 1711*b870b9d3SBitterblue Smith rtw_write32_clr(rtwdev, REG_CNTRST, BIT(0)); 1712*b870b9d3SBitterblue Smith } 1713*b870b9d3SBitterblue Smith EXPORT_SYMBOL(rtw88xxa_false_alarm_statistics); 1714*b870b9d3SBitterblue Smith 1715*b870b9d3SBitterblue Smith void rtw88xxa_iqk_backup_mac_bb(struct rtw_dev *rtwdev, 1716*b870b9d3SBitterblue Smith u32 *macbb_backup, 1717*b870b9d3SBitterblue Smith const u32 *backup_macbb_reg, 1718*b870b9d3SBitterblue Smith u32 macbb_num) 1719*b870b9d3SBitterblue Smith { 1720*b870b9d3SBitterblue Smith u32 i; 1721*b870b9d3SBitterblue Smith 1722*b870b9d3SBitterblue Smith /* [31] = 0 --> Page C */ 1723*b870b9d3SBitterblue Smith rtw_write32_mask(rtwdev, REG_CCASEL, BIT(31), 0x0); 1724*b870b9d3SBitterblue Smith 1725*b870b9d3SBitterblue Smith /* save MACBB default value */ 1726*b870b9d3SBitterblue Smith for (i = 0; i < macbb_num; i++) 1727*b870b9d3SBitterblue Smith macbb_backup[i] = rtw_read32(rtwdev, backup_macbb_reg[i]); 1728*b870b9d3SBitterblue Smith } 1729*b870b9d3SBitterblue Smith EXPORT_SYMBOL(rtw88xxa_iqk_backup_mac_bb); 1730*b870b9d3SBitterblue Smith 1731*b870b9d3SBitterblue Smith void rtw88xxa_iqk_backup_afe(struct rtw_dev *rtwdev, u32 *afe_backup, 1732*b870b9d3SBitterblue Smith const u32 *backup_afe_reg, u32 afe_num) 1733*b870b9d3SBitterblue Smith { 1734*b870b9d3SBitterblue Smith u32 i; 1735*b870b9d3SBitterblue Smith 1736*b870b9d3SBitterblue Smith /* [31] = 0 --> Page C */ 1737*b870b9d3SBitterblue Smith rtw_write32_mask(rtwdev, REG_CCASEL, BIT(31), 0x0); 1738*b870b9d3SBitterblue Smith 1739*b870b9d3SBitterblue Smith /* Save AFE Parameters */ 1740*b870b9d3SBitterblue Smith for (i = 0; i < afe_num; i++) 1741*b870b9d3SBitterblue Smith afe_backup[i] = rtw_read32(rtwdev, backup_afe_reg[i]); 1742*b870b9d3SBitterblue Smith } 1743*b870b9d3SBitterblue Smith EXPORT_SYMBOL(rtw88xxa_iqk_backup_afe); 1744*b870b9d3SBitterblue Smith 1745*b870b9d3SBitterblue Smith void rtw88xxa_iqk_restore_mac_bb(struct rtw_dev *rtwdev, 1746*b870b9d3SBitterblue Smith u32 *macbb_backup, 1747*b870b9d3SBitterblue Smith const u32 *backup_macbb_reg, 1748*b870b9d3SBitterblue Smith u32 macbb_num) 1749*b870b9d3SBitterblue Smith { 1750*b870b9d3SBitterblue Smith u32 i; 1751*b870b9d3SBitterblue Smith 1752*b870b9d3SBitterblue Smith /* [31] = 0 --> Page C */ 1753*b870b9d3SBitterblue Smith rtw_write32_mask(rtwdev, REG_CCASEL, BIT(31), 0x0); 1754*b870b9d3SBitterblue Smith 1755*b870b9d3SBitterblue Smith /* Reload MacBB Parameters */ 1756*b870b9d3SBitterblue Smith for (i = 0; i < macbb_num; i++) 1757*b870b9d3SBitterblue Smith rtw_write32(rtwdev, backup_macbb_reg[i], macbb_backup[i]); 1758*b870b9d3SBitterblue Smith } 1759*b870b9d3SBitterblue Smith EXPORT_SYMBOL(rtw88xxa_iqk_restore_mac_bb); 1760*b870b9d3SBitterblue Smith 1761*b870b9d3SBitterblue Smith void rtw88xxa_iqk_configure_mac(struct rtw_dev *rtwdev) 1762*b870b9d3SBitterblue Smith { 1763*b870b9d3SBitterblue Smith /* [31] = 0 --> Page C */ 1764*b870b9d3SBitterblue Smith rtw_write32_mask(rtwdev, REG_CCASEL, BIT(31), 0x0); 1765*b870b9d3SBitterblue Smith 1766*b870b9d3SBitterblue Smith rtw_write8(rtwdev, REG_TXPAUSE, 0x3f); 1767*b870b9d3SBitterblue Smith rtw_write32_mask(rtwdev, REG_BCN_CTRL, 1768*b870b9d3SBitterblue Smith (BIT_EN_BCN_FUNCTION << 8) | BIT_EN_BCN_FUNCTION, 0x0); 1769*b870b9d3SBitterblue Smith 1770*b870b9d3SBitterblue Smith /* RX ante off */ 1771*b870b9d3SBitterblue Smith rtw_write8(rtwdev, REG_RXPSEL, 0x00); 1772*b870b9d3SBitterblue Smith 1773*b870b9d3SBitterblue Smith /* CCA off */ 1774*b870b9d3SBitterblue Smith rtw_write32_mask(rtwdev, REG_CCA2ND, 0xf, 0xc); 1775*b870b9d3SBitterblue Smith 1776*b870b9d3SBitterblue Smith /* CCK RX path off */ 1777*b870b9d3SBitterblue Smith rtw_write8(rtwdev, REG_CCK_RX + 3, 0xf); 1778*b870b9d3SBitterblue Smith } 1779*b870b9d3SBitterblue Smith EXPORT_SYMBOL(rtw88xxa_iqk_configure_mac); 1780*b870b9d3SBitterblue Smith 1781*b870b9d3SBitterblue Smith bool rtw88xxa_iqk_finish(int average, int threshold, 1782*b870b9d3SBitterblue Smith int *x_temp, int *y_temp, int *x, int *y, 1783*b870b9d3SBitterblue Smith bool break_inner, bool break_outer) 1784*b870b9d3SBitterblue Smith { 1785*b870b9d3SBitterblue Smith bool finish = false; 1786*b870b9d3SBitterblue Smith int i, ii, dx, dy; 1787*b870b9d3SBitterblue Smith 1788*b870b9d3SBitterblue Smith for (i = 0; i < average; i++) { 1789*b870b9d3SBitterblue Smith for (ii = i + 1; ii < average; ii++) { 1790*b870b9d3SBitterblue Smith dx = abs_diff(x_temp[i] >> 21, x_temp[ii] >> 21); 1791*b870b9d3SBitterblue Smith dy = abs_diff(y_temp[i] >> 21, y_temp[ii] >> 21); 1792*b870b9d3SBitterblue Smith 1793*b870b9d3SBitterblue Smith if (dx < threshold && dy < threshold) { 1794*b870b9d3SBitterblue Smith *x = ((x_temp[i] >> 21) + (x_temp[ii] >> 21)); 1795*b870b9d3SBitterblue Smith *y = ((y_temp[i] >> 21) + (y_temp[ii] >> 21)); 1796*b870b9d3SBitterblue Smith 1797*b870b9d3SBitterblue Smith *x /= 2; 1798*b870b9d3SBitterblue Smith *y /= 2; 1799*b870b9d3SBitterblue Smith 1800*b870b9d3SBitterblue Smith finish = true; 1801*b870b9d3SBitterblue Smith 1802*b870b9d3SBitterblue Smith if (break_inner) 1803*b870b9d3SBitterblue Smith break; 1804*b870b9d3SBitterblue Smith } 1805*b870b9d3SBitterblue Smith } 1806*b870b9d3SBitterblue Smith 1807*b870b9d3SBitterblue Smith if (finish && break_outer) 1808*b870b9d3SBitterblue Smith break; 1809*b870b9d3SBitterblue Smith } 1810*b870b9d3SBitterblue Smith 1811*b870b9d3SBitterblue Smith return finish; 1812*b870b9d3SBitterblue Smith } 1813*b870b9d3SBitterblue Smith EXPORT_SYMBOL(rtw88xxa_iqk_finish); 1814*b870b9d3SBitterblue Smith 1815*b870b9d3SBitterblue Smith static void rtw88xxa_pwrtrack_set(struct rtw_dev *rtwdev, u8 tx_rate, u8 path) 1816*b870b9d3SBitterblue Smith { 1817*b870b9d3SBitterblue Smith static const u32 reg_txscale[2] = { REG_TXSCALE_A, REG_TXSCALE_B }; 1818*b870b9d3SBitterblue Smith struct rtw_dm_info *dm_info = &rtwdev->dm_info; 1819*b870b9d3SBitterblue Smith u8 cck_swing_idx, ofdm_swing_idx; 1820*b870b9d3SBitterblue Smith u8 pwr_tracking_limit; 1821*b870b9d3SBitterblue Smith 1822*b870b9d3SBitterblue Smith switch (tx_rate) { 1823*b870b9d3SBitterblue Smith case DESC_RATE1M ... DESC_RATE11M: 1824*b870b9d3SBitterblue Smith pwr_tracking_limit = 32; 1825*b870b9d3SBitterblue Smith break; 1826*b870b9d3SBitterblue Smith case DESC_RATE6M ... DESC_RATE48M: 1827*b870b9d3SBitterblue Smith case DESC_RATEMCS3 ... DESC_RATEMCS4: 1828*b870b9d3SBitterblue Smith case DESC_RATEMCS11 ... DESC_RATEMCS12: 1829*b870b9d3SBitterblue Smith case DESC_RATEVHT1SS_MCS3 ... DESC_RATEVHT1SS_MCS4: 1830*b870b9d3SBitterblue Smith case DESC_RATEVHT2SS_MCS3 ... DESC_RATEVHT2SS_MCS4: 1831*b870b9d3SBitterblue Smith pwr_tracking_limit = 30; 1832*b870b9d3SBitterblue Smith break; 1833*b870b9d3SBitterblue Smith case DESC_RATE54M: 1834*b870b9d3SBitterblue Smith case DESC_RATEMCS5 ... DESC_RATEMCS7: 1835*b870b9d3SBitterblue Smith case DESC_RATEMCS13 ... DESC_RATEMCS15: 1836*b870b9d3SBitterblue Smith case DESC_RATEVHT1SS_MCS5 ... DESC_RATEVHT1SS_MCS6: 1837*b870b9d3SBitterblue Smith case DESC_RATEVHT2SS_MCS5 ... DESC_RATEVHT2SS_MCS6: 1838*b870b9d3SBitterblue Smith pwr_tracking_limit = 28; 1839*b870b9d3SBitterblue Smith break; 1840*b870b9d3SBitterblue Smith case DESC_RATEMCS0 ... DESC_RATEMCS2: 1841*b870b9d3SBitterblue Smith case DESC_RATEMCS8 ... DESC_RATEMCS10: 1842*b870b9d3SBitterblue Smith case DESC_RATEVHT1SS_MCS0 ... DESC_RATEVHT1SS_MCS2: 1843*b870b9d3SBitterblue Smith case DESC_RATEVHT2SS_MCS0 ... DESC_RATEVHT2SS_MCS2: 1844*b870b9d3SBitterblue Smith pwr_tracking_limit = 34; 1845*b870b9d3SBitterblue Smith break; 1846*b870b9d3SBitterblue Smith case DESC_RATEVHT1SS_MCS7: 1847*b870b9d3SBitterblue Smith case DESC_RATEVHT2SS_MCS7: 1848*b870b9d3SBitterblue Smith pwr_tracking_limit = 26; 1849*b870b9d3SBitterblue Smith break; 1850*b870b9d3SBitterblue Smith default: 1851*b870b9d3SBitterblue Smith case DESC_RATEVHT1SS_MCS8: 1852*b870b9d3SBitterblue Smith case DESC_RATEVHT2SS_MCS8: 1853*b870b9d3SBitterblue Smith pwr_tracking_limit = 24; 1854*b870b9d3SBitterblue Smith break; 1855*b870b9d3SBitterblue Smith case DESC_RATEVHT1SS_MCS9: 1856*b870b9d3SBitterblue Smith case DESC_RATEVHT2SS_MCS9: 1857*b870b9d3SBitterblue Smith pwr_tracking_limit = 22; 1858*b870b9d3SBitterblue Smith break; 1859*b870b9d3SBitterblue Smith } 1860*b870b9d3SBitterblue Smith 1861*b870b9d3SBitterblue Smith cck_swing_idx = dm_info->delta_power_index[path] + dm_info->default_cck_index; 1862*b870b9d3SBitterblue Smith ofdm_swing_idx = dm_info->delta_power_index[path] + dm_info->default_ofdm_index; 1863*b870b9d3SBitterblue Smith 1864*b870b9d3SBitterblue Smith if (ofdm_swing_idx > pwr_tracking_limit) { 1865*b870b9d3SBitterblue Smith if (path == RF_PATH_A) 1866*b870b9d3SBitterblue Smith dm_info->txagc_remnant_cck = cck_swing_idx - pwr_tracking_limit; 1867*b870b9d3SBitterblue Smith dm_info->txagc_remnant_ofdm[path] = ofdm_swing_idx - pwr_tracking_limit; 1868*b870b9d3SBitterblue Smith 1869*b870b9d3SBitterblue Smith ofdm_swing_idx = pwr_tracking_limit; 1870*b870b9d3SBitterblue Smith } else if (ofdm_swing_idx == 0) { 1871*b870b9d3SBitterblue Smith if (path == RF_PATH_A) 1872*b870b9d3SBitterblue Smith dm_info->txagc_remnant_cck = cck_swing_idx; 1873*b870b9d3SBitterblue Smith dm_info->txagc_remnant_ofdm[path] = ofdm_swing_idx; 1874*b870b9d3SBitterblue Smith } else { 1875*b870b9d3SBitterblue Smith if (path == RF_PATH_A) 1876*b870b9d3SBitterblue Smith dm_info->txagc_remnant_cck = 0; 1877*b870b9d3SBitterblue Smith dm_info->txagc_remnant_ofdm[path] = 0; 1878*b870b9d3SBitterblue Smith } 1879*b870b9d3SBitterblue Smith 1880*b870b9d3SBitterblue Smith rtw_write32_mask(rtwdev, reg_txscale[path], GENMASK(31, 21), 1881*b870b9d3SBitterblue Smith rtw88xxa_txscale_tbl[ofdm_swing_idx]); 1882*b870b9d3SBitterblue Smith } 1883*b870b9d3SBitterblue Smith 1884*b870b9d3SBitterblue Smith void rtw88xxa_phy_pwrtrack(struct rtw_dev *rtwdev, 1885*b870b9d3SBitterblue Smith void (*do_lck)(struct rtw_dev *rtwdev), 1886*b870b9d3SBitterblue Smith void (*do_iqk)(struct rtw_dev *rtwdev)) 1887*b870b9d3SBitterblue Smith { 1888*b870b9d3SBitterblue Smith struct rtw_dm_info *dm_info = &rtwdev->dm_info; 1889*b870b9d3SBitterblue Smith struct rtw_hal *hal = &rtwdev->hal; 1890*b870b9d3SBitterblue Smith struct rtw_swing_table swing_table; 1891*b870b9d3SBitterblue Smith s8 remnant_pre[RTW_RF_PATH_MAX]; 1892*b870b9d3SBitterblue Smith u8 thermal_value, delta, path; 1893*b870b9d3SBitterblue Smith bool need_iqk; 1894*b870b9d3SBitterblue Smith 1895*b870b9d3SBitterblue Smith rtw_phy_config_swing_table(rtwdev, &swing_table); 1896*b870b9d3SBitterblue Smith 1897*b870b9d3SBitterblue Smith if (rtwdev->efuse.thermal_meter[0] == 0xff) { 1898*b870b9d3SBitterblue Smith pr_err_once("efuse thermal meter is 0xff\n"); 1899*b870b9d3SBitterblue Smith return; 1900*b870b9d3SBitterblue Smith } 1901*b870b9d3SBitterblue Smith 1902*b870b9d3SBitterblue Smith thermal_value = rtw_read_rf(rtwdev, RF_PATH_A, RF_T_METER, 0xfc00); 1903*b870b9d3SBitterblue Smith 1904*b870b9d3SBitterblue Smith rtw_phy_pwrtrack_avg(rtwdev, thermal_value, RF_PATH_A); 1905*b870b9d3SBitterblue Smith 1906*b870b9d3SBitterblue Smith need_iqk = rtw_phy_pwrtrack_need_iqk(rtwdev); 1907*b870b9d3SBitterblue Smith 1908*b870b9d3SBitterblue Smith if (need_iqk && do_lck) 1909*b870b9d3SBitterblue Smith do_lck(rtwdev); 1910*b870b9d3SBitterblue Smith 1911*b870b9d3SBitterblue Smith if (dm_info->pwr_trk_init_trigger) 1912*b870b9d3SBitterblue Smith dm_info->pwr_trk_init_trigger = false; 1913*b870b9d3SBitterblue Smith else if (!rtw_phy_pwrtrack_thermal_changed(rtwdev, thermal_value, 1914*b870b9d3SBitterblue Smith RF_PATH_A)) 1915*b870b9d3SBitterblue Smith goto iqk; 1916*b870b9d3SBitterblue Smith 1917*b870b9d3SBitterblue Smith delta = rtw_phy_pwrtrack_get_delta(rtwdev, RF_PATH_A); 1918*b870b9d3SBitterblue Smith 1919*b870b9d3SBitterblue Smith for (path = RF_PATH_A; path < hal->rf_path_num; path++) { 1920*b870b9d3SBitterblue Smith remnant_pre[path] = dm_info->txagc_remnant_ofdm[path]; 1921*b870b9d3SBitterblue Smith 1922*b870b9d3SBitterblue Smith dm_info->delta_power_index[path] = 1923*b870b9d3SBitterblue Smith rtw_phy_pwrtrack_get_pwridx(rtwdev, &swing_table, path, 1924*b870b9d3SBitterblue Smith RF_PATH_A, delta); 1925*b870b9d3SBitterblue Smith 1926*b870b9d3SBitterblue Smith if (dm_info->delta_power_index[path] != 1927*b870b9d3SBitterblue Smith dm_info->delta_power_index_last[path]) { 1928*b870b9d3SBitterblue Smith dm_info->delta_power_index_last[path] = 1929*b870b9d3SBitterblue Smith dm_info->delta_power_index[path]; 1930*b870b9d3SBitterblue Smith 1931*b870b9d3SBitterblue Smith rtw88xxa_pwrtrack_set(rtwdev, dm_info->tx_rate, path); 1932*b870b9d3SBitterblue Smith } 1933*b870b9d3SBitterblue Smith } 1934*b870b9d3SBitterblue Smith 1935*b870b9d3SBitterblue Smith for (path = RF_PATH_A; path < hal->rf_path_num; path++) { 1936*b870b9d3SBitterblue Smith if (remnant_pre[path] != dm_info->txagc_remnant_ofdm[path]) { 1937*b870b9d3SBitterblue Smith rtw_phy_set_tx_power_level(rtwdev, 1938*b870b9d3SBitterblue Smith hal->current_channel); 1939*b870b9d3SBitterblue Smith break; 1940*b870b9d3SBitterblue Smith } 1941*b870b9d3SBitterblue Smith } 1942*b870b9d3SBitterblue Smith 1943*b870b9d3SBitterblue Smith iqk: 1944*b870b9d3SBitterblue Smith if (need_iqk) 1945*b870b9d3SBitterblue Smith do_iqk(rtwdev); 1946*b870b9d3SBitterblue Smith } 1947*b870b9d3SBitterblue Smith EXPORT_SYMBOL(rtw88xxa_phy_pwrtrack); 1948*b870b9d3SBitterblue Smith 1949*b870b9d3SBitterblue Smith void rtw88xxa_phy_cck_pd_set(struct rtw_dev *rtwdev, u8 new_lvl) 1950*b870b9d3SBitterblue Smith { 1951*b870b9d3SBitterblue Smith static const u8 pd[CCK_PD_LV_MAX] = {0x40, 0x83, 0xcd, 0xdd, 0xed}; 1952*b870b9d3SBitterblue Smith struct rtw_dm_info *dm_info = &rtwdev->dm_info; 1953*b870b9d3SBitterblue Smith 1954*b870b9d3SBitterblue Smith /* Override rtw_phy_cck_pd_lv_link(). It implements something 1955*b870b9d3SBitterblue Smith * like type 2/3/4. We need type 1 here. 1956*b870b9d3SBitterblue Smith */ 1957*b870b9d3SBitterblue Smith if (rtw_is_assoc(rtwdev)) { 1958*b870b9d3SBitterblue Smith if (dm_info->min_rssi > 60) { 1959*b870b9d3SBitterblue Smith new_lvl = CCK_PD_LV3; 1960*b870b9d3SBitterblue Smith } else if (dm_info->min_rssi > 35) { 1961*b870b9d3SBitterblue Smith new_lvl = CCK_PD_LV2; 1962*b870b9d3SBitterblue Smith } else if (dm_info->min_rssi > 20) { 1963*b870b9d3SBitterblue Smith if (dm_info->cck_fa_avg > 500) 1964*b870b9d3SBitterblue Smith new_lvl = CCK_PD_LV2; 1965*b870b9d3SBitterblue Smith else if (dm_info->cck_fa_avg < 250) 1966*b870b9d3SBitterblue Smith new_lvl = CCK_PD_LV1; 1967*b870b9d3SBitterblue Smith else 1968*b870b9d3SBitterblue Smith return; 1969*b870b9d3SBitterblue Smith } else { 1970*b870b9d3SBitterblue Smith new_lvl = CCK_PD_LV1; 1971*b870b9d3SBitterblue Smith } 1972*b870b9d3SBitterblue Smith } 1973*b870b9d3SBitterblue Smith 1974*b870b9d3SBitterblue Smith rtw_dbg(rtwdev, RTW_DBG_PHY, "lv: (%d) -> (%d)\n", 1975*b870b9d3SBitterblue Smith dm_info->cck_pd_lv[RTW_CHANNEL_WIDTH_20][RF_PATH_A], new_lvl); 1976*b870b9d3SBitterblue Smith 1977*b870b9d3SBitterblue Smith if (dm_info->cck_pd_lv[RTW_CHANNEL_WIDTH_20][RF_PATH_A] == new_lvl) 1978*b870b9d3SBitterblue Smith return; 1979*b870b9d3SBitterblue Smith 1980*b870b9d3SBitterblue Smith dm_info->cck_fa_avg = CCK_FA_AVG_RESET; 1981*b870b9d3SBitterblue Smith dm_info->cck_pd_lv[RTW_CHANNEL_WIDTH_20][RF_PATH_A] = new_lvl; 1982*b870b9d3SBitterblue Smith 1983*b870b9d3SBitterblue Smith rtw_write8(rtwdev, REG_CCK_PD_TH, pd[new_lvl]); 1984*b870b9d3SBitterblue Smith } 1985*b870b9d3SBitterblue Smith EXPORT_SYMBOL(rtw88xxa_phy_cck_pd_set); 1986*b870b9d3SBitterblue Smith 1987*b870b9d3SBitterblue Smith MODULE_AUTHOR("Realtek Corporation"); 1988*b870b9d3SBitterblue Smith MODULE_DESCRIPTION("Realtek 802.11ac wireless 8821a/8811a/8812a common code"); 1989*b870b9d3SBitterblue Smith MODULE_LICENSE("Dual BSD/GPL"); 1990