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