Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/ide
[deliverable/linux.git] / drivers / net / wireless / rtlwifi / rtl8723be / phy.c
CommitLineData
a619d1ab
LF
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"
25b13dbc 29#include "../core.h"
a619d1ab
LF
30#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);
a619d1ab
LF
45static 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) {
25b13dbc 115 rtl_bb_delay(hw, v1, v2);
a619d1ab
LF
116 } 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) {
25b13dbc 136 rtl_bb_delay(hw,
a619d1ab
LF
137 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
a619d1ab
LF
390static 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
4e3b3bcd 632 if (band != BAND_ON_2_4G && band != BAND_ON_5G) {
a619d1ab
LF
633 RT_TRACE(rtlpriv, COMP_POWER, PHY_TXPWR,
634 "Invalid Band %d\n", band);
4e3b3bcd
LF
635 return;
636 }
a619d1ab 637
4e3b3bcd 638 if (rfpath > TX_PWR_BY_RATE_NUM_RF) {
a619d1ab
LF
639 RT_TRACE(rtlpriv, COMP_POWER, PHY_TXPWR,
640 "Invalid RfPath %d\n", rfpath);
4e3b3bcd
LF
641 return;
642 }
643 if (txnum > TX_PWR_BY_RATE_NUM_RF) {
a619d1ab
LF
644 RT_TRACE(rtlpriv, COMP_POWER, PHY_TXPWR,
645 "Invalid TxNum %d\n", txnum);
4e3b3bcd
LF
646 return;
647 }
a619d1ab
LF
648 rtlphy->tx_power_by_rate_offset[band][rfpath][txnum][rate_section] =
649 data;
650}
651
652static bool _rtl8723be_phy_config_bb_with_pgheaderfile(struct ieee80211_hw *hw,
653 u8 configtype)
654{
655 struct rtl_priv *rtlpriv = rtl_priv(hw);
656 int i;
657 u32 *phy_regarray_table_pg;
658 u16 phy_regarray_pg_len;
659 u32 v1 = 0, v2 = 0, v3 = 0, v4 = 0, v5 = 0, v6 = 0;
660
661 phy_regarray_pg_len = RTL8723BEPHY_REG_ARRAY_PGLEN;
662 phy_regarray_table_pg = RTL8723BEPHY_REG_ARRAY_PG;
663
664 if (configtype == BASEBAND_CONFIG_PHY_REG) {
665 for (i = 0; i < phy_regarray_pg_len; i = i + 6) {
666 v1 = phy_regarray_table_pg[i];
667 v2 = phy_regarray_table_pg[i+1];
668 v3 = phy_regarray_table_pg[i+2];
669 v4 = phy_regarray_table_pg[i+3];
670 v5 = phy_regarray_table_pg[i+4];
671 v6 = phy_regarray_table_pg[i+5];
672
673 if (v1 < 0xcdcdcdcd) {
674 if (phy_regarray_table_pg[i] == 0xfe ||
675 phy_regarray_table_pg[i] == 0xffe)
676 mdelay(50);
677 else
678 _rtl8723be_store_tx_power_by_rate(hw,
679 v1, v2, v3, v4, v5, v6);
680 continue;
681 } else {
682 /*don't need the hw_body*/
683 if (!_rtl8723be_check_condition(hw,
684 phy_regarray_table_pg[i])) {
685 i += 2; /* skip the pair of expression*/
686 v1 = phy_regarray_table_pg[i];
687 v2 = phy_regarray_table_pg[i+1];
688 v3 = phy_regarray_table_pg[i+2];
689 while (v2 != 0xDEAD) {
690 i += 3;
691 v1 = phy_regarray_table_pg[i];
692 v2 = phy_regarray_table_pg[i+1];
693 v3 = phy_regarray_table_pg[i+2];
694 }
695 }
696 }
697 }
698 } else {
699 RT_TRACE(rtlpriv, COMP_SEND, DBG_TRACE,
700 "configtype != BaseBand_Config_PHY_REG\n");
701 }
702 return true;
703}
704
705bool rtl8723be_phy_config_rf_with_headerfile(struct ieee80211_hw *hw,
706 enum radio_path rfpath)
707{
708 #define READ_NEXT_RF_PAIR(v1, v2, i) \
709 do { \
710 i += 2; \
711 v1 = radioa_array_table[i]; \
712 v2 = radioa_array_table[i+1]; \
713 } while (0)
714
715 int i;
716 bool rtstatus = true;
717 u32 *radioa_array_table;
718 u16 radioa_arraylen;
719 struct rtl_priv *rtlpriv = rtl_priv(hw);
720 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
721 u32 v1 = 0, v2 = 0;
722
723 radioa_arraylen = RTL8723BE_RADIOA_1TARRAYLEN;
724 radioa_array_table = RTL8723BE_RADIOA_1TARRAY;
725 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
726 "Radio_A:RTL8723BE_RADIOA_1TARRAY %d\n", radioa_arraylen);
727 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "Radio No %x\n", rfpath);
728 rtstatus = true;
729 switch (rfpath) {
730 case RF90_PATH_A:
731 for (i = 0; i < radioa_arraylen; i = i + 2) {
732 v1 = radioa_array_table[i];
733 v2 = radioa_array_table[i+1];
734 if (v1 < 0xcdcdcdcd) {
735 _rtl8723be_config_rf_radio_a(hw, v1, v2);
736 } else { /*This line is the start line of branch.*/
737 if (!_rtl8723be_check_condition(hw,
738 radioa_array_table[i])) {
739 /* Discard the following
740 * (offset, data) pairs
741 */
742 READ_NEXT_RF_PAIR(v1, v2, i);
743 while (v2 != 0xDEAD &&
744 v2 != 0xCDEF &&
745 v2 != 0xCDCD &&
746 i < radioa_arraylen - 2)
747 READ_NEXT_RF_PAIR(v1, v2, i);
748 i -= 2; /* prevent from for-loop += 2*/
749 } else {
750 /* Configure matched pairs
751 * and skip to end of if-else.
752 */
753 READ_NEXT_RF_PAIR(v1, v2, i);
754 while (v2 != 0xDEAD &&
755 v2 != 0xCDEF &&
756 v2 != 0xCDCD &&
757 i < radioa_arraylen - 2) {
758 _rtl8723be_config_rf_radio_a(hw,
759 v1, v2);
760 READ_NEXT_RF_PAIR(v1, v2, i);
761 }
762
763 while (v2 != 0xDEAD &&
764 i < radioa_arraylen - 2) {
765 READ_NEXT_RF_PAIR(v1, v2, i);
766 }
767 }
768 }
769 }
770
771 if (rtlhal->oem_id == RT_CID_819X_HP)
772 _rtl8723be_config_rf_radio_a(hw, 0x52, 0x7E4BD);
773
774 break;
775 case RF90_PATH_B:
776 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
777 "switch case not process\n");
778 break;
779 case RF90_PATH_C:
780 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
781 "switch case not process\n");
782 break;
783 case RF90_PATH_D:
784 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
785 "switch case not process\n");
786 break;
787 }
788 return true;
789}
790
791void rtl8723be_phy_get_hw_reg_originalvalue(struct ieee80211_hw *hw)
792{
793 struct rtl_priv *rtlpriv = rtl_priv(hw);
794 struct rtl_phy *rtlphy = &(rtlpriv->phy);
795
796 rtlphy->default_initialgain[0] =
797 (u8) rtl_get_bbreg(hw, ROFDM0_XAAGCCORE1, MASKBYTE0);
798 rtlphy->default_initialgain[1] =
799 (u8) rtl_get_bbreg(hw, ROFDM0_XBAGCCORE1, MASKBYTE0);
800 rtlphy->default_initialgain[2] =
801 (u8) rtl_get_bbreg(hw, ROFDM0_XCAGCCORE1, MASKBYTE0);
802 rtlphy->default_initialgain[3] =
803 (u8) rtl_get_bbreg(hw, ROFDM0_XDAGCCORE1, MASKBYTE0);
804
805 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
806 "Default initial gain (c50 = 0x%x, "
807 "c58 = 0x%x, c60 = 0x%x, c68 = 0x%x\n",
808 rtlphy->default_initialgain[0],
809 rtlphy->default_initialgain[1],
810 rtlphy->default_initialgain[2],
811 rtlphy->default_initialgain[3]);
812
813 rtlphy->framesync = (u8) rtl_get_bbreg(hw, ROFDM0_RXDETECTOR3,
814 MASKBYTE0);
815 rtlphy->framesync_c34 = rtl_get_bbreg(hw, ROFDM0_RXDETECTOR2,
816 MASKDWORD);
817
818 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
819 "Default framesync (0x%x) = 0x%x\n",
820 ROFDM0_RXDETECTOR3, rtlphy->framesync);
821}
822
823void rtl8723be_phy_get_txpower_level(struct ieee80211_hw *hw, long *powerlevel)
824{
825 struct rtl_priv *rtlpriv = rtl_priv(hw);
826 struct rtl_phy *rtlphy = &(rtlpriv->phy);
827 u8 txpwr_level;
828 long txpwr_dbm;
829
830 txpwr_level = rtlphy->cur_cck_txpwridx;
831 txpwr_dbm = rtl8723_phy_txpwr_idx_to_dbm(hw, WIRELESS_MODE_B,
832 txpwr_level);
833 txpwr_level = rtlphy->cur_ofdm24g_txpwridx;
834 if (rtl8723_phy_txpwr_idx_to_dbm(hw, WIRELESS_MODE_G, txpwr_level) >
835 txpwr_dbm)
836 txpwr_dbm =
837 rtl8723_phy_txpwr_idx_to_dbm(hw, WIRELESS_MODE_G,
838 txpwr_level);
839 txpwr_level = rtlphy->cur_ofdm24g_txpwridx;
840 if (rtl8723_phy_txpwr_idx_to_dbm(hw, WIRELESS_MODE_N_24G,
841 txpwr_level) > txpwr_dbm)
842 txpwr_dbm =
843 rtl8723_phy_txpwr_idx_to_dbm(hw, WIRELESS_MODE_N_24G,
844 txpwr_level);
845 *powerlevel = txpwr_dbm;
846}
847
848static u8 _rtl8723be_phy_get_ratesection_intxpower_byrate(enum radio_path path,
849 u8 rate)
850{
851 u8 rate_section = 0;
852
853 switch (rate) {
854 case DESC92C_RATE1M:
855 rate_section = 2;
856 break;
857 case DESC92C_RATE2M:
858 case DESC92C_RATE5_5M:
859 if (path == RF90_PATH_A)
860 rate_section = 3;
861 else if (path == RF90_PATH_B)
862 rate_section = 2;
863 break;
864 case DESC92C_RATE11M:
865 rate_section = 3;
866 break;
867 case DESC92C_RATE6M:
868 case DESC92C_RATE9M:
869 case DESC92C_RATE12M:
870 case DESC92C_RATE18M:
871 rate_section = 0;
872 break;
873 case DESC92C_RATE24M:
874 case DESC92C_RATE36M:
875 case DESC92C_RATE48M:
876 case DESC92C_RATE54M:
877 rate_section = 1;
878 break;
879 case DESC92C_RATEMCS0:
880 case DESC92C_RATEMCS1:
881 case DESC92C_RATEMCS2:
882 case DESC92C_RATEMCS3:
883 rate_section = 4;
884 break;
885 case DESC92C_RATEMCS4:
886 case DESC92C_RATEMCS5:
887 case DESC92C_RATEMCS6:
888 case DESC92C_RATEMCS7:
889 rate_section = 5;
890 break;
891 case DESC92C_RATEMCS8:
892 case DESC92C_RATEMCS9:
893 case DESC92C_RATEMCS10:
894 case DESC92C_RATEMCS11:
895 rate_section = 6;
896 break;
897 case DESC92C_RATEMCS12:
898 case DESC92C_RATEMCS13:
899 case DESC92C_RATEMCS14:
900 case DESC92C_RATEMCS15:
901 rate_section = 7;
902 break;
903 default:
904 RT_ASSERT(true, "Rate_Section is Illegal\n");
905 break;
906 }
907 return rate_section;
908}
909
910static u8 _rtl8723be_get_txpower_by_rate(struct ieee80211_hw *hw,
911 enum band_type band,
912 enum radio_path rfpath, u8 rate)
913{
914 struct rtl_priv *rtlpriv = rtl_priv(hw);
915 struct rtl_phy *rtlphy = &(rtlpriv->phy);
916 u8 shift = 0, rate_section, tx_num;
917 char tx_pwr_diff = 0;
918
919 rate_section = _rtl8723be_phy_get_ratesection_intxpower_byrate(rfpath,
920 rate);
921 tx_num = RF_TX_NUM_NONIMPLEMENT;
922
923 if (tx_num == RF_TX_NUM_NONIMPLEMENT) {
924 if (rate >= DESC92C_RATEMCS8 && rate <= DESC92C_RATEMCS15)
925 tx_num = RF_2TX;
926 else
927 tx_num = RF_1TX;
928 }
929
930 switch (rate) {
931 case DESC92C_RATE6M:
932 case DESC92C_RATE24M:
933 case DESC92C_RATEMCS0:
934 case DESC92C_RATEMCS4:
935 case DESC92C_RATEMCS8:
936 case DESC92C_RATEMCS12:
937 shift = 0;
938 break;
939 case DESC92C_RATE1M:
940 case DESC92C_RATE2M:
941 case DESC92C_RATE9M:
942 case DESC92C_RATE36M:
943 case DESC92C_RATEMCS1:
944 case DESC92C_RATEMCS5:
945 case DESC92C_RATEMCS9:
946 case DESC92C_RATEMCS13:
947 shift = 8;
948 break;
949 case DESC92C_RATE5_5M:
950 case DESC92C_RATE12M:
951 case DESC92C_RATE48M:
952 case DESC92C_RATEMCS2:
953 case DESC92C_RATEMCS6:
954 case DESC92C_RATEMCS10:
955 case DESC92C_RATEMCS14:
956 shift = 16;
957 break;
958 case DESC92C_RATE11M:
959 case DESC92C_RATE18M:
960 case DESC92C_RATE54M:
961 case DESC92C_RATEMCS3:
962 case DESC92C_RATEMCS7:
963 case DESC92C_RATEMCS11:
964 case DESC92C_RATEMCS15:
965 shift = 24;
966 break;
967 default:
968 RT_ASSERT(true, "Rate_Section is Illegal\n");
969 break;
970 }
971 tx_pwr_diff = (u8)(rtlphy->tx_power_by_rate_offset[band][rfpath][tx_num]
972 [rate_section] >> shift) & 0xff;
973
974 return tx_pwr_diff;
975}
976
977static u8 _rtl8723be_get_txpower_index(struct ieee80211_hw *hw, u8 path,
978 u8 rate, u8 bandwidth, u8 channel)
979{
980 struct rtl_priv *rtlpriv = rtl_priv(hw);
981 struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
982 u8 index = (channel - 1);
983 u8 txpower;
984 u8 power_diff_byrate = 0;
985
986 if (channel > 14 || channel < 1) {
987 index = 0;
988 RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
989 "Illegal channel!\n");
990 }
991 if (RTL8723E_RX_HAL_IS_CCK_RATE(rate))
992 txpower = rtlefuse->txpwrlevel_cck[path][index];
993 else if (DESC92C_RATE6M <= rate)
994 txpower = rtlefuse->txpwrlevel_ht40_1s[path][index];
995 else
996 RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
997 "invalid rate\n");
998
999 if (DESC92C_RATE6M <= rate && rate <= DESC92C_RATE54M &&
1000 !RTL8723E_RX_HAL_IS_CCK_RATE(rate))
1001 txpower += rtlefuse->txpwr_legacyhtdiff[0][TX_1S];
1002
1003 if (bandwidth == HT_CHANNEL_WIDTH_20) {
1004 if (DESC92C_RATEMCS0 <= rate && rate <= DESC92C_RATEMCS15)
1005 txpower += rtlefuse->txpwr_ht20diff[0][TX_1S];
1006 if (DESC92C_RATEMCS8 <= rate && rate <= DESC92C_RATEMCS15)
1007 txpower += rtlefuse->txpwr_ht20diff[0][TX_2S];
1008 } else if (bandwidth == HT_CHANNEL_WIDTH_20_40) {
1009 if (DESC92C_RATEMCS0 <= rate && rate <= DESC92C_RATEMCS15)
1010 txpower += rtlefuse->txpwr_ht40diff[0][TX_1S];
1011 if (DESC92C_RATEMCS8 <= rate && rate <= DESC92C_RATEMCS15)
1012 txpower += rtlefuse->txpwr_ht40diff[0][TX_2S];
1013 }
1014 if (rtlefuse->eeprom_regulatory != 2)
1015 power_diff_byrate = _rtl8723be_get_txpower_by_rate(hw,
1016 BAND_ON_2_4G,
1017 path, rate);
1018
1019 txpower += power_diff_byrate;
1020
1021 if (txpower > MAX_POWER_INDEX)
1022 txpower = MAX_POWER_INDEX;
1023
1024 return txpower;
1025}
1026
1027static void _rtl8723be_phy_set_txpower_index(struct ieee80211_hw *hw,
1028 u8 power_index, u8 path, u8 rate)
1029{
1030 struct rtl_priv *rtlpriv = rtl_priv(hw);
1031 if (path == RF90_PATH_A) {
1032 switch (rate) {
1033 case DESC92C_RATE1M:
1034 rtl8723_phy_set_bb_reg(hw, RTXAGC_A_CCK1_MCS32,
1035 MASKBYTE1, power_index);
1036 break;
1037 case DESC92C_RATE2M:
1038 rtl8723_phy_set_bb_reg(hw, RTXAGC_B_CCK11_A_CCK2_11,
1039 MASKBYTE1, power_index);
1040 break;
1041 case DESC92C_RATE5_5M:
1042 rtl8723_phy_set_bb_reg(hw, RTXAGC_B_CCK11_A_CCK2_11,
1043 MASKBYTE2, power_index);
1044 break;
1045 case DESC92C_RATE11M:
1046 rtl8723_phy_set_bb_reg(hw, RTXAGC_B_CCK11_A_CCK2_11,
1047 MASKBYTE3, power_index);
1048 break;
1049 case DESC92C_RATE6M:
1050 rtl8723_phy_set_bb_reg(hw, RTXAGC_A_RATE18_06,
1051 MASKBYTE0, power_index);
1052 break;
1053 case DESC92C_RATE9M:
1054 rtl8723_phy_set_bb_reg(hw, RTXAGC_A_RATE18_06,
1055 MASKBYTE1, power_index);
1056 break;
1057 case DESC92C_RATE12M:
1058 rtl8723_phy_set_bb_reg(hw, RTXAGC_A_RATE18_06,
1059 MASKBYTE2, power_index);
1060 break;
1061 case DESC92C_RATE18M:
1062 rtl8723_phy_set_bb_reg(hw, RTXAGC_A_RATE18_06,
1063 MASKBYTE3, power_index);
1064 break;
1065 case DESC92C_RATE24M:
1066 rtl8723_phy_set_bb_reg(hw, RTXAGC_A_RATE54_24,
1067 MASKBYTE0, power_index);
1068 break;
1069 case DESC92C_RATE36M:
1070 rtl8723_phy_set_bb_reg(hw, RTXAGC_A_RATE54_24,
1071 MASKBYTE1, power_index);
1072 break;
1073 case DESC92C_RATE48M:
1074 rtl8723_phy_set_bb_reg(hw, RTXAGC_A_RATE54_24,
1075 MASKBYTE2, power_index);
1076 break;
1077 case DESC92C_RATE54M:
1078 rtl8723_phy_set_bb_reg(hw, RTXAGC_A_RATE54_24,
1079 MASKBYTE3, power_index);
1080 break;
1081 case DESC92C_RATEMCS0:
1082 rtl8723_phy_set_bb_reg(hw, RTXAGC_A_MCS03_MCS00,
1083 MASKBYTE0, power_index);
1084 break;
1085 case DESC92C_RATEMCS1:
1086 rtl8723_phy_set_bb_reg(hw, RTXAGC_A_MCS03_MCS00,
1087 MASKBYTE1, power_index);
1088 break;
1089 case DESC92C_RATEMCS2:
1090 rtl8723_phy_set_bb_reg(hw, RTXAGC_A_MCS03_MCS00,
1091 MASKBYTE2, power_index);
1092 break;
1093 case DESC92C_RATEMCS3:
1094 rtl8723_phy_set_bb_reg(hw, RTXAGC_A_MCS03_MCS00,
1095 MASKBYTE3, power_index);
1096 break;
1097 case DESC92C_RATEMCS4:
1098 rtl8723_phy_set_bb_reg(hw, RTXAGC_A_MCS07_MCS04,
1099 MASKBYTE0, power_index);
1100 break;
1101 case DESC92C_RATEMCS5:
1102 rtl8723_phy_set_bb_reg(hw, RTXAGC_A_MCS07_MCS04,
1103 MASKBYTE1, power_index);
1104 break;
1105 case DESC92C_RATEMCS6:
1106 rtl8723_phy_set_bb_reg(hw, RTXAGC_A_MCS07_MCS04,
1107 MASKBYTE2, power_index);
1108 break;
1109 case DESC92C_RATEMCS7:
1110 rtl8723_phy_set_bb_reg(hw, RTXAGC_A_MCS07_MCS04,
1111 MASKBYTE3, power_index);
1112 break;
1113 case DESC92C_RATEMCS8:
1114 rtl8723_phy_set_bb_reg(hw, RTXAGC_A_MCS11_MCS08,
1115 MASKBYTE0, power_index);
1116 break;
1117 case DESC92C_RATEMCS9:
1118 rtl8723_phy_set_bb_reg(hw, RTXAGC_A_MCS11_MCS08,
1119 MASKBYTE1, power_index);
1120 break;
1121 case DESC92C_RATEMCS10:
1122 rtl8723_phy_set_bb_reg(hw, RTXAGC_A_MCS11_MCS08,
1123 MASKBYTE2, power_index);
1124 break;
1125 case DESC92C_RATEMCS11:
1126 rtl8723_phy_set_bb_reg(hw, RTXAGC_A_MCS11_MCS08,
1127 MASKBYTE3, power_index);
1128 break;
1129 default:
1130 RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
1131 "Invalid Rate!!\n");
1132 break;
1133 }
1134 } else {
1135 RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, "Invalid RFPath!!\n");
1136 }
1137}
1138
1139void rtl8723be_phy_set_txpower_level(struct ieee80211_hw *hw, u8 channel)
1140{
1141 struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
1142 u8 cck_rates[] = {DESC92C_RATE1M, DESC92C_RATE2M,
1143 DESC92C_RATE5_5M, DESC92C_RATE11M};
1144 u8 ofdm_rates[] = {DESC92C_RATE6M, DESC92C_RATE9M,
1145 DESC92C_RATE12M, DESC92C_RATE18M,
1146 DESC92C_RATE24M, DESC92C_RATE36M,
1147 DESC92C_RATE48M, DESC92C_RATE54M};
1148 u8 ht_rates_1t[] = {DESC92C_RATEMCS0, DESC92C_RATEMCS1,
1149 DESC92C_RATEMCS2, DESC92C_RATEMCS3,
1150 DESC92C_RATEMCS4, DESC92C_RATEMCS5,
1151 DESC92C_RATEMCS6, DESC92C_RATEMCS7};
1152 u8 i, size;
1153 u8 power_index;
1154
1155 if (!rtlefuse->txpwr_fromeprom)
1156 return;
1157
1158 size = sizeof(cck_rates) / sizeof(u8);
1159 for (i = 0; i < size; i++) {
1160 power_index = _rtl8723be_get_txpower_index(hw, RF90_PATH_A,
1161 cck_rates[i],
1162 rtl_priv(hw)->phy.current_chan_bw,
1163 channel);
1164 _rtl8723be_phy_set_txpower_index(hw, power_index, RF90_PATH_A,
1165 cck_rates[i]);
1166 }
1167 size = sizeof(ofdm_rates) / sizeof(u8);
1168 for (i = 0; i < size; i++) {
1169 power_index = _rtl8723be_get_txpower_index(hw, RF90_PATH_A,
1170 ofdm_rates[i],
1171 rtl_priv(hw)->phy.current_chan_bw,
1172 channel);
1173 _rtl8723be_phy_set_txpower_index(hw, power_index, RF90_PATH_A,
1174 ofdm_rates[i]);
1175 }
1176 size = sizeof(ht_rates_1t) / sizeof(u8);
1177 for (i = 0; i < size; i++) {
1178 power_index = _rtl8723be_get_txpower_index(hw, RF90_PATH_A,
1179 ht_rates_1t[i],
1180 rtl_priv(hw)->phy.current_chan_bw,
1181 channel);
1182 _rtl8723be_phy_set_txpower_index(hw, power_index, RF90_PATH_A,
1183 ht_rates_1t[i]);
1184 }
1185}
1186
1187void rtl8723be_phy_scan_operation_backup(struct ieee80211_hw *hw, u8 operation)
1188{
1189 struct rtl_priv *rtlpriv = rtl_priv(hw);
1190 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
1191 enum io_type iotype;
1192
1193 if (!is_hal_stop(rtlhal)) {
1194 switch (operation) {
1195 case SCAN_OPT_BACKUP:
1196 iotype = IO_CMD_PAUSE_DM_BY_SCAN;
1197 rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_IO_CMD,
1198 (u8 *)&iotype);
1199 break;
1200 case SCAN_OPT_RESTORE:
1201 iotype = IO_CMD_RESUME_DM_BY_SCAN;
1202 rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_IO_CMD,
1203 (u8 *)&iotype);
1204 break;
1205 default:
1206 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
1207 "Unknown Scan Backup operation.\n");
1208 break;
1209 }
1210 }
1211}
1212
1213void rtl8723be_phy_set_bw_mode_callback(struct ieee80211_hw *hw)
1214{
1215 struct rtl_priv *rtlpriv = rtl_priv(hw);
1216 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
1217 struct rtl_phy *rtlphy = &(rtlpriv->phy);
1218 struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
1219 u8 reg_bw_opmode;
1220 u8 reg_prsr_rsc;
1221
1222 RT_TRACE(rtlpriv, COMP_SCAN, DBG_TRACE,
1223 "Switch to %s bandwidth\n",
1224 rtlphy->current_chan_bw == HT_CHANNEL_WIDTH_20 ?
1225 "20MHz" : "40MHz");
1226
1227 if (is_hal_stop(rtlhal)) {
1228 rtlphy->set_bwmode_inprogress = false;
1229 return;
1230 }
1231
1232 reg_bw_opmode = rtl_read_byte(rtlpriv, REG_BWOPMODE);
1233 reg_prsr_rsc = rtl_read_byte(rtlpriv, REG_RRSR + 2);
1234
1235 switch (rtlphy->current_chan_bw) {
1236 case HT_CHANNEL_WIDTH_20:
1237 reg_bw_opmode |= BW_OPMODE_20MHZ;
1238 rtl_write_byte(rtlpriv, REG_BWOPMODE, reg_bw_opmode);
1239 break;
1240 case HT_CHANNEL_WIDTH_20_40:
1241 reg_bw_opmode &= ~BW_OPMODE_20MHZ;
1242 rtl_write_byte(rtlpriv, REG_BWOPMODE, reg_bw_opmode);
1243 reg_prsr_rsc = (reg_prsr_rsc & 0x90) |
1244 (mac->cur_40_prime_sc << 5);
1245 rtl_write_byte(rtlpriv, REG_RRSR + 2, reg_prsr_rsc);
1246 break;
1247 default:
1248 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
1249 "unknown bandwidth: %#X\n", rtlphy->current_chan_bw);
1250 break;
1251 }
1252
1253 switch (rtlphy->current_chan_bw) {
1254 case HT_CHANNEL_WIDTH_20:
1255 rtl_set_bbreg(hw, RFPGA0_RFMOD, BRFMOD, 0x0);
1256 rtl_set_bbreg(hw, RFPGA1_RFMOD, BRFMOD, 0x0);
1257 break;
1258 case HT_CHANNEL_WIDTH_20_40:
1259 rtl_set_bbreg(hw, RFPGA0_RFMOD, BRFMOD, 0x1);
1260 rtl_set_bbreg(hw, RFPGA1_RFMOD, BRFMOD, 0x1);
1261 rtl_set_bbreg(hw, RCCK0_SYSTEM, BCCK_SIDEBAND,
1262 (mac->cur_40_prime_sc >> 1));
1263 rtl_set_bbreg(hw, ROFDM1_LSTF, 0xC00, mac->cur_40_prime_sc);
1264 rtl_set_bbreg(hw, 0x818, (BIT(26) | BIT(27)),
1265 (mac->cur_40_prime_sc ==
1266 HAL_PRIME_CHNL_OFFSET_LOWER) ? 2 : 1);
1267 break;
1268 default:
1269 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
1270 "unknown bandwidth: %#X\n", rtlphy->current_chan_bw);
1271 break;
1272 }
1273 rtl8723be_phy_rf6052_set_bandwidth(hw, rtlphy->current_chan_bw);
1274 rtlphy->set_bwmode_inprogress = false;
1275 RT_TRACE(rtlpriv, COMP_SCAN, DBG_LOUD, "\n");
1276}
1277
1278void rtl8723be_phy_set_bw_mode(struct ieee80211_hw *hw,
1279 enum nl80211_channel_type ch_type)
1280{
1281 struct rtl_priv *rtlpriv = rtl_priv(hw);
1282 struct rtl_phy *rtlphy = &(rtlpriv->phy);
1283 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
1284 u8 tmp_bw = rtlphy->current_chan_bw;
1285
1286 if (rtlphy->set_bwmode_inprogress)
1287 return;
1288 rtlphy->set_bwmode_inprogress = true;
1289 if ((!is_hal_stop(rtlhal)) && !(RT_CANNOT_IO(hw))) {
1290 rtl8723be_phy_set_bw_mode_callback(hw);
1291 } else {
1292 RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
1293 "false driver sleep or unload\n");
1294 rtlphy->set_bwmode_inprogress = false;
1295 rtlphy->current_chan_bw = tmp_bw;
1296 }
1297}
1298
1299void rtl8723be_phy_sw_chnl_callback(struct ieee80211_hw *hw)
1300{
1301 struct rtl_priv *rtlpriv = rtl_priv(hw);
1302 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
1303 struct rtl_phy *rtlphy = &(rtlpriv->phy);
1304 u32 delay;
1305
1306 RT_TRACE(rtlpriv, COMP_SCAN, DBG_TRACE,
1307 "switch to channel%d\n", rtlphy->current_channel);
1308 if (is_hal_stop(rtlhal))
1309 return;
1310 do {
1311 if (!rtlphy->sw_chnl_inprogress)
1312 break;
1313 if (!rtl8723be_phy_sw_chn_step_by_step(hw,
1314 rtlphy->current_channel,
1315 &rtlphy->sw_chnl_stage,
1316 &rtlphy->sw_chnl_step,
1317 &delay)) {
1318 if (delay > 0)
1319 mdelay(delay);
1320 else
1321 continue;
1322 } else {
1323 rtlphy->sw_chnl_inprogress = false;
1324 }
1325 break;
1326 } while (true);
1327 RT_TRACE(rtlpriv, COMP_SCAN, DBG_TRACE, "\n");
1328}
1329
1330u8 rtl8723be_phy_sw_chnl(struct ieee80211_hw *hw)
1331{
1332 struct rtl_priv *rtlpriv = rtl_priv(hw);
1333 struct rtl_phy *rtlphy = &(rtlpriv->phy);
1334 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
1335
1336 if (rtlphy->sw_chnl_inprogress)
1337 return 0;
1338 if (rtlphy->set_bwmode_inprogress)
1339 return 0;
1340 RT_ASSERT((rtlphy->current_channel <= 14),
1341 "WIRELESS_MODE_G but channel>14");
1342 rtlphy->sw_chnl_inprogress = true;
1343 rtlphy->sw_chnl_stage = 0;
1344 rtlphy->sw_chnl_step = 0;
1345 if (!(is_hal_stop(rtlhal)) && !(RT_CANNOT_IO(hw))) {
1346 rtl8723be_phy_sw_chnl_callback(hw);
1347 RT_TRACE(rtlpriv, COMP_CHAN, DBG_LOUD,
1348 "sw_chnl_inprogress false schdule "
1349 "workitem current channel %d\n",
1350 rtlphy->current_channel);
1351 rtlphy->sw_chnl_inprogress = false;
1352 } else {
1353 RT_TRACE(rtlpriv, COMP_CHAN, DBG_LOUD,
1354 "sw_chnl_inprogress false driver sleep or"
1355 " unload\n");
1356 rtlphy->sw_chnl_inprogress = false;
1357 }
1358 return 1;
1359}
1360
1361static bool rtl8723be_phy_sw_chn_step_by_step(struct ieee80211_hw *hw,
1362 u8 channel, u8 *stage,
1363 u8 *step, u32 *delay)
1364{
1365 struct rtl_priv *rtlpriv = rtl_priv(hw);
1366 struct rtl_phy *rtlphy = &(rtlpriv->phy);
1367 struct swchnlcmd precommoncmd[MAX_PRECMD_CNT];
1368 u32 precommoncmdcnt;
1369 struct swchnlcmd postcommoncmd[MAX_POSTCMD_CNT];
1370 u32 postcommoncmdcnt;
1371 struct swchnlcmd rfdependcmd[MAX_RFDEPENDCMD_CNT];
1372 u32 rfdependcmdcnt;
1373 struct swchnlcmd *currentcmd = NULL;
1374 u8 rfpath;
1375 u8 num_total_rfpath = rtlphy->num_total_rfpath;
1376
1377 precommoncmdcnt = 0;
1378 rtl8723_phy_set_sw_chnl_cmdarray(precommoncmd, precommoncmdcnt++,
1379 MAX_PRECMD_CNT,
1380 CMDID_SET_TXPOWEROWER_LEVEL,
1381 0, 0, 0);
1382 rtl8723_phy_set_sw_chnl_cmdarray(precommoncmd, precommoncmdcnt++,
1383 MAX_PRECMD_CNT, CMDID_END, 0, 0, 0);
1384 postcommoncmdcnt = 0;
1385 rtl8723_phy_set_sw_chnl_cmdarray(postcommoncmd, postcommoncmdcnt++,
1386 MAX_POSTCMD_CNT, CMDID_END,
1387 0, 0, 0);
1388 rfdependcmdcnt = 0;
1389
1390 RT_ASSERT((channel >= 1 && channel <= 14),
1391 "illegal channel for Zebra: %d\n", channel);
1392
1393 rtl8723_phy_set_sw_chnl_cmdarray(rfdependcmd, rfdependcmdcnt++,
1394 MAX_RFDEPENDCMD_CNT,
1395 CMDID_RF_WRITEREG,
1396 RF_CHNLBW, channel, 10);
1397
1398 rtl8723_phy_set_sw_chnl_cmdarray(rfdependcmd, rfdependcmdcnt++,
1399 MAX_RFDEPENDCMD_CNT,
1400 CMDID_END, 0, 0, 0);
1401
1402 do {
1403 switch (*stage) {
1404 case 0:
1405 currentcmd = &precommoncmd[*step];
1406 break;
1407 case 1:
1408 currentcmd = &rfdependcmd[*step];
1409 break;
1410 case 2:
1411 currentcmd = &postcommoncmd[*step];
1412 break;
1413 }
1414
1415 if (currentcmd->cmdid == CMDID_END) {
1416 if ((*stage) == 2) {
1417 return true;
1418 } else {
1419 (*stage)++;
1420 (*step) = 0;
1421 continue;
1422 }
1423 }
1424
1425 switch (currentcmd->cmdid) {
1426 case CMDID_SET_TXPOWEROWER_LEVEL:
1427 rtl8723be_phy_set_txpower_level(hw, channel);
1428 break;
1429 case CMDID_WRITEPORT_ULONG:
1430 rtl_write_dword(rtlpriv, currentcmd->para1,
1431 currentcmd->para2);
1432 break;
1433 case CMDID_WRITEPORT_USHORT:
1434 rtl_write_word(rtlpriv, currentcmd->para1,
1435 (u16) currentcmd->para2);
1436 break;
1437 case CMDID_WRITEPORT_UCHAR:
1438 rtl_write_byte(rtlpriv, currentcmd->para1,
1439 (u8) currentcmd->para2);
1440 break;
1441 case CMDID_RF_WRITEREG:
1442 for (rfpath = 0; rfpath < num_total_rfpath; rfpath++) {
1443 rtlphy->rfreg_chnlval[rfpath] =
1444 ((rtlphy->rfreg_chnlval[rfpath] &
1445 0xfffffc00) | currentcmd->para2);
1446
1447 rtl_set_rfreg(hw, (enum radio_path)rfpath,
1448 currentcmd->para1,
1449 RFREG_OFFSET_MASK,
1450 rtlphy->rfreg_chnlval[rfpath]);
1451 }
1452 break;
1453 default:
1454 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
1455 "switch case not process\n");
1456 break;
1457 }
1458
1459 break;
1460 } while (true);
1461
1462 (*delay) = currentcmd->msdelay;
1463 (*step)++;
1464 return false;
1465}
1466
1467static u8 _rtl8723be_phy_path_a_iqk(struct ieee80211_hw *hw, bool config_pathb)
1468{
1469 u32 reg_eac, reg_e94, reg_e9c, reg_ea4;
1470 u8 result = 0x00;
1471
1472 rtl_set_bbreg(hw, 0xe30, MASKDWORD, 0x10008c1c);
1473 rtl_set_bbreg(hw, 0xe34, MASKDWORD, 0x30008c1c);
1474 rtl_set_bbreg(hw, 0xe38, MASKDWORD, 0x8214032a);
1475 rtl_set_bbreg(hw, 0xe3c, MASKDWORD, 0x28160000);
1476
1477 rtl_set_bbreg(hw, 0xe4c, MASKDWORD, 0x00462911);
1478 rtl_set_bbreg(hw, 0xe48, MASKDWORD, 0xf9000000);
1479 rtl_set_bbreg(hw, 0xe48, MASKDWORD, 0xf8000000);
1480
1481 mdelay(IQK_DELAY_TIME);
1482
1483 reg_eac = rtl_get_bbreg(hw, 0xeac, MASKDWORD);
1484 reg_e94 = rtl_get_bbreg(hw, 0xe94, MASKDWORD);
1485 reg_e9c = rtl_get_bbreg(hw, 0xe9c, MASKDWORD);
1486 reg_ea4 = rtl_get_bbreg(hw, 0xea4, MASKDWORD);
1487
1488 if (!(reg_eac & BIT(28)) &&
1489 (((reg_e94 & 0x03FF0000) >> 16) != 0x142) &&
1490 (((reg_e9c & 0x03FF0000) >> 16) != 0x42))
1491 result |= 0x01;
1492 return result;
1493}
1494
1495static bool phy_similarity_cmp(struct ieee80211_hw *hw, long result[][8],
1496 u8 c1, u8 c2)
1497{
1498 u32 i, j, diff, simularity_bitmap, bound;
1499 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
1500
1501 u8 final_candidate[2] = { 0xFF, 0xFF };
1502 bool bresult = true, is2t = IS_92C_SERIAL(rtlhal->version);
1503
1504 if (is2t)
1505 bound = 8;
1506 else
1507 bound = 4;
1508
1509 simularity_bitmap = 0;
1510
1511 for (i = 0; i < bound; i++) {
1512 diff = (result[c1][i] > result[c2][i]) ?
1513 (result[c1][i] - result[c2][i]) :
1514 (result[c2][i] - result[c1][i]);
1515
1516 if (diff > MAX_TOLERANCE) {
1517 if ((i == 2 || i == 6) && !simularity_bitmap) {
1518 if (result[c1][i] + result[c1][i + 1] == 0)
1519 final_candidate[(i / 4)] = c2;
1520 else if (result[c2][i] + result[c2][i + 1] == 0)
1521 final_candidate[(i / 4)] = c1;
1522 else
1523 simularity_bitmap |= (1 << i);
1524 } else {
1525 simularity_bitmap |= (1 << i);
1526 }
1527 }
1528 }
1529
1530 if (simularity_bitmap == 0) {
1531 for (i = 0; i < (bound / 4); i++) {
1532 if (final_candidate[i] != 0xFF) {
1533 for (j = i * 4; j < (i + 1) * 4 - 2; j++)
1534 result[3][j] =
1535 result[final_candidate[i]][j];
1536 bresult = false;
1537 }
1538 }
1539 return bresult;
1540 } else if (!(simularity_bitmap & 0x0F)) {
1541 for (i = 0; i < 4; i++)
1542 result[3][i] = result[c1][i];
1543 return false;
1544 } else if (!(simularity_bitmap & 0xF0) && is2t) {
1545 for (i = 4; i < 8; i++)
1546 result[3][i] = result[c1][i];
1547 return false;
1548 } else {
1549 return false;
1550 }
1551}
1552
1553static void _rtl8723be_phy_iq_calibrate(struct ieee80211_hw *hw,
1554 long result[][8], u8 t, bool is2t)
1555{
1556 struct rtl_priv *rtlpriv = rtl_priv(hw);
1557 struct rtl_phy *rtlphy = &(rtlpriv->phy);
1558 u32 i;
1559 u8 patha_ok;
1560 u32 adda_reg[IQK_ADDA_REG_NUM] = {
1561 0x85c, 0xe6c, 0xe70, 0xe74,
1562 0xe78, 0xe7c, 0xe80, 0xe84,
1563 0xe88, 0xe8c, 0xed0, 0xed4,
1564 0xed8, 0xedc, 0xee0, 0xeec
1565 };
1566
1567 u32 iqk_mac_reg[IQK_MAC_REG_NUM] = {
1568 0x522, 0x550, 0x551, 0x040
1569 };
1570 u32 iqk_bb_reg[IQK_BB_REG_NUM] = {
1571 ROFDM0_TRXPATHENABLE, ROFDM0_TRMUXPAR,
1572 RFPGA0_XCD_RFINTERFACESW, 0xb68, 0xb6c,
1573 0x870, 0x860,
1574 0x864, 0x800
1575 };
1576 const u32 retrycount = 2;
1577 u32 path_sel_bb, path_sel_rf;
1578 u8 tmp_reg_c50, tmp_reg_c58;
1579
1580 tmp_reg_c50 = rtl_get_bbreg(hw, 0xc50, MASKBYTE0);
1581 tmp_reg_c58 = rtl_get_bbreg(hw, 0xc58, MASKBYTE0);
1582
1583 if (t == 0) {
1584 rtl8723_save_adda_registers(hw, adda_reg,
1585 rtlphy->adda_backup, 16);
1586 rtl8723_phy_save_mac_registers(hw, iqk_mac_reg,
1587 rtlphy->iqk_mac_backup);
1588 rtl8723_save_adda_registers(hw, iqk_bb_reg,
1589 rtlphy->iqk_bb_backup,
1590 IQK_BB_REG_NUM);
1591 }
1592 rtl8723_phy_path_adda_on(hw, adda_reg, true, is2t);
1593 if (t == 0) {
1594 rtlphy->rfpi_enable = (u8) rtl_get_bbreg(hw,
1595 RFPGA0_XA_HSSIPARAMETER1,
1596 BIT(8));
1597 }
1598 if (!rtlphy->rfpi_enable)
1599 rtl8723_phy_pi_mode_switch(hw, true);
1600
1601 path_sel_bb = rtl_get_bbreg(hw, 0x948, MASKDWORD);
1602 path_sel_rf = rtl_get_rfreg(hw, RF90_PATH_A, 0xb0, 0xfffff);
1603
1604 /*BB Setting*/
1605 rtl_set_bbreg(hw, 0x800, BIT(24), 0x00);
1606 rtl_set_bbreg(hw, 0xc04, MASKDWORD, 0x03a05600);
1607 rtl_set_bbreg(hw, 0xc08, MASKDWORD, 0x000800e4);
1608 rtl_set_bbreg(hw, 0x874, MASKDWORD, 0x22204000);
1609
1610 rtl_set_bbreg(hw, 0x870, BIT(10), 0x01);
1611 rtl_set_bbreg(hw, 0x870, BIT(26), 0x01);
1612 rtl_set_bbreg(hw, 0x860, BIT(10), 0x00);
1613 rtl_set_bbreg(hw, 0x864, BIT(10), 0x00);
1614
1615 if (is2t)
1616 rtl_set_rfreg(hw, RF90_PATH_B, 0x00, MASKDWORD, 0x10000);
1617 rtl8723_phy_mac_setting_calibration(hw, iqk_mac_reg,
1618 rtlphy->iqk_mac_backup);
1619 rtl_set_bbreg(hw, 0xb68, MASKDWORD, 0x0f600000);
1620
1621 rtl_set_bbreg(hw, 0xe28, MASKDWORD, 0x80800000);
1622 rtl_set_bbreg(hw, 0xe40, MASKDWORD, 0x01007c00);
1623 rtl_set_bbreg(hw, 0xe44, MASKDWORD, 0x81004800);
1624 for (i = 0; i < retrycount; i++) {
1625 patha_ok = _rtl8723be_phy_path_a_iqk(hw, is2t);
1626 if (patha_ok == 0x01) {
1627 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
1628 "Path A Tx IQK Success!!\n");
1629 result[t][0] = (rtl_get_bbreg(hw, 0xe94, MASKDWORD) &
1630 0x3FF0000) >> 16;
1631 result[t][1] = (rtl_get_bbreg(hw, 0xe9c, MASKDWORD) &
1632 0x3FF0000) >> 16;
1633 break;
1634 }
1635 }
1636
1637 if (0 == patha_ok)
1638 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
1639 "Path A IQK Success!!\n");
1640 if (is2t) {
1641 rtl8723_phy_path_a_standby(hw);
1642 rtl8723_phy_path_adda_on(hw, adda_reg, false, is2t);
1643 }
1644
1645 rtl_set_bbreg(hw, 0xe28, MASKDWORD, 0);
1646
1647 if (t != 0) {
1648 if (!rtlphy->rfpi_enable)
1649 rtl8723_phy_pi_mode_switch(hw, false);
1650 rtl8723_phy_reload_adda_registers(hw, adda_reg,
1651 rtlphy->adda_backup, 16);
1652 rtl8723_phy_reload_mac_registers(hw, iqk_mac_reg,
1653 rtlphy->iqk_mac_backup);
1654 rtl8723_phy_reload_adda_registers(hw, iqk_bb_reg,
1655 rtlphy->iqk_bb_backup,
1656 IQK_BB_REG_NUM);
1657
1658 rtl_set_bbreg(hw, 0x948, MASKDWORD, path_sel_bb);
1659 rtl_set_rfreg(hw, RF90_PATH_B, 0xb0, 0xfffff, path_sel_rf);
1660
1661 rtl_set_bbreg(hw, 0xc50, MASKBYTE0, 0x50);
1662 rtl_set_bbreg(hw, 0xc50, MASKBYTE0, tmp_reg_c50);
1663 if (is2t) {
1664 rtl_set_bbreg(hw, 0xc58, MASKBYTE0, 0x50);
1665 rtl_set_bbreg(hw, 0xc58, MASKBYTE0, tmp_reg_c58);
1666 }
1667 rtl_set_bbreg(hw, 0xe30, MASKDWORD, 0x01008c00);
1668 rtl_set_bbreg(hw, 0xe34, MASKDWORD, 0x01008c00);
1669 }
1670 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "8723be IQK Finish!!\n");
1671}
1672
1673static void _rtl8723be_phy_lc_calibrate(struct ieee80211_hw *hw, bool is2t)
1674{
1675 struct rtl_priv *rtlpriv = rtl_priv(hw);
1676 u8 tmpreg;
1677 u32 rf_a_mode = 0, rf_b_mode = 0, lc_cal;
1678
1679 tmpreg = rtl_read_byte(rtlpriv, 0xd03);
1680
1681 if ((tmpreg & 0x70) != 0)
1682 rtl_write_byte(rtlpriv, 0xd03, tmpreg & 0x8F);
1683 else
1684 rtl_write_byte(rtlpriv, REG_TXPAUSE, 0xFF);
1685
1686 if ((tmpreg & 0x70) != 0) {
1687 rf_a_mode = rtl_get_rfreg(hw, RF90_PATH_A, 0x00, MASK12BITS);
1688
1689 if (is2t)
1690 rf_b_mode = rtl_get_rfreg(hw, RF90_PATH_B, 0x00,
1691 MASK12BITS);
1692
1693 rtl_set_rfreg(hw, RF90_PATH_A, 0x00, MASK12BITS,
1694 (rf_a_mode & 0x8FFFF) | 0x10000);
1695
1696 if (is2t)
1697 rtl_set_rfreg(hw, RF90_PATH_B, 0x00, MASK12BITS,
1698 (rf_b_mode & 0x8FFFF) | 0x10000);
1699 }
1700 lc_cal = rtl_get_rfreg(hw, RF90_PATH_A, 0x18, MASK12BITS);
1701
1702 rtl_set_rfreg(hw, RF90_PATH_A, 0xb0, RFREG_OFFSET_MASK, 0xdfbe0);
1703 rtl_set_rfreg(hw, RF90_PATH_A, 0x18, MASK12BITS, 0x8c0a);
1704
1705 mdelay(100);
1706
1707 rtl_set_rfreg(hw, RF90_PATH_A, 0xb0, RFREG_OFFSET_MASK, 0xdffe0);
1708
1709 if ((tmpreg & 0x70) != 0) {
1710 rtl_write_byte(rtlpriv, 0xd03, tmpreg);
1711 rtl_set_rfreg(hw, RF90_PATH_A, 0x00, MASK12BITS, rf_a_mode);
1712
1713 if (is2t)
1714 rtl_set_rfreg(hw, RF90_PATH_B, 0x00,
1715 MASK12BITS, rf_b_mode);
1716 } else {
1717 rtl_write_byte(rtlpriv, REG_TXPAUSE, 0x00);
1718 }
1719 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "\n");
1720}
1721
1722static void _rtl8723be_phy_set_rfpath_switch(struct ieee80211_hw *hw,
1723 bool bmain, bool is2t)
1724{
1725 struct rtl_priv *rtlpriv = rtl_priv(hw);
1726 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
1727 struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
1728 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "\n");
1729
1730 if (is_hal_stop(rtlhal)) {
1731 u8 u1btmp;
1732 u1btmp = rtl_read_byte(rtlpriv, REG_LEDCFG0);
1733 rtl_write_byte(rtlpriv, REG_LEDCFG0, u1btmp | BIT(7));
1734 rtl_set_bbreg(hw, RFPGA0_XAB_RFPARAMETER, BIT(13), 0x01);
1735 }
1736 if (is2t) {
1737 if (bmain)
1738 rtl_set_bbreg(hw, RFPGA0_XB_RFINTERFACEOE,
1739 BIT(5) | BIT(6), 0x1);
1740 else
1741 rtl_set_bbreg(hw, RFPGA0_XB_RFINTERFACEOE,
1742 BIT(5) | BIT(6), 0x2);
1743 } else {
1744 rtl_set_bbreg(hw, RFPGA0_XAB_RFINTERFACESW, BIT(8) | BIT(9), 0);
1745 rtl_set_bbreg(hw, 0x914, MASKLWORD, 0x0201);
1746
1747 /* We use the RF definition of MAIN and AUX,
1748 * left antenna and right antenna repectively.
1749 * Default output at AUX.
1750 */
1751 if (bmain) {
1752 rtl_set_bbreg(hw, RFPGA0_XA_RFINTERFACEOE,
1753 BIT(14) | BIT(13) | BIT(12), 0);
1754 rtl_set_bbreg(hw, RFPGA0_XB_RFINTERFACEOE,
1755 BIT(5) | BIT(4) | BIT(3), 0);
1756 if (rtlefuse->antenna_div_type == CGCS_RX_HW_ANTDIV)
1757 rtl_set_bbreg(hw, CONFIG_RAM64X16, BIT(31), 0);
1758 } else {
1759 rtl_set_bbreg(hw, RFPGA0_XA_RFINTERFACEOE,
1760 BIT(14) | BIT(13) | BIT(12), 1);
1761 rtl_set_bbreg(hw, RFPGA0_XB_RFINTERFACEOE,
1762 BIT(5) | BIT(4) | BIT(3), 1);
1763 if (rtlefuse->antenna_div_type == CGCS_RX_HW_ANTDIV)
1764 rtl_set_bbreg(hw, CONFIG_RAM64X16, BIT(31), 1);
1765 }
1766 }
1767}
1768
1769#undef IQK_ADDA_REG_NUM
1770#undef IQK_DELAY_TIME
1771
1772void rtl8723be_phy_iq_calibrate(struct ieee80211_hw *hw, bool recovery)
1773{
1774 struct rtl_priv *rtlpriv = rtl_priv(hw);
1775 struct rtl_phy *rtlphy = &(rtlpriv->phy);
1776 long result[4][8];
1777 u8 i, final_candidate;
1778 bool patha_ok, pathb_ok;
1779 long reg_e94, reg_e9c, reg_ea4, reg_eac, reg_eb4, reg_ebc, reg_ec4,
1780 reg_ecc, reg_tmp = 0;
1781 bool is12simular, is13simular, is23simular;
1782 u32 iqk_bb_reg[9] = {
1783 ROFDM0_XARXIQIMBALANCE,
1784 ROFDM0_XBRXIQIMBALANCE,
1785 ROFDM0_ECCATHRESHOLD,
1786 ROFDM0_AGCRSSITABLE,
1787 ROFDM0_XATXIQIMBALANCE,
1788 ROFDM0_XBTXIQIMBALANCE,
1789 ROFDM0_XCTXAFE,
1790 ROFDM0_XDTXAFE,
1791 ROFDM0_RXIQEXTANTA
1792 };
1793
1794 if (recovery) {
1795 rtl8723_phy_reload_adda_registers(hw, iqk_bb_reg,
1796 rtlphy->iqk_bb_backup, 9);
1797 return;
1798 }
1799
1800 for (i = 0; i < 8; i++) {
1801 result[0][i] = 0;
1802 result[1][i] = 0;
1803 result[2][i] = 0;
1804 result[3][i] = 0;
1805 }
1806 final_candidate = 0xff;
1807 patha_ok = false;
1808 pathb_ok = false;
1809 is12simular = false;
1810 is23simular = false;
1811 is13simular = false;
1812 for (i = 0; i < 3; i++) {
1813 if (get_rf_type(rtlphy) == RF_2T2R)
1814 _rtl8723be_phy_iq_calibrate(hw, result, i, true);
1815 else
1816 _rtl8723be_phy_iq_calibrate(hw, result, i, false);
1817 if (i == 1) {
1818 is12simular = phy_similarity_cmp(hw, result, 0, 1);
1819 if (is12simular) {
1820 final_candidate = 0;
1821 break;
1822 }
1823 }
1824 if (i == 2) {
1825 is13simular = phy_similarity_cmp(hw, result, 0, 2);
1826 if (is13simular) {
1827 final_candidate = 0;
1828 break;
1829 }
1830 is23simular = phy_similarity_cmp(hw, result, 1, 2);
1831 if (is23simular) {
1832 final_candidate = 1;
1833 } else {
1834 for (i = 0; i < 8; i++)
1835 reg_tmp += result[3][i];
1836
1837 if (reg_tmp != 0)
1838 final_candidate = 3;
1839 else
1840 final_candidate = 0xFF;
1841 }
1842 }
1843 }
1844 for (i = 0; i < 4; i++) {
1845 reg_e94 = result[i][0];
1846 reg_e9c = result[i][1];
1847 reg_ea4 = result[i][2];
1848 reg_eac = result[i][3];
1849 reg_eb4 = result[i][4];
1850 reg_ebc = result[i][5];
1851 reg_ec4 = result[i][6];
1852 reg_ecc = result[i][7];
1853 }
1854 if (final_candidate != 0xff) {
1855 reg_e94 = result[final_candidate][0];
1856 rtlphy->reg_e94 = reg_e94;
1857 reg_e9c = result[final_candidate][1];
1858 rtlphy->reg_e9c = reg_e9c;
1859 reg_ea4 = result[final_candidate][2];
1860 reg_eac = result[final_candidate][3];
1861 reg_eb4 = result[final_candidate][4];
1862 rtlphy->reg_eb4 = reg_eb4;
1863 reg_ebc = result[final_candidate][5];
1864 rtlphy->reg_ebc = reg_ebc;
1865 reg_ec4 = result[final_candidate][6];
1866 reg_ecc = result[final_candidate][7];
1867 patha_ok = true;
1868 pathb_ok = true;
1869 } else {
1870 rtlphy->reg_e94 = 0x100;
1871 rtlphy->reg_eb4 = 0x100;
1872 rtlphy->reg_e9c = 0x0;
1873 rtlphy->reg_ebc = 0x0;
1874 }
1875 if (reg_e94 != 0) /*&&(reg_ea4 != 0) */
1876 rtl8723_phy_path_a_fill_iqk_matrix(hw, patha_ok, result,
1877 final_candidate,
1878 (reg_ea4 == 0));
1879 if (final_candidate != 0xFF) {
1880 for (i = 0; i < IQK_MATRIX_REG_NUM; i++)
1881 rtlphy->iqk_matrix[0].value[0][i] =
1882 result[final_candidate][i];
1883 rtlphy->iqk_matrix[0].iqk_done = true;
1884 }
1885 rtl8723_save_adda_registers(hw, iqk_bb_reg, rtlphy->iqk_bb_backup, 9);
1886}
1887
1888void rtl8723be_phy_lc_calibrate(struct ieee80211_hw *hw)
1889{
1890 struct rtl_priv *rtlpriv = rtl_priv(hw);
1891 struct rtl_phy *rtlphy = &(rtlpriv->phy);
1892 struct rtl_hal *rtlhal = &(rtlpriv->rtlhal);
1893 u32 timeout = 2000, timecount = 0;
1894
1895 while (rtlpriv->mac80211.act_scanning && timecount < timeout) {
1896 udelay(50);
1897 timecount += 50;
1898 }
1899
1900 rtlphy->lck_inprogress = true;
1901 RTPRINT(rtlpriv, FINIT, INIT_EEPROM,
1902 "LCK:Start!!! currentband %x delay %d ms\n",
1903 rtlhal->current_bandtype, timecount);
1904
1905 _rtl8723be_phy_lc_calibrate(hw, false);
1906
1907 rtlphy->lck_inprogress = false;
1908}
1909
1910void rtl23b_phy_ap_calibrate(struct ieee80211_hw *hw, char delta)
1911{
1912 struct rtl_priv *rtlpriv = rtl_priv(hw);
1913 struct rtl_phy *rtlphy = &(rtlpriv->phy);
1914
1915 if (rtlphy->apk_done)
1916 return;
1917
1918 return;
1919}
1920
1921void rtl8723be_phy_set_rfpath_switch(struct ieee80211_hw *hw, bool bmain)
1922{
1923 _rtl8723be_phy_set_rfpath_switch(hw, bmain, false);
1924}
1925
1926static void rtl8723be_phy_set_io(struct ieee80211_hw *hw)
1927{
1928 struct rtl_priv *rtlpriv = rtl_priv(hw);
1929 struct rtl_phy *rtlphy = &(rtlpriv->phy);
1930
1931 RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE,
1932 "--->Cmd(%#x), set_io_inprogress(%d)\n",
1933 rtlphy->current_io_type, rtlphy->set_io_inprogress);
1934 switch (rtlphy->current_io_type) {
1935 case IO_CMD_RESUME_DM_BY_SCAN:
1936 rtlpriv->dm_digtable.cur_igvalue =
1937 rtlphy->initgain_backup.xaagccore1;
1938 /*rtl92c_dm_write_dig(hw);*/
1939 rtl8723be_phy_set_txpower_level(hw, rtlphy->current_channel);
1940 rtl_set_bbreg(hw, RCCK0_CCA, 0xff0000, 0x83);
1941 break;
1942 case IO_CMD_PAUSE_DM_BY_SCAN:
1943 rtlphy->initgain_backup.xaagccore1 =
1944 rtlpriv->dm_digtable.cur_igvalue;
1945 rtlpriv->dm_digtable.cur_igvalue = 0x17;
1946 rtl_set_bbreg(hw, RCCK0_CCA, 0xff0000, 0x40);
1947 break;
1948 default:
1949 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
1950 "switch case not process\n");
1951 break;
1952 }
1953 rtlphy->set_io_inprogress = false;
1954 RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE,
1955 "(%#x)\n", rtlphy->current_io_type);
1956}
1957
1958bool rtl8723be_phy_set_io_cmd(struct ieee80211_hw *hw, enum io_type iotype)
1959{
1960 struct rtl_priv *rtlpriv = rtl_priv(hw);
1961 struct rtl_phy *rtlphy = &(rtlpriv->phy);
1962 bool postprocessing = false;
1963
1964 RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE,
1965 "-->IO Cmd(%#x), set_io_inprogress(%d)\n",
1966 iotype, rtlphy->set_io_inprogress);
1967 do {
1968 switch (iotype) {
1969 case IO_CMD_RESUME_DM_BY_SCAN:
1970 RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE,
1971 "[IO CMD] Resume DM after scan.\n");
1972 postprocessing = true;
1973 break;
1974 case IO_CMD_PAUSE_DM_BY_SCAN:
1975 RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE,
1976 "[IO CMD] Pause DM before scan.\n");
1977 postprocessing = true;
1978 break;
1979 default:
1980 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
1981 "switch case not process\n");
1982 break;
1983 }
1984 } while (false);
1985 if (postprocessing && !rtlphy->set_io_inprogress) {
1986 rtlphy->set_io_inprogress = true;
1987 rtlphy->current_io_type = iotype;
1988 } else {
1989 return false;
1990 }
1991 rtl8723be_phy_set_io(hw);
1992 RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE, "IO Type(%#x)\n", iotype);
1993 return true;
1994}
1995
1996static void rtl8723be_phy_set_rf_on(struct ieee80211_hw *hw)
1997{
1998 struct rtl_priv *rtlpriv = rtl_priv(hw);
1999
2000 rtl_write_byte(rtlpriv, REG_SPS0_CTRL, 0x2b);
2001 rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE3);
2002 rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE2);
2003 rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE3);
2004 rtl_write_byte(rtlpriv, REG_TXPAUSE, 0x00);
2005}
2006
2007static void _rtl8723be_phy_set_rf_sleep(struct ieee80211_hw *hw)
2008{
2009 struct rtl_priv *rtlpriv = rtl_priv(hw);
2010
2011 rtl_write_byte(rtlpriv, REG_TXPAUSE, 0xFF);
2012 rtl_set_rfreg(hw, RF90_PATH_A, 0x00, RFREG_OFFSET_MASK, 0x00);
2013 rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE2);
2014 rtl_write_byte(rtlpriv, REG_SPS0_CTRL, 0x22);
2015}
2016
2017static bool _rtl8723be_phy_set_rf_power_state(struct ieee80211_hw *hw,
2018 enum rf_pwrstate rfpwr_state)
2019{
2020 struct rtl_priv *rtlpriv = rtl_priv(hw);
2021 struct rtl_pci_priv *pcipriv = rtl_pcipriv(hw);
2022 struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
2023 struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
2024 bool bresult = true;
2025 u8 i, queue_id;
2026 struct rtl8192_tx_ring *ring = NULL;
2027
2028 switch (rfpwr_state) {
2029 case ERFON:
2030 if ((ppsc->rfpwr_state == ERFOFF) &&
2031 RT_IN_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_HALT_NIC)) {
2032 bool rtstatus;
2033 u32 initialize_count = 0;
2034 do {
2035 initialize_count++;
2036 RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG,
2037 "IPS Set eRf nic enable\n");
2038 rtstatus = rtl_ps_enable_nic(hw);
2039 } while (!rtstatus && (initialize_count < 10));
2040 RT_CLEAR_PS_LEVEL(ppsc,
2041 RT_RF_OFF_LEVL_HALT_NIC);
2042 } else {
2043 RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG,
2044 "Set ERFON sleeped:%d ms\n",
2045 jiffies_to_msecs(jiffies -
2046 ppsc->last_sleep_jiffies));
2047 ppsc->last_awake_jiffies = jiffies;
2048 rtl8723be_phy_set_rf_on(hw);
2049 }
2050 if (mac->link_state == MAC80211_LINKED)
2051 rtlpriv->cfg->ops->led_control(hw, LED_CTL_LINK);
2052 else
2053 rtlpriv->cfg->ops->led_control(hw, LED_CTL_NO_LINK);
2054 break;
2055 case ERFOFF:
2056 for (queue_id = 0, i = 0;
2057 queue_id < RTL_PCI_MAX_TX_QUEUE_COUNT;) {
2058 ring = &pcipriv->dev.tx_ring[queue_id];
2059 if (skb_queue_len(&ring->queue) == 0) {
2060 queue_id++;
2061 continue;
2062 } else {
2063 RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
2064 "eRf Off/Sleep: %d times "
2065 "TcbBusyQueue[%d] =%d before "
2066 "doze!\n", (i + 1), queue_id,
2067 skb_queue_len(&ring->queue));
2068
2069 udelay(10);
2070 i++;
2071 }
2072 if (i >= MAX_DOZE_WAITING_TIMES_9x) {
2073 RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
2074 "\n ERFSLEEP: %d times "
2075 "TcbBusyQueue[%d] = %d !\n",
2076 MAX_DOZE_WAITING_TIMES_9x,
2077 queue_id,
2078 skb_queue_len(&ring->queue));
2079 break;
2080 }
2081 }
2082
2083 if (ppsc->reg_rfps_level & RT_RF_OFF_LEVL_HALT_NIC) {
2084 RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG,
2085 "IPS Set eRf nic disable\n");
2086 rtl_ps_disable_nic(hw);
2087 RT_SET_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_HALT_NIC);
2088 } else {
2089 if (ppsc->rfoff_reason == RF_CHANGE_BY_IPS) {
2090 rtlpriv->cfg->ops->led_control(hw,
2091 LED_CTL_NO_LINK);
2092 } else {
2093 rtlpriv->cfg->ops->led_control(hw,
2094 LED_CTL_POWER_OFF);
2095 }
2096 }
2097 break;
2098 case ERFSLEEP:
2099 if (ppsc->rfpwr_state == ERFOFF)
2100 break;
2101 for (queue_id = 0, i = 0;
2102 queue_id < RTL_PCI_MAX_TX_QUEUE_COUNT;) {
2103 ring = &pcipriv->dev.tx_ring[queue_id];
2104 if (skb_queue_len(&ring->queue) == 0) {
2105 queue_id++;
2106 continue;
2107 } else {
2108 RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
2109 "eRf Off/Sleep: %d times "
2110 "TcbBusyQueue[%d] =%d before "
2111 "doze!\n", (i + 1), queue_id,
2112 skb_queue_len(&ring->queue));
2113
2114 udelay(10);
2115 i++;
2116 }
2117 if (i >= MAX_DOZE_WAITING_TIMES_9x) {
2118 RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
2119 "\n ERFSLEEP: %d times "
2120 "TcbBusyQueue[%d] = %d !\n",
2121 MAX_DOZE_WAITING_TIMES_9x,
2122 queue_id,
2123 skb_queue_len(&ring->queue));
2124 break;
2125 }
2126 }
2127 RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG,
2128 "Set ERFSLEEP awaked:%d ms\n",
2129 jiffies_to_msecs(jiffies -
2130 ppsc->last_awake_jiffies));
2131 ppsc->last_sleep_jiffies = jiffies;
2132 _rtl8723be_phy_set_rf_sleep(hw);
2133 break;
2134 default:
2135 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
2136 "switch case not process\n");
2137 bresult = false;
2138 break;
2139 }
2140 if (bresult)
2141 ppsc->rfpwr_state = rfpwr_state;
2142 return bresult;
2143}
2144
2145bool rtl8723be_phy_set_rf_power_state(struct ieee80211_hw *hw,
2146 enum rf_pwrstate rfpwr_state)
2147{
2148 struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
2149
2150 bool bresult = false;
2151
2152 if (rfpwr_state == ppsc->rfpwr_state)
2153 return bresult;
2154 bresult = _rtl8723be_phy_set_rf_power_state(hw, rfpwr_state);
2155 return bresult;
2156}
This page took 0.133252 seconds and 5 git commands to generate.