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