1 | // SPDX-License-Identifier: GPL-2.0 |
2 | /* |
3 | * Copyright(c) 2008 - 2010 Realtek Corporation. All rights reserved. |
4 | * |
5 | * Contact Information: wlanfae <wlanfae@realtek.com> |
6 | */ |
7 | #include <linux/bitops.h> |
8 | #include "rtl_core.h" |
9 | #include "r8192E_hw.h" |
10 | #include "r8192E_phyreg.h" |
11 | #include "r8190P_rtl8256.h" |
12 | #include "r8192E_phy.h" |
13 | #include "rtl_dm.h" |
14 | |
15 | #include "table.h" |
16 | |
17 | /*************************Define local function prototype**********************/ |
18 | |
19 | static u32 _rtl92e_phy_rf_fw_read(struct net_device *dev, |
20 | enum rf90_radio_path eRFPath, u32 Offset); |
21 | static void _rtl92e_phy_rf_fw_write(struct net_device *dev, |
22 | enum rf90_radio_path eRFPath, u32 Offset, |
23 | u32 Data); |
24 | |
25 | static u32 _rtl92e_calculate_bit_shift(u32 dwBitMask) |
26 | { |
27 | if (!dwBitMask) |
28 | return 32; |
29 | return ffs(dwBitMask) - 1; |
30 | } |
31 | |
32 | void rtl92e_set_bb_reg(struct net_device *dev, u32 dwRegAddr, u32 dwBitMask, |
33 | u32 dwData) |
34 | { |
35 | u32 OriginalValue, BitShift, NewValue; |
36 | |
37 | if (dwBitMask != bMaskDWord) { |
38 | OriginalValue = rtl92e_readl(dev, x: dwRegAddr); |
39 | BitShift = _rtl92e_calculate_bit_shift(dwBitMask); |
40 | NewValue = (OriginalValue & ~dwBitMask) | (dwData << BitShift); |
41 | rtl92e_writel(dev, x: dwRegAddr, y: NewValue); |
42 | } else { |
43 | rtl92e_writel(dev, x: dwRegAddr, y: dwData); |
44 | } |
45 | } |
46 | |
47 | u32 rtl92e_get_bb_reg(struct net_device *dev, u32 dwRegAddr, u32 dwBitMask) |
48 | { |
49 | u32 OriginalValue, BitShift; |
50 | |
51 | OriginalValue = rtl92e_readl(dev, x: dwRegAddr); |
52 | BitShift = _rtl92e_calculate_bit_shift(dwBitMask); |
53 | |
54 | return (OriginalValue & dwBitMask) >> BitShift; |
55 | } |
56 | |
57 | static u32 _rtl92e_phy_rf_read(struct net_device *dev, |
58 | enum rf90_radio_path eRFPath, u32 Offset) |
59 | { |
60 | struct r8192_priv *priv = rtllib_priv(dev); |
61 | u32 ret = 0; |
62 | u32 NewOffset = 0; |
63 | struct bb_reg_definition *pPhyReg = &priv->phy_reg_def[eRFPath]; |
64 | |
65 | Offset &= 0x3f; |
66 | |
67 | rtl92e_set_bb_reg(dev, rFPGA0_AnalogParameter4, dwBitMask: 0xf00, dwData: 0x0); |
68 | if (Offset >= 31) { |
69 | priv->rf_reg_0value[eRFPath] |= 0x140; |
70 | rtl92e_set_bb_reg(dev, dwRegAddr: pPhyReg->rf3wireOffset, |
71 | bMaskDWord, |
72 | dwData: (priv->rf_reg_0value[eRFPath] << 16)); |
73 | NewOffset = Offset - 30; |
74 | } else if (Offset >= 16) { |
75 | priv->rf_reg_0value[eRFPath] |= 0x100; |
76 | priv->rf_reg_0value[eRFPath] &= (~0x40); |
77 | rtl92e_set_bb_reg(dev, dwRegAddr: pPhyReg->rf3wireOffset, |
78 | bMaskDWord, |
79 | dwData: (priv->rf_reg_0value[eRFPath] << 16)); |
80 | NewOffset = Offset - 15; |
81 | } else { |
82 | NewOffset = Offset; |
83 | } |
84 | rtl92e_set_bb_reg(dev, dwRegAddr: pPhyReg->rfHSSIPara2, bLSSIReadAddress, |
85 | dwData: NewOffset); |
86 | rtl92e_set_bb_reg(dev, dwRegAddr: pPhyReg->rfHSSIPara2, bLSSIReadEdge, dwData: 0x0); |
87 | rtl92e_set_bb_reg(dev, dwRegAddr: pPhyReg->rfHSSIPara2, bLSSIReadEdge, dwData: 0x1); |
88 | |
89 | mdelay(1); |
90 | |
91 | ret = rtl92e_get_bb_reg(dev, dwRegAddr: pPhyReg->rfLSSIReadBack, |
92 | bLSSIReadBackData); |
93 | |
94 | priv->rf_reg_0value[eRFPath] &= 0xebf; |
95 | |
96 | rtl92e_set_bb_reg(dev, dwRegAddr: pPhyReg->rf3wireOffset, bMaskDWord, |
97 | dwData: (priv->rf_reg_0value[eRFPath] << 16)); |
98 | |
99 | rtl92e_set_bb_reg(dev, rFPGA0_AnalogParameter4, dwBitMask: 0x300, dwData: 0x3); |
100 | |
101 | return ret; |
102 | } |
103 | |
104 | static void _rtl92e_phy_rf_write(struct net_device *dev, |
105 | enum rf90_radio_path eRFPath, u32 Offset, |
106 | u32 Data) |
107 | { |
108 | struct r8192_priv *priv = rtllib_priv(dev); |
109 | u32 DataAndAddr = 0, NewOffset = 0; |
110 | struct bb_reg_definition *pPhyReg = &priv->phy_reg_def[eRFPath]; |
111 | |
112 | Offset &= 0x3f; |
113 | |
114 | rtl92e_set_bb_reg(dev, rFPGA0_AnalogParameter4, dwBitMask: 0xf00, dwData: 0x0); |
115 | |
116 | if (Offset >= 31) { |
117 | priv->rf_reg_0value[eRFPath] |= 0x140; |
118 | rtl92e_set_bb_reg(dev, dwRegAddr: pPhyReg->rf3wireOffset, |
119 | bMaskDWord, |
120 | dwData: (priv->rf_reg_0value[eRFPath] << 16)); |
121 | NewOffset = Offset - 30; |
122 | } else if (Offset >= 16) { |
123 | priv->rf_reg_0value[eRFPath] |= 0x100; |
124 | priv->rf_reg_0value[eRFPath] &= (~0x40); |
125 | rtl92e_set_bb_reg(dev, dwRegAddr: pPhyReg->rf3wireOffset, |
126 | bMaskDWord, |
127 | dwData: (priv->rf_reg_0value[eRFPath] << 16)); |
128 | NewOffset = Offset - 15; |
129 | } else { |
130 | NewOffset = Offset; |
131 | } |
132 | |
133 | DataAndAddr = (NewOffset & 0x3f) | (Data << 16); |
134 | |
135 | rtl92e_set_bb_reg(dev, dwRegAddr: pPhyReg->rf3wireOffset, bMaskDWord, dwData: DataAndAddr); |
136 | |
137 | if (Offset == 0x0) |
138 | priv->rf_reg_0value[eRFPath] = Data; |
139 | |
140 | if (Offset != 0) { |
141 | priv->rf_reg_0value[eRFPath] &= 0xebf; |
142 | rtl92e_set_bb_reg(dev, dwRegAddr: pPhyReg->rf3wireOffset, |
143 | bMaskDWord, |
144 | dwData: (priv->rf_reg_0value[eRFPath] << 16)); |
145 | } |
146 | rtl92e_set_bb_reg(dev, rFPGA0_AnalogParameter4, dwBitMask: 0x300, dwData: 0x3); |
147 | } |
148 | |
149 | void rtl92e_set_rf_reg(struct net_device *dev, enum rf90_radio_path eRFPath, |
150 | u32 RegAddr, u32 BitMask, u32 Data) |
151 | { |
152 | struct r8192_priv *priv = rtllib_priv(dev); |
153 | u32 Original_Value, BitShift, New_Value; |
154 | |
155 | if (priv->rtllib->rf_power_state != rf_on && !priv->being_init_adapter) |
156 | return; |
157 | |
158 | if (priv->rf_mode == RF_OP_By_FW) { |
159 | if (BitMask != bMask12Bits) { |
160 | Original_Value = _rtl92e_phy_rf_fw_read(dev, eRFPath, |
161 | Offset: RegAddr); |
162 | BitShift = _rtl92e_calculate_bit_shift(dwBitMask: BitMask); |
163 | New_Value = (Original_Value & ~BitMask) | (Data << BitShift); |
164 | |
165 | _rtl92e_phy_rf_fw_write(dev, eRFPath, Offset: RegAddr, |
166 | Data: New_Value); |
167 | } else { |
168 | _rtl92e_phy_rf_fw_write(dev, eRFPath, Offset: RegAddr, Data); |
169 | } |
170 | udelay(200); |
171 | } else { |
172 | if (BitMask != bMask12Bits) { |
173 | Original_Value = _rtl92e_phy_rf_read(dev, eRFPath, |
174 | Offset: RegAddr); |
175 | BitShift = _rtl92e_calculate_bit_shift(dwBitMask: BitMask); |
176 | New_Value = (Original_Value & ~BitMask) | (Data << BitShift); |
177 | |
178 | _rtl92e_phy_rf_write(dev, eRFPath, Offset: RegAddr, Data: New_Value); |
179 | } else { |
180 | _rtl92e_phy_rf_write(dev, eRFPath, Offset: RegAddr, Data); |
181 | } |
182 | } |
183 | } |
184 | |
185 | u32 rtl92e_get_rf_reg(struct net_device *dev, enum rf90_radio_path eRFPath, |
186 | u32 RegAddr, u32 BitMask) |
187 | { |
188 | u32 Original_Value, Readback_Value, BitShift; |
189 | struct r8192_priv *priv = rtllib_priv(dev); |
190 | |
191 | if (priv->rtllib->rf_power_state != rf_on && !priv->being_init_adapter) |
192 | return 0; |
193 | mutex_lock(&priv->rf_mutex); |
194 | if (priv->rf_mode == RF_OP_By_FW) { |
195 | Original_Value = _rtl92e_phy_rf_fw_read(dev, eRFPath, Offset: RegAddr); |
196 | udelay(200); |
197 | } else { |
198 | Original_Value = _rtl92e_phy_rf_read(dev, eRFPath, Offset: RegAddr); |
199 | } |
200 | BitShift = _rtl92e_calculate_bit_shift(dwBitMask: BitMask); |
201 | Readback_Value = (Original_Value & BitMask) >> BitShift; |
202 | mutex_unlock(lock: &priv->rf_mutex); |
203 | return Readback_Value; |
204 | } |
205 | |
206 | static u32 _rtl92e_phy_rf_fw_read(struct net_device *dev, |
207 | enum rf90_radio_path eRFPath, u32 Offset) |
208 | { |
209 | u32 Data = 0; |
210 | u8 time = 0; |
211 | |
212 | Data |= ((Offset & 0xFF) << 12); |
213 | Data |= ((eRFPath & 0x3) << 20); |
214 | Data |= 0x80000000; |
215 | while (rtl92e_readl(dev, x: QPNR) & 0x80000000) { |
216 | if (time++ < 100) |
217 | udelay(10); |
218 | else |
219 | break; |
220 | } |
221 | rtl92e_writel(dev, x: QPNR, y: Data); |
222 | while (rtl92e_readl(dev, x: QPNR) & 0x80000000) { |
223 | if (time++ < 100) |
224 | udelay(10); |
225 | else |
226 | return 0; |
227 | } |
228 | return rtl92e_readl(dev, RF_DATA); |
229 | } |
230 | |
231 | static void _rtl92e_phy_rf_fw_write(struct net_device *dev, |
232 | enum rf90_radio_path eRFPath, u32 Offset, |
233 | u32 Data) |
234 | { |
235 | u8 time = 0; |
236 | |
237 | Data |= ((Offset & 0xFF) << 12); |
238 | Data |= ((eRFPath & 0x3) << 20); |
239 | Data |= 0x400000; |
240 | Data |= 0x80000000; |
241 | |
242 | while (rtl92e_readl(dev, x: QPNR) & 0x80000000) { |
243 | if (time++ < 100) |
244 | udelay(10); |
245 | else |
246 | break; |
247 | } |
248 | rtl92e_writel(dev, x: QPNR, y: Data); |
249 | } |
250 | |
251 | void rtl92e_config_mac(struct net_device *dev) |
252 | { |
253 | u32 dwArrayLen = 0, i = 0; |
254 | u32 *pdwArray = NULL; |
255 | struct r8192_priv *priv = rtllib_priv(dev); |
256 | |
257 | if (priv->tx_pwr_data_read_from_eeprom) { |
258 | dwArrayLen = RTL8192E_MACPHY_ARR_PG_LEN; |
259 | pdwArray = RTL8192E_MACPHY_ARR_PG; |
260 | |
261 | } else { |
262 | dwArrayLen = RTL8192E_MACPHY_ARR_LEN; |
263 | pdwArray = RTL8192E_MACPHY_ARR; |
264 | } |
265 | for (i = 0; i < dwArrayLen; i += 3) { |
266 | if (pdwArray[i] == 0x318) |
267 | pdwArray[i + 2] = 0x00000800; |
268 | rtl92e_set_bb_reg(dev, dwRegAddr: pdwArray[i], dwBitMask: pdwArray[i + 1], |
269 | dwData: pdwArray[i + 2]); |
270 | } |
271 | } |
272 | |
273 | static void _rtl92e_phy_config_bb(struct net_device *dev, u8 ConfigType) |
274 | { |
275 | int i; |
276 | u32 *Rtl819XPHY_REGArray_Table = NULL; |
277 | u32 *Rtl819XAGCTAB_Array_Table = NULL; |
278 | u16 AGCTAB_ArrayLen, PHY_REGArrayLen = 0; |
279 | |
280 | AGCTAB_ArrayLen = RTL8192E_AGCTAB_ARR_LEN; |
281 | Rtl819XAGCTAB_Array_Table = RTL8192E_AGCTAB_ARR; |
282 | PHY_REGArrayLen = RTL8192E_PHY_REG_1T2R_ARR_LEN; |
283 | Rtl819XPHY_REGArray_Table = RTL8192E_PHY_REG_1T2R_ARR; |
284 | |
285 | if (ConfigType == BB_CONFIG_PHY_REG) { |
286 | for (i = 0; i < PHY_REGArrayLen; i += 2) { |
287 | rtl92e_set_bb_reg(dev, dwRegAddr: Rtl819XPHY_REGArray_Table[i], |
288 | bMaskDWord, |
289 | dwData: Rtl819XPHY_REGArray_Table[i + 1]); |
290 | } |
291 | } else if (ConfigType == BB_CONFIG_AGC_TAB) { |
292 | for (i = 0; i < AGCTAB_ArrayLen; i += 2) { |
293 | rtl92e_set_bb_reg(dev, dwRegAddr: Rtl819XAGCTAB_Array_Table[i], |
294 | bMaskDWord, |
295 | dwData: Rtl819XAGCTAB_Array_Table[i + 1]); |
296 | } |
297 | } |
298 | } |
299 | |
300 | static void _rtl92e_init_bb_rf_reg_def(struct net_device *dev) |
301 | { |
302 | struct r8192_priv *priv = rtllib_priv(dev); |
303 | |
304 | priv->phy_reg_def[RF90_PATH_A].rfintfs = rFPGA0_XAB_RFInterfaceSW; |
305 | priv->phy_reg_def[RF90_PATH_B].rfintfs = rFPGA0_XAB_RFInterfaceSW; |
306 | |
307 | priv->phy_reg_def[RF90_PATH_A].rfintfo = rFPGA0_XA_RFInterfaceOE; |
308 | priv->phy_reg_def[RF90_PATH_B].rfintfo = rFPGA0_XB_RFInterfaceOE; |
309 | |
310 | priv->phy_reg_def[RF90_PATH_A].rfintfe = rFPGA0_XA_RFInterfaceOE; |
311 | priv->phy_reg_def[RF90_PATH_B].rfintfe = rFPGA0_XB_RFInterfaceOE; |
312 | |
313 | priv->phy_reg_def[RF90_PATH_A].rf3wireOffset = rFPGA0_XA_LSSIParameter; |
314 | priv->phy_reg_def[RF90_PATH_B].rf3wireOffset = rFPGA0_XB_LSSIParameter; |
315 | |
316 | priv->phy_reg_def[RF90_PATH_A].rfHSSIPara2 = rFPGA0_XA_HSSIParameter2; |
317 | priv->phy_reg_def[RF90_PATH_B].rfHSSIPara2 = rFPGA0_XB_HSSIParameter2; |
318 | |
319 | priv->phy_reg_def[RF90_PATH_A].rfLSSIReadBack = rFPGA0_XA_LSSIReadBack; |
320 | priv->phy_reg_def[RF90_PATH_B].rfLSSIReadBack = rFPGA0_XB_LSSIReadBack; |
321 | } |
322 | |
323 | bool rtl92e_check_bb_and_rf(struct net_device *dev, enum hw90_block CheckBlock, |
324 | enum rf90_radio_path eRFPath) |
325 | { |
326 | bool ret = true; |
327 | u32 i, CheckTimes = 4, dwRegRead = 0; |
328 | u32 WriteAddr[4]; |
329 | u32 WriteData[] = {0xfffff027, 0xaa55a02f, 0x00000027, 0x55aa502f}; |
330 | |
331 | WriteAddr[HW90_BLOCK_MAC] = 0x100; |
332 | WriteAddr[HW90_BLOCK_PHY0] = 0x900; |
333 | WriteAddr[HW90_BLOCK_PHY1] = 0x800; |
334 | WriteAddr[HW90_BLOCK_RF] = 0x3; |
335 | |
336 | if (CheckBlock == HW90_BLOCK_MAC) { |
337 | netdev_warn(dev, format: "%s(): No checks available for MAC block.\n" , |
338 | __func__); |
339 | return ret; |
340 | } |
341 | |
342 | for (i = 0; i < CheckTimes; i++) { |
343 | switch (CheckBlock) { |
344 | case HW90_BLOCK_PHY0: |
345 | case HW90_BLOCK_PHY1: |
346 | rtl92e_writel(dev, x: WriteAddr[CheckBlock], |
347 | y: WriteData[i]); |
348 | dwRegRead = rtl92e_readl(dev, x: WriteAddr[CheckBlock]); |
349 | break; |
350 | |
351 | case HW90_BLOCK_RF: |
352 | WriteData[i] &= 0xfff; |
353 | rtl92e_set_rf_reg(dev, eRFPath, |
354 | RegAddr: WriteAddr[HW90_BLOCK_RF], |
355 | bMask12Bits, Data: WriteData[i]); |
356 | mdelay(10); |
357 | dwRegRead = rtl92e_get_rf_reg(dev, eRFPath, |
358 | RegAddr: WriteAddr[HW90_BLOCK_RF], |
359 | bMaskDWord); |
360 | mdelay(10); |
361 | break; |
362 | |
363 | default: |
364 | ret = false; |
365 | break; |
366 | } |
367 | |
368 | if (dwRegRead != WriteData[i]) { |
369 | netdev_warn(dev, format: "%s(): Check failed.\n" , __func__); |
370 | ret = false; |
371 | break; |
372 | } |
373 | } |
374 | |
375 | return ret; |
376 | } |
377 | |
378 | static bool _rtl92e_bb_config_para_file(struct net_device *dev) |
379 | { |
380 | struct r8192_priv *priv = rtllib_priv(dev); |
381 | bool rtStatus = true; |
382 | u8 bRegValue = 0, eCheckItem = 0; |
383 | u32 dwRegValue = 0; |
384 | |
385 | bRegValue = rtl92e_readb(dev, x: BB_GLOBAL_RESET); |
386 | rtl92e_writeb(dev, x: BB_GLOBAL_RESET, y: (bRegValue | BB_GLOBAL_RESET_BIT)); |
387 | |
388 | dwRegValue = rtl92e_readl(dev, x: CPU_GEN); |
389 | rtl92e_writel(dev, x: CPU_GEN, y: (dwRegValue & (~CPU_GEN_BB_RST))); |
390 | |
391 | for (eCheckItem = (enum hw90_block)HW90_BLOCK_PHY0; |
392 | eCheckItem <= HW90_BLOCK_PHY1; eCheckItem++) { |
393 | rtStatus = rtl92e_check_bb_and_rf(dev, |
394 | CheckBlock: (enum hw90_block)eCheckItem, |
395 | eRFPath: (enum rf90_radio_path)0); |
396 | if (!rtStatus) |
397 | return rtStatus; |
398 | } |
399 | rtl92e_set_bb_reg(dev, rFPGA0_RFMOD, bCCKEn | bOFDMEn, dwData: 0x0); |
400 | _rtl92e_phy_config_bb(dev, ConfigType: BB_CONFIG_PHY_REG); |
401 | |
402 | dwRegValue = rtl92e_readl(dev, x: CPU_GEN); |
403 | rtl92e_writel(dev, x: CPU_GEN, y: (dwRegValue | CPU_GEN_BB_RST)); |
404 | |
405 | _rtl92e_phy_config_bb(dev, ConfigType: BB_CONFIG_AGC_TAB); |
406 | |
407 | if (priv->ic_cut > VERSION_8190_BD) { |
408 | dwRegValue = 0x0; |
409 | rtl92e_set_bb_reg(dev, rFPGA0_TxGainStage, |
410 | dwBitMask: (bXBTxAGC | bXCTxAGC | bXDTxAGC), dwData: dwRegValue); |
411 | |
412 | dwRegValue = priv->crystal_cap; |
413 | rtl92e_set_bb_reg(dev, rFPGA0_AnalogParameter1, bXtalCap92x, |
414 | dwData: dwRegValue); |
415 | } |
416 | |
417 | return rtStatus; |
418 | } |
419 | bool rtl92e_config_bb(struct net_device *dev) |
420 | { |
421 | _rtl92e_init_bb_rf_reg_def(dev); |
422 | return _rtl92e_bb_config_para_file(dev); |
423 | } |
424 | |
425 | void rtl92e_get_tx_power(struct net_device *dev) |
426 | { |
427 | struct r8192_priv *priv = rtllib_priv(dev); |
428 | |
429 | priv->mcs_tx_pwr_level_org_offset[0] = |
430 | rtl92e_readl(dev, rTxAGC_Rate18_06); |
431 | priv->mcs_tx_pwr_level_org_offset[1] = |
432 | rtl92e_readl(dev, rTxAGC_Rate54_24); |
433 | priv->mcs_tx_pwr_level_org_offset[2] = |
434 | rtl92e_readl(dev, rTxAGC_Mcs03_Mcs00); |
435 | priv->mcs_tx_pwr_level_org_offset[3] = |
436 | rtl92e_readl(dev, rTxAGC_Mcs07_Mcs04); |
437 | priv->mcs_tx_pwr_level_org_offset[4] = |
438 | rtl92e_readl(dev, rTxAGC_Mcs11_Mcs08); |
439 | priv->mcs_tx_pwr_level_org_offset[5] = |
440 | rtl92e_readl(dev, rTxAGC_Mcs15_Mcs12); |
441 | |
442 | priv->def_initial_gain[0] = rtl92e_readb(dev, rOFDM0_XAAGCCore1); |
443 | priv->def_initial_gain[1] = rtl92e_readb(dev, rOFDM0_XBAGCCore1); |
444 | priv->def_initial_gain[2] = rtl92e_readb(dev, rOFDM0_XCAGCCore1); |
445 | priv->def_initial_gain[3] = rtl92e_readb(dev, rOFDM0_XDAGCCore1); |
446 | |
447 | priv->framesync = rtl92e_readb(dev, rOFDM0_RxDetector3); |
448 | } |
449 | |
450 | void rtl92e_set_tx_power(struct net_device *dev, u8 channel) |
451 | { |
452 | struct r8192_priv *priv = rtllib_priv(dev); |
453 | u8 powerlevel = 0, powerlevelOFDM24G = 0; |
454 | |
455 | if (priv->epromtype == EEPROM_93C46) { |
456 | powerlevel = priv->tx_pwr_level_cck[channel - 1]; |
457 | powerlevelOFDM24G = priv->tx_pwr_level_ofdm_24g[channel - 1]; |
458 | } |
459 | |
460 | rtl92e_set_cck_tx_power(dev, powerlevel); |
461 | rtl92e_set_ofdm_tx_power(dev, powerlevel: powerlevelOFDM24G); |
462 | } |
463 | |
464 | u8 rtl92e_config_rf_path(struct net_device *dev, enum rf90_radio_path eRFPath) |
465 | { |
466 | int i; |
467 | |
468 | switch (eRFPath) { |
469 | case RF90_PATH_A: |
470 | for (i = 0; i < RTL8192E_RADIO_A_ARR_LEN; i += 2) { |
471 | if (RTL8192E_RADIO_A_ARR[i] == 0xfe) { |
472 | msleep(msecs: 100); |
473 | continue; |
474 | } |
475 | rtl92e_set_rf_reg(dev, eRFPath, RegAddr: RTL8192E_RADIO_A_ARR[i], |
476 | bMask12Bits, |
477 | Data: RTL8192E_RADIO_A_ARR[i + 1]); |
478 | } |
479 | break; |
480 | case RF90_PATH_B: |
481 | for (i = 0; i < RTL8192E_RADIO_B_ARR_LEN; i += 2) { |
482 | if (RTL8192E_RADIO_B_ARR[i] == 0xfe) { |
483 | msleep(msecs: 100); |
484 | continue; |
485 | } |
486 | rtl92e_set_rf_reg(dev, eRFPath, RegAddr: RTL8192E_RADIO_B_ARR[i], |
487 | bMask12Bits, |
488 | Data: RTL8192E_RADIO_B_ARR[i + 1]); |
489 | } |
490 | break; |
491 | default: |
492 | break; |
493 | } |
494 | |
495 | return 0; |
496 | } |
497 | |
498 | static void _rtl92e_set_tx_power_level(struct net_device *dev, u8 channel) |
499 | { |
500 | struct r8192_priv *priv = rtllib_priv(dev); |
501 | u8 powerlevel = priv->tx_pwr_level_cck[channel - 1]; |
502 | u8 powerlevelOFDM24G = priv->tx_pwr_level_ofdm_24g[channel - 1]; |
503 | |
504 | rtl92e_set_cck_tx_power(dev, powerlevel); |
505 | rtl92e_set_ofdm_tx_power(dev, powerlevel: powerlevelOFDM24G); |
506 | } |
507 | |
508 | static u8 _rtl92e_phy_set_sw_chnl_cmd_array(struct net_device *dev, |
509 | struct sw_chnl_cmd *CmdTable, |
510 | u32 CmdTableIdx, u32 CmdTableSz, |
511 | enum sw_chnl_cmd_id CmdID, |
512 | u32 Para1, u32 Para2, u32 msDelay) |
513 | { |
514 | struct sw_chnl_cmd *pCmd; |
515 | |
516 | if (!CmdTable) { |
517 | netdev_err(dev, format: "%s(): CmdTable cannot be NULL.\n" , __func__); |
518 | return false; |
519 | } |
520 | if (CmdTableIdx >= CmdTableSz) { |
521 | netdev_err(dev, format: "%s(): Invalid index requested.\n" , __func__); |
522 | return false; |
523 | } |
524 | |
525 | pCmd = CmdTable + CmdTableIdx; |
526 | pCmd->CmdID = CmdID; |
527 | pCmd->Para1 = Para1; |
528 | pCmd->Para2 = Para2; |
529 | pCmd->msDelay = msDelay; |
530 | |
531 | return true; |
532 | } |
533 | |
534 | static u8 _rtl92e_phy_switch_channel_step(struct net_device *dev, u8 channel, |
535 | u8 *stage, u8 *step, u32 *delay) |
536 | { |
537 | struct r8192_priv *priv = rtllib_priv(dev); |
538 | struct rtllib_device *ieee = priv->rtllib; |
539 | u32 PreCommonCmdCnt; |
540 | u32 PostCommonCmdCnt; |
541 | u32 RfDependCmdCnt; |
542 | struct sw_chnl_cmd *CurrentCmd = NULL; |
543 | u8 eRFPath; |
544 | |
545 | if (!rtllib_legal_channel(rtllib: priv->rtllib, channel)) { |
546 | netdev_err(dev, format: "Invalid channel requested: %d\n" , channel); |
547 | return true; |
548 | } |
549 | |
550 | { |
551 | PreCommonCmdCnt = 0; |
552 | _rtl92e_phy_set_sw_chnl_cmd_array(dev, CmdTable: ieee->PreCommonCmd, |
553 | CmdTableIdx: PreCommonCmdCnt++, |
554 | MAX_PRECMD_CNT, |
555 | CmdID: CmdID_SetTxPowerLevel, |
556 | Para1: 0, Para2: 0, msDelay: 0); |
557 | _rtl92e_phy_set_sw_chnl_cmd_array(dev, CmdTable: ieee->PreCommonCmd, |
558 | CmdTableIdx: PreCommonCmdCnt++, |
559 | MAX_PRECMD_CNT, CmdID: CmdID_End, |
560 | Para1: 0, Para2: 0, msDelay: 0); |
561 | |
562 | PostCommonCmdCnt = 0; |
563 | |
564 | _rtl92e_phy_set_sw_chnl_cmd_array(dev, CmdTable: ieee->PostCommonCmd, |
565 | CmdTableIdx: PostCommonCmdCnt++, |
566 | MAX_POSTCMD_CNT, CmdID: CmdID_End, |
567 | Para1: 0, Para2: 0, msDelay: 0); |
568 | |
569 | RfDependCmdCnt = 0; |
570 | |
571 | if (!(channel >= 1 && channel <= 14)) { |
572 | netdev_err(dev, |
573 | format: "Invalid channel requested for 8256: %d\n" , |
574 | channel); |
575 | return false; |
576 | } |
577 | _rtl92e_phy_set_sw_chnl_cmd_array(dev, |
578 | CmdTable: ieee->RfDependCmd, |
579 | CmdTableIdx: RfDependCmdCnt++, |
580 | MAX_RFDEPENDCMD_CNT, |
581 | CmdID: CmdID_RF_WriteReg, |
582 | rZebra1_Channel, |
583 | Para2: channel, msDelay: 10); |
584 | _rtl92e_phy_set_sw_chnl_cmd_array(dev, |
585 | CmdTable: ieee->RfDependCmd, |
586 | CmdTableIdx: RfDependCmdCnt++, |
587 | MAX_RFDEPENDCMD_CNT, |
588 | CmdID: CmdID_End, Para1: 0, Para2: 0, msDelay: 0); |
589 | |
590 | do { |
591 | switch (*stage) { |
592 | case 0: |
593 | CurrentCmd = &ieee->PreCommonCmd[*step]; |
594 | break; |
595 | case 1: |
596 | CurrentCmd = &ieee->RfDependCmd[*step]; |
597 | break; |
598 | case 2: |
599 | CurrentCmd = &ieee->PostCommonCmd[*step]; |
600 | break; |
601 | } |
602 | |
603 | if (CurrentCmd && CurrentCmd->CmdID == CmdID_End) { |
604 | if ((*stage) == 2) |
605 | return true; |
606 | (*stage)++; |
607 | (*step) = 0; |
608 | continue; |
609 | } |
610 | |
611 | if (!CurrentCmd) |
612 | continue; |
613 | switch (CurrentCmd->CmdID) { |
614 | case CmdID_SetTxPowerLevel: |
615 | if (priv->ic_cut > VERSION_8190_BD) |
616 | _rtl92e_set_tx_power_level(dev, |
617 | channel); |
618 | break; |
619 | case CmdID_WritePortUlong: |
620 | rtl92e_writel(dev, x: CurrentCmd->Para1, |
621 | y: CurrentCmd->Para2); |
622 | break; |
623 | case CmdID_WritePortUshort: |
624 | rtl92e_writew(dev, x: CurrentCmd->Para1, |
625 | y: CurrentCmd->Para2); |
626 | break; |
627 | case CmdID_WritePortUchar: |
628 | rtl92e_writeb(dev, x: CurrentCmd->Para1, |
629 | y: CurrentCmd->Para2); |
630 | break; |
631 | case CmdID_RF_WriteReg: |
632 | for (eRFPath = 0; eRFPath < |
633 | priv->num_total_rf_path; eRFPath++) |
634 | rtl92e_set_rf_reg(dev, |
635 | eRFPath: (enum rf90_radio_path)eRFPath, |
636 | RegAddr: CurrentCmd->Para1, bMask12Bits, |
637 | Data: CurrentCmd->Para2 << 7); |
638 | break; |
639 | default: |
640 | break; |
641 | } |
642 | |
643 | break; |
644 | } while (true); |
645 | } /*for (Number of RF paths)*/ |
646 | |
647 | (*delay) = CurrentCmd->msDelay; |
648 | (*step)++; |
649 | return false; |
650 | } |
651 | |
652 | static void _rtl92e_phy_switch_channel(struct net_device *dev, u8 channel) |
653 | { |
654 | struct r8192_priv *priv = rtllib_priv(dev); |
655 | u32 delay = 0; |
656 | |
657 | while (!_rtl92e_phy_switch_channel_step(dev, channel, |
658 | stage: &priv->sw_chnl_stage, |
659 | step: &priv->sw_chnl_step, delay: &delay)) { |
660 | if (delay > 0) |
661 | msleep(msecs: delay); |
662 | if (!priv->up) |
663 | break; |
664 | } |
665 | } |
666 | |
667 | static void _rtl92e_phy_switch_channel_work_item(struct net_device *dev) |
668 | { |
669 | struct r8192_priv *priv = rtllib_priv(dev); |
670 | |
671 | _rtl92e_phy_switch_channel(dev, channel: priv->chan); |
672 | } |
673 | |
674 | void rtl92e_set_channel(struct net_device *dev, u8 channel) |
675 | { |
676 | struct r8192_priv *priv = rtllib_priv(dev); |
677 | |
678 | if (!priv->up) { |
679 | netdev_err(dev, format: "%s(): Driver is not initialized\n" , __func__); |
680 | return; |
681 | } |
682 | if (priv->sw_chnl_in_progress) |
683 | return; |
684 | |
685 | switch (priv->rtllib->mode) { |
686 | case WIRELESS_MODE_B: |
687 | if (channel > 14) { |
688 | netdev_warn(dev, |
689 | format: "Channel %d not available in 802.11b.\n" , |
690 | channel); |
691 | return; |
692 | } |
693 | break; |
694 | case WIRELESS_MODE_G: |
695 | case WIRELESS_MODE_N_24G: |
696 | if (channel > 14) { |
697 | netdev_warn(dev, |
698 | format: "Channel %d not available in 802.11g.\n" , |
699 | channel); |
700 | return; |
701 | } |
702 | break; |
703 | } |
704 | |
705 | priv->sw_chnl_in_progress = true; |
706 | if (channel == 0) |
707 | channel = 1; |
708 | |
709 | priv->chan = channel; |
710 | |
711 | priv->sw_chnl_stage = 0; |
712 | priv->sw_chnl_step = 0; |
713 | |
714 | if (priv->up) |
715 | _rtl92e_phy_switch_channel_work_item(dev); |
716 | priv->sw_chnl_in_progress = false; |
717 | } |
718 | |
719 | static void _rtl92e_cck_tx_power_track_bw_switch_tssi(struct net_device *dev) |
720 | { |
721 | struct r8192_priv *priv = rtllib_priv(dev); |
722 | |
723 | switch (priv->current_chnl_bw) { |
724 | case HT_CHANNEL_WIDTH_20: |
725 | priv->cck_present_attn = |
726 | priv->cck_present_attn_20m_def + |
727 | priv->cck_present_attn_diff; |
728 | |
729 | if (priv->cck_present_attn > |
730 | (CCK_TX_BB_GAIN_TABLE_LEN - 1)) |
731 | priv->cck_present_attn = |
732 | CCK_TX_BB_GAIN_TABLE_LEN - 1; |
733 | if (priv->cck_present_attn < 0) |
734 | priv->cck_present_attn = 0; |
735 | |
736 | if (priv->rtllib->current_network.channel == 14 && |
737 | !priv->bcck_in_ch14) { |
738 | priv->bcck_in_ch14 = true; |
739 | rtl92e_dm_cck_txpower_adjust(dev, binch14: priv->bcck_in_ch14); |
740 | } else if (priv->rtllib->current_network.channel != |
741 | 14 && priv->bcck_in_ch14) { |
742 | priv->bcck_in_ch14 = false; |
743 | rtl92e_dm_cck_txpower_adjust(dev, binch14: priv->bcck_in_ch14); |
744 | } else { |
745 | rtl92e_dm_cck_txpower_adjust(dev, binch14: priv->bcck_in_ch14); |
746 | } |
747 | break; |
748 | |
749 | case HT_CHANNEL_WIDTH_20_40: |
750 | priv->cck_present_attn = |
751 | priv->cck_present_attn_40m_def + |
752 | priv->cck_present_attn_diff; |
753 | |
754 | if (priv->cck_present_attn > |
755 | (CCK_TX_BB_GAIN_TABLE_LEN - 1)) |
756 | priv->cck_present_attn = |
757 | CCK_TX_BB_GAIN_TABLE_LEN - 1; |
758 | if (priv->cck_present_attn < 0) |
759 | priv->cck_present_attn = 0; |
760 | |
761 | if (priv->rtllib->current_network.channel == 14 && |
762 | !priv->bcck_in_ch14) { |
763 | priv->bcck_in_ch14 = true; |
764 | rtl92e_dm_cck_txpower_adjust(dev, binch14: priv->bcck_in_ch14); |
765 | } else if (priv->rtllib->current_network.channel != 14 |
766 | && priv->bcck_in_ch14) { |
767 | priv->bcck_in_ch14 = false; |
768 | rtl92e_dm_cck_txpower_adjust(dev, binch14: priv->bcck_in_ch14); |
769 | } else { |
770 | rtl92e_dm_cck_txpower_adjust(dev, binch14: priv->bcck_in_ch14); |
771 | } |
772 | break; |
773 | } |
774 | } |
775 | |
776 | static void _rtl92e_cck_tx_power_track_bw_switch_thermal(struct net_device *dev) |
777 | { |
778 | struct r8192_priv *priv = rtllib_priv(dev); |
779 | |
780 | if (priv->rtllib->current_network.channel == 14 && |
781 | !priv->bcck_in_ch14) |
782 | priv->bcck_in_ch14 = true; |
783 | else if (priv->rtllib->current_network.channel != 14 && |
784 | priv->bcck_in_ch14) |
785 | priv->bcck_in_ch14 = false; |
786 | |
787 | switch (priv->current_chnl_bw) { |
788 | case HT_CHANNEL_WIDTH_20: |
789 | if (priv->rec_cck_20m_idx == 0) |
790 | priv->rec_cck_20m_idx = 6; |
791 | priv->cck_index = priv->rec_cck_20m_idx; |
792 | break; |
793 | |
794 | case HT_CHANNEL_WIDTH_20_40: |
795 | priv->cck_index = priv->rec_cck_40m_idx; |
796 | break; |
797 | } |
798 | rtl92e_dm_cck_txpower_adjust(dev, binch14: priv->bcck_in_ch14); |
799 | } |
800 | |
801 | static void _rtl92e_cck_tx_power_track_bw_switch(struct net_device *dev) |
802 | { |
803 | struct r8192_priv *priv = rtllib_priv(dev); |
804 | |
805 | if (priv->ic_cut >= IC_VersionCut_D) |
806 | _rtl92e_cck_tx_power_track_bw_switch_tssi(dev); |
807 | else |
808 | _rtl92e_cck_tx_power_track_bw_switch_thermal(dev); |
809 | } |
810 | |
811 | static void _rtl92e_set_bw_mode_work_item(struct net_device *dev) |
812 | { |
813 | struct r8192_priv *priv = rtllib_priv(dev); |
814 | u8 regBwOpMode; |
815 | |
816 | if (!priv->up) { |
817 | netdev_err(dev, format: "%s(): Driver is not initialized\n" , __func__); |
818 | return; |
819 | } |
820 | regBwOpMode = rtl92e_readb(dev, x: BW_OPMODE); |
821 | |
822 | switch (priv->current_chnl_bw) { |
823 | case HT_CHANNEL_WIDTH_20: |
824 | regBwOpMode |= BW_OPMODE_20MHZ; |
825 | rtl92e_writeb(dev, x: BW_OPMODE, y: regBwOpMode); |
826 | break; |
827 | |
828 | case HT_CHANNEL_WIDTH_20_40: |
829 | regBwOpMode &= ~BW_OPMODE_20MHZ; |
830 | rtl92e_writeb(dev, x: BW_OPMODE, y: regBwOpMode); |
831 | break; |
832 | |
833 | default: |
834 | netdev_err(dev, format: "%s(): unknown Bandwidth: %#X\n" , __func__, |
835 | priv->current_chnl_bw); |
836 | break; |
837 | } |
838 | |
839 | switch (priv->current_chnl_bw) { |
840 | case HT_CHANNEL_WIDTH_20: |
841 | rtl92e_set_bb_reg(dev, rFPGA0_RFMOD, bRFMOD, dwData: 0x0); |
842 | rtl92e_set_bb_reg(dev, rFPGA1_RFMOD, bRFMOD, dwData: 0x0); |
843 | |
844 | if (!priv->btxpower_tracking) { |
845 | rtl92e_writel(dev, rCCK0_TxFilter1, y: 0x1a1b0000); |
846 | rtl92e_writel(dev, rCCK0_TxFilter2, y: 0x090e1317); |
847 | rtl92e_writel(dev, rCCK0_DebugPort, y: 0x00000204); |
848 | } else { |
849 | _rtl92e_cck_tx_power_track_bw_switch(dev); |
850 | } |
851 | |
852 | rtl92e_set_bb_reg(dev, rFPGA0_AnalogParameter1, dwBitMask: 0x00100000, dwData: 1); |
853 | |
854 | break; |
855 | case HT_CHANNEL_WIDTH_20_40: |
856 | rtl92e_set_bb_reg(dev, rFPGA0_RFMOD, bRFMOD, dwData: 0x1); |
857 | rtl92e_set_bb_reg(dev, rFPGA1_RFMOD, bRFMOD, dwData: 0x1); |
858 | |
859 | if (!priv->btxpower_tracking) { |
860 | rtl92e_writel(dev, rCCK0_TxFilter1, y: 0x35360000); |
861 | rtl92e_writel(dev, rCCK0_TxFilter2, y: 0x121c252e); |
862 | rtl92e_writel(dev, rCCK0_DebugPort, y: 0x00000409); |
863 | } else { |
864 | _rtl92e_cck_tx_power_track_bw_switch(dev); |
865 | } |
866 | |
867 | rtl92e_set_bb_reg(dev, rCCK0_System, bCCKSideBand, |
868 | dwData: (priv->n_cur_40mhz_prime_sc >> 1)); |
869 | rtl92e_set_bb_reg(dev, rOFDM1_LSTF, dwBitMask: 0xC00, |
870 | dwData: priv->n_cur_40mhz_prime_sc); |
871 | |
872 | rtl92e_set_bb_reg(dev, rFPGA0_AnalogParameter1, dwBitMask: 0x00100000, dwData: 0); |
873 | break; |
874 | default: |
875 | netdev_err(dev, format: "%s(): unknown Bandwidth: %#X\n" , __func__, |
876 | priv->current_chnl_bw); |
877 | break; |
878 | } |
879 | |
880 | rtl92e_set_bandwidth(dev, bandwidth: priv->current_chnl_bw); |
881 | |
882 | atomic_dec(v: &(priv->rtllib->atm_swbw)); |
883 | priv->set_bw_mode_in_progress = false; |
884 | } |
885 | |
886 | void rtl92e_set_bw_mode(struct net_device *dev, enum ht_channel_width bandwidth, |
887 | enum ht_extchnl_offset Offset) |
888 | { |
889 | struct r8192_priv *priv = rtllib_priv(dev); |
890 | |
891 | if (priv->set_bw_mode_in_progress) |
892 | return; |
893 | |
894 | atomic_inc(v: &(priv->rtllib->atm_swbw)); |
895 | priv->set_bw_mode_in_progress = true; |
896 | |
897 | priv->current_chnl_bw = bandwidth; |
898 | |
899 | if (Offset == HT_EXTCHNL_OFFSET_LOWER) |
900 | priv->n_cur_40mhz_prime_sc = HAL_PRIME_CHNL_OFFSET_UPPER; |
901 | else if (Offset == HT_EXTCHNL_OFFSET_UPPER) |
902 | priv->n_cur_40mhz_prime_sc = HAL_PRIME_CHNL_OFFSET_LOWER; |
903 | else |
904 | priv->n_cur_40mhz_prime_sc = HAL_PRIME_CHNL_OFFSET_DONT_CARE; |
905 | |
906 | _rtl92e_set_bw_mode_work_item(dev); |
907 | } |
908 | |
909 | void rtl92e_init_gain(struct net_device *dev, u8 Operation) |
910 | { |
911 | #define SCAN_RX_INITIAL_GAIN 0x17 |
912 | #define POWER_DETECTION_TH 0x08 |
913 | struct r8192_priv *priv = rtllib_priv(dev); |
914 | u32 BitMask; |
915 | u8 initial_gain; |
916 | |
917 | if (priv->up) { |
918 | switch (Operation) { |
919 | case IG_Backup: |
920 | initial_gain = SCAN_RX_INITIAL_GAIN; |
921 | BitMask = bMaskByte0; |
922 | priv->initgain_backup.xaagccore1 = |
923 | rtl92e_get_bb_reg(dev, rOFDM0_XAAGCCore1, |
924 | dwBitMask: BitMask); |
925 | priv->initgain_backup.xbagccore1 = |
926 | rtl92e_get_bb_reg(dev, rOFDM0_XBAGCCore1, |
927 | dwBitMask: BitMask); |
928 | priv->initgain_backup.xcagccore1 = |
929 | rtl92e_get_bb_reg(dev, rOFDM0_XCAGCCore1, |
930 | dwBitMask: BitMask); |
931 | priv->initgain_backup.xdagccore1 = |
932 | rtl92e_get_bb_reg(dev, rOFDM0_XDAGCCore1, |
933 | dwBitMask: BitMask); |
934 | BitMask = bMaskByte2; |
935 | priv->initgain_backup.cca = (u8)rtl92e_get_bb_reg(dev, |
936 | rCCK0_CCA, dwBitMask: BitMask); |
937 | |
938 | rtl92e_writeb(dev, rOFDM0_XAAGCCore1, y: initial_gain); |
939 | rtl92e_writeb(dev, rOFDM0_XBAGCCore1, y: initial_gain); |
940 | rtl92e_writeb(dev, rOFDM0_XCAGCCore1, y: initial_gain); |
941 | rtl92e_writeb(dev, rOFDM0_XDAGCCore1, y: initial_gain); |
942 | rtl92e_writeb(dev, x: 0xa0a, POWER_DETECTION_TH); |
943 | break; |
944 | case IG_Restore: |
945 | BitMask = 0x7f; |
946 | rtl92e_set_bb_reg(dev, rOFDM0_XAAGCCore1, dwBitMask: BitMask, |
947 | dwData: (u32)priv->initgain_backup.xaagccore1); |
948 | rtl92e_set_bb_reg(dev, rOFDM0_XBAGCCore1, dwBitMask: BitMask, |
949 | dwData: (u32)priv->initgain_backup.xbagccore1); |
950 | rtl92e_set_bb_reg(dev, rOFDM0_XCAGCCore1, dwBitMask: BitMask, |
951 | dwData: (u32)priv->initgain_backup.xcagccore1); |
952 | rtl92e_set_bb_reg(dev, rOFDM0_XDAGCCore1, dwBitMask: BitMask, |
953 | dwData: (u32)priv->initgain_backup.xdagccore1); |
954 | BitMask = bMaskByte2; |
955 | rtl92e_set_bb_reg(dev, rCCK0_CCA, dwBitMask: BitMask, |
956 | dwData: (u32)priv->initgain_backup.cca); |
957 | |
958 | rtl92e_set_tx_power(dev, |
959 | channel: priv->rtllib->current_network.channel); |
960 | break; |
961 | } |
962 | } |
963 | } |
964 | |
965 | void rtl92e_set_rf_off(struct net_device *dev) |
966 | { |
967 | rtl92e_set_bb_reg(dev, rFPGA0_XA_RFInterfaceOE, BIT(4), dwData: 0x0); |
968 | rtl92e_set_bb_reg(dev, rFPGA0_AnalogParameter4, dwBitMask: 0x300, dwData: 0x0); |
969 | rtl92e_set_bb_reg(dev, rFPGA0_AnalogParameter1, dwBitMask: 0x18, dwData: 0x0); |
970 | rtl92e_set_bb_reg(dev, rOFDM0_TRxPathEnable, dwBitMask: 0xf, dwData: 0x0); |
971 | rtl92e_set_bb_reg(dev, rOFDM1_TRxPathEnable, dwBitMask: 0xf, dwData: 0x0); |
972 | rtl92e_set_bb_reg(dev, rFPGA0_AnalogParameter1, dwBitMask: 0x60, dwData: 0x0); |
973 | rtl92e_set_bb_reg(dev, rFPGA0_AnalogParameter1, dwBitMask: 0x4, dwData: 0x0); |
974 | rtl92e_writeb(dev, ANAPAR_FOR_8192PCIE, y: 0x07); |
975 | } |
976 | |
977 | static bool _rtl92e_set_rf_power_state(struct net_device *dev, |
978 | enum rt_rf_power_state rf_power_state) |
979 | { |
980 | struct r8192_priv *priv = rtllib_priv(dev); |
981 | struct rt_pwr_save_ctrl *psc = (struct rt_pwr_save_ctrl *) |
982 | (&priv->rtllib->pwr_save_ctrl); |
983 | bool bResult = true; |
984 | u8 i = 0, QueueID = 0; |
985 | struct rtl8192_tx_ring *ring = NULL; |
986 | |
987 | if (priv->set_rf_pwr_state_in_progress) |
988 | return false; |
989 | priv->set_rf_pwr_state_in_progress = true; |
990 | |
991 | switch (rf_power_state) { |
992 | case rf_on: |
993 | if ((priv->rtllib->rf_power_state == rf_off) && |
994 | RT_IN_PS_LEVEL(psc, RT_RF_OFF_LEVL_HALT_NIC)) { |
995 | bool rtstatus; |
996 | u32 InitilizeCount = 3; |
997 | |
998 | do { |
999 | InitilizeCount--; |
1000 | rtstatus = rtl92e_enable_nic(dev); |
1001 | } while (!rtstatus && (InitilizeCount > 0)); |
1002 | if (!rtstatus) { |
1003 | netdev_err(dev, |
1004 | format: "%s(): Failed to initialize Adapter.\n" , |
1005 | __func__); |
1006 | priv->set_rf_pwr_state_in_progress = false; |
1007 | return false; |
1008 | } |
1009 | RT_CLEAR_PS_LEVEL(psc, |
1010 | RT_RF_OFF_LEVL_HALT_NIC); |
1011 | } else { |
1012 | rtl92e_writeb(dev, x: ANAPAR, y: 0x37); |
1013 | mdelay(1); |
1014 | rtl92e_set_bb_reg(dev, rFPGA0_AnalogParameter1, |
1015 | dwBitMask: 0x4, dwData: 0x1); |
1016 | priv->hw_rf_off_action = 0; |
1017 | rtl92e_set_bb_reg(dev, rFPGA0_XA_RFInterfaceOE, |
1018 | BIT(4), dwData: 0x1); |
1019 | rtl92e_set_bb_reg(dev, rFPGA0_AnalogParameter4, |
1020 | dwBitMask: 0x300, dwData: 0x3); |
1021 | rtl92e_set_bb_reg(dev, rFPGA0_AnalogParameter1, |
1022 | dwBitMask: 0x18, dwData: 0x3); |
1023 | rtl92e_set_bb_reg(dev, rOFDM0_TRxPathEnable, |
1024 | dwBitMask: 0x3, dwData: 0x3); |
1025 | rtl92e_set_bb_reg(dev, rOFDM1_TRxPathEnable, |
1026 | dwBitMask: 0x3, dwData: 0x3); |
1027 | rtl92e_set_bb_reg(dev, rFPGA0_AnalogParameter1, |
1028 | dwBitMask: 0x60, dwData: 0x3); |
1029 | } |
1030 | break; |
1031 | case rf_sleep: |
1032 | if (priv->rtllib->rf_power_state == rf_off) |
1033 | break; |
1034 | for (QueueID = 0, i = 0; QueueID < MAX_TX_QUEUE; ) { |
1035 | ring = &priv->tx_ring[QueueID]; |
1036 | if (skb_queue_len(list_: &ring->queue) == 0) { |
1037 | QueueID++; |
1038 | continue; |
1039 | } else { |
1040 | udelay(10); |
1041 | i++; |
1042 | } |
1043 | if (i >= MAX_DOZE_WAITING_TIMES_9x) |
1044 | break; |
1045 | } |
1046 | rtl92e_set_rf_off(dev); |
1047 | break; |
1048 | case rf_off: |
1049 | for (QueueID = 0, i = 0; QueueID < MAX_TX_QUEUE; ) { |
1050 | ring = &priv->tx_ring[QueueID]; |
1051 | if (skb_queue_len(list_: &ring->queue) == 0) { |
1052 | QueueID++; |
1053 | continue; |
1054 | } else { |
1055 | udelay(10); |
1056 | i++; |
1057 | } |
1058 | if (i >= MAX_DOZE_WAITING_TIMES_9x) |
1059 | break; |
1060 | } |
1061 | rtl92e_set_rf_off(dev); |
1062 | break; |
1063 | default: |
1064 | bResult = false; |
1065 | netdev_warn(dev, |
1066 | format: "%s(): Unknown state requested: 0x%X.\n" , |
1067 | __func__, rf_power_state); |
1068 | break; |
1069 | } |
1070 | |
1071 | if (bResult) |
1072 | priv->rtllib->rf_power_state = rf_power_state; |
1073 | |
1074 | priv->set_rf_pwr_state_in_progress = false; |
1075 | return bResult; |
1076 | } |
1077 | |
1078 | bool rtl92e_set_rf_power_state(struct net_device *dev, |
1079 | enum rt_rf_power_state rf_power_state) |
1080 | { |
1081 | struct r8192_priv *priv = rtllib_priv(dev); |
1082 | |
1083 | bool bResult = false; |
1084 | |
1085 | if (rf_power_state == priv->rtllib->rf_power_state && |
1086 | priv->hw_rf_off_action == 0) { |
1087 | return bResult; |
1088 | } |
1089 | |
1090 | bResult = _rtl92e_set_rf_power_state(dev, rf_power_state); |
1091 | return bResult; |
1092 | } |
1093 | |
1094 | void rtl92e_scan_op_backup(struct net_device *dev, u8 Operation) |
1095 | { |
1096 | struct r8192_priv *priv = rtllib_priv(dev); |
1097 | |
1098 | if (priv->up) { |
1099 | switch (Operation) { |
1100 | case SCAN_OPT_BACKUP: |
1101 | priv->rtllib->init_gain_handler(dev, IG_Backup); |
1102 | break; |
1103 | |
1104 | case SCAN_OPT_RESTORE: |
1105 | priv->rtllib->init_gain_handler(dev, IG_Restore); |
1106 | break; |
1107 | } |
1108 | } |
1109 | } |
1110 | |