1811853daSPing-Ke Shih // SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause 2811853daSPing-Ke Shih /* Copyright(c) 2018-2019 Realtek Corporation 3811853daSPing-Ke Shih */ 4811853daSPing-Ke Shih 5811853daSPing-Ke Shih #include "main.h" 6811853daSPing-Ke Shih #include "coex.h" 7811853daSPing-Ke Shih #include "fw.h" 8811853daSPing-Ke Shih #include "tx.h" 9811853daSPing-Ke Shih #include "rx.h" 10811853daSPing-Ke Shih #include "phy.h" 11811853daSPing-Ke Shih #include "rtw8723d.h" 12811853daSPing-Ke Shih #include "rtw8723d_table.h" 13811853daSPing-Ke Shih #include "mac.h" 14811853daSPing-Ke Shih #include "reg.h" 15811853daSPing-Ke Shih #include "debug.h" 16811853daSPing-Ke Shih 17ba9f0d1bSPing-Ke Shih static const struct rtw_hw_reg rtw8723d_txagc[] = { 18ba9f0d1bSPing-Ke Shih [DESC_RATE1M] = { .addr = 0xe08, .mask = 0x0000ff00 }, 19ba9f0d1bSPing-Ke Shih [DESC_RATE2M] = { .addr = 0x86c, .mask = 0x0000ff00 }, 20ba9f0d1bSPing-Ke Shih [DESC_RATE5_5M] = { .addr = 0x86c, .mask = 0x00ff0000 }, 21ba9f0d1bSPing-Ke Shih [DESC_RATE11M] = { .addr = 0x86c, .mask = 0xff000000 }, 22ba9f0d1bSPing-Ke Shih [DESC_RATE6M] = { .addr = 0xe00, .mask = 0x000000ff }, 23ba9f0d1bSPing-Ke Shih [DESC_RATE9M] = { .addr = 0xe00, .mask = 0x0000ff00 }, 24ba9f0d1bSPing-Ke Shih [DESC_RATE12M] = { .addr = 0xe00, .mask = 0x00ff0000 }, 25ba9f0d1bSPing-Ke Shih [DESC_RATE18M] = { .addr = 0xe00, .mask = 0xff000000 }, 26ba9f0d1bSPing-Ke Shih [DESC_RATE24M] = { .addr = 0xe04, .mask = 0x000000ff }, 27ba9f0d1bSPing-Ke Shih [DESC_RATE36M] = { .addr = 0xe04, .mask = 0x0000ff00 }, 28ba9f0d1bSPing-Ke Shih [DESC_RATE48M] = { .addr = 0xe04, .mask = 0x00ff0000 }, 29ba9f0d1bSPing-Ke Shih [DESC_RATE54M] = { .addr = 0xe04, .mask = 0xff000000 }, 30ba9f0d1bSPing-Ke Shih [DESC_RATEMCS0] = { .addr = 0xe10, .mask = 0x000000ff }, 31ba9f0d1bSPing-Ke Shih [DESC_RATEMCS1] = { .addr = 0xe10, .mask = 0x0000ff00 }, 32ba9f0d1bSPing-Ke Shih [DESC_RATEMCS2] = { .addr = 0xe10, .mask = 0x00ff0000 }, 33ba9f0d1bSPing-Ke Shih [DESC_RATEMCS3] = { .addr = 0xe10, .mask = 0xff000000 }, 34ba9f0d1bSPing-Ke Shih [DESC_RATEMCS4] = { .addr = 0xe14, .mask = 0x000000ff }, 35ba9f0d1bSPing-Ke Shih [DESC_RATEMCS5] = { .addr = 0xe14, .mask = 0x0000ff00 }, 36ba9f0d1bSPing-Ke Shih [DESC_RATEMCS6] = { .addr = 0xe14, .mask = 0x00ff0000 }, 37ba9f0d1bSPing-Ke Shih [DESC_RATEMCS7] = { .addr = 0xe14, .mask = 0xff000000 }, 38ba9f0d1bSPing-Ke Shih }; 39ba9f0d1bSPing-Ke Shih 4075e69fb1SPing-Ke Shih #define WLAN_TXQ_RPT_EN 0x1F 4175e69fb1SPing-Ke Shih #define WLAN_SLOT_TIME 0x09 4275e69fb1SPing-Ke Shih #define WLAN_RL_VAL 0x3030 4375e69fb1SPing-Ke Shih #define WLAN_BAR_VAL 0x0201ffff 4475e69fb1SPing-Ke Shih #define BIT_MASK_TBTT_HOLD 0x00000fff 4575e69fb1SPing-Ke Shih #define BIT_SHIFT_TBTT_HOLD 8 4675e69fb1SPing-Ke Shih #define BIT_MASK_TBTT_SETUP 0x000000ff 4775e69fb1SPing-Ke Shih #define BIT_SHIFT_TBTT_SETUP 0 4875e69fb1SPing-Ke Shih #define BIT_MASK_TBTT_MASK ((BIT_MASK_TBTT_HOLD << BIT_SHIFT_TBTT_HOLD) | \ 4975e69fb1SPing-Ke Shih (BIT_MASK_TBTT_SETUP << BIT_SHIFT_TBTT_SETUP)) 5075e69fb1SPing-Ke Shih #define TBTT_TIME(s, h)((((s) & BIT_MASK_TBTT_SETUP) << BIT_SHIFT_TBTT_SETUP) |\ 5175e69fb1SPing-Ke Shih (((h) & BIT_MASK_TBTT_HOLD) << BIT_SHIFT_TBTT_HOLD)) 5275e69fb1SPing-Ke Shih #define WLAN_TBTT_TIME_NORMAL TBTT_TIME(0x04, 0x80) 5375e69fb1SPing-Ke Shih #define WLAN_TBTT_TIME_STOP_BCN TBTT_TIME(0x04, 0x64) 5475e69fb1SPing-Ke Shih #define WLAN_PIFS_VAL 0 5575e69fb1SPing-Ke Shih #define WLAN_AGG_BRK_TIME 0x16 5675e69fb1SPing-Ke Shih #define WLAN_NAV_PROT_LEN 0x0040 5775e69fb1SPing-Ke Shih #define WLAN_SPEC_SIFS 0x100a 5875e69fb1SPing-Ke Shih #define WLAN_RX_PKT_LIMIT 0x17 5975e69fb1SPing-Ke Shih #define WLAN_MAX_AGG_NR 0x0A 6075e69fb1SPing-Ke Shih #define WLAN_AMPDU_MAX_TIME 0x1C 6175e69fb1SPing-Ke Shih #define WLAN_ANT_SEL 0x82 6275e69fb1SPing-Ke Shih #define WLAN_LTR_IDLE_LAT 0x883C883C 6375e69fb1SPing-Ke Shih #define WLAN_LTR_ACT_LAT 0x880B880B 6475e69fb1SPing-Ke Shih #define WLAN_LTR_CTRL1 0xCB004010 6575e69fb1SPing-Ke Shih #define WLAN_LTR_CTRL2 0x01233425 6675e69fb1SPing-Ke Shih 67f71eb7f6SPing-Ke Shih static void rtw8723d_lck(struct rtw_dev *rtwdev) 68f71eb7f6SPing-Ke Shih { 69f71eb7f6SPing-Ke Shih u32 lc_cal; 70f71eb7f6SPing-Ke Shih u8 val_ctx, rf_val; 71f71eb7f6SPing-Ke Shih int ret; 72f71eb7f6SPing-Ke Shih 73f71eb7f6SPing-Ke Shih val_ctx = rtw_read8(rtwdev, REG_CTX); 74f71eb7f6SPing-Ke Shih if ((val_ctx & BIT_MASK_CTX_TYPE) != 0) 75f71eb7f6SPing-Ke Shih rtw_write8(rtwdev, REG_CTX, val_ctx & ~BIT_MASK_CTX_TYPE); 76f71eb7f6SPing-Ke Shih else 77f71eb7f6SPing-Ke Shih rtw_write8(rtwdev, REG_TXPAUSE, 0xFF); 78f71eb7f6SPing-Ke Shih lc_cal = rtw_read_rf(rtwdev, RF_PATH_A, RF_CFGCH, RFREG_MASK); 79f71eb7f6SPing-Ke Shih 80f71eb7f6SPing-Ke Shih rtw_write_rf(rtwdev, RF_PATH_A, RF_CFGCH, RFREG_MASK, lc_cal | BIT_LCK); 81f71eb7f6SPing-Ke Shih 82f71eb7f6SPing-Ke Shih ret = read_poll_timeout(rtw_read_rf, rf_val, rf_val != 0x1, 83f71eb7f6SPing-Ke Shih 10000, 1000000, false, 84f71eb7f6SPing-Ke Shih rtwdev, RF_PATH_A, RF_CFGCH, BIT_LCK); 85f71eb7f6SPing-Ke Shih if (ret) 86f71eb7f6SPing-Ke Shih rtw_warn(rtwdev, "failed to poll LCK status bit\n"); 87f71eb7f6SPing-Ke Shih 88f71eb7f6SPing-Ke Shih rtw_write_rf(rtwdev, RF_PATH_A, RF_CFGCH, RFREG_MASK, lc_cal); 89f71eb7f6SPing-Ke Shih if ((val_ctx & BIT_MASK_CTX_TYPE) != 0) 90f71eb7f6SPing-Ke Shih rtw_write8(rtwdev, REG_CTX, val_ctx); 91f71eb7f6SPing-Ke Shih else 92f71eb7f6SPing-Ke Shih rtw_write8(rtwdev, REG_TXPAUSE, 0x00); 93f71eb7f6SPing-Ke Shih } 94f71eb7f6SPing-Ke Shih 95608d2a08SPing-Ke Shih static const u32 rtw8723d_ofdm_swing_table[] = { 96608d2a08SPing-Ke Shih 0x0b40002d, 0x0c000030, 0x0cc00033, 0x0d800036, 0x0e400039, 0x0f00003c, 97608d2a08SPing-Ke Shih 0x10000040, 0x11000044, 0x12000048, 0x1300004c, 0x14400051, 0x15800056, 98608d2a08SPing-Ke Shih 0x16c0005b, 0x18000060, 0x19800066, 0x1b00006c, 0x1c800072, 0x1e400079, 99608d2a08SPing-Ke Shih 0x20000080, 0x22000088, 0x24000090, 0x26000098, 0x288000a2, 0x2ac000ab, 100608d2a08SPing-Ke Shih 0x2d4000b5, 0x300000c0, 0x32c000cb, 0x35c000d7, 0x390000e4, 0x3c8000f2, 101608d2a08SPing-Ke Shih 0x40000100, 0x43c0010f, 0x47c0011f, 0x4c000130, 0x50800142, 0x55400155, 102608d2a08SPing-Ke Shih 0x5a400169, 0x5fc0017f, 0x65400195, 0x6b8001ae, 0x71c001c7, 0x788001e2, 103608d2a08SPing-Ke Shih 0x7f8001fe, 104608d2a08SPing-Ke Shih }; 105608d2a08SPing-Ke Shih 106608d2a08SPing-Ke Shih static const u32 rtw8723d_cck_swing_table[] = { 107608d2a08SPing-Ke Shih 0x0CD, 0x0D9, 0x0E6, 0x0F3, 0x102, 0x111, 0x121, 0x132, 0x144, 0x158, 108608d2a08SPing-Ke Shih 0x16C, 0x182, 0x198, 0x1B1, 0x1CA, 0x1E5, 0x202, 0x221, 0x241, 0x263, 109608d2a08SPing-Ke Shih 0x287, 0x2AE, 0x2D6, 0x301, 0x32F, 0x35F, 0x392, 0x3C9, 0x402, 0x43F, 110608d2a08SPing-Ke Shih 0x47F, 0x4C3, 0x50C, 0x558, 0x5A9, 0x5FF, 0x65A, 0x6BA, 0x720, 0x78C, 111608d2a08SPing-Ke Shih 0x7FF, 112608d2a08SPing-Ke Shih }; 113608d2a08SPing-Ke Shih 114608d2a08SPing-Ke Shih #define RTW_OFDM_SWING_TABLE_SIZE ARRAY_SIZE(rtw8723d_ofdm_swing_table) 115608d2a08SPing-Ke Shih #define RTW_CCK_SWING_TABLE_SIZE ARRAY_SIZE(rtw8723d_cck_swing_table) 116608d2a08SPing-Ke Shih 117608d2a08SPing-Ke Shih static void rtw8723d_pwrtrack_init(struct rtw_dev *rtwdev) 118608d2a08SPing-Ke Shih { 119608d2a08SPing-Ke Shih struct rtw_dm_info *dm_info = &rtwdev->dm_info; 120608d2a08SPing-Ke Shih u8 path; 121608d2a08SPing-Ke Shih 122608d2a08SPing-Ke Shih dm_info->default_ofdm_index = RTW_DEF_OFDM_SWING_INDEX; 123608d2a08SPing-Ke Shih 124608d2a08SPing-Ke Shih for (path = RF_PATH_A; path < rtwdev->hal.rf_path_num; path++) { 125608d2a08SPing-Ke Shih ewma_thermal_init(&dm_info->avg_thermal[path]); 126608d2a08SPing-Ke Shih dm_info->delta_power_index[path] = 0; 127608d2a08SPing-Ke Shih } 128608d2a08SPing-Ke Shih dm_info->pwr_trk_triggered = false; 129608d2a08SPing-Ke Shih dm_info->pwr_trk_init_trigger = true; 130608d2a08SPing-Ke Shih dm_info->thermal_meter_k = rtwdev->efuse.thermal_meter_k; 131608d2a08SPing-Ke Shih dm_info->txagc_remnant_cck = 0; 132608d2a08SPing-Ke Shih dm_info->txagc_remnant_ofdm = 0; 133608d2a08SPing-Ke Shih } 134608d2a08SPing-Ke Shih 13575e69fb1SPing-Ke Shih static void rtw8723d_phy_set_param(struct rtw_dev *rtwdev) 13675e69fb1SPing-Ke Shih { 13775e69fb1SPing-Ke Shih u8 xtal_cap; 13875e69fb1SPing-Ke Shih u32 val32; 13975e69fb1SPing-Ke Shih 14075e69fb1SPing-Ke Shih /* power on BB/RF domain */ 14175e69fb1SPing-Ke Shih rtw_write16_set(rtwdev, REG_SYS_FUNC_EN, 14275e69fb1SPing-Ke Shih BIT_FEN_EN_25_1 | BIT_FEN_BB_GLB_RST | BIT_FEN_BB_RSTB); 14375e69fb1SPing-Ke Shih rtw_write8_set(rtwdev, REG_RF_CTRL, 14475e69fb1SPing-Ke Shih BIT_RF_EN | BIT_RF_RSTB | BIT_RF_SDM_RSTB); 14575e69fb1SPing-Ke Shih rtw_write8(rtwdev, REG_AFE_CTRL1 + 1, 0x80); 14675e69fb1SPing-Ke Shih 14775e69fb1SPing-Ke Shih rtw_phy_load_tables(rtwdev); 14875e69fb1SPing-Ke Shih 14975e69fb1SPing-Ke Shih /* post init after header files config */ 15075e69fb1SPing-Ke Shih rtw_write32_clr(rtwdev, REG_RCR, BIT_RCR_ADF); 15175e69fb1SPing-Ke Shih rtw_write8_set(rtwdev, REG_HIQ_NO_LMT_EN, BIT_HIQ_NO_LMT_EN_ROOT); 15275e69fb1SPing-Ke Shih rtw_write16_set(rtwdev, REG_AFE_CTRL_4, BIT_CK320M_AFE_EN | BIT_EN_SYN); 15375e69fb1SPing-Ke Shih 15475e69fb1SPing-Ke Shih xtal_cap = rtwdev->efuse.crystal_cap & 0x3F; 15575e69fb1SPing-Ke Shih rtw_write32_mask(rtwdev, REG_AFE_CTRL3, BIT_MASK_XTAL, 15675e69fb1SPing-Ke Shih xtal_cap | (xtal_cap << 6)); 15775e69fb1SPing-Ke Shih rtw_write32_set(rtwdev, REG_FPGA0_RFMOD, BIT_CCKEN | BIT_OFDMEN); 15875e69fb1SPing-Ke Shih if ((rtwdev->efuse.afe >> 4) == 14) { 15975e69fb1SPing-Ke Shih rtw_write32_set(rtwdev, REG_AFE_CTRL3, BIT_XTAL_GMP_BIT4); 16075e69fb1SPing-Ke Shih rtw_write32_clr(rtwdev, REG_AFE_CTRL1, BITS_PLL); 16175e69fb1SPing-Ke Shih rtw_write32_set(rtwdev, REG_LDO_SWR_CTRL, BIT_XTA1); 16275e69fb1SPing-Ke Shih rtw_write32_clr(rtwdev, REG_LDO_SWR_CTRL, BIT_XTA0); 16375e69fb1SPing-Ke Shih } 16475e69fb1SPing-Ke Shih 16575e69fb1SPing-Ke Shih rtw_write8(rtwdev, REG_SLOT, WLAN_SLOT_TIME); 16675e69fb1SPing-Ke Shih rtw_write8(rtwdev, REG_FWHW_TXQ_CTRL + 1, WLAN_TXQ_RPT_EN); 16775e69fb1SPing-Ke Shih rtw_write16(rtwdev, REG_RETRY_LIMIT, WLAN_RL_VAL); 16875e69fb1SPing-Ke Shih rtw_write32(rtwdev, REG_BAR_MODE_CTRL, WLAN_BAR_VAL); 16975e69fb1SPing-Ke Shih rtw_write8(rtwdev, REG_ATIMWND, 0x2); 17075e69fb1SPing-Ke Shih rtw_write8(rtwdev, REG_BCN_CTRL, 17175e69fb1SPing-Ke Shih BIT_DIS_TSF_UDT | BIT_EN_BCN_FUNCTION | BIT_EN_TXBCN_RPT); 17275e69fb1SPing-Ke Shih val32 = rtw_read32(rtwdev, REG_TBTT_PROHIBIT); 17375e69fb1SPing-Ke Shih val32 &= ~BIT_MASK_TBTT_MASK; 17475e69fb1SPing-Ke Shih val32 |= WLAN_TBTT_TIME_STOP_BCN; 17575e69fb1SPing-Ke Shih rtw_write8(rtwdev, REG_TBTT_PROHIBIT, val32); 17675e69fb1SPing-Ke Shih rtw_write8(rtwdev, REG_PIFS, WLAN_PIFS_VAL); 17775e69fb1SPing-Ke Shih rtw_write8(rtwdev, REG_AGGR_BREAK_TIME, WLAN_AGG_BRK_TIME); 17875e69fb1SPing-Ke Shih rtw_write16(rtwdev, REG_NAV_PROT_LEN, WLAN_NAV_PROT_LEN); 17975e69fb1SPing-Ke Shih rtw_write16(rtwdev, REG_MAC_SPEC_SIFS, WLAN_SPEC_SIFS); 18075e69fb1SPing-Ke Shih rtw_write16(rtwdev, REG_SIFS, WLAN_SPEC_SIFS); 18175e69fb1SPing-Ke Shih rtw_write16(rtwdev, REG_SIFS + 2, WLAN_SPEC_SIFS); 18275e69fb1SPing-Ke Shih rtw_write8(rtwdev, REG_SINGLE_AMPDU_CTRL, BIT_EN_SINGLE_APMDU); 18375e69fb1SPing-Ke Shih rtw_write8(rtwdev, REG_RX_PKT_LIMIT, WLAN_RX_PKT_LIMIT); 18475e69fb1SPing-Ke Shih rtw_write8(rtwdev, REG_MAX_AGGR_NUM, WLAN_MAX_AGG_NR); 18575e69fb1SPing-Ke Shih rtw_write8(rtwdev, REG_AMPDU_MAX_TIME, WLAN_AMPDU_MAX_TIME); 18675e69fb1SPing-Ke Shih rtw_write8(rtwdev, REG_LEDCFG2, WLAN_ANT_SEL); 18775e69fb1SPing-Ke Shih 18875e69fb1SPing-Ke Shih rtw_write32(rtwdev, REG_LTR_IDLE_LATENCY, WLAN_LTR_IDLE_LAT); 18975e69fb1SPing-Ke Shih rtw_write32(rtwdev, REG_LTR_ACTIVE_LATENCY, WLAN_LTR_ACT_LAT); 19075e69fb1SPing-Ke Shih rtw_write32(rtwdev, REG_LTR_CTRL_BASIC, WLAN_LTR_CTRL1); 19175e69fb1SPing-Ke Shih rtw_write32(rtwdev, REG_LTR_CTRL_BASIC + 4, WLAN_LTR_CTRL2); 19275e69fb1SPing-Ke Shih 19375e69fb1SPing-Ke Shih rtw_phy_init(rtwdev); 19475e69fb1SPing-Ke Shih 19575e69fb1SPing-Ke Shih rtw_write16_set(rtwdev, REG_TXDMA_OFFSET_CHK, BIT_DROP_DATA_EN); 196f71eb7f6SPing-Ke Shih 197f71eb7f6SPing-Ke Shih rtw8723d_lck(rtwdev); 198f71eb7f6SPing-Ke Shih 19975e69fb1SPing-Ke Shih rtw_write32_mask(rtwdev, REG_OFDM0_XAAGC1, MASKBYTE0, 0x50); 20075e69fb1SPing-Ke Shih rtw_write32_mask(rtwdev, REG_OFDM0_XAAGC1, MASKBYTE0, 0x20); 201608d2a08SPing-Ke Shih 202608d2a08SPing-Ke Shih rtw8723d_pwrtrack_init(rtwdev); 20375e69fb1SPing-Ke Shih } 20475e69fb1SPing-Ke Shih 205ab0a031eSPing-Ke Shih static void rtw8723de_efuse_parsing(struct rtw_efuse *efuse, 206ab0a031eSPing-Ke Shih struct rtw8723d_efuse *map) 207ab0a031eSPing-Ke Shih { 208ab0a031eSPing-Ke Shih ether_addr_copy(efuse->addr, map->e.mac_addr); 209ab0a031eSPing-Ke Shih } 210ab0a031eSPing-Ke Shih 211ab0a031eSPing-Ke Shih static int rtw8723d_read_efuse(struct rtw_dev *rtwdev, u8 *log_map) 212ab0a031eSPing-Ke Shih { 213ab0a031eSPing-Ke Shih struct rtw_efuse *efuse = &rtwdev->efuse; 214ab0a031eSPing-Ke Shih struct rtw8723d_efuse *map; 215ab0a031eSPing-Ke Shih int i; 216ab0a031eSPing-Ke Shih 217ab0a031eSPing-Ke Shih map = (struct rtw8723d_efuse *)log_map; 218ab0a031eSPing-Ke Shih 219ab0a031eSPing-Ke Shih efuse->rfe_option = 0; 220ab0a031eSPing-Ke Shih efuse->rf_board_option = map->rf_board_option; 221ab0a031eSPing-Ke Shih efuse->crystal_cap = map->xtal_k; 222ab0a031eSPing-Ke Shih efuse->pa_type_2g = map->pa_type; 223ab0a031eSPing-Ke Shih efuse->lna_type_2g = map->lna_type_2g[0]; 224ab0a031eSPing-Ke Shih efuse->channel_plan = map->channel_plan; 225ab0a031eSPing-Ke Shih efuse->country_code[0] = map->country_code[0]; 226ab0a031eSPing-Ke Shih efuse->country_code[1] = map->country_code[1]; 227ab0a031eSPing-Ke Shih efuse->bt_setting = map->rf_bt_setting; 228ab0a031eSPing-Ke Shih efuse->regd = map->rf_board_option & 0x7; 229ab0a031eSPing-Ke Shih efuse->thermal_meter[0] = map->thermal_meter; 230ab0a031eSPing-Ke Shih efuse->thermal_meter_k = map->thermal_meter; 23175e69fb1SPing-Ke Shih efuse->afe = map->afe; 232ab0a031eSPing-Ke Shih 233ab0a031eSPing-Ke Shih for (i = 0; i < 4; i++) 234ab0a031eSPing-Ke Shih efuse->txpwr_idx_table[i] = map->txpwr_idx_table[i]; 235ab0a031eSPing-Ke Shih 236ab0a031eSPing-Ke Shih switch (rtw_hci_type(rtwdev)) { 237ab0a031eSPing-Ke Shih case RTW_HCI_TYPE_PCIE: 238ab0a031eSPing-Ke Shih rtw8723de_efuse_parsing(efuse, map); 239ab0a031eSPing-Ke Shih break; 240ab0a031eSPing-Ke Shih default: 241ab0a031eSPing-Ke Shih /* unsupported now */ 242ab0a031eSPing-Ke Shih return -ENOTSUPP; 243ab0a031eSPing-Ke Shih } 244ab0a031eSPing-Ke Shih 245ab0a031eSPing-Ke Shih return 0; 246ab0a031eSPing-Ke Shih } 247ab0a031eSPing-Ke Shih 248158441a2SPing-Ke Shih static void query_phy_status_page0(struct rtw_dev *rtwdev, u8 *phy_status, 249158441a2SPing-Ke Shih struct rtw_rx_pkt_stat *pkt_stat) 250158441a2SPing-Ke Shih { 251158441a2SPing-Ke Shih struct rtw_dm_info *dm_info = &rtwdev->dm_info; 252158441a2SPing-Ke Shih s8 min_rx_power = -120; 253158441a2SPing-Ke Shih u8 pwdb = GET_PHY_STAT_P0_PWDB(phy_status); 254158441a2SPing-Ke Shih 255158441a2SPing-Ke Shih pkt_stat->rx_power[RF_PATH_A] = pwdb - 97; 256158441a2SPing-Ke Shih pkt_stat->rssi = rtw_phy_rf_power_2_rssi(pkt_stat->rx_power, 1); 257158441a2SPing-Ke Shih pkt_stat->bw = RTW_CHANNEL_WIDTH_20; 258158441a2SPing-Ke Shih pkt_stat->signal_power = max(pkt_stat->rx_power[RF_PATH_A], 259158441a2SPing-Ke Shih min_rx_power); 260158441a2SPing-Ke Shih dm_info->rssi[RF_PATH_A] = pkt_stat->rssi; 261158441a2SPing-Ke Shih } 262158441a2SPing-Ke Shih 263158441a2SPing-Ke Shih static void query_phy_status_page1(struct rtw_dev *rtwdev, u8 *phy_status, 264158441a2SPing-Ke Shih struct rtw_rx_pkt_stat *pkt_stat) 265158441a2SPing-Ke Shih { 266158441a2SPing-Ke Shih struct rtw_dm_info *dm_info = &rtwdev->dm_info; 267158441a2SPing-Ke Shih u8 rxsc, bw; 268158441a2SPing-Ke Shih s8 min_rx_power = -120; 269158441a2SPing-Ke Shih s8 rx_evm; 270158441a2SPing-Ke Shih 271158441a2SPing-Ke Shih if (pkt_stat->rate > DESC_RATE11M && pkt_stat->rate < DESC_RATEMCS0) 272158441a2SPing-Ke Shih rxsc = GET_PHY_STAT_P1_L_RXSC(phy_status); 273158441a2SPing-Ke Shih else 274158441a2SPing-Ke Shih rxsc = GET_PHY_STAT_P1_HT_RXSC(phy_status); 275158441a2SPing-Ke Shih 276158441a2SPing-Ke Shih if (GET_PHY_STAT_P1_RF_MODE(phy_status) == 0) 277158441a2SPing-Ke Shih bw = RTW_CHANNEL_WIDTH_20; 278158441a2SPing-Ke Shih else if ((rxsc == 1) || (rxsc == 2)) 279158441a2SPing-Ke Shih bw = RTW_CHANNEL_WIDTH_20; 280158441a2SPing-Ke Shih else 281158441a2SPing-Ke Shih bw = RTW_CHANNEL_WIDTH_40; 282158441a2SPing-Ke Shih 283158441a2SPing-Ke Shih pkt_stat->rx_power[RF_PATH_A] = GET_PHY_STAT_P1_PWDB_A(phy_status) - 110; 284158441a2SPing-Ke Shih pkt_stat->rssi = rtw_phy_rf_power_2_rssi(pkt_stat->rx_power, 1); 285158441a2SPing-Ke Shih pkt_stat->bw = bw; 286158441a2SPing-Ke Shih pkt_stat->signal_power = max(pkt_stat->rx_power[RF_PATH_A], 287158441a2SPing-Ke Shih min_rx_power); 288158441a2SPing-Ke Shih pkt_stat->rx_evm[RF_PATH_A] = GET_PHY_STAT_P1_RXEVM_A(phy_status); 289158441a2SPing-Ke Shih pkt_stat->rx_snr[RF_PATH_A] = GET_PHY_STAT_P1_RXSNR_A(phy_status); 290158441a2SPing-Ke Shih pkt_stat->cfo_tail[RF_PATH_A] = GET_PHY_STAT_P1_CFO_TAIL_A(phy_status); 291158441a2SPing-Ke Shih 292158441a2SPing-Ke Shih dm_info->curr_rx_rate = pkt_stat->rate; 293158441a2SPing-Ke Shih dm_info->rssi[RF_PATH_A] = pkt_stat->rssi; 294158441a2SPing-Ke Shih dm_info->rx_snr[RF_PATH_A] = pkt_stat->rx_snr[RF_PATH_A] >> 1; 295158441a2SPing-Ke Shih dm_info->cfo_tail[RF_PATH_A] = (pkt_stat->cfo_tail[RF_PATH_A] * 5) >> 1; 296158441a2SPing-Ke Shih 297158441a2SPing-Ke Shih rx_evm = clamp_t(s8, -pkt_stat->rx_evm[RF_PATH_A] >> 1, 0, 64); 298158441a2SPing-Ke Shih rx_evm &= 0x3F; /* 64->0: second path of 1SS rate is 64 */ 299158441a2SPing-Ke Shih dm_info->rx_evm_dbm[RF_PATH_A] = rx_evm; 300158441a2SPing-Ke Shih } 301158441a2SPing-Ke Shih 302158441a2SPing-Ke Shih static void query_phy_status(struct rtw_dev *rtwdev, u8 *phy_status, 303158441a2SPing-Ke Shih struct rtw_rx_pkt_stat *pkt_stat) 304158441a2SPing-Ke Shih { 305158441a2SPing-Ke Shih u8 page; 306158441a2SPing-Ke Shih 307158441a2SPing-Ke Shih page = *phy_status & 0xf; 308158441a2SPing-Ke Shih 309158441a2SPing-Ke Shih switch (page) { 310158441a2SPing-Ke Shih case 0: 311158441a2SPing-Ke Shih query_phy_status_page0(rtwdev, phy_status, pkt_stat); 312158441a2SPing-Ke Shih break; 313158441a2SPing-Ke Shih case 1: 314158441a2SPing-Ke Shih query_phy_status_page1(rtwdev, phy_status, pkt_stat); 315158441a2SPing-Ke Shih break; 316158441a2SPing-Ke Shih default: 317158441a2SPing-Ke Shih rtw_warn(rtwdev, "unused phy status page (%d)\n", page); 318158441a2SPing-Ke Shih return; 319158441a2SPing-Ke Shih } 320158441a2SPing-Ke Shih } 321158441a2SPing-Ke Shih 322158441a2SPing-Ke Shih static void rtw8723d_query_rx_desc(struct rtw_dev *rtwdev, u8 *rx_desc, 323158441a2SPing-Ke Shih struct rtw_rx_pkt_stat *pkt_stat, 324158441a2SPing-Ke Shih struct ieee80211_rx_status *rx_status) 325158441a2SPing-Ke Shih { 326158441a2SPing-Ke Shih struct ieee80211_hdr *hdr; 327158441a2SPing-Ke Shih u32 desc_sz = rtwdev->chip->rx_pkt_desc_sz; 328158441a2SPing-Ke Shih u8 *phy_status = NULL; 329158441a2SPing-Ke Shih 330158441a2SPing-Ke Shih memset(pkt_stat, 0, sizeof(*pkt_stat)); 331158441a2SPing-Ke Shih 332158441a2SPing-Ke Shih pkt_stat->phy_status = GET_RX_DESC_PHYST(rx_desc); 333158441a2SPing-Ke Shih pkt_stat->icv_err = GET_RX_DESC_ICV_ERR(rx_desc); 334158441a2SPing-Ke Shih pkt_stat->crc_err = GET_RX_DESC_CRC32(rx_desc); 335158441a2SPing-Ke Shih pkt_stat->decrypted = !GET_RX_DESC_SWDEC(rx_desc) && 336158441a2SPing-Ke Shih GET_RX_DESC_ENC_TYPE(rx_desc) != RX_DESC_ENC_NONE; 337158441a2SPing-Ke Shih pkt_stat->is_c2h = GET_RX_DESC_C2H(rx_desc); 338158441a2SPing-Ke Shih pkt_stat->pkt_len = GET_RX_DESC_PKT_LEN(rx_desc); 339158441a2SPing-Ke Shih pkt_stat->drv_info_sz = GET_RX_DESC_DRV_INFO_SIZE(rx_desc); 340158441a2SPing-Ke Shih pkt_stat->shift = GET_RX_DESC_SHIFT(rx_desc); 341158441a2SPing-Ke Shih pkt_stat->rate = GET_RX_DESC_RX_RATE(rx_desc); 342158441a2SPing-Ke Shih pkt_stat->cam_id = GET_RX_DESC_MACID(rx_desc); 343158441a2SPing-Ke Shih pkt_stat->ppdu_cnt = 0; 344158441a2SPing-Ke Shih pkt_stat->tsf_low = GET_RX_DESC_TSFL(rx_desc); 345158441a2SPing-Ke Shih 346158441a2SPing-Ke Shih /* drv_info_sz is in unit of 8-bytes */ 347158441a2SPing-Ke Shih pkt_stat->drv_info_sz *= 8; 348158441a2SPing-Ke Shih 349158441a2SPing-Ke Shih /* c2h cmd pkt's rx/phy status is not interested */ 350158441a2SPing-Ke Shih if (pkt_stat->is_c2h) 351158441a2SPing-Ke Shih return; 352158441a2SPing-Ke Shih 353158441a2SPing-Ke Shih hdr = (struct ieee80211_hdr *)(rx_desc + desc_sz + pkt_stat->shift + 354158441a2SPing-Ke Shih pkt_stat->drv_info_sz); 355158441a2SPing-Ke Shih if (pkt_stat->phy_status) { 356158441a2SPing-Ke Shih phy_status = rx_desc + desc_sz + pkt_stat->shift; 357158441a2SPing-Ke Shih query_phy_status(rtwdev, phy_status, pkt_stat); 358158441a2SPing-Ke Shih } 359158441a2SPing-Ke Shih 360158441a2SPing-Ke Shih rtw_rx_fill_rx_status(rtwdev, pkt_stat, hdr, rx_status, phy_status); 361158441a2SPing-Ke Shih } 362158441a2SPing-Ke Shih 3635f028a9cSPing-Ke Shih static bool rtw8723d_check_spur_ov_thres(struct rtw_dev *rtwdev, 3645f028a9cSPing-Ke Shih u8 channel, u32 thres) 3655f028a9cSPing-Ke Shih { 3665f028a9cSPing-Ke Shih u32 freq; 3675f028a9cSPing-Ke Shih bool ret = false; 3685f028a9cSPing-Ke Shih 3695f028a9cSPing-Ke Shih if (channel == 13) 3705f028a9cSPing-Ke Shih freq = FREQ_CH13; 3715f028a9cSPing-Ke Shih else if (channel == 14) 3725f028a9cSPing-Ke Shih freq = FREQ_CH14; 3735f028a9cSPing-Ke Shih else 3745f028a9cSPing-Ke Shih return false; 3755f028a9cSPing-Ke Shih 3765f028a9cSPing-Ke Shih rtw_write32(rtwdev, REG_ANALOG_P4, DIS_3WIRE); 3775f028a9cSPing-Ke Shih rtw_write32(rtwdev, REG_PSDFN, freq); 3785f028a9cSPing-Ke Shih rtw_write32(rtwdev, REG_PSDFN, START_PSD | freq); 3795f028a9cSPing-Ke Shih 3805f028a9cSPing-Ke Shih msleep(30); 3815f028a9cSPing-Ke Shih if (rtw_read32(rtwdev, REG_PSDRPT) >= thres) 3825f028a9cSPing-Ke Shih ret = true; 3835f028a9cSPing-Ke Shih 3845f028a9cSPing-Ke Shih rtw_write32(rtwdev, REG_PSDFN, freq); 3855f028a9cSPing-Ke Shih rtw_write32(rtwdev, REG_ANALOG_P4, EN_3WIRE); 3865f028a9cSPing-Ke Shih 3875f028a9cSPing-Ke Shih return ret; 3885f028a9cSPing-Ke Shih } 3895f028a9cSPing-Ke Shih 3905f028a9cSPing-Ke Shih static void rtw8723d_cfg_notch(struct rtw_dev *rtwdev, u8 channel, bool notch) 3915f028a9cSPing-Ke Shih { 3925f028a9cSPing-Ke Shih if (!notch) { 3935f028a9cSPing-Ke Shih rtw_write32_mask(rtwdev, REG_OFDM0_RXDSP, BIT_MASK_RXDSP, 0x1f); 3945f028a9cSPing-Ke Shih rtw_write32_mask(rtwdev, REG_OFDM0_RXDSP, BIT_EN_RXDSP, 0x0); 3955f028a9cSPing-Ke Shih rtw_write32(rtwdev, REG_OFDM1_CSI1, 0x00000000); 3965f028a9cSPing-Ke Shih rtw_write32(rtwdev, REG_OFDM1_CSI2, 0x00000000); 3975f028a9cSPing-Ke Shih rtw_write32(rtwdev, REG_OFDM1_CSI3, 0x00000000); 3985f028a9cSPing-Ke Shih rtw_write32(rtwdev, REG_OFDM1_CSI4, 0x00000000); 3995f028a9cSPing-Ke Shih rtw_write32_mask(rtwdev, REG_OFDM1_CFOTRK, BIT_EN_CFOTRK, 0x0); 4005f028a9cSPing-Ke Shih return; 4015f028a9cSPing-Ke Shih } 4025f028a9cSPing-Ke Shih 4035f028a9cSPing-Ke Shih switch (channel) { 4045f028a9cSPing-Ke Shih case 13: 4055f028a9cSPing-Ke Shih rtw_write32_mask(rtwdev, REG_OFDM0_RXDSP, BIT_MASK_RXDSP, 0xb); 4065f028a9cSPing-Ke Shih rtw_write32_mask(rtwdev, REG_OFDM0_RXDSP, BIT_EN_RXDSP, 0x1); 4075f028a9cSPing-Ke Shih rtw_write32(rtwdev, REG_OFDM1_CSI1, 0x04000000); 4085f028a9cSPing-Ke Shih rtw_write32(rtwdev, REG_OFDM1_CSI2, 0x00000000); 4095f028a9cSPing-Ke Shih rtw_write32(rtwdev, REG_OFDM1_CSI3, 0x00000000); 4105f028a9cSPing-Ke Shih rtw_write32(rtwdev, REG_OFDM1_CSI4, 0x00000000); 4115f028a9cSPing-Ke Shih rtw_write32_mask(rtwdev, REG_OFDM1_CFOTRK, BIT_EN_CFOTRK, 0x1); 4125f028a9cSPing-Ke Shih break; 4135f028a9cSPing-Ke Shih case 14: 4145f028a9cSPing-Ke Shih rtw_write32_mask(rtwdev, REG_OFDM0_RXDSP, BIT_MASK_RXDSP, 0x5); 4155f028a9cSPing-Ke Shih rtw_write32_mask(rtwdev, REG_OFDM0_RXDSP, BIT_EN_RXDSP, 0x1); 4165f028a9cSPing-Ke Shih rtw_write32(rtwdev, REG_OFDM1_CSI1, 0x00000000); 4175f028a9cSPing-Ke Shih rtw_write32(rtwdev, REG_OFDM1_CSI2, 0x00000000); 4185f028a9cSPing-Ke Shih rtw_write32(rtwdev, REG_OFDM1_CSI3, 0x00000000); 4195f028a9cSPing-Ke Shih rtw_write32(rtwdev, REG_OFDM1_CSI4, 0x00080000); 4205f028a9cSPing-Ke Shih rtw_write32_mask(rtwdev, REG_OFDM1_CFOTRK, BIT_EN_CFOTRK, 0x1); 4215f028a9cSPing-Ke Shih break; 4225f028a9cSPing-Ke Shih default: 4235f028a9cSPing-Ke Shih rtw_write32_mask(rtwdev, REG_OFDM0_RXDSP, BIT_EN_RXDSP, 0x0); 4245f028a9cSPing-Ke Shih rtw_write32_mask(rtwdev, REG_OFDM1_CFOTRK, BIT_EN_CFOTRK, 0x0); 4255f028a9cSPing-Ke Shih break; 4265f028a9cSPing-Ke Shih } 4275f028a9cSPing-Ke Shih } 4285f028a9cSPing-Ke Shih 4295f028a9cSPing-Ke Shih static void rtw8723d_spur_cal(struct rtw_dev *rtwdev, u8 channel) 4305f028a9cSPing-Ke Shih { 4315f028a9cSPing-Ke Shih bool notch; 4325f028a9cSPing-Ke Shih 4335f028a9cSPing-Ke Shih if (channel < 13) { 4345f028a9cSPing-Ke Shih rtw8723d_cfg_notch(rtwdev, channel, false); 4355f028a9cSPing-Ke Shih return; 4365f028a9cSPing-Ke Shih } 4375f028a9cSPing-Ke Shih 4385f028a9cSPing-Ke Shih notch = rtw8723d_check_spur_ov_thres(rtwdev, channel, SPUR_THRES); 4395f028a9cSPing-Ke Shih rtw8723d_cfg_notch(rtwdev, channel, notch); 4405f028a9cSPing-Ke Shih } 4415f028a9cSPing-Ke Shih 4425f028a9cSPing-Ke Shih static void rtw8723d_set_channel_rf(struct rtw_dev *rtwdev, u8 channel, u8 bw) 4435f028a9cSPing-Ke Shih { 4445f028a9cSPing-Ke Shih u32 rf_cfgch_a, rf_cfgch_b; 4455f028a9cSPing-Ke Shih 4465f028a9cSPing-Ke Shih rf_cfgch_a = rtw_read_rf(rtwdev, RF_PATH_A, RF_CFGCH, RFREG_MASK); 4475f028a9cSPing-Ke Shih rf_cfgch_b = rtw_read_rf(rtwdev, RF_PATH_B, RF_CFGCH, RFREG_MASK); 4485f028a9cSPing-Ke Shih 4495f028a9cSPing-Ke Shih rf_cfgch_a &= ~RFCFGCH_CHANNEL_MASK; 4505f028a9cSPing-Ke Shih rf_cfgch_b &= ~RFCFGCH_CHANNEL_MASK; 4515f028a9cSPing-Ke Shih rf_cfgch_a |= (channel & RFCFGCH_CHANNEL_MASK); 4525f028a9cSPing-Ke Shih rf_cfgch_b |= (channel & RFCFGCH_CHANNEL_MASK); 4535f028a9cSPing-Ke Shih 4545f028a9cSPing-Ke Shih rf_cfgch_a &= ~RFCFGCH_BW_MASK; 4555f028a9cSPing-Ke Shih switch (bw) { 4565f028a9cSPing-Ke Shih case RTW_CHANNEL_WIDTH_20: 4575f028a9cSPing-Ke Shih rf_cfgch_a |= RFCFGCH_BW_20M; 4585f028a9cSPing-Ke Shih break; 4595f028a9cSPing-Ke Shih case RTW_CHANNEL_WIDTH_40: 4605f028a9cSPing-Ke Shih rf_cfgch_a |= RFCFGCH_BW_40M; 4615f028a9cSPing-Ke Shih break; 4625f028a9cSPing-Ke Shih default: 4635f028a9cSPing-Ke Shih break; 4645f028a9cSPing-Ke Shih } 4655f028a9cSPing-Ke Shih 4665f028a9cSPing-Ke Shih rtw_write_rf(rtwdev, RF_PATH_A, RF_CFGCH, RFREG_MASK, rf_cfgch_a); 4675f028a9cSPing-Ke Shih rtw_write_rf(rtwdev, RF_PATH_B, RF_CFGCH, RFREG_MASK, rf_cfgch_b); 4685f028a9cSPing-Ke Shih 4695f028a9cSPing-Ke Shih rtw8723d_spur_cal(rtwdev, channel); 4705f028a9cSPing-Ke Shih } 4715f028a9cSPing-Ke Shih 4725f028a9cSPing-Ke Shih static const struct rtw_backup_info cck_dfir_cfg[][CCK_DFIR_NR] = { 4735f028a9cSPing-Ke Shih [0] = { 4745f028a9cSPing-Ke Shih { .len = 4, .reg = 0xA24, .val = 0x64B80C1C }, 4755f028a9cSPing-Ke Shih { .len = 4, .reg = 0xA28, .val = 0x00008810 }, 4765f028a9cSPing-Ke Shih { .len = 4, .reg = 0xAAC, .val = 0x01235667 }, 4775f028a9cSPing-Ke Shih }, 4785f028a9cSPing-Ke Shih [1] = { 4795f028a9cSPing-Ke Shih { .len = 4, .reg = 0xA24, .val = 0x0000B81C }, 4805f028a9cSPing-Ke Shih { .len = 4, .reg = 0xA28, .val = 0x00000000 }, 4815f028a9cSPing-Ke Shih { .len = 4, .reg = 0xAAC, .val = 0x00003667 }, 4825f028a9cSPing-Ke Shih }, 4835f028a9cSPing-Ke Shih }; 4845f028a9cSPing-Ke Shih 4855f028a9cSPing-Ke Shih static void rtw8723d_set_channel_bb(struct rtw_dev *rtwdev, u8 channel, u8 bw, 4865f028a9cSPing-Ke Shih u8 primary_ch_idx) 4875f028a9cSPing-Ke Shih { 4885f028a9cSPing-Ke Shih const struct rtw_backup_info *cck_dfir; 4895f028a9cSPing-Ke Shih int i; 4905f028a9cSPing-Ke Shih 4915f028a9cSPing-Ke Shih cck_dfir = channel <= 13 ? cck_dfir_cfg[0] : cck_dfir_cfg[1]; 4925f028a9cSPing-Ke Shih 4935f028a9cSPing-Ke Shih for (i = 0; i < CCK_DFIR_NR; i++, cck_dfir++) 4945f028a9cSPing-Ke Shih rtw_write32(rtwdev, cck_dfir->reg, cck_dfir->val); 4955f028a9cSPing-Ke Shih 4965f028a9cSPing-Ke Shih switch (bw) { 4975f028a9cSPing-Ke Shih case RTW_CHANNEL_WIDTH_20: 4985f028a9cSPing-Ke Shih rtw_write32_mask(rtwdev, REG_FPGA0_RFMOD, BIT_MASK_RFMOD, 0x0); 4995f028a9cSPing-Ke Shih rtw_write32_mask(rtwdev, REG_FPGA1_RFMOD, BIT_MASK_RFMOD, 0x0); 5005f028a9cSPing-Ke Shih rtw_write32_mask(rtwdev, REG_BBRX_DFIR, BIT_RXBB_DFIR_EN, 1); 5015f028a9cSPing-Ke Shih rtw_write32_mask(rtwdev, REG_BBRX_DFIR, BIT_MASK_RXBB_DFIR, 0xa); 5025f028a9cSPing-Ke Shih break; 5035f028a9cSPing-Ke Shih case RTW_CHANNEL_WIDTH_40: 5045f028a9cSPing-Ke Shih rtw_write32_mask(rtwdev, REG_FPGA0_RFMOD, BIT_MASK_RFMOD, 0x1); 5055f028a9cSPing-Ke Shih rtw_write32_mask(rtwdev, REG_FPGA1_RFMOD, BIT_MASK_RFMOD, 0x1); 5065f028a9cSPing-Ke Shih rtw_write32_mask(rtwdev, REG_BBRX_DFIR, BIT_RXBB_DFIR_EN, 0); 5075f028a9cSPing-Ke Shih rtw_write32_mask(rtwdev, REG_CCK0_SYS, BIT_CCK_SIDE_BAND, 5085f028a9cSPing-Ke Shih (primary_ch_idx == RTW_SC_20_UPPER ? 1 : 0)); 5095f028a9cSPing-Ke Shih break; 5105f028a9cSPing-Ke Shih default: 5115f028a9cSPing-Ke Shih break; 5125f028a9cSPing-Ke Shih } 5135f028a9cSPing-Ke Shih } 5145f028a9cSPing-Ke Shih 5155f028a9cSPing-Ke Shih static void rtw8723d_set_channel(struct rtw_dev *rtwdev, u8 channel, u8 bw, 5165f028a9cSPing-Ke Shih u8 primary_chan_idx) 5175f028a9cSPing-Ke Shih { 5185f028a9cSPing-Ke Shih rtw8723d_set_channel_rf(rtwdev, channel, bw); 5195f028a9cSPing-Ke Shih rtw_set_channel_mac(rtwdev, channel, bw, primary_chan_idx); 5205f028a9cSPing-Ke Shih rtw8723d_set_channel_bb(rtwdev, channel, bw, primary_chan_idx); 5215f028a9cSPing-Ke Shih } 5225f028a9cSPing-Ke Shih 52375e69fb1SPing-Ke Shih #define BIT_CFENDFORM BIT(9) 52475e69fb1SPing-Ke Shih #define BIT_WMAC_TCR_ERR0 BIT(12) 52575e69fb1SPing-Ke Shih #define BIT_WMAC_TCR_ERR1 BIT(13) 52675e69fb1SPing-Ke Shih #define BIT_TCR_CFG (BIT_CFENDFORM | BIT_WMAC_TCR_ERR0 | \ 52775e69fb1SPing-Ke Shih BIT_WMAC_TCR_ERR1) 52875e69fb1SPing-Ke Shih #define WLAN_RX_FILTER0 0xFFFF 52975e69fb1SPing-Ke Shih #define WLAN_RX_FILTER1 0x400 53075e69fb1SPing-Ke Shih #define WLAN_RX_FILTER2 0xFFFF 53175e69fb1SPing-Ke Shih #define WLAN_RCR_CFG 0x700060CE 53275e69fb1SPing-Ke Shih 53375e69fb1SPing-Ke Shih static int rtw8723d_mac_init(struct rtw_dev *rtwdev) 53475e69fb1SPing-Ke Shih { 53575e69fb1SPing-Ke Shih rtw_write8(rtwdev, REG_FWHW_TXQ_CTRL + 1, WLAN_TXQ_RPT_EN); 53675e69fb1SPing-Ke Shih rtw_write32(rtwdev, REG_TCR, BIT_TCR_CFG); 53775e69fb1SPing-Ke Shih 53875e69fb1SPing-Ke Shih rtw_write16(rtwdev, REG_RXFLTMAP0, WLAN_RX_FILTER0); 53975e69fb1SPing-Ke Shih rtw_write16(rtwdev, REG_RXFLTMAP1, WLAN_RX_FILTER1); 54075e69fb1SPing-Ke Shih rtw_write16(rtwdev, REG_RXFLTMAP2, WLAN_RX_FILTER2); 54175e69fb1SPing-Ke Shih rtw_write32(rtwdev, REG_RCR, WLAN_RCR_CFG); 54275e69fb1SPing-Ke Shih 54375e69fb1SPing-Ke Shih rtw_write32(rtwdev, REG_INT_MIG, 0); 54475e69fb1SPing-Ke Shih rtw_write32(rtwdev, REG_MCUTST_1, 0x0); 54575e69fb1SPing-Ke Shih 54675e69fb1SPing-Ke Shih rtw_write8(rtwdev, REG_MISC_CTRL, BIT_DIS_SECOND_CCA); 54775e69fb1SPing-Ke Shih rtw_write8(rtwdev, REG_2ND_CCA_CTRL, 0); 54875e69fb1SPing-Ke Shih 54975e69fb1SPing-Ke Shih return 0; 55075e69fb1SPing-Ke Shih } 55175e69fb1SPing-Ke Shih 55205202746SPing-Ke Shih static void rtw8723d_shutdown(struct rtw_dev *rtwdev) 55305202746SPing-Ke Shih { 55405202746SPing-Ke Shih rtw_write16_set(rtwdev, REG_HCI_OPT_CTRL, BIT_USB_SUS_DIS); 55505202746SPing-Ke Shih } 55605202746SPing-Ke Shih 5571afb5eb7SPing-Ke Shih static void rtw8723d_cfg_ldo25(struct rtw_dev *rtwdev, bool enable) 5581afb5eb7SPing-Ke Shih { 5591afb5eb7SPing-Ke Shih u8 ldo_pwr; 5601afb5eb7SPing-Ke Shih 5611afb5eb7SPing-Ke Shih ldo_pwr = rtw_read8(rtwdev, REG_LDO_EFUSE_CTRL + 3); 5621afb5eb7SPing-Ke Shih if (enable) { 5631afb5eb7SPing-Ke Shih ldo_pwr &= ~BIT_MASK_LDO25_VOLTAGE; 5641afb5eb7SPing-Ke Shih ldo_pwr = (BIT_LDO25_VOLTAGE_V25 << 4) | BIT_LDO25_EN; 5651afb5eb7SPing-Ke Shih } else { 5661afb5eb7SPing-Ke Shih ldo_pwr &= ~BIT_LDO25_EN; 5671afb5eb7SPing-Ke Shih } 5681afb5eb7SPing-Ke Shih rtw_write8(rtwdev, REG_LDO_EFUSE_CTRL + 3, ldo_pwr); 5691afb5eb7SPing-Ke Shih } 5701afb5eb7SPing-Ke Shih 571ba9f0d1bSPing-Ke Shih static void 572ba9f0d1bSPing-Ke Shih rtw8723d_set_tx_power_index_by_rate(struct rtw_dev *rtwdev, u8 path, u8 rs) 573ba9f0d1bSPing-Ke Shih { 574ba9f0d1bSPing-Ke Shih struct rtw_hal *hal = &rtwdev->hal; 575ba9f0d1bSPing-Ke Shih const struct rtw_hw_reg *txagc; 576ba9f0d1bSPing-Ke Shih u8 rate, pwr_index; 577ba9f0d1bSPing-Ke Shih int j; 578ba9f0d1bSPing-Ke Shih 579ba9f0d1bSPing-Ke Shih for (j = 0; j < rtw_rate_size[rs]; j++) { 580ba9f0d1bSPing-Ke Shih rate = rtw_rate_section[rs][j]; 581ba9f0d1bSPing-Ke Shih pwr_index = hal->tx_pwr_tbl[path][rate]; 582ba9f0d1bSPing-Ke Shih 583ba9f0d1bSPing-Ke Shih if (rate >= ARRAY_SIZE(rtw8723d_txagc)) { 584ba9f0d1bSPing-Ke Shih rtw_warn(rtwdev, "rate 0x%x isn't supported\n", rate); 585ba9f0d1bSPing-Ke Shih continue; 586ba9f0d1bSPing-Ke Shih } 587ba9f0d1bSPing-Ke Shih txagc = &rtw8723d_txagc[rate]; 588ba9f0d1bSPing-Ke Shih if (!txagc->addr) { 589ba9f0d1bSPing-Ke Shih rtw_warn(rtwdev, "rate 0x%x isn't defined\n", rate); 590ba9f0d1bSPing-Ke Shih continue; 591ba9f0d1bSPing-Ke Shih } 592ba9f0d1bSPing-Ke Shih 593ba9f0d1bSPing-Ke Shih rtw_write32_mask(rtwdev, txagc->addr, txagc->mask, pwr_index); 594ba9f0d1bSPing-Ke Shih } 595ba9f0d1bSPing-Ke Shih } 596ba9f0d1bSPing-Ke Shih 597ba9f0d1bSPing-Ke Shih static void rtw8723d_set_tx_power_index(struct rtw_dev *rtwdev) 598ba9f0d1bSPing-Ke Shih { 599ba9f0d1bSPing-Ke Shih struct rtw_hal *hal = &rtwdev->hal; 600ba9f0d1bSPing-Ke Shih int rs, path; 601ba9f0d1bSPing-Ke Shih 602ba9f0d1bSPing-Ke Shih for (path = 0; path < hal->rf_path_num; path++) { 603ba9f0d1bSPing-Ke Shih for (rs = 0; rs <= RTW_RATE_SECTION_HT_1S; rs++) 604ba9f0d1bSPing-Ke Shih rtw8723d_set_tx_power_index_by_rate(rtwdev, path, rs); 605ba9f0d1bSPing-Ke Shih } 606ba9f0d1bSPing-Ke Shih } 607ba9f0d1bSPing-Ke Shih 60844baa97cSPing-Ke Shih static void rtw8723d_efuse_grant(struct rtw_dev *rtwdev, bool on) 60944baa97cSPing-Ke Shih { 61044baa97cSPing-Ke Shih if (on) { 61144baa97cSPing-Ke Shih rtw_write8(rtwdev, REG_EFUSE_ACCESS, EFUSE_ACCESS_ON); 61244baa97cSPing-Ke Shih 61344baa97cSPing-Ke Shih rtw_write16_set(rtwdev, REG_SYS_FUNC_EN, BIT_FEN_ELDR); 61444baa97cSPing-Ke Shih rtw_write16_set(rtwdev, REG_SYS_CLKR, BIT_LOADER_CLK_EN | BIT_ANA8M); 61544baa97cSPing-Ke Shih } else { 61644baa97cSPing-Ke Shih rtw_write8(rtwdev, REG_EFUSE_ACCESS, EFUSE_ACCESS_OFF); 61744baa97cSPing-Ke Shih } 61844baa97cSPing-Ke Shih } 61944baa97cSPing-Ke Shih 620439d4a97SPing-Ke Shih static void rtw8723d_false_alarm_statistics(struct rtw_dev *rtwdev) 621439d4a97SPing-Ke Shih { 622439d4a97SPing-Ke Shih struct rtw_dm_info *dm_info = &rtwdev->dm_info; 623439d4a97SPing-Ke Shih u32 cck_fa_cnt; 624439d4a97SPing-Ke Shih u32 ofdm_fa_cnt; 625439d4a97SPing-Ke Shih u32 crc32_cnt; 626439d4a97SPing-Ke Shih u32 val32; 627439d4a97SPing-Ke Shih 628439d4a97SPing-Ke Shih /* hold counter */ 629439d4a97SPing-Ke Shih rtw_write32_mask(rtwdev, REG_OFDM_FA_HOLDC_11N, BIT_MASK_OFDM_FA_KEEP, 1); 630439d4a97SPing-Ke Shih rtw_write32_mask(rtwdev, REG_OFDM_FA_RSTD_11N, BIT_MASK_OFDM_FA_KEEP1, 1); 631439d4a97SPing-Ke Shih rtw_write32_mask(rtwdev, REG_CCK_FA_RST_11N, BIT_MASK_CCK_CNT_KEEP, 1); 632439d4a97SPing-Ke Shih rtw_write32_mask(rtwdev, REG_CCK_FA_RST_11N, BIT_MASK_CCK_FA_KEEP, 1); 633439d4a97SPing-Ke Shih 634439d4a97SPing-Ke Shih cck_fa_cnt = rtw_read32_mask(rtwdev, REG_CCK_FA_LSB_11N, MASKBYTE0); 635439d4a97SPing-Ke Shih cck_fa_cnt += rtw_read32_mask(rtwdev, REG_CCK_FA_MSB_11N, MASKBYTE3) << 8; 636439d4a97SPing-Ke Shih 637439d4a97SPing-Ke Shih val32 = rtw_read32(rtwdev, REG_OFDM_FA_TYPE1_11N); 638439d4a97SPing-Ke Shih ofdm_fa_cnt = u32_get_bits(val32, BIT_MASK_OFDM_FF_CNT); 639439d4a97SPing-Ke Shih ofdm_fa_cnt += u32_get_bits(val32, BIT_MASK_OFDM_SF_CNT); 640439d4a97SPing-Ke Shih val32 = rtw_read32(rtwdev, REG_OFDM_FA_TYPE2_11N); 641439d4a97SPing-Ke Shih dm_info->ofdm_cca_cnt = u32_get_bits(val32, BIT_MASK_OFDM_CCA_CNT); 642439d4a97SPing-Ke Shih ofdm_fa_cnt += u32_get_bits(val32, BIT_MASK_OFDM_PF_CNT); 643439d4a97SPing-Ke Shih val32 = rtw_read32(rtwdev, REG_OFDM_FA_TYPE3_11N); 644439d4a97SPing-Ke Shih ofdm_fa_cnt += u32_get_bits(val32, BIT_MASK_OFDM_RI_CNT); 645439d4a97SPing-Ke Shih ofdm_fa_cnt += u32_get_bits(val32, BIT_MASK_OFDM_CRC_CNT); 646439d4a97SPing-Ke Shih val32 = rtw_read32(rtwdev, REG_OFDM_FA_TYPE4_11N); 647439d4a97SPing-Ke Shih ofdm_fa_cnt += u32_get_bits(val32, BIT_MASK_OFDM_MNS_CNT); 648439d4a97SPing-Ke Shih 649439d4a97SPing-Ke Shih dm_info->cck_fa_cnt = cck_fa_cnt; 650439d4a97SPing-Ke Shih dm_info->ofdm_fa_cnt = ofdm_fa_cnt; 651439d4a97SPing-Ke Shih dm_info->total_fa_cnt = cck_fa_cnt + ofdm_fa_cnt; 652439d4a97SPing-Ke Shih 653439d4a97SPing-Ke Shih dm_info->cck_err_cnt = rtw_read32(rtwdev, REG_IGI_C_11N); 654439d4a97SPing-Ke Shih dm_info->cck_ok_cnt = rtw_read32(rtwdev, REG_IGI_D_11N); 655439d4a97SPing-Ke Shih crc32_cnt = rtw_read32(rtwdev, REG_OFDM_CRC32_CNT_11N); 656439d4a97SPing-Ke Shih dm_info->ofdm_err_cnt = u32_get_bits(crc32_cnt, BIT_MASK_OFDM_LCRC_ERR); 657439d4a97SPing-Ke Shih dm_info->ofdm_ok_cnt = u32_get_bits(crc32_cnt, BIT_MASK_OFDM_LCRC_OK); 658439d4a97SPing-Ke Shih crc32_cnt = rtw_read32(rtwdev, REG_HT_CRC32_CNT_11N); 659439d4a97SPing-Ke Shih dm_info->ht_err_cnt = u32_get_bits(crc32_cnt, BIT_MASK_HT_CRC_ERR); 660439d4a97SPing-Ke Shih dm_info->ht_ok_cnt = u32_get_bits(crc32_cnt, BIT_MASK_HT_CRC_OK); 661439d4a97SPing-Ke Shih dm_info->vht_err_cnt = 0; 662439d4a97SPing-Ke Shih dm_info->vht_ok_cnt = 0; 663439d4a97SPing-Ke Shih 664439d4a97SPing-Ke Shih val32 = rtw_read32(rtwdev, REG_CCK_CCA_CNT_11N); 665439d4a97SPing-Ke Shih dm_info->cck_cca_cnt = (u32_get_bits(val32, BIT_MASK_CCK_FA_MSB) << 8) | 666439d4a97SPing-Ke Shih u32_get_bits(val32, BIT_MASK_CCK_FA_LSB); 667439d4a97SPing-Ke Shih dm_info->total_cca_cnt = dm_info->cck_cca_cnt + dm_info->ofdm_cca_cnt; 668439d4a97SPing-Ke Shih 669439d4a97SPing-Ke Shih /* reset counter */ 670439d4a97SPing-Ke Shih rtw_write32_mask(rtwdev, REG_OFDM_FA_RSTC_11N, BIT_MASK_OFDM_FA_RST, 1); 671439d4a97SPing-Ke Shih rtw_write32_mask(rtwdev, REG_OFDM_FA_RSTC_11N, BIT_MASK_OFDM_FA_RST, 0); 672439d4a97SPing-Ke Shih rtw_write32_mask(rtwdev, REG_OFDM_FA_RSTD_11N, BIT_MASK_OFDM_FA_RST1, 1); 673439d4a97SPing-Ke Shih rtw_write32_mask(rtwdev, REG_OFDM_FA_RSTD_11N, BIT_MASK_OFDM_FA_RST1, 0); 674439d4a97SPing-Ke Shih rtw_write32_mask(rtwdev, REG_OFDM_FA_HOLDC_11N, BIT_MASK_OFDM_FA_KEEP, 0); 675439d4a97SPing-Ke Shih rtw_write32_mask(rtwdev, REG_OFDM_FA_RSTD_11N, BIT_MASK_OFDM_FA_KEEP1, 0); 676439d4a97SPing-Ke Shih rtw_write32_mask(rtwdev, REG_CCK_FA_RST_11N, BIT_MASK_CCK_CNT_KPEN, 0); 677439d4a97SPing-Ke Shih rtw_write32_mask(rtwdev, REG_CCK_FA_RST_11N, BIT_MASK_CCK_CNT_KPEN, 2); 678439d4a97SPing-Ke Shih rtw_write32_mask(rtwdev, REG_CCK_FA_RST_11N, BIT_MASK_CCK_FA_KPEN, 0); 679439d4a97SPing-Ke Shih rtw_write32_mask(rtwdev, REG_CCK_FA_RST_11N, BIT_MASK_CCK_FA_KPEN, 2); 680439d4a97SPing-Ke Shih rtw_write32_mask(rtwdev, REG_PAGE_F_RST_11N, BIT_MASK_F_RST_ALL, 1); 681439d4a97SPing-Ke Shih rtw_write32_mask(rtwdev, REG_PAGE_F_RST_11N, BIT_MASK_F_RST_ALL, 0); 682439d4a97SPing-Ke Shih } 683439d4a97SPing-Ke Shih 6841d229e88SPing-Ke Shih static const u32 iqk_adda_regs[] = { 6851d229e88SPing-Ke Shih 0x85c, 0xe6c, 0xe70, 0xe74, 0xe78, 0xe7c, 0xe80, 0xe84, 0xe88, 0xe8c, 6861d229e88SPing-Ke Shih 0xed0, 0xed4, 0xed8, 0xedc, 0xee0, 0xeec 6871d229e88SPing-Ke Shih }; 6881d229e88SPing-Ke Shih 6891d229e88SPing-Ke Shih static const u32 iqk_mac8_regs[] = {0x522, 0x550, 0x551}; 6901d229e88SPing-Ke Shih static const u32 iqk_mac32_regs[] = {0x40}; 6911d229e88SPing-Ke Shih 6921d229e88SPing-Ke Shih static const u32 iqk_bb_regs[] = { 6931d229e88SPing-Ke Shih 0xc04, 0xc08, 0x874, 0xb68, 0xb6c, 0x870, 0x860, 0x864, 0xa04 6941d229e88SPing-Ke Shih }; 6951d229e88SPing-Ke Shih 6961d229e88SPing-Ke Shih #define IQK_ADDA_REG_NUM ARRAY_SIZE(iqk_adda_regs) 6971d229e88SPing-Ke Shih #define IQK_MAC8_REG_NUM ARRAY_SIZE(iqk_mac8_regs) 6981d229e88SPing-Ke Shih #define IQK_MAC32_REG_NUM ARRAY_SIZE(iqk_mac32_regs) 6991d229e88SPing-Ke Shih #define IQK_BB_REG_NUM ARRAY_SIZE(iqk_bb_regs) 7001d229e88SPing-Ke Shih 7011d229e88SPing-Ke Shih struct iqk_backup_regs { 7021d229e88SPing-Ke Shih u32 adda[IQK_ADDA_REG_NUM]; 7031d229e88SPing-Ke Shih u8 mac8[IQK_MAC8_REG_NUM]; 7041d229e88SPing-Ke Shih u32 mac32[IQK_MAC32_REG_NUM]; 7051d229e88SPing-Ke Shih u32 bb[IQK_BB_REG_NUM]; 7061d229e88SPing-Ke Shih 7071d229e88SPing-Ke Shih u32 lte_path; 7081d229e88SPing-Ke Shih u32 lte_gnt; 7091d229e88SPing-Ke Shih 7101d229e88SPing-Ke Shih u32 bb_sel_btg; 7111d229e88SPing-Ke Shih u8 btg_sel; 7121d229e88SPing-Ke Shih 7131d229e88SPing-Ke Shih u8 igia; 7141d229e88SPing-Ke Shih u8 igib; 7151d229e88SPing-Ke Shih }; 7161d229e88SPing-Ke Shih 7171d229e88SPing-Ke Shih static void rtw8723d_iqk_backup_regs(struct rtw_dev *rtwdev, 7181d229e88SPing-Ke Shih struct iqk_backup_regs *backup) 7191d229e88SPing-Ke Shih { 7201d229e88SPing-Ke Shih int i; 7211d229e88SPing-Ke Shih 7221d229e88SPing-Ke Shih for (i = 0; i < IQK_ADDA_REG_NUM; i++) 7231d229e88SPing-Ke Shih backup->adda[i] = rtw_read32(rtwdev, iqk_adda_regs[i]); 7241d229e88SPing-Ke Shih 7251d229e88SPing-Ke Shih for (i = 0; i < IQK_MAC8_REG_NUM; i++) 7261d229e88SPing-Ke Shih backup->mac8[i] = rtw_read8(rtwdev, iqk_mac8_regs[i]); 7271d229e88SPing-Ke Shih for (i = 0; i < IQK_MAC32_REG_NUM; i++) 7281d229e88SPing-Ke Shih backup->mac32[i] = rtw_read32(rtwdev, iqk_mac32_regs[i]); 7291d229e88SPing-Ke Shih 7301d229e88SPing-Ke Shih for (i = 0; i < IQK_BB_REG_NUM; i++) 7311d229e88SPing-Ke Shih backup->bb[i] = rtw_read32(rtwdev, iqk_bb_regs[i]); 7321d229e88SPing-Ke Shih 7331d229e88SPing-Ke Shih backup->igia = rtw_read32_mask(rtwdev, REG_OFDM0_XAAGC1, MASKBYTE0); 7341d229e88SPing-Ke Shih backup->igib = rtw_read32_mask(rtwdev, REG_OFDM0_XBAGC1, MASKBYTE0); 7351d229e88SPing-Ke Shih 7361d229e88SPing-Ke Shih backup->bb_sel_btg = rtw_read32(rtwdev, REG_BB_SEL_BTG); 7371d229e88SPing-Ke Shih } 7381d229e88SPing-Ke Shih 7391d229e88SPing-Ke Shih static void rtw8723d_iqk_restore_regs(struct rtw_dev *rtwdev, 7401d229e88SPing-Ke Shih const struct iqk_backup_regs *backup) 7411d229e88SPing-Ke Shih { 7421d229e88SPing-Ke Shih int i; 7431d229e88SPing-Ke Shih 7441d229e88SPing-Ke Shih for (i = 0; i < IQK_ADDA_REG_NUM; i++) 7451d229e88SPing-Ke Shih rtw_write32(rtwdev, iqk_adda_regs[i], backup->adda[i]); 7461d229e88SPing-Ke Shih 7471d229e88SPing-Ke Shih for (i = 0; i < IQK_MAC8_REG_NUM; i++) 7481d229e88SPing-Ke Shih rtw_write8(rtwdev, iqk_mac8_regs[i], backup->mac8[i]); 7491d229e88SPing-Ke Shih for (i = 0; i < IQK_MAC32_REG_NUM; i++) 7501d229e88SPing-Ke Shih rtw_write32(rtwdev, iqk_mac32_regs[i], backup->mac32[i]); 7511d229e88SPing-Ke Shih 7521d229e88SPing-Ke Shih for (i = 0; i < IQK_BB_REG_NUM; i++) 7531d229e88SPing-Ke Shih rtw_write32(rtwdev, iqk_bb_regs[i], backup->bb[i]); 7541d229e88SPing-Ke Shih 7551d229e88SPing-Ke Shih rtw_write32_mask(rtwdev, REG_OFDM0_XAAGC1, MASKBYTE0, 0x50); 7561d229e88SPing-Ke Shih rtw_write32_mask(rtwdev, REG_OFDM0_XAAGC1, MASKBYTE0, backup->igia); 7571d229e88SPing-Ke Shih 7581d229e88SPing-Ke Shih rtw_write32_mask(rtwdev, REG_OFDM0_XBAGC1, MASKBYTE0, 0x50); 7591d229e88SPing-Ke Shih rtw_write32_mask(rtwdev, REG_OFDM0_XBAGC1, MASKBYTE0, backup->igib); 7601d229e88SPing-Ke Shih 7611d229e88SPing-Ke Shih rtw_write32(rtwdev, REG_TXIQK_TONE_A_11N, 0x01008c00); 7621d229e88SPing-Ke Shih rtw_write32(rtwdev, REG_RXIQK_TONE_A_11N, 0x01008c00); 7631d229e88SPing-Ke Shih } 7641d229e88SPing-Ke Shih 7651d229e88SPing-Ke Shih static void rtw8723d_iqk_backup_path_ctrl(struct rtw_dev *rtwdev, 7661d229e88SPing-Ke Shih struct iqk_backup_regs *backup) 7671d229e88SPing-Ke Shih { 7681d229e88SPing-Ke Shih backup->btg_sel = rtw_read8(rtwdev, REG_BTG_SEL); 7691d229e88SPing-Ke Shih rtw_dbg(rtwdev, RTW_DBG_RFK, "[IQK] original 0x67 = 0x%x\n", 7701d229e88SPing-Ke Shih backup->btg_sel); 7711d229e88SPing-Ke Shih } 7721d229e88SPing-Ke Shih 7731d229e88SPing-Ke Shih static void rtw8723d_iqk_config_path_ctrl(struct rtw_dev *rtwdev) 7741d229e88SPing-Ke Shih { 7751d229e88SPing-Ke Shih rtw_write32_mask(rtwdev, REG_PAD_CTRL1, BIT_BT_BTG_SEL, 0x1); 7761d229e88SPing-Ke Shih rtw_dbg(rtwdev, RTW_DBG_RFK, "[IQK] set 0x67 = 0x%x\n", 7771d229e88SPing-Ke Shih rtw_read32_mask(rtwdev, REG_PAD_CTRL1, MASKBYTE3)); 7781d229e88SPing-Ke Shih } 7791d229e88SPing-Ke Shih 7801d229e88SPing-Ke Shih static void rtw8723d_iqk_restore_path_ctrl(struct rtw_dev *rtwdev, 7811d229e88SPing-Ke Shih const struct iqk_backup_regs *backup) 7821d229e88SPing-Ke Shih { 7831d229e88SPing-Ke Shih rtw_write8(rtwdev, REG_BTG_SEL, backup->btg_sel); 7841d229e88SPing-Ke Shih rtw_dbg(rtwdev, RTW_DBG_RFK, "[IQK] restore 0x67 = 0x%x\n", 7851d229e88SPing-Ke Shih rtw_read32_mask(rtwdev, REG_PAD_CTRL1, MASKBYTE3)); 7861d229e88SPing-Ke Shih } 7871d229e88SPing-Ke Shih 7881d229e88SPing-Ke Shih static void rtw8723d_iqk_backup_lte_path_gnt(struct rtw_dev *rtwdev, 7891d229e88SPing-Ke Shih struct iqk_backup_regs *backup) 7901d229e88SPing-Ke Shih { 7911d229e88SPing-Ke Shih backup->lte_path = rtw_read32(rtwdev, REG_LTECOEX_PATH_CONTROL); 7921d229e88SPing-Ke Shih rtw_write32(rtwdev, REG_LTECOEX_CTRL, 0x800f0038); 7931d229e88SPing-Ke Shih mdelay(1); 7941d229e88SPing-Ke Shih backup->lte_gnt = rtw_read32(rtwdev, REG_LTECOEX_READ_DATA); 7951d229e88SPing-Ke Shih rtw_dbg(rtwdev, RTW_DBG_RFK, "[IQK] OriginalGNT = 0x%x\n", 7961d229e88SPing-Ke Shih backup->lte_gnt); 7971d229e88SPing-Ke Shih } 7981d229e88SPing-Ke Shih 7991d229e88SPing-Ke Shih static void rtw8723d_iqk_config_lte_path_gnt(struct rtw_dev *rtwdev) 8001d229e88SPing-Ke Shih { 8011d229e88SPing-Ke Shih rtw_write32(rtwdev, REG_LTECOEX_WRITE_DATA, 0x0000ff00); 8021d229e88SPing-Ke Shih rtw_write32(rtwdev, REG_LTECOEX_CTRL, 0xc0020038); 8031d229e88SPing-Ke Shih rtw_write32_mask(rtwdev, REG_LTECOEX_PATH_CONTROL, BIT_LTE_MUX_CTRL_PATH, 0x1); 8041d229e88SPing-Ke Shih } 8051d229e88SPing-Ke Shih 8061d229e88SPing-Ke Shih static void rtw8723d_iqk_restore_lte_path_gnt(struct rtw_dev *rtwdev, 8071d229e88SPing-Ke Shih const struct iqk_backup_regs *bak) 8081d229e88SPing-Ke Shih { 8091d229e88SPing-Ke Shih rtw_write32(rtwdev, REG_LTECOEX_WRITE_DATA, bak->lte_gnt); 8101d229e88SPing-Ke Shih rtw_write32(rtwdev, REG_LTECOEX_CTRL, 0xc00f0038); 8111d229e88SPing-Ke Shih rtw_write32(rtwdev, REG_LTECOEX_PATH_CONTROL, bak->lte_path); 8121d229e88SPing-Ke Shih } 8131d229e88SPing-Ke Shih 8141d229e88SPing-Ke Shih struct rtw_8723d_iqk_cfg { 8151d229e88SPing-Ke Shih const char *name; 8161d229e88SPing-Ke Shih u32 val_bb_sel_btg; 8171d229e88SPing-Ke Shih u32 reg_lutwe; 8181d229e88SPing-Ke Shih u32 val_txiqk_pi; 8191d229e88SPing-Ke Shih u32 reg_padlut; 8201d229e88SPing-Ke Shih u32 reg_gaintx; 8211d229e88SPing-Ke Shih u32 reg_bspad; 8221d229e88SPing-Ke Shih u32 val_wlint; 8231d229e88SPing-Ke Shih u32 val_wlsel; 8241d229e88SPing-Ke Shih u32 val_iqkpts; 8251d229e88SPing-Ke Shih }; 8261d229e88SPing-Ke Shih 8271d229e88SPing-Ke Shih static const struct rtw_8723d_iqk_cfg iqk_tx_cfg[PATH_NR] = { 8281d229e88SPing-Ke Shih [PATH_S1] = { 8291d229e88SPing-Ke Shih .name = "S1", 8301d229e88SPing-Ke Shih .val_bb_sel_btg = 0x99000000, 8311d229e88SPing-Ke Shih .reg_lutwe = RF_LUTWE, 8321d229e88SPing-Ke Shih .val_txiqk_pi = 0x8214019f, 8331d229e88SPing-Ke Shih .reg_padlut = RF_LUTDBG, 8341d229e88SPing-Ke Shih .reg_gaintx = RF_GAINTX, 8351d229e88SPing-Ke Shih .reg_bspad = RF_BSPAD, 8361d229e88SPing-Ke Shih .val_wlint = 0xe0d, 8371d229e88SPing-Ke Shih .val_wlsel = 0x60d, 8381d229e88SPing-Ke Shih .val_iqkpts = 0xfa000000, 8391d229e88SPing-Ke Shih }, 8401d229e88SPing-Ke Shih [PATH_S0] = { 8411d229e88SPing-Ke Shih .name = "S0", 8421d229e88SPing-Ke Shih .val_bb_sel_btg = 0x99000280, 8431d229e88SPing-Ke Shih .reg_lutwe = RF_LUTWE2, 8441d229e88SPing-Ke Shih .val_txiqk_pi = 0x8214018a, 8451d229e88SPing-Ke Shih .reg_padlut = RF_TXADBG, 8461d229e88SPing-Ke Shih .reg_gaintx = RF_TRXIQ, 8471d229e88SPing-Ke Shih .reg_bspad = RF_TXATANK, 8481d229e88SPing-Ke Shih .val_wlint = 0xe6d, 8491d229e88SPing-Ke Shih .val_wlsel = 0x66d, 8501d229e88SPing-Ke Shih .val_iqkpts = 0xf9000000, 8511d229e88SPing-Ke Shih }, 8521d229e88SPing-Ke Shih }; 8531d229e88SPing-Ke Shih 8541d229e88SPing-Ke Shih static u8 rtw8723d_iqk_check_tx_failed(struct rtw_dev *rtwdev, 8551d229e88SPing-Ke Shih const struct rtw_8723d_iqk_cfg *iqk_cfg) 8561d229e88SPing-Ke Shih { 8571d229e88SPing-Ke Shih s32 tx_x, tx_y; 8581d229e88SPing-Ke Shih u32 tx_fail; 8591d229e88SPing-Ke Shih 8601d229e88SPing-Ke Shih rtw_dbg(rtwdev, RTW_DBG_RFK, "[IQK] 0xeac = 0x%x\n", 8611d229e88SPing-Ke Shih rtw_read32(rtwdev, REG_IQK_RES_RY)); 8621d229e88SPing-Ke Shih rtw_dbg(rtwdev, RTW_DBG_RFK, "[IQK] 0xe94 = 0x%x, 0xe9c = 0x%x\n", 8631d229e88SPing-Ke Shih rtw_read32(rtwdev, REG_IQK_RES_TX), 8641d229e88SPing-Ke Shih rtw_read32(rtwdev, REG_IQK_RES_TY)); 8651d229e88SPing-Ke Shih rtw_dbg(rtwdev, RTW_DBG_RFK, 8661d229e88SPing-Ke Shih "[IQK] 0xe90(before IQK)= 0x%x, 0xe98(afer IQK) = 0x%x\n", 8671d229e88SPing-Ke Shih rtw_read32(rtwdev, 0xe90), 8681d229e88SPing-Ke Shih rtw_read32(rtwdev, 0xe98)); 8691d229e88SPing-Ke Shih 8701d229e88SPing-Ke Shih tx_fail = rtw_read32_mask(rtwdev, REG_IQK_RES_RY, BIT_IQK_TX_FAIL); 8711d229e88SPing-Ke Shih tx_x = rtw_read32_mask(rtwdev, REG_IQK_RES_TX, BIT_MASK_RES_TX); 8721d229e88SPing-Ke Shih tx_y = rtw_read32_mask(rtwdev, REG_IQK_RES_TY, BIT_MASK_RES_TY); 8731d229e88SPing-Ke Shih 8741d229e88SPing-Ke Shih if (!tx_fail && tx_x != IQK_TX_X_ERR && tx_y != IQK_TX_Y_ERR) 8751d229e88SPing-Ke Shih return IQK_TX_OK; 8761d229e88SPing-Ke Shih 8771d229e88SPing-Ke Shih rtw_dbg(rtwdev, RTW_DBG_RFK, "[IQK] %s TXIQK is failed\n", 8781d229e88SPing-Ke Shih iqk_cfg->name); 8791d229e88SPing-Ke Shih 8801d229e88SPing-Ke Shih return 0; 8811d229e88SPing-Ke Shih } 8821d229e88SPing-Ke Shih 8831d229e88SPing-Ke Shih static u8 rtw8723d_iqk_check_rx_failed(struct rtw_dev *rtwdev, 8841d229e88SPing-Ke Shih const struct rtw_8723d_iqk_cfg *iqk_cfg) 8851d229e88SPing-Ke Shih { 8861d229e88SPing-Ke Shih s32 rx_x, rx_y; 8871d229e88SPing-Ke Shih u32 rx_fail; 8881d229e88SPing-Ke Shih 8891d229e88SPing-Ke Shih rtw_dbg(rtwdev, RTW_DBG_RFK, "[IQK] 0xea4 = 0x%x, 0xeac = 0x%x\n", 8901d229e88SPing-Ke Shih rtw_read32(rtwdev, REG_IQK_RES_RX), 8911d229e88SPing-Ke Shih rtw_read32(rtwdev, REG_IQK_RES_RY)); 8921d229e88SPing-Ke Shih 8931d229e88SPing-Ke Shih rtw_dbg(rtwdev, RTW_DBG_RFK, 8941d229e88SPing-Ke Shih "[IQK] 0xea0(before IQK)= 0x%x, 0xea8(afer IQK) = 0x%x\n", 8951d229e88SPing-Ke Shih rtw_read32(rtwdev, 0xea0), 8961d229e88SPing-Ke Shih rtw_read32(rtwdev, 0xea8)); 8971d229e88SPing-Ke Shih 8981d229e88SPing-Ke Shih rx_fail = rtw_read32_mask(rtwdev, REG_IQK_RES_RY, BIT_IQK_RX_FAIL); 8991d229e88SPing-Ke Shih rx_x = rtw_read32_mask(rtwdev, REG_IQK_RES_RX, BIT_MASK_RES_RX); 9001d229e88SPing-Ke Shih rx_y = rtw_read32_mask(rtwdev, REG_IQK_RES_RY, BIT_MASK_RES_RY); 9011d229e88SPing-Ke Shih rx_y = abs(iqkxy_to_s32(rx_y)); 9021d229e88SPing-Ke Shih 9031d229e88SPing-Ke Shih if (!rx_fail && rx_x < IQK_RX_X_UPPER && rx_x > IQK_RX_X_LOWER && 9041d229e88SPing-Ke Shih rx_y < IQK_RX_Y_LMT) 9051d229e88SPing-Ke Shih return IQK_RX_OK; 9061d229e88SPing-Ke Shih 9071d229e88SPing-Ke Shih rtw_dbg(rtwdev, RTW_DBG_RFK, "[IQK] %s RXIQK STEP2 is failed\n", 9081d229e88SPing-Ke Shih iqk_cfg->name); 9091d229e88SPing-Ke Shih 9101d229e88SPing-Ke Shih return 0; 9111d229e88SPing-Ke Shih } 9121d229e88SPing-Ke Shih 9131d229e88SPing-Ke Shih static void rtw8723d_iqk_one_shot(struct rtw_dev *rtwdev, bool tx, 9141d229e88SPing-Ke Shih const struct rtw_8723d_iqk_cfg *iqk_cfg) 9151d229e88SPing-Ke Shih { 9161d229e88SPing-Ke Shih u32 pts = (tx ? iqk_cfg->val_iqkpts : 0xf9000000); 9171d229e88SPing-Ke Shih 9181d229e88SPing-Ke Shih /* enter IQK mode */ 9191d229e88SPing-Ke Shih rtw_write32_mask(rtwdev, REG_FPGA0_IQK_11N, BIT_MASK_IQK_MOD, EN_IQK); 9201d229e88SPing-Ke Shih rtw8723d_iqk_config_lte_path_gnt(rtwdev); 9211d229e88SPing-Ke Shih 9221d229e88SPing-Ke Shih rtw_write32(rtwdev, REG_LTECOEX_CTRL, 0x800f0054); 9231d229e88SPing-Ke Shih mdelay(1); 9241d229e88SPing-Ke Shih rtw_dbg(rtwdev, RTW_DBG_RFK, "[IQK] GNT_BT @%s %sIQK1 = 0x%x\n", 9251d229e88SPing-Ke Shih iqk_cfg->name, tx ? "TX" : "RX", 9261d229e88SPing-Ke Shih rtw_read32(rtwdev, REG_LTECOEX_READ_DATA)); 9271d229e88SPing-Ke Shih rtw_dbg(rtwdev, RTW_DBG_RFK, "[IQK] 0x948 @%s %sIQK1 = 0x%x\n", 9281d229e88SPing-Ke Shih iqk_cfg->name, tx ? "TX" : "RX", 9291d229e88SPing-Ke Shih rtw_read32(rtwdev, REG_BB_SEL_BTG)); 9301d229e88SPing-Ke Shih 9311d229e88SPing-Ke Shih /* One shot, LOK & IQK */ 9321d229e88SPing-Ke Shih rtw_write32(rtwdev, REG_IQK_AGC_PTS_11N, pts); 9331d229e88SPing-Ke Shih rtw_write32(rtwdev, REG_IQK_AGC_PTS_11N, 0xf8000000); 9341d229e88SPing-Ke Shih 9351d229e88SPing-Ke Shih if (!check_hw_ready(rtwdev, REG_IQK_RES_RY, BIT_IQK_DONE, 1)) 9361d229e88SPing-Ke Shih rtw_warn(rtwdev, "%s %s IQK isn't done\n", iqk_cfg->name, 9371d229e88SPing-Ke Shih tx ? "TX" : "RX"); 9381d229e88SPing-Ke Shih } 9391d229e88SPing-Ke Shih 9401d229e88SPing-Ke Shih static void rtw8723d_iqk_txrx_path_post(struct rtw_dev *rtwdev, 9411d229e88SPing-Ke Shih const struct rtw_8723d_iqk_cfg *iqk_cfg, 9421d229e88SPing-Ke Shih const struct iqk_backup_regs *backup) 9431d229e88SPing-Ke Shih { 9441d229e88SPing-Ke Shih rtw8723d_iqk_restore_lte_path_gnt(rtwdev, backup); 9451d229e88SPing-Ke Shih rtw_write32(rtwdev, REG_BB_SEL_BTG, backup->bb_sel_btg); 9461d229e88SPing-Ke Shih 9471d229e88SPing-Ke Shih /* leave IQK mode */ 9481d229e88SPing-Ke Shih rtw_write32_mask(rtwdev, REG_FPGA0_IQK_11N, BIT_MASK_IQK_MOD, RST_IQK); 9491d229e88SPing-Ke Shih mdelay(1); 9501d229e88SPing-Ke Shih rtw_write_rf(rtwdev, RF_PATH_A, iqk_cfg->reg_padlut, 0x800, 0x0); 9511d229e88SPing-Ke Shih rtw_write_rf(rtwdev, RF_PATH_A, RF_WLINT, BIT(0), 0x0); 9521d229e88SPing-Ke Shih rtw_write_rf(rtwdev, RF_PATH_A, RF_WLSEL, BIT(0), 0x0); 9531d229e88SPing-Ke Shih } 9541d229e88SPing-Ke Shih 9551d229e88SPing-Ke Shih static u8 rtw8723d_iqk_tx_path(struct rtw_dev *rtwdev, 9561d229e88SPing-Ke Shih const struct rtw_8723d_iqk_cfg *iqk_cfg, 9571d229e88SPing-Ke Shih const struct iqk_backup_regs *backup) 9581d229e88SPing-Ke Shih { 9591d229e88SPing-Ke Shih u8 status; 9601d229e88SPing-Ke Shih 9611d229e88SPing-Ke Shih rtw_dbg(rtwdev, RTW_DBG_RFK, "[IQK] path %s TXIQK!!\n", iqk_cfg->name); 9621d229e88SPing-Ke Shih rtw_dbg(rtwdev, RTW_DBG_RFK, "[IQK] 0x67 @%s TXIQK = 0x%x\n", 9631d229e88SPing-Ke Shih iqk_cfg->name, 9641d229e88SPing-Ke Shih rtw_read32_mask(rtwdev, REG_PAD_CTRL1, MASKBYTE3)); 9651d229e88SPing-Ke Shih 9661d229e88SPing-Ke Shih rtw_write32(rtwdev, REG_BB_SEL_BTG, iqk_cfg->val_bb_sel_btg); 9671d229e88SPing-Ke Shih rtw_write32_mask(rtwdev, REG_FPGA0_IQK_11N, BIT_MASK_IQK_MOD, RST_IQK); 9681d229e88SPing-Ke Shih mdelay(1); 9691d229e88SPing-Ke Shih rtw_write_rf(rtwdev, RF_PATH_A, iqk_cfg->reg_lutwe, RFREG_MASK, 0x80000); 9701d229e88SPing-Ke Shih rtw_write_rf(rtwdev, RF_PATH_A, RF_LUTWA, RFREG_MASK, 0x00004); 9711d229e88SPing-Ke Shih rtw_write_rf(rtwdev, RF_PATH_A, RF_LUTWD1, RFREG_MASK, 0x0005d); 9721d229e88SPing-Ke Shih rtw_write_rf(rtwdev, RF_PATH_A, RF_LUTWD0, RFREG_MASK, 0xBFFE0); 9731d229e88SPing-Ke Shih rtw_write_rf(rtwdev, RF_PATH_A, iqk_cfg->reg_lutwe, RFREG_MASK, 0x00000); 9741d229e88SPing-Ke Shih 9751d229e88SPing-Ke Shih /* IQK setting */ 9761d229e88SPing-Ke Shih rtw_write32(rtwdev, REG_TXIQK_TONE_A_11N, 0x08008c0c); 9771d229e88SPing-Ke Shih rtw_write32(rtwdev, REG_RXIQK_TONE_A_11N, 0x38008c1c); 9781d229e88SPing-Ke Shih rtw_write32(rtwdev, REG_TXIQK_PI_A_11N, iqk_cfg->val_txiqk_pi); 9791d229e88SPing-Ke Shih rtw_write32(rtwdev, REG_RXIQK_PI_A_11N, 0x28160200); 9801d229e88SPing-Ke Shih rtw_write32(rtwdev, REG_TXIQK_11N, 0x01007c00); 9811d229e88SPing-Ke Shih rtw_write32(rtwdev, REG_RXIQK_11N, 0x01004800); 9821d229e88SPing-Ke Shih 9831d229e88SPing-Ke Shih /* LOK setting */ 9841d229e88SPing-Ke Shih rtw_write32(rtwdev, REG_IQK_AGC_RSP_11N, 0x00462911); 9851d229e88SPing-Ke Shih 9861d229e88SPing-Ke Shih /* PA, PAD setting */ 9871d229e88SPing-Ke Shih rtw_write_rf(rtwdev, RF_PATH_A, iqk_cfg->reg_padlut, 0x800, 0x1); 9881d229e88SPing-Ke Shih rtw_write_rf(rtwdev, RF_PATH_A, iqk_cfg->reg_gaintx, 0x600, 0x0); 9891d229e88SPing-Ke Shih rtw_write_rf(rtwdev, RF_PATH_A, iqk_cfg->reg_gaintx, 0x1E0, 0x3); 9901d229e88SPing-Ke Shih rtw_write_rf(rtwdev, RF_PATH_A, RF_RXIQGEN, 0x1F, 0xf); 9911d229e88SPing-Ke Shih 9921d229e88SPing-Ke Shih /* LOK setting for 8723D */ 9931d229e88SPing-Ke Shih rtw_write_rf(rtwdev, RF_PATH_A, iqk_cfg->reg_lutwe, 0x10, 0x1); 9941d229e88SPing-Ke Shih rtw_write_rf(rtwdev, RF_PATH_A, iqk_cfg->reg_bspad, 0x1, 0x1); 9951d229e88SPing-Ke Shih 9961d229e88SPing-Ke Shih rtw_write_rf(rtwdev, RF_PATH_A, RF_WLINT, RFREG_MASK, iqk_cfg->val_wlint); 9971d229e88SPing-Ke Shih rtw_write_rf(rtwdev, RF_PATH_A, RF_WLSEL, RFREG_MASK, iqk_cfg->val_wlsel); 9981d229e88SPing-Ke Shih 9991d229e88SPing-Ke Shih rtw_dbg(rtwdev, RTW_DBG_RFK, "[IQK] RF0x1 @%s TXIQK = 0x%x\n", 10001d229e88SPing-Ke Shih iqk_cfg->name, 10011d229e88SPing-Ke Shih rtw_read_rf(rtwdev, RF_PATH_A, RF_WLINT, RFREG_MASK)); 10021d229e88SPing-Ke Shih rtw_dbg(rtwdev, RTW_DBG_RFK, "[IQK] RF0x2 @%s TXIQK = 0x%x\n", 10031d229e88SPing-Ke Shih iqk_cfg->name, 10041d229e88SPing-Ke Shih rtw_read_rf(rtwdev, RF_PATH_A, RF_WLSEL, RFREG_MASK)); 10051d229e88SPing-Ke Shih 10061d229e88SPing-Ke Shih rtw8723d_iqk_one_shot(rtwdev, true, iqk_cfg); 10071d229e88SPing-Ke Shih status = rtw8723d_iqk_check_tx_failed(rtwdev, iqk_cfg); 10081d229e88SPing-Ke Shih 10091d229e88SPing-Ke Shih rtw8723d_iqk_txrx_path_post(rtwdev, iqk_cfg, backup); 10101d229e88SPing-Ke Shih 10111d229e88SPing-Ke Shih return status; 10121d229e88SPing-Ke Shih } 10131d229e88SPing-Ke Shih 10141d229e88SPing-Ke Shih static u8 rtw8723d_iqk_rx_path(struct rtw_dev *rtwdev, 10151d229e88SPing-Ke Shih const struct rtw_8723d_iqk_cfg *iqk_cfg, 10161d229e88SPing-Ke Shih const struct iqk_backup_regs *backup) 10171d229e88SPing-Ke Shih { 10181d229e88SPing-Ke Shih u32 tx_x, tx_y; 10191d229e88SPing-Ke Shih u8 status; 10201d229e88SPing-Ke Shih 10211d229e88SPing-Ke Shih rtw_dbg(rtwdev, RTW_DBG_RFK, "[IQK] path %s RXIQK Step1!!\n", 10221d229e88SPing-Ke Shih iqk_cfg->name); 10231d229e88SPing-Ke Shih rtw_dbg(rtwdev, RTW_DBG_RFK, "[IQK] 0x67 @%s RXIQK1 = 0x%x\n", 10241d229e88SPing-Ke Shih iqk_cfg->name, 10251d229e88SPing-Ke Shih rtw_read32_mask(rtwdev, REG_PAD_CTRL1, MASKBYTE3)); 10261d229e88SPing-Ke Shih rtw_write32(rtwdev, REG_BB_SEL_BTG, iqk_cfg->val_bb_sel_btg); 10271d229e88SPing-Ke Shih 10281d229e88SPing-Ke Shih rtw_write32_mask(rtwdev, REG_FPGA0_IQK_11N, BIT_MASK_IQK_MOD, RST_IQK); 10291d229e88SPing-Ke Shih 10301d229e88SPing-Ke Shih /* IQK setting */ 10311d229e88SPing-Ke Shih rtw_write32(rtwdev, REG_TXIQK_11N, 0x01007c00); 10321d229e88SPing-Ke Shih rtw_write32(rtwdev, REG_RXIQK_11N, 0x01004800); 10331d229e88SPing-Ke Shih 10341d229e88SPing-Ke Shih /* path IQK setting */ 10351d229e88SPing-Ke Shih rtw_write32(rtwdev, REG_TXIQK_TONE_A_11N, 0x18008c1c); 10361d229e88SPing-Ke Shih rtw_write32(rtwdev, REG_RXIQK_TONE_A_11N, 0x38008c1c); 10371d229e88SPing-Ke Shih rtw_write32(rtwdev, REG_TX_IQK_TONE_B, 0x38008c1c); 10381d229e88SPing-Ke Shih rtw_write32(rtwdev, REG_RX_IQK_TONE_B, 0x38008c1c); 10391d229e88SPing-Ke Shih rtw_write32(rtwdev, REG_TXIQK_PI_A_11N, 0x82160000); 10401d229e88SPing-Ke Shih rtw_write32(rtwdev, REG_RXIQK_PI_A_11N, 0x28160000); 10411d229e88SPing-Ke Shih 10421d229e88SPing-Ke Shih /* LOK setting */ 10431d229e88SPing-Ke Shih rtw_write32(rtwdev, REG_IQK_AGC_RSP_11N, 0x0046a911); 10441d229e88SPing-Ke Shih 10451d229e88SPing-Ke Shih /* RXIQK mode */ 10461d229e88SPing-Ke Shih rtw_write_rf(rtwdev, RF_PATH_A, iqk_cfg->reg_lutwe, RFREG_MASK, 0x80000); 10471d229e88SPing-Ke Shih rtw_write_rf(rtwdev, RF_PATH_A, RF_LUTWA, RFREG_MASK, 0x00006); 10481d229e88SPing-Ke Shih rtw_write_rf(rtwdev, RF_PATH_A, RF_LUTWD1, RFREG_MASK, 0x0005f); 10491d229e88SPing-Ke Shih rtw_write_rf(rtwdev, RF_PATH_A, RF_LUTWD0, RFREG_MASK, 0xa7ffb); 10501d229e88SPing-Ke Shih rtw_write_rf(rtwdev, RF_PATH_A, iqk_cfg->reg_lutwe, RFREG_MASK, 0x00000); 10511d229e88SPing-Ke Shih 10521d229e88SPing-Ke Shih /* PA/PAD=0 */ 10531d229e88SPing-Ke Shih rtw_write_rf(rtwdev, RF_PATH_A, iqk_cfg->reg_padlut, 0x800, 0x1); 10541d229e88SPing-Ke Shih rtw_write_rf(rtwdev, RF_PATH_A, iqk_cfg->reg_gaintx, 0x600, 0x0); 10551d229e88SPing-Ke Shih rtw_write_rf(rtwdev, RF_PATH_A, RF_WLINT, RFREG_MASK, iqk_cfg->val_wlint); 10561d229e88SPing-Ke Shih rtw_write_rf(rtwdev, RF_PATH_A, RF_WLSEL, RFREG_MASK, iqk_cfg->val_wlsel); 10571d229e88SPing-Ke Shih 10581d229e88SPing-Ke Shih rtw_dbg(rtwdev, RTW_DBG_RFK, "[IQK] RF0x1@ path %s RXIQK1 = 0x%x\n", 10591d229e88SPing-Ke Shih iqk_cfg->name, 10601d229e88SPing-Ke Shih rtw_read_rf(rtwdev, RF_PATH_A, RF_WLINT, RFREG_MASK)); 10611d229e88SPing-Ke Shih rtw_dbg(rtwdev, RTW_DBG_RFK, "[IQK] RF0x2@ path %s RXIQK1 = 0x%x\n", 10621d229e88SPing-Ke Shih iqk_cfg->name, 10631d229e88SPing-Ke Shih rtw_read_rf(rtwdev, RF_PATH_A, RF_WLSEL, RFREG_MASK)); 10641d229e88SPing-Ke Shih 10651d229e88SPing-Ke Shih rtw8723d_iqk_one_shot(rtwdev, false, iqk_cfg); 10661d229e88SPing-Ke Shih status = rtw8723d_iqk_check_tx_failed(rtwdev, iqk_cfg); 10671d229e88SPing-Ke Shih 10681d229e88SPing-Ke Shih if (!status) 10691d229e88SPing-Ke Shih goto restore; 10701d229e88SPing-Ke Shih 10711d229e88SPing-Ke Shih /* second round */ 10721d229e88SPing-Ke Shih tx_x = rtw_read32_mask(rtwdev, REG_IQK_RES_TX, BIT_MASK_RES_TX); 10731d229e88SPing-Ke Shih tx_y = rtw_read32_mask(rtwdev, REG_IQK_RES_TY, BIT_MASK_RES_TY); 10741d229e88SPing-Ke Shih 10751d229e88SPing-Ke Shih rtw_write32(rtwdev, REG_TXIQK_11N, BIT_SET_TXIQK_11N(tx_x, tx_y)); 10761d229e88SPing-Ke Shih rtw_dbg(rtwdev, RTW_DBG_RFK, "[IQK] 0xe40 = 0x%x u4tmp = 0x%x\n", 10771d229e88SPing-Ke Shih rtw_read32(rtwdev, REG_TXIQK_11N), 10781d229e88SPing-Ke Shih BIT_SET_TXIQK_11N(tx_x, tx_y)); 10791d229e88SPing-Ke Shih 10801d229e88SPing-Ke Shih rtw_dbg(rtwdev, RTW_DBG_RFK, "[IQK] path %s RXIQK STEP2!!\n", 10811d229e88SPing-Ke Shih iqk_cfg->name); 10821d229e88SPing-Ke Shih rtw_dbg(rtwdev, RTW_DBG_RFK, "[IQK] 0x67 @%s RXIQK2 = 0x%x\n", 10831d229e88SPing-Ke Shih iqk_cfg->name, 10841d229e88SPing-Ke Shih rtw_read32_mask(rtwdev, REG_PAD_CTRL1, MASKBYTE3)); 10851d229e88SPing-Ke Shih 10861d229e88SPing-Ke Shih rtw_write32(rtwdev, REG_RXIQK_11N, 0x01004800); 10871d229e88SPing-Ke Shih rtw_write32(rtwdev, REG_TXIQK_TONE_A_11N, 0x38008c1c); 10881d229e88SPing-Ke Shih rtw_write32(rtwdev, REG_RXIQK_TONE_A_11N, 0x18008c1c); 10891d229e88SPing-Ke Shih rtw_write32(rtwdev, REG_TX_IQK_TONE_B, 0x38008c1c); 10901d229e88SPing-Ke Shih rtw_write32(rtwdev, REG_RX_IQK_TONE_B, 0x38008c1c); 10911d229e88SPing-Ke Shih rtw_write32(rtwdev, REG_TXIQK_PI_A_11N, 0x82170000); 10921d229e88SPing-Ke Shih rtw_write32(rtwdev, REG_RXIQK_PI_A_11N, 0x28171400); 10931d229e88SPing-Ke Shih 10941d229e88SPing-Ke Shih /* LOK setting */ 10951d229e88SPing-Ke Shih rtw_write32(rtwdev, REG_IQK_AGC_RSP_11N, 0x0046a8d1); 10961d229e88SPing-Ke Shih 10971d229e88SPing-Ke Shih /* RXIQK mode */ 10981d229e88SPing-Ke Shih rtw_write32_mask(rtwdev, REG_FPGA0_IQK_11N, BIT_MASK_IQK_MOD, RST_IQK); 10991d229e88SPing-Ke Shih mdelay(1); 11001d229e88SPing-Ke Shih rtw_write_rf(rtwdev, RF_PATH_A, iqk_cfg->reg_lutwe, 0x80000, 0x1); 11011d229e88SPing-Ke Shih rtw_write_rf(rtwdev, RF_PATH_A, RF_LUTWA, RFREG_MASK, 0x00007); 11021d229e88SPing-Ke Shih rtw_write_rf(rtwdev, RF_PATH_A, RF_LUTWD1, RFREG_MASK, 0x0005f); 11031d229e88SPing-Ke Shih rtw_write_rf(rtwdev, RF_PATH_A, RF_LUTWD0, RFREG_MASK, 0xb3fdb); 11041d229e88SPing-Ke Shih rtw_write_rf(rtwdev, RF_PATH_A, iqk_cfg->reg_lutwe, RFREG_MASK, 0x00000); 11051d229e88SPing-Ke Shih 11061d229e88SPing-Ke Shih rtw_dbg(rtwdev, RTW_DBG_RFK, "[IQK] RF0x1 @%s RXIQK2 = 0x%x\n", 11071d229e88SPing-Ke Shih iqk_cfg->name, 11081d229e88SPing-Ke Shih rtw_read_rf(rtwdev, RF_PATH_A, RF_WLINT, RFREG_MASK)); 11091d229e88SPing-Ke Shih rtw_dbg(rtwdev, RTW_DBG_RFK, "[IQK] RF0x2 @%s RXIQK2 = 0x%x\n", 11101d229e88SPing-Ke Shih iqk_cfg->name, 11111d229e88SPing-Ke Shih rtw_read_rf(rtwdev, RF_PATH_A, RF_WLSEL, RFREG_MASK)); 11121d229e88SPing-Ke Shih 11131d229e88SPing-Ke Shih rtw8723d_iqk_one_shot(rtwdev, false, iqk_cfg); 11141d229e88SPing-Ke Shih status |= rtw8723d_iqk_check_rx_failed(rtwdev, iqk_cfg); 11151d229e88SPing-Ke Shih 11161d229e88SPing-Ke Shih restore: 11171d229e88SPing-Ke Shih rtw8723d_iqk_txrx_path_post(rtwdev, iqk_cfg, backup); 11181d229e88SPing-Ke Shih 11191d229e88SPing-Ke Shih return status; 11201d229e88SPing-Ke Shih } 11211d229e88SPing-Ke Shih 11221d229e88SPing-Ke Shih static 11231d229e88SPing-Ke Shih void rtw8723d_iqk_fill_s1_matrix(struct rtw_dev *rtwdev, const s32 result[]) 11241d229e88SPing-Ke Shih { 11251d229e88SPing-Ke Shih s32 oldval_1; 11261d229e88SPing-Ke Shih s32 x, y; 11271d229e88SPing-Ke Shih s32 tx1_a, tx1_a_ext; 11281d229e88SPing-Ke Shih s32 tx1_c, tx1_c_ext; 11291d229e88SPing-Ke Shih 11301d229e88SPing-Ke Shih if (result[IQK_S1_TX_X] == 0) 11311d229e88SPing-Ke Shih return; 11321d229e88SPing-Ke Shih 11331d229e88SPing-Ke Shih oldval_1 = rtw_read32_mask(rtwdev, REG_OFDM_0_XA_TX_IQ_IMBALANCE, 11341d229e88SPing-Ke Shih BIT_MASK_TXIQ_ELM_D); 11351d229e88SPing-Ke Shih 11361d229e88SPing-Ke Shih x = iqkxy_to_s32(result[IQK_S1_TX_X]); 11371d229e88SPing-Ke Shih tx1_a = iqk_mult(x, oldval_1, &tx1_a_ext); 11381d229e88SPing-Ke Shih rtw_write32_mask(rtwdev, REG_OFDM_0_XA_TX_IQ_IMBALANCE, 11391d229e88SPing-Ke Shih BIT_MASK_TXIQ_ELM_A, tx1_a); 11401d229e88SPing-Ke Shih rtw_write32_mask(rtwdev, REG_OFDM_0_ECCA_THRESHOLD, 11411d229e88SPing-Ke Shih BIT_MASK_OFDM0_EXT_A, tx1_a_ext); 11421d229e88SPing-Ke Shih 11431d229e88SPing-Ke Shih y = iqkxy_to_s32(result[IQK_S1_TX_Y]); 11441d229e88SPing-Ke Shih tx1_c = iqk_mult(y, oldval_1, &tx1_c_ext); 11451d229e88SPing-Ke Shih rtw_write32_mask(rtwdev, REG_TXIQK_MATRIXA_LSB2_11N, MASKH4BITS, 11461d229e88SPing-Ke Shih BIT_SET_TXIQ_ELM_C1(tx1_c)); 11471d229e88SPing-Ke Shih rtw_write32_mask(rtwdev, REG_OFDM_0_XA_TX_IQ_IMBALANCE, 11481d229e88SPing-Ke Shih BIT_MASK_TXIQ_ELM_C, BIT_SET_TXIQ_ELM_C2(tx1_c)); 11491d229e88SPing-Ke Shih rtw_write32_mask(rtwdev, REG_OFDM_0_ECCA_THRESHOLD, 11501d229e88SPing-Ke Shih BIT_MASK_OFDM0_EXT_C, tx1_c_ext); 11511d229e88SPing-Ke Shih 11521d229e88SPing-Ke Shih rtw_dbg(rtwdev, RTW_DBG_RFK, 11531d229e88SPing-Ke Shih "[IQK] X = 0x%x, TX1_A = 0x%x, oldval_1 0x%x\n", 11541d229e88SPing-Ke Shih x, tx1_a, oldval_1); 11551d229e88SPing-Ke Shih rtw_dbg(rtwdev, RTW_DBG_RFK, 11561d229e88SPing-Ke Shih "[IQK] Y = 0x%x, TX1_C = 0x%x\n", y, tx1_c); 11571d229e88SPing-Ke Shih 11581d229e88SPing-Ke Shih if (result[IQK_S1_RX_X] == 0) 11591d229e88SPing-Ke Shih return; 11601d229e88SPing-Ke Shih 11611d229e88SPing-Ke Shih rtw_write32_mask(rtwdev, REG_A_RXIQI, BIT_MASK_RXIQ_S1_X, 11621d229e88SPing-Ke Shih result[IQK_S1_RX_X]); 11631d229e88SPing-Ke Shih rtw_write32_mask(rtwdev, REG_A_RXIQI, BIT_MASK_RXIQ_S1_Y1, 11641d229e88SPing-Ke Shih BIT_SET_RXIQ_S1_Y1(result[IQK_S1_RX_Y])); 11651d229e88SPing-Ke Shih rtw_write32_mask(rtwdev, REG_RXIQK_MATRIX_LSB_11N, BIT_MASK_RXIQ_S1_Y2, 11661d229e88SPing-Ke Shih BIT_SET_RXIQ_S1_Y2(result[IQK_S1_RX_Y])); 11671d229e88SPing-Ke Shih } 11681d229e88SPing-Ke Shih 11691d229e88SPing-Ke Shih static 11701d229e88SPing-Ke Shih void rtw8723d_iqk_fill_s0_matrix(struct rtw_dev *rtwdev, const s32 result[]) 11711d229e88SPing-Ke Shih { 11721d229e88SPing-Ke Shih s32 oldval_0; 11731d229e88SPing-Ke Shih s32 x, y; 11741d229e88SPing-Ke Shih s32 tx0_a, tx0_a_ext; 11751d229e88SPing-Ke Shih s32 tx0_c, tx0_c_ext; 11761d229e88SPing-Ke Shih 11771d229e88SPing-Ke Shih if (result[IQK_S0_TX_X] == 0) 11781d229e88SPing-Ke Shih return; 11791d229e88SPing-Ke Shih 11801d229e88SPing-Ke Shih oldval_0 = rtw_read32_mask(rtwdev, REG_TXIQ_CD_S0, BIT_MASK_TXIQ_D_S0); 11811d229e88SPing-Ke Shih 11821d229e88SPing-Ke Shih x = iqkxy_to_s32(result[IQK_S0_TX_X]); 11831d229e88SPing-Ke Shih tx0_a = iqk_mult(x, oldval_0, &tx0_a_ext); 11841d229e88SPing-Ke Shih 11851d229e88SPing-Ke Shih rtw_write32_mask(rtwdev, REG_TXIQ_AB_S0, BIT_MASK_TXIQ_A_S0, tx0_a); 11861d229e88SPing-Ke Shih rtw_write32_mask(rtwdev, REG_TXIQ_AB_S0, BIT_MASK_TXIQ_A_EXT_S0, tx0_a_ext); 11871d229e88SPing-Ke Shih 11881d229e88SPing-Ke Shih y = iqkxy_to_s32(result[IQK_S0_TX_Y]); 11891d229e88SPing-Ke Shih tx0_c = iqk_mult(y, oldval_0, &tx0_c_ext); 11901d229e88SPing-Ke Shih 11911d229e88SPing-Ke Shih rtw_write32_mask(rtwdev, REG_TXIQ_CD_S0, BIT_MASK_TXIQ_C_S0, tx0_c); 11921d229e88SPing-Ke Shih rtw_write32_mask(rtwdev, REG_TXIQ_CD_S0, BIT_MASK_TXIQ_C_EXT_S0, tx0_c_ext); 11931d229e88SPing-Ke Shih 11941d229e88SPing-Ke Shih if (result[IQK_S0_RX_X] == 0) 11951d229e88SPing-Ke Shih return; 11961d229e88SPing-Ke Shih 11971d229e88SPing-Ke Shih rtw_write32_mask(rtwdev, REG_RXIQ_AB_S0, BIT_MASK_RXIQ_X_S0, 11981d229e88SPing-Ke Shih result[IQK_S0_RX_X]); 11991d229e88SPing-Ke Shih rtw_write32_mask(rtwdev, REG_RXIQ_AB_S0, BIT_MASK_RXIQ_Y_S0, 12001d229e88SPing-Ke Shih result[IQK_S0_RX_Y]); 12011d229e88SPing-Ke Shih } 12021d229e88SPing-Ke Shih 12031d229e88SPing-Ke Shih static void rtw8723d_iqk_path_adda_on(struct rtw_dev *rtwdev) 12041d229e88SPing-Ke Shih { 12051d229e88SPing-Ke Shih int i; 12061d229e88SPing-Ke Shih 12071d229e88SPing-Ke Shih for (i = 0; i < IQK_ADDA_REG_NUM; i++) 12081d229e88SPing-Ke Shih rtw_write32(rtwdev, iqk_adda_regs[i], 0x03c00016); 12091d229e88SPing-Ke Shih } 12101d229e88SPing-Ke Shih 12111d229e88SPing-Ke Shih static void rtw8723d_iqk_config_mac(struct rtw_dev *rtwdev) 12121d229e88SPing-Ke Shih { 12131d229e88SPing-Ke Shih rtw_write8(rtwdev, REG_TXPAUSE, 0xff); 12141d229e88SPing-Ke Shih } 12151d229e88SPing-Ke Shih 12161d229e88SPing-Ke Shih static 12171d229e88SPing-Ke Shih void rtw8723d_iqk_rf_standby(struct rtw_dev *rtwdev, enum rtw_rf_path path) 12181d229e88SPing-Ke Shih { 12191d229e88SPing-Ke Shih rtw_dbg(rtwdev, RTW_DBG_RFK, "[IQK] path-%s standby mode!\n", 12201d229e88SPing-Ke Shih path == RF_PATH_A ? "S1" : "S0"); 12211d229e88SPing-Ke Shih 12221d229e88SPing-Ke Shih rtw_write32_mask(rtwdev, REG_FPGA0_IQK_11N, BIT_MASK_IQK_MOD, RST_IQK); 12231d229e88SPing-Ke Shih mdelay(1); 12241d229e88SPing-Ke Shih rtw_write_rf(rtwdev, path, RF_MODE, RFREG_MASK, 0x10000); 12251d229e88SPing-Ke Shih rtw_write32_mask(rtwdev, REG_FPGA0_IQK_11N, BIT_MASK_IQK_MOD, EN_IQK); 12261d229e88SPing-Ke Shih } 12271d229e88SPing-Ke Shih 12281d229e88SPing-Ke Shih static 12291d229e88SPing-Ke Shih bool rtw8723d_iqk_similarity_cmp(struct rtw_dev *rtwdev, s32 result[][IQK_NR], 12301d229e88SPing-Ke Shih u8 c1, u8 c2) 12311d229e88SPing-Ke Shih { 12321d229e88SPing-Ke Shih u32 i, j, diff; 12331d229e88SPing-Ke Shih u32 bitmap = 0; 12341d229e88SPing-Ke Shih u8 candidate[PATH_NR] = {IQK_ROUND_INVALID, IQK_ROUND_INVALID}; 12351d229e88SPing-Ke Shih bool ret = true; 12361d229e88SPing-Ke Shih 12371d229e88SPing-Ke Shih s32 tmp1, tmp2; 12381d229e88SPing-Ke Shih 12391d229e88SPing-Ke Shih for (i = 0; i < IQK_NR; i++) { 12401d229e88SPing-Ke Shih tmp1 = iqkxy_to_s32(result[c1][i]); 12411d229e88SPing-Ke Shih tmp2 = iqkxy_to_s32(result[c2][i]); 12421d229e88SPing-Ke Shih 12431d229e88SPing-Ke Shih diff = abs(tmp1 - tmp2); 12441d229e88SPing-Ke Shih 12451d229e88SPing-Ke Shih if (diff <= MAX_TOLERANCE) 12461d229e88SPing-Ke Shih continue; 12471d229e88SPing-Ke Shih 12481d229e88SPing-Ke Shih if ((i == IQK_S1_RX_X || i == IQK_S0_RX_X) && !bitmap) { 12491d229e88SPing-Ke Shih if (result[c1][i] + result[c1][i + 1] == 0) 12501d229e88SPing-Ke Shih candidate[i / IQK_SX_NR] = c2; 12511d229e88SPing-Ke Shih else if (result[c2][i] + result[c2][i + 1] == 0) 12521d229e88SPing-Ke Shih candidate[i / IQK_SX_NR] = c1; 12531d229e88SPing-Ke Shih else 12541d229e88SPing-Ke Shih bitmap |= BIT(i); 12551d229e88SPing-Ke Shih } else { 12561d229e88SPing-Ke Shih bitmap |= BIT(i); 12571d229e88SPing-Ke Shih } 12581d229e88SPing-Ke Shih } 12591d229e88SPing-Ke Shih 12601d229e88SPing-Ke Shih if (bitmap != 0) 12611d229e88SPing-Ke Shih goto check_sim; 12621d229e88SPing-Ke Shih 12631d229e88SPing-Ke Shih for (i = 0; i < PATH_NR; i++) { 12641d229e88SPing-Ke Shih if (candidate[i] == IQK_ROUND_INVALID) 12651d229e88SPing-Ke Shih continue; 12661d229e88SPing-Ke Shih 12671d229e88SPing-Ke Shih for (j = i * IQK_SX_NR; j < i * IQK_SX_NR + 2; j++) 12681d229e88SPing-Ke Shih result[IQK_ROUND_HYBRID][j] = result[candidate[i]][j]; 12691d229e88SPing-Ke Shih ret = false; 12701d229e88SPing-Ke Shih } 12711d229e88SPing-Ke Shih 12721d229e88SPing-Ke Shih return ret; 12731d229e88SPing-Ke Shih 12741d229e88SPing-Ke Shih check_sim: 12751d229e88SPing-Ke Shih for (i = 0; i < IQK_NR; i++) { 12761d229e88SPing-Ke Shih j = i & ~1; /* 2 bits are a pair for IQ[X, Y] */ 12771d229e88SPing-Ke Shih if (bitmap & GENMASK(j + 1, j)) 12781d229e88SPing-Ke Shih continue; 12791d229e88SPing-Ke Shih 12801d229e88SPing-Ke Shih result[IQK_ROUND_HYBRID][i] = result[c1][i]; 12811d229e88SPing-Ke Shih } 12821d229e88SPing-Ke Shih 12831d229e88SPing-Ke Shih return false; 12841d229e88SPing-Ke Shih } 12851d229e88SPing-Ke Shih 12861d229e88SPing-Ke Shih static 12871d229e88SPing-Ke Shih void rtw8723d_iqk_precfg_path(struct rtw_dev *rtwdev, enum rtw8723d_path path) 12881d229e88SPing-Ke Shih { 12891d229e88SPing-Ke Shih if (path == PATH_S0) { 12901d229e88SPing-Ke Shih rtw8723d_iqk_rf_standby(rtwdev, RF_PATH_A); 12911d229e88SPing-Ke Shih rtw8723d_iqk_path_adda_on(rtwdev); 12921d229e88SPing-Ke Shih } 12931d229e88SPing-Ke Shih 12941d229e88SPing-Ke Shih rtw_write32_mask(rtwdev, REG_FPGA0_IQK_11N, BIT_MASK_IQK_MOD, EN_IQK); 12951d229e88SPing-Ke Shih rtw_write32(rtwdev, REG_TXIQK_11N, 0x01007c00); 12961d229e88SPing-Ke Shih rtw_write32(rtwdev, REG_RXIQK_11N, 0x01004800); 12971d229e88SPing-Ke Shih 12981d229e88SPing-Ke Shih if (path == PATH_S1) { 12991d229e88SPing-Ke Shih rtw8723d_iqk_rf_standby(rtwdev, RF_PATH_B); 13001d229e88SPing-Ke Shih rtw8723d_iqk_path_adda_on(rtwdev); 13011d229e88SPing-Ke Shih } 13021d229e88SPing-Ke Shih } 13031d229e88SPing-Ke Shih 13041d229e88SPing-Ke Shih static 13051d229e88SPing-Ke Shih void rtw8723d_iqk_one_round(struct rtw_dev *rtwdev, s32 result[][IQK_NR], u8 t, 13061d229e88SPing-Ke Shih const struct iqk_backup_regs *backup) 13071d229e88SPing-Ke Shih { 13081d229e88SPing-Ke Shih u32 i; 13091d229e88SPing-Ke Shih u8 s1_ok, s0_ok; 13101d229e88SPing-Ke Shih 13111d229e88SPing-Ke Shih rtw_dbg(rtwdev, RTW_DBG_RFK, 13121d229e88SPing-Ke Shih "[IQK] IQ Calibration for 1T1R_S0/S1 for %d times\n", t); 13131d229e88SPing-Ke Shih 13141d229e88SPing-Ke Shih rtw8723d_iqk_path_adda_on(rtwdev); 13151d229e88SPing-Ke Shih rtw8723d_iqk_config_mac(rtwdev); 13161d229e88SPing-Ke Shih rtw_write32_mask(rtwdev, REG_CCK_ANT_SEL_11N, 0x0f000000, 0xf); 13171d229e88SPing-Ke Shih rtw_write32(rtwdev, REG_BB_RX_PATH_11N, 0x03a05611); 13181d229e88SPing-Ke Shih rtw_write32(rtwdev, REG_TRMUX_11N, 0x000800e4); 13191d229e88SPing-Ke Shih rtw_write32(rtwdev, REG_BB_PWR_SAV1_11N, 0x25204200); 13201d229e88SPing-Ke Shih rtw8723d_iqk_precfg_path(rtwdev, PATH_S1); 13211d229e88SPing-Ke Shih 13221d229e88SPing-Ke Shih for (i = 0; i < PATH_IQK_RETRY; i++) { 13231d229e88SPing-Ke Shih s1_ok = rtw8723d_iqk_tx_path(rtwdev, &iqk_tx_cfg[PATH_S1], backup); 13241d229e88SPing-Ke Shih if (s1_ok == IQK_TX_OK) { 13251d229e88SPing-Ke Shih rtw_dbg(rtwdev, RTW_DBG_RFK, 13261d229e88SPing-Ke Shih "[IQK] path S1 Tx IQK Success!!\n"); 13271d229e88SPing-Ke Shih result[t][IQK_S1_TX_X] = 13281d229e88SPing-Ke Shih rtw_read32_mask(rtwdev, REG_IQK_RES_TX, BIT_MASK_RES_TX); 13291d229e88SPing-Ke Shih result[t][IQK_S1_TX_Y] = 13301d229e88SPing-Ke Shih rtw_read32_mask(rtwdev, REG_IQK_RES_TY, BIT_MASK_RES_TY); 13311d229e88SPing-Ke Shih break; 13321d229e88SPing-Ke Shih } 13331d229e88SPing-Ke Shih 13341d229e88SPing-Ke Shih rtw_dbg(rtwdev, RTW_DBG_RFK, "[IQK] path S1 Tx IQK Fail!!\n"); 13351d229e88SPing-Ke Shih result[t][IQK_S1_TX_X] = 0x100; 13361d229e88SPing-Ke Shih result[t][IQK_S1_TX_Y] = 0x0; 13371d229e88SPing-Ke Shih } 13381d229e88SPing-Ke Shih 13391d229e88SPing-Ke Shih for (i = 0; i < PATH_IQK_RETRY; i++) { 13401d229e88SPing-Ke Shih s1_ok = rtw8723d_iqk_rx_path(rtwdev, &iqk_tx_cfg[PATH_S1], backup); 13411d229e88SPing-Ke Shih if (s1_ok == (IQK_TX_OK | IQK_RX_OK)) { 13421d229e88SPing-Ke Shih rtw_dbg(rtwdev, RTW_DBG_RFK, 13431d229e88SPing-Ke Shih "[IQK] path S1 Rx IQK Success!!\n"); 13441d229e88SPing-Ke Shih result[t][IQK_S1_RX_X] = 13451d229e88SPing-Ke Shih rtw_read32_mask(rtwdev, REG_IQK_RES_RX, BIT_MASK_RES_RX); 13461d229e88SPing-Ke Shih result[t][IQK_S1_RX_Y] = 13471d229e88SPing-Ke Shih rtw_read32_mask(rtwdev, REG_IQK_RES_RY, BIT_MASK_RES_RY); 13481d229e88SPing-Ke Shih break; 13491d229e88SPing-Ke Shih } 13501d229e88SPing-Ke Shih 13511d229e88SPing-Ke Shih rtw_dbg(rtwdev, RTW_DBG_RFK, "[IQK] path S1 Rx IQK Fail!!\n"); 13521d229e88SPing-Ke Shih result[t][IQK_S1_RX_X] = 0x100; 13531d229e88SPing-Ke Shih result[t][IQK_S1_RX_Y] = 0x0; 13541d229e88SPing-Ke Shih } 13551d229e88SPing-Ke Shih 13561d229e88SPing-Ke Shih if (s1_ok == 0x0) 13571d229e88SPing-Ke Shih rtw_dbg(rtwdev, RTW_DBG_RFK, "[IQK] path S1 IQK is failed!!\n"); 13581d229e88SPing-Ke Shih 13591d229e88SPing-Ke Shih rtw8723d_iqk_precfg_path(rtwdev, PATH_S0); 13601d229e88SPing-Ke Shih 13611d229e88SPing-Ke Shih for (i = 0; i < PATH_IQK_RETRY; i++) { 13621d229e88SPing-Ke Shih s0_ok = rtw8723d_iqk_tx_path(rtwdev, &iqk_tx_cfg[PATH_S0], backup); 13631d229e88SPing-Ke Shih if (s0_ok == IQK_TX_OK) { 13641d229e88SPing-Ke Shih rtw_dbg(rtwdev, RTW_DBG_RFK, 13651d229e88SPing-Ke Shih "[IQK] path S0 Tx IQK Success!!\n"); 13661d229e88SPing-Ke Shih result[t][IQK_S0_TX_X] = 13671d229e88SPing-Ke Shih rtw_read32_mask(rtwdev, REG_IQK_RES_TX, BIT_MASK_RES_TX); 13681d229e88SPing-Ke Shih result[t][IQK_S0_TX_Y] = 13691d229e88SPing-Ke Shih rtw_read32_mask(rtwdev, REG_IQK_RES_TY, BIT_MASK_RES_TY); 13701d229e88SPing-Ke Shih break; 13711d229e88SPing-Ke Shih } 13721d229e88SPing-Ke Shih 13731d229e88SPing-Ke Shih rtw_dbg(rtwdev, RTW_DBG_RFK, "[IQK] path S0 Tx IQK Fail!!\n"); 13741d229e88SPing-Ke Shih result[t][IQK_S0_TX_X] = 0x100; 13751d229e88SPing-Ke Shih result[t][IQK_S0_TX_Y] = 0x0; 13761d229e88SPing-Ke Shih } 13771d229e88SPing-Ke Shih 13781d229e88SPing-Ke Shih for (i = 0; i < PATH_IQK_RETRY; i++) { 13791d229e88SPing-Ke Shih s0_ok = rtw8723d_iqk_rx_path(rtwdev, &iqk_tx_cfg[PATH_S0], backup); 13801d229e88SPing-Ke Shih if (s0_ok == (IQK_TX_OK | IQK_RX_OK)) { 13811d229e88SPing-Ke Shih rtw_dbg(rtwdev, RTW_DBG_RFK, 13821d229e88SPing-Ke Shih "[IQK] path S0 Rx IQK Success!!\n"); 13831d229e88SPing-Ke Shih 13841d229e88SPing-Ke Shih result[t][IQK_S0_RX_X] = 13851d229e88SPing-Ke Shih rtw_read32_mask(rtwdev, REG_IQK_RES_RX, BIT_MASK_RES_RX); 13861d229e88SPing-Ke Shih result[t][IQK_S0_RX_Y] = 13871d229e88SPing-Ke Shih rtw_read32_mask(rtwdev, REG_IQK_RES_RY, BIT_MASK_RES_RY); 13881d229e88SPing-Ke Shih break; 13891d229e88SPing-Ke Shih } 13901d229e88SPing-Ke Shih 13911d229e88SPing-Ke Shih rtw_dbg(rtwdev, RTW_DBG_RFK, "[IQK] path S0 Rx IQK Fail!!\n"); 13921d229e88SPing-Ke Shih result[t][IQK_S0_RX_X] = 0x100; 13931d229e88SPing-Ke Shih result[t][IQK_S0_RX_Y] = 0x0; 13941d229e88SPing-Ke Shih } 13951d229e88SPing-Ke Shih 13961d229e88SPing-Ke Shih if (s0_ok == 0x0) 13971d229e88SPing-Ke Shih rtw_dbg(rtwdev, RTW_DBG_RFK, "[IQK] path S0 IQK is failed!!\n"); 13981d229e88SPing-Ke Shih 13991d229e88SPing-Ke Shih rtw_write32_mask(rtwdev, REG_FPGA0_IQK_11N, BIT_MASK_IQK_MOD, RST_IQK); 14001d229e88SPing-Ke Shih mdelay(1); 14011d229e88SPing-Ke Shih 14021d229e88SPing-Ke Shih rtw_dbg(rtwdev, RTW_DBG_RFK, 14031d229e88SPing-Ke Shih "[IQK] back to BB mode, load original value!\n"); 14041d229e88SPing-Ke Shih } 14051d229e88SPing-Ke Shih 14061d229e88SPing-Ke Shih static void rtw8723d_phy_calibration(struct rtw_dev *rtwdev) 14071d229e88SPing-Ke Shih { 14081d229e88SPing-Ke Shih struct rtw_dm_info *dm_info = &rtwdev->dm_info; 14091d229e88SPing-Ke Shih s32 result[IQK_ROUND_SIZE][IQK_NR]; 14101d229e88SPing-Ke Shih struct iqk_backup_regs backup; 14111d229e88SPing-Ke Shih u8 i, j; 14121d229e88SPing-Ke Shih u8 final_candidate = IQK_ROUND_INVALID; 14131d229e88SPing-Ke Shih bool good; 14141d229e88SPing-Ke Shih 14151d229e88SPing-Ke Shih rtw_dbg(rtwdev, RTW_DBG_RFK, "[IQK] Start!!!\n"); 14161d229e88SPing-Ke Shih 14171d229e88SPing-Ke Shih memset(result, 0, sizeof(result)); 14181d229e88SPing-Ke Shih 14191d229e88SPing-Ke Shih rtw8723d_iqk_backup_path_ctrl(rtwdev, &backup); 14201d229e88SPing-Ke Shih rtw8723d_iqk_backup_lte_path_gnt(rtwdev, &backup); 14211d229e88SPing-Ke Shih rtw8723d_iqk_backup_regs(rtwdev, &backup); 14221d229e88SPing-Ke Shih 14231d229e88SPing-Ke Shih for (i = IQK_ROUND_0; i <= IQK_ROUND_2; i++) { 14241d229e88SPing-Ke Shih rtw8723d_iqk_config_path_ctrl(rtwdev); 14251d229e88SPing-Ke Shih rtw8723d_iqk_config_lte_path_gnt(rtwdev); 14261d229e88SPing-Ke Shih 14271d229e88SPing-Ke Shih rtw8723d_iqk_one_round(rtwdev, result, i, &backup); 14281d229e88SPing-Ke Shih 14291d229e88SPing-Ke Shih if (i > IQK_ROUND_0) 14301d229e88SPing-Ke Shih rtw8723d_iqk_restore_regs(rtwdev, &backup); 14311d229e88SPing-Ke Shih rtw8723d_iqk_restore_lte_path_gnt(rtwdev, &backup); 14321d229e88SPing-Ke Shih rtw8723d_iqk_restore_path_ctrl(rtwdev, &backup); 14331d229e88SPing-Ke Shih 14341d229e88SPing-Ke Shih for (j = IQK_ROUND_0; j < i; j++) { 14351d229e88SPing-Ke Shih good = rtw8723d_iqk_similarity_cmp(rtwdev, result, j, i); 14361d229e88SPing-Ke Shih 14371d229e88SPing-Ke Shih if (good) { 14381d229e88SPing-Ke Shih final_candidate = j; 14391d229e88SPing-Ke Shih rtw_dbg(rtwdev, RTW_DBG_RFK, 14401d229e88SPing-Ke Shih "[IQK] cmp %d:%d final_candidate is %x\n", 14411d229e88SPing-Ke Shih j, i, final_candidate); 14421d229e88SPing-Ke Shih goto iqk_done; 14431d229e88SPing-Ke Shih } 14441d229e88SPing-Ke Shih } 14451d229e88SPing-Ke Shih } 14461d229e88SPing-Ke Shih 14471d229e88SPing-Ke Shih if (final_candidate == IQK_ROUND_INVALID) { 14481d229e88SPing-Ke Shih s32 reg_tmp = 0; 14491d229e88SPing-Ke Shih 14501d229e88SPing-Ke Shih for (i = 0; i < IQK_NR; i++) 14511d229e88SPing-Ke Shih reg_tmp += result[IQK_ROUND_HYBRID][i]; 14521d229e88SPing-Ke Shih 14531d229e88SPing-Ke Shih if (reg_tmp != 0) { 14541d229e88SPing-Ke Shih final_candidate = IQK_ROUND_HYBRID; 14551d229e88SPing-Ke Shih } else { 14561d229e88SPing-Ke Shih WARN(1, "IQK is failed\n"); 14571d229e88SPing-Ke Shih goto out; 14581d229e88SPing-Ke Shih } 14591d229e88SPing-Ke Shih } 14601d229e88SPing-Ke Shih 14611d229e88SPing-Ke Shih iqk_done: 14621d229e88SPing-Ke Shih rtw8723d_iqk_fill_s1_matrix(rtwdev, result[final_candidate]); 14631d229e88SPing-Ke Shih rtw8723d_iqk_fill_s0_matrix(rtwdev, result[final_candidate]); 14641d229e88SPing-Ke Shih 14651d229e88SPing-Ke Shih dm_info->iqk.result.s1_x = result[final_candidate][IQK_S1_TX_X]; 14661d229e88SPing-Ke Shih dm_info->iqk.result.s1_y = result[final_candidate][IQK_S1_TX_Y]; 14671d229e88SPing-Ke Shih dm_info->iqk.result.s0_x = result[final_candidate][IQK_S0_TX_X]; 14681d229e88SPing-Ke Shih dm_info->iqk.result.s0_y = result[final_candidate][IQK_S0_TX_Y]; 14691d229e88SPing-Ke Shih dm_info->iqk.done = true; 14701d229e88SPing-Ke Shih 14711d229e88SPing-Ke Shih out: 14721d229e88SPing-Ke Shih rtw_write32(rtwdev, REG_BB_SEL_BTG, backup.bb_sel_btg); 14731d229e88SPing-Ke Shih 14741d229e88SPing-Ke Shih rtw_dbg(rtwdev, RTW_DBG_RFK, "[IQK] final_candidate is %x\n", 14751d229e88SPing-Ke Shih final_candidate); 14761d229e88SPing-Ke Shih 14771d229e88SPing-Ke Shih for (i = IQK_ROUND_0; i < IQK_ROUND_SIZE; i++) 14781d229e88SPing-Ke Shih rtw_dbg(rtwdev, RTW_DBG_RFK, 14791d229e88SPing-Ke Shih "[IQK] Result %u: rege94_s1=%x rege9c_s1=%x regea4_s1=%x regeac_s1=%x rege94_s0=%x rege9c_s0=%x regea4_s0=%x regeac_s0=%x %s\n", 14801d229e88SPing-Ke Shih i, 14811d229e88SPing-Ke Shih result[i][0], result[i][1], result[i][2], result[i][3], 14821d229e88SPing-Ke Shih result[i][4], result[i][5], result[i][6], result[i][7], 14831d229e88SPing-Ke Shih final_candidate == i ? "(final candidate)" : ""); 14841d229e88SPing-Ke Shih 14851d229e88SPing-Ke Shih rtw_dbg(rtwdev, RTW_DBG_RFK, 14861d229e88SPing-Ke Shih "[IQK]0xc80 = 0x%x 0xc94 = 0x%x 0xc14 = 0x%x 0xca0 = 0x%x\n", 14871d229e88SPing-Ke Shih rtw_read32(rtwdev, REG_OFDM_0_XA_TX_IQ_IMBALANCE), 14881d229e88SPing-Ke Shih rtw_read32(rtwdev, REG_TXIQK_MATRIXA_LSB2_11N), 14891d229e88SPing-Ke Shih rtw_read32(rtwdev, REG_A_RXIQI), 14901d229e88SPing-Ke Shih rtw_read32(rtwdev, REG_RXIQK_MATRIX_LSB_11N)); 14911d229e88SPing-Ke Shih rtw_dbg(rtwdev, RTW_DBG_RFK, 14921d229e88SPing-Ke Shih "[IQK]0xcd0 = 0x%x 0xcd4 = 0x%x 0xcd8 = 0x%x\n", 14931d229e88SPing-Ke Shih rtw_read32(rtwdev, REG_TXIQ_AB_S0), 14941d229e88SPing-Ke Shih rtw_read32(rtwdev, REG_TXIQ_CD_S0), 14951d229e88SPing-Ke Shih rtw_read32(rtwdev, REG_RXIQ_AB_S0)); 14961d229e88SPing-Ke Shih 14971d229e88SPing-Ke Shih rtw_dbg(rtwdev, RTW_DBG_RFK, "[IQK] finished\n"); 14981d229e88SPing-Ke Shih } 14991d229e88SPing-Ke Shih 1500608d2a08SPing-Ke Shih static u8 rtw8723d_pwrtrack_get_limit_ofdm(struct rtw_dev *rtwdev) 1501608d2a08SPing-Ke Shih { 1502608d2a08SPing-Ke Shih struct rtw_dm_info *dm_info = &rtwdev->dm_info; 1503608d2a08SPing-Ke Shih u8 tx_rate = dm_info->tx_rate; 1504608d2a08SPing-Ke Shih u8 limit_ofdm = 30; 1505608d2a08SPing-Ke Shih 1506608d2a08SPing-Ke Shih switch (tx_rate) { 1507608d2a08SPing-Ke Shih case DESC_RATE1M...DESC_RATE5_5M: 1508608d2a08SPing-Ke Shih case DESC_RATE11M: 1509608d2a08SPing-Ke Shih break; 1510608d2a08SPing-Ke Shih case DESC_RATE6M...DESC_RATE48M: 1511608d2a08SPing-Ke Shih limit_ofdm = 36; 1512608d2a08SPing-Ke Shih break; 1513608d2a08SPing-Ke Shih case DESC_RATE54M: 1514608d2a08SPing-Ke Shih limit_ofdm = 34; 1515608d2a08SPing-Ke Shih break; 1516608d2a08SPing-Ke Shih case DESC_RATEMCS0...DESC_RATEMCS2: 1517608d2a08SPing-Ke Shih limit_ofdm = 38; 1518608d2a08SPing-Ke Shih break; 1519608d2a08SPing-Ke Shih case DESC_RATEMCS3...DESC_RATEMCS4: 1520608d2a08SPing-Ke Shih limit_ofdm = 36; 1521608d2a08SPing-Ke Shih break; 1522608d2a08SPing-Ke Shih case DESC_RATEMCS5...DESC_RATEMCS7: 1523608d2a08SPing-Ke Shih limit_ofdm = 34; 1524608d2a08SPing-Ke Shih break; 1525608d2a08SPing-Ke Shih default: 1526608d2a08SPing-Ke Shih rtw_warn(rtwdev, "pwrtrack unhandled tx_rate 0x%x\n", tx_rate); 1527608d2a08SPing-Ke Shih break; 1528608d2a08SPing-Ke Shih } 1529608d2a08SPing-Ke Shih 1530608d2a08SPing-Ke Shih return limit_ofdm; 1531608d2a08SPing-Ke Shih } 1532608d2a08SPing-Ke Shih 1533608d2a08SPing-Ke Shih static void rtw8723d_set_iqk_matrix_by_result(struct rtw_dev *rtwdev, 1534608d2a08SPing-Ke Shih u32 ofdm_swing, u8 rf_path) 1535608d2a08SPing-Ke Shih { 1536608d2a08SPing-Ke Shih struct rtw_dm_info *dm_info = &rtwdev->dm_info; 1537608d2a08SPing-Ke Shih s32 ele_A, ele_D, ele_C; 1538608d2a08SPing-Ke Shih s32 ele_A_ext, ele_C_ext, ele_D_ext; 1539608d2a08SPing-Ke Shih s32 iqk_result_x; 1540608d2a08SPing-Ke Shih s32 iqk_result_y; 1541608d2a08SPing-Ke Shih s32 value32; 1542608d2a08SPing-Ke Shih 1543608d2a08SPing-Ke Shih switch (rf_path) { 1544608d2a08SPing-Ke Shih default: 1545608d2a08SPing-Ke Shih case RF_PATH_A: 1546608d2a08SPing-Ke Shih iqk_result_x = dm_info->iqk.result.s1_x; 1547608d2a08SPing-Ke Shih iqk_result_y = dm_info->iqk.result.s1_y; 1548608d2a08SPing-Ke Shih break; 1549608d2a08SPing-Ke Shih case RF_PATH_B: 1550608d2a08SPing-Ke Shih iqk_result_x = dm_info->iqk.result.s0_x; 1551608d2a08SPing-Ke Shih iqk_result_y = dm_info->iqk.result.s0_y; 1552608d2a08SPing-Ke Shih break; 1553608d2a08SPing-Ke Shih } 1554608d2a08SPing-Ke Shih 1555608d2a08SPing-Ke Shih /* new element D */ 1556608d2a08SPing-Ke Shih ele_D = OFDM_SWING_D(ofdm_swing); 1557608d2a08SPing-Ke Shih iqk_mult(iqk_result_x, ele_D, &ele_D_ext); 1558608d2a08SPing-Ke Shih /* new element A */ 1559608d2a08SPing-Ke Shih iqk_result_x = iqkxy_to_s32(iqk_result_x); 1560608d2a08SPing-Ke Shih ele_A = iqk_mult(iqk_result_x, ele_D, &ele_A_ext); 1561608d2a08SPing-Ke Shih /* new element C */ 1562608d2a08SPing-Ke Shih iqk_result_y = iqkxy_to_s32(iqk_result_y); 1563608d2a08SPing-Ke Shih ele_C = iqk_mult(iqk_result_y, ele_D, &ele_C_ext); 1564608d2a08SPing-Ke Shih 1565608d2a08SPing-Ke Shih switch (rf_path) { 1566608d2a08SPing-Ke Shih case RF_PATH_A: 1567608d2a08SPing-Ke Shih default: 1568608d2a08SPing-Ke Shih /* write new elements A, C, D, and element B is always 0 */ 1569608d2a08SPing-Ke Shih value32 = BIT_SET_TXIQ_ELM_ACD(ele_A, ele_C, ele_D); 1570608d2a08SPing-Ke Shih rtw_write32(rtwdev, REG_OFDM_0_XA_TX_IQ_IMBALANCE, value32); 1571608d2a08SPing-Ke Shih value32 = BIT_SET_TXIQ_ELM_C1(ele_C); 1572608d2a08SPing-Ke Shih rtw_write32_mask(rtwdev, REG_TXIQK_MATRIXA_LSB2_11N, MASKH4BITS, 1573608d2a08SPing-Ke Shih value32); 1574608d2a08SPing-Ke Shih value32 = rtw_read32(rtwdev, REG_OFDM_0_ECCA_THRESHOLD); 1575608d2a08SPing-Ke Shih value32 &= ~BIT_MASK_OFDM0_EXTS; 1576608d2a08SPing-Ke Shih value32 |= BIT_SET_OFDM0_EXTS(ele_A_ext, ele_C_ext, ele_D_ext); 1577608d2a08SPing-Ke Shih rtw_write32(rtwdev, REG_OFDM_0_ECCA_THRESHOLD, value32); 1578608d2a08SPing-Ke Shih break; 1579608d2a08SPing-Ke Shih 1580608d2a08SPing-Ke Shih case RF_PATH_B: 1581608d2a08SPing-Ke Shih /* write new elements A, C, D, and element B is always 0 */ 1582608d2a08SPing-Ke Shih rtw_write32_mask(rtwdev, REG_TXIQ_CD_S0, BIT_MASK_TXIQ_D_S0, ele_D); 1583608d2a08SPing-Ke Shih rtw_write32_mask(rtwdev, REG_TXIQ_CD_S0, BIT_MASK_TXIQ_C_S0, ele_C); 1584608d2a08SPing-Ke Shih rtw_write32_mask(rtwdev, REG_TXIQ_AB_S0, BIT_MASK_TXIQ_A_S0, ele_A); 1585608d2a08SPing-Ke Shih 1586608d2a08SPing-Ke Shih rtw_write32_mask(rtwdev, REG_TXIQ_CD_S0, BIT_MASK_TXIQ_D_EXT_S0, 1587608d2a08SPing-Ke Shih ele_D_ext); 1588608d2a08SPing-Ke Shih rtw_write32_mask(rtwdev, REG_TXIQ_AB_S0, BIT_MASK_TXIQ_A_EXT_S0, 1589608d2a08SPing-Ke Shih ele_A_ext); 1590608d2a08SPing-Ke Shih rtw_write32_mask(rtwdev, REG_TXIQ_CD_S0, BIT_MASK_TXIQ_C_EXT_S0, 1591608d2a08SPing-Ke Shih ele_C_ext); 1592608d2a08SPing-Ke Shih break; 1593608d2a08SPing-Ke Shih } 1594608d2a08SPing-Ke Shih } 1595608d2a08SPing-Ke Shih 1596608d2a08SPing-Ke Shih static void rtw8723d_set_iqk_matrix(struct rtw_dev *rtwdev, s8 ofdm_index, 1597608d2a08SPing-Ke Shih u8 rf_path) 1598608d2a08SPing-Ke Shih { 1599608d2a08SPing-Ke Shih struct rtw_dm_info *dm_info = &rtwdev->dm_info; 1600608d2a08SPing-Ke Shih s32 value32; 1601608d2a08SPing-Ke Shih u32 ofdm_swing; 1602608d2a08SPing-Ke Shih 1603608d2a08SPing-Ke Shih if (ofdm_index >= RTW_OFDM_SWING_TABLE_SIZE) 1604608d2a08SPing-Ke Shih ofdm_index = RTW_OFDM_SWING_TABLE_SIZE - 1; 1605608d2a08SPing-Ke Shih else if (ofdm_index < 0) 1606608d2a08SPing-Ke Shih ofdm_index = 0; 1607608d2a08SPing-Ke Shih 1608608d2a08SPing-Ke Shih ofdm_swing = rtw8723d_ofdm_swing_table[ofdm_index]; 1609608d2a08SPing-Ke Shih 1610608d2a08SPing-Ke Shih if (dm_info->iqk.done) { 1611608d2a08SPing-Ke Shih rtw8723d_set_iqk_matrix_by_result(rtwdev, ofdm_swing, rf_path); 1612608d2a08SPing-Ke Shih return; 1613608d2a08SPing-Ke Shih } 1614608d2a08SPing-Ke Shih 1615608d2a08SPing-Ke Shih switch (rf_path) { 1616608d2a08SPing-Ke Shih case RF_PATH_A: 1617608d2a08SPing-Ke Shih default: 1618608d2a08SPing-Ke Shih rtw_write32(rtwdev, REG_OFDM_0_XA_TX_IQ_IMBALANCE, ofdm_swing); 1619608d2a08SPing-Ke Shih rtw_write32_mask(rtwdev, REG_TXIQK_MATRIXA_LSB2_11N, MASKH4BITS, 1620608d2a08SPing-Ke Shih 0x00); 1621608d2a08SPing-Ke Shih value32 = rtw_read32(rtwdev, REG_OFDM_0_ECCA_THRESHOLD); 1622608d2a08SPing-Ke Shih value32 &= ~BIT_MASK_OFDM0_EXTS; 1623608d2a08SPing-Ke Shih rtw_write32(rtwdev, REG_OFDM_0_ECCA_THRESHOLD, value32); 1624608d2a08SPing-Ke Shih break; 1625608d2a08SPing-Ke Shih 1626608d2a08SPing-Ke Shih case RF_PATH_B: 1627608d2a08SPing-Ke Shih /* image S1:c80 to S0:Cd0 and Cd4 */ 1628608d2a08SPing-Ke Shih rtw_write32_mask(rtwdev, REG_TXIQ_AB_S0, BIT_MASK_TXIQ_A_S0, 1629608d2a08SPing-Ke Shih OFDM_SWING_A(ofdm_swing)); 1630608d2a08SPing-Ke Shih rtw_write32_mask(rtwdev, REG_TXIQ_AB_S0, BIT_MASK_TXIQ_B_S0, 1631608d2a08SPing-Ke Shih OFDM_SWING_B(ofdm_swing)); 1632608d2a08SPing-Ke Shih rtw_write32_mask(rtwdev, REG_TXIQ_CD_S0, BIT_MASK_TXIQ_C_S0, 1633608d2a08SPing-Ke Shih OFDM_SWING_C(ofdm_swing)); 1634608d2a08SPing-Ke Shih rtw_write32_mask(rtwdev, REG_TXIQ_CD_S0, BIT_MASK_TXIQ_D_S0, 1635608d2a08SPing-Ke Shih OFDM_SWING_D(ofdm_swing)); 1636608d2a08SPing-Ke Shih rtw_write32_mask(rtwdev, REG_TXIQ_CD_S0, BIT_MASK_TXIQ_D_EXT_S0, 0x0); 1637608d2a08SPing-Ke Shih rtw_write32_mask(rtwdev, REG_TXIQ_CD_S0, BIT_MASK_TXIQ_C_EXT_S0, 0x0); 1638608d2a08SPing-Ke Shih rtw_write32_mask(rtwdev, REG_TXIQ_AB_S0, BIT_MASK_TXIQ_A_EXT_S0, 0x0); 1639608d2a08SPing-Ke Shih break; 1640608d2a08SPing-Ke Shih } 1641608d2a08SPing-Ke Shih } 1642608d2a08SPing-Ke Shih 1643608d2a08SPing-Ke Shih static void rtw8723d_pwrtrack_set_ofdm_pwr(struct rtw_dev *rtwdev, s8 swing_idx, 1644608d2a08SPing-Ke Shih s8 txagc_idx) 1645608d2a08SPing-Ke Shih { 1646608d2a08SPing-Ke Shih struct rtw_dm_info *dm_info = &rtwdev->dm_info; 1647608d2a08SPing-Ke Shih 1648608d2a08SPing-Ke Shih dm_info->txagc_remnant_ofdm = txagc_idx; 1649608d2a08SPing-Ke Shih 1650608d2a08SPing-Ke Shih rtw8723d_set_iqk_matrix(rtwdev, swing_idx, RF_PATH_A); 1651608d2a08SPing-Ke Shih rtw8723d_set_iqk_matrix(rtwdev, swing_idx, RF_PATH_B); 1652608d2a08SPing-Ke Shih } 1653608d2a08SPing-Ke Shih 1654608d2a08SPing-Ke Shih static void rtw8723d_pwrtrack_set_cck_pwr(struct rtw_dev *rtwdev, s8 swing_idx, 1655608d2a08SPing-Ke Shih s8 txagc_idx) 1656608d2a08SPing-Ke Shih { 1657608d2a08SPing-Ke Shih struct rtw_dm_info *dm_info = &rtwdev->dm_info; 1658608d2a08SPing-Ke Shih 1659608d2a08SPing-Ke Shih dm_info->txagc_remnant_cck = txagc_idx; 1660608d2a08SPing-Ke Shih 1661608d2a08SPing-Ke Shih rtw_write32_mask(rtwdev, 0xab4, 0x000007FF, 1662608d2a08SPing-Ke Shih rtw8723d_cck_swing_table[swing_idx]); 1663608d2a08SPing-Ke Shih } 1664608d2a08SPing-Ke Shih 1665608d2a08SPing-Ke Shih static void rtw8723d_pwrtrack_set(struct rtw_dev *rtwdev, u8 path) 1666608d2a08SPing-Ke Shih { 1667608d2a08SPing-Ke Shih struct rtw_dm_info *dm_info = &rtwdev->dm_info; 1668608d2a08SPing-Ke Shih struct rtw_hal *hal = &rtwdev->hal; 1669608d2a08SPing-Ke Shih u8 limit_ofdm; 1670608d2a08SPing-Ke Shih u8 limit_cck = 40; 1671608d2a08SPing-Ke Shih s8 final_ofdm_swing_index; 1672608d2a08SPing-Ke Shih s8 final_cck_swing_index; 1673608d2a08SPing-Ke Shih 1674608d2a08SPing-Ke Shih limit_ofdm = rtw8723d_pwrtrack_get_limit_ofdm(rtwdev); 1675608d2a08SPing-Ke Shih 1676608d2a08SPing-Ke Shih final_ofdm_swing_index = RTW_DEF_OFDM_SWING_INDEX + 1677608d2a08SPing-Ke Shih dm_info->delta_power_index[path]; 1678608d2a08SPing-Ke Shih final_cck_swing_index = RTW_DEF_CCK_SWING_INDEX + 1679608d2a08SPing-Ke Shih dm_info->delta_power_index[path]; 1680608d2a08SPing-Ke Shih 1681608d2a08SPing-Ke Shih if (final_ofdm_swing_index > limit_ofdm) 1682608d2a08SPing-Ke Shih rtw8723d_pwrtrack_set_ofdm_pwr(rtwdev, limit_ofdm, 1683608d2a08SPing-Ke Shih final_ofdm_swing_index - limit_ofdm); 1684608d2a08SPing-Ke Shih else if (final_ofdm_swing_index < 0) 1685608d2a08SPing-Ke Shih rtw8723d_pwrtrack_set_ofdm_pwr(rtwdev, 0, 1686608d2a08SPing-Ke Shih final_ofdm_swing_index); 1687608d2a08SPing-Ke Shih else 1688608d2a08SPing-Ke Shih rtw8723d_pwrtrack_set_ofdm_pwr(rtwdev, final_ofdm_swing_index, 0); 1689608d2a08SPing-Ke Shih 1690608d2a08SPing-Ke Shih if (final_cck_swing_index > limit_cck) 1691608d2a08SPing-Ke Shih rtw8723d_pwrtrack_set_cck_pwr(rtwdev, limit_cck, 1692608d2a08SPing-Ke Shih final_cck_swing_index - limit_cck); 1693608d2a08SPing-Ke Shih else if (final_cck_swing_index < 0) 1694608d2a08SPing-Ke Shih rtw8723d_pwrtrack_set_cck_pwr(rtwdev, 0, 1695608d2a08SPing-Ke Shih final_cck_swing_index); 1696608d2a08SPing-Ke Shih else 1697608d2a08SPing-Ke Shih rtw8723d_pwrtrack_set_cck_pwr(rtwdev, final_cck_swing_index, 0); 1698608d2a08SPing-Ke Shih 1699608d2a08SPing-Ke Shih rtw_phy_set_tx_power_level(rtwdev, hal->current_channel); 1700608d2a08SPing-Ke Shih } 1701608d2a08SPing-Ke Shih 1702608d2a08SPing-Ke Shih static void rtw8723d_pwrtrack_set_xtal(struct rtw_dev *rtwdev, u8 therm_path, 1703608d2a08SPing-Ke Shih u8 delta) 1704608d2a08SPing-Ke Shih { 1705608d2a08SPing-Ke Shih struct rtw_dm_info *dm_info = &rtwdev->dm_info; 1706608d2a08SPing-Ke Shih const struct rtw_pwr_track_tbl *tbl = rtwdev->chip->pwr_track_tbl; 1707608d2a08SPing-Ke Shih const s8 *pwrtrk_xtal; 1708608d2a08SPing-Ke Shih s8 xtal_cap; 1709608d2a08SPing-Ke Shih 1710608d2a08SPing-Ke Shih if (dm_info->thermal_avg[therm_path] > 1711608d2a08SPing-Ke Shih rtwdev->efuse.thermal_meter[therm_path]) 1712608d2a08SPing-Ke Shih pwrtrk_xtal = tbl->pwrtrk_xtal_p; 1713608d2a08SPing-Ke Shih else 1714608d2a08SPing-Ke Shih pwrtrk_xtal = tbl->pwrtrk_xtal_n; 1715608d2a08SPing-Ke Shih 1716608d2a08SPing-Ke Shih xtal_cap = rtwdev->efuse.crystal_cap & 0x3F; 1717608d2a08SPing-Ke Shih xtal_cap = clamp_t(s8, xtal_cap + pwrtrk_xtal[delta], 0, 0x3F); 1718608d2a08SPing-Ke Shih rtw_write32_mask(rtwdev, REG_AFE_CTRL3, BIT_MASK_XTAL, 1719608d2a08SPing-Ke Shih xtal_cap | (xtal_cap << 6)); 1720608d2a08SPing-Ke Shih } 1721608d2a08SPing-Ke Shih 1722608d2a08SPing-Ke Shih static void rtw8723d_phy_pwrtrack(struct rtw_dev *rtwdev) 1723608d2a08SPing-Ke Shih { 1724608d2a08SPing-Ke Shih struct rtw_dm_info *dm_info = &rtwdev->dm_info; 1725608d2a08SPing-Ke Shih struct rtw_swing_table swing_table; 1726608d2a08SPing-Ke Shih u8 thermal_value, delta, path; 1727608d2a08SPing-Ke Shih bool do_iqk = false; 1728608d2a08SPing-Ke Shih 1729608d2a08SPing-Ke Shih rtw_phy_config_swing_table(rtwdev, &swing_table); 1730608d2a08SPing-Ke Shih 1731608d2a08SPing-Ke Shih if (rtwdev->efuse.thermal_meter[0] == 0xff) 1732608d2a08SPing-Ke Shih return; 1733608d2a08SPing-Ke Shih 1734608d2a08SPing-Ke Shih thermal_value = rtw_read_rf(rtwdev, RF_PATH_A, RF_T_METER, 0xfc00); 1735608d2a08SPing-Ke Shih 1736608d2a08SPing-Ke Shih rtw_phy_pwrtrack_avg(rtwdev, thermal_value, RF_PATH_A); 1737608d2a08SPing-Ke Shih 1738608d2a08SPing-Ke Shih do_iqk = rtw_phy_pwrtrack_need_iqk(rtwdev); 1739608d2a08SPing-Ke Shih 1740608d2a08SPing-Ke Shih if (do_iqk) 1741608d2a08SPing-Ke Shih rtw8723d_lck(rtwdev); 1742608d2a08SPing-Ke Shih 1743608d2a08SPing-Ke Shih if (dm_info->pwr_trk_init_trigger) 1744608d2a08SPing-Ke Shih dm_info->pwr_trk_init_trigger = false; 1745608d2a08SPing-Ke Shih else if (!rtw_phy_pwrtrack_thermal_changed(rtwdev, thermal_value, 1746608d2a08SPing-Ke Shih RF_PATH_A)) 1747608d2a08SPing-Ke Shih goto iqk; 1748608d2a08SPing-Ke Shih 1749608d2a08SPing-Ke Shih delta = rtw_phy_pwrtrack_get_delta(rtwdev, RF_PATH_A); 1750608d2a08SPing-Ke Shih 1751608d2a08SPing-Ke Shih delta = min_t(u8, delta, RTW_PWR_TRK_TBL_SZ - 1); 1752608d2a08SPing-Ke Shih 1753608d2a08SPing-Ke Shih for (path = 0; path < rtwdev->hal.rf_path_num; path++) { 1754608d2a08SPing-Ke Shih s8 delta_cur, delta_last; 1755608d2a08SPing-Ke Shih 1756608d2a08SPing-Ke Shih delta_last = dm_info->delta_power_index[path]; 1757608d2a08SPing-Ke Shih delta_cur = rtw_phy_pwrtrack_get_pwridx(rtwdev, &swing_table, 1758608d2a08SPing-Ke Shih path, RF_PATH_A, delta); 1759608d2a08SPing-Ke Shih if (delta_last == delta_cur) 1760608d2a08SPing-Ke Shih continue; 1761608d2a08SPing-Ke Shih 1762608d2a08SPing-Ke Shih dm_info->delta_power_index[path] = delta_cur; 1763608d2a08SPing-Ke Shih rtw8723d_pwrtrack_set(rtwdev, path); 1764608d2a08SPing-Ke Shih } 1765608d2a08SPing-Ke Shih 1766608d2a08SPing-Ke Shih rtw8723d_pwrtrack_set_xtal(rtwdev, RF_PATH_A, delta); 1767608d2a08SPing-Ke Shih 1768608d2a08SPing-Ke Shih iqk: 1769608d2a08SPing-Ke Shih if (do_iqk) 1770608d2a08SPing-Ke Shih rtw8723d_phy_calibration(rtwdev); 1771608d2a08SPing-Ke Shih } 1772608d2a08SPing-Ke Shih 1773608d2a08SPing-Ke Shih void rtw8723d_pwr_track(struct rtw_dev *rtwdev) 1774608d2a08SPing-Ke Shih { 1775608d2a08SPing-Ke Shih struct rtw_efuse *efuse = &rtwdev->efuse; 1776608d2a08SPing-Ke Shih struct rtw_dm_info *dm_info = &rtwdev->dm_info; 1777608d2a08SPing-Ke Shih 1778608d2a08SPing-Ke Shih if (efuse->power_track_type != 0) 1779608d2a08SPing-Ke Shih return; 1780608d2a08SPing-Ke Shih 1781608d2a08SPing-Ke Shih if (!dm_info->pwr_trk_triggered) { 1782608d2a08SPing-Ke Shih rtw_write_rf(rtwdev, RF_PATH_A, RF_T_METER, 1783608d2a08SPing-Ke Shih GENMASK(17, 16), 0x03); 1784608d2a08SPing-Ke Shih dm_info->pwr_trk_triggered = true; 1785608d2a08SPing-Ke Shih return; 1786608d2a08SPing-Ke Shih } 1787608d2a08SPing-Ke Shih 1788608d2a08SPing-Ke Shih rtw8723d_phy_pwrtrack(rtwdev); 1789608d2a08SPing-Ke Shih dm_info->pwr_trk_triggered = false; 1790608d2a08SPing-Ke Shih } 1791608d2a08SPing-Ke Shih 1792811853daSPing-Ke Shih static struct rtw_chip_ops rtw8723d_ops = { 179375e69fb1SPing-Ke Shih .phy_set_param = rtw8723d_phy_set_param, 1794ab0a031eSPing-Ke Shih .read_efuse = rtw8723d_read_efuse, 1795158441a2SPing-Ke Shih .query_rx_desc = rtw8723d_query_rx_desc, 17965f028a9cSPing-Ke Shih .set_channel = rtw8723d_set_channel, 179775e69fb1SPing-Ke Shih .mac_init = rtw8723d_mac_init, 179805202746SPing-Ke Shih .shutdown = rtw8723d_shutdown, 1799e0c27cdbSPing-Ke Shih .read_rf = rtw_phy_read_rf_sipi, 1800e0c27cdbSPing-Ke Shih .write_rf = rtw_phy_write_rf_reg_sipi, 1801ba9f0d1bSPing-Ke Shih .set_tx_power_index = rtw8723d_set_tx_power_index, 1802811853daSPing-Ke Shih .set_antenna = NULL, 18031afb5eb7SPing-Ke Shih .cfg_ldo25 = rtw8723d_cfg_ldo25, 180444baa97cSPing-Ke Shih .efuse_grant = rtw8723d_efuse_grant, 1805439d4a97SPing-Ke Shih .false_alarm_statistics = rtw8723d_false_alarm_statistics, 18061d229e88SPing-Ke Shih .phy_calibration = rtw8723d_phy_calibration, 1807608d2a08SPing-Ke Shih .pwr_track = rtw8723d_pwr_track, 180893ae973fSPing-Ke Shih .config_bfee = NULL, 180993ae973fSPing-Ke Shih .set_gid_table = NULL, 181093ae973fSPing-Ke Shih .cfg_csi_rate = NULL, 1811811853daSPing-Ke Shih }; 1812811853daSPing-Ke Shih 1813c57bd7c3SPing-Ke Shih static const struct rtw_pwr_seq_cmd trans_carddis_to_cardemu_8723d[] = { 1814c57bd7c3SPing-Ke Shih {0x0005, 1815c57bd7c3SPing-Ke Shih RTW_PWR_CUT_ALL_MSK, 1816c57bd7c3SPing-Ke Shih RTW_PWR_INTF_ALL_MSK, 1817c57bd7c3SPing-Ke Shih RTW_PWR_ADDR_MAC, 1818c57bd7c3SPing-Ke Shih RTW_PWR_CMD_WRITE, BIT(3) | BIT(7), 0}, 1819c57bd7c3SPing-Ke Shih {0x0086, 1820c57bd7c3SPing-Ke Shih RTW_PWR_CUT_ALL_MSK, 1821c57bd7c3SPing-Ke Shih RTW_PWR_INTF_SDIO_MSK, 1822c57bd7c3SPing-Ke Shih RTW_PWR_ADDR_SDIO, 1823c57bd7c3SPing-Ke Shih RTW_PWR_CMD_WRITE, BIT(0), 0}, 1824c57bd7c3SPing-Ke Shih {0x0086, 1825c57bd7c3SPing-Ke Shih RTW_PWR_CUT_ALL_MSK, 1826c57bd7c3SPing-Ke Shih RTW_PWR_INTF_SDIO_MSK, 1827c57bd7c3SPing-Ke Shih RTW_PWR_ADDR_SDIO, 1828c57bd7c3SPing-Ke Shih RTW_PWR_CMD_POLLING, BIT(1), BIT(1)}, 1829c57bd7c3SPing-Ke Shih {0x004A, 1830c57bd7c3SPing-Ke Shih RTW_PWR_CUT_ALL_MSK, 1831c57bd7c3SPing-Ke Shih RTW_PWR_INTF_USB_MSK, 1832c57bd7c3SPing-Ke Shih RTW_PWR_ADDR_MAC, 1833c57bd7c3SPing-Ke Shih RTW_PWR_CMD_WRITE, BIT(0), 0}, 1834c57bd7c3SPing-Ke Shih {0x0005, 1835c57bd7c3SPing-Ke Shih RTW_PWR_CUT_ALL_MSK, 1836c57bd7c3SPing-Ke Shih RTW_PWR_INTF_ALL_MSK, 1837c57bd7c3SPing-Ke Shih RTW_PWR_ADDR_MAC, 1838c57bd7c3SPing-Ke Shih RTW_PWR_CMD_WRITE, BIT(3) | BIT(4), 0}, 1839c57bd7c3SPing-Ke Shih {0x0023, 1840c57bd7c3SPing-Ke Shih RTW_PWR_CUT_ALL_MSK, 1841c57bd7c3SPing-Ke Shih RTW_PWR_INTF_SDIO_MSK, 1842c57bd7c3SPing-Ke Shih RTW_PWR_ADDR_MAC, 1843c57bd7c3SPing-Ke Shih RTW_PWR_CMD_WRITE, BIT(4), 0}, 1844c57bd7c3SPing-Ke Shih {0x0301, 1845c57bd7c3SPing-Ke Shih RTW_PWR_CUT_ALL_MSK, 1846c57bd7c3SPing-Ke Shih RTW_PWR_INTF_PCI_MSK, 1847c57bd7c3SPing-Ke Shih RTW_PWR_ADDR_MAC, 1848c57bd7c3SPing-Ke Shih RTW_PWR_CMD_WRITE, 0xFF, 0}, 1849c57bd7c3SPing-Ke Shih {0xFFFF, 1850c57bd7c3SPing-Ke Shih RTW_PWR_CUT_ALL_MSK, 1851c57bd7c3SPing-Ke Shih RTW_PWR_INTF_ALL_MSK, 1852c57bd7c3SPing-Ke Shih 0, 1853c57bd7c3SPing-Ke Shih RTW_PWR_CMD_END, 0, 0}, 1854c57bd7c3SPing-Ke Shih }; 1855c57bd7c3SPing-Ke Shih 1856c57bd7c3SPing-Ke Shih static const struct rtw_pwr_seq_cmd trans_cardemu_to_act_8723d[] = { 1857c57bd7c3SPing-Ke Shih {0x0020, 1858c57bd7c3SPing-Ke Shih RTW_PWR_CUT_ALL_MSK, 1859c57bd7c3SPing-Ke Shih RTW_PWR_INTF_USB_MSK | RTW_PWR_INTF_SDIO_MSK, 1860c57bd7c3SPing-Ke Shih RTW_PWR_ADDR_MAC, 1861c57bd7c3SPing-Ke Shih RTW_PWR_CMD_WRITE, BIT(0), BIT(0)}, 1862c57bd7c3SPing-Ke Shih {0x0001, 1863c57bd7c3SPing-Ke Shih RTW_PWR_CUT_ALL_MSK, 1864c57bd7c3SPing-Ke Shih RTW_PWR_INTF_USB_MSK | RTW_PWR_INTF_SDIO_MSK, 1865c57bd7c3SPing-Ke Shih RTW_PWR_ADDR_MAC, 1866c57bd7c3SPing-Ke Shih RTW_PWR_CMD_DELAY, 1, RTW_PWR_DELAY_MS}, 1867c57bd7c3SPing-Ke Shih {0x0000, 1868c57bd7c3SPing-Ke Shih RTW_PWR_CUT_ALL_MSK, 1869c57bd7c3SPing-Ke Shih RTW_PWR_INTF_USB_MSK | RTW_PWR_INTF_SDIO_MSK, 1870c57bd7c3SPing-Ke Shih RTW_PWR_ADDR_MAC, 1871c57bd7c3SPing-Ke Shih RTW_PWR_CMD_WRITE, BIT(5), 0}, 1872c57bd7c3SPing-Ke Shih {0x0005, 1873c57bd7c3SPing-Ke Shih RTW_PWR_CUT_ALL_MSK, 1874c57bd7c3SPing-Ke Shih RTW_PWR_INTF_ALL_MSK, 1875c57bd7c3SPing-Ke Shih RTW_PWR_ADDR_MAC, 1876c57bd7c3SPing-Ke Shih RTW_PWR_CMD_WRITE, (BIT(4) | BIT(3) | BIT(2)), 0}, 1877c57bd7c3SPing-Ke Shih {0x0075, 1878c57bd7c3SPing-Ke Shih RTW_PWR_CUT_ALL_MSK, 1879c57bd7c3SPing-Ke Shih RTW_PWR_INTF_PCI_MSK, 1880c57bd7c3SPing-Ke Shih RTW_PWR_ADDR_MAC, 1881c57bd7c3SPing-Ke Shih RTW_PWR_CMD_WRITE, BIT(0), BIT(0)}, 1882c57bd7c3SPing-Ke Shih {0x0006, 1883c57bd7c3SPing-Ke Shih RTW_PWR_CUT_ALL_MSK, 1884c57bd7c3SPing-Ke Shih RTW_PWR_INTF_ALL_MSK, 1885c57bd7c3SPing-Ke Shih RTW_PWR_ADDR_MAC, 1886c57bd7c3SPing-Ke Shih RTW_PWR_CMD_POLLING, BIT(1), BIT(1)}, 1887c57bd7c3SPing-Ke Shih {0x0075, 1888c57bd7c3SPing-Ke Shih RTW_PWR_CUT_ALL_MSK, 1889c57bd7c3SPing-Ke Shih RTW_PWR_INTF_PCI_MSK, 1890c57bd7c3SPing-Ke Shih RTW_PWR_ADDR_MAC, 1891c57bd7c3SPing-Ke Shih RTW_PWR_CMD_WRITE, BIT(0), 0}, 1892c57bd7c3SPing-Ke Shih {0x0006, 1893c57bd7c3SPing-Ke Shih RTW_PWR_CUT_ALL_MSK, 1894c57bd7c3SPing-Ke Shih RTW_PWR_INTF_ALL_MSK, 1895c57bd7c3SPing-Ke Shih RTW_PWR_ADDR_MAC, 1896c57bd7c3SPing-Ke Shih RTW_PWR_CMD_WRITE, BIT(0), BIT(0)}, 1897c57bd7c3SPing-Ke Shih {0x0005, 1898c57bd7c3SPing-Ke Shih RTW_PWR_CUT_ALL_MSK, 1899c57bd7c3SPing-Ke Shih RTW_PWR_INTF_ALL_MSK, 1900c57bd7c3SPing-Ke Shih RTW_PWR_ADDR_MAC, 1901c57bd7c3SPing-Ke Shih RTW_PWR_CMD_POLLING, (BIT(1) | BIT(0)), 0}, 1902c57bd7c3SPing-Ke Shih {0x0005, 1903c57bd7c3SPing-Ke Shih RTW_PWR_CUT_ALL_MSK, 1904c57bd7c3SPing-Ke Shih RTW_PWR_INTF_ALL_MSK, 1905c57bd7c3SPing-Ke Shih RTW_PWR_ADDR_MAC, 1906c57bd7c3SPing-Ke Shih RTW_PWR_CMD_WRITE, BIT(7), 0}, 1907c57bd7c3SPing-Ke Shih {0x0005, 1908c57bd7c3SPing-Ke Shih RTW_PWR_CUT_ALL_MSK, 1909c57bd7c3SPing-Ke Shih RTW_PWR_INTF_ALL_MSK, 1910c57bd7c3SPing-Ke Shih RTW_PWR_ADDR_MAC, 1911c57bd7c3SPing-Ke Shih RTW_PWR_CMD_WRITE, (BIT(4) | BIT(3)), 0}, 1912c57bd7c3SPing-Ke Shih {0x0005, 1913c57bd7c3SPing-Ke Shih RTW_PWR_CUT_ALL_MSK, 1914c57bd7c3SPing-Ke Shih RTW_PWR_INTF_ALL_MSK, 1915c57bd7c3SPing-Ke Shih RTW_PWR_ADDR_MAC, 1916c57bd7c3SPing-Ke Shih RTW_PWR_CMD_WRITE, BIT(0), BIT(0)}, 1917c57bd7c3SPing-Ke Shih {0x0005, 1918c57bd7c3SPing-Ke Shih RTW_PWR_CUT_ALL_MSK, 1919c57bd7c3SPing-Ke Shih RTW_PWR_INTF_ALL_MSK, 1920c57bd7c3SPing-Ke Shih RTW_PWR_ADDR_MAC, 1921c57bd7c3SPing-Ke Shih RTW_PWR_CMD_POLLING, BIT(0), 0}, 1922c57bd7c3SPing-Ke Shih {0x0010, 1923c57bd7c3SPing-Ke Shih RTW_PWR_CUT_ALL_MSK, 1924c57bd7c3SPing-Ke Shih RTW_PWR_INTF_ALL_MSK, 1925c57bd7c3SPing-Ke Shih RTW_PWR_ADDR_MAC, 1926c57bd7c3SPing-Ke Shih RTW_PWR_CMD_WRITE, BIT(6), BIT(6)}, 1927c57bd7c3SPing-Ke Shih {0x0049, 1928c57bd7c3SPing-Ke Shih RTW_PWR_CUT_ALL_MSK, 1929c57bd7c3SPing-Ke Shih RTW_PWR_INTF_ALL_MSK, 1930c57bd7c3SPing-Ke Shih RTW_PWR_ADDR_MAC, 1931c57bd7c3SPing-Ke Shih RTW_PWR_CMD_WRITE, BIT(1), BIT(1)}, 1932c57bd7c3SPing-Ke Shih {0x0063, 1933c57bd7c3SPing-Ke Shih RTW_PWR_CUT_ALL_MSK, 1934c57bd7c3SPing-Ke Shih RTW_PWR_INTF_ALL_MSK, 1935c57bd7c3SPing-Ke Shih RTW_PWR_ADDR_MAC, 1936c57bd7c3SPing-Ke Shih RTW_PWR_CMD_WRITE, BIT(1), BIT(1)}, 1937c57bd7c3SPing-Ke Shih {0x0062, 1938c57bd7c3SPing-Ke Shih RTW_PWR_CUT_ALL_MSK, 1939c57bd7c3SPing-Ke Shih RTW_PWR_INTF_ALL_MSK, 1940c57bd7c3SPing-Ke Shih RTW_PWR_ADDR_MAC, 1941c57bd7c3SPing-Ke Shih RTW_PWR_CMD_WRITE, BIT(1), 0}, 1942c57bd7c3SPing-Ke Shih {0x0058, 1943c57bd7c3SPing-Ke Shih RTW_PWR_CUT_ALL_MSK, 1944c57bd7c3SPing-Ke Shih RTW_PWR_INTF_ALL_MSK, 1945c57bd7c3SPing-Ke Shih RTW_PWR_ADDR_MAC, 1946c57bd7c3SPing-Ke Shih RTW_PWR_CMD_WRITE, BIT(0), BIT(0)}, 1947c57bd7c3SPing-Ke Shih {0x005A, 1948c57bd7c3SPing-Ke Shih RTW_PWR_CUT_ALL_MSK, 1949c57bd7c3SPing-Ke Shih RTW_PWR_INTF_ALL_MSK, 1950c57bd7c3SPing-Ke Shih RTW_PWR_ADDR_MAC, 1951c57bd7c3SPing-Ke Shih RTW_PWR_CMD_WRITE, BIT(1), BIT(1)}, 1952c57bd7c3SPing-Ke Shih {0x0068, 1953c57bd7c3SPing-Ke Shih RTW_PWR_CUT_TEST_MSK, 1954c57bd7c3SPing-Ke Shih RTW_PWR_INTF_ALL_MSK, 1955c57bd7c3SPing-Ke Shih RTW_PWR_ADDR_MAC, 1956c57bd7c3SPing-Ke Shih RTW_PWR_CMD_WRITE, BIT(3), BIT(3)}, 1957c57bd7c3SPing-Ke Shih {0x0069, 1958c57bd7c3SPing-Ke Shih RTW_PWR_CUT_ALL_MSK, 1959c57bd7c3SPing-Ke Shih RTW_PWR_INTF_ALL_MSK, 1960c57bd7c3SPing-Ke Shih RTW_PWR_ADDR_MAC, 1961c57bd7c3SPing-Ke Shih RTW_PWR_CMD_WRITE, BIT(6), BIT(6)}, 1962c57bd7c3SPing-Ke Shih {0x001f, 1963c57bd7c3SPing-Ke Shih RTW_PWR_CUT_ALL_MSK, 1964c57bd7c3SPing-Ke Shih RTW_PWR_INTF_ALL_MSK, 1965c57bd7c3SPing-Ke Shih RTW_PWR_ADDR_MAC, 1966c57bd7c3SPing-Ke Shih RTW_PWR_CMD_WRITE, 0xFF, 0x00}, 1967c57bd7c3SPing-Ke Shih {0x0077, 1968c57bd7c3SPing-Ke Shih RTW_PWR_CUT_ALL_MSK, 1969c57bd7c3SPing-Ke Shih RTW_PWR_INTF_ALL_MSK, 1970c57bd7c3SPing-Ke Shih RTW_PWR_ADDR_MAC, 1971c57bd7c3SPing-Ke Shih RTW_PWR_CMD_WRITE, 0xFF, 0x00}, 1972c57bd7c3SPing-Ke Shih {0x001f, 1973c57bd7c3SPing-Ke Shih RTW_PWR_CUT_ALL_MSK, 1974c57bd7c3SPing-Ke Shih RTW_PWR_INTF_ALL_MSK, 1975c57bd7c3SPing-Ke Shih RTW_PWR_ADDR_MAC, 1976c57bd7c3SPing-Ke Shih RTW_PWR_CMD_WRITE, 0xFF, 0x07}, 1977c57bd7c3SPing-Ke Shih {0x0077, 1978c57bd7c3SPing-Ke Shih RTW_PWR_CUT_ALL_MSK, 1979c57bd7c3SPing-Ke Shih RTW_PWR_INTF_ALL_MSK, 1980c57bd7c3SPing-Ke Shih RTW_PWR_ADDR_MAC, 1981c57bd7c3SPing-Ke Shih RTW_PWR_CMD_WRITE, 0xFF, 0x07}, 1982c57bd7c3SPing-Ke Shih {0xFFFF, 1983c57bd7c3SPing-Ke Shih RTW_PWR_CUT_ALL_MSK, 1984c57bd7c3SPing-Ke Shih RTW_PWR_INTF_ALL_MSK, 1985c57bd7c3SPing-Ke Shih 0, 1986c57bd7c3SPing-Ke Shih RTW_PWR_CMD_END, 0, 0}, 1987c57bd7c3SPing-Ke Shih }; 1988c57bd7c3SPing-Ke Shih 1989c57bd7c3SPing-Ke Shih static const struct rtw_pwr_seq_cmd *card_enable_flow_8723d[] = { 1990c57bd7c3SPing-Ke Shih trans_carddis_to_cardemu_8723d, 1991c57bd7c3SPing-Ke Shih trans_cardemu_to_act_8723d, 1992c57bd7c3SPing-Ke Shih NULL 1993c57bd7c3SPing-Ke Shih }; 1994c57bd7c3SPing-Ke Shih 1995c57bd7c3SPing-Ke Shih static const struct rtw_pwr_seq_cmd trans_act_to_lps_8723d[] = { 1996c57bd7c3SPing-Ke Shih {0x0301, 1997c57bd7c3SPing-Ke Shih RTW_PWR_CUT_ALL_MSK, 1998c57bd7c3SPing-Ke Shih RTW_PWR_INTF_PCI_MSK, 1999c57bd7c3SPing-Ke Shih RTW_PWR_ADDR_MAC, 2000c57bd7c3SPing-Ke Shih RTW_PWR_CMD_WRITE, 0xFF, 0xFF}, 2001c57bd7c3SPing-Ke Shih {0x0522, 2002c57bd7c3SPing-Ke Shih RTW_PWR_CUT_ALL_MSK, 2003c57bd7c3SPing-Ke Shih RTW_PWR_INTF_ALL_MSK, 2004c57bd7c3SPing-Ke Shih RTW_PWR_ADDR_MAC, 2005c57bd7c3SPing-Ke Shih RTW_PWR_CMD_WRITE, 0xFF, 0xFF}, 2006c57bd7c3SPing-Ke Shih {0x05F8, 2007c57bd7c3SPing-Ke Shih RTW_PWR_CUT_ALL_MSK, 2008c57bd7c3SPing-Ke Shih RTW_PWR_INTF_ALL_MSK, 2009c57bd7c3SPing-Ke Shih RTW_PWR_ADDR_MAC, 2010c57bd7c3SPing-Ke Shih RTW_PWR_CMD_POLLING, 0xFF, 0}, 2011c57bd7c3SPing-Ke Shih {0x05F9, 2012c57bd7c3SPing-Ke Shih RTW_PWR_CUT_ALL_MSK, 2013c57bd7c3SPing-Ke Shih RTW_PWR_INTF_ALL_MSK, 2014c57bd7c3SPing-Ke Shih RTW_PWR_ADDR_MAC, 2015c57bd7c3SPing-Ke Shih RTW_PWR_CMD_POLLING, 0xFF, 0}, 2016c57bd7c3SPing-Ke Shih {0x05FA, 2017c57bd7c3SPing-Ke Shih RTW_PWR_CUT_ALL_MSK, 2018c57bd7c3SPing-Ke Shih RTW_PWR_INTF_ALL_MSK, 2019c57bd7c3SPing-Ke Shih RTW_PWR_ADDR_MAC, 2020c57bd7c3SPing-Ke Shih RTW_PWR_CMD_POLLING, 0xFF, 0}, 2021c57bd7c3SPing-Ke Shih {0x05FB, 2022c57bd7c3SPing-Ke Shih RTW_PWR_CUT_ALL_MSK, 2023c57bd7c3SPing-Ke Shih RTW_PWR_INTF_ALL_MSK, 2024c57bd7c3SPing-Ke Shih RTW_PWR_ADDR_MAC, 2025c57bd7c3SPing-Ke Shih RTW_PWR_CMD_POLLING, 0xFF, 0}, 2026c57bd7c3SPing-Ke Shih {0x0002, 2027c57bd7c3SPing-Ke Shih RTW_PWR_CUT_ALL_MSK, 2028c57bd7c3SPing-Ke Shih RTW_PWR_INTF_ALL_MSK, 2029c57bd7c3SPing-Ke Shih RTW_PWR_ADDR_MAC, 2030c57bd7c3SPing-Ke Shih RTW_PWR_CMD_WRITE, BIT(0), 0}, 2031c57bd7c3SPing-Ke Shih {0x0002, 2032c57bd7c3SPing-Ke Shih RTW_PWR_CUT_ALL_MSK, 2033c57bd7c3SPing-Ke Shih RTW_PWR_INTF_ALL_MSK, 2034c57bd7c3SPing-Ke Shih RTW_PWR_ADDR_MAC, 2035c57bd7c3SPing-Ke Shih RTW_PWR_CMD_DELAY, 0, RTW_PWR_DELAY_US}, 2036c57bd7c3SPing-Ke Shih {0x0002, 2037c57bd7c3SPing-Ke Shih RTW_PWR_CUT_ALL_MSK, 2038c57bd7c3SPing-Ke Shih RTW_PWR_INTF_ALL_MSK, 2039c57bd7c3SPing-Ke Shih RTW_PWR_ADDR_MAC, 2040c57bd7c3SPing-Ke Shih RTW_PWR_CMD_WRITE, BIT(1), 0}, 2041c57bd7c3SPing-Ke Shih {0x0100, 2042c57bd7c3SPing-Ke Shih RTW_PWR_CUT_ALL_MSK, 2043c57bd7c3SPing-Ke Shih RTW_PWR_INTF_ALL_MSK, 2044c57bd7c3SPing-Ke Shih RTW_PWR_ADDR_MAC, 2045c57bd7c3SPing-Ke Shih RTW_PWR_CMD_WRITE, 0xFF, 0x03}, 2046c57bd7c3SPing-Ke Shih {0x0101, 2047c57bd7c3SPing-Ke Shih RTW_PWR_CUT_ALL_MSK, 2048c57bd7c3SPing-Ke Shih RTW_PWR_INTF_ALL_MSK, 2049c57bd7c3SPing-Ke Shih RTW_PWR_ADDR_MAC, 2050c57bd7c3SPing-Ke Shih RTW_PWR_CMD_WRITE, BIT(1), 0}, 2051c57bd7c3SPing-Ke Shih {0x0093, 2052c57bd7c3SPing-Ke Shih RTW_PWR_CUT_ALL_MSK, 2053c57bd7c3SPing-Ke Shih RTW_PWR_INTF_SDIO_MSK, 2054c57bd7c3SPing-Ke Shih RTW_PWR_ADDR_MAC, 2055c57bd7c3SPing-Ke Shih RTW_PWR_CMD_WRITE, 0xFF, 0x00}, 2056c57bd7c3SPing-Ke Shih {0x0553, 2057c57bd7c3SPing-Ke Shih RTW_PWR_CUT_ALL_MSK, 2058c57bd7c3SPing-Ke Shih RTW_PWR_INTF_ALL_MSK, 2059c57bd7c3SPing-Ke Shih RTW_PWR_ADDR_MAC, 2060c57bd7c3SPing-Ke Shih RTW_PWR_CMD_WRITE, BIT(5), BIT(5)}, 2061c57bd7c3SPing-Ke Shih {0xFFFF, 2062c57bd7c3SPing-Ke Shih RTW_PWR_CUT_ALL_MSK, 2063c57bd7c3SPing-Ke Shih RTW_PWR_INTF_ALL_MSK, 2064c57bd7c3SPing-Ke Shih 0, 2065c57bd7c3SPing-Ke Shih RTW_PWR_CMD_END, 0, 0}, 2066c57bd7c3SPing-Ke Shih }; 2067c57bd7c3SPing-Ke Shih 2068c57bd7c3SPing-Ke Shih static const struct rtw_pwr_seq_cmd trans_act_to_pre_carddis_8723d[] = { 2069c57bd7c3SPing-Ke Shih {0x0003, 2070c57bd7c3SPing-Ke Shih RTW_PWR_CUT_ALL_MSK, 2071c57bd7c3SPing-Ke Shih RTW_PWR_INTF_ALL_MSK, 2072c57bd7c3SPing-Ke Shih RTW_PWR_ADDR_MAC, 2073c57bd7c3SPing-Ke Shih RTW_PWR_CMD_WRITE, BIT(2), 0}, 2074c57bd7c3SPing-Ke Shih {0x0080, 2075c57bd7c3SPing-Ke Shih RTW_PWR_CUT_ALL_MSK, 2076c57bd7c3SPing-Ke Shih RTW_PWR_INTF_ALL_MSK, 2077c57bd7c3SPing-Ke Shih RTW_PWR_ADDR_MAC, 2078c57bd7c3SPing-Ke Shih RTW_PWR_CMD_WRITE, 0xFF, 0}, 2079c57bd7c3SPing-Ke Shih {0xFFFF, 2080c57bd7c3SPing-Ke Shih RTW_PWR_CUT_ALL_MSK, 2081c57bd7c3SPing-Ke Shih RTW_PWR_INTF_ALL_MSK, 2082c57bd7c3SPing-Ke Shih 0, 2083c57bd7c3SPing-Ke Shih RTW_PWR_CMD_END, 0, 0}, 2084c57bd7c3SPing-Ke Shih }; 2085c57bd7c3SPing-Ke Shih 2086c57bd7c3SPing-Ke Shih static const struct rtw_pwr_seq_cmd trans_act_to_cardemu_8723d[] = { 2087c57bd7c3SPing-Ke Shih {0x0002, 2088c57bd7c3SPing-Ke Shih RTW_PWR_CUT_ALL_MSK, 2089c57bd7c3SPing-Ke Shih RTW_PWR_INTF_ALL_MSK, 2090c57bd7c3SPing-Ke Shih RTW_PWR_ADDR_MAC, 2091c57bd7c3SPing-Ke Shih RTW_PWR_CMD_WRITE, BIT(0), 0}, 2092c57bd7c3SPing-Ke Shih {0x0049, 2093c57bd7c3SPing-Ke Shih RTW_PWR_CUT_ALL_MSK, 2094c57bd7c3SPing-Ke Shih RTW_PWR_INTF_ALL_MSK, 2095c57bd7c3SPing-Ke Shih RTW_PWR_ADDR_MAC, 2096c57bd7c3SPing-Ke Shih RTW_PWR_CMD_WRITE, BIT(1), 0}, 2097c57bd7c3SPing-Ke Shih {0x0006, 2098c57bd7c3SPing-Ke Shih RTW_PWR_CUT_ALL_MSK, 2099c57bd7c3SPing-Ke Shih RTW_PWR_INTF_ALL_MSK, 2100c57bd7c3SPing-Ke Shih RTW_PWR_ADDR_MAC, 2101c57bd7c3SPing-Ke Shih RTW_PWR_CMD_WRITE, BIT(0), BIT(0)}, 2102c57bd7c3SPing-Ke Shih {0x0005, 2103c57bd7c3SPing-Ke Shih RTW_PWR_CUT_ALL_MSK, 2104c57bd7c3SPing-Ke Shih RTW_PWR_INTF_ALL_MSK, 2105c57bd7c3SPing-Ke Shih RTW_PWR_ADDR_MAC, 2106c57bd7c3SPing-Ke Shih RTW_PWR_CMD_WRITE, BIT(1), BIT(1)}, 2107c57bd7c3SPing-Ke Shih {0x0005, 2108c57bd7c3SPing-Ke Shih RTW_PWR_CUT_ALL_MSK, 2109c57bd7c3SPing-Ke Shih RTW_PWR_INTF_ALL_MSK, 2110c57bd7c3SPing-Ke Shih RTW_PWR_ADDR_MAC, 2111c57bd7c3SPing-Ke Shih RTW_PWR_CMD_POLLING, BIT(1), 0}, 2112c57bd7c3SPing-Ke Shih {0x0010, 2113c57bd7c3SPing-Ke Shih RTW_PWR_CUT_ALL_MSK, 2114c57bd7c3SPing-Ke Shih RTW_PWR_INTF_ALL_MSK, 2115c57bd7c3SPing-Ke Shih RTW_PWR_ADDR_MAC, 2116c57bd7c3SPing-Ke Shih RTW_PWR_CMD_WRITE, BIT(6), 0}, 2117c57bd7c3SPing-Ke Shih {0x0000, 2118c57bd7c3SPing-Ke Shih RTW_PWR_CUT_ALL_MSK, 2119c57bd7c3SPing-Ke Shih RTW_PWR_INTF_USB_MSK | RTW_PWR_INTF_SDIO_MSK, 2120c57bd7c3SPing-Ke Shih RTW_PWR_ADDR_MAC, 2121c57bd7c3SPing-Ke Shih RTW_PWR_CMD_WRITE, BIT(5), BIT(5)}, 2122c57bd7c3SPing-Ke Shih {0x0020, 2123c57bd7c3SPing-Ke Shih RTW_PWR_CUT_ALL_MSK, 2124c57bd7c3SPing-Ke Shih RTW_PWR_INTF_USB_MSK | RTW_PWR_INTF_SDIO_MSK, 2125c57bd7c3SPing-Ke Shih RTW_PWR_ADDR_MAC, 2126c57bd7c3SPing-Ke Shih RTW_PWR_CMD_WRITE, BIT(0), 0}, 2127c57bd7c3SPing-Ke Shih {0xFFFF, 2128c57bd7c3SPing-Ke Shih RTW_PWR_CUT_ALL_MSK, 2129c57bd7c3SPing-Ke Shih RTW_PWR_INTF_ALL_MSK, 2130c57bd7c3SPing-Ke Shih 0, 2131c57bd7c3SPing-Ke Shih RTW_PWR_CMD_END, 0, 0}, 2132c57bd7c3SPing-Ke Shih }; 2133c57bd7c3SPing-Ke Shih 2134c57bd7c3SPing-Ke Shih static const struct rtw_pwr_seq_cmd trans_cardemu_to_carddis_8723d[] = { 2135c57bd7c3SPing-Ke Shih {0x0007, 2136c57bd7c3SPing-Ke Shih RTW_PWR_CUT_ALL_MSK, 2137c57bd7c3SPing-Ke Shih RTW_PWR_INTF_SDIO_MSK, 2138c57bd7c3SPing-Ke Shih RTW_PWR_ADDR_MAC, 2139c57bd7c3SPing-Ke Shih RTW_PWR_CMD_WRITE, 0xFF, 0x20}, 2140c57bd7c3SPing-Ke Shih {0x0005, 2141c57bd7c3SPing-Ke Shih RTW_PWR_CUT_ALL_MSK, 2142c57bd7c3SPing-Ke Shih RTW_PWR_INTF_USB_MSK | RTW_PWR_INTF_SDIO_MSK, 2143c57bd7c3SPing-Ke Shih RTW_PWR_ADDR_MAC, 2144c57bd7c3SPing-Ke Shih RTW_PWR_CMD_WRITE, BIT(3) | BIT(4), BIT(3)}, 2145c57bd7c3SPing-Ke Shih {0x0005, 2146c57bd7c3SPing-Ke Shih RTW_PWR_CUT_ALL_MSK, 2147c57bd7c3SPing-Ke Shih RTW_PWR_INTF_PCI_MSK, 2148c57bd7c3SPing-Ke Shih RTW_PWR_ADDR_MAC, 2149c57bd7c3SPing-Ke Shih RTW_PWR_CMD_WRITE, BIT(2), BIT(2)}, 2150c57bd7c3SPing-Ke Shih {0x0005, 2151c57bd7c3SPing-Ke Shih RTW_PWR_CUT_ALL_MSK, 2152c57bd7c3SPing-Ke Shih RTW_PWR_INTF_PCI_MSK, 2153c57bd7c3SPing-Ke Shih RTW_PWR_ADDR_MAC, 2154c57bd7c3SPing-Ke Shih RTW_PWR_CMD_WRITE, BIT(3) | BIT(4), BIT(3) | BIT(4)}, 2155c57bd7c3SPing-Ke Shih {0x004A, 2156c57bd7c3SPing-Ke Shih RTW_PWR_CUT_ALL_MSK, 2157c57bd7c3SPing-Ke Shih RTW_PWR_INTF_USB_MSK, 2158c57bd7c3SPing-Ke Shih RTW_PWR_ADDR_MAC, 2159c57bd7c3SPing-Ke Shih RTW_PWR_CMD_WRITE, BIT(0), 1}, 2160c57bd7c3SPing-Ke Shih {0x0023, 2161c57bd7c3SPing-Ke Shih RTW_PWR_CUT_ALL_MSK, 2162c57bd7c3SPing-Ke Shih RTW_PWR_INTF_SDIO_MSK, 2163c57bd7c3SPing-Ke Shih RTW_PWR_ADDR_MAC, 2164c57bd7c3SPing-Ke Shih RTW_PWR_CMD_WRITE, BIT(4), BIT(4)}, 2165c57bd7c3SPing-Ke Shih {0x0086, 2166c57bd7c3SPing-Ke Shih RTW_PWR_CUT_ALL_MSK, 2167c57bd7c3SPing-Ke Shih RTW_PWR_INTF_SDIO_MSK, 2168c57bd7c3SPing-Ke Shih RTW_PWR_ADDR_SDIO, 2169c57bd7c3SPing-Ke Shih RTW_PWR_CMD_WRITE, BIT(0), BIT(0)}, 2170c57bd7c3SPing-Ke Shih {0x0086, 2171c57bd7c3SPing-Ke Shih RTW_PWR_CUT_ALL_MSK, 2172c57bd7c3SPing-Ke Shih RTW_PWR_INTF_SDIO_MSK, 2173c57bd7c3SPing-Ke Shih RTW_PWR_ADDR_SDIO, 2174c57bd7c3SPing-Ke Shih RTW_PWR_CMD_POLLING, BIT(1), 0}, 2175c57bd7c3SPing-Ke Shih {0xFFFF, 2176c57bd7c3SPing-Ke Shih RTW_PWR_CUT_ALL_MSK, 2177c57bd7c3SPing-Ke Shih RTW_PWR_INTF_ALL_MSK, 2178c57bd7c3SPing-Ke Shih 0, 2179c57bd7c3SPing-Ke Shih RTW_PWR_CMD_END, 0, 0}, 2180c57bd7c3SPing-Ke Shih }; 2181c57bd7c3SPing-Ke Shih 2182c57bd7c3SPing-Ke Shih static const struct rtw_pwr_seq_cmd trans_act_to_post_carddis_8723d[] = { 2183c57bd7c3SPing-Ke Shih {0x001D, 2184c57bd7c3SPing-Ke Shih RTW_PWR_CUT_ALL_MSK, 2185c57bd7c3SPing-Ke Shih RTW_PWR_INTF_ALL_MSK, 2186c57bd7c3SPing-Ke Shih RTW_PWR_ADDR_MAC, 2187c57bd7c3SPing-Ke Shih RTW_PWR_CMD_WRITE, BIT(0), 0}, 2188c57bd7c3SPing-Ke Shih {0x001D, 2189c57bd7c3SPing-Ke Shih RTW_PWR_CUT_ALL_MSK, 2190c57bd7c3SPing-Ke Shih RTW_PWR_INTF_ALL_MSK, 2191c57bd7c3SPing-Ke Shih RTW_PWR_ADDR_MAC, 2192c57bd7c3SPing-Ke Shih RTW_PWR_CMD_WRITE, BIT(0), BIT(0)}, 2193c57bd7c3SPing-Ke Shih {0x001C, 2194c57bd7c3SPing-Ke Shih RTW_PWR_CUT_ALL_MSK, 2195c57bd7c3SPing-Ke Shih RTW_PWR_INTF_ALL_MSK, 2196c57bd7c3SPing-Ke Shih RTW_PWR_ADDR_MAC, 2197c57bd7c3SPing-Ke Shih RTW_PWR_CMD_WRITE, 0xFF, 0x0E}, 2198c57bd7c3SPing-Ke Shih {0xFFFF, 2199c57bd7c3SPing-Ke Shih RTW_PWR_CUT_ALL_MSK, 2200c57bd7c3SPing-Ke Shih RTW_PWR_INTF_ALL_MSK, 2201c57bd7c3SPing-Ke Shih 0, 2202c57bd7c3SPing-Ke Shih RTW_PWR_CMD_END, 0, 0}, 2203c57bd7c3SPing-Ke Shih }; 2204c57bd7c3SPing-Ke Shih 2205c57bd7c3SPing-Ke Shih static const struct rtw_pwr_seq_cmd *card_disable_flow_8723d[] = { 2206c57bd7c3SPing-Ke Shih trans_act_to_lps_8723d, 2207c57bd7c3SPing-Ke Shih trans_act_to_pre_carddis_8723d, 2208c57bd7c3SPing-Ke Shih trans_act_to_cardemu_8723d, 2209c57bd7c3SPing-Ke Shih trans_cardemu_to_carddis_8723d, 2210c57bd7c3SPing-Ke Shih trans_act_to_post_carddis_8723d, 2211c57bd7c3SPing-Ke Shih NULL 2212c57bd7c3SPing-Ke Shih }; 2213c57bd7c3SPing-Ke Shih 2214d91277deSPing-Ke Shih static const struct rtw_page_table page_table_8723d[] = { 2215d91277deSPing-Ke Shih {12, 2, 2, 0, 1}, 2216d91277deSPing-Ke Shih {12, 2, 2, 0, 1}, 2217d91277deSPing-Ke Shih {12, 2, 2, 0, 1}, 2218d91277deSPing-Ke Shih {12, 2, 2, 0, 1}, 2219d91277deSPing-Ke Shih {12, 2, 2, 0, 1}, 2220d91277deSPing-Ke Shih }; 2221d91277deSPing-Ke Shih 2222d91277deSPing-Ke Shih static const struct rtw_rqpn rqpn_table_8723d[] = { 2223d91277deSPing-Ke Shih {RTW_DMA_MAPPING_NORMAL, RTW_DMA_MAPPING_NORMAL, 2224d91277deSPing-Ke Shih RTW_DMA_MAPPING_LOW, RTW_DMA_MAPPING_LOW, 2225d91277deSPing-Ke Shih RTW_DMA_MAPPING_EXTRA, RTW_DMA_MAPPING_HIGH}, 2226d91277deSPing-Ke Shih {RTW_DMA_MAPPING_NORMAL, RTW_DMA_MAPPING_NORMAL, 2227d91277deSPing-Ke Shih RTW_DMA_MAPPING_LOW, RTW_DMA_MAPPING_LOW, 2228d91277deSPing-Ke Shih RTW_DMA_MAPPING_EXTRA, RTW_DMA_MAPPING_HIGH}, 2229d91277deSPing-Ke Shih {RTW_DMA_MAPPING_NORMAL, RTW_DMA_MAPPING_NORMAL, 2230d91277deSPing-Ke Shih RTW_DMA_MAPPING_NORMAL, RTW_DMA_MAPPING_HIGH, 2231d91277deSPing-Ke Shih RTW_DMA_MAPPING_HIGH, RTW_DMA_MAPPING_HIGH}, 2232d91277deSPing-Ke Shih {RTW_DMA_MAPPING_NORMAL, RTW_DMA_MAPPING_NORMAL, 2233d91277deSPing-Ke Shih RTW_DMA_MAPPING_LOW, RTW_DMA_MAPPING_LOW, 2234d91277deSPing-Ke Shih RTW_DMA_MAPPING_HIGH, RTW_DMA_MAPPING_HIGH}, 2235d91277deSPing-Ke Shih {RTW_DMA_MAPPING_NORMAL, RTW_DMA_MAPPING_NORMAL, 2236d91277deSPing-Ke Shih RTW_DMA_MAPPING_LOW, RTW_DMA_MAPPING_LOW, 2237d91277deSPing-Ke Shih RTW_DMA_MAPPING_EXTRA, RTW_DMA_MAPPING_HIGH}, 2238d91277deSPing-Ke Shih }; 2239d91277deSPing-Ke Shih 22407d754f97SPing-Ke Shih static const struct rtw_prioq_addrs prioq_addrs_8723d = { 22417d754f97SPing-Ke Shih .prio[RTW_DMA_MAPPING_EXTRA] = { 22427d754f97SPing-Ke Shih .rsvd = REG_RQPN_NPQ + 2, .avail = REG_RQPN_NPQ + 3, 22437d754f97SPing-Ke Shih }, 22447d754f97SPing-Ke Shih .prio[RTW_DMA_MAPPING_LOW] = { 22457d754f97SPing-Ke Shih .rsvd = REG_RQPN + 1, .avail = REG_FIFOPAGE_CTRL_2 + 1, 22467d754f97SPing-Ke Shih }, 22477d754f97SPing-Ke Shih .prio[RTW_DMA_MAPPING_NORMAL] = { 22487d754f97SPing-Ke Shih .rsvd = REG_RQPN_NPQ, .avail = REG_RQPN_NPQ + 1, 22497d754f97SPing-Ke Shih }, 22507d754f97SPing-Ke Shih .prio[RTW_DMA_MAPPING_HIGH] = { 22517d754f97SPing-Ke Shih .rsvd = REG_RQPN, .avail = REG_FIFOPAGE_CTRL_2, 22527d754f97SPing-Ke Shih }, 22537d754f97SPing-Ke Shih .wsize = false, 22547d754f97SPing-Ke Shih }; 22557d754f97SPing-Ke Shih 225617579404SPing-Ke Shih static const struct rtw_intf_phy_para pcie_gen1_param_8723d[] = { 225717579404SPing-Ke Shih {0x0008, 0x4a22, 225817579404SPing-Ke Shih RTW_IP_SEL_PHY, 225917579404SPing-Ke Shih RTW_INTF_PHY_CUT_ALL, 226017579404SPing-Ke Shih RTW_INTF_PHY_PLATFORM_ALL}, 226117579404SPing-Ke Shih {0x0009, 0x1000, 226217579404SPing-Ke Shih RTW_IP_SEL_PHY, 226317579404SPing-Ke Shih ~(RTW_INTF_PHY_CUT_A | RTW_INTF_PHY_CUT_B), 226417579404SPing-Ke Shih RTW_INTF_PHY_PLATFORM_ALL}, 226517579404SPing-Ke Shih {0xFFFF, 0x0000, 226617579404SPing-Ke Shih RTW_IP_SEL_PHY, 226717579404SPing-Ke Shih RTW_INTF_PHY_CUT_ALL, 226817579404SPing-Ke Shih RTW_INTF_PHY_PLATFORM_ALL}, 226917579404SPing-Ke Shih }; 227017579404SPing-Ke Shih 227117579404SPing-Ke Shih static const struct rtw_intf_phy_para_table phy_para_table_8723d = { 227217579404SPing-Ke Shih .gen1_para = pcie_gen1_param_8723d, 227317579404SPing-Ke Shih .n_gen1_para = ARRAY_SIZE(pcie_gen1_param_8723d), 227417579404SPing-Ke Shih }; 227517579404SPing-Ke Shih 2276db39a9ddSPing-Ke Shih static const struct rtw_hw_reg rtw8723d_dig[] = { 2277db39a9ddSPing-Ke Shih [0] = { .addr = 0xc50, .mask = 0x7f }, 2278db39a9ddSPing-Ke Shih [1] = { .addr = 0xc50, .mask = 0x7f }, 2279db39a9ddSPing-Ke Shih }; 2280db39a9ddSPing-Ke Shih 2281fc637a86SPing-Ke Shih static const struct rtw_hw_reg rtw8723d_dig_cck[] = { 2282fc637a86SPing-Ke Shih [0] = { .addr = 0xa0c, .mask = 0x3f00 }, 2283fc637a86SPing-Ke Shih }; 2284fc637a86SPing-Ke Shih 2285e0c27cdbSPing-Ke Shih static const struct rtw_rf_sipi_addr rtw8723d_rf_sipi_addr[] = { 2286e0c27cdbSPing-Ke Shih [RF_PATH_A] = { .hssi_1 = 0x820, .lssi_read = 0x8a0, 2287e0c27cdbSPing-Ke Shih .hssi_2 = 0x824, .lssi_read_pi = 0x8b8}, 2288e0c27cdbSPing-Ke Shih [RF_PATH_B] = { .hssi_1 = 0x828, .lssi_read = 0x8a4, 2289e0c27cdbSPing-Ke Shih .hssi_2 = 0x82c, .lssi_read_pi = 0x8bc}, 2290e0c27cdbSPing-Ke Shih }; 2291e0c27cdbSPing-Ke Shih 22927e149368SPing-Ke Shih static const struct rtw_ltecoex_addr rtw8723d_ltecoex_addr = { 22937e149368SPing-Ke Shih .ctrl = REG_LTECOEX_CTRL, 22947e149368SPing-Ke Shih .wdata = REG_LTECOEX_WRITE_DATA, 22957e149368SPing-Ke Shih .rdata = REG_LTECOEX_READ_DATA, 22967e149368SPing-Ke Shih }; 22977e149368SPing-Ke Shih 22989874f685SPing-Ke Shih static const struct rtw_rfe_def rtw8723d_rfe_defs[] = { 22999874f685SPing-Ke Shih [0] = { .phy_pg_tbl = &rtw8723d_bb_pg_tbl, 23009874f685SPing-Ke Shih .txpwr_lmt_tbl = &rtw8723d_txpwr_lmt_tbl,}, 23019874f685SPing-Ke Shih }; 23029874f685SPing-Ke Shih 2303608d2a08SPing-Ke Shih static const u8 rtw8723d_pwrtrk_2gb_n[] = { 2304608d2a08SPing-Ke Shih 0, 0, 1, 1, 1, 2, 2, 3, 4, 4, 4, 4, 5, 5, 5, 2305608d2a08SPing-Ke Shih 6, 6, 7, 7, 8, 8, 8, 9, 9, 9, 10, 10, 10, 10, 10 2306608d2a08SPing-Ke Shih }; 2307608d2a08SPing-Ke Shih 2308608d2a08SPing-Ke Shih static const u8 rtw8723d_pwrtrk_2gb_p[] = { 2309608d2a08SPing-Ke Shih 0, 0, 1, 1, 2, 2, 2, 3, 3, 4, 4, 5, 5, 6, 7, 2310608d2a08SPing-Ke Shih 7, 8, 8, 8, 9, 9, 10, 10, 10, 10, 10, 10, 10, 10, 10 2311608d2a08SPing-Ke Shih }; 2312608d2a08SPing-Ke Shih 2313608d2a08SPing-Ke Shih static const u8 rtw8723d_pwrtrk_2ga_n[] = { 2314608d2a08SPing-Ke Shih 0, 0, 1, 1, 1, 2, 2, 3, 4, 4, 4, 4, 5, 5, 5, 2315608d2a08SPing-Ke Shih 6, 6, 7, 7, 8, 8, 8, 9, 9, 9, 10, 10, 10, 10, 10 2316608d2a08SPing-Ke Shih }; 2317608d2a08SPing-Ke Shih 2318608d2a08SPing-Ke Shih static const u8 rtw8723d_pwrtrk_2ga_p[] = { 2319608d2a08SPing-Ke Shih 0, 0, 1, 1, 2, 2, 2, 3, 3, 4, 4, 5, 5, 6, 7, 2320608d2a08SPing-Ke Shih 7, 8, 8, 8, 9, 9, 10, 10, 10, 10, 10, 10, 10, 10, 10 2321608d2a08SPing-Ke Shih }; 2322608d2a08SPing-Ke Shih 2323608d2a08SPing-Ke Shih static const u8 rtw8723d_pwrtrk_2g_cck_b_n[] = { 2324608d2a08SPing-Ke Shih 0, 1, 1, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 2325608d2a08SPing-Ke Shih 6, 7, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 11, 11, 11 2326608d2a08SPing-Ke Shih }; 2327608d2a08SPing-Ke Shih 2328608d2a08SPing-Ke Shih static const u8 rtw8723d_pwrtrk_2g_cck_b_p[] = { 2329608d2a08SPing-Ke Shih 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 2330608d2a08SPing-Ke Shih 7, 8, 9, 9, 10, 10, 11, 11, 11, 11, 11, 11, 11, 11, 11 2331608d2a08SPing-Ke Shih }; 2332608d2a08SPing-Ke Shih 2333608d2a08SPing-Ke Shih static const u8 rtw8723d_pwrtrk_2g_cck_a_n[] = { 2334608d2a08SPing-Ke Shih 0, 1, 1, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 2335608d2a08SPing-Ke Shih 6, 7, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 11, 11, 11 2336608d2a08SPing-Ke Shih }; 2337608d2a08SPing-Ke Shih 2338608d2a08SPing-Ke Shih static const u8 rtw8723d_pwrtrk_2g_cck_a_p[] = { 2339608d2a08SPing-Ke Shih 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 2340608d2a08SPing-Ke Shih 7, 8, 9, 9, 10, 10, 11, 11, 11, 11, 11, 11, 11, 11, 11 2341608d2a08SPing-Ke Shih }; 2342608d2a08SPing-Ke Shih 2343608d2a08SPing-Ke Shih static const s8 rtw8723d_pwrtrk_xtal_n[] = { 2344608d2a08SPing-Ke Shih 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2345608d2a08SPing-Ke Shih 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 2346608d2a08SPing-Ke Shih }; 2347608d2a08SPing-Ke Shih 2348608d2a08SPing-Ke Shih static const s8 rtw8723d_pwrtrk_xtal_p[] = { 2349608d2a08SPing-Ke Shih 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2350608d2a08SPing-Ke Shih 0, -10, -12, -14, -16, -16, -16, -16, -16, -16, -16, -16, -16, -16, -16 2351608d2a08SPing-Ke Shih }; 2352608d2a08SPing-Ke Shih 2353608d2a08SPing-Ke Shih static const struct rtw_pwr_track_tbl rtw8723d_rtw_pwr_track_tbl = { 2354608d2a08SPing-Ke Shih .pwrtrk_2gb_n = rtw8723d_pwrtrk_2gb_n, 2355608d2a08SPing-Ke Shih .pwrtrk_2gb_p = rtw8723d_pwrtrk_2gb_p, 2356608d2a08SPing-Ke Shih .pwrtrk_2ga_n = rtw8723d_pwrtrk_2ga_n, 2357608d2a08SPing-Ke Shih .pwrtrk_2ga_p = rtw8723d_pwrtrk_2ga_p, 2358608d2a08SPing-Ke Shih .pwrtrk_2g_cckb_n = rtw8723d_pwrtrk_2g_cck_b_n, 2359608d2a08SPing-Ke Shih .pwrtrk_2g_cckb_p = rtw8723d_pwrtrk_2g_cck_b_p, 2360608d2a08SPing-Ke Shih .pwrtrk_2g_ccka_n = rtw8723d_pwrtrk_2g_cck_a_n, 2361608d2a08SPing-Ke Shih .pwrtrk_2g_ccka_p = rtw8723d_pwrtrk_2g_cck_a_p, 2362608d2a08SPing-Ke Shih .pwrtrk_xtal_p = rtw8723d_pwrtrk_xtal_p, 2363608d2a08SPing-Ke Shih .pwrtrk_xtal_n = rtw8723d_pwrtrk_xtal_n, 2364608d2a08SPing-Ke Shih }; 2365608d2a08SPing-Ke Shih 2366811853daSPing-Ke Shih struct rtw_chip_info rtw8723d_hw_spec = { 2367811853daSPing-Ke Shih .ops = &rtw8723d_ops, 2368811853daSPing-Ke Shih .id = RTW_CHIP_TYPE_8723D, 2369811853daSPing-Ke Shih .fw_name = "rtw88/rtw8723d_fw.bin", 237015d2fcc6SPing-Ke Shih .wlan_cpu = RTW_WCPU_11N, 2371811853daSPing-Ke Shih .tx_pkt_desc_sz = 40, 2372811853daSPing-Ke Shih .tx_buf_desc_sz = 16, 2373811853daSPing-Ke Shih .rx_pkt_desc_sz = 24, 2374811853daSPing-Ke Shih .rx_buf_desc_sz = 8, 2375811853daSPing-Ke Shih .phy_efuse_size = 512, 2376811853daSPing-Ke Shih .log_efuse_size = 512, 2377811853daSPing-Ke Shih .ptct_efuse_size = 96 + 1, 2378d91277deSPing-Ke Shih .txff_size = 32768, 2379d91277deSPing-Ke Shih .rxff_size = 16384, 2380811853daSPing-Ke Shih .txgi_factor = 1, 2381811853daSPing-Ke Shih .is_pwr_by_rate_dec = true, 2382811853daSPing-Ke Shih .max_power_index = 0x3f, 2383811853daSPing-Ke Shih .csi_buf_pg_num = 0, 2384811853daSPing-Ke Shih .band = RTW_BAND_2G, 2385d91277deSPing-Ke Shih .page_size = 128, 2386db39a9ddSPing-Ke Shih .dig_min = 0x20, 2387811853daSPing-Ke Shih .ht_supported = true, 2388811853daSPing-Ke Shih .vht_supported = false, 2389811853daSPing-Ke Shih .lps_deep_mode_supported = 0, 2390811853daSPing-Ke Shih .sys_func_en = 0xFD, 2391c57bd7c3SPing-Ke Shih .pwr_on_seq = card_enable_flow_8723d, 2392c57bd7c3SPing-Ke Shih .pwr_off_seq = card_disable_flow_8723d, 2393d91277deSPing-Ke Shih .page_table = page_table_8723d, 2394d91277deSPing-Ke Shih .rqpn_table = rqpn_table_8723d, 23957d754f97SPing-Ke Shih .prioq_addrs = &prioq_addrs_8723d, 239617579404SPing-Ke Shih .intf_table = &phy_para_table_8723d, 2397db39a9ddSPing-Ke Shih .dig = rtw8723d_dig, 2398fc637a86SPing-Ke Shih .dig_cck = rtw8723d_dig_cck, 2399e0c27cdbSPing-Ke Shih .rf_sipi_addr = {0x840, 0x844}, 2400e0c27cdbSPing-Ke Shih .rf_sipi_read_addr = rtw8723d_rf_sipi_addr, 2401e0c27cdbSPing-Ke Shih .fix_rf_phy_num = 2, 24027e149368SPing-Ke Shih .ltecoex_addr = &rtw8723d_ltecoex_addr, 24039874f685SPing-Ke Shih .mac_tbl = &rtw8723d_mac_tbl, 24049874f685SPing-Ke Shih .agc_tbl = &rtw8723d_agc_tbl, 24059874f685SPing-Ke Shih .bb_tbl = &rtw8723d_bb_tbl, 24069874f685SPing-Ke Shih .rf_tbl = {&rtw8723d_rf_a_tbl}, 24079874f685SPing-Ke Shih .rfe_defs = rtw8723d_rfe_defs, 24089874f685SPing-Ke Shih .rfe_defs_size = ARRAY_SIZE(rtw8723d_rfe_defs), 24093ac14439SPing-Ke Shih .rx_ldpc = false, 2410608d2a08SPing-Ke Shih .pwr_track_tbl = &rtw8723d_rtw_pwr_track_tbl, 2411608d2a08SPing-Ke Shih .iqk_threshold = 8, 2412811853daSPing-Ke Shih }; 2413811853daSPing-Ke Shih EXPORT_SYMBOL(rtw8723d_hw_spec); 2414811853daSPing-Ke Shih 2415811853daSPing-Ke Shih MODULE_FIRMWARE("rtw88/rtw8723d_fw.bin"); 2416