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