1 /******************************************************************************
2 *
3 * Copyright(c) 2007 - 2017 Realtek Corporation.
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of version 2 of the GNU General Public License as
7 * published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12 * more details.
13 *
14 *****************************************************************************/
15 #define _HAL_COM_C_
16
17 #include <drv_types.h>
18 #include "hal_com_h2c.h"
19
20 #include "hal_data.h"
21
22 #ifdef RTW_HALMAC
23 #include "../../hal/hal_halmac.h"
24 #endif
25
rtw_dump_fw_info(void * sel,_adapter * adapter)26 void rtw_dump_fw_info(void *sel, _adapter *adapter)
27 {
28 HAL_DATA_TYPE *hal_data = NULL;
29
30 if (!adapter)
31 return;
32
33 hal_data = GET_HAL_DATA(adapter);
34 if (hal_data->bFWReady)
35 RTW_PRINT_SEL(sel, "FW VER -%d.%d\n", hal_data->firmware_version, hal_data->firmware_sub_version);
36 else
37 RTW_PRINT_SEL(sel, "FW not ready\n");
38 }
39
40 /* #define CONFIG_GTK_OL_DBG */
41
42 /*#define DBG_SEC_CAM_MOVE*/
43 #ifdef DBG_SEC_CAM_MOVE
rtw_hal_move_sta_gk_to_dk(_adapter * adapter)44 void rtw_hal_move_sta_gk_to_dk(_adapter *adapter)
45 {
46 struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
47 int cam_id, index = 0;
48 u8 *addr = NULL;
49
50 if (!MLME_IS_STA(adapter))
51 return;
52
53 addr = get_bssid(pmlmepriv);
54
55 if (addr == NULL) {
56 RTW_INFO("%s: get bssid MAC addr fail!!\n", __func__);
57 return;
58 }
59
60 rtw_clean_dk_section(adapter);
61
62 do {
63 cam_id = rtw_camid_search(adapter, addr, index, 1);
64
65 if (cam_id == -1)
66 RTW_INFO("%s: cam_id: %d, key_id:%d\n", __func__, cam_id, index);
67 else
68 rtw_sec_cam_swap(adapter, cam_id, index);
69
70 index++;
71 } while (index < 4);
72
73 }
74
rtw_hal_read_sta_dk_key(_adapter * adapter,u8 key_id)75 void rtw_hal_read_sta_dk_key(_adapter *adapter, u8 key_id)
76 {
77 struct security_priv *psecuritypriv = &adapter->securitypriv;
78 struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
79 struct cam_ctl_t *cam_ctl = &dvobj->cam_ctl;
80 _irqL irqL;
81 u8 get_key[16];
82
83 _rtw_memset(get_key, 0, sizeof(get_key));
84
85 if (key_id > 4) {
86 RTW_INFO("%s [ERROR] gtk_keyindex:%d invalid\n", __func__, key_id);
87 rtw_warn_on(1);
88 return;
89 }
90 rtw_sec_read_cam_ent(adapter, key_id, NULL, NULL, get_key);
91
92 /*update key into related sw variable*/
93 _enter_critical_bh(&cam_ctl->lock, &irqL);
94 if (_rtw_camid_is_gk(adapter, key_id)) {
95 RTW_INFO("[HW KEY] -Key-id:%d "KEY_FMT"\n", key_id, KEY_ARG(get_key));
96 RTW_INFO("[cam_cache KEY] - Key-id:%d "KEY_FMT"\n", key_id, KEY_ARG(&dvobj->cam_cache[key_id].key));
97 }
98 _exit_critical_bh(&cam_ctl->lock, &irqL);
99
100 }
101 #endif
102
103
104 #ifdef CONFIG_LOAD_PHY_PARA_FROM_FILE
105 char rtw_phy_para_file_path[PATH_LENGTH_MAX];
106 #endif
107
dump_chip_info(HAL_VERSION ChipVersion)108 void dump_chip_info(HAL_VERSION ChipVersion)
109 {
110 int cnt = 0;
111 u8 buf[128] = {0};
112
113 if (IS_8188E(ChipVersion))
114 cnt += sprintf((buf + cnt), "Chip Version Info: CHIP_8188E_");
115 else if (IS_8188F(ChipVersion))
116 cnt += sprintf((buf + cnt), "Chip Version Info: CHIP_8188F_");
117 else if (IS_8812_SERIES(ChipVersion))
118 cnt += sprintf((buf + cnt), "Chip Version Info: CHIP_8812_");
119 else if (IS_8192E(ChipVersion))
120 cnt += sprintf((buf + cnt), "Chip Version Info: CHIP_8192E_");
121 else if (IS_8821_SERIES(ChipVersion))
122 cnt += sprintf((buf + cnt), "Chip Version Info: CHIP_8821_");
123 else if (IS_8723B_SERIES(ChipVersion))
124 cnt += sprintf((buf + cnt), "Chip Version Info: CHIP_8723B_");
125 else if (IS_8703B_SERIES(ChipVersion))
126 cnt += sprintf((buf + cnt), "Chip Version Info: CHIP_8703B_");
127 else if (IS_8723D_SERIES(ChipVersion))
128 cnt += sprintf((buf + cnt), "Chip Version Info: CHIP_8723D_");
129 else if (IS_8814A_SERIES(ChipVersion))
130 cnt += sprintf((buf + cnt), "Chip Version Info: CHIP_8814A_");
131 else if (IS_8822B_SERIES(ChipVersion))
132 cnt += sprintf((buf + cnt), "Chip Version Info: CHIP_8822B_");
133 else if (IS_8821C_SERIES(ChipVersion))
134 cnt += sprintf((buf + cnt), "Chip Version Info: CHIP_8821C_");
135 else
136 cnt += sprintf((buf + cnt), "Chip Version Info: CHIP_UNKNOWN_");
137
138 cnt += sprintf((buf + cnt), "%s_", IS_NORMAL_CHIP(ChipVersion) ? "Normal_Chip" : "Test_Chip");
139 if (IS_CHIP_VENDOR_TSMC(ChipVersion))
140 cnt += sprintf((buf + cnt), "%s_", "TSMC");
141 else if (IS_CHIP_VENDOR_UMC(ChipVersion))
142 cnt += sprintf((buf + cnt), "%s_", "UMC");
143 else if (IS_CHIP_VENDOR_SMIC(ChipVersion))
144 cnt += sprintf((buf + cnt), "%s_", "SMIC");
145
146 if (IS_A_CUT(ChipVersion))
147 cnt += sprintf((buf + cnt), "A_CUT_");
148 else if (IS_B_CUT(ChipVersion))
149 cnt += sprintf((buf + cnt), "B_CUT_");
150 else if (IS_C_CUT(ChipVersion))
151 cnt += sprintf((buf + cnt), "C_CUT_");
152 else if (IS_D_CUT(ChipVersion))
153 cnt += sprintf((buf + cnt), "D_CUT_");
154 else if (IS_E_CUT(ChipVersion))
155 cnt += sprintf((buf + cnt), "E_CUT_");
156 else if (IS_F_CUT(ChipVersion))
157 cnt += sprintf((buf + cnt), "F_CUT_");
158 else if (IS_I_CUT(ChipVersion))
159 cnt += sprintf((buf + cnt), "I_CUT_");
160 else if (IS_J_CUT(ChipVersion))
161 cnt += sprintf((buf + cnt), "J_CUT_");
162 else if (IS_K_CUT(ChipVersion))
163 cnt += sprintf((buf + cnt), "K_CUT_");
164 else
165 cnt += sprintf((buf + cnt), "UNKNOWN_CUT(%d)_", ChipVersion.CUTVersion);
166
167 if (IS_1T1R(ChipVersion))
168 cnt += sprintf((buf + cnt), "1T1R_");
169 else if (IS_1T2R(ChipVersion))
170 cnt += sprintf((buf + cnt), "1T2R_");
171 else if (IS_2T2R(ChipVersion))
172 cnt += sprintf((buf + cnt), "2T2R_");
173 else if (IS_3T3R(ChipVersion))
174 cnt += sprintf((buf + cnt), "3T3R_");
175 else if (IS_3T4R(ChipVersion))
176 cnt += sprintf((buf + cnt), "3T4R_");
177 else if (IS_4T4R(ChipVersion))
178 cnt += sprintf((buf + cnt), "4T4R_");
179 else
180 cnt += sprintf((buf + cnt), "UNKNOWN_RFTYPE(%d)_", ChipVersion.RFType);
181
182 cnt += sprintf((buf + cnt), "RomVer(%d)\n", ChipVersion.ROMVer);
183
184 RTW_INFO("%s", buf);
185 }
rtw_hal_config_rftype(PADAPTER padapter)186 void rtw_hal_config_rftype(PADAPTER padapter)
187 {
188 HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);
189
190 if (IS_1T1R(pHalData->version_id)) {
191 pHalData->rf_type = RF_1T1R;
192 pHalData->NumTotalRFPath = 1;
193 } else if (IS_2T2R(pHalData->version_id)) {
194 pHalData->rf_type = RF_2T2R;
195 pHalData->NumTotalRFPath = 2;
196 } else if (IS_1T2R(pHalData->version_id)) {
197 pHalData->rf_type = RF_1T2R;
198 pHalData->NumTotalRFPath = 2;
199 } else if (IS_3T3R(pHalData->version_id)) {
200 pHalData->rf_type = RF_3T3R;
201 pHalData->NumTotalRFPath = 3;
202 } else if (IS_4T4R(pHalData->version_id)) {
203 pHalData->rf_type = RF_4T4R;
204 pHalData->NumTotalRFPath = 4;
205 } else {
206 pHalData->rf_type = RF_1T1R;
207 pHalData->NumTotalRFPath = 1;
208 }
209
210 RTW_INFO("%s RF_Type is %d TotalTxPath is %d\n", __FUNCTION__, pHalData->rf_type, pHalData->NumTotalRFPath);
211 }
212
213 #define EEPROM_CHANNEL_PLAN_BY_HW_MASK 0x80
214
215 /*
216 * Description:
217 * Use hardware(efuse), driver parameter(registry) and default channel plan
218 * to decide which one should be used.
219 *
220 * Parameters:
221 * padapter pointer of adapter
222 * hw_alpha2 country code from HW (efuse/eeprom/mapfile)
223 * hw_chplan channel plan from HW (efuse/eeprom/mapfile)
224 * BIT[7] software configure mode; 0:Enable, 1:disable
225 * BIT[6:0] Channel Plan
226 * sw_alpha2 country code from HW (registry/module param)
227 * sw_chplan channel plan from SW (registry/module param)
228 * def_chplan channel plan used when HW/SW both invalid
229 * AutoLoadFail efuse autoload fail or not
230 *
231 */
hal_com_config_channel_plan(IN PADAPTER padapter,IN char * hw_alpha2,IN u8 hw_chplan,IN char * sw_alpha2,IN u8 sw_chplan,IN u8 def_chplan,IN BOOLEAN AutoLoadFail)232 void hal_com_config_channel_plan(
233 IN PADAPTER padapter,
234 IN char *hw_alpha2,
235 IN u8 hw_chplan,
236 IN char *sw_alpha2,
237 IN u8 sw_chplan,
238 IN u8 def_chplan,
239 IN BOOLEAN AutoLoadFail
240 )
241 {
242 struct rf_ctl_t *rfctl = adapter_to_rfctl(padapter);
243 PHAL_DATA_TYPE pHalData;
244 u8 force_hw_chplan = _FALSE;
245 int chplan = -1;
246 const struct country_chplan *country_ent = NULL, *ent;
247
248 pHalData = GET_HAL_DATA(padapter);
249
250 /* treat 0xFF as invalid value, bypass hw_chplan & force_hw_chplan parsing */
251 if (hw_chplan == 0xFF)
252 goto chk_hw_country_code;
253
254 if (AutoLoadFail == _TRUE)
255 goto chk_sw_config;
256
257 #ifndef CONFIG_FORCE_SW_CHANNEL_PLAN
258 if (hw_chplan & EEPROM_CHANNEL_PLAN_BY_HW_MASK)
259 force_hw_chplan = _TRUE;
260 #endif
261
262 hw_chplan &= (~EEPROM_CHANNEL_PLAN_BY_HW_MASK);
263
264 chk_hw_country_code:
265 if (hw_alpha2 && !IS_ALPHA2_NO_SPECIFIED(hw_alpha2)) {
266 ent = rtw_get_chplan_from_country(hw_alpha2);
267 if (ent) {
268 /* get chplan from hw country code, by pass hw chplan setting */
269 country_ent = ent;
270 chplan = ent->chplan;
271 goto chk_sw_config;
272 } else
273 RTW_PRINT("%s unsupported hw_alpha2:\"%c%c\"\n", __func__, hw_alpha2[0], hw_alpha2[1]);
274 }
275
276 if (rtw_is_channel_plan_valid(hw_chplan))
277 chplan = hw_chplan;
278 else if (force_hw_chplan == _TRUE) {
279 RTW_PRINT("%s unsupported hw_chplan:0x%02X\n", __func__, hw_chplan);
280 /* hw infomaton invalid, refer to sw information */
281 force_hw_chplan = _FALSE;
282 }
283
284 chk_sw_config:
285 if (force_hw_chplan == _TRUE)
286 goto done;
287
288 if (sw_alpha2 && !IS_ALPHA2_NO_SPECIFIED(sw_alpha2)) {
289 ent = rtw_get_chplan_from_country(sw_alpha2);
290 if (ent) {
291 /* get chplan from sw country code, by pass sw chplan setting */
292 country_ent = ent;
293 chplan = ent->chplan;
294 goto done;
295 } else
296 RTW_PRINT("%s unsupported sw_alpha2:\"%c%c\"\n", __func__, sw_alpha2[0], sw_alpha2[1]);
297 }
298
299 if (rtw_is_channel_plan_valid(sw_chplan)) {
300 /* cancel hw_alpha2 because chplan is specified by sw_chplan*/
301 country_ent = NULL;
302 chplan = sw_chplan;
303 } else if (sw_chplan != RTW_CHPLAN_UNSPECIFIED)
304 RTW_PRINT("%s unsupported sw_chplan:0x%02X\n", __func__, sw_chplan);
305
306 done:
307 if (chplan == -1) {
308 RTW_PRINT("%s use def_chplan:0x%02X\n", __func__, def_chplan);
309 chplan = def_chplan;
310 } else if (country_ent) {
311 RTW_PRINT("%s country code:\"%c%c\" with chplan:0x%02X\n", __func__
312 , country_ent->alpha2[0], country_ent->alpha2[1], country_ent->chplan);
313 } else
314 RTW_PRINT("%s chplan:0x%02X\n", __func__, chplan);
315
316 rfctl->country_ent = country_ent;
317 rfctl->ChannelPlan = chplan;
318 pHalData->bDisableSWChannelPlan = force_hw_chplan;
319 }
320
321 BOOLEAN
HAL_IsLegalChannel(IN PADAPTER Adapter,IN u32 Channel)322 HAL_IsLegalChannel(
323 IN PADAPTER Adapter,
324 IN u32 Channel
325 )
326 {
327 BOOLEAN bLegalChannel = _TRUE;
328
329 if (Channel > 14) {
330 if (is_supported_5g(Adapter->registrypriv.wireless_mode) == _FALSE) {
331 bLegalChannel = _FALSE;
332 RTW_INFO("Channel > 14 but wireless_mode do not support 5G\n");
333 }
334 } else if ((Channel <= 14) && (Channel >= 1)) {
335 if (IsSupported24G(Adapter->registrypriv.wireless_mode) == _FALSE) {
336 bLegalChannel = _FALSE;
337 RTW_INFO("(Channel <= 14) && (Channel >=1) but wireless_mode do not support 2.4G\n");
338 }
339 } else {
340 bLegalChannel = _FALSE;
341 RTW_INFO("Channel is Invalid !!!\n");
342 }
343
344 return bLegalChannel;
345 }
346
MRateToHwRate(u8 rate)347 u8 MRateToHwRate(u8 rate)
348 {
349 u8 ret = DESC_RATE1M;
350
351 switch (rate) {
352 case MGN_1M:
353 ret = DESC_RATE1M;
354 break;
355 case MGN_2M:
356 ret = DESC_RATE2M;
357 break;
358 case MGN_5_5M:
359 ret = DESC_RATE5_5M;
360 break;
361 case MGN_11M:
362 ret = DESC_RATE11M;
363 break;
364 case MGN_6M:
365 ret = DESC_RATE6M;
366 break;
367 case MGN_9M:
368 ret = DESC_RATE9M;
369 break;
370 case MGN_12M:
371 ret = DESC_RATE12M;
372 break;
373 case MGN_18M:
374 ret = DESC_RATE18M;
375 break;
376 case MGN_24M:
377 ret = DESC_RATE24M;
378 break;
379 case MGN_36M:
380 ret = DESC_RATE36M;
381 break;
382 case MGN_48M:
383 ret = DESC_RATE48M;
384 break;
385 case MGN_54M:
386 ret = DESC_RATE54M;
387 break;
388
389 case MGN_MCS0:
390 ret = DESC_RATEMCS0;
391 break;
392 case MGN_MCS1:
393 ret = DESC_RATEMCS1;
394 break;
395 case MGN_MCS2:
396 ret = DESC_RATEMCS2;
397 break;
398 case MGN_MCS3:
399 ret = DESC_RATEMCS3;
400 break;
401 case MGN_MCS4:
402 ret = DESC_RATEMCS4;
403 break;
404 case MGN_MCS5:
405 ret = DESC_RATEMCS5;
406 break;
407 case MGN_MCS6:
408 ret = DESC_RATEMCS6;
409 break;
410 case MGN_MCS7:
411 ret = DESC_RATEMCS7;
412 break;
413 case MGN_MCS8:
414 ret = DESC_RATEMCS8;
415 break;
416 case MGN_MCS9:
417 ret = DESC_RATEMCS9;
418 break;
419 case MGN_MCS10:
420 ret = DESC_RATEMCS10;
421 break;
422 case MGN_MCS11:
423 ret = DESC_RATEMCS11;
424 break;
425 case MGN_MCS12:
426 ret = DESC_RATEMCS12;
427 break;
428 case MGN_MCS13:
429 ret = DESC_RATEMCS13;
430 break;
431 case MGN_MCS14:
432 ret = DESC_RATEMCS14;
433 break;
434 case MGN_MCS15:
435 ret = DESC_RATEMCS15;
436 break;
437 case MGN_MCS16:
438 ret = DESC_RATEMCS16;
439 break;
440 case MGN_MCS17:
441 ret = DESC_RATEMCS17;
442 break;
443 case MGN_MCS18:
444 ret = DESC_RATEMCS18;
445 break;
446 case MGN_MCS19:
447 ret = DESC_RATEMCS19;
448 break;
449 case MGN_MCS20:
450 ret = DESC_RATEMCS20;
451 break;
452 case MGN_MCS21:
453 ret = DESC_RATEMCS21;
454 break;
455 case MGN_MCS22:
456 ret = DESC_RATEMCS22;
457 break;
458 case MGN_MCS23:
459 ret = DESC_RATEMCS23;
460 break;
461 case MGN_MCS24:
462 ret = DESC_RATEMCS24;
463 break;
464 case MGN_MCS25:
465 ret = DESC_RATEMCS25;
466 break;
467 case MGN_MCS26:
468 ret = DESC_RATEMCS26;
469 break;
470 case MGN_MCS27:
471 ret = DESC_RATEMCS27;
472 break;
473 case MGN_MCS28:
474 ret = DESC_RATEMCS28;
475 break;
476 case MGN_MCS29:
477 ret = DESC_RATEMCS29;
478 break;
479 case MGN_MCS30:
480 ret = DESC_RATEMCS30;
481 break;
482 case MGN_MCS31:
483 ret = DESC_RATEMCS31;
484 break;
485
486 case MGN_VHT1SS_MCS0:
487 ret = DESC_RATEVHTSS1MCS0;
488 break;
489 case MGN_VHT1SS_MCS1:
490 ret = DESC_RATEVHTSS1MCS1;
491 break;
492 case MGN_VHT1SS_MCS2:
493 ret = DESC_RATEVHTSS1MCS2;
494 break;
495 case MGN_VHT1SS_MCS3:
496 ret = DESC_RATEVHTSS1MCS3;
497 break;
498 case MGN_VHT1SS_MCS4:
499 ret = DESC_RATEVHTSS1MCS4;
500 break;
501 case MGN_VHT1SS_MCS5:
502 ret = DESC_RATEVHTSS1MCS5;
503 break;
504 case MGN_VHT1SS_MCS6:
505 ret = DESC_RATEVHTSS1MCS6;
506 break;
507 case MGN_VHT1SS_MCS7:
508 ret = DESC_RATEVHTSS1MCS7;
509 break;
510 case MGN_VHT1SS_MCS8:
511 ret = DESC_RATEVHTSS1MCS8;
512 break;
513 case MGN_VHT1SS_MCS9:
514 ret = DESC_RATEVHTSS1MCS9;
515 break;
516 case MGN_VHT2SS_MCS0:
517 ret = DESC_RATEVHTSS2MCS0;
518 break;
519 case MGN_VHT2SS_MCS1:
520 ret = DESC_RATEVHTSS2MCS1;
521 break;
522 case MGN_VHT2SS_MCS2:
523 ret = DESC_RATEVHTSS2MCS2;
524 break;
525 case MGN_VHT2SS_MCS3:
526 ret = DESC_RATEVHTSS2MCS3;
527 break;
528 case MGN_VHT2SS_MCS4:
529 ret = DESC_RATEVHTSS2MCS4;
530 break;
531 case MGN_VHT2SS_MCS5:
532 ret = DESC_RATEVHTSS2MCS5;
533 break;
534 case MGN_VHT2SS_MCS6:
535 ret = DESC_RATEVHTSS2MCS6;
536 break;
537 case MGN_VHT2SS_MCS7:
538 ret = DESC_RATEVHTSS2MCS7;
539 break;
540 case MGN_VHT2SS_MCS8:
541 ret = DESC_RATEVHTSS2MCS8;
542 break;
543 case MGN_VHT2SS_MCS9:
544 ret = DESC_RATEVHTSS2MCS9;
545 break;
546 case MGN_VHT3SS_MCS0:
547 ret = DESC_RATEVHTSS3MCS0;
548 break;
549 case MGN_VHT3SS_MCS1:
550 ret = DESC_RATEVHTSS3MCS1;
551 break;
552 case MGN_VHT3SS_MCS2:
553 ret = DESC_RATEVHTSS3MCS2;
554 break;
555 case MGN_VHT3SS_MCS3:
556 ret = DESC_RATEVHTSS3MCS3;
557 break;
558 case MGN_VHT3SS_MCS4:
559 ret = DESC_RATEVHTSS3MCS4;
560 break;
561 case MGN_VHT3SS_MCS5:
562 ret = DESC_RATEVHTSS3MCS5;
563 break;
564 case MGN_VHT3SS_MCS6:
565 ret = DESC_RATEVHTSS3MCS6;
566 break;
567 case MGN_VHT3SS_MCS7:
568 ret = DESC_RATEVHTSS3MCS7;
569 break;
570 case MGN_VHT3SS_MCS8:
571 ret = DESC_RATEVHTSS3MCS8;
572 break;
573 case MGN_VHT3SS_MCS9:
574 ret = DESC_RATEVHTSS3MCS9;
575 break;
576 case MGN_VHT4SS_MCS0:
577 ret = DESC_RATEVHTSS4MCS0;
578 break;
579 case MGN_VHT4SS_MCS1:
580 ret = DESC_RATEVHTSS4MCS1;
581 break;
582 case MGN_VHT4SS_MCS2:
583 ret = DESC_RATEVHTSS4MCS2;
584 break;
585 case MGN_VHT4SS_MCS3:
586 ret = DESC_RATEVHTSS4MCS3;
587 break;
588 case MGN_VHT4SS_MCS4:
589 ret = DESC_RATEVHTSS4MCS4;
590 break;
591 case MGN_VHT4SS_MCS5:
592 ret = DESC_RATEVHTSS4MCS5;
593 break;
594 case MGN_VHT4SS_MCS6:
595 ret = DESC_RATEVHTSS4MCS6;
596 break;
597 case MGN_VHT4SS_MCS7:
598 ret = DESC_RATEVHTSS4MCS7;
599 break;
600 case MGN_VHT4SS_MCS8:
601 ret = DESC_RATEVHTSS4MCS8;
602 break;
603 case MGN_VHT4SS_MCS9:
604 ret = DESC_RATEVHTSS4MCS9;
605 break;
606 default:
607 break;
608 }
609
610 return ret;
611 }
612
hw_rate_to_m_rate(u8 rate)613 u8 hw_rate_to_m_rate(u8 rate)
614 {
615 u8 ret_rate = MGN_1M;
616
617 switch (rate) {
618
619 case DESC_RATE1M:
620 ret_rate = MGN_1M;
621 break;
622 case DESC_RATE2M:
623 ret_rate = MGN_2M;
624 break;
625 case DESC_RATE5_5M:
626 ret_rate = MGN_5_5M;
627 break;
628 case DESC_RATE11M:
629 ret_rate = MGN_11M;
630 break;
631 case DESC_RATE6M:
632 ret_rate = MGN_6M;
633 break;
634 case DESC_RATE9M:
635 ret_rate = MGN_9M;
636 break;
637 case DESC_RATE12M:
638 ret_rate = MGN_12M;
639 break;
640 case DESC_RATE18M:
641 ret_rate = MGN_18M;
642 break;
643 case DESC_RATE24M:
644 ret_rate = MGN_24M;
645 break;
646 case DESC_RATE36M:
647 ret_rate = MGN_36M;
648 break;
649 case DESC_RATE48M:
650 ret_rate = MGN_48M;
651 break;
652 case DESC_RATE54M:
653 ret_rate = MGN_54M;
654 break;
655 case DESC_RATEMCS0:
656 ret_rate = MGN_MCS0;
657 break;
658 case DESC_RATEMCS1:
659 ret_rate = MGN_MCS1;
660 break;
661 case DESC_RATEMCS2:
662 ret_rate = MGN_MCS2;
663 break;
664 case DESC_RATEMCS3:
665 ret_rate = MGN_MCS3;
666 break;
667 case DESC_RATEMCS4:
668 ret_rate = MGN_MCS4;
669 break;
670 case DESC_RATEMCS5:
671 ret_rate = MGN_MCS5;
672 break;
673 case DESC_RATEMCS6:
674 ret_rate = MGN_MCS6;
675 break;
676 case DESC_RATEMCS7:
677 ret_rate = MGN_MCS7;
678 break;
679 case DESC_RATEMCS8:
680 ret_rate = MGN_MCS8;
681 break;
682 case DESC_RATEMCS9:
683 ret_rate = MGN_MCS9;
684 break;
685 case DESC_RATEMCS10:
686 ret_rate = MGN_MCS10;
687 break;
688 case DESC_RATEMCS11:
689 ret_rate = MGN_MCS11;
690 break;
691 case DESC_RATEMCS12:
692 ret_rate = MGN_MCS12;
693 break;
694 case DESC_RATEMCS13:
695 ret_rate = MGN_MCS13;
696 break;
697 case DESC_RATEMCS14:
698 ret_rate = MGN_MCS14;
699 break;
700 case DESC_RATEMCS15:
701 ret_rate = MGN_MCS15;
702 break;
703 case DESC_RATEMCS16:
704 ret_rate = MGN_MCS16;
705 break;
706 case DESC_RATEMCS17:
707 ret_rate = MGN_MCS17;
708 break;
709 case DESC_RATEMCS18:
710 ret_rate = MGN_MCS18;
711 break;
712 case DESC_RATEMCS19:
713 ret_rate = MGN_MCS19;
714 break;
715 case DESC_RATEMCS20:
716 ret_rate = MGN_MCS20;
717 break;
718 case DESC_RATEMCS21:
719 ret_rate = MGN_MCS21;
720 break;
721 case DESC_RATEMCS22:
722 ret_rate = MGN_MCS22;
723 break;
724 case DESC_RATEMCS23:
725 ret_rate = MGN_MCS23;
726 break;
727 case DESC_RATEMCS24:
728 ret_rate = MGN_MCS24;
729 break;
730 case DESC_RATEMCS25:
731 ret_rate = MGN_MCS25;
732 break;
733 case DESC_RATEMCS26:
734 ret_rate = MGN_MCS26;
735 break;
736 case DESC_RATEMCS27:
737 ret_rate = MGN_MCS27;
738 break;
739 case DESC_RATEMCS28:
740 ret_rate = MGN_MCS28;
741 break;
742 case DESC_RATEMCS29:
743 ret_rate = MGN_MCS29;
744 break;
745 case DESC_RATEMCS30:
746 ret_rate = MGN_MCS30;
747 break;
748 case DESC_RATEMCS31:
749 ret_rate = MGN_MCS31;
750 break;
751 case DESC_RATEVHTSS1MCS0:
752 ret_rate = MGN_VHT1SS_MCS0;
753 break;
754 case DESC_RATEVHTSS1MCS1:
755 ret_rate = MGN_VHT1SS_MCS1;
756 break;
757 case DESC_RATEVHTSS1MCS2:
758 ret_rate = MGN_VHT1SS_MCS2;
759 break;
760 case DESC_RATEVHTSS1MCS3:
761 ret_rate = MGN_VHT1SS_MCS3;
762 break;
763 case DESC_RATEVHTSS1MCS4:
764 ret_rate = MGN_VHT1SS_MCS4;
765 break;
766 case DESC_RATEVHTSS1MCS5:
767 ret_rate = MGN_VHT1SS_MCS5;
768 break;
769 case DESC_RATEVHTSS1MCS6:
770 ret_rate = MGN_VHT1SS_MCS6;
771 break;
772 case DESC_RATEVHTSS1MCS7:
773 ret_rate = MGN_VHT1SS_MCS7;
774 break;
775 case DESC_RATEVHTSS1MCS8:
776 ret_rate = MGN_VHT1SS_MCS8;
777 break;
778 case DESC_RATEVHTSS1MCS9:
779 ret_rate = MGN_VHT1SS_MCS9;
780 break;
781 case DESC_RATEVHTSS2MCS0:
782 ret_rate = MGN_VHT2SS_MCS0;
783 break;
784 case DESC_RATEVHTSS2MCS1:
785 ret_rate = MGN_VHT2SS_MCS1;
786 break;
787 case DESC_RATEVHTSS2MCS2:
788 ret_rate = MGN_VHT2SS_MCS2;
789 break;
790 case DESC_RATEVHTSS2MCS3:
791 ret_rate = MGN_VHT2SS_MCS3;
792 break;
793 case DESC_RATEVHTSS2MCS4:
794 ret_rate = MGN_VHT2SS_MCS4;
795 break;
796 case DESC_RATEVHTSS2MCS5:
797 ret_rate = MGN_VHT2SS_MCS5;
798 break;
799 case DESC_RATEVHTSS2MCS6:
800 ret_rate = MGN_VHT2SS_MCS6;
801 break;
802 case DESC_RATEVHTSS2MCS7:
803 ret_rate = MGN_VHT2SS_MCS7;
804 break;
805 case DESC_RATEVHTSS2MCS8:
806 ret_rate = MGN_VHT2SS_MCS8;
807 break;
808 case DESC_RATEVHTSS2MCS9:
809 ret_rate = MGN_VHT2SS_MCS9;
810 break;
811 case DESC_RATEVHTSS3MCS0:
812 ret_rate = MGN_VHT3SS_MCS0;
813 break;
814 case DESC_RATEVHTSS3MCS1:
815 ret_rate = MGN_VHT3SS_MCS1;
816 break;
817 case DESC_RATEVHTSS3MCS2:
818 ret_rate = MGN_VHT3SS_MCS2;
819 break;
820 case DESC_RATEVHTSS3MCS3:
821 ret_rate = MGN_VHT3SS_MCS3;
822 break;
823 case DESC_RATEVHTSS3MCS4:
824 ret_rate = MGN_VHT3SS_MCS4;
825 break;
826 case DESC_RATEVHTSS3MCS5:
827 ret_rate = MGN_VHT3SS_MCS5;
828 break;
829 case DESC_RATEVHTSS3MCS6:
830 ret_rate = MGN_VHT3SS_MCS6;
831 break;
832 case DESC_RATEVHTSS3MCS7:
833 ret_rate = MGN_VHT3SS_MCS7;
834 break;
835 case DESC_RATEVHTSS3MCS8:
836 ret_rate = MGN_VHT3SS_MCS8;
837 break;
838 case DESC_RATEVHTSS3MCS9:
839 ret_rate = MGN_VHT3SS_MCS9;
840 break;
841 case DESC_RATEVHTSS4MCS0:
842 ret_rate = MGN_VHT4SS_MCS0;
843 break;
844 case DESC_RATEVHTSS4MCS1:
845 ret_rate = MGN_VHT4SS_MCS1;
846 break;
847 case DESC_RATEVHTSS4MCS2:
848 ret_rate = MGN_VHT4SS_MCS2;
849 break;
850 case DESC_RATEVHTSS4MCS3:
851 ret_rate = MGN_VHT4SS_MCS3;
852 break;
853 case DESC_RATEVHTSS4MCS4:
854 ret_rate = MGN_VHT4SS_MCS4;
855 break;
856 case DESC_RATEVHTSS4MCS5:
857 ret_rate = MGN_VHT4SS_MCS5;
858 break;
859 case DESC_RATEVHTSS4MCS6:
860 ret_rate = MGN_VHT4SS_MCS6;
861 break;
862 case DESC_RATEVHTSS4MCS7:
863 ret_rate = MGN_VHT4SS_MCS7;
864 break;
865 case DESC_RATEVHTSS4MCS8:
866 ret_rate = MGN_VHT4SS_MCS8;
867 break;
868 case DESC_RATEVHTSS4MCS9:
869 ret_rate = MGN_VHT4SS_MCS9;
870 break;
871
872 default:
873 RTW_INFO("hw_rate_to_m_rate(): Non supported Rate [%x]!!!\n", rate);
874 break;
875 }
876
877 return ret_rate;
878 }
879
HalSetBrateCfg(IN PADAPTER Adapter,IN u8 * mBratesOS,OUT u16 * pBrateCfg)880 void HalSetBrateCfg(
881 IN PADAPTER Adapter,
882 IN u8 *mBratesOS,
883 OUT u16 *pBrateCfg)
884 {
885 u8 i, is_brate, brate;
886
887 for (i = 0; i < NDIS_802_11_LENGTH_RATES_EX; i++) {
888 is_brate = mBratesOS[i] & IEEE80211_BASIC_RATE_MASK;
889 brate = mBratesOS[i] & 0x7f;
890
891 if (is_brate) {
892 switch (brate) {
893 case IEEE80211_CCK_RATE_1MB:
894 *pBrateCfg |= RATE_1M;
895 break;
896 case IEEE80211_CCK_RATE_2MB:
897 *pBrateCfg |= RATE_2M;
898 break;
899 case IEEE80211_CCK_RATE_5MB:
900 *pBrateCfg |= RATE_5_5M;
901 break;
902 case IEEE80211_CCK_RATE_11MB:
903 *pBrateCfg |= RATE_11M;
904 break;
905 case IEEE80211_OFDM_RATE_6MB:
906 *pBrateCfg |= RATE_6M;
907 break;
908 case IEEE80211_OFDM_RATE_9MB:
909 *pBrateCfg |= RATE_9M;
910 break;
911 case IEEE80211_OFDM_RATE_12MB:
912 *pBrateCfg |= RATE_12M;
913 break;
914 case IEEE80211_OFDM_RATE_18MB:
915 *pBrateCfg |= RATE_18M;
916 break;
917 case IEEE80211_OFDM_RATE_24MB:
918 *pBrateCfg |= RATE_24M;
919 break;
920 case IEEE80211_OFDM_RATE_36MB:
921 *pBrateCfg |= RATE_36M;
922 break;
923 case IEEE80211_OFDM_RATE_48MB:
924 *pBrateCfg |= RATE_48M;
925 break;
926 case IEEE80211_OFDM_RATE_54MB:
927 *pBrateCfg |= RATE_54M;
928 break;
929 }
930 }
931 }
932 }
933
934 static VOID
_OneOutPipeMapping(IN PADAPTER pAdapter)935 _OneOutPipeMapping(
936 IN PADAPTER pAdapter
937 )
938 {
939 struct dvobj_priv *pdvobjpriv = adapter_to_dvobj(pAdapter);
940
941 pdvobjpriv->Queue2Pipe[0] = pdvobjpriv->RtOutPipe[0];/* VO */
942 pdvobjpriv->Queue2Pipe[1] = pdvobjpriv->RtOutPipe[0];/* VI */
943 pdvobjpriv->Queue2Pipe[2] = pdvobjpriv->RtOutPipe[0];/* BE */
944 pdvobjpriv->Queue2Pipe[3] = pdvobjpriv->RtOutPipe[0];/* BK */
945
946 pdvobjpriv->Queue2Pipe[4] = pdvobjpriv->RtOutPipe[0];/* BCN */
947 pdvobjpriv->Queue2Pipe[5] = pdvobjpriv->RtOutPipe[0];/* MGT */
948 pdvobjpriv->Queue2Pipe[6] = pdvobjpriv->RtOutPipe[0];/* HIGH */
949 pdvobjpriv->Queue2Pipe[7] = pdvobjpriv->RtOutPipe[0];/* TXCMD */
950 }
951
952 static VOID
_TwoOutPipeMapping(IN PADAPTER pAdapter,IN BOOLEAN bWIFICfg)953 _TwoOutPipeMapping(
954 IN PADAPTER pAdapter,
955 IN BOOLEAN bWIFICfg
956 )
957 {
958 struct dvobj_priv *pdvobjpriv = adapter_to_dvobj(pAdapter);
959
960 if (bWIFICfg) { /* WMM */
961
962 /* BK, BE, VI, VO, BCN, CMD,MGT,HIGH,HCCA */
963 /* { 0, 1, 0, 1, 0, 0, 0, 0, 0 }; */
964 /* 0:ep_0 num, 1:ep_1 num */
965
966 pdvobjpriv->Queue2Pipe[0] = pdvobjpriv->RtOutPipe[1];/* VO */
967 pdvobjpriv->Queue2Pipe[1] = pdvobjpriv->RtOutPipe[0];/* VI */
968 pdvobjpriv->Queue2Pipe[2] = pdvobjpriv->RtOutPipe[1];/* BE */
969 pdvobjpriv->Queue2Pipe[3] = pdvobjpriv->RtOutPipe[0];/* BK */
970
971 pdvobjpriv->Queue2Pipe[4] = pdvobjpriv->RtOutPipe[0];/* BCN */
972 pdvobjpriv->Queue2Pipe[5] = pdvobjpriv->RtOutPipe[0];/* MGT */
973 pdvobjpriv->Queue2Pipe[6] = pdvobjpriv->RtOutPipe[0];/* HIGH */
974 pdvobjpriv->Queue2Pipe[7] = pdvobjpriv->RtOutPipe[0];/* TXCMD */
975
976 } else { /* typical setting */
977
978
979 /* BK, BE, VI, VO, BCN, CMD,MGT,HIGH,HCCA */
980 /* { 1, 1, 0, 0, 0, 0, 0, 0, 0 }; */
981 /* 0:ep_0 num, 1:ep_1 num */
982
983 pdvobjpriv->Queue2Pipe[0] = pdvobjpriv->RtOutPipe[0];/* VO */
984 pdvobjpriv->Queue2Pipe[1] = pdvobjpriv->RtOutPipe[0];/* VI */
985 pdvobjpriv->Queue2Pipe[2] = pdvobjpriv->RtOutPipe[1];/* BE */
986 pdvobjpriv->Queue2Pipe[3] = pdvobjpriv->RtOutPipe[1];/* BK */
987
988 pdvobjpriv->Queue2Pipe[4] = pdvobjpriv->RtOutPipe[0];/* BCN */
989 pdvobjpriv->Queue2Pipe[5] = pdvobjpriv->RtOutPipe[0];/* MGT */
990 pdvobjpriv->Queue2Pipe[6] = pdvobjpriv->RtOutPipe[0];/* HIGH */
991 pdvobjpriv->Queue2Pipe[7] = pdvobjpriv->RtOutPipe[0];/* TXCMD */
992
993 }
994
995 }
996
_ThreeOutPipeMapping(IN PADAPTER pAdapter,IN BOOLEAN bWIFICfg)997 static VOID _ThreeOutPipeMapping(
998 IN PADAPTER pAdapter,
999 IN BOOLEAN bWIFICfg
1000 )
1001 {
1002 struct dvobj_priv *pdvobjpriv = adapter_to_dvobj(pAdapter);
1003
1004 if (bWIFICfg) { /* for WMM */
1005
1006 /* BK, BE, VI, VO, BCN, CMD,MGT,HIGH,HCCA */
1007 /* { 1, 2, 1, 0, 0, 0, 0, 0, 0 }; */
1008 /* 0:H, 1:N, 2:L */
1009
1010 pdvobjpriv->Queue2Pipe[0] = pdvobjpriv->RtOutPipe[0];/* VO */
1011 pdvobjpriv->Queue2Pipe[1] = pdvobjpriv->RtOutPipe[1];/* VI */
1012 pdvobjpriv->Queue2Pipe[2] = pdvobjpriv->RtOutPipe[2];/* BE */
1013 pdvobjpriv->Queue2Pipe[3] = pdvobjpriv->RtOutPipe[1];/* BK */
1014
1015 pdvobjpriv->Queue2Pipe[4] = pdvobjpriv->RtOutPipe[0];/* BCN */
1016 pdvobjpriv->Queue2Pipe[5] = pdvobjpriv->RtOutPipe[0];/* MGT */
1017 pdvobjpriv->Queue2Pipe[6] = pdvobjpriv->RtOutPipe[0];/* HIGH */
1018 pdvobjpriv->Queue2Pipe[7] = pdvobjpriv->RtOutPipe[0];/* TXCMD */
1019
1020 } else { /* typical setting */
1021
1022
1023 /* BK, BE, VI, VO, BCN, CMD,MGT,HIGH,HCCA */
1024 /* { 2, 2, 1, 0, 0, 0, 0, 0, 0 }; */
1025 /* 0:H, 1:N, 2:L */
1026
1027 pdvobjpriv->Queue2Pipe[0] = pdvobjpriv->RtOutPipe[0];/* VO */
1028 pdvobjpriv->Queue2Pipe[1] = pdvobjpriv->RtOutPipe[1];/* VI */
1029 pdvobjpriv->Queue2Pipe[2] = pdvobjpriv->RtOutPipe[2];/* BE */
1030 pdvobjpriv->Queue2Pipe[3] = pdvobjpriv->RtOutPipe[2];/* BK */
1031
1032 pdvobjpriv->Queue2Pipe[4] = pdvobjpriv->RtOutPipe[0];/* BCN */
1033 pdvobjpriv->Queue2Pipe[5] = pdvobjpriv->RtOutPipe[0];/* MGT */
1034 pdvobjpriv->Queue2Pipe[6] = pdvobjpriv->RtOutPipe[0];/* HIGH */
1035 pdvobjpriv->Queue2Pipe[7] = pdvobjpriv->RtOutPipe[0];/* TXCMD */
1036 }
1037
1038 }
_FourOutPipeMapping(IN PADAPTER pAdapter,IN BOOLEAN bWIFICfg)1039 static VOID _FourOutPipeMapping(
1040 IN PADAPTER pAdapter,
1041 IN BOOLEAN bWIFICfg
1042 )
1043 {
1044 struct dvobj_priv *pdvobjpriv = adapter_to_dvobj(pAdapter);
1045
1046 if (bWIFICfg) { /* for WMM */
1047
1048 /* BK, BE, VI, VO, BCN, CMD,MGT,HIGH,HCCA */
1049 /* { 1, 2, 1, 0, 0, 0, 0, 0, 0 }; */
1050 /* 0:H, 1:N, 2:L ,3:E */
1051
1052 pdvobjpriv->Queue2Pipe[0] = pdvobjpriv->RtOutPipe[0];/* VO */
1053 pdvobjpriv->Queue2Pipe[1] = pdvobjpriv->RtOutPipe[1];/* VI */
1054 pdvobjpriv->Queue2Pipe[2] = pdvobjpriv->RtOutPipe[2];/* BE */
1055 pdvobjpriv->Queue2Pipe[3] = pdvobjpriv->RtOutPipe[1];/* BK */
1056
1057 pdvobjpriv->Queue2Pipe[4] = pdvobjpriv->RtOutPipe[0];/* BCN */
1058 pdvobjpriv->Queue2Pipe[5] = pdvobjpriv->RtOutPipe[0];/* MGT */
1059 pdvobjpriv->Queue2Pipe[6] = pdvobjpriv->RtOutPipe[3];/* HIGH */
1060 pdvobjpriv->Queue2Pipe[7] = pdvobjpriv->RtOutPipe[0];/* TXCMD */
1061
1062 } else { /* typical setting */
1063
1064
1065 /* BK, BE, VI, VO, BCN, CMD,MGT,HIGH,HCCA */
1066 /* { 2, 2, 1, 0, 0, 0, 0, 0, 0 }; */
1067 /* 0:H, 1:N, 2:L */
1068
1069 pdvobjpriv->Queue2Pipe[0] = pdvobjpriv->RtOutPipe[0];/* VO */
1070 pdvobjpriv->Queue2Pipe[1] = pdvobjpriv->RtOutPipe[1];/* VI */
1071 pdvobjpriv->Queue2Pipe[2] = pdvobjpriv->RtOutPipe[2];/* BE */
1072 pdvobjpriv->Queue2Pipe[3] = pdvobjpriv->RtOutPipe[2];/* BK */
1073
1074 pdvobjpriv->Queue2Pipe[4] = pdvobjpriv->RtOutPipe[0];/* BCN */
1075 pdvobjpriv->Queue2Pipe[5] = pdvobjpriv->RtOutPipe[0];/* MGT */
1076 pdvobjpriv->Queue2Pipe[6] = pdvobjpriv->RtOutPipe[3];/* HIGH */
1077 pdvobjpriv->Queue2Pipe[7] = pdvobjpriv->RtOutPipe[0];/* TXCMD */
1078 }
1079
1080 }
1081 BOOLEAN
Hal_MappingOutPipe(IN PADAPTER pAdapter,IN u8 NumOutPipe)1082 Hal_MappingOutPipe(
1083 IN PADAPTER pAdapter,
1084 IN u8 NumOutPipe
1085 )
1086 {
1087 struct registry_priv *pregistrypriv = &pAdapter->registrypriv;
1088
1089 BOOLEAN bWIFICfg = (pregistrypriv->wifi_spec) ? _TRUE : _FALSE;
1090
1091 BOOLEAN result = _TRUE;
1092
1093 switch (NumOutPipe) {
1094 case 2:
1095 _TwoOutPipeMapping(pAdapter, bWIFICfg);
1096 break;
1097 case 3:
1098 case 4:
1099 _ThreeOutPipeMapping(pAdapter, bWIFICfg);
1100 break;
1101 case 1:
1102 _OneOutPipeMapping(pAdapter);
1103 break;
1104 default:
1105 result = _FALSE;
1106 break;
1107 }
1108
1109 return result;
1110
1111 }
1112
rtw_hal_reqtxrpt(_adapter * padapter,u8 macid)1113 void rtw_hal_reqtxrpt(_adapter *padapter, u8 macid)
1114 {
1115 if (padapter->hal_func.reqtxrpt)
1116 padapter->hal_func.reqtxrpt(padapter, macid);
1117 }
1118
rtw_hal_dump_macaddr(void * sel,_adapter * adapter)1119 void rtw_hal_dump_macaddr(void *sel, _adapter *adapter)
1120 {
1121 int i;
1122 _adapter *iface;
1123 struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
1124 u8 mac_addr[ETH_ALEN];
1125
1126 #ifdef CONFIG_MI_WITH_MBSSID_CAM
1127 rtw_mbid_cam_dump(sel, __func__, adapter);
1128 #else
1129 for (i = 0; i < dvobj->iface_nums; i++) {
1130 iface = dvobj->padapters[i];
1131 if (iface) {
1132 rtw_hal_get_hwreg(iface, HW_VAR_MAC_ADDR, mac_addr);
1133 RTW_PRINT_SEL(sel, ADPT_FMT"- hw port(%d) mac_addr ="MAC_FMT"\n",
1134 ADPT_ARG(iface), iface->hw_port, MAC_ARG(mac_addr));
1135 }
1136 }
1137 #endif
1138 }
1139
1140 #ifdef RTW_HALMAC
rtw_hal_hw_port_enable(_adapter * adapter)1141 void rtw_hal_hw_port_enable(_adapter *adapter)
1142 {
1143 #if 1
1144 u8 port_enable = _TRUE;
1145
1146 rtw_hal_set_hwreg(adapter, HW_VAR_PORT_CFG, &port_enable);
1147 #else
1148 struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
1149 struct rtw_halmac_bcn_ctrl bcn_ctrl;
1150
1151 _rtw_memset(&bcn_ctrl, 0, sizeof(struct rtw_halmac_bcn_ctrl));
1152 bcn_ctrl.enable_bcn = 1;
1153
1154 /*rtw_halmac_get_bcn_ctrl(struct dvobj_priv *d, enum _hw_port hwport,
1155 struct rtw_halmac_bcn_ctrl *bcn_ctrl)*/
1156 if (rtw_halmac_set_bcn_ctrl(dvobj, get_hw_port(adapter), &bcn_ctrl) == -1) {
1157 RTW_ERR(ADPT_FMT" - hw port(%d) enable fail!!\n", ADPT_ARG(adapter), get_hw_port(adapter));
1158 rtw_warn_on(1);
1159 }
1160 #endif
1161 }
rtw_hal_hw_port_disable(_adapter * adapter)1162 void rtw_hal_hw_port_disable(_adapter *adapter)
1163 {
1164 u8 port_enable = _FALSE;
1165
1166 rtw_hal_set_hwreg(adapter, HW_VAR_PORT_CFG, &port_enable);
1167 }
1168
rtw_restore_hw_port_cfg(_adapter * adapter)1169 void rtw_restore_hw_port_cfg(_adapter *adapter)
1170 {
1171 #ifdef CONFIG_MI_WITH_MBSSID_CAM
1172
1173 #else
1174 int i;
1175 _adapter *iface;
1176 struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
1177
1178 for (i = 0; i < dvobj->iface_nums; i++) {
1179 iface = dvobj->padapters[i];
1180 if (iface)
1181 rtw_hal_hw_port_enable(iface);
1182 }
1183 #endif
1184 }
1185 #endif
1186
rtw_restore_mac_addr(_adapter * adapter)1187 void rtw_restore_mac_addr(_adapter *adapter)
1188 {
1189 #ifdef CONFIG_MI_WITH_MBSSID_CAM
1190 _adapter *iface;
1191 struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
1192
1193 rtw_mbid_cam_restore(adapter);
1194 #else
1195 int i;
1196 _adapter *iface;
1197 struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
1198
1199 for (i = 0; i < dvobj->iface_nums; i++) {
1200 iface = dvobj->padapters[i];
1201 if (iface)
1202 rtw_hal_set_hwreg(iface, HW_VAR_MAC_ADDR, adapter_mac_addr(iface));
1203 }
1204 #endif
1205 if (1)
1206 rtw_hal_dump_macaddr(RTW_DBGDUMP, adapter);
1207 }
1208
rtw_init_hal_com_default_value(PADAPTER Adapter)1209 void rtw_init_hal_com_default_value(PADAPTER Adapter)
1210 {
1211 PHAL_DATA_TYPE pHalData = GET_HAL_DATA(Adapter);
1212 struct registry_priv *regsty = adapter_to_regsty(Adapter);
1213
1214 pHalData->AntDetection = 1;
1215 pHalData->antenna_test = _FALSE;
1216 pHalData->RegIQKFWOffload = regsty->iqk_fw_offload;
1217 }
1218
1219 #ifdef CONFIG_FW_C2H_REG
c2h_evt_clear(_adapter * adapter)1220 void c2h_evt_clear(_adapter *adapter)
1221 {
1222 rtw_write8(adapter, REG_C2HEVT_CLEAR, C2H_EVT_HOST_CLOSE);
1223 }
1224
c2h_evt_read_88xx(_adapter * adapter,u8 * buf)1225 s32 c2h_evt_read_88xx(_adapter *adapter, u8 *buf)
1226 {
1227 s32 ret = _FAIL;
1228 int i;
1229 u8 trigger;
1230
1231 if (buf == NULL)
1232 goto exit;
1233
1234 trigger = rtw_read8(adapter, REG_C2HEVT_CLEAR);
1235
1236 if (trigger == C2H_EVT_HOST_CLOSE) {
1237 goto exit; /* Not ready */
1238 } else if (trigger != C2H_EVT_FW_CLOSE) {
1239 goto clear_evt; /* Not a valid value */
1240 }
1241
1242 _rtw_memset(buf, 0, C2H_REG_LEN);
1243
1244 /* Read ID, LEN, SEQ */
1245 SET_C2H_ID_88XX(buf, rtw_read8(adapter, REG_C2HEVT_MSG_NORMAL));
1246 SET_C2H_SEQ_88XX(buf, rtw_read8(adapter, REG_C2HEVT_CMD_SEQ_88XX));
1247 SET_C2H_PLEN_88XX(buf, rtw_read8(adapter, REG_C2HEVT_CMD_LEN_88XX));
1248
1249 if (0) {
1250 RTW_INFO("%s id=0x%02x, seq=%u, plen=%u, trigger=0x%02x\n", __func__
1251 , C2H_ID_88XX(buf), C2H_SEQ_88XX(buf), C2H_PLEN_88XX(buf), trigger);
1252 }
1253
1254 /* Read the content */
1255 for (i = 0; i < C2H_PLEN_88XX(buf); i++)
1256 *(C2H_PAYLOAD_88XX(buf) + i) = rtw_read8(adapter, REG_C2HEVT_MSG_NORMAL + 2 + i);
1257
1258 RTW_DBG_DUMP("payload:\n", C2H_PAYLOAD_88XX(buf), C2H_PLEN_88XX(buf));
1259
1260 ret = _SUCCESS;
1261
1262 clear_evt:
1263 /*
1264 * Clear event to notify FW we have read the command.
1265 * If this field isn't clear, the FW won't update the next command message.
1266 */
1267 c2h_evt_clear(adapter);
1268
1269 exit:
1270 return ret;
1271 }
1272 #endif /* CONFIG_FW_C2H_REG */
1273
1274 #ifdef CONFIG_FW_C2H_PKT
1275 #ifndef DBG_C2H_PKT_PRE_HDL
1276 #define DBG_C2H_PKT_PRE_HDL 0
1277 #endif
1278 #ifndef DBG_C2H_PKT_HDL
1279 #define DBG_C2H_PKT_HDL 0
1280 #endif
rtw_hal_c2h_pkt_pre_hdl(_adapter * adapter,u8 * buf,u16 len)1281 void rtw_hal_c2h_pkt_pre_hdl(_adapter *adapter, u8 *buf, u16 len)
1282 {
1283 #ifdef RTW_HALMAC
1284 /* TODO: extract hal_mac IC's code here*/
1285 #else
1286 u8 parse_fail = 0;
1287 u8 hdl_here = 0;
1288 s32 ret = _FAIL;
1289 u8 id, seq, plen;
1290 u8 *payload;
1291
1292 if (rtw_hal_c2h_pkt_hdr_parse(adapter, buf, len, &id, &seq, &plen, &payload) != _SUCCESS) {
1293 parse_fail = 1;
1294 goto exit;
1295 }
1296
1297 hdl_here = rtw_hal_c2h_id_handle_directly(adapter, id, seq, plen, payload) == _TRUE ? 1 : 0;
1298 if (hdl_here)
1299 ret = rtw_hal_c2h_handler(adapter, id, seq, plen, payload);
1300 else
1301 ret = rtw_c2h_packet_wk_cmd(adapter, buf, len);
1302
1303 exit:
1304 if (parse_fail)
1305 RTW_ERR("%s parse fail, buf=%p, len=:%u\n", __func__, buf, len);
1306 else if (ret != _SUCCESS || DBG_C2H_PKT_PRE_HDL > 0) {
1307 RTW_PRINT("%s: id=0x%02x, seq=%u, plen=%u, %s %s\n", __func__, id, seq, plen
1308 , hdl_here ? "handle" : "enqueue"
1309 , ret == _SUCCESS ? "ok" : "fail"
1310 );
1311 if (DBG_C2H_PKT_PRE_HDL >= 2)
1312 RTW_PRINT_DUMP("dump: ", buf, len);
1313 }
1314 #endif
1315 }
1316
rtw_hal_c2h_pkt_hdl(_adapter * adapter,u8 * buf,u16 len)1317 void rtw_hal_c2h_pkt_hdl(_adapter *adapter, u8 *buf, u16 len)
1318 {
1319 #ifdef RTW_HALMAC
1320 adapter->hal_func.hal_mac_c2h_handler(adapter, buf, len);
1321 #else
1322 u8 parse_fail = 0;
1323 u8 bypass = 0;
1324 s32 ret = _FAIL;
1325 u8 id, seq, plen;
1326 u8 *payload;
1327
1328 if (rtw_hal_c2h_pkt_hdr_parse(adapter, buf, len, &id, &seq, &plen, &payload) != _SUCCESS) {
1329 parse_fail = 1;
1330 goto exit;
1331 }
1332
1333 #ifdef CONFIG_WOWLAN
1334 if (adapter_to_pwrctl(adapter)->wowlan_mode == _TRUE) {
1335 bypass = 1;
1336 ret = _SUCCESS;
1337 goto exit;
1338 }
1339 #endif
1340
1341 ret = rtw_hal_c2h_handler(adapter, id, seq, plen, payload);
1342
1343 exit:
1344 if (parse_fail)
1345 RTW_ERR("%s parse fail, buf=%p, len=:%u\n", __func__, buf, len);
1346 else if (ret != _SUCCESS || bypass || DBG_C2H_PKT_HDL > 0) {
1347 RTW_PRINT("%s: id=0x%02x, seq=%u, plen=%u, %s %s\n", __func__, id, seq, plen
1348 , !bypass ? "handle" : "bypass"
1349 , ret == _SUCCESS ? "ok" : "fail"
1350 );
1351 if (DBG_C2H_PKT_HDL >= 2)
1352 RTW_PRINT_DUMP("dump: ", buf, len);
1353 }
1354 #endif
1355 }
1356 #endif /* CONFIG_FW_C2H_PKT */
1357
c2h_iqk_offload(_adapter * adapter,u8 * data,u8 len)1358 void c2h_iqk_offload(_adapter *adapter, u8 *data, u8 len)
1359 {
1360 HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
1361 struct submit_ctx *iqk_sctx = &hal_data->iqk_sctx;
1362
1363 RTW_INFO("IQK offload finish in %dms\n", rtw_get_passing_time_ms(iqk_sctx->submit_time));
1364 if (0)
1365 RTW_INFO_DUMP("C2H_IQK_FINISH: ", data, len);
1366
1367 rtw_sctx_done(&iqk_sctx);
1368 }
1369
c2h_iqk_offload_wait(_adapter * adapter,u32 timeout_ms)1370 int c2h_iqk_offload_wait(_adapter *adapter, u32 timeout_ms)
1371 {
1372 HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
1373 struct submit_ctx *iqk_sctx = &hal_data->iqk_sctx;
1374
1375 iqk_sctx->submit_time = rtw_get_current_time();
1376 iqk_sctx->timeout_ms = timeout_ms;
1377 iqk_sctx->status = RTW_SCTX_SUBMITTED;
1378
1379 return rtw_sctx_wait(iqk_sctx, __func__);
1380 }
1381
1382 #define GET_C2H_MAC_HIDDEN_RPT_UUID_X(_data) LE_BITS_TO_1BYTE(((u8 *)(_data)) + 0, 0, 8)
1383 #define GET_C2H_MAC_HIDDEN_RPT_UUID_Y(_data) LE_BITS_TO_1BYTE(((u8 *)(_data)) + 1, 0, 8)
1384 #define GET_C2H_MAC_HIDDEN_RPT_UUID_Z(_data) LE_BITS_TO_1BYTE(((u8 *)(_data)) + 2, 0, 5)
1385 #define GET_C2H_MAC_HIDDEN_RPT_UUID_CRC(_data) LE_BITS_TO_2BYTE(((u8 *)(_data)) + 2, 5, 11)
1386 #define GET_C2H_MAC_HIDDEN_RPT_HCI_TYPE(_data) LE_BITS_TO_1BYTE(((u8 *)(_data)) + 4, 0, 4)
1387 #define GET_C2H_MAC_HIDDEN_RPT_PACKAGE_TYPE(_data) LE_BITS_TO_1BYTE(((u8 *)(_data)) + 4, 4, 3)
1388 #define GET_C2H_MAC_HIDDEN_RPT_TR_SWITCH(_data) LE_BITS_TO_1BYTE(((u8 *)(_data)) + 4, 7, 1)
1389 #define GET_C2H_MAC_HIDDEN_RPT_WL_FUNC(_data) LE_BITS_TO_1BYTE(((u8 *)(_data)) + 5, 0, 4)
1390 #define GET_C2H_MAC_HIDDEN_RPT_HW_STYPE(_data) LE_BITS_TO_1BYTE(((u8 *)(_data)) + 5, 4, 4)
1391 #define GET_C2H_MAC_HIDDEN_RPT_BW(_data) LE_BITS_TO_1BYTE(((u8 *)(_data)) + 6, 0, 3)
1392 #define GET_C2H_MAC_HIDDEN_RPT_ANT_NUM(_data) LE_BITS_TO_1BYTE(((u8 *)(_data)) + 6, 5, 3)
1393 #define GET_C2H_MAC_HIDDEN_RPT_80211_PROTOCOL(_data) LE_BITS_TO_1BYTE(((u8 *)(_data)) + 7, 2, 2)
1394 #define GET_C2H_MAC_HIDDEN_RPT_NIC_ROUTER(_data) LE_BITS_TO_1BYTE(((u8 *)(_data)) + 7, 6, 2)
1395
1396 #ifndef DBG_C2H_MAC_HIDDEN_RPT_HANDLE
1397 #define DBG_C2H_MAC_HIDDEN_RPT_HANDLE 0
1398 #endif
1399
1400 #ifdef CONFIG_RTW_MAC_HIDDEN_RPT
c2h_mac_hidden_rpt_hdl(_adapter * adapter,u8 * data,u8 len)1401 int c2h_mac_hidden_rpt_hdl(_adapter *adapter, u8 *data, u8 len)
1402 {
1403 HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
1404 struct hal_spec_t *hal_spec = GET_HAL_SPEC(adapter);
1405 int ret = _FAIL;
1406
1407 u32 uuid;
1408 u8 uuid_x;
1409 u8 uuid_y;
1410 u8 uuid_z;
1411 u16 uuid_crc;
1412
1413 u8 hci_type;
1414 u8 package_type;
1415 u8 tr_switch;
1416 u8 wl_func;
1417 u8 hw_stype;
1418 u8 bw;
1419 u8 ant_num;
1420 u8 protocol;
1421 u8 nic;
1422
1423 int i;
1424
1425 if (len < MAC_HIDDEN_RPT_LEN) {
1426 RTW_WARN("%s len(%u) < %d\n", __func__, len, MAC_HIDDEN_RPT_LEN);
1427 goto exit;
1428 }
1429
1430 uuid_x = GET_C2H_MAC_HIDDEN_RPT_UUID_X(data);
1431 uuid_y = GET_C2H_MAC_HIDDEN_RPT_UUID_Y(data);
1432 uuid_z = GET_C2H_MAC_HIDDEN_RPT_UUID_Z(data);
1433 uuid_crc = GET_C2H_MAC_HIDDEN_RPT_UUID_CRC(data);
1434
1435 hci_type = GET_C2H_MAC_HIDDEN_RPT_HCI_TYPE(data);
1436 package_type = GET_C2H_MAC_HIDDEN_RPT_PACKAGE_TYPE(data);
1437
1438 tr_switch = GET_C2H_MAC_HIDDEN_RPT_TR_SWITCH(data);
1439
1440 wl_func = GET_C2H_MAC_HIDDEN_RPT_WL_FUNC(data);
1441 hw_stype = GET_C2H_MAC_HIDDEN_RPT_HW_STYPE(data);
1442
1443 bw = GET_C2H_MAC_HIDDEN_RPT_BW(data);
1444 ant_num = GET_C2H_MAC_HIDDEN_RPT_ANT_NUM(data);
1445
1446 protocol = GET_C2H_MAC_HIDDEN_RPT_80211_PROTOCOL(data);
1447 nic = GET_C2H_MAC_HIDDEN_RPT_NIC_ROUTER(data);
1448
1449 if (DBG_C2H_MAC_HIDDEN_RPT_HANDLE) {
1450 for (i = 0; i < len; i++)
1451 RTW_PRINT("%s: 0x%02X\n", __func__, *(data + i));
1452
1453 RTW_PRINT("uuid x:0x%02x y:0x%02x z:0x%x crc:0x%x\n", uuid_x, uuid_y, uuid_z, uuid_crc);
1454 RTW_PRINT("hci_type:0x%x\n", hci_type);
1455 RTW_PRINT("package_type:0x%x\n", package_type);
1456 RTW_PRINT("tr_switch:0x%x\n", tr_switch);
1457 RTW_PRINT("wl_func:0x%x\n", wl_func);
1458 RTW_PRINT("hw_stype:0x%x\n", hw_stype);
1459 RTW_PRINT("bw:0x%x\n", bw);
1460 RTW_PRINT("ant_num:0x%x\n", ant_num);
1461 RTW_PRINT("protocol:0x%x\n", protocol);
1462 RTW_PRINT("nic:0x%x\n", nic);
1463 }
1464
1465 /*
1466 * NOTICE:
1467 * for now, the following is common info/format
1468 * if there is any hal difference need to export
1469 * some IC dependent code will need to be implement
1470 */
1471 hal_data->PackageType = package_type;
1472 hal_spec->wl_func &= mac_hidden_wl_func_to_hal_wl_func(wl_func);
1473 hal_spec->bw_cap &= mac_hidden_max_bw_to_hal_bw_cap(bw);
1474 hal_spec->tx_nss_num = rtw_min(hal_spec->tx_nss_num, ant_num);
1475 hal_spec->rx_nss_num = rtw_min(hal_spec->rx_nss_num, ant_num);
1476 hal_spec->proto_cap &= mac_hidden_proto_to_hal_proto_cap(protocol);
1477 hal_spec->hci_type = hci_type;
1478
1479 /* TODO: tr_switch */
1480
1481 ret = _SUCCESS;
1482
1483 exit:
1484 return ret;
1485 }
1486
c2h_mac_hidden_rpt_2_hdl(_adapter * adapter,u8 * data,u8 len)1487 int c2h_mac_hidden_rpt_2_hdl(_adapter *adapter, u8 *data, u8 len)
1488 {
1489 HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
1490 struct hal_spec_t *hal_spec = GET_HAL_SPEC(adapter);
1491 int ret = _FAIL;
1492
1493 int i;
1494
1495 if (len < MAC_HIDDEN_RPT_2_LEN) {
1496 RTW_WARN("%s len(%u) < %d\n", __func__, len, MAC_HIDDEN_RPT_2_LEN);
1497 goto exit;
1498 }
1499
1500 if (DBG_C2H_MAC_HIDDEN_RPT_HANDLE) {
1501 for (i = 0; i < len; i++)
1502 RTW_PRINT("%s: 0x%02X\n", __func__, *(data + i));
1503 }
1504
1505 #ifdef CONFIG_RTL8188F
1506 if (IS_8188F(hal_data->version_id)) {
1507 #define GET_C2H_MAC_HIDDEN_RPT_IRV(_data) LE_BITS_TO_1BYTE(((u8 *)(_data)) + 0, 0, 4)
1508 u8 irv = GET_C2H_MAC_HIDDEN_RPT_IRV(data);
1509
1510 if (DBG_C2H_MAC_HIDDEN_RPT_HANDLE)
1511 RTW_PRINT("irv:0x%x\n", irv);
1512
1513 if(irv != 0xf)
1514 hal_data->version_id.CUTVersion = irv;
1515 }
1516 #endif
1517
1518 ret = _SUCCESS;
1519
1520 exit:
1521 return ret;
1522 }
1523
hal_read_mac_hidden_rpt(_adapter * adapter)1524 int hal_read_mac_hidden_rpt(_adapter *adapter)
1525 {
1526 HAL_DATA_TYPE *pHalData = GET_HAL_DATA(adapter);
1527 int ret = _FAIL;
1528 int ret_fwdl;
1529 u8 mac_hidden_rpt[MAC_HIDDEN_RPT_LEN + MAC_HIDDEN_RPT_2_LEN] = {0};
1530 systime start = rtw_get_current_time();
1531 u32 cnt = 0;
1532 u32 timeout_ms = 800;
1533 u32 min_cnt = 10;
1534 u8 id = C2H_DEFEATURE_RSVD;
1535 int i;
1536
1537 #if defined(CONFIG_USB_HCI) || defined(CONFIG_PCI_HCI)
1538 u8 hci_type = rtw_get_intf_type(adapter);
1539
1540 if ((hci_type == RTW_USB || hci_type == RTW_PCIE)
1541 && !rtw_is_hw_init_completed(adapter))
1542 rtw_hal_power_on(adapter);
1543 #endif
1544
1545 /* inform FW mac hidden rpt from reg is needed */
1546 rtw_write8(adapter, REG_C2HEVT_MSG_NORMAL, C2H_DEFEATURE_RSVD);
1547
1548 /* download FW */
1549 pHalData->not_xmitframe_fw_dl = 1;
1550 ret_fwdl = rtw_hal_fw_dl(adapter, _FALSE);
1551 pHalData->not_xmitframe_fw_dl = 0;
1552 if (ret_fwdl != _SUCCESS)
1553 goto mac_hidden_rpt_hdl;
1554
1555 /* polling for data ready */
1556 start = rtw_get_current_time();
1557 do {
1558 cnt++;
1559 id = rtw_read8(adapter, REG_C2HEVT_MSG_NORMAL);
1560 if (id == C2H_MAC_HIDDEN_RPT || RTW_CANNOT_IO(adapter))
1561 break;
1562 rtw_msleep_os(10);
1563 } while (rtw_get_passing_time_ms(start) < timeout_ms || cnt < min_cnt);
1564
1565 if (id == C2H_MAC_HIDDEN_RPT) {
1566 /* read data */
1567 for (i = 0; i < MAC_HIDDEN_RPT_LEN + MAC_HIDDEN_RPT_2_LEN; i++)
1568 mac_hidden_rpt[i] = rtw_read8(adapter, REG_C2HEVT_MSG_NORMAL + 2 + i);
1569 }
1570
1571 /* inform FW mac hidden rpt has read */
1572 rtw_write8(adapter, REG_C2HEVT_MSG_NORMAL, C2H_DBG);
1573
1574 mac_hidden_rpt_hdl:
1575 c2h_mac_hidden_rpt_hdl(adapter, mac_hidden_rpt, MAC_HIDDEN_RPT_LEN);
1576 c2h_mac_hidden_rpt_2_hdl(adapter, mac_hidden_rpt + MAC_HIDDEN_RPT_LEN, MAC_HIDDEN_RPT_2_LEN);
1577
1578 if (ret_fwdl == _SUCCESS && id == C2H_MAC_HIDDEN_RPT)
1579 ret = _SUCCESS;
1580
1581 exit:
1582
1583 #if defined(CONFIG_USB_HCI) || defined(CONFIG_PCI_HCI)
1584 if ((hci_type == RTW_USB || hci_type == RTW_PCIE)
1585 && !rtw_is_hw_init_completed(adapter))
1586 rtw_hal_power_off(adapter);
1587 #endif
1588
1589 RTW_INFO("%s %s! (%u, %dms), fwdl:%d, id:0x%02x\n", __func__
1590 , (ret == _SUCCESS) ? "OK" : "Fail", cnt, rtw_get_passing_time_ms(start), ret_fwdl, id);
1591
1592 return ret;
1593 }
1594 #endif /* CONFIG_RTW_MAC_HIDDEN_RPT */
1595
c2h_defeature_dbg_hdl(_adapter * adapter,u8 * data,u8 len)1596 int c2h_defeature_dbg_hdl(_adapter *adapter, u8 *data, u8 len)
1597 {
1598 HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
1599 struct hal_spec_t *hal_spec = GET_HAL_SPEC(adapter);
1600 int ret = _FAIL;
1601
1602 int i;
1603
1604 if (len < DEFEATURE_DBG_LEN) {
1605 RTW_WARN("%s len(%u) < %d\n", __func__, len, DEFEATURE_DBG_LEN);
1606 goto exit;
1607 }
1608
1609 for (i = 0; i < len; i++)
1610 RTW_PRINT("%s: 0x%02X\n", __func__, *(data + i));
1611
1612 ret = _SUCCESS;
1613
1614 exit:
1615 return ret;
1616 }
1617
1618 #ifndef DBG_CUSTOMER_STR_RPT_HANDLE
1619 #define DBG_CUSTOMER_STR_RPT_HANDLE 0
1620 #endif
1621
1622 #ifdef CONFIG_RTW_CUSTOMER_STR
rtw_hal_h2c_customer_str_req(_adapter * adapter)1623 s32 rtw_hal_h2c_customer_str_req(_adapter *adapter)
1624 {
1625 u8 h2c_data[H2C_CUSTOMER_STR_REQ_LEN] = {0};
1626
1627 SET_H2CCMD_CUSTOMER_STR_REQ_EN(h2c_data, 1);
1628 return rtw_hal_fill_h2c_cmd(adapter, H2C_CUSTOMER_STR_REQ, H2C_CUSTOMER_STR_REQ_LEN, h2c_data);
1629 }
1630
1631 #define C2H_CUSTOMER_STR_RPT_BYTE0(_data) ((u8 *)(_data))
1632 #define C2H_CUSTOMER_STR_RPT_2_BYTE8(_data) ((u8 *)(_data))
1633
c2h_customer_str_rpt_hdl(_adapter * adapter,u8 * data,u8 len)1634 int c2h_customer_str_rpt_hdl(_adapter *adapter, u8 *data, u8 len)
1635 {
1636 struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
1637 int ret = _FAIL;
1638 int i;
1639
1640 if (len < CUSTOMER_STR_RPT_LEN) {
1641 RTW_WARN("%s len(%u) < %d\n", __func__, len, CUSTOMER_STR_RPT_LEN);
1642 goto exit;
1643 }
1644
1645 if (DBG_CUSTOMER_STR_RPT_HANDLE)
1646 RTW_PRINT_DUMP("customer_str_rpt: ", data, CUSTOMER_STR_RPT_LEN);
1647
1648 _enter_critical_mutex(&dvobj->customer_str_mutex, NULL);
1649
1650 if (dvobj->customer_str_sctx != NULL) {
1651 if (dvobj->customer_str_sctx->status != RTW_SCTX_SUBMITTED)
1652 RTW_WARN("%s invalid sctx.status:%d\n", __func__, dvobj->customer_str_sctx->status);
1653 _rtw_memcpy(dvobj->customer_str, C2H_CUSTOMER_STR_RPT_BYTE0(data), CUSTOMER_STR_RPT_LEN);
1654 dvobj->customer_str_sctx->status = RTX_SCTX_CSTR_WAIT_RPT2;
1655 } else
1656 RTW_WARN("%s sctx not set\n", __func__);
1657
1658 _exit_critical_mutex(&dvobj->customer_str_mutex, NULL);
1659
1660 ret = _SUCCESS;
1661
1662 exit:
1663 return ret;
1664 }
1665
c2h_customer_str_rpt_2_hdl(_adapter * adapter,u8 * data,u8 len)1666 int c2h_customer_str_rpt_2_hdl(_adapter *adapter, u8 *data, u8 len)
1667 {
1668 struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
1669 int ret = _FAIL;
1670 int i;
1671
1672 if (len < CUSTOMER_STR_RPT_2_LEN) {
1673 RTW_WARN("%s len(%u) < %d\n", __func__, len, CUSTOMER_STR_RPT_2_LEN);
1674 goto exit;
1675 }
1676
1677 if (DBG_CUSTOMER_STR_RPT_HANDLE)
1678 RTW_PRINT_DUMP("customer_str_rpt_2: ", data, CUSTOMER_STR_RPT_2_LEN);
1679
1680 _enter_critical_mutex(&dvobj->customer_str_mutex, NULL);
1681
1682 if (dvobj->customer_str_sctx != NULL) {
1683 if (dvobj->customer_str_sctx->status != RTX_SCTX_CSTR_WAIT_RPT2)
1684 RTW_WARN("%s rpt not ready\n", __func__);
1685 _rtw_memcpy(dvobj->customer_str + CUSTOMER_STR_RPT_LEN, C2H_CUSTOMER_STR_RPT_2_BYTE8(data), CUSTOMER_STR_RPT_2_LEN);
1686 rtw_sctx_done(&dvobj->customer_str_sctx);
1687 } else
1688 RTW_WARN("%s sctx not set\n", __func__);
1689
1690 _exit_critical_mutex(&dvobj->customer_str_mutex, NULL);
1691
1692 ret = _SUCCESS;
1693
1694 exit:
1695 return ret;
1696 }
1697
1698 /* read customer str */
rtw_hal_customer_str_read(_adapter * adapter,u8 * cs)1699 s32 rtw_hal_customer_str_read(_adapter *adapter, u8 *cs)
1700 {
1701 struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
1702 struct submit_ctx sctx;
1703 s32 ret = _SUCCESS;
1704
1705 _enter_critical_mutex(&dvobj->customer_str_mutex, NULL);
1706 if (dvobj->customer_str_sctx != NULL)
1707 ret = _FAIL;
1708 else {
1709 rtw_sctx_init(&sctx, 2 * 1000);
1710 dvobj->customer_str_sctx = &sctx;
1711 }
1712 _exit_critical_mutex(&dvobj->customer_str_mutex, NULL);
1713
1714 if (ret == _FAIL) {
1715 RTW_WARN("%s another handle ongoing\n", __func__);
1716 goto exit;
1717 }
1718
1719 ret = rtw_customer_str_req_cmd(adapter);
1720 if (ret != _SUCCESS) {
1721 RTW_WARN("%s read cmd fail\n", __func__);
1722 _enter_critical_mutex(&dvobj->customer_str_mutex, NULL);
1723 dvobj->customer_str_sctx = NULL;
1724 _exit_critical_mutex(&dvobj->customer_str_mutex, NULL);
1725 goto exit;
1726 }
1727
1728 /* wait till rpt done or timeout */
1729 rtw_sctx_wait(&sctx, __func__);
1730
1731 _enter_critical_mutex(&dvobj->customer_str_mutex, NULL);
1732 dvobj->customer_str_sctx = NULL;
1733 if (sctx.status == RTW_SCTX_DONE_SUCCESS)
1734 _rtw_memcpy(cs, dvobj->customer_str, RTW_CUSTOMER_STR_LEN);
1735 else
1736 ret = _FAIL;
1737 _exit_critical_mutex(&dvobj->customer_str_mutex, NULL);
1738
1739 exit:
1740 return ret;
1741 }
1742
rtw_hal_h2c_customer_str_write(_adapter * adapter,const u8 * cs)1743 s32 rtw_hal_h2c_customer_str_write(_adapter *adapter, const u8 *cs)
1744 {
1745 u8 h2c_data_w1[H2C_CUSTOMER_STR_W1_LEN] = {0};
1746 u8 h2c_data_w2[H2C_CUSTOMER_STR_W2_LEN] = {0};
1747 u8 h2c_data_w3[H2C_CUSTOMER_STR_W3_LEN] = {0};
1748 s32 ret;
1749
1750 SET_H2CCMD_CUSTOMER_STR_W1_EN(h2c_data_w1, 1);
1751 _rtw_memcpy(H2CCMD_CUSTOMER_STR_W1_BYTE0(h2c_data_w1), cs, 6);
1752
1753 SET_H2CCMD_CUSTOMER_STR_W2_EN(h2c_data_w2, 1);
1754 _rtw_memcpy(H2CCMD_CUSTOMER_STR_W2_BYTE6(h2c_data_w2), cs + 6, 6);
1755
1756 SET_H2CCMD_CUSTOMER_STR_W3_EN(h2c_data_w3, 1);
1757 _rtw_memcpy(H2CCMD_CUSTOMER_STR_W3_BYTE12(h2c_data_w3), cs + 6 + 6, 4);
1758
1759 ret = rtw_hal_fill_h2c_cmd(adapter, H2C_CUSTOMER_STR_W1, H2C_CUSTOMER_STR_W1_LEN, h2c_data_w1);
1760 if (ret != _SUCCESS) {
1761 RTW_WARN("%s w1 fail\n", __func__);
1762 goto exit;
1763 }
1764
1765 ret = rtw_hal_fill_h2c_cmd(adapter, H2C_CUSTOMER_STR_W2, H2C_CUSTOMER_STR_W2_LEN, h2c_data_w2);
1766 if (ret != _SUCCESS) {
1767 RTW_WARN("%s w2 fail\n", __func__);
1768 goto exit;
1769 }
1770
1771 ret = rtw_hal_fill_h2c_cmd(adapter, H2C_CUSTOMER_STR_W3, H2C_CUSTOMER_STR_W3_LEN, h2c_data_w3);
1772 if (ret != _SUCCESS) {
1773 RTW_WARN("%s w3 fail\n", __func__);
1774 goto exit;
1775 }
1776
1777 exit:
1778 return ret;
1779 }
1780
1781 /* write customer str and check if value reported is the same as requested */
rtw_hal_customer_str_write(_adapter * adapter,const u8 * cs)1782 s32 rtw_hal_customer_str_write(_adapter *adapter, const u8 *cs)
1783 {
1784 struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
1785 struct submit_ctx sctx;
1786 s32 ret = _SUCCESS;
1787
1788 _enter_critical_mutex(&dvobj->customer_str_mutex, NULL);
1789 if (dvobj->customer_str_sctx != NULL)
1790 ret = _FAIL;
1791 else {
1792 rtw_sctx_init(&sctx, 2 * 1000);
1793 dvobj->customer_str_sctx = &sctx;
1794 }
1795 _exit_critical_mutex(&dvobj->customer_str_mutex, NULL);
1796
1797 if (ret == _FAIL) {
1798 RTW_WARN("%s another handle ongoing\n", __func__);
1799 goto exit;
1800 }
1801
1802 ret = rtw_customer_str_write_cmd(adapter, cs);
1803 if (ret != _SUCCESS) {
1804 RTW_WARN("%s write cmd fail\n", __func__);
1805 _enter_critical_mutex(&dvobj->customer_str_mutex, NULL);
1806 dvobj->customer_str_sctx = NULL;
1807 _exit_critical_mutex(&dvobj->customer_str_mutex, NULL);
1808 goto exit;
1809 }
1810
1811 ret = rtw_customer_str_req_cmd(adapter);
1812 if (ret != _SUCCESS) {
1813 RTW_WARN("%s read cmd fail\n", __func__);
1814 _enter_critical_mutex(&dvobj->customer_str_mutex, NULL);
1815 dvobj->customer_str_sctx = NULL;
1816 _exit_critical_mutex(&dvobj->customer_str_mutex, NULL);
1817 goto exit;
1818 }
1819
1820 /* wait till rpt done or timeout */
1821 rtw_sctx_wait(&sctx, __func__);
1822
1823 _enter_critical_mutex(&dvobj->customer_str_mutex, NULL);
1824 dvobj->customer_str_sctx = NULL;
1825 if (sctx.status == RTW_SCTX_DONE_SUCCESS) {
1826 if (_rtw_memcmp(cs, dvobj->customer_str, RTW_CUSTOMER_STR_LEN) != _TRUE) {
1827 RTW_WARN("%s read back check fail\n", __func__);
1828 RTW_INFO_DUMP("write req: ", cs, RTW_CUSTOMER_STR_LEN);
1829 RTW_INFO_DUMP("read back: ", dvobj->customer_str, RTW_CUSTOMER_STR_LEN);
1830 ret = _FAIL;
1831 }
1832 } else
1833 ret = _FAIL;
1834 _exit_critical_mutex(&dvobj->customer_str_mutex, NULL);
1835
1836 exit:
1837 return ret;
1838 }
1839 #endif /* CONFIG_RTW_CUSTOMER_STR */
1840
rtw_hal_update_sta_wset(_adapter * adapter,struct sta_info * psta)1841 void rtw_hal_update_sta_wset(_adapter *adapter, struct sta_info *psta)
1842 {
1843 u8 w_set = 0;
1844
1845 if (psta->wireless_mode & WIRELESS_11B)
1846 w_set |= WIRELESS_CCK;
1847
1848 if ((psta->wireless_mode & WIRELESS_11G) || (psta->wireless_mode & WIRELESS_11A))
1849 w_set |= WIRELESS_OFDM;
1850
1851 if (psta->wireless_mode & WIRELESS_11_24N)
1852 w_set |= WIRELESS_HT;
1853
1854 if ((psta->wireless_mode & WIRELESS_11AC) || (psta->wireless_mode & WIRELESS_11_5N))
1855 w_set |= WIRELESS_VHT;
1856
1857 psta->cmn.support_wireless_set = w_set;
1858 }
1859
rtw_hal_update_sta_mimo_type(_adapter * adapter,struct sta_info * psta)1860 void rtw_hal_update_sta_mimo_type(_adapter *adapter, struct sta_info *psta)
1861 {
1862 s8 tx_nss, rx_nss;
1863
1864 tx_nss = rtw_get_sta_tx_nss(adapter, psta);
1865 rx_nss = rtw_get_sta_rx_nss(adapter, psta);
1866 if ((tx_nss == 1) && (rx_nss == 1))
1867 psta->cmn.mimo_type = RF_1T1R;
1868 else if ((tx_nss == 1) && (rx_nss == 2))
1869 psta->cmn.mimo_type = RF_1T2R;
1870 else if ((tx_nss == 2) && (rx_nss == 2))
1871 psta->cmn.mimo_type = RF_2T2R;
1872 else if ((tx_nss == 2) && (rx_nss == 3))
1873 psta->cmn.mimo_type = RF_2T3R;
1874 else if ((tx_nss == 2) && (rx_nss == 4))
1875 psta->cmn.mimo_type = RF_2T4R;
1876 else if ((tx_nss == 3) && (rx_nss == 3))
1877 psta->cmn.mimo_type = RF_3T3R;
1878 else if ((tx_nss == 3) && (rx_nss == 4))
1879 psta->cmn.mimo_type = RF_3T4R;
1880 else if ((tx_nss == 4) && (rx_nss == 4))
1881 psta->cmn.mimo_type = RF_4T4R;
1882 else
1883 rtw_warn_on(1);
1884
1885 RTW_INFO("STA - MAC_ID:%d, Tx - %d SS, Rx - %d SS\n",
1886 psta->cmn.mac_id, tx_nss, rx_nss);
1887 }
1888
rtw_hal_update_sta_smps_cap(_adapter * adapter,struct sta_info * psta)1889 void rtw_hal_update_sta_smps_cap(_adapter *adapter, struct sta_info *psta)
1890 {
1891 /*Spatial Multiplexing Power Save*/
1892 #if 0
1893 if (check_fwstate(&adapter->mlmepriv, WIFI_AP_STATE) == _TRUE) {
1894 #ifdef CONFIG_80211N_HT
1895 if (psta->htpriv.ht_option) {
1896 if (psta->htpriv.smps_cap == 0)
1897 psta->cmn.sm_ps = SM_PS_STATIC;
1898 else if (psta->htpriv.smps_cap == 1)
1899 psta->cmn.sm_ps = SM_PS_DYNAMIC;
1900 else
1901 psta->cmn.sm_ps = SM_PS_DISABLE;
1902 }
1903 #endif /* CONFIG_80211N_HT */
1904 } else
1905 #endif
1906 psta->cmn.sm_ps = SM_PS_DISABLE;
1907
1908 RTW_INFO("STA - MAC_ID:%d, SM_PS %d\n",
1909 psta->cmn.mac_id, psta->cmn.sm_ps);
1910 }
1911
rtw_get_mgntframe_raid(_adapter * adapter,unsigned char network_type)1912 u8 rtw_get_mgntframe_raid(_adapter *adapter, unsigned char network_type)
1913 {
1914
1915 u8 raid;
1916 if (IS_NEW_GENERATION_IC(adapter)) {
1917
1918 raid = (network_type & WIRELESS_11B) ? RATEID_IDX_B
1919 : RATEID_IDX_G;
1920 } else {
1921 raid = (network_type & WIRELESS_11B) ? RATR_INX_WIRELESS_B
1922 : RATR_INX_WIRELESS_G;
1923 }
1924 return raid;
1925 }
1926
rtw_hal_update_sta_rate_mask(PADAPTER padapter,struct sta_info * psta)1927 void rtw_hal_update_sta_rate_mask(PADAPTER padapter, struct sta_info *psta)
1928 {
1929 struct hal_spec_t *hal_spec = GET_HAL_SPEC(padapter);
1930 u8 i, rf_type, tx_nss;
1931 u64 tx_ra_bitmap = 0;
1932
1933 if (psta == NULL)
1934 return;
1935
1936 /* b/g mode ra_bitmap */
1937 for (i = 0; i < sizeof(psta->bssrateset); i++) {
1938 if (psta->bssrateset[i])
1939 tx_ra_bitmap |= rtw_get_bit_value_from_ieee_value(psta->bssrateset[i] & 0x7f);
1940 }
1941
1942 #ifdef CONFIG_80211N_HT
1943 rtw_hal_get_hwreg(padapter, HW_VAR_RF_TYPE, (u8 *)(&rf_type));
1944 tx_nss = rtw_min(rf_type_to_rf_tx_cnt(rf_type), hal_spec->tx_nss_num);
1945 #ifdef CONFIG_80211AC_VHT
1946 if (psta->vhtpriv.vht_option) {
1947 /* AC mode ra_bitmap */
1948 tx_ra_bitmap |= (rtw_vht_mcs_map_to_bitmap(psta->vhtpriv.vht_mcs_map, tx_nss) << 12);
1949 } else
1950 #endif /* CONFIG_80211AC_VHT */
1951 if (psta->htpriv.ht_option) {
1952 /* n mode ra_bitmap */
1953
1954 /* Handling SMPS mode for AP MODE only*/
1955 if (check_fwstate(&padapter->mlmepriv, WIFI_AP_STATE) == _TRUE) {
1956 /*0:static SMPS, 1:dynamic SMPS, 3:SMPS disabled, 2:reserved*/
1957 if (psta->htpriv.smps_cap == 0 || psta->htpriv.smps_cap == 1) {
1958 /*operate with only one active receive chain // 11n-MCS rate <= MSC7*/
1959 tx_nss = rtw_min(tx_nss, 1);
1960 }
1961 }
1962
1963 tx_ra_bitmap |= (rtw_ht_mcs_set_to_bitmap(psta->htpriv.ht_cap.supp_mcs_set, tx_nss) << 12);
1964 }
1965 #endif /* CONFIG_80211N_HT */
1966 psta->cmn.ra_info.ramask = tx_ra_bitmap;
1967 psta->init_rate = get_highest_rate_idx(tx_ra_bitmap) & 0x3f;
1968 }
1969
rtw_hal_update_sta_ra_info(PADAPTER padapter,struct sta_info * psta)1970 void rtw_hal_update_sta_ra_info(PADAPTER padapter, struct sta_info *psta)
1971 {
1972 rtw_hal_update_sta_mimo_type(padapter, psta);
1973 rtw_hal_update_sta_smps_cap(padapter, psta);
1974 rtw_hal_update_sta_rate_mask(padapter, psta);
1975 }
1976
1977 #ifndef SEC_CAM_ACCESS_TIMEOUT_MS
1978 #define SEC_CAM_ACCESS_TIMEOUT_MS 200
1979 #endif
1980
1981 #ifndef DBG_SEC_CAM_ACCESS
1982 #define DBG_SEC_CAM_ACCESS 0
1983 #endif
1984
rtw_sec_read_cam(_adapter * adapter,u8 addr)1985 u32 rtw_sec_read_cam(_adapter *adapter, u8 addr)
1986 {
1987 _mutex *mutex = &adapter_to_dvobj(adapter)->cam_ctl.sec_cam_access_mutex;
1988 u32 rdata;
1989 u32 cnt = 0;
1990 systime start = 0, end = 0;
1991 u8 timeout = 0;
1992 u8 sr = 0;
1993
1994 _enter_critical_mutex(mutex, NULL);
1995
1996 rtw_write32(adapter, REG_CAMCMD, CAM_POLLINIG | addr);
1997
1998 start = rtw_get_current_time();
1999 while (1) {
2000 if (rtw_is_surprise_removed(adapter)) {
2001 sr = 1;
2002 break;
2003 }
2004
2005 cnt++;
2006 if (0 == (rtw_read32(adapter, REG_CAMCMD) & CAM_POLLINIG))
2007 break;
2008
2009 if (rtw_get_passing_time_ms(start) > SEC_CAM_ACCESS_TIMEOUT_MS) {
2010 timeout = 1;
2011 break;
2012 }
2013 }
2014 end = rtw_get_current_time();
2015
2016 rdata = rtw_read32(adapter, REG_CAMREAD);
2017
2018 _exit_critical_mutex(mutex, NULL);
2019
2020 if (DBG_SEC_CAM_ACCESS || timeout) {
2021 RTW_INFO(FUNC_ADPT_FMT" addr:0x%02x, rdata:0x%08x, to:%u, polling:%u, %d ms\n"
2022 , FUNC_ADPT_ARG(adapter), addr, rdata, timeout, cnt, rtw_get_time_interval_ms(start, end));
2023 }
2024
2025 return rdata;
2026 }
2027
rtw_sec_write_cam(_adapter * adapter,u8 addr,u32 wdata)2028 void rtw_sec_write_cam(_adapter *adapter, u8 addr, u32 wdata)
2029 {
2030 _mutex *mutex = &adapter_to_dvobj(adapter)->cam_ctl.sec_cam_access_mutex;
2031 u32 cnt = 0;
2032 systime start = 0, end = 0;
2033 u8 timeout = 0;
2034 u8 sr = 0;
2035
2036 _enter_critical_mutex(mutex, NULL);
2037
2038 rtw_write32(adapter, REG_CAMWRITE, wdata);
2039 rtw_write32(adapter, REG_CAMCMD, CAM_POLLINIG | CAM_WRITE | addr);
2040
2041 start = rtw_get_current_time();
2042 while (1) {
2043 if (rtw_is_surprise_removed(adapter)) {
2044 sr = 1;
2045 break;
2046 }
2047
2048 cnt++;
2049 if (0 == (rtw_read32(adapter, REG_CAMCMD) & CAM_POLLINIG))
2050 break;
2051
2052 if (rtw_get_passing_time_ms(start) > SEC_CAM_ACCESS_TIMEOUT_MS) {
2053 timeout = 1;
2054 break;
2055 }
2056 }
2057 end = rtw_get_current_time();
2058
2059 _exit_critical_mutex(mutex, NULL);
2060
2061 if (DBG_SEC_CAM_ACCESS || timeout) {
2062 RTW_INFO(FUNC_ADPT_FMT" addr:0x%02x, wdata:0x%08x, to:%u, polling:%u, %d ms\n"
2063 , FUNC_ADPT_ARG(adapter), addr, wdata, timeout, cnt, rtw_get_time_interval_ms(start, end));
2064 }
2065 }
2066
rtw_sec_read_cam_ent(_adapter * adapter,u8 id,u8 * ctrl,u8 * mac,u8 * key)2067 void rtw_sec_read_cam_ent(_adapter *adapter, u8 id, u8 *ctrl, u8 *mac, u8 *key)
2068 {
2069 unsigned int val, addr;
2070 u8 i;
2071 u32 rdata;
2072 u8 begin = 0;
2073 u8 end = 5; /* TODO: consider other key length accordingly */
2074
2075 if (!ctrl && !mac && !key) {
2076 rtw_warn_on(1);
2077 goto exit;
2078 }
2079
2080 /* TODO: check id range */
2081
2082 if (!ctrl && !mac)
2083 begin = 2; /* read from key */
2084
2085 if (!key && !mac)
2086 end = 0; /* read to ctrl */
2087 else if (!key)
2088 end = 2; /* read to mac */
2089
2090 for (i = begin; i <= end; i++) {
2091 rdata = rtw_sec_read_cam(adapter, (id << 3) | i);
2092
2093 switch (i) {
2094 case 0:
2095 if (ctrl)
2096 _rtw_memcpy(ctrl, (u8 *)(&rdata), 2);
2097 if (mac)
2098 _rtw_memcpy(mac, ((u8 *)(&rdata)) + 2, 2);
2099 break;
2100 case 1:
2101 if (mac)
2102 _rtw_memcpy(mac + 2, (u8 *)(&rdata), 4);
2103 break;
2104 default:
2105 if (key)
2106 _rtw_memcpy(key + (i - 2) * 4, (u8 *)(&rdata), 4);
2107 break;
2108 }
2109 }
2110
2111 exit:
2112 return;
2113 }
2114
2115
rtw_sec_write_cam_ent(_adapter * adapter,u8 id,u16 ctrl,u8 * mac,u8 * key)2116 void rtw_sec_write_cam_ent(_adapter *adapter, u8 id, u16 ctrl, u8 *mac, u8 *key)
2117 {
2118 unsigned int i;
2119 int j;
2120 u8 addr;
2121 u32 wdata;
2122
2123 /* TODO: consider other key length accordingly */
2124 #if 0
2125 switch ((ctrl & 0x1c) >> 2) {
2126 case _WEP40_:
2127 case _TKIP_:
2128 case _AES_:
2129 case _WEP104_:
2130
2131 }
2132 #else
2133 j = 7;
2134 #endif
2135
2136 for (; j >= 0; j--) {
2137 switch (j) {
2138 case 0:
2139 wdata = (ctrl | (mac[0] << 16) | (mac[1] << 24));
2140 break;
2141 case 1:
2142 wdata = (mac[2] | (mac[3] << 8) | (mac[4] << 16) | (mac[5] << 24));
2143 break;
2144 case 6:
2145 case 7:
2146 wdata = 0;
2147 break;
2148 default:
2149 i = (j - 2) << 2;
2150 wdata = (key[i] | (key[i + 1] << 8) | (key[i + 2] << 16) | (key[i + 3] << 24));
2151 break;
2152 }
2153
2154 addr = (id << 3) + j;
2155
2156 rtw_sec_write_cam(adapter, addr, wdata);
2157 }
2158 }
2159
rtw_sec_clr_cam_ent(_adapter * adapter,u8 id)2160 void rtw_sec_clr_cam_ent(_adapter *adapter, u8 id)
2161 {
2162 u8 addr;
2163
2164 addr = (id << 3);
2165 rtw_sec_write_cam(adapter, addr, 0);
2166 }
2167
rtw_sec_read_cam_is_gk(_adapter * adapter,u8 id)2168 bool rtw_sec_read_cam_is_gk(_adapter *adapter, u8 id)
2169 {
2170 bool res;
2171 u16 ctrl;
2172
2173 rtw_sec_read_cam_ent(adapter, id, (u8 *)&ctrl, NULL, NULL);
2174
2175 res = (ctrl & BIT6) ? _TRUE : _FALSE;
2176 return res;
2177 }
2178 #ifdef CONFIG_MBSSID_CAM
rtw_mbid_cam_init(struct dvobj_priv * dvobj)2179 void rtw_mbid_cam_init(struct dvobj_priv *dvobj)
2180 {
2181 struct mbid_cam_ctl_t *mbid_cam_ctl = &dvobj->mbid_cam_ctl;
2182
2183 _rtw_spinlock_init(&mbid_cam_ctl->lock);
2184 mbid_cam_ctl->bitmap = 0;
2185 ATOMIC_SET(&mbid_cam_ctl->mbid_entry_num, 0);
2186 _rtw_memset(&dvobj->mbid_cam_cache, 0, sizeof(dvobj->mbid_cam_cache));
2187 }
2188
rtw_mbid_cam_deinit(struct dvobj_priv * dvobj)2189 void rtw_mbid_cam_deinit(struct dvobj_priv *dvobj)
2190 {
2191 struct mbid_cam_ctl_t *mbid_cam_ctl = &dvobj->mbid_cam_ctl;
2192
2193 _rtw_spinlock_free(&mbid_cam_ctl->lock);
2194 }
2195
rtw_mbid_cam_reset(_adapter * adapter)2196 void rtw_mbid_cam_reset(_adapter *adapter)
2197 {
2198 _irqL irqL;
2199 struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
2200 struct mbid_cam_ctl_t *mbid_cam_ctl = &dvobj->mbid_cam_ctl;
2201
2202 _enter_critical_bh(&mbid_cam_ctl->lock, &irqL);
2203 mbid_cam_ctl->bitmap = 0;
2204 _rtw_memset(&dvobj->mbid_cam_cache, 0, sizeof(dvobj->mbid_cam_cache));
2205 _exit_critical_bh(&mbid_cam_ctl->lock, &irqL);
2206
2207 ATOMIC_SET(&mbid_cam_ctl->mbid_entry_num, 0);
2208 }
_rtw_mbid_cam_search_by_macaddr(_adapter * adapter,u8 * mac_addr)2209 static u8 _rtw_mbid_cam_search_by_macaddr(_adapter *adapter, u8 *mac_addr)
2210 {
2211 u8 i;
2212 u8 cam_id = INVALID_CAM_ID;
2213 struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
2214
2215 for (i = 0; i < TOTAL_MBID_CAM_NUM; i++) {
2216 if (mac_addr && _rtw_memcmp(dvobj->mbid_cam_cache[i].mac_addr, mac_addr, ETH_ALEN) == _TRUE) {
2217 cam_id = i;
2218 break;
2219 }
2220 }
2221
2222 RTW_INFO("%s mac:"MAC_FMT" - cam_id:%d\n", __func__, MAC_ARG(mac_addr), cam_id);
2223 return cam_id;
2224 }
2225
rtw_mbid_cam_search_by_macaddr(_adapter * adapter,u8 * mac_addr)2226 u8 rtw_mbid_cam_search_by_macaddr(_adapter *adapter, u8 *mac_addr)
2227 {
2228 _irqL irqL;
2229
2230 u8 cam_id = INVALID_CAM_ID;
2231 struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
2232 struct mbid_cam_ctl_t *mbid_cam_ctl = &dvobj->mbid_cam_ctl;
2233
2234 _enter_critical_bh(&mbid_cam_ctl->lock, &irqL);
2235 cam_id = _rtw_mbid_cam_search_by_macaddr(adapter, mac_addr);
2236 _exit_critical_bh(&mbid_cam_ctl->lock, &irqL);
2237
2238 return cam_id;
2239 }
_rtw_mbid_cam_search_by_ifaceid(_adapter * adapter,u8 iface_id)2240 static u8 _rtw_mbid_cam_search_by_ifaceid(_adapter *adapter, u8 iface_id)
2241 {
2242 u8 i;
2243 u8 cam_id = INVALID_CAM_ID;
2244 struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
2245
2246 for (i = 0; i < TOTAL_MBID_CAM_NUM; i++) {
2247 if (iface_id == dvobj->mbid_cam_cache[i].iface_id) {
2248 cam_id = i;
2249 break;
2250 }
2251 }
2252 if (cam_id != INVALID_CAM_ID)
2253 RTW_INFO("%s iface_id:%d mac:"MAC_FMT" - cam_id:%d\n",
2254 __func__, iface_id, MAC_ARG(dvobj->mbid_cam_cache[cam_id].mac_addr), cam_id);
2255
2256 return cam_id;
2257 }
2258
rtw_mbid_cam_search_by_ifaceid(_adapter * adapter,u8 iface_id)2259 u8 rtw_mbid_cam_search_by_ifaceid(_adapter *adapter, u8 iface_id)
2260 {
2261 _irqL irqL;
2262 u8 cam_id = INVALID_CAM_ID;
2263 struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
2264 struct mbid_cam_ctl_t *mbid_cam_ctl = &dvobj->mbid_cam_ctl;
2265
2266 _enter_critical_bh(&mbid_cam_ctl->lock, &irqL);
2267 cam_id = _rtw_mbid_cam_search_by_ifaceid(adapter, iface_id);
2268 _exit_critical_bh(&mbid_cam_ctl->lock, &irqL);
2269
2270 return cam_id;
2271 }
rtw_get_max_mbid_cam_id(_adapter * adapter)2272 u8 rtw_get_max_mbid_cam_id(_adapter *adapter)
2273 {
2274 _irqL irqL;
2275 s8 i;
2276 u8 cam_id = INVALID_CAM_ID;
2277 struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
2278 struct mbid_cam_ctl_t *mbid_cam_ctl = &dvobj->mbid_cam_ctl;
2279
2280 _enter_critical_bh(&mbid_cam_ctl->lock, &irqL);
2281 for (i = (TOTAL_MBID_CAM_NUM - 1); i >= 0; i--) {
2282 if (mbid_cam_ctl->bitmap & BIT(i)) {
2283 cam_id = i;
2284 break;
2285 }
2286 }
2287 _exit_critical_bh(&mbid_cam_ctl->lock, &irqL);
2288 /*RTW_INFO("%s max cam_id:%d\n", __func__, cam_id);*/
2289 return cam_id;
2290 }
2291
rtw_get_mbid_cam_entry_num(_adapter * adapter)2292 inline u8 rtw_get_mbid_cam_entry_num(_adapter *adapter)
2293 {
2294 struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
2295 struct mbid_cam_ctl_t *mbid_cam_ctl = &dvobj->mbid_cam_ctl;
2296
2297 return ATOMIC_READ(&mbid_cam_ctl->mbid_entry_num);
2298 }
2299
mbid_cam_cache_init(_adapter * adapter,struct mbid_cam_cache * pmbid_cam,u8 * mac_addr)2300 static inline void mbid_cam_cache_init(_adapter *adapter, struct mbid_cam_cache *pmbid_cam, u8 *mac_addr)
2301 {
2302 if (adapter && pmbid_cam && mac_addr) {
2303 _rtw_memcpy(pmbid_cam->mac_addr, mac_addr, ETH_ALEN);
2304 pmbid_cam->iface_id = adapter->iface_id;
2305 }
2306 }
mbid_cam_cache_clr(struct mbid_cam_cache * pmbid_cam)2307 static inline void mbid_cam_cache_clr(struct mbid_cam_cache *pmbid_cam)
2308 {
2309 if (pmbid_cam) {
2310 _rtw_memset(pmbid_cam->mac_addr, 0, ETH_ALEN);
2311 pmbid_cam->iface_id = CONFIG_IFACE_NUMBER;
2312 }
2313 }
2314
rtw_mbid_camid_alloc(_adapter * adapter,u8 * mac_addr)2315 u8 rtw_mbid_camid_alloc(_adapter *adapter, u8 *mac_addr)
2316 {
2317 _irqL irqL;
2318 u8 cam_id = INVALID_CAM_ID, i;
2319 struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
2320 struct mbid_cam_ctl_t *mbid_cam_ctl = &dvobj->mbid_cam_ctl;
2321 u8 entry_num = ATOMIC_READ(&mbid_cam_ctl->mbid_entry_num);
2322
2323 if (entry_num >= TOTAL_MBID_CAM_NUM) {
2324 RTW_INFO(FUNC_ADPT_FMT" failed !! MBSSID number :%d over TOTAL_CAM_ENTRY(8)\n", FUNC_ADPT_ARG(adapter), entry_num);
2325 rtw_warn_on(1);
2326 }
2327
2328 if (INVALID_CAM_ID != rtw_mbid_cam_search_by_macaddr(adapter, mac_addr))
2329 goto exit;
2330
2331 _enter_critical_bh(&mbid_cam_ctl->lock, &irqL);
2332 for (i = 0; i < TOTAL_MBID_CAM_NUM; i++) {
2333 if (!(mbid_cam_ctl->bitmap & BIT(i))) {
2334 mbid_cam_ctl->bitmap |= BIT(i);
2335 cam_id = i;
2336 break;
2337 }
2338 }
2339 if ((cam_id != INVALID_CAM_ID) && (mac_addr))
2340 mbid_cam_cache_init(adapter, &dvobj->mbid_cam_cache[cam_id], mac_addr);
2341 _exit_critical_bh(&mbid_cam_ctl->lock, &irqL);
2342
2343 if (cam_id != INVALID_CAM_ID) {
2344 ATOMIC_INC(&mbid_cam_ctl->mbid_entry_num);
2345 RTW_INFO("%s mac:"MAC_FMT" - cam_id:%d\n", __func__, MAC_ARG(mac_addr), cam_id);
2346 #ifdef DBG_MBID_CAM_DUMP
2347 rtw_mbid_cam_cache_dump(RTW_DBGDUMP, __func__, adapter);
2348 #endif
2349 } else
2350 RTW_INFO("%s [WARN] "MAC_FMT" - invalid cam_id:%d\n", __func__, MAC_ARG(mac_addr), cam_id);
2351 exit:
2352 return cam_id;
2353 }
2354
rtw_mbid_cam_info_change(_adapter * adapter,u8 * mac_addr)2355 u8 rtw_mbid_cam_info_change(_adapter *adapter, u8 *mac_addr)
2356 {
2357 _irqL irqL;
2358 u8 entry_id = INVALID_CAM_ID;
2359 struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
2360 struct mbid_cam_ctl_t *mbid_cam_ctl = &dvobj->mbid_cam_ctl;
2361
2362 _enter_critical_bh(&mbid_cam_ctl->lock, &irqL);
2363 entry_id = _rtw_mbid_cam_search_by_ifaceid(adapter, adapter->iface_id);
2364 if (entry_id != INVALID_CAM_ID)
2365 mbid_cam_cache_init(adapter, &dvobj->mbid_cam_cache[entry_id], mac_addr);
2366
2367 _exit_critical_bh(&mbid_cam_ctl->lock, &irqL);
2368
2369 return entry_id;
2370 }
2371
rtw_mbid_cam_assign(_adapter * adapter,u8 * mac_addr,u8 camid)2372 u8 rtw_mbid_cam_assign(_adapter *adapter, u8 *mac_addr, u8 camid)
2373 {
2374 _irqL irqL;
2375 u8 ret = _FALSE;
2376 struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
2377 struct mbid_cam_ctl_t *mbid_cam_ctl = &dvobj->mbid_cam_ctl;
2378
2379 if ((camid >= TOTAL_MBID_CAM_NUM) || (camid == INVALID_CAM_ID)) {
2380 RTW_INFO(FUNC_ADPT_FMT" failed !! invlaid mbid_canid :%d\n", FUNC_ADPT_ARG(adapter), camid);
2381 rtw_warn_on(1);
2382 }
2383 if (INVALID_CAM_ID != rtw_mbid_cam_search_by_macaddr(adapter, mac_addr))
2384 goto exit;
2385
2386 _enter_critical_bh(&mbid_cam_ctl->lock, &irqL);
2387 if (!(mbid_cam_ctl->bitmap & BIT(camid))) {
2388 if (mac_addr) {
2389 mbid_cam_ctl->bitmap |= BIT(camid);
2390 mbid_cam_cache_init(adapter, &dvobj->mbid_cam_cache[camid], mac_addr);
2391 ret = _TRUE;
2392 }
2393 }
2394 _exit_critical_bh(&mbid_cam_ctl->lock, &irqL);
2395
2396 if (ret == _TRUE) {
2397 ATOMIC_INC(&mbid_cam_ctl->mbid_entry_num);
2398 RTW_INFO("%s mac:"MAC_FMT" - cam_id:%d\n", __func__, MAC_ARG(mac_addr), camid);
2399 #ifdef DBG_MBID_CAM_DUMP
2400 rtw_mbid_cam_cache_dump(RTW_DBGDUMP, __func__, adapter);
2401 #endif
2402 } else
2403 RTW_INFO("%s [WARN] mac:"MAC_FMT" - cam_id:%d assigned failed\n", __func__, MAC_ARG(mac_addr), camid);
2404
2405 exit:
2406 return ret;
2407 }
2408
rtw_mbid_camid_clean(_adapter * adapter,u8 mbss_canid)2409 void rtw_mbid_camid_clean(_adapter *adapter, u8 mbss_canid)
2410 {
2411 _irqL irqL;
2412 struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
2413 struct mbid_cam_ctl_t *mbid_cam_ctl = &dvobj->mbid_cam_ctl;
2414
2415 if ((mbss_canid >= TOTAL_MBID_CAM_NUM) || (mbss_canid == INVALID_CAM_ID)) {
2416 RTW_INFO(FUNC_ADPT_FMT" failed !! invlaid mbid_canid :%d\n", FUNC_ADPT_ARG(adapter), mbss_canid);
2417 rtw_warn_on(1);
2418 }
2419 _enter_critical_bh(&mbid_cam_ctl->lock, &irqL);
2420 mbid_cam_cache_clr(&dvobj->mbid_cam_cache[mbss_canid]);
2421 mbid_cam_ctl->bitmap &= (~BIT(mbss_canid));
2422 _exit_critical_bh(&mbid_cam_ctl->lock, &irqL);
2423 ATOMIC_DEC(&mbid_cam_ctl->mbid_entry_num);
2424 RTW_INFO("%s - cam_id:%d\n", __func__, mbss_canid);
2425 }
rtw_mbid_cam_cache_dump(void * sel,const char * fun_name,_adapter * adapter)2426 int rtw_mbid_cam_cache_dump(void *sel, const char *fun_name, _adapter *adapter)
2427 {
2428 _irqL irqL;
2429 u8 i;
2430 _adapter *iface;
2431 u8 iface_id;
2432 struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
2433 struct mbid_cam_ctl_t *mbid_cam_ctl = &dvobj->mbid_cam_ctl;
2434 u8 entry_num = ATOMIC_READ(&mbid_cam_ctl->mbid_entry_num);
2435 u8 max_cam_id = rtw_get_max_mbid_cam_id(adapter);
2436
2437 RTW_PRINT_SEL(sel, "== MBSSID CAM DUMP (%s)==\n", fun_name);
2438
2439 _enter_critical_bh(&mbid_cam_ctl->lock, &irqL);
2440 RTW_PRINT_SEL(sel, "Entry numbers:%d, max_camid:%d, bitmap:0x%08x\n", entry_num, max_cam_id, mbid_cam_ctl->bitmap);
2441 for (i = 0; i < TOTAL_MBID_CAM_NUM; i++) {
2442 RTW_PRINT_SEL(sel, "CAM_ID = %d\t", i);
2443
2444 if (mbid_cam_ctl->bitmap & BIT(i)) {
2445 iface_id = dvobj->mbid_cam_cache[i].iface_id;
2446 RTW_PRINT_SEL(sel, "IF_ID:%d\t", iface_id);
2447 RTW_PRINT_SEL(sel, "MAC Addr:"MAC_FMT"\t", MAC_ARG(dvobj->mbid_cam_cache[i].mac_addr));
2448
2449 iface = dvobj->padapters[iface_id];
2450 if (iface) {
2451 if (MLME_IS_STA(iface))
2452 RTW_PRINT_SEL(sel, "ROLE:%s\n", "STA");
2453 else if (MLME_IS_AP(iface))
2454 RTW_PRINT_SEL(sel, "ROLE:%s\n", "AP");
2455 else if (MLME_IS_MESH(iface))
2456 RTW_PRINT_SEL(sel, "ROLE:%s\n", "MESH");
2457 else
2458 RTW_PRINT_SEL(sel, "ROLE:%s\n", "NONE");
2459 }
2460
2461 } else
2462 RTW_PRINT_SEL(sel, "N/A\n");
2463 }
2464 _exit_critical_bh(&mbid_cam_ctl->lock, &irqL);
2465 return 0;
2466 }
2467
read_mbssid_cam(_adapter * padapter,u8 cam_addr,u8 * mac)2468 static void read_mbssid_cam(_adapter *padapter, u8 cam_addr, u8 *mac)
2469 {
2470 u8 poll = 1;
2471 u8 cam_ready = _FALSE;
2472 u32 cam_data1 = 0;
2473 u16 cam_data2 = 0;
2474
2475 if (RTW_CANNOT_RUN(padapter))
2476 return;
2477
2478 rtw_write32(padapter, REG_MBIDCAMCFG_2, BIT_MBIDCAM_POLL | ((cam_addr & MBIDCAM_ADDR_MASK) << MBIDCAM_ADDR_SHIFT));
2479
2480 do {
2481 if (0 == (rtw_read32(padapter, REG_MBIDCAMCFG_2) & BIT_MBIDCAM_POLL)) {
2482 cam_ready = _TRUE;
2483 break;
2484 }
2485 poll++;
2486 } while ((poll % 10) != 0 && !RTW_CANNOT_RUN(padapter));
2487
2488 if (cam_ready) {
2489 cam_data1 = rtw_read32(padapter, REG_MBIDCAMCFG_1);
2490 mac[0] = cam_data1 & 0xFF;
2491 mac[1] = (cam_data1 >> 8) & 0xFF;
2492 mac[2] = (cam_data1 >> 16) & 0xFF;
2493 mac[3] = (cam_data1 >> 24) & 0xFF;
2494
2495 cam_data2 = rtw_read16(padapter, REG_MBIDCAMCFG_2);
2496 mac[4] = cam_data2 & 0xFF;
2497 mac[5] = (cam_data2 >> 8) & 0xFF;
2498 }
2499
2500 }
rtw_mbid_cam_dump(void * sel,const char * fun_name,_adapter * adapter)2501 int rtw_mbid_cam_dump(void *sel, const char *fun_name, _adapter *adapter)
2502 {
2503 /*_irqL irqL;*/
2504 u8 i;
2505 u8 mac_addr[ETH_ALEN];
2506
2507 struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
2508 struct mbid_cam_ctl_t *mbid_cam_ctl = &dvobj->mbid_cam_ctl;
2509
2510 RTW_PRINT_SEL(sel, "\n== MBSSID HW-CAM DUMP (%s)==\n", fun_name);
2511
2512 /*_enter_critical_bh(&mbid_cam_ctl->lock, &irqL);*/
2513 for (i = 0; i < TOTAL_MBID_CAM_NUM; i++) {
2514 RTW_PRINT_SEL(sel, "CAM_ID = %d\t", i);
2515 _rtw_memset(mac_addr, 0, ETH_ALEN);
2516 read_mbssid_cam(adapter, i, mac_addr);
2517 RTW_PRINT_SEL(sel, "MAC Addr:"MAC_FMT"\n", MAC_ARG(mac_addr));
2518 }
2519 /*_exit_critical_bh(&mbid_cam_ctl->lock, &irqL);*/
2520 return 0;
2521 }
2522
write_mbssid_cam(_adapter * padapter,u8 cam_addr,u8 * mac)2523 static void write_mbssid_cam(_adapter *padapter, u8 cam_addr, u8 *mac)
2524 {
2525 u32 cam_val[2] = {0};
2526
2527 cam_val[0] = (mac[3] << 24) | (mac[2] << 16) | (mac[1] << 8) | mac[0];
2528 cam_val[1] = ((cam_addr & MBIDCAM_ADDR_MASK) << MBIDCAM_ADDR_SHIFT) | (mac[5] << 8) | mac[4];
2529
2530 rtw_hal_set_hwreg(padapter, HW_VAR_MBSSID_CAM_WRITE, (u8 *)cam_val);
2531 }
2532
clear_mbssid_cam(_adapter * padapter,u8 cam_addr)2533 static void clear_mbssid_cam(_adapter *padapter, u8 cam_addr)
2534 {
2535 rtw_hal_set_hwreg(padapter, HW_VAR_MBSSID_CAM_CLEAR, &cam_addr);
2536 }
enable_mbssid_cam(_adapter * adapter)2537 static void enable_mbssid_cam(_adapter *adapter)
2538 {
2539 u8 max_cam_id = rtw_get_max_mbid_cam_id(adapter);
2540 /*enable MBSSID*/
2541 rtw_hal_rcr_add(adapter, RCR_ENMBID);
2542 if (max_cam_id != INVALID_CAM_ID) {
2543 rtw_write8(adapter, REG_MBID_NUM,
2544 ((rtw_read8(adapter, REG_MBID_NUM) & 0xF8) | (max_cam_id & 0x07)));
2545 }
2546 }
rtw_mbid_cam_restore(_adapter * adapter)2547 void rtw_mbid_cam_restore(_adapter *adapter)
2548 {
2549 u8 i;
2550 struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
2551 struct mbid_cam_ctl_t *mbid_cam_ctl = &dvobj->mbid_cam_ctl;
2552
2553 #ifdef DBG_MBID_CAM_DUMP
2554 rtw_mbid_cam_cache_dump(RTW_DBGDUMP, __func__, adapter);
2555 #endif
2556
2557 for (i = 0; i < TOTAL_MBID_CAM_NUM; i++) {
2558 if (mbid_cam_ctl->bitmap & BIT(i)) {
2559 write_mbssid_cam(adapter, i, dvobj->mbid_cam_cache[i].mac_addr);
2560 RTW_INFO("%s - cam_id:%d => mac:"MAC_FMT"\n", __func__, i, MAC_ARG(dvobj->mbid_cam_cache[i].mac_addr));
2561 }
2562 }
2563 enable_mbssid_cam(adapter);
2564 }
2565 #endif /*CONFIG_MBSSID_CAM*/
2566
2567 #ifdef CONFIG_MI_WITH_MBSSID_CAM
rtw_hal_set_macaddr_mbid(_adapter * adapter,u8 * mac_addr)2568 void rtw_hal_set_macaddr_mbid(_adapter *adapter, u8 *mac_addr)
2569 {
2570
2571 #if 0 /*TODO - modify for more flexible*/
2572 u8 idx = 0;
2573
2574 if ((check_fwstate(&adapter->mlmepriv, WIFI_STATION_STATE) == _TRUE) &&
2575 (DEV_STA_NUM(adapter_to_dvobj(adapter)) == 1)) {
2576 for (idx = 0; idx < 6; idx++)
2577 rtw_write8(GET_PRIMARY_ADAPTER(adapter), (REG_MACID + idx), val[idx]);
2578 } else {
2579 /*MBID entry_id = 0~7 ,0 for root AP, 1~7 for VAP*/
2580 u8 entry_id;
2581
2582 if ((check_fwstate(&adapter->mlmepriv, WIFI_AP_STATE) == _TRUE) &&
2583 (DEV_AP_NUM(adapter_to_dvobj(adapter)) == 1)) {
2584 entry_id = 0;
2585 if (rtw_mbid_cam_assign(adapter, val, entry_id)) {
2586 RTW_INFO(FUNC_ADPT_FMT" Root AP assigned success\n", FUNC_ADPT_ARG(adapter));
2587 write_mbssid_cam(adapter, entry_id, val);
2588 }
2589 } else {
2590 entry_id = rtw_mbid_camid_alloc(adapter, val);
2591 if (entry_id != INVALID_CAM_ID)
2592 write_mbssid_cam(adapter, entry_id, val);
2593 }
2594 }
2595 #else
2596 {
2597 /*
2598 MBID entry_id = 0~7 ,for IFACE_ID0 ~ IFACE_IDx
2599 */
2600 u8 entry_id = rtw_mbid_camid_alloc(adapter, mac_addr);
2601
2602
2603 if (entry_id != INVALID_CAM_ID) {
2604 write_mbssid_cam(adapter, entry_id, mac_addr);
2605 enable_mbssid_cam(adapter);
2606 }
2607 }
2608 #endif
2609 }
2610
rtw_hal_change_macaddr_mbid(_adapter * adapter,u8 * mac_addr)2611 void rtw_hal_change_macaddr_mbid(_adapter *adapter, u8 *mac_addr)
2612 {
2613 u8 idx = 0;
2614 struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
2615 u8 entry_id;
2616
2617 if (!mac_addr) {
2618 rtw_warn_on(1);
2619 return;
2620 }
2621
2622
2623 entry_id = rtw_mbid_cam_info_change(adapter, mac_addr);
2624
2625 if (entry_id != INVALID_CAM_ID)
2626 write_mbssid_cam(adapter, entry_id, mac_addr);
2627 }
2628
2629 #ifdef CONFIG_SWTIMER_BASED_TXBCN
rtw_hal_bcn_interval_adjust(_adapter * adapter,u16 bcn_interval)2630 u16 rtw_hal_bcn_interval_adjust(_adapter *adapter, u16 bcn_interval)
2631 {
2632 if (adapter_to_dvobj(adapter)->inter_bcn_space != bcn_interval)
2633 return adapter_to_dvobj(adapter)->inter_bcn_space;
2634 else
2635 return bcn_interval;
2636 }
2637 #endif/*CONFIG_SWTIMER_BASED_TXBCN*/
2638
2639 #endif/*#ifdef CONFIG_MI_WITH_MBSSID_CAM*/
2640
rtw_hal_set_macaddr_port(_adapter * adapter,u8 * val)2641 static void rtw_hal_set_macaddr_port(_adapter *adapter, u8 *val)
2642 {
2643 u8 idx = 0;
2644 u32 reg_macid = 0;
2645
2646 if (val == NULL)
2647 return;
2648
2649 RTW_INFO("%s "ADPT_FMT"- hw port(%d) mac_addr ="MAC_FMT"\n", __func__,
2650 ADPT_ARG(adapter), adapter->hw_port, MAC_ARG(val));
2651
2652 #ifdef RTW_HALMAC
2653 rtw_halmac_set_mac_address(adapter_to_dvobj(adapter), adapter->hw_port, val);
2654 #else /* !RTW_HALMAC */
2655 switch (adapter->hw_port) {
2656 case HW_PORT0:
2657 default:
2658 reg_macid = REG_MACID;
2659 break;
2660 case HW_PORT1:
2661 reg_macid = REG_MACID1;
2662 break;
2663 #if defined(CONFIG_RTL8814A)
2664 case HW_PORT2:
2665 reg_macid = REG_MACID2;
2666 break;
2667 case HW_PORT3:
2668 reg_macid = REG_MACID3;
2669 break;
2670 case HW_PORT4:
2671 reg_macid = REG_MACID4;
2672 break;
2673 #endif/*defined(CONFIG_RTL8814A)*/
2674 }
2675
2676 for (idx = 0; idx < 6; idx++)
2677 rtw_write8(GET_PRIMARY_ADAPTER(adapter), (reg_macid + idx), val[idx]);
2678 #endif /* !RTW_HALMAC */
2679 }
2680
rtw_hal_get_macaddr_port(_adapter * adapter,u8 * mac_addr)2681 static void rtw_hal_get_macaddr_port(_adapter *adapter, u8 *mac_addr)
2682 {
2683 u8 idx = 0;
2684 u32 reg_macid = 0;
2685
2686 if (mac_addr == NULL)
2687 return;
2688
2689 _rtw_memset(mac_addr, 0, ETH_ALEN);
2690 #ifdef RTW_HALMAC
2691 rtw_halmac_get_mac_address(adapter_to_dvobj(adapter), adapter->hw_port, mac_addr);
2692 #else /* !RTW_HALMAC */
2693 switch (adapter->hw_port) {
2694 case HW_PORT0:
2695 default:
2696 reg_macid = REG_MACID;
2697 break;
2698 case HW_PORT1:
2699 reg_macid = REG_MACID1;
2700 break;
2701 #if defined(CONFIG_RTL8814A)
2702 case HW_PORT2:
2703 reg_macid = REG_MACID2;
2704 break;
2705 case HW_PORT3:
2706 reg_macid = REG_MACID3;
2707 break;
2708 case HW_PORT4:
2709 reg_macid = REG_MACID4;
2710 break;
2711 #endif /*defined(CONFIG_RTL8814A)*/
2712 }
2713
2714 for (idx = 0; idx < 6; idx++)
2715 mac_addr[idx] = rtw_read8(GET_PRIMARY_ADAPTER(adapter), (reg_macid + idx));
2716 #endif /* !RTW_HALMAC */
2717
2718 RTW_INFO("%s "ADPT_FMT"- hw port(%d) mac_addr ="MAC_FMT"\n", __func__,
2719 ADPT_ARG(adapter), adapter->hw_port, MAC_ARG(mac_addr));
2720 }
2721
rtw_hal_set_bssid(_adapter * adapter,u8 * val)2722 static void rtw_hal_set_bssid(_adapter *adapter, u8 *val)
2723 {
2724 #ifdef RTW_HALMAC
2725 rtw_halmac_set_bssid(adapter_to_dvobj(adapter), adapter->hw_port, val);
2726 #else /* !RTW_HALMAC */
2727 u8 idx = 0;
2728 u32 reg_bssid = 0;
2729
2730 switch (adapter->hw_port) {
2731 case HW_PORT0:
2732 default:
2733 reg_bssid = REG_BSSID;
2734 break;
2735 case HW_PORT1:
2736 reg_bssid = REG_BSSID1;
2737 break;
2738 #if defined(CONFIG_RTL8814A) || defined(CONFIG_RTL8822B)
2739 case HW_PORT2:
2740 reg_bssid = REG_BSSID2;
2741 break;
2742 case HW_PORT3:
2743 reg_bssid = REG_BSSID3;
2744 break;
2745 case HW_PORT4:
2746 reg_bssid = REG_BSSID4;
2747 break;
2748 #endif/*defined(CONFIG_RTL8814A) || defined(CONFIG_RTL8822B)*/
2749 }
2750
2751 for (idx = 0 ; idx < 6; idx++)
2752 rtw_write8(adapter, (reg_bssid + idx), val[idx]);
2753 #endif /* !RTW_HALMAC */
2754
2755 RTW_INFO("%s "ADPT_FMT"- hw port -%d BSSID: "MAC_FMT"\n", __func__, ADPT_ARG(adapter), adapter->hw_port, MAC_ARG(val));
2756 }
2757
hw_var_rcr_config(_adapter * adapter,u32 rcr)2758 static inline u8 hw_var_rcr_config(_adapter *adapter, u32 rcr)
2759 {
2760 int err;
2761
2762 err = rtw_write32(adapter, REG_RCR, rcr);
2763 if (err == _SUCCESS)
2764 GET_HAL_DATA(adapter)->ReceiveConfig = rcr;
2765 return err;
2766 }
2767
hw_var_rcr_get(_adapter * adapter,u32 * rcr)2768 static inline u8 hw_var_rcr_get(_adapter *adapter, u32 *rcr)
2769 {
2770 u32 v32;
2771
2772 v32 = rtw_read32(adapter, REG_RCR);
2773 if (rcr)
2774 *rcr = v32;
2775 GET_HAL_DATA(adapter)->ReceiveConfig = v32;
2776 return _SUCCESS;
2777 }
2778
2779 /* only check SW RCR variable */
rtw_hal_rcr_check(_adapter * adapter,u32 check_bit)2780 inline u8 rtw_hal_rcr_check(_adapter *adapter, u32 check_bit)
2781 {
2782 PHAL_DATA_TYPE hal;
2783 u32 rcr;
2784
2785 hal = GET_HAL_DATA(adapter);
2786
2787 rcr = hal->ReceiveConfig;
2788 if ((rcr & check_bit) == check_bit)
2789 return 1;
2790
2791 return 0;
2792 }
2793
rtw_hal_rcr_add(_adapter * adapter,u32 add)2794 inline u8 rtw_hal_rcr_add(_adapter *adapter, u32 add)
2795 {
2796 PHAL_DATA_TYPE hal;
2797 u32 rcr;
2798 u8 ret = _SUCCESS;
2799
2800 hal = GET_HAL_DATA(adapter);
2801
2802 rtw_hal_get_hwreg(adapter, HW_VAR_RCR, (u8 *)&rcr);
2803 rcr |= add;
2804 if (rcr != hal->ReceiveConfig)
2805 ret = rtw_hal_set_hwreg(adapter, HW_VAR_RCR, (u8 *)&rcr);
2806
2807 return ret;
2808 }
2809
rtw_hal_rcr_clear(_adapter * adapter,u32 clear)2810 inline u8 rtw_hal_rcr_clear(_adapter *adapter, u32 clear)
2811 {
2812 PHAL_DATA_TYPE hal;
2813 u32 rcr;
2814 u8 ret = _SUCCESS;
2815
2816 hal = GET_HAL_DATA(adapter);
2817
2818 rtw_hal_get_hwreg(adapter, HW_VAR_RCR, (u8 *)&rcr);
2819 rcr &= ~clear;
2820 if (rcr != hal->ReceiveConfig)
2821 ret = rtw_hal_set_hwreg(adapter, HW_VAR_RCR, (u8 *)&rcr);
2822
2823 return ret;
2824 }
2825
rtw_hal_rcr_set_chk_bssid(_adapter * adapter,u8 self_action)2826 void rtw_hal_rcr_set_chk_bssid(_adapter *adapter, u8 self_action)
2827 {
2828 HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
2829 u32 rcr, rcr_new;
2830 struct mi_state mstate, mstate_s;
2831
2832 rtw_hal_get_hwreg(adapter, HW_VAR_RCR, (u8 *)&rcr);
2833 rcr_new = rcr;
2834
2835 #ifdef CONFIG_MI_WITH_MBSSID_CAM
2836 rcr_new &= ~(RCR_CBSSID_BCN | RCR_CBSSID_DATA);
2837 #else
2838 rtw_mi_status_no_self(adapter, &mstate);
2839 rtw_mi_status_no_others(adapter, &mstate_s);
2840
2841 /* only adjust parameters interested */
2842 switch (self_action) {
2843 case MLME_SCAN_ENTER:
2844 mstate_s.scan_num = 1;
2845 mstate_s.scan_enter_num = 1;
2846 break;
2847 case MLME_SCAN_DONE:
2848 mstate_s.scan_enter_num = 0;
2849 break;
2850 #ifdef CONFIG_TDLS
2851 case MLME_TDLS_LINKED:
2852 mstate_s.ld_tdls_num = 1;
2853 break;
2854 case MLME_TDLS_NOLINK:
2855 mstate_s.ld_tdls_num = 0;
2856 break;
2857 #endif
2858 #ifdef CONFIG_AP_MODE
2859 case MLME_AP_STARTED:
2860 mstate_s.ap_num = 1;
2861 break;
2862 case MLME_AP_STOPPED:
2863 mstate_s.ap_num = 0;
2864 mstate_s.ld_ap_num = 0;
2865 break;
2866 #endif
2867 #ifdef CONFIG_RTW_MESH
2868 case MLME_MESH_STARTED:
2869 mstate_s.mesh_num = 1;
2870 break;
2871 case MLME_MESH_STOPPED:
2872 mstate_s.mesh_num = 0;
2873 mstate_s.ld_mesh_num = 0;
2874 break;
2875 #endif
2876 case MLME_ACTION_NONE:
2877 case MLME_STA_CONNECTING:
2878 case MLME_ADHOC_STARTED:
2879 /* caller without effect of decision */
2880 break;
2881 default:
2882 rtw_warn_on(1);
2883 };
2884
2885 rtw_mi_status_merge(&mstate, &mstate_s);
2886
2887 if (MSTATE_AP_NUM(&mstate) || MSTATE_MESH_NUM(&mstate) || MSTATE_TDLS_LD_NUM(&mstate)
2888 #ifdef CONFIG_FIND_BEST_CHANNEL
2889 || MSTATE_SCAN_ENTER_NUM(&mstate)
2890 #endif
2891 || hal_data->in_cta_test
2892 )
2893 rcr_new &= ~RCR_CBSSID_DATA;
2894 else
2895 rcr_new |= RCR_CBSSID_DATA;
2896
2897 if ((MSTATE_AP_NUM(&mstate) && adapter->registrypriv.wifi_spec) /* for 11n Logo 4.2.31/4.2.32 */
2898 || MSTATE_MESH_NUM(&mstate)
2899 || MSTATE_SCAN_ENTER_NUM(&mstate)
2900 || hal_data->in_cta_test
2901 )
2902 rcr_new &= ~RCR_CBSSID_BCN;
2903 else
2904 rcr_new |= RCR_CBSSID_BCN;
2905 #endif /* CONFIG_MI_WITH_MBSSID_CAM */
2906
2907 if (rcr != rcr_new)
2908 rtw_hal_set_hwreg(adapter, HW_VAR_RCR, (u8 *)&rcr_new);
2909 }
2910
hw_var_set_rcr_am(_adapter * adapter,u8 enable)2911 static void hw_var_set_rcr_am(_adapter *adapter, u8 enable)
2912 {
2913 u32 rcr = RCR_AM;
2914
2915 if (enable)
2916 rtw_hal_rcr_add(adapter, rcr);
2917 else
2918 rtw_hal_rcr_clear(adapter, rcr);
2919 }
2920
rtw_hal_get_msr(_adapter * adapter,u8 * net_type)2921 static void rtw_hal_get_msr(_adapter *adapter, u8 *net_type)
2922 {
2923 #ifdef RTW_HALMAC
2924 rtw_halmac_get_network_type(adapter_to_dvobj(adapter),
2925 adapter->hw_port, net_type);
2926 #else /* !RTW_HALMAC */
2927 switch (adapter->hw_port) {
2928 case HW_PORT0:
2929 /*REG_CR - BIT[17:16]-Network Type for port 1*/
2930 *net_type = rtw_read8(adapter, MSR) & 0x03;
2931 break;
2932 case HW_PORT1:
2933 /*REG_CR - BIT[19:18]-Network Type for port 1*/
2934 *net_type = (rtw_read8(adapter, MSR) & 0x0C) >> 2;
2935 break;
2936 #if defined(CONFIG_RTL8814A) || defined(CONFIG_RTL8822B)
2937 case HW_PORT2:
2938 /*REG_CR_EXT- BIT[1:0]-Network Type for port 2*/
2939 *net_type = rtw_read8(adapter, MSR1) & 0x03;
2940 break;
2941 case HW_PORT3:
2942 /*REG_CR_EXT- BIT[3:2]-Network Type for port 3*/
2943 *net_type = (rtw_read8(adapter, MSR1) & 0x0C) >> 2;
2944 break;
2945 case HW_PORT4:
2946 /*REG_CR_EXT- BIT[5:4]-Network Type for port 4*/
2947 *net_type = (rtw_read8(adapter, MSR1) & 0x30) >> 4;
2948 break;
2949 #endif /*#if defined(CONFIG_RTL8814A) || defined(CONFIG_RTL8822B)*/
2950 default:
2951 RTW_INFO("[WARN] "ADPT_FMT"- invalid hw port -%d\n",
2952 ADPT_ARG(adapter), adapter->hw_port);
2953 rtw_warn_on(1);
2954 break;
2955 }
2956 #endif /* !RTW_HALMAC */
2957 }
2958
2959 #if defined(CONFIG_MI_WITH_MBSSID_CAM) && defined(CONFIG_MBSSID_CAM) /*For 2 hw ports - 88E/92E/8812/8821/8723B*/
rtw_hal_net_type_decision(_adapter * adapter,u8 net_type)2960 static u8 rtw_hal_net_type_decision(_adapter *adapter, u8 net_type)
2961 {
2962 if ((adapter->hw_port == HW_PORT0) && (rtw_get_mbid_cam_entry_num(adapter))) {
2963 if (net_type != _HW_STATE_NOLINK_)
2964 return _HW_STATE_AP_;
2965 }
2966 return net_type;
2967 }
2968 #endif
rtw_hal_set_msr(_adapter * adapter,u8 net_type)2969 static void rtw_hal_set_msr(_adapter *adapter, u8 net_type)
2970 {
2971 #ifdef RTW_HALMAC
2972 #if defined(CONFIG_MI_WITH_MBSSID_CAM) && defined(CONFIG_MBSSID_CAM)
2973 net_type = rtw_hal_net_type_decision(adapter, net_type);
2974 #endif
2975 rtw_halmac_set_network_type(adapter_to_dvobj(adapter),
2976 adapter->hw_port, net_type);
2977 #else /* !RTW_HALMAC */
2978 u8 val8 = 0;
2979
2980 switch (adapter->hw_port) {
2981 case HW_PORT0:
2982 #if defined(CONFIG_MI_WITH_MBSSID_CAM) && defined(CONFIG_MBSSID_CAM)
2983 net_type = rtw_hal_net_type_decision(adapter, net_type);
2984 #endif
2985 /*REG_CR - BIT[17:16]-Network Type for port 0*/
2986 val8 = rtw_read8(adapter, MSR) & 0x0C;
2987 val8 |= net_type;
2988 rtw_write8(adapter, MSR, val8);
2989 break;
2990 case HW_PORT1:
2991 /*REG_CR - BIT[19:18]-Network Type for port 1*/
2992 val8 = rtw_read8(adapter, MSR) & 0x03;
2993 val8 |= net_type << 2;
2994 rtw_write8(adapter, MSR, val8);
2995 break;
2996 #if defined(CONFIG_RTL8814A) || defined(CONFIG_RTL8822B) || defined(CONFIG_RTL8821C)
2997 case HW_PORT2:
2998 /*REG_CR_EXT- BIT[1:0]-Network Type for port 2*/
2999 val8 = rtw_read8(adapter, MSR1) & 0xFC;
3000 val8 |= net_type;
3001 rtw_write8(adapter, MSR1, val8);
3002 break;
3003 case HW_PORT3:
3004 /*REG_CR_EXT- BIT[3:2]-Network Type for port 3*/
3005 val8 = rtw_read8(adapter, MSR1) & 0xF3;
3006 val8 |= net_type << 2;
3007 rtw_write8(adapter, MSR1, val8);
3008 break;
3009 case HW_PORT4:
3010 /*REG_CR_EXT- BIT[5:4]-Network Type for port 4*/
3011 val8 = rtw_read8(adapter, MSR1) & 0xCF;
3012 val8 |= net_type << 4;
3013 rtw_write8(adapter, MSR1, val8);
3014 break;
3015 #endif /* CONFIG_RTL8814A | CONFIG_RTL8822B */
3016 default:
3017 RTW_INFO("[WARN] "ADPT_FMT"- invalid hw port -%d\n",
3018 ADPT_ARG(adapter), adapter->hw_port);
3019 rtw_warn_on(1);
3020 break;
3021 }
3022 #endif /* !RTW_HALMAC */
3023 }
3024
hw_var_set_bcn_interval(struct _ADAPTER * a,u16 interval)3025 static void hw_var_set_bcn_interval(struct _ADAPTER *a, u16 interval)
3026 {
3027 #ifdef RTW_HALMAC
3028 rtw_halmac_set_bcn_interval(adapter_to_dvobj(a), a->hw_port, interval);
3029 #else /* !RTW_HALMAC */
3030 RTW_ERR(FUNC_ADPT_FMT ": Not implemented yet!!\n", FUNC_ADPT_ARG(a));
3031 rtw_warn_on(1);
3032 #endif /* !RTW_HALMAC */
3033 }
3034
hw_var_port_switch(_adapter * adapter)3035 void hw_var_port_switch(_adapter *adapter)
3036 {
3037 #ifdef CONFIG_CONCURRENT_MODE
3038 #ifdef CONFIG_RUNTIME_PORT_SWITCH
3039 /*
3040 0x102: MSR
3041 0x550: REG_BCN_CTRL
3042 0x551: REG_BCN_CTRL_1
3043 0x55A: REG_ATIMWND
3044 0x560: REG_TSFTR
3045 0x568: REG_TSFTR1
3046 0x570: REG_ATIMWND_1
3047 0x610: REG_MACID
3048 0x618: REG_BSSID
3049 0x700: REG_MACID1
3050 0x708: REG_BSSID1
3051 */
3052
3053 int i;
3054 u8 msr;
3055 u8 bcn_ctrl;
3056 u8 bcn_ctrl_1;
3057 u8 atimwnd[2];
3058 u8 atimwnd_1[2];
3059 u8 tsftr[8];
3060 u8 tsftr_1[8];
3061 u8 macid[6];
3062 u8 bssid[6];
3063 u8 macid_1[6];
3064 u8 bssid_1[6];
3065
3066 u8 hw_port;
3067 struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
3068 _adapter *iface = NULL;
3069
3070 msr = rtw_read8(adapter, MSR);
3071 bcn_ctrl = rtw_read8(adapter, REG_BCN_CTRL);
3072 bcn_ctrl_1 = rtw_read8(adapter, REG_BCN_CTRL_1);
3073
3074 for (i = 0; i < 2; i++)
3075 atimwnd[i] = rtw_read8(adapter, REG_ATIMWND + i);
3076 for (i = 0; i < 2; i++)
3077 atimwnd_1[i] = rtw_read8(adapter, REG_ATIMWND_1 + i);
3078
3079 for (i = 0; i < 8; i++)
3080 tsftr[i] = rtw_read8(adapter, REG_TSFTR + i);
3081 for (i = 0; i < 8; i++)
3082 tsftr_1[i] = rtw_read8(adapter, REG_TSFTR1 + i);
3083
3084 for (i = 0; i < 6; i++)
3085 macid[i] = rtw_read8(adapter, REG_MACID + i);
3086
3087 for (i = 0; i < 6; i++)
3088 bssid[i] = rtw_read8(adapter, REG_BSSID + i);
3089
3090 for (i = 0; i < 6; i++)
3091 macid_1[i] = rtw_read8(adapter, REG_MACID1 + i);
3092
3093 for (i = 0; i < 6; i++)
3094 bssid_1[i] = rtw_read8(adapter, REG_BSSID1 + i);
3095
3096 #ifdef DBG_RUNTIME_PORT_SWITCH
3097 RTW_INFO(FUNC_ADPT_FMT" before switch\n"
3098 "msr:0x%02x\n"
3099 "bcn_ctrl:0x%02x\n"
3100 "bcn_ctrl_1:0x%02x\n"
3101 "atimwnd:0x%04x\n"
3102 "atimwnd_1:0x%04x\n"
3103 "tsftr:%llu\n"
3104 "tsftr1:%llu\n"
3105 "macid:"MAC_FMT"\n"
3106 "bssid:"MAC_FMT"\n"
3107 "macid_1:"MAC_FMT"\n"
3108 "bssid_1:"MAC_FMT"\n"
3109 , FUNC_ADPT_ARG(adapter)
3110 , msr
3111 , bcn_ctrl
3112 , bcn_ctrl_1
3113 , *((u16 *)atimwnd)
3114 , *((u16 *)atimwnd_1)
3115 , *((u64 *)tsftr)
3116 , *((u64 *)tsftr_1)
3117 , MAC_ARG(macid)
3118 , MAC_ARG(bssid)
3119 , MAC_ARG(macid_1)
3120 , MAC_ARG(bssid_1)
3121 );
3122 #endif /* DBG_RUNTIME_PORT_SWITCH */
3123
3124 /* disable bcn function, disable update TSF */
3125 rtw_write8(adapter, REG_BCN_CTRL, (bcn_ctrl & (~EN_BCN_FUNCTION)) | DIS_TSF_UDT);
3126 rtw_write8(adapter, REG_BCN_CTRL_1, (bcn_ctrl_1 & (~EN_BCN_FUNCTION)) | DIS_TSF_UDT);
3127
3128 /* switch msr */
3129 msr = (msr & 0xf0) | ((msr & 0x03) << 2) | ((msr & 0x0c) >> 2);
3130 rtw_write8(adapter, MSR, msr);
3131
3132 /* write port0 */
3133 rtw_write8(adapter, REG_BCN_CTRL, bcn_ctrl_1 & ~EN_BCN_FUNCTION);
3134 for (i = 0; i < 2; i++)
3135 rtw_write8(adapter, REG_ATIMWND + i, atimwnd_1[i]);
3136 for (i = 0; i < 8; i++)
3137 rtw_write8(adapter, REG_TSFTR + i, tsftr_1[i]);
3138 for (i = 0; i < 6; i++)
3139 rtw_write8(adapter, REG_MACID + i, macid_1[i]);
3140 for (i = 0; i < 6; i++)
3141 rtw_write8(adapter, REG_BSSID + i, bssid_1[i]);
3142
3143 /* write port1 */
3144 rtw_write8(adapter, REG_BCN_CTRL_1, bcn_ctrl & ~EN_BCN_FUNCTION);
3145 for (i = 0; i < 2; i++)
3146 rtw_write8(adapter, REG_ATIMWND_1 + i, atimwnd[i]);
3147 for (i = 0; i < 8; i++)
3148 rtw_write8(adapter, REG_TSFTR1 + i, tsftr[i]);
3149 for (i = 0; i < 6; i++)
3150 rtw_write8(adapter, REG_MACID1 + i, macid[i]);
3151 for (i = 0; i < 6; i++)
3152 rtw_write8(adapter, REG_BSSID1 + i, bssid[i]);
3153
3154 /* write bcn ctl */
3155 #ifdef CONFIG_BT_COEXIST
3156 /* always enable port0 beacon function for PSTDMA */
3157 if (IS_HARDWARE_TYPE_8723B(adapter) || IS_HARDWARE_TYPE_8703B(adapter)
3158 || IS_HARDWARE_TYPE_8723D(adapter))
3159 bcn_ctrl_1 |= EN_BCN_FUNCTION;
3160 /* always disable port1 beacon function for PSTDMA */
3161 if (IS_HARDWARE_TYPE_8723B(adapter) || IS_HARDWARE_TYPE_8703B(adapter))
3162 bcn_ctrl &= ~EN_BCN_FUNCTION;
3163 #endif
3164 rtw_write8(adapter, REG_BCN_CTRL, bcn_ctrl_1);
3165 rtw_write8(adapter, REG_BCN_CTRL_1, bcn_ctrl);
3166
3167 if (adapter->iface_id == IFACE_ID0)
3168 iface = dvobj->padapters[IFACE_ID1];
3169 else if (adapter->iface_id == IFACE_ID1)
3170 iface = dvobj->padapters[IFACE_ID0];
3171
3172
3173 if (adapter->hw_port == HW_PORT0) {
3174 adapter->hw_port = HW_PORT1;
3175 iface->hw_port = HW_PORT0;
3176 RTW_PRINT("port switch - port0("ADPT_FMT"), port1("ADPT_FMT")\n",
3177 ADPT_ARG(iface), ADPT_ARG(adapter));
3178 } else {
3179 adapter->hw_port = HW_PORT0;
3180 iface->hw_port = HW_PORT1;
3181 RTW_PRINT("port switch - port0("ADPT_FMT"), port1("ADPT_FMT")\n",
3182 ADPT_ARG(adapter), ADPT_ARG(iface));
3183 }
3184
3185 #ifdef DBG_RUNTIME_PORT_SWITCH
3186 msr = rtw_read8(adapter, MSR);
3187 bcn_ctrl = rtw_read8(adapter, REG_BCN_CTRL);
3188 bcn_ctrl_1 = rtw_read8(adapter, REG_BCN_CTRL_1);
3189
3190 for (i = 0; i < 2; i++)
3191 atimwnd[i] = rtw_read8(adapter, REG_ATIMWND + i);
3192 for (i = 0; i < 2; i++)
3193 atimwnd_1[i] = rtw_read8(adapter, REG_ATIMWND_1 + i);
3194
3195 for (i = 0; i < 8; i++)
3196 tsftr[i] = rtw_read8(adapter, REG_TSFTR + i);
3197 for (i = 0; i < 8; i++)
3198 tsftr_1[i] = rtw_read8(adapter, REG_TSFTR1 + i);
3199
3200 for (i = 0; i < 6; i++)
3201 macid[i] = rtw_read8(adapter, REG_MACID + i);
3202
3203 for (i = 0; i < 6; i++)
3204 bssid[i] = rtw_read8(adapter, REG_BSSID + i);
3205
3206 for (i = 0; i < 6; i++)
3207 macid_1[i] = rtw_read8(adapter, REG_MACID1 + i);
3208
3209 for (i = 0; i < 6; i++)
3210 bssid_1[i] = rtw_read8(adapter, REG_BSSID1 + i);
3211
3212 RTW_INFO(FUNC_ADPT_FMT" after switch\n"
3213 "msr:0x%02x\n"
3214 "bcn_ctrl:0x%02x\n"
3215 "bcn_ctrl_1:0x%02x\n"
3216 "atimwnd:%u\n"
3217 "atimwnd_1:%u\n"
3218 "tsftr:%llu\n"
3219 "tsftr1:%llu\n"
3220 "macid:"MAC_FMT"\n"
3221 "bssid:"MAC_FMT"\n"
3222 "macid_1:"MAC_FMT"\n"
3223 "bssid_1:"MAC_FMT"\n"
3224 , FUNC_ADPT_ARG(adapter)
3225 , msr
3226 , bcn_ctrl
3227 , bcn_ctrl_1
3228 , *((u16 *)atimwnd)
3229 , *((u16 *)atimwnd_1)
3230 , *((u64 *)tsftr)
3231 , *((u64 *)tsftr_1)
3232 , MAC_ARG(macid)
3233 , MAC_ARG(bssid)
3234 , MAC_ARG(macid_1)
3235 , MAC_ARG(bssid_1)
3236 );
3237 #endif /* DBG_RUNTIME_PORT_SWITCH */
3238
3239 #endif /* CONFIG_RUNTIME_PORT_SWITCH */
3240 #endif /* CONFIG_CONCURRENT_MODE */
3241 }
3242
3243 const char *const _h2c_msr_role_str[] = {
3244 "RSVD",
3245 "STA",
3246 "AP",
3247 "GC",
3248 "GO",
3249 "TDLS",
3250 "ADHOC",
3251 "MESH",
3252 "INVALID",
3253 };
3254
3255 #ifdef CONFIG_FW_MULTI_PORT_SUPPORT
rtw_hal_set_default_port_id_cmd(_adapter * adapter,u8 mac_id)3256 s32 rtw_hal_set_default_port_id_cmd(_adapter *adapter, u8 mac_id)
3257 {
3258 s32 ret = _SUCCESS;
3259 u8 parm[H2C_DEFAULT_PORT_ID_LEN] = {0};
3260 struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
3261
3262 SET_H2CCMD_DFTPID_PORT_ID(parm, adapter->hw_port);
3263 SET_H2CCMD_DFTPID_MAC_ID(parm, mac_id);
3264
3265 RTW_DBG_DUMP("DFT port id parm:", parm, H2C_DEFAULT_PORT_ID_LEN);
3266 RTW_INFO("%s port_id :%d, mad_id:%d\n", __func__, adapter->hw_port, mac_id);
3267
3268 ret = rtw_hal_fill_h2c_cmd(adapter, H2C_DEFAULT_PORT_ID, H2C_DEFAULT_PORT_ID_LEN, parm);
3269 dvobj->default_port_id = adapter->hw_port;
3270
3271 return ret;
3272 }
rtw_set_default_port_id(_adapter * adapter)3273 s32 rtw_set_default_port_id(_adapter *adapter)
3274 {
3275 s32 ret = _SUCCESS;
3276 struct sta_info *psta;
3277 struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
3278 struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
3279
3280 if (adapter->hw_port == dvobj->default_port_id)
3281 return ret;
3282
3283 if (check_fwstate(pmlmepriv, WIFI_STATION_STATE) == _TRUE) {
3284 psta = rtw_get_stainfo(&adapter->stapriv, get_bssid(pmlmepriv));
3285 if (psta)
3286 ret = rtw_hal_set_default_port_id_cmd(adapter, psta->cmn.mac_id);
3287 } else if (check_fwstate(pmlmepriv, WIFI_AP_STATE) == _TRUE) {
3288
3289 } else {
3290 }
3291
3292 return ret;
3293 }
rtw_set_ps_rsvd_page(_adapter * adapter)3294 s32 rtw_set_ps_rsvd_page(_adapter *adapter)
3295 {
3296 s32 ret = _SUCCESS;
3297 u16 media_status_rpt = RT_MEDIA_CONNECT;
3298 struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
3299
3300 if (adapter->hw_port == dvobj->default_port_id)
3301 return ret;
3302
3303 rtw_hal_set_hwreg(adapter, HW_VAR_H2C_FW_JOINBSSRPT,
3304 (u8 *)&media_status_rpt);
3305
3306 return ret;
3307 }
3308
3309 #endif
3310
3311 #ifdef CONFIG_P2P_PS
3312 #ifdef RTW_HALMAC
rtw_set_p2p_ps_offload_cmd(_adapter * adapter,u8 p2p_ps_state)3313 void rtw_set_p2p_ps_offload_cmd(_adapter *adapter, u8 p2p_ps_state)
3314 {
3315 PHAL_DATA_TYPE hal = GET_HAL_DATA(adapter);
3316 struct wifidirect_info *pwdinfo = &adapter->wdinfo;
3317 struct mlme_ext_priv *pmlmeext = &adapter->mlmeextpriv;
3318 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
3319 WLAN_BSSID_EX *cur_network = &(pmlmeinfo->network);
3320 struct sta_priv *pstapriv = &adapter->stapriv;
3321 struct sta_info *psta;
3322 HAL_P2P_PS_PARA p2p_ps_para;
3323 int status = -1;
3324 u8 i;
3325
3326 _rtw_memset(&p2p_ps_para, 0, sizeof(HAL_P2P_PS_PARA));
3327 _rtw_memcpy((&p2p_ps_para) , &hal->p2p_ps_offload , sizeof(hal->p2p_ps_offload));
3328
3329 (&p2p_ps_para)->p2p_port_id = adapter->hw_port;
3330 (&p2p_ps_para)->p2p_group = 0;
3331 psta = rtw_get_stainfo(pstapriv, cur_network->MacAddress);
3332 if (psta) {
3333 (&p2p_ps_para)->p2p_macid = psta->cmn.mac_id;
3334 } else {
3335 if (p2p_ps_state != P2P_PS_DISABLE) {
3336 RTW_ERR("%s , psta was NULL\n", __func__);
3337 return;
3338 }
3339 }
3340
3341
3342 switch (p2p_ps_state) {
3343 case P2P_PS_DISABLE:
3344 RTW_INFO("P2P_PS_DISABLE\n");
3345 _rtw_memset(&p2p_ps_para , 0, sizeof(HAL_P2P_PS_PARA));
3346 break;
3347
3348 case P2P_PS_ENABLE:
3349 RTW_INFO("P2P_PS_ENABLE\n");
3350 /* update CTWindow value. */
3351 if (pwdinfo->ctwindow > 0) {
3352 (&p2p_ps_para)->ctwindow_en = 1;
3353 (&p2p_ps_para)->ctwindow_length = pwdinfo->ctwindow;
3354 /*RTW_INFO("%s , ctwindow_length = %d\n" , __func__ , (&p2p_ps_para)->ctwindow_length);*/
3355 }
3356
3357
3358 if ((pwdinfo->opp_ps == 1) || (pwdinfo->noa_num > 0)) {
3359 (&p2p_ps_para)->offload_en = 1;
3360 if (pwdinfo->role == P2P_ROLE_GO) {
3361 (&p2p_ps_para)->role = 1;
3362 (&p2p_ps_para)->all_sta_sleep = 0;
3363 } else
3364 (&p2p_ps_para)->role = 0;
3365
3366 (&p2p_ps_para)->discovery = 0;
3367 }
3368 /* hw only support 2 set of NoA */
3369 for (i = 0; i < pwdinfo->noa_num; i++) {
3370 /* To control the register setting for which NOA */
3371 (&p2p_ps_para)->noa_sel = i;
3372 (&p2p_ps_para)->noa_en = 1;
3373 /* config P2P NoA Descriptor Register */
3374 /* config NOA duration */
3375 (&p2p_ps_para)->noa_duration_para = pwdinfo->noa_duration[i];
3376 /* config NOA interval */
3377 (&p2p_ps_para)->noa_interval_para = pwdinfo->noa_interval[i];
3378 /* config NOA start time */
3379 (&p2p_ps_para)->noa_start_time_para = pwdinfo->noa_start_time[i];
3380 /* config NOA count */
3381 (&p2p_ps_para)->noa_count_para = pwdinfo->noa_count[i];
3382 /*RTW_INFO("%s , noa_duration_para = %d , noa_interval_para = %d , noa_start_time_para = %d , noa_count_para = %d\n" , __func__ ,
3383 (&p2p_ps_para)->noa_duration_para , (&p2p_ps_para)->noa_interval_para ,
3384 (&p2p_ps_para)->noa_start_time_para , (&p2p_ps_para)->noa_count_para);*/
3385 status = rtw_halmac_p2pps(adapter_to_dvobj(adapter) , (&p2p_ps_para));
3386 if (status == -1)
3387 RTW_ERR("%s , rtw_halmac_p2pps fail\n", __func__);
3388 }
3389
3390 break;
3391
3392 case P2P_PS_SCAN:
3393 /*This feature FW not ready 20161116 YiWei*/
3394 return;
3395 RTW_INFO("P2P_PS_SCAN\n");
3396 (&p2p_ps_para)->discovery = 1;
3397 /*
3398 (&p2p_ps_para)->ctwindow_length = pwdinfo->ctwindow;
3399 (&p2p_ps_para)->noa_duration_para = pwdinfo->noa_duration[0];
3400 (&p2p_ps_para)->noa_interval_para = pwdinfo->noa_interval[0];
3401 (&p2p_ps_para)->noa_start_time_para = pwdinfo->noa_start_time[0];
3402 (&p2p_ps_para)->noa_count_para = pwdinfo->noa_count[0];
3403 */
3404 break;
3405
3406 case P2P_PS_SCAN_DONE:
3407 /*This feature FW not ready 20161116 YiWei*/
3408 return;
3409 RTW_INFO("P2P_PS_SCAN_DONE\n");
3410 (&p2p_ps_para)->discovery = 0;
3411 /*
3412 pwdinfo->p2p_ps_state = P2P_PS_ENABLE;
3413 (&p2p_ps_para)->ctwindow_length = pwdinfo->ctwindow;
3414 (&p2p_ps_para)->noa_duration_para = pwdinfo->noa_duration[0];
3415 (&p2p_ps_para)->noa_interval_para = pwdinfo->noa_interval[0];
3416 (&p2p_ps_para)->noa_start_time_para = pwdinfo->noa_start_time[0];
3417 (&p2p_ps_para)->noa_count_para = pwdinfo->noa_count[0];
3418 */
3419 break;
3420
3421 default:
3422 break;
3423 }
3424
3425 if (p2p_ps_state != P2P_PS_ENABLE || (&p2p_ps_para)->noa_en == 0) {
3426 status = rtw_halmac_p2pps(adapter_to_dvobj(adapter) , (&p2p_ps_para));
3427 if (status == -1)
3428 RTW_ERR("%s , rtw_halmac_p2pps fail\n", __func__);
3429 }
3430 _rtw_memcpy(&hal->p2p_ps_offload , (&p2p_ps_para) , sizeof(hal->p2p_ps_offload));
3431
3432 }
3433 #endif /* RTW_HALMAC */
3434 #endif /* CONFIG_P2P */
3435
3436 /*
3437 * rtw_hal_set_FwMediaStatusRpt_cmd -
3438 *
3439 * @adapter:
3440 * @opmode: 0:disconnect, 1:connect
3441 * @miracast: 0:it's not in miracast scenario. 1:it's in miracast scenario
3442 * @miracast_sink: 0:source. 1:sink
3443 * @role: The role of this macid. 0:rsvd. 1:STA. 2:AP. 3:GC. 4:GO. 5:TDLS
3444 * @macid:
3445 * @macid_ind: 0:update Media Status to macid. 1:update Media Status from macid to macid_end
3446 * @macid_end:
3447 */
rtw_hal_set_FwMediaStatusRpt_cmd(_adapter * adapter,bool opmode,bool miracast,bool miracast_sink,u8 role,u8 macid,bool macid_ind,u8 macid_end)3448 s32 rtw_hal_set_FwMediaStatusRpt_cmd(_adapter *adapter, bool opmode, bool miracast, bool miracast_sink, u8 role, u8 macid, bool macid_ind, u8 macid_end)
3449 {
3450 struct macid_ctl_t *macid_ctl = &adapter->dvobj->macid_ctl;
3451 u8 parm[H2C_MEDIA_STATUS_RPT_LEN] = {0};
3452 int i;
3453 s32 ret;
3454
3455 SET_H2CCMD_MSRRPT_PARM_OPMODE(parm, opmode);
3456 SET_H2CCMD_MSRRPT_PARM_MACID_IND(parm, macid_ind);
3457 SET_H2CCMD_MSRRPT_PARM_MIRACAST(parm, miracast);
3458 SET_H2CCMD_MSRRPT_PARM_MIRACAST_SINK(parm, miracast_sink);
3459 SET_H2CCMD_MSRRPT_PARM_ROLE(parm, role);
3460 SET_H2CCMD_MSRRPT_PARM_MACID(parm, macid);
3461 SET_H2CCMD_MSRRPT_PARM_MACID_END(parm, macid_end);
3462 #ifdef CONFIG_FW_MULTI_PORT_SUPPORT
3463 SET_H2CCMD_MSRRPT_PARM_PORT_NUM(parm, adapter->hw_port);
3464 #endif
3465 RTW_DBG_DUMP("MediaStatusRpt parm:", parm, H2C_MEDIA_STATUS_RPT_LEN);
3466
3467 ret = rtw_hal_fill_h2c_cmd(adapter, H2C_MEDIA_STATUS_RPT, H2C_MEDIA_STATUS_RPT_LEN, parm);
3468 if (ret != _SUCCESS)
3469 goto exit;
3470
3471 #if defined(CONFIG_RTL8188E)
3472 if (rtw_get_chip_type(adapter) == RTL8188E) {
3473 HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
3474
3475 /* 8188E FW doesn't set macid no link, driver does it by self */
3476 if (opmode)
3477 rtw_hal_set_hwreg(adapter, HW_VAR_MACID_LINK, &macid);
3478 else
3479 rtw_hal_set_hwreg(adapter, HW_VAR_MACID_NOLINK, &macid);
3480
3481 /* for 8188E RA */
3482 #if (RATE_ADAPTIVE_SUPPORT == 1)
3483 if (hal_data->fw_ractrl == _FALSE) {
3484 u8 max_macid;
3485
3486 max_macid = rtw_search_max_mac_id(adapter);
3487 rtw_hal_set_hwreg(adapter, HW_VAR_TX_RPT_MAX_MACID, &max_macid);
3488 }
3489 #endif
3490 }
3491 #endif
3492
3493 #if defined(CONFIG_RTL8812A) || defined(CONFIG_RTL8821A)
3494 /* TODO: this should move to IOT issue area */
3495 if (rtw_get_chip_type(adapter) == RTL8812
3496 || rtw_get_chip_type(adapter) == RTL8821
3497 ) {
3498 if (MLME_IS_STA(adapter))
3499 Hal_PatchwithJaguar_8812(adapter, opmode);
3500 }
3501 #endif
3502
3503 SET_H2CCMD_MSRRPT_PARM_MACID_IND(parm, 0);
3504 if (macid_ind == 0)
3505 macid_end = macid;
3506
3507 for (i = macid; macid <= macid_end; macid++) {
3508 rtw_macid_ctl_set_h2c_msr(macid_ctl, macid, parm[0]);
3509 if (!opmode) {
3510 rtw_macid_ctl_set_bw(macid_ctl, macid, CHANNEL_WIDTH_20);
3511 rtw_macid_ctl_set_vht_en(macid_ctl, macid, 0);
3512 rtw_macid_ctl_set_rate_bmp0(macid_ctl, macid, 0);
3513 rtw_macid_ctl_set_rate_bmp1(macid_ctl, macid, 0);
3514 }
3515 }
3516 if (!opmode)
3517 rtw_update_tx_rate_bmp(adapter_to_dvobj(adapter));
3518
3519 exit:
3520 return ret;
3521 }
3522
rtw_hal_set_FwMediaStatusRpt_single_cmd(_adapter * adapter,bool opmode,bool miracast,bool miracast_sink,u8 role,u8 macid)3523 inline s32 rtw_hal_set_FwMediaStatusRpt_single_cmd(_adapter *adapter, bool opmode, bool miracast, bool miracast_sink, u8 role, u8 macid)
3524 {
3525 return rtw_hal_set_FwMediaStatusRpt_cmd(adapter, opmode, miracast, miracast_sink, role, macid, 0, 0);
3526 }
3527
rtw_hal_set_FwMediaStatusRpt_range_cmd(_adapter * adapter,bool opmode,bool miracast,bool miracast_sink,u8 role,u8 macid,u8 macid_end)3528 inline s32 rtw_hal_set_FwMediaStatusRpt_range_cmd(_adapter *adapter, bool opmode, bool miracast, bool miracast_sink, u8 role, u8 macid, u8 macid_end)
3529 {
3530 return rtw_hal_set_FwMediaStatusRpt_cmd(adapter, opmode, miracast, miracast_sink, role, macid, 1, macid_end);
3531 }
3532
rtw_hal_set_FwRsvdPage_cmd(PADAPTER padapter,PRSVDPAGE_LOC rsvdpageloc)3533 void rtw_hal_set_FwRsvdPage_cmd(PADAPTER padapter, PRSVDPAGE_LOC rsvdpageloc)
3534 {
3535 struct hal_ops *pHalFunc = &padapter->hal_func;
3536 u8 u1H2CRsvdPageParm[H2C_RSVDPAGE_LOC_LEN] = {0};
3537 u8 ret = 0;
3538
3539 RTW_INFO("RsvdPageLoc: ProbeRsp=%d PsPoll=%d Null=%d QoSNull=%d BTNull=%d\n",
3540 rsvdpageloc->LocProbeRsp, rsvdpageloc->LocPsPoll,
3541 rsvdpageloc->LocNullData, rsvdpageloc->LocQosNull,
3542 rsvdpageloc->LocBTQosNull);
3543
3544 SET_H2CCMD_RSVDPAGE_LOC_PROBE_RSP(u1H2CRsvdPageParm, rsvdpageloc->LocProbeRsp);
3545 SET_H2CCMD_RSVDPAGE_LOC_PSPOLL(u1H2CRsvdPageParm, rsvdpageloc->LocPsPoll);
3546 SET_H2CCMD_RSVDPAGE_LOC_NULL_DATA(u1H2CRsvdPageParm, rsvdpageloc->LocNullData);
3547 SET_H2CCMD_RSVDPAGE_LOC_QOS_NULL_DATA(u1H2CRsvdPageParm, rsvdpageloc->LocQosNull);
3548 SET_H2CCMD_RSVDPAGE_LOC_BT_QOS_NULL_DATA(u1H2CRsvdPageParm, rsvdpageloc->LocBTQosNull);
3549
3550 ret = rtw_hal_fill_h2c_cmd(padapter,
3551 H2C_RSVD_PAGE,
3552 H2C_RSVDPAGE_LOC_LEN,
3553 u1H2CRsvdPageParm);
3554
3555 }
3556
3557 #ifdef CONFIG_GPIO_WAKEUP
rtw_hal_switch_gpio_wl_ctrl(_adapter * padapter,u8 index,u8 enable)3558 void rtw_hal_switch_gpio_wl_ctrl(_adapter *padapter, u8 index, u8 enable)
3559 {
3560 PHAL_DATA_TYPE pHalData = GET_HAL_DATA(padapter);
3561
3562 if (IS_8723D_SERIES(pHalData->version_id) || IS_8822B_SERIES(pHalData->version_id))
3563 rtw_hal_set_hwreg(padapter, HW_SET_GPIO_WL_CTRL, (u8 *)(&enable));
3564 /*
3565 * Switch GPIO_13, GPIO_14 to wlan control, or pull GPIO_13,14 MUST fail.
3566 * It happended at 8723B/8192E/8821A. New IC will check multi function GPIO,
3567 * and implement HAL function.
3568 * TODO: GPIO_8 multi function?
3569 */
3570
3571 if ((index == 13 || index == 14)
3572 #if defined(CONFIG_RTL8821A) && defined(CONFIG_SDIO_HCI)
3573 /* 8821A's LED2 circuit(used by HW_LED strategy) needs enable WL GPIO control of GPIO[14:13], can't disable */
3574 && (!IS_HW_LED_STRATEGY(rtw_led_get_strategy(padapter)) || enable)
3575 #endif
3576 )
3577 rtw_hal_set_hwreg(padapter, HW_SET_GPIO_WL_CTRL, (u8 *)(&enable));
3578 }
3579
rtw_hal_set_output_gpio(_adapter * padapter,u8 index,u8 outputval)3580 void rtw_hal_set_output_gpio(_adapter *padapter, u8 index, u8 outputval)
3581 {
3582 if (index <= 7) {
3583 /* config GPIO mode */
3584 rtw_write8(padapter, REG_GPIO_PIN_CTRL + 3,
3585 rtw_read8(padapter, REG_GPIO_PIN_CTRL + 3) & ~BIT(index));
3586
3587 /* config GPIO Sel */
3588 /* 0: input */
3589 /* 1: output */
3590 rtw_write8(padapter, REG_GPIO_PIN_CTRL + 2,
3591 rtw_read8(padapter, REG_GPIO_PIN_CTRL + 2) | BIT(index));
3592
3593 /* set output value */
3594 if (outputval) {
3595 rtw_write8(padapter, REG_GPIO_PIN_CTRL + 1,
3596 rtw_read8(padapter, REG_GPIO_PIN_CTRL + 1) | BIT(index));
3597 } else {
3598 rtw_write8(padapter, REG_GPIO_PIN_CTRL + 1,
3599 rtw_read8(padapter, REG_GPIO_PIN_CTRL + 1) & ~BIT(index));
3600 }
3601 } else if (index <= 15) {
3602 /* 88C Series: */
3603 /* index: 11~8 transform to 3~0 */
3604 /* 8723 Series: */
3605 /* index: 12~8 transform to 4~0 */
3606
3607 index -= 8;
3608
3609 /* config GPIO mode */
3610 rtw_write8(padapter, REG_GPIO_PIN_CTRL_2 + 3,
3611 rtw_read8(padapter, REG_GPIO_PIN_CTRL_2 + 3) & ~BIT(index));
3612
3613 /* config GPIO Sel */
3614 /* 0: input */
3615 /* 1: output */
3616 rtw_write8(padapter, REG_GPIO_PIN_CTRL_2 + 2,
3617 rtw_read8(padapter, REG_GPIO_PIN_CTRL_2 + 2) | BIT(index));
3618
3619 /* set output value */
3620 if (outputval) {
3621 rtw_write8(padapter, REG_GPIO_PIN_CTRL_2 + 1,
3622 rtw_read8(padapter, REG_GPIO_PIN_CTRL_2 + 1) | BIT(index));
3623 } else {
3624 rtw_write8(padapter, REG_GPIO_PIN_CTRL_2 + 1,
3625 rtw_read8(padapter, REG_GPIO_PIN_CTRL_2 + 1) & ~BIT(index));
3626 }
3627 } else {
3628 RTW_INFO("%s: invalid GPIO%d=%d\n",
3629 __FUNCTION__, index, outputval);
3630 }
3631 }
rtw_hal_set_input_gpio(_adapter * padapter,u8 index)3632 void rtw_hal_set_input_gpio(_adapter *padapter, u8 index)
3633 {
3634 if (index <= 7) {
3635 /* config GPIO mode */
3636 rtw_write8(padapter, REG_GPIO_PIN_CTRL + 3,
3637 rtw_read8(padapter, REG_GPIO_PIN_CTRL + 3) & ~BIT(index));
3638
3639 /* config GPIO Sel */
3640 /* 0: input */
3641 /* 1: output */
3642 rtw_write8(padapter, REG_GPIO_PIN_CTRL + 2,
3643 rtw_read8(padapter, REG_GPIO_PIN_CTRL + 2) & ~BIT(index));
3644
3645 } else if (index <= 15) {
3646 /* 88C Series: */
3647 /* index: 11~8 transform to 3~0 */
3648 /* 8723 Series: */
3649 /* index: 12~8 transform to 4~0 */
3650
3651 index -= 8;
3652
3653 /* config GPIO mode */
3654 rtw_write8(padapter, REG_GPIO_PIN_CTRL_2 + 3,
3655 rtw_read8(padapter, REG_GPIO_PIN_CTRL_2 + 3) & ~BIT(index));
3656
3657 /* config GPIO Sel */
3658 /* 0: input */
3659 /* 1: output */
3660 rtw_write8(padapter, REG_GPIO_PIN_CTRL_2 + 2,
3661 rtw_read8(padapter, REG_GPIO_PIN_CTRL_2 + 2) & ~BIT(index));
3662 } else
3663 RTW_INFO("%s: invalid GPIO%d\n", __func__, index);
3664
3665 }
3666
3667 #endif
3668
rtw_hal_set_FwAoacRsvdPage_cmd(PADAPTER padapter,PRSVDPAGE_LOC rsvdpageloc)3669 void rtw_hal_set_FwAoacRsvdPage_cmd(PADAPTER padapter, PRSVDPAGE_LOC rsvdpageloc)
3670 {
3671 struct hal_ops *pHalFunc = &padapter->hal_func;
3672 struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(padapter);
3673 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
3674 u8 res = 0, count = 0, ret = 0;
3675 #ifdef CONFIG_WOWLAN
3676 u8 u1H2CAoacRsvdPageParm[H2C_AOAC_RSVDPAGE_LOC_LEN] = {0};
3677
3678 RTW_INFO("%s: RWC: %d ArpRsp: %d NbrAdv: %d LocNDPInfo: %d\n",
3679 __func__, rsvdpageloc->LocRemoteCtrlInfo,
3680 rsvdpageloc->LocArpRsp, rsvdpageloc->LocNbrAdv,
3681 rsvdpageloc->LocNDPInfo);
3682 RTW_INFO("%s:GtkRsp: %d GtkInfo: %d ProbeReq: %d NetworkList: %d\n",
3683 __func__, rsvdpageloc->LocGTKRsp, rsvdpageloc->LocGTKInfo,
3684 rsvdpageloc->LocProbeReq, rsvdpageloc->LocNetList);
3685
3686 if (check_fwstate(pmlmepriv, _FW_LINKED)) {
3687 SET_H2CCMD_AOAC_RSVDPAGE_LOC_REMOTE_WAKE_CTRL_INFO(u1H2CAoacRsvdPageParm, rsvdpageloc->LocRemoteCtrlInfo);
3688 SET_H2CCMD_AOAC_RSVDPAGE_LOC_ARP_RSP(u1H2CAoacRsvdPageParm, rsvdpageloc->LocArpRsp);
3689 SET_H2CCMD_AOAC_RSVDPAGE_LOC_NEIGHBOR_ADV(u1H2CAoacRsvdPageParm,
3690 rsvdpageloc->LocNbrAdv);
3691 SET_H2CCMD_AOAC_RSVDPAGE_LOC_NDP_INFO(u1H2CAoacRsvdPageParm,
3692 rsvdpageloc->LocNDPInfo);
3693 #ifdef CONFIG_GTK_OL
3694 SET_H2CCMD_AOAC_RSVDPAGE_LOC_GTK_RSP(u1H2CAoacRsvdPageParm, rsvdpageloc->LocGTKRsp);
3695 SET_H2CCMD_AOAC_RSVDPAGE_LOC_GTK_INFO(u1H2CAoacRsvdPageParm, rsvdpageloc->LocGTKInfo);
3696 SET_H2CCMD_AOAC_RSVDPAGE_LOC_GTK_EXT_MEM(u1H2CAoacRsvdPageParm, rsvdpageloc->LocGTKEXTMEM);
3697 #endif /* CONFIG_GTK_OL */
3698 ret = rtw_hal_fill_h2c_cmd(padapter,
3699 H2C_AOAC_RSVD_PAGE,
3700 H2C_AOAC_RSVDPAGE_LOC_LEN,
3701 u1H2CAoacRsvdPageParm);
3702
3703 RTW_INFO("AOAC Report=%d\n", rsvdpageloc->LocAOACReport);
3704 _rtw_memset(&u1H2CAoacRsvdPageParm, 0, sizeof(u1H2CAoacRsvdPageParm));
3705 SET_H2CCMD_AOAC_RSVDPAGE_LOC_AOAC_REPORT(u1H2CAoacRsvdPageParm,
3706 rsvdpageloc->LocAOACReport);
3707 ret = rtw_hal_fill_h2c_cmd(padapter,
3708 H2C_AOAC_RSVDPAGE3,
3709 H2C_AOAC_RSVDPAGE_LOC_LEN,
3710 u1H2CAoacRsvdPageParm);
3711 pwrpriv->wowlan_aoac_rpt_loc = rsvdpageloc->LocAOACReport;
3712 }
3713 #ifdef CONFIG_PNO_SUPPORT
3714 else {
3715
3716 if (!pwrpriv->wowlan_in_resume) {
3717 RTW_INFO("NLO_INFO=%d\n", rsvdpageloc->LocPNOInfo);
3718 _rtw_memset(&u1H2CAoacRsvdPageParm, 0,
3719 sizeof(u1H2CAoacRsvdPageParm));
3720 SET_H2CCMD_AOAC_RSVDPAGE_LOC_NLO_INFO(u1H2CAoacRsvdPageParm,
3721 rsvdpageloc->LocPNOInfo);
3722 ret = rtw_hal_fill_h2c_cmd(padapter,
3723 H2C_AOAC_RSVDPAGE3,
3724 H2C_AOAC_RSVDPAGE_LOC_LEN,
3725 u1H2CAoacRsvdPageParm);
3726 }
3727 }
3728 #endif /* CONFIG_PNO_SUPPORT */
3729 #endif /* CONFIG_WOWLAN */
3730 }
3731
3732 /*#define DBG_GET_RSVD_PAGE*/
rtw_hal_get_rsvd_page(_adapter * adapter,u32 page_offset,u32 page_num,u8 * buffer,u32 buffer_size)3733 int rtw_hal_get_rsvd_page(_adapter *adapter, u32 page_offset,
3734 u32 page_num, u8 *buffer, u32 buffer_size)
3735 {
3736 u32 addr = 0, size = 0, count = 0;
3737 u32 page_size = 0, data_low = 0, data_high = 0;
3738 u16 txbndy = 0, offset = 0;
3739 u8 i = 0;
3740 bool rst = _FALSE;
3741
3742 rtw_hal_get_def_var(adapter, HAL_DEF_TX_PAGE_SIZE, &page_size);
3743
3744 addr = page_offset * page_size;
3745 size = page_num * page_size;
3746
3747 if (buffer_size < size) {
3748 RTW_ERR("%s buffer_size(%d) < get page total size(%d)\n",
3749 __func__, buffer_size, size);
3750 return rst;
3751 }
3752 #ifdef RTW_HALMAC
3753 if (rtw_halmac_dump_fifo(adapter_to_dvobj(adapter), 2, addr, size, buffer) < 0)
3754 rst = _FALSE;
3755 else
3756 rst = _TRUE;
3757 #else
3758 txbndy = rtw_read8(adapter, REG_TDECTRL + 1);
3759
3760 offset = (txbndy + page_offset) * page_size / 8;
3761 count = (buffer_size / 8) + 1;
3762
3763 rtw_write8(adapter, REG_PKT_BUFF_ACCESS_CTRL, 0x69);
3764
3765 for (i = 0 ; i < count ; i++) {
3766 rtw_write32(adapter, REG_PKTBUF_DBG_CTRL, offset + i);
3767 data_low = rtw_read32(adapter, REG_PKTBUF_DBG_DATA_L);
3768 data_high = rtw_read32(adapter, REG_PKTBUF_DBG_DATA_H);
3769 _rtw_memcpy(buffer + (i * 8),
3770 &data_low, sizeof(data_low));
3771 _rtw_memcpy(buffer + ((i * 8) + 4),
3772 &data_high, sizeof(data_high));
3773 }
3774 rtw_write8(adapter, REG_PKT_BUFF_ACCESS_CTRL, 0x0);
3775 rst = _TRUE;
3776 #endif /*RTW_HALMAC*/
3777
3778 #ifdef DBG_GET_RSVD_PAGE
3779 RTW_INFO("%s [page_offset:%d , page_num:%d][start_addr:0x%04x , size:%d]\n",
3780 __func__, page_offset, page_num, addr, size);
3781 RTW_INFO_DUMP("\n", buffer, size);
3782 RTW_INFO(" ==================================================\n");
3783 #endif
3784 return rst;
3785 }
3786
rtw_dump_rsvd_page(void * sel,_adapter * adapter,u8 page_offset,u8 page_num)3787 void rtw_dump_rsvd_page(void *sel, _adapter *adapter, u8 page_offset, u8 page_num)
3788 {
3789 u32 page_size = 0;
3790 u8 *buffer = NULL;
3791 u32 buf_size = 0;
3792
3793 if (page_num == 0)
3794 return;
3795
3796 RTW_PRINT_SEL(sel, "======= RSVG PAGE DUMP =======\n");
3797 RTW_PRINT_SEL(sel, "page_offset:%d, page_num:%d\n", page_offset, page_num);
3798
3799 rtw_hal_get_def_var(adapter, HAL_DEF_TX_PAGE_SIZE, &page_size);
3800 if (page_size) {
3801 buf_size = page_size * page_num;
3802 buffer = rtw_zvmalloc(buf_size);
3803
3804 if (buffer) {
3805 rtw_hal_get_rsvd_page(adapter, page_offset, page_num, buffer, buf_size);
3806 _RTW_DUMP_SEL(sel, buffer, buf_size);
3807 rtw_vmfree(buffer, buf_size);
3808 } else
3809 RTW_PRINT_SEL(sel, "ERROR - rsvd_buf mem allocate failed\n");
3810 } else
3811 RTW_PRINT_SEL(sel, "ERROR - Tx page size is zero ??\n");
3812
3813 RTW_PRINT_SEL(sel, "==========================\n");
3814 }
3815
3816 #ifdef CONFIG_SUPPORT_FIFO_DUMP
rtw_dump_fifo(void * sel,_adapter * adapter,u8 fifo_sel,u32 fifo_addr,u32 fifo_size)3817 void rtw_dump_fifo(void *sel, _adapter *adapter, u8 fifo_sel, u32 fifo_addr, u32 fifo_size)
3818 {
3819 u8 *buffer = NULL;
3820 u8 buff_size = 0;
3821 static const char * const fifo_sel_str[] = {
3822 "TX", "RX", "RSVD_PAGE", "REPORT", "LLT", "RXBUF_FW"
3823 };
3824
3825 if (fifo_sel > 5) {
3826 RTW_ERR("fifo_sel:%d invalid\n", fifo_sel);
3827 return;
3828 }
3829
3830 RTW_PRINT_SEL(sel, "========= FIFO DUMP =========\n");
3831 RTW_PRINT_SEL(sel, "%s FIFO DUMP [start_addr:0x%04x , size:%d]\n", fifo_sel_str[fifo_sel], fifo_addr, fifo_size);
3832
3833 if (fifo_size) {
3834 buff_size = RND4(fifo_size);
3835 buffer = rtw_zvmalloc(buff_size);
3836 if (buffer == NULL)
3837 buff_size = 0;
3838 }
3839
3840 rtw_halmac_dump_fifo(adapter_to_dvobj(adapter), fifo_sel, fifo_addr, buff_size, buffer);
3841
3842 if (buffer) {
3843 _RTW_DUMP_SEL(sel, buffer, fifo_size);
3844 rtw_vmfree(buffer, buff_size);
3845 }
3846
3847 RTW_PRINT_SEL(sel, "==========================\n");
3848 }
3849 #endif
3850
3851 #if defined(CONFIG_WOWLAN) || defined(CONFIG_AP_WOWLAN)
rtw_hal_force_enable_rxdma(_adapter * adapter)3852 static void rtw_hal_force_enable_rxdma(_adapter *adapter)
3853 {
3854 RTW_INFO("%s: Set 0x690=0x00\n", __func__);
3855 rtw_write8(adapter, REG_WOW_CTRL,
3856 (rtw_read8(adapter, REG_WOW_CTRL) & 0xf0));
3857 RTW_PRINT("%s: Release RXDMA\n", __func__);
3858 rtw_write32(adapter, REG_RXPKT_NUM,
3859 (rtw_read32(adapter, REG_RXPKT_NUM) & (~RW_RELEASE_EN)));
3860 }
3861 #if defined(CONFIG_RTL8188E)
rtw_hal_disable_tx_report(_adapter * adapter)3862 static void rtw_hal_disable_tx_report(_adapter *adapter)
3863 {
3864 rtw_write8(adapter, REG_TX_RPT_CTRL,
3865 ((rtw_read8(adapter, REG_TX_RPT_CTRL) & ~BIT(1))) & ~BIT(5));
3866 RTW_INFO("disable TXRPT:0x%02x\n", rtw_read8(adapter, REG_TX_RPT_CTRL));
3867 }
3868
rtw_hal_enable_tx_report(_adapter * adapter)3869 static void rtw_hal_enable_tx_report(_adapter *adapter)
3870 {
3871 rtw_write8(adapter, REG_TX_RPT_CTRL,
3872 ((rtw_read8(adapter, REG_TX_RPT_CTRL) | BIT(1))) | BIT(5));
3873 RTW_INFO("enable TX_RPT:0x%02x\n", rtw_read8(adapter, REG_TX_RPT_CTRL));
3874 }
3875 #endif
rtw_hal_release_rx_dma(_adapter * adapter)3876 static void rtw_hal_release_rx_dma(_adapter *adapter)
3877 {
3878 u32 val32 = 0;
3879
3880 val32 = rtw_read32(adapter, REG_RXPKT_NUM);
3881
3882 rtw_write32(adapter, REG_RXPKT_NUM, (val32 & (~RW_RELEASE_EN)));
3883
3884 RTW_INFO("%s, [0x%04x]: 0x%08x\n",
3885 __func__, REG_RXPKT_NUM, (val32 & (~RW_RELEASE_EN)));
3886 }
3887
rtw_hal_pause_rx_dma(_adapter * adapter)3888 static u8 rtw_hal_pause_rx_dma(_adapter *adapter)
3889 {
3890 PHAL_DATA_TYPE hal = GET_HAL_DATA(adapter);
3891 u8 ret = 0;
3892 s8 trycnt = 100;
3893 u32 tmp = 0;
3894 int res = 0;
3895 /* RX DMA stop */
3896 RTW_PRINT("Pause DMA\n");
3897 rtw_write32(adapter, REG_RXPKT_NUM,
3898 (rtw_read32(adapter, REG_RXPKT_NUM) | RW_RELEASE_EN));
3899 do {
3900 if ((rtw_read32(adapter, REG_RXPKT_NUM) & RXDMA_IDLE)) {
3901 #ifdef CONFIG_USB_HCI
3902 /* stop interface before leave */
3903 if (_TRUE == hal->usb_intf_start) {
3904 rtw_intf_stop(adapter);
3905 RTW_ENABLE_FUNC(adapter, DF_RX_BIT);
3906 RTW_ENABLE_FUNC(adapter, DF_TX_BIT);
3907 }
3908 #endif /* CONFIG_USB_HCI */
3909
3910 RTW_PRINT("RX_DMA_IDLE is true\n");
3911 ret = _SUCCESS;
3912 break;
3913 }
3914 #if defined(CONFIG_SDIO_HCI) || defined(CONFIG_GSPI_HCI)
3915 else {
3916 res = RecvOnePkt(adapter);
3917 RTW_PRINT("RecvOnePkt Result: %d\n", res);
3918 }
3919 #endif /* CONFIG_SDIO_HCI || CONFIG_GSPI_HCI */
3920
3921 #ifdef CONFIG_USB_HCI
3922 else {
3923 /* to avoid interface start repeatedly */
3924 if (_FALSE == hal->usb_intf_start)
3925 rtw_intf_start(adapter);
3926 }
3927 #endif /* CONFIG_USB_HCI */
3928 } while (trycnt--);
3929
3930 if (trycnt < 0) {
3931 tmp = rtw_read16(adapter, REG_RXPKT_NUM + 2);
3932
3933 RTW_PRINT("Stop RX DMA failed......\n");
3934 RTW_PRINT("%s, RXPKT_NUM: 0x%02x\n",
3935 __func__, ((tmp & 0xFF00) >> 8));
3936
3937 if (tmp & BIT(3))
3938 RTW_PRINT("%s, RX DMA has req\n",
3939 __func__);
3940 else
3941 RTW_PRINT("%s, RX DMA no req\n",
3942 __func__);
3943 ret = _FAIL;
3944 }
3945
3946 return ret;
3947 }
3948
3949 #if defined(CONFIG_SDIO_HCI) || defined(CONFIG_GSPI_HCI)
3950 #ifndef RTW_HALMAC
rtw_hal_enable_cpwm2(_adapter * adapter)3951 static u8 rtw_hal_enable_cpwm2(_adapter *adapter)
3952 {
3953 u8 ret = 0;
3954 int res = 0;
3955 u32 tmp = 0;
3956 #ifdef CONFIG_GPIO_WAKEUP
3957 return _SUCCESS;
3958 #else
3959 RTW_PRINT("%s\n", __func__);
3960
3961 res = sdio_local_read(adapter, SDIO_REG_HIMR, 4, (u8 *)&tmp);
3962 if (!res)
3963 RTW_INFO("read SDIO_REG_HIMR: 0x%08x\n", tmp);
3964 else
3965 RTW_INFO("sdio_local_read fail\n");
3966
3967 tmp = SDIO_HIMR_CPWM2_MSK;
3968
3969 res = sdio_local_write(adapter, SDIO_REG_HIMR, 4, (u8 *)&tmp);
3970
3971 if (!res) {
3972 res = sdio_local_read(adapter, SDIO_REG_HIMR, 4, (u8 *)&tmp);
3973 RTW_INFO("read again SDIO_REG_HIMR: 0x%08x\n", tmp);
3974 ret = _SUCCESS;
3975 } else {
3976 RTW_INFO("sdio_local_write fail\n");
3977 ret = _FAIL;
3978 }
3979 return ret;
3980 #endif /* CONFIG_CPIO_WAKEUP */
3981 }
3982 #endif
3983 #endif /* CONFIG_SDIO_HCI, CONFIG_GSPI_HCI */
3984 #endif /* CONFIG_WOWLAN || CONFIG_AP_WOWLAN */
3985
3986 #ifdef CONFIG_WOWLAN
3987 /*
3988 * rtw_hal_check_wow_ctrl
3989 * chk_type: _TRUE means to check enable, if 0x690 & bit1 (for 8051), WOW enable successful.
3990 * If 0x1C7 == 0 (for 3081), WOW enable successful.
3991 * _FALSE means to check disable, if 0x690 & bit1 (for 8051), WOW disable fail.
3992 * If 0x120 & bit16 || 0x284 & bit18 (for 3081), WOW disable fail.
3993 */
rtw_hal_check_wow_ctrl(_adapter * adapter,u8 chk_type)3994 static u8 rtw_hal_check_wow_ctrl(_adapter *adapter, u8 chk_type)
3995 {
3996 u32 fe1_imr = 0xFF, rxpkt_num = 0xFF;
3997 u8 mstatus = 0;
3998 u8 reason = 0xFF;
3999 u8 trycnt = 25;
4000 u8 res = _FALSE;
4001
4002 if (IS_HARDWARE_TYPE_JAGUAR2(adapter)) {
4003 if (chk_type) {
4004 reason = rtw_read8(adapter, REG_WOWLAN_WAKE_REASON);
4005 RTW_INFO("%s reason:0x%02x\n", __func__, reason);
4006
4007 while (reason && trycnt > 1) {
4008 reason = rtw_read8(adapter, REG_WOWLAN_WAKE_REASON);
4009 RTW_PRINT("Loop index: %d :0x%02x\n",
4010 trycnt, reason);
4011 trycnt--;
4012 rtw_msleep_os(20);
4013 }
4014 if (!reason)
4015 res = _TRUE;
4016 else
4017 res = _FALSE;
4018 } else {
4019 /* Wait FW to cleare 0x120 bit16, 0x284 bit18 to 0 */
4020 fe1_imr = rtw_read32(adapter, REG_FE1IMR); /* RxDone IMR for 3081 */
4021 rxpkt_num = rtw_read32(adapter, REG_RXPKT_NUM); /* Release RXDMA */
4022 RTW_PRINT("%s REG_FE1IMR (reg120): 0x%x, REG_RXPKT_NUM(reg284): 0x%x\n", __func__, fe1_imr, rxpkt_num);
4023
4024 while (((fe1_imr & BIT_FS_RXDONE_INT_EN) || (rxpkt_num & BIT_RW_RELEASE_EN)) && trycnt > 1) {
4025 rtw_msleep_os(20);
4026 fe1_imr = rtw_read32(adapter, REG_FE1IMR);
4027 rxpkt_num = rtw_read32(adapter, REG_RXPKT_NUM);
4028 RTW_PRINT("Loop index: %d :0x%x, 0x%x\n",
4029 trycnt, fe1_imr, rxpkt_num);
4030 trycnt--;
4031 }
4032
4033 if ((fe1_imr & BIT_FS_RXDONE_INT_EN) || (rxpkt_num & BIT_RW_RELEASE_EN))
4034 res = _FALSE;
4035 else
4036 res = _TRUE;
4037 }
4038 } else {
4039 mstatus = rtw_read8(adapter, REG_WOW_CTRL);
4040 RTW_INFO("%s mstatus:0x%02x\n", __func__, mstatus);
4041
4042
4043 if (chk_type) {
4044 while (!(mstatus & BIT1) && trycnt > 1) {
4045 mstatus = rtw_read8(adapter, REG_WOW_CTRL);
4046 RTW_PRINT("Loop index: %d :0x%02x\n",
4047 trycnt, mstatus);
4048 trycnt--;
4049 rtw_msleep_os(20);
4050 }
4051 if (mstatus & BIT1)
4052 res = _TRUE;
4053 else
4054 res = _FALSE;
4055 } else {
4056 while (mstatus & BIT1 && trycnt > 1) {
4057 mstatus = rtw_read8(adapter, REG_WOW_CTRL);
4058 RTW_PRINT("Loop index: %d :0x%02x\n",
4059 trycnt, mstatus);
4060 trycnt--;
4061 rtw_msleep_os(20);
4062 }
4063
4064 if (mstatus & BIT1)
4065 res = _FALSE;
4066 else
4067 res = _TRUE;
4068 }
4069 }
4070
4071 RTW_PRINT("%s check_type: %d res: %d trycnt: %d\n",
4072 __func__, chk_type, res, (25 - trycnt));
4073 return res;
4074 }
4075
4076 #ifdef CONFIG_PNO_SUPPORT
rtw_hal_check_pno_enabled(_adapter * adapter)4077 static u8 rtw_hal_check_pno_enabled(_adapter *adapter)
4078 {
4079 struct pwrctrl_priv *ppwrpriv = adapter_to_pwrctl(adapter);
4080 u8 res = 0, count = 0;
4081 u8 ret = _FALSE;
4082
4083 if (ppwrpriv->wowlan_pno_enable && ppwrpriv->wowlan_in_resume == _FALSE) {
4084 res = rtw_read8(adapter, REG_PNO_STATUS);
4085 while (!(res & BIT(7)) && count < 25) {
4086 RTW_INFO("[%d] cmd: 0x81 REG_PNO_STATUS: 0x%02x\n",
4087 count, res);
4088 res = rtw_read8(adapter, REG_PNO_STATUS);
4089 count++;
4090 rtw_msleep_os(2);
4091 }
4092 if (res & BIT(7))
4093 ret = _TRUE;
4094 else
4095 ret = _FALSE;
4096 RTW_INFO("cmd: 0x81 REG_PNO_STATUS: ret(%d)\n", ret);
4097 }
4098 return ret;
4099 }
4100 #endif
4101
rtw_hal_backup_rate(_adapter * adapter)4102 static void rtw_hal_backup_rate(_adapter *adapter)
4103 {
4104 RTW_INFO("%s\n", __func__);
4105 /* backup data rate to register 0x8b for wowlan FW */
4106 rtw_write8(adapter, 0x8d, 1);
4107 rtw_write8(adapter, 0x8c, 0);
4108 rtw_write8(adapter, 0x8f, 0x40);
4109 rtw_write8(adapter, 0x8b, rtw_read8(adapter, 0x2f0));
4110 }
4111
4112 #ifdef CONFIG_GTK_OL
rtw_hal_fw_sync_cam_id(_adapter * adapter)4113 static void rtw_hal_fw_sync_cam_id(_adapter *adapter)
4114 {
4115 struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
4116 int cam_id, index = 0;
4117 u8 *addr = NULL;
4118
4119 if (!MLME_IS_STA(adapter))
4120 return;
4121
4122 addr = get_bssid(pmlmepriv);
4123
4124 if (addr == NULL) {
4125 RTW_INFO("%s: get bssid MAC addr fail!!\n", __func__);
4126 return;
4127 }
4128
4129 rtw_clean_dk_section(adapter);
4130
4131 do {
4132 cam_id = rtw_camid_search(adapter, addr, index, 1);
4133
4134 if (cam_id == -1)
4135 RTW_INFO("%s: cam_id: %d, key_id:%d\n", __func__, cam_id, index);
4136 else
4137 rtw_sec_cam_swap(adapter, cam_id, index);
4138
4139 index++;
4140 } while (index < 4);
4141
4142 rtw_write8(adapter, REG_SECCFG, 0xcc);
4143 }
4144
rtw_hal_update_gtk_offload_info(_adapter * adapter)4145 static void rtw_hal_update_gtk_offload_info(_adapter *adapter)
4146 {
4147 struct pwrctrl_priv *pwrctl = adapter_to_pwrctl(adapter);
4148 struct aoac_report *paoac_rpt = &pwrctl->wowlan_aoac_rpt;
4149 struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
4150 struct security_priv *psecuritypriv = &adapter->securitypriv;
4151 struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
4152 struct cam_ctl_t *cam_ctl = &dvobj->cam_ctl;
4153 _irqL irqL;
4154 u8 get_key[16];
4155 u8 gtk_id = 0, offset = 0, i = 0, sz = 0;
4156 u64 replay_count = 0, tmp_iv_hdr = 0, pkt_pn = 0;
4157
4158 if (!MLME_IS_STA(adapter))
4159 return;
4160
4161 _rtw_memset(get_key, 0, sizeof(get_key));
4162 _rtw_memcpy(&replay_count,
4163 paoac_rpt->replay_counter_eapol_key, 8);
4164
4165 /*read gtk key index*/
4166 gtk_id = paoac_rpt->key_index;
4167
4168 if (gtk_id == 5 || gtk_id == 0) {
4169 RTW_INFO("%s no rekey event happened.\n", __func__);
4170 } else if (gtk_id > 0 && gtk_id < 4) {
4171 RTW_INFO("%s update security key.\n", __func__);
4172 /*read key from sec-cam,for DK ,keyindex is equal to cam-id*/
4173 rtw_sec_read_cam_ent(adapter, gtk_id,
4174 NULL, NULL, get_key);
4175 rtw_clean_hw_dk_cam(adapter);
4176
4177 if (_rtw_camid_is_gk(adapter, gtk_id)) {
4178 _enter_critical_bh(&cam_ctl->lock, &irqL);
4179 _rtw_memcpy(&dvobj->cam_cache[gtk_id].key,
4180 get_key, 16);
4181 _exit_critical_bh(&cam_ctl->lock, &irqL);
4182 } else {
4183 struct setkey_parm parm_gtk;
4184
4185 parm_gtk.algorithm = paoac_rpt->security_type;
4186 parm_gtk.keyid = gtk_id;
4187 _rtw_memcpy(parm_gtk.key, get_key, 16);
4188 setkey_hdl(adapter, (u8 *)&parm_gtk);
4189 }
4190
4191 /*update key into related sw variable and sec-cam cache*/
4192 psecuritypriv->dot118021XGrpKeyid = gtk_id;
4193 _rtw_memcpy(&psecuritypriv->dot118021XGrpKey[gtk_id],
4194 get_key, 16);
4195 /* update SW TKIP TX/RX MIC value */
4196 if (psecuritypriv->dot118021XGrpPrivacy == _TKIP_) {
4197 offset = RTW_KEK_LEN + RTW_TKIP_MIC_LEN;
4198 _rtw_memcpy(
4199 &psecuritypriv->dot118021XGrptxmickey[gtk_id],
4200 &(paoac_rpt->group_key[offset]),
4201 RTW_TKIP_MIC_LEN);
4202
4203 offset = RTW_KEK_LEN;
4204 _rtw_memcpy(
4205 &psecuritypriv->dot118021XGrprxmickey[gtk_id],
4206 &(paoac_rpt->group_key[offset]),
4207 RTW_TKIP_MIC_LEN);
4208 }
4209 RTW_PRINT("GTK (%d) "KEY_FMT"\n", gtk_id,
4210 KEY_ARG(psecuritypriv->dot118021XGrpKey[gtk_id].skey));
4211 }
4212
4213 /* Update broadcast RX IV */
4214 if (psecuritypriv->dot118021XGrpPrivacy == _AES_) {
4215 sz = sizeof(psecuritypriv->iv_seq[0]);
4216 for (i = 0 ; i < 4 ; i++) {
4217 _rtw_memcpy(&tmp_iv_hdr, paoac_rpt->rxgtk_iv[i], sz);
4218 tmp_iv_hdr = le64_to_cpu(tmp_iv_hdr);
4219 pkt_pn = CCMPH_2_PN(tmp_iv_hdr);
4220 _rtw_memcpy(psecuritypriv->iv_seq[i], &pkt_pn, sz);
4221 }
4222 }
4223
4224 rtw_clean_dk_section(adapter);
4225
4226 rtw_write8(adapter, REG_SECCFG, 0x0c);
4227
4228 #ifdef CONFIG_GTK_OL_DBG
4229 /* if (gtk_keyindex != 5) */
4230 dump_sec_cam(RTW_DBGDUMP, adapter);
4231 dump_sec_cam_cache(RTW_DBGDUMP, adapter);
4232 #endif
4233 }
4234 #endif /*CONFIG_GTK_OL*/
4235
rtw_dump_aoac_rpt(_adapter * adapter)4236 static void rtw_dump_aoac_rpt(_adapter *adapter)
4237 {
4238 struct pwrctrl_priv *pwrctl = adapter_to_pwrctl(adapter);
4239 struct aoac_report *paoac_rpt = &pwrctl->wowlan_aoac_rpt;
4240 int i = 0;
4241
4242 RTW_INFO_DUMP("[AOAC-RPT] IV -", paoac_rpt->iv, 8);
4243 RTW_INFO_DUMP("[AOAC-RPT] Replay counter of EAPOL key - ",
4244 paoac_rpt->replay_counter_eapol_key, 8);
4245 RTW_INFO_DUMP("[AOAC-RPT] Group key - ", paoac_rpt->group_key, 32);
4246 RTW_INFO("[AOAC-RPT] Key Index - %d\n", paoac_rpt->key_index);
4247 RTW_INFO("[AOAC-RPT] Security Type - %d\n", paoac_rpt->security_type);
4248 RTW_INFO("[AOAC-RPT] wow_pattern_idx - %d\n",
4249 paoac_rpt->wow_pattern_idx);
4250 RTW_INFO("[AOAC-RPT] version_info - %d\n", paoac_rpt->version_info);
4251 RTW_INFO_DUMP("[AOAC-RPT] RX PTK IV-", paoac_rpt->rxptk_iv, 8);
4252 RTW_INFO_DUMP("[AOAC-RPT] RX GTK[0] IV-", paoac_rpt->rxgtk_iv[0], 8);
4253 RTW_INFO_DUMP("[AOAC-RPT] RX GTK[1] IV-", paoac_rpt->rxgtk_iv[1], 8);
4254 RTW_INFO_DUMP("[AOAC-RPT] RX GTK[2] IV-", paoac_rpt->rxgtk_iv[2], 8);
4255 RTW_INFO_DUMP("[AOAC-RPT] RX GTK[3] IV-", paoac_rpt->rxgtk_iv[3], 8);
4256 }
4257
rtw_hal_get_aoac_rpt(_adapter * adapter)4258 static void rtw_hal_get_aoac_rpt(_adapter *adapter)
4259 {
4260 struct pwrctrl_priv *pwrctl = adapter_to_pwrctl(adapter);
4261 struct aoac_report *paoac_rpt = &pwrctl->wowlan_aoac_rpt;
4262 u32 page_offset = 0, page_number = 0;
4263 u32 page_size = 0, buf_size = 0;
4264 u8 *buffer = NULL;
4265 u8 i = 0, tmp = 0;
4266 int ret = -1;
4267
4268 /* read aoac report from rsvd page */
4269 page_offset = pwrctl->wowlan_aoac_rpt_loc;
4270 page_number = 1;
4271
4272 rtw_hal_get_def_var(adapter, HAL_DEF_TX_PAGE_SIZE, &page_size);
4273 buf_size = page_size * page_number;
4274
4275 buffer = rtw_zvmalloc(buf_size);
4276
4277 if (buffer == NULL) {
4278 RTW_ERR("%s buffer allocate failed size(%d)\n",
4279 __func__, buf_size);
4280 return;
4281 }
4282
4283 RTW_INFO("Get AOAC Report from rsvd page_offset:%d\n", page_offset);
4284
4285 ret = rtw_hal_get_rsvd_page(adapter, page_offset,
4286 page_number, buffer, buf_size);
4287
4288 if (ret == _FALSE) {
4289 RTW_ERR("%s get aoac report failed\n", __func__);
4290 rtw_warn_on(1);
4291 goto _exit;
4292 }
4293
4294 _rtw_memset(paoac_rpt, 0, sizeof(struct aoac_report));
4295 _rtw_memcpy(paoac_rpt, buffer, sizeof(struct aoac_report));
4296
4297 for (i = 0 ; i < 4 ; i++) {
4298 tmp = paoac_rpt->replay_counter_eapol_key[i];
4299 paoac_rpt->replay_counter_eapol_key[i] =
4300 paoac_rpt->replay_counter_eapol_key[7 - i];
4301 paoac_rpt->replay_counter_eapol_key[7 - i] = tmp;
4302 }
4303
4304 rtw_dump_aoac_rpt(adapter);
4305
4306 _exit:
4307 if (buffer)
4308 rtw_vmfree(buffer, buf_size);
4309 }
4310
rtw_hal_update_tx_iv(_adapter * adapter)4311 static void rtw_hal_update_tx_iv(_adapter *adapter)
4312 {
4313 struct pwrctrl_priv *pwrctl = adapter_to_pwrctl(adapter);
4314 struct aoac_report *paoac_rpt = &pwrctl->wowlan_aoac_rpt;
4315 struct sta_info *psta;
4316 struct mlme_ext_priv *pmlmeext = &(adapter->mlmeextpriv);
4317 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
4318 struct security_priv *psecpriv = &adapter->securitypriv;
4319
4320 u16 val16 = 0;
4321 u32 val32 = 0;
4322 u64 txiv = 0;
4323 u8 *pval = NULL;
4324
4325 psta = rtw_get_stainfo(&adapter->stapriv,
4326 get_my_bssid(&pmlmeinfo->network));
4327
4328 /* Update TX iv data. */
4329 pval = (u8 *)&paoac_rpt->iv;
4330
4331 if (psecpriv->dot11PrivacyAlgrthm == _TKIP_) {
4332 val16 = ((u16)(paoac_rpt->iv[2]) << 0) +
4333 ((u16)(paoac_rpt->iv[0]) << 8);
4334 val32 = ((u32)(paoac_rpt->iv[4]) << 0) +
4335 ((u32)(paoac_rpt->iv[5]) << 8) +
4336 ((u32)(paoac_rpt->iv[6]) << 16) +
4337 ((u32)(paoac_rpt->iv[7]) << 24);
4338 } else if (psecpriv->dot11PrivacyAlgrthm == _AES_) {
4339 val16 = ((u16)(paoac_rpt->iv[0]) << 0) +
4340 ((u16)(paoac_rpt->iv[1]) << 8);
4341 val32 = ((u32)(paoac_rpt->iv[4]) << 0) +
4342 ((u32)(paoac_rpt->iv[5]) << 8) +
4343 ((u32)(paoac_rpt->iv[6]) << 16) +
4344 ((u32)(paoac_rpt->iv[7]) << 24);
4345 }
4346
4347 if (psta) {
4348 txiv = val16 + ((u64)val32 << 16);
4349 if (txiv != 0)
4350 psta->dot11txpn.val = txiv;
4351 }
4352 }
4353
rtw_hal_update_sw_security_info(_adapter * adapter)4354 static void rtw_hal_update_sw_security_info(_adapter *adapter)
4355 {
4356 struct security_priv *psecpriv = &adapter->securitypriv;
4357 u8 sz = sizeof (psecpriv->iv_seq);
4358
4359 rtw_hal_update_tx_iv(adapter);
4360 #ifdef CONFIG_GTK_OL
4361 if (psecpriv->binstallKCK_KEK == _TRUE &&
4362 psecpriv->ndisauthtype == Ndis802_11AuthModeWPA2PSK)
4363 rtw_hal_update_gtk_offload_info(adapter);
4364 #else
4365 _rtw_memset(psecpriv->iv_seq, 0, sz);
4366 #endif
4367 }
4368
rtw_hal_set_keep_alive_cmd(_adapter * adapter,u8 enable,u8 pkt_type)4369 static u8 rtw_hal_set_keep_alive_cmd(_adapter *adapter, u8 enable, u8 pkt_type)
4370 {
4371 struct hal_ops *pHalFunc = &adapter->hal_func;
4372
4373 u8 u1H2CKeepAliveParm[H2C_KEEP_ALIVE_CTRL_LEN] = {0};
4374 u8 adopt = 1, check_period = 5;
4375 u8 ret = _FAIL;
4376
4377 SET_H2CCMD_KEEPALIVE_PARM_ENABLE(u1H2CKeepAliveParm, enable);
4378 SET_H2CCMD_KEEPALIVE_PARM_ADOPT(u1H2CKeepAliveParm, adopt);
4379 SET_H2CCMD_KEEPALIVE_PARM_PKT_TYPE(u1H2CKeepAliveParm, pkt_type);
4380 SET_H2CCMD_KEEPALIVE_PARM_CHECK_PERIOD(u1H2CKeepAliveParm, check_period);
4381 #ifdef CONFIG_FW_MULTI_PORT_SUPPORT
4382 SET_H2CCMD_KEEPALIVE_PARM_PORT_NUM(u1H2CKeepAliveParm, adapter->hw_port);
4383 RTW_INFO("%s(): enable = %d, port = %d\n", __func__, enable, adapter->hw_port);
4384 #else
4385 RTW_INFO("%s(): enable = %d\n", __func__, enable);
4386 #endif
4387 ret = rtw_hal_fill_h2c_cmd(adapter,
4388 H2C_KEEP_ALIVE,
4389 H2C_KEEP_ALIVE_CTRL_LEN,
4390 u1H2CKeepAliveParm);
4391
4392 return ret;
4393 }
4394
rtw_hal_set_disconnect_decision_cmd(_adapter * adapter,u8 enable)4395 static u8 rtw_hal_set_disconnect_decision_cmd(_adapter *adapter, u8 enable)
4396 {
4397 struct hal_ops *pHalFunc = &adapter->hal_func;
4398 u8 u1H2CDisconDecisionParm[H2C_DISCON_DECISION_LEN] = {0};
4399 u8 adopt = 1, check_period = 30, trypkt_num = 5;
4400 u8 ret = _FAIL;
4401
4402 SET_H2CCMD_DISCONDECISION_PARM_ENABLE(u1H2CDisconDecisionParm, enable);
4403 SET_H2CCMD_DISCONDECISION_PARM_ADOPT(u1H2CDisconDecisionParm, adopt);
4404 SET_H2CCMD_DISCONDECISION_PARM_CHECK_PERIOD(u1H2CDisconDecisionParm, check_period);
4405 SET_H2CCMD_DISCONDECISION_PARM_TRY_PKT_NUM(u1H2CDisconDecisionParm, trypkt_num);
4406 #ifdef CONFIG_FW_MULTI_PORT_SUPPORT
4407 SET_H2CCMD_DISCONDECISION_PORT_NUM(u1H2CDisconDecisionParm, adapter->hw_port);
4408 RTW_INFO("%s(): enable = %d, port = %d\n", __func__, enable, adapter->hw_port);
4409 #else
4410 RTW_INFO("%s(): enable = %d\n", __func__, enable);
4411 #endif
4412
4413 ret = rtw_hal_fill_h2c_cmd(adapter,
4414 H2C_DISCON_DECISION,
4415 H2C_DISCON_DECISION_LEN,
4416 u1H2CDisconDecisionParm);
4417 return ret;
4418 }
4419
rtw_hal_set_wowlan_ctrl_cmd(_adapter * adapter,u8 enable,u8 change_unit)4420 static u8 rtw_hal_set_wowlan_ctrl_cmd(_adapter *adapter, u8 enable, u8 change_unit)
4421 {
4422 struct registry_priv *registry_par = &adapter->registrypriv;
4423 struct security_priv *psecpriv = &adapter->securitypriv;
4424 struct pwrctrl_priv *ppwrpriv = adapter_to_pwrctl(adapter);
4425 struct hal_ops *pHalFunc = &adapter->hal_func;
4426
4427 u8 u1H2CWoWlanCtrlParm[H2C_WOWLAN_LEN] = {0};
4428 u8 discont_wake = 0, gpionum = 0, gpio_dur = 0;
4429 u8 hw_unicast = 0, gpio_pulse_cnt = 0, gpio_pulse_en = 0;
4430 u8 sdio_wakeup_enable = 1;
4431 u8 gpio_high_active = 0;
4432 u8 magic_pkt = 0;
4433 u8 gpio_unit = 0; /*0: 64ns, 1: 8ms*/
4434 u8 ret = _FAIL;
4435
4436 #ifdef CONFIG_GPIO_WAKEUP
4437 gpio_high_active = ppwrpriv->is_high_active;
4438 gpionum = WAKEUP_GPIO_IDX;
4439 sdio_wakeup_enable = 0;
4440 #endif /* CONFIG_GPIO_WAKEUP */
4441
4442 if (!ppwrpriv->wowlan_pno_enable &&
4443 registry_par->wakeup_event & BIT(0))
4444 magic_pkt = enable;
4445
4446 if ((registry_par->wakeup_event & BIT(1)) &&
4447 (psecpriv->dot11PrivacyAlgrthm == _WEP40_ ||
4448 psecpriv->dot11PrivacyAlgrthm == _WEP104_))
4449 hw_unicast = 1;
4450
4451 if (registry_par->wakeup_event & BIT(2))
4452 discont_wake = enable;
4453
4454 RTW_INFO("%s(): enable=%d change_unit=%d\n", __func__,
4455 enable, change_unit);
4456
4457 /* time = (gpio_dur/2) * gpio_unit, default:256 ms */
4458 if (enable && change_unit) {
4459 gpio_dur = 0x40;
4460 gpio_unit = 1;
4461 gpio_pulse_en = 1;
4462 }
4463
4464 #ifdef CONFIG_PLATFORM_ARM_RK3188
4465 if (enable) {
4466 gpio_pulse_en = 1;
4467 gpio_pulse_cnt = 0x04;
4468 }
4469 #endif
4470
4471 SET_H2CCMD_WOWLAN_FUNC_ENABLE(u1H2CWoWlanCtrlParm, enable);
4472 SET_H2CCMD_WOWLAN_PATTERN_MATCH_ENABLE(u1H2CWoWlanCtrlParm, enable);
4473 SET_H2CCMD_WOWLAN_MAGIC_PKT_ENABLE(u1H2CWoWlanCtrlParm, magic_pkt);
4474 SET_H2CCMD_WOWLAN_UNICAST_PKT_ENABLE(u1H2CWoWlanCtrlParm, hw_unicast);
4475 SET_H2CCMD_WOWLAN_ALL_PKT_DROP(u1H2CWoWlanCtrlParm, 0);
4476 SET_H2CCMD_WOWLAN_GPIO_ACTIVE(u1H2CWoWlanCtrlParm, gpio_high_active);
4477
4478 #ifdef CONFIG_GTK_OL
4479 if (psecpriv->binstallKCK_KEK == _TRUE &&
4480 psecpriv->ndisauthtype == Ndis802_11AuthModeWPA2PSK)
4481 SET_H2CCMD_WOWLAN_REKEY_WAKE_UP(u1H2CWoWlanCtrlParm, 0);
4482 else
4483 SET_H2CCMD_WOWLAN_REKEY_WAKE_UP(u1H2CWoWlanCtrlParm, 1);
4484 #else
4485 SET_H2CCMD_WOWLAN_REKEY_WAKE_UP(u1H2CWoWlanCtrlParm, enable);
4486 #endif
4487 SET_H2CCMD_WOWLAN_DISCONNECT_WAKE_UP(u1H2CWoWlanCtrlParm, discont_wake);
4488 SET_H2CCMD_WOWLAN_GPIONUM(u1H2CWoWlanCtrlParm, gpionum);
4489 SET_H2CCMD_WOWLAN_DATAPIN_WAKE_UP(u1H2CWoWlanCtrlParm, sdio_wakeup_enable);
4490
4491 SET_H2CCMD_WOWLAN_GPIO_DURATION(u1H2CWoWlanCtrlParm, gpio_dur);
4492 SET_H2CCMD_WOWLAN_CHANGE_UNIT(u1H2CWoWlanCtrlParm, gpio_unit);
4493
4494 SET_H2CCMD_WOWLAN_GPIO_PULSE_EN(u1H2CWoWlanCtrlParm, gpio_pulse_en);
4495 SET_H2CCMD_WOWLAN_GPIO_PULSE_COUNT(u1H2CWoWlanCtrlParm, gpio_pulse_cnt);
4496
4497 #ifdef CONFIG_WAKEUP_GPIO_INPUT_MODE
4498 if (enable)
4499 SET_H2CCMD_WOWLAN_GPIO_INPUT_EN(u1H2CWoWlanCtrlParm, 1);
4500 #endif
4501 ret = rtw_hal_fill_h2c_cmd(adapter,
4502 H2C_WOWLAN,
4503 H2C_WOWLAN_LEN,
4504 u1H2CWoWlanCtrlParm);
4505 return ret;
4506 }
4507
rtw_hal_set_remote_wake_ctrl_cmd(_adapter * adapter,u8 enable)4508 static u8 rtw_hal_set_remote_wake_ctrl_cmd(_adapter *adapter, u8 enable)
4509 {
4510 struct hal_ops *pHalFunc = &adapter->hal_func;
4511 struct security_priv *psecuritypriv = &(adapter->securitypriv);
4512 struct pwrctrl_priv *ppwrpriv = adapter_to_pwrctl(adapter);
4513 struct registry_priv *pregistrypriv = &adapter->registrypriv;
4514 u8 u1H2CRemoteWakeCtrlParm[H2C_REMOTE_WAKE_CTRL_LEN] = {0};
4515 u8 ret = _FAIL, count = 0;
4516
4517 RTW_INFO("%s(): enable=%d\n", __func__, enable);
4518
4519 if (!ppwrpriv->wowlan_pno_enable) {
4520 SET_H2CCMD_REMOTE_WAKECTRL_ENABLE(
4521 u1H2CRemoteWakeCtrlParm, enable);
4522 SET_H2CCMD_REMOTE_WAKE_CTRL_ARP_OFFLOAD_EN(
4523 u1H2CRemoteWakeCtrlParm, 1);
4524 #ifdef CONFIG_GTK_OL
4525 if (psecuritypriv->binstallKCK_KEK == _TRUE &&
4526 psecuritypriv->ndisauthtype == Ndis802_11AuthModeWPA2PSK) {
4527 SET_H2CCMD_REMOTE_WAKE_CTRL_GTK_OFFLOAD_EN(
4528 u1H2CRemoteWakeCtrlParm, 1);
4529 } else {
4530 RTW_INFO("no kck kek\n");
4531 SET_H2CCMD_REMOTE_WAKE_CTRL_GTK_OFFLOAD_EN(
4532 u1H2CRemoteWakeCtrlParm, 0);
4533 }
4534 #endif /* CONFIG_GTK_OL */
4535
4536 #ifdef CONFIG_IPV6
4537 if (ppwrpriv->wowlan_ns_offload_en == _TRUE) {
4538 RTW_INFO("enable NS offload\n");
4539 SET_H2CCMD_REMOTE_WAKE_CTRL_NDP_OFFLOAD_EN(
4540 u1H2CRemoteWakeCtrlParm, enable);
4541 }
4542
4543 /*
4544 * filter NetBios name service pkt to avoid being waked-up
4545 * by this kind of unicast pkt this exceptional modification
4546 * is used for match competitor's behavior
4547 */
4548
4549 SET_H2CCMD_REMOTE_WAKE_CTRL_NBNS_FILTER_EN(
4550 u1H2CRemoteWakeCtrlParm, enable);
4551 #endif /*CONFIG_IPV6*/
4552
4553 if ((psecuritypriv->dot11PrivacyAlgrthm == _AES_) ||
4554 (psecuritypriv->dot11PrivacyAlgrthm == _TKIP_) ||
4555 (psecuritypriv->dot11PrivacyAlgrthm == _NO_PRIVACY_)) {
4556 SET_H2CCMD_REMOTE_WAKE_CTRL_ARP_ACTION(
4557 u1H2CRemoteWakeCtrlParm, 0);
4558 } else {
4559 SET_H2CCMD_REMOTE_WAKE_CTRL_ARP_ACTION(
4560 u1H2CRemoteWakeCtrlParm, 1);
4561 }
4562
4563 if (psecuritypriv->dot11PrivacyAlgrthm == _TKIP_ &&
4564 psecuritypriv->ndisauthtype == Ndis802_11AuthModeWPA2PSK) {
4565 SET_H2CCMD_REMOTE_WAKE_CTRL_TKIP_OFFLOAD_EN(
4566 u1H2CRemoteWakeCtrlParm, enable);
4567
4568 if (IS_HARDWARE_TYPE_8188E(adapter) ||
4569 IS_HARDWARE_TYPE_8812(adapter)) {
4570 SET_H2CCMD_REMOTE_WAKE_CTRL_TKIP_OFFLOAD_EN(
4571 u1H2CRemoteWakeCtrlParm, 0);
4572 SET_H2CCMD_REMOTE_WAKE_CTRL_ARP_ACTION(
4573 u1H2CRemoteWakeCtrlParm, 1);
4574 }
4575 }
4576
4577 SET_H2CCMD_REMOTE_WAKE_CTRL_FW_PARSING_UNTIL_WAKEUP(
4578 u1H2CRemoteWakeCtrlParm, 1);
4579 }
4580 #ifdef CONFIG_PNO_SUPPORT
4581 else {
4582 SET_H2CCMD_REMOTE_WAKECTRL_ENABLE(
4583 u1H2CRemoteWakeCtrlParm, enable);
4584 SET_H2CCMD_REMOTE_WAKE_CTRL_NLO_OFFLOAD_EN(
4585 u1H2CRemoteWakeCtrlParm, enable);
4586 }
4587 #endif
4588
4589 #ifdef CONFIG_P2P_WOWLAN
4590 if (_TRUE == ppwrpriv->wowlan_p2p_mode) {
4591 RTW_INFO("P2P OFFLOAD ENABLE\n");
4592 SET_H2CCMD_REMOTE_WAKE_CTRL_P2P_OFFLAD_EN(u1H2CRemoteWakeCtrlParm, 1);
4593 } else {
4594 RTW_INFO("P2P OFFLOAD DISABLE\n");
4595 SET_H2CCMD_REMOTE_WAKE_CTRL_P2P_OFFLAD_EN(u1H2CRemoteWakeCtrlParm, 0);
4596 }
4597 #endif /* CONFIG_P2P_WOWLAN */
4598
4599
4600 ret = rtw_hal_fill_h2c_cmd(adapter,
4601 H2C_REMOTE_WAKE_CTRL,
4602 H2C_REMOTE_WAKE_CTRL_LEN,
4603 u1H2CRemoteWakeCtrlParm);
4604 return ret;
4605 }
4606
rtw_hal_set_global_info_cmd(_adapter * adapter,u8 group_alg,u8 pairwise_alg)4607 static u8 rtw_hal_set_global_info_cmd(_adapter *adapter, u8 group_alg, u8 pairwise_alg)
4608 {
4609 struct hal_ops *pHalFunc = &adapter->hal_func;
4610 u8 ret = _FAIL;
4611 u8 u1H2CAOACGlobalInfoParm[H2C_AOAC_GLOBAL_INFO_LEN] = {0};
4612
4613 RTW_INFO("%s(): group_alg=%d pairwise_alg=%d\n",
4614 __func__, group_alg, pairwise_alg);
4615 SET_H2CCMD_AOAC_GLOBAL_INFO_PAIRWISE_ENC_ALG(u1H2CAOACGlobalInfoParm,
4616 pairwise_alg);
4617 SET_H2CCMD_AOAC_GLOBAL_INFO_GROUP_ENC_ALG(u1H2CAOACGlobalInfoParm,
4618 group_alg);
4619
4620 ret = rtw_hal_fill_h2c_cmd(adapter,
4621 H2C_AOAC_GLOBAL_INFO,
4622 H2C_AOAC_GLOBAL_INFO_LEN,
4623 u1H2CAOACGlobalInfoParm);
4624
4625 return ret;
4626 }
4627
4628 #ifdef CONFIG_PNO_SUPPORT
rtw_hal_set_scan_offload_info_cmd(_adapter * adapter,PRSVDPAGE_LOC rsvdpageloc,u8 enable)4629 static u8 rtw_hal_set_scan_offload_info_cmd(_adapter *adapter,
4630 PRSVDPAGE_LOC rsvdpageloc, u8 enable)
4631 {
4632 struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(adapter);
4633 struct hal_ops *pHalFunc = &adapter->hal_func;
4634
4635 u8 u1H2CScanOffloadInfoParm[H2C_SCAN_OFFLOAD_CTRL_LEN] = {0};
4636 u8 res = 0, count = 0, ret = _FAIL;
4637
4638 RTW_INFO("%s: loc_probe_packet:%d, loc_scan_info: %d loc_ssid_info:%d\n",
4639 __func__, rsvdpageloc->LocProbePacket,
4640 rsvdpageloc->LocScanInfo, rsvdpageloc->LocSSIDInfo);
4641
4642 SET_H2CCMD_AOAC_NLO_FUN_EN(u1H2CScanOffloadInfoParm, enable);
4643 SET_H2CCMD_AOAC_NLO_IPS_EN(u1H2CScanOffloadInfoParm, enable);
4644 SET_H2CCMD_AOAC_RSVDPAGE_LOC_SCAN_INFO(u1H2CScanOffloadInfoParm,
4645 rsvdpageloc->LocScanInfo);
4646 SET_H2CCMD_AOAC_RSVDPAGE_LOC_PROBE_PACKET(u1H2CScanOffloadInfoParm,
4647 rsvdpageloc->LocProbePacket);
4648 /*
4649 SET_H2CCMD_AOAC_RSVDPAGE_LOC_SSID_INFO(u1H2CScanOffloadInfoParm,
4650 rsvdpageloc->LocSSIDInfo);
4651 */
4652 ret = rtw_hal_fill_h2c_cmd(adapter,
4653 H2C_D0_SCAN_OFFLOAD_INFO,
4654 H2C_SCAN_OFFLOAD_CTRL_LEN,
4655 u1H2CScanOffloadInfoParm);
4656 return ret;
4657 }
4658 #endif /* CONFIG_PNO_SUPPORT */
4659
rtw_hal_set_fw_wow_related_cmd(_adapter * padapter,u8 enable)4660 void rtw_hal_set_fw_wow_related_cmd(_adapter *padapter, u8 enable)
4661 {
4662 struct security_priv *psecpriv = &padapter->securitypriv;
4663 struct pwrctrl_priv *ppwrpriv = adapter_to_pwrctl(padapter);
4664 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
4665 struct registry_priv *pregistry = &padapter->registrypriv;
4666 struct sta_info *psta = NULL;
4667 u16 media_status_rpt;
4668 u8 pkt_type = 0;
4669 u8 ret = _SUCCESS;
4670
4671 RTW_PRINT("+%s()+: enable=%d\n", __func__, enable);
4672
4673 rtw_hal_set_wowlan_ctrl_cmd(padapter, enable, _FALSE);
4674
4675 if (enable) {
4676 rtw_hal_set_global_info_cmd(padapter,
4677 psecpriv->dot118021XGrpPrivacy,
4678 psecpriv->dot11PrivacyAlgrthm);
4679
4680 if (!(ppwrpriv->wowlan_pno_enable)) {
4681 if (pregistry->wakeup_event & BIT(2))
4682 rtw_hal_set_disconnect_decision_cmd(padapter,
4683 enable);
4684 #ifdef CONFIG_ARP_KEEP_ALIVE
4685 if ((psecpriv->dot11PrivacyAlgrthm == _WEP40_) ||
4686 (psecpriv->dot11PrivacyAlgrthm == _WEP104_))
4687 pkt_type = 0;
4688 else
4689 pkt_type = 1;
4690 #else
4691 pkt_type = 0;
4692 #endif /* CONFIG_ARP_KEEP_ALIVE */
4693 rtw_hal_set_keep_alive_cmd(padapter, enable, pkt_type);
4694 }
4695 rtw_hal_set_remote_wake_ctrl_cmd(padapter, enable);
4696 #ifdef CONFIG_PNO_SUPPORT
4697 rtw_hal_check_pno_enabled(padapter);
4698 #endif /* CONFIG_PNO_SUPPORT */
4699 } else {
4700 #if 0
4701 {
4702 u32 PageSize = 0;
4703 rtw_hal_get_def_var(padapter, HAL_DEF_TX_PAGE_SIZE, (u8 *)&PageSize);
4704 dump_TX_FIFO(padapter, 4, PageSize);
4705 }
4706 #endif
4707
4708 rtw_hal_set_remote_wake_ctrl_cmd(padapter, enable);
4709 }
4710 RTW_PRINT("-%s()-\n", __func__);
4711 }
4712 #endif /* CONFIG_WOWLAN */
4713
4714 #ifdef CONFIG_AP_WOWLAN
rtw_hal_set_ap_wowlan_ctrl_cmd(_adapter * adapter,u8 enable)4715 static u8 rtw_hal_set_ap_wowlan_ctrl_cmd(_adapter *adapter, u8 enable)
4716 {
4717 struct security_priv *psecpriv = &adapter->securitypriv;
4718 struct pwrctrl_priv *ppwrpriv = adapter_to_pwrctl(adapter);
4719 struct hal_ops *pHalFunc = &adapter->hal_func;
4720
4721 u8 u1H2CAPWoWlanCtrlParm[H2C_AP_WOW_GPIO_CTRL_LEN] = {0};
4722 u8 gpionum = 0, gpio_dur = 0;
4723 u8 gpio_pulse = enable;
4724 u8 sdio_wakeup_enable = 1;
4725 u8 gpio_high_active = 0;
4726 u8 ret = _FAIL;
4727
4728 #ifdef CONFIG_GPIO_WAKEUP
4729 gpio_high_active = ppwrpriv->is_high_active;
4730 gpionum = WAKEUP_GPIO_IDX;
4731 sdio_wakeup_enable = 0;
4732 #endif /*CONFIG_GPIO_WAKEUP*/
4733
4734 RTW_INFO("%s(): enable=%d\n", __func__, enable);
4735
4736 SET_H2CCMD_AP_WOW_GPIO_CTRL_INDEX(u1H2CAPWoWlanCtrlParm,
4737 gpionum);
4738 SET_H2CCMD_AP_WOW_GPIO_CTRL_PLUS(u1H2CAPWoWlanCtrlParm,
4739 gpio_pulse);
4740 SET_H2CCMD_AP_WOW_GPIO_CTRL_HIGH_ACTIVE(u1H2CAPWoWlanCtrlParm,
4741 gpio_high_active);
4742 SET_H2CCMD_AP_WOW_GPIO_CTRL_EN(u1H2CAPWoWlanCtrlParm,
4743 enable);
4744 SET_H2CCMD_AP_WOW_GPIO_CTRL_DURATION(u1H2CAPWoWlanCtrlParm,
4745 gpio_dur);
4746
4747 ret = rtw_hal_fill_h2c_cmd(adapter,
4748 H2C_AP_WOW_GPIO_CTRL,
4749 H2C_AP_WOW_GPIO_CTRL_LEN,
4750 u1H2CAPWoWlanCtrlParm);
4751
4752 return ret;
4753 }
4754
rtw_hal_set_ap_offload_ctrl_cmd(_adapter * adapter,u8 enable)4755 static u8 rtw_hal_set_ap_offload_ctrl_cmd(_adapter *adapter, u8 enable)
4756 {
4757 struct hal_ops *pHalFunc = &adapter->hal_func;
4758 u8 u1H2CAPOffloadCtrlParm[H2C_WOWLAN_LEN] = {0};
4759 u8 ret = _FAIL;
4760
4761 RTW_INFO("%s(): bFuncEn=%d\n", __func__, enable);
4762
4763 SET_H2CCMD_AP_WOWLAN_EN(u1H2CAPOffloadCtrlParm, enable);
4764
4765 ret = rtw_hal_fill_h2c_cmd(adapter,
4766 H2C_AP_OFFLOAD,
4767 H2C_AP_OFFLOAD_LEN,
4768 u1H2CAPOffloadCtrlParm);
4769
4770 return ret;
4771 }
4772
rtw_hal_set_ap_ps_cmd(_adapter * adapter,u8 enable)4773 static u8 rtw_hal_set_ap_ps_cmd(_adapter *adapter, u8 enable)
4774 {
4775 struct hal_ops *pHalFunc = &adapter->hal_func;
4776 u8 ap_ps_parm[H2C_AP_PS_LEN] = {0};
4777 u8 ret = _FAIL;
4778
4779 RTW_INFO("%s(): enable=%d\n" , __func__ , enable);
4780
4781 SET_H2CCMD_AP_WOW_PS_EN(ap_ps_parm, enable);
4782 #ifndef CONFIG_USB_HCI
4783 SET_H2CCMD_AP_WOW_PS_32K_EN(ap_ps_parm, enable);
4784 #endif /*CONFIG_USB_HCI*/
4785 SET_H2CCMD_AP_WOW_PS_RF(ap_ps_parm, enable);
4786
4787 if (enable)
4788 SET_H2CCMD_AP_WOW_PS_DURATION(ap_ps_parm, 0x32);
4789 else
4790 SET_H2CCMD_AP_WOW_PS_DURATION(ap_ps_parm, 0x0);
4791
4792 ret = rtw_hal_fill_h2c_cmd(adapter, H2C_SAP_PS_,
4793 H2C_AP_PS_LEN, ap_ps_parm);
4794
4795 return ret;
4796 }
4797
rtw_hal_set_ap_rsvdpage_loc_cmd(PADAPTER padapter,PRSVDPAGE_LOC rsvdpageloc)4798 static void rtw_hal_set_ap_rsvdpage_loc_cmd(PADAPTER padapter,
4799 PRSVDPAGE_LOC rsvdpageloc)
4800 {
4801 struct hal_ops *pHalFunc = &padapter->hal_func;
4802 u8 rsvdparm[H2C_AOAC_RSVDPAGE_LOC_LEN] = {0};
4803 u8 ret = _FAIL, header = 0;
4804
4805 if (pHalFunc->fill_h2c_cmd == NULL) {
4806 RTW_INFO("%s: Please hook fill_h2c_cmd first!\n", __func__);
4807 return;
4808 }
4809
4810 header = rtw_read8(padapter, REG_BCNQ_BDNY);
4811
4812 RTW_INFO("%s: beacon: %d, probeRsp: %d, header:0x%02x\n", __func__,
4813 rsvdpageloc->LocApOffloadBCN,
4814 rsvdpageloc->LocProbeRsp,
4815 header);
4816
4817 SET_H2CCMD_AP_WOWLAN_RSVDPAGE_LOC_BCN(rsvdparm,
4818 rsvdpageloc->LocApOffloadBCN + header);
4819
4820 ret = rtw_hal_fill_h2c_cmd(padapter, H2C_BCN_RSVDPAGE,
4821 H2C_BCN_RSVDPAGE_LEN, rsvdparm);
4822
4823 if (ret == _FAIL)
4824 RTW_INFO("%s: H2C_BCN_RSVDPAGE cmd fail\n", __func__);
4825
4826 rtw_msleep_os(10);
4827
4828 _rtw_memset(&rsvdparm, 0, sizeof(rsvdparm));
4829
4830 SET_H2CCMD_AP_WOWLAN_RSVDPAGE_LOC_ProbeRsp(rsvdparm,
4831 rsvdpageloc->LocProbeRsp + header);
4832
4833 ret = rtw_hal_fill_h2c_cmd(padapter, H2C_PROBERSP_RSVDPAGE,
4834 H2C_PROBERSP_RSVDPAGE_LEN, rsvdparm);
4835
4836 if (ret == _FAIL)
4837 RTW_INFO("%s: H2C_PROBERSP_RSVDPAGE cmd fail\n", __func__);
4838
4839 rtw_msleep_os(10);
4840 }
4841
rtw_hal_set_fw_ap_wow_related_cmd(_adapter * padapter,u8 enable)4842 static void rtw_hal_set_fw_ap_wow_related_cmd(_adapter *padapter, u8 enable)
4843 {
4844 rtw_hal_set_ap_offload_ctrl_cmd(padapter, enable);
4845 rtw_hal_set_ap_wowlan_ctrl_cmd(padapter, enable);
4846 rtw_hal_set_ap_ps_cmd(padapter, enable);
4847 }
4848
rtw_hal_ap_wow_enable(_adapter * padapter)4849 static void rtw_hal_ap_wow_enable(_adapter *padapter)
4850 {
4851 struct pwrctrl_priv *pwrctl = adapter_to_pwrctl(padapter);
4852 struct security_priv *psecuritypriv = &padapter->securitypriv;
4853 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
4854 struct hal_ops *pHalFunc = &padapter->hal_func;
4855 struct sta_info *psta = NULL;
4856 PHAL_DATA_TYPE pHalData = GET_HAL_DATA(padapter);
4857 #ifdef DBG_CHECK_FW_PS_STATE
4858 struct dvobj_priv *psdpriv = padapter->dvobj;
4859 struct debug_priv *pdbgpriv = &psdpriv->drv_dbg;
4860 #endif /*DBG_CHECK_FW_PS_STATE*/
4861 int res;
4862 u16 media_status_rpt;
4863
4864 RTW_INFO("%s, WOWLAN_AP_ENABLE\n", __func__);
4865 #ifdef DBG_CHECK_FW_PS_STATE
4866 if (rtw_fw_ps_state(padapter) == _FAIL) {
4867 pdbgpriv->dbg_enwow_dload_fw_fail_cnt++;
4868 RTW_PRINT("wowlan enable no leave 32k\n");
4869 }
4870 #endif /*DBG_CHECK_FW_PS_STATE*/
4871
4872 /* 1. Download WOWLAN FW*/
4873 rtw_hal_fw_dl(padapter, _TRUE);
4874
4875 media_status_rpt = RT_MEDIA_CONNECT;
4876 rtw_hal_set_hwreg(padapter, HW_VAR_H2C_FW_JOINBSSRPT,
4877 (u8 *)&media_status_rpt);
4878
4879 issue_beacon(padapter, 0);
4880
4881 rtw_msleep_os(2);
4882 #if defined(CONFIG_RTL8188E)
4883 if (IS_HARDWARE_TYPE_8188E(padapter))
4884 rtw_hal_disable_tx_report(padapter);
4885 #endif
4886 /* RX DMA stop */
4887 res = rtw_hal_pause_rx_dma(padapter);
4888 if (res == _FAIL)
4889 RTW_PRINT("[WARNING] pause RX DMA fail\n");
4890
4891 #if defined(CONFIG_SDIO_HCI) || defined(CONFIG_GSPI_HCI)
4892 /* Enable CPWM2 only. */
4893 res = rtw_hal_enable_cpwm2(padapter);
4894 if (res == _FAIL)
4895 RTW_PRINT("[WARNING] enable cpwm2 fail\n");
4896 #endif
4897
4898 #ifdef CONFIG_GPIO_WAKEUP
4899 rtw_hal_switch_gpio_wl_ctrl(padapter, WAKEUP_GPIO_IDX, _TRUE);
4900 #endif
4901 /* 5. Set Enable WOWLAN H2C command. */
4902 RTW_PRINT("Set Enable AP WOWLan cmd\n");
4903 rtw_hal_set_fw_ap_wow_related_cmd(padapter, 1);
4904
4905 rtw_write8(padapter, REG_MCUTST_WOWLAN, 0);
4906 #ifdef CONFIG_USB_HCI
4907 rtw_mi_intf_stop(padapter);
4908 #endif
4909 #if defined(CONFIG_USB_HCI) || defined(CONFIG_PCI_HCI)
4910 /* Invoid SE0 reset signal during suspending*/
4911 rtw_write8(padapter, REG_RSV_CTRL, 0x20);
4912 if (IS_8188F(pHalData->version_id) == FALSE)
4913 rtw_write8(padapter, REG_RSV_CTRL, 0x60);
4914 #endif
4915 }
4916
rtw_hal_ap_wow_disable(_adapter * padapter)4917 static void rtw_hal_ap_wow_disable(_adapter *padapter)
4918 {
4919 struct pwrctrl_priv *pwrctl = adapter_to_pwrctl(padapter);
4920 struct hal_ops *pHalFunc = &padapter->hal_func;
4921 #ifdef DBG_CHECK_FW_PS_STATE
4922 struct dvobj_priv *psdpriv = padapter->dvobj;
4923 struct debug_priv *pdbgpriv = &psdpriv->drv_dbg;
4924 #endif /*DBG_CHECK_FW_PS_STATE*/
4925 u16 media_status_rpt;
4926 u8 val8;
4927
4928 RTW_INFO("%s, WOWLAN_AP_DISABLE\n", __func__);
4929 /* 1. Read wakeup reason*/
4930 pwrctl->wowlan_wake_reason = rtw_read8(padapter, REG_MCUTST_WOWLAN);
4931
4932 RTW_PRINT("wakeup_reason: 0x%02x\n",
4933 pwrctl->wowlan_wake_reason);
4934
4935 rtw_hal_set_fw_ap_wow_related_cmd(padapter, 0);
4936
4937 rtw_msleep_os(2);
4938 #ifdef DBG_CHECK_FW_PS_STATE
4939 if (rtw_fw_ps_state(padapter) == _FAIL) {
4940 pdbgpriv->dbg_diswow_dload_fw_fail_cnt++;
4941 RTW_PRINT("wowlan enable no leave 32k\n");
4942 }
4943 #endif /*DBG_CHECK_FW_PS_STATE*/
4944
4945 #if defined(CONFIG_RTL8188E)
4946 if (IS_HARDWARE_TYPE_8188E(padapter))
4947 rtw_hal_enable_tx_report(padapter);
4948 #endif
4949
4950 rtw_hal_force_enable_rxdma(padapter);
4951
4952 rtw_hal_fw_dl(padapter, _FALSE);
4953
4954 #ifdef CONFIG_GPIO_WAKEUP
4955 #ifdef CONFIG_WAKEUP_GPIO_INPUT_MODE
4956 if (pwrctl->is_high_active == 0)
4957 rtw_hal_set_input_gpio(padapter, WAKEUP_GPIO_IDX);
4958 else
4959 rtw_hal_set_output_gpio(padapter, WAKEUP_GPIO_IDX, 0);
4960 #else
4961 val8 = (pwrctl->is_high_active == 0) ? 1 : 0;
4962 RTW_PRINT("Set Wake GPIO to default(%d).\n", val8);
4963 rtw_hal_set_output_gpio(padapter, WAKEUP_GPIO_IDX, val8);
4964
4965 rtw_hal_switch_gpio_wl_ctrl(padapter, WAKEUP_GPIO_IDX, _FALSE);
4966 #endif/*CONFIG_WAKEUP_GPIO_INPUT_MODE*/
4967 #endif
4968 media_status_rpt = RT_MEDIA_CONNECT;
4969
4970 rtw_hal_set_hwreg(padapter, HW_VAR_H2C_FW_JOINBSSRPT,
4971 (u8 *)&media_status_rpt);
4972
4973 issue_beacon(padapter, 0);
4974 }
4975 #endif /*CONFIG_AP_WOWLAN*/
4976
4977 #ifdef CONFIG_P2P_WOWLAN
update_hidden_ssid(u8 * ies,u32 ies_len,u8 hidden_ssid_mode)4978 static int update_hidden_ssid(u8 *ies, u32 ies_len, u8 hidden_ssid_mode)
4979 {
4980 u8 *ssid_ie;
4981 sint ssid_len_ori;
4982 int len_diff = 0;
4983
4984 ssid_ie = rtw_get_ie(ies, WLAN_EID_SSID, &ssid_len_ori, ies_len);
4985
4986 /* RTW_INFO("%s hidden_ssid_mode:%u, ssid_ie:%p, ssid_len_ori:%d\n", __FUNCTION__, hidden_ssid_mode, ssid_ie, ssid_len_ori); */
4987
4988 if (ssid_ie && ssid_len_ori > 0) {
4989 switch (hidden_ssid_mode) {
4990 case 1: {
4991 u8 *next_ie = ssid_ie + 2 + ssid_len_ori;
4992 u32 remain_len = 0;
4993
4994 remain_len = ies_len - (next_ie - ies);
4995
4996 ssid_ie[1] = 0;
4997 _rtw_memcpy(ssid_ie + 2, next_ie, remain_len);
4998 len_diff -= ssid_len_ori;
4999
5000 break;
5001 }
5002 case 2:
5003 _rtw_memset(&ssid_ie[2], 0, ssid_len_ori);
5004 break;
5005 default:
5006 break;
5007 }
5008 }
5009
5010 return len_diff;
5011 }
5012
rtw_hal_construct_P2PBeacon(_adapter * padapter,u8 * pframe,u32 * pLength)5013 static void rtw_hal_construct_P2PBeacon(_adapter *padapter, u8 *pframe, u32 *pLength)
5014 {
5015 /* struct xmit_frame *pmgntframe; */
5016 /* struct pkt_attrib *pattrib; */
5017 /* unsigned char *pframe; */
5018 struct rtw_ieee80211_hdr *pwlanhdr;
5019 unsigned short *fctrl;
5020 unsigned int rate_len;
5021 struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
5022 u32 pktlen;
5023 /* #if defined (CONFIG_AP_MODE) && defined (CONFIG_NATIVEAP_MLME) */
5024 /* _irqL irqL;
5025 * struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
5026 * #endif */ /* #if defined (CONFIG_AP_MODE) && defined (CONFIG_NATIVEAP_MLME) */
5027 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
5028 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
5029 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
5030 WLAN_BSSID_EX *cur_network = &(pmlmeinfo->network);
5031 u8 bc_addr[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
5032 #ifdef CONFIG_P2P
5033 struct wifidirect_info *pwdinfo = &(padapter->wdinfo);
5034 #endif /* CONFIG_P2P */
5035
5036 /* for debug */
5037 u8 *dbgbuf = pframe;
5038 u8 dbgbufLen = 0, index = 0;
5039
5040 RTW_INFO("%s\n", __FUNCTION__);
5041 /* #if defined (CONFIG_AP_MODE) && defined (CONFIG_NATIVEAP_MLME) */
5042 /* _enter_critical_bh(&pmlmepriv->bcn_update_lock, &irqL);
5043 * #endif */ /* #if defined (CONFIG_AP_MODE) && defined (CONFIG_NATIVEAP_MLME) */
5044
5045 pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
5046
5047
5048 fctrl = &(pwlanhdr->frame_ctl);
5049 *(fctrl) = 0;
5050
5051 _rtw_memcpy(pwlanhdr->addr1, bc_addr, ETH_ALEN);
5052 _rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN);
5053 _rtw_memcpy(pwlanhdr->addr3, get_my_bssid(cur_network), ETH_ALEN);
5054
5055 SetSeqNum(pwlanhdr, 0/*pmlmeext->mgnt_seq*/);
5056 /* pmlmeext->mgnt_seq++; */
5057 set_frame_sub_type(pframe, WIFI_BEACON);
5058
5059 pframe += sizeof(struct rtw_ieee80211_hdr_3addr);
5060 pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
5061
5062 if ((pmlmeinfo->state & 0x03) == WIFI_FW_AP_STATE) {
5063 /* RTW_INFO("ie len=%d\n", cur_network->IELength); */
5064 #ifdef CONFIG_P2P
5065 /* for P2P : Primary Device Type & Device Name */
5066 u32 wpsielen = 0, insert_len = 0;
5067 u8 *wpsie = NULL;
5068 wpsie = rtw_get_wps_ie(cur_network->IEs + _FIXED_IE_LENGTH_, cur_network->IELength - _FIXED_IE_LENGTH_, NULL, &wpsielen);
5069
5070 if (rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO) && wpsie && wpsielen > 0) {
5071 uint wps_offset, remainder_ielen;
5072 u8 *premainder_ie, *pframe_wscie;
5073
5074 wps_offset = (uint)(wpsie - cur_network->IEs);
5075
5076 premainder_ie = wpsie + wpsielen;
5077
5078 remainder_ielen = cur_network->IELength - wps_offset - wpsielen;
5079
5080 #ifdef CONFIG_IOCTL_CFG80211
5081 if (pwdinfo->driver_interface == DRIVER_CFG80211) {
5082 if (pmlmepriv->wps_beacon_ie && pmlmepriv->wps_beacon_ie_len > 0) {
5083 _rtw_memcpy(pframe, cur_network->IEs, wps_offset);
5084 pframe += wps_offset;
5085 pktlen += wps_offset;
5086
5087 _rtw_memcpy(pframe, pmlmepriv->wps_beacon_ie, pmlmepriv->wps_beacon_ie_len);
5088 pframe += pmlmepriv->wps_beacon_ie_len;
5089 pktlen += pmlmepriv->wps_beacon_ie_len;
5090
5091 /* copy remainder_ie to pframe */
5092 _rtw_memcpy(pframe, premainder_ie, remainder_ielen);
5093 pframe += remainder_ielen;
5094 pktlen += remainder_ielen;
5095 } else {
5096 _rtw_memcpy(pframe, cur_network->IEs, cur_network->IELength);
5097 pframe += cur_network->IELength;
5098 pktlen += cur_network->IELength;
5099 }
5100 } else
5101 #endif /* CONFIG_IOCTL_CFG80211 */
5102 {
5103 pframe_wscie = pframe + wps_offset;
5104 _rtw_memcpy(pframe, cur_network->IEs, wps_offset + wpsielen);
5105 pframe += (wps_offset + wpsielen);
5106 pktlen += (wps_offset + wpsielen);
5107
5108 /* now pframe is end of wsc ie, insert Primary Device Type & Device Name */
5109 /* Primary Device Type */
5110 /* Type: */
5111 *(u16 *)(pframe + insert_len) = cpu_to_be16(WPS_ATTR_PRIMARY_DEV_TYPE);
5112 insert_len += 2;
5113
5114 /* Length: */
5115 *(u16 *)(pframe + insert_len) = cpu_to_be16(0x0008);
5116 insert_len += 2;
5117
5118 /* Value: */
5119 /* Category ID */
5120 *(u16 *)(pframe + insert_len) = cpu_to_be16(WPS_PDT_CID_MULIT_MEDIA);
5121 insert_len += 2;
5122
5123 /* OUI */
5124 *(u32 *)(pframe + insert_len) = cpu_to_be32(WPSOUI);
5125 insert_len += 4;
5126
5127 /* Sub Category ID */
5128 *(u16 *)(pframe + insert_len) = cpu_to_be16(WPS_PDT_SCID_MEDIA_SERVER);
5129 insert_len += 2;
5130
5131
5132 /* Device Name */
5133 /* Type: */
5134 *(u16 *)(pframe + insert_len) = cpu_to_be16(WPS_ATTR_DEVICE_NAME);
5135 insert_len += 2;
5136
5137 /* Length: */
5138 *(u16 *)(pframe + insert_len) = cpu_to_be16(pwdinfo->device_name_len);
5139 insert_len += 2;
5140
5141 /* Value: */
5142 _rtw_memcpy(pframe + insert_len, pwdinfo->device_name, pwdinfo->device_name_len);
5143 insert_len += pwdinfo->device_name_len;
5144
5145
5146 /* update wsc ie length */
5147 *(pframe_wscie + 1) = (wpsielen - 2) + insert_len;
5148
5149 /* pframe move to end */
5150 pframe += insert_len;
5151 pktlen += insert_len;
5152
5153 /* copy remainder_ie to pframe */
5154 _rtw_memcpy(pframe, premainder_ie, remainder_ielen);
5155 pframe += remainder_ielen;
5156 pktlen += remainder_ielen;
5157 }
5158 } else
5159 #endif /* CONFIG_P2P */
5160 {
5161 int len_diff;
5162 _rtw_memcpy(pframe, cur_network->IEs, cur_network->IELength);
5163 len_diff = update_hidden_ssid(
5164 pframe + _BEACON_IE_OFFSET_
5165 , cur_network->IELength - _BEACON_IE_OFFSET_
5166 , pmlmeinfo->hidden_ssid_mode
5167 );
5168 pframe += (cur_network->IELength + len_diff);
5169 pktlen += (cur_network->IELength + len_diff);
5170 }
5171 #if 0
5172 {
5173 u8 *wps_ie;
5174 uint wps_ielen;
5175 u8 sr = 0;
5176 wps_ie = rtw_get_wps_ie(pmgntframe->buf_addr + TXDESC_OFFSET + sizeof(struct rtw_ieee80211_hdr_3addr) + _BEACON_IE_OFFSET_,
5177 pattrib->pktlen - sizeof(struct rtw_ieee80211_hdr_3addr) - _BEACON_IE_OFFSET_, NULL, &wps_ielen);
5178 if (wps_ie && wps_ielen > 0)
5179 rtw_get_wps_attr_content(wps_ie, wps_ielen, WPS_ATTR_SELECTED_REGISTRAR, (u8 *)(&sr), NULL);
5180 if (sr != 0)
5181 set_fwstate(pmlmepriv, WIFI_UNDER_WPS);
5182 else
5183 _clr_fwstate_(pmlmepriv, WIFI_UNDER_WPS);
5184 }
5185 #endif
5186 #ifdef CONFIG_P2P
5187 if (rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO)) {
5188 u32 len;
5189 #ifdef CONFIG_IOCTL_CFG80211
5190 if (pwdinfo->driver_interface == DRIVER_CFG80211) {
5191 len = pmlmepriv->p2p_beacon_ie_len;
5192 if (pmlmepriv->p2p_beacon_ie && len > 0)
5193 _rtw_memcpy(pframe, pmlmepriv->p2p_beacon_ie, len);
5194 } else
5195 #endif /* CONFIG_IOCTL_CFG80211 */
5196 {
5197 len = build_beacon_p2p_ie(pwdinfo, pframe);
5198 }
5199
5200 pframe += len;
5201 pktlen += len;
5202
5203 #ifdef CONFIG_WFD
5204 len = rtw_append_beacon_wfd_ie(padapter, pframe);
5205 pframe += len;
5206 pktlen += len;
5207 #endif
5208
5209 }
5210 #endif /* CONFIG_P2P */
5211
5212 goto _issue_bcn;
5213
5214 }
5215
5216 /* below for ad-hoc mode */
5217
5218 /* timestamp will be inserted by hardware */
5219 pframe += 8;
5220 pktlen += 8;
5221
5222 /* beacon interval: 2 bytes */
5223
5224 _rtw_memcpy(pframe, (unsigned char *)(rtw_get_beacon_interval_from_ie(cur_network->IEs)), 2);
5225
5226 pframe += 2;
5227 pktlen += 2;
5228
5229 /* capability info: 2 bytes */
5230
5231 _rtw_memcpy(pframe, (unsigned char *)(rtw_get_capability_from_ie(cur_network->IEs)), 2);
5232
5233 pframe += 2;
5234 pktlen += 2;
5235
5236 /* SSID */
5237 pframe = rtw_set_ie(pframe, _SSID_IE_, cur_network->Ssid.SsidLength, cur_network->Ssid.Ssid, &pktlen);
5238
5239 /* supported rates... */
5240 rate_len = rtw_get_rateset_len(cur_network->SupportedRates);
5241 pframe = rtw_set_ie(pframe, _SUPPORTEDRATES_IE_, ((rate_len > 8) ? 8 : rate_len), cur_network->SupportedRates, &pktlen);
5242
5243 /* DS parameter set */
5244 pframe = rtw_set_ie(pframe, _DSSET_IE_, 1, (unsigned char *)&(cur_network->Configuration.DSConfig), &pktlen);
5245
5246 /* if( (pmlmeinfo->state&0x03) == WIFI_FW_ADHOC_STATE) */
5247 {
5248 u8 erpinfo = 0;
5249 u32 ATIMWindow;
5250 /* IBSS Parameter Set... */
5251 /* ATIMWindow = cur->Configuration.ATIMWindow; */
5252 ATIMWindow = 0;
5253 pframe = rtw_set_ie(pframe, _IBSS_PARA_IE_, 2, (unsigned char *)(&ATIMWindow), &pktlen);
5254
5255 /* ERP IE */
5256 pframe = rtw_set_ie(pframe, _ERPINFO_IE_, 1, &erpinfo, &pktlen);
5257 }
5258
5259
5260 /* EXTERNDED SUPPORTED RATE */
5261 if (rate_len > 8)
5262 pframe = rtw_set_ie(pframe, _EXT_SUPPORTEDRATES_IE_, (rate_len - 8), (cur_network->SupportedRates + 8), &pktlen);
5263
5264
5265 /* todo:HT for adhoc */
5266
5267 _issue_bcn:
5268
5269 /* #if defined (CONFIG_AP_MODE) && defined (CONFIG_NATIVEAP_MLME) */
5270 /* pmlmepriv->update_bcn = _FALSE;
5271 *
5272 * _exit_critical_bh(&pmlmepriv->bcn_update_lock, &irqL);
5273 * #endif */ /* #if defined (CONFIG_AP_MODE) && defined (CONFIG_NATIVEAP_MLME) */
5274
5275 *pLength = pktlen;
5276 #if 0
5277 /* printf dbg msg */
5278 dbgbufLen = pktlen;
5279 RTW_INFO("======> DBG MSG FOR CONSTRAUCT P2P BEACON\n");
5280
5281 for (index = 0; index < dbgbufLen; index++)
5282 printk("%x ", *(dbgbuf + index));
5283
5284 printk("\n");
5285 RTW_INFO("<====== DBG MSG FOR CONSTRAUCT P2P BEACON\n");
5286
5287 #endif
5288 }
5289
rtw_hal_construct_P2PProbeRsp(_adapter * padapter,u8 * pframe,u32 * pLength)5290 static void rtw_hal_construct_P2PProbeRsp(_adapter *padapter, u8 *pframe, u32 *pLength)
5291 {
5292 /* struct xmit_frame *pmgntframe; */
5293 /* struct pkt_attrib *pattrib; */
5294 /* unsigned char *pframe; */
5295 struct rtw_ieee80211_hdr *pwlanhdr;
5296 unsigned short *fctrl;
5297 unsigned char *mac;
5298 struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
5299 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
5300 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
5301 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
5302 /* WLAN_BSSID_EX *cur_network = &(pmlmeinfo->network); */
5303 u16 beacon_interval = 100;
5304 u16 capInfo = 0;
5305 struct wifidirect_info *pwdinfo = &(padapter->wdinfo);
5306 u8 wpsie[255] = { 0x00 };
5307 u32 wpsielen = 0, p2pielen = 0;
5308 u32 pktlen;
5309 #ifdef CONFIG_WFD
5310 u32 wfdielen = 0;
5311 #endif
5312 #ifdef CONFIG_INTEL_WIDI
5313 u8 zero_array_check[L2SDTA_SERVICE_VE_LEN] = { 0x00 };
5314 #endif /* CONFIG_INTEL_WIDI */
5315
5316 /* for debug */
5317 u8 *dbgbuf = pframe;
5318 u8 dbgbufLen = 0, index = 0;
5319
5320 RTW_INFO("%s\n", __FUNCTION__);
5321 pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
5322
5323 mac = adapter_mac_addr(padapter);
5324
5325 fctrl = &(pwlanhdr->frame_ctl);
5326 *(fctrl) = 0;
5327
5328 /* DA filled by FW */
5329 _rtw_memset(pwlanhdr->addr1, 0, ETH_ALEN);
5330 _rtw_memcpy(pwlanhdr->addr2, mac, ETH_ALEN);
5331
5332 /* Use the device address for BSSID field. */
5333 _rtw_memcpy(pwlanhdr->addr3, mac, ETH_ALEN);
5334
5335 SetSeqNum(pwlanhdr, 0);
5336 set_frame_sub_type(fctrl, WIFI_PROBERSP);
5337
5338 pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
5339 pframe += pktlen;
5340
5341
5342 /* timestamp will be inserted by hardware */
5343 pframe += 8;
5344 pktlen += 8;
5345
5346 /* beacon interval: 2 bytes */
5347 _rtw_memcpy(pframe, (unsigned char *) &beacon_interval, 2);
5348 pframe += 2;
5349 pktlen += 2;
5350
5351 /* capability info: 2 bytes */
5352 /* ESS and IBSS bits must be 0 (defined in the 3.1.2.1.1 of WiFi Direct Spec) */
5353 capInfo |= cap_ShortPremble;
5354 capInfo |= cap_ShortSlot;
5355
5356 _rtw_memcpy(pframe, (unsigned char *) &capInfo, 2);
5357 pframe += 2;
5358 pktlen += 2;
5359
5360
5361 /* SSID */
5362 pframe = rtw_set_ie(pframe, _SSID_IE_, 7, pwdinfo->p2p_wildcard_ssid, &pktlen);
5363
5364 /* supported rates... */
5365 /* Use the OFDM rate in the P2P probe response frame. ( 6(B), 9(B), 12, 18, 24, 36, 48, 54 ) */
5366 pframe = rtw_set_ie(pframe, _SUPPORTEDRATES_IE_, 8, pwdinfo->support_rate, &pktlen);
5367
5368 /* DS parameter set */
5369 pframe = rtw_set_ie(pframe, _DSSET_IE_, 1, (unsigned char *)&pwdinfo->listen_channel, &pktlen);
5370
5371 #ifdef CONFIG_IOCTL_CFG80211
5372 if (pwdinfo->driver_interface == DRIVER_CFG80211) {
5373 if (pmlmepriv->wps_probe_resp_ie != NULL && pmlmepriv->p2p_probe_resp_ie != NULL) {
5374 /* WPS IE */
5375 _rtw_memcpy(pframe, pmlmepriv->wps_probe_resp_ie, pmlmepriv->wps_probe_resp_ie_len);
5376 pktlen += pmlmepriv->wps_probe_resp_ie_len;
5377 pframe += pmlmepriv->wps_probe_resp_ie_len;
5378
5379 /* P2P IE */
5380 _rtw_memcpy(pframe, pmlmepriv->p2p_probe_resp_ie, pmlmepriv->p2p_probe_resp_ie_len);
5381 pktlen += pmlmepriv->p2p_probe_resp_ie_len;
5382 pframe += pmlmepriv->p2p_probe_resp_ie_len;
5383 }
5384 } else
5385 #endif /* CONFIG_IOCTL_CFG80211 */
5386 {
5387
5388 /* Todo: WPS IE */
5389 /* Noted by Albert 20100907 */
5390 /* According to the WPS specification, all the WPS attribute is presented by Big Endian. */
5391
5392 wpsielen = 0;
5393 /* WPS OUI */
5394 *(u32 *)(wpsie) = cpu_to_be32(WPSOUI);
5395 wpsielen += 4;
5396
5397 /* WPS version */
5398 /* Type: */
5399 *(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_VER1);
5400 wpsielen += 2;
5401
5402 /* Length: */
5403 *(u16 *)(wpsie + wpsielen) = cpu_to_be16(0x0001);
5404 wpsielen += 2;
5405
5406 /* Value: */
5407 wpsie[wpsielen++] = WPS_VERSION_1; /* Version 1.0 */
5408
5409 #ifdef CONFIG_INTEL_WIDI
5410 /* Commented by Kurt */
5411 /* Appended WiDi info. only if we did issued_probereq_widi(), and then we saved ven. ext. in pmlmepriv->sa_ext. */
5412 if (_rtw_memcmp(pmlmepriv->sa_ext, zero_array_check, L2SDTA_SERVICE_VE_LEN) == _FALSE
5413 || pmlmepriv->num_p2p_sdt != 0) {
5414 /* Sec dev type */
5415 *(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_SEC_DEV_TYPE_LIST);
5416 wpsielen += 2;
5417
5418 /* Length: */
5419 *(u16 *)(wpsie + wpsielen) = cpu_to_be16(0x0008);
5420 wpsielen += 2;
5421
5422 /* Value: */
5423 /* Category ID */
5424 *(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_PDT_CID_DISPLAYS);
5425 wpsielen += 2;
5426
5427 /* OUI */
5428 *(u32 *)(wpsie + wpsielen) = cpu_to_be32(INTEL_DEV_TYPE_OUI);
5429 wpsielen += 4;
5430
5431 *(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_PDT_SCID_WIDI_CONSUMER_SINK);
5432 wpsielen += 2;
5433
5434 if (_rtw_memcmp(pmlmepriv->sa_ext, zero_array_check, L2SDTA_SERVICE_VE_LEN) == _FALSE) {
5435 /* Vendor Extension */
5436 _rtw_memcpy(wpsie + wpsielen, pmlmepriv->sa_ext, L2SDTA_SERVICE_VE_LEN);
5437 wpsielen += L2SDTA_SERVICE_VE_LEN;
5438 }
5439 }
5440 #endif /* CONFIG_INTEL_WIDI */
5441
5442 /* WiFi Simple Config State */
5443 /* Type: */
5444 *(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_SIMPLE_CONF_STATE);
5445 wpsielen += 2;
5446
5447 /* Length: */
5448 *(u16 *)(wpsie + wpsielen) = cpu_to_be16(0x0001);
5449 wpsielen += 2;
5450
5451 /* Value: */
5452 wpsie[wpsielen++] = WPS_WSC_STATE_NOT_CONFIG; /* Not Configured. */
5453
5454 /* Response Type */
5455 /* Type: */
5456 *(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_RESP_TYPE);
5457 wpsielen += 2;
5458
5459 /* Length: */
5460 *(u16 *)(wpsie + wpsielen) = cpu_to_be16(0x0001);
5461 wpsielen += 2;
5462
5463 /* Value: */
5464 wpsie[wpsielen++] = WPS_RESPONSE_TYPE_8021X;
5465
5466 /* UUID-E */
5467 /* Type: */
5468 *(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_UUID_E);
5469 wpsielen += 2;
5470
5471 /* Length: */
5472 *(u16 *)(wpsie + wpsielen) = cpu_to_be16(0x0010);
5473 wpsielen += 2;
5474
5475 /* Value: */
5476 if (pwdinfo->external_uuid == 0) {
5477 _rtw_memset(wpsie + wpsielen, 0x0, 16);
5478 _rtw_memcpy(wpsie + wpsielen, mac, ETH_ALEN);
5479 } else
5480 _rtw_memcpy(wpsie + wpsielen, pwdinfo->uuid, 0x10);
5481 wpsielen += 0x10;
5482
5483 /* Manufacturer */
5484 /* Type: */
5485 *(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_MANUFACTURER);
5486 wpsielen += 2;
5487
5488 /* Length: */
5489 *(u16 *)(wpsie + wpsielen) = cpu_to_be16(0x0007);
5490 wpsielen += 2;
5491
5492 /* Value: */
5493 _rtw_memcpy(wpsie + wpsielen, "Realtek", 7);
5494 wpsielen += 7;
5495
5496 /* Model Name */
5497 /* Type: */
5498 *(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_MODEL_NAME);
5499 wpsielen += 2;
5500
5501 /* Length: */
5502 *(u16 *)(wpsie + wpsielen) = cpu_to_be16(0x0006);
5503 wpsielen += 2;
5504
5505 /* Value: */
5506 _rtw_memcpy(wpsie + wpsielen, "8192CU", 6);
5507 wpsielen += 6;
5508
5509 /* Model Number */
5510 /* Type: */
5511 *(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_MODEL_NUMBER);
5512 wpsielen += 2;
5513
5514 /* Length: */
5515 *(u16 *)(wpsie + wpsielen) = cpu_to_be16(0x0001);
5516 wpsielen += 2;
5517
5518 /* Value: */
5519 wpsie[wpsielen++] = 0x31; /* character 1 */
5520
5521 /* Serial Number */
5522 /* Type: */
5523 *(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_SERIAL_NUMBER);
5524 wpsielen += 2;
5525
5526 /* Length: */
5527 *(u16 *)(wpsie + wpsielen) = cpu_to_be16(ETH_ALEN);
5528 wpsielen += 2;
5529
5530 /* Value: */
5531 _rtw_memcpy(wpsie + wpsielen, "123456" , ETH_ALEN);
5532 wpsielen += ETH_ALEN;
5533
5534 /* Primary Device Type */
5535 /* Type: */
5536 *(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_PRIMARY_DEV_TYPE);
5537 wpsielen += 2;
5538
5539 /* Length: */
5540 *(u16 *)(wpsie + wpsielen) = cpu_to_be16(0x0008);
5541 wpsielen += 2;
5542
5543 /* Value: */
5544 /* Category ID */
5545 *(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_PDT_CID_MULIT_MEDIA);
5546 wpsielen += 2;
5547
5548 /* OUI */
5549 *(u32 *)(wpsie + wpsielen) = cpu_to_be32(WPSOUI);
5550 wpsielen += 4;
5551
5552 /* Sub Category ID */
5553 *(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_PDT_SCID_MEDIA_SERVER);
5554 wpsielen += 2;
5555
5556 /* Device Name */
5557 /* Type: */
5558 *(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_DEVICE_NAME);
5559 wpsielen += 2;
5560
5561 /* Length: */
5562 *(u16 *)(wpsie + wpsielen) = cpu_to_be16(pwdinfo->device_name_len);
5563 wpsielen += 2;
5564
5565 /* Value: */
5566 _rtw_memcpy(wpsie + wpsielen, pwdinfo->device_name, pwdinfo->device_name_len);
5567 wpsielen += pwdinfo->device_name_len;
5568
5569 /* Config Method */
5570 /* Type: */
5571 *(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_CONF_METHOD);
5572 wpsielen += 2;
5573
5574 /* Length: */
5575 *(u16 *)(wpsie + wpsielen) = cpu_to_be16(0x0002);
5576 wpsielen += 2;
5577
5578 /* Value: */
5579 *(u16 *)(wpsie + wpsielen) = cpu_to_be16(pwdinfo->supported_wps_cm);
5580 wpsielen += 2;
5581
5582
5583 pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, wpsielen, (unsigned char *) wpsie, &pktlen);
5584
5585
5586 p2pielen = build_probe_resp_p2p_ie(pwdinfo, pframe);
5587 pframe += p2pielen;
5588 pktlen += p2pielen;
5589 }
5590
5591 #ifdef CONFIG_WFD
5592 wfdielen = rtw_append_probe_resp_wfd_ie(padapter, pframe);
5593 pframe += wfdielen;
5594 pktlen += wfdielen;
5595 #endif
5596
5597 *pLength = pktlen;
5598
5599 #if 0
5600 /* printf dbg msg */
5601 dbgbufLen = pktlen;
5602 RTW_INFO("======> DBG MSG FOR CONSTRAUCT P2P Probe Rsp\n");
5603
5604 for (index = 0; index < dbgbufLen; index++)
5605 printk("%x ", *(dbgbuf + index));
5606
5607 printk("\n");
5608 RTW_INFO("<====== DBG MSG FOR CONSTRAUCT P2P Probe Rsp\n");
5609 #endif
5610 }
rtw_hal_construct_P2PNegoRsp(_adapter * padapter,u8 * pframe,u32 * pLength)5611 static void rtw_hal_construct_P2PNegoRsp(_adapter *padapter, u8 *pframe, u32 *pLength)
5612 {
5613 struct p2p_channels *ch_list = &(adapter_to_rfctl(padapter)->channel_list);
5614 unsigned char category = RTW_WLAN_CATEGORY_PUBLIC;
5615 u8 action = P2P_PUB_ACTION_ACTION;
5616 u32 p2poui = cpu_to_be32(P2POUI);
5617 u8 oui_subtype = P2P_GO_NEGO_RESP;
5618 u8 wpsie[255] = { 0x00 }, p2pie[255] = { 0x00 };
5619 u8 p2pielen = 0, i;
5620 uint wpsielen = 0;
5621 u16 wps_devicepassword_id = 0x0000;
5622 uint wps_devicepassword_id_len = 0;
5623 u8 channel_cnt_24g = 0, channel_cnt_5gl = 0, channel_cnt_5gh;
5624 u16 len_channellist_attr = 0;
5625 u32 pktlen;
5626 u8 dialogToken = 0;
5627
5628 /* struct xmit_frame *pmgntframe; */
5629 /* struct pkt_attrib *pattrib; */
5630 /* unsigned char *pframe; */
5631 struct rtw_ieee80211_hdr *pwlanhdr;
5632 unsigned short *fctrl;
5633 struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
5634 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
5635 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
5636 struct wifidirect_info *pwdinfo = &(padapter->wdinfo);
5637 /* WLAN_BSSID_EX *cur_network = &(pmlmeinfo->network); */
5638
5639 #ifdef CONFIG_WFD
5640 u32 wfdielen = 0;
5641 #endif
5642
5643 /* for debug */
5644 u8 *dbgbuf = pframe;
5645 u8 dbgbufLen = 0, index = 0;
5646
5647 RTW_INFO("%s\n", __FUNCTION__);
5648 pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
5649
5650 fctrl = &(pwlanhdr->frame_ctl);
5651 *(fctrl) = 0;
5652
5653 /* RA, filled by FW */
5654 _rtw_memset(pwlanhdr->addr1, 0, ETH_ALEN);
5655 _rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN);
5656 _rtw_memcpy(pwlanhdr->addr3, adapter_mac_addr(padapter), ETH_ALEN);
5657
5658 SetSeqNum(pwlanhdr, 0);
5659 set_frame_sub_type(pframe, WIFI_ACTION);
5660
5661 pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
5662 pframe += pktlen;
5663
5664 pframe = rtw_set_fixed_ie(pframe, 1, &(category), &(pktlen));
5665 pframe = rtw_set_fixed_ie(pframe, 1, &(action), &(pktlen));
5666 pframe = rtw_set_fixed_ie(pframe, 4, (unsigned char *) &(p2poui), &(pktlen));
5667 pframe = rtw_set_fixed_ie(pframe, 1, &(oui_subtype), &(pktlen));
5668
5669 /* dialog token, filled by FW */
5670 pframe = rtw_set_fixed_ie(pframe, 1, &(dialogToken), &(pktlen));
5671
5672 _rtw_memset(wpsie, 0x00, 255);
5673 wpsielen = 0;
5674
5675 /* WPS Section */
5676 wpsielen = 0;
5677 /* WPS OUI */
5678 *(u32 *)(wpsie) = cpu_to_be32(WPSOUI);
5679 wpsielen += 4;
5680
5681 /* WPS version */
5682 /* Type: */
5683 *(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_VER1);
5684 wpsielen += 2;
5685
5686 /* Length: */
5687 *(u16 *)(wpsie + wpsielen) = cpu_to_be16(0x0001);
5688 wpsielen += 2;
5689
5690 /* Value: */
5691 wpsie[wpsielen++] = WPS_VERSION_1; /* Version 1.0 */
5692
5693 /* Device Password ID */
5694 /* Type: */
5695 *(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_DEVICE_PWID);
5696 wpsielen += 2;
5697
5698 /* Length: */
5699 *(u16 *)(wpsie + wpsielen) = cpu_to_be16(0x0002);
5700 wpsielen += 2;
5701
5702 /* Value: */
5703 if (wps_devicepassword_id == WPS_DPID_USER_SPEC)
5704 *(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_DPID_REGISTRAR_SPEC);
5705 else if (wps_devicepassword_id == WPS_DPID_REGISTRAR_SPEC)
5706 *(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_DPID_USER_SPEC);
5707 else
5708 *(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_DPID_PBC);
5709 wpsielen += 2;
5710
5711 pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, wpsielen, (unsigned char *) wpsie, &pktlen);
5712
5713
5714 /* P2P IE Section. */
5715
5716 /* P2P OUI */
5717 p2pielen = 0;
5718 p2pie[p2pielen++] = 0x50;
5719 p2pie[p2pielen++] = 0x6F;
5720 p2pie[p2pielen++] = 0x9A;
5721 p2pie[p2pielen++] = 0x09; /* WFA P2P v1.0 */
5722
5723 /* Commented by Albert 20100908 */
5724 /* According to the P2P Specification, the group negoitation response frame should contain 9 P2P attributes */
5725 /* 1. Status */
5726 /* 2. P2P Capability */
5727 /* 3. Group Owner Intent */
5728 /* 4. Configuration Timeout */
5729 /* 5. Operating Channel */
5730 /* 6. Intended P2P Interface Address */
5731 /* 7. Channel List */
5732 /* 8. Device Info */
5733 /* 9. Group ID ( Only GO ) */
5734
5735
5736 /* ToDo: */
5737
5738 /* P2P Status */
5739 /* Type: */
5740 p2pie[p2pielen++] = P2P_ATTR_STATUS;
5741
5742 /* Length: */
5743 *(u16 *)(p2pie + p2pielen) = cpu_to_le16(0x0001);
5744 p2pielen += 2;
5745
5746 /* Value, filled by FW */
5747 p2pie[p2pielen++] = 1;
5748
5749 /* P2P Capability */
5750 /* Type: */
5751 p2pie[p2pielen++] = P2P_ATTR_CAPABILITY;
5752
5753 /* Length: */
5754 *(u16 *)(p2pie + p2pielen) = cpu_to_le16(0x0002);
5755 p2pielen += 2;
5756
5757 /* Value: */
5758 /* Device Capability Bitmap, 1 byte */
5759
5760 if (rtw_p2p_chk_role(pwdinfo, P2P_ROLE_CLIENT)) {
5761 /* Commented by Albert 2011/03/08 */
5762 /* According to the P2P specification */
5763 /* if the sending device will be client, the P2P Capability should be reserved of group negotation response frame */
5764 p2pie[p2pielen++] = 0;
5765 } else {
5766 /* Be group owner or meet the error case */
5767 p2pie[p2pielen++] = DMP_P2P_DEVCAP_SUPPORT;
5768 }
5769
5770 /* Group Capability Bitmap, 1 byte */
5771 if (pwdinfo->persistent_supported)
5772 p2pie[p2pielen++] = P2P_GRPCAP_CROSS_CONN | P2P_GRPCAP_PERSISTENT_GROUP;
5773 else
5774 p2pie[p2pielen++] = P2P_GRPCAP_CROSS_CONN;
5775
5776 /* Group Owner Intent */
5777 /* Type: */
5778 p2pie[p2pielen++] = P2P_ATTR_GO_INTENT;
5779
5780 /* Length: */
5781 *(u16 *)(p2pie + p2pielen) = cpu_to_le16(0x0001);
5782 p2pielen += 2;
5783
5784 /* Value: */
5785 if (pwdinfo->peer_intent & 0x01) {
5786 /* Peer's tie breaker bit is 1, our tie breaker bit should be 0 */
5787 p2pie[p2pielen++] = (pwdinfo->intent << 1);
5788 } else {
5789 /* Peer's tie breaker bit is 0, our tie breaker bit should be 1 */
5790 p2pie[p2pielen++] = ((pwdinfo->intent << 1) | BIT(0));
5791 }
5792
5793
5794 /* Configuration Timeout */
5795 /* Type: */
5796 p2pie[p2pielen++] = P2P_ATTR_CONF_TIMEOUT;
5797
5798 /* Length: */
5799 *(u16 *)(p2pie + p2pielen) = cpu_to_le16(0x0002);
5800 p2pielen += 2;
5801
5802 /* Value: */
5803 p2pie[p2pielen++] = 200; /* 2 seconds needed to be the P2P GO */
5804 p2pie[p2pielen++] = 200; /* 2 seconds needed to be the P2P Client */
5805
5806 /* Operating Channel */
5807 /* Type: */
5808 p2pie[p2pielen++] = P2P_ATTR_OPERATING_CH;
5809
5810 /* Length: */
5811 *(u16 *)(p2pie + p2pielen) = cpu_to_le16(0x0005);
5812 p2pielen += 2;
5813
5814 /* Value: */
5815 /* Country String */
5816 p2pie[p2pielen++] = 'X';
5817 p2pie[p2pielen++] = 'X';
5818
5819 /* The third byte should be set to 0x04. */
5820 /* Described in the "Operating Channel Attribute" section. */
5821 p2pie[p2pielen++] = 0x04;
5822
5823 /* Operating Class */
5824 if (pwdinfo->operating_channel <= 14) {
5825 /* Operating Class */
5826 p2pie[p2pielen++] = 0x51;
5827 } else if ((pwdinfo->operating_channel >= 36) && (pwdinfo->operating_channel <= 48)) {
5828 /* Operating Class */
5829 p2pie[p2pielen++] = 0x73;
5830 } else {
5831 /* Operating Class */
5832 p2pie[p2pielen++] = 0x7c;
5833 }
5834
5835 /* Channel Number */
5836 p2pie[p2pielen++] = pwdinfo->operating_channel; /* operating channel number */
5837
5838 /* Intended P2P Interface Address */
5839 /* Type: */
5840 p2pie[p2pielen++] = P2P_ATTR_INTENDED_IF_ADDR;
5841
5842 /* Length: */
5843 *(u16 *)(p2pie + p2pielen) = cpu_to_le16(ETH_ALEN);
5844 p2pielen += 2;
5845
5846 /* Value: */
5847 _rtw_memcpy(p2pie + p2pielen, adapter_mac_addr(padapter), ETH_ALEN);
5848 p2pielen += ETH_ALEN;
5849
5850 /* Channel List */
5851 /* Type: */
5852 p2pie[p2pielen++] = P2P_ATTR_CH_LIST;
5853
5854 /* Country String(3) */
5855 /* + ( Operating Class (1) + Number of Channels(1) ) * Operation Classes (?) */
5856 /* + number of channels in all classes */
5857 len_channellist_attr = 3
5858 + (1 + 1) * (u16)ch_list->reg_classes
5859 + get_reg_classes_full_count(ch_list);
5860
5861 #ifdef CONFIG_CONCURRENT_MODE
5862 if (rtw_mi_buddy_check_fwstate(padapter, _FW_LINKED))
5863 *(u16 *)(p2pie + p2pielen) = cpu_to_le16(5 + 1);
5864 else
5865 *(u16 *)(p2pie + p2pielen) = cpu_to_le16(len_channellist_attr);
5866
5867 #else
5868
5869 *(u16 *)(p2pie + p2pielen) = cpu_to_le16(len_channellist_attr);
5870
5871 #endif
5872 p2pielen += 2;
5873
5874 /* Value: */
5875 /* Country String */
5876 p2pie[p2pielen++] = 'X';
5877 p2pie[p2pielen++] = 'X';
5878
5879 /* The third byte should be set to 0x04. */
5880 /* Described in the "Operating Channel Attribute" section. */
5881 p2pie[p2pielen++] = 0x04;
5882
5883 /* Channel Entry List */
5884
5885 #ifdef CONFIG_CONCURRENT_MODE
5886 if (rtw_mi_check_status(padapter, MI_LINKED)) {
5887 u8 union_ch = rtw_mi_get_union_chan(padapter);
5888
5889 /* Operating Class */
5890 if (union_ch > 14) {
5891 if (union_ch >= 149)
5892 p2pie[p2pielen++] = 0x7c;
5893 else
5894 p2pie[p2pielen++] = 0x73;
5895 } else
5896 p2pie[p2pielen++] = 0x51;
5897
5898
5899 /* Number of Channels */
5900 /* Just support 1 channel and this channel is AP's channel */
5901 p2pie[p2pielen++] = 1;
5902
5903 /* Channel List */
5904 p2pie[p2pielen++] = union_ch;
5905 } else
5906 #endif /* CONFIG_CONCURRENT_MODE */
5907 {
5908 int i, j;
5909 for (j = 0; j < ch_list->reg_classes; j++) {
5910 /* Operating Class */
5911 p2pie[p2pielen++] = ch_list->reg_class[j].reg_class;
5912
5913 /* Number of Channels */
5914 p2pie[p2pielen++] = ch_list->reg_class[j].channels;
5915
5916 /* Channel List */
5917 for (i = 0; i < ch_list->reg_class[j].channels; i++)
5918 p2pie[p2pielen++] = ch_list->reg_class[j].channel[i];
5919 }
5920 }
5921
5922 /* Device Info */
5923 /* Type: */
5924 p2pie[p2pielen++] = P2P_ATTR_DEVICE_INFO;
5925
5926 /* Length: */
5927 /* 21->P2P Device Address (6bytes) + Config Methods (2bytes) + Primary Device Type (8bytes) */
5928 /* + NumofSecondDevType (1byte) + WPS Device Name ID field (2bytes) + WPS Device Name Len field (2bytes) */
5929 *(u16 *)(p2pie + p2pielen) = cpu_to_le16(21 + pwdinfo->device_name_len);
5930 p2pielen += 2;
5931
5932 /* Value: */
5933 /* P2P Device Address */
5934 _rtw_memcpy(p2pie + p2pielen, adapter_mac_addr(padapter), ETH_ALEN);
5935 p2pielen += ETH_ALEN;
5936
5937 /* Config Method */
5938 /* This field should be big endian. Noted by P2P specification. */
5939
5940 *(u16 *)(p2pie + p2pielen) = cpu_to_be16(pwdinfo->supported_wps_cm);
5941
5942 p2pielen += 2;
5943
5944 /* Primary Device Type */
5945 /* Category ID */
5946 *(u16 *)(p2pie + p2pielen) = cpu_to_be16(WPS_PDT_CID_MULIT_MEDIA);
5947 p2pielen += 2;
5948
5949 /* OUI */
5950 *(u32 *)(p2pie + p2pielen) = cpu_to_be32(WPSOUI);
5951 p2pielen += 4;
5952
5953 /* Sub Category ID */
5954 *(u16 *)(p2pie + p2pielen) = cpu_to_be16(WPS_PDT_SCID_MEDIA_SERVER);
5955 p2pielen += 2;
5956
5957 /* Number of Secondary Device Types */
5958 p2pie[p2pielen++] = 0x00; /* No Secondary Device Type List */
5959
5960 /* Device Name */
5961 /* Type: */
5962 *(u16 *)(p2pie + p2pielen) = cpu_to_be16(WPS_ATTR_DEVICE_NAME);
5963 p2pielen += 2;
5964
5965 /* Length: */
5966 *(u16 *)(p2pie + p2pielen) = cpu_to_be16(pwdinfo->device_name_len);
5967 p2pielen += 2;
5968
5969 /* Value: */
5970 _rtw_memcpy(p2pie + p2pielen, pwdinfo->device_name , pwdinfo->device_name_len);
5971 p2pielen += pwdinfo->device_name_len;
5972
5973 if (rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO)) {
5974 /* Group ID Attribute */
5975 /* Type: */
5976 p2pie[p2pielen++] = P2P_ATTR_GROUP_ID;
5977
5978 /* Length: */
5979 *(u16 *)(p2pie + p2pielen) = cpu_to_le16(ETH_ALEN + pwdinfo->nego_ssidlen);
5980 p2pielen += 2;
5981
5982 /* Value: */
5983 /* p2P Device Address */
5984 _rtw_memcpy(p2pie + p2pielen , pwdinfo->device_addr, ETH_ALEN);
5985 p2pielen += ETH_ALEN;
5986
5987 /* SSID */
5988 _rtw_memcpy(p2pie + p2pielen, pwdinfo->nego_ssid, pwdinfo->nego_ssidlen);
5989 p2pielen += pwdinfo->nego_ssidlen;
5990
5991 }
5992
5993 pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, p2pielen, (unsigned char *) p2pie, &pktlen);
5994
5995 #ifdef CONFIG_WFD
5996 wfdielen = build_nego_resp_wfd_ie(pwdinfo, pframe);
5997 pframe += wfdielen;
5998 pktlen += wfdielen;
5999 #endif
6000
6001 *pLength = pktlen;
6002 #if 0
6003 /* printf dbg msg */
6004 dbgbufLen = pktlen;
6005 RTW_INFO("======> DBG MSG FOR CONSTRAUCT Nego Rsp\n");
6006
6007 for (index = 0; index < dbgbufLen; index++)
6008 printk("%x ", *(dbgbuf + index));
6009
6010 printk("\n");
6011 RTW_INFO("<====== DBG MSG FOR CONSTRAUCT Nego Rsp\n");
6012 #endif
6013 }
6014
rtw_hal_construct_P2PInviteRsp(_adapter * padapter,u8 * pframe,u32 * pLength)6015 static void rtw_hal_construct_P2PInviteRsp(_adapter *padapter, u8 *pframe, u32 *pLength)
6016 {
6017 unsigned char category = RTW_WLAN_CATEGORY_PUBLIC;
6018 u8 action = P2P_PUB_ACTION_ACTION;
6019 u32 p2poui = cpu_to_be32(P2POUI);
6020 u8 oui_subtype = P2P_INVIT_RESP;
6021 u8 p2pie[255] = { 0x00 };
6022 u8 p2pielen = 0, i;
6023 u8 channel_cnt_24g = 0, channel_cnt_5gl = 0, channel_cnt_5gh = 0;
6024 u16 len_channellist_attr = 0;
6025 u32 pktlen;
6026 u8 dialogToken = 0;
6027 #ifdef CONFIG_WFD
6028 u32 wfdielen = 0;
6029 #endif
6030
6031 /* struct xmit_frame *pmgntframe; */
6032 /* struct pkt_attrib *pattrib; */
6033 /* unsigned char *pframe; */
6034 struct rtw_ieee80211_hdr *pwlanhdr;
6035 unsigned short *fctrl;
6036 struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
6037 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
6038 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
6039 struct wifidirect_info *pwdinfo = &(padapter->wdinfo);
6040
6041 /* for debug */
6042 u8 *dbgbuf = pframe;
6043 u8 dbgbufLen = 0, index = 0;
6044
6045
6046 RTW_INFO("%s\n", __FUNCTION__);
6047 pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
6048
6049 fctrl = &(pwlanhdr->frame_ctl);
6050 *(fctrl) = 0;
6051
6052 /* RA fill by FW */
6053 _rtw_memset(pwlanhdr->addr1, 0, ETH_ALEN);
6054 _rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN);
6055
6056 /* BSSID fill by FW */
6057 _rtw_memset(pwlanhdr->addr3, 0, ETH_ALEN);
6058
6059 SetSeqNum(pwlanhdr, 0);
6060 set_frame_sub_type(pframe, WIFI_ACTION);
6061
6062 pframe += sizeof(struct rtw_ieee80211_hdr_3addr);
6063 pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
6064
6065 pframe = rtw_set_fixed_ie(pframe, 1, &(category), &(pktlen));
6066 pframe = rtw_set_fixed_ie(pframe, 1, &(action), &(pktlen));
6067 pframe = rtw_set_fixed_ie(pframe, 4, (unsigned char *) &(p2poui), &(pktlen));
6068 pframe = rtw_set_fixed_ie(pframe, 1, &(oui_subtype), &(pktlen));
6069
6070 /* dialog token, filled by FW */
6071 pframe = rtw_set_fixed_ie(pframe, 1, &(dialogToken), &(pktlen));
6072
6073 /* P2P IE Section. */
6074
6075 /* P2P OUI */
6076 p2pielen = 0;
6077 p2pie[p2pielen++] = 0x50;
6078 p2pie[p2pielen++] = 0x6F;
6079 p2pie[p2pielen++] = 0x9A;
6080 p2pie[p2pielen++] = 0x09; /* WFA P2P v1.0 */
6081
6082 /* Commented by Albert 20101005 */
6083 /* According to the P2P Specification, the P2P Invitation response frame should contain 5 P2P attributes */
6084 /* 1. Status */
6085 /* 2. Configuration Timeout */
6086 /* 3. Operating Channel ( Only GO ) */
6087 /* 4. P2P Group BSSID ( Only GO ) */
6088 /* 5. Channel List */
6089
6090 /* P2P Status */
6091 /* Type: */
6092 p2pie[p2pielen++] = P2P_ATTR_STATUS;
6093
6094 /* Length: */
6095 *(u16 *)(p2pie + p2pielen) = cpu_to_le16(0x0001);
6096 p2pielen += 2;
6097
6098 /* Value: filled by FW, defult value is FAIL INFO UNAVAILABLE */
6099 p2pie[p2pielen++] = P2P_STATUS_FAIL_INFO_UNAVAILABLE;
6100
6101 /* Configuration Timeout */
6102 /* Type: */
6103 p2pie[p2pielen++] = P2P_ATTR_CONF_TIMEOUT;
6104
6105 /* Length: */
6106 *(u16 *)(p2pie + p2pielen) = cpu_to_le16(0x0002);
6107 p2pielen += 2;
6108
6109 /* Value: */
6110 p2pie[p2pielen++] = 200; /* 2 seconds needed to be the P2P GO */
6111 p2pie[p2pielen++] = 200; /* 2 seconds needed to be the P2P Client */
6112
6113 /* due to defult value is FAIL INFO UNAVAILABLE, so the following IE is not needed */
6114 #if 0
6115 if (status_code == P2P_STATUS_SUCCESS) {
6116 struct p2p_channels *ch_list = &(adapter_to_rfctl(padapter)->channel_list);
6117
6118 if (rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO)) {
6119 /* The P2P Invitation request frame asks this Wi-Fi device to be the P2P GO */
6120 /* In this case, the P2P Invitation response frame should carry the two more P2P attributes. */
6121 /* First one is operating channel attribute. */
6122 /* Second one is P2P Group BSSID attribute. */
6123
6124 /* Operating Channel */
6125 /* Type: */
6126 p2pie[p2pielen++] = P2P_ATTR_OPERATING_CH;
6127
6128 /* Length: */
6129 *(u16 *)(p2pie + p2pielen) = cpu_to_le16(0x0005);
6130 p2pielen += 2;
6131
6132 /* Value: */
6133 /* Country String */
6134 p2pie[p2pielen++] = 'X';
6135 p2pie[p2pielen++] = 'X';
6136
6137 /* The third byte should be set to 0x04. */
6138 /* Described in the "Operating Channel Attribute" section. */
6139 p2pie[p2pielen++] = 0x04;
6140
6141 /* Operating Class */
6142 p2pie[p2pielen++] = 0x51; /* Copy from SD7 */
6143
6144 /* Channel Number */
6145 p2pie[p2pielen++] = pwdinfo->operating_channel; /* operating channel number */
6146
6147
6148 /* P2P Group BSSID */
6149 /* Type: */
6150 p2pie[p2pielen++] = P2P_ATTR_GROUP_BSSID;
6151
6152 /* Length: */
6153 *(u16 *)(p2pie + p2pielen) = cpu_to_le16(ETH_ALEN);
6154 p2pielen += 2;
6155
6156 /* Value: */
6157 /* P2P Device Address for GO */
6158 _rtw_memcpy(p2pie + p2pielen, adapter_mac_addr(padapter), ETH_ALEN);
6159 p2pielen += ETH_ALEN;
6160
6161 }
6162
6163 /* Channel List */
6164 /* Type: */
6165 p2pie[p2pielen++] = P2P_ATTR_CH_LIST;
6166
6167 /* Length: */
6168 /* Country String(3) */
6169 /* + ( Operating Class (1) + Number of Channels(1) ) * Operation Classes (?) */
6170 /* + number of channels in all classes */
6171 len_channellist_attr = 3
6172 + (1 + 1) * (u16)ch_list->reg_classes
6173 + get_reg_classes_full_count(ch_list);
6174
6175 #ifdef CONFIG_CONCURRENT_MODE
6176 if (rtw_mi_check_status(padapter, MI_LINKED))
6177 *(u16 *)(p2pie + p2pielen) = cpu_to_le16(5 + 1);
6178 else
6179 *(u16 *)(p2pie + p2pielen) = cpu_to_le16(len_channellist_attr);
6180
6181 #else
6182
6183 *(u16 *)(p2pie + p2pielen) = cpu_to_le16(len_channellist_attr);
6184
6185 #endif
6186 p2pielen += 2;
6187
6188 /* Value: */
6189 /* Country String */
6190 p2pie[p2pielen++] = 'X';
6191 p2pie[p2pielen++] = 'X';
6192
6193 /* The third byte should be set to 0x04. */
6194 /* Described in the "Operating Channel Attribute" section. */
6195 p2pie[p2pielen++] = 0x04;
6196
6197 /* Channel Entry List */
6198 #ifdef CONFIG_CONCURRENT_MODE
6199 if (rtw_mi_check_status(padapter, MI_LINKED)) {
6200 u8 union_ch = rtw_mi_get_union_chan(padapter);
6201
6202 /* Operating Class */
6203 if (union_ch > 14) {
6204 if (union_ch >= 149)
6205 p2pie[p2pielen++] = 0x7c;
6206 else
6207 p2pie[p2pielen++] = 0x73;
6208
6209 } else
6210 p2pie[p2pielen++] = 0x51;
6211
6212
6213 /* Number of Channels */
6214 /* Just support 1 channel and this channel is AP's channel */
6215 p2pie[p2pielen++] = 1;
6216
6217 /* Channel List */
6218 p2pie[p2pielen++] = union_ch;
6219 } else
6220 #endif /* CONFIG_CONCURRENT_MODE */
6221 {
6222 int i, j;
6223 for (j = 0; j < ch_list->reg_classes; j++) {
6224 /* Operating Class */
6225 p2pie[p2pielen++] = ch_list->reg_class[j].reg_class;
6226
6227 /* Number of Channels */
6228 p2pie[p2pielen++] = ch_list->reg_class[j].channels;
6229
6230 /* Channel List */
6231 for (i = 0; i < ch_list->reg_class[j].channels; i++)
6232 p2pie[p2pielen++] = ch_list->reg_class[j].channel[i];
6233 }
6234 }
6235 }
6236 #endif
6237
6238 pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, p2pielen, (unsigned char *) p2pie, &pktlen);
6239
6240 #ifdef CONFIG_WFD
6241 wfdielen = build_invitation_resp_wfd_ie(pwdinfo, pframe);
6242 pframe += wfdielen;
6243 pktlen += wfdielen;
6244 #endif
6245
6246 *pLength = pktlen;
6247
6248 #if 0
6249 /* printf dbg msg */
6250 dbgbufLen = pktlen;
6251 RTW_INFO("======> DBG MSG FOR CONSTRAUCT Invite Rsp\n");
6252
6253 for (index = 0; index < dbgbufLen; index++)
6254 printk("%x ", *(dbgbuf + index));
6255
6256 printk("\n");
6257 RTW_INFO("<====== DBG MSG FOR CONSTRAUCT Invite Rsp\n");
6258 #endif
6259 }
6260
6261
rtw_hal_construct_P2PProvisionDisRsp(_adapter * padapter,u8 * pframe,u32 * pLength)6262 static void rtw_hal_construct_P2PProvisionDisRsp(_adapter *padapter, u8 *pframe, u32 *pLength)
6263 {
6264 unsigned char category = RTW_WLAN_CATEGORY_PUBLIC;
6265 u8 action = P2P_PUB_ACTION_ACTION;
6266 u8 dialogToken = 0;
6267 u32 p2poui = cpu_to_be32(P2POUI);
6268 u8 oui_subtype = P2P_PROVISION_DISC_RESP;
6269 u8 wpsie[100] = { 0x00 };
6270 u8 wpsielen = 0;
6271 u32 pktlen;
6272 #ifdef CONFIG_WFD
6273 u32 wfdielen = 0;
6274 #endif
6275
6276 /* struct xmit_frame *pmgntframe; */
6277 /* struct pkt_attrib *pattrib; */
6278 /* unsigned char *pframe; */
6279 struct rtw_ieee80211_hdr *pwlanhdr;
6280 unsigned short *fctrl;
6281 struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
6282 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
6283 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
6284 struct wifidirect_info *pwdinfo = &(padapter->wdinfo);
6285
6286 /* for debug */
6287 u8 *dbgbuf = pframe;
6288 u8 dbgbufLen = 0, index = 0;
6289
6290 RTW_INFO("%s\n", __FUNCTION__);
6291
6292 pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
6293
6294 fctrl = &(pwlanhdr->frame_ctl);
6295 *(fctrl) = 0;
6296
6297 /* RA filled by FW */
6298 _rtw_memset(pwlanhdr->addr1, 0, ETH_ALEN);
6299 _rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN);
6300 _rtw_memcpy(pwlanhdr->addr3, adapter_mac_addr(padapter), ETH_ALEN);
6301
6302 SetSeqNum(pwlanhdr, 0);
6303 set_frame_sub_type(pframe, WIFI_ACTION);
6304
6305 pframe += sizeof(struct rtw_ieee80211_hdr_3addr);
6306 pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
6307
6308 pframe = rtw_set_fixed_ie(pframe, 1, &(category), &(pktlen));
6309 pframe = rtw_set_fixed_ie(pframe, 1, &(action), &(pktlen));
6310 pframe = rtw_set_fixed_ie(pframe, 4, (unsigned char *) &(p2poui), &(pktlen));
6311 pframe = rtw_set_fixed_ie(pframe, 1, &(oui_subtype), &(pktlen));
6312 /* dialog token, filled by FW */
6313 pframe = rtw_set_fixed_ie(pframe, 1, &(dialogToken), &(pktlen));
6314
6315 wpsielen = 0;
6316 /* WPS OUI */
6317 /* *(u32*) ( wpsie ) = cpu_to_be32( WPSOUI ); */
6318 RTW_PUT_BE32(wpsie, WPSOUI);
6319 wpsielen += 4;
6320
6321 #if 0
6322 /* WPS version */
6323 /* Type: */
6324 *(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_VER1);
6325 wpsielen += 2;
6326
6327 /* Length: */
6328 *(u16 *)(wpsie + wpsielen) = cpu_to_be16(0x0001);
6329 wpsielen += 2;
6330
6331 /* Value: */
6332 wpsie[wpsielen++] = WPS_VERSION_1; /* Version 1.0 */
6333 #endif
6334
6335 /* Config Method */
6336 /* Type: */
6337 /* *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_ATTR_CONF_METHOD ); */
6338 RTW_PUT_BE16(wpsie + wpsielen, WPS_ATTR_CONF_METHOD);
6339 wpsielen += 2;
6340
6341 /* Length: */
6342 /* *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( 0x0002 ); */
6343 RTW_PUT_BE16(wpsie + wpsielen, 0x0002);
6344 wpsielen += 2;
6345
6346 /* Value: filled by FW, default value is PBC */
6347 /* *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( config_method ); */
6348 RTW_PUT_BE16(wpsie + wpsielen, WPS_CM_PUSH_BUTTON);
6349 wpsielen += 2;
6350
6351 pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, wpsielen, (unsigned char *) wpsie, &pktlen);
6352
6353 #ifdef CONFIG_WFD
6354 wfdielen = build_provdisc_resp_wfd_ie(pwdinfo, pframe);
6355 pframe += wfdielen;
6356 pktlen += wfdielen;
6357 #endif
6358
6359 *pLength = pktlen;
6360
6361 /* printf dbg msg */
6362 #if 0
6363 dbgbufLen = pktlen;
6364 RTW_INFO("======> DBG MSG FOR CONSTRAUCT ProvisionDis Rsp\n");
6365
6366 for (index = 0; index < dbgbufLen; index++)
6367 printk("%x ", *(dbgbuf + index));
6368
6369 printk("\n");
6370 RTW_INFO("<====== DBG MSG FOR CONSTRAUCT ProvisionDis Rsp\n");
6371 #endif
6372 }
6373
rtw_hal_set_FwP2PRsvdPage_cmd(_adapter * adapter,PRSVDPAGE_LOC rsvdpageloc)6374 u8 rtw_hal_set_FwP2PRsvdPage_cmd(_adapter *adapter, PRSVDPAGE_LOC rsvdpageloc)
6375 {
6376 u8 u1H2CP2PRsvdPageParm[H2C_P2PRSVDPAGE_LOC_LEN] = {0};
6377 struct hal_ops *pHalFunc = &adapter->hal_func;
6378 u8 ret = _FAIL;
6379
6380 RTW_INFO("P2PRsvdPageLoc: P2PBeacon=%d P2PProbeRsp=%d NegoRsp=%d InviteRsp=%d PDRsp=%d\n",
6381 rsvdpageloc->LocP2PBeacon, rsvdpageloc->LocP2PProbeRsp,
6382 rsvdpageloc->LocNegoRsp, rsvdpageloc->LocInviteRsp,
6383 rsvdpageloc->LocPDRsp);
6384
6385 SET_H2CCMD_RSVDPAGE_LOC_P2P_BCN(u1H2CP2PRsvdPageParm, rsvdpageloc->LocProbeRsp);
6386 SET_H2CCMD_RSVDPAGE_LOC_P2P_PROBE_RSP(u1H2CP2PRsvdPageParm, rsvdpageloc->LocPsPoll);
6387 SET_H2CCMD_RSVDPAGE_LOC_P2P_NEGO_RSP(u1H2CP2PRsvdPageParm, rsvdpageloc->LocNullData);
6388 SET_H2CCMD_RSVDPAGE_LOC_P2P_INVITE_RSP(u1H2CP2PRsvdPageParm, rsvdpageloc->LocQosNull);
6389 SET_H2CCMD_RSVDPAGE_LOC_P2P_PD_RSP(u1H2CP2PRsvdPageParm, rsvdpageloc->LocBTQosNull);
6390
6391 /* FillH2CCmd8723B(padapter, H2C_8723B_P2P_OFFLOAD_RSVD_PAGE, H2C_P2PRSVDPAGE_LOC_LEN, u1H2CP2PRsvdPageParm); */
6392 ret = rtw_hal_fill_h2c_cmd(adapter,
6393 H2C_P2P_OFFLOAD_RSVD_PAGE,
6394 H2C_P2PRSVDPAGE_LOC_LEN,
6395 u1H2CP2PRsvdPageParm);
6396
6397 return ret;
6398 }
6399
rtw_hal_set_p2p_wowlan_offload_cmd(_adapter * adapter)6400 u8 rtw_hal_set_p2p_wowlan_offload_cmd(_adapter *adapter)
6401 {
6402
6403 u8 offload_cmd[H2C_P2P_OFFLOAD_LEN] = {0};
6404 struct wifidirect_info *pwdinfo = &(adapter->wdinfo);
6405 struct P2P_WoWlan_Offload_t *p2p_wowlan_offload = (struct P2P_WoWlan_Offload_t *)offload_cmd;
6406 struct hal_ops *pHalFunc = &adapter->hal_func;
6407 u8 ret = _FAIL;
6408
6409 _rtw_memset(p2p_wowlan_offload, 0 , sizeof(struct P2P_WoWlan_Offload_t));
6410 RTW_INFO("%s\n", __func__);
6411 switch (pwdinfo->role) {
6412 case P2P_ROLE_DEVICE:
6413 RTW_INFO("P2P_ROLE_DEVICE\n");
6414 p2p_wowlan_offload->role = 0;
6415 break;
6416 case P2P_ROLE_CLIENT:
6417 RTW_INFO("P2P_ROLE_CLIENT\n");
6418 p2p_wowlan_offload->role = 1;
6419 break;
6420 case P2P_ROLE_GO:
6421 RTW_INFO("P2P_ROLE_GO\n");
6422 p2p_wowlan_offload->role = 2;
6423 break;
6424 default:
6425 RTW_INFO("P2P_ROLE_DISABLE\n");
6426 break;
6427 }
6428 p2p_wowlan_offload->Wps_Config[0] = pwdinfo->supported_wps_cm >> 8;
6429 p2p_wowlan_offload->Wps_Config[1] = pwdinfo->supported_wps_cm;
6430 offload_cmd = (u8 *)p2p_wowlan_offload;
6431 RTW_INFO("p2p_wowlan_offload: %x:%x:%x\n", offload_cmd[0], offload_cmd[1], offload_cmd[2]);
6432
6433 ret = rtw_hal_fill_h2c_cmd(adapter,
6434 H2C_P2P_OFFLOAD,
6435 H2C_P2P_OFFLOAD_LEN,
6436 offload_cmd);
6437 return ret;
6438
6439 /* FillH2CCmd8723B(adapter, H2C_8723B_P2P_OFFLOAD, sizeof(struct P2P_WoWlan_Offload_t), (u8 *)p2p_wowlan_offload); */
6440 }
6441 #endif /* CONFIG_P2P_WOWLAN */
6442
rtw_hal_construct_beacon(_adapter * padapter,u8 * pframe,u32 * pLength)6443 static void rtw_hal_construct_beacon(_adapter *padapter,
6444 u8 *pframe, u32 *pLength)
6445 {
6446 struct rtw_ieee80211_hdr *pwlanhdr;
6447 u16 *fctrl;
6448 u32 rate_len, pktlen;
6449 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
6450 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
6451 WLAN_BSSID_EX *cur_network = &(pmlmeinfo->network);
6452 u8 bc_addr[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
6453
6454
6455 /* RTW_INFO("%s\n", __FUNCTION__); */
6456
6457 pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
6458
6459 fctrl = &(pwlanhdr->frame_ctl);
6460 *(fctrl) = 0;
6461
6462 _rtw_memcpy(pwlanhdr->addr1, bc_addr, ETH_ALEN);
6463 _rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN);
6464 _rtw_memcpy(pwlanhdr->addr3, get_my_bssid(cur_network), ETH_ALEN);
6465
6466 SetSeqNum(pwlanhdr, 0/*pmlmeext->mgnt_seq*/);
6467 /* pmlmeext->mgnt_seq++; */
6468 set_frame_sub_type(pframe, WIFI_BEACON);
6469
6470 pframe += sizeof(struct rtw_ieee80211_hdr_3addr);
6471 pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
6472
6473 /* timestamp will be inserted by hardware */
6474 pframe += 8;
6475 pktlen += 8;
6476
6477 /* beacon interval: 2 bytes */
6478 _rtw_memcpy(pframe, (unsigned char *)(rtw_get_beacon_interval_from_ie(cur_network->IEs)), 2);
6479
6480 pframe += 2;
6481 pktlen += 2;
6482
6483 /* capability info: 2 bytes */
6484 _rtw_memcpy(pframe, (unsigned char *)(rtw_get_capability_from_ie(cur_network->IEs)), 2);
6485
6486 pframe += 2;
6487 pktlen += 2;
6488
6489 if ((pmlmeinfo->state & 0x03) == WIFI_FW_AP_STATE) {
6490 /* RTW_INFO("ie len=%d\n", cur_network->IELength); */
6491 pktlen += cur_network->IELength - sizeof(NDIS_802_11_FIXED_IEs);
6492 _rtw_memcpy(pframe, cur_network->IEs + sizeof(NDIS_802_11_FIXED_IEs), pktlen);
6493
6494 goto _ConstructBeacon;
6495 }
6496
6497 /* below for ad-hoc mode */
6498
6499 /* SSID */
6500 pframe = rtw_set_ie(pframe, _SSID_IE_, cur_network->Ssid.SsidLength, cur_network->Ssid.Ssid, &pktlen);
6501
6502 /* supported rates... */
6503 rate_len = rtw_get_rateset_len(cur_network->SupportedRates);
6504 pframe = rtw_set_ie(pframe, _SUPPORTEDRATES_IE_, ((rate_len > 8) ? 8 : rate_len), cur_network->SupportedRates, &pktlen);
6505
6506 /* DS parameter set */
6507 pframe = rtw_set_ie(pframe, _DSSET_IE_, 1, (unsigned char *)&(cur_network->Configuration.DSConfig), &pktlen);
6508
6509 if ((pmlmeinfo->state & 0x03) == WIFI_FW_ADHOC_STATE) {
6510 u32 ATIMWindow;
6511 /* IBSS Parameter Set... */
6512 /* ATIMWindow = cur->Configuration.ATIMWindow; */
6513 ATIMWindow = 0;
6514 pframe = rtw_set_ie(pframe, _IBSS_PARA_IE_, 2, (unsigned char *)(&ATIMWindow), &pktlen);
6515 }
6516
6517
6518 /* todo: ERP IE */
6519
6520
6521 /* EXTERNDED SUPPORTED RATE */
6522 if (rate_len > 8)
6523 pframe = rtw_set_ie(pframe, _EXT_SUPPORTEDRATES_IE_, (rate_len - 8), (cur_network->SupportedRates + 8), &pktlen);
6524
6525
6526 /* todo:HT for adhoc */
6527
6528 _ConstructBeacon:
6529
6530 if ((pktlen + TXDESC_SIZE) > 512) {
6531 RTW_INFO("beacon frame too large\n");
6532 return;
6533 }
6534
6535 *pLength = pktlen;
6536
6537 /* RTW_INFO("%s bcn_sz=%d\n", __FUNCTION__, pktlen); */
6538
6539 }
6540
rtw_hal_construct_PSPoll(_adapter * padapter,u8 * pframe,u32 * pLength)6541 static void rtw_hal_construct_PSPoll(_adapter *padapter,
6542 u8 *pframe, u32 *pLength)
6543 {
6544 struct rtw_ieee80211_hdr *pwlanhdr;
6545 u16 *fctrl;
6546 u32 pktlen;
6547 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
6548 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
6549
6550 /* RTW_INFO("%s\n", __FUNCTION__); */
6551
6552 pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
6553
6554 /* Frame control. */
6555 fctrl = &(pwlanhdr->frame_ctl);
6556 *(fctrl) = 0;
6557 SetPwrMgt(fctrl);
6558 set_frame_sub_type(pframe, WIFI_PSPOLL);
6559
6560 /* AID. */
6561 set_duration(pframe, (pmlmeinfo->aid | 0xc000));
6562
6563 /* BSSID. */
6564 _rtw_memcpy(pwlanhdr->addr1, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
6565
6566 /* TA. */
6567 _rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN);
6568
6569 *pLength = 16;
6570 }
6571
rtw_hal_construct_NullFunctionData(PADAPTER padapter,u8 * pframe,u32 * pLength,u8 * StaAddr,u8 bQoS,u8 AC,u8 bEosp,u8 bForcePowerSave)6572 void rtw_hal_construct_NullFunctionData(
6573 PADAPTER padapter,
6574 u8 *pframe,
6575 u32 *pLength,
6576 u8 *StaAddr,
6577 u8 bQoS,
6578 u8 AC,
6579 u8 bEosp,
6580 u8 bForcePowerSave)
6581 {
6582 struct rtw_ieee80211_hdr *pwlanhdr;
6583 u16 *fctrl;
6584 u32 pktlen;
6585 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
6586 struct wlan_network *cur_network = &pmlmepriv->cur_network;
6587 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
6588 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
6589
6590
6591 /* RTW_INFO("%s:%d\n", __FUNCTION__, bForcePowerSave); */
6592
6593 pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
6594
6595 fctrl = &pwlanhdr->frame_ctl;
6596 *(fctrl) = 0;
6597 if (bForcePowerSave)
6598 SetPwrMgt(fctrl);
6599
6600 switch (cur_network->network.InfrastructureMode) {
6601 case Ndis802_11Infrastructure:
6602 SetToDs(fctrl);
6603 _rtw_memcpy(pwlanhdr->addr1, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
6604 _rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN);
6605 _rtw_memcpy(pwlanhdr->addr3, StaAddr, ETH_ALEN);
6606 break;
6607 case Ndis802_11APMode:
6608 SetFrDs(fctrl);
6609 _rtw_memcpy(pwlanhdr->addr1, StaAddr, ETH_ALEN);
6610 _rtw_memcpy(pwlanhdr->addr2, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
6611 _rtw_memcpy(pwlanhdr->addr3, adapter_mac_addr(padapter), ETH_ALEN);
6612 break;
6613 case Ndis802_11IBSS:
6614 default:
6615 _rtw_memcpy(pwlanhdr->addr1, StaAddr, ETH_ALEN);
6616 _rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN);
6617 _rtw_memcpy(pwlanhdr->addr3, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
6618 break;
6619 }
6620
6621 SetSeqNum(pwlanhdr, 0);
6622
6623 if (bQoS == _TRUE) {
6624 struct rtw_ieee80211_hdr_3addr_qos *pwlanqoshdr;
6625
6626 set_frame_sub_type(pframe, WIFI_QOS_DATA_NULL);
6627
6628 pwlanqoshdr = (struct rtw_ieee80211_hdr_3addr_qos *)pframe;
6629 SetPriority(&pwlanqoshdr->qc, AC);
6630 SetEOSP(&pwlanqoshdr->qc, bEosp);
6631
6632 pktlen = sizeof(struct rtw_ieee80211_hdr_3addr_qos);
6633 } else {
6634 set_frame_sub_type(pframe, WIFI_DATA_NULL);
6635
6636 pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
6637 }
6638
6639 *pLength = pktlen;
6640 }
6641
rtw_hal_construct_ProbeRsp(_adapter * padapter,u8 * pframe,u32 * pLength,u8 * StaAddr,BOOLEAN bHideSSID)6642 void rtw_hal_construct_ProbeRsp(_adapter *padapter, u8 *pframe, u32 *pLength,
6643 u8 *StaAddr, BOOLEAN bHideSSID)
6644 {
6645 struct rtw_ieee80211_hdr *pwlanhdr;
6646 u16 *fctrl;
6647 u8 *mac, *bssid;
6648 u32 pktlen;
6649 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
6650 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
6651 WLAN_BSSID_EX *cur_network = &(pmlmeinfo->network);
6652
6653 /*RTW_INFO("%s\n", __FUNCTION__);*/
6654
6655 pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
6656
6657 mac = adapter_mac_addr(padapter);
6658 bssid = cur_network->MacAddress;
6659
6660 fctrl = &(pwlanhdr->frame_ctl);
6661 *(fctrl) = 0;
6662 _rtw_memcpy(pwlanhdr->addr1, StaAddr, ETH_ALEN);
6663 _rtw_memcpy(pwlanhdr->addr2, mac, ETH_ALEN);
6664 _rtw_memcpy(pwlanhdr->addr3, bssid, ETH_ALEN);
6665
6666 SetSeqNum(pwlanhdr, 0);
6667 set_frame_sub_type(fctrl, WIFI_PROBERSP);
6668
6669 pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
6670 pframe += pktlen;
6671
6672 if (cur_network->IELength > MAX_IE_SZ)
6673 return;
6674
6675 _rtw_memcpy(pframe, cur_network->IEs, cur_network->IELength);
6676 pframe += cur_network->IELength;
6677 pktlen += cur_network->IELength;
6678
6679 *pLength = pktlen;
6680 }
6681
6682 #ifdef CONFIG_WOWLAN
rtw_hal_append_tkip_mic(PADAPTER padapter,u8 * pframe,u32 offset)6683 static void rtw_hal_append_tkip_mic(PADAPTER padapter,
6684 u8 *pframe, u32 offset)
6685 {
6686 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
6687 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
6688 struct rtw_ieee80211_hdr *pwlanhdr;
6689 struct mic_data micdata;
6690 struct sta_info *psta = NULL;
6691 int res = 0;
6692
6693 u8 *payload = (u8 *)(pframe + offset);
6694
6695 u8 mic[8];
6696 u8 priority[4] = {0x0};
6697 u8 null_key[16] = {0x0};
6698
6699 RTW_INFO("%s(): Add MIC, offset: %d\n", __func__, offset);
6700
6701 pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
6702
6703 psta = rtw_get_stainfo(&padapter->stapriv,
6704 get_my_bssid(&(pmlmeinfo->network)));
6705 if (psta != NULL) {
6706 res = _rtw_memcmp(&psta->dot11tkiptxmickey.skey[0],
6707 null_key, 16);
6708 if (res == _TRUE)
6709 RTW_INFO("%s(): STA dot11tkiptxmickey==0\n", __func__);
6710 rtw_secmicsetkey(&micdata, &psta->dot11tkiptxmickey.skey[0]);
6711 }
6712
6713 rtw_secmicappend(&micdata, pwlanhdr->addr3, 6); /* DA */
6714
6715 rtw_secmicappend(&micdata, pwlanhdr->addr2, 6); /* SA */
6716
6717 priority[0] = 0;
6718
6719 rtw_secmicappend(&micdata, &priority[0], 4);
6720
6721 rtw_secmicappend(&micdata, payload, 36); /* payload length = 8 + 28 */
6722
6723 rtw_secgetmic(&micdata, &(mic[0]));
6724
6725 payload += 36;
6726
6727 _rtw_memcpy(payload, &(mic[0]), 8);
6728 }
6729 /*
6730 * Description:
6731 * Construct the ARP response packet to support ARP offload.
6732 * */
rtw_hal_construct_ARPRsp(PADAPTER padapter,u8 * pframe,u32 * pLength,u8 * pIPAddress)6733 static void rtw_hal_construct_ARPRsp(
6734 PADAPTER padapter,
6735 u8 *pframe,
6736 u32 *pLength,
6737 u8 *pIPAddress
6738 )
6739 {
6740 struct rtw_ieee80211_hdr *pwlanhdr;
6741 u16 *fctrl;
6742 u32 pktlen;
6743 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
6744 struct wlan_network *cur_network = &pmlmepriv->cur_network;
6745 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
6746 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
6747 struct security_priv *psecuritypriv = &padapter->securitypriv;
6748 static u8 ARPLLCHeader[8] = {0xAA, 0xAA, 0x03, 0x00, 0x00, 0x00, 0x08, 0x06};
6749 u8 *pARPRspPkt = pframe;
6750 /* for TKIP Cal MIC */
6751 u8 *payload = pframe;
6752 u8 EncryptionHeadOverhead = 0, arp_offset = 0;
6753 /* RTW_INFO("%s:%d\n", __FUNCTION__, bForcePowerSave); */
6754
6755 pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
6756
6757 fctrl = &pwlanhdr->frame_ctl;
6758 *(fctrl) = 0;
6759
6760 /* ------------------------------------------------------------------------- */
6761 /* MAC Header. */
6762 /* ------------------------------------------------------------------------- */
6763 SetFrameType(fctrl, WIFI_DATA);
6764 /* set_frame_sub_type(fctrl, 0); */
6765 SetToDs(fctrl);
6766 _rtw_memcpy(pwlanhdr->addr1, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
6767 _rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN);
6768 _rtw_memcpy(pwlanhdr->addr3, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
6769
6770 SetSeqNum(pwlanhdr, 0);
6771 set_duration(pwlanhdr, 0);
6772 /* SET_80211_HDR_FRAME_CONTROL(pARPRspPkt, 0); */
6773 /* SET_80211_HDR_TYPE_AND_SUBTYPE(pARPRspPkt, Type_Data); */
6774 /* SET_80211_HDR_TO_DS(pARPRspPkt, 1); */
6775 /* SET_80211_HDR_ADDRESS1(pARPRspPkt, pMgntInfo->Bssid); */
6776 /* SET_80211_HDR_ADDRESS2(pARPRspPkt, Adapter->CurrentAddress); */
6777 /* SET_80211_HDR_ADDRESS3(pARPRspPkt, pMgntInfo->Bssid); */
6778
6779 /* SET_80211_HDR_DURATION(pARPRspPkt, 0); */
6780 /* SET_80211_HDR_FRAGMENT_SEQUENCE(pARPRspPkt, 0); */
6781 #ifdef CONFIG_WAPI_SUPPORT
6782 *pLength = sMacHdrLng;
6783 #else
6784 *pLength = 24;
6785 #endif
6786 switch (psecuritypriv->dot11PrivacyAlgrthm) {
6787 case _WEP40_:
6788 case _WEP104_:
6789 EncryptionHeadOverhead = 4;
6790 break;
6791 case _TKIP_:
6792 EncryptionHeadOverhead = 8;
6793 break;
6794 case _AES_:
6795 EncryptionHeadOverhead = 8;
6796 break;
6797 #ifdef CONFIG_WAPI_SUPPORT
6798 case _SMS4_:
6799 EncryptionHeadOverhead = 18;
6800 break;
6801 #endif
6802 default:
6803 EncryptionHeadOverhead = 0;
6804 }
6805
6806 if (EncryptionHeadOverhead > 0) {
6807 _rtw_memset(&(pframe[*pLength]), 0, EncryptionHeadOverhead);
6808 *pLength += EncryptionHeadOverhead;
6809 /* SET_80211_HDR_WEP(pARPRspPkt, 1); */ /* Suggested by CCW. */
6810 SetPrivacy(fctrl);
6811 }
6812
6813 /* ------------------------------------------------------------------------- */
6814 /* Frame Body. */
6815 /* ------------------------------------------------------------------------- */
6816 arp_offset = *pLength;
6817 pARPRspPkt = (u8 *)(pframe + arp_offset);
6818 payload = pARPRspPkt; /* Get Payload pointer */
6819 /* LLC header */
6820 _rtw_memcpy(pARPRspPkt, ARPLLCHeader, 8);
6821 *pLength += 8;
6822
6823 /* ARP element */
6824 pARPRspPkt += 8;
6825 SET_ARP_PKT_HW(pARPRspPkt, 0x0100);
6826 SET_ARP_PKT_PROTOCOL(pARPRspPkt, 0x0008); /* IP protocol */
6827 SET_ARP_PKT_HW_ADDR_LEN(pARPRspPkt, 6);
6828 SET_ARP_PKT_PROTOCOL_ADDR_LEN(pARPRspPkt, 4);
6829 SET_ARP_PKT_OPERATION(pARPRspPkt, 0x0200); /* ARP response */
6830 SET_ARP_PKT_SENDER_MAC_ADDR(pARPRspPkt, adapter_mac_addr(padapter));
6831 SET_ARP_PKT_SENDER_IP_ADDR(pARPRspPkt, pIPAddress);
6832 #ifdef CONFIG_ARP_KEEP_ALIVE
6833 if (!is_zero_mac_addr(pmlmepriv->gw_mac_addr)) {
6834 SET_ARP_PKT_TARGET_MAC_ADDR(pARPRspPkt, pmlmepriv->gw_mac_addr);
6835 SET_ARP_PKT_TARGET_IP_ADDR(pARPRspPkt, pmlmepriv->gw_ip);
6836 } else
6837 #endif
6838 {
6839 SET_ARP_PKT_TARGET_MAC_ADDR(pARPRspPkt,
6840 get_my_bssid(&(pmlmeinfo->network)));
6841 SET_ARP_PKT_TARGET_IP_ADDR(pARPRspPkt,
6842 pIPAddress);
6843 RTW_INFO("%s Target Mac Addr:" MAC_FMT "\n", __FUNCTION__,
6844 MAC_ARG(get_my_bssid(&(pmlmeinfo->network))));
6845 RTW_INFO("%s Target IP Addr" IP_FMT "\n", __FUNCTION__,
6846 IP_ARG(pIPAddress));
6847 }
6848
6849 *pLength += 28;
6850
6851 if (psecuritypriv->dot11PrivacyAlgrthm == _TKIP_) {
6852 if (IS_HARDWARE_TYPE_8188E(padapter) ||
6853 IS_HARDWARE_TYPE_8812(padapter)) {
6854 rtw_hal_append_tkip_mic(padapter, pframe, arp_offset);
6855 }
6856 *pLength += 8;
6857 }
6858 }
6859
6860 #ifdef CONFIG_IPV6
6861 /*
6862 * Description: Neighbor Discovery Offload.
6863 */
rtw_hal_construct_na_message(_adapter * padapter,u8 * pframe,u32 * pLength)6864 static void rtw_hal_construct_na_message(_adapter *padapter,
6865 u8 *pframe, u32 *pLength)
6866 {
6867 struct rtw_ieee80211_hdr *pwlanhdr = NULL;
6868 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
6869 struct wlan_network *cur_network = &pmlmepriv->cur_network;
6870 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
6871 struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
6872 struct security_priv *psecuritypriv = &padapter->securitypriv;
6873
6874 u32 pktlen = 0;
6875 u16 *fctrl = NULL;
6876
6877 u8 ns_hdr[8] = {0xAA, 0xAA, 0x03, 0x00, 0x00, 0x00, 0x86, 0xDD};
6878 u8 ipv6_info[4] = {0x60, 0x00, 0x00, 0x00};
6879 u8 ipv6_contx[4] = {0x00, 0x20, 0x3a, 0xff};
6880 u8 icmpv6_hdr[8] = {0x88, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00};
6881 u8 val8 = 0;
6882
6883 u8 *p_na_msg = pframe;
6884 /* for TKIP Cal MIC */
6885 u8 *payload = pframe;
6886 u8 EncryptionHeadOverhead = 0, na_msg_offset = 0;
6887 /* RTW_INFO("%s:%d\n", __FUNCTION__, bForcePowerSave); */
6888
6889 pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
6890
6891 fctrl = &pwlanhdr->frame_ctl;
6892 *(fctrl) = 0;
6893
6894 /* ------------------------------------------------------------------------- */
6895 /* MAC Header. */
6896 /* ------------------------------------------------------------------------- */
6897 SetFrameType(fctrl, WIFI_DATA);
6898 SetToDs(fctrl);
6899 _rtw_memcpy(pwlanhdr->addr1,
6900 get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
6901 _rtw_memcpy(pwlanhdr->addr2,
6902 adapter_mac_addr(padapter), ETH_ALEN);
6903 _rtw_memcpy(pwlanhdr->addr3,
6904 get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
6905
6906 SetSeqNum(pwlanhdr, 0);
6907 set_duration(pwlanhdr, 0);
6908
6909 #ifdef CONFIG_WAPI_SUPPORT
6910 *pLength = sMacHdrLng;
6911 #else
6912 *pLength = 24;
6913 #endif
6914 switch (psecuritypriv->dot11PrivacyAlgrthm) {
6915 case _WEP40_:
6916 case _WEP104_:
6917 EncryptionHeadOverhead = 4;
6918 break;
6919 case _TKIP_:
6920 EncryptionHeadOverhead = 8;
6921 break;
6922 case _AES_:
6923 EncryptionHeadOverhead = 8;
6924 break;
6925 #ifdef CONFIG_WAPI_SUPPORT
6926 case _SMS4_:
6927 EncryptionHeadOverhead = 18;
6928 break;
6929 #endif
6930 default:
6931 EncryptionHeadOverhead = 0;
6932 }
6933
6934 if (EncryptionHeadOverhead > 0) {
6935 _rtw_memset(&(pframe[*pLength]), 0, EncryptionHeadOverhead);
6936 *pLength += EncryptionHeadOverhead;
6937 /* SET_80211_HDR_WEP(pARPRspPkt, 1); */ /* Suggested by CCW. */
6938 SetPrivacy(fctrl);
6939 }
6940
6941 /* ------------------------------------------------------------------------- */
6942 /* Frame Body. */
6943 /* ------------------------------------------------------------------------- */
6944 na_msg_offset = *pLength;
6945 p_na_msg = (u8 *)(pframe + na_msg_offset);
6946 payload = p_na_msg; /* Get Payload pointer */
6947
6948 /* LLC header */
6949 val8 = sizeof(ns_hdr);
6950 _rtw_memcpy(p_na_msg, ns_hdr, val8);
6951 *pLength += val8;
6952 p_na_msg += val8;
6953
6954 /* IPv6 Header */
6955 /* 1 . Information (4 bytes): 0x60 0x00 0x00 0x00 */
6956 val8 = sizeof(ipv6_info);
6957 _rtw_memcpy(p_na_msg, ipv6_info, val8);
6958 *pLength += val8;
6959 p_na_msg += val8;
6960
6961 /* 2 . playload : 0x00 0x20 , NextProt : 0x3a (ICMPv6) HopLim : 0xff */
6962 val8 = sizeof(ipv6_contx);
6963 _rtw_memcpy(p_na_msg, ipv6_contx, val8);
6964 *pLength += val8;
6965 p_na_msg += val8;
6966
6967 /* 3 . SA : 16 bytes , DA : 16 bytes ( Fw will filled ) */
6968 _rtw_memset(&(p_na_msg[*pLength]), 0, 32);
6969 *pLength += 32;
6970 p_na_msg += 32;
6971
6972 /* ICMPv6 */
6973 /* 1. Type : 0x88 (NA)
6974 * 2. Code : 0x00
6975 * 3. ChechSum : 0x00 0x00 (RSvd)
6976 * 4. NAFlag: 0x60 0x00 0x00 0x00 ( Solicited , Override)
6977 */
6978 val8 = sizeof(icmpv6_hdr);
6979 _rtw_memcpy(p_na_msg, icmpv6_hdr, val8);
6980 *pLength += val8;
6981 p_na_msg += val8;
6982
6983 /* TA: 16 bytes*/
6984 _rtw_memset(&(p_na_msg[*pLength]), 0, 16);
6985 *pLength += 16;
6986 p_na_msg += 16;
6987
6988 /* ICMPv6 Target Link Layer Address */
6989 p_na_msg[0] = 0x02; /* type */
6990 p_na_msg[1] = 0x01; /* len 1 unit of 8 octes */
6991 *pLength += 2;
6992 p_na_msg += 2;
6993
6994 _rtw_memset(&(p_na_msg[*pLength]), 0, 6);
6995 *pLength += 6;
6996 p_na_msg += 6;
6997
6998 if (psecuritypriv->dot11PrivacyAlgrthm == _TKIP_) {
6999 if (IS_HARDWARE_TYPE_8188E(padapter) ||
7000 IS_HARDWARE_TYPE_8812(padapter)) {
7001 rtw_hal_append_tkip_mic(padapter, pframe,
7002 na_msg_offset);
7003 }
7004 *pLength += 8;
7005 }
7006 }
7007 /*
7008 * Description: Neighbor Discovery Protocol Information.
7009 */
rtw_hal_construct_ndp_info(_adapter * padapter,u8 * pframe,u32 * pLength)7010 static void rtw_hal_construct_ndp_info(_adapter *padapter,
7011 u8 *pframe, u32 *pLength)
7012 {
7013 struct mlme_ext_priv *pmlmeext = NULL;
7014 struct mlme_ext_info *pmlmeinfo = NULL;
7015 struct rtw_ndp_info ndp_info;
7016 u8 *pndp_info = pframe;
7017 u8 len = sizeof(struct rtw_ndp_info);
7018
7019 RTW_INFO("%s: len: %d\n", __func__, len);
7020
7021 pmlmeext = &padapter->mlmeextpriv;
7022 pmlmeinfo = &pmlmeext->mlmext_info;
7023
7024 _rtw_memset(pframe, 0, len);
7025 _rtw_memset(&ndp_info, 0, len);
7026
7027 ndp_info.enable = 1;
7028 ndp_info.check_remote_ip = 0;
7029 ndp_info.num_of_target_ip = 1;
7030
7031 _rtw_memcpy(&ndp_info.target_link_addr, adapter_mac_addr(padapter),
7032 ETH_ALEN);
7033 _rtw_memcpy(&ndp_info.target_ipv6_addr, pmlmeinfo->ip6_addr,
7034 RTW_IPv6_ADDR_LEN);
7035
7036 _rtw_memcpy(pndp_info, &ndp_info, len);
7037 }
7038 #endif /* CONFIG_IPV6 */
7039
7040 #ifdef CONFIG_PNO_SUPPORT
rtw_hal_construct_ProbeReq(_adapter * padapter,u8 * pframe,u32 * pLength,pno_ssid_t * ssid)7041 static void rtw_hal_construct_ProbeReq(_adapter *padapter, u8 *pframe,
7042 u32 *pLength, pno_ssid_t *ssid)
7043 {
7044 struct rtw_ieee80211_hdr *pwlanhdr;
7045 u16 *fctrl;
7046 u32 pktlen;
7047 unsigned char *mac;
7048 unsigned char bssrate[NumRates];
7049 struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
7050 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
7051 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
7052 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
7053 int bssrate_len = 0;
7054 u8 bc_addr[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
7055
7056 pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
7057 mac = adapter_mac_addr(padapter);
7058
7059 fctrl = &(pwlanhdr->frame_ctl);
7060 *(fctrl) = 0;
7061
7062 _rtw_memcpy(pwlanhdr->addr1, bc_addr, ETH_ALEN);
7063 _rtw_memcpy(pwlanhdr->addr3, bc_addr, ETH_ALEN);
7064
7065 _rtw_memcpy(pwlanhdr->addr2, mac, ETH_ALEN);
7066
7067 SetSeqNum(pwlanhdr, 0);
7068 set_frame_sub_type(pframe, WIFI_PROBEREQ);
7069
7070 pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
7071 pframe += pktlen;
7072
7073 if (ssid == NULL)
7074 pframe = rtw_set_ie(pframe, _SSID_IE_, 0, NULL, &pktlen);
7075 else {
7076 /* RTW_INFO("%s len:%d\n", ssid->SSID, ssid->SSID_len); */
7077 pframe = rtw_set_ie(pframe, _SSID_IE_, ssid->SSID_len, ssid->SSID, &pktlen);
7078 }
7079
7080 get_rate_set(padapter, bssrate, &bssrate_len);
7081
7082 if (bssrate_len > 8) {
7083 pframe = rtw_set_ie(pframe, _SUPPORTEDRATES_IE_ , 8, bssrate, &pktlen);
7084 pframe = rtw_set_ie(pframe, _EXT_SUPPORTEDRATES_IE_ , (bssrate_len - 8), (bssrate + 8), &pktlen);
7085 } else
7086 pframe = rtw_set_ie(pframe, _SUPPORTEDRATES_IE_ , bssrate_len , bssrate, &pktlen);
7087
7088 *pLength = pktlen;
7089 }
7090
rtw_hal_construct_PNO_info(_adapter * padapter,u8 * pframe,u32 * pLength)7091 static void rtw_hal_construct_PNO_info(_adapter *padapter,
7092 u8 *pframe, u32 *pLength)
7093 {
7094 struct pwrctrl_priv *pwrctl = adapter_to_pwrctl(padapter);
7095 int i;
7096
7097 u8 *pPnoInfoPkt = pframe;
7098 pPnoInfoPkt = (u8 *)(pframe + *pLength);
7099 _rtw_memcpy(pPnoInfoPkt, &pwrctl->pnlo_info->ssid_num, 1);
7100
7101 pPnoInfoPkt += 1;
7102 _rtw_memcpy(pPnoInfoPkt, &pwrctl->pnlo_info->hidden_ssid_num, 1);
7103
7104 pPnoInfoPkt += 3;
7105 _rtw_memcpy(pPnoInfoPkt, &pwrctl->pnlo_info->fast_scan_period, 1);
7106
7107 pPnoInfoPkt += 4;
7108 _rtw_memcpy(pPnoInfoPkt, &pwrctl->pnlo_info->fast_scan_iterations, 4);
7109
7110 pPnoInfoPkt += 4;
7111 _rtw_memcpy(pPnoInfoPkt, &pwrctl->pnlo_info->slow_scan_period, 4);
7112
7113 pPnoInfoPkt += 4;
7114 _rtw_memcpy(pPnoInfoPkt, &pwrctl->pnlo_info->ssid_length, MAX_PNO_LIST_COUNT);
7115
7116 pPnoInfoPkt += MAX_PNO_LIST_COUNT;
7117 _rtw_memcpy(pPnoInfoPkt, &pwrctl->pnlo_info->ssid_cipher_info, MAX_PNO_LIST_COUNT);
7118
7119 pPnoInfoPkt += MAX_PNO_LIST_COUNT;
7120 _rtw_memcpy(pPnoInfoPkt, &pwrctl->pnlo_info->ssid_channel_info, MAX_PNO_LIST_COUNT);
7121
7122 pPnoInfoPkt += MAX_PNO_LIST_COUNT;
7123 _rtw_memcpy(pPnoInfoPkt, &pwrctl->pnlo_info->loc_probe_req, MAX_HIDDEN_AP);
7124
7125 pPnoInfoPkt += MAX_HIDDEN_AP;
7126
7127 /*
7128 SSID is located at 128th Byte in NLO info Page
7129 */
7130
7131 *pLength += 128;
7132 pPnoInfoPkt = pframe + 128;
7133
7134 for (i = 0; i < pwrctl->pnlo_info->ssid_num ; i++) {
7135 _rtw_memcpy(pPnoInfoPkt, &pwrctl->pno_ssid_list->node[i].SSID,
7136 pwrctl->pnlo_info->ssid_length[i]);
7137 *pLength += WLAN_SSID_MAXLEN;
7138 pPnoInfoPkt += WLAN_SSID_MAXLEN;
7139 }
7140 }
7141
rtw_hal_construct_ssid_list(_adapter * padapter,u8 * pframe,u32 * pLength)7142 static void rtw_hal_construct_ssid_list(_adapter *padapter,
7143 u8 *pframe, u32 *pLength)
7144 {
7145 struct pwrctrl_priv *pwrctl = adapter_to_pwrctl(padapter);
7146 u8 *pSSIDListPkt = pframe;
7147 int i;
7148
7149 pSSIDListPkt = (u8 *)(pframe + *pLength);
7150
7151 for (i = 0; i < pwrctl->pnlo_info->ssid_num ; i++) {
7152 _rtw_memcpy(pSSIDListPkt, &pwrctl->pno_ssid_list->node[i].SSID,
7153 pwrctl->pnlo_info->ssid_length[i]);
7154
7155 *pLength += WLAN_SSID_MAXLEN;
7156 pSSIDListPkt += WLAN_SSID_MAXLEN;
7157 }
7158 }
7159
rtw_hal_construct_scan_info(_adapter * padapter,u8 * pframe,u32 * pLength)7160 static void rtw_hal_construct_scan_info(_adapter *padapter,
7161 u8 *pframe, u32 *pLength)
7162 {
7163 struct pwrctrl_priv *pwrctl = adapter_to_pwrctl(padapter);
7164 u8 *pScanInfoPkt = pframe;
7165 int i;
7166
7167 pScanInfoPkt = (u8 *)(pframe + *pLength);
7168
7169 _rtw_memcpy(pScanInfoPkt, &pwrctl->pscan_info->channel_num, 1);
7170
7171 *pLength += 1;
7172 pScanInfoPkt += 1;
7173 _rtw_memcpy(pScanInfoPkt, &pwrctl->pscan_info->orig_ch, 1);
7174
7175
7176 *pLength += 1;
7177 pScanInfoPkt += 1;
7178 _rtw_memcpy(pScanInfoPkt, &pwrctl->pscan_info->orig_bw, 1);
7179
7180
7181 *pLength += 1;
7182 pScanInfoPkt += 1;
7183 _rtw_memcpy(pScanInfoPkt, &pwrctl->pscan_info->orig_40_offset, 1);
7184
7185 *pLength += 1;
7186 pScanInfoPkt += 1;
7187 _rtw_memcpy(pScanInfoPkt, &pwrctl->pscan_info->orig_80_offset, 1);
7188
7189 *pLength += 1;
7190 pScanInfoPkt += 1;
7191 _rtw_memcpy(pScanInfoPkt, &pwrctl->pscan_info->periodScan, 1);
7192
7193 *pLength += 1;
7194 pScanInfoPkt += 1;
7195 _rtw_memcpy(pScanInfoPkt, &pwrctl->pscan_info->period_scan_time, 1);
7196
7197 *pLength += 1;
7198 pScanInfoPkt += 1;
7199 _rtw_memcpy(pScanInfoPkt, &pwrctl->pscan_info->enableRFE, 1);
7200
7201 *pLength += 1;
7202 pScanInfoPkt += 1;
7203 _rtw_memcpy(pScanInfoPkt, &pwrctl->pscan_info->rfe_type, 8);
7204
7205 *pLength += 8;
7206 pScanInfoPkt += 8;
7207
7208 for (i = 0 ; i < MAX_SCAN_LIST_COUNT ; i++) {
7209 _rtw_memcpy(pScanInfoPkt,
7210 &pwrctl->pscan_info->ssid_channel_info[i], 4);
7211 *pLength += 4;
7212 pScanInfoPkt += 4;
7213 }
7214 }
7215 #endif /* CONFIG_PNO_SUPPORT */
7216
7217 #ifdef CONFIG_GTK_OL
rtw_hal_construct_GTKRsp(PADAPTER padapter,u8 * pframe,u32 * pLength)7218 static void rtw_hal_construct_GTKRsp(
7219 PADAPTER padapter,
7220 u8 *pframe,
7221 u32 *pLength
7222 )
7223 {
7224 struct rtw_ieee80211_hdr *pwlanhdr;
7225 u16 *fctrl;
7226 u32 pktlen;
7227 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
7228 struct wlan_network *cur_network = &pmlmepriv->cur_network;
7229 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
7230 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
7231 struct security_priv *psecuritypriv = &padapter->securitypriv;
7232 static u8 LLCHeader[8] = {0xAA, 0xAA, 0x03, 0x00, 0x00, 0x00, 0x88, 0x8E};
7233 static u8 GTKbody_a[11] = {0x01, 0x03, 0x00, 0x5F, 0x02, 0x03, 0x12, 0x00, 0x10, 0x42, 0x0B};
7234 u8 *pGTKRspPkt = pframe;
7235 u8 EncryptionHeadOverhead = 0;
7236 /* RTW_INFO("%s:%d\n", __FUNCTION__, bForcePowerSave); */
7237
7238 pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
7239
7240 fctrl = &pwlanhdr->frame_ctl;
7241 *(fctrl) = 0;
7242
7243 /* ------------------------------------------------------------------------- */
7244 /* MAC Header. */
7245 /* ------------------------------------------------------------------------- */
7246 SetFrameType(fctrl, WIFI_DATA);
7247 /* set_frame_sub_type(fctrl, 0); */
7248 SetToDs(fctrl);
7249
7250 _rtw_memcpy(pwlanhdr->addr1,
7251 get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
7252
7253 _rtw_memcpy(pwlanhdr->addr2,
7254 adapter_mac_addr(padapter), ETH_ALEN);
7255
7256 _rtw_memcpy(pwlanhdr->addr3,
7257 get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
7258
7259 SetSeqNum(pwlanhdr, 0);
7260 set_duration(pwlanhdr, 0);
7261
7262 #ifdef CONFIG_WAPI_SUPPORT
7263 *pLength = sMacHdrLng;
7264 #else
7265 *pLength = 24;
7266 #endif /* CONFIG_WAPI_SUPPORT */
7267
7268 /* ------------------------------------------------------------------------- */
7269 /* Security Header: leave space for it if necessary. */
7270 /* ------------------------------------------------------------------------- */
7271 switch (psecuritypriv->dot11PrivacyAlgrthm) {
7272 case _WEP40_:
7273 case _WEP104_:
7274 EncryptionHeadOverhead = 4;
7275 break;
7276 case _TKIP_:
7277 EncryptionHeadOverhead = 8;
7278 break;
7279 case _AES_:
7280 EncryptionHeadOverhead = 8;
7281 break;
7282 #ifdef CONFIG_WAPI_SUPPORT
7283 case _SMS4_:
7284 EncryptionHeadOverhead = 18;
7285 break;
7286 #endif /* CONFIG_WAPI_SUPPORT */
7287 default:
7288 EncryptionHeadOverhead = 0;
7289 }
7290
7291 if (EncryptionHeadOverhead > 0) {
7292 _rtw_memset(&(pframe[*pLength]), 0, EncryptionHeadOverhead);
7293 *pLength += EncryptionHeadOverhead;
7294 /* SET_80211_HDR_WEP(pGTKRspPkt, 1); */ /* Suggested by CCW. */
7295 /* GTK's privacy bit is done by FW */
7296 /* SetPrivacy(fctrl); */
7297 }
7298 /* ------------------------------------------------------------------------- */
7299 /* Frame Body. */
7300 /* ------------------------------------------------------------------------- */
7301 pGTKRspPkt = (u8 *)(pframe + *pLength);
7302 /* LLC header */
7303 _rtw_memcpy(pGTKRspPkt, LLCHeader, 8);
7304 *pLength += 8;
7305
7306 /* GTK element */
7307 pGTKRspPkt += 8;
7308
7309 /* GTK frame body after LLC, part 1 */
7310 /* TKIP key_length = 32, AES key_length = 16 */
7311 if (psecuritypriv->dot118021XGrpPrivacy == _TKIP_)
7312 GTKbody_a[8] = 0x20;
7313
7314 /* GTK frame body after LLC, part 1 */
7315 _rtw_memcpy(pGTKRspPkt, GTKbody_a, 11);
7316 *pLength += 11;
7317 pGTKRspPkt += 11;
7318 /* GTK frame body after LLC, part 2 */
7319 _rtw_memset(&(pframe[*pLength]), 0, 88);
7320 *pLength += 88;
7321 pGTKRspPkt += 88;
7322
7323 if (psecuritypriv->dot118021XGrpPrivacy == _TKIP_)
7324 *pLength += 8;
7325 }
7326 #endif /* CONFIG_GTK_OL */
7327
7328 #define PN_2_CCMPH(ch,key_id) ((ch) & 0x000000000000ffff) \
7329 | (((ch) & 0x0000ffffffff0000) << 16) \
7330 | (((key_id) << 30)) \
7331 | BIT(29)
rtw_hal_construct_remote_control_info(_adapter * adapter,u8 * pframe,u32 * pLength)7332 static void rtw_hal_construct_remote_control_info(_adapter *adapter,
7333 u8 *pframe, u32 *pLength)
7334 {
7335 struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
7336 struct sta_priv *pstapriv = &adapter->stapriv;
7337 struct security_priv *psecuritypriv = &adapter->securitypriv;
7338 struct mlme_ext_priv *pmlmeext = &adapter->mlmeextpriv;
7339 struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
7340 struct sta_info *psta;
7341 struct stainfo_rxcache *prxcache;
7342 u8 cur_dot11rxiv[8], id = 0, tid_id = 0, i = 0;
7343 size_t sz = 0, total = 0;
7344 u64 ccmp_hdr = 0, tmp_key = 0;
7345
7346 psta = rtw_get_stainfo(pstapriv, get_bssid(pmlmepriv));
7347
7348 if (psta == NULL) {
7349 rtw_warn_on(1);
7350 return;
7351 }
7352
7353 prxcache = &psta->sta_recvpriv.rxcache;
7354 sz = sizeof(cur_dot11rxiv);
7355
7356 /* 3 SEC IV * 1 page */
7357 rtw_get_sec_iv(adapter, cur_dot11rxiv,
7358 get_my_bssid(&pmlmeinfo->network));
7359
7360 _rtw_memcpy(pframe, cur_dot11rxiv, sz);
7361 *pLength += sz;
7362 pframe += sz;
7363
7364 _rtw_memset(&cur_dot11rxiv, 0, sz);
7365
7366 if (psecuritypriv->ndisauthtype == Ndis802_11AuthModeWPA2PSK) {
7367 id = psecuritypriv->dot118021XGrpKeyid;
7368 tid_id = prxcache->last_tid;
7369 REMOTE_INFO_CTRL_SET_VALD_EN(cur_dot11rxiv, 0xdd);
7370 REMOTE_INFO_CTRL_SET_PTK_EN(cur_dot11rxiv, 1);
7371 REMOTE_INFO_CTRL_SET_GTK_EN(cur_dot11rxiv, 1);
7372 REMOTE_INFO_CTRL_SET_GTK_IDX(cur_dot11rxiv, id);
7373 _rtw_memcpy(pframe, cur_dot11rxiv, sz);
7374 *pLength += sz;
7375 pframe += sz;
7376
7377 _rtw_memcpy(pframe, prxcache->iv[tid_id], sz);
7378 *pLength += sz;
7379 pframe += sz;
7380
7381 total = sizeof(psecuritypriv->iv_seq);
7382 total /= sizeof(psecuritypriv->iv_seq[0]);
7383
7384 for (i = 0 ; i < total ; i ++) {
7385 ccmp_hdr =
7386 le64_to_cpu(*(u64*)psecuritypriv->iv_seq[i]);
7387 _rtw_memset(&cur_dot11rxiv, 0, sz);
7388 if (ccmp_hdr != 0) {
7389 tmp_key = i;
7390 ccmp_hdr = PN_2_CCMPH(ccmp_hdr, tmp_key);
7391 *(u64*)cur_dot11rxiv = cpu_to_le64(ccmp_hdr);
7392 _rtw_memcpy(pframe, cur_dot11rxiv, sz);
7393 }
7394 *pLength += sz;
7395 pframe += sz;
7396 }
7397 }
7398 }
7399
7400 /*#define DBG_RSVD_PAGE_CFG*/
7401 #ifdef DBG_RSVD_PAGE_CFG
7402 #define RSVD_PAGE_CFG(ops, v1, v2, v3) \
7403 RTW_INFO("=== [RSVD][%s]-NeedPage:%d, TotalPageNum:%d TotalPacketLen:%d ===\n", \
7404 ops, v1, v2, v3)
7405 #endif
rtw_hal_set_wow_fw_rsvd_page(_adapter * adapter,u8 * pframe,u16 index,u8 tx_desc,u32 page_size,u8 * page_num,u32 * total_pkt_len,RSVDPAGE_LOC * rsvd_page_loc)7406 void rtw_hal_set_wow_fw_rsvd_page(_adapter *adapter, u8 *pframe, u16 index,
7407 u8 tx_desc, u32 page_size, u8 *page_num, u32 *total_pkt_len,
7408 RSVDPAGE_LOC *rsvd_page_loc)
7409 {
7410 struct security_priv *psecuritypriv = &adapter->securitypriv;
7411 struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
7412 struct pwrctrl_priv *pwrctl = adapter_to_pwrctl(adapter);
7413 struct mlme_ext_priv *pmlmeext;
7414 struct mlme_ext_info *pmlmeinfo;
7415 u32 ARPLength = 0, GTKLength = 0, PNOLength = 0, ScanInfoLength = 0;
7416 u32 SSIDLegnth = 0, ProbeReqLength = 0, ns_len = 0, rc_len = 0;
7417 u8 CurtPktPageNum = 0;
7418
7419 #ifdef CONFIG_GTK_OL
7420 struct sta_priv *pstapriv = &adapter->stapriv;
7421 struct sta_info *psta;
7422 struct security_priv *psecpriv = &adapter->securitypriv;
7423 u8 kek[RTW_KEK_LEN];
7424 u8 kck[RTW_KCK_LEN];
7425 #endif /* CONFIG_GTK_OL */
7426 #ifdef CONFIG_PNO_SUPPORT
7427 int pno_index;
7428 u8 ssid_num;
7429 #endif /* CONFIG_PNO_SUPPORT */
7430
7431 pmlmeext = &adapter->mlmeextpriv;
7432 pmlmeinfo = &pmlmeext->mlmext_info;
7433
7434 if (pwrctl->wowlan_pno_enable == _FALSE) {
7435 /* ARP RSP * 1 page */
7436
7437 rsvd_page_loc->LocArpRsp = *page_num;
7438
7439 RTW_INFO("LocArpRsp: %d\n", rsvd_page_loc->LocArpRsp);
7440
7441 rtw_hal_construct_ARPRsp(adapter, &pframe[index],
7442 &ARPLength, pmlmeinfo->ip_addr);
7443
7444 rtw_hal_fill_fake_txdesc(adapter,
7445 &pframe[index - tx_desc],
7446 ARPLength, _FALSE, _FALSE, _TRUE);
7447
7448 CurtPktPageNum = (u8)PageNum(tx_desc + ARPLength, page_size);
7449
7450 *page_num += CurtPktPageNum;
7451
7452 index += (CurtPktPageNum * page_size);
7453 #ifdef CONFIG_IPV6
7454 /* 2 NS offload and NDP Info*/
7455 if (pwrctl->wowlan_ns_offload_en == _TRUE) {
7456 rsvd_page_loc->LocNbrAdv = *page_num;
7457 RTW_INFO("LocNbrAdv: %d\n", rsvd_page_loc->LocNbrAdv);
7458 rtw_hal_construct_na_message(adapter,
7459 &pframe[index], &ns_len);
7460 rtw_hal_fill_fake_txdesc(adapter,
7461 &pframe[index - tx_desc],
7462 ns_len, _FALSE,
7463 _FALSE, _TRUE);
7464 CurtPktPageNum = (u8)PageNum(tx_desc + ns_len,
7465 page_size);
7466 *page_num += CurtPktPageNum;
7467 index += (CurtPktPageNum * page_size);
7468
7469 rsvd_page_loc->LocNDPInfo = *page_num;
7470 RTW_INFO("LocNDPInfo: %d\n",
7471 rsvd_page_loc->LocNDPInfo);
7472
7473 rtw_hal_construct_ndp_info(adapter,
7474 &pframe[index - tx_desc],
7475 &ns_len);
7476 CurtPktPageNum =
7477 (u8)PageNum(tx_desc + ns_len, page_size);
7478 *page_num += CurtPktPageNum;
7479 index += (CurtPktPageNum * page_size);
7480 }
7481 #endif /*CONFIG_IPV6*/
7482 /* 3 Remote Control Info. * 1 page */
7483 rsvd_page_loc->LocRemoteCtrlInfo = *page_num;
7484 RTW_INFO("LocRemoteCtrlInfo: %d\n", rsvd_page_loc->LocRemoteCtrlInfo);
7485 rtw_hal_construct_remote_control_info(adapter,
7486 &pframe[index - tx_desc],
7487 &rc_len);
7488 CurtPktPageNum = (u8)PageNum(rc_len, page_size);
7489 *page_num += CurtPktPageNum;
7490 *total_pkt_len = index + rc_len;
7491 #ifdef DBG_RSVD_PAGE_CFG
7492 RSVD_PAGE_CFG("WOW-RCI", CurtPktPageNum, *page_num, *total_pkt_len);
7493 #endif
7494 #ifdef CONFIG_GTK_OL
7495 index += (CurtPktPageNum * page_size);
7496
7497 /* if the ap staion info. exists, get the kek, kck from staion info. */
7498 psta = rtw_get_stainfo(pstapriv, get_bssid(pmlmepriv));
7499 if (psta == NULL) {
7500 _rtw_memset(kek, 0, RTW_KEK_LEN);
7501 _rtw_memset(kck, 0, RTW_KCK_LEN);
7502 RTW_INFO("%s, KEK, KCK download rsvd page all zero\n",
7503 __func__);
7504 } else {
7505 _rtw_memcpy(kek, psta->kek, RTW_KEK_LEN);
7506 _rtw_memcpy(kck, psta->kck, RTW_KCK_LEN);
7507 }
7508
7509 /* 3 KEK, KCK */
7510 rsvd_page_loc->LocGTKInfo = *page_num;
7511 RTW_INFO("LocGTKInfo: %d\n", rsvd_page_loc->LocGTKInfo);
7512
7513 if (IS_HARDWARE_TYPE_8188E(adapter) || IS_HARDWARE_TYPE_8812(adapter)) {
7514 struct security_priv *psecpriv = NULL;
7515
7516 psecpriv = &adapter->securitypriv;
7517 _rtw_memcpy(pframe + index - tx_desc,
7518 &psecpriv->dot11PrivacyAlgrthm, 1);
7519 _rtw_memcpy(pframe + index - tx_desc + 1,
7520 &psecpriv->dot118021XGrpPrivacy, 1);
7521 _rtw_memcpy(pframe + index - tx_desc + 2,
7522 kck, RTW_KCK_LEN);
7523 _rtw_memcpy(pframe + index - tx_desc + 2 + RTW_KCK_LEN,
7524 kek, RTW_KEK_LEN);
7525 CurtPktPageNum = (u8)PageNum(tx_desc + 2 + RTW_KCK_LEN + RTW_KEK_LEN, page_size);
7526 } else {
7527
7528 _rtw_memcpy(pframe + index - tx_desc, kck, RTW_KCK_LEN);
7529 _rtw_memcpy(pframe + index - tx_desc + RTW_KCK_LEN,
7530 kek, RTW_KEK_LEN);
7531 GTKLength = tx_desc + RTW_KCK_LEN + RTW_KEK_LEN;
7532
7533 if (psta != NULL &&
7534 psecuritypriv->dot118021XGrpPrivacy == _TKIP_) {
7535 _rtw_memcpy(pframe + index - tx_desc + 56,
7536 &psta->dot11tkiptxmickey, RTW_TKIP_MIC_LEN);
7537 GTKLength += RTW_TKIP_MIC_LEN;
7538 }
7539 CurtPktPageNum = (u8)PageNum(GTKLength, page_size);
7540 }
7541 #if 0
7542 {
7543 int i;
7544 printk("\ntoFW KCK: ");
7545 for (i = 0; i < 16; i++)
7546 printk(" %02x ", kck[i]);
7547 printk("\ntoFW KEK: ");
7548 for (i = 0; i < 16; i++)
7549 printk(" %02x ", kek[i]);
7550 printk("\n");
7551 }
7552
7553 RTW_INFO("%s(): HW_VAR_SET_TX_CMD: KEK KCK %p %d\n",
7554 __FUNCTION__, &pframe[index - tx_desc],
7555 (tx_desc + RTW_KCK_LEN + RTW_KEK_LEN));
7556 #endif
7557
7558 *page_num += CurtPktPageNum;
7559
7560 index += (CurtPktPageNum * page_size);
7561
7562 /* 3 GTK Response */
7563 rsvd_page_loc->LocGTKRsp = *page_num;
7564 RTW_INFO("LocGTKRsp: %d\n", rsvd_page_loc->LocGTKRsp);
7565 rtw_hal_construct_GTKRsp(adapter, &pframe[index], >KLength);
7566
7567 rtw_hal_fill_fake_txdesc(adapter, &pframe[index - tx_desc],
7568 GTKLength, _FALSE, _FALSE, _TRUE);
7569 #if 0
7570 {
7571 int gj;
7572 printk("123GTK pkt=>\n");
7573 for (gj = 0; gj < GTKLength + tx_desc; gj++) {
7574 printk(" %02x ", pframe[index - tx_desc + gj]);
7575 if ((gj + 1) % 16 == 0)
7576 printk("\n");
7577 }
7578 printk(" <=end\n");
7579 }
7580
7581 RTW_INFO("%s(): HW_VAR_SET_TX_CMD: GTK RSP %p %d\n",
7582 __FUNCTION__, &pframe[index - tx_desc],
7583 (tx_desc + GTKLength));
7584 #endif
7585
7586 CurtPktPageNum = (u8)PageNum(tx_desc + GTKLength, page_size);
7587
7588 *page_num += CurtPktPageNum;
7589
7590 index += (CurtPktPageNum * page_size);
7591
7592 /* below page is empty for GTK extension memory */
7593 /* 3(11) GTK EXT MEM */
7594 rsvd_page_loc->LocGTKEXTMEM = *page_num;
7595 RTW_INFO("LocGTKEXTMEM: %d\n", rsvd_page_loc->LocGTKEXTMEM);
7596 CurtPktPageNum = 2;
7597
7598 if (page_size >= 256)
7599 CurtPktPageNum = 1;
7600
7601 *page_num += CurtPktPageNum;
7602 /* extension memory for FW */
7603 *total_pkt_len = index + (page_size * CurtPktPageNum);
7604 #endif /* CONFIG_GTK_OL */
7605
7606 index += (CurtPktPageNum * page_size);
7607
7608 /*Reserve 1 page for AOAC report*/
7609 rsvd_page_loc->LocAOACReport = *page_num;
7610 RTW_INFO("LocAOACReport: %d\n", rsvd_page_loc->LocAOACReport);
7611 *page_num += 1;
7612 *total_pkt_len = index + (page_size * 1);
7613 } else {
7614 #ifdef CONFIG_PNO_SUPPORT
7615 if (pwrctl->wowlan_in_resume == _FALSE &&
7616 pwrctl->pno_inited == _TRUE) {
7617
7618 /* Broadcast Probe Request */
7619 rsvd_page_loc->LocProbePacket = *page_num;
7620
7621 RTW_INFO("loc_probe_req: %d\n",
7622 rsvd_page_loc->LocProbePacket);
7623
7624 rtw_hal_construct_ProbeReq(
7625 adapter,
7626 &pframe[index],
7627 &ProbeReqLength,
7628 NULL);
7629
7630 rtw_hal_fill_fake_txdesc(adapter,
7631 &pframe[index - tx_desc],
7632 ProbeReqLength, _FALSE, _FALSE, _FALSE);
7633
7634 CurtPktPageNum =
7635 (u8)PageNum(tx_desc + ProbeReqLength, page_size);
7636
7637 *page_num += CurtPktPageNum;
7638
7639 index += (CurtPktPageNum * page_size);
7640
7641 /* Hidden SSID Probe Request */
7642 ssid_num = pwrctl->pnlo_info->hidden_ssid_num;
7643
7644 for (pno_index = 0 ; pno_index < ssid_num ; pno_index++) {
7645 pwrctl->pnlo_info->loc_probe_req[pno_index] =
7646 *page_num;
7647
7648 rtw_hal_construct_ProbeReq(
7649 adapter,
7650 &pframe[index],
7651 &ProbeReqLength,
7652 &pwrctl->pno_ssid_list->node[pno_index]);
7653
7654 rtw_hal_fill_fake_txdesc(adapter,
7655 &pframe[index - tx_desc],
7656 ProbeReqLength, _FALSE, _FALSE, _FALSE);
7657
7658 CurtPktPageNum =
7659 (u8)PageNum(tx_desc + ProbeReqLength, page_size);
7660
7661 *page_num += CurtPktPageNum;
7662
7663 index += (CurtPktPageNum * page_size);
7664 }
7665
7666 /* PNO INFO Page */
7667 rsvd_page_loc->LocPNOInfo = *page_num;
7668 RTW_INFO("LocPNOInfo: %d\n", rsvd_page_loc->LocPNOInfo);
7669 rtw_hal_construct_PNO_info(adapter,
7670 &pframe[index - tx_desc],
7671 &PNOLength);
7672
7673 CurtPktPageNum = (u8)PageNum(PNOLength, page_size);
7674 *page_num += CurtPktPageNum;
7675 index += (CurtPktPageNum * page_size);
7676
7677 /* Scan Info Page */
7678 rsvd_page_loc->LocScanInfo = *page_num;
7679 RTW_INFO("LocScanInfo: %d\n", rsvd_page_loc->LocScanInfo);
7680 rtw_hal_construct_scan_info(adapter,
7681 &pframe[index - tx_desc],
7682 &ScanInfoLength);
7683
7684 CurtPktPageNum = (u8)PageNum(ScanInfoLength, page_size);
7685 *page_num += CurtPktPageNum;
7686 *total_pkt_len = index + ScanInfoLength;
7687 index += (CurtPktPageNum * page_size);
7688 }
7689 #endif /* CONFIG_PNO_SUPPORT */
7690 }
7691 }
7692
rtw_hal_gate_bb(_adapter * adapter,bool stop)7693 static void rtw_hal_gate_bb(_adapter *adapter, bool stop)
7694 {
7695 struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(adapter);
7696 u8 i = 0, val8 = 0, empty = _FAIL;
7697 u16 val16 = 0;
7698
7699 if (stop) {
7700 /* checking TX queue status */
7701 for (i = 0 ; i < 5 ; i++) {
7702 rtw_hal_get_hwreg(adapter, HW_VAR_CHK_MGQ_CPU_EMPTY, &empty);
7703 if (empty) {
7704 break;
7705 } else {
7706 RTW_WARN("%s: MGQ_CPU is busy(%d)!\n",
7707 __func__, i);
7708 rtw_mdelay_os(10);
7709 }
7710 }
7711
7712 if (val8 == 5)
7713 RTW_ERR("%s: Polling MGQ_CPU empty fail!\n", __func__);
7714
7715 /* Pause TX*/
7716 pwrpriv->wowlan_txpause_status = rtw_read8(adapter, REG_TXPAUSE);
7717 rtw_write8(adapter, REG_TXPAUSE, 0xff);
7718 val8 = rtw_read8(adapter, REG_SYS_FUNC_EN);
7719 val8 &= ~BIT(0);
7720 rtw_write8(adapter, REG_SYS_FUNC_EN, val8);
7721 RTW_INFO("%s: BB gated: 0x%02x, store TXPAUSE: %02x\n",
7722 __func__,
7723 rtw_read8(adapter, REG_SYS_FUNC_EN),
7724 pwrpriv->wowlan_txpause_status);
7725 } else {
7726 val8 = rtw_read8(adapter, REG_SYS_FUNC_EN);
7727 val8 |= BIT(0);
7728 rtw_write8(adapter, REG_SYS_FUNC_EN, val8);
7729 RTW_INFO("%s: BB release: 0x%02x, recover TXPAUSE:%02x\n",
7730 __func__, rtw_read8(adapter, REG_SYS_FUNC_EN),
7731 pwrpriv->wowlan_txpause_status);
7732 /* release TX*/
7733 rtw_write8(adapter, REG_TXPAUSE, pwrpriv->wowlan_txpause_status);
7734 }
7735 }
7736
rtw_hal_reset_mac_rx(_adapter * adapter)7737 static void rtw_hal_reset_mac_rx(_adapter *adapter)
7738 {
7739 u8 val8 = 0;
7740 /* Set REG_CR bit1, bit3, bit7 to 0*/
7741 val8 = rtw_read8(adapter, REG_CR);
7742 val8 &= 0x75;
7743 rtw_write8(adapter, REG_CR, val8);
7744 val8 = rtw_read8(adapter, REG_CR);
7745 /* Set REG_CR bit1, bit3, bit7 to 1*/
7746 val8 |= 0x8a;
7747 rtw_write8(adapter, REG_CR, val8);
7748 RTW_INFO("0x%04x: %02x\n", REG_CR, rtw_read8(adapter, REG_CR));
7749 }
7750
rtw_hal_wow_pattern_generate(_adapter * adapter,u8 idx,struct rtl_wow_pattern * pwow_pattern)7751 static u8 rtw_hal_wow_pattern_generate(_adapter *adapter, u8 idx, struct rtl_wow_pattern *pwow_pattern)
7752 {
7753 struct pwrctrl_priv *pwrctl = adapter_to_pwrctl(adapter);
7754 u8 *pattern;
7755 u8 len = 0;
7756 u8 *mask;
7757
7758 u8 mask_hw[MAX_WKFM_SIZE] = {0};
7759 u8 content[MAX_WKFM_PATTERN_SIZE] = {0};
7760 u8 broadcast_addr[6] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
7761 u8 multicast_addr1[2] = {0x33, 0x33};
7762 u8 multicast_addr2[3] = {0x01, 0x00, 0x5e};
7763 u8 mask_len = 0;
7764 u8 mac_addr[ETH_ALEN] = {0};
7765 u16 count = 0;
7766 int i, j;
7767
7768 if (pwrctl->wowlan_pattern_idx > MAX_WKFM_CAM_NUM) {
7769 RTW_INFO("%s pattern_idx is more than MAX_FMC_NUM: %d\n",
7770 __func__, MAX_WKFM_CAM_NUM);
7771 return _FAIL;
7772 }
7773
7774 pattern = pwrctl->patterns[idx].content;
7775 len = pwrctl->patterns[idx].len;
7776 mask = pwrctl->patterns[idx].mask;
7777
7778 _rtw_memcpy(mac_addr, adapter_mac_addr(adapter), ETH_ALEN);
7779 _rtw_memset(pwow_pattern, 0, sizeof(struct rtl_wow_pattern));
7780
7781 mask_len = DIV_ROUND_UP(len, 8);
7782
7783 /* 1. setup A1 table */
7784 if (memcmp(pattern, broadcast_addr, ETH_ALEN) == 0)
7785 pwow_pattern->type = PATTERN_BROADCAST;
7786 else if (memcmp(pattern, multicast_addr1, 2) == 0)
7787 pwow_pattern->type = PATTERN_MULTICAST;
7788 else if (memcmp(pattern, multicast_addr2, 3) == 0)
7789 pwow_pattern->type = PATTERN_MULTICAST;
7790 else if (memcmp(pattern, mac_addr, ETH_ALEN) == 0)
7791 pwow_pattern->type = PATTERN_UNICAST;
7792 else
7793 pwow_pattern->type = PATTERN_INVALID;
7794
7795 /* translate mask from os to mask for hw */
7796
7797 /******************************************************************************
7798 * pattern from OS uses 'ethenet frame', like this:
7799
7800 | 6 | 6 | 2 | 20 | Variable | 4 |
7801 |--------+--------+------+-----------+------------+-----|
7802 | 802.3 Mac Header | IP Header | TCP Packet | FCS |
7803 | DA | SA | Type |
7804
7805 * BUT, packet catched by our HW is in '802.11 frame', begin from LLC,
7806
7807 | 24 or 30 | 6 | 2 | 20 | Variable | 4 |
7808 |-------------------+--------+------+-----------+------------+-----|
7809 | 802.11 MAC Header | LLC | IP Header | TCP Packet | FCS |
7810 | Others | Tpye |
7811
7812 * Therefore, we need translate mask_from_OS to mask_to_hw.
7813 * We should left-shift mask by 6 bits, then set the new bit[0~5] = 0,
7814 * because new mask[0~5] means 'SA', but our HW packet begins from LLC,
7815 * bit[0~5] corresponds to first 6 Bytes in LLC, they just don't match.
7816 ******************************************************************************/
7817 /* Shift 6 bits */
7818 for (i = 0; i < mask_len - 1; i++) {
7819 mask_hw[i] = mask[i] >> 6;
7820 mask_hw[i] |= (mask[i + 1] & 0x3F) << 2;
7821 }
7822
7823 mask_hw[i] = (mask[i] >> 6) & 0x3F;
7824 /* Set bit 0-5 to zero */
7825 mask_hw[0] &= 0xC0;
7826
7827 for (i = 0; i < (MAX_WKFM_SIZE / 4); i++) {
7828 pwow_pattern->mask[i] = mask_hw[i * 4];
7829 pwow_pattern->mask[i] |= (mask_hw[i * 4 + 1] << 8);
7830 pwow_pattern->mask[i] |= (mask_hw[i * 4 + 2] << 16);
7831 pwow_pattern->mask[i] |= (mask_hw[i * 4 + 3] << 24);
7832 }
7833
7834 /* To get the wake up pattern from the mask.
7835 * We do not count first 12 bits which means
7836 * DA[6] and SA[6] in the pattern to match HW design. */
7837 count = 0;
7838 for (i = 12; i < len; i++) {
7839 if ((mask[i / 8] >> (i % 8)) & 0x01) {
7840 content[count] = pattern[i];
7841 count++;
7842 }
7843 }
7844
7845 pwow_pattern->crc = rtw_calc_crc(content, count);
7846
7847 if (pwow_pattern->crc != 0) {
7848 if (pwow_pattern->type == PATTERN_INVALID)
7849 pwow_pattern->type = PATTERN_VALID;
7850 }
7851
7852 return _SUCCESS;
7853 }
7854
7855 #ifndef CONFIG_WOW_PATTERN_HW_CAM
rtw_hal_set_wow_rxff_boundary(_adapter * adapter,bool wow_mode)7856 static void rtw_hal_set_wow_rxff_boundary(_adapter *adapter, bool wow_mode)
7857 {
7858 u8 val8 = 0;
7859 u16 rxff_bndy = 0;
7860 u32 rx_dma_buff_sz = 0;
7861
7862 val8 = rtw_read8(adapter, REG_FIFOPAGE + 3);
7863 if (val8 != 0)
7864 RTW_INFO("%s:[%04x]some PKTs in TXPKTBUF\n",
7865 __func__, (REG_FIFOPAGE + 3));
7866
7867 rtw_hal_reset_mac_rx(adapter);
7868
7869 if (wow_mode) {
7870 rtw_hal_get_def_var(adapter, HAL_DEF_RX_DMA_SZ_WOW,
7871 (u8 *)&rx_dma_buff_sz);
7872 rxff_bndy = rx_dma_buff_sz - 1;
7873
7874 rtw_write16(adapter, (REG_TRXFF_BNDY + 2), rxff_bndy);
7875 RTW_INFO("%s: wow mode, 0x%04x: 0x%04x\n", __func__,
7876 REG_TRXFF_BNDY + 2,
7877 rtw_read16(adapter, (REG_TRXFF_BNDY + 2)));
7878 } else {
7879 rtw_hal_get_def_var(adapter, HAL_DEF_RX_DMA_SZ,
7880 (u8 *)&rx_dma_buff_sz);
7881 rxff_bndy = rx_dma_buff_sz - 1;
7882 rtw_write16(adapter, (REG_TRXFF_BNDY + 2), rxff_bndy);
7883 RTW_INFO("%s: normal mode, 0x%04x: 0x%04x\n", __func__,
7884 REG_TRXFF_BNDY + 2,
7885 rtw_read16(adapter, (REG_TRXFF_BNDY + 2)));
7886 }
7887 }
7888
rtw_read_from_frame_mask(_adapter * adapter,u8 idx)7889 bool rtw_read_from_frame_mask(_adapter *adapter, u8 idx)
7890 {
7891 u32 data_l = 0, data_h = 0, rx_dma_buff_sz = 0, page_sz = 0;
7892 u16 offset, rx_buf_ptr = 0;
7893 u16 cam_start_offset = 0;
7894 u16 ctrl_l = 0, ctrl_h = 0;
7895 u8 count = 0, tmp = 0;
7896 int i = 0;
7897 bool res = _TRUE;
7898
7899 if (idx > MAX_WKFM_CAM_NUM) {
7900 RTW_INFO("[Error]: %s, pattern index is out of range\n",
7901 __func__);
7902 return _FALSE;
7903 }
7904
7905 rtw_hal_get_def_var(adapter, HAL_DEF_RX_DMA_SZ_WOW,
7906 (u8 *)&rx_dma_buff_sz);
7907
7908 if (rx_dma_buff_sz == 0) {
7909 RTW_INFO("[Error]: %s, rx_dma_buff_sz is 0!!\n", __func__);
7910 return _FALSE;
7911 }
7912
7913 rtw_hal_get_def_var(adapter, HAL_DEF_RX_PAGE_SIZE, (u8 *)&page_sz);
7914
7915 if (page_sz == 0) {
7916 RTW_INFO("[Error]: %s, page_sz is 0!!\n", __func__);
7917 return _FALSE;
7918 }
7919
7920 offset = (u16)PageNum(rx_dma_buff_sz, page_sz);
7921 cam_start_offset = offset * page_sz;
7922
7923 ctrl_l = 0x0;
7924 ctrl_h = 0x0;
7925
7926 /* Enable RX packet buffer access */
7927 rtw_write8(adapter, REG_PKT_BUFF_ACCESS_CTRL, RXPKT_BUF_SELECT);
7928
7929 /* Read the WKFM CAM */
7930 for (i = 0; i < (WKFMCAM_ADDR_NUM / 2); i++) {
7931 /*
7932 * Set Rx packet buffer offset.
7933 * RxBufer pointer increases 1, we can access 8 bytes in Rx packet buffer.
7934 * CAM start offset (unit: 1 byte) = Index*WKFMCAM_SIZE
7935 * RxBufer pointer addr = (CAM start offset + per entry offset of a WKFMCAM)/8
7936 * * Index: The index of the wake up frame mask
7937 * * WKFMCAM_SIZE: the total size of one WKFM CAM
7938 * * per entry offset of a WKFM CAM: Addr i * 4 bytes
7939 */
7940 rx_buf_ptr =
7941 (cam_start_offset + idx * WKFMCAM_SIZE + i * 8) >> 3;
7942 rtw_write16(adapter, REG_PKTBUF_DBG_CTRL, rx_buf_ptr);
7943
7944 rtw_write16(adapter, REG_RXPKTBUF_CTRL, ctrl_l);
7945 data_l = rtw_read32(adapter, REG_PKTBUF_DBG_DATA_L);
7946 data_h = rtw_read32(adapter, REG_PKTBUF_DBG_DATA_H);
7947
7948 RTW_INFO("[%d]: %08x %08x\n", i, data_h, data_l);
7949
7950 count = 0;
7951
7952 do {
7953 tmp = rtw_read8(adapter, REG_RXPKTBUF_CTRL);
7954 rtw_udelay_os(2);
7955 count++;
7956 } while (!tmp && count < 100);
7957
7958 if (count >= 100) {
7959 RTW_INFO("%s count:%d\n", __func__, count);
7960 res = _FALSE;
7961 }
7962 }
7963
7964 /* Disable RX packet buffer access */
7965 rtw_write8(adapter, REG_PKT_BUFF_ACCESS_CTRL,
7966 DISABLE_TRXPKT_BUF_ACCESS);
7967 return res;
7968 }
7969
rtw_write_to_frame_mask(_adapter * adapter,u8 idx,struct rtl_wow_pattern * context)7970 bool rtw_write_to_frame_mask(_adapter *adapter, u8 idx,
7971 struct rtl_wow_pattern *context)
7972 {
7973 u32 data = 0, rx_dma_buff_sz = 0, page_sz = 0;
7974 u16 offset, rx_buf_ptr = 0;
7975 u16 cam_start_offset = 0;
7976 u16 ctrl_l = 0, ctrl_h = 0;
7977 u8 count = 0, tmp = 0;
7978 int res = 0, i = 0;
7979
7980 if (idx > MAX_WKFM_CAM_NUM) {
7981 RTW_INFO("[Error]: %s, pattern index is out of range\n",
7982 __func__);
7983 return _FALSE;
7984 }
7985
7986 rtw_hal_get_def_var(adapter, HAL_DEF_RX_DMA_SZ_WOW,
7987 (u8 *)&rx_dma_buff_sz);
7988
7989 if (rx_dma_buff_sz == 0) {
7990 RTW_INFO("[Error]: %s, rx_dma_buff_sz is 0!!\n", __func__);
7991 return _FALSE;
7992 }
7993
7994 rtw_hal_get_def_var(adapter, HAL_DEF_RX_PAGE_SIZE, (u8 *)&page_sz);
7995
7996 if (page_sz == 0) {
7997 RTW_INFO("[Error]: %s, page_sz is 0!!\n", __func__);
7998 return _FALSE;
7999 }
8000
8001 offset = (u16)PageNum(rx_dma_buff_sz, page_sz);
8002
8003 cam_start_offset = offset * page_sz;
8004
8005 if (IS_HARDWARE_TYPE_8188E(adapter)) {
8006 ctrl_l = 0x0001;
8007 ctrl_h = 0x0001;
8008 } else {
8009 ctrl_l = 0x0f01;
8010 ctrl_h = 0xf001;
8011 }
8012
8013 /* Enable RX packet buffer access */
8014 rtw_write8(adapter, REG_PKT_BUFF_ACCESS_CTRL, RXPKT_BUF_SELECT);
8015
8016 /* Write the WKFM CAM */
8017 for (i = 0; i < WKFMCAM_ADDR_NUM; i++) {
8018 /*
8019 * Set Rx packet buffer offset.
8020 * RxBufer pointer increases 1, we can access 8 bytes in Rx packet buffer.
8021 * CAM start offset (unit: 1 byte) = Index*WKFMCAM_SIZE
8022 * RxBufer pointer addr = (CAM start offset + per entry offset of a WKFMCAM)/8
8023 * * Index: The index of the wake up frame mask
8024 * * WKFMCAM_SIZE: the total size of one WKFM CAM
8025 * * per entry offset of a WKFM CAM: Addr i * 4 bytes
8026 */
8027 rx_buf_ptr =
8028 (cam_start_offset + idx * WKFMCAM_SIZE + i * 4) >> 3;
8029 rtw_write16(adapter, REG_PKTBUF_DBG_CTRL, rx_buf_ptr);
8030
8031 if (i == 0) {
8032 if (context->type == PATTERN_VALID)
8033 data = BIT(31);
8034 else if (context->type == PATTERN_BROADCAST)
8035 data = BIT(31) | BIT(26);
8036 else if (context->type == PATTERN_MULTICAST)
8037 data = BIT(31) | BIT(25);
8038 else if (context->type == PATTERN_UNICAST)
8039 data = BIT(31) | BIT(24);
8040
8041 if (context->crc != 0)
8042 data |= context->crc;
8043
8044 rtw_write32(adapter, REG_PKTBUF_DBG_DATA_L, data);
8045 rtw_write16(adapter, REG_RXPKTBUF_CTRL, ctrl_l);
8046 } else if (i == 1) {
8047 data = 0;
8048 rtw_write32(adapter, REG_PKTBUF_DBG_DATA_H, data);
8049 rtw_write16(adapter, REG_RXPKTBUF_CTRL, ctrl_h);
8050 } else if (i == 2 || i == 4) {
8051 data = context->mask[i - 2];
8052 rtw_write32(adapter, REG_PKTBUF_DBG_DATA_L, data);
8053 /* write to RX packet buffer*/
8054 rtw_write16(adapter, REG_RXPKTBUF_CTRL, ctrl_l);
8055 } else if (i == 3 || i == 5) {
8056 data = context->mask[i - 2];
8057 rtw_write32(adapter, REG_PKTBUF_DBG_DATA_H, data);
8058 /* write to RX packet buffer*/
8059 rtw_write16(adapter, REG_RXPKTBUF_CTRL, ctrl_h);
8060 }
8061
8062 count = 0;
8063 do {
8064 tmp = rtw_read8(adapter, REG_RXPKTBUF_CTRL);
8065 rtw_udelay_os(2);
8066 count++;
8067 } while (tmp && count < 100);
8068
8069 if (count >= 100)
8070 res = _FALSE;
8071 else
8072 res = _TRUE;
8073 }
8074
8075 /* Disable RX packet buffer access */
8076 rtw_write8(adapter, REG_PKT_BUFF_ACCESS_CTRL,
8077 DISABLE_TRXPKT_BUF_ACCESS);
8078
8079 return res;
8080 }
rtw_clean_pattern(_adapter * adapter)8081 void rtw_clean_pattern(_adapter *adapter)
8082 {
8083 struct pwrctrl_priv *pwrctl = adapter_to_pwrctl(adapter);
8084 struct rtl_wow_pattern zero_pattern;
8085 int i = 0;
8086
8087 _rtw_memset(&zero_pattern, 0, sizeof(struct rtl_wow_pattern));
8088
8089 zero_pattern.type = PATTERN_INVALID;
8090
8091 for (i = 0; i < MAX_WKFM_CAM_NUM; i++)
8092 rtw_write_to_frame_mask(adapter, i, &zero_pattern);
8093
8094 rtw_write8(adapter, REG_WKFMCAM_NUM, 0);
8095 }
rtw_hal_set_pattern(_adapter * adapter,u8 * pattern,u8 len,u8 * mask,u8 idx)8096 static int rtw_hal_set_pattern(_adapter *adapter, u8 *pattern,
8097 u8 len, u8 *mask, u8 idx)
8098 {
8099 struct pwrctrl_priv *pwrctl = adapter_to_pwrctl(adapter);
8100 struct mlme_ext_priv *pmlmeext = NULL;
8101 struct mlme_ext_info *pmlmeinfo = NULL;
8102 struct rtl_wow_pattern wow_pattern;
8103 u8 mask_hw[MAX_WKFM_SIZE] = {0};
8104 u8 content[MAX_WKFM_PATTERN_SIZE] = {0};
8105 u8 broadcast_addr[6] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
8106 u8 multicast_addr1[2] = {0x33, 0x33};
8107 u8 multicast_addr2[3] = {0x01, 0x00, 0x5e};
8108 u8 res = _FALSE, index = 0, mask_len = 0;
8109 u8 mac_addr[ETH_ALEN] = {0};
8110 u16 count = 0;
8111 int i, j;
8112
8113 if (pwrctl->wowlan_pattern_idx > MAX_WKFM_CAM_NUM) {
8114 RTW_INFO("%s pattern_idx is more than MAX_FMC_NUM: %d\n",
8115 __func__, MAX_WKFM_CAM_NUM);
8116 return _FALSE;
8117 }
8118
8119 pmlmeext = &adapter->mlmeextpriv;
8120 pmlmeinfo = &pmlmeext->mlmext_info;
8121 _rtw_memcpy(mac_addr, adapter_mac_addr(adapter), ETH_ALEN);
8122 _rtw_memset(&wow_pattern, 0, sizeof(struct rtl_wow_pattern));
8123
8124 mask_len = DIV_ROUND_UP(len, 8);
8125
8126 /* 1. setup A1 table */
8127 if (memcmp(pattern, broadcast_addr, ETH_ALEN) == 0)
8128 wow_pattern.type = PATTERN_BROADCAST;
8129 else if (memcmp(pattern, multicast_addr1, 2) == 0)
8130 wow_pattern.type = PATTERN_MULTICAST;
8131 else if (memcmp(pattern, multicast_addr2, 3) == 0)
8132 wow_pattern.type = PATTERN_MULTICAST;
8133 else if (memcmp(pattern, mac_addr, ETH_ALEN) == 0)
8134 wow_pattern.type = PATTERN_UNICAST;
8135 else
8136 wow_pattern.type = PATTERN_INVALID;
8137
8138 /* translate mask from os to mask for hw */
8139
8140 /******************************************************************************
8141 * pattern from OS uses 'ethenet frame', like this:
8142
8143 | 6 | 6 | 2 | 20 | Variable | 4 |
8144 |--------+--------+------+-----------+------------+-----|
8145 | 802.3 Mac Header | IP Header | TCP Packet | FCS |
8146 | DA | SA | Type |
8147
8148 * BUT, packet catched by our HW is in '802.11 frame', begin from LLC,
8149
8150 | 24 or 30 | 6 | 2 | 20 | Variable | 4 |
8151 |-------------------+--------+------+-----------+------------+-----|
8152 | 802.11 MAC Header | LLC | IP Header | TCP Packet | FCS |
8153 | Others | Tpye |
8154
8155 * Therefore, we need translate mask_from_OS to mask_to_hw.
8156 * We should left-shift mask by 6 bits, then set the new bit[0~5] = 0,
8157 * because new mask[0~5] means 'SA', but our HW packet begins from LLC,
8158 * bit[0~5] corresponds to first 6 Bytes in LLC, they just don't match.
8159 ******************************************************************************/
8160 /* Shift 6 bits */
8161 for (i = 0; i < mask_len - 1; i++) {
8162 mask_hw[i] = mask[i] >> 6;
8163 mask_hw[i] |= (mask[i + 1] & 0x3F) << 2;
8164 }
8165
8166 mask_hw[i] = (mask[i] >> 6) & 0x3F;
8167 /* Set bit 0-5 to zero */
8168 mask_hw[0] &= 0xC0;
8169
8170 for (i = 0; i < (MAX_WKFM_SIZE / 4); i++) {
8171 wow_pattern.mask[i] = mask_hw[i * 4];
8172 wow_pattern.mask[i] |= (mask_hw[i * 4 + 1] << 8);
8173 wow_pattern.mask[i] |= (mask_hw[i * 4 + 2] << 16);
8174 wow_pattern.mask[i] |= (mask_hw[i * 4 + 3] << 24);
8175 }
8176
8177 /* To get the wake up pattern from the mask.
8178 * We do not count first 12 bits which means
8179 * DA[6] and SA[6] in the pattern to match HW design. */
8180 count = 0;
8181 for (i = 12; i < len; i++) {
8182 if ((mask[i / 8] >> (i % 8)) & 0x01) {
8183 content[count] = pattern[i];
8184 count++;
8185 }
8186 }
8187
8188 wow_pattern.crc = rtw_calc_crc(content, count);
8189
8190 if (wow_pattern.crc != 0) {
8191 if (wow_pattern.type == PATTERN_INVALID)
8192 wow_pattern.type = PATTERN_VALID;
8193 }
8194
8195 index = idx;
8196
8197 if (!pwrctl->bInSuspend)
8198 index += 2;
8199
8200 /* write pattern */
8201 res = rtw_write_to_frame_mask(adapter, index, &wow_pattern);
8202
8203 if (res == _FALSE)
8204 RTW_INFO("%s: ERROR!! idx: %d write_to_frame_mask_cam fail\n",
8205 __func__, idx);
8206
8207 return res;
8208 }
rtw_fill_pattern(_adapter * adapter)8209 void rtw_fill_pattern(_adapter *adapter)
8210 {
8211 int i = 0, total = 0, index;
8212 struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(adapter);
8213 struct rtl_wow_pattern wow_pattern;
8214
8215 total = pwrpriv->wowlan_pattern_idx;
8216
8217 if (total > MAX_WKFM_CAM_NUM)
8218 total = MAX_WKFM_CAM_NUM;
8219
8220 for (i = 0 ; i < total ; i++) {
8221 if (_SUCCESS == rtw_hal_wow_pattern_generate(adapter, i, &wow_pattern)) {
8222
8223 index = i;
8224 if (!pwrpriv->bInSuspend)
8225 index += 2;
8226
8227 if (rtw_write_to_frame_mask(adapter, index, &wow_pattern) == _FALSE)
8228 RTW_INFO("%s: ERROR!! idx: %d write_to_frame_mask_cam fail\n", __func__, i);
8229 }
8230
8231 }
8232 rtw_write8(adapter, REG_WKFMCAM_NUM, total);
8233
8234 }
8235
8236 #else /*CONFIG_WOW_PATTERN_HW_CAM*/
8237
8238 #define WOW_CAM_ACCESS_TIMEOUT_MS 200
8239 #define WOW_VALID_BIT BIT31
8240 #define WOW_BC_BIT BIT26
8241 #define WOW_MC_BIT BIT25
8242 #define WOW_UC_BIT BIT24
8243
_rtw_wow_pattern_read_cam(_adapter * adapter,u8 addr)8244 static u32 _rtw_wow_pattern_read_cam(_adapter *adapter, u8 addr)
8245 {
8246 struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(adapter);
8247 _mutex *mutex = &pwrpriv->wowlan_pattern_cam_mutex;
8248
8249 u32 rdata = 0;
8250 u32 cnt = 0;
8251 systime start = 0;
8252 u8 timeout = 0;
8253 u8 rst = _FALSE;
8254
8255 _enter_critical_mutex(mutex, NULL);
8256
8257 rtw_write32(adapter, REG_WKFMCAM_CMD, BIT_WKFCAM_POLLING_V1 | BIT_WKFCAM_ADDR_V2(addr));
8258
8259 start = rtw_get_current_time();
8260 while (1) {
8261 if (rtw_is_surprise_removed(adapter))
8262 break;
8263
8264 cnt++;
8265 if (0 == (rtw_read32(adapter, REG_WKFMCAM_CMD) & BIT_WKFCAM_POLLING_V1)) {
8266 rst = _SUCCESS;
8267 break;
8268 }
8269 if (rtw_get_passing_time_ms(start) > WOW_CAM_ACCESS_TIMEOUT_MS) {
8270 timeout = 1;
8271 break;
8272 }
8273 }
8274
8275 rdata = rtw_read32(adapter, REG_WKFMCAM_RWD);
8276
8277 _exit_critical_mutex(mutex, NULL);
8278
8279 /*RTW_INFO("%s ==> addr:0x%02x , rdata:0x%08x\n", __func__, addr, rdata);*/
8280
8281 if (timeout)
8282 RTW_ERR(FUNC_ADPT_FMT" failed due to polling timeout\n", FUNC_ADPT_ARG(adapter));
8283
8284 return rdata;
8285 }
rtw_wow_pattern_read_cam_ent(_adapter * adapter,u8 id,struct rtl_wow_pattern * context)8286 void rtw_wow_pattern_read_cam_ent(_adapter *adapter, u8 id, struct rtl_wow_pattern *context)
8287 {
8288 int i;
8289 u32 rdata;
8290
8291 _rtw_memset(context, 0, sizeof(struct rtl_wow_pattern));
8292
8293 for (i = 4; i >= 0; i--) {
8294 rdata = _rtw_wow_pattern_read_cam(adapter, (id << 3) | i);
8295
8296 switch (i) {
8297 case 4:
8298 if (rdata & WOW_BC_BIT)
8299 context->type = PATTERN_BROADCAST;
8300 else if (rdata & WOW_MC_BIT)
8301 context->type = PATTERN_MULTICAST;
8302 else if (rdata & WOW_UC_BIT)
8303 context->type = PATTERN_UNICAST;
8304 else
8305 context->type = PATTERN_INVALID;
8306
8307 context->crc = rdata & 0xFFFF;
8308 break;
8309 default:
8310 _rtw_memcpy(&context->mask[i], (u8 *)(&rdata), 4);
8311 break;
8312 }
8313 }
8314 }
8315
_rtw_wow_pattern_write_cam(_adapter * adapter,u8 addr,u32 wdata)8316 static void _rtw_wow_pattern_write_cam(_adapter *adapter, u8 addr, u32 wdata)
8317 {
8318 struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(adapter);
8319 _mutex *mutex = &pwrpriv->wowlan_pattern_cam_mutex;
8320 u32 cnt = 0;
8321 systime start = 0, end = 0;
8322 u8 timeout = 0;
8323
8324 /*RTW_INFO("%s ==> addr:0x%02x , wdata:0x%08x\n", __func__, addr, wdata);*/
8325 _enter_critical_mutex(mutex, NULL);
8326
8327 rtw_write32(adapter, REG_WKFMCAM_RWD, wdata);
8328 rtw_write32(adapter, REG_WKFMCAM_CMD, BIT_WKFCAM_POLLING_V1 | BIT_WKFCAM_WE | BIT_WKFCAM_ADDR_V2(addr));
8329
8330 start = rtw_get_current_time();
8331 while (1) {
8332 if (rtw_is_surprise_removed(adapter))
8333 break;
8334
8335 cnt++;
8336 if (0 == (rtw_read32(adapter, REG_WKFMCAM_CMD) & BIT_WKFCAM_POLLING_V1))
8337 break;
8338
8339 if (rtw_get_passing_time_ms(start) > WOW_CAM_ACCESS_TIMEOUT_MS) {
8340 timeout = 1;
8341 break;
8342 }
8343 }
8344 end = rtw_get_current_time();
8345
8346 _exit_critical_mutex(mutex, NULL);
8347
8348 if (timeout) {
8349 RTW_ERR(FUNC_ADPT_FMT" addr:0x%02x, wdata:0x%08x, to:%u, polling:%u, %d ms\n"
8350 , FUNC_ADPT_ARG(adapter), addr, wdata, timeout, cnt, rtw_get_time_interval_ms(start, end));
8351 }
8352 }
8353
rtw_wow_pattern_write_cam_ent(_adapter * adapter,u8 id,struct rtl_wow_pattern * context)8354 void rtw_wow_pattern_write_cam_ent(_adapter *adapter, u8 id, struct rtl_wow_pattern *context)
8355 {
8356 int j;
8357 u8 addr;
8358 u32 wdata = 0;
8359
8360 for (j = 4; j >= 0; j--) {
8361 switch (j) {
8362 case 4:
8363 wdata = context->crc;
8364
8365 if (PATTERN_BROADCAST == context->type)
8366 wdata |= WOW_BC_BIT;
8367 if (PATTERN_MULTICAST == context->type)
8368 wdata |= WOW_MC_BIT;
8369 if (PATTERN_UNICAST == context->type)
8370 wdata |= WOW_UC_BIT;
8371 if (PATTERN_INVALID != context->type)
8372 wdata |= WOW_VALID_BIT;
8373 break;
8374 default:
8375 wdata = context->mask[j];
8376 break;
8377 }
8378
8379 addr = (id << 3) + j;
8380
8381 _rtw_wow_pattern_write_cam(adapter, addr, wdata);
8382 }
8383 }
8384
_rtw_wow_pattern_clean_cam(_adapter * adapter)8385 static u8 _rtw_wow_pattern_clean_cam(_adapter *adapter)
8386 {
8387 struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(adapter);
8388 _mutex *mutex = &pwrpriv->wowlan_pattern_cam_mutex;
8389 u32 cnt = 0;
8390 systime start = 0;
8391 u8 timeout = 0;
8392 u8 rst = _FAIL;
8393
8394 _enter_critical_mutex(mutex, NULL);
8395 rtw_write32(adapter, REG_WKFMCAM_CMD, BIT_WKFCAM_POLLING_V1 | BIT_WKFCAM_CLR_V1);
8396
8397 start = rtw_get_current_time();
8398 while (1) {
8399 if (rtw_is_surprise_removed(adapter))
8400 break;
8401
8402 cnt++;
8403 if (0 == (rtw_read32(adapter, REG_WKFMCAM_CMD) & BIT_WKFCAM_POLLING_V1)) {
8404 rst = _SUCCESS;
8405 break;
8406 }
8407 if (rtw_get_passing_time_ms(start) > WOW_CAM_ACCESS_TIMEOUT_MS) {
8408 timeout = 1;
8409 break;
8410 }
8411 }
8412 _exit_critical_mutex(mutex, NULL);
8413
8414 if (timeout)
8415 RTW_ERR(FUNC_ADPT_FMT" falied ,polling timeout\n", FUNC_ADPT_ARG(adapter));
8416
8417 return rst;
8418 }
8419
rtw_clean_pattern(_adapter * adapter)8420 void rtw_clean_pattern(_adapter *adapter)
8421 {
8422 if (_FAIL == _rtw_wow_pattern_clean_cam(adapter))
8423 RTW_ERR("rtw_clean_pattern failed\n");
8424 }
8425
rtw_dump_wow_pattern(void * sel,struct rtl_wow_pattern * pwow_pattern,u8 idx)8426 void rtw_dump_wow_pattern(void *sel, struct rtl_wow_pattern *pwow_pattern, u8 idx)
8427 {
8428 int j;
8429
8430 RTW_PRINT_SEL(sel, "=======WOW CAM-ID[%d]=======\n", idx);
8431 RTW_PRINT_SEL(sel, "[WOW CAM] type:%d\n", pwow_pattern->type);
8432 RTW_PRINT_SEL(sel, "[WOW CAM] crc:0x%04x\n", pwow_pattern->crc);
8433 for (j = 0; j < 4; j++)
8434 RTW_PRINT_SEL(sel, "[WOW CAM] Mask:0x%08x\n", pwow_pattern->mask[j]);
8435 }
8436
rtw_fill_pattern(_adapter * adapter)8437 void rtw_fill_pattern(_adapter *adapter)
8438 {
8439 int i = 0, total = 0;
8440 struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(adapter);
8441 struct rtl_wow_pattern wow_pattern;
8442
8443 total = pwrpriv->wowlan_pattern_idx;
8444
8445 if (total > MAX_WKFM_CAM_NUM)
8446 total = MAX_WKFM_CAM_NUM;
8447
8448 for (i = 0 ; i < total ; i++) {
8449 if (_SUCCESS == rtw_hal_wow_pattern_generate(adapter, i, &wow_pattern)) {
8450 rtw_dump_wow_pattern(RTW_DBGDUMP, &wow_pattern, i);
8451 rtw_wow_pattern_write_cam_ent(adapter, i, &wow_pattern);
8452 }
8453 }
8454 }
8455
8456 #endif
rtw_wow_pattern_cam_dump(_adapter * adapter)8457 void rtw_wow_pattern_cam_dump(_adapter *adapter)
8458 {
8459
8460 #ifndef CONFIG_WOW_PATTERN_HW_CAM
8461 int i;
8462
8463 for (i = 0 ; i < MAX_WKFM_CAM_NUM; i++) {
8464 RTW_INFO("=======[%d]=======\n", i);
8465 rtw_read_from_frame_mask(adapter, i);
8466 }
8467 #else
8468 struct rtl_wow_pattern context;
8469 int i;
8470
8471 for (i = 0 ; i < MAX_WKFM_CAM_NUM; i++) {
8472 rtw_wow_pattern_read_cam_ent(adapter, i, &context);
8473 rtw_dump_wow_pattern(RTW_DBGDUMP, &context, i);
8474 }
8475
8476 #endif
8477 }
8478
8479
rtw_hal_dl_pattern(_adapter * adapter,u8 mode)8480 static void rtw_hal_dl_pattern(_adapter *adapter, u8 mode)
8481 {
8482 struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(adapter);
8483
8484 switch (mode) {
8485 case 0:
8486 rtw_clean_pattern(adapter);
8487 RTW_INFO("%s: total patterns: %d\n", __func__, pwrpriv->wowlan_pattern_idx);
8488 break;
8489 case 1:
8490 rtw_set_default_pattern(adapter);
8491 rtw_fill_pattern(adapter);
8492 RTW_INFO("%s: pattern total: %d downloaded\n", __func__, pwrpriv->wowlan_pattern_idx);
8493 break;
8494 case 2:
8495 rtw_clean_pattern(adapter);
8496 rtw_wow_pattern_sw_reset(adapter);
8497 RTW_INFO("%s: clean patterns\n", __func__);
8498 break;
8499 default:
8500 RTW_INFO("%s: unknown mode\n", __func__);
8501 break;
8502 }
8503 }
8504
rtw_hal_wow_enable(_adapter * adapter)8505 static void rtw_hal_wow_enable(_adapter *adapter)
8506 {
8507 struct pwrctrl_priv *pwrctl = adapter_to_pwrctl(adapter);
8508 struct security_priv *psecuritypriv = &adapter->securitypriv;
8509 struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
8510 struct hal_ops *pHalFunc = &adapter->hal_func;
8511 struct sta_info *psta = NULL;
8512 PHAL_DATA_TYPE pHalData = GET_HAL_DATA(adapter);
8513 int res;
8514 u16 media_status_rpt;
8515
8516
8517 RTW_PRINT("%s, WOWLAN_ENABLE\n", __func__);
8518 rtw_hal_gate_bb(adapter, _TRUE);
8519 #ifdef CONFIG_GTK_OL
8520 if (psecuritypriv->binstallKCK_KEK == _TRUE)
8521 rtw_hal_fw_sync_cam_id(adapter);
8522 #endif
8523 if (IS_HARDWARE_TYPE_8723B(adapter))
8524 rtw_hal_backup_rate(adapter);
8525
8526 rtw_hal_fw_dl(adapter, _TRUE);
8527 media_status_rpt = RT_MEDIA_CONNECT;
8528 rtw_hal_set_hwreg(adapter, HW_VAR_H2C_FW_JOINBSSRPT,
8529 (u8 *)&media_status_rpt);
8530
8531 /* RX DMA stop */
8532 #if defined(CONFIG_RTL8188E)
8533 if (IS_HARDWARE_TYPE_8188E(adapter))
8534 rtw_hal_disable_tx_report(adapter);
8535 #endif
8536
8537 res = rtw_hal_pause_rx_dma(adapter);
8538 if (res == _FAIL)
8539 RTW_PRINT("[WARNING] pause RX DMA fail\n");
8540
8541 #ifndef CONFIG_WOW_PATTERN_HW_CAM
8542 /* Reconfig RX_FF Boundary */
8543 rtw_hal_set_wow_rxff_boundary(adapter, _TRUE);
8544 #endif
8545
8546 /* redownload wow pattern */
8547 rtw_hal_dl_pattern(adapter, 1);
8548
8549 if (!pwrctl->wowlan_pno_enable) {
8550 psta = rtw_get_stainfo(&adapter->stapriv, get_bssid(pmlmepriv));
8551
8552 if (psta != NULL) {
8553 #ifdef CONFIG_FW_MULTI_PORT_SUPPORT
8554 rtw_hal_set_default_port_id_cmd(adapter, psta->cmn.mac_id);
8555 #endif
8556
8557 rtw_sta_media_status_rpt(adapter, psta, 1);
8558 }
8559 }
8560
8561 #if defined(CONFIG_SDIO_HCI) || defined(CONFIG_GSPI_HCI)
8562 /* Enable CPWM2 only. */
8563 res = rtw_hal_enable_cpwm2(adapter);
8564 if (res == _FAIL)
8565 RTW_PRINT("[WARNING] enable cpwm2 fail\n");
8566 #endif
8567 #ifdef CONFIG_GPIO_WAKEUP
8568 rtw_hal_switch_gpio_wl_ctrl(adapter, WAKEUP_GPIO_IDX, _TRUE);
8569 #endif
8570 /* Set WOWLAN H2C command. */
8571 RTW_PRINT("Set WOWLan cmd\n");
8572 rtw_hal_set_fw_wow_related_cmd(adapter, 1);
8573
8574 res = rtw_hal_check_wow_ctrl(adapter, _TRUE);
8575
8576 if (res == _FALSE)
8577 RTW_INFO("[Error]%s: set wowlan CMD fail!!\n", __func__);
8578
8579 pwrctl->wowlan_wake_reason =
8580 rtw_read8(adapter, REG_WOWLAN_WAKE_REASON);
8581
8582 RTW_PRINT("wowlan_wake_reason: 0x%02x\n",
8583 pwrctl->wowlan_wake_reason);
8584 #ifdef CONFIG_GTK_OL_DBG
8585 dump_sec_cam(RTW_DBGDUMP, adapter);
8586 dump_sec_cam_cache(RTW_DBGDUMP, adapter);
8587 #endif
8588 #ifdef CONFIG_USB_HCI
8589 /* free adapter's resource */
8590 rtw_mi_intf_stop(adapter);
8591
8592 #endif
8593 #if defined(CONFIG_USB_HCI) || defined(CONFIG_PCI_HCI)
8594 /* Invoid SE0 reset signal during suspending*/
8595 rtw_write8(adapter, REG_RSV_CTRL, 0x20);
8596 if (IS_8188F(pHalData->version_id) == FALSE)
8597 rtw_write8(adapter, REG_RSV_CTRL, 0x60);
8598 #endif
8599
8600 rtw_hal_gate_bb(adapter, _FALSE);
8601 }
8602
8603 #define DBG_WAKEUP_REASON
8604 #ifdef DBG_WAKEUP_REASON
_dbg_wake_up_reason_string(_adapter * adapter,const char * srt_res)8605 void _dbg_wake_up_reason_string(_adapter *adapter, const char *srt_res)
8606 {
8607 RTW_INFO(ADPT_FMT "- wake up reason - %s\n", ADPT_ARG(adapter), srt_res);
8608 }
_dbg_rtw_wake_up_reason(_adapter * adapter,u8 reason)8609 void _dbg_rtw_wake_up_reason(_adapter *adapter, u8 reason)
8610 {
8611 if (RX_PAIRWISEKEY == reason)
8612 _dbg_wake_up_reason_string(adapter, "Rx pairwise key");
8613 else if (RX_GTK == reason)
8614 _dbg_wake_up_reason_string(adapter, "Rx GTK");
8615 else if (RX_FOURWAY_HANDSHAKE == reason)
8616 _dbg_wake_up_reason_string(adapter, "Rx four way handshake");
8617 else if (RX_DISASSOC == reason)
8618 _dbg_wake_up_reason_string(adapter, "Rx disassoc");
8619 else if (RX_DEAUTH == reason)
8620 _dbg_wake_up_reason_string(adapter, "Rx deauth");
8621 else if (RX_ARP_REQUEST == reason)
8622 _dbg_wake_up_reason_string(adapter, "Rx ARP request");
8623 else if (FW_DECISION_DISCONNECT == reason)
8624 _dbg_wake_up_reason_string(adapter, "FW detect disconnect");
8625 else if (RX_MAGIC_PKT == reason)
8626 _dbg_wake_up_reason_string(adapter, "Rx magic packet");
8627 else if (RX_UNICAST_PKT == reason)
8628 _dbg_wake_up_reason_string(adapter, "Rx unicast packet");
8629 else if (RX_PATTERN_PKT == reason)
8630 _dbg_wake_up_reason_string(adapter, "Rx pattern packet");
8631 else if (RTD3_SSID_MATCH == reason)
8632 _dbg_wake_up_reason_string(adapter, "RTD3 SSID match");
8633 else if (RX_REALWOW_V2_WAKEUP_PKT == reason)
8634 _dbg_wake_up_reason_string(adapter, "Rx real WOW V2 wakeup packet");
8635 else if (RX_REALWOW_V2_ACK_LOST == reason)
8636 _dbg_wake_up_reason_string(adapter, "Rx real WOW V2 ack lost");
8637 else if (ENABLE_FAIL_DMA_IDLE == reason)
8638 _dbg_wake_up_reason_string(adapter, "enable fail DMA idle");
8639 else if (ENABLE_FAIL_DMA_PAUSE == reason)
8640 _dbg_wake_up_reason_string(adapter, "enable fail DMA pause");
8641 else if (AP_OFFLOAD_WAKEUP == reason)
8642 _dbg_wake_up_reason_string(adapter, "AP offload wakeup");
8643 else if (CLK_32K_UNLOCK == reason)
8644 _dbg_wake_up_reason_string(adapter, "clk 32k unlock");
8645 else if (RTIME_FAIL_DMA_IDLE == reason)
8646 _dbg_wake_up_reason_string(adapter, "RTIME fail DMA idle");
8647 else if (CLK_32K_LOCK == reason)
8648 _dbg_wake_up_reason_string(adapter, "clk 32k lock");
8649 else
8650 _dbg_wake_up_reason_string(adapter, "unknown reasoen");
8651 }
8652 #endif
8653
rtw_hal_wow_disable(_adapter * adapter)8654 static void rtw_hal_wow_disable(_adapter *adapter)
8655 {
8656 struct pwrctrl_priv *pwrctl = adapter_to_pwrctl(adapter);
8657 struct security_priv *psecuritypriv = &adapter->securitypriv;
8658 struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
8659 struct hal_ops *pHalFunc = &adapter->hal_func;
8660 struct sta_info *psta = NULL;
8661 int res;
8662 u16 media_status_rpt;
8663 u8 val8;
8664
8665 RTW_PRINT("%s, WOWLAN_DISABLE\n", __func__);
8666
8667 if (!pwrctl->wowlan_pno_enable) {
8668 psta = rtw_get_stainfo(&adapter->stapriv, get_bssid(pmlmepriv));
8669 if (psta != NULL)
8670 rtw_sta_media_status_rpt(adapter, psta, 0);
8671 else
8672 RTW_INFO("%s: psta is null\n", __func__);
8673 }
8674
8675 if (0) {
8676 RTW_INFO("0x630:0x%02x\n", rtw_read8(adapter, 0x630));
8677 RTW_INFO("0x631:0x%02x\n", rtw_read8(adapter, 0x631));
8678 RTW_INFO("0x634:0x%02x\n", rtw_read8(adapter, 0x634));
8679 RTW_INFO("0x1c7:0x%02x\n", rtw_read8(adapter, 0x1c7));
8680 }
8681
8682 pwrctl->wowlan_wake_reason = rtw_read8(adapter, REG_WOWLAN_WAKE_REASON);
8683
8684 RTW_PRINT("wakeup_reason: 0x%02x\n",
8685 pwrctl->wowlan_wake_reason);
8686 #ifdef DBG_WAKEUP_REASON
8687 _dbg_rtw_wake_up_reason(adapter, pwrctl->wowlan_wake_reason);
8688 #endif
8689
8690 rtw_hal_set_fw_wow_related_cmd(adapter, 0);
8691
8692 res = rtw_hal_check_wow_ctrl(adapter, _FALSE);
8693
8694 if (res == _FALSE) {
8695 RTW_INFO("[Error]%s: disable WOW cmd fail\n!!", __func__);
8696 rtw_hal_force_enable_rxdma(adapter);
8697 }
8698
8699 rtw_hal_gate_bb(adapter, _TRUE);
8700
8701 res = rtw_hal_pause_rx_dma(adapter);
8702 if (res == _FAIL)
8703 RTW_PRINT("[WARNING] pause RX DMA fail\n");
8704
8705 /* clean HW pattern match */
8706 rtw_hal_dl_pattern(adapter, 0);
8707
8708 #ifndef CONFIG_WOW_PATTERN_HW_CAM
8709 /* config RXFF boundary to original */
8710 rtw_hal_set_wow_rxff_boundary(adapter, _FALSE);
8711 #endif
8712 rtw_hal_release_rx_dma(adapter);
8713
8714 #if defined(CONFIG_RTL8188E)
8715 if (IS_HARDWARE_TYPE_8188E(adapter))
8716 rtw_hal_enable_tx_report(adapter);
8717 #endif
8718
8719 if ((pwrctl->wowlan_wake_reason != RX_DISASSOC) ||
8720 (pwrctl->wowlan_wake_reason != RX_DEAUTH) ||
8721 (pwrctl->wowlan_wake_reason != FW_DECISION_DISCONNECT)) {
8722 rtw_hal_get_aoac_rpt(adapter);
8723 rtw_hal_update_sw_security_info(adapter);
8724 }
8725
8726 rtw_hal_fw_dl(adapter, _FALSE);
8727
8728 #ifdef CONFIG_GPIO_WAKEUP
8729
8730 #ifdef CONFIG_WAKEUP_GPIO_INPUT_MODE
8731 if (pwrctl->is_high_active == 0)
8732 rtw_hal_set_input_gpio(adapter, WAKEUP_GPIO_IDX);
8733 else
8734 rtw_hal_set_output_gpio(adapter, WAKEUP_GPIO_IDX, 0);
8735 #else
8736 val8 = (pwrctl->is_high_active == 0) ? 1 : 0;
8737 RTW_PRINT("Set Wake GPIO to default(%d).\n", val8);
8738
8739 rtw_hal_set_output_gpio(adapter, WAKEUP_GPIO_IDX, val8);
8740 rtw_hal_switch_gpio_wl_ctrl(adapter, WAKEUP_GPIO_IDX, _FALSE);
8741 #endif
8742
8743 #endif
8744 if ((pwrctl->wowlan_wake_reason != FW_DECISION_DISCONNECT) &&
8745 (pwrctl->wowlan_wake_reason != RX_PAIRWISEKEY) &&
8746 (pwrctl->wowlan_wake_reason != RX_DISASSOC) &&
8747 (pwrctl->wowlan_wake_reason != RX_DEAUTH)) {
8748
8749 media_status_rpt = RT_MEDIA_CONNECT;
8750 rtw_hal_set_hwreg(adapter, HW_VAR_H2C_FW_JOINBSSRPT,
8751 (u8 *)&media_status_rpt);
8752
8753 if (psta != NULL) {
8754 #ifdef CONFIG_FW_MULTI_PORT_SUPPORT
8755 rtw_hal_set_default_port_id_cmd(adapter, psta->cmn.mac_id);
8756 #endif
8757 rtw_sta_media_status_rpt(adapter, psta, 1);
8758 }
8759 }
8760 rtw_hal_gate_bb(adapter, _FALSE);
8761 }
8762 #endif /*CONFIG_WOWLAN*/
8763
8764 #ifdef CONFIG_P2P_WOWLAN
rtw_hal_set_p2p_wow_fw_rsvd_page(_adapter * adapter,u8 * pframe,u16 index,u8 tx_desc,u32 page_size,u8 * page_num,u32 * total_pkt_len,RSVDPAGE_LOC * rsvd_page_loc)8765 void rtw_hal_set_p2p_wow_fw_rsvd_page(_adapter *adapter, u8 *pframe, u16 index,
8766 u8 tx_desc, u32 page_size, u8 *page_num, u32 *total_pkt_len,
8767 RSVDPAGE_LOC *rsvd_page_loc)
8768 {
8769 u32 P2PNegoRspLength = 0, P2PInviteRspLength = 0;
8770 u32 P2PPDRspLength = 0, P2PProbeRspLength = 0, P2PBCNLength = 0;
8771 u8 CurtPktPageNum = 0;
8772
8773 /* P2P Beacon */
8774 rsvd_page_loc->LocP2PBeacon = *page_num;
8775 rtw_hal_construct_P2PBeacon(adapter, &pframe[index], &P2PBCNLength);
8776 rtw_hal_fill_fake_txdesc(adapter, &pframe[index - tx_desc],
8777 P2PBCNLength, _FALSE, _FALSE, _FALSE);
8778
8779 #if 0
8780 RTW_INFO("%s(): HW_VAR_SET_TX_CMD: PROBE RSP %p %d\n",
8781 __FUNCTION__, &pframe[index - tx_desc], (P2PBCNLength + tx_desc));
8782 #endif
8783
8784 CurtPktPageNum = (u8)PageNum(tx_desc + P2PBCNLength, page_size);
8785
8786 *page_num += CurtPktPageNum;
8787
8788 index += (CurtPktPageNum * page_size);
8789
8790 /* P2P Probe rsp */
8791 rsvd_page_loc->LocP2PProbeRsp = *page_num;
8792 rtw_hal_construct_P2PProbeRsp(adapter, &pframe[index],
8793 &P2PProbeRspLength);
8794 rtw_hal_fill_fake_txdesc(adapter, &pframe[index - tx_desc],
8795 P2PProbeRspLength, _FALSE, _FALSE, _FALSE);
8796
8797 /* RTW_INFO("%s(): HW_VAR_SET_TX_CMD: PROBE RSP %p %d\n", */
8798 /* __FUNCTION__, &pframe[index-tx_desc], (P2PProbeRspLength+tx_desc)); */
8799
8800 CurtPktPageNum = (u8)PageNum(tx_desc + P2PProbeRspLength, page_size);
8801
8802 *page_num += CurtPktPageNum;
8803
8804 index += (CurtPktPageNum * page_size);
8805
8806 /* P2P nego rsp */
8807 rsvd_page_loc->LocNegoRsp = *page_num;
8808 rtw_hal_construct_P2PNegoRsp(adapter, &pframe[index],
8809 &P2PNegoRspLength);
8810 rtw_hal_fill_fake_txdesc(adapter, &pframe[index - tx_desc],
8811 P2PNegoRspLength, _FALSE, _FALSE, _FALSE);
8812
8813 /* RTW_INFO("%s(): HW_VAR_SET_TX_CMD: QOS NULL DATA %p %d\n", */
8814 /* __FUNCTION__, &pframe[index-tx_desc], (NegoRspLength+tx_desc)); */
8815
8816 CurtPktPageNum = (u8)PageNum(tx_desc + P2PNegoRspLength, page_size);
8817
8818 *page_num += CurtPktPageNum;
8819
8820 index += (CurtPktPageNum * page_size);
8821
8822 /* P2P invite rsp */
8823 rsvd_page_loc->LocInviteRsp = *page_num;
8824 rtw_hal_construct_P2PInviteRsp(adapter, &pframe[index],
8825 &P2PInviteRspLength);
8826 rtw_hal_fill_fake_txdesc(adapter, &pframe[index - tx_desc],
8827 P2PInviteRspLength, _FALSE, _FALSE, _FALSE);
8828
8829 /* RTW_INFO("%s(): HW_VAR_SET_TX_CMD: QOS NULL DATA %p %d\n", */
8830 /* __FUNCTION__, &pframe[index-tx_desc], (InviteRspLength+tx_desc)); */
8831
8832 CurtPktPageNum = (u8)PageNum(tx_desc + P2PInviteRspLength, page_size);
8833
8834 *page_num += CurtPktPageNum;
8835
8836 index += (CurtPktPageNum * page_size);
8837
8838 /* P2P provision discovery rsp */
8839 rsvd_page_loc->LocPDRsp = *page_num;
8840 rtw_hal_construct_P2PProvisionDisRsp(adapter,
8841 &pframe[index], &P2PPDRspLength);
8842
8843 rtw_hal_fill_fake_txdesc(adapter, &pframe[index - tx_desc],
8844 P2PPDRspLength, _FALSE, _FALSE, _FALSE);
8845
8846 /* RTW_INFO("%s(): HW_VAR_SET_TX_CMD: QOS NULL DATA %p %d\n", */
8847 /* __FUNCTION__, &pframe[index-tx_desc], (PDRspLength+tx_desc)); */
8848
8849 CurtPktPageNum = (u8)PageNum(tx_desc + P2PPDRspLength, page_size);
8850
8851 *page_num += CurtPktPageNum;
8852
8853 *total_pkt_len = index + P2PPDRspLength;
8854
8855 index += (CurtPktPageNum * page_size);
8856
8857
8858 }
8859 #endif /* CONFIG_P2P_WOWLAN */
8860
8861 #ifdef CONFIG_LPS_PG
8862 #include "hal_halmac.h"
8863
8864 #define DBG_LPSPG_SEC_DUMP
8865 #define LPS_PG_INFO_RSVD_LEN 16
8866 #define LPS_PG_INFO_RSVD_PAGE_NUM 1
8867
8868 #define DBG_LPSPG_INFO_DUMP
rtw_hal_set_lps_pg_info_rsvd_page(_adapter * adapter)8869 static void rtw_hal_set_lps_pg_info_rsvd_page(_adapter *adapter)
8870 {
8871 struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(adapter);
8872 struct sta_info *psta = rtw_get_stainfo(&adapter->stapriv, get_bssid(&adapter->mlmepriv));
8873 struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
8874 PHAL_DATA_TYPE phal_data = GET_HAL_DATA(adapter);
8875 u8 lps_pg_info[LPS_PG_INFO_RSVD_LEN] = {0};
8876 #ifdef CONFIG_MBSSID_CAM
8877 u8 cam_id = INVALID_CAM_ID;
8878 #endif
8879 u8 *psec_cam_id = lps_pg_info + 8;
8880 u8 sec_cam_num = 0;
8881 u8 drv_rsvdpage_num = 0;
8882
8883 if (!psta) {
8884 RTW_ERR("%s [ERROR] sta is NULL\n", __func__);
8885 rtw_warn_on(1);
8886 return;
8887 }
8888
8889 /*Byte 0 - used macid*/
8890 LPSPG_RSVD_PAGE_SET_MACID(lps_pg_info, psta->cmn.mac_id);
8891 RTW_INFO("[LPSPG-INFO] mac_id:%d\n", psta->cmn.mac_id);
8892
8893 #ifdef CONFIG_MBSSID_CAM
8894 /*Byte 1 - used BSSID CAM entry*/
8895 cam_id = rtw_mbid_cam_search_by_ifaceid(adapter, adapter->iface_id);
8896 if (cam_id != INVALID_CAM_ID)
8897 LPSPG_RSVD_PAGE_SET_MBSSCAMID(lps_pg_info, cam_id);
8898 RTW_INFO("[LPSPG-INFO] mbss_cam_id:%d\n", cam_id);
8899 #endif
8900
8901 #ifdef CONFIG_WOWLAN /*&& pattern match cam used*/
8902 /*Btye 2 - Max used Pattern Match CAM entry*/
8903 if (pwrpriv->wowlan_mode == _TRUE &&
8904 check_fwstate(&adapter->mlmepriv, _FW_LINKED) == _TRUE) {
8905 LPSPG_RSVD_PAGE_SET_PMC_NUM(lps_pg_info, pwrpriv->wowlan_pattern_idx);
8906 RTW_INFO("[LPSPG-INFO] Max Pattern Match CAM entry :%d\n", pwrpriv->wowlan_pattern_idx);
8907 }
8908 #endif
8909 #ifdef CONFIG_BEAMFORMING /*&& MU BF*/
8910 /*Btye 3 - Max MU rate table Group ID*/
8911 LPSPG_RSVD_PAGE_SET_MU_RAID_GID(lps_pg_info, _value);
8912 RTW_INFO("[LPSPG-INFO] Max MU rate table Group ID :%d\n", _value);
8913 #endif
8914
8915 /*Btye 8 ~15 - used Security CAM entry */
8916 sec_cam_num = rtw_get_sec_camid(adapter, 8, psec_cam_id);
8917
8918 /*Btye 4 - used Security CAM entry number*/
8919 if (sec_cam_num < 8)
8920 LPSPG_RSVD_PAGE_SET_SEC_CAM_NUM(lps_pg_info, sec_cam_num);
8921 RTW_INFO("[LPSPG-INFO] Security CAM entry number :%d\n", sec_cam_num);
8922
8923 /*Btye 5 - Txbuf used page number for fw offload*/
8924 if (pwrpriv->wowlan_mode == _TRUE || pwrpriv->wowlan_ap_mode == _TRUE)
8925 drv_rsvdpage_num = rtw_hal_get_txbuff_rsvd_page_num(adapter, _TRUE);
8926 else
8927 drv_rsvdpage_num = rtw_hal_get_txbuff_rsvd_page_num(adapter, _FALSE);
8928 LPSPG_RSVD_PAGE_SET_DRV_RSVDPAGE_NUM(lps_pg_info, drv_rsvdpage_num);
8929 RTW_INFO("[LPSPG-INFO] DRV's rsvd page numbers :%d\n", drv_rsvdpage_num);
8930
8931 #ifdef DBG_LPSPG_SEC_DUMP
8932 {
8933 int i;
8934
8935 for (i = 0; i < sec_cam_num; i++)
8936 RTW_INFO("%d = sec_cam_id:%d\n", i, psec_cam_id[i]);
8937 }
8938 #endif
8939
8940 #ifdef DBG_LPSPG_INFO_DUMP
8941 RTW_INFO("==== DBG_LPSPG_INFO_RSVD_PAGE_DUMP====\n");
8942 RTW_INFO(" %02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X\n",
8943 *(lps_pg_info), *(lps_pg_info + 1), *(lps_pg_info + 2), *(lps_pg_info + 3),
8944 *(lps_pg_info + 4), *(lps_pg_info + 5), *(lps_pg_info + 6), *(lps_pg_info + 7));
8945 RTW_INFO(" %02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X\n",
8946 *(lps_pg_info + 8), *(lps_pg_info + 9), *(lps_pg_info + 10), *(lps_pg_info + 11),
8947 *(lps_pg_info + 12), *(lps_pg_info + 13), *(lps_pg_info + 14), *(lps_pg_info + 15));
8948 RTW_INFO("==== DBG_LPSPG_INFO_RSVD_PAGE_DUMP====\n");
8949 #endif
8950
8951 rtw_halmac_download_rsvd_page(dvobj, pwrpriv->lpspg_rsvd_page_locate, lps_pg_info, LPS_PG_INFO_RSVD_LEN);
8952
8953 #ifdef DBG_LPSPG_INFO_DUMP
8954 RTW_INFO("Get LPS-PG INFO from rsvd page_offset:%d\n", pwrpriv->lpspg_rsvd_page_locate);
8955 rtw_dump_rsvd_page(RTW_DBGDUMP, adapter, pwrpriv->lpspg_rsvd_page_locate, 1);
8956 #endif
8957 }
8958
8959
rtw_hal_set_lps_pg_info_cmd(_adapter * adapter)8960 static u8 rtw_hal_set_lps_pg_info_cmd(_adapter *adapter)
8961 {
8962 struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(adapter);
8963 struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
8964
8965 u8 lpspg_info[H2C_LPS_PG_INFO_LEN] = {0};
8966 u8 ret = _FAIL;
8967
8968 RTW_INFO("%s: loc_lpspg_info:%d\n", __func__, pwrpriv->lpspg_rsvd_page_locate);
8969
8970 if (_NO_PRIVACY_ != adapter->securitypriv.dot11PrivacyAlgrthm)
8971 SET_H2CCMD_LPSPG_SEC_CAM_EN(lpspg_info, 1); /*SecurityCAM_En*/
8972 #ifdef CONFIG_MBSSID_CAM
8973 SET_H2CCMD_LPSPG_MBID_CAM_EN(lpspg_info, 1); /*BSSIDCAM_En*/
8974 #endif
8975
8976 #if defined(CONFIG_WOWLAN) && defined(CONFIG_WOW_PATTERN_HW_CAM)
8977 if (pwrpriv->wowlan_mode == _TRUE &&
8978 check_fwstate(pmlmepriv, _FW_LINKED) == _TRUE) {
8979
8980 SET_H2CCMD_LPSPG_PMC_CAM_EN(lpspg_info, 1); /*PatternMatchCAM_En*/
8981 }
8982 #endif
8983
8984 #ifdef CONFIG_MACID_SEARCH
8985 SET_H2CCMD_LPSPG_MACID_SEARCH_EN(lpspg_info, 1); /*MACIDSearch_En*/
8986 #endif
8987
8988 #ifdef CONFIG_TX_SC
8989 SET_H2CCMD_LPSPG_TXSC_EN(lpspg_info, 1); /*TXSC_En*/
8990 #endif
8991
8992 #ifdef CONFIG_BEAMFORMING /*&& MU BF*/
8993 SET_H2CCMD_LPSPG_MU_RATE_TB_EN(lpspg_info, 1); /*MURateTable_En*/
8994 #endif
8995
8996 SET_H2CCMD_LPSPG_LOC(lpspg_info, pwrpriv->lpspg_rsvd_page_locate);
8997
8998 #ifdef DBG_LPSPG_INFO_DUMP
8999 RTW_INFO("==== DBG_LPSPG_INFO_CMD_DUMP====\n");
9000 RTW_INFO(" H2C_CMD: 0x%02x, H2C_LEN: %d\n", H2C_LPS_PG_INFO, H2C_LPS_PG_INFO_LEN);
9001 RTW_INFO(" %02X:%02X\n", *(lpspg_info), *(lpspg_info + 1));
9002 RTW_INFO("==== DBG_LPSPG_INFO_CMD_DUMP====\n");
9003 #endif
9004
9005 ret = rtw_hal_fill_h2c_cmd(adapter,
9006 H2C_LPS_PG_INFO,
9007 H2C_LPS_PG_INFO_LEN,
9008 lpspg_info);
9009 return ret;
9010 }
rtw_hal_set_lps_pg_info(_adapter * adapter)9011 u8 rtw_hal_set_lps_pg_info(_adapter *adapter)
9012 {
9013 u8 ret = _FAIL;
9014 struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(adapter);
9015
9016 if (pwrpriv->lpspg_rsvd_page_locate == 0) {
9017 RTW_ERR("%s [ERROR] lpspg_rsvd_page_locate = 0\n", __func__);
9018 rtw_warn_on(1);
9019 return ret;
9020 }
9021
9022 rtw_hal_set_lps_pg_info_rsvd_page(adapter);
9023 ret = rtw_hal_set_lps_pg_info_cmd(adapter);
9024 if (_SUCCESS == ret)
9025 pwrpriv->blpspg_info_up = _FALSE;
9026
9027 return ret;
9028 }
9029
rtw_hal_lps_pg_rssi_lv_decide(_adapter * adapter,struct sta_info * sta)9030 void rtw_hal_lps_pg_rssi_lv_decide(_adapter *adapter, struct sta_info *sta)
9031 {
9032 #if 0
9033 if (sta->cmn.ra_info.rssi_level >= 4)
9034 sta->lps_pg_rssi_lv = 3; /*RSSI High - 1SS_VHT_MCS7*/
9035 else if (sta->cmn.ra_info.rssi_level >= 2)
9036 sta->lps_pg_rssi_lv = 2; /*RSSI Middle - 1SS_VHT_MCS3*/
9037 else
9038 sta->lps_pg_rssi_lv = 1; /*RSSI Lower - Lowest_rate*/
9039 #else
9040 sta->lps_pg_rssi_lv = 0;
9041 #endif
9042 RTW_INFO("%s mac-id:%d, rssi:%d, rssi_level:%d, lps_pg_rssi_lv:%d\n",
9043 __func__, sta->cmn.mac_id, sta->cmn.rssi_stat.rssi, sta->cmn.ra_info.rssi_level, sta->lps_pg_rssi_lv);
9044 }
9045
rtw_hal_lps_pg_handler(_adapter * adapter,enum lps_pg_hdl_id hdl_id)9046 void rtw_hal_lps_pg_handler(_adapter *adapter, enum lps_pg_hdl_id hdl_id)
9047 {
9048 switch (hdl_id) {
9049 case LPS_PG_INFO_CFG:
9050 rtw_hal_set_lps_pg_info(adapter);
9051 break;
9052 case LPS_PG_REDLEMEM:
9053 {
9054 /*set xmit_block*/
9055 rtw_set_xmit_block(adapter, XMIT_BLOCK_REDLMEM);
9056 if (_FAIL == rtw_hal_fw_mem_dl(adapter, FW_EMEM))
9057 rtw_warn_on(1);
9058 /*clearn xmit_block*/
9059 rtw_clr_xmit_block(adapter, XMIT_BLOCK_REDLMEM);
9060 }
9061 break;
9062
9063 case LPS_PG_RESEND_H2C:
9064 {
9065 struct macid_ctl_t *macid_ctl = &adapter->dvobj->macid_ctl;
9066 struct sta_info *sta;
9067 int i;
9068
9069 for (i = 0; i < MACID_NUM_SW_LIMIT; i++) {
9070 sta = macid_ctl->sta[i];
9071 if (sta && !is_broadcast_mac_addr(sta->cmn.mac_addr)) {
9072 rtw_hal_lps_pg_rssi_lv_decide(adapter, sta);
9073 set_sta_rate(adapter, sta);
9074 sta->lps_pg_rssi_lv = 0;
9075 }
9076 }
9077 }
9078 break;
9079
9080 default:
9081 break;
9082 }
9083 }
9084
9085 #endif /*CONFIG_LPS_PG*/
9086
9087 /*
9088 * Description: Fill the reserved packets that FW will use to RSVD page.
9089 * Now we just send 4 types packet to rsvd page.
9090 * (1)Beacon, (2)Ps-poll, (3)Null data, (4)ProbeRsp.
9091 * Input:
9092 * finished - FALSE:At the first time we will send all the packets as a large packet to Hw,
9093 * so we need to set the packet length to total lengh.
9094 * TRUE: At the second time, we should send the first packet (default:beacon)
9095 * to Hw again and set the lengh in descriptor to the real beacon lengh.
9096 * page_num - The amount of reserved page which driver need.
9097 * If this is not NULL, this function doesn't real download reserved
9098 * page, but just count the number of reserved page.
9099 *
9100 * 2009.10.15 by tynli.
9101 * 2017.06.20 modified by Lucas.
9102 *
9103 * Page Size = 128: 8188e, 8723a/b, 8192c/d,
9104 * Page Size = 256: 8192e, 8821a
9105 * Page Size = 512: 8812a
9106 */
9107
9108 /*#define DBG_DUMP_SET_RSVD_PAGE*/
_rtw_hal_set_fw_rsvd_page(_adapter * adapter,bool finished,u8 * page_num)9109 static void _rtw_hal_set_fw_rsvd_page(_adapter *adapter, bool finished, u8 *page_num)
9110 {
9111 PHAL_DATA_TYPE pHalData;
9112 struct xmit_frame *pcmdframe = NULL;
9113 struct pkt_attrib *pattrib;
9114 struct xmit_priv *pxmitpriv;
9115 struct mlme_ext_priv *pmlmeext;
9116 struct mlme_ext_info *pmlmeinfo;
9117 struct pwrctrl_priv *pwrctl;
9118 struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
9119 struct hal_ops *pHalFunc = &adapter->hal_func;
9120 u32 BeaconLength = 0, ProbeRspLength = 0, PSPollLength = 0;
9121 u32 NullDataLength = 0, QosNullLength = 0, BTQosNullLength = 0;
9122 u32 ProbeReqLength = 0, NullFunctionDataLength = 0;
9123 u8 TxDescLen = TXDESC_SIZE, TxDescOffset = TXDESC_OFFSET;
9124 u8 TotalPageNum = 0 , CurtPktPageNum = 0 , RsvdPageNum = 0;
9125 u8 *ReservedPagePacket;
9126 u16 BufIndex = 0;
9127 u32 TotalPacketLen = 0, MaxRsvdPageBufSize = 0, PageSize = 0;
9128 RSVDPAGE_LOC RsvdPageLoc;
9129
9130 #ifdef DBG_CONFIG_ERROR_DETECT
9131 struct sreset_priv *psrtpriv;
9132 #endif /* DBG_CONFIG_ERROR_DETECT */
9133
9134 #ifdef CONFIG_MCC_MODE
9135 u8 dl_mcc_page = _FAIL;
9136 #endif /* CONFIG_MCC_MODE */
9137
9138 pHalData = GET_HAL_DATA(adapter);
9139 #ifdef DBG_CONFIG_ERROR_DETECT
9140 psrtpriv = &pHalData->srestpriv;
9141 #endif
9142 pxmitpriv = &adapter->xmitpriv;
9143 pmlmeext = &adapter->mlmeextpriv;
9144 pmlmeinfo = &pmlmeext->mlmext_info;
9145 pwrctl = adapter_to_pwrctl(adapter);
9146
9147 rtw_hal_get_def_var(adapter, HAL_DEF_TX_PAGE_SIZE, (u8 *)&PageSize);
9148
9149 if (PageSize == 0) {
9150 RTW_INFO("[Error]: %s, PageSize is zero!!\n", __func__);
9151 return;
9152 }
9153
9154 /* Prepare ReservedPagePacket */
9155 if (page_num) {
9156 ReservedPagePacket = rtw_zmalloc(MAX_CMDBUF_SZ);
9157 if (!ReservedPagePacket) {
9158 RTW_WARN("%s: alloc ReservedPagePacket fail!\n", __FUNCTION__);
9159 *page_num = 0xFF;
9160 return;
9161 }
9162 } else {
9163 if (pwrctl->wowlan_mode == _TRUE || pwrctl->wowlan_ap_mode == _TRUE)
9164 RsvdPageNum = rtw_hal_get_txbuff_rsvd_page_num(adapter, _TRUE);
9165 else
9166 RsvdPageNum = rtw_hal_get_txbuff_rsvd_page_num(adapter, _FALSE);
9167
9168 RTW_INFO("%s PageSize: %d, RsvdPageNUm: %d\n", __func__, PageSize, RsvdPageNum);
9169
9170 MaxRsvdPageBufSize = RsvdPageNum * PageSize;
9171 if (MaxRsvdPageBufSize > MAX_CMDBUF_SZ) {
9172 RTW_ERR("%s MaxRsvdPageBufSize(%d) is larger than MAX_CMDBUF_SZ(%d)",
9173 __func__, MaxRsvdPageBufSize, MAX_CMDBUF_SZ);
9174 rtw_warn_on(1);
9175 return;
9176 }
9177
9178 pcmdframe = rtw_alloc_cmdxmitframe(pxmitpriv);
9179 if (pcmdframe == NULL) {
9180 RTW_ERR("%s: alloc ReservedPagePacket fail!\n", __FUNCTION__);
9181 return;
9182 }
9183
9184 ReservedPagePacket = pcmdframe->buf_addr;
9185 }
9186
9187 _rtw_memset(&RsvdPageLoc, 0, sizeof(RSVDPAGE_LOC));
9188
9189 /* beacon * 1 pages */
9190 BufIndex = TxDescOffset;
9191 rtw_hal_construct_beacon(adapter,
9192 &ReservedPagePacket[BufIndex], &BeaconLength);
9193
9194 /*
9195 * When we count the first page size, we need to reserve description size for the RSVD
9196 * packet, it will be filled in front of the packet in TXPKTBUF.
9197 */
9198 CurtPktPageNum = (u8)PageNum((TxDescLen + BeaconLength), PageSize);
9199
9200 TotalPageNum += CurtPktPageNum;
9201
9202 BufIndex += (CurtPktPageNum * PageSize);
9203
9204 if (pwrctl->wowlan_ap_mode == _TRUE) {
9205 /* (4) probe response*/
9206 RsvdPageLoc.LocProbeRsp = TotalPageNum;
9207 rtw_hal_construct_ProbeRsp(
9208 adapter, &ReservedPagePacket[BufIndex],
9209 &ProbeRspLength,
9210 get_my_bssid(&pmlmeinfo->network), _FALSE);
9211 rtw_hal_fill_fake_txdesc(adapter,
9212 &ReservedPagePacket[BufIndex - TxDescLen],
9213 ProbeRspLength, _FALSE, _FALSE, _FALSE);
9214
9215 CurtPktPageNum = (u8)PageNum(TxDescLen + ProbeRspLength, PageSize);
9216 TotalPageNum += CurtPktPageNum;
9217 TotalPacketLen = BufIndex + ProbeRspLength;
9218 BufIndex += (CurtPktPageNum * PageSize);
9219 goto download_page;
9220 }
9221
9222 /* ps-poll * 1 page */
9223 RsvdPageLoc.LocPsPoll = TotalPageNum;
9224 RTW_INFO("LocPsPoll: %d\n", RsvdPageLoc.LocPsPoll);
9225 rtw_hal_construct_PSPoll(adapter,
9226 &ReservedPagePacket[BufIndex], &PSPollLength);
9227 rtw_hal_fill_fake_txdesc(adapter,
9228 &ReservedPagePacket[BufIndex - TxDescLen],
9229 PSPollLength, _TRUE, _FALSE, _FALSE);
9230
9231 CurtPktPageNum = (u8)PageNum((TxDescLen + PSPollLength), PageSize);
9232
9233 TotalPageNum += CurtPktPageNum;
9234
9235 BufIndex += (CurtPktPageNum * PageSize);
9236
9237 #ifdef CONFIG_BT_COEXIST
9238 if (pwrctl->wowlan_mode == _FALSE ||
9239 pwrctl->wowlan_in_resume == _TRUE) {
9240 /* BT Qos null data * 1 page */
9241 RsvdPageLoc.LocBTQosNull = TotalPageNum;
9242
9243 RTW_INFO("LocBTQosNull: %d\n", RsvdPageLoc.LocBTQosNull);
9244
9245 rtw_hal_construct_NullFunctionData(adapter,
9246 &ReservedPagePacket[BufIndex],
9247 &BTQosNullLength,
9248 get_my_bssid(&pmlmeinfo->network),
9249 _TRUE, 0, 0, _FALSE);
9250
9251 rtw_hal_fill_fake_txdesc(adapter,
9252 &ReservedPagePacket[BufIndex - TxDescLen],
9253 BTQosNullLength, _FALSE, _TRUE, _FALSE);
9254
9255 CurtPktPageNum = (u8)PageNum(TxDescLen + BTQosNullLength,
9256 PageSize);
9257
9258 TotalPageNum += CurtPktPageNum;
9259 BufIndex += (CurtPktPageNum * PageSize);
9260 }
9261 #endif /* CONFIG_BT_COEXIT */
9262
9263 #ifdef CONFIG_MCC_MODE
9264 if (MCC_EN(adapter)) {
9265 dl_mcc_page = rtw_hal_dl_mcc_fw_rsvd_page(adapter, ReservedPagePacket,
9266 &BufIndex, TxDescLen, PageSize,
9267 &TotalPageNum, &TotalPacketLen, &RsvdPageLoc);
9268 } else {
9269 dl_mcc_page = _FAIL;
9270 }
9271
9272 if (dl_mcc_page == _FAIL)
9273 #endif /* CONFIG_MCC_MODE */
9274 {
9275 /* null data * 1 page */
9276 RsvdPageLoc.LocNullData = TotalPageNum;
9277 RTW_INFO("LocNullData: %d\n", RsvdPageLoc.LocNullData);
9278 rtw_hal_construct_NullFunctionData(
9279 adapter,
9280 &ReservedPagePacket[BufIndex],
9281 &NullDataLength,
9282 get_my_bssid(&pmlmeinfo->network),
9283 _FALSE, 0, 0, _FALSE);
9284 rtw_hal_fill_fake_txdesc(adapter,
9285 &ReservedPagePacket[BufIndex - TxDescLen],
9286 NullDataLength, _FALSE, _FALSE, _FALSE);
9287
9288 CurtPktPageNum = (u8)PageNum(TxDescLen + NullDataLength, PageSize);
9289
9290 TotalPageNum += CurtPktPageNum;
9291
9292 BufIndex += (CurtPktPageNum * PageSize);
9293 }
9294
9295 if (pwrctl->wowlan_mode == _FALSE ||
9296 pwrctl->wowlan_in_resume == _TRUE) {
9297 /* Qos null data * 1 page */
9298 RsvdPageLoc.LocQosNull = TotalPageNum;
9299 RTW_INFO("LocQosNull: %d\n", RsvdPageLoc.LocQosNull);
9300 rtw_hal_construct_NullFunctionData(adapter,
9301 &ReservedPagePacket[BufIndex],
9302 &QosNullLength,
9303 get_my_bssid(&pmlmeinfo->network),
9304 _TRUE, 0, 0, _FALSE);
9305 rtw_hal_fill_fake_txdesc(adapter,
9306 &ReservedPagePacket[BufIndex - TxDescLen],
9307 QosNullLength, _FALSE, _FALSE, _FALSE);
9308
9309 CurtPktPageNum = (u8)PageNum(TxDescLen + QosNullLength,
9310 PageSize);
9311
9312 TotalPageNum += CurtPktPageNum;
9313
9314 BufIndex += (CurtPktPageNum * PageSize);
9315 }
9316
9317 TotalPacketLen = BufIndex + QosNullLength;
9318
9319 #ifdef CONFIG_WOWLAN
9320 if (pwrctl->wowlan_mode == _TRUE &&
9321 pwrctl->wowlan_in_resume == _FALSE) {
9322 rtw_hal_set_wow_fw_rsvd_page(adapter, ReservedPagePacket,
9323 BufIndex, TxDescLen, PageSize,
9324 &TotalPageNum, &TotalPacketLen, &RsvdPageLoc);
9325 }
9326 #endif /* CONFIG_WOWLAN */
9327
9328 #ifdef CONFIG_P2P_WOWLAN
9329 if (_TRUE == pwrctl->wowlan_p2p_mode) {
9330 rtw_hal_set_p2p_wow_fw_rsvd_page(adapter, ReservedPagePacket,
9331 BufIndex, TxDescLen, PageSize,
9332 &TotalPageNum, &TotalPacketLen, &RsvdPageLoc);
9333 }
9334 #endif /* CONFIG_P2P_WOWLAN */
9335
9336 #ifdef CONFIG_LPS_PG
9337 /* must reserved last 1 x page for LPS PG Info*/
9338 pwrctl->lpspg_rsvd_page_locate = TotalPageNum;
9339 pwrctl->blpspg_info_up = _TRUE;
9340 if (page_num)
9341 TotalPageNum += LPS_PG_INFO_RSVD_PAGE_NUM;
9342 #endif
9343
9344 download_page:
9345 if (page_num) {
9346 *page_num = TotalPageNum;
9347 rtw_mfree(ReservedPagePacket, MAX_CMDBUF_SZ);
9348 ReservedPagePacket = NULL;
9349 return;
9350 }
9351
9352 /* RTW_INFO("%s BufIndex(%d), TxDescLen(%d), PageSize(%d)\n",__func__, BufIndex, TxDescLen, PageSize);*/
9353 RTW_INFO("%s PageNum(%d), pktlen(%d)\n",
9354 __func__, TotalPageNum, TotalPacketLen);
9355
9356 #ifdef CONFIG_LPS_PG
9357 if ((TotalPacketLen + (LPS_PG_INFO_RSVD_PAGE_NUM * PageSize)) > MaxRsvdPageBufSize) {
9358 pwrctl->lpspg_rsvd_page_locate = 0;
9359 pwrctl->blpspg_info_up = _FALSE;
9360
9361 RTW_ERR("%s rsvd page size is not enough!!TotalPacketLen+LPS_PG_INFO_LEN %d, MaxRsvdPageBufSize %d\n",
9362 __func__, (TotalPacketLen + (LPS_PG_INFO_RSVD_PAGE_NUM * PageSize)), MaxRsvdPageBufSize);
9363 rtw_warn_on(1);
9364 }
9365 #endif
9366
9367 if (TotalPacketLen > MaxRsvdPageBufSize) {
9368 RTW_ERR("%s(ERROR): rsvd page size is not enough!!TotalPacketLen %d, MaxRsvdPageBufSize %d\n",
9369 __FUNCTION__, TotalPacketLen, MaxRsvdPageBufSize);
9370 rtw_warn_on(1);
9371 goto error;
9372 } else {
9373 /* update attribute */
9374 pattrib = &pcmdframe->attrib;
9375 update_mgntframe_attrib(adapter, pattrib);
9376 pattrib->qsel = QSLT_BEACON;
9377 pattrib->pktlen = TotalPacketLen - TxDescOffset;
9378 pattrib->last_txcmdsz = TotalPacketLen - TxDescOffset;
9379 #ifdef CONFIG_PCI_HCI
9380 dump_mgntframe(adapter, pcmdframe);
9381 #else
9382 dump_mgntframe_and_wait(adapter, pcmdframe, 100);
9383 #endif
9384 }
9385
9386 RTW_INFO("%s: Set RSVD page location to Fw ,TotalPacketLen(%d), TotalPageNum(%d)\n",
9387 __func__, TotalPacketLen, TotalPageNum);
9388 #ifdef DBG_DUMP_SET_RSVD_PAGE
9389 RTW_INFO(" ==================================================\n");
9390 RTW_INFO_DUMP("\n", ReservedPagePacket, TotalPacketLen);
9391 RTW_INFO(" ==================================================\n");
9392 #endif
9393 if (check_fwstate(pmlmepriv, _FW_LINKED) == _TRUE) {
9394 rtw_hal_set_FwRsvdPage_cmd(adapter, &RsvdPageLoc);
9395 #ifdef CONFIG_WOWLAN
9396 if (pwrctl->wowlan_mode == _TRUE &&
9397 pwrctl->wowlan_in_resume == _FALSE)
9398 rtw_hal_set_FwAoacRsvdPage_cmd(adapter, &RsvdPageLoc);
9399 #endif /* CONFIG_WOWLAN */
9400 #ifdef CONFIG_AP_WOWLAN
9401 if (pwrctl->wowlan_ap_mode == _TRUE)
9402 rtw_hal_set_ap_rsvdpage_loc_cmd(adapter, &RsvdPageLoc);
9403 #endif /* CONFIG_AP_WOWLAN */
9404 } else if (pwrctl->wowlan_pno_enable) {
9405 #ifdef CONFIG_PNO_SUPPORT
9406 rtw_hal_set_FwAoacRsvdPage_cmd(adapter, &RsvdPageLoc);
9407 if (pwrctl->wowlan_in_resume)
9408 rtw_hal_set_scan_offload_info_cmd(adapter,
9409 &RsvdPageLoc, 0);
9410 else
9411 rtw_hal_set_scan_offload_info_cmd(adapter,
9412 &RsvdPageLoc, 1);
9413 #endif /* CONFIG_PNO_SUPPORT */
9414 }
9415
9416 #ifdef CONFIG_P2P_WOWLAN
9417 if (_TRUE == pwrctl->wowlan_p2p_mode)
9418 rtw_hal_set_FwP2PRsvdPage_cmd(adapter, &RsvdPageLoc);
9419 #endif /* CONFIG_P2P_WOWLAN */
9420
9421 return;
9422 error:
9423 rtw_free_xmitframe(pxmitpriv, pcmdframe);
9424 }
9425
rtw_hal_set_fw_rsvd_page(struct _ADAPTER * adapter,bool finished)9426 void rtw_hal_set_fw_rsvd_page(struct _ADAPTER *adapter, bool finished)
9427 {
9428 _rtw_hal_set_fw_rsvd_page(adapter, finished, NULL);
9429 }
9430
9431 /**
9432 * rtw_hal_get_rsvd_page_num() - Get needed reserved page number
9433 * @adapter: struct _ADAPTER*
9434 *
9435 * Caculate needed reserved page number.
9436 * In different state would get different number, for example normal mode and
9437 * WOW mode would need different reserved page size.
9438 *
9439 * Return the number of reserved page which driver need.
9440 */
rtw_hal_get_rsvd_page_num(struct _ADAPTER * adapter)9441 u8 rtw_hal_get_rsvd_page_num(struct _ADAPTER *adapter)
9442 {
9443 u8 num = 0;
9444
9445
9446 _rtw_hal_set_fw_rsvd_page(adapter, _FALSE, &num);
9447
9448 return num;
9449 }
9450
hw_var_set_mlme_sitesurvey(_adapter * adapter,u8 variable,u8 * val)9451 static void hw_var_set_mlme_sitesurvey(_adapter *adapter, u8 variable, u8 *val)
9452 {
9453 struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
9454 HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
9455 u16 value_rxfltmap2;
9456 int i;
9457 _adapter *iface;
9458
9459 #ifdef DBG_IFACE_STATUS
9460 DBG_IFACE_STATUS_DUMP(adapter);
9461 #endif
9462
9463 #ifdef CONFIG_FIND_BEST_CHANNEL
9464 /* Receive all data frames */
9465 value_rxfltmap2 = 0xFFFF;
9466 #else
9467 /* not to receive data frame */
9468 value_rxfltmap2 = 0;
9469 #endif
9470
9471 if (*((u8 *)val)) { /* under sitesurvey */
9472 /*
9473 * 1. configure REG_RXFLTMAP2
9474 * 2. disable TSF update & buddy TSF update to avoid updating wrong TSF due to clear RCR_CBSSID_BCN
9475 * 3. config RCR to receive different BSSID BCN or probe rsp
9476 */
9477 rtw_write16(adapter, REG_RXFLTMAP2, value_rxfltmap2);
9478
9479 #ifdef CONFIG_MI_WITH_MBSSID_CAM
9480 /*do nothing~~*/
9481 #else
9482
9483 /* disable update TSF */
9484 for (i = 0; i < dvobj->iface_nums; i++) {
9485 iface = dvobj->padapters[i];
9486 if (!iface)
9487 continue;
9488
9489 if (rtw_linked_check(iface)
9490 && !MLME_IS_AP(iface) && !MLME_IS_MESH(iface)
9491 ) {
9492 if (iface->hw_port == HW_PORT1)
9493 rtw_write8(iface, REG_BCN_CTRL_1, rtw_read8(iface, REG_BCN_CTRL_1) | DIS_TSF_UDT);
9494 else
9495 rtw_write8(iface, REG_BCN_CTRL, rtw_read8(iface, REG_BCN_CTRL) | DIS_TSF_UDT);
9496
9497 iface->mlmeextpriv.en_hw_update_tsf = _FALSE;
9498 }
9499 }
9500 #endif /* CONFIG_MI_WITH_MBSSID_CAM */
9501
9502 rtw_hal_rcr_set_chk_bssid(adapter, MLME_SCAN_ENTER);
9503
9504 /* Save orignal RRSR setting. needed? */
9505 hal_data->RegRRSR = rtw_read16(adapter, REG_RRSR);
9506
9507 #if defined(CONFIG_BEAMFORMING) && (defined(CONFIG_RTL8812A) || defined(CONFIG_RTL8821A))
9508 if (IS_8812_SERIES(hal_data->version_id) || IS_8821_SERIES(hal_data->version_id)) {
9509 /* set 718[1:0]=2'b00 to avoid BF scan hang */
9510 hal_data->backup_snd_ptcl_ctrl = rtw_read8(adapter, REG_SND_PTCL_CTRL_8812A);
9511 rtw_write8(adapter, REG_SND_PTCL_CTRL_8812A, (hal_data->backup_snd_ptcl_ctrl & 0xfc));
9512 }
9513 #endif
9514
9515 if (rtw_mi_get_ap_num(adapter) || rtw_mi_get_mesh_num(adapter))
9516 StopTxBeacon(adapter);
9517 } else { /* sitesurvey done */
9518 /*
9519 * 1. enable rx data frame
9520 * 2. config RCR not to receive different BSSID BCN or probe rsp
9521 * 3. doesn't enable TSF update & buddy TSF right now to avoid HW conflict
9522 * so, we enable TSF update when rx first BCN after sitesurvey done
9523 */
9524 if (rtw_mi_check_fwstate(adapter, _FW_LINKED | WIFI_AP_STATE | WIFI_MESH_STATE)) {
9525 /* enable to rx data frame */
9526 rtw_write16(adapter, REG_RXFLTMAP2, 0xFFFF);
9527 }
9528
9529 rtw_hal_rcr_set_chk_bssid(adapter, MLME_SCAN_DONE);
9530
9531 #ifdef CONFIG_MI_WITH_MBSSID_CAM
9532 /*if ((rtw_mi_get_assoced_sta_num(adapter) == 1) && (!rtw_mi_check_status(adapter, MI_AP_MODE)))
9533 rtw_write8(adapter, REG_BCN_CTRL, rtw_read8(adapter, REG_BCN_CTRL)&(~DIS_TSF_UDT));*/
9534 #else
9535
9536 for (i = 0; i < dvobj->iface_nums; i++) {
9537 iface = dvobj->padapters[i];
9538 if (!iface)
9539 continue;
9540 if (rtw_linked_check(iface)
9541 && !MLME_IS_AP(iface) && !MLME_IS_MESH(iface)
9542 ) {
9543 /* enable HW TSF update when recive beacon*/
9544 /*if (iface->hw_port == HW_PORT1)
9545 rtw_write8(iface, REG_BCN_CTRL_1, rtw_read8(iface, REG_BCN_CTRL_1)&(~(DIS_TSF_UDT)));
9546 else
9547 rtw_write8(iface, REG_BCN_CTRL, rtw_read8(iface, REG_BCN_CTRL)&(~(DIS_TSF_UDT)));
9548 */
9549 iface->mlmeextpriv.en_hw_update_tsf = _TRUE;
9550 }
9551 }
9552 #endif /* CONFIG_MI_WITH_MBSSID_CAM */
9553
9554 /* Restore orignal RRSR setting. needed? */
9555 rtw_write16(adapter, REG_RRSR, hal_data->RegRRSR);
9556
9557 #if defined(CONFIG_BEAMFORMING) && (defined(CONFIG_RTL8812A) || defined(CONFIG_RTL8821A))
9558 if (IS_8812_SERIES(hal_data->version_id) || IS_8821_SERIES(hal_data->version_id)) {
9559 /* Restore orignal 0x718 setting*/
9560 rtw_write8(adapter, REG_SND_PTCL_CTRL_8812A, hal_data->backup_snd_ptcl_ctrl);
9561 }
9562 #endif
9563
9564 if (rtw_mi_get_ap_num(adapter) || rtw_mi_get_mesh_num(adapter)) {
9565 ResumeTxBeacon(adapter);
9566 rtw_mi_tx_beacon_hdl(adapter);
9567 }
9568 }
9569 }
9570
9571 #ifdef CONFIG_TSF_RESET_OFFLOAD
rtw_hal_h2c_reset_tsf(_adapter * adapter,u8 reset_port)9572 static int rtw_hal_h2c_reset_tsf(_adapter *adapter, u8 reset_port)
9573 {
9574 u8 buf[2];
9575 int ret;
9576
9577 if (reset_port == HW_PORT0) {
9578 buf[0] = 0x1;
9579 buf[1] = 0;
9580 } else {
9581 buf[0] = 0x0;
9582 buf[1] = 0x1;
9583 }
9584
9585 ret = rtw_hal_fill_h2c_cmd(adapter, H2C_RESET_TSF, 2, buf);
9586
9587 return ret;
9588 }
9589
rtw_hal_reset_tsf(_adapter * adapter,u8 reset_port)9590 int rtw_hal_reset_tsf(_adapter *adapter, u8 reset_port)
9591 {
9592 u8 reset_cnt_before = 0, reset_cnt_after = 0, loop_cnt = 0;
9593 u32 reg_reset_tsf_cnt = (reset_port == HW_PORT0) ?
9594 REG_FW_RESET_TSF_CNT_0 : REG_FW_RESET_TSF_CNT_1;
9595 int ret;
9596
9597 /* site survey will cause reset tsf fail */
9598 rtw_mi_buddy_scan_abort(adapter, _FALSE);
9599 reset_cnt_after = reset_cnt_before = rtw_read8(adapter, reg_reset_tsf_cnt);
9600 ret = rtw_hal_h2c_reset_tsf(adapter, reset_port);
9601 if (ret != _SUCCESS)
9602 return ret;
9603
9604 while ((reset_cnt_after == reset_cnt_before) && (loop_cnt < 10)) {
9605 rtw_msleep_os(100);
9606 loop_cnt++;
9607 reset_cnt_after = rtw_read8(adapter, reg_reset_tsf_cnt);
9608 }
9609
9610 return (loop_cnt >= 10) ? _FAIL : _SUCCESS;
9611 }
9612 #endif /* CONFIG_TSF_RESET_OFFLOAD */
9613
rtw_hal_set_hw_update_tsf(PADAPTER padapter)9614 static void rtw_hal_set_hw_update_tsf(PADAPTER padapter)
9615 {
9616 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
9617 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
9618
9619 #if defined(CONFIG_RTL8822B) || defined(CONFIG_MI_WITH_MBSSID_CAM)
9620 RTW_INFO("[Warn] %s "ADPT_FMT" enter func\n", __func__, ADPT_ARG(padapter));
9621 rtw_warn_on(1);
9622 return;
9623 #endif
9624
9625 if (!pmlmeext->en_hw_update_tsf)
9626 return;
9627
9628 /* check RCR */
9629 if (!rtw_hal_rcr_check(padapter, RCR_CBSSID_BCN))
9630 return;
9631
9632 /* enable hw update tsf function for non-AP and non-Mesh */
9633 if (rtw_linked_check(padapter)
9634 && !MLME_IS_AP(padapter) && !MLME_IS_MESH(padapter)
9635 ) {
9636 #ifdef CONFIG_CONCURRENT_MODE
9637 if (padapter->hw_port == HW_PORT1)
9638 rtw_write8(padapter, REG_BCN_CTRL_1, rtw_read8(padapter, REG_BCN_CTRL_1) & (~DIS_TSF_UDT));
9639 else
9640 #endif
9641 rtw_write8(padapter, REG_BCN_CTRL, rtw_read8(padapter, REG_BCN_CTRL) & (~DIS_TSF_UDT));
9642 }
9643 pmlmeext->en_hw_update_tsf = _FALSE;
9644 }
9645
hw_var_set_correct_tsf(_adapter * adapter)9646 static void hw_var_set_correct_tsf(_adapter *adapter)
9647 {
9648 #ifdef CONFIG_MI_WITH_MBSSID_CAM
9649 /*do nothing*/
9650 #else
9651 u64 tsf;
9652 struct mlme_ext_priv *mlmeext = &adapter->mlmeextpriv;
9653 struct mlme_ext_info *mlmeinfo = &(mlmeext->mlmext_info);
9654
9655 tsf = mlmeext->TSFValue - rtw_modular64(mlmeext->TSFValue, (mlmeinfo->bcn_interval * 1024)) - 1024; /*us*/
9656
9657 if ((mlmeinfo->state & 0x03) == WIFI_FW_ADHOC_STATE
9658 || (mlmeinfo->state & 0x03) == WIFI_FW_AP_STATE)
9659 StopTxBeacon(adapter);
9660
9661 rtw_hal_correct_tsf(adapter, adapter->hw_port, tsf);
9662
9663 #ifdef CONFIG_CONCURRENT_MODE
9664 /* Update buddy port's TSF if it is SoftAP/Mesh for beacon TX issue! */
9665 if ((mlmeinfo->state & 0x03) == WIFI_FW_STATION_STATE
9666 && (rtw_mi_get_ap_num(adapter) || rtw_mi_get_mesh_num(adapter))
9667 ) {
9668 struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
9669 int i;
9670 _adapter *iface;
9671
9672 for (i = 0; i < dvobj->iface_nums; i++) {
9673 iface = dvobj->padapters[i];
9674 if (!iface)
9675 continue;
9676 if (iface == adapter)
9677 continue;
9678
9679 if ((MLME_IS_AP(iface) || MLME_IS_MESH(iface))
9680 && check_fwstate(&iface->mlmepriv, WIFI_ASOC_STATE) == _TRUE
9681 ) {
9682 rtw_hal_correct_tsf(iface, iface->hw_port, tsf);
9683 #ifdef CONFIG_TSF_RESET_OFFLOAD
9684 if (rtw_hal_reset_tsf(iface, iface->hw_port) == _FAIL)
9685 RTW_INFO("%s-[ERROR] "ADPT_FMT" Reset port%d TSF fail\n"
9686 , __func__, ADPT_ARG(iface), iface->hw_port);
9687 #endif /* CONFIG_TSF_RESET_OFFLOAD*/
9688 }
9689 }
9690 }
9691 #endif /* CONFIG_CONCURRENT_MODE */
9692
9693 if ((mlmeinfo->state & 0x03) == WIFI_FW_ADHOC_STATE
9694 || (mlmeinfo->state & 0x03) == WIFI_FW_AP_STATE)
9695 ResumeTxBeacon(adapter);
9696
9697 #endif /*CONFIG_MI_WITH_MBSSID_CAM*/
9698 }
9699
9700 #ifdef CONFIG_TDLS
9701 #ifdef CONFIG_TDLS_CH_SW
rtw_hal_ch_sw_oper_offload(_adapter * padapter,u8 channel,u8 channel_offset,u16 bwmode)9702 s32 rtw_hal_ch_sw_oper_offload(_adapter *padapter, u8 channel, u8 channel_offset, u16 bwmode)
9703 {
9704 PHAL_DATA_TYPE pHalData = GET_HAL_DATA(padapter);
9705 u8 ch_sw_h2c_buf[4] = {0x00, 0x00, 0x00, 0x00};
9706
9707
9708 SET_H2CCMD_CH_SW_OPER_OFFLOAD_CH_NUM(ch_sw_h2c_buf, channel);
9709 SET_H2CCMD_CH_SW_OPER_OFFLOAD_BW_MODE(ch_sw_h2c_buf, bwmode);
9710 switch (bwmode) {
9711 case CHANNEL_WIDTH_40:
9712 SET_H2CCMD_CH_SW_OPER_OFFLOAD_BW_40M_SC(ch_sw_h2c_buf, channel_offset);
9713 break;
9714 case CHANNEL_WIDTH_80:
9715 SET_H2CCMD_CH_SW_OPER_OFFLOAD_BW_80M_SC(ch_sw_h2c_buf, channel_offset);
9716 break;
9717 case CHANNEL_WIDTH_20:
9718 default:
9719 break;
9720 }
9721 SET_H2CCMD_CH_SW_OPER_OFFLOAD_RFE_TYPE(ch_sw_h2c_buf, pHalData->rfe_type);
9722
9723 return rtw_hal_fill_h2c_cmd(padapter, H2C_CHNL_SWITCH_OPER_OFFLOAD, sizeof(ch_sw_h2c_buf), ch_sw_h2c_buf);
9724 }
9725 #endif
9726 #endif
9727
9728 #ifdef CONFIG_WMMPS_STA
rtw_hal_update_uapsd_tid(_adapter * adapter)9729 void rtw_hal_update_uapsd_tid(_adapter *adapter)
9730 {
9731 struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
9732 struct qos_priv *pqospriv = &pmlmepriv->qospriv;
9733
9734 /* write complement of pqospriv->uapsd_tid to mac register 0x693 because
9735 it's designed for "0" represents "enable" and "1" represents "disable" */
9736 rtw_write8(adapter, REG_WMMPS_UAPSD_TID, (u8)(~pqospriv->uapsd_tid));
9737 }
9738 #endif /* CONFIG_WMMPS_STA */
9739
9740 #if defined(CONFIG_BT_COEXIST) && defined(CONFIG_FW_MULTI_PORT_SUPPORT)
9741 /* For multi-port support, driver needs to inform the port ID to FW for btc operations */
rtw_hal_set_wifi_port_id_cmd(_adapter * adapter)9742 s32 rtw_hal_set_wifi_port_id_cmd(_adapter *adapter)
9743 {
9744 u8 port_id = 0;
9745 u8 h2c_buf[H2C_BTC_WL_PORT_ID_LEN] = {0};
9746
9747 SET_H2CCMD_BTC_WL_PORT_ID(h2c_buf, adapter->hw_port);
9748 return rtw_hal_fill_h2c_cmd(adapter, H2C_BTC_WL_PORT_ID, H2C_BTC_WL_PORT_ID_LEN, h2c_buf);
9749 }
9750 #endif
9751
SetHwReg(_adapter * adapter,u8 variable,u8 * val)9752 u8 SetHwReg(_adapter *adapter, u8 variable, u8 *val)
9753 {
9754 HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
9755 u8 ret = _SUCCESS;
9756
9757 switch (variable) {
9758 case HW_VAR_MEDIA_STATUS: {
9759 u8 net_type = *((u8 *)val);
9760
9761 rtw_hal_set_msr(adapter, net_type);
9762 }
9763 break;
9764 case HW_VAR_MAC_ADDR:
9765 #ifdef CONFIG_MI_WITH_MBSSID_CAM
9766 rtw_hal_set_macaddr_mbid(adapter, val);
9767 #else
9768 rtw_hal_set_macaddr_port(adapter, val);
9769 #endif
9770 break;
9771 case HW_VAR_BSSID:
9772 rtw_hal_set_bssid(adapter, val);
9773 break;
9774 case HW_VAR_RCR:
9775 ret = hw_var_rcr_config(adapter, *((u32 *)val));
9776 break;
9777 case HW_VAR_ON_RCR_AM:
9778 hw_var_set_rcr_am(adapter, 1);
9779 break;
9780 case HW_VAR_OFF_RCR_AM:
9781 hw_var_set_rcr_am(adapter, 0);
9782 break;
9783 case HW_VAR_BEACON_INTERVAL:
9784 hw_var_set_bcn_interval(adapter, *(u16 *)val);
9785 break;
9786 #ifdef CONFIG_MBSSID_CAM
9787 case HW_VAR_MBSSID_CAM_WRITE: {
9788 u32 cmd = 0;
9789 u32 *cam_val = (u32 *)val;
9790
9791 rtw_write32(adapter, REG_MBIDCAMCFG_1, cam_val[0]);
9792 cmd = BIT_MBIDCAM_POLL | BIT_MBIDCAM_WT_EN | BIT_MBIDCAM_VALID | cam_val[1];
9793 rtw_write32(adapter, REG_MBIDCAMCFG_2, cmd);
9794 }
9795 break;
9796 case HW_VAR_MBSSID_CAM_CLEAR: {
9797 u32 cmd;
9798 u8 entry_id = *(u8 *)val;
9799
9800 rtw_write32(adapter, REG_MBIDCAMCFG_1, 0);
9801
9802 cmd = BIT_MBIDCAM_POLL | BIT_MBIDCAM_WT_EN | ((entry_id & MBIDCAM_ADDR_MASK) << MBIDCAM_ADDR_SHIFT);
9803 rtw_write32(adapter, REG_MBIDCAMCFG_2, cmd);
9804 }
9805 break;
9806 case HW_VAR_RCR_MBSSID_EN:
9807 if (*((u8 *)val))
9808 rtw_hal_rcr_add(adapter, RCR_ENMBID);
9809 else
9810 rtw_hal_rcr_clear(adapter, RCR_ENMBID);
9811 break;
9812 #endif
9813 case HW_VAR_PORT_SWITCH:
9814 hw_var_port_switch(adapter);
9815 break;
9816 case HW_VAR_INIT_RTS_RATE: {
9817 u16 brate_cfg = *((u16 *)val);
9818 u8 rate_index = 0;
9819 HAL_VERSION *hal_ver = &hal_data->version_id;
9820
9821 if (IS_8188E(*hal_ver)) {
9822
9823 while (brate_cfg > 0x1) {
9824 brate_cfg = (brate_cfg >> 1);
9825 rate_index++;
9826 }
9827 rtw_write8(adapter, REG_INIRTS_RATE_SEL, rate_index);
9828 } else
9829 rtw_warn_on(1);
9830 }
9831 break;
9832 case HW_VAR_SEC_CFG: {
9833 u16 reg_scr_ori;
9834 u16 reg_scr;
9835
9836 reg_scr = reg_scr_ori = rtw_read16(adapter, REG_SECCFG);
9837 reg_scr |= (SCR_CHK_KEYID | SCR_RxDecEnable | SCR_TxEncEnable);
9838
9839 if (_rtw_camctl_chk_cap(adapter, SEC_CAP_CHK_BMC))
9840 reg_scr |= SCR_CHK_BMC;
9841
9842 if (_rtw_camctl_chk_flags(adapter, SEC_STATUS_STA_PK_GK_CONFLICT_DIS_BMC_SEARCH))
9843 reg_scr |= SCR_NoSKMC;
9844
9845 if (reg_scr != reg_scr_ori)
9846 rtw_write16(adapter, REG_SECCFG, reg_scr);
9847 }
9848 break;
9849 case HW_VAR_SEC_DK_CFG: {
9850 struct security_priv *sec = &adapter->securitypriv;
9851 u8 reg_scr = rtw_read8(adapter, REG_SECCFG);
9852
9853 if (val) { /* Enable default key related setting */
9854 reg_scr |= SCR_TXBCUSEDK;
9855 if (sec->dot11AuthAlgrthm != dot11AuthAlgrthm_8021X)
9856 reg_scr |= (SCR_RxUseDK | SCR_TxUseDK);
9857 } else /* Disable default key related setting */
9858 reg_scr &= ~(SCR_RXBCUSEDK | SCR_TXBCUSEDK | SCR_RxUseDK | SCR_TxUseDK);
9859
9860 rtw_write8(adapter, REG_SECCFG, reg_scr);
9861 }
9862 break;
9863
9864 case HW_VAR_ASIX_IOT:
9865 /* enable ASIX IOT function */
9866 if (*((u8 *)val) == _TRUE) {
9867 /* 0xa2e[0]=0 (disable rake receiver) */
9868 rtw_write8(adapter, rCCK0_FalseAlarmReport + 2,
9869 rtw_read8(adapter, rCCK0_FalseAlarmReport + 2) & ~(BIT0));
9870 /* 0xa1c=0xa0 (reset channel estimation if signal quality is bad) */
9871 rtw_write8(adapter, rCCK0_DSPParameter2, 0xa0);
9872 } else {
9873 /* restore reg:0xa2e, reg:0xa1c */
9874 rtw_write8(adapter, rCCK0_FalseAlarmReport + 2,
9875 rtw_read8(adapter, rCCK0_FalseAlarmReport + 2) | (BIT0));
9876 rtw_write8(adapter, rCCK0_DSPParameter2, 0x00);
9877 }
9878 break;
9879 #if defined(CONFIG_WOWLAN) || defined(CONFIG_AP_WOWLAN)
9880 case HW_VAR_WOWLAN: {
9881 struct wowlan_ioctl_param *poidparam;
9882
9883 poidparam = (struct wowlan_ioctl_param *)val;
9884 switch (poidparam->subcode) {
9885 #ifdef CONFIG_WOWLAN
9886 case WOWLAN_PATTERN_CLEAN:
9887 rtw_hal_dl_pattern(adapter, 2);
9888 break;
9889 case WOWLAN_ENABLE:
9890 rtw_hal_wow_enable(adapter);
9891 break;
9892 case WOWLAN_DISABLE:
9893 rtw_hal_wow_disable(adapter);
9894 break;
9895 #endif /*CONFIG_WOWLAN*/
9896 #ifdef CONFIG_AP_WOWLAN
9897 case WOWLAN_AP_ENABLE:
9898 rtw_hal_ap_wow_enable(adapter);
9899 break;
9900 case WOWLAN_AP_DISABLE:
9901 rtw_hal_ap_wow_disable(adapter);
9902 break;
9903 #endif /*CONFIG_AP_WOWLAN*/
9904 default:
9905 break;
9906 }
9907 }
9908 break;
9909 #endif /*defined(CONFIG_WOWLAN) || defined(CONFIG_AP_WOWLAN)*/
9910
9911 case HW_VAR_MLME_SITESURVEY:
9912 hw_var_set_mlme_sitesurvey(adapter, variable, val);
9913 #ifdef CONFIG_BT_COEXIST
9914 if (hal_data->EEPROMBluetoothCoexist == 1)
9915 rtw_btcoex_ScanNotify(adapter, *val ? _TRUE : _FALSE);
9916 #endif
9917 break;
9918
9919 case HW_VAR_EN_HW_UPDATE_TSF:
9920 rtw_hal_set_hw_update_tsf(adapter);
9921 break;
9922
9923 case HW_VAR_CORRECT_TSF:
9924 hw_var_set_correct_tsf(adapter);
9925 break;
9926
9927 case HW_VAR_APFM_ON_MAC:
9928 hal_data->bMacPwrCtrlOn = *val;
9929 RTW_INFO("%s: bMacPwrCtrlOn=%d\n", __func__, hal_data->bMacPwrCtrlOn);
9930 break;
9931 #ifdef CONFIG_WMMPS_STA
9932 case HW_VAR_UAPSD_TID:
9933 rtw_hal_update_uapsd_tid(adapter);
9934 break;
9935 #endif /* CONFIG_WMMPS_STA */
9936 #ifdef CONFIG_LPS_PG
9937 case HW_VAR_LPS_PG_HANDLE:
9938 rtw_hal_lps_pg_handler(adapter, *val);
9939 break;
9940 #endif
9941 #ifdef CONFIG_LPS_LCLK_WD_TIMER
9942 case HW_VAR_DM_IN_LPS_LCLK:
9943 rtw_phydm_wd_lps_lclk_hdl(adapter);
9944 break;
9945 #endif
9946 default:
9947 if (0)
9948 RTW_PRINT(FUNC_ADPT_FMT" variable(%d) not defined!\n",
9949 FUNC_ADPT_ARG(adapter), variable);
9950 ret = _FAIL;
9951 break;
9952 }
9953
9954 return ret;
9955 }
9956
GetHwReg(_adapter * adapter,u8 variable,u8 * val)9957 void GetHwReg(_adapter *adapter, u8 variable, u8 *val)
9958 {
9959 HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
9960
9961
9962 switch (variable) {
9963 case HW_VAR_MAC_ADDR:
9964 rtw_hal_get_macaddr_port(adapter, val);
9965 break;
9966 case HW_VAR_BASIC_RATE:
9967 *((u16 *)val) = hal_data->BasicRateSet;
9968 break;
9969 case HW_VAR_RF_TYPE:
9970 *((u8 *)val) = hal_data->rf_type;
9971 break;
9972 case HW_VAR_MEDIA_STATUS:
9973 rtw_hal_get_msr(adapter, val);
9974 break;
9975 case HW_VAR_DO_IQK:
9976 *val = hal_data->bNeedIQK;
9977 break;
9978 case HW_VAR_CH_SW_NEED_TO_TAKE_CARE_IQK_INFO:
9979 if (hal_is_band_support(adapter, BAND_ON_5G))
9980 *val = _TRUE;
9981 else
9982 *val = _FALSE;
9983 break;
9984 case HW_VAR_APFM_ON_MAC:
9985 *val = hal_data->bMacPwrCtrlOn;
9986 break;
9987 case HW_VAR_RCR:
9988 hw_var_rcr_get(adapter, (u32 *)val);
9989 break;
9990 case HW_VAR_FWLPS_RF_ON:
9991 /* When we halt NIC, we should check if FW LPS is leave. */
9992 if (rtw_is_surprise_removed(adapter)
9993 || (adapter_to_pwrctl(adapter)->rf_pwrstate == rf_off)
9994 ) {
9995 /*
9996 * If it is in HW/SW Radio OFF or IPS state,
9997 * we do not check Fw LPS Leave,
9998 * because Fw is unload.
9999 */
10000 *val = _TRUE;
10001 } else {
10002 u32 rcr = 0;
10003
10004 rtw_hal_get_hwreg(adapter, HW_VAR_RCR, (u8 *)&rcr);
10005 if (rcr & (RCR_UC_MD_EN | RCR_BC_MD_EN | RCR_TIM_PARSER_EN))
10006 *val = _FALSE;
10007 else
10008 *val = _TRUE;
10009 }
10010 break;
10011 default:
10012 if (0)
10013 RTW_PRINT(FUNC_ADPT_FMT" variable(%d) not defined!\n",
10014 FUNC_ADPT_ARG(adapter), variable);
10015 break;
10016 }
10017
10018 }
10019
_get_page_size(struct _ADAPTER * a)10020 static u32 _get_page_size(struct _ADAPTER *a)
10021 {
10022 #ifdef RTW_HALMAC
10023 struct dvobj_priv *d;
10024 u32 size = 0;
10025 int err = 0;
10026
10027
10028 d = adapter_to_dvobj(a);
10029
10030 err = rtw_halmac_get_page_size(d, &size);
10031 if (!err)
10032 return size;
10033
10034 RTW_WARN(FUNC_ADPT_FMT ": Fail to get Page size!!(err=%d)\n",
10035 FUNC_ADPT_ARG(a), err);
10036 #endif /* RTW_HALMAC */
10037
10038 return PAGE_SIZE_128;
10039 }
10040
10041 u8
SetHalDefVar(_adapter * adapter,HAL_DEF_VARIABLE variable,void * value)10042 SetHalDefVar(_adapter *adapter, HAL_DEF_VARIABLE variable, void *value)
10043 {
10044 HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
10045 u8 bResult = _SUCCESS;
10046
10047 switch (variable) {
10048
10049 case HAL_DEF_DBG_DUMP_RXPKT:
10050 hal_data->bDumpRxPkt = *((u8 *)value);
10051 break;
10052 case HAL_DEF_DBG_DUMP_TXPKT:
10053 hal_data->bDumpTxPkt = *((u8 *)value);
10054 break;
10055 case HAL_DEF_ANT_DETECT:
10056 hal_data->AntDetection = *((u8 *)value);
10057 break;
10058 case HAL_DEF_DBG_DIS_PWT:
10059 hal_data->bDisableTXPowerTraining = *((u8 *)value);
10060 break;
10061 default:
10062 RTW_PRINT("%s: [WARNING] HAL_DEF_VARIABLE(%d) not defined!\n", __FUNCTION__, variable);
10063 bResult = _FAIL;
10064 break;
10065 }
10066
10067 return bResult;
10068 }
10069
10070 #ifdef CONFIG_BEAMFORMING
rtw_hal_query_txbfer_rf_num(_adapter * adapter)10071 u8 rtw_hal_query_txbfer_rf_num(_adapter *adapter)
10072 {
10073 struct registry_priv *pregistrypriv = &adapter->registrypriv;
10074 HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
10075
10076 if ((pregistrypriv->beamformer_rf_num) && (IS_HARDWARE_TYPE_8814AE(adapter) || IS_HARDWARE_TYPE_8814AU(adapter) || IS_HARDWARE_TYPE_8822BU(adapter) || IS_HARDWARE_TYPE_8821C(adapter)))
10077 return pregistrypriv->beamformer_rf_num;
10078 else if (IS_HARDWARE_TYPE_8814AE(adapter)
10079 #if 0
10080 #if defined(CONFIG_USB_HCI)
10081 || (IS_HARDWARE_TYPE_8814AU(adapter) && (pUsbModeMech->CurUsbMode == 2 || pUsbModeMech->HubUsbMode == 2)) /* for USB3.0 */
10082 #endif
10083 #endif
10084 ) {
10085 /*BF cap provided by Yu Chen, Sean, 2015, 01 */
10086 if (hal_data->rf_type == RF_3T3R)
10087 return 2;
10088 else if (hal_data->rf_type == RF_4T4R)
10089 return 3;
10090 else
10091 return 1;
10092 } else
10093 return 1;
10094
10095 }
rtw_hal_query_txbfee_rf_num(_adapter * adapter)10096 u8 rtw_hal_query_txbfee_rf_num(_adapter *adapter)
10097 {
10098 struct registry_priv *pregistrypriv = &adapter->registrypriv;
10099 struct mlme_ext_priv *pmlmeext = &adapter->mlmeextpriv;
10100 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
10101
10102 HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
10103
10104 if ((pregistrypriv->beamformee_rf_num) && (IS_HARDWARE_TYPE_8814AE(adapter) || IS_HARDWARE_TYPE_8814AU(adapter) || IS_HARDWARE_TYPE_8822BU(adapter) || IS_HARDWARE_TYPE_8821C(adapter)))
10105 return pregistrypriv->beamformee_rf_num;
10106 else if (IS_HARDWARE_TYPE_8814AE(adapter) || IS_HARDWARE_TYPE_8814AU(adapter)) {
10107 if (pmlmeinfo->assoc_AP_vendor == HT_IOT_PEER_BROADCOM)
10108 return 2;
10109 else
10110 return 2;/*TODO: May be 3 in the future, by ChenYu. */
10111 } else
10112 return 1;
10113
10114 }
10115 #endif
10116
10117 u8
GetHalDefVar(_adapter * adapter,HAL_DEF_VARIABLE variable,void * value)10118 GetHalDefVar(_adapter *adapter, HAL_DEF_VARIABLE variable, void *value)
10119 {
10120 HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
10121 u8 bResult = _SUCCESS;
10122
10123 switch (variable) {
10124 case HAL_DEF_UNDERCORATEDSMOOTHEDPWDB: {
10125 struct mlme_priv *pmlmepriv;
10126 struct sta_priv *pstapriv;
10127 struct sta_info *psta;
10128
10129 pmlmepriv = &adapter->mlmepriv;
10130 pstapriv = &adapter->stapriv;
10131 psta = rtw_get_stainfo(pstapriv, pmlmepriv->cur_network.network.MacAddress);
10132 if (psta)
10133 *((int *)value) = psta->cmn.rssi_stat.rssi;
10134 }
10135 break;
10136 case HAL_DEF_DBG_DUMP_RXPKT:
10137 *((u8 *)value) = hal_data->bDumpRxPkt;
10138 break;
10139 case HAL_DEF_DBG_DUMP_TXPKT:
10140 *((u8 *)value) = hal_data->bDumpTxPkt;
10141 break;
10142 case HAL_DEF_ANT_DETECT:
10143 *((u8 *)value) = hal_data->AntDetection;
10144 break;
10145 case HAL_DEF_MACID_SLEEP:
10146 *(u8 *)value = _FALSE;
10147 break;
10148 case HAL_DEF_TX_PAGE_SIZE:
10149 *((u32 *)value) = _get_page_size(adapter);
10150 break;
10151 case HAL_DEF_DBG_DIS_PWT:
10152 *(u8 *)value = hal_data->bDisableTXPowerTraining;
10153 break;
10154 case HAL_DEF_EXPLICIT_BEAMFORMER:
10155 case HAL_DEF_EXPLICIT_BEAMFORMEE:
10156 case HAL_DEF_VHT_MU_BEAMFORMER:
10157 case HAL_DEF_VHT_MU_BEAMFORMEE:
10158 *(u8 *)value = _FALSE;
10159 break;
10160 #ifdef CONFIG_BEAMFORMING
10161 case HAL_DEF_BEAMFORMER_CAP:
10162 *(u8 *)value = rtw_hal_query_txbfer_rf_num(adapter);
10163 break;
10164 case HAL_DEF_BEAMFORMEE_CAP:
10165 *(u8 *)value = rtw_hal_query_txbfee_rf_num(adapter);
10166 break;
10167 #endif
10168 default:
10169 RTW_PRINT("%s: [WARNING] HAL_DEF_VARIABLE(%d) not defined!\n", __FUNCTION__, variable);
10170 bResult = _FAIL;
10171 break;
10172 }
10173
10174 return bResult;
10175 }
10176
10177
10178 BOOLEAN
eqNByte(u8 * str1,u8 * str2,u32 num)10179 eqNByte(
10180 u8 *str1,
10181 u8 *str2,
10182 u32 num
10183 )
10184 {
10185 if (num == 0)
10186 return _FALSE;
10187 while (num > 0) {
10188 num--;
10189 if (str1[num] != str2[num])
10190 return _FALSE;
10191 }
10192 return _TRUE;
10193 }
10194
10195 /*
10196 * Description:
10197 * Translate a character to hex digit.
10198 * */
10199 u32
MapCharToHexDigit(IN char chTmp)10200 MapCharToHexDigit(
10201 IN char chTmp
10202 )
10203 {
10204 if (chTmp >= '0' && chTmp <= '9')
10205 return chTmp - '0';
10206 else if (chTmp >= 'a' && chTmp <= 'f')
10207 return 10 + (chTmp - 'a');
10208 else if (chTmp >= 'A' && chTmp <= 'F')
10209 return 10 + (chTmp - 'A');
10210 else
10211 return 0;
10212 }
10213
10214
10215
10216 /*
10217 * Description:
10218 * Parse hex number from the string pucStr.
10219 * */
10220 BOOLEAN
GetHexValueFromString(IN char * szStr,IN OUT u32 * pu4bVal,IN OUT u32 * pu4bMove)10221 GetHexValueFromString(
10222 IN char *szStr,
10223 IN OUT u32 *pu4bVal,
10224 IN OUT u32 *pu4bMove
10225 )
10226 {
10227 char *szScan = szStr;
10228
10229 /* Check input parameter. */
10230 if (szStr == NULL || pu4bVal == NULL || pu4bMove == NULL) {
10231 RTW_INFO("GetHexValueFromString(): Invalid inpur argumetns! szStr: %p, pu4bVal: %p, pu4bMove: %p\n", szStr, pu4bVal, pu4bMove);
10232 return _FALSE;
10233 }
10234
10235 /* Initialize output. */
10236 *pu4bMove = 0;
10237 *pu4bVal = 0;
10238
10239 /* Skip leading space. */
10240 while (*szScan != '\0' &&
10241 (*szScan == ' ' || *szScan == '\t')) {
10242 szScan++;
10243 (*pu4bMove)++;
10244 }
10245
10246 /* Skip leading '0x' or '0X'. */
10247 if (*szScan == '0' && (*(szScan + 1) == 'x' || *(szScan + 1) == 'X')) {
10248 szScan += 2;
10249 (*pu4bMove) += 2;
10250 }
10251
10252 /* Check if szScan is now pointer to a character for hex digit, */
10253 /* if not, it means this is not a valid hex number. */
10254 if (!IsHexDigit(*szScan))
10255 return _FALSE;
10256
10257 /* Parse each digit. */
10258 do {
10259 (*pu4bVal) <<= 4;
10260 *pu4bVal += MapCharToHexDigit(*szScan);
10261
10262 szScan++;
10263 (*pu4bMove)++;
10264 } while (IsHexDigit(*szScan));
10265
10266 return _TRUE;
10267 }
10268
10269 BOOLEAN
GetFractionValueFromString(IN char * szStr,IN OUT u8 * pInteger,IN OUT u8 * pFraction,IN OUT u32 * pu4bMove)10270 GetFractionValueFromString(
10271 IN char *szStr,
10272 IN OUT u8 *pInteger,
10273 IN OUT u8 *pFraction,
10274 IN OUT u32 *pu4bMove
10275 )
10276 {
10277 char *szScan = szStr;
10278
10279 /* Initialize output. */
10280 *pu4bMove = 0;
10281 *pInteger = 0;
10282 *pFraction = 0;
10283
10284 /* Skip leading space. */
10285 while (*szScan != '\0' && (*szScan == ' ' || *szScan == '\t')) {
10286 ++szScan;
10287 ++(*pu4bMove);
10288 }
10289
10290 /* Parse each digit. */
10291 do {
10292 (*pInteger) *= 10;
10293 *pInteger += (*szScan - '0');
10294
10295 ++szScan;
10296 ++(*pu4bMove);
10297
10298 if (*szScan == '.') {
10299 ++szScan;
10300 ++(*pu4bMove);
10301
10302 if (*szScan < '0' || *szScan > '9')
10303 return _FALSE;
10304 else {
10305 *pFraction = *szScan - '0';
10306 ++szScan;
10307 ++(*pu4bMove);
10308 return _TRUE;
10309 }
10310 }
10311 } while (*szScan >= '0' && *szScan <= '9');
10312
10313 return _TRUE;
10314 }
10315
10316 /*
10317 * Description:
10318 * Return TRUE if szStr is comment out with leading " */ /* ".
10319 * */
10320 BOOLEAN
IsCommentString(IN char * szStr)10321 IsCommentString(
10322 IN char *szStr
10323 )
10324 {
10325 if (*szStr == '/' && *(szStr + 1) == '/')
10326 return _TRUE;
10327 else
10328 return _FALSE;
10329 }
10330
10331 BOOLEAN
GetU1ByteIntegerFromStringInDecimal(IN char * Str,IN OUT u8 * pInt)10332 GetU1ByteIntegerFromStringInDecimal(
10333 IN char *Str,
10334 IN OUT u8 *pInt
10335 )
10336 {
10337 u16 i = 0;
10338 *pInt = 0;
10339
10340 while (Str[i] != '\0') {
10341 if (Str[i] >= '0' && Str[i] <= '9') {
10342 *pInt *= 10;
10343 *pInt += (Str[i] - '0');
10344 } else
10345 return _FALSE;
10346 ++i;
10347 }
10348
10349 return _TRUE;
10350 }
10351
10352 /* <20121004, Kordan> For example,
10353 * ParseQualifiedString(inString, 0, outString, '[', ']') gets "Kordan" from a string "Hello [Kordan]".
10354 * If RightQualifier does not exist, it will hang on in the while loop */
10355 BOOLEAN
ParseQualifiedString(IN char * In,IN OUT u32 * Start,OUT char * Out,IN char LeftQualifier,IN char RightQualifier)10356 ParseQualifiedString(
10357 IN char *In,
10358 IN OUT u32 *Start,
10359 OUT char *Out,
10360 IN char LeftQualifier,
10361 IN char RightQualifier
10362 )
10363 {
10364 u32 i = 0, j = 0;
10365 char c = In[(*Start)++];
10366
10367 if (c != LeftQualifier)
10368 return _FALSE;
10369
10370 i = (*Start);
10371 c = In[(*Start)++];
10372 while (c != RightQualifier && c != '\0')
10373 c = In[(*Start)++];
10374
10375 if (c == '\0')
10376 return _FALSE;
10377
10378 j = (*Start) - 2;
10379 strncpy((char *)Out, (const char *)(In + i), j - i + 1);
10380
10381 return _TRUE;
10382 }
10383
10384 BOOLEAN
isAllSpaceOrTab(u8 * data,u8 size)10385 isAllSpaceOrTab(
10386 u8 *data,
10387 u8 size
10388 )
10389 {
10390 u8 cnt = 0, NumOfSpaceAndTab = 0;
10391
10392 while (size > cnt) {
10393 if (data[cnt] == ' ' || data[cnt] == '\t' || data[cnt] == '\0')
10394 ++NumOfSpaceAndTab;
10395
10396 ++cnt;
10397 }
10398
10399 return size == NumOfSpaceAndTab;
10400 }
10401
10402
rtw_hal_check_rxfifo_full(_adapter * adapter)10403 void rtw_hal_check_rxfifo_full(_adapter *adapter)
10404 {
10405 struct dvobj_priv *psdpriv = adapter->dvobj;
10406 struct debug_priv *pdbgpriv = &psdpriv->drv_dbg;
10407 HAL_DATA_TYPE *pHalData = GET_HAL_DATA(adapter);
10408 struct registry_priv *regsty = &adapter->registrypriv;
10409 int save_cnt = _FALSE;
10410
10411 if (regsty->check_hw_status == 1) {
10412 /* switch counter to RX fifo */
10413 if (IS_8188E(pHalData->version_id) ||
10414 IS_8188F(pHalData->version_id) ||
10415 IS_8812_SERIES(pHalData->version_id) ||
10416 IS_8821_SERIES(pHalData->version_id) ||
10417 IS_8723B_SERIES(pHalData->version_id) ||
10418 IS_8192E(pHalData->version_id) ||
10419 IS_8703B_SERIES(pHalData->version_id) ||
10420 IS_8723D_SERIES(pHalData->version_id)) {
10421 rtw_write8(adapter, REG_RXERR_RPT + 3, rtw_read8(adapter, REG_RXERR_RPT + 3) | 0xa0);
10422 save_cnt = _TRUE;
10423 } else {
10424 /* todo: other chips */
10425 }
10426
10427
10428 if (save_cnt) {
10429 pdbgpriv->dbg_rx_fifo_last_overflow = pdbgpriv->dbg_rx_fifo_curr_overflow;
10430 pdbgpriv->dbg_rx_fifo_curr_overflow = rtw_read16(adapter, REG_RXERR_RPT);
10431 pdbgpriv->dbg_rx_fifo_diff_overflow = pdbgpriv->dbg_rx_fifo_curr_overflow - pdbgpriv->dbg_rx_fifo_last_overflow;
10432 } else {
10433 /* special value to indicate no implementation */
10434 pdbgpriv->dbg_rx_fifo_last_overflow = 1;
10435 pdbgpriv->dbg_rx_fifo_curr_overflow = 1;
10436 pdbgpriv->dbg_rx_fifo_diff_overflow = 1;
10437 }
10438 }
10439 }
10440
linked_info_dump(_adapter * padapter,u8 benable)10441 void linked_info_dump(_adapter *padapter, u8 benable)
10442 {
10443 struct pwrctrl_priv *pwrctrlpriv = adapter_to_pwrctl(padapter);
10444
10445 if (padapter->bLinkInfoDump == benable)
10446 return;
10447
10448 RTW_INFO("%s %s\n", __FUNCTION__, (benable) ? "enable" : "disable");
10449
10450 if (benable) {
10451 #ifdef CONFIG_LPS
10452 pwrctrlpriv->org_power_mgnt = pwrctrlpriv->power_mgnt;/* keep org value */
10453 rtw_pm_set_lps(padapter, PS_MODE_ACTIVE);
10454 #endif
10455
10456 #ifdef CONFIG_IPS
10457 pwrctrlpriv->ips_org_mode = pwrctrlpriv->ips_mode;/* keep org value */
10458 rtw_pm_set_ips(padapter, IPS_NONE);
10459 #endif
10460 } else {
10461 #ifdef CONFIG_IPS
10462 rtw_pm_set_ips(padapter, pwrctrlpriv->ips_org_mode);
10463 #endif /* CONFIG_IPS */
10464
10465 #ifdef CONFIG_LPS
10466 rtw_pm_set_lps(padapter, pwrctrlpriv->org_power_mgnt);
10467 #endif /* CONFIG_LPS */
10468 }
10469 padapter->bLinkInfoDump = benable ;
10470 }
10471
10472 #ifdef DBG_RX_SIGNAL_DISPLAY_RAW_DATA
rtw_get_raw_rssi_info(void * sel,_adapter * padapter)10473 void rtw_get_raw_rssi_info(void *sel, _adapter *padapter)
10474 {
10475 u8 isCCKrate, rf_path;
10476 PHAL_DATA_TYPE pHalData = GET_HAL_DATA(padapter);
10477 struct rx_raw_rssi *psample_pkt_rssi = &padapter->recvpriv.raw_rssi_info;
10478 RTW_PRINT_SEL(sel, "RxRate = %s, PWDBALL = %d(%%), rx_pwr_all = %d(dBm)\n",
10479 HDATA_RATE(psample_pkt_rssi->data_rate), psample_pkt_rssi->pwdball, psample_pkt_rssi->pwr_all);
10480 isCCKrate = (psample_pkt_rssi->data_rate <= DESC_RATE11M) ? TRUE : FALSE;
10481
10482 if (isCCKrate)
10483 psample_pkt_rssi->mimo_signal_strength[0] = psample_pkt_rssi->pwdball;
10484
10485 for (rf_path = 0; rf_path < pHalData->NumTotalRFPath; rf_path++) {
10486 RTW_PRINT_SEL(sel, "RF_PATH_%d=>signal_strength:%d(%%),signal_quality:%d(%%)\n"
10487 , rf_path, psample_pkt_rssi->mimo_signal_strength[rf_path], psample_pkt_rssi->mimo_signal_quality[rf_path]);
10488
10489 if (!isCCKrate) {
10490 RTW_PRINT_SEL(sel, "\trx_ofdm_pwr:%d(dBm),rx_ofdm_snr:%d(dB)\n",
10491 psample_pkt_rssi->ofdm_pwr[rf_path], psample_pkt_rssi->ofdm_snr[rf_path]);
10492 }
10493 }
10494 }
10495
rtw_dump_raw_rssi_info(_adapter * padapter,void * sel)10496 void rtw_dump_raw_rssi_info(_adapter *padapter, void *sel)
10497 {
10498 u8 isCCKrate, rf_path;
10499 PHAL_DATA_TYPE pHalData = GET_HAL_DATA(padapter);
10500 struct rx_raw_rssi *psample_pkt_rssi = &padapter->recvpriv.raw_rssi_info;
10501 _RTW_PRINT_SEL(sel, "============ RAW Rx Info dump ===================\n");
10502 _RTW_PRINT_SEL(sel, "RxRate = %s, PWDBALL = %d(%%), rx_pwr_all = %d(dBm)\n", HDATA_RATE(psample_pkt_rssi->data_rate), psample_pkt_rssi->pwdball, psample_pkt_rssi->pwr_all);
10503
10504 isCCKrate = (psample_pkt_rssi->data_rate <= DESC_RATE11M) ? TRUE : FALSE;
10505
10506 if (isCCKrate)
10507 psample_pkt_rssi->mimo_signal_strength[0] = psample_pkt_rssi->pwdball;
10508
10509 for (rf_path = 0; rf_path < pHalData->NumTotalRFPath; rf_path++) {
10510 _RTW_PRINT_SEL(sel , "RF_PATH_%d=>signal_strength:%d(%%),signal_quality:%d(%%)"
10511 , rf_path, psample_pkt_rssi->mimo_signal_strength[rf_path], psample_pkt_rssi->mimo_signal_quality[rf_path]);
10512
10513 if (!isCCKrate)
10514 _RTW_PRINT_SEL(sel , ",rx_ofdm_pwr:%d(dBm),rx_ofdm_snr:%d(dB)\n", psample_pkt_rssi->ofdm_pwr[rf_path], psample_pkt_rssi->ofdm_snr[rf_path]);
10515 else
10516 _RTW_PRINT_SEL(sel , "\n");
10517
10518 }
10519 }
10520 #endif
10521
10522 #ifdef DBG_RX_DFRAME_RAW_DATA
rtw_dump_rx_dframe_info(_adapter * padapter,void * sel)10523 void rtw_dump_rx_dframe_info(_adapter *padapter, void *sel)
10524 {
10525 _irqL irqL;
10526 u8 isCCKrate, rf_path;
10527 struct recv_priv *precvpriv = &(padapter->recvpriv);
10528 PHAL_DATA_TYPE pHalData = GET_HAL_DATA(padapter);
10529 struct sta_priv *pstapriv = &padapter->stapriv;
10530 struct sta_info *psta;
10531 struct sta_recv_dframe_info *psta_dframe_info;
10532 int i;
10533 _list *plist, *phead;
10534 char *BW;
10535 u8 bc_addr[6] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
10536 u8 null_addr[6] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
10537
10538 if (precvpriv->store_law_data_flag) {
10539
10540 _enter_critical_bh(&pstapriv->sta_hash_lock, &irqL);
10541
10542 for (i = 0; i < NUM_STA; i++) {
10543 phead = &(pstapriv->sta_hash[i]);
10544 plist = get_next(phead);
10545
10546 while ((rtw_end_of_queue_search(phead, plist)) == _FALSE) {
10547
10548 psta = LIST_CONTAINOR(plist, struct sta_info, hash_list);
10549 plist = get_next(plist);
10550
10551 if (psta) {
10552 psta_dframe_info = &psta->sta_dframe_info;
10553 if ((_rtw_memcmp(psta->cmn.mac_addr, bc_addr, 6) != _TRUE)
10554 && (_rtw_memcmp(psta->cmn.mac_addr, null_addr, 6) != _TRUE)
10555 && (_rtw_memcmp(psta->cmn.mac_addr, adapter_mac_addr(padapter), 6) != _TRUE)) {
10556
10557
10558 isCCKrate = (psta_dframe_info->sta_data_rate <= DESC_RATE11M) ? TRUE : FALSE;
10559
10560 switch (psta_dframe_info->sta_bw_mode) {
10561
10562 case CHANNEL_WIDTH_20:
10563 BW = "20M";
10564 break;
10565
10566 case CHANNEL_WIDTH_40:
10567 BW = "40M";
10568 break;
10569
10570 case CHANNEL_WIDTH_80:
10571 BW = "80M";
10572 break;
10573
10574 case CHANNEL_WIDTH_160:
10575 BW = "160M";
10576 break;
10577
10578 default:
10579 BW = "";
10580 break;
10581 }
10582
10583 RTW_PRINT_SEL(sel, "==============================\n");
10584 _RTW_PRINT_SEL(sel, "macaddr =" MAC_FMT "\n", MAC_ARG(psta->cmn.mac_addr));
10585 _RTW_PRINT_SEL(sel, "BW=%s, sgi =%d\n", BW, psta_dframe_info->sta_sgi);
10586 _RTW_PRINT_SEL(sel, "Rx_Data_Rate = %s\n", HDATA_RATE(psta_dframe_info->sta_data_rate));
10587
10588 for (rf_path = 0; rf_path < pHalData->NumTotalRFPath; rf_path++) {
10589
10590 if (!isCCKrate) {
10591
10592 _RTW_PRINT_SEL(sel , "RF_PATH_%d RSSI:%d(dBm)", rf_path, psta_dframe_info->sta_RxPwr[rf_path]);
10593 _RTW_PRINT_SEL(sel , ",rx_ofdm_snr:%d(dB)\n", psta_dframe_info->sta_ofdm_snr[rf_path]);
10594
10595 } else
10596
10597 _RTW_PRINT_SEL(sel , "RF_PATH_%d RSSI:%d(dBm)\n", rf_path, (psta_dframe_info->sta_mimo_signal_strength[rf_path]) - 100);
10598 }
10599 }
10600 }
10601 }
10602 }
10603 _exit_critical_bh(&pstapriv->sta_hash_lock, &irqL);
10604 }
10605 }
10606 #endif
rtw_store_phy_info(_adapter * padapter,union recv_frame * prframe)10607 void rtw_store_phy_info(_adapter *padapter, union recv_frame *prframe)
10608 {
10609 u8 isCCKrate, rf_path , dframe_type;
10610 u8 *ptr;
10611 u8 bc_addr[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
10612 #ifdef DBG_RX_DFRAME_RAW_DATA
10613 struct sta_recv_dframe_info *psta_dframe_info;
10614 #endif
10615 struct recv_priv *precvpriv = &(padapter->recvpriv);
10616 PHAL_DATA_TYPE pHalData = GET_HAL_DATA(padapter);
10617 struct rx_pkt_attrib *pattrib = &prframe->u.hdr.attrib;
10618 struct sta_info *psta = prframe->u.hdr.psta;
10619 struct phydm_phyinfo_struct *p_phy_info = &pattrib->phy_info;
10620 struct rx_raw_rssi *psample_pkt_rssi = &padapter->recvpriv.raw_rssi_info;
10621 psample_pkt_rssi->data_rate = pattrib->data_rate;
10622 ptr = prframe->u.hdr.rx_data;
10623 dframe_type = GetFrameType(ptr);
10624 /*RTW_INFO("=>%s\n", __FUNCTION__);*/
10625
10626
10627 if (precvpriv->store_law_data_flag) {
10628 isCCKrate = (pattrib->data_rate <= DESC_RATE11M) ? TRUE : FALSE;
10629
10630 psample_pkt_rssi->pwdball = p_phy_info->rx_pwdb_all;
10631 psample_pkt_rssi->pwr_all = p_phy_info->recv_signal_power;
10632
10633 for (rf_path = 0; rf_path < pHalData->NumTotalRFPath; rf_path++) {
10634 psample_pkt_rssi->mimo_signal_strength[rf_path] = p_phy_info->rx_mimo_signal_strength[rf_path];
10635 psample_pkt_rssi->mimo_signal_quality[rf_path] = p_phy_info->rx_mimo_signal_quality[rf_path];
10636 if (!isCCKrate) {
10637 psample_pkt_rssi->ofdm_pwr[rf_path] = p_phy_info->rx_pwr[rf_path];
10638 psample_pkt_rssi->ofdm_snr[rf_path] = p_phy_info->rx_snr[rf_path];
10639 }
10640 }
10641 #ifdef DBG_RX_DFRAME_RAW_DATA
10642 if ((dframe_type == WIFI_DATA_TYPE) || (dframe_type == WIFI_QOS_DATA_TYPE) || (padapter->registrypriv.mp_mode == 1)) {
10643
10644 /*RTW_INFO("=>%s WIFI_DATA_TYPE or WIFI_QOS_DATA_TYPE\n", __FUNCTION__);*/
10645 if (psta) {
10646 psta_dframe_info = &psta->sta_dframe_info;
10647 /*RTW_INFO("=>%s psta->cmn.mac_addr="MAC_FMT" !\n",
10648 __FUNCTION__, MAC_ARG(psta->cmn.mac_addr));*/
10649 if ((_rtw_memcmp(psta->cmn.mac_addr, bc_addr, ETH_ALEN) != _TRUE) || (padapter->registrypriv.mp_mode == 1)) {
10650 psta_dframe_info->sta_data_rate = pattrib->data_rate;
10651 psta_dframe_info->sta_sgi = pattrib->sgi;
10652 psta_dframe_info->sta_bw_mode = pattrib->bw;
10653 for (rf_path = 0; rf_path < pHalData->NumTotalRFPath; rf_path++) {
10654
10655 psta_dframe_info->sta_mimo_signal_strength[rf_path] = (p_phy_info->rx_mimo_signal_strength[rf_path]);/*Percentage to dbm*/
10656
10657 if (!isCCKrate) {
10658 psta_dframe_info->sta_ofdm_snr[rf_path] = p_phy_info->rx_snr[rf_path];
10659 psta_dframe_info->sta_RxPwr[rf_path] = p_phy_info->rx_pwr[rf_path];
10660 }
10661 }
10662 }
10663 }
10664 }
10665 #endif
10666 }
10667
10668 }
10669
10670
check_phy_efuse_tx_power_info_valid(PADAPTER padapter)10671 int check_phy_efuse_tx_power_info_valid(PADAPTER padapter)
10672 {
10673 PHAL_DATA_TYPE pHalData = GET_HAL_DATA(padapter);
10674 u8 *pContent = pHalData->efuse_eeprom_data;
10675 int index = 0;
10676 u16 tx_index_offset = 0x0000;
10677
10678 switch (rtw_get_chip_type(padapter)) {
10679 case RTL8723B:
10680 tx_index_offset = EEPROM_TX_PWR_INX_8723B;
10681 break;
10682 case RTL8703B:
10683 tx_index_offset = EEPROM_TX_PWR_INX_8703B;
10684 break;
10685 case RTL8723D:
10686 tx_index_offset = EEPROM_TX_PWR_INX_8723D;
10687 break;
10688 case RTL8188E:
10689 tx_index_offset = EEPROM_TX_PWR_INX_88E;
10690 break;
10691 case RTL8188F:
10692 tx_index_offset = EEPROM_TX_PWR_INX_8188F;
10693 break;
10694 case RTL8192E:
10695 tx_index_offset = EEPROM_TX_PWR_INX_8192E;
10696 break;
10697 case RTL8821:
10698 tx_index_offset = EEPROM_TX_PWR_INX_8821;
10699 break;
10700 case RTL8812:
10701 tx_index_offset = EEPROM_TX_PWR_INX_8812;
10702 break;
10703 case RTL8814A:
10704 tx_index_offset = EEPROM_TX_PWR_INX_8814;
10705 break;
10706 case RTL8822B:
10707 tx_index_offset = EEPROM_TX_PWR_INX_8822B;
10708 break;
10709 case RTL8821C:
10710 tx_index_offset = EEPROM_TX_PWR_INX_8821C;
10711 break;
10712 default:
10713 tx_index_offset = 0x0010;
10714 break;
10715 }
10716
10717 /* TODO: chacking length by ICs */
10718 for (index = 0 ; index < 11 ; index++) {
10719 if (pContent[tx_index_offset + index] == 0xFF)
10720 return _FALSE;
10721 }
10722 return _TRUE;
10723 }
10724
hal_efuse_macaddr_offset(_adapter * adapter)10725 int hal_efuse_macaddr_offset(_adapter *adapter)
10726 {
10727 u8 interface_type = 0;
10728 int addr_offset = -1;
10729
10730 interface_type = rtw_get_intf_type(adapter);
10731
10732 switch (rtw_get_chip_type(adapter)) {
10733 #ifdef CONFIG_RTL8723B
10734 case RTL8723B:
10735 if (interface_type == RTW_USB)
10736 addr_offset = EEPROM_MAC_ADDR_8723BU;
10737 else if (interface_type == RTW_SDIO)
10738 addr_offset = EEPROM_MAC_ADDR_8723BS;
10739 else if (interface_type == RTW_PCIE)
10740 addr_offset = EEPROM_MAC_ADDR_8723BE;
10741 break;
10742 #endif
10743 #ifdef CONFIG_RTL8703B
10744 case RTL8703B:
10745 if (interface_type == RTW_USB)
10746 addr_offset = EEPROM_MAC_ADDR_8703BU;
10747 else if (interface_type == RTW_SDIO)
10748 addr_offset = EEPROM_MAC_ADDR_8703BS;
10749 break;
10750 #endif
10751 #ifdef CONFIG_RTL8723D
10752 case RTL8723D:
10753 if (interface_type == RTW_USB)
10754 addr_offset = EEPROM_MAC_ADDR_8723DU;
10755 else if (interface_type == RTW_SDIO)
10756 addr_offset = EEPROM_MAC_ADDR_8723DS;
10757 else if (interface_type == RTW_PCIE)
10758 addr_offset = EEPROM_MAC_ADDR_8723DE;
10759 break;
10760 #endif
10761
10762 #ifdef CONFIG_RTL8188E
10763 case RTL8188E:
10764 if (interface_type == RTW_USB)
10765 addr_offset = EEPROM_MAC_ADDR_88EU;
10766 else if (interface_type == RTW_SDIO)
10767 addr_offset = EEPROM_MAC_ADDR_88ES;
10768 else if (interface_type == RTW_PCIE)
10769 addr_offset = EEPROM_MAC_ADDR_88EE;
10770 break;
10771 #endif
10772 #ifdef CONFIG_RTL8188F
10773 case RTL8188F:
10774 if (interface_type == RTW_USB)
10775 addr_offset = EEPROM_MAC_ADDR_8188FU;
10776 else if (interface_type == RTW_SDIO)
10777 addr_offset = EEPROM_MAC_ADDR_8188FS;
10778 break;
10779 #endif
10780 #ifdef CONFIG_RTL8812A
10781 case RTL8812:
10782 if (interface_type == RTW_USB)
10783 addr_offset = EEPROM_MAC_ADDR_8812AU;
10784 else if (interface_type == RTW_PCIE)
10785 addr_offset = EEPROM_MAC_ADDR_8812AE;
10786 break;
10787 #endif
10788 #ifdef CONFIG_RTL8821A
10789 case RTL8821:
10790 if (interface_type == RTW_USB)
10791 addr_offset = EEPROM_MAC_ADDR_8821AU;
10792 else if (interface_type == RTW_SDIO)
10793 addr_offset = EEPROM_MAC_ADDR_8821AS;
10794 else if (interface_type == RTW_PCIE)
10795 addr_offset = EEPROM_MAC_ADDR_8821AE;
10796 break;
10797 #endif
10798 #ifdef CONFIG_RTL8192E
10799 case RTL8192E:
10800 if (interface_type == RTW_USB)
10801 addr_offset = EEPROM_MAC_ADDR_8192EU;
10802 else if (interface_type == RTW_SDIO)
10803 addr_offset = EEPROM_MAC_ADDR_8192ES;
10804 else if (interface_type == RTW_PCIE)
10805 addr_offset = EEPROM_MAC_ADDR_8192EE;
10806 break;
10807 #endif
10808 #ifdef CONFIG_RTL8814A
10809 case RTL8814A:
10810 if (interface_type == RTW_USB)
10811 addr_offset = EEPROM_MAC_ADDR_8814AU;
10812 else if (interface_type == RTW_PCIE)
10813 addr_offset = EEPROM_MAC_ADDR_8814AE;
10814 break;
10815 #endif
10816
10817 #ifdef CONFIG_RTL8822B
10818 case RTL8822B:
10819 if (interface_type == RTW_USB)
10820 addr_offset = EEPROM_MAC_ADDR_8822BU;
10821 else if (interface_type == RTW_SDIO)
10822 addr_offset = EEPROM_MAC_ADDR_8822BS;
10823 else if (interface_type == RTW_PCIE)
10824 addr_offset = EEPROM_MAC_ADDR_8822BE;
10825 break;
10826 #endif /* CONFIG_RTL8822B */
10827
10828 #ifdef CONFIG_RTL8821C
10829 case RTL8821C:
10830 if (interface_type == RTW_USB)
10831 addr_offset = EEPROM_MAC_ADDR_8821CU;
10832 else if (interface_type == RTW_SDIO)
10833 addr_offset = EEPROM_MAC_ADDR_8821CS;
10834 else if (interface_type == RTW_PCIE)
10835 addr_offset = EEPROM_MAC_ADDR_8821CE;
10836 break;
10837 #endif /* CONFIG_RTL8821C */
10838 }
10839
10840 if (addr_offset == -1) {
10841 RTW_ERR("%s: unknown combination - chip_type:%u, interface:%u\n"
10842 , __func__, rtw_get_chip_type(adapter), rtw_get_intf_type(adapter));
10843 }
10844
10845 return addr_offset;
10846 }
10847
Hal_GetPhyEfuseMACAddr(PADAPTER padapter,u8 * mac_addr)10848 int Hal_GetPhyEfuseMACAddr(PADAPTER padapter, u8 *mac_addr)
10849 {
10850 int ret = _FAIL;
10851 int addr_offset;
10852
10853 addr_offset = hal_efuse_macaddr_offset(padapter);
10854 if (addr_offset == -1)
10855 goto exit;
10856
10857 ret = rtw_efuse_map_read(padapter, addr_offset, ETH_ALEN, mac_addr);
10858
10859 exit:
10860 return ret;
10861 }
10862
rtw_dump_cur_efuse(PADAPTER padapter)10863 void rtw_dump_cur_efuse(PADAPTER padapter)
10864 {
10865 int i =0;
10866 int mapsize =0;
10867 HAL_DATA_TYPE *hal_data = GET_HAL_DATA(padapter);
10868
10869 EFUSE_GetEfuseDefinition(padapter, EFUSE_WIFI, TYPE_EFUSE_MAP_LEN , (void *)&mapsize, _FALSE);
10870
10871 if (mapsize <= 0 || mapsize > EEPROM_MAX_SIZE) {
10872 RTW_ERR("wrong map size %d\n", mapsize);
10873 return;
10874 }
10875
10876 if (hal_data->efuse_file_status == EFUSE_FILE_LOADED)
10877 RTW_INFO("EFUSE FILE\n");
10878 else
10879 RTW_INFO("HW EFUSE\n");
10880
10881 #ifdef CONFIG_RTW_DEBUG
10882 for (i = 0; i < mapsize; i++) {
10883 if (i % 16 == 0)
10884 RTW_PRINT_SEL(RTW_DBGDUMP, "0x%03x: ", i);
10885
10886 _RTW_PRINT_SEL(RTW_DBGDUMP, "%02X%s"
10887 , hal_data->efuse_eeprom_data[i]
10888 , ((i + 1) % 16 == 0) ? "\n" : (((i + 1) % 8 == 0) ? " " : " ")
10889 );
10890 }
10891 _RTW_PRINT_SEL(RTW_DBGDUMP, "\n");
10892 #endif
10893 }
10894
10895
10896 #ifdef CONFIG_EFUSE_CONFIG_FILE
Hal_readPGDataFromConfigFile(PADAPTER padapter)10897 u32 Hal_readPGDataFromConfigFile(PADAPTER padapter)
10898 {
10899 HAL_DATA_TYPE *hal_data = GET_HAL_DATA(padapter);
10900 u32 ret = _FALSE;
10901 u32 maplen = 0;
10902
10903 EFUSE_GetEfuseDefinition(padapter, EFUSE_WIFI, TYPE_EFUSE_MAP_LEN , (void *)&maplen, _FALSE);
10904
10905 if (maplen < 256 || maplen > EEPROM_MAX_SIZE) {
10906 RTW_ERR("eFuse length error :%d\n", maplen);
10907 return _FALSE;
10908 }
10909
10910 ret = rtw_read_efuse_from_file(EFUSE_MAP_PATH, hal_data->efuse_eeprom_data, maplen);
10911
10912 hal_data->efuse_file_status = ((ret == _FAIL) ? EFUSE_FILE_FAILED : EFUSE_FILE_LOADED);
10913
10914 if (hal_data->efuse_file_status == EFUSE_FILE_LOADED)
10915 rtw_dump_cur_efuse(padapter);
10916
10917 return ret;
10918 }
10919
Hal_ReadMACAddrFromFile(PADAPTER padapter,u8 * mac_addr)10920 u32 Hal_ReadMACAddrFromFile(PADAPTER padapter, u8 *mac_addr)
10921 {
10922 HAL_DATA_TYPE *hal_data = GET_HAL_DATA(padapter);
10923 u32 ret = _FAIL;
10924
10925 if (rtw_read_macaddr_from_file(WIFIMAC_PATH, mac_addr) == _SUCCESS
10926 && rtw_check_invalid_mac_address(mac_addr, _TRUE) == _FALSE
10927 ) {
10928 hal_data->macaddr_file_status = MACADDR_FILE_LOADED;
10929 ret = _SUCCESS;
10930 } else
10931 hal_data->macaddr_file_status = MACADDR_FILE_FAILED;
10932
10933 return ret;
10934 }
10935 #endif /* CONFIG_EFUSE_CONFIG_FILE */
10936
hal_config_macaddr(_adapter * adapter,bool autoload_fail)10937 int hal_config_macaddr(_adapter *adapter, bool autoload_fail)
10938 {
10939 HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
10940 u8 addr[ETH_ALEN];
10941 int addr_offset = hal_efuse_macaddr_offset(adapter);
10942 u8 *hw_addr = NULL;
10943 int ret = _SUCCESS;
10944
10945 if (autoload_fail)
10946 goto bypass_hw_pg;
10947
10948 if (addr_offset != -1)
10949 hw_addr = &hal_data->efuse_eeprom_data[addr_offset];
10950
10951 #ifdef CONFIG_EFUSE_CONFIG_FILE
10952 /* if the hw_addr is written by efuse file, set to NULL */
10953 if (hal_data->efuse_file_status == EFUSE_FILE_LOADED)
10954 hw_addr = NULL;
10955 #endif
10956
10957 if (!hw_addr) {
10958 /* try getting hw pg data */
10959 if (Hal_GetPhyEfuseMACAddr(adapter, addr) == _SUCCESS)
10960 hw_addr = addr;
10961 }
10962
10963 /* check hw pg data */
10964 if (hw_addr && rtw_check_invalid_mac_address(hw_addr, _TRUE) == _FALSE) {
10965 _rtw_memcpy(hal_data->EEPROMMACAddr, hw_addr, ETH_ALEN);
10966 goto exit;
10967 }
10968
10969 bypass_hw_pg:
10970
10971 #ifdef CONFIG_EFUSE_CONFIG_FILE
10972 /* check wifi mac file */
10973 if (Hal_ReadMACAddrFromFile(adapter, addr) == _SUCCESS) {
10974 _rtw_memcpy(hal_data->EEPROMMACAddr, addr, ETH_ALEN);
10975 goto exit;
10976 }
10977 #endif
10978
10979 _rtw_memset(hal_data->EEPROMMACAddr, 0, ETH_ALEN);
10980 ret = _FAIL;
10981
10982 exit:
10983 return ret;
10984 }
10985
10986 #ifdef CONFIG_RF_POWER_TRIM
10987 u32 Array_kfreemap[] = {
10988 0x08, 0xe,
10989 0x06, 0xc,
10990 0x04, 0xa,
10991 0x02, 0x8,
10992 0x00, 0x6,
10993 0x03, 0x4,
10994 0x05, 0x2,
10995 0x07, 0x0,
10996 0x09, 0x0,
10997 0x0c, 0x0,
10998 };
10999
rtw_bb_rf_gain_offset(_adapter * padapter)11000 void rtw_bb_rf_gain_offset(_adapter *padapter)
11001 {
11002 HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);
11003 struct registry_priv *registry_par = &padapter->registrypriv;
11004 struct kfree_data_t *kfree_data = &pHalData->kfree_data;
11005 u8 value = pHalData->EEPROMRFGainOffset;
11006 u8 tmp = 0x3e;
11007 u32 res, i = 0;
11008 u4Byte ArrayLen = sizeof(Array_kfreemap) / sizeof(u32);
11009 pu4Byte Array = Array_kfreemap;
11010 u4Byte v1 = 0, v2 = 0, GainValue = 0, target = 0;
11011
11012 if (registry_par->RegPwrTrimEnable == 2) {
11013 RTW_INFO("Registry kfree default force disable.\n");
11014 return;
11015 }
11016
11017 #if defined(CONFIG_RTL8723B)
11018 if (value & BIT4 && (registry_par->RegPwrTrimEnable == 1)) {
11019 RTW_INFO("Offset RF Gain.\n");
11020 RTW_INFO("Offset RF Gain. pHalData->EEPROMRFGainVal=0x%x\n", pHalData->EEPROMRFGainVal);
11021
11022 if (pHalData->EEPROMRFGainVal != 0xff) {
11023
11024 if (pHalData->ant_path == RF_PATH_A)
11025 GainValue = (pHalData->EEPROMRFGainVal & 0x0f);
11026
11027 else
11028 GainValue = (pHalData->EEPROMRFGainVal & 0xf0) >> 4;
11029 RTW_INFO("Ant PATH_%d GainValue Offset = 0x%x\n", (pHalData->ant_path == RF_PATH_A) ? (RF_PATH_A) : (RF_PATH_B), GainValue);
11030
11031 for (i = 0; i < ArrayLen; i += 2) {
11032 /* RTW_INFO("ArrayLen in =%d ,Array 1 =0x%x ,Array2 =0x%x\n",i,Array[i],Array[i]+1); */
11033 v1 = Array[i];
11034 v2 = Array[i + 1];
11035 if (v1 == GainValue) {
11036 RTW_INFO("Offset RF Gain. got v1 =0x%x ,v2 =0x%x\n", v1, v2);
11037 target = v2;
11038 break;
11039 }
11040 }
11041 RTW_INFO("pHalData->EEPROMRFGainVal=0x%x ,Gain offset Target Value=0x%x\n", pHalData->EEPROMRFGainVal, target);
11042
11043 res = rtw_hal_read_rfreg(padapter, RF_PATH_A, 0x7f, 0xffffffff);
11044 RTW_INFO("Offset RF Gain. before reg 0x7f=0x%08x\n", res);
11045 phy_set_rf_reg(padapter, RF_PATH_A, REG_RF_BB_GAIN_OFFSET, BIT18 | BIT17 | BIT16 | BIT15, target);
11046 res = rtw_hal_read_rfreg(padapter, RF_PATH_A, 0x7f, 0xffffffff);
11047
11048 RTW_INFO("Offset RF Gain. After reg 0x7f=0x%08x\n", res);
11049
11050 } else
11051
11052 RTW_INFO("Offset RF Gain. pHalData->EEPROMRFGainVal=0x%x != 0xff, didn't run Kfree\n", pHalData->EEPROMRFGainVal);
11053 } else
11054 RTW_INFO("Using the default RF gain.\n");
11055
11056 #elif defined(CONFIG_RTL8188E)
11057 if (value & BIT4 && (registry_par->RegPwrTrimEnable == 1)) {
11058 RTW_INFO("8188ES Offset RF Gain.\n");
11059 RTW_INFO("8188ES Offset RF Gain. EEPROMRFGainVal=0x%x\n",
11060 pHalData->EEPROMRFGainVal);
11061
11062 if (pHalData->EEPROMRFGainVal != 0xff) {
11063 res = rtw_hal_read_rfreg(padapter, RF_PATH_A,
11064 REG_RF_BB_GAIN_OFFSET, 0xffffffff);
11065
11066 RTW_INFO("Offset RF Gain. reg 0x55=0x%x\n", res);
11067 res &= 0xfff87fff;
11068
11069 res |= (pHalData->EEPROMRFGainVal & 0x0f) << 15;
11070 RTW_INFO("Offset RF Gain. res=0x%x\n", res);
11071
11072 rtw_hal_write_rfreg(padapter, RF_PATH_A,
11073 REG_RF_BB_GAIN_OFFSET,
11074 RF_GAIN_OFFSET_MASK, res);
11075 } else {
11076 RTW_INFO("Offset RF Gain. EEPROMRFGainVal=0x%x == 0xff, didn't run Kfree\n",
11077 pHalData->EEPROMRFGainVal);
11078 }
11079 } else
11080 RTW_INFO("Using the default RF gain.\n");
11081 #else
11082 /* TODO: call this when channel switch */
11083 if (kfree_data->flag & KFREE_FLAG_ON)
11084 rtw_rf_apply_tx_gain_offset(padapter, 6); /* input ch6 to select BB_GAIN_2G */
11085 #endif
11086
11087 }
11088 #endif /*CONFIG_RF_POWER_TRIM */
11089
kfree_data_is_bb_gain_empty(struct kfree_data_t * data)11090 bool kfree_data_is_bb_gain_empty(struct kfree_data_t *data)
11091 {
11092 #ifdef CONFIG_RF_POWER_TRIM
11093 int i, j;
11094
11095 for (i = 0; i < BB_GAIN_NUM; i++)
11096 for (j = 0; j < RF_PATH_MAX; j++)
11097 if (data->bb_gain[i][j] != 0)
11098 return 0;
11099 #endif
11100 return 1;
11101 }
11102
11103 #ifdef CONFIG_USB_RX_AGGREGATION
rtw_set_usb_agg_by_mode_normal(_adapter * padapter,u8 cur_wireless_mode)11104 void rtw_set_usb_agg_by_mode_normal(_adapter *padapter, u8 cur_wireless_mode)
11105 {
11106 HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);
11107 if (cur_wireless_mode < WIRELESS_11_24N
11108 && cur_wireless_mode > 0) { /* ABG mode */
11109 #ifdef CONFIG_PREALLOC_RX_SKB_BUFFER
11110 u32 remainder = 0;
11111 u8 quotient = 0;
11112
11113 remainder = MAX_RECVBUF_SZ % (4 * 1024);
11114 quotient = (u8)(MAX_RECVBUF_SZ >> 12);
11115
11116 if (quotient > 5) {
11117 pHalData->rxagg_usb_size = 0x6;
11118 pHalData->rxagg_usb_timeout = 0x10;
11119 } else {
11120 if (remainder >= 2048) {
11121 pHalData->rxagg_usb_size = quotient;
11122 pHalData->rxagg_usb_timeout = 0x10;
11123 } else {
11124 pHalData->rxagg_usb_size = (quotient - 1);
11125 pHalData->rxagg_usb_timeout = 0x10;
11126 }
11127 }
11128 #else /* !CONFIG_PREALLOC_RX_SKB_BUFFER */
11129 if (0x6 != pHalData->rxagg_usb_size || 0x10 != pHalData->rxagg_usb_timeout) {
11130 pHalData->rxagg_usb_size = 0x6;
11131 pHalData->rxagg_usb_timeout = 0x10;
11132 rtw_write16(padapter, REG_RXDMA_AGG_PG_TH,
11133 pHalData->rxagg_usb_size | (pHalData->rxagg_usb_timeout << 8));
11134 }
11135 #endif /* CONFIG_PREALLOC_RX_SKB_BUFFER */
11136
11137 } else if (cur_wireless_mode >= WIRELESS_11_24N
11138 && cur_wireless_mode <= WIRELESS_MODE_MAX) { /* N AC mode */
11139 #ifdef CONFIG_PREALLOC_RX_SKB_BUFFER
11140 u32 remainder = 0;
11141 u8 quotient = 0;
11142
11143 remainder = MAX_RECVBUF_SZ % (4 * 1024);
11144 quotient = (u8)(MAX_RECVBUF_SZ >> 12);
11145
11146 if (quotient > 5) {
11147 pHalData->rxagg_usb_size = 0x5;
11148 pHalData->rxagg_usb_timeout = 0x20;
11149 } else {
11150 if (remainder >= 2048) {
11151 pHalData->rxagg_usb_size = quotient;
11152 pHalData->rxagg_usb_timeout = 0x10;
11153 } else {
11154 pHalData->rxagg_usb_size = (quotient - 1);
11155 pHalData->rxagg_usb_timeout = 0x10;
11156 }
11157 }
11158 #else /* !CONFIG_PREALLOC_RX_SKB_BUFFER */
11159 if ((0x5 != pHalData->rxagg_usb_size) || (0x20 != pHalData->rxagg_usb_timeout)) {
11160 pHalData->rxagg_usb_size = 0x5;
11161 pHalData->rxagg_usb_timeout = 0x20;
11162 rtw_write16(padapter, REG_RXDMA_AGG_PG_TH,
11163 pHalData->rxagg_usb_size | (pHalData->rxagg_usb_timeout << 8));
11164 }
11165 #endif /* CONFIG_PREALLOC_RX_SKB_BUFFER */
11166
11167 } else {
11168 /* RTW_INFO("%s: Unknow wireless mode(0x%x)\n",__func__,padapter->mlmeextpriv.cur_wireless_mode); */
11169 }
11170 }
11171
rtw_set_usb_agg_by_mode_customer(_adapter * padapter,u8 cur_wireless_mode,u8 UsbDmaSize,u8 Legacy_UsbDmaSize)11172 void rtw_set_usb_agg_by_mode_customer(_adapter *padapter, u8 cur_wireless_mode, u8 UsbDmaSize, u8 Legacy_UsbDmaSize)
11173 {
11174 HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);
11175
11176 if (cur_wireless_mode < WIRELESS_11_24N
11177 && cur_wireless_mode > 0) { /* ABG mode */
11178 if (Legacy_UsbDmaSize != pHalData->rxagg_usb_size
11179 || 0x10 != pHalData->rxagg_usb_timeout) {
11180 pHalData->rxagg_usb_size = Legacy_UsbDmaSize;
11181 pHalData->rxagg_usb_timeout = 0x10;
11182 rtw_write16(padapter, REG_RXDMA_AGG_PG_TH,
11183 pHalData->rxagg_usb_size | (pHalData->rxagg_usb_timeout << 8));
11184 }
11185 } else if (cur_wireless_mode >= WIRELESS_11_24N
11186 && cur_wireless_mode <= WIRELESS_MODE_MAX) { /* N AC mode */
11187 if (UsbDmaSize != pHalData->rxagg_usb_size
11188 || 0x20 != pHalData->rxagg_usb_timeout) {
11189 pHalData->rxagg_usb_size = UsbDmaSize;
11190 pHalData->rxagg_usb_timeout = 0x20;
11191 rtw_write16(padapter, REG_RXDMA_AGG_PG_TH,
11192 pHalData->rxagg_usb_size | (pHalData->rxagg_usb_timeout << 8));
11193 }
11194 } else {
11195 /* RTW_INFO("%s: Unknown wireless mode(0x%x)\n",__func__,padapter->mlmeextpriv.cur_wireless_mode); */
11196 }
11197 }
11198
rtw_set_usb_agg_by_mode(_adapter * padapter,u8 cur_wireless_mode)11199 void rtw_set_usb_agg_by_mode(_adapter *padapter, u8 cur_wireless_mode)
11200 {
11201 #ifdef CONFIG_PLATFORM_NOVATEK_NT72668
11202 rtw_set_usb_agg_by_mode_customer(padapter, cur_wireless_mode, 0x3, 0x3);
11203 return;
11204 #endif /* CONFIG_PLATFORM_NOVATEK_NT72668 */
11205
11206 rtw_set_usb_agg_by_mode_normal(padapter, cur_wireless_mode);
11207 }
11208 #endif /* CONFIG_USB_RX_AGGREGATION */
11209
11210 /* To avoid RX affect TX throughput */
dm_DynamicUsbTxAgg(_adapter * padapter,u8 from_timer)11211 void dm_DynamicUsbTxAgg(_adapter *padapter, u8 from_timer)
11212 {
11213 struct dvobj_priv *pdvobjpriv = adapter_to_dvobj(padapter);
11214 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
11215 struct registry_priv *registry_par = &padapter->registrypriv;
11216 HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);
11217 u8 cur_wireless_mode = WIRELESS_INVALID;
11218
11219 #ifdef CONFIG_USB_RX_AGGREGATION
11220 if (!registry_par->dynamic_agg_enable)
11221 return;
11222
11223 #ifdef RTW_HALMAC
11224 if (IS_HARDWARE_TYPE_8822BU(padapter) || IS_HARDWARE_TYPE_8821CU(padapter))
11225 rtw_hal_set_hwreg(padapter, HW_VAR_RXDMA_AGG_PG_TH, NULL);
11226 #else /* !RTW_HALMAC */
11227 if (IS_HARDWARE_TYPE_8821U(padapter)) { /* || IS_HARDWARE_TYPE_8192EU(padapter)) */
11228 /* This AGG_PH_TH only for UsbRxAggMode == USB_RX_AGG_USB */
11229 if ((pHalData->rxagg_mode == RX_AGG_USB) && (check_fwstate(pmlmepriv, _FW_LINKED) == _TRUE)) {
11230 if (pdvobjpriv->traffic_stat.cur_tx_tp > 2 && pdvobjpriv->traffic_stat.cur_rx_tp < 30)
11231 rtw_write16(padapter , REG_RXDMA_AGG_PG_TH , 0x1010);
11232 else if (pdvobjpriv->traffic_stat.last_tx_bytes > 220000 && pdvobjpriv->traffic_stat.cur_rx_tp < 30)
11233 rtw_write16(padapter , REG_RXDMA_AGG_PG_TH , 0x1006);
11234 else
11235 rtw_write16(padapter, REG_RXDMA_AGG_PG_TH, 0x2005); /* dmc agg th 20K */
11236
11237 /* RTW_INFO("TX_TP=%u, RX_TP=%u\n", pdvobjpriv->traffic_stat.cur_tx_tp, pdvobjpriv->traffic_stat.cur_rx_tp); */
11238 }
11239 } else if (IS_HARDWARE_TYPE_8812(padapter)) {
11240 #ifdef CONFIG_CONCURRENT_MODE
11241 u8 i;
11242 _adapter *iface;
11243 u8 bassocaed = _FALSE;
11244 struct mlme_ext_priv *mlmeext;
11245
11246 for (i = 0; i < pdvobjpriv->iface_nums; i++) {
11247 iface = pdvobjpriv->padapters[i];
11248 mlmeext = &iface->mlmeextpriv;
11249 if (rtw_linked_check(iface) == _TRUE) {
11250 if (mlmeext->cur_wireless_mode >= cur_wireless_mode)
11251 cur_wireless_mode = mlmeext->cur_wireless_mode;
11252 bassocaed = _TRUE;
11253 }
11254 }
11255 if (bassocaed)
11256 #endif
11257 rtw_set_usb_agg_by_mode(padapter, cur_wireless_mode);
11258 #ifdef CONFIG_PLATFORM_NOVATEK_NT72668
11259 } else {
11260 rtw_set_usb_agg_by_mode(padapter, cur_wireless_mode);
11261 #endif /* CONFIG_PLATFORM_NOVATEK_NT72668 */
11262 }
11263 #endif /* RTW_HALMAC */
11264 #endif /* CONFIG_USB_RX_AGGREGATION */
11265
11266 }
11267
11268 /* bus-agg check for SoftAP mode */
rtw_hal_busagg_qsel_check(_adapter * padapter,u8 pre_qsel,u8 next_qsel)11269 inline u8 rtw_hal_busagg_qsel_check(_adapter *padapter, u8 pre_qsel, u8 next_qsel)
11270 {
11271 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
11272 u8 chk_rst = _SUCCESS;
11273
11274 if (!MLME_IS_AP(padapter) && !MLME_IS_MESH(padapter))
11275 return chk_rst;
11276
11277 /* if((pre_qsel == 0xFF)||(next_qsel== 0xFF)) */
11278 /* return chk_rst; */
11279
11280 if (((pre_qsel == QSLT_HIGH) || ((next_qsel == QSLT_HIGH)))
11281 && (pre_qsel != next_qsel)) {
11282 /* RTW_INFO("### bus-agg break cause of qsel misatch, pre_qsel=0x%02x,next_qsel=0x%02x ###\n", */
11283 /* pre_qsel,next_qsel); */
11284 chk_rst = _FAIL;
11285 }
11286 return chk_rst;
11287 }
11288
11289 /*
11290 * Description:
11291 * dump_TX_FIFO: This is only used to dump TX_FIFO for debug WoW mode offload
11292 * contant.
11293 *
11294 * Input:
11295 * adapter: adapter pointer.
11296 * page_num: The max. page number that user want to dump.
11297 * page_size: page size of each page. eg. 128 bytes, 256 bytes, 512byte.
11298 */
dump_TX_FIFO(_adapter * padapter,u8 page_num,u16 page_size)11299 void dump_TX_FIFO(_adapter *padapter, u8 page_num, u16 page_size)
11300 {
11301
11302 int i;
11303 u8 val = 0;
11304 u8 base = 0;
11305 u32 addr = 0;
11306 u32 count = (page_size / 8);
11307
11308 if (page_num <= 0) {
11309 RTW_INFO("!!%s: incorrect input page_num paramter!\n", __func__);
11310 return;
11311 }
11312
11313 if (page_size < 128 || page_size > 512) {
11314 RTW_INFO("!!%s: incorrect input page_size paramter!\n", __func__);
11315 return;
11316 }
11317
11318 RTW_INFO("+%s+\n", __func__);
11319 val = rtw_read8(padapter, 0x106);
11320 rtw_write8(padapter, 0x106, 0x69);
11321 RTW_INFO("0x106: 0x%02x\n", val);
11322 base = rtw_read8(padapter, 0x209);
11323 RTW_INFO("0x209: 0x%02x\n", base);
11324
11325 addr = ((base)*page_size) / 8;
11326 for (i = 0 ; i < page_num * count ; i += 2) {
11327 rtw_write32(padapter, 0x140, addr + i);
11328 printk(" %08x %08x ", rtw_read32(padapter, 0x144), rtw_read32(padapter, 0x148));
11329 rtw_write32(padapter, 0x140, addr + i + 1);
11330 printk(" %08x %08x\n", rtw_read32(padapter, 0x144), rtw_read32(padapter, 0x148));
11331 }
11332 }
11333
11334 #ifdef CONFIG_GPIO_API
rtw_hal_get_gpio(_adapter * adapter,u8 gpio_num)11335 u8 rtw_hal_get_gpio(_adapter *adapter, u8 gpio_num)
11336 {
11337 u8 value = 0;
11338 u8 direction = 0;
11339 u32 gpio_pin_input_val = REG_GPIO_PIN_CTRL;
11340 u32 gpio_pin_output_val = REG_GPIO_PIN_CTRL + 1;
11341 u32 gpio_pin_output_en = REG_GPIO_PIN_CTRL + 2;
11342 u8 gpio_num_to_set = gpio_num;
11343 struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(adapter);
11344
11345 if (rtw_hal_gpio_func_check(adapter, gpio_num) == _FAIL)
11346 return value;
11347
11348 rtw_ps_deny(adapter, PS_DENY_IOCTL);
11349
11350 RTW_INFO("rf_pwrstate=0x%02x\n", pwrpriv->rf_pwrstate);
11351 LeaveAllPowerSaveModeDirect(adapter);
11352
11353 if (gpio_num > 7) {
11354 gpio_pin_input_val = REG_GPIO_PIN_CTRL_2;
11355 gpio_pin_output_val = REG_GPIO_PIN_CTRL_2 + 1;
11356 gpio_pin_output_en = REG_GPIO_PIN_CTRL_2 + 2;
11357 gpio_num_to_set = gpio_num - 8;
11358 }
11359
11360 /* Read GPIO Direction */
11361 direction = (rtw_read8(adapter, gpio_pin_output_en) & BIT(gpio_num_to_set)) >> gpio_num_to_set;
11362
11363 /* According the direction to read register value */
11364 if (direction)
11365 value = (rtw_read8(adapter, gpio_pin_output_val) & BIT(gpio_num_to_set)) >> gpio_num_to_set;
11366 else
11367 value = (rtw_read8(adapter, gpio_pin_input_val) & BIT(gpio_num_to_set)) >> gpio_num_to_set;
11368
11369 rtw_ps_deny_cancel(adapter, PS_DENY_IOCTL);
11370 RTW_INFO("%s direction=%d value=%d\n", __FUNCTION__, direction, value);
11371
11372 return value;
11373 }
11374
rtw_hal_set_gpio_output_value(_adapter * adapter,u8 gpio_num,bool isHigh)11375 int rtw_hal_set_gpio_output_value(_adapter *adapter, u8 gpio_num, bool isHigh)
11376 {
11377 u8 direction = 0;
11378 u8 res = -1;
11379 u32 gpio_pin_output_val = REG_GPIO_PIN_CTRL + 1;
11380 u32 gpio_pin_output_en = REG_GPIO_PIN_CTRL + 2;
11381 u8 gpio_num_to_set = gpio_num;
11382
11383 if (rtw_hal_gpio_func_check(adapter, gpio_num) == _FAIL)
11384 return -1;
11385
11386 rtw_ps_deny(adapter, PS_DENY_IOCTL);
11387
11388 LeaveAllPowerSaveModeDirect(adapter);
11389
11390 if (gpio_num > 7) {
11391 gpio_pin_output_val = REG_GPIO_PIN_CTRL_2 + 1;
11392 gpio_pin_output_en = REG_GPIO_PIN_CTRL_2 + 2;
11393 gpio_num_to_set = gpio_num - 8;
11394 }
11395
11396 /* Read GPIO direction */
11397 direction = (rtw_read8(adapter, gpio_pin_output_en) & BIT(gpio_num_to_set)) >> gpio_num_to_set;
11398
11399 /* If GPIO is output direction, setting value. */
11400 if (direction) {
11401 if (isHigh)
11402 rtw_write8(adapter, gpio_pin_output_val, rtw_read8(adapter, gpio_pin_output_val) | BIT(gpio_num_to_set));
11403 else
11404 rtw_write8(adapter, gpio_pin_output_val, rtw_read8(adapter, gpio_pin_output_val) & ~BIT(gpio_num_to_set));
11405
11406 RTW_INFO("%s Set gpio %x[%d]=%d\n", __FUNCTION__, REG_GPIO_PIN_CTRL + 1, gpio_num, isHigh);
11407 res = 0;
11408 } else {
11409 RTW_INFO("%s The gpio is input,not be set!\n", __FUNCTION__);
11410 res = -1;
11411 }
11412
11413 rtw_ps_deny_cancel(adapter, PS_DENY_IOCTL);
11414 return res;
11415 }
11416
rtw_hal_config_gpio(_adapter * adapter,u8 gpio_num,bool isOutput)11417 int rtw_hal_config_gpio(_adapter *adapter, u8 gpio_num, bool isOutput)
11418 {
11419 u32 gpio_ctrl_reg_to_set = REG_GPIO_PIN_CTRL + 2;
11420 u8 gpio_num_to_set = gpio_num;
11421
11422 if (rtw_hal_gpio_func_check(adapter, gpio_num) == _FAIL)
11423 return -1;
11424
11425 RTW_INFO("%s gpio_num =%d direction=%d\n", __FUNCTION__, gpio_num, isOutput);
11426
11427 rtw_ps_deny(adapter, PS_DENY_IOCTL);
11428
11429 LeaveAllPowerSaveModeDirect(adapter);
11430
11431 rtw_hal_gpio_multi_func_reset(adapter, gpio_num);
11432
11433 if (gpio_num > 7) {
11434 gpio_ctrl_reg_to_set = REG_GPIO_PIN_CTRL_2 + 2;
11435 gpio_num_to_set = gpio_num - 8;
11436 }
11437
11438 if (isOutput)
11439 rtw_write8(adapter, gpio_ctrl_reg_to_set, rtw_read8(adapter, gpio_ctrl_reg_to_set) | BIT(gpio_num_to_set));
11440 else
11441 rtw_write8(adapter, gpio_ctrl_reg_to_set, rtw_read8(adapter, gpio_ctrl_reg_to_set) & ~BIT(gpio_num_to_set));
11442
11443 rtw_ps_deny_cancel(adapter, PS_DENY_IOCTL);
11444
11445 return 0;
11446 }
rtw_hal_register_gpio_interrupt(_adapter * adapter,int gpio_num,void (* callback)(u8 level))11447 int rtw_hal_register_gpio_interrupt(_adapter *adapter, int gpio_num, void(*callback)(u8 level))
11448 {
11449 u8 value;
11450 u8 direction;
11451 PHAL_DATA_TYPE phal = GET_HAL_DATA(adapter);
11452
11453 if (IS_HARDWARE_TYPE_8188E(adapter)) {
11454 if (gpio_num > 7 || gpio_num < 4) {
11455 RTW_PRINT("%s The gpio number does not included 4~7.\n", __FUNCTION__);
11456 return -1;
11457 }
11458 }
11459
11460 rtw_ps_deny(adapter, PS_DENY_IOCTL);
11461
11462 LeaveAllPowerSaveModeDirect(adapter);
11463
11464 /* Read GPIO direction */
11465 direction = (rtw_read8(adapter, REG_GPIO_PIN_CTRL + 2) & BIT(gpio_num)) >> gpio_num;
11466 if (direction) {
11467 RTW_PRINT("%s Can't register output gpio as interrupt.\n", __FUNCTION__);
11468 return -1;
11469 }
11470
11471 /* Config GPIO Mode */
11472 rtw_write8(adapter, REG_GPIO_PIN_CTRL + 3, rtw_read8(adapter, REG_GPIO_PIN_CTRL + 3) | BIT(gpio_num));
11473
11474 /* Register GPIO interrupt handler*/
11475 adapter->gpiointpriv.callback[gpio_num] = callback;
11476
11477 /* Set GPIO interrupt mode, 0:positive edge, 1:negative edge */
11478 value = rtw_read8(adapter, REG_GPIO_PIN_CTRL) & BIT(gpio_num);
11479 adapter->gpiointpriv.interrupt_mode = rtw_read8(adapter, REG_HSIMR + 2) ^ value;
11480 rtw_write8(adapter, REG_GPIO_INTM, adapter->gpiointpriv.interrupt_mode);
11481
11482 /* Enable GPIO interrupt */
11483 adapter->gpiointpriv.interrupt_enable_mask = rtw_read8(adapter, REG_HSIMR + 2) | BIT(gpio_num);
11484 rtw_write8(adapter, REG_HSIMR + 2, adapter->gpiointpriv.interrupt_enable_mask);
11485
11486 rtw_hal_update_hisr_hsisr_ind(adapter, 1);
11487
11488 rtw_ps_deny_cancel(adapter, PS_DENY_IOCTL);
11489
11490 return 0;
11491 }
rtw_hal_disable_gpio_interrupt(_adapter * adapter,int gpio_num)11492 int rtw_hal_disable_gpio_interrupt(_adapter *adapter, int gpio_num)
11493 {
11494 u8 value;
11495 u8 direction;
11496 PHAL_DATA_TYPE phal = GET_HAL_DATA(adapter);
11497
11498 if (IS_HARDWARE_TYPE_8188E(adapter)) {
11499 if (gpio_num > 7 || gpio_num < 4) {
11500 RTW_INFO("%s The gpio number does not included 4~7.\n", __FUNCTION__);
11501 return -1;
11502 }
11503 }
11504
11505 rtw_ps_deny(adapter, PS_DENY_IOCTL);
11506
11507 LeaveAllPowerSaveModeDirect(adapter);
11508
11509 /* Config GPIO Mode */
11510 rtw_write8(adapter, REG_GPIO_PIN_CTRL + 3, rtw_read8(adapter, REG_GPIO_PIN_CTRL + 3) & ~BIT(gpio_num));
11511
11512 /* Unregister GPIO interrupt handler*/
11513 adapter->gpiointpriv.callback[gpio_num] = NULL;
11514
11515 /* Reset GPIO interrupt mode, 0:positive edge, 1:negative edge */
11516 adapter->gpiointpriv.interrupt_mode = rtw_read8(adapter, REG_GPIO_INTM) & ~BIT(gpio_num);
11517 rtw_write8(adapter, REG_GPIO_INTM, 0x00);
11518
11519 /* Disable GPIO interrupt */
11520 adapter->gpiointpriv.interrupt_enable_mask = rtw_read8(adapter, REG_HSIMR + 2) & ~BIT(gpio_num);
11521 rtw_write8(adapter, REG_HSIMR + 2, adapter->gpiointpriv.interrupt_enable_mask);
11522
11523 if (!adapter->gpiointpriv.interrupt_enable_mask)
11524 rtw_hal_update_hisr_hsisr_ind(adapter, 0);
11525
11526 rtw_ps_deny_cancel(adapter, PS_DENY_IOCTL);
11527
11528 return 0;
11529 }
11530 #endif
11531
rtw_hal_ch_sw_iqk_info_search(_adapter * padapter,u8 central_chnl,u8 bw_mode)11532 s8 rtw_hal_ch_sw_iqk_info_search(_adapter *padapter, u8 central_chnl, u8 bw_mode)
11533 {
11534 HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);
11535 u8 i;
11536
11537 for (i = 0; i < MAX_IQK_INFO_BACKUP_CHNL_NUM; i++) {
11538 if ((pHalData->iqk_reg_backup[i].central_chnl != 0)) {
11539 if ((pHalData->iqk_reg_backup[i].central_chnl == central_chnl)
11540 && (pHalData->iqk_reg_backup[i].bw_mode == bw_mode))
11541 return i;
11542 }
11543 }
11544
11545 return -1;
11546 }
11547
rtw_hal_ch_sw_iqk_info_backup(_adapter * padapter)11548 void rtw_hal_ch_sw_iqk_info_backup(_adapter *padapter)
11549 {
11550 HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);
11551 s8 res;
11552 u8 i;
11553
11554 /* If it's an existed record, overwrite it */
11555 res = rtw_hal_ch_sw_iqk_info_search(padapter, pHalData->current_channel, pHalData->current_channel_bw);
11556 if ((res >= 0) && (res < MAX_IQK_INFO_BACKUP_CHNL_NUM)) {
11557 rtw_hal_set_hwreg(padapter, HW_VAR_CH_SW_IQK_INFO_BACKUP, (u8 *)&(pHalData->iqk_reg_backup[res]));
11558 return;
11559 }
11560
11561 /* Search for the empty record to use */
11562 for (i = 0; i < MAX_IQK_INFO_BACKUP_CHNL_NUM; i++) {
11563 if (pHalData->iqk_reg_backup[i].central_chnl == 0) {
11564 rtw_hal_set_hwreg(padapter, HW_VAR_CH_SW_IQK_INFO_BACKUP, (u8 *)&(pHalData->iqk_reg_backup[i]));
11565 return;
11566 }
11567 }
11568
11569 /* Else, overwrite the oldest record */
11570 for (i = 1; i < MAX_IQK_INFO_BACKUP_CHNL_NUM; i++)
11571 _rtw_memcpy(&(pHalData->iqk_reg_backup[i - 1]), &(pHalData->iqk_reg_backup[i]), sizeof(struct hal_iqk_reg_backup));
11572
11573 rtw_hal_set_hwreg(padapter, HW_VAR_CH_SW_IQK_INFO_BACKUP, (u8 *)&(pHalData->iqk_reg_backup[MAX_IQK_INFO_BACKUP_CHNL_NUM - 1]));
11574 }
11575
rtw_hal_ch_sw_iqk_info_restore(_adapter * padapter,u8 ch_sw_use_case)11576 void rtw_hal_ch_sw_iqk_info_restore(_adapter *padapter, u8 ch_sw_use_case)
11577 {
11578 rtw_hal_set_hwreg(padapter, HW_VAR_CH_SW_IQK_INFO_RESTORE, &ch_sw_use_case);
11579 }
11580
rtw_dump_mac_rx_counters(_adapter * padapter,struct dbg_rx_counter * rx_counter)11581 void rtw_dump_mac_rx_counters(_adapter *padapter, struct dbg_rx_counter *rx_counter)
11582 {
11583 u32 mac_cck_ok = 0, mac_ofdm_ok = 0, mac_ht_ok = 0, mac_vht_ok = 0;
11584 u32 mac_cck_err = 0, mac_ofdm_err = 0, mac_ht_err = 0, mac_vht_err = 0;
11585 u32 mac_cck_fa = 0, mac_ofdm_fa = 0, mac_ht_fa = 0;
11586 u32 DropPacket = 0;
11587
11588 if (!rx_counter) {
11589 rtw_warn_on(1);
11590 return;
11591 }
11592 if (IS_HARDWARE_TYPE_JAGUAR(padapter) || IS_HARDWARE_TYPE_JAGUAR2(padapter))
11593 phy_set_mac_reg(padapter, REG_RXERR_RPT, BIT26, 0x0);/*clear bit-26*/
11594
11595 phy_set_mac_reg(padapter, REG_RXERR_RPT, BIT28 | BIT29 | BIT30 | BIT31, 0x3);
11596 mac_cck_ok = phy_query_mac_reg(padapter, REG_RXERR_RPT, bMaskLWord);/* [15:0] */
11597 phy_set_mac_reg(padapter, REG_RXERR_RPT, BIT28 | BIT29 | BIT30 | BIT31, 0x0);
11598 mac_ofdm_ok = phy_query_mac_reg(padapter, REG_RXERR_RPT, bMaskLWord);/* [15:0] */
11599 phy_set_mac_reg(padapter, REG_RXERR_RPT, BIT28 | BIT29 | BIT30 | BIT31, 0x6);
11600 mac_ht_ok = phy_query_mac_reg(padapter, REG_RXERR_RPT, bMaskLWord);/* [15:0] */
11601 mac_vht_ok = 0;
11602 if (IS_HARDWARE_TYPE_JAGUAR(padapter) || IS_HARDWARE_TYPE_JAGUAR2(padapter)) {
11603 phy_set_mac_reg(padapter, REG_RXERR_RPT, BIT28 | BIT29 | BIT30 | BIT31, 0x0);
11604 phy_set_mac_reg(padapter, REG_RXERR_RPT, BIT26, 0x1);
11605 mac_vht_ok = phy_query_mac_reg(padapter, REG_RXERR_RPT, bMaskLWord);/* [15:0]*/
11606 phy_set_mac_reg(padapter, REG_RXERR_RPT, BIT26, 0x0);/*clear bit-26*/
11607 }
11608
11609 phy_set_mac_reg(padapter, REG_RXERR_RPT, BIT28 | BIT29 | BIT30 | BIT31, 0x4);
11610 mac_cck_err = phy_query_mac_reg(padapter, REG_RXERR_RPT, bMaskLWord);/* [15:0] */
11611 phy_set_mac_reg(padapter, REG_RXERR_RPT, BIT28 | BIT29 | BIT30 | BIT31, 0x1);
11612 mac_ofdm_err = phy_query_mac_reg(padapter, REG_RXERR_RPT, bMaskLWord);/* [15:0] */
11613 phy_set_mac_reg(padapter, REG_RXERR_RPT, BIT28 | BIT29 | BIT30 | BIT31, 0x7);
11614 mac_ht_err = phy_query_mac_reg(padapter, REG_RXERR_RPT, bMaskLWord);/* [15:0] */
11615 mac_vht_err = 0;
11616 if (IS_HARDWARE_TYPE_JAGUAR(padapter) || IS_HARDWARE_TYPE_JAGUAR2(padapter)) {
11617 phy_set_mac_reg(padapter, REG_RXERR_RPT, BIT28 | BIT29 | BIT30 | BIT31, 0x1);
11618 phy_set_mac_reg(padapter, REG_RXERR_RPT, BIT26, 0x1);
11619 mac_vht_err = phy_query_mac_reg(padapter, REG_RXERR_RPT, bMaskLWord);/* [15:0]*/
11620 phy_set_mac_reg(padapter, REG_RXERR_RPT, BIT26, 0x0);/*clear bit-26*/
11621 }
11622
11623 phy_set_mac_reg(padapter, REG_RXERR_RPT, BIT28 | BIT29 | BIT30 | BIT31, 0x5);
11624 mac_cck_fa = phy_query_mac_reg(padapter, REG_RXERR_RPT, bMaskLWord);/* [15:0] */
11625 phy_set_mac_reg(padapter, REG_RXERR_RPT, BIT28 | BIT29 | BIT30 | BIT31, 0x2);
11626 mac_ofdm_fa = phy_query_mac_reg(padapter, REG_RXERR_RPT, bMaskLWord);/* [15:0] */
11627 phy_set_mac_reg(padapter, REG_RXERR_RPT, BIT28 | BIT29 | BIT30 | BIT31, 0x9);
11628 mac_ht_fa = phy_query_mac_reg(padapter, REG_RXERR_RPT, bMaskLWord);/* [15:0] */
11629
11630 /* Mac_DropPacket */
11631 rtw_write32(padapter, REG_RXERR_RPT, (rtw_read32(padapter, REG_RXERR_RPT) & 0x0FFFFFFF) | Mac_DropPacket);
11632 DropPacket = rtw_read32(padapter, REG_RXERR_RPT) & 0x0000FFFF;
11633
11634 rx_counter->rx_pkt_ok = mac_cck_ok + mac_ofdm_ok + mac_ht_ok + mac_vht_ok;
11635 rx_counter->rx_pkt_crc_error = mac_cck_err + mac_ofdm_err + mac_ht_err + mac_vht_err;
11636 rx_counter->rx_cck_fa = mac_cck_fa;
11637 rx_counter->rx_ofdm_fa = mac_ofdm_fa;
11638 rx_counter->rx_ht_fa = mac_ht_fa;
11639 rx_counter->rx_pkt_drop = DropPacket;
11640 }
rtw_reset_mac_rx_counters(_adapter * padapter)11641 void rtw_reset_mac_rx_counters(_adapter *padapter)
11642 {
11643
11644 /* If no packet rx, MaxRx clock be gating ,BIT_DISGCLK bit19 set 1 for fix*/
11645 if (IS_HARDWARE_TYPE_8703B(padapter) ||
11646 IS_HARDWARE_TYPE_8723D(padapter) ||
11647 IS_HARDWARE_TYPE_8188F(padapter))
11648 phy_set_mac_reg(padapter, REG_RCR, BIT19, 0x1);
11649
11650 /* reset mac counter */
11651 phy_set_mac_reg(padapter, REG_RXERR_RPT, BIT27, 0x1);
11652 phy_set_mac_reg(padapter, REG_RXERR_RPT, BIT27, 0x0);
11653 }
11654
rtw_dump_phy_rx_counters(_adapter * padapter,struct dbg_rx_counter * rx_counter)11655 void rtw_dump_phy_rx_counters(_adapter *padapter, struct dbg_rx_counter *rx_counter)
11656 {
11657 u32 cckok = 0, cckcrc = 0, ofdmok = 0, ofdmcrc = 0, htok = 0, htcrc = 0, OFDM_FA = 0, CCK_FA = 0, vht_ok = 0, vht_err = 0;
11658 if (!rx_counter) {
11659 rtw_warn_on(1);
11660 return;
11661 }
11662 if (IS_HARDWARE_TYPE_JAGUAR(padapter) || IS_HARDWARE_TYPE_JAGUAR2(padapter)) {
11663 cckok = phy_query_bb_reg(padapter, 0xF04, 0x3FFF); /* [13:0] */
11664 ofdmok = phy_query_bb_reg(padapter, 0xF14, 0x3FFF); /* [13:0] */
11665 htok = phy_query_bb_reg(padapter, 0xF10, 0x3FFF); /* [13:0] */
11666 vht_ok = phy_query_bb_reg(padapter, 0xF0C, 0x3FFF); /* [13:0] */
11667 cckcrc = phy_query_bb_reg(padapter, 0xF04, 0x3FFF0000); /* [29:16] */
11668 ofdmcrc = phy_query_bb_reg(padapter, 0xF14, 0x3FFF0000); /* [29:16] */
11669 htcrc = phy_query_bb_reg(padapter, 0xF10, 0x3FFF0000); /* [29:16] */
11670 vht_err = phy_query_bb_reg(padapter, 0xF0C, 0x3FFF0000); /* [29:16] */
11671 CCK_FA = phy_query_bb_reg(padapter, 0xA5C, bMaskLWord);
11672 OFDM_FA = phy_query_bb_reg(padapter, 0xF48, bMaskLWord);
11673 } else {
11674 cckok = phy_query_bb_reg(padapter, 0xF88, bMaskDWord);
11675 ofdmok = phy_query_bb_reg(padapter, 0xF94, bMaskLWord);
11676 htok = phy_query_bb_reg(padapter, 0xF90, bMaskLWord);
11677 vht_ok = 0;
11678 cckcrc = phy_query_bb_reg(padapter, 0xF84, bMaskDWord);
11679 ofdmcrc = phy_query_bb_reg(padapter, 0xF94, bMaskHWord);
11680 htcrc = phy_query_bb_reg(padapter, 0xF90, bMaskHWord);
11681 vht_err = 0;
11682 OFDM_FA = phy_query_bb_reg(padapter, 0xCF0, bMaskLWord) + phy_query_bb_reg(padapter, 0xCF2, bMaskLWord) +
11683 phy_query_bb_reg(padapter, 0xDA2, bMaskLWord) + phy_query_bb_reg(padapter, 0xDA4, bMaskLWord) +
11684 phy_query_bb_reg(padapter, 0xDA6, bMaskLWord) + phy_query_bb_reg(padapter, 0xDA8, bMaskLWord);
11685
11686 CCK_FA = (rtw_read8(padapter, 0xA5B) << 8) | (rtw_read8(padapter, 0xA5C));
11687 }
11688
11689 rx_counter->rx_pkt_ok = cckok + ofdmok + htok + vht_ok;
11690 rx_counter->rx_pkt_crc_error = cckcrc + ofdmcrc + htcrc + vht_err;
11691 rx_counter->rx_ofdm_fa = OFDM_FA;
11692 rx_counter->rx_cck_fa = CCK_FA;
11693
11694 }
11695
rtw_reset_phy_trx_ok_counters(_adapter * padapter)11696 void rtw_reset_phy_trx_ok_counters(_adapter *padapter)
11697 {
11698 if (IS_HARDWARE_TYPE_JAGUAR(padapter) || IS_HARDWARE_TYPE_JAGUAR2(padapter)) {
11699 phy_set_bb_reg(padapter, 0xB58, BIT0, 0x1);
11700 phy_set_bb_reg(padapter, 0xB58, BIT0, 0x0);
11701 }
11702 }
rtw_reset_phy_rx_counters(_adapter * padapter)11703 void rtw_reset_phy_rx_counters(_adapter *padapter)
11704 {
11705 /* reset phy counter */
11706 if (IS_HARDWARE_TYPE_JAGUAR(padapter) || IS_HARDWARE_TYPE_JAGUAR2(padapter)) {
11707 rtw_reset_phy_trx_ok_counters(padapter);
11708
11709 phy_set_bb_reg(padapter, 0x9A4, BIT17, 0x1);/* reset OFDA FA counter */
11710 phy_set_bb_reg(padapter, 0x9A4, BIT17, 0x0);
11711
11712 phy_set_bb_reg(padapter, 0xA2C, BIT15, 0x0);/* reset CCK FA counter */
11713 phy_set_bb_reg(padapter, 0xA2C, BIT15, 0x1);
11714 } else {
11715 phy_set_bb_reg(padapter, 0xF14, BIT16, 0x1);
11716 rtw_msleep_os(10);
11717 phy_set_bb_reg(padapter, 0xF14, BIT16, 0x0);
11718
11719 phy_set_bb_reg(padapter, 0xD00, BIT27, 0x1);/* reset OFDA FA counter */
11720 phy_set_bb_reg(padapter, 0xC0C, BIT31, 0x1);/* reset OFDA FA counter */
11721 phy_set_bb_reg(padapter, 0xD00, BIT27, 0x0);
11722 phy_set_bb_reg(padapter, 0xC0C, BIT31, 0x0);
11723
11724 phy_set_bb_reg(padapter, 0xA2C, BIT15, 0x0);/* reset CCK FA counter */
11725 phy_set_bb_reg(padapter, 0xA2C, BIT15, 0x1);
11726 }
11727 }
11728 #ifdef DBG_RX_COUNTER_DUMP
rtw_dump_drv_rx_counters(_adapter * padapter,struct dbg_rx_counter * rx_counter)11729 void rtw_dump_drv_rx_counters(_adapter *padapter, struct dbg_rx_counter *rx_counter)
11730 {
11731 struct recv_priv *precvpriv = &padapter->recvpriv;
11732 if (!rx_counter) {
11733 rtw_warn_on(1);
11734 return;
11735 }
11736 rx_counter->rx_pkt_ok = padapter->drv_rx_cnt_ok;
11737 rx_counter->rx_pkt_crc_error = padapter->drv_rx_cnt_crcerror;
11738 rx_counter->rx_pkt_drop = precvpriv->rx_drop - padapter->drv_rx_cnt_drop;
11739 }
rtw_reset_drv_rx_counters(_adapter * padapter)11740 void rtw_reset_drv_rx_counters(_adapter *padapter)
11741 {
11742 struct recv_priv *precvpriv = &padapter->recvpriv;
11743 padapter->drv_rx_cnt_ok = 0;
11744 padapter->drv_rx_cnt_crcerror = 0;
11745 padapter->drv_rx_cnt_drop = precvpriv->rx_drop;
11746 }
rtw_dump_phy_rxcnts_preprocess(_adapter * padapter,u8 rx_cnt_mode)11747 void rtw_dump_phy_rxcnts_preprocess(_adapter *padapter, u8 rx_cnt_mode)
11748 {
11749 u8 initialgain;
11750 HAL_DATA_TYPE *hal_data = GET_HAL_DATA(padapter);
11751
11752 if ((!(padapter->dump_rx_cnt_mode & DUMP_PHY_RX_COUNTER)) && (rx_cnt_mode & DUMP_PHY_RX_COUNTER)) {
11753 rtw_hal_get_odm_var(padapter, HAL_ODM_INITIAL_GAIN, &initialgain, NULL);
11754 RTW_INFO("%s CurIGValue:0x%02x\n", __FUNCTION__, initialgain);
11755 rtw_hal_set_odm_var(padapter, HAL_ODM_INITIAL_GAIN, &initialgain, _FALSE);
11756 /*disable dynamic functions, such as high power, DIG*/
11757 rtw_phydm_ability_backup(padapter);
11758 rtw_phydm_func_clr(padapter, (ODM_BB_DIG | ODM_BB_FA_CNT));
11759 } else if ((padapter->dump_rx_cnt_mode & DUMP_PHY_RX_COUNTER) && (!(rx_cnt_mode & DUMP_PHY_RX_COUNTER))) {
11760 /* turn on phy-dynamic functions */
11761 rtw_phydm_ability_restore(padapter);
11762 initialgain = 0xff; /* restore RX GAIN */
11763 rtw_hal_set_odm_var(padapter, HAL_ODM_INITIAL_GAIN, &initialgain, _FALSE);
11764
11765 }
11766 }
11767
rtw_dump_rx_counters(_adapter * padapter)11768 void rtw_dump_rx_counters(_adapter *padapter)
11769 {
11770 struct dbg_rx_counter rx_counter;
11771
11772 if (padapter->dump_rx_cnt_mode & DUMP_DRV_RX_COUNTER) {
11773 _rtw_memset(&rx_counter, 0, sizeof(struct dbg_rx_counter));
11774 rtw_dump_drv_rx_counters(padapter, &rx_counter);
11775 RTW_INFO("Drv Received packet OK:%d CRC error:%d Drop Packets: %d\n",
11776 rx_counter.rx_pkt_ok, rx_counter.rx_pkt_crc_error, rx_counter.rx_pkt_drop);
11777 rtw_reset_drv_rx_counters(padapter);
11778 }
11779
11780 if (padapter->dump_rx_cnt_mode & DUMP_MAC_RX_COUNTER) {
11781 _rtw_memset(&rx_counter, 0, sizeof(struct dbg_rx_counter));
11782 rtw_dump_mac_rx_counters(padapter, &rx_counter);
11783 RTW_INFO("Mac Received packet OK:%d CRC error:%d FA Counter: %d Drop Packets: %d\n",
11784 rx_counter.rx_pkt_ok, rx_counter.rx_pkt_crc_error,
11785 rx_counter.rx_cck_fa + rx_counter.rx_ofdm_fa + rx_counter.rx_ht_fa,
11786 rx_counter.rx_pkt_drop);
11787 rtw_reset_mac_rx_counters(padapter);
11788 }
11789
11790 if (padapter->dump_rx_cnt_mode & DUMP_PHY_RX_COUNTER) {
11791 _rtw_memset(&rx_counter, 0, sizeof(struct dbg_rx_counter));
11792 rtw_dump_phy_rx_counters(padapter, &rx_counter);
11793 /* RTW_INFO("%s: OFDM_FA =%d\n", __FUNCTION__, rx_counter.rx_ofdm_fa); */
11794 /* RTW_INFO("%s: CCK_FA =%d\n", __FUNCTION__, rx_counter.rx_cck_fa); */
11795 RTW_INFO("Phy Received packet OK:%d CRC error:%d FA Counter: %d\n", rx_counter.rx_pkt_ok, rx_counter.rx_pkt_crc_error,
11796 rx_counter.rx_ofdm_fa + rx_counter.rx_cck_fa);
11797 rtw_reset_phy_rx_counters(padapter);
11798 }
11799 }
11800 #endif
rtw_get_current_tx_sgi(_adapter * padapter,struct sta_info * psta)11801 u8 rtw_get_current_tx_sgi(_adapter *padapter, struct sta_info *psta)
11802 {
11803 u8 curr_tx_sgi = 0;
11804 struct ra_sta_info *ra_info;
11805
11806 if (!psta)
11807 return curr_tx_sgi;
11808
11809 ra_info = &psta->cmn.ra_info;
11810 curr_tx_sgi = ((ra_info->curr_tx_rate) & 0x80) >> 7;
11811
11812 return curr_tx_sgi;
11813 }
rtw_get_current_tx_rate(_adapter * padapter,struct sta_info * psta)11814 u8 rtw_get_current_tx_rate(_adapter *padapter, struct sta_info *psta)
11815 {
11816 u8 rate_id = 0;
11817 struct ra_sta_info *ra_info;
11818
11819 if (!psta)
11820 return rate_id;
11821
11822 ra_info = &psta->cmn.ra_info;
11823 rate_id = ra_info->curr_tx_rate & 0x7f;
11824
11825 return rate_id;
11826 }
11827
update_IOT_info(_adapter * padapter)11828 void update_IOT_info(_adapter *padapter)
11829 {
11830 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
11831 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
11832
11833 switch (pmlmeinfo->assoc_AP_vendor) {
11834 case HT_IOT_PEER_MARVELL:
11835 pmlmeinfo->turboMode_cts2self = 1;
11836 pmlmeinfo->turboMode_rtsen = 0;
11837 break;
11838
11839 case HT_IOT_PEER_RALINK:
11840 pmlmeinfo->turboMode_cts2self = 0;
11841 pmlmeinfo->turboMode_rtsen = 1;
11842 break;
11843 case HT_IOT_PEER_REALTEK:
11844 /* rtw_write16(padapter, 0x4cc, 0xffff); */
11845 /* rtw_write16(padapter, 0x546, 0x01c0); */
11846 break;
11847 default:
11848 pmlmeinfo->turboMode_cts2self = 0;
11849 pmlmeinfo->turboMode_rtsen = 1;
11850 break;
11851 }
11852
11853 }
11854
11855 /* TODO: merge with phydm, see odm_SetCrystalCap() */
hal_set_crystal_cap(_adapter * adapter,u8 crystal_cap)11856 void hal_set_crystal_cap(_adapter *adapter, u8 crystal_cap)
11857 {
11858 crystal_cap = crystal_cap & 0x3F;
11859
11860 switch (rtw_get_chip_type(adapter)) {
11861 #if defined(CONFIG_RTL8188E) || defined(CONFIG_RTL8188F)
11862 case RTL8188E:
11863 case RTL8188F:
11864 /* write 0x24[16:11] = 0x24[22:17] = CrystalCap */
11865 phy_set_bb_reg(adapter, REG_AFE_XTAL_CTRL, 0x007FF800, (crystal_cap | (crystal_cap << 6)));
11866 break;
11867 #endif
11868 #if defined(CONFIG_RTL8812A)
11869 case RTL8812:
11870 /* write 0x2C[30:25] = 0x2C[24:19] = CrystalCap */
11871 phy_set_bb_reg(adapter, REG_MAC_PHY_CTRL, 0x7FF80000, (crystal_cap | (crystal_cap << 6)));
11872 break;
11873 #endif
11874 #if defined(CONFIG_RTL8723B) || defined(CONFIG_RTL8703B) || \
11875 defined(CONFIG_RTL8723D) || defined(CONFIG_RTL8821A) || \
11876 defined(CONFIG_RTL8192E)
11877 case RTL8723B:
11878 case RTL8703B:
11879 case RTL8723D:
11880 case RTL8821:
11881 case RTL8192E:
11882 /* write 0x2C[23:18] = 0x2C[17:12] = CrystalCap */
11883 phy_set_bb_reg(adapter, REG_MAC_PHY_CTRL, 0x00FFF000, (crystal_cap | (crystal_cap << 6)));
11884 break;
11885 #endif
11886 #if defined(CONFIG_RTL8814A)
11887 case RTL8814A:
11888 /* write 0x2C[26:21] = 0x2C[20:15] = CrystalCap*/
11889 phy_set_bb_reg(adapter, REG_MAC_PHY_CTRL, 0x07FF8000, (crystal_cap | (crystal_cap << 6)));
11890 break;
11891 #endif
11892 #if defined(CONFIG_RTL8822B) || defined(CONFIG_RTL8821C)
11893
11894 case RTL8822B:
11895 case RTL8821C:
11896 /* write 0x28[6:1] = 0x24[30:25] = CrystalCap */
11897 crystal_cap = crystal_cap & 0x3F;
11898 phy_set_bb_reg(adapter, REG_AFE_XTAL_CTRL, 0x7E000000, crystal_cap);
11899 phy_set_bb_reg(adapter, REG_AFE_PLL_CTRL, 0x7E, crystal_cap);
11900 break;
11901 #endif
11902 default:
11903 rtw_warn_on(1);
11904 }
11905 }
11906
hal_spec_init(_adapter * adapter)11907 int hal_spec_init(_adapter *adapter)
11908 {
11909 u8 interface_type = 0;
11910 int ret = _SUCCESS;
11911
11912 interface_type = rtw_get_intf_type(adapter);
11913
11914 switch (rtw_get_chip_type(adapter)) {
11915 #ifdef CONFIG_RTL8723B
11916 case RTL8723B:
11917 init_hal_spec_8723b(adapter);
11918 break;
11919 #endif
11920 #ifdef CONFIG_RTL8703B
11921 case RTL8703B:
11922 init_hal_spec_8703b(adapter);
11923 break;
11924 #endif
11925 #ifdef CONFIG_RTL8723D
11926 case RTL8723D:
11927 init_hal_spec_8723d(adapter);
11928 break;
11929 #endif
11930 #ifdef CONFIG_RTL8188E
11931 case RTL8188E:
11932 init_hal_spec_8188e(adapter);
11933 break;
11934 #endif
11935 #ifdef CONFIG_RTL8188F
11936 case RTL8188F:
11937 init_hal_spec_8188f(adapter);
11938 break;
11939 #endif
11940 #ifdef CONFIG_RTL8812A
11941 case RTL8812:
11942 init_hal_spec_8812a(adapter);
11943 break;
11944 #endif
11945 #ifdef CONFIG_RTL8821A
11946 case RTL8821:
11947 init_hal_spec_8821a(adapter);
11948 break;
11949 #endif
11950 #ifdef CONFIG_RTL8192E
11951 case RTL8192E:
11952 init_hal_spec_8192e(adapter);
11953 break;
11954 #endif
11955 #ifdef CONFIG_RTL8814A
11956 case RTL8814A:
11957 init_hal_spec_8814a(adapter);
11958 break;
11959 #endif
11960 #ifdef CONFIG_RTL8822B
11961 case RTL8822B:
11962 rtl8822b_init_hal_spec(adapter);
11963 break;
11964 #endif
11965 #ifdef CONFIG_RTL8821C
11966 case RTL8821C:
11967 init_hal_spec_rtl8821c(adapter);
11968 break;
11969 #endif
11970 default:
11971 RTW_ERR("%s: unknown chip_type:%u\n"
11972 , __func__, rtw_get_chip_type(adapter));
11973 ret = _FAIL;
11974 break;
11975 }
11976
11977 return ret;
11978 }
11979
11980 static const char *const _band_cap_str[] = {
11981 /* BIT0 */"2G",
11982 /* BIT1 */"5G",
11983 };
11984
11985 static const char *const _bw_cap_str[] = {
11986 /* BIT0 */"5M",
11987 /* BIT1 */"10M",
11988 /* BIT2 */"20M",
11989 /* BIT3 */"40M",
11990 /* BIT4 */"80M",
11991 /* BIT5 */"160M",
11992 /* BIT6 */"80_80M",
11993 };
11994
11995 static const char *const _proto_cap_str[] = {
11996 /* BIT0 */"b",
11997 /* BIT1 */"g",
11998 /* BIT2 */"n",
11999 /* BIT3 */"ac",
12000 };
12001
12002 static const char *const _wl_func_str[] = {
12003 /* BIT0 */"P2P",
12004 /* BIT1 */"MIRACAST",
12005 /* BIT2 */"TDLS",
12006 /* BIT3 */"FTM",
12007 };
12008
dump_hal_spec(void * sel,_adapter * adapter)12009 void dump_hal_spec(void *sel, _adapter *adapter)
12010 {
12011 struct hal_spec_t *hal_spec = GET_HAL_SPEC(adapter);
12012 int i;
12013
12014 RTW_PRINT_SEL(sel, "macid_num:%u\n", hal_spec->macid_num);
12015 RTW_PRINT_SEL(sel, "sec_cap:0x%02x\n", hal_spec->sec_cap);
12016 RTW_PRINT_SEL(sel, "sec_cam_ent_num:%u\n", hal_spec->sec_cam_ent_num);
12017 RTW_PRINT_SEL(sel, "rfpath_num_2g:%u\n", hal_spec->rfpath_num_2g);
12018 RTW_PRINT_SEL(sel, "rfpath_num_5g:%u\n", hal_spec->rfpath_num_5g);
12019 RTW_PRINT_SEL(sel, "max_tx_cnt:%u\n", hal_spec->max_tx_cnt);
12020 RTW_PRINT_SEL(sel, "tx_nss_num:%u\n", hal_spec->tx_nss_num);
12021 RTW_PRINT_SEL(sel, "rx_nss_num:%u\n", hal_spec->rx_nss_num);
12022
12023 RTW_PRINT_SEL(sel, "band_cap:");
12024 for (i = 0; i < BAND_CAP_BIT_NUM; i++) {
12025 if (((hal_spec->band_cap) >> i) & BIT0 && _band_cap_str[i])
12026 _RTW_PRINT_SEL(sel, "%s ", _band_cap_str[i]);
12027 }
12028 _RTW_PRINT_SEL(sel, "\n");
12029
12030 RTW_PRINT_SEL(sel, "bw_cap:");
12031 for (i = 0; i < BW_CAP_BIT_NUM; i++) {
12032 if (((hal_spec->bw_cap) >> i) & BIT0 && _bw_cap_str[i])
12033 _RTW_PRINT_SEL(sel, "%s ", _bw_cap_str[i]);
12034 }
12035 _RTW_PRINT_SEL(sel, "\n");
12036
12037 RTW_PRINT_SEL(sel, "proto_cap:");
12038 for (i = 0; i < PROTO_CAP_BIT_NUM; i++) {
12039 if (((hal_spec->proto_cap) >> i) & BIT0 && _proto_cap_str[i])
12040 _RTW_PRINT_SEL(sel, "%s ", _proto_cap_str[i]);
12041 }
12042 _RTW_PRINT_SEL(sel, "\n");
12043
12044 RTW_PRINT_SEL(sel, "wl_func:");
12045 for (i = 0; i < WL_FUNC_BIT_NUM; i++) {
12046 if (((hal_spec->wl_func) >> i) & BIT0 && _wl_func_str[i])
12047 _RTW_PRINT_SEL(sel, "%s ", _wl_func_str[i]);
12048 }
12049 _RTW_PRINT_SEL(sel, "\n");
12050 }
12051
hal_chk_band_cap(_adapter * adapter,u8 cap)12052 inline bool hal_chk_band_cap(_adapter *adapter, u8 cap)
12053 {
12054 return GET_HAL_SPEC(adapter)->band_cap & cap;
12055 }
12056
hal_chk_bw_cap(_adapter * adapter,u8 cap)12057 inline bool hal_chk_bw_cap(_adapter *adapter, u8 cap)
12058 {
12059 return GET_HAL_SPEC(adapter)->bw_cap & cap;
12060 }
12061
hal_chk_proto_cap(_adapter * adapter,u8 cap)12062 inline bool hal_chk_proto_cap(_adapter *adapter, u8 cap)
12063 {
12064 return GET_HAL_SPEC(adapter)->proto_cap & cap;
12065 }
12066
hal_chk_wl_func(_adapter * adapter,u8 func)12067 inline bool hal_chk_wl_func(_adapter *adapter, u8 func)
12068 {
12069 return GET_HAL_SPEC(adapter)->wl_func & func;
12070 }
12071
hal_is_band_support(_adapter * adapter,u8 band)12072 inline bool hal_is_band_support(_adapter *adapter, u8 band)
12073 {
12074 return GET_HAL_SPEC(adapter)->band_cap & band_to_band_cap(band);
12075 }
12076
hal_is_bw_support(_adapter * adapter,u8 bw)12077 inline bool hal_is_bw_support(_adapter *adapter, u8 bw)
12078 {
12079 return GET_HAL_SPEC(adapter)->bw_cap & ch_width_to_bw_cap(bw);
12080 }
12081
hal_is_wireless_mode_support(_adapter * adapter,u8 mode)12082 inline bool hal_is_wireless_mode_support(_adapter *adapter, u8 mode)
12083 {
12084 u8 proto_cap = GET_HAL_SPEC(adapter)->proto_cap;
12085
12086 if (mode == WIRELESS_11B)
12087 if ((proto_cap & PROTO_CAP_11B) && hal_chk_band_cap(adapter, BAND_CAP_2G))
12088 return 1;
12089
12090 if (mode == WIRELESS_11G)
12091 if ((proto_cap & PROTO_CAP_11G) && hal_chk_band_cap(adapter, BAND_CAP_2G))
12092 return 1;
12093
12094 if (mode == WIRELESS_11A)
12095 if ((proto_cap & PROTO_CAP_11G) && hal_chk_band_cap(adapter, BAND_CAP_5G))
12096 return 1;
12097
12098 if (mode == WIRELESS_11_24N)
12099 if ((proto_cap & PROTO_CAP_11N) && hal_chk_band_cap(adapter, BAND_CAP_2G))
12100 return 1;
12101
12102 if (mode == WIRELESS_11_5N)
12103 if ((proto_cap & PROTO_CAP_11N) && hal_chk_band_cap(adapter, BAND_CAP_5G))
12104 return 1;
12105
12106 if (mode == WIRELESS_11AC)
12107 if ((proto_cap & PROTO_CAP_11AC) && hal_chk_band_cap(adapter, BAND_CAP_5G))
12108 return 1;
12109
12110 return 0;
12111 }
12112
12113 /*
12114 * hal_largest_bw - starting from in_bw, get largest bw supported by HAL
12115 * @adapter:
12116 * @in_bw: starting bw, value of enum channel_width
12117 *
12118 * Returns: value of enum channel_width
12119 */
hal_largest_bw(_adapter * adapter,u8 in_bw)12120 u8 hal_largest_bw(_adapter *adapter, u8 in_bw)
12121 {
12122 for (; in_bw > CHANNEL_WIDTH_20; in_bw--) {
12123 if (hal_is_bw_support(adapter, in_bw))
12124 break;
12125 }
12126
12127 if (!hal_is_bw_support(adapter, in_bw))
12128 rtw_warn_on(1);
12129
12130 return in_bw;
12131 }
12132
rtw_hal_correct_tsf(_adapter * padapter,u8 hw_port,u64 tsf)12133 void rtw_hal_correct_tsf(_adapter *padapter, u8 hw_port, u64 tsf)
12134 {
12135 if (hw_port == HW_PORT0) {
12136 /*disable related TSF function*/
12137 rtw_write8(padapter, REG_BCN_CTRL, rtw_read8(padapter, REG_BCN_CTRL) & (~EN_BCN_FUNCTION));
12138
12139 rtw_write32(padapter, REG_TSFTR, tsf);
12140 rtw_write32(padapter, REG_TSFTR + 4, tsf >> 32);
12141
12142 /*enable related TSF function*/
12143 rtw_write8(padapter, REG_BCN_CTRL, rtw_read8(padapter, REG_BCN_CTRL) | EN_BCN_FUNCTION);
12144 } else if (hw_port == HW_PORT1) {
12145 /*disable related TSF function*/
12146 rtw_write8(padapter, REG_BCN_CTRL_1, rtw_read8(padapter, REG_BCN_CTRL_1) & (~EN_BCN_FUNCTION));
12147
12148 rtw_write32(padapter, REG_TSFTR1, tsf);
12149 rtw_write32(padapter, REG_TSFTR1 + 4, tsf >> 32);
12150
12151 /*enable related TSF function*/
12152 rtw_write8(padapter, REG_BCN_CTRL_1, rtw_read8(padapter, REG_BCN_CTRL_1) | EN_BCN_FUNCTION);
12153 } else
12154 RTW_INFO("%s-[WARN] "ADPT_FMT" invalid hw_port:%d\n", __func__, ADPT_ARG(padapter), hw_port);
12155 }
12156
ResumeTxBeacon(_adapter * padapter)12157 void ResumeTxBeacon(_adapter *padapter)
12158 {
12159 #ifdef CONFIG_MI_WITH_MBSSID_CAM
12160 #else
12161 rtw_write8(padapter, REG_FWHW_TXQ_CTRL + 2,
12162 rtw_read8(padapter, REG_FWHW_TXQ_CTRL + 2) | BIT(6));
12163
12164 #ifdef RTW_HALMAC
12165 /* Add this for driver using HALMAC because driver doesn't have setup time init by self */
12166 /* TBTT setup time */
12167 rtw_write8(padapter, REG_TBTT_PROHIBIT, TBTT_PROHIBIT_SETUP_TIME);
12168 #endif
12169
12170 /* TBTT hold time: 0x540[19:8] */
12171 rtw_write8(padapter, REG_TBTT_PROHIBIT + 1, TBTT_PROHIBIT_HOLD_TIME & 0xFF);
12172 rtw_write8(padapter, REG_TBTT_PROHIBIT + 2,
12173 (rtw_read8(padapter, REG_TBTT_PROHIBIT + 2) & 0xF0) | (TBTT_PROHIBIT_HOLD_TIME >> 8));
12174 #endif
12175 }
12176
StopTxBeacon(_adapter * padapter)12177 void StopTxBeacon(_adapter *padapter)
12178 {
12179 #ifdef CONFIG_MI_WITH_MBSSID_CAM
12180 #else
12181 rtw_write8(padapter, REG_FWHW_TXQ_CTRL + 2,
12182 rtw_read8(padapter, REG_FWHW_TXQ_CTRL + 2) & (~BIT6));
12183
12184 /* TBTT hold time: 0x540[19:8] */
12185 rtw_write8(padapter, REG_TBTT_PROHIBIT + 1, TBTT_PROHIBIT_HOLD_TIME_STOP_BCN & 0xFF);
12186 rtw_write8(padapter, REG_TBTT_PROHIBIT + 2,
12187 (rtw_read8(padapter, REG_TBTT_PROHIBIT + 2) & 0xF0) | (TBTT_PROHIBIT_HOLD_TIME_STOP_BCN >> 8));
12188 #endif
12189 }
12190
12191 #ifdef CONFIG_MI_WITH_MBSSID_CAM /*HW port0 - MBSS*/
hw_var_set_opmode_mbid(_adapter * Adapter,u8 mode)12192 void hw_var_set_opmode_mbid(_adapter *Adapter, u8 mode)
12193 {
12194 RTW_INFO("%s()-"ADPT_FMT" mode = %d\n", __func__, ADPT_ARG(Adapter), mode);
12195
12196 rtw_hal_rcr_set_chk_bssid(Adapter, MLME_ACTION_NONE);
12197
12198 /* disable Port0 TSF update*/
12199 rtw_write8(Adapter, REG_BCN_CTRL, rtw_read8(Adapter, REG_BCN_CTRL) | DIS_TSF_UDT);
12200
12201 /* set net_type */
12202 Set_MSR(Adapter, mode);
12203
12204 if ((mode == _HW_STATE_STATION_) || (mode == _HW_STATE_NOLINK_)) {
12205 if (!rtw_mi_get_ap_num(Adapter) && !rtw_mi_get_mesh_num(Adapter))
12206 StopTxBeacon(Adapter);
12207
12208 rtw_write8(Adapter, REG_BCN_CTRL, DIS_TSF_UDT | EN_BCN_FUNCTION | DIS_ATIM);/*disable atim wnd*/
12209 } else if (mode == _HW_STATE_ADHOC_) {
12210 ResumeTxBeacon(Adapter);
12211 rtw_write8(Adapter, REG_BCN_CTRL, DIS_TSF_UDT | EN_BCN_FUNCTION | DIS_BCNQ_SUB);
12212
12213 } else if (mode == _HW_STATE_AP_) {
12214 ResumeTxBeacon(Adapter);
12215
12216 rtw_write8(Adapter, REG_BCN_CTRL, DIS_TSF_UDT | DIS_BCNQ_SUB);
12217
12218 /*enable to rx data frame*/
12219 rtw_write16(Adapter, REG_RXFLTMAP2, 0xFFFF);
12220
12221 /*Beacon Control related register for first time*/
12222 rtw_write8(Adapter, REG_BCNDMATIM, 0x02); /* 2ms */
12223
12224 /*rtw_write8(Adapter, REG_BCN_MAX_ERR, 0xFF);*/
12225 rtw_write8(Adapter, REG_ATIMWND, 0x0c); /* 12ms */
12226 rtw_write16(Adapter, REG_BCNTCFG, 0x00);
12227
12228 rtw_write16(Adapter, REG_TSFTR_SYN_OFFSET, 0x7fff);/* +32767 (~32ms) */
12229
12230 /*reset TSF*/
12231 rtw_write8(Adapter, REG_DUAL_TSF_RST, BIT(0));
12232
12233 /*enable BCN0 Function for if1*/
12234 /*don't enable update TSF0 for if1 (due to TSF update when beacon,probe rsp are received)*/
12235 rtw_write8(Adapter, REG_BCN_CTRL, (DIS_TSF_UDT | EN_BCN_FUNCTION | EN_TXBCN_RPT | DIS_BCNQ_SUB));
12236 #ifdef CONFIG_BCN_XMIT_PROTECT
12237 rtw_write8(Adapter, REG_CCK_CHECK, rtw_read8(Adapter, REG_CCK_CHECK) | BIT_EN_BCN_PKT_REL);
12238 #endif
12239
12240 if (IS_HARDWARE_TYPE_8821(Adapter) || IS_HARDWARE_TYPE_8192E(Adapter))/* select BCN on port 0 for DualBeacon*/
12241 rtw_write8(Adapter, REG_CCK_CHECK, rtw_read8(Adapter, REG_CCK_CHECK) & (~BIT_BCN_PORT_SEL));
12242
12243 }
12244
12245 }
12246 #endif
12247
12248 #ifdef CONFIG_ANTENNA_DIVERSITY
rtw_hal_antdiv_before_linked(_adapter * padapter)12249 u8 rtw_hal_antdiv_before_linked(_adapter *padapter)
12250 {
12251 HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);
12252 u8 cur_ant, change_ant;
12253
12254 if (!pHalData->AntDivCfg)
12255 return _FALSE;
12256
12257 if (pHalData->sw_antdiv_bl_state == 0) {
12258 pHalData->sw_antdiv_bl_state = 1;
12259
12260 rtw_hal_get_odm_var(padapter, HAL_ODM_ANTDIV_SELECT, &cur_ant, NULL);
12261 change_ant = (cur_ant == MAIN_ANT) ? AUX_ANT : MAIN_ANT;
12262
12263 return rtw_antenna_select_cmd(padapter, change_ant, _FALSE);
12264 }
12265
12266 pHalData->sw_antdiv_bl_state = 0;
12267 return _FALSE;
12268 }
12269
rtw_hal_antdiv_rssi_compared(_adapter * padapter,WLAN_BSSID_EX * dst,WLAN_BSSID_EX * src)12270 void rtw_hal_antdiv_rssi_compared(_adapter *padapter, WLAN_BSSID_EX *dst, WLAN_BSSID_EX *src)
12271 {
12272 HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);
12273
12274 if (pHalData->AntDivCfg) {
12275 /*RTW_INFO("update_network=> org-RSSI(%d), new-RSSI(%d)\n", dst->Rssi, src->Rssi);*/
12276 /*select optimum_antenna for before linked =>For antenna diversity*/
12277 if (dst->Rssi >= src->Rssi) {/*keep org parameter*/
12278 src->Rssi = dst->Rssi;
12279 src->PhyInfo.Optimum_antenna = dst->PhyInfo.Optimum_antenna;
12280 }
12281 }
12282 }
12283 #endif
12284
12285 #ifdef CONFIG_PHY_CAPABILITY_QUERY
rtw_dump_phy_cap_by_phydmapi(void * sel,_adapter * adapter)12286 void rtw_dump_phy_cap_by_phydmapi(void *sel, _adapter *adapter)
12287 {
12288 HAL_DATA_TYPE *pHalData = GET_HAL_DATA(adapter);
12289 struct phy_spec_t *phy_spec = &pHalData->phy_spec;
12290
12291 RTW_PRINT_SEL(sel, "[PHY SPEC] TRx Capability : 0x%08x\n", phy_spec->trx_cap);
12292 RTW_PRINT_SEL(sel, "[PHY SPEC] Tx Stream Num Index : %d\n", (phy_spec->trx_cap >> 24) & 0xFF); /*Tx Stream Num Index [31:24]*/
12293 RTW_PRINT_SEL(sel, "[PHY SPEC] Rx Stream Num Index : %d\n", (phy_spec->trx_cap >> 16) & 0xFF); /*Rx Stream Num Index [23:16]*/
12294 RTW_PRINT_SEL(sel, "[PHY SPEC] Tx Path Num Index : %d\n", (phy_spec->trx_cap >> 8) & 0xFF);/*Tx Path Num Index [15:8]*/
12295 RTW_PRINT_SEL(sel, "[PHY SPEC] Rx Path Num Index : %d\n\n", (phy_spec->trx_cap & 0xFF));/*Rx Path Num Index [7:0]*/
12296
12297 RTW_PRINT_SEL(sel, "[PHY SPEC] STBC Capability : 0x%08x\n", phy_spec->stbc_cap);
12298 RTW_PRINT_SEL(sel, "[PHY SPEC] VHT STBC Tx : %s\n", ((phy_spec->stbc_cap >> 24) & 0xFF) ? "Supported" : "N/A"); /*VHT STBC Tx [31:24]*/
12299 /*VHT STBC Rx [23:16]
12300 0 = not support
12301 1 = support for 1 spatial stream
12302 2 = support for 1 or 2 spatial streams
12303 3 = support for 1 or 2 or 3 spatial streams
12304 4 = support for 1 or 2 or 3 or 4 spatial streams*/
12305 RTW_PRINT_SEL(sel, "[PHY SPEC] VHT STBC Rx :%d\n", ((phy_spec->stbc_cap >> 16) & 0xFF));
12306 RTW_PRINT_SEL(sel, "[PHY SPEC] HT STBC Tx : %s\n", ((phy_spec->stbc_cap >> 8) & 0xFF) ? "Supported" : "N/A"); /*HT STBC Tx [15:8]*/
12307 /*HT STBC Rx [7:0]
12308 0 = not support
12309 1 = support for 1 spatial stream
12310 2 = support for 1 or 2 spatial streams
12311 3 = support for 1 or 2 or 3 spatial streams*/
12312 RTW_PRINT_SEL(sel, "[PHY SPEC] HT STBC Rx : %d\n\n", (phy_spec->stbc_cap & 0xFF));
12313
12314 RTW_PRINT_SEL(sel, "[PHY SPEC] LDPC Capability : 0x%08x\n", phy_spec->ldpc_cap);
12315 RTW_PRINT_SEL(sel, "[PHY SPEC] VHT LDPC Tx : %s\n", ((phy_spec->ldpc_cap >> 24) & 0xFF) ? "Supported" : "N/A"); /*VHT LDPC Tx [31:24]*/
12316 RTW_PRINT_SEL(sel, "[PHY SPEC] VHT LDPC Rx : %s\n", ((phy_spec->ldpc_cap >> 16) & 0xFF) ? "Supported" : "N/A"); /*VHT LDPC Rx [23:16]*/
12317 RTW_PRINT_SEL(sel, "[PHY SPEC] HT LDPC Tx : %s\n", ((phy_spec->ldpc_cap >> 8) & 0xFF) ? "Supported" : "N/A"); /*HT LDPC Tx [15:8]*/
12318 RTW_PRINT_SEL(sel, "[PHY SPEC] HT LDPC Rx : %s\n\n", (phy_spec->ldpc_cap & 0xFF) ? "Supported" : "N/A"); /*HT LDPC Rx [7:0]*/
12319 #ifdef CONFIG_BEAMFORMING
12320 RTW_PRINT_SEL(sel, "[PHY SPEC] TxBF Capability : 0x%08x\n", phy_spec->txbf_cap);
12321 RTW_PRINT_SEL(sel, "[PHY SPEC] VHT MU Bfer : %s\n", ((phy_spec->txbf_cap >> 28) & 0xF) ? "Supported" : "N/A"); /*VHT MU Bfer [31:28]*/
12322 RTW_PRINT_SEL(sel, "[PHY SPEC] VHT MU Bfee : %s\n", ((phy_spec->txbf_cap >> 24) & 0xF) ? "Supported" : "N/A"); /*VHT MU Bfee [27:24]*/
12323 RTW_PRINT_SEL(sel, "[PHY SPEC] VHT SU Bfer : %s\n", ((phy_spec->txbf_cap >> 20) & 0xF) ? "Supported" : "N/A"); /*VHT SU Bfer [23:20]*/
12324 RTW_PRINT_SEL(sel, "[PHY SPEC] VHT SU Bfee : %s\n", ((phy_spec->txbf_cap >> 16) & 0xF) ? "Supported" : "N/A"); /*VHT SU Bfee [19:16]*/
12325 RTW_PRINT_SEL(sel, "[PHY SPEC] HT Bfer : %s\n", ((phy_spec->txbf_cap >> 4) & 0xF) ? "Supported" : "N/A"); /*HT Bfer [7:4]*/
12326 RTW_PRINT_SEL(sel, "[PHY SPEC] HT Bfee : %s\n\n", (phy_spec->txbf_cap & 0xF) ? "Supported" : "N/A"); /*HT Bfee [3:0]*/
12327
12328 RTW_PRINT_SEL(sel, "[PHY SPEC] TxBF parameter : 0x%08x\n", phy_spec->txbf_param);
12329 RTW_PRINT_SEL(sel, "[PHY SPEC] VHT Sounding Dim : %d\n", (phy_spec->txbf_param >> 24) & 0xFF); /*VHT Sounding Dim [31:24]*/
12330 RTW_PRINT_SEL(sel, "[PHY SPEC] VHT Steering Ant : %d\n", (phy_spec->txbf_param >> 16) & 0xFF); /*VHT Steering Ant [23:16]*/
12331 RTW_PRINT_SEL(sel, "[PHY SPEC] HT Sounding Dim : %d\n", (phy_spec->txbf_param >> 8) & 0xFF); /*HT Sounding Dim [15:8]*/
12332 RTW_PRINT_SEL(sel, "[PHY SPEC] HT Steering Ant : %d\n", phy_spec->txbf_param & 0xFF); /*HT Steering Ant [7:0]*/
12333 #endif
12334 }
12335 #else
rtw_dump_phy_cap_by_hal(void * sel,_adapter * adapter)12336 void rtw_dump_phy_cap_by_hal(void *sel, _adapter *adapter)
12337 {
12338 u8 phy_cap = _FALSE;
12339
12340 /* STBC */
12341 rtw_hal_get_def_var(adapter, HAL_DEF_TX_STBC, (u8 *)&phy_cap);
12342 RTW_PRINT_SEL(sel, "[HAL] STBC Tx : %s\n", (_TRUE == phy_cap) ? "Supported" : "N/A");
12343
12344 phy_cap = _FALSE;
12345 rtw_hal_get_def_var(adapter, HAL_DEF_RX_STBC, (u8 *)&phy_cap);
12346 RTW_PRINT_SEL(sel, "[HAL] STBC Rx : %s\n\n", (_TRUE == phy_cap) ? "Supported" : "N/A");
12347
12348 /* LDPC support */
12349 phy_cap = _FALSE;
12350 rtw_hal_get_def_var(adapter, HAL_DEF_TX_LDPC, (u8 *)&phy_cap);
12351 RTW_PRINT_SEL(sel, "[HAL] LDPC Tx : %s\n", (_TRUE == phy_cap) ? "Supported" : "N/A");
12352
12353 phy_cap = _FALSE;
12354 rtw_hal_get_def_var(adapter, HAL_DEF_RX_LDPC, (u8 *)&phy_cap);
12355 RTW_PRINT_SEL(sel, "[HAL] LDPC Rx : %s\n\n", (_TRUE == phy_cap) ? "Supported" : "N/A");
12356
12357 #ifdef CONFIG_BEAMFORMING
12358 phy_cap = _FALSE;
12359 rtw_hal_get_def_var(adapter, HAL_DEF_EXPLICIT_BEAMFORMER, (u8 *)&phy_cap);
12360 RTW_PRINT_SEL(sel, "[HAL] Beamformer: %s\n", (_TRUE == phy_cap) ? "Supported" : "N/A");
12361
12362 phy_cap = _FALSE;
12363 rtw_hal_get_def_var(adapter, HAL_DEF_EXPLICIT_BEAMFORMEE, (u8 *)&phy_cap);
12364 RTW_PRINT_SEL(sel, "[HAL] Beamformee: %s\n", (_TRUE == phy_cap) ? "Supported" : "N/A");
12365
12366 phy_cap = _FALSE;
12367 rtw_hal_get_def_var(adapter, HAL_DEF_VHT_MU_BEAMFORMER, &phy_cap);
12368 RTW_PRINT_SEL(sel, "[HAL] VHT MU Beamformer: %s\n", (_TRUE == phy_cap) ? "Supported" : "N/A");
12369
12370 phy_cap = _FALSE;
12371 rtw_hal_get_def_var(adapter, HAL_DEF_VHT_MU_BEAMFORMEE, &phy_cap);
12372 RTW_PRINT_SEL(sel, "[HAL] VHT MU Beamformee: %s\n", (_TRUE == phy_cap) ? "Supported" : "N/A");
12373 #endif
12374 }
12375 #endif
rtw_dump_phy_cap(void * sel,_adapter * adapter)12376 void rtw_dump_phy_cap(void *sel, _adapter *adapter)
12377 {
12378 RTW_PRINT_SEL(sel, "\n ======== PHY Capability ========\n");
12379 #ifdef CONFIG_PHY_CAPABILITY_QUERY
12380 rtw_dump_phy_cap_by_phydmapi(sel, adapter);
12381 #else
12382 rtw_dump_phy_cap_by_hal(sel, adapter);
12383 #endif
12384 }
12385
translate_dbm_to_percentage(s16 signal)12386 inline s16 translate_dbm_to_percentage(s16 signal)
12387 {
12388 if ((signal <= -100) || (signal >= 20))
12389 return 0;
12390 else if (signal >= 0)
12391 return 100;
12392 else
12393 return 100 + signal;
12394 }
12395
12396 #ifdef CONFIG_SWTIMER_BASED_TXBCN
12397 #ifdef CONFIG_BCN_RECOVERY
12398 #define REG_CPU_MGQ_INFO 0x041C
12399 #define BIT_BCN_POLL BIT(28)
rtw_ap_bcn_recovery(_adapter * padapter)12400 u8 rtw_ap_bcn_recovery(_adapter *padapter)
12401 {
12402 HAL_DATA_TYPE *hal_data = GET_HAL_DATA(padapter);
12403
12404 if (hal_data->issue_bcn_fail >= 2) {
12405 RTW_ERR("%s ISSUE BCN Fail\n", __func__);
12406 rtw_write8(padapter, REG_CPU_MGQ_INFO + 3, 0x10);
12407 hal_data->issue_bcn_fail = 0;
12408 }
12409 return _SUCCESS;
12410 }
12411 #endif /*CONFIG_BCN_RECOVERY*/
12412
12413 #ifdef CONFIG_BCN_XMIT_PROTECT
rtw_ap_bcn_queue_empty_check(_adapter * padapter,u32 txbcn_timer_ms)12414 u8 rtw_ap_bcn_queue_empty_check(_adapter *padapter, u32 txbcn_timer_ms)
12415 {
12416 u32 start_time = rtw_get_current_time();
12417 u8 bcn_queue_empty = _FALSE;
12418
12419 do {
12420 if (rtw_read16(padapter, REG_TXPKT_EMPTY) & BIT(11)) {
12421 bcn_queue_empty = _TRUE;
12422 break;
12423 }
12424 } while (rtw_get_passing_time_ms(start_time) <= (txbcn_timer_ms + 10));
12425
12426 if (bcn_queue_empty == _FALSE)
12427 RTW_ERR("%s BCN queue not empty\n", __func__);
12428
12429 return bcn_queue_empty;
12430 }
12431 #endif /*CONFIG_BCN_XMIT_PROTECT*/
12432 #endif /*CONFIG_SWTIMER_BASED_TXBCN*/
12433