1 | // SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause |
2 | /* Copyright(c) 2018-2019 Realtek Corporation |
3 | */ |
4 | |
5 | #include <linux/module.h> |
6 | #include "main.h" |
7 | #include "coex.h" |
8 | #include "fw.h" |
9 | #include "tx.h" |
10 | #include "rx.h" |
11 | #include "phy.h" |
12 | #include "rtw8723d.h" |
13 | #include "rtw8723d_table.h" |
14 | #include "mac.h" |
15 | #include "reg.h" |
16 | #include "debug.h" |
17 | |
18 | static const struct rtw_hw_reg rtw8723d_txagc[] = { |
19 | [DESC_RATE1M] = { .addr = 0xe08, .mask = 0x0000ff00 }, |
20 | [DESC_RATE2M] = { .addr = 0x86c, .mask = 0x0000ff00 }, |
21 | [DESC_RATE5_5M] = { .addr = 0x86c, .mask = 0x00ff0000 }, |
22 | [DESC_RATE11M] = { .addr = 0x86c, .mask = 0xff000000 }, |
23 | [DESC_RATE6M] = { .addr = 0xe00, .mask = 0x000000ff }, |
24 | [DESC_RATE9M] = { .addr = 0xe00, .mask = 0x0000ff00 }, |
25 | [DESC_RATE12M] = { .addr = 0xe00, .mask = 0x00ff0000 }, |
26 | [DESC_RATE18M] = { .addr = 0xe00, .mask = 0xff000000 }, |
27 | [DESC_RATE24M] = { .addr = 0xe04, .mask = 0x000000ff }, |
28 | [DESC_RATE36M] = { .addr = 0xe04, .mask = 0x0000ff00 }, |
29 | [DESC_RATE48M] = { .addr = 0xe04, .mask = 0x00ff0000 }, |
30 | [DESC_RATE54M] = { .addr = 0xe04, .mask = 0xff000000 }, |
31 | [DESC_RATEMCS0] = { .addr = 0xe10, .mask = 0x000000ff }, |
32 | [DESC_RATEMCS1] = { .addr = 0xe10, .mask = 0x0000ff00 }, |
33 | [DESC_RATEMCS2] = { .addr = 0xe10, .mask = 0x00ff0000 }, |
34 | [DESC_RATEMCS3] = { .addr = 0xe10, .mask = 0xff000000 }, |
35 | [DESC_RATEMCS4] = { .addr = 0xe14, .mask = 0x000000ff }, |
36 | [DESC_RATEMCS5] = { .addr = 0xe14, .mask = 0x0000ff00 }, |
37 | [DESC_RATEMCS6] = { .addr = 0xe14, .mask = 0x00ff0000 }, |
38 | [DESC_RATEMCS7] = { .addr = 0xe14, .mask = 0xff000000 }, |
39 | }; |
40 | |
41 | #define WLAN_TXQ_RPT_EN 0x1F |
42 | #define WLAN_SLOT_TIME 0x09 |
43 | #define WLAN_RL_VAL 0x3030 |
44 | #define WLAN_BAR_VAL 0x0201ffff |
45 | #define BIT_MASK_TBTT_HOLD 0x00000fff |
46 | #define BIT_SHIFT_TBTT_HOLD 8 |
47 | #define BIT_MASK_TBTT_SETUP 0x000000ff |
48 | #define BIT_SHIFT_TBTT_SETUP 0 |
49 | #define BIT_MASK_TBTT_MASK ((BIT_MASK_TBTT_HOLD << BIT_SHIFT_TBTT_HOLD) | \ |
50 | (BIT_MASK_TBTT_SETUP << BIT_SHIFT_TBTT_SETUP)) |
51 | #define TBTT_TIME(s, h)((((s) & BIT_MASK_TBTT_SETUP) << BIT_SHIFT_TBTT_SETUP) |\ |
52 | (((h) & BIT_MASK_TBTT_HOLD) << BIT_SHIFT_TBTT_HOLD)) |
53 | #define WLAN_TBTT_TIME_NORMAL TBTT_TIME(0x04, 0x80) |
54 | #define WLAN_TBTT_TIME_STOP_BCN TBTT_TIME(0x04, 0x64) |
55 | #define WLAN_PIFS_VAL 0 |
56 | #define WLAN_AGG_BRK_TIME 0x16 |
57 | #define WLAN_NAV_PROT_LEN 0x0040 |
58 | #define WLAN_SPEC_SIFS 0x100a |
59 | #define WLAN_RX_PKT_LIMIT 0x17 |
60 | #define WLAN_MAX_AGG_NR 0x0A |
61 | #define WLAN_AMPDU_MAX_TIME 0x1C |
62 | #define WLAN_ANT_SEL 0x82 |
63 | #define WLAN_LTR_IDLE_LAT 0x90039003 |
64 | #define WLAN_LTR_ACT_LAT 0x883c883c |
65 | #define WLAN_LTR_CTRL1 0xCB004010 |
66 | #define WLAN_LTR_CTRL2 0x01233425 |
67 | |
68 | static void rtw8723d_lck(struct rtw_dev *rtwdev) |
69 | { |
70 | u32 lc_cal; |
71 | u8 val_ctx, rf_val; |
72 | int ret; |
73 | |
74 | val_ctx = rtw_read8(rtwdev, REG_CTX); |
75 | if ((val_ctx & BIT_MASK_CTX_TYPE) != 0) |
76 | rtw_write8(rtwdev, REG_CTX, val: val_ctx & ~BIT_MASK_CTX_TYPE); |
77 | else |
78 | rtw_write8(rtwdev, REG_TXPAUSE, val: 0xFF); |
79 | lc_cal = rtw_read_rf(rtwdev, rf_path: RF_PATH_A, RF_CFGCH, RFREG_MASK); |
80 | |
81 | rtw_write_rf(rtwdev, rf_path: RF_PATH_A, RF_CFGCH, RFREG_MASK, data: lc_cal | BIT_LCK); |
82 | |
83 | ret = read_poll_timeout(rtw_read_rf, rf_val, rf_val != 0x1, |
84 | 10000, 1000000, false, |
85 | rtwdev, RF_PATH_A, RF_CFGCH, BIT_LCK); |
86 | if (ret) |
87 | rtw_warn(rtwdev, "failed to poll LCK status bit\n" ); |
88 | |
89 | rtw_write_rf(rtwdev, rf_path: RF_PATH_A, RF_CFGCH, RFREG_MASK, data: lc_cal); |
90 | if ((val_ctx & BIT_MASK_CTX_TYPE) != 0) |
91 | rtw_write8(rtwdev, REG_CTX, val: val_ctx); |
92 | else |
93 | rtw_write8(rtwdev, REG_TXPAUSE, val: 0x00); |
94 | } |
95 | |
96 | static const u32 rtw8723d_ofdm_swing_table[] = { |
97 | 0x0b40002d, 0x0c000030, 0x0cc00033, 0x0d800036, 0x0e400039, 0x0f00003c, |
98 | 0x10000040, 0x11000044, 0x12000048, 0x1300004c, 0x14400051, 0x15800056, |
99 | 0x16c0005b, 0x18000060, 0x19800066, 0x1b00006c, 0x1c800072, 0x1e400079, |
100 | 0x20000080, 0x22000088, 0x24000090, 0x26000098, 0x288000a2, 0x2ac000ab, |
101 | 0x2d4000b5, 0x300000c0, 0x32c000cb, 0x35c000d7, 0x390000e4, 0x3c8000f2, |
102 | 0x40000100, 0x43c0010f, 0x47c0011f, 0x4c000130, 0x50800142, 0x55400155, |
103 | 0x5a400169, 0x5fc0017f, 0x65400195, 0x6b8001ae, 0x71c001c7, 0x788001e2, |
104 | 0x7f8001fe, |
105 | }; |
106 | |
107 | static const u32 rtw8723d_cck_swing_table[] = { |
108 | 0x0CD, 0x0D9, 0x0E6, 0x0F3, 0x102, 0x111, 0x121, 0x132, 0x144, 0x158, |
109 | 0x16C, 0x182, 0x198, 0x1B1, 0x1CA, 0x1E5, 0x202, 0x221, 0x241, 0x263, |
110 | 0x287, 0x2AE, 0x2D6, 0x301, 0x32F, 0x35F, 0x392, 0x3C9, 0x402, 0x43F, |
111 | 0x47F, 0x4C3, 0x50C, 0x558, 0x5A9, 0x5FF, 0x65A, 0x6BA, 0x720, 0x78C, |
112 | 0x7FF, |
113 | }; |
114 | |
115 | #define RTW_OFDM_SWING_TABLE_SIZE ARRAY_SIZE(rtw8723d_ofdm_swing_table) |
116 | #define RTW_CCK_SWING_TABLE_SIZE ARRAY_SIZE(rtw8723d_cck_swing_table) |
117 | |
118 | static void rtw8723d_pwrtrack_init(struct rtw_dev *rtwdev) |
119 | { |
120 | struct rtw_dm_info *dm_info = &rtwdev->dm_info; |
121 | u8 path; |
122 | |
123 | dm_info->default_ofdm_index = RTW_DEF_OFDM_SWING_INDEX; |
124 | |
125 | for (path = RF_PATH_A; path < rtwdev->hal.rf_path_num; path++) { |
126 | ewma_thermal_init(e: &dm_info->avg_thermal[path]); |
127 | dm_info->delta_power_index[path] = 0; |
128 | } |
129 | dm_info->pwr_trk_triggered = false; |
130 | dm_info->pwr_trk_init_trigger = true; |
131 | dm_info->thermal_meter_k = rtwdev->efuse.thermal_meter_k; |
132 | dm_info->txagc_remnant_cck = 0; |
133 | dm_info->txagc_remnant_ofdm = 0; |
134 | } |
135 | |
136 | static void rtw8723d_phy_set_param(struct rtw_dev *rtwdev) |
137 | { |
138 | u8 xtal_cap; |
139 | u32 val32; |
140 | |
141 | /* power on BB/RF domain */ |
142 | rtw_write16_set(rtwdev, REG_SYS_FUNC_EN, |
143 | BIT_FEN_EN_25_1 | BIT_FEN_BB_GLB_RST | BIT_FEN_BB_RSTB); |
144 | rtw_write8_set(rtwdev, REG_RF_CTRL, |
145 | BIT_RF_EN | BIT_RF_RSTB | BIT_RF_SDM_RSTB); |
146 | rtw_write8(rtwdev, REG_AFE_CTRL1 + 1, val: 0x80); |
147 | |
148 | rtw_phy_load_tables(rtwdev); |
149 | |
150 | /* post init after header files config */ |
151 | rtw_write32_clr(rtwdev, REG_RCR, BIT_RCR_ADF); |
152 | rtw_write8_set(rtwdev, REG_HIQ_NO_LMT_EN, BIT_HIQ_NO_LMT_EN_ROOT); |
153 | rtw_write16_set(rtwdev, REG_AFE_CTRL_4, BIT_CK320M_AFE_EN | BIT_EN_SYN); |
154 | |
155 | xtal_cap = rtwdev->efuse.crystal_cap & 0x3F; |
156 | rtw_write32_mask(rtwdev, REG_AFE_CTRL3, BIT_MASK_XTAL, |
157 | data: xtal_cap | (xtal_cap << 6)); |
158 | rtw_write32_set(rtwdev, REG_FPGA0_RFMOD, BIT_CCKEN | BIT_OFDMEN); |
159 | if ((rtwdev->efuse.afe >> 4) == 14) { |
160 | rtw_write32_set(rtwdev, REG_AFE_CTRL3, BIT_XTAL_GMP_BIT4); |
161 | rtw_write32_clr(rtwdev, REG_AFE_CTRL1, BITS_PLL); |
162 | rtw_write32_set(rtwdev, REG_LDO_SWR_CTRL, BIT_XTA1); |
163 | rtw_write32_clr(rtwdev, REG_LDO_SWR_CTRL, BIT_XTA0); |
164 | } |
165 | |
166 | rtw_write8(rtwdev, REG_SLOT, WLAN_SLOT_TIME); |
167 | rtw_write8(rtwdev, REG_FWHW_TXQ_CTRL + 1, WLAN_TXQ_RPT_EN); |
168 | rtw_write16(rtwdev, REG_RETRY_LIMIT, WLAN_RL_VAL); |
169 | rtw_write32(rtwdev, REG_BAR_MODE_CTRL, WLAN_BAR_VAL); |
170 | rtw_write8(rtwdev, REG_ATIMWND, val: 0x2); |
171 | rtw_write8(rtwdev, REG_BCN_CTRL, |
172 | BIT_DIS_TSF_UDT | BIT_EN_BCN_FUNCTION | BIT_EN_TXBCN_RPT); |
173 | val32 = rtw_read32(rtwdev, REG_TBTT_PROHIBIT); |
174 | val32 &= ~BIT_MASK_TBTT_MASK; |
175 | val32 |= WLAN_TBTT_TIME_STOP_BCN; |
176 | rtw_write8(rtwdev, REG_TBTT_PROHIBIT, val: val32); |
177 | rtw_write8(rtwdev, REG_PIFS, WLAN_PIFS_VAL); |
178 | rtw_write8(rtwdev, REG_AGGR_BREAK_TIME, WLAN_AGG_BRK_TIME); |
179 | rtw_write16(rtwdev, REG_NAV_PROT_LEN, WLAN_NAV_PROT_LEN); |
180 | rtw_write16(rtwdev, REG_MAC_SPEC_SIFS, WLAN_SPEC_SIFS); |
181 | rtw_write16(rtwdev, REG_SIFS, WLAN_SPEC_SIFS); |
182 | rtw_write16(rtwdev, REG_SIFS + 2, WLAN_SPEC_SIFS); |
183 | rtw_write8(rtwdev, REG_SINGLE_AMPDU_CTRL, BIT_EN_SINGLE_APMDU); |
184 | rtw_write8(rtwdev, REG_RX_PKT_LIMIT, WLAN_RX_PKT_LIMIT); |
185 | rtw_write8(rtwdev, REG_MAX_AGGR_NUM, WLAN_MAX_AGG_NR); |
186 | rtw_write8(rtwdev, REG_AMPDU_MAX_TIME, WLAN_AMPDU_MAX_TIME); |
187 | rtw_write8(rtwdev, REG_LEDCFG2, WLAN_ANT_SEL); |
188 | |
189 | rtw_write32(rtwdev, REG_LTR_IDLE_LATENCY, WLAN_LTR_IDLE_LAT); |
190 | rtw_write32(rtwdev, REG_LTR_ACTIVE_LATENCY, WLAN_LTR_ACT_LAT); |
191 | rtw_write32(rtwdev, REG_LTR_CTRL_BASIC, WLAN_LTR_CTRL1); |
192 | rtw_write32(rtwdev, REG_LTR_CTRL_BASIC + 4, WLAN_LTR_CTRL2); |
193 | |
194 | rtw_phy_init(rtwdev); |
195 | rtwdev->dm_info.cck_pd_default = rtw_read8(rtwdev, REG_CSRATIO) & 0x1f; |
196 | |
197 | rtw_write16_set(rtwdev, REG_TXDMA_OFFSET_CHK, BIT_DROP_DATA_EN); |
198 | |
199 | rtw8723d_lck(rtwdev); |
200 | |
201 | rtw_write32_mask(rtwdev, REG_OFDM0_XAAGC1, MASKBYTE0, data: 0x50); |
202 | rtw_write32_mask(rtwdev, REG_OFDM0_XAAGC1, MASKBYTE0, data: 0x20); |
203 | |
204 | rtw8723d_pwrtrack_init(rtwdev); |
205 | } |
206 | |
207 | static void rtw8723de_efuse_parsing(struct rtw_efuse *efuse, |
208 | struct rtw8723d_efuse *map) |
209 | { |
210 | ether_addr_copy(dst: efuse->addr, src: map->e.mac_addr); |
211 | } |
212 | |
213 | static void rtw8723du_efuse_parsing(struct rtw_efuse *efuse, |
214 | struct rtw8723d_efuse *map) |
215 | { |
216 | ether_addr_copy(dst: efuse->addr, src: map->u.mac_addr); |
217 | } |
218 | |
219 | static void rtw8723ds_efuse_parsing(struct rtw_efuse *efuse, |
220 | struct rtw8723d_efuse *map) |
221 | { |
222 | ether_addr_copy(dst: efuse->addr, src: map->s.mac_addr); |
223 | } |
224 | |
225 | static int rtw8723d_read_efuse(struct rtw_dev *rtwdev, u8 *log_map) |
226 | { |
227 | struct rtw_efuse *efuse = &rtwdev->efuse; |
228 | struct rtw8723d_efuse *map; |
229 | int i; |
230 | |
231 | map = (struct rtw8723d_efuse *)log_map; |
232 | |
233 | efuse->rfe_option = 0; |
234 | efuse->rf_board_option = map->rf_board_option; |
235 | efuse->crystal_cap = map->xtal_k; |
236 | efuse->pa_type_2g = map->pa_type; |
237 | efuse->lna_type_2g = map->lna_type_2g[0]; |
238 | efuse->channel_plan = map->channel_plan; |
239 | efuse->country_code[0] = map->country_code[0]; |
240 | efuse->country_code[1] = map->country_code[1]; |
241 | efuse->bt_setting = map->rf_bt_setting; |
242 | efuse->regd = map->rf_board_option & 0x7; |
243 | efuse->thermal_meter[0] = map->thermal_meter; |
244 | efuse->thermal_meter_k = map->thermal_meter; |
245 | efuse->afe = map->afe; |
246 | |
247 | for (i = 0; i < 4; i++) |
248 | efuse->txpwr_idx_table[i] = map->txpwr_idx_table[i]; |
249 | |
250 | switch (rtw_hci_type(rtwdev)) { |
251 | case RTW_HCI_TYPE_PCIE: |
252 | rtw8723de_efuse_parsing(efuse, map); |
253 | break; |
254 | case RTW_HCI_TYPE_USB: |
255 | rtw8723du_efuse_parsing(efuse, map); |
256 | break; |
257 | case RTW_HCI_TYPE_SDIO: |
258 | rtw8723ds_efuse_parsing(efuse, map); |
259 | break; |
260 | default: |
261 | /* unsupported now */ |
262 | return -ENOTSUPP; |
263 | } |
264 | |
265 | return 0; |
266 | } |
267 | |
268 | static void query_phy_status_page0(struct rtw_dev *rtwdev, u8 *phy_status, |
269 | struct rtw_rx_pkt_stat *pkt_stat) |
270 | { |
271 | struct rtw_dm_info *dm_info = &rtwdev->dm_info; |
272 | s8 min_rx_power = -120; |
273 | u8 pwdb = GET_PHY_STAT_P0_PWDB(phy_status); |
274 | |
275 | pkt_stat->rx_power[RF_PATH_A] = pwdb - 97; |
276 | pkt_stat->rssi = rtw_phy_rf_power_2_rssi(rf_power: pkt_stat->rx_power, path_num: 1); |
277 | pkt_stat->bw = RTW_CHANNEL_WIDTH_20; |
278 | pkt_stat->signal_power = max(pkt_stat->rx_power[RF_PATH_A], |
279 | min_rx_power); |
280 | dm_info->rssi[RF_PATH_A] = pkt_stat->rssi; |
281 | } |
282 | |
283 | static void query_phy_status_page1(struct rtw_dev *rtwdev, u8 *phy_status, |
284 | struct rtw_rx_pkt_stat *pkt_stat) |
285 | { |
286 | struct rtw_dm_info *dm_info = &rtwdev->dm_info; |
287 | u8 rxsc, bw; |
288 | s8 min_rx_power = -120; |
289 | s8 rx_evm; |
290 | |
291 | if (pkt_stat->rate > DESC_RATE11M && pkt_stat->rate < DESC_RATEMCS0) |
292 | rxsc = GET_PHY_STAT_P1_L_RXSC(phy_status); |
293 | else |
294 | rxsc = GET_PHY_STAT_P1_HT_RXSC(phy_status); |
295 | |
296 | if (GET_PHY_STAT_P1_RF_MODE(phy_status) == 0) |
297 | bw = RTW_CHANNEL_WIDTH_20; |
298 | else if ((rxsc == 1) || (rxsc == 2)) |
299 | bw = RTW_CHANNEL_WIDTH_20; |
300 | else |
301 | bw = RTW_CHANNEL_WIDTH_40; |
302 | |
303 | pkt_stat->rx_power[RF_PATH_A] = GET_PHY_STAT_P1_PWDB_A(phy_status) - 110; |
304 | pkt_stat->rssi = rtw_phy_rf_power_2_rssi(rf_power: pkt_stat->rx_power, path_num: 1); |
305 | pkt_stat->bw = bw; |
306 | pkt_stat->signal_power = max(pkt_stat->rx_power[RF_PATH_A], |
307 | min_rx_power); |
308 | pkt_stat->rx_evm[RF_PATH_A] = GET_PHY_STAT_P1_RXEVM_A(phy_status); |
309 | pkt_stat->rx_snr[RF_PATH_A] = GET_PHY_STAT_P1_RXSNR_A(phy_status); |
310 | pkt_stat->cfo_tail[RF_PATH_A] = GET_PHY_STAT_P1_CFO_TAIL_A(phy_status); |
311 | |
312 | dm_info->curr_rx_rate = pkt_stat->rate; |
313 | dm_info->rssi[RF_PATH_A] = pkt_stat->rssi; |
314 | dm_info->rx_snr[RF_PATH_A] = pkt_stat->rx_snr[RF_PATH_A] >> 1; |
315 | dm_info->cfo_tail[RF_PATH_A] = (pkt_stat->cfo_tail[RF_PATH_A] * 5) >> 1; |
316 | |
317 | rx_evm = clamp_t(s8, -pkt_stat->rx_evm[RF_PATH_A] >> 1, 0, 64); |
318 | rx_evm &= 0x3F; /* 64->0: second path of 1SS rate is 64 */ |
319 | dm_info->rx_evm_dbm[RF_PATH_A] = rx_evm; |
320 | } |
321 | |
322 | static void query_phy_status(struct rtw_dev *rtwdev, u8 *phy_status, |
323 | struct rtw_rx_pkt_stat *pkt_stat) |
324 | { |
325 | u8 page; |
326 | |
327 | page = *phy_status & 0xf; |
328 | |
329 | switch (page) { |
330 | case 0: |
331 | query_phy_status_page0(rtwdev, phy_status, pkt_stat); |
332 | break; |
333 | case 1: |
334 | query_phy_status_page1(rtwdev, phy_status, pkt_stat); |
335 | break; |
336 | default: |
337 | rtw_warn(rtwdev, "unused phy status page (%d)\n" , page); |
338 | return; |
339 | } |
340 | } |
341 | |
342 | static void rtw8723d_query_rx_desc(struct rtw_dev *rtwdev, u8 *rx_desc, |
343 | struct rtw_rx_pkt_stat *pkt_stat, |
344 | struct ieee80211_rx_status *rx_status) |
345 | { |
346 | struct ieee80211_hdr *hdr; |
347 | u32 desc_sz = rtwdev->chip->rx_pkt_desc_sz; |
348 | u8 *phy_status = NULL; |
349 | |
350 | memset(pkt_stat, 0, sizeof(*pkt_stat)); |
351 | |
352 | pkt_stat->phy_status = GET_RX_DESC_PHYST(rx_desc); |
353 | pkt_stat->icv_err = GET_RX_DESC_ICV_ERR(rx_desc); |
354 | pkt_stat->crc_err = GET_RX_DESC_CRC32(rx_desc); |
355 | pkt_stat->decrypted = !GET_RX_DESC_SWDEC(rx_desc) && |
356 | GET_RX_DESC_ENC_TYPE(rx_desc) != RX_DESC_ENC_NONE; |
357 | pkt_stat->is_c2h = GET_RX_DESC_C2H(rx_desc); |
358 | pkt_stat->pkt_len = GET_RX_DESC_PKT_LEN(rx_desc); |
359 | pkt_stat->drv_info_sz = GET_RX_DESC_DRV_INFO_SIZE(rx_desc); |
360 | pkt_stat->shift = GET_RX_DESC_SHIFT(rx_desc); |
361 | pkt_stat->rate = GET_RX_DESC_RX_RATE(rx_desc); |
362 | pkt_stat->cam_id = GET_RX_DESC_MACID(rx_desc); |
363 | pkt_stat->ppdu_cnt = 0; |
364 | pkt_stat->tsf_low = GET_RX_DESC_TSFL(rx_desc); |
365 | |
366 | /* drv_info_sz is in unit of 8-bytes */ |
367 | pkt_stat->drv_info_sz *= 8; |
368 | |
369 | /* c2h cmd pkt's rx/phy status is not interested */ |
370 | if (pkt_stat->is_c2h) |
371 | return; |
372 | |
373 | hdr = (struct ieee80211_hdr *)(rx_desc + desc_sz + pkt_stat->shift + |
374 | pkt_stat->drv_info_sz); |
375 | if (pkt_stat->phy_status) { |
376 | phy_status = rx_desc + desc_sz + pkt_stat->shift; |
377 | query_phy_status(rtwdev, phy_status, pkt_stat); |
378 | } |
379 | |
380 | rtw_rx_fill_rx_status(rtwdev, pkt_stat, hdr, rx_status, phy_status); |
381 | } |
382 | |
383 | static bool rtw8723d_check_spur_ov_thres(struct rtw_dev *rtwdev, |
384 | u8 channel, u32 thres) |
385 | { |
386 | u32 freq; |
387 | bool ret = false; |
388 | |
389 | if (channel == 13) |
390 | freq = FREQ_CH13; |
391 | else if (channel == 14) |
392 | freq = FREQ_CH14; |
393 | else |
394 | return false; |
395 | |
396 | rtw_write32(rtwdev, REG_ANALOG_P4, DIS_3WIRE); |
397 | rtw_write32(rtwdev, REG_PSDFN, val: freq); |
398 | rtw_write32(rtwdev, REG_PSDFN, START_PSD | freq); |
399 | |
400 | msleep(msecs: 30); |
401 | if (rtw_read32(rtwdev, REG_PSDRPT) >= thres) |
402 | ret = true; |
403 | |
404 | rtw_write32(rtwdev, REG_PSDFN, val: freq); |
405 | rtw_write32(rtwdev, REG_ANALOG_P4, EN_3WIRE); |
406 | |
407 | return ret; |
408 | } |
409 | |
410 | static void rtw8723d_cfg_notch(struct rtw_dev *rtwdev, u8 channel, bool notch) |
411 | { |
412 | if (!notch) { |
413 | rtw_write32_mask(rtwdev, REG_OFDM0_RXDSP, BIT_MASK_RXDSP, data: 0x1f); |
414 | rtw_write32_mask(rtwdev, REG_OFDM0_RXDSP, BIT_EN_RXDSP, data: 0x0); |
415 | rtw_write32(rtwdev, REG_OFDM1_CSI1, val: 0x00000000); |
416 | rtw_write32(rtwdev, REG_OFDM1_CSI2, val: 0x00000000); |
417 | rtw_write32(rtwdev, REG_OFDM1_CSI3, val: 0x00000000); |
418 | rtw_write32(rtwdev, REG_OFDM1_CSI4, val: 0x00000000); |
419 | rtw_write32_mask(rtwdev, REG_OFDM1_CFOTRK, BIT_EN_CFOTRK, data: 0x0); |
420 | return; |
421 | } |
422 | |
423 | switch (channel) { |
424 | case 13: |
425 | rtw_write32_mask(rtwdev, REG_OFDM0_RXDSP, BIT_MASK_RXDSP, data: 0xb); |
426 | rtw_write32_mask(rtwdev, REG_OFDM0_RXDSP, BIT_EN_RXDSP, data: 0x1); |
427 | rtw_write32(rtwdev, REG_OFDM1_CSI1, val: 0x04000000); |
428 | rtw_write32(rtwdev, REG_OFDM1_CSI2, val: 0x00000000); |
429 | rtw_write32(rtwdev, REG_OFDM1_CSI3, val: 0x00000000); |
430 | rtw_write32(rtwdev, REG_OFDM1_CSI4, val: 0x00000000); |
431 | rtw_write32_mask(rtwdev, REG_OFDM1_CFOTRK, BIT_EN_CFOTRK, data: 0x1); |
432 | break; |
433 | case 14: |
434 | rtw_write32_mask(rtwdev, REG_OFDM0_RXDSP, BIT_MASK_RXDSP, data: 0x5); |
435 | rtw_write32_mask(rtwdev, REG_OFDM0_RXDSP, BIT_EN_RXDSP, data: 0x1); |
436 | rtw_write32(rtwdev, REG_OFDM1_CSI1, val: 0x00000000); |
437 | rtw_write32(rtwdev, REG_OFDM1_CSI2, val: 0x00000000); |
438 | rtw_write32(rtwdev, REG_OFDM1_CSI3, val: 0x00000000); |
439 | rtw_write32(rtwdev, REG_OFDM1_CSI4, val: 0x00080000); |
440 | rtw_write32_mask(rtwdev, REG_OFDM1_CFOTRK, BIT_EN_CFOTRK, data: 0x1); |
441 | break; |
442 | default: |
443 | rtw_write32_mask(rtwdev, REG_OFDM0_RXDSP, BIT_EN_RXDSP, data: 0x0); |
444 | rtw_write32_mask(rtwdev, REG_OFDM1_CFOTRK, BIT_EN_CFOTRK, data: 0x0); |
445 | break; |
446 | } |
447 | } |
448 | |
449 | static void rtw8723d_spur_cal(struct rtw_dev *rtwdev, u8 channel) |
450 | { |
451 | bool notch; |
452 | |
453 | if (channel < 13) { |
454 | rtw8723d_cfg_notch(rtwdev, channel, notch: false); |
455 | return; |
456 | } |
457 | |
458 | notch = rtw8723d_check_spur_ov_thres(rtwdev, channel, SPUR_THRES); |
459 | rtw8723d_cfg_notch(rtwdev, channel, notch); |
460 | } |
461 | |
462 | static void rtw8723d_set_channel_rf(struct rtw_dev *rtwdev, u8 channel, u8 bw) |
463 | { |
464 | u32 rf_cfgch_a, rf_cfgch_b; |
465 | |
466 | rf_cfgch_a = rtw_read_rf(rtwdev, rf_path: RF_PATH_A, RF_CFGCH, RFREG_MASK); |
467 | rf_cfgch_b = rtw_read_rf(rtwdev, rf_path: RF_PATH_B, RF_CFGCH, RFREG_MASK); |
468 | |
469 | rf_cfgch_a &= ~RFCFGCH_CHANNEL_MASK; |
470 | rf_cfgch_b &= ~RFCFGCH_CHANNEL_MASK; |
471 | rf_cfgch_a |= (channel & RFCFGCH_CHANNEL_MASK); |
472 | rf_cfgch_b |= (channel & RFCFGCH_CHANNEL_MASK); |
473 | |
474 | rf_cfgch_a &= ~RFCFGCH_BW_MASK; |
475 | switch (bw) { |
476 | case RTW_CHANNEL_WIDTH_20: |
477 | rf_cfgch_a |= RFCFGCH_BW_20M; |
478 | break; |
479 | case RTW_CHANNEL_WIDTH_40: |
480 | rf_cfgch_a |= RFCFGCH_BW_40M; |
481 | break; |
482 | default: |
483 | break; |
484 | } |
485 | |
486 | rtw_write_rf(rtwdev, rf_path: RF_PATH_A, RF_CFGCH, RFREG_MASK, data: rf_cfgch_a); |
487 | rtw_write_rf(rtwdev, rf_path: RF_PATH_B, RF_CFGCH, RFREG_MASK, data: rf_cfgch_b); |
488 | |
489 | rtw8723d_spur_cal(rtwdev, channel); |
490 | } |
491 | |
492 | static const struct rtw_backup_info cck_dfir_cfg[][CCK_DFIR_NR] = { |
493 | [0] = { |
494 | { .len = 4, .reg = 0xA24, .val = 0x64B80C1C }, |
495 | { .len = 4, .reg = 0xA28, .val = 0x00008810 }, |
496 | { .len = 4, .reg = 0xAAC, .val = 0x01235667 }, |
497 | }, |
498 | [1] = { |
499 | { .len = 4, .reg = 0xA24, .val = 0x0000B81C }, |
500 | { .len = 4, .reg = 0xA28, .val = 0x00000000 }, |
501 | { .len = 4, .reg = 0xAAC, .val = 0x00003667 }, |
502 | }, |
503 | }; |
504 | |
505 | static void rtw8723d_set_channel_bb(struct rtw_dev *rtwdev, u8 channel, u8 bw, |
506 | u8 primary_ch_idx) |
507 | { |
508 | const struct rtw_backup_info *cck_dfir; |
509 | int i; |
510 | |
511 | cck_dfir = channel <= 13 ? cck_dfir_cfg[0] : cck_dfir_cfg[1]; |
512 | |
513 | for (i = 0; i < CCK_DFIR_NR; i++, cck_dfir++) |
514 | rtw_write32(rtwdev, addr: cck_dfir->reg, val: cck_dfir->val); |
515 | |
516 | switch (bw) { |
517 | case RTW_CHANNEL_WIDTH_20: |
518 | rtw_write32_mask(rtwdev, REG_FPGA0_RFMOD, BIT_MASK_RFMOD, data: 0x0); |
519 | rtw_write32_mask(rtwdev, REG_FPGA1_RFMOD, BIT_MASK_RFMOD, data: 0x0); |
520 | rtw_write32_mask(rtwdev, REG_BBRX_DFIR, BIT_RXBB_DFIR_EN, data: 1); |
521 | rtw_write32_mask(rtwdev, REG_BBRX_DFIR, BIT_MASK_RXBB_DFIR, data: 0xa); |
522 | break; |
523 | case RTW_CHANNEL_WIDTH_40: |
524 | rtw_write32_mask(rtwdev, REG_FPGA0_RFMOD, BIT_MASK_RFMOD, data: 0x1); |
525 | rtw_write32_mask(rtwdev, REG_FPGA1_RFMOD, BIT_MASK_RFMOD, data: 0x1); |
526 | rtw_write32_mask(rtwdev, REG_BBRX_DFIR, BIT_RXBB_DFIR_EN, data: 0); |
527 | rtw_write32_mask(rtwdev, REG_CCK0_SYS, BIT_CCK_SIDE_BAND, |
528 | data: (primary_ch_idx == RTW_SC_20_UPPER ? 1 : 0)); |
529 | break; |
530 | default: |
531 | break; |
532 | } |
533 | } |
534 | |
535 | static void rtw8723d_set_channel(struct rtw_dev *rtwdev, u8 channel, u8 bw, |
536 | u8 primary_chan_idx) |
537 | { |
538 | rtw8723d_set_channel_rf(rtwdev, channel, bw); |
539 | rtw_set_channel_mac(rtwdev, channel, bw, primary_ch_idx: primary_chan_idx); |
540 | rtw8723d_set_channel_bb(rtwdev, channel, bw, primary_ch_idx: primary_chan_idx); |
541 | } |
542 | |
543 | #define BIT_CFENDFORM BIT(9) |
544 | #define BIT_WMAC_TCR_ERR0 BIT(12) |
545 | #define BIT_WMAC_TCR_ERR1 BIT(13) |
546 | #define BIT_TCR_CFG (BIT_CFENDFORM | BIT_WMAC_TCR_ERR0 | \ |
547 | BIT_WMAC_TCR_ERR1) |
548 | #define WLAN_RX_FILTER0 0xFFFF |
549 | #define WLAN_RX_FILTER1 0x400 |
550 | #define WLAN_RX_FILTER2 0xFFFF |
551 | #define WLAN_RCR_CFG 0x700060CE |
552 | |
553 | static int rtw8723d_mac_init(struct rtw_dev *rtwdev) |
554 | { |
555 | rtw_write8(rtwdev, REG_FWHW_TXQ_CTRL + 1, WLAN_TXQ_RPT_EN); |
556 | rtw_write32(rtwdev, REG_TCR, BIT_TCR_CFG); |
557 | |
558 | rtw_write16(rtwdev, REG_RXFLTMAP0, WLAN_RX_FILTER0); |
559 | rtw_write16(rtwdev, REG_RXFLTMAP1, WLAN_RX_FILTER1); |
560 | rtw_write16(rtwdev, REG_RXFLTMAP2, WLAN_RX_FILTER2); |
561 | rtw_write32(rtwdev, REG_RCR, WLAN_RCR_CFG); |
562 | |
563 | rtw_write32(rtwdev, REG_INT_MIG, val: 0); |
564 | rtw_write32(rtwdev, REG_MCUTST_1, val: 0x0); |
565 | |
566 | rtw_write8(rtwdev, REG_MISC_CTRL, BIT_DIS_SECOND_CCA); |
567 | rtw_write8(rtwdev, REG_2ND_CCA_CTRL, val: 0); |
568 | |
569 | return 0; |
570 | } |
571 | |
572 | static void rtw8723d_shutdown(struct rtw_dev *rtwdev) |
573 | { |
574 | rtw_write16_set(rtwdev, REG_HCI_OPT_CTRL, BIT_USB_SUS_DIS); |
575 | } |
576 | |
577 | static void rtw8723d_cfg_ldo25(struct rtw_dev *rtwdev, bool enable) |
578 | { |
579 | u8 ldo_pwr; |
580 | |
581 | ldo_pwr = rtw_read8(rtwdev, REG_LDO_EFUSE_CTRL + 3); |
582 | if (enable) { |
583 | ldo_pwr &= ~BIT_MASK_LDO25_VOLTAGE; |
584 | ldo_pwr |= (BIT_LDO25_VOLTAGE_V25 << 4) | BIT_LDO25_EN; |
585 | } else { |
586 | ldo_pwr &= ~BIT_LDO25_EN; |
587 | } |
588 | rtw_write8(rtwdev, REG_LDO_EFUSE_CTRL + 3, val: ldo_pwr); |
589 | } |
590 | |
591 | static void |
592 | rtw8723d_set_tx_power_index_by_rate(struct rtw_dev *rtwdev, u8 path, u8 rs) |
593 | { |
594 | struct rtw_hal *hal = &rtwdev->hal; |
595 | const struct rtw_hw_reg *txagc; |
596 | u8 rate, pwr_index; |
597 | int j; |
598 | |
599 | for (j = 0; j < rtw_rate_size[rs]; j++) { |
600 | rate = rtw_rate_section[rs][j]; |
601 | pwr_index = hal->tx_pwr_tbl[path][rate]; |
602 | |
603 | if (rate >= ARRAY_SIZE(rtw8723d_txagc)) { |
604 | rtw_warn(rtwdev, "rate 0x%x isn't supported\n" , rate); |
605 | continue; |
606 | } |
607 | txagc = &rtw8723d_txagc[rate]; |
608 | if (!txagc->addr) { |
609 | rtw_warn(rtwdev, "rate 0x%x isn't defined\n" , rate); |
610 | continue; |
611 | } |
612 | |
613 | rtw_write32_mask(rtwdev, addr: txagc->addr, mask: txagc->mask, data: pwr_index); |
614 | } |
615 | } |
616 | |
617 | static void rtw8723d_set_tx_power_index(struct rtw_dev *rtwdev) |
618 | { |
619 | struct rtw_hal *hal = &rtwdev->hal; |
620 | int rs, path; |
621 | |
622 | for (path = 0; path < hal->rf_path_num; path++) { |
623 | for (rs = 0; rs <= RTW_RATE_SECTION_HT_1S; rs++) |
624 | rtw8723d_set_tx_power_index_by_rate(rtwdev, path, rs); |
625 | } |
626 | } |
627 | |
628 | static void rtw8723d_efuse_grant(struct rtw_dev *rtwdev, bool on) |
629 | { |
630 | if (on) { |
631 | rtw_write8(rtwdev, REG_EFUSE_ACCESS, EFUSE_ACCESS_ON); |
632 | |
633 | rtw_write16_set(rtwdev, REG_SYS_FUNC_EN, BIT_FEN_ELDR); |
634 | rtw_write16_set(rtwdev, REG_SYS_CLKR, BIT_LOADER_CLK_EN | BIT_ANA8M); |
635 | } else { |
636 | rtw_write8(rtwdev, REG_EFUSE_ACCESS, EFUSE_ACCESS_OFF); |
637 | } |
638 | } |
639 | |
640 | static void rtw8723d_false_alarm_statistics(struct rtw_dev *rtwdev) |
641 | { |
642 | struct rtw_dm_info *dm_info = &rtwdev->dm_info; |
643 | u32 cck_fa_cnt; |
644 | u32 ofdm_fa_cnt; |
645 | u32 crc32_cnt; |
646 | u32 val32; |
647 | |
648 | /* hold counter */ |
649 | rtw_write32_mask(rtwdev, REG_OFDM_FA_HOLDC_11N, BIT_MASK_OFDM_FA_KEEP, data: 1); |
650 | rtw_write32_mask(rtwdev, REG_OFDM_FA_RSTD_11N, BIT_MASK_OFDM_FA_KEEP1, data: 1); |
651 | rtw_write32_mask(rtwdev, REG_CCK_FA_RST_11N, BIT_MASK_CCK_CNT_KEEP, data: 1); |
652 | rtw_write32_mask(rtwdev, REG_CCK_FA_RST_11N, BIT_MASK_CCK_FA_KEEP, data: 1); |
653 | |
654 | cck_fa_cnt = rtw_read32_mask(rtwdev, REG_CCK_FA_LSB_11N, MASKBYTE0); |
655 | cck_fa_cnt += rtw_read32_mask(rtwdev, REG_CCK_FA_MSB_11N, MASKBYTE3) << 8; |
656 | |
657 | val32 = rtw_read32(rtwdev, REG_OFDM_FA_TYPE1_11N); |
658 | ofdm_fa_cnt = u32_get_bits(v: val32, BIT_MASK_OFDM_FF_CNT); |
659 | ofdm_fa_cnt += u32_get_bits(v: val32, BIT_MASK_OFDM_SF_CNT); |
660 | val32 = rtw_read32(rtwdev, REG_OFDM_FA_TYPE2_11N); |
661 | dm_info->ofdm_cca_cnt = u32_get_bits(v: val32, BIT_MASK_OFDM_CCA_CNT); |
662 | ofdm_fa_cnt += u32_get_bits(v: val32, BIT_MASK_OFDM_PF_CNT); |
663 | val32 = rtw_read32(rtwdev, REG_OFDM_FA_TYPE3_11N); |
664 | ofdm_fa_cnt += u32_get_bits(v: val32, BIT_MASK_OFDM_RI_CNT); |
665 | ofdm_fa_cnt += u32_get_bits(v: val32, BIT_MASK_OFDM_CRC_CNT); |
666 | val32 = rtw_read32(rtwdev, REG_OFDM_FA_TYPE4_11N); |
667 | ofdm_fa_cnt += u32_get_bits(v: val32, BIT_MASK_OFDM_MNS_CNT); |
668 | |
669 | dm_info->cck_fa_cnt = cck_fa_cnt; |
670 | dm_info->ofdm_fa_cnt = ofdm_fa_cnt; |
671 | dm_info->total_fa_cnt = cck_fa_cnt + ofdm_fa_cnt; |
672 | |
673 | dm_info->cck_err_cnt = rtw_read32(rtwdev, REG_IGI_C_11N); |
674 | dm_info->cck_ok_cnt = rtw_read32(rtwdev, REG_IGI_D_11N); |
675 | crc32_cnt = rtw_read32(rtwdev, REG_OFDM_CRC32_CNT_11N); |
676 | dm_info->ofdm_err_cnt = u32_get_bits(v: crc32_cnt, BIT_MASK_OFDM_LCRC_ERR); |
677 | dm_info->ofdm_ok_cnt = u32_get_bits(v: crc32_cnt, BIT_MASK_OFDM_LCRC_OK); |
678 | crc32_cnt = rtw_read32(rtwdev, REG_HT_CRC32_CNT_11N); |
679 | dm_info->ht_err_cnt = u32_get_bits(v: crc32_cnt, BIT_MASK_HT_CRC_ERR); |
680 | dm_info->ht_ok_cnt = u32_get_bits(v: crc32_cnt, BIT_MASK_HT_CRC_OK); |
681 | dm_info->vht_err_cnt = 0; |
682 | dm_info->vht_ok_cnt = 0; |
683 | |
684 | val32 = rtw_read32(rtwdev, REG_CCK_CCA_CNT_11N); |
685 | dm_info->cck_cca_cnt = (u32_get_bits(v: val32, BIT_MASK_CCK_FA_MSB) << 8) | |
686 | u32_get_bits(v: val32, BIT_MASK_CCK_FA_LSB); |
687 | dm_info->total_cca_cnt = dm_info->cck_cca_cnt + dm_info->ofdm_cca_cnt; |
688 | |
689 | /* reset counter */ |
690 | rtw_write32_mask(rtwdev, REG_OFDM_FA_RSTC_11N, BIT_MASK_OFDM_FA_RST, data: 1); |
691 | rtw_write32_mask(rtwdev, REG_OFDM_FA_RSTC_11N, BIT_MASK_OFDM_FA_RST, data: 0); |
692 | rtw_write32_mask(rtwdev, REG_OFDM_FA_RSTD_11N, BIT_MASK_OFDM_FA_RST1, data: 1); |
693 | rtw_write32_mask(rtwdev, REG_OFDM_FA_RSTD_11N, BIT_MASK_OFDM_FA_RST1, data: 0); |
694 | rtw_write32_mask(rtwdev, REG_OFDM_FA_HOLDC_11N, BIT_MASK_OFDM_FA_KEEP, data: 0); |
695 | rtw_write32_mask(rtwdev, REG_OFDM_FA_RSTD_11N, BIT_MASK_OFDM_FA_KEEP1, data: 0); |
696 | rtw_write32_mask(rtwdev, REG_CCK_FA_RST_11N, BIT_MASK_CCK_CNT_KPEN, data: 0); |
697 | rtw_write32_mask(rtwdev, REG_CCK_FA_RST_11N, BIT_MASK_CCK_CNT_KPEN, data: 2); |
698 | rtw_write32_mask(rtwdev, REG_CCK_FA_RST_11N, BIT_MASK_CCK_FA_KPEN, data: 0); |
699 | rtw_write32_mask(rtwdev, REG_CCK_FA_RST_11N, BIT_MASK_CCK_FA_KPEN, data: 2); |
700 | rtw_write32_mask(rtwdev, REG_PAGE_F_RST_11N, BIT_MASK_F_RST_ALL, data: 1); |
701 | rtw_write32_mask(rtwdev, REG_PAGE_F_RST_11N, BIT_MASK_F_RST_ALL, data: 0); |
702 | } |
703 | |
704 | static const u32 iqk_adda_regs[] = { |
705 | 0x85c, 0xe6c, 0xe70, 0xe74, 0xe78, 0xe7c, 0xe80, 0xe84, 0xe88, 0xe8c, |
706 | 0xed0, 0xed4, 0xed8, 0xedc, 0xee0, 0xeec |
707 | }; |
708 | |
709 | static const u32 iqk_mac8_regs[] = {0x522, 0x550, 0x551}; |
710 | static const u32 iqk_mac32_regs[] = {0x40}; |
711 | |
712 | static const u32 iqk_bb_regs[] = { |
713 | 0xc04, 0xc08, 0x874, 0xb68, 0xb6c, 0x870, 0x860, 0x864, 0xa04 |
714 | }; |
715 | |
716 | #define IQK_ADDA_REG_NUM ARRAY_SIZE(iqk_adda_regs) |
717 | #define IQK_MAC8_REG_NUM ARRAY_SIZE(iqk_mac8_regs) |
718 | #define IQK_MAC32_REG_NUM ARRAY_SIZE(iqk_mac32_regs) |
719 | #define IQK_BB_REG_NUM ARRAY_SIZE(iqk_bb_regs) |
720 | |
721 | struct iqk_backup_regs { |
722 | u32 adda[IQK_ADDA_REG_NUM]; |
723 | u8 mac8[IQK_MAC8_REG_NUM]; |
724 | u32 mac32[IQK_MAC32_REG_NUM]; |
725 | u32 bb[IQK_BB_REG_NUM]; |
726 | |
727 | u32 lte_path; |
728 | u32 lte_gnt; |
729 | |
730 | u32 bb_sel_btg; |
731 | u8 btg_sel; |
732 | |
733 | u8 igia; |
734 | u8 igib; |
735 | }; |
736 | |
737 | static void rtw8723d_iqk_backup_regs(struct rtw_dev *rtwdev, |
738 | struct iqk_backup_regs *backup) |
739 | { |
740 | int i; |
741 | |
742 | for (i = 0; i < IQK_ADDA_REG_NUM; i++) |
743 | backup->adda[i] = rtw_read32(rtwdev, addr: iqk_adda_regs[i]); |
744 | |
745 | for (i = 0; i < IQK_MAC8_REG_NUM; i++) |
746 | backup->mac8[i] = rtw_read8(rtwdev, addr: iqk_mac8_regs[i]); |
747 | for (i = 0; i < IQK_MAC32_REG_NUM; i++) |
748 | backup->mac32[i] = rtw_read32(rtwdev, addr: iqk_mac32_regs[i]); |
749 | |
750 | for (i = 0; i < IQK_BB_REG_NUM; i++) |
751 | backup->bb[i] = rtw_read32(rtwdev, addr: iqk_bb_regs[i]); |
752 | |
753 | backup->igia = rtw_read32_mask(rtwdev, REG_OFDM0_XAAGC1, MASKBYTE0); |
754 | backup->igib = rtw_read32_mask(rtwdev, REG_OFDM0_XBAGC1, MASKBYTE0); |
755 | |
756 | backup->bb_sel_btg = rtw_read32(rtwdev, REG_BB_SEL_BTG); |
757 | } |
758 | |
759 | static void rtw8723d_iqk_restore_regs(struct rtw_dev *rtwdev, |
760 | const struct iqk_backup_regs *backup) |
761 | { |
762 | int i; |
763 | |
764 | for (i = 0; i < IQK_ADDA_REG_NUM; i++) |
765 | rtw_write32(rtwdev, addr: iqk_adda_regs[i], val: backup->adda[i]); |
766 | |
767 | for (i = 0; i < IQK_MAC8_REG_NUM; i++) |
768 | rtw_write8(rtwdev, addr: iqk_mac8_regs[i], val: backup->mac8[i]); |
769 | for (i = 0; i < IQK_MAC32_REG_NUM; i++) |
770 | rtw_write32(rtwdev, addr: iqk_mac32_regs[i], val: backup->mac32[i]); |
771 | |
772 | for (i = 0; i < IQK_BB_REG_NUM; i++) |
773 | rtw_write32(rtwdev, addr: iqk_bb_regs[i], val: backup->bb[i]); |
774 | |
775 | rtw_write32_mask(rtwdev, REG_OFDM0_XAAGC1, MASKBYTE0, data: 0x50); |
776 | rtw_write32_mask(rtwdev, REG_OFDM0_XAAGC1, MASKBYTE0, data: backup->igia); |
777 | |
778 | rtw_write32_mask(rtwdev, REG_OFDM0_XBAGC1, MASKBYTE0, data: 0x50); |
779 | rtw_write32_mask(rtwdev, REG_OFDM0_XBAGC1, MASKBYTE0, data: backup->igib); |
780 | |
781 | rtw_write32(rtwdev, REG_TXIQK_TONE_A_11N, val: 0x01008c00); |
782 | rtw_write32(rtwdev, REG_RXIQK_TONE_A_11N, val: 0x01008c00); |
783 | } |
784 | |
785 | static void rtw8723d_iqk_backup_path_ctrl(struct rtw_dev *rtwdev, |
786 | struct iqk_backup_regs *backup) |
787 | { |
788 | backup->btg_sel = rtw_read8(rtwdev, REG_BTG_SEL); |
789 | rtw_dbg(rtwdev, mask: RTW_DBG_RFK, fmt: "[IQK] original 0x67 = 0x%x\n" , |
790 | backup->btg_sel); |
791 | } |
792 | |
793 | static void rtw8723d_iqk_config_path_ctrl(struct rtw_dev *rtwdev) |
794 | { |
795 | rtw_write32_mask(rtwdev, REG_PAD_CTRL1, BIT_BT_BTG_SEL, data: 0x1); |
796 | rtw_dbg(rtwdev, mask: RTW_DBG_RFK, fmt: "[IQK] set 0x67 = 0x%x\n" , |
797 | rtw_read32_mask(rtwdev, REG_PAD_CTRL1, MASKBYTE3)); |
798 | } |
799 | |
800 | static void rtw8723d_iqk_restore_path_ctrl(struct rtw_dev *rtwdev, |
801 | const struct iqk_backup_regs *backup) |
802 | { |
803 | rtw_write8(rtwdev, REG_BTG_SEL, val: backup->btg_sel); |
804 | rtw_dbg(rtwdev, mask: RTW_DBG_RFK, fmt: "[IQK] restore 0x67 = 0x%x\n" , |
805 | rtw_read32_mask(rtwdev, REG_PAD_CTRL1, MASKBYTE3)); |
806 | } |
807 | |
808 | static void rtw8723d_iqk_backup_lte_path_gnt(struct rtw_dev *rtwdev, |
809 | struct iqk_backup_regs *backup) |
810 | { |
811 | backup->lte_path = rtw_read32(rtwdev, REG_LTECOEX_PATH_CONTROL); |
812 | rtw_write32(rtwdev, REG_LTECOEX_CTRL, val: 0x800f0038); |
813 | mdelay(1); |
814 | backup->lte_gnt = rtw_read32(rtwdev, REG_LTECOEX_READ_DATA); |
815 | rtw_dbg(rtwdev, mask: RTW_DBG_RFK, fmt: "[IQK] OriginalGNT = 0x%x\n" , |
816 | backup->lte_gnt); |
817 | } |
818 | |
819 | static void rtw8723d_iqk_config_lte_path_gnt(struct rtw_dev *rtwdev) |
820 | { |
821 | rtw_write32(rtwdev, REG_LTECOEX_WRITE_DATA, val: 0x0000ff00); |
822 | rtw_write32(rtwdev, REG_LTECOEX_CTRL, val: 0xc0020038); |
823 | rtw_write32_mask(rtwdev, REG_LTECOEX_PATH_CONTROL, BIT_LTE_MUX_CTRL_PATH, data: 0x1); |
824 | } |
825 | |
826 | static void rtw8723d_iqk_restore_lte_path_gnt(struct rtw_dev *rtwdev, |
827 | const struct iqk_backup_regs *bak) |
828 | { |
829 | rtw_write32(rtwdev, REG_LTECOEX_WRITE_DATA, val: bak->lte_gnt); |
830 | rtw_write32(rtwdev, REG_LTECOEX_CTRL, val: 0xc00f0038); |
831 | rtw_write32(rtwdev, REG_LTECOEX_PATH_CONTROL, val: bak->lte_path); |
832 | } |
833 | |
834 | struct rtw_8723d_iqk_cfg { |
835 | const char *name; |
836 | u32 val_bb_sel_btg; |
837 | u32 reg_lutwe; |
838 | u32 val_txiqk_pi; |
839 | u32 reg_padlut; |
840 | u32 reg_gaintx; |
841 | u32 reg_bspad; |
842 | u32 val_wlint; |
843 | u32 val_wlsel; |
844 | u32 val_iqkpts; |
845 | }; |
846 | |
847 | static const struct rtw_8723d_iqk_cfg iqk_tx_cfg[PATH_NR] = { |
848 | [PATH_S1] = { |
849 | .name = "S1" , |
850 | .val_bb_sel_btg = 0x99000000, |
851 | .reg_lutwe = RF_LUTWE, |
852 | .val_txiqk_pi = 0x8214019f, |
853 | .reg_padlut = RF_LUTDBG, |
854 | .reg_gaintx = RF_GAINTX, |
855 | .reg_bspad = RF_BSPAD, |
856 | .val_wlint = 0xe0d, |
857 | .val_wlsel = 0x60d, |
858 | .val_iqkpts = 0xfa000000, |
859 | }, |
860 | [PATH_S0] = { |
861 | .name = "S0" , |
862 | .val_bb_sel_btg = 0x99000280, |
863 | .reg_lutwe = RF_LUTWE2, |
864 | .val_txiqk_pi = 0x8214018a, |
865 | .reg_padlut = RF_TXADBG, |
866 | .reg_gaintx = RF_TRXIQ, |
867 | .reg_bspad = RF_TXATANK, |
868 | .val_wlint = 0xe6d, |
869 | .val_wlsel = 0x66d, |
870 | .val_iqkpts = 0xf9000000, |
871 | }, |
872 | }; |
873 | |
874 | static u8 rtw8723d_iqk_check_tx_failed(struct rtw_dev *rtwdev, |
875 | const struct rtw_8723d_iqk_cfg *iqk_cfg) |
876 | { |
877 | s32 tx_x, tx_y; |
878 | u32 tx_fail; |
879 | |
880 | rtw_dbg(rtwdev, mask: RTW_DBG_RFK, fmt: "[IQK] 0xeac = 0x%x\n" , |
881 | rtw_read32(rtwdev, REG_IQK_RES_RY)); |
882 | rtw_dbg(rtwdev, mask: RTW_DBG_RFK, fmt: "[IQK] 0xe94 = 0x%x, 0xe9c = 0x%x\n" , |
883 | rtw_read32(rtwdev, REG_IQK_RES_TX), |
884 | rtw_read32(rtwdev, REG_IQK_RES_TY)); |
885 | rtw_dbg(rtwdev, mask: RTW_DBG_RFK, |
886 | fmt: "[IQK] 0xe90(before IQK)= 0x%x, 0xe98(afer IQK) = 0x%x\n" , |
887 | rtw_read32(rtwdev, addr: 0xe90), |
888 | rtw_read32(rtwdev, addr: 0xe98)); |
889 | |
890 | tx_fail = rtw_read32_mask(rtwdev, REG_IQK_RES_RY, BIT_IQK_TX_FAIL); |
891 | tx_x = rtw_read32_mask(rtwdev, REG_IQK_RES_TX, BIT_MASK_RES_TX); |
892 | tx_y = rtw_read32_mask(rtwdev, REG_IQK_RES_TY, BIT_MASK_RES_TY); |
893 | |
894 | if (!tx_fail && tx_x != IQK_TX_X_ERR && tx_y != IQK_TX_Y_ERR) |
895 | return IQK_TX_OK; |
896 | |
897 | rtw_dbg(rtwdev, mask: RTW_DBG_RFK, fmt: "[IQK] %s TXIQK is failed\n" , |
898 | iqk_cfg->name); |
899 | |
900 | return 0; |
901 | } |
902 | |
903 | static u8 rtw8723d_iqk_check_rx_failed(struct rtw_dev *rtwdev, |
904 | const struct rtw_8723d_iqk_cfg *iqk_cfg) |
905 | { |
906 | s32 rx_x, rx_y; |
907 | u32 rx_fail; |
908 | |
909 | rtw_dbg(rtwdev, mask: RTW_DBG_RFK, fmt: "[IQK] 0xea4 = 0x%x, 0xeac = 0x%x\n" , |
910 | rtw_read32(rtwdev, REG_IQK_RES_RX), |
911 | rtw_read32(rtwdev, REG_IQK_RES_RY)); |
912 | |
913 | rtw_dbg(rtwdev, mask: RTW_DBG_RFK, |
914 | fmt: "[IQK] 0xea0(before IQK)= 0x%x, 0xea8(afer IQK) = 0x%x\n" , |
915 | rtw_read32(rtwdev, addr: 0xea0), |
916 | rtw_read32(rtwdev, addr: 0xea8)); |
917 | |
918 | rx_fail = rtw_read32_mask(rtwdev, REG_IQK_RES_RY, BIT_IQK_RX_FAIL); |
919 | rx_x = rtw_read32_mask(rtwdev, REG_IQK_RES_RX, BIT_MASK_RES_RX); |
920 | rx_y = rtw_read32_mask(rtwdev, REG_IQK_RES_RY, BIT_MASK_RES_RY); |
921 | rx_y = abs(iqkxy_to_s32(rx_y)); |
922 | |
923 | if (!rx_fail && rx_x < IQK_RX_X_UPPER && rx_x > IQK_RX_X_LOWER && |
924 | rx_y < IQK_RX_Y_LMT) |
925 | return IQK_RX_OK; |
926 | |
927 | rtw_dbg(rtwdev, mask: RTW_DBG_RFK, fmt: "[IQK] %s RXIQK STEP2 is failed\n" , |
928 | iqk_cfg->name); |
929 | |
930 | return 0; |
931 | } |
932 | |
933 | static void rtw8723d_iqk_one_shot(struct rtw_dev *rtwdev, bool tx, |
934 | const struct rtw_8723d_iqk_cfg *iqk_cfg) |
935 | { |
936 | u32 pts = (tx ? iqk_cfg->val_iqkpts : 0xf9000000); |
937 | |
938 | /* enter IQK mode */ |
939 | rtw_write32_mask(rtwdev, REG_FPGA0_IQK_11N, BIT_MASK_IQK_MOD, EN_IQK); |
940 | rtw8723d_iqk_config_lte_path_gnt(rtwdev); |
941 | |
942 | rtw_write32(rtwdev, REG_LTECOEX_CTRL, val: 0x800f0054); |
943 | mdelay(1); |
944 | rtw_dbg(rtwdev, mask: RTW_DBG_RFK, fmt: "[IQK] GNT_BT @%s %sIQK1 = 0x%x\n" , |
945 | iqk_cfg->name, tx ? "TX" : "RX" , |
946 | rtw_read32(rtwdev, REG_LTECOEX_READ_DATA)); |
947 | rtw_dbg(rtwdev, mask: RTW_DBG_RFK, fmt: "[IQK] 0x948 @%s %sIQK1 = 0x%x\n" , |
948 | iqk_cfg->name, tx ? "TX" : "RX" , |
949 | rtw_read32(rtwdev, REG_BB_SEL_BTG)); |
950 | |
951 | /* One shot, LOK & IQK */ |
952 | rtw_write32(rtwdev, REG_IQK_AGC_PTS_11N, val: pts); |
953 | rtw_write32(rtwdev, REG_IQK_AGC_PTS_11N, val: 0xf8000000); |
954 | |
955 | if (!check_hw_ready(rtwdev, REG_IQK_RES_RY, BIT_IQK_DONE, target: 1)) |
956 | rtw_warn(rtwdev, "%s %s IQK isn't done\n" , iqk_cfg->name, |
957 | tx ? "TX" : "RX" ); |
958 | } |
959 | |
960 | static void rtw8723d_iqk_txrx_path_post(struct rtw_dev *rtwdev, |
961 | const struct rtw_8723d_iqk_cfg *iqk_cfg, |
962 | const struct iqk_backup_regs *backup) |
963 | { |
964 | rtw8723d_iqk_restore_lte_path_gnt(rtwdev, bak: backup); |
965 | rtw_write32(rtwdev, REG_BB_SEL_BTG, val: backup->bb_sel_btg); |
966 | |
967 | /* leave IQK mode */ |
968 | rtw_write32_mask(rtwdev, REG_FPGA0_IQK_11N, BIT_MASK_IQK_MOD, RST_IQK); |
969 | mdelay(1); |
970 | rtw_write_rf(rtwdev, rf_path: RF_PATH_A, addr: iqk_cfg->reg_padlut, mask: 0x800, data: 0x0); |
971 | rtw_write_rf(rtwdev, rf_path: RF_PATH_A, RF_WLINT, BIT(0), data: 0x0); |
972 | rtw_write_rf(rtwdev, rf_path: RF_PATH_A, RF_WLSEL, BIT(0), data: 0x0); |
973 | } |
974 | |
975 | static u8 rtw8723d_iqk_tx_path(struct rtw_dev *rtwdev, |
976 | const struct rtw_8723d_iqk_cfg *iqk_cfg, |
977 | const struct iqk_backup_regs *backup) |
978 | { |
979 | u8 status; |
980 | |
981 | rtw_dbg(rtwdev, mask: RTW_DBG_RFK, fmt: "[IQK] path %s TXIQK!!\n" , iqk_cfg->name); |
982 | rtw_dbg(rtwdev, mask: RTW_DBG_RFK, fmt: "[IQK] 0x67 @%s TXIQK = 0x%x\n" , |
983 | iqk_cfg->name, |
984 | rtw_read32_mask(rtwdev, REG_PAD_CTRL1, MASKBYTE3)); |
985 | |
986 | rtw_write32(rtwdev, REG_BB_SEL_BTG, val: iqk_cfg->val_bb_sel_btg); |
987 | rtw_write32_mask(rtwdev, REG_FPGA0_IQK_11N, BIT_MASK_IQK_MOD, RST_IQK); |
988 | mdelay(1); |
989 | rtw_write_rf(rtwdev, rf_path: RF_PATH_A, addr: iqk_cfg->reg_lutwe, RFREG_MASK, data: 0x80000); |
990 | rtw_write_rf(rtwdev, rf_path: RF_PATH_A, RF_LUTWA, RFREG_MASK, data: 0x00004); |
991 | rtw_write_rf(rtwdev, rf_path: RF_PATH_A, RF_LUTWD1, RFREG_MASK, data: 0x0005d); |
992 | rtw_write_rf(rtwdev, rf_path: RF_PATH_A, RF_LUTWD0, RFREG_MASK, data: 0xBFFE0); |
993 | rtw_write_rf(rtwdev, rf_path: RF_PATH_A, addr: iqk_cfg->reg_lutwe, RFREG_MASK, data: 0x00000); |
994 | |
995 | /* IQK setting */ |
996 | rtw_write32(rtwdev, REG_TXIQK_TONE_A_11N, val: 0x08008c0c); |
997 | rtw_write32(rtwdev, REG_RXIQK_TONE_A_11N, val: 0x38008c1c); |
998 | rtw_write32(rtwdev, REG_TXIQK_PI_A_11N, val: iqk_cfg->val_txiqk_pi); |
999 | rtw_write32(rtwdev, REG_RXIQK_PI_A_11N, val: 0x28160200); |
1000 | rtw_write32(rtwdev, REG_TXIQK_11N, val: 0x01007c00); |
1001 | rtw_write32(rtwdev, REG_RXIQK_11N, val: 0x01004800); |
1002 | |
1003 | /* LOK setting */ |
1004 | rtw_write32(rtwdev, REG_IQK_AGC_RSP_11N, val: 0x00462911); |
1005 | |
1006 | /* PA, PAD setting */ |
1007 | rtw_write_rf(rtwdev, rf_path: RF_PATH_A, addr: iqk_cfg->reg_padlut, mask: 0x800, data: 0x1); |
1008 | rtw_write_rf(rtwdev, rf_path: RF_PATH_A, addr: iqk_cfg->reg_gaintx, mask: 0x600, data: 0x0); |
1009 | rtw_write_rf(rtwdev, rf_path: RF_PATH_A, addr: iqk_cfg->reg_gaintx, mask: 0x1E0, data: 0x3); |
1010 | rtw_write_rf(rtwdev, rf_path: RF_PATH_A, RF_RXIQGEN, mask: 0x1F, data: 0xf); |
1011 | |
1012 | /* LOK setting for 8723D */ |
1013 | rtw_write_rf(rtwdev, rf_path: RF_PATH_A, addr: iqk_cfg->reg_lutwe, mask: 0x10, data: 0x1); |
1014 | rtw_write_rf(rtwdev, rf_path: RF_PATH_A, addr: iqk_cfg->reg_bspad, mask: 0x1, data: 0x1); |
1015 | |
1016 | rtw_write_rf(rtwdev, rf_path: RF_PATH_A, RF_WLINT, RFREG_MASK, data: iqk_cfg->val_wlint); |
1017 | rtw_write_rf(rtwdev, rf_path: RF_PATH_A, RF_WLSEL, RFREG_MASK, data: iqk_cfg->val_wlsel); |
1018 | |
1019 | rtw_dbg(rtwdev, mask: RTW_DBG_RFK, fmt: "[IQK] RF0x1 @%s TXIQK = 0x%x\n" , |
1020 | iqk_cfg->name, |
1021 | rtw_read_rf(rtwdev, rf_path: RF_PATH_A, RF_WLINT, RFREG_MASK)); |
1022 | rtw_dbg(rtwdev, mask: RTW_DBG_RFK, fmt: "[IQK] RF0x2 @%s TXIQK = 0x%x\n" , |
1023 | iqk_cfg->name, |
1024 | rtw_read_rf(rtwdev, rf_path: RF_PATH_A, RF_WLSEL, RFREG_MASK)); |
1025 | |
1026 | rtw8723d_iqk_one_shot(rtwdev, tx: true, iqk_cfg); |
1027 | status = rtw8723d_iqk_check_tx_failed(rtwdev, iqk_cfg); |
1028 | |
1029 | rtw8723d_iqk_txrx_path_post(rtwdev, iqk_cfg, backup); |
1030 | |
1031 | return status; |
1032 | } |
1033 | |
1034 | static u8 rtw8723d_iqk_rx_path(struct rtw_dev *rtwdev, |
1035 | const struct rtw_8723d_iqk_cfg *iqk_cfg, |
1036 | const struct iqk_backup_regs *backup) |
1037 | { |
1038 | u32 tx_x, tx_y; |
1039 | u8 status; |
1040 | |
1041 | rtw_dbg(rtwdev, mask: RTW_DBG_RFK, fmt: "[IQK] path %s RXIQK Step1!!\n" , |
1042 | iqk_cfg->name); |
1043 | rtw_dbg(rtwdev, mask: RTW_DBG_RFK, fmt: "[IQK] 0x67 @%s RXIQK1 = 0x%x\n" , |
1044 | iqk_cfg->name, |
1045 | rtw_read32_mask(rtwdev, REG_PAD_CTRL1, MASKBYTE3)); |
1046 | rtw_write32(rtwdev, REG_BB_SEL_BTG, val: iqk_cfg->val_bb_sel_btg); |
1047 | |
1048 | rtw_write32_mask(rtwdev, REG_FPGA0_IQK_11N, BIT_MASK_IQK_MOD, RST_IQK); |
1049 | |
1050 | /* IQK setting */ |
1051 | rtw_write32(rtwdev, REG_TXIQK_11N, val: 0x01007c00); |
1052 | rtw_write32(rtwdev, REG_RXIQK_11N, val: 0x01004800); |
1053 | |
1054 | /* path IQK setting */ |
1055 | rtw_write32(rtwdev, REG_TXIQK_TONE_A_11N, val: 0x18008c1c); |
1056 | rtw_write32(rtwdev, REG_RXIQK_TONE_A_11N, val: 0x38008c1c); |
1057 | rtw_write32(rtwdev, REG_TX_IQK_TONE_B, val: 0x38008c1c); |
1058 | rtw_write32(rtwdev, REG_RX_IQK_TONE_B, val: 0x38008c1c); |
1059 | rtw_write32(rtwdev, REG_TXIQK_PI_A_11N, val: 0x82160000); |
1060 | rtw_write32(rtwdev, REG_RXIQK_PI_A_11N, val: 0x28160000); |
1061 | |
1062 | /* LOK setting */ |
1063 | rtw_write32(rtwdev, REG_IQK_AGC_RSP_11N, val: 0x0046a911); |
1064 | |
1065 | /* RXIQK mode */ |
1066 | rtw_write_rf(rtwdev, rf_path: RF_PATH_A, addr: iqk_cfg->reg_lutwe, RFREG_MASK, data: 0x80000); |
1067 | rtw_write_rf(rtwdev, rf_path: RF_PATH_A, RF_LUTWA, RFREG_MASK, data: 0x00006); |
1068 | rtw_write_rf(rtwdev, rf_path: RF_PATH_A, RF_LUTWD1, RFREG_MASK, data: 0x0005f); |
1069 | rtw_write_rf(rtwdev, rf_path: RF_PATH_A, RF_LUTWD0, RFREG_MASK, data: 0xa7ffb); |
1070 | rtw_write_rf(rtwdev, rf_path: RF_PATH_A, addr: iqk_cfg->reg_lutwe, RFREG_MASK, data: 0x00000); |
1071 | |
1072 | /* PA/PAD=0 */ |
1073 | rtw_write_rf(rtwdev, rf_path: RF_PATH_A, addr: iqk_cfg->reg_padlut, mask: 0x800, data: 0x1); |
1074 | rtw_write_rf(rtwdev, rf_path: RF_PATH_A, addr: iqk_cfg->reg_gaintx, mask: 0x600, data: 0x0); |
1075 | rtw_write_rf(rtwdev, rf_path: RF_PATH_A, RF_WLINT, RFREG_MASK, data: iqk_cfg->val_wlint); |
1076 | rtw_write_rf(rtwdev, rf_path: RF_PATH_A, RF_WLSEL, RFREG_MASK, data: iqk_cfg->val_wlsel); |
1077 | |
1078 | rtw_dbg(rtwdev, mask: RTW_DBG_RFK, fmt: "[IQK] RF0x1@ path %s RXIQK1 = 0x%x\n" , |
1079 | iqk_cfg->name, |
1080 | rtw_read_rf(rtwdev, rf_path: RF_PATH_A, RF_WLINT, RFREG_MASK)); |
1081 | rtw_dbg(rtwdev, mask: RTW_DBG_RFK, fmt: "[IQK] RF0x2@ path %s RXIQK1 = 0x%x\n" , |
1082 | iqk_cfg->name, |
1083 | rtw_read_rf(rtwdev, rf_path: RF_PATH_A, RF_WLSEL, RFREG_MASK)); |
1084 | |
1085 | rtw8723d_iqk_one_shot(rtwdev, tx: false, iqk_cfg); |
1086 | status = rtw8723d_iqk_check_tx_failed(rtwdev, iqk_cfg); |
1087 | |
1088 | if (!status) |
1089 | goto restore; |
1090 | |
1091 | /* second round */ |
1092 | tx_x = rtw_read32_mask(rtwdev, REG_IQK_RES_TX, BIT_MASK_RES_TX); |
1093 | tx_y = rtw_read32_mask(rtwdev, REG_IQK_RES_TY, BIT_MASK_RES_TY); |
1094 | |
1095 | rtw_write32(rtwdev, REG_TXIQK_11N, BIT_SET_TXIQK_11N(tx_x, tx_y)); |
1096 | rtw_dbg(rtwdev, mask: RTW_DBG_RFK, fmt: "[IQK] 0xe40 = 0x%x u4tmp = 0x%x\n" , |
1097 | rtw_read32(rtwdev, REG_TXIQK_11N), |
1098 | BIT_SET_TXIQK_11N(tx_x, tx_y)); |
1099 | |
1100 | rtw_dbg(rtwdev, mask: RTW_DBG_RFK, fmt: "[IQK] path %s RXIQK STEP2!!\n" , |
1101 | iqk_cfg->name); |
1102 | rtw_dbg(rtwdev, mask: RTW_DBG_RFK, fmt: "[IQK] 0x67 @%s RXIQK2 = 0x%x\n" , |
1103 | iqk_cfg->name, |
1104 | rtw_read32_mask(rtwdev, REG_PAD_CTRL1, MASKBYTE3)); |
1105 | |
1106 | rtw_write32(rtwdev, REG_RXIQK_11N, val: 0x01004800); |
1107 | rtw_write32(rtwdev, REG_TXIQK_TONE_A_11N, val: 0x38008c1c); |
1108 | rtw_write32(rtwdev, REG_RXIQK_TONE_A_11N, val: 0x18008c1c); |
1109 | rtw_write32(rtwdev, REG_TX_IQK_TONE_B, val: 0x38008c1c); |
1110 | rtw_write32(rtwdev, REG_RX_IQK_TONE_B, val: 0x38008c1c); |
1111 | rtw_write32(rtwdev, REG_TXIQK_PI_A_11N, val: 0x82170000); |
1112 | rtw_write32(rtwdev, REG_RXIQK_PI_A_11N, val: 0x28171400); |
1113 | |
1114 | /* LOK setting */ |
1115 | rtw_write32(rtwdev, REG_IQK_AGC_RSP_11N, val: 0x0046a8d1); |
1116 | |
1117 | /* RXIQK mode */ |
1118 | rtw_write32_mask(rtwdev, REG_FPGA0_IQK_11N, BIT_MASK_IQK_MOD, RST_IQK); |
1119 | mdelay(1); |
1120 | rtw_write_rf(rtwdev, rf_path: RF_PATH_A, addr: iqk_cfg->reg_lutwe, mask: 0x80000, data: 0x1); |
1121 | rtw_write_rf(rtwdev, rf_path: RF_PATH_A, RF_LUTWA, RFREG_MASK, data: 0x00007); |
1122 | rtw_write_rf(rtwdev, rf_path: RF_PATH_A, RF_LUTWD1, RFREG_MASK, data: 0x0005f); |
1123 | rtw_write_rf(rtwdev, rf_path: RF_PATH_A, RF_LUTWD0, RFREG_MASK, data: 0xb3fdb); |
1124 | rtw_write_rf(rtwdev, rf_path: RF_PATH_A, addr: iqk_cfg->reg_lutwe, RFREG_MASK, data: 0x00000); |
1125 | |
1126 | rtw_dbg(rtwdev, mask: RTW_DBG_RFK, fmt: "[IQK] RF0x1 @%s RXIQK2 = 0x%x\n" , |
1127 | iqk_cfg->name, |
1128 | rtw_read_rf(rtwdev, rf_path: RF_PATH_A, RF_WLINT, RFREG_MASK)); |
1129 | rtw_dbg(rtwdev, mask: RTW_DBG_RFK, fmt: "[IQK] RF0x2 @%s RXIQK2 = 0x%x\n" , |
1130 | iqk_cfg->name, |
1131 | rtw_read_rf(rtwdev, rf_path: RF_PATH_A, RF_WLSEL, RFREG_MASK)); |
1132 | |
1133 | rtw8723d_iqk_one_shot(rtwdev, tx: false, iqk_cfg); |
1134 | status |= rtw8723d_iqk_check_rx_failed(rtwdev, iqk_cfg); |
1135 | |
1136 | restore: |
1137 | rtw8723d_iqk_txrx_path_post(rtwdev, iqk_cfg, backup); |
1138 | |
1139 | return status; |
1140 | } |
1141 | |
1142 | static |
1143 | void rtw8723d_iqk_fill_s1_matrix(struct rtw_dev *rtwdev, const s32 result[]) |
1144 | { |
1145 | s32 oldval_1; |
1146 | s32 x, y; |
1147 | s32 tx1_a, tx1_a_ext; |
1148 | s32 tx1_c, tx1_c_ext; |
1149 | |
1150 | if (result[IQK_S1_TX_X] == 0) |
1151 | return; |
1152 | |
1153 | oldval_1 = rtw_read32_mask(rtwdev, REG_OFDM_0_XA_TX_IQ_IMBALANCE, |
1154 | BIT_MASK_TXIQ_ELM_D); |
1155 | |
1156 | x = iqkxy_to_s32(val: result[IQK_S1_TX_X]); |
1157 | tx1_a = iqk_mult(x, y: oldval_1, ext: &tx1_a_ext); |
1158 | rtw_write32_mask(rtwdev, REG_OFDM_0_XA_TX_IQ_IMBALANCE, |
1159 | BIT_MASK_TXIQ_ELM_A, data: tx1_a); |
1160 | rtw_write32_mask(rtwdev, REG_OFDM_0_ECCA_THRESHOLD, |
1161 | BIT_MASK_OFDM0_EXT_A, data: tx1_a_ext); |
1162 | |
1163 | y = iqkxy_to_s32(val: result[IQK_S1_TX_Y]); |
1164 | tx1_c = iqk_mult(x: y, y: oldval_1, ext: &tx1_c_ext); |
1165 | rtw_write32_mask(rtwdev, REG_TXIQK_MATRIXA_LSB2_11N, MASKH4BITS, |
1166 | BIT_SET_TXIQ_ELM_C1(tx1_c)); |
1167 | rtw_write32_mask(rtwdev, REG_OFDM_0_XA_TX_IQ_IMBALANCE, |
1168 | BIT_MASK_TXIQ_ELM_C, BIT_SET_TXIQ_ELM_C2(tx1_c)); |
1169 | rtw_write32_mask(rtwdev, REG_OFDM_0_ECCA_THRESHOLD, |
1170 | BIT_MASK_OFDM0_EXT_C, data: tx1_c_ext); |
1171 | |
1172 | rtw_dbg(rtwdev, mask: RTW_DBG_RFK, |
1173 | fmt: "[IQK] X = 0x%x, TX1_A = 0x%x, oldval_1 0x%x\n" , |
1174 | x, tx1_a, oldval_1); |
1175 | rtw_dbg(rtwdev, mask: RTW_DBG_RFK, |
1176 | fmt: "[IQK] Y = 0x%x, TX1_C = 0x%x\n" , y, tx1_c); |
1177 | |
1178 | if (result[IQK_S1_RX_X] == 0) |
1179 | return; |
1180 | |
1181 | rtw_write32_mask(rtwdev, REG_A_RXIQI, BIT_MASK_RXIQ_S1_X, |
1182 | data: result[IQK_S1_RX_X]); |
1183 | rtw_write32_mask(rtwdev, REG_A_RXIQI, BIT_MASK_RXIQ_S1_Y1, |
1184 | BIT_SET_RXIQ_S1_Y1(result[IQK_S1_RX_Y])); |
1185 | rtw_write32_mask(rtwdev, REG_RXIQK_MATRIX_LSB_11N, BIT_MASK_RXIQ_S1_Y2, |
1186 | BIT_SET_RXIQ_S1_Y2(result[IQK_S1_RX_Y])); |
1187 | } |
1188 | |
1189 | static |
1190 | void rtw8723d_iqk_fill_s0_matrix(struct rtw_dev *rtwdev, const s32 result[]) |
1191 | { |
1192 | s32 oldval_0; |
1193 | s32 x, y; |
1194 | s32 tx0_a, tx0_a_ext; |
1195 | s32 tx0_c, tx0_c_ext; |
1196 | |
1197 | if (result[IQK_S0_TX_X] == 0) |
1198 | return; |
1199 | |
1200 | oldval_0 = rtw_read32_mask(rtwdev, REG_TXIQ_CD_S0, BIT_MASK_TXIQ_D_S0); |
1201 | |
1202 | x = iqkxy_to_s32(val: result[IQK_S0_TX_X]); |
1203 | tx0_a = iqk_mult(x, y: oldval_0, ext: &tx0_a_ext); |
1204 | |
1205 | rtw_write32_mask(rtwdev, REG_TXIQ_AB_S0, BIT_MASK_TXIQ_A_S0, data: tx0_a); |
1206 | rtw_write32_mask(rtwdev, REG_TXIQ_AB_S0, BIT_MASK_TXIQ_A_EXT_S0, data: tx0_a_ext); |
1207 | |
1208 | y = iqkxy_to_s32(val: result[IQK_S0_TX_Y]); |
1209 | tx0_c = iqk_mult(x: y, y: oldval_0, ext: &tx0_c_ext); |
1210 | |
1211 | rtw_write32_mask(rtwdev, REG_TXIQ_CD_S0, BIT_MASK_TXIQ_C_S0, data: tx0_c); |
1212 | rtw_write32_mask(rtwdev, REG_TXIQ_CD_S0, BIT_MASK_TXIQ_C_EXT_S0, data: tx0_c_ext); |
1213 | |
1214 | if (result[IQK_S0_RX_X] == 0) |
1215 | return; |
1216 | |
1217 | rtw_write32_mask(rtwdev, REG_RXIQ_AB_S0, BIT_MASK_RXIQ_X_S0, |
1218 | data: result[IQK_S0_RX_X]); |
1219 | rtw_write32_mask(rtwdev, REG_RXIQ_AB_S0, BIT_MASK_RXIQ_Y_S0, |
1220 | data: result[IQK_S0_RX_Y]); |
1221 | } |
1222 | |
1223 | static void rtw8723d_iqk_path_adda_on(struct rtw_dev *rtwdev) |
1224 | { |
1225 | int i; |
1226 | |
1227 | for (i = 0; i < IQK_ADDA_REG_NUM; i++) |
1228 | rtw_write32(rtwdev, addr: iqk_adda_regs[i], val: 0x03c00016); |
1229 | } |
1230 | |
1231 | static void rtw8723d_iqk_config_mac(struct rtw_dev *rtwdev) |
1232 | { |
1233 | rtw_write8(rtwdev, REG_TXPAUSE, val: 0xff); |
1234 | } |
1235 | |
1236 | static |
1237 | void rtw8723d_iqk_rf_standby(struct rtw_dev *rtwdev, enum rtw_rf_path path) |
1238 | { |
1239 | rtw_dbg(rtwdev, mask: RTW_DBG_RFK, fmt: "[IQK] path-%s standby mode!\n" , |
1240 | path == RF_PATH_A ? "S1" : "S0" ); |
1241 | |
1242 | rtw_write32_mask(rtwdev, REG_FPGA0_IQK_11N, BIT_MASK_IQK_MOD, RST_IQK); |
1243 | mdelay(1); |
1244 | rtw_write_rf(rtwdev, rf_path: path, RF_MODE, RFREG_MASK, data: 0x10000); |
1245 | rtw_write32_mask(rtwdev, REG_FPGA0_IQK_11N, BIT_MASK_IQK_MOD, EN_IQK); |
1246 | } |
1247 | |
1248 | static |
1249 | bool rtw8723d_iqk_similarity_cmp(struct rtw_dev *rtwdev, s32 result[][IQK_NR], |
1250 | u8 c1, u8 c2) |
1251 | { |
1252 | u32 i, j, diff; |
1253 | u32 bitmap = 0; |
1254 | u8 candidate[PATH_NR] = {IQK_ROUND_INVALID, IQK_ROUND_INVALID}; |
1255 | bool ret = true; |
1256 | |
1257 | s32 tmp1, tmp2; |
1258 | |
1259 | for (i = 0; i < IQK_NR; i++) { |
1260 | tmp1 = iqkxy_to_s32(val: result[c1][i]); |
1261 | tmp2 = iqkxy_to_s32(val: result[c2][i]); |
1262 | |
1263 | diff = abs(tmp1 - tmp2); |
1264 | |
1265 | if (diff <= MAX_TOLERANCE) |
1266 | continue; |
1267 | |
1268 | if ((i == IQK_S1_RX_X || i == IQK_S0_RX_X) && !bitmap) { |
1269 | if (result[c1][i] + result[c1][i + 1] == 0) |
1270 | candidate[i / IQK_SX_NR] = c2; |
1271 | else if (result[c2][i] + result[c2][i + 1] == 0) |
1272 | candidate[i / IQK_SX_NR] = c1; |
1273 | else |
1274 | bitmap |= BIT(i); |
1275 | } else { |
1276 | bitmap |= BIT(i); |
1277 | } |
1278 | } |
1279 | |
1280 | if (bitmap != 0) |
1281 | goto check_sim; |
1282 | |
1283 | for (i = 0; i < PATH_NR; i++) { |
1284 | if (candidate[i] == IQK_ROUND_INVALID) |
1285 | continue; |
1286 | |
1287 | for (j = i * IQK_SX_NR; j < i * IQK_SX_NR + 2; j++) |
1288 | result[IQK_ROUND_HYBRID][j] = result[candidate[i]][j]; |
1289 | ret = false; |
1290 | } |
1291 | |
1292 | return ret; |
1293 | |
1294 | check_sim: |
1295 | for (i = 0; i < IQK_NR; i++) { |
1296 | j = i & ~1; /* 2 bits are a pair for IQ[X, Y] */ |
1297 | if (bitmap & GENMASK(j + 1, j)) |
1298 | continue; |
1299 | |
1300 | result[IQK_ROUND_HYBRID][i] = result[c1][i]; |
1301 | } |
1302 | |
1303 | return false; |
1304 | } |
1305 | |
1306 | static |
1307 | void rtw8723d_iqk_precfg_path(struct rtw_dev *rtwdev, enum rtw8723d_path path) |
1308 | { |
1309 | if (path == PATH_S0) { |
1310 | rtw8723d_iqk_rf_standby(rtwdev, path: RF_PATH_A); |
1311 | rtw8723d_iqk_path_adda_on(rtwdev); |
1312 | } |
1313 | |
1314 | rtw_write32_mask(rtwdev, REG_FPGA0_IQK_11N, BIT_MASK_IQK_MOD, EN_IQK); |
1315 | rtw_write32(rtwdev, REG_TXIQK_11N, val: 0x01007c00); |
1316 | rtw_write32(rtwdev, REG_RXIQK_11N, val: 0x01004800); |
1317 | |
1318 | if (path == PATH_S1) { |
1319 | rtw8723d_iqk_rf_standby(rtwdev, path: RF_PATH_B); |
1320 | rtw8723d_iqk_path_adda_on(rtwdev); |
1321 | } |
1322 | } |
1323 | |
1324 | static |
1325 | void rtw8723d_iqk_one_round(struct rtw_dev *rtwdev, s32 result[][IQK_NR], u8 t, |
1326 | const struct iqk_backup_regs *backup) |
1327 | { |
1328 | u32 i; |
1329 | u8 s1_ok, s0_ok; |
1330 | |
1331 | rtw_dbg(rtwdev, mask: RTW_DBG_RFK, |
1332 | fmt: "[IQK] IQ Calibration for 1T1R_S0/S1 for %d times\n" , t); |
1333 | |
1334 | rtw8723d_iqk_path_adda_on(rtwdev); |
1335 | rtw8723d_iqk_config_mac(rtwdev); |
1336 | rtw_write32_mask(rtwdev, REG_CCK_ANT_SEL_11N, mask: 0x0f000000, data: 0xf); |
1337 | rtw_write32(rtwdev, REG_BB_RX_PATH_11N, val: 0x03a05611); |
1338 | rtw_write32(rtwdev, REG_TRMUX_11N, val: 0x000800e4); |
1339 | rtw_write32(rtwdev, REG_BB_PWR_SAV1_11N, val: 0x25204200); |
1340 | rtw8723d_iqk_precfg_path(rtwdev, path: PATH_S1); |
1341 | |
1342 | for (i = 0; i < PATH_IQK_RETRY; i++) { |
1343 | s1_ok = rtw8723d_iqk_tx_path(rtwdev, iqk_cfg: &iqk_tx_cfg[PATH_S1], backup); |
1344 | if (s1_ok == IQK_TX_OK) { |
1345 | rtw_dbg(rtwdev, mask: RTW_DBG_RFK, |
1346 | fmt: "[IQK] path S1 Tx IQK Success!!\n" ); |
1347 | result[t][IQK_S1_TX_X] = |
1348 | rtw_read32_mask(rtwdev, REG_IQK_RES_TX, BIT_MASK_RES_TX); |
1349 | result[t][IQK_S1_TX_Y] = |
1350 | rtw_read32_mask(rtwdev, REG_IQK_RES_TY, BIT_MASK_RES_TY); |
1351 | break; |
1352 | } |
1353 | |
1354 | rtw_dbg(rtwdev, mask: RTW_DBG_RFK, fmt: "[IQK] path S1 Tx IQK Fail!!\n" ); |
1355 | result[t][IQK_S1_TX_X] = 0x100; |
1356 | result[t][IQK_S1_TX_Y] = 0x0; |
1357 | } |
1358 | |
1359 | for (i = 0; i < PATH_IQK_RETRY; i++) { |
1360 | s1_ok = rtw8723d_iqk_rx_path(rtwdev, iqk_cfg: &iqk_tx_cfg[PATH_S1], backup); |
1361 | if (s1_ok == (IQK_TX_OK | IQK_RX_OK)) { |
1362 | rtw_dbg(rtwdev, mask: RTW_DBG_RFK, |
1363 | fmt: "[IQK] path S1 Rx IQK Success!!\n" ); |
1364 | result[t][IQK_S1_RX_X] = |
1365 | rtw_read32_mask(rtwdev, REG_IQK_RES_RX, BIT_MASK_RES_RX); |
1366 | result[t][IQK_S1_RX_Y] = |
1367 | rtw_read32_mask(rtwdev, REG_IQK_RES_RY, BIT_MASK_RES_RY); |
1368 | break; |
1369 | } |
1370 | |
1371 | rtw_dbg(rtwdev, mask: RTW_DBG_RFK, fmt: "[IQK] path S1 Rx IQK Fail!!\n" ); |
1372 | result[t][IQK_S1_RX_X] = 0x100; |
1373 | result[t][IQK_S1_RX_Y] = 0x0; |
1374 | } |
1375 | |
1376 | if (s1_ok == 0x0) |
1377 | rtw_dbg(rtwdev, mask: RTW_DBG_RFK, fmt: "[IQK] path S1 IQK is failed!!\n" ); |
1378 | |
1379 | rtw8723d_iqk_precfg_path(rtwdev, path: PATH_S0); |
1380 | |
1381 | for (i = 0; i < PATH_IQK_RETRY; i++) { |
1382 | s0_ok = rtw8723d_iqk_tx_path(rtwdev, iqk_cfg: &iqk_tx_cfg[PATH_S0], backup); |
1383 | if (s0_ok == IQK_TX_OK) { |
1384 | rtw_dbg(rtwdev, mask: RTW_DBG_RFK, |
1385 | fmt: "[IQK] path S0 Tx IQK Success!!\n" ); |
1386 | result[t][IQK_S0_TX_X] = |
1387 | rtw_read32_mask(rtwdev, REG_IQK_RES_TX, BIT_MASK_RES_TX); |
1388 | result[t][IQK_S0_TX_Y] = |
1389 | rtw_read32_mask(rtwdev, REG_IQK_RES_TY, BIT_MASK_RES_TY); |
1390 | break; |
1391 | } |
1392 | |
1393 | rtw_dbg(rtwdev, mask: RTW_DBG_RFK, fmt: "[IQK] path S0 Tx IQK Fail!!\n" ); |
1394 | result[t][IQK_S0_TX_X] = 0x100; |
1395 | result[t][IQK_S0_TX_Y] = 0x0; |
1396 | } |
1397 | |
1398 | for (i = 0; i < PATH_IQK_RETRY; i++) { |
1399 | s0_ok = rtw8723d_iqk_rx_path(rtwdev, iqk_cfg: &iqk_tx_cfg[PATH_S0], backup); |
1400 | if (s0_ok == (IQK_TX_OK | IQK_RX_OK)) { |
1401 | rtw_dbg(rtwdev, mask: RTW_DBG_RFK, |
1402 | fmt: "[IQK] path S0 Rx IQK Success!!\n" ); |
1403 | |
1404 | result[t][IQK_S0_RX_X] = |
1405 | rtw_read32_mask(rtwdev, REG_IQK_RES_RX, BIT_MASK_RES_RX); |
1406 | result[t][IQK_S0_RX_Y] = |
1407 | rtw_read32_mask(rtwdev, REG_IQK_RES_RY, BIT_MASK_RES_RY); |
1408 | break; |
1409 | } |
1410 | |
1411 | rtw_dbg(rtwdev, mask: RTW_DBG_RFK, fmt: "[IQK] path S0 Rx IQK Fail!!\n" ); |
1412 | result[t][IQK_S0_RX_X] = 0x100; |
1413 | result[t][IQK_S0_RX_Y] = 0x0; |
1414 | } |
1415 | |
1416 | if (s0_ok == 0x0) |
1417 | rtw_dbg(rtwdev, mask: RTW_DBG_RFK, fmt: "[IQK] path S0 IQK is failed!!\n" ); |
1418 | |
1419 | rtw_write32_mask(rtwdev, REG_FPGA0_IQK_11N, BIT_MASK_IQK_MOD, RST_IQK); |
1420 | mdelay(1); |
1421 | |
1422 | rtw_dbg(rtwdev, mask: RTW_DBG_RFK, |
1423 | fmt: "[IQK] back to BB mode, load original value!\n" ); |
1424 | } |
1425 | |
1426 | static void rtw8723d_phy_calibration(struct rtw_dev *rtwdev) |
1427 | { |
1428 | struct rtw_dm_info *dm_info = &rtwdev->dm_info; |
1429 | s32 result[IQK_ROUND_SIZE][IQK_NR]; |
1430 | struct iqk_backup_regs backup; |
1431 | u8 i, j; |
1432 | u8 final_candidate = IQK_ROUND_INVALID; |
1433 | bool good; |
1434 | |
1435 | rtw_dbg(rtwdev, mask: RTW_DBG_RFK, fmt: "[IQK] Start!!!\n" ); |
1436 | |
1437 | memset(result, 0, sizeof(result)); |
1438 | |
1439 | rtw8723d_iqk_backup_path_ctrl(rtwdev, backup: &backup); |
1440 | rtw8723d_iqk_backup_lte_path_gnt(rtwdev, backup: &backup); |
1441 | rtw8723d_iqk_backup_regs(rtwdev, backup: &backup); |
1442 | |
1443 | for (i = IQK_ROUND_0; i <= IQK_ROUND_2; i++) { |
1444 | rtw8723d_iqk_config_path_ctrl(rtwdev); |
1445 | rtw8723d_iqk_config_lte_path_gnt(rtwdev); |
1446 | |
1447 | rtw8723d_iqk_one_round(rtwdev, result, t: i, backup: &backup); |
1448 | |
1449 | if (i > IQK_ROUND_0) |
1450 | rtw8723d_iqk_restore_regs(rtwdev, backup: &backup); |
1451 | rtw8723d_iqk_restore_lte_path_gnt(rtwdev, bak: &backup); |
1452 | rtw8723d_iqk_restore_path_ctrl(rtwdev, backup: &backup); |
1453 | |
1454 | for (j = IQK_ROUND_0; j < i; j++) { |
1455 | good = rtw8723d_iqk_similarity_cmp(rtwdev, result, c1: j, c2: i); |
1456 | |
1457 | if (good) { |
1458 | final_candidate = j; |
1459 | rtw_dbg(rtwdev, mask: RTW_DBG_RFK, |
1460 | fmt: "[IQK] cmp %d:%d final_candidate is %x\n" , |
1461 | j, i, final_candidate); |
1462 | goto iqk_done; |
1463 | } |
1464 | } |
1465 | } |
1466 | |
1467 | if (final_candidate == IQK_ROUND_INVALID) { |
1468 | s32 reg_tmp = 0; |
1469 | |
1470 | for (i = 0; i < IQK_NR; i++) |
1471 | reg_tmp += result[IQK_ROUND_HYBRID][i]; |
1472 | |
1473 | if (reg_tmp != 0) { |
1474 | final_candidate = IQK_ROUND_HYBRID; |
1475 | } else { |
1476 | WARN(1, "IQK is failed\n" ); |
1477 | goto out; |
1478 | } |
1479 | } |
1480 | |
1481 | iqk_done: |
1482 | rtw8723d_iqk_fill_s1_matrix(rtwdev, result: result[final_candidate]); |
1483 | rtw8723d_iqk_fill_s0_matrix(rtwdev, result: result[final_candidate]); |
1484 | |
1485 | dm_info->iqk.result.s1_x = result[final_candidate][IQK_S1_TX_X]; |
1486 | dm_info->iqk.result.s1_y = result[final_candidate][IQK_S1_TX_Y]; |
1487 | dm_info->iqk.result.s0_x = result[final_candidate][IQK_S0_TX_X]; |
1488 | dm_info->iqk.result.s0_y = result[final_candidate][IQK_S0_TX_Y]; |
1489 | dm_info->iqk.done = true; |
1490 | |
1491 | out: |
1492 | rtw_write32(rtwdev, REG_BB_SEL_BTG, val: backup.bb_sel_btg); |
1493 | |
1494 | rtw_dbg(rtwdev, mask: RTW_DBG_RFK, fmt: "[IQK] final_candidate is %x\n" , |
1495 | final_candidate); |
1496 | |
1497 | for (i = IQK_ROUND_0; i < IQK_ROUND_SIZE; i++) |
1498 | rtw_dbg(rtwdev, mask: RTW_DBG_RFK, |
1499 | fmt: "[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" , |
1500 | i, |
1501 | result[i][0], result[i][1], result[i][2], result[i][3], |
1502 | result[i][4], result[i][5], result[i][6], result[i][7], |
1503 | final_candidate == i ? "(final candidate)" : "" ); |
1504 | |
1505 | rtw_dbg(rtwdev, mask: RTW_DBG_RFK, |
1506 | fmt: "[IQK]0xc80 = 0x%x 0xc94 = 0x%x 0xc14 = 0x%x 0xca0 = 0x%x\n" , |
1507 | rtw_read32(rtwdev, REG_OFDM_0_XA_TX_IQ_IMBALANCE), |
1508 | rtw_read32(rtwdev, REG_TXIQK_MATRIXA_LSB2_11N), |
1509 | rtw_read32(rtwdev, REG_A_RXIQI), |
1510 | rtw_read32(rtwdev, REG_RXIQK_MATRIX_LSB_11N)); |
1511 | rtw_dbg(rtwdev, mask: RTW_DBG_RFK, |
1512 | fmt: "[IQK]0xcd0 = 0x%x 0xcd4 = 0x%x 0xcd8 = 0x%x\n" , |
1513 | rtw_read32(rtwdev, REG_TXIQ_AB_S0), |
1514 | rtw_read32(rtwdev, REG_TXIQ_CD_S0), |
1515 | rtw_read32(rtwdev, REG_RXIQ_AB_S0)); |
1516 | |
1517 | rtw_dbg(rtwdev, mask: RTW_DBG_RFK, fmt: "[IQK] finished\n" ); |
1518 | } |
1519 | |
1520 | static void rtw8723d_phy_cck_pd_set(struct rtw_dev *rtwdev, u8 new_lvl) |
1521 | { |
1522 | struct rtw_dm_info *dm_info = &rtwdev->dm_info; |
1523 | u8 pd[CCK_PD_LV_MAX] = {3, 7, 13, 13, 13}; |
1524 | u8 cck_n_rx; |
1525 | |
1526 | rtw_dbg(rtwdev, mask: RTW_DBG_PHY, fmt: "lv: (%d) -> (%d)\n" , |
1527 | dm_info->cck_pd_lv[RTW_CHANNEL_WIDTH_20][RF_PATH_A], new_lvl); |
1528 | |
1529 | if (dm_info->cck_pd_lv[RTW_CHANNEL_WIDTH_20][RF_PATH_A] == new_lvl) |
1530 | return; |
1531 | |
1532 | cck_n_rx = (rtw_read8_mask(rtwdev, REG_CCK0_FAREPORT, BIT_CCK0_2RX) && |
1533 | rtw_read8_mask(rtwdev, REG_CCK0_FAREPORT, BIT_CCK0_MRC)) ? 2 : 1; |
1534 | rtw_dbg(rtwdev, mask: RTW_DBG_PHY, |
1535 | fmt: "is_linked=%d, lv=%d, n_rx=%d, cs_ratio=0x%x, pd_th=0x%x, cck_fa_avg=%d\n" , |
1536 | rtw_is_assoc(rtwdev), new_lvl, cck_n_rx, |
1537 | dm_info->cck_pd_default + new_lvl * 2, |
1538 | pd[new_lvl], dm_info->cck_fa_avg); |
1539 | |
1540 | dm_info->cck_fa_avg = CCK_FA_AVG_RESET; |
1541 | |
1542 | dm_info->cck_pd_lv[RTW_CHANNEL_WIDTH_20][RF_PATH_A] = new_lvl; |
1543 | rtw_write32_mask(rtwdev, REG_PWRTH, mask: 0x3f0000, data: pd[new_lvl]); |
1544 | rtw_write32_mask(rtwdev, REG_PWRTH2, mask: 0x1f0000, |
1545 | data: dm_info->cck_pd_default + new_lvl * 2); |
1546 | } |
1547 | |
1548 | /* for coex */ |
1549 | static void rtw8723d_coex_cfg_init(struct rtw_dev *rtwdev) |
1550 | { |
1551 | /* enable TBTT nterrupt */ |
1552 | rtw_write8_set(rtwdev, REG_BCN_CTRL, BIT_EN_BCN_FUNCTION); |
1553 | |
1554 | /* BT report packet sample rate */ |
1555 | /* 0x790[5:0]=0x5 */ |
1556 | rtw_write8_mask(rtwdev, REG_BT_TDMA_TIME, BIT_MASK_SAMPLE_RATE, data: 0x5); |
1557 | |
1558 | /* enable BT counter statistics */ |
1559 | rtw_write8(rtwdev, REG_BT_STAT_CTRL, val: 0x1); |
1560 | |
1561 | /* enable PTA (3-wire function form BT side) */ |
1562 | rtw_write32_set(rtwdev, REG_GPIO_MUXCFG, BIT_BT_PTA_EN); |
1563 | rtw_write32_set(rtwdev, REG_GPIO_MUXCFG, BIT_PO_BT_PTA_PINS); |
1564 | |
1565 | /* enable PTA (tx/rx signal form WiFi side) */ |
1566 | rtw_write8_set(rtwdev, REG_QUEUE_CTRL, BIT_PTA_WL_TX_EN); |
1567 | } |
1568 | |
1569 | static void rtw8723d_coex_cfg_gnt_fix(struct rtw_dev *rtwdev) |
1570 | { |
1571 | } |
1572 | |
1573 | static void rtw8723d_coex_cfg_gnt_debug(struct rtw_dev *rtwdev) |
1574 | { |
1575 | rtw_write8_mask(rtwdev, REG_LEDCFG2, BIT(6), data: 0); |
1576 | rtw_write8_mask(rtwdev, REG_PAD_CTRL1 + 3, BIT(0), data: 0); |
1577 | rtw_write8_mask(rtwdev, REG_GPIO_INTM + 2, BIT(4), data: 0); |
1578 | rtw_write8_mask(rtwdev, REG_GPIO_MUXCFG + 2, BIT(1), data: 0); |
1579 | rtw_write8_mask(rtwdev, REG_PAD_CTRL1 + 3, BIT(1), data: 0); |
1580 | rtw_write8_mask(rtwdev, REG_PAD_CTRL1 + 2, BIT(7), data: 0); |
1581 | rtw_write8_mask(rtwdev, REG_SYS_CLKR + 1, BIT(1), data: 0); |
1582 | rtw_write8_mask(rtwdev, REG_SYS_SDIO_CTRL + 3, BIT(3), data: 0); |
1583 | } |
1584 | |
1585 | static void rtw8723d_coex_cfg_rfe_type(struct rtw_dev *rtwdev) |
1586 | { |
1587 | struct rtw_efuse *efuse = &rtwdev->efuse; |
1588 | struct rtw_coex *coex = &rtwdev->coex; |
1589 | struct rtw_coex_rfe *coex_rfe = &coex->rfe; |
1590 | bool aux = efuse->bt_setting & BIT(6); |
1591 | |
1592 | coex_rfe->rfe_module_type = rtwdev->efuse.rfe_option; |
1593 | coex_rfe->ant_switch_polarity = 0; |
1594 | coex_rfe->ant_switch_exist = false; |
1595 | coex_rfe->ant_switch_with_bt = false; |
1596 | coex_rfe->ant_switch_diversity = false; |
1597 | coex_rfe->wlg_at_btg = true; |
1598 | |
1599 | /* decide antenna at main or aux */ |
1600 | if (efuse->share_ant) { |
1601 | if (aux) |
1602 | rtw_write16(rtwdev, REG_BB_SEL_BTG, val: 0x80); |
1603 | else |
1604 | rtw_write16(rtwdev, REG_BB_SEL_BTG, val: 0x200); |
1605 | } else { |
1606 | if (aux) |
1607 | rtw_write16(rtwdev, REG_BB_SEL_BTG, val: 0x280); |
1608 | else |
1609 | rtw_write16(rtwdev, REG_BB_SEL_BTG, val: 0x0); |
1610 | } |
1611 | |
1612 | /* disable LTE coex in wifi side */ |
1613 | rtw_coex_write_indirect_reg(rtwdev, LTE_COEX_CTRL, BIT_LTE_COEX_EN, val: 0x0); |
1614 | rtw_coex_write_indirect_reg(rtwdev, LTE_WL_TRX_CTRL, MASKLWORD, val: 0xffff); |
1615 | rtw_coex_write_indirect_reg(rtwdev, LTE_BT_TRX_CTRL, MASKLWORD, val: 0xffff); |
1616 | } |
1617 | |
1618 | static void rtw8723d_coex_cfg_wl_tx_power(struct rtw_dev *rtwdev, u8 wl_pwr) |
1619 | { |
1620 | struct rtw_coex *coex = &rtwdev->coex; |
1621 | struct rtw_coex_dm *coex_dm = &coex->dm; |
1622 | static const u8 wl_tx_power[] = {0xb2, 0x90}; |
1623 | u8 pwr; |
1624 | |
1625 | if (wl_pwr == coex_dm->cur_wl_pwr_lvl) |
1626 | return; |
1627 | |
1628 | coex_dm->cur_wl_pwr_lvl = wl_pwr; |
1629 | |
1630 | if (coex_dm->cur_wl_pwr_lvl >= ARRAY_SIZE(wl_tx_power)) |
1631 | coex_dm->cur_wl_pwr_lvl = ARRAY_SIZE(wl_tx_power) - 1; |
1632 | |
1633 | pwr = wl_tx_power[coex_dm->cur_wl_pwr_lvl]; |
1634 | |
1635 | rtw_write8(rtwdev, REG_ANA_PARAM1 + 3, val: pwr); |
1636 | } |
1637 | |
1638 | static void rtw8723d_coex_cfg_wl_rx_gain(struct rtw_dev *rtwdev, bool low_gain) |
1639 | { |
1640 | struct rtw_coex *coex = &rtwdev->coex; |
1641 | struct rtw_coex_dm *coex_dm = &coex->dm; |
1642 | /* WL Rx Low gain on */ |
1643 | static const u32 wl_rx_low_gain_on[] = { |
1644 | 0xec120101, 0xeb130101, 0xce140101, 0xcd150101, 0xcc160101, |
1645 | 0xcb170101, 0xca180101, 0x8d190101, 0x8c1a0101, 0x8b1b0101, |
1646 | 0x4f1c0101, 0x4e1d0101, 0x4d1e0101, 0x4c1f0101, 0x0e200101, |
1647 | 0x0d210101, 0x0c220101, 0x0b230101, 0xcf240001, 0xce250001, |
1648 | 0xcd260001, 0xcc270001, 0x8f280001 |
1649 | }; |
1650 | /* WL Rx Low gain off */ |
1651 | static const u32 wl_rx_low_gain_off[] = { |
1652 | 0xec120101, 0xeb130101, 0xea140101, 0xe9150101, 0xe8160101, |
1653 | 0xe7170101, 0xe6180101, 0xe5190101, 0xe41a0101, 0xe31b0101, |
1654 | 0xe21c0101, 0xe11d0101, 0xe01e0101, 0x861f0101, 0x85200101, |
1655 | 0x84210101, 0x83220101, 0x82230101, 0x81240101, 0x80250101, |
1656 | 0x44260101, 0x43270101, 0x42280101 |
1657 | }; |
1658 | u8 i; |
1659 | |
1660 | if (low_gain == coex_dm->cur_wl_rx_low_gain_en) |
1661 | return; |
1662 | |
1663 | coex_dm->cur_wl_rx_low_gain_en = low_gain; |
1664 | |
1665 | if (coex_dm->cur_wl_rx_low_gain_en) { |
1666 | for (i = 0; i < ARRAY_SIZE(wl_rx_low_gain_on); i++) |
1667 | rtw_write32(rtwdev, REG_AGCRSSI, val: wl_rx_low_gain_on[i]); |
1668 | } else { |
1669 | for (i = 0; i < ARRAY_SIZE(wl_rx_low_gain_off); i++) |
1670 | rtw_write32(rtwdev, REG_AGCRSSI, val: wl_rx_low_gain_off[i]); |
1671 | } |
1672 | } |
1673 | |
1674 | static u8 rtw8723d_pwrtrack_get_limit_ofdm(struct rtw_dev *rtwdev) |
1675 | { |
1676 | struct rtw_dm_info *dm_info = &rtwdev->dm_info; |
1677 | u8 tx_rate = dm_info->tx_rate; |
1678 | u8 limit_ofdm = 30; |
1679 | |
1680 | switch (tx_rate) { |
1681 | case DESC_RATE1M...DESC_RATE5_5M: |
1682 | case DESC_RATE11M: |
1683 | break; |
1684 | case DESC_RATE6M...DESC_RATE48M: |
1685 | limit_ofdm = 36; |
1686 | break; |
1687 | case DESC_RATE54M: |
1688 | limit_ofdm = 34; |
1689 | break; |
1690 | case DESC_RATEMCS0...DESC_RATEMCS2: |
1691 | limit_ofdm = 38; |
1692 | break; |
1693 | case DESC_RATEMCS3...DESC_RATEMCS4: |
1694 | limit_ofdm = 36; |
1695 | break; |
1696 | case DESC_RATEMCS5...DESC_RATEMCS7: |
1697 | limit_ofdm = 34; |
1698 | break; |
1699 | default: |
1700 | rtw_warn(rtwdev, "pwrtrack unhandled tx_rate 0x%x\n" , tx_rate); |
1701 | break; |
1702 | } |
1703 | |
1704 | return limit_ofdm; |
1705 | } |
1706 | |
1707 | static void rtw8723d_set_iqk_matrix_by_result(struct rtw_dev *rtwdev, |
1708 | u32 ofdm_swing, u8 rf_path) |
1709 | { |
1710 | struct rtw_dm_info *dm_info = &rtwdev->dm_info; |
1711 | s32 ele_A, ele_D, ele_C; |
1712 | s32 ele_A_ext, ele_C_ext, ele_D_ext; |
1713 | s32 iqk_result_x; |
1714 | s32 iqk_result_y; |
1715 | s32 value32; |
1716 | |
1717 | switch (rf_path) { |
1718 | default: |
1719 | case RF_PATH_A: |
1720 | iqk_result_x = dm_info->iqk.result.s1_x; |
1721 | iqk_result_y = dm_info->iqk.result.s1_y; |
1722 | break; |
1723 | case RF_PATH_B: |
1724 | iqk_result_x = dm_info->iqk.result.s0_x; |
1725 | iqk_result_y = dm_info->iqk.result.s0_y; |
1726 | break; |
1727 | } |
1728 | |
1729 | /* new element D */ |
1730 | ele_D = OFDM_SWING_D(ofdm_swing); |
1731 | iqk_mult(x: iqk_result_x, y: ele_D, ext: &ele_D_ext); |
1732 | /* new element A */ |
1733 | iqk_result_x = iqkxy_to_s32(val: iqk_result_x); |
1734 | ele_A = iqk_mult(x: iqk_result_x, y: ele_D, ext: &ele_A_ext); |
1735 | /* new element C */ |
1736 | iqk_result_y = iqkxy_to_s32(val: iqk_result_y); |
1737 | ele_C = iqk_mult(x: iqk_result_y, y: ele_D, ext: &ele_C_ext); |
1738 | |
1739 | switch (rf_path) { |
1740 | case RF_PATH_A: |
1741 | default: |
1742 | /* write new elements A, C, D, and element B is always 0 */ |
1743 | value32 = BIT_SET_TXIQ_ELM_ACD(ele_A, ele_C, ele_D); |
1744 | rtw_write32(rtwdev, REG_OFDM_0_XA_TX_IQ_IMBALANCE, val: value32); |
1745 | value32 = BIT_SET_TXIQ_ELM_C1(ele_C); |
1746 | rtw_write32_mask(rtwdev, REG_TXIQK_MATRIXA_LSB2_11N, MASKH4BITS, |
1747 | data: value32); |
1748 | value32 = rtw_read32(rtwdev, REG_OFDM_0_ECCA_THRESHOLD); |
1749 | value32 &= ~BIT_MASK_OFDM0_EXTS; |
1750 | value32 |= BIT_SET_OFDM0_EXTS(ele_A_ext, ele_C_ext, ele_D_ext); |
1751 | rtw_write32(rtwdev, REG_OFDM_0_ECCA_THRESHOLD, val: value32); |
1752 | break; |
1753 | |
1754 | case RF_PATH_B: |
1755 | /* write new elements A, C, D, and element B is always 0 */ |
1756 | rtw_write32_mask(rtwdev, REG_TXIQ_CD_S0, BIT_MASK_TXIQ_D_S0, data: ele_D); |
1757 | rtw_write32_mask(rtwdev, REG_TXIQ_CD_S0, BIT_MASK_TXIQ_C_S0, data: ele_C); |
1758 | rtw_write32_mask(rtwdev, REG_TXIQ_AB_S0, BIT_MASK_TXIQ_A_S0, data: ele_A); |
1759 | |
1760 | rtw_write32_mask(rtwdev, REG_TXIQ_CD_S0, BIT_MASK_TXIQ_D_EXT_S0, |
1761 | data: ele_D_ext); |
1762 | rtw_write32_mask(rtwdev, REG_TXIQ_AB_S0, BIT_MASK_TXIQ_A_EXT_S0, |
1763 | data: ele_A_ext); |
1764 | rtw_write32_mask(rtwdev, REG_TXIQ_CD_S0, BIT_MASK_TXIQ_C_EXT_S0, |
1765 | data: ele_C_ext); |
1766 | break; |
1767 | } |
1768 | } |
1769 | |
1770 | static void rtw8723d_set_iqk_matrix(struct rtw_dev *rtwdev, s8 ofdm_index, |
1771 | u8 rf_path) |
1772 | { |
1773 | struct rtw_dm_info *dm_info = &rtwdev->dm_info; |
1774 | s32 value32; |
1775 | u32 ofdm_swing; |
1776 | |
1777 | if (ofdm_index >= RTW_OFDM_SWING_TABLE_SIZE) |
1778 | ofdm_index = RTW_OFDM_SWING_TABLE_SIZE - 1; |
1779 | else if (ofdm_index < 0) |
1780 | ofdm_index = 0; |
1781 | |
1782 | ofdm_swing = rtw8723d_ofdm_swing_table[ofdm_index]; |
1783 | |
1784 | if (dm_info->iqk.done) { |
1785 | rtw8723d_set_iqk_matrix_by_result(rtwdev, ofdm_swing, rf_path); |
1786 | return; |
1787 | } |
1788 | |
1789 | switch (rf_path) { |
1790 | case RF_PATH_A: |
1791 | default: |
1792 | rtw_write32(rtwdev, REG_OFDM_0_XA_TX_IQ_IMBALANCE, val: ofdm_swing); |
1793 | rtw_write32_mask(rtwdev, REG_TXIQK_MATRIXA_LSB2_11N, MASKH4BITS, |
1794 | data: 0x00); |
1795 | value32 = rtw_read32(rtwdev, REG_OFDM_0_ECCA_THRESHOLD); |
1796 | value32 &= ~BIT_MASK_OFDM0_EXTS; |
1797 | rtw_write32(rtwdev, REG_OFDM_0_ECCA_THRESHOLD, val: value32); |
1798 | break; |
1799 | |
1800 | case RF_PATH_B: |
1801 | /* image S1:c80 to S0:Cd0 and Cd4 */ |
1802 | rtw_write32_mask(rtwdev, REG_TXIQ_AB_S0, BIT_MASK_TXIQ_A_S0, |
1803 | OFDM_SWING_A(ofdm_swing)); |
1804 | rtw_write32_mask(rtwdev, REG_TXIQ_AB_S0, BIT_MASK_TXIQ_B_S0, |
1805 | OFDM_SWING_B(ofdm_swing)); |
1806 | rtw_write32_mask(rtwdev, REG_TXIQ_CD_S0, BIT_MASK_TXIQ_C_S0, |
1807 | OFDM_SWING_C(ofdm_swing)); |
1808 | rtw_write32_mask(rtwdev, REG_TXIQ_CD_S0, BIT_MASK_TXIQ_D_S0, |
1809 | OFDM_SWING_D(ofdm_swing)); |
1810 | rtw_write32_mask(rtwdev, REG_TXIQ_CD_S0, BIT_MASK_TXIQ_D_EXT_S0, data: 0x0); |
1811 | rtw_write32_mask(rtwdev, REG_TXIQ_CD_S0, BIT_MASK_TXIQ_C_EXT_S0, data: 0x0); |
1812 | rtw_write32_mask(rtwdev, REG_TXIQ_AB_S0, BIT_MASK_TXIQ_A_EXT_S0, data: 0x0); |
1813 | break; |
1814 | } |
1815 | } |
1816 | |
1817 | static void rtw8723d_pwrtrack_set_ofdm_pwr(struct rtw_dev *rtwdev, s8 swing_idx, |
1818 | s8 txagc_idx) |
1819 | { |
1820 | struct rtw_dm_info *dm_info = &rtwdev->dm_info; |
1821 | |
1822 | dm_info->txagc_remnant_ofdm = txagc_idx; |
1823 | |
1824 | rtw8723d_set_iqk_matrix(rtwdev, ofdm_index: swing_idx, rf_path: RF_PATH_A); |
1825 | rtw8723d_set_iqk_matrix(rtwdev, ofdm_index: swing_idx, rf_path: RF_PATH_B); |
1826 | } |
1827 | |
1828 | static void rtw8723d_pwrtrack_set_cck_pwr(struct rtw_dev *rtwdev, s8 swing_idx, |
1829 | s8 txagc_idx) |
1830 | { |
1831 | struct rtw_dm_info *dm_info = &rtwdev->dm_info; |
1832 | |
1833 | dm_info->txagc_remnant_cck = txagc_idx; |
1834 | |
1835 | rtw_write32_mask(rtwdev, addr: 0xab4, mask: 0x000007FF, |
1836 | data: rtw8723d_cck_swing_table[swing_idx]); |
1837 | } |
1838 | |
1839 | static void rtw8723d_pwrtrack_set(struct rtw_dev *rtwdev, u8 path) |
1840 | { |
1841 | struct rtw_dm_info *dm_info = &rtwdev->dm_info; |
1842 | struct rtw_hal *hal = &rtwdev->hal; |
1843 | u8 limit_ofdm; |
1844 | u8 limit_cck = 40; |
1845 | s8 final_ofdm_swing_index; |
1846 | s8 final_cck_swing_index; |
1847 | |
1848 | limit_ofdm = rtw8723d_pwrtrack_get_limit_ofdm(rtwdev); |
1849 | |
1850 | final_ofdm_swing_index = RTW_DEF_OFDM_SWING_INDEX + |
1851 | dm_info->delta_power_index[path]; |
1852 | final_cck_swing_index = RTW_DEF_CCK_SWING_INDEX + |
1853 | dm_info->delta_power_index[path]; |
1854 | |
1855 | if (final_ofdm_swing_index > limit_ofdm) |
1856 | rtw8723d_pwrtrack_set_ofdm_pwr(rtwdev, swing_idx: limit_ofdm, |
1857 | txagc_idx: final_ofdm_swing_index - limit_ofdm); |
1858 | else if (final_ofdm_swing_index < 0) |
1859 | rtw8723d_pwrtrack_set_ofdm_pwr(rtwdev, swing_idx: 0, |
1860 | txagc_idx: final_ofdm_swing_index); |
1861 | else |
1862 | rtw8723d_pwrtrack_set_ofdm_pwr(rtwdev, swing_idx: final_ofdm_swing_index, txagc_idx: 0); |
1863 | |
1864 | if (final_cck_swing_index > limit_cck) |
1865 | rtw8723d_pwrtrack_set_cck_pwr(rtwdev, swing_idx: limit_cck, |
1866 | txagc_idx: final_cck_swing_index - limit_cck); |
1867 | else if (final_cck_swing_index < 0) |
1868 | rtw8723d_pwrtrack_set_cck_pwr(rtwdev, swing_idx: 0, |
1869 | txagc_idx: final_cck_swing_index); |
1870 | else |
1871 | rtw8723d_pwrtrack_set_cck_pwr(rtwdev, swing_idx: final_cck_swing_index, txagc_idx: 0); |
1872 | |
1873 | rtw_phy_set_tx_power_level(rtwdev, channel: hal->current_channel); |
1874 | } |
1875 | |
1876 | static void rtw8723d_pwrtrack_set_xtal(struct rtw_dev *rtwdev, u8 therm_path, |
1877 | u8 delta) |
1878 | { |
1879 | struct rtw_dm_info *dm_info = &rtwdev->dm_info; |
1880 | const struct rtw_pwr_track_tbl *tbl = rtwdev->chip->pwr_track_tbl; |
1881 | const s8 *pwrtrk_xtal; |
1882 | s8 xtal_cap; |
1883 | |
1884 | if (dm_info->thermal_avg[therm_path] > |
1885 | rtwdev->efuse.thermal_meter[therm_path]) |
1886 | pwrtrk_xtal = tbl->pwrtrk_xtal_p; |
1887 | else |
1888 | pwrtrk_xtal = tbl->pwrtrk_xtal_n; |
1889 | |
1890 | xtal_cap = rtwdev->efuse.crystal_cap & 0x3F; |
1891 | xtal_cap = clamp_t(s8, xtal_cap + pwrtrk_xtal[delta], 0, 0x3F); |
1892 | rtw_write32_mask(rtwdev, REG_AFE_CTRL3, BIT_MASK_XTAL, |
1893 | data: xtal_cap | (xtal_cap << 6)); |
1894 | } |
1895 | |
1896 | static void rtw8723d_phy_pwrtrack(struct rtw_dev *rtwdev) |
1897 | { |
1898 | struct rtw_dm_info *dm_info = &rtwdev->dm_info; |
1899 | struct rtw_swing_table swing_table; |
1900 | u8 thermal_value, delta, path; |
1901 | bool do_iqk = false; |
1902 | |
1903 | rtw_phy_config_swing_table(rtwdev, swing_table: &swing_table); |
1904 | |
1905 | if (rtwdev->efuse.thermal_meter[0] == 0xff) |
1906 | return; |
1907 | |
1908 | thermal_value = rtw_read_rf(rtwdev, rf_path: RF_PATH_A, RF_T_METER, mask: 0xfc00); |
1909 | |
1910 | rtw_phy_pwrtrack_avg(rtwdev, thermal: thermal_value, path: RF_PATH_A); |
1911 | |
1912 | do_iqk = rtw_phy_pwrtrack_need_iqk(rtwdev); |
1913 | |
1914 | if (do_iqk) |
1915 | rtw8723d_lck(rtwdev); |
1916 | |
1917 | if (dm_info->pwr_trk_init_trigger) |
1918 | dm_info->pwr_trk_init_trigger = false; |
1919 | else if (!rtw_phy_pwrtrack_thermal_changed(rtwdev, thermal: thermal_value, |
1920 | path: RF_PATH_A)) |
1921 | goto iqk; |
1922 | |
1923 | delta = rtw_phy_pwrtrack_get_delta(rtwdev, path: RF_PATH_A); |
1924 | |
1925 | delta = min_t(u8, delta, RTW_PWR_TRK_TBL_SZ - 1); |
1926 | |
1927 | for (path = 0; path < rtwdev->hal.rf_path_num; path++) { |
1928 | s8 delta_cur, delta_last; |
1929 | |
1930 | delta_last = dm_info->delta_power_index[path]; |
1931 | delta_cur = rtw_phy_pwrtrack_get_pwridx(rtwdev, swing_table: &swing_table, |
1932 | tbl_path: path, therm_path: RF_PATH_A, delta); |
1933 | if (delta_last == delta_cur) |
1934 | continue; |
1935 | |
1936 | dm_info->delta_power_index[path] = delta_cur; |
1937 | rtw8723d_pwrtrack_set(rtwdev, path); |
1938 | } |
1939 | |
1940 | rtw8723d_pwrtrack_set_xtal(rtwdev, therm_path: RF_PATH_A, delta); |
1941 | |
1942 | iqk: |
1943 | if (do_iqk) |
1944 | rtw8723d_phy_calibration(rtwdev); |
1945 | } |
1946 | |
1947 | static void rtw8723d_pwr_track(struct rtw_dev *rtwdev) |
1948 | { |
1949 | struct rtw_efuse *efuse = &rtwdev->efuse; |
1950 | struct rtw_dm_info *dm_info = &rtwdev->dm_info; |
1951 | |
1952 | if (efuse->power_track_type != 0) |
1953 | return; |
1954 | |
1955 | if (!dm_info->pwr_trk_triggered) { |
1956 | rtw_write_rf(rtwdev, rf_path: RF_PATH_A, RF_T_METER, |
1957 | GENMASK(17, 16), data: 0x03); |
1958 | dm_info->pwr_trk_triggered = true; |
1959 | return; |
1960 | } |
1961 | |
1962 | rtw8723d_phy_pwrtrack(rtwdev); |
1963 | dm_info->pwr_trk_triggered = false; |
1964 | } |
1965 | |
1966 | static void rtw8723d_fill_txdesc_checksum(struct rtw_dev *rtwdev, |
1967 | struct rtw_tx_pkt_info *pkt_info, |
1968 | u8 *txdesc) |
1969 | { |
1970 | size_t words = 32 / 2; /* calculate the first 32 bytes (16 words) */ |
1971 | __le16 chksum = 0; |
1972 | __le16 *data = (__le16 *)(txdesc); |
1973 | struct rtw_tx_desc *tx_desc = (struct rtw_tx_desc *)txdesc; |
1974 | |
1975 | le32p_replace_bits(p: &tx_desc->w7, val: 0, RTW_TX_DESC_W7_TXDESC_CHECKSUM); |
1976 | |
1977 | while (words--) |
1978 | chksum ^= *data++; |
1979 | |
1980 | chksum = ~chksum; |
1981 | |
1982 | le32p_replace_bits(p: &tx_desc->w7, __le16_to_cpu(chksum), |
1983 | RTW_TX_DESC_W7_TXDESC_CHECKSUM); |
1984 | } |
1985 | |
1986 | static struct rtw_chip_ops rtw8723d_ops = { |
1987 | .phy_set_param = rtw8723d_phy_set_param, |
1988 | .read_efuse = rtw8723d_read_efuse, |
1989 | .query_rx_desc = rtw8723d_query_rx_desc, |
1990 | .set_channel = rtw8723d_set_channel, |
1991 | .mac_init = rtw8723d_mac_init, |
1992 | .shutdown = rtw8723d_shutdown, |
1993 | .read_rf = rtw_phy_read_rf_sipi, |
1994 | .write_rf = rtw_phy_write_rf_reg_sipi, |
1995 | .set_tx_power_index = rtw8723d_set_tx_power_index, |
1996 | .set_antenna = NULL, |
1997 | .cfg_ldo25 = rtw8723d_cfg_ldo25, |
1998 | .efuse_grant = rtw8723d_efuse_grant, |
1999 | .false_alarm_statistics = rtw8723d_false_alarm_statistics, |
2000 | .phy_calibration = rtw8723d_phy_calibration, |
2001 | .cck_pd_set = rtw8723d_phy_cck_pd_set, |
2002 | .pwr_track = rtw8723d_pwr_track, |
2003 | .config_bfee = NULL, |
2004 | .set_gid_table = NULL, |
2005 | .cfg_csi_rate = NULL, |
2006 | .fill_txdesc_checksum = rtw8723d_fill_txdesc_checksum, |
2007 | |
2008 | .coex_set_init = rtw8723d_coex_cfg_init, |
2009 | .coex_set_ant_switch = NULL, |
2010 | .coex_set_gnt_fix = rtw8723d_coex_cfg_gnt_fix, |
2011 | .coex_set_gnt_debug = rtw8723d_coex_cfg_gnt_debug, |
2012 | .coex_set_rfe_type = rtw8723d_coex_cfg_rfe_type, |
2013 | .coex_set_wl_tx_power = rtw8723d_coex_cfg_wl_tx_power, |
2014 | .coex_set_wl_rx_gain = rtw8723d_coex_cfg_wl_rx_gain, |
2015 | }; |
2016 | |
2017 | /* Shared-Antenna Coex Table */ |
2018 | static const struct coex_table_para table_sant_8723d[] = { |
2019 | {0xffffffff, 0xffffffff}, /* case-0 */ |
2020 | {0x55555555, 0x55555555}, |
2021 | {0x66555555, 0x66555555}, |
2022 | {0xaaaaaaaa, 0xaaaaaaaa}, |
2023 | {0x5a5a5a5a, 0x5a5a5a5a}, |
2024 | {0xfafafafa, 0xfafafafa}, /* case-5 */ |
2025 | {0x6a5a5555, 0xaaaaaaaa}, |
2026 | {0x6a5a56aa, 0x6a5a56aa}, |
2027 | {0x6a5a5a5a, 0x6a5a5a5a}, |
2028 | {0x66555555, 0x5a5a5a5a}, |
2029 | {0x66555555, 0x6a5a5a5a}, /* case-10 */ |
2030 | {0x66555555, 0x6a5a5aaa}, |
2031 | {0x66555555, 0x5a5a5aaa}, |
2032 | {0x66555555, 0x6aaa5aaa}, |
2033 | {0x66555555, 0xaaaa5aaa}, |
2034 | {0x66555555, 0xaaaaaaaa}, /* case-15 */ |
2035 | {0xffff55ff, 0xfafafafa}, |
2036 | {0xffff55ff, 0x6afa5afa}, |
2037 | {0xaaffffaa, 0xfafafafa}, |
2038 | {0xaa5555aa, 0x5a5a5a5a}, |
2039 | {0xaa5555aa, 0x6a5a5a5a}, /* case-20 */ |
2040 | {0xaa5555aa, 0xaaaaaaaa}, |
2041 | {0xffffffff, 0x5a5a5a5a}, |
2042 | {0xffffffff, 0x5a5a5a5a}, |
2043 | {0xffffffff, 0x55555555}, |
2044 | {0xffffffff, 0x5a5a5aaa}, /* case-25 */ |
2045 | {0x55555555, 0x5a5a5a5a}, |
2046 | {0x55555555, 0xaaaaaaaa}, |
2047 | {0x55555555, 0x6a5a6a5a}, |
2048 | {0x66556655, 0x66556655}, |
2049 | {0x66556aaa, 0x6a5a6aaa}, /* case-30 */ |
2050 | {0xffffffff, 0x5aaa5aaa}, |
2051 | {0x56555555, 0x5a5a5aaa}, |
2052 | }; |
2053 | |
2054 | /* Non-Shared-Antenna Coex Table */ |
2055 | static const struct coex_table_para table_nsant_8723d[] = { |
2056 | {0xffffffff, 0xffffffff}, /* case-100 */ |
2057 | {0x55555555, 0x55555555}, |
2058 | {0x66555555, 0x66555555}, |
2059 | {0xaaaaaaaa, 0xaaaaaaaa}, |
2060 | {0x5a5a5a5a, 0x5a5a5a5a}, |
2061 | {0xfafafafa, 0xfafafafa}, /* case-105 */ |
2062 | {0x5afa5afa, 0x5afa5afa}, |
2063 | {0x55555555, 0xfafafafa}, |
2064 | {0x66555555, 0xfafafafa}, |
2065 | {0x66555555, 0x5a5a5a5a}, |
2066 | {0x66555555, 0x6a5a5a5a}, /* case-110 */ |
2067 | {0x66555555, 0xaaaaaaaa}, |
2068 | {0xffff55ff, 0xfafafafa}, |
2069 | {0xffff55ff, 0x5afa5afa}, |
2070 | {0xffff55ff, 0xaaaaaaaa}, |
2071 | {0xffff55ff, 0xffff55ff}, /* case-115 */ |
2072 | {0xaaffffaa, 0x5afa5afa}, |
2073 | {0xaaffffaa, 0xaaaaaaaa}, |
2074 | {0xffffffff, 0xfafafafa}, |
2075 | {0xffffffff, 0x5afa5afa}, |
2076 | {0xffffffff, 0xaaaaaaaa}, /* case-120 */ |
2077 | {0x55ff55ff, 0x5afa5afa}, |
2078 | {0x55ff55ff, 0xaaaaaaaa}, |
2079 | {0x55ff55ff, 0x55ff55ff} |
2080 | }; |
2081 | |
2082 | /* Shared-Antenna TDMA */ |
2083 | static const struct coex_tdma_para tdma_sant_8723d[] = { |
2084 | { {0x00, 0x00, 0x00, 0x00, 0x00} }, /* case-0 */ |
2085 | { {0x61, 0x45, 0x03, 0x11, 0x11} }, /* case-1 */ |
2086 | { {0x61, 0x3a, 0x03, 0x11, 0x11} }, |
2087 | { {0x61, 0x30, 0x03, 0x11, 0x11} }, |
2088 | { {0x61, 0x20, 0x03, 0x11, 0x11} }, |
2089 | { {0x61, 0x10, 0x03, 0x11, 0x11} }, /* case-5 */ |
2090 | { {0x61, 0x45, 0x03, 0x11, 0x10} }, |
2091 | { {0x61, 0x3a, 0x03, 0x11, 0x10} }, |
2092 | { {0x61, 0x30, 0x03, 0x11, 0x10} }, |
2093 | { {0x61, 0x20, 0x03, 0x11, 0x10} }, |
2094 | { {0x61, 0x10, 0x03, 0x11, 0x10} }, /* case-10 */ |
2095 | { {0x61, 0x08, 0x03, 0x11, 0x14} }, |
2096 | { {0x61, 0x08, 0x03, 0x10, 0x14} }, |
2097 | { {0x51, 0x08, 0x03, 0x10, 0x54} }, |
2098 | { {0x51, 0x08, 0x03, 0x10, 0x55} }, |
2099 | { {0x51, 0x08, 0x07, 0x10, 0x54} }, /* case-15 */ |
2100 | { {0x51, 0x45, 0x03, 0x10, 0x50} }, |
2101 | { {0x51, 0x3a, 0x03, 0x10, 0x50} }, |
2102 | { {0x51, 0x30, 0x03, 0x10, 0x50} }, |
2103 | { {0x51, 0x20, 0x03, 0x10, 0x50} }, |
2104 | { {0x51, 0x10, 0x03, 0x10, 0x50} }, /* case-20 */ |
2105 | { {0x51, 0x4a, 0x03, 0x10, 0x50} }, |
2106 | { {0x51, 0x0c, 0x03, 0x10, 0x54} }, |
2107 | { {0x55, 0x08, 0x03, 0x10, 0x54} }, |
2108 | { {0x65, 0x10, 0x03, 0x11, 0x10} }, |
2109 | { {0x51, 0x10, 0x03, 0x10, 0x51} }, /* case-25 */ |
2110 | { {0x51, 0x08, 0x03, 0x10, 0x50} }, |
2111 | { {0x61, 0x08, 0x03, 0x11, 0x11} } |
2112 | }; |
2113 | |
2114 | /* Non-Shared-Antenna TDMA */ |
2115 | static const struct coex_tdma_para tdma_nsant_8723d[] = { |
2116 | { {0x00, 0x00, 0x00, 0x00, 0x01} }, /* case-100 */ |
2117 | { {0x61, 0x45, 0x03, 0x11, 0x11} }, /* case-101 */ |
2118 | { {0x61, 0x3a, 0x03, 0x11, 0x11} }, |
2119 | { {0x61, 0x30, 0x03, 0x11, 0x11} }, |
2120 | { {0x61, 0x20, 0x03, 0x11, 0x11} }, |
2121 | { {0x61, 0x10, 0x03, 0x11, 0x11} }, /* case-105 */ |
2122 | { {0x61, 0x45, 0x03, 0x11, 0x10} }, |
2123 | { {0x61, 0x3a, 0x03, 0x11, 0x10} }, |
2124 | { {0x61, 0x30, 0x03, 0x11, 0x10} }, |
2125 | { {0x61, 0x20, 0x03, 0x11, 0x10} }, |
2126 | { {0x61, 0x10, 0x03, 0x11, 0x10} }, /* case-110 */ |
2127 | { {0x61, 0x08, 0x03, 0x11, 0x14} }, |
2128 | { {0x61, 0x08, 0x03, 0x10, 0x14} }, |
2129 | { {0x51, 0x08, 0x03, 0x10, 0x54} }, |
2130 | { {0x51, 0x08, 0x03, 0x10, 0x55} }, |
2131 | { {0x51, 0x08, 0x07, 0x10, 0x54} }, /* case-115 */ |
2132 | { {0x51, 0x45, 0x03, 0x10, 0x50} }, |
2133 | { {0x51, 0x3a, 0x03, 0x10, 0x50} }, |
2134 | { {0x51, 0x30, 0x03, 0x10, 0x50} }, |
2135 | { {0x51, 0x20, 0x03, 0x10, 0x50} }, |
2136 | { {0x51, 0x10, 0x03, 0x10, 0x50} }, /* case-120 */ |
2137 | { {0x51, 0x08, 0x03, 0x10, 0x50} } |
2138 | }; |
2139 | |
2140 | /* rssi in percentage % (dbm = % - 100) */ |
2141 | static const u8 [] = {60, 50, 44, 30}; |
2142 | static const u8 [] = {30, 30, 30, 30}; |
2143 | static const struct coex_5g_afh_map afh_5g_8723d[] = { {0, 0, 0} }; |
2144 | |
2145 | static const struct rtw_hw_reg btg_reg_8723d = { |
2146 | .addr = REG_BTG_SEL, .mask = BIT_MASK_BTG_WL, |
2147 | }; |
2148 | |
2149 | /* wl_tx_dec_power, bt_tx_dec_power, wl_rx_gain, bt_rx_lna_constrain */ |
2150 | static const struct coex_rf_para rf_para_tx_8723d[] = { |
2151 | {0, 0, false, 7}, /* for normal */ |
2152 | {0, 10, false, 7}, /* for WL-CPT */ |
2153 | {1, 0, true, 4}, |
2154 | {1, 2, true, 4}, |
2155 | {1, 10, true, 4}, |
2156 | {1, 15, true, 4} |
2157 | }; |
2158 | |
2159 | static const struct coex_rf_para rf_para_rx_8723d[] = { |
2160 | {0, 0, false, 7}, /* for normal */ |
2161 | {0, 10, false, 7}, /* for WL-CPT */ |
2162 | {1, 0, true, 5}, |
2163 | {1, 2, true, 5}, |
2164 | {1, 10, true, 5}, |
2165 | {1, 15, true, 5} |
2166 | }; |
2167 | |
2168 | static const struct rtw_pwr_seq_cmd trans_carddis_to_cardemu_8723d[] = { |
2169 | {0x0005, |
2170 | RTW_PWR_CUT_ALL_MSK, |
2171 | RTW_PWR_INTF_ALL_MSK, |
2172 | RTW_PWR_ADDR_MAC, |
2173 | RTW_PWR_CMD_WRITE, BIT(3) | BIT(7), 0}, |
2174 | {0x0086, |
2175 | RTW_PWR_CUT_ALL_MSK, |
2176 | RTW_PWR_INTF_SDIO_MSK, |
2177 | RTW_PWR_ADDR_SDIO, |
2178 | RTW_PWR_CMD_WRITE, BIT(0), 0}, |
2179 | {0x0086, |
2180 | RTW_PWR_CUT_ALL_MSK, |
2181 | RTW_PWR_INTF_SDIO_MSK, |
2182 | RTW_PWR_ADDR_SDIO, |
2183 | RTW_PWR_CMD_POLLING, BIT(1), BIT(1)}, |
2184 | {0x004A, |
2185 | RTW_PWR_CUT_ALL_MSK, |
2186 | RTW_PWR_INTF_USB_MSK, |
2187 | RTW_PWR_ADDR_MAC, |
2188 | RTW_PWR_CMD_WRITE, BIT(0), 0}, |
2189 | {0x0005, |
2190 | RTW_PWR_CUT_ALL_MSK, |
2191 | RTW_PWR_INTF_ALL_MSK, |
2192 | RTW_PWR_ADDR_MAC, |
2193 | RTW_PWR_CMD_WRITE, BIT(3) | BIT(4), 0}, |
2194 | {0x0023, |
2195 | RTW_PWR_CUT_ALL_MSK, |
2196 | RTW_PWR_INTF_SDIO_MSK, |
2197 | RTW_PWR_ADDR_MAC, |
2198 | RTW_PWR_CMD_WRITE, BIT(4), 0}, |
2199 | {0x0301, |
2200 | RTW_PWR_CUT_ALL_MSK, |
2201 | RTW_PWR_INTF_PCI_MSK, |
2202 | RTW_PWR_ADDR_MAC, |
2203 | RTW_PWR_CMD_WRITE, 0xFF, 0}, |
2204 | {0xFFFF, |
2205 | RTW_PWR_CUT_ALL_MSK, |
2206 | RTW_PWR_INTF_ALL_MSK, |
2207 | 0, |
2208 | RTW_PWR_CMD_END, 0, 0}, |
2209 | }; |
2210 | |
2211 | static const struct rtw_pwr_seq_cmd trans_cardemu_to_act_8723d[] = { |
2212 | {0x0020, |
2213 | RTW_PWR_CUT_ALL_MSK, |
2214 | RTW_PWR_INTF_USB_MSK | RTW_PWR_INTF_SDIO_MSK, |
2215 | RTW_PWR_ADDR_MAC, |
2216 | RTW_PWR_CMD_WRITE, BIT(0), BIT(0)}, |
2217 | {0x0001, |
2218 | RTW_PWR_CUT_ALL_MSK, |
2219 | RTW_PWR_INTF_USB_MSK | RTW_PWR_INTF_SDIO_MSK, |
2220 | RTW_PWR_ADDR_MAC, |
2221 | RTW_PWR_CMD_DELAY, 1, RTW_PWR_DELAY_MS}, |
2222 | {0x0000, |
2223 | RTW_PWR_CUT_ALL_MSK, |
2224 | RTW_PWR_INTF_USB_MSK | RTW_PWR_INTF_SDIO_MSK, |
2225 | RTW_PWR_ADDR_MAC, |
2226 | RTW_PWR_CMD_WRITE, BIT(5), 0}, |
2227 | {0x0005, |
2228 | RTW_PWR_CUT_ALL_MSK, |
2229 | RTW_PWR_INTF_ALL_MSK, |
2230 | RTW_PWR_ADDR_MAC, |
2231 | RTW_PWR_CMD_WRITE, (BIT(4) | BIT(3) | BIT(2)), 0}, |
2232 | {0x0075, |
2233 | RTW_PWR_CUT_ALL_MSK, |
2234 | RTW_PWR_INTF_PCI_MSK, |
2235 | RTW_PWR_ADDR_MAC, |
2236 | RTW_PWR_CMD_WRITE, BIT(0), BIT(0)}, |
2237 | {0x0006, |
2238 | RTW_PWR_CUT_ALL_MSK, |
2239 | RTW_PWR_INTF_ALL_MSK, |
2240 | RTW_PWR_ADDR_MAC, |
2241 | RTW_PWR_CMD_POLLING, BIT(1), BIT(1)}, |
2242 | {0x0075, |
2243 | RTW_PWR_CUT_ALL_MSK, |
2244 | RTW_PWR_INTF_PCI_MSK, |
2245 | RTW_PWR_ADDR_MAC, |
2246 | RTW_PWR_CMD_WRITE, BIT(0), 0}, |
2247 | {0x0006, |
2248 | RTW_PWR_CUT_ALL_MSK, |
2249 | RTW_PWR_INTF_ALL_MSK, |
2250 | RTW_PWR_ADDR_MAC, |
2251 | RTW_PWR_CMD_WRITE, BIT(0), BIT(0)}, |
2252 | {0x0005, |
2253 | RTW_PWR_CUT_ALL_MSK, |
2254 | RTW_PWR_INTF_ALL_MSK, |
2255 | RTW_PWR_ADDR_MAC, |
2256 | RTW_PWR_CMD_POLLING, (BIT(1) | BIT(0)), 0}, |
2257 | {0x0005, |
2258 | RTW_PWR_CUT_ALL_MSK, |
2259 | RTW_PWR_INTF_ALL_MSK, |
2260 | RTW_PWR_ADDR_MAC, |
2261 | RTW_PWR_CMD_WRITE, BIT(7), 0}, |
2262 | {0x0005, |
2263 | RTW_PWR_CUT_ALL_MSK, |
2264 | RTW_PWR_INTF_ALL_MSK, |
2265 | RTW_PWR_ADDR_MAC, |
2266 | RTW_PWR_CMD_WRITE, (BIT(4) | BIT(3)), 0}, |
2267 | {0x0005, |
2268 | RTW_PWR_CUT_ALL_MSK, |
2269 | RTW_PWR_INTF_ALL_MSK, |
2270 | RTW_PWR_ADDR_MAC, |
2271 | RTW_PWR_CMD_WRITE, BIT(0), BIT(0)}, |
2272 | {0x0005, |
2273 | RTW_PWR_CUT_ALL_MSK, |
2274 | RTW_PWR_INTF_ALL_MSK, |
2275 | RTW_PWR_ADDR_MAC, |
2276 | RTW_PWR_CMD_POLLING, BIT(0), 0}, |
2277 | {0x0010, |
2278 | RTW_PWR_CUT_ALL_MSK, |
2279 | RTW_PWR_INTF_ALL_MSK, |
2280 | RTW_PWR_ADDR_MAC, |
2281 | RTW_PWR_CMD_WRITE, BIT(6), BIT(6)}, |
2282 | {0x0049, |
2283 | RTW_PWR_CUT_ALL_MSK, |
2284 | RTW_PWR_INTF_ALL_MSK, |
2285 | RTW_PWR_ADDR_MAC, |
2286 | RTW_PWR_CMD_WRITE, BIT(1), BIT(1)}, |
2287 | {0x0063, |
2288 | RTW_PWR_CUT_ALL_MSK, |
2289 | RTW_PWR_INTF_ALL_MSK, |
2290 | RTW_PWR_ADDR_MAC, |
2291 | RTW_PWR_CMD_WRITE, BIT(1), BIT(1)}, |
2292 | {0x0062, |
2293 | RTW_PWR_CUT_ALL_MSK, |
2294 | RTW_PWR_INTF_ALL_MSK, |
2295 | RTW_PWR_ADDR_MAC, |
2296 | RTW_PWR_CMD_WRITE, BIT(1), 0}, |
2297 | {0x0058, |
2298 | RTW_PWR_CUT_ALL_MSK, |
2299 | RTW_PWR_INTF_ALL_MSK, |
2300 | RTW_PWR_ADDR_MAC, |
2301 | RTW_PWR_CMD_WRITE, BIT(0), BIT(0)}, |
2302 | {0x005A, |
2303 | RTW_PWR_CUT_ALL_MSK, |
2304 | RTW_PWR_INTF_ALL_MSK, |
2305 | RTW_PWR_ADDR_MAC, |
2306 | RTW_PWR_CMD_WRITE, BIT(1), BIT(1)}, |
2307 | {0x0068, |
2308 | RTW_PWR_CUT_TEST_MSK, |
2309 | RTW_PWR_INTF_ALL_MSK, |
2310 | RTW_PWR_ADDR_MAC, |
2311 | RTW_PWR_CMD_WRITE, BIT(3), BIT(3)}, |
2312 | {0x0069, |
2313 | RTW_PWR_CUT_ALL_MSK, |
2314 | RTW_PWR_INTF_ALL_MSK, |
2315 | RTW_PWR_ADDR_MAC, |
2316 | RTW_PWR_CMD_WRITE, BIT(6), BIT(6)}, |
2317 | {0x001f, |
2318 | RTW_PWR_CUT_ALL_MSK, |
2319 | RTW_PWR_INTF_ALL_MSK, |
2320 | RTW_PWR_ADDR_MAC, |
2321 | RTW_PWR_CMD_WRITE, 0xFF, 0x00}, |
2322 | {0x0077, |
2323 | RTW_PWR_CUT_ALL_MSK, |
2324 | RTW_PWR_INTF_ALL_MSK, |
2325 | RTW_PWR_ADDR_MAC, |
2326 | RTW_PWR_CMD_WRITE, 0xFF, 0x00}, |
2327 | {0x001f, |
2328 | RTW_PWR_CUT_ALL_MSK, |
2329 | RTW_PWR_INTF_ALL_MSK, |
2330 | RTW_PWR_ADDR_MAC, |
2331 | RTW_PWR_CMD_WRITE, 0xFF, 0x07}, |
2332 | {0x0077, |
2333 | RTW_PWR_CUT_ALL_MSK, |
2334 | RTW_PWR_INTF_ALL_MSK, |
2335 | RTW_PWR_ADDR_MAC, |
2336 | RTW_PWR_CMD_WRITE, 0xFF, 0x07}, |
2337 | {0xFFFF, |
2338 | RTW_PWR_CUT_ALL_MSK, |
2339 | RTW_PWR_INTF_ALL_MSK, |
2340 | 0, |
2341 | RTW_PWR_CMD_END, 0, 0}, |
2342 | }; |
2343 | |
2344 | static const struct rtw_pwr_seq_cmd *card_enable_flow_8723d[] = { |
2345 | trans_carddis_to_cardemu_8723d, |
2346 | trans_cardemu_to_act_8723d, |
2347 | NULL |
2348 | }; |
2349 | |
2350 | static const struct rtw_pwr_seq_cmd trans_act_to_lps_8723d[] = { |
2351 | {0x0301, |
2352 | RTW_PWR_CUT_ALL_MSK, |
2353 | RTW_PWR_INTF_PCI_MSK, |
2354 | RTW_PWR_ADDR_MAC, |
2355 | RTW_PWR_CMD_WRITE, 0xFF, 0xFF}, |
2356 | {0x0522, |
2357 | RTW_PWR_CUT_ALL_MSK, |
2358 | RTW_PWR_INTF_ALL_MSK, |
2359 | RTW_PWR_ADDR_MAC, |
2360 | RTW_PWR_CMD_WRITE, 0xFF, 0xFF}, |
2361 | {0x05F8, |
2362 | RTW_PWR_CUT_ALL_MSK, |
2363 | RTW_PWR_INTF_ALL_MSK, |
2364 | RTW_PWR_ADDR_MAC, |
2365 | RTW_PWR_CMD_POLLING, 0xFF, 0}, |
2366 | {0x05F9, |
2367 | RTW_PWR_CUT_ALL_MSK, |
2368 | RTW_PWR_INTF_ALL_MSK, |
2369 | RTW_PWR_ADDR_MAC, |
2370 | RTW_PWR_CMD_POLLING, 0xFF, 0}, |
2371 | {0x05FA, |
2372 | RTW_PWR_CUT_ALL_MSK, |
2373 | RTW_PWR_INTF_ALL_MSK, |
2374 | RTW_PWR_ADDR_MAC, |
2375 | RTW_PWR_CMD_POLLING, 0xFF, 0}, |
2376 | {0x05FB, |
2377 | RTW_PWR_CUT_ALL_MSK, |
2378 | RTW_PWR_INTF_ALL_MSK, |
2379 | RTW_PWR_ADDR_MAC, |
2380 | RTW_PWR_CMD_POLLING, 0xFF, 0}, |
2381 | {0x0002, |
2382 | RTW_PWR_CUT_ALL_MSK, |
2383 | RTW_PWR_INTF_ALL_MSK, |
2384 | RTW_PWR_ADDR_MAC, |
2385 | RTW_PWR_CMD_WRITE, BIT(0), 0}, |
2386 | {0x0002, |
2387 | RTW_PWR_CUT_ALL_MSK, |
2388 | RTW_PWR_INTF_ALL_MSK, |
2389 | RTW_PWR_ADDR_MAC, |
2390 | RTW_PWR_CMD_DELAY, 0, RTW_PWR_DELAY_US}, |
2391 | {0x0002, |
2392 | RTW_PWR_CUT_ALL_MSK, |
2393 | RTW_PWR_INTF_ALL_MSK, |
2394 | RTW_PWR_ADDR_MAC, |
2395 | RTW_PWR_CMD_WRITE, BIT(1), 0}, |
2396 | {0x0100, |
2397 | RTW_PWR_CUT_ALL_MSK, |
2398 | RTW_PWR_INTF_ALL_MSK, |
2399 | RTW_PWR_ADDR_MAC, |
2400 | RTW_PWR_CMD_WRITE, 0xFF, 0x03}, |
2401 | {0x0101, |
2402 | RTW_PWR_CUT_ALL_MSK, |
2403 | RTW_PWR_INTF_ALL_MSK, |
2404 | RTW_PWR_ADDR_MAC, |
2405 | RTW_PWR_CMD_WRITE, BIT(1), 0}, |
2406 | {0x0093, |
2407 | RTW_PWR_CUT_ALL_MSK, |
2408 | RTW_PWR_INTF_SDIO_MSK, |
2409 | RTW_PWR_ADDR_MAC, |
2410 | RTW_PWR_CMD_WRITE, 0xFF, 0x00}, |
2411 | {0x0553, |
2412 | RTW_PWR_CUT_ALL_MSK, |
2413 | RTW_PWR_INTF_ALL_MSK, |
2414 | RTW_PWR_ADDR_MAC, |
2415 | RTW_PWR_CMD_WRITE, BIT(5), BIT(5)}, |
2416 | {0xFFFF, |
2417 | RTW_PWR_CUT_ALL_MSK, |
2418 | RTW_PWR_INTF_ALL_MSK, |
2419 | 0, |
2420 | RTW_PWR_CMD_END, 0, 0}, |
2421 | }; |
2422 | |
2423 | static const struct rtw_pwr_seq_cmd trans_act_to_pre_carddis_8723d[] = { |
2424 | {0x0003, |
2425 | RTW_PWR_CUT_ALL_MSK, |
2426 | RTW_PWR_INTF_ALL_MSK, |
2427 | RTW_PWR_ADDR_MAC, |
2428 | RTW_PWR_CMD_WRITE, BIT(2), 0}, |
2429 | {0x0080, |
2430 | RTW_PWR_CUT_ALL_MSK, |
2431 | RTW_PWR_INTF_ALL_MSK, |
2432 | RTW_PWR_ADDR_MAC, |
2433 | RTW_PWR_CMD_WRITE, 0xFF, 0}, |
2434 | {0xFFFF, |
2435 | RTW_PWR_CUT_ALL_MSK, |
2436 | RTW_PWR_INTF_ALL_MSK, |
2437 | 0, |
2438 | RTW_PWR_CMD_END, 0, 0}, |
2439 | }; |
2440 | |
2441 | static const struct rtw_pwr_seq_cmd trans_act_to_cardemu_8723d[] = { |
2442 | {0x0002, |
2443 | RTW_PWR_CUT_ALL_MSK, |
2444 | RTW_PWR_INTF_ALL_MSK, |
2445 | RTW_PWR_ADDR_MAC, |
2446 | RTW_PWR_CMD_WRITE, BIT(0), 0}, |
2447 | {0x0049, |
2448 | RTW_PWR_CUT_ALL_MSK, |
2449 | RTW_PWR_INTF_ALL_MSK, |
2450 | RTW_PWR_ADDR_MAC, |
2451 | RTW_PWR_CMD_WRITE, BIT(1), 0}, |
2452 | {0x0006, |
2453 | RTW_PWR_CUT_ALL_MSK, |
2454 | RTW_PWR_INTF_ALL_MSK, |
2455 | RTW_PWR_ADDR_MAC, |
2456 | RTW_PWR_CMD_WRITE, BIT(0), BIT(0)}, |
2457 | {0x0005, |
2458 | RTW_PWR_CUT_ALL_MSK, |
2459 | RTW_PWR_INTF_ALL_MSK, |
2460 | RTW_PWR_ADDR_MAC, |
2461 | RTW_PWR_CMD_WRITE, BIT(1), BIT(1)}, |
2462 | {0x0005, |
2463 | RTW_PWR_CUT_ALL_MSK, |
2464 | RTW_PWR_INTF_ALL_MSK, |
2465 | RTW_PWR_ADDR_MAC, |
2466 | RTW_PWR_CMD_POLLING, BIT(1), 0}, |
2467 | {0x0010, |
2468 | RTW_PWR_CUT_ALL_MSK, |
2469 | RTW_PWR_INTF_ALL_MSK, |
2470 | RTW_PWR_ADDR_MAC, |
2471 | RTW_PWR_CMD_WRITE, BIT(6), 0}, |
2472 | {0x0000, |
2473 | RTW_PWR_CUT_ALL_MSK, |
2474 | RTW_PWR_INTF_USB_MSK | RTW_PWR_INTF_SDIO_MSK, |
2475 | RTW_PWR_ADDR_MAC, |
2476 | RTW_PWR_CMD_WRITE, BIT(5), BIT(5)}, |
2477 | {0x0020, |
2478 | RTW_PWR_CUT_ALL_MSK, |
2479 | RTW_PWR_INTF_USB_MSK | RTW_PWR_INTF_SDIO_MSK, |
2480 | RTW_PWR_ADDR_MAC, |
2481 | RTW_PWR_CMD_WRITE, BIT(0), 0}, |
2482 | {0xFFFF, |
2483 | RTW_PWR_CUT_ALL_MSK, |
2484 | RTW_PWR_INTF_ALL_MSK, |
2485 | 0, |
2486 | RTW_PWR_CMD_END, 0, 0}, |
2487 | }; |
2488 | |
2489 | static const struct rtw_pwr_seq_cmd trans_cardemu_to_carddis_8723d[] = { |
2490 | {0x0007, |
2491 | RTW_PWR_CUT_ALL_MSK, |
2492 | RTW_PWR_INTF_SDIO_MSK, |
2493 | RTW_PWR_ADDR_MAC, |
2494 | RTW_PWR_CMD_WRITE, 0xFF, 0x20}, |
2495 | {0x0005, |
2496 | RTW_PWR_CUT_ALL_MSK, |
2497 | RTW_PWR_INTF_USB_MSK | RTW_PWR_INTF_SDIO_MSK, |
2498 | RTW_PWR_ADDR_MAC, |
2499 | RTW_PWR_CMD_WRITE, BIT(3) | BIT(4), BIT(3)}, |
2500 | {0x0005, |
2501 | RTW_PWR_CUT_ALL_MSK, |
2502 | RTW_PWR_INTF_PCI_MSK, |
2503 | RTW_PWR_ADDR_MAC, |
2504 | RTW_PWR_CMD_WRITE, BIT(2), BIT(2)}, |
2505 | {0x0005, |
2506 | RTW_PWR_CUT_ALL_MSK, |
2507 | RTW_PWR_INTF_PCI_MSK, |
2508 | RTW_PWR_ADDR_MAC, |
2509 | RTW_PWR_CMD_WRITE, BIT(3) | BIT(4), BIT(3) | BIT(4)}, |
2510 | {0x004A, |
2511 | RTW_PWR_CUT_ALL_MSK, |
2512 | RTW_PWR_INTF_USB_MSK, |
2513 | RTW_PWR_ADDR_MAC, |
2514 | RTW_PWR_CMD_WRITE, BIT(0), 1}, |
2515 | {0x0023, |
2516 | RTW_PWR_CUT_ALL_MSK, |
2517 | RTW_PWR_INTF_SDIO_MSK, |
2518 | RTW_PWR_ADDR_MAC, |
2519 | RTW_PWR_CMD_WRITE, BIT(4), BIT(4)}, |
2520 | {0x0086, |
2521 | RTW_PWR_CUT_ALL_MSK, |
2522 | RTW_PWR_INTF_SDIO_MSK, |
2523 | RTW_PWR_ADDR_SDIO, |
2524 | RTW_PWR_CMD_WRITE, BIT(0), BIT(0)}, |
2525 | {0x0086, |
2526 | RTW_PWR_CUT_ALL_MSK, |
2527 | RTW_PWR_INTF_SDIO_MSK, |
2528 | RTW_PWR_ADDR_SDIO, |
2529 | RTW_PWR_CMD_POLLING, BIT(1), 0}, |
2530 | {0xFFFF, |
2531 | RTW_PWR_CUT_ALL_MSK, |
2532 | RTW_PWR_INTF_ALL_MSK, |
2533 | 0, |
2534 | RTW_PWR_CMD_END, 0, 0}, |
2535 | }; |
2536 | |
2537 | static const struct rtw_pwr_seq_cmd trans_act_to_post_carddis_8723d[] = { |
2538 | {0x001D, |
2539 | RTW_PWR_CUT_ALL_MSK, |
2540 | RTW_PWR_INTF_ALL_MSK, |
2541 | RTW_PWR_ADDR_MAC, |
2542 | RTW_PWR_CMD_WRITE, BIT(0), 0}, |
2543 | {0x001D, |
2544 | RTW_PWR_CUT_ALL_MSK, |
2545 | RTW_PWR_INTF_ALL_MSK, |
2546 | RTW_PWR_ADDR_MAC, |
2547 | RTW_PWR_CMD_WRITE, BIT(0), BIT(0)}, |
2548 | {0x001C, |
2549 | RTW_PWR_CUT_ALL_MSK, |
2550 | RTW_PWR_INTF_ALL_MSK, |
2551 | RTW_PWR_ADDR_MAC, |
2552 | RTW_PWR_CMD_WRITE, 0xFF, 0x0E}, |
2553 | {0xFFFF, |
2554 | RTW_PWR_CUT_ALL_MSK, |
2555 | RTW_PWR_INTF_ALL_MSK, |
2556 | 0, |
2557 | RTW_PWR_CMD_END, 0, 0}, |
2558 | }; |
2559 | |
2560 | static const struct rtw_pwr_seq_cmd *card_disable_flow_8723d[] = { |
2561 | trans_act_to_lps_8723d, |
2562 | trans_act_to_pre_carddis_8723d, |
2563 | trans_act_to_cardemu_8723d, |
2564 | trans_cardemu_to_carddis_8723d, |
2565 | trans_act_to_post_carddis_8723d, |
2566 | NULL |
2567 | }; |
2568 | |
2569 | static const struct rtw_page_table page_table_8723d[] = { |
2570 | {12, 2, 2, 0, 1}, |
2571 | {12, 2, 2, 0, 1}, |
2572 | {12, 2, 2, 0, 1}, |
2573 | {12, 2, 2, 0, 1}, |
2574 | {12, 2, 2, 0, 1}, |
2575 | }; |
2576 | |
2577 | static const struct rtw_rqpn rqpn_table_8723d[] = { |
2578 | {RTW_DMA_MAPPING_NORMAL, RTW_DMA_MAPPING_NORMAL, |
2579 | RTW_DMA_MAPPING_LOW, RTW_DMA_MAPPING_LOW, |
2580 | RTW_DMA_MAPPING_EXTRA, RTW_DMA_MAPPING_HIGH}, |
2581 | {RTW_DMA_MAPPING_NORMAL, RTW_DMA_MAPPING_NORMAL, |
2582 | RTW_DMA_MAPPING_LOW, RTW_DMA_MAPPING_LOW, |
2583 | RTW_DMA_MAPPING_EXTRA, RTW_DMA_MAPPING_HIGH}, |
2584 | {RTW_DMA_MAPPING_NORMAL, RTW_DMA_MAPPING_NORMAL, |
2585 | RTW_DMA_MAPPING_NORMAL, RTW_DMA_MAPPING_HIGH, |
2586 | RTW_DMA_MAPPING_HIGH, RTW_DMA_MAPPING_HIGH}, |
2587 | {RTW_DMA_MAPPING_NORMAL, RTW_DMA_MAPPING_NORMAL, |
2588 | RTW_DMA_MAPPING_LOW, RTW_DMA_MAPPING_LOW, |
2589 | RTW_DMA_MAPPING_HIGH, RTW_DMA_MAPPING_HIGH}, |
2590 | {RTW_DMA_MAPPING_NORMAL, RTW_DMA_MAPPING_NORMAL, |
2591 | RTW_DMA_MAPPING_LOW, RTW_DMA_MAPPING_LOW, |
2592 | RTW_DMA_MAPPING_EXTRA, RTW_DMA_MAPPING_HIGH}, |
2593 | }; |
2594 | |
2595 | static const struct rtw_prioq_addrs prioq_addrs_8723d = { |
2596 | .prio[RTW_DMA_MAPPING_EXTRA] = { |
2597 | .rsvd = REG_RQPN_NPQ + 2, .avail = REG_RQPN_NPQ + 3, |
2598 | }, |
2599 | .prio[RTW_DMA_MAPPING_LOW] = { |
2600 | .rsvd = REG_RQPN + 1, .avail = REG_FIFOPAGE_CTRL_2 + 1, |
2601 | }, |
2602 | .prio[RTW_DMA_MAPPING_NORMAL] = { |
2603 | .rsvd = REG_RQPN_NPQ, .avail = REG_RQPN_NPQ + 1, |
2604 | }, |
2605 | .prio[RTW_DMA_MAPPING_HIGH] = { |
2606 | .rsvd = REG_RQPN, .avail = REG_FIFOPAGE_CTRL_2, |
2607 | }, |
2608 | .wsize = false, |
2609 | }; |
2610 | |
2611 | static const struct rtw_intf_phy_para pcie_gen1_param_8723d[] = { |
2612 | {0x0008, 0x4a22, |
2613 | RTW_IP_SEL_PHY, |
2614 | RTW_INTF_PHY_CUT_ALL, |
2615 | RTW_INTF_PHY_PLATFORM_ALL}, |
2616 | {0x0009, 0x1000, |
2617 | RTW_IP_SEL_PHY, |
2618 | ~(RTW_INTF_PHY_CUT_A | RTW_INTF_PHY_CUT_B), |
2619 | RTW_INTF_PHY_PLATFORM_ALL}, |
2620 | {0xFFFF, 0x0000, |
2621 | RTW_IP_SEL_PHY, |
2622 | RTW_INTF_PHY_CUT_ALL, |
2623 | RTW_INTF_PHY_PLATFORM_ALL}, |
2624 | }; |
2625 | |
2626 | static const struct rtw_intf_phy_para_table phy_para_table_8723d = { |
2627 | .gen1_para = pcie_gen1_param_8723d, |
2628 | .n_gen1_para = ARRAY_SIZE(pcie_gen1_param_8723d), |
2629 | }; |
2630 | |
2631 | static const struct rtw_hw_reg rtw8723d_dig[] = { |
2632 | [0] = { .addr = 0xc50, .mask = 0x7f }, |
2633 | [1] = { .addr = 0xc50, .mask = 0x7f }, |
2634 | }; |
2635 | |
2636 | static const struct rtw_hw_reg rtw8723d_dig_cck[] = { |
2637 | [0] = { .addr = 0xa0c, .mask = 0x3f00 }, |
2638 | }; |
2639 | |
2640 | static const struct rtw_rf_sipi_addr rtw8723d_rf_sipi_addr[] = { |
2641 | [RF_PATH_A] = { .hssi_1 = 0x820, .lssi_read = 0x8a0, |
2642 | .hssi_2 = 0x824, .lssi_read_pi = 0x8b8}, |
2643 | [RF_PATH_B] = { .hssi_1 = 0x828, .lssi_read = 0x8a4, |
2644 | .hssi_2 = 0x82c, .lssi_read_pi = 0x8bc}, |
2645 | }; |
2646 | |
2647 | static const struct rtw_ltecoex_addr rtw8723d_ltecoex_addr = { |
2648 | .ctrl = REG_LTECOEX_CTRL, |
2649 | .wdata = REG_LTECOEX_WRITE_DATA, |
2650 | .rdata = REG_LTECOEX_READ_DATA, |
2651 | }; |
2652 | |
2653 | static const struct rtw_rfe_def rtw8723d_rfe_defs[] = { |
2654 | [0] = { .phy_pg_tbl = &rtw8723d_bb_pg_tbl, |
2655 | .txpwr_lmt_tbl = &rtw8723d_txpwr_lmt_tbl,}, |
2656 | }; |
2657 | |
2658 | static const u8 rtw8723d_pwrtrk_2gb_n[] = { |
2659 | 0, 0, 1, 1, 1, 2, 2, 3, 4, 4, 4, 4, 5, 5, 5, |
2660 | 6, 6, 7, 7, 8, 8, 8, 9, 9, 9, 10, 10, 10, 10, 10 |
2661 | }; |
2662 | |
2663 | static const u8 rtw8723d_pwrtrk_2gb_p[] = { |
2664 | 0, 0, 1, 1, 2, 2, 2, 3, 3, 4, 4, 5, 5, 6, 7, |
2665 | 7, 8, 8, 8, 9, 9, 10, 10, 10, 10, 10, 10, 10, 10, 10 |
2666 | }; |
2667 | |
2668 | static const u8 rtw8723d_pwrtrk_2ga_n[] = { |
2669 | 0, 0, 1, 1, 1, 2, 2, 3, 4, 4, 4, 4, 5, 5, 5, |
2670 | 6, 6, 7, 7, 8, 8, 8, 9, 9, 9, 10, 10, 10, 10, 10 |
2671 | }; |
2672 | |
2673 | static const u8 rtw8723d_pwrtrk_2ga_p[] = { |
2674 | 0, 0, 1, 1, 2, 2, 2, 3, 3, 4, 4, 5, 5, 6, 7, |
2675 | 7, 8, 8, 8, 9, 9, 10, 10, 10, 10, 10, 10, 10, 10, 10 |
2676 | }; |
2677 | |
2678 | static const u8 rtw8723d_pwrtrk_2g_cck_b_n[] = { |
2679 | 0, 1, 1, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, |
2680 | 6, 7, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 11, 11, 11 |
2681 | }; |
2682 | |
2683 | static const u8 rtw8723d_pwrtrk_2g_cck_b_p[] = { |
2684 | 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, |
2685 | 7, 8, 9, 9, 10, 10, 11, 11, 11, 11, 11, 11, 11, 11, 11 |
2686 | }; |
2687 | |
2688 | static const u8 rtw8723d_pwrtrk_2g_cck_a_n[] = { |
2689 | 0, 1, 1, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, |
2690 | 6, 7, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 11, 11, 11 |
2691 | }; |
2692 | |
2693 | static const u8 rtw8723d_pwrtrk_2g_cck_a_p[] = { |
2694 | 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, |
2695 | 7, 8, 9, 9, 10, 10, 11, 11, 11, 11, 11, 11, 11, 11, 11 |
2696 | }; |
2697 | |
2698 | static const s8 rtw8723d_pwrtrk_xtal_n[] = { |
2699 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
2700 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 |
2701 | }; |
2702 | |
2703 | static const s8 rtw8723d_pwrtrk_xtal_p[] = { |
2704 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
2705 | 0, -10, -12, -14, -16, -16, -16, -16, -16, -16, -16, -16, -16, -16, -16 |
2706 | }; |
2707 | |
2708 | static const struct rtw_pwr_track_tbl rtw8723d_rtw_pwr_track_tbl = { |
2709 | .pwrtrk_2gb_n = rtw8723d_pwrtrk_2gb_n, |
2710 | .pwrtrk_2gb_p = rtw8723d_pwrtrk_2gb_p, |
2711 | .pwrtrk_2ga_n = rtw8723d_pwrtrk_2ga_n, |
2712 | .pwrtrk_2ga_p = rtw8723d_pwrtrk_2ga_p, |
2713 | .pwrtrk_2g_cckb_n = rtw8723d_pwrtrk_2g_cck_b_n, |
2714 | .pwrtrk_2g_cckb_p = rtw8723d_pwrtrk_2g_cck_b_p, |
2715 | .pwrtrk_2g_ccka_n = rtw8723d_pwrtrk_2g_cck_a_n, |
2716 | .pwrtrk_2g_ccka_p = rtw8723d_pwrtrk_2g_cck_a_p, |
2717 | .pwrtrk_xtal_p = rtw8723d_pwrtrk_xtal_p, |
2718 | .pwrtrk_xtal_n = rtw8723d_pwrtrk_xtal_n, |
2719 | }; |
2720 | |
2721 | static const struct rtw_reg_domain coex_info_hw_regs_8723d[] = { |
2722 | {0x948, MASKDWORD, RTW_REG_DOMAIN_MAC32}, |
2723 | {0x67, BIT(7), RTW_REG_DOMAIN_MAC8}, |
2724 | {0, 0, RTW_REG_DOMAIN_NL}, |
2725 | {0x964, BIT(1), RTW_REG_DOMAIN_MAC8}, |
2726 | {0x864, BIT(0), RTW_REG_DOMAIN_MAC8}, |
2727 | {0xab7, BIT(5), RTW_REG_DOMAIN_MAC8}, |
2728 | {0xa01, BIT(7), RTW_REG_DOMAIN_MAC8}, |
2729 | {0, 0, RTW_REG_DOMAIN_NL}, |
2730 | {0x430, MASKDWORD, RTW_REG_DOMAIN_MAC32}, |
2731 | {0x434, MASKDWORD, RTW_REG_DOMAIN_MAC32}, |
2732 | {0x42a, MASKLWORD, RTW_REG_DOMAIN_MAC16}, |
2733 | {0x426, MASKBYTE0, RTW_REG_DOMAIN_MAC8}, |
2734 | {0x45e, BIT(3), RTW_REG_DOMAIN_MAC8}, |
2735 | {0, 0, RTW_REG_DOMAIN_NL}, |
2736 | {0x4c6, BIT(4), RTW_REG_DOMAIN_MAC8}, |
2737 | {0x40, BIT(5), RTW_REG_DOMAIN_MAC8}, |
2738 | {0x550, MASKDWORD, RTW_REG_DOMAIN_MAC32}, |
2739 | {0x522, MASKBYTE0, RTW_REG_DOMAIN_MAC8}, |
2740 | {0x953, BIT(1), RTW_REG_DOMAIN_MAC8}, |
2741 | }; |
2742 | |
2743 | const struct rtw_chip_info rtw8723d_hw_spec = { |
2744 | .ops = &rtw8723d_ops, |
2745 | .id = RTW_CHIP_TYPE_8723D, |
2746 | .fw_name = "rtw88/rtw8723d_fw.bin" , |
2747 | .wlan_cpu = RTW_WCPU_11N, |
2748 | .tx_pkt_desc_sz = 40, |
2749 | .tx_buf_desc_sz = 16, |
2750 | .rx_pkt_desc_sz = 24, |
2751 | .rx_buf_desc_sz = 8, |
2752 | .phy_efuse_size = 512, |
2753 | .log_efuse_size = 512, |
2754 | .ptct_efuse_size = 96 + 1, |
2755 | .txff_size = 32768, |
2756 | .rxff_size = 16384, |
2757 | .rsvd_drv_pg_num = 8, |
2758 | .txgi_factor = 1, |
2759 | .is_pwr_by_rate_dec = true, |
2760 | .max_power_index = 0x3f, |
2761 | .csi_buf_pg_num = 0, |
2762 | .band = RTW_BAND_2G, |
2763 | .page_size = TX_PAGE_SIZE, |
2764 | .dig_min = 0x20, |
2765 | .ht_supported = true, |
2766 | .vht_supported = false, |
2767 | .lps_deep_mode_supported = 0, |
2768 | .sys_func_en = 0xFD, |
2769 | .pwr_on_seq = card_enable_flow_8723d, |
2770 | .pwr_off_seq = card_disable_flow_8723d, |
2771 | .page_table = page_table_8723d, |
2772 | .rqpn_table = rqpn_table_8723d, |
2773 | .prioq_addrs = &prioq_addrs_8723d, |
2774 | .intf_table = &phy_para_table_8723d, |
2775 | .dig = rtw8723d_dig, |
2776 | .dig_cck = rtw8723d_dig_cck, |
2777 | .rf_sipi_addr = {0x840, 0x844}, |
2778 | .rf_sipi_read_addr = rtw8723d_rf_sipi_addr, |
2779 | .fix_rf_phy_num = 2, |
2780 | .ltecoex_addr = &rtw8723d_ltecoex_addr, |
2781 | .mac_tbl = &rtw8723d_mac_tbl, |
2782 | .agc_tbl = &rtw8723d_agc_tbl, |
2783 | .bb_tbl = &rtw8723d_bb_tbl, |
2784 | .rf_tbl = {&rtw8723d_rf_a_tbl}, |
2785 | .rfe_defs = rtw8723d_rfe_defs, |
2786 | .rfe_defs_size = ARRAY_SIZE(rtw8723d_rfe_defs), |
2787 | .rx_ldpc = false, |
2788 | .pwr_track_tbl = &rtw8723d_rtw_pwr_track_tbl, |
2789 | .iqk_threshold = 8, |
2790 | .ampdu_density = IEEE80211_HT_MPDU_DENSITY_16, |
2791 | .max_scan_ie_len = IEEE80211_MAX_DATA_LEN, |
2792 | |
2793 | .coex_para_ver = 0x2007022f, |
2794 | .bt_desired_ver = 0x2f, |
2795 | .scbd_support = true, |
2796 | .new_scbd10_def = true, |
2797 | .ble_hid_profile_support = false, |
2798 | .wl_mimo_ps_support = false, |
2799 | .pstdma_type = COEX_PSTDMA_FORCE_LPSOFF, |
2800 | .bt_rssi_type = COEX_BTRSSI_RATIO, |
2801 | .ant_isolation = 15, |
2802 | .rssi_tolerance = 2, |
2803 | .wl_rssi_step = wl_rssi_step_8723d, |
2804 | .bt_rssi_step = bt_rssi_step_8723d, |
2805 | .table_sant_num = ARRAY_SIZE(table_sant_8723d), |
2806 | .table_sant = table_sant_8723d, |
2807 | .table_nsant_num = ARRAY_SIZE(table_nsant_8723d), |
2808 | .table_nsant = table_nsant_8723d, |
2809 | .tdma_sant_num = ARRAY_SIZE(tdma_sant_8723d), |
2810 | .tdma_sant = tdma_sant_8723d, |
2811 | .tdma_nsant_num = ARRAY_SIZE(tdma_nsant_8723d), |
2812 | .tdma_nsant = tdma_nsant_8723d, |
2813 | .wl_rf_para_num = ARRAY_SIZE(rf_para_tx_8723d), |
2814 | .wl_rf_para_tx = rf_para_tx_8723d, |
2815 | .wl_rf_para_rx = rf_para_rx_8723d, |
2816 | .bt_afh_span_bw20 = 0x20, |
2817 | .bt_afh_span_bw40 = 0x30, |
2818 | .afh_5g_num = ARRAY_SIZE(afh_5g_8723d), |
2819 | .afh_5g = afh_5g_8723d, |
2820 | .btg_reg = &btg_reg_8723d, |
2821 | |
2822 | .coex_info_hw_regs_num = ARRAY_SIZE(coex_info_hw_regs_8723d), |
2823 | .coex_info_hw_regs = coex_info_hw_regs_8723d, |
2824 | }; |
2825 | EXPORT_SYMBOL(rtw8723d_hw_spec); |
2826 | |
2827 | MODULE_FIRMWARE("rtw88/rtw8723d_fw.bin" ); |
2828 | |
2829 | MODULE_AUTHOR("Realtek Corporation" ); |
2830 | MODULE_DESCRIPTION("Realtek 802.11n wireless 8723d driver" ); |
2831 | MODULE_LICENSE("Dual BSD/GPL" ); |
2832 | |