1 // SPDX-License-Identifier: GPL-2.0
2 /******************************************************************************
3 *
4 * Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved.
5 *
6 ******************************************************************************/
7
8 #include <linux/kernel.h>
9 #include <drv_types.h>
10 #include <rtw_debug.h>
11 #include "hal_com_h2c.h"
12
13 #include "odm_precomp.h"
14
rtw_hal_data_init(struct adapter * padapter)15 u8 rtw_hal_data_init(struct adapter *padapter)
16 {
17 if (is_primary_adapter(padapter)) { /* if (padapter->isprimary) */
18 padapter->hal_data_sz = sizeof(struct hal_com_data);
19 padapter->HalData = vzalloc(padapter->hal_data_sz);
20 if (!padapter->HalData)
21 return _FAIL;
22 }
23 return _SUCCESS;
24 }
25
rtw_hal_data_deinit(struct adapter * padapter)26 void rtw_hal_data_deinit(struct adapter *padapter)
27 {
28 if (is_primary_adapter(padapter)) { /* if (padapter->isprimary) */
29 if (padapter->HalData) {
30 vfree(padapter->HalData);
31 padapter->HalData = NULL;
32 padapter->hal_data_sz = 0;
33 }
34 }
35 }
36
37
dump_chip_info(struct hal_version ChipVersion)38 void dump_chip_info(struct hal_version ChipVersion)
39 {
40 char buf[128];
41 size_t cnt = 0;
42
43 cnt += scnprintf(buf + cnt, sizeof(buf) - cnt, "Chip Version Info: CHIP_8723B_%s_",
44 IS_NORMAL_CHIP(ChipVersion) ? "Normal_Chip" : "Test_Chip");
45
46 if (IS_CHIP_VENDOR_TSMC(ChipVersion))
47 cnt += scnprintf(buf + cnt, sizeof(buf) - cnt, "TSMC_");
48 else if (IS_CHIP_VENDOR_UMC(ChipVersion))
49 cnt += scnprintf(buf + cnt, sizeof(buf) - cnt, "UMC_");
50 else if (IS_CHIP_VENDOR_SMIC(ChipVersion))
51 cnt += scnprintf(buf + cnt, sizeof(buf) - cnt, "SMIC_");
52
53 if (IS_A_CUT(ChipVersion))
54 cnt += scnprintf(buf + cnt, sizeof(buf) - cnt, "A_CUT_");
55 else if (IS_B_CUT(ChipVersion))
56 cnt += scnprintf(buf + cnt, sizeof(buf) - cnt, "B_CUT_");
57 else if (IS_C_CUT(ChipVersion))
58 cnt += scnprintf(buf + cnt, sizeof(buf) - cnt, "C_CUT_");
59 else if (IS_D_CUT(ChipVersion))
60 cnt += scnprintf(buf + cnt, sizeof(buf) - cnt, "D_CUT_");
61 else if (IS_E_CUT(ChipVersion))
62 cnt += scnprintf(buf + cnt, sizeof(buf) - cnt, "E_CUT_");
63 else if (IS_I_CUT(ChipVersion))
64 cnt += scnprintf(buf + cnt, sizeof(buf) - cnt, "I_CUT_");
65 else if (IS_J_CUT(ChipVersion))
66 cnt += scnprintf(buf + cnt, sizeof(buf) - cnt, "J_CUT_");
67 else if (IS_K_CUT(ChipVersion))
68 cnt += scnprintf(buf + cnt, sizeof(buf) - cnt, "K_CUT_");
69 else
70 cnt += scnprintf(buf + cnt, sizeof(buf) - cnt,
71 "UNKNOWN_CUT(%d)_", ChipVersion.CUTVersion);
72
73 cnt += scnprintf(buf + cnt, sizeof(buf) - cnt, "1T1R_");
74
75 cnt += scnprintf(buf + cnt, sizeof(buf) - cnt, "RomVer(%d)\n", ChipVersion.ROMVer);
76 }
77
78
79 #define EEPROM_CHANNEL_PLAN_BY_HW_MASK 0x80
80
81 /*
82 * Description:
83 *Use hardware(efuse), driver parameter(registry) and default channel plan
84 *to decide which one should be used.
85 *
86 * Parameters:
87 *padapter pointer of adapter
88 *hw_channel_plan channel plan from HW (efuse/eeprom)
89 * BIT[7] software configure mode; 0:Enable, 1:disable
90 * BIT[6:0] Channel Plan
91 *sw_channel_plan channel plan from SW (registry/module param)
92 *def_channel_plan channel plan used when HW/SW both invalid
93 *AutoLoadFail efuse autoload fail or not
94 *
95 * Return:
96 *Final channel plan decision
97 *
98 */
hal_com_config_channel_plan(struct adapter * padapter,u8 hw_channel_plan,u8 sw_channel_plan,u8 def_channel_plan,bool AutoLoadFail)99 u8 hal_com_config_channel_plan(
100 struct adapter *padapter,
101 u8 hw_channel_plan,
102 u8 sw_channel_plan,
103 u8 def_channel_plan,
104 bool AutoLoadFail
105 )
106 {
107 struct hal_com_data *pHalData;
108 u8 chnlPlan;
109
110 pHalData = GET_HAL_DATA(padapter);
111 pHalData->bDisableSWChannelPlan = false;
112 chnlPlan = def_channel_plan;
113
114 if (0xFF == hw_channel_plan)
115 AutoLoadFail = true;
116
117 if (!AutoLoadFail) {
118 u8 hw_chnlPlan;
119
120 hw_chnlPlan = hw_channel_plan & (~EEPROM_CHANNEL_PLAN_BY_HW_MASK);
121 if (rtw_is_channel_plan_valid(hw_chnlPlan)) {
122 if (hw_channel_plan & EEPROM_CHANNEL_PLAN_BY_HW_MASK)
123 pHalData->bDisableSWChannelPlan = true;
124
125 chnlPlan = hw_chnlPlan;
126 }
127 }
128
129 if (
130 (false == pHalData->bDisableSWChannelPlan) &&
131 rtw_is_channel_plan_valid(sw_channel_plan)
132 )
133 chnlPlan = sw_channel_plan;
134
135 return chnlPlan;
136 }
137
HAL_IsLegalChannel(struct adapter * adapter,u32 Channel)138 bool HAL_IsLegalChannel(struct adapter *adapter, u32 Channel)
139 {
140 bool bLegalChannel = true;
141
142 if ((Channel <= 14) && (Channel >= 1)) {
143 if (is_supported_24g(adapter->registrypriv.wireless_mode) == false)
144 bLegalChannel = false;
145 } else {
146 bLegalChannel = false;
147 }
148
149 return bLegalChannel;
150 }
151
MRateToHwRate(u8 rate)152 u8 MRateToHwRate(u8 rate)
153 {
154 u8 ret = DESC_RATE1M;
155
156 switch (rate) {
157 case MGN_1M:
158 ret = DESC_RATE1M;
159 break;
160 case MGN_2M:
161 ret = DESC_RATE2M;
162 break;
163 case MGN_5_5M:
164 ret = DESC_RATE5_5M;
165 break;
166 case MGN_11M:
167 ret = DESC_RATE11M;
168 break;
169 case MGN_6M:
170 ret = DESC_RATE6M;
171 break;
172 case MGN_9M:
173 ret = DESC_RATE9M;
174 break;
175 case MGN_12M:
176 ret = DESC_RATE12M;
177 break;
178 case MGN_18M:
179 ret = DESC_RATE18M;
180 break;
181 case MGN_24M:
182 ret = DESC_RATE24M;
183 break;
184 case MGN_36M:
185 ret = DESC_RATE36M;
186 break;
187 case MGN_48M:
188 ret = DESC_RATE48M;
189 break;
190 case MGN_54M:
191 ret = DESC_RATE54M;
192 break;
193 case MGN_MCS0:
194 ret = DESC_RATEMCS0;
195 break;
196 case MGN_MCS1:
197 ret = DESC_RATEMCS1;
198 break;
199 case MGN_MCS2:
200 ret = DESC_RATEMCS2;
201 break;
202 case MGN_MCS3:
203 ret = DESC_RATEMCS3;
204 break;
205 case MGN_MCS4:
206 ret = DESC_RATEMCS4;
207 break;
208 case MGN_MCS5:
209 ret = DESC_RATEMCS5;
210 break;
211 case MGN_MCS6:
212 ret = DESC_RATEMCS6;
213 break;
214 case MGN_MCS7:
215 ret = DESC_RATEMCS7;
216 break;
217 default:
218 break;
219 }
220
221 return ret;
222 }
223
HwRateToMRate(u8 rate)224 u8 HwRateToMRate(u8 rate)
225 {
226 u8 ret_rate = MGN_1M;
227
228 switch (rate) {
229 case DESC_RATE1M:
230 ret_rate = MGN_1M;
231 break;
232 case DESC_RATE2M:
233 ret_rate = MGN_2M;
234 break;
235 case DESC_RATE5_5M:
236 ret_rate = MGN_5_5M;
237 break;
238 case DESC_RATE11M:
239 ret_rate = MGN_11M;
240 break;
241 case DESC_RATE6M:
242 ret_rate = MGN_6M;
243 break;
244 case DESC_RATE9M:
245 ret_rate = MGN_9M;
246 break;
247 case DESC_RATE12M:
248 ret_rate = MGN_12M;
249 break;
250 case DESC_RATE18M:
251 ret_rate = MGN_18M;
252 break;
253 case DESC_RATE24M:
254 ret_rate = MGN_24M;
255 break;
256 case DESC_RATE36M:
257 ret_rate = MGN_36M;
258 break;
259 case DESC_RATE48M:
260 ret_rate = MGN_48M;
261 break;
262 case DESC_RATE54M:
263 ret_rate = MGN_54M;
264 break;
265 case DESC_RATEMCS0:
266 ret_rate = MGN_MCS0;
267 break;
268 case DESC_RATEMCS1:
269 ret_rate = MGN_MCS1;
270 break;
271 case DESC_RATEMCS2:
272 ret_rate = MGN_MCS2;
273 break;
274 case DESC_RATEMCS3:
275 ret_rate = MGN_MCS3;
276 break;
277 case DESC_RATEMCS4:
278 ret_rate = MGN_MCS4;
279 break;
280 case DESC_RATEMCS5:
281 ret_rate = MGN_MCS5;
282 break;
283 case DESC_RATEMCS6:
284 ret_rate = MGN_MCS6;
285 break;
286 case DESC_RATEMCS7:
287 ret_rate = MGN_MCS7;
288 break;
289 default:
290 break;
291 }
292
293 return ret_rate;
294 }
295
HalSetBrateCfg(struct adapter * Adapter,u8 * mBratesOS,u16 * pBrateCfg)296 void HalSetBrateCfg(struct adapter *Adapter, u8 *mBratesOS, u16 *pBrateCfg)
297 {
298 u8 i, is_brate, brate;
299
300 for (i = 0; i < NDIS_802_11_LENGTH_RATES_EX; i++) {
301
302 is_brate = mBratesOS[i] & IEEE80211_BASIC_RATE_MASK;
303 brate = mBratesOS[i] & 0x7f;
304
305 if (is_brate) {
306 switch (brate) {
307 case IEEE80211_CCK_RATE_1MB:
308 *pBrateCfg |= RATE_1M;
309 break;
310 case IEEE80211_CCK_RATE_2MB:
311 *pBrateCfg |= RATE_2M;
312 break;
313 case IEEE80211_CCK_RATE_5MB:
314 *pBrateCfg |= RATE_5_5M;
315 break;
316 case IEEE80211_CCK_RATE_11MB:
317 *pBrateCfg |= RATE_11M;
318 break;
319 case IEEE80211_OFDM_RATE_6MB:
320 *pBrateCfg |= RATE_6M;
321 break;
322 case IEEE80211_OFDM_RATE_9MB:
323 *pBrateCfg |= RATE_9M;
324 break;
325 case IEEE80211_OFDM_RATE_12MB:
326 *pBrateCfg |= RATE_12M;
327 break;
328 case IEEE80211_OFDM_RATE_18MB:
329 *pBrateCfg |= RATE_18M;
330 break;
331 case IEEE80211_OFDM_RATE_24MB:
332 *pBrateCfg |= RATE_24M;
333 break;
334 case IEEE80211_OFDM_RATE_36MB:
335 *pBrateCfg |= RATE_36M;
336 break;
337 case IEEE80211_OFDM_RATE_48MB:
338 *pBrateCfg |= RATE_48M;
339 break;
340 case IEEE80211_OFDM_RATE_54MB:
341 *pBrateCfg |= RATE_54M;
342 break;
343 }
344 }
345 }
346 }
347
_OneOutPipeMapping(struct adapter * padapter)348 static void _OneOutPipeMapping(struct adapter *padapter)
349 {
350 struct dvobj_priv *pdvobjpriv = adapter_to_dvobj(padapter);
351
352 pdvobjpriv->Queue2Pipe[0] = pdvobjpriv->RtOutPipe[0];/* VO */
353 pdvobjpriv->Queue2Pipe[1] = pdvobjpriv->RtOutPipe[0];/* VI */
354 pdvobjpriv->Queue2Pipe[2] = pdvobjpriv->RtOutPipe[0];/* BE */
355 pdvobjpriv->Queue2Pipe[3] = pdvobjpriv->RtOutPipe[0];/* BK */
356
357 pdvobjpriv->Queue2Pipe[4] = pdvobjpriv->RtOutPipe[0];/* BCN */
358 pdvobjpriv->Queue2Pipe[5] = pdvobjpriv->RtOutPipe[0];/* MGT */
359 pdvobjpriv->Queue2Pipe[6] = pdvobjpriv->RtOutPipe[0];/* HIGH */
360 pdvobjpriv->Queue2Pipe[7] = pdvobjpriv->RtOutPipe[0];/* TXCMD */
361 }
362
_TwoOutPipeMapping(struct adapter * padapter,bool bWIFICfg)363 static void _TwoOutPipeMapping(struct adapter *padapter, bool bWIFICfg)
364 {
365 struct dvobj_priv *pdvobjpriv = adapter_to_dvobj(padapter);
366
367 if (bWIFICfg) { /* WMM */
368
369 /* BK, BE, VI, VO, BCN, CMD, MGT, HIGH, HCCA */
370 /* 0, 1, 0, 1, 0, 0, 0, 0, 0 }; */
371 /* 0:ep_0 num, 1:ep_1 num */
372
373 pdvobjpriv->Queue2Pipe[0] = pdvobjpriv->RtOutPipe[1];/* VO */
374 pdvobjpriv->Queue2Pipe[1] = pdvobjpriv->RtOutPipe[0];/* VI */
375 pdvobjpriv->Queue2Pipe[2] = pdvobjpriv->RtOutPipe[1];/* BE */
376 pdvobjpriv->Queue2Pipe[3] = pdvobjpriv->RtOutPipe[0];/* BK */
377
378 pdvobjpriv->Queue2Pipe[4] = pdvobjpriv->RtOutPipe[0];/* BCN */
379 pdvobjpriv->Queue2Pipe[5] = pdvobjpriv->RtOutPipe[0];/* MGT */
380 pdvobjpriv->Queue2Pipe[6] = pdvobjpriv->RtOutPipe[0];/* HIGH */
381 pdvobjpriv->Queue2Pipe[7] = pdvobjpriv->RtOutPipe[0];/* TXCMD */
382
383 } else { /* typical setting */
384
385
386 /* BK, BE, VI, VO, BCN, CMD, MGT, HIGH, HCCA */
387 /* 1, 1, 0, 0, 0, 0, 0, 0, 0 }; */
388 /* 0:ep_0 num, 1:ep_1 num */
389
390 pdvobjpriv->Queue2Pipe[0] = pdvobjpriv->RtOutPipe[0];/* VO */
391 pdvobjpriv->Queue2Pipe[1] = pdvobjpriv->RtOutPipe[0];/* VI */
392 pdvobjpriv->Queue2Pipe[2] = pdvobjpriv->RtOutPipe[1];/* BE */
393 pdvobjpriv->Queue2Pipe[3] = pdvobjpriv->RtOutPipe[1];/* BK */
394
395 pdvobjpriv->Queue2Pipe[4] = pdvobjpriv->RtOutPipe[0];/* BCN */
396 pdvobjpriv->Queue2Pipe[5] = pdvobjpriv->RtOutPipe[0];/* MGT */
397 pdvobjpriv->Queue2Pipe[6] = pdvobjpriv->RtOutPipe[0];/* HIGH */
398 pdvobjpriv->Queue2Pipe[7] = pdvobjpriv->RtOutPipe[0];/* TXCMD */
399
400 }
401
402 }
403
_ThreeOutPipeMapping(struct adapter * padapter,bool bWIFICfg)404 static void _ThreeOutPipeMapping(struct adapter *padapter, bool bWIFICfg)
405 {
406 struct dvobj_priv *pdvobjpriv = adapter_to_dvobj(padapter);
407
408 if (bWIFICfg) { /* for WMM */
409
410 /* BK, BE, VI, VO, BCN, CMD, MGT, HIGH, HCCA */
411 /* 1, 2, 1, 0, 0, 0, 0, 0, 0 }; */
412 /* 0:H, 1:N, 2:L */
413
414 pdvobjpriv->Queue2Pipe[0] = pdvobjpriv->RtOutPipe[0];/* VO */
415 pdvobjpriv->Queue2Pipe[1] = pdvobjpriv->RtOutPipe[1];/* VI */
416 pdvobjpriv->Queue2Pipe[2] = pdvobjpriv->RtOutPipe[2];/* BE */
417 pdvobjpriv->Queue2Pipe[3] = pdvobjpriv->RtOutPipe[1];/* BK */
418
419 pdvobjpriv->Queue2Pipe[4] = pdvobjpriv->RtOutPipe[0];/* BCN */
420 pdvobjpriv->Queue2Pipe[5] = pdvobjpriv->RtOutPipe[0];/* MGT */
421 pdvobjpriv->Queue2Pipe[6] = pdvobjpriv->RtOutPipe[0];/* HIGH */
422 pdvobjpriv->Queue2Pipe[7] = pdvobjpriv->RtOutPipe[0];/* TXCMD */
423
424 } else { /* typical setting */
425
426
427 /* BK, BE, VI, VO, BCN, CMD, MGT, HIGH, HCCA */
428 /* 2, 2, 1, 0, 0, 0, 0, 0, 0 }; */
429 /* 0:H, 1:N, 2:L */
430
431 pdvobjpriv->Queue2Pipe[0] = pdvobjpriv->RtOutPipe[0];/* VO */
432 pdvobjpriv->Queue2Pipe[1] = pdvobjpriv->RtOutPipe[1];/* VI */
433 pdvobjpriv->Queue2Pipe[2] = pdvobjpriv->RtOutPipe[2];/* BE */
434 pdvobjpriv->Queue2Pipe[3] = pdvobjpriv->RtOutPipe[2];/* BK */
435
436 pdvobjpriv->Queue2Pipe[4] = pdvobjpriv->RtOutPipe[0];/* BCN */
437 pdvobjpriv->Queue2Pipe[5] = pdvobjpriv->RtOutPipe[0];/* MGT */
438 pdvobjpriv->Queue2Pipe[6] = pdvobjpriv->RtOutPipe[0];/* HIGH */
439 pdvobjpriv->Queue2Pipe[7] = pdvobjpriv->RtOutPipe[0];/* TXCMD */
440 }
441
442 }
443
Hal_MappingOutPipe(struct adapter * padapter,u8 NumOutPipe)444 bool Hal_MappingOutPipe(struct adapter *padapter, u8 NumOutPipe)
445 {
446 struct registry_priv *pregistrypriv = &padapter->registrypriv;
447
448 bool bWIFICfg = (pregistrypriv->wifi_spec) ? true : false;
449
450 bool result = true;
451
452 switch (NumOutPipe) {
453 case 2:
454 _TwoOutPipeMapping(padapter, bWIFICfg);
455 break;
456 case 3:
457 case 4:
458 _ThreeOutPipeMapping(padapter, bWIFICfg);
459 break;
460 case 1:
461 _OneOutPipeMapping(padapter);
462 break;
463 default:
464 result = false;
465 break;
466 }
467
468 return result;
469
470 }
471
hal_init_macaddr(struct adapter * adapter)472 void hal_init_macaddr(struct adapter *adapter)
473 {
474 rtw_hal_set_hwreg(adapter, HW_VAR_MAC_ADDR, adapter->eeprompriv.mac_addr);
475 }
476
rtw_init_hal_com_default_value(struct adapter * Adapter)477 void rtw_init_hal_com_default_value(struct adapter *Adapter)
478 {
479 struct hal_com_data *pHalData = GET_HAL_DATA(Adapter);
480
481 pHalData->AntDetection = 1;
482 }
483
484 /*
485 * C2H event format:
486 * Field TRIGGER CONTENT CMD_SEQ CMD_LEN CMD_ID
487 * BITS [127:120] [119:16] [15:8] [7:4] [3:0]
488 */
489
c2h_evt_clear(struct adapter * adapter)490 void c2h_evt_clear(struct adapter *adapter)
491 {
492 rtw_write8(adapter, REG_C2HEVT_CLEAR, C2H_EVT_HOST_CLOSE);
493 }
494
495 /*
496 * C2H event format:
497 * Field TRIGGER CMD_LEN CONTENT CMD_SEQ CMD_ID
498 * BITS [127:120] [119:112] [111:16] [15:8] [7:0]
499 */
c2h_evt_read_88xx(struct adapter * adapter,u8 * buf)500 s32 c2h_evt_read_88xx(struct adapter *adapter, u8 *buf)
501 {
502 s32 ret = _FAIL;
503 struct c2h_evt_hdr_88xx *c2h_evt;
504 int i;
505 u8 trigger;
506
507 if (!buf)
508 goto exit;
509
510 trigger = rtw_read8(adapter, REG_C2HEVT_CLEAR);
511
512 if (trigger == C2H_EVT_HOST_CLOSE)
513 goto exit; /* Not ready */
514 else if (trigger != C2H_EVT_FW_CLOSE)
515 goto clear_evt; /* Not a valid value */
516
517 c2h_evt = (struct c2h_evt_hdr_88xx *)buf;
518
519 memset(c2h_evt, 0, 16);
520
521 c2h_evt->id = rtw_read8(adapter, REG_C2HEVT_MSG_NORMAL);
522 c2h_evt->seq = rtw_read8(adapter, REG_C2HEVT_CMD_SEQ_88XX);
523 c2h_evt->plen = rtw_read8(adapter, REG_C2HEVT_CMD_LEN_88XX);
524
525 /* Read the content */
526 for (i = 0; i < c2h_evt->plen; i++)
527 c2h_evt->payload[i] = rtw_read8(adapter, REG_C2HEVT_MSG_NORMAL + 2 + i);
528
529 ret = _SUCCESS;
530
531 clear_evt:
532 /*
533 * Clear event to notify FW we have read the command.
534 * If this field isn't clear, the FW won't update the next command message.
535 */
536 c2h_evt_clear(adapter);
537 exit:
538 return ret;
539 }
540
rtw_get_mgntframe_raid(struct adapter * adapter,unsigned char network_type)541 u8 rtw_get_mgntframe_raid(struct adapter *adapter, unsigned char network_type)
542 {
543 return (network_type & WIRELESS_11B) ? RATEID_IDX_B : RATEID_IDX_G;
544 }
545
rtw_hal_update_sta_rate_mask(struct adapter * padapter,struct sta_info * psta)546 void rtw_hal_update_sta_rate_mask(struct adapter *padapter, struct sta_info *psta)
547 {
548 u8 i, limit;
549 u32 tx_ra_bitmap;
550
551 if (!psta)
552 return;
553
554 tx_ra_bitmap = 0;
555
556 /* b/g mode ra_bitmap */
557 for (i = 0; i < sizeof(psta->bssrateset); i++) {
558 if (psta->bssrateset[i])
559 tx_ra_bitmap |= rtw_get_bit_value_from_ieee_value(psta->bssrateset[i]&0x7f);
560 }
561
562 /* n mode ra_bitmap */
563 if (psta->htpriv.ht_option) {
564 limit = 8; /* 1R */
565
566 for (i = 0; i < limit; i++) {
567 if (psta->htpriv.ht_cap.mcs.rx_mask[i/8] & BIT(i%8))
568 tx_ra_bitmap |= BIT(i+12);
569 }
570 }
571
572 psta->ra_mask = tx_ra_bitmap;
573 psta->init_rate = get_highest_rate_idx(tx_ra_bitmap)&0x3f;
574 }
575
hw_var_port_switch(struct adapter * adapter)576 void hw_var_port_switch(struct adapter *adapter)
577 {
578 }
579
SetHwReg(struct adapter * adapter,u8 variable,u8 * val)580 void SetHwReg(struct adapter *adapter, u8 variable, u8 *val)
581 {
582 struct hal_com_data *hal_data = GET_HAL_DATA(adapter);
583 struct dm_odm_t *odm = &(hal_data->odmpriv);
584
585 switch (variable) {
586 case HW_VAR_PORT_SWITCH:
587 hw_var_port_switch(adapter);
588 break;
589 case HW_VAR_INIT_RTS_RATE:
590 rtw_warn_on(1);
591 break;
592 case HW_VAR_SEC_CFG:
593 {
594 u16 reg_scr;
595
596 reg_scr = rtw_read16(adapter, REG_SECCFG);
597 rtw_write16(adapter, REG_SECCFG, reg_scr|SCR_CHK_KEYID|SCR_RxDecEnable|SCR_TxEncEnable);
598 }
599 break;
600 case HW_VAR_SEC_DK_CFG:
601 {
602 struct security_priv *sec = &adapter->securitypriv;
603 u8 reg_scr = rtw_read8(adapter, REG_SECCFG);
604
605 if (val) { /* Enable default key related setting */
606 reg_scr |= SCR_TXBCUSEDK;
607 if (sec->dot11AuthAlgrthm != dot11AuthAlgrthm_8021X)
608 reg_scr |= (SCR_RxUseDK|SCR_TxUseDK);
609 } else /* Disable default key related setting */
610 reg_scr &= ~(SCR_RXBCUSEDK|SCR_TXBCUSEDK|SCR_RxUseDK|SCR_TxUseDK);
611
612 rtw_write8(adapter, REG_SECCFG, reg_scr);
613 }
614 break;
615 case HW_VAR_DM_FLAG:
616 odm->SupportAbility = *((u32 *)val);
617 break;
618 case HW_VAR_DM_FUNC_OP:
619 if (*((u8 *)val) == true) {
620 /* save dm flag */
621 odm->BK_SupportAbility = odm->SupportAbility;
622 } else {
623 /* restore dm flag */
624 odm->SupportAbility = odm->BK_SupportAbility;
625 }
626 break;
627 case HW_VAR_DM_FUNC_SET:
628 if (*((u32 *)val) == DYNAMIC_ALL_FUNC_ENABLE) {
629 struct dm_priv *dm = &hal_data->dmpriv;
630 dm->DMFlag = dm->InitDMFlag;
631 odm->SupportAbility = dm->InitODMFlag;
632 } else {
633 odm->SupportAbility |= *((u32 *)val);
634 }
635 break;
636 case HW_VAR_DM_FUNC_CLR:
637 /*
638 * input is already a mask to clear function
639 * don't invert it again! George, Lucas@20130513
640 */
641 odm->SupportAbility &= *((u32 *)val);
642 break;
643 case HW_VAR_AMPDU_MIN_SPACE:
644 /* TODO - Is something needed here? */
645 break;
646 case HW_VAR_WIRELESS_MODE:
647 /* TODO - Is something needed here? */
648 break;
649 default:
650 netdev_dbg(adapter->pnetdev,
651 FUNC_ADPT_FMT " variable(%d) not defined!\n",
652 FUNC_ADPT_ARG(adapter), variable);
653 break;
654 }
655 }
656
GetHwReg(struct adapter * adapter,u8 variable,u8 * val)657 void GetHwReg(struct adapter *adapter, u8 variable, u8 *val)
658 {
659 struct hal_com_data *hal_data = GET_HAL_DATA(adapter);
660 struct dm_odm_t *odm = &(hal_data->odmpriv);
661
662 switch (variable) {
663 case HW_VAR_BASIC_RATE:
664 *((u16 *)val) = hal_data->BasicRateSet;
665 break;
666 case HW_VAR_DM_FLAG:
667 *((u32 *)val) = odm->SupportAbility;
668 break;
669 default:
670 netdev_dbg(adapter->pnetdev,
671 FUNC_ADPT_FMT " variable(%d) not defined!\n",
672 FUNC_ADPT_ARG(adapter), variable);
673 break;
674 }
675 }
676
677
678
679
SetHalDefVar(struct adapter * adapter,enum hal_def_variable variable,void * value)680 u8 SetHalDefVar(
681 struct adapter *adapter, enum hal_def_variable variable, void *value
682 )
683 {
684 struct hal_com_data *hal_data = GET_HAL_DATA(adapter);
685 struct dm_odm_t *odm = &(hal_data->odmpriv);
686 u8 bResult = _SUCCESS;
687
688 switch (variable) {
689 case HAL_DEF_DBG_RX_INFO_DUMP:
690
691 if (odm->bLinked) {
692 #ifdef DBG_RX_SIGNAL_DISPLAY_RAW_DATA
693 rtw_dump_raw_rssi_info(adapter);
694 #endif
695 }
696 break;
697 case HW_DEF_ODM_DBG_FLAG:
698 ODM_CmnInfoUpdate(odm, ODM_CMNINFO_DBG_COMP, *((u64 *)value));
699 break;
700 case HW_DEF_ODM_DBG_LEVEL:
701 ODM_CmnInfoUpdate(odm, ODM_CMNINFO_DBG_LEVEL, *((u32 *)value));
702 break;
703 case HAL_DEF_DBG_DM_FUNC:
704 {
705 u8 dm_func = *((u8 *)value);
706 struct dm_priv *dm = &hal_data->dmpriv;
707
708 if (dm_func == 0) { /* disable all dynamic func */
709 odm->SupportAbility = DYNAMIC_FUNC_DISABLE;
710 } else if (dm_func == 1) {/* disable DIG */
711 odm->SupportAbility &= (~DYNAMIC_BB_DIG);
712 } else if (dm_func == 2) {/* disable High power */
713 odm->SupportAbility &= (~DYNAMIC_BB_DYNAMIC_TXPWR);
714 } else if (dm_func == 3) {/* disable tx power tracking */
715 odm->SupportAbility &= (~DYNAMIC_RF_CALIBRATION);
716 } else if (dm_func == 4) {/* disable BT coexistence */
717 dm->DMFlag &= (~DYNAMIC_FUNC_BT);
718 } else if (dm_func == 5) {/* disable antenna diversity */
719 odm->SupportAbility &= (~DYNAMIC_BB_ANT_DIV);
720 } else if (dm_func == 6) {/* turn on all dynamic func */
721 if (!(odm->SupportAbility & DYNAMIC_BB_DIG)) {
722 struct dig_t *pDigTable = &odm->DM_DigTable;
723 pDigTable->CurIGValue = rtw_read8(adapter, 0xc50);
724 }
725 dm->DMFlag |= DYNAMIC_FUNC_BT;
726 odm->SupportAbility = DYNAMIC_ALL_FUNC_ENABLE;
727 }
728 }
729 break;
730 case HAL_DEF_DBG_DUMP_RXPKT:
731 hal_data->bDumpRxPkt = *((u8 *)value);
732 break;
733 case HAL_DEF_DBG_DUMP_TXPKT:
734 hal_data->bDumpTxPkt = *((u8 *)value);
735 break;
736 case HAL_DEF_ANT_DETECT:
737 hal_data->AntDetection = *((u8 *)value);
738 break;
739 default:
740 netdev_dbg(adapter->pnetdev,
741 "%s: [WARNING] HAL_DEF_VARIABLE(%d) not defined!\n",
742 __func__, variable);
743 bResult = _FAIL;
744 break;
745 }
746
747 return bResult;
748 }
749
GetHalDefVar(struct adapter * adapter,enum hal_def_variable variable,void * value)750 u8 GetHalDefVar(
751 struct adapter *adapter, enum hal_def_variable variable, void *value
752 )
753 {
754 struct hal_com_data *hal_data = GET_HAL_DATA(adapter);
755 u8 bResult = _SUCCESS;
756
757 switch (variable) {
758 case HAL_DEF_UNDERCORATEDSMOOTHEDPWDB:
759 {
760 struct mlme_priv *pmlmepriv;
761 struct sta_priv *pstapriv;
762 struct sta_info *psta;
763
764 pmlmepriv = &adapter->mlmepriv;
765 pstapriv = &adapter->stapriv;
766 psta = rtw_get_stainfo(pstapriv, pmlmepriv->cur_network.network.mac_address);
767 if (psta)
768 *((int *)value) = psta->rssi_stat.UndecoratedSmoothedPWDB;
769 }
770 break;
771 case HAL_DEF_DBG_DM_FUNC:
772 *((u32 *)value) = hal_data->odmpriv.SupportAbility;
773 break;
774 case HAL_DEF_DBG_DUMP_RXPKT:
775 *((u8 *)value) = hal_data->bDumpRxPkt;
776 break;
777 case HAL_DEF_DBG_DUMP_TXPKT:
778 *((u8 *)value) = hal_data->bDumpTxPkt;
779 break;
780 case HAL_DEF_ANT_DETECT:
781 *((u8 *)value) = hal_data->AntDetection;
782 break;
783 case HAL_DEF_MACID_SLEEP:
784 *(u8 *)value = false;
785 break;
786 case HAL_DEF_TX_PAGE_SIZE:
787 *((u32 *)value) = PAGE_SIZE_128;
788 break;
789 default:
790 netdev_dbg(adapter->pnetdev,
791 "%s: [WARNING] HAL_DEF_VARIABLE(%d) not defined!\n",
792 __func__, variable);
793 bResult = _FAIL;
794 break;
795 }
796
797 return bResult;
798 }
799
GetHalODMVar(struct adapter * Adapter,enum hal_odm_variable eVariable,void * pValue1,void * pValue2)800 void GetHalODMVar(
801 struct adapter *Adapter,
802 enum hal_odm_variable eVariable,
803 void *pValue1,
804 void *pValue2
805 )
806 {
807 switch (eVariable) {
808 default:
809 break;
810 }
811 }
812
SetHalODMVar(struct adapter * Adapter,enum hal_odm_variable eVariable,void * pValue1,bool bSet)813 void SetHalODMVar(
814 struct adapter *Adapter,
815 enum hal_odm_variable eVariable,
816 void *pValue1,
817 bool bSet
818 )
819 {
820 struct hal_com_data *pHalData = GET_HAL_DATA(Adapter);
821 struct dm_odm_t *podmpriv = &pHalData->odmpriv;
822 /* _irqL irqL; */
823 switch (eVariable) {
824 case HAL_ODM_STA_INFO:
825 {
826 struct sta_info *psta = pValue1;
827 if (bSet) {
828 ODM_CmnInfoPtrArrayHook(podmpriv, ODM_CMNINFO_STA_STATUS, psta->mac_id, psta);
829 } else {
830 /* spin_lock_bh(&pHalData->odm_stainfo_lock); */
831 ODM_CmnInfoPtrArrayHook(podmpriv, ODM_CMNINFO_STA_STATUS, psta->mac_id, NULL);
832
833 /* spin_unlock_bh(&pHalData->odm_stainfo_lock); */
834 }
835 }
836 break;
837 case HAL_ODM_P2P_STATE:
838 ODM_CmnInfoUpdate(podmpriv, ODM_CMNINFO_WIFI_DIRECT, bSet);
839 break;
840 case HAL_ODM_WIFI_DISPLAY_STATE:
841 ODM_CmnInfoUpdate(podmpriv, ODM_CMNINFO_WIFI_DISPLAY, bSet);
842 break;
843
844 default:
845 break;
846 }
847 }
848
849
eqNByte(u8 * str1,u8 * str2,u32 num)850 bool eqNByte(u8 *str1, u8 *str2, u32 num)
851 {
852 if (num == 0)
853 return false;
854 while (num > 0) {
855 num--;
856 if (str1[num] != str2[num])
857 return false;
858 }
859 return true;
860 }
861
862 /* */
863 /* Description: */
864 /* Translate a character to hex digit. */
865 /* */
MapCharToHexDigit(char chTmp)866 u32 MapCharToHexDigit(char chTmp)
867 {
868 if (chTmp >= '0' && chTmp <= '9')
869 return chTmp - '0';
870 else if (chTmp >= 'a' && chTmp <= 'f')
871 return 10 + (chTmp - 'a');
872 else if (chTmp >= 'A' && chTmp <= 'F')
873 return 10 + (chTmp - 'A');
874 else
875 return 0;
876 }
877
GetU1ByteIntegerFromStringInDecimal(char * Str,u8 * pInt)878 bool GetU1ByteIntegerFromStringInDecimal(char *Str, u8 *pInt)
879 {
880 u16 i = 0;
881 *pInt = 0;
882
883 while (Str[i] != '\0') {
884 if (Str[i] >= '0' && Str[i] <= '9') {
885 *pInt *= 10;
886 *pInt += (Str[i] - '0');
887 } else
888 return false;
889
890 ++i;
891 }
892
893 return true;
894 }
895
896 /* <20121004, Kordan> For example,
897 * ParseQualifiedString(inString, 0, outString, '[', ']') gets "Kordan" from
898 * a string "Hello [Kordan]".
899 * If RightQualifier does not exist, it will hang in the while loop
900 */
ParseQualifiedString(char * In,u32 * Start,char * Out,char LeftQualifier,char RightQualifier)901 bool ParseQualifiedString(
902 char *In, u32 *Start, char *Out, char LeftQualifier, char RightQualifier
903 )
904 {
905 u32 i = 0, j = 0;
906 char c = In[(*Start)++];
907
908 if (c != LeftQualifier)
909 return false;
910
911 i = (*Start);
912 while ((c = In[(*Start)++]) != RightQualifier)
913 ; /* find ']' */
914 j = (*Start) - 2;
915 strncpy((char *)Out, (const char *)(In+i), j-i+1);
916
917 return true;
918 }
919
isAllSpaceOrTab(u8 * data,u8 size)920 bool isAllSpaceOrTab(u8 *data, u8 size)
921 {
922 u8 cnt = 0, NumOfSpaceAndTab = 0;
923
924 while (size > cnt) {
925 if (data[cnt] == ' ' || data[cnt] == '\t' || data[cnt] == '\0')
926 ++NumOfSpaceAndTab;
927
928 ++cnt;
929 }
930
931 return size == NumOfSpaceAndTab;
932 }
933
934
rtw_hal_check_rxfifo_full(struct adapter * adapter)935 void rtw_hal_check_rxfifo_full(struct adapter *adapter)
936 {
937 struct dvobj_priv *psdpriv = adapter->dvobj;
938 struct debug_priv *pdbgpriv = &psdpriv->drv_dbg;
939 int save_cnt = false;
940
941 /* switch counter to RX fifo */
942 /* printk("8723b or 8192e , MAC_667 set 0xf0\n"); */
943 rtw_write8(adapter, REG_RXERR_RPT+3, rtw_read8(adapter, REG_RXERR_RPT+3)|0xf0);
944 save_cnt = true;
945 /* todo: other chips */
946
947 if (save_cnt) {
948 /* rtw_write8(adapter, REG_RXERR_RPT+3, rtw_read8(adapter, REG_RXERR_RPT+3)|0xa0); */
949 pdbgpriv->dbg_rx_fifo_last_overflow = pdbgpriv->dbg_rx_fifo_curr_overflow;
950 pdbgpriv->dbg_rx_fifo_curr_overflow = rtw_read16(adapter, REG_RXERR_RPT);
951 pdbgpriv->dbg_rx_fifo_diff_overflow = pdbgpriv->dbg_rx_fifo_curr_overflow-pdbgpriv->dbg_rx_fifo_last_overflow;
952 }
953 }
954
linked_info_dump(struct adapter * padapter,u8 benable)955 void linked_info_dump(struct adapter *padapter, u8 benable)
956 {
957 struct pwrctrl_priv *pwrctrlpriv = adapter_to_pwrctl(padapter);
958
959 if (padapter->bLinkInfoDump == benable)
960 return;
961
962 if (benable) {
963 pwrctrlpriv->org_power_mgnt = pwrctrlpriv->power_mgnt;/* keep org value */
964 rtw_pm_set_lps(padapter, PS_MODE_ACTIVE);
965
966 pwrctrlpriv->ips_org_mode = pwrctrlpriv->ips_mode;/* keep org value */
967 rtw_pm_set_ips(padapter, IPS_NONE);
968 } else {
969 rtw_pm_set_ips(padapter, pwrctrlpriv->ips_org_mode);
970
971 rtw_pm_set_lps(padapter, pwrctrlpriv->ips_org_mode);
972 }
973 padapter->bLinkInfoDump = benable;
974 }
975
976 #ifdef DBG_RX_SIGNAL_DISPLAY_RAW_DATA
rtw_get_raw_rssi_info(void * sel,struct adapter * padapter)977 void rtw_get_raw_rssi_info(void *sel, struct adapter *padapter)
978 {
979 u8 isCCKrate, rf_path;
980 struct hal_com_data *pHalData = GET_HAL_DATA(padapter);
981 struct rx_raw_rssi *psample_pkt_rssi = &padapter->recvpriv.raw_rssi_info;
982
983 netdev_dbg(padapter->pnetdev,
984 "RxRate = %s, PWDBALL = %d(%%), rx_pwr_all = %d(dBm)\n",
985 HDATA_RATE(psample_pkt_rssi->data_rate),
986 psample_pkt_rssi->pwdball, psample_pkt_rssi->pwr_all);
987
988 isCCKrate = psample_pkt_rssi->data_rate <= DESC_RATE11M;
989
990 if (isCCKrate)
991 psample_pkt_rssi->mimo_signal_strength[0] = psample_pkt_rssi->pwdball;
992
993 for (rf_path = 0; rf_path < pHalData->NumTotalRFPath; rf_path++) {
994 netdev_dbg(padapter->pnetdev,
995 "RF_PATH_%d =>signal_strength:%d(%%), signal_quality:%d(%%)\n",
996 rf_path,
997 psample_pkt_rssi->mimo_signal_strength[rf_path],
998 psample_pkt_rssi->mimo_signal_quality[rf_path]);
999
1000 if (!isCCKrate) {
1001 netdev_dbg(padapter->pnetdev,
1002 "\trx_ofdm_pwr:%d(dBm), rx_ofdm_snr:%d(dB)\n",
1003 psample_pkt_rssi->ofdm_pwr[rf_path],
1004 psample_pkt_rssi->ofdm_snr[rf_path]);
1005 }
1006 }
1007 }
1008
rtw_dump_raw_rssi_info(struct adapter * padapter)1009 void rtw_dump_raw_rssi_info(struct adapter *padapter)
1010 {
1011 u8 isCCKrate, rf_path;
1012 struct hal_com_data *pHalData = GET_HAL_DATA(padapter);
1013 struct rx_raw_rssi *psample_pkt_rssi = &padapter->recvpriv.raw_rssi_info;
1014
1015 isCCKrate = psample_pkt_rssi->data_rate <= DESC_RATE11M;
1016
1017 if (isCCKrate)
1018 psample_pkt_rssi->mimo_signal_strength[0] = psample_pkt_rssi->pwdball;
1019
1020 for (rf_path = 0; rf_path < pHalData->NumTotalRFPath; rf_path++) {
1021 if (!isCCKrate) {
1022 printk(", rx_ofdm_pwr:%d(dBm), rx_ofdm_snr:%d(dB)\n",
1023 psample_pkt_rssi->ofdm_pwr[rf_path], psample_pkt_rssi->ofdm_snr[rf_path]);
1024 } else {
1025 printk("\n");
1026 }
1027 }
1028 }
1029
rtw_store_phy_info(struct adapter * padapter,union recv_frame * prframe)1030 void rtw_store_phy_info(struct adapter *padapter, union recv_frame *prframe)
1031 {
1032 u8 isCCKrate, rf_path;
1033 struct hal_com_data *pHalData = GET_HAL_DATA(padapter);
1034 struct rx_pkt_attrib *pattrib = &prframe->u.hdr.attrib;
1035
1036 struct odm_phy_info *pPhyInfo = (PODM_PHY_INFO_T)(&pattrib->phy_info);
1037 struct rx_raw_rssi *psample_pkt_rssi = &padapter->recvpriv.raw_rssi_info;
1038
1039 psample_pkt_rssi->data_rate = pattrib->data_rate;
1040 isCCKrate = pattrib->data_rate <= DESC_RATE11M;
1041
1042 psample_pkt_rssi->pwdball = pPhyInfo->rx_pwd_ba11;
1043 psample_pkt_rssi->pwr_all = pPhyInfo->recv_signal_power;
1044
1045 for (rf_path = 0; rf_path < pHalData->NumTotalRFPath; rf_path++) {
1046 psample_pkt_rssi->mimo_signal_strength[rf_path] = pPhyInfo->rx_mimo_signal_strength[rf_path];
1047 psample_pkt_rssi->mimo_signal_quality[rf_path] = pPhyInfo->rx_mimo_signal_quality[rf_path];
1048 if (!isCCKrate) {
1049 psample_pkt_rssi->ofdm_pwr[rf_path] = pPhyInfo->RxPwr[rf_path];
1050 psample_pkt_rssi->ofdm_snr[rf_path] = pPhyInfo->RxSNR[rf_path];
1051 }
1052 }
1053 }
1054 #endif
1055
1056 static u32 Array_kfreemap[] = {
1057 0xf8, 0xe,
1058 0xf6, 0xc,
1059 0xf4, 0xa,
1060 0xf2, 0x8,
1061 0xf0, 0x6,
1062 0xf3, 0x4,
1063 0xf5, 0x2,
1064 0xf7, 0x0,
1065 0xf9, 0x0,
1066 0xfc, 0x0,
1067 };
1068
rtw_bb_rf_gain_offset(struct adapter * padapter)1069 void rtw_bb_rf_gain_offset(struct adapter *padapter)
1070 {
1071 u8 value = padapter->eeprompriv.EEPROMRFGainOffset;
1072 u32 res, i = 0;
1073 u32 *Array = Array_kfreemap;
1074 u32 v1 = 0, v2 = 0, target = 0;
1075
1076 if (value & BIT4) {
1077 if (padapter->eeprompriv.EEPROMRFGainVal != 0xff) {
1078 res = rtw_hal_read_rfreg(padapter, RF_PATH_A, 0x7f, 0xffffffff);
1079 res &= 0xfff87fff;
1080 /* res &= 0xfff87fff; */
1081 for (i = 0; i < ARRAY_SIZE(Array_kfreemap); i += 2) {
1082 v1 = Array[i];
1083 v2 = Array[i+1];
1084 if (v1 == padapter->eeprompriv.EEPROMRFGainVal) {
1085 target = v2;
1086 break;
1087 }
1088 }
1089 PHY_SetRFReg(padapter, RF_PATH_A, REG_RF_BB_GAIN_OFFSET, BIT18|BIT17|BIT16|BIT15, target);
1090
1091 /* res |= (padapter->eeprompriv.EEPROMRFGainVal & 0x0f)<< 15; */
1092 /* rtw_hal_write_rfreg(padapter, RF_PATH_A, REG_RF_BB_GAIN_OFFSET, RF_GAIN_OFFSET_MASK, res); */
1093 res = rtw_hal_read_rfreg(padapter, RF_PATH_A, 0x7f, 0xffffffff);
1094 }
1095 }
1096 }
1097