Loading...
Note: File does not exist in v6.8.
1/******************************************************************************
2 *
3 * Copyright(c) 2009-2012 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 * You should have received a copy of the GNU General Public License along with
15 * this program; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
17 *
18 * The full GNU General Public License is included in this distribution in the
19 * file called LICENSE.
20 *
21 * Contact Information:
22 * wlanfae <wlanfae@realtek.com>
23 * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
24 * Hsinchu 300, Taiwan.
25 *
26 * Larry Finger <Larry.Finger@lwfinger.net>
27 *
28 *****************************************************************************/
29
30#include "../wifi.h"
31#include "../pci.h"
32#include "../ps.h"
33#include "reg.h"
34#include "def.h"
35#include "hw.h"
36#include "phy.h"
37#include "rf.h"
38#include "dm.h"
39#include "table.h"
40
41static bool _rtl92c_phy_config_mac_with_headerfile(struct ieee80211_hw *hw);
42
43u32 rtl92c_phy_query_rf_reg(struct ieee80211_hw *hw,
44 enum radio_path rfpath, u32 regaddr, u32 bitmask)
45{
46 struct rtl_priv *rtlpriv = rtl_priv(hw);
47 u32 original_value, readback_value, bitshift;
48 struct rtl_phy *rtlphy = &(rtlpriv->phy);
49
50 RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE,
51 "regaddr(%#x), rfpath(%#x), bitmask(%#x)\n",
52 regaddr, rfpath, bitmask);
53
54 spin_lock(&rtlpriv->locks.rf_lock);
55
56 if (rtlphy->rf_mode != RF_OP_BY_FW) {
57 original_value = _rtl92c_phy_rf_serial_read(hw,
58 rfpath, regaddr);
59 } else {
60 original_value = _rtl92c_phy_fw_rf_serial_read(hw,
61 rfpath, regaddr);
62 }
63
64 bitshift = _rtl92c_phy_calculate_bit_shift(bitmask);
65 readback_value = (original_value & bitmask) >> bitshift;
66
67 spin_unlock(&rtlpriv->locks.rf_lock);
68
69 RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE,
70 "regaddr(%#x), rfpath(%#x), bitmask(%#x), original_value(%#x)\n",
71 regaddr, rfpath, bitmask, original_value);
72
73 return readback_value;
74}
75
76bool rtl92c_phy_mac_config(struct ieee80211_hw *hw)
77{
78 struct rtl_priv *rtlpriv = rtl_priv(hw);
79 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
80 bool is92c = IS_92C_SERIAL(rtlhal->version);
81 bool rtstatus = _rtl92c_phy_config_mac_with_headerfile(hw);
82
83 if (is92c)
84 rtl_write_byte(rtlpriv, 0x14, 0x71);
85 return rtstatus;
86}
87
88bool rtl92c_phy_bb_config(struct ieee80211_hw *hw)
89{
90 bool rtstatus = true;
91 struct rtl_priv *rtlpriv = rtl_priv(hw);
92 u16 regval;
93 u32 regvaldw;
94 u8 reg_hwparafile = 1;
95
96 _rtl92c_phy_init_bb_rf_register_definition(hw);
97 regval = rtl_read_word(rtlpriv, REG_SYS_FUNC_EN);
98 rtl_write_word(rtlpriv, REG_SYS_FUNC_EN,
99 regval | BIT(13) | BIT(0) | BIT(1));
100 rtl_write_byte(rtlpriv, REG_AFE_PLL_CTRL, 0x83);
101 rtl_write_byte(rtlpriv, REG_AFE_PLL_CTRL + 1, 0xdb);
102 rtl_write_byte(rtlpriv, REG_RF_CTRL, RF_EN | RF_RSTB | RF_SDMRSTB);
103 rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN,
104 FEN_PPLL | FEN_PCIEA | FEN_DIO_PCIE |
105 FEN_BB_GLB_RSTn | FEN_BBRSTB);
106 rtl_write_byte(rtlpriv, REG_AFE_XTAL_CTRL + 1, 0x80);
107 regvaldw = rtl_read_dword(rtlpriv, REG_LEDCFG0);
108 rtl_write_dword(rtlpriv, REG_LEDCFG0, regvaldw | BIT(23));
109 if (reg_hwparafile == 1)
110 rtstatus = _rtl92c_phy_bb8192c_config_parafile(hw);
111 return rtstatus;
112}
113
114void rtl92ce_phy_set_rf_reg(struct ieee80211_hw *hw,
115 enum radio_path rfpath,
116 u32 regaddr, u32 bitmask, u32 data)
117{
118 struct rtl_priv *rtlpriv = rtl_priv(hw);
119 struct rtl_phy *rtlphy = &(rtlpriv->phy);
120 u32 original_value, bitshift;
121
122 RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE,
123 "regaddr(%#x), bitmask(%#x), data(%#x), rfpath(%#x)\n",
124 regaddr, bitmask, data, rfpath);
125
126 spin_lock(&rtlpriv->locks.rf_lock);
127
128 if (rtlphy->rf_mode != RF_OP_BY_FW) {
129 if (bitmask != RFREG_OFFSET_MASK) {
130 original_value = _rtl92c_phy_rf_serial_read(hw,
131 rfpath,
132 regaddr);
133 bitshift = _rtl92c_phy_calculate_bit_shift(bitmask);
134 data =
135 ((original_value & (~bitmask)) |
136 (data << bitshift));
137 }
138
139 _rtl92c_phy_rf_serial_write(hw, rfpath, regaddr, data);
140 } else {
141 if (bitmask != RFREG_OFFSET_MASK) {
142 original_value = _rtl92c_phy_fw_rf_serial_read(hw,
143 rfpath,
144 regaddr);
145 bitshift = _rtl92c_phy_calculate_bit_shift(bitmask);
146 data =
147 ((original_value & (~bitmask)) |
148 (data << bitshift));
149 }
150 _rtl92c_phy_fw_rf_serial_write(hw, rfpath, regaddr, data);
151 }
152
153 spin_unlock(&rtlpriv->locks.rf_lock);
154
155 RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE,
156 "regaddr(%#x), bitmask(%#x), data(%#x), rfpath(%#x)\n",
157 regaddr, bitmask, data, rfpath);
158}
159
160static bool _rtl92c_phy_config_mac_with_headerfile(struct ieee80211_hw *hw)
161{
162 struct rtl_priv *rtlpriv = rtl_priv(hw);
163 u32 i;
164 u32 arraylength;
165 u32 *ptrarray;
166
167 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, "Read Rtl819XMACPHY_Array\n");
168 arraylength = MAC_2T_ARRAYLENGTH;
169 ptrarray = RTL8192CEMAC_2T_ARRAY;
170 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, "Img:RTL8192CEMAC_2T_ARRAY\n");
171 for (i = 0; i < arraylength; i = i + 2)
172 rtl_write_byte(rtlpriv, ptrarray[i], (u8) ptrarray[i + 1]);
173 return true;
174}
175
176bool _rtl92ce_phy_config_bb_with_headerfile(struct ieee80211_hw *hw,
177 u8 configtype)
178{
179 int i;
180 u32 *phy_regarray_table;
181 u32 *agctab_array_table;
182 u16 phy_reg_arraylen, agctab_arraylen;
183 struct rtl_priv *rtlpriv = rtl_priv(hw);
184 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
185
186 if (IS_92C_SERIAL(rtlhal->version)) {
187 agctab_arraylen = AGCTAB_2TARRAYLENGTH;
188 agctab_array_table = RTL8192CEAGCTAB_2TARRAY;
189 phy_reg_arraylen = PHY_REG_2TARRAY_LENGTH;
190 phy_regarray_table = RTL8192CEPHY_REG_2TARRAY;
191 } else {
192 agctab_arraylen = AGCTAB_1TARRAYLENGTH;
193 agctab_array_table = RTL8192CEAGCTAB_1TARRAY;
194 phy_reg_arraylen = PHY_REG_1TARRAY_LENGTH;
195 phy_regarray_table = RTL8192CEPHY_REG_1TARRAY;
196 }
197 if (configtype == BASEBAND_CONFIG_PHY_REG) {
198 for (i = 0; i < phy_reg_arraylen; i = i + 2) {
199 if (phy_regarray_table[i] == 0xfe)
200 mdelay(50);
201 else if (phy_regarray_table[i] == 0xfd)
202 mdelay(5);
203 else if (phy_regarray_table[i] == 0xfc)
204 mdelay(1);
205 else if (phy_regarray_table[i] == 0xfb)
206 udelay(50);
207 else if (phy_regarray_table[i] == 0xfa)
208 udelay(5);
209 else if (phy_regarray_table[i] == 0xf9)
210 udelay(1);
211 rtl_set_bbreg(hw, phy_regarray_table[i], MASKDWORD,
212 phy_regarray_table[i + 1]);
213 udelay(1);
214 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
215 "The phy_regarray_table[0] is %x Rtl819XPHY_REGArray[1] is %x\n",
216 phy_regarray_table[i],
217 phy_regarray_table[i + 1]);
218 }
219 } else if (configtype == BASEBAND_CONFIG_AGC_TAB) {
220 for (i = 0; i < agctab_arraylen; i = i + 2) {
221 rtl_set_bbreg(hw, agctab_array_table[i], MASKDWORD,
222 agctab_array_table[i + 1]);
223 udelay(1);
224 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
225 "The agctab_array_table[0] is %x Rtl819XPHY_REGArray[1] is %x\n",
226 agctab_array_table[i],
227 agctab_array_table[i + 1]);
228 }
229 }
230 return true;
231}
232
233bool _rtl92ce_phy_config_bb_with_pgheaderfile(struct ieee80211_hw *hw,
234 u8 configtype)
235{
236 struct rtl_priv *rtlpriv = rtl_priv(hw);
237 int i;
238 u32 *phy_regarray_table_pg;
239 u16 phy_regarray_pg_len;
240
241 phy_regarray_pg_len = PHY_REG_ARRAY_PGLENGTH;
242 phy_regarray_table_pg = RTL8192CEPHY_REG_ARRAY_PG;
243
244 if (configtype == BASEBAND_CONFIG_PHY_REG) {
245 for (i = 0; i < phy_regarray_pg_len; i = i + 3) {
246 if (phy_regarray_table_pg[i] == 0xfe)
247 mdelay(50);
248 else if (phy_regarray_table_pg[i] == 0xfd)
249 mdelay(5);
250 else if (phy_regarray_table_pg[i] == 0xfc)
251 mdelay(1);
252 else if (phy_regarray_table_pg[i] == 0xfb)
253 udelay(50);
254 else if (phy_regarray_table_pg[i] == 0xfa)
255 udelay(5);
256 else if (phy_regarray_table_pg[i] == 0xf9)
257 udelay(1);
258
259 _rtl92c_store_pwrIndex_diffrate_offset(hw,
260 phy_regarray_table_pg[i],
261 phy_regarray_table_pg[i + 1],
262 phy_regarray_table_pg[i + 2]);
263 }
264 } else {
265
266 RT_TRACE(rtlpriv, COMP_SEND, DBG_TRACE,
267 "configtype != BaseBand_Config_PHY_REG\n");
268 }
269 return true;
270}
271
272bool rtl92c_phy_config_rf_with_headerfile(struct ieee80211_hw *hw,
273 enum radio_path rfpath)
274{
275
276 int i;
277 u32 *radioa_array_table;
278 u32 *radiob_array_table;
279 u16 radioa_arraylen, radiob_arraylen;
280 struct rtl_priv *rtlpriv = rtl_priv(hw);
281 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
282
283 if (IS_92C_SERIAL(rtlhal->version)) {
284 radioa_arraylen = RADIOA_2TARRAYLENGTH;
285 radioa_array_table = RTL8192CERADIOA_2TARRAY;
286 radiob_arraylen = RADIOB_2TARRAYLENGTH;
287 radiob_array_table = RTL8192CE_RADIOB_2TARRAY;
288 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
289 "Radio_A:RTL8192CERADIOA_2TARRAY\n");
290 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
291 "Radio_B:RTL8192CE_RADIOB_2TARRAY\n");
292 } else {
293 radioa_arraylen = RADIOA_1TARRAYLENGTH;
294 radioa_array_table = RTL8192CE_RADIOA_1TARRAY;
295 radiob_arraylen = RADIOB_1TARRAYLENGTH;
296 radiob_array_table = RTL8192CE_RADIOB_1TARRAY;
297 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
298 "Radio_A:RTL8192CE_RADIOA_1TARRAY\n");
299 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
300 "Radio_B:RTL8192CE_RADIOB_1TARRAY\n");
301 }
302 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, "Radio No %x\n", rfpath);
303 switch (rfpath) {
304 case RF90_PATH_A:
305 for (i = 0; i < radioa_arraylen; i = i + 2) {
306 if (radioa_array_table[i] == 0xfe)
307 mdelay(50);
308 else if (radioa_array_table[i] == 0xfd)
309 mdelay(5);
310 else if (radioa_array_table[i] == 0xfc)
311 mdelay(1);
312 else if (radioa_array_table[i] == 0xfb)
313 udelay(50);
314 else if (radioa_array_table[i] == 0xfa)
315 udelay(5);
316 else if (radioa_array_table[i] == 0xf9)
317 udelay(1);
318 else {
319 rtl_set_rfreg(hw, rfpath, radioa_array_table[i],
320 RFREG_OFFSET_MASK,
321 radioa_array_table[i + 1]);
322 udelay(1);
323 }
324 }
325 break;
326 case RF90_PATH_B:
327 for (i = 0; i < radiob_arraylen; i = i + 2) {
328 if (radiob_array_table[i] == 0xfe) {
329 mdelay(50);
330 } else if (radiob_array_table[i] == 0xfd)
331 mdelay(5);
332 else if (radiob_array_table[i] == 0xfc)
333 mdelay(1);
334 else if (radiob_array_table[i] == 0xfb)
335 udelay(50);
336 else if (radiob_array_table[i] == 0xfa)
337 udelay(5);
338 else if (radiob_array_table[i] == 0xf9)
339 udelay(1);
340 else {
341 rtl_set_rfreg(hw, rfpath, radiob_array_table[i],
342 RFREG_OFFSET_MASK,
343 radiob_array_table[i + 1]);
344 udelay(1);
345 }
346 }
347 break;
348 case RF90_PATH_C:
349 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
350 "switch case not processed\n");
351 break;
352 case RF90_PATH_D:
353 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
354 "switch case not processed\n");
355 break;
356 }
357 return true;
358}
359
360void rtl92ce_phy_set_bw_mode_callback(struct ieee80211_hw *hw)
361{
362 struct rtl_priv *rtlpriv = rtl_priv(hw);
363 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
364 struct rtl_phy *rtlphy = &(rtlpriv->phy);
365 struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
366 u8 reg_bw_opmode;
367 u8 reg_prsr_rsc;
368
369 RT_TRACE(rtlpriv, COMP_SCAN, DBG_TRACE, "Switch to %s bandwidth\n",
370 rtlphy->current_chan_bw == HT_CHANNEL_WIDTH_20 ?
371 "20MHz" : "40MHz");
372
373 if (is_hal_stop(rtlhal)) {
374 rtlphy->set_bwmode_inprogress = false;
375 return;
376 }
377
378 reg_bw_opmode = rtl_read_byte(rtlpriv, REG_BWOPMODE);
379 reg_prsr_rsc = rtl_read_byte(rtlpriv, REG_RRSR + 2);
380
381 switch (rtlphy->current_chan_bw) {
382 case HT_CHANNEL_WIDTH_20:
383 reg_bw_opmode |= BW_OPMODE_20MHZ;
384 rtl_write_byte(rtlpriv, REG_BWOPMODE, reg_bw_opmode);
385 break;
386 case HT_CHANNEL_WIDTH_20_40:
387 reg_bw_opmode &= ~BW_OPMODE_20MHZ;
388 rtl_write_byte(rtlpriv, REG_BWOPMODE, reg_bw_opmode);
389 reg_prsr_rsc =
390 (reg_prsr_rsc & 0x90) | (mac->cur_40_prime_sc << 5);
391 rtl_write_byte(rtlpriv, REG_RRSR + 2, reg_prsr_rsc);
392 break;
393 default:
394 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
395 "unknown bandwidth: %#X\n", rtlphy->current_chan_bw);
396 break;
397 }
398
399 switch (rtlphy->current_chan_bw) {
400 case HT_CHANNEL_WIDTH_20:
401 rtl_set_bbreg(hw, RFPGA0_RFMOD, BRFMOD, 0x0);
402 rtl_set_bbreg(hw, RFPGA1_RFMOD, BRFMOD, 0x0);
403 rtl_set_bbreg(hw, RFPGA0_ANALOGPARAMETER2, BIT(10), 1);
404 break;
405 case HT_CHANNEL_WIDTH_20_40:
406 rtl_set_bbreg(hw, RFPGA0_RFMOD, BRFMOD, 0x1);
407 rtl_set_bbreg(hw, RFPGA1_RFMOD, BRFMOD, 0x1);
408
409 rtl_set_bbreg(hw, RCCK0_SYSTEM, BCCK_SIDEBAND,
410 (mac->cur_40_prime_sc >> 1));
411 rtl_set_bbreg(hw, ROFDM1_LSTF, 0xC00, mac->cur_40_prime_sc);
412 rtl_set_bbreg(hw, RFPGA0_ANALOGPARAMETER2, BIT(10), 0);
413
414 rtl_set_bbreg(hw, 0x818, (BIT(26) | BIT(27)),
415 (mac->cur_40_prime_sc ==
416 HAL_PRIME_CHNL_OFFSET_LOWER) ? 2 : 1);
417 break;
418 default:
419 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
420 "unknown bandwidth: %#X\n", rtlphy->current_chan_bw);
421 break;
422 }
423 rtl92ce_phy_rf6052_set_bandwidth(hw, rtlphy->current_chan_bw);
424 rtlphy->set_bwmode_inprogress = false;
425 RT_TRACE(rtlpriv, COMP_SCAN, DBG_TRACE, "<==\n");
426}
427
428void _rtl92ce_phy_lc_calibrate(struct ieee80211_hw *hw, bool is2t)
429{
430 u8 tmpreg;
431 u32 rf_a_mode = 0, rf_b_mode = 0, lc_cal;
432 struct rtl_priv *rtlpriv = rtl_priv(hw);
433
434 tmpreg = rtl_read_byte(rtlpriv, 0xd03);
435
436 if ((tmpreg & 0x70) != 0)
437 rtl_write_byte(rtlpriv, 0xd03, tmpreg & 0x8F);
438 else
439 rtl_write_byte(rtlpriv, REG_TXPAUSE, 0xFF);
440
441 if ((tmpreg & 0x70) != 0) {
442 rf_a_mode = rtl_get_rfreg(hw, RF90_PATH_A, 0x00, MASK12BITS);
443
444 if (is2t)
445 rf_b_mode = rtl_get_rfreg(hw, RF90_PATH_B, 0x00,
446 MASK12BITS);
447
448 rtl_set_rfreg(hw, RF90_PATH_A, 0x00, MASK12BITS,
449 (rf_a_mode & 0x8FFFF) | 0x10000);
450
451 if (is2t)
452 rtl_set_rfreg(hw, RF90_PATH_B, 0x00, MASK12BITS,
453 (rf_b_mode & 0x8FFFF) | 0x10000);
454 }
455 lc_cal = rtl_get_rfreg(hw, RF90_PATH_A, 0x18, MASK12BITS);
456
457 rtl_set_rfreg(hw, RF90_PATH_A, 0x18, MASK12BITS, lc_cal | 0x08000);
458
459 mdelay(100);
460
461 if ((tmpreg & 0x70) != 0) {
462 rtl_write_byte(rtlpriv, 0xd03, tmpreg);
463 rtl_set_rfreg(hw, RF90_PATH_A, 0x00, MASK12BITS, rf_a_mode);
464
465 if (is2t)
466 rtl_set_rfreg(hw, RF90_PATH_B, 0x00, MASK12BITS,
467 rf_b_mode);
468 } else {
469 rtl_write_byte(rtlpriv, REG_TXPAUSE, 0x00);
470 }
471}
472
473static void _rtl92ce_phy_set_rf_sleep(struct ieee80211_hw *hw)
474{
475 u32 u4b_tmp;
476 u8 delay = 5;
477 struct rtl_priv *rtlpriv = rtl_priv(hw);
478
479 rtl_write_byte(rtlpriv, REG_TXPAUSE, 0xFF);
480 rtl_set_rfreg(hw, RF90_PATH_A, 0x00, RFREG_OFFSET_MASK, 0x00);
481 rtl_write_byte(rtlpriv, REG_APSD_CTRL, 0x40);
482 u4b_tmp = rtl_get_rfreg(hw, RF90_PATH_A, 0, RFREG_OFFSET_MASK);
483 while (u4b_tmp != 0 && delay > 0) {
484 rtl_write_byte(rtlpriv, REG_APSD_CTRL, 0x0);
485 rtl_set_rfreg(hw, RF90_PATH_A, 0x00, RFREG_OFFSET_MASK, 0x00);
486 rtl_write_byte(rtlpriv, REG_APSD_CTRL, 0x40);
487 u4b_tmp = rtl_get_rfreg(hw, RF90_PATH_A, 0, RFREG_OFFSET_MASK);
488 delay--;
489 }
490 if (delay == 0) {
491 rtl_write_byte(rtlpriv, REG_APSD_CTRL, 0x00);
492 rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE2);
493 rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE3);
494 rtl_write_byte(rtlpriv, REG_TXPAUSE, 0x00);
495 RT_TRACE(rtlpriv, COMP_POWER, DBG_TRACE,
496 "Switch RF timeout !!!\n");
497 return;
498 }
499 rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE2);
500 rtl_write_byte(rtlpriv, REG_SPS0_CTRL, 0x22);
501}
502
503static bool _rtl92ce_phy_set_rf_power_state(struct ieee80211_hw *hw,
504 enum rf_pwrstate rfpwr_state)
505{
506 struct rtl_priv *rtlpriv = rtl_priv(hw);
507 struct rtl_pci_priv *pcipriv = rtl_pcipriv(hw);
508 struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
509 struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
510 bool bresult = true;
511 u8 i, queue_id;
512 struct rtl8192_tx_ring *ring = NULL;
513
514 switch (rfpwr_state) {
515 case ERFON:{
516 if ((ppsc->rfpwr_state == ERFOFF) &&
517 RT_IN_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_HALT_NIC)) {
518 bool rtstatus;
519 u32 InitializeCount = 0;
520 do {
521 InitializeCount++;
522 RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG,
523 "IPS Set eRf nic enable\n");
524 rtstatus = rtl_ps_enable_nic(hw);
525 } while (!rtstatus && (InitializeCount < 10));
526 RT_CLEAR_PS_LEVEL(ppsc,
527 RT_RF_OFF_LEVL_HALT_NIC);
528 } else {
529 RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG,
530 "Set ERFON sleeped:%d ms\n",
531 jiffies_to_msecs(jiffies -
532 ppsc->
533 last_sleep_jiffies));
534 ppsc->last_awake_jiffies = jiffies;
535 rtl92ce_phy_set_rf_on(hw);
536 }
537 if (mac->link_state == MAC80211_LINKED) {
538 rtlpriv->cfg->ops->led_control(hw,
539 LED_CTL_LINK);
540 } else {
541 rtlpriv->cfg->ops->led_control(hw,
542 LED_CTL_NO_LINK);
543 }
544 break;
545 }
546 case ERFOFF:{
547 if (ppsc->reg_rfps_level & RT_RF_OFF_LEVL_HALT_NIC) {
548 RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG,
549 "IPS Set eRf nic disable\n");
550 rtl_ps_disable_nic(hw);
551 RT_SET_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_HALT_NIC);
552 } else {
553 if (ppsc->rfoff_reason == RF_CHANGE_BY_IPS) {
554 rtlpriv->cfg->ops->led_control(hw,
555 LED_CTL_NO_LINK);
556 } else {
557 rtlpriv->cfg->ops->led_control(hw,
558 LED_CTL_POWER_OFF);
559 }
560 }
561 break;
562 }
563 case ERFSLEEP:{
564 if (ppsc->rfpwr_state == ERFOFF)
565 return false;
566 for (queue_id = 0, i = 0;
567 queue_id < RTL_PCI_MAX_TX_QUEUE_COUNT;) {
568 ring = &pcipriv->dev.tx_ring[queue_id];
569 if (skb_queue_len(&ring->queue) == 0) {
570 queue_id++;
571 continue;
572 } else {
573 RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
574 "eRf Off/Sleep: %d times TcbBusyQueue[%d] =%d before doze!\n",
575 i + 1, queue_id,
576 skb_queue_len(&ring->queue));
577
578 udelay(10);
579 i++;
580 }
581 if (i >= MAX_DOZE_WAITING_TIMES_9x) {
582 RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
583 "ERFSLEEP: %d times TcbBusyQueue[%d] = %d !\n",
584 MAX_DOZE_WAITING_TIMES_9x,
585 queue_id,
586 skb_queue_len(&ring->queue));
587 break;
588 }
589 }
590 RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG,
591 "Set ERFSLEEP awaked:%d ms\n",
592 jiffies_to_msecs(jiffies -
593 ppsc->last_awake_jiffies));
594 ppsc->last_sleep_jiffies = jiffies;
595 _rtl92ce_phy_set_rf_sleep(hw);
596 break;
597 }
598 default:
599 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
600 "switch case not processed\n");
601 bresult = false;
602 break;
603 }
604 if (bresult)
605 ppsc->rfpwr_state = rfpwr_state;
606 return bresult;
607}
608
609bool rtl92c_phy_set_rf_power_state(struct ieee80211_hw *hw,
610 enum rf_pwrstate rfpwr_state)
611{
612 struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
613
614 bool bresult = false;
615
616 if (rfpwr_state == ppsc->rfpwr_state)
617 return bresult;
618 bresult = _rtl92ce_phy_set_rf_power_state(hw, rfpwr_state);
619 return bresult;
620}