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