rtlwifi: Add missing newlines to RT_TRACE calls
[deliverable/linux.git] / drivers / net / wireless / realtek / rtlwifi / rtl8821ae / phy.c
CommitLineData
21e4b072
LF
1/******************************************************************************
2 *
3 * Copyright(c) 2009-2010 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
26#include "../wifi.h"
27#include "../pci.h"
28#include "../ps.h"
29#include "reg.h"
30#include "def.h"
31#include "phy.h"
32#include "rf.h"
33#include "dm.h"
34#include "table.h"
35#include "trx.h"
36#include "../btcoexist/halbt_precomp.h"
37#include "hw.h"
38#include "../efuse.h"
39
40#define READ_NEXT_PAIR(array_table, v1, v2, i) \
41 do { \
42 i += 2; \
43 v1 = array_table[i]; \
44 v2 = array_table[i+1]; \
45 } while (0)
46
47static u32 _rtl8821ae_phy_rf_serial_read(struct ieee80211_hw *hw,
48 enum radio_path rfpath, u32 offset);
49static void _rtl8821ae_phy_rf_serial_write(struct ieee80211_hw *hw,
50 enum radio_path rfpath, u32 offset,
51 u32 data);
52static u32 _rtl8821ae_phy_calculate_bit_shift(u32 bitmask);
53static bool _rtl8821ae_phy_bb8821a_config_parafile(struct ieee80211_hw *hw);
54/*static bool _rtl8812ae_phy_config_mac_with_headerfile(struct ieee80211_hw *hw);*/
55static bool _rtl8821ae_phy_config_mac_with_headerfile(struct ieee80211_hw *hw);
56static bool _rtl8821ae_phy_config_bb_with_headerfile(struct ieee80211_hw *hw,
57 u8 configtype);
58static bool _rtl8821ae_phy_config_bb_with_pgheaderfile(struct ieee80211_hw *hw,
59 u8 configtype);
60static void phy_init_bb_rf_register_definition(struct ieee80211_hw *hw);
61
62static long _rtl8821ae_phy_txpwr_idx_to_dbm(struct ieee80211_hw *hw,
63 enum wireless_mode wirelessmode,
64 u8 txpwridx);
65static void rtl8821ae_phy_set_rf_on(struct ieee80211_hw *hw);
66static void rtl8821ae_phy_set_io(struct ieee80211_hw *hw);
67
68static void rtl8812ae_fixspur(struct ieee80211_hw *hw,
69 enum ht_channel_width band_width, u8 channel)
70{
71 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
72
73 /*C cut Item12 ADC FIFO CLOCK*/
74 if (IS_VENDOR_8812A_C_CUT(rtlhal->version)) {
75 if (band_width == HT_CHANNEL_WIDTH_20_40 && channel == 11)
76 rtl_set_bbreg(hw, RRFMOD, 0xC00, 0x3);
77 /* 0x8AC[11:10] = 2'b11*/
78 else
79 rtl_set_bbreg(hw, RRFMOD, 0xC00, 0x2);
80 /* 0x8AC[11:10] = 2'b10*/
81
82 /* <20120914, Kordan> A workarould to resolve
83 * 2480Mhz spur by setting ADC clock as 160M. (Asked by Binson)
84 */
85 if (band_width == HT_CHANNEL_WIDTH_20 &&
86 (channel == 13 || channel == 14)) {
87 rtl_set_bbreg(hw, RRFMOD, 0x300, 0x3);
88 /*0x8AC[9:8] = 2'b11*/
89 rtl_set_bbreg(hw, RADC_BUF_CLK, BIT(30), 1);
90 /* 0x8C4[30] = 1*/
91 } else if (band_width == HT_CHANNEL_WIDTH_20_40 &&
92 channel == 11) {
93 rtl_set_bbreg(hw, RADC_BUF_CLK, BIT(30), 1);
94 /*0x8C4[30] = 1*/
95 } else if (band_width != HT_CHANNEL_WIDTH_80) {
96 rtl_set_bbreg(hw, RRFMOD, 0x300, 0x2);
97 /*0x8AC[9:8] = 2'b10*/
98 rtl_set_bbreg(hw, RADC_BUF_CLK, BIT(30), 0);
99 /*0x8C4[30] = 0*/
100 }
101 } else if (rtlhal->hw_type == HARDWARE_TYPE_RTL8812AE) {
102 /* <20120914, Kordan> A workarould to resolve
103 * 2480Mhz spur by setting ADC clock as 160M.
104 */
105 if (band_width == HT_CHANNEL_WIDTH_20 &&
106 (channel == 13 || channel == 14))
107 rtl_set_bbreg(hw, RRFMOD, 0x300, 0x3);
108 /*0x8AC[9:8] = 11*/
109 else if (channel <= 14) /*2.4G only*/
110 rtl_set_bbreg(hw, RRFMOD, 0x300, 0x2);
111 /*0x8AC[9:8] = 10*/
112 }
113}
114
115u32 rtl8821ae_phy_query_bb_reg(struct ieee80211_hw *hw, u32 regaddr,
116 u32 bitmask)
117{
118 struct rtl_priv *rtlpriv = rtl_priv(hw);
119 u32 returnvalue, originalvalue, bitshift;
120
121 RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE,
122 "regaddr(%#x), bitmask(%#x)\n",
123 regaddr, bitmask);
124 originalvalue = rtl_read_dword(rtlpriv, regaddr);
125 bitshift = _rtl8821ae_phy_calculate_bit_shift(bitmask);
126 returnvalue = (originalvalue & bitmask) >> bitshift;
127
128 RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE,
129 "BBR MASK=0x%x Addr[0x%x]=0x%x\n",
130 bitmask, regaddr, originalvalue);
131 return returnvalue;
132}
133
134void rtl8821ae_phy_set_bb_reg(struct ieee80211_hw *hw,
135 u32 regaddr, u32 bitmask, u32 data)
136{
137 struct rtl_priv *rtlpriv = rtl_priv(hw);
138 u32 originalvalue, bitshift;
139
140 RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE,
141 "regaddr(%#x), bitmask(%#x), data(%#x)\n",
142 regaddr, bitmask, data);
143
144 if (bitmask != MASKDWORD) {
145 originalvalue = rtl_read_dword(rtlpriv, regaddr);
146 bitshift = _rtl8821ae_phy_calculate_bit_shift(bitmask);
147 data = ((originalvalue & (~bitmask)) |
148 ((data << bitshift) & bitmask));
149 }
150
151 rtl_write_dword(rtlpriv, regaddr, data);
152
153 RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE,
154 "regaddr(%#x), bitmask(%#x), data(%#x)\n",
155 regaddr, bitmask, data);
156}
157
158u32 rtl8821ae_phy_query_rf_reg(struct ieee80211_hw *hw,
159 enum radio_path rfpath, u32 regaddr,
160 u32 bitmask)
161{
162 struct rtl_priv *rtlpriv = rtl_priv(hw);
163 u32 original_value, readback_value, bitshift;
164 unsigned long flags;
165
166 RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE,
167 "regaddr(%#x), rfpath(%#x), bitmask(%#x)\n",
168 regaddr, rfpath, bitmask);
169
170 spin_lock_irqsave(&rtlpriv->locks.rf_lock, flags);
171
172 original_value = _rtl8821ae_phy_rf_serial_read(hw, rfpath, regaddr);
173 bitshift = _rtl8821ae_phy_calculate_bit_shift(bitmask);
174 readback_value = (original_value & bitmask) >> bitshift;
175
176 spin_unlock_irqrestore(&rtlpriv->locks.rf_lock, flags);
177
178 RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE,
179 "regaddr(%#x), rfpath(%#x), bitmask(%#x), original_value(%#x)\n",
180 regaddr, rfpath, bitmask, original_value);
181
182 return readback_value;
183}
184
185void rtl8821ae_phy_set_rf_reg(struct ieee80211_hw *hw,
186 enum radio_path rfpath,
187 u32 regaddr, u32 bitmask, u32 data)
188{
189 struct rtl_priv *rtlpriv = rtl_priv(hw);
190 u32 original_value, bitshift;
191 unsigned long flags;
192
193 RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE,
194 "regaddr(%#x), bitmask(%#x), data(%#x), rfpath(%#x)\n",
195 regaddr, bitmask, data, rfpath);
196
197 spin_lock_irqsave(&rtlpriv->locks.rf_lock, flags);
198
199 if (bitmask != RFREG_OFFSET_MASK) {
200 original_value =
201 _rtl8821ae_phy_rf_serial_read(hw, rfpath, regaddr);
202 bitshift = _rtl8821ae_phy_calculate_bit_shift(bitmask);
203 data = ((original_value & (~bitmask)) | (data << bitshift));
204 }
205
206 _rtl8821ae_phy_rf_serial_write(hw, rfpath, regaddr, data);
207
208 spin_unlock_irqrestore(&rtlpriv->locks.rf_lock, flags);
209
210 RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE,
211 "regaddr(%#x), bitmask(%#x), data(%#x), rfpath(%#x)\n",
212 regaddr, bitmask, data, rfpath);
213}
214
215static u32 _rtl8821ae_phy_rf_serial_read(struct ieee80211_hw *hw,
216 enum radio_path rfpath, u32 offset)
217{
218 struct rtl_priv *rtlpriv = rtl_priv(hw);
219 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
220 bool is_pi_mode = false;
221 u32 retvalue = 0;
222
223 /* 2009/06/17 MH We can not execute IO for power
224 save or other accident mode.*/
225 if (RT_CANNOT_IO(hw)) {
226 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, "return all one\n");
227 return 0xFFFFFFFF;
228 }
229 /* <20120809, Kordan> CCA OFF(when entering),
230 asked by James to avoid reading the wrong value.
231 <20120828, Kordan> Toggling CCA would affect RF 0x0, skip it!*/
232 if (offset != 0x0 &&
233 !((rtlhal->hw_type == HARDWARE_TYPE_RTL8821AE) ||
234 (IS_VENDOR_8812A_C_CUT(rtlhal->version))))
235 rtl_set_bbreg(hw, RCCAONSEC, 0x8, 1);
236 offset &= 0xff;
237
238 if (rfpath == RF90_PATH_A)
239 is_pi_mode = (bool)rtl_get_bbreg(hw, 0xC00, 0x4);
240 else if (rfpath == RF90_PATH_B)
241 is_pi_mode = (bool)rtl_get_bbreg(hw, 0xE00, 0x4);
242
243 rtl_set_bbreg(hw, RHSSIREAD_8821AE, 0xff, offset);
244
245 if ((rtlhal->hw_type == HARDWARE_TYPE_RTL8821AE) ||
246 (IS_VENDOR_8812A_C_CUT(rtlhal->version)))
247 udelay(20);
248
249 if (is_pi_mode) {
250 if (rfpath == RF90_PATH_A)
251 retvalue =
252 rtl_get_bbreg(hw, RA_PIREAD_8821A, BLSSIREADBACKDATA);
253 else if (rfpath == RF90_PATH_B)
254 retvalue =
255 rtl_get_bbreg(hw, RB_PIREAD_8821A, BLSSIREADBACKDATA);
256 } else {
257 if (rfpath == RF90_PATH_A)
258 retvalue =
259 rtl_get_bbreg(hw, RA_SIREAD_8821A, BLSSIREADBACKDATA);
260 else if (rfpath == RF90_PATH_B)
261 retvalue =
262 rtl_get_bbreg(hw, RB_SIREAD_8821A, BLSSIREADBACKDATA);
263 }
264
265 /*<20120809, Kordan> CCA ON(when exiting),
266 * asked by James to avoid reading the wrong value.
267 * <20120828, Kordan> Toggling CCA would affect RF 0x0, skip it!
268 */
269 if (offset != 0x0 &&
270 !((rtlhal->hw_type == HARDWARE_TYPE_RTL8821AE) ||
271 (IS_VENDOR_8812A_C_CUT(rtlhal->version))))
272 rtl_set_bbreg(hw, RCCAONSEC, 0x8, 0);
273 return retvalue;
274}
275
276static void _rtl8821ae_phy_rf_serial_write(struct ieee80211_hw *hw,
277 enum radio_path rfpath, u32 offset,
278 u32 data)
279{
280 struct rtl_priv *rtlpriv = rtl_priv(hw);
281 struct rtl_phy *rtlphy = &rtlpriv->phy;
282 struct bb_reg_def *pphyreg = &rtlphy->phyreg_def[rfpath];
283 u32 data_and_addr;
284 u32 newoffset;
285
286 if (RT_CANNOT_IO(hw)) {
287 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, "stop\n");
288 return;
289 }
290 offset &= 0xff;
291 newoffset = offset;
292 data_and_addr = ((newoffset << 20) |
293 (data & 0x000fffff)) & 0x0fffffff;
294 rtl_set_bbreg(hw, pphyreg->rf3wire_offset, MASKDWORD, data_and_addr);
295 RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE,
296 "RFW-%d Addr[0x%x]=0x%x\n",
297 rfpath, pphyreg->rf3wire_offset, data_and_addr);
298}
299
300static u32 _rtl8821ae_phy_calculate_bit_shift(u32 bitmask)
301{
302 u32 i;
303
304 for (i = 0; i <= 31; i++) {
305 if (((bitmask >> i) & 0x1) == 1)
306 break;
307 }
308 return i;
309}
310
311bool rtl8821ae_phy_mac_config(struct ieee80211_hw *hw)
312{
313 bool rtstatus = 0;
314
315 rtstatus = _rtl8821ae_phy_config_mac_with_headerfile(hw);
316
317 return rtstatus;
318}
319
320bool rtl8821ae_phy_bb_config(struct ieee80211_hw *hw)
321{
322 bool rtstatus = true;
323 struct rtl_priv *rtlpriv = rtl_priv(hw);
324 struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
325 struct rtl_phy *rtlphy = &rtlpriv->phy;
326 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
327 u8 regval;
328 u8 crystal_cap;
329
330 phy_init_bb_rf_register_definition(hw);
331
332 regval = rtl_read_byte(rtlpriv, REG_SYS_FUNC_EN);
333 regval |= FEN_PCIEA;
334 rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, regval);
335 rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN,
336 regval | FEN_BB_GLB_RSTN | FEN_BBRSTB);
337
338 rtl_write_byte(rtlpriv, REG_RF_CTRL, 0x7);
339 rtl_write_byte(rtlpriv, REG_OPT_CTRL + 2, 0x7);
340
341 rtstatus = _rtl8821ae_phy_bb8821a_config_parafile(hw);
342
343 if (rtlhal->hw_type == HARDWARE_TYPE_RTL8812AE) {
344 crystal_cap = rtlefuse->crystalcap & 0x3F;
345 rtl_set_bbreg(hw, REG_MAC_PHY_CTRL, 0x7FF80000,
346 (crystal_cap | (crystal_cap << 6)));
347 } else {
348 crystal_cap = rtlefuse->crystalcap & 0x3F;
349 rtl_set_bbreg(hw, REG_MAC_PHY_CTRL, 0xFFF000,
350 (crystal_cap | (crystal_cap << 6)));
351 }
352 rtlphy->reg_837 = rtl_read_byte(rtlpriv, 0x837);
353
354 return rtstatus;
355}
356
357bool rtl8821ae_phy_rf_config(struct ieee80211_hw *hw)
358{
359 return rtl8821ae_phy_rf6052_config(hw);
360}
361
362u32 phy_get_tx_swing_8812A(struct ieee80211_hw *hw, u8 band,
363 u8 rf_path)
364{
365 struct rtl_priv *rtlpriv = rtl_priv(hw);
366 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
367 struct rtl_dm *rtldm = rtl_dm(rtlpriv);
368 struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
08aba42f
AB
369 s8 reg_swing_2g = -1;/* 0xff; */
370 s8 reg_swing_5g = -1;/* 0xff; */
371 s8 swing_2g = -1 * reg_swing_2g;
372 s8 swing_5g = -1 * reg_swing_5g;
21e4b072 373 u32 out = 0x200;
08aba42f 374 const s8 auto_temp = -1;
21e4b072
LF
375
376 RT_TRACE(rtlpriv, COMP_SCAN, DBG_LOUD,
377 "===> PHY_GetTxBBSwing_8812A, bbSwing_2G: %d, bbSwing_5G: %d,autoload_failflag=%d.\n",
378 (int)swing_2g, (int)swing_5g,
379 (int)rtlefuse->autoload_failflag);
380
381 if (rtlefuse->autoload_failflag) {
382 if (band == BAND_ON_2_4G) {
383 rtldm->swing_diff_2g = swing_2g;
384 if (swing_2g == 0) {
385 out = 0x200; /* 0 dB */
386 } else if (swing_2g == -3) {
387 out = 0x16A; /* -3 dB */
388 } else if (swing_2g == -6) {
389 out = 0x101; /* -6 dB */
390 } else if (swing_2g == -9) {
391 out = 0x0B6; /* -9 dB */
392 } else {
393 rtldm->swing_diff_2g = 0;
394 out = 0x200;
395 }
396 } else if (band == BAND_ON_5G) {
397 rtldm->swing_diff_5g = swing_5g;
398 if (swing_5g == 0) {
399 out = 0x200; /* 0 dB */
400 } else if (swing_5g == -3) {
401 out = 0x16A; /* -3 dB */
402 } else if (swing_5g == -6) {
403 out = 0x101; /* -6 dB */
404 } else if (swing_5g == -9) {
405 out = 0x0B6; /* -9 dB */
406 } else {
407 if (rtlhal->hw_type == HARDWARE_TYPE_RTL8821AE) {
408 rtldm->swing_diff_5g = -3;
409 out = 0x16A;
410 } else {
411 rtldm->swing_diff_5g = 0;
412 out = 0x200;
413 }
414 }
415 } else {
416 rtldm->swing_diff_2g = -3;
417 rtldm->swing_diff_5g = -3;
418 out = 0x16A; /* -3 dB */
419 }
420 } else {
1e812458 421 u32 swing = 0, swing_a = 0, swing_b = 0;
21e4b072 422
1e812458 423 if (band == BAND_ON_2_4G) {
21e4b072
LF
424 if (reg_swing_2g == auto_temp) {
425 efuse_shadow_read(hw, 1, 0xC6, (u32 *)&swing);
426 swing = (swing == 0xFF) ? 0x00 : swing;
427 } else if (swing_2g == 0) {
428 swing = 0x00; /* 0 dB */
429 } else if (swing_2g == -3) {
430 swing = 0x05; /* -3 dB */
431 } else if (swing_2g == -6) {
432 swing = 0x0A; /* -6 dB */
433 } else if (swing_2g == -9) {
434 swing = 0xFF; /* -9 dB */
435 } else {
436 swing = 0x00;
437 }
438 } else {
439 if (reg_swing_5g == auto_temp) {
440 efuse_shadow_read(hw, 1, 0xC7, (u32 *)&swing);
441 swing = (swing == 0xFF) ? 0x00 : swing;
442 } else if (swing_5g == 0) {
443 swing = 0x00; /* 0 dB */
444 } else if (swing_5g == -3) {
445 swing = 0x05; /* -3 dB */
446 } else if (swing_5g == -6) {
447 swing = 0x0A; /* -6 dB */
448 } else if (swing_5g == -9) {
449 swing = 0xFF; /* -9 dB */
450 } else {
451 swing = 0x00;
452 }
453 }
454
455 swing_a = (swing & 0x3) >> 0; /* 0xC6/C7[1:0] */
456 swing_b = (swing & 0xC) >> 2; /* 0xC6/C7[3:2] */
457 RT_TRACE(rtlpriv, COMP_SCAN, DBG_LOUD,
458 "===> PHY_GetTxBBSwing_8812A, swingA: 0x%X, swingB: 0x%X\n",
459 swing_a, swing_b);
460
461 /* 3 Path-A */
462 if (swing_a == 0x0) {
463 if (band == BAND_ON_2_4G)
464 rtldm->swing_diff_2g = 0;
465 else
466 rtldm->swing_diff_5g = 0;
467 out = 0x200; /* 0 dB */
468 } else if (swing_a == 0x1) {
469 if (band == BAND_ON_2_4G)
470 rtldm->swing_diff_2g = -3;
471 else
472 rtldm->swing_diff_5g = -3;
473 out = 0x16A; /* -3 dB */
474 } else if (swing_a == 0x2) {
475 if (band == BAND_ON_2_4G)
476 rtldm->swing_diff_2g = -6;
477 else
478 rtldm->swing_diff_5g = -6;
479 out = 0x101; /* -6 dB */
480 } else if (swing_a == 0x3) {
481 if (band == BAND_ON_2_4G)
482 rtldm->swing_diff_2g = -9;
483 else
484 rtldm->swing_diff_5g = -9;
485 out = 0x0B6; /* -9 dB */
486 }
487 /* 3 Path-B */
488 if (swing_b == 0x0) {
489 if (band == BAND_ON_2_4G)
490 rtldm->swing_diff_2g = 0;
491 else
492 rtldm->swing_diff_5g = 0;
493 out = 0x200; /* 0 dB */
494 } else if (swing_b == 0x1) {
495 if (band == BAND_ON_2_4G)
496 rtldm->swing_diff_2g = -3;
497 else
498 rtldm->swing_diff_5g = -3;
499 out = 0x16A; /* -3 dB */
500 } else if (swing_b == 0x2) {
501 if (band == BAND_ON_2_4G)
502 rtldm->swing_diff_2g = -6;
503 else
504 rtldm->swing_diff_5g = -6;
505 out = 0x101; /* -6 dB */
506 } else if (swing_b == 0x3) {
507 if (band == BAND_ON_2_4G)
508 rtldm->swing_diff_2g = -9;
509 else
510 rtldm->swing_diff_5g = -9;
511 out = 0x0B6; /* -9 dB */
512 }
513 }
514
515 RT_TRACE(rtlpriv, COMP_SCAN, DBG_LOUD,
516 "<=== PHY_GetTxBBSwing_8812A, out = 0x%X\n", out);
1e812458 517 return out;
21e4b072
LF
518}
519
520void rtl8821ae_phy_switch_wirelessband(struct ieee80211_hw *hw, u8 band)
521{
522 struct rtl_priv *rtlpriv = rtl_priv(hw);
523 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
524 struct rtl_dm *rtldm = rtl_dm(rtlpriv);
525 u8 current_band = rtlhal->current_bandtype;
526 u32 txpath, rxpath;
08aba42f 527 s8 bb_diff_between_band;
21e4b072
LF
528
529 txpath = rtl8821ae_phy_query_bb_reg(hw, RTXPATH, 0xf0);
530 rxpath = rtl8821ae_phy_query_bb_reg(hw, RCCK_RX, 0x0f000000);
531 rtlhal->current_bandtype = (enum band_type) band;
532 /* reconfig BB/RF according to wireless mode */
533 if (rtlhal->current_bandtype == BAND_ON_2_4G) {
534 /* BB & RF Config */
535 rtl_set_bbreg(hw, ROFDMCCKEN, BOFDMEN|BCCKEN, 0x03);
536
537 if (rtlhal->hw_type == HARDWARE_TYPE_RTL8821AE) {
538 /* 0xCB0[15:12] = 0x7 (LNA_On)*/
539 rtl_set_bbreg(hw, RA_RFE_PINMUX, 0xF000, 0x7);
540 /* 0xCB0[7:4] = 0x7 (PAPE_A)*/
541 rtl_set_bbreg(hw, RA_RFE_PINMUX, 0xF0, 0x7);
542 }
543
544 if (rtlhal->hw_type == HARDWARE_TYPE_RTL8812AE) {
545 /*0x834[1:0] = 0x1*/
546 rtl_set_bbreg(hw, 0x834, 0x3, 0x1);
547 }
548
549 if (rtlhal->hw_type == HARDWARE_TYPE_RTL8821AE) {
550 /* 0xC1C[11:8] = 0 */
551 rtl_set_bbreg(hw, RA_TXSCALE, 0xF00, 0);
552 } else {
553 /* 0x82C[1:0] = 2b'00 */
554 rtl_set_bbreg(hw, 0x82c, 0x3, 0);
555 }
556 if (rtlhal->hw_type == HARDWARE_TYPE_RTL8812AE) {
557 rtl_set_bbreg(hw, RA_RFE_PINMUX, BMASKDWORD,
558 0x77777777);
559 rtl_set_bbreg(hw, RB_RFE_PINMUX, BMASKDWORD,
560 0x77777777);
561 rtl_set_bbreg(hw, RA_RFE_INV, 0x3ff00000, 0x000);
562 rtl_set_bbreg(hw, RB_RFE_INV, 0x3ff00000, 0x000);
563 }
564
565 rtl_set_bbreg(hw, RTXPATH, 0xf0, 0x1);
566 rtl_set_bbreg(hw, RCCK_RX, 0x0f000000, 0x1);
567
568 rtl_write_byte(rtlpriv, REG_CCK_CHECK, 0x0);
569 } else {/* 5G band */
570 u16 count, reg_41a;
571
572 if (rtlhal->hw_type == HARDWARE_TYPE_RTL8821AE) {
573 /*0xCB0[15:12] = 0x5 (LNA_On)*/
574 rtl_set_bbreg(hw, RA_RFE_PINMUX, 0xF000, 0x5);
575 /*0xCB0[7:4] = 0x4 (PAPE_A)*/
576 rtl_set_bbreg(hw, RA_RFE_PINMUX, 0xF0, 0x4);
577 }
578 /*CCK_CHECK_en*/
579 rtl_write_byte(rtlpriv, REG_CCK_CHECK, 0x80);
580
581 count = 0;
582 reg_41a = rtl_read_word(rtlpriv, REG_TXPKT_EMPTY);
583 RT_TRACE(rtlpriv, COMP_SCAN, DBG_LOUD,
4713bd1c 584 "Reg41A value %d\n", reg_41a);
21e4b072
LF
585 reg_41a &= 0x30;
586 while ((reg_41a != 0x30) && (count < 50)) {
587 udelay(50);
588 RT_TRACE(rtlpriv, COMP_SCAN, DBG_LOUD, "Delay 50us\n");
589
590 reg_41a = rtl_read_word(rtlpriv, REG_TXPKT_EMPTY);
591 reg_41a &= 0x30;
592 count++;
593 RT_TRACE(rtlpriv, COMP_SCAN, DBG_LOUD,
4713bd1c 594 "Reg41A value %d\n", reg_41a);
21e4b072
LF
595 }
596 if (count != 0)
597 RT_TRACE(rtlpriv, COMP_MLME, DBG_LOUD,
598 "PHY_SwitchWirelessBand8812(): Switch to 5G Band. Count = %d reg41A=0x%x\n",
599 count, reg_41a);
600
601 /* 2012/02/01, Sinda add registry to switch workaround
602 without long-run verification for scan issue. */
603 rtl_set_bbreg(hw, ROFDMCCKEN, BOFDMEN|BCCKEN, 0x03);
604
605 if (rtlhal->hw_type == HARDWARE_TYPE_RTL8812AE) {
606 /*0x834[1:0] = 0x2*/
607 rtl_set_bbreg(hw, 0x834, 0x3, 0x2);
608 }
609
610 if (rtlhal->hw_type == HARDWARE_TYPE_RTL8821AE) {
611 /* AGC table select */
612 /* 0xC1C[11:8] = 1*/
613 rtl_set_bbreg(hw, RA_TXSCALE, 0xF00, 1);
614 } else
615 /* 0x82C[1:0] = 2'b00 */
616 rtl_set_bbreg(hw, 0x82c, 0x3, 1);
617
618 if (rtlhal->hw_type == HARDWARE_TYPE_RTL8812AE) {
619 rtl_set_bbreg(hw, RA_RFE_PINMUX, BMASKDWORD,
620 0x77337777);
621 rtl_set_bbreg(hw, RB_RFE_PINMUX, BMASKDWORD,
622 0x77337777);
623 rtl_set_bbreg(hw, RA_RFE_INV, 0x3ff00000, 0x010);
624 rtl_set_bbreg(hw, RB_RFE_INV, 0x3ff00000, 0x010);
625 }
626
627 rtl_set_bbreg(hw, RTXPATH, 0xf0, 0);
628 rtl_set_bbreg(hw, RCCK_RX, 0x0f000000, 0xf);
629
630 RT_TRACE(rtlpriv, COMP_SCAN, DBG_LOUD,
631 "==>PHY_SwitchWirelessBand8812() BAND_ON_5G settings OFDM index 0x%x\n",
632 rtlpriv->dm.ofdm_index[RF90_PATH_A]);
633 }
634
635 if ((rtlhal->hw_type == HARDWARE_TYPE_RTL8821AE) ||
636 (rtlhal->hw_type == HARDWARE_TYPE_RTL8812AE)) {
637 /* 0xC1C[31:21] */
638 rtl_set_bbreg(hw, RA_TXSCALE, 0xFFE00000,
639 phy_get_tx_swing_8812A(hw, band, RF90_PATH_A));
640 /* 0xE1C[31:21] */
641 rtl_set_bbreg(hw, RB_TXSCALE, 0xFFE00000,
642 phy_get_tx_swing_8812A(hw, band, RF90_PATH_B));
643
644 /* <20121005, Kordan> When TxPowerTrack is ON,
645 * we should take care of the change of BB swing.
646 * That is, reset all info to trigger Tx power tracking.
647 */
648 if (band != current_band) {
649 bb_diff_between_band =
650 (rtldm->swing_diff_2g - rtldm->swing_diff_5g);
651 bb_diff_between_band = (band == BAND_ON_2_4G) ?
652 bb_diff_between_band :
653 (-1 * bb_diff_between_band);
654 rtldm->default_ofdm_index += bb_diff_between_band * 2;
655 }
656 rtl8821ae_dm_clear_txpower_tracking_state(hw);
657 }
658
659 RT_TRACE(rtlpriv, COMP_SCAN, DBG_TRACE,
660 "<==rtl8821ae_phy_switch_wirelessband():Switch Band OK.\n");
661 return;
662}
663
664static bool _rtl8821ae_check_condition(struct ieee80211_hw *hw,
665 const u32 condition)
666{
667 struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
668 u32 _board = rtlefuse->board_type; /*need efuse define*/
669 u32 _interface = 0x01; /* ODM_ITRF_PCIE */
670 u32 _platform = 0x08;/* ODM_WIN */
671 u32 cond = condition;
672
673 if (condition == 0xCDCDCDCD)
674 return true;
675
676 cond = condition & 0xFF;
677 if ((_board != cond) && cond != 0xFF)
678 return false;
679
680 cond = condition & 0xFF00;
681 cond = cond >> 8;
682 if ((_interface & cond) == 0 && cond != 0x07)
683 return false;
684
685 cond = condition & 0xFF0000;
686 cond = cond >> 16;
687 if ((_platform & cond) == 0 && cond != 0x0F)
688 return false;
689 return true;
690}
691
692static void _rtl8821ae_config_rf_reg(struct ieee80211_hw *hw,
693 u32 addr, u32 data,
694 enum radio_path rfpath, u32 regaddr)
695{
696 if (addr == 0xfe || addr == 0xffe) {
697 /* In order not to disturb BT music when
698 * wifi init.(1ant NIC only)
699 */
700 mdelay(50);
701 } else {
702 rtl_set_rfreg(hw, rfpath, regaddr, RFREG_OFFSET_MASK, data);
703 udelay(1);
704 }
705}
706
707static void _rtl8821ae_config_rf_radio_a(struct ieee80211_hw *hw,
708 u32 addr, u32 data)
709{
710 u32 content = 0x1000; /*RF Content: radio_a_txt*/
711 u32 maskforphyset = (u32)(content & 0xE000);
712
713 _rtl8821ae_config_rf_reg(hw, addr, data,
714 RF90_PATH_A, addr | maskforphyset);
715}
716
717static void _rtl8821ae_config_rf_radio_b(struct ieee80211_hw *hw,
718 u32 addr, u32 data)
719{
720 u32 content = 0x1001; /*RF Content: radio_b_txt*/
721 u32 maskforphyset = (u32)(content & 0xE000);
722
723 _rtl8821ae_config_rf_reg(hw, addr, data,
724 RF90_PATH_B, addr | maskforphyset);
725}
726
727static void _rtl8821ae_config_bb_reg(struct ieee80211_hw *hw,
728 u32 addr, u32 data)
729{
730 if (addr == 0xfe)
731 mdelay(50);
732 else if (addr == 0xfd)
733 mdelay(5);
734 else if (addr == 0xfc)
735 mdelay(1);
736 else if (addr == 0xfb)
737 udelay(50);
738 else if (addr == 0xfa)
739 udelay(5);
740 else if (addr == 0xf9)
741 udelay(1);
742 else
743 rtl_set_bbreg(hw, addr, MASKDWORD, data);
744
745 udelay(1);
746}
747
748static void _rtl8821ae_phy_init_tx_power_by_rate(struct ieee80211_hw *hw)
749{
750 struct rtl_priv *rtlpriv = rtl_priv(hw);
751 struct rtl_phy *rtlphy = &rtlpriv->phy;
752 u8 band, rfpath, txnum, rate_section;
753
754 for (band = BAND_ON_2_4G; band <= BAND_ON_5G; ++band)
755 for (rfpath = 0; rfpath < TX_PWR_BY_RATE_NUM_RF; ++rfpath)
756 for (txnum = 0; txnum < TX_PWR_BY_RATE_NUM_RF; ++txnum)
757 for (rate_section = 0;
758 rate_section < TX_PWR_BY_RATE_NUM_SECTION;
759 ++rate_section)
760 rtlphy->tx_power_by_rate_offset[band]
761 [rfpath][txnum][rate_section] = 0;
762}
763
764static void _rtl8821ae_phy_set_txpower_by_rate_base(struct ieee80211_hw *hw,
765 u8 band, u8 path,
766 u8 rate_section,
767 u8 txnum, u8 value)
768{
769 struct rtl_priv *rtlpriv = rtl_priv(hw);
770 struct rtl_phy *rtlphy = &rtlpriv->phy;
771
772 if (path > RF90_PATH_D) {
773 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
774 "Invalid Rf Path %d in phy_SetTxPowerByRatBase()\n", path);
775 return;
776 }
777
778 if (band == BAND_ON_2_4G) {
779 switch (rate_section) {
780 case CCK:
781 rtlphy->txpwr_by_rate_base_24g[path][txnum][0] = value;
782 break;
783 case OFDM:
784 rtlphy->txpwr_by_rate_base_24g[path][txnum][1] = value;
785 break;
786 case HT_MCS0_MCS7:
787 rtlphy->txpwr_by_rate_base_24g[path][txnum][2] = value;
788 break;
789 case HT_MCS8_MCS15:
790 rtlphy->txpwr_by_rate_base_24g[path][txnum][3] = value;
791 break;
792 case VHT_1SSMCS0_1SSMCS9:
793 rtlphy->txpwr_by_rate_base_24g[path][txnum][4] = value;
794 break;
795 case VHT_2SSMCS0_2SSMCS9:
796 rtlphy->txpwr_by_rate_base_24g[path][txnum][5] = value;
797 break;
798 default:
799 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
800 "Invalid RateSection %d in Band 2.4G,Rf Path %d, %dTx in PHY_SetTxPowerByRateBase()\n",
801 rate_section, path, txnum);
802 break;
09fa9d87 803 }
21e4b072
LF
804 } else if (band == BAND_ON_5G) {
805 switch (rate_section) {
806 case OFDM:
807 rtlphy->txpwr_by_rate_base_5g[path][txnum][0] = value;
808 break;
809 case HT_MCS0_MCS7:
810 rtlphy->txpwr_by_rate_base_5g[path][txnum][1] = value;
811 break;
812 case HT_MCS8_MCS15:
813 rtlphy->txpwr_by_rate_base_5g[path][txnum][2] = value;
814 break;
815 case VHT_1SSMCS0_1SSMCS9:
816 rtlphy->txpwr_by_rate_base_5g[path][txnum][3] = value;
817 break;
818 case VHT_2SSMCS0_2SSMCS9:
819 rtlphy->txpwr_by_rate_base_5g[path][txnum][4] = value;
820 break;
821 default:
822 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
823 "Invalid RateSection %d in Band 5G, Rf Path %d, %dTx in PHY_SetTxPowerByRateBase()\n",
824 rate_section, path, txnum);
825 break;
09fa9d87 826 }
21e4b072
LF
827 } else {
828 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
829 "Invalid Band %d in PHY_SetTxPowerByRateBase()\n", band);
830 }
831}
832
833static u8 _rtl8821ae_phy_get_txpower_by_rate_base(struct ieee80211_hw *hw,
834 u8 band, u8 path,
835 u8 txnum, u8 rate_section)
836{
837 struct rtl_priv *rtlpriv = rtl_priv(hw);
838 struct rtl_phy *rtlphy = &rtlpriv->phy;
839 u8 value = 0;
840
841 if (path > RF90_PATH_D) {
842 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
843 "Invalid Rf Path %d in PHY_GetTxPowerByRateBase()\n",
844 path);
845 return 0;
846 }
847
848 if (band == BAND_ON_2_4G) {
849 switch (rate_section) {
850 case CCK:
851 value = rtlphy->txpwr_by_rate_base_24g[path][txnum][0];
852 break;
853 case OFDM:
854 value = rtlphy->txpwr_by_rate_base_24g[path][txnum][1];
855 break;
856 case HT_MCS0_MCS7:
857 value = rtlphy->txpwr_by_rate_base_24g[path][txnum][2];
858 break;
859 case HT_MCS8_MCS15:
860 value = rtlphy->txpwr_by_rate_base_24g[path][txnum][3];
861 break;
862 case VHT_1SSMCS0_1SSMCS9:
863 value = rtlphy->txpwr_by_rate_base_24g[path][txnum][4];
864 break;
865 case VHT_2SSMCS0_2SSMCS9:
866 value = rtlphy->txpwr_by_rate_base_24g[path][txnum][5];
867 break;
868 default:
869 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
870 "Invalid RateSection %d in Band 2.4G, Rf Path %d, %dTx in PHY_GetTxPowerByRateBase()\n",
871 rate_section, path, txnum);
872 break;
09fa9d87 873 }
21e4b072
LF
874 } else if (band == BAND_ON_5G) {
875 switch (rate_section) {
876 case OFDM:
877 value = rtlphy->txpwr_by_rate_base_5g[path][txnum][0];
878 break;
879 case HT_MCS0_MCS7:
880 value = rtlphy->txpwr_by_rate_base_5g[path][txnum][1];
881 break;
882 case HT_MCS8_MCS15:
883 value = rtlphy->txpwr_by_rate_base_5g[path][txnum][2];
884 break;
885 case VHT_1SSMCS0_1SSMCS9:
886 value = rtlphy->txpwr_by_rate_base_5g[path][txnum][3];
887 break;
888 case VHT_2SSMCS0_2SSMCS9:
889 value = rtlphy->txpwr_by_rate_base_5g[path][txnum][4];
890 break;
891 default:
892 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
893 "Invalid RateSection %d in Band 5G, Rf Path %d, %dTx in PHY_GetTxPowerByRateBase()\n",
894 rate_section, path, txnum);
895 break;
09fa9d87 896 }
21e4b072
LF
897 } else {
898 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
899 "Invalid Band %d in PHY_GetTxPowerByRateBase()\n", band);
900 }
901
902 return value;
903}
904
905static void _rtl8821ae_phy_store_txpower_by_rate_base(struct ieee80211_hw *hw)
906{
907 struct rtl_priv *rtlpriv = rtl_priv(hw);
908 struct rtl_phy *rtlphy = &rtlpriv->phy;
909 u16 rawValue = 0;
910 u8 base = 0, path = 0;
911
912 for (path = RF90_PATH_A; path <= RF90_PATH_B; ++path) {
913 rawValue = (u16)(rtlphy->tx_power_by_rate_offset[BAND_ON_2_4G][path][RF_1TX][0] >> 24) & 0xFF;
914 base = (rawValue >> 4) * 10 + (rawValue & 0xF);
915 _rtl8821ae_phy_set_txpower_by_rate_base(hw, BAND_ON_2_4G, path, CCK, RF_1TX, base);
916
917 rawValue = (u16)(rtlphy->tx_power_by_rate_offset[BAND_ON_2_4G][path][RF_1TX][2] >> 24) & 0xFF;
918 base = (rawValue >> 4) * 10 + (rawValue & 0xF);
919 _rtl8821ae_phy_set_txpower_by_rate_base(hw, BAND_ON_2_4G, path, OFDM, RF_1TX, base);
920
921 rawValue = (u16)(rtlphy->tx_power_by_rate_offset[BAND_ON_2_4G][path][RF_1TX][4] >> 24) & 0xFF;
922 base = (rawValue >> 4) * 10 + (rawValue & 0xF);
923 _rtl8821ae_phy_set_txpower_by_rate_base(hw, BAND_ON_2_4G, path, HT_MCS0_MCS7, RF_1TX, base);
924
925 rawValue = (u16)(rtlphy->tx_power_by_rate_offset[BAND_ON_2_4G][path][RF_2TX][6] >> 24) & 0xFF;
926 base = (rawValue >> 4) * 10 + (rawValue & 0xF);
927 _rtl8821ae_phy_set_txpower_by_rate_base(hw, BAND_ON_2_4G, path, HT_MCS8_MCS15, RF_2TX, base);
928
929 rawValue = (u16)(rtlphy->tx_power_by_rate_offset[BAND_ON_2_4G][path][RF_1TX][8] >> 24) & 0xFF;
930 base = (rawValue >> 4) * 10 + (rawValue & 0xF);
931 _rtl8821ae_phy_set_txpower_by_rate_base(hw, BAND_ON_2_4G, path, VHT_1SSMCS0_1SSMCS9, RF_1TX, base);
932
933 rawValue = (u16)(rtlphy->tx_power_by_rate_offset[BAND_ON_2_4G][path][RF_2TX][11] >> 8) & 0xFF;
934 base = (rawValue >> 4) * 10 + (rawValue & 0xF);
935 _rtl8821ae_phy_set_txpower_by_rate_base(hw, BAND_ON_2_4G, path, VHT_2SSMCS0_2SSMCS9, RF_2TX, base);
936
937 rawValue = (u16)(rtlphy->tx_power_by_rate_offset[BAND_ON_5G][path][RF_1TX][2] >> 24) & 0xFF;
938 base = (rawValue >> 4) * 10 + (rawValue & 0xF);
939 _rtl8821ae_phy_set_txpower_by_rate_base(hw, BAND_ON_5G, path, OFDM, RF_1TX, base);
940
941 rawValue = (u16)(rtlphy->tx_power_by_rate_offset[BAND_ON_5G][path][RF_1TX][4] >> 24) & 0xFF;
942 base = (rawValue >> 4) * 10 + (rawValue & 0xF);
943 _rtl8821ae_phy_set_txpower_by_rate_base(hw, BAND_ON_5G, path, HT_MCS0_MCS7, RF_1TX, base);
944
945 rawValue = (u16)(rtlphy->tx_power_by_rate_offset[BAND_ON_5G][path][RF_2TX][6] >> 24) & 0xFF;
946 base = (rawValue >> 4) * 10 + (rawValue & 0xF);
947 _rtl8821ae_phy_set_txpower_by_rate_base(hw, BAND_ON_5G, path, HT_MCS8_MCS15, RF_2TX, base);
948
949 rawValue = (u16)(rtlphy->tx_power_by_rate_offset[BAND_ON_5G][path][RF_1TX][8] >> 24) & 0xFF;
950 base = (rawValue >> 4) * 10 + (rawValue & 0xF);
951 _rtl8821ae_phy_set_txpower_by_rate_base(hw, BAND_ON_5G, path, VHT_1SSMCS0_1SSMCS9, RF_1TX, base);
952
953 rawValue = (u16)(rtlphy->tx_power_by_rate_offset[BAND_ON_5G][path][RF_2TX][11] >> 8) & 0xFF;
954 base = (rawValue >> 4) * 10 + (rawValue & 0xF);
955 _rtl8821ae_phy_set_txpower_by_rate_base(hw, BAND_ON_5G, path, VHT_2SSMCS0_2SSMCS9, RF_2TX, base);
956 }
957}
958
959static void _phy_convert_txpower_dbm_to_relative_value(u32 *data, u8 start,
960 u8 end, u8 base_val)
961{
005a425b 962 int i;
21e4b072
LF
963 u8 temp_value = 0;
964 u32 temp_data = 0;
965
966 for (i = 3; i >= 0; --i) {
967 if (i >= start && i <= end) {
968 /* Get the exact value */
969 temp_value = (u8)(*data >> (i * 8)) & 0xF;
970 temp_value += ((u8)((*data >> (i * 8 + 4)) & 0xF)) * 10;
971
972 /* Change the value to a relative value */
973 temp_value = (temp_value > base_val) ? temp_value -
974 base_val : base_val - temp_value;
975 } else {
976 temp_value = (u8)(*data >> (i * 8)) & 0xFF;
977 }
978 temp_data <<= 8;
979 temp_data |= temp_value;
980 }
981 *data = temp_data;
982}
983
984static void _rtl8812ae_phy_cross_reference_ht_and_vht_txpower_limit(struct ieee80211_hw *hw)
985{
986 struct rtl_priv *rtlpriv = rtl_priv(hw);
987 struct rtl_phy *rtlphy = &rtlpriv->phy;
988 u8 regulation, bw, channel, rate_section;
08aba42f 989 s8 temp_pwrlmt = 0;
21e4b072
LF
990
991 for (regulation = 0; regulation < MAX_REGULATION_NUM; ++regulation) {
992 for (bw = 0; bw < MAX_5G_BANDWITH_NUM; ++bw) {
993 for (channel = 0; channel < CHANNEL_MAX_NUMBER_5G; ++channel) {
994 for (rate_section = 0; rate_section < MAX_RATE_SECTION_NUM; ++rate_section) {
995 temp_pwrlmt = rtlphy->txpwr_limit_5g[regulation]
996 [bw][rate_section][channel][RF90_PATH_A];
997 if (temp_pwrlmt == MAX_POWER_INDEX) {
998 if (bw == 0 || bw == 1) { /*5G 20M 40M VHT and HT can cross reference*/
999 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
1000 "No power limit table of the specified band %d, bandwidth %d, ratesection %d, channel %d, rf path %d\n",
1001 1, bw, rate_section, channel, RF90_PATH_A);
1002 if (rate_section == 2) {
1003 rtlphy->txpwr_limit_5g[regulation][bw][2][channel][RF90_PATH_A] =
1004 rtlphy->txpwr_limit_5g[regulation][bw][4][channel][RF90_PATH_A];
1005 } else if (rate_section == 4) {
1006 rtlphy->txpwr_limit_5g[regulation][bw][4][channel][RF90_PATH_A] =
1007 rtlphy->txpwr_limit_5g[regulation][bw][2][channel][RF90_PATH_A];
1008 } else if (rate_section == 3) {
1009 rtlphy->txpwr_limit_5g[regulation][bw][3][channel][RF90_PATH_A] =
1010 rtlphy->txpwr_limit_5g[regulation][bw][5][channel][RF90_PATH_A];
1011 } else if (rate_section == 5) {
1012 rtlphy->txpwr_limit_5g[regulation][bw][5][channel][RF90_PATH_A] =
1013 rtlphy->txpwr_limit_5g[regulation][bw][3][channel][RF90_PATH_A];
1014 }
1015
4713bd1c 1016 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, "use other value %d\n", temp_pwrlmt);
21e4b072
LF
1017 }
1018 }
1019 }
1020 }
1021 }
1022 }
1023}
1024
1025static u8 _rtl8812ae_phy_get_txpower_by_rate_base_index(struct ieee80211_hw *hw,
1026 enum band_type band, u8 rate)
1027{
1028 struct rtl_priv *rtlpriv = rtl_priv(hw);
1029 u8 index = 0;
1030 if (band == BAND_ON_2_4G) {
1031 switch (rate) {
1032 case MGN_1M:
1033 case MGN_2M:
1034 case MGN_5_5M:
1035 case MGN_11M:
1036 index = 0;
1037 break;
1038
1039 case MGN_6M:
1040 case MGN_9M:
1041 case MGN_12M:
1042 case MGN_18M:
1043 case MGN_24M:
1044 case MGN_36M:
1045 case MGN_48M:
1046 case MGN_54M:
1047 index = 1;
1048 break;
1049
1050 case MGN_MCS0:
1051 case MGN_MCS1:
1052 case MGN_MCS2:
1053 case MGN_MCS3:
1054 case MGN_MCS4:
1055 case MGN_MCS5:
1056 case MGN_MCS6:
1057 case MGN_MCS7:
1058 index = 2;
1059 break;
1060
1061 case MGN_MCS8:
1062 case MGN_MCS9:
1063 case MGN_MCS10:
1064 case MGN_MCS11:
1065 case MGN_MCS12:
1066 case MGN_MCS13:
1067 case MGN_MCS14:
1068 case MGN_MCS15:
1069 index = 3;
1070 break;
1071
1072 default:
1073 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
1074 "Wrong rate 0x%x to obtain index in 2.4G in PHY_GetTxPowerByRateBaseIndex()\n",
1075 rate);
1076 break;
1077 }
1078 } else if (band == BAND_ON_5G) {
1079 switch (rate) {
1080 case MGN_6M:
1081 case MGN_9M:
1082 case MGN_12M:
1083 case MGN_18M:
1084 case MGN_24M:
1085 case MGN_36M:
1086 case MGN_48M:
1087 case MGN_54M:
1088 index = 0;
1089 break;
1090
1091 case MGN_MCS0:
1092 case MGN_MCS1:
1093 case MGN_MCS2:
1094 case MGN_MCS3:
1095 case MGN_MCS4:
1096 case MGN_MCS5:
1097 case MGN_MCS6:
1098 case MGN_MCS7:
1099 index = 1;
1100 break;
1101
1102 case MGN_MCS8:
1103 case MGN_MCS9:
1104 case MGN_MCS10:
1105 case MGN_MCS11:
1106 case MGN_MCS12:
1107 case MGN_MCS13:
1108 case MGN_MCS14:
1109 case MGN_MCS15:
1110 index = 2;
1111 break;
1112
1113 case MGN_VHT1SS_MCS0:
1114 case MGN_VHT1SS_MCS1:
1115 case MGN_VHT1SS_MCS2:
1116 case MGN_VHT1SS_MCS3:
1117 case MGN_VHT1SS_MCS4:
1118 case MGN_VHT1SS_MCS5:
1119 case MGN_VHT1SS_MCS6:
1120 case MGN_VHT1SS_MCS7:
1121 case MGN_VHT1SS_MCS8:
1122 case MGN_VHT1SS_MCS9:
1123 index = 3;
1124 break;
1125
1126 case MGN_VHT2SS_MCS0:
1127 case MGN_VHT2SS_MCS1:
1128 case MGN_VHT2SS_MCS2:
1129 case MGN_VHT2SS_MCS3:
1130 case MGN_VHT2SS_MCS4:
1131 case MGN_VHT2SS_MCS5:
1132 case MGN_VHT2SS_MCS6:
1133 case MGN_VHT2SS_MCS7:
1134 case MGN_VHT2SS_MCS8:
1135 case MGN_VHT2SS_MCS9:
1136 index = 4;
1137 break;
1138
1139 default:
1140 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
1141 "Wrong rate 0x%x to obtain index in 5G in PHY_GetTxPowerByRateBaseIndex()\n",
1142 rate);
1143 break;
1144 }
1145 }
1146
1147 return index;
1148}
1149
1150static void _rtl8812ae_phy_convert_txpower_limit_to_power_index(struct ieee80211_hw *hw)
1151{
1152 struct rtl_priv *rtlpriv = rtl_priv(hw);
1153 struct rtl_phy *rtlphy = &rtlpriv->phy;
1154 u8 bw40_pwr_base_dbm2_4G, bw40_pwr_base_dbm5G;
1155 u8 regulation, bw, channel, rate_section;
1156 u8 base_index2_4G = 0;
1157 u8 base_index5G = 0;
08aba42f 1158 s8 temp_value = 0, temp_pwrlmt = 0;
21e4b072
LF
1159 u8 rf_path = 0;
1160
1161 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
1162 "=====> _rtl8812ae_phy_convert_txpower_limit_to_power_index()\n");
1163
1164 _rtl8812ae_phy_cross_reference_ht_and_vht_txpower_limit(hw);
1165
1166 for (regulation = 0; regulation < MAX_REGULATION_NUM; ++regulation) {
1167 for (bw = 0; bw < MAX_2_4G_BANDWITH_NUM; ++bw) {
1168 for (channel = 0; channel < CHANNEL_MAX_NUMBER_2G; ++channel) {
1169 for (rate_section = 0; rate_section < MAX_RATE_SECTION_NUM; ++rate_section) {
1170 /* obtain the base dBm values in 2.4G band
1171 CCK => 11M, OFDM => 54M, HT 1T => MCS7, HT 2T => MCS15*/
1172 if (rate_section == 0) { /*CCK*/
1173 base_index2_4G =
1174 _rtl8812ae_phy_get_txpower_by_rate_base_index(hw,
1175 BAND_ON_2_4G, MGN_11M);
1176 } else if (rate_section == 1) { /*OFDM*/
1177 base_index2_4G =
1178 _rtl8812ae_phy_get_txpower_by_rate_base_index(hw,
1179 BAND_ON_2_4G, MGN_54M);
1180 } else if (rate_section == 2) { /*HT IT*/
1181 base_index2_4G =
1182 _rtl8812ae_phy_get_txpower_by_rate_base_index(hw,
1183 BAND_ON_2_4G, MGN_MCS7);
1184 } else if (rate_section == 3) { /*HT 2T*/
1185 base_index2_4G =
1186 _rtl8812ae_phy_get_txpower_by_rate_base_index(hw,
1187 BAND_ON_2_4G, MGN_MCS15);
1188 }
1189
1190 temp_pwrlmt = rtlphy->txpwr_limit_2_4g[regulation]
1191 [bw][rate_section][channel][RF90_PATH_A];
1192
1193 for (rf_path = RF90_PATH_A;
1194 rf_path < MAX_RF_PATH_NUM;
1195 ++rf_path) {
1196 if (rate_section == 3)
1197 bw40_pwr_base_dbm2_4G =
1198 rtlphy->txpwr_by_rate_base_24g[rf_path][RF_2TX][base_index2_4G];
1199 else
1200 bw40_pwr_base_dbm2_4G =
1201 rtlphy->txpwr_by_rate_base_24g[rf_path][RF_1TX][base_index2_4G];
1202
1203 if (temp_pwrlmt != MAX_POWER_INDEX) {
1204 temp_value = temp_pwrlmt - bw40_pwr_base_dbm2_4G;
1205 rtlphy->txpwr_limit_2_4g[regulation]
1206 [bw][rate_section][channel][rf_path] =
1207 temp_value;
1208 }
1209
1210 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
1211 "TxPwrLimit_2_4G[regulation %d][bw %d][rateSection %d][channel %d] = %d\n(TxPwrLimit in dBm %d - BW40PwrLmt2_4G[channel %d][rfPath %d] %d)\n",
1212 regulation, bw, rate_section, channel,
1213 rtlphy->txpwr_limit_2_4g[regulation][bw]
1214 [rate_section][channel][rf_path], (temp_pwrlmt == 63)
1215 ? 0 : temp_pwrlmt/2, channel, rf_path,
1216 bw40_pwr_base_dbm2_4G);
1217 }
1218 }
1219 }
1220 }
1221 }
1222 for (regulation = 0; regulation < MAX_REGULATION_NUM; ++regulation) {
1223 for (bw = 0; bw < MAX_5G_BANDWITH_NUM; ++bw) {
1224 for (channel = 0; channel < CHANNEL_MAX_NUMBER_5G; ++channel) {
1225 for (rate_section = 0; rate_section < MAX_RATE_SECTION_NUM; ++rate_section) {
1226 /* obtain the base dBm values in 5G band
1227 OFDM => 54M, HT 1T => MCS7, HT 2T => MCS15,
1228 VHT => 1SSMCS7, VHT 2T => 2SSMCS7*/
1229 if (rate_section == 1) { /*OFDM*/
1230 base_index5G =
1231 _rtl8812ae_phy_get_txpower_by_rate_base_index(hw,
1232 BAND_ON_5G, MGN_54M);
1233 } else if (rate_section == 2) { /*HT 1T*/
1234 base_index5G =
1235 _rtl8812ae_phy_get_txpower_by_rate_base_index(hw,
1236 BAND_ON_5G, MGN_MCS7);
1237 } else if (rate_section == 3) { /*HT 2T*/
1238 base_index5G =
1239 _rtl8812ae_phy_get_txpower_by_rate_base_index(hw,
1240 BAND_ON_5G, MGN_MCS15);
1241 } else if (rate_section == 4) { /*VHT 1T*/
1242 base_index5G =
1243 _rtl8812ae_phy_get_txpower_by_rate_base_index(hw,
1244 BAND_ON_5G, MGN_VHT1SS_MCS7);
1245 } else if (rate_section == 5) { /*VHT 2T*/
1246 base_index5G =
1247 _rtl8812ae_phy_get_txpower_by_rate_base_index(hw,
1248 BAND_ON_5G, MGN_VHT2SS_MCS7);
1249 }
1250
1251 temp_pwrlmt = rtlphy->txpwr_limit_5g[regulation]
1252 [bw][rate_section][channel]
1253 [RF90_PATH_A];
1254
1255 for (rf_path = RF90_PATH_A;
1256 rf_path < MAX_RF_PATH_NUM;
1257 ++rf_path) {
1258 if (rate_section == 3 || rate_section == 5)
1259 bw40_pwr_base_dbm5G =
1260 rtlphy->txpwr_by_rate_base_5g[rf_path]
1261 [RF_2TX][base_index5G];
1262 else
1263 bw40_pwr_base_dbm5G =
1264 rtlphy->txpwr_by_rate_base_5g[rf_path]
1265 [RF_1TX][base_index5G];
1266
1267 if (temp_pwrlmt != MAX_POWER_INDEX) {
1268 temp_value =
1269 temp_pwrlmt - bw40_pwr_base_dbm5G;
1270 rtlphy->txpwr_limit_5g[regulation]
1271 [bw][rate_section][channel]
1272 [rf_path] = temp_value;
1273 }
1274
1275 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
1276 "TxPwrLimit_5G[regulation %d][bw %d][rateSection %d][channel %d] =%d\n(TxPwrLimit in dBm %d - BW40PwrLmt5G[chnl group %d][rfPath %d] %d)\n",
1277 regulation, bw, rate_section,
1278 channel, rtlphy->txpwr_limit_5g[regulation]
1279 [bw][rate_section][channel][rf_path],
1280 temp_pwrlmt, channel, rf_path, bw40_pwr_base_dbm5G);
1281 }
1282 }
1283 }
1284 }
1285 }
1286 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
1287 "<===== _rtl8812ae_phy_convert_txpower_limit_to_power_index()\n");
1288}
1289
1290static void _rtl8821ae_phy_init_txpower_limit(struct ieee80211_hw *hw)
1291{
1292 struct rtl_priv *rtlpriv = rtl_priv(hw);
1293 struct rtl_phy *rtlphy = &rtlpriv->phy;
1294 u8 i, j, k, l, m;
1295
1296 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
1297 "=====> _rtl8821ae_phy_init_txpower_limit()!\n");
1298
1299 for (i = 0; i < MAX_REGULATION_NUM; ++i) {
1300 for (j = 0; j < MAX_2_4G_BANDWITH_NUM; ++j)
1301 for (k = 0; k < MAX_RATE_SECTION_NUM; ++k)
1302 for (m = 0; m < CHANNEL_MAX_NUMBER_2G; ++m)
1303 for (l = 0; l < MAX_RF_PATH_NUM; ++l)
1304 rtlphy->txpwr_limit_2_4g
1305 [i][j][k][m][l]
1306 = MAX_POWER_INDEX;
1307 }
1308 for (i = 0; i < MAX_REGULATION_NUM; ++i) {
1309 for (j = 0; j < MAX_5G_BANDWITH_NUM; ++j)
1310 for (k = 0; k < MAX_RATE_SECTION_NUM; ++k)
1311 for (m = 0; m < CHANNEL_MAX_NUMBER_5G; ++m)
1312 for (l = 0; l < MAX_RF_PATH_NUM; ++l)
1313 rtlphy->txpwr_limit_5g
1314 [i][j][k][m][l]
1315 = MAX_POWER_INDEX;
1316 }
1317
1318 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
1319 "<===== _rtl8821ae_phy_init_txpower_limit()!\n");
1320}
1321
1322static void _rtl8821ae_phy_convert_txpower_dbm_to_relative_value(struct ieee80211_hw *hw)
1323{
1324 struct rtl_priv *rtlpriv = rtl_priv(hw);
1325 struct rtl_phy *rtlphy = &rtlpriv->phy;
1326 u8 base = 0, rfPath = 0;
1327
1328 for (rfPath = RF90_PATH_A; rfPath <= RF90_PATH_B; ++rfPath) {
1329 base = _rtl8821ae_phy_get_txpower_by_rate_base(hw, BAND_ON_2_4G, rfPath, RF_1TX, CCK);
1330 _phy_convert_txpower_dbm_to_relative_value(
1331 &rtlphy->tx_power_by_rate_offset[BAND_ON_2_4G][rfPath][RF_1TX][0],
1332 0, 3, base);
1333
1334 base = _rtl8821ae_phy_get_txpower_by_rate_base(hw, BAND_ON_2_4G, rfPath, RF_1TX, OFDM);
1335 _phy_convert_txpower_dbm_to_relative_value(
1336 &rtlphy->tx_power_by_rate_offset[BAND_ON_2_4G][rfPath][RF_1TX][1],
1337 0, 3, base);
1338 _phy_convert_txpower_dbm_to_relative_value(
1339 &rtlphy->tx_power_by_rate_offset[BAND_ON_2_4G][rfPath][RF_1TX][2],
1340 0, 3, base);
1341
1342 base = _rtl8821ae_phy_get_txpower_by_rate_base(hw, BAND_ON_2_4G, rfPath, RF_1TX, HT_MCS0_MCS7);
1343 _phy_convert_txpower_dbm_to_relative_value(
1344 &rtlphy->tx_power_by_rate_offset[BAND_ON_2_4G][rfPath][RF_1TX][3],
1345 0, 3, base);
1346 _phy_convert_txpower_dbm_to_relative_value(
1347 &rtlphy->tx_power_by_rate_offset[BAND_ON_2_4G][rfPath][RF_1TX][4],
1348 0, 3, base);
1349
1350 base = _rtl8821ae_phy_get_txpower_by_rate_base(hw, BAND_ON_2_4G, rfPath, RF_2TX, HT_MCS8_MCS15);
1351
1352 _phy_convert_txpower_dbm_to_relative_value(
1353 &rtlphy->tx_power_by_rate_offset[BAND_ON_2_4G][rfPath][RF_2TX][5],
1354 0, 3, base);
1355
1356 _phy_convert_txpower_dbm_to_relative_value(
1357 &rtlphy->tx_power_by_rate_offset[BAND_ON_2_4G][rfPath][RF_2TX][6],
1358 0, 3, base);
1359
1360 base = _rtl8821ae_phy_get_txpower_by_rate_base(hw, BAND_ON_2_4G, rfPath, RF_1TX, VHT_1SSMCS0_1SSMCS9);
1361 _phy_convert_txpower_dbm_to_relative_value(
1362 &rtlphy->tx_power_by_rate_offset[BAND_ON_2_4G][rfPath][RF_1TX][7],
1363 0, 3, base);
1364 _phy_convert_txpower_dbm_to_relative_value(
1365 &rtlphy->tx_power_by_rate_offset[BAND_ON_2_4G][rfPath][RF_1TX][8],
1366 0, 3, base);
1367 _phy_convert_txpower_dbm_to_relative_value(
1368 &rtlphy->tx_power_by_rate_offset[BAND_ON_2_4G][rfPath][RF_1TX][9],
1369 0, 1, base);
1370
1371 base = _rtl8821ae_phy_get_txpower_by_rate_base(hw, BAND_ON_2_4G, rfPath, RF_2TX, VHT_2SSMCS0_2SSMCS9);
1372 _phy_convert_txpower_dbm_to_relative_value(
1373 &rtlphy->tx_power_by_rate_offset[BAND_ON_2_4G][rfPath][RF_1TX][9],
1374 2, 3, base);
1375 _phy_convert_txpower_dbm_to_relative_value(
1376 &rtlphy->tx_power_by_rate_offset[BAND_ON_2_4G][rfPath][RF_2TX][10],
1377 0, 3, base);
1378 _phy_convert_txpower_dbm_to_relative_value(
1379 &rtlphy->tx_power_by_rate_offset[BAND_ON_2_4G][rfPath][RF_2TX][11],
1380 0, 3, base);
1381
1382 base = _rtl8821ae_phy_get_txpower_by_rate_base(hw, BAND_ON_5G, rfPath, RF_1TX, OFDM);
1383 _phy_convert_txpower_dbm_to_relative_value(
1384 &rtlphy->tx_power_by_rate_offset[BAND_ON_5G][rfPath][RF_1TX][1],
1385 0, 3, base);
1386 _phy_convert_txpower_dbm_to_relative_value(
1387 &rtlphy->tx_power_by_rate_offset[BAND_ON_5G][rfPath][RF_1TX][2],
1388 0, 3, base);
1389
1390 base = _rtl8821ae_phy_get_txpower_by_rate_base(hw, BAND_ON_5G, rfPath, RF_1TX, HT_MCS0_MCS7);
1391 _phy_convert_txpower_dbm_to_relative_value(
1392 &rtlphy->tx_power_by_rate_offset[BAND_ON_5G][rfPath][RF_1TX][3],
1393 0, 3, base);
1394 _phy_convert_txpower_dbm_to_relative_value(
1395 &rtlphy->tx_power_by_rate_offset[BAND_ON_5G][rfPath][RF_1TX][4],
1396 0, 3, base);
1397
1398 base = _rtl8821ae_phy_get_txpower_by_rate_base(hw, BAND_ON_5G, rfPath, RF_2TX, HT_MCS8_MCS15);
1399 _phy_convert_txpower_dbm_to_relative_value(
1400 &rtlphy->tx_power_by_rate_offset[BAND_ON_5G][rfPath][RF_2TX][5],
1401 0, 3, base);
1402 _phy_convert_txpower_dbm_to_relative_value(
1403 &rtlphy->tx_power_by_rate_offset[BAND_ON_5G][rfPath][RF_2TX][6],
1404 0, 3, base);
1405
1406 base = _rtl8821ae_phy_get_txpower_by_rate_base(hw, BAND_ON_5G, rfPath, RF_1TX, VHT_1SSMCS0_1SSMCS9);
1407 _phy_convert_txpower_dbm_to_relative_value(
1408 &rtlphy->tx_power_by_rate_offset[BAND_ON_5G][rfPath][RF_1TX][7],
1409 0, 3, base);
1410 _phy_convert_txpower_dbm_to_relative_value(
1411 &rtlphy->tx_power_by_rate_offset[BAND_ON_5G][rfPath][RF_1TX][8],
1412 0, 3, base);
1413 _phy_convert_txpower_dbm_to_relative_value(
1414 &rtlphy->tx_power_by_rate_offset[BAND_ON_5G][rfPath][RF_1TX][9],
1415 0, 1, base);
1416
1417 base = _rtl8821ae_phy_get_txpower_by_rate_base(hw, BAND_ON_5G, rfPath, RF_2TX, VHT_2SSMCS0_2SSMCS9);
1418 _phy_convert_txpower_dbm_to_relative_value(
1419 &rtlphy->tx_power_by_rate_offset[BAND_ON_5G][rfPath][RF_1TX][9],
1420 2, 3, base);
1421 _phy_convert_txpower_dbm_to_relative_value(
1422 &rtlphy->tx_power_by_rate_offset[BAND_ON_5G][rfPath][RF_2TX][10],
1423 0, 3, base);
1424 _phy_convert_txpower_dbm_to_relative_value(
1425 &rtlphy->tx_power_by_rate_offset[BAND_ON_5G][rfPath][RF_2TX][11],
1426 0, 3, base);
1427 }
1428
1429 RT_TRACE(rtlpriv, COMP_POWER, DBG_TRACE,
1430 "<===_rtl8821ae_phy_convert_txpower_dbm_to_relative_value()\n");
1431}
1432
1433static void _rtl8821ae_phy_txpower_by_rate_configuration(struct ieee80211_hw *hw)
1434{
1435 _rtl8821ae_phy_store_txpower_by_rate_base(hw);
1436 _rtl8821ae_phy_convert_txpower_dbm_to_relative_value(hw);
1437}
1438
1439/* string is in decimal */
1440static bool _rtl8812ae_get_integer_from_string(char *str, u8 *pint)
1441{
1442 u16 i = 0;
1443 *pint = 0;
1444
1445 while (str[i] != '\0') {
1446 if (str[i] >= '0' && str[i] <= '9') {
1447 *pint *= 10;
1448 *pint += (str[i] - '0');
1449 } else {
1450 return false;
1451 }
1452 ++i;
1453 }
1454
1455 return true;
1456}
1457
1458static bool _rtl8812ae_eq_n_byte(u8 *str1, u8 *str2, u32 num)
1459{
1460 if (num == 0)
1461 return false;
1462 while (num > 0) {
1463 num--;
1464 if (str1[num] != str2[num])
1465 return false;
1466 }
1467 return true;
1468}
1469
08aba42f 1470static s8 _rtl8812ae_phy_get_chnl_idx_of_txpwr_lmt(struct ieee80211_hw *hw,
21e4b072
LF
1471 u8 band, u8 channel)
1472{
1473 struct rtl_priv *rtlpriv = rtl_priv(hw);
08aba42f 1474 s8 channel_index = -1;
21e4b072 1475 u8 i = 0;
0a44b220 1476
21e4b072
LF
1477 if (band == BAND_ON_2_4G)
1478 channel_index = channel - 1;
1479 else if (band == BAND_ON_5G) {
0a44b220
LF
1480 for (i = 0; i < sizeof(channel5g)/sizeof(u8); ++i) {
1481 if (channel5g[i] == channel)
21e4b072
LF
1482 channel_index = i;
1483 }
1484 } else
4713bd1c 1485 RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, "Invalid Band %d in %s\n",
21e4b072
LF
1486 band, __func__);
1487
1488 if (channel_index == -1)
1489 RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
4713bd1c 1490 "Invalid Channel %d of Band %d in %s\n", channel,
21e4b072
LF
1491 band, __func__);
1492
1493 return channel_index;
1494}
1495
1496static void _rtl8812ae_phy_set_txpower_limit(struct ieee80211_hw *hw, u8 *pregulation,
1497 u8 *pband, u8 *pbandwidth,
1498 u8 *prate_section, u8 *prf_path,
1499 u8 *pchannel, u8 *ppower_limit)
1500{
1501 struct rtl_priv *rtlpriv = rtl_priv(hw);
1502 struct rtl_phy *rtlphy = &rtlpriv->phy;
1503 u8 regulation = 0, bandwidth = 0, rate_section = 0, channel;
1504 u8 channel_index;
08aba42f 1505 s8 power_limit = 0, prev_power_limit, ret;
21e4b072
LF
1506
1507 if (!_rtl8812ae_get_integer_from_string((char *)pchannel, &channel) ||
1508 !_rtl8812ae_get_integer_from_string((char *)ppower_limit,
1509 &power_limit)) {
1510 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
1511 "Illegal index of pwr_lmt table [chnl %d][val %d]\n",
1512 channel, power_limit);
1513 }
1514
1515 power_limit = power_limit > MAX_POWER_INDEX ?
1516 MAX_POWER_INDEX : power_limit;
1517
1518 if (_rtl8812ae_eq_n_byte(pregulation, (u8 *)("FCC"), 3))
1519 regulation = 0;
1520 else if (_rtl8812ae_eq_n_byte(pregulation, (u8 *)("MKK"), 3))
1521 regulation = 1;
1522 else if (_rtl8812ae_eq_n_byte(pregulation, (u8 *)("ETSI"), 4))
1523 regulation = 2;
1524 else if (_rtl8812ae_eq_n_byte(pregulation, (u8 *)("WW13"), 4))
1525 regulation = 3;
1526
1527 if (_rtl8812ae_eq_n_byte(prate_section, (u8 *)("CCK"), 3))
1528 rate_section = 0;
1529 else if (_rtl8812ae_eq_n_byte(prate_section, (u8 *)("OFDM"), 4))
1530 rate_section = 1;
1531 else if (_rtl8812ae_eq_n_byte(prate_section, (u8 *)("HT"), 2) &&
1532 _rtl8812ae_eq_n_byte(prf_path, (u8 *)("1T"), 2))
1533 rate_section = 2;
1534 else if (_rtl8812ae_eq_n_byte(prate_section, (u8 *)("HT"), 2) &&
1535 _rtl8812ae_eq_n_byte(prf_path, (u8 *)("2T"), 2))
1536 rate_section = 3;
1537 else if (_rtl8812ae_eq_n_byte(prate_section, (u8 *)("VHT"), 3) &&
1538 _rtl8812ae_eq_n_byte(prf_path, (u8 *)("1T"), 2))
1539 rate_section = 4;
1540 else if (_rtl8812ae_eq_n_byte(prate_section, (u8 *)("VHT"), 3) &&
1541 _rtl8812ae_eq_n_byte(prf_path, (u8 *)("2T"), 2))
1542 rate_section = 5;
1543
1544 if (_rtl8812ae_eq_n_byte(pbandwidth, (u8 *)("20M"), 3))
1545 bandwidth = 0;
1546 else if (_rtl8812ae_eq_n_byte(pbandwidth, (u8 *)("40M"), 3))
1547 bandwidth = 1;
1548 else if (_rtl8812ae_eq_n_byte(pbandwidth, (u8 *)("80M"), 3))
1549 bandwidth = 2;
1550 else if (_rtl8812ae_eq_n_byte(pbandwidth, (u8 *)("160M"), 4))
1551 bandwidth = 3;
1552
1553 if (_rtl8812ae_eq_n_byte(pband, (u8 *)("2.4G"), 4)) {
1554 ret = _rtl8812ae_phy_get_chnl_idx_of_txpwr_lmt(hw,
1555 BAND_ON_2_4G,
1556 channel);
1557
1558 if (ret == -1)
1559 return;
1560
1561 channel_index = ret;
1562
1563 prev_power_limit = rtlphy->txpwr_limit_2_4g[regulation]
1564 [bandwidth][rate_section]
1565 [channel_index][RF90_PATH_A];
1566
1567 if (power_limit < prev_power_limit)
1568 rtlphy->txpwr_limit_2_4g[regulation][bandwidth]
1569 [rate_section][channel_index][RF90_PATH_A] =
1570 power_limit;
1571
1572 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
1573 "2.4G [regula %d][bw %d][sec %d][chnl %d][val %d]\n",
1574 regulation, bandwidth, rate_section, channel_index,
1575 rtlphy->txpwr_limit_2_4g[regulation][bandwidth]
1576 [rate_section][channel_index][RF90_PATH_A]);
1577 } else if (_rtl8812ae_eq_n_byte(pband, (u8 *)("5G"), 2)) {
1578 ret = _rtl8812ae_phy_get_chnl_idx_of_txpwr_lmt(hw,
1579 BAND_ON_5G,
1580 channel);
1581
1582 if (ret == -1)
1583 return;
1584
1585 channel_index = ret;
1586
1587 prev_power_limit = rtlphy->txpwr_limit_5g[regulation][bandwidth]
1588 [rate_section][channel_index]
1589 [RF90_PATH_A];
1590
1591 if (power_limit < prev_power_limit)
1592 rtlphy->txpwr_limit_5g[regulation][bandwidth]
1593 [rate_section][channel_index][RF90_PATH_A] = power_limit;
1594
1595 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
1596 "5G: [regul %d][bw %d][sec %d][chnl %d][val %d]\n",
1597 regulation, bandwidth, rate_section, channel,
1598 rtlphy->txpwr_limit_5g[regulation][bandwidth]
1599 [rate_section][channel_index][RF90_PATH_A]);
1600 } else {
1601 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
1602 "Cannot recognize the band info in %s\n", pband);
1603 return;
1604 }
1605}
1606
1607static void _rtl8812ae_phy_config_bb_txpwr_lmt(struct ieee80211_hw *hw,
1608 u8 *regulation, u8 *band,
1609 u8 *bandwidth, u8 *rate_section,
1610 u8 *rf_path, u8 *channel,
1611 u8 *power_limit)
1612{
1613 _rtl8812ae_phy_set_txpower_limit(hw, regulation, band, bandwidth,
1614 rate_section, rf_path, channel,
1615 power_limit);
1616}
1617
1618static void _rtl8821ae_phy_read_and_config_txpwr_lmt(struct ieee80211_hw *hw)
1619{
1620 struct rtl_priv *rtlpriv = rtl_priv(hw);
1621 struct rtl_hal *rtlhal = rtl_hal(rtlpriv);
1622 u32 i = 0;
1623 u32 array_len;
1624 u8 **array;
1625
1626 if (rtlhal->hw_type == HARDWARE_TYPE_RTL8812AE) {
1627 array_len = RTL8812AE_TXPWR_LMT_ARRAY_LEN;
1628 array = RTL8812AE_TXPWR_LMT;
1629 } else {
1630 array_len = RTL8821AE_TXPWR_LMT_ARRAY_LEN;
1631 array = RTL8821AE_TXPWR_LMT;
1632 }
1633
1634 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
1635 "\n");
1636
1637 for (i = 0; i < array_len; i += 7) {
1638 u8 *regulation = array[i];
1639 u8 *band = array[i+1];
1640 u8 *bandwidth = array[i+2];
1641 u8 *rate = array[i+3];
1642 u8 *rf_path = array[i+4];
1643 u8 *chnl = array[i+5];
1644 u8 *val = array[i+6];
1645
1646 _rtl8812ae_phy_config_bb_txpwr_lmt(hw, regulation, band,
1647 bandwidth, rate, rf_path,
1648 chnl, val);
1649 }
1650}
1651
1652static bool _rtl8821ae_phy_bb8821a_config_parafile(struct ieee80211_hw *hw)
1653{
1654 struct rtl_priv *rtlpriv = rtl_priv(hw);
1655 struct rtl_phy *rtlphy = &rtlpriv->phy;
1656 struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
1657 bool rtstatus;
1658
1659 _rtl8821ae_phy_init_txpower_limit(hw);
1660
1661 /* RegEnableTxPowerLimit == 1 for 8812a & 8821a */
1662 if (rtlefuse->eeprom_regulatory != 2)
1663 _rtl8821ae_phy_read_and_config_txpwr_lmt(hw);
1664
1665 rtstatus = _rtl8821ae_phy_config_bb_with_headerfile(hw,
1666 BASEBAND_CONFIG_PHY_REG);
1667 if (rtstatus != true) {
4713bd1c 1668 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, "Write BB Reg Fail!!\n");
21e4b072
LF
1669 return false;
1670 }
1671 _rtl8821ae_phy_init_tx_power_by_rate(hw);
1672 if (rtlefuse->autoload_failflag == false) {
1673 rtstatus = _rtl8821ae_phy_config_bb_with_pgheaderfile(hw,
1674 BASEBAND_CONFIG_PHY_REG);
1675 }
1676 if (rtstatus != true) {
4713bd1c 1677 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, "BB_PG Reg Fail!!\n");
21e4b072
LF
1678 return false;
1679 }
1680
1681 _rtl8821ae_phy_txpower_by_rate_configuration(hw);
1682
1683 /* RegEnableTxPowerLimit == 1 for 8812a & 8821a */
1684 if (rtlefuse->eeprom_regulatory != 2)
1685 _rtl8812ae_phy_convert_txpower_limit_to_power_index(hw);
1686
1687 rtstatus = _rtl8821ae_phy_config_bb_with_headerfile(hw,
1688 BASEBAND_CONFIG_AGC_TAB);
1689
1690 if (rtstatus != true) {
1691 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, "AGC Table Fail\n");
1692 return false;
1693 }
1694 rtlphy->cck_high_power = (bool)(rtl_get_bbreg(hw,
1695 RFPGA0_XA_HSSIPARAMETER2, 0x200));
1696 return true;
1697}
1698
1699static bool _rtl8821ae_phy_config_mac_with_headerfile(struct ieee80211_hw *hw)
1700{
1701 struct rtl_priv *rtlpriv = rtl_priv(hw);
1702 struct rtl_hal *rtlhal = rtl_hal(rtlpriv);
1703 u32 i, v1, v2;
1704 u32 arraylength;
1705 u32 *ptrarray;
1706
1707 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, "Read MAC_REG_Array\n");
1708 if (rtlhal->hw_type == HARDWARE_TYPE_RTL8821AE) {
1709 arraylength = RTL8821AEMAC_1T_ARRAYLEN;
1710 ptrarray = RTL8821AE_MAC_REG_ARRAY;
1711 } else {
1712 arraylength = RTL8812AEMAC_1T_ARRAYLEN;
1713 ptrarray = RTL8812AE_MAC_REG_ARRAY;
1714 }
1715 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
1716 "Img: MAC_REG_ARRAY LEN %d\n", arraylength);
1717 for (i = 0; i < arraylength; i += 2) {
1718 v1 = ptrarray[i];
1719 v2 = (u8)ptrarray[i + 1];
1720 if (v1 < 0xCDCDCDCD) {
1721 rtl_write_byte(rtlpriv, v1, (u8)v2);
1722 continue;
1723 } else {
1724 if (!_rtl8821ae_check_condition(hw, v1)) {
1725 /*Discard the following (offset, data) pairs*/
1726 READ_NEXT_PAIR(ptrarray, v1, v2, i);
1727 while (v2 != 0xDEAD &&
1728 v2 != 0xCDEF &&
1729 v2 != 0xCDCD && i < arraylength - 2) {
1730 READ_NEXT_PAIR(ptrarray, v1, v2, i);
1731 }
1732 i -= 2; /* prevent from for-loop += 2*/
1733 } else {/*Configure matched pairs and skip to end of if-else.*/
1734 READ_NEXT_PAIR(ptrarray, v1, v2, i);
1735 while (v2 != 0xDEAD &&
1736 v2 != 0xCDEF &&
1737 v2 != 0xCDCD && i < arraylength - 2) {
1738 rtl_write_byte(rtlpriv, v1, v2);
1739 READ_NEXT_PAIR(ptrarray, v1, v2, i);
1740 }
1741
1742 while (v2 != 0xDEAD && i < arraylength - 2)
1743 READ_NEXT_PAIR(ptrarray, v1, v2, i);
1744 }
1745 }
1746 }
1747 return true;
1748}
1749
1750static bool _rtl8821ae_phy_config_bb_with_headerfile(struct ieee80211_hw *hw,
1751 u8 configtype)
1752{
1753 struct rtl_priv *rtlpriv = rtl_priv(hw);
1754 struct rtl_hal *rtlhal = rtl_hal(rtlpriv);
1755 int i;
1756 u32 *array_table;
1757 u16 arraylen;
1758 u32 v1 = 0, v2 = 0;
1759
1760 if (configtype == BASEBAND_CONFIG_PHY_REG) {
1761 if (rtlhal->hw_type == HARDWARE_TYPE_RTL8812AE) {
1762 arraylen = RTL8812AEPHY_REG_1TARRAYLEN;
1763 array_table = RTL8812AE_PHY_REG_ARRAY;
1764 } else {
1765 arraylen = RTL8821AEPHY_REG_1TARRAYLEN;
1766 array_table = RTL8821AE_PHY_REG_ARRAY;
1767 }
1768
1769 for (i = 0; i < arraylen; i += 2) {
1770 v1 = array_table[i];
1771 v2 = array_table[i + 1];
1772 if (v1 < 0xCDCDCDCD) {
1773 _rtl8821ae_config_bb_reg(hw, v1, v2);
1774 continue;
1775 } else {/*This line is the start line of branch.*/
1776 if (!_rtl8821ae_check_condition(hw, v1)) {
1777 /*Discard the following (offset, data) pairs*/
1778 READ_NEXT_PAIR(array_table, v1, v2, i);
1779 while (v2 != 0xDEAD &&
1780 v2 != 0xCDEF &&
1781 v2 != 0xCDCD &&
1782 i < arraylen - 2) {
1783 READ_NEXT_PAIR(array_table, v1,
1784 v2, i);
1785 }
1786
1787 i -= 2; /* prevent from for-loop += 2*/
1788 } else {/*Configure matched pairs and skip to end of if-else.*/
1789 READ_NEXT_PAIR(array_table, v1, v2, i);
1790 while (v2 != 0xDEAD &&
1791 v2 != 0xCDEF &&
1792 v2 != 0xCDCD &&
1793 i < arraylen - 2) {
1794 _rtl8821ae_config_bb_reg(hw, v1,
1795 v2);
1796 READ_NEXT_PAIR(array_table, v1,
1797 v2, i);
1798 }
1799
1800 while (v2 != 0xDEAD &&
1801 i < arraylen - 2) {
1802 READ_NEXT_PAIR(array_table, v1,
1803 v2, i);
1804 }
1805 }
1806 }
1807 }
1808 } else if (configtype == BASEBAND_CONFIG_AGC_TAB) {
1809 if (rtlhal->hw_type == HARDWARE_TYPE_RTL8812AE) {
1810 arraylen = RTL8812AEAGCTAB_1TARRAYLEN;
1811 array_table = RTL8812AE_AGC_TAB_ARRAY;
1812 } else {
1813 arraylen = RTL8821AEAGCTAB_1TARRAYLEN;
1814 array_table = RTL8821AE_AGC_TAB_ARRAY;
1815 }
1816
1817 for (i = 0; i < arraylen; i = i + 2) {
1818 v1 = array_table[i];
1819 v2 = array_table[i+1];
1820 if (v1 < 0xCDCDCDCD) {
1821 rtl_set_bbreg(hw, v1, MASKDWORD, v2);
1822 udelay(1);
1823 continue;
1824 } else {/*This line is the start line of branch.*/
1825 if (!_rtl8821ae_check_condition(hw, v1)) {
1826 /*Discard the following (offset, data) pairs*/
1827 READ_NEXT_PAIR(array_table, v1, v2, i);
1828 while (v2 != 0xDEAD &&
1829 v2 != 0xCDEF &&
1830 v2 != 0xCDCD &&
1831 i < arraylen - 2) {
1832 READ_NEXT_PAIR(array_table, v1,
1833 v2, i);
1834 }
1835 i -= 2; /* prevent from for-loop += 2*/
1836 } else {/*Configure matched pairs and skip to end of if-else.*/
1837 READ_NEXT_PAIR(array_table, v1, v2, i);
1838 while (v2 != 0xDEAD &&
1839 v2 != 0xCDEF &&
1840 v2 != 0xCDCD &&
1841 i < arraylen - 2) {
1842 rtl_set_bbreg(hw, v1, MASKDWORD,
1843 v2);
1844 udelay(1);
1845 READ_NEXT_PAIR(array_table, v1,
1846 v2, i);
1847 }
1848
1849 while (v2 != 0xDEAD &&
1850 i < arraylen - 2) {
1851 READ_NEXT_PAIR(array_table, v1,
1852 v2, i);
1853 }
1854 }
1855 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
1856 "The agctab_array_table[0] is %x Rtl818EEPHY_REGArray[1] is %x\n",
1857 array_table[i], array_table[i + 1]);
1858 }
1859 }
1860 }
1861 return true;
1862}
1863
1864static u8 _rtl8821ae_get_rate_section_index(u32 regaddr)
1865{
1866 u8 index = 0;
1867 regaddr &= 0xFFF;
1868 if (regaddr >= 0xC20 && regaddr <= 0xC4C)
1869 index = (u8)((regaddr - 0xC20) / 4);
1870 else if (regaddr >= 0xE20 && regaddr <= 0xE4C)
1871 index = (u8)((regaddr - 0xE20) / 4);
1872 else
1873 RT_ASSERT(!COMP_INIT,
1874 "Invalid RegAddr 0x%x\n", regaddr);
1875 return index;
1876}
1877
1878static void _rtl8821ae_store_tx_power_by_rate(struct ieee80211_hw *hw,
1879 u32 band, u32 rfpath,
1880 u32 txnum, u32 regaddr,
1881 u32 bitmask, u32 data)
1882{
1883 struct rtl_priv *rtlpriv = rtl_priv(hw);
1884 struct rtl_phy *rtlphy = &rtlpriv->phy;
1885 u8 rate_section = _rtl8821ae_get_rate_section_index(regaddr);
1886
d514aefb 1887 if (band != BAND_ON_2_4G && band != BAND_ON_5G) {
21e4b072 1888 RT_TRACE(rtlpriv, COMP_INIT, DBG_WARNING, "Invalid Band %d\n", band);
d514aefb
LF
1889 band = BAND_ON_2_4G;
1890 }
1891 if (rfpath >= MAX_RF_PATH) {
21e4b072 1892 RT_TRACE(rtlpriv, COMP_INIT, DBG_WARNING, "Invalid RfPath %d\n", rfpath);
d514aefb
LF
1893 rfpath = MAX_RF_PATH - 1;
1894 }
1895 if (txnum >= MAX_RF_PATH) {
21e4b072 1896 RT_TRACE(rtlpriv, COMP_INIT, DBG_WARNING, "Invalid TxNum %d\n", txnum);
d514aefb
LF
1897 txnum = MAX_RF_PATH - 1;
1898 }
21e4b072
LF
1899 rtlphy->tx_power_by_rate_offset[band][rfpath][txnum][rate_section] = data;
1900 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
1901 "TxPwrByRateOffset[Band %d][RfPath %d][TxNum %d][RateSection %d] = 0x%x\n",
1902 band, rfpath, txnum, rate_section,
1903 rtlphy->tx_power_by_rate_offset[band][rfpath][txnum][rate_section]);
1904}
1905
1906static bool _rtl8821ae_phy_config_bb_with_pgheaderfile(struct ieee80211_hw *hw,
1907 u8 configtype)
1908{
1909 struct rtl_priv *rtlpriv = rtl_priv(hw);
1910 struct rtl_hal *rtlhal = rtl_hal(rtlpriv);
1911 int i;
1912 u32 *array;
1913 u16 arraylen;
1914 u32 v1, v2, v3, v4, v5, v6;
1915
1916 if (rtlhal->hw_type == HARDWARE_TYPE_RTL8812AE) {
1917 arraylen = RTL8812AEPHY_REG_ARRAY_PGLEN;
1918 array = RTL8812AE_PHY_REG_ARRAY_PG;
1919 } else {
1920 arraylen = RTL8821AEPHY_REG_ARRAY_PGLEN;
1921 array = RTL8821AE_PHY_REG_ARRAY_PG;
1922 }
1923
1924 if (configtype != BASEBAND_CONFIG_PHY_REG) {
1925 RT_TRACE(rtlpriv, COMP_SEND, DBG_TRACE,
1926 "configtype != BaseBand_Config_PHY_REG\n");
1927 return true;
1928 }
1929 for (i = 0; i < arraylen; i += 6) {
1930 v1 = array[i];
1931 v2 = array[i+1];
1932 v3 = array[i+2];
1933 v4 = array[i+3];
1934 v5 = array[i+4];
1935 v6 = array[i+5];
1936
1937 if (v1 < 0xCDCDCDCD) {
1938 if (rtlhal->hw_type == HARDWARE_TYPE_RTL8812AE &&
1939 (v4 == 0xfe || v4 == 0xffe)) {
1940 msleep(50);
1941 continue;
1942 }
1943
1944 if (rtlhal->hw_type == HARDWARE_TYPE_RTL8821AE) {
1945 if (v4 == 0xfe)
1946 msleep(50);
1947 else if (v4 == 0xfd)
1948 mdelay(5);
1949 else if (v4 == 0xfc)
1950 mdelay(1);
1951 else if (v4 == 0xfb)
1952 udelay(50);
1953 else if (v4 == 0xfa)
1954 udelay(5);
1955 else if (v4 == 0xf9)
1956 udelay(1);
1957 }
1958 _rtl8821ae_store_tx_power_by_rate(hw, v1, v2, v3,
1959 v4, v5, v6);
1960 continue;
1961 } else {
1962 /*don't need the hw_body*/
1963 if (!_rtl8821ae_check_condition(hw, v1)) {
1964 i += 2; /* skip the pair of expression*/
1965 v1 = array[i];
1966 v2 = array[i+1];
1967 v3 = array[i+2];
1968 while (v2 != 0xDEAD) {
1969 i += 3;
1970 v1 = array[i];
1971 v2 = array[i+1];
1972 v3 = array[i+2];
1973 }
1974 }
1975 }
1976 }
1977
1978 return true;
1979}
1980
1981bool rtl8812ae_phy_config_rf_with_headerfile(struct ieee80211_hw *hw,
1982 enum radio_path rfpath)
1983{
1984 int i;
1985 bool rtstatus = true;
1986 u32 *radioa_array_table_a, *radioa_array_table_b;
1987 u16 radioa_arraylen_a, radioa_arraylen_b;
1988 struct rtl_priv *rtlpriv = rtl_priv(hw);
1989 u32 v1 = 0, v2 = 0;
1990
1991 radioa_arraylen_a = RTL8812AE_RADIOA_1TARRAYLEN;
1992 radioa_array_table_a = RTL8812AE_RADIOA_ARRAY;
1993 radioa_arraylen_b = RTL8812AE_RADIOB_1TARRAYLEN;
1994 radioa_array_table_b = RTL8812AE_RADIOB_ARRAY;
1995 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
1996 "Radio_A:RTL8821AE_RADIOA_ARRAY %d\n", radioa_arraylen_a);
1997 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "Radio No %x\n", rfpath);
1998 rtstatus = true;
1999 switch (rfpath) {
2000 case RF90_PATH_A:
2001 for (i = 0; i < radioa_arraylen_a; i = i + 2) {
2002 v1 = radioa_array_table_a[i];
2003 v2 = radioa_array_table_a[i+1];
2004 if (v1 < 0xcdcdcdcd) {
2005 _rtl8821ae_config_rf_radio_a(hw, v1, v2);
2006 continue;
2007 } else{/*This line is the start line of branch.*/
2008 if (!_rtl8821ae_check_condition(hw, v1)) {
2009 /*Discard the following (offset, data) pairs*/
2010 READ_NEXT_PAIR(radioa_array_table_a, v1, v2, i);
2011 while (v2 != 0xDEAD &&
2012 v2 != 0xCDEF &&
2013 v2 != 0xCDCD && i < radioa_arraylen_a-2)
2014 READ_NEXT_PAIR(radioa_array_table_a, v1, v2, i);
2015
2016 i -= 2; /* prevent from for-loop += 2*/
2017 } else {/*Configure matched pairs and skip to end of if-else.*/
2018 READ_NEXT_PAIR(radioa_array_table_a, v1, v2, i);
2019 while (v2 != 0xDEAD &&
2020 v2 != 0xCDEF &&
2021 v2 != 0xCDCD && i < radioa_arraylen_a - 2) {
2022 _rtl8821ae_config_rf_radio_a(hw, v1, v2);
2023 READ_NEXT_PAIR(radioa_array_table_a, v1, v2, i);
2024 }
2025
2026 while (v2 != 0xDEAD && i < radioa_arraylen_a-2)
2027 READ_NEXT_PAIR(radioa_array_table_a, v1, v2, i);
2028
2029 }
2030 }
2031 }
2032 break;
2033 case RF90_PATH_B:
2034 for (i = 0; i < radioa_arraylen_b; i = i + 2) {
2035 v1 = radioa_array_table_b[i];
2036 v2 = radioa_array_table_b[i+1];
2037 if (v1 < 0xcdcdcdcd) {
2038 _rtl8821ae_config_rf_radio_b(hw, v1, v2);
2039 continue;
2040 } else{/*This line is the start line of branch.*/
2041 if (!_rtl8821ae_check_condition(hw, v1)) {
2042 /*Discard the following (offset, data) pairs*/
2043 READ_NEXT_PAIR(radioa_array_table_b, v1, v2, i);
2044 while (v2 != 0xDEAD &&
2045 v2 != 0xCDEF &&
2046 v2 != 0xCDCD && i < radioa_arraylen_b-2)
2047 READ_NEXT_PAIR(radioa_array_table_b, v1, v2, i);
2048
2049 i -= 2; /* prevent from for-loop += 2*/
2050 } else {/*Configure matched pairs and skip to end of if-else.*/
2051 READ_NEXT_PAIR(radioa_array_table_b, v1, v2, i);
2052 while (v2 != 0xDEAD &&
2053 v2 != 0xCDEF &&
2054 v2 != 0xCDCD && i < radioa_arraylen_b-2) {
2055 _rtl8821ae_config_rf_radio_b(hw, v1, v2);
2056 READ_NEXT_PAIR(radioa_array_table_b, v1, v2, i);
2057 }
2058
2059 while (v2 != 0xDEAD && i < radioa_arraylen_b-2)
2060 READ_NEXT_PAIR(radioa_array_table_b, v1, v2, i);
2061 }
2062 }
2063 }
2064 break;
2065 case RF90_PATH_C:
2066 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
2067 "switch case not process\n");
2068 break;
2069 case RF90_PATH_D:
2070 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
2071 "switch case not process\n");
2072 break;
2073 }
2074 return true;
2075}
2076
2077bool rtl8821ae_phy_config_rf_with_headerfile(struct ieee80211_hw *hw,
2078 enum radio_path rfpath)
2079{
2080 #define READ_NEXT_RF_PAIR(v1, v2, i) \
2081 do { \
2082 i += 2; \
2083 v1 = radioa_array_table[i]; \
2084 v2 = radioa_array_table[i+1]; \
2085 } \
2086 while (0)
2087
2088 int i;
2089 bool rtstatus = true;
2090 u32 *radioa_array_table;
2091 u16 radioa_arraylen;
2092 struct rtl_priv *rtlpriv = rtl_priv(hw);
2093 /* struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); */
2094 u32 v1 = 0, v2 = 0;
2095
2096 radioa_arraylen = RTL8821AE_RADIOA_1TARRAYLEN;
2097 radioa_array_table = RTL8821AE_RADIOA_ARRAY;
2098 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
2099 "Radio_A:RTL8821AE_RADIOA_ARRAY %d\n", radioa_arraylen);
2100 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "Radio No %x\n", rfpath);
2101 rtstatus = true;
2102 switch (rfpath) {
2103 case RF90_PATH_A:
2104 for (i = 0; i < radioa_arraylen; i = i + 2) {
2105 v1 = radioa_array_table[i];
2106 v2 = radioa_array_table[i+1];
2107 if (v1 < 0xcdcdcdcd)
2108 _rtl8821ae_config_rf_radio_a(hw, v1, v2);
2109 else{/*This line is the start line of branch.*/
2110 if (!_rtl8821ae_check_condition(hw, v1)) {
2111 /*Discard the following (offset, data) pairs*/
2112 READ_NEXT_RF_PAIR(v1, v2, i);
2113 while (v2 != 0xDEAD &&
2114 v2 != 0xCDEF &&
2115 v2 != 0xCDCD && i < radioa_arraylen - 2)
2116 READ_NEXT_RF_PAIR(v1, v2, i);
2117
2118 i -= 2; /* prevent from for-loop += 2*/
2119 } else {/*Configure matched pairs and skip to end of if-else.*/
2120 READ_NEXT_RF_PAIR(v1, v2, i);
2121 while (v2 != 0xDEAD &&
2122 v2 != 0xCDEF &&
2123 v2 != 0xCDCD && i < radioa_arraylen - 2) {
2124 _rtl8821ae_config_rf_radio_a(hw, v1, v2);
2125 READ_NEXT_RF_PAIR(v1, v2, i);
2126 }
2127
2128 while (v2 != 0xDEAD && i < radioa_arraylen - 2)
2129 READ_NEXT_RF_PAIR(v1, v2, i);
2130 }
2131 }
2132 }
2133 break;
2134
2135 case RF90_PATH_B:
2136 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
2137 "switch case not process\n");
2138 break;
2139 case RF90_PATH_C:
2140 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
2141 "switch case not process\n");
2142 break;
2143 case RF90_PATH_D:
2144 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
2145 "switch case not process\n");
2146 break;
2147 }
2148 return true;
2149}
2150
2151void rtl8821ae_phy_get_hw_reg_originalvalue(struct ieee80211_hw *hw)
2152{
2153 struct rtl_priv *rtlpriv = rtl_priv(hw);
2154 struct rtl_phy *rtlphy = &rtlpriv->phy;
2155
2156 rtlphy->default_initialgain[0] =
2157 (u8)rtl_get_bbreg(hw, ROFDM0_XAAGCCORE1, MASKBYTE0);
2158 rtlphy->default_initialgain[1] =
2159 (u8)rtl_get_bbreg(hw, ROFDM0_XBAGCCORE1, MASKBYTE0);
2160 rtlphy->default_initialgain[2] =
2161 (u8)rtl_get_bbreg(hw, ROFDM0_XCAGCCORE1, MASKBYTE0);
2162 rtlphy->default_initialgain[3] =
2163 (u8)rtl_get_bbreg(hw, ROFDM0_XDAGCCORE1, MASKBYTE0);
2164
2165 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
2166 "Default initial gain (c50=0x%x, c58=0x%x, c60=0x%x, c68=0x%x\n",
2167 rtlphy->default_initialgain[0],
2168 rtlphy->default_initialgain[1],
2169 rtlphy->default_initialgain[2],
2170 rtlphy->default_initialgain[3]);
2171
2172 rtlphy->framesync = (u8)rtl_get_bbreg(hw,
2173 ROFDM0_RXDETECTOR3, MASKBYTE0);
2174 rtlphy->framesync_c34 = rtl_get_bbreg(hw,
2175 ROFDM0_RXDETECTOR2, MASKDWORD);
2176
2177 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
2178 "Default framesync (0x%x) = 0x%x\n",
2179 ROFDM0_RXDETECTOR3, rtlphy->framesync);
2180}
2181
2182static void phy_init_bb_rf_register_definition(struct ieee80211_hw *hw)
2183{
2184 struct rtl_priv *rtlpriv = rtl_priv(hw);
2185 struct rtl_phy *rtlphy = &rtlpriv->phy;
2186
2187 rtlphy->phyreg_def[RF90_PATH_A].rfintfs = RFPGA0_XAB_RFINTERFACESW;
2188 rtlphy->phyreg_def[RF90_PATH_B].rfintfs = RFPGA0_XAB_RFINTERFACESW;
2189
2190 rtlphy->phyreg_def[RF90_PATH_A].rfintfo = RFPGA0_XA_RFINTERFACEOE;
2191 rtlphy->phyreg_def[RF90_PATH_B].rfintfo = RFPGA0_XB_RFINTERFACEOE;
2192
2193 rtlphy->phyreg_def[RF90_PATH_A].rfintfe = RFPGA0_XA_RFINTERFACEOE;
2194 rtlphy->phyreg_def[RF90_PATH_B].rfintfe = RFPGA0_XB_RFINTERFACEOE;
2195
2196 rtlphy->phyreg_def[RF90_PATH_A].rf3wire_offset = RA_LSSIWRITE_8821A;
2197 rtlphy->phyreg_def[RF90_PATH_B].rf3wire_offset = RB_LSSIWRITE_8821A;
2198
2199 rtlphy->phyreg_def[RF90_PATH_A].rfhssi_para2 = RHSSIREAD_8821AE;
2200 rtlphy->phyreg_def[RF90_PATH_B].rfhssi_para2 = RHSSIREAD_8821AE;
2201
2202 rtlphy->phyreg_def[RF90_PATH_A].rf_rb = RA_SIREAD_8821A;
2203 rtlphy->phyreg_def[RF90_PATH_B].rf_rb = RB_SIREAD_8821A;
2204
2205 rtlphy->phyreg_def[RF90_PATH_A].rf_rbpi = RA_PIREAD_8821A;
2206 rtlphy->phyreg_def[RF90_PATH_B].rf_rbpi = RB_PIREAD_8821A;
2207}
2208
2209void rtl8821ae_phy_get_txpower_level(struct ieee80211_hw *hw, long *powerlevel)
2210{
2211 struct rtl_priv *rtlpriv = rtl_priv(hw);
2212 struct rtl_phy *rtlphy = &rtlpriv->phy;
2213 u8 txpwr_level;
2214 long txpwr_dbm;
2215
2216 txpwr_level = rtlphy->cur_cck_txpwridx;
2217 txpwr_dbm = _rtl8821ae_phy_txpwr_idx_to_dbm(hw,
2218 WIRELESS_MODE_B, txpwr_level);
2219 txpwr_level = rtlphy->cur_ofdm24g_txpwridx;
2220 if (_rtl8821ae_phy_txpwr_idx_to_dbm(hw,
2221 WIRELESS_MODE_G,
2222 txpwr_level) > txpwr_dbm)
2223 txpwr_dbm =
2224 _rtl8821ae_phy_txpwr_idx_to_dbm(hw, WIRELESS_MODE_G,
2225 txpwr_level);
2226 txpwr_level = rtlphy->cur_ofdm24g_txpwridx;
2227 if (_rtl8821ae_phy_txpwr_idx_to_dbm(hw,
2228 WIRELESS_MODE_N_24G,
2229 txpwr_level) > txpwr_dbm)
2230 txpwr_dbm =
2231 _rtl8821ae_phy_txpwr_idx_to_dbm(hw, WIRELESS_MODE_N_24G,
2232 txpwr_level);
2233 *powerlevel = txpwr_dbm;
2234}
2235
2236static bool _rtl8821ae_phy_get_chnl_index(u8 channel, u8 *chnl_index)
2237{
21e4b072
LF
2238 u8 i = 0;
2239 bool in_24g = true;
2240
2241 if (channel <= 14) {
2242 in_24g = true;
2243 *chnl_index = channel - 1;
2244 } else {
2245 in_24g = false;
2246
2247 for (i = 0; i < CHANNEL_MAX_NUMBER_5G; ++i) {
0a44b220 2248 if (channel5g[i] == channel) {
21e4b072
LF
2249 *chnl_index = i;
2250 return in_24g;
2251 }
2252 }
2253 }
2254 return in_24g;
2255}
2256
08aba42f 2257static s8 _rtl8821ae_phy_get_ratesection_intxpower_byrate(u8 path, u8 rate)
21e4b072 2258{
08aba42f 2259 s8 rate_section = 0;
21e4b072
LF
2260 switch (rate) {
2261 case DESC_RATE1M:
2262 case DESC_RATE2M:
2263 case DESC_RATE5_5M:
2264 case DESC_RATE11M:
2265 rate_section = 0;
2266 break;
2267 case DESC_RATE6M:
2268 case DESC_RATE9M:
2269 case DESC_RATE12M:
2270 case DESC_RATE18M:
2271 rate_section = 1;
2272 break;
2273 case DESC_RATE24M:
2274 case DESC_RATE36M:
2275 case DESC_RATE48M:
2276 case DESC_RATE54M:
2277 rate_section = 2;
2278 break;
2279 case DESC_RATEMCS0:
2280 case DESC_RATEMCS1:
2281 case DESC_RATEMCS2:
2282 case DESC_RATEMCS3:
2283 rate_section = 3;
2284 break;
2285 case DESC_RATEMCS4:
2286 case DESC_RATEMCS5:
2287 case DESC_RATEMCS6:
2288 case DESC_RATEMCS7:
2289 rate_section = 4;
2290 break;
2291 case DESC_RATEMCS8:
2292 case DESC_RATEMCS9:
2293 case DESC_RATEMCS10:
2294 case DESC_RATEMCS11:
2295 rate_section = 5;
2296 break;
2297 case DESC_RATEMCS12:
2298 case DESC_RATEMCS13:
2299 case DESC_RATEMCS14:
2300 case DESC_RATEMCS15:
2301 rate_section = 6;
2302 break;
2303 case DESC_RATEVHT1SS_MCS0:
2304 case DESC_RATEVHT1SS_MCS1:
2305 case DESC_RATEVHT1SS_MCS2:
2306 case DESC_RATEVHT1SS_MCS3:
2307 rate_section = 7;
2308 break;
2309 case DESC_RATEVHT1SS_MCS4:
2310 case DESC_RATEVHT1SS_MCS5:
2311 case DESC_RATEVHT1SS_MCS6:
2312 case DESC_RATEVHT1SS_MCS7:
2313 rate_section = 8;
2314 break;
2315 case DESC_RATEVHT1SS_MCS8:
2316 case DESC_RATEVHT1SS_MCS9:
2317 case DESC_RATEVHT2SS_MCS0:
2318 case DESC_RATEVHT2SS_MCS1:
2319 rate_section = 9;
2320 break;
2321 case DESC_RATEVHT2SS_MCS2:
2322 case DESC_RATEVHT2SS_MCS3:
2323 case DESC_RATEVHT2SS_MCS4:
2324 case DESC_RATEVHT2SS_MCS5:
2325 rate_section = 10;
2326 break;
2327 case DESC_RATEVHT2SS_MCS6:
2328 case DESC_RATEVHT2SS_MCS7:
2329 case DESC_RATEVHT2SS_MCS8:
2330 case DESC_RATEVHT2SS_MCS9:
2331 rate_section = 11;
2332 break;
2333 default:
2334 RT_ASSERT(true, "Rate_Section is Illegal\n");
2335 break;
2336 }
2337
2338 return rate_section;
2339}
2340
08aba42f 2341static s8 _rtl8812ae_phy_get_world_wide_limit(s8 *limit_table)
21e4b072 2342{
08aba42f 2343 s8 min = limit_table[0];
21e4b072
LF
2344 u8 i = 0;
2345
2346 for (i = 0; i < MAX_REGULATION_NUM; ++i) {
2347 if (limit_table[i] < min)
2348 min = limit_table[i];
2349 }
2350 return min;
2351}
2352
08aba42f 2353static s8 _rtl8812ae_phy_get_txpower_limit(struct ieee80211_hw *hw,
21e4b072
LF
2354 u8 band,
2355 enum ht_channel_width bandwidth,
2356 enum radio_path rf_path,
2357 u8 rate, u8 channel)
2358{
2359 struct rtl_priv *rtlpriv = rtl_priv(hw);
2360 struct rtl_efuse *rtlefuse = rtl_efuse(rtlpriv);
2361 struct rtl_phy *rtlphy = &rtlpriv->phy;
2362 short band_temp = -1, regulation = -1, bandwidth_temp = -1,
2363 rate_section = -1, channel_temp = -1;
2364 u16 bd, regu, bdwidth, sec, chnl;
08aba42f 2365 s8 power_limit = MAX_POWER_INDEX;
21e4b072
LF
2366
2367 if (rtlefuse->eeprom_regulatory == 2)
2368 return MAX_POWER_INDEX;
2369
2370 regulation = TXPWR_LMT_WW;
2371
2372 if (band == BAND_ON_2_4G)
2373 band_temp = 0;
2374 else if (band == BAND_ON_5G)
2375 band_temp = 1;
2376
2377 if (bandwidth == HT_CHANNEL_WIDTH_20)
2378 bandwidth_temp = 0;
2379 else if (bandwidth == HT_CHANNEL_WIDTH_20_40)
2380 bandwidth_temp = 1;
2381 else if (bandwidth == HT_CHANNEL_WIDTH_80)
2382 bandwidth_temp = 2;
2383
2384 switch (rate) {
2385 case DESC_RATE1M:
2386 case DESC_RATE2M:
2387 case DESC_RATE5_5M:
2388 case DESC_RATE11M:
2389 rate_section = 0;
2390 break;
2391 case DESC_RATE6M:
2392 case DESC_RATE9M:
2393 case DESC_RATE12M:
2394 case DESC_RATE18M:
2395 case DESC_RATE24M:
2396 case DESC_RATE36M:
2397 case DESC_RATE48M:
2398 case DESC_RATE54M:
2399 rate_section = 1;
2400 break;
2401 case DESC_RATEMCS0:
2402 case DESC_RATEMCS1:
2403 case DESC_RATEMCS2:
2404 case DESC_RATEMCS3:
2405 case DESC_RATEMCS4:
2406 case DESC_RATEMCS5:
2407 case DESC_RATEMCS6:
2408 case DESC_RATEMCS7:
2409 rate_section = 2;
2410 break;
2411 case DESC_RATEMCS8:
2412 case DESC_RATEMCS9:
2413 case DESC_RATEMCS10:
2414 case DESC_RATEMCS11:
2415 case DESC_RATEMCS12:
2416 case DESC_RATEMCS13:
2417 case DESC_RATEMCS14:
2418 case DESC_RATEMCS15:
2419 rate_section = 3;
2420 break;
2421 case DESC_RATEVHT1SS_MCS0:
2422 case DESC_RATEVHT1SS_MCS1:
2423 case DESC_RATEVHT1SS_MCS2:
2424 case DESC_RATEVHT1SS_MCS3:
2425 case DESC_RATEVHT1SS_MCS4:
2426 case DESC_RATEVHT1SS_MCS5:
2427 case DESC_RATEVHT1SS_MCS6:
2428 case DESC_RATEVHT1SS_MCS7:
2429 case DESC_RATEVHT1SS_MCS8:
2430 case DESC_RATEVHT1SS_MCS9:
2431 rate_section = 4;
2432 break;
2433 case DESC_RATEVHT2SS_MCS0:
2434 case DESC_RATEVHT2SS_MCS1:
2435 case DESC_RATEVHT2SS_MCS2:
2436 case DESC_RATEVHT2SS_MCS3:
2437 case DESC_RATEVHT2SS_MCS4:
2438 case DESC_RATEVHT2SS_MCS5:
2439 case DESC_RATEVHT2SS_MCS6:
2440 case DESC_RATEVHT2SS_MCS7:
2441 case DESC_RATEVHT2SS_MCS8:
2442 case DESC_RATEVHT2SS_MCS9:
2443 rate_section = 5;
2444 break;
2445 default:
2446 RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
2447 "Wrong rate 0x%x\n", rate);
2448 break;
2449 }
2450
2451 if (band_temp == BAND_ON_5G && rate_section == 0)
2452 RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
2453 "Wrong rate 0x%x: No CCK in 5G Band\n", rate);
2454
2455 /*workaround for wrong index combination to obtain tx power limit,
2456 OFDM only exists in BW 20M*/
2457 if (rate_section == 1)
2458 bandwidth_temp = 0;
2459
2460 /*workaround for wrong index combination to obtain tx power limit,
2461 *HT on 80M will reference to HT on 40M
2462 */
2463 if ((rate_section == 2 || rate_section == 3) && band == BAND_ON_5G &&
2464 bandwidth_temp == 2)
2465 bandwidth_temp = 1;
2466
2467 if (band == BAND_ON_2_4G)
2468 channel_temp = _rtl8812ae_phy_get_chnl_idx_of_txpwr_lmt(hw,
2469 BAND_ON_2_4G, channel);
2470 else if (band == BAND_ON_5G)
2471 channel_temp = _rtl8812ae_phy_get_chnl_idx_of_txpwr_lmt(hw,
2472 BAND_ON_5G, channel);
2473 else if (band == BAND_ON_BOTH)
2474 ;/* BAND_ON_BOTH don't care temporarily */
2475
2476 if (band_temp == -1 || regulation == -1 || bandwidth_temp == -1 ||
2477 rate_section == -1 || channel_temp == -1) {
2478 RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
2479 "Wrong index value to access power limit table [band %d][regulation %d][bandwidth %d][rf_path %d][rate_section %d][chnl %d]\n",
2480 band_temp, regulation, bandwidth_temp, rf_path,
2481 rate_section, channel_temp);
2482 return MAX_POWER_INDEX;
2483 }
2484
2485 bd = band_temp;
2486 regu = regulation;
2487 bdwidth = bandwidth_temp;
2488 sec = rate_section;
2489 chnl = channel_temp;
2490
2491 if (band == BAND_ON_2_4G) {
08aba42f 2492 s8 limits[10] = {0};
21e4b072
LF
2493 u8 i;
2494
2495 for (i = 0; i < 4; ++i)
2496 limits[i] = rtlphy->txpwr_limit_2_4g[i][bdwidth]
2497 [sec][chnl][rf_path];
2498
2499 power_limit = (regulation == TXPWR_LMT_WW) ?
2500 _rtl8812ae_phy_get_world_wide_limit(limits) :
2501 rtlphy->txpwr_limit_2_4g[regu][bdwidth]
2502 [sec][chnl][rf_path];
2503 } else if (band == BAND_ON_5G) {
08aba42f 2504 s8 limits[10] = {0};
21e4b072
LF
2505 u8 i;
2506
2507 for (i = 0; i < MAX_REGULATION_NUM; ++i)
2508 limits[i] = rtlphy->txpwr_limit_5g[i][bdwidth]
2509 [sec][chnl][rf_path];
2510
2511 power_limit = (regulation == TXPWR_LMT_WW) ?
2512 _rtl8812ae_phy_get_world_wide_limit(limits) :
2513 rtlphy->txpwr_limit_5g[regu][chnl]
2514 [sec][chnl][rf_path];
2515 } else {
2516 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
2517 "No power limit table of the specified band\n");
2518 }
2519 return power_limit;
2520}
2521
08aba42f 2522static s8 _rtl8821ae_phy_get_txpower_by_rate(struct ieee80211_hw *hw,
21e4b072
LF
2523 u8 band, u8 path, u8 rate)
2524{
2525 struct rtl_priv *rtlpriv = rtl_priv(hw);
2526 struct rtl_phy *rtlphy = &rtlpriv->phy;
2527 u8 shift = 0, rate_section, tx_num;
08aba42f
AB
2528 s8 tx_pwr_diff = 0;
2529 s8 limit = 0;
21e4b072
LF
2530
2531 rate_section = _rtl8821ae_phy_get_ratesection_intxpower_byrate(path, rate);
2532 tx_num = RF_TX_NUM_NONIMPLEMENT;
2533
2534 if (tx_num == RF_TX_NUM_NONIMPLEMENT) {
2535 if ((rate >= DESC_RATEMCS8 && rate <= DESC_RATEMCS15) ||
2536 (rate >= DESC_RATEVHT2SS_MCS2 && rate <= DESC_RATEVHT2SS_MCS9))
2537 tx_num = RF_2TX;
2538 else
2539 tx_num = RF_1TX;
2540 }
2541
2542 switch (rate) {
2543 case DESC_RATE1M:
2544 case DESC_RATE6M:
2545 case DESC_RATE24M:
2546 case DESC_RATEMCS0:
2547 case DESC_RATEMCS4:
2548 case DESC_RATEMCS8:
2549 case DESC_RATEMCS12:
2550 case DESC_RATEVHT1SS_MCS0:
2551 case DESC_RATEVHT1SS_MCS4:
2552 case DESC_RATEVHT1SS_MCS8:
2553 case DESC_RATEVHT2SS_MCS2:
2554 case DESC_RATEVHT2SS_MCS6:
2555 shift = 0;
2556 break;
2557 case DESC_RATE2M:
2558 case DESC_RATE9M:
2559 case DESC_RATE36M:
2560 case DESC_RATEMCS1:
2561 case DESC_RATEMCS5:
2562 case DESC_RATEMCS9:
2563 case DESC_RATEMCS13:
2564 case DESC_RATEVHT1SS_MCS1:
2565 case DESC_RATEVHT1SS_MCS5:
2566 case DESC_RATEVHT1SS_MCS9:
2567 case DESC_RATEVHT2SS_MCS3:
2568 case DESC_RATEVHT2SS_MCS7:
2569 shift = 8;
2570 break;
2571 case DESC_RATE5_5M:
2572 case DESC_RATE12M:
2573 case DESC_RATE48M:
2574 case DESC_RATEMCS2:
2575 case DESC_RATEMCS6:
2576 case DESC_RATEMCS10:
2577 case DESC_RATEMCS14:
2578 case DESC_RATEVHT1SS_MCS2:
2579 case DESC_RATEVHT1SS_MCS6:
2580 case DESC_RATEVHT2SS_MCS0:
2581 case DESC_RATEVHT2SS_MCS4:
2582 case DESC_RATEVHT2SS_MCS8:
2583 shift = 16;
2584 break;
2585 case DESC_RATE11M:
2586 case DESC_RATE18M:
2587 case DESC_RATE54M:
2588 case DESC_RATEMCS3:
2589 case DESC_RATEMCS7:
2590 case DESC_RATEMCS11:
2591 case DESC_RATEMCS15:
2592 case DESC_RATEVHT1SS_MCS3:
2593 case DESC_RATEVHT1SS_MCS7:
2594 case DESC_RATEVHT2SS_MCS1:
2595 case DESC_RATEVHT2SS_MCS5:
2596 case DESC_RATEVHT2SS_MCS9:
2597 shift = 24;
2598 break;
2599 default:
2600 RT_ASSERT(true, "Rate_Section is Illegal\n");
2601 break;
2602 }
2603
2604 tx_pwr_diff = (u8)(rtlphy->tx_power_by_rate_offset[band][path]
2605 [tx_num][rate_section] >> shift) & 0xff;
2606
2607 /* RegEnableTxPowerLimit == 1 for 8812a & 8821a */
2608 if (rtlpriv->efuse.eeprom_regulatory != 2) {
2609 limit = _rtl8812ae_phy_get_txpower_limit(hw, band,
2610 rtlphy->current_chan_bw, path, rate,
2611 rtlphy->current_channel);
2612
2613 if (rate == DESC_RATEVHT1SS_MCS8 || rate == DESC_RATEVHT1SS_MCS9 ||
2614 rate == DESC_RATEVHT2SS_MCS8 || rate == DESC_RATEVHT2SS_MCS9) {
2615 if (limit < 0) {
2616 if (tx_pwr_diff < (-limit))
2617 tx_pwr_diff = -limit;
2618 }
2619 } else {
2620 if (limit < 0)
2621 tx_pwr_diff = limit;
2622 else
2623 tx_pwr_diff = tx_pwr_diff > limit ? limit : tx_pwr_diff;
2624 }
2625 RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
2626 "Maximum power by rate %d, final power by rate %d\n",
2627 limit, tx_pwr_diff);
2628 }
2629
2630 return tx_pwr_diff;
2631}
2632
2633static u8 _rtl8821ae_get_txpower_index(struct ieee80211_hw *hw, u8 path,
2634 u8 rate, u8 bandwidth, u8 channel)
2635{
2636 struct rtl_priv *rtlpriv = rtl_priv(hw);
2637 struct rtl_hal *rtlhal = rtl_hal(rtlpriv);
2638 struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
2639 u8 index = (channel - 1);
2640 u8 txpower = 0;
2641 bool in_24g = false;
08aba42f 2642 s8 powerdiff_byrate = 0;
21e4b072
LF
2643
2644 if (((rtlhal->current_bandtype == BAND_ON_2_4G) &&
2645 (channel > 14 || channel < 1)) ||
2646 ((rtlhal->current_bandtype == BAND_ON_5G) && (channel <= 14))) {
2647 index = 0;
2648 RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
2649 "Illegal channel!!\n");
2650 }
2651
2652 in_24g = _rtl8821ae_phy_get_chnl_index(channel, &index);
2653 if (in_24g) {
2654 if (RTL8821AE_RX_HAL_IS_CCK_RATE(rate))
2655 txpower = rtlefuse->txpwrlevel_cck[path][index];
2656 else if (DESC_RATE6M <= rate)
2657 txpower = rtlefuse->txpwrlevel_ht40_1s[path][index];
2658 else
2659 RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, "invalid rate\n");
2660
2661 if (DESC_RATE6M <= rate && rate <= DESC_RATE54M &&
2662 !RTL8821AE_RX_HAL_IS_CCK_RATE(rate))
2663 txpower += rtlefuse->txpwr_legacyhtdiff[path][TX_1S];
2664
2665 if (bandwidth == HT_CHANNEL_WIDTH_20) {
2666 if ((DESC_RATEMCS0 <= rate && rate <= DESC_RATEMCS15) ||
2667 (DESC_RATEVHT1SS_MCS0 <= rate && rate <= DESC_RATEVHT2SS_MCS9))
2668 txpower += rtlefuse->txpwr_ht20diff[path][TX_1S];
2669 if ((DESC_RATEMCS8 <= rate && rate <= DESC_RATEMCS15) ||
2670 (DESC_RATEVHT2SS_MCS0 <= rate && rate <= DESC_RATEVHT2SS_MCS9))
2671 txpower += rtlefuse->txpwr_ht20diff[path][TX_2S];
2672 } else if (bandwidth == HT_CHANNEL_WIDTH_20_40) {
2673 if ((DESC_RATEMCS0 <= rate && rate <= DESC_RATEMCS15) ||
2674 (DESC_RATEVHT1SS_MCS0 <= rate && rate <= DESC_RATEVHT2SS_MCS9))
2675 txpower += rtlefuse->txpwr_ht40diff[path][TX_1S];
2676 if ((DESC_RATEMCS8 <= rate && rate <= DESC_RATEMCS15) ||
2677 (DESC_RATEVHT2SS_MCS0 <= rate && rate <= DESC_RATEVHT2SS_MCS9))
2678 txpower += rtlefuse->txpwr_ht40diff[path][TX_2S];
2679 } else if (bandwidth == HT_CHANNEL_WIDTH_80) {
2680 if ((DESC_RATEMCS0 <= rate && rate <= DESC_RATEMCS15) ||
2681 (DESC_RATEVHT1SS_MCS0 <= rate &&
2682 rate <= DESC_RATEVHT2SS_MCS9))
2683 txpower += rtlefuse->txpwr_ht40diff[path][TX_1S];
2684 if ((DESC_RATEMCS8 <= rate && rate <= DESC_RATEMCS15) ||
2685 (DESC_RATEVHT2SS_MCS0 <= rate &&
2686 rate <= DESC_RATEVHT2SS_MCS9))
2687 txpower += rtlefuse->txpwr_ht40diff[path][TX_2S];
2688 }
2689 } else {
2690 if (DESC_RATE6M <= rate)
2691 txpower = rtlefuse->txpwr_5g_bw40base[path][index];
2692 else
2693 RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_WARNING,
2694 "INVALID Rate.\n");
2695
2696 if (DESC_RATE6M <= rate && rate <= DESC_RATE54M &&
2697 !RTL8821AE_RX_HAL_IS_CCK_RATE(rate))
2698 txpower += rtlefuse->txpwr_5g_ofdmdiff[path][TX_1S];
2699
2700 if (bandwidth == HT_CHANNEL_WIDTH_20) {
2701 if ((DESC_RATEMCS0 <= rate && rate <= DESC_RATEMCS15) ||
2702 (DESC_RATEVHT1SS_MCS0 <= rate &&
2703 rate <= DESC_RATEVHT2SS_MCS9))
2704 txpower += rtlefuse->txpwr_5g_bw20diff[path][TX_1S];
2705 if ((DESC_RATEMCS8 <= rate && rate <= DESC_RATEMCS15) ||
2706 (DESC_RATEVHT2SS_MCS0 <= rate &&
2707 rate <= DESC_RATEVHT2SS_MCS9))
2708 txpower += rtlefuse->txpwr_5g_bw20diff[path][TX_2S];
2709 } else if (bandwidth == HT_CHANNEL_WIDTH_20_40) {
2710 if ((DESC_RATEMCS0 <= rate && rate <= DESC_RATEMCS15) ||
2711 (DESC_RATEVHT1SS_MCS0 <= rate &&
2712 rate <= DESC_RATEVHT2SS_MCS9))
2713 txpower += rtlefuse->txpwr_5g_bw40diff[path][TX_1S];
2714 if ((DESC_RATEMCS8 <= rate && rate <= DESC_RATEMCS15) ||
2715 (DESC_RATEVHT2SS_MCS0 <= rate &&
2716 rate <= DESC_RATEVHT2SS_MCS9))
2717 txpower += rtlefuse->txpwr_5g_bw40diff[path][TX_2S];
2718 } else if (bandwidth == HT_CHANNEL_WIDTH_80) {
21e4b072
LF
2719 u8 i;
2720
0a44b220
LF
2721 for (i = 0; i < sizeof(channel5g_80m) / sizeof(u8); ++i)
2722 if (channel5g_80m[i] == channel)
21e4b072
LF
2723 index = i;
2724
2725 if ((DESC_RATEMCS0 <= rate && rate <= DESC_RATEMCS15) ||
2726 (DESC_RATEVHT1SS_MCS0 <= rate &&
2727 rate <= DESC_RATEVHT2SS_MCS9))
2728 txpower = rtlefuse->txpwr_5g_bw80base[path][index]
2729 + rtlefuse->txpwr_5g_bw80diff[path][TX_1S];
2730 if ((DESC_RATEMCS8 <= rate && rate <= DESC_RATEMCS15) ||
2731 (DESC_RATEVHT2SS_MCS0 <= rate &&
2732 rate <= DESC_RATEVHT2SS_MCS9))
2733 txpower = rtlefuse->txpwr_5g_bw80base[path][index]
2734 + rtlefuse->txpwr_5g_bw80diff[path][TX_1S]
2735 + rtlefuse->txpwr_5g_bw80diff[path][TX_2S];
2736 }
2737 }
2738 if (rtlefuse->eeprom_regulatory != 2)
2739 powerdiff_byrate =
2740 _rtl8821ae_phy_get_txpower_by_rate(hw, (u8)(!in_24g),
2741 path, rate);
2742
2743 if (rate == DESC_RATEVHT1SS_MCS8 || rate == DESC_RATEVHT1SS_MCS9 ||
2744 rate == DESC_RATEVHT2SS_MCS8 || rate == DESC_RATEVHT2SS_MCS9)
2745 txpower -= powerdiff_byrate;
2746 else
2747 txpower += powerdiff_byrate;
2748
2749 if (rate > DESC_RATE11M)
2750 txpower += rtlpriv->dm.remnant_ofdm_swing_idx[path];
2751 else
2752 txpower += rtlpriv->dm.remnant_cck_idx;
2753
2754 if (txpower > MAX_POWER_INDEX)
2755 txpower = MAX_POWER_INDEX;
2756
2757 return txpower;
2758}
2759
2760static void _rtl8821ae_phy_set_txpower_index(struct ieee80211_hw *hw,
2761 u8 power_index, u8 path, u8 rate)
2762{
2763 struct rtl_priv *rtlpriv = rtl_priv(hw);
2764
2765 if (path == RF90_PATH_A) {
2766 switch (rate) {
2767 case DESC_RATE1M:
2768 rtl_set_bbreg(hw, RTXAGC_A_CCK11_CCK1,
2769 MASKBYTE0, power_index);
2770 break;
2771 case DESC_RATE2M:
2772 rtl_set_bbreg(hw, RTXAGC_A_CCK11_CCK1,
2773 MASKBYTE1, power_index);
2774 break;
2775 case DESC_RATE5_5M:
2776 rtl_set_bbreg(hw, RTXAGC_A_CCK11_CCK1,
2777 MASKBYTE2, power_index);
2778 break;
2779 case DESC_RATE11M:
2780 rtl_set_bbreg(hw, RTXAGC_A_CCK11_CCK1,
2781 MASKBYTE3, power_index);
2782 break;
2783 case DESC_RATE6M:
2784 rtl_set_bbreg(hw, RTXAGC_A_OFDM18_OFDM6,
2785 MASKBYTE0, power_index);
2786 break;
2787 case DESC_RATE9M:
2788 rtl_set_bbreg(hw, RTXAGC_A_OFDM18_OFDM6,
2789 MASKBYTE1, power_index);
2790 break;
2791 case DESC_RATE12M:
2792 rtl_set_bbreg(hw, RTXAGC_A_OFDM18_OFDM6,
2793 MASKBYTE2, power_index);
2794 break;
2795 case DESC_RATE18M:
2796 rtl_set_bbreg(hw, RTXAGC_A_OFDM18_OFDM6,
2797 MASKBYTE3, power_index);
2798 break;
2799 case DESC_RATE24M:
2800 rtl_set_bbreg(hw, RTXAGC_A_OFDM54_OFDM24,
2801 MASKBYTE0, power_index);
2802 break;
2803 case DESC_RATE36M:
2804 rtl_set_bbreg(hw, RTXAGC_A_OFDM54_OFDM24,
2805 MASKBYTE1, power_index);
2806 break;
2807 case DESC_RATE48M:
2808 rtl_set_bbreg(hw, RTXAGC_A_OFDM54_OFDM24,
2809 MASKBYTE2, power_index);
2810 break;
2811 case DESC_RATE54M:
2812 rtl_set_bbreg(hw, RTXAGC_A_OFDM54_OFDM24,
2813 MASKBYTE3, power_index);
2814 break;
2815 case DESC_RATEMCS0:
2816 rtl_set_bbreg(hw, RTXAGC_A_MCS03_MCS00,
2817 MASKBYTE0, power_index);
2818 break;
2819 case DESC_RATEMCS1:
2820 rtl_set_bbreg(hw, RTXAGC_A_MCS03_MCS00,
2821 MASKBYTE1, power_index);
2822 break;
2823 case DESC_RATEMCS2:
2824 rtl_set_bbreg(hw, RTXAGC_A_MCS03_MCS00,
2825 MASKBYTE2, power_index);
2826 break;
2827 case DESC_RATEMCS3:
2828 rtl_set_bbreg(hw, RTXAGC_A_MCS03_MCS00,
2829 MASKBYTE3, power_index);
2830 break;
2831 case DESC_RATEMCS4:
2832 rtl_set_bbreg(hw, RTXAGC_A_MCS07_MCS04,
2833 MASKBYTE0, power_index);
2834 break;
2835 case DESC_RATEMCS5:
2836 rtl_set_bbreg(hw, RTXAGC_A_MCS07_MCS04,
2837 MASKBYTE1, power_index);
2838 break;
2839 case DESC_RATEMCS6:
2840 rtl_set_bbreg(hw, RTXAGC_A_MCS07_MCS04,
2841 MASKBYTE2, power_index);
2842 break;
2843 case DESC_RATEMCS7:
2844 rtl_set_bbreg(hw, RTXAGC_A_MCS07_MCS04,
2845 MASKBYTE3, power_index);
2846 break;
2847 case DESC_RATEMCS8:
2848 rtl_set_bbreg(hw, RTXAGC_A_MCS11_MCS08,
2849 MASKBYTE0, power_index);
2850 break;
2851 case DESC_RATEMCS9:
2852 rtl_set_bbreg(hw, RTXAGC_A_MCS11_MCS08,
2853 MASKBYTE1, power_index);
2854 break;
2855 case DESC_RATEMCS10:
2856 rtl_set_bbreg(hw, RTXAGC_A_MCS11_MCS08,
2857 MASKBYTE2, power_index);
2858 break;
2859 case DESC_RATEMCS11:
2860 rtl_set_bbreg(hw, RTXAGC_A_MCS11_MCS08,
2861 MASKBYTE3, power_index);
2862 break;
2863 case DESC_RATEMCS12:
2864 rtl_set_bbreg(hw, RTXAGC_A_MCS15_MCS12,
2865 MASKBYTE0, power_index);
2866 break;
2867 case DESC_RATEMCS13:
2868 rtl_set_bbreg(hw, RTXAGC_A_MCS15_MCS12,
2869 MASKBYTE1, power_index);
2870 break;
2871 case DESC_RATEMCS14:
2872 rtl_set_bbreg(hw, RTXAGC_A_MCS15_MCS12,
2873 MASKBYTE2, power_index);
2874 break;
2875 case DESC_RATEMCS15:
2876 rtl_set_bbreg(hw, RTXAGC_A_MCS15_MCS12,
2877 MASKBYTE3, power_index);
2878 break;
2879 case DESC_RATEVHT1SS_MCS0:
2880 rtl_set_bbreg(hw, RTXAGC_A_NSS1INDEX3_NSS1INDEX0,
2881 MASKBYTE0, power_index);
2882 break;
2883 case DESC_RATEVHT1SS_MCS1:
2884 rtl_set_bbreg(hw, RTXAGC_A_NSS1INDEX3_NSS1INDEX0,
2885 MASKBYTE1, power_index);
2886 break;
2887 case DESC_RATEVHT1SS_MCS2:
2888 rtl_set_bbreg(hw, RTXAGC_A_NSS1INDEX3_NSS1INDEX0,
2889 MASKBYTE2, power_index);
2890 break;
2891 case DESC_RATEVHT1SS_MCS3:
2892 rtl_set_bbreg(hw, RTXAGC_A_NSS1INDEX3_NSS1INDEX0,
2893 MASKBYTE3, power_index);
2894 break;
2895 case DESC_RATEVHT1SS_MCS4:
2896 rtl_set_bbreg(hw, RTXAGC_A_NSS1INDEX7_NSS1INDEX4,
2897 MASKBYTE0, power_index);
2898 break;
2899 case DESC_RATEVHT1SS_MCS5:
2900 rtl_set_bbreg(hw, RTXAGC_A_NSS1INDEX7_NSS1INDEX4,
2901 MASKBYTE1, power_index);
2902 break;
2903 case DESC_RATEVHT1SS_MCS6:
2904 rtl_set_bbreg(hw, RTXAGC_A_NSS1INDEX7_NSS1INDEX4,
2905 MASKBYTE2, power_index);
2906 break;
2907 case DESC_RATEVHT1SS_MCS7:
2908 rtl_set_bbreg(hw, RTXAGC_A_NSS1INDEX7_NSS1INDEX4,
2909 MASKBYTE3, power_index);
2910 break;
2911 case DESC_RATEVHT1SS_MCS8:
2912 rtl_set_bbreg(hw, RTXAGC_A_NSS2INDEX1_NSS1INDEX8,
2913 MASKBYTE0, power_index);
2914 break;
2915 case DESC_RATEVHT1SS_MCS9:
2916 rtl_set_bbreg(hw, RTXAGC_A_NSS2INDEX1_NSS1INDEX8,
2917 MASKBYTE1, power_index);
2918 break;
2919 case DESC_RATEVHT2SS_MCS0:
2920 rtl_set_bbreg(hw, RTXAGC_A_NSS2INDEX1_NSS1INDEX8,
2921 MASKBYTE2, power_index);
2922 break;
2923 case DESC_RATEVHT2SS_MCS1:
2924 rtl_set_bbreg(hw, RTXAGC_A_NSS2INDEX1_NSS1INDEX8,
2925 MASKBYTE3, power_index);
2926 break;
2927 case DESC_RATEVHT2SS_MCS2:
2928 rtl_set_bbreg(hw, RTXAGC_A_NSS2INDEX5_NSS2INDEX2,
2929 MASKBYTE0, power_index);
2930 break;
2931 case DESC_RATEVHT2SS_MCS3:
2932 rtl_set_bbreg(hw, RTXAGC_A_NSS2INDEX5_NSS2INDEX2,
2933 MASKBYTE1, power_index);
2934 break;
2935 case DESC_RATEVHT2SS_MCS4:
2936 rtl_set_bbreg(hw, RTXAGC_A_NSS2INDEX5_NSS2INDEX2,
2937 MASKBYTE2, power_index);
2938 break;
2939 case DESC_RATEVHT2SS_MCS5:
2940 rtl_set_bbreg(hw, RTXAGC_A_NSS2INDEX5_NSS2INDEX2,
2941 MASKBYTE3, power_index);
2942 break;
2943 case DESC_RATEVHT2SS_MCS6:
2944 rtl_set_bbreg(hw, RTXAGC_A_NSS2INDEX9_NSS2INDEX6,
2945 MASKBYTE0, power_index);
2946 break;
2947 case DESC_RATEVHT2SS_MCS7:
2948 rtl_set_bbreg(hw, RTXAGC_A_NSS2INDEX9_NSS2INDEX6,
2949 MASKBYTE1, power_index);
2950 break;
2951 case DESC_RATEVHT2SS_MCS8:
2952 rtl_set_bbreg(hw, RTXAGC_A_NSS2INDEX9_NSS2INDEX6,
2953 MASKBYTE2, power_index);
2954 break;
2955 case DESC_RATEVHT2SS_MCS9:
2956 rtl_set_bbreg(hw, RTXAGC_A_NSS2INDEX9_NSS2INDEX6,
2957 MASKBYTE3, power_index);
2958 break;
2959 default:
2960 RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
2961 "Invalid Rate!!\n");
2962 break;
2963 }
2964 } else if (path == RF90_PATH_B) {
2965 switch (rate) {
2966 case DESC_RATE1M:
2967 rtl_set_bbreg(hw, RTXAGC_B_CCK11_CCK1,
2968 MASKBYTE0, power_index);
2969 break;
2970 case DESC_RATE2M:
2971 rtl_set_bbreg(hw, RTXAGC_B_CCK11_CCK1,
2972 MASKBYTE1, power_index);
2973 break;
2974 case DESC_RATE5_5M:
2975 rtl_set_bbreg(hw, RTXAGC_B_CCK11_CCK1,
2976 MASKBYTE2, power_index);
2977 break;
2978 case DESC_RATE11M:
2979 rtl_set_bbreg(hw, RTXAGC_B_CCK11_CCK1,
2980 MASKBYTE3, power_index);
2981 break;
2982 case DESC_RATE6M:
2983 rtl_set_bbreg(hw, RTXAGC_B_OFDM18_OFDM6,
2984 MASKBYTE0, power_index);
2985 break;
2986 case DESC_RATE9M:
2987 rtl_set_bbreg(hw, RTXAGC_B_OFDM18_OFDM6,
2988 MASKBYTE1, power_index);
2989 break;
2990 case DESC_RATE12M:
2991 rtl_set_bbreg(hw, RTXAGC_B_OFDM18_OFDM6,
2992 MASKBYTE2, power_index);
2993 break;
2994 case DESC_RATE18M:
2995 rtl_set_bbreg(hw, RTXAGC_B_OFDM18_OFDM6,
2996 MASKBYTE3, power_index);
2997 break;
2998 case DESC_RATE24M:
2999 rtl_set_bbreg(hw, RTXAGC_B_OFDM54_OFDM24,
3000 MASKBYTE0, power_index);
3001 break;
3002 case DESC_RATE36M:
3003 rtl_set_bbreg(hw, RTXAGC_B_OFDM54_OFDM24,
3004 MASKBYTE1, power_index);
3005 break;
3006 case DESC_RATE48M:
3007 rtl_set_bbreg(hw, RTXAGC_B_OFDM54_OFDM24,
3008 MASKBYTE2, power_index);
3009 break;
3010 case DESC_RATE54M:
3011 rtl_set_bbreg(hw, RTXAGC_B_OFDM54_OFDM24,
3012 MASKBYTE3, power_index);
3013 break;
3014 case DESC_RATEMCS0:
3015 rtl_set_bbreg(hw, RTXAGC_B_MCS03_MCS00,
3016 MASKBYTE0, power_index);
3017 break;
3018 case DESC_RATEMCS1:
3019 rtl_set_bbreg(hw, RTXAGC_B_MCS03_MCS00,
3020 MASKBYTE1, power_index);
3021 break;
3022 case DESC_RATEMCS2:
3023 rtl_set_bbreg(hw, RTXAGC_B_MCS03_MCS00,
3024 MASKBYTE2, power_index);
3025 break;
3026 case DESC_RATEMCS3:
3027 rtl_set_bbreg(hw, RTXAGC_B_MCS03_MCS00,
3028 MASKBYTE3, power_index);
3029 break;
3030 case DESC_RATEMCS4:
3031 rtl_set_bbreg(hw, RTXAGC_B_MCS07_MCS04,
3032 MASKBYTE0, power_index);
3033 break;
3034 case DESC_RATEMCS5:
3035 rtl_set_bbreg(hw, RTXAGC_B_MCS07_MCS04,
3036 MASKBYTE1, power_index);
3037 break;
3038 case DESC_RATEMCS6:
3039 rtl_set_bbreg(hw, RTXAGC_B_MCS07_MCS04,
3040 MASKBYTE2, power_index);
3041 break;
3042 case DESC_RATEMCS7:
3043 rtl_set_bbreg(hw, RTXAGC_B_MCS07_MCS04,
3044 MASKBYTE3, power_index);
3045 break;
3046 case DESC_RATEMCS8:
3047 rtl_set_bbreg(hw, RTXAGC_B_MCS11_MCS08,
3048 MASKBYTE0, power_index);
3049 break;
3050 case DESC_RATEMCS9:
3051 rtl_set_bbreg(hw, RTXAGC_B_MCS11_MCS08,
3052 MASKBYTE1, power_index);
3053 break;
3054 case DESC_RATEMCS10:
3055 rtl_set_bbreg(hw, RTXAGC_B_MCS11_MCS08,
3056 MASKBYTE2, power_index);
3057 break;
3058 case DESC_RATEMCS11:
3059 rtl_set_bbreg(hw, RTXAGC_B_MCS11_MCS08,
3060 MASKBYTE3, power_index);
3061 break;
3062 case DESC_RATEMCS12:
3063 rtl_set_bbreg(hw, RTXAGC_B_MCS15_MCS12,
3064 MASKBYTE0, power_index);
3065 break;
3066 case DESC_RATEMCS13:
3067 rtl_set_bbreg(hw, RTXAGC_B_MCS15_MCS12,
3068 MASKBYTE1, power_index);
3069 break;
3070 case DESC_RATEMCS14:
3071 rtl_set_bbreg(hw, RTXAGC_B_MCS15_MCS12,
3072 MASKBYTE2, power_index);
3073 break;
3074 case DESC_RATEMCS15:
3075 rtl_set_bbreg(hw, RTXAGC_B_MCS15_MCS12,
3076 MASKBYTE3, power_index);
3077 break;
3078 case DESC_RATEVHT1SS_MCS0:
3079 rtl_set_bbreg(hw, RTXAGC_B_NSS1INDEX3_NSS1INDEX0,
3080 MASKBYTE0, power_index);
3081 break;
3082 case DESC_RATEVHT1SS_MCS1:
3083 rtl_set_bbreg(hw, RTXAGC_B_NSS1INDEX3_NSS1INDEX0,
3084 MASKBYTE1, power_index);
3085 break;
3086 case DESC_RATEVHT1SS_MCS2:
3087 rtl_set_bbreg(hw, RTXAGC_B_NSS1INDEX3_NSS1INDEX0,
3088 MASKBYTE2, power_index);
3089 break;
3090 case DESC_RATEVHT1SS_MCS3:
3091 rtl_set_bbreg(hw, RTXAGC_B_NSS1INDEX3_NSS1INDEX0,
3092 MASKBYTE3, power_index);
3093 break;
3094 case DESC_RATEVHT1SS_MCS4:
3095 rtl_set_bbreg(hw, RTXAGC_B_NSS1INDEX7_NSS1INDEX4,
3096 MASKBYTE0, power_index);
3097 break;
3098 case DESC_RATEVHT1SS_MCS5:
3099 rtl_set_bbreg(hw, RTXAGC_B_NSS1INDEX7_NSS1INDEX4,
3100 MASKBYTE1, power_index);
3101 break;
3102 case DESC_RATEVHT1SS_MCS6:
3103 rtl_set_bbreg(hw, RTXAGC_B_NSS1INDEX7_NSS1INDEX4,
3104 MASKBYTE2, power_index);
3105 break;
3106 case DESC_RATEVHT1SS_MCS7:
3107 rtl_set_bbreg(hw, RTXAGC_B_NSS1INDEX7_NSS1INDEX4,
3108 MASKBYTE3, power_index);
3109 break;
3110 case DESC_RATEVHT1SS_MCS8:
3111 rtl_set_bbreg(hw, RTXAGC_B_NSS2INDEX1_NSS1INDEX8,
3112 MASKBYTE0, power_index);
3113 break;
3114 case DESC_RATEVHT1SS_MCS9:
3115 rtl_set_bbreg(hw, RTXAGC_B_NSS2INDEX1_NSS1INDEX8,
3116 MASKBYTE1, power_index);
3117 break;
3118 case DESC_RATEVHT2SS_MCS0:
3119 rtl_set_bbreg(hw, RTXAGC_B_NSS2INDEX1_NSS1INDEX8,
3120 MASKBYTE2, power_index);
3121 break;
3122 case DESC_RATEVHT2SS_MCS1:
3123 rtl_set_bbreg(hw, RTXAGC_B_NSS2INDEX1_NSS1INDEX8,
3124 MASKBYTE3, power_index);
3125 break;
3126 case DESC_RATEVHT2SS_MCS2:
3127 rtl_set_bbreg(hw, RTXAGC_B_NSS2INDEX5_NSS2INDEX2,
3128 MASKBYTE0, power_index);
3129 break;
3130 case DESC_RATEVHT2SS_MCS3:
3131 rtl_set_bbreg(hw, RTXAGC_B_NSS2INDEX5_NSS2INDEX2,
3132 MASKBYTE1, power_index);
3133 break;
3134 case DESC_RATEVHT2SS_MCS4:
3135 rtl_set_bbreg(hw, RTXAGC_B_NSS2INDEX5_NSS2INDEX2,
3136 MASKBYTE2, power_index);
3137 break;
3138 case DESC_RATEVHT2SS_MCS5:
3139 rtl_set_bbreg(hw, RTXAGC_B_NSS2INDEX5_NSS2INDEX2,
3140 MASKBYTE3, power_index);
3141 break;
3142 case DESC_RATEVHT2SS_MCS6:
3143 rtl_set_bbreg(hw, RTXAGC_B_NSS2INDEX9_NSS2INDEX6,
3144 MASKBYTE0, power_index);
3145 break;
3146 case DESC_RATEVHT2SS_MCS7:
3147 rtl_set_bbreg(hw, RTXAGC_B_NSS2INDEX9_NSS2INDEX6,
3148 MASKBYTE1, power_index);
3149 break;
3150 case DESC_RATEVHT2SS_MCS8:
3151 rtl_set_bbreg(hw, RTXAGC_B_NSS2INDEX9_NSS2INDEX6,
3152 MASKBYTE2, power_index);
3153 break;
3154 case DESC_RATEVHT2SS_MCS9:
3155 rtl_set_bbreg(hw, RTXAGC_B_NSS2INDEX9_NSS2INDEX6,
3156 MASKBYTE3, power_index);
3157 break;
3158 default:
3159 RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
3160 "Invalid Rate!!\n");
3161 break;
3162 }
3163 } else {
3164 RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
3165 "Invalid RFPath!!\n");
3166 }
3167}
3168
3169static void _rtl8821ae_phy_set_txpower_level_by_path(struct ieee80211_hw *hw,
3170 u8 *array, u8 path,
3171 u8 channel, u8 size)
3172{
3173 struct rtl_priv *rtlpriv = rtl_priv(hw);
3174 struct rtl_phy *rtlphy = &rtlpriv->phy;
3175 u8 i;
3176 u8 power_index;
3177
3178 for (i = 0; i < size; i++) {
3179 power_index =
3180 _rtl8821ae_get_txpower_index(hw, path, array[i],
3181 rtlphy->current_chan_bw,
3182 channel);
3183 _rtl8821ae_phy_set_txpower_index(hw, power_index, path,
3184 array[i]);
3185 }
3186}
3187
3188static void _rtl8821ae_phy_txpower_training_by_path(struct ieee80211_hw *hw,
3189 u8 bw, u8 channel, u8 path)
3190{
3191 struct rtl_priv *rtlpriv = rtl_priv(hw);
3192 struct rtl_phy *rtlphy = &rtlpriv->phy;
3193
3194 u8 i;
3195 u32 power_level, data, offset;
3196
3197 if (path >= rtlphy->num_total_rfpath)
3198 return;
3199
3200 data = 0;
3201 if (path == RF90_PATH_A) {
3202 power_level =
3203 _rtl8821ae_get_txpower_index(hw, RF90_PATH_A,
3204 DESC_RATEMCS7, bw, channel);
3205 offset = RA_TXPWRTRAING;
3206 } else {
3207 power_level =
3208 _rtl8821ae_get_txpower_index(hw, RF90_PATH_B,
3209 DESC_RATEMCS7, bw, channel);
3210 offset = RB_TXPWRTRAING;
3211 }
3212
3213 for (i = 0; i < 3; i++) {
3214 if (i == 0)
3215 power_level = power_level - 10;
3216 else if (i == 1)
3217 power_level = power_level - 8;
3218 else
3219 power_level = power_level - 6;
3220
3221 data |= (((power_level > 2) ? (power_level) : 2) << (i * 8));
3222 }
3223 rtl_set_bbreg(hw, offset, 0xffffff, data);
3224}
3225
3226void rtl8821ae_phy_set_txpower_level_by_path(struct ieee80211_hw *hw,
3227 u8 channel, u8 path)
3228{
3229 /* struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); */
3230 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
3231 struct rtl_priv *rtlpriv = rtl_priv(hw);
3232 struct rtl_phy *rtlphy = &rtlpriv->phy;
3233 u8 cck_rates[] = {DESC_RATE1M, DESC_RATE2M, DESC_RATE5_5M,
3234 DESC_RATE11M};
3235 u8 sizes_of_cck_retes = 4;
3236 u8 ofdm_rates[] = {DESC_RATE6M, DESC_RATE9M, DESC_RATE12M,
3237 DESC_RATE18M, DESC_RATE24M, DESC_RATE36M,
3238 DESC_RATE48M, DESC_RATE54M};
3239 u8 sizes_of_ofdm_retes = 8;
3240 u8 ht_rates_1t[] = {DESC_RATEMCS0, DESC_RATEMCS1, DESC_RATEMCS2,
3241 DESC_RATEMCS3, DESC_RATEMCS4, DESC_RATEMCS5,
3242 DESC_RATEMCS6, DESC_RATEMCS7};
3243 u8 sizes_of_ht_retes_1t = 8;
3244 u8 ht_rates_2t[] = {DESC_RATEMCS8, DESC_RATEMCS9,
3245 DESC_RATEMCS10, DESC_RATEMCS11,
3246 DESC_RATEMCS12, DESC_RATEMCS13,
3247 DESC_RATEMCS14, DESC_RATEMCS15};
3248 u8 sizes_of_ht_retes_2t = 8;
3249 u8 vht_rates_1t[] = {DESC_RATEVHT1SS_MCS0, DESC_RATEVHT1SS_MCS1,
3250 DESC_RATEVHT1SS_MCS2, DESC_RATEVHT1SS_MCS3,
3251 DESC_RATEVHT1SS_MCS4, DESC_RATEVHT1SS_MCS5,
3252 DESC_RATEVHT1SS_MCS6, DESC_RATEVHT1SS_MCS7,
3253 DESC_RATEVHT1SS_MCS8, DESC_RATEVHT1SS_MCS9};
3254 u8 vht_rates_2t[] = {DESC_RATEVHT2SS_MCS0, DESC_RATEVHT2SS_MCS1,
3255 DESC_RATEVHT2SS_MCS2, DESC_RATEVHT2SS_MCS3,
3256 DESC_RATEVHT2SS_MCS4, DESC_RATEVHT2SS_MCS5,
3257 DESC_RATEVHT2SS_MCS6, DESC_RATEVHT2SS_MCS7,
3258 DESC_RATEVHT2SS_MCS8, DESC_RATEVHT2SS_MCS9};
3259 u8 sizes_of_vht_retes = 10;
3260
3261 if (rtlhal->current_bandtype == BAND_ON_2_4G)
3262 _rtl8821ae_phy_set_txpower_level_by_path(hw, cck_rates, path, channel,
3263 sizes_of_cck_retes);
3264
3265 _rtl8821ae_phy_set_txpower_level_by_path(hw, ofdm_rates, path, channel,
3266 sizes_of_ofdm_retes);
3267 _rtl8821ae_phy_set_txpower_level_by_path(hw, ht_rates_1t, path, channel,
3268 sizes_of_ht_retes_1t);
3269 _rtl8821ae_phy_set_txpower_level_by_path(hw, vht_rates_1t, path, channel,
3270 sizes_of_vht_retes);
3271
3272 if (rtlphy->num_total_rfpath >= 2) {
3273 _rtl8821ae_phy_set_txpower_level_by_path(hw, ht_rates_2t, path,
3274 channel,
3275 sizes_of_ht_retes_2t);
3276 _rtl8821ae_phy_set_txpower_level_by_path(hw, vht_rates_2t, path,
3277 channel,
3278 sizes_of_vht_retes);
3279 }
3280
3281 _rtl8821ae_phy_txpower_training_by_path(hw, rtlphy->current_chan_bw,
3282 channel, path);
3283}
3284
3285/*just in case, write txpower in DW, to reduce time*/
3286void rtl8821ae_phy_set_txpower_level(struct ieee80211_hw *hw, u8 channel)
3287{
3288 struct rtl_priv *rtlpriv = rtl_priv(hw);
3289 struct rtl_phy *rtlphy = &rtlpriv->phy;
3290 u8 path = 0;
3291
3292 for (path = RF90_PATH_A; path < rtlphy->num_total_rfpath; ++path)
3293 rtl8821ae_phy_set_txpower_level_by_path(hw, channel, path);
3294}
3295
3296static long _rtl8821ae_phy_txpwr_idx_to_dbm(struct ieee80211_hw *hw,
3297 enum wireless_mode wirelessmode,
3298 u8 txpwridx)
3299{
3300 long offset;
3301 long pwrout_dbm;
3302
3303 switch (wirelessmode) {
3304 case WIRELESS_MODE_B:
3305 offset = -7;
3306 break;
3307 case WIRELESS_MODE_G:
3308 case WIRELESS_MODE_N_24G:
3309 offset = -8;
3310 break;
3311 default:
3312 offset = -8;
3313 break;
3314 }
3315 pwrout_dbm = txpwridx / 2 + offset;
3316 return pwrout_dbm;
3317}
3318
3319void rtl8821ae_phy_scan_operation_backup(struct ieee80211_hw *hw, u8 operation)
3320{
3321 struct rtl_priv *rtlpriv = rtl_priv(hw);
3322 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
3323 enum io_type iotype = IO_CMD_PAUSE_BAND0_DM_BY_SCAN;
3324
3325 if (!is_hal_stop(rtlhal)) {
3326 switch (operation) {
3327 case SCAN_OPT_BACKUP_BAND0:
3328 iotype = IO_CMD_PAUSE_BAND0_DM_BY_SCAN;
3329 rtlpriv->cfg->ops->set_hw_reg(hw,
3330 HW_VAR_IO_CMD,
3331 (u8 *)&iotype);
3332
3333 break;
3334 case SCAN_OPT_BACKUP_BAND1:
3335 iotype = IO_CMD_PAUSE_BAND1_DM_BY_SCAN;
3336 rtlpriv->cfg->ops->set_hw_reg(hw,
3337 HW_VAR_IO_CMD,
3338 (u8 *)&iotype);
3339
3340 break;
3341 case SCAN_OPT_RESTORE:
3342 iotype = IO_CMD_RESUME_DM_BY_SCAN;
3343 rtlpriv->cfg->ops->set_hw_reg(hw,
3344 HW_VAR_IO_CMD,
3345 (u8 *)&iotype);
3346 break;
3347 default:
3348 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
3349 "Unknown Scan Backup operation.\n");
3350 break;
3351 }
3352 }
3353}
3354
3355static void _rtl8821ae_phy_set_reg_bw(struct rtl_priv *rtlpriv, u8 bw)
3356{
3357 u16 reg_rf_mode_bw, tmp = 0;
3358
3359 reg_rf_mode_bw = rtl_read_word(rtlpriv, REG_TRXPTCL_CTL);
3360 switch (bw) {
3361 case HT_CHANNEL_WIDTH_20:
3362 rtl_write_word(rtlpriv, REG_TRXPTCL_CTL, reg_rf_mode_bw & 0xFE7F);
3363 break;
3364 case HT_CHANNEL_WIDTH_20_40:
3365 tmp = reg_rf_mode_bw | BIT(7);
3366 rtl_write_word(rtlpriv, REG_TRXPTCL_CTL, tmp & 0xFEFF);
3367 break;
3368 case HT_CHANNEL_WIDTH_80:
3369 tmp = reg_rf_mode_bw | BIT(8);
3370 rtl_write_word(rtlpriv, REG_TRXPTCL_CTL, tmp & 0xFF7F);
3371 break;
3372 default:
3373 RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING, "unknown Bandwidth: 0x%x\n", bw);
3374 break;
3375 }
3376}
3377
3378static u8 _rtl8821ae_phy_get_secondary_chnl(struct rtl_priv *rtlpriv)
3379{
3380 struct rtl_phy *rtlphy = &rtlpriv->phy;
3381 struct rtl_mac *mac = rtl_mac(rtlpriv);
3382 u8 sc_set_40 = 0, sc_set_20 = 0;
3383
3384 if (rtlphy->current_chan_bw == HT_CHANNEL_WIDTH_80) {
3385 if (mac->cur_80_prime_sc == PRIME_CHNL_OFFSET_LOWER)
3386 sc_set_40 = VHT_DATA_SC_40_LOWER_OF_80MHZ;
3387 else if (mac->cur_80_prime_sc == PRIME_CHNL_OFFSET_UPPER)
3388 sc_set_40 = VHT_DATA_SC_40_UPPER_OF_80MHZ;
3389 else
3390 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
3391 "SCMapping: Not Correct Primary40MHz Setting\n");
3392
3393 if ((mac->cur_40_prime_sc == PRIME_CHNL_OFFSET_LOWER) &&
3394 (mac->cur_80_prime_sc == HAL_PRIME_CHNL_OFFSET_LOWER))
3395 sc_set_20 = VHT_DATA_SC_20_LOWEST_OF_80MHZ;
3396 else if ((mac->cur_40_prime_sc == PRIME_CHNL_OFFSET_UPPER) &&
3397 (mac->cur_80_prime_sc == HAL_PRIME_CHNL_OFFSET_LOWER))
3398 sc_set_20 = VHT_DATA_SC_20_LOWER_OF_80MHZ;
3399 else if ((mac->cur_40_prime_sc == PRIME_CHNL_OFFSET_LOWER) &&
3400 (mac->cur_80_prime_sc == HAL_PRIME_CHNL_OFFSET_UPPER))
3401 sc_set_20 = VHT_DATA_SC_20_UPPER_OF_80MHZ;
3402 else if ((mac->cur_40_prime_sc == PRIME_CHNL_OFFSET_UPPER) &&
3403 (mac->cur_80_prime_sc == HAL_PRIME_CHNL_OFFSET_UPPER))
3404 sc_set_20 = VHT_DATA_SC_20_UPPERST_OF_80MHZ;
3405 else
3406 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
3407 "SCMapping: Not Correct Primary40MHz Setting\n");
3408 } else if (rtlphy->current_chan_bw == HT_CHANNEL_WIDTH_20_40) {
3409 if (mac->cur_40_prime_sc == PRIME_CHNL_OFFSET_UPPER)
3410 sc_set_20 = VHT_DATA_SC_20_UPPER_OF_80MHZ;
3411 else if (mac->cur_40_prime_sc == PRIME_CHNL_OFFSET_LOWER)
3412 sc_set_20 = VHT_DATA_SC_20_LOWER_OF_80MHZ;
3413 else
3414 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
3415 "SCMapping: Not Correct Primary40MHz Setting\n");
3416 }
3417 return (sc_set_40 << 4) | sc_set_20;
3418}
3419
3420void rtl8821ae_phy_set_bw_mode_callback(struct ieee80211_hw *hw)
3421{
3422 struct rtl_priv *rtlpriv = rtl_priv(hw);
3423 struct rtl_phy *rtlphy = &rtlpriv->phy;
3424 u8 sub_chnl = 0;
3425 u8 l1pk_val = 0;
3426
3427 RT_TRACE(rtlpriv, COMP_SCAN, DBG_TRACE,
3428 "Switch to %s bandwidth\n",
3429 (rtlphy->current_chan_bw == HT_CHANNEL_WIDTH_20 ?
3430 "20MHz" :
3431 (rtlphy->current_chan_bw == HT_CHANNEL_WIDTH_20_40 ?
3432 "40MHz" : "80MHz")));
3433
3434 _rtl8821ae_phy_set_reg_bw(rtlpriv, rtlphy->current_chan_bw);
3435 sub_chnl = _rtl8821ae_phy_get_secondary_chnl(rtlpriv);
3436 rtl_write_byte(rtlpriv, 0x0483, sub_chnl);
3437
3438 switch (rtlphy->current_chan_bw) {
3439 case HT_CHANNEL_WIDTH_20:
3440 rtl_set_bbreg(hw, RRFMOD, 0x003003C3, 0x00300200);
3441 rtl_set_bbreg(hw, RADC_BUF_CLK, BIT(30), 0);
3442
3443 if (rtlphy->rf_type == RF_2T2R)
3444 rtl_set_bbreg(hw, RL1PEAKTH, 0x03C00000, 7);
3445 else
3446 rtl_set_bbreg(hw, RL1PEAKTH, 0x03C00000, 8);
3447 break;
3448 case HT_CHANNEL_WIDTH_20_40:
3449 rtl_set_bbreg(hw, RRFMOD, 0x003003C3, 0x00300201);
3450 rtl_set_bbreg(hw, RADC_BUF_CLK, BIT(30), 0);
3451 rtl_set_bbreg(hw, RRFMOD, 0x3C, sub_chnl);
3452 rtl_set_bbreg(hw, RCCAONSEC, 0xf0000000, sub_chnl);
3453
3454 if (rtlphy->reg_837 & BIT(2))
3455 l1pk_val = 6;
3456 else {
3457 if (rtlphy->rf_type == RF_2T2R)
3458 l1pk_val = 7;
3459 else
3460 l1pk_val = 8;
3461 }
3462 /* 0x848[25:22] = 0x6 */
3463 rtl_set_bbreg(hw, RL1PEAKTH, 0x03C00000, l1pk_val);
3464
3465 if (sub_chnl == VHT_DATA_SC_20_UPPER_OF_80MHZ)
3466 rtl_set_bbreg(hw, RCCK_SYSTEM, BCCK_SYSTEM, 1);
3467 else
3468 rtl_set_bbreg(hw, RCCK_SYSTEM, BCCK_SYSTEM, 0);
3469 break;
3470
3471 case HT_CHANNEL_WIDTH_80:
3472 /* 0x8ac[21,20,9:6,1,0]=8'b11100010 */
3473 rtl_set_bbreg(hw, RRFMOD, 0x003003C3, 0x00300202);
3474 /* 0x8c4[30] = 1 */
3475 rtl_set_bbreg(hw, RADC_BUF_CLK, BIT(30), 1);
3476 rtl_set_bbreg(hw, RRFMOD, 0x3C, sub_chnl);
3477 rtl_set_bbreg(hw, RCCAONSEC, 0xf0000000, sub_chnl);
3478
3479 if (rtlphy->reg_837 & BIT(2))
3480 l1pk_val = 5;
3481 else {
3482 if (rtlphy->rf_type == RF_2T2R)
3483 l1pk_val = 6;
3484 else
3485 l1pk_val = 7;
3486 }
3487 rtl_set_bbreg(hw, RL1PEAKTH, 0x03C00000, l1pk_val);
3488
3489 break;
3490 default:
3491 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
3492 "unknown bandwidth: %#X\n", rtlphy->current_chan_bw);
3493 break;
3494 }
3495
3496 rtl8812ae_fixspur(hw, rtlphy->current_chan_bw, rtlphy->current_channel);
3497
3498 rtl8821ae_phy_rf6052_set_bandwidth(hw, rtlphy->current_chan_bw);
3499 rtlphy->set_bwmode_inprogress = false;
3500
3501 RT_TRACE(rtlpriv, COMP_SCAN, DBG_LOUD, "\n");
3502}
3503
3504void rtl8821ae_phy_set_bw_mode(struct ieee80211_hw *hw,
3505 enum nl80211_channel_type ch_type)
3506{
3507 struct rtl_priv *rtlpriv = rtl_priv(hw);
3508 struct rtl_phy *rtlphy = &rtlpriv->phy;
3509 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
3510 u8 tmp_bw = rtlphy->current_chan_bw;
3511
3512 if (rtlphy->set_bwmode_inprogress)
3513 return;
3514 rtlphy->set_bwmode_inprogress = true;
3515 if ((!is_hal_stop(rtlhal)) && !(RT_CANNOT_IO(hw)))
3516 rtl8821ae_phy_set_bw_mode_callback(hw);
3517 else {
3518 RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
3519 "FALSE driver sleep or unload\n");
3520 rtlphy->set_bwmode_inprogress = false;
3521 rtlphy->current_chan_bw = tmp_bw;
3522 }
3523}
3524
3525void rtl8821ae_phy_sw_chnl_callback(struct ieee80211_hw *hw)
3526{
3527 struct rtl_priv *rtlpriv = rtl_priv(hw);
3528 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
3529 struct rtl_phy *rtlphy = &rtlpriv->phy;
3530 u8 channel = rtlphy->current_channel;
3531 u8 path;
3532 u32 data;
3533
3534 RT_TRACE(rtlpriv, COMP_SCAN, DBG_TRACE,
3535 "switch to channel%d\n", rtlphy->current_channel);
3536 if (is_hal_stop(rtlhal))
3537 return;
3538
3539 if (36 <= channel && channel <= 48)
3540 data = 0x494;
3541 else if (50 <= channel && channel <= 64)
3542 data = 0x453;
3543 else if (100 <= channel && channel <= 116)
3544 data = 0x452;
3545 else if (118 <= channel)
3546 data = 0x412;
3547 else
3548 data = 0x96a;
3549 rtl_set_bbreg(hw, RFC_AREA, 0x1ffe0000, data);
3550
3551 for (path = RF90_PATH_A; path < rtlphy->num_total_rfpath; path++) {
3552 if (36 <= channel && channel <= 64)
3553 data = 0x101;
3554 else if (100 <= channel && channel <= 140)
3555 data = 0x301;
3556 else if (140 < channel)
3557 data = 0x501;
3558 else
3559 data = 0x000;
3560 rtl8821ae_phy_set_rf_reg(hw, path, RF_CHNLBW,
3561 BIT(18)|BIT(17)|BIT(16)|BIT(9)|BIT(8), data);
3562
3563 rtl8821ae_phy_set_rf_reg(hw, path, RF_CHNLBW,
3564 BMASKBYTE0, channel);
3565
3566 if (channel > 14) {
3567 if (rtlhal->hw_type == HARDWARE_TYPE_RTL8821AE) {
3568 if (36 <= channel && channel <= 64)
3569 data = 0x114E9;
3570 else if (100 <= channel && channel <= 140)
3571 data = 0x110E9;
3572 else
3573 data = 0x110E9;
3574 rtl8821ae_phy_set_rf_reg(hw, path, RF_APK,
3575 BRFREGOFFSETMASK, data);
3576 }
3577 }
3578 }
3579 RT_TRACE(rtlpriv, COMP_SCAN, DBG_TRACE, "\n");
3580}
3581
3582u8 rtl8821ae_phy_sw_chnl(struct ieee80211_hw *hw)
3583{
3584 struct rtl_priv *rtlpriv = rtl_priv(hw);
3585 struct rtl_phy *rtlphy = &rtlpriv->phy;
3586 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
3587 u32 timeout = 1000, timecount = 0;
3588 u8 channel = rtlphy->current_channel;
3589
3590 if (rtlphy->sw_chnl_inprogress)
3591 return 0;
3592 if (rtlphy->set_bwmode_inprogress)
3593 return 0;
3594
3595 if ((is_hal_stop(rtlhal)) || (RT_CANNOT_IO(hw))) {
3596 RT_TRACE(rtlpriv, COMP_CHAN, DBG_LOUD,
3597 "sw_chnl_inprogress false driver sleep or unload\n");
3598 return 0;
3599 }
3600 while (rtlphy->lck_inprogress && timecount < timeout) {
3601 mdelay(50);
3602 timecount += 50;
3603 }
3604
3605 if (rtlphy->current_channel > 14 && rtlhal->current_bandtype != BAND_ON_5G)
3606 rtl8821ae_phy_switch_wirelessband(hw, BAND_ON_5G);
3607 else if (rtlphy->current_channel <= 14 && rtlhal->current_bandtype != BAND_ON_2_4G)
3608 rtl8821ae_phy_switch_wirelessband(hw, BAND_ON_2_4G);
3609
3610 rtlphy->sw_chnl_inprogress = true;
3611 if (channel == 0)
3612 channel = 1;
3613
3614 RT_TRACE(rtlpriv, COMP_SCAN, DBG_TRACE,
3615 "switch to channel%d, band type is %d\n",
3616 rtlphy->current_channel, rtlhal->current_bandtype);
3617
3618 rtl8821ae_phy_sw_chnl_callback(hw);
3619
3620 rtl8821ae_dm_clear_txpower_tracking_state(hw);
3621 rtl8821ae_phy_set_txpower_level(hw, rtlphy->current_channel);
3622
3623 RT_TRACE(rtlpriv, COMP_SCAN, DBG_TRACE, "\n");
3624 rtlphy->sw_chnl_inprogress = false;
3625 return 1;
3626}
3627
3628u8 _rtl8812ae_get_right_chnl_place_for_iqk(u8 chnl)
3629{
3630 u8 channel_all[TARGET_CHNL_NUM_2G_5G_8812] = {
3631 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13,
3632 14, 36, 38, 40, 42, 44, 46, 48, 50, 52, 54,
3633 56, 58, 60, 62, 64, 100, 102, 104, 106, 108,
3634 110, 112, 114, 116, 118, 120, 122, 124, 126,
3635 128, 130, 132, 134, 136, 138, 140, 149, 151,
3636 153, 155, 157, 159, 161, 163, 165};
3637 u8 place = chnl;
3638
3639 if (chnl > 14) {
3640 for (place = 14; place < sizeof(channel_all); place++)
3641 if (channel_all[place] == chnl)
3642 return place-13;
3643 }
3644
3645 return 0;
3646}
3647
3648#define MACBB_REG_NUM 10
3649#define AFE_REG_NUM 14
3650#define RF_REG_NUM 3
3651
3652static void _rtl8821ae_iqk_backup_macbb(struct ieee80211_hw *hw,
3653 u32 *macbb_backup,
3654 u32 *backup_macbb_reg, u32 mac_bb_num)
3655{
3656 struct rtl_priv *rtlpriv = rtl_priv(hw);
3657 u32 i;
3658
3659 rtl_set_bbreg(hw, 0x82c, BIT(31), 0x0); /*[31] = 0 --> Page C*/
3660 /*save MACBB default value*/
3661 for (i = 0; i < mac_bb_num; i++)
3662 macbb_backup[i] = rtl_read_dword(rtlpriv, backup_macbb_reg[i]);
3663
3664 RT_TRACE(rtlpriv, COMP_IQK, DBG_LOUD, "BackupMacBB Success!!!!\n");
3665}
3666
3667static void _rtl8821ae_iqk_backup_afe(struct ieee80211_hw *hw, u32 *afe_backup,
3668 u32 *backup_afe_REG, u32 afe_num)
3669{
3670 struct rtl_priv *rtlpriv = rtl_priv(hw);
3671 u32 i;
3672
3673 rtl_set_bbreg(hw, 0x82c, BIT(31), 0x0); /*[31] = 0 --> Page C*/
3674 /*Save AFE Parameters */
3675 for (i = 0; i < afe_num; i++)
3676 afe_backup[i] = rtl_read_dword(rtlpriv, backup_afe_REG[i]);
3677 RT_TRACE(rtlpriv, COMP_IQK, DBG_LOUD, "BackupAFE Success!!!!\n");
3678}
3679
3680static void _rtl8821ae_iqk_backup_rf(struct ieee80211_hw *hw, u32 *rfa_backup,
3681 u32 *rfb_backup, u32 *backup_rf_reg,
3682 u32 rf_num)
3683{
3684 struct rtl_priv *rtlpriv = rtl_priv(hw);
3685 u32 i;
3686
3687 rtl_set_bbreg(hw, 0x82c, BIT(31), 0x0); /*[31] = 0 --> Page C*/
3688 /*Save RF Parameters*/
3689 for (i = 0; i < rf_num; i++) {
3690 rfa_backup[i] = rtl_get_rfreg(hw, RF90_PATH_A, backup_rf_reg[i],
3691 BMASKDWORD);
3692 rfb_backup[i] = rtl_get_rfreg(hw, RF90_PATH_B, backup_rf_reg[i],
3693 BMASKDWORD);
3694 }
3695 RT_TRACE(rtlpriv, COMP_IQK, DBG_LOUD, "BackupRF Success!!!!\n");
3696}
3697
3698static void _rtl8821ae_iqk_configure_mac(
3699 struct ieee80211_hw *hw
3700 )
3701{
3702 struct rtl_priv *rtlpriv = rtl_priv(hw);
3703 /* ========MAC register setting========*/
3704 rtl_set_bbreg(hw, 0x82c, BIT(31), 0x0); /*[31] = 0 --> Page C*/
3705 rtl_write_byte(rtlpriv, 0x522, 0x3f);
3706 rtl_set_bbreg(hw, 0x550, BIT(11) | BIT(3), 0x0);
3707 rtl_write_byte(rtlpriv, 0x808, 0x00); /*RX ante off*/
3708 rtl_set_bbreg(hw, 0x838, 0xf, 0xc); /*CCA off*/
3709}
3710
3711static void _rtl8821ae_iqk_tx_fill_iqc(struct ieee80211_hw *hw,
3712 enum radio_path path, u32 tx_x, u32 tx_y)
3713{
3714 struct rtl_priv *rtlpriv = rtl_priv(hw);
3715 switch (path) {
3716 case RF90_PATH_A:
3717 /* [31] = 1 --> Page C1 */
3718 rtl_set_bbreg(hw, 0x82c, BIT(31), 0x1);
3719 rtl_write_dword(rtlpriv, 0xc90, 0x00000080);
3720 rtl_write_dword(rtlpriv, 0xcc4, 0x20040000);
3721 rtl_write_dword(rtlpriv, 0xcc8, 0x20000000);
3722 rtl_set_bbreg(hw, 0xccc, 0x000007ff, tx_y);
3723 rtl_set_bbreg(hw, 0xcd4, 0x000007ff, tx_x);
3724 RT_TRACE(rtlpriv, COMP_IQK, DBG_LOUD,
3725 "TX_X = %x;;TX_Y = %x =====> fill to IQC\n",
3726 tx_x, tx_y);
3727 RT_TRACE(rtlpriv, COMP_IQK, DBG_LOUD,
3728 "0xcd4 = %x;;0xccc = %x ====>fill to IQC\n",
3729 rtl_get_bbreg(hw, 0xcd4, 0x000007ff),
3730 rtl_get_bbreg(hw, 0xccc, 0x000007ff));
3731 break;
3732 default:
3733 break;
09fa9d87 3734 }
21e4b072
LF
3735}
3736
3737static void _rtl8821ae_iqk_rx_fill_iqc(struct ieee80211_hw *hw,
3738 enum radio_path path, u32 rx_x, u32 rx_y)
3739{
3740 struct rtl_priv *rtlpriv = rtl_priv(hw);
3741 switch (path) {
3742 case RF90_PATH_A:
3743 rtl_set_bbreg(hw, 0x82c, BIT(31), 0x0); /* [31] = 0 --> Page C */
3744 rtl_set_bbreg(hw, 0xc10, 0x000003ff, rx_x>>1);
3745 rtl_set_bbreg(hw, 0xc10, 0x03ff0000, rx_y>>1);
3746 RT_TRACE(rtlpriv, COMP_IQK, DBG_LOUD,
3747 "rx_x = %x;;rx_y = %x ====>fill to IQC\n",
3748 rx_x>>1, rx_y>>1);
3749 RT_TRACE(rtlpriv, COMP_IQK, DBG_LOUD,
3750 "0xc10 = %x ====>fill to IQC\n",
3751 rtl_read_dword(rtlpriv, 0xc10));
3752 break;
3753 default:
3754 break;
09fa9d87 3755 }
21e4b072
LF
3756}
3757
3758#define cal_num 10
3759
3760static void _rtl8821ae_iqk_tx(struct ieee80211_hw *hw, enum radio_path path)
3761{
3762 struct rtl_priv *rtlpriv = rtl_priv(hw);
3763 struct rtl_phy *rtlphy = &rtlpriv->phy;
3764 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
3765
3766 u32 tx_fail, rx_fail, delay_count, iqk_ready, cal_retry, cal = 0, temp_reg65;
3767 int tx_x = 0, tx_y = 0, rx_x = 0, rx_y = 0, tx_average = 0, rx_average = 0;
3768 int tx_x0[cal_num], tx_y0[cal_num], tx_x0_rxk[cal_num],
3769 tx_y0_rxk[cal_num], rx_x0[cal_num], rx_y0[cal_num];
3770 bool tx0iqkok = false, rx0iqkok = false;
3771 bool vdf_enable = false;
3772 int i, k, vdf_y[3], vdf_x[3], tx_dt[3], rx_dt[3],
3773 ii, dx = 0, dy = 0, tx_finish = 0, rx_finish = 0;
3774
3775 RT_TRACE(rtlpriv, COMP_IQK, DBG_LOUD,
3776 "BandWidth = %d.\n",
3777 rtlphy->current_chan_bw);
3778 if (rtlphy->current_chan_bw == HT_CHANNEL_WIDTH_80)
3779 vdf_enable = true;
3780
3781 while (cal < cal_num) {
3782 switch (path) {
3783 case RF90_PATH_A:
3784 temp_reg65 = rtl_get_rfreg(hw, path, 0x65, 0xffffffff);
3785 /* Path-A LOK */
3786 rtl_set_bbreg(hw, 0x82c, BIT(31), 0x0); /*[31] = 0 --> Page C*/
3787 /*========Path-A AFE all on========*/
3788 /*Port 0 DAC/ADC on*/
3789 rtl_write_dword(rtlpriv, 0xc60, 0x77777777);
3790 rtl_write_dword(rtlpriv, 0xc64, 0x77777777);
3791 rtl_write_dword(rtlpriv, 0xc68, 0x19791979);
3792 rtl_write_dword(rtlpriv, 0xc6c, 0x19791979);
3793 rtl_write_dword(rtlpriv, 0xc70, 0x19791979);
3794 rtl_write_dword(rtlpriv, 0xc74, 0x19791979);
3795 rtl_write_dword(rtlpriv, 0xc78, 0x19791979);
3796 rtl_write_dword(rtlpriv, 0xc7c, 0x19791979);
3797 rtl_write_dword(rtlpriv, 0xc80, 0x19791979);
3798 rtl_write_dword(rtlpriv, 0xc84, 0x19791979);
3799
3800 rtl_set_bbreg(hw, 0xc00, 0xf, 0x4); /*hardware 3-wire off*/
3801
3802 /* LOK Setting */
3803 /* ====== LOK ====== */
3804 /*DAC/ADC sampling rate (160 MHz)*/
3805 rtl_set_bbreg(hw, 0xc5c, BIT(26) | BIT(25) | BIT(24), 0x7);
3806
3807 /* 2. LoK RF Setting (at BW = 20M) */
3808 rtl_set_rfreg(hw, path, 0xef, RFREG_OFFSET_MASK, 0x80002);
3809 rtl_set_rfreg(hw, path, 0x18, 0x00c00, 0x3); /* BW 20M */
3810 rtl_set_rfreg(hw, path, 0x30, RFREG_OFFSET_MASK, 0x20000);
3811 rtl_set_rfreg(hw, path, 0x31, RFREG_OFFSET_MASK, 0x0003f);
3812 rtl_set_rfreg(hw, path, 0x32, RFREG_OFFSET_MASK, 0xf3fc3);
3813 rtl_set_rfreg(hw, path, 0x65, RFREG_OFFSET_MASK, 0x931d5);
3814 rtl_set_rfreg(hw, path, 0x8f, RFREG_OFFSET_MASK, 0x8a001);
3815 rtl_set_bbreg(hw, 0xcb8, 0xf, 0xd);
3816 rtl_write_dword(rtlpriv, 0x90c, 0x00008000);
3817 rtl_write_dword(rtlpriv, 0xb00, 0x03000100);
3818 rtl_set_bbreg(hw, 0xc94, BIT(0), 0x1);
3819 rtl_write_dword(rtlpriv, 0x978, 0x29002000);/* TX (X,Y) */
3820 rtl_write_dword(rtlpriv, 0x97c, 0xa9002000);/* RX (X,Y) */
3821 rtl_write_dword(rtlpriv, 0x984, 0x00462910);/* [0]:AGC_en, [15]:idac_K_Mask */
3822
3823 rtl_set_bbreg(hw, 0x82c, BIT(31), 0x1); /* [31] = 1 --> Page C1 */
3824 rtl_write_dword(rtlpriv, 0xc88, 0x821403f4);
3825
3826 if (rtlhal->current_bandtype)
3827 rtl_write_dword(rtlpriv, 0xc8c, 0x68163e96);
3828 else
3829 rtl_write_dword(rtlpriv, 0xc8c, 0x28163e96);
3830
3831 rtl_write_dword(rtlpriv, 0xc80, 0x18008c10);/* TX_TONE_idx[9:0], TxK_Mask[29] TX_Tone = 16 */
3832 rtl_write_dword(rtlpriv, 0xc84, 0x38008c10);/* RX_TONE_idx[9:0], RxK_Mask[29] */
3833 rtl_write_dword(rtlpriv, 0xcb8, 0x00100000);/* cb8[20] \B1N SI/PI \A8Ï¥\CE\C5v\A4\C1\B5\B9 iqk_dpk module */
3834 rtl_write_dword(rtlpriv, 0x980, 0xfa000000);
3835 rtl_write_dword(rtlpriv, 0x980, 0xf8000000);
3836
3837 mdelay(10); /* Delay 10ms */
3838 rtl_write_dword(rtlpriv, 0xcb8, 0x00000000);
3839
3840 rtl_set_bbreg(hw, 0x82c, BIT(31), 0x0); /* [31] = 0 --> Page C */
3841 rtl_set_rfreg(hw, path, 0x58, 0x7fe00, rtl_get_rfreg(hw, path, 0x8, 0xffc00)); /* Load LOK */
3842
3843 switch (rtlphy->current_chan_bw) {
3844 case 1:
3845 rtl_set_rfreg(hw, path, 0x18, 0x00c00, 0x1);
3846 break;
3847 case 2:
3848 rtl_set_rfreg(hw, path, 0x18, 0x00c00, 0x0);
3849 break;
3850 default:
3851 break;
3852 }
3853
3854 rtl_set_bbreg(hw, 0x82c, BIT(31), 0x1); /* [31] = 1 --> Page C1 */
3855
3856 /* 3. TX RF Setting */
3857 rtl_set_bbreg(hw, 0x82c, BIT(31), 0x0); /* [31] = 0 --> Page C */
3858 rtl_set_rfreg(hw, path, 0xef, RFREG_OFFSET_MASK, 0x80000);
3859 rtl_set_rfreg(hw, path, 0x30, RFREG_OFFSET_MASK, 0x20000);
3860 rtl_set_rfreg(hw, path, 0x31, RFREG_OFFSET_MASK, 0x0003f);
3861 rtl_set_rfreg(hw, path, 0x32, RFREG_OFFSET_MASK, 0xf3fc3);
3862 rtl_set_rfreg(hw, path, 0x65, RFREG_OFFSET_MASK, 0x931d5);
3863 rtl_set_rfreg(hw, path, 0x8f, RFREG_OFFSET_MASK, 0x8a001);
3864 rtl_set_rfreg(hw, path, 0xef, RFREG_OFFSET_MASK, 0x00000);
3865 /* ODM_SetBBReg(pDM_Odm, 0xcb8, 0xf, 0xd); */
3866 rtl_write_dword(rtlpriv, 0x90c, 0x00008000);
3867 rtl_write_dword(rtlpriv, 0xb00, 0x03000100);
3868 rtl_set_bbreg(hw, 0xc94, BIT(0), 0x1);
3869 rtl_write_dword(rtlpriv, 0x978, 0x29002000);/* TX (X,Y) */
3870 rtl_write_dword(rtlpriv, 0x97c, 0xa9002000);/* RX (X,Y) */
3871 rtl_write_dword(rtlpriv, 0x984, 0x0046a910);/* [0]:AGC_en, [15]:idac_K_Mask */
3872
3873 rtl_set_bbreg(hw, 0x82c, BIT(31), 0x1); /* [31] = 1 --> Page C1 */
3874 rtl_write_dword(rtlpriv, 0xc88, 0x821403f1);
3875 if (rtlhal->current_bandtype)
3876 rtl_write_dword(rtlpriv, 0xc8c, 0x40163e96);
3877 else
3878 rtl_write_dword(rtlpriv, 0xc8c, 0x00163e96);
3879
3880 if (vdf_enable == 1) {
3881 RT_TRACE(rtlpriv, COMP_IQK, DBG_LOUD, "VDF_enable\n");
3882 for (k = 0; k <= 2; k++) {
3883 switch (k) {
3884 case 0:
3885 rtl_write_dword(rtlpriv, 0xc80, 0x18008c38);/* TX_TONE_idx[9:0], TxK_Mask[29] TX_Tone = 16 */
3886 rtl_write_dword(rtlpriv, 0xc84, 0x38008c38);/* RX_TONE_idx[9:0], RxK_Mask[29] */
3887 rtl_set_bbreg(hw, 0xce8, BIT(31), 0x0);
3888 break;
3889 case 1:
3890 rtl_set_bbreg(hw, 0xc80, BIT(28), 0x0);
3891 rtl_set_bbreg(hw, 0xc84, BIT(28), 0x0);
3892 rtl_set_bbreg(hw, 0xce8, BIT(31), 0x0);
3893 break;
3894 case 2:
3895 RT_TRACE(rtlpriv, COMP_IQK, DBG_LOUD,
3896 "vdf_y[1] = %x;;;vdf_y[0] = %x\n", vdf_y[1]>>21 & 0x00007ff, vdf_y[0]>>21 & 0x00007ff);
3897 RT_TRACE(rtlpriv, COMP_IQK, DBG_LOUD,
3898 "vdf_x[1] = %x;;;vdf_x[0] = %x\n", vdf_x[1]>>21 & 0x00007ff, vdf_x[0]>>21 & 0x00007ff);
3899 tx_dt[cal] = (vdf_y[1]>>20)-(vdf_y[0]>>20);
3900 tx_dt[cal] = ((16*tx_dt[cal])*10000/15708);
3901 tx_dt[cal] = (tx_dt[cal] >> 1)+(tx_dt[cal] & BIT(0));
3902 rtl_write_dword(rtlpriv, 0xc80, 0x18008c20);/* TX_TONE_idx[9:0], TxK_Mask[29] TX_Tone = 16 */
3903 rtl_write_dword(rtlpriv, 0xc84, 0x38008c20);/* RX_TONE_idx[9:0], RxK_Mask[29] */
3904 rtl_set_bbreg(hw, 0xce8, BIT(31), 0x1);
3905 rtl_set_bbreg(hw, 0xce8, 0x3fff0000, tx_dt[cal] & 0x00003fff);
3906 break;
3907 default:
3908 break;
3909 }
3910 rtl_write_dword(rtlpriv, 0xcb8, 0x00100000);/* cb8[20] \B1N SI/PI \A8Ï¥\CE\C5v\A4\C1\B5\B9 iqk_dpk module */
3911 cal_retry = 0;
3912 while (1) {
3913 /* one shot */
3914 rtl_write_dword(rtlpriv, 0x980, 0xfa000000);
3915 rtl_write_dword(rtlpriv, 0x980, 0xf8000000);
3916
3917 mdelay(10); /* Delay 10ms */
3918 rtl_write_dword(rtlpriv, 0xcb8, 0x00000000);
3919 delay_count = 0;
3920 while (1) {
3921 iqk_ready = rtl_get_bbreg(hw, 0xd00, BIT(10));
3922 if ((~iqk_ready) || (delay_count > 20))
3923 break;
3924 else{
3925 mdelay(1);
3926 delay_count++;
3927 }
3928 }
3929
3930 if (delay_count < 20) { /* If 20ms No Result, then cal_retry++ */
3931 /* ============TXIQK Check============== */
3932 tx_fail = rtl_get_bbreg(hw, 0xd00, BIT(12));
3933
3934 if (~tx_fail) {
3935 rtl_write_dword(rtlpriv, 0xcb8, 0x02000000);
3936 vdf_x[k] = rtl_get_bbreg(hw, 0xd00, 0x07ff0000)<<21;
3937 rtl_write_dword(rtlpriv, 0xcb8, 0x04000000);
3938 vdf_y[k] = rtl_get_bbreg(hw, 0xd00, 0x07ff0000)<<21;
3939 tx0iqkok = true;
3940 break;
3941 } else {
3942 rtl_set_bbreg(hw, 0xccc, 0x000007ff, 0x0);
3943 rtl_set_bbreg(hw, 0xcd4, 0x000007ff, 0x200);
3944 tx0iqkok = false;
3945 cal_retry++;
3946 if (cal_retry == 10)
3947 break;
3948 }
3949 } else {
3950 tx0iqkok = false;
3951 cal_retry++;
3952 if (cal_retry == 10)
3953 break;
3954 }
3955 }
3956 }
3957 if (k == 3) {
3958 tx_x0[cal] = vdf_x[k-1];
3959 tx_y0[cal] = vdf_y[k-1];
3960 }
3961 } else {
3962 rtl_write_dword(rtlpriv, 0xc80, 0x18008c10);/* TX_TONE_idx[9:0], TxK_Mask[29] TX_Tone = 16 */
3963 rtl_write_dword(rtlpriv, 0xc84, 0x38008c10);/* RX_TONE_idx[9:0], RxK_Mask[29] */
3964 rtl_write_dword(rtlpriv, 0xcb8, 0x00100000);/* cb8[20] \B1N SI/PI \A8Ï¥\CE\C5v\A4\C1\B5\B9 iqk_dpk module */
3965 cal_retry = 0;
3966 while (1) {
3967 /* one shot */
3968 rtl_write_dword(rtlpriv, 0x980, 0xfa000000);
3969 rtl_write_dword(rtlpriv, 0x980, 0xf8000000);
3970
3971 mdelay(10); /* Delay 10ms */
3972 rtl_write_dword(rtlpriv, 0xcb8, 0x00000000);
3973 delay_count = 0;
3974 while (1) {
3975 iqk_ready = rtl_get_bbreg(hw, 0xd00, BIT(10));
3976 if ((~iqk_ready) || (delay_count > 20))
3977 break;
3978 else{
3979 mdelay(1);
3980 delay_count++;
3981 }
3982 }
3983
3984 if (delay_count < 20) { /* If 20ms No Result, then cal_retry++ */
3985 /* ============TXIQK Check============== */
3986 tx_fail = rtl_get_bbreg(hw, 0xd00, BIT(12));
3987
3988 if (~tx_fail) {
3989 rtl_write_dword(rtlpriv, 0xcb8, 0x02000000);
3990 tx_x0[cal] = rtl_get_bbreg(hw, 0xd00, 0x07ff0000)<<21;
3991 rtl_write_dword(rtlpriv, 0xcb8, 0x04000000);
3992 tx_y0[cal] = rtl_get_bbreg(hw, 0xd00, 0x07ff0000)<<21;
3993 tx0iqkok = true;
3994 break;
3995 } else {
3996 rtl_set_bbreg(hw, 0xccc, 0x000007ff, 0x0);
3997 rtl_set_bbreg(hw, 0xcd4, 0x000007ff, 0x200);
3998 tx0iqkok = false;
3999 cal_retry++;
4000 if (cal_retry == 10)
4001 break;
4002 }
4003 } else {
4004 tx0iqkok = false;
4005 cal_retry++;
4006 if (cal_retry == 10)
4007 break;
4008 }
4009 }
4010 }
4011
4012 if (tx0iqkok == false)
4013 break; /* TXK fail, Don't do RXK */
4014
4015 if (vdf_enable == 1) {
4016 rtl_set_bbreg(hw, 0xce8, BIT(31), 0x0); /* TX VDF Disable */
4017 RT_TRACE(rtlpriv, COMP_IQK, DBG_LOUD, "RXVDF Start\n");
4018 for (k = 0; k <= 2; k++) {
4019 /* ====== RX mode TXK (RXK Step 1) ====== */
4020 rtl_set_bbreg(hw, 0x82c, BIT(31), 0x0); /* [31] = 0 --> Page C */
4021 /* 1. TX RF Setting */
4022 rtl_set_rfreg(hw, path, 0xef, RFREG_OFFSET_MASK, 0x80000);
4023 rtl_set_rfreg(hw, path, 0x30, RFREG_OFFSET_MASK, 0x30000);
4024 rtl_set_rfreg(hw, path, 0x31, RFREG_OFFSET_MASK, 0x00029);
4025 rtl_set_rfreg(hw, path, 0x32, RFREG_OFFSET_MASK, 0xd7ffb);
4026 rtl_set_rfreg(hw, path, 0x65, RFREG_OFFSET_MASK, temp_reg65);
4027 rtl_set_rfreg(hw, path, 0x8f, RFREG_OFFSET_MASK, 0x8a001);
4028 rtl_set_rfreg(hw, path, 0xef, RFREG_OFFSET_MASK, 0x00000);
4029
4030 rtl_set_bbreg(hw, 0xcb8, 0xf, 0xd);
4031 rtl_write_dword(rtlpriv, 0x978, 0x29002000);/* TX (X,Y) */
4032 rtl_write_dword(rtlpriv, 0x97c, 0xa9002000);/* RX (X,Y) */
4033 rtl_write_dword(rtlpriv, 0x984, 0x0046a910);/* [0]:AGC_en, [15]:idac_K_Mask */
4034 rtl_write_dword(rtlpriv, 0x90c, 0x00008000);
4035 rtl_write_dword(rtlpriv, 0xb00, 0x03000100);
4036 rtl_set_bbreg(hw, 0x82c, BIT(31), 0x1); /* [31] = 1 --> Page C1 */
4037 switch (k) {
4038 case 0:
4039 {
4040 rtl_write_dword(rtlpriv, 0xc80, 0x18008c38);/* TX_TONE_idx[9:0], TxK_Mask[29] TX_Tone = 16 */
4041 rtl_write_dword(rtlpriv, 0xc84, 0x38008c38);/* RX_TONE_idx[9:0], RxK_Mask[29] */
4042 rtl_set_bbreg(hw, 0xce8, BIT(30), 0x0);
4043 }
4044 break;
4045 case 1:
4046 {
4047 rtl_write_dword(rtlpriv, 0xc80, 0x08008c38);/* TX_TONE_idx[9:0], TxK_Mask[29] TX_Tone = 16 */
4048 rtl_write_dword(rtlpriv, 0xc84, 0x28008c38);/* RX_TONE_idx[9:0], RxK_Mask[29] */
4049 rtl_set_bbreg(hw, 0xce8, BIT(30), 0x0);
4050 }
4051 break;
4052 case 2:
4053 {
4054 RT_TRACE(rtlpriv, COMP_IQK, DBG_LOUD,
4055 "VDF_Y[1] = %x;;;VDF_Y[0] = %x\n",
4056 vdf_y[1]>>21 & 0x00007ff, vdf_y[0]>>21 & 0x00007ff);
4057 RT_TRACE(rtlpriv, COMP_IQK, DBG_LOUD,
4058 "VDF_X[1] = %x;;;VDF_X[0] = %x\n",
4059 vdf_x[1]>>21 & 0x00007ff, vdf_x[0]>>21 & 0x00007ff);
4060 rx_dt[cal] = (vdf_y[1]>>20)-(vdf_y[0]>>20);
4061 RT_TRACE(rtlpriv, COMP_IQK, DBG_LOUD, "Rx_dt = %d\n", rx_dt[cal]);
4062 rx_dt[cal] = ((16*rx_dt[cal])*10000/13823);
4063 rx_dt[cal] = (rx_dt[cal] >> 1)+(rx_dt[cal] & BIT(0));
4064 rtl_write_dword(rtlpriv, 0xc80, 0x18008c20);/* TX_TONE_idx[9:0], TxK_Mask[29] TX_Tone = 16 */
4065 rtl_write_dword(rtlpriv, 0xc84, 0x38008c20);/* RX_TONE_idx[9:0], RxK_Mask[29] */
4066 rtl_set_bbreg(hw, 0xce8, 0x00003fff, rx_dt[cal] & 0x00003fff);
4067 }
4068 break;
4069 default:
4070 break;
4071 }
4072 rtl_write_dword(rtlpriv, 0xc88, 0x821603e0);
4073 rtl_write_dword(rtlpriv, 0xc8c, 0x68163e96);
4074 rtl_write_dword(rtlpriv, 0xcb8, 0x00100000);/* cb8[20] \B1N SI/PI \A8Ï¥\CE\C5v\A4\C1\B5\B9 iqk_dpk module */
4075 cal_retry = 0;
4076 while (1) {
4077 /* one shot */
4078 rtl_write_dword(rtlpriv, 0x980, 0xfa000000);
4079 rtl_write_dword(rtlpriv, 0x980, 0xf8000000);
4080
4081 mdelay(10); /* Delay 10ms */
4082 rtl_write_dword(rtlpriv, 0xcb8, 0x00000000);
4083 delay_count = 0;
4084 while (1) {
4085 iqk_ready = rtl_get_bbreg(hw, 0xd00, BIT(10));
4086 if ((~iqk_ready) || (delay_count > 20))
4087 break;
4088 else{
4089 mdelay(1);
4090 delay_count++;
4091 }
4092 }
4093
4094 if (delay_count < 20) { /* If 20ms No Result, then cal_retry++ */
4095 /* ============TXIQK Check============== */
4096 tx_fail = rtl_get_bbreg(hw, 0xd00, BIT(12));
4097
4098 if (~tx_fail) {
4099 rtl_write_dword(rtlpriv, 0xcb8, 0x02000000);
4100 tx_x0_rxk[cal] = rtl_get_bbreg(hw, 0xd00, 0x07ff0000)<<21;
4101 rtl_write_dword(rtlpriv, 0xcb8, 0x04000000);
4102 tx_y0_rxk[cal] = rtl_get_bbreg(hw, 0xd00, 0x07ff0000)<<21;
4103 tx0iqkok = true;
4104 break;
4105 } else{
4106 tx0iqkok = false;
4107 cal_retry++;
4108 if (cal_retry == 10)
4109 break;
4110 }
4111 } else {
4112 tx0iqkok = false;
4113 cal_retry++;
4114 if (cal_retry == 10)
4115 break;
4116 }
4117 }
4118
4119 if (tx0iqkok == false) { /* If RX mode TXK fail, then take TXK Result */
4120 tx_x0_rxk[cal] = tx_x0[cal];
4121 tx_y0_rxk[cal] = tx_y0[cal];
4122 tx0iqkok = true;
4123 RT_TRACE(rtlpriv,
4124 COMP_IQK,
4125 DBG_LOUD,
4126 "RXK Step 1 fail\n");
4127 }
4128
4129 /* ====== RX IQK ====== */
4130 rtl_set_bbreg(hw, 0x82c, BIT(31), 0x0); /* [31] = 0 --> Page C */
4131 /* 1. RX RF Setting */
4132 rtl_set_rfreg(hw, path, 0xef, RFREG_OFFSET_MASK, 0x80000);
4133 rtl_set_rfreg(hw, path, 0x30, RFREG_OFFSET_MASK, 0x30000);
4134 rtl_set_rfreg(hw, path, 0x31, RFREG_OFFSET_MASK, 0x0002f);
4135 rtl_set_rfreg(hw, path, 0x32, RFREG_OFFSET_MASK, 0xfffbb);
4136 rtl_set_rfreg(hw, path, 0x8f, RFREG_OFFSET_MASK, 0x88001);
4137 rtl_set_rfreg(hw, path, 0x65, RFREG_OFFSET_MASK, 0x931d8);
4138 rtl_set_rfreg(hw, path, 0xef, RFREG_OFFSET_MASK, 0x00000);
4139
4140 rtl_set_bbreg(hw, 0x978, 0x03FF8000, (tx_x0_rxk[cal])>>21&0x000007ff);
4141 rtl_set_bbreg(hw, 0x978, 0x000007FF, (tx_y0_rxk[cal])>>21&0x000007ff);
4142 rtl_set_bbreg(hw, 0x978, BIT(31), 0x1);
4143 rtl_set_bbreg(hw, 0x97c, BIT(31), 0x0);
4144 rtl_set_bbreg(hw, 0xcb8, 0xF, 0xe);
4145 rtl_write_dword(rtlpriv, 0x90c, 0x00008000);
4146 rtl_write_dword(rtlpriv, 0x984, 0x0046a911);
4147
4148 rtl_set_bbreg(hw, 0x82c, BIT(31), 0x1); /* [31] = 1 --> Page C1 */
4149 rtl_set_bbreg(hw, 0xc80, BIT(29), 0x1);
4150 rtl_set_bbreg(hw, 0xc84, BIT(29), 0x0);
4151 rtl_write_dword(rtlpriv, 0xc88, 0x02140119);
4152
4153 rtl_write_dword(rtlpriv, 0xc8c, 0x28160d00); /* pDM_Odm->SupportInterface == 1 */
4154
4155 if (k == 2)
4156 rtl_set_bbreg(hw, 0xce8, BIT(30), 0x1); /* RX VDF Enable */
4157 rtl_write_dword(rtlpriv, 0xcb8, 0x00100000);/* cb8[20] \B1N SI/PI \A8Ï¥\CE\C5v\A4\C1\B5\B9 iqk_dpk module */
4158
4159 cal_retry = 0;
4160 while (1) {
4161 /* one shot */
4162 rtl_write_dword(rtlpriv, 0x980, 0xfa000000);
4163 rtl_write_dword(rtlpriv, 0x980, 0xf8000000);
4164
4165 mdelay(10); /* Delay 10ms */
4166 rtl_write_dword(rtlpriv, 0xcb8, 0x00000000);
4167 delay_count = 0;
4168 while (1) {
4169 iqk_ready = rtl_get_bbreg(hw, 0xd00, BIT(10));
4170 if ((~iqk_ready) || (delay_count > 20))
4171 break;
4172 else{
4173 mdelay(1);
4174 delay_count++;
4175 }
4176 }
4177
4178 if (delay_count < 20) { /* If 20ms No Result, then cal_retry++ */
4179 /* ============RXIQK Check============== */
4180 rx_fail = rtl_get_bbreg(hw, 0xd00, BIT(11));
4181 if (rx_fail == 0) {
4182 rtl_write_dword(rtlpriv, 0xcb8, 0x06000000);
4183 vdf_x[k] = rtl_get_bbreg(hw, 0xd00, 0x07ff0000)<<21;
4184 rtl_write_dword(rtlpriv, 0xcb8, 0x08000000);
4185 vdf_y[k] = rtl_get_bbreg(hw, 0xd00, 0x07ff0000)<<21;
4186 rx0iqkok = true;
4187 break;
4188 } else {
4189 rtl_set_bbreg(hw, 0xc10, 0x000003ff, 0x200>>1);
4190 rtl_set_bbreg(hw, 0xc10, 0x03ff0000, 0x0>>1);
4191 rx0iqkok = false;
4192 cal_retry++;
4193 if (cal_retry == 10)
4194 break;
4195
4196 }
4197 } else{
4198 rx0iqkok = false;
4199 cal_retry++;
4200 if (cal_retry == 10)
4201 break;
4202 }
4203 }
4204
4205 }
4206 if (k == 3) {
4207 rx_x0[cal] = vdf_x[k-1];
4208 rx_y0[cal] = vdf_y[k-1];
4209 }
4210 rtl_set_bbreg(hw, 0xce8, BIT(31), 0x1); /* TX VDF Enable */
4211 }
4212
4213 else{
4214 /* ====== RX mode TXK (RXK Step 1) ====== */
4215 rtl_set_bbreg(hw, 0x82c, BIT(31), 0x0); /* [31] = 0 --> Page C */
4216 /* 1. TX RF Setting */
4217 rtl_set_rfreg(hw, path, 0xef, RFREG_OFFSET_MASK, 0x80000);
4218 rtl_set_rfreg(hw, path, 0x30, RFREG_OFFSET_MASK, 0x30000);
4219 rtl_set_rfreg(hw, path, 0x31, RFREG_OFFSET_MASK, 0x00029);
4220 rtl_set_rfreg(hw, path, 0x32, RFREG_OFFSET_MASK, 0xd7ffb);
4221 rtl_set_rfreg(hw, path, 0x65, RFREG_OFFSET_MASK, temp_reg65);
4222 rtl_set_rfreg(hw, path, 0x8f, RFREG_OFFSET_MASK, 0x8a001);
4223 rtl_set_rfreg(hw, path, 0xef, RFREG_OFFSET_MASK, 0x00000);
4224 rtl_write_dword(rtlpriv, 0x90c, 0x00008000);
4225 rtl_write_dword(rtlpriv, 0xb00, 0x03000100);
4226 rtl_write_dword(rtlpriv, 0x984, 0x0046a910);/* [0]:AGC_en, [15]:idac_K_Mask */
4227
4228 rtl_set_bbreg(hw, 0x82c, BIT(31), 0x1); /* [31] = 1 --> Page C1 */
4229 rtl_write_dword(rtlpriv, 0xc80, 0x18008c10);/* TX_TONE_idx[9:0], TxK_Mask[29] TX_Tone = 16 */
4230 rtl_write_dword(rtlpriv, 0xc84, 0x38008c10);/* RX_TONE_idx[9:0], RxK_Mask[29] */
4231 rtl_write_dword(rtlpriv, 0xc88, 0x821603e0);
4232 /* ODM_Write4Byte(pDM_Odm, 0xc8c, 0x68163e96); */
4233 rtl_write_dword(rtlpriv, 0xcb8, 0x00100000);/* cb8[20] \B1N SI/PI \A8Ï¥\CE\C5v\A4\C1\B5\B9 iqk_dpk module */
4234 cal_retry = 0;
4235 while (1) {
4236 /* one shot */
4237 rtl_write_dword(rtlpriv, 0x980, 0xfa000000);
4238 rtl_write_dword(rtlpriv, 0x980, 0xf8000000);
4239
4240 mdelay(10); /* Delay 10ms */
4241 rtl_write_dword(rtlpriv, 0xcb8, 0x00000000);
4242 delay_count = 0;
4243 while (1) {
4244 iqk_ready = rtl_get_bbreg(hw, 0xd00, BIT(10));
4245 if ((~iqk_ready) || (delay_count > 20))
4246 break;
4247 else{
4248 mdelay(1);
4249 delay_count++;
4250 }
4251 }
4252
4253 if (delay_count < 20) { /* If 20ms No Result, then cal_retry++ */
4254 /* ============TXIQK Check============== */
4255 tx_fail = rtl_get_bbreg(hw, 0xd00, BIT(12));
4256
4257 if (~tx_fail) {
4258 rtl_write_dword(rtlpriv, 0xcb8, 0x02000000);
4259 tx_x0_rxk[cal] = rtl_get_bbreg(hw, 0xd00, 0x07ff0000)<<21;
4260 rtl_write_dword(rtlpriv, 0xcb8, 0x04000000);
4261 tx_y0_rxk[cal] = rtl_get_bbreg(hw, 0xd00, 0x07ff0000)<<21;
4262 tx0iqkok = true;
4263 break;
4264 } else {
4265 tx0iqkok = false;
4266 cal_retry++;
4267 if (cal_retry == 10)
4268 break;
4269 }
4270 } else{
4271 tx0iqkok = false;
4272 cal_retry++;
4273 if (cal_retry == 10)
4274 break;
4275 }
4276 }
4277
4278 if (tx0iqkok == false) { /* If RX mode TXK fail, then take TXK Result */
4279 tx_x0_rxk[cal] = tx_x0[cal];
4280 tx_y0_rxk[cal] = tx_y0[cal];
4281 tx0iqkok = true;
4282 RT_TRACE(rtlpriv, COMP_IQK,
4283 DBG_LOUD, "1");
4284 }
4285
4286 /* ====== RX IQK ====== */
4287 rtl_set_bbreg(hw, 0x82c, BIT(31), 0x0); /* [31] = 0 --> Page C */
4288 /* 1. RX RF Setting */
4289 rtl_set_rfreg(hw, path, 0xef, RFREG_OFFSET_MASK, 0x80000);
4290 rtl_set_rfreg(hw, path, 0x30, RFREG_OFFSET_MASK, 0x30000);
4291 rtl_set_rfreg(hw, path, 0x31, RFREG_OFFSET_MASK, 0x0002f);
4292 rtl_set_rfreg(hw, path, 0x32, RFREG_OFFSET_MASK, 0xfffbb);
4293 rtl_set_rfreg(hw, path, 0x8f, RFREG_OFFSET_MASK, 0x88001);
4294 rtl_set_rfreg(hw, path, 0x65, RFREG_OFFSET_MASK, 0x931d8);
4295 rtl_set_rfreg(hw, path, 0xef, RFREG_OFFSET_MASK, 0x00000);
4296
4297 rtl_set_bbreg(hw, 0x978, 0x03FF8000, (tx_x0_rxk[cal])>>21&0x000007ff);
4298 rtl_set_bbreg(hw, 0x978, 0x000007FF, (tx_y0_rxk[cal])>>21&0x000007ff);
4299 rtl_set_bbreg(hw, 0x978, BIT(31), 0x1);
4300 rtl_set_bbreg(hw, 0x97c, BIT(31), 0x0);
4301 /* ODM_SetBBReg(pDM_Odm, 0xcb8, 0xF, 0xe); */
4302 rtl_write_dword(rtlpriv, 0x90c, 0x00008000);
4303 rtl_write_dword(rtlpriv, 0x984, 0x0046a911);
4304
4305 rtl_set_bbreg(hw, 0x82c, BIT(31), 0x1); /* [31] = 1 --> Page C1 */
4306 rtl_write_dword(rtlpriv, 0xc80, 0x38008c10);/* TX_TONE_idx[9:0], TxK_Mask[29] TX_Tone = 16 */
4307 rtl_write_dword(rtlpriv, 0xc84, 0x18008c10);/* RX_TONE_idx[9:0], RxK_Mask[29] */
4308 rtl_write_dword(rtlpriv, 0xc88, 0x02140119);
4309
4310 rtl_write_dword(rtlpriv, 0xc8c, 0x28160d00); /*pDM_Odm->SupportInterface == 1*/
4311
4312 rtl_write_dword(rtlpriv, 0xcb8, 0x00100000);/* cb8[20] \B1N SI/PI \A8Ï¥\CE\C5v\A4\C1\B5\B9 iqk_dpk module */
4313
4314 cal_retry = 0;
4315 while (1) {
4316 /* one shot */
4317 rtl_write_dword(rtlpriv, 0x980, 0xfa000000);
4318 rtl_write_dword(rtlpriv, 0x980, 0xf8000000);
4319
4320 mdelay(10); /* Delay 10ms */
4321 rtl_write_dword(rtlpriv, 0xcb8, 0x00000000);
4322 delay_count = 0;
4323 while (1) {
4324 iqk_ready = rtl_get_bbreg(hw, 0xd00, BIT(10));
4325 if ((~iqk_ready) || (delay_count > 20))
4326 break;
4327 else{
4328 mdelay(1);
4329 delay_count++;
4330 }
4331 }
4332
4333 if (delay_count < 20) { /* If 20ms No Result, then cal_retry++ */
4334 /* ============RXIQK Check============== */
4335 rx_fail = rtl_get_bbreg(hw, 0xd00, BIT(11));
4336 if (rx_fail == 0) {
4337 rtl_write_dword(rtlpriv, 0xcb8, 0x06000000);
4338 rx_x0[cal] = rtl_get_bbreg(hw, 0xd00, 0x07ff0000)<<21;
4339 rtl_write_dword(rtlpriv, 0xcb8, 0x08000000);
4340 rx_y0[cal] = rtl_get_bbreg(hw, 0xd00, 0x07ff0000)<<21;
4341 rx0iqkok = true;
4342 break;
4343 } else{
4344 rtl_set_bbreg(hw, 0xc10, 0x000003ff, 0x200>>1);
4345 rtl_set_bbreg(hw, 0xc10, 0x03ff0000, 0x0>>1);
4346 rx0iqkok = false;
4347 cal_retry++;
4348 if (cal_retry == 10)
4349 break;
4350
4351 }
4352 } else{
4353 rx0iqkok = false;
4354 cal_retry++;
4355 if (cal_retry == 10)
4356 break;
4357 }
4358 }
4359 }
4360
4361 if (tx0iqkok)
4362 tx_average++;
4363 if (rx0iqkok)
4364 rx_average++;
4365 rtl_set_bbreg(hw, 0x82c, BIT(31), 0x0); /* [31] = 0 --> Page C */
4366 rtl_set_rfreg(hw, path, 0x65, RFREG_OFFSET_MASK, temp_reg65);
4367 break;
4368 default:
4369 break;
4370 }
4371 cal++;
4372 }
4373
4374 /* FillIQK Result */
4375 switch (path) {
4376 case RF90_PATH_A:
4377 RT_TRACE(rtlpriv, COMP_IQK, DBG_LOUD,
4378 "========Path_A =======\n");
4379 if (tx_average == 0)
4380 break;
4381
4382 for (i = 0; i < tx_average; i++) {
4383 RT_TRACE(rtlpriv, COMP_IQK, DBG_LOUD,
4384 "TX_X0_RXK[%d] = %x ;; TX_Y0_RXK[%d] = %x\n", i,
4385 (tx_x0_rxk[i])>>21&0x000007ff, i,
4386 (tx_y0_rxk[i])>>21&0x000007ff);
4387 RT_TRACE(rtlpriv, COMP_IQK, DBG_LOUD,
4388 "TX_X0[%d] = %x ;; TX_Y0[%d] = %x\n", i,
4389 (tx_x0[i])>>21&0x000007ff, i,
4390 (tx_y0[i])>>21&0x000007ff);
4391 }
4392 for (i = 0; i < tx_average; i++) {
4393 for (ii = i+1; ii < tx_average; ii++) {
4394 dx = (tx_x0[i]>>21) - (tx_x0[ii]>>21);
4395 if (dx < 3 && dx > -3) {
4396 dy = (tx_y0[i]>>21) - (tx_y0[ii]>>21);
4397 if (dy < 3 && dy > -3) {
4398 tx_x = ((tx_x0[i]>>21) + (tx_x0[ii]>>21))/2;
4399 tx_y = ((tx_y0[i]>>21) + (tx_y0[ii]>>21))/2;
4400 tx_finish = 1;
4401 break;
4402 }
4403 }
4404 }
4405 if (tx_finish == 1)
4406 break;
4407 }
4408
4409 if (tx_finish == 1)
4410 _rtl8821ae_iqk_tx_fill_iqc(hw, path, tx_x, tx_y); /* ? */
4411 else
4412 _rtl8821ae_iqk_tx_fill_iqc(hw, path, 0x200, 0x0);
4413
4414 if (rx_average == 0)
4415 break;
4416
4417 for (i = 0; i < rx_average; i++)
4418 RT_TRACE(rtlpriv, COMP_IQK, DBG_LOUD,
4419 "RX_X0[%d] = %x ;; RX_Y0[%d] = %x\n", i,
4420 (rx_x0[i])>>21&0x000007ff, i,
4421 (rx_y0[i])>>21&0x000007ff);
4422 for (i = 0; i < rx_average; i++) {
4423 for (ii = i+1; ii < rx_average; ii++) {
4424 dx = (rx_x0[i]>>21) - (rx_x0[ii]>>21);
4425 if (dx < 4 && dx > -4) {
4426 dy = (rx_y0[i]>>21) - (rx_y0[ii]>>21);
4427 if (dy < 4 && dy > -4) {
4428 rx_x = ((rx_x0[i]>>21) + (rx_x0[ii]>>21))/2;
4429 rx_y = ((rx_y0[i]>>21) + (rx_y0[ii]>>21))/2;
4430 rx_finish = 1;
4431 break;
4432 }
4433 }
4434 }
4435 if (rx_finish == 1)
4436 break;
4437 }
4438
4439 if (rx_finish == 1)
4440 _rtl8821ae_iqk_rx_fill_iqc(hw, path, rx_x, rx_y);
4441 else
4442 _rtl8821ae_iqk_rx_fill_iqc(hw, path, 0x200, 0x0);
4443 break;
4444 default:
4445 break;
4446 }
4447}
4448
4449static void _rtl8821ae_iqk_restore_rf(struct ieee80211_hw *hw,
4450 enum radio_path path,
4451 u32 *backup_rf_reg,
4452 u32 *rf_backup, u32 rf_reg_num)
4453{
4454 struct rtl_priv *rtlpriv = rtl_priv(hw);
4455 u32 i;
4456
4457 rtl_set_bbreg(hw, 0x82c, BIT(31), 0x0); /* [31] = 0 --> Page C */
4458 for (i = 0; i < RF_REG_NUM; i++)
4459 rtl_set_rfreg(hw, path, backup_rf_reg[i], RFREG_OFFSET_MASK,
4460 rf_backup[i]);
4461
4462 switch (path) {
4463 case RF90_PATH_A:
4464 RT_TRACE(rtlpriv, COMP_IQK, DBG_LOUD,
4465 "RestoreRF Path A Success!!!!\n");
4466 break;
4467 default:
4468 break;
4469 }
4470}
4471
4472static void _rtl8821ae_iqk_restore_afe(struct ieee80211_hw *hw,
4473 u32 *afe_backup, u32 *backup_afe_reg,
4474 u32 afe_num)
4475{
4476 u32 i;
4477 struct rtl_priv *rtlpriv = rtl_priv(hw);
4478
4479 rtl_set_bbreg(hw, 0x82c, BIT(31), 0x0); /* [31] = 0 --> Page C */
4480 /* Reload AFE Parameters */
4481 for (i = 0; i < afe_num; i++)
4482 rtl_write_dword(rtlpriv, backup_afe_reg[i], afe_backup[i]);
4483 rtl_set_bbreg(hw, 0x82c, BIT(31), 0x1); /* [31] = 1 --> Page C1 */
4484 rtl_write_dword(rtlpriv, 0xc80, 0x0);
4485 rtl_write_dword(rtlpriv, 0xc84, 0x0);
4486 rtl_write_dword(rtlpriv, 0xc88, 0x0);
4487 rtl_write_dword(rtlpriv, 0xc8c, 0x3c000000);
4488 rtl_write_dword(rtlpriv, 0xc90, 0x00000080);
4489 rtl_write_dword(rtlpriv, 0xc94, 0x00000000);
4490 rtl_write_dword(rtlpriv, 0xcc4, 0x20040000);
4491 rtl_write_dword(rtlpriv, 0xcc8, 0x20000000);
4492 rtl_write_dword(rtlpriv, 0xcb8, 0x0);
4493 RT_TRACE(rtlpriv, COMP_IQK, DBG_LOUD, "RestoreAFE Success!!!!\n");
4494}
4495
4496static void _rtl8821ae_iqk_restore_macbb(struct ieee80211_hw *hw,
4497 u32 *macbb_backup,
4498 u32 *backup_macbb_reg,
4499 u32 macbb_num)
4500{
4501 u32 i;
4502 struct rtl_priv *rtlpriv = rtl_priv(hw);
4503
4504 rtl_set_bbreg(hw, 0x82c, BIT(31), 0x0); /* [31] = 0 --> Page C */
4505 /* Reload MacBB Parameters */
4506 for (i = 0; i < macbb_num; i++)
4507 rtl_write_dword(rtlpriv, backup_macbb_reg[i], macbb_backup[i]);
4508 RT_TRACE(rtlpriv, COMP_IQK, DBG_LOUD, "RestoreMacBB Success!!!!\n");
4509}
4510
4511#undef MACBB_REG_NUM
4512#undef AFE_REG_NUM
4513#undef RF_REG_NUM
4514
4515#define MACBB_REG_NUM 11
4516#define AFE_REG_NUM 12
4517#define RF_REG_NUM 3
4518
4519static void _rtl8821ae_phy_iq_calibrate(struct ieee80211_hw *hw)
4520{
4521 u32 macbb_backup[MACBB_REG_NUM];
4522 u32 afe_backup[AFE_REG_NUM];
4523 u32 rfa_backup[RF_REG_NUM];
4524 u32 rfb_backup[RF_REG_NUM];
4525 u32 backup_macbb_reg[MACBB_REG_NUM] = {
4526 0xb00, 0x520, 0x550, 0x808, 0x90c, 0xc00, 0xc50,
4527 0xe00, 0xe50, 0x838, 0x82c
4528 };
4529 u32 backup_afe_reg[AFE_REG_NUM] = {
4530 0xc5c, 0xc60, 0xc64, 0xc68, 0xc6c, 0xc70, 0xc74,
4531 0xc78, 0xc7c, 0xc80, 0xc84, 0xcb8
4532 };
4533 u32 backup_rf_reg[RF_REG_NUM] = {0x65, 0x8f, 0x0};
4534
4535 _rtl8821ae_iqk_backup_macbb(hw, macbb_backup, backup_macbb_reg,
4536 MACBB_REG_NUM);
4537 _rtl8821ae_iqk_backup_afe(hw, afe_backup, backup_afe_reg, AFE_REG_NUM);
4538 _rtl8821ae_iqk_backup_rf(hw, rfa_backup, rfb_backup, backup_rf_reg,
4539 RF_REG_NUM);
4540
4541 _rtl8821ae_iqk_configure_mac(hw);
4542 _rtl8821ae_iqk_tx(hw, RF90_PATH_A);
4543 _rtl8821ae_iqk_restore_rf(hw, RF90_PATH_A, backup_rf_reg, rfa_backup,
4544 RF_REG_NUM);
4545
4546 _rtl8821ae_iqk_restore_afe(hw, afe_backup, backup_afe_reg, AFE_REG_NUM);
4547 _rtl8821ae_iqk_restore_macbb(hw, macbb_backup, backup_macbb_reg,
4548 MACBB_REG_NUM);
4549}
4550
4551static void _rtl8821ae_phy_set_rfpath_switch(struct ieee80211_hw *hw, bool main)
4552{
4553 struct rtl_priv *rtlpriv = rtl_priv(hw);
4554 /* struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); */
4555 /* struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); */
4556 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "\n");
4557
4558 if (main)
4559 rtl_set_bbreg(hw, RA_RFE_PINMUX + 4, BIT(29) | BIT(28), 0x1);
4560 else
4561 rtl_set_bbreg(hw, RA_RFE_PINMUX + 4, BIT(29) | BIT(28), 0x2);
4562}
4563
4564#undef IQK_ADDA_REG_NUM
4565#undef IQK_DELAY_TIME
4566
4567void rtl8812ae_phy_iq_calibrate(struct ieee80211_hw *hw, bool b_recovery)
4568{
4569}
4570
4571void rtl8812ae_do_iqk(struct ieee80211_hw *hw, u8 delta_thermal_index,
4572 u8 thermal_value, u8 threshold)
4573{
4574 struct rtl_dm *rtldm = rtl_dm(rtl_priv(hw));
4575
4576 rtldm->thermalvalue_iqk = thermal_value;
4577 rtl8812ae_phy_iq_calibrate(hw, false);
4578}
4579
4580void rtl8821ae_phy_iq_calibrate(struct ieee80211_hw *hw, bool b_recovery)
4581{
4582 struct rtl_priv *rtlpriv = rtl_priv(hw);
4583 struct rtl_phy *rtlphy = &rtlpriv->phy;
4584
4585 if (!rtlphy->lck_inprogress) {
4586 spin_lock(&rtlpriv->locks.iqk_lock);
4587 rtlphy->lck_inprogress = true;
4588 spin_unlock(&rtlpriv->locks.iqk_lock);
4589
4590 _rtl8821ae_phy_iq_calibrate(hw);
4591
4592 spin_lock(&rtlpriv->locks.iqk_lock);
4593 rtlphy->lck_inprogress = false;
4594 spin_unlock(&rtlpriv->locks.iqk_lock);
4595 }
4596}
4597
4598void rtl8821ae_reset_iqk_result(struct ieee80211_hw *hw)
4599{
4600 struct rtl_priv *rtlpriv = rtl_priv(hw);
4601 struct rtl_phy *rtlphy = &rtlpriv->phy;
4602 u8 i;
4603
4604 RT_TRACE(rtlpriv, COMP_IQK, DBG_LOUD,
4605 "rtl8812ae_dm_reset_iqk_result:: settings regs %d default regs %d\n",
4606 (int)(sizeof(rtlphy->iqk_matrix) /
4607 sizeof(struct iqk_matrix_regs)),
4608 IQK_MATRIX_SETTINGS_NUM);
4609
4610 for (i = 0; i < IQK_MATRIX_SETTINGS_NUM; i++) {
4611 rtlphy->iqk_matrix[i].value[0][0] = 0x100;
4612 rtlphy->iqk_matrix[i].value[0][2] = 0x100;
4613 rtlphy->iqk_matrix[i].value[0][4] = 0x100;
4614 rtlphy->iqk_matrix[i].value[0][6] = 0x100;
4615
4616 rtlphy->iqk_matrix[i].value[0][1] = 0x0;
4617 rtlphy->iqk_matrix[i].value[0][3] = 0x0;
4618 rtlphy->iqk_matrix[i].value[0][5] = 0x0;
4619 rtlphy->iqk_matrix[i].value[0][7] = 0x0;
4620
4621 rtlphy->iqk_matrix[i].iqk_done = false;
4622 }
4623}
4624
4625void rtl8821ae_do_iqk(struct ieee80211_hw *hw, u8 delta_thermal_index,
4626 u8 thermal_value, u8 threshold)
4627{
4628 struct rtl_dm *rtldm = rtl_dm(rtl_priv(hw));
4629
4630 rtl8821ae_reset_iqk_result(hw);
4631
4632 rtldm->thermalvalue_iqk = thermal_value;
4633 rtl8821ae_phy_iq_calibrate(hw, false);
4634}
4635
4636void rtl8821ae_phy_lc_calibrate(struct ieee80211_hw *hw)
4637{
4638}
4639
08aba42f 4640void rtl8821ae_phy_ap_calibrate(struct ieee80211_hw *hw, s8 delta)
21e4b072
LF
4641{
4642}
4643
4644void rtl8821ae_phy_set_rfpath_switch(struct ieee80211_hw *hw, bool bmain)
4645{
4646 _rtl8821ae_phy_set_rfpath_switch(hw, bmain);
4647}
4648
4649bool rtl8821ae_phy_set_io_cmd(struct ieee80211_hw *hw, enum io_type iotype)
4650{
4651 struct rtl_priv *rtlpriv = rtl_priv(hw);
4652 struct rtl_phy *rtlphy = &rtlpriv->phy;
4653 bool postprocessing = false;
4654
4655 RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE,
4656 "-->IO Cmd(%#x), set_io_inprogress(%d)\n",
4657 iotype, rtlphy->set_io_inprogress);
4658 do {
4659 switch (iotype) {
4660 case IO_CMD_RESUME_DM_BY_SCAN:
4661 RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE,
4662 "[IO CMD] Resume DM after scan.\n");
4663 postprocessing = true;
4664 break;
4665 case IO_CMD_PAUSE_BAND0_DM_BY_SCAN:
4666 case IO_CMD_PAUSE_BAND1_DM_BY_SCAN:
4667 RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE,
4668 "[IO CMD] Pause DM before scan.\n");
4669 postprocessing = true;
4670 break;
4671 default:
4672 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
4673 "switch case not process\n");
4674 break;
4675 }
4676 } while (false);
4677 if (postprocessing && !rtlphy->set_io_inprogress) {
4678 rtlphy->set_io_inprogress = true;
4679 rtlphy->current_io_type = iotype;
4680 } else {
4681 return false;
4682 }
4683 rtl8821ae_phy_set_io(hw);
4684 RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE, "IO Type(%#x)\n", iotype);
4685 return true;
4686}
4687
4688static void rtl8821ae_phy_set_io(struct ieee80211_hw *hw)
4689{
4690 struct rtl_priv *rtlpriv = rtl_priv(hw);
4691 struct dig_t *dm_digtable = &rtlpriv->dm_digtable;
4692 struct rtl_phy *rtlphy = &rtlpriv->phy;
4693
4694 RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE,
4695 "--->Cmd(%#x), set_io_inprogress(%d)\n",
4696 rtlphy->current_io_type, rtlphy->set_io_inprogress);
4697 switch (rtlphy->current_io_type) {
4698 case IO_CMD_RESUME_DM_BY_SCAN:
4699 if (rtlpriv->mac80211.opmode == NL80211_IFTYPE_ADHOC)
4700 _rtl8821ae_resume_tx_beacon(hw);
4701 rtl8821ae_dm_write_dig(hw, rtlphy->initgain_backup.xaagccore1);
4702 rtl8821ae_dm_write_cck_cca_thres(hw,
4703 rtlphy->initgain_backup.cca);
4704 break;
4705 case IO_CMD_PAUSE_BAND0_DM_BY_SCAN:
4706 if (rtlpriv->mac80211.opmode == NL80211_IFTYPE_ADHOC)
4707 _rtl8821ae_stop_tx_beacon(hw);
4708 rtlphy->initgain_backup.xaagccore1 = dm_digtable->cur_igvalue;
4709 rtl8821ae_dm_write_dig(hw, 0x17);
4710 rtlphy->initgain_backup.cca = dm_digtable->cur_cck_cca_thres;
4711 rtl8821ae_dm_write_cck_cca_thres(hw, 0x40);
4712 break;
4713 case IO_CMD_PAUSE_BAND1_DM_BY_SCAN:
4714 break;
4715 default:
4716 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
4717 "switch case not process\n");
4718 break;
4719 }
4720 rtlphy->set_io_inprogress = false;
4721 RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE,
4722 "(%#x)\n", rtlphy->current_io_type);
4723}
4724
4725static void rtl8821ae_phy_set_rf_on(struct ieee80211_hw *hw)
4726{
4727 struct rtl_priv *rtlpriv = rtl_priv(hw);
4728
4729 rtl_write_byte(rtlpriv, REG_SPS0_CTRL, 0x2b);
4730 rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE3);
4731 rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE2);
4732 rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE3);
4733 rtl_write_byte(rtlpriv, REG_TXPAUSE, 0x00);
4734}
4735
4736static bool _rtl8821ae_phy_set_rf_power_state(struct ieee80211_hw *hw,
4737 enum rf_pwrstate rfpwr_state)
4738{
4739 struct rtl_priv *rtlpriv = rtl_priv(hw);
4740 struct rtl_pci_priv *pcipriv = rtl_pcipriv(hw);
4741 struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
4742 struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
4743 bool bresult = true;
4744 u8 i, queue_id;
4745 struct rtl8192_tx_ring *ring = NULL;
4746
4747 switch (rfpwr_state) {
4748 case ERFON:
4749 if ((ppsc->rfpwr_state == ERFOFF) &&
4750 RT_IN_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_HALT_NIC)) {
4751 bool rtstatus = false;
4752 u32 initializecount = 0;
4753
4754 do {
4755 initializecount++;
4756 RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG,
4757 "IPS Set eRf nic enable\n");
4758 rtstatus = rtl_ps_enable_nic(hw);
4759 } while (!rtstatus && (initializecount < 10));
4760 RT_CLEAR_PS_LEVEL(ppsc,
4761 RT_RF_OFF_LEVL_HALT_NIC);
4762 } else {
4763 RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG,
4764 "Set ERFON sleeped:%d ms\n",
4765 jiffies_to_msecs(jiffies -
4766 ppsc->
4767 last_sleep_jiffies));
4768 ppsc->last_awake_jiffies = jiffies;
4769 rtl8821ae_phy_set_rf_on(hw);
4770 }
4771 if (mac->link_state == MAC80211_LINKED) {
4772 rtlpriv->cfg->ops->led_control(hw,
4773 LED_CTL_LINK);
4774 } else {
4775 rtlpriv->cfg->ops->led_control(hw,
4776 LED_CTL_NO_LINK);
4777 }
4778 break;
4779 case ERFOFF:
4780 for (queue_id = 0, i = 0;
4781 queue_id < RTL_PCI_MAX_TX_QUEUE_COUNT;) {
4782 ring = &pcipriv->dev.tx_ring[queue_id];
4783 if (queue_id == BEACON_QUEUE ||
4784 skb_queue_len(&ring->queue) == 0) {
4785 queue_id++;
4786 continue;
4787 } else {
4788 RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
4789 "eRf Off/Sleep: %d times TcbBusyQueue[%d] =%d before doze!\n",
4790 (i + 1), queue_id,
4791 skb_queue_len(&ring->queue));
4792
4793 udelay(10);
4794 i++;
4795 }
4796 if (i >= MAX_DOZE_WAITING_TIMES_9x) {
4797 RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
4798 "\n ERFSLEEP: %d times TcbBusyQueue[%d] = %d !\n",
4799 MAX_DOZE_WAITING_TIMES_9x,
4800 queue_id,
4801 skb_queue_len(&ring->queue));
4802 break;
4803 }
4804 }
4805
4806 if (ppsc->reg_rfps_level & RT_RF_OFF_LEVL_HALT_NIC) {
4807 RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG,
4808 "IPS Set eRf nic disable\n");
4809 rtl_ps_disable_nic(hw);
4810 RT_SET_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_HALT_NIC);
4811 } else {
4812 if (ppsc->rfoff_reason == RF_CHANGE_BY_IPS) {
4813 rtlpriv->cfg->ops->led_control(hw,
4814 LED_CTL_NO_LINK);
4815 } else {
4816 rtlpriv->cfg->ops->led_control(hw,
4817 LED_CTL_POWER_OFF);
4818 }
4819 }
4820 break;
4821 default:
4822 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
4823 "switch case not process\n");
4824 bresult = false;
4825 break;
4826 }
4827 if (bresult)
4828 ppsc->rfpwr_state = rfpwr_state;
4829 return bresult;
4830}
4831
4832bool rtl8821ae_phy_set_rf_power_state(struct ieee80211_hw *hw,
4833 enum rf_pwrstate rfpwr_state)
4834{
4835 struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
4836
4837 bool bresult = false;
4838
4839 if (rfpwr_state == ppsc->rfpwr_state)
4840 return bresult;
4841 bresult = _rtl8821ae_phy_set_rf_power_state(hw, rfpwr_state);
4842 return bresult;
4843}
This page took 0.47981 seconds and 5 git commands to generate.