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