1 /******************************************************************************
2 *
3 * Copyright(c) 2007 - 2017 Realtek Corporation.
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of version 2 of the GNU General Public License as
7 * published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12 * more details.
13 *
14 * The full GNU General Public License is included in this distribution in the
15 * file called LICENSE.
16 *
17 * Contact Information:
18 * wlanfae <wlanfae@realtek.com>
19 * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
20 * Hsinchu 300, Taiwan.
21 *
22 * Larry Finger <Larry.Finger@lwfinger.net>
23 *
24 *****************************************************************************/
25 #include "mp_precomp.h"
26 #include "../phydm_precomp.h"
27
28 #if (RTL8822C_SUPPORT)
29 #if (PHYDM_FW_API_ENABLE_8822C)
30 /* ======================================================================== */
31 /* These following functions can be used for PHY DM only*/
32 #ifdef CONFIG_TXAGC_DEBUG_8822C
33 __odm_func__
phydm_set_pw_by_rate_8822c(struct dm_struct * dm,s8 * pw_idx,u8 rate_idx)34 boolean phydm_set_pw_by_rate_8822c(struct dm_struct *dm, s8 *pw_idx,
35 u8 rate_idx)
36 {
37 u32 pw_all = 0;
38 u8 j = 0;
39
40 if (rate_idx % 4 != 0) {
41 pr_debug("[Warning] %s\n", __func__);
42 return false;
43 }
44
45 PHYDM_DBG(dm, ODM_PHY_CONFIG, "pow = {%d, %d, %d, %d}\n",
46 *pw_idx, *(pw_idx - 1), *(pw_idx - 2), *(pw_idx - 3));
47
48 /*bbrstb TX AGC report - default disable */
49 /*Enable for writing the TX AGC table when bb_reset=0 */
50 if (odm_get_bb_reg(dm, R_0x1c90, BIT(15)))
51 odm_set_bb_reg(dm, R_0x1c90, BIT(15), 0x0);
52
53 /*According the rate to write in the ofdm or the cck */
54 /*driver need to construct a 4-byte power index */
55 odm_set_bb_reg(dm, R_0x3a00 + rate_idx, MASKDWORD, pw_all);
56
57 PHYDM_DBG(dm, ODM_PHY_CONFIG, "rate_idx=0x%x (REG0x%x) = 0x%x\n",
58 rate_idx, R_0x3a00 + rate_idx, pw_all);
59
60 for (j = 0; j < 4; j++)
61 config_phydm_read_txagc_diff_8822c(dm, rate_idx + j);
62
63 return true;
64 }
65
66 __odm_func__
phydm_txagc_tab_buff_init_8822c(struct dm_struct * dm)67 void phydm_txagc_tab_buff_init_8822c(struct dm_struct *dm)
68 {
69 u8 i;
70
71 for (i = 0; i < NUM_RATE_AC_2SS; i++) {
72 dm->txagc_buff[RF_PATH_A][i] = i >> 2;
73 dm->txagc_buff[RF_PATH_B][i] = i >> 2;
74 }
75 }
76
77 __odm_func__
phydm_txagc_tab_buff_show_8822c(struct dm_struct * dm)78 void phydm_txagc_tab_buff_show_8822c(struct dm_struct *dm)
79 {
80 u8 i;
81
82 pr_debug("path A\n");
83 for (i = 0; i < NUM_RATE_AC_2SS; i++)
84 pr_debug("[A][rate:%d] = %d\n", i,
85 dm->txagc_buff[RF_PATH_A][i]);
86 pr_debug("path B\n");
87 for (i = 0; i < NUM_RATE_AC_2SS; i++)
88 pr_debug("[B][rate:%d] = %d\n", i,
89 dm->txagc_buff[RF_PATH_B][i]);
90 }
91 #endif
92
93 __odm_func__
phydm_rstb_3wire_8822c(struct dm_struct * dm,boolean enable)94 void phydm_rstb_3wire_8822c(struct dm_struct *dm, boolean enable)
95 {
96 if (enable) {
97 odm_set_bb_reg(dm, R_0x1c90, BIT(8), 0x1);
98 /*force update anapar*/
99 odm_set_bb_reg(dm, R_0x1830, BIT(29), 0x1);
100 odm_set_bb_reg(dm, R_0x4130, BIT(29), 0x1);
101 } else {
102 odm_set_bb_reg(dm, R_0x1c90, BIT(8), 0x0);
103 }
104 }
105
106 __odm_func__
phydm_sdm_reset_8822c(struct dm_struct * dm)107 void phydm_sdm_reset_8822c(struct dm_struct *dm)
108 {
109 /*reset HSSI*/
110 phydm_rstb_3wire_8822c(dm, false);
111 /*write RF-0x18*/
112 odm_set_rf_reg(dm, RF_PATH_A, RF_0xbc, BIT(19), 0x0);
113 odm_set_rf_reg(dm, RF_PATH_A, RF_0xbc, BIT(19), 0x1);
114 odm_set_rf_reg(dm, RF_PATH_A, RF_0xbc, BIT(19), 0x0);
115 /*reset HSSI*/
116 phydm_rstb_3wire_8822c(dm, true);
117 }
118
119 __odm_func__
phydm_bb_reset_8822c(struct dm_struct * dm)120 void phydm_bb_reset_8822c(struct dm_struct *dm)
121 {
122 if (*dm->mp_mode)
123 return;
124
125 odm_set_mac_reg(dm, R_0x0, BIT(16), 1);
126 odm_set_mac_reg(dm, R_0x0, BIT(16), 0);
127 odm_set_mac_reg(dm, R_0x0, BIT(16), 1);
128 }
129
130 __odm_func__
phydm_bb_reset_no_3wires_8822c(struct dm_struct * dm)131 void phydm_bb_reset_no_3wires_8822c(struct dm_struct *dm)
132 {
133 /* Disable PI hardware */
134 odm_set_bb_reg(dm, R_0x1c90, BIT(8), 0x0);
135
136 odm_set_mac_reg(dm, R_0x0, BIT(16), 1);
137 odm_set_mac_reg(dm, R_0x0, BIT(16), 0);
138 odm_set_mac_reg(dm, R_0x0, BIT(16), 1);
139
140 /* Enable PI hardware */
141 odm_set_bb_reg(dm, R_0x1c90, BIT(8), 0x1);
142 }
143
144 __odm_func__
phydm_chk_pkg_set_valid_8822c(struct dm_struct * dm,u8 ver_bb,u8 ver_rf)145 boolean phydm_chk_pkg_set_valid_8822c(struct dm_struct *dm,
146 u8 ver_bb, u8 ver_rf)
147 {
148 boolean valid = true;
149
150 if (ver_bb >= 47 && ver_rf >= 28)
151 valid = true;
152 else if (ver_bb == 46 && ver_rf == 27)
153 valid = true;
154 else if (ver_bb >= 41 && ver_bb < 46 && ver_rf >= 23 && ver_rf < 27)
155 valid = true;
156 else if (ver_bb < 41 && ver_rf < 23)
157 valid = true;
158 else
159 valid = false;
160
161 if (!valid) {
162 odm_set_bb_reg(dm, R_0x1c3c, (BIT(0) | BIT(1)), 0x0);
163 pr_debug("[Warning][%s] Pkg_ver{bb, rf}={%d, %d} disable all BB block\n",
164 __func__, ver_bb, ver_rf);
165 }
166
167 return valid;
168 }
169
170 __odm_func__
phydm_igi_toggle_8822c(struct dm_struct * dm)171 void phydm_igi_toggle_8822c(struct dm_struct *dm)
172 {
173 /*
174 *Toggle IGI to force BB HW send 3-wire-cmd and will let RF HW enter RX mode.
175 *Because BB HW does not send 3-wire command automacically when BB setting
176 *is changed including the configuration of path/channel/BW
177 */
178 u32 reg_1d70 = 0x0;
179
180 reg_1d70 = odm_get_bb_reg(dm, R_0x1d70, MASKDWORD);
181 odm_set_bb_reg(dm, R_0x1d70, MASKDWORD, reg_1d70 - 0x202);
182 odm_set_bb_reg(dm, R_0x1d70, MASKDWORD, reg_1d70);
183 }
184
185 __odm_func__
phydm_check_bit_mask_8822c(u32 bit_mask,u32 data_original,u32 data)186 u32 phydm_check_bit_mask_8822c(u32 bit_mask, u32 data_original, u32 data)
187 {
188 u8 bit_shift = 0;
189
190 if (bit_mask != 0xfffff) {
191 for (bit_shift = 0; bit_shift <= 19; bit_shift++) {
192 if ((bit_mask >> bit_shift) & 0x1)
193 break;
194 }
195 return (data_original & (~bit_mask)) | (data << bit_shift);
196 }
197
198 return data;
199 }
200
201 __odm_func__
config_phydm_read_rf_reg_8822c(struct dm_struct * dm,enum rf_path path,u32 reg_addr,u32 bit_mask)202 u32 config_phydm_read_rf_reg_8822c(struct dm_struct *dm, enum rf_path path,
203 u32 reg_addr, u32 bit_mask)
204 {
205 u32 readback_value = 0, direct_addr = 0;
206 u32 offset_read_rf[2] = {R_0x3c00, R_0x4c00};
207
208 PHYDM_DBG(dm, ODM_PHY_CONFIG, "%s ======>\n", __func__);
209
210 /* @Error handling.*/
211 if (path > RF_PATH_B) {
212 PHYDM_DBG(dm, ODM_PHY_CONFIG, "Unsupported path (%d)\n", path);
213 return INVALID_RF_DATA;
214 }
215
216 /* @Calculate offset */
217 reg_addr &= 0xff;
218 direct_addr = offset_read_rf[path] + (reg_addr << 2);
219
220 /* @RF register only has 20bits */
221 bit_mask &= RFREG_MASK;
222
223 /* @Read RF register directly */
224 readback_value = odm_get_bb_reg(dm, direct_addr, bit_mask);
225 PHYDM_DBG(dm, ODM_PHY_CONFIG,
226 "RF-%d 0x%x = 0x%x, bit mask = 0x%x\n", path, reg_addr,
227 readback_value, bit_mask);
228 return readback_value;
229 }
230
231 __odm_func__
232 boolean
config_phydm_direct_write_rf_reg_8822c(struct dm_struct * dm,enum rf_path path,u32 reg_addr,u32 bit_mask,u32 data)233 config_phydm_direct_write_rf_reg_8822c(struct dm_struct *dm, enum rf_path path,
234 u32 reg_addr, u32 bit_mask, u32 data)
235 {
236 u32 direct_addr = 0;
237 u32 offset_write_rf[2] = {R_0x3c00, R_0x4c00};
238
239 PHYDM_DBG(dm, ODM_PHY_CONFIG, "%s ======>\n", __func__);
240
241 /* @Calculate offset */
242 reg_addr &= 0xff;
243 direct_addr = offset_write_rf[path] + (reg_addr << 2);
244
245 /* @RF register only has 20bits */
246 bit_mask &= RFREG_MASK;
247
248
249 /* @write RF register directly*/
250 odm_set_bb_reg(dm, direct_addr, bit_mask, data);
251
252 ODM_delay_us(1);
253
254 PHYDM_DBG(dm, ODM_PHY_CONFIG,
255 "RF-%d 0x%x = 0x%x , bit mask = 0x%x\n",
256 path, reg_addr, data, bit_mask);
257
258 return true;
259 }
260
261 __odm_func__
262 boolean
config_phydm_write_rf_reg_8822c(struct dm_struct * dm,enum rf_path path,u32 reg_addr,u32 bit_mask,u32 data)263 config_phydm_write_rf_reg_8822c(struct dm_struct *dm, enum rf_path path,
264 u32 reg_addr, u32 bit_mask, u32 data)
265 {
266 u32 data_and_addr = 0, data_original = 0;
267 u32 offset_write_rf[2] = {R_0x1808, R_0x4108};
268 boolean result = false;
269
270 PHYDM_DBG(dm, ODM_PHY_CONFIG, "%s ======>\n", __func__);
271
272 /* @Error handling.*/
273 if (path > RF_PATH_B) {
274 PHYDM_DBG(dm, ODM_PHY_CONFIG, "Invalid path=%d\n", path);
275 return false;
276 }
277
278 if (!(reg_addr == RF_0x0)) {
279 result = config_phydm_direct_write_rf_reg_8822c(dm, path,
280 reg_addr,
281 bit_mask, data);
282 return result;
283 }
284
285 /* @Read RF register content first */
286 reg_addr &= 0xff;
287 bit_mask &= RFREG_MASK;
288
289 if (bit_mask != RFREG_MASK) {
290 data_original = config_phydm_read_rf_reg_8822c(dm, path,
291 reg_addr,
292 RFREG_MASK);
293
294 /* @Error handling. RF is disabled */
295 if (!(data_original != INVALID_RF_DATA)) {
296 PHYDM_DBG(dm, ODM_PHY_CONFIG,
297 "Write fail, RF is disable\n");
298 return false;
299 }
300
301 /* @check bit mask */
302 data = phydm_check_bit_mask_8822c(bit_mask, data_original,
303 data);
304 }
305
306 /* @Put write addr in [27:20] and write data in [19:00] */
307 data_and_addr = ((reg_addr << 20) | (data & 0x000fffff)) & 0x0fffffff;
308
309 /* @Write operation */
310 odm_set_bb_reg(dm, offset_write_rf[path], MASKDWORD, data_and_addr);
311
312 PHYDM_DBG(dm, ODM_PHY_CONFIG,
313 "RF-%d 0x%x = 0x%x (original: 0x%x), bit mask = 0x%x\n",
314 path, reg_addr, data, data_original, bit_mask);
315 #if (defined(CONFIG_RUN_IN_DRV))
316 if (dm->support_interface == ODM_ITRF_PCIE)
317 ODM_delay_us(13);
318 #elif (defined(CONFIG_RUN_IN_FW))
319 ODM_delay_us(13);
320 #endif
321
322 return true;
323 }
324
325 __odm_func__
326 boolean
phydm_write_txagc_1byte_8822c(struct dm_struct * dm,u32 pw_idx,u8 hw_rate)327 phydm_write_txagc_1byte_8822c(struct dm_struct *dm, u32 pw_idx, u8 hw_rate)
328 {
329 #if (PHYDM_FW_API_FUNC_ENABLE_8822C)
330 u32 offset_txagc = R_0x3a00;
331 u8 rate_idx = (hw_rate & 0xfc), i = 0;
332 u8 rate_offset = (hw_rate & 0x3);
333 u8 ret = 0;
334 u32 txagc_idx = 0x0;
335
336 PHYDM_DBG(dm, ODM_PHY_CONFIG, "%s ======>\n", __func__);
337 /*For debug command only!!!! */
338
339 /*bbrstb TX AGC report - default disable */
340 /*Enable for writing the TX AGC table when bb_reset=0 */
341 if (odm_get_bb_reg(dm, R_0x1c90, BIT(15)))
342 odm_set_bb_reg(dm, R_0x1c90, BIT(15), 0x0);
343
344 /*Error handling */
345 if (hw_rate > 0x53) {
346 PHYDM_DBG(dm, ODM_PHY_CONFIG, "Unsupported rate\n");
347 return false;
348 }
349
350 /*For HW limitation, We can't write TXAGC once a byte. */
351 for (i = 0; i < 4; i++) {
352 if (i != rate_offset) {
353 ret = config_phydm_read_txagc_diff_8822c(dm,
354 rate_idx + i);
355 txagc_idx |= ret << (i << 3);
356 } else {
357 txagc_idx |= (pw_idx & 0x7f) << (i << 3);
358 }
359 }
360 odm_set_bb_reg(dm, (offset_txagc + rate_idx), MASKDWORD, txagc_idx);
361
362 PHYDM_DBG(dm, ODM_PHY_CONFIG, "rate_idx 0x%x (0x%x) = 0x%x\n",
363 hw_rate, (offset_txagc + hw_rate), txagc_idx);
364 return true;
365 #else
366 return false;
367 #endif
368 }
369
370 __odm_func__
371 boolean
config_phydm_write_txagc_ref_8822c(struct dm_struct * dm,u8 power_index,enum rf_path path,enum PDM_RATE_TYPE rate_type)372 config_phydm_write_txagc_ref_8822c(struct dm_struct *dm, u8 power_index,
373 enum rf_path path,
374 enum PDM_RATE_TYPE rate_type)
375 {
376 /*2-path power reference */
377 u32 txagc_ofdm_ref[2] = {R_0x18e8, R_0x41e8};
378 u32 txagc_cck_ref[2] = {R_0x18a0, R_0x41a0};
379
380 PHYDM_DBG(dm, ODM_PHY_CONFIG, "%s ======>\n", __func__);
381
382 /*Input need to be HW rate index, not driver rate index!!!! */
383 if (dm->is_disable_phy_api) {
384 PHYDM_DBG(dm, ODM_PHY_CONFIG, "Disable PHY API for debug\n");
385 return true;
386 }
387
388 /*Error handling */
389 if (path > RF_PATH_B) {
390 PHYDM_DBG(dm, ODM_PHY_CONFIG, "Unsupported path (%d)\n",
391 path);
392 return false;
393 }
394
395 /*bbrstb TX AGC report - default disable */
396 /*Enable for writing the TX AGC table when bb_reset=0 */
397 if (odm_get_bb_reg(dm, R_0x1c90, BIT(15)))
398 odm_set_bb_reg(dm, R_0x1c90, BIT(15), 0x0);
399
400 /*According the rate to write in the ofdm or the cck */
401 /*CCK reference setting */
402 if (rate_type == PDM_CCK) {
403 odm_set_bb_reg(dm, txagc_cck_ref[path], 0x007f0000,
404 power_index);
405 PHYDM_DBG(dm, ODM_PHY_CONFIG,
406 "path-%d rate type %d (0x%x) = 0x%x\n",
407 path, rate_type, txagc_cck_ref[path], power_index);
408
409 /*OFDM reference setting */
410 } else {
411 odm_set_bb_reg(dm, txagc_ofdm_ref[path], 0x0001fc00,
412 power_index);
413 PHYDM_DBG(dm, ODM_PHY_CONFIG,
414 "path-%d rate type %d (0x%x) = 0x%x\n",
415 path, rate_type, txagc_ofdm_ref[path], power_index);
416 }
417
418 return true;
419 }
420
421 __odm_func__
422 boolean
config_phydm_write_txagc_diff_8822c(struct dm_struct * dm,s8 power_index1,s8 power_index2,s8 power_index3,s8 power_index4,u8 hw_rate)423 config_phydm_write_txagc_diff_8822c(struct dm_struct *dm, s8 power_index1,
424 s8 power_index2, s8 power_index3,
425 s8 power_index4, u8 hw_rate)
426 {
427 u32 offset_txagc = R_0x3a00;
428 u8 rate_idx = hw_rate & 0xfc; /*Extract the 0xfc */
429 u8 power_idx1 = 0;
430 u8 power_idx2 = 0;
431 u8 power_idx3 = 0;
432 u8 power_idx4 = 0;
433 u32 pw_all = 0;
434
435 power_idx1 = power_index1 & 0x7f;
436 power_idx2 = power_index2 & 0x7f;
437 power_idx3 = power_index3 & 0x7f;
438 power_idx4 = power_index4 & 0x7f;
439 pw_all = (power_idx4 << 24) | (power_idx3 << 16) | (power_idx2 << 8) |
440 power_idx1;
441
442 PHYDM_DBG(dm, ODM_PHY_CONFIG, "%s ======>\n", __func__);
443
444 /*Input need to be HW rate index, not driver rate index!!!! */
445 if (dm->is_disable_phy_api) {
446 PHYDM_DBG(dm, ODM_PHY_CONFIG, "Disable PHY API for debug\n");
447 return true;
448 }
449
450 /*Error handling */
451 if (hw_rate > ODM_RATEVHTSS2MCS9) {
452 PHYDM_DBG(dm, ODM_PHY_CONFIG, "Unsupported rate\n");
453 return false;
454 }
455
456 /*bbrstb TX AGC report - default disable */
457 /*Enable for writing the TX AGC table when bb_reset=0 */
458 if (odm_get_bb_reg(dm, R_0x1c90, BIT(15)))
459 odm_set_bb_reg(dm, R_0x1c90, BIT(15), 0x0);
460
461 /*According the rate to write in the ofdm or the cck */
462 /*driver need to construct a 4-byte power index */
463 odm_set_bb_reg(dm, (offset_txagc + rate_idx), MASKDWORD, pw_all);
464
465 PHYDM_DBG(dm, ODM_PHY_CONFIG, "rate index 0x%x (0x%x) = 0x%x\n",
466 hw_rate, (offset_txagc + hw_rate), pw_all);
467 return true;
468 }
469
470 #if 1 /*Will remove when FW fill TXAGC funciton well verified*/
471 __odm_func__
config_phydm_set_txagc_to_hw_8822c(struct dm_struct * dm)472 void config_phydm_set_txagc_to_hw_8822c(struct dm_struct *dm)
473 {
474 #if (defined(CONFIG_RUN_IN_DRV))
475 s8 diff_tab[2][NUM_RATE_AC_2SS]; /*power diff table of 2 paths*/
476 s8 diff_tab_min[NUM_RATE_AC_2SS];
477 u8 ref_pow_cck[2] = {dm->txagc_buff[RF_PATH_A][ODM_RATE11M],
478 dm->txagc_buff[RF_PATH_B][ODM_RATE11M]};
479 u8 ref_pow_ofdm[2] = {dm->txagc_buff[RF_PATH_A][ODM_RATEMCS7],
480 dm->txagc_buff[RF_PATH_B][ODM_RATEMCS7]};
481 u8 ref_pow_tmp = 0;
482 enum rf_path path = 0;
483 u8 i, j = 0;
484
485 if (*dm->is_fcs_mode_enable)
486 return;
487
488 /* === [Reference base] =============================================*/
489 #ifdef CONFIG_TXAGC_DEBUG_8822C
490 pr_debug("ref_pow_cck={%d, %d}, ref_pow_ofdm={%d, %d}\n",
491 ref_pow_cck[0], ref_pow_cck[1], ref_pow_ofdm[0],
492 ref_pow_ofdm[1]);
493 #endif
494 /*Set OFDM/CCK Ref. power index*/
495 config_phydm_write_txagc_ref_8822c(dm, ref_pow_cck[0], RF_PATH_A,
496 PDM_CCK);
497 config_phydm_write_txagc_ref_8822c(dm, ref_pow_cck[1], RF_PATH_B,
498 PDM_CCK);
499 config_phydm_write_txagc_ref_8822c(dm, ref_pow_ofdm[0], RF_PATH_A,
500 PDM_OFDM);
501 config_phydm_write_txagc_ref_8822c(dm, ref_pow_ofdm[1], RF_PATH_B,
502 PDM_OFDM);
503
504 /* === [Power By Rate] ==============================================*/
505 for (path = RF_PATH_A; path <= RF_PATH_B; path++)
506 odm_move_memory(dm, diff_tab[path], dm->txagc_buff[path],
507 NUM_RATE_AC_2SS);
508
509 #ifdef CONFIG_TXAGC_DEBUG_8822C
510 pr_debug("1. diff_tab path A\n");
511 for (i = 0; i <= ODM_RATEVHTSS2MCS9; i++)
512 pr_debug("[A][rate:%d] = %d\n", i, diff_tab[RF_PATH_A][i]);
513 pr_debug("2. diff_tab path B\n");
514 for (i = 0; i <= ODM_RATEVHTSS2MCS9; i++)
515 pr_debug("[B][rate:%d] = %d\n", i, diff_tab[RF_PATH_B][i]);
516 #endif
517
518 for (path = RF_PATH_A; path <= RF_PATH_B; path++) {
519 /*CCK*/
520 ref_pow_tmp = ref_pow_cck[path];
521 for (j = ODM_RATE1M; j <= ODM_RATE11M; j++) {
522 diff_tab[path][j] -= (s8)ref_pow_tmp;
523 /**/
524 }
525 /*OFDM*/
526 ref_pow_tmp = ref_pow_ofdm[path];
527 for (j = ODM_RATE6M; j <= ODM_RATEMCS15; j++) {
528 diff_tab[path][j] -= (s8)ref_pow_tmp;
529 /**/
530 }
531 for (j = ODM_RATEVHTSS1MCS0; j <= ODM_RATEVHTSS2MCS9; j++) {
532 diff_tab[path][j] -= (s8)ref_pow_tmp;
533 /**/
534 }
535 }
536
537 #ifdef CONFIG_TXAGC_DEBUG_8822C
538 pr_debug("3. diff_tab path A\n");
539 for (i = 0; i <= ODM_RATEVHTSS2MCS9; i++)
540 pr_debug("[A][rate:%d] = %d\n", i, diff_tab[RF_PATH_A][i]);
541 pr_debug("4. diff_tab path B\n");
542 for (i = 0; i <= ODM_RATEVHTSS2MCS9; i++)
543 pr_debug("[B][rate:%d] = %d\n", i, diff_tab[RF_PATH_B][i]);
544 #endif
545
546 for (i = ODM_RATE1M; i <= ODM_RATEMCS15; i++) {
547 diff_tab_min[i] = MIN_2(diff_tab[RF_PATH_A][i],
548 diff_tab[RF_PATH_B][i]);
549 #ifdef CONFIG_TXAGC_DEBUG_8822C
550 pr_debug("diff_tab_min[rate:%d]= %d\n", i, diff_tab_min[i]);
551 #endif
552 if (i % 4 == 3) {
553 config_phydm_write_txagc_diff_8822c(dm,
554 diff_tab_min[i - 3],
555 diff_tab_min[i - 2],
556 diff_tab_min[i - 1],
557 diff_tab_min[i],
558 i - 3);
559 }
560 }
561
562 for (i = ODM_RATEVHTSS1MCS0; i <= ODM_RATEVHTSS2MCS9; i++) {
563 diff_tab_min[i] = MIN_2(diff_tab[RF_PATH_A][i],
564 diff_tab[RF_PATH_B][i]);
565 #ifdef CONFIG_TXAGC_DEBUG_8822C
566 pr_debug("diff_tab_min[rate:%d]= %d\n", i, diff_tab_min[i]);
567 #endif
568 if (i % 4 == 3) {
569 config_phydm_write_txagc_diff_8822c(dm,
570 diff_tab_min[i - 3],
571 diff_tab_min[i - 2],
572 diff_tab_min[i - 1],
573 diff_tab_min[i],
574 i - 3);
575 }
576 }
577 #endif
578 }
579
580 __odm_func__
config_phydm_write_txagc_8822c(struct dm_struct * dm,u32 pw_idx,enum rf_path path,u8 hw_rate)581 boolean config_phydm_write_txagc_8822c(struct dm_struct *dm, u32 pw_idx,
582 enum rf_path path, u8 hw_rate)
583 {
584 #if (defined(CONFIG_RUN_IN_DRV))
585 u8 ref_rate = ODM_RATEMCS15;
586 u8 rate;
587 u8 fill_valid_cnt = 0;
588 u8 i = 0;
589
590 if (*dm->is_fcs_mode_enable)
591 return false;
592
593 if (dm->is_disable_phy_api) {
594 PHYDM_DBG(dm, ODM_PHY_CONFIG, "Disable PHY API for debug\n");
595 return true;
596 }
597
598 if (path > RF_PATH_B) {
599 pr_debug("[Warning 1] %s\n", __func__);
600 return false;
601 }
602
603 if ((hw_rate > ODM_RATEMCS15 && hw_rate <= ODM_RATEMCS31) ||
604 hw_rate > ODM_RATEVHTSS2MCS9) {
605 pr_debug("[Warning 2] %s\n", __func__);
606 return false;
607 }
608
609 if (hw_rate <= ODM_RATEMCS15)
610 ref_rate = ODM_RATEMCS15;
611 else
612 ref_rate = ODM_RATEVHTSS2MCS9;
613
614 fill_valid_cnt = ref_rate - hw_rate + 1;
615 if (fill_valid_cnt > 4)
616 fill_valid_cnt = 4;
617
618 for (i = 0; i < fill_valid_cnt; i++) {
619 rate = hw_rate + i;
620 if (rate > (PHY_NUM_RATE_IDX - 1)) /*Just for protection*/
621 break;
622
623 dm->txagc_buff[path][rate] = (u8)((pw_idx >> (8 * i)) & 0xff);
624 }
625 #endif
626 return true;
627 }
628 #endif
629
630 #if 1 /*API for FW fill txagc*/
631 __odm_func__
phydm_set_txagc_by_table_8822c(struct dm_struct * dm,struct txagc_table_8822c * tab)632 void phydm_set_txagc_by_table_8822c(struct dm_struct *dm,
633 struct txagc_table_8822c *tab)
634 {
635 #if (defined(CONFIG_RUN_IN_FW))
636 u8 i = 0;
637
638 /* === [Reference base] =============================================*/
639 /*Set OFDM/CCK Ref. power index*/
640 config_phydm_write_txagc_ref_8822c(dm, tab->ref_pow_cck[0], RF_PATH_A,
641 PDM_CCK);
642 config_phydm_write_txagc_ref_8822c(dm, tab->ref_pow_cck[1], RF_PATH_B,
643 PDM_CCK);
644 config_phydm_write_txagc_ref_8822c(dm, tab->ref_pow_ofdm[0], RF_PATH_A,
645 PDM_OFDM);
646 config_phydm_write_txagc_ref_8822c(dm, tab->ref_pow_ofdm[1], RF_PATH_B,
647 PDM_OFDM);
648
649 for (i = ODM_RATE1M; i <= ODM_RATEMCS15; i++) {
650 if (i % 4 == 3) {
651 config_phydm_write_txagc_diff_8822c(dm,
652 tab->diff_t[i - 3],
653 tab->diff_t[i - 2],
654 tab->diff_t[i - 1],
655 tab->diff_t[i],
656 i - 3);
657 }
658 }
659
660 for (i = ODM_RATEVHTSS1MCS0; i <= ODM_RATEVHTSS2MCS9; i++) {
661 if (i % 4 == 3) {
662 config_phydm_write_txagc_diff_8822c(dm,
663 tab->diff_t[i - 3],
664 tab->diff_t[i - 2],
665 tab->diff_t[i - 1],
666 tab->diff_t[i],
667 i - 3);
668 }
669 }
670 #endif
671 }
672
673 __odm_func__
phydm_get_txagc_ref_and_diff_8822c(struct dm_struct * dm,u8 txagc_buff[2][NUM_RATE_AC_2SS],u16 length,struct txagc_table_8822c * tab)674 void phydm_get_txagc_ref_and_diff_8822c(struct dm_struct *dm,
675 u8 txagc_buff[2][NUM_RATE_AC_2SS],
676 u16 length,
677 struct txagc_table_8822c *tab)
678 {
679 #if (defined(CONFIG_RUN_IN_DRV))
680 s8 diff_tab[2][NUM_RATE_AC_2SS]; /*power diff table of 2 paths*/
681 s8 diff_tab_min[NUM_RATE_AC_2SS];
682 u8 ref_pow_cck[2];
683 u8 ref_pow_ofdm[2];
684 u8 ref_pow_tmp = 0;
685 enum rf_path path = 0;
686 u8 i, j = 0;
687
688 if (*dm->mp_mode || !dm->is_download_fw)
689 return;
690
691 if (length != NUM_RATE_AC_2SS) {
692 pr_debug("[warning] %s\n", __func__);
693 return;
694 }
695
696 /* === [Reference base] =============================================*/
697 #ifdef CONFIG_TXAGC_DEBUG_8822C
698 pr_debug("ref_pow_cck={%d, %d}, ref_pow_ofdm={%d, %d}\n",
699 ref_pow_cck[0], ref_pow_cck[1], ref_pow_ofdm[0],
700 ref_pow_ofdm[1]);
701 #endif
702
703 /* === [Power By Rate] ==============================================*/
704 for (path = RF_PATH_A; path <= RF_PATH_B; path++)
705 odm_move_memory(dm, diff_tab[path], txagc_buff[path],
706 NUM_RATE_AC_2SS);
707
708 ref_pow_cck[0] = diff_tab[RF_PATH_A][ODM_RATE11M];
709 ref_pow_cck[1] = diff_tab[RF_PATH_B][ODM_RATE11M];
710
711 ref_pow_ofdm[0] = diff_tab[RF_PATH_A][ODM_RATEMCS7];
712 ref_pow_ofdm[1] = diff_tab[RF_PATH_B][ODM_RATEMCS7];
713
714 #ifdef CONFIG_TXAGC_DEBUG_8822C
715 pr_debug("1. diff_tab path A\n");
716 for (i = 0; i <= ODM_RATEVHTSS2MCS9; i++)
717 pr_debug("[A][rate:%d] = %d\n", i, diff_tab[RF_PATH_A][i]);
718 pr_debug("2. diff_tab path B\n");
719 for (i = 0; i <= ODM_RATEVHTSS2MCS9; i++)
720 pr_debug("[B][rate:%d] = %d\n", i, diff_tab[RF_PATH_B][i]);
721 #endif
722
723 for (path = RF_PATH_A; path <= RF_PATH_B; path++) {
724 /*CCK*/
725 ref_pow_tmp = ref_pow_cck[path];
726 for (j = ODM_RATE1M; j <= ODM_RATE11M; j++) {
727 diff_tab[path][j] -= (s8)ref_pow_tmp;
728 /**/
729 }
730 /*OFDM*/
731 ref_pow_tmp = ref_pow_ofdm[path];
732 for (j = ODM_RATE6M; j <= ODM_RATEMCS15; j++) {
733 diff_tab[path][j] -= (s8)ref_pow_tmp;
734 /**/
735 }
736 for (j = ODM_RATEVHTSS1MCS0; j <= ODM_RATEVHTSS2MCS9; j++) {
737 diff_tab[path][j] -= (s8)ref_pow_tmp;
738 /**/
739 }
740 }
741
742 #ifdef CONFIG_TXAGC_DEBUG_8822C
743 pr_debug("3. diff_tab path A\n");
744 for (i = 0; i <= ODM_RATEVHTSS2MCS9; i++)
745 pr_debug("[A][rate:%d] = %d\n", i, diff_tab[RF_PATH_A][i]);
746 pr_debug("4. diff_tab path B\n");
747 for (i = 0; i <= ODM_RATEVHTSS2MCS9; i++)
748 pr_debug("[B][rate:%d] = %d\n", i, diff_tab[RF_PATH_B][i]);
749 #endif
750
751 for (i = ODM_RATE1M; i <= ODM_RATEMCS15; i++) {
752 diff_tab_min[i] = MIN_2(diff_tab[RF_PATH_A][i],
753 diff_tab[RF_PATH_B][i]);
754 #ifdef CONFIG_TXAGC_DEBUG_8822C
755 pr_debug("diff_tab_min[rate:%d]= %d\n", i, diff_tab_min[i]);
756 #endif
757 }
758
759 for (i = ODM_RATEVHTSS1MCS0; i <= ODM_RATEVHTSS2MCS9; i++) {
760 diff_tab_min[i] = MIN_2(diff_tab[RF_PATH_A][i],
761 diff_tab[RF_PATH_B][i]);
762 #ifdef CONFIG_TXAGC_DEBUG_8822C
763 pr_debug("diff_tab_min[rate:%d]= %d\n", i, diff_tab_min[i]);
764 #endif
765 }
766
767 odm_move_memory(dm, tab->ref_pow_cck, ref_pow_cck, 2);
768 odm_move_memory(dm, tab->ref_pow_ofdm, ref_pow_ofdm, 2);
769 odm_move_memory(dm, tab->diff_t, diff_tab_min, NUM_RATE_AC_2SS);
770 #endif
771 }
772 #endif
773
774 __odm_func__
config_phydm_read_txagc_diff_8822c(struct dm_struct * dm,u8 hw_rate)775 s8 config_phydm_read_txagc_diff_8822c(struct dm_struct *dm, u8 hw_rate)
776 {
777 #if (PHYDM_FW_API_FUNC_ENABLE_8822C)
778 s8 read_back_data = 0;
779
780 PHYDM_DBG(dm, ODM_PHY_CONFIG, "%s ======>\n", __func__);
781
782 /* @Input need to be HW rate index, not driver rate index!!!! */
783
784 /* @Error handling */
785 if (hw_rate > 0x53) {
786 PHYDM_DBG(dm, ODM_PHY_CONFIG, "Unsupported rate\n");
787 return INVALID_TXAGC_DATA;
788 }
789
790 /* @Disable TX AGC report */
791 odm_set_bb_reg(dm, R_0x1c7c, BIT(23), 0x0); /* need to check */
792
793 /* @Set data rate index (bit30~24) */
794 odm_set_bb_reg(dm, R_0x1c7c, 0x7F000000, hw_rate);
795
796 /* @Enable TXAGC report */
797 odm_set_bb_reg(dm, R_0x1c7c, BIT(23), 0x1);
798
799 /* @Read TX AGC report */
800 read_back_data = (s8)odm_get_bb_reg(dm, R_0x2de8, 0xff);
801 if (read_back_data & BIT(6))
802 read_back_data |= BIT(7);
803
804 /* @Driver have to disable TXAGC report after reading TXAGC */
805 odm_set_bb_reg(dm, R_0x1c7c, BIT(23), 0x0);
806
807 PHYDM_DBG(dm, ODM_PHY_CONFIG, "rate index 0x%x = 0x%x\n", hw_rate,
808 read_back_data);
809 return read_back_data;
810 #else
811 return 0;
812 #endif
813 }
814
815 __odm_func__
config_phydm_read_txagc_8822c(struct dm_struct * dm,enum rf_path path,u8 hw_rate,enum PDM_RATE_TYPE rate_type)816 u8 config_phydm_read_txagc_8822c(struct dm_struct *dm, enum rf_path path,
817 u8 hw_rate, enum PDM_RATE_TYPE rate_type)
818 {
819 s8 read_back_data = 0;
820 u8 ref_data = 0;
821 u8 result_data = 0;
822 /* @2-path power reference */
823 u32 r_txagc_ofdm[2] = {R_0x18e8, R_0x41e8};
824 u32 r_txagc_cck[2] = {R_0x18a0, R_0x41a0};
825
826 PHYDM_DBG(dm, ODM_PHY_CONFIG, "%s ======>\n", __func__);
827
828 /* @Input need to be HW rate index, not driver rate index!!!! */
829
830 /* @Error handling */
831 if (path > RF_PATH_B || hw_rate > 0x53) {
832 PHYDM_DBG(dm, ODM_PHY_CONFIG, "Unsupported path (%d)\n", path);
833 return INVALID_TXAGC_DATA;
834 }
835
836 /* @Disable TX AGC report */
837 odm_set_bb_reg(dm, R_0x1c7c, BIT(23), 0x0); /* need to check */
838
839 /* @Set data rate index (bit30~24) */
840 odm_set_bb_reg(dm, R_0x1c7c, 0x7F000000, hw_rate);
841
842 /* @Enable TXAGC report */
843 odm_set_bb_reg(dm, R_0x1c7c, BIT(23), 0x1);
844
845 /* @Read power difference report */
846 read_back_data = (s8)odm_get_bb_reg(dm, R_0x2de8, 0xff);
847 if (read_back_data & BIT(6))
848 read_back_data |= BIT(7);
849
850 /* @Read power reference value report */
851 if (rate_type == PDM_CCK) /* @Bit=22:16 */
852 ref_data = (u8)odm_get_bb_reg(dm, r_txagc_cck[path], 0x7F0000);
853 else if (rate_type == PDM_OFDM) /* @Bit=16:10 */
854 ref_data = (u8)odm_get_bb_reg(dm, r_txagc_ofdm[path], 0x1FC00);
855
856 PHYDM_DBG(dm, ODM_PHY_CONFIG, "diff=%d ref=%d\n", read_back_data,
857 ref_data);
858
859 if (read_back_data + ref_data < 0)
860 result_data = 0;
861 else
862 result_data = read_back_data + ref_data;
863
864 /* @Driver have to disable TXAGC report after reading TXAGC */
865 odm_set_bb_reg(dm, R_0x1c7c, BIT(23), 0x0);
866
867 PHYDM_DBG(dm, ODM_PHY_CONFIG, "path-%d rate index 0x%x = 0x%x\n",
868 path, hw_rate, result_data);
869 return result_data;
870 }
871
872 __odm_func__
873 void
phydm_get_tx_path_en_setting_8822c(struct dm_struct * dm,struct tx_path_en_8822c * path)874 phydm_get_tx_path_en_setting_8822c(struct dm_struct *dm,
875 struct tx_path_en_8822c *path)
876 {
877 u32 val = 0;
878 #ifdef CONFIG_PATH_DIVERSITY
879 struct _ODM_PATH_DIVERSITY_ *p_div = &dm->dm_path_div;
880 #endif
881
882 /*OFDM*/
883 val = odm_get_bb_reg(dm, R_0x820, MASKDWORD);
884 path->tx_path_en_ofdm_2sts = (u8)((val & 0xf0) >> 4);
885 path->tx_path_en_ofdm_1sts = (u8)(val & 0xf);
886
887 /*CCK*/
888 val = odm_get_bb_reg(dm, R_0x1a04, 0xf0000000);
889
890 if (val == 0xc)
891 path->tx_path_en_cck = 3; /*AB*/
892 else if (val == 0x8)
893 path->tx_path_en_cck = 1; /*A*/
894 else if (val == 0x4)
895 path->tx_path_en_cck = 2; /*B*/
896 else if (val == 0x0)
897 path->tx_path_en_cck = 0; /*disable cck tx in 5G*/
898
899 /*Path CTRL source*/
900 val = odm_get_bb_reg(dm, R_0x1e24, BIT(16));
901 path->is_path_ctrl_by_bb_reg = (boolean)(~val);
902
903 /*stop path div*/
904 #ifdef CONFIG_PATH_DIVERSITY
905 path->stop_path_div = p_div->stop_path_div;
906 #else
907 path->stop_path_div = true;
908 #endif
909 }
910
911 __odm_func__
912 void
phydm_get_rx_path_en_setting_8822c(struct dm_struct * dm,struct rx_path_en_8822c * path)913 phydm_get_rx_path_en_setting_8822c(struct dm_struct *dm,
914 struct rx_path_en_8822c *path)
915 {
916 u32 val = 0;
917
918 /*OFDM*/
919 path->rx_path_en_ofdm = (u8)odm_get_bb_reg(dm, R_0x824, 0xf0000);
920
921 /*CCK*/
922 val = odm_get_bb_reg(dm, R_0x1a04, 0x0f000000);
923
924 if (val == 0x1)
925 path->rx_path_en_cck = 3; /*AB*/
926 else if (val == 0x0)
927 path->rx_path_en_cck = 1; /*A*/
928 else if (val == 0x5)
929 path->rx_path_en_cck = 2; /*B*/
930 }
931
932 __odm_func__
933 void
phydm_config_cck_tx_path_8822c(struct dm_struct * dm,enum bb_path tx_path)934 phydm_config_cck_tx_path_8822c(struct dm_struct *dm, enum bb_path tx_path)
935 {
936 if (tx_path == BB_PATH_A)
937 odm_set_bb_reg(dm, R_0x1a04, 0xf0000000, 0x8);
938 else if (tx_path == BB_PATH_B)
939 odm_set_bb_reg(dm, R_0x1a04, 0xf0000000, 0x4);
940 else /* if (tx_path == BB_PATH_AB)*/
941 odm_set_bb_reg(dm, R_0x1a04, 0xf0000000, 0xc);
942
943 phydm_bb_reset_8822c(dm);
944 }
945
946 __odm_func__
947 boolean
phydm_config_cck_rx_path_8822c(struct dm_struct * dm,enum bb_path rx_path)948 phydm_config_cck_rx_path_8822c(struct dm_struct *dm, enum bb_path rx_path)
949 {
950 boolean set_result = PHYDM_SET_FAIL;
951
952 if (rx_path == BB_PATH_A) {
953 /* Select ant_A to receive CCK_1 and CCK_2*/
954 odm_set_bb_reg(dm, R_0x1a04, 0x0f000000, 0x0);
955 /* Enable Rx clk gated */
956 odm_set_bb_reg(dm, R_0x1a2c, BIT(5), 0x0);
957 /* Disable MRC for CCK barker */
958 odm_set_bb_reg(dm, R_0x1a2c, 0x00060000, 0x0);
959 /* Disable MRC for CCK CCA */
960 odm_set_bb_reg(dm, R_0x1a2c, 0x00600000, 0x0);
961 } else if (rx_path == BB_PATH_B) {
962 /* Select ant_B to receive CCK_1 and CCK_2*/
963 odm_set_bb_reg(dm, R_0x1a04, 0x0f000000, 0x5);
964 /* Disable Rx clk gated */
965 odm_set_bb_reg(dm, R_0x1a2c, BIT(5), 0x1);
966 /* replace path-B with path-AB: [PHYDM-336]*/
967 /* Disable MRC for CCK barker */
968 odm_set_bb_reg(dm, R_0x1a2c, 0x00060000, 0x0);
969 /* Enable MRC for CCK CCA */
970 odm_set_bb_reg(dm, R_0x1a2c, 0x00600000, 0x1);
971 } else if (rx_path == BB_PATH_AB) {
972 /* Select ant_A to receive CCK_1 and ant_B to receive CCK_2*/
973 odm_set_bb_reg(dm, R_0x1a04, 0x0f000000, 0x1);
974 /* Enable Rx clk gated */
975 odm_set_bb_reg(dm, R_0x1a2c, BIT(5), 0x0);
976 /* Enable MRC for CCK barker */
977 odm_set_bb_reg(dm, R_0x1a2c, 0x00060000, 0x1);
978 /* Enable MRC for CCK CCA */
979 odm_set_bb_reg(dm, R_0x1a2c, 0x00600000, 0x1);
980 }
981
982 set_result = PHYDM_SET_SUCCESS;
983 phydm_bb_reset_8822c(dm);
984 return set_result;
985 }
986
987 __odm_func__
988 void
phydm_config_ofdm_tx_path_8822c(struct dm_struct * dm,enum bb_path tx_path_2ss,enum bb_path tx_path_sel_1ss)989 phydm_config_ofdm_tx_path_8822c(struct dm_struct *dm, enum bb_path tx_path_2ss,
990 enum bb_path tx_path_sel_1ss)
991 {
992 u8 tx_path_2ss_en = false;
993
994 if (tx_path_2ss == BB_PATH_AB)
995 tx_path_2ss_en = true;
996
997 if (!tx_path_2ss_en) {/* 1ss1T, do not config this with STBC*/
998 if (tx_path_sel_1ss == BB_PATH_A) {
999 odm_set_bb_reg(dm, R_0x820, 0xff, 0x1);
1000 odm_set_bb_reg(dm, R_0x1e2c, 0xffff, 0x0);
1001 } else { /*if (tx_path_sel_1ss == BB_PATH_B)*/
1002 odm_set_bb_reg(dm, R_0x820, 0xff, 0x2);
1003 odm_set_bb_reg(dm, R_0x1e2c, 0xffff, 0x0);
1004 }
1005 } else {
1006 if (tx_path_sel_1ss == BB_PATH_A) {
1007 odm_set_bb_reg(dm, R_0x820, 0xff, 0x31);
1008 odm_set_bb_reg(dm, R_0x1e2c, 0xffff, 0x0400);
1009 } else if (tx_path_sel_1ss == BB_PATH_B) {
1010 odm_set_bb_reg(dm, R_0x820, 0xff, 0x32);
1011 odm_set_bb_reg(dm, R_0x1e2c, 0xffff, 0x0400);
1012 } else { /*BB_PATH_AB*/
1013 odm_set_bb_reg(dm, R_0x820, 0xff, 0x33);
1014 odm_set_bb_reg(dm, R_0x1e2c, 0xffff, 0x0404);
1015 }
1016 }
1017
1018 phydm_bb_reset_8822c(dm);
1019 }
1020
1021 __odm_func__
1022 void
phydm_config_ofdm_rx_path_8822c(struct dm_struct * dm,enum bb_path rx_path)1023 phydm_config_ofdm_rx_path_8822c(struct dm_struct *dm, enum bb_path rx_path)
1024 {
1025 u32 ofdm_rx = 0x0;
1026
1027 ofdm_rx = (u32)rx_path;
1028 if (!(*dm->mp_mode)) {
1029 if (ofdm_rx == BB_PATH_B) {
1030 ofdm_rx = BB_PATH_AB;
1031 odm_set_bb_reg(dm, R_0xcc0, 0x7ff, 0x0);
1032 odm_set_bb_reg(dm, R_0xcc0, BIT(22), 0x1);
1033 odm_set_bb_reg(dm, R_0xcc8, 0x7ff, 0x0);
1034 odm_set_bb_reg(dm, R_0xcc8, BIT(22), 0x1);
1035 } else { /* ofdm_rx == BB_PATH_A || ofdm_rx == BB_PATH_AB*/
1036 odm_set_bb_reg(dm, R_0xcc0, 0x7ff, 0x400);
1037 odm_set_bb_reg(dm, R_0xcc0, BIT(22), 0x0);
1038 odm_set_bb_reg(dm, R_0xcc8, 0x7ff, 0x400);
1039 odm_set_bb_reg(dm, R_0xcc8, BIT(22), 0x0);
1040 }
1041 }
1042
1043 if (ofdm_rx == BB_PATH_A || ofdm_rx == BB_PATH_B) {
1044 /*@ ht_mcs_limit*/
1045 odm_set_bb_reg(dm, R_0x1d30, 0x300, 0x0);
1046 /*@ vht_nss_limit*/
1047 odm_set_bb_reg(dm, R_0x1d30, 0x600000, 0x0);
1048 /* @Disable Antenna weighting */
1049 odm_set_bb_reg(dm, R_0xc44, BIT(17), 0x0);
1050 /* @htstf ant-wgt enable = 0*/
1051 odm_set_bb_reg(dm, R_0xc54, BIT(20), 0x0);
1052 /* @MRC_mode = 'original ZF eqz'*/
1053 odm_set_bb_reg(dm, R_0xc38, BIT(24), 0x0);
1054 /* @Rx_ant */
1055 odm_set_bb_reg(dm, R_0x824, 0x000f0000, rx_path);
1056 /* @Rx_CCA*/
1057 odm_set_bb_reg(dm, R_0x824, 0x0f000000, rx_path);
1058 } else if (ofdm_rx == BB_PATH_AB) {
1059 /*@ ht_mcs_limit*/
1060 odm_set_bb_reg(dm, R_0x1d30, 0x300, 0x1);
1061 /*@ vht_nss_limit*/
1062 odm_set_bb_reg(dm, R_0x1d30, 0x600000, 0x1);
1063 /* @Enable Antenna weighting */
1064 odm_set_bb_reg(dm, R_0xc44, BIT(17), 0x1);
1065 /* @htstf ant-wgt enable = 1*/
1066 odm_set_bb_reg(dm, R_0xc54, BIT(20), 0x1);
1067 /* @MRC_mode = 'modified ZF eqz'*/
1068 odm_set_bb_reg(dm, R_0xc38, BIT(24), 0x1);
1069 /* @Rx_ant */
1070 odm_set_bb_reg(dm, R_0x824, 0x000f0000, BB_PATH_AB);
1071 /* @Rx_CCA*/
1072 odm_set_bb_reg(dm, R_0x824, 0x0f000000, BB_PATH_AB);
1073 }
1074
1075 phydm_bb_reset_8822c(dm);
1076 }
1077
1078 __odm_func__
phydm_config_tx_path_8822c(struct dm_struct * dm,enum bb_path tx_path_2ss,enum bb_path tx_path_sel_1ss,enum bb_path tx_path_sel_cck)1079 void phydm_config_tx_path_8822c(struct dm_struct *dm, enum bb_path tx_path_2ss,
1080 enum bb_path tx_path_sel_1ss,
1081 enum bb_path tx_path_sel_cck)
1082 {
1083 dm->tx_2ss_status = tx_path_2ss;
1084 dm->tx_1ss_status = tx_path_sel_1ss;
1085
1086 dm->tx_ant_status = dm->tx_2ss_status | dm->tx_1ss_status;
1087
1088 /* @CCK TX antenna mapping */
1089 phydm_config_cck_tx_path_8822c(dm, tx_path_sel_cck);
1090
1091 /* @OFDM TX antenna mapping*/
1092 phydm_config_ofdm_tx_path_8822c(dm, tx_path_2ss, tx_path_sel_1ss);
1093
1094 PHYDM_DBG(dm, ODM_PHY_CONFIG, "path_sel_2ss/1ss/cck={%d, %d, %d}\n",
1095 tx_path_2ss, tx_path_sel_1ss, tx_path_sel_cck);
1096
1097 phydm_bb_reset_8822c(dm);
1098 }
1099
1100 __odm_func__
phydm_config_rx_path_8822c(struct dm_struct * dm,enum bb_path rx_path)1101 void phydm_config_rx_path_8822c(struct dm_struct *dm, enum bb_path rx_path)
1102 {
1103 /* @CCK RX antenna mapping */
1104 phydm_config_cck_rx_path_8822c(dm, rx_path);
1105
1106 /* @OFDM RX antenna mapping*/
1107 phydm_config_ofdm_rx_path_8822c(dm, rx_path);
1108
1109 dm->rx_ant_status = rx_path;
1110
1111 phydm_bb_reset_8822c(dm);
1112 }
1113
1114 __odm_func__
1115 void
phydm_set_rf_mode_table_8822c(struct dm_struct * dm,enum bb_path tx_path_mode_table,enum bb_path rx_path)1116 phydm_set_rf_mode_table_8822c(struct dm_struct *dm,
1117 enum bb_path tx_path_mode_table,
1118 enum bb_path rx_path)
1119 {
1120 /*Cannot shutdown path-A, beacause synthesizer will shutdown
1121 *when path-A is in shut down mode.
1122 */
1123
1124 /*Cannot set path-A into standby mode due to the sensitivity of CCK
1125 *would degrade when 1T1R-B.
1126 */
1127
1128 /*RF mode setting : 0:shutdown, 1:standby, 2:TX, 3:RX*/
1129 /*Mode table setting : tx:[3:0], txoff:[7:4], rx:[19:8]*/
1130 if (rx_path == BB_PATH_A) {
1131 if (tx_path_mode_table == BB_PATH_A)
1132 odm_set_bb_reg(dm, R_0x4100, 0xfffff, 0x0);
1133 else
1134 odm_set_bb_reg(dm, R_0x4100, 0xfffff, 0x11112);
1135 } else {
1136 odm_set_bb_reg(dm, R_0x4100, 0xfffff, 0x33312);
1137 }
1138 }
1139
1140 __odm_func__
1141 void
phydm_rfe_8822c(struct dm_struct * dm,enum bb_path path)1142 phydm_rfe_8822c(struct dm_struct *dm, enum bb_path path)
1143 {
1144 u8 rfe_type = dm->rfe_type;
1145 u32 rf_reg18 = 0;
1146 u8 central_ch = 0;
1147 boolean is_2g_ch = false;
1148
1149 rf_reg18 = config_phydm_read_rf_reg_8822c(dm, RF_PATH_A, RF_0x18,
1150 RFREG_MASK);
1151 central_ch = (u8)(rf_reg18 & 0xff);
1152 is_2g_ch = (central_ch <= 14) ? true : false;
1153
1154 PHYDM_DBG(dm, ODM_PHY_CONFIG,
1155 "[8822C] Update RFE PINs: T/RX_path:{0x%x, 0x%x}, rfe_type:%d\n",
1156 dm->tx_ant_status, dm->rx_ant_status, rfe_type);
1157
1158 /*HW Setting for each RFE type */
1159 if (rfe_type == 21 || rfe_type == 22) {
1160 /*rfe sel*/
1161 /*0 : PAPE_2G_rfm*/
1162 /*2 : LNAON_2G*/
1163 /*3 : rfm_lnaon*/
1164 /*7 : 1'b0*/
1165 if (is_2g_ch)
1166 path = BB_PATH_NON;
1167
1168 switch (path) {
1169 case BB_PATH_NON:
1170 odm_set_bb_reg(dm, R_0x1840, 0xffff, 0x7770);
1171 odm_set_bb_reg(dm, R_0x4144, 0xffff, 0x7077);
1172 break;
1173 case BB_PATH_A:
1174 odm_set_bb_reg(dm, R_0x1840, 0xffff, 0x2300);
1175 odm_set_bb_reg(dm, R_0x4144, 0xffff, 0x7077);
1176 break;
1177 case BB_PATH_B:
1178 odm_set_bb_reg(dm, R_0x1840, 0xffff, 0x7770);
1179 odm_set_bb_reg(dm, R_0x4144, 0xffff, 0x2030);
1180 break;
1181 case BB_PATH_AB:
1182 odm_set_bb_reg(dm, R_0x1840, 0xffff, 0x2300);
1183 odm_set_bb_reg(dm, R_0x4144, 0xffff, 0x2030);
1184 break;
1185 default:
1186 break;
1187 }
1188 }
1189 }
1190
1191 __odm_func__
1192 boolean
config_phydm_trx_mode_8822c(struct dm_struct * dm,enum bb_path tx_path_en,enum bb_path rx_path,enum bb_path tx_path_sel_1ss)1193 config_phydm_trx_mode_8822c(struct dm_struct *dm, enum bb_path tx_path_en,
1194 enum bb_path rx_path, enum bb_path tx_path_sel_1ss)
1195 {
1196 #ifdef CONFIG_PATH_DIVERSITY
1197 struct _ODM_PATH_DIVERSITY_ *p_div = &dm->dm_path_div;
1198 #endif
1199 boolean disable_2sts_div_mode = false;
1200 enum bb_path tx_path_mode_table = tx_path_en;
1201 enum bb_path tx_path_2ss = BB_PATH_AB;
1202 u8 rfe_type = dm->rfe_type;
1203
1204 PHYDM_DBG(dm, ODM_PHY_CONFIG, "%s ======>\n", __func__);
1205
1206 if (dm->is_disable_phy_api) {
1207 pr_debug("[%s] Disable PHY API\n", __func__);
1208 return true;
1209 }
1210
1211 /*RX Check*/
1212 if (rx_path & ~BB_PATH_AB) {
1213 pr_debug("[Warning][%s] RX:0x%x\n", __func__, rx_path);
1214 return false;
1215 }
1216
1217 /*TX Check*/
1218 if (tx_path_en == BB_PATH_AUTO && tx_path_sel_1ss == BB_PATH_AUTO) {
1219 /*@ Shutting down 2sts rate, but 1sts PathDiv is enabled*/
1220 disable_2sts_div_mode = true;
1221 tx_path_mode_table = BB_PATH_AB;
1222 } else if (tx_path_en & ~BB_PATH_AB) {
1223 pr_debug("[Warning][%s] TX:0x%x\n", __func__, tx_path_en);
1224 return false;
1225 }
1226
1227 /* @==== [RF Mode Table] ========================================*/
1228 phydm_set_rf_mode_table_8822c(dm, tx_path_mode_table, rx_path);
1229
1230 /* @==== [RX Path] ==============================================*/
1231 phydm_config_rx_path_8822c(dm, rx_path);
1232
1233 /* @==== [TX Path] ==============================================*/
1234 #ifdef CONFIG_PATH_DIVERSITY
1235 /*@ [PHYDM-312]*/
1236 if (p_div->default_tx_path != BB_PATH_A &&
1237 p_div->default_tx_path != BB_PATH_B)
1238 p_div->default_tx_path = BB_PATH_A;
1239
1240 if (tx_path_en == BB_PATH_A || tx_path_en == BB_PATH_B) {
1241 p_div->stop_path_div = true;
1242 tx_path_sel_1ss = tx_path_en;
1243 tx_path_2ss = BB_PATH_NON;
1244 } else if (tx_path_en == BB_PATH_AB) {
1245 if (tx_path_sel_1ss == BB_PATH_AUTO) {
1246 p_div->stop_path_div = false;
1247 tx_path_sel_1ss = p_div->default_tx_path;
1248 } else { /* @BB_PATH_AB, BB_PATH_A, BB_PATH_B*/
1249 p_div->stop_path_div = true;
1250 }
1251 tx_path_2ss = BB_PATH_AB;
1252 } else if (disable_2sts_div_mode) {
1253 p_div->stop_path_div = false;
1254 tx_path_sel_1ss = p_div->default_tx_path;
1255 tx_path_2ss = BB_PATH_NON;
1256 }
1257 #else
1258 if (dm->tx_1ss_status == BB_PATH_NON)
1259 dm->tx_1ss_status = BB_PATH_A;
1260
1261 if (tx_path_en == BB_PATH_A || tx_path_en == BB_PATH_B) {
1262 tx_path_2ss = BB_PATH_NON;
1263 tx_path_sel_1ss = tx_path_en;
1264 } else if (tx_path_en == BB_PATH_AB) {
1265 tx_path_2ss = BB_PATH_AB;
1266 if (tx_path_sel_1ss == BB_PATH_AUTO)
1267 tx_path_sel_1ss = dm->tx_1ss_status;
1268 } else if (disable_2sts_div_mode) {
1269 tx_path_2ss = BB_PATH_NON;
1270 tx_path_sel_1ss = dm->tx_1ss_status;
1271 }
1272 #endif
1273 phydm_config_tx_path_8822c(dm, tx_path_2ss, tx_path_sel_1ss,
1274 tx_path_sel_1ss);
1275
1276 /*====== [RFE ctrl] =============================================*/
1277 if (rfe_type == 21 || rfe_type == 22) {
1278 if (dm->tx_ant_status == BB_PATH_A && rx_path == BB_PATH_A)
1279 phydm_rfe_8822c(dm, BB_PATH_A);
1280 else if (dm->tx_ant_status == BB_PATH_B && rx_path == BB_PATH_B)
1281 phydm_rfe_8822c(dm, BB_PATH_B);
1282 else
1283 phydm_rfe_8822c(dm, BB_PATH_AB);
1284 }
1285
1286 PHYDM_DBG(dm, ODM_PHY_CONFIG, "RX_en=%x, tx_en/2ss/1ss={%x,%x,%x}\n",
1287 rx_path, tx_path_en, tx_path_2ss, tx_path_sel_1ss);
1288
1289 phydm_bb_reset_8822c(dm);
1290
1291 phydm_igi_toggle_8822c(dm);
1292
1293 return true;
1294 }
1295
phydm_cck_rxiq_8822c(struct dm_struct * dm,u8 set_type)1296 void phydm_cck_rxiq_8822c(struct dm_struct *dm, u8 set_type)
1297 {
1298 PHYDM_DBG(dm, ODM_PHY_CONFIG, "%s ======>\n", __func__);
1299
1300 if (set_type == PHYDM_SET) {
1301 /* @ CCK source 5*/
1302 odm_set_bb_reg(dm, R_0x1a9c, BIT(20), 0x1);
1303 /* @ CCK RxIQ weighting = [1,1] */
1304 odm_set_bb_reg(dm, R_0x1a14, 0x300, 0x0);
1305 } else if (set_type == PHYDM_REVERT) {
1306 /* @ CCK source 1*/
1307 odm_set_bb_reg(dm, R_0x1a9c, BIT(20), 0x0);
1308 /* @ CCK RxIQ weighting = [0,0] */
1309 odm_set_bb_reg(dm, R_0x1a14, 0x300, 0x3);
1310 }
1311 }
1312
1313 __odm_func__
1314 boolean
config_phydm_switch_band_8822c(struct dm_struct * dm,u8 central_ch)1315 config_phydm_switch_band_8822c(struct dm_struct *dm, u8 central_ch)
1316 {
1317 return true;
1318 }
1319
1320 __odm_func__
1321 void
phydm_cck_tx_shaping_filter_8822c(struct dm_struct * dm,u8 central_ch)1322 phydm_cck_tx_shaping_filter_8822c(struct dm_struct *dm, u8 central_ch)
1323 {
1324 if (central_ch == 14) {
1325 /*TX Shaping Filter C0~1 */
1326 odm_set_bb_reg(dm, R_0x1a20, MASKHWORD, 0x3da0);
1327 /*TX Shaping Filter C2~5 */
1328 odm_set_bb_reg(dm, R_0x1a24, MASKDWORD, 0x4962c931);
1329 /*TX Shaping Filter C6~7 */
1330 odm_set_bb_reg(dm, R_0x1a28, MASKLWORD, 0x6aa3);
1331 /*TX Shaping Filter C8~9 */
1332 odm_set_bb_reg(dm, R_0x1a98, MASKHWORD, 0xaa7b);
1333 /*TX Shaping Filter C10~11 */
1334 odm_set_bb_reg(dm, R_0x1a9c, MASKLWORD, 0xf3d7);
1335 /*TX Shaping Filter C12~15 */
1336 odm_set_bb_reg(dm, R_0x1aa0, MASKDWORD, 0x00000000);
1337 /*TX Shaping Filter_MSB C0~7 */
1338 odm_set_bb_reg(dm, R_0x1aac, MASKDWORD, 0xfe012577);
1339 /*TX Shaping Filter_MSB C8~15 */
1340 odm_set_bb_reg(dm, R_0x1ab0, MASKDWORD, 0x0000ffff);
1341 /*Tx backoff CCK*/
1342 odm_set_bb_reg(dm, R_0x818, 0xf8000000, 0x1f);
1343 } else {
1344 /*TX Shaping Filter C0~1 */
1345 odm_set_bb_reg(dm, R_0x1a20, MASKHWORD, 0x5284);
1346 /*TX Shaping Filter C2~5 */
1347 odm_set_bb_reg(dm, R_0x1a24, MASKDWORD, 0x3e18fec8);
1348 /*TX Shaping Filter C6~7 */
1349 odm_set_bb_reg(dm, R_0x1a28, MASKLWORD, 0x0a88);
1350 /*TX Shaping Filter C8~9 */
1351 odm_set_bb_reg(dm, R_0x1a98, MASKHWORD, 0xacc4);
1352 /*TX Shaping Filter C10~11 */
1353 odm_set_bb_reg(dm, R_0x1a9c, MASKLWORD, 0xc8b2);
1354 /*TX Shaping Filter C12~15 */
1355 odm_set_bb_reg(dm, R_0x1aa0, MASKDWORD, 0x00faf0de);
1356 /*TX Shaping Filter_MSB C0~7 */
1357 odm_set_bb_reg(dm, R_0x1aac, MASKDWORD, 0x00122344);
1358 /*TX Shaping Filter_MSB C8~15 */
1359 odm_set_bb_reg(dm, R_0x1ab0, MASKDWORD, 0x0fffffff);
1360 /*Tx backoff CCK*/
1361 odm_set_bb_reg(dm, R_0x818, 0xf8000000, 0x18);
1362 }
1363 }
1364
1365 __odm_func__
1366 void
phydm_cck_agc_tab_sel_8822c(struct dm_struct * dm,u8 table)1367 phydm_cck_agc_tab_sel_8822c(struct dm_struct *dm, u8 table)
1368 {
1369 odm_set_bb_reg(dm, R_0x18ac, 0xf000, table);
1370 odm_set_bb_reg(dm, R_0x41ac, 0xf000, table);
1371 }
1372
1373 __odm_func__
1374 void
phydm_ofdm_agc_tab_sel_8822c(struct dm_struct * dm,u8 table)1375 phydm_ofdm_agc_tab_sel_8822c(struct dm_struct *dm, u8 table)
1376 {
1377 struct phydm_dig_struct *dig_tab = &dm->dm_dig_table;
1378 u8 lower_bound = dm->ofdm_rxagc_l_bnd[table];
1379
1380 odm_set_bb_reg(dm, R_0x18ac, 0x1f0, table);
1381 odm_set_bb_reg(dm, R_0x41ac, 0x1f0, table);
1382 dig_tab->agc_table_idx = table;
1383
1384 if (!dm->l_bnd_detect[table])
1385 lower_bound = L_BND_DEFAULT_8822C;
1386
1387 /*AGC lower bound, need to be updated with AGC table*/
1388 odm_set_bb_reg(dm, R_0x828, 0xf8, lower_bound);
1389 }
1390
1391 __odm_func__
1392 void
phydm_sco_trk_fc_setting_8822c(struct dm_struct * dm,u8 central_ch)1393 phydm_sco_trk_fc_setting_8822c(struct dm_struct *dm, u8 central_ch)
1394 {
1395 if (central_ch == 13 || central_ch == 14) {
1396 /* @n:41, s:37 */
1397 odm_set_bb_reg(dm, R_0xc30, 0xfff, 0x969);
1398 } else if (central_ch == 11 || central_ch == 12) {
1399 /* @n:42, s:37 */
1400 odm_set_bb_reg(dm, R_0xc30, 0xfff, 0x96a);
1401 } else if (central_ch >= 1 && central_ch <= 10) {
1402 /* @n:42, s:38 */
1403 odm_set_bb_reg(dm, R_0xc30, 0xfff, 0x9aa);
1404 } else if (central_ch >= 36 && central_ch <= 51) {
1405 /* @n:20, s:18 */
1406 odm_set_bb_reg(dm, R_0xc30, 0xfff, 0x494);
1407 } else if (central_ch >= 52 && central_ch <= 55) {
1408 /* @n:19, s:18 */
1409 odm_set_bb_reg(dm, R_0xc30, 0xfff, 0x493);
1410 } else if ((central_ch >= 56) && (central_ch <= 111)) {
1411 /* @n:19, s:17 */
1412 odm_set_bb_reg(dm, R_0xc30, 0xfff, 0x453);
1413 } else if ((central_ch >= 112) && (central_ch <= 119)) {
1414 /* @n:18, s:17 */
1415 odm_set_bb_reg(dm, R_0xc30, 0xfff, 0x452);
1416 } else if ((central_ch >= 120) && (central_ch <= 172)) {
1417 /* @n:18, s:16 */
1418 odm_set_bb_reg(dm, R_0xc30, 0xfff, 0x412);
1419 } else { /* if ((central_ch >= 173) && (central_ch <= 177)) */
1420 /* n:17, s:16 */
1421 odm_set_bb_reg(dm, R_0xc30, 0xfff, 0x411);
1422 }
1423 }
1424
1425 __odm_func__
1426 void
phydm_tx_dfir_setting_8822c(struct dm_struct * dm,u8 central_ch)1427 phydm_tx_dfir_setting_8822c(struct dm_struct *dm, u8 central_ch)
1428 {
1429 if (central_ch <= 14) {
1430 if (central_ch == 13)
1431 odm_set_bb_reg(dm, R_0x808, 0x70, 0x3);
1432 else
1433 odm_set_bb_reg(dm, R_0x808, 0x70, 0x1);
1434 } else {
1435 odm_set_bb_reg(dm, R_0x808, 0x70, 0x3);
1436 }
1437 }
1438
1439 __odm_func__
phydm_set_manual_nbi_8822c(struct dm_struct * dm,boolean en_manual_nbi,int tone_idx)1440 void phydm_set_manual_nbi_8822c(struct dm_struct *dm, boolean en_manual_nbi,
1441 int tone_idx)
1442 {
1443 if (en_manual_nbi) {
1444 /*set tone_idx*/
1445 odm_set_bb_reg(dm, R_0x1944, 0x001ff000, tone_idx);
1446 odm_set_bb_reg(dm, R_0x4044, 0x001ff000, tone_idx);
1447 /*enable manual NBI path_en*/
1448 odm_set_bb_reg(dm, R_0x1940, BIT(31), 0x1);
1449 odm_set_bb_reg(dm, R_0x4040, BIT(31), 0x1);
1450 /*enable manual NBI*/
1451 odm_set_bb_reg(dm, R_0x818, BIT(11), 0x1);
1452 /*enable NBI block*/
1453 odm_set_bb_reg(dm, R_0x1d3c, 0x78000000, 0xf);
1454 } else {
1455 /*reset tone_idx*/
1456 odm_set_bb_reg(dm, R_0x1944, 0x001ff000, 0x0);
1457 odm_set_bb_reg(dm, R_0x4044, 0x001ff000, 0x0);
1458 /*disable manual NBI path_en*/
1459 odm_set_bb_reg(dm, R_0x1940, BIT(31), 0x0);
1460 odm_set_bb_reg(dm, R_0x4040, BIT(31), 0x0);
1461 /*disable manual NBI*/
1462 odm_set_bb_reg(dm, R_0x818, BIT(11), 0x0);
1463 /*disable NBI block*/
1464 odm_set_bb_reg(dm, R_0x1d3c, 0x78000000, 0x0);
1465 }
1466 }
1467
1468 __odm_func__
phydm_set_nbi_wa_para_8822c(struct dm_struct * dm,boolean en_nbi,enum channel_width bw)1469 void phydm_set_nbi_wa_para_8822c(struct dm_struct *dm, boolean en_nbi,
1470 enum channel_width bw)
1471 {
1472 if (en_nbi) {
1473 switch (bw) {
1474 case CHANNEL_WIDTH_20:
1475 case CHANNEL_WIDTH_80:
1476 odm_set_bb_reg(dm, R_0x810, 0xf, 0x7);
1477 odm_set_bb_reg(dm, R_0x810, 0xf0000, 0x7);
1478 odm_set_bb_reg(dm, R_0x88c, 0x30000, 0x3);
1479 odm_set_bb_reg(dm, R_0x1944, 0x300, 0x3);
1480 odm_set_bb_reg(dm, R_0x4044, 0x300, 0x3);
1481 break;
1482 case CHANNEL_WIDTH_40:
1483 odm_set_bb_reg(dm, R_0x810, 0xf, 0x7);
1484 odm_set_bb_reg(dm, R_0x810, 0xf0000, 0x7);
1485 odm_set_bb_reg(dm, R_0x88c, 0x30000, 0x3);
1486 odm_set_bb_reg(dm, R_0x1944, 0x300, 0x0);
1487 odm_set_bb_reg(dm, R_0x4044, 0x300, 0x0);
1488 break;
1489 default:
1490 break;
1491 }
1492 } else {
1493 odm_set_bb_reg(dm, R_0x810, 0xf, 0x0);
1494 odm_set_bb_reg(dm, R_0x810, 0xf0000, 0x0);
1495 odm_set_bb_reg(dm, R_0x88c, 0x30000, 0x2);
1496 odm_set_bb_reg(dm, R_0x1944, 0x300, 0x3);
1497 odm_set_bb_reg(dm, R_0x4044, 0x300, 0x3);
1498 }
1499 }
1500
1501 __odm_func__
phydm_set_auto_nbi_8822c(struct dm_struct * dm,boolean en_auto_nbi)1502 void phydm_set_auto_nbi_8822c(struct dm_struct *dm, boolean en_auto_nbi)
1503 {
1504 if (en_auto_nbi) {
1505 /*enable auto nbi detection*/
1506 odm_set_bb_reg(dm, R_0x818, BIT(3), 0x1);
1507 odm_set_bb_reg(dm, R_0x1d3c, 0x78000000, 0xf);
1508 } else {
1509 odm_set_bb_reg(dm, R_0x818, BIT(3), 0x0);
1510 odm_set_bb_reg(dm, R_0x1d3c, 0x78000000, 0x0);
1511 }
1512
1513 if (dm->en_nbi_detect) /*0x1 would be effective for techicolor*/
1514 odm_set_bb_reg(dm, R_0x818, 0x7, 0x1);
1515 }
1516
1517 __odm_func__
phydm_csi_mask_enable_8822c(struct dm_struct * dm,boolean enable)1518 void phydm_csi_mask_enable_8822c(struct dm_struct *dm, boolean enable)
1519 {
1520 if (enable)
1521 odm_set_bb_reg(dm, R_0xc0c, BIT(3), 0x1);
1522 else
1523 odm_set_bb_reg(dm, R_0xc0c, BIT(3), 0x0);
1524 }
1525
1526 __odm_func__
phydm_set_csi_mask_8822c(struct dm_struct * dm,u32 tone_idx)1527 void phydm_set_csi_mask_8822c(struct dm_struct *dm, u32 tone_idx)
1528 {
1529 u32 table_addr = tone_idx >> 1;
1530
1531 /*enable clk*/
1532 odm_set_bb_reg(dm, R_0x1ee8, 0x3, 0x3);
1533 /*enable write table*/
1534 odm_set_bb_reg(dm, R_0x1d94, BIT(31) | BIT(30), 0x1);
1535 /*set table_addr*/
1536 odm_set_bb_reg(dm, R_0x1d94, MASKBYTE2, (table_addr & 0xff));
1537
1538 if (tone_idx & 0x1)
1539 odm_set_bb_reg(dm, R_0x1d94, 0xf0, 0x8);
1540 else
1541 odm_set_bb_reg(dm, R_0x1d94, 0xf, 0x8);
1542
1543 /*disable clk*/
1544 odm_set_bb_reg(dm, R_0x1ee8, 0x3, 0x0);
1545 }
1546
1547 __odm_func__
phydm_clean_all_csi_mask_8822c(struct dm_struct * dm)1548 void phydm_clean_all_csi_mask_8822c(struct dm_struct *dm)
1549 {
1550 u8 i = 0;
1551
1552 /*enable clk*/
1553 odm_set_bb_reg(dm, R_0x1ee8, 0x3, 0x3);
1554 /*enable write table*/
1555 odm_set_bb_reg(dm, R_0x1d94, BIT(31) | BIT(30), 0x1);
1556
1557 for (i = 0; i < 128; i++) {
1558 odm_set_bb_reg(dm, R_0x1d94, MASKBYTE2, i);
1559 odm_set_bb_reg(dm, R_0x1d94, MASKBYTE0, 0x0);
1560 }
1561
1562 /*disable clk*/
1563 odm_set_bb_reg(dm, R_0x1ee8, 0x3, 0x0);
1564 }
1565
1566 __odm_func__
phydm_spur_eliminate_8822c(struct dm_struct * dm,u8 central_ch)1567 void phydm_spur_eliminate_8822c(struct dm_struct *dm, u8 central_ch)
1568 {
1569 phydm_set_auto_nbi_8822c(dm, false);
1570 phydm_csi_mask_enable_8822c(dm, true);
1571
1572 if (central_ch == 153 && (*dm->band_width == CHANNEL_WIDTH_20)) {
1573 phydm_set_manual_nbi_8822c(dm, true, 112); /*5760 MHz*/
1574 phydm_set_nbi_wa_para_8822c(dm, true, *dm->band_width);
1575 phydm_set_csi_mask_8822c(dm, 112);
1576 } else if (central_ch == 151 && (*dm->band_width == CHANNEL_WIDTH_40)) {
1577 phydm_set_manual_nbi_8822c(dm, true, 16); /*5760 MHz*/
1578 phydm_set_nbi_wa_para_8822c(dm, true, *dm->band_width);
1579 phydm_set_csi_mask_8822c(dm, 16);
1580 } else if (central_ch == 155 && (*dm->band_width == CHANNEL_WIDTH_80)) {
1581 phydm_set_manual_nbi_8822c(dm, true, 208); /*5760 MHz*/
1582 phydm_set_nbi_wa_para_8822c(dm, true, *dm->band_width);
1583 phydm_set_csi_mask_8822c(dm, 208);
1584 } else {
1585 phydm_set_manual_nbi_8822c(dm, false, 0);
1586 phydm_set_nbi_wa_para_8822c(dm, false, *dm->band_width);
1587 phydm_clean_all_csi_mask_8822c(dm);
1588 phydm_csi_mask_enable_8822c(dm, false);
1589 }
1590 }
1591
1592 __odm_func__
phydm_set_dis_dpd_by_rate_8822c(struct dm_struct * dm,u16 bitmask)1593 void phydm_set_dis_dpd_by_rate_8822c(struct dm_struct *dm, u16 bitmask)
1594 {
1595 /* bit(0) : ofdm 6m*/
1596 /* bit(1) : ofdm 9m*/
1597 /* bit(2) : ht mcs0*/
1598 /* bit(3) : ht mcs1*/
1599 /* bit(4) : ht mcs8*/
1600 /* bit(5) : ht mcs9*/
1601 /* bit(6) : vht 1ss mcs0*/
1602 /* bit(7) : vht 1ss mcs1*/
1603 /* bit(8) : vht 2ss mcs0*/
1604 /* bit(9) : vht 2ss mcs1*/
1605
1606 odm_set_bb_reg(dm, R_0xa70, 0x3ff, bitmask);
1607 dm->dis_dpd_rate = bitmask;
1608 }
1609
1610 __odm_func__
1611 boolean
config_phydm_switch_channel_8822c(struct dm_struct * dm,u8 central_ch)1612 config_phydm_switch_channel_8822c(struct dm_struct *dm, u8 central_ch)
1613 {
1614 u32 rf_reg18 = 0;
1615 boolean is_2g_ch = true;
1616 enum bb_path tx_1sts = BB_PATH_NON;
1617 enum bb_path tx_2sts = BB_PATH_NON;
1618 enum bb_path tx = BB_PATH_NON;
1619 enum bb_path rx = BB_PATH_NON;
1620 u8 rfe_type = dm->rfe_type;
1621 struct phydm_iot_center *iot_table = &dm->iot_table;
1622
1623 PHYDM_DBG(dm, ODM_PHY_CONFIG, "%s ======>\n", __func__);
1624
1625 if (dm->is_disable_phy_api) {
1626 PHYDM_DBG(dm, ODM_PHY_CONFIG, "Disable PHY API\n");
1627 return true;
1628 }
1629
1630 if ((central_ch > 14 && central_ch < 36) ||
1631 (central_ch > 64 && central_ch < 100) ||
1632 (central_ch > 144 && central_ch < 149) ||
1633 central_ch > 177) {
1634 PHYDM_DBG(dm, ODM_PHY_CONFIG, "Error CH:%d\n", central_ch);
1635 return false;
1636 }
1637
1638 rf_reg18 = config_phydm_read_rf_reg_8822c(dm, RF_PATH_A, RF_0x18,
1639 RFREG_MASK);
1640 if (rf_reg18 == INVALID_RF_DATA) {
1641 PHYDM_DBG(dm, ODM_PHY_CONFIG, "Invalid RF_0x18\n");
1642 return false;
1643 }
1644
1645 is_2g_ch = (central_ch <= 14) ? true : false;
1646
1647 /* [get trx info for cck tx and rfe ctrl] */
1648 tx_1sts = dm->tx_1ss_status;
1649 if (tx_1sts == BB_PATH_NON) {
1650 tx_1sts = (u8)odm_get_bb_reg(dm, R_0x820, 0xf);
1651 dm->tx_1ss_status = (u8)tx_1sts;
1652 pr_debug("[%s]tx_1ss is non!, update tx_1sts:%d\n",
1653 __func__, tx_1sts);
1654 }
1655 tx = dm->tx_ant_status;
1656 if (tx == BB_PATH_NON) {
1657 tx_2sts = (u8)odm_get_bb_reg(dm, R_0x820, 0xf0);
1658 tx = (u8)(tx_1sts | tx_2sts);
1659 dm->tx_2ss_status = (u8)tx_2sts;
1660 dm->tx_ant_status = tx;
1661 pr_debug("[%s]tx_ant_status is non!, update tx_2sts/tx_path:%d/%d\n",
1662 __func__, tx_2sts, tx);
1663 }
1664 rx = dm->rx_ant_status;
1665 if (rx == BB_PATH_NON) {
1666 rx = (u8)odm_get_bb_reg(dm, R_0x824, 0xf0000);
1667 dm->rx_ant_status = (u8)rx;
1668 pr_debug("[%s]rx_ant_status is non!, update rx_path:%d\n",
1669 __func__, rx);
1670 }
1671
1672 /* ==== [Set RF Reg 0x18] ===========================================*/
1673 rf_reg18 &= ~0x703ff; /*[18:17],[16],[9:8],[7:0]*/
1674 rf_reg18 |= central_ch; /* Channel*/
1675
1676 if (!is_2g_ch) { /*5G*/
1677 rf_reg18 |= (BIT(16) | BIT(8));
1678
1679 /* 5G Sub-Band, 01: 5400<f<=5720, 10: f>5720*/
1680 if (central_ch > 144)
1681 rf_reg18 |= BIT(18);
1682 else if (central_ch >= 80)
1683 rf_reg18 |= BIT(17);
1684 }
1685
1686 /*reset HSSI*/
1687 phydm_rstb_3wire_8822c(dm, false);
1688 /*write RF-0x18*/
1689 odm_set_rf_reg(dm, RF_PATH_A, RF_0x18, RFREG_MASK, rf_reg18);
1690 odm_set_rf_reg(dm, RF_PATH_B, RF_0x18, RFREG_MASK, rf_reg18);
1691 /*RxA enhance-Q setting*/
1692 odm_set_rf_reg(dm, RF_PATH_A, RF_0xdf, BIT(18), is_2g_ch);
1693 /*reset HSSI*/
1694 phydm_rstb_3wire_8822c(dm, true);
1695 /* ==== [Set BB Reg] =================================================*/
1696 /* 1. AGC table selection */
1697 if (central_ch <= 14) {
1698 if (*dm->band_width == CHANNEL_WIDTH_20) {
1699 phydm_cck_agc_tab_sel_8822c(dm, CCK_BW20_8822C);
1700 phydm_ofdm_agc_tab_sel_8822c(dm, OFDM_2G_BW20_8822C);
1701 } else {
1702 phydm_cck_agc_tab_sel_8822c(dm, CCK_BW40_8822C);
1703 phydm_ofdm_agc_tab_sel_8822c(dm, OFDM_2G_BW40_8822C);
1704 }
1705 } else if (central_ch >= 36 && central_ch <= 64) {
1706 phydm_ofdm_agc_tab_sel_8822c(dm, OFDM_5G_LOW_BAND_8822C);
1707 } else if ((central_ch >= 100) && (central_ch <= 144)) {
1708 phydm_ofdm_agc_tab_sel_8822c(dm, OFDM_5G_MID_BAND_8822C);
1709 } else { /*if (central_ch >= 149)*/
1710 phydm_ofdm_agc_tab_sel_8822c(dm, OFDM_5G_HIGH_BAND_8822C);
1711 }
1712 /* 2. Set fc for clock offset tracking */
1713 phydm_sco_trk_fc_setting_8822c(dm, central_ch);
1714 /* 3. TX DFIR*/
1715 phydm_tx_dfir_setting_8822c(dm, central_ch);
1716 /* 4. Other BB Settings*/
1717 if (is_2g_ch) {
1718 phydm_cck_tx_shaping_filter_8822c(dm, central_ch);
1719 /* Enable CCK Rx IQ */
1720 phydm_cck_rxiq_8822c(dm, PHYDM_SET);
1721 /* Disable MAC CCK check */
1722 odm_set_mac_reg(dm, R_0x454, BIT(7), 0x0);
1723 /* Disable BB CCK check */
1724 odm_set_bb_reg(dm, R_0x1a80, BIT(18), 0x0);
1725 /* CCA Mask, default = 0xf */
1726 odm_set_bb_reg(dm, R_0x1c80, 0x3F000000, 0xF);
1727 /*RFE ctrl*/
1728 if (rfe_type == 21 || rfe_type == 22)
1729 phydm_rfe_8822c(dm, BB_PATH_NON);
1730 } else { /* 5G*/
1731 /* Enable BB CCK check */
1732 odm_set_bb_reg(dm, R_0x1a80, BIT(18), 0x1);
1733 /* Enable CCK check */
1734 odm_set_mac_reg(dm, R_0x454, BIT(7), 0x1);
1735 /* Disable CCK Rx IQ */
1736 phydm_cck_rxiq_8822c(dm, PHYDM_REVERT);
1737 /* CCA Mask */
1738 odm_set_bb_reg(dm, R_0x1c80, 0x3F000000, 0x22);
1739 /*RFE ctrl*/
1740 if (rfe_type == 21 || rfe_type == 22) {
1741 if (tx == BB_PATH_A && rx == BB_PATH_A)
1742 phydm_rfe_8822c(dm, BB_PATH_A);
1743 else if (tx == BB_PATH_B && rx == BB_PATH_B)
1744 phydm_rfe_8822c(dm, BB_PATH_B);
1745 else
1746 phydm_rfe_8822c(dm, BB_PATH_AB);
1747 }
1748 }
1749
1750 if (iot_table->patch_id_011f0500) {
1751 if (central_ch != 1 && dm->en_dis_dpd)
1752 phydm_set_dis_dpd_by_rate_8822c(dm, 0x3ff);
1753 else
1754 phydm_set_dis_dpd_by_rate_8822c(dm, 0x0);
1755 }
1756 /*====================================================================*/
1757 if (*dm->mp_mode)
1758 phydm_spur_eliminate_8822c(dm, central_ch);
1759
1760 phydm_bb_reset_8822c(dm);
1761
1762 phydm_igi_toggle_8822c(dm);
1763
1764 PHYDM_DBG(dm, ODM_PHY_CONFIG, "Switch CH:%d success\n", central_ch);
1765 return true;
1766 }
1767
1768 __odm_func__
1769 boolean
config_phydm_switch_bandwidth_8822c(struct dm_struct * dm,u8 pri_ch,enum channel_width bw)1770 config_phydm_switch_bandwidth_8822c(struct dm_struct *dm, u8 pri_ch,
1771 enum channel_width bw)
1772 {
1773 u32 rf_reg18 = 0;
1774 u32 rf_reg3f = 0;
1775 boolean rf_reg_status = true;
1776
1777 PHYDM_DBG(dm, ODM_PHY_CONFIG, "%s ======>\n", __func__);
1778
1779 if (dm->is_disable_phy_api) {
1780 PHYDM_DBG(dm, ODM_PHY_CONFIG, "Disable PHY API for debug!!\n");
1781 return true;
1782 }
1783
1784 /*Error handling */
1785 if (bw >= CHANNEL_WIDTH_MAX || (bw == CHANNEL_WIDTH_40 && pri_ch > 2) ||
1786 (bw == CHANNEL_WIDTH_80 && pri_ch > 4)) {
1787 PHYDM_DBG(dm, ODM_PHY_CONFIG,
1788 "Fail to switch bw(bw:%d, pri ch:%d)\n", bw, pri_ch);
1789 return false;
1790 }
1791
1792 rf_reg18 = config_phydm_read_rf_reg_8822c(dm, RF_PATH_A, RF_0x18,
1793 RFREG_MASK);
1794 if (rf_reg18 != INVALID_RF_DATA)
1795 rf_reg_status = true;
1796 else
1797 rf_reg_status = false;
1798
1799 rf_reg18 &= ~(BIT(13) | BIT(12));
1800
1801 /*Switch bandwidth */
1802 switch (bw) {
1803 case CHANNEL_WIDTH_5:
1804 case CHANNEL_WIDTH_10:
1805 case CHANNEL_WIDTH_20:
1806 if (bw == CHANNEL_WIDTH_5) {
1807 /*RX DFIR*/
1808 odm_set_bb_reg(dm, R_0x810, 0x3ff0, 0x2ab);
1809
1810 /*small BW:[7:6]=0x1 */
1811 /*TX pri ch:[11:8]=0x0, RX pri ch:[15:12]=0x0 */
1812 odm_set_bb_reg(dm, R_0x9b0, 0xffc0, 0x1);
1813
1814 /*DAC clock = 120M clock for BW5 */
1815 odm_set_bb_reg(dm, R_0x9b4, 0x00000700, 0x4);
1816
1817 /*ADC clock = 40M clock for BW5 */
1818 odm_set_bb_reg(dm, R_0x9b4, 0x00700000, 0x4);
1819
1820 /*Set nbi wa para*/
1821 if (dm->en_nbi_detect)
1822 phydm_set_nbi_wa_para_8822c(dm, false, bw);
1823 } else if (bw == CHANNEL_WIDTH_10) {
1824 /*RX DFIR*/
1825 odm_set_bb_reg(dm, R_0x810, 0x3ff0, 0x2ab);
1826
1827 /*small BW:[7:6]=0x2 */
1828 /*TX pri ch:[11:8]=0x0, RX pri ch:[15:12]=0x0 */
1829 odm_set_bb_reg(dm, R_0x9b0, 0xffc0, 0x2);
1830
1831 /*DAC clock = 240M clock for BW10 */
1832 odm_set_bb_reg(dm, R_0x9b4, 0x00000700, 0x6);
1833
1834 /*ADC clock = 80M clock for BW10 */
1835 odm_set_bb_reg(dm, R_0x9b4, 0x00700000, 0x5);
1836
1837 /*Set nbi wa para*/
1838 if (dm->en_nbi_detect)
1839 phydm_set_nbi_wa_para_8822c(dm, false, bw);
1840 } else if (bw == CHANNEL_WIDTH_20) {
1841 /*RX DFIR*/
1842 odm_set_bb_reg(dm, R_0x810, 0x3ff0, 0x19b);
1843
1844 /*small BW:[7:6]=0x0 */
1845 /*TX pri ch:[11:8]=0x0, RX pri ch:[15:12]=0x0 */
1846 odm_set_bb_reg(dm, R_0x9b0, 0xffc0, 0x0);
1847
1848 /*DAC clock = 480M clock for BW20 */
1849 odm_set_bb_reg(dm, R_0x9b4, 0x00000700, 0x7);
1850
1851 /*ADC clock = 160M clock for BW20 */
1852 odm_set_bb_reg(dm, R_0x9b4, 0x00700000, 0x6);
1853
1854 /*Set nbi wa para*/
1855 if (dm->en_nbi_detect)
1856 phydm_set_nbi_wa_para_8822c(dm, true, bw);
1857 }
1858
1859 /*TX_RF_BW:[1:0]=0x0, RX_RF_BW:[3:2]=0x0 */
1860 odm_set_bb_reg(dm, R_0x9b0, 0xf, 0x0);
1861
1862 /*RF bandwidth */
1863 rf_reg18 |= (BIT(13) | BIT(12));
1864
1865 /*RF RXBB setting*/
1866 rf_reg3f = (BIT(4) | BIT(3));
1867
1868 /*pilot smoothing on */
1869 odm_set_bb_reg(dm, R_0xcbc, BIT(21), 0x0);
1870
1871 /*CCK source 4 */
1872 odm_set_bb_reg(dm, R_0x1abc, BIT(30), 0x0);
1873
1874 /*dynamic CCK PD th*/
1875 odm_set_bb_reg(dm, R_0x1ae8, BIT(31), 0x1);
1876 odm_set_bb_reg(dm, R_0x1aec, 0xf, 0x6);
1877
1878 /*subtune*/
1879 odm_set_bb_reg(dm, R_0x88c, 0xf000, 0x1);
1880
1881 if (*dm->band_type == ODM_BAND_2_4G) {
1882 phydm_cck_agc_tab_sel_8822c(dm, CCK_BW20_8822C);
1883 phydm_ofdm_agc_tab_sel_8822c(dm, OFDM_2G_BW20_8822C);
1884 }
1885 break;
1886 case CHANNEL_WIDTH_40:
1887 /*CCK primary channel */
1888 if (pri_ch == 1)
1889 odm_set_bb_reg(dm, R_0x1a00, BIT(4), pri_ch);
1890 else
1891 odm_set_bb_reg(dm, R_0x1a00, BIT(4), 0);
1892
1893 /*TX_RF_BW:[1:0]=0x1, RX_RF_BW:[3:2]=0x1 */
1894 odm_set_bb_reg(dm, R_0x9b0, 0xf, 0x5);
1895
1896 /*small BW */
1897 odm_set_bb_reg(dm, R_0x9b0, 0xc0, 0x0);
1898
1899 /*TX pri ch:[11:8], RX pri ch:[15:12] */
1900 odm_set_bb_reg(dm, R_0x9b0, 0xff00, (pri_ch | (pri_ch << 4)));
1901
1902 /*RF bandwidth */
1903 rf_reg18 |= BIT(13);
1904
1905 /*RF RXBB setting*/
1906 rf_reg3f = BIT(4);
1907
1908 /*pilot smoothing off */
1909 odm_set_bb_reg(dm, R_0xcbc, BIT(21), 0x1);
1910
1911 /*CCK source 5 */
1912 odm_set_bb_reg(dm, R_0x1abc, BIT(30), 0x1);
1913
1914 /*dynamic CCK PD th*/
1915 odm_set_bb_reg(dm, R_0x1ae8, BIT(31), 0x0);
1916 odm_set_bb_reg(dm, R_0x1aec, 0xf, 0x8);
1917
1918 /*subtune*/
1919 odm_set_bb_reg(dm, R_0x88c, 0xf000, 0x1);
1920
1921 if (*dm->band_type == ODM_BAND_2_4G) {
1922 /*CCK*/
1923 phydm_cck_agc_tab_sel_8822c(dm, CCK_BW40_8822C);
1924 phydm_ofdm_agc_tab_sel_8822c(dm, OFDM_2G_BW40_8822C);
1925 }
1926
1927 /*Set nbi wa para*/
1928 if (dm->en_nbi_detect)
1929 phydm_set_nbi_wa_para_8822c(dm, true, bw);
1930 break;
1931 case CHANNEL_WIDTH_80:
1932 /*TX_RF_BW:[1:0]=0x2, RX_RF_BW:[3:2]=0x2 */
1933 odm_set_bb_reg(dm, R_0x9b0, 0xf, 0xa);
1934
1935 /*small BW */
1936 odm_set_bb_reg(dm, R_0x9b0, 0xc0, 0x0);
1937
1938 /*TX pri ch:[11:8], RX pri ch:[15:12] */
1939 odm_set_bb_reg(dm, R_0x9b0, 0xff00, (pri_ch | (pri_ch << 4)));
1940
1941 /*RF bandwidth */
1942 rf_reg18 |= BIT(12);
1943
1944 /*RF RXBB setting*/
1945 rf_reg3f = BIT(3);
1946
1947 /*pilot smoothing off */
1948 odm_set_bb_reg(dm, R_0xcbc, BIT(21), 0x1);
1949
1950 /*subtune*/
1951 odm_set_bb_reg(dm, R_0x88c, 0xf000, 0x6);
1952
1953 /*Set nbi wa para*/
1954 if (dm->en_nbi_detect)
1955 phydm_set_nbi_wa_para_8822c(dm, true, bw);
1956 break;
1957 default:
1958 PHYDM_DBG(dm, ODM_PHY_CONFIG,
1959 "Fail to switch bw (bw:%d, pri ch:%d)\n", bw, pri_ch);
1960 }
1961
1962 /*Write RF register */
1963 /*reset HSSI*/
1964 phydm_rstb_3wire_8822c(dm, false);
1965 /*RF RXBB setting, WLANBB-1081*/
1966 odm_set_rf_reg(dm, RF_PATH_A, RF_0xee, 0x4, 0x1);
1967 odm_set_rf_reg(dm, RF_PATH_A, RF_0x33, 0x1F, 0x12);
1968 odm_set_rf_reg(dm, RF_PATH_A, RF_0x3f, RFREG_MASK, rf_reg3f);
1969 odm_set_rf_reg(dm, RF_PATH_A, RF_0xee, 0x4, 0x0);
1970
1971 odm_set_rf_reg(dm, RF_PATH_B, RF_0xee, 0x4, 0x1);
1972 odm_set_rf_reg(dm, RF_PATH_B, RF_0x33, 0x1F, 0x12);
1973 odm_set_rf_reg(dm, RF_PATH_B, RF_0x3f, RFREG_MASK, rf_reg3f);
1974 odm_set_rf_reg(dm, RF_PATH_B, RF_0xee, 0x4, 0x0);
1975 /*write RF-0x18*/
1976 odm_set_rf_reg(dm, RF_PATH_A, RF_0x18, RFREG_MASK, rf_reg18);
1977 odm_set_rf_reg(dm, RF_PATH_B, RF_0x18, RFREG_MASK, rf_reg18);
1978 /*reset HSSI*/
1979 phydm_rstb_3wire_8822c(dm, true);
1980
1981 if (!rf_reg_status) {
1982 PHYDM_DBG(dm, ODM_PHY_CONFIG,
1983 "Fail to switch bw (bw:%d, primary ch:%d), because writing RF register is fail\n",
1984 bw, pri_ch);
1985 return false;
1986 }
1987
1988 /*fix bw setting*/
1989 #ifdef CONFIG_BW_INDICATION
1990 if (!(*dm->mp_mode))
1991 phydm_bw_fixed_setting(dm);
1992 #endif
1993
1994 PHYDM_DBG(dm, ODM_PHY_CONFIG,
1995 "Success to switch bw (bw:%d, pri ch:%d)\n", bw, pri_ch);
1996
1997 phydm_bb_reset_8822c(dm);
1998
1999 phydm_igi_toggle_8822c(dm);
2000
2001 return true;
2002 }
2003
2004 __odm_func__
2005 boolean
config_phydm_switch_channel_bw_8822c(struct dm_struct * dm,u8 central_ch,u8 primary_ch_idx,enum channel_width bandwidth)2006 config_phydm_switch_channel_bw_8822c(struct dm_struct *dm, u8 central_ch,
2007 u8 primary_ch_idx,
2008 enum channel_width bandwidth)
2009 {
2010 /* @Switch channel */
2011 if (!config_phydm_switch_channel_8822c(dm, central_ch))
2012 return false;
2013
2014 /* @Switch bandwidth */
2015 if (!config_phydm_switch_bandwidth_8822c(dm, primary_ch_idx, bandwidth))
2016 return false;
2017
2018 return true;
2019 }
2020
2021 __odm_func__
phydm_i_only_setting_8822c(struct dm_struct * dm,boolean en_i_only,boolean en_before_cca)2022 void phydm_i_only_setting_8822c(struct dm_struct *dm, boolean en_i_only,
2023 boolean en_before_cca)
2024 {
2025 if (en_i_only) { /*@ Set path-a*/
2026 if (en_before_cca) {
2027 odm_set_bb_reg(dm, R_0x1800, 0xfff00, 0x833);
2028 odm_set_bb_reg(dm, R_0x1c68, 0xc000, 0x2);
2029 odm_set_bb_reg(dm, R_0x1830, MASKDWORD, 0x70038001);
2030 } else {
2031 if (!(*dm->band_width == CHANNEL_WIDTH_40))
2032 return;
2033
2034 dm->bp_0x9b0 = odm_get_bb_reg(dm, R_0x9b0, MASKDWORD);
2035 odm_set_bb_reg(dm, R_0x1800, 0xfff00, 0x888);
2036 odm_set_bb_reg(dm, R_0x898, BIT(30), 0x1);
2037 odm_set_bb_reg(dm, R_0x1c68, 0xc000, 0x1);
2038 odm_set_bb_reg(dm, R_0x9b0, MASKDWORD, 0x2200);
2039 odm_set_bb_reg(dm, R_0x1830, MASKDWORD, 0x70038001);
2040 odm_set_bb_reg(dm, R_0x1830, MASKDWORD, 0x70038001);
2041 odm_set_bb_reg(dm, R_0x1830, MASKDWORD, 0x70538001);
2042 odm_set_bb_reg(dm, R_0x1830, MASKDWORD, 0x70738001);
2043 odm_set_bb_reg(dm, R_0x1830, MASKDWORD, 0x70838001);
2044 odm_set_bb_reg(dm, R_0x1830, MASKDWORD, 0x70938001);
2045 odm_set_bb_reg(dm, R_0x1830, MASKDWORD, 0x70a38001);
2046 odm_set_bb_reg(dm, R_0x1830, MASKDWORD, 0x70b38001);
2047 odm_set_bb_reg(dm, R_0x1830, MASKDWORD, 0x70c38001);
2048 odm_set_bb_reg(dm, R_0x1830, MASKDWORD, 0x70d38001);
2049 odm_set_bb_reg(dm, R_0x1830, MASKDWORD, 0x70e38001);
2050 odm_set_bb_reg(dm, R_0x1830, MASKDWORD, 0x70f38001);
2051 odm_set_bb_reg(dm, R_0x1830, MASKDWORD, 0x70f38001);
2052 }
2053 } else {
2054 if (en_before_cca) {
2055 odm_set_bb_reg(dm, R_0x1800, 0xfff00, 0x333);
2056 odm_set_bb_reg(dm, R_0x1c68, 0xc000, 0x0);
2057 odm_set_bb_reg(dm, R_0x1830, MASKDWORD, 0x700b8001);
2058 } else {
2059 if (!(*dm->band_width == CHANNEL_WIDTH_40))
2060 return;
2061
2062 odm_set_bb_reg(dm, R_0x1800, 0xfff00, 0x333);
2063 odm_set_bb_reg(dm, R_0x898, BIT(30), 0x0);
2064 odm_set_bb_reg(dm, R_0x1c68, 0xc000, 0x0);
2065 odm_set_bb_reg(dm, R_0x9b0, MASKDWORD, dm->bp_0x9b0);
2066 odm_set_bb_reg(dm, R_0x1830, MASKDWORD, 0x700b8001);
2067 odm_set_bb_reg(dm, R_0x1830, MASKDWORD, 0x700b8001);
2068 odm_set_bb_reg(dm, R_0x1830, MASKDWORD, 0x705b8001);
2069 odm_set_bb_reg(dm, R_0x1830, MASKDWORD, 0x707b8001);
2070 odm_set_bb_reg(dm, R_0x1830, MASKDWORD, 0x708b8001);
2071 odm_set_bb_reg(dm, R_0x1830, MASKDWORD, 0x709b8001);
2072 odm_set_bb_reg(dm, R_0x1830, MASKDWORD, 0x70ab8001);
2073 odm_set_bb_reg(dm, R_0x1830, MASKDWORD, 0x70bb8001);
2074 odm_set_bb_reg(dm, R_0x1830, MASKDWORD, 0x70cb8001);
2075 odm_set_bb_reg(dm, R_0x1830, MASKDWORD, 0x70db8001);
2076 odm_set_bb_reg(dm, R_0x1830, MASKDWORD, 0x70eb8001);
2077 odm_set_bb_reg(dm, R_0x1830, MASKDWORD, 0x70fb8001);
2078 odm_set_bb_reg(dm, R_0x1830, MASKDWORD, 0x70fb8001);
2079 }
2080 }
2081 }
2082
2083 __odm_func__
phydm_1rcca_setting_8822c(struct dm_struct * dm,boolean en_1rcca)2084 boolean phydm_1rcca_setting_8822c(struct dm_struct *dm, boolean en_1rcca)
2085 {
2086 enum bb_path ofdm_rx = BB_PATH_NON;
2087
2088 ofdm_rx = (u8)odm_get_bb_reg(dm, R_0x824, 0xf0000);
2089
2090 if (en_1rcca) { /*Set path-a*/
2091 if (ofdm_rx != BB_PATH_AB) {
2092 pr_debug("Do not set 1RCCA when rx config is not 2R!");
2093 return false;
2094 }
2095
2096 odm_set_bb_reg(dm, R_0x83c, BIT(2), 0x1);
2097 odm_set_bb_reg(dm, R_0x824, 0x0f000000, BB_PATH_A);
2098 odm_set_bb_reg(dm, R_0x4100, 0xf0000, 0x1);
2099 /*odm_set_bb_reg(dm, R_0x4130, MASKDWORD, 0x70008001);*/
2100 /* Select ant_A to receive CCK_1 and CCK_2*/
2101 odm_set_bb_reg(dm, R_0x1a04, 0x0f000000, 0x0);
2102 /* Disable MRC for CCK barker */
2103 odm_set_bb_reg(dm, R_0x1a2c, 0x00060000, 0x0);
2104 /* Disable MRC for CCK CCA */
2105 odm_set_bb_reg(dm, R_0x1a2c, 0x00600000, 0x0);
2106 } else {
2107 odm_set_bb_reg(dm, R_0x83c, BIT(2), 0x0);
2108 odm_set_bb_reg(dm, R_0x824, 0x0f000000, BB_PATH_AB);
2109 odm_set_bb_reg(dm, R_0x4100, 0xf0000, 0x3);
2110 /* odm_set_bb_reg(dm, R_0x4130, MASKDWORD, 0x700b8001); */
2111 /* Select ant_A to receive CCK_1 and ant_B to receive CCK_2*/
2112 odm_set_bb_reg(dm, R_0x1a04, 0x0f000000, 0x1);
2113 /* Enable MRC for CCK barker */
2114 odm_set_bb_reg(dm, R_0x1a2c, 0x00060000, 0x1);
2115 /* Enable MRC for CCK CCA */
2116 odm_set_bb_reg(dm, R_0x1a2c, 0x00600000, 0x1);
2117 }
2118
2119 return true;
2120 }
2121
2122 __odm_func__
phydm_invld_pkt_setting_8822c(struct dm_struct * dm,boolean en_invld_pkt)2123 void phydm_invld_pkt_setting_8822c(struct dm_struct *dm, boolean en_invld_pkt)
2124 {
2125 #if 0
2126 if (en_invld_pkt) {
2127 odm_set_bb_reg(dm, R_0x1c64, BIT(30), 0x1);
2128 odm_set_bb_reg(dm, R_0x1830, MASKDWORD, 0x70e0c001);
2129 odm_set_bb_reg(dm, R_0x4130, MASKDWORD, 0x70e0c001);
2130 } else {
2131 odm_set_bb_reg(dm, R_0x1c64, BIT(30), 0x0);
2132 odm_set_bb_reg(dm, R_0x1830, MASKDWORD, 0x70eb8001);
2133 odm_set_bb_reg(dm, R_0x4130, MASKDWORD, 0x70eb8001);
2134 }
2135 #endif
2136 if (en_invld_pkt) {
2137 odm_set_bb_reg(dm, R_0x1c64, BIT(30), 0x1);
2138 odm_set_bb_reg(dm, R_0x1cd8, BIT(28), 0x1);
2139 } else {
2140 odm_set_bb_reg(dm, R_0x1c64, BIT(30), 0x0);
2141 odm_set_bb_reg(dm, R_0x1cd8, BIT(28), 0x0);
2142 }
2143 }
2144
2145 __odm_func__
phydm_cck_gi_bound_8822c(struct dm_struct * dm)2146 void phydm_cck_gi_bound_8822c(struct dm_struct *dm)
2147 {
2148 struct phydm_physts *physts_table = &dm->dm_physts_table;
2149 u8 cck_gi_u_bnd_msb = 0;
2150 u8 cck_gi_u_bnd_lsb = 0;
2151 u8 cck_gi_l_bnd_msb = 0;
2152 u8 cck_gi_l_bnd_lsb = 0;
2153
2154 cck_gi_u_bnd_msb = (u8)odm_get_bb_reg(dm, R_0x1a98, 0xc000);
2155 cck_gi_u_bnd_lsb = (u8)odm_get_bb_reg(dm, R_0x1aa8, 0xf0000);
2156 cck_gi_l_bnd_msb = (u8)odm_get_bb_reg(dm, R_0x1a98, 0xc0);
2157 cck_gi_l_bnd_lsb = (u8)odm_get_bb_reg(dm, R_0x1a70, 0x0f000000);
2158
2159 physts_table->cck_gi_u_bnd = (u8)((cck_gi_u_bnd_msb << 4) |
2160 (cck_gi_u_bnd_lsb));
2161 physts_table->cck_gi_l_bnd = (u8)((cck_gi_l_bnd_msb << 4) |
2162 (cck_gi_l_bnd_lsb));
2163 }
2164
2165 __odm_func__
phydm_ch_smooth_setting_8822c(struct dm_struct * dm,boolean en_ch_smooth)2166 void phydm_ch_smooth_setting_8822c(struct dm_struct *dm, boolean en_ch_smooth)
2167 {
2168 if (en_ch_smooth)
2169 /* @enable force channel smoothing*/
2170 odm_set_bb_reg(dm, R_0xc54, BIT(7), 0x1);
2171 else
2172 odm_set_bb_reg(dm, R_0xc54, BIT(7), 0x0);
2173 }
2174
2175 __odm_func__
phydm_get_dis_dpd_by_rate_8822c(struct dm_struct * dm)2176 u16 phydm_get_dis_dpd_by_rate_8822c(struct dm_struct *dm)
2177 {
2178 u16 dis_dpd_rate = 0;
2179
2180 dis_dpd_rate = dm->dis_dpd_rate;
2181
2182 return dis_dpd_rate;
2183 }
2184
phydm_cck_pd_init_8822c(struct dm_struct * dm)2185 void phydm_cck_pd_init_8822c(struct dm_struct *dm)
2186 {
2187 #if (defined(CONFIG_RUN_IN_DRV))
2188 struct phydm_iot_center *iot_table = &dm->iot_table;
2189
2190 if (*dm->mp_mode && iot_table->patch_id_021f0800)
2191 /*CS ratio:BW20/1R*/
2192 odm_set_bb_reg(dm, R_0x1ad0, 0x1f, 0x12);
2193 #endif
2194 }
2195
2196 __odm_func__
2197 boolean
config_phydm_parameter_init_8822c(struct dm_struct * dm,enum odm_parameter_init type)2198 config_phydm_parameter_init_8822c(struct dm_struct *dm,
2199 enum odm_parameter_init type)
2200 {
2201 PHYDM_DBG(dm, ODM_PHY_CONFIG, "%s ======>\n", __func__);
2202
2203 phydm_cck_gi_bound_8822c(dm);
2204 phydm_cck_pd_init_8822c(dm);
2205
2206 if (*dm->mp_mode)
2207 phydm_ch_smooth_setting_8822c(dm, true);
2208 else if (dm->en_nbi_detect)
2209 phydm_set_auto_nbi_8822c(dm, true);
2210
2211 /* Disable low rate DPD*/
2212 if (dm->en_dis_dpd)
2213 phydm_set_dis_dpd_by_rate_8822c(dm, 0x3ff);
2214 else
2215 phydm_set_dis_dpd_by_rate_8822c(dm, 0x0);
2216
2217 /* @Do not use PHYDM API to read/write because FW can not access */
2218 /* @Turn on 3-wire*/
2219 odm_set_bb_reg(dm, R_0x180c, 0x3, 0x3);
2220 odm_set_bb_reg(dm, R_0x180c, BIT(28), 0x1);
2221 odm_set_bb_reg(dm, R_0x410c, 0x3, 0x3);
2222 odm_set_bb_reg(dm, R_0x410c, BIT(28), 0x1);
2223
2224 if (type == ODM_PRE_SETTING) {
2225 odm_set_bb_reg(dm, R_0x1c3c, (BIT(0) | BIT(1)), 0x0);
2226 PHYDM_DBG(dm, ODM_PHY_CONFIG,
2227 "Pre setting: disable OFDM and CCK block\n");
2228 } else if (type == ODM_POST_SETTING) {
2229 odm_set_bb_reg(dm, R_0x1c3c, (BIT(0) | BIT(1)), 0x3);
2230 PHYDM_DBG(dm, ODM_PHY_CONFIG,
2231 "Post setting: enable OFDM and CCK block\n");
2232 } else {
2233 PHYDM_DBG(dm, ODM_PHY_CONFIG, "Wrong type!!\n");
2234 return false;
2235 }
2236
2237 phydm_bb_reset_8822c(dm);
2238 #ifdef CONFIG_TXAGC_DEBUG_8822C
2239 /*phydm_txagc_tab_buff_init_8822c(dm);*/
2240 #endif
2241
2242 return true;
2243 }
2244
2245 __odm_func__
2246 boolean
phydm_chk_bb_state_idle_8822c(struct dm_struct * dm)2247 phydm_chk_bb_state_idle_8822c(struct dm_struct *dm)
2248 {
2249 u32 dbgport = 0;
2250
2251 /* Do not check GNT_WL for LPS */
2252 odm_set_bb_reg(dm, R_0x1c3c, 0x00f00000, 0x0);
2253 dbgport = odm_get_bb_reg(dm, R_0x2db4, MASKDWORD);
2254 if ((dbgport & 0x1ffeff3f) == 0 &&
2255 (dbgport & 0xc0000000) == 0xc0000000)
2256 return true;
2257 else
2258 return false;
2259 }
2260
2261 #if CONFIG_POWERSAVING
2262 __odm_func_aon__
2263 boolean
phydm_8822c_lps(struct dm_struct * dm,boolean enable_lps)2264 phydm_8822c_lps(struct dm_struct *dm, boolean enable_lps)
2265 {
2266 u16 poll_cnt = 0;
2267 u32 bbtemp = 0;
2268
2269 if (enable_lps == _TRUE) {
2270 /* backup RF reg0x0 */
2271 SysMib.Wlan.PS.PSParm.RxGainPathA = config_phydm_read_rf_reg_8822c(dm, RF_PATH_A, RF_0x0, RFREG_MASK);
2272 SysMib.Wlan.PS.PSParm.RxGainPathB = config_phydm_read_rf_reg_8822c(dm, RF_PATH_B, RF_0x0, RFREG_MASK);
2273
2274 /* turn off TRx HSSI*/
2275 odm_set_bb_reg(dm, R_0x180c, 0x3, 0x0);
2276 odm_set_bb_reg(dm, R_0x410c, 0x3, 0x0);
2277
2278 /* Set RF enter shutdown mode*/
2279 bbtemp = odm_get_bb_reg(dm, R_0x824, MASKDWORD);
2280 odm_set_bb_reg(dm, R_0x824, 0xf0000, 0x3);
2281 config_phydm_write_rf_reg_8822c(dm, RF_PATH_A, RF_0x0, RFREG_MASK, 0x0);
2282 config_phydm_write_rf_reg_8822c(dm, RF_PATH_B, RF_0x0, RFREG_MASK, 0x0);
2283 odm_set_bb_reg(dm, R_0x824, MASKDWORD, bbtemp);
2284
2285 /*bb reset w/o 3-wires */
2286 phydm_bb_reset_no_3wires_8822c(dm);
2287
2288 while (1) {
2289 if (phydm_chk_bb_state_idle_8822c(dm))
2290 break;
2291
2292 if (poll_cnt > WAIT_TXSM_STABLE_CNT) {
2293 WriteMACRegDWord(REG_DBG_DW_FW_ERR, ReadMACRegDWord(REG_DBG_DW_FW_ERR) | FES_BBSTATE_IDLE);
2294 /* SysMib.Wlan.DbgPort.DbgInfoParm.u4ErrFlag[0] |= FES_BBSTATE_IDLE; */
2295 return _FALSE;
2296 }
2297
2298 DelayUS(WAIT_TXSM_STABLE_ONCE_TIME);
2299 poll_cnt++;
2300 }
2301
2302 /*When BB reset = 0, enter shutdown mode*/
2303 odm_set_bb_reg(dm, R_0x1c64, BIT(3), 0x0);
2304
2305 /* disable CCK and OFDM module */
2306 WriteMACRegByte(REG_SYS_FUNC_EN, ReadMACRegByte(REG_SYS_FUNC_EN)
2307 & ~BIT_FEN_BBRSTB);
2308
2309 /* Gated BBclk*/
2310 odm_set_bb_reg(dm, R_0x1c24, BIT(0), 0x1);
2311
2312 return _TRUE;
2313 } else {
2314 /* release BB clk*/
2315 odm_set_bb_reg(dm, R_0x1c24, BIT(0), 0x0);
2316
2317 PsRestoreBB8822C();
2318
2319 /* Enable CCK and OFDM module, */
2320 /* should be a delay large than 200ns before RF access */
2321 WriteMACRegByte(REG_SYS_FUNC_EN, ReadMACRegByte(REG_SYS_FUNC_EN)
2322 | BIT_FEN_BBRSTB);
2323 DelayUS(1);
2324
2325 /*When BB reset = 0, enter standby mode*/
2326 odm_set_bb_reg(dm, R_0x1c64, BIT(3), 0x1);
2327
2328 /* Set RF enter active mode */
2329 bbtemp = odm_get_bb_reg(dm, R_0x824, MASKDWORD);
2330 odm_set_bb_reg(dm, R_0x824, 0xf0000, 0x3);
2331 config_phydm_write_rf_reg_8822c(dm, RF_PATH_A, RF_0x0, RFREG_MASK, SysMib.Wlan.PS.PSParm.RxGainPathA);
2332 config_phydm_write_rf_reg_8822c(dm, RF_PATH_B, RF_0x0, RFREG_MASK, SysMib.Wlan.PS.PSParm.RxGainPathB);
2333 odm_set_bb_reg(dm, R_0x824, MASKDWORD, bbtemp);
2334
2335 /*bb reset */
2336 phydm_bb_reset_8822c(dm);
2337
2338 /* turn on TRx HSSI*/
2339 odm_set_bb_reg(dm, R_0x180c, 0x3, 0x3);
2340 odm_set_bb_reg(dm, R_0x410c, 0x3, 0x3);
2341
2342 /*sdm reset for rf shutdown mode spur issue*/
2343 phydm_sdm_reset_8822c(dm);
2344
2345 return _TRUE;
2346 }
2347 }
2348 #endif /* #if CONFIG_POWERSAVING */
2349
2350 /* ======================================================================== */
2351 #endif /* PHYDM_FW_API_ENABLE_8822C */
2352 #endif /* RTL8822C_SUPPORT */
2353