12774f206SBjoern A. Zeeb // SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause 22774f206SBjoern A. Zeeb /* Copyright(c) 2018-2019 Realtek Corporation 32774f206SBjoern A. Zeeb */ 42774f206SBjoern A. Zeeb 52774f206SBjoern A. Zeeb #include "main.h" 62774f206SBjoern A. Zeeb #include "coex.h" 72774f206SBjoern A. Zeeb #include "fw.h" 82774f206SBjoern A. Zeeb #include "tx.h" 92774f206SBjoern A. Zeeb #include "rx.h" 102774f206SBjoern A. Zeeb #include "phy.h" 112774f206SBjoern A. Zeeb #include "rtw8821c.h" 122774f206SBjoern A. Zeeb #include "rtw8821c_table.h" 132774f206SBjoern A. Zeeb #include "mac.h" 142774f206SBjoern A. Zeeb #include "reg.h" 152774f206SBjoern A. Zeeb #include "debug.h" 162774f206SBjoern A. Zeeb #include "bf.h" 172774f206SBjoern A. Zeeb #include "regd.h" 182774f206SBjoern A. Zeeb 192774f206SBjoern A. Zeeb static const s8 lna_gain_table_0[8] = {22, 8, -6, -22, -31, -40, -46, -52}; 202774f206SBjoern A. Zeeb static const s8 lna_gain_table_1[16] = {10, 6, 2, -2, -6, -10, -14, -17, 212774f206SBjoern A. Zeeb -20, -24, -28, -31, -34, -37, -40, -44}; 222774f206SBjoern A. Zeeb 232774f206SBjoern A. Zeeb static void rtw8821ce_efuse_parsing(struct rtw_efuse *efuse, 242774f206SBjoern A. Zeeb struct rtw8821c_efuse *map) 252774f206SBjoern A. Zeeb { 262774f206SBjoern A. Zeeb ether_addr_copy(efuse->addr, map->e.mac_addr); 272774f206SBjoern A. Zeeb } 282774f206SBjoern A. Zeeb 2990aac0d8SBjoern A. Zeeb static void rtw8821cu_efuse_parsing(struct rtw_efuse *efuse, 3090aac0d8SBjoern A. Zeeb struct rtw8821c_efuse *map) 3190aac0d8SBjoern A. Zeeb { 3290aac0d8SBjoern A. Zeeb ether_addr_copy(efuse->addr, map->u.mac_addr); 3390aac0d8SBjoern A. Zeeb } 3490aac0d8SBjoern A. Zeeb 3590aac0d8SBjoern A. Zeeb static void rtw8821cs_efuse_parsing(struct rtw_efuse *efuse, 3690aac0d8SBjoern A. Zeeb struct rtw8821c_efuse *map) 3790aac0d8SBjoern A. Zeeb { 3890aac0d8SBjoern A. Zeeb ether_addr_copy(efuse->addr, map->s.mac_addr); 3990aac0d8SBjoern A. Zeeb } 4090aac0d8SBjoern A. Zeeb 412774f206SBjoern A. Zeeb enum rtw8821ce_rf_set { 422774f206SBjoern A. Zeeb SWITCH_TO_BTG, 432774f206SBjoern A. Zeeb SWITCH_TO_WLG, 442774f206SBjoern A. Zeeb SWITCH_TO_WLA, 452774f206SBjoern A. Zeeb SWITCH_TO_BT, 462774f206SBjoern A. Zeeb }; 472774f206SBjoern A. Zeeb 482774f206SBjoern A. Zeeb static int rtw8821c_read_efuse(struct rtw_dev *rtwdev, u8 *log_map) 492774f206SBjoern A. Zeeb { 5090aac0d8SBjoern A. Zeeb struct rtw_hal *hal = &rtwdev->hal; 512774f206SBjoern A. Zeeb struct rtw_efuse *efuse = &rtwdev->efuse; 522774f206SBjoern A. Zeeb struct rtw8821c_efuse *map; 532774f206SBjoern A. Zeeb int i; 542774f206SBjoern A. Zeeb 552774f206SBjoern A. Zeeb map = (struct rtw8821c_efuse *)log_map; 562774f206SBjoern A. Zeeb 5790aac0d8SBjoern A. Zeeb efuse->rfe_option = map->rfe_option & 0x1f; 582774f206SBjoern A. Zeeb efuse->rf_board_option = map->rf_board_option; 592774f206SBjoern A. Zeeb efuse->crystal_cap = map->xtal_k; 602774f206SBjoern A. Zeeb efuse->pa_type_2g = map->pa_type; 612774f206SBjoern A. Zeeb efuse->pa_type_5g = map->pa_type; 622774f206SBjoern A. Zeeb efuse->lna_type_2g = map->lna_type_2g[0]; 632774f206SBjoern A. Zeeb efuse->lna_type_5g = map->lna_type_5g[0]; 642774f206SBjoern A. Zeeb efuse->channel_plan = map->channel_plan; 652774f206SBjoern A. Zeeb efuse->country_code[0] = map->country_code[0]; 662774f206SBjoern A. Zeeb efuse->country_code[1] = map->country_code[1]; 672774f206SBjoern A. Zeeb efuse->bt_setting = map->rf_bt_setting; 682774f206SBjoern A. Zeeb efuse->regd = map->rf_board_option & 0x7; 692774f206SBjoern A. Zeeb efuse->thermal_meter[0] = map->thermal_meter; 702774f206SBjoern A. Zeeb efuse->thermal_meter_k = map->thermal_meter; 712774f206SBjoern A. Zeeb efuse->tx_bb_swing_setting_2g = map->tx_bb_swing_setting_2g; 722774f206SBjoern A. Zeeb efuse->tx_bb_swing_setting_5g = map->tx_bb_swing_setting_5g; 732774f206SBjoern A. Zeeb 7490aac0d8SBjoern A. Zeeb hal->pkg_type = map->rfe_option & BIT(5) ? 1 : 0; 7590aac0d8SBjoern A. Zeeb 7690aac0d8SBjoern A. Zeeb switch (efuse->rfe_option) { 7790aac0d8SBjoern A. Zeeb case 0x2: 7890aac0d8SBjoern A. Zeeb case 0x4: 7990aac0d8SBjoern A. Zeeb case 0x7: 8090aac0d8SBjoern A. Zeeb case 0xa: 8190aac0d8SBjoern A. Zeeb case 0xc: 8290aac0d8SBjoern A. Zeeb case 0xf: 8390aac0d8SBjoern A. Zeeb hal->rfe_btg = true; 8490aac0d8SBjoern A. Zeeb break; 8590aac0d8SBjoern A. Zeeb } 8690aac0d8SBjoern A. Zeeb 872774f206SBjoern A. Zeeb for (i = 0; i < 4; i++) 882774f206SBjoern A. Zeeb efuse->txpwr_idx_table[i] = map->txpwr_idx_table[i]; 892774f206SBjoern A. Zeeb 902774f206SBjoern A. Zeeb if (rtwdev->efuse.rfe_option == 2 || rtwdev->efuse.rfe_option == 4) 912774f206SBjoern A. Zeeb efuse->txpwr_idx_table[0].pwr_idx_2g = map->txpwr_idx_table[1].pwr_idx_2g; 922774f206SBjoern A. Zeeb 932774f206SBjoern A. Zeeb switch (rtw_hci_type(rtwdev)) { 942774f206SBjoern A. Zeeb case RTW_HCI_TYPE_PCIE: 952774f206SBjoern A. Zeeb rtw8821ce_efuse_parsing(efuse, map); 962774f206SBjoern A. Zeeb break; 9790aac0d8SBjoern A. Zeeb case RTW_HCI_TYPE_USB: 9890aac0d8SBjoern A. Zeeb rtw8821cu_efuse_parsing(efuse, map); 9990aac0d8SBjoern A. Zeeb break; 10090aac0d8SBjoern A. Zeeb case RTW_HCI_TYPE_SDIO: 10190aac0d8SBjoern A. Zeeb rtw8821cs_efuse_parsing(efuse, map); 10290aac0d8SBjoern A. Zeeb break; 1032774f206SBjoern A. Zeeb default: 1042774f206SBjoern A. Zeeb /* unsupported now */ 1052774f206SBjoern A. Zeeb return -ENOTSUPP; 1062774f206SBjoern A. Zeeb } 1072774f206SBjoern A. Zeeb 1082774f206SBjoern A. Zeeb return 0; 1092774f206SBjoern A. Zeeb } 1102774f206SBjoern A. Zeeb 1112774f206SBjoern A. Zeeb static const u32 rtw8821c_txscale_tbl[] = { 1122774f206SBjoern A. Zeeb 0x081, 0x088, 0x090, 0x099, 0x0a2, 0x0ac, 0x0b6, 0x0c0, 0x0cc, 0x0d8, 1132774f206SBjoern A. Zeeb 0x0e5, 0x0f2, 0x101, 0x110, 0x120, 0x131, 0x143, 0x156, 0x16a, 0x180, 1142774f206SBjoern A. Zeeb 0x197, 0x1af, 0x1c8, 0x1e3, 0x200, 0x21e, 0x23e, 0x261, 0x285, 0x2ab, 1152774f206SBjoern A. Zeeb 0x2d3, 0x2fe, 0x32b, 0x35c, 0x38e, 0x3c4, 0x3fe 1162774f206SBjoern A. Zeeb }; 1172774f206SBjoern A. Zeeb 1182774f206SBjoern A. Zeeb static u8 rtw8821c_get_swing_index(struct rtw_dev *rtwdev) 1192774f206SBjoern A. Zeeb { 1202774f206SBjoern A. Zeeb u8 i = 0; 1212774f206SBjoern A. Zeeb u32 swing, table_value; 1222774f206SBjoern A. Zeeb 1232774f206SBjoern A. Zeeb swing = rtw_read32_mask(rtwdev, REG_TXSCALE_A, 0xffe00000); 1242774f206SBjoern A. Zeeb for (i = 0; i < ARRAY_SIZE(rtw8821c_txscale_tbl); i++) { 1252774f206SBjoern A. Zeeb table_value = rtw8821c_txscale_tbl[i]; 1262774f206SBjoern A. Zeeb if (swing == table_value) 1272774f206SBjoern A. Zeeb break; 1282774f206SBjoern A. Zeeb } 1292774f206SBjoern A. Zeeb 1302774f206SBjoern A. Zeeb return i; 1312774f206SBjoern A. Zeeb } 1322774f206SBjoern A. Zeeb 1332774f206SBjoern A. Zeeb static void rtw8821c_pwrtrack_init(struct rtw_dev *rtwdev) 1342774f206SBjoern A. Zeeb { 1352774f206SBjoern A. Zeeb struct rtw_dm_info *dm_info = &rtwdev->dm_info; 1362774f206SBjoern A. Zeeb u8 swing_idx = rtw8821c_get_swing_index(rtwdev); 1372774f206SBjoern A. Zeeb 1382774f206SBjoern A. Zeeb if (swing_idx >= ARRAY_SIZE(rtw8821c_txscale_tbl)) 1392774f206SBjoern A. Zeeb dm_info->default_ofdm_index = 24; 1402774f206SBjoern A. Zeeb else 1412774f206SBjoern A. Zeeb dm_info->default_ofdm_index = swing_idx; 1422774f206SBjoern A. Zeeb 1432774f206SBjoern A. Zeeb ewma_thermal_init(&dm_info->avg_thermal[RF_PATH_A]); 1442774f206SBjoern A. Zeeb dm_info->delta_power_index[RF_PATH_A] = 0; 1452774f206SBjoern A. Zeeb dm_info->delta_power_index_last[RF_PATH_A] = 0; 1462774f206SBjoern A. Zeeb dm_info->pwr_trk_triggered = false; 1472774f206SBjoern A. Zeeb dm_info->pwr_trk_init_trigger = true; 1482774f206SBjoern A. Zeeb dm_info->thermal_meter_k = rtwdev->efuse.thermal_meter_k; 1492774f206SBjoern A. Zeeb } 1502774f206SBjoern A. Zeeb 1512774f206SBjoern A. Zeeb static void rtw8821c_phy_bf_init(struct rtw_dev *rtwdev) 1522774f206SBjoern A. Zeeb { 1532774f206SBjoern A. Zeeb rtw_bf_phy_init(rtwdev); 1542774f206SBjoern A. Zeeb /* Grouping bitmap parameters */ 1552774f206SBjoern A. Zeeb rtw_write32(rtwdev, 0x1C94, 0xAFFFAFFF); 1562774f206SBjoern A. Zeeb } 1572774f206SBjoern A. Zeeb 1582774f206SBjoern A. Zeeb static void rtw8821c_phy_set_param(struct rtw_dev *rtwdev) 1592774f206SBjoern A. Zeeb { 1609c951734SBjoern A. Zeeb struct rtw_hal *hal = &rtwdev->hal; 1612774f206SBjoern A. Zeeb u8 crystal_cap, val; 1622774f206SBjoern A. Zeeb 1632774f206SBjoern A. Zeeb /* power on BB/RF domain */ 1642774f206SBjoern A. Zeeb val = rtw_read8(rtwdev, REG_SYS_FUNC_EN); 1652774f206SBjoern A. Zeeb val |= BIT_FEN_PCIEA; 1662774f206SBjoern A. Zeeb rtw_write8(rtwdev, REG_SYS_FUNC_EN, val); 1672774f206SBjoern A. Zeeb 1682774f206SBjoern A. Zeeb /* toggle BB reset */ 1692774f206SBjoern A. Zeeb val |= BIT_FEN_BB_RSTB | BIT_FEN_BB_GLB_RST; 1702774f206SBjoern A. Zeeb rtw_write8(rtwdev, REG_SYS_FUNC_EN, val); 1712774f206SBjoern A. Zeeb val &= ~(BIT_FEN_BB_RSTB | BIT_FEN_BB_GLB_RST); 1722774f206SBjoern A. Zeeb rtw_write8(rtwdev, REG_SYS_FUNC_EN, val); 1732774f206SBjoern A. Zeeb val |= BIT_FEN_BB_RSTB | BIT_FEN_BB_GLB_RST; 1742774f206SBjoern A. Zeeb rtw_write8(rtwdev, REG_SYS_FUNC_EN, val); 1752774f206SBjoern A. Zeeb 1762774f206SBjoern A. Zeeb rtw_write8(rtwdev, REG_RF_CTRL, 1772774f206SBjoern A. Zeeb BIT_RF_EN | BIT_RF_RSTB | BIT_RF_SDM_RSTB); 1782774f206SBjoern A. Zeeb usleep_range(10, 11); 1792774f206SBjoern A. Zeeb rtw_write8(rtwdev, REG_WLRF1 + 3, 1802774f206SBjoern A. Zeeb BIT_RF_EN | BIT_RF_RSTB | BIT_RF_SDM_RSTB); 1812774f206SBjoern A. Zeeb usleep_range(10, 11); 1822774f206SBjoern A. Zeeb 1832774f206SBjoern A. Zeeb /* pre init before header files config */ 1842774f206SBjoern A. Zeeb rtw_write32_clr(rtwdev, REG_RXPSEL, BIT_RX_PSEL_RST); 1852774f206SBjoern A. Zeeb 1862774f206SBjoern A. Zeeb rtw_phy_load_tables(rtwdev); 1872774f206SBjoern A. Zeeb 1882774f206SBjoern A. Zeeb crystal_cap = rtwdev->efuse.crystal_cap & 0x3F; 1892774f206SBjoern A. Zeeb rtw_write32_mask(rtwdev, REG_AFE_XTAL_CTRL, 0x7e000000, crystal_cap); 1902774f206SBjoern A. Zeeb rtw_write32_mask(rtwdev, REG_AFE_PLL_CTRL, 0x7e, crystal_cap); 1912774f206SBjoern A. Zeeb rtw_write32_mask(rtwdev, REG_CCK0_FAREPORT, BIT(18) | BIT(22), 0); 1922774f206SBjoern A. Zeeb 1932774f206SBjoern A. Zeeb /* post init after header files config */ 1942774f206SBjoern A. Zeeb rtw_write32_set(rtwdev, REG_RXPSEL, BIT_RX_PSEL_RST); 1959c951734SBjoern A. Zeeb hal->ch_param[0] = rtw_read32_mask(rtwdev, REG_TXSF2, MASKDWORD); 1969c951734SBjoern A. Zeeb hal->ch_param[1] = rtw_read32_mask(rtwdev, REG_TXSF6, MASKDWORD); 1979c951734SBjoern A. Zeeb hal->ch_param[2] = rtw_read32_mask(rtwdev, REG_TXFILTER, MASKDWORD); 1982774f206SBjoern A. Zeeb 1992774f206SBjoern A. Zeeb rtw_phy_init(rtwdev); 2002774f206SBjoern A. Zeeb rtwdev->dm_info.cck_pd_default = rtw_read8(rtwdev, REG_CSRATIO) & 0x1f; 2012774f206SBjoern A. Zeeb 2022774f206SBjoern A. Zeeb rtw8821c_pwrtrack_init(rtwdev); 2032774f206SBjoern A. Zeeb 2042774f206SBjoern A. Zeeb rtw8821c_phy_bf_init(rtwdev); 2052774f206SBjoern A. Zeeb } 2062774f206SBjoern A. Zeeb 2072774f206SBjoern A. Zeeb static int rtw8821c_mac_init(struct rtw_dev *rtwdev) 2082774f206SBjoern A. Zeeb { 2092774f206SBjoern A. Zeeb u32 value32; 2102774f206SBjoern A. Zeeb u16 pre_txcnt; 2112774f206SBjoern A. Zeeb 2122774f206SBjoern A. Zeeb /* protocol configuration */ 2132774f206SBjoern A. Zeeb rtw_write8(rtwdev, REG_AMPDU_MAX_TIME_V1, WLAN_AMPDU_MAX_TIME); 2142774f206SBjoern A. Zeeb rtw_write8_set(rtwdev, REG_TX_HANG_CTRL, BIT_EN_EOF_V1); 2152774f206SBjoern A. Zeeb pre_txcnt = WLAN_PRE_TXCNT_TIME_TH | BIT_EN_PRECNT; 2162774f206SBjoern A. Zeeb rtw_write8(rtwdev, REG_PRECNT_CTRL, (u8)(pre_txcnt & 0xFF)); 2172774f206SBjoern A. Zeeb rtw_write8(rtwdev, REG_PRECNT_CTRL + 1, (u8)(pre_txcnt >> 8)); 2182774f206SBjoern A. Zeeb value32 = WLAN_RTS_LEN_TH | (WLAN_RTS_TX_TIME_TH << 8) | 2192774f206SBjoern A. Zeeb (WLAN_MAX_AGG_PKT_LIMIT << 16) | 2202774f206SBjoern A. Zeeb (WLAN_RTS_MAX_AGG_PKT_LIMIT << 24); 2212774f206SBjoern A. Zeeb rtw_write32(rtwdev, REG_PROT_MODE_CTRL, value32); 2222774f206SBjoern A. Zeeb rtw_write16(rtwdev, REG_BAR_MODE_CTRL + 2, 2232774f206SBjoern A. Zeeb WLAN_BAR_RETRY_LIMIT | WLAN_RA_TRY_RATE_AGG_LIMIT << 8); 2242774f206SBjoern A. Zeeb rtw_write8(rtwdev, REG_FAST_EDCA_VOVI_SETTING, FAST_EDCA_VO_TH); 2252774f206SBjoern A. Zeeb rtw_write8(rtwdev, REG_FAST_EDCA_VOVI_SETTING + 2, FAST_EDCA_VI_TH); 2262774f206SBjoern A. Zeeb rtw_write8(rtwdev, REG_FAST_EDCA_BEBK_SETTING, FAST_EDCA_BE_TH); 2272774f206SBjoern A. Zeeb rtw_write8(rtwdev, REG_FAST_EDCA_BEBK_SETTING + 2, FAST_EDCA_BK_TH); 2282774f206SBjoern A. Zeeb rtw_write8_set(rtwdev, REG_INIRTS_RATE_SEL, BIT(5)); 2292774f206SBjoern A. Zeeb 2302774f206SBjoern A. Zeeb /* EDCA configuration */ 2312774f206SBjoern A. Zeeb rtw_write8_clr(rtwdev, REG_TIMER0_SRC_SEL, BIT_TSFT_SEL_TIMER0); 2322774f206SBjoern A. Zeeb rtw_write16(rtwdev, REG_TXPAUSE, 0); 2332774f206SBjoern A. Zeeb rtw_write8(rtwdev, REG_SLOT, WLAN_SLOT_TIME); 2342774f206SBjoern A. Zeeb rtw_write8(rtwdev, REG_PIFS, WLAN_PIFS_TIME); 2352774f206SBjoern A. Zeeb rtw_write32(rtwdev, REG_SIFS, WLAN_SIFS_CFG); 2362774f206SBjoern A. Zeeb rtw_write16(rtwdev, REG_EDCA_VO_PARAM + 2, WLAN_VO_TXOP_LIMIT); 2372774f206SBjoern A. Zeeb rtw_write16(rtwdev, REG_EDCA_VI_PARAM + 2, WLAN_VI_TXOP_LIMIT); 2382774f206SBjoern A. Zeeb rtw_write32(rtwdev, REG_RD_NAV_NXT, WLAN_NAV_CFG); 2392774f206SBjoern A. Zeeb rtw_write16(rtwdev, REG_RXTSF_OFFSET_CCK, WLAN_RX_TSF_CFG); 2402774f206SBjoern A. Zeeb 2412774f206SBjoern A. Zeeb /* Set beacon cotnrol - enable TSF and other related functions */ 2422774f206SBjoern A. Zeeb rtw_write8_set(rtwdev, REG_BCN_CTRL, BIT_EN_BCN_FUNCTION); 2432774f206SBjoern A. Zeeb 2442774f206SBjoern A. Zeeb /* Set send beacon related registers */ 2452774f206SBjoern A. Zeeb rtw_write32(rtwdev, REG_TBTT_PROHIBIT, WLAN_TBTT_TIME); 2462774f206SBjoern A. Zeeb rtw_write8(rtwdev, REG_DRVERLYINT, WLAN_DRV_EARLY_INT); 2472774f206SBjoern A. Zeeb rtw_write8(rtwdev, REG_BCNDMATIM, WLAN_BCN_DMA_TIME); 2482774f206SBjoern A. Zeeb rtw_write8_clr(rtwdev, REG_TX_PTCL_CTRL + 1, BIT_SIFS_BK_EN >> 8); 2492774f206SBjoern A. Zeeb 2502774f206SBjoern A. Zeeb /* WMAC configuration */ 2512774f206SBjoern A. Zeeb rtw_write32(rtwdev, REG_RXFLTMAP0, WLAN_RX_FILTER0); 2522774f206SBjoern A. Zeeb rtw_write16(rtwdev, REG_RXFLTMAP2, WLAN_RX_FILTER2); 2532774f206SBjoern A. Zeeb rtw_write32(rtwdev, REG_RCR, WLAN_RCR_CFG); 2542774f206SBjoern A. Zeeb rtw_write8(rtwdev, REG_RX_PKT_LIMIT, WLAN_RXPKT_MAX_SZ_512); 2552774f206SBjoern A. Zeeb rtw_write8(rtwdev, REG_TCR + 2, WLAN_TX_FUNC_CFG2); 2562774f206SBjoern A. Zeeb rtw_write8(rtwdev, REG_TCR + 1, WLAN_TX_FUNC_CFG1); 2572774f206SBjoern A. Zeeb rtw_write8(rtwdev, REG_ACKTO_CCK, 0x40); 2582774f206SBjoern A. Zeeb rtw_write8_set(rtwdev, REG_WMAC_TRXPTCL_CTL_H, BIT(1)); 2592774f206SBjoern A. Zeeb rtw_write8_set(rtwdev, REG_SND_PTCL_CTRL, 2602774f206SBjoern A. Zeeb BIT_DIS_CHK_VHTSIGB_CRC); 2612774f206SBjoern A. Zeeb rtw_write32(rtwdev, REG_WMAC_OPTION_FUNCTION + 8, WLAN_MAC_OPT_FUNC2); 2622774f206SBjoern A. Zeeb rtw_write8(rtwdev, REG_WMAC_OPTION_FUNCTION + 4, WLAN_MAC_OPT_NORM_FUNC1); 2632774f206SBjoern A. Zeeb 2642774f206SBjoern A. Zeeb return 0; 2652774f206SBjoern A. Zeeb } 2662774f206SBjoern A. Zeeb 2672774f206SBjoern A. Zeeb static void rtw8821c_cfg_ldo25(struct rtw_dev *rtwdev, bool enable) 2682774f206SBjoern A. Zeeb { 2692774f206SBjoern A. Zeeb u8 ldo_pwr; 2702774f206SBjoern A. Zeeb 2712774f206SBjoern A. Zeeb ldo_pwr = rtw_read8(rtwdev, REG_LDO_EFUSE_CTRL + 3); 2722774f206SBjoern A. Zeeb ldo_pwr = enable ? ldo_pwr | BIT(7) : ldo_pwr & ~BIT(7); 2732774f206SBjoern A. Zeeb rtw_write8(rtwdev, REG_LDO_EFUSE_CTRL + 3, ldo_pwr); 2742774f206SBjoern A. Zeeb } 2752774f206SBjoern A. Zeeb 2762774f206SBjoern A. Zeeb static void rtw8821c_switch_rf_set(struct rtw_dev *rtwdev, u8 rf_set) 2772774f206SBjoern A. Zeeb { 2782774f206SBjoern A. Zeeb u32 reg; 2792774f206SBjoern A. Zeeb 2802774f206SBjoern A. Zeeb rtw_write32_set(rtwdev, REG_DMEM_CTRL, BIT_WL_RST); 2812774f206SBjoern A. Zeeb rtw_write32_set(rtwdev, REG_SYS_CTRL, BIT_FEN_EN); 2822774f206SBjoern A. Zeeb 2832774f206SBjoern A. Zeeb reg = rtw_read32(rtwdev, REG_RFECTL); 2842774f206SBjoern A. Zeeb switch (rf_set) { 2852774f206SBjoern A. Zeeb case SWITCH_TO_BTG: 2862774f206SBjoern A. Zeeb reg |= B_BTG_SWITCH; 2872774f206SBjoern A. Zeeb reg &= ~(B_CTRL_SWITCH | B_WL_SWITCH | B_WLG_SWITCH | 2882774f206SBjoern A. Zeeb B_WLA_SWITCH); 2892774f206SBjoern A. Zeeb rtw_write32_mask(rtwdev, REG_ENRXCCA, MASKBYTE2, BTG_CCA); 2902774f206SBjoern A. Zeeb rtw_write32_mask(rtwdev, REG_ENTXCCK, MASKLWORD, BTG_LNA); 2912774f206SBjoern A. Zeeb break; 2922774f206SBjoern A. Zeeb case SWITCH_TO_WLG: 2932774f206SBjoern A. Zeeb reg |= B_WL_SWITCH | B_WLG_SWITCH; 2942774f206SBjoern A. Zeeb reg &= ~(B_BTG_SWITCH | B_CTRL_SWITCH | B_WLA_SWITCH); 2952774f206SBjoern A. Zeeb rtw_write32_mask(rtwdev, REG_ENRXCCA, MASKBYTE2, WLG_CCA); 2962774f206SBjoern A. Zeeb rtw_write32_mask(rtwdev, REG_ENTXCCK, MASKLWORD, WLG_LNA); 2972774f206SBjoern A. Zeeb break; 2982774f206SBjoern A. Zeeb case SWITCH_TO_WLA: 2992774f206SBjoern A. Zeeb reg |= B_WL_SWITCH | B_WLA_SWITCH; 3002774f206SBjoern A. Zeeb reg &= ~(B_BTG_SWITCH | B_CTRL_SWITCH | B_WLG_SWITCH); 3012774f206SBjoern A. Zeeb break; 3022774f206SBjoern A. Zeeb case SWITCH_TO_BT: 3032774f206SBjoern A. Zeeb default: 3042774f206SBjoern A. Zeeb break; 3052774f206SBjoern A. Zeeb } 3062774f206SBjoern A. Zeeb 3072774f206SBjoern A. Zeeb rtw_write32(rtwdev, REG_RFECTL, reg); 3082774f206SBjoern A. Zeeb } 3092774f206SBjoern A. Zeeb 3102774f206SBjoern A. Zeeb static void rtw8821c_set_channel_rf(struct rtw_dev *rtwdev, u8 channel, u8 bw) 3112774f206SBjoern A. Zeeb { 31290aac0d8SBjoern A. Zeeb struct rtw_hal *hal = &rtwdev->hal; 3132774f206SBjoern A. Zeeb u32 rf_reg18; 3142774f206SBjoern A. Zeeb 3152774f206SBjoern A. Zeeb rf_reg18 = rtw_read_rf(rtwdev, RF_PATH_A, 0x18, RFREG_MASK); 3162774f206SBjoern A. Zeeb 3172774f206SBjoern A. Zeeb rf_reg18 &= ~(RF18_BAND_MASK | RF18_CHANNEL_MASK | RF18_RFSI_MASK | 3182774f206SBjoern A. Zeeb RF18_BW_MASK); 3192774f206SBjoern A. Zeeb 3202774f206SBjoern A. Zeeb rf_reg18 |= (channel <= 14 ? RF18_BAND_2G : RF18_BAND_5G); 3212774f206SBjoern A. Zeeb rf_reg18 |= (channel & RF18_CHANNEL_MASK); 3222774f206SBjoern A. Zeeb 3232774f206SBjoern A. Zeeb if (channel >= 100 && channel <= 140) 3242774f206SBjoern A. Zeeb rf_reg18 |= RF18_RFSI_GE; 3252774f206SBjoern A. Zeeb else if (channel > 140) 3262774f206SBjoern A. Zeeb rf_reg18 |= RF18_RFSI_GT; 3272774f206SBjoern A. Zeeb 3282774f206SBjoern A. Zeeb switch (bw) { 3292774f206SBjoern A. Zeeb case RTW_CHANNEL_WIDTH_5: 3302774f206SBjoern A. Zeeb case RTW_CHANNEL_WIDTH_10: 3312774f206SBjoern A. Zeeb case RTW_CHANNEL_WIDTH_20: 3322774f206SBjoern A. Zeeb default: 3332774f206SBjoern A. Zeeb rf_reg18 |= RF18_BW_20M; 3342774f206SBjoern A. Zeeb break; 3352774f206SBjoern A. Zeeb case RTW_CHANNEL_WIDTH_40: 3362774f206SBjoern A. Zeeb rf_reg18 |= RF18_BW_40M; 3372774f206SBjoern A. Zeeb break; 3382774f206SBjoern A. Zeeb case RTW_CHANNEL_WIDTH_80: 3392774f206SBjoern A. Zeeb rf_reg18 |= RF18_BW_80M; 3402774f206SBjoern A. Zeeb break; 3412774f206SBjoern A. Zeeb } 3422774f206SBjoern A. Zeeb 3432774f206SBjoern A. Zeeb if (channel <= 14) { 34490aac0d8SBjoern A. Zeeb if (hal->rfe_btg) 3452774f206SBjoern A. Zeeb rtw8821c_switch_rf_set(rtwdev, SWITCH_TO_BTG); 34690aac0d8SBjoern A. Zeeb else 34790aac0d8SBjoern A. Zeeb rtw8821c_switch_rf_set(rtwdev, SWITCH_TO_WLG); 3482774f206SBjoern A. Zeeb rtw_write_rf(rtwdev, RF_PATH_A, RF_LUTDBG, BIT(6), 0x1); 3492774f206SBjoern A. Zeeb rtw_write_rf(rtwdev, RF_PATH_A, 0x64, 0xf, 0xf); 3502774f206SBjoern A. Zeeb } else { 3512774f206SBjoern A. Zeeb rtw8821c_switch_rf_set(rtwdev, SWITCH_TO_WLA); 3522774f206SBjoern A. Zeeb rtw_write_rf(rtwdev, RF_PATH_A, RF_LUTDBG, BIT(6), 0x0); 3532774f206SBjoern A. Zeeb } 3542774f206SBjoern A. Zeeb 3552774f206SBjoern A. Zeeb rtw_write_rf(rtwdev, RF_PATH_A, 0x18, RFREG_MASK, rf_reg18); 3562774f206SBjoern A. Zeeb 3572774f206SBjoern A. Zeeb rtw_write_rf(rtwdev, RF_PATH_A, RF_XTALX2, BIT(19), 0); 3582774f206SBjoern A. Zeeb rtw_write_rf(rtwdev, RF_PATH_A, RF_XTALX2, BIT(19), 1); 3592774f206SBjoern A. Zeeb } 3602774f206SBjoern A. Zeeb 3612774f206SBjoern A. Zeeb static void rtw8821c_set_channel_rxdfir(struct rtw_dev *rtwdev, u8 bw) 3622774f206SBjoern A. Zeeb { 3632774f206SBjoern A. Zeeb if (bw == RTW_CHANNEL_WIDTH_40) { 3642774f206SBjoern A. Zeeb /* RX DFIR for BW40 */ 3652774f206SBjoern A. Zeeb rtw_write32_mask(rtwdev, REG_ACBB0, BIT(29) | BIT(28), 0x2); 3662774f206SBjoern A. Zeeb rtw_write32_mask(rtwdev, REG_ACBBRXFIR, BIT(29) | BIT(28), 0x2); 3672774f206SBjoern A. Zeeb rtw_write32_mask(rtwdev, REG_TXDFIR, BIT(31), 0x0); 3682774f206SBjoern A. Zeeb rtw_write32_mask(rtwdev, REG_CHFIR, BIT(31), 0x0); 3692774f206SBjoern A. Zeeb } else if (bw == RTW_CHANNEL_WIDTH_80) { 3702774f206SBjoern A. Zeeb /* RX DFIR for BW80 */ 3712774f206SBjoern A. Zeeb rtw_write32_mask(rtwdev, REG_ACBB0, BIT(29) | BIT(28), 0x2); 3722774f206SBjoern A. Zeeb rtw_write32_mask(rtwdev, REG_ACBBRXFIR, BIT(29) | BIT(28), 0x1); 3732774f206SBjoern A. Zeeb rtw_write32_mask(rtwdev, REG_TXDFIR, BIT(31), 0x0); 3742774f206SBjoern A. Zeeb rtw_write32_mask(rtwdev, REG_CHFIR, BIT(31), 0x1); 3752774f206SBjoern A. Zeeb } else { 3762774f206SBjoern A. Zeeb /* RX DFIR for BW20, BW10 and BW5 */ 3772774f206SBjoern A. Zeeb rtw_write32_mask(rtwdev, REG_ACBB0, BIT(29) | BIT(28), 0x2); 3782774f206SBjoern A. Zeeb rtw_write32_mask(rtwdev, REG_ACBBRXFIR, BIT(29) | BIT(28), 0x2); 3792774f206SBjoern A. Zeeb rtw_write32_mask(rtwdev, REG_TXDFIR, BIT(31), 0x1); 3802774f206SBjoern A. Zeeb rtw_write32_mask(rtwdev, REG_CHFIR, BIT(31), 0x0); 3812774f206SBjoern A. Zeeb } 3822774f206SBjoern A. Zeeb } 3832774f206SBjoern A. Zeeb 384*11c53278SBjoern A. Zeeb static void rtw8821c_cck_tx_filter_srrc(struct rtw_dev *rtwdev, u8 channel, u8 bw) 385*11c53278SBjoern A. Zeeb { 386*11c53278SBjoern A. Zeeb struct rtw_hal *hal = &rtwdev->hal; 387*11c53278SBjoern A. Zeeb 388*11c53278SBjoern A. Zeeb if (channel == 14) { 389*11c53278SBjoern A. Zeeb rtw_write32_mask(rtwdev, REG_CCA_FLTR, MASKHWORD, 0xe82c); 390*11c53278SBjoern A. Zeeb rtw_write32_mask(rtwdev, REG_TXSF2, MASKDWORD, 0x0000b81c); 391*11c53278SBjoern A. Zeeb rtw_write32_mask(rtwdev, REG_TXSF6, MASKLWORD, 0x0000); 392*11c53278SBjoern A. Zeeb rtw_write32_mask(rtwdev, REG_TXFILTER, MASKDWORD, 0x00003667); 393*11c53278SBjoern A. Zeeb 394*11c53278SBjoern A. Zeeb rtw_write_rf(rtwdev, RF_PATH_A, RF_LUTWE2, RFREG_MASK, 0x00002); 395*11c53278SBjoern A. Zeeb rtw_write_rf(rtwdev, RF_PATH_A, RF_LUTWA, RFREG_MASK, 0x0001e); 396*11c53278SBjoern A. Zeeb rtw_write_rf(rtwdev, RF_PATH_A, RF_LUTWD0, RFREG_MASK, 0x00000); 397*11c53278SBjoern A. Zeeb rtw_write_rf(rtwdev, RF_PATH_A, RF_LUTWA, RFREG_MASK, 0x0001c); 398*11c53278SBjoern A. Zeeb rtw_write_rf(rtwdev, RF_PATH_A, RF_LUTWD0, RFREG_MASK, 0x00000); 399*11c53278SBjoern A. Zeeb rtw_write_rf(rtwdev, RF_PATH_A, RF_LUTWA, RFREG_MASK, 0x0000e); 400*11c53278SBjoern A. Zeeb rtw_write_rf(rtwdev, RF_PATH_A, RF_LUTWD0, RFREG_MASK, 0x00000); 401*11c53278SBjoern A. Zeeb rtw_write_rf(rtwdev, RF_PATH_A, RF_LUTWA, RFREG_MASK, 0x0000c); 402*11c53278SBjoern A. Zeeb rtw_write_rf(rtwdev, RF_PATH_A, RF_LUTWD0, RFREG_MASK, 0x00000); 403*11c53278SBjoern A. Zeeb rtw_write_rf(rtwdev, RF_PATH_A, RF_LUTWE2, RFREG_MASK, 0x00000); 404*11c53278SBjoern A. Zeeb } else if (channel == 13 || 405*11c53278SBjoern A. Zeeb (channel == 11 && bw == RTW_CHANNEL_WIDTH_40)) { 406*11c53278SBjoern A. Zeeb rtw_write32_mask(rtwdev, REG_CCA_FLTR, MASKHWORD, 0xf8fe); 407*11c53278SBjoern A. Zeeb rtw_write32_mask(rtwdev, REG_TXSF2, MASKDWORD, 0x64b80c1c); 408*11c53278SBjoern A. Zeeb rtw_write32_mask(rtwdev, REG_TXSF6, MASKLWORD, 0x8810); 409*11c53278SBjoern A. Zeeb rtw_write32_mask(rtwdev, REG_TXFILTER, MASKDWORD, 0x01235667); 410*11c53278SBjoern A. Zeeb 411*11c53278SBjoern A. Zeeb rtw_write_rf(rtwdev, RF_PATH_A, RF_LUTWE2, RFREG_MASK, 0x00002); 412*11c53278SBjoern A. Zeeb rtw_write_rf(rtwdev, RF_PATH_A, RF_LUTWA, RFREG_MASK, 0x0001e); 413*11c53278SBjoern A. Zeeb rtw_write_rf(rtwdev, RF_PATH_A, RF_LUTWD0, RFREG_MASK, 0x00027); 414*11c53278SBjoern A. Zeeb rtw_write_rf(rtwdev, RF_PATH_A, RF_LUTWA, RFREG_MASK, 0x0001c); 415*11c53278SBjoern A. Zeeb rtw_write_rf(rtwdev, RF_PATH_A, RF_LUTWD0, RFREG_MASK, 0x00027); 416*11c53278SBjoern A. Zeeb rtw_write_rf(rtwdev, RF_PATH_A, RF_LUTWA, RFREG_MASK, 0x0000e); 417*11c53278SBjoern A. Zeeb rtw_write_rf(rtwdev, RF_PATH_A, RF_LUTWD0, RFREG_MASK, 0x00029); 418*11c53278SBjoern A. Zeeb rtw_write_rf(rtwdev, RF_PATH_A, RF_LUTWA, RFREG_MASK, 0x0000c); 419*11c53278SBjoern A. Zeeb rtw_write_rf(rtwdev, RF_PATH_A, RF_LUTWD0, RFREG_MASK, 0x00026); 420*11c53278SBjoern A. Zeeb rtw_write_rf(rtwdev, RF_PATH_A, RF_LUTWE2, RFREG_MASK, 0x00000); 421*11c53278SBjoern A. Zeeb } else { 422*11c53278SBjoern A. Zeeb rtw_write32_mask(rtwdev, REG_CCA_FLTR, MASKHWORD, 0xe82c); 423*11c53278SBjoern A. Zeeb rtw_write32_mask(rtwdev, REG_TXSF2, MASKDWORD, 424*11c53278SBjoern A. Zeeb hal->ch_param[0]); 425*11c53278SBjoern A. Zeeb rtw_write32_mask(rtwdev, REG_TXSF6, MASKLWORD, 426*11c53278SBjoern A. Zeeb hal->ch_param[1] & MASKLWORD); 427*11c53278SBjoern A. Zeeb rtw_write32_mask(rtwdev, REG_TXFILTER, MASKDWORD, 428*11c53278SBjoern A. Zeeb hal->ch_param[2]); 429*11c53278SBjoern A. Zeeb 430*11c53278SBjoern A. Zeeb rtw_write_rf(rtwdev, RF_PATH_A, RF_LUTWE2, RFREG_MASK, 0x00002); 431*11c53278SBjoern A. Zeeb rtw_write_rf(rtwdev, RF_PATH_A, RF_LUTWA, RFREG_MASK, 0x0001e); 432*11c53278SBjoern A. Zeeb rtw_write_rf(rtwdev, RF_PATH_A, RF_LUTWD0, RFREG_MASK, 0x00000); 433*11c53278SBjoern A. Zeeb rtw_write_rf(rtwdev, RF_PATH_A, RF_LUTWA, RFREG_MASK, 0x0001c); 434*11c53278SBjoern A. Zeeb rtw_write_rf(rtwdev, RF_PATH_A, RF_LUTWD0, RFREG_MASK, 0x00000); 435*11c53278SBjoern A. Zeeb rtw_write_rf(rtwdev, RF_PATH_A, RF_LUTWA, RFREG_MASK, 0x0000e); 436*11c53278SBjoern A. Zeeb rtw_write_rf(rtwdev, RF_PATH_A, RF_LUTWD0, RFREG_MASK, 0x00000); 437*11c53278SBjoern A. Zeeb rtw_write_rf(rtwdev, RF_PATH_A, RF_LUTWA, RFREG_MASK, 0x0000c); 438*11c53278SBjoern A. Zeeb rtw_write_rf(rtwdev, RF_PATH_A, RF_LUTWD0, RFREG_MASK, 0x00000); 439*11c53278SBjoern A. Zeeb rtw_write_rf(rtwdev, RF_PATH_A, RF_LUTWE2, RFREG_MASK, 0x00000); 440*11c53278SBjoern A. Zeeb } 441*11c53278SBjoern A. Zeeb } 442*11c53278SBjoern A. Zeeb 4432774f206SBjoern A. Zeeb static void rtw8821c_set_channel_bb(struct rtw_dev *rtwdev, u8 channel, u8 bw, 4442774f206SBjoern A. Zeeb u8 primary_ch_idx) 4452774f206SBjoern A. Zeeb { 4469c951734SBjoern A. Zeeb struct rtw_hal *hal = &rtwdev->hal; 4472774f206SBjoern A. Zeeb u32 val32; 4482774f206SBjoern A. Zeeb 4492774f206SBjoern A. Zeeb if (channel <= 14) { 4502774f206SBjoern A. Zeeb rtw_write32_mask(rtwdev, REG_RXPSEL, BIT(28), 0x1); 4512774f206SBjoern A. Zeeb rtw_write32_mask(rtwdev, REG_CCK_CHECK, BIT(7), 0x0); 4522774f206SBjoern A. Zeeb rtw_write32_mask(rtwdev, REG_ENTXCCK, BIT(18), 0x0); 4532774f206SBjoern A. Zeeb rtw_write32_mask(rtwdev, REG_RXCCAMSK, 0x0000FC00, 15); 4542774f206SBjoern A. Zeeb 4552774f206SBjoern A. Zeeb rtw_write32_mask(rtwdev, REG_TXSCALE_A, 0xf00, 0x0); 4562774f206SBjoern A. Zeeb rtw_write32_mask(rtwdev, REG_CLKTRK, 0x1ffe0000, 0x96a); 457*11c53278SBjoern A. Zeeb 458*11c53278SBjoern A. Zeeb if (rtw_regd_srrc(rtwdev)) { 459*11c53278SBjoern A. Zeeb rtw8821c_cck_tx_filter_srrc(rtwdev, channel, bw); 460*11c53278SBjoern A. Zeeb goto set_bw; 461*11c53278SBjoern A. Zeeb } 462*11c53278SBjoern A. Zeeb 463*11c53278SBjoern A. Zeeb /* CCK TX filter parameters for default case */ 4642774f206SBjoern A. Zeeb if (channel == 14) { 4652774f206SBjoern A. Zeeb rtw_write32_mask(rtwdev, REG_TXSF2, MASKDWORD, 0x0000b81c); 4662774f206SBjoern A. Zeeb rtw_write32_mask(rtwdev, REG_TXSF6, MASKLWORD, 0x0000); 4672774f206SBjoern A. Zeeb rtw_write32_mask(rtwdev, REG_TXFILTER, MASKDWORD, 0x00003667); 4682774f206SBjoern A. Zeeb } else { 4692774f206SBjoern A. Zeeb rtw_write32_mask(rtwdev, REG_TXSF2, MASKDWORD, 4709c951734SBjoern A. Zeeb hal->ch_param[0]); 4712774f206SBjoern A. Zeeb rtw_write32_mask(rtwdev, REG_TXSF6, MASKLWORD, 4729c951734SBjoern A. Zeeb hal->ch_param[1] & MASKLWORD); 4732774f206SBjoern A. Zeeb rtw_write32_mask(rtwdev, REG_TXFILTER, MASKDWORD, 4749c951734SBjoern A. Zeeb hal->ch_param[2]); 4752774f206SBjoern A. Zeeb } 4762774f206SBjoern A. Zeeb } else if (channel > 35) { 4772774f206SBjoern A. Zeeb rtw_write32_mask(rtwdev, REG_ENTXCCK, BIT(18), 0x1); 4782774f206SBjoern A. Zeeb rtw_write32_mask(rtwdev, REG_CCK_CHECK, BIT(7), 0x1); 4792774f206SBjoern A. Zeeb rtw_write32_mask(rtwdev, REG_RXPSEL, BIT(28), 0x0); 4802774f206SBjoern A. Zeeb rtw_write32_mask(rtwdev, REG_RXCCAMSK, 0x0000FC00, 15); 4812774f206SBjoern A. Zeeb 4822774f206SBjoern A. Zeeb if (channel >= 36 && channel <= 64) 4832774f206SBjoern A. Zeeb rtw_write32_mask(rtwdev, REG_TXSCALE_A, 0xf00, 0x1); 4842774f206SBjoern A. Zeeb else if (channel >= 100 && channel <= 144) 4852774f206SBjoern A. Zeeb rtw_write32_mask(rtwdev, REG_TXSCALE_A, 0xf00, 0x2); 4862774f206SBjoern A. Zeeb else if (channel >= 149) 4872774f206SBjoern A. Zeeb rtw_write32_mask(rtwdev, REG_TXSCALE_A, 0xf00, 0x3); 4882774f206SBjoern A. Zeeb 4892774f206SBjoern A. Zeeb if (channel >= 36 && channel <= 48) 4902774f206SBjoern A. Zeeb rtw_write32_mask(rtwdev, REG_CLKTRK, 0x1ffe0000, 0x494); 4912774f206SBjoern A. Zeeb else if (channel >= 52 && channel <= 64) 4922774f206SBjoern A. Zeeb rtw_write32_mask(rtwdev, REG_CLKTRK, 0x1ffe0000, 0x453); 4932774f206SBjoern A. Zeeb else if (channel >= 100 && channel <= 116) 4942774f206SBjoern A. Zeeb rtw_write32_mask(rtwdev, REG_CLKTRK, 0x1ffe0000, 0x452); 4952774f206SBjoern A. Zeeb else if (channel >= 118 && channel <= 177) 4962774f206SBjoern A. Zeeb rtw_write32_mask(rtwdev, REG_CLKTRK, 0x1ffe0000, 0x412); 4972774f206SBjoern A. Zeeb } 4982774f206SBjoern A. Zeeb 499*11c53278SBjoern A. Zeeb set_bw: 5002774f206SBjoern A. Zeeb switch (bw) { 5012774f206SBjoern A. Zeeb case RTW_CHANNEL_WIDTH_20: 5022774f206SBjoern A. Zeeb default: 5032774f206SBjoern A. Zeeb val32 = rtw_read32_mask(rtwdev, REG_ADCCLK, MASKDWORD); 5042774f206SBjoern A. Zeeb val32 &= 0xffcffc00; 5052774f206SBjoern A. Zeeb val32 |= 0x10010000; 5062774f206SBjoern A. Zeeb rtw_write32_mask(rtwdev, REG_ADCCLK, MASKDWORD, val32); 5072774f206SBjoern A. Zeeb 5082774f206SBjoern A. Zeeb rtw_write32_mask(rtwdev, REG_ADC160, BIT(30), 0x1); 5092774f206SBjoern A. Zeeb break; 5102774f206SBjoern A. Zeeb case RTW_CHANNEL_WIDTH_40: 5112774f206SBjoern A. Zeeb if (primary_ch_idx == 1) 5122774f206SBjoern A. Zeeb rtw_write32_set(rtwdev, REG_RXSB, BIT(4)); 5132774f206SBjoern A. Zeeb else 5142774f206SBjoern A. Zeeb rtw_write32_clr(rtwdev, REG_RXSB, BIT(4)); 5152774f206SBjoern A. Zeeb 5162774f206SBjoern A. Zeeb val32 = rtw_read32_mask(rtwdev, REG_ADCCLK, MASKDWORD); 5172774f206SBjoern A. Zeeb val32 &= 0xff3ff300; 5182774f206SBjoern A. Zeeb val32 |= 0x20020000 | ((primary_ch_idx & 0xf) << 2) | 5192774f206SBjoern A. Zeeb RTW_CHANNEL_WIDTH_40; 5202774f206SBjoern A. Zeeb rtw_write32_mask(rtwdev, REG_ADCCLK, MASKDWORD, val32); 5212774f206SBjoern A. Zeeb 5222774f206SBjoern A. Zeeb rtw_write32_mask(rtwdev, REG_ADC160, BIT(30), 0x1); 5232774f206SBjoern A. Zeeb break; 5242774f206SBjoern A. Zeeb case RTW_CHANNEL_WIDTH_80: 5252774f206SBjoern A. Zeeb val32 = rtw_read32_mask(rtwdev, REG_ADCCLK, MASKDWORD); 5262774f206SBjoern A. Zeeb val32 &= 0xfcffcf00; 5272774f206SBjoern A. Zeeb val32 |= 0x40040000 | ((primary_ch_idx & 0xf) << 2) | 5282774f206SBjoern A. Zeeb RTW_CHANNEL_WIDTH_80; 5292774f206SBjoern A. Zeeb rtw_write32_mask(rtwdev, REG_ADCCLK, MASKDWORD, val32); 5302774f206SBjoern A. Zeeb 5312774f206SBjoern A. Zeeb rtw_write32_mask(rtwdev, REG_ADC160, BIT(30), 0x1); 5322774f206SBjoern A. Zeeb break; 5332774f206SBjoern A. Zeeb case RTW_CHANNEL_WIDTH_5: 5342774f206SBjoern A. Zeeb val32 = rtw_read32_mask(rtwdev, REG_ADCCLK, MASKDWORD); 5352774f206SBjoern A. Zeeb val32 &= 0xefcefc00; 5362774f206SBjoern A. Zeeb val32 |= 0x200240; 5372774f206SBjoern A. Zeeb rtw_write32_mask(rtwdev, REG_ADCCLK, MASKDWORD, val32); 5382774f206SBjoern A. Zeeb 5392774f206SBjoern A. Zeeb rtw_write32_mask(rtwdev, REG_ADC160, BIT(30), 0x0); 5402774f206SBjoern A. Zeeb rtw_write32_mask(rtwdev, REG_ADC40, BIT(31), 0x1); 5412774f206SBjoern A. Zeeb break; 5422774f206SBjoern A. Zeeb case RTW_CHANNEL_WIDTH_10: 5432774f206SBjoern A. Zeeb val32 = rtw_read32_mask(rtwdev, REG_ADCCLK, MASKDWORD); 5442774f206SBjoern A. Zeeb val32 &= 0xefcefc00; 5452774f206SBjoern A. Zeeb val32 |= 0x300380; 5462774f206SBjoern A. Zeeb rtw_write32_mask(rtwdev, REG_ADCCLK, MASKDWORD, val32); 5472774f206SBjoern A. Zeeb 5482774f206SBjoern A. Zeeb rtw_write32_mask(rtwdev, REG_ADC160, BIT(30), 0x0); 5492774f206SBjoern A. Zeeb rtw_write32_mask(rtwdev, REG_ADC40, BIT(31), 0x1); 5502774f206SBjoern A. Zeeb break; 5512774f206SBjoern A. Zeeb } 5522774f206SBjoern A. Zeeb } 5532774f206SBjoern A. Zeeb 5542774f206SBjoern A. Zeeb static u32 rtw8821c_get_bb_swing(struct rtw_dev *rtwdev, u8 channel) 5552774f206SBjoern A. Zeeb { 5562774f206SBjoern A. Zeeb struct rtw_efuse efuse = rtwdev->efuse; 5572774f206SBjoern A. Zeeb u8 tx_bb_swing; 5582774f206SBjoern A. Zeeb u32 swing2setting[4] = {0x200, 0x16a, 0x101, 0x0b6}; 5592774f206SBjoern A. Zeeb 5602774f206SBjoern A. Zeeb tx_bb_swing = channel <= 14 ? efuse.tx_bb_swing_setting_2g : 5612774f206SBjoern A. Zeeb efuse.tx_bb_swing_setting_5g; 5622774f206SBjoern A. Zeeb if (tx_bb_swing > 9) 5632774f206SBjoern A. Zeeb tx_bb_swing = 0; 5642774f206SBjoern A. Zeeb 5652774f206SBjoern A. Zeeb return swing2setting[(tx_bb_swing / 3)]; 5662774f206SBjoern A. Zeeb } 5672774f206SBjoern A. Zeeb 5682774f206SBjoern A. Zeeb static void rtw8821c_set_channel_bb_swing(struct rtw_dev *rtwdev, u8 channel, 5692774f206SBjoern A. Zeeb u8 bw, u8 primary_ch_idx) 5702774f206SBjoern A. Zeeb { 5712774f206SBjoern A. Zeeb rtw_write32_mask(rtwdev, REG_TXSCALE_A, GENMASK(31, 21), 5722774f206SBjoern A. Zeeb rtw8821c_get_bb_swing(rtwdev, channel)); 5732774f206SBjoern A. Zeeb rtw8821c_pwrtrack_init(rtwdev); 5742774f206SBjoern A. Zeeb } 5752774f206SBjoern A. Zeeb 5762774f206SBjoern A. Zeeb static void rtw8821c_set_channel(struct rtw_dev *rtwdev, u8 channel, u8 bw, 5772774f206SBjoern A. Zeeb u8 primary_chan_idx) 5782774f206SBjoern A. Zeeb { 5792774f206SBjoern A. Zeeb rtw8821c_set_channel_bb(rtwdev, channel, bw, primary_chan_idx); 5802774f206SBjoern A. Zeeb rtw8821c_set_channel_bb_swing(rtwdev, channel, bw, primary_chan_idx); 5812774f206SBjoern A. Zeeb rtw_set_channel_mac(rtwdev, channel, bw, primary_chan_idx); 5822774f206SBjoern A. Zeeb rtw8821c_set_channel_rf(rtwdev, channel, bw); 5832774f206SBjoern A. Zeeb rtw8821c_set_channel_rxdfir(rtwdev, bw); 5842774f206SBjoern A. Zeeb } 5852774f206SBjoern A. Zeeb 5862774f206SBjoern A. Zeeb static s8 get_cck_rx_pwr(struct rtw_dev *rtwdev, u8 lna_idx, u8 vga_idx) 5872774f206SBjoern A. Zeeb { 5882774f206SBjoern A. Zeeb struct rtw_efuse *efuse = &rtwdev->efuse; 5892774f206SBjoern A. Zeeb const s8 *lna_gain_table; 5902774f206SBjoern A. Zeeb int lna_gain_table_size; 5912774f206SBjoern A. Zeeb s8 rx_pwr_all = 0; 5922774f206SBjoern A. Zeeb s8 lna_gain = 0; 5932774f206SBjoern A. Zeeb 5942774f206SBjoern A. Zeeb if (efuse->rfe_option == 0) { 5952774f206SBjoern A. Zeeb lna_gain_table = lna_gain_table_0; 5962774f206SBjoern A. Zeeb lna_gain_table_size = ARRAY_SIZE(lna_gain_table_0); 5972774f206SBjoern A. Zeeb } else { 5982774f206SBjoern A. Zeeb lna_gain_table = lna_gain_table_1; 5992774f206SBjoern A. Zeeb lna_gain_table_size = ARRAY_SIZE(lna_gain_table_1); 6002774f206SBjoern A. Zeeb } 6012774f206SBjoern A. Zeeb 6022774f206SBjoern A. Zeeb if (lna_idx >= lna_gain_table_size) { 6039c951734SBjoern A. Zeeb rtw_warn(rtwdev, "incorrect lna index (%d)\n", lna_idx); 6042774f206SBjoern A. Zeeb return -120; 6052774f206SBjoern A. Zeeb } 6062774f206SBjoern A. Zeeb 6072774f206SBjoern A. Zeeb lna_gain = lna_gain_table[lna_idx]; 6082774f206SBjoern A. Zeeb rx_pwr_all = lna_gain - 2 * vga_idx; 6092774f206SBjoern A. Zeeb 6102774f206SBjoern A. Zeeb return rx_pwr_all; 6112774f206SBjoern A. Zeeb } 6122774f206SBjoern A. Zeeb 6132774f206SBjoern A. Zeeb static void query_phy_status_page0(struct rtw_dev *rtwdev, u8 *phy_status, 6142774f206SBjoern A. Zeeb struct rtw_rx_pkt_stat *pkt_stat) 6152774f206SBjoern A. Zeeb { 6169c951734SBjoern A. Zeeb struct rtw_dm_info *dm_info = &rtwdev->dm_info; 6172774f206SBjoern A. Zeeb s8 rx_power; 6182774f206SBjoern A. Zeeb u8 lna_idx = 0; 6192774f206SBjoern A. Zeeb u8 vga_idx = 0; 6202774f206SBjoern A. Zeeb 6212774f206SBjoern A. Zeeb vga_idx = GET_PHY_STAT_P0_VGA(phy_status); 6222774f206SBjoern A. Zeeb lna_idx = FIELD_PREP(BIT_LNA_H_MASK, GET_PHY_STAT_P0_LNA_H(phy_status)) | 6232774f206SBjoern A. Zeeb FIELD_PREP(BIT_LNA_L_MASK, GET_PHY_STAT_P0_LNA_L(phy_status)); 6242774f206SBjoern A. Zeeb rx_power = get_cck_rx_pwr(rtwdev, lna_idx, vga_idx); 6252774f206SBjoern A. Zeeb 6262774f206SBjoern A. Zeeb pkt_stat->rx_power[RF_PATH_A] = rx_power; 6272774f206SBjoern A. Zeeb pkt_stat->rssi = rtw_phy_rf_power_2_rssi(pkt_stat->rx_power, 1); 6289c951734SBjoern A. Zeeb dm_info->rssi[RF_PATH_A] = pkt_stat->rssi; 6292774f206SBjoern A. Zeeb pkt_stat->bw = RTW_CHANNEL_WIDTH_20; 6302774f206SBjoern A. Zeeb pkt_stat->signal_power = rx_power; 6312774f206SBjoern A. Zeeb } 6322774f206SBjoern A. Zeeb 6332774f206SBjoern A. Zeeb static void query_phy_status_page1(struct rtw_dev *rtwdev, u8 *phy_status, 6342774f206SBjoern A. Zeeb struct rtw_rx_pkt_stat *pkt_stat) 6352774f206SBjoern A. Zeeb { 6369c951734SBjoern A. Zeeb struct rtw_dm_info *dm_info = &rtwdev->dm_info; 6372774f206SBjoern A. Zeeb u8 rxsc, bw; 6382774f206SBjoern A. Zeeb s8 min_rx_power = -120; 6392774f206SBjoern A. Zeeb 6402774f206SBjoern A. Zeeb if (pkt_stat->rate > DESC_RATE11M && pkt_stat->rate < DESC_RATEMCS0) 6412774f206SBjoern A. Zeeb rxsc = GET_PHY_STAT_P1_L_RXSC(phy_status); 6422774f206SBjoern A. Zeeb else 6432774f206SBjoern A. Zeeb rxsc = GET_PHY_STAT_P1_HT_RXSC(phy_status); 6442774f206SBjoern A. Zeeb 6452774f206SBjoern A. Zeeb if (rxsc >= 1 && rxsc <= 8) 6462774f206SBjoern A. Zeeb bw = RTW_CHANNEL_WIDTH_20; 6472774f206SBjoern A. Zeeb else if (rxsc >= 9 && rxsc <= 12) 6482774f206SBjoern A. Zeeb bw = RTW_CHANNEL_WIDTH_40; 6492774f206SBjoern A. Zeeb else if (rxsc >= 13) 6502774f206SBjoern A. Zeeb bw = RTW_CHANNEL_WIDTH_80; 6512774f206SBjoern A. Zeeb else 6522774f206SBjoern A. Zeeb bw = GET_PHY_STAT_P1_RF_MODE(phy_status); 6532774f206SBjoern A. Zeeb 6542774f206SBjoern A. Zeeb pkt_stat->rx_power[RF_PATH_A] = GET_PHY_STAT_P1_PWDB_A(phy_status) - 110; 6552774f206SBjoern A. Zeeb pkt_stat->rssi = rtw_phy_rf_power_2_rssi(pkt_stat->rx_power, 1); 6569c951734SBjoern A. Zeeb dm_info->rssi[RF_PATH_A] = pkt_stat->rssi; 6572774f206SBjoern A. Zeeb pkt_stat->bw = bw; 6582774f206SBjoern A. Zeeb pkt_stat->signal_power = max(pkt_stat->rx_power[RF_PATH_A], 6592774f206SBjoern A. Zeeb min_rx_power); 6602774f206SBjoern A. Zeeb } 6612774f206SBjoern A. Zeeb 6622774f206SBjoern A. Zeeb static void query_phy_status(struct rtw_dev *rtwdev, u8 *phy_status, 6632774f206SBjoern A. Zeeb struct rtw_rx_pkt_stat *pkt_stat) 6642774f206SBjoern A. Zeeb { 6652774f206SBjoern A. Zeeb u8 page; 6662774f206SBjoern A. Zeeb 6672774f206SBjoern A. Zeeb page = *phy_status & 0xf; 6682774f206SBjoern A. Zeeb 6692774f206SBjoern A. Zeeb switch (page) { 6702774f206SBjoern A. Zeeb case 0: 6712774f206SBjoern A. Zeeb query_phy_status_page0(rtwdev, phy_status, pkt_stat); 6722774f206SBjoern A. Zeeb break; 6732774f206SBjoern A. Zeeb case 1: 6742774f206SBjoern A. Zeeb query_phy_status_page1(rtwdev, phy_status, pkt_stat); 6752774f206SBjoern A. Zeeb break; 6762774f206SBjoern A. Zeeb default: 6772774f206SBjoern A. Zeeb rtw_warn(rtwdev, "unused phy status page (%d)\n", page); 6782774f206SBjoern A. Zeeb return; 6792774f206SBjoern A. Zeeb } 6802774f206SBjoern A. Zeeb } 6812774f206SBjoern A. Zeeb 6822774f206SBjoern A. Zeeb static void rtw8821c_query_rx_desc(struct rtw_dev *rtwdev, u8 *rx_desc, 6832774f206SBjoern A. Zeeb struct rtw_rx_pkt_stat *pkt_stat, 6842774f206SBjoern A. Zeeb struct ieee80211_rx_status *rx_status) 6852774f206SBjoern A. Zeeb { 6862774f206SBjoern A. Zeeb struct ieee80211_hdr *hdr; 6872774f206SBjoern A. Zeeb u32 desc_sz = rtwdev->chip->rx_pkt_desc_sz; 6882774f206SBjoern A. Zeeb u8 *phy_status = NULL; 6892774f206SBjoern A. Zeeb 6902774f206SBjoern A. Zeeb memset(pkt_stat, 0, sizeof(*pkt_stat)); 6912774f206SBjoern A. Zeeb 6922774f206SBjoern A. Zeeb pkt_stat->phy_status = GET_RX_DESC_PHYST(rx_desc); 6932774f206SBjoern A. Zeeb pkt_stat->icv_err = GET_RX_DESC_ICV_ERR(rx_desc); 6942774f206SBjoern A. Zeeb pkt_stat->crc_err = GET_RX_DESC_CRC32(rx_desc); 6952774f206SBjoern A. Zeeb pkt_stat->decrypted = !GET_RX_DESC_SWDEC(rx_desc) && 6962774f206SBjoern A. Zeeb GET_RX_DESC_ENC_TYPE(rx_desc) != RX_DESC_ENC_NONE; 6972774f206SBjoern A. Zeeb pkt_stat->is_c2h = GET_RX_DESC_C2H(rx_desc); 6982774f206SBjoern A. Zeeb pkt_stat->pkt_len = GET_RX_DESC_PKT_LEN(rx_desc); 6992774f206SBjoern A. Zeeb pkt_stat->drv_info_sz = GET_RX_DESC_DRV_INFO_SIZE(rx_desc); 7002774f206SBjoern A. Zeeb pkt_stat->shift = GET_RX_DESC_SHIFT(rx_desc); 7012774f206SBjoern A. Zeeb pkt_stat->rate = GET_RX_DESC_RX_RATE(rx_desc); 7022774f206SBjoern A. Zeeb pkt_stat->cam_id = GET_RX_DESC_MACID(rx_desc); 7032774f206SBjoern A. Zeeb pkt_stat->ppdu_cnt = GET_RX_DESC_PPDU_CNT(rx_desc); 7042774f206SBjoern A. Zeeb pkt_stat->tsf_low = GET_RX_DESC_TSFL(rx_desc); 7052774f206SBjoern A. Zeeb 7062774f206SBjoern A. Zeeb /* drv_info_sz is in unit of 8-bytes */ 7072774f206SBjoern A. Zeeb pkt_stat->drv_info_sz *= 8; 7082774f206SBjoern A. Zeeb 7092774f206SBjoern A. Zeeb /* c2h cmd pkt's rx/phy status is not interested */ 7102774f206SBjoern A. Zeeb if (pkt_stat->is_c2h) 7112774f206SBjoern A. Zeeb return; 7122774f206SBjoern A. Zeeb 7132774f206SBjoern A. Zeeb hdr = (struct ieee80211_hdr *)(rx_desc + desc_sz + pkt_stat->shift + 7142774f206SBjoern A. Zeeb pkt_stat->drv_info_sz); 7152774f206SBjoern A. Zeeb if (pkt_stat->phy_status) { 7162774f206SBjoern A. Zeeb phy_status = rx_desc + desc_sz + pkt_stat->shift; 7172774f206SBjoern A. Zeeb query_phy_status(rtwdev, phy_status, pkt_stat); 7182774f206SBjoern A. Zeeb } 7192774f206SBjoern A. Zeeb 7202774f206SBjoern A. Zeeb rtw_rx_fill_rx_status(rtwdev, pkt_stat, hdr, rx_status, phy_status); 7212774f206SBjoern A. Zeeb } 7222774f206SBjoern A. Zeeb 7232774f206SBjoern A. Zeeb static void 7242774f206SBjoern A. Zeeb rtw8821c_set_tx_power_index_by_rate(struct rtw_dev *rtwdev, u8 path, u8 rs) 7252774f206SBjoern A. Zeeb { 7262774f206SBjoern A. Zeeb struct rtw_hal *hal = &rtwdev->hal; 7272774f206SBjoern A. Zeeb static const u32 offset_txagc[2] = {0x1d00, 0x1d80}; 7282774f206SBjoern A. Zeeb static u32 phy_pwr_idx; 7292774f206SBjoern A. Zeeb u8 rate, rate_idx, pwr_index, shift; 7302774f206SBjoern A. Zeeb int j; 7312774f206SBjoern A. Zeeb 7322774f206SBjoern A. Zeeb for (j = 0; j < rtw_rate_size[rs]; j++) { 7332774f206SBjoern A. Zeeb rate = rtw_rate_section[rs][j]; 7342774f206SBjoern A. Zeeb pwr_index = hal->tx_pwr_tbl[path][rate]; 7352774f206SBjoern A. Zeeb shift = rate & 0x3; 7362774f206SBjoern A. Zeeb phy_pwr_idx |= ((u32)pwr_index << (shift * 8)); 7372774f206SBjoern A. Zeeb if (shift == 0x3 || rate == DESC_RATEVHT1SS_MCS9) { 7382774f206SBjoern A. Zeeb rate_idx = rate & 0xfc; 7392774f206SBjoern A. Zeeb rtw_write32(rtwdev, offset_txagc[path] + rate_idx, 7402774f206SBjoern A. Zeeb phy_pwr_idx); 7412774f206SBjoern A. Zeeb phy_pwr_idx = 0; 7422774f206SBjoern A. Zeeb } 7432774f206SBjoern A. Zeeb } 7442774f206SBjoern A. Zeeb } 7452774f206SBjoern A. Zeeb 7462774f206SBjoern A. Zeeb static void rtw8821c_set_tx_power_index(struct rtw_dev *rtwdev) 7472774f206SBjoern A. Zeeb { 7482774f206SBjoern A. Zeeb struct rtw_hal *hal = &rtwdev->hal; 7492774f206SBjoern A. Zeeb int rs, path; 7502774f206SBjoern A. Zeeb 7512774f206SBjoern A. Zeeb for (path = 0; path < hal->rf_path_num; path++) { 7522774f206SBjoern A. Zeeb for (rs = 0; rs < RTW_RATE_SECTION_MAX; rs++) { 7532774f206SBjoern A. Zeeb if (rs == RTW_RATE_SECTION_HT_2S || 7542774f206SBjoern A. Zeeb rs == RTW_RATE_SECTION_VHT_2S) 7552774f206SBjoern A. Zeeb continue; 7562774f206SBjoern A. Zeeb rtw8821c_set_tx_power_index_by_rate(rtwdev, path, rs); 7572774f206SBjoern A. Zeeb } 7582774f206SBjoern A. Zeeb } 7592774f206SBjoern A. Zeeb } 7602774f206SBjoern A. Zeeb 7612774f206SBjoern A. Zeeb static void rtw8821c_false_alarm_statistics(struct rtw_dev *rtwdev) 7622774f206SBjoern A. Zeeb { 7632774f206SBjoern A. Zeeb struct rtw_dm_info *dm_info = &rtwdev->dm_info; 7642774f206SBjoern A. Zeeb u32 cck_enable; 7652774f206SBjoern A. Zeeb u32 cck_fa_cnt; 7662774f206SBjoern A. Zeeb u32 ofdm_fa_cnt; 7672774f206SBjoern A. Zeeb u32 crc32_cnt; 7682774f206SBjoern A. Zeeb u32 cca32_cnt; 7692774f206SBjoern A. Zeeb 7702774f206SBjoern A. Zeeb cck_enable = rtw_read32(rtwdev, REG_RXPSEL) & BIT(28); 7712774f206SBjoern A. Zeeb cck_fa_cnt = rtw_read16(rtwdev, REG_FA_CCK); 7722774f206SBjoern A. Zeeb ofdm_fa_cnt = rtw_read16(rtwdev, REG_FA_OFDM); 7732774f206SBjoern A. Zeeb 7742774f206SBjoern A. Zeeb dm_info->cck_fa_cnt = cck_fa_cnt; 7752774f206SBjoern A. Zeeb dm_info->ofdm_fa_cnt = ofdm_fa_cnt; 776*11c53278SBjoern A. Zeeb dm_info->total_fa_cnt = ofdm_fa_cnt; 7772774f206SBjoern A. Zeeb if (cck_enable) 7782774f206SBjoern A. Zeeb dm_info->total_fa_cnt += cck_fa_cnt; 7792774f206SBjoern A. Zeeb 7802774f206SBjoern A. Zeeb crc32_cnt = rtw_read32(rtwdev, REG_CRC_CCK); 7812774f206SBjoern A. Zeeb dm_info->cck_ok_cnt = FIELD_GET(GENMASK(15, 0), crc32_cnt); 7822774f206SBjoern A. Zeeb dm_info->cck_err_cnt = FIELD_GET(GENMASK(31, 16), crc32_cnt); 7832774f206SBjoern A. Zeeb 7842774f206SBjoern A. Zeeb crc32_cnt = rtw_read32(rtwdev, REG_CRC_OFDM); 7852774f206SBjoern A. Zeeb dm_info->ofdm_ok_cnt = FIELD_GET(GENMASK(15, 0), crc32_cnt); 7862774f206SBjoern A. Zeeb dm_info->ofdm_err_cnt = FIELD_GET(GENMASK(31, 16), crc32_cnt); 7872774f206SBjoern A. Zeeb 7882774f206SBjoern A. Zeeb crc32_cnt = rtw_read32(rtwdev, REG_CRC_HT); 7892774f206SBjoern A. Zeeb dm_info->ht_ok_cnt = FIELD_GET(GENMASK(15, 0), crc32_cnt); 7902774f206SBjoern A. Zeeb dm_info->ht_err_cnt = FIELD_GET(GENMASK(31, 16), crc32_cnt); 7912774f206SBjoern A. Zeeb 7922774f206SBjoern A. Zeeb crc32_cnt = rtw_read32(rtwdev, REG_CRC_VHT); 7932774f206SBjoern A. Zeeb dm_info->vht_ok_cnt = FIELD_GET(GENMASK(15, 0), crc32_cnt); 7942774f206SBjoern A. Zeeb dm_info->vht_err_cnt = FIELD_GET(GENMASK(31, 16), crc32_cnt); 7952774f206SBjoern A. Zeeb 7962774f206SBjoern A. Zeeb cca32_cnt = rtw_read32(rtwdev, REG_CCA_OFDM); 7972774f206SBjoern A. Zeeb dm_info->ofdm_cca_cnt = FIELD_GET(GENMASK(31, 16), cca32_cnt); 7982774f206SBjoern A. Zeeb dm_info->total_cca_cnt = dm_info->ofdm_cca_cnt; 7992774f206SBjoern A. Zeeb if (cck_enable) { 8002774f206SBjoern A. Zeeb cca32_cnt = rtw_read32(rtwdev, REG_CCA_CCK); 8012774f206SBjoern A. Zeeb dm_info->cck_cca_cnt = FIELD_GET(GENMASK(15, 0), cca32_cnt); 8022774f206SBjoern A. Zeeb dm_info->total_cca_cnt += dm_info->cck_cca_cnt; 8032774f206SBjoern A. Zeeb } 8042774f206SBjoern A. Zeeb 8052774f206SBjoern A. Zeeb rtw_write32_set(rtwdev, REG_FAS, BIT(17)); 8062774f206SBjoern A. Zeeb rtw_write32_clr(rtwdev, REG_FAS, BIT(17)); 8072774f206SBjoern A. Zeeb rtw_write32_clr(rtwdev, REG_RXDESC, BIT(15)); 8082774f206SBjoern A. Zeeb rtw_write32_set(rtwdev, REG_RXDESC, BIT(15)); 8092774f206SBjoern A. Zeeb rtw_write32_set(rtwdev, REG_CNTRST, BIT(0)); 8102774f206SBjoern A. Zeeb rtw_write32_clr(rtwdev, REG_CNTRST, BIT(0)); 8112774f206SBjoern A. Zeeb } 8122774f206SBjoern A. Zeeb 8132774f206SBjoern A. Zeeb static void rtw8821c_do_iqk(struct rtw_dev *rtwdev) 8142774f206SBjoern A. Zeeb { 8152774f206SBjoern A. Zeeb static int do_iqk_cnt; 8162774f206SBjoern A. Zeeb struct rtw_iqk_para para = {.clear = 0, .segment_iqk = 0}; 8172774f206SBjoern A. Zeeb u32 rf_reg, iqk_fail_mask; 8182774f206SBjoern A. Zeeb int counter; 8192774f206SBjoern A. Zeeb bool reload; 8202774f206SBjoern A. Zeeb 8212774f206SBjoern A. Zeeb if (rtw_is_assoc(rtwdev)) 8222774f206SBjoern A. Zeeb para.segment_iqk = 1; 8232774f206SBjoern A. Zeeb 8242774f206SBjoern A. Zeeb rtw_fw_do_iqk(rtwdev, ¶); 8252774f206SBjoern A. Zeeb 8262774f206SBjoern A. Zeeb for (counter = 0; counter < 300; counter++) { 8272774f206SBjoern A. Zeeb rf_reg = rtw_read_rf(rtwdev, RF_PATH_A, RF_DTXLOK, RFREG_MASK); 8282774f206SBjoern A. Zeeb if (rf_reg == 0xabcde) 8292774f206SBjoern A. Zeeb break; 8302774f206SBjoern A. Zeeb msleep(20); 8312774f206SBjoern A. Zeeb } 8322774f206SBjoern A. Zeeb rtw_write_rf(rtwdev, RF_PATH_A, RF_DTXLOK, RFREG_MASK, 0x0); 8332774f206SBjoern A. Zeeb 8342774f206SBjoern A. Zeeb reload = !!rtw_read32_mask(rtwdev, REG_IQKFAILMSK, BIT(16)); 8352774f206SBjoern A. Zeeb iqk_fail_mask = rtw_read32_mask(rtwdev, REG_IQKFAILMSK, GENMASK(7, 0)); 8362774f206SBjoern A. Zeeb rtw_dbg(rtwdev, RTW_DBG_PHY, 8372774f206SBjoern A. Zeeb "iqk counter=%d reload=%d do_iqk_cnt=%d n_iqk_fail(mask)=0x%02x\n", 8382774f206SBjoern A. Zeeb counter, reload, ++do_iqk_cnt, iqk_fail_mask); 8392774f206SBjoern A. Zeeb } 8402774f206SBjoern A. Zeeb 8412774f206SBjoern A. Zeeb static void rtw8821c_phy_calibration(struct rtw_dev *rtwdev) 8422774f206SBjoern A. Zeeb { 8432774f206SBjoern A. Zeeb rtw8821c_do_iqk(rtwdev); 8442774f206SBjoern A. Zeeb } 8452774f206SBjoern A. Zeeb 8462774f206SBjoern A. Zeeb /* for coex */ 8472774f206SBjoern A. Zeeb static void rtw8821c_coex_cfg_init(struct rtw_dev *rtwdev) 8482774f206SBjoern A. Zeeb { 8492774f206SBjoern A. Zeeb /* enable TBTT nterrupt */ 8502774f206SBjoern A. Zeeb rtw_write8_set(rtwdev, REG_BCN_CTRL, BIT_EN_BCN_FUNCTION); 8512774f206SBjoern A. Zeeb 8522774f206SBjoern A. Zeeb /* BT report packet sample rate */ 8532774f206SBjoern A. Zeeb rtw_write8_mask(rtwdev, REG_BT_TDMA_TIME, BIT_MASK_SAMPLE_RATE, 0x5); 8542774f206SBjoern A. Zeeb 8552774f206SBjoern A. Zeeb /* enable BT counter statistics */ 8562774f206SBjoern A. Zeeb rtw_write8(rtwdev, REG_BT_STAT_CTRL, BT_CNT_ENABLE); 8572774f206SBjoern A. Zeeb 8582774f206SBjoern A. Zeeb /* enable PTA (3-wire function form BT side) */ 8592774f206SBjoern A. Zeeb rtw_write32_set(rtwdev, REG_GPIO_MUXCFG, BIT_BT_PTA_EN); 8602774f206SBjoern A. Zeeb rtw_write32_set(rtwdev, REG_GPIO_MUXCFG, BIT_PO_BT_PTA_PINS); 8612774f206SBjoern A. Zeeb 8622774f206SBjoern A. Zeeb /* enable PTA (tx/rx signal form WiFi side) */ 8632774f206SBjoern A. Zeeb rtw_write8_set(rtwdev, REG_QUEUE_CTRL, BIT_PTA_WL_TX_EN); 8642774f206SBjoern A. Zeeb /* wl tx signal to PTA not case EDCCA */ 8652774f206SBjoern A. Zeeb rtw_write8_clr(rtwdev, REG_QUEUE_CTRL, BIT_PTA_EDCCA_EN); 8662774f206SBjoern A. Zeeb /* GNT_BT=1 while select both */ 8672774f206SBjoern A. Zeeb rtw_write16_set(rtwdev, REG_BT_COEX_V2, BIT_GNT_BT_POLARITY); 8682774f206SBjoern A. Zeeb 8692774f206SBjoern A. Zeeb /* beacon queue always hi-pri */ 8702774f206SBjoern A. Zeeb rtw_write8_mask(rtwdev, REG_BT_COEX_TABLE_H + 3, BIT_BCN_QUEUE, 8712774f206SBjoern A. Zeeb BCN_PRI_EN); 8722774f206SBjoern A. Zeeb } 8732774f206SBjoern A. Zeeb 8742774f206SBjoern A. Zeeb static void rtw8821c_coex_cfg_ant_switch(struct rtw_dev *rtwdev, u8 ctrl_type, 8752774f206SBjoern A. Zeeb u8 pos_type) 8762774f206SBjoern A. Zeeb { 8772774f206SBjoern A. Zeeb struct rtw_coex *coex = &rtwdev->coex; 8782774f206SBjoern A. Zeeb struct rtw_coex_dm *coex_dm = &coex->dm; 8792774f206SBjoern A. Zeeb struct rtw_coex_rfe *coex_rfe = &coex->rfe; 8802774f206SBjoern A. Zeeb u32 switch_status = FIELD_PREP(CTRL_TYPE_MASK, ctrl_type) | pos_type; 8812774f206SBjoern A. Zeeb bool polarity_inverse; 8822774f206SBjoern A. Zeeb u8 regval = 0; 8832774f206SBjoern A. Zeeb 8842774f206SBjoern A. Zeeb if (switch_status == coex_dm->cur_switch_status) 8852774f206SBjoern A. Zeeb return; 8862774f206SBjoern A. Zeeb 8872774f206SBjoern A. Zeeb if (coex_rfe->wlg_at_btg) { 8882774f206SBjoern A. Zeeb ctrl_type = COEX_SWITCH_CTRL_BY_BBSW; 8892774f206SBjoern A. Zeeb 8902774f206SBjoern A. Zeeb if (coex_rfe->ant_switch_polarity) 8912774f206SBjoern A. Zeeb pos_type = COEX_SWITCH_TO_WLA; 8922774f206SBjoern A. Zeeb else 8932774f206SBjoern A. Zeeb pos_type = COEX_SWITCH_TO_WLG_BT; 8942774f206SBjoern A. Zeeb } 8952774f206SBjoern A. Zeeb 8962774f206SBjoern A. Zeeb coex_dm->cur_switch_status = switch_status; 8972774f206SBjoern A. Zeeb 8982774f206SBjoern A. Zeeb if (coex_rfe->ant_switch_diversity && 8992774f206SBjoern A. Zeeb ctrl_type == COEX_SWITCH_CTRL_BY_BBSW) 9002774f206SBjoern A. Zeeb ctrl_type = COEX_SWITCH_CTRL_BY_ANTDIV; 9012774f206SBjoern A. Zeeb 9022774f206SBjoern A. Zeeb polarity_inverse = (coex_rfe->ant_switch_polarity == 1); 9032774f206SBjoern A. Zeeb 9042774f206SBjoern A. Zeeb switch (ctrl_type) { 9052774f206SBjoern A. Zeeb default: 9062774f206SBjoern A. Zeeb case COEX_SWITCH_CTRL_BY_BBSW: 9072774f206SBjoern A. Zeeb rtw_write32_clr(rtwdev, REG_LED_CFG, BIT_DPDT_SEL_EN); 9082774f206SBjoern A. Zeeb rtw_write32_set(rtwdev, REG_LED_CFG, BIT_DPDT_WL_SEL); 9092774f206SBjoern A. Zeeb /* BB SW, DPDT use RFE_ctrl8 and RFE_ctrl9 as ctrl pin */ 9102774f206SBjoern A. Zeeb rtw_write8_mask(rtwdev, REG_RFE_CTRL8, BIT_MASK_RFE_SEL89, 9112774f206SBjoern A. Zeeb DPDT_CTRL_PIN); 9122774f206SBjoern A. Zeeb 9132774f206SBjoern A. Zeeb if (pos_type == COEX_SWITCH_TO_WLG_BT) { 9142774f206SBjoern A. Zeeb if (coex_rfe->rfe_module_type != 0x4 && 9152774f206SBjoern A. Zeeb coex_rfe->rfe_module_type != 0x2) 9162774f206SBjoern A. Zeeb regval = 0x3; 9172774f206SBjoern A. Zeeb else 9182774f206SBjoern A. Zeeb regval = (!polarity_inverse ? 0x2 : 0x1); 9192774f206SBjoern A. Zeeb } else if (pos_type == COEX_SWITCH_TO_WLG) { 9202774f206SBjoern A. Zeeb regval = (!polarity_inverse ? 0x2 : 0x1); 9212774f206SBjoern A. Zeeb } else { 9222774f206SBjoern A. Zeeb regval = (!polarity_inverse ? 0x1 : 0x2); 9232774f206SBjoern A. Zeeb } 9242774f206SBjoern A. Zeeb 9252774f206SBjoern A. Zeeb rtw_write32_mask(rtwdev, REG_RFE_CTRL8, BIT_MASK_R_RFE_SEL_15, 9262774f206SBjoern A. Zeeb regval); 9272774f206SBjoern A. Zeeb break; 9282774f206SBjoern A. Zeeb case COEX_SWITCH_CTRL_BY_PTA: 9292774f206SBjoern A. Zeeb rtw_write32_clr(rtwdev, REG_LED_CFG, BIT_DPDT_SEL_EN); 9302774f206SBjoern A. Zeeb rtw_write32_set(rtwdev, REG_LED_CFG, BIT_DPDT_WL_SEL); 9312774f206SBjoern A. Zeeb /* PTA, DPDT use RFE_ctrl8 and RFE_ctrl9 as ctrl pin */ 9322774f206SBjoern A. Zeeb rtw_write8_mask(rtwdev, REG_RFE_CTRL8, BIT_MASK_RFE_SEL89, 9332774f206SBjoern A. Zeeb PTA_CTRL_PIN); 9342774f206SBjoern A. Zeeb 9352774f206SBjoern A. Zeeb regval = (!polarity_inverse ? 0x2 : 0x1); 9362774f206SBjoern A. Zeeb rtw_write32_mask(rtwdev, REG_RFE_CTRL8, BIT_MASK_R_RFE_SEL_15, 9372774f206SBjoern A. Zeeb regval); 9382774f206SBjoern A. Zeeb break; 9392774f206SBjoern A. Zeeb case COEX_SWITCH_CTRL_BY_ANTDIV: 9402774f206SBjoern A. Zeeb rtw_write32_clr(rtwdev, REG_LED_CFG, BIT_DPDT_SEL_EN); 9412774f206SBjoern A. Zeeb rtw_write32_set(rtwdev, REG_LED_CFG, BIT_DPDT_WL_SEL); 9422774f206SBjoern A. Zeeb rtw_write8_mask(rtwdev, REG_RFE_CTRL8, BIT_MASK_RFE_SEL89, 9432774f206SBjoern A. Zeeb ANTDIC_CTRL_PIN); 9442774f206SBjoern A. Zeeb break; 9452774f206SBjoern A. Zeeb case COEX_SWITCH_CTRL_BY_MAC: 9462774f206SBjoern A. Zeeb rtw_write32_set(rtwdev, REG_LED_CFG, BIT_DPDT_SEL_EN); 9472774f206SBjoern A. Zeeb 9482774f206SBjoern A. Zeeb regval = (!polarity_inverse ? 0x0 : 0x1); 9492774f206SBjoern A. Zeeb rtw_write8_mask(rtwdev, REG_PAD_CTRL1, BIT_SW_DPDT_SEL_DATA, 9502774f206SBjoern A. Zeeb regval); 9512774f206SBjoern A. Zeeb break; 9522774f206SBjoern A. Zeeb case COEX_SWITCH_CTRL_BY_FW: 9532774f206SBjoern A. Zeeb rtw_write32_clr(rtwdev, REG_LED_CFG, BIT_DPDT_SEL_EN); 9542774f206SBjoern A. Zeeb rtw_write32_set(rtwdev, REG_LED_CFG, BIT_DPDT_WL_SEL); 9552774f206SBjoern A. Zeeb break; 9562774f206SBjoern A. Zeeb case COEX_SWITCH_CTRL_BY_BT: 9572774f206SBjoern A. Zeeb rtw_write32_clr(rtwdev, REG_LED_CFG, BIT_DPDT_SEL_EN); 9582774f206SBjoern A. Zeeb rtw_write32_clr(rtwdev, REG_LED_CFG, BIT_DPDT_WL_SEL); 9592774f206SBjoern A. Zeeb break; 9602774f206SBjoern A. Zeeb } 9612774f206SBjoern A. Zeeb 9622774f206SBjoern A. Zeeb if (ctrl_type == COEX_SWITCH_CTRL_BY_BT) { 9632774f206SBjoern A. Zeeb rtw_write8_clr(rtwdev, REG_CTRL_TYPE, BIT_CTRL_TYPE1); 9642774f206SBjoern A. Zeeb rtw_write8_clr(rtwdev, REG_CTRL_TYPE, BIT_CTRL_TYPE2); 9652774f206SBjoern A. Zeeb } else { 9662774f206SBjoern A. Zeeb rtw_write8_set(rtwdev, REG_CTRL_TYPE, BIT_CTRL_TYPE1); 9672774f206SBjoern A. Zeeb rtw_write8_set(rtwdev, REG_CTRL_TYPE, BIT_CTRL_TYPE2); 9682774f206SBjoern A. Zeeb } 9692774f206SBjoern A. Zeeb } 9702774f206SBjoern A. Zeeb 9712774f206SBjoern A. Zeeb static void rtw8821c_coex_cfg_gnt_fix(struct rtw_dev *rtwdev) 9722774f206SBjoern A. Zeeb {} 9732774f206SBjoern A. Zeeb 9742774f206SBjoern A. Zeeb static void rtw8821c_coex_cfg_gnt_debug(struct rtw_dev *rtwdev) 9752774f206SBjoern A. Zeeb { 9762774f206SBjoern A. Zeeb rtw_write32_clr(rtwdev, REG_PAD_CTRL1, BIT_BTGP_SPI_EN); 9772774f206SBjoern A. Zeeb rtw_write32_clr(rtwdev, REG_PAD_CTRL1, BIT_BTGP_JTAG_EN); 9782774f206SBjoern A. Zeeb rtw_write32_clr(rtwdev, REG_GPIO_MUXCFG, BIT_FSPI_EN); 9792774f206SBjoern A. Zeeb rtw_write32_clr(rtwdev, REG_PAD_CTRL1, BIT_LED1DIS); 9802774f206SBjoern A. Zeeb rtw_write32_clr(rtwdev, REG_SYS_SDIO_CTRL, BIT_SDIO_INT); 9812774f206SBjoern A. Zeeb rtw_write32_clr(rtwdev, REG_SYS_SDIO_CTRL, BIT_DBG_GNT_WL_BT); 9822774f206SBjoern A. Zeeb } 9832774f206SBjoern A. Zeeb 9842774f206SBjoern A. Zeeb static void rtw8821c_coex_cfg_rfe_type(struct rtw_dev *rtwdev) 9852774f206SBjoern A. Zeeb { 9862774f206SBjoern A. Zeeb struct rtw_coex *coex = &rtwdev->coex; 9872774f206SBjoern A. Zeeb struct rtw_coex_rfe *coex_rfe = &coex->rfe; 9882774f206SBjoern A. Zeeb struct rtw_efuse *efuse = &rtwdev->efuse; 9892774f206SBjoern A. Zeeb 9902774f206SBjoern A. Zeeb coex_rfe->rfe_module_type = efuse->rfe_option; 9912774f206SBjoern A. Zeeb coex_rfe->ant_switch_polarity = 0; 9922774f206SBjoern A. Zeeb coex_rfe->ant_switch_exist = true; 9932774f206SBjoern A. Zeeb coex_rfe->wlg_at_btg = false; 9942774f206SBjoern A. Zeeb 9952774f206SBjoern A. Zeeb switch (coex_rfe->rfe_module_type) { 9962774f206SBjoern A. Zeeb case 0: 9972774f206SBjoern A. Zeeb case 8: 9982774f206SBjoern A. Zeeb case 1: 9992774f206SBjoern A. Zeeb case 9: /* 1-Ant, Main, WLG */ 10002774f206SBjoern A. Zeeb default: /* 2-Ant, DPDT, WLG */ 10012774f206SBjoern A. Zeeb break; 10022774f206SBjoern A. Zeeb case 2: 10032774f206SBjoern A. Zeeb case 10: /* 1-Ant, Main, BTG */ 10042774f206SBjoern A. Zeeb case 7: 10052774f206SBjoern A. Zeeb case 15: /* 2-Ant, DPDT, BTG */ 10062774f206SBjoern A. Zeeb coex_rfe->wlg_at_btg = true; 10072774f206SBjoern A. Zeeb break; 10082774f206SBjoern A. Zeeb case 3: 10092774f206SBjoern A. Zeeb case 11: /* 1-Ant, Aux, WLG */ 10102774f206SBjoern A. Zeeb coex_rfe->ant_switch_polarity = 1; 10112774f206SBjoern A. Zeeb break; 10122774f206SBjoern A. Zeeb case 4: 10132774f206SBjoern A. Zeeb case 12: /* 1-Ant, Aux, BTG */ 10142774f206SBjoern A. Zeeb coex_rfe->wlg_at_btg = true; 10152774f206SBjoern A. Zeeb coex_rfe->ant_switch_polarity = 1; 10162774f206SBjoern A. Zeeb break; 10172774f206SBjoern A. Zeeb case 5: 10182774f206SBjoern A. Zeeb case 13: /* 2-Ant, no switch, WLG */ 10192774f206SBjoern A. Zeeb case 6: 10202774f206SBjoern A. Zeeb case 14: /* 2-Ant, no antenna switch, WLG */ 10212774f206SBjoern A. Zeeb coex_rfe->ant_switch_exist = false; 10222774f206SBjoern A. Zeeb break; 10232774f206SBjoern A. Zeeb } 10242774f206SBjoern A. Zeeb } 10252774f206SBjoern A. Zeeb 10262774f206SBjoern A. Zeeb static void rtw8821c_coex_cfg_wl_tx_power(struct rtw_dev *rtwdev, u8 wl_pwr) 10272774f206SBjoern A. Zeeb { 10282774f206SBjoern A. Zeeb struct rtw_coex *coex = &rtwdev->coex; 10292774f206SBjoern A. Zeeb struct rtw_coex_dm *coex_dm = &coex->dm; 10302774f206SBjoern A. Zeeb struct rtw_efuse *efuse = &rtwdev->efuse; 10312774f206SBjoern A. Zeeb bool share_ant = efuse->share_ant; 10322774f206SBjoern A. Zeeb 10332774f206SBjoern A. Zeeb if (share_ant) 10342774f206SBjoern A. Zeeb return; 10352774f206SBjoern A. Zeeb 10362774f206SBjoern A. Zeeb if (wl_pwr == coex_dm->cur_wl_pwr_lvl) 10372774f206SBjoern A. Zeeb return; 10382774f206SBjoern A. Zeeb 10392774f206SBjoern A. Zeeb coex_dm->cur_wl_pwr_lvl = wl_pwr; 10402774f206SBjoern A. Zeeb } 10412774f206SBjoern A. Zeeb 10422774f206SBjoern A. Zeeb static void rtw8821c_coex_cfg_wl_rx_gain(struct rtw_dev *rtwdev, bool low_gain) 10432774f206SBjoern A. Zeeb {} 10442774f206SBjoern A. Zeeb 10452774f206SBjoern A. Zeeb static void 10462774f206SBjoern A. Zeeb rtw8821c_txagc_swing_offset(struct rtw_dev *rtwdev, u8 pwr_idx_offset, 10472774f206SBjoern A. Zeeb s8 pwr_idx_offset_lower, 10482774f206SBjoern A. Zeeb s8 *txagc_idx, u8 *swing_idx) 10492774f206SBjoern A. Zeeb { 10502774f206SBjoern A. Zeeb struct rtw_dm_info *dm_info = &rtwdev->dm_info; 10512774f206SBjoern A. Zeeb s8 delta_pwr_idx = dm_info->delta_power_index[RF_PATH_A]; 10522774f206SBjoern A. Zeeb u8 swing_upper_bound = dm_info->default_ofdm_index + 10; 10532774f206SBjoern A. Zeeb u8 swing_lower_bound = 0; 10542774f206SBjoern A. Zeeb u8 max_pwr_idx_offset = 0xf; 10552774f206SBjoern A. Zeeb s8 agc_index = 0; 10562774f206SBjoern A. Zeeb u8 swing_index = dm_info->default_ofdm_index; 10572774f206SBjoern A. Zeeb 10582774f206SBjoern A. Zeeb pwr_idx_offset = min_t(u8, pwr_idx_offset, max_pwr_idx_offset); 10592774f206SBjoern A. Zeeb pwr_idx_offset_lower = max_t(s8, pwr_idx_offset_lower, -15); 10602774f206SBjoern A. Zeeb 10612774f206SBjoern A. Zeeb if (delta_pwr_idx >= 0) { 10622774f206SBjoern A. Zeeb if (delta_pwr_idx <= pwr_idx_offset) { 10632774f206SBjoern A. Zeeb agc_index = delta_pwr_idx; 10642774f206SBjoern A. Zeeb swing_index = dm_info->default_ofdm_index; 10652774f206SBjoern A. Zeeb } else if (delta_pwr_idx > pwr_idx_offset) { 10662774f206SBjoern A. Zeeb agc_index = pwr_idx_offset; 10672774f206SBjoern A. Zeeb swing_index = dm_info->default_ofdm_index + 10682774f206SBjoern A. Zeeb delta_pwr_idx - pwr_idx_offset; 10692774f206SBjoern A. Zeeb swing_index = min_t(u8, swing_index, swing_upper_bound); 10702774f206SBjoern A. Zeeb } 10712774f206SBjoern A. Zeeb } else if (delta_pwr_idx < 0) { 10722774f206SBjoern A. Zeeb if (delta_pwr_idx >= pwr_idx_offset_lower) { 10732774f206SBjoern A. Zeeb agc_index = delta_pwr_idx; 10742774f206SBjoern A. Zeeb swing_index = dm_info->default_ofdm_index; 10752774f206SBjoern A. Zeeb } else if (delta_pwr_idx < pwr_idx_offset_lower) { 10762774f206SBjoern A. Zeeb if (dm_info->default_ofdm_index > 10772774f206SBjoern A. Zeeb (pwr_idx_offset_lower - delta_pwr_idx)) 10782774f206SBjoern A. Zeeb swing_index = dm_info->default_ofdm_index + 10792774f206SBjoern A. Zeeb delta_pwr_idx - pwr_idx_offset_lower; 10802774f206SBjoern A. Zeeb else 10812774f206SBjoern A. Zeeb swing_index = swing_lower_bound; 10822774f206SBjoern A. Zeeb 10832774f206SBjoern A. Zeeb agc_index = pwr_idx_offset_lower; 10842774f206SBjoern A. Zeeb } 10852774f206SBjoern A. Zeeb } 10862774f206SBjoern A. Zeeb 10872774f206SBjoern A. Zeeb if (swing_index >= ARRAY_SIZE(rtw8821c_txscale_tbl)) { 10882774f206SBjoern A. Zeeb rtw_warn(rtwdev, "swing index overflow\n"); 10892774f206SBjoern A. Zeeb swing_index = ARRAY_SIZE(rtw8821c_txscale_tbl) - 1; 10902774f206SBjoern A. Zeeb } 10912774f206SBjoern A. Zeeb 10922774f206SBjoern A. Zeeb *txagc_idx = agc_index; 10932774f206SBjoern A. Zeeb *swing_idx = swing_index; 10942774f206SBjoern A. Zeeb } 10952774f206SBjoern A. Zeeb 10962774f206SBjoern A. Zeeb static void rtw8821c_pwrtrack_set_pwr(struct rtw_dev *rtwdev, u8 pwr_idx_offset, 10972774f206SBjoern A. Zeeb s8 pwr_idx_offset_lower) 10982774f206SBjoern A. Zeeb { 10992774f206SBjoern A. Zeeb s8 txagc_idx; 11002774f206SBjoern A. Zeeb u8 swing_idx; 11012774f206SBjoern A. Zeeb 11022774f206SBjoern A. Zeeb rtw8821c_txagc_swing_offset(rtwdev, pwr_idx_offset, pwr_idx_offset_lower, 11032774f206SBjoern A. Zeeb &txagc_idx, &swing_idx); 11042774f206SBjoern A. Zeeb rtw_write32_mask(rtwdev, REG_TXAGCIDX, GENMASK(6, 1), txagc_idx); 11052774f206SBjoern A. Zeeb rtw_write32_mask(rtwdev, REG_TXSCALE_A, GENMASK(31, 21), 11062774f206SBjoern A. Zeeb rtw8821c_txscale_tbl[swing_idx]); 11072774f206SBjoern A. Zeeb } 11082774f206SBjoern A. Zeeb 11092774f206SBjoern A. Zeeb static void rtw8821c_pwrtrack_set(struct rtw_dev *rtwdev) 11102774f206SBjoern A. Zeeb { 11112774f206SBjoern A. Zeeb struct rtw_dm_info *dm_info = &rtwdev->dm_info; 11122774f206SBjoern A. Zeeb u8 pwr_idx_offset, tx_pwr_idx; 11132774f206SBjoern A. Zeeb s8 pwr_idx_offset_lower; 11142774f206SBjoern A. Zeeb u8 channel = rtwdev->hal.current_channel; 11152774f206SBjoern A. Zeeb u8 band_width = rtwdev->hal.current_band_width; 11162774f206SBjoern A. Zeeb u8 regd = rtw_regd_get(rtwdev); 11172774f206SBjoern A. Zeeb u8 tx_rate = dm_info->tx_rate; 11182774f206SBjoern A. Zeeb u8 max_pwr_idx = rtwdev->chip->max_power_index; 11192774f206SBjoern A. Zeeb 11202774f206SBjoern A. Zeeb tx_pwr_idx = rtw_phy_get_tx_power_index(rtwdev, RF_PATH_A, tx_rate, 11212774f206SBjoern A. Zeeb band_width, channel, regd); 11222774f206SBjoern A. Zeeb 11232774f206SBjoern A. Zeeb tx_pwr_idx = min_t(u8, tx_pwr_idx, max_pwr_idx); 11242774f206SBjoern A. Zeeb 11252774f206SBjoern A. Zeeb pwr_idx_offset = max_pwr_idx - tx_pwr_idx; 11262774f206SBjoern A. Zeeb pwr_idx_offset_lower = 0 - tx_pwr_idx; 11272774f206SBjoern A. Zeeb 11282774f206SBjoern A. Zeeb rtw8821c_pwrtrack_set_pwr(rtwdev, pwr_idx_offset, pwr_idx_offset_lower); 11292774f206SBjoern A. Zeeb } 11302774f206SBjoern A. Zeeb 11312774f206SBjoern A. Zeeb static void rtw8821c_phy_pwrtrack(struct rtw_dev *rtwdev) 11322774f206SBjoern A. Zeeb { 11332774f206SBjoern A. Zeeb struct rtw_dm_info *dm_info = &rtwdev->dm_info; 11342774f206SBjoern A. Zeeb struct rtw_swing_table swing_table; 11352774f206SBjoern A. Zeeb u8 thermal_value, delta; 11362774f206SBjoern A. Zeeb 11372774f206SBjoern A. Zeeb rtw_phy_config_swing_table(rtwdev, &swing_table); 11382774f206SBjoern A. Zeeb 11392774f206SBjoern A. Zeeb if (rtwdev->efuse.thermal_meter[0] == 0xff) 11402774f206SBjoern A. Zeeb return; 11412774f206SBjoern A. Zeeb 11422774f206SBjoern A. Zeeb thermal_value = rtw_read_rf(rtwdev, RF_PATH_A, RF_T_METER, 0xfc00); 11432774f206SBjoern A. Zeeb 11442774f206SBjoern A. Zeeb rtw_phy_pwrtrack_avg(rtwdev, thermal_value, RF_PATH_A); 11452774f206SBjoern A. Zeeb 11462774f206SBjoern A. Zeeb if (dm_info->pwr_trk_init_trigger) 11472774f206SBjoern A. Zeeb dm_info->pwr_trk_init_trigger = false; 11482774f206SBjoern A. Zeeb else if (!rtw_phy_pwrtrack_thermal_changed(rtwdev, thermal_value, 11492774f206SBjoern A. Zeeb RF_PATH_A)) 11502774f206SBjoern A. Zeeb goto iqk; 11512774f206SBjoern A. Zeeb 11522774f206SBjoern A. Zeeb delta = rtw_phy_pwrtrack_get_delta(rtwdev, RF_PATH_A); 11532774f206SBjoern A. Zeeb 11542774f206SBjoern A. Zeeb delta = min_t(u8, delta, RTW_PWR_TRK_TBL_SZ - 1); 11552774f206SBjoern A. Zeeb 11562774f206SBjoern A. Zeeb dm_info->delta_power_index[RF_PATH_A] = 11572774f206SBjoern A. Zeeb rtw_phy_pwrtrack_get_pwridx(rtwdev, &swing_table, RF_PATH_A, 11582774f206SBjoern A. Zeeb RF_PATH_A, delta); 11592774f206SBjoern A. Zeeb if (dm_info->delta_power_index[RF_PATH_A] == 11602774f206SBjoern A. Zeeb dm_info->delta_power_index_last[RF_PATH_A]) 11612774f206SBjoern A. Zeeb goto iqk; 11622774f206SBjoern A. Zeeb else 11632774f206SBjoern A. Zeeb dm_info->delta_power_index_last[RF_PATH_A] = 11642774f206SBjoern A. Zeeb dm_info->delta_power_index[RF_PATH_A]; 11652774f206SBjoern A. Zeeb rtw8821c_pwrtrack_set(rtwdev); 11662774f206SBjoern A. Zeeb 11672774f206SBjoern A. Zeeb iqk: 11682774f206SBjoern A. Zeeb if (rtw_phy_pwrtrack_need_iqk(rtwdev)) 11692774f206SBjoern A. Zeeb rtw8821c_do_iqk(rtwdev); 11702774f206SBjoern A. Zeeb } 11712774f206SBjoern A. Zeeb 11722774f206SBjoern A. Zeeb static void rtw8821c_pwr_track(struct rtw_dev *rtwdev) 11732774f206SBjoern A. Zeeb { 11742774f206SBjoern A. Zeeb struct rtw_efuse *efuse = &rtwdev->efuse; 11752774f206SBjoern A. Zeeb struct rtw_dm_info *dm_info = &rtwdev->dm_info; 11762774f206SBjoern A. Zeeb 11772774f206SBjoern A. Zeeb if (efuse->power_track_type != 0) 11782774f206SBjoern A. Zeeb return; 11792774f206SBjoern A. Zeeb 11802774f206SBjoern A. Zeeb if (!dm_info->pwr_trk_triggered) { 11812774f206SBjoern A. Zeeb rtw_write_rf(rtwdev, RF_PATH_A, RF_T_METER, 11822774f206SBjoern A. Zeeb GENMASK(17, 16), 0x03); 11832774f206SBjoern A. Zeeb dm_info->pwr_trk_triggered = true; 11842774f206SBjoern A. Zeeb return; 11852774f206SBjoern A. Zeeb } 11862774f206SBjoern A. Zeeb 11872774f206SBjoern A. Zeeb rtw8821c_phy_pwrtrack(rtwdev); 11882774f206SBjoern A. Zeeb dm_info->pwr_trk_triggered = false; 11892774f206SBjoern A. Zeeb } 11902774f206SBjoern A. Zeeb 11912774f206SBjoern A. Zeeb static void rtw8821c_bf_config_bfee_su(struct rtw_dev *rtwdev, 11922774f206SBjoern A. Zeeb struct rtw_vif *vif, 11932774f206SBjoern A. Zeeb struct rtw_bfee *bfee, bool enable) 11942774f206SBjoern A. Zeeb { 11952774f206SBjoern A. Zeeb if (enable) 11962774f206SBjoern A. Zeeb rtw_bf_enable_bfee_su(rtwdev, vif, bfee); 11972774f206SBjoern A. Zeeb else 11982774f206SBjoern A. Zeeb rtw_bf_remove_bfee_su(rtwdev, bfee); 11992774f206SBjoern A. Zeeb } 12002774f206SBjoern A. Zeeb 12012774f206SBjoern A. Zeeb static void rtw8821c_bf_config_bfee_mu(struct rtw_dev *rtwdev, 12022774f206SBjoern A. Zeeb struct rtw_vif *vif, 12032774f206SBjoern A. Zeeb struct rtw_bfee *bfee, bool enable) 12042774f206SBjoern A. Zeeb { 12052774f206SBjoern A. Zeeb if (enable) 12062774f206SBjoern A. Zeeb rtw_bf_enable_bfee_mu(rtwdev, vif, bfee); 12072774f206SBjoern A. Zeeb else 12082774f206SBjoern A. Zeeb rtw_bf_remove_bfee_mu(rtwdev, bfee); 12092774f206SBjoern A. Zeeb } 12102774f206SBjoern A. Zeeb 12112774f206SBjoern A. Zeeb static void rtw8821c_bf_config_bfee(struct rtw_dev *rtwdev, struct rtw_vif *vif, 12122774f206SBjoern A. Zeeb struct rtw_bfee *bfee, bool enable) 12132774f206SBjoern A. Zeeb { 12142774f206SBjoern A. Zeeb if (bfee->role == RTW_BFEE_SU) 12152774f206SBjoern A. Zeeb rtw8821c_bf_config_bfee_su(rtwdev, vif, bfee, enable); 12162774f206SBjoern A. Zeeb else if (bfee->role == RTW_BFEE_MU) 12172774f206SBjoern A. Zeeb rtw8821c_bf_config_bfee_mu(rtwdev, vif, bfee, enable); 12182774f206SBjoern A. Zeeb else 12192774f206SBjoern A. Zeeb rtw_warn(rtwdev, "wrong bfee role\n"); 12202774f206SBjoern A. Zeeb } 12212774f206SBjoern A. Zeeb 12222774f206SBjoern A. Zeeb static void rtw8821c_phy_cck_pd_set(struct rtw_dev *rtwdev, u8 new_lvl) 12232774f206SBjoern A. Zeeb { 12242774f206SBjoern A. Zeeb struct rtw_dm_info *dm_info = &rtwdev->dm_info; 12252774f206SBjoern A. Zeeb u8 pd[CCK_PD_LV_MAX] = {3, 7, 13, 13, 13}; 12262774f206SBjoern A. Zeeb u8 cck_n_rx; 12272774f206SBjoern A. Zeeb 12282774f206SBjoern A. Zeeb rtw_dbg(rtwdev, RTW_DBG_PHY, "lv: (%d) -> (%d)\n", 12292774f206SBjoern A. Zeeb dm_info->cck_pd_lv[RTW_CHANNEL_WIDTH_20][RF_PATH_A], new_lvl); 12302774f206SBjoern A. Zeeb 12312774f206SBjoern A. Zeeb if (dm_info->cck_pd_lv[RTW_CHANNEL_WIDTH_20][RF_PATH_A] == new_lvl) 12322774f206SBjoern A. Zeeb return; 12332774f206SBjoern A. Zeeb 12342774f206SBjoern A. Zeeb cck_n_rx = (rtw_read8_mask(rtwdev, REG_CCK0_FAREPORT, BIT_CCK0_2RX) && 12352774f206SBjoern A. Zeeb rtw_read8_mask(rtwdev, REG_CCK0_FAREPORT, BIT_CCK0_MRC)) ? 2 : 1; 12362774f206SBjoern A. Zeeb rtw_dbg(rtwdev, RTW_DBG_PHY, 12372774f206SBjoern A. Zeeb "is_linked=%d, lv=%d, n_rx=%d, cs_ratio=0x%x, pd_th=0x%x, cck_fa_avg=%d\n", 12382774f206SBjoern A. Zeeb rtw_is_assoc(rtwdev), new_lvl, cck_n_rx, 12392774f206SBjoern A. Zeeb dm_info->cck_pd_default + new_lvl * 2, 12402774f206SBjoern A. Zeeb pd[new_lvl], dm_info->cck_fa_avg); 12412774f206SBjoern A. Zeeb 12422774f206SBjoern A. Zeeb dm_info->cck_fa_avg = CCK_FA_AVG_RESET; 12432774f206SBjoern A. Zeeb 12442774f206SBjoern A. Zeeb dm_info->cck_pd_lv[RTW_CHANNEL_WIDTH_20][RF_PATH_A] = new_lvl; 12452774f206SBjoern A. Zeeb rtw_write32_mask(rtwdev, REG_PWRTH, 0x3f0000, pd[new_lvl]); 12462774f206SBjoern A. Zeeb rtw_write32_mask(rtwdev, REG_PWRTH2, 0x1f0000, 12472774f206SBjoern A. Zeeb dm_info->cck_pd_default + new_lvl * 2); 12482774f206SBjoern A. Zeeb } 12492774f206SBjoern A. Zeeb 125090aac0d8SBjoern A. Zeeb static void rtw8821c_fill_txdesc_checksum(struct rtw_dev *rtwdev, 125190aac0d8SBjoern A. Zeeb struct rtw_tx_pkt_info *pkt_info, 125290aac0d8SBjoern A. Zeeb u8 *txdesc) 125390aac0d8SBjoern A. Zeeb { 125490aac0d8SBjoern A. Zeeb fill_txdesc_checksum_common(txdesc, 16); 125590aac0d8SBjoern A. Zeeb } 125690aac0d8SBjoern A. Zeeb 12572774f206SBjoern A. Zeeb static struct rtw_pwr_seq_cmd trans_carddis_to_cardemu_8821c[] = { 12582774f206SBjoern A. Zeeb {0x0086, 12592774f206SBjoern A. Zeeb RTW_PWR_CUT_ALL_MSK, 12602774f206SBjoern A. Zeeb RTW_PWR_INTF_SDIO_MSK, 12612774f206SBjoern A. Zeeb RTW_PWR_ADDR_SDIO, 12622774f206SBjoern A. Zeeb RTW_PWR_CMD_WRITE, BIT(0), 0}, 12632774f206SBjoern A. Zeeb {0x0086, 12642774f206SBjoern A. Zeeb RTW_PWR_CUT_ALL_MSK, 12652774f206SBjoern A. Zeeb RTW_PWR_INTF_SDIO_MSK, 12662774f206SBjoern A. Zeeb RTW_PWR_ADDR_SDIO, 12672774f206SBjoern A. Zeeb RTW_PWR_CMD_POLLING, BIT(1), BIT(1)}, 12682774f206SBjoern A. Zeeb {0x004A, 12692774f206SBjoern A. Zeeb RTW_PWR_CUT_ALL_MSK, 12702774f206SBjoern A. Zeeb RTW_PWR_INTF_USB_MSK, 12712774f206SBjoern A. Zeeb RTW_PWR_ADDR_MAC, 12722774f206SBjoern A. Zeeb RTW_PWR_CMD_WRITE, BIT(0), 0}, 12732774f206SBjoern A. Zeeb {0x0005, 12742774f206SBjoern A. Zeeb RTW_PWR_CUT_ALL_MSK, 12752774f206SBjoern A. Zeeb RTW_PWR_INTF_ALL_MSK, 12762774f206SBjoern A. Zeeb RTW_PWR_ADDR_MAC, 12772774f206SBjoern A. Zeeb RTW_PWR_CMD_WRITE, BIT(3) | BIT(4) | BIT(7), 0}, 12782774f206SBjoern A. Zeeb {0x0300, 12792774f206SBjoern A. Zeeb RTW_PWR_CUT_ALL_MSK, 12802774f206SBjoern A. Zeeb RTW_PWR_INTF_PCI_MSK, 12812774f206SBjoern A. Zeeb RTW_PWR_ADDR_MAC, 12822774f206SBjoern A. Zeeb RTW_PWR_CMD_WRITE, 0xFF, 0}, 12832774f206SBjoern A. Zeeb {0x0301, 12842774f206SBjoern A. Zeeb RTW_PWR_CUT_ALL_MSK, 12852774f206SBjoern A. Zeeb RTW_PWR_INTF_PCI_MSK, 12862774f206SBjoern A. Zeeb RTW_PWR_ADDR_MAC, 12872774f206SBjoern A. Zeeb RTW_PWR_CMD_WRITE, 0xFF, 0}, 12882774f206SBjoern A. Zeeb {0xFFFF, 12892774f206SBjoern A. Zeeb RTW_PWR_CUT_ALL_MSK, 12902774f206SBjoern A. Zeeb RTW_PWR_INTF_ALL_MSK, 12912774f206SBjoern A. Zeeb 0, 12922774f206SBjoern A. Zeeb RTW_PWR_CMD_END, 0, 0}, 12932774f206SBjoern A. Zeeb }; 12942774f206SBjoern A. Zeeb 12952774f206SBjoern A. Zeeb static struct rtw_pwr_seq_cmd trans_cardemu_to_act_8821c[] = { 12962774f206SBjoern A. Zeeb {0x0020, 12972774f206SBjoern A. Zeeb RTW_PWR_CUT_ALL_MSK, 12982774f206SBjoern A. Zeeb RTW_PWR_INTF_USB_MSK | RTW_PWR_INTF_SDIO_MSK, 12992774f206SBjoern A. Zeeb RTW_PWR_ADDR_MAC, 13002774f206SBjoern A. Zeeb RTW_PWR_CMD_WRITE, BIT(0), BIT(0)}, 13012774f206SBjoern A. Zeeb {0x0001, 13022774f206SBjoern A. Zeeb RTW_PWR_CUT_ALL_MSK, 13032774f206SBjoern A. Zeeb RTW_PWR_INTF_USB_MSK | RTW_PWR_INTF_SDIO_MSK, 13042774f206SBjoern A. Zeeb RTW_PWR_ADDR_MAC, 13052774f206SBjoern A. Zeeb RTW_PWR_CMD_DELAY, 1, RTW_PWR_DELAY_MS}, 13062774f206SBjoern A. Zeeb {0x0000, 13072774f206SBjoern A. Zeeb RTW_PWR_CUT_ALL_MSK, 13082774f206SBjoern A. Zeeb RTW_PWR_INTF_USB_MSK | RTW_PWR_INTF_SDIO_MSK, 13092774f206SBjoern A. Zeeb RTW_PWR_ADDR_MAC, 13102774f206SBjoern A. Zeeb RTW_PWR_CMD_WRITE, BIT(5), 0}, 13112774f206SBjoern A. Zeeb {0x0005, 13122774f206SBjoern A. Zeeb RTW_PWR_CUT_ALL_MSK, 13132774f206SBjoern A. Zeeb RTW_PWR_INTF_ALL_MSK, 13142774f206SBjoern A. Zeeb RTW_PWR_ADDR_MAC, 13152774f206SBjoern A. Zeeb RTW_PWR_CMD_WRITE, (BIT(4) | BIT(3) | BIT(2)), 0}, 13162774f206SBjoern A. Zeeb {0x0075, 13172774f206SBjoern A. Zeeb RTW_PWR_CUT_ALL_MSK, 13182774f206SBjoern A. Zeeb RTW_PWR_INTF_PCI_MSK, 13192774f206SBjoern A. Zeeb RTW_PWR_ADDR_MAC, 13202774f206SBjoern A. Zeeb RTW_PWR_CMD_WRITE, BIT(0), BIT(0)}, 13212774f206SBjoern A. Zeeb {0x0006, 13222774f206SBjoern A. Zeeb RTW_PWR_CUT_ALL_MSK, 13232774f206SBjoern A. Zeeb RTW_PWR_INTF_ALL_MSK, 13242774f206SBjoern A. Zeeb RTW_PWR_ADDR_MAC, 13252774f206SBjoern A. Zeeb RTW_PWR_CMD_POLLING, BIT(1), BIT(1)}, 13262774f206SBjoern A. Zeeb {0x0075, 13272774f206SBjoern A. Zeeb RTW_PWR_CUT_ALL_MSK, 13282774f206SBjoern A. Zeeb RTW_PWR_INTF_PCI_MSK, 13292774f206SBjoern A. Zeeb RTW_PWR_ADDR_MAC, 13302774f206SBjoern A. Zeeb RTW_PWR_CMD_WRITE, BIT(0), 0}, 13312774f206SBjoern A. Zeeb {0x0006, 13322774f206SBjoern A. Zeeb RTW_PWR_CUT_ALL_MSK, 13332774f206SBjoern A. Zeeb RTW_PWR_INTF_ALL_MSK, 13342774f206SBjoern A. Zeeb RTW_PWR_ADDR_MAC, 13352774f206SBjoern A. Zeeb RTW_PWR_CMD_WRITE, BIT(0), BIT(0)}, 13362774f206SBjoern A. Zeeb {0x0005, 13372774f206SBjoern A. Zeeb RTW_PWR_CUT_ALL_MSK, 13382774f206SBjoern A. Zeeb RTW_PWR_INTF_ALL_MSK, 13392774f206SBjoern A. Zeeb RTW_PWR_ADDR_MAC, 13402774f206SBjoern A. Zeeb RTW_PWR_CMD_WRITE, BIT(7), 0}, 13412774f206SBjoern A. Zeeb {0x0005, 13422774f206SBjoern A. Zeeb RTW_PWR_CUT_ALL_MSK, 13432774f206SBjoern A. Zeeb RTW_PWR_INTF_ALL_MSK, 13442774f206SBjoern A. Zeeb RTW_PWR_ADDR_MAC, 13452774f206SBjoern A. Zeeb RTW_PWR_CMD_WRITE, (BIT(4) | BIT(3)), 0}, 13462774f206SBjoern A. Zeeb {0x10C3, 13472774f206SBjoern A. Zeeb RTW_PWR_CUT_ALL_MSK, 13482774f206SBjoern A. Zeeb RTW_PWR_INTF_USB_MSK, 13492774f206SBjoern A. Zeeb RTW_PWR_ADDR_MAC, 13502774f206SBjoern A. Zeeb RTW_PWR_CMD_WRITE, BIT(0), BIT(0)}, 13512774f206SBjoern A. Zeeb {0x0005, 13522774f206SBjoern A. Zeeb RTW_PWR_CUT_ALL_MSK, 13532774f206SBjoern A. Zeeb RTW_PWR_INTF_ALL_MSK, 13542774f206SBjoern A. Zeeb RTW_PWR_ADDR_MAC, 13552774f206SBjoern A. Zeeb RTW_PWR_CMD_WRITE, BIT(0), BIT(0)}, 13562774f206SBjoern A. Zeeb {0x0005, 13572774f206SBjoern A. Zeeb RTW_PWR_CUT_ALL_MSK, 13582774f206SBjoern A. Zeeb RTW_PWR_INTF_ALL_MSK, 13592774f206SBjoern A. Zeeb RTW_PWR_ADDR_MAC, 13602774f206SBjoern A. Zeeb RTW_PWR_CMD_POLLING, BIT(0), 0}, 13612774f206SBjoern A. Zeeb {0x0020, 13622774f206SBjoern A. Zeeb RTW_PWR_CUT_ALL_MSK, 13632774f206SBjoern A. Zeeb RTW_PWR_INTF_ALL_MSK, 13642774f206SBjoern A. Zeeb RTW_PWR_ADDR_MAC, 13652774f206SBjoern A. Zeeb RTW_PWR_CMD_WRITE, BIT(3), BIT(3)}, 13662774f206SBjoern A. Zeeb {0x0074, 13672774f206SBjoern A. Zeeb RTW_PWR_CUT_ALL_MSK, 13682774f206SBjoern A. Zeeb RTW_PWR_INTF_PCI_MSK, 13692774f206SBjoern A. Zeeb RTW_PWR_ADDR_MAC, 13702774f206SBjoern A. Zeeb RTW_PWR_CMD_WRITE, BIT(5), BIT(5)}, 13712774f206SBjoern A. Zeeb {0x0022, 13722774f206SBjoern A. Zeeb RTW_PWR_CUT_ALL_MSK, 13732774f206SBjoern A. Zeeb RTW_PWR_INTF_PCI_MSK, 13742774f206SBjoern A. Zeeb RTW_PWR_ADDR_MAC, 13752774f206SBjoern A. Zeeb RTW_PWR_CMD_WRITE, BIT(1), 0}, 13762774f206SBjoern A. Zeeb {0x0062, 13772774f206SBjoern A. Zeeb RTW_PWR_CUT_ALL_MSK, 13782774f206SBjoern A. Zeeb RTW_PWR_INTF_PCI_MSK, 13792774f206SBjoern A. Zeeb RTW_PWR_ADDR_MAC, 13802774f206SBjoern A. Zeeb RTW_PWR_CMD_WRITE, (BIT(7) | BIT(6) | BIT(5)), 13812774f206SBjoern A. Zeeb (BIT(7) | BIT(6) | BIT(5))}, 13822774f206SBjoern A. Zeeb {0x0061, 13832774f206SBjoern A. Zeeb RTW_PWR_CUT_ALL_MSK, 13842774f206SBjoern A. Zeeb RTW_PWR_INTF_PCI_MSK, 13852774f206SBjoern A. Zeeb RTW_PWR_ADDR_MAC, 13862774f206SBjoern A. Zeeb RTW_PWR_CMD_WRITE, (BIT(7) | BIT(6) | BIT(5)), 0}, 13872774f206SBjoern A. Zeeb {0x007C, 13882774f206SBjoern A. Zeeb RTW_PWR_CUT_ALL_MSK, 13892774f206SBjoern A. Zeeb RTW_PWR_INTF_ALL_MSK, 13902774f206SBjoern A. Zeeb RTW_PWR_ADDR_MAC, 13912774f206SBjoern A. Zeeb RTW_PWR_CMD_WRITE, BIT(1), 0}, 13922774f206SBjoern A. Zeeb {0xFFFF, 13932774f206SBjoern A. Zeeb RTW_PWR_CUT_ALL_MSK, 13942774f206SBjoern A. Zeeb RTW_PWR_INTF_ALL_MSK, 13952774f206SBjoern A. Zeeb 0, 13962774f206SBjoern A. Zeeb RTW_PWR_CMD_END, 0, 0}, 13972774f206SBjoern A. Zeeb }; 13982774f206SBjoern A. Zeeb 13992774f206SBjoern A. Zeeb static struct rtw_pwr_seq_cmd trans_act_to_cardemu_8821c[] = { 14002774f206SBjoern A. Zeeb {0x0093, 14012774f206SBjoern A. Zeeb RTW_PWR_CUT_ALL_MSK, 14022774f206SBjoern A. Zeeb RTW_PWR_INTF_ALL_MSK, 14032774f206SBjoern A. Zeeb RTW_PWR_ADDR_MAC, 14042774f206SBjoern A. Zeeb RTW_PWR_CMD_WRITE, BIT(3), 0}, 14052774f206SBjoern A. Zeeb {0x001F, 14062774f206SBjoern A. Zeeb RTW_PWR_CUT_ALL_MSK, 14072774f206SBjoern A. Zeeb RTW_PWR_INTF_ALL_MSK, 14082774f206SBjoern A. Zeeb RTW_PWR_ADDR_MAC, 14092774f206SBjoern A. Zeeb RTW_PWR_CMD_WRITE, 0xFF, 0}, 14102774f206SBjoern A. Zeeb {0x0049, 14112774f206SBjoern A. Zeeb RTW_PWR_CUT_ALL_MSK, 14122774f206SBjoern A. Zeeb RTW_PWR_INTF_ALL_MSK, 14132774f206SBjoern A. Zeeb RTW_PWR_ADDR_MAC, 14142774f206SBjoern A. Zeeb RTW_PWR_CMD_WRITE, BIT(1), 0}, 14152774f206SBjoern A. Zeeb {0x0006, 14162774f206SBjoern A. Zeeb RTW_PWR_CUT_ALL_MSK, 14172774f206SBjoern A. Zeeb RTW_PWR_INTF_ALL_MSK, 14182774f206SBjoern A. Zeeb RTW_PWR_ADDR_MAC, 14192774f206SBjoern A. Zeeb RTW_PWR_CMD_WRITE, BIT(0), BIT(0)}, 14202774f206SBjoern A. Zeeb {0x0002, 14212774f206SBjoern A. Zeeb RTW_PWR_CUT_ALL_MSK, 14222774f206SBjoern A. Zeeb RTW_PWR_INTF_ALL_MSK, 14232774f206SBjoern A. Zeeb RTW_PWR_ADDR_MAC, 14242774f206SBjoern A. Zeeb RTW_PWR_CMD_WRITE, BIT(1), 0}, 14252774f206SBjoern A. Zeeb {0x10C3, 14262774f206SBjoern A. Zeeb RTW_PWR_CUT_ALL_MSK, 14272774f206SBjoern A. Zeeb RTW_PWR_INTF_USB_MSK, 14282774f206SBjoern A. Zeeb RTW_PWR_ADDR_MAC, 14292774f206SBjoern A. Zeeb RTW_PWR_CMD_WRITE, BIT(0), 0}, 14302774f206SBjoern A. Zeeb {0x0005, 14312774f206SBjoern A. Zeeb RTW_PWR_CUT_ALL_MSK, 14322774f206SBjoern A. Zeeb RTW_PWR_INTF_ALL_MSK, 14332774f206SBjoern A. Zeeb RTW_PWR_ADDR_MAC, 14342774f206SBjoern A. Zeeb RTW_PWR_CMD_WRITE, BIT(1), BIT(1)}, 14352774f206SBjoern A. Zeeb {0x0005, 14362774f206SBjoern A. Zeeb RTW_PWR_CUT_ALL_MSK, 14372774f206SBjoern A. Zeeb RTW_PWR_INTF_ALL_MSK, 14382774f206SBjoern A. Zeeb RTW_PWR_ADDR_MAC, 14392774f206SBjoern A. Zeeb RTW_PWR_CMD_POLLING, BIT(1), 0}, 14402774f206SBjoern A. Zeeb {0x0020, 14412774f206SBjoern A. Zeeb RTW_PWR_CUT_ALL_MSK, 14422774f206SBjoern A. Zeeb RTW_PWR_INTF_ALL_MSK, 14432774f206SBjoern A. Zeeb RTW_PWR_ADDR_MAC, 14442774f206SBjoern A. Zeeb RTW_PWR_CMD_WRITE, BIT(3), 0}, 14452774f206SBjoern A. Zeeb {0x0000, 14462774f206SBjoern A. Zeeb RTW_PWR_CUT_ALL_MSK, 14472774f206SBjoern A. Zeeb RTW_PWR_INTF_USB_MSK | RTW_PWR_INTF_SDIO_MSK, 14482774f206SBjoern A. Zeeb RTW_PWR_ADDR_MAC, 14492774f206SBjoern A. Zeeb RTW_PWR_CMD_WRITE, BIT(5), BIT(5)}, 14502774f206SBjoern A. Zeeb {0xFFFF, 14512774f206SBjoern A. Zeeb RTW_PWR_CUT_ALL_MSK, 14522774f206SBjoern A. Zeeb RTW_PWR_INTF_ALL_MSK, 14532774f206SBjoern A. Zeeb 0, 14542774f206SBjoern A. Zeeb RTW_PWR_CMD_END, 0, 0}, 14552774f206SBjoern A. Zeeb }; 14562774f206SBjoern A. Zeeb 14572774f206SBjoern A. Zeeb static struct rtw_pwr_seq_cmd trans_cardemu_to_carddis_8821c[] = { 14582774f206SBjoern A. Zeeb {0x0007, 14592774f206SBjoern A. Zeeb RTW_PWR_CUT_ALL_MSK, 14602774f206SBjoern A. Zeeb RTW_PWR_INTF_USB_MSK | RTW_PWR_INTF_SDIO_MSK, 14612774f206SBjoern A. Zeeb RTW_PWR_ADDR_MAC, 14622774f206SBjoern A. Zeeb RTW_PWR_CMD_WRITE, 0xFF, 0x20}, 14632774f206SBjoern A. Zeeb {0x0067, 14642774f206SBjoern A. Zeeb RTW_PWR_CUT_ALL_MSK, 14652774f206SBjoern A. Zeeb RTW_PWR_INTF_ALL_MSK, 14662774f206SBjoern A. Zeeb RTW_PWR_ADDR_MAC, 14672774f206SBjoern A. Zeeb RTW_PWR_CMD_WRITE, BIT(5), 0}, 14682774f206SBjoern A. Zeeb {0x0005, 14692774f206SBjoern A. Zeeb RTW_PWR_CUT_ALL_MSK, 14702774f206SBjoern A. Zeeb RTW_PWR_INTF_PCI_MSK, 14712774f206SBjoern A. Zeeb RTW_PWR_ADDR_MAC, 14722774f206SBjoern A. Zeeb RTW_PWR_CMD_WRITE, BIT(2), BIT(2)}, 14732774f206SBjoern A. Zeeb {0x004A, 14742774f206SBjoern A. Zeeb RTW_PWR_CUT_ALL_MSK, 14752774f206SBjoern A. Zeeb RTW_PWR_INTF_USB_MSK, 14762774f206SBjoern A. Zeeb RTW_PWR_ADDR_MAC, 14772774f206SBjoern A. Zeeb RTW_PWR_CMD_WRITE, BIT(0), 0}, 14782774f206SBjoern A. Zeeb {0x0067, 14792774f206SBjoern A. Zeeb RTW_PWR_CUT_ALL_MSK, 14802774f206SBjoern A. Zeeb RTW_PWR_INTF_SDIO_MSK, 14812774f206SBjoern A. Zeeb RTW_PWR_ADDR_MAC, 14822774f206SBjoern A. Zeeb RTW_PWR_CMD_WRITE, BIT(5), 0}, 14832774f206SBjoern A. Zeeb {0x0067, 14842774f206SBjoern A. Zeeb RTW_PWR_CUT_ALL_MSK, 14852774f206SBjoern A. Zeeb RTW_PWR_INTF_SDIO_MSK, 14862774f206SBjoern A. Zeeb RTW_PWR_ADDR_MAC, 14872774f206SBjoern A. Zeeb RTW_PWR_CMD_WRITE, BIT(4), 0}, 14882774f206SBjoern A. Zeeb {0x004F, 14892774f206SBjoern A. Zeeb RTW_PWR_CUT_ALL_MSK, 14902774f206SBjoern A. Zeeb RTW_PWR_INTF_SDIO_MSK, 14912774f206SBjoern A. Zeeb RTW_PWR_ADDR_MAC, 14922774f206SBjoern A. Zeeb RTW_PWR_CMD_WRITE, BIT(0), 0}, 14932774f206SBjoern A. Zeeb {0x0067, 14942774f206SBjoern A. Zeeb RTW_PWR_CUT_ALL_MSK, 14952774f206SBjoern A. Zeeb RTW_PWR_INTF_SDIO_MSK, 14962774f206SBjoern A. Zeeb RTW_PWR_ADDR_MAC, 14972774f206SBjoern A. Zeeb RTW_PWR_CMD_WRITE, BIT(1), 0}, 14982774f206SBjoern A. Zeeb {0x0046, 14992774f206SBjoern A. Zeeb RTW_PWR_CUT_ALL_MSK, 15002774f206SBjoern A. Zeeb RTW_PWR_INTF_SDIO_MSK, 15012774f206SBjoern A. Zeeb RTW_PWR_ADDR_MAC, 15022774f206SBjoern A. Zeeb RTW_PWR_CMD_WRITE, BIT(6), BIT(6)}, 15032774f206SBjoern A. Zeeb {0x0067, 15042774f206SBjoern A. Zeeb RTW_PWR_CUT_ALL_MSK, 15052774f206SBjoern A. Zeeb RTW_PWR_INTF_SDIO_MSK, 15062774f206SBjoern A. Zeeb RTW_PWR_ADDR_MAC, 15072774f206SBjoern A. Zeeb RTW_PWR_CMD_WRITE, BIT(2), 0}, 15082774f206SBjoern A. Zeeb {0x0046, 15092774f206SBjoern A. Zeeb RTW_PWR_CUT_ALL_MSK, 15102774f206SBjoern A. Zeeb RTW_PWR_INTF_SDIO_MSK, 15112774f206SBjoern A. Zeeb RTW_PWR_ADDR_MAC, 15122774f206SBjoern A. Zeeb RTW_PWR_CMD_WRITE, BIT(7), BIT(7)}, 15132774f206SBjoern A. Zeeb {0x0062, 15142774f206SBjoern A. Zeeb RTW_PWR_CUT_ALL_MSK, 15152774f206SBjoern A. Zeeb RTW_PWR_INTF_SDIO_MSK, 15162774f206SBjoern A. Zeeb RTW_PWR_ADDR_MAC, 15172774f206SBjoern A. Zeeb RTW_PWR_CMD_WRITE, BIT(4), BIT(4)}, 15182774f206SBjoern A. Zeeb {0x0081, 15192774f206SBjoern A. Zeeb RTW_PWR_CUT_ALL_MSK, 15202774f206SBjoern A. Zeeb RTW_PWR_INTF_ALL_MSK, 15212774f206SBjoern A. Zeeb RTW_PWR_ADDR_MAC, 15222774f206SBjoern A. Zeeb RTW_PWR_CMD_WRITE, BIT(7) | BIT(6), 0}, 15232774f206SBjoern A. Zeeb {0x0005, 15242774f206SBjoern A. Zeeb RTW_PWR_CUT_ALL_MSK, 15252774f206SBjoern A. Zeeb RTW_PWR_INTF_USB_MSK | RTW_PWR_INTF_SDIO_MSK, 15262774f206SBjoern A. Zeeb RTW_PWR_ADDR_MAC, 15272774f206SBjoern A. Zeeb RTW_PWR_CMD_WRITE, BIT(3) | BIT(4), BIT(3)}, 15282774f206SBjoern A. Zeeb {0x0086, 15292774f206SBjoern A. Zeeb RTW_PWR_CUT_ALL_MSK, 15302774f206SBjoern A. Zeeb RTW_PWR_INTF_SDIO_MSK, 15312774f206SBjoern A. Zeeb RTW_PWR_ADDR_SDIO, 15322774f206SBjoern A. Zeeb RTW_PWR_CMD_WRITE, BIT(0), BIT(0)}, 15332774f206SBjoern A. Zeeb {0x0086, 15342774f206SBjoern A. Zeeb RTW_PWR_CUT_ALL_MSK, 15352774f206SBjoern A. Zeeb RTW_PWR_INTF_SDIO_MSK, 15362774f206SBjoern A. Zeeb RTW_PWR_ADDR_SDIO, 15372774f206SBjoern A. Zeeb RTW_PWR_CMD_POLLING, BIT(1), 0}, 15382774f206SBjoern A. Zeeb {0x0090, 15392774f206SBjoern A. Zeeb RTW_PWR_CUT_ALL_MSK, 15402774f206SBjoern A. Zeeb RTW_PWR_INTF_USB_MSK | RTW_PWR_INTF_PCI_MSK, 15412774f206SBjoern A. Zeeb RTW_PWR_ADDR_MAC, 15422774f206SBjoern A. Zeeb RTW_PWR_CMD_WRITE, BIT(1), 0}, 15432774f206SBjoern A. Zeeb {0x0044, 15442774f206SBjoern A. Zeeb RTW_PWR_CUT_ALL_MSK, 15452774f206SBjoern A. Zeeb RTW_PWR_INTF_SDIO_MSK, 15462774f206SBjoern A. Zeeb RTW_PWR_ADDR_SDIO, 15472774f206SBjoern A. Zeeb RTW_PWR_CMD_WRITE, 0xFF, 0}, 15482774f206SBjoern A. Zeeb {0x0040, 15492774f206SBjoern A. Zeeb RTW_PWR_CUT_ALL_MSK, 15502774f206SBjoern A. Zeeb RTW_PWR_INTF_SDIO_MSK, 15512774f206SBjoern A. Zeeb RTW_PWR_ADDR_SDIO, 15522774f206SBjoern A. Zeeb RTW_PWR_CMD_WRITE, 0xFF, 0x90}, 15532774f206SBjoern A. Zeeb {0x0041, 15542774f206SBjoern A. Zeeb RTW_PWR_CUT_ALL_MSK, 15552774f206SBjoern A. Zeeb RTW_PWR_INTF_SDIO_MSK, 15562774f206SBjoern A. Zeeb RTW_PWR_ADDR_SDIO, 15572774f206SBjoern A. Zeeb RTW_PWR_CMD_WRITE, 0xFF, 0x00}, 15582774f206SBjoern A. Zeeb {0x0042, 15592774f206SBjoern A. Zeeb RTW_PWR_CUT_ALL_MSK, 15602774f206SBjoern A. Zeeb RTW_PWR_INTF_SDIO_MSK, 15612774f206SBjoern A. Zeeb RTW_PWR_ADDR_SDIO, 15622774f206SBjoern A. Zeeb RTW_PWR_CMD_WRITE, 0xFF, 0x04}, 15632774f206SBjoern A. Zeeb {0xFFFF, 15642774f206SBjoern A. Zeeb RTW_PWR_CUT_ALL_MSK, 15652774f206SBjoern A. Zeeb RTW_PWR_INTF_ALL_MSK, 15662774f206SBjoern A. Zeeb 0, 15672774f206SBjoern A. Zeeb RTW_PWR_CMD_END, 0, 0}, 15682774f206SBjoern A. Zeeb }; 15692774f206SBjoern A. Zeeb 15702774f206SBjoern A. Zeeb static const struct rtw_pwr_seq_cmd *card_enable_flow_8821c[] = { 15712774f206SBjoern A. Zeeb trans_carddis_to_cardemu_8821c, 15722774f206SBjoern A. Zeeb trans_cardemu_to_act_8821c, 15732774f206SBjoern A. Zeeb NULL 15742774f206SBjoern A. Zeeb }; 15752774f206SBjoern A. Zeeb 15762774f206SBjoern A. Zeeb static const struct rtw_pwr_seq_cmd *card_disable_flow_8821c[] = { 15772774f206SBjoern A. Zeeb trans_act_to_cardemu_8821c, 15782774f206SBjoern A. Zeeb trans_cardemu_to_carddis_8821c, 15792774f206SBjoern A. Zeeb NULL 15802774f206SBjoern A. Zeeb }; 15812774f206SBjoern A. Zeeb 15822774f206SBjoern A. Zeeb static const struct rtw_intf_phy_para usb2_param_8821c[] = { 15832774f206SBjoern A. Zeeb {0xFFFF, 0x00, 15842774f206SBjoern A. Zeeb RTW_IP_SEL_PHY, 15852774f206SBjoern A. Zeeb RTW_INTF_PHY_CUT_ALL, 15862774f206SBjoern A. Zeeb RTW_INTF_PHY_PLATFORM_ALL}, 15872774f206SBjoern A. Zeeb }; 15882774f206SBjoern A. Zeeb 15892774f206SBjoern A. Zeeb static const struct rtw_intf_phy_para usb3_param_8821c[] = { 15902774f206SBjoern A. Zeeb {0xFFFF, 0x0000, 15912774f206SBjoern A. Zeeb RTW_IP_SEL_PHY, 15922774f206SBjoern A. Zeeb RTW_INTF_PHY_CUT_ALL, 15932774f206SBjoern A. Zeeb RTW_INTF_PHY_PLATFORM_ALL}, 15942774f206SBjoern A. Zeeb }; 15952774f206SBjoern A. Zeeb 15962774f206SBjoern A. Zeeb static const struct rtw_intf_phy_para pcie_gen1_param_8821c[] = { 15972774f206SBjoern A. Zeeb {0x0009, 0x6380, 15982774f206SBjoern A. Zeeb RTW_IP_SEL_PHY, 15992774f206SBjoern A. Zeeb RTW_INTF_PHY_CUT_ALL, 16002774f206SBjoern A. Zeeb RTW_INTF_PHY_PLATFORM_ALL}, 16012774f206SBjoern A. Zeeb {0xFFFF, 0x0000, 16022774f206SBjoern A. Zeeb RTW_IP_SEL_PHY, 16032774f206SBjoern A. Zeeb RTW_INTF_PHY_CUT_ALL, 16042774f206SBjoern A. Zeeb RTW_INTF_PHY_PLATFORM_ALL}, 16052774f206SBjoern A. Zeeb }; 16062774f206SBjoern A. Zeeb 16072774f206SBjoern A. Zeeb static const struct rtw_intf_phy_para pcie_gen2_param_8821c[] = { 16082774f206SBjoern A. Zeeb {0xFFFF, 0x0000, 16092774f206SBjoern A. Zeeb RTW_IP_SEL_PHY, 16102774f206SBjoern A. Zeeb RTW_INTF_PHY_CUT_ALL, 16112774f206SBjoern A. Zeeb RTW_INTF_PHY_PLATFORM_ALL}, 16122774f206SBjoern A. Zeeb }; 16132774f206SBjoern A. Zeeb 16142774f206SBjoern A. Zeeb static const struct rtw_intf_phy_para_table phy_para_table_8821c = { 16152774f206SBjoern A. Zeeb .usb2_para = usb2_param_8821c, 16162774f206SBjoern A. Zeeb .usb3_para = usb3_param_8821c, 16172774f206SBjoern A. Zeeb .gen1_para = pcie_gen1_param_8821c, 16182774f206SBjoern A. Zeeb .gen2_para = pcie_gen2_param_8821c, 16192774f206SBjoern A. Zeeb .n_usb2_para = ARRAY_SIZE(usb2_param_8821c), 16202774f206SBjoern A. Zeeb .n_usb3_para = ARRAY_SIZE(usb2_param_8821c), 16212774f206SBjoern A. Zeeb .n_gen1_para = ARRAY_SIZE(pcie_gen1_param_8821c), 16222774f206SBjoern A. Zeeb .n_gen2_para = ARRAY_SIZE(pcie_gen2_param_8821c), 16232774f206SBjoern A. Zeeb }; 16242774f206SBjoern A. Zeeb 16252774f206SBjoern A. Zeeb static const struct rtw_rfe_def rtw8821c_rfe_defs[] = { 16262774f206SBjoern A. Zeeb [0] = RTW_DEF_RFE(8821c, 0, 0), 16272774f206SBjoern A. Zeeb [2] = RTW_DEF_RFE_EXT(8821c, 0, 0, 2), 16282774f206SBjoern A. Zeeb [4] = RTW_DEF_RFE_EXT(8821c, 0, 0, 2), 16299c951734SBjoern A. Zeeb [6] = RTW_DEF_RFE(8821c, 0, 0), 16302774f206SBjoern A. Zeeb }; 16312774f206SBjoern A. Zeeb 16322774f206SBjoern A. Zeeb static struct rtw_hw_reg rtw8821c_dig[] = { 16332774f206SBjoern A. Zeeb [0] = { .addr = 0xc50, .mask = 0x7f }, 16342774f206SBjoern A. Zeeb }; 16352774f206SBjoern A. Zeeb 16362774f206SBjoern A. Zeeb static const struct rtw_ltecoex_addr rtw8821c_ltecoex_addr = { 16372774f206SBjoern A. Zeeb .ctrl = LTECOEX_ACCESS_CTRL, 16382774f206SBjoern A. Zeeb .wdata = LTECOEX_WRITE_DATA, 16392774f206SBjoern A. Zeeb .rdata = LTECOEX_READ_DATA, 16402774f206SBjoern A. Zeeb }; 16412774f206SBjoern A. Zeeb 16422774f206SBjoern A. Zeeb static struct rtw_page_table page_table_8821c[] = { 16432774f206SBjoern A. Zeeb /* not sure what [0] stands for */ 16442774f206SBjoern A. Zeeb {16, 16, 16, 14, 1}, 16452774f206SBjoern A. Zeeb {16, 16, 16, 14, 1}, 16462774f206SBjoern A. Zeeb {16, 16, 0, 0, 1}, 16472774f206SBjoern A. Zeeb {16, 16, 16, 0, 1}, 16482774f206SBjoern A. Zeeb {16, 16, 16, 14, 1}, 16492774f206SBjoern A. Zeeb }; 16502774f206SBjoern A. Zeeb 16512774f206SBjoern A. Zeeb static struct rtw_rqpn rqpn_table_8821c[] = { 16522774f206SBjoern A. Zeeb /* not sure what [0] stands for */ 16532774f206SBjoern A. Zeeb {RTW_DMA_MAPPING_NORMAL, RTW_DMA_MAPPING_NORMAL, 16542774f206SBjoern A. Zeeb RTW_DMA_MAPPING_LOW, RTW_DMA_MAPPING_LOW, 16552774f206SBjoern A. Zeeb RTW_DMA_MAPPING_EXTRA, RTW_DMA_MAPPING_HIGH}, 16562774f206SBjoern A. Zeeb {RTW_DMA_MAPPING_NORMAL, RTW_DMA_MAPPING_NORMAL, 16572774f206SBjoern A. Zeeb RTW_DMA_MAPPING_LOW, RTW_DMA_MAPPING_LOW, 16582774f206SBjoern A. Zeeb RTW_DMA_MAPPING_EXTRA, RTW_DMA_MAPPING_HIGH}, 16592774f206SBjoern A. Zeeb {RTW_DMA_MAPPING_NORMAL, RTW_DMA_MAPPING_NORMAL, 16602774f206SBjoern A. Zeeb RTW_DMA_MAPPING_NORMAL, RTW_DMA_MAPPING_HIGH, 16612774f206SBjoern A. Zeeb RTW_DMA_MAPPING_HIGH, RTW_DMA_MAPPING_HIGH}, 16622774f206SBjoern A. Zeeb {RTW_DMA_MAPPING_NORMAL, RTW_DMA_MAPPING_NORMAL, 16632774f206SBjoern A. Zeeb RTW_DMA_MAPPING_LOW, RTW_DMA_MAPPING_LOW, 16642774f206SBjoern A. Zeeb RTW_DMA_MAPPING_HIGH, RTW_DMA_MAPPING_HIGH}, 16652774f206SBjoern A. Zeeb {RTW_DMA_MAPPING_NORMAL, RTW_DMA_MAPPING_NORMAL, 16662774f206SBjoern A. Zeeb RTW_DMA_MAPPING_LOW, RTW_DMA_MAPPING_LOW, 16672774f206SBjoern A. Zeeb RTW_DMA_MAPPING_EXTRA, RTW_DMA_MAPPING_HIGH}, 16682774f206SBjoern A. Zeeb }; 16692774f206SBjoern A. Zeeb 16702774f206SBjoern A. Zeeb static struct rtw_prioq_addrs prioq_addrs_8821c = { 16712774f206SBjoern A. Zeeb .prio[RTW_DMA_MAPPING_EXTRA] = { 16722774f206SBjoern A. Zeeb .rsvd = REG_FIFOPAGE_INFO_4, .avail = REG_FIFOPAGE_INFO_4 + 2, 16732774f206SBjoern A. Zeeb }, 16742774f206SBjoern A. Zeeb .prio[RTW_DMA_MAPPING_LOW] = { 16752774f206SBjoern A. Zeeb .rsvd = REG_FIFOPAGE_INFO_2, .avail = REG_FIFOPAGE_INFO_2 + 2, 16762774f206SBjoern A. Zeeb }, 16772774f206SBjoern A. Zeeb .prio[RTW_DMA_MAPPING_NORMAL] = { 16782774f206SBjoern A. Zeeb .rsvd = REG_FIFOPAGE_INFO_3, .avail = REG_FIFOPAGE_INFO_3 + 2, 16792774f206SBjoern A. Zeeb }, 16802774f206SBjoern A. Zeeb .prio[RTW_DMA_MAPPING_HIGH] = { 16812774f206SBjoern A. Zeeb .rsvd = REG_FIFOPAGE_INFO_1, .avail = REG_FIFOPAGE_INFO_1 + 2, 16822774f206SBjoern A. Zeeb }, 16832774f206SBjoern A. Zeeb .wsize = true, 16842774f206SBjoern A. Zeeb }; 16852774f206SBjoern A. Zeeb 16862774f206SBjoern A. Zeeb static struct rtw_chip_ops rtw8821c_ops = { 16872774f206SBjoern A. Zeeb .phy_set_param = rtw8821c_phy_set_param, 16882774f206SBjoern A. Zeeb .read_efuse = rtw8821c_read_efuse, 16892774f206SBjoern A. Zeeb .query_rx_desc = rtw8821c_query_rx_desc, 16902774f206SBjoern A. Zeeb .set_channel = rtw8821c_set_channel, 16912774f206SBjoern A. Zeeb .mac_init = rtw8821c_mac_init, 16922774f206SBjoern A. Zeeb .read_rf = rtw_phy_read_rf, 16932774f206SBjoern A. Zeeb .write_rf = rtw_phy_write_rf_reg_sipi, 16942774f206SBjoern A. Zeeb .set_antenna = NULL, 16952774f206SBjoern A. Zeeb .set_tx_power_index = rtw8821c_set_tx_power_index, 16962774f206SBjoern A. Zeeb .cfg_ldo25 = rtw8821c_cfg_ldo25, 16972774f206SBjoern A. Zeeb .false_alarm_statistics = rtw8821c_false_alarm_statistics, 16982774f206SBjoern A. Zeeb .phy_calibration = rtw8821c_phy_calibration, 16992774f206SBjoern A. Zeeb .cck_pd_set = rtw8821c_phy_cck_pd_set, 17002774f206SBjoern A. Zeeb .pwr_track = rtw8821c_pwr_track, 17012774f206SBjoern A. Zeeb .config_bfee = rtw8821c_bf_config_bfee, 17022774f206SBjoern A. Zeeb .set_gid_table = rtw_bf_set_gid_table, 17032774f206SBjoern A. Zeeb .cfg_csi_rate = rtw_bf_cfg_csi_rate, 170490aac0d8SBjoern A. Zeeb .fill_txdesc_checksum = rtw8821c_fill_txdesc_checksum, 17052774f206SBjoern A. Zeeb 17062774f206SBjoern A. Zeeb .coex_set_init = rtw8821c_coex_cfg_init, 17072774f206SBjoern A. Zeeb .coex_set_ant_switch = rtw8821c_coex_cfg_ant_switch, 17082774f206SBjoern A. Zeeb .coex_set_gnt_fix = rtw8821c_coex_cfg_gnt_fix, 17092774f206SBjoern A. Zeeb .coex_set_gnt_debug = rtw8821c_coex_cfg_gnt_debug, 17102774f206SBjoern A. Zeeb .coex_set_rfe_type = rtw8821c_coex_cfg_rfe_type, 17112774f206SBjoern A. Zeeb .coex_set_wl_tx_power = rtw8821c_coex_cfg_wl_tx_power, 17122774f206SBjoern A. Zeeb .coex_set_wl_rx_gain = rtw8821c_coex_cfg_wl_rx_gain, 17132774f206SBjoern A. Zeeb }; 17142774f206SBjoern A. Zeeb 17152774f206SBjoern A. Zeeb /* rssi in percentage % (dbm = % - 100) */ 17162774f206SBjoern A. Zeeb static const u8 wl_rssi_step_8821c[] = {101, 45, 101, 40}; 17172774f206SBjoern A. Zeeb static const u8 bt_rssi_step_8821c[] = {101, 101, 101, 101}; 17182774f206SBjoern A. Zeeb 17192774f206SBjoern A. Zeeb /* Shared-Antenna Coex Table */ 17202774f206SBjoern A. Zeeb static const struct coex_table_para table_sant_8821c[] = { 17212774f206SBjoern A. Zeeb {0x55555555, 0x55555555}, /* case-0 */ 17222774f206SBjoern A. Zeeb {0x55555555, 0x55555555}, 17232774f206SBjoern A. Zeeb {0x66555555, 0x66555555}, 17242774f206SBjoern A. Zeeb {0xaaaaaaaa, 0xaaaaaaaa}, 17252774f206SBjoern A. Zeeb {0x5a5a5a5a, 0x5a5a5a5a}, 17262774f206SBjoern A. Zeeb {0xfafafafa, 0xfafafafa}, /* case-5 */ 17272774f206SBjoern A. Zeeb {0x6a5a5555, 0xaaaaaaaa}, 17282774f206SBjoern A. Zeeb {0x6a5a56aa, 0x6a5a56aa}, 17292774f206SBjoern A. Zeeb {0x6a5a5a5a, 0x6a5a5a5a}, 17302774f206SBjoern A. Zeeb {0x66555555, 0x5a5a5a5a}, 17312774f206SBjoern A. Zeeb {0x66555555, 0x6a5a5a5a}, /* case-10 */ 17322774f206SBjoern A. Zeeb {0x66555555, 0xaaaaaaaa}, 17332774f206SBjoern A. Zeeb {0x66555555, 0x6a5a5aaa}, 17342774f206SBjoern A. Zeeb {0x66555555, 0x6aaa6aaa}, 17352774f206SBjoern A. Zeeb {0x66555555, 0x6a5a5aaa}, 17362774f206SBjoern A. Zeeb {0x66555555, 0xaaaaaaaa}, /* case-15 */ 17372774f206SBjoern A. Zeeb {0xffff55ff, 0xfafafafa}, 17382774f206SBjoern A. Zeeb {0xffff55ff, 0x6afa5afa}, 17392774f206SBjoern A. Zeeb {0xaaffffaa, 0xfafafafa}, 17402774f206SBjoern A. Zeeb {0xaa5555aa, 0x5a5a5a5a}, 17412774f206SBjoern A. Zeeb {0xaa5555aa, 0x6a5a5a5a}, /* case-20 */ 17422774f206SBjoern A. Zeeb {0xaa5555aa, 0xaaaaaaaa}, 17432774f206SBjoern A. Zeeb {0xffffffff, 0x55555555}, 17442774f206SBjoern A. Zeeb {0xffffffff, 0x5a5a5a5a}, 17452774f206SBjoern A. Zeeb {0xffffffff, 0x5a5a5a5a}, 17462774f206SBjoern A. Zeeb {0xffffffff, 0x5a5a5aaa}, /* case-25 */ 17472774f206SBjoern A. Zeeb {0x55555555, 0x5a5a5a5a}, 17482774f206SBjoern A. Zeeb {0x55555555, 0xaaaaaaaa}, 17492774f206SBjoern A. Zeeb {0x66555555, 0x6a5a6a5a}, 17502774f206SBjoern A. Zeeb {0x66556655, 0x66556655}, 17512774f206SBjoern A. Zeeb {0x66556aaa, 0x6a5a6aaa}, /* case-30 */ 17522774f206SBjoern A. Zeeb {0xffffffff, 0x5aaa5aaa}, 17532774f206SBjoern A. Zeeb {0x56555555, 0x5a5a5aaa} 17542774f206SBjoern A. Zeeb }; 17552774f206SBjoern A. Zeeb 17562774f206SBjoern A. Zeeb /* Non-Shared-Antenna Coex Table */ 17572774f206SBjoern A. Zeeb static const struct coex_table_para table_nsant_8821c[] = { 17582774f206SBjoern A. Zeeb {0xffffffff, 0xffffffff}, /* case-100 */ 17592774f206SBjoern A. Zeeb {0xffff55ff, 0xfafafafa}, 17602774f206SBjoern A. Zeeb {0x66555555, 0x66555555}, 17612774f206SBjoern A. Zeeb {0xaaaaaaaa, 0xaaaaaaaa}, 17622774f206SBjoern A. Zeeb {0x5a5a5a5a, 0x5a5a5a5a}, 17632774f206SBjoern A. Zeeb {0xffffffff, 0xffffffff}, /* case-105 */ 17642774f206SBjoern A. Zeeb {0x5afa5afa, 0x5afa5afa}, 17652774f206SBjoern A. Zeeb {0x55555555, 0xfafafafa}, 17662774f206SBjoern A. Zeeb {0x66555555, 0xfafafafa}, 17672774f206SBjoern A. Zeeb {0x66555555, 0x5a5a5a5a}, 17682774f206SBjoern A. Zeeb {0x66555555, 0x6a5a5a5a}, /* case-110 */ 17692774f206SBjoern A. Zeeb {0x66555555, 0xaaaaaaaa}, 17702774f206SBjoern A. Zeeb {0xffff55ff, 0xfafafafa}, 17712774f206SBjoern A. Zeeb {0xffff55ff, 0x5afa5afa}, 17722774f206SBjoern A. Zeeb {0xffff55ff, 0xaaaaaaaa}, 17732774f206SBjoern A. Zeeb {0xffff55ff, 0xffff55ff}, /* case-115 */ 17742774f206SBjoern A. Zeeb {0xaaffffaa, 0x5afa5afa}, 17752774f206SBjoern A. Zeeb {0xaaffffaa, 0xaaaaaaaa}, 17762774f206SBjoern A. Zeeb {0xffffffff, 0xfafafafa}, 17772774f206SBjoern A. Zeeb {0xffff55ff, 0xfafafafa}, 17782774f206SBjoern A. Zeeb {0xffffffff, 0xaaaaaaaa}, /* case-120 */ 17792774f206SBjoern A. Zeeb {0xffff55ff, 0x5afa5afa}, 17802774f206SBjoern A. Zeeb {0xffff55ff, 0x5afa5afa}, 17812774f206SBjoern A. Zeeb {0x55ff55ff, 0x55ff55ff} 17822774f206SBjoern A. Zeeb }; 17832774f206SBjoern A. Zeeb 17842774f206SBjoern A. Zeeb /* Shared-Antenna TDMA */ 17852774f206SBjoern A. Zeeb static const struct coex_tdma_para tdma_sant_8821c[] = { 17862774f206SBjoern A. Zeeb { {0x00, 0x00, 0x00, 0x00, 0x00} }, /* case-0 */ 17872774f206SBjoern A. Zeeb { {0x61, 0x45, 0x03, 0x11, 0x11} }, /* case-1 */ 17882774f206SBjoern A. Zeeb { {0x61, 0x3a, 0x03, 0x11, 0x11} }, 17892774f206SBjoern A. Zeeb { {0x61, 0x35, 0x03, 0x11, 0x11} }, 17902774f206SBjoern A. Zeeb { {0x61, 0x20, 0x03, 0x11, 0x11} }, 17912774f206SBjoern A. Zeeb { {0x61, 0x3a, 0x03, 0x11, 0x11} }, /* case-5 */ 17922774f206SBjoern A. Zeeb { {0x61, 0x45, 0x03, 0x11, 0x10} }, 17932774f206SBjoern A. Zeeb { {0x61, 0x35, 0x03, 0x11, 0x10} }, 17942774f206SBjoern A. Zeeb { {0x61, 0x30, 0x03, 0x11, 0x10} }, 17952774f206SBjoern A. Zeeb { {0x61, 0x20, 0x03, 0x11, 0x10} }, 17962774f206SBjoern A. Zeeb { {0x61, 0x10, 0x03, 0x11, 0x10} }, /* case-10 */ 17972774f206SBjoern A. Zeeb { {0x61, 0x08, 0x03, 0x11, 0x15} }, 17982774f206SBjoern A. Zeeb { {0x61, 0x08, 0x03, 0x10, 0x14} }, 17992774f206SBjoern A. Zeeb { {0x51, 0x08, 0x03, 0x10, 0x54} }, 18002774f206SBjoern A. Zeeb { {0x51, 0x08, 0x03, 0x10, 0x55} }, 18012774f206SBjoern A. Zeeb { {0x51, 0x08, 0x07, 0x10, 0x54} }, /* case-15 */ 18022774f206SBjoern A. Zeeb { {0x51, 0x45, 0x03, 0x10, 0x50} }, 18032774f206SBjoern A. Zeeb { {0x51, 0x3a, 0x03, 0x11, 0x50} }, 18042774f206SBjoern A. Zeeb { {0x51, 0x30, 0x03, 0x10, 0x50} }, 18052774f206SBjoern A. Zeeb { {0x51, 0x21, 0x03, 0x10, 0x50} }, 18062774f206SBjoern A. Zeeb { {0x51, 0x10, 0x03, 0x10, 0x50} }, /* case-20 */ 18072774f206SBjoern A. Zeeb { {0x51, 0x4a, 0x03, 0x10, 0x50} }, 18082774f206SBjoern A. Zeeb { {0x51, 0x08, 0x03, 0x30, 0x54} }, 18092774f206SBjoern A. Zeeb { {0x55, 0x08, 0x03, 0x10, 0x54} }, 18102774f206SBjoern A. Zeeb { {0x65, 0x10, 0x03, 0x11, 0x10} }, 18112774f206SBjoern A. Zeeb { {0x51, 0x10, 0x03, 0x10, 0x51} }, /* case-25 */ 18122774f206SBjoern A. Zeeb { {0x51, 0x21, 0x03, 0x10, 0x50} }, 18132774f206SBjoern A. Zeeb { {0x61, 0x08, 0x03, 0x11, 0x11} } 18142774f206SBjoern A. Zeeb }; 18152774f206SBjoern A. Zeeb 18162774f206SBjoern A. Zeeb /* Non-Shared-Antenna TDMA */ 18172774f206SBjoern A. Zeeb static const struct coex_tdma_para tdma_nsant_8821c[] = { 18182774f206SBjoern A. Zeeb { {0x00, 0x00, 0x00, 0x40, 0x00} }, /* case-100 */ 18192774f206SBjoern A. Zeeb { {0x61, 0x45, 0x03, 0x11, 0x11} }, 18202774f206SBjoern A. Zeeb { {0x61, 0x25, 0x03, 0x11, 0x11} }, 18212774f206SBjoern A. Zeeb { {0x61, 0x35, 0x03, 0x11, 0x11} }, 18222774f206SBjoern A. Zeeb { {0x61, 0x20, 0x03, 0x11, 0x11} }, 18232774f206SBjoern A. Zeeb { {0x61, 0x10, 0x03, 0x11, 0x11} }, /* case-105 */ 18242774f206SBjoern A. Zeeb { {0x61, 0x45, 0x03, 0x11, 0x10} }, 18252774f206SBjoern A. Zeeb { {0x61, 0x30, 0x03, 0x11, 0x10} }, 18262774f206SBjoern A. Zeeb { {0x61, 0x30, 0x03, 0x11, 0x10} }, 18272774f206SBjoern A. Zeeb { {0x61, 0x20, 0x03, 0x11, 0x10} }, 18282774f206SBjoern A. Zeeb { {0x61, 0x10, 0x03, 0x11, 0x10} }, /* case-110 */ 18292774f206SBjoern A. Zeeb { {0x61, 0x10, 0x03, 0x11, 0x11} }, 18302774f206SBjoern A. Zeeb { {0x61, 0x08, 0x03, 0x10, 0x14} }, 18312774f206SBjoern A. Zeeb { {0x51, 0x08, 0x03, 0x10, 0x54} }, 18322774f206SBjoern A. Zeeb { {0x51, 0x08, 0x03, 0x10, 0x55} }, 18332774f206SBjoern A. Zeeb { {0x51, 0x08, 0x07, 0x10, 0x54} }, /* case-115 */ 18342774f206SBjoern A. Zeeb { {0x51, 0x45, 0x03, 0x10, 0x50} }, 18352774f206SBjoern A. Zeeb { {0x51, 0x3a, 0x03, 0x10, 0x50} }, 18362774f206SBjoern A. Zeeb { {0x51, 0x30, 0x03, 0x10, 0x50} }, 18372774f206SBjoern A. Zeeb { {0x51, 0x21, 0x03, 0x10, 0x50} }, 18382774f206SBjoern A. Zeeb { {0x51, 0x21, 0x03, 0x10, 0x50} }, /* case-120 */ 18392774f206SBjoern A. Zeeb { {0x51, 0x10, 0x03, 0x10, 0x50} } 18402774f206SBjoern A. Zeeb }; 18412774f206SBjoern A. Zeeb 18422774f206SBjoern A. Zeeb static const struct coex_5g_afh_map afh_5g_8821c[] = { {0, 0, 0} }; 18432774f206SBjoern A. Zeeb 18442774f206SBjoern A. Zeeb /* wl_tx_dec_power, bt_tx_dec_power, wl_rx_gain, bt_rx_lna_constrain */ 18452774f206SBjoern A. Zeeb static const struct coex_rf_para rf_para_tx_8821c[] = { 18462774f206SBjoern A. Zeeb {0, 0, false, 7}, /* for normal */ 18472774f206SBjoern A. Zeeb {0, 20, false, 7}, /* for WL-CPT */ 18482774f206SBjoern A. Zeeb {8, 17, true, 4}, 18492774f206SBjoern A. Zeeb {7, 18, true, 4}, 18502774f206SBjoern A. Zeeb {6, 19, true, 4}, 18512774f206SBjoern A. Zeeb {5, 20, true, 4} 18522774f206SBjoern A. Zeeb }; 18532774f206SBjoern A. Zeeb 18542774f206SBjoern A. Zeeb static const struct coex_rf_para rf_para_rx_8821c[] = { 18552774f206SBjoern A. Zeeb {0, 0, false, 7}, /* for normal */ 18562774f206SBjoern A. Zeeb {0, 20, false, 7}, /* for WL-CPT */ 18572774f206SBjoern A. Zeeb {3, 24, true, 5}, 18582774f206SBjoern A. Zeeb {2, 26, true, 5}, 18592774f206SBjoern A. Zeeb {1, 27, true, 5}, 18602774f206SBjoern A. Zeeb {0, 28, true, 5} 18612774f206SBjoern A. Zeeb }; 18622774f206SBjoern A. Zeeb 18632774f206SBjoern A. Zeeb #if defined(__linux__) 18642774f206SBjoern A. Zeeb static_assert(ARRAY_SIZE(rf_para_tx_8821c) == ARRAY_SIZE(rf_para_rx_8821c)); 18652774f206SBjoern A. Zeeb #elif defined(__FreeBSD__) 18662774f206SBjoern A. Zeeb rtw88_static_assert(ARRAY_SIZE(rf_para_tx_8821c) == ARRAY_SIZE(rf_para_rx_8821c)); 18672774f206SBjoern A. Zeeb #endif 18682774f206SBjoern A. Zeeb 18692774f206SBjoern A. Zeeb static const u8 rtw8821c_pwrtrk_5gb_n[][RTW_PWR_TRK_TBL_SZ] = { 18702774f206SBjoern A. Zeeb {0, 1, 1, 2, 3, 3, 3, 4, 4, 5, 5, 6, 6, 6, 7, 8, 8, 8, 9, 9, 9, 10, 10, 18712774f206SBjoern A. Zeeb 11, 11, 12, 12, 12, 12, 12}, 18722774f206SBjoern A. Zeeb {0, 1, 1, 1, 2, 3, 3, 4, 4, 5, 5, 5, 6, 6, 7, 8, 8, 9, 9, 10, 10, 11, 18732774f206SBjoern A. Zeeb 11, 12, 12, 12, 12, 12, 12, 12}, 18742774f206SBjoern A. Zeeb {0, 1, 2, 2, 3, 4, 4, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 9, 10, 10, 11, 18752774f206SBjoern A. Zeeb 11, 12, 12, 12, 12, 12, 12}, 18762774f206SBjoern A. Zeeb }; 18772774f206SBjoern A. Zeeb 18782774f206SBjoern A. Zeeb static const u8 rtw8821c_pwrtrk_5gb_p[][RTW_PWR_TRK_TBL_SZ] = { 18792774f206SBjoern A. Zeeb {0, 1, 1, 2, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 11, 11, 18802774f206SBjoern A. Zeeb 12, 12, 12, 12, 12, 12, 12}, 18812774f206SBjoern A. Zeeb {0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 5, 6, 7, 7, 8, 8, 9, 10, 10, 11, 11, 18822774f206SBjoern A. Zeeb 12, 12, 12, 12, 12, 12, 12, 12}, 18832774f206SBjoern A. Zeeb {0, 1, 1, 1, 2, 3, 3, 3, 4, 4, 4, 5, 6, 6, 7, 7, 8, 8, 9, 10, 10, 11, 18842774f206SBjoern A. Zeeb 11, 12, 12, 12, 12, 12, 12, 12}, 18852774f206SBjoern A. Zeeb }; 18862774f206SBjoern A. Zeeb 18872774f206SBjoern A. Zeeb static const u8 rtw8821c_pwrtrk_5ga_n[][RTW_PWR_TRK_TBL_SZ] = { 18882774f206SBjoern A. Zeeb {0, 1, 1, 2, 3, 3, 3, 4, 4, 5, 5, 6, 6, 6, 7, 8, 8, 8, 9, 9, 9, 10, 10, 18892774f206SBjoern A. Zeeb 11, 11, 12, 12, 12, 12, 12}, 18902774f206SBjoern A. Zeeb {0, 1, 1, 1, 2, 3, 3, 4, 4, 5, 5, 5, 6, 6, 7, 8, 8, 9, 9, 10, 10, 11, 18912774f206SBjoern A. Zeeb 11, 12, 12, 12, 12, 12, 12, 12}, 18922774f206SBjoern A. Zeeb {0, 1, 2, 2, 3, 4, 4, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 9, 10, 10, 11, 18932774f206SBjoern A. Zeeb 11, 12, 12, 12, 12, 12, 12}, 18942774f206SBjoern A. Zeeb }; 18952774f206SBjoern A. Zeeb 18962774f206SBjoern A. Zeeb static const u8 rtw8821c_pwrtrk_5ga_p[][RTW_PWR_TRK_TBL_SZ] = { 18972774f206SBjoern A. Zeeb {0, 1, 1, 2, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 11, 11, 18982774f206SBjoern A. Zeeb 12, 12, 12, 12, 12, 12, 12}, 18992774f206SBjoern A. Zeeb {0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 5, 6, 7, 7, 8, 8, 9, 10, 10, 11, 11, 19002774f206SBjoern A. Zeeb 12, 12, 12, 12, 12, 12, 12, 12}, 19012774f206SBjoern A. Zeeb {0, 1, 1, 1, 2, 3, 3, 3, 4, 4, 4, 5, 6, 6, 7, 7, 8, 8, 9, 10, 10, 11, 19022774f206SBjoern A. Zeeb 11, 12, 12, 12, 12, 12, 12, 12}, 19032774f206SBjoern A. Zeeb }; 19042774f206SBjoern A. Zeeb 19052774f206SBjoern A. Zeeb static const u8 rtw8821c_pwrtrk_2gb_n[] = { 19062774f206SBjoern A. Zeeb 0, 0, 0, 1, 1, 1, 2, 2, 2, 3, 3, 3, 3, 3, 4, 4, 19072774f206SBjoern A. Zeeb 4, 4, 5, 5, 5, 5, 6, 6, 6, 7, 7, 8, 8, 9 19082774f206SBjoern A. Zeeb }; 19092774f206SBjoern A. Zeeb 19102774f206SBjoern A. Zeeb static const u8 rtw8821c_pwrtrk_2gb_p[] = { 19112774f206SBjoern A. Zeeb 0, 1, 1, 1, 1, 2, 2, 2, 3, 3, 3, 3, 4, 4, 5, 5, 19122774f206SBjoern A. Zeeb 5, 5, 6, 6, 6, 7, 7, 7, 8, 8, 9, 9, 9, 9 19132774f206SBjoern A. Zeeb }; 19142774f206SBjoern A. Zeeb 19152774f206SBjoern A. Zeeb static const u8 rtw8821c_pwrtrk_2ga_n[] = { 19162774f206SBjoern A. Zeeb 0, 0, 0, 1, 1, 1, 2, 2, 2, 3, 3, 3, 3, 3, 4, 4, 19172774f206SBjoern A. Zeeb 4, 4, 5, 5, 5, 5, 6, 6, 6, 7, 7, 8, 8, 9 19182774f206SBjoern A. Zeeb }; 19192774f206SBjoern A. Zeeb 19202774f206SBjoern A. Zeeb static const u8 rtw8821c_pwrtrk_2ga_p[] = { 19212774f206SBjoern A. Zeeb 0, 1, 1, 1, 1, 2, 2, 2, 3, 3, 3, 3, 4, 4, 5, 5, 19222774f206SBjoern A. Zeeb 5, 5, 6, 6, 6, 7, 7, 7, 8, 8, 9, 9, 9, 9 19232774f206SBjoern A. Zeeb }; 19242774f206SBjoern A. Zeeb 19252774f206SBjoern A. Zeeb static const u8 rtw8821c_pwrtrk_2g_cck_b_n[] = { 19262774f206SBjoern A. Zeeb 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 19272774f206SBjoern A. Zeeb 4, 5, 5, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 9 19282774f206SBjoern A. Zeeb }; 19292774f206SBjoern A. Zeeb 19302774f206SBjoern A. Zeeb static const u8 rtw8821c_pwrtrk_2g_cck_b_p[] = { 19312774f206SBjoern A. Zeeb 0, 1, 1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 4, 5, 5, 19322774f206SBjoern A. Zeeb 5, 6, 6, 7, 7, 7, 8, 8, 9, 9, 9, 9, 9, 9 19332774f206SBjoern A. Zeeb }; 19342774f206SBjoern A. Zeeb 19352774f206SBjoern A. Zeeb static const u8 rtw8821c_pwrtrk_2g_cck_a_n[] = { 19362774f206SBjoern A. Zeeb 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 19372774f206SBjoern A. Zeeb 4, 5, 5, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 9 19382774f206SBjoern A. Zeeb }; 19392774f206SBjoern A. Zeeb 19402774f206SBjoern A. Zeeb static const u8 rtw8821c_pwrtrk_2g_cck_a_p[] = { 19412774f206SBjoern A. Zeeb 0, 1, 1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 4, 5, 5, 19422774f206SBjoern A. Zeeb 5, 6, 6, 7, 7, 7, 8, 8, 9, 9, 9, 9, 9, 9 19432774f206SBjoern A. Zeeb }; 19442774f206SBjoern A. Zeeb 19452774f206SBjoern A. Zeeb static const struct rtw_pwr_track_tbl rtw8821c_rtw_pwr_track_tbl = { 19462774f206SBjoern A. Zeeb .pwrtrk_5gb_n[0] = rtw8821c_pwrtrk_5gb_n[0], 19472774f206SBjoern A. Zeeb .pwrtrk_5gb_n[1] = rtw8821c_pwrtrk_5gb_n[1], 19482774f206SBjoern A. Zeeb .pwrtrk_5gb_n[2] = rtw8821c_pwrtrk_5gb_n[2], 19492774f206SBjoern A. Zeeb .pwrtrk_5gb_p[0] = rtw8821c_pwrtrk_5gb_p[0], 19502774f206SBjoern A. Zeeb .pwrtrk_5gb_p[1] = rtw8821c_pwrtrk_5gb_p[1], 19512774f206SBjoern A. Zeeb .pwrtrk_5gb_p[2] = rtw8821c_pwrtrk_5gb_p[2], 19522774f206SBjoern A. Zeeb .pwrtrk_5ga_n[0] = rtw8821c_pwrtrk_5ga_n[0], 19532774f206SBjoern A. Zeeb .pwrtrk_5ga_n[1] = rtw8821c_pwrtrk_5ga_n[1], 19542774f206SBjoern A. Zeeb .pwrtrk_5ga_n[2] = rtw8821c_pwrtrk_5ga_n[2], 19552774f206SBjoern A. Zeeb .pwrtrk_5ga_p[0] = rtw8821c_pwrtrk_5ga_p[0], 19562774f206SBjoern A. Zeeb .pwrtrk_5ga_p[1] = rtw8821c_pwrtrk_5ga_p[1], 19572774f206SBjoern A. Zeeb .pwrtrk_5ga_p[2] = rtw8821c_pwrtrk_5ga_p[2], 19582774f206SBjoern A. Zeeb .pwrtrk_2gb_n = rtw8821c_pwrtrk_2gb_n, 19592774f206SBjoern A. Zeeb .pwrtrk_2gb_p = rtw8821c_pwrtrk_2gb_p, 19602774f206SBjoern A. Zeeb .pwrtrk_2ga_n = rtw8821c_pwrtrk_2ga_n, 19612774f206SBjoern A. Zeeb .pwrtrk_2ga_p = rtw8821c_pwrtrk_2ga_p, 19622774f206SBjoern A. Zeeb .pwrtrk_2g_cckb_n = rtw8821c_pwrtrk_2g_cck_b_n, 19632774f206SBjoern A. Zeeb .pwrtrk_2g_cckb_p = rtw8821c_pwrtrk_2g_cck_b_p, 19642774f206SBjoern A. Zeeb .pwrtrk_2g_ccka_n = rtw8821c_pwrtrk_2g_cck_a_n, 19652774f206SBjoern A. Zeeb .pwrtrk_2g_ccka_p = rtw8821c_pwrtrk_2g_cck_a_p, 19662774f206SBjoern A. Zeeb }; 19672774f206SBjoern A. Zeeb 19682774f206SBjoern A. Zeeb static const struct rtw_reg_domain coex_info_hw_regs_8821c[] = { 19692774f206SBjoern A. Zeeb {0xCB0, MASKDWORD, RTW_REG_DOMAIN_MAC32}, 19702774f206SBjoern A. Zeeb {0xCB4, MASKDWORD, RTW_REG_DOMAIN_MAC32}, 19712774f206SBjoern A. Zeeb {0xCBA, MASKBYTE0, RTW_REG_DOMAIN_MAC8}, 19722774f206SBjoern A. Zeeb {0, 0, RTW_REG_DOMAIN_NL}, 19732774f206SBjoern A. Zeeb {0x430, MASKDWORD, RTW_REG_DOMAIN_MAC32}, 19742774f206SBjoern A. Zeeb {0x434, MASKDWORD, RTW_REG_DOMAIN_MAC32}, 19752774f206SBjoern A. Zeeb {0x42a, MASKLWORD, RTW_REG_DOMAIN_MAC16}, 19762774f206SBjoern A. Zeeb {0x426, MASKBYTE0, RTW_REG_DOMAIN_MAC8}, 19772774f206SBjoern A. Zeeb {0x45e, BIT(3), RTW_REG_DOMAIN_MAC8}, 19782774f206SBjoern A. Zeeb {0x454, MASKLWORD, RTW_REG_DOMAIN_MAC16}, 19792774f206SBjoern A. Zeeb {0, 0, RTW_REG_DOMAIN_NL}, 19802774f206SBjoern A. Zeeb {0x4c, BIT(24) | BIT(23), RTW_REG_DOMAIN_MAC32}, 19812774f206SBjoern A. Zeeb {0x64, BIT(0), RTW_REG_DOMAIN_MAC8}, 19822774f206SBjoern A. Zeeb {0x4c6, BIT(4), RTW_REG_DOMAIN_MAC8}, 19832774f206SBjoern A. Zeeb {0x40, BIT(5), RTW_REG_DOMAIN_MAC8}, 19842774f206SBjoern A. Zeeb {0x1, RFREG_MASK, RTW_REG_DOMAIN_RF_A}, 19852774f206SBjoern A. Zeeb {0, 0, RTW_REG_DOMAIN_NL}, 19862774f206SBjoern A. Zeeb {0x550, MASKDWORD, RTW_REG_DOMAIN_MAC32}, 19872774f206SBjoern A. Zeeb {0x522, MASKBYTE0, RTW_REG_DOMAIN_MAC8}, 19882774f206SBjoern A. Zeeb {0x953, BIT(1), RTW_REG_DOMAIN_MAC8}, 19892774f206SBjoern A. Zeeb {0xc50, MASKBYTE0, RTW_REG_DOMAIN_MAC8}, 19902774f206SBjoern A. Zeeb {0x60A, MASKBYTE0, RTW_REG_DOMAIN_MAC8}, 19912774f206SBjoern A. Zeeb }; 19922774f206SBjoern A. Zeeb 19939c951734SBjoern A. Zeeb const struct rtw_chip_info rtw8821c_hw_spec = { 19942774f206SBjoern A. Zeeb .ops = &rtw8821c_ops, 19952774f206SBjoern A. Zeeb .id = RTW_CHIP_TYPE_8821C, 19962774f206SBjoern A. Zeeb .fw_name = "rtw88/rtw8821c_fw.bin", 19972774f206SBjoern A. Zeeb .wlan_cpu = RTW_WCPU_11AC, 19982774f206SBjoern A. Zeeb .tx_pkt_desc_sz = 48, 19992774f206SBjoern A. Zeeb .tx_buf_desc_sz = 16, 20002774f206SBjoern A. Zeeb .rx_pkt_desc_sz = 24, 20012774f206SBjoern A. Zeeb .rx_buf_desc_sz = 8, 20022774f206SBjoern A. Zeeb .phy_efuse_size = 512, 20032774f206SBjoern A. Zeeb .log_efuse_size = 512, 20042774f206SBjoern A. Zeeb .ptct_efuse_size = 96, 20052774f206SBjoern A. Zeeb .txff_size = 65536, 20062774f206SBjoern A. Zeeb .rxff_size = 16384, 200790aac0d8SBjoern A. Zeeb .rsvd_drv_pg_num = 8, 20082774f206SBjoern A. Zeeb .txgi_factor = 1, 20092774f206SBjoern A. Zeeb .is_pwr_by_rate_dec = true, 20102774f206SBjoern A. Zeeb .max_power_index = 0x3f, 20112774f206SBjoern A. Zeeb .csi_buf_pg_num = 0, 20122774f206SBjoern A. Zeeb .band = RTW_BAND_2G | RTW_BAND_5G, 201390aac0d8SBjoern A. Zeeb .page_size = TX_PAGE_SIZE, 20142774f206SBjoern A. Zeeb .dig_min = 0x1c, 2015*11c53278SBjoern A. Zeeb .usb_tx_agg_desc_num = 3, 20162774f206SBjoern A. Zeeb .ht_supported = true, 20172774f206SBjoern A. Zeeb .vht_supported = true, 20182774f206SBjoern A. Zeeb .lps_deep_mode_supported = BIT(LPS_DEEP_MODE_LCLK), 20192774f206SBjoern A. Zeeb .sys_func_en = 0xD8, 20202774f206SBjoern A. Zeeb .pwr_on_seq = card_enable_flow_8821c, 20212774f206SBjoern A. Zeeb .pwr_off_seq = card_disable_flow_8821c, 20222774f206SBjoern A. Zeeb .page_table = page_table_8821c, 20232774f206SBjoern A. Zeeb .rqpn_table = rqpn_table_8821c, 20242774f206SBjoern A. Zeeb .prioq_addrs = &prioq_addrs_8821c, 20252774f206SBjoern A. Zeeb .intf_table = &phy_para_table_8821c, 20262774f206SBjoern A. Zeeb .dig = rtw8821c_dig, 20272774f206SBjoern A. Zeeb .rf_base_addr = {0x2800, 0x2c00}, 20282774f206SBjoern A. Zeeb .rf_sipi_addr = {0xc90, 0xe90}, 20292774f206SBjoern A. Zeeb .ltecoex_addr = &rtw8821c_ltecoex_addr, 20302774f206SBjoern A. Zeeb .mac_tbl = &rtw8821c_mac_tbl, 20312774f206SBjoern A. Zeeb .agc_tbl = &rtw8821c_agc_tbl, 20322774f206SBjoern A. Zeeb .bb_tbl = &rtw8821c_bb_tbl, 20332774f206SBjoern A. Zeeb .rf_tbl = {&rtw8821c_rf_a_tbl}, 20342774f206SBjoern A. Zeeb .rfe_defs = rtw8821c_rfe_defs, 20352774f206SBjoern A. Zeeb .rfe_defs_size = ARRAY_SIZE(rtw8821c_rfe_defs), 20362774f206SBjoern A. Zeeb .rx_ldpc = false, 20372774f206SBjoern A. Zeeb .pwr_track_tbl = &rtw8821c_rtw_pwr_track_tbl, 20382774f206SBjoern A. Zeeb .iqk_threshold = 8, 20392774f206SBjoern A. Zeeb .bfer_su_max_num = 2, 20402774f206SBjoern A. Zeeb .bfer_mu_max_num = 1, 20419c951734SBjoern A. Zeeb .ampdu_density = IEEE80211_HT_MPDU_DENSITY_2, 204290aac0d8SBjoern A. Zeeb .max_scan_ie_len = IEEE80211_MAX_DATA_LEN, 20432774f206SBjoern A. Zeeb 20442774f206SBjoern A. Zeeb .coex_para_ver = 0x19092746, 20452774f206SBjoern A. Zeeb .bt_desired_ver = 0x46, 20462774f206SBjoern A. Zeeb .scbd_support = true, 20472774f206SBjoern A. Zeeb .new_scbd10_def = false, 20482774f206SBjoern A. Zeeb .ble_hid_profile_support = false, 20499c951734SBjoern A. Zeeb .wl_mimo_ps_support = false, 20502774f206SBjoern A. Zeeb .pstdma_type = COEX_PSTDMA_FORCE_LPSOFF, 20512774f206SBjoern A. Zeeb .bt_rssi_type = COEX_BTRSSI_RATIO, 20522774f206SBjoern A. Zeeb .ant_isolation = 15, 20532774f206SBjoern A. Zeeb .rssi_tolerance = 2, 20542774f206SBjoern A. Zeeb .wl_rssi_step = wl_rssi_step_8821c, 20552774f206SBjoern A. Zeeb .bt_rssi_step = bt_rssi_step_8821c, 20562774f206SBjoern A. Zeeb .table_sant_num = ARRAY_SIZE(table_sant_8821c), 20572774f206SBjoern A. Zeeb .table_sant = table_sant_8821c, 20582774f206SBjoern A. Zeeb .table_nsant_num = ARRAY_SIZE(table_nsant_8821c), 20592774f206SBjoern A. Zeeb .table_nsant = table_nsant_8821c, 20602774f206SBjoern A. Zeeb .tdma_sant_num = ARRAY_SIZE(tdma_sant_8821c), 20612774f206SBjoern A. Zeeb .tdma_sant = tdma_sant_8821c, 20622774f206SBjoern A. Zeeb .tdma_nsant_num = ARRAY_SIZE(tdma_nsant_8821c), 20632774f206SBjoern A. Zeeb .tdma_nsant = tdma_nsant_8821c, 20642774f206SBjoern A. Zeeb .wl_rf_para_num = ARRAY_SIZE(rf_para_tx_8821c), 20652774f206SBjoern A. Zeeb .wl_rf_para_tx = rf_para_tx_8821c, 20662774f206SBjoern A. Zeeb .wl_rf_para_rx = rf_para_rx_8821c, 20672774f206SBjoern A. Zeeb .bt_afh_span_bw20 = 0x24, 20682774f206SBjoern A. Zeeb .bt_afh_span_bw40 = 0x36, 20692774f206SBjoern A. Zeeb .afh_5g_num = ARRAY_SIZE(afh_5g_8821c), 20702774f206SBjoern A. Zeeb .afh_5g = afh_5g_8821c, 20712774f206SBjoern A. Zeeb 20722774f206SBjoern A. Zeeb .coex_info_hw_regs_num = ARRAY_SIZE(coex_info_hw_regs_8821c), 20732774f206SBjoern A. Zeeb .coex_info_hw_regs = coex_info_hw_regs_8821c, 20742774f206SBjoern A. Zeeb }; 20752774f206SBjoern A. Zeeb EXPORT_SYMBOL(rtw8821c_hw_spec); 20762774f206SBjoern A. Zeeb 20772774f206SBjoern A. Zeeb MODULE_FIRMWARE("rtw88/rtw8821c_fw.bin"); 20782774f206SBjoern A. Zeeb 20792774f206SBjoern A. Zeeb MODULE_AUTHOR("Realtek Corporation"); 20802774f206SBjoern A. Zeeb MODULE_DESCRIPTION("Realtek 802.11ac wireless 8821c driver"); 20812774f206SBjoern A. Zeeb MODULE_LICENSE("Dual BSD/GPL"); 2082