1 /******************************************************************************
2 *
3 * Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved.
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 * You should have received a copy of the GNU General Public License along with
15 * this program; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
17 *
18 *
19 ******************************************************************************/
20 #define _HAL_COM_C_
21
22 #include <drv_types.h>
23 #include "hal_com_h2c.h"
24
25 #include "hal_data.h"
26
27 /* #define CONFIG_GTK_OL_DBG */
28
29 /*#define DBG_SEC_CAM_MOVE*/
30 #ifdef DBG_SEC_CAM_MOVE
rtw_hal_move_sta_gk_to_dk(_adapter * adapter)31 void rtw_hal_move_sta_gk_to_dk(_adapter *adapter)
32 {
33 struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
34 int cam_id, index = 0;
35 u8 *addr = NULL;
36
37 if (check_fwstate(pmlmepriv, WIFI_AP_STATE) == _TRUE)
38 return;
39
40 addr = get_bssid(pmlmepriv);
41
42 if (addr == NULL) {
43 RTW_INFO("%s: get bssid MAC addr fail!!\n", __func__);
44 return;
45 }
46
47 rtw_clean_dk_section(adapter);
48
49 do {
50 cam_id = rtw_camid_search(adapter, addr, index, 1);
51
52 if (cam_id == -1)
53 RTW_INFO("%s: cam_id: %d, key_id:%d\n", __func__, cam_id, index);
54 else
55 rtw_sec_cam_swap(adapter, cam_id, index);
56
57 index++;
58 } while (index < 4);
59
60 }
61
rtw_hal_read_sta_dk_key(_adapter * adapter,u8 key_id)62 void rtw_hal_read_sta_dk_key(_adapter *adapter, u8 key_id)
63 {
64 struct security_priv *psecuritypriv = &adapter->securitypriv;
65 struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
66 struct cam_ctl_t *cam_ctl = &dvobj->cam_ctl;
67 _irqL irqL;
68 u8 get_key[16];
69
70 _rtw_memset(get_key, 0, sizeof(get_key));
71
72 if (key_id > 4) {
73 RTW_INFO("%s [ERROR] gtk_keyindex:%d invalid\n", __func__, key_id);
74 rtw_warn_on(1);
75 return;
76 }
77 rtw_sec_read_cam_ent(adapter, key_id, NULL, NULL, get_key);
78
79 /*update key into related sw variable*/
80 _enter_critical_bh(&cam_ctl->lock, &irqL);
81 if (_rtw_camid_is_gk(adapter, key_id)) {
82 RTW_INFO("[HW KEY] -Key-id:%d "KEY_FMT"\n", key_id, KEY_ARG(get_key));
83 RTW_INFO("[cam_cache KEY] - Key-id:%d "KEY_FMT"\n", key_id, KEY_ARG(&dvobj->cam_cache[key_id].key));
84 }
85 _exit_critical_bh(&cam_ctl->lock, &irqL);
86
87 }
88 #endif
89
90
91 #ifdef CONFIG_LOAD_PHY_PARA_FROM_FILE
92 char rtw_phy_para_file_path[PATH_LENGTH_MAX];
93 #endif
94
dump_chip_info(HAL_VERSION ChipVersion)95 void dump_chip_info(HAL_VERSION ChipVersion)
96 {
97 int cnt = 0;
98 u8 buf[128] = {0};
99
100 if (IS_8188E(ChipVersion))
101 cnt += sprintf((buf + cnt), "Chip Version Info: CHIP_8188E_");
102 else if (IS_8188F(ChipVersion))
103 cnt += sprintf((buf + cnt), "Chip Version Info: CHIP_8188F_");
104 else if (IS_8812_SERIES(ChipVersion))
105 cnt += sprintf((buf + cnt), "Chip Version Info: CHIP_8812_");
106 else if (IS_8192E(ChipVersion))
107 cnt += sprintf((buf + cnt), "Chip Version Info: CHIP_8192E_");
108 else if (IS_8821_SERIES(ChipVersion))
109 cnt += sprintf((buf + cnt), "Chip Version Info: CHIP_8821_");
110 else if (IS_8723B_SERIES(ChipVersion))
111 cnt += sprintf((buf + cnt), "Chip Version Info: CHIP_8723B_");
112 else if (IS_8703B_SERIES(ChipVersion))
113 cnt += sprintf((buf + cnt), "Chip Version Info: CHIP_8703B_");
114 else if (IS_8723D_SERIES(ChipVersion))
115 cnt += sprintf((buf + cnt), "Chip Version Info: CHIP_8723D_");
116 else if (IS_8814A_SERIES(ChipVersion))
117 cnt += sprintf((buf + cnt), "Chip Version Info: CHIP_8814A_");
118 else if (IS_8822B_SERIES(ChipVersion))
119 cnt += sprintf((buf + cnt), "Chip Version Info: CHIP_8822B_");
120 else if (IS_8821C_SERIES(ChipVersion))
121 cnt += sprintf((buf + cnt), "Chip Version Info: CHIP_8821C_");
122 else
123 cnt += sprintf((buf + cnt), "Chip Version Info: CHIP_UNKNOWN_");
124
125 cnt += sprintf((buf + cnt), "%s_", IS_NORMAL_CHIP(ChipVersion) ? "Normal_Chip" : "Test_Chip");
126 if (IS_CHIP_VENDOR_TSMC(ChipVersion))
127 cnt += sprintf((buf + cnt), "%s_", "TSMC");
128 else if (IS_CHIP_VENDOR_UMC(ChipVersion))
129 cnt += sprintf((buf + cnt), "%s_", "UMC");
130 else if (IS_CHIP_VENDOR_SMIC(ChipVersion))
131 cnt += sprintf((buf + cnt), "%s_", "SMIC");
132
133 if (IS_A_CUT(ChipVersion))
134 cnt += sprintf((buf + cnt), "A_CUT_");
135 else if (IS_B_CUT(ChipVersion))
136 cnt += sprintf((buf + cnt), "B_CUT_");
137 else if (IS_C_CUT(ChipVersion))
138 cnt += sprintf((buf + cnt), "C_CUT_");
139 else if (IS_D_CUT(ChipVersion))
140 cnt += sprintf((buf + cnt), "D_CUT_");
141 else if (IS_E_CUT(ChipVersion))
142 cnt += sprintf((buf + cnt), "E_CUT_");
143 else if (IS_F_CUT(ChipVersion))
144 cnt += sprintf((buf + cnt), "F_CUT_");
145 else if (IS_I_CUT(ChipVersion))
146 cnt += sprintf((buf + cnt), "I_CUT_");
147 else if (IS_J_CUT(ChipVersion))
148 cnt += sprintf((buf + cnt), "J_CUT_");
149 else if (IS_K_CUT(ChipVersion))
150 cnt += sprintf((buf + cnt), "K_CUT_");
151 else
152 cnt += sprintf((buf + cnt), "UNKNOWN_CUT(%d)_", ChipVersion.CUTVersion);
153
154 if (IS_1T1R(ChipVersion))
155 cnt += sprintf((buf + cnt), "1T1R_");
156 else if (IS_1T2R(ChipVersion))
157 cnt += sprintf((buf + cnt), "1T2R_");
158 else if (IS_2T2R(ChipVersion))
159 cnt += sprintf((buf + cnt), "2T2R_");
160 else if (IS_3T3R(ChipVersion))
161 cnt += sprintf((buf + cnt), "3T3R_");
162 else if (IS_3T4R(ChipVersion))
163 cnt += sprintf((buf + cnt), "3T4R_");
164 else if (IS_4T4R(ChipVersion))
165 cnt += sprintf((buf + cnt), "4T4R_");
166 else
167 cnt += sprintf((buf + cnt), "UNKNOWN_RFTYPE(%d)_", ChipVersion.RFType);
168
169 cnt += sprintf((buf + cnt), "RomVer(%d)\n", ChipVersion.ROMVer);
170
171 RTW_INFO("%s", buf);
172 }
rtw_hal_config_rftype(PADAPTER padapter)173 void rtw_hal_config_rftype(PADAPTER padapter)
174 {
175 HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);
176
177 if (IS_1T1R(pHalData->VersionID)) {
178 pHalData->rf_type = RF_1T1R;
179 pHalData->NumTotalRFPath = 1;
180 } else if (IS_2T2R(pHalData->VersionID)) {
181 pHalData->rf_type = RF_2T2R;
182 pHalData->NumTotalRFPath = 2;
183 } else if (IS_1T2R(pHalData->VersionID)) {
184 pHalData->rf_type = RF_1T2R;
185 pHalData->NumTotalRFPath = 2;
186 } else if (IS_3T3R(pHalData->VersionID)) {
187 pHalData->rf_type = RF_3T3R;
188 pHalData->NumTotalRFPath = 3;
189 } else if (IS_4T4R(pHalData->VersionID)) {
190 pHalData->rf_type = RF_4T4R;
191 pHalData->NumTotalRFPath = 4;
192 } else {
193 pHalData->rf_type = RF_1T1R;
194 pHalData->NumTotalRFPath = 1;
195 }
196
197 RTW_INFO("%s RF_Type is %d TotalTxPath is %d\n", __FUNCTION__, pHalData->rf_type, pHalData->NumTotalRFPath);
198 }
199
200 #define EEPROM_CHANNEL_PLAN_BY_HW_MASK 0x80
201
202 /*
203 * Description:
204 * Use hardware(efuse), driver parameter(registry) and default channel plan
205 * to decide which one should be used.
206 *
207 * Parameters:
208 * padapter pointer of adapter
209 * hw_alpha2 country code from HW (efuse/eeprom/mapfile)
210 * hw_chplan channel plan from HW (efuse/eeprom/mapfile)
211 * BIT[7] software configure mode; 0:Enable, 1:disable
212 * BIT[6:0] Channel Plan
213 * sw_alpha2 country code from HW (registry/module param)
214 * sw_chplan channel plan from SW (registry/module param)
215 * def_chplan channel plan used when HW/SW both invalid
216 * AutoLoadFail efuse autoload fail or not
217 *
218 * Return:
219 * Final channel plan decision
220 *
221 */
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)222 u8 hal_com_config_channel_plan(
223 IN PADAPTER padapter,
224 IN char *hw_alpha2,
225 IN u8 hw_chplan,
226 IN char *sw_alpha2,
227 IN u8 sw_chplan,
228 IN u8 def_chplan,
229 IN BOOLEAN AutoLoadFail
230 )
231 {
232 PHAL_DATA_TYPE pHalData;
233 u8 force_hw_chplan = _FALSE;
234 int chplan = -1;
235 const struct country_chplan *country_ent = NULL, *ent;
236
237 pHalData = GET_HAL_DATA(padapter);
238
239 /* treat 0xFF as invalid value, bypass hw_chplan & force_hw_chplan parsing */
240 if (hw_chplan == 0xFF)
241 goto chk_hw_country_code;
242
243 if (AutoLoadFail == _TRUE)
244 goto chk_sw_config;
245
246 #ifndef CONFIG_FORCE_SW_CHANNEL_PLAN
247 if (hw_chplan & EEPROM_CHANNEL_PLAN_BY_HW_MASK)
248 force_hw_chplan = _TRUE;
249 #endif
250
251 hw_chplan &= (~EEPROM_CHANNEL_PLAN_BY_HW_MASK);
252
253 chk_hw_country_code:
254 if (hw_alpha2 && !IS_ALPHA2_NO_SPECIFIED(hw_alpha2)) {
255 ent = rtw_get_chplan_from_country(hw_alpha2);
256 if (ent) {
257 /* get chplan from hw country code, by pass hw chplan setting */
258 country_ent = ent;
259 chplan = ent->chplan;
260 goto chk_sw_config;
261 } else
262 RTW_PRINT("%s unsupported hw_alpha2:\"%c%c\"\n", __func__, hw_alpha2[0], hw_alpha2[1]);
263 }
264
265 if (rtw_is_channel_plan_valid(hw_chplan))
266 chplan = hw_chplan;
267 else if (force_hw_chplan == _TRUE) {
268 RTW_PRINT("%s unsupported hw_chplan:0x%02X\n", __func__, hw_chplan);
269 /* hw infomaton invalid, refer to sw information */
270 force_hw_chplan = _FALSE;
271 }
272
273 chk_sw_config:
274 if (force_hw_chplan == _TRUE)
275 goto done;
276
277 if (sw_alpha2 && !IS_ALPHA2_NO_SPECIFIED(sw_alpha2)) {
278 ent = rtw_get_chplan_from_country(sw_alpha2);
279 if (ent) {
280 /* get chplan from sw country code, by pass sw chplan setting */
281 country_ent = ent;
282 chplan = ent->chplan;
283 goto done;
284 } else
285 RTW_PRINT("%s unsupported sw_alpha2:\"%c%c\"\n", __func__, sw_alpha2[0], sw_alpha2[1]);
286 }
287
288 if (rtw_is_channel_plan_valid(sw_chplan)) {
289 /* cancel hw_alpha2 because chplan is specified by sw_chplan*/
290 country_ent = NULL;
291 chplan = sw_chplan;
292 } else if (sw_chplan != RTW_CHPLAN_MAX)
293 RTW_PRINT("%s unsupported sw_chplan:0x%02X\n", __func__, sw_chplan);
294
295 done:
296 if (chplan == -1) {
297 RTW_PRINT("%s use def_chplan:0x%02X\n", __func__, def_chplan);
298 chplan = def_chplan;
299 } else if (country_ent) {
300 RTW_PRINT("%s country code:\"%c%c\" with chplan:0x%02X\n", __func__
301 , country_ent->alpha2[0], country_ent->alpha2[1], country_ent->chplan);
302 } else
303 RTW_PRINT("%s chplan:0x%02X\n", __func__, chplan);
304
305 padapter->mlmepriv.country_ent = country_ent;
306 pHalData->bDisableSWChannelPlan = force_hw_chplan;
307
308 return chplan;
309 }
310
311 BOOLEAN
HAL_IsLegalChannel(IN PADAPTER Adapter,IN u32 Channel)312 HAL_IsLegalChannel(
313 IN PADAPTER Adapter,
314 IN u32 Channel
315 )
316 {
317 BOOLEAN bLegalChannel = _TRUE;
318
319 if (Channel > 14) {
320 if (IsSupported5G(Adapter->registrypriv.wireless_mode) == _FALSE) {
321 bLegalChannel = _FALSE;
322 RTW_INFO("Channel > 14 but wireless_mode do not support 5G\n");
323 }
324 } else if ((Channel <= 14) && (Channel >= 1)) {
325 if (IsSupported24G(Adapter->registrypriv.wireless_mode) == _FALSE) {
326 bLegalChannel = _FALSE;
327 RTW_INFO("(Channel <= 14) && (Channel >=1) but wireless_mode do not support 2.4G\n");
328 }
329 } else {
330 bLegalChannel = _FALSE;
331 RTW_INFO("Channel is Invalid !!!\n");
332 }
333
334 return bLegalChannel;
335 }
336
MRateToHwRate(u8 rate)337 u8 MRateToHwRate(u8 rate)
338 {
339 u8 ret = DESC_RATE1M;
340
341 switch (rate) {
342 case MGN_1M:
343 ret = DESC_RATE1M;
344 break;
345 case MGN_2M:
346 ret = DESC_RATE2M;
347 break;
348 case MGN_5_5M:
349 ret = DESC_RATE5_5M;
350 break;
351 case MGN_11M:
352 ret = DESC_RATE11M;
353 break;
354 case MGN_6M:
355 ret = DESC_RATE6M;
356 break;
357 case MGN_9M:
358 ret = DESC_RATE9M;
359 break;
360 case MGN_12M:
361 ret = DESC_RATE12M;
362 break;
363 case MGN_18M:
364 ret = DESC_RATE18M;
365 break;
366 case MGN_24M:
367 ret = DESC_RATE24M;
368 break;
369 case MGN_36M:
370 ret = DESC_RATE36M;
371 break;
372 case MGN_48M:
373 ret = DESC_RATE48M;
374 break;
375 case MGN_54M:
376 ret = DESC_RATE54M;
377 break;
378
379 case MGN_MCS0:
380 ret = DESC_RATEMCS0;
381 break;
382 case MGN_MCS1:
383 ret = DESC_RATEMCS1;
384 break;
385 case MGN_MCS2:
386 ret = DESC_RATEMCS2;
387 break;
388 case MGN_MCS3:
389 ret = DESC_RATEMCS3;
390 break;
391 case MGN_MCS4:
392 ret = DESC_RATEMCS4;
393 break;
394 case MGN_MCS5:
395 ret = DESC_RATEMCS5;
396 break;
397 case MGN_MCS6:
398 ret = DESC_RATEMCS6;
399 break;
400 case MGN_MCS7:
401 ret = DESC_RATEMCS7;
402 break;
403 case MGN_MCS8:
404 ret = DESC_RATEMCS8;
405 break;
406 case MGN_MCS9:
407 ret = DESC_RATEMCS9;
408 break;
409 case MGN_MCS10:
410 ret = DESC_RATEMCS10;
411 break;
412 case MGN_MCS11:
413 ret = DESC_RATEMCS11;
414 break;
415 case MGN_MCS12:
416 ret = DESC_RATEMCS12;
417 break;
418 case MGN_MCS13:
419 ret = DESC_RATEMCS13;
420 break;
421 case MGN_MCS14:
422 ret = DESC_RATEMCS14;
423 break;
424 case MGN_MCS15:
425 ret = DESC_RATEMCS15;
426 break;
427 case MGN_MCS16:
428 ret = DESC_RATEMCS16;
429 break;
430 case MGN_MCS17:
431 ret = DESC_RATEMCS17;
432 break;
433 case MGN_MCS18:
434 ret = DESC_RATEMCS18;
435 break;
436 case MGN_MCS19:
437 ret = DESC_RATEMCS19;
438 break;
439 case MGN_MCS20:
440 ret = DESC_RATEMCS20;
441 break;
442 case MGN_MCS21:
443 ret = DESC_RATEMCS21;
444 break;
445 case MGN_MCS22:
446 ret = DESC_RATEMCS22;
447 break;
448 case MGN_MCS23:
449 ret = DESC_RATEMCS23;
450 break;
451 case MGN_MCS24:
452 ret = DESC_RATEMCS24;
453 break;
454 case MGN_MCS25:
455 ret = DESC_RATEMCS25;
456 break;
457 case MGN_MCS26:
458 ret = DESC_RATEMCS26;
459 break;
460 case MGN_MCS27:
461 ret = DESC_RATEMCS27;
462 break;
463 case MGN_MCS28:
464 ret = DESC_RATEMCS28;
465 break;
466 case MGN_MCS29:
467 ret = DESC_RATEMCS29;
468 break;
469 case MGN_MCS30:
470 ret = DESC_RATEMCS30;
471 break;
472 case MGN_MCS31:
473 ret = DESC_RATEMCS31;
474 break;
475
476 case MGN_VHT1SS_MCS0:
477 ret = DESC_RATEVHTSS1MCS0;
478 break;
479 case MGN_VHT1SS_MCS1:
480 ret = DESC_RATEVHTSS1MCS1;
481 break;
482 case MGN_VHT1SS_MCS2:
483 ret = DESC_RATEVHTSS1MCS2;
484 break;
485 case MGN_VHT1SS_MCS3:
486 ret = DESC_RATEVHTSS1MCS3;
487 break;
488 case MGN_VHT1SS_MCS4:
489 ret = DESC_RATEVHTSS1MCS4;
490 break;
491 case MGN_VHT1SS_MCS5:
492 ret = DESC_RATEVHTSS1MCS5;
493 break;
494 case MGN_VHT1SS_MCS6:
495 ret = DESC_RATEVHTSS1MCS6;
496 break;
497 case MGN_VHT1SS_MCS7:
498 ret = DESC_RATEVHTSS1MCS7;
499 break;
500 case MGN_VHT1SS_MCS8:
501 ret = DESC_RATEVHTSS1MCS8;
502 break;
503 case MGN_VHT1SS_MCS9:
504 ret = DESC_RATEVHTSS1MCS9;
505 break;
506 case MGN_VHT2SS_MCS0:
507 ret = DESC_RATEVHTSS2MCS0;
508 break;
509 case MGN_VHT2SS_MCS1:
510 ret = DESC_RATEVHTSS2MCS1;
511 break;
512 case MGN_VHT2SS_MCS2:
513 ret = DESC_RATEVHTSS2MCS2;
514 break;
515 case MGN_VHT2SS_MCS3:
516 ret = DESC_RATEVHTSS2MCS3;
517 break;
518 case MGN_VHT2SS_MCS4:
519 ret = DESC_RATEVHTSS2MCS4;
520 break;
521 case MGN_VHT2SS_MCS5:
522 ret = DESC_RATEVHTSS2MCS5;
523 break;
524 case MGN_VHT2SS_MCS6:
525 ret = DESC_RATEVHTSS2MCS6;
526 break;
527 case MGN_VHT2SS_MCS7:
528 ret = DESC_RATEVHTSS2MCS7;
529 break;
530 case MGN_VHT2SS_MCS8:
531 ret = DESC_RATEVHTSS2MCS8;
532 break;
533 case MGN_VHT2SS_MCS9:
534 ret = DESC_RATEVHTSS2MCS9;
535 break;
536 case MGN_VHT3SS_MCS0:
537 ret = DESC_RATEVHTSS3MCS0;
538 break;
539 case MGN_VHT3SS_MCS1:
540 ret = DESC_RATEVHTSS3MCS1;
541 break;
542 case MGN_VHT3SS_MCS2:
543 ret = DESC_RATEVHTSS3MCS2;
544 break;
545 case MGN_VHT3SS_MCS3:
546 ret = DESC_RATEVHTSS3MCS3;
547 break;
548 case MGN_VHT3SS_MCS4:
549 ret = DESC_RATEVHTSS3MCS4;
550 break;
551 case MGN_VHT3SS_MCS5:
552 ret = DESC_RATEVHTSS3MCS5;
553 break;
554 case MGN_VHT3SS_MCS6:
555 ret = DESC_RATEVHTSS3MCS6;
556 break;
557 case MGN_VHT3SS_MCS7:
558 ret = DESC_RATEVHTSS3MCS7;
559 break;
560 case MGN_VHT3SS_MCS8:
561 ret = DESC_RATEVHTSS3MCS8;
562 break;
563 case MGN_VHT3SS_MCS9:
564 ret = DESC_RATEVHTSS3MCS9;
565 break;
566 case MGN_VHT4SS_MCS0:
567 ret = DESC_RATEVHTSS4MCS0;
568 break;
569 case MGN_VHT4SS_MCS1:
570 ret = DESC_RATEVHTSS4MCS1;
571 break;
572 case MGN_VHT4SS_MCS2:
573 ret = DESC_RATEVHTSS4MCS2;
574 break;
575 case MGN_VHT4SS_MCS3:
576 ret = DESC_RATEVHTSS4MCS3;
577 break;
578 case MGN_VHT4SS_MCS4:
579 ret = DESC_RATEVHTSS4MCS4;
580 break;
581 case MGN_VHT4SS_MCS5:
582 ret = DESC_RATEVHTSS4MCS5;
583 break;
584 case MGN_VHT4SS_MCS6:
585 ret = DESC_RATEVHTSS4MCS6;
586 break;
587 case MGN_VHT4SS_MCS7:
588 ret = DESC_RATEVHTSS4MCS7;
589 break;
590 case MGN_VHT4SS_MCS8:
591 ret = DESC_RATEVHTSS4MCS8;
592 break;
593 case MGN_VHT4SS_MCS9:
594 ret = DESC_RATEVHTSS4MCS9;
595 break;
596 default:
597 break;
598 }
599
600 return ret;
601 }
602
HwRateToMRate(u8 rate)603 u8 HwRateToMRate(u8 rate)
604 {
605 u8 ret_rate = MGN_1M;
606
607 switch (rate) {
608
609 case DESC_RATE1M:
610 ret_rate = MGN_1M;
611 break;
612 case DESC_RATE2M:
613 ret_rate = MGN_2M;
614 break;
615 case DESC_RATE5_5M:
616 ret_rate = MGN_5_5M;
617 break;
618 case DESC_RATE11M:
619 ret_rate = MGN_11M;
620 break;
621 case DESC_RATE6M:
622 ret_rate = MGN_6M;
623 break;
624 case DESC_RATE9M:
625 ret_rate = MGN_9M;
626 break;
627 case DESC_RATE12M:
628 ret_rate = MGN_12M;
629 break;
630 case DESC_RATE18M:
631 ret_rate = MGN_18M;
632 break;
633 case DESC_RATE24M:
634 ret_rate = MGN_24M;
635 break;
636 case DESC_RATE36M:
637 ret_rate = MGN_36M;
638 break;
639 case DESC_RATE48M:
640 ret_rate = MGN_48M;
641 break;
642 case DESC_RATE54M:
643 ret_rate = MGN_54M;
644 break;
645 case DESC_RATEMCS0:
646 ret_rate = MGN_MCS0;
647 break;
648 case DESC_RATEMCS1:
649 ret_rate = MGN_MCS1;
650 break;
651 case DESC_RATEMCS2:
652 ret_rate = MGN_MCS2;
653 break;
654 case DESC_RATEMCS3:
655 ret_rate = MGN_MCS3;
656 break;
657 case DESC_RATEMCS4:
658 ret_rate = MGN_MCS4;
659 break;
660 case DESC_RATEMCS5:
661 ret_rate = MGN_MCS5;
662 break;
663 case DESC_RATEMCS6:
664 ret_rate = MGN_MCS6;
665 break;
666 case DESC_RATEMCS7:
667 ret_rate = MGN_MCS7;
668 break;
669 case DESC_RATEMCS8:
670 ret_rate = MGN_MCS8;
671 break;
672 case DESC_RATEMCS9:
673 ret_rate = MGN_MCS9;
674 break;
675 case DESC_RATEMCS10:
676 ret_rate = MGN_MCS10;
677 break;
678 case DESC_RATEMCS11:
679 ret_rate = MGN_MCS11;
680 break;
681 case DESC_RATEMCS12:
682 ret_rate = MGN_MCS12;
683 break;
684 case DESC_RATEMCS13:
685 ret_rate = MGN_MCS13;
686 break;
687 case DESC_RATEMCS14:
688 ret_rate = MGN_MCS14;
689 break;
690 case DESC_RATEMCS15:
691 ret_rate = MGN_MCS15;
692 break;
693 case DESC_RATEMCS16:
694 ret_rate = MGN_MCS16;
695 break;
696 case DESC_RATEMCS17:
697 ret_rate = MGN_MCS17;
698 break;
699 case DESC_RATEMCS18:
700 ret_rate = MGN_MCS18;
701 break;
702 case DESC_RATEMCS19:
703 ret_rate = MGN_MCS19;
704 break;
705 case DESC_RATEMCS20:
706 ret_rate = MGN_MCS20;
707 break;
708 case DESC_RATEMCS21:
709 ret_rate = MGN_MCS21;
710 break;
711 case DESC_RATEMCS22:
712 ret_rate = MGN_MCS22;
713 break;
714 case DESC_RATEMCS23:
715 ret_rate = MGN_MCS23;
716 break;
717 case DESC_RATEMCS24:
718 ret_rate = MGN_MCS24;
719 break;
720 case DESC_RATEMCS25:
721 ret_rate = MGN_MCS25;
722 break;
723 case DESC_RATEMCS26:
724 ret_rate = MGN_MCS26;
725 break;
726 case DESC_RATEMCS27:
727 ret_rate = MGN_MCS27;
728 break;
729 case DESC_RATEMCS28:
730 ret_rate = MGN_MCS28;
731 break;
732 case DESC_RATEMCS29:
733 ret_rate = MGN_MCS29;
734 break;
735 case DESC_RATEMCS30:
736 ret_rate = MGN_MCS30;
737 break;
738 case DESC_RATEMCS31:
739 ret_rate = MGN_MCS31;
740 break;
741 case DESC_RATEVHTSS1MCS0:
742 ret_rate = MGN_VHT1SS_MCS0;
743 break;
744 case DESC_RATEVHTSS1MCS1:
745 ret_rate = MGN_VHT1SS_MCS1;
746 break;
747 case DESC_RATEVHTSS1MCS2:
748 ret_rate = MGN_VHT1SS_MCS2;
749 break;
750 case DESC_RATEVHTSS1MCS3:
751 ret_rate = MGN_VHT1SS_MCS3;
752 break;
753 case DESC_RATEVHTSS1MCS4:
754 ret_rate = MGN_VHT1SS_MCS4;
755 break;
756 case DESC_RATEVHTSS1MCS5:
757 ret_rate = MGN_VHT1SS_MCS5;
758 break;
759 case DESC_RATEVHTSS1MCS6:
760 ret_rate = MGN_VHT1SS_MCS6;
761 break;
762 case DESC_RATEVHTSS1MCS7:
763 ret_rate = MGN_VHT1SS_MCS7;
764 break;
765 case DESC_RATEVHTSS1MCS8:
766 ret_rate = MGN_VHT1SS_MCS8;
767 break;
768 case DESC_RATEVHTSS1MCS9:
769 ret_rate = MGN_VHT1SS_MCS9;
770 break;
771 case DESC_RATEVHTSS2MCS0:
772 ret_rate = MGN_VHT2SS_MCS0;
773 break;
774 case DESC_RATEVHTSS2MCS1:
775 ret_rate = MGN_VHT2SS_MCS1;
776 break;
777 case DESC_RATEVHTSS2MCS2:
778 ret_rate = MGN_VHT2SS_MCS2;
779 break;
780 case DESC_RATEVHTSS2MCS3:
781 ret_rate = MGN_VHT2SS_MCS3;
782 break;
783 case DESC_RATEVHTSS2MCS4:
784 ret_rate = MGN_VHT2SS_MCS4;
785 break;
786 case DESC_RATEVHTSS2MCS5:
787 ret_rate = MGN_VHT2SS_MCS5;
788 break;
789 case DESC_RATEVHTSS2MCS6:
790 ret_rate = MGN_VHT2SS_MCS6;
791 break;
792 case DESC_RATEVHTSS2MCS7:
793 ret_rate = MGN_VHT2SS_MCS7;
794 break;
795 case DESC_RATEVHTSS2MCS8:
796 ret_rate = MGN_VHT2SS_MCS8;
797 break;
798 case DESC_RATEVHTSS2MCS9:
799 ret_rate = MGN_VHT2SS_MCS9;
800 break;
801 case DESC_RATEVHTSS3MCS0:
802 ret_rate = MGN_VHT3SS_MCS0;
803 break;
804 case DESC_RATEVHTSS3MCS1:
805 ret_rate = MGN_VHT3SS_MCS1;
806 break;
807 case DESC_RATEVHTSS3MCS2:
808 ret_rate = MGN_VHT3SS_MCS2;
809 break;
810 case DESC_RATEVHTSS3MCS3:
811 ret_rate = MGN_VHT3SS_MCS3;
812 break;
813 case DESC_RATEVHTSS3MCS4:
814 ret_rate = MGN_VHT3SS_MCS4;
815 break;
816 case DESC_RATEVHTSS3MCS5:
817 ret_rate = MGN_VHT3SS_MCS5;
818 break;
819 case DESC_RATEVHTSS3MCS6:
820 ret_rate = MGN_VHT3SS_MCS6;
821 break;
822 case DESC_RATEVHTSS3MCS7:
823 ret_rate = MGN_VHT3SS_MCS7;
824 break;
825 case DESC_RATEVHTSS3MCS8:
826 ret_rate = MGN_VHT3SS_MCS8;
827 break;
828 case DESC_RATEVHTSS3MCS9:
829 ret_rate = MGN_VHT3SS_MCS9;
830 break;
831 case DESC_RATEVHTSS4MCS0:
832 ret_rate = MGN_VHT4SS_MCS0;
833 break;
834 case DESC_RATEVHTSS4MCS1:
835 ret_rate = MGN_VHT4SS_MCS1;
836 break;
837 case DESC_RATEVHTSS4MCS2:
838 ret_rate = MGN_VHT4SS_MCS2;
839 break;
840 case DESC_RATEVHTSS4MCS3:
841 ret_rate = MGN_VHT4SS_MCS3;
842 break;
843 case DESC_RATEVHTSS4MCS4:
844 ret_rate = MGN_VHT4SS_MCS4;
845 break;
846 case DESC_RATEVHTSS4MCS5:
847 ret_rate = MGN_VHT4SS_MCS5;
848 break;
849 case DESC_RATEVHTSS4MCS6:
850 ret_rate = MGN_VHT4SS_MCS6;
851 break;
852 case DESC_RATEVHTSS4MCS7:
853 ret_rate = MGN_VHT4SS_MCS7;
854 break;
855 case DESC_RATEVHTSS4MCS8:
856 ret_rate = MGN_VHT4SS_MCS8;
857 break;
858 case DESC_RATEVHTSS4MCS9:
859 ret_rate = MGN_VHT4SS_MCS9;
860 break;
861
862 default:
863 RTW_INFO("HwRateToMRate(): Non supported Rate [%x]!!!\n", rate);
864 break;
865 }
866
867 return ret_rate;
868 }
869
HalSetBrateCfg(IN PADAPTER Adapter,IN u8 * mBratesOS,OUT u16 * pBrateCfg)870 void HalSetBrateCfg(
871 IN PADAPTER Adapter,
872 IN u8 *mBratesOS,
873 OUT u16 *pBrateCfg)
874 {
875 u8 i, is_brate, brate;
876
877 for (i = 0; i < NDIS_802_11_LENGTH_RATES_EX; i++) {
878 is_brate = mBratesOS[i] & IEEE80211_BASIC_RATE_MASK;
879 brate = mBratesOS[i] & 0x7f;
880
881 if (is_brate) {
882 switch (brate) {
883 case IEEE80211_CCK_RATE_1MB:
884 *pBrateCfg |= RATE_1M;
885 break;
886 case IEEE80211_CCK_RATE_2MB:
887 *pBrateCfg |= RATE_2M;
888 break;
889 case IEEE80211_CCK_RATE_5MB:
890 *pBrateCfg |= RATE_5_5M;
891 break;
892 case IEEE80211_CCK_RATE_11MB:
893 *pBrateCfg |= RATE_11M;
894 break;
895 case IEEE80211_OFDM_RATE_6MB:
896 *pBrateCfg |= RATE_6M;
897 break;
898 case IEEE80211_OFDM_RATE_9MB:
899 *pBrateCfg |= RATE_9M;
900 break;
901 case IEEE80211_OFDM_RATE_12MB:
902 *pBrateCfg |= RATE_12M;
903 break;
904 case IEEE80211_OFDM_RATE_18MB:
905 *pBrateCfg |= RATE_18M;
906 break;
907 case IEEE80211_OFDM_RATE_24MB:
908 *pBrateCfg |= RATE_24M;
909 break;
910 case IEEE80211_OFDM_RATE_36MB:
911 *pBrateCfg |= RATE_36M;
912 break;
913 case IEEE80211_OFDM_RATE_48MB:
914 *pBrateCfg |= RATE_48M;
915 break;
916 case IEEE80211_OFDM_RATE_54MB:
917 *pBrateCfg |= RATE_54M;
918 break;
919 }
920 }
921 }
922 }
923
924 static VOID
_OneOutPipeMapping(IN PADAPTER pAdapter)925 _OneOutPipeMapping(
926 IN PADAPTER pAdapter
927 )
928 {
929 struct dvobj_priv *pdvobjpriv = adapter_to_dvobj(pAdapter);
930
931 pdvobjpriv->Queue2Pipe[0] = pdvobjpriv->RtOutPipe[0];/* VO */
932 pdvobjpriv->Queue2Pipe[1] = pdvobjpriv->RtOutPipe[0];/* VI */
933 pdvobjpriv->Queue2Pipe[2] = pdvobjpriv->RtOutPipe[0];/* BE */
934 pdvobjpriv->Queue2Pipe[3] = pdvobjpriv->RtOutPipe[0];/* BK */
935
936 pdvobjpriv->Queue2Pipe[4] = pdvobjpriv->RtOutPipe[0];/* BCN */
937 pdvobjpriv->Queue2Pipe[5] = pdvobjpriv->RtOutPipe[0];/* MGT */
938 pdvobjpriv->Queue2Pipe[6] = pdvobjpriv->RtOutPipe[0];/* HIGH */
939 pdvobjpriv->Queue2Pipe[7] = pdvobjpriv->RtOutPipe[0];/* TXCMD */
940 }
941
942 static VOID
_TwoOutPipeMapping(IN PADAPTER pAdapter,IN BOOLEAN bWIFICfg)943 _TwoOutPipeMapping(
944 IN PADAPTER pAdapter,
945 IN BOOLEAN bWIFICfg
946 )
947 {
948 struct dvobj_priv *pdvobjpriv = adapter_to_dvobj(pAdapter);
949
950 if (bWIFICfg) { /* WMM */
951
952 /* BK, BE, VI, VO, BCN, CMD,MGT,HIGH,HCCA */
953 /* { 0, 1, 0, 1, 0, 0, 0, 0, 0 }; */
954 /* 0:ep_0 num, 1:ep_1 num */
955
956 pdvobjpriv->Queue2Pipe[0] = pdvobjpriv->RtOutPipe[1];/* VO */
957 pdvobjpriv->Queue2Pipe[1] = pdvobjpriv->RtOutPipe[0];/* VI */
958 pdvobjpriv->Queue2Pipe[2] = pdvobjpriv->RtOutPipe[1];/* BE */
959 pdvobjpriv->Queue2Pipe[3] = pdvobjpriv->RtOutPipe[0];/* BK */
960
961 pdvobjpriv->Queue2Pipe[4] = pdvobjpriv->RtOutPipe[0];/* BCN */
962 pdvobjpriv->Queue2Pipe[5] = pdvobjpriv->RtOutPipe[0];/* MGT */
963 pdvobjpriv->Queue2Pipe[6] = pdvobjpriv->RtOutPipe[0];/* HIGH */
964 pdvobjpriv->Queue2Pipe[7] = pdvobjpriv->RtOutPipe[0];/* TXCMD */
965
966 } else { /* typical setting */
967
968
969 /* BK, BE, VI, VO, BCN, CMD,MGT,HIGH,HCCA */
970 /* { 1, 1, 0, 0, 0, 0, 0, 0, 0 }; */
971 /* 0:ep_0 num, 1:ep_1 num */
972
973 pdvobjpriv->Queue2Pipe[0] = pdvobjpriv->RtOutPipe[0];/* VO */
974 pdvobjpriv->Queue2Pipe[1] = pdvobjpriv->RtOutPipe[0];/* VI */
975 pdvobjpriv->Queue2Pipe[2] = pdvobjpriv->RtOutPipe[1];/* BE */
976 pdvobjpriv->Queue2Pipe[3] = pdvobjpriv->RtOutPipe[1];/* BK */
977
978 pdvobjpriv->Queue2Pipe[4] = pdvobjpriv->RtOutPipe[0];/* BCN */
979 pdvobjpriv->Queue2Pipe[5] = pdvobjpriv->RtOutPipe[0];/* MGT */
980 pdvobjpriv->Queue2Pipe[6] = pdvobjpriv->RtOutPipe[0];/* HIGH */
981 pdvobjpriv->Queue2Pipe[7] = pdvobjpriv->RtOutPipe[0];/* TXCMD */
982
983 }
984
985 }
986
_ThreeOutPipeMapping(IN PADAPTER pAdapter,IN BOOLEAN bWIFICfg)987 static VOID _ThreeOutPipeMapping(
988 IN PADAPTER pAdapter,
989 IN BOOLEAN bWIFICfg
990 )
991 {
992 struct dvobj_priv *pdvobjpriv = adapter_to_dvobj(pAdapter);
993
994 if (bWIFICfg) { /* for WMM */
995
996 /* BK, BE, VI, VO, BCN, CMD,MGT,HIGH,HCCA */
997 /* { 1, 2, 1, 0, 0, 0, 0, 0, 0 }; */
998 /* 0:H, 1:N, 2:L */
999
1000 pdvobjpriv->Queue2Pipe[0] = pdvobjpriv->RtOutPipe[0];/* VO */
1001 pdvobjpriv->Queue2Pipe[1] = pdvobjpriv->RtOutPipe[1];/* VI */
1002 pdvobjpriv->Queue2Pipe[2] = pdvobjpriv->RtOutPipe[2];/* BE */
1003 pdvobjpriv->Queue2Pipe[3] = pdvobjpriv->RtOutPipe[1];/* BK */
1004
1005 pdvobjpriv->Queue2Pipe[4] = pdvobjpriv->RtOutPipe[0];/* BCN */
1006 pdvobjpriv->Queue2Pipe[5] = pdvobjpriv->RtOutPipe[0];/* MGT */
1007 pdvobjpriv->Queue2Pipe[6] = pdvobjpriv->RtOutPipe[0];/* HIGH */
1008 pdvobjpriv->Queue2Pipe[7] = pdvobjpriv->RtOutPipe[0];/* TXCMD */
1009
1010 } else { /* typical setting */
1011
1012
1013 /* BK, BE, VI, VO, BCN, CMD,MGT,HIGH,HCCA */
1014 /* { 2, 2, 1, 0, 0, 0, 0, 0, 0 }; */
1015 /* 0:H, 1:N, 2:L */
1016
1017 pdvobjpriv->Queue2Pipe[0] = pdvobjpriv->RtOutPipe[0];/* VO */
1018 pdvobjpriv->Queue2Pipe[1] = pdvobjpriv->RtOutPipe[1];/* VI */
1019 pdvobjpriv->Queue2Pipe[2] = pdvobjpriv->RtOutPipe[2];/* BE */
1020 pdvobjpriv->Queue2Pipe[3] = pdvobjpriv->RtOutPipe[2];/* BK */
1021
1022 pdvobjpriv->Queue2Pipe[4] = pdvobjpriv->RtOutPipe[0];/* BCN */
1023 pdvobjpriv->Queue2Pipe[5] = pdvobjpriv->RtOutPipe[0];/* MGT */
1024 pdvobjpriv->Queue2Pipe[6] = pdvobjpriv->RtOutPipe[0];/* HIGH */
1025 pdvobjpriv->Queue2Pipe[7] = pdvobjpriv->RtOutPipe[0];/* TXCMD */
1026 }
1027
1028 }
_FourOutPipeMapping(IN PADAPTER pAdapter,IN BOOLEAN bWIFICfg)1029 static VOID _FourOutPipeMapping(
1030 IN PADAPTER pAdapter,
1031 IN BOOLEAN bWIFICfg
1032 )
1033 {
1034 struct dvobj_priv *pdvobjpriv = adapter_to_dvobj(pAdapter);
1035
1036 if (bWIFICfg) { /* for WMM */
1037
1038 /* BK, BE, VI, VO, BCN, CMD,MGT,HIGH,HCCA */
1039 /* { 1, 2, 1, 0, 0, 0, 0, 0, 0 }; */
1040 /* 0:H, 1:N, 2:L ,3:E */
1041
1042 pdvobjpriv->Queue2Pipe[0] = pdvobjpriv->RtOutPipe[0];/* VO */
1043 pdvobjpriv->Queue2Pipe[1] = pdvobjpriv->RtOutPipe[1];/* VI */
1044 pdvobjpriv->Queue2Pipe[2] = pdvobjpriv->RtOutPipe[2];/* BE */
1045 pdvobjpriv->Queue2Pipe[3] = pdvobjpriv->RtOutPipe[1];/* BK */
1046
1047 pdvobjpriv->Queue2Pipe[4] = pdvobjpriv->RtOutPipe[0];/* BCN */
1048 pdvobjpriv->Queue2Pipe[5] = pdvobjpriv->RtOutPipe[0];/* MGT */
1049 pdvobjpriv->Queue2Pipe[6] = pdvobjpriv->RtOutPipe[3];/* HIGH */
1050 pdvobjpriv->Queue2Pipe[7] = pdvobjpriv->RtOutPipe[0];/* TXCMD */
1051
1052 } else { /* typical setting */
1053
1054
1055 /* BK, BE, VI, VO, BCN, CMD,MGT,HIGH,HCCA */
1056 /* { 2, 2, 1, 0, 0, 0, 0, 0, 0 }; */
1057 /* 0:H, 1:N, 2:L */
1058
1059 pdvobjpriv->Queue2Pipe[0] = pdvobjpriv->RtOutPipe[0];/* VO */
1060 pdvobjpriv->Queue2Pipe[1] = pdvobjpriv->RtOutPipe[1];/* VI */
1061 pdvobjpriv->Queue2Pipe[2] = pdvobjpriv->RtOutPipe[2];/* BE */
1062 pdvobjpriv->Queue2Pipe[3] = pdvobjpriv->RtOutPipe[2];/* BK */
1063
1064 pdvobjpriv->Queue2Pipe[4] = pdvobjpriv->RtOutPipe[0];/* BCN */
1065 pdvobjpriv->Queue2Pipe[5] = pdvobjpriv->RtOutPipe[0];/* MGT */
1066 pdvobjpriv->Queue2Pipe[6] = pdvobjpriv->RtOutPipe[3];/* HIGH */
1067 pdvobjpriv->Queue2Pipe[7] = pdvobjpriv->RtOutPipe[0];/* TXCMD */
1068 }
1069
1070 }
1071 BOOLEAN
Hal_MappingOutPipe(IN PADAPTER pAdapter,IN u8 NumOutPipe)1072 Hal_MappingOutPipe(
1073 IN PADAPTER pAdapter,
1074 IN u8 NumOutPipe
1075 )
1076 {
1077 struct registry_priv *pregistrypriv = &pAdapter->registrypriv;
1078
1079 BOOLEAN bWIFICfg = (pregistrypriv->wifi_spec) ? _TRUE : _FALSE;
1080
1081 BOOLEAN result = _TRUE;
1082
1083 switch (NumOutPipe) {
1084 case 2:
1085 _TwoOutPipeMapping(pAdapter, bWIFICfg);
1086 break;
1087 case 3:
1088 case 4:
1089 _ThreeOutPipeMapping(pAdapter, bWIFICfg);
1090 break;
1091 case 1:
1092 _OneOutPipeMapping(pAdapter);
1093 break;
1094 default:
1095 result = _FALSE;
1096 break;
1097 }
1098
1099 return result;
1100
1101 }
1102
rtw_hal_reqtxrpt(_adapter * padapter,u8 macid)1103 void rtw_hal_reqtxrpt(_adapter *padapter, u8 macid)
1104 {
1105 if (padapter->HalFunc.reqtxrpt)
1106 padapter->HalFunc.reqtxrpt(padapter, macid);
1107 }
1108
rtw_hal_dump_macaddr(void * sel,_adapter * adapter)1109 void rtw_hal_dump_macaddr(void *sel, _adapter *adapter)
1110 {
1111 int i;
1112 _adapter *iface;
1113 struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
1114 u8 mac_addr[ETH_ALEN];
1115
1116 #ifdef CONFIG_MI_WITH_MBSSID_CAM
1117 rtw_mbid_cam_dump(sel, __func__, adapter);
1118 #else
1119 for (i = 0; i < dvobj->iface_nums; i++) {
1120 iface = dvobj->padapters[i];
1121 if (iface) {
1122 rtw_hal_get_macaddr_port(iface, mac_addr);
1123 RTW_PRINT_SEL(sel, ADPT_FMT"- hw port(%d) mac_addr ="MAC_FMT"\n",
1124 ADPT_ARG(iface), iface->hw_port, MAC_ARG(mac_addr));
1125 }
1126 }
1127 #endif
1128 }
1129
rtw_restore_mac_addr(_adapter * adapter)1130 void rtw_restore_mac_addr(_adapter *adapter)
1131 {
1132 #ifdef CONFIG_MI_WITH_MBSSID_CAM
1133 _adapter *iface;
1134 struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
1135
1136 rtw_mbid_cam_restore(adapter);
1137 #else
1138 int i;
1139 _adapter *iface;
1140 struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
1141
1142 for (i = 0; i < dvobj->iface_nums; i++) {
1143 iface = dvobj->padapters[i];
1144 if (iface)
1145 rtw_hal_set_macaddr_port(iface, adapter_mac_addr(iface));
1146 }
1147 #endif
1148 if (1)
1149 rtw_hal_dump_macaddr(RTW_DBGDUMP, adapter);
1150 }
1151
rtw_init_hal_com_default_value(PADAPTER Adapter)1152 void rtw_init_hal_com_default_value(PADAPTER Adapter)
1153 {
1154 PHAL_DATA_TYPE pHalData = GET_HAL_DATA(Adapter);
1155 struct registry_priv *regsty = adapter_to_regsty(Adapter);
1156
1157 pHalData->AntDetection = 1;
1158 pHalData->antenna_test = _FALSE;
1159 pHalData->u1ForcedIgiLb = regsty->force_igi_lb;
1160 }
1161
1162 /*
1163 * C2H event format:
1164 * Field TRIGGER CONTENT CMD_SEQ CMD_LEN CMD_ID
1165 * BITS [127:120] [119:16] [15:8] [7:4] [3:0]
1166 */
1167
c2h_evt_clear(_adapter * adapter)1168 void c2h_evt_clear(_adapter *adapter)
1169 {
1170 rtw_write8(adapter, REG_C2HEVT_CLEAR, C2H_EVT_HOST_CLOSE);
1171 }
1172
c2h_evt_read(_adapter * adapter,u8 * buf)1173 s32 c2h_evt_read(_adapter *adapter, u8 *buf)
1174 {
1175 s32 ret = _FAIL;
1176 struct c2h_evt_hdr *c2h_evt;
1177 int i;
1178 u8 trigger;
1179
1180 if (buf == NULL)
1181 goto exit;
1182
1183 #if defined(CONFIG_RTL8188E)
1184
1185 trigger = rtw_read8(adapter, REG_C2HEVT_CLEAR);
1186
1187 if (trigger == C2H_EVT_HOST_CLOSE) {
1188 goto exit; /* Not ready */
1189 } else if (trigger != C2H_EVT_FW_CLOSE) {
1190 goto clear_evt; /* Not a valid value */
1191 }
1192
1193 c2h_evt = (struct c2h_evt_hdr *)buf;
1194
1195 _rtw_memset(c2h_evt, 0, 16);
1196
1197 *buf = rtw_read8(adapter, REG_C2HEVT_MSG_NORMAL);
1198 *(buf + 1) = rtw_read8(adapter, REG_C2HEVT_MSG_NORMAL + 1);
1199
1200 RTW_DBG_DUMP("c2h_evt_read(): ",
1201 &c2h_evt , sizeof(c2h_evt));
1202
1203 if (0) {
1204 RTW_INFO("%s id:%u, len:%u, seq:%u, trigger:0x%02x\n", __func__
1205 , c2h_evt->id, c2h_evt->plen, c2h_evt->seq, trigger);
1206 }
1207
1208 /* Read the content */
1209 for (i = 0; i < c2h_evt->plen; i++)
1210 c2h_evt->payload[i] = rtw_read8(adapter, REG_C2HEVT_MSG_NORMAL + 2 + i);
1211
1212 RTW_DBG_DUMP("c2h_evt_read(): Command Content:\n",
1213 c2h_evt->payload, c2h_evt->plen);
1214
1215 ret = _SUCCESS;
1216
1217 clear_evt:
1218 /*
1219 * Clear event to notify FW we have read the command.
1220 * If this field isn't clear, the FW won't update the next command message.
1221 */
1222 c2h_evt_clear(adapter);
1223 #endif
1224 exit:
1225 return ret;
1226 }
1227
1228 /*
1229 * C2H event format:
1230 * Field TRIGGER CMD_LEN CONTENT CMD_SEQ CMD_ID
1231 * BITS [127:120] [119:112] [111:16] [15:8] [7:0]
1232 */
c2h_evt_read_88xx(_adapter * adapter,u8 * buf)1233 s32 c2h_evt_read_88xx(_adapter *adapter, u8 *buf)
1234 {
1235 s32 ret = _FAIL;
1236 struct c2h_evt_hdr_88xx *c2h_evt;
1237 int i;
1238 u8 trigger;
1239
1240 if (buf == NULL)
1241 goto exit;
1242
1243 #if defined(CONFIG_RTL8812A) || defined(CONFIG_RTL8821A) \
1244 || defined(CONFIG_RTL8192E) || defined(CONFIG_RTL8723B) \
1245 || defined(CONFIG_RTL8703B) || defined(CONFIG_RTL8723D)
1246
1247 trigger = rtw_read8(adapter, REG_C2HEVT_CLEAR);
1248
1249 if (trigger == C2H_EVT_HOST_CLOSE) {
1250 goto exit; /* Not ready */
1251 } else if (trigger != C2H_EVT_FW_CLOSE) {
1252 goto clear_evt; /* Not a valid value */
1253 }
1254
1255 c2h_evt = (struct c2h_evt_hdr_88xx *)buf;
1256
1257 _rtw_memset(c2h_evt, 0, 16);
1258
1259 c2h_evt->id = rtw_read8(adapter, REG_C2HEVT_MSG_NORMAL);
1260 c2h_evt->seq = rtw_read8(adapter, REG_C2HEVT_CMD_SEQ_88XX);
1261 c2h_evt->plen = rtw_read8(adapter, REG_C2HEVT_CMD_LEN_88XX);
1262
1263 RTW_DBG_DUMP("c2h_evt_read(): ",
1264 &c2h_evt , sizeof(c2h_evt));
1265
1266 if (0) {
1267 RTW_INFO("%s id:%u, len:%u, seq:%u, trigger:0x%02x\n", __func__
1268 , c2h_evt->id, c2h_evt->plen, c2h_evt->seq, trigger);
1269 }
1270
1271 /* Read the content */
1272 for (i = 0; i < c2h_evt->plen; i++)
1273 c2h_evt->payload[i] = rtw_read8(adapter, REG_C2HEVT_MSG_NORMAL + 2 + i);
1274
1275 RTW_DBG_DUMP("c2h_evt_read(): Command Content:\n",
1276 c2h_evt->payload, c2h_evt->plen);
1277
1278 ret = _SUCCESS;
1279
1280 clear_evt:
1281 /*
1282 * Clear event to notify FW we have read the command.
1283 * If this field isn't clear, the FW won't update the next command message.
1284 */
1285 c2h_evt_clear(adapter);
1286 #endif
1287 exit:
1288 return ret;
1289 }
1290
1291 #define GET_C2H_MAC_HIDDEN_RPT_UUID_X(_data) LE_BITS_TO_1BYTE(((u8 *)(_data)) + 0, 0, 8)
1292 #define GET_C2H_MAC_HIDDEN_RPT_UUID_Y(_data) LE_BITS_TO_1BYTE(((u8 *)(_data)) + 1, 0, 8)
1293 #define GET_C2H_MAC_HIDDEN_RPT_UUID_Z(_data) LE_BITS_TO_1BYTE(((u8 *)(_data)) + 2, 0, 5)
1294 #define GET_C2H_MAC_HIDDEN_RPT_UUID_CRC(_data) LE_BITS_TO_2BYTE(((u8 *)(_data)) + 2, 5, 11)
1295 #define GET_C2H_MAC_HIDDEN_RPT_HCI_TYPE(_data) LE_BITS_TO_1BYTE(((u8 *)(_data)) + 4, 0, 4)
1296 #define GET_C2H_MAC_HIDDEN_RPT_PACKAGE_TYPE(_data) LE_BITS_TO_1BYTE(((u8 *)(_data)) + 4, 4, 4)
1297 #define GET_C2H_MAC_HIDDEN_RPT_WL_FUNC(_data) LE_BITS_TO_1BYTE(((u8 *)(_data)) + 5, 0, 4)
1298 #define GET_C2H_MAC_HIDDEN_RPT_HW_STYPE(_data) LE_BITS_TO_1BYTE(((u8 *)(_data)) + 5, 4, 4)
1299 #define GET_C2H_MAC_HIDDEN_RPT_BW(_data) LE_BITS_TO_1BYTE(((u8 *)(_data)) + 6, 0, 3)
1300 #define GET_C2H_MAC_HIDDEN_RPT_ANT_NUM(_data) LE_BITS_TO_1BYTE(((u8 *)(_data)) + 6, 5, 3)
1301 #define GET_C2H_MAC_HIDDEN_RPT_80211_PROTOCOL(_data) LE_BITS_TO_1BYTE(((u8 *)(_data)) + 7, 2, 2)
1302 #define GET_C2H_MAC_HIDDEN_RPT_NIC_ROUTER(_data) LE_BITS_TO_1BYTE(((u8 *)(_data)) + 7, 6, 2)
1303
1304 #ifndef DBG_C2H_MAC_HIDDEN_RPT_HANDLE
1305 #define DBG_C2H_MAC_HIDDEN_RPT_HANDLE 0
1306 #endif
1307
c2h_mac_hidden_rpt_hdl(_adapter * adapter,u8 * data,u8 len)1308 int c2h_mac_hidden_rpt_hdl(_adapter *adapter, u8 *data, u8 len)
1309 {
1310 HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
1311 struct hal_spec_t *hal_spec = GET_HAL_SPEC(adapter);
1312 int ret = _FAIL;
1313
1314 u32 uuid;
1315 u8 uuid_x;
1316 u8 uuid_y;
1317 u8 uuid_z;
1318 u16 uuid_crc;
1319
1320 u8 hci_type;
1321 u8 package_type;
1322 u8 wl_func;
1323 u8 hw_stype;
1324 u8 bw;
1325 u8 ant_num;
1326 u8 protocol;
1327 u8 nic;
1328
1329 int i;
1330
1331 if (len < MAC_HIDDEN_RPT_LEN) {
1332 RTW_WARN("%s len(%u) < %d\n", __func__, len, MAC_HIDDEN_RPT_LEN);
1333 goto exit;
1334 }
1335
1336 uuid_x = GET_C2H_MAC_HIDDEN_RPT_UUID_X(data);
1337 uuid_y = GET_C2H_MAC_HIDDEN_RPT_UUID_Y(data);
1338 uuid_z = GET_C2H_MAC_HIDDEN_RPT_UUID_Z(data);
1339 uuid_crc = GET_C2H_MAC_HIDDEN_RPT_UUID_CRC(data);
1340
1341 hci_type = GET_C2H_MAC_HIDDEN_RPT_HCI_TYPE(data);
1342 package_type = GET_C2H_MAC_HIDDEN_RPT_PACKAGE_TYPE(data);
1343
1344 wl_func = GET_C2H_MAC_HIDDEN_RPT_WL_FUNC(data);
1345 hw_stype = GET_C2H_MAC_HIDDEN_RPT_HW_STYPE(data);
1346
1347 bw = GET_C2H_MAC_HIDDEN_RPT_BW(data);
1348 ant_num = GET_C2H_MAC_HIDDEN_RPT_ANT_NUM(data);
1349
1350 protocol = GET_C2H_MAC_HIDDEN_RPT_80211_PROTOCOL(data);
1351 nic = GET_C2H_MAC_HIDDEN_RPT_NIC_ROUTER(data);
1352
1353 if (DBG_C2H_MAC_HIDDEN_RPT_HANDLE) {
1354 for (i = 0; i < len; i++)
1355 RTW_INFO("%s: 0x%02X\n", __func__, *(data + i));
1356
1357 RTW_INFO("uuid x:0x%02x y:0x%02x z:0x%x crc:0x%x\n", uuid_x, uuid_y, uuid_z, uuid_crc);
1358 RTW_INFO("hci_type:0x%x\n", hci_type);
1359 RTW_INFO("package_type:0x%x\n", package_type);
1360 RTW_INFO("wl_func:0x%x\n", wl_func);
1361 RTW_INFO("hw_stype:0x%x\n", hw_stype);
1362 RTW_INFO("bw:0x%x\n", bw);
1363 RTW_INFO("ant_num:0x%x\n", ant_num);
1364 RTW_INFO("protocol:0x%x\n", protocol);
1365 RTW_INFO("nic:0x%x\n", nic);
1366 }
1367
1368 hal_data->PackageType = package_type;
1369 hal_spec->wl_func &= mac_hidden_wl_func_to_hal_wl_func(wl_func);
1370 hal_spec->bw_cap &= mac_hidden_max_bw_to_hal_bw_cap(bw);
1371 hal_spec->nss_num = rtw_min(hal_spec->nss_num, ant_num);
1372 hal_spec->proto_cap &= mac_hidden_proto_to_hal_proto_cap(protocol);
1373
1374 ret = _SUCCESS;
1375
1376 exit:
1377 return ret;
1378 }
1379
hal_read_mac_hidden_rpt(_adapter * adapter)1380 int hal_read_mac_hidden_rpt(_adapter *adapter)
1381 {
1382 int ret = _FAIL;
1383 int ret_fwdl;
1384 u8 mac_hidden_rpt[MAC_HIDDEN_RPT_LEN] = {0};
1385 u32 start = rtw_get_current_time();
1386 u32 cnt = 0;
1387 u32 timeout_ms = 800;
1388 u32 min_cnt = 10;
1389 u8 id = C2H_MAC_HIDDEN_RPT + 1;
1390 int i;
1391
1392 #if defined(CONFIG_USB_HCI) || defined(CONFIG_PCI_HCI)
1393 u8 hci_type = rtw_get_intf_type(adapter);
1394
1395 if ((hci_type == RTW_USB || hci_type == RTW_PCIE)
1396 && !rtw_is_hw_init_completed(adapter))
1397 rtw_hal_power_on(adapter);
1398 #endif
1399
1400 /* clear data ready */
1401 rtw_write8(adapter, REG_C2HEVT_MSG_NORMAL, id);
1402
1403 /* download FW */
1404 ret_fwdl = rtw_hal_fw_dl(adapter, _FALSE);
1405 if (ret_fwdl != _SUCCESS)
1406 goto mac_hidden_rpt_hdl;
1407
1408 /* polling for data ready */
1409 start = rtw_get_current_time();
1410 do {
1411 cnt++;
1412 id = rtw_read8(adapter, REG_C2HEVT_MSG_NORMAL);
1413 if (id == C2H_MAC_HIDDEN_RPT || RTW_CANNOT_IO(adapter))
1414 break;
1415 rtw_msleep_os(10);
1416 } while (rtw_get_passing_time_ms(start) < timeout_ms || cnt < min_cnt);
1417
1418 if (id == C2H_MAC_HIDDEN_RPT) {
1419 /* read data */
1420 for (i = 0; i < MAC_HIDDEN_RPT_LEN; i++)
1421 mac_hidden_rpt[i] = rtw_read8(adapter, REG_C2HEVT_MSG_NORMAL + 2 + i);
1422 }
1423
1424 mac_hidden_rpt_hdl:
1425 c2h_mac_hidden_rpt_hdl(adapter, mac_hidden_rpt, MAC_HIDDEN_RPT_LEN);
1426
1427 if (ret_fwdl == _SUCCESS && id == C2H_MAC_HIDDEN_RPT)
1428 ret = _SUCCESS;
1429
1430 exit:
1431
1432 #if defined(CONFIG_USB_HCI) || defined(CONFIG_PCI_HCI)
1433 if ((hci_type == RTW_USB || hci_type == RTW_PCIE)
1434 && !rtw_is_hw_init_completed(adapter))
1435 rtw_hal_power_off(adapter);
1436 #endif
1437
1438 RTW_INFO("%s %s! (%u, %dms), fwdl:%d, id:0x%02x\n", __func__
1439 , (ret == _SUCCESS) ? "OK" : "Fail", cnt, rtw_get_passing_time_ms(start), ret_fwdl, id);
1440
1441 return ret;
1442 }
1443
rtw_hal_networktype_to_raid(_adapter * adapter,struct sta_info * psta)1444 u8 rtw_hal_networktype_to_raid(_adapter *adapter, struct sta_info *psta)
1445 {
1446 if (IS_NEW_GENERATION_IC(adapter))
1447 return networktype_to_raid_ex(adapter, psta);
1448 else
1449 return networktype_to_raid(adapter, psta);
1450
1451 }
rtw_get_mgntframe_raid(_adapter * adapter,unsigned char network_type)1452 u8 rtw_get_mgntframe_raid(_adapter *adapter, unsigned char network_type)
1453 {
1454
1455 u8 raid;
1456 if (IS_NEW_GENERATION_IC(adapter)) {
1457
1458 raid = (network_type & WIRELESS_11B) ? RATEID_IDX_B
1459 : RATEID_IDX_G;
1460 } else {
1461 raid = (network_type & WIRELESS_11B) ? RATR_INX_WIRELESS_B
1462 : RATR_INX_WIRELESS_G;
1463 }
1464 return raid;
1465 }
1466
rtw_hal_update_sta_rate_mask(PADAPTER padapter,struct sta_info * psta)1467 void rtw_hal_update_sta_rate_mask(PADAPTER padapter, struct sta_info *psta)
1468 {
1469 u8 i, rf_type, limit;
1470 u64 tx_ra_bitmap;
1471
1472 if (psta == NULL)
1473 return;
1474
1475 tx_ra_bitmap = 0;
1476
1477 /* b/g mode ra_bitmap */
1478 for (i = 0; i < sizeof(psta->bssrateset); i++) {
1479 if (psta->bssrateset[i])
1480 tx_ra_bitmap |= rtw_get_bit_value_from_ieee_value(psta->bssrateset[i] & 0x7f);
1481 }
1482
1483 #ifdef CONFIG_80211N_HT
1484 #ifdef CONFIG_80211AC_VHT
1485 /* AC mode ra_bitmap */
1486 if (psta->vhtpriv.vht_option)
1487 tx_ra_bitmap |= (rtw_vht_rate_to_bitmap(psta->vhtpriv.vht_mcs_map) << 12);
1488 else
1489 #endif /* CONFIG_80211AC_VHT */
1490 {
1491 /* n mode ra_bitmap */
1492 if (psta->htpriv.ht_option) {
1493 rf_type = RF_1T1R;
1494 rtw_hal_get_hwreg(padapter, HW_VAR_RF_TYPE, (u8 *)(&rf_type));
1495 if (rf_type == RF_2T2R)
1496 limit = 16; /* 2R */
1497 else if (rf_type == RF_3T3R)
1498 limit = 24; /* 3R */
1499 else
1500 limit = 8; /* 1R */
1501
1502
1503 /* Handling SMPS mode for AP MODE only*/
1504 if (check_fwstate(&padapter->mlmepriv, WIFI_AP_STATE) == _TRUE) {
1505 /*0:static SMPS, 1:dynamic SMPS, 3:SMPS disabled, 2:reserved*/
1506 if (psta->htpriv.smps_cap == 0 || psta->htpriv.smps_cap == 1) {
1507 /*operate with only one active receive chain // 11n-MCS rate <= MSC7*/
1508 limit = 8;/* 1R*/
1509 }
1510 }
1511
1512 for (i = 0; i < limit; i++) {
1513 if (psta->htpriv.ht_cap.supp_mcs_set[i / 8] & BIT(i % 8))
1514 tx_ra_bitmap |= BIT(i + 12);
1515 }
1516 }
1517 }
1518 #endif /* CONFIG_80211N_HT */
1519 RTW_INFO("supp_mcs_set = %02x, %02x, %02x, rf_type=%d, tx_ra_bitmap=%016llx\n"
1520 , psta->htpriv.ht_cap.supp_mcs_set[0], psta->htpriv.ht_cap.supp_mcs_set[1], psta->htpriv.ht_cap.supp_mcs_set[2], rf_type, tx_ra_bitmap);
1521 psta->ra_mask = tx_ra_bitmap;
1522 psta->init_rate = get_highest_rate_idx(tx_ra_bitmap) & 0x3f;
1523 }
1524
1525 #ifndef SEC_CAM_ACCESS_TIMEOUT_MS
1526 #define SEC_CAM_ACCESS_TIMEOUT_MS 200
1527 #endif
1528
1529 #ifndef DBG_SEC_CAM_ACCESS
1530 #define DBG_SEC_CAM_ACCESS 0
1531 #endif
1532
rtw_sec_read_cam(_adapter * adapter,u8 addr)1533 u32 rtw_sec_read_cam(_adapter *adapter, u8 addr)
1534 {
1535 _mutex *mutex = &adapter_to_dvobj(adapter)->cam_ctl.sec_cam_access_mutex;
1536 u32 rdata;
1537 u32 cnt = 0;
1538 u32 start = 0, end = 0;
1539 u8 timeout = 0;
1540 u8 sr = 0;
1541
1542 _enter_critical_mutex(mutex, NULL);
1543
1544 rtw_write32(adapter, REG_CAMCMD, CAM_POLLINIG | addr);
1545
1546 start = rtw_get_current_time();
1547 while (1) {
1548 if (rtw_is_surprise_removed(adapter)) {
1549 sr = 1;
1550 break;
1551 }
1552
1553 cnt++;
1554 if (0 == (rtw_read32(adapter, REG_CAMCMD) & CAM_POLLINIG))
1555 break;
1556
1557 if (rtw_get_passing_time_ms(start) > SEC_CAM_ACCESS_TIMEOUT_MS) {
1558 timeout = 1;
1559 break;
1560 }
1561 }
1562 end = rtw_get_current_time();
1563
1564 rdata = rtw_read32(adapter, REG_CAMREAD);
1565
1566 _exit_critical_mutex(mutex, NULL);
1567
1568 if (DBG_SEC_CAM_ACCESS || timeout) {
1569 RTW_INFO(FUNC_ADPT_FMT" addr:0x%02x, rdata:0x%08x, to:%u, polling:%u, %d ms\n"
1570 , FUNC_ADPT_ARG(adapter), addr, rdata, timeout, cnt, rtw_get_time_interval_ms(start, end));
1571 }
1572
1573 return rdata;
1574 }
1575
rtw_sec_write_cam(_adapter * adapter,u8 addr,u32 wdata)1576 void rtw_sec_write_cam(_adapter *adapter, u8 addr, u32 wdata)
1577 {
1578 _mutex *mutex = &adapter_to_dvobj(adapter)->cam_ctl.sec_cam_access_mutex;
1579 u32 cnt = 0;
1580 u32 start = 0, end = 0;
1581 u8 timeout = 0;
1582 u8 sr = 0;
1583
1584 _enter_critical_mutex(mutex, NULL);
1585
1586 rtw_write32(adapter, REG_CAMWRITE, wdata);
1587 rtw_write32(adapter, REG_CAMCMD, CAM_POLLINIG | CAM_WRITE | addr);
1588
1589 start = rtw_get_current_time();
1590 while (1) {
1591 if (rtw_is_surprise_removed(adapter)) {
1592 sr = 1;
1593 break;
1594 }
1595
1596 cnt++;
1597 if (0 == (rtw_read32(adapter, REG_CAMCMD) & CAM_POLLINIG))
1598 break;
1599
1600 if (rtw_get_passing_time_ms(start) > SEC_CAM_ACCESS_TIMEOUT_MS) {
1601 timeout = 1;
1602 break;
1603 }
1604 }
1605 end = rtw_get_current_time();
1606
1607 _exit_critical_mutex(mutex, NULL);
1608
1609 if (DBG_SEC_CAM_ACCESS || timeout) {
1610 RTW_INFO(FUNC_ADPT_FMT" addr:0x%02x, wdata:0x%08x, to:%u, polling:%u, %d ms\n"
1611 , FUNC_ADPT_ARG(adapter), addr, wdata, timeout, cnt, rtw_get_time_interval_ms(start, end));
1612 }
1613 }
1614
rtw_sec_read_cam_ent(_adapter * adapter,u8 id,u8 * ctrl,u8 * mac,u8 * key)1615 void rtw_sec_read_cam_ent(_adapter *adapter, u8 id, u8 *ctrl, u8 *mac, u8 *key)
1616 {
1617 unsigned int val, addr;
1618 u8 i;
1619 u32 rdata;
1620 u8 begin = 0;
1621 u8 end = 5; /* TODO: consider other key length accordingly */
1622
1623 if (!ctrl && !mac && !key) {
1624 rtw_warn_on(1);
1625 goto exit;
1626 }
1627
1628 /* TODO: check id range */
1629
1630 if (!ctrl && !mac)
1631 begin = 2; /* read from key */
1632
1633 if (!key && !mac)
1634 end = 0; /* read to ctrl */
1635 else if (!key)
1636 end = 2; /* read to mac */
1637
1638 for (i = begin; i <= end; i++) {
1639 rdata = rtw_sec_read_cam(adapter, (id << 3) | i);
1640
1641 switch (i) {
1642 case 0:
1643 if (ctrl)
1644 _rtw_memcpy(ctrl, (u8 *)(&rdata), 2);
1645 if (mac)
1646 _rtw_memcpy(mac, ((u8 *)(&rdata)) + 2, 2);
1647 break;
1648 case 1:
1649 if (mac)
1650 _rtw_memcpy(mac + 2, (u8 *)(&rdata), 4);
1651 break;
1652 default:
1653 if (key)
1654 _rtw_memcpy(key + (i - 2) * 4, (u8 *)(&rdata), 4);
1655 break;
1656 }
1657 }
1658
1659 exit:
1660 return;
1661 }
1662
1663
rtw_sec_write_cam_ent(_adapter * adapter,u8 id,u16 ctrl,u8 * mac,u8 * key)1664 void rtw_sec_write_cam_ent(_adapter *adapter, u8 id, u16 ctrl, u8 *mac, u8 *key)
1665 {
1666 unsigned int i;
1667 int j;
1668 u8 addr;
1669 u32 wdata;
1670
1671 /* TODO: consider other key length accordingly */
1672 #if 0
1673 switch ((ctrl & 0x1c) >> 2) {
1674 case _WEP40_:
1675 case _TKIP_:
1676 case _AES_:
1677 case _WEP104_:
1678
1679 }
1680 #else
1681 j = 5;
1682 #endif
1683
1684 for (; j >= 0; j--) {
1685 switch (j) {
1686 case 0:
1687 wdata = (ctrl | (mac[0] << 16) | (mac[1] << 24));
1688 break;
1689 case 1:
1690 wdata = (mac[2] | (mac[3] << 8) | (mac[4] << 16) | (mac[5] << 24));
1691 break;
1692 default:
1693 i = (j - 2) << 2;
1694 wdata = (key[i] | (key[i + 1] << 8) | (key[i + 2] << 16) | (key[i + 3] << 24));
1695 break;
1696 }
1697
1698 addr = (id << 3) + j;
1699
1700 rtw_sec_write_cam(adapter, addr, wdata);
1701 }
1702 }
1703
rtw_sec_clr_cam_ent(_adapter * adapter,u8 id)1704 void rtw_sec_clr_cam_ent(_adapter *adapter, u8 id)
1705 {
1706 u8 addr;
1707
1708 addr = (id << 3);
1709 rtw_sec_write_cam(adapter, addr, 0);
1710 }
1711
rtw_sec_read_cam_is_gk(_adapter * adapter,u8 id)1712 bool rtw_sec_read_cam_is_gk(_adapter *adapter, u8 id)
1713 {
1714 bool res;
1715 u16 ctrl;
1716
1717 rtw_sec_read_cam_ent(adapter, id, (u8 *)&ctrl, NULL, NULL);
1718
1719 res = (ctrl & BIT6) ? _TRUE : _FALSE;
1720 return res;
1721 }
1722 #ifdef CONFIG_MBSSID_CAM
rtw_mbid_cam_init(struct dvobj_priv * dvobj)1723 void rtw_mbid_cam_init(struct dvobj_priv *dvobj)
1724 {
1725 struct mbid_cam_ctl_t *mbid_cam_ctl = &dvobj->mbid_cam_ctl;
1726
1727 _rtw_spinlock_init(&mbid_cam_ctl->lock);
1728 mbid_cam_ctl->bitmap = 0;
1729 ATOMIC_SET(&mbid_cam_ctl->mbid_entry_num, 0);
1730 _rtw_memset(&dvobj->mbid_cam_cache, 0, sizeof(dvobj->mbid_cam_cache));
1731 }
1732
rtw_mbid_cam_deinit(struct dvobj_priv * dvobj)1733 void rtw_mbid_cam_deinit(struct dvobj_priv *dvobj)
1734 {
1735 struct mbid_cam_ctl_t *mbid_cam_ctl = &dvobj->mbid_cam_ctl;
1736
1737 _rtw_spinlock_free(&mbid_cam_ctl->lock);
1738 }
1739
rtw_mbid_cam_reset(_adapter * adapter)1740 void rtw_mbid_cam_reset(_adapter *adapter)
1741 {
1742 _irqL irqL;
1743 struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
1744 struct mbid_cam_ctl_t *mbid_cam_ctl = &dvobj->mbid_cam_ctl;
1745
1746 _enter_critical_bh(&mbid_cam_ctl->lock, &irqL);
1747 mbid_cam_ctl->bitmap = 0;
1748 _rtw_memset(&dvobj->mbid_cam_cache, 0, sizeof(dvobj->mbid_cam_cache));
1749 _exit_critical_bh(&mbid_cam_ctl->lock, &irqL);
1750
1751 ATOMIC_SET(&mbid_cam_ctl->mbid_entry_num, 0);
1752 }
_rtw_mbid_cam_search_by_macaddr(_adapter * adapter,u8 * mac_addr)1753 static u8 _rtw_mbid_cam_search_by_macaddr(_adapter *adapter, u8 *mac_addr)
1754 {
1755 u8 i;
1756 u8 cam_id = INVALID_CAM_ID;
1757 struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
1758
1759 for (i = 0; i < TOTAL_MBID_CAM_NUM; i++) {
1760 if (mac_addr && _rtw_memcmp(dvobj->mbid_cam_cache[i].mac_addr, mac_addr, ETH_ALEN) == _TRUE) {
1761 cam_id = i;
1762 break;
1763 }
1764 }
1765
1766 RTW_INFO("%s mac:"MAC_FMT" - cam_id:%d\n", __func__, MAC_ARG(mac_addr), cam_id);
1767 return cam_id;
1768 }
1769
rtw_mbid_cam_search_by_macaddr(_adapter * adapter,u8 * mac_addr)1770 u8 rtw_mbid_cam_search_by_macaddr(_adapter *adapter, u8 *mac_addr)
1771 {
1772 _irqL irqL;
1773
1774 u8 cam_id = INVALID_CAM_ID;
1775 struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
1776 struct mbid_cam_ctl_t *mbid_cam_ctl = &dvobj->mbid_cam_ctl;
1777
1778 _enter_critical_bh(&mbid_cam_ctl->lock, &irqL);
1779 cam_id = _rtw_mbid_cam_search_by_macaddr(adapter, mac_addr);
1780 _exit_critical_bh(&mbid_cam_ctl->lock, &irqL);
1781
1782 return cam_id;
1783 }
_rtw_mbid_cam_search_by_ifaceid(_adapter * adapter,u8 iface_id)1784 static u8 _rtw_mbid_cam_search_by_ifaceid(_adapter *adapter, u8 iface_id)
1785 {
1786 u8 i;
1787 u8 cam_id = INVALID_CAM_ID;
1788 struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
1789
1790 for (i = 0; i < TOTAL_MBID_CAM_NUM; i++) {
1791 if (iface_id == dvobj->mbid_cam_cache[i].iface_id) {
1792 cam_id = i;
1793 break;
1794 }
1795 }
1796 if (cam_id != INVALID_CAM_ID)
1797 RTW_INFO("%s iface_id:%d mac:"MAC_FMT" - cam_id:%d\n",
1798 __func__, iface_id, MAC_ARG(dvobj->mbid_cam_cache[cam_id].mac_addr), cam_id);
1799
1800 return cam_id;
1801 }
1802
rtw_mbid_cam_search_by_ifaceid(_adapter * adapter,u8 iface_id)1803 u8 rtw_mbid_cam_search_by_ifaceid(_adapter *adapter, u8 iface_id)
1804 {
1805 _irqL irqL;
1806 u8 cam_id = INVALID_CAM_ID;
1807 struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
1808 struct mbid_cam_ctl_t *mbid_cam_ctl = &dvobj->mbid_cam_ctl;
1809
1810 _enter_critical_bh(&mbid_cam_ctl->lock, &irqL);
1811 cam_id = _rtw_mbid_cam_search_by_ifaceid(adapter, iface_id);
1812 _exit_critical_bh(&mbid_cam_ctl->lock, &irqL);
1813
1814 return cam_id;
1815 }
rtw_get_max_mbid_cam_id(_adapter * adapter)1816 u8 rtw_get_max_mbid_cam_id(_adapter *adapter)
1817 {
1818 _irqL irqL;
1819 s8 i;
1820 u8 cam_id = INVALID_CAM_ID;
1821 struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
1822 struct mbid_cam_ctl_t *mbid_cam_ctl = &dvobj->mbid_cam_ctl;
1823
1824 _enter_critical_bh(&mbid_cam_ctl->lock, &irqL);
1825 for (i = (TOTAL_MBID_CAM_NUM - 1); i >= 0; i--) {
1826 if (mbid_cam_ctl->bitmap & BIT(i)) {
1827 cam_id = i;
1828 break;
1829 }
1830 }
1831 _exit_critical_bh(&mbid_cam_ctl->lock, &irqL);
1832 /*RTW_INFO("%s max cam_id:%d\n", __func__, cam_id);*/
1833 return cam_id;
1834 }
1835
rtw_get_mbid_cam_entry_num(_adapter * adapter)1836 inline u8 rtw_get_mbid_cam_entry_num(_adapter *adapter)
1837 {
1838 struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
1839 struct mbid_cam_ctl_t *mbid_cam_ctl = &dvobj->mbid_cam_ctl;
1840
1841 return ATOMIC_READ(&mbid_cam_ctl->mbid_entry_num);
1842 }
1843
mbid_cam_cache_init(_adapter * adapter,struct mbid_cam_cache * pmbid_cam,u8 * mac_addr)1844 static inline void mbid_cam_cache_init(_adapter *adapter, struct mbid_cam_cache *pmbid_cam, u8 *mac_addr)
1845 {
1846 if (adapter && pmbid_cam && mac_addr) {
1847 _rtw_memcpy(pmbid_cam->mac_addr, mac_addr, ETH_ALEN);
1848 pmbid_cam->iface_id = adapter->iface_id;
1849 }
1850 }
mbid_cam_cache_clr(struct mbid_cam_cache * pmbid_cam)1851 static inline void mbid_cam_cache_clr(struct mbid_cam_cache *pmbid_cam)
1852 {
1853 if (pmbid_cam) {
1854 _rtw_memset(pmbid_cam->mac_addr, 0, ETH_ALEN);
1855 pmbid_cam->iface_id = CONFIG_IFACE_NUMBER;
1856 }
1857 }
1858
rtw_mbid_camid_alloc(_adapter * adapter,u8 * mac_addr)1859 u8 rtw_mbid_camid_alloc(_adapter *adapter, u8 *mac_addr)
1860 {
1861 _irqL irqL;
1862 u8 cam_id = INVALID_CAM_ID, i;
1863 struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
1864 struct mbid_cam_ctl_t *mbid_cam_ctl = &dvobj->mbid_cam_ctl;
1865 u8 entry_num = ATOMIC_READ(&mbid_cam_ctl->mbid_entry_num);
1866
1867 if (entry_num >= TOTAL_MBID_CAM_NUM) {
1868 RTW_INFO(FUNC_ADPT_FMT" failed !! MBSSID number :%d over TOTAL_CAM_ENTRY(8)\n", FUNC_ADPT_ARG(adapter), entry_num);
1869 rtw_warn_on(1);
1870 }
1871
1872 if (INVALID_CAM_ID != rtw_mbid_cam_search_by_macaddr(adapter, mac_addr))
1873 goto exit;
1874
1875 _enter_critical_bh(&mbid_cam_ctl->lock, &irqL);
1876 for (i = 0; i < TOTAL_MBID_CAM_NUM; i++) {
1877 if (!(mbid_cam_ctl->bitmap & BIT(i))) {
1878 mbid_cam_ctl->bitmap |= BIT(i);
1879 cam_id = i;
1880 break;
1881 }
1882 }
1883 if ((cam_id != INVALID_CAM_ID) && (mac_addr))
1884 mbid_cam_cache_init(adapter, &dvobj->mbid_cam_cache[cam_id], mac_addr);
1885 _exit_critical_bh(&mbid_cam_ctl->lock, &irqL);
1886
1887 if (cam_id != INVALID_CAM_ID) {
1888 ATOMIC_INC(&mbid_cam_ctl->mbid_entry_num);
1889 RTW_INFO("%s mac:"MAC_FMT" - cam_id:%d\n", __func__, MAC_ARG(mac_addr), cam_id);
1890 #ifdef DBG_MBID_CAM_DUMP
1891 rtw_mbid_cam_cache_dump(RTW_DBGDUMP, __func__, adapter);
1892 #endif
1893 } else
1894 RTW_INFO("%s [WARN] "MAC_FMT" - invalid cam_id:%d\n", __func__, MAC_ARG(mac_addr), cam_id);
1895 exit:
1896 return cam_id;
1897 }
1898
rtw_mbid_cam_info_change(_adapter * adapter,u8 * mac_addr)1899 u8 rtw_mbid_cam_info_change(_adapter *adapter, u8 *mac_addr)
1900 {
1901 _irqL irqL;
1902 u8 entry_id = INVALID_CAM_ID;
1903 struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
1904 struct mbid_cam_ctl_t *mbid_cam_ctl = &dvobj->mbid_cam_ctl;
1905
1906 _enter_critical_bh(&mbid_cam_ctl->lock, &irqL);
1907 entry_id = _rtw_mbid_cam_search_by_ifaceid(adapter, adapter->iface_id);
1908 if (entry_id != INVALID_CAM_ID)
1909 mbid_cam_cache_init(adapter, &dvobj->mbid_cam_cache[entry_id], mac_addr);
1910
1911 _exit_critical_bh(&mbid_cam_ctl->lock, &irqL);
1912
1913 return entry_id;
1914 }
1915
rtw_mbid_cam_assign(_adapter * adapter,u8 * mac_addr,u8 camid)1916 u8 rtw_mbid_cam_assign(_adapter *adapter, u8 *mac_addr, u8 camid)
1917 {
1918 _irqL irqL;
1919 u8 ret = _FALSE;
1920 struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
1921 struct mbid_cam_ctl_t *mbid_cam_ctl = &dvobj->mbid_cam_ctl;
1922
1923 if ((camid >= TOTAL_MBID_CAM_NUM) || (camid == INVALID_CAM_ID)) {
1924 RTW_INFO(FUNC_ADPT_FMT" failed !! invlaid mbid_canid :%d\n", FUNC_ADPT_ARG(adapter), camid);
1925 rtw_warn_on(1);
1926 }
1927 if (INVALID_CAM_ID != rtw_mbid_cam_search_by_macaddr(adapter, mac_addr))
1928 goto exit;
1929
1930 _enter_critical_bh(&mbid_cam_ctl->lock, &irqL);
1931 if (!(mbid_cam_ctl->bitmap & BIT(camid))) {
1932 if (mac_addr) {
1933 mbid_cam_ctl->bitmap |= BIT(camid);
1934 mbid_cam_cache_init(adapter, &dvobj->mbid_cam_cache[camid], mac_addr);
1935 ret = _TRUE;
1936 }
1937 }
1938 _exit_critical_bh(&mbid_cam_ctl->lock, &irqL);
1939
1940 if (ret == _TRUE) {
1941 ATOMIC_INC(&mbid_cam_ctl->mbid_entry_num);
1942 RTW_INFO("%s mac:"MAC_FMT" - cam_id:%d\n", __func__, MAC_ARG(mac_addr), camid);
1943 #ifdef DBG_MBID_CAM_DUMP
1944 rtw_mbid_cam_cache_dump(RTW_DBGDUMP, __func__, adapter);
1945 #endif
1946 } else
1947 RTW_INFO("%s [WARN] mac:"MAC_FMT" - cam_id:%d assigned failed\n", __func__, MAC_ARG(mac_addr), camid);
1948
1949 exit:
1950 return ret;
1951 }
1952
rtw_mbid_camid_clean(_adapter * adapter,u8 mbss_canid)1953 void rtw_mbid_camid_clean(_adapter *adapter, u8 mbss_canid)
1954 {
1955 _irqL irqL;
1956 struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
1957 struct mbid_cam_ctl_t *mbid_cam_ctl = &dvobj->mbid_cam_ctl;
1958
1959 if ((mbss_canid >= TOTAL_MBID_CAM_NUM) || (mbss_canid == INVALID_CAM_ID)) {
1960 RTW_INFO(FUNC_ADPT_FMT" failed !! invlaid mbid_canid :%d\n", FUNC_ADPT_ARG(adapter), mbss_canid);
1961 rtw_warn_on(1);
1962 }
1963 _enter_critical_bh(&mbid_cam_ctl->lock, &irqL);
1964 mbid_cam_cache_clr(&dvobj->mbid_cam_cache[mbss_canid]);
1965 mbid_cam_ctl->bitmap &= (~BIT(mbss_canid));
1966 _exit_critical_bh(&mbid_cam_ctl->lock, &irqL);
1967 ATOMIC_DEC(&mbid_cam_ctl->mbid_entry_num);
1968 RTW_INFO("%s - cam_id:%d\n", __func__, mbss_canid);
1969 }
rtw_mbid_cam_cache_dump(void * sel,const char * fun_name,_adapter * adapter)1970 int rtw_mbid_cam_cache_dump(void *sel, const char *fun_name, _adapter *adapter)
1971 {
1972 _irqL irqL;
1973 u8 i;
1974 _adapter *iface;
1975 u8 iface_id;
1976 struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
1977 struct mbid_cam_ctl_t *mbid_cam_ctl = &dvobj->mbid_cam_ctl;
1978 u8 entry_num = ATOMIC_READ(&mbid_cam_ctl->mbid_entry_num);
1979 u8 max_cam_id = rtw_get_max_mbid_cam_id(adapter);
1980
1981 RTW_PRINT_SEL(sel, "== MBSSID CAM DUMP (%s)==\n", fun_name);
1982
1983 _enter_critical_bh(&mbid_cam_ctl->lock, &irqL);
1984 RTW_PRINT_SEL(sel, "Entry numbers:%d, max_camid:%d, bitmap:0x%08x\n", entry_num, max_cam_id, mbid_cam_ctl->bitmap);
1985 for (i = 0; i < TOTAL_MBID_CAM_NUM; i++) {
1986 RTW_PRINT_SEL(sel, "CAM_ID = %d\t", i);
1987
1988 if (mbid_cam_ctl->bitmap & BIT(i)) {
1989 iface_id = dvobj->mbid_cam_cache[i].iface_id;
1990 RTW_PRINT_SEL(sel, "IF_ID:%d\t", iface_id);
1991 RTW_PRINT_SEL(sel, "MAC Addr:"MAC_FMT"\t", MAC_ARG(dvobj->mbid_cam_cache[i].mac_addr));
1992
1993 iface = dvobj->padapters[iface_id];
1994 if (iface) {
1995 if (check_fwstate(&iface->mlmepriv, WIFI_STATION_STATE) == _TRUE)
1996 RTW_PRINT_SEL(sel, "ROLE:%s\n", "STA");
1997 else if (check_fwstate(&iface->mlmepriv, WIFI_AP_STATE) == _TRUE)
1998 RTW_PRINT_SEL(sel, "ROLE:%s\n", "AP");
1999 else
2000 RTW_PRINT_SEL(sel, "ROLE:%s\n", "NONE");
2001 }
2002
2003 } else
2004 RTW_PRINT_SEL(sel, "N/A\n");
2005 }
2006 _exit_critical_bh(&mbid_cam_ctl->lock, &irqL);
2007 return 0;
2008 }
2009
read_mbssid_cam(_adapter * padapter,u8 cam_addr,u8 * mac)2010 static void read_mbssid_cam(_adapter *padapter, u8 cam_addr, u8 *mac)
2011 {
2012 u8 poll = 1;
2013 u8 cam_ready = _FALSE;
2014 u32 cam_data1 = 0;
2015 u16 cam_data2 = 0;
2016
2017 if (RTW_CANNOT_RUN(padapter))
2018 return;
2019
2020 rtw_write32(padapter, REG_MBIDCAMCFG_2, BIT_MBIDCAM_POLL | ((cam_addr & MBIDCAM_ADDR_MASK) << MBIDCAM_ADDR_SHIFT));
2021
2022 do {
2023 if (0 == (rtw_read32(padapter, REG_MBIDCAMCFG_2) & BIT_MBIDCAM_POLL)) {
2024 cam_ready = _TRUE;
2025 break;
2026 }
2027 poll++;
2028 } while ((poll % 10) != 0 && !RTW_CANNOT_RUN(padapter));
2029
2030 if (cam_ready) {
2031 cam_data1 = rtw_read32(padapter, REG_MBIDCAMCFG_1);
2032 mac[0] = cam_data1 & 0xFF;
2033 mac[1] = (cam_data1 >> 8) & 0xFF;
2034 mac[2] = (cam_data1 >> 16) & 0xFF;
2035 mac[3] = (cam_data1 >> 24) & 0xFF;
2036
2037 cam_data2 = rtw_read16(padapter, REG_MBIDCAMCFG_2);
2038 mac[4] = cam_data2 & 0xFF;
2039 mac[5] = (cam_data2 >> 8) & 0xFF;
2040 }
2041
2042 }
rtw_mbid_cam_dump(void * sel,const char * fun_name,_adapter * adapter)2043 int rtw_mbid_cam_dump(void *sel, const char *fun_name, _adapter *adapter)
2044 {
2045 /*_irqL irqL;*/
2046 u8 i;
2047 u8 mac_addr[ETH_ALEN];
2048
2049 struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
2050 struct mbid_cam_ctl_t *mbid_cam_ctl = &dvobj->mbid_cam_ctl;
2051
2052 RTW_PRINT_SEL(sel, "\n== MBSSID HW-CAM DUMP (%s)==\n", fun_name);
2053
2054 /*_enter_critical_bh(&mbid_cam_ctl->lock, &irqL);*/
2055 for (i = 0; i < TOTAL_MBID_CAM_NUM; i++) {
2056 RTW_PRINT_SEL(sel, "CAM_ID = %d\t", i);
2057 _rtw_memset(mac_addr, 0, ETH_ALEN);
2058 read_mbssid_cam(adapter, i, mac_addr);
2059 RTW_PRINT_SEL(sel, "MAC Addr:"MAC_FMT"\n", MAC_ARG(mac_addr));
2060 }
2061 /*_exit_critical_bh(&mbid_cam_ctl->lock, &irqL);*/
2062 return 0;
2063 }
2064
write_mbssid_cam(_adapter * padapter,u8 cam_addr,u8 * mac)2065 static void write_mbssid_cam(_adapter *padapter, u8 cam_addr, u8 *mac)
2066 {
2067 u32 cam_val[2] = {0};
2068
2069 cam_val[0] = (mac[3] << 24) | (mac[2] << 16) | (mac[1] << 8) | mac[0];
2070 cam_val[1] = ((cam_addr & MBIDCAM_ADDR_MASK) << MBIDCAM_ADDR_SHIFT) | (mac[5] << 8) | mac[4];
2071
2072 rtw_hal_set_hwreg(padapter, HW_VAR_MBSSID_CAM_WRITE, (u8 *)cam_val);
2073 }
2074
clear_mbssid_cam(_adapter * padapter,u8 cam_addr)2075 static void clear_mbssid_cam(_adapter *padapter, u8 cam_addr)
2076 {
2077 rtw_hal_set_hwreg(padapter, HW_VAR_MBSSID_CAM_CLEAR, &cam_addr);
2078 }
enable_mbssid_cam(_adapter * adapter)2079 static void enable_mbssid_cam(_adapter *adapter)
2080 {
2081 u8 max_cam_id = rtw_get_max_mbid_cam_id(adapter);
2082 /*enable MBSSID*/
2083 rtw_write32(adapter, REG_RCR, rtw_read32(adapter, REG_RCR) | RCR_ENMBID);
2084 if (max_cam_id != INVALID_CAM_ID) {
2085 rtw_write8(adapter, REG_MBID_NUM,
2086 ((rtw_read8(adapter, REG_MBID_NUM) & 0xF8) | (max_cam_id & 0x07)));
2087 }
2088 }
rtw_mbid_cam_restore(_adapter * adapter)2089 void rtw_mbid_cam_restore(_adapter *adapter)
2090 {
2091 u8 i;
2092 struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
2093 struct mbid_cam_ctl_t *mbid_cam_ctl = &dvobj->mbid_cam_ctl;
2094
2095 #ifdef DBG_MBID_CAM_DUMP
2096 rtw_mbid_cam_cache_dump(RTW_DBGDUMP, __func__, adapter);
2097 #endif
2098
2099 for (i = 0; i < TOTAL_MBID_CAM_NUM; i++) {
2100 if (mbid_cam_ctl->bitmap & BIT(i)) {
2101 write_mbssid_cam(adapter, i, dvobj->mbid_cam_cache[i].mac_addr);
2102 RTW_INFO("%s - cam_id:%d => mac:"MAC_FMT"\n", __func__, i, MAC_ARG(dvobj->mbid_cam_cache[i].mac_addr));
2103 }
2104 }
2105 enable_mbssid_cam(adapter);
2106 }
2107 #endif /*CONFIG_MBSSID_CAM*/
2108
2109 #ifdef CONFIG_MI_WITH_MBSSID_CAM
rtw_hal_set_macaddr_mbid(_adapter * adapter,u8 * mac_addr)2110 void rtw_hal_set_macaddr_mbid(_adapter *adapter, u8 *mac_addr)
2111 {
2112
2113 #if 0 /*TODO - modify for more flexible*/
2114 u8 idx = 0;
2115
2116 if ((check_fwstate(&adapter->mlmepriv, WIFI_STATION_STATE) == _TRUE) &&
2117 (adapter_to_dvobj(adapter)->iface_state.sta_num == 1)) {
2118 for (idx = 0; idx < 6; idx++)
2119 rtw_write8(GET_PRIMARY_ADAPTER(adapter), (REG_MACID + idx), val[idx]);
2120 } else {
2121 /*MBID entry_id = 0~7 ,0 for root AP, 1~7 for VAP*/
2122 u8 entry_id;
2123
2124 if ((check_fwstate(&adapter->mlmepriv, WIFI_AP_STATE) == _TRUE) &&
2125 (adapter_to_dvobj(adapter)->iface_state.ap_num == 1)) {
2126 entry_id = 0;
2127 if (rtw_mbid_cam_assign(adapter, val, entry_id)) {
2128 RTW_INFO(FUNC_ADPT_FMT" Root AP assigned success\n", FUNC_ADPT_ARG(adapter));
2129 write_mbssid_cam(adapter, entry_id, val);
2130 }
2131 } else {
2132 entry_id = rtw_mbid_camid_alloc(adapter, val);
2133 if (entry_id != INVALID_CAM_ID)
2134 write_mbssid_cam(adapter, entry_id, val);
2135 }
2136 }
2137 #else
2138 {
2139 /*
2140 MBID entry_id = 0~7 ,for IFACE_ID0 ~ IFACE_IDx
2141 */
2142 u8 entry_id = rtw_mbid_camid_alloc(adapter, mac_addr);
2143
2144
2145 if (entry_id != INVALID_CAM_ID) {
2146 write_mbssid_cam(adapter, entry_id, mac_addr);
2147 enable_mbssid_cam(adapter);
2148 }
2149 }
2150 #endif
2151 }
2152
rtw_hal_change_macaddr_mbid(_adapter * adapter,u8 * mac_addr)2153 void rtw_hal_change_macaddr_mbid(_adapter *adapter, u8 *mac_addr)
2154 {
2155 u8 idx = 0;
2156 struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
2157 u8 entry_id;
2158
2159 if (!mac_addr) {
2160 rtw_warn_on(1);
2161 return;
2162 }
2163
2164
2165 entry_id = rtw_mbid_cam_info_change(adapter, mac_addr);
2166
2167 if (entry_id != INVALID_CAM_ID)
2168 write_mbssid_cam(adapter, entry_id, mac_addr);
2169 }
2170
2171
2172 #endif/*#ifdef CONFIG_MI_WITH_MBSSID_CAM*/
2173
rtw_hal_set_macaddr_port(_adapter * adapter,u8 * val)2174 void rtw_hal_set_macaddr_port(_adapter *adapter, u8 *val)
2175 {
2176 u8 idx = 0;
2177 u32 reg_macid = 0;
2178
2179 if (val == NULL)
2180 return;
2181
2182 RTW_INFO("%s "ADPT_FMT"- hw port(%d) mac_addr ="MAC_FMT"\n", __func__,
2183 ADPT_ARG(adapter), adapter->hw_port, MAC_ARG(val));
2184
2185 switch (adapter->hw_port) {
2186 case HW_PORT0:
2187 default:
2188 reg_macid = REG_MACID;
2189 break;
2190 case HW_PORT1:
2191 reg_macid = REG_MACID1;
2192 break;
2193 #if defined(CONFIG_RTL8814A)
2194 case HW_PORT2:
2195 reg_macid = REG_MACID2;
2196 break;
2197 case HW_PORT3:
2198 reg_macid = REG_MACID3;
2199 break;
2200 case HW_PORT4:
2201 reg_macid = REG_MACID4;
2202 break;
2203 #endif/*defined(CONFIG_RTL8814A)*/
2204 }
2205
2206 for (idx = 0; idx < 6; idx++)
2207 rtw_write8(GET_PRIMARY_ADAPTER(adapter), (reg_macid + idx), val[idx]);
2208 }
rtw_hal_get_macaddr_port(_adapter * adapter,u8 * mac_addr)2209 void rtw_hal_get_macaddr_port(_adapter *adapter, u8 *mac_addr)
2210 {
2211 u8 idx = 0;
2212 u32 reg_macid = 0;
2213
2214 if (mac_addr == NULL)
2215 return;
2216
2217 _rtw_memset(mac_addr, 0, ETH_ALEN);
2218 switch (adapter->hw_port) {
2219 case HW_PORT0:
2220 default:
2221 reg_macid = REG_MACID;
2222 break;
2223 case HW_PORT1:
2224 reg_macid = REG_MACID1;
2225 break;
2226 #if defined(CONFIG_RTL8814A)
2227 case HW_PORT2:
2228 reg_macid = REG_MACID2;
2229 break;
2230 case HW_PORT3:
2231 reg_macid = REG_MACID3;
2232 break;
2233 case HW_PORT4:
2234 reg_macid = REG_MACID4;
2235 break;
2236 #endif /*defined(CONFIG_RTL8814A)*/
2237 }
2238
2239 for (idx = 0; idx < 6; idx++)
2240 mac_addr[idx] = rtw_read8(GET_PRIMARY_ADAPTER(adapter), (reg_macid + idx));
2241
2242 RTW_INFO("%s "ADPT_FMT"- hw port(%d) mac_addr ="MAC_FMT"\n", __func__,
2243 ADPT_ARG(adapter), adapter->hw_port, MAC_ARG(mac_addr));
2244 }
2245
rtw_hal_set_bssid(_adapter * adapter,u8 * val)2246 void rtw_hal_set_bssid(_adapter *adapter, u8 *val)
2247 {
2248 u8 idx = 0;
2249 u32 reg_bssid = 0;
2250
2251 switch (adapter->hw_port) {
2252 case HW_PORT0:
2253 default:
2254 reg_bssid = REG_BSSID;
2255 break;
2256 case HW_PORT1:
2257 reg_bssid = REG_BSSID1;
2258 break;
2259 #if defined(CONFIG_RTL8814A) || defined(CONFIG_RTL8822B)
2260 case HW_PORT2:
2261 reg_bssid = REG_BSSID2;
2262 break;
2263 case HW_PORT3:
2264 reg_bssid = REG_BSSID3;
2265 break;
2266 case HW_PORT4:
2267 reg_bssid = REG_BSSID4;
2268 break;
2269 #endif/*defined(CONFIG_RTL8814A) || defined(CONFIG_RTL8822B)*/
2270 }
2271
2272 for (idx = 0 ; idx < 6; idx++)
2273 rtw_write8(adapter, (reg_bssid + idx), val[idx]);
2274
2275 RTW_INFO("%s "ADPT_FMT"- hw port -%d BSSID: "MAC_FMT"\n", __func__, ADPT_ARG(adapter), adapter->hw_port, MAC_ARG(val));
2276 }
2277
rtw_hal_get_msr(_adapter * adapter,u8 * net_type)2278 void rtw_hal_get_msr(_adapter *adapter, u8 *net_type)
2279 {
2280 switch (adapter->hw_port) {
2281 case HW_PORT0:
2282 /*REG_CR - BIT[17:16]-Network Type for port 1*/
2283 *net_type = rtw_read8(adapter, MSR) & 0x03;
2284 break;
2285 case HW_PORT1:
2286 /*REG_CR - BIT[19:18]-Network Type for port 1*/
2287 *net_type = (rtw_read8(adapter, MSR) & 0x0C) >> 2;
2288 break;
2289 #if defined(CONFIG_RTL8814A) || defined(CONFIG_RTL8822B)
2290 case HW_PORT2:
2291 /*REG_CR_EXT- BIT[1:0]-Network Type for port 2*/
2292 *net_type = rtw_read8(adapter, MSR1) & 0x03;
2293 break;
2294 case HW_PORT3:
2295 /*REG_CR_EXT- BIT[3:2]-Network Type for port 3*/
2296 *net_type = (rtw_read8(adapter, MSR1) & 0x0C) >> 2;
2297 break;
2298 case HW_PORT4:
2299 /*REG_CR_EXT- BIT[5:4]-Network Type for port 4*/
2300 *net_type = (rtw_read8(adapter, MSR1) & 0x30) >> 4;
2301 break;
2302 #endif /*#if defined(CONFIG_RTL8814A) || defined(CONFIG_RTL8822B)*/
2303 default:
2304 RTW_INFO("[WARN] "ADPT_FMT"- invalid hw port -%d\n",
2305 ADPT_ARG(adapter), adapter->hw_port);
2306 rtw_warn_on(1);
2307 break;
2308 }
2309 }
2310
rtw_hal_set_msr(_adapter * adapter,u8 net_type)2311 void rtw_hal_set_msr(_adapter *adapter, u8 net_type)
2312 {
2313 u8 val8 = 0;
2314
2315 switch (adapter->hw_port) {
2316 case HW_PORT0:
2317 #if defined(CONFIG_MI_WITH_MBSSID_CAM) && defined(CONFIG_MBSSID_CAM) /*For 2 hw ports - 88E/92E/8812/8821/8723B*/
2318 if (rtw_get_mbid_cam_entry_num(adapter)) {
2319 if (net_type != _HW_STATE_NOLINK_)
2320 net_type = _HW_STATE_AP_;
2321 }
2322 #endif
2323 /*REG_CR - BIT[17:16]-Network Type for port 0*/
2324 val8 = rtw_read8(adapter, MSR) & 0x0C;
2325 val8 |= net_type;
2326 rtw_write8(adapter, MSR, val8);
2327 break;
2328 case HW_PORT1:
2329 /*REG_CR - BIT[19:18]-Network Type for port 1*/
2330 val8 = rtw_read8(adapter, MSR) & 0x03;
2331 val8 |= net_type << 2;
2332 rtw_write8(adapter, MSR, val8);
2333 break;
2334 #if defined(CONFIG_RTL8814A) || defined(CONFIG_RTL8822B) || defined(CONFIG_RTL8821C)
2335 case HW_PORT2:
2336 /*REG_CR_EXT- BIT[1:0]-Network Type for port 2*/
2337 val8 = rtw_read8(adapter, MSR1) & 0xFC;
2338 val8 |= net_type;
2339 rtw_write8(adapter, MSR1, val8);
2340 break;
2341 case HW_PORT3:
2342 /*REG_CR_EXT- BIT[3:2]-Network Type for port 3*/
2343 val8 = rtw_read8(adapter, MSR1) & 0xF3;
2344 val8 |= net_type << 2;
2345 rtw_write8(adapter, MSR1, val8);
2346 break;
2347 case HW_PORT4:
2348 /*REG_CR_EXT- BIT[5:4]-Network Type for port 4*/
2349 val8 = rtw_read8(adapter, MSR1) & 0xCF;
2350 val8 |= net_type << 4;
2351 rtw_write8(adapter, MSR1, val8);
2352 break;
2353 #endif /* CONFIG_RTL8814A | CONFIG_RTL8822B */
2354 default:
2355 RTW_INFO("[WARN] "ADPT_FMT"- invalid hw port -%d\n",
2356 ADPT_ARG(adapter), adapter->hw_port);
2357 rtw_warn_on(1);
2358 break;
2359 }
2360 }
2361
rtw_hal_port_reconfig(_adapter * adapter,u8 port)2362 void rtw_hal_port_reconfig(_adapter *adapter, u8 port)
2363 {
2364 #ifdef CONFIG_CONCURRENT_MODE
2365 u8 hal_port_num = 0;
2366 struct hal_spec_t *hal_spec = GET_HAL_SPEC(adapter);
2367 struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
2368
2369 if (port > (hal_spec->port_num - 1)) {
2370 RTW_INFO("[WARN] "ADPT_FMT"- hw_port : %d,will switch to invalid port-%d\n",
2371 ADPT_ARG(adapter), adapter->hw_port, port);
2372 rtw_warn_on(1);
2373 }
2374
2375 RTW_PRINT(ADPT_FMT"- hw_port : %d,will switch to port-%d\n",
2376 ADPT_ARG(adapter), adapter->hw_port, port);
2377
2378 #endif
2379
2380 }
2381
2382
hw_var_port_switch(_adapter * adapter)2383 void hw_var_port_switch(_adapter *adapter)
2384 {
2385 #ifdef CONFIG_CONCURRENT_MODE
2386 #ifdef CONFIG_RUNTIME_PORT_SWITCH
2387 /*
2388 0x102: MSR
2389 0x550: REG_BCN_CTRL
2390 0x551: REG_BCN_CTRL_1
2391 0x55A: REG_ATIMWND
2392 0x560: REG_TSFTR
2393 0x568: REG_TSFTR1
2394 0x570: REG_ATIMWND_1
2395 0x610: REG_MACID
2396 0x618: REG_BSSID
2397 0x700: REG_MACID1
2398 0x708: REG_BSSID1
2399 */
2400
2401 int i;
2402 u8 msr;
2403 u8 bcn_ctrl;
2404 u8 bcn_ctrl_1;
2405 u8 atimwnd[2];
2406 u8 atimwnd_1[2];
2407 u8 tsftr[8];
2408 u8 tsftr_1[8];
2409 u8 macid[6];
2410 u8 bssid[6];
2411 u8 macid_1[6];
2412 u8 bssid_1[6];
2413
2414 u8 hw_port;
2415 struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
2416 _adapter *iface = NULL;
2417
2418 msr = rtw_read8(adapter, MSR);
2419 bcn_ctrl = rtw_read8(adapter, REG_BCN_CTRL);
2420 bcn_ctrl_1 = rtw_read8(adapter, REG_BCN_CTRL_1);
2421
2422 for (i = 0; i < 2; i++)
2423 atimwnd[i] = rtw_read8(adapter, REG_ATIMWND + i);
2424 for (i = 0; i < 2; i++)
2425 atimwnd_1[i] = rtw_read8(adapter, REG_ATIMWND_1 + i);
2426
2427 for (i = 0; i < 8; i++)
2428 tsftr[i] = rtw_read8(adapter, REG_TSFTR + i);
2429 for (i = 0; i < 8; i++)
2430 tsftr_1[i] = rtw_read8(adapter, REG_TSFTR1 + i);
2431
2432 for (i = 0; i < 6; i++)
2433 macid[i] = rtw_read8(adapter, REG_MACID + i);
2434
2435 for (i = 0; i < 6; i++)
2436 bssid[i] = rtw_read8(adapter, REG_BSSID + i);
2437
2438 for (i = 0; i < 6; i++)
2439 macid_1[i] = rtw_read8(adapter, REG_MACID1 + i);
2440
2441 for (i = 0; i < 6; i++)
2442 bssid_1[i] = rtw_read8(adapter, REG_BSSID1 + i);
2443
2444 #ifdef DBG_RUNTIME_PORT_SWITCH
2445 RTW_INFO(FUNC_ADPT_FMT" before switch\n"
2446 "msr:0x%02x\n"
2447 "bcn_ctrl:0x%02x\n"
2448 "bcn_ctrl_1:0x%02x\n"
2449 "atimwnd:0x%04x\n"
2450 "atimwnd_1:0x%04x\n"
2451 "tsftr:%llu\n"
2452 "tsftr1:%llu\n"
2453 "macid:"MAC_FMT"\n"
2454 "bssid:"MAC_FMT"\n"
2455 "macid_1:"MAC_FMT"\n"
2456 "bssid_1:"MAC_FMT"\n"
2457 , FUNC_ADPT_ARG(adapter)
2458 , msr
2459 , bcn_ctrl
2460 , bcn_ctrl_1
2461 , *((u16 *)atimwnd)
2462 , *((u16 *)atimwnd_1)
2463 , *((u64 *)tsftr)
2464 , *((u64 *)tsftr_1)
2465 , MAC_ARG(macid)
2466 , MAC_ARG(bssid)
2467 , MAC_ARG(macid_1)
2468 , MAC_ARG(bssid_1)
2469 );
2470 #endif /* DBG_RUNTIME_PORT_SWITCH */
2471
2472 /* disable bcn function, disable update TSF */
2473 rtw_write8(adapter, REG_BCN_CTRL, (bcn_ctrl & (~EN_BCN_FUNCTION)) | DIS_TSF_UDT);
2474 rtw_write8(adapter, REG_BCN_CTRL_1, (bcn_ctrl_1 & (~EN_BCN_FUNCTION)) | DIS_TSF_UDT);
2475
2476 /* switch msr */
2477 msr = (msr & 0xf0) | ((msr & 0x03) << 2) | ((msr & 0x0c) >> 2);
2478 rtw_write8(adapter, MSR, msr);
2479
2480 /* write port0 */
2481 rtw_write8(adapter, REG_BCN_CTRL, bcn_ctrl_1 & ~EN_BCN_FUNCTION);
2482 for (i = 0; i < 2; i++)
2483 rtw_write8(adapter, REG_ATIMWND + i, atimwnd_1[i]);
2484 for (i = 0; i < 8; i++)
2485 rtw_write8(adapter, REG_TSFTR + i, tsftr_1[i]);
2486 for (i = 0; i < 6; i++)
2487 rtw_write8(adapter, REG_MACID + i, macid_1[i]);
2488 for (i = 0; i < 6; i++)
2489 rtw_write8(adapter, REG_BSSID + i, bssid_1[i]);
2490
2491 /* write port1 */
2492 rtw_write8(adapter, REG_BCN_CTRL_1, bcn_ctrl & ~EN_BCN_FUNCTION);
2493 for (i = 0; i < 2; i++)
2494 rtw_write8(adapter, REG_ATIMWND_1 + i, atimwnd[i]);
2495 for (i = 0; i < 8; i++)
2496 rtw_write8(adapter, REG_TSFTR1 + i, tsftr[i]);
2497 for (i = 0; i < 6; i++)
2498 rtw_write8(adapter, REG_MACID1 + i, macid[i]);
2499 for (i = 0; i < 6; i++)
2500 rtw_write8(adapter, REG_BSSID1 + i, bssid[i]);
2501
2502 /* write bcn ctl */
2503 #ifdef CONFIG_BT_COEXIST
2504 /* always enable port0 beacon function for PSTDMA */
2505 if (IS_HARDWARE_TYPE_8723B(adapter) || IS_HARDWARE_TYPE_8703B(adapter)
2506 || IS_HARDWARE_TYPE_8723D(adapter))
2507 bcn_ctrl_1 |= EN_BCN_FUNCTION;
2508 /* always disable port1 beacon function for PSTDMA */
2509 if (IS_HARDWARE_TYPE_8723B(adapter) || IS_HARDWARE_TYPE_8703B(adapter))
2510 bcn_ctrl &= ~EN_BCN_FUNCTION;
2511 #endif
2512 rtw_write8(adapter, REG_BCN_CTRL, bcn_ctrl_1);
2513 rtw_write8(adapter, REG_BCN_CTRL_1, bcn_ctrl);
2514
2515 if (adapter->iface_id == IFACE_ID0)
2516 iface = dvobj->padapters[IFACE_ID1];
2517 else if (adapter->iface_id == IFACE_ID1)
2518 iface = dvobj->padapters[IFACE_ID0];
2519
2520
2521 if (adapter->hw_port == HW_PORT0) {
2522 adapter->hw_port = HW_PORT1;
2523 iface->hw_port = HW_PORT0;
2524 RTW_PRINT("port switch - port0("ADPT_FMT"), port1("ADPT_FMT")\n",
2525 ADPT_ARG(iface), ADPT_ARG(adapter));
2526 } else {
2527 adapter->hw_port = HW_PORT0;
2528 iface->hw_port = HW_PORT1;
2529 RTW_PRINT("port switch - port0("ADPT_FMT"), port1("ADPT_FMT")\n",
2530 ADPT_ARG(adapter), ADPT_ARG(iface));
2531 }
2532
2533 #ifdef DBG_RUNTIME_PORT_SWITCH
2534 msr = rtw_read8(adapter, MSR);
2535 bcn_ctrl = rtw_read8(adapter, REG_BCN_CTRL);
2536 bcn_ctrl_1 = rtw_read8(adapter, REG_BCN_CTRL_1);
2537
2538 for (i = 0; i < 2; i++)
2539 atimwnd[i] = rtw_read8(adapter, REG_ATIMWND + i);
2540 for (i = 0; i < 2; i++)
2541 atimwnd_1[i] = rtw_read8(adapter, REG_ATIMWND_1 + i);
2542
2543 for (i = 0; i < 8; i++)
2544 tsftr[i] = rtw_read8(adapter, REG_TSFTR + i);
2545 for (i = 0; i < 8; i++)
2546 tsftr_1[i] = rtw_read8(adapter, REG_TSFTR1 + i);
2547
2548 for (i = 0; i < 6; i++)
2549 macid[i] = rtw_read8(adapter, REG_MACID + i);
2550
2551 for (i = 0; i < 6; i++)
2552 bssid[i] = rtw_read8(adapter, REG_BSSID + i);
2553
2554 for (i = 0; i < 6; i++)
2555 macid_1[i] = rtw_read8(adapter, REG_MACID1 + i);
2556
2557 for (i = 0; i < 6; i++)
2558 bssid_1[i] = rtw_read8(adapter, REG_BSSID1 + i);
2559
2560 RTW_INFO(FUNC_ADPT_FMT" after switch\n"
2561 "msr:0x%02x\n"
2562 "bcn_ctrl:0x%02x\n"
2563 "bcn_ctrl_1:0x%02x\n"
2564 "atimwnd:%u\n"
2565 "atimwnd_1:%u\n"
2566 "tsftr:%llu\n"
2567 "tsftr1:%llu\n"
2568 "macid:"MAC_FMT"\n"
2569 "bssid:"MAC_FMT"\n"
2570 "macid_1:"MAC_FMT"\n"
2571 "bssid_1:"MAC_FMT"\n"
2572 , FUNC_ADPT_ARG(adapter)
2573 , msr
2574 , bcn_ctrl
2575 , bcn_ctrl_1
2576 , *((u16 *)atimwnd)
2577 , *((u16 *)atimwnd_1)
2578 , *((u64 *)tsftr)
2579 , *((u64 *)tsftr_1)
2580 , MAC_ARG(macid)
2581 , MAC_ARG(bssid)
2582 , MAC_ARG(macid_1)
2583 , MAC_ARG(bssid_1)
2584 );
2585 #endif /* DBG_RUNTIME_PORT_SWITCH */
2586
2587 #endif /* CONFIG_RUNTIME_PORT_SWITCH */
2588 #endif /* CONFIG_CONCURRENT_MODE */
2589 }
2590
2591 const char *const _h2c_msr_role_str[] = {
2592 "RSVD",
2593 "STA",
2594 "AP",
2595 "GC",
2596 "GO",
2597 "TDLS",
2598 "ADHOC",
2599 "INVALID",
2600 };
2601
2602 /*
2603 * rtw_hal_set_FwMediaStatusRpt_cmd -
2604 *
2605 * @adapter:
2606 * @opmode: 0:disconnect, 1:connect
2607 * @miracast: 0:it's not in miracast scenario. 1:it's in miracast scenario
2608 * @miracast_sink: 0:source. 1:sink
2609 * @role: The role of this macid. 0:rsvd. 1:STA. 2:AP. 3:GC. 4:GO. 5:TDLS
2610 * @macid:
2611 * @macid_ind: 0:update Media Status to macid. 1:update Media Status from macid to macid_end
2612 * @macid_end:
2613 */
rtw_hal_set_FwMediaStatusRpt_cmd(_adapter * adapter,bool opmode,bool miracast,bool miracast_sink,u8 role,u8 macid,bool macid_ind,u8 macid_end)2614 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)
2615 {
2616 struct macid_ctl_t *macid_ctl = &adapter->dvobj->macid_ctl;
2617 u8 parm[H2C_MEDIA_STATUS_RPT_LEN] = {0};
2618 int i;
2619 s32 ret;
2620
2621 SET_H2CCMD_MSRRPT_PARM_OPMODE(parm, opmode);
2622 SET_H2CCMD_MSRRPT_PARM_MACID_IND(parm, macid_ind);
2623 SET_H2CCMD_MSRRPT_PARM_MIRACAST(parm, miracast);
2624 SET_H2CCMD_MSRRPT_PARM_MIRACAST_SINK(parm, miracast_sink);
2625 SET_H2CCMD_MSRRPT_PARM_ROLE(parm, role);
2626 SET_H2CCMD_MSRRPT_PARM_MACID(parm, macid);
2627 SET_H2CCMD_MSRRPT_PARM_MACID_END(parm, macid_end);
2628
2629 RTW_DBG_DUMP("MediaStatusRpt parm:", parm, H2C_MEDIA_STATUS_RPT_LEN);
2630
2631 #ifdef CONFIG_DFS_MASTER
2632 /* workaround for TXPAUSE cleared issue by FW's MediaStatusRpt handling */
2633 if (macid_ind == 0 && macid == 1) {
2634 u8 parm0_bak = parm[0];
2635
2636 SET_H2CCMD_MSRRPT_PARM_MACID_IND(&parm0_bak, 0);
2637 if (macid_ctl->h2c_msr[macid] == parm0_bak) {
2638 ret = _SUCCESS;
2639 goto post_action;
2640 }
2641 }
2642 #endif
2643
2644 ret = rtw_hal_fill_h2c_cmd(adapter, H2C_MEDIA_STATUS_RPT, H2C_MEDIA_STATUS_RPT_LEN, parm);
2645 if (ret != _SUCCESS)
2646 goto exit;
2647
2648 #ifdef CONFIG_DFS_MASTER
2649 post_action:
2650 #endif
2651
2652 #if defined(CONFIG_RTL8188E)
2653 if (rtw_get_chip_type(adapter) == RTL8188E) {
2654 HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
2655
2656 /* 8188E FW doesn't set macid no link, driver does it by self */
2657 if (opmode)
2658 rtw_hal_set_hwreg(adapter, HW_VAR_MACID_LINK, &macid);
2659 else
2660 rtw_hal_set_hwreg(adapter, HW_VAR_MACID_NOLINK, &macid);
2661
2662 /* for 8188E RA */
2663 #if (RATE_ADAPTIVE_SUPPORT == 1)
2664 if (hal_data->fw_ractrl == _FALSE) {
2665 u8 max_macid;
2666
2667 max_macid = rtw_search_max_mac_id(adapter);
2668 rtw_hal_set_hwreg(adapter, HW_VAR_TX_RPT_MAX_MACID, &max_macid);
2669 }
2670 #endif
2671 }
2672 #endif
2673
2674 #if defined(CONFIG_RTL8812A) || defined(CONFIG_RTL8821A)
2675 /* TODO: this should move to IOT issue area */
2676 if (rtw_get_chip_type(adapter) == RTL8812
2677 || rtw_get_chip_type(adapter) == RTL8821
2678 ) {
2679 if (MLME_IS_STA(adapter))
2680 Hal_PatchwithJaguar_8812(adapter, opmode);
2681 }
2682 #endif
2683
2684 SET_H2CCMD_MSRRPT_PARM_MACID_IND(parm, 0);
2685 if (macid_ind == 0)
2686 macid_end = macid;
2687
2688 for (i = macid; macid <= macid_end; macid++)
2689 rtw_macid_ctl_set_h2c_msr(macid_ctl, macid, parm[0]);
2690
2691 exit:
2692 return ret;
2693 }
2694
rtw_hal_set_FwMediaStatusRpt_single_cmd(_adapter * adapter,bool opmode,bool miracast,bool miracast_sink,u8 role,u8 macid)2695 inline s32 rtw_hal_set_FwMediaStatusRpt_single_cmd(_adapter *adapter, bool opmode, bool miracast, bool miracast_sink, u8 role, u8 macid)
2696 {
2697 return rtw_hal_set_FwMediaStatusRpt_cmd(adapter, opmode, miracast, miracast_sink, role, macid, 0, 0);
2698 }
2699
rtw_hal_set_FwMediaStatusRpt_range_cmd(_adapter * adapter,bool opmode,bool miracast,bool miracast_sink,u8 role,u8 macid,u8 macid_end)2700 inline s32 rtw_hal_set_FwMediaStatusRpt_range_cmd(_adapter *adapter, bool opmode, bool miracast, bool miracast_sink, u8 role, u8 macid, u8 macid_end)
2701 {
2702 return rtw_hal_set_FwMediaStatusRpt_cmd(adapter, opmode, miracast, miracast_sink, role, macid, 1, macid_end);
2703 }
2704
rtw_hal_set_FwRsvdPage_cmd(PADAPTER padapter,PRSVDPAGE_LOC rsvdpageloc)2705 void rtw_hal_set_FwRsvdPage_cmd(PADAPTER padapter, PRSVDPAGE_LOC rsvdpageloc)
2706 {
2707 struct hal_ops *pHalFunc = &padapter->HalFunc;
2708 u8 u1H2CRsvdPageParm[H2C_RSVDPAGE_LOC_LEN] = {0};
2709 u8 ret = 0;
2710
2711 RTW_INFO("RsvdPageLoc: ProbeRsp=%d PsPoll=%d Null=%d QoSNull=%d BTNull=%d\n",
2712 rsvdpageloc->LocProbeRsp, rsvdpageloc->LocPsPoll,
2713 rsvdpageloc->LocNullData, rsvdpageloc->LocQosNull,
2714 rsvdpageloc->LocBTQosNull);
2715
2716 SET_H2CCMD_RSVDPAGE_LOC_PROBE_RSP(u1H2CRsvdPageParm, rsvdpageloc->LocProbeRsp);
2717 SET_H2CCMD_RSVDPAGE_LOC_PSPOLL(u1H2CRsvdPageParm, rsvdpageloc->LocPsPoll);
2718 SET_H2CCMD_RSVDPAGE_LOC_NULL_DATA(u1H2CRsvdPageParm, rsvdpageloc->LocNullData);
2719 SET_H2CCMD_RSVDPAGE_LOC_QOS_NULL_DATA(u1H2CRsvdPageParm, rsvdpageloc->LocQosNull);
2720 SET_H2CCMD_RSVDPAGE_LOC_BT_QOS_NULL_DATA(u1H2CRsvdPageParm, rsvdpageloc->LocBTQosNull);
2721
2722 ret = rtw_hal_fill_h2c_cmd(padapter,
2723 H2C_RSVD_PAGE,
2724 H2C_RSVDPAGE_LOC_LEN,
2725 u1H2CRsvdPageParm);
2726
2727 }
2728
2729 #ifdef CONFIG_GPIO_WAKEUP
rtw_hal_switch_gpio_wl_ctrl(_adapter * padapter,u8 index,u8 enable)2730 void rtw_hal_switch_gpio_wl_ctrl(_adapter *padapter, u8 index, u8 enable)
2731 {
2732 /*
2733 * Switch GPIO_13, GPIO_14 to wlan control, or pull GPIO_13,14 MUST fail.
2734 * It happended at 8723B/8192E/8821A. New IC will check multi function GPIO,
2735 * and implement HAL function.
2736 * TODO: GPIO_8 multi function?
2737 */
2738 if (index == 13 || index == 14)
2739 rtw_hal_set_hwreg(padapter, HW_SET_GPIO_WL_CTRL, (u8 *)(&enable));
2740 }
2741
rtw_hal_set_output_gpio(_adapter * padapter,u8 index,u8 outputval)2742 void rtw_hal_set_output_gpio(_adapter *padapter, u8 index, u8 outputval)
2743 {
2744 if (index <= 7) {
2745 /* config GPIO mode */
2746 rtw_write8(padapter, REG_GPIO_PIN_CTRL + 3,
2747 rtw_read8(padapter, REG_GPIO_PIN_CTRL + 3) & ~BIT(index));
2748
2749 /* config GPIO Sel */
2750 /* 0: input */
2751 /* 1: output */
2752 rtw_write8(padapter, REG_GPIO_PIN_CTRL + 2,
2753 rtw_read8(padapter, REG_GPIO_PIN_CTRL + 2) | BIT(index));
2754
2755 /* set output value */
2756 if (outputval) {
2757 rtw_write8(padapter, REG_GPIO_PIN_CTRL + 1,
2758 rtw_read8(padapter, REG_GPIO_PIN_CTRL + 1) | BIT(index));
2759 } else {
2760 rtw_write8(padapter, REG_GPIO_PIN_CTRL + 1,
2761 rtw_read8(padapter, REG_GPIO_PIN_CTRL + 1) & ~BIT(index));
2762 }
2763 } else if (index <= 15) {
2764 /* 88C Series: */
2765 /* index: 11~8 transform to 3~0 */
2766 /* 8723 Series: */
2767 /* index: 12~8 transform to 4~0 */
2768
2769 index -= 8;
2770
2771 /* config GPIO mode */
2772 rtw_write8(padapter, REG_GPIO_PIN_CTRL_2 + 3,
2773 rtw_read8(padapter, REG_GPIO_PIN_CTRL_2 + 3) & ~BIT(index));
2774
2775 /* config GPIO Sel */
2776 /* 0: input */
2777 /* 1: output */
2778 rtw_write8(padapter, REG_GPIO_PIN_CTRL_2 + 2,
2779 rtw_read8(padapter, REG_GPIO_PIN_CTRL_2 + 2) | BIT(index));
2780
2781 /* set output value */
2782 if (outputval) {
2783 rtw_write8(padapter, REG_GPIO_PIN_CTRL_2 + 1,
2784 rtw_read8(padapter, REG_GPIO_PIN_CTRL_2 + 1) | BIT(index));
2785 } else {
2786 rtw_write8(padapter, REG_GPIO_PIN_CTRL_2 + 1,
2787 rtw_read8(padapter, REG_GPIO_PIN_CTRL_2 + 1) & ~BIT(index));
2788 }
2789 } else {
2790 RTW_INFO("%s: invalid GPIO%d=%d\n",
2791 __FUNCTION__, index, outputval);
2792 }
2793 }
2794 #endif
2795
rtw_hal_set_FwAoacRsvdPage_cmd(PADAPTER padapter,PRSVDPAGE_LOC rsvdpageloc)2796 void rtw_hal_set_FwAoacRsvdPage_cmd(PADAPTER padapter, PRSVDPAGE_LOC rsvdpageloc)
2797 {
2798 struct hal_ops *pHalFunc = &padapter->HalFunc;
2799 struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(padapter);
2800 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
2801 u8 res = 0, count = 0, ret = 0;
2802 #ifdef CONFIG_WOWLAN
2803 u8 u1H2CAoacRsvdPageParm[H2C_AOAC_RSVDPAGE_LOC_LEN] = {0};
2804
2805 RTW_INFO("AOACRsvdPageLoc: RWC=%d ArpRsp=%d NbrAdv=%d GtkRsp=%d GtkInfo=%d ProbeReq=%d NetworkList=%d\n",
2806 rsvdpageloc->LocRemoteCtrlInfo, rsvdpageloc->LocArpRsp,
2807 rsvdpageloc->LocNbrAdv, rsvdpageloc->LocGTKRsp,
2808 rsvdpageloc->LocGTKInfo, rsvdpageloc->LocProbeReq,
2809 rsvdpageloc->LocNetList);
2810
2811 if (check_fwstate(pmlmepriv, _FW_LINKED)) {
2812 SET_H2CCMD_AOAC_RSVDPAGE_LOC_REMOTE_WAKE_CTRL_INFO(u1H2CAoacRsvdPageParm, rsvdpageloc->LocRemoteCtrlInfo);
2813 SET_H2CCMD_AOAC_RSVDPAGE_LOC_ARP_RSP(u1H2CAoacRsvdPageParm, rsvdpageloc->LocArpRsp);
2814 /* SET_H2CCMD_AOAC_RSVDPAGE_LOC_NEIGHBOR_ADV(u1H2CAoacRsvdPageParm, rsvdpageloc->LocNbrAdv); */
2815 SET_H2CCMD_AOAC_RSVDPAGE_LOC_GTK_RSP(u1H2CAoacRsvdPageParm, rsvdpageloc->LocGTKRsp);
2816 SET_H2CCMD_AOAC_RSVDPAGE_LOC_GTK_INFO(u1H2CAoacRsvdPageParm, rsvdpageloc->LocGTKInfo);
2817 #ifdef CONFIG_GTK_OL
2818 SET_H2CCMD_AOAC_RSVDPAGE_LOC_GTK_EXT_MEM(u1H2CAoacRsvdPageParm, rsvdpageloc->LocGTKEXTMEM);
2819 #endif /* CONFIG_GTK_OL */
2820 ret = rtw_hal_fill_h2c_cmd(padapter,
2821 H2C_AOAC_RSVD_PAGE,
2822 H2C_AOAC_RSVDPAGE_LOC_LEN,
2823 u1H2CAoacRsvdPageParm);
2824 }
2825 #ifdef CONFIG_PNO_SUPPORT
2826 else {
2827
2828 if (!pwrpriv->pno_in_resume) {
2829 RTW_INFO("NLO_INFO=%d\n", rsvdpageloc->LocPNOInfo);
2830 _rtw_memset(&u1H2CAoacRsvdPageParm, 0,
2831 sizeof(u1H2CAoacRsvdPageParm));
2832 SET_H2CCMD_AOAC_RSVDPAGE_LOC_NLO_INFO(u1H2CAoacRsvdPageParm,
2833 rsvdpageloc->LocPNOInfo);
2834 ret = rtw_hal_fill_h2c_cmd(padapter,
2835 H2C_AOAC_RSVDPAGE3,
2836 H2C_AOAC_RSVDPAGE_LOC_LEN,
2837 u1H2CAoacRsvdPageParm);
2838 }
2839 }
2840 #endif /* CONFIG_PNO_SUPPORT */
2841 #endif /* CONFIG_WOWLAN */
2842 }
2843
2844 #if defined(CONFIG_WOWLAN) || defined(CONFIG_AP_WOWLAN)
rtw_hal_force_enable_rxdma(_adapter * adapter)2845 static void rtw_hal_force_enable_rxdma(_adapter *adapter)
2846 {
2847 RTW_INFO("%s: Set 0x690=0x00\n", __func__);
2848 rtw_write8(adapter, REG_WOW_CTRL,
2849 (rtw_read8(adapter, REG_WOW_CTRL) & 0xf0));
2850 RTW_PRINT("%s: Release RXDMA\n", __func__);
2851 rtw_write32(adapter, REG_RXPKT_NUM,
2852 (rtw_read32(adapter, REG_RXPKT_NUM) & (~RW_RELEASE_EN)));
2853 }
2854
rtw_hal_disable_tx_report(_adapter * adapter)2855 static void rtw_hal_disable_tx_report(_adapter *adapter)
2856 {
2857 rtw_write8(adapter, REG_TX_RPT_CTRL,
2858 ((rtw_read8(adapter, REG_TX_RPT_CTRL) & ~BIT(1))) & ~BIT(5));
2859 RTW_INFO("disable TXRPT:0x%02x\n", rtw_read8(adapter, REG_TX_RPT_CTRL));
2860 }
2861
rtw_hal_enable_tx_report(_adapter * adapter)2862 static void rtw_hal_enable_tx_report(_adapter *adapter)
2863 {
2864 rtw_write8(adapter, REG_TX_RPT_CTRL,
2865 ((rtw_read8(adapter, REG_TX_RPT_CTRL) | BIT(1))) | BIT(5));
2866 RTW_INFO("enable TX_RPT:0x%02x\n", rtw_read8(adapter, REG_TX_RPT_CTRL));
2867 }
2868
rtw_hal_release_rx_dma(_adapter * adapter)2869 static void rtw_hal_release_rx_dma(_adapter *adapter)
2870 {
2871 u32 val32 = 0;
2872
2873 val32 = rtw_read32(adapter, REG_RXPKT_NUM);
2874
2875 rtw_write32(adapter, REG_RXPKT_NUM, (val32 & (~RW_RELEASE_EN)));
2876
2877 RTW_INFO("%s, [0x%04x]: 0x%08x\n",
2878 __func__, REG_RXPKT_NUM, (val32 & (~RW_RELEASE_EN)));
2879 }
2880
rtw_hal_pause_rx_dma(_adapter * adapter)2881 static u8 rtw_hal_pause_rx_dma(_adapter *adapter)
2882 {
2883 u8 ret = 0;
2884 s8 trycnt = 100;
2885 u16 len = 0;
2886 u32 tmp = 0;
2887 int res = 0;
2888 /* RX DMA stop */
2889 RTW_PRINT("Pause DMA\n");
2890 rtw_write32(adapter, REG_RXPKT_NUM,
2891 (rtw_read32(adapter, REG_RXPKT_NUM) | RW_RELEASE_EN));
2892 do {
2893 if ((rtw_read32(adapter, REG_RXPKT_NUM) & RXDMA_IDLE)) {
2894 RTW_PRINT("RX_DMA_IDLE is true\n");
2895 ret = _SUCCESS;
2896 break;
2897 }
2898 #if defined(CONFIG_SDIO_HCI) || defined(CONFIG_GSPI_HCI)
2899 else {
2900 /* If RX_DMA is not idle, receive one pkt from DMA */
2901 res = sdio_local_read(adapter,
2902 SDIO_REG_RX0_REQ_LEN, 4, (u8 *)&tmp);
2903 len = le16_to_cpu(tmp);
2904 RTW_PRINT("RX len:%d\n", len);
2905
2906 if (len > 0)
2907 res = RecvOnePkt(adapter, len);
2908 else
2909 RTW_PRINT("read length fail %d\n", len);
2910
2911 RTW_PRINT("RecvOnePkt Result: %d\n", res);
2912 }
2913 #endif /* CONFIG_SDIO_HCI || CONFIG_GSPI_HCI */
2914 #ifdef CONFIG_USB_HCI
2915 else {
2916 rtw_intf_start(adapter);
2917
2918 tmp = rtw_read32(adapter, REG_RXPKT_NUM) & RXDMA_IDLE;
2919 if (tmp) {
2920 rtw_intf_stop(adapter);
2921 RTW_ENABLE_FUNC(adapter, DF_RX_BIT);
2922 RTW_ENABLE_FUNC(adapter, DF_TX_BIT);
2923 }
2924 }
2925 #endif
2926 } while (trycnt--);
2927
2928 if (trycnt < 0) {
2929 tmp = rtw_read16(adapter, REG_RXPKT_NUM + 3);
2930
2931 RTW_PRINT("Stop RX DMA failed......\n");
2932 RTW_PRINT("%s, RXPKT_NUM: 0x%04x\n",
2933 __func__, tmp);
2934 tmp = rtw_read16(adapter, REG_RXPKT_NUM + 2);
2935 if (tmp & BIT(3))
2936 RTW_PRINT("%s, RX DMA has req\n",
2937 __func__);
2938 else
2939 RTW_PRINT("%s, RX DMA no req\n",
2940 __func__);
2941 ret = _FAIL;
2942 }
2943
2944 return ret;
2945 }
2946
2947 #if defined(CONFIG_SDIO_HCI) || defined(CONFIG_GSPI_HCI)
rtw_hal_enable_cpwm2(_adapter * adapter)2948 static u8 rtw_hal_enable_cpwm2(_adapter *adapter)
2949 {
2950 u8 ret = 0;
2951 int res = 0;
2952 u32 tmp = 0;
2953
2954 RTW_PRINT("%s\n", __func__);
2955
2956 res = sdio_local_read(adapter, SDIO_REG_HIMR, 4, (u8 *)&tmp);
2957 if (!res)
2958 RTW_INFO("read SDIO_REG_HIMR: 0x%08x\n", tmp);
2959 else
2960 RTW_INFO("sdio_local_read fail\n");
2961
2962 tmp = SDIO_HIMR_CPWM2_MSK;
2963
2964 res = sdio_local_write(adapter, SDIO_REG_HIMR, 4, (u8 *)&tmp);
2965
2966 if (!res) {
2967 res = sdio_local_read(adapter, SDIO_REG_HIMR, 4, (u8 *)&tmp);
2968 RTW_INFO("read again SDIO_REG_HIMR: 0x%08x\n", tmp);
2969 ret = _SUCCESS;
2970 } else {
2971 RTW_INFO("sdio_local_write fail\n");
2972 ret = _FAIL;
2973 }
2974
2975 return ret;
2976 }
2977 #endif /* CONFIG_SDIO_HCI, CONFIG_GSPI_HCI */
2978 #endif /* CONFIG_WOWLAN || CONFIG_AP_WOWLAN */
2979
2980 #ifdef CONFIG_WOWLAN
2981 /*
2982 * rtw_hal_check_wow_ctrl
2983 * chk_type: _TRUE means to check enable, if 0x690 & bit1, WOW enable successful
2984 * _FALSE means to check disable, if 0x690 & bit1, WOW disable fail
2985 */
rtw_hal_check_wow_ctrl(_adapter * adapter,u8 chk_type)2986 static u8 rtw_hal_check_wow_ctrl(_adapter *adapter, u8 chk_type)
2987 {
2988 u8 mstatus = 0;
2989 u8 trycnt = 25;
2990 u8 res = _FALSE;
2991
2992 mstatus = rtw_read8(adapter, REG_WOW_CTRL);
2993 RTW_INFO("%s mstatus:0x%02x\n", __func__, mstatus);
2994
2995 if (chk_type) {
2996 while (!(mstatus & BIT1) && trycnt > 1) {
2997 mstatus = rtw_read8(adapter, REG_WOW_CTRL);
2998 RTW_PRINT("Loop index: %d :0x%02x\n",
2999 trycnt, mstatus);
3000 trycnt--;
3001 rtw_msleep_os(20);
3002 }
3003 if (mstatus & BIT1)
3004 res = _TRUE;
3005 else
3006 res = _FALSE;
3007 } else {
3008 while (mstatus & BIT1 && trycnt > 1) {
3009 mstatus = rtw_read8(adapter, REG_WOW_CTRL);
3010 RTW_PRINT("Loop index: %d :0x%02x\n",
3011 trycnt, mstatus);
3012 trycnt--;
3013 rtw_msleep_os(20);
3014 }
3015
3016 if (mstatus & BIT1)
3017 res = _FALSE;
3018 else
3019 res = _TRUE;
3020 }
3021 RTW_PRINT("%s check_type: %d res: %d trycnt: %d\n",
3022 __func__, chk_type, res, (25 - trycnt));
3023 return res;
3024 }
3025
3026 #ifdef CONFIG_PNO_SUPPORT
rtw_hal_check_pno_enabled(_adapter * adapter)3027 static u8 rtw_hal_check_pno_enabled(_adapter *adapter)
3028 {
3029 struct pwrctrl_priv *ppwrpriv = adapter_to_pwrctl(adapter);
3030 u8 res = 0, count = 0;
3031 u8 ret = _FALSE;
3032
3033 if (ppwrpriv->wowlan_pno_enable && ppwrpriv->pno_in_resume == _FALSE) {
3034 res = rtw_read8(adapter, REG_PNO_STATUS);
3035 while (!(res & BIT(7)) && count < 25) {
3036 RTW_INFO("[%d] cmd: 0x81 REG_PNO_STATUS: 0x%02x\n",
3037 count, res);
3038 res = rtw_read8(adapter, REG_PNO_STATUS);
3039 count++;
3040 rtw_msleep_os(2);
3041 }
3042 if (res & BIT(7))
3043 ret = _TRUE;
3044 else
3045 ret = _FALSE;
3046 RTW_INFO("cmd: 0x81 REG_PNO_STATUS: ret(%d)\n", ret);
3047 }
3048 return ret;
3049 }
3050 #endif
3051
rtw_hal_backup_rate(_adapter * adapter)3052 static void rtw_hal_backup_rate(_adapter *adapter)
3053 {
3054 RTW_INFO("%s\n", __func__);
3055 /* backup data rate to register 0x8b for wowlan FW */
3056 rtw_write8(adapter, 0x8d, 1);
3057 rtw_write8(adapter, 0x8c, 0);
3058 rtw_write8(adapter, 0x8f, 0x40);
3059 rtw_write8(adapter, 0x8b, rtw_read8(adapter, 0x2f0));
3060 }
3061
3062 #ifdef CONFIG_GTK_OL
rtw_hal_fw_sync_cam_id(_adapter * adapter)3063 static void rtw_hal_fw_sync_cam_id(_adapter *adapter)
3064 {
3065 struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
3066 int cam_id, index = 0;
3067 u8 *addr = NULL;
3068
3069 if (check_fwstate(pmlmepriv, WIFI_AP_STATE) == _TRUE)
3070 return;
3071
3072 addr = get_bssid(pmlmepriv);
3073
3074 if (addr == NULL) {
3075 RTW_INFO("%s: get bssid MAC addr fail!!\n", __func__);
3076 return;
3077 }
3078
3079 rtw_clean_dk_section(adapter);
3080
3081 do {
3082 cam_id = rtw_camid_search(adapter, addr, index, 1);
3083
3084 if (cam_id == -1)
3085 RTW_INFO("%s: cam_id: %d, key_id:%d\n", __func__, cam_id, index);
3086 else
3087 rtw_sec_cam_swap(adapter, cam_id, index);
3088
3089 index++;
3090 } while (index < 4);
3091
3092 rtw_write8(adapter, REG_SECCFG, 0xcc);
3093 }
3094
3095 #ifndef CONFIG_WOW_PATTERN_HW_CAM
rtw_hal_update_gtk_offload_info(_adapter * adapter)3096 static void rtw_hal_update_gtk_offload_info(_adapter *adapter)
3097 {
3098 struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
3099 struct security_priv *psecuritypriv = &adapter->securitypriv;
3100 struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
3101 struct cam_ctl_t *cam_ctl = &dvobj->cam_ctl;
3102 _irqL irqL;
3103 u8 get_key[16];
3104 u8 gtk_keyindex = 0;
3105
3106 if (check_fwstate(pmlmepriv, WIFI_AP_STATE) == _TRUE)
3107 return;
3108
3109 _rtw_memset(get_key, 0, sizeof(get_key));
3110
3111 if (psecuritypriv->binstallKCK_KEK == _TRUE) {
3112
3113 /*read gtk key index*/
3114 gtk_keyindex = rtw_read8(adapter, 0x48c);
3115
3116 if (gtk_keyindex > 4) {
3117 RTW_INFO("%s [ERROR] gtk_keyindex:%d invalid\n", __func__, gtk_keyindex);
3118 rtw_warn_on(1);
3119 return;
3120 }
3121 /*read key from sec-cam,for DK ,keyindex is equal to cam-id*/
3122 rtw_sec_read_cam_ent(adapter, gtk_keyindex, NULL, NULL, get_key);
3123
3124 /*update key into related sw variable and sec-cam cache*/
3125 psecuritypriv->dot118021XGrpKeyid = gtk_keyindex;
3126 _rtw_memcpy(psecuritypriv->dot118021XGrpKey[gtk_keyindex].skey, get_key, 16);
3127
3128 rtw_clean_hw_dk_cam(adapter);
3129 if (_rtw_camid_is_gk(adapter, gtk_keyindex)) {
3130 _enter_critical_bh(&cam_ctl->lock, &irqL);
3131 _rtw_memcpy(&dvobj->cam_cache[gtk_keyindex].key, get_key, 16);
3132 _exit_critical_bh(&cam_ctl->lock, &irqL);
3133 } else {
3134 struct setkey_parm aes_gtk;
3135
3136 aes_gtk.algorithm = _AES_;
3137 aes_gtk.keyid = gtk_keyindex;
3138 _rtw_memcpy(aes_gtk.key, get_key, 16);
3139 setkey_hdl(adapter, (u8 *)&aes_gtk);
3140 }
3141 rtw_clean_dk_section(adapter);
3142
3143 RTW_PRINT("GTK (%d) "KEY_FMT"\n",
3144 gtk_keyindex,
3145 KEY_ARG(psecuritypriv->dot118021XGrpKey[gtk_keyindex].skey));
3146
3147 rtw_write8(adapter, REG_SECCFG, 0x0c);
3148
3149 #ifdef CONFIG_GTK_OL_DBG
3150 /* if (gtk_keyindex != 5) */
3151 dump_sec_cam(RTW_DBGDUMP, adapter);
3152 dump_sec_cam_cache(RTW_DBGDUMP, adapter);
3153 #endif
3154 }
3155 }
3156 #else
rtw_hal_update_gtk_offload_info(_adapter * adapter)3157 static void rtw_hal_update_gtk_offload_info(_adapter *adapter)
3158 {
3159 struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
3160 struct security_priv *psecuritypriv = &adapter->securitypriv;
3161 struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
3162 struct pwrctrl_priv *pwrctl = adapter_to_pwrctl(adapter);
3163 struct aoac_report *aoac_rpt = &pwrctl->wowlan_aoac_rpt;
3164 struct cam_ctl_t *cam_ctl = &dvobj->cam_ctl;
3165 _irqL irqL;
3166 u8 gtk_keyindex = aoac_rpt->key_index;
3167
3168 if (check_fwstate(pmlmepriv, WIFI_AP_STATE) == _TRUE)
3169 return;
3170
3171 if (psecuritypriv->binstallKCK_KEK == _TRUE) {
3172
3173 if (gtk_keyindex > 4) {
3174 RTW_INFO("%s [ERROR] gtk_keyindex:%d invalid\n", __func__, gtk_keyindex);
3175 rtw_warn_on(1);
3176 return;
3177 }
3178
3179 /*update key into related sw variable and sec-cam cache*/
3180 psecuritypriv->dot118021XGrpKeyid = gtk_keyindex;
3181 _rtw_memcpy(psecuritypriv->dot118021XGrpKey[gtk_keyindex].skey, aoac_rpt->group_key, 16);
3182 rtw_clean_hw_dk_cam(adapter);
3183 if (_rtw_camid_is_gk(adapter, gtk_keyindex)) {
3184 _enter_critical_bh(&cam_ctl->lock, &irqL);
3185 _rtw_memcpy(&dvobj->cam_cache[gtk_keyindex].key, aoac_rpt->group_key, 16);
3186 _exit_critical_bh(&cam_ctl->lock, &irqL);
3187 } else {
3188 struct setkey_parm aes_gtk;
3189
3190 aes_gtk.algorithm = aoac_rpt->scurity_type;
3191 aes_gtk.keyid = gtk_keyindex;
3192 _rtw_memcpy(aes_gtk.key, aoac_rpt->group_key, 16);
3193 setkey_hdl(adapter, (u8 *)&aes_gtk);
3194 }
3195 rtw_clean_dk_section(adapter);
3196
3197 RTW_PRINT("GTK (%d) "KEY_FMT"\n",
3198 gtk_keyindex,
3199 KEY_ARG(psecuritypriv->dot118021XGrpKey[gtk_keyindex].skey));
3200
3201 rtw_write8(adapter, REG_SECCFG, 0x0c);
3202
3203 #ifdef CONFIG_GTK_OL_DBG
3204 /* if (gtk_keyindex != 5) */
3205 dump_sec_cam(RTW_DBGDUMP, adapter);
3206 dump_sec_cam_cache(RTW_DBGDUMP, adapter);
3207 #endif
3208 }
3209 }
3210
3211 #endif /*CONFIG_WOW_PATTERN_HW_CAM*/
3212
3213 #endif /*CONFIG_GTK_OL*/
3214
3215 #ifndef CONFIG_WOW_PATTERN_HW_CAM
rtw_hal_update_tx_iv(_adapter * adapter)3216 static void rtw_hal_update_tx_iv(_adapter *adapter)
3217 {
3218 struct pwrctrl_priv *pwrctl = adapter_to_pwrctl(adapter);
3219 u64 iv_low = 0, iv_high = 0;
3220
3221 /* 3.1 read fw iv */
3222 iv_low = rtw_read32(adapter, REG_TXPKTBUF_IV_LOW);
3223 /* only low two bytes is PN, check AES_IV macro for detail */
3224 iv_low &= 0xffff;
3225 iv_high = rtw_read32(adapter, REG_TXPKTBUF_IV_HIGH);
3226 /* get the real packet number */
3227 pwrctl->wowlan_fw_iv = iv_high << 16 | iv_low;
3228 RTW_PRINT("fw_iv: 0x%016llx\n", pwrctl->wowlan_fw_iv);
3229 /* Update TX iv data. */
3230 rtw_set_sec_pn(adapter);
3231 }
3232 #else
3233 #define DBG_AOAC_RPT
rtw_parse_aoac_rpt(_adapter * adapter,u8 * buffer,struct aoac_report * paoac_rpt)3234 void rtw_parse_aoac_rpt(_adapter *adapter, u8 *buffer, struct aoac_report *paoac_rpt)
3235 {
3236 if ((!buffer) && (!paoac_rpt))
3237 return;
3238
3239 _rtw_memcpy(paoac_rpt->iv, buffer, 8);
3240 _rtw_memcpy(paoac_rpt->replay_counter_eapol_key, buffer + 8, 8);
3241 _rtw_memcpy(paoac_rpt->group_key, buffer + 16, 32);
3242 paoac_rpt->key_index = *(buffer + 48);
3243 paoac_rpt->scurity_type = *(buffer + 49);
3244
3245 #ifdef DBG_AOAC_RPT
3246 RTW_INFO_DUMP("[AOAC-RPT] IV -", paoac_rpt->iv, 8);
3247 RTW_INFO_DUMP("[AOAC-RPT] Replay counter of EAPOL key - ", paoac_rpt->replay_counter_eapol_key, 8);
3248 RTW_INFO_DUMP("[AOAC-RPT] Group key - ", paoac_rpt->group_key, 32);
3249 RTW_INFO("[AOAC-RPT] Key Index - %d\n", paoac_rpt->key_index);
3250 RTW_INFO("[AOAC-RPT] Security Type - %d\n", paoac_rpt->scurity_type);
3251 #endif
3252 }
3253
rtw_hal_update_tx_iv(_adapter * adapter)3254 static void rtw_hal_update_tx_iv(_adapter *adapter)
3255 {
3256 struct pwrctrl_priv *pwrctl = adapter_to_pwrctl(adapter);
3257 struct aoac_report *aoac_rpt = &pwrctl->wowlan_aoac_rpt;
3258 u32 page_offset, page_number;
3259 u32 page_size = 0;
3260 u8 *buffer = NULL;
3261 u32 buf_size = 0;
3262 int ret = -1;
3263
3264 /* read fw iv from rsvd page */
3265 page_offset = pwrctl->wowlan_aoac_rpt_loc;
3266 page_number = 1;
3267
3268 rtw_hal_get_def_var(adapter, HAL_DEF_TX_PAGE_SIZE, &page_size);
3269 buf_size = page_size * page_number;
3270
3271 buffer = rtw_zvmalloc(buf_size);
3272
3273 if (NULL == buffer) {
3274 RTW_ERR("%s buffer allocate failed size(%d)\n", __func__, buf_size);
3275 return;
3276 }
3277
3278 RTW_INFO("Get AOAC Report from rsvd page_offset:%d\n", page_offset);
3279 ret = rtw_hal_get_rsvd_page(adapter, page_offset, page_number, buffer, buf_size);
3280 if (ret) {
3281 RTW_ERR("%s get aoac report failed\n", __func__);
3282 rtw_warn_on(1);
3283 goto _exit;
3284 }
3285
3286 _rtw_memset(aoac_rpt, 0, sizeof(struct aoac_report));
3287 rtw_parse_aoac_rpt(adapter, buffer, aoac_rpt);
3288
3289 _rtw_memcpy(&pwrctl->wowlan_fw_iv, aoac_rpt->iv, 8);
3290
3291 RTW_PRINT("fw_iv: 0x%016llx\n", pwrctl->wowlan_fw_iv);
3292 /* Update TX iv data. */
3293 rtw_set_sec_pn(adapter);
3294
3295 _exit:
3296 if (buffer)
3297 rtw_vmfree(buffer, buf_size);
3298 }
3299 #endif
3300
rtw_hal_set_keep_alive_cmd(_adapter * adapter,u8 enable,u8 pkt_type)3301 static u8 rtw_hal_set_keep_alive_cmd(_adapter *adapter, u8 enable, u8 pkt_type)
3302 {
3303 struct hal_ops *pHalFunc = &adapter->HalFunc;
3304
3305 u8 u1H2CKeepAliveParm[H2C_KEEP_ALIVE_CTRL_LEN] = {0};
3306 u8 adopt = 1, check_period = 5;
3307 u8 ret = _FAIL;
3308
3309 RTW_INFO("%s(): enable = %d\n", __func__, enable);
3310 SET_H2CCMD_KEEPALIVE_PARM_ENABLE(u1H2CKeepAliveParm, enable);
3311 SET_H2CCMD_KEEPALIVE_PARM_ADOPT(u1H2CKeepAliveParm, adopt);
3312 SET_H2CCMD_KEEPALIVE_PARM_PKT_TYPE(u1H2CKeepAliveParm, pkt_type);
3313 SET_H2CCMD_KEEPALIVE_PARM_CHECK_PERIOD(u1H2CKeepAliveParm, check_period);
3314
3315 ret = rtw_hal_fill_h2c_cmd(adapter,
3316 H2C_KEEP_ALIVE,
3317 H2C_KEEP_ALIVE_CTRL_LEN,
3318 u1H2CKeepAliveParm);
3319
3320 return ret;
3321 }
3322
rtw_hal_set_disconnect_decision_cmd(_adapter * adapter,u8 enable)3323 static u8 rtw_hal_set_disconnect_decision_cmd(_adapter *adapter, u8 enable)
3324 {
3325 struct hal_ops *pHalFunc = &adapter->HalFunc;
3326 u8 u1H2CDisconDecisionParm[H2C_DISCON_DECISION_LEN] = {0};
3327 u8 adopt = 1, check_period = 10, trypkt_num = 0;
3328 u8 ret = _FAIL;
3329
3330 RTW_INFO("%s(): enable = %d\n", __func__, enable);
3331 SET_H2CCMD_DISCONDECISION_PARM_ENABLE(u1H2CDisconDecisionParm, enable);
3332 SET_H2CCMD_DISCONDECISION_PARM_ADOPT(u1H2CDisconDecisionParm, adopt);
3333 SET_H2CCMD_DISCONDECISION_PARM_CHECK_PERIOD(u1H2CDisconDecisionParm, check_period);
3334 SET_H2CCMD_DISCONDECISION_PARM_TRY_PKT_NUM(u1H2CDisconDecisionParm, trypkt_num);
3335
3336 ret = rtw_hal_fill_h2c_cmd(adapter,
3337 H2C_DISCON_DECISION,
3338 H2C_DISCON_DECISION_LEN,
3339 u1H2CDisconDecisionParm);
3340 return ret;
3341 }
3342
rtw_hal_set_wowlan_ctrl_cmd(_adapter * adapter,u8 enable,u8 change_unit)3343 static u8 rtw_hal_set_wowlan_ctrl_cmd(_adapter *adapter, u8 enable, u8 change_unit)
3344 {
3345 struct security_priv *psecpriv = &adapter->securitypriv;
3346 struct pwrctrl_priv *ppwrpriv = adapter_to_pwrctl(adapter);
3347 struct hal_ops *pHalFunc = &adapter->HalFunc;
3348
3349 u8 u1H2CWoWlanCtrlParm[H2C_WOWLAN_LEN] = {0};
3350 u8 discont_wake = 1, gpionum = 0, gpio_dur = 0;
3351 u8 hw_unicast = 0, gpio_pulse_cnt = 0, gpio_pulse_en = 0;
3352 u8 sdio_wakeup_enable = 1;
3353 u8 gpio_high_active = 0;
3354 u8 magic_pkt = 0;
3355 u8 gpio_unit = 0; /*0: 64ns, 1: 8ms*/
3356 u8 ret = _FAIL;
3357
3358 #ifdef CONFIG_GPIO_WAKEUP
3359 gpio_high_active = ppwrpriv->is_high_active;
3360 gpionum = WAKEUP_GPIO_IDX;
3361 sdio_wakeup_enable = 0;
3362 #endif /* CONFIG_GPIO_WAKEUP */
3363
3364 if (!ppwrpriv->wowlan_pno_enable)
3365 magic_pkt = enable;
3366
3367 if (psecpriv->dot11PrivacyAlgrthm == _WEP40_ || psecpriv->dot11PrivacyAlgrthm == _WEP104_)
3368 hw_unicast = 1;
3369 else
3370 hw_unicast = 0;
3371
3372 RTW_INFO("%s(): enable=%d change_unit=%d\n", __func__,
3373 enable, change_unit);
3374
3375 /* time = (gpio_dur/2) * gpio_unit, default:256 ms */
3376 if (enable && change_unit) {
3377 gpio_dur = 0x40;
3378 gpio_unit = 1;
3379 gpio_pulse_en = 1;
3380 }
3381
3382 #ifdef CONFIG_PLATFORM_ARM_RK3188
3383 if (enable) {
3384 gpio_pulse_en = 1;
3385 gpio_pulse_cnt = 0x04;
3386 }
3387 #endif
3388
3389 SET_H2CCMD_WOWLAN_FUNC_ENABLE(u1H2CWoWlanCtrlParm, enable);
3390 SET_H2CCMD_WOWLAN_PATTERN_MATCH_ENABLE(u1H2CWoWlanCtrlParm, enable);
3391 SET_H2CCMD_WOWLAN_MAGIC_PKT_ENABLE(u1H2CWoWlanCtrlParm, magic_pkt);
3392 SET_H2CCMD_WOWLAN_UNICAST_PKT_ENABLE(u1H2CWoWlanCtrlParm, hw_unicast);
3393 SET_H2CCMD_WOWLAN_ALL_PKT_DROP(u1H2CWoWlanCtrlParm, 0);
3394 SET_H2CCMD_WOWLAN_GPIO_ACTIVE(u1H2CWoWlanCtrlParm, gpio_high_active);
3395
3396 #ifdef CONFIG_GTK_OL
3397 if (enable == _TRUE) {
3398 /* GTK rekey only for AES, if GTK rekey is TKIP, then wake up*/
3399 if (psecpriv->dot118021XGrpPrivacy == _AES_)
3400 SET_H2CCMD_WOWLAN_REKEY_WAKE_UP(u1H2CWoWlanCtrlParm, 0);
3401 else if (psecpriv->dot118021XGrpPrivacy == _TKIP_)
3402 SET_H2CCMD_WOWLAN_REKEY_WAKE_UP(u1H2CWoWlanCtrlParm, 1);
3403 }
3404 #else
3405 SET_H2CCMD_WOWLAN_REKEY_WAKE_UP(u1H2CWoWlanCtrlParm, enable);
3406 #endif
3407 SET_H2CCMD_WOWLAN_DISCONNECT_WAKE_UP(u1H2CWoWlanCtrlParm, discont_wake);
3408 SET_H2CCMD_WOWLAN_GPIONUM(u1H2CWoWlanCtrlParm, gpionum);
3409 SET_H2CCMD_WOWLAN_DATAPIN_WAKE_UP(u1H2CWoWlanCtrlParm, sdio_wakeup_enable);
3410
3411 SET_H2CCMD_WOWLAN_GPIO_DURATION(u1H2CWoWlanCtrlParm, gpio_dur);
3412 SET_H2CCMD_WOWLAN_CHANGE_UNIT(u1H2CWoWlanCtrlParm, gpio_unit);
3413
3414 SET_H2CCMD_WOWLAN_GPIO_PULSE_EN(u1H2CWoWlanCtrlParm, gpio_pulse_en);
3415 SET_H2CCMD_WOWLAN_GPIO_PULSE_COUNT(u1H2CWoWlanCtrlParm, gpio_pulse_cnt);
3416
3417 ret = rtw_hal_fill_h2c_cmd(adapter,
3418 H2C_WOWLAN,
3419 H2C_WOWLAN_LEN,
3420 u1H2CWoWlanCtrlParm);
3421 return ret;
3422 }
3423
rtw_hal_set_remote_wake_ctrl_cmd(_adapter * adapter,u8 enable)3424 static u8 rtw_hal_set_remote_wake_ctrl_cmd(_adapter *adapter, u8 enable)
3425 {
3426 struct hal_ops *pHalFunc = &adapter->HalFunc;
3427 struct security_priv *psecuritypriv = &(adapter->securitypriv);
3428 struct pwrctrl_priv *ppwrpriv = adapter_to_pwrctl(adapter);
3429 struct registry_priv *pregistrypriv = &adapter->registrypriv;
3430 u8 u1H2CRemoteWakeCtrlParm[H2C_REMOTE_WAKE_CTRL_LEN] = {0};
3431 u8 ret = _FAIL, count = 0;
3432
3433 RTW_INFO("%s(): enable=%d\n", __func__, enable);
3434
3435 if (!ppwrpriv->wowlan_pno_enable) {
3436 SET_H2CCMD_REMOTE_WAKECTRL_ENABLE(
3437 u1H2CRemoteWakeCtrlParm, enable);
3438 SET_H2CCMD_REMOTE_WAKE_CTRL_ARP_OFFLOAD_EN(
3439 u1H2CRemoteWakeCtrlParm, 1);
3440 #ifdef CONFIG_GTK_OL
3441 if (psecuritypriv->binstallKCK_KEK == _TRUE &&
3442 psecuritypriv->dot11PrivacyAlgrthm == _AES_ &&
3443 psecuritypriv->dot118021XGrpPrivacy == _AES_) {
3444 SET_H2CCMD_REMOTE_WAKE_CTRL_GTK_OFFLOAD_EN(
3445 u1H2CRemoteWakeCtrlParm, 1);
3446 } else {
3447 RTW_INFO("no kck or security is not AES\n");
3448 SET_H2CCMD_REMOTE_WAKE_CTRL_GTK_OFFLOAD_EN(
3449 u1H2CRemoteWakeCtrlParm, 0);
3450 }
3451 #endif /* CONFIG_GTK_OL */
3452
3453 if (pregistrypriv->default_patterns_en == _FALSE) {
3454 SET_H2CCMD_REMOTE_WAKE_CTRL_FW_UNICAST_EN(
3455 u1H2CRemoteWakeCtrlParm, enable);
3456 /*
3457 * filter NetBios name service pkt to avoid being waked-up
3458 * by this kind of unicast pkt this exceptional modification
3459 * is used for match competitor's behavior
3460 */
3461 SET_H2CCMD_REMOTE_WAKE_CTRL_NBNS_FILTER_EN(
3462 u1H2CRemoteWakeCtrlParm, enable);
3463 }
3464
3465 if ((psecuritypriv->dot11PrivacyAlgrthm == _AES_) ||
3466 (psecuritypriv->dot11PrivacyAlgrthm == _NO_PRIVACY_)) {
3467 SET_H2CCMD_REMOTE_WAKE_CTRL_ARP_ACTION(
3468 u1H2CRemoteWakeCtrlParm, 0);
3469 } else {
3470 SET_H2CCMD_REMOTE_WAKE_CTRL_ARP_ACTION(
3471 u1H2CRemoteWakeCtrlParm, 1);
3472 }
3473
3474 SET_H2CCMD_REMOTE_WAKE_CTRL_FW_PARSING_UNTIL_WAKEUP(
3475 u1H2CRemoteWakeCtrlParm, 1);
3476 }
3477 #ifdef CONFIG_PNO_SUPPORT
3478 else {
3479 SET_H2CCMD_REMOTE_WAKECTRL_ENABLE(
3480 u1H2CRemoteWakeCtrlParm, enable);
3481 SET_H2CCMD_REMOTE_WAKE_CTRL_NLO_OFFLOAD_EN(
3482 u1H2CRemoteWakeCtrlParm, enable);
3483 }
3484 #endif
3485
3486 #ifdef CONFIG_P2P_WOWLAN
3487 if (_TRUE == ppwrpriv->wowlan_p2p_mode) {
3488 RTW_INFO("P2P OFFLOAD ENABLE\n");
3489 SET_H2CCMD_REMOTE_WAKE_CTRL_P2P_OFFLAD_EN(u1H2CRemoteWakeCtrlParm, 1);
3490 } else {
3491 RTW_INFO("P2P OFFLOAD DISABLE\n");
3492 SET_H2CCMD_REMOTE_WAKE_CTRL_P2P_OFFLAD_EN(u1H2CRemoteWakeCtrlParm, 0);
3493 }
3494 #endif /* CONFIG_P2P_WOWLAN */
3495
3496
3497 ret = rtw_hal_fill_h2c_cmd(adapter,
3498 H2C_REMOTE_WAKE_CTRL,
3499 H2C_REMOTE_WAKE_CTRL_LEN,
3500 u1H2CRemoteWakeCtrlParm);
3501 return ret;
3502 }
3503
rtw_hal_set_global_info_cmd(_adapter * adapter,u8 group_alg,u8 pairwise_alg)3504 static u8 rtw_hal_set_global_info_cmd(_adapter *adapter, u8 group_alg, u8 pairwise_alg)
3505 {
3506 struct hal_ops *pHalFunc = &adapter->HalFunc;
3507 u8 ret = _FAIL;
3508 u8 u1H2CAOACGlobalInfoParm[H2C_AOAC_GLOBAL_INFO_LEN] = {0};
3509
3510 RTW_INFO("%s(): group_alg=%d pairwise_alg=%d\n",
3511 __func__, group_alg, pairwise_alg);
3512 SET_H2CCMD_AOAC_GLOBAL_INFO_PAIRWISE_ENC_ALG(u1H2CAOACGlobalInfoParm,
3513 pairwise_alg);
3514 SET_H2CCMD_AOAC_GLOBAL_INFO_GROUP_ENC_ALG(u1H2CAOACGlobalInfoParm,
3515 group_alg);
3516
3517 ret = rtw_hal_fill_h2c_cmd(adapter,
3518 H2C_AOAC_GLOBAL_INFO,
3519 H2C_AOAC_GLOBAL_INFO_LEN,
3520 u1H2CAOACGlobalInfoParm);
3521
3522 return ret;
3523 }
3524
3525 #ifdef CONFIG_PNO_SUPPORT
rtw_hal_set_scan_offload_info_cmd(_adapter * adapter,PRSVDPAGE_LOC rsvdpageloc,u8 enable)3526 static u8 rtw_hal_set_scan_offload_info_cmd(_adapter *adapter,
3527 PRSVDPAGE_LOC rsvdpageloc, u8 enable)
3528 {
3529 struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(adapter);
3530 struct hal_ops *pHalFunc = &adapter->HalFunc;
3531
3532 u8 u1H2CScanOffloadInfoParm[H2C_SCAN_OFFLOAD_CTRL_LEN] = {0};
3533 u8 res = 0, count = 0, ret = _FAIL;
3534
3535 RTW_INFO("%s: loc_probe_packet:%d, loc_scan_info: %d loc_ssid_info:%d\n",
3536 __func__, rsvdpageloc->LocProbePacket,
3537 rsvdpageloc->LocScanInfo, rsvdpageloc->LocSSIDInfo);
3538
3539 SET_H2CCMD_AOAC_NLO_FUN_EN(u1H2CScanOffloadInfoParm, enable);
3540 SET_H2CCMD_AOAC_NLO_IPS_EN(u1H2CScanOffloadInfoParm, enable);
3541 SET_H2CCMD_AOAC_RSVDPAGE_LOC_SCAN_INFO(u1H2CScanOffloadInfoParm,
3542 rsvdpageloc->LocScanInfo);
3543 SET_H2CCMD_AOAC_RSVDPAGE_LOC_PROBE_PACKET(u1H2CScanOffloadInfoParm,
3544 rsvdpageloc->LocProbePacket);
3545 /*
3546 SET_H2CCMD_AOAC_RSVDPAGE_LOC_SSID_INFO(u1H2CScanOffloadInfoParm,
3547 rsvdpageloc->LocSSIDInfo);
3548 */
3549 ret = rtw_hal_fill_h2c_cmd(adapter,
3550 H2C_D0_SCAN_OFFLOAD_INFO,
3551 H2C_SCAN_OFFLOAD_CTRL_LEN,
3552 u1H2CScanOffloadInfoParm);
3553 return ret;
3554 }
3555 #endif /* CONFIG_PNO_SUPPORT */
3556
rtw_hal_set_fw_wow_related_cmd(_adapter * padapter,u8 enable)3557 void rtw_hal_set_fw_wow_related_cmd(_adapter *padapter, u8 enable)
3558 {
3559 struct security_priv *psecpriv = &padapter->securitypriv;
3560 struct pwrctrl_priv *ppwrpriv = adapter_to_pwrctl(padapter);
3561 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
3562 struct sta_info *psta = NULL;
3563 u16 media_status_rpt;
3564 u8 pkt_type = 0;
3565 u8 ret = _SUCCESS;
3566
3567 RTW_PRINT("+%s()+: enable=%d\n", __func__, enable);
3568 _func_enter_;
3569
3570 rtw_hal_set_wowlan_ctrl_cmd(padapter, enable, _FALSE);
3571
3572 if (enable) {
3573 rtw_hal_set_global_info_cmd(padapter,
3574 psecpriv->dot118021XGrpPrivacy,
3575 psecpriv->dot11PrivacyAlgrthm);
3576
3577 if (!(ppwrpriv->wowlan_pno_enable)) {
3578 rtw_hal_set_disconnect_decision_cmd(padapter, enable);
3579 #ifdef CONFIG_ARP_KEEP_ALIVE
3580 if ((psecpriv->dot11PrivacyAlgrthm == _WEP40_) ||
3581 (psecpriv->dot11PrivacyAlgrthm == _WEP104_))
3582 pkt_type = 0;
3583 else
3584 pkt_type = 1;
3585 #else
3586 pkt_type = 0;
3587 #endif /* CONFIG_ARP_KEEP_ALIVE */
3588 rtw_hal_set_keep_alive_cmd(padapter, enable, pkt_type);
3589 }
3590 rtw_hal_set_remote_wake_ctrl_cmd(padapter, enable);
3591 #ifdef CONFIG_PNO_SUPPORT
3592 rtw_hal_check_pno_enabled(padapter);
3593 #endif /* CONFIG_PNO_SUPPORT */
3594 } else {
3595 #if 0
3596 {
3597 u32 PageSize = 0;
3598 rtw_hal_get_def_var(padapter, HAL_DEF_TX_PAGE_SIZE, (u8 *)&PageSize);
3599 dump_TX_FIFO(padapter, 4, PageSize);
3600 }
3601 #endif
3602
3603 rtw_hal_set_remote_wake_ctrl_cmd(padapter, enable);
3604 }
3605 _func_exit_;
3606 RTW_PRINT("-%s()-\n", __func__);
3607 }
3608 #endif /* CONFIG_WOWLAN */
3609
3610 #ifdef CONFIG_AP_WOWLAN
rtw_hal_set_ap_wowlan_ctrl_cmd(_adapter * adapter,u8 enable)3611 static u8 rtw_hal_set_ap_wowlan_ctrl_cmd(_adapter *adapter, u8 enable)
3612 {
3613 struct security_priv *psecpriv = &adapter->securitypriv;
3614 struct pwrctrl_priv *ppwrpriv = adapter_to_pwrctl(adapter);
3615 struct hal_ops *pHalFunc = &adapter->HalFunc;
3616
3617 u8 u1H2CAPWoWlanCtrlParm[H2C_AP_WOW_GPIO_CTRL_LEN] = {0};
3618 u8 gpionum = 0, gpio_dur = 0;
3619 u8 gpio_pulse = enable;
3620 u8 sdio_wakeup_enable = 1;
3621 u8 gpio_high_active = 0;
3622 u8 ret = _FAIL;
3623
3624 #ifdef CONFIG_GPIO_WAKEUP
3625 gpio_high_active = ppwrpriv->is_high_active;
3626 gpionum = WAKEUP_GPIO_IDX;
3627 sdio_wakeup_enable = 0;
3628 #endif /*CONFIG_GPIO_WAKEUP*/
3629
3630 RTW_INFO("%s(): enable=%d\n", __func__, enable);
3631
3632 SET_H2CCMD_AP_WOW_GPIO_CTRL_INDEX(u1H2CAPWoWlanCtrlParm,
3633 gpionum);
3634 SET_H2CCMD_AP_WOW_GPIO_CTRL_PLUS(u1H2CAPWoWlanCtrlParm,
3635 gpio_pulse);
3636 SET_H2CCMD_AP_WOW_GPIO_CTRL_HIGH_ACTIVE(u1H2CAPWoWlanCtrlParm,
3637 gpio_high_active);
3638 SET_H2CCMD_AP_WOW_GPIO_CTRL_EN(u1H2CAPWoWlanCtrlParm,
3639 enable);
3640 SET_H2CCMD_AP_WOW_GPIO_CTRL_DURATION(u1H2CAPWoWlanCtrlParm,
3641 gpio_dur);
3642
3643 ret = rtw_hal_fill_h2c_cmd(adapter,
3644 H2C_AP_WOW_GPIO_CTRL,
3645 H2C_AP_WOW_GPIO_CTRL_LEN,
3646 u1H2CAPWoWlanCtrlParm);
3647
3648 return ret;
3649 }
3650
rtw_hal_set_ap_offload_ctrl_cmd(_adapter * adapter,u8 enable)3651 static u8 rtw_hal_set_ap_offload_ctrl_cmd(_adapter *adapter, u8 enable)
3652 {
3653 struct hal_ops *pHalFunc = &adapter->HalFunc;
3654 u8 u1H2CAPOffloadCtrlParm[H2C_WOWLAN_LEN] = {0};
3655 u8 ret = _FAIL;
3656
3657 RTW_INFO("%s(): bFuncEn=%d\n", __func__, enable);
3658
3659 SET_H2CCMD_AP_WOWLAN_EN(u1H2CAPOffloadCtrlParm, enable);
3660
3661 ret = rtw_hal_fill_h2c_cmd(adapter,
3662 H2C_AP_OFFLOAD,
3663 H2C_AP_OFFLOAD_LEN,
3664 u1H2CAPOffloadCtrlParm);
3665
3666 return ret;
3667 }
3668
rtw_hal_set_ap_ps_cmd(_adapter * adapter,u8 enable)3669 static u8 rtw_hal_set_ap_ps_cmd(_adapter *adapter, u8 enable)
3670 {
3671 struct hal_ops *pHalFunc = &adapter->HalFunc;
3672 u8 ap_ps_parm[H2C_AP_PS_LEN] = {0};
3673 u8 ret = _FAIL;
3674
3675 RTW_INFO("%s(): enable=%d\n" , __func__ , enable);
3676
3677 SET_H2CCMD_AP_WOW_PS_EN(ap_ps_parm, enable);
3678 #ifndef CONFIG_USB_HCI
3679 SET_H2CCMD_AP_WOW_PS_32K_EN(ap_ps_parm, enable);
3680 #endif /*CONFIG_USB_HCI*/
3681 SET_H2CCMD_AP_WOW_PS_RF(ap_ps_parm, enable);
3682
3683 if (enable)
3684 SET_H2CCMD_AP_WOW_PS_DURATION(ap_ps_parm, 0x32);
3685 else
3686 SET_H2CCMD_AP_WOW_PS_DURATION(ap_ps_parm, 0x0);
3687
3688 ret = rtw_hal_fill_h2c_cmd(adapter, H2C_SAP_PS_,
3689 H2C_AP_PS_LEN, ap_ps_parm);
3690
3691 return ret;
3692 }
3693
rtw_hal_set_ap_rsvdpage_loc_cmd(PADAPTER padapter,PRSVDPAGE_LOC rsvdpageloc)3694 static void rtw_hal_set_ap_rsvdpage_loc_cmd(PADAPTER padapter,
3695 PRSVDPAGE_LOC rsvdpageloc)
3696 {
3697 struct hal_ops *pHalFunc = &padapter->HalFunc;
3698 u8 rsvdparm[H2C_AOAC_RSVDPAGE_LOC_LEN] = {0};
3699 u8 ret = _FAIL, header = 0;
3700
3701 if (pHalFunc->fill_h2c_cmd == NULL) {
3702 RTW_INFO("%s: Please hook fill_h2c_cmd first!\n", __func__);
3703 return;
3704 }
3705
3706 header = rtw_read8(padapter, REG_BCNQ_BDNY);
3707
3708 RTW_INFO("%s: beacon: %d, probeRsp: %d, header:0x%02x\n", __func__,
3709 rsvdpageloc->LocApOffloadBCN,
3710 rsvdpageloc->LocProbeRsp,
3711 header);
3712
3713 SET_H2CCMD_AP_WOWLAN_RSVDPAGE_LOC_BCN(rsvdparm,
3714 rsvdpageloc->LocApOffloadBCN + header);
3715
3716 ret = rtw_hal_fill_h2c_cmd(padapter, H2C_BCN_RSVDPAGE,
3717 H2C_BCN_RSVDPAGE_LEN, rsvdparm);
3718
3719 if (ret == _FAIL)
3720 RTW_INFO("%s: H2C_BCN_RSVDPAGE cmd fail\n", __func__);
3721
3722 rtw_msleep_os(10);
3723
3724 _rtw_memset(&rsvdparm, 0, sizeof(rsvdparm));
3725
3726 SET_H2CCMD_AP_WOWLAN_RSVDPAGE_LOC_ProbeRsp(rsvdparm,
3727 rsvdpageloc->LocProbeRsp + header);
3728
3729 ret = rtw_hal_fill_h2c_cmd(padapter, H2C_PROBERSP_RSVDPAGE,
3730 H2C_PROBERSP_RSVDPAGE_LEN, rsvdparm);
3731
3732 if (ret == _FAIL)
3733 RTW_INFO("%s: H2C_PROBERSP_RSVDPAGE cmd fail\n", __func__);
3734
3735 rtw_msleep_os(10);
3736 }
3737
rtw_hal_set_fw_ap_wow_related_cmd(_adapter * padapter,u8 enable)3738 static void rtw_hal_set_fw_ap_wow_related_cmd(_adapter *padapter, u8 enable)
3739 {
3740 rtw_hal_set_ap_offload_ctrl_cmd(padapter, enable);
3741 rtw_hal_set_ap_wowlan_ctrl_cmd(padapter, enable);
3742 rtw_hal_set_ap_ps_cmd(padapter, enable);
3743 }
3744
rtw_hal_ap_wow_enable(_adapter * padapter)3745 static void rtw_hal_ap_wow_enable(_adapter *padapter)
3746 {
3747 struct pwrctrl_priv *pwrctl = adapter_to_pwrctl(padapter);
3748 struct security_priv *psecuritypriv = &padapter->securitypriv;
3749 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
3750 struct hal_ops *pHalFunc = &padapter->HalFunc;
3751 struct sta_info *psta = NULL;
3752 #ifdef DBG_CHECK_FW_PS_STATE
3753 struct dvobj_priv *psdpriv = padapter->dvobj;
3754 struct debug_priv *pdbgpriv = &psdpriv->drv_dbg;
3755 #endif /*DBG_CHECK_FW_PS_STATE*/
3756 int res;
3757 u16 media_status_rpt;
3758
3759 RTW_INFO("%s, WOWLAN_AP_ENABLE\n", __func__);
3760 #ifdef DBG_CHECK_FW_PS_STATE
3761 if (rtw_fw_ps_state(padapter) == _FAIL) {
3762 pdbgpriv->dbg_enwow_dload_fw_fail_cnt++;
3763 RTW_PRINT("wowlan enable no leave 32k\n");
3764 }
3765 #endif /*DBG_CHECK_FW_PS_STATE*/
3766
3767 /* 1. Download WOWLAN FW*/
3768 rtw_hal_fw_dl(padapter, _TRUE);
3769
3770 media_status_rpt = RT_MEDIA_CONNECT;
3771 rtw_hal_set_hwreg(padapter, HW_VAR_H2C_FW_JOINBSSRPT,
3772 (u8 *)&media_status_rpt);
3773
3774 issue_beacon(padapter, 0);
3775
3776 rtw_msleep_os(2);
3777
3778 if (IS_HARDWARE_TYPE_8188E(padapter))
3779 rtw_hal_disable_tx_report(padapter);
3780
3781 /* RX DMA stop */
3782 res = rtw_hal_pause_rx_dma(padapter);
3783 if (res == _FAIL)
3784 RTW_PRINT("[WARNING] pause RX DMA fail\n");
3785
3786 #if defined(CONFIG_SDIO_HCI) || defined(CONFIG_GSPI_HCI)
3787 /* Enable CPWM2 only. */
3788 res = rtw_hal_enable_cpwm2(padapter);
3789 if (res == _FAIL)
3790 RTW_PRINT("[WARNING] enable cpwm2 fail\n");
3791 #endif
3792
3793 #ifdef CONFIG_GPIO_WAKEUP
3794 rtw_hal_switch_gpio_wl_ctrl(padapter, WAKEUP_GPIO_IDX, _TRUE);
3795 #endif
3796 /* 5. Set Enable WOWLAN H2C command. */
3797 RTW_PRINT("Set Enable AP WOWLan cmd\n");
3798 rtw_hal_set_fw_ap_wow_related_cmd(padapter, 1);
3799
3800 rtw_write8(padapter, REG_MCUTST_WOWLAN, 0);
3801 #ifdef CONFIG_USB_HCI
3802 rtw_mi_intf_stop(padapter);
3803 /* Invoid SE0 reset signal during suspending*/
3804 rtw_write8(padapter, REG_RSV_CTRL, 0x20);
3805 rtw_write8(padapter, REG_RSV_CTRL, 0x60);
3806 #endif /*CONFIG_USB_HCI*/
3807 }
3808
rtw_hal_ap_wow_disable(_adapter * padapter)3809 static void rtw_hal_ap_wow_disable(_adapter *padapter)
3810 {
3811 struct pwrctrl_priv *pwrctl = adapter_to_pwrctl(padapter);
3812 struct hal_ops *pHalFunc = &padapter->HalFunc;
3813 #ifdef DBG_CHECK_FW_PS_STATE
3814 struct dvobj_priv *psdpriv = padapter->dvobj;
3815 struct debug_priv *pdbgpriv = &psdpriv->drv_dbg;
3816 #endif /*DBG_CHECK_FW_PS_STATE*/
3817 u16 media_status_rpt;
3818 u8 val8;
3819
3820 RTW_INFO("%s, WOWLAN_AP_DISABLE\n", __func__);
3821 /* 1. Read wakeup reason*/
3822 pwrctl->wowlan_wake_reason = rtw_read8(padapter, REG_MCUTST_WOWLAN);
3823
3824 RTW_PRINT("wakeup_reason: 0x%02x\n",
3825 pwrctl->wowlan_wake_reason);
3826
3827 rtw_hal_set_fw_ap_wow_related_cmd(padapter, 0);
3828
3829 rtw_msleep_os(2);
3830 #ifdef DBG_CHECK_FW_PS_STATE
3831 if (rtw_fw_ps_state(padapter) == _FAIL) {
3832 pdbgpriv->dbg_diswow_dload_fw_fail_cnt++;
3833 RTW_PRINT("wowlan enable no leave 32k\n");
3834 }
3835 #endif /*DBG_CHECK_FW_PS_STATE*/
3836
3837 if (IS_HARDWARE_TYPE_8188E(padapter))
3838 rtw_hal_enable_tx_report(padapter);
3839
3840 rtw_hal_force_enable_rxdma(padapter);
3841
3842 rtw_hal_fw_dl(padapter, _FALSE);
3843
3844 #ifdef CONFIG_GPIO_WAKEUP
3845 val8 = (pwrctl->is_high_active == 0) ? 1 : 0;
3846 RTW_PRINT("Set Wake GPIO to default(%d).\n", val8);
3847 rtw_hal_set_output_gpio(padapter, WAKEUP_GPIO_IDX, val8);
3848 #endif
3849 media_status_rpt = RT_MEDIA_CONNECT;
3850
3851 rtw_hal_set_hwreg(padapter, HW_VAR_H2C_FW_JOINBSSRPT,
3852 (u8 *)&media_status_rpt);
3853
3854 issue_beacon(padapter, 0);
3855 }
3856 #endif /*CONFIG_AP_WOWLAN*/
3857
3858 #ifdef CONFIG_P2P_WOWLAN
update_hidden_ssid(u8 * ies,u32 ies_len,u8 hidden_ssid_mode)3859 static int update_hidden_ssid(u8 *ies, u32 ies_len, u8 hidden_ssid_mode)
3860 {
3861 u8 *ssid_ie;
3862 sint ssid_len_ori;
3863 int len_diff = 0;
3864
3865 ssid_ie = rtw_get_ie(ies, WLAN_EID_SSID, &ssid_len_ori, ies_len);
3866
3867 /* RTW_INFO("%s hidden_ssid_mode:%u, ssid_ie:%p, ssid_len_ori:%d\n", __FUNCTION__, hidden_ssid_mode, ssid_ie, ssid_len_ori); */
3868
3869 if (ssid_ie && ssid_len_ori > 0) {
3870 switch (hidden_ssid_mode) {
3871 case 1: {
3872 u8 *next_ie = ssid_ie + 2 + ssid_len_ori;
3873 u32 remain_len = 0;
3874
3875 remain_len = ies_len - (next_ie - ies);
3876
3877 ssid_ie[1] = 0;
3878 _rtw_memcpy(ssid_ie + 2, next_ie, remain_len);
3879 len_diff -= ssid_len_ori;
3880
3881 break;
3882 }
3883 case 2:
3884 _rtw_memset(&ssid_ie[2], 0, ssid_len_ori);
3885 break;
3886 default:
3887 break;
3888 }
3889 }
3890
3891 return len_diff;
3892 }
3893
rtw_hal_construct_P2PBeacon(_adapter * padapter,u8 * pframe,u32 * pLength)3894 static void rtw_hal_construct_P2PBeacon(_adapter *padapter, u8 *pframe, u32 *pLength)
3895 {
3896 /* struct xmit_frame *pmgntframe; */
3897 /* struct pkt_attrib *pattrib; */
3898 /* unsigned char *pframe; */
3899 struct rtw_ieee80211_hdr *pwlanhdr;
3900 unsigned short *fctrl;
3901 unsigned int rate_len;
3902 struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
3903 u32 pktlen;
3904 /* #if defined (CONFIG_AP_MODE) && defined (CONFIG_NATIVEAP_MLME) */
3905 /* _irqL irqL;
3906 * struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
3907 * #endif */ /* #if defined (CONFIG_AP_MODE) && defined (CONFIG_NATIVEAP_MLME) */
3908 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
3909 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
3910 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
3911 WLAN_BSSID_EX *cur_network = &(pmlmeinfo->network);
3912 u8 bc_addr[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
3913 #ifdef CONFIG_P2P
3914 struct wifidirect_info *pwdinfo = &(padapter->wdinfo);
3915 #endif /* CONFIG_P2P */
3916
3917 /* for debug */
3918 u8 *dbgbuf = pframe;
3919 u8 dbgbufLen = 0, index = 0;
3920
3921 RTW_INFO("%s\n", __FUNCTION__);
3922 /* #if defined (CONFIG_AP_MODE) && defined (CONFIG_NATIVEAP_MLME) */
3923 /* _enter_critical_bh(&pmlmepriv->bcn_update_lock, &irqL);
3924 * #endif */ /* #if defined (CONFIG_AP_MODE) && defined (CONFIG_NATIVEAP_MLME) */
3925
3926 pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
3927
3928
3929 fctrl = &(pwlanhdr->frame_ctl);
3930 *(fctrl) = 0;
3931
3932 _rtw_memcpy(pwlanhdr->addr1, bc_addr, ETH_ALEN);
3933 _rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN);
3934 _rtw_memcpy(pwlanhdr->addr3, get_my_bssid(cur_network), ETH_ALEN);
3935
3936 SetSeqNum(pwlanhdr, 0/*pmlmeext->mgnt_seq*/);
3937 /* pmlmeext->mgnt_seq++; */
3938 SetFrameSubType(pframe, WIFI_BEACON);
3939
3940 pframe += sizeof(struct rtw_ieee80211_hdr_3addr);
3941 pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
3942
3943 if ((pmlmeinfo->state & 0x03) == WIFI_FW_AP_STATE) {
3944 /* RTW_INFO("ie len=%d\n", cur_network->IELength); */
3945 #ifdef CONFIG_P2P
3946 /* for P2P : Primary Device Type & Device Name */
3947 u32 wpsielen = 0, insert_len = 0;
3948 u8 *wpsie = NULL;
3949 wpsie = rtw_get_wps_ie(cur_network->IEs + _FIXED_IE_LENGTH_, cur_network->IELength - _FIXED_IE_LENGTH_, NULL, &wpsielen);
3950
3951 if (rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO) && wpsie && wpsielen > 0) {
3952 uint wps_offset, remainder_ielen;
3953 u8 *premainder_ie, *pframe_wscie;
3954
3955 wps_offset = (uint)(wpsie - cur_network->IEs);
3956
3957 premainder_ie = wpsie + wpsielen;
3958
3959 remainder_ielen = cur_network->IELength - wps_offset - wpsielen;
3960
3961 #ifdef CONFIG_IOCTL_CFG80211
3962 if (pwdinfo->driver_interface == DRIVER_CFG80211) {
3963 if (pmlmepriv->wps_beacon_ie && pmlmepriv->wps_beacon_ie_len > 0) {
3964 _rtw_memcpy(pframe, cur_network->IEs, wps_offset);
3965 pframe += wps_offset;
3966 pktlen += wps_offset;
3967
3968 _rtw_memcpy(pframe, pmlmepriv->wps_beacon_ie, pmlmepriv->wps_beacon_ie_len);
3969 pframe += pmlmepriv->wps_beacon_ie_len;
3970 pktlen += pmlmepriv->wps_beacon_ie_len;
3971
3972 /* copy remainder_ie to pframe */
3973 _rtw_memcpy(pframe, premainder_ie, remainder_ielen);
3974 pframe += remainder_ielen;
3975 pktlen += remainder_ielen;
3976 } else {
3977 _rtw_memcpy(pframe, cur_network->IEs, cur_network->IELength);
3978 pframe += cur_network->IELength;
3979 pktlen += cur_network->IELength;
3980 }
3981 } else
3982 #endif /* CONFIG_IOCTL_CFG80211 */
3983 {
3984 pframe_wscie = pframe + wps_offset;
3985 _rtw_memcpy(pframe, cur_network->IEs, wps_offset + wpsielen);
3986 pframe += (wps_offset + wpsielen);
3987 pktlen += (wps_offset + wpsielen);
3988
3989 /* now pframe is end of wsc ie, insert Primary Device Type & Device Name */
3990 /* Primary Device Type */
3991 /* Type: */
3992 *(u16 *)(pframe + insert_len) = cpu_to_be16(WPS_ATTR_PRIMARY_DEV_TYPE);
3993 insert_len += 2;
3994
3995 /* Length: */
3996 *(u16 *)(pframe + insert_len) = cpu_to_be16(0x0008);
3997 insert_len += 2;
3998
3999 /* Value: */
4000 /* Category ID */
4001 *(u16 *)(pframe + insert_len) = cpu_to_be16(WPS_PDT_CID_MULIT_MEDIA);
4002 insert_len += 2;
4003
4004 /* OUI */
4005 *(u32 *)(pframe + insert_len) = cpu_to_be32(WPSOUI);
4006 insert_len += 4;
4007
4008 /* Sub Category ID */
4009 *(u16 *)(pframe + insert_len) = cpu_to_be16(WPS_PDT_SCID_MEDIA_SERVER);
4010 insert_len += 2;
4011
4012
4013 /* Device Name */
4014 /* Type: */
4015 *(u16 *)(pframe + insert_len) = cpu_to_be16(WPS_ATTR_DEVICE_NAME);
4016 insert_len += 2;
4017
4018 /* Length: */
4019 *(u16 *)(pframe + insert_len) = cpu_to_be16(pwdinfo->device_name_len);
4020 insert_len += 2;
4021
4022 /* Value: */
4023 _rtw_memcpy(pframe + insert_len, pwdinfo->device_name, pwdinfo->device_name_len);
4024 insert_len += pwdinfo->device_name_len;
4025
4026
4027 /* update wsc ie length */
4028 *(pframe_wscie + 1) = (wpsielen - 2) + insert_len;
4029
4030 /* pframe move to end */
4031 pframe += insert_len;
4032 pktlen += insert_len;
4033
4034 /* copy remainder_ie to pframe */
4035 _rtw_memcpy(pframe, premainder_ie, remainder_ielen);
4036 pframe += remainder_ielen;
4037 pktlen += remainder_ielen;
4038 }
4039 } else
4040 #endif /* CONFIG_P2P */
4041 {
4042 int len_diff;
4043 _rtw_memcpy(pframe, cur_network->IEs, cur_network->IELength);
4044 len_diff = update_hidden_ssid(
4045 pframe + _BEACON_IE_OFFSET_
4046 , cur_network->IELength - _BEACON_IE_OFFSET_
4047 , pmlmeinfo->hidden_ssid_mode
4048 );
4049 pframe += (cur_network->IELength + len_diff);
4050 pktlen += (cur_network->IELength + len_diff);
4051 }
4052 #if 0
4053 {
4054 u8 *wps_ie;
4055 uint wps_ielen;
4056 u8 sr = 0;
4057 wps_ie = rtw_get_wps_ie(pmgntframe->buf_addr + TXDESC_OFFSET + sizeof(struct rtw_ieee80211_hdr_3addr) + _BEACON_IE_OFFSET_,
4058 pattrib->pktlen - sizeof(struct rtw_ieee80211_hdr_3addr) - _BEACON_IE_OFFSET_, NULL, &wps_ielen);
4059 if (wps_ie && wps_ielen > 0)
4060 rtw_get_wps_attr_content(wps_ie, wps_ielen, WPS_ATTR_SELECTED_REGISTRAR, (u8 *)(&sr), NULL);
4061 if (sr != 0)
4062 set_fwstate(pmlmepriv, WIFI_UNDER_WPS);
4063 else
4064 _clr_fwstate_(pmlmepriv, WIFI_UNDER_WPS);
4065 }
4066 #endif
4067 #ifdef CONFIG_P2P
4068 if (rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO)) {
4069 u32 len;
4070 #ifdef CONFIG_IOCTL_CFG80211
4071 if (pwdinfo->driver_interface == DRIVER_CFG80211) {
4072 len = pmlmepriv->p2p_beacon_ie_len;
4073 if (pmlmepriv->p2p_beacon_ie && len > 0)
4074 _rtw_memcpy(pframe, pmlmepriv->p2p_beacon_ie, len);
4075 } else
4076 #endif /* CONFIG_IOCTL_CFG80211 */
4077 {
4078 len = build_beacon_p2p_ie(pwdinfo, pframe);
4079 }
4080
4081 pframe += len;
4082 pktlen += len;
4083
4084 #ifdef CONFIG_WFD
4085 len = rtw_append_beacon_wfd_ie(padapter, pframe);
4086 pframe += len;
4087 pktlen += len;
4088 #endif
4089
4090 }
4091 #endif /* CONFIG_P2P */
4092
4093 goto _issue_bcn;
4094
4095 }
4096
4097 /* below for ad-hoc mode */
4098
4099 /* timestamp will be inserted by hardware */
4100 pframe += 8;
4101 pktlen += 8;
4102
4103 /* beacon interval: 2 bytes */
4104
4105 _rtw_memcpy(pframe, (unsigned char *)(rtw_get_beacon_interval_from_ie(cur_network->IEs)), 2);
4106
4107 pframe += 2;
4108 pktlen += 2;
4109
4110 /* capability info: 2 bytes */
4111
4112 _rtw_memcpy(pframe, (unsigned char *)(rtw_get_capability_from_ie(cur_network->IEs)), 2);
4113
4114 pframe += 2;
4115 pktlen += 2;
4116
4117 /* SSID */
4118 pframe = rtw_set_ie(pframe, _SSID_IE_, cur_network->Ssid.SsidLength, cur_network->Ssid.Ssid, &pktlen);
4119
4120 /* supported rates... */
4121 rate_len = rtw_get_rateset_len(cur_network->SupportedRates);
4122 pframe = rtw_set_ie(pframe, _SUPPORTEDRATES_IE_, ((rate_len > 8) ? 8 : rate_len), cur_network->SupportedRates, &pktlen);
4123
4124 /* DS parameter set */
4125 pframe = rtw_set_ie(pframe, _DSSET_IE_, 1, (unsigned char *)&(cur_network->Configuration.DSConfig), &pktlen);
4126
4127 /* if( (pmlmeinfo->state&0x03) == WIFI_FW_ADHOC_STATE) */
4128 {
4129 u8 erpinfo = 0;
4130 u32 ATIMWindow;
4131 /* IBSS Parameter Set... */
4132 /* ATIMWindow = cur->Configuration.ATIMWindow; */
4133 ATIMWindow = 0;
4134 pframe = rtw_set_ie(pframe, _IBSS_PARA_IE_, 2, (unsigned char *)(&ATIMWindow), &pktlen);
4135
4136 /* ERP IE */
4137 pframe = rtw_set_ie(pframe, _ERPINFO_IE_, 1, &erpinfo, &pktlen);
4138 }
4139
4140
4141 /* EXTERNDED SUPPORTED RATE */
4142 if (rate_len > 8)
4143 pframe = rtw_set_ie(pframe, _EXT_SUPPORTEDRATES_IE_, (rate_len - 8), (cur_network->SupportedRates + 8), &pktlen);
4144
4145
4146 /* todo:HT for adhoc */
4147
4148 _issue_bcn:
4149
4150 /* #if defined (CONFIG_AP_MODE) && defined (CONFIG_NATIVEAP_MLME) */
4151 /* pmlmepriv->update_bcn = _FALSE;
4152 *
4153 * _exit_critical_bh(&pmlmepriv->bcn_update_lock, &irqL);
4154 * #endif */ /* #if defined (CONFIG_AP_MODE) && defined (CONFIG_NATIVEAP_MLME) */
4155
4156 *pLength = pktlen;
4157 #if 0
4158 /* printf dbg msg */
4159 dbgbufLen = pktlen;
4160 RTW_INFO("======> DBG MSG FOR CONSTRAUCT P2P BEACON\n");
4161
4162 for (index = 0; index < dbgbufLen; index++)
4163 printk("%x ", *(dbgbuf + index));
4164
4165 printk("\n");
4166 RTW_INFO("<====== DBG MSG FOR CONSTRAUCT P2P BEACON\n");
4167
4168 #endif
4169 }
4170
get_reg_classes_full_count(struct p2p_channels channel_list)4171 static int get_reg_classes_full_count(struct p2p_channels channel_list)
4172 {
4173 int cnt = 0;
4174 int i;
4175
4176 for (i = 0; i < channel_list.reg_classes; i++)
4177 cnt += channel_list.reg_class[i].channels;
4178
4179 return cnt;
4180 }
4181
rtw_hal_construct_P2PProbeRsp(_adapter * padapter,u8 * pframe,u32 * pLength)4182 static void rtw_hal_construct_P2PProbeRsp(_adapter *padapter, u8 *pframe, u32 *pLength)
4183 {
4184 /* struct xmit_frame *pmgntframe; */
4185 /* struct pkt_attrib *pattrib; */
4186 /* unsigned char *pframe; */
4187 struct rtw_ieee80211_hdr *pwlanhdr;
4188 unsigned short *fctrl;
4189 unsigned char *mac;
4190 struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
4191 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
4192 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
4193 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
4194 /* WLAN_BSSID_EX *cur_network = &(pmlmeinfo->network); */
4195 u16 beacon_interval = 100;
4196 u16 capInfo = 0;
4197 struct wifidirect_info *pwdinfo = &(padapter->wdinfo);
4198 u8 wpsie[255] = { 0x00 };
4199 u32 wpsielen = 0, p2pielen = 0;
4200 u32 pktlen;
4201 #ifdef CONFIG_WFD
4202 u32 wfdielen = 0;
4203 #endif
4204 #ifdef CONFIG_INTEL_WIDI
4205 u8 zero_array_check[L2SDTA_SERVICE_VE_LEN] = { 0x00 };
4206 #endif /* CONFIG_INTEL_WIDI */
4207
4208 /* for debug */
4209 u8 *dbgbuf = pframe;
4210 u8 dbgbufLen = 0, index = 0;
4211
4212 RTW_INFO("%s\n", __FUNCTION__);
4213 pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
4214
4215 mac = adapter_mac_addr(padapter);
4216
4217 fctrl = &(pwlanhdr->frame_ctl);
4218 *(fctrl) = 0;
4219
4220 /* DA filled by FW */
4221 _rtw_memset(pwlanhdr->addr1, 0, ETH_ALEN);
4222 _rtw_memcpy(pwlanhdr->addr2, mac, ETH_ALEN);
4223
4224 /* Use the device address for BSSID field. */
4225 _rtw_memcpy(pwlanhdr->addr3, mac, ETH_ALEN);
4226
4227 SetSeqNum(pwlanhdr, 0);
4228 SetFrameSubType(fctrl, WIFI_PROBERSP);
4229
4230 pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
4231 pframe += pktlen;
4232
4233
4234 /* timestamp will be inserted by hardware */
4235 pframe += 8;
4236 pktlen += 8;
4237
4238 /* beacon interval: 2 bytes */
4239 _rtw_memcpy(pframe, (unsigned char *) &beacon_interval, 2);
4240 pframe += 2;
4241 pktlen += 2;
4242
4243 /* capability info: 2 bytes */
4244 /* ESS and IBSS bits must be 0 (defined in the 3.1.2.1.1 of WiFi Direct Spec) */
4245 capInfo |= cap_ShortPremble;
4246 capInfo |= cap_ShortSlot;
4247
4248 _rtw_memcpy(pframe, (unsigned char *) &capInfo, 2);
4249 pframe += 2;
4250 pktlen += 2;
4251
4252
4253 /* SSID */
4254 pframe = rtw_set_ie(pframe, _SSID_IE_, 7, pwdinfo->p2p_wildcard_ssid, &pktlen);
4255
4256 /* supported rates... */
4257 /* Use the OFDM rate in the P2P probe response frame. ( 6(B), 9(B), 12, 18, 24, 36, 48, 54 ) */
4258 pframe = rtw_set_ie(pframe, _SUPPORTEDRATES_IE_, 8, pwdinfo->support_rate, &pktlen);
4259
4260 /* DS parameter set */
4261 pframe = rtw_set_ie(pframe, _DSSET_IE_, 1, (unsigned char *)&pwdinfo->listen_channel, &pktlen);
4262
4263 #ifdef CONFIG_IOCTL_CFG80211
4264 if (pwdinfo->driver_interface == DRIVER_CFG80211) {
4265 if (pmlmepriv->wps_probe_resp_ie != NULL && pmlmepriv->p2p_probe_resp_ie != NULL) {
4266 /* WPS IE */
4267 _rtw_memcpy(pframe, pmlmepriv->wps_probe_resp_ie, pmlmepriv->wps_probe_resp_ie_len);
4268 pktlen += pmlmepriv->wps_probe_resp_ie_len;
4269 pframe += pmlmepriv->wps_probe_resp_ie_len;
4270
4271 /* P2P IE */
4272 _rtw_memcpy(pframe, pmlmepriv->p2p_probe_resp_ie, pmlmepriv->p2p_probe_resp_ie_len);
4273 pktlen += pmlmepriv->p2p_probe_resp_ie_len;
4274 pframe += pmlmepriv->p2p_probe_resp_ie_len;
4275 }
4276 } else
4277 #endif /* CONFIG_IOCTL_CFG80211 */
4278 {
4279
4280 /* Todo: WPS IE */
4281 /* Noted by Albert 20100907 */
4282 /* According to the WPS specification, all the WPS attribute is presented by Big Endian. */
4283
4284 wpsielen = 0;
4285 /* WPS OUI */
4286 *(u32 *)(wpsie) = cpu_to_be32(WPSOUI);
4287 wpsielen += 4;
4288
4289 /* WPS version */
4290 /* Type: */
4291 *(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_VER1);
4292 wpsielen += 2;
4293
4294 /* Length: */
4295 *(u16 *)(wpsie + wpsielen) = cpu_to_be16(0x0001);
4296 wpsielen += 2;
4297
4298 /* Value: */
4299 wpsie[wpsielen++] = WPS_VERSION_1; /* Version 1.0 */
4300
4301 #ifdef CONFIG_INTEL_WIDI
4302 /* Commented by Kurt */
4303 /* Appended WiDi info. only if we did issued_probereq_widi(), and then we saved ven. ext. in pmlmepriv->sa_ext. */
4304 if (_rtw_memcmp(pmlmepriv->sa_ext, zero_array_check, L2SDTA_SERVICE_VE_LEN) == _FALSE
4305 || pmlmepriv->num_p2p_sdt != 0) {
4306 /* Sec dev type */
4307 *(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_SEC_DEV_TYPE_LIST);
4308 wpsielen += 2;
4309
4310 /* Length: */
4311 *(u16 *)(wpsie + wpsielen) = cpu_to_be16(0x0008);
4312 wpsielen += 2;
4313
4314 /* Value: */
4315 /* Category ID */
4316 *(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_PDT_CID_DISPLAYS);
4317 wpsielen += 2;
4318
4319 /* OUI */
4320 *(u32 *)(wpsie + wpsielen) = cpu_to_be32(INTEL_DEV_TYPE_OUI);
4321 wpsielen += 4;
4322
4323 *(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_PDT_SCID_WIDI_CONSUMER_SINK);
4324 wpsielen += 2;
4325
4326 if (_rtw_memcmp(pmlmepriv->sa_ext, zero_array_check, L2SDTA_SERVICE_VE_LEN) == _FALSE) {
4327 /* Vendor Extension */
4328 _rtw_memcpy(wpsie + wpsielen, pmlmepriv->sa_ext, L2SDTA_SERVICE_VE_LEN);
4329 wpsielen += L2SDTA_SERVICE_VE_LEN;
4330 }
4331 }
4332 #endif /* CONFIG_INTEL_WIDI */
4333
4334 /* WiFi Simple Config State */
4335 /* Type: */
4336 *(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_SIMPLE_CONF_STATE);
4337 wpsielen += 2;
4338
4339 /* Length: */
4340 *(u16 *)(wpsie + wpsielen) = cpu_to_be16(0x0001);
4341 wpsielen += 2;
4342
4343 /* Value: */
4344 wpsie[wpsielen++] = WPS_WSC_STATE_NOT_CONFIG; /* Not Configured. */
4345
4346 /* Response Type */
4347 /* Type: */
4348 *(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_RESP_TYPE);
4349 wpsielen += 2;
4350
4351 /* Length: */
4352 *(u16 *)(wpsie + wpsielen) = cpu_to_be16(0x0001);
4353 wpsielen += 2;
4354
4355 /* Value: */
4356 wpsie[wpsielen++] = WPS_RESPONSE_TYPE_8021X;
4357
4358 /* UUID-E */
4359 /* Type: */
4360 *(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_UUID_E);
4361 wpsielen += 2;
4362
4363 /* Length: */
4364 *(u16 *)(wpsie + wpsielen) = cpu_to_be16(0x0010);
4365 wpsielen += 2;
4366
4367 /* Value: */
4368 if (pwdinfo->external_uuid == 0) {
4369 _rtw_memset(wpsie + wpsielen, 0x0, 16);
4370 _rtw_memcpy(wpsie + wpsielen, mac, ETH_ALEN);
4371 } else
4372 _rtw_memcpy(wpsie + wpsielen, pwdinfo->uuid, 0x10);
4373 wpsielen += 0x10;
4374
4375 /* Manufacturer */
4376 /* Type: */
4377 *(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_MANUFACTURER);
4378 wpsielen += 2;
4379
4380 /* Length: */
4381 *(u16 *)(wpsie + wpsielen) = cpu_to_be16(0x0007);
4382 wpsielen += 2;
4383
4384 /* Value: */
4385 _rtw_memcpy(wpsie + wpsielen, "Realtek", 7);
4386 wpsielen += 7;
4387
4388 /* Model Name */
4389 /* Type: */
4390 *(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_MODEL_NAME);
4391 wpsielen += 2;
4392
4393 /* Length: */
4394 *(u16 *)(wpsie + wpsielen) = cpu_to_be16(0x0006);
4395 wpsielen += 2;
4396
4397 /* Value: */
4398 _rtw_memcpy(wpsie + wpsielen, "8192CU", 6);
4399 wpsielen += 6;
4400
4401 /* Model Number */
4402 /* Type: */
4403 *(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_MODEL_NUMBER);
4404 wpsielen += 2;
4405
4406 /* Length: */
4407 *(u16 *)(wpsie + wpsielen) = cpu_to_be16(0x0001);
4408 wpsielen += 2;
4409
4410 /* Value: */
4411 wpsie[wpsielen++] = 0x31; /* character 1 */
4412
4413 /* Serial Number */
4414 /* Type: */
4415 *(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_SERIAL_NUMBER);
4416 wpsielen += 2;
4417
4418 /* Length: */
4419 *(u16 *)(wpsie + wpsielen) = cpu_to_be16(ETH_ALEN);
4420 wpsielen += 2;
4421
4422 /* Value: */
4423 _rtw_memcpy(wpsie + wpsielen, "123456" , ETH_ALEN);
4424 wpsielen += ETH_ALEN;
4425
4426 /* Primary Device Type */
4427 /* Type: */
4428 *(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_PRIMARY_DEV_TYPE);
4429 wpsielen += 2;
4430
4431 /* Length: */
4432 *(u16 *)(wpsie + wpsielen) = cpu_to_be16(0x0008);
4433 wpsielen += 2;
4434
4435 /* Value: */
4436 /* Category ID */
4437 *(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_PDT_CID_MULIT_MEDIA);
4438 wpsielen += 2;
4439
4440 /* OUI */
4441 *(u32 *)(wpsie + wpsielen) = cpu_to_be32(WPSOUI);
4442 wpsielen += 4;
4443
4444 /* Sub Category ID */
4445 *(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_PDT_SCID_MEDIA_SERVER);
4446 wpsielen += 2;
4447
4448 /* Device Name */
4449 /* Type: */
4450 *(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_DEVICE_NAME);
4451 wpsielen += 2;
4452
4453 /* Length: */
4454 *(u16 *)(wpsie + wpsielen) = cpu_to_be16(pwdinfo->device_name_len);
4455 wpsielen += 2;
4456
4457 /* Value: */
4458 _rtw_memcpy(wpsie + wpsielen, pwdinfo->device_name, pwdinfo->device_name_len);
4459 wpsielen += pwdinfo->device_name_len;
4460
4461 /* Config Method */
4462 /* Type: */
4463 *(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_CONF_METHOD);
4464 wpsielen += 2;
4465
4466 /* Length: */
4467 *(u16 *)(wpsie + wpsielen) = cpu_to_be16(0x0002);
4468 wpsielen += 2;
4469
4470 /* Value: */
4471 *(u16 *)(wpsie + wpsielen) = cpu_to_be16(pwdinfo->supported_wps_cm);
4472 wpsielen += 2;
4473
4474
4475 pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, wpsielen, (unsigned char *) wpsie, &pktlen);
4476
4477
4478 p2pielen = build_probe_resp_p2p_ie(pwdinfo, pframe);
4479 pframe += p2pielen;
4480 pktlen += p2pielen;
4481 }
4482
4483 #ifdef CONFIG_WFD
4484 wfdielen = rtw_append_probe_resp_wfd_ie(padapter, pframe);
4485 pframe += wfdielen;
4486 pktlen += wfdielen;
4487 #endif
4488
4489 *pLength = pktlen;
4490
4491 #if 0
4492 /* printf dbg msg */
4493 dbgbufLen = pktlen;
4494 RTW_INFO("======> DBG MSG FOR CONSTRAUCT P2P Probe Rsp\n");
4495
4496 for (index = 0; index < dbgbufLen; index++)
4497 printk("%x ", *(dbgbuf + index));
4498
4499 printk("\n");
4500 RTW_INFO("<====== DBG MSG FOR CONSTRAUCT P2P Probe Rsp\n");
4501 #endif
4502 }
rtw_hal_construct_P2PNegoRsp(_adapter * padapter,u8 * pframe,u32 * pLength)4503 static void rtw_hal_construct_P2PNegoRsp(_adapter *padapter, u8 *pframe, u32 *pLength)
4504 {
4505 unsigned char category = RTW_WLAN_CATEGORY_PUBLIC;
4506 u8 action = P2P_PUB_ACTION_ACTION;
4507 u32 p2poui = cpu_to_be32(P2POUI);
4508 u8 oui_subtype = P2P_GO_NEGO_RESP;
4509 u8 wpsie[255] = { 0x00 }, p2pie[255] = { 0x00 };
4510 u8 p2pielen = 0, i;
4511 uint wpsielen = 0;
4512 u16 wps_devicepassword_id = 0x0000;
4513 uint wps_devicepassword_id_len = 0;
4514 u8 channel_cnt_24g = 0, channel_cnt_5gl = 0, channel_cnt_5gh;
4515 u16 len_channellist_attr = 0;
4516 u32 pktlen;
4517 u8 dialogToken = 0;
4518
4519 /* struct xmit_frame *pmgntframe; */
4520 /* struct pkt_attrib *pattrib; */
4521 /* unsigned char *pframe; */
4522 struct rtw_ieee80211_hdr *pwlanhdr;
4523 unsigned short *fctrl;
4524 struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
4525 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
4526 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
4527 struct wifidirect_info *pwdinfo = &(padapter->wdinfo);
4528 /* WLAN_BSSID_EX *cur_network = &(pmlmeinfo->network); */
4529
4530 #ifdef CONFIG_WFD
4531 u32 wfdielen = 0;
4532 #endif
4533
4534 /* for debug */
4535 u8 *dbgbuf = pframe;
4536 u8 dbgbufLen = 0, index = 0;
4537
4538 RTW_INFO("%s\n", __FUNCTION__);
4539 pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
4540
4541 fctrl = &(pwlanhdr->frame_ctl);
4542 *(fctrl) = 0;
4543
4544 /* RA, filled by FW */
4545 _rtw_memset(pwlanhdr->addr1, 0, ETH_ALEN);
4546 _rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN);
4547 _rtw_memcpy(pwlanhdr->addr3, adapter_mac_addr(padapter), ETH_ALEN);
4548
4549 SetSeqNum(pwlanhdr, 0);
4550 SetFrameSubType(pframe, WIFI_ACTION);
4551
4552 pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
4553 pframe += pktlen;
4554
4555 pframe = rtw_set_fixed_ie(pframe, 1, &(category), &(pktlen));
4556 pframe = rtw_set_fixed_ie(pframe, 1, &(action), &(pktlen));
4557 pframe = rtw_set_fixed_ie(pframe, 4, (unsigned char *) &(p2poui), &(pktlen));
4558 pframe = rtw_set_fixed_ie(pframe, 1, &(oui_subtype), &(pktlen));
4559
4560 /* dialog token, filled by FW */
4561 pframe = rtw_set_fixed_ie(pframe, 1, &(dialogToken), &(pktlen));
4562
4563 _rtw_memset(wpsie, 0x00, 255);
4564 wpsielen = 0;
4565
4566 /* WPS Section */
4567 wpsielen = 0;
4568 /* WPS OUI */
4569 *(u32 *)(wpsie) = cpu_to_be32(WPSOUI);
4570 wpsielen += 4;
4571
4572 /* WPS version */
4573 /* Type: */
4574 *(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_VER1);
4575 wpsielen += 2;
4576
4577 /* Length: */
4578 *(u16 *)(wpsie + wpsielen) = cpu_to_be16(0x0001);
4579 wpsielen += 2;
4580
4581 /* Value: */
4582 wpsie[wpsielen++] = WPS_VERSION_1; /* Version 1.0 */
4583
4584 /* Device Password ID */
4585 /* Type: */
4586 *(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_DEVICE_PWID);
4587 wpsielen += 2;
4588
4589 /* Length: */
4590 *(u16 *)(wpsie + wpsielen) = cpu_to_be16(0x0002);
4591 wpsielen += 2;
4592
4593 /* Value: */
4594 if (wps_devicepassword_id == WPS_DPID_USER_SPEC)
4595 *(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_DPID_REGISTRAR_SPEC);
4596 else if (wps_devicepassword_id == WPS_DPID_REGISTRAR_SPEC)
4597 *(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_DPID_USER_SPEC);
4598 else
4599 *(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_DPID_PBC);
4600 wpsielen += 2;
4601
4602 pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, wpsielen, (unsigned char *) wpsie, &pktlen);
4603
4604
4605 /* P2P IE Section. */
4606
4607 /* P2P OUI */
4608 p2pielen = 0;
4609 p2pie[p2pielen++] = 0x50;
4610 p2pie[p2pielen++] = 0x6F;
4611 p2pie[p2pielen++] = 0x9A;
4612 p2pie[p2pielen++] = 0x09; /* WFA P2P v1.0 */
4613
4614 /* Commented by Albert 20100908 */
4615 /* According to the P2P Specification, the group negoitation response frame should contain 9 P2P attributes */
4616 /* 1. Status */
4617 /* 2. P2P Capability */
4618 /* 3. Group Owner Intent */
4619 /* 4. Configuration Timeout */
4620 /* 5. Operating Channel */
4621 /* 6. Intended P2P Interface Address */
4622 /* 7. Channel List */
4623 /* 8. Device Info */
4624 /* 9. Group ID ( Only GO ) */
4625
4626
4627 /* ToDo: */
4628
4629 /* P2P Status */
4630 /* Type: */
4631 p2pie[p2pielen++] = P2P_ATTR_STATUS;
4632
4633 /* Length: */
4634 *(u16 *)(p2pie + p2pielen) = cpu_to_le16(0x0001);
4635 p2pielen += 2;
4636
4637 /* Value, filled by FW */
4638 p2pie[p2pielen++] = 1;
4639
4640 /* P2P Capability */
4641 /* Type: */
4642 p2pie[p2pielen++] = P2P_ATTR_CAPABILITY;
4643
4644 /* Length: */
4645 *(u16 *)(p2pie + p2pielen) = cpu_to_le16(0x0002);
4646 p2pielen += 2;
4647
4648 /* Value: */
4649 /* Device Capability Bitmap, 1 byte */
4650
4651 if (rtw_p2p_chk_role(pwdinfo, P2P_ROLE_CLIENT)) {
4652 /* Commented by Albert 2011/03/08 */
4653 /* According to the P2P specification */
4654 /* if the sending device will be client, the P2P Capability should be reserved of group negotation response frame */
4655 p2pie[p2pielen++] = 0;
4656 } else {
4657 /* Be group owner or meet the error case */
4658 p2pie[p2pielen++] = DMP_P2P_DEVCAP_SUPPORT;
4659 }
4660
4661 /* Group Capability Bitmap, 1 byte */
4662 if (pwdinfo->persistent_supported)
4663 p2pie[p2pielen++] = P2P_GRPCAP_CROSS_CONN | P2P_GRPCAP_PERSISTENT_GROUP;
4664 else
4665 p2pie[p2pielen++] = P2P_GRPCAP_CROSS_CONN;
4666
4667 /* Group Owner Intent */
4668 /* Type: */
4669 p2pie[p2pielen++] = P2P_ATTR_GO_INTENT;
4670
4671 /* Length: */
4672 *(u16 *)(p2pie + p2pielen) = cpu_to_le16(0x0001);
4673 p2pielen += 2;
4674
4675 /* Value: */
4676 if (pwdinfo->peer_intent & 0x01) {
4677 /* Peer's tie breaker bit is 1, our tie breaker bit should be 0 */
4678 p2pie[p2pielen++] = (pwdinfo->intent << 1);
4679 } else {
4680 /* Peer's tie breaker bit is 0, our tie breaker bit should be 1 */
4681 p2pie[p2pielen++] = ((pwdinfo->intent << 1) | BIT(0));
4682 }
4683
4684
4685 /* Configuration Timeout */
4686 /* Type: */
4687 p2pie[p2pielen++] = P2P_ATTR_CONF_TIMEOUT;
4688
4689 /* Length: */
4690 *(u16 *)(p2pie + p2pielen) = cpu_to_le16(0x0002);
4691 p2pielen += 2;
4692
4693 /* Value: */
4694 p2pie[p2pielen++] = 200; /* 2 seconds needed to be the P2P GO */
4695 p2pie[p2pielen++] = 200; /* 2 seconds needed to be the P2P Client */
4696
4697 /* Operating Channel */
4698 /* Type: */
4699 p2pie[p2pielen++] = P2P_ATTR_OPERATING_CH;
4700
4701 /* Length: */
4702 *(u16 *)(p2pie + p2pielen) = cpu_to_le16(0x0005);
4703 p2pielen += 2;
4704
4705 /* Value: */
4706 /* Country String */
4707 p2pie[p2pielen++] = 'X';
4708 p2pie[p2pielen++] = 'X';
4709
4710 /* The third byte should be set to 0x04. */
4711 /* Described in the "Operating Channel Attribute" section. */
4712 p2pie[p2pielen++] = 0x04;
4713
4714 /* Operating Class */
4715 if (pwdinfo->operating_channel <= 14) {
4716 /* Operating Class */
4717 p2pie[p2pielen++] = 0x51;
4718 } else if ((pwdinfo->operating_channel >= 36) && (pwdinfo->operating_channel <= 48)) {
4719 /* Operating Class */
4720 p2pie[p2pielen++] = 0x73;
4721 } else {
4722 /* Operating Class */
4723 p2pie[p2pielen++] = 0x7c;
4724 }
4725
4726 /* Channel Number */
4727 p2pie[p2pielen++] = pwdinfo->operating_channel; /* operating channel number */
4728
4729 /* Intended P2P Interface Address */
4730 /* Type: */
4731 p2pie[p2pielen++] = P2P_ATTR_INTENTED_IF_ADDR;
4732
4733 /* Length: */
4734 *(u16 *)(p2pie + p2pielen) = cpu_to_le16(ETH_ALEN);
4735 p2pielen += 2;
4736
4737 /* Value: */
4738 _rtw_memcpy(p2pie + p2pielen, adapter_mac_addr(padapter), ETH_ALEN);
4739 p2pielen += ETH_ALEN;
4740
4741 /* Channel List */
4742 /* Type: */
4743 p2pie[p2pielen++] = P2P_ATTR_CH_LIST;
4744
4745 /* Country String(3) */
4746 /* + ( Operating Class (1) + Number of Channels(1) ) * Operation Classes (?) */
4747 /* + number of channels in all classes */
4748 len_channellist_attr = 3
4749 + (1 + 1) * (u16)pmlmeext->channel_list.reg_classes
4750 + get_reg_classes_full_count(pmlmeext->channel_list);
4751
4752 #ifdef CONFIG_CONCURRENT_MODE
4753 if (rtw_mi_buddy_check_fwstate(padapter, _FW_LINKED))
4754 *(u16 *)(p2pie + p2pielen) = cpu_to_le16(5 + 1);
4755 else
4756 *(u16 *)(p2pie + p2pielen) = cpu_to_le16(len_channellist_attr);
4757
4758 #else
4759
4760 *(u16 *)(p2pie + p2pielen) = cpu_to_le16(len_channellist_attr);
4761
4762 #endif
4763 p2pielen += 2;
4764
4765 /* Value: */
4766 /* Country String */
4767 p2pie[p2pielen++] = 'X';
4768 p2pie[p2pielen++] = 'X';
4769
4770 /* The third byte should be set to 0x04. */
4771 /* Described in the "Operating Channel Attribute" section. */
4772 p2pie[p2pielen++] = 0x04;
4773
4774 /* Channel Entry List */
4775
4776 #ifdef CONFIG_CONCURRENT_MODE
4777 if (rtw_mi_check_status(padapter, MI_LINKED)) {
4778 u8 union_ch = rtw_mi_get_union_chan(padapter);
4779
4780 /* Operating Class */
4781 if (union_ch > 14) {
4782 if (union_ch >= 149)
4783 p2pie[p2pielen++] = 0x7c;
4784 else
4785 p2pie[p2pielen++] = 0x73;
4786 } else
4787 p2pie[p2pielen++] = 0x51;
4788
4789
4790 /* Number of Channels */
4791 /* Just support 1 channel and this channel is AP's channel */
4792 p2pie[p2pielen++] = 1;
4793
4794 /* Channel List */
4795 p2pie[p2pielen++] = union_ch;
4796 } else {
4797 int i, j;
4798 for (j = 0; j < pmlmeext->channel_list.reg_classes; j++) {
4799 /* Operating Class */
4800 p2pie[p2pielen++] = pmlmeext->channel_list.reg_class[j].reg_class;
4801
4802 /* Number of Channels */
4803 p2pie[p2pielen++] = pmlmeext->channel_list.reg_class[j].channels;
4804
4805 /* Channel List */
4806 for (i = 0; i < pmlmeext->channel_list.reg_class[j].channels; i++)
4807 p2pie[p2pielen++] = pmlmeext->channel_list.reg_class[j].channel[i];
4808 }
4809 }
4810 #else /* CONFIG_CONCURRENT_MODE */
4811 {
4812 int i, j;
4813 for (j = 0; j < pmlmeext->channel_list.reg_classes; j++) {
4814 /* Operating Class */
4815 p2pie[p2pielen++] = pmlmeext->channel_list.reg_class[j].reg_class;
4816
4817 /* Number of Channels */
4818 p2pie[p2pielen++] = pmlmeext->channel_list.reg_class[j].channels;
4819
4820 /* Channel List */
4821 for (i = 0; i < pmlmeext->channel_list.reg_class[j].channels; i++)
4822 p2pie[p2pielen++] = pmlmeext->channel_list.reg_class[j].channel[i];
4823 }
4824 }
4825 #endif /* CONFIG_CONCURRENT_MODE */
4826
4827
4828 /* Device Info */
4829 /* Type: */
4830 p2pie[p2pielen++] = P2P_ATTR_DEVICE_INFO;
4831
4832 /* Length: */
4833 /* 21->P2P Device Address (6bytes) + Config Methods (2bytes) + Primary Device Type (8bytes) */
4834 /* + NumofSecondDevType (1byte) + WPS Device Name ID field (2bytes) + WPS Device Name Len field (2bytes) */
4835 *(u16 *)(p2pie + p2pielen) = cpu_to_le16(21 + pwdinfo->device_name_len);
4836 p2pielen += 2;
4837
4838 /* Value: */
4839 /* P2P Device Address */
4840 _rtw_memcpy(p2pie + p2pielen, adapter_mac_addr(padapter), ETH_ALEN);
4841 p2pielen += ETH_ALEN;
4842
4843 /* Config Method */
4844 /* This field should be big endian. Noted by P2P specification. */
4845
4846 *(u16 *)(p2pie + p2pielen) = cpu_to_be16(pwdinfo->supported_wps_cm);
4847
4848 p2pielen += 2;
4849
4850 /* Primary Device Type */
4851 /* Category ID */
4852 *(u16 *)(p2pie + p2pielen) = cpu_to_be16(WPS_PDT_CID_MULIT_MEDIA);
4853 p2pielen += 2;
4854
4855 /* OUI */
4856 *(u32 *)(p2pie + p2pielen) = cpu_to_be32(WPSOUI);
4857 p2pielen += 4;
4858
4859 /* Sub Category ID */
4860 *(u16 *)(p2pie + p2pielen) = cpu_to_be16(WPS_PDT_SCID_MEDIA_SERVER);
4861 p2pielen += 2;
4862
4863 /* Number of Secondary Device Types */
4864 p2pie[p2pielen++] = 0x00; /* No Secondary Device Type List */
4865
4866 /* Device Name */
4867 /* Type: */
4868 *(u16 *)(p2pie + p2pielen) = cpu_to_be16(WPS_ATTR_DEVICE_NAME);
4869 p2pielen += 2;
4870
4871 /* Length: */
4872 *(u16 *)(p2pie + p2pielen) = cpu_to_be16(pwdinfo->device_name_len);
4873 p2pielen += 2;
4874
4875 /* Value: */
4876 _rtw_memcpy(p2pie + p2pielen, pwdinfo->device_name , pwdinfo->device_name_len);
4877 p2pielen += pwdinfo->device_name_len;
4878
4879 if (rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO)) {
4880 /* Group ID Attribute */
4881 /* Type: */
4882 p2pie[p2pielen++] = P2P_ATTR_GROUP_ID;
4883
4884 /* Length: */
4885 *(u16 *)(p2pie + p2pielen) = cpu_to_le16(ETH_ALEN + pwdinfo->nego_ssidlen);
4886 p2pielen += 2;
4887
4888 /* Value: */
4889 /* p2P Device Address */
4890 _rtw_memcpy(p2pie + p2pielen , pwdinfo->device_addr, ETH_ALEN);
4891 p2pielen += ETH_ALEN;
4892
4893 /* SSID */
4894 _rtw_memcpy(p2pie + p2pielen, pwdinfo->nego_ssid, pwdinfo->nego_ssidlen);
4895 p2pielen += pwdinfo->nego_ssidlen;
4896
4897 }
4898
4899 pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, p2pielen, (unsigned char *) p2pie, &pktlen);
4900
4901 #ifdef CONFIG_WFD
4902 wfdielen = build_nego_resp_wfd_ie(pwdinfo, pframe);
4903 pframe += wfdielen;
4904 pktlen += wfdielen;
4905 #endif
4906
4907 *pLength = pktlen;
4908 #if 0
4909 /* printf dbg msg */
4910 dbgbufLen = pktlen;
4911 RTW_INFO("======> DBG MSG FOR CONSTRAUCT Nego Rsp\n");
4912
4913 for (index = 0; index < dbgbufLen; index++)
4914 printk("%x ", *(dbgbuf + index));
4915
4916 printk("\n");
4917 RTW_INFO("<====== DBG MSG FOR CONSTRAUCT Nego Rsp\n");
4918 #endif
4919 }
4920
rtw_hal_construct_P2PInviteRsp(_adapter * padapter,u8 * pframe,u32 * pLength)4921 static void rtw_hal_construct_P2PInviteRsp(_adapter *padapter, u8 *pframe, u32 *pLength)
4922 {
4923 unsigned char category = RTW_WLAN_CATEGORY_PUBLIC;
4924 u8 action = P2P_PUB_ACTION_ACTION;
4925 u32 p2poui = cpu_to_be32(P2POUI);
4926 u8 oui_subtype = P2P_INVIT_RESP;
4927 u8 p2pie[255] = { 0x00 };
4928 u8 p2pielen = 0, i;
4929 u8 channel_cnt_24g = 0, channel_cnt_5gl = 0, channel_cnt_5gh = 0;
4930 u16 len_channellist_attr = 0;
4931 u32 pktlen;
4932 u8 dialogToken = 0;
4933 #ifdef CONFIG_WFD
4934 u32 wfdielen = 0;
4935 #endif
4936
4937 /* struct xmit_frame *pmgntframe; */
4938 /* struct pkt_attrib *pattrib; */
4939 /* unsigned char *pframe; */
4940 struct rtw_ieee80211_hdr *pwlanhdr;
4941 unsigned short *fctrl;
4942 struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
4943 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
4944 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
4945 struct wifidirect_info *pwdinfo = &(padapter->wdinfo);
4946
4947 /* for debug */
4948 u8 *dbgbuf = pframe;
4949 u8 dbgbufLen = 0, index = 0;
4950
4951
4952 RTW_INFO("%s\n", __FUNCTION__);
4953 pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
4954
4955 fctrl = &(pwlanhdr->frame_ctl);
4956 *(fctrl) = 0;
4957
4958 /* RA fill by FW */
4959 _rtw_memset(pwlanhdr->addr1, 0, ETH_ALEN);
4960 _rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN);
4961
4962 /* BSSID fill by FW */
4963 _rtw_memset(pwlanhdr->addr3, 0, ETH_ALEN);
4964
4965 SetSeqNum(pwlanhdr, 0);
4966 SetFrameSubType(pframe, WIFI_ACTION);
4967
4968 pframe += sizeof(struct rtw_ieee80211_hdr_3addr);
4969 pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
4970
4971 pframe = rtw_set_fixed_ie(pframe, 1, &(category), &(pktlen));
4972 pframe = rtw_set_fixed_ie(pframe, 1, &(action), &(pktlen));
4973 pframe = rtw_set_fixed_ie(pframe, 4, (unsigned char *) &(p2poui), &(pktlen));
4974 pframe = rtw_set_fixed_ie(pframe, 1, &(oui_subtype), &(pktlen));
4975
4976 /* dialog token, filled by FW */
4977 pframe = rtw_set_fixed_ie(pframe, 1, &(dialogToken), &(pktlen));
4978
4979 /* P2P IE Section. */
4980
4981 /* P2P OUI */
4982 p2pielen = 0;
4983 p2pie[p2pielen++] = 0x50;
4984 p2pie[p2pielen++] = 0x6F;
4985 p2pie[p2pielen++] = 0x9A;
4986 p2pie[p2pielen++] = 0x09; /* WFA P2P v1.0 */
4987
4988 /* Commented by Albert 20101005 */
4989 /* According to the P2P Specification, the P2P Invitation response frame should contain 5 P2P attributes */
4990 /* 1. Status */
4991 /* 2. Configuration Timeout */
4992 /* 3. Operating Channel ( Only GO ) */
4993 /* 4. P2P Group BSSID ( Only GO ) */
4994 /* 5. Channel List */
4995
4996 /* P2P Status */
4997 /* Type: */
4998 p2pie[p2pielen++] = P2P_ATTR_STATUS;
4999
5000 /* Length: */
5001 *(u16 *)(p2pie + p2pielen) = cpu_to_le16(0x0001);
5002 p2pielen += 2;
5003
5004 /* Value: filled by FW, defult value is FAIL INFO UNAVAILABLE */
5005 p2pie[p2pielen++] = P2P_STATUS_FAIL_INFO_UNAVAILABLE;
5006
5007 /* Configuration Timeout */
5008 /* Type: */
5009 p2pie[p2pielen++] = P2P_ATTR_CONF_TIMEOUT;
5010
5011 /* Length: */
5012 *(u16 *)(p2pie + p2pielen) = cpu_to_le16(0x0002);
5013 p2pielen += 2;
5014
5015 /* Value: */
5016 p2pie[p2pielen++] = 200; /* 2 seconds needed to be the P2P GO */
5017 p2pie[p2pielen++] = 200; /* 2 seconds needed to be the P2P Client */
5018
5019 /* due to defult value is FAIL INFO UNAVAILABLE, so the following IE is not needed */
5020 #if 0
5021 if (status_code == P2P_STATUS_SUCCESS) {
5022 if (rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO)) {
5023 /* The P2P Invitation request frame asks this Wi-Fi device to be the P2P GO */
5024 /* In this case, the P2P Invitation response frame should carry the two more P2P attributes. */
5025 /* First one is operating channel attribute. */
5026 /* Second one is P2P Group BSSID attribute. */
5027
5028 /* Operating Channel */
5029 /* Type: */
5030 p2pie[p2pielen++] = P2P_ATTR_OPERATING_CH;
5031
5032 /* Length: */
5033 *(u16 *)(p2pie + p2pielen) = cpu_to_le16(0x0005);
5034 p2pielen += 2;
5035
5036 /* Value: */
5037 /* Country String */
5038 p2pie[p2pielen++] = 'X';
5039 p2pie[p2pielen++] = 'X';
5040
5041 /* The third byte should be set to 0x04. */
5042 /* Described in the "Operating Channel Attribute" section. */
5043 p2pie[p2pielen++] = 0x04;
5044
5045 /* Operating Class */
5046 p2pie[p2pielen++] = 0x51; /* Copy from SD7 */
5047
5048 /* Channel Number */
5049 p2pie[p2pielen++] = pwdinfo->operating_channel; /* operating channel number */
5050
5051
5052 /* P2P Group BSSID */
5053 /* Type: */
5054 p2pie[p2pielen++] = P2P_ATTR_GROUP_BSSID;
5055
5056 /* Length: */
5057 *(u16 *)(p2pie + p2pielen) = cpu_to_le16(ETH_ALEN);
5058 p2pielen += 2;
5059
5060 /* Value: */
5061 /* P2P Device Address for GO */
5062 _rtw_memcpy(p2pie + p2pielen, adapter_mac_addr(padapter), ETH_ALEN);
5063 p2pielen += ETH_ALEN;
5064
5065 }
5066
5067 /* Channel List */
5068 /* Type: */
5069 p2pie[p2pielen++] = P2P_ATTR_CH_LIST;
5070
5071 /* Length: */
5072 /* Country String(3) */
5073 /* + ( Operating Class (1) + Number of Channels(1) ) * Operation Classes (?) */
5074 /* + number of channels in all classes */
5075 len_channellist_attr = 3
5076 + (1 + 1) * (u16)pmlmeext->channel_list.reg_classes
5077 + get_reg_classes_full_count(pmlmeext->channel_list);
5078
5079 #ifdef CONFIG_CONCURRENT_MODE
5080 if (rtw_mi_check_status(padapter, MI_LINKED))
5081 *(u16 *)(p2pie + p2pielen) = cpu_to_le16(5 + 1);
5082 else
5083 *(u16 *)(p2pie + p2pielen) = cpu_to_le16(len_channellist_attr);
5084
5085 #else
5086
5087 *(u16 *)(p2pie + p2pielen) = cpu_to_le16(len_channellist_attr);
5088
5089 #endif
5090 p2pielen += 2;
5091
5092 /* Value: */
5093 /* Country String */
5094 p2pie[p2pielen++] = 'X';
5095 p2pie[p2pielen++] = 'X';
5096
5097 /* The third byte should be set to 0x04. */
5098 /* Described in the "Operating Channel Attribute" section. */
5099 p2pie[p2pielen++] = 0x04;
5100
5101 /* Channel Entry List */
5102 #ifdef CONFIG_CONCURRENT_MODE
5103 if (rtw_mi_check_status(padapter, MI_LINKED)) {
5104 u8 union_ch = rtw_mi_get_union_chan(padapter);
5105
5106 /* Operating Class */
5107 if (union_ch > 14) {
5108 if (union_ch >= 149)
5109 p2pie[p2pielen++] = 0x7c;
5110 else
5111 p2pie[p2pielen++] = 0x73;
5112
5113 } else
5114 p2pie[p2pielen++] = 0x51;
5115
5116
5117 /* Number of Channels */
5118 /* Just support 1 channel and this channel is AP's channel */
5119 p2pie[p2pielen++] = 1;
5120
5121 /* Channel List */
5122 p2pie[p2pielen++] = union_ch;
5123 } else {
5124 int i, j;
5125 for (j = 0; j < pmlmeext->channel_list.reg_classes; j++) {
5126 /* Operating Class */
5127 p2pie[p2pielen++] = pmlmeext->channel_list.reg_class[j].reg_class;
5128
5129 /* Number of Channels */
5130 p2pie[p2pielen++] = pmlmeext->channel_list.reg_class[j].channels;
5131
5132 /* Channel List */
5133 for (i = 0; i < pmlmeext->channel_list.reg_class[j].channels; i++)
5134 p2pie[p2pielen++] = pmlmeext->channel_list.reg_class[j].channel[i];
5135 }
5136 }
5137 #else /* CONFIG_CONCURRENT_MODE */
5138 {
5139 int i, j;
5140 for (j = 0; j < pmlmeext->channel_list.reg_classes; j++) {
5141 /* Operating Class */
5142 p2pie[p2pielen++] = pmlmeext->channel_list.reg_class[j].reg_class;
5143
5144 /* Number of Channels */
5145 p2pie[p2pielen++] = pmlmeext->channel_list.reg_class[j].channels;
5146
5147 /* Channel List */
5148 for (i = 0; i < pmlmeext->channel_list.reg_class[j].channels; i++)
5149 p2pie[p2pielen++] = pmlmeext->channel_list.reg_class[j].channel[i];
5150 }
5151 }
5152 #endif /* CONFIG_CONCURRENT_MODE */
5153 }
5154 #endif
5155
5156 pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, p2pielen, (unsigned char *) p2pie, &pktlen);
5157
5158 #ifdef CONFIG_WFD
5159 wfdielen = build_invitation_resp_wfd_ie(pwdinfo, pframe);
5160 pframe += wfdielen;
5161 pktlen += wfdielen;
5162 #endif
5163
5164 *pLength = pktlen;
5165
5166 #if 0
5167 /* printf dbg msg */
5168 dbgbufLen = pktlen;
5169 RTW_INFO("======> DBG MSG FOR CONSTRAUCT Invite Rsp\n");
5170
5171 for (index = 0; index < dbgbufLen; index++)
5172 printk("%x ", *(dbgbuf + index));
5173
5174 printk("\n");
5175 RTW_INFO("<====== DBG MSG FOR CONSTRAUCT Invite Rsp\n");
5176 #endif
5177 }
5178
5179
rtw_hal_construct_P2PProvisionDisRsp(_adapter * padapter,u8 * pframe,u32 * pLength)5180 static void rtw_hal_construct_P2PProvisionDisRsp(_adapter *padapter, u8 *pframe, u32 *pLength)
5181 {
5182 unsigned char category = RTW_WLAN_CATEGORY_PUBLIC;
5183 u8 action = P2P_PUB_ACTION_ACTION;
5184 u8 dialogToken = 0;
5185 u32 p2poui = cpu_to_be32(P2POUI);
5186 u8 oui_subtype = P2P_PROVISION_DISC_RESP;
5187 u8 wpsie[100] = { 0x00 };
5188 u8 wpsielen = 0;
5189 u32 pktlen;
5190 #ifdef CONFIG_WFD
5191 u32 wfdielen = 0;
5192 #endif
5193
5194 /* struct xmit_frame *pmgntframe; */
5195 /* struct pkt_attrib *pattrib; */
5196 /* unsigned char *pframe; */
5197 struct rtw_ieee80211_hdr *pwlanhdr;
5198 unsigned short *fctrl;
5199 struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
5200 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
5201 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
5202 struct wifidirect_info *pwdinfo = &(padapter->wdinfo);
5203
5204 /* for debug */
5205 u8 *dbgbuf = pframe;
5206 u8 dbgbufLen = 0, index = 0;
5207
5208 RTW_INFO("%s\n", __FUNCTION__);
5209
5210 pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
5211
5212 fctrl = &(pwlanhdr->frame_ctl);
5213 *(fctrl) = 0;
5214
5215 /* RA filled by FW */
5216 _rtw_memset(pwlanhdr->addr1, 0, ETH_ALEN);
5217 _rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN);
5218 _rtw_memcpy(pwlanhdr->addr3, adapter_mac_addr(padapter), ETH_ALEN);
5219
5220 SetSeqNum(pwlanhdr, 0);
5221 SetFrameSubType(pframe, WIFI_ACTION);
5222
5223 pframe += sizeof(struct rtw_ieee80211_hdr_3addr);
5224 pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
5225
5226 pframe = rtw_set_fixed_ie(pframe, 1, &(category), &(pktlen));
5227 pframe = rtw_set_fixed_ie(pframe, 1, &(action), &(pktlen));
5228 pframe = rtw_set_fixed_ie(pframe, 4, (unsigned char *) &(p2poui), &(pktlen));
5229 pframe = rtw_set_fixed_ie(pframe, 1, &(oui_subtype), &(pktlen));
5230 /* dialog token, filled by FW */
5231 pframe = rtw_set_fixed_ie(pframe, 1, &(dialogToken), &(pktlen));
5232
5233 wpsielen = 0;
5234 /* WPS OUI */
5235 /* *(u32*) ( wpsie ) = cpu_to_be32( WPSOUI ); */
5236 RTW_PUT_BE32(wpsie, WPSOUI);
5237 wpsielen += 4;
5238
5239 #if 0
5240 /* WPS version */
5241 /* Type: */
5242 *(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_VER1);
5243 wpsielen += 2;
5244
5245 /* Length: */
5246 *(u16 *)(wpsie + wpsielen) = cpu_to_be16(0x0001);
5247 wpsielen += 2;
5248
5249 /* Value: */
5250 wpsie[wpsielen++] = WPS_VERSION_1; /* Version 1.0 */
5251 #endif
5252
5253 /* Config Method */
5254 /* Type: */
5255 /* *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_ATTR_CONF_METHOD ); */
5256 RTW_PUT_BE16(wpsie + wpsielen, WPS_ATTR_CONF_METHOD);
5257 wpsielen += 2;
5258
5259 /* Length: */
5260 /* *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( 0x0002 ); */
5261 RTW_PUT_BE16(wpsie + wpsielen, 0x0002);
5262 wpsielen += 2;
5263
5264 /* Value: filled by FW, default value is PBC */
5265 /* *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( config_method ); */
5266 RTW_PUT_BE16(wpsie + wpsielen, WPS_CM_PUSH_BUTTON);
5267 wpsielen += 2;
5268
5269 pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, wpsielen, (unsigned char *) wpsie, &pktlen);
5270
5271 #ifdef CONFIG_WFD
5272 wfdielen = build_provdisc_resp_wfd_ie(pwdinfo, pframe);
5273 pframe += wfdielen;
5274 pktlen += wfdielen;
5275 #endif
5276
5277 *pLength = pktlen;
5278
5279 /* printf dbg msg */
5280 #if 0
5281 dbgbufLen = pktlen;
5282 RTW_INFO("======> DBG MSG FOR CONSTRAUCT ProvisionDis Rsp\n");
5283
5284 for (index = 0; index < dbgbufLen; index++)
5285 printk("%x ", *(dbgbuf + index));
5286
5287 printk("\n");
5288 RTW_INFO("<====== DBG MSG FOR CONSTRAUCT ProvisionDis Rsp\n");
5289 #endif
5290 }
5291
rtw_hal_set_FwP2PRsvdPage_cmd(_adapter * adapter,PRSVDPAGE_LOC rsvdpageloc)5292 u8 rtw_hal_set_FwP2PRsvdPage_cmd(_adapter *adapter, PRSVDPAGE_LOC rsvdpageloc)
5293 {
5294 u8 u1H2CP2PRsvdPageParm[H2C_P2PRSVDPAGE_LOC_LEN] = {0};
5295 struct hal_ops *pHalFunc = &adapter->HalFunc;
5296 u8 ret = _FAIL;
5297
5298 RTW_INFO("P2PRsvdPageLoc: P2PBeacon=%d P2PProbeRsp=%d NegoRsp=%d InviteRsp=%d PDRsp=%d\n",
5299 rsvdpageloc->LocP2PBeacon, rsvdpageloc->LocP2PProbeRsp,
5300 rsvdpageloc->LocNegoRsp, rsvdpageloc->LocInviteRsp,
5301 rsvdpageloc->LocPDRsp);
5302
5303 SET_H2CCMD_RSVDPAGE_LOC_P2P_BCN(u1H2CP2PRsvdPageParm, rsvdpageloc->LocProbeRsp);
5304 SET_H2CCMD_RSVDPAGE_LOC_P2P_PROBE_RSP(u1H2CP2PRsvdPageParm, rsvdpageloc->LocPsPoll);
5305 SET_H2CCMD_RSVDPAGE_LOC_P2P_NEGO_RSP(u1H2CP2PRsvdPageParm, rsvdpageloc->LocNullData);
5306 SET_H2CCMD_RSVDPAGE_LOC_P2P_INVITE_RSP(u1H2CP2PRsvdPageParm, rsvdpageloc->LocQosNull);
5307 SET_H2CCMD_RSVDPAGE_LOC_P2P_PD_RSP(u1H2CP2PRsvdPageParm, rsvdpageloc->LocBTQosNull);
5308
5309 /* FillH2CCmd8723B(padapter, H2C_8723B_P2P_OFFLOAD_RSVD_PAGE, H2C_P2PRSVDPAGE_LOC_LEN, u1H2CP2PRsvdPageParm); */
5310 ret = rtw_hal_fill_h2c_cmd(adapter,
5311 H2C_P2P_OFFLOAD_RSVD_PAGE,
5312 H2C_P2PRSVDPAGE_LOC_LEN,
5313 u1H2CP2PRsvdPageParm);
5314
5315 return ret;
5316 }
5317
rtw_hal_set_p2p_wowlan_offload_cmd(_adapter * adapter)5318 u8 rtw_hal_set_p2p_wowlan_offload_cmd(_adapter *adapter)
5319 {
5320
5321 u8 offload_cmd[H2C_P2P_OFFLOAD_LEN] = {0};
5322 struct wifidirect_info *pwdinfo = &(adapter->wdinfo);
5323 struct P2P_WoWlan_Offload_t *p2p_wowlan_offload = (struct P2P_WoWlan_Offload_t *)offload_cmd;
5324 struct hal_ops *pHalFunc = &adapter->HalFunc;
5325 u8 ret = _FAIL;
5326
5327 _rtw_memset(p2p_wowlan_offload, 0 , sizeof(struct P2P_WoWlan_Offload_t));
5328 RTW_INFO("%s\n", __func__);
5329 switch (pwdinfo->role) {
5330 case P2P_ROLE_DEVICE:
5331 RTW_INFO("P2P_ROLE_DEVICE\n");
5332 p2p_wowlan_offload->role = 0;
5333 break;
5334 case P2P_ROLE_CLIENT:
5335 RTW_INFO("P2P_ROLE_CLIENT\n");
5336 p2p_wowlan_offload->role = 1;
5337 break;
5338 case P2P_ROLE_GO:
5339 RTW_INFO("P2P_ROLE_GO\n");
5340 p2p_wowlan_offload->role = 2;
5341 break;
5342 default:
5343 RTW_INFO("P2P_ROLE_DISABLE\n");
5344 break;
5345 }
5346 p2p_wowlan_offload->Wps_Config[0] = pwdinfo->supported_wps_cm >> 8;
5347 p2p_wowlan_offload->Wps_Config[1] = pwdinfo->supported_wps_cm;
5348 offload_cmd = (u8 *)p2p_wowlan_offload;
5349 RTW_INFO("p2p_wowlan_offload: %x:%x:%x\n", offload_cmd[0], offload_cmd[1], offload_cmd[2]);
5350
5351 ret = rtw_hal_fill_h2c_cmd(adapter,
5352 H2C_P2P_OFFLOAD,
5353 H2C_P2P_OFFLOAD_LEN,
5354 offload_cmd);
5355 return ret;
5356
5357 /* FillH2CCmd8723B(adapter, H2C_8723B_P2P_OFFLOAD, sizeof(struct P2P_WoWlan_Offload_t), (u8 *)p2p_wowlan_offload); */
5358 }
5359 #endif /* CONFIG_P2P_WOWLAN */
5360
rtw_hal_construct_beacon(_adapter * padapter,u8 * pframe,u32 * pLength)5361 static void rtw_hal_construct_beacon(_adapter *padapter,
5362 u8 *pframe, u32 *pLength)
5363 {
5364 struct rtw_ieee80211_hdr *pwlanhdr;
5365 u16 *fctrl;
5366 u32 rate_len, pktlen;
5367 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
5368 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
5369 WLAN_BSSID_EX *cur_network = &(pmlmeinfo->network);
5370 u8 bc_addr[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
5371
5372
5373 /* RTW_INFO("%s\n", __FUNCTION__); */
5374
5375 pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
5376
5377 fctrl = &(pwlanhdr->frame_ctl);
5378 *(fctrl) = 0;
5379
5380 _rtw_memcpy(pwlanhdr->addr1, bc_addr, ETH_ALEN);
5381 _rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN);
5382 _rtw_memcpy(pwlanhdr->addr3, get_my_bssid(cur_network), ETH_ALEN);
5383
5384 SetSeqNum(pwlanhdr, 0/*pmlmeext->mgnt_seq*/);
5385 /* pmlmeext->mgnt_seq++; */
5386 SetFrameSubType(pframe, WIFI_BEACON);
5387
5388 pframe += sizeof(struct rtw_ieee80211_hdr_3addr);
5389 pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
5390
5391 /* timestamp will be inserted by hardware */
5392 pframe += 8;
5393 pktlen += 8;
5394
5395 /* beacon interval: 2 bytes */
5396 _rtw_memcpy(pframe, (unsigned char *)(rtw_get_beacon_interval_from_ie(cur_network->IEs)), 2);
5397
5398 pframe += 2;
5399 pktlen += 2;
5400
5401 /* capability info: 2 bytes */
5402 _rtw_memcpy(pframe, (unsigned char *)(rtw_get_capability_from_ie(cur_network->IEs)), 2);
5403
5404 pframe += 2;
5405 pktlen += 2;
5406
5407 if ((pmlmeinfo->state & 0x03) == WIFI_FW_AP_STATE) {
5408 /* RTW_INFO("ie len=%d\n", cur_network->IELength); */
5409 pktlen += cur_network->IELength - sizeof(NDIS_802_11_FIXED_IEs);
5410 _rtw_memcpy(pframe, cur_network->IEs + sizeof(NDIS_802_11_FIXED_IEs), pktlen);
5411
5412 goto _ConstructBeacon;
5413 }
5414
5415 /* below for ad-hoc mode */
5416
5417 /* SSID */
5418 pframe = rtw_set_ie(pframe, _SSID_IE_, cur_network->Ssid.SsidLength, cur_network->Ssid.Ssid, &pktlen);
5419
5420 /* supported rates... */
5421 rate_len = rtw_get_rateset_len(cur_network->SupportedRates);
5422 pframe = rtw_set_ie(pframe, _SUPPORTEDRATES_IE_, ((rate_len > 8) ? 8 : rate_len), cur_network->SupportedRates, &pktlen);
5423
5424 /* DS parameter set */
5425 pframe = rtw_set_ie(pframe, _DSSET_IE_, 1, (unsigned char *)&(cur_network->Configuration.DSConfig), &pktlen);
5426
5427 if ((pmlmeinfo->state & 0x03) == WIFI_FW_ADHOC_STATE) {
5428 u32 ATIMWindow;
5429 /* IBSS Parameter Set... */
5430 /* ATIMWindow = cur->Configuration.ATIMWindow; */
5431 ATIMWindow = 0;
5432 pframe = rtw_set_ie(pframe, _IBSS_PARA_IE_, 2, (unsigned char *)(&ATIMWindow), &pktlen);
5433 }
5434
5435
5436 /* todo: ERP IE */
5437
5438
5439 /* EXTERNDED SUPPORTED RATE */
5440 if (rate_len > 8)
5441 pframe = rtw_set_ie(pframe, _EXT_SUPPORTEDRATES_IE_, (rate_len - 8), (cur_network->SupportedRates + 8), &pktlen);
5442
5443
5444 /* todo:HT for adhoc */
5445
5446 _ConstructBeacon:
5447
5448 if ((pktlen + TXDESC_SIZE) > 512) {
5449 RTW_INFO("beacon frame too large\n");
5450 return;
5451 }
5452
5453 *pLength = pktlen;
5454
5455 /* RTW_INFO("%s bcn_sz=%d\n", __FUNCTION__, pktlen); */
5456
5457 }
5458
rtw_hal_construct_PSPoll(_adapter * padapter,u8 * pframe,u32 * pLength)5459 static void rtw_hal_construct_PSPoll(_adapter *padapter,
5460 u8 *pframe, u32 *pLength)
5461 {
5462 struct rtw_ieee80211_hdr *pwlanhdr;
5463 u16 *fctrl;
5464 u32 pktlen;
5465 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
5466 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
5467
5468 /* RTW_INFO("%s\n", __FUNCTION__); */
5469
5470 pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
5471
5472 /* Frame control. */
5473 fctrl = &(pwlanhdr->frame_ctl);
5474 *(fctrl) = 0;
5475 SetPwrMgt(fctrl);
5476 SetFrameSubType(pframe, WIFI_PSPOLL);
5477
5478 /* AID. */
5479 SetDuration(pframe, (pmlmeinfo->aid | 0xc000));
5480
5481 /* BSSID. */
5482 _rtw_memcpy(pwlanhdr->addr1, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
5483
5484 /* TA. */
5485 _rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN);
5486
5487 *pLength = 16;
5488 }
5489
rtw_hal_construct_NullFunctionData(PADAPTER padapter,u8 * pframe,u32 * pLength,u8 * StaAddr,u8 bQoS,u8 AC,u8 bEosp,u8 bForcePowerSave)5490 void rtw_hal_construct_NullFunctionData(
5491 PADAPTER padapter,
5492 u8 *pframe,
5493 u32 *pLength,
5494 u8 *StaAddr,
5495 u8 bQoS,
5496 u8 AC,
5497 u8 bEosp,
5498 u8 bForcePowerSave)
5499 {
5500 struct rtw_ieee80211_hdr *pwlanhdr;
5501 u16 *fctrl;
5502 u32 pktlen;
5503 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
5504 struct wlan_network *cur_network = &pmlmepriv->cur_network;
5505 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
5506 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
5507
5508
5509 /* RTW_INFO("%s:%d\n", __FUNCTION__, bForcePowerSave); */
5510
5511 pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
5512
5513 fctrl = &pwlanhdr->frame_ctl;
5514 *(fctrl) = 0;
5515 if (bForcePowerSave)
5516 SetPwrMgt(fctrl);
5517
5518 switch (cur_network->network.InfrastructureMode) {
5519 case Ndis802_11Infrastructure:
5520 SetToDs(fctrl);
5521 _rtw_memcpy(pwlanhdr->addr1, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
5522 _rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN);
5523 _rtw_memcpy(pwlanhdr->addr3, StaAddr, ETH_ALEN);
5524 break;
5525 case Ndis802_11APMode:
5526 SetFrDs(fctrl);
5527 _rtw_memcpy(pwlanhdr->addr1, StaAddr, ETH_ALEN);
5528 _rtw_memcpy(pwlanhdr->addr2, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
5529 _rtw_memcpy(pwlanhdr->addr3, adapter_mac_addr(padapter), ETH_ALEN);
5530 break;
5531 case Ndis802_11IBSS:
5532 default:
5533 _rtw_memcpy(pwlanhdr->addr1, StaAddr, ETH_ALEN);
5534 _rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN);
5535 _rtw_memcpy(pwlanhdr->addr3, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
5536 break;
5537 }
5538
5539 SetSeqNum(pwlanhdr, 0);
5540
5541 if (bQoS == _TRUE) {
5542 struct rtw_ieee80211_hdr_3addr_qos *pwlanqoshdr;
5543
5544 SetFrameSubType(pframe, WIFI_QOS_DATA_NULL);
5545
5546 pwlanqoshdr = (struct rtw_ieee80211_hdr_3addr_qos *)pframe;
5547 SetPriority(&pwlanqoshdr->qc, AC);
5548 SetEOSP(&pwlanqoshdr->qc, bEosp);
5549
5550 pktlen = sizeof(struct rtw_ieee80211_hdr_3addr_qos);
5551 } else {
5552 SetFrameSubType(pframe, WIFI_DATA_NULL);
5553
5554 pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
5555 }
5556
5557 *pLength = pktlen;
5558 }
5559
rtw_hal_construct_ProbeRsp(_adapter * padapter,u8 * pframe,u32 * pLength,u8 * StaAddr,BOOLEAN bHideSSID)5560 void rtw_hal_construct_ProbeRsp(_adapter *padapter, u8 *pframe, u32 *pLength,
5561 u8 *StaAddr, BOOLEAN bHideSSID)
5562 {
5563 struct rtw_ieee80211_hdr *pwlanhdr;
5564 u16 *fctrl;
5565 u8 *mac, *bssid;
5566 u32 pktlen;
5567 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
5568 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
5569 WLAN_BSSID_EX *cur_network = &(pmlmeinfo->network);
5570
5571 /*RTW_INFO("%s\n", __FUNCTION__);*/
5572
5573 pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
5574
5575 mac = adapter_mac_addr(padapter);
5576 bssid = cur_network->MacAddress;
5577
5578 fctrl = &(pwlanhdr->frame_ctl);
5579 *(fctrl) = 0;
5580 _rtw_memcpy(pwlanhdr->addr1, StaAddr, ETH_ALEN);
5581 _rtw_memcpy(pwlanhdr->addr2, mac, ETH_ALEN);
5582 _rtw_memcpy(pwlanhdr->addr3, bssid, ETH_ALEN);
5583
5584 SetSeqNum(pwlanhdr, 0);
5585 SetFrameSubType(fctrl, WIFI_PROBERSP);
5586
5587 pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
5588 pframe += pktlen;
5589
5590 if (cur_network->IELength > MAX_IE_SZ)
5591 return;
5592
5593 _rtw_memcpy(pframe, cur_network->IEs, cur_network->IELength);
5594 pframe += cur_network->IELength;
5595 pktlen += cur_network->IELength;
5596
5597 *pLength = pktlen;
5598 }
5599
5600 #ifdef CONFIG_WOWLAN
5601 /*
5602 * Description:
5603 * Construct the ARP response packet to support ARP offload.
5604 * */
rtw_hal_construct_ARPRsp(PADAPTER padapter,u8 * pframe,u32 * pLength,u8 * pIPAddress)5605 static void rtw_hal_construct_ARPRsp(
5606 PADAPTER padapter,
5607 u8 *pframe,
5608 u32 *pLength,
5609 u8 *pIPAddress
5610 )
5611 {
5612 struct rtw_ieee80211_hdr *pwlanhdr;
5613 u16 *fctrl;
5614 u32 pktlen;
5615 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
5616 struct wlan_network *cur_network = &pmlmepriv->cur_network;
5617 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
5618 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
5619 struct security_priv *psecuritypriv = &padapter->securitypriv;
5620 static u8 ARPLLCHeader[8] = {0xAA, 0xAA, 0x03, 0x00, 0x00, 0x00, 0x08, 0x06};
5621 u8 *pARPRspPkt = pframe;
5622 /* for TKIP Cal MIC */
5623 u8 *payload = pframe;
5624 u8 EncryptionHeadOverhead = 0;
5625 /* RTW_INFO("%s:%d\n", __FUNCTION__, bForcePowerSave); */
5626
5627 pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
5628
5629 fctrl = &pwlanhdr->frame_ctl;
5630 *(fctrl) = 0;
5631
5632 /* ------------------------------------------------------------------------- */
5633 /* MAC Header. */
5634 /* ------------------------------------------------------------------------- */
5635 SetFrameType(fctrl, WIFI_DATA);
5636 /* SetFrameSubType(fctrl, 0); */
5637 SetToDs(fctrl);
5638 _rtw_memcpy(pwlanhdr->addr1, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
5639 _rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN);
5640 _rtw_memcpy(pwlanhdr->addr3, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
5641
5642 SetSeqNum(pwlanhdr, 0);
5643 SetDuration(pwlanhdr, 0);
5644 /* SET_80211_HDR_FRAME_CONTROL(pARPRspPkt, 0); */
5645 /* SET_80211_HDR_TYPE_AND_SUBTYPE(pARPRspPkt, Type_Data); */
5646 /* SET_80211_HDR_TO_DS(pARPRspPkt, 1); */
5647 /* SET_80211_HDR_ADDRESS1(pARPRspPkt, pMgntInfo->Bssid); */
5648 /* SET_80211_HDR_ADDRESS2(pARPRspPkt, Adapter->CurrentAddress); */
5649 /* SET_80211_HDR_ADDRESS3(pARPRspPkt, pMgntInfo->Bssid); */
5650
5651 /* SET_80211_HDR_DURATION(pARPRspPkt, 0); */
5652 /* SET_80211_HDR_FRAGMENT_SEQUENCE(pARPRspPkt, 0); */
5653 #ifdef CONFIG_WAPI_SUPPORT
5654 *pLength = sMacHdrLng;
5655 #else
5656 *pLength = 24;
5657 #endif
5658 switch (psecuritypriv->dot11PrivacyAlgrthm) {
5659 case _WEP40_:
5660 case _WEP104_:
5661 EncryptionHeadOverhead = 4;
5662 break;
5663 case _TKIP_:
5664 EncryptionHeadOverhead = 8;
5665 break;
5666 case _AES_:
5667 EncryptionHeadOverhead = 8;
5668 break;
5669 #ifdef CONFIG_WAPI_SUPPORT
5670 case _SMS4_:
5671 EncryptionHeadOverhead = 18;
5672 break;
5673 #endif
5674 default:
5675 EncryptionHeadOverhead = 0;
5676 }
5677
5678 if (EncryptionHeadOverhead > 0) {
5679 _rtw_memset(&(pframe[*pLength]), 0, EncryptionHeadOverhead);
5680 *pLength += EncryptionHeadOverhead;
5681 /* SET_80211_HDR_WEP(pARPRspPkt, 1); */ /* Suggested by CCW. */
5682 SetPrivacy(fctrl);
5683 }
5684
5685 /* ------------------------------------------------------------------------- */
5686 /* Frame Body. */
5687 /* ------------------------------------------------------------------------- */
5688 pARPRspPkt = (u8 *)(pframe + *pLength);
5689 payload = pARPRspPkt; /* Get Payload pointer */
5690 /* LLC header */
5691 _rtw_memcpy(pARPRspPkt, ARPLLCHeader, 8);
5692 *pLength += 8;
5693
5694 /* ARP element */
5695 pARPRspPkt += 8;
5696 SET_ARP_PKT_HW(pARPRspPkt, 0x0100);
5697 SET_ARP_PKT_PROTOCOL(pARPRspPkt, 0x0008); /* IP protocol */
5698 SET_ARP_PKT_HW_ADDR_LEN(pARPRspPkt, 6);
5699 SET_ARP_PKT_PROTOCOL_ADDR_LEN(pARPRspPkt, 4);
5700 SET_ARP_PKT_OPERATION(pARPRspPkt, 0x0200); /* ARP response */
5701 SET_ARP_PKT_SENDER_MAC_ADDR(pARPRspPkt, adapter_mac_addr(padapter));
5702 SET_ARP_PKT_SENDER_IP_ADDR(pARPRspPkt, pIPAddress);
5703 #ifdef CONFIG_ARP_KEEP_ALIVE
5704 if (!is_zero_mac_addr(pmlmepriv->gw_mac_addr)) {
5705 SET_ARP_PKT_TARGET_MAC_ADDR(pARPRspPkt, pmlmepriv->gw_mac_addr);
5706 SET_ARP_PKT_TARGET_IP_ADDR(pARPRspPkt, pmlmepriv->gw_ip);
5707 } else
5708 #endif
5709 {
5710 SET_ARP_PKT_TARGET_MAC_ADDR(pARPRspPkt,
5711 get_my_bssid(&(pmlmeinfo->network)));
5712 SET_ARP_PKT_TARGET_IP_ADDR(pARPRspPkt,
5713 pIPAddress);
5714 RTW_INFO("%s Target Mac Addr:" MAC_FMT "\n", __FUNCTION__,
5715 MAC_ARG(get_my_bssid(&(pmlmeinfo->network))));
5716 RTW_INFO("%s Target IP Addr" IP_FMT "\n", __FUNCTION__,
5717 IP_ARG(pIPAddress));
5718 }
5719
5720 *pLength += 28;
5721
5722 if (psecuritypriv->dot11PrivacyAlgrthm == _TKIP_) {
5723 u8 mic[8];
5724 struct mic_data micdata;
5725 struct sta_info *psta = NULL;
5726 u8 priority[4] = {0x0, 0x0, 0x0, 0x0};
5727 u8 null_key[16] = {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0};
5728
5729 RTW_INFO("%s(): Add MIC\n", __FUNCTION__);
5730
5731 psta = rtw_get_stainfo(&padapter->stapriv,
5732 get_my_bssid(&(pmlmeinfo->network)));
5733 if (psta != NULL) {
5734 if (_rtw_memcmp(&psta->dot11tkiptxmickey.skey[0],
5735 null_key, 16) == _TRUE) {
5736 RTW_INFO("%s(): STA dot11tkiptxmickey==0\n",
5737 __func__);
5738 }
5739 /* start to calculate the mic code */
5740 rtw_secmicsetkey(&micdata,
5741 &psta->dot11tkiptxmickey.skey[0]);
5742 }
5743
5744 rtw_secmicappend(&micdata, pwlanhdr->addr3, 6); /* DA */
5745
5746 rtw_secmicappend(&micdata, pwlanhdr->addr2, 6); /* SA */
5747
5748 priority[0] = 0;
5749
5750 rtw_secmicappend(&micdata, &priority[0], 4);
5751
5752 rtw_secmicappend(&micdata, payload, 36); /* payload length = 8 + 28 */
5753
5754 rtw_secgetmic(&micdata, &(mic[0]));
5755
5756 pARPRspPkt += 28;
5757 _rtw_memcpy(pARPRspPkt, &(mic[0]), 8);
5758
5759 *pLength += 8;
5760 }
5761 }
5762
5763 #ifdef CONFIG_PNO_SUPPORT
rtw_hal_construct_ProbeReq(_adapter * padapter,u8 * pframe,u32 * pLength,pno_ssid_t * ssid)5764 static void rtw_hal_construct_ProbeReq(_adapter *padapter, u8 *pframe,
5765 u32 *pLength, pno_ssid_t *ssid)
5766 {
5767 struct rtw_ieee80211_hdr *pwlanhdr;
5768 u16 *fctrl;
5769 u32 pktlen;
5770 unsigned char *mac;
5771 unsigned char bssrate[NumRates];
5772 struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
5773 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
5774 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
5775 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
5776 int bssrate_len = 0;
5777 u8 bc_addr[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
5778
5779 pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
5780 mac = adapter_mac_addr(padapter);
5781
5782 fctrl = &(pwlanhdr->frame_ctl);
5783 *(fctrl) = 0;
5784
5785 _rtw_memcpy(pwlanhdr->addr1, bc_addr, ETH_ALEN);
5786 _rtw_memcpy(pwlanhdr->addr3, bc_addr, ETH_ALEN);
5787
5788 _rtw_memcpy(pwlanhdr->addr2, mac, ETH_ALEN);
5789
5790 SetSeqNum(pwlanhdr, 0);
5791 SetFrameSubType(pframe, WIFI_PROBEREQ);
5792
5793 pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
5794 pframe += pktlen;
5795
5796 if (ssid == NULL)
5797 pframe = rtw_set_ie(pframe, _SSID_IE_, 0, NULL, &pktlen);
5798 else {
5799 /* RTW_INFO("%s len:%d\n", ssid->SSID, ssid->SSID_len); */
5800 pframe = rtw_set_ie(pframe, _SSID_IE_, ssid->SSID_len, ssid->SSID, &pktlen);
5801 }
5802
5803 get_rate_set(padapter, bssrate, &bssrate_len);
5804
5805 if (bssrate_len > 8) {
5806 pframe = rtw_set_ie(pframe, _SUPPORTEDRATES_IE_ , 8, bssrate, &pktlen);
5807 pframe = rtw_set_ie(pframe, _EXT_SUPPORTEDRATES_IE_ , (bssrate_len - 8), (bssrate + 8), &pktlen);
5808 } else
5809 pframe = rtw_set_ie(pframe, _SUPPORTEDRATES_IE_ , bssrate_len , bssrate, &pktlen);
5810
5811 *pLength = pktlen;
5812 }
5813
rtw_hal_construct_PNO_info(_adapter * padapter,u8 * pframe,u32 * pLength)5814 static void rtw_hal_construct_PNO_info(_adapter *padapter,
5815 u8 *pframe, u32 *pLength)
5816 {
5817 struct pwrctrl_priv *pwrctl = adapter_to_pwrctl(padapter);
5818 int i;
5819
5820 u8 *pPnoInfoPkt = pframe;
5821 pPnoInfoPkt = (u8 *)(pframe + *pLength);
5822 _rtw_memcpy(pPnoInfoPkt, &pwrctl->pnlo_info->ssid_num, 1);
5823
5824 pPnoInfoPkt += 1;
5825 _rtw_memcpy(pPnoInfoPkt, &pwrctl->pnlo_info->hidden_ssid_num, 1);
5826
5827 pPnoInfoPkt += 3;
5828 _rtw_memcpy(pPnoInfoPkt, &pwrctl->pnlo_info->fast_scan_period, 1);
5829
5830 pPnoInfoPkt += 4;
5831 _rtw_memcpy(pPnoInfoPkt, &pwrctl->pnlo_info->fast_scan_iterations, 4);
5832
5833 pPnoInfoPkt += 4;
5834 _rtw_memcpy(pPnoInfoPkt, &pwrctl->pnlo_info->slow_scan_period, 4);
5835
5836 pPnoInfoPkt += 4;
5837 _rtw_memcpy(pPnoInfoPkt, &pwrctl->pnlo_info->ssid_length, MAX_PNO_LIST_COUNT);
5838
5839 pPnoInfoPkt += MAX_PNO_LIST_COUNT;
5840 _rtw_memcpy(pPnoInfoPkt, &pwrctl->pnlo_info->ssid_cipher_info, MAX_PNO_LIST_COUNT);
5841
5842 pPnoInfoPkt += MAX_PNO_LIST_COUNT;
5843 _rtw_memcpy(pPnoInfoPkt, &pwrctl->pnlo_info->ssid_channel_info, MAX_PNO_LIST_COUNT);
5844
5845 pPnoInfoPkt += MAX_PNO_LIST_COUNT;
5846 _rtw_memcpy(pPnoInfoPkt, &pwrctl->pnlo_info->loc_probe_req, MAX_HIDDEN_AP);
5847
5848 pPnoInfoPkt += MAX_HIDDEN_AP;
5849
5850 /*
5851 SSID is located at 128th Byte in NLO info Page
5852 */
5853
5854 *pLength += 128;
5855 pPnoInfoPkt = pframe + 128;
5856
5857 for (i = 0; i < pwrctl->pnlo_info->ssid_num ; i++) {
5858 _rtw_memcpy(pPnoInfoPkt, &pwrctl->pno_ssid_list->node[i].SSID,
5859 pwrctl->pnlo_info->ssid_length[i]);
5860 *pLength += WLAN_SSID_MAXLEN;
5861 pPnoInfoPkt += WLAN_SSID_MAXLEN;
5862 }
5863 }
5864
rtw_hal_construct_ssid_list(_adapter * padapter,u8 * pframe,u32 * pLength)5865 static void rtw_hal_construct_ssid_list(_adapter *padapter,
5866 u8 *pframe, u32 *pLength)
5867 {
5868 struct pwrctrl_priv *pwrctl = adapter_to_pwrctl(padapter);
5869 u8 *pSSIDListPkt = pframe;
5870 int i;
5871
5872 pSSIDListPkt = (u8 *)(pframe + *pLength);
5873
5874 for (i = 0; i < pwrctl->pnlo_info->ssid_num ; i++) {
5875 _rtw_memcpy(pSSIDListPkt, &pwrctl->pno_ssid_list->node[i].SSID,
5876 pwrctl->pnlo_info->ssid_length[i]);
5877
5878 *pLength += WLAN_SSID_MAXLEN;
5879 pSSIDListPkt += WLAN_SSID_MAXLEN;
5880 }
5881 }
5882
rtw_hal_construct_scan_info(_adapter * padapter,u8 * pframe,u32 * pLength)5883 static void rtw_hal_construct_scan_info(_adapter *padapter,
5884 u8 *pframe, u32 *pLength)
5885 {
5886 struct pwrctrl_priv *pwrctl = adapter_to_pwrctl(padapter);
5887 u8 *pScanInfoPkt = pframe;
5888 int i;
5889
5890 pScanInfoPkt = (u8 *)(pframe + *pLength);
5891
5892 _rtw_memcpy(pScanInfoPkt, &pwrctl->pscan_info->channel_num, 1);
5893
5894 *pLength += 1;
5895 pScanInfoPkt += 1;
5896 _rtw_memcpy(pScanInfoPkt, &pwrctl->pscan_info->orig_ch, 1);
5897
5898
5899 *pLength += 1;
5900 pScanInfoPkt += 1;
5901 _rtw_memcpy(pScanInfoPkt, &pwrctl->pscan_info->orig_bw, 1);
5902
5903
5904 *pLength += 1;
5905 pScanInfoPkt += 1;
5906 _rtw_memcpy(pScanInfoPkt, &pwrctl->pscan_info->orig_40_offset, 1);
5907
5908 *pLength += 1;
5909 pScanInfoPkt += 1;
5910 _rtw_memcpy(pScanInfoPkt, &pwrctl->pscan_info->orig_80_offset, 1);
5911
5912 *pLength += 1;
5913 pScanInfoPkt += 1;
5914 _rtw_memcpy(pScanInfoPkt, &pwrctl->pscan_info->periodScan, 1);
5915
5916 *pLength += 1;
5917 pScanInfoPkt += 1;
5918 _rtw_memcpy(pScanInfoPkt, &pwrctl->pscan_info->period_scan_time, 1);
5919
5920 *pLength += 1;
5921 pScanInfoPkt += 1;
5922 _rtw_memcpy(pScanInfoPkt, &pwrctl->pscan_info->enableRFE, 1);
5923
5924 *pLength += 1;
5925 pScanInfoPkt += 1;
5926 _rtw_memcpy(pScanInfoPkt, &pwrctl->pscan_info->rfe_type, 8);
5927
5928 *pLength += 8;
5929 pScanInfoPkt += 8;
5930
5931 for (i = 0 ; i < MAX_SCAN_LIST_COUNT ; i++) {
5932 _rtw_memcpy(pScanInfoPkt,
5933 &pwrctl->pscan_info->ssid_channel_info[i], 4);
5934 *pLength += 4;
5935 pScanInfoPkt += 4;
5936 }
5937 }
5938 #endif /* CONFIG_PNO_SUPPORT */
5939
5940 #ifdef CONFIG_GTK_OL
rtw_hal_construct_GTKRsp(PADAPTER padapter,u8 * pframe,u32 * pLength)5941 static void rtw_hal_construct_GTKRsp(
5942 PADAPTER padapter,
5943 u8 *pframe,
5944 u32 *pLength
5945 )
5946 {
5947 struct rtw_ieee80211_hdr *pwlanhdr;
5948 u16 *fctrl;
5949 u32 pktlen;
5950 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
5951 struct wlan_network *cur_network = &pmlmepriv->cur_network;
5952 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
5953 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
5954 struct security_priv *psecuritypriv = &padapter->securitypriv;
5955 static u8 LLCHeader[8] = {0xAA, 0xAA, 0x03, 0x00, 0x00, 0x00, 0x88, 0x8E};
5956 static u8 GTKbody_a[11] = {0x01, 0x03, 0x00, 0x5F, 0x02, 0x03, 0x12, 0x00, 0x10, 0x42, 0x0B};
5957 u8 *pGTKRspPkt = pframe;
5958 u8 EncryptionHeadOverhead = 0;
5959 /* RTW_INFO("%s:%d\n", __FUNCTION__, bForcePowerSave); */
5960
5961 pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
5962
5963 fctrl = &pwlanhdr->frame_ctl;
5964 *(fctrl) = 0;
5965
5966 /* ------------------------------------------------------------------------- */
5967 /* MAC Header. */
5968 /* ------------------------------------------------------------------------- */
5969 SetFrameType(fctrl, WIFI_DATA);
5970 /* SetFrameSubType(fctrl, 0); */
5971 SetToDs(fctrl);
5972
5973 _rtw_memcpy(pwlanhdr->addr1,
5974 get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
5975
5976 _rtw_memcpy(pwlanhdr->addr2,
5977 adapter_mac_addr(padapter), ETH_ALEN);
5978
5979 _rtw_memcpy(pwlanhdr->addr3,
5980 get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
5981
5982 SetSeqNum(pwlanhdr, 0);
5983 SetDuration(pwlanhdr, 0);
5984
5985 #ifdef CONFIG_WAPI_SUPPORT
5986 *pLength = sMacHdrLng;
5987 #else
5988 *pLength = 24;
5989 #endif /* CONFIG_WAPI_SUPPORT */
5990
5991 /* ------------------------------------------------------------------------- */
5992 /* Security Header: leave space for it if necessary. */
5993 /* ------------------------------------------------------------------------- */
5994 switch (psecuritypriv->dot11PrivacyAlgrthm) {
5995 case _WEP40_:
5996 case _WEP104_:
5997 EncryptionHeadOverhead = 4;
5998 break;
5999 case _TKIP_:
6000 EncryptionHeadOverhead = 8;
6001 break;
6002 case _AES_:
6003 EncryptionHeadOverhead = 8;
6004 break;
6005 #ifdef CONFIG_WAPI_SUPPORT
6006 case _SMS4_:
6007 EncryptionHeadOverhead = 18;
6008 break;
6009 #endif /* CONFIG_WAPI_SUPPORT */
6010 default:
6011 EncryptionHeadOverhead = 0;
6012 }
6013
6014 if (EncryptionHeadOverhead > 0) {
6015 _rtw_memset(&(pframe[*pLength]), 0, EncryptionHeadOverhead);
6016 *pLength += EncryptionHeadOverhead;
6017 /* SET_80211_HDR_WEP(pGTKRspPkt, 1); */ /* Suggested by CCW. */
6018 /* GTK's privacy bit is done by FW */
6019 /* SetPrivacy(fctrl); */
6020 }
6021 /* ------------------------------------------------------------------------- */
6022 /* Frame Body. */
6023 /* ------------------------------------------------------------------------- */
6024 pGTKRspPkt = (u8 *)(pframe + *pLength);
6025 /* LLC header */
6026 _rtw_memcpy(pGTKRspPkt, LLCHeader, 8);
6027 *pLength += 8;
6028
6029 /* GTK element */
6030 pGTKRspPkt += 8;
6031
6032 /* GTK frame body after LLC, part 1 */
6033 _rtw_memcpy(pGTKRspPkt, GTKbody_a, 11);
6034 *pLength += 11;
6035 pGTKRspPkt += 11;
6036 /* GTK frame body after LLC, part 2 */
6037 _rtw_memset(&(pframe[*pLength]), 0, 88);
6038 *pLength += 88;
6039 pGTKRspPkt += 88;
6040
6041 }
6042 #endif /* CONFIG_GTK_OL */
6043
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)6044 void rtw_hal_set_wow_fw_rsvd_page(_adapter *adapter, u8 *pframe, u16 index,
6045 u8 tx_desc, u32 page_size, u8 *page_num, u32 *total_pkt_len,
6046 RSVDPAGE_LOC *rsvd_page_loc)
6047 {
6048 struct security_priv *psecuritypriv = &adapter->securitypriv;
6049 struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
6050 struct pwrctrl_priv *pwrctl = adapter_to_pwrctl(adapter);
6051 struct mlme_ext_priv *pmlmeext;
6052 struct mlme_ext_info *pmlmeinfo;
6053 u32 ARPLegnth = 0, GTKLegnth = 0, PNOLength = 0, ScanInfoLength = 0;
6054 u32 SSIDLegnth = 0, ProbeReqLength = 0;
6055 u8 CurtPktPageNum = 0;
6056 u8 currentip[4];
6057 u8 cur_dot11txpn[8];
6058
6059 #ifdef CONFIG_GTK_OL
6060 struct sta_priv *pstapriv = &adapter->stapriv;
6061 struct sta_info *psta;
6062 u8 kek[RTW_KEK_LEN];
6063 u8 kck[RTW_KCK_LEN];
6064 #endif /* CONFIG_GTK_OL */
6065 #ifdef CONFIG_PNO_SUPPORT
6066 int pno_index;
6067 u8 ssid_num;
6068 #endif /* CONFIG_PNO_SUPPORT */
6069
6070 pmlmeext = &adapter->mlmeextpriv;
6071 pmlmeinfo = &pmlmeext->mlmext_info;
6072
6073 if (pwrctl->wowlan_pno_enable == _FALSE) {
6074 /* ARP RSP * 1 page */
6075 rtw_get_current_ip_address(adapter, currentip);
6076
6077 rsvd_page_loc->LocArpRsp = *page_num;
6078
6079 RTW_INFO("LocArpRsp: %d\n", rsvd_page_loc->LocArpRsp);
6080
6081 rtw_hal_construct_ARPRsp(adapter, &pframe[index],
6082 &ARPLegnth, currentip);
6083
6084 rtw_hal_fill_fake_txdesc(adapter,
6085 &pframe[index - tx_desc],
6086 ARPLegnth, _FALSE, _FALSE, _TRUE);
6087
6088 CurtPktPageNum = (u8)PageNum(tx_desc + ARPLegnth, page_size);
6089
6090 *page_num += CurtPktPageNum;
6091
6092 index += (CurtPktPageNum * page_size);
6093
6094 /* 3 SEC IV * 1 page */
6095 rtw_get_sec_iv(adapter, cur_dot11txpn,
6096 get_my_bssid(&pmlmeinfo->network));
6097
6098 rsvd_page_loc->LocRemoteCtrlInfo = *page_num;
6099
6100 RTW_INFO("LocRemoteCtrlInfo: %d\n", rsvd_page_loc->LocRemoteCtrlInfo);
6101
6102 _rtw_memcpy(pframe + index - tx_desc, cur_dot11txpn, _AES_IV_LEN_);
6103
6104 CurtPktPageNum = (u8)PageNum(_AES_IV_LEN_, page_size);
6105
6106 *page_num += CurtPktPageNum;
6107
6108 *total_pkt_len = index + _AES_IV_LEN_;
6109 #ifdef CONFIG_GTK_OL
6110 index += (CurtPktPageNum * page_size);
6111
6112 /* if the ap staion info. exists, get the kek, kck from staion info. */
6113 psta = rtw_get_stainfo(pstapriv, get_bssid(pmlmepriv));
6114 if (psta == NULL) {
6115 _rtw_memset(kek, 0, RTW_KEK_LEN);
6116 _rtw_memset(kck, 0, RTW_KCK_LEN);
6117 RTW_INFO("%s, KEK, KCK download rsvd page all zero\n",
6118 __func__);
6119 } else {
6120 _rtw_memcpy(kek, psta->kek, RTW_KEK_LEN);
6121 _rtw_memcpy(kck, psta->kck, RTW_KCK_LEN);
6122 }
6123
6124 /* 3 KEK, KCK */
6125 rsvd_page_loc->LocGTKInfo = *page_num;
6126 RTW_INFO("LocGTKInfo: %d\n", rsvd_page_loc->LocGTKInfo);
6127
6128 if (IS_HARDWARE_TYPE_8188E(adapter) || IS_HARDWARE_TYPE_8812(adapter)) {
6129 struct security_priv *psecpriv = NULL;
6130
6131 psecpriv = &adapter->securitypriv;
6132 _rtw_memcpy(pframe + index - tx_desc,
6133 &psecpriv->dot11PrivacyAlgrthm, 1);
6134 _rtw_memcpy(pframe + index - tx_desc + 1,
6135 &psecpriv->dot118021XGrpPrivacy, 1);
6136 _rtw_memcpy(pframe + index - tx_desc + 2,
6137 kck, RTW_KCK_LEN);
6138 _rtw_memcpy(pframe + index - tx_desc + 2 + RTW_KCK_LEN,
6139 kek, RTW_KEK_LEN);
6140 CurtPktPageNum = (u8)PageNum(tx_desc + 2 + RTW_KCK_LEN + RTW_KEK_LEN, page_size);
6141 } else {
6142 _rtw_memcpy(pframe + index - tx_desc, kck, RTW_KCK_LEN);
6143 _rtw_memcpy(pframe + index - tx_desc + RTW_KCK_LEN, kek, RTW_KEK_LEN);
6144 CurtPktPageNum = (u8)PageNum(tx_desc + RTW_KCK_LEN + RTW_KEK_LEN, page_size);
6145 }
6146
6147
6148
6149 #if 0
6150 {
6151 int i;
6152 printk("\ntoFW KCK: ");
6153 for (i = 0; i < 16; i++)
6154 printk(" %02x ", kck[i]);
6155 printk("\ntoFW KEK: ");
6156 for (i = 0; i < 16; i++)
6157 printk(" %02x ", kek[i]);
6158 printk("\n");
6159 }
6160
6161 RTW_INFO("%s(): HW_VAR_SET_TX_CMD: KEK KCK %p %d\n",
6162 __FUNCTION__, &pframe[index - tx_desc],
6163 (tx_desc + RTW_KCK_LEN + RTW_KEK_LEN));
6164 #endif
6165
6166 *page_num += CurtPktPageNum;
6167
6168 index += (CurtPktPageNum * page_size);
6169
6170 /* 3 GTK Response */
6171 rsvd_page_loc->LocGTKRsp = *page_num;
6172 RTW_INFO("LocGTKRsp: %d\n", rsvd_page_loc->LocGTKRsp);
6173 rtw_hal_construct_GTKRsp(adapter, &pframe[index], >KLegnth);
6174
6175 rtw_hal_fill_fake_txdesc(adapter, &pframe[index - tx_desc],
6176 GTKLegnth, _FALSE, _FALSE, _TRUE);
6177 #if 0
6178 {
6179 int gj;
6180 printk("123GTK pkt=>\n");
6181 for (gj = 0; gj < GTKLegnth + tx_desc; gj++) {
6182 printk(" %02x ", pframe[index - tx_desc + gj]);
6183 if ((gj + 1) % 16 == 0)
6184 printk("\n");
6185 }
6186 printk(" <=end\n");
6187 }
6188
6189 RTW_INFO("%s(): HW_VAR_SET_TX_CMD: GTK RSP %p %d\n",
6190 __FUNCTION__, &pframe[index - tx_desc],
6191 (tx_desc + GTKLegnth));
6192 #endif
6193
6194 CurtPktPageNum = (u8)PageNum(tx_desc + GTKLegnth, page_size);
6195
6196 *page_num += CurtPktPageNum;
6197
6198 index += (CurtPktPageNum * page_size);
6199
6200 /* below page is empty for GTK extension memory */
6201 /* 3(11) GTK EXT MEM */
6202 rsvd_page_loc->LocGTKEXTMEM = *page_num;
6203 RTW_INFO("LocGTKEXTMEM: %d\n", rsvd_page_loc->LocGTKEXTMEM);
6204 CurtPktPageNum = 2;
6205
6206 if (page_size >= 256)
6207 CurtPktPageNum = 1;
6208
6209 *page_num += CurtPktPageNum;
6210 /* extension memory for FW */
6211 *total_pkt_len = index + (page_size * CurtPktPageNum);
6212
6213 #endif /* CONFIG_GTK_OL */
6214 } else {
6215 #ifdef CONFIG_PNO_SUPPORT
6216 if (pwrctl->pno_in_resume == _FALSE &&
6217 pwrctl->pno_inited == _TRUE) {
6218
6219 /* Broadcast Probe Request */
6220 rsvd_page_loc->LocProbePacket = *page_num;
6221
6222 RTW_INFO("loc_probe_req: %d\n",
6223 rsvd_page_loc->LocProbePacket);
6224
6225 rtw_hal_construct_ProbeReq(
6226 adapter,
6227 &pframe[index],
6228 &ProbeReqLength,
6229 NULL);
6230
6231 rtw_hal_fill_fake_txdesc(adapter,
6232 &pframe[index - tx_desc],
6233 ProbeReqLength, _FALSE, _FALSE, _FALSE);
6234
6235 CurtPktPageNum =
6236 (u8)PageNum(tx_desc + ProbeReqLength, page_size);
6237
6238 *page_num += CurtPktPageNum;
6239
6240 index += (CurtPktPageNum * page_size);
6241
6242 /* Hidden SSID Probe Request */
6243 ssid_num = pwrctl->pnlo_info->hidden_ssid_num;
6244
6245 for (pno_index = 0 ; pno_index < ssid_num ; pno_index++) {
6246 pwrctl->pnlo_info->loc_probe_req[pno_index] =
6247 *page_num;
6248
6249 rtw_hal_construct_ProbeReq(
6250 adapter,
6251 &pframe[index],
6252 &ProbeReqLength,
6253 &pwrctl->pno_ssid_list->node[pno_index]);
6254
6255 rtw_hal_fill_fake_txdesc(adapter,
6256 &pframe[index - tx_desc],
6257 ProbeReqLength, _FALSE, _FALSE, _FALSE);
6258
6259 CurtPktPageNum =
6260 (u8)PageNum(tx_desc + ProbeReqLength, page_size);
6261
6262 *page_num += CurtPktPageNum;
6263
6264 index += (CurtPktPageNum * page_size);
6265 }
6266
6267 /* PNO INFO Page */
6268 rsvd_page_loc->LocPNOInfo = *page_num;
6269 RTW_INFO("LocPNOInfo: %d\n", rsvd_page_loc->LocPNOInfo);
6270 rtw_hal_construct_PNO_info(adapter,
6271 &pframe[index - tx_desc],
6272 &PNOLength);
6273
6274 CurtPktPageNum = (u8)PageNum(PNOLength, page_size);
6275 *page_num += CurtPktPageNum;
6276 index += (CurtPktPageNum * page_size);
6277
6278 /* Scan Info Page */
6279 rsvd_page_loc->LocScanInfo = *page_num;
6280 RTW_INFO("LocScanInfo: %d\n", rsvd_page_loc->LocScanInfo);
6281 rtw_hal_construct_scan_info(adapter,
6282 &pframe[index - tx_desc],
6283 &ScanInfoLength);
6284
6285 CurtPktPageNum = (u8)PageNum(ScanInfoLength, page_size);
6286 *page_num += CurtPktPageNum;
6287 *total_pkt_len = index + ScanInfoLength;
6288 index += (CurtPktPageNum * page_size);
6289
6290 }
6291 #endif /* CONFIG_PNO_SUPPORT */
6292 }
6293 }
6294
rtw_hal_gate_bb(_adapter * adapter,bool stop)6295 static void rtw_hal_gate_bb(_adapter *adapter, bool stop)
6296 {
6297 struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(adapter);
6298 u8 val8 = 0;
6299 u16 val16 = 0;
6300
6301 if (stop) {
6302 /* Pause TX*/
6303 pwrpriv->wowlan_txpause_status = rtw_read8(adapter, REG_TXPAUSE);
6304 rtw_write8(adapter, REG_TXPAUSE, 0xff);
6305 val8 = rtw_read8(adapter, REG_SYS_FUNC_EN);
6306 val8 &= ~BIT(0);
6307 rtw_write8(adapter, REG_SYS_FUNC_EN, val8);
6308 RTW_INFO("%s: BB gated: 0x%02x, store TXPAUSE: %02x\n",
6309 __func__,
6310 rtw_read8(adapter, REG_SYS_FUNC_EN),
6311 pwrpriv->wowlan_txpause_status);
6312 } else {
6313 val8 = rtw_read8(adapter, REG_SYS_FUNC_EN);
6314 val8 |= BIT(0);
6315 rtw_write8(adapter, REG_SYS_FUNC_EN, val8);
6316 RTW_INFO("%s: BB release: 0x%02x, recover TXPAUSE:%02x\n",
6317 __func__, rtw_read8(adapter, REG_SYS_FUNC_EN),
6318 pwrpriv->wowlan_txpause_status);
6319 /* release TX*/
6320 rtw_write8(adapter, REG_TXPAUSE, pwrpriv->wowlan_txpause_status);
6321 }
6322 }
6323
rtw_hal_reset_mac_rx(_adapter * adapter)6324 static void rtw_hal_reset_mac_rx(_adapter *adapter)
6325 {
6326 u8 val8 = 0;
6327 /* Set REG_CR bit1, bit3, bit7 to 0*/
6328 val8 = rtw_read8(adapter, REG_CR);
6329 val8 &= 0x75;
6330 rtw_write8(adapter, REG_CR, val8);
6331 val8 = rtw_read8(adapter, REG_CR);
6332 /* Set REG_CR bit1, bit3, bit7 to 1*/
6333 val8 |= 0x8a;
6334 rtw_write8(adapter, REG_CR, val8);
6335 RTW_INFO("0x%04x: %02x\n", REG_CR, rtw_read8(adapter, REG_CR));
6336 }
6337
rtw_hal_set_wow_rxff_boundary(_adapter * adapter,bool wow_mode)6338 static void rtw_hal_set_wow_rxff_boundary(_adapter *adapter, bool wow_mode)
6339 {
6340 u8 val8 = 0;
6341 u16 rxff_bndy = 0;
6342 u32 rx_dma_buff_sz = 0;
6343
6344 val8 = rtw_read8(adapter, REG_FIFOPAGE + 3);
6345 if (val8 != 0)
6346 RTW_INFO("%s:[%04x]some PKTs in TXPKTBUF\n",
6347 __func__, (REG_FIFOPAGE + 3));
6348
6349 rtw_hal_reset_mac_rx(adapter);
6350
6351 if (wow_mode) {
6352 rtw_hal_get_def_var(adapter, HAL_DEF_RX_DMA_SZ_WOW,
6353 (u8 *)&rx_dma_buff_sz);
6354 rxff_bndy = rx_dma_buff_sz - 1;
6355
6356 rtw_write16(adapter, (REG_TRXFF_BNDY + 2), rxff_bndy);
6357 RTW_INFO("%s: wow mode, 0x%04x: 0x%04x\n", __func__,
6358 REG_TRXFF_BNDY + 2,
6359 rtw_read16(adapter, (REG_TRXFF_BNDY + 2)));
6360 } else {
6361 rtw_hal_get_def_var(adapter, HAL_DEF_RX_DMA_SZ,
6362 (u8 *)&rx_dma_buff_sz);
6363 rxff_bndy = rx_dma_buff_sz - 1;
6364 rtw_write16(adapter, (REG_TRXFF_BNDY + 2), rxff_bndy);
6365 RTW_INFO("%s: normal mode, 0x%04x: 0x%04x\n", __func__,
6366 REG_TRXFF_BNDY + 2,
6367 rtw_read16(adapter, (REG_TRXFF_BNDY + 2)));
6368 }
6369 }
6370
rtw_hal_set_pattern(_adapter * adapter,u8 * pattern,u8 len,u8 * mask,u8 idx)6371 static int rtw_hal_set_pattern(_adapter *adapter, u8 *pattern,
6372 u8 len, u8 *mask, u8 idx)
6373 {
6374 struct pwrctrl_priv *pwrctl = adapter_to_pwrctl(adapter);
6375 struct mlme_ext_priv *pmlmeext = NULL;
6376 struct mlme_ext_info *pmlmeinfo = NULL;
6377 struct rtl_wow_pattern wow_pattern;
6378 u8 mask_hw[MAX_WKFM_SIZE] = {0};
6379 u8 content[MAX_WKFM_PATTERN_SIZE] = {0};
6380 u8 broadcast_addr[6] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
6381 u8 multicast_addr1[2] = {0x33, 0x33};
6382 u8 multicast_addr2[3] = {0x01, 0x00, 0x5e};
6383 u8 res = _FALSE, index = 0, mask_len = 0;
6384 u8 mac_addr[ETH_ALEN] = {0};
6385 u16 count = 0;
6386 int i, j;
6387
6388 if (pwrctl->wowlan_pattern_idx > MAX_WKFM_NUM) {
6389 RTW_INFO("%s pattern_idx is more than MAX_FMC_NUM: %d\n",
6390 __func__, MAX_WKFM_NUM);
6391 return _FALSE;
6392 }
6393
6394 pmlmeext = &adapter->mlmeextpriv;
6395 pmlmeinfo = &pmlmeext->mlmext_info;
6396 _rtw_memcpy(mac_addr, adapter_mac_addr(adapter), ETH_ALEN);
6397 _rtw_memset(&wow_pattern, 0, sizeof(struct rtl_wow_pattern));
6398
6399 mask_len = DIV_ROUND_UP(len, 8);
6400
6401 /* 1. setup A1 table */
6402 if (memcmp(pattern, broadcast_addr, ETH_ALEN) == 0)
6403 wow_pattern.type = PATTERN_BROADCAST;
6404 else if (memcmp(pattern, multicast_addr1, 2) == 0)
6405 wow_pattern.type = PATTERN_MULTICAST;
6406 else if (memcmp(pattern, multicast_addr2, 3) == 0)
6407 wow_pattern.type = PATTERN_MULTICAST;
6408 else if (memcmp(pattern, mac_addr, ETH_ALEN) == 0)
6409 wow_pattern.type = PATTERN_UNICAST;
6410 else
6411 wow_pattern.type = PATTERN_INVALID;
6412
6413 /* translate mask from os to mask for hw */
6414
6415 /******************************************************************************
6416 * pattern from OS uses 'ethenet frame', like this:
6417
6418 | 6 | 6 | 2 | 20 | Variable | 4 |
6419 |--------+--------+------+-----------+------------+-----|
6420 | 802.3 Mac Header | IP Header | TCP Packet | FCS |
6421 | DA | SA | Type |
6422
6423 * BUT, packet catched by our HW is in '802.11 frame', begin from LLC,
6424
6425 | 24 or 30 | 6 | 2 | 20 | Variable | 4 |
6426 |-------------------+--------+------+-----------+------------+-----|
6427 | 802.11 MAC Header | LLC | IP Header | TCP Packet | FCS |
6428 | Others | Tpye |
6429
6430 * Therefore, we need translate mask_from_OS to mask_to_hw.
6431 * We should left-shift mask by 6 bits, then set the new bit[0~5] = 0,
6432 * because new mask[0~5] means 'SA', but our HW packet begins from LLC,
6433 * bit[0~5] corresponds to first 6 Bytes in LLC, they just don't match.
6434 ******************************************************************************/
6435 /* Shift 6 bits */
6436 for (i = 0; i < mask_len - 1; i++) {
6437 mask_hw[i] = mask[i] >> 6;
6438 mask_hw[i] |= (mask[i + 1] & 0x3F) << 2;
6439 }
6440
6441 mask_hw[i] = (mask[i] >> 6) & 0x3F;
6442 /* Set bit 0-5 to zero */
6443 mask_hw[0] &= 0xC0;
6444
6445 for (i = 0; i < (MAX_WKFM_SIZE / 4); i++) {
6446 wow_pattern.mask[i] = mask_hw[i * 4];
6447 wow_pattern.mask[i] |= (mask_hw[i * 4 + 1] << 8);
6448 wow_pattern.mask[i] |= (mask_hw[i * 4 + 2] << 16);
6449 wow_pattern.mask[i] |= (mask_hw[i * 4 + 3] << 24);
6450 }
6451
6452 /* To get the wake up pattern from the mask.
6453 * We do not count first 12 bits which means
6454 * DA[6] and SA[6] in the pattern to match HW design. */
6455 count = 0;
6456 for (i = 12; i < len; i++) {
6457 if ((mask[i / 8] >> (i % 8)) & 0x01) {
6458 content[count] = pattern[i];
6459 count++;
6460 }
6461 }
6462
6463 wow_pattern.crc = rtw_calc_crc(content, count);
6464
6465 if (wow_pattern.crc != 0) {
6466 if (wow_pattern.type == PATTERN_INVALID)
6467 wow_pattern.type = PATTERN_VALID;
6468 }
6469
6470 index = idx;
6471
6472 if (!pwrctl->bInSuspend)
6473 index += 2;
6474
6475 /* write pattern */
6476 res = rtw_write_to_frame_mask(adapter, index, &wow_pattern);
6477
6478 if (res == _FALSE)
6479 RTW_INFO("%s: ERROR!! idx: %d write_to_frame_mask_cam fail\n",
6480 __func__, idx);
6481
6482 return res;
6483 }
6484
rtw_hal_dl_pattern(_adapter * adapter,u8 mode)6485 static void rtw_hal_dl_pattern(_adapter *adapter, u8 mode)
6486 {
6487 struct registry_priv *pregistrypriv = &adapter->registrypriv;
6488 struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(adapter);
6489 int i = 0, total = 0;
6490
6491 total = pwrpriv->wowlan_pattern_idx;
6492
6493 if (total > MAX_WKFM_NUM)
6494 total = MAX_WKFM_NUM;
6495
6496 rtw_clean_pattern(adapter);
6497
6498 switch (mode) {
6499 case 0:
6500 RTW_INFO("%s: total patterns: %d\n", __func__, total);
6501 break;
6502 case 1:
6503 rtw_set_default_pattern(adapter);
6504 for (i = 0 ; i < total ; i++) {
6505 rtw_hal_set_pattern(adapter,
6506 pwrpriv->patterns[i].content,
6507 pwrpriv->patterns[i].len,
6508 pwrpriv->patterns[i].mask, i);
6509 }
6510 rtw_write8(adapter, REG_WKFMCAM_NUM, total);
6511 RTW_INFO("%s: pattern total: %d downloaded\n",
6512 __func__, total);
6513 break;
6514 case 2:
6515 pwrpriv->wowlan_pattern_idx = DEFAULT_PATTERN_NUM;
6516
6517 for (i = DEFAULT_PATTERN_NUM ; i < MAX_WKFM_NUM ; i++) {
6518 _rtw_memset(pwrpriv->patterns[i].content, '\0',
6519 sizeof(pwrpriv->patterns[i].content));
6520 _rtw_memset(pwrpriv->patterns[i].mask, '\0',
6521 sizeof(pwrpriv->patterns[i].mask));
6522 pwrpriv->patterns[i].len = 0;
6523 }
6524 RTW_INFO("%s: clean patterns\n", __func__);
6525 break;
6526 default:
6527 RTW_INFO("%s: unknown mode\n", __func__);
6528 break;
6529 }
6530 }
6531
rtw_hal_wow_enable(_adapter * adapter)6532 static void rtw_hal_wow_enable(_adapter *adapter)
6533 {
6534 struct pwrctrl_priv *pwrctl = adapter_to_pwrctl(adapter);
6535 struct security_priv *psecuritypriv = &adapter->securitypriv;
6536 struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
6537 struct hal_ops *pHalFunc = &adapter->HalFunc;
6538 struct sta_info *psta = NULL;
6539 int res;
6540 u16 media_status_rpt;
6541
6542
6543 RTW_PRINT("%s, WOWLAN_ENABLE\n", __func__);
6544 rtw_hal_gate_bb(adapter, _TRUE);
6545 #ifdef CONFIG_GTK_OL
6546 if (psecuritypriv->dot11PrivacyAlgrthm == _AES_ &&
6547 psecuritypriv->dot118021XGrpPrivacy == _AES_)
6548 rtw_hal_fw_sync_cam_id(adapter);
6549 #endif
6550 if (IS_HARDWARE_TYPE_8723B(adapter))
6551 rtw_hal_backup_rate(adapter);
6552
6553 /* RX DMA stop */
6554 if (IS_HARDWARE_TYPE_8188E(adapter))
6555 rtw_hal_disable_tx_report(adapter);
6556
6557 res = rtw_hal_pause_rx_dma(adapter);
6558 if (res == _FAIL)
6559 RTW_PRINT("[WARNING] pause RX DMA fail\n");
6560
6561 /* Reconfig RX_FF Boundary */
6562 rtw_hal_set_wow_rxff_boundary(adapter, _TRUE);
6563
6564 /* redownload wow pattern */
6565 rtw_hal_dl_pattern(adapter, 1);
6566
6567 rtw_hal_fw_dl(adapter, _TRUE);
6568 media_status_rpt = RT_MEDIA_CONNECT;
6569 rtw_hal_set_hwreg(adapter, HW_VAR_H2C_FW_JOINBSSRPT,
6570 (u8 *)&media_status_rpt);
6571
6572 if (!pwrctl->wowlan_pno_enable) {
6573 psta = rtw_get_stainfo(&adapter->stapriv, get_bssid(pmlmepriv));
6574 if (psta != NULL)
6575 rtw_sta_media_status_rpt(adapter, psta, 1);
6576 }
6577
6578 #if defined(CONFIG_SDIO_HCI) || defined(CONFIG_GSPI_HCI)
6579 /* Enable CPWM2 only. */
6580 res = rtw_hal_enable_cpwm2(adapter);
6581 if (res == _FAIL)
6582 RTW_PRINT("[WARNING] enable cpwm2 fail\n");
6583 #endif
6584 #ifdef CONFIG_GPIO_WAKEUP
6585 rtw_hal_switch_gpio_wl_ctrl(adapter, WAKEUP_GPIO_IDX, _TRUE);
6586 #endif
6587 /* Set WOWLAN H2C command. */
6588 RTW_PRINT("Set WOWLan cmd\n");
6589 rtw_hal_set_fw_wow_related_cmd(adapter, 1);
6590
6591 res = rtw_hal_check_wow_ctrl(adapter, _TRUE);
6592
6593 if (res == _FALSE)
6594 RTW_INFO("[Error]%s: set wowlan CMD fail!!\n", __func__);
6595
6596 pwrctl->wowlan_wake_reason =
6597 rtw_read8(adapter, REG_WOWLAN_WAKE_REASON);
6598
6599 RTW_PRINT("wowlan_wake_reason: 0x%02x\n",
6600 pwrctl->wowlan_wake_reason);
6601 #ifdef CONFIG_GTK_OL_DBG
6602 dump_sec_cam(RTW_DBGDUMP, adapter);
6603 dump_sec_cam_cache(RTW_DBGDUMP, adapter);
6604 #endif
6605 #ifdef CONFIG_USB_HCI
6606 /* free adapter's resource */
6607 rtw_mi_intf_stop(adapter);
6608
6609 /* Invoid SE0 reset signal during suspending*/
6610 rtw_write8(adapter, REG_RSV_CTRL, 0x20);
6611 rtw_write8(adapter, REG_RSV_CTRL, 0x60);
6612 #endif /*CONFIG_USB_HCI*/
6613
6614 rtw_hal_gate_bb(adapter, _FALSE);
6615 }
6616
rtw_hal_wow_disable(_adapter * adapter)6617 static void rtw_hal_wow_disable(_adapter *adapter)
6618 {
6619 struct pwrctrl_priv *pwrctl = adapter_to_pwrctl(adapter);
6620 struct security_priv *psecuritypriv = &adapter->securitypriv;
6621 struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
6622 struct hal_ops *pHalFunc = &adapter->HalFunc;
6623 struct sta_info *psta = NULL;
6624 int res;
6625 u16 media_status_rpt;
6626 u8 val8;
6627
6628 RTW_PRINT("%s, WOWLAN_DISABLE\n", __func__);
6629
6630 if (!pwrctl->wowlan_pno_enable) {
6631 psta = rtw_get_stainfo(&adapter->stapriv, get_bssid(pmlmepriv));
6632 if (psta != NULL)
6633 rtw_sta_media_status_rpt(adapter, psta, 0);
6634 else
6635 RTW_INFO("%s: psta is null\n", __func__);
6636 }
6637
6638 if (0) {
6639 RTW_INFO("0x630:0x%02x\n", rtw_read8(adapter, 0x630));
6640 RTW_INFO("0x631:0x%02x\n", rtw_read8(adapter, 0x631));
6641 }
6642
6643 pwrctl->wowlan_wake_reason = rtw_read8(adapter, REG_WOWLAN_WAKE_REASON);
6644
6645 RTW_PRINT("wakeup_reason: 0x%02x\n",
6646 pwrctl->wowlan_wake_reason);
6647
6648 rtw_hal_set_fw_wow_related_cmd(adapter, 0);
6649
6650 res = rtw_hal_check_wow_ctrl(adapter, _FALSE);
6651
6652 if (res == _FALSE) {
6653 RTW_INFO("[Error]%s: disable WOW cmd fail\n!!", __func__);
6654 rtw_hal_force_enable_rxdma(adapter);
6655 }
6656
6657 rtw_hal_gate_bb(adapter, _TRUE);
6658
6659 res = rtw_hal_pause_rx_dma(adapter);
6660 if (res == _FAIL)
6661 RTW_PRINT("[WARNING] pause RX DMA fail\n");
6662
6663 /* clean HW pattern match */
6664 rtw_hal_dl_pattern(adapter, 0);
6665
6666 /* config RXFF boundary to original */
6667 rtw_hal_set_wow_rxff_boundary(adapter, _FALSE);
6668
6669 rtw_hal_release_rx_dma(adapter);
6670
6671 if (IS_HARDWARE_TYPE_8188E(adapter))
6672 rtw_hal_enable_tx_report(adapter);
6673
6674 rtw_hal_update_tx_iv(adapter);
6675
6676 #ifdef CONFIG_GTK_OL
6677 if (psecuritypriv->dot11PrivacyAlgrthm == _AES_ &&
6678 psecuritypriv->dot118021XGrpPrivacy == _AES_)
6679 rtw_hal_update_gtk_offload_info(adapter);
6680 #endif /*CONFIG_GTK_OL*/
6681
6682 rtw_hal_fw_dl(adapter, _FALSE);
6683
6684 #ifdef CONFIG_GPIO_WAKEUP
6685 val8 = (pwrctl->is_high_active == 0) ? 1 : 0;
6686 RTW_PRINT("Set Wake GPIO to default(%d).\n", val8);
6687 rtw_hal_set_output_gpio(adapter, WAKEUP_GPIO_IDX, val8);
6688 #endif
6689
6690 if ((pwrctl->wowlan_wake_reason != FWDecisionDisconnect) &&
6691 (pwrctl->wowlan_wake_reason != Rx_Pairwisekey) &&
6692 (pwrctl->wowlan_wake_reason != Rx_DisAssoc) &&
6693 (pwrctl->wowlan_wake_reason != Rx_DeAuth)) {
6694
6695 media_status_rpt = RT_MEDIA_CONNECT;
6696 rtw_hal_set_hwreg(adapter, HW_VAR_H2C_FW_JOINBSSRPT,
6697 (u8 *)&media_status_rpt);
6698
6699 if (psta != NULL)
6700 rtw_sta_media_status_rpt(adapter, psta, 1);
6701 }
6702 rtw_hal_gate_bb(adapter, _FALSE);
6703 }
6704 #endif /*CONFIG_WOWLAN*/
6705
6706 #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)6707 void rtw_hal_set_p2p_wow_fw_rsvd_page(_adapter *adapter, u8 *pframe, u16 index,
6708 u8 tx_desc, u32 page_size, u8 *page_num, u32 *total_pkt_len,
6709 RSVDPAGE_LOC *rsvd_page_loc)
6710 {
6711 u32 P2PNegoRspLength = 0, P2PInviteRspLength = 0;
6712 u32 P2PPDRspLength = 0, P2PProbeRspLength = 0, P2PBCNLength = 0;
6713 u8 CurtPktPageNum = 0;
6714
6715 /* P2P Beacon */
6716 rsvd_page_loc->LocP2PBeacon = *page_num;
6717 rtw_hal_construct_P2PBeacon(adapter, &pframe[index], &P2PBCNLength);
6718 rtw_hal_fill_fake_txdesc(adapter, &pframe[index - tx_desc],
6719 P2PBCNLength, _FALSE, _FALSE, _FALSE);
6720
6721 #if 0
6722 RTW_INFO("%s(): HW_VAR_SET_TX_CMD: PROBE RSP %p %d\n",
6723 __FUNCTION__, &pframe[index - tx_desc], (P2PBCNLength + tx_desc));
6724 #endif
6725
6726 CurtPktPageNum = (u8)PageNum(tx_desc + P2PBCNLength, page_size);
6727
6728 *page_num += CurtPktPageNum;
6729
6730 index += (CurtPktPageNum * page_size);
6731
6732 /* P2P Probe rsp */
6733 rsvd_page_loc->LocP2PProbeRsp = *page_num;
6734 rtw_hal_construct_P2PProbeRsp(adapter, &pframe[index],
6735 &P2PProbeRspLength);
6736 rtw_hal_fill_fake_txdesc(adapter, &pframe[index - tx_desc],
6737 P2PProbeRspLength, _FALSE, _FALSE, _FALSE);
6738
6739 /* RTW_INFO("%s(): HW_VAR_SET_TX_CMD: PROBE RSP %p %d\n", */
6740 /* __FUNCTION__, &pframe[index-tx_desc], (P2PProbeRspLength+tx_desc)); */
6741
6742 CurtPktPageNum = (u8)PageNum(tx_desc + P2PProbeRspLength, page_size);
6743
6744 *page_num += CurtPktPageNum;
6745
6746 index += (CurtPktPageNum * page_size);
6747
6748 /* P2P nego rsp */
6749 rsvd_page_loc->LocNegoRsp = *page_num;
6750 rtw_hal_construct_P2PNegoRsp(adapter, &pframe[index],
6751 &P2PNegoRspLength);
6752 rtw_hal_fill_fake_txdesc(adapter, &pframe[index - tx_desc],
6753 P2PNegoRspLength, _FALSE, _FALSE, _FALSE);
6754
6755 /* RTW_INFO("%s(): HW_VAR_SET_TX_CMD: QOS NULL DATA %p %d\n", */
6756 /* __FUNCTION__, &pframe[index-tx_desc], (NegoRspLength+tx_desc)); */
6757
6758 CurtPktPageNum = (u8)PageNum(tx_desc + P2PNegoRspLength, page_size);
6759
6760 *page_num += CurtPktPageNum;
6761
6762 index += (CurtPktPageNum * page_size);
6763
6764 /* P2P invite rsp */
6765 rsvd_page_loc->LocInviteRsp = *page_num;
6766 rtw_hal_construct_P2PInviteRsp(adapter, &pframe[index],
6767 &P2PInviteRspLength);
6768 rtw_hal_fill_fake_txdesc(adapter, &pframe[index - tx_desc],
6769 P2PInviteRspLength, _FALSE, _FALSE, _FALSE);
6770
6771 /* RTW_INFO("%s(): HW_VAR_SET_TX_CMD: QOS NULL DATA %p %d\n", */
6772 /* __FUNCTION__, &pframe[index-tx_desc], (InviteRspLength+tx_desc)); */
6773
6774 CurtPktPageNum = (u8)PageNum(tx_desc + P2PInviteRspLength, page_size);
6775
6776 *page_num += CurtPktPageNum;
6777
6778 index += (CurtPktPageNum * page_size);
6779
6780 /* P2P provision discovery rsp */
6781 rsvd_page_loc->LocPDRsp = *page_num;
6782 rtw_hal_construct_P2PProvisionDisRsp(adapter,
6783 &pframe[index], &P2PPDRspLength);
6784
6785 rtw_hal_fill_fake_txdesc(adapter, &pframe[index - tx_desc],
6786 P2PPDRspLength, _FALSE, _FALSE, _FALSE);
6787
6788 /* RTW_INFO("%s(): HW_VAR_SET_TX_CMD: QOS NULL DATA %p %d\n", */
6789 /* __FUNCTION__, &pframe[index-tx_desc], (PDRspLength+tx_desc)); */
6790
6791 CurtPktPageNum = (u8)PageNum(tx_desc + P2PPDRspLength, page_size);
6792
6793 *page_num += CurtPktPageNum;
6794
6795 *total_pkt_len = index + P2PPDRspLength;
6796
6797 index += (CurtPktPageNum * page_size);
6798
6799
6800 }
6801 #endif /* CONFIG_P2P_WOWLAN */
6802
6803 #ifdef CONFIG_LPS_PG
6804 #define LPSPG_RSVD_PAGE_SET_MACID(_rsvd_pag, _value) SET_BITS_TO_LE_4BYTE(_rsvd_pag+0x00, 0, 8, _value)/*used macid*/
6805 #define LPSPG_RSVD_PAGE_SET_MBSSCAMID(_rsvd_pag, _value) SET_BITS_TO_LE_4BYTE(_rsvd_pag+0x00, 8, 8, _value)/*used BSSID CAM entry*/
6806 #define LPSPG_RSVD_PAGE_SET_PMC_NUM(_rsvd_pag, _value) SET_BITS_TO_LE_4BYTE(_rsvd_pag+0x00, 16, 8, _value)/*Max used Pattern Match CAM entry*/
6807 #define LPSPG_RSVD_PAGE_SET_MU_RAID_GID(_rsvd_pag, _value) SET_BITS_TO_LE_4BYTE(_rsvd_pag+0x00, 24, 8, _value)/*Max MU rate table Group ID*/
6808 #define LPSPG_RSVD_PAGE_SET_SEC_CAM_NUM(_rsvd_pag, _value) SET_BITS_TO_LE_4BYTE(_rsvd_pag+0x04, 0, 8, _value)/*used Security CAM entry number*/
6809 #define LPSPG_RSVD_PAGE_SET_SEC_CAM_ID1(_rsvd_pag, _value) SET_BITS_TO_LE_4BYTE(_rsvd_pag+0x08, 0, 8, _value)/*used Security CAM entry -1*/
6810 #define LPSPG_RSVD_PAGE_SET_SEC_CAM_ID2(_rsvd_pag, _value) SET_BITS_TO_LE_4BYTE(_rsvd_pag+0x08, 8, 8, _value)/*used Security CAM entry -2*/
6811 #define LPSPG_RSVD_PAGE_SET_SEC_CAM_ID3(_rsvd_pag, _value) SET_BITS_TO_LE_4BYTE(_rsvd_pag+0x08, 16, 8, _value)/*used Security CAM entry -3*/
6812 #define LPSPG_RSVD_PAGE_SET_SEC_CAM_ID4(_rsvd_pag, _value) SET_BITS_TO_LE_4BYTE(_rsvd_pag+0x08, 24, 8, _value)/*used Security CAM entry -4*/
6813 #define LPSPG_RSVD_PAGE_SET_SEC_CAM_ID5(_rsvd_pag, _value) SET_BITS_TO_LE_4BYTE(_rsvd_pag+0x0C, 0, 8, _value)/*used Security CAM entry -5*/
6814 #define LPSPG_RSVD_PAGE_SET_SEC_CAM_ID6(_rsvd_pag, _value) SET_BITS_TO_LE_4BYTE(_rsvd_pag+0x0C, 8, 8, _value)/*used Security CAM entry -6*/
6815 #define LPSPG_RSVD_PAGE_SET_SEC_CAM_ID7(_rsvd_pag, _value) SET_BITS_TO_LE_4BYTE(_rsvd_pag+0x0C, 16, 8, _value)/*used Security CAM entry -7*/
6816 #define LPSPG_RSVD_PAGE_SET_SEC_CAM_ID8(_rsvd_pag, _value) SET_BITS_TO_LE_4BYTE(_rsvd_pag+0x0C, 24, 8, _value)/*used Security CAM entry -8*/
6817 #endif
6818 #ifdef CONFIG_LPS_PG
6819 #include "hal_halmac.h"
6820
6821 #define DBG_LPSPG_SEC_DUMP
6822 #define LPS_PG_INFO_RSVD_LEN 16
6823
rtw_hal_set_lps_pg_info_rsvd_page(_adapter * adapter)6824 static void rtw_hal_set_lps_pg_info_rsvd_page(_adapter *adapter)
6825 {
6826 u8 cur_pag_num = 0;
6827 struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(adapter);
6828 struct sta_info *psta = rtw_get_stainfo(&adapter->stapriv, get_bssid(&adapter->mlmepriv));
6829 struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
6830 u8 lps_pg_info[LPS_PG_INFO_RSVD_LEN] = {0};
6831 #ifdef CONFIG_MBSSID_CAM
6832 u8 cam_id = INVALID_CAM_ID;
6833 #endif
6834 u8 *psec_cam_id = lps_pg_info + 8;
6835 u8 sec_cam_num = 0;
6836
6837 if (!psta) {
6838 RTW_INFO("%s [ERROR] sta is NULL\n", __func__);
6839 rtw_warn_on(1);
6840 return;
6841 }
6842
6843 LPSPG_RSVD_PAGE_SET_MACID(lps_pg_info, psta->mac_id); /*used macid*/
6844 RTW_INFO("[LPSPG-INFO] mac_id:%d\n", psta->mac_id);
6845
6846 #ifdef CONFIG_MBSSID_CAM
6847 cam_id = rtw_mbid_cam_search_by_ifaceid(adapter, adapter->iface_id);
6848 if (cam_id != INVALID_CAM_ID)
6849 LPSPG_RSVD_PAGE_SET_MBSSCAMID(lps_pg_info, cam_id); /*used BSSID CAM entry*/
6850 RTW_INFO("[LPSPG-INFO] mbss_cam_id:%d\n", cam_id);
6851 #endif
6852
6853 #ifdef CONFIG_WOWLAN /*&& pattern match cam used*/
6854 if (pwrpriv->wowlan_mode == _TRUE &&
6855 check_fwstate(&adapter->mlmepriv, _FW_LINKED) == _TRUE) {
6856 LPSPG_RSVD_PAGE_SET_PMC_NUM(lps_pg_info, pwrpriv->wowlan_pattern_idx); /*Max used Pattern Match CAM entry*/
6857 RTW_INFO("[LPSPG-INFO] Max Pattern Match CAM entry :%d\n", _value);
6858 }
6859 #endif
6860 #ifdef CONFIG_BEAMFORMING /*&& MU BF*/
6861 LPSPG_RSVD_PAGE_SET_MU_RAID_GID(lps_pg_info, _value); /*Max MU rate table Group ID*/
6862 RTW_INFO("[LPSPG-INFO] Max MU rate table Group ID :%d\n", _value);
6863 #endif
6864
6865 sec_cam_num = rtw_get_sec_camid(adapter, 8, psec_cam_id);
6866 if (sec_cam_num < 8)
6867 LPSPG_RSVD_PAGE_SET_SEC_CAM_NUM(lps_pg_info, sec_cam_num); /*used Security CAM entry number*/
6868 RTW_INFO("[LPSPG-INFO] Security CAM entry number :%d\n", sec_cam_num);
6869
6870 #ifdef DBG_LPSPG_SEC_DUMP
6871 {
6872 int i;
6873
6874 for (i = 0; i < sec_cam_num; i++)
6875 RTW_INFO("%d = sec_cam_id:%d\n", i, psec_cam_id[i]);
6876 }
6877 #endif
6878
6879 #ifdef DBG_LPSPG_INFO_DUMP
6880 RTW_INFO("==== DBG_LPSPG_INFO_RSVD_PAGE_DUMP====\n");
6881 RTW_INFO(" %02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X\n",
6882 *(lps_pg_info), *(lps_pg_info + 1), *(lps_pg_info + 2), *(lps_pg_info + 3),
6883 *(lps_pg_info + 4), *(lps_pg_info + 5), *(lps_pg_info + 6), *(lps_pg_info + 7));
6884 RTW_INFO(" %02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X\n",
6885 *(lps_pg_info + 8), *(lps_pg_info + 9), *(lps_pg_info + 10), *(lps_pg_info + 11),
6886 *(lps_pg_info + 12), *(lps_pg_info + 13), *(lps_pg_info + 14), *(lps_pg_info + 15));
6887 RTW_INFO("==== DBG_LPSPG_INFO_RSVD_PAGE_DUMP====\n");
6888 #endif
6889
6890 rtw_halmac_download_rsvd_page(dvobj, pwrpriv->lpspg_rsvd_page_locate, lps_pg_info, LPS_PG_INFO_RSVD_LEN);
6891
6892 }
6893
6894 #define DBG_LPSPG_INFO_DUMP
rtw_hal_set_lps_pg_info_cmd(_adapter * adapter)6895 static u8 rtw_hal_set_lps_pg_info_cmd(_adapter *adapter)
6896 {
6897 struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(adapter);
6898 struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
6899
6900 u8 lpspg_info[H2C_LPS_PG_INFO_LEN] = {0};
6901 u8 ret = _FAIL;
6902
6903 RTW_INFO("%s: loc_lpspg_info:%d\n", __func__, pwrpriv->lpspg_rsvd_page_locate);
6904
6905 if (_NO_PRIVACY_ != adapter->securitypriv.dot11PrivacyAlgrthm)
6906 SET_H2CCMD_LPSPG_SEC_CAM_EN(lpspg_info, 1); /*SecurityCAM_En*/
6907 #ifdef CONFIG_MBSSID_CAM
6908 SET_H2CCMD_LPSPG_MBID_CAM_EN(lpspg_info, 1); /*BSSIDCAM_En*/
6909 #endif
6910
6911 #ifdef CONFIG_WOWLAN /*&& pattern match cam used*/
6912 if (pwrpriv->wowlan_mode == _TRUE &&
6913 check_fwstate(pmlmepriv, _FW_LINKED) == _TRUE) {
6914
6915 SET_H2CCMD_LPSPG_PMC_CAM_EN(lpspg_info, 1); /*PatternMatchCAM_En*/
6916 }
6917 #endif
6918
6919 #ifdef CONFIG_MACID_SEARCH
6920 SET_H2CCMD_LPSPG_MACID_SEARCH_EN(lpspg_info, 1); /*MACIDSearch_En*/
6921 #endif
6922
6923 #ifdef CONFIG_TX_SC
6924 SET_H2CCMD_LPSPG_TXSC_EN(lpspg_info, 1); /*TXSC_En*/
6925 #endif
6926
6927 #ifdef CONFIG_BEAMFORMING /*&& MU BF*/
6928 SET_H2CCMD_LPSPG_MU_RATE_TB_EN(lpspg_info, 1); /*MURateTable_En*/
6929 #endif
6930
6931 SET_H2CCMD_LPSPG_LOC(lpspg_info, pwrpriv->lpspg_rsvd_page_locate);
6932
6933 #ifdef DBG_LPSPG_INFO_DUMP
6934 RTW_INFO("==== DBG_LPSPG_INFO_CMD_DUMP====\n");
6935 RTW_INFO(" H2C_CMD: 0x%02x, H2C_LEN: %d\n", H2C_LPS_PG_INFO, H2C_LPS_PG_INFO_LEN);
6936 RTW_INFO(" %02X:%02X\n", *(lpspg_info), *(lpspg_info + 1));
6937 RTW_INFO("==== DBG_LPSPG_INFO_CMD_DUMP====\n");
6938 #endif
6939
6940 ret = rtw_hal_fill_h2c_cmd(adapter,
6941 H2C_LPS_PG_INFO,
6942 H2C_LPS_PG_INFO_LEN,
6943 lpspg_info);
6944 return ret;
6945 }
rtw_hal_set_lps_pg_info(_adapter * adapter)6946 u8 rtw_hal_set_lps_pg_info(_adapter *adapter)
6947 {
6948 u8 ret = _FAIL;
6949
6950 rtw_hal_set_lps_pg_info_rsvd_page(adapter);
6951 ret = rtw_hal_set_lps_pg_info_cmd(adapter);
6952 return ret;
6953 }
6954 #endif /*CONFIG_LPS_PG*/
6955
6956 /*
6957 * Description: Fill the reserved packets that FW will use to RSVD page.
6958 * Now we just send 4 types packet to rsvd page.
6959 * (1)Beacon, (2)Ps-poll, (3)Null data, (4)ProbeRsp.
6960 * Input:
6961 * finished - FALSE:At the first time we will send all the packets as a large packet to Hw,
6962 * so we need to set the packet length to total lengh.
6963 * TRUE: At the second time, we should send the first packet (default:beacon)
6964 * to Hw again and set the lengh in descriptor to the real beacon lengh.
6965 * 2009.10.15 by tynli.
6966 *
6967 * Page Size = 128: 8188e, 8723a/b, 8192c/d,
6968 * Page Size = 256: 8192e, 8821a
6969 * Page Size = 512: 8812a
6970 */
6971
rtw_hal_set_fw_rsvd_page(_adapter * adapter,bool finished)6972 void rtw_hal_set_fw_rsvd_page(_adapter *adapter, bool finished)
6973 {
6974 PHAL_DATA_TYPE pHalData;
6975 struct xmit_frame *pcmdframe;
6976 struct pkt_attrib *pattrib;
6977 struct xmit_priv *pxmitpriv;
6978 struct mlme_ext_priv *pmlmeext;
6979 struct mlme_ext_info *pmlmeinfo;
6980 struct pwrctrl_priv *pwrctl;
6981 struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
6982 struct hal_ops *pHalFunc = &adapter->HalFunc;
6983 u32 BeaconLength = 0, ProbeRspLength = 0, PSPollLength = 0;
6984 u32 NullDataLength = 0, QosNullLength = 0, BTQosNullLength = 0;
6985 u32 ProbeReqLength = 0, NullFunctionDataLength = 0;
6986 u8 TxDescLen = TXDESC_SIZE, TxDescOffset = TXDESC_OFFSET;
6987 u8 TotalPageNum = 0 , CurtPktPageNum = 0 , RsvdPageNum = 0;
6988 u8 *ReservedPagePacket;
6989 u16 BufIndex = 0;
6990 u32 TotalPacketLen = 0, MaxRsvdPageBufSize = 0, PageSize = 0;
6991 RSVDPAGE_LOC RsvdPageLoc;
6992
6993 #ifdef DBG_CONFIG_ERROR_DETECT
6994 struct sreset_priv *psrtpriv;
6995 #endif /* DBG_CONFIG_ERROR_DETECT */
6996
6997 #ifdef CONFIG_MCC_MODE
6998 u8 dl_mcc_page = _FAIL;
6999 #endif /* CONFIG_MCC_MODE */
7000
7001 pHalData = GET_HAL_DATA(adapter);
7002 #ifdef DBG_CONFIG_ERROR_DETECT
7003 psrtpriv = &pHalData->srestpriv;
7004 #endif
7005 pxmitpriv = &adapter->xmitpriv;
7006 pmlmeext = &adapter->mlmeextpriv;
7007 pmlmeinfo = &pmlmeext->mlmext_info;
7008 pwrctl = adapter_to_pwrctl(adapter);
7009
7010 rtw_hal_get_def_var(adapter, HAL_DEF_TX_PAGE_SIZE, (u8 *)&PageSize);
7011
7012 if (PageSize == 0) {
7013 RTW_INFO("[Error]: %s, PageSize is zero!!\n", __func__);
7014 return;
7015 }
7016
7017 if (pwrctl->wowlan_mode == _TRUE || pwrctl->wowlan_ap_mode == _TRUE)
7018 RsvdPageNum = rtw_hal_get_txbuff_rsvd_page_num(adapter, _TRUE);
7019 else
7020 RsvdPageNum = rtw_hal_get_txbuff_rsvd_page_num(adapter, _FALSE);
7021
7022 RTW_INFO("%s PageSize: %d, RsvdPageNUm: %d\n", __func__, PageSize, RsvdPageNum);
7023
7024 MaxRsvdPageBufSize = RsvdPageNum * PageSize;
7025
7026 if (MaxRsvdPageBufSize > MAX_CMDBUF_SZ) {
7027 RTW_INFO("%s MaxRsvdPageBufSize(%d) is larger than MAX_CMDBUF_SZ(%d)",
7028 __func__, MaxRsvdPageBufSize, MAX_CMDBUF_SZ);
7029 rtw_warn_on(1);
7030 return;
7031 }
7032
7033 pcmdframe = rtw_alloc_cmdxmitframe(pxmitpriv);
7034
7035 if (pcmdframe == NULL) {
7036 RTW_INFO("%s: alloc ReservedPagePacket fail!\n", __FUNCTION__);
7037 return;
7038 }
7039
7040 ReservedPagePacket = pcmdframe->buf_addr;
7041 _rtw_memset(&RsvdPageLoc, 0, sizeof(RSVDPAGE_LOC));
7042
7043 /* beacon * 2 pages */
7044 BufIndex = TxDescOffset;
7045 rtw_hal_construct_beacon(adapter,
7046 &ReservedPagePacket[BufIndex], &BeaconLength);
7047
7048 /*
7049 * When we count the first page size, we need to reserve description size for the RSVD
7050 * packet, it will be filled in front of the packet in TXPKTBUF.
7051 */
7052 CurtPktPageNum = (u8)PageNum((TxDescLen + BeaconLength), PageSize);
7053 /* If we don't add 1 more page, ARP offload function will fail at 8723bs.*/
7054 if (CurtPktPageNum == 1)
7055 CurtPktPageNum += 1;
7056
7057 TotalPageNum += CurtPktPageNum;
7058
7059 BufIndex += (CurtPktPageNum * PageSize);
7060
7061 if (pwrctl->wowlan_ap_mode == _TRUE) {
7062 /* (4) probe response*/
7063 RsvdPageLoc.LocProbeRsp = TotalPageNum;
7064 rtw_hal_construct_ProbeRsp(
7065 adapter, &ReservedPagePacket[BufIndex],
7066 &ProbeRspLength,
7067 get_my_bssid(&pmlmeinfo->network), _FALSE);
7068 rtw_hal_fill_fake_txdesc(adapter,
7069 &ReservedPagePacket[BufIndex - TxDescLen],
7070 ProbeRspLength, _FALSE, _FALSE, _FALSE);
7071
7072 CurtPktPageNum = (u8)PageNum(TxDescLen + ProbeRspLength, PageSize);
7073 TotalPageNum += CurtPktPageNum;
7074 TotalPacketLen = BufIndex + ProbeRspLength;
7075 BufIndex += (CurtPktPageNum * PageSize);
7076 goto download_page;
7077 }
7078
7079 /* ps-poll * 1 page */
7080 RsvdPageLoc.LocPsPoll = TotalPageNum;
7081 RTW_INFO("LocPsPoll: %d\n", RsvdPageLoc.LocPsPoll);
7082 rtw_hal_construct_PSPoll(adapter,
7083 &ReservedPagePacket[BufIndex], &PSPollLength);
7084 rtw_hal_fill_fake_txdesc(adapter,
7085 &ReservedPagePacket[BufIndex - TxDescLen],
7086 PSPollLength, _TRUE, _FALSE, _FALSE);
7087
7088 CurtPktPageNum = (u8)PageNum((TxDescLen + PSPollLength), PageSize);
7089
7090 TotalPageNum += CurtPktPageNum;
7091
7092 BufIndex += (CurtPktPageNum * PageSize);
7093
7094 #ifdef CONFIG_BT_COEXIST
7095 /* BT Qos null data * 1 page */
7096 RsvdPageLoc.LocBTQosNull = TotalPageNum;
7097 RTW_INFO("LocBTQosNull: %d\n", RsvdPageLoc.LocBTQosNull);
7098 rtw_hal_construct_NullFunctionData(
7099 adapter,
7100 &ReservedPagePacket[BufIndex],
7101 &BTQosNullLength,
7102 get_my_bssid(&pmlmeinfo->network),
7103 _TRUE, 0, 0, _FALSE);
7104 rtw_hal_fill_fake_txdesc(adapter,
7105 &ReservedPagePacket[BufIndex - TxDescLen],
7106 BTQosNullLength, _FALSE, _TRUE, _FALSE);
7107
7108 CurtPktPageNum = (u8)PageNum(TxDescLen + BTQosNullLength, PageSize);
7109
7110 TotalPageNum += CurtPktPageNum;
7111
7112 BufIndex += (CurtPktPageNum * PageSize);
7113 #endif /* CONFIG_BT_COEXIT */
7114
7115 #ifdef CONFIG_MCC_MODE
7116 if (MCC_EN(adapter)) {
7117 dl_mcc_page = rtw_hal_dl_mcc_fw_rsvd_page(adapter, ReservedPagePacket,
7118 &BufIndex, TxDescLen, PageSize,
7119 &TotalPageNum, &TotalPacketLen, &RsvdPageLoc);
7120 } else
7121 dl_mcc_page = _FAIL;
7122
7123 if (dl_mcc_page == _FAIL) {
7124 #endif /* CONFIG_MCC_MODE */
7125
7126 /* null data * 1 page */
7127 RsvdPageLoc.LocNullData = TotalPageNum;
7128 RTW_INFO("LocNullData: %d\n", RsvdPageLoc.LocNullData);
7129 rtw_hal_construct_NullFunctionData(
7130 adapter,
7131 &ReservedPagePacket[BufIndex],
7132 &NullDataLength,
7133 get_my_bssid(&pmlmeinfo->network),
7134 _FALSE, 0, 0, _FALSE);
7135 rtw_hal_fill_fake_txdesc(adapter,
7136 &ReservedPagePacket[BufIndex - TxDescLen],
7137 NullDataLength, _FALSE, _FALSE, _FALSE);
7138
7139 CurtPktPageNum = (u8)PageNum(TxDescLen + NullDataLength, PageSize);
7140
7141 TotalPageNum += CurtPktPageNum;
7142
7143 BufIndex += (CurtPktPageNum * PageSize);
7144 #ifdef CONFIG_MCC_MODE
7145 }
7146 #endif /* CONFIG_MCC_MODE */
7147
7148 /* Qos null data * 1 page */
7149 RsvdPageLoc.LocQosNull = TotalPageNum;
7150 RTW_INFO("LocQosNull: %d\n", RsvdPageLoc.LocQosNull);
7151 rtw_hal_construct_NullFunctionData(
7152 adapter,
7153 &ReservedPagePacket[BufIndex],
7154 &QosNullLength,
7155 get_my_bssid(&pmlmeinfo->network),
7156 _TRUE, 0, 0, _FALSE);
7157 rtw_hal_fill_fake_txdesc(adapter,
7158 &ReservedPagePacket[BufIndex - TxDescLen],
7159 QosNullLength, _FALSE, _FALSE, _FALSE);
7160
7161 CurtPktPageNum = (u8)PageNum(TxDescLen + QosNullLength, PageSize);
7162
7163 TotalPageNum += CurtPktPageNum;
7164
7165 TotalPacketLen = BufIndex + QosNullLength;
7166
7167 BufIndex += (CurtPktPageNum * PageSize);
7168
7169 #ifdef CONFIG_WOWLAN
7170 if (pwrctl->wowlan_mode == _TRUE) {
7171 rtw_hal_set_wow_fw_rsvd_page(adapter, ReservedPagePacket,
7172 BufIndex, TxDescLen, PageSize,
7173 &TotalPageNum, &TotalPacketLen, &RsvdPageLoc);
7174 }
7175 #endif /* CONFIG_WOWLAN */
7176
7177 #ifdef CONFIG_P2P_WOWLAN
7178 if (_TRUE == pwrctl->wowlan_p2p_mode) {
7179 rtw_hal_set_p2p_wow_fw_rsvd_page(adapter, ReservedPagePacket,
7180 BufIndex, TxDescLen, PageSize,
7181 &TotalPageNum, &TotalPacketLen, &RsvdPageLoc);
7182 }
7183 #endif /* CONFIG_P2P_WOWLAN */
7184
7185 #ifdef CONFIG_LPS_PG
7186 /* must reserved last 1 x page for LPS PG Info*/
7187 pwrctl->lpspg_rsvd_page_locate = TotalPageNum;
7188 #endif
7189
7190 download_page:
7191 /* RTW_INFO("%s BufIndex(%d), TxDescLen(%d), PageSize(%d)\n",__func__, BufIndex, TxDescLen, PageSize);*/
7192 RTW_INFO("%s PageNum(%d), pktlen(%d)\n",
7193 __func__, TotalPageNum, TotalPacketLen);
7194
7195 if (TotalPacketLen > MaxRsvdPageBufSize) {
7196 RTW_INFO("%s(ERROR): rsvd page size is not enough!!TotalPacketLen %d, MaxRsvdPageBufSize %d\n",
7197 __FUNCTION__, TotalPacketLen, MaxRsvdPageBufSize);
7198 rtw_warn_on(1);
7199 goto error;
7200 } else {
7201 /* update attribute */
7202 pattrib = &pcmdframe->attrib;
7203 update_mgntframe_attrib(adapter, pattrib);
7204 pattrib->qsel = QSLT_BEACON;
7205 pattrib->pktlen = TotalPacketLen - TxDescOffset;
7206 pattrib->last_txcmdsz = TotalPacketLen - TxDescOffset;
7207 #ifdef CONFIG_PCI_HCI
7208 dump_mgntframe(adapter, pcmdframe);
7209 #else
7210 dump_mgntframe_and_wait(adapter, pcmdframe, 100);
7211 #endif
7212 }
7213
7214 RTW_INFO("%s: Set RSVD page location to Fw ,TotalPacketLen(%d), TotalPageNum(%d)\n",
7215 __func__, TotalPacketLen, TotalPageNum);
7216
7217 if (check_fwstate(pmlmepriv, _FW_LINKED) == _TRUE) {
7218 rtw_hal_set_FwRsvdPage_cmd(adapter, &RsvdPageLoc);
7219 if (pwrctl->wowlan_mode == _TRUE)
7220 rtw_hal_set_FwAoacRsvdPage_cmd(adapter, &RsvdPageLoc);
7221 #ifdef CONFIG_AP_WOWLAN
7222 if (pwrctl->wowlan_ap_mode == _TRUE)
7223 rtw_hal_set_ap_rsvdpage_loc_cmd(adapter, &RsvdPageLoc);
7224 #endif /* CONFIG_AP_WOWLAN */
7225 } else if (pwrctl->wowlan_pno_enable) {
7226 #ifdef CONFIG_PNO_SUPPORT
7227 rtw_hal_set_FwAoacRsvdPage_cmd(adapter, &RsvdPageLoc);
7228 if (pwrctl->pno_in_resume)
7229 rtw_hal_set_scan_offload_info_cmd(adapter,
7230 &RsvdPageLoc, 0);
7231 else
7232 rtw_hal_set_scan_offload_info_cmd(adapter,
7233 &RsvdPageLoc, 1);
7234 #endif /* CONFIG_PNO_SUPPORT */
7235 }
7236 #ifdef CONFIG_P2P_WOWLAN
7237 if (_TRUE == pwrctl->wowlan_p2p_mode)
7238 rtw_hal_set_FwP2PRsvdPage_cmd(adapter, &RsvdPageLoc);
7239 #endif /* CONFIG_P2P_WOWLAN */
7240 return;
7241 error:
7242 rtw_free_xmitframe(pxmitpriv, pcmdframe);
7243 }
rtw_hal_set_hw_update_tsf(PADAPTER padapter)7244 static void rtw_hal_set_hw_update_tsf(PADAPTER padapter)
7245 {
7246 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
7247 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
7248
7249 #if defined(CONFIG_RTL8822B) || defined(CONFIG_MI_WITH_MBSSID_CAM)
7250 RTW_INFO("[Warn] %s "ADPT_FMT" enter func\n", __func__, ADPT_ARG(padapter));
7251 rtw_warn_on(1);
7252 return;
7253 #endif
7254
7255 if (!pmlmeext->en_hw_update_tsf)
7256 return;
7257
7258 /* check REG_RCR bit is set */
7259 if (!(rtw_read32(padapter, REG_RCR) & RCR_CBSSID_BCN))
7260 return;
7261
7262 /* enable hw update tsf function for non-AP */
7263 if (rtw_linked_check(padapter) &&
7264 check_fwstate(pmlmepriv, WIFI_AP_STATE) != _TRUE) {
7265 #ifdef CONFIG_CONCURRENT_MODE
7266 if (padapter->hw_port == HW_PORT1)
7267 rtw_write8(padapter, REG_BCN_CTRL_1, rtw_read8(padapter, REG_BCN_CTRL_1) & (~DIS_TSF_UDT));
7268 else
7269 #endif
7270 rtw_write8(padapter, REG_BCN_CTRL, rtw_read8(padapter, REG_BCN_CTRL) & (~DIS_TSF_UDT));
7271 }
7272 pmlmeext->en_hw_update_tsf = _FALSE;
7273 }
7274
7275 #ifdef CONFIG_TDLS
7276 #ifdef CONFIG_TDLS_CH_SW
rtw_hal_ch_sw_oper_offload(_adapter * padapter,u8 channel,u8 channel_offset,u16 bwmode)7277 s32 rtw_hal_ch_sw_oper_offload(_adapter *padapter, u8 channel, u8 channel_offset, u16 bwmode)
7278 {
7279 PHAL_DATA_TYPE pHalData = GET_HAL_DATA(padapter);
7280 u8 ch_sw_h2c_buf[4] = {0x00, 0x00, 0x00, 0x00};
7281
7282
7283 SET_H2CCMD_CH_SW_OPER_OFFLOAD_CH_NUM(ch_sw_h2c_buf, channel);
7284 SET_H2CCMD_CH_SW_OPER_OFFLOAD_BW_MODE(ch_sw_h2c_buf, bwmode);
7285 switch (bwmode) {
7286 case CHANNEL_WIDTH_40:
7287 SET_H2CCMD_CH_SW_OPER_OFFLOAD_BW_40M_SC(ch_sw_h2c_buf, channel_offset);
7288 break;
7289 case CHANNEL_WIDTH_80:
7290 SET_H2CCMD_CH_SW_OPER_OFFLOAD_BW_80M_SC(ch_sw_h2c_buf, channel_offset);
7291 break;
7292 case CHANNEL_WIDTH_20:
7293 default:
7294 break;
7295 }
7296 SET_H2CCMD_CH_SW_OPER_OFFLOAD_RFE_TYPE(ch_sw_h2c_buf, pHalData->RFEType);
7297
7298 return rtw_hal_fill_h2c_cmd(padapter, H2C_CHNL_SWITCH_OPER_OFFLOAD, sizeof(ch_sw_h2c_buf), ch_sw_h2c_buf);
7299 }
7300 #endif
7301 #endif
7302
7303 #ifdef CONFIG_BT_COEXIST
7304 /* 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)7305 s32 rtw_hal_set_wifi_port_id_cmd(_adapter *adapter)
7306 {
7307 u8 port_id = 0;
7308 u8 h2c_buf[H2C_BTC_WL_PORT_ID_LEN] = {0};
7309
7310 port_id = get_hw_port(adapter);
7311
7312 SET_H2CCMD_BTC_WL_PORT_ID(h2c_buf, port_id);
7313
7314 return rtw_hal_fill_h2c_cmd(adapter, H2C_BTC_WL_PORT_ID, H2C_BTC_WL_PORT_ID_LEN, h2c_buf);
7315 }
7316 #endif
7317
SetHwReg(_adapter * adapter,u8 variable,u8 * val)7318 void SetHwReg(_adapter *adapter, u8 variable, u8 *val)
7319 {
7320 HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
7321 _func_enter_;
7322
7323 switch (variable) {
7324 case HW_VAR_MEDIA_STATUS: {
7325 u8 net_type = *((u8 *)val);
7326
7327 rtw_hal_set_msr(adapter, net_type);
7328 }
7329 break;
7330 case HW_VAR_MAC_ADDR:
7331 #ifdef CONFIG_MI_WITH_MBSSID_CAM
7332 rtw_hal_set_macaddr_mbid(adapter, val);
7333 #else
7334 rtw_hal_set_macaddr_port(adapter, val);
7335 #endif
7336 break;
7337 case HW_VAR_BSSID:
7338 rtw_hal_set_bssid(adapter, val);
7339 break;
7340 #ifdef CONFIG_MBSSID_CAM
7341 case HW_VAR_MBSSID_CAM_WRITE: {
7342 u32 cmd = 0;
7343 u32 *cam_val = (u32 *)val;
7344
7345 rtw_write32(adapter, REG_MBIDCAMCFG_1, cam_val[0]);
7346 cmd = BIT_MBIDCAM_POLL | BIT_MBIDCAM_WT_EN | BIT_MBIDCAM_VALID | cam_val[1];
7347 rtw_write32(adapter, REG_MBIDCAMCFG_2, cmd);
7348 }
7349 break;
7350 case HW_VAR_MBSSID_CAM_CLEAR: {
7351 u32 cmd;
7352 u8 entry_id = *(u8 *)val;
7353
7354 rtw_write32(adapter, REG_MBIDCAMCFG_1, 0);
7355
7356 cmd = BIT_MBIDCAM_POLL | BIT_MBIDCAM_WT_EN | ((entry_id & MBIDCAM_ADDR_MASK) << MBIDCAM_ADDR_SHIFT);
7357 rtw_write32(adapter, REG_MBIDCAMCFG_2, cmd);
7358 }
7359 break;
7360 case HW_VAR_RCR_MBSSID_EN:
7361 if (*((u8 *)val))
7362 rtw_write32(adapter, REG_RCR, rtw_read32(adapter, REG_RCR) | RCR_ENMBID);
7363 else {
7364 u32 val32;
7365
7366 val32 = rtw_read32(adapter, REG_RCR);
7367 val32 &= ~(RCR_ENMBID);
7368 rtw_write32(adapter, REG_RCR, val32);
7369 }
7370 break;
7371 #endif
7372 case HW_VAR_PORT_SWITCH:
7373 hw_var_port_switch(adapter);
7374 break;
7375 case HW_VAR_INIT_RTS_RATE: {
7376 u16 brate_cfg = *((u16 *)val);
7377 u8 rate_index = 0;
7378 HAL_VERSION *hal_ver = &hal_data->VersionID;
7379
7380 if (IS_8188E(*hal_ver)) {
7381
7382 while (brate_cfg > 0x1) {
7383 brate_cfg = (brate_cfg >> 1);
7384 rate_index++;
7385 }
7386 rtw_write8(adapter, REG_INIRTS_RATE_SEL, rate_index);
7387 } else
7388 rtw_warn_on(1);
7389 }
7390 break;
7391 case HW_VAR_SEC_CFG: {
7392 u16 reg_scr_ori;
7393 u16 reg_scr;
7394
7395 reg_scr = reg_scr_ori = rtw_read16(adapter, REG_SECCFG);
7396 reg_scr |= (SCR_CHK_KEYID | SCR_RxDecEnable | SCR_TxEncEnable);
7397
7398 if (_rtw_camctl_chk_cap(adapter, SEC_CAP_CHK_BMC))
7399 reg_scr |= SCR_CHK_BMC;
7400
7401 if (_rtw_camctl_chk_flags(adapter, SEC_STATUS_STA_PK_GK_CONFLICT_DIS_BMC_SEARCH))
7402 reg_scr |= SCR_NoSKMC;
7403
7404 if (reg_scr != reg_scr_ori)
7405 rtw_write16(adapter, REG_SECCFG, reg_scr);
7406 }
7407 break;
7408 case HW_VAR_SEC_DK_CFG: {
7409 struct security_priv *sec = &adapter->securitypriv;
7410 u8 reg_scr = rtw_read8(adapter, REG_SECCFG);
7411
7412 if (val) { /* Enable default key related setting */
7413 reg_scr |= SCR_TXBCUSEDK;
7414 if (sec->dot11AuthAlgrthm != dot11AuthAlgrthm_8021X)
7415 reg_scr |= (SCR_RxUseDK | SCR_TxUseDK);
7416 } else /* Disable default key related setting */
7417 reg_scr &= ~(SCR_RXBCUSEDK | SCR_TXBCUSEDK | SCR_RxUseDK | SCR_TxUseDK);
7418
7419 rtw_write8(adapter, REG_SECCFG, reg_scr);
7420 }
7421 break;
7422
7423 case HW_VAR_ASIX_IOT:
7424 /* enable ASIX IOT function */
7425 if (*((u8 *)val) == _TRUE) {
7426 /* 0xa2e[0]=0 (disable rake receiver) */
7427 rtw_write8(adapter, rCCK0_FalseAlarmReport + 2,
7428 rtw_read8(adapter, rCCK0_FalseAlarmReport + 2) & ~(BIT0));
7429 /* 0xa1c=0xa0 (reset channel estimation if signal quality is bad) */
7430 rtw_write8(adapter, rCCK0_DSPParameter2, 0xa0);
7431 } else {
7432 /* restore reg:0xa2e, reg:0xa1c */
7433 rtw_write8(adapter, rCCK0_FalseAlarmReport + 2,
7434 rtw_read8(adapter, rCCK0_FalseAlarmReport + 2) | (BIT0));
7435 rtw_write8(adapter, rCCK0_DSPParameter2, 0x00);
7436 }
7437 break;
7438 #if defined(CONFIG_WOWLAN) || defined(CONFIG_AP_WOWLAN)
7439 case HW_VAR_WOWLAN: {
7440 struct wowlan_ioctl_param *poidparam;
7441
7442 poidparam = (struct wowlan_ioctl_param *)val;
7443 switch (poidparam->subcode) {
7444 #ifdef CONFIG_WOWLAN
7445 case WOWLAN_PATTERN_CLEAN:
7446 rtw_hal_dl_pattern(adapter, 2);
7447 break;
7448 case WOWLAN_ENABLE:
7449 rtw_hal_wow_enable(adapter);
7450 break;
7451 case WOWLAN_DISABLE:
7452 rtw_hal_wow_disable(adapter);
7453 break;
7454 #endif /*CONFIG_WOWLAN*/
7455 #ifdef CONFIG_AP_WOWLAN
7456 case WOWLAN_AP_ENABLE:
7457 rtw_hal_ap_wow_enable(adapter);
7458 break;
7459 case WOWLAN_AP_DISABLE:
7460 rtw_hal_ap_wow_disable(adapter);
7461 break;
7462 #endif /*CONFIG_AP_WOWLAN*/
7463 default:
7464 break;
7465 }
7466 }
7467 break;
7468 #endif /*defined(CONFIG_WOWLAN) || defined(CONFIG_AP_WOWLAN)*/
7469
7470 case HW_VAR_EN_HW_UPDATE_TSF:
7471 rtw_hal_set_hw_update_tsf(adapter);
7472 break;
7473
7474 default:
7475 if (0)
7476 RTW_PRINT(FUNC_ADPT_FMT" variable(%d) not defined!\n",
7477 FUNC_ADPT_ARG(adapter), variable);
7478 break;
7479 }
7480
7481 _func_exit_;
7482 }
7483
GetHwReg(_adapter * adapter,u8 variable,u8 * val)7484 void GetHwReg(_adapter *adapter, u8 variable, u8 *val)
7485 {
7486 HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
7487
7488 _func_enter_;
7489
7490 switch (variable) {
7491 case HW_VAR_BASIC_RATE:
7492 *((u16 *)val) = hal_data->BasicRateSet;
7493 break;
7494 case HW_VAR_RF_TYPE:
7495 *((u8 *)val) = hal_data->rf_type;
7496 break;
7497 case HW_VAR_MEDIA_STATUS:
7498 rtw_hal_get_msr(adapter, val);
7499 break;
7500 case HW_VAR_DO_IQK:
7501 *val = hal_data->bNeedIQK;
7502 break;
7503 case HW_VAR_CH_SW_NEED_TO_TAKE_CARE_IQK_INFO:
7504 if (hal_is_band_support(adapter, BAND_ON_5G))
7505 *val = _TRUE;
7506 else
7507 *val = _FALSE;
7508
7509 break;
7510 default:
7511 if (0)
7512 RTW_PRINT(FUNC_ADPT_FMT" variable(%d) not defined!\n",
7513 FUNC_ADPT_ARG(adapter), variable);
7514 break;
7515 }
7516
7517 _func_exit_;
7518 }
7519
7520 u8
SetHalDefVar(_adapter * adapter,HAL_DEF_VARIABLE variable,void * value)7521 SetHalDefVar(_adapter *adapter, HAL_DEF_VARIABLE variable, void *value)
7522 {
7523 HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
7524 u8 bResult = _SUCCESS;
7525
7526 switch (variable) {
7527
7528 case HAL_DEF_DBG_DUMP_RXPKT:
7529 hal_data->bDumpRxPkt = *((u8 *)value);
7530 break;
7531 case HAL_DEF_DBG_DUMP_TXPKT:
7532 hal_data->bDumpTxPkt = *((u8 *)value);
7533 break;
7534 case HAL_DEF_ANT_DETECT:
7535 hal_data->AntDetection = *((u8 *)value);
7536 break;
7537 case HAL_DEF_DBG_DIS_PWT:
7538 hal_data->bDisableTXPowerTraining = *((u8 *)value);
7539 break;
7540 default:
7541 RTW_PRINT("%s: [WARNING] HAL_DEF_VARIABLE(%d) not defined!\n", __FUNCTION__, variable);
7542 bResult = _FAIL;
7543 break;
7544 }
7545
7546 return bResult;
7547 }
7548
7549 #ifdef CONFIG_BEAMFORMING
rtw_hal_query_txbfer_rf_num(_adapter * adapter)7550 u8 rtw_hal_query_txbfer_rf_num(_adapter *adapter)
7551 {
7552 struct registry_priv *pregistrypriv = &adapter->registrypriv;
7553 HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
7554
7555 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)))
7556 return pregistrypriv->beamformer_rf_num;
7557 else if (IS_HARDWARE_TYPE_8814AE(adapter)
7558 #if 0
7559 #if defined(CONFIG_USB_HCI)
7560 || (IS_HARDWARE_TYPE_8814AU(adapter) && (pUsbModeMech->CurUsbMode == 2 || pUsbModeMech->HubUsbMode == 2)) /* for USB3.0 */
7561 #endif
7562 #endif
7563 ) {
7564 /*BF cap provided by Yu Chen, Sean, 2015, 01 */
7565 if (hal_data->rf_type == RF_3T3R)
7566 return 2;
7567 else if (hal_data->rf_type == RF_4T4R)
7568 return 3;
7569 else
7570 return 1;
7571 } else
7572 return 1;
7573
7574 }
rtw_hal_query_txbfee_rf_num(_adapter * adapter)7575 u8 rtw_hal_query_txbfee_rf_num(_adapter *adapter)
7576 {
7577 struct registry_priv *pregistrypriv = &adapter->registrypriv;
7578 struct mlme_ext_priv *pmlmeext = &adapter->mlmeextpriv;
7579 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
7580
7581 HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
7582
7583 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)))
7584 return pregistrypriv->beamformee_rf_num;
7585 else if (IS_HARDWARE_TYPE_8814AE(adapter) || IS_HARDWARE_TYPE_8814AU(adapter)) {
7586 if (pmlmeinfo->assoc_AP_vendor == HT_IOT_PEER_BROADCOM)
7587 return 2;
7588 else
7589 return 2;/*TODO: May be 3 in the future, by ChenYu. */
7590 } else
7591 return 1;
7592
7593 }
7594 #endif
7595
7596 u8
GetHalDefVar(_adapter * adapter,HAL_DEF_VARIABLE variable,void * value)7597 GetHalDefVar(_adapter *adapter, HAL_DEF_VARIABLE variable, void *value)
7598 {
7599 HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
7600 u8 bResult = _SUCCESS;
7601
7602 switch (variable) {
7603 case HAL_DEF_UNDERCORATEDSMOOTHEDPWDB: {
7604 struct mlme_priv *pmlmepriv;
7605 struct sta_priv *pstapriv;
7606 struct sta_info *psta;
7607
7608 pmlmepriv = &adapter->mlmepriv;
7609 pstapriv = &adapter->stapriv;
7610 psta = rtw_get_stainfo(pstapriv, pmlmepriv->cur_network.network.MacAddress);
7611 if (psta)
7612 *((int *)value) = psta->rssi_stat.UndecoratedSmoothedPWDB;
7613 }
7614 break;
7615 case HAL_DEF_DBG_DUMP_RXPKT:
7616 *((u8 *)value) = hal_data->bDumpRxPkt;
7617 break;
7618 case HAL_DEF_DBG_DUMP_TXPKT:
7619 *((u8 *)value) = hal_data->bDumpTxPkt;
7620 break;
7621 case HAL_DEF_ANT_DETECT:
7622 *((u8 *)value) = hal_data->AntDetection;
7623 break;
7624 case HAL_DEF_MACID_SLEEP:
7625 *(u8 *)value = _FALSE;
7626 break;
7627 case HAL_DEF_TX_PAGE_SIZE:
7628 *((u32 *)value) = PAGE_SIZE_128;
7629 break;
7630 case HAL_DEF_DBG_DIS_PWT:
7631 *(u8 *)value = hal_data->bDisableTXPowerTraining;
7632 break;
7633 case HAL_DEF_EXPLICIT_BEAMFORMER:
7634 case HAL_DEF_EXPLICIT_BEAMFORMEE:
7635 case HAL_DEF_VHT_MU_BEAMFORMER:
7636 case HAL_DEF_VHT_MU_BEAMFORMEE:
7637 *(u8 *)value = _FALSE;
7638 break;
7639 #ifdef CONFIG_BEAMFORMING
7640 case HAL_DEF_BEAMFORMER_CAP:
7641 *(u8 *)value = rtw_hal_query_txbfer_rf_num(adapter);
7642 break;
7643 case HAL_DEF_BEAMFORMEE_CAP:
7644 *(u8 *)value = rtw_hal_query_txbfee_rf_num(adapter);
7645 break;
7646 #endif
7647 default:
7648 RTW_PRINT("%s: [WARNING] HAL_DEF_VARIABLE(%d) not defined!\n", __FUNCTION__, variable);
7649 bResult = _FAIL;
7650 break;
7651 }
7652
7653 return bResult;
7654 }
7655
SetHalODMVar(PADAPTER Adapter,HAL_ODM_VARIABLE eVariable,PVOID pValue1,BOOLEAN bSet)7656 void SetHalODMVar(
7657 PADAPTER Adapter,
7658 HAL_ODM_VARIABLE eVariable,
7659 PVOID pValue1,
7660 BOOLEAN bSet)
7661 {
7662 HAL_DATA_TYPE *pHalData = GET_HAL_DATA(Adapter);
7663 PDM_ODM_T podmpriv = &pHalData->odmpriv;
7664 /* _irqL irqL; */
7665 switch (eVariable) {
7666 case HAL_ODM_STA_INFO: {
7667 struct sta_info *psta = (struct sta_info *)pValue1;
7668 if (bSet) {
7669 RTW_INFO("### Set STA_(%d) info ###\n", psta->mac_id);
7670 ODM_CmnInfoPtrArrayHook(podmpriv, ODM_CMNINFO_STA_STATUS, psta->mac_id, psta);
7671 } else {
7672 RTW_INFO("### Clean STA_(%d) info ###\n", psta->mac_id);
7673 /* _enter_critical_bh(&pHalData->odm_stainfo_lock, &irqL); */
7674 ODM_CmnInfoPtrArrayHook(podmpriv, ODM_CMNINFO_STA_STATUS, psta->mac_id, NULL);
7675
7676 /* _exit_critical_bh(&pHalData->odm_stainfo_lock, &irqL); */
7677 }
7678 }
7679 break;
7680 case HAL_ODM_P2P_STATE:
7681 ODM_CmnInfoUpdate(podmpriv, ODM_CMNINFO_WIFI_DIRECT, bSet);
7682 break;
7683 case HAL_ODM_WIFI_DISPLAY_STATE:
7684 ODM_CmnInfoUpdate(podmpriv, ODM_CMNINFO_WIFI_DISPLAY, bSet);
7685 break;
7686 case HAL_ODM_REGULATION:
7687 ODM_CmnInfoInit(podmpriv, ODM_CMNINFO_DOMAIN_CODE_2G, pHalData->Regulation2_4G);
7688 ODM_CmnInfoInit(podmpriv, ODM_CMNINFO_DOMAIN_CODE_5G, pHalData->Regulation5G);
7689 break;
7690 #if defined(CONFIG_SIGNAL_DISPLAY_DBM) && defined(CONFIG_BACKGROUND_NOISE_MONITOR)
7691 case HAL_ODM_NOISE_MONITOR: {
7692 struct noise_info *pinfo = (struct noise_info *)pValue1;
7693
7694 #ifdef DBG_NOISE_MONITOR
7695 RTW_INFO("### Noise monitor chan(%d)-bPauseDIG:%d,IGIValue:0x%02x,max_time:%d (ms) ###\n",
7696 pinfo->chan, pinfo->bPauseDIG, pinfo->IGIValue, pinfo->max_time);
7697 #endif
7698
7699 pHalData->noise[pinfo->chan] = ODM_InbandNoise_Monitor(podmpriv, pinfo->bPauseDIG, pinfo->IGIValue, pinfo->max_time);
7700 RTW_INFO("chan_%d, noise = %d (dBm)\n", pinfo->chan, pHalData->noise[pinfo->chan]);
7701 #ifdef DBG_NOISE_MONITOR
7702 RTW_INFO("noise_a = %d, noise_b = %d noise_all:%d\n",
7703 podmpriv->noise_level.noise[ODM_RF_PATH_A],
7704 podmpriv->noise_level.noise[ODM_RF_PATH_B],
7705 podmpriv->noise_level.noise_all);
7706 #endif
7707 }
7708 break;
7709 #endif/*#ifdef CONFIG_BACKGROUND_NOISE_MONITOR*/
7710
7711 case HAL_ODM_INITIAL_GAIN: {
7712 u8 rx_gain = *((u8 *)(pValue1));
7713 /*printk("rx_gain:%x\n",rx_gain);*/
7714 if (rx_gain == 0xff) {/*restore rx gain*/
7715 /*ODM_Write_DIG(podmpriv,pDigTable->BackupIGValue);*/
7716 odm_PauseDIG(podmpriv, PHYDM_RESUME, PHYDM_PAUSE_LEVEL_0, rx_gain);
7717 } else {
7718 /*pDigTable->BackupIGValue = pDigTable->CurIGValue;*/
7719 /*ODM_Write_DIG(podmpriv,rx_gain);*/
7720 odm_PauseDIG(podmpriv, PHYDM_PAUSE, PHYDM_PAUSE_LEVEL_0, rx_gain);
7721 }
7722 }
7723 break;
7724 case HAL_ODM_FA_CNT_DUMP:
7725 if (*((u8 *)pValue1))
7726 podmpriv->DebugComponents |= (ODM_COMP_DIG | ODM_COMP_FA_CNT);
7727 else
7728 podmpriv->DebugComponents &= ~(ODM_COMP_DIG | ODM_COMP_FA_CNT);
7729 break;
7730 case HAL_ODM_DBG_FLAG:
7731 ODM_CmnInfoUpdate(podmpriv, ODM_CMNINFO_DBG_COMP, *((u8Byte *)pValue1));
7732 break;
7733 case HAL_ODM_DBG_LEVEL:
7734 ODM_CmnInfoUpdate(podmpriv, ODM_CMNINFO_DBG_LEVEL, *((u4Byte *)pValue1));
7735 break;
7736 case HAL_ODM_RX_INFO_DUMP: {
7737 PFALSE_ALARM_STATISTICS FalseAlmCnt = (PFALSE_ALARM_STATISTICS)PhyDM_Get_Structure(podmpriv , PHYDM_FALSEALMCNT);
7738 pDIG_T pDM_DigTable = &podmpriv->DM_DigTable;
7739 void *sel;
7740
7741 sel = pValue1;
7742
7743 _RTW_PRINT_SEL(sel , "============ Rx Info dump ===================\n");
7744 _RTW_PRINT_SEL(sel , "bLinked = %d, RSSI_Min = %d(%%), CurrentIGI = 0x%x\n", podmpriv->bLinked, podmpriv->RSSI_Min, pDM_DigTable->CurIGValue);
7745 _RTW_PRINT_SEL(sel , "Cnt_Cck_fail = %d, Cnt_Ofdm_fail = %d, Total False Alarm = %d\n", FalseAlmCnt->Cnt_Cck_fail, FalseAlmCnt->Cnt_Ofdm_fail, FalseAlmCnt->Cnt_all);
7746
7747 if (podmpriv->bLinked) {
7748 _RTW_PRINT_SEL(sel , "RxRate = %s", HDATA_RATE(podmpriv->RxRate));
7749 _RTW_PRINT_SEL(sel , " RSSI_A = %d(%%), RSSI_B = %d(%%)\n", podmpriv->RSSI_A, podmpriv->RSSI_B);
7750 #ifdef DBG_RX_SIGNAL_DISPLAY_RAW_DATA
7751 rtw_dump_raw_rssi_info(Adapter, sel);
7752 #endif
7753 }
7754 }
7755 break;
7756 case HAL_ODM_RX_Dframe_INFO: {
7757 void *sel;
7758
7759 sel = pValue1;
7760
7761 /*_RTW_PRINT_SEL(sel , "HAL_ODM_RX_Dframe_INFO\n");*/
7762 #ifdef DBG_RX_DFRAME_RAW_DATA
7763 rtw_dump_rx_dframe_info(Adapter, sel);
7764 #endif
7765 }
7766 break;
7767
7768 #ifdef CONFIG_AUTO_CHNL_SEL_NHM
7769 case HAL_ODM_AUTO_CHNL_SEL: {
7770 ACS_OP acs_op = *(ACS_OP *)pValue1;
7771
7772 rtw_phydm_func_set(Adapter, ODM_BB_NHM_CNT);
7773
7774 if (ACS_INIT == acs_op) {
7775 #ifdef DBG_AUTO_CHNL_SEL_NHM
7776 RTW_INFO("[ACS-"ADPT_FMT"] HAL_ODM_AUTO_CHNL_SEL: ACS_INIT\n", ADPT_ARG(Adapter));
7777 #endif
7778 odm_AutoChannelSelectInit(podmpriv);
7779 } else if (ACS_RESET == acs_op) {
7780 /* Reset statistics for auto channel selection mechanism.*/
7781 #ifdef DBG_AUTO_CHNL_SEL_NHM
7782 RTW_INFO("[ACS-"ADPT_FMT"] HAL_ODM_AUTO_CHNL_SEL: ACS_RESET\n", ADPT_ARG(Adapter));
7783 #endif
7784 odm_AutoChannelSelectReset(podmpriv);
7785
7786 } else if (ACS_SELECT == acs_op) {
7787 /* Collect NHM measurement result after current channel */
7788 #ifdef DBG_AUTO_CHNL_SEL_NHM
7789 RTW_INFO("[ACS-"ADPT_FMT"] HAL_ODM_AUTO_CHNL_SEL: ACS_SELECT, CH(%d)\n", ADPT_ARG(Adapter), rtw_get_acs_channel(Adapter));
7790 #endif
7791 odm_AutoChannelSelect(podmpriv, rtw_get_acs_channel(Adapter));
7792 } else
7793 RTW_INFO("[ACS-"ADPT_FMT"] HAL_ODM_AUTO_CHNL_SEL: Unexpected OP\n", ADPT_ARG(Adapter));
7794
7795 }
7796 break;
7797 #endif
7798 #ifdef CONFIG_ANTENNA_DIVERSITY
7799 case HAL_ODM_ANTDIV_SELECT: {
7800 u8 antenna = (*(u8 *)pValue1);
7801
7802 /*switch antenna*/
7803 ODM_UpdateRxIdleAnt(&pHalData->odmpriv, antenna);
7804 /*RTW_INFO("==> HAL_ODM_ANTDIV_SELECT, Ant_(%s)\n", (antenna == MAIN_ANT) ? "MAIN_ANT" : "AUX_ANT");*/
7805
7806 }
7807 break;
7808 #endif
7809
7810 default:
7811 break;
7812 }
7813 }
7814
GetHalODMVar(PADAPTER Adapter,HAL_ODM_VARIABLE eVariable,PVOID pValue1,PVOID pValue2)7815 void GetHalODMVar(
7816 PADAPTER Adapter,
7817 HAL_ODM_VARIABLE eVariable,
7818 PVOID pValue1,
7819 PVOID pValue2)
7820 {
7821 HAL_DATA_TYPE *pHalData = GET_HAL_DATA(Adapter);
7822 PDM_ODM_T podmpriv = &pHalData->odmpriv;
7823
7824 switch (eVariable) {
7825 #if defined(CONFIG_SIGNAL_DISPLAY_DBM) && defined(CONFIG_BACKGROUND_NOISE_MONITOR)
7826 case HAL_ODM_NOISE_MONITOR: {
7827 u8 chan = *(u8 *)pValue1;
7828 *(s16 *)pValue2 = pHalData->noise[chan];
7829 #ifdef DBG_NOISE_MONITOR
7830 RTW_INFO("### Noise monitor chan(%d)-noise:%d (dBm) ###\n",
7831 chan, pHalData->noise[chan]);
7832 #endif
7833 }
7834 break;
7835 #endif/*#ifdef CONFIG_BACKGROUND_NOISE_MONITOR*/
7836 case HAL_ODM_DBG_FLAG:
7837 *((u8Byte *)pValue1) = podmpriv->DebugComponents;
7838 break;
7839 case HAL_ODM_DBG_LEVEL:
7840 *((u4Byte *)pValue1) = podmpriv->DebugLevel;
7841 break;
7842
7843 #ifdef CONFIG_AUTO_CHNL_SEL_NHM
7844 case HAL_ODM_AUTO_CHNL_SEL: {
7845 #ifdef DBG_AUTO_CHNL_SEL_NHM
7846 RTW_INFO("[ACS-"ADPT_FMT"] HAL_ODM_AUTO_CHNL_SEL: GET_BEST_CHAN\n", ADPT_ARG(Adapter));
7847 #endif
7848 /* Retrieve better channel from NHM mechanism */
7849 if (IsSupported24G(Adapter->registrypriv.wireless_mode))
7850 *((u8 *)(pValue1)) = ODM_GetAutoChannelSelectResult(podmpriv, BAND_ON_2_4G);
7851 if (IsSupported5G(Adapter->registrypriv.wireless_mode))
7852 *((u8 *)(pValue2)) = ODM_GetAutoChannelSelectResult(podmpriv, BAND_ON_5G);
7853 }
7854 break;
7855 #endif
7856 #ifdef CONFIG_ANTENNA_DIVERSITY
7857 case HAL_ODM_ANTDIV_SELECT: {
7858 pFAT_T pDM_FatTable = &podmpriv->DM_FatTable;
7859 *((u8 *)pValue1) = pDM_FatTable->RxIdleAnt;
7860 }
7861 break;
7862 #endif
7863 case HAL_ODM_INITIAL_GAIN: {
7864 pDIG_T pDM_DigTable = &podmpriv->DM_DigTable;
7865 *((u8 *)pValue1) = pDM_DigTable->CurIGValue;
7866 }
7867 break;
7868 default:
7869 break;
7870 }
7871 }
7872
7873
rtw_phydm_ability_ops(_adapter * adapter,HAL_PHYDM_OPS ops,u32 ability)7874 u32 rtw_phydm_ability_ops(_adapter *adapter, HAL_PHYDM_OPS ops, u32 ability)
7875 {
7876 HAL_DATA_TYPE *pHalData = GET_HAL_DATA(adapter);
7877 PDM_ODM_T podmpriv = &pHalData->odmpriv;
7878 u32 result = 0;
7879
7880 switch (ops) {
7881 case HAL_PHYDM_DIS_ALL_FUNC:
7882 podmpriv->SupportAbility = DYNAMIC_FUNC_DISABLE;
7883 break;
7884 case HAL_PHYDM_FUNC_SET:
7885 podmpriv->SupportAbility |= ability;
7886 break;
7887 case HAL_PHYDM_FUNC_CLR:
7888 podmpriv->SupportAbility &= ~(ability);
7889 break;
7890 case HAL_PHYDM_ABILITY_BK:
7891 /* dm flag backup*/
7892 podmpriv->BK_SupportAbility = podmpriv->SupportAbility;
7893 break;
7894 case HAL_PHYDM_ABILITY_RESTORE:
7895 /* restore dm flag */
7896 podmpriv->SupportAbility = podmpriv->BK_SupportAbility;
7897 break;
7898 case HAL_PHYDM_ABILITY_SET:
7899 podmpriv->SupportAbility = ability;
7900 break;
7901 case HAL_PHYDM_ABILITY_GET:
7902 result = podmpriv->SupportAbility;
7903 break;
7904 }
7905 return result;
7906 }
7907
7908
7909 BOOLEAN
eqNByte(u8 * str1,u8 * str2,u32 num)7910 eqNByte(
7911 u8 *str1,
7912 u8 *str2,
7913 u32 num
7914 )
7915 {
7916 if (num == 0)
7917 return _FALSE;
7918 while (num > 0) {
7919 num--;
7920 if (str1[num] != str2[num])
7921 return _FALSE;
7922 }
7923 return _TRUE;
7924 }
7925
7926 /*
7927 * Description:
7928 * Translate a character to hex digit.
7929 * */
7930 u32
MapCharToHexDigit(IN char chTmp)7931 MapCharToHexDigit(
7932 IN char chTmp
7933 )
7934 {
7935 if (chTmp >= '0' && chTmp <= '9')
7936 return chTmp - '0';
7937 else if (chTmp >= 'a' && chTmp <= 'f')
7938 return 10 + (chTmp - 'a');
7939 else if (chTmp >= 'A' && chTmp <= 'F')
7940 return 10 + (chTmp - 'A');
7941 else
7942 return 0;
7943 }
7944
7945
7946
7947 /*
7948 * Description:
7949 * Parse hex number from the string pucStr.
7950 * */
7951 BOOLEAN
GetHexValueFromString(IN char * szStr,IN OUT u32 * pu4bVal,IN OUT u32 * pu4bMove)7952 GetHexValueFromString(
7953 IN char *szStr,
7954 IN OUT u32 *pu4bVal,
7955 IN OUT u32 *pu4bMove
7956 )
7957 {
7958 char *szScan = szStr;
7959
7960 /* Check input parameter. */
7961 if (szStr == NULL || pu4bVal == NULL || pu4bMove == NULL) {
7962 RTW_INFO("GetHexValueFromString(): Invalid inpur argumetns! szStr: %p, pu4bVal: %p, pu4bMove: %p\n", szStr, pu4bVal, pu4bMove);
7963 return _FALSE;
7964 }
7965
7966 /* Initialize output. */
7967 *pu4bMove = 0;
7968 *pu4bVal = 0;
7969
7970 /* Skip leading space. */
7971 while (*szScan != '\0' &&
7972 (*szScan == ' ' || *szScan == '\t')) {
7973 szScan++;
7974 (*pu4bMove)++;
7975 }
7976
7977 /* Skip leading '0x' or '0X'. */
7978 if (*szScan == '0' && (*(szScan + 1) == 'x' || *(szScan + 1) == 'X')) {
7979 szScan += 2;
7980 (*pu4bMove) += 2;
7981 }
7982
7983 /* Check if szScan is now pointer to a character for hex digit, */
7984 /* if not, it means this is not a valid hex number. */
7985 if (!IsHexDigit(*szScan))
7986 return _FALSE;
7987
7988 /* Parse each digit. */
7989 do {
7990 (*pu4bVal) <<= 4;
7991 *pu4bVal += MapCharToHexDigit(*szScan);
7992
7993 szScan++;
7994 (*pu4bMove)++;
7995 } while (IsHexDigit(*szScan));
7996
7997 return _TRUE;
7998 }
7999
8000 BOOLEAN
GetFractionValueFromString(IN char * szStr,IN OUT u8 * pInteger,IN OUT u8 * pFraction,IN OUT u32 * pu4bMove)8001 GetFractionValueFromString(
8002 IN char *szStr,
8003 IN OUT u8 *pInteger,
8004 IN OUT u8 *pFraction,
8005 IN OUT u32 *pu4bMove
8006 )
8007 {
8008 char *szScan = szStr;
8009
8010 /* Initialize output. */
8011 *pu4bMove = 0;
8012 *pInteger = 0;
8013 *pFraction = 0;
8014
8015 /* Skip leading space. */
8016 while (*szScan != '\0' && (*szScan == ' ' || *szScan == '\t')) {
8017 ++szScan;
8018 ++(*pu4bMove);
8019 }
8020
8021 /* Parse each digit. */
8022 do {
8023 (*pInteger) *= 10;
8024 *pInteger += (*szScan - '0');
8025
8026 ++szScan;
8027 ++(*pu4bMove);
8028
8029 if (*szScan == '.') {
8030 ++szScan;
8031 ++(*pu4bMove);
8032
8033 if (*szScan < '0' || *szScan > '9')
8034 return _FALSE;
8035 else {
8036 *pFraction = *szScan - '0';
8037 ++szScan;
8038 ++(*pu4bMove);
8039 return _TRUE;
8040 }
8041 }
8042 } while (*szScan >= '0' && *szScan <= '9');
8043
8044 return _TRUE;
8045 }
8046
8047 /*
8048 * Description:
8049 * Return TRUE if szStr is comment out with leading " */ /* ".
8050 * */
8051 BOOLEAN
IsCommentString(IN char * szStr)8052 IsCommentString(
8053 IN char *szStr
8054 )
8055 {
8056 if (*szStr == '/' && *(szStr + 1) == '/')
8057 return _TRUE;
8058 else
8059 return _FALSE;
8060 }
8061
8062 BOOLEAN
GetU1ByteIntegerFromStringInDecimal(IN char * Str,IN OUT u8 * pInt)8063 GetU1ByteIntegerFromStringInDecimal(
8064 IN char *Str,
8065 IN OUT u8 *pInt
8066 )
8067 {
8068 u16 i = 0;
8069 *pInt = 0;
8070
8071 while (Str[i] != '\0') {
8072 if (Str[i] >= '0' && Str[i] <= '9') {
8073 *pInt *= 10;
8074 *pInt += (Str[i] - '0');
8075 } else
8076 return _FALSE;
8077 ++i;
8078 }
8079
8080 return _TRUE;
8081 }
8082
8083 /* <20121004, Kordan> For example,
8084 * ParseQualifiedString(inString, 0, outString, '[', ']') gets "Kordan" from a string "Hello [Kordan]".
8085 * If RightQualifier does not exist, it will hang on in the while loop */
8086 BOOLEAN
ParseQualifiedString(IN char * In,IN OUT u32 * Start,OUT char * Out,IN char LeftQualifier,IN char RightQualifier)8087 ParseQualifiedString(
8088 IN char *In,
8089 IN OUT u32 *Start,
8090 OUT char *Out,
8091 IN char LeftQualifier,
8092 IN char RightQualifier
8093 )
8094 {
8095 u32 i = 0, j = 0;
8096 char c = In[(*Start)++];
8097
8098 if (c != LeftQualifier)
8099 return _FALSE;
8100
8101 i = (*Start);
8102 while ((c = In[(*Start)++]) != RightQualifier)
8103 ; /* find ']' */
8104 j = (*Start) - 2;
8105 strncpy((char *)Out, (const char *)(In + i), j - i + 1);
8106
8107 return _TRUE;
8108 }
8109
8110 BOOLEAN
isAllSpaceOrTab(u8 * data,u8 size)8111 isAllSpaceOrTab(
8112 u8 *data,
8113 u8 size
8114 )
8115 {
8116 u8 cnt = 0, NumOfSpaceAndTab = 0;
8117
8118 while (size > cnt) {
8119 if (data[cnt] == ' ' || data[cnt] == '\t' || data[cnt] == '\0')
8120 ++NumOfSpaceAndTab;
8121
8122 ++cnt;
8123 }
8124
8125 return size == NumOfSpaceAndTab;
8126 }
8127
8128
rtw_hal_check_rxfifo_full(_adapter * adapter)8129 void rtw_hal_check_rxfifo_full(_adapter *adapter)
8130 {
8131 struct dvobj_priv *psdpriv = adapter->dvobj;
8132 struct debug_priv *pdbgpriv = &psdpriv->drv_dbg;
8133 HAL_DATA_TYPE *pHalData = GET_HAL_DATA(adapter);
8134 struct registry_priv *regsty = &adapter->registrypriv;
8135 int save_cnt = _FALSE;
8136
8137 if (regsty->check_hw_status == 1) {
8138 /* switch counter to RX fifo */
8139 if (IS_8188E(pHalData->VersionID) ||
8140 IS_8188F(pHalData->VersionID) ||
8141 IS_8812_SERIES(pHalData->VersionID) ||
8142 IS_8821_SERIES(pHalData->VersionID) ||
8143 IS_8723B_SERIES(pHalData->VersionID) ||
8144 IS_8192E(pHalData->VersionID) ||
8145 IS_8703B_SERIES(pHalData->VersionID) ||
8146 IS_8723D_SERIES(pHalData->VersionID)) {
8147 rtw_write8(adapter, REG_RXERR_RPT + 3, rtw_read8(adapter, REG_RXERR_RPT + 3) | 0xa0);
8148 save_cnt = _TRUE;
8149 } else {
8150 /* todo: other chips */
8151 }
8152
8153
8154 if (save_cnt) {
8155 pdbgpriv->dbg_rx_fifo_last_overflow = pdbgpriv->dbg_rx_fifo_curr_overflow;
8156 pdbgpriv->dbg_rx_fifo_curr_overflow = rtw_read16(adapter, REG_RXERR_RPT);
8157 pdbgpriv->dbg_rx_fifo_diff_overflow = pdbgpriv->dbg_rx_fifo_curr_overflow - pdbgpriv->dbg_rx_fifo_last_overflow;
8158 } else {
8159 /* special value to indicate no implementation */
8160 pdbgpriv->dbg_rx_fifo_last_overflow = 1;
8161 pdbgpriv->dbg_rx_fifo_curr_overflow = 1;
8162 pdbgpriv->dbg_rx_fifo_diff_overflow = 1;
8163 }
8164 }
8165 }
8166
linked_info_dump(_adapter * padapter,u8 benable)8167 void linked_info_dump(_adapter *padapter, u8 benable)
8168 {
8169 struct pwrctrl_priv *pwrctrlpriv = adapter_to_pwrctl(padapter);
8170
8171 if (padapter->bLinkInfoDump == benable)
8172 return;
8173
8174 RTW_INFO("%s %s\n", __FUNCTION__, (benable) ? "enable" : "disable");
8175
8176 if (benable) {
8177 #ifdef CONFIG_LPS
8178 pwrctrlpriv->org_power_mgnt = pwrctrlpriv->power_mgnt;/* keep org value */
8179 rtw_pm_set_lps(padapter, PS_MODE_ACTIVE);
8180 #endif
8181
8182 #ifdef CONFIG_IPS
8183 pwrctrlpriv->ips_org_mode = pwrctrlpriv->ips_mode;/* keep org value */
8184 rtw_pm_set_ips(padapter, IPS_NONE);
8185 #endif
8186 } else {
8187 #ifdef CONFIG_IPS
8188 rtw_pm_set_ips(padapter, pwrctrlpriv->ips_org_mode);
8189 #endif /* CONFIG_IPS */
8190
8191 #ifdef CONFIG_LPS
8192 rtw_pm_set_lps(padapter, pwrctrlpriv->org_power_mgnt);
8193 #endif /* CONFIG_LPS */
8194 }
8195 padapter->bLinkInfoDump = benable ;
8196 }
8197
8198 #ifdef DBG_RX_SIGNAL_DISPLAY_RAW_DATA
rtw_get_raw_rssi_info(void * sel,_adapter * padapter)8199 void rtw_get_raw_rssi_info(void *sel, _adapter *padapter)
8200 {
8201 u8 isCCKrate, rf_path;
8202 PHAL_DATA_TYPE pHalData = GET_HAL_DATA(padapter);
8203 struct rx_raw_rssi *psample_pkt_rssi = &padapter->recvpriv.raw_rssi_info;
8204 RTW_PRINT_SEL(sel, "RxRate = %s, PWDBALL = %d(%%), rx_pwr_all = %d(dBm)\n",
8205 HDATA_RATE(psample_pkt_rssi->data_rate), psample_pkt_rssi->pwdball, psample_pkt_rssi->pwr_all);
8206 isCCKrate = (psample_pkt_rssi->data_rate <= DESC_RATE11M) ? TRUE : FALSE;
8207
8208 if (isCCKrate)
8209 psample_pkt_rssi->mimo_signal_strength[0] = psample_pkt_rssi->pwdball;
8210
8211 for (rf_path = 0; rf_path < pHalData->NumTotalRFPath; rf_path++) {
8212 RTW_PRINT_SEL(sel, "RF_PATH_%d=>signal_strength:%d(%%),signal_quality:%d(%%)\n"
8213 , rf_path, psample_pkt_rssi->mimo_signal_strength[rf_path], psample_pkt_rssi->mimo_signal_quality[rf_path]);
8214
8215 if (!isCCKrate) {
8216 RTW_PRINT_SEL(sel, "\trx_ofdm_pwr:%d(dBm),rx_ofdm_snr:%d(dB)\n",
8217 psample_pkt_rssi->ofdm_pwr[rf_path], psample_pkt_rssi->ofdm_snr[rf_path]);
8218 }
8219 }
8220 }
8221
rtw_dump_raw_rssi_info(_adapter * padapter,void * sel)8222 void rtw_dump_raw_rssi_info(_adapter *padapter, void *sel)
8223 {
8224 u8 isCCKrate, rf_path;
8225 PHAL_DATA_TYPE pHalData = GET_HAL_DATA(padapter);
8226 struct rx_raw_rssi *psample_pkt_rssi = &padapter->recvpriv.raw_rssi_info;
8227 _RTW_PRINT_SEL(sel, "============ RAW Rx Info dump ===================\n");
8228 _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);
8229
8230 isCCKrate = (psample_pkt_rssi->data_rate <= DESC_RATE11M) ? TRUE : FALSE;
8231
8232 if (isCCKrate)
8233 psample_pkt_rssi->mimo_signal_strength[0] = psample_pkt_rssi->pwdball;
8234
8235 for (rf_path = 0; rf_path < pHalData->NumTotalRFPath; rf_path++) {
8236 _RTW_PRINT_SEL(sel , "RF_PATH_%d=>signal_strength:%d(%%),signal_quality:%d(%%)"
8237 , rf_path, psample_pkt_rssi->mimo_signal_strength[rf_path], psample_pkt_rssi->mimo_signal_quality[rf_path]);
8238
8239 if (!isCCKrate)
8240 _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]);
8241 else
8242 _RTW_PRINT_SEL(sel , "\n");
8243
8244 }
8245 }
8246 #endif
8247
8248 #ifdef DBG_RX_DFRAME_RAW_DATA
rtw_dump_rx_dframe_info(_adapter * padapter,void * sel)8249 void rtw_dump_rx_dframe_info(_adapter *padapter, void *sel)
8250 {
8251 _irqL irqL;
8252 u8 isCCKrate, rf_path;
8253 struct recv_priv *precvpriv = &(padapter->recvpriv);
8254 PHAL_DATA_TYPE pHalData = GET_HAL_DATA(padapter);
8255 struct sta_priv *pstapriv = &padapter->stapriv;
8256 struct sta_info *psta;
8257 struct sta_recv_dframe_info *psta_dframe_info;
8258 int i;
8259 _list *plist, *phead;
8260 char *BW;
8261 u8 bc_addr[6] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
8262 u8 null_addr[6] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
8263
8264 if (precvpriv->store_law_data_flag) {
8265
8266 _enter_critical_bh(&pstapriv->sta_hash_lock, &irqL);
8267
8268 for (i = 0; i < NUM_STA; i++) {
8269 phead = &(pstapriv->sta_hash[i]);
8270 plist = get_next(phead);
8271
8272 while ((rtw_end_of_queue_search(phead, plist)) == _FALSE) {
8273
8274 psta = LIST_CONTAINOR(plist, struct sta_info, hash_list);
8275 plist = get_next(plist);
8276
8277 if (psta) {
8278 psta_dframe_info = &psta->sta_dframe_info;
8279 if ((_rtw_memcmp(psta->hwaddr, bc_addr, 6) != _TRUE)
8280 && (_rtw_memcmp(psta->hwaddr, null_addr, 6) != _TRUE)
8281 && (_rtw_memcmp(psta->hwaddr, adapter_mac_addr(padapter), 6) != _TRUE)) {
8282
8283
8284 isCCKrate = (psta_dframe_info->sta_data_rate <= DESC_RATE11M) ? TRUE : FALSE;
8285
8286 switch (psta_dframe_info->sta_bw_mode) {
8287
8288 case CHANNEL_WIDTH_20:
8289 BW = "20M";
8290 break;
8291
8292 case CHANNEL_WIDTH_40:
8293 BW = "40M";
8294 break;
8295
8296 case CHANNEL_WIDTH_80:
8297 BW = "80M";
8298 break;
8299
8300 case CHANNEL_WIDTH_160:
8301 BW = "160M";
8302 break;
8303
8304 default:
8305 BW = "";
8306 break;
8307 }
8308
8309 RTW_PRINT_SEL(sel, "==============================\n");
8310 _RTW_PRINT_SEL(sel, "macaddr =" MAC_FMT "\n", MAC_ARG(psta->hwaddr));
8311 _RTW_PRINT_SEL(sel, "BW=%s, sgi =%d\n", BW, psta_dframe_info->sta_sgi);
8312 _RTW_PRINT_SEL(sel, "Rx_Data_Rate = %s\n", HDATA_RATE(psta_dframe_info->sta_data_rate));
8313
8314 for (rf_path = 0; rf_path < pHalData->NumTotalRFPath; rf_path++) {
8315
8316 if (!isCCKrate) {
8317
8318 _RTW_PRINT_SEL(sel , "RF_PATH_%d RSSI:%d(dBm)", rf_path, psta_dframe_info->sta_RxPwr[rf_path]);
8319 _RTW_PRINT_SEL(sel , ",rx_ofdm_snr:%d(dB)\n", psta_dframe_info->sta_ofdm_snr[rf_path]);
8320
8321 } else
8322
8323 _RTW_PRINT_SEL(sel , "RF_PATH_%d RSSI:%d(dBm)\n", rf_path, (psta_dframe_info->sta_mimo_signal_strength[rf_path]) - 100);
8324 }
8325 }
8326 }
8327 }
8328 }
8329 _exit_critical_bh(&pstapriv->sta_hash_lock, &irqL);
8330 }
8331 }
8332 #endif
rtw_store_phy_info(_adapter * padapter,union recv_frame * prframe)8333 void rtw_store_phy_info(_adapter *padapter, union recv_frame *prframe)
8334 {
8335 u8 isCCKrate, rf_path , dframe_type;
8336 u8 *ptr;
8337 u8 bc_addr[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
8338 #ifdef DBG_RX_DFRAME_RAW_DATA
8339 struct sta_recv_dframe_info *psta_dframe_info;
8340 #endif
8341 struct recv_priv *precvpriv = &(padapter->recvpriv);
8342 PHAL_DATA_TYPE pHalData = GET_HAL_DATA(padapter);
8343 struct rx_pkt_attrib *pattrib = &prframe->u.hdr.attrib;
8344 struct sta_info *psta = prframe->u.hdr.psta;
8345 PODM_PHY_INFO_T pPhyInfo = (PODM_PHY_INFO_T)(&pattrib->phy_info);
8346 struct rx_raw_rssi *psample_pkt_rssi = &padapter->recvpriv.raw_rssi_info;
8347 psample_pkt_rssi->data_rate = pattrib->data_rate;
8348 ptr = prframe->u.hdr.rx_data;
8349 dframe_type = GetFrameType(ptr);
8350 /*RTW_INFO("=>%s\n", __FUNCTION__);*/
8351
8352
8353 if (precvpriv->store_law_data_flag) {
8354 isCCKrate = (pattrib->data_rate <= DESC_RATE11M) ? TRUE : FALSE;
8355
8356 psample_pkt_rssi->pwdball = pPhyInfo->RxPWDBAll;
8357 psample_pkt_rssi->pwr_all = pPhyInfo->RecvSignalPower;
8358
8359 for (rf_path = 0; rf_path < pHalData->NumTotalRFPath; rf_path++) {
8360 psample_pkt_rssi->mimo_signal_strength[rf_path] = pPhyInfo->RxMIMOSignalStrength[rf_path];
8361 psample_pkt_rssi->mimo_signal_quality[rf_path] = pPhyInfo->RxMIMOSignalQuality[rf_path];
8362 if (!isCCKrate) {
8363 psample_pkt_rssi->ofdm_pwr[rf_path] = pPhyInfo->RxPwr[rf_path];
8364 psample_pkt_rssi->ofdm_snr[rf_path] = pPhyInfo->RxSNR[rf_path];
8365 }
8366 }
8367 #ifdef DBG_RX_DFRAME_RAW_DATA
8368 if (dframe_type == WIFI_DATA_TYPE || dframe_type == WIFI_QOS_DATA_TYPE) {
8369
8370 /*RTW_INFO("=>%s WIFI_DATA_TYPE or WIFI_QOS_DATA_TYPE\n", __FUNCTION__);*/
8371 if (psta) {
8372 psta_dframe_info = &psta->sta_dframe_info;
8373 /*RTW_INFO("=>%s psta->hwaddr="MAC_FMT" !\n", __FUNCTION__, MAC_ARG(psta->hwaddr));*/
8374 if (_rtw_memcmp(psta->hwaddr, bc_addr, ETH_ALEN) != _TRUE) {
8375
8376 psta_dframe_info->sta_data_rate = pattrib->data_rate;
8377 psta_dframe_info->sta_sgi = pattrib->sgi;
8378 psta_dframe_info->sta_bw_mode = pattrib->bw;
8379 for (rf_path = 0; rf_path < pHalData->NumTotalRFPath; rf_path++) {
8380
8381 psta_dframe_info->sta_mimo_signal_strength[rf_path] = (pPhyInfo->RxMIMOSignalStrength[rf_path]);/*Percentage to dbm*/
8382
8383 if (!isCCKrate) {
8384 psta_dframe_info->sta_ofdm_snr[rf_path] = pPhyInfo->RxSNR[rf_path];
8385 psta_dframe_info->sta_RxPwr[rf_path] = pPhyInfo->RxPwr[rf_path];
8386 }
8387 }
8388 }
8389 }
8390 }
8391 #endif
8392 }
8393
8394 }
8395
8396
check_phy_efuse_tx_power_info_valid(PADAPTER padapter)8397 int check_phy_efuse_tx_power_info_valid(PADAPTER padapter)
8398 {
8399 PHAL_DATA_TYPE pHalData = GET_HAL_DATA(padapter);
8400 u8 *pContent = pHalData->efuse_eeprom_data;
8401 int index = 0;
8402 u16 tx_index_offset = 0x0000;
8403
8404 switch (rtw_get_chip_type(padapter)) {
8405 case RTL8723B:
8406 tx_index_offset = EEPROM_TX_PWR_INX_8723B;
8407 break;
8408 case RTL8703B:
8409 tx_index_offset = EEPROM_TX_PWR_INX_8703B;
8410 break;
8411 case RTL8723D:
8412 tx_index_offset = EEPROM_TX_PWR_INX_8723D;
8413 break;
8414 case RTL8188E:
8415 tx_index_offset = EEPROM_TX_PWR_INX_88E;
8416 break;
8417 case RTL8188F:
8418 tx_index_offset = EEPROM_TX_PWR_INX_8188F;
8419 break;
8420 case RTL8192E:
8421 tx_index_offset = EEPROM_TX_PWR_INX_8192E;
8422 break;
8423 case RTL8821:
8424 tx_index_offset = EEPROM_TX_PWR_INX_8821;
8425 break;
8426 case RTL8812:
8427 tx_index_offset = EEPROM_TX_PWR_INX_8812;
8428 break;
8429 case RTL8814A:
8430 tx_index_offset = EEPROM_TX_PWR_INX_8814;
8431 break;
8432 case RTL8822B:
8433 tx_index_offset = EEPROM_TX_PWR_INX_8822B;
8434 break;
8435 case RTL8821C:
8436 tx_index_offset = EEPROM_TX_PWR_INX_8821C;
8437 break;
8438 default:
8439 tx_index_offset = 0x0010;
8440 break;
8441 }
8442
8443 /* TODO: chacking length by ICs */
8444 for (index = 0 ; index < 11 ; index++) {
8445 if (pContent[tx_index_offset + index] == 0xFF)
8446 return _FALSE;
8447 }
8448 return _TRUE;
8449 }
8450
hal_efuse_macaddr_offset(_adapter * adapter)8451 int hal_efuse_macaddr_offset(_adapter *adapter)
8452 {
8453 u8 interface_type = 0;
8454 int addr_offset = -1;
8455
8456 interface_type = rtw_get_intf_type(adapter);
8457
8458 switch (rtw_get_chip_type(adapter)) {
8459 #ifdef CONFIG_RTL8723B
8460 case RTL8723B:
8461 if (interface_type == RTW_USB)
8462 addr_offset = EEPROM_MAC_ADDR_8723BU;
8463 else if (interface_type == RTW_SDIO)
8464 addr_offset = EEPROM_MAC_ADDR_8723BS;
8465 else if (interface_type == RTW_PCIE)
8466 addr_offset = EEPROM_MAC_ADDR_8723BE;
8467 break;
8468 #endif
8469 #ifdef CONFIG_RTL8703B
8470 case RTL8703B:
8471 if (interface_type == RTW_USB)
8472 addr_offset = EEPROM_MAC_ADDR_8703BU;
8473 else if (interface_type == RTW_SDIO)
8474 addr_offset = EEPROM_MAC_ADDR_8703BS;
8475 break;
8476 #endif
8477 #ifdef CONFIG_RTL8723D
8478 case RTL8723D:
8479 if (interface_type == RTW_USB)
8480 addr_offset = EEPROM_MAC_ADDR_8723DU;
8481 else if (interface_type == RTW_SDIO)
8482 addr_offset = EEPROM_MAC_ADDR_8723DS;
8483 else if (interface_type == RTW_PCIE)
8484 addr_offset = EEPROM_MAC_ADDR_8723DE;
8485 break;
8486 #endif
8487
8488 #ifdef CONFIG_RTL8188E
8489 case RTL8188E:
8490 if (interface_type == RTW_USB)
8491 addr_offset = EEPROM_MAC_ADDR_88EU;
8492 else if (interface_type == RTW_SDIO)
8493 addr_offset = EEPROM_MAC_ADDR_88ES;
8494 else if (interface_type == RTW_PCIE)
8495 addr_offset = EEPROM_MAC_ADDR_88EE;
8496 break;
8497 #endif
8498 #ifdef CONFIG_RTL8188F
8499 case RTL8188F:
8500 if (interface_type == RTW_USB)
8501 addr_offset = EEPROM_MAC_ADDR_8188FU;
8502 else if (interface_type == RTW_SDIO)
8503 addr_offset = EEPROM_MAC_ADDR_8188FS;
8504 break;
8505 #endif
8506 #ifdef CONFIG_RTL8812A
8507 case RTL8812:
8508 if (interface_type == RTW_USB)
8509 addr_offset = EEPROM_MAC_ADDR_8812AU;
8510 else if (interface_type == RTW_PCIE)
8511 addr_offset = EEPROM_MAC_ADDR_8812AE;
8512 break;
8513 #endif
8514 #ifdef CONFIG_RTL8821A
8515 case RTL8821:
8516 if (interface_type == RTW_USB)
8517 addr_offset = EEPROM_MAC_ADDR_8821AU;
8518 else if (interface_type == RTW_SDIO)
8519 addr_offset = EEPROM_MAC_ADDR_8821AS;
8520 else if (interface_type == RTW_PCIE)
8521 addr_offset = EEPROM_MAC_ADDR_8821AE;
8522 break;
8523 #endif
8524 #ifdef CONFIG_RTL8192E
8525 case RTL8192E:
8526 if (interface_type == RTW_USB)
8527 addr_offset = EEPROM_MAC_ADDR_8192EU;
8528 else if (interface_type == RTW_SDIO)
8529 addr_offset = EEPROM_MAC_ADDR_8192ES;
8530 else if (interface_type == RTW_PCIE)
8531 addr_offset = EEPROM_MAC_ADDR_8192EE;
8532 break;
8533 #endif
8534 #ifdef CONFIG_RTL8814A
8535 case RTL8814A:
8536 if (interface_type == RTW_USB)
8537 addr_offset = EEPROM_MAC_ADDR_8814AU;
8538 else if (interface_type == RTW_PCIE)
8539 addr_offset = EEPROM_MAC_ADDR_8814AE;
8540 break;
8541 #endif
8542
8543 #ifdef CONFIG_RTL8822B
8544 case RTL8822B:
8545 if (interface_type == RTW_USB)
8546 addr_offset = EEPROM_MAC_ADDR_8822BU;
8547 else if (interface_type == RTW_SDIO)
8548 addr_offset = EEPROM_MAC_ADDR_8822BS;
8549 else if (interface_type == RTW_PCIE)
8550 addr_offset = EEPROM_MAC_ADDR_8822BE;
8551 break;
8552 #endif /* CONFIG_RTL8822B */
8553
8554 #ifdef CONFIG_RTL8821C
8555 case RTL8821C:
8556 if (interface_type == RTW_USB)
8557 addr_offset = EEPROM_MAC_ADDR_8821CU;
8558 else if (interface_type == RTW_SDIO)
8559 addr_offset = EEPROM_MAC_ADDR_8821CS;
8560 else if (interface_type == RTW_PCIE)
8561 addr_offset = EEPROM_MAC_ADDR_8821CE;
8562 break;
8563 #endif /* CONFIG_RTL8821C */
8564 }
8565
8566 if (addr_offset == -1) {
8567 RTW_ERR("%s: unknown combination - chip_type:%u, interface:%u\n"
8568 , __func__, rtw_get_chip_type(adapter), rtw_get_intf_type(adapter));
8569 }
8570
8571 return addr_offset;
8572 }
8573
Hal_GetPhyEfuseMACAddr(PADAPTER padapter,u8 * mac_addr)8574 int Hal_GetPhyEfuseMACAddr(PADAPTER padapter, u8 *mac_addr)
8575 {
8576 int ret = _FAIL;
8577 int addr_offset;
8578
8579 addr_offset = hal_efuse_macaddr_offset(padapter);
8580 if (addr_offset == -1)
8581 goto exit;
8582
8583 ret = rtw_efuse_map_read(padapter, addr_offset, ETH_ALEN, mac_addr);
8584
8585 exit:
8586 return ret;
8587 }
8588
rtw_dump_cur_efuse(PADAPTER padapter)8589 void rtw_dump_cur_efuse(PADAPTER padapter)
8590 {
8591 int i =0;
8592 int mapsize =0;
8593 HAL_DATA_TYPE *hal_data = GET_HAL_DATA(padapter);
8594
8595 EFUSE_GetEfuseDefinition(padapter, EFUSE_WIFI, TYPE_EFUSE_MAP_LEN , (void *)&mapsize, _FALSE);
8596
8597 if (mapsize <= 0 || mapsize > EEPROM_MAX_SIZE) {
8598 RTW_INFO("wrong map size %d\n", mapsize);
8599 return;
8600 }
8601
8602 if (hal_data->efuse_file_status == EFUSE_FILE_LOADED)
8603 RTW_INFO("Use EFUSE FILE\n");
8604 else
8605 RTW_INFO("HW EFUSE\n");
8606
8607 #ifdef CONFIG_RTW_DEBUG
8608 #ifdef PLATFORM_LINUX
8609 RTW_INFO("eFuse Content:\n");
8610 print_hex_dump(KERN_DEBUG, "eFuse ",
8611 DUMP_PREFIX_OFFSET, 16, 1,
8612 hal_data->efuse_eeprom_data, mapsize, false);
8613 #endif /* PLATFORM_LINUX */
8614 #endif /* CONFIG_RTW_DEBUG */
8615 }
8616
8617
8618 #ifdef CONFIG_EFUSE_CONFIG_FILE
Hal_readPGDataFromConfigFile(PADAPTER padapter)8619 u32 Hal_readPGDataFromConfigFile(PADAPTER padapter)
8620 {
8621 HAL_DATA_TYPE *hal_data = GET_HAL_DATA(padapter);
8622 u32 ret = _FALSE;
8623 u32 maplen = 0;
8624
8625 EFUSE_GetEfuseDefinition(padapter, EFUSE_WIFI, TYPE_EFUSE_MAP_LEN , (void *)&maplen, _FALSE);
8626
8627 if (maplen < 256 || maplen > EEPROM_MAX_SIZE) {
8628 RTW_ERR("eFuse length error :%d\n", maplen);
8629 return _FALSE;
8630 }
8631
8632 ret = rtw_efuse_file_read(padapter, EFUSE_MAP_PATH, hal_data->efuse_eeprom_data, maplen);
8633 if (ret == _FALSE)
8634 ret = rtw_read_efuse_from_file(EFUSE_MAP_PATH, hal_data->efuse_eeprom_data);
8635
8636 hal_data->efuse_file_status = ((ret == _FAIL) ? EFUSE_FILE_FAILED : EFUSE_FILE_LOADED);
8637
8638 return ret;
8639 }
8640
Hal_ReadMACAddrFromFile(PADAPTER padapter,u8 * mac_addr)8641 u32 Hal_ReadMACAddrFromFile(PADAPTER padapter, u8 *mac_addr)
8642 {
8643 HAL_DATA_TYPE *hal_data = GET_HAL_DATA(padapter);
8644 u32 ret = _FAIL;
8645
8646 if (rtw_read_macaddr_from_file(WIFIMAC_PATH, mac_addr) == _SUCCESS
8647 && rtw_check_invalid_mac_address(mac_addr, _TRUE) == _FALSE
8648 ) {
8649 hal_data->macaddr_file_status = MACADDR_FILE_LOADED;
8650 ret = _SUCCESS;
8651 } else
8652 hal_data->macaddr_file_status = MACADDR_FILE_FAILED;
8653
8654 return ret;
8655 }
8656 #endif /* CONFIG_EFUSE_CONFIG_FILE */
8657
hal_config_macaddr(_adapter * adapter,bool autoload_fail)8658 int hal_config_macaddr(_adapter *adapter, bool autoload_fail)
8659 {
8660 HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
8661 u8 addr[ETH_ALEN];
8662 int addr_offset = hal_efuse_macaddr_offset(adapter);
8663 u8 *hw_addr = NULL;
8664 int ret = _SUCCESS;
8665
8666 if (autoload_fail)
8667 goto bypass_hw_pg;
8668
8669 if (addr_offset != -1)
8670 hw_addr = &hal_data->efuse_eeprom_data[addr_offset];
8671
8672 #ifdef CONFIG_EFUSE_CONFIG_FILE
8673 /* if the hw_addr is written by efuse file, set to NULL */
8674 if (hal_data->efuse_file_status == EFUSE_FILE_LOADED)
8675 hw_addr = NULL;
8676 #endif
8677
8678 if (!hw_addr) {
8679 /* try getting hw pg data */
8680 if (Hal_GetPhyEfuseMACAddr(adapter, addr) == _SUCCESS)
8681 hw_addr = addr;
8682 }
8683
8684 /* check hw pg data */
8685 if (hw_addr && rtw_check_invalid_mac_address(hw_addr, _TRUE) == _FALSE) {
8686 _rtw_memcpy(hal_data->EEPROMMACAddr, hw_addr, ETH_ALEN);
8687 goto exit;
8688 }
8689
8690 bypass_hw_pg:
8691
8692 #ifdef CONFIG_EFUSE_CONFIG_FILE
8693 /* check wifi mac file */
8694 if (Hal_ReadMACAddrFromFile(adapter, addr) == _SUCCESS) {
8695 _rtw_memcpy(hal_data->EEPROMMACAddr, addr, ETH_ALEN);
8696 goto exit;
8697 }
8698 #endif
8699
8700 _rtw_memset(hal_data->EEPROMMACAddr, 0, ETH_ALEN);
8701 ret = _FAIL;
8702
8703 exit:
8704 return ret;
8705 }
8706
8707 #ifdef CONFIG_RF_POWER_TRIM
8708 u32 Array_kfreemap[] = {
8709 0x08, 0xe,
8710 0x06, 0xc,
8711 0x04, 0xa,
8712 0x02, 0x8,
8713 0x00, 0x6,
8714 0x03, 0x4,
8715 0x05, 0x2,
8716 0x07, 0x0,
8717 0x09, 0x0,
8718 0x0c, 0x0,
8719 };
8720
rtw_bb_rf_gain_offset(_adapter * padapter)8721 void rtw_bb_rf_gain_offset(_adapter *padapter)
8722 {
8723 HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);
8724 struct registry_priv *registry_par = &padapter->registrypriv;
8725 struct kfree_data_t *kfree_data = &pHalData->kfree_data;
8726 u8 value = pHalData->EEPROMRFGainOffset;
8727 u8 tmp = 0x3e;
8728 u32 res, i = 0;
8729 u4Byte ArrayLen = sizeof(Array_kfreemap) / sizeof(u32);
8730 pu4Byte Array = Array_kfreemap;
8731 u4Byte v1 = 0, v2 = 0, GainValue = 0, target = 0;
8732
8733 if (registry_par->RegPwrTrimEnable == 2) {
8734 RTW_INFO("Registry kfree default force disable.\n");
8735 return;
8736 }
8737
8738 #if defined(CONFIG_RTL8723B)
8739 if (value & BIT4 || (registry_par->RegPwrTrimEnable == 1)) {
8740 RTW_INFO("Offset RF Gain.\n");
8741 RTW_INFO("Offset RF Gain. pHalData->EEPROMRFGainVal=0x%x\n", pHalData->EEPROMRFGainVal);
8742
8743 if (pHalData->EEPROMRFGainVal != 0xff) {
8744
8745 if (pHalData->ant_path == ODM_RF_PATH_A)
8746 GainValue = (pHalData->EEPROMRFGainVal & 0x0f);
8747
8748 else
8749 GainValue = (pHalData->EEPROMRFGainVal & 0xf0) >> 4;
8750 RTW_INFO("Ant PATH_%d GainValue Offset = 0x%x\n", (pHalData->ant_path == ODM_RF_PATH_A) ? (ODM_RF_PATH_A) : (ODM_RF_PATH_B), GainValue);
8751
8752 for (i = 0; i < ArrayLen; i += 2) {
8753 /* RTW_INFO("ArrayLen in =%d ,Array 1 =0x%x ,Array2 =0x%x\n",i,Array[i],Array[i]+1); */
8754 v1 = Array[i];
8755 v2 = Array[i + 1];
8756 if (v1 == GainValue) {
8757 RTW_INFO("Offset RF Gain. got v1 =0x%x ,v2 =0x%x\n", v1, v2);
8758 target = v2;
8759 break;
8760 }
8761 }
8762 RTW_INFO("pHalData->EEPROMRFGainVal=0x%x ,Gain offset Target Value=0x%x\n", pHalData->EEPROMRFGainVal, target);
8763
8764 res = rtw_hal_read_rfreg(padapter, RF_PATH_A, 0x7f, 0xffffffff);
8765 RTW_INFO("Offset RF Gain. before reg 0x7f=0x%08x\n", res);
8766 PHY_SetRFReg(padapter, RF_PATH_A, REG_RF_BB_GAIN_OFFSET, BIT18 | BIT17 | BIT16 | BIT15, target);
8767 res = rtw_hal_read_rfreg(padapter, RF_PATH_A, 0x7f, 0xffffffff);
8768
8769 RTW_INFO("Offset RF Gain. After reg 0x7f=0x%08x\n", res);
8770
8771 } else
8772
8773 RTW_INFO("Offset RF Gain. pHalData->EEPROMRFGainVal=0x%x != 0xff, didn't run Kfree\n", pHalData->EEPROMRFGainVal);
8774 } else
8775 RTW_INFO("Using the default RF gain.\n");
8776
8777 #elif defined(CONFIG_RTL8188E)
8778 if (value & BIT4 || (registry_par->RegPwrTrimEnable == 1)) {
8779 RTW_INFO("8188ES Offset RF Gain.\n");
8780 RTW_INFO("8188ES Offset RF Gain. EEPROMRFGainVal=0x%x\n",
8781 pHalData->EEPROMRFGainVal);
8782
8783 if (pHalData->EEPROMRFGainVal != 0xff) {
8784 res = rtw_hal_read_rfreg(padapter, RF_PATH_A,
8785 REG_RF_BB_GAIN_OFFSET, 0xffffffff);
8786
8787 RTW_INFO("Offset RF Gain. reg 0x55=0x%x\n", res);
8788 res &= 0xfff87fff;
8789
8790 res |= (pHalData->EEPROMRFGainVal & 0x0f) << 15;
8791 RTW_INFO("Offset RF Gain. res=0x%x\n", res);
8792
8793 rtw_hal_write_rfreg(padapter, RF_PATH_A,
8794 REG_RF_BB_GAIN_OFFSET,
8795 RF_GAIN_OFFSET_MASK, res);
8796 } else {
8797 RTW_INFO("Offset RF Gain. EEPROMRFGainVal=0x%x == 0xff, didn't run Kfree\n",
8798 pHalData->EEPROMRFGainVal);
8799 }
8800 } else
8801 RTW_INFO("Using the default RF gain.\n");
8802 #else
8803 /* TODO: call this when channel switch */
8804 if (kfree_data->flag & KFREE_FLAG_ON)
8805 rtw_rf_apply_tx_gain_offset(padapter, 6); /* input ch6 to select BB_GAIN_2G */
8806 #endif
8807
8808 }
8809 #endif /*CONFIG_RF_POWER_TRIM */
8810
kfree_data_is_bb_gain_empty(struct kfree_data_t * data)8811 bool kfree_data_is_bb_gain_empty(struct kfree_data_t *data)
8812 {
8813 #ifdef CONFIG_RF_POWER_TRIM
8814 int i, j;
8815
8816 for (i = 0; i < BB_GAIN_NUM; i++)
8817 for (j = 0; j < RF_PATH_MAX; j++)
8818 if (data->bb_gain[i][j] != 0)
8819 return 0;
8820 #endif
8821 return 1;
8822 }
8823
8824 #ifdef CONFIG_USB_RX_AGGREGATION
rtw_set_usb_agg_by_mode_normal(_adapter * padapter,u8 cur_wireless_mode)8825 void rtw_set_usb_agg_by_mode_normal(_adapter *padapter, u8 cur_wireless_mode)
8826 {
8827 HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);
8828 if (cur_wireless_mode < WIRELESS_11_24N
8829 && cur_wireless_mode > 0) { /* ABG mode */
8830 #ifdef CONFIG_PREALLOC_RX_SKB_BUFFER
8831 u32 remainder = 0;
8832 u8 quotient = 0;
8833
8834 remainder = MAX_RECVBUF_SZ % (4 * 1024);
8835 quotient = (u8)(MAX_RECVBUF_SZ >> 12);
8836
8837 if (quotient > 5) {
8838 pHalData->rxagg_usb_size = 0x6;
8839 pHalData->rxagg_usb_timeout = 0x10;
8840 } else {
8841 if (remainder >= 2048) {
8842 pHalData->rxagg_usb_size = quotient;
8843 pHalData->rxagg_usb_timeout = 0x10;
8844 } else {
8845 pHalData->rxagg_usb_size = (quotient - 1);
8846 pHalData->rxagg_usb_timeout = 0x10;
8847 }
8848 }
8849 #else /* !CONFIG_PREALLOC_RX_SKB_BUFFER */
8850 if (0x6 != pHalData->rxagg_usb_size || 0x10 != pHalData->rxagg_usb_timeout) {
8851 pHalData->rxagg_usb_size = 0x6;
8852 pHalData->rxagg_usb_timeout = 0x10;
8853 rtw_write16(padapter, REG_RXDMA_AGG_PG_TH,
8854 pHalData->rxagg_usb_size | (pHalData->rxagg_usb_timeout << 8));
8855 }
8856 #endif /* CONFIG_PREALLOC_RX_SKB_BUFFER */
8857
8858 } else if (cur_wireless_mode >= WIRELESS_11_24N
8859 && cur_wireless_mode <= WIRELESS_MODE_MAX) { /* N AC mode */
8860 #ifdef CONFIG_PREALLOC_RX_SKB_BUFFER
8861 u32 remainder = 0;
8862 u8 quotient = 0;
8863
8864 remainder = MAX_RECVBUF_SZ % (4 * 1024);
8865 quotient = (u8)(MAX_RECVBUF_SZ >> 12);
8866
8867 if (quotient > 5) {
8868 pHalData->rxagg_usb_size = 0x5;
8869 pHalData->rxagg_usb_timeout = 0x20;
8870 } else {
8871 if (remainder >= 2048) {
8872 pHalData->rxagg_usb_size = quotient;
8873 pHalData->rxagg_usb_timeout = 0x10;
8874 } else {
8875 pHalData->rxagg_usb_size = (quotient - 1);
8876 pHalData->rxagg_usb_timeout = 0x10;
8877 }
8878 }
8879 #else /* !CONFIG_PREALLOC_RX_SKB_BUFFER */
8880 if ((0x5 != pHalData->rxagg_usb_size) || (0x20 != pHalData->rxagg_usb_timeout)) {
8881 pHalData->rxagg_usb_size = 0x5;
8882 pHalData->rxagg_usb_timeout = 0x20;
8883 rtw_write16(padapter, REG_RXDMA_AGG_PG_TH,
8884 pHalData->rxagg_usb_size | (pHalData->rxagg_usb_timeout << 8));
8885 }
8886 #endif /* CONFIG_PREALLOC_RX_SKB_BUFFER */
8887
8888 } else {
8889 /* RTW_INFO("%s: Unknow wireless mode(0x%x)\n",__func__,padapter->mlmeextpriv.cur_wireless_mode); */
8890 }
8891 }
8892
rtw_set_usb_agg_by_mode_customer(_adapter * padapter,u8 cur_wireless_mode,u8 UsbDmaSize,u8 Legacy_UsbDmaSize)8893 void rtw_set_usb_agg_by_mode_customer(_adapter *padapter, u8 cur_wireless_mode, u8 UsbDmaSize, u8 Legacy_UsbDmaSize)
8894 {
8895 HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);
8896
8897 if (cur_wireless_mode < WIRELESS_11_24N
8898 && cur_wireless_mode > 0) { /* ABG mode */
8899 if (Legacy_UsbDmaSize != pHalData->rxagg_usb_size
8900 || 0x10 != pHalData->rxagg_usb_timeout) {
8901 pHalData->rxagg_usb_size = Legacy_UsbDmaSize;
8902 pHalData->rxagg_usb_timeout = 0x10;
8903 rtw_write16(padapter, REG_RXDMA_AGG_PG_TH,
8904 pHalData->rxagg_usb_size | (pHalData->rxagg_usb_timeout << 8));
8905 }
8906 } else if (cur_wireless_mode >= WIRELESS_11_24N
8907 && cur_wireless_mode <= WIRELESS_MODE_MAX) { /* N AC mode */
8908 if (UsbDmaSize != pHalData->rxagg_usb_size
8909 || 0x20 != pHalData->rxagg_usb_timeout) {
8910 pHalData->rxagg_usb_size = UsbDmaSize;
8911 pHalData->rxagg_usb_timeout = 0x20;
8912 rtw_write16(padapter, REG_RXDMA_AGG_PG_TH,
8913 pHalData->rxagg_usb_size | (pHalData->rxagg_usb_timeout << 8));
8914 }
8915 } else {
8916 /* RTW_INFO("%s: Unknown wireless mode(0x%x)\n",__func__,padapter->mlmeextpriv.cur_wireless_mode); */
8917 }
8918 }
8919
rtw_set_usb_agg_by_mode(_adapter * padapter,u8 cur_wireless_mode)8920 void rtw_set_usb_agg_by_mode(_adapter *padapter, u8 cur_wireless_mode)
8921 {
8922 #ifdef CONFIG_PLATFORM_NOVATEK_NT72668
8923 rtw_set_usb_agg_by_mode_customer(padapter, cur_wireless_mode, 0x3, 0x3);
8924 return;
8925 #endif /* CONFIG_PLATFORM_NOVATEK_NT72668 */
8926
8927 rtw_set_usb_agg_by_mode_normal(padapter, cur_wireless_mode);
8928 }
8929 #endif /* CONFIG_USB_RX_AGGREGATION */
8930
8931 /* To avoid RX affect TX throughput */
dm_DynamicUsbTxAgg(_adapter * padapter,u8 from_timer)8932 void dm_DynamicUsbTxAgg(_adapter *padapter, u8 from_timer)
8933 {
8934 struct dvobj_priv *pdvobjpriv = adapter_to_dvobj(padapter);
8935 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
8936 HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);
8937 u8 cur_wireless_mode = WIRELESS_INVALID;
8938
8939 #ifdef CONFIG_USB_RX_AGGREGATION
8940 if (IS_HARDWARE_TYPE_8821U(padapter)) { /* || IS_HARDWARE_TYPE_8192EU(padapter)) */
8941 /* This AGG_PH_TH only for UsbRxAggMode == USB_RX_AGG_USB */
8942 if ((pHalData->rxagg_mode == RX_AGG_USB) && (check_fwstate(pmlmepriv, _FW_LINKED) == _TRUE)) {
8943 if (pdvobjpriv->traffic_stat.cur_tx_tp > 2 && pdvobjpriv->traffic_stat.cur_rx_tp < 30)
8944 rtw_write16(padapter , REG_RXDMA_AGG_PG_TH , 0x1010);
8945 else if (pdvobjpriv->traffic_stat.last_tx_bytes > 220000 && pdvobjpriv->traffic_stat.cur_rx_tp < 30)
8946 rtw_write16(padapter , REG_RXDMA_AGG_PG_TH , 0x1006);
8947 else
8948 rtw_write16(padapter, REG_RXDMA_AGG_PG_TH, 0x2005); /* dmc agg th 20K */
8949
8950 /* RTW_INFO("TX_TP=%u, RX_TP=%u\n", pdvobjpriv->traffic_stat.cur_tx_tp, pdvobjpriv->traffic_stat.cur_rx_tp); */
8951 }
8952 } else if (IS_HARDWARE_TYPE_8812(padapter)) {
8953 #ifdef CONFIG_CONCURRENT_MODE
8954 u8 i;
8955 _adapter *iface;
8956 u8 bassocaed = _FALSE;
8957 struct mlme_ext_priv *mlmeext;
8958
8959 for (i = 0; i < pdvobjpriv->iface_nums; i++) {
8960 iface = pdvobjpriv->padapters[i];
8961 mlmeext = &iface->mlmeextpriv;
8962 if (rtw_linked_check(iface) == _TRUE) {
8963 if (mlmeext->cur_wireless_mode >= cur_wireless_mode)
8964 cur_wireless_mode = mlmeext->cur_wireless_mode;
8965 bassocaed = _TRUE;
8966 }
8967 }
8968 if (bassocaed)
8969 #endif
8970 rtw_set_usb_agg_by_mode(padapter, cur_wireless_mode);
8971 #ifdef CONFIG_PLATFORM_NOVATEK_NT72668
8972 } else {
8973 rtw_set_usb_agg_by_mode(padapter, cur_wireless_mode);
8974 #endif /* CONFIG_PLATFORM_NOVATEK_NT72668 */
8975 }
8976 #endif
8977 }
8978
8979 /* bus-agg check for SoftAP mode */
rtw_hal_busagg_qsel_check(_adapter * padapter,u8 pre_qsel,u8 next_qsel)8980 inline u8 rtw_hal_busagg_qsel_check(_adapter *padapter, u8 pre_qsel, u8 next_qsel)
8981 {
8982 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
8983 u8 chk_rst = _SUCCESS;
8984
8985 if (check_fwstate(pmlmepriv, WIFI_AP_STATE) != _TRUE)
8986 return chk_rst;
8987
8988 /* if((pre_qsel == 0xFF)||(next_qsel== 0xFF)) */
8989 /* return chk_rst; */
8990
8991 if (((pre_qsel == QSLT_HIGH) || ((next_qsel == QSLT_HIGH)))
8992 && (pre_qsel != next_qsel)) {
8993 /* RTW_INFO("### bus-agg break cause of qsel misatch, pre_qsel=0x%02x,next_qsel=0x%02x ###\n", */
8994 /* pre_qsel,next_qsel); */
8995 chk_rst = _FAIL;
8996 }
8997 return chk_rst;
8998 }
8999
9000 /*
9001 * Description:
9002 * dump_TX_FIFO: This is only used to dump TX_FIFO for debug WoW mode offload
9003 * contant.
9004 *
9005 * Input:
9006 * adapter: adapter pointer.
9007 * page_num: The max. page number that user want to dump.
9008 * page_size: page size of each page. eg. 128 bytes, 256 bytes, 512byte.
9009 */
dump_TX_FIFO(_adapter * padapter,u8 page_num,u16 page_size)9010 void dump_TX_FIFO(_adapter *padapter, u8 page_num, u16 page_size)
9011 {
9012
9013 int i;
9014 u8 val = 0;
9015 u8 base = 0;
9016 u32 addr = 0;
9017 u32 count = (page_size / 8);
9018
9019 if (page_num <= 0) {
9020 RTW_INFO("!!%s: incorrect input page_num paramter!\n", __func__);
9021 return;
9022 }
9023
9024 if (page_size < 128 || page_size > 512) {
9025 RTW_INFO("!!%s: incorrect input page_size paramter!\n", __func__);
9026 return;
9027 }
9028
9029 RTW_INFO("+%s+\n", __func__);
9030 val = rtw_read8(padapter, 0x106);
9031 rtw_write8(padapter, 0x106, 0x69);
9032 RTW_INFO("0x106: 0x%02x\n", val);
9033 base = rtw_read8(padapter, 0x209);
9034 RTW_INFO("0x209: 0x%02x\n", base);
9035
9036 addr = ((base)*page_size) / 8;
9037 for (i = 0 ; i < page_num * count ; i += 2) {
9038 rtw_write32(padapter, 0x140, addr + i);
9039 printk(" %08x %08x ", rtw_read32(padapter, 0x144), rtw_read32(padapter, 0x148));
9040 rtw_write32(padapter, 0x140, addr + i + 1);
9041 printk(" %08x %08x\n", rtw_read32(padapter, 0x144), rtw_read32(padapter, 0x148));
9042 }
9043 }
9044
9045 #ifdef CONFIG_GPIO_API
rtw_hal_get_gpio(_adapter * adapter,u8 gpio_num)9046 u8 rtw_hal_get_gpio(_adapter *adapter, u8 gpio_num)
9047 {
9048 u8 value = 0;
9049 u8 direction = 0;
9050 u32 gpio_ctrl_reg_to_set = REG_GPIO_PIN_CTRL + 2;
9051 u8 gpio_num_to_set = gpio_num;
9052 struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(adapter);
9053
9054 if (rtw_hal_gpio_func_check(adapter, gpio_num) == _FAIL)
9055 return value;
9056
9057 rtw_ps_deny(adapter, PS_DENY_IOCTL);
9058
9059 RTW_INFO("rf_pwrstate=0x%02x\n", pwrpriv->rf_pwrstate);
9060 LeaveAllPowerSaveModeDirect(adapter);
9061
9062 if (gpio_num > 7) {
9063 gpio_ctrl_reg_to_set = REG_GPIO_PIN_CTRL_2 + 2;
9064 gpio_num_to_set = gpio_num - 8;
9065 }
9066
9067 /* Read GPIO Direction */
9068 direction = (rtw_read8(adapter, gpio_ctrl_reg_to_set) & BIT(gpio_num_to_set)) >> gpio_num;
9069
9070 /* According the direction to read register value */
9071 if (direction)
9072 value = (rtw_read8(adapter, gpio_ctrl_reg_to_set) & BIT(gpio_num_to_set)) >> gpio_num;
9073 else
9074 value = (rtw_read8(adapter, gpio_ctrl_reg_to_set) & BIT(gpio_num_to_set)) >> gpio_num;
9075
9076 rtw_ps_deny_cancel(adapter, PS_DENY_IOCTL);
9077 RTW_INFO("%s direction=%d value=%d\n", __FUNCTION__, direction, value);
9078
9079 return value;
9080 }
9081
rtw_hal_set_gpio_output_value(_adapter * adapter,u8 gpio_num,bool isHigh)9082 int rtw_hal_set_gpio_output_value(_adapter *adapter, u8 gpio_num, bool isHigh)
9083 {
9084 u8 direction = 0;
9085 u8 res = -1;
9086 u32 gpio_ctrl_reg_to_set = REG_GPIO_PIN_CTRL + 2;
9087 u8 gpio_num_to_set = gpio_num;
9088
9089 if (rtw_hal_gpio_func_check(adapter, gpio_num) == _FAIL)
9090 return -1;
9091
9092 rtw_ps_deny(adapter, PS_DENY_IOCTL);
9093
9094 LeaveAllPowerSaveModeDirect(adapter);
9095
9096 if (gpio_num > 7) {
9097 gpio_ctrl_reg_to_set = REG_GPIO_PIN_CTRL_2 + 2;
9098 gpio_num_to_set = gpio_num - 8;
9099 }
9100
9101 /* Read GPIO direction */
9102 direction = (rtw_read8(adapter, REG_GPIO_PIN_CTRL + 2) & BIT(gpio_num)) >> gpio_num;
9103
9104 /* If GPIO is output direction, setting value. */
9105 if (direction) {
9106 if (isHigh)
9107 rtw_write8(adapter, gpio_ctrl_reg_to_set, rtw_read8(adapter, gpio_ctrl_reg_to_set) | BIT(gpio_num_to_set));
9108 else
9109 rtw_write8(adapter, gpio_ctrl_reg_to_set, rtw_read8(adapter, gpio_ctrl_reg_to_set) & ~BIT(gpio_num_to_set));
9110
9111 RTW_INFO("%s Set gpio %x[%d]=%d\n", __FUNCTION__, REG_GPIO_PIN_CTRL + 1, gpio_num, isHigh);
9112 res = 0;
9113 } else {
9114 RTW_INFO("%s The gpio is input,not be set!\n", __FUNCTION__);
9115 res = -1;
9116 }
9117
9118 rtw_ps_deny_cancel(adapter, PS_DENY_IOCTL);
9119 return res;
9120 }
9121
rtw_hal_config_gpio(_adapter * adapter,u8 gpio_num,bool isOutput)9122 int rtw_hal_config_gpio(_adapter *adapter, u8 gpio_num, bool isOutput)
9123 {
9124 u32 gpio_ctrl_reg_to_set = REG_GPIO_PIN_CTRL + 2;
9125 u8 gpio_num_to_set = gpio_num;
9126
9127 if (rtw_hal_gpio_func_check(adapter, gpio_num) == _FAIL)
9128 return -1;
9129
9130 RTW_INFO("%s gpio_num =%d direction=%d\n", __FUNCTION__, gpio_num, isOutput);
9131
9132 rtw_ps_deny(adapter, PS_DENY_IOCTL);
9133
9134 LeaveAllPowerSaveModeDirect(adapter);
9135
9136 rtw_hal_gpio_multi_func_reset(adapter, gpio_num);
9137
9138 if (gpio_num > 7) {
9139 gpio_ctrl_reg_to_set = REG_GPIO_PIN_CTRL_2 + 2;
9140 gpio_num_to_set = gpio_num - 8;
9141 }
9142
9143 if (isOutput)
9144 rtw_write8(adapter, gpio_ctrl_reg_to_set, rtw_read8(adapter, gpio_ctrl_reg_to_set) | BIT(gpio_num_to_set));
9145 else
9146 rtw_write8(adapter, gpio_ctrl_reg_to_set, rtw_read8(adapter, gpio_ctrl_reg_to_set) & ~BIT(gpio_num_to_set));
9147
9148 rtw_ps_deny_cancel(adapter, PS_DENY_IOCTL);
9149
9150 return 0;
9151 }
rtw_hal_register_gpio_interrupt(_adapter * adapter,int gpio_num,void (* callback)(u8 level))9152 int rtw_hal_register_gpio_interrupt(_adapter *adapter, int gpio_num, void(*callback)(u8 level))
9153 {
9154 u8 value;
9155 u8 direction;
9156 PHAL_DATA_TYPE phal = GET_HAL_DATA(adapter);
9157
9158 if (IS_HARDWARE_TYPE_8188E(adapter)) {
9159 if (gpio_num > 7 || gpio_num < 4) {
9160 RTW_PRINT("%s The gpio number does not included 4~7.\n", __FUNCTION__);
9161 return -1;
9162 }
9163 }
9164
9165 rtw_ps_deny(adapter, PS_DENY_IOCTL);
9166
9167 LeaveAllPowerSaveModeDirect(adapter);
9168
9169 /* Read GPIO direction */
9170 direction = (rtw_read8(adapter, REG_GPIO_PIN_CTRL + 2) & BIT(gpio_num)) >> gpio_num;
9171 if (direction) {
9172 RTW_PRINT("%s Can't register output gpio as interrupt.\n", __FUNCTION__);
9173 return -1;
9174 }
9175
9176 /* Config GPIO Mode */
9177 rtw_write8(adapter, REG_GPIO_PIN_CTRL + 3, rtw_read8(adapter, REG_GPIO_PIN_CTRL + 3) | BIT(gpio_num));
9178
9179 /* Register GPIO interrupt handler*/
9180 adapter->gpiointpriv.callback[gpio_num] = callback;
9181
9182 /* Set GPIO interrupt mode, 0:positive edge, 1:negative edge */
9183 value = rtw_read8(adapter, REG_GPIO_PIN_CTRL) & BIT(gpio_num);
9184 adapter->gpiointpriv.interrupt_mode = rtw_read8(adapter, REG_HSIMR + 2) ^ value;
9185 rtw_write8(adapter, REG_GPIO_INTM, adapter->gpiointpriv.interrupt_mode);
9186
9187 /* Enable GPIO interrupt */
9188 adapter->gpiointpriv.interrupt_enable_mask = rtw_read8(adapter, REG_HSIMR + 2) | BIT(gpio_num);
9189 rtw_write8(adapter, REG_HSIMR + 2, adapter->gpiointpriv.interrupt_enable_mask);
9190
9191 rtw_hal_update_hisr_hsisr_ind(adapter, 1);
9192
9193 rtw_ps_deny_cancel(adapter, PS_DENY_IOCTL);
9194
9195 return 0;
9196 }
rtw_hal_disable_gpio_interrupt(_adapter * adapter,int gpio_num)9197 int rtw_hal_disable_gpio_interrupt(_adapter *adapter, int gpio_num)
9198 {
9199 u8 value;
9200 u8 direction;
9201 PHAL_DATA_TYPE phal = GET_HAL_DATA(adapter);
9202
9203 if (IS_HARDWARE_TYPE_8188E(adapter)) {
9204 if (gpio_num > 7 || gpio_num < 4) {
9205 RTW_INFO("%s The gpio number does not included 4~7.\n", __FUNCTION__);
9206 return -1;
9207 }
9208 }
9209
9210 rtw_ps_deny(adapter, PS_DENY_IOCTL);
9211
9212 LeaveAllPowerSaveModeDirect(adapter);
9213
9214 /* Config GPIO Mode */
9215 rtw_write8(adapter, REG_GPIO_PIN_CTRL + 3, rtw_read8(adapter, REG_GPIO_PIN_CTRL + 3) & ~BIT(gpio_num));
9216
9217 /* Unregister GPIO interrupt handler*/
9218 adapter->gpiointpriv.callback[gpio_num] = NULL;
9219
9220 /* Reset GPIO interrupt mode, 0:positive edge, 1:negative edge */
9221 adapter->gpiointpriv.interrupt_mode = rtw_read8(adapter, REG_GPIO_INTM) & ~BIT(gpio_num);
9222 rtw_write8(adapter, REG_GPIO_INTM, 0x00);
9223
9224 /* Disable GPIO interrupt */
9225 adapter->gpiointpriv.interrupt_enable_mask = rtw_read8(adapter, REG_HSIMR + 2) & ~BIT(gpio_num);
9226 rtw_write8(adapter, REG_HSIMR + 2, adapter->gpiointpriv.interrupt_enable_mask);
9227
9228 if (!adapter->gpiointpriv.interrupt_enable_mask)
9229 rtw_hal_update_hisr_hsisr_ind(adapter, 0);
9230
9231 rtw_ps_deny_cancel(adapter, PS_DENY_IOCTL);
9232
9233 return 0;
9234 }
9235 #endif
9236
rtw_hal_ch_sw_iqk_info_search(_adapter * padapter,u8 central_chnl,u8 bw_mode)9237 s8 rtw_hal_ch_sw_iqk_info_search(_adapter *padapter, u8 central_chnl, u8 bw_mode)
9238 {
9239 HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);
9240 u8 i;
9241
9242 for (i = 0; i < MAX_IQK_INFO_BACKUP_CHNL_NUM; i++) {
9243 if ((pHalData->iqk_reg_backup[i].central_chnl != 0)) {
9244 if ((pHalData->iqk_reg_backup[i].central_chnl == central_chnl)
9245 && (pHalData->iqk_reg_backup[i].bw_mode == bw_mode))
9246 return i;
9247 }
9248 }
9249
9250 return -1;
9251 }
9252
rtw_hal_ch_sw_iqk_info_backup(_adapter * padapter)9253 void rtw_hal_ch_sw_iqk_info_backup(_adapter *padapter)
9254 {
9255 HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);
9256 s8 res;
9257 u8 i;
9258
9259 /* If it's an existed record, overwrite it */
9260 res = rtw_hal_ch_sw_iqk_info_search(padapter, pHalData->CurrentChannel, pHalData->CurrentChannelBW);
9261 if ((res >= 0) && (res < MAX_IQK_INFO_BACKUP_CHNL_NUM)) {
9262 rtw_hal_set_hwreg(padapter, HW_VAR_CH_SW_IQK_INFO_BACKUP, (u8 *)&(pHalData->iqk_reg_backup[res]));
9263 return;
9264 }
9265
9266 /* Search for the empty record to use */
9267 for (i = 0; i < MAX_IQK_INFO_BACKUP_CHNL_NUM; i++) {
9268 if (pHalData->iqk_reg_backup[i].central_chnl == 0) {
9269 rtw_hal_set_hwreg(padapter, HW_VAR_CH_SW_IQK_INFO_BACKUP, (u8 *)&(pHalData->iqk_reg_backup[i]));
9270 return;
9271 }
9272 }
9273
9274 /* Else, overwrite the oldest record */
9275 for (i = 1; i < MAX_IQK_INFO_BACKUP_CHNL_NUM; i++)
9276 _rtw_memcpy(&(pHalData->iqk_reg_backup[i - 1]), &(pHalData->iqk_reg_backup[i]), sizeof(struct hal_iqk_reg_backup));
9277
9278 rtw_hal_set_hwreg(padapter, HW_VAR_CH_SW_IQK_INFO_BACKUP, (u8 *)&(pHalData->iqk_reg_backup[MAX_IQK_INFO_BACKUP_CHNL_NUM - 1]));
9279 }
9280
rtw_hal_ch_sw_iqk_info_restore(_adapter * padapter,u8 ch_sw_use_case)9281 void rtw_hal_ch_sw_iqk_info_restore(_adapter *padapter, u8 ch_sw_use_case)
9282 {
9283 rtw_hal_set_hwreg(padapter, HW_VAR_CH_SW_IQK_INFO_RESTORE, &ch_sw_use_case);
9284 }
9285
rtw_dump_mac_rx_counters(_adapter * padapter,struct dbg_rx_counter * rx_counter)9286 void rtw_dump_mac_rx_counters(_adapter *padapter, struct dbg_rx_counter *rx_counter)
9287 {
9288 u32 mac_cck_ok = 0, mac_ofdm_ok = 0, mac_ht_ok = 0, mac_vht_ok = 0;
9289 u32 mac_cck_err = 0, mac_ofdm_err = 0, mac_ht_err = 0, mac_vht_err = 0;
9290 u32 mac_cck_fa = 0, mac_ofdm_fa = 0, mac_ht_fa = 0;
9291 u32 DropPacket = 0;
9292
9293 if (!rx_counter) {
9294 rtw_warn_on(1);
9295 return;
9296 }
9297 if (IS_HARDWARE_TYPE_JAGUAR(padapter) || IS_HARDWARE_TYPE_JAGUAR2(padapter))
9298 PHY_SetMacReg(padapter, REG_RXERR_RPT, BIT26, 0x0);/*clear bit-26*/
9299
9300 PHY_SetMacReg(padapter, REG_RXERR_RPT, BIT28 | BIT29 | BIT30 | BIT31, 0x3);
9301 mac_cck_ok = PHY_QueryMacReg(padapter, REG_RXERR_RPT, bMaskLWord);/* [15:0] */
9302 PHY_SetMacReg(padapter, REG_RXERR_RPT, BIT28 | BIT29 | BIT30 | BIT31, 0x0);
9303 mac_ofdm_ok = PHY_QueryMacReg(padapter, REG_RXERR_RPT, bMaskLWord);/* [15:0] */
9304 PHY_SetMacReg(padapter, REG_RXERR_RPT, BIT28 | BIT29 | BIT30 | BIT31, 0x6);
9305 mac_ht_ok = PHY_QueryMacReg(padapter, REG_RXERR_RPT, bMaskLWord);/* [15:0] */
9306 mac_vht_ok = 0;
9307 if (IS_HARDWARE_TYPE_JAGUAR(padapter) || IS_HARDWARE_TYPE_JAGUAR2(padapter)) {
9308 PHY_SetMacReg(padapter, REG_RXERR_RPT, BIT28 | BIT29 | BIT30 | BIT31, 0x0);
9309 PHY_SetMacReg(padapter, REG_RXERR_RPT, BIT26, 0x1);
9310 mac_vht_ok = PHY_QueryMacReg(padapter, REG_RXERR_RPT, bMaskLWord);/* [15:0]*/
9311 PHY_SetMacReg(padapter, REG_RXERR_RPT, BIT26, 0x0);/*clear bit-26*/
9312 }
9313
9314 PHY_SetMacReg(padapter, REG_RXERR_RPT, BIT28 | BIT29 | BIT30 | BIT31, 0x4);
9315 mac_cck_err = PHY_QueryMacReg(padapter, REG_RXERR_RPT, bMaskLWord);/* [15:0] */
9316 PHY_SetMacReg(padapter, REG_RXERR_RPT, BIT28 | BIT29 | BIT30 | BIT31, 0x1);
9317 mac_ofdm_err = PHY_QueryMacReg(padapter, REG_RXERR_RPT, bMaskLWord);/* [15:0] */
9318 PHY_SetMacReg(padapter, REG_RXERR_RPT, BIT28 | BIT29 | BIT30 | BIT31, 0x7);
9319 mac_ht_err = PHY_QueryMacReg(padapter, REG_RXERR_RPT, bMaskLWord);/* [15:0] */
9320 mac_vht_err = 0;
9321 if (IS_HARDWARE_TYPE_JAGUAR(padapter) || IS_HARDWARE_TYPE_JAGUAR2(padapter)) {
9322 PHY_SetMacReg(padapter, REG_RXERR_RPT, BIT28 | BIT29 | BIT30 | BIT31, 0x1);
9323 PHY_SetMacReg(padapter, REG_RXERR_RPT, BIT26, 0x1);
9324 mac_vht_err = PHY_QueryMacReg(padapter, REG_RXERR_RPT, bMaskLWord);/* [15:0]*/
9325 PHY_SetMacReg(padapter, REG_RXERR_RPT, BIT26, 0x0);/*clear bit-26*/
9326 }
9327
9328 PHY_SetMacReg(padapter, REG_RXERR_RPT, BIT28 | BIT29 | BIT30 | BIT31, 0x5);
9329 mac_cck_fa = PHY_QueryMacReg(padapter, REG_RXERR_RPT, bMaskLWord);/* [15:0] */
9330 PHY_SetMacReg(padapter, REG_RXERR_RPT, BIT28 | BIT29 | BIT30 | BIT31, 0x2);
9331 mac_ofdm_fa = PHY_QueryMacReg(padapter, REG_RXERR_RPT, bMaskLWord);/* [15:0] */
9332 PHY_SetMacReg(padapter, REG_RXERR_RPT, BIT28 | BIT29 | BIT30 | BIT31, 0x9);
9333 mac_ht_fa = PHY_QueryMacReg(padapter, REG_RXERR_RPT, bMaskLWord);/* [15:0] */
9334
9335 /* Mac_DropPacket */
9336 rtw_write32(padapter, REG_RXERR_RPT, (rtw_read32(padapter, REG_RXERR_RPT) & 0x0FFFFFFF) | Mac_DropPacket);
9337 DropPacket = rtw_read32(padapter, REG_RXERR_RPT) & 0x0000FFFF;
9338
9339 rx_counter->rx_pkt_ok = mac_cck_ok + mac_ofdm_ok + mac_ht_ok + mac_vht_ok;
9340 rx_counter->rx_pkt_crc_error = mac_cck_err + mac_ofdm_err + mac_ht_err + mac_vht_err;
9341 rx_counter->rx_cck_fa = mac_cck_fa;
9342 rx_counter->rx_ofdm_fa = mac_ofdm_fa;
9343 rx_counter->rx_ht_fa = mac_ht_fa;
9344 rx_counter->rx_pkt_drop = DropPacket;
9345 }
rtw_reset_mac_rx_counters(_adapter * padapter)9346 void rtw_reset_mac_rx_counters(_adapter *padapter)
9347 {
9348
9349 /* If no packet rx, MaxRx clock be gating ,BIT_DISGCLK bit19 set 1 for fix*/
9350 if (IS_HARDWARE_TYPE_8703B(padapter) ||
9351 IS_HARDWARE_TYPE_8723D(padapter) ||
9352 IS_HARDWARE_TYPE_8188F(padapter))
9353 PHY_SetMacReg(padapter, REG_RCR, BIT19, 0x1);
9354
9355 /* reset mac counter */
9356 PHY_SetMacReg(padapter, REG_RXERR_RPT, BIT27, 0x1);
9357 PHY_SetMacReg(padapter, REG_RXERR_RPT, BIT27, 0x0);
9358 }
9359
rtw_dump_phy_rx_counters(_adapter * padapter,struct dbg_rx_counter * rx_counter)9360 void rtw_dump_phy_rx_counters(_adapter *padapter, struct dbg_rx_counter *rx_counter)
9361 {
9362 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;
9363 if (!rx_counter) {
9364 rtw_warn_on(1);
9365 return;
9366 }
9367 if (IS_HARDWARE_TYPE_JAGUAR(padapter) || IS_HARDWARE_TYPE_JAGUAR2(padapter)) {
9368 cckok = PHY_QueryBBReg(padapter, 0xF04, 0x3FFF); /* [13:0] */
9369 ofdmok = PHY_QueryBBReg(padapter, 0xF14, 0x3FFF); /* [13:0] */
9370 htok = PHY_QueryBBReg(padapter, 0xF10, 0x3FFF); /* [13:0] */
9371 vht_ok = PHY_QueryBBReg(padapter, 0xF0C, 0x3FFF); /* [13:0] */
9372 cckcrc = PHY_QueryBBReg(padapter, 0xF04, 0x3FFF0000); /* [29:16] */
9373 ofdmcrc = PHY_QueryBBReg(padapter, 0xF14, 0x3FFF0000); /* [29:16] */
9374 htcrc = PHY_QueryBBReg(padapter, 0xF10, 0x3FFF0000); /* [29:16] */
9375 vht_err = PHY_QueryBBReg(padapter, 0xF0C, 0x3FFF0000); /* [29:16] */
9376 CCK_FA = PHY_QueryBBReg(padapter, 0xA5C, bMaskLWord);
9377 OFDM_FA = PHY_QueryBBReg(padapter, 0xF48, bMaskLWord);
9378 } else {
9379 cckok = PHY_QueryBBReg(padapter, 0xF88, bMaskDWord);
9380 ofdmok = PHY_QueryBBReg(padapter, 0xF94, bMaskLWord);
9381 htok = PHY_QueryBBReg(padapter, 0xF90, bMaskLWord);
9382 vht_ok = 0;
9383 cckcrc = PHY_QueryBBReg(padapter, 0xF84, bMaskDWord);
9384 ofdmcrc = PHY_QueryBBReg(padapter, 0xF94, bMaskHWord);
9385 htcrc = PHY_QueryBBReg(padapter, 0xF90, bMaskHWord);
9386 vht_err = 0;
9387 OFDM_FA = PHY_QueryBBReg(padapter, 0xCF0, bMaskLWord) + PHY_QueryBBReg(padapter, 0xCF2, bMaskLWord) +
9388 PHY_QueryBBReg(padapter, 0xDA2, bMaskLWord) + PHY_QueryBBReg(padapter, 0xDA4, bMaskLWord) +
9389 PHY_QueryBBReg(padapter, 0xDA6, bMaskLWord) + PHY_QueryBBReg(padapter, 0xDA8, bMaskLWord);
9390
9391 CCK_FA = (rtw_read8(padapter, 0xA5B) << 8) | (rtw_read8(padapter, 0xA5C));
9392 }
9393
9394 rx_counter->rx_pkt_ok = cckok + ofdmok + htok + vht_ok;
9395 rx_counter->rx_pkt_crc_error = cckcrc + ofdmcrc + htcrc + vht_err;
9396 rx_counter->rx_ofdm_fa = OFDM_FA;
9397 rx_counter->rx_cck_fa = CCK_FA;
9398
9399 }
9400
rtw_reset_phy_trx_ok_counters(_adapter * padapter)9401 void rtw_reset_phy_trx_ok_counters(_adapter *padapter)
9402 {
9403 if (IS_HARDWARE_TYPE_JAGUAR(padapter) || IS_HARDWARE_TYPE_JAGUAR2(padapter)) {
9404 PHY_SetBBReg(padapter, 0xB58, BIT0, 0x1);
9405 PHY_SetBBReg(padapter, 0xB58, BIT0, 0x0);
9406 }
9407 }
rtw_reset_phy_rx_counters(_adapter * padapter)9408 void rtw_reset_phy_rx_counters(_adapter *padapter)
9409 {
9410 /* reset phy counter */
9411 if (IS_HARDWARE_TYPE_JAGUAR(padapter) || IS_HARDWARE_TYPE_JAGUAR2(padapter)) {
9412 rtw_reset_phy_trx_ok_counters(padapter);
9413
9414 PHY_SetBBReg(padapter, 0x9A4, BIT17, 0x1);/* reset OFDA FA counter */
9415 PHY_SetBBReg(padapter, 0x9A4, BIT17, 0x0);
9416
9417 PHY_SetBBReg(padapter, 0xA2C, BIT15, 0x0);/* reset CCK FA counter */
9418 PHY_SetBBReg(padapter, 0xA2C, BIT15, 0x1);
9419 } else {
9420 PHY_SetBBReg(padapter, 0xF14, BIT16, 0x1);
9421 rtw_msleep_os(10);
9422 PHY_SetBBReg(padapter, 0xF14, BIT16, 0x0);
9423
9424 PHY_SetBBReg(padapter, 0xD00, BIT27, 0x1);/* reset OFDA FA counter */
9425 PHY_SetBBReg(padapter, 0xC0C, BIT31, 0x1);/* reset OFDA FA counter */
9426 PHY_SetBBReg(padapter, 0xD00, BIT27, 0x0);
9427 PHY_SetBBReg(padapter, 0xC0C, BIT31, 0x0);
9428
9429 PHY_SetBBReg(padapter, 0xA2C, BIT15, 0x0);/* reset CCK FA counter */
9430 PHY_SetBBReg(padapter, 0xA2C, BIT15, 0x1);
9431 }
9432 }
9433 #ifdef DBG_RX_COUNTER_DUMP
rtw_dump_drv_rx_counters(_adapter * padapter,struct dbg_rx_counter * rx_counter)9434 void rtw_dump_drv_rx_counters(_adapter *padapter, struct dbg_rx_counter *rx_counter)
9435 {
9436 struct recv_priv *precvpriv = &padapter->recvpriv;
9437 if (!rx_counter) {
9438 rtw_warn_on(1);
9439 return;
9440 }
9441 rx_counter->rx_pkt_ok = padapter->drv_rx_cnt_ok;
9442 rx_counter->rx_pkt_crc_error = padapter->drv_rx_cnt_crcerror;
9443 rx_counter->rx_pkt_drop = precvpriv->rx_drop - padapter->drv_rx_cnt_drop;
9444 }
rtw_reset_drv_rx_counters(_adapter * padapter)9445 void rtw_reset_drv_rx_counters(_adapter *padapter)
9446 {
9447 struct recv_priv *precvpriv = &padapter->recvpriv;
9448 padapter->drv_rx_cnt_ok = 0;
9449 padapter->drv_rx_cnt_crcerror = 0;
9450 padapter->drv_rx_cnt_drop = precvpriv->rx_drop;
9451 }
rtw_dump_phy_rxcnts_preprocess(_adapter * padapter,u8 rx_cnt_mode)9452 void rtw_dump_phy_rxcnts_preprocess(_adapter *padapter, u8 rx_cnt_mode)
9453 {
9454 u8 initialgain;
9455 HAL_DATA_TYPE *hal_data = GET_HAL_DATA(padapter);
9456
9457 if ((!(padapter->dump_rx_cnt_mode & DUMP_PHY_RX_COUNTER)) && (rx_cnt_mode & DUMP_PHY_RX_COUNTER)) {
9458 rtw_hal_get_odm_var(padapter, HAL_ODM_INITIAL_GAIN, &initialgain, NULL);
9459 RTW_INFO("%s CurIGValue:0x%02x\n", __FUNCTION__, initialgain);
9460 rtw_hal_set_odm_var(padapter, HAL_ODM_INITIAL_GAIN, &initialgain, _FALSE);
9461 /*disable dynamic functions, such as high power, DIG*/
9462 rtw_phydm_ability_backup(padapter);
9463 rtw_phydm_func_clr(padapter, (ODM_BB_DIG | ODM_BB_FA_CNT));
9464 } else if ((padapter->dump_rx_cnt_mode & DUMP_PHY_RX_COUNTER) && (!(rx_cnt_mode & DUMP_PHY_RX_COUNTER))) {
9465 /* turn on phy-dynamic functions */
9466 rtw_phydm_ability_restore(padapter);
9467 initialgain = 0xff; /* restore RX GAIN */
9468 rtw_hal_set_odm_var(padapter, HAL_ODM_INITIAL_GAIN, &initialgain, _FALSE);
9469
9470 }
9471 }
9472
rtw_dump_rx_counters(_adapter * padapter)9473 void rtw_dump_rx_counters(_adapter *padapter)
9474 {
9475 struct dbg_rx_counter rx_counter;
9476
9477 if (padapter->dump_rx_cnt_mode & DUMP_DRV_RX_COUNTER) {
9478 _rtw_memset(&rx_counter, 0, sizeof(struct dbg_rx_counter));
9479 rtw_dump_drv_rx_counters(padapter, &rx_counter);
9480 RTW_INFO("Drv Received packet OK:%d CRC error:%d Drop Packets: %d\n",
9481 rx_counter.rx_pkt_ok, rx_counter.rx_pkt_crc_error, rx_counter.rx_pkt_drop);
9482 rtw_reset_drv_rx_counters(padapter);
9483 }
9484
9485 if (padapter->dump_rx_cnt_mode & DUMP_MAC_RX_COUNTER) {
9486 _rtw_memset(&rx_counter, 0, sizeof(struct dbg_rx_counter));
9487 rtw_dump_mac_rx_counters(padapter, &rx_counter);
9488 RTW_INFO("Mac Received packet OK:%d CRC error:%d FA Counter: %d Drop Packets: %d\n",
9489 rx_counter.rx_pkt_ok, rx_counter.rx_pkt_crc_error,
9490 rx_counter.rx_cck_fa + rx_counter.rx_ofdm_fa + rx_counter.rx_ht_fa,
9491 rx_counter.rx_pkt_drop);
9492 rtw_reset_mac_rx_counters(padapter);
9493 }
9494
9495 if (padapter->dump_rx_cnt_mode & DUMP_PHY_RX_COUNTER) {
9496 _rtw_memset(&rx_counter, 0, sizeof(struct dbg_rx_counter));
9497 rtw_dump_phy_rx_counters(padapter, &rx_counter);
9498 /* RTW_INFO("%s: OFDM_FA =%d\n", __FUNCTION__, rx_counter.rx_ofdm_fa); */
9499 /* RTW_INFO("%s: CCK_FA =%d\n", __FUNCTION__, rx_counter.rx_cck_fa); */
9500 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,
9501 rx_counter.rx_ofdm_fa + rx_counter.rx_cck_fa);
9502 rtw_reset_phy_rx_counters(padapter);
9503 }
9504 }
9505 #endif
rtw_get_noise(_adapter * padapter)9506 void rtw_get_noise(_adapter *padapter)
9507 {
9508 #if defined(CONFIG_SIGNAL_DISPLAY_DBM) && defined(CONFIG_BACKGROUND_NOISE_MONITOR)
9509 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
9510 struct noise_info info;
9511 if (rtw_linked_check(padapter)) {
9512 info.bPauseDIG = _TRUE;
9513 info.IGIValue = 0x1e;
9514 info.max_time = 100;/* ms */
9515 info.chan = pmlmeext->cur_channel ;/* rtw_get_oper_ch(padapter); */
9516 rtw_ps_deny(padapter, PS_DENY_IOCTL);
9517 LeaveAllPowerSaveModeDirect(padapter);
9518
9519 rtw_hal_set_odm_var(padapter, HAL_ODM_NOISE_MONITOR, &info, _FALSE);
9520 /* ODM_InbandNoise_Monitor(podmpriv,_TRUE,0x20,100); */
9521 rtw_ps_deny_cancel(padapter, PS_DENY_IOCTL);
9522 rtw_hal_get_odm_var(padapter, HAL_ODM_NOISE_MONITOR, &(info.chan), &(padapter->recvpriv.noise));
9523 #ifdef DBG_NOISE_MONITOR
9524 RTW_INFO("chan:%d,noise_level:%d\n", info.chan, padapter->recvpriv.noise);
9525 #endif
9526 }
9527 #endif
9528
9529 }
rtw_get_current_tx_sgi(_adapter * padapter,u8 macid)9530 u8 rtw_get_current_tx_sgi(_adapter *padapter, u8 macid)
9531 {
9532 HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);
9533 PDM_ODM_T pDM_Odm = &pHalData->odmpriv;
9534 pRA_T pRA_Table = &pDM_Odm->DM_RA_Table;
9535 u8 curr_tx_sgi = 0;
9536
9537 #if defined(CONFIG_RTL8188E)
9538 curr_tx_sgi = ODM_RA_GetDecisionRate_8188E(pDM_Odm, macid);
9539 #else
9540 curr_tx_sgi = ((pRA_Table->link_tx_rate[macid]) & 0x80) >> 7;
9541 #endif
9542
9543 return curr_tx_sgi;
9544
9545 }
rtw_get_current_tx_rate(_adapter * padapter,u8 macid)9546 u8 rtw_get_current_tx_rate(_adapter *padapter, u8 macid)
9547 {
9548 HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);
9549 PDM_ODM_T pDM_Odm = &pHalData->odmpriv;
9550 pRA_T pRA_Table = &pDM_Odm->DM_RA_Table;
9551 u8 rate_id = 0;
9552
9553 #if (RATE_ADAPTIVE_SUPPORT == 1)
9554 rate_id = ODM_RA_GetDecisionRate_8188E(pDM_Odm, macid);
9555 #else
9556 rate_id = (pRA_Table->link_tx_rate[macid]) & 0x7f;
9557 #endif
9558
9559 return rate_id;
9560
9561 }
9562
9563 #ifdef CONFIG_FW_C2H_DEBUG
9564
9565 /* C2H RX package original is 128.
9566 if enable CONFIG_FW_C2H_DEBUG, it should increase to 256.
9567 C2H FW debug message:
9568 without aggregate:
9569 {C2H_CmdID,Seq,SubID,Len,Content[0~n]}
9570 Content[0~n]={'a','b','c',...,'z','\n'}
9571 with aggregate:
9572 {C2H_CmdID,Seq,SubID,Len,Content[0~n]}
9573 Content[0~n]={'a','b','c',...,'z','\n',Extend C2H pkt 2...}
9574 Extend C2H pkt 2={C2H CmdID,Seq,SubID,Len,Content = {'a','b','c',...,'z','\n'}}
9575 Author: Isaac */
9576
Debug_FwC2H(PADAPTER padapter,u8 * pdata,u8 len)9577 void Debug_FwC2H(PADAPTER padapter, u8 *pdata, u8 len)
9578 {
9579 int i = 0;
9580 int cnt = 0, total_length = 0;
9581 u8 buf[128] = {0};
9582 u8 more_data = _FALSE;
9583 u8 *nextdata = NULL;
9584 u8 test = 0;
9585
9586 u8 data_len;
9587 u8 seq_no;
9588
9589 nextdata = pdata;
9590 do {
9591 data_len = *(nextdata + 1);
9592 seq_no = *(nextdata + 2);
9593
9594 for (i = 0 ; i < data_len - 2 ; i++) {
9595 cnt += sprintf((buf + cnt), "%c", nextdata[3 + i]);
9596
9597 if (nextdata[3 + i] == 0x0a && nextdata[4 + i] == 0xff)
9598 more_data = _TRUE;
9599 else if (nextdata[3 + i] == 0x0a && nextdata[4 + i] != 0xff)
9600 more_data = _FALSE;
9601 }
9602
9603 RTW_INFO("[RTKFW, SEQ=%d]: %s", seq_no, buf);
9604 data_len += 3;
9605 total_length += data_len;
9606
9607 if (more_data == _TRUE) {
9608 _rtw_memset(buf, '\0', 128);
9609 cnt = 0;
9610 nextdata = (pdata + total_length);
9611 }
9612 } while (more_data == _TRUE);
9613 }
9614 #endif /*CONFIG_FW_C2H_DEBUG*/
update_IOT_info(_adapter * padapter)9615 void update_IOT_info(_adapter *padapter)
9616 {
9617 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
9618 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
9619
9620 switch (pmlmeinfo->assoc_AP_vendor) {
9621 case HT_IOT_PEER_MARVELL:
9622 pmlmeinfo->turboMode_cts2self = 1;
9623 pmlmeinfo->turboMode_rtsen = 0;
9624 break;
9625
9626 case HT_IOT_PEER_RALINK:
9627 pmlmeinfo->turboMode_cts2self = 0;
9628 pmlmeinfo->turboMode_rtsen = 1;
9629 /* disable high power */
9630 rtw_phydm_func_clr(padapter, ODM_BB_DYNAMIC_TXPWR);
9631 break;
9632 case HT_IOT_PEER_REALTEK:
9633 /* rtw_write16(padapter, 0x4cc, 0xffff); */
9634 /* rtw_write16(padapter, 0x546, 0x01c0); */
9635 /* disable high power */
9636 rtw_phydm_func_clr(padapter, ODM_BB_DYNAMIC_TXPWR);
9637 break;
9638 default:
9639 pmlmeinfo->turboMode_cts2self = 0;
9640 pmlmeinfo->turboMode_rtsen = 1;
9641 break;
9642 }
9643
9644 }
9645 #ifdef CONFIG_AUTO_CHNL_SEL_NHM
rtw_acs_start(_adapter * padapter,bool bStart)9646 void rtw_acs_start(_adapter *padapter, bool bStart)
9647 {
9648 if (_TRUE == bStart) {
9649 ACS_OP acs_op = ACS_INIT;
9650
9651 rtw_hal_set_odm_var(padapter, HAL_ODM_AUTO_CHNL_SEL, &acs_op, _TRUE);
9652 rtw_set_acs_channel(padapter, 0);
9653 SET_ACS_STATE(padapter, ACS_ENABLE);
9654 } else {
9655 SET_ACS_STATE(padapter, ACS_DISABLE);
9656 #ifdef DBG_AUTO_CHNL_SEL_NHM
9657 if (1) {
9658 u8 best_24g_ch = 0;
9659 u8 best_5g_ch = 0;
9660
9661 rtw_hal_get_odm_var(padapter, HAL_ODM_AUTO_CHNL_SEL, &(best_24g_ch), &(best_5g_ch));
9662 RTW_INFO("[ACS-"ADPT_FMT"] Best 2.4G CH:%u\n", ADPT_ARG(padapter), best_24g_ch);
9663 RTW_INFO("[ACS-"ADPT_FMT"] Best 5G CH:%u\n", ADPT_ARG(padapter), best_5g_ch);
9664 }
9665 #endif
9666 }
9667 }
9668 #endif
9669
9670 /* TODO: merge with phydm, see odm_SetCrystalCap() */
hal_set_crystal_cap(_adapter * adapter,u8 crystal_cap)9671 void hal_set_crystal_cap(_adapter *adapter, u8 crystal_cap)
9672 {
9673 crystal_cap = crystal_cap & 0x3F;
9674
9675 switch (rtw_get_chip_type(adapter)) {
9676 #if defined(CONFIG_RTL8188E) || defined(CONFIG_RTL8188F)
9677 case RTL8188E:
9678 case RTL8188F:
9679 /* write 0x24[16:11] = 0x24[22:17] = CrystalCap */
9680 PHY_SetBBReg(adapter, REG_AFE_XTAL_CTRL, 0x007FF800, (crystal_cap | (crystal_cap << 6)));
9681 break;
9682 #endif
9683 #if defined(CONFIG_RTL8812A)
9684 case RTL8812:
9685 /* write 0x2C[30:25] = 0x2C[24:19] = CrystalCap */
9686 PHY_SetBBReg(adapter, REG_MAC_PHY_CTRL, 0x7FF80000, (crystal_cap | (crystal_cap << 6)));
9687 break;
9688 #endif
9689 #if defined(CONFIG_RTL8723B) || defined(CONFIG_RTL8703B) || \
9690 defined(CONFIG_RTL8723D) || defined(CONFIG_RTL8821A) || \
9691 defined(CONFIG_RTL8192E)
9692 case RTL8723B:
9693 case RTL8703B:
9694 case RTL8723D:
9695 case RTL8821:
9696 case RTL8192E:
9697 /* write 0x2C[23:18] = 0x2C[17:12] = CrystalCap */
9698 PHY_SetBBReg(adapter, REG_MAC_PHY_CTRL, 0x00FFF000, (crystal_cap | (crystal_cap << 6)));
9699 break;
9700 #endif
9701 #if defined(CONFIG_RTL8814A)
9702 case RTL8814A:
9703 /* write 0x2C[26:21] = 0x2C[20:15] = CrystalCap*/
9704 PHY_SetBBReg(adapter, REG_MAC_PHY_CTRL, 0x07FF8000, (crystal_cap | (crystal_cap << 6)));
9705 break;
9706 #endif
9707 #if defined(CONFIG_RTL8822B) || defined(CONFIG_RTL8821C)
9708
9709 case RTL8822B:
9710 case RTL8821C:
9711 /* write 0x28[6:1] = 0x24[30:25] = CrystalCap */
9712 crystal_cap = crystal_cap & 0x3F;
9713 PHY_SetBBReg(adapter, REG_AFE_XTAL_CTRL, 0x7E000000, crystal_cap);
9714 PHY_SetBBReg(adapter, REG_AFE_PLL_CTRL, 0x7E, crystal_cap);
9715 break;
9716 #endif
9717 default:
9718 rtw_warn_on(1);
9719 }
9720 }
9721
hal_spec_init(_adapter * adapter)9722 int hal_spec_init(_adapter *adapter)
9723 {
9724 u8 interface_type = 0;
9725 int ret = _SUCCESS;
9726
9727 interface_type = rtw_get_intf_type(adapter);
9728
9729 switch (rtw_get_chip_type(adapter)) {
9730 #ifdef CONFIG_RTL8723B
9731 case RTL8723B:
9732 init_hal_spec_8723b(adapter);
9733 break;
9734 #endif
9735 #ifdef CONFIG_RTL8703B
9736 case RTL8703B:
9737 init_hal_spec_8703b(adapter);
9738 break;
9739 #endif
9740 #ifdef CONFIG_RTL8723D
9741 case RTL8723D:
9742 init_hal_spec_8723d(adapter);
9743 break;
9744 #endif
9745 #ifdef CONFIG_RTL8188E
9746 case RTL8188E:
9747 init_hal_spec_8188e(adapter);
9748 break;
9749 #endif
9750 #ifdef CONFIG_RTL8188F
9751 case RTL8188F:
9752 init_hal_spec_8188f(adapter);
9753 break;
9754 #endif
9755 #ifdef CONFIG_RTL8812A
9756 case RTL8812:
9757 init_hal_spec_8812a(adapter);
9758 break;
9759 #endif
9760 #ifdef CONFIG_RTL8821A
9761 case RTL8821:
9762 init_hal_spec_8821a(adapter);
9763 break;
9764 #endif
9765 #ifdef CONFIG_RTL8192E
9766 case RTL8192E:
9767 init_hal_spec_8192e(adapter);
9768 break;
9769 #endif
9770 #ifdef CONFIG_RTL8814A
9771 case RTL8814A:
9772 init_hal_spec_8814a(adapter);
9773 break;
9774 #endif
9775 #ifdef CONFIG_RTL8822B
9776 case RTL8822B:
9777 rtl8822b_init_hal_spec(adapter);
9778 break;
9779 #endif
9780 #ifdef CONFIG_RTL8821C
9781 case RTL8821C:
9782 init_hal_spec_rtl8821c(adapter);
9783 break;
9784 #endif
9785 default:
9786 RTW_ERR("%s: unknown chip_type:%u\n"
9787 , __func__, rtw_get_chip_type(adapter));
9788 ret = _FAIL;
9789 break;
9790 }
9791
9792 return ret;
9793 }
9794
9795 static const char *const _band_cap_str[] = {
9796 /* BIT0 */"2G",
9797 /* BIT1 */"5G",
9798 };
9799
9800 static const char *const _bw_cap_str[] = {
9801 /* BIT0 */"5M",
9802 /* BIT1 */"10M",
9803 /* BIT2 */"20M",
9804 /* BIT3 */"40M",
9805 /* BIT4 */"80M",
9806 /* BIT5 */"160M",
9807 /* BIT6 */"80_80M",
9808 };
9809
9810 static const char *const _proto_cap_str[] = {
9811 /* BIT0 */"b",
9812 /* BIT1 */"g",
9813 /* BIT2 */"n",
9814 /* BIT3 */"ac",
9815 };
9816
9817 static const char *const _wl_func_str[] = {
9818 /* BIT0 */"P2P",
9819 /* BIT1 */"MIRACAST",
9820 /* BIT2 */"TDLS",
9821 /* BIT3 */"FTM",
9822 };
9823
dump_hal_spec(void * sel,_adapter * adapter)9824 void dump_hal_spec(void *sel, _adapter *adapter)
9825 {
9826 struct hal_spec_t *hal_spec = GET_HAL_SPEC(adapter);
9827 int i;
9828
9829 RTW_PRINT_SEL(sel, "macid_num:%u\n", hal_spec->macid_num);
9830 RTW_PRINT_SEL(sel, "sec_cap:0x%02x\n", hal_spec->sec_cap);
9831 RTW_PRINT_SEL(sel, "sec_cam_ent_num:%u\n", hal_spec->sec_cam_ent_num);
9832 RTW_PRINT_SEL(sel, "nss_num:%u\n", hal_spec->nss_num);
9833
9834 RTW_PRINT_SEL(sel, "band_cap:");
9835 for (i = 0; i < BAND_CAP_BIT_NUM; i++) {
9836 if (((hal_spec->band_cap) >> i) & BIT0 && _band_cap_str[i])
9837 _RTW_PRINT_SEL(sel, "%s ", _band_cap_str[i]);
9838 }
9839 _RTW_PRINT_SEL(sel, "\n");
9840
9841 RTW_PRINT_SEL(sel, "bw_cap:");
9842 for (i = 0; i < BW_CAP_BIT_NUM; i++) {
9843 if (((hal_spec->bw_cap) >> i) & BIT0 && _bw_cap_str[i])
9844 _RTW_PRINT_SEL(sel, "%s ", _bw_cap_str[i]);
9845 }
9846 _RTW_PRINT_SEL(sel, "\n");
9847
9848 RTW_PRINT_SEL(sel, "proto_cap:");
9849 for (i = 0; i < PROTO_CAP_BIT_NUM; i++) {
9850 if (((hal_spec->proto_cap) >> i) & BIT0 && _proto_cap_str[i])
9851 _RTW_PRINT_SEL(sel, "%s ", _proto_cap_str[i]);
9852 }
9853 _RTW_PRINT_SEL(sel, "\n");
9854
9855 RTW_PRINT_SEL(sel, "wl_func:");
9856 for (i = 0; i < WL_FUNC_BIT_NUM; i++) {
9857 if (((hal_spec->wl_func) >> i) & BIT0 && _wl_func_str[i])
9858 _RTW_PRINT_SEL(sel, "%s ", _wl_func_str[i]);
9859 }
9860 _RTW_PRINT_SEL(sel, "\n");
9861 }
9862
hal_chk_band_cap(_adapter * adapter,u8 cap)9863 inline bool hal_chk_band_cap(_adapter *adapter, u8 cap)
9864 {
9865 return GET_HAL_SPEC(adapter)->band_cap & cap;
9866 }
9867
hal_chk_bw_cap(_adapter * adapter,u8 cap)9868 inline bool hal_chk_bw_cap(_adapter *adapter, u8 cap)
9869 {
9870 return GET_HAL_SPEC(adapter)->bw_cap & cap;
9871 }
9872
hal_chk_proto_cap(_adapter * adapter,u8 cap)9873 inline bool hal_chk_proto_cap(_adapter *adapter, u8 cap)
9874 {
9875 return GET_HAL_SPEC(adapter)->proto_cap & cap;
9876 }
9877
hal_chk_wl_func(_adapter * adapter,u8 func)9878 inline bool hal_chk_wl_func(_adapter *adapter, u8 func)
9879 {
9880 return GET_HAL_SPEC(adapter)->wl_func & func;
9881 }
9882
hal_is_band_support(_adapter * adapter,u8 band)9883 inline bool hal_is_band_support(_adapter *adapter, u8 band)
9884 {
9885 return GET_HAL_SPEC(adapter)->band_cap & band_to_band_cap(band);
9886 }
9887
hal_is_bw_support(_adapter * adapter,u8 bw)9888 inline bool hal_is_bw_support(_adapter *adapter, u8 bw)
9889 {
9890 return GET_HAL_SPEC(adapter)->bw_cap & ch_width_to_bw_cap(bw);
9891 }
9892
hal_is_wireless_mode_support(_adapter * adapter,u8 mode)9893 inline bool hal_is_wireless_mode_support(_adapter *adapter, u8 mode)
9894 {
9895 u8 proto_cap = GET_HAL_SPEC(adapter)->proto_cap;
9896
9897 if (mode == WIRELESS_11B)
9898 if ((proto_cap & PROTO_CAP_11B) && hal_chk_band_cap(adapter, BAND_CAP_2G))
9899 return 1;
9900
9901 if (mode == WIRELESS_11G)
9902 if ((proto_cap & PROTO_CAP_11G) && hal_chk_band_cap(adapter, BAND_CAP_2G))
9903 return 1;
9904
9905 if (mode == WIRELESS_11A)
9906 if ((proto_cap & PROTO_CAP_11G) && hal_chk_band_cap(adapter, BAND_CAP_5G))
9907 return 1;
9908
9909 if (mode == WIRELESS_11_24N)
9910 if ((proto_cap & PROTO_CAP_11N) && hal_chk_band_cap(adapter, BAND_CAP_2G))
9911 return 1;
9912
9913 if (mode == WIRELESS_11_5N)
9914 if ((proto_cap & PROTO_CAP_11N) && hal_chk_band_cap(adapter, BAND_CAP_5G))
9915 return 1;
9916
9917 if (mode == WIRELESS_11AC)
9918 if ((proto_cap & PROTO_CAP_11AC) && hal_chk_band_cap(adapter, BAND_CAP_5G))
9919 return 1;
9920
9921 return 0;
9922 }
9923
9924 /*
9925 * hal_largest_bw - starting from in_bw, get largest bw supported by HAL
9926 * @adapter:
9927 * @in_bw: starting bw, value of CHANNEL_WIDTH
9928 *
9929 * Returns: value of CHANNEL_WIDTH
9930 */
hal_largest_bw(_adapter * adapter,u8 in_bw)9931 u8 hal_largest_bw(_adapter *adapter, u8 in_bw)
9932 {
9933 for (; in_bw > CHANNEL_WIDTH_20; in_bw--) {
9934 if (hal_is_bw_support(adapter, in_bw))
9935 break;
9936 }
9937
9938 if (!hal_is_bw_support(adapter, in_bw))
9939 rtw_warn_on(1);
9940
9941 return in_bw;
9942 }
9943
rtw_hal_correct_tsf(_adapter * padapter,u8 hw_port,u64 tsf)9944 void rtw_hal_correct_tsf(_adapter *padapter, u8 hw_port, u64 tsf)
9945 {
9946 if (hw_port == HW_PORT0) {
9947 /*disable related TSF function*/
9948 rtw_write8(padapter, REG_BCN_CTRL, rtw_read8(padapter, REG_BCN_CTRL) & (~EN_BCN_FUNCTION));
9949
9950 rtw_write32(padapter, REG_TSFTR, tsf);
9951 rtw_write32(padapter, REG_TSFTR + 4, tsf >> 32);
9952
9953 /*enable related TSF function*/
9954 rtw_write8(padapter, REG_BCN_CTRL, rtw_read8(padapter, REG_BCN_CTRL) | EN_BCN_FUNCTION);
9955 } else if (hw_port == HW_PORT1) {
9956 /*disable related TSF function*/
9957 rtw_write8(padapter, REG_BCN_CTRL_1, rtw_read8(padapter, REG_BCN_CTRL_1) & (~EN_BCN_FUNCTION));
9958
9959 rtw_write32(padapter, REG_TSFTR1, tsf);
9960 rtw_write32(padapter, REG_TSFTR1 + 4, tsf >> 32);
9961
9962 /*enable related TSF function*/
9963 rtw_write8(padapter, REG_BCN_CTRL_1, rtw_read8(padapter, REG_BCN_CTRL_1) | EN_BCN_FUNCTION);
9964 } else
9965 RTW_INFO("%s-[WARN] "ADPT_FMT" invalid hw_port:%d\n", __func__, ADPT_ARG(padapter), hw_port);
9966 }
9967
ResumeTxBeacon(_adapter * padapter)9968 void ResumeTxBeacon(_adapter *padapter)
9969 {
9970 PHAL_DATA_TYPE pHalData = GET_HAL_DATA(padapter);
9971
9972
9973 /* 2010.03.01. Marked by tynli. No need to call workitem beacause we record the value */
9974 /* which should be read from register to a global variable. */
9975
9976 RT_TRACE(_module_hci_hal_init_c_, _drv_info_, ("+ResumeTxBeacon\n"));
9977
9978 pHalData->RegFwHwTxQCtrl |= BIT(6);
9979 rtw_write8(padapter, REG_FWHW_TXQ_CTRL + 2, pHalData->RegFwHwTxQCtrl);
9980 rtw_write8(padapter, REG_TBTT_PROHIBIT + 1, 0xff);
9981 pHalData->RegReg542 |= BIT(0);
9982 rtw_write8(padapter, REG_TBTT_PROHIBIT + 2, pHalData->RegReg542);
9983 }
9984
StopTxBeacon(_adapter * padapter)9985 void StopTxBeacon(_adapter *padapter)
9986 {
9987 PHAL_DATA_TYPE pHalData = GET_HAL_DATA(padapter);
9988
9989
9990 /* 2010.03.01. Marked by tynli. No need to call workitem beacause we record the value */
9991 /* which should be read from register to a global variable. */
9992
9993 RT_TRACE(_module_hci_hal_init_c_, _drv_info_, ("+StopTxBeacon\n"));
9994
9995 pHalData->RegFwHwTxQCtrl &= ~BIT(6);
9996 rtw_write8(padapter, REG_FWHW_TXQ_CTRL + 2, pHalData->RegFwHwTxQCtrl);
9997 rtw_write8(padapter, REG_TBTT_PROHIBIT + 1, 0x64);
9998 pHalData->RegReg542 &= ~BIT(0);
9999 rtw_write8(padapter, REG_TBTT_PROHIBIT + 2, pHalData->RegReg542);
10000
10001 /*CheckFwRsvdPageContent(padapter);*/ /* 2010.06.23. Added by tynli. */
10002 }
10003
10004 #ifdef CONFIG_MI_WITH_MBSSID_CAM /*HW port0 - MBSS*/
hw_var_set_opmode_mbid(_adapter * Adapter,u8 mode)10005 void hw_var_set_opmode_mbid(_adapter *Adapter, u8 mode)
10006 {
10007 RTW_INFO("%s()-"ADPT_FMT" mode = %d\n", __func__, ADPT_ARG(Adapter), mode);
10008
10009 rtw_write32(Adapter, REG_RCR, rtw_read32(Adapter, REG_RCR) & (~(RCR_CBSSID_DATA | RCR_CBSSID_BCN)));
10010
10011 /* disable Port0 TSF update*/
10012 rtw_write8(Adapter, REG_BCN_CTRL, rtw_read8(Adapter, REG_BCN_CTRL) | DIS_TSF_UDT);
10013
10014 /* set net_type */
10015 Set_MSR(Adapter, mode);
10016
10017 if ((mode == _HW_STATE_STATION_) || (mode == _HW_STATE_NOLINK_)) {
10018 if (!rtw_mi_check_status(Adapter, MI_AP_MODE))
10019 StopTxBeacon(Adapter);
10020
10021 rtw_write8(Adapter, REG_BCN_CTRL, DIS_TSF_UDT | EN_BCN_FUNCTION | DIS_ATIM);/*disable atim wnd*/
10022 } else if (mode == _HW_STATE_ADHOC_) {
10023 ResumeTxBeacon(Adapter);
10024 rtw_write8(Adapter, REG_BCN_CTRL, DIS_TSF_UDT | EN_BCN_FUNCTION | DIS_BCNQ_SUB);
10025
10026 } else if (mode == _HW_STATE_AP_) {
10027 ResumeTxBeacon(Adapter);
10028
10029 rtw_write8(Adapter, REG_BCN_CTRL, DIS_TSF_UDT | DIS_BCNQ_SUB);
10030
10031 /*enable to rx data frame*/
10032 rtw_write16(Adapter, REG_RXFLTMAP2, 0xFFFF);
10033
10034 /*Beacon Control related register for first time*/
10035 rtw_write8(Adapter, REG_BCNDMATIM, 0x02); /* 2ms */
10036
10037 /*rtw_write8(Adapter, REG_BCN_MAX_ERR, 0xFF);*/
10038 rtw_write8(Adapter, REG_ATIMWND, 0x0a); /* 10ms */
10039 rtw_write16(Adapter, REG_BCNTCFG, 0x00);
10040 rtw_write16(Adapter, REG_TBTT_PROHIBIT, 0xff04);
10041 rtw_write16(Adapter, REG_TSFTR_SYN_OFFSET, 0x7fff);/* +32767 (~32ms) */
10042
10043 /*reset TSF*/
10044 rtw_write8(Adapter, REG_DUAL_TSF_RST, BIT(0));
10045
10046 /*enable BCN0 Function for if1*/
10047 /*don't enable update TSF0 for if1 (due to TSF update when beacon,probe rsp are received)*/
10048 rtw_write8(Adapter, REG_BCN_CTRL, (DIS_TSF_UDT | EN_BCN_FUNCTION | EN_TXBCN_RPT | DIS_BCNQ_SUB));
10049
10050 if (IS_HARDWARE_TYPE_8821(Adapter) || IS_HARDWARE_TYPE_8192E(Adapter))/* select BCN on port 0 for DualBeacon*/
10051 rtw_write8(Adapter, REG_CCK_CHECK, rtw_read8(Adapter, REG_CCK_CHECK) & (~BIT_BCN_PORT_SEL));
10052
10053 }
10054
10055 }
10056 #endif
10057
10058 #ifdef CONFIG_ANTENNA_DIVERSITY
rtw_hal_antdiv_before_linked(_adapter * padapter)10059 u8 rtw_hal_antdiv_before_linked(_adapter *padapter)
10060 {
10061 HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);
10062 u8 cur_ant, change_ant;
10063
10064 if (!pHalData->AntDivCfg)
10065 return _FALSE;
10066
10067 if (pHalData->sw_antdiv_bl_state == 0) {
10068 pHalData->sw_antdiv_bl_state = 1;
10069
10070 rtw_hal_get_odm_var(padapter, HAL_ODM_ANTDIV_SELECT, &cur_ant, NULL);
10071 change_ant = (cur_ant == MAIN_ANT) ? AUX_ANT : MAIN_ANT;
10072
10073 return rtw_antenna_select_cmd(padapter, change_ant, _FALSE);
10074 }
10075
10076 pHalData->sw_antdiv_bl_state = 0;
10077 return _FALSE;
10078 }
10079
rtw_hal_antdiv_rssi_compared(_adapter * padapter,WLAN_BSSID_EX * dst,WLAN_BSSID_EX * src)10080 void rtw_hal_antdiv_rssi_compared(_adapter *padapter, WLAN_BSSID_EX *dst, WLAN_BSSID_EX *src)
10081 {
10082 HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);
10083
10084 if (pHalData->AntDivCfg) {
10085 /*RTW_INFO("update_network=> org-RSSI(%d), new-RSSI(%d)\n", dst->Rssi, src->Rssi);*/
10086 /*select optimum_antenna for before linked =>For antenna diversity*/
10087 if (dst->Rssi >= src->Rssi) {/*keep org parameter*/
10088 src->Rssi = dst->Rssi;
10089 src->PhyInfo.Optimum_antenna = dst->PhyInfo.Optimum_antenna;
10090 }
10091 }
10092 }
10093 #endif
10094
10095 #ifdef CONFIG_PHY_CAPABILITY_QUERY
rtw_dump_phy_cap(void * sel,_adapter * adapter)10096 void rtw_dump_phy_cap(void *sel, _adapter *adapter)
10097 {
10098 HAL_DATA_TYPE *pHalData = GET_HAL_DATA(adapter);
10099 struct phy_spec_t *phy_spec = &pHalData->phy_spec;
10100
10101 RTW_PRINT_SEL(sel, "[PHY SPEC] TRx Capability : 0x%08x\n", phy_spec->trx_cap);
10102 RTW_PRINT_SEL(sel, "[PHY SPEC] Tx Stream Num Index : %d\n", (phy_spec->trx_cap >> 24) & 0xFF); /*Tx Stream Num Index [31:24]*/
10103 RTW_PRINT_SEL(sel, "[PHY SPEC] Rx Stream Num Index : %d\n", (phy_spec->trx_cap >> 16) & 0xFF); /*Rx Stream Num Index [23:16]*/
10104 RTW_PRINT_SEL(sel, "[PHY SPEC] Tx Path Num Index : %d\n", (phy_spec->trx_cap >> 8) & 0xFF);/*Tx Path Num Index [15:8]*/
10105 RTW_PRINT_SEL(sel, "[PHY SPEC] Rx Path Num Index : %d\n", (phy_spec->trx_cap & 0xFF));/*Rx Path Num Index [7:0]*/
10106
10107 RTW_PRINT_SEL(sel, "[PHY SPEC] STBC Capability : 0x%08x\n", phy_spec->stbc_cap);
10108 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]*/
10109 RTW_PRINT_SEL(sel, "[PHY SPEC] VHT STBC Rx : %s\n", ((phy_spec->stbc_cap >> 16) & 0xFF) ? "Supported" : "N/A"); /*VHT STBC Rx [23:16]*/
10110 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]*/
10111 /*HT STBC Rx [7:0]
10112 0 = not support
10113 1 = support for 1 spatial stream
10114 2 = support for 1 or 2 spatial streams
10115 3 = support for 1 or 2 or 3 spatial streams*/
10116 if (phy_spec->stbc_cap & 0xFF)
10117 RTW_PRINT_SEL(sel, "[PHY SPEC] HT STBC Rx : %d\n", (phy_spec->stbc_cap & 0xFF));
10118 else
10119 RTW_PRINT_SEL(sel, "[PHY SPEC] HT STBC Rx : N/A\n");
10120
10121 RTW_PRINT_SEL(sel, "[PHY SPEC] LDPC Capability : 0x%08x\n", phy_spec->ldpc_cap);
10122 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]*/
10123 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]*/
10124 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]*/
10125 RTW_PRINT_SEL(sel, "[PHY SPEC] HT LDPC Rx : %s\n", (phy_spec->ldpc_cap & 0xFF) ? "Supported" : "N/A"); /*HT LDPC Rx [7:0]*/
10126
10127 RTW_PRINT_SEL(sel, "[PHY SPEC] TxBF parameter : 0x%08x\n", phy_spec->txbf_param);
10128 RTW_PRINT_SEL(sel, "[PHY SPEC] VHT Sounding Dim : %d\n", (phy_spec->txbf_param >> 24) & 0xFF); /*VHT Sounding Dim [31:24]*/
10129 RTW_PRINT_SEL(sel, "[PHY SPEC] VHT Steering Ant : %d\n", (phy_spec->txbf_param >> 16) & 0xFF); /*VHT Steering Ant [23:16]*/
10130 RTW_PRINT_SEL(sel, "[PHY SPEC] HT Sounding Dim : %d\n", (phy_spec->txbf_param >> 8) & 0xFF); /*HT Sounding Dim [15:8]*/
10131 RTW_PRINT_SEL(sel, "[PHY SPEC] HT Steering Ant : %d\n", phy_spec->txbf_param & 0xFF); /*HT Steering Ant [7:0]*/
10132
10133 RTW_PRINT_SEL(sel, "[PHY SPEC] TxBF Capability : 0x%08x\n", phy_spec->txbf_cap);
10134 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]*/
10135 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]*/
10136 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]*/
10137 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]*/
10138 RTW_PRINT_SEL(sel, "[PHY SPEC] HT Bfer : %s\n", ((phy_spec->txbf_cap >> 4) & 0xF) ? "Supported" : "N/A"); /*HT Bfer [7:4]*/
10139 RTW_PRINT_SEL(sel, "[PHY SPEC] HT Bfee : %s\n", (phy_spec->txbf_cap & 0xF) ? "Supported" : "N/A"); /*HT Bfee [3:0]*/
10140 }
10141 #endif
10142