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