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 
5f56f0863SZong-Zhe Yang #include <linux/module.h>
6811853daSPing-Ke Shih #include "main.h"
7811853daSPing-Ke Shih #include "coex.h"
8811853daSPing-Ke Shih #include "fw.h"
9811853daSPing-Ke Shih #include "tx.h"
10811853daSPing-Ke Shih #include "rx.h"
11811853daSPing-Ke Shih #include "phy.h"
12811853daSPing-Ke Shih #include "rtw8723d.h"
13811853daSPing-Ke Shih #include "rtw8723d_table.h"
14811853daSPing-Ke Shih #include "mac.h"
15811853daSPing-Ke Shih #include "reg.h"
16811853daSPing-Ke Shih #include "debug.h"
17811853daSPing-Ke Shih 
18ba9f0d1bSPing-Ke Shih static const struct rtw_hw_reg rtw8723d_txagc[] = {
19ba9f0d1bSPing-Ke Shih 	[DESC_RATE1M]	= { .addr = 0xe08, .mask = 0x0000ff00 },
20ba9f0d1bSPing-Ke Shih 	[DESC_RATE2M]	= { .addr = 0x86c, .mask = 0x0000ff00 },
21ba9f0d1bSPing-Ke Shih 	[DESC_RATE5_5M]	= { .addr = 0x86c, .mask = 0x00ff0000 },
22ba9f0d1bSPing-Ke Shih 	[DESC_RATE11M]	= { .addr = 0x86c, .mask = 0xff000000 },
23ba9f0d1bSPing-Ke Shih 	[DESC_RATE6M]	= { .addr = 0xe00, .mask = 0x000000ff },
24ba9f0d1bSPing-Ke Shih 	[DESC_RATE9M]	= { .addr = 0xe00, .mask = 0x0000ff00 },
25ba9f0d1bSPing-Ke Shih 	[DESC_RATE12M]	= { .addr = 0xe00, .mask = 0x00ff0000 },
26ba9f0d1bSPing-Ke Shih 	[DESC_RATE18M]	= { .addr = 0xe00, .mask = 0xff000000 },
27ba9f0d1bSPing-Ke Shih 	[DESC_RATE24M]	= { .addr = 0xe04, .mask = 0x000000ff },
28ba9f0d1bSPing-Ke Shih 	[DESC_RATE36M]	= { .addr = 0xe04, .mask = 0x0000ff00 },
29ba9f0d1bSPing-Ke Shih 	[DESC_RATE48M]	= { .addr = 0xe04, .mask = 0x00ff0000 },
30ba9f0d1bSPing-Ke Shih 	[DESC_RATE54M]	= { .addr = 0xe04, .mask = 0xff000000 },
31ba9f0d1bSPing-Ke Shih 	[DESC_RATEMCS0]	= { .addr = 0xe10, .mask = 0x000000ff },
32ba9f0d1bSPing-Ke Shih 	[DESC_RATEMCS1]	= { .addr = 0xe10, .mask = 0x0000ff00 },
33ba9f0d1bSPing-Ke Shih 	[DESC_RATEMCS2]	= { .addr = 0xe10, .mask = 0x00ff0000 },
34ba9f0d1bSPing-Ke Shih 	[DESC_RATEMCS3]	= { .addr = 0xe10, .mask = 0xff000000 },
35ba9f0d1bSPing-Ke Shih 	[DESC_RATEMCS4]	= { .addr = 0xe14, .mask = 0x000000ff },
36ba9f0d1bSPing-Ke Shih 	[DESC_RATEMCS5]	= { .addr = 0xe14, .mask = 0x0000ff00 },
37ba9f0d1bSPing-Ke Shih 	[DESC_RATEMCS6]	= { .addr = 0xe14, .mask = 0x00ff0000 },
38ba9f0d1bSPing-Ke Shih 	[DESC_RATEMCS7]	= { .addr = 0xe14, .mask = 0xff000000 },
39ba9f0d1bSPing-Ke Shih };
40ba9f0d1bSPing-Ke Shih 
4175e69fb1SPing-Ke Shih #define WLAN_TXQ_RPT_EN		0x1F
4275e69fb1SPing-Ke Shih #define WLAN_SLOT_TIME		0x09
4375e69fb1SPing-Ke Shih #define WLAN_RL_VAL		0x3030
4475e69fb1SPing-Ke Shih #define WLAN_BAR_VAL		0x0201ffff
4575e69fb1SPing-Ke Shih #define BIT_MASK_TBTT_HOLD	0x00000fff
4675e69fb1SPing-Ke Shih #define BIT_SHIFT_TBTT_HOLD	8
4775e69fb1SPing-Ke Shih #define BIT_MASK_TBTT_SETUP	0x000000ff
4875e69fb1SPing-Ke Shih #define BIT_SHIFT_TBTT_SETUP	0
4975e69fb1SPing-Ke Shih #define BIT_MASK_TBTT_MASK	((BIT_MASK_TBTT_HOLD << BIT_SHIFT_TBTT_HOLD) | \
5075e69fb1SPing-Ke Shih 				 (BIT_MASK_TBTT_SETUP << BIT_SHIFT_TBTT_SETUP))
5175e69fb1SPing-Ke Shih #define TBTT_TIME(s, h)((((s) & BIT_MASK_TBTT_SETUP) << BIT_SHIFT_TBTT_SETUP) |\
5275e69fb1SPing-Ke Shih 			(((h) & BIT_MASK_TBTT_HOLD) << BIT_SHIFT_TBTT_HOLD))
5375e69fb1SPing-Ke Shih #define WLAN_TBTT_TIME_NORMAL	TBTT_TIME(0x04, 0x80)
5475e69fb1SPing-Ke Shih #define WLAN_TBTT_TIME_STOP_BCN	TBTT_TIME(0x04, 0x64)
5575e69fb1SPing-Ke Shih #define WLAN_PIFS_VAL		0
5675e69fb1SPing-Ke Shih #define WLAN_AGG_BRK_TIME	0x16
5775e69fb1SPing-Ke Shih #define WLAN_NAV_PROT_LEN	0x0040
5875e69fb1SPing-Ke Shih #define WLAN_SPEC_SIFS		0x100a
5975e69fb1SPing-Ke Shih #define WLAN_RX_PKT_LIMIT	0x17
6075e69fb1SPing-Ke Shih #define WLAN_MAX_AGG_NR		0x0A
6175e69fb1SPing-Ke Shih #define WLAN_AMPDU_MAX_TIME	0x1C
6275e69fb1SPing-Ke Shih #define WLAN_ANT_SEL		0x82
6375e69fb1SPing-Ke Shih #define WLAN_LTR_IDLE_LAT	0x883C883C
6475e69fb1SPing-Ke Shih #define WLAN_LTR_ACT_LAT	0x880B880B
6575e69fb1SPing-Ke Shih #define WLAN_LTR_CTRL1		0xCB004010
6675e69fb1SPing-Ke Shih #define WLAN_LTR_CTRL2		0x01233425
6775e69fb1SPing-Ke Shih 
68f71eb7f6SPing-Ke Shih static void rtw8723d_lck(struct rtw_dev *rtwdev)
69f71eb7f6SPing-Ke Shih {
70f71eb7f6SPing-Ke Shih 	u32 lc_cal;
71f71eb7f6SPing-Ke Shih 	u8 val_ctx, rf_val;
72f71eb7f6SPing-Ke Shih 	int ret;
73f71eb7f6SPing-Ke Shih 
74f71eb7f6SPing-Ke Shih 	val_ctx = rtw_read8(rtwdev, REG_CTX);
75f71eb7f6SPing-Ke Shih 	if ((val_ctx & BIT_MASK_CTX_TYPE) != 0)
76f71eb7f6SPing-Ke Shih 		rtw_write8(rtwdev, REG_CTX, val_ctx & ~BIT_MASK_CTX_TYPE);
77f71eb7f6SPing-Ke Shih 	else
78f71eb7f6SPing-Ke Shih 		rtw_write8(rtwdev, REG_TXPAUSE, 0xFF);
79f71eb7f6SPing-Ke Shih 	lc_cal = rtw_read_rf(rtwdev, RF_PATH_A, RF_CFGCH, RFREG_MASK);
80f71eb7f6SPing-Ke Shih 
81f71eb7f6SPing-Ke Shih 	rtw_write_rf(rtwdev, RF_PATH_A, RF_CFGCH, RFREG_MASK, lc_cal | BIT_LCK);
82f71eb7f6SPing-Ke Shih 
83f71eb7f6SPing-Ke Shih 	ret = read_poll_timeout(rtw_read_rf, rf_val, rf_val != 0x1,
84f71eb7f6SPing-Ke Shih 				10000, 1000000, false,
85f71eb7f6SPing-Ke Shih 				rtwdev, RF_PATH_A, RF_CFGCH, BIT_LCK);
86f71eb7f6SPing-Ke Shih 	if (ret)
87f71eb7f6SPing-Ke Shih 		rtw_warn(rtwdev, "failed to poll LCK status bit\n");
88f71eb7f6SPing-Ke Shih 
89f71eb7f6SPing-Ke Shih 	rtw_write_rf(rtwdev, RF_PATH_A, RF_CFGCH, RFREG_MASK, lc_cal);
90f71eb7f6SPing-Ke Shih 	if ((val_ctx & BIT_MASK_CTX_TYPE) != 0)
91f71eb7f6SPing-Ke Shih 		rtw_write8(rtwdev, REG_CTX, val_ctx);
92f71eb7f6SPing-Ke Shih 	else
93f71eb7f6SPing-Ke Shih 		rtw_write8(rtwdev, REG_TXPAUSE, 0x00);
94f71eb7f6SPing-Ke Shih }
95f71eb7f6SPing-Ke Shih 
96608d2a08SPing-Ke Shih static const u32 rtw8723d_ofdm_swing_table[] = {
97608d2a08SPing-Ke Shih 	0x0b40002d, 0x0c000030, 0x0cc00033, 0x0d800036, 0x0e400039, 0x0f00003c,
98608d2a08SPing-Ke Shih 	0x10000040, 0x11000044, 0x12000048, 0x1300004c, 0x14400051, 0x15800056,
99608d2a08SPing-Ke Shih 	0x16c0005b, 0x18000060, 0x19800066, 0x1b00006c, 0x1c800072, 0x1e400079,
100608d2a08SPing-Ke Shih 	0x20000080, 0x22000088, 0x24000090, 0x26000098, 0x288000a2, 0x2ac000ab,
101608d2a08SPing-Ke Shih 	0x2d4000b5, 0x300000c0, 0x32c000cb, 0x35c000d7, 0x390000e4, 0x3c8000f2,
102608d2a08SPing-Ke Shih 	0x40000100, 0x43c0010f, 0x47c0011f, 0x4c000130, 0x50800142, 0x55400155,
103608d2a08SPing-Ke Shih 	0x5a400169, 0x5fc0017f, 0x65400195, 0x6b8001ae, 0x71c001c7, 0x788001e2,
104608d2a08SPing-Ke Shih 	0x7f8001fe,
105608d2a08SPing-Ke Shih };
106608d2a08SPing-Ke Shih 
107608d2a08SPing-Ke Shih static const u32 rtw8723d_cck_swing_table[] = {
108608d2a08SPing-Ke Shih 	0x0CD, 0x0D9, 0x0E6, 0x0F3, 0x102, 0x111, 0x121, 0x132, 0x144, 0x158,
109608d2a08SPing-Ke Shih 	0x16C, 0x182, 0x198, 0x1B1, 0x1CA, 0x1E5, 0x202, 0x221, 0x241, 0x263,
110608d2a08SPing-Ke Shih 	0x287, 0x2AE, 0x2D6, 0x301, 0x32F, 0x35F, 0x392, 0x3C9, 0x402, 0x43F,
111608d2a08SPing-Ke Shih 	0x47F, 0x4C3, 0x50C, 0x558, 0x5A9, 0x5FF, 0x65A, 0x6BA, 0x720, 0x78C,
112608d2a08SPing-Ke Shih 	0x7FF,
113608d2a08SPing-Ke Shih };
114608d2a08SPing-Ke Shih 
115608d2a08SPing-Ke Shih #define RTW_OFDM_SWING_TABLE_SIZE	ARRAY_SIZE(rtw8723d_ofdm_swing_table)
116608d2a08SPing-Ke Shih #define RTW_CCK_SWING_TABLE_SIZE	ARRAY_SIZE(rtw8723d_cck_swing_table)
117608d2a08SPing-Ke Shih 
118608d2a08SPing-Ke Shih static void rtw8723d_pwrtrack_init(struct rtw_dev *rtwdev)
119608d2a08SPing-Ke Shih {
120608d2a08SPing-Ke Shih 	struct rtw_dm_info *dm_info = &rtwdev->dm_info;
121608d2a08SPing-Ke Shih 	u8 path;
122608d2a08SPing-Ke Shih 
123608d2a08SPing-Ke Shih 	dm_info->default_ofdm_index = RTW_DEF_OFDM_SWING_INDEX;
124608d2a08SPing-Ke Shih 
125608d2a08SPing-Ke Shih 	for (path = RF_PATH_A; path < rtwdev->hal.rf_path_num; path++) {
126608d2a08SPing-Ke Shih 		ewma_thermal_init(&dm_info->avg_thermal[path]);
127608d2a08SPing-Ke Shih 		dm_info->delta_power_index[path] = 0;
128608d2a08SPing-Ke Shih 	}
129608d2a08SPing-Ke Shih 	dm_info->pwr_trk_triggered = false;
130608d2a08SPing-Ke Shih 	dm_info->pwr_trk_init_trigger = true;
131608d2a08SPing-Ke Shih 	dm_info->thermal_meter_k = rtwdev->efuse.thermal_meter_k;
132608d2a08SPing-Ke Shih 	dm_info->txagc_remnant_cck = 0;
133608d2a08SPing-Ke Shih 	dm_info->txagc_remnant_ofdm = 0;
134608d2a08SPing-Ke Shih }
135608d2a08SPing-Ke Shih 
13675e69fb1SPing-Ke Shih static void rtw8723d_phy_set_param(struct rtw_dev *rtwdev)
13775e69fb1SPing-Ke Shih {
13875e69fb1SPing-Ke Shih 	u8 xtal_cap;
13975e69fb1SPing-Ke Shih 	u32 val32;
14075e69fb1SPing-Ke Shih 
14175e69fb1SPing-Ke Shih 	/* power on BB/RF domain */
14275e69fb1SPing-Ke Shih 	rtw_write16_set(rtwdev, REG_SYS_FUNC_EN,
14375e69fb1SPing-Ke Shih 			BIT_FEN_EN_25_1 | BIT_FEN_BB_GLB_RST | BIT_FEN_BB_RSTB);
14475e69fb1SPing-Ke Shih 	rtw_write8_set(rtwdev, REG_RF_CTRL,
14575e69fb1SPing-Ke Shih 		       BIT_RF_EN | BIT_RF_RSTB | BIT_RF_SDM_RSTB);
14675e69fb1SPing-Ke Shih 	rtw_write8(rtwdev, REG_AFE_CTRL1 + 1, 0x80);
14775e69fb1SPing-Ke Shih 
14875e69fb1SPing-Ke Shih 	rtw_phy_load_tables(rtwdev);
14975e69fb1SPing-Ke Shih 
15075e69fb1SPing-Ke Shih 	/* post init after header files config */
15175e69fb1SPing-Ke Shih 	rtw_write32_clr(rtwdev, REG_RCR, BIT_RCR_ADF);
15275e69fb1SPing-Ke Shih 	rtw_write8_set(rtwdev, REG_HIQ_NO_LMT_EN, BIT_HIQ_NO_LMT_EN_ROOT);
15375e69fb1SPing-Ke Shih 	rtw_write16_set(rtwdev, REG_AFE_CTRL_4, BIT_CK320M_AFE_EN | BIT_EN_SYN);
15475e69fb1SPing-Ke Shih 
15575e69fb1SPing-Ke Shih 	xtal_cap = rtwdev->efuse.crystal_cap & 0x3F;
15675e69fb1SPing-Ke Shih 	rtw_write32_mask(rtwdev, REG_AFE_CTRL3, BIT_MASK_XTAL,
15775e69fb1SPing-Ke Shih 			 xtal_cap | (xtal_cap << 6));
15875e69fb1SPing-Ke Shih 	rtw_write32_set(rtwdev, REG_FPGA0_RFMOD, BIT_CCKEN | BIT_OFDMEN);
15975e69fb1SPing-Ke Shih 	if ((rtwdev->efuse.afe >> 4) == 14) {
16075e69fb1SPing-Ke Shih 		rtw_write32_set(rtwdev, REG_AFE_CTRL3, BIT_XTAL_GMP_BIT4);
16175e69fb1SPing-Ke Shih 		rtw_write32_clr(rtwdev, REG_AFE_CTRL1, BITS_PLL);
16275e69fb1SPing-Ke Shih 		rtw_write32_set(rtwdev, REG_LDO_SWR_CTRL, BIT_XTA1);
16375e69fb1SPing-Ke Shih 		rtw_write32_clr(rtwdev, REG_LDO_SWR_CTRL, BIT_XTA0);
16475e69fb1SPing-Ke Shih 	}
16575e69fb1SPing-Ke Shih 
16675e69fb1SPing-Ke Shih 	rtw_write8(rtwdev, REG_SLOT, WLAN_SLOT_TIME);
16775e69fb1SPing-Ke Shih 	rtw_write8(rtwdev, REG_FWHW_TXQ_CTRL + 1, WLAN_TXQ_RPT_EN);
16875e69fb1SPing-Ke Shih 	rtw_write16(rtwdev, REG_RETRY_LIMIT, WLAN_RL_VAL);
16975e69fb1SPing-Ke Shih 	rtw_write32(rtwdev, REG_BAR_MODE_CTRL, WLAN_BAR_VAL);
17075e69fb1SPing-Ke Shih 	rtw_write8(rtwdev, REG_ATIMWND, 0x2);
17175e69fb1SPing-Ke Shih 	rtw_write8(rtwdev, REG_BCN_CTRL,
17275e69fb1SPing-Ke Shih 		   BIT_DIS_TSF_UDT | BIT_EN_BCN_FUNCTION | BIT_EN_TXBCN_RPT);
17375e69fb1SPing-Ke Shih 	val32 = rtw_read32(rtwdev, REG_TBTT_PROHIBIT);
17475e69fb1SPing-Ke Shih 	val32 &= ~BIT_MASK_TBTT_MASK;
17575e69fb1SPing-Ke Shih 	val32 |= WLAN_TBTT_TIME_STOP_BCN;
17675e69fb1SPing-Ke Shih 	rtw_write8(rtwdev, REG_TBTT_PROHIBIT, val32);
17775e69fb1SPing-Ke Shih 	rtw_write8(rtwdev, REG_PIFS, WLAN_PIFS_VAL);
17875e69fb1SPing-Ke Shih 	rtw_write8(rtwdev, REG_AGGR_BREAK_TIME, WLAN_AGG_BRK_TIME);
17975e69fb1SPing-Ke Shih 	rtw_write16(rtwdev, REG_NAV_PROT_LEN, WLAN_NAV_PROT_LEN);
18075e69fb1SPing-Ke Shih 	rtw_write16(rtwdev, REG_MAC_SPEC_SIFS, WLAN_SPEC_SIFS);
18175e69fb1SPing-Ke Shih 	rtw_write16(rtwdev, REG_SIFS, WLAN_SPEC_SIFS);
18275e69fb1SPing-Ke Shih 	rtw_write16(rtwdev, REG_SIFS + 2, WLAN_SPEC_SIFS);
18375e69fb1SPing-Ke Shih 	rtw_write8(rtwdev, REG_SINGLE_AMPDU_CTRL, BIT_EN_SINGLE_APMDU);
18475e69fb1SPing-Ke Shih 	rtw_write8(rtwdev, REG_RX_PKT_LIMIT, WLAN_RX_PKT_LIMIT);
18575e69fb1SPing-Ke Shih 	rtw_write8(rtwdev, REG_MAX_AGGR_NUM, WLAN_MAX_AGG_NR);
18675e69fb1SPing-Ke Shih 	rtw_write8(rtwdev, REG_AMPDU_MAX_TIME, WLAN_AMPDU_MAX_TIME);
18775e69fb1SPing-Ke Shih 	rtw_write8(rtwdev, REG_LEDCFG2, WLAN_ANT_SEL);
18875e69fb1SPing-Ke Shih 
18975e69fb1SPing-Ke Shih 	rtw_write32(rtwdev, REG_LTR_IDLE_LATENCY, WLAN_LTR_IDLE_LAT);
19075e69fb1SPing-Ke Shih 	rtw_write32(rtwdev, REG_LTR_ACTIVE_LATENCY, WLAN_LTR_ACT_LAT);
19175e69fb1SPing-Ke Shih 	rtw_write32(rtwdev, REG_LTR_CTRL_BASIC, WLAN_LTR_CTRL1);
19275e69fb1SPing-Ke Shih 	rtw_write32(rtwdev, REG_LTR_CTRL_BASIC + 4, WLAN_LTR_CTRL2);
19375e69fb1SPing-Ke Shih 
19475e69fb1SPing-Ke Shih 	rtw_phy_init(rtwdev);
19575e69fb1SPing-Ke Shih 
19675e69fb1SPing-Ke Shih 	rtw_write16_set(rtwdev, REG_TXDMA_OFFSET_CHK, BIT_DROP_DATA_EN);
197f71eb7f6SPing-Ke Shih 
198f71eb7f6SPing-Ke Shih 	rtw8723d_lck(rtwdev);
199f71eb7f6SPing-Ke Shih 
20075e69fb1SPing-Ke Shih 	rtw_write32_mask(rtwdev, REG_OFDM0_XAAGC1, MASKBYTE0, 0x50);
20175e69fb1SPing-Ke Shih 	rtw_write32_mask(rtwdev, REG_OFDM0_XAAGC1, MASKBYTE0, 0x20);
202608d2a08SPing-Ke Shih 
203608d2a08SPing-Ke Shih 	rtw8723d_pwrtrack_init(rtwdev);
20475e69fb1SPing-Ke Shih }
20575e69fb1SPing-Ke Shih 
206ab0a031eSPing-Ke Shih static void rtw8723de_efuse_parsing(struct rtw_efuse *efuse,
207ab0a031eSPing-Ke Shih 				    struct rtw8723d_efuse *map)
208ab0a031eSPing-Ke Shih {
209ab0a031eSPing-Ke Shih 	ether_addr_copy(efuse->addr, map->e.mac_addr);
210ab0a031eSPing-Ke Shih }
211ab0a031eSPing-Ke Shih 
212ab0a031eSPing-Ke Shih static int rtw8723d_read_efuse(struct rtw_dev *rtwdev, u8 *log_map)
213ab0a031eSPing-Ke Shih {
214ab0a031eSPing-Ke Shih 	struct rtw_efuse *efuse = &rtwdev->efuse;
215ab0a031eSPing-Ke Shih 	struct rtw8723d_efuse *map;
216ab0a031eSPing-Ke Shih 	int i;
217ab0a031eSPing-Ke Shih 
218ab0a031eSPing-Ke Shih 	map = (struct rtw8723d_efuse *)log_map;
219ab0a031eSPing-Ke Shih 
220ab0a031eSPing-Ke Shih 	efuse->rfe_option = 0;
221ab0a031eSPing-Ke Shih 	efuse->rf_board_option = map->rf_board_option;
222ab0a031eSPing-Ke Shih 	efuse->crystal_cap = map->xtal_k;
223ab0a031eSPing-Ke Shih 	efuse->pa_type_2g = map->pa_type;
224ab0a031eSPing-Ke Shih 	efuse->lna_type_2g = map->lna_type_2g[0];
225ab0a031eSPing-Ke Shih 	efuse->channel_plan = map->channel_plan;
226ab0a031eSPing-Ke Shih 	efuse->country_code[0] = map->country_code[0];
227ab0a031eSPing-Ke Shih 	efuse->country_code[1] = map->country_code[1];
228ab0a031eSPing-Ke Shih 	efuse->bt_setting = map->rf_bt_setting;
229ab0a031eSPing-Ke Shih 	efuse->regd = map->rf_board_option & 0x7;
230ab0a031eSPing-Ke Shih 	efuse->thermal_meter[0] = map->thermal_meter;
231ab0a031eSPing-Ke Shih 	efuse->thermal_meter_k = map->thermal_meter;
23275e69fb1SPing-Ke Shih 	efuse->afe = map->afe;
233ab0a031eSPing-Ke Shih 
234ab0a031eSPing-Ke Shih 	for (i = 0; i < 4; i++)
235ab0a031eSPing-Ke Shih 		efuse->txpwr_idx_table[i] = map->txpwr_idx_table[i];
236ab0a031eSPing-Ke Shih 
237ab0a031eSPing-Ke Shih 	switch (rtw_hci_type(rtwdev)) {
238ab0a031eSPing-Ke Shih 	case RTW_HCI_TYPE_PCIE:
239ab0a031eSPing-Ke Shih 		rtw8723de_efuse_parsing(efuse, map);
240ab0a031eSPing-Ke Shih 		break;
241ab0a031eSPing-Ke Shih 	default:
242ab0a031eSPing-Ke Shih 		/* unsupported now */
243ab0a031eSPing-Ke Shih 		return -ENOTSUPP;
244ab0a031eSPing-Ke Shih 	}
245ab0a031eSPing-Ke Shih 
246ab0a031eSPing-Ke Shih 	return 0;
247ab0a031eSPing-Ke Shih }
248ab0a031eSPing-Ke Shih 
249158441a2SPing-Ke Shih static void query_phy_status_page0(struct rtw_dev *rtwdev, u8 *phy_status,
250158441a2SPing-Ke Shih 				   struct rtw_rx_pkt_stat *pkt_stat)
251158441a2SPing-Ke Shih {
252158441a2SPing-Ke Shih 	struct rtw_dm_info *dm_info = &rtwdev->dm_info;
253158441a2SPing-Ke Shih 	s8 min_rx_power = -120;
254158441a2SPing-Ke Shih 	u8 pwdb = GET_PHY_STAT_P0_PWDB(phy_status);
255158441a2SPing-Ke Shih 
256158441a2SPing-Ke Shih 	pkt_stat->rx_power[RF_PATH_A] = pwdb - 97;
257158441a2SPing-Ke Shih 	pkt_stat->rssi = rtw_phy_rf_power_2_rssi(pkt_stat->rx_power, 1);
258158441a2SPing-Ke Shih 	pkt_stat->bw = RTW_CHANNEL_WIDTH_20;
259158441a2SPing-Ke Shih 	pkt_stat->signal_power = max(pkt_stat->rx_power[RF_PATH_A],
260158441a2SPing-Ke Shih 				     min_rx_power);
261158441a2SPing-Ke Shih 	dm_info->rssi[RF_PATH_A] = pkt_stat->rssi;
262158441a2SPing-Ke Shih }
263158441a2SPing-Ke Shih 
264158441a2SPing-Ke Shih static void query_phy_status_page1(struct rtw_dev *rtwdev, u8 *phy_status,
265158441a2SPing-Ke Shih 				   struct rtw_rx_pkt_stat *pkt_stat)
266158441a2SPing-Ke Shih {
267158441a2SPing-Ke Shih 	struct rtw_dm_info *dm_info = &rtwdev->dm_info;
268158441a2SPing-Ke Shih 	u8 rxsc, bw;
269158441a2SPing-Ke Shih 	s8 min_rx_power = -120;
270158441a2SPing-Ke Shih 	s8 rx_evm;
271158441a2SPing-Ke Shih 
272158441a2SPing-Ke Shih 	if (pkt_stat->rate > DESC_RATE11M && pkt_stat->rate < DESC_RATEMCS0)
273158441a2SPing-Ke Shih 		rxsc = GET_PHY_STAT_P1_L_RXSC(phy_status);
274158441a2SPing-Ke Shih 	else
275158441a2SPing-Ke Shih 		rxsc = GET_PHY_STAT_P1_HT_RXSC(phy_status);
276158441a2SPing-Ke Shih 
277158441a2SPing-Ke Shih 	if (GET_PHY_STAT_P1_RF_MODE(phy_status) == 0)
278158441a2SPing-Ke Shih 		bw = RTW_CHANNEL_WIDTH_20;
279158441a2SPing-Ke Shih 	else if ((rxsc == 1) || (rxsc == 2))
280158441a2SPing-Ke Shih 		bw = RTW_CHANNEL_WIDTH_20;
281158441a2SPing-Ke Shih 	else
282158441a2SPing-Ke Shih 		bw = RTW_CHANNEL_WIDTH_40;
283158441a2SPing-Ke Shih 
284158441a2SPing-Ke Shih 	pkt_stat->rx_power[RF_PATH_A] = GET_PHY_STAT_P1_PWDB_A(phy_status) - 110;
285158441a2SPing-Ke Shih 	pkt_stat->rssi = rtw_phy_rf_power_2_rssi(pkt_stat->rx_power, 1);
286158441a2SPing-Ke Shih 	pkt_stat->bw = bw;
287158441a2SPing-Ke Shih 	pkt_stat->signal_power = max(pkt_stat->rx_power[RF_PATH_A],
288158441a2SPing-Ke Shih 				     min_rx_power);
289158441a2SPing-Ke Shih 	pkt_stat->rx_evm[RF_PATH_A] = GET_PHY_STAT_P1_RXEVM_A(phy_status);
290158441a2SPing-Ke Shih 	pkt_stat->rx_snr[RF_PATH_A] = GET_PHY_STAT_P1_RXSNR_A(phy_status);
291158441a2SPing-Ke Shih 	pkt_stat->cfo_tail[RF_PATH_A] = GET_PHY_STAT_P1_CFO_TAIL_A(phy_status);
292158441a2SPing-Ke Shih 
293158441a2SPing-Ke Shih 	dm_info->curr_rx_rate = pkt_stat->rate;
294158441a2SPing-Ke Shih 	dm_info->rssi[RF_PATH_A] = pkt_stat->rssi;
295158441a2SPing-Ke Shih 	dm_info->rx_snr[RF_PATH_A] = pkt_stat->rx_snr[RF_PATH_A] >> 1;
296158441a2SPing-Ke Shih 	dm_info->cfo_tail[RF_PATH_A] = (pkt_stat->cfo_tail[RF_PATH_A] * 5) >> 1;
297158441a2SPing-Ke Shih 
298158441a2SPing-Ke Shih 	rx_evm = clamp_t(s8, -pkt_stat->rx_evm[RF_PATH_A] >> 1, 0, 64);
299158441a2SPing-Ke Shih 	rx_evm &= 0x3F;	/* 64->0: second path of 1SS rate is 64 */
300158441a2SPing-Ke Shih 	dm_info->rx_evm_dbm[RF_PATH_A] = rx_evm;
301158441a2SPing-Ke Shih }
302158441a2SPing-Ke Shih 
303158441a2SPing-Ke Shih static void query_phy_status(struct rtw_dev *rtwdev, u8 *phy_status,
304158441a2SPing-Ke Shih 			     struct rtw_rx_pkt_stat *pkt_stat)
305158441a2SPing-Ke Shih {
306158441a2SPing-Ke Shih 	u8 page;
307158441a2SPing-Ke Shih 
308158441a2SPing-Ke Shih 	page = *phy_status & 0xf;
309158441a2SPing-Ke Shih 
310158441a2SPing-Ke Shih 	switch (page) {
311158441a2SPing-Ke Shih 	case 0:
312158441a2SPing-Ke Shih 		query_phy_status_page0(rtwdev, phy_status, pkt_stat);
313158441a2SPing-Ke Shih 		break;
314158441a2SPing-Ke Shih 	case 1:
315158441a2SPing-Ke Shih 		query_phy_status_page1(rtwdev, phy_status, pkt_stat);
316158441a2SPing-Ke Shih 		break;
317158441a2SPing-Ke Shih 	default:
318158441a2SPing-Ke Shih 		rtw_warn(rtwdev, "unused phy status page (%d)\n", page);
319158441a2SPing-Ke Shih 		return;
320158441a2SPing-Ke Shih 	}
321158441a2SPing-Ke Shih }
322158441a2SPing-Ke Shih 
323158441a2SPing-Ke Shih static void rtw8723d_query_rx_desc(struct rtw_dev *rtwdev, u8 *rx_desc,
324158441a2SPing-Ke Shih 				   struct rtw_rx_pkt_stat *pkt_stat,
325158441a2SPing-Ke Shih 				   struct ieee80211_rx_status *rx_status)
326158441a2SPing-Ke Shih {
327158441a2SPing-Ke Shih 	struct ieee80211_hdr *hdr;
328158441a2SPing-Ke Shih 	u32 desc_sz = rtwdev->chip->rx_pkt_desc_sz;
329158441a2SPing-Ke Shih 	u8 *phy_status = NULL;
330158441a2SPing-Ke Shih 
331158441a2SPing-Ke Shih 	memset(pkt_stat, 0, sizeof(*pkt_stat));
332158441a2SPing-Ke Shih 
333158441a2SPing-Ke Shih 	pkt_stat->phy_status = GET_RX_DESC_PHYST(rx_desc);
334158441a2SPing-Ke Shih 	pkt_stat->icv_err = GET_RX_DESC_ICV_ERR(rx_desc);
335158441a2SPing-Ke Shih 	pkt_stat->crc_err = GET_RX_DESC_CRC32(rx_desc);
336158441a2SPing-Ke Shih 	pkt_stat->decrypted = !GET_RX_DESC_SWDEC(rx_desc) &&
337158441a2SPing-Ke Shih 			      GET_RX_DESC_ENC_TYPE(rx_desc) != RX_DESC_ENC_NONE;
338158441a2SPing-Ke Shih 	pkt_stat->is_c2h = GET_RX_DESC_C2H(rx_desc);
339158441a2SPing-Ke Shih 	pkt_stat->pkt_len = GET_RX_DESC_PKT_LEN(rx_desc);
340158441a2SPing-Ke Shih 	pkt_stat->drv_info_sz = GET_RX_DESC_DRV_INFO_SIZE(rx_desc);
341158441a2SPing-Ke Shih 	pkt_stat->shift = GET_RX_DESC_SHIFT(rx_desc);
342158441a2SPing-Ke Shih 	pkt_stat->rate = GET_RX_DESC_RX_RATE(rx_desc);
343158441a2SPing-Ke Shih 	pkt_stat->cam_id = GET_RX_DESC_MACID(rx_desc);
344158441a2SPing-Ke Shih 	pkt_stat->ppdu_cnt = 0;
345158441a2SPing-Ke Shih 	pkt_stat->tsf_low = GET_RX_DESC_TSFL(rx_desc);
346158441a2SPing-Ke Shih 
347158441a2SPing-Ke Shih 	/* drv_info_sz is in unit of 8-bytes */
348158441a2SPing-Ke Shih 	pkt_stat->drv_info_sz *= 8;
349158441a2SPing-Ke Shih 
350158441a2SPing-Ke Shih 	/* c2h cmd pkt's rx/phy status is not interested */
351158441a2SPing-Ke Shih 	if (pkt_stat->is_c2h)
352158441a2SPing-Ke Shih 		return;
353158441a2SPing-Ke Shih 
354158441a2SPing-Ke Shih 	hdr = (struct ieee80211_hdr *)(rx_desc + desc_sz + pkt_stat->shift +
355158441a2SPing-Ke Shih 				       pkt_stat->drv_info_sz);
356158441a2SPing-Ke Shih 	if (pkt_stat->phy_status) {
357158441a2SPing-Ke Shih 		phy_status = rx_desc + desc_sz + pkt_stat->shift;
358158441a2SPing-Ke Shih 		query_phy_status(rtwdev, phy_status, pkt_stat);
359158441a2SPing-Ke Shih 	}
360158441a2SPing-Ke Shih 
361158441a2SPing-Ke Shih 	rtw_rx_fill_rx_status(rtwdev, pkt_stat, hdr, rx_status, phy_status);
362158441a2SPing-Ke Shih }
363158441a2SPing-Ke Shih 
3645f028a9cSPing-Ke Shih static bool rtw8723d_check_spur_ov_thres(struct rtw_dev *rtwdev,
3655f028a9cSPing-Ke Shih 					 u8 channel, u32 thres)
3665f028a9cSPing-Ke Shih {
3675f028a9cSPing-Ke Shih 	u32 freq;
3685f028a9cSPing-Ke Shih 	bool ret = false;
3695f028a9cSPing-Ke Shih 
3705f028a9cSPing-Ke Shih 	if (channel == 13)
3715f028a9cSPing-Ke Shih 		freq = FREQ_CH13;
3725f028a9cSPing-Ke Shih 	else if (channel == 14)
3735f028a9cSPing-Ke Shih 		freq = FREQ_CH14;
3745f028a9cSPing-Ke Shih 	else
3755f028a9cSPing-Ke Shih 		return false;
3765f028a9cSPing-Ke Shih 
3775f028a9cSPing-Ke Shih 	rtw_write32(rtwdev, REG_ANALOG_P4, DIS_3WIRE);
3785f028a9cSPing-Ke Shih 	rtw_write32(rtwdev, REG_PSDFN, freq);
3795f028a9cSPing-Ke Shih 	rtw_write32(rtwdev, REG_PSDFN, START_PSD | freq);
3805f028a9cSPing-Ke Shih 
3815f028a9cSPing-Ke Shih 	msleep(30);
3825f028a9cSPing-Ke Shih 	if (rtw_read32(rtwdev, REG_PSDRPT) >= thres)
3835f028a9cSPing-Ke Shih 		ret = true;
3845f028a9cSPing-Ke Shih 
3855f028a9cSPing-Ke Shih 	rtw_write32(rtwdev, REG_PSDFN, freq);
3865f028a9cSPing-Ke Shih 	rtw_write32(rtwdev, REG_ANALOG_P4, EN_3WIRE);
3875f028a9cSPing-Ke Shih 
3885f028a9cSPing-Ke Shih 	return ret;
3895f028a9cSPing-Ke Shih }
3905f028a9cSPing-Ke Shih 
3915f028a9cSPing-Ke Shih static void rtw8723d_cfg_notch(struct rtw_dev *rtwdev, u8 channel, bool notch)
3925f028a9cSPing-Ke Shih {
3935f028a9cSPing-Ke Shih 	if (!notch) {
3945f028a9cSPing-Ke Shih 		rtw_write32_mask(rtwdev, REG_OFDM0_RXDSP, BIT_MASK_RXDSP, 0x1f);
3955f028a9cSPing-Ke Shih 		rtw_write32_mask(rtwdev, REG_OFDM0_RXDSP, BIT_EN_RXDSP, 0x0);
3965f028a9cSPing-Ke Shih 		rtw_write32(rtwdev, REG_OFDM1_CSI1, 0x00000000);
3975f028a9cSPing-Ke Shih 		rtw_write32(rtwdev, REG_OFDM1_CSI2, 0x00000000);
3985f028a9cSPing-Ke Shih 		rtw_write32(rtwdev, REG_OFDM1_CSI3, 0x00000000);
3995f028a9cSPing-Ke Shih 		rtw_write32(rtwdev, REG_OFDM1_CSI4, 0x00000000);
4005f028a9cSPing-Ke Shih 		rtw_write32_mask(rtwdev, REG_OFDM1_CFOTRK, BIT_EN_CFOTRK, 0x0);
4015f028a9cSPing-Ke Shih 		return;
4025f028a9cSPing-Ke Shih 	}
4035f028a9cSPing-Ke Shih 
4045f028a9cSPing-Ke Shih 	switch (channel) {
4055f028a9cSPing-Ke Shih 	case 13:
4065f028a9cSPing-Ke Shih 		rtw_write32_mask(rtwdev, REG_OFDM0_RXDSP, BIT_MASK_RXDSP, 0xb);
4075f028a9cSPing-Ke Shih 		rtw_write32_mask(rtwdev, REG_OFDM0_RXDSP, BIT_EN_RXDSP, 0x1);
4085f028a9cSPing-Ke Shih 		rtw_write32(rtwdev, REG_OFDM1_CSI1, 0x04000000);
4095f028a9cSPing-Ke Shih 		rtw_write32(rtwdev, REG_OFDM1_CSI2, 0x00000000);
4105f028a9cSPing-Ke Shih 		rtw_write32(rtwdev, REG_OFDM1_CSI3, 0x00000000);
4115f028a9cSPing-Ke Shih 		rtw_write32(rtwdev, REG_OFDM1_CSI4, 0x00000000);
4125f028a9cSPing-Ke Shih 		rtw_write32_mask(rtwdev, REG_OFDM1_CFOTRK, BIT_EN_CFOTRK, 0x1);
4135f028a9cSPing-Ke Shih 		break;
4145f028a9cSPing-Ke Shih 	case 14:
4155f028a9cSPing-Ke Shih 		rtw_write32_mask(rtwdev, REG_OFDM0_RXDSP, BIT_MASK_RXDSP, 0x5);
4165f028a9cSPing-Ke Shih 		rtw_write32_mask(rtwdev, REG_OFDM0_RXDSP, BIT_EN_RXDSP, 0x1);
4175f028a9cSPing-Ke Shih 		rtw_write32(rtwdev, REG_OFDM1_CSI1, 0x00000000);
4185f028a9cSPing-Ke Shih 		rtw_write32(rtwdev, REG_OFDM1_CSI2, 0x00000000);
4195f028a9cSPing-Ke Shih 		rtw_write32(rtwdev, REG_OFDM1_CSI3, 0x00000000);
4205f028a9cSPing-Ke Shih 		rtw_write32(rtwdev, REG_OFDM1_CSI4, 0x00080000);
4215f028a9cSPing-Ke Shih 		rtw_write32_mask(rtwdev, REG_OFDM1_CFOTRK, BIT_EN_CFOTRK, 0x1);
4225f028a9cSPing-Ke Shih 		break;
4235f028a9cSPing-Ke Shih 	default:
4245f028a9cSPing-Ke Shih 		rtw_write32_mask(rtwdev, REG_OFDM0_RXDSP, BIT_EN_RXDSP, 0x0);
4255f028a9cSPing-Ke Shih 		rtw_write32_mask(rtwdev, REG_OFDM1_CFOTRK, BIT_EN_CFOTRK, 0x0);
4265f028a9cSPing-Ke Shih 		break;
4275f028a9cSPing-Ke Shih 	}
4285f028a9cSPing-Ke Shih }
4295f028a9cSPing-Ke Shih 
4305f028a9cSPing-Ke Shih static void rtw8723d_spur_cal(struct rtw_dev *rtwdev, u8 channel)
4315f028a9cSPing-Ke Shih {
4325f028a9cSPing-Ke Shih 	bool notch;
4335f028a9cSPing-Ke Shih 
4345f028a9cSPing-Ke Shih 	if (channel < 13) {
4355f028a9cSPing-Ke Shih 		rtw8723d_cfg_notch(rtwdev, channel, false);
4365f028a9cSPing-Ke Shih 		return;
4375f028a9cSPing-Ke Shih 	}
4385f028a9cSPing-Ke Shih 
4395f028a9cSPing-Ke Shih 	notch = rtw8723d_check_spur_ov_thres(rtwdev, channel, SPUR_THRES);
4405f028a9cSPing-Ke Shih 	rtw8723d_cfg_notch(rtwdev, channel, notch);
4415f028a9cSPing-Ke Shih }
4425f028a9cSPing-Ke Shih 
4435f028a9cSPing-Ke Shih static void rtw8723d_set_channel_rf(struct rtw_dev *rtwdev, u8 channel, u8 bw)
4445f028a9cSPing-Ke Shih {
4455f028a9cSPing-Ke Shih 	u32 rf_cfgch_a, rf_cfgch_b;
4465f028a9cSPing-Ke Shih 
4475f028a9cSPing-Ke Shih 	rf_cfgch_a = rtw_read_rf(rtwdev, RF_PATH_A, RF_CFGCH, RFREG_MASK);
4485f028a9cSPing-Ke Shih 	rf_cfgch_b = rtw_read_rf(rtwdev, RF_PATH_B, RF_CFGCH, RFREG_MASK);
4495f028a9cSPing-Ke Shih 
4505f028a9cSPing-Ke Shih 	rf_cfgch_a &= ~RFCFGCH_CHANNEL_MASK;
4515f028a9cSPing-Ke Shih 	rf_cfgch_b &= ~RFCFGCH_CHANNEL_MASK;
4525f028a9cSPing-Ke Shih 	rf_cfgch_a |= (channel & RFCFGCH_CHANNEL_MASK);
4535f028a9cSPing-Ke Shih 	rf_cfgch_b |= (channel & RFCFGCH_CHANNEL_MASK);
4545f028a9cSPing-Ke Shih 
4555f028a9cSPing-Ke Shih 	rf_cfgch_a &= ~RFCFGCH_BW_MASK;
4565f028a9cSPing-Ke Shih 	switch (bw) {
4575f028a9cSPing-Ke Shih 	case RTW_CHANNEL_WIDTH_20:
4585f028a9cSPing-Ke Shih 		rf_cfgch_a |= RFCFGCH_BW_20M;
4595f028a9cSPing-Ke Shih 		break;
4605f028a9cSPing-Ke Shih 	case RTW_CHANNEL_WIDTH_40:
4615f028a9cSPing-Ke Shih 		rf_cfgch_a |= RFCFGCH_BW_40M;
4625f028a9cSPing-Ke Shih 		break;
4635f028a9cSPing-Ke Shih 	default:
4645f028a9cSPing-Ke Shih 		break;
4655f028a9cSPing-Ke Shih 	}
4665f028a9cSPing-Ke Shih 
4675f028a9cSPing-Ke Shih 	rtw_write_rf(rtwdev, RF_PATH_A, RF_CFGCH, RFREG_MASK, rf_cfgch_a);
4685f028a9cSPing-Ke Shih 	rtw_write_rf(rtwdev, RF_PATH_B, RF_CFGCH, RFREG_MASK, rf_cfgch_b);
4695f028a9cSPing-Ke Shih 
4705f028a9cSPing-Ke Shih 	rtw8723d_spur_cal(rtwdev, channel);
4715f028a9cSPing-Ke Shih }
4725f028a9cSPing-Ke Shih 
4735f028a9cSPing-Ke Shih static const struct rtw_backup_info cck_dfir_cfg[][CCK_DFIR_NR] = {
4745f028a9cSPing-Ke Shih 	[0] = {
4755f028a9cSPing-Ke Shih 		{ .len = 4, .reg = 0xA24, .val = 0x64B80C1C },
4765f028a9cSPing-Ke Shih 		{ .len = 4, .reg = 0xA28, .val = 0x00008810 },
4775f028a9cSPing-Ke Shih 		{ .len = 4, .reg = 0xAAC, .val = 0x01235667 },
4785f028a9cSPing-Ke Shih 	},
4795f028a9cSPing-Ke Shih 	[1] = {
4805f028a9cSPing-Ke Shih 		{ .len = 4, .reg = 0xA24, .val = 0x0000B81C },
4815f028a9cSPing-Ke Shih 		{ .len = 4, .reg = 0xA28, .val = 0x00000000 },
4825f028a9cSPing-Ke Shih 		{ .len = 4, .reg = 0xAAC, .val = 0x00003667 },
4835f028a9cSPing-Ke Shih 	},
4845f028a9cSPing-Ke Shih };
4855f028a9cSPing-Ke Shih 
4865f028a9cSPing-Ke Shih static void rtw8723d_set_channel_bb(struct rtw_dev *rtwdev, u8 channel, u8 bw,
4875f028a9cSPing-Ke Shih 				    u8 primary_ch_idx)
4885f028a9cSPing-Ke Shih {
4895f028a9cSPing-Ke Shih 	const struct rtw_backup_info *cck_dfir;
4905f028a9cSPing-Ke Shih 	int i;
4915f028a9cSPing-Ke Shih 
4925f028a9cSPing-Ke Shih 	cck_dfir = channel <= 13 ? cck_dfir_cfg[0] : cck_dfir_cfg[1];
4935f028a9cSPing-Ke Shih 
4945f028a9cSPing-Ke Shih 	for (i = 0; i < CCK_DFIR_NR; i++, cck_dfir++)
4955f028a9cSPing-Ke Shih 		rtw_write32(rtwdev, cck_dfir->reg, cck_dfir->val);
4965f028a9cSPing-Ke Shih 
4975f028a9cSPing-Ke Shih 	switch (bw) {
4985f028a9cSPing-Ke Shih 	case RTW_CHANNEL_WIDTH_20:
4995f028a9cSPing-Ke Shih 		rtw_write32_mask(rtwdev, REG_FPGA0_RFMOD, BIT_MASK_RFMOD, 0x0);
5005f028a9cSPing-Ke Shih 		rtw_write32_mask(rtwdev, REG_FPGA1_RFMOD, BIT_MASK_RFMOD, 0x0);
5015f028a9cSPing-Ke Shih 		rtw_write32_mask(rtwdev, REG_BBRX_DFIR, BIT_RXBB_DFIR_EN, 1);
5025f028a9cSPing-Ke Shih 		rtw_write32_mask(rtwdev, REG_BBRX_DFIR, BIT_MASK_RXBB_DFIR, 0xa);
5035f028a9cSPing-Ke Shih 		break;
5045f028a9cSPing-Ke Shih 	case RTW_CHANNEL_WIDTH_40:
5055f028a9cSPing-Ke Shih 		rtw_write32_mask(rtwdev, REG_FPGA0_RFMOD, BIT_MASK_RFMOD, 0x1);
5065f028a9cSPing-Ke Shih 		rtw_write32_mask(rtwdev, REG_FPGA1_RFMOD, BIT_MASK_RFMOD, 0x1);
5075f028a9cSPing-Ke Shih 		rtw_write32_mask(rtwdev, REG_BBRX_DFIR, BIT_RXBB_DFIR_EN, 0);
5085f028a9cSPing-Ke Shih 		rtw_write32_mask(rtwdev, REG_CCK0_SYS, BIT_CCK_SIDE_BAND,
5095f028a9cSPing-Ke Shih 				 (primary_ch_idx == RTW_SC_20_UPPER ? 1 : 0));
5105f028a9cSPing-Ke Shih 		break;
5115f028a9cSPing-Ke Shih 	default:
5125f028a9cSPing-Ke Shih 		break;
5135f028a9cSPing-Ke Shih 	}
5145f028a9cSPing-Ke Shih }
5155f028a9cSPing-Ke Shih 
5165f028a9cSPing-Ke Shih static void rtw8723d_set_channel(struct rtw_dev *rtwdev, u8 channel, u8 bw,
5175f028a9cSPing-Ke Shih 				 u8 primary_chan_idx)
5185f028a9cSPing-Ke Shih {
5195f028a9cSPing-Ke Shih 	rtw8723d_set_channel_rf(rtwdev, channel, bw);
5205f028a9cSPing-Ke Shih 	rtw_set_channel_mac(rtwdev, channel, bw, primary_chan_idx);
5215f028a9cSPing-Ke Shih 	rtw8723d_set_channel_bb(rtwdev, channel, bw, primary_chan_idx);
5225f028a9cSPing-Ke Shih }
5235f028a9cSPing-Ke Shih 
52475e69fb1SPing-Ke Shih #define BIT_CFENDFORM		BIT(9)
52575e69fb1SPing-Ke Shih #define BIT_WMAC_TCR_ERR0	BIT(12)
52675e69fb1SPing-Ke Shih #define BIT_WMAC_TCR_ERR1	BIT(13)
52775e69fb1SPing-Ke Shih #define BIT_TCR_CFG		(BIT_CFENDFORM | BIT_WMAC_TCR_ERR0 |	       \
52875e69fb1SPing-Ke Shih 				 BIT_WMAC_TCR_ERR1)
52975e69fb1SPing-Ke Shih #define WLAN_RX_FILTER0		0xFFFF
53075e69fb1SPing-Ke Shih #define WLAN_RX_FILTER1		0x400
53175e69fb1SPing-Ke Shih #define WLAN_RX_FILTER2		0xFFFF
53275e69fb1SPing-Ke Shih #define WLAN_RCR_CFG		0x700060CE
53375e69fb1SPing-Ke Shih 
53475e69fb1SPing-Ke Shih static int rtw8723d_mac_init(struct rtw_dev *rtwdev)
53575e69fb1SPing-Ke Shih {
53675e69fb1SPing-Ke Shih 	rtw_write8(rtwdev, REG_FWHW_TXQ_CTRL + 1, WLAN_TXQ_RPT_EN);
53775e69fb1SPing-Ke Shih 	rtw_write32(rtwdev, REG_TCR, BIT_TCR_CFG);
53875e69fb1SPing-Ke Shih 
53975e69fb1SPing-Ke Shih 	rtw_write16(rtwdev, REG_RXFLTMAP0, WLAN_RX_FILTER0);
54075e69fb1SPing-Ke Shih 	rtw_write16(rtwdev, REG_RXFLTMAP1, WLAN_RX_FILTER1);
54175e69fb1SPing-Ke Shih 	rtw_write16(rtwdev, REG_RXFLTMAP2, WLAN_RX_FILTER2);
54275e69fb1SPing-Ke Shih 	rtw_write32(rtwdev, REG_RCR, WLAN_RCR_CFG);
54375e69fb1SPing-Ke Shih 
54475e69fb1SPing-Ke Shih 	rtw_write32(rtwdev, REG_INT_MIG, 0);
54575e69fb1SPing-Ke Shih 	rtw_write32(rtwdev, REG_MCUTST_1, 0x0);
54675e69fb1SPing-Ke Shih 
54775e69fb1SPing-Ke Shih 	rtw_write8(rtwdev, REG_MISC_CTRL, BIT_DIS_SECOND_CCA);
54875e69fb1SPing-Ke Shih 	rtw_write8(rtwdev, REG_2ND_CCA_CTRL, 0);
54975e69fb1SPing-Ke Shih 
55075e69fb1SPing-Ke Shih 	return 0;
55175e69fb1SPing-Ke Shih }
55275e69fb1SPing-Ke Shih 
55305202746SPing-Ke Shih static void rtw8723d_shutdown(struct rtw_dev *rtwdev)
55405202746SPing-Ke Shih {
55505202746SPing-Ke Shih 	rtw_write16_set(rtwdev, REG_HCI_OPT_CTRL, BIT_USB_SUS_DIS);
55605202746SPing-Ke Shih }
55705202746SPing-Ke Shih 
5581afb5eb7SPing-Ke Shih static void rtw8723d_cfg_ldo25(struct rtw_dev *rtwdev, bool enable)
5591afb5eb7SPing-Ke Shih {
5601afb5eb7SPing-Ke Shih 	u8 ldo_pwr;
5611afb5eb7SPing-Ke Shih 
5621afb5eb7SPing-Ke Shih 	ldo_pwr = rtw_read8(rtwdev, REG_LDO_EFUSE_CTRL + 3);
5631afb5eb7SPing-Ke Shih 	if (enable) {
5641afb5eb7SPing-Ke Shih 		ldo_pwr &= ~BIT_MASK_LDO25_VOLTAGE;
565c5457559SColin Ian King 		ldo_pwr |= (BIT_LDO25_VOLTAGE_V25 << 4) | BIT_LDO25_EN;
5661afb5eb7SPing-Ke Shih 	} else {
5671afb5eb7SPing-Ke Shih 		ldo_pwr &= ~BIT_LDO25_EN;
5681afb5eb7SPing-Ke Shih 	}
5691afb5eb7SPing-Ke Shih 	rtw_write8(rtwdev, REG_LDO_EFUSE_CTRL + 3, ldo_pwr);
5701afb5eb7SPing-Ke Shih }
5711afb5eb7SPing-Ke Shih 
572ba9f0d1bSPing-Ke Shih static void
573ba9f0d1bSPing-Ke Shih rtw8723d_set_tx_power_index_by_rate(struct rtw_dev *rtwdev, u8 path, u8 rs)
574ba9f0d1bSPing-Ke Shih {
575ba9f0d1bSPing-Ke Shih 	struct rtw_hal *hal = &rtwdev->hal;
576ba9f0d1bSPing-Ke Shih 	const struct rtw_hw_reg *txagc;
577ba9f0d1bSPing-Ke Shih 	u8 rate, pwr_index;
578ba9f0d1bSPing-Ke Shih 	int j;
579ba9f0d1bSPing-Ke Shih 
580ba9f0d1bSPing-Ke Shih 	for (j = 0; j < rtw_rate_size[rs]; j++) {
581ba9f0d1bSPing-Ke Shih 		rate = rtw_rate_section[rs][j];
582ba9f0d1bSPing-Ke Shih 		pwr_index = hal->tx_pwr_tbl[path][rate];
583ba9f0d1bSPing-Ke Shih 
584ba9f0d1bSPing-Ke Shih 		if (rate >= ARRAY_SIZE(rtw8723d_txagc)) {
585ba9f0d1bSPing-Ke Shih 			rtw_warn(rtwdev, "rate 0x%x isn't supported\n", rate);
586ba9f0d1bSPing-Ke Shih 			continue;
587ba9f0d1bSPing-Ke Shih 		}
588ba9f0d1bSPing-Ke Shih 		txagc = &rtw8723d_txagc[rate];
589ba9f0d1bSPing-Ke Shih 		if (!txagc->addr) {
590ba9f0d1bSPing-Ke Shih 			rtw_warn(rtwdev, "rate 0x%x isn't defined\n", rate);
591ba9f0d1bSPing-Ke Shih 			continue;
592ba9f0d1bSPing-Ke Shih 		}
593ba9f0d1bSPing-Ke Shih 
594ba9f0d1bSPing-Ke Shih 		rtw_write32_mask(rtwdev, txagc->addr, txagc->mask, pwr_index);
595ba9f0d1bSPing-Ke Shih 	}
596ba9f0d1bSPing-Ke Shih }
597ba9f0d1bSPing-Ke Shih 
598ba9f0d1bSPing-Ke Shih static void rtw8723d_set_tx_power_index(struct rtw_dev *rtwdev)
599ba9f0d1bSPing-Ke Shih {
600ba9f0d1bSPing-Ke Shih 	struct rtw_hal *hal = &rtwdev->hal;
601ba9f0d1bSPing-Ke Shih 	int rs, path;
602ba9f0d1bSPing-Ke Shih 
603ba9f0d1bSPing-Ke Shih 	for (path = 0; path < hal->rf_path_num; path++) {
604ba9f0d1bSPing-Ke Shih 		for (rs = 0; rs <= RTW_RATE_SECTION_HT_1S; rs++)
605ba9f0d1bSPing-Ke Shih 			rtw8723d_set_tx_power_index_by_rate(rtwdev, path, rs);
606ba9f0d1bSPing-Ke Shih 	}
607ba9f0d1bSPing-Ke Shih }
608ba9f0d1bSPing-Ke Shih 
60944baa97cSPing-Ke Shih static void rtw8723d_efuse_grant(struct rtw_dev *rtwdev, bool on)
61044baa97cSPing-Ke Shih {
61144baa97cSPing-Ke Shih 	if (on) {
61244baa97cSPing-Ke Shih 		rtw_write8(rtwdev, REG_EFUSE_ACCESS, EFUSE_ACCESS_ON);
61344baa97cSPing-Ke Shih 
61444baa97cSPing-Ke Shih 		rtw_write16_set(rtwdev, REG_SYS_FUNC_EN, BIT_FEN_ELDR);
61544baa97cSPing-Ke Shih 		rtw_write16_set(rtwdev, REG_SYS_CLKR, BIT_LOADER_CLK_EN | BIT_ANA8M);
61644baa97cSPing-Ke Shih 	} else {
61744baa97cSPing-Ke Shih 		rtw_write8(rtwdev, REG_EFUSE_ACCESS, EFUSE_ACCESS_OFF);
61844baa97cSPing-Ke Shih 	}
61944baa97cSPing-Ke Shih }
62044baa97cSPing-Ke Shih 
621439d4a97SPing-Ke Shih static void rtw8723d_false_alarm_statistics(struct rtw_dev *rtwdev)
622439d4a97SPing-Ke Shih {
623439d4a97SPing-Ke Shih 	struct rtw_dm_info *dm_info = &rtwdev->dm_info;
624439d4a97SPing-Ke Shih 	u32 cck_fa_cnt;
625439d4a97SPing-Ke Shih 	u32 ofdm_fa_cnt;
626439d4a97SPing-Ke Shih 	u32 crc32_cnt;
627439d4a97SPing-Ke Shih 	u32 val32;
628439d4a97SPing-Ke Shih 
629439d4a97SPing-Ke Shih 	/* hold counter */
630439d4a97SPing-Ke Shih 	rtw_write32_mask(rtwdev, REG_OFDM_FA_HOLDC_11N, BIT_MASK_OFDM_FA_KEEP, 1);
631439d4a97SPing-Ke Shih 	rtw_write32_mask(rtwdev, REG_OFDM_FA_RSTD_11N, BIT_MASK_OFDM_FA_KEEP1, 1);
632439d4a97SPing-Ke Shih 	rtw_write32_mask(rtwdev, REG_CCK_FA_RST_11N, BIT_MASK_CCK_CNT_KEEP, 1);
633439d4a97SPing-Ke Shih 	rtw_write32_mask(rtwdev, REG_CCK_FA_RST_11N, BIT_MASK_CCK_FA_KEEP, 1);
634439d4a97SPing-Ke Shih 
635439d4a97SPing-Ke Shih 	cck_fa_cnt = rtw_read32_mask(rtwdev, REG_CCK_FA_LSB_11N, MASKBYTE0);
636439d4a97SPing-Ke Shih 	cck_fa_cnt += rtw_read32_mask(rtwdev, REG_CCK_FA_MSB_11N, MASKBYTE3) << 8;
637439d4a97SPing-Ke Shih 
638439d4a97SPing-Ke Shih 	val32 = rtw_read32(rtwdev, REG_OFDM_FA_TYPE1_11N);
639439d4a97SPing-Ke Shih 	ofdm_fa_cnt = u32_get_bits(val32, BIT_MASK_OFDM_FF_CNT);
640439d4a97SPing-Ke Shih 	ofdm_fa_cnt += u32_get_bits(val32, BIT_MASK_OFDM_SF_CNT);
641439d4a97SPing-Ke Shih 	val32 = rtw_read32(rtwdev, REG_OFDM_FA_TYPE2_11N);
642439d4a97SPing-Ke Shih 	dm_info->ofdm_cca_cnt = u32_get_bits(val32, BIT_MASK_OFDM_CCA_CNT);
643439d4a97SPing-Ke Shih 	ofdm_fa_cnt += u32_get_bits(val32, BIT_MASK_OFDM_PF_CNT);
644439d4a97SPing-Ke Shih 	val32 = rtw_read32(rtwdev, REG_OFDM_FA_TYPE3_11N);
645439d4a97SPing-Ke Shih 	ofdm_fa_cnt += u32_get_bits(val32, BIT_MASK_OFDM_RI_CNT);
646439d4a97SPing-Ke Shih 	ofdm_fa_cnt += u32_get_bits(val32, BIT_MASK_OFDM_CRC_CNT);
647439d4a97SPing-Ke Shih 	val32 = rtw_read32(rtwdev, REG_OFDM_FA_TYPE4_11N);
648439d4a97SPing-Ke Shih 	ofdm_fa_cnt += u32_get_bits(val32, BIT_MASK_OFDM_MNS_CNT);
649439d4a97SPing-Ke Shih 
650439d4a97SPing-Ke Shih 	dm_info->cck_fa_cnt = cck_fa_cnt;
651439d4a97SPing-Ke Shih 	dm_info->ofdm_fa_cnt = ofdm_fa_cnt;
652439d4a97SPing-Ke Shih 	dm_info->total_fa_cnt = cck_fa_cnt + ofdm_fa_cnt;
653439d4a97SPing-Ke Shih 
654439d4a97SPing-Ke Shih 	dm_info->cck_err_cnt = rtw_read32(rtwdev, REG_IGI_C_11N);
655439d4a97SPing-Ke Shih 	dm_info->cck_ok_cnt = rtw_read32(rtwdev, REG_IGI_D_11N);
656439d4a97SPing-Ke Shih 	crc32_cnt = rtw_read32(rtwdev, REG_OFDM_CRC32_CNT_11N);
657439d4a97SPing-Ke Shih 	dm_info->ofdm_err_cnt = u32_get_bits(crc32_cnt, BIT_MASK_OFDM_LCRC_ERR);
658439d4a97SPing-Ke Shih 	dm_info->ofdm_ok_cnt = u32_get_bits(crc32_cnt, BIT_MASK_OFDM_LCRC_OK);
659439d4a97SPing-Ke Shih 	crc32_cnt = rtw_read32(rtwdev, REG_HT_CRC32_CNT_11N);
660439d4a97SPing-Ke Shih 	dm_info->ht_err_cnt = u32_get_bits(crc32_cnt, BIT_MASK_HT_CRC_ERR);
661439d4a97SPing-Ke Shih 	dm_info->ht_ok_cnt = u32_get_bits(crc32_cnt, BIT_MASK_HT_CRC_OK);
662439d4a97SPing-Ke Shih 	dm_info->vht_err_cnt = 0;
663439d4a97SPing-Ke Shih 	dm_info->vht_ok_cnt = 0;
664439d4a97SPing-Ke Shih 
665439d4a97SPing-Ke Shih 	val32 = rtw_read32(rtwdev, REG_CCK_CCA_CNT_11N);
666439d4a97SPing-Ke Shih 	dm_info->cck_cca_cnt = (u32_get_bits(val32, BIT_MASK_CCK_FA_MSB) << 8) |
667439d4a97SPing-Ke Shih 			       u32_get_bits(val32, BIT_MASK_CCK_FA_LSB);
668439d4a97SPing-Ke Shih 	dm_info->total_cca_cnt = dm_info->cck_cca_cnt + dm_info->ofdm_cca_cnt;
669439d4a97SPing-Ke Shih 
670439d4a97SPing-Ke Shih 	/* reset counter */
671439d4a97SPing-Ke Shih 	rtw_write32_mask(rtwdev, REG_OFDM_FA_RSTC_11N, BIT_MASK_OFDM_FA_RST, 1);
672439d4a97SPing-Ke Shih 	rtw_write32_mask(rtwdev, REG_OFDM_FA_RSTC_11N, BIT_MASK_OFDM_FA_RST, 0);
673439d4a97SPing-Ke Shih 	rtw_write32_mask(rtwdev, REG_OFDM_FA_RSTD_11N, BIT_MASK_OFDM_FA_RST1, 1);
674439d4a97SPing-Ke Shih 	rtw_write32_mask(rtwdev, REG_OFDM_FA_RSTD_11N, BIT_MASK_OFDM_FA_RST1, 0);
675439d4a97SPing-Ke Shih 	rtw_write32_mask(rtwdev, REG_OFDM_FA_HOLDC_11N, BIT_MASK_OFDM_FA_KEEP, 0);
676439d4a97SPing-Ke Shih 	rtw_write32_mask(rtwdev, REG_OFDM_FA_RSTD_11N, BIT_MASK_OFDM_FA_KEEP1, 0);
677439d4a97SPing-Ke Shih 	rtw_write32_mask(rtwdev, REG_CCK_FA_RST_11N, BIT_MASK_CCK_CNT_KPEN, 0);
678439d4a97SPing-Ke Shih 	rtw_write32_mask(rtwdev, REG_CCK_FA_RST_11N, BIT_MASK_CCK_CNT_KPEN, 2);
679439d4a97SPing-Ke Shih 	rtw_write32_mask(rtwdev, REG_CCK_FA_RST_11N, BIT_MASK_CCK_FA_KPEN, 0);
680439d4a97SPing-Ke Shih 	rtw_write32_mask(rtwdev, REG_CCK_FA_RST_11N, BIT_MASK_CCK_FA_KPEN, 2);
681439d4a97SPing-Ke Shih 	rtw_write32_mask(rtwdev, REG_PAGE_F_RST_11N, BIT_MASK_F_RST_ALL, 1);
682439d4a97SPing-Ke Shih 	rtw_write32_mask(rtwdev, REG_PAGE_F_RST_11N, BIT_MASK_F_RST_ALL, 0);
683439d4a97SPing-Ke Shih }
684439d4a97SPing-Ke Shih 
6851d229e88SPing-Ke Shih static const u32 iqk_adda_regs[] = {
6861d229e88SPing-Ke Shih 	0x85c, 0xe6c, 0xe70, 0xe74, 0xe78, 0xe7c, 0xe80, 0xe84, 0xe88, 0xe8c,
6871d229e88SPing-Ke Shih 	0xed0, 0xed4, 0xed8, 0xedc, 0xee0, 0xeec
6881d229e88SPing-Ke Shih };
6891d229e88SPing-Ke Shih 
6901d229e88SPing-Ke Shih static const u32 iqk_mac8_regs[] = {0x522, 0x550, 0x551};
6911d229e88SPing-Ke Shih static const u32 iqk_mac32_regs[] = {0x40};
6921d229e88SPing-Ke Shih 
6931d229e88SPing-Ke Shih static const u32 iqk_bb_regs[] = {
6941d229e88SPing-Ke Shih 	0xc04, 0xc08, 0x874, 0xb68, 0xb6c, 0x870, 0x860, 0x864, 0xa04
6951d229e88SPing-Ke Shih };
6961d229e88SPing-Ke Shih 
6971d229e88SPing-Ke Shih #define IQK_ADDA_REG_NUM	ARRAY_SIZE(iqk_adda_regs)
6981d229e88SPing-Ke Shih #define IQK_MAC8_REG_NUM	ARRAY_SIZE(iqk_mac8_regs)
6991d229e88SPing-Ke Shih #define IQK_MAC32_REG_NUM	ARRAY_SIZE(iqk_mac32_regs)
7001d229e88SPing-Ke Shih #define IQK_BB_REG_NUM		ARRAY_SIZE(iqk_bb_regs)
7011d229e88SPing-Ke Shih 
7021d229e88SPing-Ke Shih struct iqk_backup_regs {
7031d229e88SPing-Ke Shih 	u32 adda[IQK_ADDA_REG_NUM];
7041d229e88SPing-Ke Shih 	u8 mac8[IQK_MAC8_REG_NUM];
7051d229e88SPing-Ke Shih 	u32 mac32[IQK_MAC32_REG_NUM];
7061d229e88SPing-Ke Shih 	u32 bb[IQK_BB_REG_NUM];
7071d229e88SPing-Ke Shih 
7081d229e88SPing-Ke Shih 	u32 lte_path;
7091d229e88SPing-Ke Shih 	u32 lte_gnt;
7101d229e88SPing-Ke Shih 
7111d229e88SPing-Ke Shih 	u32 bb_sel_btg;
7121d229e88SPing-Ke Shih 	u8 btg_sel;
7131d229e88SPing-Ke Shih 
7141d229e88SPing-Ke Shih 	u8 igia;
7151d229e88SPing-Ke Shih 	u8 igib;
7161d229e88SPing-Ke Shih };
7171d229e88SPing-Ke Shih 
7181d229e88SPing-Ke Shih static void rtw8723d_iqk_backup_regs(struct rtw_dev *rtwdev,
7191d229e88SPing-Ke Shih 				     struct iqk_backup_regs *backup)
7201d229e88SPing-Ke Shih {
7211d229e88SPing-Ke Shih 	int i;
7221d229e88SPing-Ke Shih 
7231d229e88SPing-Ke Shih 	for (i = 0; i < IQK_ADDA_REG_NUM; i++)
7241d229e88SPing-Ke Shih 		backup->adda[i] = rtw_read32(rtwdev, iqk_adda_regs[i]);
7251d229e88SPing-Ke Shih 
7261d229e88SPing-Ke Shih 	for (i = 0; i < IQK_MAC8_REG_NUM; i++)
7271d229e88SPing-Ke Shih 		backup->mac8[i] = rtw_read8(rtwdev, iqk_mac8_regs[i]);
7281d229e88SPing-Ke Shih 	for (i = 0; i < IQK_MAC32_REG_NUM; i++)
7291d229e88SPing-Ke Shih 		backup->mac32[i] = rtw_read32(rtwdev, iqk_mac32_regs[i]);
7301d229e88SPing-Ke Shih 
7311d229e88SPing-Ke Shih 	for (i = 0; i < IQK_BB_REG_NUM; i++)
7321d229e88SPing-Ke Shih 		backup->bb[i] = rtw_read32(rtwdev, iqk_bb_regs[i]);
7331d229e88SPing-Ke Shih 
7341d229e88SPing-Ke Shih 	backup->igia = rtw_read32_mask(rtwdev, REG_OFDM0_XAAGC1, MASKBYTE0);
7351d229e88SPing-Ke Shih 	backup->igib = rtw_read32_mask(rtwdev, REG_OFDM0_XBAGC1, MASKBYTE0);
7361d229e88SPing-Ke Shih 
7371d229e88SPing-Ke Shih 	backup->bb_sel_btg = rtw_read32(rtwdev, REG_BB_SEL_BTG);
7381d229e88SPing-Ke Shih }
7391d229e88SPing-Ke Shih 
7401d229e88SPing-Ke Shih static void rtw8723d_iqk_restore_regs(struct rtw_dev *rtwdev,
7411d229e88SPing-Ke Shih 				      const struct iqk_backup_regs *backup)
7421d229e88SPing-Ke Shih {
7431d229e88SPing-Ke Shih 	int i;
7441d229e88SPing-Ke Shih 
7451d229e88SPing-Ke Shih 	for (i = 0; i < IQK_ADDA_REG_NUM; i++)
7461d229e88SPing-Ke Shih 		rtw_write32(rtwdev, iqk_adda_regs[i], backup->adda[i]);
7471d229e88SPing-Ke Shih 
7481d229e88SPing-Ke Shih 	for (i = 0; i < IQK_MAC8_REG_NUM; i++)
7491d229e88SPing-Ke Shih 		rtw_write8(rtwdev, iqk_mac8_regs[i], backup->mac8[i]);
7501d229e88SPing-Ke Shih 	for (i = 0; i < IQK_MAC32_REG_NUM; i++)
7511d229e88SPing-Ke Shih 		rtw_write32(rtwdev, iqk_mac32_regs[i], backup->mac32[i]);
7521d229e88SPing-Ke Shih 
7531d229e88SPing-Ke Shih 	for (i = 0; i < IQK_BB_REG_NUM; i++)
7541d229e88SPing-Ke Shih 		rtw_write32(rtwdev, iqk_bb_regs[i], backup->bb[i]);
7551d229e88SPing-Ke Shih 
7561d229e88SPing-Ke Shih 	rtw_write32_mask(rtwdev, REG_OFDM0_XAAGC1, MASKBYTE0, 0x50);
7571d229e88SPing-Ke Shih 	rtw_write32_mask(rtwdev, REG_OFDM0_XAAGC1, MASKBYTE0, backup->igia);
7581d229e88SPing-Ke Shih 
7591d229e88SPing-Ke Shih 	rtw_write32_mask(rtwdev, REG_OFDM0_XBAGC1, MASKBYTE0, 0x50);
7601d229e88SPing-Ke Shih 	rtw_write32_mask(rtwdev, REG_OFDM0_XBAGC1, MASKBYTE0, backup->igib);
7611d229e88SPing-Ke Shih 
7621d229e88SPing-Ke Shih 	rtw_write32(rtwdev, REG_TXIQK_TONE_A_11N, 0x01008c00);
7631d229e88SPing-Ke Shih 	rtw_write32(rtwdev, REG_RXIQK_TONE_A_11N, 0x01008c00);
7641d229e88SPing-Ke Shih }
7651d229e88SPing-Ke Shih 
7661d229e88SPing-Ke Shih static void rtw8723d_iqk_backup_path_ctrl(struct rtw_dev *rtwdev,
7671d229e88SPing-Ke Shih 					  struct iqk_backup_regs *backup)
7681d229e88SPing-Ke Shih {
7691d229e88SPing-Ke Shih 	backup->btg_sel = rtw_read8(rtwdev, REG_BTG_SEL);
7701d229e88SPing-Ke Shih 	rtw_dbg(rtwdev, RTW_DBG_RFK, "[IQK] original 0x67 = 0x%x\n",
7711d229e88SPing-Ke Shih 		backup->btg_sel);
7721d229e88SPing-Ke Shih }
7731d229e88SPing-Ke Shih 
7741d229e88SPing-Ke Shih static void rtw8723d_iqk_config_path_ctrl(struct rtw_dev *rtwdev)
7751d229e88SPing-Ke Shih {
7761d229e88SPing-Ke Shih 	rtw_write32_mask(rtwdev, REG_PAD_CTRL1, BIT_BT_BTG_SEL, 0x1);
7771d229e88SPing-Ke Shih 	rtw_dbg(rtwdev, RTW_DBG_RFK, "[IQK] set 0x67 = 0x%x\n",
7781d229e88SPing-Ke Shih 		rtw_read32_mask(rtwdev, REG_PAD_CTRL1, MASKBYTE3));
7791d229e88SPing-Ke Shih }
7801d229e88SPing-Ke Shih 
7811d229e88SPing-Ke Shih static void rtw8723d_iqk_restore_path_ctrl(struct rtw_dev *rtwdev,
7821d229e88SPing-Ke Shih 					   const struct iqk_backup_regs *backup)
7831d229e88SPing-Ke Shih {
7841d229e88SPing-Ke Shih 	rtw_write8(rtwdev, REG_BTG_SEL, backup->btg_sel);
7851d229e88SPing-Ke Shih 	rtw_dbg(rtwdev, RTW_DBG_RFK, "[IQK] restore 0x67 = 0x%x\n",
7861d229e88SPing-Ke Shih 		rtw_read32_mask(rtwdev, REG_PAD_CTRL1, MASKBYTE3));
7871d229e88SPing-Ke Shih }
7881d229e88SPing-Ke Shih 
7891d229e88SPing-Ke Shih static void rtw8723d_iqk_backup_lte_path_gnt(struct rtw_dev *rtwdev,
7901d229e88SPing-Ke Shih 					     struct iqk_backup_regs *backup)
7911d229e88SPing-Ke Shih {
7921d229e88SPing-Ke Shih 	backup->lte_path = rtw_read32(rtwdev, REG_LTECOEX_PATH_CONTROL);
7931d229e88SPing-Ke Shih 	rtw_write32(rtwdev, REG_LTECOEX_CTRL, 0x800f0038);
7941d229e88SPing-Ke Shih 	mdelay(1);
7951d229e88SPing-Ke Shih 	backup->lte_gnt = rtw_read32(rtwdev, REG_LTECOEX_READ_DATA);
7961d229e88SPing-Ke Shih 	rtw_dbg(rtwdev, RTW_DBG_RFK, "[IQK] OriginalGNT = 0x%x\n",
7971d229e88SPing-Ke Shih 		backup->lte_gnt);
7981d229e88SPing-Ke Shih }
7991d229e88SPing-Ke Shih 
8001d229e88SPing-Ke Shih static void rtw8723d_iqk_config_lte_path_gnt(struct rtw_dev *rtwdev)
8011d229e88SPing-Ke Shih {
8021d229e88SPing-Ke Shih 	rtw_write32(rtwdev, REG_LTECOEX_WRITE_DATA, 0x0000ff00);
8031d229e88SPing-Ke Shih 	rtw_write32(rtwdev, REG_LTECOEX_CTRL, 0xc0020038);
8041d229e88SPing-Ke Shih 	rtw_write32_mask(rtwdev, REG_LTECOEX_PATH_CONTROL, BIT_LTE_MUX_CTRL_PATH, 0x1);
8051d229e88SPing-Ke Shih }
8061d229e88SPing-Ke Shih 
8071d229e88SPing-Ke Shih static void rtw8723d_iqk_restore_lte_path_gnt(struct rtw_dev *rtwdev,
8081d229e88SPing-Ke Shih 					      const struct iqk_backup_regs *bak)
8091d229e88SPing-Ke Shih {
8101d229e88SPing-Ke Shih 	rtw_write32(rtwdev, REG_LTECOEX_WRITE_DATA, bak->lte_gnt);
8111d229e88SPing-Ke Shih 	rtw_write32(rtwdev, REG_LTECOEX_CTRL, 0xc00f0038);
8121d229e88SPing-Ke Shih 	rtw_write32(rtwdev, REG_LTECOEX_PATH_CONTROL, bak->lte_path);
8131d229e88SPing-Ke Shih }
8141d229e88SPing-Ke Shih 
8151d229e88SPing-Ke Shih struct rtw_8723d_iqk_cfg {
8161d229e88SPing-Ke Shih 	const char *name;
8171d229e88SPing-Ke Shih 	u32 val_bb_sel_btg;
8181d229e88SPing-Ke Shih 	u32 reg_lutwe;
8191d229e88SPing-Ke Shih 	u32 val_txiqk_pi;
8201d229e88SPing-Ke Shih 	u32 reg_padlut;
8211d229e88SPing-Ke Shih 	u32 reg_gaintx;
8221d229e88SPing-Ke Shih 	u32 reg_bspad;
8231d229e88SPing-Ke Shih 	u32 val_wlint;
8241d229e88SPing-Ke Shih 	u32 val_wlsel;
8251d229e88SPing-Ke Shih 	u32 val_iqkpts;
8261d229e88SPing-Ke Shih };
8271d229e88SPing-Ke Shih 
8281d229e88SPing-Ke Shih static const struct rtw_8723d_iqk_cfg iqk_tx_cfg[PATH_NR] = {
8291d229e88SPing-Ke Shih 	[PATH_S1] = {
8301d229e88SPing-Ke Shih 		.name = "S1",
8311d229e88SPing-Ke Shih 		.val_bb_sel_btg = 0x99000000,
8321d229e88SPing-Ke Shih 		.reg_lutwe = RF_LUTWE,
8331d229e88SPing-Ke Shih 		.val_txiqk_pi = 0x8214019f,
8341d229e88SPing-Ke Shih 		.reg_padlut = RF_LUTDBG,
8351d229e88SPing-Ke Shih 		.reg_gaintx = RF_GAINTX,
8361d229e88SPing-Ke Shih 		.reg_bspad = RF_BSPAD,
8371d229e88SPing-Ke Shih 		.val_wlint = 0xe0d,
8381d229e88SPing-Ke Shih 		.val_wlsel = 0x60d,
8391d229e88SPing-Ke Shih 		.val_iqkpts = 0xfa000000,
8401d229e88SPing-Ke Shih 	},
8411d229e88SPing-Ke Shih 	[PATH_S0] = {
8421d229e88SPing-Ke Shih 		.name = "S0",
8431d229e88SPing-Ke Shih 		.val_bb_sel_btg = 0x99000280,
8441d229e88SPing-Ke Shih 		.reg_lutwe = RF_LUTWE2,
8451d229e88SPing-Ke Shih 		.val_txiqk_pi = 0x8214018a,
8461d229e88SPing-Ke Shih 		.reg_padlut = RF_TXADBG,
8471d229e88SPing-Ke Shih 		.reg_gaintx = RF_TRXIQ,
8481d229e88SPing-Ke Shih 		.reg_bspad = RF_TXATANK,
8491d229e88SPing-Ke Shih 		.val_wlint = 0xe6d,
8501d229e88SPing-Ke Shih 		.val_wlsel = 0x66d,
8511d229e88SPing-Ke Shih 		.val_iqkpts = 0xf9000000,
8521d229e88SPing-Ke Shih 	},
8531d229e88SPing-Ke Shih };
8541d229e88SPing-Ke Shih 
8551d229e88SPing-Ke Shih static u8 rtw8723d_iqk_check_tx_failed(struct rtw_dev *rtwdev,
8561d229e88SPing-Ke Shih 				       const struct rtw_8723d_iqk_cfg *iqk_cfg)
8571d229e88SPing-Ke Shih {
8581d229e88SPing-Ke Shih 	s32 tx_x, tx_y;
8591d229e88SPing-Ke Shih 	u32 tx_fail;
8601d229e88SPing-Ke Shih 
8611d229e88SPing-Ke Shih 	rtw_dbg(rtwdev, RTW_DBG_RFK, "[IQK] 0xeac = 0x%x\n",
8621d229e88SPing-Ke Shih 		rtw_read32(rtwdev, REG_IQK_RES_RY));
8631d229e88SPing-Ke Shih 	rtw_dbg(rtwdev, RTW_DBG_RFK, "[IQK] 0xe94 = 0x%x, 0xe9c = 0x%x\n",
8641d229e88SPing-Ke Shih 		rtw_read32(rtwdev, REG_IQK_RES_TX),
8651d229e88SPing-Ke Shih 		rtw_read32(rtwdev, REG_IQK_RES_TY));
8661d229e88SPing-Ke Shih 	rtw_dbg(rtwdev, RTW_DBG_RFK,
8671d229e88SPing-Ke Shih 		"[IQK] 0xe90(before IQK)= 0x%x, 0xe98(afer IQK) = 0x%x\n",
8681d229e88SPing-Ke Shih 		rtw_read32(rtwdev, 0xe90),
8691d229e88SPing-Ke Shih 		rtw_read32(rtwdev, 0xe98));
8701d229e88SPing-Ke Shih 
8711d229e88SPing-Ke Shih 	tx_fail = rtw_read32_mask(rtwdev, REG_IQK_RES_RY, BIT_IQK_TX_FAIL);
8721d229e88SPing-Ke Shih 	tx_x = rtw_read32_mask(rtwdev, REG_IQK_RES_TX, BIT_MASK_RES_TX);
8731d229e88SPing-Ke Shih 	tx_y = rtw_read32_mask(rtwdev, REG_IQK_RES_TY, BIT_MASK_RES_TY);
8741d229e88SPing-Ke Shih 
8751d229e88SPing-Ke Shih 	if (!tx_fail && tx_x != IQK_TX_X_ERR && tx_y != IQK_TX_Y_ERR)
8761d229e88SPing-Ke Shih 		return IQK_TX_OK;
8771d229e88SPing-Ke Shih 
8781d229e88SPing-Ke Shih 	rtw_dbg(rtwdev, RTW_DBG_RFK, "[IQK] %s TXIQK is failed\n",
8791d229e88SPing-Ke Shih 		iqk_cfg->name);
8801d229e88SPing-Ke Shih 
8811d229e88SPing-Ke Shih 	return 0;
8821d229e88SPing-Ke Shih }
8831d229e88SPing-Ke Shih 
8841d229e88SPing-Ke Shih static u8 rtw8723d_iqk_check_rx_failed(struct rtw_dev *rtwdev,
8851d229e88SPing-Ke Shih 				       const struct rtw_8723d_iqk_cfg *iqk_cfg)
8861d229e88SPing-Ke Shih {
8871d229e88SPing-Ke Shih 	s32 rx_x, rx_y;
8881d229e88SPing-Ke Shih 	u32 rx_fail;
8891d229e88SPing-Ke Shih 
8901d229e88SPing-Ke Shih 	rtw_dbg(rtwdev, RTW_DBG_RFK, "[IQK] 0xea4 = 0x%x, 0xeac = 0x%x\n",
8911d229e88SPing-Ke Shih 		rtw_read32(rtwdev, REG_IQK_RES_RX),
8921d229e88SPing-Ke Shih 		rtw_read32(rtwdev, REG_IQK_RES_RY));
8931d229e88SPing-Ke Shih 
8941d229e88SPing-Ke Shih 	rtw_dbg(rtwdev, RTW_DBG_RFK,
8951d229e88SPing-Ke Shih 		"[IQK] 0xea0(before IQK)= 0x%x, 0xea8(afer IQK) = 0x%x\n",
8961d229e88SPing-Ke Shih 		rtw_read32(rtwdev, 0xea0),
8971d229e88SPing-Ke Shih 		rtw_read32(rtwdev, 0xea8));
8981d229e88SPing-Ke Shih 
8991d229e88SPing-Ke Shih 	rx_fail = rtw_read32_mask(rtwdev, REG_IQK_RES_RY, BIT_IQK_RX_FAIL);
9001d229e88SPing-Ke Shih 	rx_x = rtw_read32_mask(rtwdev, REG_IQK_RES_RX, BIT_MASK_RES_RX);
9011d229e88SPing-Ke Shih 	rx_y = rtw_read32_mask(rtwdev, REG_IQK_RES_RY, BIT_MASK_RES_RY);
9021d229e88SPing-Ke Shih 	rx_y = abs(iqkxy_to_s32(rx_y));
9031d229e88SPing-Ke Shih 
9041d229e88SPing-Ke Shih 	if (!rx_fail && rx_x < IQK_RX_X_UPPER && rx_x > IQK_RX_X_LOWER &&
9051d229e88SPing-Ke Shih 	    rx_y < IQK_RX_Y_LMT)
9061d229e88SPing-Ke Shih 		return IQK_RX_OK;
9071d229e88SPing-Ke Shih 
9081d229e88SPing-Ke Shih 	rtw_dbg(rtwdev, RTW_DBG_RFK, "[IQK] %s RXIQK STEP2 is failed\n",
9091d229e88SPing-Ke Shih 		iqk_cfg->name);
9101d229e88SPing-Ke Shih 
9111d229e88SPing-Ke Shih 	return 0;
9121d229e88SPing-Ke Shih }
9131d229e88SPing-Ke Shih 
9141d229e88SPing-Ke Shih static void rtw8723d_iqk_one_shot(struct rtw_dev *rtwdev, bool tx,
9151d229e88SPing-Ke Shih 				  const struct rtw_8723d_iqk_cfg *iqk_cfg)
9161d229e88SPing-Ke Shih {
9171d229e88SPing-Ke Shih 	u32 pts = (tx ? iqk_cfg->val_iqkpts : 0xf9000000);
9181d229e88SPing-Ke Shih 
9191d229e88SPing-Ke Shih 	/* enter IQK mode */
9201d229e88SPing-Ke Shih 	rtw_write32_mask(rtwdev, REG_FPGA0_IQK_11N, BIT_MASK_IQK_MOD, EN_IQK);
9211d229e88SPing-Ke Shih 	rtw8723d_iqk_config_lte_path_gnt(rtwdev);
9221d229e88SPing-Ke Shih 
9231d229e88SPing-Ke Shih 	rtw_write32(rtwdev, REG_LTECOEX_CTRL, 0x800f0054);
9241d229e88SPing-Ke Shih 	mdelay(1);
9251d229e88SPing-Ke Shih 	rtw_dbg(rtwdev, RTW_DBG_RFK, "[IQK] GNT_BT @%s %sIQK1 = 0x%x\n",
9261d229e88SPing-Ke Shih 		iqk_cfg->name, tx ? "TX" : "RX",
9271d229e88SPing-Ke Shih 		rtw_read32(rtwdev, REG_LTECOEX_READ_DATA));
9281d229e88SPing-Ke Shih 	rtw_dbg(rtwdev, RTW_DBG_RFK, "[IQK] 0x948 @%s %sIQK1 = 0x%x\n",
9291d229e88SPing-Ke Shih 		iqk_cfg->name, tx ? "TX" : "RX",
9301d229e88SPing-Ke Shih 		rtw_read32(rtwdev, REG_BB_SEL_BTG));
9311d229e88SPing-Ke Shih 
9321d229e88SPing-Ke Shih 	/* One shot, LOK & IQK */
9331d229e88SPing-Ke Shih 	rtw_write32(rtwdev, REG_IQK_AGC_PTS_11N, pts);
9341d229e88SPing-Ke Shih 	rtw_write32(rtwdev, REG_IQK_AGC_PTS_11N, 0xf8000000);
9351d229e88SPing-Ke Shih 
9361d229e88SPing-Ke Shih 	if (!check_hw_ready(rtwdev, REG_IQK_RES_RY, BIT_IQK_DONE, 1))
9371d229e88SPing-Ke Shih 		rtw_warn(rtwdev, "%s %s IQK isn't done\n", iqk_cfg->name,
9381d229e88SPing-Ke Shih 			 tx ? "TX" : "RX");
9391d229e88SPing-Ke Shih }
9401d229e88SPing-Ke Shih 
9411d229e88SPing-Ke Shih static void rtw8723d_iqk_txrx_path_post(struct rtw_dev *rtwdev,
9421d229e88SPing-Ke Shih 					const struct rtw_8723d_iqk_cfg *iqk_cfg,
9431d229e88SPing-Ke Shih 					const struct iqk_backup_regs *backup)
9441d229e88SPing-Ke Shih {
9451d229e88SPing-Ke Shih 	rtw8723d_iqk_restore_lte_path_gnt(rtwdev, backup);
9461d229e88SPing-Ke Shih 	rtw_write32(rtwdev, REG_BB_SEL_BTG, backup->bb_sel_btg);
9471d229e88SPing-Ke Shih 
9481d229e88SPing-Ke Shih 	/* leave IQK mode */
9491d229e88SPing-Ke Shih 	rtw_write32_mask(rtwdev, REG_FPGA0_IQK_11N, BIT_MASK_IQK_MOD, RST_IQK);
9501d229e88SPing-Ke Shih 	mdelay(1);
9511d229e88SPing-Ke Shih 	rtw_write_rf(rtwdev, RF_PATH_A, iqk_cfg->reg_padlut, 0x800, 0x0);
9521d229e88SPing-Ke Shih 	rtw_write_rf(rtwdev, RF_PATH_A, RF_WLINT, BIT(0), 0x0);
9531d229e88SPing-Ke Shih 	rtw_write_rf(rtwdev, RF_PATH_A, RF_WLSEL, BIT(0), 0x0);
9541d229e88SPing-Ke Shih }
9551d229e88SPing-Ke Shih 
9561d229e88SPing-Ke Shih static u8 rtw8723d_iqk_tx_path(struct rtw_dev *rtwdev,
9571d229e88SPing-Ke Shih 			       const struct rtw_8723d_iqk_cfg *iqk_cfg,
9581d229e88SPing-Ke Shih 			       const struct iqk_backup_regs *backup)
9591d229e88SPing-Ke Shih {
9601d229e88SPing-Ke Shih 	u8 status;
9611d229e88SPing-Ke Shih 
9621d229e88SPing-Ke Shih 	rtw_dbg(rtwdev, RTW_DBG_RFK, "[IQK] path %s TXIQK!!\n", iqk_cfg->name);
9631d229e88SPing-Ke Shih 	rtw_dbg(rtwdev, RTW_DBG_RFK, "[IQK] 0x67 @%s TXIQK = 0x%x\n",
9641d229e88SPing-Ke Shih 		iqk_cfg->name,
9651d229e88SPing-Ke Shih 		rtw_read32_mask(rtwdev, REG_PAD_CTRL1, MASKBYTE3));
9661d229e88SPing-Ke Shih 
9671d229e88SPing-Ke Shih 	rtw_write32(rtwdev, REG_BB_SEL_BTG, iqk_cfg->val_bb_sel_btg);
9681d229e88SPing-Ke Shih 	rtw_write32_mask(rtwdev, REG_FPGA0_IQK_11N, BIT_MASK_IQK_MOD, RST_IQK);
9691d229e88SPing-Ke Shih 	mdelay(1);
9701d229e88SPing-Ke Shih 	rtw_write_rf(rtwdev, RF_PATH_A, iqk_cfg->reg_lutwe, RFREG_MASK, 0x80000);
9711d229e88SPing-Ke Shih 	rtw_write_rf(rtwdev, RF_PATH_A, RF_LUTWA, RFREG_MASK, 0x00004);
9721d229e88SPing-Ke Shih 	rtw_write_rf(rtwdev, RF_PATH_A, RF_LUTWD1, RFREG_MASK, 0x0005d);
9731d229e88SPing-Ke Shih 	rtw_write_rf(rtwdev, RF_PATH_A, RF_LUTWD0, RFREG_MASK, 0xBFFE0);
9741d229e88SPing-Ke Shih 	rtw_write_rf(rtwdev, RF_PATH_A, iqk_cfg->reg_lutwe, RFREG_MASK, 0x00000);
9751d229e88SPing-Ke Shih 
9761d229e88SPing-Ke Shih 	/* IQK setting */
9771d229e88SPing-Ke Shih 	rtw_write32(rtwdev, REG_TXIQK_TONE_A_11N, 0x08008c0c);
9781d229e88SPing-Ke Shih 	rtw_write32(rtwdev, REG_RXIQK_TONE_A_11N, 0x38008c1c);
9791d229e88SPing-Ke Shih 	rtw_write32(rtwdev, REG_TXIQK_PI_A_11N, iqk_cfg->val_txiqk_pi);
9801d229e88SPing-Ke Shih 	rtw_write32(rtwdev, REG_RXIQK_PI_A_11N, 0x28160200);
9811d229e88SPing-Ke Shih 	rtw_write32(rtwdev, REG_TXIQK_11N, 0x01007c00);
9821d229e88SPing-Ke Shih 	rtw_write32(rtwdev, REG_RXIQK_11N, 0x01004800);
9831d229e88SPing-Ke Shih 
9841d229e88SPing-Ke Shih 	/* LOK setting */
9851d229e88SPing-Ke Shih 	rtw_write32(rtwdev, REG_IQK_AGC_RSP_11N, 0x00462911);
9861d229e88SPing-Ke Shih 
9871d229e88SPing-Ke Shih 	/* PA, PAD setting */
9881d229e88SPing-Ke Shih 	rtw_write_rf(rtwdev, RF_PATH_A, iqk_cfg->reg_padlut, 0x800, 0x1);
9891d229e88SPing-Ke Shih 	rtw_write_rf(rtwdev, RF_PATH_A, iqk_cfg->reg_gaintx, 0x600, 0x0);
9901d229e88SPing-Ke Shih 	rtw_write_rf(rtwdev, RF_PATH_A, iqk_cfg->reg_gaintx, 0x1E0, 0x3);
9911d229e88SPing-Ke Shih 	rtw_write_rf(rtwdev, RF_PATH_A, RF_RXIQGEN, 0x1F, 0xf);
9921d229e88SPing-Ke Shih 
9931d229e88SPing-Ke Shih 	/* LOK setting for 8723D */
9941d229e88SPing-Ke Shih 	rtw_write_rf(rtwdev, RF_PATH_A, iqk_cfg->reg_lutwe, 0x10, 0x1);
9951d229e88SPing-Ke Shih 	rtw_write_rf(rtwdev, RF_PATH_A, iqk_cfg->reg_bspad, 0x1, 0x1);
9961d229e88SPing-Ke Shih 
9971d229e88SPing-Ke Shih 	rtw_write_rf(rtwdev, RF_PATH_A, RF_WLINT, RFREG_MASK, iqk_cfg->val_wlint);
9981d229e88SPing-Ke Shih 	rtw_write_rf(rtwdev, RF_PATH_A, RF_WLSEL, RFREG_MASK, iqk_cfg->val_wlsel);
9991d229e88SPing-Ke Shih 
10001d229e88SPing-Ke Shih 	rtw_dbg(rtwdev, RTW_DBG_RFK, "[IQK] RF0x1 @%s TXIQK = 0x%x\n",
10011d229e88SPing-Ke Shih 		iqk_cfg->name,
10021d229e88SPing-Ke Shih 		rtw_read_rf(rtwdev, RF_PATH_A, RF_WLINT, RFREG_MASK));
10031d229e88SPing-Ke Shih 	rtw_dbg(rtwdev, RTW_DBG_RFK, "[IQK] RF0x2 @%s TXIQK = 0x%x\n",
10041d229e88SPing-Ke Shih 		iqk_cfg->name,
10051d229e88SPing-Ke Shih 		rtw_read_rf(rtwdev, RF_PATH_A, RF_WLSEL, RFREG_MASK));
10061d229e88SPing-Ke Shih 
10071d229e88SPing-Ke Shih 	rtw8723d_iqk_one_shot(rtwdev, true, iqk_cfg);
10081d229e88SPing-Ke Shih 	status = rtw8723d_iqk_check_tx_failed(rtwdev, iqk_cfg);
10091d229e88SPing-Ke Shih 
10101d229e88SPing-Ke Shih 	rtw8723d_iqk_txrx_path_post(rtwdev, iqk_cfg, backup);
10111d229e88SPing-Ke Shih 
10121d229e88SPing-Ke Shih 	return status;
10131d229e88SPing-Ke Shih }
10141d229e88SPing-Ke Shih 
10151d229e88SPing-Ke Shih static u8 rtw8723d_iqk_rx_path(struct rtw_dev *rtwdev,
10161d229e88SPing-Ke Shih 			       const struct rtw_8723d_iqk_cfg *iqk_cfg,
10171d229e88SPing-Ke Shih 			       const struct iqk_backup_regs *backup)
10181d229e88SPing-Ke Shih {
10191d229e88SPing-Ke Shih 	u32 tx_x, tx_y;
10201d229e88SPing-Ke Shih 	u8 status;
10211d229e88SPing-Ke Shih 
10221d229e88SPing-Ke Shih 	rtw_dbg(rtwdev, RTW_DBG_RFK, "[IQK] path %s RXIQK Step1!!\n",
10231d229e88SPing-Ke Shih 		iqk_cfg->name);
10241d229e88SPing-Ke Shih 	rtw_dbg(rtwdev, RTW_DBG_RFK, "[IQK] 0x67 @%s RXIQK1 = 0x%x\n",
10251d229e88SPing-Ke Shih 		iqk_cfg->name,
10261d229e88SPing-Ke Shih 		rtw_read32_mask(rtwdev, REG_PAD_CTRL1, MASKBYTE3));
10271d229e88SPing-Ke Shih 	rtw_write32(rtwdev, REG_BB_SEL_BTG, iqk_cfg->val_bb_sel_btg);
10281d229e88SPing-Ke Shih 
10291d229e88SPing-Ke Shih 	rtw_write32_mask(rtwdev, REG_FPGA0_IQK_11N, BIT_MASK_IQK_MOD, RST_IQK);
10301d229e88SPing-Ke Shih 
10311d229e88SPing-Ke Shih 	/* IQK setting */
10321d229e88SPing-Ke Shih 	rtw_write32(rtwdev, REG_TXIQK_11N, 0x01007c00);
10331d229e88SPing-Ke Shih 	rtw_write32(rtwdev, REG_RXIQK_11N, 0x01004800);
10341d229e88SPing-Ke Shih 
10351d229e88SPing-Ke Shih 	/* path IQK setting */
10361d229e88SPing-Ke Shih 	rtw_write32(rtwdev, REG_TXIQK_TONE_A_11N, 0x18008c1c);
10371d229e88SPing-Ke Shih 	rtw_write32(rtwdev, REG_RXIQK_TONE_A_11N, 0x38008c1c);
10381d229e88SPing-Ke Shih 	rtw_write32(rtwdev, REG_TX_IQK_TONE_B, 0x38008c1c);
10391d229e88SPing-Ke Shih 	rtw_write32(rtwdev, REG_RX_IQK_TONE_B, 0x38008c1c);
10401d229e88SPing-Ke Shih 	rtw_write32(rtwdev, REG_TXIQK_PI_A_11N, 0x82160000);
10411d229e88SPing-Ke Shih 	rtw_write32(rtwdev, REG_RXIQK_PI_A_11N, 0x28160000);
10421d229e88SPing-Ke Shih 
10431d229e88SPing-Ke Shih 	/* LOK setting */
10441d229e88SPing-Ke Shih 	rtw_write32(rtwdev, REG_IQK_AGC_RSP_11N, 0x0046a911);
10451d229e88SPing-Ke Shih 
10461d229e88SPing-Ke Shih 	/* RXIQK mode */
10471d229e88SPing-Ke Shih 	rtw_write_rf(rtwdev, RF_PATH_A, iqk_cfg->reg_lutwe, RFREG_MASK, 0x80000);
10481d229e88SPing-Ke Shih 	rtw_write_rf(rtwdev, RF_PATH_A, RF_LUTWA, RFREG_MASK, 0x00006);
10491d229e88SPing-Ke Shih 	rtw_write_rf(rtwdev, RF_PATH_A, RF_LUTWD1, RFREG_MASK, 0x0005f);
10501d229e88SPing-Ke Shih 	rtw_write_rf(rtwdev, RF_PATH_A, RF_LUTWD0, RFREG_MASK, 0xa7ffb);
10511d229e88SPing-Ke Shih 	rtw_write_rf(rtwdev, RF_PATH_A, iqk_cfg->reg_lutwe, RFREG_MASK, 0x00000);
10521d229e88SPing-Ke Shih 
10531d229e88SPing-Ke Shih 	/* PA/PAD=0 */
10541d229e88SPing-Ke Shih 	rtw_write_rf(rtwdev, RF_PATH_A, iqk_cfg->reg_padlut, 0x800, 0x1);
10551d229e88SPing-Ke Shih 	rtw_write_rf(rtwdev, RF_PATH_A, iqk_cfg->reg_gaintx, 0x600, 0x0);
10561d229e88SPing-Ke Shih 	rtw_write_rf(rtwdev, RF_PATH_A, RF_WLINT, RFREG_MASK, iqk_cfg->val_wlint);
10571d229e88SPing-Ke Shih 	rtw_write_rf(rtwdev, RF_PATH_A, RF_WLSEL, RFREG_MASK, iqk_cfg->val_wlsel);
10581d229e88SPing-Ke Shih 
10591d229e88SPing-Ke Shih 	rtw_dbg(rtwdev, RTW_DBG_RFK, "[IQK] RF0x1@ path %s RXIQK1 = 0x%x\n",
10601d229e88SPing-Ke Shih 		iqk_cfg->name,
10611d229e88SPing-Ke Shih 		rtw_read_rf(rtwdev, RF_PATH_A, RF_WLINT, RFREG_MASK));
10621d229e88SPing-Ke Shih 	rtw_dbg(rtwdev, RTW_DBG_RFK, "[IQK] RF0x2@ path %s RXIQK1 = 0x%x\n",
10631d229e88SPing-Ke Shih 		iqk_cfg->name,
10641d229e88SPing-Ke Shih 		rtw_read_rf(rtwdev, RF_PATH_A, RF_WLSEL, RFREG_MASK));
10651d229e88SPing-Ke Shih 
10661d229e88SPing-Ke Shih 	rtw8723d_iqk_one_shot(rtwdev, false, iqk_cfg);
10671d229e88SPing-Ke Shih 	status = rtw8723d_iqk_check_tx_failed(rtwdev, iqk_cfg);
10681d229e88SPing-Ke Shih 
10691d229e88SPing-Ke Shih 	if (!status)
10701d229e88SPing-Ke Shih 		goto restore;
10711d229e88SPing-Ke Shih 
10721d229e88SPing-Ke Shih 	/* second round */
10731d229e88SPing-Ke Shih 	tx_x = rtw_read32_mask(rtwdev, REG_IQK_RES_TX, BIT_MASK_RES_TX);
10741d229e88SPing-Ke Shih 	tx_y = rtw_read32_mask(rtwdev, REG_IQK_RES_TY, BIT_MASK_RES_TY);
10751d229e88SPing-Ke Shih 
10761d229e88SPing-Ke Shih 	rtw_write32(rtwdev, REG_TXIQK_11N, BIT_SET_TXIQK_11N(tx_x, tx_y));
10771d229e88SPing-Ke Shih 	rtw_dbg(rtwdev, RTW_DBG_RFK, "[IQK] 0xe40 = 0x%x u4tmp = 0x%x\n",
10781d229e88SPing-Ke Shih 		rtw_read32(rtwdev, REG_TXIQK_11N),
10791d229e88SPing-Ke Shih 		BIT_SET_TXIQK_11N(tx_x, tx_y));
10801d229e88SPing-Ke Shih 
10811d229e88SPing-Ke Shih 	rtw_dbg(rtwdev, RTW_DBG_RFK, "[IQK] path %s RXIQK STEP2!!\n",
10821d229e88SPing-Ke Shih 		iqk_cfg->name);
10831d229e88SPing-Ke Shih 	rtw_dbg(rtwdev, RTW_DBG_RFK, "[IQK] 0x67 @%s RXIQK2 = 0x%x\n",
10841d229e88SPing-Ke Shih 		iqk_cfg->name,
10851d229e88SPing-Ke Shih 		rtw_read32_mask(rtwdev, REG_PAD_CTRL1, MASKBYTE3));
10861d229e88SPing-Ke Shih 
10871d229e88SPing-Ke Shih 	rtw_write32(rtwdev, REG_RXIQK_11N, 0x01004800);
10881d229e88SPing-Ke Shih 	rtw_write32(rtwdev, REG_TXIQK_TONE_A_11N, 0x38008c1c);
10891d229e88SPing-Ke Shih 	rtw_write32(rtwdev, REG_RXIQK_TONE_A_11N, 0x18008c1c);
10901d229e88SPing-Ke Shih 	rtw_write32(rtwdev, REG_TX_IQK_TONE_B, 0x38008c1c);
10911d229e88SPing-Ke Shih 	rtw_write32(rtwdev, REG_RX_IQK_TONE_B, 0x38008c1c);
10921d229e88SPing-Ke Shih 	rtw_write32(rtwdev, REG_TXIQK_PI_A_11N, 0x82170000);
10931d229e88SPing-Ke Shih 	rtw_write32(rtwdev, REG_RXIQK_PI_A_11N, 0x28171400);
10941d229e88SPing-Ke Shih 
10951d229e88SPing-Ke Shih 	/* LOK setting */
10961d229e88SPing-Ke Shih 	rtw_write32(rtwdev, REG_IQK_AGC_RSP_11N, 0x0046a8d1);
10971d229e88SPing-Ke Shih 
10981d229e88SPing-Ke Shih 	/* RXIQK mode */
10991d229e88SPing-Ke Shih 	rtw_write32_mask(rtwdev, REG_FPGA0_IQK_11N, BIT_MASK_IQK_MOD, RST_IQK);
11001d229e88SPing-Ke Shih 	mdelay(1);
11011d229e88SPing-Ke Shih 	rtw_write_rf(rtwdev, RF_PATH_A, iqk_cfg->reg_lutwe, 0x80000, 0x1);
11021d229e88SPing-Ke Shih 	rtw_write_rf(rtwdev, RF_PATH_A, RF_LUTWA, RFREG_MASK, 0x00007);
11031d229e88SPing-Ke Shih 	rtw_write_rf(rtwdev, RF_PATH_A, RF_LUTWD1, RFREG_MASK, 0x0005f);
11041d229e88SPing-Ke Shih 	rtw_write_rf(rtwdev, RF_PATH_A, RF_LUTWD0, RFREG_MASK, 0xb3fdb);
11051d229e88SPing-Ke Shih 	rtw_write_rf(rtwdev, RF_PATH_A, iqk_cfg->reg_lutwe, RFREG_MASK, 0x00000);
11061d229e88SPing-Ke Shih 
11071d229e88SPing-Ke Shih 	rtw_dbg(rtwdev, RTW_DBG_RFK, "[IQK] RF0x1 @%s RXIQK2 = 0x%x\n",
11081d229e88SPing-Ke Shih 		iqk_cfg->name,
11091d229e88SPing-Ke Shih 		rtw_read_rf(rtwdev, RF_PATH_A, RF_WLINT, RFREG_MASK));
11101d229e88SPing-Ke Shih 	rtw_dbg(rtwdev, RTW_DBG_RFK, "[IQK] RF0x2 @%s RXIQK2 = 0x%x\n",
11111d229e88SPing-Ke Shih 		iqk_cfg->name,
11121d229e88SPing-Ke Shih 		rtw_read_rf(rtwdev, RF_PATH_A, RF_WLSEL, RFREG_MASK));
11131d229e88SPing-Ke Shih 
11141d229e88SPing-Ke Shih 	rtw8723d_iqk_one_shot(rtwdev, false, iqk_cfg);
11151d229e88SPing-Ke Shih 	status |= rtw8723d_iqk_check_rx_failed(rtwdev, iqk_cfg);
11161d229e88SPing-Ke Shih 
11171d229e88SPing-Ke Shih restore:
11181d229e88SPing-Ke Shih 	rtw8723d_iqk_txrx_path_post(rtwdev, iqk_cfg, backup);
11191d229e88SPing-Ke Shih 
11201d229e88SPing-Ke Shih 	return status;
11211d229e88SPing-Ke Shih }
11221d229e88SPing-Ke Shih 
11231d229e88SPing-Ke Shih static
11241d229e88SPing-Ke Shih void rtw8723d_iqk_fill_s1_matrix(struct rtw_dev *rtwdev, const s32 result[])
11251d229e88SPing-Ke Shih {
11261d229e88SPing-Ke Shih 	s32 oldval_1;
11271d229e88SPing-Ke Shih 	s32 x, y;
11281d229e88SPing-Ke Shih 	s32 tx1_a, tx1_a_ext;
11291d229e88SPing-Ke Shih 	s32 tx1_c, tx1_c_ext;
11301d229e88SPing-Ke Shih 
11311d229e88SPing-Ke Shih 	if (result[IQK_S1_TX_X] == 0)
11321d229e88SPing-Ke Shih 		return;
11331d229e88SPing-Ke Shih 
11341d229e88SPing-Ke Shih 	oldval_1 = rtw_read32_mask(rtwdev, REG_OFDM_0_XA_TX_IQ_IMBALANCE,
11351d229e88SPing-Ke Shih 				   BIT_MASK_TXIQ_ELM_D);
11361d229e88SPing-Ke Shih 
11371d229e88SPing-Ke Shih 	x = iqkxy_to_s32(result[IQK_S1_TX_X]);
11381d229e88SPing-Ke Shih 	tx1_a = iqk_mult(x, oldval_1, &tx1_a_ext);
11391d229e88SPing-Ke Shih 	rtw_write32_mask(rtwdev, REG_OFDM_0_XA_TX_IQ_IMBALANCE,
11401d229e88SPing-Ke Shih 			 BIT_MASK_TXIQ_ELM_A, tx1_a);
11411d229e88SPing-Ke Shih 	rtw_write32_mask(rtwdev, REG_OFDM_0_ECCA_THRESHOLD,
11421d229e88SPing-Ke Shih 			 BIT_MASK_OFDM0_EXT_A, tx1_a_ext);
11431d229e88SPing-Ke Shih 
11441d229e88SPing-Ke Shih 	y = iqkxy_to_s32(result[IQK_S1_TX_Y]);
11451d229e88SPing-Ke Shih 	tx1_c = iqk_mult(y, oldval_1, &tx1_c_ext);
11461d229e88SPing-Ke Shih 	rtw_write32_mask(rtwdev, REG_TXIQK_MATRIXA_LSB2_11N, MASKH4BITS,
11471d229e88SPing-Ke Shih 			 BIT_SET_TXIQ_ELM_C1(tx1_c));
11481d229e88SPing-Ke Shih 	rtw_write32_mask(rtwdev, REG_OFDM_0_XA_TX_IQ_IMBALANCE,
11491d229e88SPing-Ke Shih 			 BIT_MASK_TXIQ_ELM_C, BIT_SET_TXIQ_ELM_C2(tx1_c));
11501d229e88SPing-Ke Shih 	rtw_write32_mask(rtwdev, REG_OFDM_0_ECCA_THRESHOLD,
11511d229e88SPing-Ke Shih 			 BIT_MASK_OFDM0_EXT_C, tx1_c_ext);
11521d229e88SPing-Ke Shih 
11531d229e88SPing-Ke Shih 	rtw_dbg(rtwdev, RTW_DBG_RFK,
11541d229e88SPing-Ke Shih 		"[IQK] X = 0x%x, TX1_A = 0x%x, oldval_1 0x%x\n",
11551d229e88SPing-Ke Shih 		x, tx1_a, oldval_1);
11561d229e88SPing-Ke Shih 	rtw_dbg(rtwdev, RTW_DBG_RFK,
11571d229e88SPing-Ke Shih 		"[IQK] Y = 0x%x, TX1_C = 0x%x\n", y, tx1_c);
11581d229e88SPing-Ke Shih 
11591d229e88SPing-Ke Shih 	if (result[IQK_S1_RX_X] == 0)
11601d229e88SPing-Ke Shih 		return;
11611d229e88SPing-Ke Shih 
11621d229e88SPing-Ke Shih 	rtw_write32_mask(rtwdev, REG_A_RXIQI, BIT_MASK_RXIQ_S1_X,
11631d229e88SPing-Ke Shih 			 result[IQK_S1_RX_X]);
11641d229e88SPing-Ke Shih 	rtw_write32_mask(rtwdev, REG_A_RXIQI, BIT_MASK_RXIQ_S1_Y1,
11651d229e88SPing-Ke Shih 			 BIT_SET_RXIQ_S1_Y1(result[IQK_S1_RX_Y]));
11661d229e88SPing-Ke Shih 	rtw_write32_mask(rtwdev, REG_RXIQK_MATRIX_LSB_11N, BIT_MASK_RXIQ_S1_Y2,
11671d229e88SPing-Ke Shih 			 BIT_SET_RXIQ_S1_Y2(result[IQK_S1_RX_Y]));
11681d229e88SPing-Ke Shih }
11691d229e88SPing-Ke Shih 
11701d229e88SPing-Ke Shih static
11711d229e88SPing-Ke Shih void rtw8723d_iqk_fill_s0_matrix(struct rtw_dev *rtwdev, const s32 result[])
11721d229e88SPing-Ke Shih {
11731d229e88SPing-Ke Shih 	s32 oldval_0;
11741d229e88SPing-Ke Shih 	s32 x, y;
11751d229e88SPing-Ke Shih 	s32 tx0_a, tx0_a_ext;
11761d229e88SPing-Ke Shih 	s32 tx0_c, tx0_c_ext;
11771d229e88SPing-Ke Shih 
11781d229e88SPing-Ke Shih 	if (result[IQK_S0_TX_X] == 0)
11791d229e88SPing-Ke Shih 		return;
11801d229e88SPing-Ke Shih 
11811d229e88SPing-Ke Shih 	oldval_0 = rtw_read32_mask(rtwdev, REG_TXIQ_CD_S0, BIT_MASK_TXIQ_D_S0);
11821d229e88SPing-Ke Shih 
11831d229e88SPing-Ke Shih 	x = iqkxy_to_s32(result[IQK_S0_TX_X]);
11841d229e88SPing-Ke Shih 	tx0_a = iqk_mult(x, oldval_0, &tx0_a_ext);
11851d229e88SPing-Ke Shih 
11861d229e88SPing-Ke Shih 	rtw_write32_mask(rtwdev, REG_TXIQ_AB_S0, BIT_MASK_TXIQ_A_S0, tx0_a);
11871d229e88SPing-Ke Shih 	rtw_write32_mask(rtwdev, REG_TXIQ_AB_S0, BIT_MASK_TXIQ_A_EXT_S0, tx0_a_ext);
11881d229e88SPing-Ke Shih 
11891d229e88SPing-Ke Shih 	y = iqkxy_to_s32(result[IQK_S0_TX_Y]);
11901d229e88SPing-Ke Shih 	tx0_c = iqk_mult(y, oldval_0, &tx0_c_ext);
11911d229e88SPing-Ke Shih 
11921d229e88SPing-Ke Shih 	rtw_write32_mask(rtwdev, REG_TXIQ_CD_S0, BIT_MASK_TXIQ_C_S0, tx0_c);
11931d229e88SPing-Ke Shih 	rtw_write32_mask(rtwdev, REG_TXIQ_CD_S0, BIT_MASK_TXIQ_C_EXT_S0, tx0_c_ext);
11941d229e88SPing-Ke Shih 
11951d229e88SPing-Ke Shih 	if (result[IQK_S0_RX_X] == 0)
11961d229e88SPing-Ke Shih 		return;
11971d229e88SPing-Ke Shih 
11981d229e88SPing-Ke Shih 	rtw_write32_mask(rtwdev, REG_RXIQ_AB_S0, BIT_MASK_RXIQ_X_S0,
11991d229e88SPing-Ke Shih 			 result[IQK_S0_RX_X]);
12001d229e88SPing-Ke Shih 	rtw_write32_mask(rtwdev, REG_RXIQ_AB_S0, BIT_MASK_RXIQ_Y_S0,
12011d229e88SPing-Ke Shih 			 result[IQK_S0_RX_Y]);
12021d229e88SPing-Ke Shih }
12031d229e88SPing-Ke Shih 
12041d229e88SPing-Ke Shih static void rtw8723d_iqk_path_adda_on(struct rtw_dev *rtwdev)
12051d229e88SPing-Ke Shih {
12061d229e88SPing-Ke Shih 	int i;
12071d229e88SPing-Ke Shih 
12081d229e88SPing-Ke Shih 	for (i = 0; i < IQK_ADDA_REG_NUM; i++)
12091d229e88SPing-Ke Shih 		rtw_write32(rtwdev, iqk_adda_regs[i], 0x03c00016);
12101d229e88SPing-Ke Shih }
12111d229e88SPing-Ke Shih 
12121d229e88SPing-Ke Shih static void rtw8723d_iqk_config_mac(struct rtw_dev *rtwdev)
12131d229e88SPing-Ke Shih {
12141d229e88SPing-Ke Shih 	rtw_write8(rtwdev, REG_TXPAUSE, 0xff);
12151d229e88SPing-Ke Shih }
12161d229e88SPing-Ke Shih 
12171d229e88SPing-Ke Shih static
12181d229e88SPing-Ke Shih void rtw8723d_iqk_rf_standby(struct rtw_dev *rtwdev, enum rtw_rf_path path)
12191d229e88SPing-Ke Shih {
12201d229e88SPing-Ke Shih 	rtw_dbg(rtwdev, RTW_DBG_RFK, "[IQK] path-%s standby mode!\n",
12211d229e88SPing-Ke Shih 		path == RF_PATH_A ? "S1" : "S0");
12221d229e88SPing-Ke Shih 
12231d229e88SPing-Ke Shih 	rtw_write32_mask(rtwdev, REG_FPGA0_IQK_11N, BIT_MASK_IQK_MOD, RST_IQK);
12241d229e88SPing-Ke Shih 	mdelay(1);
12251d229e88SPing-Ke Shih 	rtw_write_rf(rtwdev, path, RF_MODE, RFREG_MASK, 0x10000);
12261d229e88SPing-Ke Shih 	rtw_write32_mask(rtwdev, REG_FPGA0_IQK_11N, BIT_MASK_IQK_MOD, EN_IQK);
12271d229e88SPing-Ke Shih }
12281d229e88SPing-Ke Shih 
12291d229e88SPing-Ke Shih static
12301d229e88SPing-Ke Shih bool rtw8723d_iqk_similarity_cmp(struct rtw_dev *rtwdev, s32 result[][IQK_NR],
12311d229e88SPing-Ke Shih 				 u8 c1, u8 c2)
12321d229e88SPing-Ke Shih {
12331d229e88SPing-Ke Shih 	u32 i, j, diff;
12341d229e88SPing-Ke Shih 	u32 bitmap = 0;
12351d229e88SPing-Ke Shih 	u8 candidate[PATH_NR] = {IQK_ROUND_INVALID, IQK_ROUND_INVALID};
12361d229e88SPing-Ke Shih 	bool ret = true;
12371d229e88SPing-Ke Shih 
12381d229e88SPing-Ke Shih 	s32 tmp1, tmp2;
12391d229e88SPing-Ke Shih 
12401d229e88SPing-Ke Shih 	for (i = 0; i < IQK_NR; i++) {
12411d229e88SPing-Ke Shih 		tmp1 = iqkxy_to_s32(result[c1][i]);
12421d229e88SPing-Ke Shih 		tmp2 = iqkxy_to_s32(result[c2][i]);
12431d229e88SPing-Ke Shih 
12441d229e88SPing-Ke Shih 		diff = abs(tmp1 - tmp2);
12451d229e88SPing-Ke Shih 
12461d229e88SPing-Ke Shih 		if (diff <= MAX_TOLERANCE)
12471d229e88SPing-Ke Shih 			continue;
12481d229e88SPing-Ke Shih 
12491d229e88SPing-Ke Shih 		if ((i == IQK_S1_RX_X || i == IQK_S0_RX_X) && !bitmap) {
12501d229e88SPing-Ke Shih 			if (result[c1][i] + result[c1][i + 1] == 0)
12511d229e88SPing-Ke Shih 				candidate[i / IQK_SX_NR] = c2;
12521d229e88SPing-Ke Shih 			else if (result[c2][i] + result[c2][i + 1] == 0)
12531d229e88SPing-Ke Shih 				candidate[i / IQK_SX_NR] = c1;
12541d229e88SPing-Ke Shih 			else
12551d229e88SPing-Ke Shih 				bitmap |= BIT(i);
12561d229e88SPing-Ke Shih 		} else {
12571d229e88SPing-Ke Shih 			bitmap |= BIT(i);
12581d229e88SPing-Ke Shih 		}
12591d229e88SPing-Ke Shih 	}
12601d229e88SPing-Ke Shih 
12611d229e88SPing-Ke Shih 	if (bitmap != 0)
12621d229e88SPing-Ke Shih 		goto check_sim;
12631d229e88SPing-Ke Shih 
12641d229e88SPing-Ke Shih 	for (i = 0; i < PATH_NR; i++) {
12651d229e88SPing-Ke Shih 		if (candidate[i] == IQK_ROUND_INVALID)
12661d229e88SPing-Ke Shih 			continue;
12671d229e88SPing-Ke Shih 
12681d229e88SPing-Ke Shih 		for (j = i * IQK_SX_NR; j < i * IQK_SX_NR + 2; j++)
12691d229e88SPing-Ke Shih 			result[IQK_ROUND_HYBRID][j] = result[candidate[i]][j];
12701d229e88SPing-Ke Shih 		ret = false;
12711d229e88SPing-Ke Shih 	}
12721d229e88SPing-Ke Shih 
12731d229e88SPing-Ke Shih 	return ret;
12741d229e88SPing-Ke Shih 
12751d229e88SPing-Ke Shih check_sim:
12761d229e88SPing-Ke Shih 	for (i = 0; i < IQK_NR; i++) {
12771d229e88SPing-Ke Shih 		j = i & ~1;	/* 2 bits are a pair for IQ[X, Y] */
12781d229e88SPing-Ke Shih 		if (bitmap & GENMASK(j + 1, j))
12791d229e88SPing-Ke Shih 			continue;
12801d229e88SPing-Ke Shih 
12811d229e88SPing-Ke Shih 		result[IQK_ROUND_HYBRID][i] = result[c1][i];
12821d229e88SPing-Ke Shih 	}
12831d229e88SPing-Ke Shih 
12841d229e88SPing-Ke Shih 	return false;
12851d229e88SPing-Ke Shih }
12861d229e88SPing-Ke Shih 
12871d229e88SPing-Ke Shih static
12881d229e88SPing-Ke Shih void rtw8723d_iqk_precfg_path(struct rtw_dev *rtwdev, enum rtw8723d_path path)
12891d229e88SPing-Ke Shih {
12901d229e88SPing-Ke Shih 	if (path == PATH_S0) {
12911d229e88SPing-Ke Shih 		rtw8723d_iqk_rf_standby(rtwdev, RF_PATH_A);
12921d229e88SPing-Ke Shih 		rtw8723d_iqk_path_adda_on(rtwdev);
12931d229e88SPing-Ke Shih 	}
12941d229e88SPing-Ke Shih 
12951d229e88SPing-Ke Shih 	rtw_write32_mask(rtwdev, REG_FPGA0_IQK_11N, BIT_MASK_IQK_MOD, EN_IQK);
12961d229e88SPing-Ke Shih 	rtw_write32(rtwdev, REG_TXIQK_11N, 0x01007c00);
12971d229e88SPing-Ke Shih 	rtw_write32(rtwdev, REG_RXIQK_11N, 0x01004800);
12981d229e88SPing-Ke Shih 
12991d229e88SPing-Ke Shih 	if (path == PATH_S1) {
13001d229e88SPing-Ke Shih 		rtw8723d_iqk_rf_standby(rtwdev, RF_PATH_B);
13011d229e88SPing-Ke Shih 		rtw8723d_iqk_path_adda_on(rtwdev);
13021d229e88SPing-Ke Shih 	}
13031d229e88SPing-Ke Shih }
13041d229e88SPing-Ke Shih 
13051d229e88SPing-Ke Shih static
13061d229e88SPing-Ke Shih void rtw8723d_iqk_one_round(struct rtw_dev *rtwdev, s32 result[][IQK_NR], u8 t,
13071d229e88SPing-Ke Shih 			    const struct iqk_backup_regs *backup)
13081d229e88SPing-Ke Shih {
13091d229e88SPing-Ke Shih 	u32 i;
13101d229e88SPing-Ke Shih 	u8 s1_ok, s0_ok;
13111d229e88SPing-Ke Shih 
13121d229e88SPing-Ke Shih 	rtw_dbg(rtwdev, RTW_DBG_RFK,
13131d229e88SPing-Ke Shih 		"[IQK] IQ Calibration for 1T1R_S0/S1 for %d times\n", t);
13141d229e88SPing-Ke Shih 
13151d229e88SPing-Ke Shih 	rtw8723d_iqk_path_adda_on(rtwdev);
13161d229e88SPing-Ke Shih 	rtw8723d_iqk_config_mac(rtwdev);
13171d229e88SPing-Ke Shih 	rtw_write32_mask(rtwdev, REG_CCK_ANT_SEL_11N, 0x0f000000, 0xf);
13181d229e88SPing-Ke Shih 	rtw_write32(rtwdev, REG_BB_RX_PATH_11N, 0x03a05611);
13191d229e88SPing-Ke Shih 	rtw_write32(rtwdev, REG_TRMUX_11N, 0x000800e4);
13201d229e88SPing-Ke Shih 	rtw_write32(rtwdev, REG_BB_PWR_SAV1_11N, 0x25204200);
13211d229e88SPing-Ke Shih 	rtw8723d_iqk_precfg_path(rtwdev, PATH_S1);
13221d229e88SPing-Ke Shih 
13231d229e88SPing-Ke Shih 	for (i = 0; i < PATH_IQK_RETRY; i++) {
13241d229e88SPing-Ke Shih 		s1_ok = rtw8723d_iqk_tx_path(rtwdev, &iqk_tx_cfg[PATH_S1], backup);
13251d229e88SPing-Ke Shih 		if (s1_ok == IQK_TX_OK) {
13261d229e88SPing-Ke Shih 			rtw_dbg(rtwdev, RTW_DBG_RFK,
13271d229e88SPing-Ke Shih 				"[IQK] path S1 Tx IQK Success!!\n");
13281d229e88SPing-Ke Shih 			result[t][IQK_S1_TX_X] =
13291d229e88SPing-Ke Shih 			  rtw_read32_mask(rtwdev, REG_IQK_RES_TX, BIT_MASK_RES_TX);
13301d229e88SPing-Ke Shih 			result[t][IQK_S1_TX_Y] =
13311d229e88SPing-Ke Shih 			  rtw_read32_mask(rtwdev, REG_IQK_RES_TY, BIT_MASK_RES_TY);
13321d229e88SPing-Ke Shih 			break;
13331d229e88SPing-Ke Shih 		}
13341d229e88SPing-Ke Shih 
13351d229e88SPing-Ke Shih 		rtw_dbg(rtwdev, RTW_DBG_RFK, "[IQK] path S1 Tx IQK Fail!!\n");
13361d229e88SPing-Ke Shih 		result[t][IQK_S1_TX_X] = 0x100;
13371d229e88SPing-Ke Shih 		result[t][IQK_S1_TX_Y] = 0x0;
13381d229e88SPing-Ke Shih 	}
13391d229e88SPing-Ke Shih 
13401d229e88SPing-Ke Shih 	for (i = 0; i < PATH_IQK_RETRY; i++) {
13411d229e88SPing-Ke Shih 		s1_ok = rtw8723d_iqk_rx_path(rtwdev, &iqk_tx_cfg[PATH_S1], backup);
13421d229e88SPing-Ke Shih 		if (s1_ok == (IQK_TX_OK | IQK_RX_OK)) {
13431d229e88SPing-Ke Shih 			rtw_dbg(rtwdev, RTW_DBG_RFK,
13441d229e88SPing-Ke Shih 				"[IQK] path S1 Rx IQK Success!!\n");
13451d229e88SPing-Ke Shih 			result[t][IQK_S1_RX_X] =
13461d229e88SPing-Ke Shih 			  rtw_read32_mask(rtwdev, REG_IQK_RES_RX, BIT_MASK_RES_RX);
13471d229e88SPing-Ke Shih 			result[t][IQK_S1_RX_Y] =
13481d229e88SPing-Ke Shih 			  rtw_read32_mask(rtwdev, REG_IQK_RES_RY, BIT_MASK_RES_RY);
13491d229e88SPing-Ke Shih 			break;
13501d229e88SPing-Ke Shih 		}
13511d229e88SPing-Ke Shih 
13521d229e88SPing-Ke Shih 		rtw_dbg(rtwdev, RTW_DBG_RFK, "[IQK] path S1 Rx IQK Fail!!\n");
13531d229e88SPing-Ke Shih 		result[t][IQK_S1_RX_X] = 0x100;
13541d229e88SPing-Ke Shih 		result[t][IQK_S1_RX_Y] = 0x0;
13551d229e88SPing-Ke Shih 	}
13561d229e88SPing-Ke Shih 
13571d229e88SPing-Ke Shih 	if (s1_ok == 0x0)
13581d229e88SPing-Ke Shih 		rtw_dbg(rtwdev, RTW_DBG_RFK, "[IQK] path S1 IQK is failed!!\n");
13591d229e88SPing-Ke Shih 
13601d229e88SPing-Ke Shih 	rtw8723d_iqk_precfg_path(rtwdev, PATH_S0);
13611d229e88SPing-Ke Shih 
13621d229e88SPing-Ke Shih 	for (i = 0; i < PATH_IQK_RETRY; i++) {
13631d229e88SPing-Ke Shih 		s0_ok = rtw8723d_iqk_tx_path(rtwdev, &iqk_tx_cfg[PATH_S0], backup);
13641d229e88SPing-Ke Shih 		if (s0_ok == IQK_TX_OK) {
13651d229e88SPing-Ke Shih 			rtw_dbg(rtwdev, RTW_DBG_RFK,
13661d229e88SPing-Ke Shih 				"[IQK] path S0 Tx IQK Success!!\n");
13671d229e88SPing-Ke Shih 			result[t][IQK_S0_TX_X] =
13681d229e88SPing-Ke Shih 			  rtw_read32_mask(rtwdev, REG_IQK_RES_TX, BIT_MASK_RES_TX);
13691d229e88SPing-Ke Shih 			result[t][IQK_S0_TX_Y] =
13701d229e88SPing-Ke Shih 			  rtw_read32_mask(rtwdev, REG_IQK_RES_TY, BIT_MASK_RES_TY);
13711d229e88SPing-Ke Shih 			break;
13721d229e88SPing-Ke Shih 		}
13731d229e88SPing-Ke Shih 
13741d229e88SPing-Ke Shih 		rtw_dbg(rtwdev, RTW_DBG_RFK, "[IQK] path S0 Tx IQK Fail!!\n");
13751d229e88SPing-Ke Shih 		result[t][IQK_S0_TX_X] = 0x100;
13761d229e88SPing-Ke Shih 		result[t][IQK_S0_TX_Y] = 0x0;
13771d229e88SPing-Ke Shih 	}
13781d229e88SPing-Ke Shih 
13791d229e88SPing-Ke Shih 	for (i = 0; i < PATH_IQK_RETRY; i++) {
13801d229e88SPing-Ke Shih 		s0_ok = rtw8723d_iqk_rx_path(rtwdev, &iqk_tx_cfg[PATH_S0], backup);
13811d229e88SPing-Ke Shih 		if (s0_ok == (IQK_TX_OK | IQK_RX_OK)) {
13821d229e88SPing-Ke Shih 			rtw_dbg(rtwdev, RTW_DBG_RFK,
13831d229e88SPing-Ke Shih 				"[IQK] path S0 Rx IQK Success!!\n");
13841d229e88SPing-Ke Shih 
13851d229e88SPing-Ke Shih 			result[t][IQK_S0_RX_X] =
13861d229e88SPing-Ke Shih 			  rtw_read32_mask(rtwdev, REG_IQK_RES_RX, BIT_MASK_RES_RX);
13871d229e88SPing-Ke Shih 			result[t][IQK_S0_RX_Y] =
13881d229e88SPing-Ke Shih 			  rtw_read32_mask(rtwdev, REG_IQK_RES_RY, BIT_MASK_RES_RY);
13891d229e88SPing-Ke Shih 			break;
13901d229e88SPing-Ke Shih 		}
13911d229e88SPing-Ke Shih 
13921d229e88SPing-Ke Shih 		rtw_dbg(rtwdev, RTW_DBG_RFK, "[IQK] path S0 Rx IQK Fail!!\n");
13931d229e88SPing-Ke Shih 		result[t][IQK_S0_RX_X] = 0x100;
13941d229e88SPing-Ke Shih 		result[t][IQK_S0_RX_Y] = 0x0;
13951d229e88SPing-Ke Shih 	}
13961d229e88SPing-Ke Shih 
13971d229e88SPing-Ke Shih 	if (s0_ok == 0x0)
13981d229e88SPing-Ke Shih 		rtw_dbg(rtwdev, RTW_DBG_RFK, "[IQK] path S0 IQK is failed!!\n");
13991d229e88SPing-Ke Shih 
14001d229e88SPing-Ke Shih 	rtw_write32_mask(rtwdev, REG_FPGA0_IQK_11N, BIT_MASK_IQK_MOD, RST_IQK);
14011d229e88SPing-Ke Shih 	mdelay(1);
14021d229e88SPing-Ke Shih 
14031d229e88SPing-Ke Shih 	rtw_dbg(rtwdev, RTW_DBG_RFK,
14041d229e88SPing-Ke Shih 		"[IQK] back to BB mode, load original value!\n");
14051d229e88SPing-Ke Shih }
14061d229e88SPing-Ke Shih 
14071d229e88SPing-Ke Shih static void rtw8723d_phy_calibration(struct rtw_dev *rtwdev)
14081d229e88SPing-Ke Shih {
14091d229e88SPing-Ke Shih 	struct rtw_dm_info *dm_info = &rtwdev->dm_info;
14101d229e88SPing-Ke Shih 	s32 result[IQK_ROUND_SIZE][IQK_NR];
14111d229e88SPing-Ke Shih 	struct iqk_backup_regs backup;
14121d229e88SPing-Ke Shih 	u8 i, j;
14131d229e88SPing-Ke Shih 	u8 final_candidate = IQK_ROUND_INVALID;
14141d229e88SPing-Ke Shih 	bool good;
14151d229e88SPing-Ke Shih 
14161d229e88SPing-Ke Shih 	rtw_dbg(rtwdev, RTW_DBG_RFK, "[IQK] Start!!!\n");
14171d229e88SPing-Ke Shih 
14181d229e88SPing-Ke Shih 	memset(result, 0, sizeof(result));
14191d229e88SPing-Ke Shih 
14201d229e88SPing-Ke Shih 	rtw8723d_iqk_backup_path_ctrl(rtwdev, &backup);
14211d229e88SPing-Ke Shih 	rtw8723d_iqk_backup_lte_path_gnt(rtwdev, &backup);
14221d229e88SPing-Ke Shih 	rtw8723d_iqk_backup_regs(rtwdev, &backup);
14231d229e88SPing-Ke Shih 
14241d229e88SPing-Ke Shih 	for (i = IQK_ROUND_0; i <= IQK_ROUND_2; i++) {
14251d229e88SPing-Ke Shih 		rtw8723d_iqk_config_path_ctrl(rtwdev);
14261d229e88SPing-Ke Shih 		rtw8723d_iqk_config_lte_path_gnt(rtwdev);
14271d229e88SPing-Ke Shih 
14281d229e88SPing-Ke Shih 		rtw8723d_iqk_one_round(rtwdev, result, i, &backup);
14291d229e88SPing-Ke Shih 
14301d229e88SPing-Ke Shih 		if (i > IQK_ROUND_0)
14311d229e88SPing-Ke Shih 			rtw8723d_iqk_restore_regs(rtwdev, &backup);
14321d229e88SPing-Ke Shih 		rtw8723d_iqk_restore_lte_path_gnt(rtwdev, &backup);
14331d229e88SPing-Ke Shih 		rtw8723d_iqk_restore_path_ctrl(rtwdev, &backup);
14341d229e88SPing-Ke Shih 
14351d229e88SPing-Ke Shih 		for (j = IQK_ROUND_0; j < i; j++) {
14361d229e88SPing-Ke Shih 			good = rtw8723d_iqk_similarity_cmp(rtwdev, result, j, i);
14371d229e88SPing-Ke Shih 
14381d229e88SPing-Ke Shih 			if (good) {
14391d229e88SPing-Ke Shih 				final_candidate = j;
14401d229e88SPing-Ke Shih 				rtw_dbg(rtwdev, RTW_DBG_RFK,
14411d229e88SPing-Ke Shih 					"[IQK] cmp %d:%d final_candidate is %x\n",
14421d229e88SPing-Ke Shih 					j, i, final_candidate);
14431d229e88SPing-Ke Shih 				goto iqk_done;
14441d229e88SPing-Ke Shih 			}
14451d229e88SPing-Ke Shih 		}
14461d229e88SPing-Ke Shih 	}
14471d229e88SPing-Ke Shih 
14481d229e88SPing-Ke Shih 	if (final_candidate == IQK_ROUND_INVALID) {
14491d229e88SPing-Ke Shih 		s32 reg_tmp = 0;
14501d229e88SPing-Ke Shih 
14511d229e88SPing-Ke Shih 		for (i = 0; i < IQK_NR; i++)
14521d229e88SPing-Ke Shih 			reg_tmp += result[IQK_ROUND_HYBRID][i];
14531d229e88SPing-Ke Shih 
14541d229e88SPing-Ke Shih 		if (reg_tmp != 0) {
14551d229e88SPing-Ke Shih 			final_candidate = IQK_ROUND_HYBRID;
14561d229e88SPing-Ke Shih 		} else {
14571d229e88SPing-Ke Shih 			WARN(1, "IQK is failed\n");
14581d229e88SPing-Ke Shih 			goto out;
14591d229e88SPing-Ke Shih 		}
14601d229e88SPing-Ke Shih 	}
14611d229e88SPing-Ke Shih 
14621d229e88SPing-Ke Shih iqk_done:
14631d229e88SPing-Ke Shih 	rtw8723d_iqk_fill_s1_matrix(rtwdev, result[final_candidate]);
14641d229e88SPing-Ke Shih 	rtw8723d_iqk_fill_s0_matrix(rtwdev, result[final_candidate]);
14651d229e88SPing-Ke Shih 
14661d229e88SPing-Ke Shih 	dm_info->iqk.result.s1_x = result[final_candidate][IQK_S1_TX_X];
14671d229e88SPing-Ke Shih 	dm_info->iqk.result.s1_y = result[final_candidate][IQK_S1_TX_Y];
14681d229e88SPing-Ke Shih 	dm_info->iqk.result.s0_x = result[final_candidate][IQK_S0_TX_X];
14691d229e88SPing-Ke Shih 	dm_info->iqk.result.s0_y = result[final_candidate][IQK_S0_TX_Y];
14701d229e88SPing-Ke Shih 	dm_info->iqk.done = true;
14711d229e88SPing-Ke Shih 
14721d229e88SPing-Ke Shih out:
14731d229e88SPing-Ke Shih 	rtw_write32(rtwdev, REG_BB_SEL_BTG, backup.bb_sel_btg);
14741d229e88SPing-Ke Shih 
14751d229e88SPing-Ke Shih 	rtw_dbg(rtwdev, RTW_DBG_RFK, "[IQK] final_candidate is %x\n",
14761d229e88SPing-Ke Shih 		final_candidate);
14771d229e88SPing-Ke Shih 
14781d229e88SPing-Ke Shih 	for (i = IQK_ROUND_0; i < IQK_ROUND_SIZE; i++)
14791d229e88SPing-Ke Shih 		rtw_dbg(rtwdev, RTW_DBG_RFK,
14801d229e88SPing-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",
14811d229e88SPing-Ke Shih 			i,
14821d229e88SPing-Ke Shih 			result[i][0], result[i][1], result[i][2], result[i][3],
14831d229e88SPing-Ke Shih 			result[i][4], result[i][5], result[i][6], result[i][7],
14841d229e88SPing-Ke Shih 			final_candidate == i ? "(final candidate)" : "");
14851d229e88SPing-Ke Shih 
14861d229e88SPing-Ke Shih 	rtw_dbg(rtwdev, RTW_DBG_RFK,
14871d229e88SPing-Ke Shih 		"[IQK]0xc80 = 0x%x 0xc94 = 0x%x 0xc14 = 0x%x 0xca0 = 0x%x\n",
14881d229e88SPing-Ke Shih 		rtw_read32(rtwdev, REG_OFDM_0_XA_TX_IQ_IMBALANCE),
14891d229e88SPing-Ke Shih 		rtw_read32(rtwdev, REG_TXIQK_MATRIXA_LSB2_11N),
14901d229e88SPing-Ke Shih 		rtw_read32(rtwdev, REG_A_RXIQI),
14911d229e88SPing-Ke Shih 		rtw_read32(rtwdev, REG_RXIQK_MATRIX_LSB_11N));
14921d229e88SPing-Ke Shih 	rtw_dbg(rtwdev, RTW_DBG_RFK,
14931d229e88SPing-Ke Shih 		"[IQK]0xcd0 = 0x%x 0xcd4 = 0x%x 0xcd8 = 0x%x\n",
14941d229e88SPing-Ke Shih 		rtw_read32(rtwdev, REG_TXIQ_AB_S0),
14951d229e88SPing-Ke Shih 		rtw_read32(rtwdev, REG_TXIQ_CD_S0),
14961d229e88SPing-Ke Shih 		rtw_read32(rtwdev, REG_RXIQ_AB_S0));
14971d229e88SPing-Ke Shih 
14981d229e88SPing-Ke Shih 	rtw_dbg(rtwdev, RTW_DBG_RFK, "[IQK] finished\n");
14991d229e88SPing-Ke Shih }
15001d229e88SPing-Ke Shih 
1501d1391c49SPing-Ke Shih /* for coex */
1502d1391c49SPing-Ke Shih static void rtw8723d_coex_cfg_init(struct rtw_dev *rtwdev)
1503d1391c49SPing-Ke Shih {
1504d1391c49SPing-Ke Shih 	/* enable TBTT nterrupt */
1505d1391c49SPing-Ke Shih 	rtw_write8_set(rtwdev, REG_BCN_CTRL, BIT_EN_BCN_FUNCTION);
1506d1391c49SPing-Ke Shih 
1507d1391c49SPing-Ke Shih 	/* BT report packet sample rate	 */
1508d1391c49SPing-Ke Shih 	/* 0x790[5:0]=0x5 */
1509d1391c49SPing-Ke Shih 	rtw_write8_set(rtwdev, REG_BT_TDMA_TIME, 0x05);
1510d1391c49SPing-Ke Shih 
1511d1391c49SPing-Ke Shih 	/* enable BT counter statistics */
1512d1391c49SPing-Ke Shih 	rtw_write8(rtwdev, REG_BT_STAT_CTRL, 0x1);
1513d1391c49SPing-Ke Shih 
1514d1391c49SPing-Ke Shih 	/* enable PTA (3-wire function form BT side) */
1515d1391c49SPing-Ke Shih 	rtw_write32_set(rtwdev, REG_GPIO_MUXCFG, BIT_BT_PTA_EN);
1516d1391c49SPing-Ke Shih 	rtw_write32_set(rtwdev, REG_GPIO_MUXCFG, BIT_BT_AOD_GPIO3);
1517d1391c49SPing-Ke Shih 
1518d1391c49SPing-Ke Shih 	/* enable PTA (tx/rx signal form WiFi side) */
1519d1391c49SPing-Ke Shih 	rtw_write8_set(rtwdev, REG_QUEUE_CTRL, BIT_PTA_WL_TX_EN);
1520d1391c49SPing-Ke Shih }
1521d1391c49SPing-Ke Shih 
1522d1391c49SPing-Ke Shih static void rtw8723d_coex_cfg_gnt_fix(struct rtw_dev *rtwdev)
1523d1391c49SPing-Ke Shih {
1524d1391c49SPing-Ke Shih }
1525d1391c49SPing-Ke Shih 
1526d1391c49SPing-Ke Shih static void rtw8723d_coex_cfg_gnt_debug(struct rtw_dev *rtwdev)
1527d1391c49SPing-Ke Shih {
1528d1391c49SPing-Ke Shih 	rtw_write8_mask(rtwdev, REG_LEDCFG2, BIT(6), 0);
1529d1391c49SPing-Ke Shih 	rtw_write8_mask(rtwdev, REG_PAD_CTRL1 + 3, BIT(0), 0);
1530d1391c49SPing-Ke Shih 	rtw_write8_mask(rtwdev, REG_GPIO_INTM + 2, BIT(4), 0);
1531d1391c49SPing-Ke Shih 	rtw_write8_mask(rtwdev, REG_GPIO_MUXCFG + 2, BIT(1), 0);
1532d1391c49SPing-Ke Shih 	rtw_write8_mask(rtwdev, REG_PAD_CTRL1 + 3, BIT(1), 0);
1533d1391c49SPing-Ke Shih 	rtw_write8_mask(rtwdev, REG_PAD_CTRL1 + 2, BIT(7), 0);
1534d1391c49SPing-Ke Shih 	rtw_write8_mask(rtwdev, REG_SYS_CLKR + 1, BIT(1), 0);
1535d1391c49SPing-Ke Shih 	rtw_write8_mask(rtwdev, REG_SYS_SDIO_CTRL + 3, BIT(3), 0);
1536d1391c49SPing-Ke Shih }
1537d1391c49SPing-Ke Shih 
1538d1391c49SPing-Ke Shih static void rtw8723d_coex_cfg_rfe_type(struct rtw_dev *rtwdev)
1539d1391c49SPing-Ke Shih {
1540d1391c49SPing-Ke Shih 	struct rtw_efuse *efuse = &rtwdev->efuse;
1541d1391c49SPing-Ke Shih 	struct rtw_coex *coex = &rtwdev->coex;
1542d1391c49SPing-Ke Shih 	struct rtw_coex_rfe *coex_rfe = &coex->rfe;
1543d1391c49SPing-Ke Shih 	bool aux = efuse->bt_setting & BIT(6);
1544d1391c49SPing-Ke Shih 
1545d1391c49SPing-Ke Shih 	coex_rfe->rfe_module_type = rtwdev->efuse.rfe_option;
1546d1391c49SPing-Ke Shih 	coex_rfe->ant_switch_polarity = 0;
1547d1391c49SPing-Ke Shih 	coex_rfe->ant_switch_exist = false;
1548d1391c49SPing-Ke Shih 	coex_rfe->ant_switch_with_bt = false;
1549d1391c49SPing-Ke Shih 	coex_rfe->ant_switch_diversity = false;
1550d1391c49SPing-Ke Shih 	coex_rfe->wlg_at_btg = true;
1551d1391c49SPing-Ke Shih 
1552d1391c49SPing-Ke Shih 	/* decide antenna at main or aux */
1553d1391c49SPing-Ke Shih 	if (efuse->share_ant) {
1554d1391c49SPing-Ke Shih 		if (aux)
1555d1391c49SPing-Ke Shih 			rtw_write16(rtwdev, REG_BB_SEL_BTG, 0x80);
1556d1391c49SPing-Ke Shih 		else
1557d1391c49SPing-Ke Shih 			rtw_write16(rtwdev, REG_BB_SEL_BTG, 0x200);
1558d1391c49SPing-Ke Shih 	} else {
1559d1391c49SPing-Ke Shih 		if (aux)
1560d1391c49SPing-Ke Shih 			rtw_write16(rtwdev, REG_BB_SEL_BTG, 0x280);
1561d1391c49SPing-Ke Shih 		else
1562d1391c49SPing-Ke Shih 			rtw_write16(rtwdev, REG_BB_SEL_BTG, 0x0);
1563d1391c49SPing-Ke Shih 	}
1564d1391c49SPing-Ke Shih 
1565d1391c49SPing-Ke Shih 	/* disable LTE coex in wifi side */
1566d1391c49SPing-Ke Shih 	rtw_coex_write_indirect_reg(rtwdev, LTE_COEX_CTRL, BIT_LTE_COEX_EN, 0x0);
1567d1391c49SPing-Ke Shih 	rtw_coex_write_indirect_reg(rtwdev, LTE_WL_TRX_CTRL, MASKLWORD, 0xffff);
1568d1391c49SPing-Ke Shih 	rtw_coex_write_indirect_reg(rtwdev, LTE_BT_TRX_CTRL, MASKLWORD, 0xffff);
1569d1391c49SPing-Ke Shih }
1570d1391c49SPing-Ke Shih 
1571d1391c49SPing-Ke Shih static void rtw8723d_coex_cfg_wl_tx_power(struct rtw_dev *rtwdev, u8 wl_pwr)
1572d1391c49SPing-Ke Shih {
1573d1391c49SPing-Ke Shih 	struct rtw_coex *coex = &rtwdev->coex;
1574d1391c49SPing-Ke Shih 	struct rtw_coex_dm *coex_dm = &coex->dm;
1575d1391c49SPing-Ke Shih 	static const u8	wl_tx_power[] = {0xb2, 0x90};
1576d1391c49SPing-Ke Shih 	u8 pwr;
1577d1391c49SPing-Ke Shih 
1578d1391c49SPing-Ke Shih 	if (wl_pwr == coex_dm->cur_wl_pwr_lvl)
1579d1391c49SPing-Ke Shih 		return;
1580d1391c49SPing-Ke Shih 
1581d1391c49SPing-Ke Shih 	coex_dm->cur_wl_pwr_lvl = wl_pwr;
1582d1391c49SPing-Ke Shih 
1583d1391c49SPing-Ke Shih 	if (coex_dm->cur_wl_pwr_lvl >= ARRAY_SIZE(wl_tx_power))
1584d1391c49SPing-Ke Shih 		coex_dm->cur_wl_pwr_lvl = ARRAY_SIZE(wl_tx_power) - 1;
1585d1391c49SPing-Ke Shih 
1586d1391c49SPing-Ke Shih 	pwr = wl_tx_power[coex_dm->cur_wl_pwr_lvl];
1587d1391c49SPing-Ke Shih 
1588d1391c49SPing-Ke Shih 	rtw_write8(rtwdev, REG_ANA_PARAM1 + 3, pwr);
1589d1391c49SPing-Ke Shih }
1590d1391c49SPing-Ke Shih 
1591d1391c49SPing-Ke Shih static void rtw8723d_coex_cfg_wl_rx_gain(struct rtw_dev *rtwdev, bool low_gain)
1592d1391c49SPing-Ke Shih {
1593d1391c49SPing-Ke Shih 	struct rtw_coex *coex = &rtwdev->coex;
1594d1391c49SPing-Ke Shih 	struct rtw_coex_dm *coex_dm = &coex->dm;
1595d1391c49SPing-Ke Shih 	/* WL Rx Low gain on */
1596d1391c49SPing-Ke Shih 	static const u32 wl_rx_low_gain_on[] = {
1597d1391c49SPing-Ke Shih 		0xec120101, 0xeb130101, 0xce140101, 0xcd150101, 0xcc160101,
1598d1391c49SPing-Ke Shih 		0xcb170101, 0xca180101, 0x8d190101, 0x8c1a0101, 0x8b1b0101,
1599d1391c49SPing-Ke Shih 		0x4f1c0101, 0x4e1d0101, 0x4d1e0101, 0x4c1f0101, 0x0e200101,
1600d1391c49SPing-Ke Shih 		0x0d210101, 0x0c220101, 0x0b230101, 0xcf240001, 0xce250001,
1601d1391c49SPing-Ke Shih 		0xcd260001, 0xcc270001, 0x8f280001
1602d1391c49SPing-Ke Shih 	};
1603d1391c49SPing-Ke Shih 	/* WL Rx Low gain off */
1604d1391c49SPing-Ke Shih 	static const u32 wl_rx_low_gain_off[] = {
1605d1391c49SPing-Ke Shih 		0xec120101, 0xeb130101, 0xea140101, 0xe9150101, 0xe8160101,
1606d1391c49SPing-Ke Shih 		0xe7170101, 0xe6180101, 0xe5190101, 0xe41a0101, 0xe31b0101,
1607d1391c49SPing-Ke Shih 		0xe21c0101, 0xe11d0101, 0xe01e0101, 0x861f0101, 0x85200101,
1608d1391c49SPing-Ke Shih 		0x84210101, 0x83220101, 0x82230101, 0x81240101, 0x80250101,
1609d1391c49SPing-Ke Shih 		0x44260101, 0x43270101, 0x42280101
1610d1391c49SPing-Ke Shih 	};
1611d1391c49SPing-Ke Shih 	u8 i;
1612d1391c49SPing-Ke Shih 
1613d1391c49SPing-Ke Shih 	if (low_gain == coex_dm->cur_wl_rx_low_gain_en)
1614d1391c49SPing-Ke Shih 		return;
1615d1391c49SPing-Ke Shih 
1616d1391c49SPing-Ke Shih 	coex_dm->cur_wl_rx_low_gain_en = low_gain;
1617d1391c49SPing-Ke Shih 
1618d1391c49SPing-Ke Shih 	if (coex_dm->cur_wl_rx_low_gain_en) {
1619d1391c49SPing-Ke Shih 		for (i = 0; i < ARRAY_SIZE(wl_rx_low_gain_on); i++)
1620d1391c49SPing-Ke Shih 			rtw_write32(rtwdev, REG_AGCRSSI, wl_rx_low_gain_on[i]);
1621d1391c49SPing-Ke Shih 	} else {
1622d1391c49SPing-Ke Shih 		for (i = 0; i < ARRAY_SIZE(wl_rx_low_gain_off); i++)
1623d1391c49SPing-Ke Shih 			rtw_write32(rtwdev, REG_AGCRSSI, wl_rx_low_gain_off[i]);
1624d1391c49SPing-Ke Shih 	}
1625d1391c49SPing-Ke Shih }
1626d1391c49SPing-Ke Shih 
1627608d2a08SPing-Ke Shih static u8 rtw8723d_pwrtrack_get_limit_ofdm(struct rtw_dev *rtwdev)
1628608d2a08SPing-Ke Shih {
1629608d2a08SPing-Ke Shih 	struct rtw_dm_info *dm_info = &rtwdev->dm_info;
1630608d2a08SPing-Ke Shih 	u8 tx_rate = dm_info->tx_rate;
1631608d2a08SPing-Ke Shih 	u8 limit_ofdm = 30;
1632608d2a08SPing-Ke Shih 
1633608d2a08SPing-Ke Shih 	switch (tx_rate) {
1634608d2a08SPing-Ke Shih 	case DESC_RATE1M...DESC_RATE5_5M:
1635608d2a08SPing-Ke Shih 	case DESC_RATE11M:
1636608d2a08SPing-Ke Shih 		break;
1637608d2a08SPing-Ke Shih 	case DESC_RATE6M...DESC_RATE48M:
1638608d2a08SPing-Ke Shih 		limit_ofdm = 36;
1639608d2a08SPing-Ke Shih 		break;
1640608d2a08SPing-Ke Shih 	case DESC_RATE54M:
1641608d2a08SPing-Ke Shih 		limit_ofdm = 34;
1642608d2a08SPing-Ke Shih 		break;
1643608d2a08SPing-Ke Shih 	case DESC_RATEMCS0...DESC_RATEMCS2:
1644608d2a08SPing-Ke Shih 		limit_ofdm = 38;
1645608d2a08SPing-Ke Shih 		break;
1646608d2a08SPing-Ke Shih 	case DESC_RATEMCS3...DESC_RATEMCS4:
1647608d2a08SPing-Ke Shih 		limit_ofdm = 36;
1648608d2a08SPing-Ke Shih 		break;
1649608d2a08SPing-Ke Shih 	case DESC_RATEMCS5...DESC_RATEMCS7:
1650608d2a08SPing-Ke Shih 		limit_ofdm = 34;
1651608d2a08SPing-Ke Shih 		break;
1652608d2a08SPing-Ke Shih 	default:
1653608d2a08SPing-Ke Shih 		rtw_warn(rtwdev, "pwrtrack unhandled tx_rate 0x%x\n", tx_rate);
1654608d2a08SPing-Ke Shih 		break;
1655608d2a08SPing-Ke Shih 	}
1656608d2a08SPing-Ke Shih 
1657608d2a08SPing-Ke Shih 	return limit_ofdm;
1658608d2a08SPing-Ke Shih }
1659608d2a08SPing-Ke Shih 
1660608d2a08SPing-Ke Shih static void rtw8723d_set_iqk_matrix_by_result(struct rtw_dev *rtwdev,
1661608d2a08SPing-Ke Shih 					      u32 ofdm_swing, u8 rf_path)
1662608d2a08SPing-Ke Shih {
1663608d2a08SPing-Ke Shih 	struct rtw_dm_info *dm_info = &rtwdev->dm_info;
1664608d2a08SPing-Ke Shih 	s32 ele_A, ele_D, ele_C;
1665608d2a08SPing-Ke Shih 	s32 ele_A_ext, ele_C_ext, ele_D_ext;
1666608d2a08SPing-Ke Shih 	s32 iqk_result_x;
1667608d2a08SPing-Ke Shih 	s32 iqk_result_y;
1668608d2a08SPing-Ke Shih 	s32 value32;
1669608d2a08SPing-Ke Shih 
1670608d2a08SPing-Ke Shih 	switch (rf_path) {
1671608d2a08SPing-Ke Shih 	default:
1672608d2a08SPing-Ke Shih 	case RF_PATH_A:
1673608d2a08SPing-Ke Shih 		iqk_result_x = dm_info->iqk.result.s1_x;
1674608d2a08SPing-Ke Shih 		iqk_result_y = dm_info->iqk.result.s1_y;
1675608d2a08SPing-Ke Shih 		break;
1676608d2a08SPing-Ke Shih 	case RF_PATH_B:
1677608d2a08SPing-Ke Shih 		iqk_result_x = dm_info->iqk.result.s0_x;
1678608d2a08SPing-Ke Shih 		iqk_result_y = dm_info->iqk.result.s0_y;
1679608d2a08SPing-Ke Shih 		break;
1680608d2a08SPing-Ke Shih 	}
1681608d2a08SPing-Ke Shih 
1682608d2a08SPing-Ke Shih 	/* new element D */
1683608d2a08SPing-Ke Shih 	ele_D = OFDM_SWING_D(ofdm_swing);
1684608d2a08SPing-Ke Shih 	iqk_mult(iqk_result_x, ele_D, &ele_D_ext);
1685608d2a08SPing-Ke Shih 	/* new element A */
1686608d2a08SPing-Ke Shih 	iqk_result_x = iqkxy_to_s32(iqk_result_x);
1687608d2a08SPing-Ke Shih 	ele_A = iqk_mult(iqk_result_x, ele_D, &ele_A_ext);
1688608d2a08SPing-Ke Shih 	/* new element C */
1689608d2a08SPing-Ke Shih 	iqk_result_y = iqkxy_to_s32(iqk_result_y);
1690608d2a08SPing-Ke Shih 	ele_C = iqk_mult(iqk_result_y, ele_D, &ele_C_ext);
1691608d2a08SPing-Ke Shih 
1692608d2a08SPing-Ke Shih 	switch (rf_path) {
1693608d2a08SPing-Ke Shih 	case RF_PATH_A:
1694608d2a08SPing-Ke Shih 	default:
1695608d2a08SPing-Ke Shih 		/* write new elements A, C, D, and element B is always 0 */
1696608d2a08SPing-Ke Shih 		value32 = BIT_SET_TXIQ_ELM_ACD(ele_A, ele_C, ele_D);
1697608d2a08SPing-Ke Shih 		rtw_write32(rtwdev, REG_OFDM_0_XA_TX_IQ_IMBALANCE, value32);
1698608d2a08SPing-Ke Shih 		value32 = BIT_SET_TXIQ_ELM_C1(ele_C);
1699608d2a08SPing-Ke Shih 		rtw_write32_mask(rtwdev, REG_TXIQK_MATRIXA_LSB2_11N, MASKH4BITS,
1700608d2a08SPing-Ke Shih 				 value32);
1701608d2a08SPing-Ke Shih 		value32 = rtw_read32(rtwdev, REG_OFDM_0_ECCA_THRESHOLD);
1702608d2a08SPing-Ke Shih 		value32 &= ~BIT_MASK_OFDM0_EXTS;
1703608d2a08SPing-Ke Shih 		value32 |= BIT_SET_OFDM0_EXTS(ele_A_ext, ele_C_ext, ele_D_ext);
1704608d2a08SPing-Ke Shih 		rtw_write32(rtwdev, REG_OFDM_0_ECCA_THRESHOLD, value32);
1705608d2a08SPing-Ke Shih 		break;
1706608d2a08SPing-Ke Shih 
1707608d2a08SPing-Ke Shih 	case RF_PATH_B:
1708608d2a08SPing-Ke Shih 		/* write new elements A, C, D, and element B is always 0 */
1709608d2a08SPing-Ke Shih 		rtw_write32_mask(rtwdev, REG_TXIQ_CD_S0, BIT_MASK_TXIQ_D_S0, ele_D);
1710608d2a08SPing-Ke Shih 		rtw_write32_mask(rtwdev, REG_TXIQ_CD_S0, BIT_MASK_TXIQ_C_S0, ele_C);
1711608d2a08SPing-Ke Shih 		rtw_write32_mask(rtwdev, REG_TXIQ_AB_S0, BIT_MASK_TXIQ_A_S0, ele_A);
1712608d2a08SPing-Ke Shih 
1713608d2a08SPing-Ke Shih 		rtw_write32_mask(rtwdev, REG_TXIQ_CD_S0, BIT_MASK_TXIQ_D_EXT_S0,
1714608d2a08SPing-Ke Shih 				 ele_D_ext);
1715608d2a08SPing-Ke Shih 		rtw_write32_mask(rtwdev, REG_TXIQ_AB_S0, BIT_MASK_TXIQ_A_EXT_S0,
1716608d2a08SPing-Ke Shih 				 ele_A_ext);
1717608d2a08SPing-Ke Shih 		rtw_write32_mask(rtwdev, REG_TXIQ_CD_S0, BIT_MASK_TXIQ_C_EXT_S0,
1718608d2a08SPing-Ke Shih 				 ele_C_ext);
1719608d2a08SPing-Ke Shih 		break;
1720608d2a08SPing-Ke Shih 	}
1721608d2a08SPing-Ke Shih }
1722608d2a08SPing-Ke Shih 
1723608d2a08SPing-Ke Shih static void rtw8723d_set_iqk_matrix(struct rtw_dev *rtwdev, s8 ofdm_index,
1724608d2a08SPing-Ke Shih 				    u8 rf_path)
1725608d2a08SPing-Ke Shih {
1726608d2a08SPing-Ke Shih 	struct rtw_dm_info *dm_info = &rtwdev->dm_info;
1727608d2a08SPing-Ke Shih 	s32 value32;
1728608d2a08SPing-Ke Shih 	u32 ofdm_swing;
1729608d2a08SPing-Ke Shih 
1730608d2a08SPing-Ke Shih 	if (ofdm_index >= RTW_OFDM_SWING_TABLE_SIZE)
1731608d2a08SPing-Ke Shih 		ofdm_index = RTW_OFDM_SWING_TABLE_SIZE - 1;
1732608d2a08SPing-Ke Shih 	else if (ofdm_index < 0)
1733608d2a08SPing-Ke Shih 		ofdm_index = 0;
1734608d2a08SPing-Ke Shih 
1735608d2a08SPing-Ke Shih 	ofdm_swing = rtw8723d_ofdm_swing_table[ofdm_index];
1736608d2a08SPing-Ke Shih 
1737608d2a08SPing-Ke Shih 	if (dm_info->iqk.done) {
1738608d2a08SPing-Ke Shih 		rtw8723d_set_iqk_matrix_by_result(rtwdev, ofdm_swing, rf_path);
1739608d2a08SPing-Ke Shih 		return;
1740608d2a08SPing-Ke Shih 	}
1741608d2a08SPing-Ke Shih 
1742608d2a08SPing-Ke Shih 	switch (rf_path) {
1743608d2a08SPing-Ke Shih 	case RF_PATH_A:
1744608d2a08SPing-Ke Shih 	default:
1745608d2a08SPing-Ke Shih 		rtw_write32(rtwdev, REG_OFDM_0_XA_TX_IQ_IMBALANCE, ofdm_swing);
1746608d2a08SPing-Ke Shih 		rtw_write32_mask(rtwdev, REG_TXIQK_MATRIXA_LSB2_11N, MASKH4BITS,
1747608d2a08SPing-Ke Shih 				 0x00);
1748608d2a08SPing-Ke Shih 		value32 = rtw_read32(rtwdev, REG_OFDM_0_ECCA_THRESHOLD);
1749608d2a08SPing-Ke Shih 		value32 &= ~BIT_MASK_OFDM0_EXTS;
1750608d2a08SPing-Ke Shih 		rtw_write32(rtwdev, REG_OFDM_0_ECCA_THRESHOLD, value32);
1751608d2a08SPing-Ke Shih 		break;
1752608d2a08SPing-Ke Shih 
1753608d2a08SPing-Ke Shih 	case RF_PATH_B:
1754608d2a08SPing-Ke Shih 		/* image S1:c80 to S0:Cd0 and Cd4 */
1755608d2a08SPing-Ke Shih 		rtw_write32_mask(rtwdev, REG_TXIQ_AB_S0, BIT_MASK_TXIQ_A_S0,
1756608d2a08SPing-Ke Shih 				 OFDM_SWING_A(ofdm_swing));
1757608d2a08SPing-Ke Shih 		rtw_write32_mask(rtwdev, REG_TXIQ_AB_S0, BIT_MASK_TXIQ_B_S0,
1758608d2a08SPing-Ke Shih 				 OFDM_SWING_B(ofdm_swing));
1759608d2a08SPing-Ke Shih 		rtw_write32_mask(rtwdev, REG_TXIQ_CD_S0, BIT_MASK_TXIQ_C_S0,
1760608d2a08SPing-Ke Shih 				 OFDM_SWING_C(ofdm_swing));
1761608d2a08SPing-Ke Shih 		rtw_write32_mask(rtwdev, REG_TXIQ_CD_S0, BIT_MASK_TXIQ_D_S0,
1762608d2a08SPing-Ke Shih 				 OFDM_SWING_D(ofdm_swing));
1763608d2a08SPing-Ke Shih 		rtw_write32_mask(rtwdev, REG_TXIQ_CD_S0, BIT_MASK_TXIQ_D_EXT_S0, 0x0);
1764608d2a08SPing-Ke Shih 		rtw_write32_mask(rtwdev, REG_TXIQ_CD_S0, BIT_MASK_TXIQ_C_EXT_S0, 0x0);
1765608d2a08SPing-Ke Shih 		rtw_write32_mask(rtwdev, REG_TXIQ_AB_S0, BIT_MASK_TXIQ_A_EXT_S0, 0x0);
1766608d2a08SPing-Ke Shih 		break;
1767608d2a08SPing-Ke Shih 	}
1768608d2a08SPing-Ke Shih }
1769608d2a08SPing-Ke Shih 
1770608d2a08SPing-Ke Shih static void rtw8723d_pwrtrack_set_ofdm_pwr(struct rtw_dev *rtwdev, s8 swing_idx,
1771608d2a08SPing-Ke Shih 					   s8 txagc_idx)
1772608d2a08SPing-Ke Shih {
1773608d2a08SPing-Ke Shih 	struct rtw_dm_info *dm_info = &rtwdev->dm_info;
1774608d2a08SPing-Ke Shih 
1775608d2a08SPing-Ke Shih 	dm_info->txagc_remnant_ofdm = txagc_idx;
1776608d2a08SPing-Ke Shih 
1777608d2a08SPing-Ke Shih 	rtw8723d_set_iqk_matrix(rtwdev, swing_idx, RF_PATH_A);
1778608d2a08SPing-Ke Shih 	rtw8723d_set_iqk_matrix(rtwdev, swing_idx, RF_PATH_B);
1779608d2a08SPing-Ke Shih }
1780608d2a08SPing-Ke Shih 
1781608d2a08SPing-Ke Shih static void rtw8723d_pwrtrack_set_cck_pwr(struct rtw_dev *rtwdev, s8 swing_idx,
1782608d2a08SPing-Ke Shih 					  s8 txagc_idx)
1783608d2a08SPing-Ke Shih {
1784608d2a08SPing-Ke Shih 	struct rtw_dm_info *dm_info = &rtwdev->dm_info;
1785608d2a08SPing-Ke Shih 
1786608d2a08SPing-Ke Shih 	dm_info->txagc_remnant_cck = txagc_idx;
1787608d2a08SPing-Ke Shih 
1788608d2a08SPing-Ke Shih 	rtw_write32_mask(rtwdev, 0xab4, 0x000007FF,
1789608d2a08SPing-Ke Shih 			 rtw8723d_cck_swing_table[swing_idx]);
1790608d2a08SPing-Ke Shih }
1791608d2a08SPing-Ke Shih 
1792608d2a08SPing-Ke Shih static void rtw8723d_pwrtrack_set(struct rtw_dev *rtwdev, u8 path)
1793608d2a08SPing-Ke Shih {
1794608d2a08SPing-Ke Shih 	struct rtw_dm_info *dm_info = &rtwdev->dm_info;
1795608d2a08SPing-Ke Shih 	struct rtw_hal *hal = &rtwdev->hal;
1796608d2a08SPing-Ke Shih 	u8 limit_ofdm;
1797608d2a08SPing-Ke Shih 	u8 limit_cck = 40;
1798608d2a08SPing-Ke Shih 	s8 final_ofdm_swing_index;
1799608d2a08SPing-Ke Shih 	s8 final_cck_swing_index;
1800608d2a08SPing-Ke Shih 
1801608d2a08SPing-Ke Shih 	limit_ofdm = rtw8723d_pwrtrack_get_limit_ofdm(rtwdev);
1802608d2a08SPing-Ke Shih 
1803608d2a08SPing-Ke Shih 	final_ofdm_swing_index = RTW_DEF_OFDM_SWING_INDEX +
1804608d2a08SPing-Ke Shih 				 dm_info->delta_power_index[path];
1805608d2a08SPing-Ke Shih 	final_cck_swing_index = RTW_DEF_CCK_SWING_INDEX +
1806608d2a08SPing-Ke Shih 				dm_info->delta_power_index[path];
1807608d2a08SPing-Ke Shih 
1808608d2a08SPing-Ke Shih 	if (final_ofdm_swing_index > limit_ofdm)
1809608d2a08SPing-Ke Shih 		rtw8723d_pwrtrack_set_ofdm_pwr(rtwdev, limit_ofdm,
1810608d2a08SPing-Ke Shih 					       final_ofdm_swing_index - limit_ofdm);
1811608d2a08SPing-Ke Shih 	else if (final_ofdm_swing_index < 0)
1812608d2a08SPing-Ke Shih 		rtw8723d_pwrtrack_set_ofdm_pwr(rtwdev, 0,
1813608d2a08SPing-Ke Shih 					       final_ofdm_swing_index);
1814608d2a08SPing-Ke Shih 	else
1815608d2a08SPing-Ke Shih 		rtw8723d_pwrtrack_set_ofdm_pwr(rtwdev, final_ofdm_swing_index, 0);
1816608d2a08SPing-Ke Shih 
1817608d2a08SPing-Ke Shih 	if (final_cck_swing_index > limit_cck)
1818608d2a08SPing-Ke Shih 		rtw8723d_pwrtrack_set_cck_pwr(rtwdev, limit_cck,
1819608d2a08SPing-Ke Shih 					      final_cck_swing_index - limit_cck);
1820608d2a08SPing-Ke Shih 	else if (final_cck_swing_index < 0)
1821608d2a08SPing-Ke Shih 		rtw8723d_pwrtrack_set_cck_pwr(rtwdev, 0,
1822608d2a08SPing-Ke Shih 					      final_cck_swing_index);
1823608d2a08SPing-Ke Shih 	else
1824608d2a08SPing-Ke Shih 		rtw8723d_pwrtrack_set_cck_pwr(rtwdev, final_cck_swing_index, 0);
1825608d2a08SPing-Ke Shih 
1826608d2a08SPing-Ke Shih 	rtw_phy_set_tx_power_level(rtwdev, hal->current_channel);
1827608d2a08SPing-Ke Shih }
1828608d2a08SPing-Ke Shih 
1829608d2a08SPing-Ke Shih static void rtw8723d_pwrtrack_set_xtal(struct rtw_dev *rtwdev, u8 therm_path,
1830608d2a08SPing-Ke Shih 				       u8 delta)
1831608d2a08SPing-Ke Shih {
1832608d2a08SPing-Ke Shih 	struct rtw_dm_info *dm_info = &rtwdev->dm_info;
1833608d2a08SPing-Ke Shih 	const struct rtw_pwr_track_tbl *tbl = rtwdev->chip->pwr_track_tbl;
1834608d2a08SPing-Ke Shih 	const s8 *pwrtrk_xtal;
1835608d2a08SPing-Ke Shih 	s8 xtal_cap;
1836608d2a08SPing-Ke Shih 
1837608d2a08SPing-Ke Shih 	if (dm_info->thermal_avg[therm_path] >
1838608d2a08SPing-Ke Shih 	    rtwdev->efuse.thermal_meter[therm_path])
1839608d2a08SPing-Ke Shih 		pwrtrk_xtal = tbl->pwrtrk_xtal_p;
1840608d2a08SPing-Ke Shih 	else
1841608d2a08SPing-Ke Shih 		pwrtrk_xtal = tbl->pwrtrk_xtal_n;
1842608d2a08SPing-Ke Shih 
1843608d2a08SPing-Ke Shih 	xtal_cap = rtwdev->efuse.crystal_cap & 0x3F;
1844608d2a08SPing-Ke Shih 	xtal_cap = clamp_t(s8, xtal_cap + pwrtrk_xtal[delta], 0, 0x3F);
1845608d2a08SPing-Ke Shih 	rtw_write32_mask(rtwdev, REG_AFE_CTRL3, BIT_MASK_XTAL,
1846608d2a08SPing-Ke Shih 			 xtal_cap | (xtal_cap << 6));
1847608d2a08SPing-Ke Shih }
1848608d2a08SPing-Ke Shih 
1849608d2a08SPing-Ke Shih static void rtw8723d_phy_pwrtrack(struct rtw_dev *rtwdev)
1850608d2a08SPing-Ke Shih {
1851608d2a08SPing-Ke Shih 	struct rtw_dm_info *dm_info = &rtwdev->dm_info;
1852608d2a08SPing-Ke Shih 	struct rtw_swing_table swing_table;
1853608d2a08SPing-Ke Shih 	u8 thermal_value, delta, path;
1854608d2a08SPing-Ke Shih 	bool do_iqk = false;
1855608d2a08SPing-Ke Shih 
1856608d2a08SPing-Ke Shih 	rtw_phy_config_swing_table(rtwdev, &swing_table);
1857608d2a08SPing-Ke Shih 
1858608d2a08SPing-Ke Shih 	if (rtwdev->efuse.thermal_meter[0] == 0xff)
1859608d2a08SPing-Ke Shih 		return;
1860608d2a08SPing-Ke Shih 
1861608d2a08SPing-Ke Shih 	thermal_value = rtw_read_rf(rtwdev, RF_PATH_A, RF_T_METER, 0xfc00);
1862608d2a08SPing-Ke Shih 
1863608d2a08SPing-Ke Shih 	rtw_phy_pwrtrack_avg(rtwdev, thermal_value, RF_PATH_A);
1864608d2a08SPing-Ke Shih 
1865608d2a08SPing-Ke Shih 	do_iqk = rtw_phy_pwrtrack_need_iqk(rtwdev);
1866608d2a08SPing-Ke Shih 
1867608d2a08SPing-Ke Shih 	if (do_iqk)
1868608d2a08SPing-Ke Shih 		rtw8723d_lck(rtwdev);
1869608d2a08SPing-Ke Shih 
1870608d2a08SPing-Ke Shih 	if (dm_info->pwr_trk_init_trigger)
1871608d2a08SPing-Ke Shih 		dm_info->pwr_trk_init_trigger = false;
1872608d2a08SPing-Ke Shih 	else if (!rtw_phy_pwrtrack_thermal_changed(rtwdev, thermal_value,
1873608d2a08SPing-Ke Shih 						   RF_PATH_A))
1874608d2a08SPing-Ke Shih 		goto iqk;
1875608d2a08SPing-Ke Shih 
1876608d2a08SPing-Ke Shih 	delta = rtw_phy_pwrtrack_get_delta(rtwdev, RF_PATH_A);
1877608d2a08SPing-Ke Shih 
1878608d2a08SPing-Ke Shih 	delta = min_t(u8, delta, RTW_PWR_TRK_TBL_SZ - 1);
1879608d2a08SPing-Ke Shih 
1880608d2a08SPing-Ke Shih 	for (path = 0; path < rtwdev->hal.rf_path_num; path++) {
1881608d2a08SPing-Ke Shih 		s8 delta_cur, delta_last;
1882608d2a08SPing-Ke Shih 
1883608d2a08SPing-Ke Shih 		delta_last = dm_info->delta_power_index[path];
1884608d2a08SPing-Ke Shih 		delta_cur = rtw_phy_pwrtrack_get_pwridx(rtwdev, &swing_table,
1885608d2a08SPing-Ke Shih 							path, RF_PATH_A, delta);
1886608d2a08SPing-Ke Shih 		if (delta_last == delta_cur)
1887608d2a08SPing-Ke Shih 			continue;
1888608d2a08SPing-Ke Shih 
1889608d2a08SPing-Ke Shih 		dm_info->delta_power_index[path] = delta_cur;
1890608d2a08SPing-Ke Shih 		rtw8723d_pwrtrack_set(rtwdev, path);
1891608d2a08SPing-Ke Shih 	}
1892608d2a08SPing-Ke Shih 
1893608d2a08SPing-Ke Shih 	rtw8723d_pwrtrack_set_xtal(rtwdev, RF_PATH_A, delta);
1894608d2a08SPing-Ke Shih 
1895608d2a08SPing-Ke Shih iqk:
1896608d2a08SPing-Ke Shih 	if (do_iqk)
1897608d2a08SPing-Ke Shih 		rtw8723d_phy_calibration(rtwdev);
1898608d2a08SPing-Ke Shih }
1899608d2a08SPing-Ke Shih 
19000c440238SYan-Hsuan Chuang static void rtw8723d_pwr_track(struct rtw_dev *rtwdev)
1901608d2a08SPing-Ke Shih {
1902608d2a08SPing-Ke Shih 	struct rtw_efuse *efuse = &rtwdev->efuse;
1903608d2a08SPing-Ke Shih 	struct rtw_dm_info *dm_info = &rtwdev->dm_info;
1904608d2a08SPing-Ke Shih 
1905608d2a08SPing-Ke Shih 	if (efuse->power_track_type != 0)
1906608d2a08SPing-Ke Shih 		return;
1907608d2a08SPing-Ke Shih 
1908608d2a08SPing-Ke Shih 	if (!dm_info->pwr_trk_triggered) {
1909608d2a08SPing-Ke Shih 		rtw_write_rf(rtwdev, RF_PATH_A, RF_T_METER,
1910608d2a08SPing-Ke Shih 			     GENMASK(17, 16), 0x03);
1911608d2a08SPing-Ke Shih 		dm_info->pwr_trk_triggered = true;
1912608d2a08SPing-Ke Shih 		return;
1913608d2a08SPing-Ke Shih 	}
1914608d2a08SPing-Ke Shih 
1915608d2a08SPing-Ke Shih 	rtw8723d_phy_pwrtrack(rtwdev);
1916608d2a08SPing-Ke Shih 	dm_info->pwr_trk_triggered = false;
1917608d2a08SPing-Ke Shih }
1918608d2a08SPing-Ke Shih 
1919811853daSPing-Ke Shih static struct rtw_chip_ops rtw8723d_ops = {
192075e69fb1SPing-Ke Shih 	.phy_set_param		= rtw8723d_phy_set_param,
1921ab0a031eSPing-Ke Shih 	.read_efuse		= rtw8723d_read_efuse,
1922158441a2SPing-Ke Shih 	.query_rx_desc		= rtw8723d_query_rx_desc,
19235f028a9cSPing-Ke Shih 	.set_channel		= rtw8723d_set_channel,
192475e69fb1SPing-Ke Shih 	.mac_init		= rtw8723d_mac_init,
192505202746SPing-Ke Shih 	.shutdown		= rtw8723d_shutdown,
1926e0c27cdbSPing-Ke Shih 	.read_rf		= rtw_phy_read_rf_sipi,
1927e0c27cdbSPing-Ke Shih 	.write_rf		= rtw_phy_write_rf_reg_sipi,
1928ba9f0d1bSPing-Ke Shih 	.set_tx_power_index	= rtw8723d_set_tx_power_index,
1929811853daSPing-Ke Shih 	.set_antenna		= NULL,
19301afb5eb7SPing-Ke Shih 	.cfg_ldo25		= rtw8723d_cfg_ldo25,
193144baa97cSPing-Ke Shih 	.efuse_grant		= rtw8723d_efuse_grant,
1932439d4a97SPing-Ke Shih 	.false_alarm_statistics	= rtw8723d_false_alarm_statistics,
19331d229e88SPing-Ke Shih 	.phy_calibration	= rtw8723d_phy_calibration,
1934608d2a08SPing-Ke Shih 	.pwr_track		= rtw8723d_pwr_track,
193593ae973fSPing-Ke Shih 	.config_bfee		= NULL,
193693ae973fSPing-Ke Shih 	.set_gid_table		= NULL,
193793ae973fSPing-Ke Shih 	.cfg_csi_rate		= NULL,
1938d1391c49SPing-Ke Shih 
1939d1391c49SPing-Ke Shih 	.coex_set_init		= rtw8723d_coex_cfg_init,
1940d1391c49SPing-Ke Shih 	.coex_set_ant_switch	= NULL,
1941d1391c49SPing-Ke Shih 	.coex_set_gnt_fix	= rtw8723d_coex_cfg_gnt_fix,
1942d1391c49SPing-Ke Shih 	.coex_set_gnt_debug	= rtw8723d_coex_cfg_gnt_debug,
1943d1391c49SPing-Ke Shih 	.coex_set_rfe_type	= rtw8723d_coex_cfg_rfe_type,
1944d1391c49SPing-Ke Shih 	.coex_set_wl_tx_power	= rtw8723d_coex_cfg_wl_tx_power,
1945d1391c49SPing-Ke Shih 	.coex_set_wl_rx_gain	= rtw8723d_coex_cfg_wl_rx_gain,
1946d1391c49SPing-Ke Shih };
1947d1391c49SPing-Ke Shih 
1948d1391c49SPing-Ke Shih /* Shared-Antenna Coex Table */
1949d1391c49SPing-Ke Shih static const struct coex_table_para table_sant_8723d[] = {
1950d1391c49SPing-Ke Shih 	{0xffffffff, 0xffffffff}, /* case-0 */
1951d1391c49SPing-Ke Shih 	{0x55555555, 0x55555555},
1952d1391c49SPing-Ke Shih 	{0x65555555, 0x65555555},
1953d1391c49SPing-Ke Shih 	{0xaaaaaaaa, 0xaaaaaaaa},
1954d1391c49SPing-Ke Shih 	{0x5a5a5a5a, 0x5a5a5a5a},
1955d1391c49SPing-Ke Shih 	{0xfafafafa, 0xfafafafa}, /* case-5 */
1956d1391c49SPing-Ke Shih 	{0xa5555555, 0xaaaa5aaa},
1957d1391c49SPing-Ke Shih 	{0x6a5a5a5a, 0x5a5a5a5a},
1958d1391c49SPing-Ke Shih 	{0x6a5a5a5a, 0x6a5a5a5a},
1959d1391c49SPing-Ke Shih 	{0x65555555, 0x5a5a5a5a},
1960d1391c49SPing-Ke Shih 	{0x65555555, 0x6a5a5a5a}, /* case-10 */
1961d1391c49SPing-Ke Shih 	{0x65555555, 0xfafafafa},
1962d1391c49SPing-Ke Shih 	{0x65555555, 0x6a5a5aaa},
1963d1391c49SPing-Ke Shih 	{0x65555555, 0x5aaa5aaa},
1964d1391c49SPing-Ke Shih 	{0x65555555, 0xaaaa5aaa},
1965d1391c49SPing-Ke Shih 	{0x65555555, 0xaaaaaaaa}, /* case-15 */
1966d1391c49SPing-Ke Shih 	{0xffff55ff, 0xfafafafa},
1967d1391c49SPing-Ke Shih 	{0xffff55ff, 0x6afa5afa},
1968d1391c49SPing-Ke Shih 	{0xaaffffaa, 0xfafafafa},
1969d1391c49SPing-Ke Shih 	{0xaa5555aa, 0x5a5a5a5a},
1970d1391c49SPing-Ke Shih 	{0xaa5555aa, 0x6a5a5a5a}, /* case-20 */
1971d1391c49SPing-Ke Shih 	{0xaa5555aa, 0xaaaaaaaa},
1972d1391c49SPing-Ke Shih 	{0xffffffff, 0x5a5a5a5a},
1973d1391c49SPing-Ke Shih 	{0xffffffff, 0x6a5a5a5a},
1974d1391c49SPing-Ke Shih 	{0xffffffff, 0x55555555},
1975d1391c49SPing-Ke Shih 	{0xffffffff, 0x6a5a5aaa}, /* case-25 */
1976d1391c49SPing-Ke Shih 	{0x55555555, 0x5a5a5a5a},
1977d1391c49SPing-Ke Shih 	{0x55555555, 0xaaaaaaaa},
1978d1391c49SPing-Ke Shih 	{0x55555555, 0x6a6a6a6a},
1979d1391c49SPing-Ke Shih 	{0x656a656a, 0x656a656a}
1980d1391c49SPing-Ke Shih };
1981d1391c49SPing-Ke Shih 
1982d1391c49SPing-Ke Shih /* Non-Shared-Antenna Coex Table */
1983d1391c49SPing-Ke Shih static const struct coex_table_para table_nsant_8723d[] = {
1984d1391c49SPing-Ke Shih 	{0xffffffff, 0xffffffff}, /* case-100 */
1985d1391c49SPing-Ke Shih 	{0x55555555, 0x55555555},
1986d1391c49SPing-Ke Shih 	{0x65555555, 0x65555555},
1987d1391c49SPing-Ke Shih 	{0xaaaaaaaa, 0xaaaaaaaa},
1988d1391c49SPing-Ke Shih 	{0x5a5a5a5a, 0x5a5a5a5a},
1989d1391c49SPing-Ke Shih 	{0xfafafafa, 0xfafafafa}, /* case-105 */
1990d1391c49SPing-Ke Shih 	{0x5afa5afa, 0x5afa5afa},
1991d1391c49SPing-Ke Shih 	{0x55555555, 0xfafafafa},
1992d1391c49SPing-Ke Shih 	{0x65555555, 0xfafafafa},
1993d1391c49SPing-Ke Shih 	{0x65555555, 0x5a5a5a5a},
1994d1391c49SPing-Ke Shih 	{0x65555555, 0x6a5a5a5a}, /* case-110 */
1995d1391c49SPing-Ke Shih 	{0x65555555, 0xaaaaaaaa},
1996d1391c49SPing-Ke Shih 	{0xffff55ff, 0xfafafafa},
1997d1391c49SPing-Ke Shih 	{0xffff55ff, 0x5afa5afa},
1998d1391c49SPing-Ke Shih 	{0xffff55ff, 0xaaaaaaaa},
1999d1391c49SPing-Ke Shih 	{0xaaffffaa, 0xfafafafa}, /* case-115 */
2000d1391c49SPing-Ke Shih 	{0xaaffffaa, 0x5afa5afa},
2001d1391c49SPing-Ke Shih 	{0xaaffffaa, 0xaaaaaaaa},
2002d1391c49SPing-Ke Shih 	{0xffffffff, 0xfafafafa},
2003d1391c49SPing-Ke Shih 	{0xffffffff, 0x5afa5afa},
2004d1391c49SPing-Ke Shih 	{0xffffffff, 0xaaaaaaaa},/* case-120 */
2005d1391c49SPing-Ke Shih 	{0x55ff55ff, 0x5afa5afa},
2006d1391c49SPing-Ke Shih 	{0x55ff55ff, 0xaaaaaaaa},
2007d1391c49SPing-Ke Shih 	{0x55ff55ff, 0x55ff55ff}
2008d1391c49SPing-Ke Shih };
2009d1391c49SPing-Ke Shih 
2010d1391c49SPing-Ke Shih /* Shared-Antenna TDMA */
2011d1391c49SPing-Ke Shih static const struct coex_tdma_para tdma_sant_8723d[] = {
2012d1391c49SPing-Ke Shih 	{ {0x08, 0x00, 0x00, 0x00, 0x00} }, /* case-0 */
2013d1391c49SPing-Ke Shih 	{ {0x61, 0x45, 0x03, 0x11, 0x11} }, /* case-1 */
2014d1391c49SPing-Ke Shih 	{ {0x61, 0x3a, 0x03, 0x11, 0x11} },
2015d1391c49SPing-Ke Shih 	{ {0x61, 0x20, 0x03, 0x11, 0x11} },
2016d1391c49SPing-Ke Shih 	{ {0x61, 0x30, 0x03, 0x11, 0x11} },
2017d1391c49SPing-Ke Shih 	{ {0x61, 0x10, 0x03, 0x11, 0x11} }, /* case-5 */
2018d1391c49SPing-Ke Shih 	{ {0x61, 0x48, 0x03, 0x11, 0x10} },
2019d1391c49SPing-Ke Shih 	{ {0x61, 0x3a, 0x03, 0x11, 0x10} },
2020d1391c49SPing-Ke Shih 	{ {0x61, 0x30, 0x03, 0x11, 0x10} },
2021d1391c49SPing-Ke Shih 	{ {0x61, 0x20, 0x03, 0x11, 0x10} },
2022d1391c49SPing-Ke Shih 	{ {0x61, 0x10, 0x03, 0x11, 0x10} }, /* case-10 */
2023d1391c49SPing-Ke Shih 	{ {0x61, 0x10, 0x03, 0x11, 0x14} },
2024d1391c49SPing-Ke Shih 	{ {0x61, 0x08, 0x03, 0x10, 0x14} },
2025d1391c49SPing-Ke Shih 	{ {0x51, 0x10, 0x03, 0x10, 0x54} },
2026d1391c49SPing-Ke Shih 	{ {0x51, 0x10, 0x03, 0x10, 0x55} },
2027d1391c49SPing-Ke Shih 	{ {0x51, 0x10, 0x07, 0x10, 0x54} }, /* case-15 */
2028d1391c49SPing-Ke Shih 	{ {0x51, 0x45, 0x03, 0x10, 0x50} },
2029d1391c49SPing-Ke Shih 	{ {0x51, 0x3a, 0x03, 0x10, 0x50} },
2030d1391c49SPing-Ke Shih 	{ {0x51, 0x30, 0x03, 0x10, 0x50} },
2031d1391c49SPing-Ke Shih 	{ {0x51, 0x20, 0x03, 0x10, 0x50} },
2032d1391c49SPing-Ke Shih 	{ {0x51, 0x15, 0x03, 0x10, 0x50} }, /* case-20 */
2033d1391c49SPing-Ke Shih 	{ {0x51, 0x4a, 0x03, 0x10, 0x50} },
2034d1391c49SPing-Ke Shih 	{ {0x51, 0x0c, 0x03, 0x10, 0x54} },
2035d1391c49SPing-Ke Shih 	{ {0x55, 0x08, 0x03, 0x10, 0x54} },
2036d1391c49SPing-Ke Shih 	{ {0x65, 0x10, 0x03, 0x11, 0x11} },
2037d1391c49SPing-Ke Shih 	{ {0x51, 0x10, 0x03, 0x10, 0x51} },
2038d1391c49SPing-Ke Shih 	{ {0x61, 0x15, 0x03, 0x11, 0x10} }
2039d1391c49SPing-Ke Shih };
2040d1391c49SPing-Ke Shih 
2041d1391c49SPing-Ke Shih /* Non-Shared-Antenna TDMA */
2042d1391c49SPing-Ke Shih static const struct coex_tdma_para tdma_nsant_8723d[] = {
2043d1391c49SPing-Ke Shih 	{ {0x00, 0x00, 0x00, 0x40, 0x00} }, /* case-100 */
2044d1391c49SPing-Ke Shih 	{ {0x61, 0x45, 0x03, 0x11, 0x11} }, /* case-101 */
2045d1391c49SPing-Ke Shih 	{ {0x61, 0x3a, 0x03, 0x11, 0x11} },
2046d1391c49SPing-Ke Shih 	{ {0x61, 0x30, 0x03, 0x11, 0x11} },
2047d1391c49SPing-Ke Shih 	{ {0x61, 0x20, 0x03, 0x11, 0x11} },
2048d1391c49SPing-Ke Shih 	{ {0x61, 0x10, 0x03, 0x11, 0x11} }, /* case-105 */
2049d1391c49SPing-Ke Shih 	{ {0x61, 0x45, 0x03, 0x11, 0x10} },
2050d1391c49SPing-Ke Shih 	{ {0x61, 0x3a, 0x03, 0x11, 0x10} },
2051d1391c49SPing-Ke Shih 	{ {0x61, 0x30, 0x03, 0x11, 0x10} },
2052d1391c49SPing-Ke Shih 	{ {0x61, 0x20, 0x03, 0x11, 0x10} },
2053d1391c49SPing-Ke Shih 	{ {0x61, 0x10, 0x03, 0x11, 0x10} }, /* case-110 */
2054d1391c49SPing-Ke Shih 	{ {0x61, 0x08, 0x03, 0x11, 0x14} },
2055d1391c49SPing-Ke Shih 	{ {0x61, 0x08, 0x03, 0x10, 0x14} },
2056d1391c49SPing-Ke Shih 	{ {0x51, 0x08, 0x03, 0x10, 0x54} },
2057d1391c49SPing-Ke Shih 	{ {0x51, 0x08, 0x03, 0x10, 0x55} },
2058d1391c49SPing-Ke Shih 	{ {0x51, 0x08, 0x07, 0x10, 0x54} }, /* case-115 */
2059d1391c49SPing-Ke Shih 	{ {0x51, 0x45, 0x03, 0x10, 0x50} },
2060d1391c49SPing-Ke Shih 	{ {0x51, 0x3a, 0x03, 0x10, 0x50} },
2061d1391c49SPing-Ke Shih 	{ {0x51, 0x30, 0x03, 0x10, 0x50} },
2062d1391c49SPing-Ke Shih 	{ {0x51, 0x20, 0x03, 0x10, 0x50} },
2063d1391c49SPing-Ke Shih 	{ {0x51, 0x10, 0x03, 0x10, 0x50} }
2064d1391c49SPing-Ke Shih };
2065d1391c49SPing-Ke Shih 
2066d1391c49SPing-Ke Shih /* rssi in percentage % (dbm = % - 100) */
2067d1391c49SPing-Ke Shih static const u8 wl_rssi_step_8723d[] = {60, 50, 44, 30};
2068d1391c49SPing-Ke Shih static const u8 bt_rssi_step_8723d[] = {30, 30, 30, 30};
2069d1391c49SPing-Ke Shih static const struct coex_5g_afh_map afh_5g_8723d[] = { {0, 0, 0} };
2070d1391c49SPing-Ke Shih 
2071d1391c49SPing-Ke Shih /* wl_tx_dec_power, bt_tx_dec_power, wl_rx_gain, bt_rx_lna_constrain */
2072d1391c49SPing-Ke Shih static const struct coex_rf_para rf_para_tx_8723d[] = {
2073d1391c49SPing-Ke Shih 	{0, 0, false, 7},  /* for normal */
2074d1391c49SPing-Ke Shih 	{0, 10, false, 7}, /* for WL-CPT */
2075d1391c49SPing-Ke Shih 	{1, 0, true, 4},
2076d1391c49SPing-Ke Shih 	{1, 2, true, 4},
2077d1391c49SPing-Ke Shih 	{1, 10, true, 4},
2078d1391c49SPing-Ke Shih 	{1, 15, true, 4}
2079d1391c49SPing-Ke Shih };
2080d1391c49SPing-Ke Shih 
2081d1391c49SPing-Ke Shih static const struct coex_rf_para rf_para_rx_8723d[] = {
2082d1391c49SPing-Ke Shih 	{0, 0, false, 7},  /* for normal */
2083d1391c49SPing-Ke Shih 	{0, 10, false, 7}, /* for WL-CPT */
2084d1391c49SPing-Ke Shih 	{1, 0, true, 5},
2085d1391c49SPing-Ke Shih 	{1, 2, true, 5},
2086d1391c49SPing-Ke Shih 	{1, 10, true, 5},
2087d1391c49SPing-Ke Shih 	{1, 15, true, 5}
2088811853daSPing-Ke Shih };
2089811853daSPing-Ke Shih 
2090c57bd7c3SPing-Ke Shih static const struct rtw_pwr_seq_cmd trans_carddis_to_cardemu_8723d[] = {
2091c57bd7c3SPing-Ke Shih 	{0x0005,
2092c57bd7c3SPing-Ke Shih 	 RTW_PWR_CUT_ALL_MSK,
2093c57bd7c3SPing-Ke Shih 	 RTW_PWR_INTF_ALL_MSK,
2094c57bd7c3SPing-Ke Shih 	 RTW_PWR_ADDR_MAC,
2095c57bd7c3SPing-Ke Shih 	 RTW_PWR_CMD_WRITE, BIT(3) | BIT(7), 0},
2096c57bd7c3SPing-Ke Shih 	{0x0086,
2097c57bd7c3SPing-Ke Shih 	 RTW_PWR_CUT_ALL_MSK,
2098c57bd7c3SPing-Ke Shih 	 RTW_PWR_INTF_SDIO_MSK,
2099c57bd7c3SPing-Ke Shih 	 RTW_PWR_ADDR_SDIO,
2100c57bd7c3SPing-Ke Shih 	 RTW_PWR_CMD_WRITE, BIT(0), 0},
2101c57bd7c3SPing-Ke Shih 	{0x0086,
2102c57bd7c3SPing-Ke Shih 	 RTW_PWR_CUT_ALL_MSK,
2103c57bd7c3SPing-Ke Shih 	 RTW_PWR_INTF_SDIO_MSK,
2104c57bd7c3SPing-Ke Shih 	 RTW_PWR_ADDR_SDIO,
2105c57bd7c3SPing-Ke Shih 	 RTW_PWR_CMD_POLLING, BIT(1), BIT(1)},
2106c57bd7c3SPing-Ke Shih 	{0x004A,
2107c57bd7c3SPing-Ke Shih 	 RTW_PWR_CUT_ALL_MSK,
2108c57bd7c3SPing-Ke Shih 	 RTW_PWR_INTF_USB_MSK,
2109c57bd7c3SPing-Ke Shih 	 RTW_PWR_ADDR_MAC,
2110c57bd7c3SPing-Ke Shih 	 RTW_PWR_CMD_WRITE, BIT(0), 0},
2111c57bd7c3SPing-Ke Shih 	{0x0005,
2112c57bd7c3SPing-Ke Shih 	 RTW_PWR_CUT_ALL_MSK,
2113c57bd7c3SPing-Ke Shih 	 RTW_PWR_INTF_ALL_MSK,
2114c57bd7c3SPing-Ke Shih 	 RTW_PWR_ADDR_MAC,
2115c57bd7c3SPing-Ke Shih 	 RTW_PWR_CMD_WRITE, BIT(3) | BIT(4), 0},
2116c57bd7c3SPing-Ke Shih 	{0x0023,
2117c57bd7c3SPing-Ke Shih 	 RTW_PWR_CUT_ALL_MSK,
2118c57bd7c3SPing-Ke Shih 	 RTW_PWR_INTF_SDIO_MSK,
2119c57bd7c3SPing-Ke Shih 	 RTW_PWR_ADDR_MAC,
2120c57bd7c3SPing-Ke Shih 	 RTW_PWR_CMD_WRITE, BIT(4), 0},
2121c57bd7c3SPing-Ke Shih 	{0x0301,
2122c57bd7c3SPing-Ke Shih 	 RTW_PWR_CUT_ALL_MSK,
2123c57bd7c3SPing-Ke Shih 	 RTW_PWR_INTF_PCI_MSK,
2124c57bd7c3SPing-Ke Shih 	 RTW_PWR_ADDR_MAC,
2125c57bd7c3SPing-Ke Shih 	 RTW_PWR_CMD_WRITE, 0xFF, 0},
2126c57bd7c3SPing-Ke Shih 	{0xFFFF,
2127c57bd7c3SPing-Ke Shih 	 RTW_PWR_CUT_ALL_MSK,
2128c57bd7c3SPing-Ke Shih 	 RTW_PWR_INTF_ALL_MSK,
2129c57bd7c3SPing-Ke Shih 	 0,
2130c57bd7c3SPing-Ke Shih 	 RTW_PWR_CMD_END, 0, 0},
2131c57bd7c3SPing-Ke Shih };
2132c57bd7c3SPing-Ke Shih 
2133c57bd7c3SPing-Ke Shih static const struct rtw_pwr_seq_cmd trans_cardemu_to_act_8723d[] = {
2134c57bd7c3SPing-Ke Shih 	{0x0020,
2135c57bd7c3SPing-Ke Shih 	 RTW_PWR_CUT_ALL_MSK,
2136c57bd7c3SPing-Ke Shih 	 RTW_PWR_INTF_USB_MSK | RTW_PWR_INTF_SDIO_MSK,
2137c57bd7c3SPing-Ke Shih 	 RTW_PWR_ADDR_MAC,
2138c57bd7c3SPing-Ke Shih 	 RTW_PWR_CMD_WRITE, BIT(0), BIT(0)},
2139c57bd7c3SPing-Ke Shih 	{0x0001,
2140c57bd7c3SPing-Ke Shih 	 RTW_PWR_CUT_ALL_MSK,
2141c57bd7c3SPing-Ke Shih 	 RTW_PWR_INTF_USB_MSK | RTW_PWR_INTF_SDIO_MSK,
2142c57bd7c3SPing-Ke Shih 	 RTW_PWR_ADDR_MAC,
2143c57bd7c3SPing-Ke Shih 	 RTW_PWR_CMD_DELAY, 1, RTW_PWR_DELAY_MS},
2144c57bd7c3SPing-Ke Shih 	{0x0000,
2145c57bd7c3SPing-Ke Shih 	 RTW_PWR_CUT_ALL_MSK,
2146c57bd7c3SPing-Ke Shih 	 RTW_PWR_INTF_USB_MSK | RTW_PWR_INTF_SDIO_MSK,
2147c57bd7c3SPing-Ke Shih 	 RTW_PWR_ADDR_MAC,
2148c57bd7c3SPing-Ke Shih 	 RTW_PWR_CMD_WRITE, BIT(5), 0},
2149c57bd7c3SPing-Ke Shih 	{0x0005,
2150c57bd7c3SPing-Ke Shih 	 RTW_PWR_CUT_ALL_MSK,
2151c57bd7c3SPing-Ke Shih 	 RTW_PWR_INTF_ALL_MSK,
2152c57bd7c3SPing-Ke Shih 	 RTW_PWR_ADDR_MAC,
2153c57bd7c3SPing-Ke Shih 	 RTW_PWR_CMD_WRITE, (BIT(4) | BIT(3) | BIT(2)), 0},
2154c57bd7c3SPing-Ke Shih 	{0x0075,
2155c57bd7c3SPing-Ke Shih 	 RTW_PWR_CUT_ALL_MSK,
2156c57bd7c3SPing-Ke Shih 	 RTW_PWR_INTF_PCI_MSK,
2157c57bd7c3SPing-Ke Shih 	 RTW_PWR_ADDR_MAC,
2158c57bd7c3SPing-Ke Shih 	 RTW_PWR_CMD_WRITE, BIT(0), BIT(0)},
2159c57bd7c3SPing-Ke Shih 	{0x0006,
2160c57bd7c3SPing-Ke Shih 	 RTW_PWR_CUT_ALL_MSK,
2161c57bd7c3SPing-Ke Shih 	 RTW_PWR_INTF_ALL_MSK,
2162c57bd7c3SPing-Ke Shih 	 RTW_PWR_ADDR_MAC,
2163c57bd7c3SPing-Ke Shih 	 RTW_PWR_CMD_POLLING, BIT(1), BIT(1)},
2164c57bd7c3SPing-Ke Shih 	{0x0075,
2165c57bd7c3SPing-Ke Shih 	 RTW_PWR_CUT_ALL_MSK,
2166c57bd7c3SPing-Ke Shih 	 RTW_PWR_INTF_PCI_MSK,
2167c57bd7c3SPing-Ke Shih 	 RTW_PWR_ADDR_MAC,
2168c57bd7c3SPing-Ke Shih 	 RTW_PWR_CMD_WRITE, BIT(0), 0},
2169c57bd7c3SPing-Ke Shih 	{0x0006,
2170c57bd7c3SPing-Ke Shih 	 RTW_PWR_CUT_ALL_MSK,
2171c57bd7c3SPing-Ke Shih 	 RTW_PWR_INTF_ALL_MSK,
2172c57bd7c3SPing-Ke Shih 	 RTW_PWR_ADDR_MAC,
2173c57bd7c3SPing-Ke Shih 	 RTW_PWR_CMD_WRITE, BIT(0), BIT(0)},
2174c57bd7c3SPing-Ke Shih 	{0x0005,
2175c57bd7c3SPing-Ke Shih 	 RTW_PWR_CUT_ALL_MSK,
2176c57bd7c3SPing-Ke Shih 	 RTW_PWR_INTF_ALL_MSK,
2177c57bd7c3SPing-Ke Shih 	 RTW_PWR_ADDR_MAC,
2178c57bd7c3SPing-Ke Shih 	 RTW_PWR_CMD_POLLING, (BIT(1) | BIT(0)), 0},
2179c57bd7c3SPing-Ke Shih 	{0x0005,
2180c57bd7c3SPing-Ke Shih 	 RTW_PWR_CUT_ALL_MSK,
2181c57bd7c3SPing-Ke Shih 	 RTW_PWR_INTF_ALL_MSK,
2182c57bd7c3SPing-Ke Shih 	 RTW_PWR_ADDR_MAC,
2183c57bd7c3SPing-Ke Shih 	 RTW_PWR_CMD_WRITE, BIT(7), 0},
2184c57bd7c3SPing-Ke Shih 	{0x0005,
2185c57bd7c3SPing-Ke Shih 	 RTW_PWR_CUT_ALL_MSK,
2186c57bd7c3SPing-Ke Shih 	 RTW_PWR_INTF_ALL_MSK,
2187c57bd7c3SPing-Ke Shih 	 RTW_PWR_ADDR_MAC,
2188c57bd7c3SPing-Ke Shih 	 RTW_PWR_CMD_WRITE, (BIT(4) | BIT(3)), 0},
2189c57bd7c3SPing-Ke Shih 	{0x0005,
2190c57bd7c3SPing-Ke Shih 	 RTW_PWR_CUT_ALL_MSK,
2191c57bd7c3SPing-Ke Shih 	 RTW_PWR_INTF_ALL_MSK,
2192c57bd7c3SPing-Ke Shih 	 RTW_PWR_ADDR_MAC,
2193c57bd7c3SPing-Ke Shih 	 RTW_PWR_CMD_WRITE, BIT(0), BIT(0)},
2194c57bd7c3SPing-Ke Shih 	{0x0005,
2195c57bd7c3SPing-Ke Shih 	 RTW_PWR_CUT_ALL_MSK,
2196c57bd7c3SPing-Ke Shih 	 RTW_PWR_INTF_ALL_MSK,
2197c57bd7c3SPing-Ke Shih 	 RTW_PWR_ADDR_MAC,
2198c57bd7c3SPing-Ke Shih 	 RTW_PWR_CMD_POLLING, BIT(0), 0},
2199c57bd7c3SPing-Ke Shih 	{0x0010,
2200c57bd7c3SPing-Ke Shih 	 RTW_PWR_CUT_ALL_MSK,
2201c57bd7c3SPing-Ke Shih 	 RTW_PWR_INTF_ALL_MSK,
2202c57bd7c3SPing-Ke Shih 	 RTW_PWR_ADDR_MAC,
2203c57bd7c3SPing-Ke Shih 	 RTW_PWR_CMD_WRITE, BIT(6), BIT(6)},
2204c57bd7c3SPing-Ke Shih 	{0x0049,
2205c57bd7c3SPing-Ke Shih 	 RTW_PWR_CUT_ALL_MSK,
2206c57bd7c3SPing-Ke Shih 	 RTW_PWR_INTF_ALL_MSK,
2207c57bd7c3SPing-Ke Shih 	 RTW_PWR_ADDR_MAC,
2208c57bd7c3SPing-Ke Shih 	 RTW_PWR_CMD_WRITE, BIT(1), BIT(1)},
2209c57bd7c3SPing-Ke Shih 	{0x0063,
2210c57bd7c3SPing-Ke Shih 	 RTW_PWR_CUT_ALL_MSK,
2211c57bd7c3SPing-Ke Shih 	 RTW_PWR_INTF_ALL_MSK,
2212c57bd7c3SPing-Ke Shih 	 RTW_PWR_ADDR_MAC,
2213c57bd7c3SPing-Ke Shih 	 RTW_PWR_CMD_WRITE, BIT(1), BIT(1)},
2214c57bd7c3SPing-Ke Shih 	{0x0062,
2215c57bd7c3SPing-Ke Shih 	 RTW_PWR_CUT_ALL_MSK,
2216c57bd7c3SPing-Ke Shih 	 RTW_PWR_INTF_ALL_MSK,
2217c57bd7c3SPing-Ke Shih 	 RTW_PWR_ADDR_MAC,
2218c57bd7c3SPing-Ke Shih 	 RTW_PWR_CMD_WRITE, BIT(1), 0},
2219c57bd7c3SPing-Ke Shih 	{0x0058,
2220c57bd7c3SPing-Ke Shih 	 RTW_PWR_CUT_ALL_MSK,
2221c57bd7c3SPing-Ke Shih 	 RTW_PWR_INTF_ALL_MSK,
2222c57bd7c3SPing-Ke Shih 	 RTW_PWR_ADDR_MAC,
2223c57bd7c3SPing-Ke Shih 	 RTW_PWR_CMD_WRITE, BIT(0), BIT(0)},
2224c57bd7c3SPing-Ke Shih 	{0x005A,
2225c57bd7c3SPing-Ke Shih 	 RTW_PWR_CUT_ALL_MSK,
2226c57bd7c3SPing-Ke Shih 	 RTW_PWR_INTF_ALL_MSK,
2227c57bd7c3SPing-Ke Shih 	 RTW_PWR_ADDR_MAC,
2228c57bd7c3SPing-Ke Shih 	 RTW_PWR_CMD_WRITE, BIT(1), BIT(1)},
2229c57bd7c3SPing-Ke Shih 	{0x0068,
2230c57bd7c3SPing-Ke Shih 	 RTW_PWR_CUT_TEST_MSK,
2231c57bd7c3SPing-Ke Shih 	 RTW_PWR_INTF_ALL_MSK,
2232c57bd7c3SPing-Ke Shih 	 RTW_PWR_ADDR_MAC,
2233c57bd7c3SPing-Ke Shih 	 RTW_PWR_CMD_WRITE, BIT(3), BIT(3)},
2234c57bd7c3SPing-Ke Shih 	{0x0069,
2235c57bd7c3SPing-Ke Shih 	 RTW_PWR_CUT_ALL_MSK,
2236c57bd7c3SPing-Ke Shih 	 RTW_PWR_INTF_ALL_MSK,
2237c57bd7c3SPing-Ke Shih 	 RTW_PWR_ADDR_MAC,
2238c57bd7c3SPing-Ke Shih 	 RTW_PWR_CMD_WRITE, BIT(6), BIT(6)},
2239c57bd7c3SPing-Ke Shih 	{0x001f,
2240c57bd7c3SPing-Ke Shih 	 RTW_PWR_CUT_ALL_MSK,
2241c57bd7c3SPing-Ke Shih 	 RTW_PWR_INTF_ALL_MSK,
2242c57bd7c3SPing-Ke Shih 	 RTW_PWR_ADDR_MAC,
2243c57bd7c3SPing-Ke Shih 	 RTW_PWR_CMD_WRITE, 0xFF, 0x00},
2244c57bd7c3SPing-Ke Shih 	{0x0077,
2245c57bd7c3SPing-Ke Shih 	 RTW_PWR_CUT_ALL_MSK,
2246c57bd7c3SPing-Ke Shih 	 RTW_PWR_INTF_ALL_MSK,
2247c57bd7c3SPing-Ke Shih 	 RTW_PWR_ADDR_MAC,
2248c57bd7c3SPing-Ke Shih 	 RTW_PWR_CMD_WRITE, 0xFF, 0x00},
2249c57bd7c3SPing-Ke Shih 	{0x001f,
2250c57bd7c3SPing-Ke Shih 	 RTW_PWR_CUT_ALL_MSK,
2251c57bd7c3SPing-Ke Shih 	 RTW_PWR_INTF_ALL_MSK,
2252c57bd7c3SPing-Ke Shih 	 RTW_PWR_ADDR_MAC,
2253c57bd7c3SPing-Ke Shih 	 RTW_PWR_CMD_WRITE, 0xFF, 0x07},
2254c57bd7c3SPing-Ke Shih 	{0x0077,
2255c57bd7c3SPing-Ke Shih 	 RTW_PWR_CUT_ALL_MSK,
2256c57bd7c3SPing-Ke Shih 	 RTW_PWR_INTF_ALL_MSK,
2257c57bd7c3SPing-Ke Shih 	 RTW_PWR_ADDR_MAC,
2258c57bd7c3SPing-Ke Shih 	 RTW_PWR_CMD_WRITE, 0xFF, 0x07},
2259c57bd7c3SPing-Ke Shih 	{0xFFFF,
2260c57bd7c3SPing-Ke Shih 	 RTW_PWR_CUT_ALL_MSK,
2261c57bd7c3SPing-Ke Shih 	 RTW_PWR_INTF_ALL_MSK,
2262c57bd7c3SPing-Ke Shih 	 0,
2263c57bd7c3SPing-Ke Shih 	 RTW_PWR_CMD_END, 0, 0},
2264c57bd7c3SPing-Ke Shih };
2265c57bd7c3SPing-Ke Shih 
2266c57bd7c3SPing-Ke Shih static const struct rtw_pwr_seq_cmd *card_enable_flow_8723d[] = {
2267c57bd7c3SPing-Ke Shih 	trans_carddis_to_cardemu_8723d,
2268c57bd7c3SPing-Ke Shih 	trans_cardemu_to_act_8723d,
2269c57bd7c3SPing-Ke Shih 	NULL
2270c57bd7c3SPing-Ke Shih };
2271c57bd7c3SPing-Ke Shih 
2272c57bd7c3SPing-Ke Shih static const struct rtw_pwr_seq_cmd trans_act_to_lps_8723d[] = {
2273c57bd7c3SPing-Ke Shih 	{0x0301,
2274c57bd7c3SPing-Ke Shih 	 RTW_PWR_CUT_ALL_MSK,
2275c57bd7c3SPing-Ke Shih 	 RTW_PWR_INTF_PCI_MSK,
2276c57bd7c3SPing-Ke Shih 	 RTW_PWR_ADDR_MAC,
2277c57bd7c3SPing-Ke Shih 	 RTW_PWR_CMD_WRITE, 0xFF, 0xFF},
2278c57bd7c3SPing-Ke Shih 	{0x0522,
2279c57bd7c3SPing-Ke Shih 	 RTW_PWR_CUT_ALL_MSK,
2280c57bd7c3SPing-Ke Shih 	 RTW_PWR_INTF_ALL_MSK,
2281c57bd7c3SPing-Ke Shih 	 RTW_PWR_ADDR_MAC,
2282c57bd7c3SPing-Ke Shih 	 RTW_PWR_CMD_WRITE, 0xFF, 0xFF},
2283c57bd7c3SPing-Ke Shih 	{0x05F8,
2284c57bd7c3SPing-Ke Shih 	 RTW_PWR_CUT_ALL_MSK,
2285c57bd7c3SPing-Ke Shih 	 RTW_PWR_INTF_ALL_MSK,
2286c57bd7c3SPing-Ke Shih 	 RTW_PWR_ADDR_MAC,
2287c57bd7c3SPing-Ke Shih 	 RTW_PWR_CMD_POLLING, 0xFF, 0},
2288c57bd7c3SPing-Ke Shih 	{0x05F9,
2289c57bd7c3SPing-Ke Shih 	 RTW_PWR_CUT_ALL_MSK,
2290c57bd7c3SPing-Ke Shih 	 RTW_PWR_INTF_ALL_MSK,
2291c57bd7c3SPing-Ke Shih 	 RTW_PWR_ADDR_MAC,
2292c57bd7c3SPing-Ke Shih 	 RTW_PWR_CMD_POLLING, 0xFF, 0},
2293c57bd7c3SPing-Ke Shih 	{0x05FA,
2294c57bd7c3SPing-Ke Shih 	 RTW_PWR_CUT_ALL_MSK,
2295c57bd7c3SPing-Ke Shih 	 RTW_PWR_INTF_ALL_MSK,
2296c57bd7c3SPing-Ke Shih 	 RTW_PWR_ADDR_MAC,
2297c57bd7c3SPing-Ke Shih 	 RTW_PWR_CMD_POLLING, 0xFF, 0},
2298c57bd7c3SPing-Ke Shih 	{0x05FB,
2299c57bd7c3SPing-Ke Shih 	 RTW_PWR_CUT_ALL_MSK,
2300c57bd7c3SPing-Ke Shih 	 RTW_PWR_INTF_ALL_MSK,
2301c57bd7c3SPing-Ke Shih 	 RTW_PWR_ADDR_MAC,
2302c57bd7c3SPing-Ke Shih 	 RTW_PWR_CMD_POLLING, 0xFF, 0},
2303c57bd7c3SPing-Ke Shih 	{0x0002,
2304c57bd7c3SPing-Ke Shih 	 RTW_PWR_CUT_ALL_MSK,
2305c57bd7c3SPing-Ke Shih 	 RTW_PWR_INTF_ALL_MSK,
2306c57bd7c3SPing-Ke Shih 	 RTW_PWR_ADDR_MAC,
2307c57bd7c3SPing-Ke Shih 	 RTW_PWR_CMD_WRITE, BIT(0), 0},
2308c57bd7c3SPing-Ke Shih 	{0x0002,
2309c57bd7c3SPing-Ke Shih 	 RTW_PWR_CUT_ALL_MSK,
2310c57bd7c3SPing-Ke Shih 	 RTW_PWR_INTF_ALL_MSK,
2311c57bd7c3SPing-Ke Shih 	 RTW_PWR_ADDR_MAC,
2312c57bd7c3SPing-Ke Shih 	 RTW_PWR_CMD_DELAY, 0, RTW_PWR_DELAY_US},
2313c57bd7c3SPing-Ke Shih 	{0x0002,
2314c57bd7c3SPing-Ke Shih 	 RTW_PWR_CUT_ALL_MSK,
2315c57bd7c3SPing-Ke Shih 	 RTW_PWR_INTF_ALL_MSK,
2316c57bd7c3SPing-Ke Shih 	 RTW_PWR_ADDR_MAC,
2317c57bd7c3SPing-Ke Shih 	 RTW_PWR_CMD_WRITE, BIT(1), 0},
2318c57bd7c3SPing-Ke Shih 	{0x0100,
2319c57bd7c3SPing-Ke Shih 	 RTW_PWR_CUT_ALL_MSK,
2320c57bd7c3SPing-Ke Shih 	 RTW_PWR_INTF_ALL_MSK,
2321c57bd7c3SPing-Ke Shih 	 RTW_PWR_ADDR_MAC,
2322c57bd7c3SPing-Ke Shih 	 RTW_PWR_CMD_WRITE, 0xFF, 0x03},
2323c57bd7c3SPing-Ke Shih 	{0x0101,
2324c57bd7c3SPing-Ke Shih 	 RTW_PWR_CUT_ALL_MSK,
2325c57bd7c3SPing-Ke Shih 	 RTW_PWR_INTF_ALL_MSK,
2326c57bd7c3SPing-Ke Shih 	 RTW_PWR_ADDR_MAC,
2327c57bd7c3SPing-Ke Shih 	 RTW_PWR_CMD_WRITE, BIT(1), 0},
2328c57bd7c3SPing-Ke Shih 	{0x0093,
2329c57bd7c3SPing-Ke Shih 	 RTW_PWR_CUT_ALL_MSK,
2330c57bd7c3SPing-Ke Shih 	 RTW_PWR_INTF_SDIO_MSK,
2331c57bd7c3SPing-Ke Shih 	 RTW_PWR_ADDR_MAC,
2332c57bd7c3SPing-Ke Shih 	 RTW_PWR_CMD_WRITE, 0xFF, 0x00},
2333c57bd7c3SPing-Ke Shih 	{0x0553,
2334c57bd7c3SPing-Ke Shih 	 RTW_PWR_CUT_ALL_MSK,
2335c57bd7c3SPing-Ke Shih 	 RTW_PWR_INTF_ALL_MSK,
2336c57bd7c3SPing-Ke Shih 	 RTW_PWR_ADDR_MAC,
2337c57bd7c3SPing-Ke Shih 	 RTW_PWR_CMD_WRITE, BIT(5), BIT(5)},
2338c57bd7c3SPing-Ke Shih 	{0xFFFF,
2339c57bd7c3SPing-Ke Shih 	 RTW_PWR_CUT_ALL_MSK,
2340c57bd7c3SPing-Ke Shih 	 RTW_PWR_INTF_ALL_MSK,
2341c57bd7c3SPing-Ke Shih 	 0,
2342c57bd7c3SPing-Ke Shih 	 RTW_PWR_CMD_END, 0, 0},
2343c57bd7c3SPing-Ke Shih };
2344c57bd7c3SPing-Ke Shih 
2345c57bd7c3SPing-Ke Shih static const struct rtw_pwr_seq_cmd trans_act_to_pre_carddis_8723d[] = {
2346c57bd7c3SPing-Ke Shih 	{0x0003,
2347c57bd7c3SPing-Ke Shih 	 RTW_PWR_CUT_ALL_MSK,
2348c57bd7c3SPing-Ke Shih 	 RTW_PWR_INTF_ALL_MSK,
2349c57bd7c3SPing-Ke Shih 	 RTW_PWR_ADDR_MAC,
2350c57bd7c3SPing-Ke Shih 	 RTW_PWR_CMD_WRITE, BIT(2), 0},
2351c57bd7c3SPing-Ke Shih 	{0x0080,
2352c57bd7c3SPing-Ke Shih 	 RTW_PWR_CUT_ALL_MSK,
2353c57bd7c3SPing-Ke Shih 	 RTW_PWR_INTF_ALL_MSK,
2354c57bd7c3SPing-Ke Shih 	 RTW_PWR_ADDR_MAC,
2355c57bd7c3SPing-Ke Shih 	 RTW_PWR_CMD_WRITE, 0xFF, 0},
2356c57bd7c3SPing-Ke Shih 	{0xFFFF,
2357c57bd7c3SPing-Ke Shih 	 RTW_PWR_CUT_ALL_MSK,
2358c57bd7c3SPing-Ke Shih 	 RTW_PWR_INTF_ALL_MSK,
2359c57bd7c3SPing-Ke Shih 	 0,
2360c57bd7c3SPing-Ke Shih 	 RTW_PWR_CMD_END, 0, 0},
2361c57bd7c3SPing-Ke Shih };
2362c57bd7c3SPing-Ke Shih 
2363c57bd7c3SPing-Ke Shih static const struct rtw_pwr_seq_cmd trans_act_to_cardemu_8723d[] = {
2364c57bd7c3SPing-Ke Shih 	{0x0002,
2365c57bd7c3SPing-Ke Shih 	 RTW_PWR_CUT_ALL_MSK,
2366c57bd7c3SPing-Ke Shih 	 RTW_PWR_INTF_ALL_MSK,
2367c57bd7c3SPing-Ke Shih 	 RTW_PWR_ADDR_MAC,
2368c57bd7c3SPing-Ke Shih 	 RTW_PWR_CMD_WRITE, BIT(0), 0},
2369c57bd7c3SPing-Ke Shih 	{0x0049,
2370c57bd7c3SPing-Ke Shih 	 RTW_PWR_CUT_ALL_MSK,
2371c57bd7c3SPing-Ke Shih 	 RTW_PWR_INTF_ALL_MSK,
2372c57bd7c3SPing-Ke Shih 	 RTW_PWR_ADDR_MAC,
2373c57bd7c3SPing-Ke Shih 	 RTW_PWR_CMD_WRITE, BIT(1), 0},
2374c57bd7c3SPing-Ke Shih 	{0x0006,
2375c57bd7c3SPing-Ke Shih 	 RTW_PWR_CUT_ALL_MSK,
2376c57bd7c3SPing-Ke Shih 	 RTW_PWR_INTF_ALL_MSK,
2377c57bd7c3SPing-Ke Shih 	 RTW_PWR_ADDR_MAC,
2378c57bd7c3SPing-Ke Shih 	 RTW_PWR_CMD_WRITE, BIT(0), BIT(0)},
2379c57bd7c3SPing-Ke Shih 	{0x0005,
2380c57bd7c3SPing-Ke Shih 	 RTW_PWR_CUT_ALL_MSK,
2381c57bd7c3SPing-Ke Shih 	 RTW_PWR_INTF_ALL_MSK,
2382c57bd7c3SPing-Ke Shih 	 RTW_PWR_ADDR_MAC,
2383c57bd7c3SPing-Ke Shih 	 RTW_PWR_CMD_WRITE, BIT(1), BIT(1)},
2384c57bd7c3SPing-Ke Shih 	{0x0005,
2385c57bd7c3SPing-Ke Shih 	 RTW_PWR_CUT_ALL_MSK,
2386c57bd7c3SPing-Ke Shih 	 RTW_PWR_INTF_ALL_MSK,
2387c57bd7c3SPing-Ke Shih 	 RTW_PWR_ADDR_MAC,
2388c57bd7c3SPing-Ke Shih 	 RTW_PWR_CMD_POLLING, BIT(1), 0},
2389c57bd7c3SPing-Ke Shih 	{0x0010,
2390c57bd7c3SPing-Ke Shih 	 RTW_PWR_CUT_ALL_MSK,
2391c57bd7c3SPing-Ke Shih 	 RTW_PWR_INTF_ALL_MSK,
2392c57bd7c3SPing-Ke Shih 	 RTW_PWR_ADDR_MAC,
2393c57bd7c3SPing-Ke Shih 	 RTW_PWR_CMD_WRITE, BIT(6), 0},
2394c57bd7c3SPing-Ke Shih 	{0x0000,
2395c57bd7c3SPing-Ke Shih 	 RTW_PWR_CUT_ALL_MSK,
2396c57bd7c3SPing-Ke Shih 	 RTW_PWR_INTF_USB_MSK | RTW_PWR_INTF_SDIO_MSK,
2397c57bd7c3SPing-Ke Shih 	 RTW_PWR_ADDR_MAC,
2398c57bd7c3SPing-Ke Shih 	 RTW_PWR_CMD_WRITE, BIT(5), BIT(5)},
2399c57bd7c3SPing-Ke Shih 	{0x0020,
2400c57bd7c3SPing-Ke Shih 	 RTW_PWR_CUT_ALL_MSK,
2401c57bd7c3SPing-Ke Shih 	 RTW_PWR_INTF_USB_MSK | RTW_PWR_INTF_SDIO_MSK,
2402c57bd7c3SPing-Ke Shih 	 RTW_PWR_ADDR_MAC,
2403c57bd7c3SPing-Ke Shih 	 RTW_PWR_CMD_WRITE, BIT(0), 0},
2404c57bd7c3SPing-Ke Shih 	{0xFFFF,
2405c57bd7c3SPing-Ke Shih 	 RTW_PWR_CUT_ALL_MSK,
2406c57bd7c3SPing-Ke Shih 	 RTW_PWR_INTF_ALL_MSK,
2407c57bd7c3SPing-Ke Shih 	 0,
2408c57bd7c3SPing-Ke Shih 	 RTW_PWR_CMD_END, 0, 0},
2409c57bd7c3SPing-Ke Shih };
2410c57bd7c3SPing-Ke Shih 
2411c57bd7c3SPing-Ke Shih static const struct rtw_pwr_seq_cmd trans_cardemu_to_carddis_8723d[] = {
2412c57bd7c3SPing-Ke Shih 	{0x0007,
2413c57bd7c3SPing-Ke Shih 	 RTW_PWR_CUT_ALL_MSK,
2414c57bd7c3SPing-Ke Shih 	 RTW_PWR_INTF_SDIO_MSK,
2415c57bd7c3SPing-Ke Shih 	 RTW_PWR_ADDR_MAC,
2416c57bd7c3SPing-Ke Shih 	 RTW_PWR_CMD_WRITE, 0xFF, 0x20},
2417c57bd7c3SPing-Ke Shih 	{0x0005,
2418c57bd7c3SPing-Ke Shih 	 RTW_PWR_CUT_ALL_MSK,
2419c57bd7c3SPing-Ke Shih 	 RTW_PWR_INTF_USB_MSK | RTW_PWR_INTF_SDIO_MSK,
2420c57bd7c3SPing-Ke Shih 	 RTW_PWR_ADDR_MAC,
2421c57bd7c3SPing-Ke Shih 	 RTW_PWR_CMD_WRITE, BIT(3) | BIT(4), BIT(3)},
2422c57bd7c3SPing-Ke Shih 	{0x0005,
2423c57bd7c3SPing-Ke Shih 	 RTW_PWR_CUT_ALL_MSK,
2424c57bd7c3SPing-Ke Shih 	 RTW_PWR_INTF_PCI_MSK,
2425c57bd7c3SPing-Ke Shih 	 RTW_PWR_ADDR_MAC,
2426c57bd7c3SPing-Ke Shih 	 RTW_PWR_CMD_WRITE, BIT(2), BIT(2)},
2427c57bd7c3SPing-Ke Shih 	{0x0005,
2428c57bd7c3SPing-Ke Shih 	 RTW_PWR_CUT_ALL_MSK,
2429c57bd7c3SPing-Ke Shih 	 RTW_PWR_INTF_PCI_MSK,
2430c57bd7c3SPing-Ke Shih 	 RTW_PWR_ADDR_MAC,
2431c57bd7c3SPing-Ke Shih 	 RTW_PWR_CMD_WRITE, BIT(3) | BIT(4), BIT(3) | BIT(4)},
2432c57bd7c3SPing-Ke Shih 	{0x004A,
2433c57bd7c3SPing-Ke Shih 	 RTW_PWR_CUT_ALL_MSK,
2434c57bd7c3SPing-Ke Shih 	 RTW_PWR_INTF_USB_MSK,
2435c57bd7c3SPing-Ke Shih 	 RTW_PWR_ADDR_MAC,
2436c57bd7c3SPing-Ke Shih 	 RTW_PWR_CMD_WRITE, BIT(0), 1},
2437c57bd7c3SPing-Ke Shih 	{0x0023,
2438c57bd7c3SPing-Ke Shih 	 RTW_PWR_CUT_ALL_MSK,
2439c57bd7c3SPing-Ke Shih 	 RTW_PWR_INTF_SDIO_MSK,
2440c57bd7c3SPing-Ke Shih 	 RTW_PWR_ADDR_MAC,
2441c57bd7c3SPing-Ke Shih 	 RTW_PWR_CMD_WRITE, BIT(4), BIT(4)},
2442c57bd7c3SPing-Ke Shih 	{0x0086,
2443c57bd7c3SPing-Ke Shih 	 RTW_PWR_CUT_ALL_MSK,
2444c57bd7c3SPing-Ke Shih 	 RTW_PWR_INTF_SDIO_MSK,
2445c57bd7c3SPing-Ke Shih 	 RTW_PWR_ADDR_SDIO,
2446c57bd7c3SPing-Ke Shih 	 RTW_PWR_CMD_WRITE, BIT(0), BIT(0)},
2447c57bd7c3SPing-Ke Shih 	{0x0086,
2448c57bd7c3SPing-Ke Shih 	 RTW_PWR_CUT_ALL_MSK,
2449c57bd7c3SPing-Ke Shih 	 RTW_PWR_INTF_SDIO_MSK,
2450c57bd7c3SPing-Ke Shih 	 RTW_PWR_ADDR_SDIO,
2451c57bd7c3SPing-Ke Shih 	 RTW_PWR_CMD_POLLING, BIT(1), 0},
2452c57bd7c3SPing-Ke Shih 	{0xFFFF,
2453c57bd7c3SPing-Ke Shih 	 RTW_PWR_CUT_ALL_MSK,
2454c57bd7c3SPing-Ke Shih 	 RTW_PWR_INTF_ALL_MSK,
2455c57bd7c3SPing-Ke Shih 	 0,
2456c57bd7c3SPing-Ke Shih 	 RTW_PWR_CMD_END, 0, 0},
2457c57bd7c3SPing-Ke Shih };
2458c57bd7c3SPing-Ke Shih 
2459c57bd7c3SPing-Ke Shih static const struct rtw_pwr_seq_cmd trans_act_to_post_carddis_8723d[] = {
2460c57bd7c3SPing-Ke Shih 	{0x001D,
2461c57bd7c3SPing-Ke Shih 	 RTW_PWR_CUT_ALL_MSK,
2462c57bd7c3SPing-Ke Shih 	 RTW_PWR_INTF_ALL_MSK,
2463c57bd7c3SPing-Ke Shih 	 RTW_PWR_ADDR_MAC,
2464c57bd7c3SPing-Ke Shih 	 RTW_PWR_CMD_WRITE, BIT(0), 0},
2465c57bd7c3SPing-Ke Shih 	{0x001D,
2466c57bd7c3SPing-Ke Shih 	 RTW_PWR_CUT_ALL_MSK,
2467c57bd7c3SPing-Ke Shih 	 RTW_PWR_INTF_ALL_MSK,
2468c57bd7c3SPing-Ke Shih 	 RTW_PWR_ADDR_MAC,
2469c57bd7c3SPing-Ke Shih 	 RTW_PWR_CMD_WRITE, BIT(0), BIT(0)},
2470c57bd7c3SPing-Ke Shih 	{0x001C,
2471c57bd7c3SPing-Ke Shih 	 RTW_PWR_CUT_ALL_MSK,
2472c57bd7c3SPing-Ke Shih 	 RTW_PWR_INTF_ALL_MSK,
2473c57bd7c3SPing-Ke Shih 	 RTW_PWR_ADDR_MAC,
2474c57bd7c3SPing-Ke Shih 	 RTW_PWR_CMD_WRITE, 0xFF, 0x0E},
2475c57bd7c3SPing-Ke Shih 	{0xFFFF,
2476c57bd7c3SPing-Ke Shih 	 RTW_PWR_CUT_ALL_MSK,
2477c57bd7c3SPing-Ke Shih 	 RTW_PWR_INTF_ALL_MSK,
2478c57bd7c3SPing-Ke Shih 	 0,
2479c57bd7c3SPing-Ke Shih 	 RTW_PWR_CMD_END, 0, 0},
2480c57bd7c3SPing-Ke Shih };
2481c57bd7c3SPing-Ke Shih 
2482c57bd7c3SPing-Ke Shih static const struct rtw_pwr_seq_cmd *card_disable_flow_8723d[] = {
2483c57bd7c3SPing-Ke Shih 	trans_act_to_lps_8723d,
2484c57bd7c3SPing-Ke Shih 	trans_act_to_pre_carddis_8723d,
2485c57bd7c3SPing-Ke Shih 	trans_act_to_cardemu_8723d,
2486c57bd7c3SPing-Ke Shih 	trans_cardemu_to_carddis_8723d,
2487c57bd7c3SPing-Ke Shih 	trans_act_to_post_carddis_8723d,
2488c57bd7c3SPing-Ke Shih 	NULL
2489c57bd7c3SPing-Ke Shih };
2490c57bd7c3SPing-Ke Shih 
2491d91277deSPing-Ke Shih static const struct rtw_page_table page_table_8723d[] = {
2492d91277deSPing-Ke Shih 	{12, 2, 2, 0, 1},
2493d91277deSPing-Ke Shih 	{12, 2, 2, 0, 1},
2494d91277deSPing-Ke Shih 	{12, 2, 2, 0, 1},
2495d91277deSPing-Ke Shih 	{12, 2, 2, 0, 1},
2496d91277deSPing-Ke Shih 	{12, 2, 2, 0, 1},
2497d91277deSPing-Ke Shih };
2498d91277deSPing-Ke Shih 
2499d91277deSPing-Ke Shih static const struct rtw_rqpn rqpn_table_8723d[] = {
2500d91277deSPing-Ke Shih 	{RTW_DMA_MAPPING_NORMAL, RTW_DMA_MAPPING_NORMAL,
2501d91277deSPing-Ke Shih 	 RTW_DMA_MAPPING_LOW, RTW_DMA_MAPPING_LOW,
2502d91277deSPing-Ke Shih 	 RTW_DMA_MAPPING_EXTRA, RTW_DMA_MAPPING_HIGH},
2503d91277deSPing-Ke Shih 	{RTW_DMA_MAPPING_NORMAL, RTW_DMA_MAPPING_NORMAL,
2504d91277deSPing-Ke Shih 	 RTW_DMA_MAPPING_LOW, RTW_DMA_MAPPING_LOW,
2505d91277deSPing-Ke Shih 	 RTW_DMA_MAPPING_EXTRA, RTW_DMA_MAPPING_HIGH},
2506d91277deSPing-Ke Shih 	{RTW_DMA_MAPPING_NORMAL, RTW_DMA_MAPPING_NORMAL,
2507d91277deSPing-Ke Shih 	 RTW_DMA_MAPPING_NORMAL, RTW_DMA_MAPPING_HIGH,
2508d91277deSPing-Ke Shih 	 RTW_DMA_MAPPING_HIGH, RTW_DMA_MAPPING_HIGH},
2509d91277deSPing-Ke Shih 	{RTW_DMA_MAPPING_NORMAL, RTW_DMA_MAPPING_NORMAL,
2510d91277deSPing-Ke Shih 	 RTW_DMA_MAPPING_LOW, RTW_DMA_MAPPING_LOW,
2511d91277deSPing-Ke Shih 	 RTW_DMA_MAPPING_HIGH, RTW_DMA_MAPPING_HIGH},
2512d91277deSPing-Ke Shih 	{RTW_DMA_MAPPING_NORMAL, RTW_DMA_MAPPING_NORMAL,
2513d91277deSPing-Ke Shih 	 RTW_DMA_MAPPING_LOW, RTW_DMA_MAPPING_LOW,
2514d91277deSPing-Ke Shih 	 RTW_DMA_MAPPING_EXTRA, RTW_DMA_MAPPING_HIGH},
2515d91277deSPing-Ke Shih };
2516d91277deSPing-Ke Shih 
25177d754f97SPing-Ke Shih static const struct rtw_prioq_addrs prioq_addrs_8723d = {
25187d754f97SPing-Ke Shih 	.prio[RTW_DMA_MAPPING_EXTRA] = {
25197d754f97SPing-Ke Shih 		.rsvd = REG_RQPN_NPQ + 2, .avail = REG_RQPN_NPQ + 3,
25207d754f97SPing-Ke Shih 	},
25217d754f97SPing-Ke Shih 	.prio[RTW_DMA_MAPPING_LOW] = {
25227d754f97SPing-Ke Shih 		.rsvd = REG_RQPN + 1, .avail = REG_FIFOPAGE_CTRL_2 + 1,
25237d754f97SPing-Ke Shih 	},
25247d754f97SPing-Ke Shih 	.prio[RTW_DMA_MAPPING_NORMAL] = {
25257d754f97SPing-Ke Shih 		.rsvd = REG_RQPN_NPQ, .avail = REG_RQPN_NPQ + 1,
25267d754f97SPing-Ke Shih 	},
25277d754f97SPing-Ke Shih 	.prio[RTW_DMA_MAPPING_HIGH] = {
25287d754f97SPing-Ke Shih 		.rsvd = REG_RQPN, .avail = REG_FIFOPAGE_CTRL_2,
25297d754f97SPing-Ke Shih 	},
25307d754f97SPing-Ke Shih 	.wsize = false,
25317d754f97SPing-Ke Shih };
25327d754f97SPing-Ke Shih 
253317579404SPing-Ke Shih static const struct rtw_intf_phy_para pcie_gen1_param_8723d[] = {
253417579404SPing-Ke Shih 	{0x0008, 0x4a22,
253517579404SPing-Ke Shih 	 RTW_IP_SEL_PHY,
253617579404SPing-Ke Shih 	 RTW_INTF_PHY_CUT_ALL,
253717579404SPing-Ke Shih 	 RTW_INTF_PHY_PLATFORM_ALL},
253817579404SPing-Ke Shih 	{0x0009, 0x1000,
253917579404SPing-Ke Shih 	 RTW_IP_SEL_PHY,
254017579404SPing-Ke Shih 	 ~(RTW_INTF_PHY_CUT_A | RTW_INTF_PHY_CUT_B),
254117579404SPing-Ke Shih 	 RTW_INTF_PHY_PLATFORM_ALL},
254217579404SPing-Ke Shih 	{0xFFFF, 0x0000,
254317579404SPing-Ke Shih 	 RTW_IP_SEL_PHY,
254417579404SPing-Ke Shih 	 RTW_INTF_PHY_CUT_ALL,
254517579404SPing-Ke Shih 	 RTW_INTF_PHY_PLATFORM_ALL},
254617579404SPing-Ke Shih };
254717579404SPing-Ke Shih 
254817579404SPing-Ke Shih static const struct rtw_intf_phy_para_table phy_para_table_8723d = {
254917579404SPing-Ke Shih 	.gen1_para	= pcie_gen1_param_8723d,
255017579404SPing-Ke Shih 	.n_gen1_para	= ARRAY_SIZE(pcie_gen1_param_8723d),
255117579404SPing-Ke Shih };
255217579404SPing-Ke Shih 
2553db39a9ddSPing-Ke Shih static const struct rtw_hw_reg rtw8723d_dig[] = {
2554db39a9ddSPing-Ke Shih 	[0] = { .addr = 0xc50, .mask = 0x7f },
2555db39a9ddSPing-Ke Shih 	[1] = { .addr = 0xc50, .mask = 0x7f },
2556db39a9ddSPing-Ke Shih };
2557db39a9ddSPing-Ke Shih 
2558fc637a86SPing-Ke Shih static const struct rtw_hw_reg rtw8723d_dig_cck[] = {
2559fc637a86SPing-Ke Shih 	[0] = { .addr = 0xa0c, .mask = 0x3f00 },
2560fc637a86SPing-Ke Shih };
2561fc637a86SPing-Ke Shih 
2562e0c27cdbSPing-Ke Shih static const struct rtw_rf_sipi_addr rtw8723d_rf_sipi_addr[] = {
2563e0c27cdbSPing-Ke Shih 	[RF_PATH_A] = { .hssi_1 = 0x820, .lssi_read    = 0x8a0,
2564e0c27cdbSPing-Ke Shih 			.hssi_2 = 0x824, .lssi_read_pi = 0x8b8},
2565e0c27cdbSPing-Ke Shih 	[RF_PATH_B] = { .hssi_1 = 0x828, .lssi_read    = 0x8a4,
2566e0c27cdbSPing-Ke Shih 			.hssi_2 = 0x82c, .lssi_read_pi = 0x8bc},
2567e0c27cdbSPing-Ke Shih };
2568e0c27cdbSPing-Ke Shih 
25697e149368SPing-Ke Shih static const struct rtw_ltecoex_addr rtw8723d_ltecoex_addr = {
25707e149368SPing-Ke Shih 	.ctrl = REG_LTECOEX_CTRL,
25717e149368SPing-Ke Shih 	.wdata = REG_LTECOEX_WRITE_DATA,
25727e149368SPing-Ke Shih 	.rdata = REG_LTECOEX_READ_DATA,
25737e149368SPing-Ke Shih };
25747e149368SPing-Ke Shih 
25759874f685SPing-Ke Shih static const struct rtw_rfe_def rtw8723d_rfe_defs[] = {
25769874f685SPing-Ke Shih 	[0] = { .phy_pg_tbl	= &rtw8723d_bb_pg_tbl,
25779874f685SPing-Ke Shih 		.txpwr_lmt_tbl	= &rtw8723d_txpwr_lmt_tbl,},
25789874f685SPing-Ke Shih };
25799874f685SPing-Ke Shih 
2580608d2a08SPing-Ke Shih static const u8 rtw8723d_pwrtrk_2gb_n[] = {
2581608d2a08SPing-Ke Shih 	0, 0, 1, 1, 1, 2, 2, 3, 4, 4, 4, 4, 5, 5, 5,
2582608d2a08SPing-Ke Shih 	6, 6, 7, 7, 8, 8, 8, 9, 9, 9, 10, 10, 10, 10, 10
2583608d2a08SPing-Ke Shih };
2584608d2a08SPing-Ke Shih 
2585608d2a08SPing-Ke Shih static const u8 rtw8723d_pwrtrk_2gb_p[] = {
2586608d2a08SPing-Ke Shih 	0, 0, 1, 1, 2, 2, 2, 3, 3, 4, 4, 5, 5, 6, 7,
2587608d2a08SPing-Ke Shih 	7, 8, 8, 8, 9, 9, 10, 10, 10, 10, 10, 10, 10, 10, 10
2588608d2a08SPing-Ke Shih };
2589608d2a08SPing-Ke Shih 
2590608d2a08SPing-Ke Shih static const u8 rtw8723d_pwrtrk_2ga_n[] = {
2591608d2a08SPing-Ke Shih 	0, 0, 1, 1, 1, 2, 2, 3, 4, 4, 4, 4, 5, 5, 5,
2592608d2a08SPing-Ke Shih 	6, 6, 7, 7, 8, 8, 8, 9, 9, 9, 10, 10, 10, 10, 10
2593608d2a08SPing-Ke Shih };
2594608d2a08SPing-Ke Shih 
2595608d2a08SPing-Ke Shih static const u8 rtw8723d_pwrtrk_2ga_p[] = {
2596608d2a08SPing-Ke Shih 	0, 0, 1, 1, 2, 2, 2, 3, 3, 4, 4, 5, 5, 6, 7,
2597608d2a08SPing-Ke Shih 	7, 8, 8, 8, 9, 9, 10, 10, 10, 10, 10, 10, 10, 10, 10
2598608d2a08SPing-Ke Shih };
2599608d2a08SPing-Ke Shih 
2600608d2a08SPing-Ke Shih static const u8 rtw8723d_pwrtrk_2g_cck_b_n[] = {
2601608d2a08SPing-Ke Shih 	0, 1, 1, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6,
2602608d2a08SPing-Ke Shih 	6, 7, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 11, 11, 11
2603608d2a08SPing-Ke Shih };
2604608d2a08SPing-Ke Shih 
2605608d2a08SPing-Ke Shih static const u8 rtw8723d_pwrtrk_2g_cck_b_p[] = {
2606608d2a08SPing-Ke Shih 	0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7,
2607608d2a08SPing-Ke Shih 	7, 8, 9, 9, 10, 10, 11, 11, 11, 11, 11, 11, 11, 11, 11
2608608d2a08SPing-Ke Shih };
2609608d2a08SPing-Ke Shih 
2610608d2a08SPing-Ke Shih static const u8 rtw8723d_pwrtrk_2g_cck_a_n[] = {
2611608d2a08SPing-Ke Shih 	0, 1, 1, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6,
2612608d2a08SPing-Ke Shih 	6, 7, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 11, 11, 11
2613608d2a08SPing-Ke Shih };
2614608d2a08SPing-Ke Shih 
2615608d2a08SPing-Ke Shih static const u8 rtw8723d_pwrtrk_2g_cck_a_p[] = {
2616608d2a08SPing-Ke Shih 	0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7,
2617608d2a08SPing-Ke Shih 	7, 8, 9, 9, 10, 10, 11, 11, 11, 11, 11, 11, 11, 11, 11
2618608d2a08SPing-Ke Shih };
2619608d2a08SPing-Ke Shih 
2620608d2a08SPing-Ke Shih static const s8 rtw8723d_pwrtrk_xtal_n[] = {
2621608d2a08SPing-Ke Shih 	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
2622608d2a08SPing-Ke Shih 	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
2623608d2a08SPing-Ke Shih };
2624608d2a08SPing-Ke Shih 
2625608d2a08SPing-Ke Shih static const s8 rtw8723d_pwrtrk_xtal_p[] = {
2626608d2a08SPing-Ke Shih 	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
2627608d2a08SPing-Ke Shih 	0, -10, -12, -14, -16, -16, -16, -16, -16, -16, -16, -16, -16, -16, -16
2628608d2a08SPing-Ke Shih };
2629608d2a08SPing-Ke Shih 
2630608d2a08SPing-Ke Shih static const struct rtw_pwr_track_tbl rtw8723d_rtw_pwr_track_tbl = {
2631608d2a08SPing-Ke Shih 	.pwrtrk_2gb_n = rtw8723d_pwrtrk_2gb_n,
2632608d2a08SPing-Ke Shih 	.pwrtrk_2gb_p = rtw8723d_pwrtrk_2gb_p,
2633608d2a08SPing-Ke Shih 	.pwrtrk_2ga_n = rtw8723d_pwrtrk_2ga_n,
2634608d2a08SPing-Ke Shih 	.pwrtrk_2ga_p = rtw8723d_pwrtrk_2ga_p,
2635608d2a08SPing-Ke Shih 	.pwrtrk_2g_cckb_n = rtw8723d_pwrtrk_2g_cck_b_n,
2636608d2a08SPing-Ke Shih 	.pwrtrk_2g_cckb_p = rtw8723d_pwrtrk_2g_cck_b_p,
2637608d2a08SPing-Ke Shih 	.pwrtrk_2g_ccka_n = rtw8723d_pwrtrk_2g_cck_a_n,
2638608d2a08SPing-Ke Shih 	.pwrtrk_2g_ccka_p = rtw8723d_pwrtrk_2g_cck_a_p,
2639608d2a08SPing-Ke Shih 	.pwrtrk_xtal_p = rtw8723d_pwrtrk_xtal_p,
2640608d2a08SPing-Ke Shih 	.pwrtrk_xtal_n = rtw8723d_pwrtrk_xtal_n,
2641608d2a08SPing-Ke Shih };
2642608d2a08SPing-Ke Shih 
2643d1391c49SPing-Ke Shih static const struct rtw_reg_domain coex_info_hw_regs_8723d[] = {
2644d1391c49SPing-Ke Shih 	{0x948, MASKDWORD, RTW_REG_DOMAIN_MAC32},
2645d1391c49SPing-Ke Shih 	{0x67, BIT(7), RTW_REG_DOMAIN_MAC8},
2646d1391c49SPing-Ke Shih 	{0, 0, RTW_REG_DOMAIN_NL},
2647d1391c49SPing-Ke Shih 	{0x964, BIT(1), RTW_REG_DOMAIN_MAC8},
2648d1391c49SPing-Ke Shih 	{0x864, BIT(0), RTW_REG_DOMAIN_MAC8},
2649d1391c49SPing-Ke Shih 	{0xab7, BIT(5), RTW_REG_DOMAIN_MAC8},
2650d1391c49SPing-Ke Shih 	{0xa01, BIT(7), RTW_REG_DOMAIN_MAC8},
2651d1391c49SPing-Ke Shih 	{0, 0, RTW_REG_DOMAIN_NL},
2652d1391c49SPing-Ke Shih 	{0x430, MASKDWORD, RTW_REG_DOMAIN_MAC32},
2653d1391c49SPing-Ke Shih 	{0x434, MASKDWORD, RTW_REG_DOMAIN_MAC32},
2654d1391c49SPing-Ke Shih 	{0x42a, MASKLWORD, RTW_REG_DOMAIN_MAC16},
2655d1391c49SPing-Ke Shih 	{0x426, MASKBYTE0, RTW_REG_DOMAIN_MAC8},
2656d1391c49SPing-Ke Shih 	{0x45e, BIT(3), RTW_REG_DOMAIN_MAC8},
2657d1391c49SPing-Ke Shih 	{0, 0, RTW_REG_DOMAIN_NL},
2658d1391c49SPing-Ke Shih 	{0x4c6, BIT(4), RTW_REG_DOMAIN_MAC8},
2659d1391c49SPing-Ke Shih 	{0x40, BIT(5), RTW_REG_DOMAIN_MAC8},
2660d1391c49SPing-Ke Shih 	{0x550, MASKDWORD, RTW_REG_DOMAIN_MAC32},
2661d1391c49SPing-Ke Shih 	{0x522, MASKBYTE0, RTW_REG_DOMAIN_MAC8},
2662d1391c49SPing-Ke Shih 	{0x953, BIT(1), RTW_REG_DOMAIN_MAC8},
2663d1391c49SPing-Ke Shih };
2664d1391c49SPing-Ke Shih 
2665811853daSPing-Ke Shih struct rtw_chip_info rtw8723d_hw_spec = {
2666811853daSPing-Ke Shih 	.ops = &rtw8723d_ops,
2667811853daSPing-Ke Shih 	.id = RTW_CHIP_TYPE_8723D,
2668811853daSPing-Ke Shih 	.fw_name = "rtw88/rtw8723d_fw.bin",
266915d2fcc6SPing-Ke Shih 	.wlan_cpu = RTW_WCPU_11N,
2670811853daSPing-Ke Shih 	.tx_pkt_desc_sz = 40,
2671811853daSPing-Ke Shih 	.tx_buf_desc_sz = 16,
2672811853daSPing-Ke Shih 	.rx_pkt_desc_sz = 24,
2673811853daSPing-Ke Shih 	.rx_buf_desc_sz = 8,
2674811853daSPing-Ke Shih 	.phy_efuse_size = 512,
2675811853daSPing-Ke Shih 	.log_efuse_size = 512,
2676811853daSPing-Ke Shih 	.ptct_efuse_size = 96 + 1,
2677d91277deSPing-Ke Shih 	.txff_size = 32768,
2678d91277deSPing-Ke Shih 	.rxff_size = 16384,
2679811853daSPing-Ke Shih 	.txgi_factor = 1,
2680811853daSPing-Ke Shih 	.is_pwr_by_rate_dec = true,
2681811853daSPing-Ke Shih 	.max_power_index = 0x3f,
2682811853daSPing-Ke Shih 	.csi_buf_pg_num = 0,
2683811853daSPing-Ke Shih 	.band = RTW_BAND_2G,
2684d91277deSPing-Ke Shih 	.page_size = 128,
2685db39a9ddSPing-Ke Shih 	.dig_min = 0x20,
2686811853daSPing-Ke Shih 	.ht_supported = true,
2687811853daSPing-Ke Shih 	.vht_supported = false,
2688811853daSPing-Ke Shih 	.lps_deep_mode_supported = 0,
2689811853daSPing-Ke Shih 	.sys_func_en = 0xFD,
2690c57bd7c3SPing-Ke Shih 	.pwr_on_seq = card_enable_flow_8723d,
2691c57bd7c3SPing-Ke Shih 	.pwr_off_seq = card_disable_flow_8723d,
2692d91277deSPing-Ke Shih 	.page_table = page_table_8723d,
2693d91277deSPing-Ke Shih 	.rqpn_table = rqpn_table_8723d,
26947d754f97SPing-Ke Shih 	.prioq_addrs = &prioq_addrs_8723d,
269517579404SPing-Ke Shih 	.intf_table = &phy_para_table_8723d,
2696db39a9ddSPing-Ke Shih 	.dig = rtw8723d_dig,
2697fc637a86SPing-Ke Shih 	.dig_cck = rtw8723d_dig_cck,
2698e0c27cdbSPing-Ke Shih 	.rf_sipi_addr = {0x840, 0x844},
2699e0c27cdbSPing-Ke Shih 	.rf_sipi_read_addr = rtw8723d_rf_sipi_addr,
2700e0c27cdbSPing-Ke Shih 	.fix_rf_phy_num = 2,
27017e149368SPing-Ke Shih 	.ltecoex_addr = &rtw8723d_ltecoex_addr,
27029874f685SPing-Ke Shih 	.mac_tbl = &rtw8723d_mac_tbl,
27039874f685SPing-Ke Shih 	.agc_tbl = &rtw8723d_agc_tbl,
27049874f685SPing-Ke Shih 	.bb_tbl = &rtw8723d_bb_tbl,
27059874f685SPing-Ke Shih 	.rf_tbl = {&rtw8723d_rf_a_tbl},
27069874f685SPing-Ke Shih 	.rfe_defs = rtw8723d_rfe_defs,
27079874f685SPing-Ke Shih 	.rfe_defs_size = ARRAY_SIZE(rtw8723d_rfe_defs),
27083ac14439SPing-Ke Shih 	.rx_ldpc = false,
2709608d2a08SPing-Ke Shih 	.pwr_track_tbl = &rtw8723d_rtw_pwr_track_tbl,
2710608d2a08SPing-Ke Shih 	.iqk_threshold = 8,
2711d1391c49SPing-Ke Shih 
2712d1391c49SPing-Ke Shih 	.coex_para_ver = 0x1905302f,
2713d1391c49SPing-Ke Shih 	.bt_desired_ver = 0x2f,
2714d1391c49SPing-Ke Shih 	.scbd_support = true,
2715d1391c49SPing-Ke Shih 	.new_scbd10_def = true,
2716d1391c49SPing-Ke Shih 	.pstdma_type = COEX_PSTDMA_FORCE_LPSOFF,
2717d1391c49SPing-Ke Shih 	.bt_rssi_type = COEX_BTRSSI_RATIO,
2718d1391c49SPing-Ke Shih 	.ant_isolation = 15,
2719d1391c49SPing-Ke Shih 	.rssi_tolerance = 2,
2720d1391c49SPing-Ke Shih 	.wl_rssi_step = wl_rssi_step_8723d,
2721d1391c49SPing-Ke Shih 	.bt_rssi_step = bt_rssi_step_8723d,
2722d1391c49SPing-Ke Shih 	.table_sant_num = ARRAY_SIZE(table_sant_8723d),
2723d1391c49SPing-Ke Shih 	.table_sant = table_sant_8723d,
2724d1391c49SPing-Ke Shih 	.table_nsant_num = ARRAY_SIZE(table_nsant_8723d),
2725d1391c49SPing-Ke Shih 	.table_nsant = table_nsant_8723d,
2726d1391c49SPing-Ke Shih 	.tdma_sant_num = ARRAY_SIZE(tdma_sant_8723d),
2727d1391c49SPing-Ke Shih 	.tdma_sant = tdma_sant_8723d,
2728d1391c49SPing-Ke Shih 	.tdma_nsant_num = ARRAY_SIZE(tdma_nsant_8723d),
2729d1391c49SPing-Ke Shih 	.tdma_nsant = tdma_nsant_8723d,
2730d1391c49SPing-Ke Shih 	.wl_rf_para_num = ARRAY_SIZE(rf_para_tx_8723d),
2731d1391c49SPing-Ke Shih 	.wl_rf_para_tx = rf_para_tx_8723d,
2732d1391c49SPing-Ke Shih 	.wl_rf_para_rx = rf_para_rx_8723d,
2733d1391c49SPing-Ke Shih 	.bt_afh_span_bw20 = 0x20,
2734d1391c49SPing-Ke Shih 	.bt_afh_span_bw40 = 0x30,
2735d1391c49SPing-Ke Shih 	.afh_5g_num = ARRAY_SIZE(afh_5g_8723d),
2736d1391c49SPing-Ke Shih 	.afh_5g = afh_5g_8723d,
2737d1391c49SPing-Ke Shih 
2738d1391c49SPing-Ke Shih 	.coex_info_hw_regs_num = ARRAY_SIZE(coex_info_hw_regs_8723d),
2739d1391c49SPing-Ke Shih 	.coex_info_hw_regs = coex_info_hw_regs_8723d,
2740811853daSPing-Ke Shih };
2741811853daSPing-Ke Shih EXPORT_SYMBOL(rtw8723d_hw_spec);
2742811853daSPing-Ke Shih 
2743811853daSPing-Ke Shih MODULE_FIRMWARE("rtw88/rtw8723d_fw.bin");
2744f56f0863SZong-Zhe Yang 
2745f56f0863SZong-Zhe Yang MODULE_AUTHOR("Realtek Corporation");
2746f56f0863SZong-Zhe Yang MODULE_DESCRIPTION("Realtek 802.11n wireless 8723d driver");
2747f56f0863SZong-Zhe Yang MODULE_LICENSE("Dual BSD/GPL");
2748