aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/rtlwifi/rtl8723be/phy.c
diff options
context:
space:
mode:
authorLarry Finger <Larry.Finger@lwfinger.net>2014-02-28 16:16:50 -0500
committerJohn W. Linville <linville@tuxdriver.com>2014-03-04 13:25:39 -0500
commita619d1abe20cc892ddd8f6f60345b24d43971fb4 (patch)
tree25643f37e962f1753f45fb3763313ba63cf94144 /drivers/net/wireless/rtlwifi/rtl8723be/phy.c
parent57d9d9630a6b3f289ae87b1fc00e83ae44636766 (diff)
rtlwifi: rtl8723be: Add new driver
Signed-off-by: Larry Finger <Larry.Finger@lwfinger.net> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net/wireless/rtlwifi/rtl8723be/phy.c')
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8723be/phy.c2175
1 files changed, 2175 insertions, 0 deletions
diff --git a/drivers/net/wireless/rtlwifi/rtl8723be/phy.c b/drivers/net/wireless/rtlwifi/rtl8723be/phy.c
new file mode 100644
index 000000000000..ebc1e2788fca
--- /dev/null
+++ b/drivers/net/wireless/rtlwifi/rtl8723be/phy.c
@@ -0,0 +1,2175 @@
1/******************************************************************************
2 *
3 * Copyright(c) 2009-2014 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 "../rtl8723com/phy_common.h"
33#include "rf.h"
34#include "dm.h"
35#include "table.h"
36#include "trx.h"
37
38static bool _rtl8723be_phy_bb8723b_config_parafile(struct ieee80211_hw *hw);
39static bool _rtl8723be_phy_config_bb_with_pgheaderfile(struct ieee80211_hw *hw,
40 u8 configtype);
41static bool rtl8723be_phy_sw_chn_step_by_step(struct ieee80211_hw *hw,
42 u8 channel, u8 *stage,
43 u8 *step, u32 *delay);
44static void _rtl8723be_config_bb_reg(struct ieee80211_hw *hw,
45 u32 addr, u32 data);
46
47static bool _rtl8723be_check_condition(struct ieee80211_hw *hw,
48 const u32 condition)
49{
50 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
51 struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
52 u32 _board = rtlefuse->board_type; /*need efuse define*/
53 u32 _interface = rtlhal->interface;
54 u32 _platform = 0x08;/*SupportPlatform */
55 u32 cond = condition;
56
57 if (condition == 0xCDCDCDCD)
58 return true;
59
60 cond = condition & 0xFF;
61 if ((_board & cond) == 0 && cond != 0x1F)
62 return false;
63
64 cond = condition & 0xFF00;
65 cond = cond >> 8;
66 if ((_interface & cond) == 0 && cond != 0x07)
67 return false;
68
69 cond = condition & 0xFF0000;
70 cond = cond >> 16;
71 if ((_platform & cond) == 0 && cond != 0x0F)
72 return false;
73 return true;
74}
75
76static bool _rtl8723be_phy_config_mac_with_headerfile(struct ieee80211_hw *hw)
77{
78 struct rtl_priv *rtlpriv = rtl_priv(hw);
79 u32 i;
80 u32 arraylength;
81 u32 *ptrarray;
82
83 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, "Read rtl8723beMACPHY_Array\n");
84 arraylength = RTL8723BEMAC_1T_ARRAYLEN;
85 ptrarray = RTL8723BEMAC_1T_ARRAY;
86 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
87 "Img:RTL8723bEMAC_1T_ARRAY LEN %d\n", arraylength);
88 for (i = 0; i < arraylength; i = i + 2)
89 rtl_write_byte(rtlpriv, ptrarray[i], (u8) ptrarray[i + 1]);
90 return true;
91}
92
93static bool _rtl8723be_phy_config_bb_with_headerfile(struct ieee80211_hw *hw,
94 u8 configtype)
95{
96 #define READ_NEXT_PAIR(v1, v2, i) \
97 do { \
98 i += 2; \
99 v1 = array_table[i];\
100 v2 = array_table[i+1]; \
101 } while (0)
102
103 int i;
104 u32 *array_table;
105 u16 arraylen;
106 struct rtl_priv *rtlpriv = rtl_priv(hw);
107 u32 v1 = 0, v2 = 0;
108
109 if (configtype == BASEBAND_CONFIG_PHY_REG) {
110 arraylen = RTL8723BEPHY_REG_1TARRAYLEN;
111 array_table = RTL8723BEPHY_REG_1TARRAY;
112
113 for (i = 0; i < arraylen; i = i + 2) {
114 v1 = array_table[i];
115 v2 = array_table[i+1];
116 if (v1 < 0xcdcdcdcd) {
117 _rtl8723be_config_bb_reg(hw, v1, v2);
118 } else {/*This line is the start line of branch.*/
119 if (!_rtl8723be_check_condition(hw, array_table[i])) {
120 /*Discard the following (offset, data) pairs*/
121 READ_NEXT_PAIR(v1, v2, i);
122 while (v2 != 0xDEAD &&
123 v2 != 0xCDEF &&
124 v2 != 0xCDCD &&
125 i < arraylen - 2) {
126 READ_NEXT_PAIR(v1, v2, i);
127 }
128 i -= 2; /* prevent from for-loop += 2*/
129 /* Configure matched pairs and
130 * skip to end of if-else.
131 */
132 } else {
133 READ_NEXT_PAIR(v1, v2, i);
134 while (v2 != 0xDEAD &&
135 v2 != 0xCDEF &&
136 v2 != 0xCDCD &&
137 i < arraylen - 2) {
138 _rtl8723be_config_bb_reg(hw,
139 v1, v2);
140 READ_NEXT_PAIR(v1, v2, i);
141 }
142
143 while (v2 != 0xDEAD && i < arraylen - 2)
144 READ_NEXT_PAIR(v1, v2, i);
145 }
146 }
147 }
148 } else if (configtype == BASEBAND_CONFIG_AGC_TAB) {
149 arraylen = RTL8723BEAGCTAB_1TARRAYLEN;
150 array_table = RTL8723BEAGCTAB_1TARRAY;
151
152 for (i = 0; i < arraylen; i = i + 2) {
153 v1 = array_table[i];
154 v2 = array_table[i+1];
155 if (v1 < 0xCDCDCDCD) {
156 rtl_set_bbreg(hw, array_table[i],
157 MASKDWORD,
158 array_table[i + 1]);
159 udelay(1);
160 continue;
161 } else {/*This line is the start line of branch.*/
162 if (!_rtl8723be_check_condition(hw, array_table[i])) {
163 /* Discard the following
164 * (offset, data) pairs
165 */
166 READ_NEXT_PAIR(v1, v2, i);
167 while (v2 != 0xDEAD &&
168 v2 != 0xCDEF &&
169 v2 != 0xCDCD &&
170 i < arraylen - 2) {
171 READ_NEXT_PAIR(v1, v2, i);
172 }
173 i -= 2; /* prevent from for-loop += 2*/
174 /*Configure matched pairs and
175 *skip to end of if-else.
176 */
177 } else {
178 READ_NEXT_PAIR(v1, v2, i);
179 while (v2 != 0xDEAD &&
180 v2 != 0xCDEF &&
181 v2 != 0xCDCD &&
182 i < arraylen - 2) {
183 rtl_set_bbreg(hw, array_table[i],
184 MASKDWORD,
185 array_table[i + 1]);
186 udelay(1);
187 READ_NEXT_PAIR(v1, v2, i);
188 }
189
190 while (v2 != 0xDEAD && i < arraylen - 2)
191 READ_NEXT_PAIR(v1, v2, i);
192 }
193 }
194 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
195 "The agctab_array_table[0] is "
196 "%x Rtl818EEPHY_REGArray[1] is %x\n",
197 array_table[i], array_table[i + 1]);
198 }
199 }
200 return true;
201}
202
203static u8 _rtl8723be_get_rate_section_index(u32 regaddr)
204{
205 u8 index = 0;
206
207 switch (regaddr) {
208 case RTXAGC_A_RATE18_06:
209 case RTXAGC_B_RATE18_06:
210 index = 0;
211 break;
212 case RTXAGC_A_RATE54_24:
213 case RTXAGC_B_RATE54_24:
214 index = 1;
215 break;
216 case RTXAGC_A_CCK1_MCS32:
217 case RTXAGC_B_CCK1_55_MCS32:
218 index = 2;
219 break;
220 case RTXAGC_B_CCK11_A_CCK2_11:
221 index = 3;
222 break;
223 case RTXAGC_A_MCS03_MCS00:
224 case RTXAGC_B_MCS03_MCS00:
225 index = 4;
226 break;
227 case RTXAGC_A_MCS07_MCS04:
228 case RTXAGC_B_MCS07_MCS04:
229 index = 5;
230 break;
231 case RTXAGC_A_MCS11_MCS08:
232 case RTXAGC_B_MCS11_MCS08:
233 index = 6;
234 break;
235 case RTXAGC_A_MCS15_MCS12:
236 case RTXAGC_B_MCS15_MCS12:
237 index = 7;
238 break;
239 default:
240 regaddr &= 0xFFF;
241 if (regaddr >= 0xC20 && regaddr <= 0xC4C)
242 index = (u8) ((regaddr - 0xC20) / 4);
243 else if (regaddr >= 0xE20 && regaddr <= 0xE4C)
244 index = (u8) ((regaddr - 0xE20) / 4);
245 break;
246 };
247 return index;
248}
249
250u32 rtl8723be_phy_query_rf_reg(struct ieee80211_hw *hw, enum radio_path rfpath,
251 u32 regaddr, u32 bitmask)
252{
253 struct rtl_priv *rtlpriv = rtl_priv(hw);
254 u32 original_value, readback_value, bitshift;
255 unsigned long flags;
256
257 RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE,
258 "regaddr(%#x), rfpath(%#x), bitmask(%#x)\n",
259 regaddr, rfpath, bitmask);
260
261 spin_lock_irqsave(&rtlpriv->locks.rf_lock, flags);
262
263 original_value = rtl8723_phy_rf_serial_read(hw, rfpath, regaddr);
264 bitshift = rtl8723_phy_calculate_bit_shift(bitmask);
265 readback_value = (original_value & bitmask) >> bitshift;
266
267 spin_unlock_irqrestore(&rtlpriv->locks.rf_lock, flags);
268
269 RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE,
270 "regaddr(%#x), rfpath(%#x), "
271 "bitmask(%#x), original_value(%#x)\n",
272 regaddr, rfpath, bitmask, original_value);
273
274 return readback_value;
275}
276
277void rtl8723be_phy_set_rf_reg(struct ieee80211_hw *hw, enum radio_path path,
278 u32 regaddr, u32 bitmask, u32 data)
279{
280 struct rtl_priv *rtlpriv = rtl_priv(hw);
281 u32 original_value, bitshift;
282 unsigned long flags;
283
284 RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE,
285 "regaddr(%#x), bitmask(%#x), data(%#x), rfpath(%#x)\n",
286 regaddr, bitmask, data, path);
287
288 spin_lock_irqsave(&rtlpriv->locks.rf_lock, flags);
289
290 if (bitmask != RFREG_OFFSET_MASK) {
291 original_value = rtl8723_phy_rf_serial_read(hw, path,
292 regaddr);
293 bitshift = rtl8723_phy_calculate_bit_shift(bitmask);
294 data = ((original_value & (~bitmask)) |
295 (data << bitshift));
296 }
297
298 rtl8723_phy_rf_serial_write(hw, path, regaddr, data);
299
300 spin_unlock_irqrestore(&rtlpriv->locks.rf_lock, flags);
301
302 RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE,
303 "regaddr(%#x), bitmask(%#x), data(%#x), rfpath(%#x)\n",
304 regaddr, bitmask, data, path);
305}
306
307bool rtl8723be_phy_mac_config(struct ieee80211_hw *hw)
308{
309 struct rtl_priv *rtlpriv = rtl_priv(hw);
310 bool rtstatus = _rtl8723be_phy_config_mac_with_headerfile(hw);
311
312 rtl_write_byte(rtlpriv, 0x04CA, 0x0B);
313 return rtstatus;
314}
315
316bool rtl8723be_phy_bb_config(struct ieee80211_hw *hw)
317{
318 bool rtstatus = true;
319 struct rtl_priv *rtlpriv = rtl_priv(hw);
320 u16 regval;
321 u8 reg_hwparafile = 1;
322 u32 tmp;
323 u8 crystalcap = rtlpriv->efuse.crystalcap;
324 rtl8723_phy_init_bb_rf_reg_def(hw);
325 regval = rtl_read_word(rtlpriv, REG_SYS_FUNC_EN);
326 rtl_write_word(rtlpriv, REG_SYS_FUNC_EN,
327 regval | BIT(13) | BIT(0) | BIT(1));
328
329 rtl_write_byte(rtlpriv, REG_RF_CTRL, RF_EN | RF_RSTB | RF_SDMRSTB);
330 rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN,
331 FEN_PPLL | FEN_PCIEA | FEN_DIO_PCIE |
332 FEN_BB_GLB_RSTN | FEN_BBRSTB);
333 tmp = rtl_read_dword(rtlpriv, 0x4c);
334 rtl_write_dword(rtlpriv, 0x4c, tmp | BIT(23));
335
336 rtl_write_byte(rtlpriv, REG_AFE_XTAL_CTRL + 1, 0x80);
337
338 if (reg_hwparafile == 1)
339 rtstatus = _rtl8723be_phy_bb8723b_config_parafile(hw);
340
341 crystalcap = crystalcap & 0x3F;
342 rtl_set_bbreg(hw, REG_MAC_PHY_CTRL, 0xFFF000,
343 (crystalcap | crystalcap << 6));
344
345 return rtstatus;
346}
347
348bool rtl8723be_phy_rf_config(struct ieee80211_hw *hw)
349{
350 return rtl8723be_phy_rf6052_config(hw);
351}
352
353static void _rtl8723be_config_rf_reg(struct ieee80211_hw *hw, u32 addr,
354 u32 data, enum radio_path rfpath,
355 u32 regaddr)
356{
357 if (addr == 0xfe || addr == 0xffe) {
358 mdelay(50);
359 } else {
360 rtl_set_rfreg(hw, rfpath, regaddr, RFREG_OFFSET_MASK, data);
361 udelay(1);
362 }
363}
364
365static void _rtl8723be_config_rf_radio_a(struct ieee80211_hw *hw,
366 u32 addr, u32 data)
367{
368 u32 content = 0x1000; /*RF Content: radio_a_txt*/
369 u32 maskforphyset = (u32)(content & 0xE000);
370
371 _rtl8723be_config_rf_reg(hw, addr, data, RF90_PATH_A,
372 addr | maskforphyset);
373}
374
375static void _rtl8723be_phy_init_tx_power_by_rate(struct ieee80211_hw *hw)
376{
377 struct rtl_priv *rtlpriv = rtl_priv(hw);
378 struct rtl_phy *rtlphy = &(rtlpriv->phy);
379
380 u8 band, path, txnum, section;
381
382 for (band = BAND_ON_2_4G; band <= BAND_ON_5G; ++band)
383 for (path = 0; path < TX_PWR_BY_RATE_NUM_RF; ++path)
384 for (txnum = 0; txnum < TX_PWR_BY_RATE_NUM_RF; ++txnum)
385 for (section = 0;
386 section < TX_PWR_BY_RATE_NUM_SECTION;
387 ++section)
388 rtlphy->tx_power_by_rate_offset[band]
389 [path][txnum][section] = 0;
390}
391
392static void _rtl8723be_config_bb_reg(struct ieee80211_hw *hw,
393 u32 addr, u32 data)
394{
395 if (addr == 0xfe) {
396 mdelay(50);
397 } else if (addr == 0xfd) {
398 mdelay(5);
399 } else if (addr == 0xfc) {
400 mdelay(1);
401 } else if (addr == 0xfb) {
402 udelay(50);
403 } else if (addr == 0xfa) {
404 udelay(5);
405 } else if (addr == 0xf9) {
406 udelay(1);
407 } else {
408 rtl_set_bbreg(hw, addr, MASKDWORD, data);
409 udelay(1);
410 }
411}
412
413static void phy_set_txpwr_by_rate_base(struct ieee80211_hw *hw, u8 band,
414 u8 path, u8 rate_section,
415 u8 txnum, u8 value)
416{
417 struct rtl_priv *rtlpriv = rtl_priv(hw);
418 struct rtl_phy *rtlphy = &(rtlpriv->phy);
419
420 if (path > RF90_PATH_D) {
421 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
422 "Invalid Rf Path %d in phy_SetTxPowerByRatBase()\n",
423 path);
424 return;
425 }
426
427 if (band == BAND_ON_2_4G) {
428 switch (rate_section) {
429 case CCK:
430 rtlphy->txpwr_by_rate_base_24g[path][txnum][0] = value;
431 break;
432 case OFDM:
433 rtlphy->txpwr_by_rate_base_24g[path][txnum][1] = value;
434 break;
435 case HT_MCS0_MCS7:
436 rtlphy->txpwr_by_rate_base_24g[path][txnum][2] = value;
437 break;
438 case HT_MCS8_MCS15:
439 rtlphy->txpwr_by_rate_base_24g[path][txnum][3] = value;
440 break;
441 default:
442 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
443 "Invalid RateSection %d in Band 2.4G, Rf Path"
444 " %d, %dTx in PHY_SetTxPowerByRateBase()\n",
445 rate_section, path, txnum);
446 break;
447 };
448 } else {
449 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
450 "Invalid Band %d in PHY_SetTxPowerByRateBase()\n",
451 band);
452 }
453}
454
455static u8 phy_get_txpwr_by_rate_base(struct ieee80211_hw *hw, u8 band, u8 path,
456 u8 txnum, u8 rate_section)
457{
458 struct rtl_priv *rtlpriv = rtl_priv(hw);
459 struct rtl_phy *rtlphy = &(rtlpriv->phy);
460 u8 value = 0;
461 if (path > RF90_PATH_D) {
462 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
463 "Invalid Rf Path %d in PHY_GetTxPowerByRateBase()\n",
464 path);
465 return 0;
466 }
467
468 if (band == BAND_ON_2_4G) {
469 switch (rate_section) {
470 case CCK:
471 value = rtlphy->txpwr_by_rate_base_24g[path][txnum][0];
472 break;
473 case OFDM:
474 value = rtlphy->txpwr_by_rate_base_24g[path][txnum][1];
475 break;
476 case HT_MCS0_MCS7:
477 value = rtlphy->txpwr_by_rate_base_24g[path][txnum][2];
478 break;
479 case HT_MCS8_MCS15:
480 value = rtlphy->txpwr_by_rate_base_24g[path][txnum][3];
481 break;
482 default:
483 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
484 "Invalid RateSection %d in Band 2.4G, Rf Path"
485 " %d, %dTx in PHY_GetTxPowerByRateBase()\n",
486 rate_section, path, txnum);
487 break;
488 };
489 } else {
490 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
491 "Invalid Band %d in PHY_GetTxPowerByRateBase()\n",
492 band);
493 }
494
495 return value;
496}
497
498static void _rtl8723be_phy_store_txpower_by_rate_base(struct ieee80211_hw *hw)
499{
500 struct rtl_priv *rtlpriv = rtl_priv(hw);
501 struct rtl_phy *rtlphy = &(rtlpriv->phy);
502 u16 raw_value = 0;
503 u8 base = 0, path = 0;
504
505 for (path = RF90_PATH_A; path <= RF90_PATH_B; ++path) {
506 if (path == RF90_PATH_A) {
507 raw_value = (u16) (rtlphy->tx_power_by_rate_offset
508 [BAND_ON_2_4G][path][RF_1TX][3] >> 24) & 0xFF;
509 base = (raw_value >> 4) * 10 + (raw_value & 0xF);
510 phy_set_txpwr_by_rate_base(hw, BAND_ON_2_4G, path, CCK,
511 RF_1TX, base);
512 } else if (path == RF90_PATH_B) {
513 raw_value = (u16) (rtlphy->tx_power_by_rate_offset
514 [BAND_ON_2_4G][path][RF_1TX][3] >> 0) & 0xFF;
515 base = (raw_value >> 4) * 10 + (raw_value & 0xF);
516 phy_set_txpwr_by_rate_base(hw, BAND_ON_2_4G, path,
517 CCK, RF_1TX, base);
518 }
519 raw_value = (u16) (rtlphy->tx_power_by_rate_offset[BAND_ON_2_4G]
520 [path][RF_1TX][1] >> 24) & 0xFF;
521 base = (raw_value >> 4) * 10 + (raw_value & 0xF);
522 phy_set_txpwr_by_rate_base(hw, BAND_ON_2_4G, path, OFDM, RF_1TX,
523 base);
524
525 raw_value = (u16) (rtlphy->tx_power_by_rate_offset[BAND_ON_2_4G]
526 [path][RF_1TX][5] >> 24) & 0xFF;
527 base = (raw_value >> 4) * 10 + (raw_value & 0xF);
528 phy_set_txpwr_by_rate_base(hw, BAND_ON_2_4G, path, HT_MCS0_MCS7,
529 RF_1TX, base);
530
531 raw_value = (u16) (rtlphy->tx_power_by_rate_offset[BAND_ON_2_4G]
532 [path][RF_2TX][7] >> 24) & 0xFF;
533 base = (raw_value >> 4) * 10 + (raw_value & 0xF);
534 phy_set_txpwr_by_rate_base(hw, BAND_ON_2_4G, path,
535 HT_MCS8_MCS15, RF_2TX, base);
536 }
537}
538
539static void phy_conv_dbm_to_rel(u32 *data, u8 start, u8 end, u8 base_val)
540{
541 char i = 0;
542 u8 temp_value = 0;
543 u32 temp_data = 0;
544
545 for (i = 3; i >= 0; --i) {
546 if (i >= start && i <= end) {
547 /* Get the exact value */
548 temp_value = (u8) (*data >> (i * 8)) & 0xF;
549 temp_value += ((u8) ((*data >> (i*8 + 4)) & 0xF)) * 10;
550
551 /* Change the value to a relative value */
552 temp_value = (temp_value > base_val) ?
553 temp_value - base_val :
554 base_val - temp_value;
555 } else {
556 temp_value = (u8) (*data >> (i * 8)) & 0xFF;
557 }
558 temp_data <<= 8;
559 temp_data |= temp_value;
560 }
561 *data = temp_data;
562}
563
564static void conv_dbm_to_rel(struct ieee80211_hw *hw)
565{
566 struct rtl_priv *rtlpriv = rtl_priv(hw);
567 struct rtl_phy *rtlphy = &(rtlpriv->phy);
568 u8 base = 0, rfpath = RF90_PATH_A;
569
570 base = phy_get_txpwr_by_rate_base(hw, BAND_ON_2_4G, rfpath,
571 RF_1TX, CCK);
572 phy_conv_dbm_to_rel(&(rtlphy->tx_power_by_rate_offset[BAND_ON_2_4G]
573 [rfpath][RF_1TX][2]), 1, 1, base);
574 phy_conv_dbm_to_rel(&(rtlphy->tx_power_by_rate_offset[BAND_ON_2_4G]
575 [rfpath][RF_1TX][3]), 1, 3, base);
576
577 base = phy_get_txpwr_by_rate_base(hw, BAND_ON_2_4G, rfpath,
578 RF_1TX, OFDM);
579 phy_conv_dbm_to_rel(&(rtlphy->tx_power_by_rate_offset[BAND_ON_2_4G]
580 [rfpath][RF_1TX][0]), 0, 3, base);
581 phy_conv_dbm_to_rel(&(rtlphy->tx_power_by_rate_offset[BAND_ON_2_4G]
582 [rfpath][RF_1TX][1]), 0, 3, base);
583
584 base = phy_get_txpwr_by_rate_base(hw, BAND_ON_2_4G, rfpath,
585 RF_1TX, HT_MCS0_MCS7);
586 phy_conv_dbm_to_rel(&(rtlphy->tx_power_by_rate_offset[BAND_ON_2_4G]
587 [rfpath][RF_1TX][4]), 0, 3, base);
588 phy_conv_dbm_to_rel(&(rtlphy->tx_power_by_rate_offset[BAND_ON_2_4G]
589 [rfpath][RF_1TX][5]), 0, 3, base);
590
591 base = phy_get_txpwr_by_rate_base(hw, BAND_ON_2_4G, rfpath,
592 RF_2TX, HT_MCS8_MCS15);
593 phy_conv_dbm_to_rel(&(rtlphy->tx_power_by_rate_offset[BAND_ON_2_4G]
594 [rfpath][RF_2TX][6]), 0, 3, base);
595
596 phy_conv_dbm_to_rel(&(rtlphy->tx_power_by_rate_offset[BAND_ON_2_4G]
597 [rfpath][RF_2TX][7]), 0, 3, base);
598
599 RT_TRACE(rtlpriv, COMP_POWER, DBG_TRACE,
600 "<=== conv_dbm_to_rel()\n");
601}
602
603static void _rtl8723be_phy_txpower_by_rate_configuration(
604 struct ieee80211_hw *hw)
605{
606 _rtl8723be_phy_store_txpower_by_rate_base(hw);
607 conv_dbm_to_rel(hw);
608}
609
610static bool _rtl8723be_phy_bb8723b_config_parafile(struct ieee80211_hw *hw)
611{
612 struct rtl_priv *rtlpriv = rtl_priv(hw);
613 struct rtl_phy *rtlphy = &(rtlpriv->phy);
614 struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
615 bool rtstatus;
616
617 rtstatus = _rtl8723be_phy_config_bb_with_headerfile(hw,
618 BASEBAND_CONFIG_PHY_REG);
619 if (!rtstatus) {
620 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, "Write BB Reg Fail!!");
621 return false;
622 }
623 _rtl8723be_phy_init_tx_power_by_rate(hw);
624 if (!rtlefuse->autoload_failflag) {
625 rtlphy->pwrgroup_cnt = 0;
626 rtstatus = _rtl8723be_phy_config_bb_with_pgheaderfile(hw,
627 BASEBAND_CONFIG_PHY_REG);
628 }
629 _rtl8723be_phy_txpower_by_rate_configuration(hw);
630 if (!rtstatus) {
631 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, "BB_PG Reg Fail!!");
632 return false;
633 }
634 rtstatus = _rtl8723be_phy_config_bb_with_headerfile(hw,
635 BASEBAND_CONFIG_AGC_TAB);
636 if (!rtstatus) {
637 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, "AGC Table Fail\n");
638 return false;
639 }
640 rtlphy->cck_high_power = (bool) (rtl_get_bbreg(hw,
641 RFPGA0_XA_HSSIPARAMETER2,
642 0x200));
643 return true;
644}
645
646static void _rtl8723be_store_tx_power_by_rate(struct ieee80211_hw *hw,
647 u32 band, u32 rfpath,
648 u32 txnum, u32 regaddr,
649 u32 bitmask, u32 data)
650{
651 struct rtl_priv *rtlpriv = rtl_priv(hw);
652 struct rtl_phy *rtlphy = &(rtlpriv->phy);
653 u8 rate_section = _rtl8723be_get_rate_section_index(regaddr);
654
655 if (band != BAND_ON_2_4G && band != BAND_ON_5G)
656 RT_TRACE(rtlpriv, COMP_POWER, PHY_TXPWR,
657 "Invalid Band %d\n", band);
658
659 if (rfpath > MAX_RF_PATH)
660 RT_TRACE(rtlpriv, COMP_POWER, PHY_TXPWR,
661 "Invalid RfPath %d\n", rfpath);
662
663 if (txnum > MAX_RF_PATH)
664 RT_TRACE(rtlpriv, COMP_POWER, PHY_TXPWR,
665 "Invalid TxNum %d\n", txnum);
666
667 rtlphy->tx_power_by_rate_offset[band][rfpath][txnum][rate_section] =
668 data;
669}
670
671static bool _rtl8723be_phy_config_bb_with_pgheaderfile(struct ieee80211_hw *hw,
672 u8 configtype)
673{
674 struct rtl_priv *rtlpriv = rtl_priv(hw);
675 int i;
676 u32 *phy_regarray_table_pg;
677 u16 phy_regarray_pg_len;
678 u32 v1 = 0, v2 = 0, v3 = 0, v4 = 0, v5 = 0, v6 = 0;
679
680 phy_regarray_pg_len = RTL8723BEPHY_REG_ARRAY_PGLEN;
681 phy_regarray_table_pg = RTL8723BEPHY_REG_ARRAY_PG;
682
683 if (configtype == BASEBAND_CONFIG_PHY_REG) {
684 for (i = 0; i < phy_regarray_pg_len; i = i + 6) {
685 v1 = phy_regarray_table_pg[i];
686 v2 = phy_regarray_table_pg[i+1];
687 v3 = phy_regarray_table_pg[i+2];
688 v4 = phy_regarray_table_pg[i+3];
689 v5 = phy_regarray_table_pg[i+4];
690 v6 = phy_regarray_table_pg[i+5];
691
692 if (v1 < 0xcdcdcdcd) {
693 if (phy_regarray_table_pg[i] == 0xfe ||
694 phy_regarray_table_pg[i] == 0xffe)
695 mdelay(50);
696 else
697 _rtl8723be_store_tx_power_by_rate(hw,
698 v1, v2, v3, v4, v5, v6);
699 continue;
700 } else {
701 /*don't need the hw_body*/
702 if (!_rtl8723be_check_condition(hw,
703 phy_regarray_table_pg[i])) {
704 i += 2; /* skip the pair of expression*/
705 v1 = phy_regarray_table_pg[i];
706 v2 = phy_regarray_table_pg[i+1];
707 v3 = phy_regarray_table_pg[i+2];
708 while (v2 != 0xDEAD) {
709 i += 3;
710 v1 = phy_regarray_table_pg[i];
711 v2 = phy_regarray_table_pg[i+1];
712 v3 = phy_regarray_table_pg[i+2];
713 }
714 }
715 }
716 }
717 } else {
718 RT_TRACE(rtlpriv, COMP_SEND, DBG_TRACE,
719 "configtype != BaseBand_Config_PHY_REG\n");
720 }
721 return true;
722}
723
724bool rtl8723be_phy_config_rf_with_headerfile(struct ieee80211_hw *hw,
725 enum radio_path rfpath)
726{
727 #define READ_NEXT_RF_PAIR(v1, v2, i) \
728 do { \
729 i += 2; \
730 v1 = radioa_array_table[i]; \
731 v2 = radioa_array_table[i+1]; \
732 } while (0)
733
734 int i;
735 bool rtstatus = true;
736 u32 *radioa_array_table;
737 u16 radioa_arraylen;
738 struct rtl_priv *rtlpriv = rtl_priv(hw);
739 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
740 u32 v1 = 0, v2 = 0;
741
742 radioa_arraylen = RTL8723BE_RADIOA_1TARRAYLEN;
743 radioa_array_table = RTL8723BE_RADIOA_1TARRAY;
744 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
745 "Radio_A:RTL8723BE_RADIOA_1TARRAY %d\n", radioa_arraylen);
746 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "Radio No %x\n", rfpath);
747 rtstatus = true;
748 switch (rfpath) {
749 case RF90_PATH_A:
750 for (i = 0; i < radioa_arraylen; i = i + 2) {
751 v1 = radioa_array_table[i];
752 v2 = radioa_array_table[i+1];
753 if (v1 < 0xcdcdcdcd) {
754 _rtl8723be_config_rf_radio_a(hw, v1, v2);
755 } else { /*This line is the start line of branch.*/
756 if (!_rtl8723be_check_condition(hw,
757 radioa_array_table[i])) {
758 /* Discard the following
759 * (offset, data) pairs
760 */
761 READ_NEXT_RF_PAIR(v1, v2, i);
762 while (v2 != 0xDEAD &&
763 v2 != 0xCDEF &&
764 v2 != 0xCDCD &&
765 i < radioa_arraylen - 2)
766 READ_NEXT_RF_PAIR(v1, v2, i);
767 i -= 2; /* prevent from for-loop += 2*/
768 } else {
769 /* Configure matched pairs
770 * and skip to end of if-else.
771 */
772 READ_NEXT_RF_PAIR(v1, v2, i);
773 while (v2 != 0xDEAD &&
774 v2 != 0xCDEF &&
775 v2 != 0xCDCD &&
776 i < radioa_arraylen - 2) {
777 _rtl8723be_config_rf_radio_a(hw,
778 v1, v2);
779 READ_NEXT_RF_PAIR(v1, v2, i);
780 }
781
782 while (v2 != 0xDEAD &&
783 i < radioa_arraylen - 2) {
784 READ_NEXT_RF_PAIR(v1, v2, i);
785 }
786 }
787 }
788 }
789
790 if (rtlhal->oem_id == RT_CID_819X_HP)
791 _rtl8723be_config_rf_radio_a(hw, 0x52, 0x7E4BD);
792
793 break;
794 case RF90_PATH_B:
795 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
796 "switch case not process\n");
797 break;
798 case RF90_PATH_C:
799 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
800 "switch case not process\n");
801 break;
802 case RF90_PATH_D:
803 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
804 "switch case not process\n");
805 break;
806 }
807 return true;
808}
809
810void rtl8723be_phy_get_hw_reg_originalvalue(struct ieee80211_hw *hw)
811{
812 struct rtl_priv *rtlpriv = rtl_priv(hw);
813 struct rtl_phy *rtlphy = &(rtlpriv->phy);
814
815 rtlphy->default_initialgain[0] =
816 (u8) rtl_get_bbreg(hw, ROFDM0_XAAGCCORE1, MASKBYTE0);
817 rtlphy->default_initialgain[1] =
818 (u8) rtl_get_bbreg(hw, ROFDM0_XBAGCCORE1, MASKBYTE0);
819 rtlphy->default_initialgain[2] =
820 (u8) rtl_get_bbreg(hw, ROFDM0_XCAGCCORE1, MASKBYTE0);
821 rtlphy->default_initialgain[3] =
822 (u8) rtl_get_bbreg(hw, ROFDM0_XDAGCCORE1, MASKBYTE0);
823
824 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
825 "Default initial gain (c50 = 0x%x, "
826 "c58 = 0x%x, c60 = 0x%x, c68 = 0x%x\n",
827 rtlphy->default_initialgain[0],
828 rtlphy->default_initialgain[1],
829 rtlphy->default_initialgain[2],
830 rtlphy->default_initialgain[3]);
831
832 rtlphy->framesync = (u8) rtl_get_bbreg(hw, ROFDM0_RXDETECTOR3,
833 MASKBYTE0);
834 rtlphy->framesync_c34 = rtl_get_bbreg(hw, ROFDM0_RXDETECTOR2,
835 MASKDWORD);
836
837 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
838 "Default framesync (0x%x) = 0x%x\n",
839 ROFDM0_RXDETECTOR3, rtlphy->framesync);
840}
841
842void rtl8723be_phy_get_txpower_level(struct ieee80211_hw *hw, long *powerlevel)
843{
844 struct rtl_priv *rtlpriv = rtl_priv(hw);
845 struct rtl_phy *rtlphy = &(rtlpriv->phy);
846 u8 txpwr_level;
847 long txpwr_dbm;
848
849 txpwr_level = rtlphy->cur_cck_txpwridx;
850 txpwr_dbm = rtl8723_phy_txpwr_idx_to_dbm(hw, WIRELESS_MODE_B,
851 txpwr_level);
852 txpwr_level = rtlphy->cur_ofdm24g_txpwridx;
853 if (rtl8723_phy_txpwr_idx_to_dbm(hw, WIRELESS_MODE_G, txpwr_level) >
854 txpwr_dbm)
855 txpwr_dbm =
856 rtl8723_phy_txpwr_idx_to_dbm(hw, WIRELESS_MODE_G,
857 txpwr_level);
858 txpwr_level = rtlphy->cur_ofdm24g_txpwridx;
859 if (rtl8723_phy_txpwr_idx_to_dbm(hw, WIRELESS_MODE_N_24G,
860 txpwr_level) > txpwr_dbm)
861 txpwr_dbm =
862 rtl8723_phy_txpwr_idx_to_dbm(hw, WIRELESS_MODE_N_24G,
863 txpwr_level);
864 *powerlevel = txpwr_dbm;
865}
866
867static u8 _rtl8723be_phy_get_ratesection_intxpower_byrate(enum radio_path path,
868 u8 rate)
869{
870 u8 rate_section = 0;
871
872 switch (rate) {
873 case DESC92C_RATE1M:
874 rate_section = 2;
875 break;
876 case DESC92C_RATE2M:
877 case DESC92C_RATE5_5M:
878 if (path == RF90_PATH_A)
879 rate_section = 3;
880 else if (path == RF90_PATH_B)
881 rate_section = 2;
882 break;
883 case DESC92C_RATE11M:
884 rate_section = 3;
885 break;
886 case DESC92C_RATE6M:
887 case DESC92C_RATE9M:
888 case DESC92C_RATE12M:
889 case DESC92C_RATE18M:
890 rate_section = 0;
891 break;
892 case DESC92C_RATE24M:
893 case DESC92C_RATE36M:
894 case DESC92C_RATE48M:
895 case DESC92C_RATE54M:
896 rate_section = 1;
897 break;
898 case DESC92C_RATEMCS0:
899 case DESC92C_RATEMCS1:
900 case DESC92C_RATEMCS2:
901 case DESC92C_RATEMCS3:
902 rate_section = 4;
903 break;
904 case DESC92C_RATEMCS4:
905 case DESC92C_RATEMCS5:
906 case DESC92C_RATEMCS6:
907 case DESC92C_RATEMCS7:
908 rate_section = 5;
909 break;
910 case DESC92C_RATEMCS8:
911 case DESC92C_RATEMCS9:
912 case DESC92C_RATEMCS10:
913 case DESC92C_RATEMCS11:
914 rate_section = 6;
915 break;
916 case DESC92C_RATEMCS12:
917 case DESC92C_RATEMCS13:
918 case DESC92C_RATEMCS14:
919 case DESC92C_RATEMCS15:
920 rate_section = 7;
921 break;
922 default:
923 RT_ASSERT(true, "Rate_Section is Illegal\n");
924 break;
925 }
926 return rate_section;
927}
928
929static u8 _rtl8723be_get_txpower_by_rate(struct ieee80211_hw *hw,
930 enum band_type band,
931 enum radio_path rfpath, u8 rate)
932{
933 struct rtl_priv *rtlpriv = rtl_priv(hw);
934 struct rtl_phy *rtlphy = &(rtlpriv->phy);
935 u8 shift = 0, rate_section, tx_num;
936 char tx_pwr_diff = 0;
937
938 rate_section = _rtl8723be_phy_get_ratesection_intxpower_byrate(rfpath,
939 rate);
940 tx_num = RF_TX_NUM_NONIMPLEMENT;
941
942 if (tx_num == RF_TX_NUM_NONIMPLEMENT) {
943 if (rate >= DESC92C_RATEMCS8 && rate <= DESC92C_RATEMCS15)
944 tx_num = RF_2TX;
945 else
946 tx_num = RF_1TX;
947 }
948
949 switch (rate) {
950 case DESC92C_RATE6M:
951 case DESC92C_RATE24M:
952 case DESC92C_RATEMCS0:
953 case DESC92C_RATEMCS4:
954 case DESC92C_RATEMCS8:
955 case DESC92C_RATEMCS12:
956 shift = 0;
957 break;
958 case DESC92C_RATE1M:
959 case DESC92C_RATE2M:
960 case DESC92C_RATE9M:
961 case DESC92C_RATE36M:
962 case DESC92C_RATEMCS1:
963 case DESC92C_RATEMCS5:
964 case DESC92C_RATEMCS9:
965 case DESC92C_RATEMCS13:
966 shift = 8;
967 break;
968 case DESC92C_RATE5_5M:
969 case DESC92C_RATE12M:
970 case DESC92C_RATE48M:
971 case DESC92C_RATEMCS2:
972 case DESC92C_RATEMCS6:
973 case DESC92C_RATEMCS10:
974 case DESC92C_RATEMCS14:
975 shift = 16;
976 break;
977 case DESC92C_RATE11M:
978 case DESC92C_RATE18M:
979 case DESC92C_RATE54M:
980 case DESC92C_RATEMCS3:
981 case DESC92C_RATEMCS7:
982 case DESC92C_RATEMCS11:
983 case DESC92C_RATEMCS15:
984 shift = 24;
985 break;
986 default:
987 RT_ASSERT(true, "Rate_Section is Illegal\n");
988 break;
989 }
990 tx_pwr_diff = (u8)(rtlphy->tx_power_by_rate_offset[band][rfpath][tx_num]
991 [rate_section] >> shift) & 0xff;
992
993 return tx_pwr_diff;
994}
995
996static u8 _rtl8723be_get_txpower_index(struct ieee80211_hw *hw, u8 path,
997 u8 rate, u8 bandwidth, u8 channel)
998{
999 struct rtl_priv *rtlpriv = rtl_priv(hw);
1000 struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
1001 u8 index = (channel - 1);
1002 u8 txpower;
1003 u8 power_diff_byrate = 0;
1004
1005 if (channel > 14 || channel < 1) {
1006 index = 0;
1007 RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
1008 "Illegal channel!\n");
1009 }
1010 if (RTL8723E_RX_HAL_IS_CCK_RATE(rate))
1011 txpower = rtlefuse->txpwrlevel_cck[path][index];
1012 else if (DESC92C_RATE6M <= rate)
1013 txpower = rtlefuse->txpwrlevel_ht40_1s[path][index];
1014 else
1015 RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
1016 "invalid rate\n");
1017
1018 if (DESC92C_RATE6M <= rate && rate <= DESC92C_RATE54M &&
1019 !RTL8723E_RX_HAL_IS_CCK_RATE(rate))
1020 txpower += rtlefuse->txpwr_legacyhtdiff[0][TX_1S];
1021
1022 if (bandwidth == HT_CHANNEL_WIDTH_20) {
1023 if (DESC92C_RATEMCS0 <= rate && rate <= DESC92C_RATEMCS15)
1024 txpower += rtlefuse->txpwr_ht20diff[0][TX_1S];
1025 if (DESC92C_RATEMCS8 <= rate && rate <= DESC92C_RATEMCS15)
1026 txpower += rtlefuse->txpwr_ht20diff[0][TX_2S];
1027 } else if (bandwidth == HT_CHANNEL_WIDTH_20_40) {
1028 if (DESC92C_RATEMCS0 <= rate && rate <= DESC92C_RATEMCS15)
1029 txpower += rtlefuse->txpwr_ht40diff[0][TX_1S];
1030 if (DESC92C_RATEMCS8 <= rate && rate <= DESC92C_RATEMCS15)
1031 txpower += rtlefuse->txpwr_ht40diff[0][TX_2S];
1032 }
1033 if (rtlefuse->eeprom_regulatory != 2)
1034 power_diff_byrate = _rtl8723be_get_txpower_by_rate(hw,
1035 BAND_ON_2_4G,
1036 path, rate);
1037
1038 txpower += power_diff_byrate;
1039
1040 if (txpower > MAX_POWER_INDEX)
1041 txpower = MAX_POWER_INDEX;
1042
1043 return txpower;
1044}
1045
1046static void _rtl8723be_phy_set_txpower_index(struct ieee80211_hw *hw,
1047 u8 power_index, u8 path, u8 rate)
1048{
1049 struct rtl_priv *rtlpriv = rtl_priv(hw);
1050 if (path == RF90_PATH_A) {
1051 switch (rate) {
1052 case DESC92C_RATE1M:
1053 rtl8723_phy_set_bb_reg(hw, RTXAGC_A_CCK1_MCS32,
1054 MASKBYTE1, power_index);
1055 break;
1056 case DESC92C_RATE2M:
1057 rtl8723_phy_set_bb_reg(hw, RTXAGC_B_CCK11_A_CCK2_11,
1058 MASKBYTE1, power_index);
1059 break;
1060 case DESC92C_RATE5_5M:
1061 rtl8723_phy_set_bb_reg(hw, RTXAGC_B_CCK11_A_CCK2_11,
1062 MASKBYTE2, power_index);
1063 break;
1064 case DESC92C_RATE11M:
1065 rtl8723_phy_set_bb_reg(hw, RTXAGC_B_CCK11_A_CCK2_11,
1066 MASKBYTE3, power_index);
1067 break;
1068 case DESC92C_RATE6M:
1069 rtl8723_phy_set_bb_reg(hw, RTXAGC_A_RATE18_06,
1070 MASKBYTE0, power_index);
1071 break;
1072 case DESC92C_RATE9M:
1073 rtl8723_phy_set_bb_reg(hw, RTXAGC_A_RATE18_06,
1074 MASKBYTE1, power_index);
1075 break;
1076 case DESC92C_RATE12M:
1077 rtl8723_phy_set_bb_reg(hw, RTXAGC_A_RATE18_06,
1078 MASKBYTE2, power_index);
1079 break;
1080 case DESC92C_RATE18M:
1081 rtl8723_phy_set_bb_reg(hw, RTXAGC_A_RATE18_06,
1082 MASKBYTE3, power_index);
1083 break;
1084 case DESC92C_RATE24M:
1085 rtl8723_phy_set_bb_reg(hw, RTXAGC_A_RATE54_24,
1086 MASKBYTE0, power_index);
1087 break;
1088 case DESC92C_RATE36M:
1089 rtl8723_phy_set_bb_reg(hw, RTXAGC_A_RATE54_24,
1090 MASKBYTE1, power_index);
1091 break;
1092 case DESC92C_RATE48M:
1093 rtl8723_phy_set_bb_reg(hw, RTXAGC_A_RATE54_24,
1094 MASKBYTE2, power_index);
1095 break;
1096 case DESC92C_RATE54M:
1097 rtl8723_phy_set_bb_reg(hw, RTXAGC_A_RATE54_24,
1098 MASKBYTE3, power_index);
1099 break;
1100 case DESC92C_RATEMCS0:
1101 rtl8723_phy_set_bb_reg(hw, RTXAGC_A_MCS03_MCS00,
1102 MASKBYTE0, power_index);
1103 break;
1104 case DESC92C_RATEMCS1:
1105 rtl8723_phy_set_bb_reg(hw, RTXAGC_A_MCS03_MCS00,
1106 MASKBYTE1, power_index);
1107 break;
1108 case DESC92C_RATEMCS2:
1109 rtl8723_phy_set_bb_reg(hw, RTXAGC_A_MCS03_MCS00,
1110 MASKBYTE2, power_index);
1111 break;
1112 case DESC92C_RATEMCS3:
1113 rtl8723_phy_set_bb_reg(hw, RTXAGC_A_MCS03_MCS00,
1114 MASKBYTE3, power_index);
1115 break;
1116 case DESC92C_RATEMCS4:
1117 rtl8723_phy_set_bb_reg(hw, RTXAGC_A_MCS07_MCS04,
1118 MASKBYTE0, power_index);
1119 break;
1120 case DESC92C_RATEMCS5:
1121 rtl8723_phy_set_bb_reg(hw, RTXAGC_A_MCS07_MCS04,
1122 MASKBYTE1, power_index);
1123 break;
1124 case DESC92C_RATEMCS6:
1125 rtl8723_phy_set_bb_reg(hw, RTXAGC_A_MCS07_MCS04,
1126 MASKBYTE2, power_index);
1127 break;
1128 case DESC92C_RATEMCS7:
1129 rtl8723_phy_set_bb_reg(hw, RTXAGC_A_MCS07_MCS04,
1130 MASKBYTE3, power_index);
1131 break;
1132 case DESC92C_RATEMCS8:
1133 rtl8723_phy_set_bb_reg(hw, RTXAGC_A_MCS11_MCS08,
1134 MASKBYTE0, power_index);
1135 break;
1136 case DESC92C_RATEMCS9:
1137 rtl8723_phy_set_bb_reg(hw, RTXAGC_A_MCS11_MCS08,
1138 MASKBYTE1, power_index);
1139 break;
1140 case DESC92C_RATEMCS10:
1141 rtl8723_phy_set_bb_reg(hw, RTXAGC_A_MCS11_MCS08,
1142 MASKBYTE2, power_index);
1143 break;
1144 case DESC92C_RATEMCS11:
1145 rtl8723_phy_set_bb_reg(hw, RTXAGC_A_MCS11_MCS08,
1146 MASKBYTE3, power_index);
1147 break;
1148 default:
1149 RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
1150 "Invalid Rate!!\n");
1151 break;
1152 }
1153 } else {
1154 RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, "Invalid RFPath!!\n");
1155 }
1156}
1157
1158void rtl8723be_phy_set_txpower_level(struct ieee80211_hw *hw, u8 channel)
1159{
1160 struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
1161 u8 cck_rates[] = {DESC92C_RATE1M, DESC92C_RATE2M,
1162 DESC92C_RATE5_5M, DESC92C_RATE11M};
1163 u8 ofdm_rates[] = {DESC92C_RATE6M, DESC92C_RATE9M,
1164 DESC92C_RATE12M, DESC92C_RATE18M,
1165 DESC92C_RATE24M, DESC92C_RATE36M,
1166 DESC92C_RATE48M, DESC92C_RATE54M};
1167 u8 ht_rates_1t[] = {DESC92C_RATEMCS0, DESC92C_RATEMCS1,
1168 DESC92C_RATEMCS2, DESC92C_RATEMCS3,
1169 DESC92C_RATEMCS4, DESC92C_RATEMCS5,
1170 DESC92C_RATEMCS6, DESC92C_RATEMCS7};
1171 u8 i, size;
1172 u8 power_index;
1173
1174 if (!rtlefuse->txpwr_fromeprom)
1175 return;
1176
1177 size = sizeof(cck_rates) / sizeof(u8);
1178 for (i = 0; i < size; i++) {
1179 power_index = _rtl8723be_get_txpower_index(hw, RF90_PATH_A,
1180 cck_rates[i],
1181 rtl_priv(hw)->phy.current_chan_bw,
1182 channel);
1183 _rtl8723be_phy_set_txpower_index(hw, power_index, RF90_PATH_A,
1184 cck_rates[i]);
1185 }
1186 size = sizeof(ofdm_rates) / sizeof(u8);
1187 for (i = 0; i < size; i++) {
1188 power_index = _rtl8723be_get_txpower_index(hw, RF90_PATH_A,
1189 ofdm_rates[i],
1190 rtl_priv(hw)->phy.current_chan_bw,
1191 channel);
1192 _rtl8723be_phy_set_txpower_index(hw, power_index, RF90_PATH_A,
1193 ofdm_rates[i]);
1194 }
1195 size = sizeof(ht_rates_1t) / sizeof(u8);
1196 for (i = 0; i < size; i++) {
1197 power_index = _rtl8723be_get_txpower_index(hw, RF90_PATH_A,
1198 ht_rates_1t[i],
1199 rtl_priv(hw)->phy.current_chan_bw,
1200 channel);
1201 _rtl8723be_phy_set_txpower_index(hw, power_index, RF90_PATH_A,
1202 ht_rates_1t[i]);
1203 }
1204}
1205
1206void rtl8723be_phy_scan_operation_backup(struct ieee80211_hw *hw, u8 operation)
1207{
1208 struct rtl_priv *rtlpriv = rtl_priv(hw);
1209 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
1210 enum io_type iotype;
1211
1212 if (!is_hal_stop(rtlhal)) {
1213 switch (operation) {
1214 case SCAN_OPT_BACKUP:
1215 iotype = IO_CMD_PAUSE_DM_BY_SCAN;
1216 rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_IO_CMD,
1217 (u8 *)&iotype);
1218 break;
1219 case SCAN_OPT_RESTORE:
1220 iotype = IO_CMD_RESUME_DM_BY_SCAN;
1221 rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_IO_CMD,
1222 (u8 *)&iotype);
1223 break;
1224 default:
1225 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
1226 "Unknown Scan Backup operation.\n");
1227 break;
1228 }
1229 }
1230}
1231
1232void rtl8723be_phy_set_bw_mode_callback(struct ieee80211_hw *hw)
1233{
1234 struct rtl_priv *rtlpriv = rtl_priv(hw);
1235 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
1236 struct rtl_phy *rtlphy = &(rtlpriv->phy);
1237 struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
1238 u8 reg_bw_opmode;
1239 u8 reg_prsr_rsc;
1240
1241 RT_TRACE(rtlpriv, COMP_SCAN, DBG_TRACE,
1242 "Switch to %s bandwidth\n",
1243 rtlphy->current_chan_bw == HT_CHANNEL_WIDTH_20 ?
1244 "20MHz" : "40MHz");
1245
1246 if (is_hal_stop(rtlhal)) {
1247 rtlphy->set_bwmode_inprogress = false;
1248 return;
1249 }
1250
1251 reg_bw_opmode = rtl_read_byte(rtlpriv, REG_BWOPMODE);
1252 reg_prsr_rsc = rtl_read_byte(rtlpriv, REG_RRSR + 2);
1253
1254 switch (rtlphy->current_chan_bw) {
1255 case HT_CHANNEL_WIDTH_20:
1256 reg_bw_opmode |= BW_OPMODE_20MHZ;
1257 rtl_write_byte(rtlpriv, REG_BWOPMODE, reg_bw_opmode);
1258 break;
1259 case HT_CHANNEL_WIDTH_20_40:
1260 reg_bw_opmode &= ~BW_OPMODE_20MHZ;
1261 rtl_write_byte(rtlpriv, REG_BWOPMODE, reg_bw_opmode);
1262 reg_prsr_rsc = (reg_prsr_rsc & 0x90) |
1263 (mac->cur_40_prime_sc << 5);
1264 rtl_write_byte(rtlpriv, REG_RRSR + 2, reg_prsr_rsc);
1265 break;
1266 default:
1267 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
1268 "unknown bandwidth: %#X\n", rtlphy->current_chan_bw);
1269 break;
1270 }
1271
1272 switch (rtlphy->current_chan_bw) {
1273 case HT_CHANNEL_WIDTH_20:
1274 rtl_set_bbreg(hw, RFPGA0_RFMOD, BRFMOD, 0x0);
1275 rtl_set_bbreg(hw, RFPGA1_RFMOD, BRFMOD, 0x0);
1276 break;
1277 case HT_CHANNEL_WIDTH_20_40:
1278 rtl_set_bbreg(hw, RFPGA0_RFMOD, BRFMOD, 0x1);
1279 rtl_set_bbreg(hw, RFPGA1_RFMOD, BRFMOD, 0x1);
1280 rtl_set_bbreg(hw, RCCK0_SYSTEM, BCCK_SIDEBAND,
1281 (mac->cur_40_prime_sc >> 1));
1282 rtl_set_bbreg(hw, ROFDM1_LSTF, 0xC00, mac->cur_40_prime_sc);
1283 rtl_set_bbreg(hw, 0x818, (BIT(26) | BIT(27)),
1284 (mac->cur_40_prime_sc ==
1285 HAL_PRIME_CHNL_OFFSET_LOWER) ? 2 : 1);
1286 break;
1287 default:
1288 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
1289 "unknown bandwidth: %#X\n", rtlphy->current_chan_bw);
1290 break;
1291 }
1292 rtl8723be_phy_rf6052_set_bandwidth(hw, rtlphy->current_chan_bw);
1293 rtlphy->set_bwmode_inprogress = false;
1294 RT_TRACE(rtlpriv, COMP_SCAN, DBG_LOUD, "\n");
1295}
1296
1297void rtl8723be_phy_set_bw_mode(struct ieee80211_hw *hw,
1298 enum nl80211_channel_type ch_type)
1299{
1300 struct rtl_priv *rtlpriv = rtl_priv(hw);
1301 struct rtl_phy *rtlphy = &(rtlpriv->phy);
1302 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
1303 u8 tmp_bw = rtlphy->current_chan_bw;
1304
1305 if (rtlphy->set_bwmode_inprogress)
1306 return;
1307 rtlphy->set_bwmode_inprogress = true;
1308 if ((!is_hal_stop(rtlhal)) && !(RT_CANNOT_IO(hw))) {
1309 rtl8723be_phy_set_bw_mode_callback(hw);
1310 } else {
1311 RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
1312 "false driver sleep or unload\n");
1313 rtlphy->set_bwmode_inprogress = false;
1314 rtlphy->current_chan_bw = tmp_bw;
1315 }
1316}
1317
1318void rtl8723be_phy_sw_chnl_callback(struct ieee80211_hw *hw)
1319{
1320 struct rtl_priv *rtlpriv = rtl_priv(hw);
1321 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
1322 struct rtl_phy *rtlphy = &(rtlpriv->phy);
1323 u32 delay;
1324
1325 RT_TRACE(rtlpriv, COMP_SCAN, DBG_TRACE,
1326 "switch to channel%d\n", rtlphy->current_channel);
1327 if (is_hal_stop(rtlhal))
1328 return;
1329 do {
1330 if (!rtlphy->sw_chnl_inprogress)
1331 break;
1332 if (!rtl8723be_phy_sw_chn_step_by_step(hw,
1333 rtlphy->current_channel,
1334 &rtlphy->sw_chnl_stage,
1335 &rtlphy->sw_chnl_step,
1336 &delay)) {
1337 if (delay > 0)
1338 mdelay(delay);
1339 else
1340 continue;
1341 } else {
1342 rtlphy->sw_chnl_inprogress = false;
1343 }
1344 break;
1345 } while (true);
1346 RT_TRACE(rtlpriv, COMP_SCAN, DBG_TRACE, "\n");
1347}
1348
1349u8 rtl8723be_phy_sw_chnl(struct ieee80211_hw *hw)
1350{
1351 struct rtl_priv *rtlpriv = rtl_priv(hw);
1352 struct rtl_phy *rtlphy = &(rtlpriv->phy);
1353 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
1354
1355 if (rtlphy->sw_chnl_inprogress)
1356 return 0;
1357 if (rtlphy->set_bwmode_inprogress)
1358 return 0;
1359 RT_ASSERT((rtlphy->current_channel <= 14),
1360 "WIRELESS_MODE_G but channel>14");
1361 rtlphy->sw_chnl_inprogress = true;
1362 rtlphy->sw_chnl_stage = 0;
1363 rtlphy->sw_chnl_step = 0;
1364 if (!(is_hal_stop(rtlhal)) && !(RT_CANNOT_IO(hw))) {
1365 rtl8723be_phy_sw_chnl_callback(hw);
1366 RT_TRACE(rtlpriv, COMP_CHAN, DBG_LOUD,
1367 "sw_chnl_inprogress false schdule "
1368 "workitem current channel %d\n",
1369 rtlphy->current_channel);
1370 rtlphy->sw_chnl_inprogress = false;
1371 } else {
1372 RT_TRACE(rtlpriv, COMP_CHAN, DBG_LOUD,
1373 "sw_chnl_inprogress false driver sleep or"
1374 " unload\n");
1375 rtlphy->sw_chnl_inprogress = false;
1376 }
1377 return 1;
1378}
1379
1380static bool rtl8723be_phy_sw_chn_step_by_step(struct ieee80211_hw *hw,
1381 u8 channel, u8 *stage,
1382 u8 *step, u32 *delay)
1383{
1384 struct rtl_priv *rtlpriv = rtl_priv(hw);
1385 struct rtl_phy *rtlphy = &(rtlpriv->phy);
1386 struct swchnlcmd precommoncmd[MAX_PRECMD_CNT];
1387 u32 precommoncmdcnt;
1388 struct swchnlcmd postcommoncmd[MAX_POSTCMD_CNT];
1389 u32 postcommoncmdcnt;
1390 struct swchnlcmd rfdependcmd[MAX_RFDEPENDCMD_CNT];
1391 u32 rfdependcmdcnt;
1392 struct swchnlcmd *currentcmd = NULL;
1393 u8 rfpath;
1394 u8 num_total_rfpath = rtlphy->num_total_rfpath;
1395
1396 precommoncmdcnt = 0;
1397 rtl8723_phy_set_sw_chnl_cmdarray(precommoncmd, precommoncmdcnt++,
1398 MAX_PRECMD_CNT,
1399 CMDID_SET_TXPOWEROWER_LEVEL,
1400 0, 0, 0);
1401 rtl8723_phy_set_sw_chnl_cmdarray(precommoncmd, precommoncmdcnt++,
1402 MAX_PRECMD_CNT, CMDID_END, 0, 0, 0);
1403 postcommoncmdcnt = 0;
1404 rtl8723_phy_set_sw_chnl_cmdarray(postcommoncmd, postcommoncmdcnt++,
1405 MAX_POSTCMD_CNT, CMDID_END,
1406 0, 0, 0);
1407 rfdependcmdcnt = 0;
1408
1409 RT_ASSERT((channel >= 1 && channel <= 14),
1410 "illegal channel for Zebra: %d\n", channel);
1411
1412 rtl8723_phy_set_sw_chnl_cmdarray(rfdependcmd, rfdependcmdcnt++,
1413 MAX_RFDEPENDCMD_CNT,
1414 CMDID_RF_WRITEREG,
1415 RF_CHNLBW, channel, 10);
1416
1417 rtl8723_phy_set_sw_chnl_cmdarray(rfdependcmd, rfdependcmdcnt++,
1418 MAX_RFDEPENDCMD_CNT,
1419 CMDID_END, 0, 0, 0);
1420
1421 do {
1422 switch (*stage) {
1423 case 0:
1424 currentcmd = &precommoncmd[*step];
1425 break;
1426 case 1:
1427 currentcmd = &rfdependcmd[*step];
1428 break;
1429 case 2:
1430 currentcmd = &postcommoncmd[*step];
1431 break;
1432 }
1433
1434 if (currentcmd->cmdid == CMDID_END) {
1435 if ((*stage) == 2) {
1436 return true;
1437 } else {
1438 (*stage)++;
1439 (*step) = 0;
1440 continue;
1441 }
1442 }
1443
1444 switch (currentcmd->cmdid) {
1445 case CMDID_SET_TXPOWEROWER_LEVEL:
1446 rtl8723be_phy_set_txpower_level(hw, channel);
1447 break;
1448 case CMDID_WRITEPORT_ULONG:
1449 rtl_write_dword(rtlpriv, currentcmd->para1,
1450 currentcmd->para2);
1451 break;
1452 case CMDID_WRITEPORT_USHORT:
1453 rtl_write_word(rtlpriv, currentcmd->para1,
1454 (u16) currentcmd->para2);
1455 break;
1456 case CMDID_WRITEPORT_UCHAR:
1457 rtl_write_byte(rtlpriv, currentcmd->para1,
1458 (u8) currentcmd->para2);
1459 break;
1460 case CMDID_RF_WRITEREG:
1461 for (rfpath = 0; rfpath < num_total_rfpath; rfpath++) {
1462 rtlphy->rfreg_chnlval[rfpath] =
1463 ((rtlphy->rfreg_chnlval[rfpath] &
1464 0xfffffc00) | currentcmd->para2);
1465
1466 rtl_set_rfreg(hw, (enum radio_path)rfpath,
1467 currentcmd->para1,
1468 RFREG_OFFSET_MASK,
1469 rtlphy->rfreg_chnlval[rfpath]);
1470 }
1471 break;
1472 default:
1473 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
1474 "switch case not process\n");
1475 break;
1476 }
1477
1478 break;
1479 } while (true);
1480
1481 (*delay) = currentcmd->msdelay;
1482 (*step)++;
1483 return false;
1484}
1485
1486static u8 _rtl8723be_phy_path_a_iqk(struct ieee80211_hw *hw, bool config_pathb)
1487{
1488 u32 reg_eac, reg_e94, reg_e9c, reg_ea4;
1489 u8 result = 0x00;
1490
1491 rtl_set_bbreg(hw, 0xe30, MASKDWORD, 0x10008c1c);
1492 rtl_set_bbreg(hw, 0xe34, MASKDWORD, 0x30008c1c);
1493 rtl_set_bbreg(hw, 0xe38, MASKDWORD, 0x8214032a);
1494 rtl_set_bbreg(hw, 0xe3c, MASKDWORD, 0x28160000);
1495
1496 rtl_set_bbreg(hw, 0xe4c, MASKDWORD, 0x00462911);
1497 rtl_set_bbreg(hw, 0xe48, MASKDWORD, 0xf9000000);
1498 rtl_set_bbreg(hw, 0xe48, MASKDWORD, 0xf8000000);
1499
1500 mdelay(IQK_DELAY_TIME);
1501
1502 reg_eac = rtl_get_bbreg(hw, 0xeac, MASKDWORD);
1503 reg_e94 = rtl_get_bbreg(hw, 0xe94, MASKDWORD);
1504 reg_e9c = rtl_get_bbreg(hw, 0xe9c, MASKDWORD);
1505 reg_ea4 = rtl_get_bbreg(hw, 0xea4, MASKDWORD);
1506
1507 if (!(reg_eac & BIT(28)) &&
1508 (((reg_e94 & 0x03FF0000) >> 16) != 0x142) &&
1509 (((reg_e9c & 0x03FF0000) >> 16) != 0x42))
1510 result |= 0x01;
1511 return result;
1512}
1513
1514static bool phy_similarity_cmp(struct ieee80211_hw *hw, long result[][8],
1515 u8 c1, u8 c2)
1516{
1517 u32 i, j, diff, simularity_bitmap, bound;
1518 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
1519
1520 u8 final_candidate[2] = { 0xFF, 0xFF };
1521 bool bresult = true, is2t = IS_92C_SERIAL(rtlhal->version);
1522
1523 if (is2t)
1524 bound = 8;
1525 else
1526 bound = 4;
1527
1528 simularity_bitmap = 0;
1529
1530 for (i = 0; i < bound; i++) {
1531 diff = (result[c1][i] > result[c2][i]) ?
1532 (result[c1][i] - result[c2][i]) :
1533 (result[c2][i] - result[c1][i]);
1534
1535 if (diff > MAX_TOLERANCE) {
1536 if ((i == 2 || i == 6) && !simularity_bitmap) {
1537 if (result[c1][i] + result[c1][i + 1] == 0)
1538 final_candidate[(i / 4)] = c2;
1539 else if (result[c2][i] + result[c2][i + 1] == 0)
1540 final_candidate[(i / 4)] = c1;
1541 else
1542 simularity_bitmap |= (1 << i);
1543 } else {
1544 simularity_bitmap |= (1 << i);
1545 }
1546 }
1547 }
1548
1549 if (simularity_bitmap == 0) {
1550 for (i = 0; i < (bound / 4); i++) {
1551 if (final_candidate[i] != 0xFF) {
1552 for (j = i * 4; j < (i + 1) * 4 - 2; j++)
1553 result[3][j] =
1554 result[final_candidate[i]][j];
1555 bresult = false;
1556 }
1557 }
1558 return bresult;
1559 } else if (!(simularity_bitmap & 0x0F)) {
1560 for (i = 0; i < 4; i++)
1561 result[3][i] = result[c1][i];
1562 return false;
1563 } else if (!(simularity_bitmap & 0xF0) && is2t) {
1564 for (i = 4; i < 8; i++)
1565 result[3][i] = result[c1][i];
1566 return false;
1567 } else {
1568 return false;
1569 }
1570}
1571
1572static void _rtl8723be_phy_iq_calibrate(struct ieee80211_hw *hw,
1573 long result[][8], u8 t, bool is2t)
1574{
1575 struct rtl_priv *rtlpriv = rtl_priv(hw);
1576 struct rtl_phy *rtlphy = &(rtlpriv->phy);
1577 u32 i;
1578 u8 patha_ok;
1579 u32 adda_reg[IQK_ADDA_REG_NUM] = {
1580 0x85c, 0xe6c, 0xe70, 0xe74,
1581 0xe78, 0xe7c, 0xe80, 0xe84,
1582 0xe88, 0xe8c, 0xed0, 0xed4,
1583 0xed8, 0xedc, 0xee0, 0xeec
1584 };
1585
1586 u32 iqk_mac_reg[IQK_MAC_REG_NUM] = {
1587 0x522, 0x550, 0x551, 0x040
1588 };
1589 u32 iqk_bb_reg[IQK_BB_REG_NUM] = {
1590 ROFDM0_TRXPATHENABLE, ROFDM0_TRMUXPAR,
1591 RFPGA0_XCD_RFINTERFACESW, 0xb68, 0xb6c,
1592 0x870, 0x860,
1593 0x864, 0x800
1594 };
1595 const u32 retrycount = 2;
1596 u32 path_sel_bb, path_sel_rf;
1597 u8 tmp_reg_c50, tmp_reg_c58;
1598
1599 tmp_reg_c50 = rtl_get_bbreg(hw, 0xc50, MASKBYTE0);
1600 tmp_reg_c58 = rtl_get_bbreg(hw, 0xc58, MASKBYTE0);
1601
1602 if (t == 0) {
1603 rtl8723_save_adda_registers(hw, adda_reg,
1604 rtlphy->adda_backup, 16);
1605 rtl8723_phy_save_mac_registers(hw, iqk_mac_reg,
1606 rtlphy->iqk_mac_backup);
1607 rtl8723_save_adda_registers(hw, iqk_bb_reg,
1608 rtlphy->iqk_bb_backup,
1609 IQK_BB_REG_NUM);
1610 }
1611 rtl8723_phy_path_adda_on(hw, adda_reg, true, is2t);
1612 if (t == 0) {
1613 rtlphy->rfpi_enable = (u8) rtl_get_bbreg(hw,
1614 RFPGA0_XA_HSSIPARAMETER1,
1615 BIT(8));
1616 }
1617 if (!rtlphy->rfpi_enable)
1618 rtl8723_phy_pi_mode_switch(hw, true);
1619
1620 path_sel_bb = rtl_get_bbreg(hw, 0x948, MASKDWORD);
1621 path_sel_rf = rtl_get_rfreg(hw, RF90_PATH_A, 0xb0, 0xfffff);
1622
1623 /*BB Setting*/
1624 rtl_set_bbreg(hw, 0x800, BIT(24), 0x00);
1625 rtl_set_bbreg(hw, 0xc04, MASKDWORD, 0x03a05600);
1626 rtl_set_bbreg(hw, 0xc08, MASKDWORD, 0x000800e4);
1627 rtl_set_bbreg(hw, 0x874, MASKDWORD, 0x22204000);
1628
1629 rtl_set_bbreg(hw, 0x870, BIT(10), 0x01);
1630 rtl_set_bbreg(hw, 0x870, BIT(26), 0x01);
1631 rtl_set_bbreg(hw, 0x860, BIT(10), 0x00);
1632 rtl_set_bbreg(hw, 0x864, BIT(10), 0x00);
1633
1634 if (is2t)
1635 rtl_set_rfreg(hw, RF90_PATH_B, 0x00, MASKDWORD, 0x10000);
1636 rtl8723_phy_mac_setting_calibration(hw, iqk_mac_reg,
1637 rtlphy->iqk_mac_backup);
1638 rtl_set_bbreg(hw, 0xb68, MASKDWORD, 0x0f600000);
1639
1640 rtl_set_bbreg(hw, 0xe28, MASKDWORD, 0x80800000);
1641 rtl_set_bbreg(hw, 0xe40, MASKDWORD, 0x01007c00);
1642 rtl_set_bbreg(hw, 0xe44, MASKDWORD, 0x81004800);
1643 for (i = 0; i < retrycount; i++) {
1644 patha_ok = _rtl8723be_phy_path_a_iqk(hw, is2t);
1645 if (patha_ok == 0x01) {
1646 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
1647 "Path A Tx IQK Success!!\n");
1648 result[t][0] = (rtl_get_bbreg(hw, 0xe94, MASKDWORD) &
1649 0x3FF0000) >> 16;
1650 result[t][1] = (rtl_get_bbreg(hw, 0xe9c, MASKDWORD) &
1651 0x3FF0000) >> 16;
1652 break;
1653 }
1654 }
1655
1656 if (0 == patha_ok)
1657 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
1658 "Path A IQK Success!!\n");
1659 if (is2t) {
1660 rtl8723_phy_path_a_standby(hw);
1661 rtl8723_phy_path_adda_on(hw, adda_reg, false, is2t);
1662 }
1663
1664 rtl_set_bbreg(hw, 0xe28, MASKDWORD, 0);
1665
1666 if (t != 0) {
1667 if (!rtlphy->rfpi_enable)
1668 rtl8723_phy_pi_mode_switch(hw, false);
1669 rtl8723_phy_reload_adda_registers(hw, adda_reg,
1670 rtlphy->adda_backup, 16);
1671 rtl8723_phy_reload_mac_registers(hw, iqk_mac_reg,
1672 rtlphy->iqk_mac_backup);
1673 rtl8723_phy_reload_adda_registers(hw, iqk_bb_reg,
1674 rtlphy->iqk_bb_backup,
1675 IQK_BB_REG_NUM);
1676
1677 rtl_set_bbreg(hw, 0x948, MASKDWORD, path_sel_bb);
1678 rtl_set_rfreg(hw, RF90_PATH_B, 0xb0, 0xfffff, path_sel_rf);
1679
1680 rtl_set_bbreg(hw, 0xc50, MASKBYTE0, 0x50);
1681 rtl_set_bbreg(hw, 0xc50, MASKBYTE0, tmp_reg_c50);
1682 if (is2t) {
1683 rtl_set_bbreg(hw, 0xc58, MASKBYTE0, 0x50);
1684 rtl_set_bbreg(hw, 0xc58, MASKBYTE0, tmp_reg_c58);
1685 }
1686 rtl_set_bbreg(hw, 0xe30, MASKDWORD, 0x01008c00);
1687 rtl_set_bbreg(hw, 0xe34, MASKDWORD, 0x01008c00);
1688 }
1689 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "8723be IQK Finish!!\n");
1690}
1691
1692static void _rtl8723be_phy_lc_calibrate(struct ieee80211_hw *hw, bool is2t)
1693{
1694 struct rtl_priv *rtlpriv = rtl_priv(hw);
1695 u8 tmpreg;
1696 u32 rf_a_mode = 0, rf_b_mode = 0, lc_cal;
1697
1698 tmpreg = rtl_read_byte(rtlpriv, 0xd03);
1699
1700 if ((tmpreg & 0x70) != 0)
1701 rtl_write_byte(rtlpriv, 0xd03, tmpreg & 0x8F);
1702 else
1703 rtl_write_byte(rtlpriv, REG_TXPAUSE, 0xFF);
1704
1705 if ((tmpreg & 0x70) != 0) {
1706 rf_a_mode = rtl_get_rfreg(hw, RF90_PATH_A, 0x00, MASK12BITS);
1707
1708 if (is2t)
1709 rf_b_mode = rtl_get_rfreg(hw, RF90_PATH_B, 0x00,
1710 MASK12BITS);
1711
1712 rtl_set_rfreg(hw, RF90_PATH_A, 0x00, MASK12BITS,
1713 (rf_a_mode & 0x8FFFF) | 0x10000);
1714
1715 if (is2t)
1716 rtl_set_rfreg(hw, RF90_PATH_B, 0x00, MASK12BITS,
1717 (rf_b_mode & 0x8FFFF) | 0x10000);
1718 }
1719 lc_cal = rtl_get_rfreg(hw, RF90_PATH_A, 0x18, MASK12BITS);
1720
1721 rtl_set_rfreg(hw, RF90_PATH_A, 0xb0, RFREG_OFFSET_MASK, 0xdfbe0);
1722 rtl_set_rfreg(hw, RF90_PATH_A, 0x18, MASK12BITS, 0x8c0a);
1723
1724 mdelay(100);
1725
1726 rtl_set_rfreg(hw, RF90_PATH_A, 0xb0, RFREG_OFFSET_MASK, 0xdffe0);
1727
1728 if ((tmpreg & 0x70) != 0) {
1729 rtl_write_byte(rtlpriv, 0xd03, tmpreg);
1730 rtl_set_rfreg(hw, RF90_PATH_A, 0x00, MASK12BITS, rf_a_mode);
1731
1732 if (is2t)
1733 rtl_set_rfreg(hw, RF90_PATH_B, 0x00,
1734 MASK12BITS, rf_b_mode);
1735 } else {
1736 rtl_write_byte(rtlpriv, REG_TXPAUSE, 0x00);
1737 }
1738 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "\n");
1739}
1740
1741static void _rtl8723be_phy_set_rfpath_switch(struct ieee80211_hw *hw,
1742 bool bmain, bool is2t)
1743{
1744 struct rtl_priv *rtlpriv = rtl_priv(hw);
1745 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
1746 struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
1747 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "\n");
1748
1749 if (is_hal_stop(rtlhal)) {
1750 u8 u1btmp;
1751 u1btmp = rtl_read_byte(rtlpriv, REG_LEDCFG0);
1752 rtl_write_byte(rtlpriv, REG_LEDCFG0, u1btmp | BIT(7));
1753 rtl_set_bbreg(hw, RFPGA0_XAB_RFPARAMETER, BIT(13), 0x01);
1754 }
1755 if (is2t) {
1756 if (bmain)
1757 rtl_set_bbreg(hw, RFPGA0_XB_RFINTERFACEOE,
1758 BIT(5) | BIT(6), 0x1);
1759 else
1760 rtl_set_bbreg(hw, RFPGA0_XB_RFINTERFACEOE,
1761 BIT(5) | BIT(6), 0x2);
1762 } else {
1763 rtl_set_bbreg(hw, RFPGA0_XAB_RFINTERFACESW, BIT(8) | BIT(9), 0);
1764 rtl_set_bbreg(hw, 0x914, MASKLWORD, 0x0201);
1765
1766 /* We use the RF definition of MAIN and AUX,
1767 * left antenna and right antenna repectively.
1768 * Default output at AUX.
1769 */
1770 if (bmain) {
1771 rtl_set_bbreg(hw, RFPGA0_XA_RFINTERFACEOE,
1772 BIT(14) | BIT(13) | BIT(12), 0);
1773 rtl_set_bbreg(hw, RFPGA0_XB_RFINTERFACEOE,
1774 BIT(5) | BIT(4) | BIT(3), 0);
1775 if (rtlefuse->antenna_div_type == CGCS_RX_HW_ANTDIV)
1776 rtl_set_bbreg(hw, CONFIG_RAM64X16, BIT(31), 0);
1777 } else {
1778 rtl_set_bbreg(hw, RFPGA0_XA_RFINTERFACEOE,
1779 BIT(14) | BIT(13) | BIT(12), 1);
1780 rtl_set_bbreg(hw, RFPGA0_XB_RFINTERFACEOE,
1781 BIT(5) | BIT(4) | BIT(3), 1);
1782 if (rtlefuse->antenna_div_type == CGCS_RX_HW_ANTDIV)
1783 rtl_set_bbreg(hw, CONFIG_RAM64X16, BIT(31), 1);
1784 }
1785 }
1786}
1787
1788#undef IQK_ADDA_REG_NUM
1789#undef IQK_DELAY_TIME
1790
1791void rtl8723be_phy_iq_calibrate(struct ieee80211_hw *hw, bool recovery)
1792{
1793 struct rtl_priv *rtlpriv = rtl_priv(hw);
1794 struct rtl_phy *rtlphy = &(rtlpriv->phy);
1795 long result[4][8];
1796 u8 i, final_candidate;
1797 bool patha_ok, pathb_ok;
1798 long reg_e94, reg_e9c, reg_ea4, reg_eac, reg_eb4, reg_ebc, reg_ec4,
1799 reg_ecc, reg_tmp = 0;
1800 bool is12simular, is13simular, is23simular;
1801 u32 iqk_bb_reg[9] = {
1802 ROFDM0_XARXIQIMBALANCE,
1803 ROFDM0_XBRXIQIMBALANCE,
1804 ROFDM0_ECCATHRESHOLD,
1805 ROFDM0_AGCRSSITABLE,
1806 ROFDM0_XATXIQIMBALANCE,
1807 ROFDM0_XBTXIQIMBALANCE,
1808 ROFDM0_XCTXAFE,
1809 ROFDM0_XDTXAFE,
1810 ROFDM0_RXIQEXTANTA
1811 };
1812
1813 if (recovery) {
1814 rtl8723_phy_reload_adda_registers(hw, iqk_bb_reg,
1815 rtlphy->iqk_bb_backup, 9);
1816 return;
1817 }
1818
1819 for (i = 0; i < 8; i++) {
1820 result[0][i] = 0;
1821 result[1][i] = 0;
1822 result[2][i] = 0;
1823 result[3][i] = 0;
1824 }
1825 final_candidate = 0xff;
1826 patha_ok = false;
1827 pathb_ok = false;
1828 is12simular = false;
1829 is23simular = false;
1830 is13simular = false;
1831 for (i = 0; i < 3; i++) {
1832 if (get_rf_type(rtlphy) == RF_2T2R)
1833 _rtl8723be_phy_iq_calibrate(hw, result, i, true);
1834 else
1835 _rtl8723be_phy_iq_calibrate(hw, result, i, false);
1836 if (i == 1) {
1837 is12simular = phy_similarity_cmp(hw, result, 0, 1);
1838 if (is12simular) {
1839 final_candidate = 0;
1840 break;
1841 }
1842 }
1843 if (i == 2) {
1844 is13simular = phy_similarity_cmp(hw, result, 0, 2);
1845 if (is13simular) {
1846 final_candidate = 0;
1847 break;
1848 }
1849 is23simular = phy_similarity_cmp(hw, result, 1, 2);
1850 if (is23simular) {
1851 final_candidate = 1;
1852 } else {
1853 for (i = 0; i < 8; i++)
1854 reg_tmp += result[3][i];
1855
1856 if (reg_tmp != 0)
1857 final_candidate = 3;
1858 else
1859 final_candidate = 0xFF;
1860 }
1861 }
1862 }
1863 for (i = 0; i < 4; i++) {
1864 reg_e94 = result[i][0];
1865 reg_e9c = result[i][1];
1866 reg_ea4 = result[i][2];
1867 reg_eac = result[i][3];
1868 reg_eb4 = result[i][4];
1869 reg_ebc = result[i][5];
1870 reg_ec4 = result[i][6];
1871 reg_ecc = result[i][7];
1872 }
1873 if (final_candidate != 0xff) {
1874 reg_e94 = result[final_candidate][0];
1875 rtlphy->reg_e94 = reg_e94;
1876 reg_e9c = result[final_candidate][1];
1877 rtlphy->reg_e9c = reg_e9c;
1878 reg_ea4 = result[final_candidate][2];
1879 reg_eac = result[final_candidate][3];
1880 reg_eb4 = result[final_candidate][4];
1881 rtlphy->reg_eb4 = reg_eb4;
1882 reg_ebc = result[final_candidate][5];
1883 rtlphy->reg_ebc = reg_ebc;
1884 reg_ec4 = result[final_candidate][6];
1885 reg_ecc = result[final_candidate][7];
1886 patha_ok = true;
1887 pathb_ok = true;
1888 } else {
1889 rtlphy->reg_e94 = 0x100;
1890 rtlphy->reg_eb4 = 0x100;
1891 rtlphy->reg_e9c = 0x0;
1892 rtlphy->reg_ebc = 0x0;
1893 }
1894 if (reg_e94 != 0) /*&&(reg_ea4 != 0) */
1895 rtl8723_phy_path_a_fill_iqk_matrix(hw, patha_ok, result,
1896 final_candidate,
1897 (reg_ea4 == 0));
1898 if (final_candidate != 0xFF) {
1899 for (i = 0; i < IQK_MATRIX_REG_NUM; i++)
1900 rtlphy->iqk_matrix[0].value[0][i] =
1901 result[final_candidate][i];
1902 rtlphy->iqk_matrix[0].iqk_done = true;
1903 }
1904 rtl8723_save_adda_registers(hw, iqk_bb_reg, rtlphy->iqk_bb_backup, 9);
1905}
1906
1907void rtl8723be_phy_lc_calibrate(struct ieee80211_hw *hw)
1908{
1909 struct rtl_priv *rtlpriv = rtl_priv(hw);
1910 struct rtl_phy *rtlphy = &(rtlpriv->phy);
1911 struct rtl_hal *rtlhal = &(rtlpriv->rtlhal);
1912 u32 timeout = 2000, timecount = 0;
1913
1914 while (rtlpriv->mac80211.act_scanning && timecount < timeout) {
1915 udelay(50);
1916 timecount += 50;
1917 }
1918
1919 rtlphy->lck_inprogress = true;
1920 RTPRINT(rtlpriv, FINIT, INIT_EEPROM,
1921 "LCK:Start!!! currentband %x delay %d ms\n",
1922 rtlhal->current_bandtype, timecount);
1923
1924 _rtl8723be_phy_lc_calibrate(hw, false);
1925
1926 rtlphy->lck_inprogress = false;
1927}
1928
1929void rtl23b_phy_ap_calibrate(struct ieee80211_hw *hw, char delta)
1930{
1931 struct rtl_priv *rtlpriv = rtl_priv(hw);
1932 struct rtl_phy *rtlphy = &(rtlpriv->phy);
1933
1934 if (rtlphy->apk_done)
1935 return;
1936
1937 return;
1938}
1939
1940void rtl8723be_phy_set_rfpath_switch(struct ieee80211_hw *hw, bool bmain)
1941{
1942 _rtl8723be_phy_set_rfpath_switch(hw, bmain, false);
1943}
1944
1945static void rtl8723be_phy_set_io(struct ieee80211_hw *hw)
1946{
1947 struct rtl_priv *rtlpriv = rtl_priv(hw);
1948 struct rtl_phy *rtlphy = &(rtlpriv->phy);
1949
1950 RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE,
1951 "--->Cmd(%#x), set_io_inprogress(%d)\n",
1952 rtlphy->current_io_type, rtlphy->set_io_inprogress);
1953 switch (rtlphy->current_io_type) {
1954 case IO_CMD_RESUME_DM_BY_SCAN:
1955 rtlpriv->dm_digtable.cur_igvalue =
1956 rtlphy->initgain_backup.xaagccore1;
1957 /*rtl92c_dm_write_dig(hw);*/
1958 rtl8723be_phy_set_txpower_level(hw, rtlphy->current_channel);
1959 rtl_set_bbreg(hw, RCCK0_CCA, 0xff0000, 0x83);
1960 break;
1961 case IO_CMD_PAUSE_DM_BY_SCAN:
1962 rtlphy->initgain_backup.xaagccore1 =
1963 rtlpriv->dm_digtable.cur_igvalue;
1964 rtlpriv->dm_digtable.cur_igvalue = 0x17;
1965 rtl_set_bbreg(hw, RCCK0_CCA, 0xff0000, 0x40);
1966 break;
1967 default:
1968 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
1969 "switch case not process\n");
1970 break;
1971 }
1972 rtlphy->set_io_inprogress = false;
1973 RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE,
1974 "(%#x)\n", rtlphy->current_io_type);
1975}
1976
1977bool rtl8723be_phy_set_io_cmd(struct ieee80211_hw *hw, enum io_type iotype)
1978{
1979 struct rtl_priv *rtlpriv = rtl_priv(hw);
1980 struct rtl_phy *rtlphy = &(rtlpriv->phy);
1981 bool postprocessing = false;
1982
1983 RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE,
1984 "-->IO Cmd(%#x), set_io_inprogress(%d)\n",
1985 iotype, rtlphy->set_io_inprogress);
1986 do {
1987 switch (iotype) {
1988 case IO_CMD_RESUME_DM_BY_SCAN:
1989 RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE,
1990 "[IO CMD] Resume DM after scan.\n");
1991 postprocessing = true;
1992 break;
1993 case IO_CMD_PAUSE_DM_BY_SCAN:
1994 RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE,
1995 "[IO CMD] Pause DM before scan.\n");
1996 postprocessing = true;
1997 break;
1998 default:
1999 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
2000 "switch case not process\n");
2001 break;
2002 }
2003 } while (false);
2004 if (postprocessing && !rtlphy->set_io_inprogress) {
2005 rtlphy->set_io_inprogress = true;
2006 rtlphy->current_io_type = iotype;
2007 } else {
2008 return false;
2009 }
2010 rtl8723be_phy_set_io(hw);
2011 RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE, "IO Type(%#x)\n", iotype);
2012 return true;
2013}
2014
2015static void rtl8723be_phy_set_rf_on(struct ieee80211_hw *hw)
2016{
2017 struct rtl_priv *rtlpriv = rtl_priv(hw);
2018
2019 rtl_write_byte(rtlpriv, REG_SPS0_CTRL, 0x2b);
2020 rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE3);
2021 rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE2);
2022 rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE3);
2023 rtl_write_byte(rtlpriv, REG_TXPAUSE, 0x00);
2024}
2025
2026static void _rtl8723be_phy_set_rf_sleep(struct ieee80211_hw *hw)
2027{
2028 struct rtl_priv *rtlpriv = rtl_priv(hw);
2029
2030 rtl_write_byte(rtlpriv, REG_TXPAUSE, 0xFF);
2031 rtl_set_rfreg(hw, RF90_PATH_A, 0x00, RFREG_OFFSET_MASK, 0x00);
2032 rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE2);
2033 rtl_write_byte(rtlpriv, REG_SPS0_CTRL, 0x22);
2034}
2035
2036static bool _rtl8723be_phy_set_rf_power_state(struct ieee80211_hw *hw,
2037 enum rf_pwrstate rfpwr_state)
2038{
2039 struct rtl_priv *rtlpriv = rtl_priv(hw);
2040 struct rtl_pci_priv *pcipriv = rtl_pcipriv(hw);
2041 struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
2042 struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
2043 bool bresult = true;
2044 u8 i, queue_id;
2045 struct rtl8192_tx_ring *ring = NULL;
2046
2047 switch (rfpwr_state) {
2048 case ERFON:
2049 if ((ppsc->rfpwr_state == ERFOFF) &&
2050 RT_IN_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_HALT_NIC)) {
2051 bool rtstatus;
2052 u32 initialize_count = 0;
2053 do {
2054 initialize_count++;
2055 RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG,
2056 "IPS Set eRf nic enable\n");
2057 rtstatus = rtl_ps_enable_nic(hw);
2058 } while (!rtstatus && (initialize_count < 10));
2059 RT_CLEAR_PS_LEVEL(ppsc,
2060 RT_RF_OFF_LEVL_HALT_NIC);
2061 } else {
2062 RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG,
2063 "Set ERFON sleeped:%d ms\n",
2064 jiffies_to_msecs(jiffies -
2065 ppsc->last_sleep_jiffies));
2066 ppsc->last_awake_jiffies = jiffies;
2067 rtl8723be_phy_set_rf_on(hw);
2068 }
2069 if (mac->link_state == MAC80211_LINKED)
2070 rtlpriv->cfg->ops->led_control(hw, LED_CTL_LINK);
2071 else
2072 rtlpriv->cfg->ops->led_control(hw, LED_CTL_NO_LINK);
2073 break;
2074 case ERFOFF:
2075 for (queue_id = 0, i = 0;
2076 queue_id < RTL_PCI_MAX_TX_QUEUE_COUNT;) {
2077 ring = &pcipriv->dev.tx_ring[queue_id];
2078 if (skb_queue_len(&ring->queue) == 0) {
2079 queue_id++;
2080 continue;
2081 } else {
2082 RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
2083 "eRf Off/Sleep: %d times "
2084 "TcbBusyQueue[%d] =%d before "
2085 "doze!\n", (i + 1), queue_id,
2086 skb_queue_len(&ring->queue));
2087
2088 udelay(10);
2089 i++;
2090 }
2091 if (i >= MAX_DOZE_WAITING_TIMES_9x) {
2092 RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
2093 "\n ERFSLEEP: %d times "
2094 "TcbBusyQueue[%d] = %d !\n",
2095 MAX_DOZE_WAITING_TIMES_9x,
2096 queue_id,
2097 skb_queue_len(&ring->queue));
2098 break;
2099 }
2100 }
2101
2102 if (ppsc->reg_rfps_level & RT_RF_OFF_LEVL_HALT_NIC) {
2103 RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG,
2104 "IPS Set eRf nic disable\n");
2105 rtl_ps_disable_nic(hw);
2106 RT_SET_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_HALT_NIC);
2107 } else {
2108 if (ppsc->rfoff_reason == RF_CHANGE_BY_IPS) {
2109 rtlpriv->cfg->ops->led_control(hw,
2110 LED_CTL_NO_LINK);
2111 } else {
2112 rtlpriv->cfg->ops->led_control(hw,
2113 LED_CTL_POWER_OFF);
2114 }
2115 }
2116 break;
2117 case ERFSLEEP:
2118 if (ppsc->rfpwr_state == ERFOFF)
2119 break;
2120 for (queue_id = 0, i = 0;
2121 queue_id < RTL_PCI_MAX_TX_QUEUE_COUNT;) {
2122 ring = &pcipriv->dev.tx_ring[queue_id];
2123 if (skb_queue_len(&ring->queue) == 0) {
2124 queue_id++;
2125 continue;
2126 } else {
2127 RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
2128 "eRf Off/Sleep: %d times "
2129 "TcbBusyQueue[%d] =%d before "
2130 "doze!\n", (i + 1), queue_id,
2131 skb_queue_len(&ring->queue));
2132
2133 udelay(10);
2134 i++;
2135 }
2136 if (i >= MAX_DOZE_WAITING_TIMES_9x) {
2137 RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
2138 "\n ERFSLEEP: %d times "
2139 "TcbBusyQueue[%d] = %d !\n",
2140 MAX_DOZE_WAITING_TIMES_9x,
2141 queue_id,
2142 skb_queue_len(&ring->queue));
2143 break;
2144 }
2145 }
2146 RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG,
2147 "Set ERFSLEEP awaked:%d ms\n",
2148 jiffies_to_msecs(jiffies -
2149 ppsc->last_awake_jiffies));
2150 ppsc->last_sleep_jiffies = jiffies;
2151 _rtl8723be_phy_set_rf_sleep(hw);
2152 break;
2153 default:
2154 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
2155 "switch case not process\n");
2156 bresult = false;
2157 break;
2158 }
2159 if (bresult)
2160 ppsc->rfpwr_state = rfpwr_state;
2161 return bresult;
2162}
2163
2164bool rtl8723be_phy_set_rf_power_state(struct ieee80211_hw *hw,
2165 enum rf_pwrstate rfpwr_state)
2166{
2167 struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
2168
2169 bool bresult = false;
2170
2171 if (rfpwr_state == ppsc->rfpwr_state)
2172 return bresult;
2173 bresult = _rtl8723be_phy_set_rf_power_state(hw, rfpwr_state);
2174 return bresult;
2175}