1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30#include "../wifi.h"
31#include "../pci.h"
32#include "../ps.h"
33#include "../core.h"
34#include "reg.h"
35#include "def.h"
36#include "phy.h"
37#include "rf.h"
38#include "dm.h"
39#include "table.h"
40#include "../rtl8723com/phy_common.h"
41
42
43static u32 _phy_fw_rf_serial_read(struct ieee80211_hw *hw,
44 enum radio_path rfpath, u32 offset);
45static void _phy_fw_rf_serial_write(struct ieee80211_hw *hw,
46 enum radio_path rfpath,
47 u32 offset, u32 data);
48static bool _phy_bb8192c_config_parafile(struct ieee80211_hw *hw);
49static bool _phy_cfg_mac_w_header(struct ieee80211_hw *hw);
50static bool _phy_cfg_bb_w_header(struct ieee80211_hw *hw, u8 configtype);
51static bool _phy_cfg_bb_w_pgheader(struct ieee80211_hw *hw, u8 configtype);
52static bool _phy_sw_chnl_step_by_step(struct ieee80211_hw *hw, u8 channel,
53 u8 *stage, u8 *step, u32 *delay);
54static u8 _phy_dbm_to_txpwr_Idx(struct ieee80211_hw *hw,
55 enum wireless_mode wirelessmode,
56 long power_indbm);
57static void rtl8723ae_phy_set_io(struct ieee80211_hw *hw);
58
59u32 rtl8723ae_phy_query_rf_reg(struct ieee80211_hw *hw,
60 enum radio_path rfpath, u32 regaddr, u32 bitmask)
61{
62 struct rtl_priv *rtlpriv = rtl_priv(hw);
63 u32 original_value, readback_value, bitshift;
64 struct rtl_phy *rtlphy = &(rtlpriv->phy);
65 unsigned long flags;
66
67 RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE,
68 "regaddr(%#x), rfpath(%#x), bitmask(%#x)\n",
69 regaddr, rfpath, bitmask);
70
71 spin_lock_irqsave(&rtlpriv->locks.rf_lock, flags);
72
73 if (rtlphy->rf_mode != RF_OP_BY_FW)
74 original_value = rtl8723_phy_rf_serial_read(hw, rfpath, regaddr);
75 else
76 original_value = _phy_fw_rf_serial_read(hw, rfpath, regaddr);
77
78 bitshift = rtl8723_phy_calculate_bit_shift(bitmask);
79 readback_value = (original_value & bitmask) >> bitshift;
80
81 spin_unlock_irqrestore(&rtlpriv->locks.rf_lock, flags);
82
83 RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE,
84 "regaddr(%#x), rfpath(%#x), bitmask(%#x), original_value(%#x)\n",
85 regaddr, rfpath, bitmask, original_value);
86
87 return readback_value;
88}
89
90void rtl8723ae_phy_set_rf_reg(struct ieee80211_hw *hw,
91 enum radio_path rfpath,
92 u32 regaddr, u32 bitmask, u32 data)
93{
94 struct rtl_priv *rtlpriv = rtl_priv(hw);
95 struct rtl_phy *rtlphy = &(rtlpriv->phy);
96 u32 original_value, bitshift;
97 unsigned long flags;
98
99 RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE,
100 "regaddr(%#x), bitmask(%#x), data(%#x), rfpath(%#x)\n",
101 regaddr, bitmask, data, rfpath);
102
103 spin_lock_irqsave(&rtlpriv->locks.rf_lock, flags);
104
105 if (rtlphy->rf_mode != RF_OP_BY_FW) {
106 if (bitmask != RFREG_OFFSET_MASK) {
107 original_value = rtl8723_phy_rf_serial_read(hw, rfpath,
108 regaddr);
109 bitshift = rtl8723_phy_calculate_bit_shift(bitmask);
110 data = ((original_value & (~bitmask)) |
111 (data << bitshift));
112 }
113
114 rtl8723_phy_rf_serial_write(hw, rfpath, regaddr, data);
115 } else {
116 if (bitmask != RFREG_OFFSET_MASK) {
117 original_value = _phy_fw_rf_serial_read(hw, rfpath,
118 regaddr);
119 bitshift = rtl8723_phy_calculate_bit_shift(bitmask);
120 data = ((original_value & (~bitmask)) |
121 (data << bitshift));
122 }
123 _phy_fw_rf_serial_write(hw, rfpath, regaddr, data);
124 }
125
126 spin_unlock_irqrestore(&rtlpriv->locks.rf_lock, flags);
127
128 RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE,
129 "regaddr(%#x), bitmask(%#x), data(%#x), rfpath(%#x)\n",
130 regaddr, bitmask, data, rfpath);
131}
132
133static u32 _phy_fw_rf_serial_read(struct ieee80211_hw *hw,
134 enum radio_path rfpath, u32 offset)
135{
136 RT_ASSERT(false, "deprecated!\n");
137 return 0;
138}
139
140static void _phy_fw_rf_serial_write(struct ieee80211_hw *hw,
141 enum radio_path rfpath,
142 u32 offset, u32 data)
143{
144 RT_ASSERT(false, "deprecated!\n");
145}
146
147static void _rtl8723ae_phy_bb_config_1t(struct ieee80211_hw *hw)
148{
149 rtl_set_bbreg(hw, RFPGA0_TXINFO, 0x3, 0x2);
150 rtl_set_bbreg(hw, RFPGA1_TXINFO, 0x300033, 0x200022);
151 rtl_set_bbreg(hw, RCCK0_AFESETTING, MASKBYTE3, 0x45);
152 rtl_set_bbreg(hw, ROFDM0_TRXPATHENABLE, MASKBYTE0, 0x23);
153 rtl_set_bbreg(hw, ROFDM0_AGCPARAMETER1, 0x30, 0x1);
154 rtl_set_bbreg(hw, 0xe74, 0x0c000000, 0x2);
155 rtl_set_bbreg(hw, 0xe78, 0x0c000000, 0x2);
156 rtl_set_bbreg(hw, 0xe7c, 0x0c000000, 0x2);
157 rtl_set_bbreg(hw, 0xe80, 0x0c000000, 0x2);
158 rtl_set_bbreg(hw, 0xe88, 0x0c000000, 0x2);
159}
160
161bool rtl8723ae_phy_mac_config(struct ieee80211_hw *hw)
162{
163 struct rtl_priv *rtlpriv = rtl_priv(hw);
164 bool rtstatus = _phy_cfg_mac_w_header(hw);
165 rtl_write_byte(rtlpriv, 0x04CA, 0x0A);
166 return rtstatus;
167}
168
169bool rtl8723ae_phy_bb_config(struct ieee80211_hw *hw)
170{
171 bool rtstatus = true;
172 struct rtl_priv *rtlpriv = rtl_priv(hw);
173 u8 tmpu1b;
174 u8 reg_hwparafile = 1;
175
176 rtl8723_phy_init_bb_rf_reg_def(hw);
177
178
179 tmpu1b = rtl_read_byte(rtlpriv, REG_AFE_PLL_CTRL);
180 udelay(2);
181 rtl_write_byte(rtlpriv, REG_AFE_PLL_CTRL, (tmpu1b|BIT(1)));
182 udelay(2);
183
184 rtl_write_byte(rtlpriv, REG_AFE_PLL_CTRL+1, 0xff);
185 udelay(2);
186
187
188 tmpu1b = rtl_read_byte(rtlpriv, REG_SYS_FUNC_EN);
189 rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, (tmpu1b |
190 FEN_BB_GLB_RSTn | FEN_BBRSTB));
191
192
193 tmpu1b = rtl_read_byte(rtlpriv, REG_AFE_XTAL_CTRL+1);
194 rtl_write_byte(rtlpriv, REG_AFE_XTAL_CTRL+1, (tmpu1b&(~BIT(6))));
195
196
197 tmpu1b = rtl_read_byte(rtlpriv, REG_AFE_XTAL_CTRL+2);
198 rtl_write_byte(rtlpriv, REG_AFE_XTAL_CTRL+2, (tmpu1b&(~BIT(4))));
199
200
201 rtl_write_byte(rtlpriv, REG_RF_CTRL, 0x07);
202
203 if (reg_hwparafile == 1)
204 rtstatus = _phy_bb8192c_config_parafile(hw);
205 return rtstatus;
206}
207
208bool rtl8723ae_phy_rf_config(struct ieee80211_hw *hw)
209{
210 return rtl8723ae_phy_rf6052_config(hw);
211}
212
213static bool _phy_bb8192c_config_parafile(struct ieee80211_hw *hw)
214{
215 struct rtl_priv *rtlpriv = rtl_priv(hw);
216 struct rtl_phy *rtlphy = &(rtlpriv->phy);
217 struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
218 bool rtstatus;
219
220 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, "==>\n");
221 rtstatus = _phy_cfg_bb_w_header(hw, BASEBAND_CONFIG_PHY_REG);
222 if (rtstatus != true) {
223 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, "Write BB Reg Fail!!");
224 return false;
225 }
226
227 if (rtlphy->rf_type == RF_1T2R) {
228 _rtl8723ae_phy_bb_config_1t(hw);
229 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, "Config to 1T!!\n");
230 }
231 if (rtlefuse->autoload_failflag == false) {
232 rtlphy->pwrgroup_cnt = 0;
233 rtstatus = _phy_cfg_bb_w_pgheader(hw, BASEBAND_CONFIG_PHY_REG);
234 }
235 if (rtstatus != true) {
236 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, "BB_PG Reg Fail!!");
237 return false;
238 }
239 rtstatus = _phy_cfg_bb_w_header(hw, BASEBAND_CONFIG_AGC_TAB);
240 if (rtstatus != true) {
241 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, "AGC Table Fail\n");
242 return false;
243 }
244 rtlphy->cck_high_power = (bool) (rtl_get_bbreg(hw,
245 RFPGA0_XA_HSSIPARAMETER2, 0x200));
246 return true;
247}
248
249static bool _phy_cfg_mac_w_header(struct ieee80211_hw *hw)
250{
251 struct rtl_priv *rtlpriv = rtl_priv(hw);
252 u32 i;
253 u32 arraylength;
254 u32 *ptrarray;
255
256 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, "Read Rtl723MACPHY_Array\n");
257 arraylength = RTL8723E_MACARRAYLENGTH;
258 ptrarray = RTL8723EMAC_ARRAY;
259
260 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
261 "Img:RTL8192CEMAC_2T_ARRAY\n");
262 for (i = 0; i < arraylength; i = i + 2)
263 rtl_write_byte(rtlpriv, ptrarray[i], (u8) ptrarray[i + 1]);
264 return true;
265}
266
267static bool _phy_cfg_bb_w_header(struct ieee80211_hw *hw, u8 configtype)
268{
269 int i;
270 u32 *phy_regarray_table;
271 u32 *agctab_array_table;
272 u16 phy_reg_arraylen, agctab_arraylen;
273 struct rtl_priv *rtlpriv = rtl_priv(hw);
274
275 agctab_arraylen = RTL8723E_AGCTAB_1TARRAYLENGTH;
276 agctab_array_table = RTL8723EAGCTAB_1TARRAY;
277 phy_reg_arraylen = RTL8723E_PHY_REG_1TARRAY_LENGTH;
278 phy_regarray_table = RTL8723EPHY_REG_1TARRAY;
279 if (configtype == BASEBAND_CONFIG_PHY_REG) {
280 for (i = 0; i < phy_reg_arraylen; i = i + 2) {
281 rtl_addr_delay(phy_regarray_table[i]);
282 rtl_set_bbreg(hw, phy_regarray_table[i], MASKDWORD,
283 phy_regarray_table[i + 1]);
284 udelay(1);
285 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
286 "The phy_regarray_table[0] is %x"
287 " Rtl819XPHY_REGArray[1] is %x\n",
288 phy_regarray_table[i],
289 phy_regarray_table[i + 1]);
290 }
291 } else if (configtype == BASEBAND_CONFIG_AGC_TAB) {
292 for (i = 0; i < agctab_arraylen; i = i + 2) {
293 rtl_set_bbreg(hw, agctab_array_table[i], MASKDWORD,
294 agctab_array_table[i + 1]);
295 udelay(1);
296 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
297 "The agctab_array_table[0] is "
298 "%x Rtl819XPHY_REGArray[1] is %x\n",
299 agctab_array_table[i],
300 agctab_array_table[i + 1]);
301 }
302 }
303 return true;
304}
305
306static void _st_pwrIdx_dfrate_off(struct ieee80211_hw *hw, u32 regaddr,
307 u32 bitmask, u32 data)
308{
309 struct rtl_priv *rtlpriv = rtl_priv(hw);
310 struct rtl_phy *rtlphy = &(rtlpriv->phy);
311
312 switch (regaddr) {
313 case RTXAGC_A_RATE18_06:
314 rtlphy->mcs_offset[rtlphy->pwrgroup_cnt][0] = data;
315 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
316 "MCSTxPowerLevelOriginalOffset[%d][0] = 0x%x\n",
317 rtlphy->pwrgroup_cnt,
318 rtlphy->mcs_offset[rtlphy->pwrgroup_cnt][0]);
319 break;
320 case RTXAGC_A_RATE54_24:
321 rtlphy->mcs_offset[rtlphy->pwrgroup_cnt][1] = data;
322 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
323 "MCSTxPowerLevelOriginalOffset[%d][1] = 0x%x\n",
324 rtlphy->pwrgroup_cnt,
325 rtlphy->mcs_offset[rtlphy->pwrgroup_cnt][1]);
326 break;
327 case RTXAGC_A_CCK1_MCS32:
328 rtlphy->mcs_offset[rtlphy->pwrgroup_cnt][6] = data;
329 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
330 "MCSTxPowerLevelOriginalOffset[%d][6] = 0x%x\n",
331 rtlphy->pwrgroup_cnt,
332 rtlphy->mcs_offset[rtlphy->pwrgroup_cnt][6]);
333 break;
334 case RTXAGC_B_CCK11_A_CCK2_11:
335 if (bitmask == 0xffffff00) {
336 rtlphy->mcs_offset[rtlphy->pwrgroup_cnt][7] = data;
337 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
338 "MCSTxPowerLevelOriginalOffset[%d][7] = 0x%x\n",
339 rtlphy->pwrgroup_cnt,
340 rtlphy->mcs_offset[rtlphy->pwrgroup_cnt][7]);
341 }
342 if (bitmask == 0x000000ff) {
343 rtlphy->mcs_offset[rtlphy->pwrgroup_cnt][15] = data;
344 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
345 "MCSTxPowerLevelOriginalOffset[%d][15] = 0x%x\n",
346 rtlphy->pwrgroup_cnt,
347 rtlphy->mcs_offset[rtlphy->pwrgroup_cnt][15]);
348 }
349 break;
350 case RTXAGC_A_MCS03_MCS00:
351 rtlphy->mcs_offset[rtlphy->pwrgroup_cnt][2] = data;
352 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
353 "MCSTxPowerLevelOriginalOffset[%d][2] = 0x%x\n",
354 rtlphy->pwrgroup_cnt,
355 rtlphy->mcs_offset[rtlphy->pwrgroup_cnt][2]);
356 break;
357 case RTXAGC_A_MCS07_MCS04:
358 rtlphy->mcs_offset[rtlphy->pwrgroup_cnt][3] = data;
359 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
360 "MCSTxPowerLevelOriginalOffset[%d][3] = 0x%x\n",
361 rtlphy->pwrgroup_cnt,
362 rtlphy->mcs_offset[rtlphy->pwrgroup_cnt][3]);
363 break;
364 case RTXAGC_A_MCS11_MCS08:
365 rtlphy->mcs_offset[rtlphy->pwrgroup_cnt][4] = data;
366 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
367 "MCSTxPowerLevelOriginalOffset[%d][4] = 0x%x\n",
368 rtlphy->pwrgroup_cnt,
369 rtlphy->mcs_offset[rtlphy->pwrgroup_cnt][4]);
370 break;
371 case RTXAGC_A_MCS15_MCS12:
372 rtlphy->mcs_offset[rtlphy->pwrgroup_cnt][5] = data;
373 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
374 "MCSTxPowerLevelOriginalOffset[%d][5] = 0x%x\n",
375 rtlphy->pwrgroup_cnt,
376 rtlphy->mcs_offset[rtlphy->pwrgroup_cnt][5]);
377 break;
378 case RTXAGC_B_RATE18_06:
379 rtlphy->mcs_offset[rtlphy->pwrgroup_cnt][8] = data;
380 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
381 "MCSTxPowerLevelOriginalOffset[%d][8] = 0x%x\n",
382 rtlphy->pwrgroup_cnt,
383 rtlphy->mcs_offset[rtlphy->pwrgroup_cnt][8]);
384 break;
385 case RTXAGC_B_RATE54_24:
386 rtlphy->mcs_offset[rtlphy->pwrgroup_cnt][9] = data;
387 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
388 "MCSTxPowerLevelOriginalOffset[%d][9] = 0x%x\n",
389 rtlphy->pwrgroup_cnt,
390 rtlphy->mcs_offset[rtlphy->pwrgroup_cnt][9]);
391 break;
392 case RTXAGC_B_CCK1_55_MCS32:
393 rtlphy->mcs_offset[rtlphy->pwrgroup_cnt][14] = data;
394 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
395 "MCSTxPowerLevelOriginalOffset[%d][14] = 0x%x\n",
396 rtlphy->pwrgroup_cnt,
397 rtlphy->mcs_offset[rtlphy->pwrgroup_cnt][14]);
398 break;
399 case RTXAGC_B_MCS03_MCS00:
400 rtlphy->mcs_offset[rtlphy->pwrgroup_cnt][10] = data;
401 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
402 "MCSTxPowerLevelOriginalOffset[%d][10] = 0x%x\n",
403 rtlphy->pwrgroup_cnt,
404 rtlphy->mcs_offset[rtlphy->pwrgroup_cnt][10]);
405 break;
406 case RTXAGC_B_MCS07_MCS04:
407 rtlphy->mcs_offset[rtlphy->pwrgroup_cnt][11] = data;
408 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
409 "MCSTxPowerLevelOriginalOffset[%d][11] = 0x%x\n",
410 rtlphy->pwrgroup_cnt,
411 rtlphy->mcs_offset[rtlphy->pwrgroup_cnt][11]);
412 break;
413 case RTXAGC_B_MCS11_MCS08:
414 rtlphy->mcs_offset[rtlphy->pwrgroup_cnt][12] = data;
415 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
416 "MCSTxPowerLevelOriginalOffset[%d][12] = 0x%x\n",
417 rtlphy->pwrgroup_cnt,
418 rtlphy->mcs_offset[rtlphy->pwrgroup_cnt][12]);
419 break;
420 case RTXAGC_B_MCS15_MCS12:
421 rtlphy->mcs_offset[rtlphy->pwrgroup_cnt][13] = data;
422 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
423 "MCSTxPowerLevelOriginalOffset[%d][13] = 0x%x\n",
424 rtlphy->pwrgroup_cnt,
425 rtlphy->mcs_offset[rtlphy->pwrgroup_cnt][13]);
426 rtlphy->pwrgroup_cnt++;
427 break;
428 }
429}
430
431static bool _phy_cfg_bb_w_pgheader(struct ieee80211_hw *hw, u8 configtype)
432{
433 struct rtl_priv *rtlpriv = rtl_priv(hw);
434 int i;
435 u32 *phy_regarray_table_pg;
436 u16 phy_regarray_pg_len;
437
438 phy_regarray_pg_len = RTL8723E_PHY_REG_ARRAY_PGLENGTH;
439 phy_regarray_table_pg = RTL8723EPHY_REG_ARRAY_PG;
440
441 if (configtype == BASEBAND_CONFIG_PHY_REG) {
442 for (i = 0; i < phy_regarray_pg_len; i = i + 3) {
443 rtl_addr_delay(phy_regarray_table_pg[i]);
444
445 _st_pwrIdx_dfrate_off(hw, phy_regarray_table_pg[i],
446 phy_regarray_table_pg[i + 1],
447 phy_regarray_table_pg[i + 2]);
448 }
449 } else {
450 RT_TRACE(rtlpriv, COMP_SEND, DBG_TRACE,
451 "configtype != BaseBand_Config_PHY_REG\n");
452 }
453 return true;
454}
455
456bool rtl8723ae_phy_config_rf_with_headerfile(struct ieee80211_hw *hw,
457 enum radio_path rfpath)
458{
459 struct rtl_priv *rtlpriv = rtl_priv(hw);
460 int i;
461 u32 *radioa_array_table;
462 u16 radioa_arraylen;
463
464 radioa_arraylen = Rtl8723ERADIOA_1TARRAYLENGTH;
465 radioa_array_table = RTL8723E_RADIOA_1TARRAY;
466
467 switch (rfpath) {
468 case RF90_PATH_A:
469 for (i = 0; i < radioa_arraylen; i = i + 2) {
470 rtl_rfreg_delay(hw, rfpath, radioa_array_table[i],
471 RFREG_OFFSET_MASK,
472 radioa_array_table[i + 1]);
473 }
474 break;
475 case RF90_PATH_B:
476 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
477 "switch case not process\n");
478 break;
479 case RF90_PATH_C:
480 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
481 "switch case not process\n");
482 break;
483 case RF90_PATH_D:
484 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
485 "switch case not process\n");
486 break;
487 }
488 return true;
489}
490
491void rtl8723ae_phy_get_hw_reg_originalvalue(struct ieee80211_hw *hw)
492{
493 struct rtl_priv *rtlpriv = rtl_priv(hw);
494 struct rtl_phy *rtlphy = &(rtlpriv->phy);
495
496 rtlphy->default_initialgain[0] =
497 (u8) rtl_get_bbreg(hw, ROFDM0_XAAGCCORE1, MASKBYTE0);
498 rtlphy->default_initialgain[1] =
499 (u8) rtl_get_bbreg(hw, ROFDM0_XBAGCCORE1, MASKBYTE0);
500 rtlphy->default_initialgain[2] =
501 (u8) rtl_get_bbreg(hw, ROFDM0_XCAGCCORE1, MASKBYTE0);
502 rtlphy->default_initialgain[3] =
503 (u8) rtl_get_bbreg(hw, ROFDM0_XDAGCCORE1, MASKBYTE0);
504
505 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
506 "Default initial gain (c50=0x%x, c58=0x%x, c60=0x%x, c68=0x%x\n",
507 rtlphy->default_initialgain[0],
508 rtlphy->default_initialgain[1],
509 rtlphy->default_initialgain[2],
510 rtlphy->default_initialgain[3]);
511
512 rtlphy->framesync = (u8) rtl_get_bbreg(hw,
513 ROFDM0_RXDETECTOR3, MASKBYTE0);
514 rtlphy->framesync_c34 = rtl_get_bbreg(hw,
515 ROFDM0_RXDETECTOR2, MASKDWORD);
516
517 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
518 "Default framesync (0x%x) = 0x%x\n",
519 ROFDM0_RXDETECTOR3, rtlphy->framesync);
520}
521
522void rtl8723ae_phy_get_txpower_level(struct ieee80211_hw *hw, long *powerlevel)
523{
524 struct rtl_priv *rtlpriv = rtl_priv(hw);
525 struct rtl_phy *rtlphy = &(rtlpriv->phy);
526 struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
527 u8 txpwr_level;
528 long txpwr_dbm;
529
530 txpwr_level = rtlphy->cur_cck_txpwridx;
531 txpwr_dbm = rtl8723_phy_txpwr_idx_to_dbm(hw, WIRELESS_MODE_B, txpwr_level);
532 txpwr_level = rtlphy->cur_ofdm24g_txpwridx +
533 rtlefuse->legacy_ht_txpowerdiff;
534 if (rtl8723_phy_txpwr_idx_to_dbm(hw, WIRELESS_MODE_G, txpwr_level) > txpwr_dbm)
535 txpwr_dbm = rtl8723_phy_txpwr_idx_to_dbm(hw, WIRELESS_MODE_G,
536 txpwr_level);
537 txpwr_level = rtlphy->cur_ofdm24g_txpwridx;
538 if (rtl8723_phy_txpwr_idx_to_dbm(hw, WIRELESS_MODE_N_24G, txpwr_level) >
539 txpwr_dbm)
540 txpwr_dbm = rtl8723_phy_txpwr_idx_to_dbm(hw, WIRELESS_MODE_N_24G,
541 txpwr_level);
542 *powerlevel = txpwr_dbm;
543}
544
545static void _rtl8723ae_get_txpower_index(struct ieee80211_hw *hw, u8 channel,
546 u8 *cckpowerlevel, u8 *ofdmpowerlevel)
547{
548 struct rtl_priv *rtlpriv = rtl_priv(hw);
549 struct rtl_phy *rtlphy = &(rtlpriv->phy);
550 struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
551 u8 index = (channel - 1);
552
553 cckpowerlevel[RF90_PATH_A] =
554 rtlefuse->txpwrlevel_cck[RF90_PATH_A][index];
555 cckpowerlevel[RF90_PATH_B] =
556 rtlefuse->txpwrlevel_cck[RF90_PATH_B][index];
557 if (get_rf_type(rtlphy) == RF_1T2R || get_rf_type(rtlphy) == RF_1T1R) {
558 ofdmpowerlevel[RF90_PATH_A] =
559 rtlefuse->txpwrlevel_ht40_1s[RF90_PATH_A][index];
560 ofdmpowerlevel[RF90_PATH_B] =
561 rtlefuse->txpwrlevel_ht40_1s[RF90_PATH_B][index];
562 } else if (get_rf_type(rtlphy) == RF_2T2R) {
563 ofdmpowerlevel[RF90_PATH_A] =
564 rtlefuse->txpwrlevel_ht40_2s[RF90_PATH_A][index];
565 ofdmpowerlevel[RF90_PATH_B] =
566 rtlefuse->txpwrlevel_ht40_2s[RF90_PATH_B][index];
567 }
568}
569
570static void _rtl8723ae_ccxpower_index_check(struct ieee80211_hw *hw,
571 u8 channel, u8 *cckpowerlevel,
572 u8 *ofdmpowerlevel)
573{
574 struct rtl_priv *rtlpriv = rtl_priv(hw);
575 struct rtl_phy *rtlphy = &(rtlpriv->phy);
576
577 rtlphy->cur_cck_txpwridx = cckpowerlevel[0];
578 rtlphy->cur_ofdm24g_txpwridx = ofdmpowerlevel[0];
579}
580
581void rtl8723ae_phy_set_txpower_level(struct ieee80211_hw *hw, u8 channel)
582{
583 struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
584 u8 cckpowerlevel[2], ofdmpowerlevel[2];
585
586 if (rtlefuse->txpwr_fromeprom == false)
587 return;
588 _rtl8723ae_get_txpower_index(hw, channel, &cckpowerlevel[0],
589 &ofdmpowerlevel[0]);
590 _rtl8723ae_ccxpower_index_check(hw, channel, &cckpowerlevel[0],
591 &ofdmpowerlevel[0]);
592 rtl8723ae_phy_rf6052_set_cck_txpower(hw, &cckpowerlevel[0]);
593 rtl8723ae_phy_rf6052_set_ofdm_txpower(hw, &ofdmpowerlevel[0], channel);
594}
595
596bool rtl8723ae_phy_update_txpower_dbm(struct ieee80211_hw *hw, long power_indbm)
597{
598 struct rtl_priv *rtlpriv = rtl_priv(hw);
599 struct rtl_phy *rtlphy = &(rtlpriv->phy);
600 struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
601 u8 idx;
602 u8 rf_path;
603 u8 ccktxpwridx = _phy_dbm_to_txpwr_Idx(hw, WIRELESS_MODE_B,
604 power_indbm);
605 u8 ofdmtxpwridx = _phy_dbm_to_txpwr_Idx(hw, WIRELESS_MODE_N_24G,
606 power_indbm);
607 if (ofdmtxpwridx - rtlefuse->legacy_ht_txpowerdiff > 0)
608 ofdmtxpwridx -= rtlefuse->legacy_ht_txpowerdiff;
609 else
610 ofdmtxpwridx = 0;
611 RT_TRACE(rtlpriv, COMP_TXAGC, DBG_TRACE,
612 "%lx dBm, ccktxpwridx = %d, ofdmtxpwridx = %d\n",
613 power_indbm, ccktxpwridx, ofdmtxpwridx);
614 for (idx = 0; idx < 14; idx++) {
615 for (rf_path = 0; rf_path < 2; rf_path++) {
616 rtlefuse->txpwrlevel_cck[rf_path][idx] = ccktxpwridx;
617 rtlefuse->txpwrlevel_ht40_1s[rf_path][idx] =
618 ofdmtxpwridx;
619 rtlefuse->txpwrlevel_ht40_2s[rf_path][idx] =
620 ofdmtxpwridx;
621 }
622 }
623 rtl8723ae_phy_set_txpower_level(hw, rtlphy->current_channel);
624 return true;
625}
626
627static u8 _phy_dbm_to_txpwr_Idx(struct ieee80211_hw *hw,
628 enum wireless_mode wirelessmode,
629 long power_indbm)
630{
631 u8 txpwridx;
632 long offset;
633
634 switch (wirelessmode) {
635 case WIRELESS_MODE_B:
636 offset = -7;
637 break;
638 case WIRELESS_MODE_G:
639 case WIRELESS_MODE_N_24G:
640 offset = -8;
641 break;
642 default:
643 offset = -8;
644 break;
645 }
646
647 if ((power_indbm - offset) > 0)
648 txpwridx = (u8) ((power_indbm - offset) * 2);
649 else
650 txpwridx = 0;
651
652 if (txpwridx > MAX_TXPWR_IDX_NMODE_92S)
653 txpwridx = MAX_TXPWR_IDX_NMODE_92S;
654
655 return txpwridx;
656}
657
658void rtl8723ae_phy_set_bw_mode_callback(struct ieee80211_hw *hw)
659{
660 struct rtl_priv *rtlpriv = rtl_priv(hw);
661 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
662 struct rtl_phy *rtlphy = &(rtlpriv->phy);
663 struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
664 u8 reg_bw_opmode;
665 u8 reg_prsr_rsc;
666
667 RT_TRACE(rtlpriv, COMP_SCAN, DBG_TRACE,
668 "Switch to %s bandwidth\n",
669 rtlphy->current_chan_bw == HT_CHANNEL_WIDTH_20 ?
670 "20MHz" : "40MHz");
671
672 if (is_hal_stop(rtlhal)) {
673 rtlphy->set_bwmode_inprogress = false;
674 return;
675 }
676
677 reg_bw_opmode = rtl_read_byte(rtlpriv, REG_BWOPMODE);
678 reg_prsr_rsc = rtl_read_byte(rtlpriv, REG_RRSR + 2);
679
680 switch (rtlphy->current_chan_bw) {
681 case HT_CHANNEL_WIDTH_20:
682 reg_bw_opmode |= BW_OPMODE_20MHZ;
683 rtl_write_byte(rtlpriv, REG_BWOPMODE, reg_bw_opmode);
684 break;
685 case HT_CHANNEL_WIDTH_20_40:
686 reg_bw_opmode &= ~BW_OPMODE_20MHZ;
687 rtl_write_byte(rtlpriv, REG_BWOPMODE, reg_bw_opmode);
688 reg_prsr_rsc =
689 (reg_prsr_rsc & 0x90) | (mac->cur_40_prime_sc << 5);
690 rtl_write_byte(rtlpriv, REG_RRSR + 2, reg_prsr_rsc);
691 break;
692 default:
693 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
694 "unknown bandwidth: %#X\n", rtlphy->current_chan_bw);
695 break;
696 }
697
698 switch (rtlphy->current_chan_bw) {
699 case HT_CHANNEL_WIDTH_20:
700 rtl_set_bbreg(hw, RFPGA0_RFMOD, BRFMOD, 0x0);
701 rtl_set_bbreg(hw, RFPGA1_RFMOD, BRFMOD, 0x0);
702 rtl_set_bbreg(hw, RFPGA0_ANALOGPARAMETER2, BIT(10), 1);
703 break;
704 case HT_CHANNEL_WIDTH_20_40:
705 rtl_set_bbreg(hw, RFPGA0_RFMOD, BRFMOD, 0x1);
706 rtl_set_bbreg(hw, RFPGA1_RFMOD, BRFMOD, 0x1);
707
708 rtl_set_bbreg(hw, RCCK0_SYSTEM, BCCK_SIDEBAND,
709 (mac->cur_40_prime_sc >> 1));
710 rtl_set_bbreg(hw, ROFDM1_LSTF, 0xC00, mac->cur_40_prime_sc);
711 rtl_set_bbreg(hw, RFPGA0_ANALOGPARAMETER2, BIT(10), 0);
712
713 rtl_set_bbreg(hw, 0x818, (BIT(26) | BIT(27)),
714 (mac->cur_40_prime_sc ==
715 HAL_PRIME_CHNL_OFFSET_LOWER) ? 2 : 1);
716 break;
717 default:
718 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
719 "unknown bandwidth: %#X\n", rtlphy->current_chan_bw);
720 break;
721 }
722 rtl8723ae_phy_rf6052_set_bandwidth(hw, rtlphy->current_chan_bw);
723 rtlphy->set_bwmode_inprogress = false;
724 RT_TRACE(rtlpriv, COMP_SCAN, DBG_TRACE, "<==\n");
725}
726
727void rtl8723ae_phy_set_bw_mode(struct ieee80211_hw *hw,
728 enum nl80211_channel_type ch_type)
729{
730 struct rtl_priv *rtlpriv = rtl_priv(hw);
731 struct rtl_phy *rtlphy = &(rtlpriv->phy);
732 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
733 u8 tmp_bw = rtlphy->current_chan_bw;
734
735 if (rtlphy->set_bwmode_inprogress)
736 return;
737 rtlphy->set_bwmode_inprogress = true;
738 if ((!is_hal_stop(rtlhal)) && !(RT_CANNOT_IO(hw))) {
739 rtl8723ae_phy_set_bw_mode_callback(hw);
740 } else {
741 RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
742 "FALSE driver sleep or unload\n");
743 rtlphy->set_bwmode_inprogress = false;
744 rtlphy->current_chan_bw = tmp_bw;
745 }
746}
747
748void rtl8723ae_phy_sw_chnl_callback(struct ieee80211_hw *hw)
749{
750 struct rtl_priv *rtlpriv = rtl_priv(hw);
751 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
752 struct rtl_phy *rtlphy = &(rtlpriv->phy);
753 u32 delay;
754
755 RT_TRACE(rtlpriv, COMP_SCAN, DBG_TRACE,
756 "switch to channel%d\n", rtlphy->current_channel);
757 if (is_hal_stop(rtlhal))
758 return;
759 do {
760 if (!rtlphy->sw_chnl_inprogress)
761 break;
762 if (!_phy_sw_chnl_step_by_step
763 (hw, rtlphy->current_channel, &rtlphy->sw_chnl_stage,
764 &rtlphy->sw_chnl_step, &delay)) {
765 if (delay > 0)
766 mdelay(delay);
767 else
768 continue;
769 } else {
770 rtlphy->sw_chnl_inprogress = false;
771 }
772 break;
773 } while (true);
774 RT_TRACE(rtlpriv, COMP_SCAN, DBG_TRACE, "<==\n");
775}
776
777u8 rtl8723ae_phy_sw_chnl(struct ieee80211_hw *hw)
778{
779 struct rtl_priv *rtlpriv = rtl_priv(hw);
780 struct rtl_phy *rtlphy = &(rtlpriv->phy);
781 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
782
783 if (rtlphy->sw_chnl_inprogress)
784 return 0;
785 if (rtlphy->set_bwmode_inprogress)
786 return 0;
787 RT_ASSERT((rtlphy->current_channel <= 14),
788 "WIRELESS_MODE_G but channel>14");
789 rtlphy->sw_chnl_inprogress = true;
790 rtlphy->sw_chnl_stage = 0;
791 rtlphy->sw_chnl_step = 0;
792 if (!(is_hal_stop(rtlhal)) && !(RT_CANNOT_IO(hw))) {
793 rtl8723ae_phy_sw_chnl_callback(hw);
794 RT_TRACE(rtlpriv, COMP_CHAN, DBG_LOUD,
795 "sw_chnl_inprogress false schedule workitem\n");
796 rtlphy->sw_chnl_inprogress = false;
797 } else {
798 RT_TRACE(rtlpriv, COMP_CHAN, DBG_LOUD,
799 "sw_chnl_inprogress false driver sleep or unload\n");
800 rtlphy->sw_chnl_inprogress = false;
801 }
802 return 1;
803}
804
805static void _rtl8723ae_phy_sw_rf_seting(struct ieee80211_hw *hw, u8 channel)
806{
807 struct rtl_priv *rtlpriv = rtl_priv(hw);
808 struct rtl_phy *rtlphy = &(rtlpriv->phy);
809 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
810
811 if (IS_81xxC_VENDOR_UMC_B_CUT(rtlhal->version)) {
812 if (channel == 6 && rtlphy->current_chan_bw ==
813 HT_CHANNEL_WIDTH_20)
814 rtl_set_rfreg(hw, RF90_PATH_A, RF_RX_G1, MASKDWORD,
815 0x00255);
816 else{
817 u32 backupRF0x1A = (u32)rtl_get_rfreg(hw, RF90_PATH_A,
818 RF_RX_G1, RFREG_OFFSET_MASK);
819 rtl_set_rfreg(hw, RF90_PATH_A, RF_RX_G1, MASKDWORD,
820 backupRF0x1A);
821 }
822 }
823}
824
825static bool _phy_sw_chnl_step_by_step(struct ieee80211_hw *hw, u8 channel,
826 u8 *stage, u8 *step, u32 *delay)
827{
828 struct rtl_priv *rtlpriv = rtl_priv(hw);
829 struct rtl_phy *rtlphy = &(rtlpriv->phy);
830 struct swchnlcmd precommoncmd[MAX_PRECMD_CNT];
831 u32 precommoncmdcnt;
832 struct swchnlcmd postcommoncmd[MAX_POSTCMD_CNT];
833 u32 postcommoncmdcnt;
834 struct swchnlcmd rfdependcmd[MAX_RFDEPENDCMD_CNT];
835 u32 rfdependcmdcnt;
836 struct swchnlcmd *currentcmd = NULL;
837 u8 rfpath;
838 u8 num_total_rfpath = rtlphy->num_total_rfpath;
839
840 precommoncmdcnt = 0;
841 rtl8723_phy_set_sw_chnl_cmdarray(precommoncmd, precommoncmdcnt++,
842 MAX_PRECMD_CNT, CMDID_SET_TXPOWEROWER_LEVEL,
843 0, 0, 0);
844 rtl8723_phy_set_sw_chnl_cmdarray(precommoncmd, precommoncmdcnt++,
845 MAX_PRECMD_CNT, CMDID_END, 0, 0, 0);
846 postcommoncmdcnt = 0;
847
848 rtl8723_phy_set_sw_chnl_cmdarray(postcommoncmd, postcommoncmdcnt++,
849 MAX_POSTCMD_CNT, CMDID_END, 0, 0, 0);
850 rfdependcmdcnt = 0;
851
852 RT_ASSERT((channel >= 1 && channel <= 14),
853 "illegal channel for Zebra: %d\n", channel);
854
855 rtl8723_phy_set_sw_chnl_cmdarray(rfdependcmd, rfdependcmdcnt++,
856 MAX_RFDEPENDCMD_CNT, CMDID_RF_WRITEREG,
857 RF_CHNLBW, channel, 10);
858
859 rtl8723_phy_set_sw_chnl_cmdarray(rfdependcmd, rfdependcmdcnt++,
860 MAX_RFDEPENDCMD_CNT, CMDID_END, 0, 0, 0);
861
862 do {
863 switch (*stage) {
864 case 0:
865 currentcmd = &precommoncmd[*step];
866 break;
867 case 1:
868 currentcmd = &rfdependcmd[*step];
869 break;
870 case 2:
871 currentcmd = &postcommoncmd[*step];
872 break;
873 }
874
875 if (currentcmd->cmdid == CMDID_END) {
876 if ((*stage) == 2) {
877 return true;
878 } else {
879 (*stage)++;
880 (*step) = 0;
881 continue;
882 }
883 }
884
885 switch (currentcmd->cmdid) {
886 case CMDID_SET_TXPOWEROWER_LEVEL:
887 rtl8723ae_phy_set_txpower_level(hw, channel);
888 break;
889 case CMDID_WRITEPORT_ULONG:
890 rtl_write_dword(rtlpriv, currentcmd->para1,
891 currentcmd->para2);
892 break;
893 case CMDID_WRITEPORT_USHORT:
894 rtl_write_word(rtlpriv, currentcmd->para1,
895 (u16) currentcmd->para2);
896 break;
897 case CMDID_WRITEPORT_UCHAR:
898 rtl_write_byte(rtlpriv, currentcmd->para1,
899 (u8) currentcmd->para2);
900 break;
901 case CMDID_RF_WRITEREG:
902 for (rfpath = 0; rfpath < num_total_rfpath; rfpath++) {
903 rtlphy->rfreg_chnlval[rfpath] =
904 ((rtlphy->rfreg_chnlval[rfpath] &
905 0xfffffc00) | currentcmd->para2);
906
907 rtl_set_rfreg(hw, (enum radio_path)rfpath,
908 currentcmd->para1,
909 RFREG_OFFSET_MASK,
910 rtlphy->rfreg_chnlval[rfpath]);
911 }
912 _rtl8723ae_phy_sw_rf_seting(hw, channel);
913 break;
914 default:
915 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
916 "switch case not process\n");
917 break;
918 }
919
920 break;
921 } while (true);
922
923 (*delay) = currentcmd->msdelay;
924 (*step)++;
925 return false;
926}
927
928static u8 _rtl8723ae_phy_path_a_iqk(struct ieee80211_hw *hw, bool config_pathb)
929{
930 u32 reg_eac, reg_e94, reg_e9c, reg_ea4;
931 u8 result = 0x00;
932
933 rtl_set_bbreg(hw, 0xe30, MASKDWORD, 0x10008c1f);
934 rtl_set_bbreg(hw, 0xe34, MASKDWORD, 0x10008c1f);
935 rtl_set_bbreg(hw, 0xe38, MASKDWORD, 0x82140102);
936 rtl_set_bbreg(hw, 0xe3c, MASKDWORD,
937 config_pathb ? 0x28160202 : 0x28160502);
938
939 if (config_pathb) {
940 rtl_set_bbreg(hw, 0xe50, MASKDWORD, 0x10008c22);
941 rtl_set_bbreg(hw, 0xe54, MASKDWORD, 0x10008c22);
942 rtl_set_bbreg(hw, 0xe58, MASKDWORD, 0x82140102);
943 rtl_set_bbreg(hw, 0xe5c, MASKDWORD, 0x28160202);
944 }
945
946 rtl_set_bbreg(hw, 0xe4c, MASKDWORD, 0x001028d1);
947 rtl_set_bbreg(hw, 0xe48, MASKDWORD, 0xf9000000);
948 rtl_set_bbreg(hw, 0xe48, MASKDWORD, 0xf8000000);
949
950 mdelay(IQK_DELAY_TIME);
951
952 reg_eac = rtl_get_bbreg(hw, 0xeac, MASKDWORD);
953 reg_e94 = rtl_get_bbreg(hw, 0xe94, MASKDWORD);
954 reg_e9c = rtl_get_bbreg(hw, 0xe9c, MASKDWORD);
955 reg_ea4 = rtl_get_bbreg(hw, 0xea4, MASKDWORD);
956
957 if (!(reg_eac & BIT(28)) &&
958 (((reg_e94 & 0x03FF0000) >> 16) != 0x142) &&
959 (((reg_e9c & 0x03FF0000) >> 16) != 0x42))
960 result |= 0x01;
961 else
962 return result;
963
964 if (!(reg_eac & BIT(27)) &&
965 (((reg_ea4 & 0x03FF0000) >> 16) != 0x132) &&
966 (((reg_eac & 0x03FF0000) >> 16) != 0x36))
967 result |= 0x02;
968 return result;
969}
970
971static u8 _rtl8723ae_phy_path_b_iqk(struct ieee80211_hw *hw)
972{
973 u32 reg_eac, reg_eb4, reg_ebc, reg_ec4, reg_ecc;
974 u8 result = 0x00;
975
976 rtl_set_bbreg(hw, 0xe60, MASKDWORD, 0x00000002);
977 rtl_set_bbreg(hw, 0xe60, MASKDWORD, 0x00000000);
978 mdelay(IQK_DELAY_TIME);
979 reg_eac = rtl_get_bbreg(hw, 0xeac, MASKDWORD);
980 reg_eb4 = rtl_get_bbreg(hw, 0xeb4, MASKDWORD);
981 reg_ebc = rtl_get_bbreg(hw, 0xebc, MASKDWORD);
982 reg_ec4 = rtl_get_bbreg(hw, 0xec4, MASKDWORD);
983 reg_ecc = rtl_get_bbreg(hw, 0xecc, MASKDWORD);
984
985 if (!(reg_eac & BIT(31)) &&
986 (((reg_eb4 & 0x03FF0000) >> 16) != 0x142) &&
987 (((reg_ebc & 0x03FF0000) >> 16) != 0x42))
988 result |= 0x01;
989 else
990 return result;
991 if (!(reg_eac & BIT(30)) &&
992 (((reg_ec4 & 0x03FF0000) >> 16) != 0x132) &&
993 (((reg_ecc & 0x03FF0000) >> 16) != 0x36))
994 result |= 0x02;
995 return result;
996}
997
998static bool phy_simularity_comp(struct ieee80211_hw *hw, long result[][8],
999 u8 c1, u8 c2)
1000{
1001 u32 i, j, diff, simularity_bitmap, bound;
1002
1003 u8 final_candidate[2] = { 0xFF, 0xFF };
1004 bool bresult = true;
1005
1006 bound = 4;
1007
1008 simularity_bitmap = 0;
1009
1010 for (i = 0; i < bound; i++) {
1011 diff = (result[c1][i] > result[c2][i]) ?
1012 (result[c1][i] - result[c2][i]) :
1013 (result[c2][i] - result[c1][i]);
1014
1015 if (diff > MAX_TOLERANCE) {
1016 if ((i == 2 || i == 6) && !simularity_bitmap) {
1017 if (result[c1][i] + result[c1][i + 1] == 0)
1018 final_candidate[(i / 4)] = c2;
1019 else if (result[c2][i] + result[c2][i + 1] == 0)
1020 final_candidate[(i / 4)] = c1;
1021 else
1022 simularity_bitmap = simularity_bitmap |
1023 (1 << i);
1024 } else
1025 simularity_bitmap =
1026 simularity_bitmap | (1 << i);
1027 }
1028 }
1029
1030 if (simularity_bitmap == 0) {
1031 for (i = 0; i < (bound / 4); i++) {
1032 if (final_candidate[i] != 0xFF) {
1033 for (j = i * 4; j < (i + 1) * 4 - 2; j++)
1034 result[3][j] =
1035 result[final_candidate[i]][j];
1036 bresult = false;
1037 }
1038 }
1039 return bresult;
1040 } else if (!(simularity_bitmap & 0x0F)) {
1041 for (i = 0; i < 4; i++)
1042 result[3][i] = result[c1][i];
1043 return false;
1044 } else {
1045 return false;
1046 }
1047
1048}
1049
1050static void _rtl8723ae_phy_iq_calibrate(struct ieee80211_hw *hw,
1051 long result[][8], u8 t, bool is2t)
1052{
1053 struct rtl_priv *rtlpriv = rtl_priv(hw);
1054 struct rtl_phy *rtlphy = &(rtlpriv->phy);
1055 u32 i;
1056 u8 patha_ok, pathb_ok;
1057 u32 adda_reg[IQK_ADDA_REG_NUM] = {
1058 0x85c, 0xe6c, 0xe70, 0xe74,
1059 0xe78, 0xe7c, 0xe80, 0xe84,
1060 0xe88, 0xe8c, 0xed0, 0xed4,
1061 0xed8, 0xedc, 0xee0, 0xeec
1062 };
1063 u32 iqk_mac_reg[IQK_MAC_REG_NUM] = {
1064 0x522, 0x550, 0x551, 0x040
1065 };
1066 const u32 retrycount = 2;
1067
1068 if (t == 0) {
1069 rtl8723_save_adda_registers(hw, adda_reg, rtlphy->adda_backup,
1070 16);
1071 rtl8723_phy_save_mac_registers(hw, iqk_mac_reg,
1072 rtlphy->iqk_mac_backup);
1073 }
1074 rtl8723_phy_path_adda_on(hw, adda_reg, true, is2t);
1075 if (t == 0) {
1076 rtlphy->rfpi_enable = (u8) rtl_get_bbreg(hw,
1077 RFPGA0_XA_HSSIPARAMETER1,
1078 BIT(8));
1079 }
1080
1081 if (!rtlphy->rfpi_enable)
1082 rtl8723_phy_pi_mode_switch(hw, true);
1083 if (t == 0) {
1084 rtlphy->reg_c04 = rtl_get_bbreg(hw, 0xc04, MASKDWORD);
1085 rtlphy->reg_c08 = rtl_get_bbreg(hw, 0xc08, MASKDWORD);
1086 rtlphy->reg_874 = rtl_get_bbreg(hw, 0x874, MASKDWORD);
1087 }
1088 rtl_set_bbreg(hw, 0xc04, MASKDWORD, 0x03a05600);
1089 rtl_set_bbreg(hw, 0xc08, MASKDWORD, 0x000800e4);
1090 rtl_set_bbreg(hw, 0x874, MASKDWORD, 0x22204000);
1091 if (is2t) {
1092 rtl_set_bbreg(hw, 0x840, MASKDWORD, 0x00010000);
1093 rtl_set_bbreg(hw, 0x844, MASKDWORD, 0x00010000);
1094 }
1095 rtl8723_phy_mac_setting_calibration(hw, iqk_mac_reg,
1096 rtlphy->iqk_mac_backup);
1097 rtl_set_bbreg(hw, 0xb68, MASKDWORD, 0x00080000);
1098 if (is2t)
1099 rtl_set_bbreg(hw, 0xb6c, MASKDWORD, 0x00080000);
1100 rtl_set_bbreg(hw, 0xe28, MASKDWORD, 0x80800000);
1101 rtl_set_bbreg(hw, 0xe40, MASKDWORD, 0x01007c00);
1102 rtl_set_bbreg(hw, 0xe44, MASKDWORD, 0x01004800);
1103 for (i = 0; i < retrycount; i++) {
1104 patha_ok = _rtl8723ae_phy_path_a_iqk(hw, is2t);
1105 if (patha_ok == 0x03) {
1106 result[t][0] = (rtl_get_bbreg(hw, 0xe94, MASKDWORD) &
1107 0x3FF0000) >> 16;
1108 result[t][1] = (rtl_get_bbreg(hw, 0xe9c, MASKDWORD) &
1109 0x3FF0000) >> 16;
1110 result[t][2] = (rtl_get_bbreg(hw, 0xea4, MASKDWORD) &
1111 0x3FF0000) >> 16;
1112 result[t][3] = (rtl_get_bbreg(hw, 0xeac, MASKDWORD) &
1113 0x3FF0000) >> 16;
1114 break;
1115 } else if (i == (retrycount - 1) && patha_ok == 0x01)
1116
1117 result[t][0] = (rtl_get_bbreg(hw, 0xe94,
1118 MASKDWORD) & 0x3FF0000) >> 16;
1119 result[t][1] =
1120 (rtl_get_bbreg(hw, 0xe9c, MASKDWORD) & 0x3FF0000) >> 16;
1121
1122 }
1123
1124 if (is2t) {
1125 rtl8723_phy_path_a_standby(hw);
1126 rtl8723_phy_path_adda_on(hw, adda_reg, false, is2t);
1127 for (i = 0; i < retrycount; i++) {
1128 pathb_ok = _rtl8723ae_phy_path_b_iqk(hw);
1129 if (pathb_ok == 0x03) {
1130 result[t][4] =
1131 (rtl_get_bbreg(hw, 0xeb4, MASKDWORD) &
1132 0x3FF0000) >> 16;
1133 result[t][5] =
1134 (rtl_get_bbreg(hw, 0xebc, MASKDWORD) &
1135 0x3FF0000) >> 16;
1136 result[t][6] =
1137 (rtl_get_bbreg(hw, 0xec4, MASKDWORD) &
1138 0x3FF0000) >> 16;
1139 result[t][7] =
1140 (rtl_get_bbreg(hw, 0xecc, MASKDWORD) &
1141 0x3FF0000) >> 16;
1142 break;
1143 } else if (i == (retrycount - 1) && pathb_ok == 0x01) {
1144 result[t][4] =
1145 (rtl_get_bbreg(hw, 0xeb4, MASKDWORD) &
1146 0x3FF0000) >> 16;
1147 }
1148 result[t][5] = (rtl_get_bbreg(hw, 0xebc, MASKDWORD) &
1149 0x3FF0000) >> 16;
1150 }
1151 }
1152 rtl_set_bbreg(hw, 0xc04, MASKDWORD, rtlphy->reg_c04);
1153 rtl_set_bbreg(hw, 0x874, MASKDWORD, rtlphy->reg_874);
1154 rtl_set_bbreg(hw, 0xc08, MASKDWORD, rtlphy->reg_c08);
1155 rtl_set_bbreg(hw, 0xe28, MASKDWORD, 0);
1156 rtl_set_bbreg(hw, 0x840, MASKDWORD, 0x00032ed3);
1157 if (is2t)
1158 rtl_set_bbreg(hw, 0x844, MASKDWORD, 0x00032ed3);
1159 if (t != 0) {
1160 if (!rtlphy->rfpi_enable)
1161 rtl8723_phy_pi_mode_switch(hw, false);
1162 rtl8723_phy_reload_adda_registers(hw, adda_reg,
1163 rtlphy->adda_backup, 16);
1164 rtl8723_phy_reload_mac_registers(hw, iqk_mac_reg,
1165 rtlphy->iqk_mac_backup);
1166 }
1167}
1168
1169static void _rtl8723ae_phy_lc_calibrate(struct ieee80211_hw *hw, bool is2t)
1170{
1171 struct rtl_priv *rtlpriv = rtl_priv(hw);
1172 u8 tmpreg;
1173 u32 rf_a_mode = 0, rf_b_mode = 0, lc_cal;
1174
1175 tmpreg = rtl_read_byte(rtlpriv, 0xd03);
1176
1177 if ((tmpreg & 0x70) != 0)
1178 rtl_write_byte(rtlpriv, 0xd03, tmpreg & 0x8F);
1179 else
1180 rtl_write_byte(rtlpriv, REG_TXPAUSE, 0xFF);
1181
1182 if ((tmpreg & 0x70) != 0) {
1183 rf_a_mode = rtl_get_rfreg(hw, RF90_PATH_A, 0x00, MASK12BITS);
1184
1185 if (is2t)
1186 rf_b_mode = rtl_get_rfreg(hw, RF90_PATH_B, 0x00,
1187 MASK12BITS);
1188
1189 rtl_set_rfreg(hw, RF90_PATH_A, 0x00, MASK12BITS,
1190 (rf_a_mode & 0x8FFFF) | 0x10000);
1191
1192 if (is2t)
1193 rtl_set_rfreg(hw, RF90_PATH_B, 0x00, MASK12BITS,
1194 (rf_b_mode & 0x8FFFF) | 0x10000);
1195 }
1196 lc_cal = rtl_get_rfreg(hw, RF90_PATH_A, 0x18, MASK12BITS);
1197
1198 rtl_set_rfreg(hw, RF90_PATH_A, 0x18, MASK12BITS, lc_cal | 0x08000);
1199
1200 mdelay(100);
1201
1202 if ((tmpreg & 0x70) != 0) {
1203 rtl_write_byte(rtlpriv, 0xd03, tmpreg);
1204 rtl_set_rfreg(hw, RF90_PATH_A, 0x00, MASK12BITS, rf_a_mode);
1205
1206 if (is2t)
1207 rtl_set_rfreg(hw, RF90_PATH_B, 0x00, MASK12BITS,
1208 rf_b_mode);
1209 } else {
1210 rtl_write_byte(rtlpriv, REG_TXPAUSE, 0x00);
1211 }
1212}
1213
1214static void _rtl8723ae_phy_set_rfpath_switch(struct ieee80211_hw *hw,
1215 bool bmain, bool is2t)
1216{
1217 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
1218
1219 if (is_hal_stop(rtlhal)) {
1220 rtl_set_bbreg(hw, REG_LEDCFG0, BIT(23), 0x01);
1221 rtl_set_bbreg(hw, rFPGA0_XAB_RFPARAMETER, BIT(13), 0x01);
1222 }
1223 if (is2t) {
1224 if (bmain)
1225 rtl_set_bbreg(hw, RFPGA0_XB_RFINTERFACEOE,
1226 BIT(5) | BIT(6), 0x1);
1227 else
1228 rtl_set_bbreg(hw, RFPGA0_XB_RFINTERFACEOE,
1229 BIT(5) | BIT(6), 0x2);
1230 } else {
1231 if (bmain)
1232 rtl_set_bbreg(hw, RFPGA0_XA_RFINTERFACEOE, 0x300, 0x2);
1233 else
1234 rtl_set_bbreg(hw, RFPGA0_XA_RFINTERFACEOE, 0x300, 0x1);
1235
1236 }
1237}
1238
1239#undef IQK_ADDA_REG_NUM
1240#undef IQK_DELAY_TIME
1241
1242void rtl8723ae_phy_iq_calibrate(struct ieee80211_hw *hw, bool recovery)
1243{
1244 struct rtl_priv *rtlpriv = rtl_priv(hw);
1245 struct rtl_phy *rtlphy = &(rtlpriv->phy);
1246 long result[4][8];
1247 u8 i, final_candidate;
1248 bool patha_ok, pathb_ok;
1249 long reg_e94, reg_e9c, reg_ea4, reg_eb4, reg_ebc, reg_tmp = 0;
1250 bool is12simular, is13simular, is23simular;
1251 bool start_conttx = false, singletone = false;
1252 u32 iqk_bb_reg[10] = {
1253 ROFDM0_XARXIQIMBALANCE,
1254 ROFDM0_XBRXIQIMBALANCE,
1255 ROFDM0_ECCATHRESHOLD,
1256 ROFDM0_AGCRSSITABLE,
1257 ROFDM0_XATXIQIMBALANCE,
1258 ROFDM0_XBTXIQIMBALANCE,
1259 ROFDM0_XCTXIQIMBALANCE,
1260 ROFDM0_XCTXAFE,
1261 ROFDM0_XDTXAFE,
1262 ROFDM0_RXIQEXTANTA
1263 };
1264
1265 if (recovery) {
1266 rtl8723_phy_reload_adda_registers(hw, iqk_bb_reg,
1267 rtlphy->iqk_bb_backup, 10);
1268 return;
1269 }
1270 if (start_conttx || singletone)
1271 return;
1272 for (i = 0; i < 8; i++) {
1273 result[0][i] = 0;
1274 result[1][i] = 0;
1275 result[2][i] = 0;
1276 result[3][i] = 0;
1277 }
1278 final_candidate = 0xff;
1279 patha_ok = false;
1280 pathb_ok = false;
1281 is12simular = false;
1282 is23simular = false;
1283 is13simular = false;
1284 for (i = 0; i < 3; i++) {
1285 _rtl8723ae_phy_iq_calibrate(hw, result, i, false);
1286 if (i == 1) {
1287 is12simular = phy_simularity_comp(hw, result, 0, 1);
1288 if (is12simular) {
1289 final_candidate = 0;
1290 break;
1291 }
1292 }
1293 if (i == 2) {
1294 is13simular = phy_simularity_comp(hw, result, 0, 2);
1295 if (is13simular) {
1296 final_candidate = 0;
1297 break;
1298 }
1299 is23simular = phy_simularity_comp(hw, result, 1, 2);
1300 if (is23simular) {
1301 final_candidate = 1;
1302 } else {
1303 for (i = 0; i < 8; i++)
1304 reg_tmp += result[3][i];
1305
1306 if (reg_tmp != 0)
1307 final_candidate = 3;
1308 else
1309 final_candidate = 0xFF;
1310 }
1311 }
1312 }
1313 for (i = 0; i < 4; i++) {
1314 reg_e94 = result[i][0];
1315 reg_e9c = result[i][1];
1316 reg_ea4 = result[i][2];
1317 reg_eb4 = result[i][4];
1318 reg_ebc = result[i][5];
1319 }
1320 if (final_candidate != 0xff) {
1321 rtlphy->reg_e94 = reg_e94 = result[final_candidate][0];
1322 rtlphy->reg_e9c = reg_e9c = result[final_candidate][1];
1323 reg_ea4 = result[final_candidate][2];
1324 rtlphy->reg_eb4 = reg_eb4 = result[final_candidate][4];
1325 rtlphy->reg_ebc = reg_ebc = result[final_candidate][5];
1326 patha_ok = pathb_ok = true;
1327 } else {
1328 rtlphy->reg_e94 = rtlphy->reg_eb4 = 0x100;
1329 rtlphy->reg_e9c = rtlphy->reg_ebc = 0x0;
1330 }
1331 if (reg_e94 != 0)
1332 rtl8723_phy_path_a_fill_iqk_matrix(hw, patha_ok, result,
1333 final_candidate,
1334 (reg_ea4 == 0));
1335 rtl8723_save_adda_registers(hw, iqk_bb_reg, rtlphy->iqk_bb_backup, 10);
1336}
1337
1338void rtl8723ae_phy_lc_calibrate(struct ieee80211_hw *hw)
1339{
1340 bool start_conttx = false, singletone = false;
1341
1342 if (start_conttx || singletone)
1343 return;
1344 _rtl8723ae_phy_lc_calibrate(hw, false);
1345}
1346
1347void rtl8723ae_phy_set_rfpath_switch(struct ieee80211_hw *hw, bool bmain)
1348{
1349 _rtl8723ae_phy_set_rfpath_switch(hw, bmain, false);
1350}
1351
1352bool rtl8723ae_phy_set_io_cmd(struct ieee80211_hw *hw, enum io_type iotype)
1353{
1354 struct rtl_priv *rtlpriv = rtl_priv(hw);
1355 struct rtl_phy *rtlphy = &(rtlpriv->phy);
1356 bool postprocessing = false;
1357
1358 RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE,
1359 "-->IO Cmd(%#x), set_io_inprogress(%d)\n",
1360 iotype, rtlphy->set_io_inprogress);
1361 do {
1362 switch (iotype) {
1363 case IO_CMD_RESUME_DM_BY_SCAN:
1364 RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE,
1365 "[IO CMD] Resume DM after scan.\n");
1366 postprocessing = true;
1367 break;
1368 case IO_CMD_PAUSE_DM_BY_SCAN:
1369 RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE,
1370 "[IO CMD] Pause DM before scan.\n");
1371 postprocessing = true;
1372 break;
1373 default:
1374 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
1375 "switch case not process\n");
1376 break;
1377 }
1378 } while (false);
1379 if (postprocessing && !rtlphy->set_io_inprogress) {
1380 rtlphy->set_io_inprogress = true;
1381 rtlphy->current_io_type = iotype;
1382 } else {
1383 return false;
1384 }
1385 rtl8723ae_phy_set_io(hw);
1386 RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE, "<--IO Type(%#x)\n", iotype);
1387 return true;
1388}
1389
1390static void rtl8723ae_phy_set_io(struct ieee80211_hw *hw)
1391{
1392 struct rtl_priv *rtlpriv = rtl_priv(hw);
1393 struct rtl_phy *rtlphy = &(rtlpriv->phy);
1394 struct dig_t *dm_digtable = &rtlpriv->dm_digtable;
1395
1396 RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE,
1397 "--->Cmd(%#x), set_io_inprogress(%d)\n",
1398 rtlphy->current_io_type, rtlphy->set_io_inprogress);
1399 switch (rtlphy->current_io_type) {
1400 case IO_CMD_RESUME_DM_BY_SCAN:
1401 dm_digtable->cur_igvalue = rtlphy->initgain_backup.xaagccore1;
1402 rtl8723ae_dm_write_dig(hw);
1403 rtl8723ae_phy_set_txpower_level(hw, rtlphy->current_channel);
1404 break;
1405 case IO_CMD_PAUSE_DM_BY_SCAN:
1406 rtlphy->initgain_backup.xaagccore1 = dm_digtable->cur_igvalue;
1407 dm_digtable->cur_igvalue = 0x17;
1408 rtl8723ae_dm_write_dig(hw);
1409 break;
1410 default:
1411 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
1412 "switch case not process\n");
1413 break;
1414 }
1415 rtlphy->set_io_inprogress = false;
1416 RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE,
1417 "<---(%#x)\n", rtlphy->current_io_type);
1418}
1419
1420static void rtl8723ae_phy_set_rf_on(struct ieee80211_hw *hw)
1421{
1422 struct rtl_priv *rtlpriv = rtl_priv(hw);
1423
1424 rtl_write_byte(rtlpriv, REG_SPS0_CTRL, 0x2b);
1425 rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE3);
1426 rtl_write_byte(rtlpriv, REG_APSD_CTRL, 0x00);
1427 rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE2);
1428 rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE3);
1429 rtl_write_byte(rtlpriv, REG_TXPAUSE, 0x00);
1430}
1431
1432static void _rtl8723ae_phy_set_rf_sleep(struct ieee80211_hw *hw)
1433{
1434 struct rtl_priv *rtlpriv = rtl_priv(hw);
1435 u32 u4b_tmp;
1436 u8 delay = 5;
1437
1438 rtl_write_byte(rtlpriv, REG_TXPAUSE, 0xFF);
1439 rtl_set_rfreg(hw, RF90_PATH_A, 0x00, RFREG_OFFSET_MASK, 0x00);
1440 rtl_write_byte(rtlpriv, REG_APSD_CTRL, 0x40);
1441 u4b_tmp = rtl_get_rfreg(hw, RF90_PATH_A, 0, RFREG_OFFSET_MASK);
1442 while (u4b_tmp != 0 && delay > 0) {
1443 rtl_write_byte(rtlpriv, REG_APSD_CTRL, 0x0);
1444 rtl_set_rfreg(hw, RF90_PATH_A, 0x00, RFREG_OFFSET_MASK, 0x00);
1445 rtl_write_byte(rtlpriv, REG_APSD_CTRL, 0x40);
1446 u4b_tmp = rtl_get_rfreg(hw, RF90_PATH_A, 0, RFREG_OFFSET_MASK);
1447 delay--;
1448 }
1449 if (delay == 0) {
1450 rtl_write_byte(rtlpriv, REG_APSD_CTRL, 0x00);
1451 rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE2);
1452 rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE3);
1453 rtl_write_byte(rtlpriv, REG_TXPAUSE, 0x00);
1454 RT_TRACE(rtlpriv, COMP_POWER, DBG_TRACE,
1455 "Switch RF timeout !!!.\n");
1456 return;
1457 }
1458 rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE2);
1459 rtl_write_byte(rtlpriv, REG_SPS0_CTRL, 0x22);
1460}
1461
1462static bool _rtl8723ae_phy_set_rf_power_state(struct ieee80211_hw *hw,
1463 enum rf_pwrstate rfpwr_state)
1464{
1465 struct rtl_priv *rtlpriv = rtl_priv(hw);
1466 struct rtl_pci_priv *pcipriv = rtl_pcipriv(hw);
1467 struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
1468 struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
1469 struct rtl8192_tx_ring *ring = NULL;
1470 bool bresult = true;
1471 u8 i, queue_id;
1472
1473 switch (rfpwr_state) {
1474 case ERFON:
1475 if ((ppsc->rfpwr_state == ERFOFF) &&
1476 RT_IN_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_HALT_NIC)) {
1477 bool rtstatus;
1478 u32 InitializeCount = 0;
1479 do {
1480 InitializeCount++;
1481 RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG,
1482 "IPS Set eRf nic enable\n");
1483 rtstatus = rtl_ps_enable_nic(hw);
1484 } while ((rtstatus != true) && (InitializeCount < 10));
1485 RT_CLEAR_PS_LEVEL(ppsc,
1486 RT_RF_OFF_LEVL_HALT_NIC);
1487 } else {
1488 RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG,
1489 "Set ERFON sleeped:%d ms\n",
1490 jiffies_to_msecs(jiffies -
1491 ppsc->last_sleep_jiffies));
1492 ppsc->last_awake_jiffies = jiffies;
1493 rtl8723ae_phy_set_rf_on(hw);
1494 }
1495 if (mac->link_state == MAC80211_LINKED) {
1496 rtlpriv->cfg->ops->led_control(hw,
1497 LED_CTL_LINK);
1498 } else {
1499 rtlpriv->cfg->ops->led_control(hw,
1500 LED_CTL_NO_LINK);
1501 }
1502 break;
1503 case ERFOFF:
1504 if (ppsc->reg_rfps_level & RT_RF_OFF_LEVL_HALT_NIC) {
1505 RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG,
1506 "IPS Set eRf nic disable\n");
1507 rtl_ps_disable_nic(hw);
1508 RT_SET_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_HALT_NIC);
1509 } else {
1510 if (ppsc->rfoff_reason == RF_CHANGE_BY_IPS) {
1511 rtlpriv->cfg->ops->led_control(hw,
1512 LED_CTL_NO_LINK);
1513 } else {
1514 rtlpriv->cfg->ops->led_control(hw,
1515 LED_CTL_POWER_OFF);
1516 }
1517 }
1518 break;
1519 case ERFSLEEP:
1520 if (ppsc->rfpwr_state == ERFOFF)
1521 break;
1522 for (queue_id = 0, i = 0;
1523 queue_id < RTL_PCI_MAX_TX_QUEUE_COUNT;) {
1524 ring = &pcipriv->dev.tx_ring[queue_id];
1525 if (skb_queue_len(&ring->queue) == 0) {
1526 queue_id++;
1527 continue;
1528 } else {
1529 RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
1530 "eRf Off/Sleep: %d times TcbBusyQueue[%d] =%d before doze!\n",
1531 (i + 1), queue_id,
1532 skb_queue_len(&ring->queue));
1533
1534 udelay(10);
1535 i++;
1536 }
1537 if (i >= MAX_DOZE_WAITING_TIMES_9x) {
1538 RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
1539 "\n ERFSLEEP: %d times TcbBusyQueue[%d] = %d !\n",
1540 MAX_DOZE_WAITING_TIMES_9x,
1541 queue_id,
1542 skb_queue_len(&ring->queue));
1543 break;
1544 }
1545 }
1546 RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG,
1547 "Set ERFSLEEP awaked:%d ms\n",
1548 jiffies_to_msecs(jiffies - ppsc->last_awake_jiffies));
1549 ppsc->last_sleep_jiffies = jiffies;
1550 _rtl8723ae_phy_set_rf_sleep(hw);
1551 break;
1552 default:
1553 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
1554 "switch case not processed\n");
1555 bresult = false;
1556 break;
1557 }
1558 if (bresult)
1559 ppsc->rfpwr_state = rfpwr_state;
1560 return bresult;
1561}
1562
1563bool rtl8723ae_phy_set_rf_power_state(struct ieee80211_hw *hw,
1564 enum rf_pwrstate rfpwr_state)
1565{
1566 struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
1567 bool bresult = false;
1568
1569 if (rfpwr_state == ppsc->rfpwr_state)
1570 return bresult;
1571 bresult = _rtl8723ae_phy_set_rf_power_state(hw, rfpwr_state);
1572 return bresult;
1573}
1574