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