1 | // SPDX-License-Identifier: GPL-2.0 |
2 | /* |
3 | * Copyright(c) 2008 - 2010 Realtek Corporation. All rights reserved. |
4 | * |
5 | * Based on the r8180 driver, which is: |
6 | * Copyright 2004-2005 Andrea Merello <andrea.merello@gmail.com>, et al. |
7 | * |
8 | * Contact Information: wlanfae <wlanfae@realtek.com> |
9 | */ |
10 | #include "rtl_core.h" |
11 | #include "r8192E_phy.h" |
12 | #include "r8192E_phyreg.h" |
13 | #include "r8190P_rtl8256.h" |
14 | #include "r8192E_cmdpkt.h" |
15 | #include "rtl_dm.h" |
16 | #include "rtl_wx.h" |
17 | |
18 | static int WDCAPARA_ADD[] = {EDCAPARA_BE, EDCAPARA_BK, EDCAPARA_VI, |
19 | EDCAPARA_VO}; |
20 | |
21 | static void _rtl92e_update_msr(struct net_device *dev) |
22 | { |
23 | struct r8192_priv *priv = rtllib_priv(dev); |
24 | u8 msr; |
25 | |
26 | msr = rtl92e_readb(dev, x: MSR); |
27 | msr &= ~MSR_LINK_MASK; |
28 | |
29 | switch (priv->rtllib->iw_mode) { |
30 | case IW_MODE_INFRA: |
31 | if (priv->rtllib->link_state == MAC80211_LINKED) |
32 | msr |= MSR_LINK_MANAGED; |
33 | break; |
34 | default: |
35 | break; |
36 | } |
37 | |
38 | rtl92e_writeb(dev, x: MSR, y: msr); |
39 | } |
40 | |
41 | void rtl92e_set_reg(struct net_device *dev, u8 variable, u8 *val) |
42 | { |
43 | struct r8192_priv *priv = rtllib_priv(dev); |
44 | |
45 | switch (variable) { |
46 | case HW_VAR_BSSID: |
47 | /* BSSIDR 2 byte alignment */ |
48 | rtl92e_writew(dev, x: BSSIDR, y: *(u16 *)val); |
49 | rtl92e_writel(dev, x: BSSIDR + 2, y: *(u32 *)(val + 2)); |
50 | break; |
51 | |
52 | case HW_VAR_MEDIA_STATUS: |
53 | { |
54 | enum rt_op_mode op_mode = *((enum rt_op_mode *)(val)); |
55 | u8 btMsr = rtl92e_readb(dev, x: MSR); |
56 | |
57 | btMsr &= 0xfc; |
58 | |
59 | switch (op_mode) { |
60 | case RT_OP_MODE_INFRASTRUCTURE: |
61 | btMsr |= MSR_INFRA; |
62 | break; |
63 | |
64 | case RT_OP_MODE_IBSS: |
65 | btMsr |= MSR_ADHOC; |
66 | break; |
67 | |
68 | case RT_OP_MODE_AP: |
69 | btMsr |= MSR_AP; |
70 | break; |
71 | |
72 | default: |
73 | btMsr |= MSR_NOLINK; |
74 | break; |
75 | } |
76 | |
77 | rtl92e_writeb(dev, x: MSR, y: btMsr); |
78 | } |
79 | break; |
80 | |
81 | case HW_VAR_CECHK_BSSID: |
82 | { |
83 | u32 RegRCR, Type; |
84 | |
85 | Type = val[0]; |
86 | RegRCR = rtl92e_readl(dev, x: RCR); |
87 | priv->receive_config = RegRCR; |
88 | |
89 | if (Type) |
90 | RegRCR |= (RCR_CBSSID); |
91 | else |
92 | RegRCR &= (~RCR_CBSSID); |
93 | |
94 | rtl92e_writel(dev, x: RCR, y: RegRCR); |
95 | priv->receive_config = RegRCR; |
96 | } |
97 | break; |
98 | |
99 | case HW_VAR_SLOT_TIME: |
100 | |
101 | priv->slot_time = val[0]; |
102 | rtl92e_writeb(dev, x: SLOT_TIME, y: val[0]); |
103 | |
104 | break; |
105 | |
106 | case HW_VAR_ACK_PREAMBLE: |
107 | { |
108 | u32 regTmp; |
109 | |
110 | priv->short_preamble = (bool)*val; |
111 | regTmp = priv->basic_rate; |
112 | if (priv->short_preamble) |
113 | regTmp |= BRSR_AckShortPmb; |
114 | rtl92e_writel(dev, x: RRSR, y: regTmp); |
115 | break; |
116 | } |
117 | |
118 | case HW_VAR_CPU_RST: |
119 | rtl92e_writel(dev, x: CPU_GEN, y: ((u32 *)(val))[0]); |
120 | break; |
121 | |
122 | case HW_VAR_AC_PARAM: |
123 | { |
124 | u8 pAcParam = *val; |
125 | u32 eACI = pAcParam; |
126 | u8 u1bAIFS; |
127 | u32 u4bAcParam; |
128 | u8 mode = priv->rtllib->mode; |
129 | struct rtllib_qos_parameters *qop = |
130 | &priv->rtllib->current_network.qos_data.parameters; |
131 | |
132 | u1bAIFS = qop->aifs[pAcParam] * |
133 | ((mode & (WIRELESS_MODE_G | WIRELESS_MODE_N_24G)) ? 9 : 20) + aSifsTime; |
134 | |
135 | rtl92e_dm_init_edca_turbo(dev); |
136 | |
137 | u4bAcParam = (le16_to_cpu(qop->tx_op_limit[pAcParam]) << |
138 | AC_PARAM_TXOP_LIMIT_OFFSET) | |
139 | ((le16_to_cpu(qop->cw_max[pAcParam])) << |
140 | AC_PARAM_ECW_MAX_OFFSET) | |
141 | ((le16_to_cpu(qop->cw_min[pAcParam])) << |
142 | AC_PARAM_ECW_MIN_OFFSET) | |
143 | (((u32)u1bAIFS) << AC_PARAM_AIFS_OFFSET); |
144 | |
145 | switch (eACI) { |
146 | case AC1_BK: |
147 | rtl92e_writel(dev, x: EDCAPARA_BK, y: u4bAcParam); |
148 | break; |
149 | |
150 | case AC0_BE: |
151 | rtl92e_writel(dev, x: EDCAPARA_BE, y: u4bAcParam); |
152 | break; |
153 | |
154 | case AC2_VI: |
155 | rtl92e_writel(dev, x: EDCAPARA_VI, y: u4bAcParam); |
156 | break; |
157 | |
158 | case AC3_VO: |
159 | rtl92e_writel(dev, x: EDCAPARA_VO, y: u4bAcParam); |
160 | break; |
161 | |
162 | default: |
163 | netdev_info(dev, format: "SetHwReg8185(): invalid ACI: %d !\n" , |
164 | eACI); |
165 | break; |
166 | } |
167 | priv->rtllib->set_hw_reg_handler(dev, HW_VAR_ACM_CTRL, |
168 | &pAcParam); |
169 | break; |
170 | } |
171 | |
172 | case HW_VAR_ACM_CTRL: |
173 | { |
174 | struct rtllib_qos_parameters *qos_parameters = |
175 | &priv->rtllib->current_network.qos_data.parameters; |
176 | u8 pAcParam = *val; |
177 | u32 eACI = pAcParam; |
178 | union aci_aifsn *pAciAifsn = (union aci_aifsn *)& |
179 | (qos_parameters->aifs[0]); |
180 | u8 acm = pAciAifsn->f.acm; |
181 | u8 AcmCtrl = rtl92e_readb(dev, x: ACM_HW_CTRL); |
182 | |
183 | if (acm) { |
184 | switch (eACI) { |
185 | case AC0_BE: |
186 | AcmCtrl |= ACM_HW_BEQ_EN; |
187 | break; |
188 | |
189 | case AC2_VI: |
190 | AcmCtrl |= ACM_HW_VIQ_EN; |
191 | break; |
192 | |
193 | case AC3_VO: |
194 | AcmCtrl |= ACM_HW_VOQ_EN; |
195 | break; |
196 | } |
197 | } else { |
198 | switch (eACI) { |
199 | case AC0_BE: |
200 | AcmCtrl &= (~ACM_HW_BEQ_EN); |
201 | break; |
202 | |
203 | case AC2_VI: |
204 | AcmCtrl &= (~ACM_HW_VIQ_EN); |
205 | break; |
206 | |
207 | case AC3_VO: |
208 | AcmCtrl &= (~ACM_HW_BEQ_EN); |
209 | break; |
210 | |
211 | default: |
212 | break; |
213 | } |
214 | } |
215 | rtl92e_writeb(dev, x: ACM_HW_CTRL, y: AcmCtrl); |
216 | break; |
217 | } |
218 | |
219 | case HW_VAR_SIFS: |
220 | rtl92e_writeb(dev, x: SIFS, y: val[0]); |
221 | rtl92e_writeb(dev, x: SIFS + 1, y: val[0]); |
222 | break; |
223 | |
224 | case HW_VAR_RF_TIMING: |
225 | { |
226 | u8 Rf_Timing = *val; |
227 | |
228 | rtl92e_writeb(dev, rFPGA0_RFTiming1, y: Rf_Timing); |
229 | break; |
230 | } |
231 | |
232 | default: |
233 | break; |
234 | } |
235 | } |
236 | |
237 | static void _rtl92e_read_eeprom_info(struct net_device *dev) |
238 | { |
239 | struct r8192_priv *priv = rtllib_priv(dev); |
240 | const u8 bMac_Tmp_Addr[ETH_ALEN] = {0x00, 0xe0, 0x4c, 0x00, 0x00, 0x01}; |
241 | u8 tempval; |
242 | u8 ICVer8192, ICVer8256; |
243 | u16 i, usValue, IC_Version; |
244 | u16 EEPROMId; |
245 | |
246 | EEPROMId = rtl92e_eeprom_read(dev, addr: 0); |
247 | if (EEPROMId != RTL8190_EEPROM_ID) { |
248 | netdev_err(dev, format: "%s(): Invalid EEPROM ID: %x\n" , __func__, |
249 | EEPROMId); |
250 | priv->autoload_fail_flag = true; |
251 | } else { |
252 | priv->autoload_fail_flag = false; |
253 | } |
254 | |
255 | if (!priv->autoload_fail_flag) { |
256 | priv->eeprom_vid = rtl92e_eeprom_read(dev, EEPROM_VID >> 1); |
257 | priv->eeprom_did = rtl92e_eeprom_read(dev, EEPROM_DID >> 1); |
258 | |
259 | usValue = rtl92e_eeprom_read(dev, |
260 | addr: (EEPROM_Customer_ID >> 1)) >> 8; |
261 | priv->eeprom_customer_id = usValue & 0xff; |
262 | usValue = rtl92e_eeprom_read(dev, |
263 | EEPROM_ICVersion_ChannelPlan >> 1); |
264 | IC_Version = (usValue & 0xff00) >> 8; |
265 | |
266 | ICVer8192 = IC_Version & 0xf; |
267 | ICVer8256 = (IC_Version & 0xf0) >> 4; |
268 | if (ICVer8192 == 0x2) { |
269 | if (ICVer8256 == 0x5) |
270 | priv->card_8192_version = VERSION_8190_BE; |
271 | } |
272 | switch (priv->card_8192_version) { |
273 | case VERSION_8190_BD: |
274 | case VERSION_8190_BE: |
275 | break; |
276 | default: |
277 | priv->card_8192_version = VERSION_8190_BD; |
278 | break; |
279 | } |
280 | } else { |
281 | priv->card_8192_version = VERSION_8190_BD; |
282 | priv->eeprom_vid = 0; |
283 | priv->eeprom_did = 0; |
284 | priv->eeprom_customer_id = 0; |
285 | } |
286 | |
287 | if (!priv->autoload_fail_flag) { |
288 | u8 addr[ETH_ALEN]; |
289 | |
290 | for (i = 0; i < 6; i += 2) { |
291 | usValue = rtl92e_eeprom_read(dev, |
292 | addr: (EEPROM_NODE_ADDRESS_BYTE_0 + i) >> 1); |
293 | *(u16 *)(&addr[i]) = usValue; |
294 | } |
295 | eth_hw_addr_set(dev, addr); |
296 | } else { |
297 | eth_hw_addr_set(dev, addr: bMac_Tmp_Addr); |
298 | } |
299 | |
300 | if (priv->card_8192_version > VERSION_8190_BD) |
301 | priv->tx_pwr_data_read_from_eeprom = true; |
302 | else |
303 | priv->tx_pwr_data_read_from_eeprom = false; |
304 | |
305 | if (priv->card_8192_version > VERSION_8190_BD) { |
306 | if (!priv->autoload_fail_flag) { |
307 | tempval = (rtl92e_eeprom_read(dev, |
308 | addr: (EEPROM_RFInd_PowerDiff >> 1))) & 0xff; |
309 | priv->eeprom_legacy_ht_tx_pwr_diff = tempval & 0xf; |
310 | } else { |
311 | priv->eeprom_legacy_ht_tx_pwr_diff = 0x04; |
312 | } |
313 | |
314 | if (!priv->autoload_fail_flag) |
315 | priv->eeprom_thermal_meter = ((rtl92e_eeprom_read(dev, |
316 | addr: (EEPROM_ThermalMeter >> 1))) & |
317 | 0xff00) >> 8; |
318 | else |
319 | priv->eeprom_thermal_meter = EEPROM_Default_ThermalMeter; |
320 | priv->tssi_13dBm = priv->eeprom_thermal_meter * 100; |
321 | |
322 | if (priv->epromtype == EEPROM_93C46) { |
323 | if (!priv->autoload_fail_flag) { |
324 | usValue = rtl92e_eeprom_read(dev, |
325 | EEPROM_TxPwDiff_CrystalCap >> 1); |
326 | priv->eeprom_ant_pwr_diff = usValue & 0x0fff; |
327 | priv->eeprom_crystal_cap = (usValue & 0xf000) |
328 | >> 12; |
329 | } else { |
330 | priv->eeprom_ant_pwr_diff = |
331 | EEPROM_Default_AntTxPowerDiff; |
332 | priv->eeprom_crystal_cap = |
333 | EEPROM_Default_TxPwDiff_CrystalCap; |
334 | } |
335 | |
336 | for (i = 0; i < 14; i += 2) { |
337 | if (!priv->autoload_fail_flag) |
338 | usValue = rtl92e_eeprom_read(dev, |
339 | addr: (EEPROM_TxPwIndex_CCK + i) >> 1); |
340 | else |
341 | usValue = EEPROM_Default_TxPower; |
342 | *((u16 *)(&priv->eeprom_tx_pwr_level_cck[i])) = |
343 | usValue; |
344 | } |
345 | for (i = 0; i < 14; i += 2) { |
346 | if (!priv->autoload_fail_flag) |
347 | usValue = rtl92e_eeprom_read(dev, |
348 | addr: (EEPROM_TxPwIndex_OFDM_24G + i) >> 1); |
349 | else |
350 | usValue = EEPROM_Default_TxPower; |
351 | *((u16 *)(&priv->eeprom_tx_pwr_level_ofdm24g[i])) |
352 | = usValue; |
353 | } |
354 | } |
355 | if (priv->epromtype == EEPROM_93C46) { |
356 | for (i = 0; i < 14; i++) { |
357 | priv->tx_pwr_level_cck[i] = |
358 | priv->eeprom_tx_pwr_level_cck[i]; |
359 | priv->tx_pwr_level_ofdm_24g[i] = |
360 | priv->eeprom_tx_pwr_level_ofdm24g[i]; |
361 | } |
362 | priv->legacy_ht_tx_pwr_diff = |
363 | priv->eeprom_legacy_ht_tx_pwr_diff; |
364 | priv->antenna_tx_pwr_diff[0] = priv->eeprom_ant_pwr_diff & 0xf; |
365 | priv->antenna_tx_pwr_diff[1] = (priv->eeprom_ant_pwr_diff & |
366 | 0xf0) >> 4; |
367 | priv->antenna_tx_pwr_diff[2] = (priv->eeprom_ant_pwr_diff & |
368 | 0xf00) >> 8; |
369 | priv->crystal_cap = priv->eeprom_crystal_cap; |
370 | priv->thermal_meter[0] = priv->eeprom_thermal_meter & 0xf; |
371 | priv->thermal_meter[1] = (priv->eeprom_thermal_meter & |
372 | 0xf0) >> 4; |
373 | } else if (priv->epromtype == EEPROM_93C56) { |
374 | priv->legacy_ht_tx_pwr_diff = |
375 | priv->eeprom_legacy_ht_tx_pwr_diff; |
376 | priv->antenna_tx_pwr_diff[0] = 0; |
377 | priv->antenna_tx_pwr_diff[1] = 0; |
378 | priv->antenna_tx_pwr_diff[2] = 0; |
379 | priv->crystal_cap = priv->eeprom_crystal_cap; |
380 | priv->thermal_meter[0] = priv->eeprom_thermal_meter & 0xf; |
381 | priv->thermal_meter[1] = (priv->eeprom_thermal_meter & |
382 | 0xf0) >> 4; |
383 | } |
384 | } |
385 | |
386 | rtl92e_init_adaptive_rate(dev); |
387 | |
388 | switch (priv->eeprom_customer_id) { |
389 | case EEPROM_CID_NetCore: |
390 | priv->customer_id = RT_CID_819X_NETCORE; |
391 | break; |
392 | case EEPROM_CID_TOSHIBA: |
393 | priv->customer_id = RT_CID_TOSHIBA; |
394 | break; |
395 | } |
396 | |
397 | if (priv->eeprom_vid == 0x1186 && priv->eeprom_did == 0x3304) |
398 | priv->rtllib->bSupportRemoteWakeUp = true; |
399 | else |
400 | priv->rtllib->bSupportRemoteWakeUp = false; |
401 | } |
402 | |
403 | void rtl92e_get_eeprom_size(struct net_device *dev) |
404 | { |
405 | u16 curCR; |
406 | struct r8192_priv *priv = rtllib_priv(dev); |
407 | |
408 | curCR = rtl92e_readw(dev, x: EPROM_CMD); |
409 | priv->epromtype = (curCR & EPROM_CMD_9356SEL) ? EEPROM_93C56 : |
410 | EEPROM_93C46; |
411 | _rtl92e_read_eeprom_info(dev); |
412 | } |
413 | |
414 | static void _rtl92e_hwconfig(struct net_device *dev) |
415 | { |
416 | u32 regRATR = 0, regRRSR = 0; |
417 | u8 regBwOpMode = 0, regTmp = 0; |
418 | struct r8192_priv *priv = rtllib_priv(dev); |
419 | |
420 | switch (priv->rtllib->mode) { |
421 | case WIRELESS_MODE_B: |
422 | regBwOpMode = BW_OPMODE_20MHZ; |
423 | regRATR = RATE_ALL_CCK; |
424 | regRRSR = RATE_ALL_CCK; |
425 | break; |
426 | case WIRELESS_MODE_AUTO: |
427 | case WIRELESS_MODE_N_24G: |
428 | regBwOpMode = BW_OPMODE_20MHZ; |
429 | regRATR = RATE_ALL_CCK | RATE_ALL_OFDM_AG | |
430 | RATE_ALL_OFDM_1SS | RATE_ALL_OFDM_2SS; |
431 | regRRSR = RATE_ALL_CCK | RATE_ALL_OFDM_AG; |
432 | break; |
433 | case WIRELESS_MODE_G: |
434 | default: |
435 | regBwOpMode = BW_OPMODE_20MHZ; |
436 | regRATR = RATE_ALL_CCK | RATE_ALL_OFDM_AG; |
437 | regRRSR = RATE_ALL_CCK | RATE_ALL_OFDM_AG; |
438 | break; |
439 | } |
440 | |
441 | rtl92e_writeb(dev, x: BW_OPMODE, y: regBwOpMode); |
442 | { |
443 | u32 ratr_value; |
444 | |
445 | ratr_value = regRATR; |
446 | ratr_value &= ~(RATE_ALL_OFDM_2SS); |
447 | rtl92e_writel(dev, x: RATR0, y: ratr_value); |
448 | rtl92e_writeb(dev, x: UFWP, y: 1); |
449 | } |
450 | regTmp = rtl92e_readb(dev, x: 0x313); |
451 | regRRSR = ((regTmp) << 24) | (regRRSR & 0x00ffffff); |
452 | rtl92e_writel(dev, x: RRSR, y: regRRSR); |
453 | |
454 | rtl92e_writew(dev, x: RETRY_LIMIT, |
455 | y: priv->short_retry_limit << RETRY_LIMIT_SHORT_SHIFT | |
456 | priv->long_retry_limit << RETRY_LIMIT_LONG_SHIFT); |
457 | } |
458 | |
459 | bool rtl92e_start_adapter(struct net_device *dev) |
460 | { |
461 | struct r8192_priv *priv = rtllib_priv(dev); |
462 | u32 ulRegRead; |
463 | bool rtStatus = true; |
464 | u8 tmpvalue; |
465 | u8 ICVersion, SwitchingRegulatorOutput; |
466 | bool bfirmwareok = true; |
467 | u32 tmpRegA, TempCCk; |
468 | int i = 0; |
469 | u32 retry_times = 0; |
470 | |
471 | priv->being_init_adapter = true; |
472 | |
473 | start: |
474 | rtl92e_reset_desc_ring(dev); |
475 | priv->rf_mode = RF_OP_By_SW_3wire; |
476 | |
477 | rtl92e_writeb(dev, x: ANAPAR, y: 0x37); |
478 | mdelay(500); |
479 | |
480 | priv->fw_info->status = FW_STATUS_0_INIT; |
481 | |
482 | ulRegRead = rtl92e_readl(dev, x: CPU_GEN); |
483 | if (priv->fw_info->status == FW_STATUS_0_INIT) |
484 | ulRegRead |= CPU_GEN_SYSTEM_RESET; |
485 | else if (priv->fw_info->status == FW_STATUS_5_READY) |
486 | ulRegRead |= CPU_GEN_FIRMWARE_RESET; |
487 | else |
488 | netdev_err(dev, format: "%s(): undefined firmware state: %d.\n" , |
489 | __func__, priv->fw_info->status); |
490 | |
491 | rtl92e_writel(dev, x: CPU_GEN, y: ulRegRead); |
492 | |
493 | ICVersion = rtl92e_readb(dev, x: IC_VERRSION); |
494 | if (ICVersion >= 0x4) { |
495 | SwitchingRegulatorOutput = rtl92e_readb(dev, x: SWREGULATOR); |
496 | if (SwitchingRegulatorOutput != 0xb8) { |
497 | rtl92e_writeb(dev, x: SWREGULATOR, y: 0xa8); |
498 | mdelay(1); |
499 | rtl92e_writeb(dev, x: SWREGULATOR, y: 0xb8); |
500 | } |
501 | } |
502 | rtStatus = rtl92e_config_bb(dev); |
503 | if (!rtStatus) { |
504 | netdev_warn(dev, format: "%s(): Failed to configure BB\n" , __func__); |
505 | return rtStatus; |
506 | } |
507 | |
508 | priv->loopback_mode = RTL819X_NO_LOOPBACK; |
509 | ulRegRead = rtl92e_readl(dev, x: CPU_GEN); |
510 | if (priv->loopback_mode == RTL819X_NO_LOOPBACK) |
511 | ulRegRead = (ulRegRead & CPU_GEN_NO_LOOPBACK_MSK) | |
512 | CPU_GEN_NO_LOOPBACK_SET; |
513 | else if (priv->loopback_mode == RTL819X_MAC_LOOPBACK) |
514 | ulRegRead |= CPU_CCK_LOOPBACK; |
515 | else |
516 | netdev_err(dev, format: "%s: Invalid loopback mode setting.\n" , |
517 | __func__); |
518 | |
519 | rtl92e_writel(dev, x: CPU_GEN, y: ulRegRead); |
520 | |
521 | udelay(500); |
522 | |
523 | _rtl92e_hwconfig(dev); |
524 | rtl92e_writeb(dev, x: CMDR, CR_RE | CR_TE); |
525 | |
526 | rtl92e_writeb(dev, x: PCIF, y: ((MXDMA2_NO_LIMIT << MXDMA2_RX_SHIFT) | |
527 | (MXDMA2_NO_LIMIT << MXDMA2_TX_SHIFT))); |
528 | rtl92e_writel(dev, x: MAC0, y: ((u32 *)dev->dev_addr)[0]); |
529 | rtl92e_writew(dev, x: MAC4, y: ((u16 *)(dev->dev_addr + 4))[0]); |
530 | rtl92e_writel(dev, x: RCR, y: priv->receive_config); |
531 | |
532 | rtl92e_writel(dev, x: RQPN1, NUM_OF_PAGE_IN_FW_QUEUE_BK << |
533 | RSVD_FW_QUEUE_PAGE_BK_SHIFT | |
534 | NUM_OF_PAGE_IN_FW_QUEUE_BE << |
535 | RSVD_FW_QUEUE_PAGE_BE_SHIFT | |
536 | NUM_OF_PAGE_IN_FW_QUEUE_VI << |
537 | RSVD_FW_QUEUE_PAGE_VI_SHIFT | |
538 | NUM_OF_PAGE_IN_FW_QUEUE_VO << |
539 | RSVD_FW_QUEUE_PAGE_VO_SHIFT); |
540 | rtl92e_writel(dev, x: RQPN2, NUM_OF_PAGE_IN_FW_QUEUE_MGNT << |
541 | RSVD_FW_QUEUE_PAGE_MGNT_SHIFT); |
542 | rtl92e_writel(dev, x: RQPN3, APPLIED_RESERVED_QUEUE_IN_FW | |
543 | NUM_OF_PAGE_IN_FW_QUEUE_BCN << |
544 | RSVD_FW_QUEUE_PAGE_BCN_SHIFT | |
545 | NUM_OF_PAGE_IN_FW_QUEUE_PUB << |
546 | RSVD_FW_QUEUE_PAGE_PUB_SHIFT); |
547 | |
548 | rtl92e_tx_enable(dev); |
549 | rtl92e_rx_enable(dev); |
550 | ulRegRead = (0xFFF00000 & rtl92e_readl(dev, x: RRSR)) | |
551 | RATE_ALL_OFDM_AG | RATE_ALL_CCK; |
552 | rtl92e_writel(dev, x: RRSR, y: ulRegRead); |
553 | rtl92e_writel(dev, x: RATR0 + 4 * 7, y: (RATE_ALL_OFDM_AG | RATE_ALL_CCK)); |
554 | |
555 | rtl92e_writeb(dev, x: ACK_TIMEOUT, y: 0x30); |
556 | |
557 | rtl92e_set_wireless_mode(dev, wireless_mode: priv->rtllib->mode); |
558 | rtl92e_cam_reset(dev); |
559 | { |
560 | u8 SECR_value = 0x0; |
561 | |
562 | SECR_value |= SCR_TxEncEnable; |
563 | SECR_value |= SCR_RxDecEnable; |
564 | SECR_value |= SCR_NoSKMC; |
565 | rtl92e_writeb(dev, x: SECR, y: SECR_value); |
566 | } |
567 | rtl92e_writew(dev, x: ATIMWND, y: 2); |
568 | rtl92e_writew(dev, x: BCN_INTERVAL, y: 100); |
569 | |
570 | for (i = 0; i < QOS_QUEUE_NUM; i++) |
571 | rtl92e_writel(dev, x: WDCAPARA_ADD[i], y: 0x005e4332); |
572 | |
573 | rtl92e_writeb(dev, x: 0xbe, y: 0xc0); |
574 | |
575 | rtl92e_config_mac(dev); |
576 | |
577 | if (priv->card_8192_version > VERSION_8190_BD) { |
578 | rtl92e_get_tx_power(dev); |
579 | rtl92e_set_tx_power(dev, channel: priv->chan); |
580 | } |
581 | |
582 | tmpvalue = rtl92e_readb(dev, x: IC_VERRSION); |
583 | priv->ic_cut = tmpvalue; |
584 | |
585 | bfirmwareok = rtl92e_init_fw(dev); |
586 | if (!bfirmwareok) { |
587 | if (retry_times < 10) { |
588 | retry_times++; |
589 | goto start; |
590 | } else { |
591 | rtStatus = false; |
592 | goto end; |
593 | } |
594 | } |
595 | |
596 | rtStatus = rtl92e_config_rf(dev); |
597 | if (!rtStatus) { |
598 | netdev_info(dev, format: "RF Config failed\n" ); |
599 | return rtStatus; |
600 | } |
601 | |
602 | rtl92e_set_bb_reg(dev, rFPGA0_RFMOD, bCCKEn, dwData: 0x1); |
603 | rtl92e_set_bb_reg(dev, rFPGA0_RFMOD, bOFDMEn, dwData: 0x1); |
604 | |
605 | rtl92e_writeb(dev, x: 0x87, y: 0x0); |
606 | |
607 | if (priv->rtllib->rf_off_reason > RF_CHANGE_BY_PS) { |
608 | rtl92e_set_rf_state(dev, state_to_set: rf_off, change_source: priv->rtllib->rf_off_reason); |
609 | } else if (priv->rtllib->rf_off_reason >= RF_CHANGE_BY_IPS) { |
610 | rtl92e_set_rf_state(dev, state_to_set: rf_off, change_source: priv->rtllib->rf_off_reason); |
611 | } else { |
612 | priv->rtllib->rf_power_state = rf_on; |
613 | priv->rtllib->rf_off_reason = 0; |
614 | } |
615 | |
616 | if (priv->rtllib->FwRWRF) |
617 | priv->rf_mode = RF_OP_By_FW; |
618 | else |
619 | priv->rf_mode = RF_OP_By_SW_3wire; |
620 | |
621 | rtl92e_dm_init_txpower_tracking(dev); |
622 | |
623 | if (priv->ic_cut >= IC_VersionCut_D) { |
624 | tmpRegA = rtl92e_get_bb_reg(dev, rOFDM0_XATxIQImbalance, |
625 | bMaskDWord); |
626 | rtl92e_get_bb_reg(dev, rOFDM0_XCTxIQImbalance, bMaskDWord); |
627 | |
628 | for (i = 0; i < TX_BB_GAIN_TABLE_LEN; i++) { |
629 | if (tmpRegA == dm_tx_bb_gain[i]) { |
630 | priv->rfa_txpowertrackingindex = i; |
631 | priv->rfa_txpowertrackingindex_real = i; |
632 | priv->rfa_txpowertracking_default = |
633 | priv->rfa_txpowertrackingindex; |
634 | break; |
635 | } |
636 | } |
637 | |
638 | TempCCk = rtl92e_get_bb_reg(dev, rCCK0_TxFilter1, |
639 | bMaskByte2); |
640 | |
641 | for (i = 0; i < CCK_TX_BB_GAIN_TABLE_LEN; i++) { |
642 | if (TempCCk == dm_cck_tx_bb_gain[i][0]) { |
643 | priv->cck_present_attn_20m_def = i; |
644 | break; |
645 | } |
646 | } |
647 | priv->cck_present_attn_40m_def = 0; |
648 | priv->cck_present_attn_diff = 0; |
649 | priv->cck_present_attn = |
650 | priv->cck_present_attn_20m_def; |
651 | priv->btxpower_tracking = false; |
652 | } |
653 | rtl92e_irq_enable(dev); |
654 | end: |
655 | priv->being_init_adapter = false; |
656 | return rtStatus; |
657 | } |
658 | |
659 | static void _rtl92e_net_update(struct net_device *dev) |
660 | { |
661 | struct r8192_priv *priv = rtllib_priv(dev); |
662 | struct rtllib_network *net; |
663 | u16 rate_config = 0; |
664 | |
665 | net = &priv->rtllib->current_network; |
666 | rtl92e_config_rate(dev, rate_config: &rate_config); |
667 | priv->dot11_current_preamble_mode = PREAMBLE_AUTO; |
668 | priv->basic_rate = rate_config &= 0x15f; |
669 | rtl92e_writew(dev, x: BSSIDR, y: *(u16 *)net->bssid); |
670 | rtl92e_writel(dev, x: BSSIDR + 2, y: *(u32 *)(net->bssid + 2)); |
671 | } |
672 | |
673 | void rtl92e_link_change(struct net_device *dev) |
674 | { |
675 | struct r8192_priv *priv = rtllib_priv(dev); |
676 | struct rtllib_device *ieee = priv->rtllib; |
677 | |
678 | if (!priv->up) |
679 | return; |
680 | |
681 | if (ieee->link_state == MAC80211_LINKED) { |
682 | _rtl92e_net_update(dev); |
683 | rtl92e_update_ratr_table(dev); |
684 | if ((ieee->pairwise_key_type == KEY_TYPE_WEP40) || |
685 | (ieee->pairwise_key_type == KEY_TYPE_WEP104)) |
686 | rtl92e_enable_hw_security_config(dev); |
687 | } else { |
688 | rtl92e_writeb(dev, x: 0x173, y: 0); |
689 | } |
690 | _rtl92e_update_msr(dev); |
691 | |
692 | if (ieee->iw_mode == IW_MODE_INFRA) { |
693 | u32 reg; |
694 | |
695 | reg = rtl92e_readl(dev, x: RCR); |
696 | if (priv->rtllib->link_state == MAC80211_LINKED) |
697 | priv->receive_config = reg |= RCR_CBSSID; |
698 | else |
699 | priv->receive_config = reg &= ~RCR_CBSSID; |
700 | |
701 | rtl92e_writel(dev, x: RCR, y: reg); |
702 | } |
703 | } |
704 | |
705 | void rtl92e_set_monitor_mode(struct net_device *dev, bool bAllowAllDA, |
706 | bool WriteIntoReg) |
707 | { |
708 | struct r8192_priv *priv = rtllib_priv(dev); |
709 | |
710 | if (bAllowAllDA) |
711 | priv->receive_config |= RCR_AAP; |
712 | else |
713 | priv->receive_config &= ~RCR_AAP; |
714 | |
715 | if (WriteIntoReg) |
716 | rtl92e_writel(dev, x: RCR, y: priv->receive_config); |
717 | } |
718 | |
719 | static u8 _rtl92e_rate_mgn_to_hw(u8 rate) |
720 | { |
721 | u8 ret = DESC90_RATE1M; |
722 | |
723 | switch (rate) { |
724 | case MGN_1M: |
725 | ret = DESC90_RATE1M; |
726 | break; |
727 | case MGN_2M: |
728 | ret = DESC90_RATE2M; |
729 | break; |
730 | case MGN_5_5M: |
731 | ret = DESC90_RATE5_5M; |
732 | break; |
733 | case MGN_11M: |
734 | ret = DESC90_RATE11M; |
735 | break; |
736 | case MGN_6M: |
737 | ret = DESC90_RATE6M; |
738 | break; |
739 | case MGN_9M: |
740 | ret = DESC90_RATE9M; |
741 | break; |
742 | case MGN_12M: |
743 | ret = DESC90_RATE12M; |
744 | break; |
745 | case MGN_18M: |
746 | ret = DESC90_RATE18M; |
747 | break; |
748 | case MGN_24M: |
749 | ret = DESC90_RATE24M; |
750 | break; |
751 | case MGN_36M: |
752 | ret = DESC90_RATE36M; |
753 | break; |
754 | case MGN_48M: |
755 | ret = DESC90_RATE48M; |
756 | break; |
757 | case MGN_54M: |
758 | ret = DESC90_RATE54M; |
759 | break; |
760 | case MGN_MCS0: |
761 | ret = DESC90_RATEMCS0; |
762 | break; |
763 | case MGN_MCS1: |
764 | ret = DESC90_RATEMCS1; |
765 | break; |
766 | case MGN_MCS2: |
767 | ret = DESC90_RATEMCS2; |
768 | break; |
769 | case MGN_MCS3: |
770 | ret = DESC90_RATEMCS3; |
771 | break; |
772 | case MGN_MCS4: |
773 | ret = DESC90_RATEMCS4; |
774 | break; |
775 | case MGN_MCS5: |
776 | ret = DESC90_RATEMCS5; |
777 | break; |
778 | case MGN_MCS6: |
779 | ret = DESC90_RATEMCS6; |
780 | break; |
781 | case MGN_MCS7: |
782 | ret = DESC90_RATEMCS7; |
783 | break; |
784 | case MGN_MCS8: |
785 | ret = DESC90_RATEMCS8; |
786 | break; |
787 | case MGN_MCS9: |
788 | ret = DESC90_RATEMCS9; |
789 | break; |
790 | case MGN_MCS10: |
791 | ret = DESC90_RATEMCS10; |
792 | break; |
793 | case MGN_MCS11: |
794 | ret = DESC90_RATEMCS11; |
795 | break; |
796 | case MGN_MCS12: |
797 | ret = DESC90_RATEMCS12; |
798 | break; |
799 | case MGN_MCS13: |
800 | ret = DESC90_RATEMCS13; |
801 | break; |
802 | case MGN_MCS14: |
803 | ret = DESC90_RATEMCS14; |
804 | break; |
805 | case MGN_MCS15: |
806 | ret = DESC90_RATEMCS15; |
807 | break; |
808 | case (0x80 | 0x20): |
809 | ret = DESC90_RATEMCS32; |
810 | break; |
811 | default: |
812 | break; |
813 | } |
814 | return ret; |
815 | } |
816 | |
817 | static u8 _rtl92e_hw_queue_to_fw_queue(struct net_device *dev, u8 QueueID, |
818 | u8 priority) |
819 | { |
820 | u8 QueueSelect = 0x0; |
821 | |
822 | switch (QueueID) { |
823 | case BE_QUEUE: |
824 | QueueSelect = QSLT_BE; |
825 | break; |
826 | |
827 | case BK_QUEUE: |
828 | QueueSelect = QSLT_BK; |
829 | break; |
830 | |
831 | case VO_QUEUE: |
832 | QueueSelect = QSLT_VO; |
833 | break; |
834 | |
835 | case VI_QUEUE: |
836 | QueueSelect = QSLT_VI; |
837 | break; |
838 | case MGNT_QUEUE: |
839 | QueueSelect = QSLT_MGNT; |
840 | break; |
841 | case BEACON_QUEUE: |
842 | QueueSelect = QSLT_BEACON; |
843 | break; |
844 | case TXCMD_QUEUE: |
845 | QueueSelect = QSLT_CMD; |
846 | break; |
847 | case HIGH_QUEUE: |
848 | QueueSelect = QSLT_HIGH; |
849 | break; |
850 | default: |
851 | netdev_warn(dev, format: "%s(): Impossible Queue Selection: %d\n" , |
852 | __func__, QueueID); |
853 | break; |
854 | } |
855 | return QueueSelect; |
856 | } |
857 | |
858 | static u8 _rtl92e_query_is_short(u8 TxHT, u8 TxRate, struct cb_desc *tcb_desc) |
859 | { |
860 | u8 tmp_Short; |
861 | |
862 | tmp_Short = (TxHT == 1) ? ((tcb_desc->bUseShortGI) ? 1 : 0) : |
863 | ((tcb_desc->bUseShortPreamble) ? 1 : 0); |
864 | if (TxHT == 1 && TxRate != DESC90_RATEMCS15) |
865 | tmp_Short = 0; |
866 | |
867 | return tmp_Short; |
868 | } |
869 | |
870 | void rtl92e_fill_tx_desc(struct net_device *dev, struct tx_desc *pdesc, |
871 | struct cb_desc *cb_desc, struct sk_buff *skb) |
872 | { |
873 | struct r8192_priv *priv = rtllib_priv(dev); |
874 | dma_addr_t mapping; |
875 | struct tx_fwinfo_8190pci *pTxFwInfo; |
876 | |
877 | pTxFwInfo = (struct tx_fwinfo_8190pci *)skb->data; |
878 | memset(pTxFwInfo, 0, sizeof(struct tx_fwinfo_8190pci)); |
879 | pTxFwInfo->TxHT = (cb_desc->data_rate & 0x80) ? 1 : 0; |
880 | pTxFwInfo->TxRate = _rtl92e_rate_mgn_to_hw(rate: cb_desc->data_rate); |
881 | pTxFwInfo->EnableCPUDur = cb_desc->tx_enable_fw_calc_dur; |
882 | pTxFwInfo->Short = _rtl92e_query_is_short(TxHT: pTxFwInfo->TxHT, |
883 | TxRate: pTxFwInfo->TxRate, tcb_desc: cb_desc); |
884 | |
885 | if (cb_desc->ampdu_enable) { |
886 | pTxFwInfo->AllowAggregation = 1; |
887 | pTxFwInfo->RxMF = cb_desc->ampdu_factor; |
888 | pTxFwInfo->RxAMD = cb_desc->ampdu_density; |
889 | } else { |
890 | pTxFwInfo->AllowAggregation = 0; |
891 | pTxFwInfo->RxMF = 0; |
892 | pTxFwInfo->RxAMD = 0; |
893 | } |
894 | |
895 | pTxFwInfo->RtsEnable = (cb_desc->bRTSEnable) ? 1 : 0; |
896 | pTxFwInfo->CtsEnable = (cb_desc->bCTSEnable) ? 1 : 0; |
897 | pTxFwInfo->RtsSTBC = (cb_desc->bRTSSTBC) ? 1 : 0; |
898 | pTxFwInfo->RtsHT = (cb_desc->rts_rate & 0x80) ? 1 : 0; |
899 | pTxFwInfo->RtsRate = _rtl92e_rate_mgn_to_hw(rate: cb_desc->rts_rate); |
900 | pTxFwInfo->RtsBandwidth = 0; |
901 | pTxFwInfo->RtsSubcarrier = cb_desc->RTSSC; |
902 | pTxFwInfo->RtsShort = (pTxFwInfo->RtsHT == 0) ? |
903 | (cb_desc->bRTSUseShortPreamble ? 1 : 0) : |
904 | (cb_desc->bRTSUseShortGI ? 1 : 0); |
905 | if (priv->current_chnl_bw == HT_CHANNEL_WIDTH_20_40) { |
906 | if (cb_desc->bPacketBW) { |
907 | pTxFwInfo->TxBandwidth = 1; |
908 | pTxFwInfo->TxSubCarrier = 0; |
909 | } else { |
910 | pTxFwInfo->TxBandwidth = 0; |
911 | pTxFwInfo->TxSubCarrier = priv->n_cur_40mhz_prime_sc; |
912 | } |
913 | } else { |
914 | pTxFwInfo->TxBandwidth = 0; |
915 | pTxFwInfo->TxSubCarrier = 0; |
916 | } |
917 | |
918 | memset((u8 *)pdesc, 0, 12); |
919 | |
920 | mapping = dma_map_single(&priv->pdev->dev, skb->data, skb->len, |
921 | DMA_TO_DEVICE); |
922 | if (dma_mapping_error(dev: &priv->pdev->dev, dma_addr: mapping)) { |
923 | netdev_err(dev, format: "%s(): DMA Mapping error\n" , __func__); |
924 | return; |
925 | } |
926 | |
927 | pdesc->LINIP = 0; |
928 | pdesc->CmdInit = 1; |
929 | pdesc->Offset = sizeof(struct tx_fwinfo_8190pci) + 8; |
930 | pdesc->PktSize = skb->len - sizeof(struct tx_fwinfo_8190pci); |
931 | |
932 | pdesc->SecCAMID = 0; |
933 | pdesc->RATid = cb_desc->ratr_index; |
934 | |
935 | pdesc->NoEnc = 1; |
936 | pdesc->SecType = 0x0; |
937 | if (cb_desc->bHwSec) { |
938 | static u8 tmp; |
939 | |
940 | if (!tmp) |
941 | tmp = 1; |
942 | switch (priv->rtllib->pairwise_key_type) { |
943 | case KEY_TYPE_WEP40: |
944 | case KEY_TYPE_WEP104: |
945 | pdesc->SecType = 0x1; |
946 | pdesc->NoEnc = 0; |
947 | break; |
948 | case KEY_TYPE_TKIP: |
949 | pdesc->SecType = 0x2; |
950 | pdesc->NoEnc = 0; |
951 | break; |
952 | case KEY_TYPE_CCMP: |
953 | pdesc->SecType = 0x3; |
954 | pdesc->NoEnc = 0; |
955 | break; |
956 | case KEY_TYPE_NA: |
957 | pdesc->SecType = 0x0; |
958 | pdesc->NoEnc = 1; |
959 | break; |
960 | } |
961 | } |
962 | |
963 | pdesc->PktId = 0x0; |
964 | |
965 | pdesc->QueueSelect = _rtl92e_hw_queue_to_fw_queue(dev, |
966 | QueueID: cb_desc->queue_index, |
967 | priority: cb_desc->priority); |
968 | pdesc->TxFWInfoSize = sizeof(struct tx_fwinfo_8190pci); |
969 | |
970 | pdesc->DISFB = cb_desc->tx_dis_rate_fallback; |
971 | pdesc->USERATE = cb_desc->tx_use_drv_assinged_rate; |
972 | |
973 | pdesc->FirstSeg = 1; |
974 | pdesc->LastSeg = 1; |
975 | pdesc->TxBufferSize = skb->len; |
976 | |
977 | pdesc->TxBuffAddr = mapping; |
978 | } |
979 | |
980 | void rtl92e_fill_tx_cmd_desc(struct net_device *dev, struct tx_desc_cmd *entry, |
981 | struct cb_desc *cb_desc, struct sk_buff *skb) |
982 | { |
983 | struct r8192_priv *priv = rtllib_priv(dev); |
984 | dma_addr_t mapping = dma_map_single(&priv->pdev->dev, skb->data, |
985 | skb->len, DMA_TO_DEVICE); |
986 | |
987 | if (dma_mapping_error(dev: &priv->pdev->dev, dma_addr: mapping)) |
988 | netdev_err(dev, format: "%s(): DMA Mapping error\n" , __func__); |
989 | memset(entry, 0, 12); |
990 | entry->LINIP = cb_desc->bLastIniPkt; |
991 | entry->FirstSeg = 1; |
992 | entry->LastSeg = 1; |
993 | if (cb_desc->bCmdOrInit == DESC_PACKET_TYPE_INIT) { |
994 | entry->CmdInit = DESC_PACKET_TYPE_INIT; |
995 | } else { |
996 | struct tx_desc *entry_tmp = (struct tx_desc *)entry; |
997 | |
998 | entry_tmp->CmdInit = DESC_PACKET_TYPE_NORMAL; |
999 | entry_tmp->Offset = sizeof(struct tx_fwinfo_8190pci) + 8; |
1000 | entry_tmp->PktSize = cb_desc->pkt_size + entry_tmp->Offset; |
1001 | entry_tmp->QueueSelect = QSLT_CMD; |
1002 | entry_tmp->TxFWInfoSize = 0x08; |
1003 | entry_tmp->RATid = DESC_PACKET_TYPE_INIT; |
1004 | } |
1005 | entry->TxBufferSize = skb->len; |
1006 | entry->TxBuffAddr = mapping; |
1007 | entry->OWN = 1; |
1008 | } |
1009 | |
1010 | static u8 _rtl92e_rate_hw_to_mgn(bool bIsHT, u8 rate) |
1011 | { |
1012 | u8 ret_rate = 0x02; |
1013 | |
1014 | if (!bIsHT) { |
1015 | switch (rate) { |
1016 | case DESC90_RATE1M: |
1017 | ret_rate = MGN_1M; |
1018 | break; |
1019 | case DESC90_RATE2M: |
1020 | ret_rate = MGN_2M; |
1021 | break; |
1022 | case DESC90_RATE5_5M: |
1023 | ret_rate = MGN_5_5M; |
1024 | break; |
1025 | case DESC90_RATE11M: |
1026 | ret_rate = MGN_11M; |
1027 | break; |
1028 | case DESC90_RATE6M: |
1029 | ret_rate = MGN_6M; |
1030 | break; |
1031 | case DESC90_RATE9M: |
1032 | ret_rate = MGN_9M; |
1033 | break; |
1034 | case DESC90_RATE12M: |
1035 | ret_rate = MGN_12M; |
1036 | break; |
1037 | case DESC90_RATE18M: |
1038 | ret_rate = MGN_18M; |
1039 | break; |
1040 | case DESC90_RATE24M: |
1041 | ret_rate = MGN_24M; |
1042 | break; |
1043 | case DESC90_RATE36M: |
1044 | ret_rate = MGN_36M; |
1045 | break; |
1046 | case DESC90_RATE48M: |
1047 | ret_rate = MGN_48M; |
1048 | break; |
1049 | case DESC90_RATE54M: |
1050 | ret_rate = MGN_54M; |
1051 | break; |
1052 | } |
1053 | |
1054 | } else { |
1055 | switch (rate) { |
1056 | case DESC90_RATEMCS0: |
1057 | ret_rate = MGN_MCS0; |
1058 | break; |
1059 | case DESC90_RATEMCS1: |
1060 | ret_rate = MGN_MCS1; |
1061 | break; |
1062 | case DESC90_RATEMCS2: |
1063 | ret_rate = MGN_MCS2; |
1064 | break; |
1065 | case DESC90_RATEMCS3: |
1066 | ret_rate = MGN_MCS3; |
1067 | break; |
1068 | case DESC90_RATEMCS4: |
1069 | ret_rate = MGN_MCS4; |
1070 | break; |
1071 | case DESC90_RATEMCS5: |
1072 | ret_rate = MGN_MCS5; |
1073 | break; |
1074 | case DESC90_RATEMCS6: |
1075 | ret_rate = MGN_MCS6; |
1076 | break; |
1077 | case DESC90_RATEMCS7: |
1078 | ret_rate = MGN_MCS7; |
1079 | break; |
1080 | case DESC90_RATEMCS8: |
1081 | ret_rate = MGN_MCS8; |
1082 | break; |
1083 | case DESC90_RATEMCS9: |
1084 | ret_rate = MGN_MCS9; |
1085 | break; |
1086 | case DESC90_RATEMCS10: |
1087 | ret_rate = MGN_MCS10; |
1088 | break; |
1089 | case DESC90_RATEMCS11: |
1090 | ret_rate = MGN_MCS11; |
1091 | break; |
1092 | case DESC90_RATEMCS12: |
1093 | ret_rate = MGN_MCS12; |
1094 | break; |
1095 | case DESC90_RATEMCS13: |
1096 | ret_rate = MGN_MCS13; |
1097 | break; |
1098 | case DESC90_RATEMCS14: |
1099 | ret_rate = MGN_MCS14; |
1100 | break; |
1101 | case DESC90_RATEMCS15: |
1102 | ret_rate = MGN_MCS15; |
1103 | break; |
1104 | case DESC90_RATEMCS32: |
1105 | ret_rate = 0x80 | 0x20; |
1106 | break; |
1107 | } |
1108 | } |
1109 | |
1110 | return ret_rate; |
1111 | } |
1112 | |
1113 | static long _rtl92e_signal_scale_mapping(struct r8192_priv *priv, long currsig) |
1114 | { |
1115 | long retsig; |
1116 | |
1117 | if (currsig >= 61 && currsig <= 100) |
1118 | retsig = 90 + ((currsig - 60) / 4); |
1119 | else if (currsig >= 41 && currsig <= 60) |
1120 | retsig = 78 + ((currsig - 40) / 2); |
1121 | else if (currsig >= 31 && currsig <= 40) |
1122 | retsig = 66 + (currsig - 30); |
1123 | else if (currsig >= 21 && currsig <= 30) |
1124 | retsig = 54 + (currsig - 20); |
1125 | else if (currsig >= 5 && currsig <= 20) |
1126 | retsig = 42 + (((currsig - 5) * 2) / 3); |
1127 | else if (currsig == 4) |
1128 | retsig = 36; |
1129 | else if (currsig == 3) |
1130 | retsig = 27; |
1131 | else if (currsig == 2) |
1132 | retsig = 18; |
1133 | else if (currsig == 1) |
1134 | retsig = 9; |
1135 | else |
1136 | retsig = currsig; |
1137 | |
1138 | return retsig; |
1139 | } |
1140 | |
1141 | #define rx_hal_is_cck_rate(_pdrvinfo)\ |
1142 | ((_pdrvinfo->RxRate == DESC90_RATE1M ||\ |
1143 | _pdrvinfo->RxRate == DESC90_RATE2M ||\ |
1144 | _pdrvinfo->RxRate == DESC90_RATE5_5M ||\ |
1145 | _pdrvinfo->RxRate == DESC90_RATE11M) &&\ |
1146 | !_pdrvinfo->RxHT) |
1147 | |
1148 | static void _rtl92e_query_rxphystatus( |
1149 | struct r8192_priv *priv, |
1150 | struct rtllib_rx_stats *pstats, |
1151 | struct rx_desc *pdesc, |
1152 | struct rx_fwinfo *pdrvinfo, |
1153 | struct rtllib_rx_stats *precord_stats, |
1154 | bool bpacket_match_bssid, |
1155 | bool bpacket_toself, |
1156 | bool bPacketBeacon, |
1157 | bool bToSelfBA |
1158 | ) |
1159 | { |
1160 | struct phy_sts_ofdm_819xpci *pofdm_buf; |
1161 | struct phy_sts_cck_819xpci *pcck_buf; |
1162 | u8 *prxpkt; |
1163 | u8 i, max_spatial_stream, tmp_rxevm; |
1164 | s8 rx_pwr[4], rx_pwr_all = 0; |
1165 | s8 rx_evmX; |
1166 | u8 evm, pwdb_all; |
1167 | u32 , = 0; |
1168 | u8 is_cck_rate = 0; |
1169 | u8 rf_rx_num = 0; |
1170 | static u8 check_reg824; |
1171 | static u32 reg824_bit9; |
1172 | |
1173 | is_cck_rate = rx_hal_is_cck_rate(pdrvinfo); |
1174 | memset(precord_stats, 0, sizeof(struct rtllib_rx_stats)); |
1175 | pstats->bPacketMatchBSSID = precord_stats->bPacketMatchBSSID = |
1176 | bpacket_match_bssid; |
1177 | pstats->bPacketToSelf = precord_stats->bPacketToSelf = bpacket_toself; |
1178 | pstats->bIsCCK = precord_stats->bIsCCK = is_cck_rate; |
1179 | pstats->bPacketBeacon = precord_stats->bPacketBeacon = bPacketBeacon; |
1180 | pstats->bToSelfBA = precord_stats->bToSelfBA = bToSelfBA; |
1181 | if (check_reg824 == 0) { |
1182 | reg824_bit9 = rtl92e_get_bb_reg(dev: priv->rtllib->dev, |
1183 | rFPGA0_XA_HSSIParameter2, |
1184 | dwBitMask: 0x200); |
1185 | check_reg824 = 1; |
1186 | } |
1187 | |
1188 | prxpkt = (u8 *)pdrvinfo; |
1189 | |
1190 | prxpkt += sizeof(struct rx_fwinfo); |
1191 | |
1192 | pcck_buf = (struct phy_sts_cck_819xpci *)prxpkt; |
1193 | pofdm_buf = (struct phy_sts_ofdm_819xpci *)prxpkt; |
1194 | |
1195 | pstats->RxMIMOSignalQuality[0] = -1; |
1196 | pstats->RxMIMOSignalQuality[1] = -1; |
1197 | precord_stats->RxMIMOSignalQuality[0] = -1; |
1198 | precord_stats->RxMIMOSignalQuality[1] = -1; |
1199 | |
1200 | if (is_cck_rate) { |
1201 | u8 report; |
1202 | |
1203 | if (!reg824_bit9) { |
1204 | report = pcck_buf->cck_agc_rpt & 0xc0; |
1205 | report >>= 6; |
1206 | switch (report) { |
1207 | case 0x3: |
1208 | rx_pwr_all = -35 - (pcck_buf->cck_agc_rpt & |
1209 | 0x3e); |
1210 | break; |
1211 | case 0x2: |
1212 | rx_pwr_all = -23 - (pcck_buf->cck_agc_rpt & |
1213 | 0x3e); |
1214 | break; |
1215 | case 0x1: |
1216 | rx_pwr_all = -11 - (pcck_buf->cck_agc_rpt & |
1217 | 0x3e); |
1218 | break; |
1219 | case 0x0: |
1220 | rx_pwr_all = 8 - (pcck_buf->cck_agc_rpt & 0x3e); |
1221 | break; |
1222 | } |
1223 | } else { |
1224 | report = pcck_buf->cck_agc_rpt & 0x60; |
1225 | report >>= 5; |
1226 | switch (report) { |
1227 | case 0x3: |
1228 | rx_pwr_all = -35 - |
1229 | ((pcck_buf->cck_agc_rpt & |
1230 | 0x1f) << 1); |
1231 | break; |
1232 | case 0x2: |
1233 | rx_pwr_all = -23 - |
1234 | ((pcck_buf->cck_agc_rpt & |
1235 | 0x1f) << 1); |
1236 | break; |
1237 | case 0x1: |
1238 | rx_pwr_all = -11 - |
1239 | ((pcck_buf->cck_agc_rpt & |
1240 | 0x1f) << 1); |
1241 | break; |
1242 | case 0x0: |
1243 | rx_pwr_all = -8 - |
1244 | ((pcck_buf->cck_agc_rpt & |
1245 | 0x1f) << 1); |
1246 | break; |
1247 | } |
1248 | } |
1249 | |
1250 | pwdb_all = rtl92e_rx_db_to_percent(antpower: rx_pwr_all); |
1251 | pstats->RxPWDBAll = precord_stats->RxPWDBAll = pwdb_all; |
1252 | pstats->RecvSignalPower = rx_pwr_all; |
1253 | |
1254 | if (bpacket_match_bssid) { |
1255 | u8 sq; |
1256 | |
1257 | if (pstats->RxPWDBAll > 40) { |
1258 | sq = 100; |
1259 | } else { |
1260 | sq = pcck_buf->sq_rpt; |
1261 | |
1262 | if (pcck_buf->sq_rpt > 64) |
1263 | sq = 0; |
1264 | else if (pcck_buf->sq_rpt < 20) |
1265 | sq = 100; |
1266 | else |
1267 | sq = ((64 - sq) * 100) / 44; |
1268 | } |
1269 | pstats->SignalQuality = sq; |
1270 | precord_stats->SignalQuality = sq; |
1271 | pstats->RxMIMOSignalQuality[0] = sq; |
1272 | precord_stats->RxMIMOSignalQuality[0] = sq; |
1273 | pstats->RxMIMOSignalQuality[1] = -1; |
1274 | precord_stats->RxMIMOSignalQuality[1] = -1; |
1275 | } |
1276 | } else { |
1277 | for (i = RF90_PATH_A; i < RF90_PATH_MAX; i++) { |
1278 | if (priv->brfpath_rxenable[i]) |
1279 | rf_rx_num++; |
1280 | |
1281 | rx_pwr[i] = ((pofdm_buf->trsw_gain_X[i] & 0x3F) * |
1282 | 2) - 110; |
1283 | |
1284 | RSSI = rtl92e_rx_db_to_percent(antpower: rx_pwr[i]); |
1285 | if (priv->brfpath_rxenable[i]) |
1286 | total_rssi += RSSI; |
1287 | |
1288 | if (bpacket_match_bssid) { |
1289 | pstats->RxMIMOSignalStrength[i] = RSSI; |
1290 | precord_stats->RxMIMOSignalStrength[i] = RSSI; |
1291 | } |
1292 | } |
1293 | |
1294 | rx_pwr_all = (((pofdm_buf->pwdb_all) >> 1) & 0x7f) - 106; |
1295 | pwdb_all = rtl92e_rx_db_to_percent(antpower: rx_pwr_all); |
1296 | |
1297 | pstats->RxPWDBAll = precord_stats->RxPWDBAll = pwdb_all; |
1298 | pstats->RecvSignalPower = rx_pwr_all; |
1299 | if (pdrvinfo->RxHT && pdrvinfo->RxRate >= DESC90_RATEMCS8 && |
1300 | pdrvinfo->RxRate <= DESC90_RATEMCS15) |
1301 | max_spatial_stream = 2; |
1302 | else |
1303 | max_spatial_stream = 1; |
1304 | |
1305 | for (i = 0; i < max_spatial_stream; i++) { |
1306 | tmp_rxevm = pofdm_buf->rxevm_X[i]; |
1307 | rx_evmX = (s8)(tmp_rxevm); |
1308 | |
1309 | rx_evmX /= 2; |
1310 | |
1311 | evm = rtl92e_evm_db_to_percent(value: rx_evmX); |
1312 | if (bpacket_match_bssid) { |
1313 | if (i == 0) { |
1314 | pstats->SignalQuality = evm & 0xff; |
1315 | precord_stats->SignalQuality = evm & 0xff; |
1316 | } |
1317 | pstats->RxMIMOSignalQuality[i] = evm & 0xff; |
1318 | precord_stats->RxMIMOSignalQuality[i] = evm & 0xff; |
1319 | } |
1320 | } |
1321 | } |
1322 | |
1323 | if (is_cck_rate) { |
1324 | pstats->SignalStrength = precord_stats->SignalStrength = |
1325 | _rtl92e_signal_scale_mapping(priv, |
1326 | currsig: (long)pwdb_all); |
1327 | |
1328 | } else { |
1329 | if (rf_rx_num != 0) |
1330 | pstats->SignalStrength = precord_stats->SignalStrength = |
1331 | _rtl92e_signal_scale_mapping(priv, |
1332 | currsig: (long)(total_rssi /= rf_rx_num)); |
1333 | } |
1334 | } |
1335 | |
1336 | static void _rtl92e_process_phyinfo(struct r8192_priv *priv, u8 *buffer, |
1337 | struct rtllib_rx_stats *prev_st, |
1338 | struct rtllib_rx_stats *curr_st) |
1339 | { |
1340 | bool bcheck = false; |
1341 | u8 rfpath; |
1342 | u32 ij, tmp_val; |
1343 | static u32 , ; |
1344 | static u32 slide_evm_index, slide_evm_statistics; |
1345 | static u32 , last_evm; |
1346 | static u32 slide_beacon_adc_pwdb_index; |
1347 | static u32 slide_beacon_adc_pwdb_statistics; |
1348 | static u32 last_beacon_adc_pwdb; |
1349 | |
1350 | if (!prev_st->bIsAMPDU) |
1351 | bcheck = true; |
1352 | |
1353 | if (slide_rssi_statistics++ >= PHY_RSSI_SLID_WIN_MAX) { |
1354 | slide_rssi_statistics = PHY_RSSI_SLID_WIN_MAX; |
1355 | last_rssi = priv->stats.slide_signal_strength[slide_rssi_index]; |
1356 | priv->stats.slide_rssi_total -= last_rssi; |
1357 | } |
1358 | priv->stats.slide_rssi_total += prev_st->SignalStrength; |
1359 | |
1360 | priv->stats.slide_signal_strength[slide_rssi_index++] = |
1361 | prev_st->SignalStrength; |
1362 | if (slide_rssi_index >= PHY_RSSI_SLID_WIN_MAX) |
1363 | slide_rssi_index = 0; |
1364 | |
1365 | tmp_val = priv->stats.slide_rssi_total / slide_rssi_statistics; |
1366 | priv->stats.signal_strength = rtl92e_translate_to_dbm(priv, signal_strength_index: tmp_val); |
1367 | curr_st->rssi = priv->stats.signal_strength; |
1368 | if (!prev_st->bPacketMatchBSSID) { |
1369 | if (!prev_st->bToSelfBA) |
1370 | return; |
1371 | } |
1372 | |
1373 | if (!bcheck) |
1374 | return; |
1375 | |
1376 | if (!prev_st->bIsCCK && prev_st->bPacketToSelf) { |
1377 | for (rfpath = RF90_PATH_A; rfpath < priv->num_total_rf_path; rfpath++) { |
1378 | if (priv->stats.rx_rssi_percentage[rfpath] == 0) { |
1379 | priv->stats.rx_rssi_percentage[rfpath] = |
1380 | prev_st->RxMIMOSignalStrength[rfpath]; |
1381 | } |
1382 | if (prev_st->RxMIMOSignalStrength[rfpath] > |
1383 | priv->stats.rx_rssi_percentage[rfpath]) { |
1384 | priv->stats.rx_rssi_percentage[rfpath] = |
1385 | ((priv->stats.rx_rssi_percentage[rfpath] |
1386 | * (RX_SMOOTH - 1)) + |
1387 | (prev_st->RxMIMOSignalStrength |
1388 | [rfpath])) / (RX_SMOOTH); |
1389 | priv->stats.rx_rssi_percentage[rfpath] = |
1390 | priv->stats.rx_rssi_percentage[rfpath] |
1391 | + 1; |
1392 | } else { |
1393 | priv->stats.rx_rssi_percentage[rfpath] = |
1394 | ((priv->stats.rx_rssi_percentage[rfpath] * |
1395 | (RX_SMOOTH - 1)) + |
1396 | (prev_st->RxMIMOSignalStrength[rfpath])) / |
1397 | (RX_SMOOTH); |
1398 | } |
1399 | } |
1400 | } |
1401 | |
1402 | if (prev_st->bPacketBeacon) { |
1403 | if (slide_beacon_adc_pwdb_statistics++ >= |
1404 | PHY_Beacon_RSSI_SLID_WIN_MAX) { |
1405 | slide_beacon_adc_pwdb_statistics = |
1406 | PHY_Beacon_RSSI_SLID_WIN_MAX; |
1407 | last_beacon_adc_pwdb = priv->stats.slide_beacon_pwdb |
1408 | [slide_beacon_adc_pwdb_index]; |
1409 | priv->stats.slide_beacon_total -= last_beacon_adc_pwdb; |
1410 | } |
1411 | priv->stats.slide_beacon_total += prev_st->RxPWDBAll; |
1412 | priv->stats.slide_beacon_pwdb[slide_beacon_adc_pwdb_index] = |
1413 | prev_st->RxPWDBAll; |
1414 | slide_beacon_adc_pwdb_index++; |
1415 | if (slide_beacon_adc_pwdb_index >= PHY_Beacon_RSSI_SLID_WIN_MAX) |
1416 | slide_beacon_adc_pwdb_index = 0; |
1417 | prev_st->RxPWDBAll = priv->stats.slide_beacon_total / |
1418 | slide_beacon_adc_pwdb_statistics; |
1419 | if (prev_st->RxPWDBAll >= 3) |
1420 | prev_st->RxPWDBAll -= 3; |
1421 | } |
1422 | if (prev_st->bPacketToSelf || prev_st->bPacketBeacon || |
1423 | prev_st->bToSelfBA) { |
1424 | if (priv->undecorated_smoothed_pwdb < 0) |
1425 | priv->undecorated_smoothed_pwdb = prev_st->RxPWDBAll; |
1426 | if (prev_st->RxPWDBAll > (u32)priv->undecorated_smoothed_pwdb) { |
1427 | priv->undecorated_smoothed_pwdb = |
1428 | (((priv->undecorated_smoothed_pwdb) * |
1429 | (RX_SMOOTH - 1)) + |
1430 | (prev_st->RxPWDBAll)) / (RX_SMOOTH); |
1431 | priv->undecorated_smoothed_pwdb = |
1432 | priv->undecorated_smoothed_pwdb + 1; |
1433 | } else { |
1434 | priv->undecorated_smoothed_pwdb = |
1435 | (((priv->undecorated_smoothed_pwdb) * |
1436 | (RX_SMOOTH - 1)) + |
1437 | (prev_st->RxPWDBAll)) / (RX_SMOOTH); |
1438 | } |
1439 | rtl92e_update_rx_statistics(priv, pprevious_stats: prev_st); |
1440 | } |
1441 | |
1442 | if (prev_st->SignalQuality != 0) { |
1443 | if (prev_st->bPacketToSelf || prev_st->bPacketBeacon || |
1444 | prev_st->bToSelfBA) { |
1445 | if (slide_evm_statistics++ >= PHY_RSSI_SLID_WIN_MAX) { |
1446 | slide_evm_statistics = PHY_RSSI_SLID_WIN_MAX; |
1447 | last_evm = |
1448 | priv->stats.slide_evm[slide_evm_index]; |
1449 | priv->stats.slide_evm_total -= last_evm; |
1450 | } |
1451 | |
1452 | priv->stats.slide_evm_total += prev_st->SignalQuality; |
1453 | |
1454 | priv->stats.slide_evm[slide_evm_index++] = |
1455 | prev_st->SignalQuality; |
1456 | if (slide_evm_index >= PHY_RSSI_SLID_WIN_MAX) |
1457 | slide_evm_index = 0; |
1458 | |
1459 | tmp_val = priv->stats.slide_evm_total / |
1460 | slide_evm_statistics; |
1461 | priv->stats.last_signal_strength_inpercent = tmp_val; |
1462 | } |
1463 | |
1464 | if (prev_st->bPacketToSelf || |
1465 | prev_st->bPacketBeacon || |
1466 | prev_st->bToSelfBA) { |
1467 | for (ij = 0; ij < 2; ij++) { |
1468 | if (prev_st->RxMIMOSignalQuality[ij] != -1) { |
1469 | if (priv->stats.rx_evm_percentage[ij] == 0) |
1470 | priv->stats.rx_evm_percentage[ij] = |
1471 | prev_st->RxMIMOSignalQuality[ij]; |
1472 | priv->stats.rx_evm_percentage[ij] = |
1473 | ((priv->stats.rx_evm_percentage[ij] * |
1474 | (RX_SMOOTH - 1)) + |
1475 | (prev_st->RxMIMOSignalQuality[ij])) / |
1476 | (RX_SMOOTH); |
1477 | } |
1478 | } |
1479 | } |
1480 | } |
1481 | } |
1482 | |
1483 | static void _rtl92e_translate_rx_signal_stats(struct net_device *dev, |
1484 | struct sk_buff *skb, |
1485 | struct rtllib_rx_stats *pstats, |
1486 | struct rx_desc *pdesc, |
1487 | struct rx_fwinfo *pdrvinfo) |
1488 | { |
1489 | struct r8192_priv *priv = (struct r8192_priv *)rtllib_priv(dev); |
1490 | bool bpacket_match_bssid, bpacket_toself; |
1491 | bool bPacketBeacon = false; |
1492 | struct ieee80211_hdr_3addr *hdr; |
1493 | bool bToSelfBA = false; |
1494 | static struct rtllib_rx_stats previous_stats; |
1495 | u16 fc, type; |
1496 | u8 *tmp_buf; |
1497 | u8 *praddr; |
1498 | |
1499 | tmp_buf = skb->data + pstats->RxDrvInfoSize + pstats->RxBufShift; |
1500 | |
1501 | hdr = (struct ieee80211_hdr_3addr *)tmp_buf; |
1502 | fc = le16_to_cpu(hdr->frame_control); |
1503 | type = WLAN_FC_GET_TYPE(fc); |
1504 | praddr = hdr->addr1; |
1505 | |
1506 | bpacket_match_bssid = |
1507 | ((type != RTLLIB_FTYPE_CTL) && |
1508 | ether_addr_equal(addr1: priv->rtllib->current_network.bssid, |
1509 | addr2: (fc & IEEE80211_FCTL_TODS) ? hdr->addr1 : |
1510 | (fc & IEEE80211_FCTL_FROMDS) ? hdr->addr2 : |
1511 | hdr->addr3) && |
1512 | (!pstats->bHwError) && (!pstats->bCRC) && (!pstats->bICV)); |
1513 | bpacket_toself = bpacket_match_bssid && /* check this */ |
1514 | ether_addr_equal(addr1: praddr, addr2: priv->rtllib->dev->dev_addr); |
1515 | if (ieee80211_is_beacon(fc: hdr->frame_control)) |
1516 | bPacketBeacon = true; |
1517 | _rtl92e_process_phyinfo(priv, buffer: tmp_buf, prev_st: &previous_stats, curr_st: pstats); |
1518 | _rtl92e_query_rxphystatus(priv, pstats, pdesc, pdrvinfo, |
1519 | precord_stats: &previous_stats, bpacket_match_bssid, |
1520 | bpacket_toself, bPacketBeacon, bToSelfBA); |
1521 | rtl92e_copy_mpdu_stats(psrc_stats: pstats, ptarget_stats: &previous_stats); |
1522 | } |
1523 | |
1524 | static void _rtl92e_update_received_rate_histogram_stats( |
1525 | struct net_device *dev, |
1526 | struct rtllib_rx_stats *pstats) |
1527 | { |
1528 | struct r8192_priv *priv = (struct r8192_priv *)rtllib_priv(dev); |
1529 | u32 rcvType = 1; |
1530 | u32 rate_index; |
1531 | |
1532 | if (pstats->bCRC) |
1533 | rcvType = 2; |
1534 | else if (pstats->bICV) |
1535 | rcvType = 3; |
1536 | |
1537 | switch (pstats->rate) { |
1538 | case MGN_1M: |
1539 | rate_index = 0; |
1540 | break; |
1541 | case MGN_2M: |
1542 | rate_index = 1; |
1543 | break; |
1544 | case MGN_5_5M: |
1545 | rate_index = 2; |
1546 | break; |
1547 | case MGN_11M: |
1548 | rate_index = 3; |
1549 | break; |
1550 | case MGN_6M: |
1551 | rate_index = 4; |
1552 | break; |
1553 | case MGN_9M: |
1554 | rate_index = 5; |
1555 | break; |
1556 | case MGN_12M: |
1557 | rate_index = 6; |
1558 | break; |
1559 | case MGN_18M: |
1560 | rate_index = 7; |
1561 | break; |
1562 | case MGN_24M: |
1563 | rate_index = 8; |
1564 | break; |
1565 | case MGN_36M: |
1566 | rate_index = 9; |
1567 | break; |
1568 | case MGN_48M: |
1569 | rate_index = 10; |
1570 | break; |
1571 | case MGN_54M: |
1572 | rate_index = 11; |
1573 | break; |
1574 | case MGN_MCS0: |
1575 | rate_index = 12; |
1576 | break; |
1577 | case MGN_MCS1: |
1578 | rate_index = 13; |
1579 | break; |
1580 | case MGN_MCS2: |
1581 | rate_index = 14; |
1582 | break; |
1583 | case MGN_MCS3: |
1584 | rate_index = 15; |
1585 | break; |
1586 | case MGN_MCS4: |
1587 | rate_index = 16; |
1588 | break; |
1589 | case MGN_MCS5: |
1590 | rate_index = 17; |
1591 | break; |
1592 | case MGN_MCS6: |
1593 | rate_index = 18; |
1594 | break; |
1595 | case MGN_MCS7: |
1596 | rate_index = 19; |
1597 | break; |
1598 | case MGN_MCS8: |
1599 | rate_index = 20; |
1600 | break; |
1601 | case MGN_MCS9: |
1602 | rate_index = 21; |
1603 | break; |
1604 | case MGN_MCS10: |
1605 | rate_index = 22; |
1606 | break; |
1607 | case MGN_MCS11: |
1608 | rate_index = 23; |
1609 | break; |
1610 | case MGN_MCS12: |
1611 | rate_index = 24; |
1612 | break; |
1613 | case MGN_MCS13: |
1614 | rate_index = 25; |
1615 | break; |
1616 | case MGN_MCS14: |
1617 | rate_index = 26; |
1618 | break; |
1619 | case MGN_MCS15: |
1620 | rate_index = 27; |
1621 | break; |
1622 | default: |
1623 | rate_index = 28; |
1624 | break; |
1625 | } |
1626 | priv->stats.received_rate_histogram[0][rate_index]++; |
1627 | priv->stats.received_rate_histogram[rcvType][rate_index]++; |
1628 | } |
1629 | |
1630 | bool rtl92e_get_rx_stats(struct net_device *dev, struct rtllib_rx_stats *stats, |
1631 | struct rx_desc *pdesc, struct sk_buff *skb) |
1632 | { |
1633 | struct rx_fwinfo *pDrvInfo = NULL; |
1634 | |
1635 | stats->bICV = pdesc->ICV; |
1636 | stats->bCRC = pdesc->CRC32; |
1637 | stats->bHwError = pdesc->CRC32 | pdesc->ICV; |
1638 | |
1639 | stats->Length = pdesc->Length; |
1640 | if (stats->Length < 24) |
1641 | stats->bHwError |= 1; |
1642 | |
1643 | if (stats->bHwError) { |
1644 | return false; |
1645 | } |
1646 | |
1647 | stats->RxDrvInfoSize = pdesc->RxDrvInfoSize; |
1648 | stats->RxBufShift = (pdesc->Shift) & 0x03; |
1649 | stats->Decrypted = !pdesc->SWDec; |
1650 | |
1651 | pDrvInfo = (struct rx_fwinfo *)(skb->data + stats->RxBufShift); |
1652 | |
1653 | stats->rate = _rtl92e_rate_hw_to_mgn(bIsHT: (bool)pDrvInfo->RxHT, |
1654 | rate: pDrvInfo->RxRate); |
1655 | |
1656 | _rtl92e_update_received_rate_histogram_stats(dev, pstats: stats); |
1657 | |
1658 | stats->bIsAMPDU = (pDrvInfo->PartAggr == 1); |
1659 | stats->bFirstMPDU = (pDrvInfo->PartAggr == 1) && |
1660 | (pDrvInfo->FirstAGGR == 1); |
1661 | |
1662 | stats->TimeStampLow = pDrvInfo->TSFL; |
1663 | stats->TimeStampHigh = rtl92e_readl(dev, x: TSFR + 4); |
1664 | |
1665 | _rtl92e_translate_rx_signal_stats(dev, skb, pstats: stats, pdesc, pdrvinfo: pDrvInfo); |
1666 | skb_trim(skb, len: skb->len - S_CRC_LEN); |
1667 | |
1668 | return true; |
1669 | } |
1670 | |
1671 | void rtl92e_stop_adapter(struct net_device *dev, bool reset) |
1672 | { |
1673 | struct r8192_priv *priv = rtllib_priv(dev); |
1674 | int i; |
1675 | u8 op_mode; |
1676 | u8 u1bTmp; |
1677 | u32 ulRegRead; |
1678 | |
1679 | op_mode = RT_OP_MODE_NO_LINK; |
1680 | priv->rtllib->set_hw_reg_handler(dev, HW_VAR_MEDIA_STATUS, &op_mode); |
1681 | |
1682 | if (!priv->rtllib->bSupportRemoteWakeUp) { |
1683 | u1bTmp = 0x0; |
1684 | rtl92e_writeb(dev, x: CMDR, y: u1bTmp); |
1685 | } |
1686 | |
1687 | mdelay(20); |
1688 | |
1689 | if (!reset) { |
1690 | mdelay(150); |
1691 | |
1692 | priv->hw_rf_off_action = 2; |
1693 | |
1694 | if (!priv->rtllib->bSupportRemoteWakeUp) { |
1695 | rtl92e_set_rf_off(dev); |
1696 | ulRegRead = rtl92e_readl(dev, x: CPU_GEN); |
1697 | ulRegRead |= CPU_GEN_SYSTEM_RESET; |
1698 | rtl92e_writel(dev, x: CPU_GEN, y: ulRegRead); |
1699 | } else { |
1700 | rtl92e_writel(dev, x: WFCRC0, y: 0xffffffff); |
1701 | rtl92e_writel(dev, x: WFCRC1, y: 0xffffffff); |
1702 | rtl92e_writel(dev, x: WFCRC2, y: 0xffffffff); |
1703 | |
1704 | rtl92e_writeb(dev, x: PMR, y: 0x5); |
1705 | rtl92e_writeb(dev, x: MAC_BLK_CTRL, y: 0xa); |
1706 | } |
1707 | } |
1708 | |
1709 | for (i = 0; i < MAX_QUEUE_SIZE; i++) |
1710 | skb_queue_purge(list: &priv->rtllib->skb_waitq[i]); |
1711 | |
1712 | skb_queue_purge(list: &priv->skb_queue); |
1713 | } |
1714 | |
1715 | void rtl92e_update_ratr_table(struct net_device *dev) |
1716 | { |
1717 | struct r8192_priv *priv = rtllib_priv(dev); |
1718 | struct rtllib_device *ieee = priv->rtllib; |
1719 | u8 *pMcsRate = ieee->dot11ht_oper_rate_set; |
1720 | u32 ratr_value = 0; |
1721 | u16 rate_config = 0; |
1722 | u8 rate_index = 0; |
1723 | |
1724 | rtl92e_config_rate(dev, rate_config: &rate_config); |
1725 | ratr_value = rate_config | *pMcsRate << 12; |
1726 | switch (ieee->mode) { |
1727 | case WIRELESS_MODE_B: |
1728 | ratr_value &= 0x0000000F; |
1729 | break; |
1730 | case WIRELESS_MODE_G: |
1731 | case WIRELESS_MODE_G | WIRELESS_MODE_B: |
1732 | ratr_value &= 0x00000FF7; |
1733 | break; |
1734 | case WIRELESS_MODE_N_24G: |
1735 | ratr_value &= 0x000FF007; |
1736 | break; |
1737 | default: |
1738 | break; |
1739 | } |
1740 | ratr_value &= 0x0FFFFFFF; |
1741 | if (ieee->ht_info->cur_tx_bw40mhz && |
1742 | ieee->ht_info->cur_short_gi_40mhz) |
1743 | ratr_value |= 0x80000000; |
1744 | else if (!ieee->ht_info->cur_tx_bw40mhz && |
1745 | ieee->ht_info->cur_short_gi_20mhz) |
1746 | ratr_value |= 0x80000000; |
1747 | rtl92e_writel(dev, x: RATR0 + rate_index * 4, y: ratr_value); |
1748 | rtl92e_writeb(dev, x: UFWP, y: 1); |
1749 | } |
1750 | |
1751 | void |
1752 | rtl92e_init_variables(struct net_device *dev) |
1753 | { |
1754 | struct r8192_priv *priv = rtllib_priv(dev); |
1755 | |
1756 | strscpy(priv->nick, "rtl8192E" , sizeof(priv->nick)); |
1757 | |
1758 | priv->rtllib->softmac_features = IEEE_SOFTMAC_SCAN | |
1759 | IEEE_SOFTMAC_ASSOCIATE | IEEE_SOFTMAC_PROBERQ | |
1760 | IEEE_SOFTMAC_PROBERS | IEEE_SOFTMAC_TX_QUEUE; |
1761 | |
1762 | priv->rtllib->tx_headroom = sizeof(struct tx_fwinfo_8190pci); |
1763 | |
1764 | priv->short_retry_limit = 0x30; |
1765 | priv->long_retry_limit = 0x30; |
1766 | |
1767 | priv->receive_config = RCR_ADD3 | |
1768 | RCR_AMF | RCR_ADF | |
1769 | RCR_AICV | |
1770 | RCR_AB | RCR_AM | RCR_APM | |
1771 | RCR_AAP | ((u32)7 << RCR_MXDMA_OFFSET) | |
1772 | ((u32)7 << RCR_FIFO_OFFSET) | RCR_ONLYERLPKT; |
1773 | |
1774 | priv->irq_mask[0] = (u32)(IMR_ROK | IMR_VODOK | IMR_VIDOK | |
1775 | IMR_BEDOK | IMR_BKDOK | IMR_HCCADOK | |
1776 | IMR_MGNTDOK | IMR_COMDOK | IMR_HIGHDOK | |
1777 | IMR_BDOK | IMR_RXCMDOK | IMR_TIMEOUT0 | |
1778 | IMR_RDU | IMR_RXFOVW | IMR_TXFOVW | |
1779 | IMR_TBDOK | IMR_TBDER); |
1780 | |
1781 | priv->bfirst_after_down = false; |
1782 | } |
1783 | |
1784 | void rtl92e_irq_enable(struct net_device *dev) |
1785 | { |
1786 | struct r8192_priv *priv = (struct r8192_priv *)rtllib_priv(dev); |
1787 | |
1788 | priv->irq_enabled = 1; |
1789 | |
1790 | rtl92e_writel(dev, x: INTA_MASK, y: priv->irq_mask[0]); |
1791 | } |
1792 | |
1793 | void rtl92e_irq_disable(struct net_device *dev) |
1794 | { |
1795 | struct r8192_priv *priv = (struct r8192_priv *)rtllib_priv(dev); |
1796 | |
1797 | rtl92e_writel(dev, x: INTA_MASK, y: 0); |
1798 | |
1799 | priv->irq_enabled = 0; |
1800 | } |
1801 | |
1802 | void rtl92e_enable_rx(struct net_device *dev) |
1803 | { |
1804 | struct r8192_priv *priv = (struct r8192_priv *)rtllib_priv(dev); |
1805 | |
1806 | rtl92e_writel(dev, x: RDQDA, y: priv->rx_ring_dma); |
1807 | } |
1808 | |
1809 | static const u32 TX_DESC_BASE[] = { |
1810 | BKQDA, BEQDA, VIQDA, VOQDA, HCCAQDA, CQDA, MQDA, HQDA, BQDA |
1811 | }; |
1812 | |
1813 | void rtl92e_enable_tx(struct net_device *dev) |
1814 | { |
1815 | struct r8192_priv *priv = (struct r8192_priv *)rtllib_priv(dev); |
1816 | u32 i; |
1817 | |
1818 | for (i = 0; i < MAX_TX_QUEUE_COUNT; i++) |
1819 | rtl92e_writel(dev, x: TX_DESC_BASE[i], y: priv->tx_ring[i].dma); |
1820 | } |
1821 | |
1822 | void rtl92e_ack_irq(struct net_device *dev, u32 *p_inta) |
1823 | { |
1824 | *p_inta = rtl92e_readl(dev, x: ISR); |
1825 | rtl92e_writel(dev, x: ISR, y: *p_inta); |
1826 | } |
1827 | |
1828 | bool rtl92e_is_rx_stuck(struct net_device *dev) |
1829 | { |
1830 | struct r8192_priv *priv = rtllib_priv(dev); |
1831 | u16 RegRxCounter = rtl92e_readw(dev, x: 0x130); |
1832 | bool bStuck = false; |
1833 | static u8 rx_chk_cnt; |
1834 | u32 slot_index = 0, TotalRxStuckCount = 0; |
1835 | u8 i; |
1836 | u8 SilentResetRxSoltNum = 4; |
1837 | |
1838 | rx_chk_cnt++; |
1839 | if (priv->undecorated_smoothed_pwdb >= (RATE_ADAPTIVE_TH_HIGH + 5)) { |
1840 | rx_chk_cnt = 0; |
1841 | } else if ((priv->undecorated_smoothed_pwdb < (RATE_ADAPTIVE_TH_HIGH + 5)) |
1842 | && (((priv->current_chnl_bw != HT_CHANNEL_WIDTH_20) && |
1843 | (priv->undecorated_smoothed_pwdb >= RATE_ADAPTIVE_TH_LOW_40M)) |
1844 | || ((priv->current_chnl_bw == HT_CHANNEL_WIDTH_20) && |
1845 | (priv->undecorated_smoothed_pwdb >= RATE_ADAPTIVE_TH_LOW_20M)))) { |
1846 | if (rx_chk_cnt < 2) |
1847 | return bStuck; |
1848 | rx_chk_cnt = 0; |
1849 | } else if ((((priv->current_chnl_bw != HT_CHANNEL_WIDTH_20) && |
1850 | (priv->undecorated_smoothed_pwdb < RATE_ADAPTIVE_TH_LOW_40M)) || |
1851 | ((priv->current_chnl_bw == HT_CHANNEL_WIDTH_20) && |
1852 | (priv->undecorated_smoothed_pwdb < RATE_ADAPTIVE_TH_LOW_20M))) && |
1853 | priv->undecorated_smoothed_pwdb >= VERY_LOW_RSSI) { |
1854 | if (rx_chk_cnt < 4) |
1855 | return bStuck; |
1856 | rx_chk_cnt = 0; |
1857 | } else { |
1858 | if (rx_chk_cnt < 8) |
1859 | return bStuck; |
1860 | rx_chk_cnt = 0; |
1861 | } |
1862 | |
1863 | |
1864 | slot_index = (priv->silent_reset_rx_slot_index++) % SilentResetRxSoltNum; |
1865 | |
1866 | if (priv->rx_ctr == RegRxCounter) { |
1867 | priv->silent_reset_rx_stuck_event[slot_index] = 1; |
1868 | |
1869 | for (i = 0; i < SilentResetRxSoltNum; i++) |
1870 | TotalRxStuckCount += priv->silent_reset_rx_stuck_event[i]; |
1871 | |
1872 | if (TotalRxStuckCount == SilentResetRxSoltNum) { |
1873 | bStuck = true; |
1874 | for (i = 0; i < SilentResetRxSoltNum; i++) |
1875 | TotalRxStuckCount += |
1876 | priv->silent_reset_rx_stuck_event[i]; |
1877 | } |
1878 | } else { |
1879 | priv->silent_reset_rx_stuck_event[slot_index] = 0; |
1880 | } |
1881 | |
1882 | priv->rx_ctr = RegRxCounter; |
1883 | |
1884 | return bStuck; |
1885 | } |
1886 | |
1887 | bool rtl92e_is_tx_stuck(struct net_device *dev) |
1888 | { |
1889 | struct r8192_priv *priv = rtllib_priv(dev); |
1890 | bool bStuck = false; |
1891 | u16 RegTxCounter = rtl92e_readw(dev, x: 0x128); |
1892 | |
1893 | if (priv->tx_counter == RegTxCounter) |
1894 | bStuck = true; |
1895 | |
1896 | priv->tx_counter = RegTxCounter; |
1897 | |
1898 | return bStuck; |
1899 | } |
1900 | |
1901 | bool rtl92e_get_nmode_support_by_sec(struct net_device *dev) |
1902 | { |
1903 | struct r8192_priv *priv = rtllib_priv(dev); |
1904 | struct rtllib_device *ieee = priv->rtllib; |
1905 | |
1906 | if (ieee->rtllib_ap_sec_type && |
1907 | (ieee->rtllib_ap_sec_type(priv->rtllib) & (SEC_ALG_WEP | |
1908 | SEC_ALG_TKIP))) { |
1909 | return false; |
1910 | } else { |
1911 | return true; |
1912 | } |
1913 | } |
1914 | |
1915 | bool rtl92e_is_halfn_supported_by_ap(struct net_device *dev) |
1916 | { |
1917 | struct r8192_priv *priv = rtllib_priv(dev); |
1918 | struct rtllib_device *ieee = priv->rtllib; |
1919 | |
1920 | return ieee->half_wireless_n24g_mode; |
1921 | } |
1922 | |