1 | // SPDX-License-Identifier: GPL-2.0 |
2 | /* Copyright(c) 2009-2012 Realtek Corporation.*/ |
3 | |
4 | #include "../wifi.h" |
5 | #include "../pci.h" |
6 | #include "../ps.h" |
7 | #include "../core.h" |
8 | #include "reg.h" |
9 | #include "def.h" |
10 | #include "phy.h" |
11 | #include "../rtl8192c/phy_common.h" |
12 | #include "rf.h" |
13 | #include "dm.h" |
14 | #include "../rtl8192c/dm_common.h" |
15 | #include "../rtl8192c/fw_common.h" |
16 | #include "table.h" |
17 | |
18 | u32 rtl92cu_phy_query_rf_reg(struct ieee80211_hw *hw, |
19 | enum radio_path rfpath, u32 regaddr, u32 bitmask) |
20 | { |
21 | struct rtl_priv *rtlpriv = rtl_priv(hw); |
22 | u32 original_value, readback_value, bitshift; |
23 | struct rtl_phy *rtlphy = &(rtlpriv->phy); |
24 | |
25 | rtl_dbg(rtlpriv, COMP_RF, DBG_TRACE, |
26 | "regaddr(%#x), rfpath(%#x), bitmask(%#x)\n" , |
27 | regaddr, rfpath, bitmask); |
28 | if (rtlphy->rf_mode != RF_OP_BY_FW) { |
29 | original_value = _rtl92c_phy_rf_serial_read(hw, |
30 | rfpath, offset: regaddr); |
31 | } else { |
32 | original_value = _rtl92c_phy_fw_rf_serial_read(hw, |
33 | rfpath, offset: regaddr); |
34 | } |
35 | bitshift = calculate_bit_shift(bitmask); |
36 | readback_value = (original_value & bitmask) >> bitshift; |
37 | rtl_dbg(rtlpriv, COMP_RF, DBG_TRACE, |
38 | "regaddr(%#x), rfpath(%#x), bitmask(%#x), original_value(%#x)\n" , |
39 | regaddr, rfpath, bitmask, original_value); |
40 | return readback_value; |
41 | } |
42 | |
43 | void rtl92cu_phy_set_rf_reg(struct ieee80211_hw *hw, |
44 | enum radio_path rfpath, |
45 | u32 regaddr, u32 bitmask, u32 data) |
46 | { |
47 | struct rtl_priv *rtlpriv = rtl_priv(hw); |
48 | struct rtl_phy *rtlphy = &(rtlpriv->phy); |
49 | u32 original_value, bitshift; |
50 | |
51 | rtl_dbg(rtlpriv, COMP_RF, DBG_TRACE, |
52 | "regaddr(%#x), bitmask(%#x), data(%#x), rfpath(%#x)\n" , |
53 | regaddr, bitmask, data, rfpath); |
54 | if (rtlphy->rf_mode != RF_OP_BY_FW) { |
55 | if (bitmask != RFREG_OFFSET_MASK) { |
56 | original_value = _rtl92c_phy_rf_serial_read(hw, |
57 | rfpath, |
58 | offset: regaddr); |
59 | bitshift = calculate_bit_shift(bitmask); |
60 | data = |
61 | ((original_value & (~bitmask)) | |
62 | (data << bitshift)); |
63 | } |
64 | _rtl92c_phy_rf_serial_write(hw, rfpath, offset: regaddr, data); |
65 | } else { |
66 | if (bitmask != RFREG_OFFSET_MASK) { |
67 | original_value = _rtl92c_phy_fw_rf_serial_read(hw, |
68 | rfpath, |
69 | offset: regaddr); |
70 | bitshift = calculate_bit_shift(bitmask); |
71 | data = |
72 | ((original_value & (~bitmask)) | |
73 | (data << bitshift)); |
74 | } |
75 | _rtl92c_phy_fw_rf_serial_write(hw, rfpath, offset: regaddr, data); |
76 | } |
77 | rtl_dbg(rtlpriv, COMP_RF, DBG_TRACE, |
78 | "regaddr(%#x), bitmask(%#x), data(%#x), rfpath(%#x)\n" , |
79 | regaddr, bitmask, data, rfpath); |
80 | } |
81 | |
82 | bool rtl92cu_phy_mac_config(struct ieee80211_hw *hw) |
83 | { |
84 | bool rtstatus; |
85 | |
86 | rtstatus = _rtl92cu_phy_config_mac_with_headerfile(hw); |
87 | return rtstatus; |
88 | } |
89 | |
90 | bool rtl92cu_phy_bb_config(struct ieee80211_hw *hw) |
91 | { |
92 | bool rtstatus = true; |
93 | struct rtl_priv *rtlpriv = rtl_priv(hw); |
94 | u16 regval; |
95 | u32 regval32; |
96 | u8 b_reg_hwparafile = 1; |
97 | |
98 | _rtl92c_phy_init_bb_rf_register_definition(hw); |
99 | regval = rtl_read_word(rtlpriv, REG_SYS_FUNC_EN); |
100 | rtl_write_word(rtlpriv, REG_SYS_FUNC_EN, val16: regval | BIT(13) | |
101 | BIT(0) | BIT(1)); |
102 | rtl_write_byte(rtlpriv, REG_AFE_PLL_CTRL, val8: 0x83); |
103 | rtl_write_byte(rtlpriv, REG_AFE_PLL_CTRL + 1, val8: 0xdb); |
104 | rtl_write_byte(rtlpriv, REG_RF_CTRL, RF_EN | RF_RSTB | RF_SDMRSTB); |
105 | rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, FEN_USBA | FEN_USBD | |
106 | FEN_BB_GLB_RSTN | FEN_BBRSTB); |
107 | regval32 = rtl_read_dword(rtlpriv, addr: 0x87c); |
108 | rtl_write_dword(rtlpriv, addr: 0x87c, val32: regval32 & (~BIT(31))); |
109 | rtl_write_byte(rtlpriv, REG_LDOHCI12_CTRL, val8: 0x0f); |
110 | rtl_write_byte(rtlpriv, REG_AFE_XTAL_CTRL + 1, val8: 0x80); |
111 | if (b_reg_hwparafile == 1) |
112 | rtstatus = _rtl92c_phy_bb8192c_config_parafile(hw); |
113 | return rtstatus; |
114 | } |
115 | |
116 | bool (struct ieee80211_hw *hw) |
117 | { |
118 | struct rtl_priv *rtlpriv = rtl_priv(hw); |
119 | struct rtl_phy *rtlphy = &(rtlpriv->phy); |
120 | u32 i; |
121 | u32 arraylength; |
122 | u32 *ptrarray; |
123 | |
124 | rtl_dbg(rtlpriv, COMP_INIT, DBG_TRACE, "Read Rtl819XMACPHY_ARRAY\n" ); |
125 | arraylength = rtlphy->hwparam_tables[MAC_REG].length ; |
126 | ptrarray = rtlphy->hwparam_tables[MAC_REG].pdata; |
127 | rtl_dbg(rtlpriv, COMP_INIT, DBG_TRACE, "Img:RTL8192CUMAC_2T_ARRAY\n" ); |
128 | for (i = 0; i < arraylength; i = i + 2) |
129 | rtl_write_byte(rtlpriv, addr: ptrarray[i], val8: (u8) ptrarray[i + 1]); |
130 | return true; |
131 | } |
132 | |
133 | bool (struct ieee80211_hw *hw, |
134 | u8 configtype) |
135 | { |
136 | int i; |
137 | u32 *phy_regarray_table; |
138 | u32 *agctab_array_table; |
139 | u16 phy_reg_arraylen, agctab_arraylen; |
140 | struct rtl_priv *rtlpriv = rtl_priv(hw); |
141 | struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); |
142 | struct rtl_phy *rtlphy = &(rtlpriv->phy); |
143 | |
144 | if (IS_92C_SERIAL(rtlhal->version)) { |
145 | agctab_arraylen = rtlphy->hwparam_tables[AGCTAB_2T].length; |
146 | agctab_array_table = rtlphy->hwparam_tables[AGCTAB_2T].pdata; |
147 | phy_reg_arraylen = rtlphy->hwparam_tables[PHY_REG_2T].length; |
148 | phy_regarray_table = rtlphy->hwparam_tables[PHY_REG_2T].pdata; |
149 | } else { |
150 | agctab_arraylen = rtlphy->hwparam_tables[AGCTAB_1T].length; |
151 | agctab_array_table = rtlphy->hwparam_tables[AGCTAB_1T].pdata; |
152 | phy_reg_arraylen = rtlphy->hwparam_tables[PHY_REG_1T].length; |
153 | phy_regarray_table = rtlphy->hwparam_tables[PHY_REG_1T].pdata; |
154 | } |
155 | if (configtype == BASEBAND_CONFIG_PHY_REG) { |
156 | for (i = 0; i < phy_reg_arraylen; i = i + 2) { |
157 | rtl_addr_delay(addr: phy_regarray_table[i]); |
158 | rtl_set_bbreg(hw, regaddr: phy_regarray_table[i], MASKDWORD, |
159 | data: phy_regarray_table[i + 1]); |
160 | udelay(1); |
161 | rtl_dbg(rtlpriv, COMP_INIT, DBG_TRACE, |
162 | "The phy_regarray_table[0] is %x Rtl819XPHY_REGARRAY[1] is %x\n" , |
163 | phy_regarray_table[i], |
164 | phy_regarray_table[i + 1]); |
165 | } |
166 | } else if (configtype == BASEBAND_CONFIG_AGC_TAB) { |
167 | for (i = 0; i < agctab_arraylen; i = i + 2) { |
168 | rtl_set_bbreg(hw, regaddr: agctab_array_table[i], MASKDWORD, |
169 | data: agctab_array_table[i + 1]); |
170 | udelay(1); |
171 | rtl_dbg(rtlpriv, COMP_INIT, DBG_TRACE, |
172 | "The agctab_array_table[0] is %x Rtl819XPHY_REGARRAY[1] is %x\n" , |
173 | agctab_array_table[i], |
174 | agctab_array_table[i + 1]); |
175 | } |
176 | } |
177 | return true; |
178 | } |
179 | |
180 | bool (struct ieee80211_hw *hw, |
181 | u8 configtype) |
182 | { |
183 | struct rtl_priv *rtlpriv = rtl_priv(hw); |
184 | struct rtl_phy *rtlphy = &(rtlpriv->phy); |
185 | int i; |
186 | u32 *phy_regarray_table_pg; |
187 | u16 phy_regarray_pg_len; |
188 | |
189 | rtlphy->pwrgroup_cnt = 0; |
190 | phy_regarray_pg_len = rtlphy->hwparam_tables[PHY_REG_PG].length; |
191 | phy_regarray_table_pg = rtlphy->hwparam_tables[PHY_REG_PG].pdata; |
192 | if (configtype == BASEBAND_CONFIG_PHY_REG) { |
193 | for (i = 0; i < phy_regarray_pg_len; i = i + 3) { |
194 | rtl_addr_delay(addr: phy_regarray_table_pg[i]); |
195 | _rtl92c_store_pwrindex_diffrate_offset(hw, |
196 | regaddr: phy_regarray_table_pg[i], |
197 | bitmask: phy_regarray_table_pg[i + 1], |
198 | data: phy_regarray_table_pg[i + 2]); |
199 | } |
200 | } else { |
201 | rtl_dbg(rtlpriv, COMP_SEND, DBG_TRACE, |
202 | "configtype != BaseBand_Config_PHY_REG\n" ); |
203 | } |
204 | return true; |
205 | } |
206 | |
207 | bool (struct ieee80211_hw *hw, |
208 | enum radio_path rfpath) |
209 | { |
210 | int i; |
211 | u32 *radioa_array_table; |
212 | u32 *radiob_array_table; |
213 | u16 radioa_arraylen, radiob_arraylen; |
214 | struct rtl_priv *rtlpriv = rtl_priv(hw); |
215 | struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); |
216 | struct rtl_phy *rtlphy = &(rtlpriv->phy); |
217 | |
218 | if (IS_92C_SERIAL(rtlhal->version)) { |
219 | radioa_arraylen = rtlphy->hwparam_tables[RADIOA_2T].length; |
220 | radioa_array_table = rtlphy->hwparam_tables[RADIOA_2T].pdata; |
221 | radiob_arraylen = rtlphy->hwparam_tables[RADIOB_2T].length; |
222 | radiob_array_table = rtlphy->hwparam_tables[RADIOB_2T].pdata; |
223 | rtl_dbg(rtlpriv, COMP_INIT, DBG_TRACE, |
224 | "Radio_A:RTL8192CURADIOA_2TARRAY\n" ); |
225 | rtl_dbg(rtlpriv, COMP_INIT, DBG_TRACE, |
226 | "Radio_B:RTL8192CU_RADIOB_2TARRAY\n" ); |
227 | } else { |
228 | radioa_arraylen = rtlphy->hwparam_tables[RADIOA_1T].length; |
229 | radioa_array_table = rtlphy->hwparam_tables[RADIOA_1T].pdata; |
230 | radiob_arraylen = rtlphy->hwparam_tables[RADIOB_1T].length; |
231 | radiob_array_table = rtlphy->hwparam_tables[RADIOB_1T].pdata; |
232 | rtl_dbg(rtlpriv, COMP_INIT, DBG_TRACE, |
233 | "Radio_A:RTL8192CU_RADIOA_1TARRAY\n" ); |
234 | rtl_dbg(rtlpriv, COMP_INIT, DBG_TRACE, |
235 | "Radio_B:RTL8192CU_RADIOB_1TARRAY\n" ); |
236 | } |
237 | rtl_dbg(rtlpriv, COMP_INIT, DBG_TRACE, "Radio No %x\n" , rfpath); |
238 | switch (rfpath) { |
239 | case RF90_PATH_A: |
240 | for (i = 0; i < radioa_arraylen; i = i + 2) { |
241 | rtl_rfreg_delay(hw, rfpath, addr: radioa_array_table[i], |
242 | RFREG_OFFSET_MASK, |
243 | data: radioa_array_table[i + 1]); |
244 | } |
245 | break; |
246 | case RF90_PATH_B: |
247 | for (i = 0; i < radiob_arraylen; i = i + 2) { |
248 | rtl_rfreg_delay(hw, rfpath, addr: radiob_array_table[i], |
249 | RFREG_OFFSET_MASK, |
250 | data: radiob_array_table[i + 1]); |
251 | } |
252 | break; |
253 | case RF90_PATH_C: |
254 | case RF90_PATH_D: |
255 | pr_err("switch case %#x not processed\n" , rfpath); |
256 | break; |
257 | default: |
258 | break; |
259 | } |
260 | return true; |
261 | } |
262 | |
263 | void rtl92cu_phy_set_bw_mode_callback(struct ieee80211_hw *hw) |
264 | { |
265 | struct rtl_priv *rtlpriv = rtl_priv(hw); |
266 | struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); |
267 | struct rtl_phy *rtlphy = &(rtlpriv->phy); |
268 | struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); |
269 | u8 reg_bw_opmode; |
270 | u8 reg_prsr_rsc; |
271 | |
272 | rtl_dbg(rtlpriv, COMP_SCAN, DBG_TRACE, "Switch to %s bandwidth\n" , |
273 | rtlphy->current_chan_bw == HT_CHANNEL_WIDTH_20 ? |
274 | "20MHz" : "40MHz" ); |
275 | if (is_hal_stop(rtlhal)) { |
276 | rtlphy->set_bwmode_inprogress = false; |
277 | return; |
278 | } |
279 | reg_bw_opmode = rtl_read_byte(rtlpriv, REG_BWOPMODE); |
280 | reg_prsr_rsc = rtl_read_byte(rtlpriv, REG_RRSR + 2); |
281 | switch (rtlphy->current_chan_bw) { |
282 | case HT_CHANNEL_WIDTH_20: |
283 | reg_bw_opmode |= BW_OPMODE_20MHZ; |
284 | rtl_write_byte(rtlpriv, REG_BWOPMODE, val8: reg_bw_opmode); |
285 | break; |
286 | case HT_CHANNEL_WIDTH_20_40: |
287 | reg_bw_opmode &= ~BW_OPMODE_20MHZ; |
288 | rtl_write_byte(rtlpriv, REG_BWOPMODE, val8: reg_bw_opmode); |
289 | reg_prsr_rsc = |
290 | (reg_prsr_rsc & 0x90) | (mac->cur_40_prime_sc << 5); |
291 | rtl_write_byte(rtlpriv, REG_RRSR + 2, val8: reg_prsr_rsc); |
292 | break; |
293 | default: |
294 | pr_err("unknown bandwidth: %#X\n" , |
295 | rtlphy->current_chan_bw); |
296 | break; |
297 | } |
298 | switch (rtlphy->current_chan_bw) { |
299 | case HT_CHANNEL_WIDTH_20: |
300 | rtl_set_bbreg(hw, RFPGA0_RFMOD, BRFMOD, data: 0x0); |
301 | rtl_set_bbreg(hw, RFPGA1_RFMOD, BRFMOD, data: 0x0); |
302 | rtl_set_bbreg(hw, RFPGA0_ANALOGPARAMETER2, BIT(10), data: 1); |
303 | break; |
304 | case HT_CHANNEL_WIDTH_20_40: |
305 | rtl_set_bbreg(hw, RFPGA0_RFMOD, BRFMOD, data: 0x1); |
306 | rtl_set_bbreg(hw, RFPGA1_RFMOD, BRFMOD, data: 0x1); |
307 | rtl_set_bbreg(hw, RCCK0_SYSTEM, BCCK_SIDEBAND, |
308 | data: (mac->cur_40_prime_sc >> 1)); |
309 | rtl_set_bbreg(hw, ROFDM1_LSTF, bitmask: 0xC00, data: mac->cur_40_prime_sc); |
310 | rtl_set_bbreg(hw, RFPGA0_ANALOGPARAMETER2, BIT(10), data: 0); |
311 | rtl_set_bbreg(hw, regaddr: 0x818, bitmask: (BIT(26) | BIT(27)), |
312 | data: (mac->cur_40_prime_sc == |
313 | HAL_PRIME_CHNL_OFFSET_LOWER) ? 2 : 1); |
314 | break; |
315 | default: |
316 | pr_err("unknown bandwidth: %#X\n" , |
317 | rtlphy->current_chan_bw); |
318 | break; |
319 | } |
320 | rtl92cu_phy_rf6052_set_bandwidth(hw, bandwidth: rtlphy->current_chan_bw); |
321 | rtlphy->set_bwmode_inprogress = false; |
322 | rtl_dbg(rtlpriv, COMP_SCAN, DBG_TRACE, "<==\n" ); |
323 | } |
324 | |
325 | void rtl92cu_bb_block_on(struct ieee80211_hw *hw) |
326 | { |
327 | struct rtl_priv *rtlpriv = rtl_priv(hw); |
328 | |
329 | mutex_lock(&rtlpriv->io.bb_mutex); |
330 | rtl_set_bbreg(hw, RFPGA0_RFMOD, BCCKEN, data: 0x1); |
331 | rtl_set_bbreg(hw, RFPGA0_RFMOD, BOFDMEN, data: 0x1); |
332 | mutex_unlock(lock: &rtlpriv->io.bb_mutex); |
333 | } |
334 | |
335 | void _rtl92cu_phy_lc_calibrate(struct ieee80211_hw *hw, bool is2t) |
336 | { |
337 | u8 tmpreg; |
338 | u32 rf_a_mode = 0, rf_b_mode = 0, lc_cal; |
339 | struct rtl_priv *rtlpriv = rtl_priv(hw); |
340 | |
341 | tmpreg = rtl_read_byte(rtlpriv, addr: 0xd03); |
342 | |
343 | if ((tmpreg & 0x70) != 0) |
344 | rtl_write_byte(rtlpriv, addr: 0xd03, val8: tmpreg & 0x8F); |
345 | else |
346 | rtl_write_byte(rtlpriv, REG_TXPAUSE, val8: 0xFF); |
347 | |
348 | if ((tmpreg & 0x70) != 0) { |
349 | rf_a_mode = rtl_get_rfreg(hw, rfpath: RF90_PATH_A, regaddr: 0x00, MASK12BITS); |
350 | if (is2t) |
351 | rf_b_mode = rtl_get_rfreg(hw, rfpath: RF90_PATH_B, regaddr: 0x00, |
352 | MASK12BITS); |
353 | rtl_set_rfreg(hw, rfpath: RF90_PATH_A, regaddr: 0x00, MASK12BITS, |
354 | data: (rf_a_mode & 0x8FFFF) | 0x10000); |
355 | if (is2t) |
356 | rtl_set_rfreg(hw, rfpath: RF90_PATH_B, regaddr: 0x00, MASK12BITS, |
357 | data: (rf_b_mode & 0x8FFFF) | 0x10000); |
358 | } |
359 | lc_cal = rtl_get_rfreg(hw, rfpath: RF90_PATH_A, regaddr: 0x18, MASK12BITS); |
360 | rtl_set_rfreg(hw, rfpath: RF90_PATH_A, regaddr: 0x18, MASK12BITS, data: lc_cal | 0x08000); |
361 | mdelay(100); |
362 | if ((tmpreg & 0x70) != 0) { |
363 | rtl_write_byte(rtlpriv, addr: 0xd03, val8: tmpreg); |
364 | rtl_set_rfreg(hw, rfpath: RF90_PATH_A, regaddr: 0x00, MASK12BITS, data: rf_a_mode); |
365 | if (is2t) |
366 | rtl_set_rfreg(hw, rfpath: RF90_PATH_B, regaddr: 0x00, MASK12BITS, |
367 | data: rf_b_mode); |
368 | } else { |
369 | rtl_write_byte(rtlpriv, REG_TXPAUSE, val8: 0x00); |
370 | } |
371 | } |
372 | |
373 | static bool _rtl92cu_phy_set_rf_power_state(struct ieee80211_hw *hw, |
374 | enum rf_pwrstate rfpwr_state) |
375 | { |
376 | struct rtl_priv *rtlpriv = rtl_priv(hw); |
377 | struct rtl_pci_priv *pcipriv = rtl_pcipriv(hw); |
378 | struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); |
379 | struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); |
380 | bool bresult = true; |
381 | u8 i, queue_id; |
382 | struct rtl8192_tx_ring *ring = NULL; |
383 | |
384 | switch (rfpwr_state) { |
385 | case ERFON: |
386 | if ((ppsc->rfpwr_state == ERFOFF) && |
387 | RT_IN_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_HALT_NIC)) { |
388 | bool rtstatus; |
389 | u32 init_count = 0; |
390 | |
391 | do { |
392 | init_count++; |
393 | rtl_dbg(rtlpriv, COMP_RF, DBG_DMESG, |
394 | "IPS Set eRf nic enable\n" ); |
395 | rtstatus = rtl_ps_enable_nic(hw); |
396 | } while (!rtstatus && (init_count < 10)); |
397 | RT_CLEAR_PS_LEVEL(ppsc, |
398 | RT_RF_OFF_LEVL_HALT_NIC); |
399 | } else { |
400 | rtl_dbg(rtlpriv, COMP_RF, DBG_DMESG, |
401 | "Set ERFON slept:%d ms\n" , |
402 | jiffies_to_msecs(jiffies - |
403 | ppsc->last_sleep_jiffies)); |
404 | ppsc->last_awake_jiffies = jiffies; |
405 | rtl92ce_phy_set_rf_on(hw); |
406 | } |
407 | if (mac->link_state == MAC80211_LINKED) { |
408 | rtlpriv->cfg->ops->led_control(hw, |
409 | LED_CTL_LINK); |
410 | } else { |
411 | rtlpriv->cfg->ops->led_control(hw, |
412 | LED_CTL_NO_LINK); |
413 | } |
414 | break; |
415 | case ERFOFF: |
416 | for (queue_id = 0, i = 0; |
417 | queue_id < RTL_PCI_MAX_TX_QUEUE_COUNT;) { |
418 | ring = &pcipriv->dev.tx_ring[queue_id]; |
419 | if (skb_queue_len(list_: &ring->queue) == 0 || |
420 | queue_id == BEACON_QUEUE) { |
421 | queue_id++; |
422 | continue; |
423 | } else { |
424 | rtl_dbg(rtlpriv, COMP_ERR, DBG_WARNING, |
425 | "eRf Off/Sleep: %d times TcbBusyQueue[%d] =%d before doze!\n" , |
426 | i + 1, |
427 | queue_id, |
428 | skb_queue_len(&ring->queue)); |
429 | udelay(10); |
430 | i++; |
431 | } |
432 | if (i >= MAX_DOZE_WAITING_TIMES_9x) { |
433 | rtl_dbg(rtlpriv, COMP_ERR, DBG_WARNING, |
434 | "ERFOFF: %d times TcbBusyQueue[%d] = %d !\n" , |
435 | MAX_DOZE_WAITING_TIMES_9x, |
436 | queue_id, |
437 | skb_queue_len(&ring->queue)); |
438 | break; |
439 | } |
440 | } |
441 | if (ppsc->reg_rfps_level & RT_RF_OFF_LEVL_HALT_NIC) { |
442 | rtl_dbg(rtlpriv, COMP_RF, DBG_DMESG, |
443 | "IPS Set eRf nic disable\n" ); |
444 | rtl_ps_disable_nic(hw); |
445 | RT_SET_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_HALT_NIC); |
446 | } else { |
447 | if (ppsc->rfoff_reason == RF_CHANGE_BY_IPS) { |
448 | rtlpriv->cfg->ops->led_control(hw, |
449 | LED_CTL_NO_LINK); |
450 | } else { |
451 | rtlpriv->cfg->ops->led_control(hw, |
452 | LED_CTL_POWER_OFF); |
453 | } |
454 | } |
455 | break; |
456 | case ERFSLEEP: |
457 | if (ppsc->rfpwr_state == ERFOFF) |
458 | return false; |
459 | for (queue_id = 0, i = 0; |
460 | queue_id < RTL_PCI_MAX_TX_QUEUE_COUNT;) { |
461 | ring = &pcipriv->dev.tx_ring[queue_id]; |
462 | if (skb_queue_len(list_: &ring->queue) == 0) { |
463 | queue_id++; |
464 | continue; |
465 | } else { |
466 | rtl_dbg(rtlpriv, COMP_ERR, DBG_WARNING, |
467 | "eRf Off/Sleep: %d times TcbBusyQueue[%d] =%d before doze!\n" , |
468 | i + 1, queue_id, |
469 | skb_queue_len(&ring->queue)); |
470 | udelay(10); |
471 | i++; |
472 | } |
473 | if (i >= MAX_DOZE_WAITING_TIMES_9x) { |
474 | rtl_dbg(rtlpriv, COMP_ERR, DBG_WARNING, |
475 | "ERFSLEEP: %d times TcbBusyQueue[%d] = %d !\n" , |
476 | MAX_DOZE_WAITING_TIMES_9x, |
477 | queue_id, |
478 | skb_queue_len(&ring->queue)); |
479 | break; |
480 | } |
481 | } |
482 | rtl_dbg(rtlpriv, COMP_RF, DBG_DMESG, |
483 | "Set ERFSLEEP awaked:%d ms\n" , |
484 | jiffies_to_msecs(jiffies - ppsc->last_awake_jiffies)); |
485 | ppsc->last_sleep_jiffies = jiffies; |
486 | _rtl92c_phy_set_rf_sleep(hw); |
487 | break; |
488 | default: |
489 | pr_err("switch case %#x not processed\n" , |
490 | rfpwr_state); |
491 | bresult = false; |
492 | break; |
493 | } |
494 | if (bresult) |
495 | ppsc->rfpwr_state = rfpwr_state; |
496 | return bresult; |
497 | } |
498 | |
499 | bool rtl92cu_phy_set_rf_power_state(struct ieee80211_hw *hw, |
500 | enum rf_pwrstate rfpwr_state) |
501 | { |
502 | struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); |
503 | bool bresult = false; |
504 | |
505 | if (rfpwr_state == ppsc->rfpwr_state) |
506 | return bresult; |
507 | bresult = _rtl92cu_phy_set_rf_power_state(hw, rfpwr_state); |
508 | return bresult; |
509 | } |
510 | |