net: wireless: rockchip: add rtl8822be pcie wifi driver
[firefly-linux-kernel-4.4.55.git] / drivers / net / wireless / rockchip_wlan / rtl8822be / core / rtw_wlan_util.c
1 /******************************************************************************
2  *
3  * Copyright(c) 2007 - 2012 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 _RTW_WLAN_UTIL_C_
21
22 #include <drv_types.h>
23
24 #if defined(CONFIG_WOWLAN) || defined(CONFIG_AP_WOWLAN)
25         #include <linux/inetdevice.h>
26         #define ETH_TYPE_OFFSET 12
27         #define PROTOCOL_OFFSET 23
28         #define IP_OFFSET       30
29 #endif
30
31 unsigned char ARTHEROS_OUI1[] = {0x00, 0x03, 0x7f};
32 unsigned char ARTHEROS_OUI2[] = {0x00, 0x13, 0x74};
33
34 unsigned char BROADCOM_OUI1[] = {0x00, 0x10, 0x18};
35 unsigned char BROADCOM_OUI2[] = {0x00, 0x0a, 0xf7};
36 unsigned char BROADCOM_OUI3[] = {0x00, 0x05, 0xb5};
37
38
39 unsigned char CISCO_OUI[] = {0x00, 0x40, 0x96};
40 unsigned char MARVELL_OUI[] = {0x00, 0x50, 0x43};
41 unsigned char RALINK_OUI[] = {0x00, 0x0c, 0x43};
42 unsigned char REALTEK_OUI[] = {0x00, 0xe0, 0x4c};
43 unsigned char AIRGOCAP_OUI[] = {0x00, 0x0a, 0xf5};
44
45 unsigned char REALTEK_96B_IE[] = {0x00, 0xe0, 0x4c, 0x02, 0x01, 0x20};
46
47 extern unsigned char RTW_WPA_OUI[];
48 extern unsigned char WPA_TKIP_CIPHER[4];
49 extern unsigned char RSN_TKIP_CIPHER[4];
50
51 #define R2T_PHY_DELAY   (0)
52
53 /* #define WAIT_FOR_BCN_TO_MIN  (3000) */
54 #define WAIT_FOR_BCN_TO_MIN     (6000)
55 #define WAIT_FOR_BCN_TO_MAX     (20000)
56
57 #define DISCONNECT_BY_CHK_BCN_FAIL_OBSERV_PERIOD_IN_MS 1000
58 #define DISCONNECT_BY_CHK_BCN_FAIL_THRESHOLD 3
59
60 static u8 rtw_basic_rate_cck[4] = {
61         IEEE80211_CCK_RATE_1MB | IEEE80211_BASIC_RATE_MASK, IEEE80211_CCK_RATE_2MB | IEEE80211_BASIC_RATE_MASK,
62         IEEE80211_CCK_RATE_5MB | IEEE80211_BASIC_RATE_MASK, IEEE80211_CCK_RATE_11MB | IEEE80211_BASIC_RATE_MASK
63 };
64
65 static u8 rtw_basic_rate_ofdm[3] = {
66         IEEE80211_OFDM_RATE_6MB | IEEE80211_BASIC_RATE_MASK, IEEE80211_OFDM_RATE_12MB | IEEE80211_BASIC_RATE_MASK,
67         IEEE80211_OFDM_RATE_24MB | IEEE80211_BASIC_RATE_MASK
68 };
69
70 static u8 rtw_basic_rate_mix[7] = {
71         IEEE80211_CCK_RATE_1MB | IEEE80211_BASIC_RATE_MASK, IEEE80211_CCK_RATE_2MB | IEEE80211_BASIC_RATE_MASK,
72         IEEE80211_CCK_RATE_5MB | IEEE80211_BASIC_RATE_MASK, IEEE80211_CCK_RATE_11MB | IEEE80211_BASIC_RATE_MASK,
73         IEEE80211_OFDM_RATE_6MB | IEEE80211_BASIC_RATE_MASK, IEEE80211_OFDM_RATE_12MB | IEEE80211_BASIC_RATE_MASK,
74         IEEE80211_OFDM_RATE_24MB | IEEE80211_BASIC_RATE_MASK
75 };
76
77 int new_bcn_max = 3;
78
79 int cckrates_included(unsigned char *rate, int ratelen)
80 {
81         int     i;
82
83         for (i = 0; i < ratelen; i++) {
84                 if ((((rate[i]) & 0x7f) == 2)   || (((rate[i]) & 0x7f) == 4) ||
85                     (((rate[i]) & 0x7f) == 11)  || (((rate[i]) & 0x7f) == 22))
86                         return _TRUE;
87         }
88
89         return _FALSE;
90
91 }
92
93 int cckratesonly_included(unsigned char *rate, int ratelen)
94 {
95         int     i;
96
97         for (i = 0; i < ratelen; i++) {
98                 if ((((rate[i]) & 0x7f) != 2) && (((rate[i]) & 0x7f) != 4) &&
99                     (((rate[i]) & 0x7f) != 11)  && (((rate[i]) & 0x7f) != 22))
100                         return _FALSE;
101         }
102
103         return _TRUE;
104 }
105
106 s8 rtw_get_tx_nss(_adapter *adapter, struct sta_info *psta)
107 {
108         u8 rf_type = RF_1T1R, custom_rf_type, vht_mcs[2];
109         s8 nss = 1;
110
111         custom_rf_type = adapter->registrypriv.rf_config;
112         rtw_hal_get_hwreg(adapter, HW_VAR_RF_TYPE, (u8 *)(&rf_type));
113
114         if (!psta)
115                 return nss;
116
117         /* rf_config is dependent on efuse or sw config */
118         if (custom_rf_type != RF_MAX_TYPE)
119                 rf_type = custom_rf_type;
120
121 #ifdef CONFIG_80211AC_VHT
122         if (psta->vhtpriv.vht_option) {
123                 u8 vht_mcs[2];
124                 struct mlme_priv        *pmlmepriv = &(adapter->mlmepriv);
125                 struct vht_priv *pvhtpriv_ap = &pmlmepriv->vhtpriv;
126
127                 _rtw_memcpy(vht_mcs, psta->vhtpriv.vht_mcs_map, 2);
128                 /* doesn't support 5~8 SS so far */
129                 vht_mcs[1] = 0xff;
130                 switch (rf_type) {
131                 case RF_1T1R:
132                 case RF_1T2R:
133                         vht_mcs[0] |= 0xfc;
134                         break;
135                 case RF_2T2R:
136                 case RF_2T4R:
137                 case RF_2T2R_GREEN:
138                 case RF_2T3R:
139                         vht_mcs[0] |= 0xf0;
140                         break;
141                 case RF_3T3R:
142                 case RF_3T4R:
143                         vht_mcs[0] |= 0xc0;
144                         break;
145                 default:
146                         RTW_INFO("%s,%d, unknown rf type\n", __func__, __LINE__);
147                         break;
148                 }
149                 nss = rtw_vht_mcsmap_to_nss(vht_mcs);
150         } else
151 #endif /* CONFIG_80211AC_VHT */
152                 if (psta->htpriv.ht_option) {
153                         u8 supp_mcs_set[4];
154
155                         _rtw_memcpy(supp_mcs_set, psta->htpriv.ht_cap.supp_mcs_set, 4);
156
157                         switch (rf_type) {
158                         case RF_1T1R:
159                         case RF_1T2R:
160                                 supp_mcs_set[1] = supp_mcs_set[2] = supp_mcs_set[3] = 0;
161                                 break;
162                         case RF_2T2R:
163                         case RF_2T4R:
164                         case RF_2T2R_GREEN:
165                         case RF_2T3R:
166                                 supp_mcs_set[2] = supp_mcs_set[3] = 0;
167                                 break;
168                         case RF_3T3R:
169                         case RF_3T4R:
170                                 supp_mcs_set[3] = 0;
171                                 break;
172                         default:
173                                 RTW_INFO("%s,%d, unknown rf type\n", __func__, __LINE__);
174                                 break;
175                         }
176                         nss = rtw_ht_mcsset_to_nss(supp_mcs_set);
177                 }
178
179         RTW_INFO("%s: %d SS, rf_type=%d\n", __func__, nss, rf_type);
180         return nss;
181 }
182
183 u8 networktype_to_raid(_adapter *adapter, struct sta_info *psta)
184 {
185         unsigned char raid;
186         switch (psta->wireless_mode) {
187         case WIRELESS_11B:
188                 raid = RATR_INX_WIRELESS_B;
189                 break;
190         case WIRELESS_11A:
191         case WIRELESS_11G:
192                 raid = RATR_INX_WIRELESS_G;
193                 break;
194         case WIRELESS_11BG:
195                 raid = RATR_INX_WIRELESS_GB;
196                 break;
197         case WIRELESS_11_24N:
198         case WIRELESS_11_5N:
199                 raid = RATR_INX_WIRELESS_N;
200                 break;
201         case WIRELESS_11A_5N:
202         case WIRELESS_11G_24N:
203                 raid = RATR_INX_WIRELESS_NG;
204                 break;
205         case WIRELESS_11BG_24N:
206                 raid = RATR_INX_WIRELESS_NGB;
207                 break;
208         default:
209                 raid = RATR_INX_WIRELESS_GB;
210                 break;
211
212         }
213         return raid;
214
215 }
216
217 u8 networktype_to_raid_ex(_adapter *adapter, struct sta_info *psta)
218 {
219         struct mlme_ext_priv    *pmlmeext = &adapter->mlmeextpriv;
220         u8 raid = RATEID_IDX_BGN_40M_1SS, cur_rf_type, rf_type, custom_rf_type;
221         s8 tx_nss;
222
223         tx_nss = rtw_get_tx_nss(adapter, psta);
224
225         switch (psta->wireless_mode) {
226         case WIRELESS_11B:
227                 raid = RATEID_IDX_B;
228                 break;
229         case WIRELESS_11A:
230         case WIRELESS_11G:
231                 raid = RATEID_IDX_G;
232                 break;
233         case WIRELESS_11BG:
234                 raid = RATEID_IDX_BG;
235                 break;
236         case WIRELESS_11_24N:
237         case WIRELESS_11_5N:
238         case WIRELESS_11A_5N:
239         case WIRELESS_11G_24N:
240                 if (tx_nss == 1)
241                         raid = RATEID_IDX_GN_N1SS;
242                 else if (tx_nss == 2)
243                         raid = RATEID_IDX_GN_N2SS;
244                 else if (tx_nss == 3)
245                         raid = RATEID_IDX_BGN_3SS;
246                 else
247                         RTW_INFO("tx_nss error!(tx_nss=%d)\n", tx_nss);
248                 break;
249         case WIRELESS_11B_24N:
250         case WIRELESS_11BG_24N:
251                 if (psta->bw_mode == CHANNEL_WIDTH_20) {
252                         if (tx_nss == 1)
253                                 raid = RATEID_IDX_BGN_20M_1SS_BN;
254                         else if (tx_nss == 2)
255                                 raid = RATEID_IDX_BGN_20M_2SS_BN;
256                         else if (tx_nss == 3)
257                                 raid = RATEID_IDX_BGN_3SS;
258                         else
259                                 RTW_INFO("tx_nss error!(tx_nss=%d)\n", tx_nss);
260                 } else {
261                         if (tx_nss == 1)
262                                 raid = RATEID_IDX_BGN_40M_1SS;
263                         else if (tx_nss == 2)
264                                 raid = RATEID_IDX_BGN_40M_2SS;
265                         else if (tx_nss == 3)
266                                 raid = RATEID_IDX_BGN_3SS;
267                         else
268                                 RTW_INFO("tx_nss error!(tx_nss=%d)\n", tx_nss);
269                 }
270                 break;
271 #ifdef CONFIG_80211AC_VHT
272         case WIRELESS_11_5AC:
273                 if (tx_nss == 1)
274                         raid = RATEID_IDX_VHT_1SS;
275                 else if (tx_nss == 2)
276                         raid = RATEID_IDX_VHT_2SS;
277                 else if (tx_nss == 3)
278                         raid = RATEID_IDX_VHT_3SS;
279                 else
280                         RTW_INFO("tx_nss error!(tx_nss=%d)\n", tx_nss);
281                 break;
282         case WIRELESS_11_24AC:
283         case WIRELESS_11_24BGAC:
284                 if (psta->bw_mode >= CHANNEL_WIDTH_80) {
285                         if (tx_nss == 1)
286                                 raid = RATEID_IDX_VHT_1SS;
287                         else if (tx_nss == 2)
288                                 raid = RATEID_IDX_VHT_2SS;
289                         else if (tx_nss == 3)
290                                 raid = RATEID_IDX_VHT_3SS;
291                         else
292                                 RTW_INFO("tx_nss error!(tx_nss=%d)\n", tx_nss);
293                 } else {
294                         if (tx_nss == 1)
295                                 raid = RATEID_IDX_MIX1;
296                         else if (tx_nss == 2)
297                                 raid = RATEID_IDX_MIX2;
298                         else if (tx_nss == 3)
299                                 raid = RATEID_IDX_VHT_3SS;
300                         else
301                                 RTW_INFO("tx_nss error!(tx_nss=%d)\n", tx_nss);
302                 }
303                 break;
304 #endif
305         default:
306                 RTW_INFO("unexpected wireless mode!(psta->wireless_mode=%x)\n", psta->wireless_mode);
307                 break;
308
309         }
310
311         /* RTW_INFO("psta->wireless_mode=%x,  tx_nss=%d\n", psta->wireless_mode, tx_nss); */
312
313         return raid;
314
315 }
316
317 u8 judge_network_type(_adapter *padapter, unsigned char *rate, int ratelen)
318 {
319         u8 network_type = 0;
320         struct mlme_ext_priv    *pmlmeext = &padapter->mlmeextpriv;
321         struct mlme_ext_info    *pmlmeinfo = &(pmlmeext->mlmext_info);
322
323
324         if (pmlmeext->cur_channel > 14) {
325                 if (pmlmeinfo->VHT_enable)
326                         network_type = WIRELESS_11AC;
327                 else if (pmlmeinfo->HT_enable)
328                         network_type = WIRELESS_11_5N;
329
330                 network_type |= WIRELESS_11A;
331         } else {
332                 if (pmlmeinfo->HT_enable)
333                         network_type = WIRELESS_11_24N;
334
335                 if ((cckratesonly_included(rate, ratelen)) == _TRUE)
336                         network_type |= WIRELESS_11B;
337                 else if ((cckrates_included(rate, ratelen)) == _TRUE)
338                         network_type |= WIRELESS_11BG;
339                 else
340                         network_type |= WIRELESS_11G;
341         }
342
343         return  network_type;
344 }
345
346 unsigned char ratetbl_val_2wifirate(unsigned char rate);
347 unsigned char ratetbl_val_2wifirate(unsigned char rate)
348 {
349         unsigned char val = 0;
350
351         switch (rate & 0x7f) {
352         case 0:
353                 val = IEEE80211_CCK_RATE_1MB;
354                 break;
355
356         case 1:
357                 val = IEEE80211_CCK_RATE_2MB;
358                 break;
359
360         case 2:
361                 val = IEEE80211_CCK_RATE_5MB;
362                 break;
363
364         case 3:
365                 val = IEEE80211_CCK_RATE_11MB;
366                 break;
367
368         case 4:
369                 val = IEEE80211_OFDM_RATE_6MB;
370                 break;
371
372         case 5:
373                 val = IEEE80211_OFDM_RATE_9MB;
374                 break;
375
376         case 6:
377                 val = IEEE80211_OFDM_RATE_12MB;
378                 break;
379
380         case 7:
381                 val = IEEE80211_OFDM_RATE_18MB;
382                 break;
383
384         case 8:
385                 val = IEEE80211_OFDM_RATE_24MB;
386                 break;
387
388         case 9:
389                 val = IEEE80211_OFDM_RATE_36MB;
390                 break;
391
392         case 10:
393                 val = IEEE80211_OFDM_RATE_48MB;
394                 break;
395
396         case 11:
397                 val = IEEE80211_OFDM_RATE_54MB;
398                 break;
399
400         }
401
402         return val;
403
404 }
405
406 int is_basicrate(_adapter *padapter, unsigned char rate);
407 int is_basicrate(_adapter *padapter, unsigned char rate)
408 {
409         int i;
410         unsigned char val;
411         struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
412
413         for (i = 0; i < NumRates; i++) {
414                 val = pmlmeext->basicrate[i];
415
416                 if ((val != 0xff) && (val != 0xfe)) {
417                         if (rate == ratetbl_val_2wifirate(val))
418                                 return _TRUE;
419                 }
420         }
421
422         return _FALSE;
423 }
424
425 unsigned int ratetbl2rateset(_adapter *padapter, unsigned char *rateset);
426 unsigned int ratetbl2rateset(_adapter *padapter, unsigned char *rateset)
427 {
428         int i;
429         unsigned char rate;
430         unsigned int    len = 0;
431         struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
432
433         for (i = 0; i < NumRates; i++) {
434                 rate = pmlmeext->datarate[i];
435
436                 switch (rate) {
437                 case 0xff:
438                         return len;
439
440                 case 0xfe:
441                         continue;
442
443                 default:
444                         rate = ratetbl_val_2wifirate(rate);
445
446                         if (is_basicrate(padapter, rate) == _TRUE)
447                                 rate |= IEEE80211_BASIC_RATE_MASK;
448
449                         rateset[len] = rate;
450                         len++;
451                         break;
452                 }
453         }
454         return len;
455 }
456
457 void get_rate_set(_adapter *padapter, unsigned char *pbssrate, int *bssrate_len)
458 {
459         unsigned char supportedrates[NumRates];
460
461         _rtw_memset(supportedrates, 0, NumRates);
462         *bssrate_len = ratetbl2rateset(padapter, supportedrates);
463         _rtw_memcpy(pbssrate, supportedrates, *bssrate_len);
464 }
465
466 void set_mcs_rate_by_mask(u8 *mcs_set, u32 mask)
467 {
468         u8 mcs_rate_1r = (u8)(mask & 0xff);
469         u8 mcs_rate_2r = (u8)((mask >> 8) & 0xff);
470         u8 mcs_rate_3r = (u8)((mask >> 16) & 0xff);
471         u8 mcs_rate_4r = (u8)((mask >> 24) & 0xff);
472
473         mcs_set[0] &= mcs_rate_1r;
474         mcs_set[1] &= mcs_rate_2r;
475         mcs_set[2] &= mcs_rate_3r;
476         mcs_set[3] &= mcs_rate_4r;
477 }
478
479 void UpdateBrateTbl(
480         IN PADAPTER             Adapter,
481         IN u8                   *mBratesOS
482 )
483 {
484         u8      i;
485         u8      rate;
486
487         /* 1M, 2M, 5.5M, 11M, 6M, 12M, 24M are mandatory. */
488         for (i = 0; i < NDIS_802_11_LENGTH_RATES_EX; i++) {
489                 rate = mBratesOS[i] & 0x7f;
490                 switch (rate) {
491                 case IEEE80211_CCK_RATE_1MB:
492                 case IEEE80211_CCK_RATE_2MB:
493                 case IEEE80211_CCK_RATE_5MB:
494                 case IEEE80211_CCK_RATE_11MB:
495                 case IEEE80211_OFDM_RATE_6MB:
496                 case IEEE80211_OFDM_RATE_12MB:
497                 case IEEE80211_OFDM_RATE_24MB:
498                         mBratesOS[i] |= IEEE80211_BASIC_RATE_MASK;
499                         break;
500                 }
501         }
502
503 }
504
505 void UpdateBrateTblForSoftAP(u8 *bssrateset, u32 bssratelen)
506 {
507         u8      i;
508         u8      rate;
509
510         for (i = 0; i < bssratelen; i++) {
511                 rate = bssrateset[i] & 0x7f;
512                 switch (rate) {
513                 case IEEE80211_CCK_RATE_1MB:
514                 case IEEE80211_CCK_RATE_2MB:
515                 case IEEE80211_CCK_RATE_5MB:
516                 case IEEE80211_CCK_RATE_11MB:
517                         bssrateset[i] |= IEEE80211_BASIC_RATE_MASK;
518                         break;
519                 }
520         }
521
522 }
523 void Set_MSR(_adapter *padapter, u8 type)
524 {
525         rtw_hal_set_hwreg(padapter, HW_VAR_MEDIA_STATUS, (u8 *)(&type));
526 }
527
528 inline u8 rtw_get_oper_ch(_adapter *adapter)
529 {
530         return adapter_to_dvobj(adapter)->oper_channel;
531 }
532
533 inline void rtw_set_oper_ch(_adapter *adapter, u8 ch)
534 {
535 #ifdef DBG_CH_SWITCH
536         const int len = 128;
537         char msg[128] = {0};
538         int cnt = 0;
539         int i = 0;
540 #endif  /* DBG_CH_SWITCH */
541         struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
542
543         if (dvobj->oper_channel != ch) {
544                 dvobj->on_oper_ch_time = rtw_get_current_time();
545
546 #ifdef DBG_CH_SWITCH
547                 cnt += snprintf(msg + cnt, len - cnt, "switch to ch %3u", ch);
548
549                 for (i = 0; i < dvobj->iface_nums; i++) {
550                         _adapter *iface = dvobj->padapters[i];
551                         cnt += snprintf(msg + cnt, len - cnt, " ["ADPT_FMT":", ADPT_ARG(iface));
552                         if (iface->mlmeextpriv.cur_channel == ch)
553                                 cnt += snprintf(msg + cnt, len - cnt, "C");
554                         else
555                                 cnt += snprintf(msg + cnt, len - cnt, "_");
556                         if (iface->wdinfo.listen_channel == ch && !rtw_p2p_chk_state(&iface->wdinfo, P2P_STATE_NONE))
557                                 cnt += snprintf(msg + cnt, len - cnt, "L");
558                         else
559                                 cnt += snprintf(msg + cnt, len - cnt, "_");
560                         cnt += snprintf(msg + cnt, len - cnt, "]");
561                 }
562
563                 RTW_INFO(FUNC_ADPT_FMT" %s\n", FUNC_ADPT_ARG(adapter), msg);
564 #endif /* DBG_CH_SWITCH */
565         }
566
567         dvobj->oper_channel = ch;
568 }
569
570 inline u8 rtw_get_oper_bw(_adapter *adapter)
571 {
572         return adapter_to_dvobj(adapter)->oper_bwmode;
573 }
574
575 inline void rtw_set_oper_bw(_adapter *adapter, u8 bw)
576 {
577         adapter_to_dvobj(adapter)->oper_bwmode = bw;
578 }
579
580 inline u8 rtw_get_oper_choffset(_adapter *adapter)
581 {
582         return adapter_to_dvobj(adapter)->oper_ch_offset;
583 }
584
585 inline void rtw_set_oper_choffset(_adapter *adapter, u8 offset)
586 {
587         adapter_to_dvobj(adapter)->oper_ch_offset = offset;
588 }
589
590 u8 rtw_get_offset_by_chbw(u8 ch, u8 bw, u8 *r_offset)
591 {
592         u8 valid = 1;
593         u8 offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE;
594
595         if (bw == CHANNEL_WIDTH_20)
596                 goto exit;
597
598         if (bw >= CHANNEL_WIDTH_80 && ch <= 14) {
599                 valid = 0;
600                 goto exit;
601         }
602
603         /* TODO: 2.4G 40MHz offset choise */
604
605         if (ch >= 1 && ch <= 4)
606                 offset = HAL_PRIME_CHNL_OFFSET_LOWER;
607         else if (ch >= 5 && ch <= 14)
608                 offset = HAL_PRIME_CHNL_OFFSET_UPPER;
609         else if (ch >= 36 && ch <= 177) {
610                 switch (ch) {
611                 case 36:
612                 case 44:
613                 case 52:
614                 case 60:
615                 case 100:
616                 case 108:
617                 case 116:
618                 case 124:
619                 case 132:
620                 case 140:
621                 case 149:
622                 case 157:
623                 case 165:
624                 case 173:
625                         offset = HAL_PRIME_CHNL_OFFSET_LOWER;
626                         break;
627                 case 40:
628                 case 48:
629                 case 56:
630                 case 64:
631                 case 104:
632                 case 112:
633                 case 120:
634                 case 128:
635                 case 136:
636                 case 144:
637                 case 153:
638                 case 161:
639                 case 169:
640                 case 177:
641                         offset = HAL_PRIME_CHNL_OFFSET_UPPER;
642                         break;
643                 default:
644                         valid = 0;
645                         break;
646                 }
647         } else
648                 valid = 0;
649
650 exit:
651         if (valid && r_offset)
652                 *r_offset = offset;
653         return valid;
654 }
655
656 u8 rtw_get_offset_by_ch(u8 channel)
657 {
658         u8 offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE;
659
660         if (channel >= 1 && channel <= 4)
661                 offset = HAL_PRIME_CHNL_OFFSET_LOWER;
662         else if (channel >= 5 && channel <= 14)
663                 offset = HAL_PRIME_CHNL_OFFSET_UPPER;
664         else {
665                 switch (channel) {
666                 case 36:
667                 case 44:
668                 case 52:
669                 case 60:
670                 case 100:
671                 case 108:
672                 case 116:
673                 case 124:
674                 case 132:
675                 case 149:
676                 case 157:
677                         offset = HAL_PRIME_CHNL_OFFSET_LOWER;
678                         break;
679                 case 40:
680                 case 48:
681                 case 56:
682                 case 64:
683                 case 104:
684                 case 112:
685                 case 120:
686                 case 128:
687                 case 136:
688                 case 153:
689                 case 161:
690                         offset = HAL_PRIME_CHNL_OFFSET_UPPER;
691                         break;
692                 default:
693                         offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE;
694                         break;
695                 }
696
697         }
698
699         return offset;
700
701 }
702
703 u8 rtw_get_center_ch(u8 channel, u8 chnl_bw, u8 chnl_offset)
704 {
705         u8 center_ch = channel;
706
707         if (chnl_bw == CHANNEL_WIDTH_80) {
708                 if (channel == 36 || channel == 40 || channel == 44 || channel == 48)
709                         center_ch = 42;
710                 else if (channel == 52 || channel == 56 || channel == 60 || channel == 64)
711                         center_ch = 58;
712                 else if (channel == 100 || channel == 104 || channel == 108 || channel == 112)
713                         center_ch = 106;
714                 else if (channel == 116 || channel == 120 || channel == 124 || channel == 128)
715                         center_ch = 122;
716                 else if (channel == 132 || channel == 136 || channel == 140 || channel == 144)
717                         center_ch = 138;
718                 else if (channel == 149 || channel == 153 || channel == 157 || channel == 161)
719                         center_ch = 155;
720                 else if (channel == 165 || channel == 169 || channel == 173 || channel == 177)
721                         center_ch = 171;
722                 else if (channel <= 14)
723                         center_ch = 7;
724         } else if (chnl_bw == CHANNEL_WIDTH_40) {
725                 if (chnl_offset == HAL_PRIME_CHNL_OFFSET_LOWER)
726                         center_ch = channel + 2;
727                 else
728                         center_ch = channel - 2;
729         } else if (chnl_bw == CHANNEL_WIDTH_20)
730                 center_ch = channel;
731         else
732                 rtw_warn_on(1);
733
734         return center_ch;
735 }
736
737 inline u32 rtw_get_on_oper_ch_time(_adapter *adapter)
738 {
739         return adapter_to_dvobj(adapter)->on_oper_ch_time;
740 }
741
742 inline u32 rtw_get_on_cur_ch_time(_adapter *adapter)
743 {
744         if (adapter->mlmeextpriv.cur_channel == adapter_to_dvobj(adapter)->oper_channel)
745                 return adapter_to_dvobj(adapter)->on_oper_ch_time;
746         else
747                 return 0;
748 }
749
750 void SelectChannel(_adapter *padapter, unsigned char channel)
751 {
752         struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
753
754         _enter_critical_mutex(&(adapter_to_dvobj(padapter)->setch_mutex), NULL);
755
756 #ifdef CONFIG_MCC_MODE
757         if (MCC_EN(padapter)) {
758                 /* driver doesn't set channel reg under MCC */
759                 if (rtw_hal_check_mcc_status(padapter, MCC_STATUS_DOING_MCC)) {
760                         RTW_INFO("Warning: Do not set channel reg MCC mode\n");
761                         rtw_warn_on(1);
762                 }
763         }
764 #endif
765
766 #ifdef CONFIG_DFS_MASTER
767         {
768                 struct rf_ctl_t *rfctl = adapter_to_rfctl(padapter);
769                 bool ori_overlap_radar_detect_ch = rtw_rfctl_overlap_radar_detect_ch(rfctl);
770                 bool new_overlap_radar_detect_ch = _rtw_rfctl_overlap_radar_detect_ch(rfctl, channel
771                         , adapter_to_dvobj(padapter)->oper_bwmode, adapter_to_dvobj(padapter)->oper_ch_offset);
772
773                 if (new_overlap_radar_detect_ch)
774                         rtw_odm_radar_detect_enable(padapter);
775
776                 if (new_overlap_radar_detect_ch && IS_CH_WAITING(rfctl)) {
777                         u8 pause = 0xFF;
778
779                         rtw_hal_set_hwreg(padapter, HW_VAR_TXPAUSE, &pause);
780                 }
781 #endif /* CONFIG_DFS_MASTER */
782
783                 /* saved channel info */
784                 rtw_set_oper_ch(padapter, channel);
785
786                 rtw_hal_set_chan(padapter, channel);
787
788 #ifdef CONFIG_DFS_MASTER
789                 if (ori_overlap_radar_detect_ch && !new_overlap_radar_detect_ch) {
790                         u8 pause = 0x00;
791
792                         rtw_odm_radar_detect_disable(padapter);
793                         rtw_hal_set_hwreg(padapter, HW_VAR_TXPAUSE, &pause);
794                 }
795         }
796 #endif /* CONFIG_DFS_MASTER */
797
798         _exit_critical_mutex(&(adapter_to_dvobj(padapter)->setch_mutex), NULL);
799
800 }
801
802 void SetBWMode(_adapter *padapter, unsigned short bwmode, unsigned char channel_offset)
803 {
804         struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
805
806         _enter_critical_mutex(&(adapter_to_dvobj(padapter)->setbw_mutex), NULL);
807
808 #ifdef CONFIG_MCC_MODE
809         if (MCC_EN(padapter)) {
810                 /* driver doesn't set bw reg under MCC */
811                 if (rtw_hal_check_mcc_status(padapter, MCC_STATUS_DOING_MCC)) {
812                         RTW_INFO("Warning: Do not set bw reg MCC mode\n");
813                         rtw_warn_on(1);
814                 }
815         }
816 #endif
817
818 #ifdef CONFIG_DFS_MASTER
819         {
820                 struct rf_ctl_t *rfctl = adapter_to_rfctl(padapter);
821                 bool ori_overlap_radar_detect_ch = rtw_rfctl_overlap_radar_detect_ch(rfctl);
822                 bool new_overlap_radar_detect_ch = _rtw_rfctl_overlap_radar_detect_ch(rfctl
823                         , adapter_to_dvobj(padapter)->oper_channel, bwmode, channel_offset);
824
825                 if (new_overlap_radar_detect_ch)
826                         rtw_odm_radar_detect_enable(padapter);
827
828                 if (new_overlap_radar_detect_ch && IS_CH_WAITING(rfctl)) {
829                         u8 pause = 0xFF;
830
831                         rtw_hal_set_hwreg(padapter, HW_VAR_TXPAUSE, &pause);
832                 }
833 #endif /* CONFIG_DFS_MASTER */
834
835                 /* saved bw info */
836                 rtw_set_oper_bw(padapter, bwmode);
837                 rtw_set_oper_choffset(padapter, channel_offset);
838
839                 rtw_hal_set_bwmode(padapter, (CHANNEL_WIDTH)bwmode, channel_offset);
840
841 #ifdef CONFIG_DFS_MASTER
842                 if (ori_overlap_radar_detect_ch && !new_overlap_radar_detect_ch) {
843                         u8 pause = 0x00;
844
845                         rtw_odm_radar_detect_disable(padapter);
846                         rtw_hal_set_hwreg(padapter, HW_VAR_TXPAUSE, &pause);
847                 }
848         }
849 #endif /* CONFIG_DFS_MASTER */
850
851         _exit_critical_mutex(&(adapter_to_dvobj(padapter)->setbw_mutex), NULL);
852 }
853
854 void set_channel_bwmode(_adapter *padapter, unsigned char channel, unsigned char channel_offset, unsigned short bwmode)
855 {
856         u8 center_ch, chnl_offset80 = HAL_PRIME_CHNL_OFFSET_DONT_CARE;
857         struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
858 #if (defined(CONFIG_TDLS) && defined(CONFIG_TDLS_CH_SW)) || defined(CONFIG_MCC_MODE)
859         u8 iqk_info_backup = _FALSE;
860 #endif
861
862         if (padapter->bNotifyChannelChange)
863                 RTW_INFO("[%s] ch = %d, offset = %d, bwmode = %d\n", __FUNCTION__, channel, channel_offset, bwmode);
864
865         center_ch = rtw_get_center_ch(channel, bwmode, channel_offset);
866
867         if (bwmode == CHANNEL_WIDTH_80) {
868                 if (center_ch > channel)
869                         chnl_offset80 = HAL_PRIME_CHNL_OFFSET_LOWER;
870                 else if (center_ch < channel)
871                         chnl_offset80 = HAL_PRIME_CHNL_OFFSET_UPPER;
872                 else
873                         chnl_offset80 = HAL_PRIME_CHNL_OFFSET_DONT_CARE;
874         }
875         _enter_critical_mutex(&(adapter_to_dvobj(padapter)->setch_mutex), NULL);
876
877 #ifdef CONFIG_MCC_MODE
878         if (MCC_EN(padapter)) {
879                 /* driver doesn't set channel setting reg under MCC */
880                 if (rtw_hal_check_mcc_status(padapter, MCC_STATUS_DOING_MCC)) {
881                         RTW_INFO("Warning: Do not set channel setting reg MCC mode\n");
882                         rtw_warn_on(1);
883                 }
884         }
885 #endif
886
887 #ifdef CONFIG_DFS_MASTER
888         {
889                 struct rf_ctl_t *rfctl = adapter_to_rfctl(padapter);
890                 bool ori_overlap_radar_detect_ch = rtw_rfctl_overlap_radar_detect_ch(rfctl);
891                 bool new_overlap_radar_detect_ch = _rtw_rfctl_overlap_radar_detect_ch(rfctl, channel, bwmode, channel_offset);
892
893                 if (new_overlap_radar_detect_ch)
894                         rtw_odm_radar_detect_enable(padapter);
895
896                 if (new_overlap_radar_detect_ch && IS_CH_WAITING(rfctl)) {
897                         u8 pause = 0xFF;
898
899                         rtw_hal_set_hwreg(padapter, HW_VAR_TXPAUSE, &pause);
900                 }
901 #endif /* CONFIG_DFS_MASTER */
902
903                 /* set Channel */
904                 /* saved channel/bw info */
905                 rtw_set_oper_ch(padapter, channel);
906                 rtw_set_oper_bw(padapter, bwmode);
907                 rtw_set_oper_choffset(padapter, channel_offset);
908
909 #if (defined(CONFIG_TDLS) && defined(CONFIG_TDLS_CH_SW)) || defined(CONFIG_MCC_MODE)
910                 /* To check if we need to backup iqk info after switch chnl & bw */
911                 {
912                         u8 take_care_iqk, do_iqk;
913
914                         rtw_hal_get_hwreg(padapter, HW_VAR_CH_SW_NEED_TO_TAKE_CARE_IQK_INFO, &take_care_iqk);
915                         rtw_hal_get_hwreg(padapter, HW_VAR_DO_IQK, &do_iqk);
916                         if ((take_care_iqk == _TRUE) && (do_iqk == _TRUE))
917                                 iqk_info_backup = _TRUE;
918                 }
919 #endif
920
921                 rtw_hal_set_chnl_bw(padapter, center_ch, bwmode, channel_offset, chnl_offset80); /* set center channel */
922
923 #if (defined(CONFIG_TDLS) && defined(CONFIG_TDLS_CH_SW)) || defined(CONFIG_MCC_MODE)
924                 if (iqk_info_backup == _TRUE)
925                         rtw_hal_ch_sw_iqk_info_backup(padapter);
926 #endif
927
928 #ifdef CONFIG_DFS_MASTER
929                 if (ori_overlap_radar_detect_ch && !new_overlap_radar_detect_ch) {
930                         u8 pause = 0x00;
931
932                         rtw_odm_radar_detect_disable(padapter);
933                         rtw_hal_set_hwreg(padapter, HW_VAR_TXPAUSE, &pause);
934                 }
935         }
936 #endif /* CONFIG_DFS_MASTER */
937
938         _exit_critical_mutex(&(adapter_to_dvobj(padapter)->setch_mutex), NULL);
939 }
940
941 int get_bsstype(unsigned short capability)
942 {
943         if (capability & BIT(0))
944                 return WIFI_FW_AP_STATE;
945         else if (capability & BIT(1))
946                 return WIFI_FW_ADHOC_STATE;
947         else
948                 return 0;
949 }
950
951 __inline u8 *get_my_bssid(WLAN_BSSID_EX *pnetwork)
952 {
953         return pnetwork->MacAddress;
954 }
955
956 u16 get_beacon_interval(WLAN_BSSID_EX *bss)
957 {
958         unsigned short val;
959         _rtw_memcpy((unsigned char *)&val, rtw_get_beacon_interval_from_ie(bss->IEs), 2);
960
961         return le16_to_cpu(val);
962
963 }
964
965 int is_client_associated_to_ap(_adapter *padapter)
966 {
967         struct mlme_ext_priv    *pmlmeext;
968         struct mlme_ext_info    *pmlmeinfo;
969
970         if (!padapter)
971                 return _FAIL;
972
973         pmlmeext = &padapter->mlmeextpriv;
974         pmlmeinfo = &(pmlmeext->mlmext_info);
975
976         if ((pmlmeinfo->state & WIFI_FW_ASSOC_SUCCESS) && ((pmlmeinfo->state & 0x03) == WIFI_FW_STATION_STATE))
977                 return _TRUE;
978         else
979                 return _FAIL;
980 }
981
982 int is_client_associated_to_ibss(_adapter *padapter)
983 {
984         struct mlme_ext_priv    *pmlmeext = &padapter->mlmeextpriv;
985         struct mlme_ext_info    *pmlmeinfo = &(pmlmeext->mlmext_info);
986
987         if ((pmlmeinfo->state & WIFI_FW_ASSOC_SUCCESS) && ((pmlmeinfo->state & 0x03) == WIFI_FW_ADHOC_STATE))
988                 return _TRUE;
989         else
990                 return _FAIL;
991 }
992
993 int is_IBSS_empty(_adapter *padapter)
994 {
995         int i;
996         struct macid_ctl_t *macid_ctl = &padapter->dvobj->macid_ctl;
997
998         for (i = 0; i < macid_ctl->num; i++) {
999                 if (!rtw_macid_is_used(macid_ctl, i))
1000                         continue;
1001                 if (rtw_macid_get_if_g(macid_ctl, i) != padapter->iface_id)
1002                         continue;
1003                 if (!GET_H2CCMD_MSRRPT_PARM_OPMODE(&macid_ctl->h2c_msr[i]))
1004                         continue;
1005                 if (GET_H2CCMD_MSRRPT_PARM_ROLE(&macid_ctl->h2c_msr[i]) == H2C_MSR_ROLE_ADHOC)
1006                         return _FAIL;
1007         }
1008
1009         return _TRUE;
1010 }
1011
1012 unsigned int decide_wait_for_beacon_timeout(unsigned int bcn_interval)
1013 {
1014         if ((bcn_interval << 2) < WAIT_FOR_BCN_TO_MIN)
1015                 return WAIT_FOR_BCN_TO_MIN;
1016         else if ((bcn_interval << 2) > WAIT_FOR_BCN_TO_MAX)
1017                 return WAIT_FOR_BCN_TO_MAX;
1018         else
1019                 return bcn_interval << 2;
1020 }
1021
1022 void CAM_empty_entry(
1023         PADAPTER        Adapter,
1024         u8                      ucIndex
1025 )
1026 {
1027         rtw_hal_set_hwreg(Adapter, HW_VAR_CAM_EMPTY_ENTRY, (u8 *)(&ucIndex));
1028 }
1029
1030 void invalidate_cam_all(_adapter *padapter)
1031 {
1032         struct dvobj_priv *dvobj = adapter_to_dvobj(padapter);
1033         struct cam_ctl_t *cam_ctl = &dvobj->cam_ctl;
1034         _irqL irqL;
1035         u8 val8 = 0;
1036
1037         rtw_hal_set_hwreg(padapter, HW_VAR_CAM_INVALID_ALL, &val8);
1038
1039         _enter_critical_bh(&cam_ctl->lock, &irqL);
1040         rtw_sec_cam_map_clr_all(&cam_ctl->used);
1041         _rtw_memset(dvobj->cam_cache, 0, sizeof(struct sec_cam_ent) * SEC_CAM_ENT_NUM_SW_LIMIT);
1042         _exit_critical_bh(&cam_ctl->lock, &irqL);
1043 }
1044
1045 void _clear_cam_entry(_adapter *padapter, u8 entry)
1046 {
1047         unsigned char null_sta[] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
1048         unsigned char null_key[] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
1049
1050         rtw_sec_write_cam_ent(padapter, entry, 0, null_sta, null_key);
1051 }
1052
1053 inline void write_cam(_adapter *adapter, u8 id, u16 ctrl, u8 *mac, u8 *key)
1054 {
1055 #ifdef CONFIG_WRITE_CACHE_ONLY
1056         write_cam_cache(adapter, id , ctrl, mac, key);
1057 #else
1058         rtw_sec_write_cam_ent(adapter, id, ctrl, mac, key);
1059         write_cam_cache(adapter, id , ctrl, mac, key);
1060 #endif
1061 }
1062
1063 inline void clear_cam_entry(_adapter *adapter, u8 id)
1064 {
1065         _clear_cam_entry(adapter, id);
1066         clear_cam_cache(adapter, id);
1067 }
1068
1069 inline void write_cam_from_cache(_adapter *adapter, u8 id)
1070 {
1071         struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
1072         struct cam_ctl_t *cam_ctl = &dvobj->cam_ctl;
1073         _irqL irqL;
1074         struct sec_cam_ent cache;
1075
1076         _enter_critical_bh(&cam_ctl->lock, &irqL);
1077         _rtw_memcpy(&cache, &dvobj->cam_cache[id], sizeof(struct sec_cam_ent));
1078         _exit_critical_bh(&cam_ctl->lock, &irqL);
1079
1080         rtw_sec_write_cam_ent(adapter, id, cache.ctrl, cache.mac, cache.key);
1081 }
1082 void write_cam_cache(_adapter *adapter, u8 id, u16 ctrl, u8 *mac, u8 *key)
1083 {
1084         struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
1085         struct cam_ctl_t *cam_ctl = &dvobj->cam_ctl;
1086         _irqL irqL;
1087
1088         _enter_critical_bh(&cam_ctl->lock, &irqL);
1089
1090         dvobj->cam_cache[id].ctrl = ctrl;
1091         _rtw_memcpy(dvobj->cam_cache[id].mac, mac, ETH_ALEN);
1092         _rtw_memcpy(dvobj->cam_cache[id].key, key, 16);
1093
1094         _exit_critical_bh(&cam_ctl->lock, &irqL);
1095 }
1096
1097 void clear_cam_cache(_adapter *adapter, u8 id)
1098 {
1099         struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
1100         struct cam_ctl_t *cam_ctl = &dvobj->cam_ctl;
1101         _irqL irqL;
1102
1103         _enter_critical_bh(&cam_ctl->lock, &irqL);
1104
1105         _rtw_memset(&(dvobj->cam_cache[id]), 0, sizeof(struct sec_cam_ent));
1106
1107         _exit_critical_bh(&cam_ctl->lock, &irqL);
1108 }
1109
1110 inline bool _rtw_camctl_chk_cap(_adapter *adapter, u8 cap)
1111 {
1112         struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
1113         struct cam_ctl_t *cam_ctl = &dvobj->cam_ctl;
1114
1115         if (cam_ctl->sec_cap & cap)
1116                 return _TRUE;
1117         return _FALSE;
1118 }
1119
1120 inline void _rtw_camctl_set_flags(_adapter *adapter, u32 flags)
1121 {
1122         struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
1123         struct cam_ctl_t *cam_ctl = &dvobj->cam_ctl;
1124
1125         cam_ctl->flags |= flags;
1126 }
1127
1128 inline void rtw_camctl_set_flags(_adapter *adapter, u32 flags)
1129 {
1130         struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
1131         struct cam_ctl_t *cam_ctl = &dvobj->cam_ctl;
1132         _irqL irqL;
1133
1134         _enter_critical_bh(&cam_ctl->lock, &irqL);
1135         _rtw_camctl_set_flags(adapter, flags);
1136         _exit_critical_bh(&cam_ctl->lock, &irqL);
1137 }
1138
1139 inline void _rtw_camctl_clr_flags(_adapter *adapter, u32 flags)
1140 {
1141         struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
1142         struct cam_ctl_t *cam_ctl = &dvobj->cam_ctl;
1143
1144         cam_ctl->flags &= ~flags;
1145 }
1146
1147 inline void rtw_camctl_clr_flags(_adapter *adapter, u32 flags)
1148 {
1149         struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
1150         struct cam_ctl_t *cam_ctl = &dvobj->cam_ctl;
1151         _irqL irqL;
1152
1153         _enter_critical_bh(&cam_ctl->lock, &irqL);
1154         _rtw_camctl_clr_flags(adapter, flags);
1155         _exit_critical_bh(&cam_ctl->lock, &irqL);
1156 }
1157
1158 inline bool _rtw_camctl_chk_flags(_adapter *adapter, u32 flags)
1159 {
1160         struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
1161         struct cam_ctl_t *cam_ctl = &dvobj->cam_ctl;
1162
1163         if (cam_ctl->flags & flags)
1164                 return _TRUE;
1165         return _FALSE;
1166 }
1167
1168 void dump_sec_cam_map(void *sel, struct sec_cam_bmp *map, u8 max_num)
1169 {
1170         RTW_PRINT_SEL(sel, "0x%08x\n", map->m0);
1171 #if (SEC_CAM_ENT_NUM_SW_LIMIT > 32)
1172         if (max_num && max_num > 32)
1173                 RTW_PRINT_SEL(sel, "0x%08x\n", map->m1);
1174 #endif
1175 #if (SEC_CAM_ENT_NUM_SW_LIMIT > 64)
1176         if (max_num && max_num > 64)
1177                 RTW_PRINT_SEL(sel, "0x%08x\n", map->m2);
1178 #endif
1179 #if (SEC_CAM_ENT_NUM_SW_LIMIT > 96)
1180         if (max_num && max_num > 96)
1181                 RTW_PRINT_SEL(sel, "0x%08x\n", map->m3);
1182 #endif
1183 }
1184
1185 inline bool rtw_sec_camid_is_set(struct sec_cam_bmp *map, u8 id)
1186 {
1187         if (id < 32)
1188                 return map->m0 & BIT(id);
1189 #if (SEC_CAM_ENT_NUM_SW_LIMIT > 32)
1190         else if (id < 64)
1191                 return map->m1 & BIT(id - 32);
1192 #endif
1193 #if (SEC_CAM_ENT_NUM_SW_LIMIT > 64)
1194         else if (id < 96)
1195                 return map->m2 & BIT(id - 64);
1196 #endif
1197 #if (SEC_CAM_ENT_NUM_SW_LIMIT > 96)
1198         else if (id < 128)
1199                 return map->m3 & BIT(id - 96);
1200 #endif
1201         else
1202                 rtw_warn_on(1);
1203
1204         return 0;
1205 }
1206
1207 inline void rtw_sec_cam_map_set(struct sec_cam_bmp *map, u8 id)
1208 {
1209         if (id < 32)
1210                 map->m0 |= BIT(id);
1211 #if (SEC_CAM_ENT_NUM_SW_LIMIT > 32)
1212         else if (id < 64)
1213                 map->m1 |= BIT(id - 32);
1214 #endif
1215 #if (SEC_CAM_ENT_NUM_SW_LIMIT > 64)
1216         else if (id < 96)
1217                 map->m2 |= BIT(id - 64);
1218 #endif
1219 #if (SEC_CAM_ENT_NUM_SW_LIMIT > 96)
1220         else if (id < 128)
1221                 map->m3 |= BIT(id - 96);
1222 #endif
1223         else
1224                 rtw_warn_on(1);
1225 }
1226
1227 inline void rtw_sec_cam_map_clr(struct sec_cam_bmp *map, u8 id)
1228 {
1229         if (id < 32)
1230                 map->m0 &= ~BIT(id);
1231 #if (SEC_CAM_ENT_NUM_SW_LIMIT > 32)
1232         else if (id < 64)
1233                 map->m1 &= ~BIT(id - 32);
1234 #endif
1235 #if (SEC_CAM_ENT_NUM_SW_LIMIT > 64)
1236         else if (id < 96)
1237                 map->m2 &= ~BIT(id - 64);
1238 #endif
1239 #if (SEC_CAM_ENT_NUM_SW_LIMIT > 96)
1240         else if (id < 128)
1241                 map->m3 &= ~BIT(id - 96);
1242 #endif
1243         else
1244                 rtw_warn_on(1);
1245 }
1246
1247 inline void rtw_sec_cam_map_clr_all(struct sec_cam_bmp *map)
1248 {
1249         map->m0 = 0;
1250 #if (SEC_CAM_ENT_NUM_SW_LIMIT > 32)
1251         map->m1 = 0;
1252 #endif
1253 #if (SEC_CAM_ENT_NUM_SW_LIMIT > 64)
1254         map->m2 = 0;
1255 #endif
1256 #if (SEC_CAM_ENT_NUM_SW_LIMIT > 96)
1257         map->m3 = 0;
1258 #endif
1259 }
1260
1261 inline bool rtw_sec_camid_is_drv_forbid(struct cam_ctl_t *cam_ctl, u8 id)
1262 {
1263         struct sec_cam_bmp forbid_map;
1264
1265         forbid_map.m0 = 0x00000ff0;
1266 #if (SEC_CAM_ENT_NUM_SW_LIMIT > 32)
1267         forbid_map.m1 = 0x00000000;
1268 #endif
1269 #if (SEC_CAM_ENT_NUM_SW_LIMIT > 64)
1270         forbid_map.m2 = 0x00000000;
1271 #endif
1272 #if (SEC_CAM_ENT_NUM_SW_LIMIT > 96)
1273         forbid_map.m3 = 0x00000000;
1274 #endif
1275
1276         if (id < 32)
1277                 return forbid_map.m0 & BIT(id);
1278 #if (SEC_CAM_ENT_NUM_SW_LIMIT > 32)
1279         else if (id < 64)
1280                 return forbid_map.m1 & BIT(id - 32);
1281 #endif
1282 #if (SEC_CAM_ENT_NUM_SW_LIMIT > 64)
1283         else if (id < 96)
1284                 return forbid_map.m2 & BIT(id - 64);
1285 #endif
1286 #if (SEC_CAM_ENT_NUM_SW_LIMIT > 96)
1287         else if (id < 128)
1288                 return forbid_map.m3 & BIT(id - 96);
1289 #endif
1290         else
1291                 rtw_warn_on(1);
1292
1293         return 1;
1294 }
1295
1296 bool _rtw_sec_camid_is_used(struct cam_ctl_t *cam_ctl, u8 id)
1297 {
1298         bool ret = _FALSE;
1299
1300         if (id >= cam_ctl->num) {
1301                 rtw_warn_on(1);
1302                 goto exit;
1303         }
1304
1305 #if 0 /* for testing */
1306         if (rtw_sec_camid_is_drv_forbid(cam_ctl, id)) {
1307                 ret = _TRUE;
1308                 goto exit;
1309         }
1310 #endif
1311
1312         ret = rtw_sec_camid_is_set(&cam_ctl->used, id);
1313
1314 exit:
1315         return ret;
1316 }
1317
1318 inline bool rtw_sec_camid_is_used(struct cam_ctl_t *cam_ctl, u8 id)
1319 {
1320         _irqL irqL;
1321         bool ret;
1322
1323         _enter_critical_bh(&cam_ctl->lock, &irqL);
1324         ret = _rtw_sec_camid_is_used(cam_ctl, id);
1325         _exit_critical_bh(&cam_ctl->lock, &irqL);
1326
1327         return ret;
1328 }
1329 u8 rtw_get_sec_camid(_adapter *adapter, u8 max_bk_key_num, u8 *sec_key_id)
1330 {
1331         struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
1332         struct cam_ctl_t *cam_ctl = &dvobj->cam_ctl;
1333         int i;
1334         _irqL irqL;
1335         u8 sec_cam_num = 0;
1336
1337         _enter_critical_bh(&cam_ctl->lock, &irqL);
1338         for (i = 0; i < cam_ctl->num; i++) {
1339                 if (_rtw_sec_camid_is_used(cam_ctl, i)) {
1340                         sec_key_id[sec_cam_num++] = i;
1341                         if (sec_cam_num == max_bk_key_num)
1342                                 break;
1343                 }
1344         }
1345         _exit_critical_bh(&cam_ctl->lock, &irqL);
1346
1347         return sec_cam_num;
1348 }
1349
1350 inline bool _rtw_camid_is_gk(_adapter *adapter, u8 cam_id)
1351 {
1352         struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
1353         struct cam_ctl_t *cam_ctl = &dvobj->cam_ctl;
1354         bool ret = _FALSE;
1355
1356         if (cam_id >= cam_ctl->num) {
1357                 rtw_warn_on(1);
1358                 goto exit;
1359         }
1360
1361         if (_rtw_sec_camid_is_used(cam_ctl, cam_id) == _FALSE)
1362                 goto exit;
1363
1364         ret = (dvobj->cam_cache[cam_id].ctrl & BIT6) ? _TRUE : _FALSE;
1365
1366 exit:
1367         return ret;
1368 }
1369
1370 inline bool rtw_camid_is_gk(_adapter *adapter, u8 cam_id)
1371 {
1372         struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
1373         struct cam_ctl_t *cam_ctl = &dvobj->cam_ctl;
1374         _irqL irqL;
1375         bool ret;
1376
1377         _enter_critical_bh(&cam_ctl->lock, &irqL);
1378         ret = _rtw_camid_is_gk(adapter, cam_id);
1379         _exit_critical_bh(&cam_ctl->lock, &irqL);
1380
1381         return ret;
1382 }
1383
1384 bool cam_cache_chk(_adapter *adapter, u8 id, u8 *addr, s16 kid, s8 gk)
1385 {
1386         struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
1387         bool ret = _FALSE;
1388
1389         if (addr && _rtw_memcmp(dvobj->cam_cache[id].mac, addr, ETH_ALEN) == _FALSE)
1390                 goto exit;
1391         if (kid >= 0 && kid != (dvobj->cam_cache[id].ctrl & 0x03))
1392                 goto exit;
1393         if (gk != -1 && (gk ? _TRUE : _FALSE) != _rtw_camid_is_gk(adapter, id))
1394                 goto exit;
1395
1396         ret = _TRUE;
1397
1398 exit:
1399         return ret;
1400 }
1401
1402 s16 _rtw_camid_search(_adapter *adapter, u8 *addr, s16 kid, s8 gk)
1403 {
1404         struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
1405         struct cam_ctl_t *cam_ctl = &dvobj->cam_ctl;
1406         int i;
1407         s16 cam_id = -1;
1408
1409         for (i = 0; i < cam_ctl->num; i++) {
1410                 if (cam_cache_chk(adapter, i, addr, kid, gk)) {
1411                         cam_id = i;
1412                         break;
1413                 }
1414         }
1415
1416         if (0) {
1417                 if (addr)
1418                         RTW_INFO(FUNC_ADPT_FMT" addr:"MAC_FMT" kid:%d, gk:%d, return cam_id:%d\n"
1419                                 , FUNC_ADPT_ARG(adapter), MAC_ARG(addr), kid, gk, cam_id);
1420                 else
1421                         RTW_INFO(FUNC_ADPT_FMT" addr:%p kid:%d, gk:%d, return cam_id:%d\n"
1422                                 , FUNC_ADPT_ARG(adapter), addr, kid, gk, cam_id);
1423         }
1424
1425         return cam_id;
1426 }
1427
1428 s16 rtw_camid_search(_adapter *adapter, u8 *addr, s16 kid, s8 gk)
1429 {
1430         struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
1431         struct cam_ctl_t *cam_ctl = &dvobj->cam_ctl;
1432         _irqL irqL;
1433         s16 cam_id = -1;
1434
1435         _enter_critical_bh(&cam_ctl->lock, &irqL);
1436         cam_id = _rtw_camid_search(adapter, addr, kid, gk);
1437         _exit_critical_bh(&cam_ctl->lock, &irqL);
1438
1439         return cam_id;
1440 }
1441
1442 s16 rtw_get_camid(_adapter *adapter, struct sta_info *sta, u8 *addr, s16 kid)
1443 {
1444         struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
1445         struct cam_ctl_t *cam_ctl = &dvobj->cam_ctl;
1446         int i;
1447 #if 0 /* for testing */
1448         static u8 start_id = 0;
1449 #else
1450         u8 start_id = 0;
1451 #endif
1452         s16 cam_id = -1;
1453
1454         if (addr == NULL) {
1455                 RTW_PRINT(FUNC_ADPT_FMT" mac_address is NULL\n"
1456                           , FUNC_ADPT_ARG(adapter));
1457                 rtw_warn_on(1);
1458                 goto _exit;
1459         }
1460
1461         /* find cam entry which has the same addr, kid (, gk bit) */
1462         if (_rtw_camctl_chk_cap(adapter, SEC_CAP_CHK_BMC) == _TRUE)
1463                 i = _rtw_camid_search(adapter, addr, kid, sta ? _FALSE : _TRUE);
1464         else
1465                 i = _rtw_camid_search(adapter, addr, kid, -1);
1466
1467         if (i >= 0) {
1468                 cam_id = i;
1469                 goto _exit;
1470         }
1471
1472         for (i = 0; i < cam_ctl->num; i++) {
1473                 /* bypass default key which is allocated statically */
1474 #ifndef CONFIG_CONCURRENT_MODE
1475                 if (((i + start_id) % cam_ctl->num) < 4)
1476                         continue;
1477 #endif
1478                 if (_rtw_sec_camid_is_used(cam_ctl, ((i + start_id) % cam_ctl->num)) == _FALSE)
1479                         break;
1480         }
1481
1482         if (i == cam_ctl->num) {
1483                 if (sta)
1484                         RTW_PRINT(FUNC_ADPT_FMT" pairwise key with "MAC_FMT" id:%u no room\n"
1485                                   , FUNC_ADPT_ARG(adapter), MAC_ARG(addr), kid);
1486                 else
1487                         RTW_PRINT(FUNC_ADPT_FMT" group key with "MAC_FMT" id:%u no room\n"
1488                                   , FUNC_ADPT_ARG(adapter), MAC_ARG(addr), kid);
1489                 rtw_warn_on(1);
1490                 goto _exit;
1491         }
1492
1493         cam_id = ((i + start_id) % cam_ctl->num);
1494         start_id = ((i + start_id + 1) % cam_ctl->num);
1495
1496 _exit:
1497         return cam_id;
1498 }
1499
1500 s16 rtw_camid_alloc(_adapter *adapter, struct sta_info *sta, u8 kid, bool *used)
1501 {
1502         struct mlme_ext_info *mlmeinfo = &adapter->mlmeextpriv.mlmext_info;
1503         struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
1504         struct cam_ctl_t *cam_ctl = &dvobj->cam_ctl;
1505         _irqL irqL;
1506         s16 cam_id = -1;
1507
1508         *used = _FALSE;
1509
1510         _enter_critical_bh(&cam_ctl->lock, &irqL);
1511
1512         if ((((mlmeinfo->state & 0x03) == WIFI_FW_AP_STATE) || ((mlmeinfo->state & 0x03) == WIFI_FW_ADHOC_STATE))
1513             && !sta) {
1514 #ifndef CONFIG_CONCURRENT_MODE
1515                 /* AP/Ad-hoc mode group key static alloction to default key by key ID on Non-concurrent*/
1516                 if (kid > 3) {
1517                         RTW_PRINT(FUNC_ADPT_FMT" group key with invalid key id:%u\n"
1518                                   , FUNC_ADPT_ARG(adapter), kid);
1519                         rtw_warn_on(1);
1520                         goto bitmap_handle;
1521                 }
1522                 cam_id = kid;
1523 #else
1524                 u8 *addr = adapter_mac_addr(adapter);
1525
1526                 cam_id = rtw_get_camid(adapter, sta, addr, kid);
1527                 if (1)
1528                         RTW_PRINT(FUNC_ADPT_FMT" group key with "MAC_FMT" assigned cam_id:%u\n"
1529                                 , FUNC_ADPT_ARG(adapter), MAC_ARG(addr), cam_id);
1530 #endif
1531         } else {
1532                 u8 *addr = sta ? sta->hwaddr : NULL;
1533
1534                 if (!sta) {
1535                         if (!(mlmeinfo->state & WIFI_FW_ASSOC_SUCCESS)) {
1536                                 /* bypass STA mode group key setting before connected(ex:WEP) because bssid is not ready */
1537                                 goto bitmap_handle;
1538                         }
1539                         addr = get_bssid(&adapter->mlmepriv);/*A2*/
1540                 }
1541                 cam_id = rtw_get_camid(adapter, sta, addr, kid);
1542         }
1543
1544
1545 bitmap_handle:
1546         if (cam_id >= 0) {
1547                 *used = _rtw_sec_camid_is_used(cam_ctl, cam_id);
1548                 rtw_sec_cam_map_set(&cam_ctl->used, cam_id);
1549         }
1550
1551         _exit_critical_bh(&cam_ctl->lock, &irqL);
1552
1553         return cam_id;
1554 }
1555
1556 void rtw_camid_set(_adapter *adapter, u8 cam_id)
1557 {
1558         struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
1559         struct cam_ctl_t *cam_ctl = &dvobj->cam_ctl;
1560         _irqL irqL;
1561
1562         _enter_critical_bh(&cam_ctl->lock, &irqL);
1563
1564         if (cam_id < cam_ctl->num)
1565                 rtw_sec_cam_map_set(&cam_ctl->used, cam_id);
1566
1567         _exit_critical_bh(&cam_ctl->lock, &irqL);
1568 }
1569
1570 void rtw_camid_free(_adapter *adapter, u8 cam_id)
1571 {
1572         struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
1573         struct cam_ctl_t *cam_ctl = &dvobj->cam_ctl;
1574         _irqL irqL;
1575
1576         _enter_critical_bh(&cam_ctl->lock, &irqL);
1577
1578         if (cam_id < cam_ctl->num)
1579                 rtw_sec_cam_map_clr(&cam_ctl->used, cam_id);
1580
1581         _exit_critical_bh(&cam_ctl->lock, &irqL);
1582 }
1583
1584 /*Must pause TX/RX before use this API*/
1585 inline void rtw_sec_cam_swap(_adapter *adapter, u8 cam_id_a, u8 cam_id_b)
1586 {
1587         struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
1588         struct cam_ctl_t *cam_ctl = &dvobj->cam_ctl;
1589         struct sec_cam_ent cache_a, cache_b;
1590         _irqL irqL;
1591         bool cam_a_used, cam_b_used;
1592
1593         if (1)
1594                 RTW_INFO(ADPT_FMT" - sec_cam %d,%d swap\n", ADPT_ARG(adapter), cam_id_a, cam_id_b);
1595
1596         if (cam_id_a == cam_id_b)
1597                 return;
1598
1599 #ifdef CONFIG_CONCURRENT_MODE
1600         rtw_mi_update_ap_bmc_camid(adapter, cam_id_a, cam_id_b);
1601 #endif
1602
1603         /*setp-1. backup org cam_info*/
1604         _enter_critical_bh(&cam_ctl->lock, &irqL);
1605
1606         cam_a_used = _rtw_sec_camid_is_used(cam_ctl, cam_id_a);
1607         cam_b_used = _rtw_sec_camid_is_used(cam_ctl, cam_id_b);
1608
1609         if (cam_a_used)
1610                 _rtw_memcpy(&cache_a, &dvobj->cam_cache[cam_id_a], sizeof(struct sec_cam_ent));
1611
1612         if (cam_b_used)
1613                 _rtw_memcpy(&cache_b, &dvobj->cam_cache[cam_id_b], sizeof(struct sec_cam_ent));
1614
1615         _exit_critical_bh(&cam_ctl->lock, &irqL);
1616
1617         /*setp-2. clean cam_info*/
1618         if (cam_a_used) {
1619                 rtw_camid_free(adapter, cam_id_a);
1620                 clear_cam_entry(adapter, cam_id_a);
1621         }
1622         if (cam_b_used) {
1623                 rtw_camid_free(adapter, cam_id_b);
1624                 clear_cam_entry(adapter, cam_id_b);
1625         }
1626
1627         /*setp-3. set cam_info*/
1628         if (cam_a_used) {
1629                 write_cam(adapter, cam_id_b, cache_a.ctrl, cache_a.mac, cache_a.key);
1630                 rtw_camid_set(adapter, cam_id_b);
1631         }
1632
1633         if (cam_b_used) {
1634                 write_cam(adapter, cam_id_a, cache_b.ctrl, cache_b.mac, cache_b.key);
1635                 rtw_camid_set(adapter, cam_id_a);
1636         }
1637 }
1638
1639 s16 rtw_get_empty_cam_entry(_adapter *adapter, u8 start_camid)
1640 {
1641         struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
1642         struct cam_ctl_t *cam_ctl = &dvobj->cam_ctl;
1643         _irqL irqL;
1644         int i;
1645         s16 cam_id = -1;
1646
1647         _enter_critical_bh(&cam_ctl->lock, &irqL);
1648         for (i = start_camid; i < cam_ctl->num; i++) {
1649                 if (_FALSE == _rtw_sec_camid_is_used(cam_ctl, i)) {
1650                         cam_id = i;
1651                         break;
1652                 }
1653         }
1654         _exit_critical_bh(&cam_ctl->lock, &irqL);
1655
1656         return cam_id;
1657 }
1658 void rtw_clean_dk_section(_adapter *adapter)
1659 {
1660         struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
1661         struct cam_ctl_t *cam_ctl = dvobj_to_sec_camctl(dvobj);
1662         s16 ept_cam_id;
1663         int i;
1664
1665         for (i = 0; i < 4; i++) {
1666                 if (rtw_sec_camid_is_used(cam_ctl, i)) {
1667                         ept_cam_id = rtw_get_empty_cam_entry(adapter, 4);
1668                         if (ept_cam_id > 0)
1669                                 rtw_sec_cam_swap(adapter, i, ept_cam_id);
1670                 }
1671         }
1672 }
1673 void rtw_clean_hw_dk_cam(_adapter *adapter)
1674 {
1675         int i;
1676
1677         for (i = 0; i < 4; i++)
1678                 rtw_sec_clr_cam_ent(adapter, i);
1679                 /*_clear_cam_entry(adapter, i);*/
1680 }
1681
1682 void flush_all_cam_entry(_adapter *padapter)
1683 {
1684         struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
1685         struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
1686         struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
1687         struct security_priv *psecpriv = &padapter->securitypriv;
1688
1689 #ifdef CONFIG_CONCURRENT_MODE
1690         if (check_fwstate(pmlmepriv, WIFI_STATION_STATE)) {
1691                 struct sta_priv *pstapriv = &padapter->stapriv;
1692                 struct sta_info         *psta;
1693
1694                 psta = rtw_get_stainfo(pstapriv, pmlmeinfo->network.MacAddress);
1695                 if (psta) {
1696                         if (psta->state & WIFI_AP_STATE) {
1697                                 /*clear cam when ap free per sta_info*/
1698                         } else
1699                                 rtw_clearstakey_cmd(padapter, psta, _FALSE);
1700                 }
1701         } else if (check_fwstate(pmlmepriv, WIFI_AP_STATE) == _TRUE) {
1702 #if 1
1703                 int cam_id = -1;
1704                 u8 *addr = adapter_mac_addr(padapter);
1705
1706                 while ((cam_id = rtw_camid_search(padapter, addr, -1, -1)) >= 0) {
1707                         RTW_PRINT("clear wep or group key for addr:"MAC_FMT", camid:%d\n", MAC_ARG(addr), cam_id);
1708                         clear_cam_entry(padapter, cam_id);
1709                         rtw_camid_free(padapter, cam_id);
1710                 }
1711 #else
1712                 /* clear default key */
1713                 int i, cam_id;
1714                 u8 null_addr[ETH_ALEN] = {0, 0, 0, 0, 0, 0};
1715
1716                 for (i = 0; i < 4; i++) {
1717                         cam_id = rtw_camid_search(padapter, null_addr, i, -1);
1718                         if (cam_id >= 0) {
1719                                 clear_cam_entry(padapter, cam_id);
1720                                 rtw_camid_free(padapter, cam_id);
1721                         }
1722                 }
1723                 /* clear default key related key search setting */
1724                 rtw_hal_set_hwreg(padapter, HW_VAR_SEC_DK_CFG, (u8 *)_FALSE);
1725 #endif
1726         }
1727
1728 #else /*NON CONFIG_CONCURRENT_MODE*/
1729
1730         invalidate_cam_all(padapter);
1731         /* clear default key related key search setting */
1732         rtw_hal_set_hwreg(padapter, HW_VAR_SEC_DK_CFG, (u8 *)_FALSE);
1733 #endif
1734 }
1735
1736 #if defined(CONFIG_P2P) && defined(CONFIG_WFD)
1737 void rtw_process_wfd_ie(_adapter *adapter, u8 *wfd_ie, u8 wfd_ielen, const char *tag)
1738 {
1739         struct wifidirect_info *wdinfo = &adapter->wdinfo;
1740
1741         u8 *attr_content;
1742         u32 attr_contentlen = 0;
1743
1744         if (!hal_chk_wl_func(adapter, WL_FUNC_MIRACAST))
1745                 return;
1746
1747         RTW_INFO("[%s] Found WFD IE\n", tag);
1748         attr_content = rtw_get_wfd_attr_content(wfd_ie, wfd_ielen, WFD_ATTR_DEVICE_INFO, NULL, &attr_contentlen);
1749         if (attr_content && attr_contentlen) {
1750                 wdinfo->wfd_info->peer_rtsp_ctrlport = RTW_GET_BE16(attr_content + 2);
1751                 RTW_INFO("[%s] Peer PORT NUM = %d\n", tag, wdinfo->wfd_info->peer_rtsp_ctrlport);
1752         }
1753 }
1754
1755 void rtw_process_wfd_ies(_adapter *adapter, u8 *ies, u8 ies_len, const char *tag)
1756 {
1757         u8 *wfd_ie;
1758         u32     wfd_ielen;
1759
1760         if (!hal_chk_wl_func(adapter, WL_FUNC_MIRACAST))
1761                 return;
1762
1763         wfd_ie = rtw_get_wfd_ie(ies, ies_len, NULL, &wfd_ielen);
1764         while (wfd_ie) {
1765                 rtw_process_wfd_ie(adapter, wfd_ie, wfd_ielen, tag);
1766                 wfd_ie = rtw_get_wfd_ie(wfd_ie + wfd_ielen, (ies + ies_len) - (wfd_ie + wfd_ielen), NULL, &wfd_ielen);
1767         }
1768 }
1769 #endif /* defined(CONFIG_P2P) && defined(CONFIG_WFD) */
1770
1771 int WMM_param_handler(_adapter *padapter, PNDIS_802_11_VARIABLE_IEs     pIE)
1772 {
1773         /* struct registry_priv *pregpriv = &padapter->registrypriv; */
1774         struct mlme_priv        *pmlmepriv = &(padapter->mlmepriv);
1775         struct mlme_ext_priv    *pmlmeext = &padapter->mlmeextpriv;
1776         struct mlme_ext_info    *pmlmeinfo = &(pmlmeext->mlmext_info);
1777
1778         if (pmlmepriv->qospriv.qos_option == 0) {
1779                 pmlmeinfo->WMM_enable = 0;
1780                 return _FALSE;
1781         }
1782
1783         if (_rtw_memcmp(&(pmlmeinfo->WMM_param), (pIE->data + 6), sizeof(struct WMM_para_element)))
1784                 return _FALSE;
1785         else
1786                 _rtw_memcpy(&(pmlmeinfo->WMM_param), (pIE->data + 6), sizeof(struct WMM_para_element));
1787         pmlmeinfo->WMM_enable = 1;
1788         return _TRUE;
1789
1790 #if 0
1791         if (pregpriv->wifi_spec == 1) {
1792                 if (pmlmeinfo->WMM_enable == 1) {
1793                         /* todo: compare the parameter set count & decide wheher to update or not */
1794                         return _FAIL;
1795                 } else {
1796                         pmlmeinfo->WMM_enable = 1;
1797                         _rtw_rtw_memcpy(&(pmlmeinfo->WMM_param), (pIE->data + 6), sizeof(struct WMM_para_element));
1798                         return _TRUE;
1799                 }
1800         } else {
1801                 pmlmeinfo->WMM_enable = 0;
1802                 return _FAIL;
1803         }
1804 #endif
1805
1806 }
1807
1808 void WMMOnAssocRsp(_adapter *padapter)
1809 {
1810         u8      ACI, ACM, AIFS, ECWMin, ECWMax, aSifsTime;
1811         u8      acm_mask;
1812         u16     TXOP;
1813         u32     acParm, i;
1814         u32     edca[4], inx[4];
1815         struct mlme_ext_priv    *pmlmeext = &padapter->mlmeextpriv;
1816         struct mlme_ext_info    *pmlmeinfo = &(pmlmeext->mlmext_info);
1817         struct xmit_priv                *pxmitpriv = &padapter->xmitpriv;
1818         struct registry_priv    *pregpriv = &padapter->registrypriv;
1819
1820         acm_mask = 0;
1821
1822         if (IsSupported5G(pmlmeext->cur_wireless_mode) ||
1823             (pmlmeext->cur_wireless_mode & WIRELESS_11_24N))
1824                 aSifsTime = 16;
1825         else
1826                 aSifsTime = 10;
1827
1828         if (pmlmeinfo->WMM_enable == 0) {
1829                 padapter->mlmepriv.acm_mask = 0;
1830
1831                 AIFS = aSifsTime + (2 * pmlmeinfo->slotTime);
1832
1833                 if (pmlmeext->cur_wireless_mode & (WIRELESS_11G | WIRELESS_11A)) {
1834                         ECWMin = 4;
1835                         ECWMax = 10;
1836                 } else if (pmlmeext->cur_wireless_mode & WIRELESS_11B) {
1837                         ECWMin = 5;
1838                         ECWMax = 10;
1839                 } else {
1840                         ECWMin = 4;
1841                         ECWMax = 10;
1842                 }
1843
1844                 TXOP = 0;
1845                 acParm = AIFS | (ECWMin << 8) | (ECWMax << 12) | (TXOP << 16);
1846                 rtw_hal_set_hwreg(padapter, HW_VAR_AC_PARAM_BE, (u8 *)(&acParm));
1847                 rtw_hal_set_hwreg(padapter, HW_VAR_AC_PARAM_BK, (u8 *)(&acParm));
1848                 rtw_hal_set_hwreg(padapter, HW_VAR_AC_PARAM_VI, (u8 *)(&acParm));
1849
1850                 ECWMin = 2;
1851                 ECWMax = 3;
1852                 TXOP = 0x2f;
1853                 acParm = AIFS | (ECWMin << 8) | (ECWMax << 12) | (TXOP << 16);
1854                 rtw_hal_set_hwreg(padapter, HW_VAR_AC_PARAM_VO, (u8 *)(&acParm));
1855         } else {
1856                 edca[0] = edca[1] = edca[2] = edca[3] = 0;
1857
1858                 for (i = 0; i < 4; i++) {
1859                         ACI = (pmlmeinfo->WMM_param.ac_param[i].ACI_AIFSN >> 5) & 0x03;
1860                         ACM = (pmlmeinfo->WMM_param.ac_param[i].ACI_AIFSN >> 4) & 0x01;
1861
1862                         /* AIFS = AIFSN * slot time + SIFS - r2t phy delay */
1863                         AIFS = (pmlmeinfo->WMM_param.ac_param[i].ACI_AIFSN & 0x0f) * pmlmeinfo->slotTime + aSifsTime;
1864
1865                         ECWMin = (pmlmeinfo->WMM_param.ac_param[i].CW & 0x0f);
1866                         ECWMax = (pmlmeinfo->WMM_param.ac_param[i].CW & 0xf0) >> 4;
1867                         TXOP = le16_to_cpu(pmlmeinfo->WMM_param.ac_param[i].TXOP_limit);
1868
1869                         acParm = AIFS | (ECWMin << 8) | (ECWMax << 12) | (TXOP << 16);
1870
1871                         switch (ACI) {
1872                         case 0x0:
1873                                 rtw_hal_set_hwreg(padapter, HW_VAR_AC_PARAM_BE, (u8 *)(&acParm));
1874                                 acm_mask |= (ACM ? BIT(1) : 0);
1875                                 edca[XMIT_BE_QUEUE] = acParm;
1876                                 break;
1877
1878                         case 0x1:
1879                                 rtw_hal_set_hwreg(padapter, HW_VAR_AC_PARAM_BK, (u8 *)(&acParm));
1880                                 /* acm_mask |= (ACM? BIT(0):0); */
1881                                 edca[XMIT_BK_QUEUE] = acParm;
1882                                 break;
1883
1884                         case 0x2:
1885                                 rtw_hal_set_hwreg(padapter, HW_VAR_AC_PARAM_VI, (u8 *)(&acParm));
1886                                 acm_mask |= (ACM ? BIT(2) : 0);
1887                                 edca[XMIT_VI_QUEUE] = acParm;
1888                                 break;
1889
1890                         case 0x3:
1891                                 rtw_hal_set_hwreg(padapter, HW_VAR_AC_PARAM_VO, (u8 *)(&acParm));
1892                                 acm_mask |= (ACM ? BIT(3) : 0);
1893                                 edca[XMIT_VO_QUEUE] = acParm;
1894                                 break;
1895                         }
1896
1897                         RTW_INFO("WMM(%x): %x, %x\n", ACI, ACM, acParm);
1898                 }
1899
1900                 if (padapter->registrypriv.acm_method == 1)
1901                         rtw_hal_set_hwreg(padapter, HW_VAR_ACM_CTRL, (u8 *)(&acm_mask));
1902                 else
1903                         padapter->mlmepriv.acm_mask = acm_mask;
1904
1905                 inx[0] = 0;
1906                 inx[1] = 1;
1907                 inx[2] = 2;
1908                 inx[3] = 3;
1909
1910                 if (pregpriv->wifi_spec == 1) {
1911                         u32     j, tmp, change_inx = _FALSE;
1912
1913                         /* entry indx: 0->vo, 1->vi, 2->be, 3->bk. */
1914                         for (i = 0; i < 4; i++) {
1915                                 for (j = i + 1; j < 4; j++) {
1916                                         /* compare CW and AIFS */
1917                                         if ((edca[j] & 0xFFFF) < (edca[i] & 0xFFFF))
1918                                                 change_inx = _TRUE;
1919                                         else if ((edca[j] & 0xFFFF) == (edca[i] & 0xFFFF)) {
1920                                                 /* compare TXOP */
1921                                                 if ((edca[j] >> 16) > (edca[i] >> 16))
1922                                                         change_inx = _TRUE;
1923                                         }
1924
1925                                         if (change_inx) {
1926                                                 tmp = edca[i];
1927                                                 edca[i] = edca[j];
1928                                                 edca[j] = tmp;
1929
1930                                                 tmp = inx[i];
1931                                                 inx[i] = inx[j];
1932                                                 inx[j] = tmp;
1933
1934                                                 change_inx = _FALSE;
1935                                         }
1936                                 }
1937                         }
1938                 }
1939
1940                 for (i = 0; i < 4; i++) {
1941                         pxmitpriv->wmm_para_seq[i] = inx[i];
1942                         RTW_INFO("wmm_para_seq(%d): %d\n", i, pxmitpriv->wmm_para_seq[i]);
1943                 }
1944         }
1945 }
1946
1947 static void bwmode_update_check(_adapter *padapter, PNDIS_802_11_VARIABLE_IEs pIE)
1948 {
1949 #ifdef CONFIG_80211N_HT
1950         unsigned char    new_bwmode;
1951         unsigned char  new_ch_offset;
1952         struct HT_info_element  *pHT_info;
1953         struct mlme_priv        *pmlmepriv = &(padapter->mlmepriv);
1954         struct mlme_ext_priv    *pmlmeext = &padapter->mlmeextpriv;
1955         struct mlme_ext_info    *pmlmeinfo = &(pmlmeext->mlmext_info);
1956         struct registry_priv *pregistrypriv = &padapter->registrypriv;
1957         struct ht_priv                  *phtpriv = &pmlmepriv->htpriv;
1958         u8      cbw40_enable = 0;
1959
1960         if (!pIE)
1961                 return;
1962
1963         if (phtpriv->ht_option == _FALSE)
1964                 return;
1965
1966         if (pmlmeext->cur_bwmode >= CHANNEL_WIDTH_80)
1967                 return;
1968
1969         if (pIE->Length > sizeof(struct HT_info_element))
1970                 return;
1971
1972         pHT_info = (struct HT_info_element *)pIE->data;
1973
1974         if (hal_chk_bw_cap(padapter, BW_CAP_40M)) {
1975                 if (pmlmeext->cur_channel > 14) {
1976                         if (REGSTY_IS_BW_5G_SUPPORT(pregistrypriv, CHANNEL_WIDTH_40))
1977                                 cbw40_enable = 1;
1978                 } else {
1979                         if (REGSTY_IS_BW_2G_SUPPORT(pregistrypriv, CHANNEL_WIDTH_40))
1980                                 cbw40_enable = 1;
1981                 }
1982         }
1983
1984         if ((pHT_info->infos[0] & BIT(2)) && cbw40_enable) {
1985                 new_bwmode = CHANNEL_WIDTH_40;
1986
1987                 switch (pHT_info->infos[0] & 0x3) {
1988                 case 1:
1989                         new_ch_offset = HAL_PRIME_CHNL_OFFSET_LOWER;
1990                         break;
1991
1992                 case 3:
1993                         new_ch_offset = HAL_PRIME_CHNL_OFFSET_UPPER;
1994                         break;
1995
1996                 default:
1997                         new_bwmode = CHANNEL_WIDTH_20;
1998                         new_ch_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE;
1999                         break;
2000                 }
2001         } else {
2002                 new_bwmode = CHANNEL_WIDTH_20;
2003                 new_ch_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE;
2004         }
2005
2006
2007         if ((new_bwmode != pmlmeext->cur_bwmode || new_ch_offset != pmlmeext->cur_ch_offset)
2008             && new_bwmode < pmlmeext->cur_bwmode
2009            ) {
2010                 pmlmeinfo->bwmode_updated = _TRUE;
2011
2012                 pmlmeext->cur_bwmode = new_bwmode;
2013                 pmlmeext->cur_ch_offset = new_ch_offset;
2014
2015                 /* update HT info also */
2016                 HT_info_handler(padapter, pIE);
2017         } else
2018                 pmlmeinfo->bwmode_updated = _FALSE;
2019
2020
2021         if (_TRUE == pmlmeinfo->bwmode_updated) {
2022                 struct sta_info *psta;
2023                 WLAN_BSSID_EX   *cur_network = &(pmlmeinfo->network);
2024                 struct sta_priv *pstapriv = &padapter->stapriv;
2025
2026                 /* set_channel_bwmode(padapter, pmlmeext->cur_channel, pmlmeext->cur_ch_offset, pmlmeext->cur_bwmode); */
2027
2028
2029                 /* update ap's stainfo */
2030                 psta = rtw_get_stainfo(pstapriv, cur_network->MacAddress);
2031                 if (psta) {
2032                         struct ht_priv  *phtpriv_sta = &psta->htpriv;
2033
2034                         if (phtpriv_sta->ht_option) {
2035                                 /* bwmode                                */
2036                                 psta->bw_mode = pmlmeext->cur_bwmode;
2037                                 phtpriv_sta->ch_offset = pmlmeext->cur_ch_offset;
2038                         } else {
2039                                 psta->bw_mode = CHANNEL_WIDTH_20;
2040                                 phtpriv_sta->ch_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE;
2041                         }
2042
2043                         rtw_dm_ra_mask_wk_cmd(padapter, (u8 *)psta);
2044                 }
2045
2046                 /* pmlmeinfo->bwmode_updated = _FALSE; */ /* bwmode_updated done, reset it! */
2047         }
2048 #endif /* CONFIG_80211N_HT */
2049 }
2050
2051 void HT_caps_handler(_adapter *padapter, PNDIS_802_11_VARIABLE_IEs pIE)
2052 {
2053 #ifdef CONFIG_80211N_HT
2054         unsigned int    i;
2055         u8      rf_type = RF_1T1R;
2056         u8      max_AMPDU_len, min_MPDU_spacing;
2057         u8      cur_ldpc_cap = 0, cur_stbc_cap = 0, cur_beamform_cap = 0;
2058         struct mlme_ext_priv    *pmlmeext = &padapter->mlmeextpriv;
2059         struct mlme_ext_info    *pmlmeinfo = &(pmlmeext->mlmext_info);
2060         struct mlme_priv                *pmlmepriv = &padapter->mlmepriv;
2061         struct ht_priv                  *phtpriv = &pmlmepriv->htpriv;
2062         struct registry_priv    *pregistrypriv = &padapter->registrypriv;
2063
2064         if (pIE == NULL)
2065                 return;
2066
2067         if (phtpriv->ht_option == _FALSE)
2068                 return;
2069
2070         pmlmeinfo->HT_caps_enable = 1;
2071
2072         for (i = 0; i < (pIE->Length); i++) {
2073                 if (i != 2) {
2074                         /*      Commented by Albert 2010/07/12 */
2075                         /*      Got the endian issue here. */
2076                         pmlmeinfo->HT_caps.u.HT_cap[i] &= (pIE->data[i]);
2077                 } else {
2078                         /* AMPDU Parameters field */
2079
2080                         /* Get MIN of MAX AMPDU Length Exp */
2081                         if ((pmlmeinfo->HT_caps.u.HT_cap_element.AMPDU_para & 0x3) > (pIE->data[i] & 0x3))
2082                                 max_AMPDU_len = (pIE->data[i] & 0x3);
2083                         else
2084                                 max_AMPDU_len = (pmlmeinfo->HT_caps.u.HT_cap_element.AMPDU_para & 0x3);
2085
2086                         /* Get MAX of MIN MPDU Start Spacing */
2087                         if ((pmlmeinfo->HT_caps.u.HT_cap_element.AMPDU_para & 0x1c) > (pIE->data[i] & 0x1c))
2088                                 min_MPDU_spacing = (pmlmeinfo->HT_caps.u.HT_cap_element.AMPDU_para & 0x1c);
2089                         else
2090                                 min_MPDU_spacing = (pIE->data[i] & 0x1c);
2091
2092                         pmlmeinfo->HT_caps.u.HT_cap_element.AMPDU_para = max_AMPDU_len | min_MPDU_spacing;
2093                 }
2094         }
2095
2096         /*      Commented by Albert 2010/07/12 */
2097         /*      Have to handle the endian issue after copying. */
2098         /*      HT_ext_caps didn't be used yet.  */
2099         pmlmeinfo->HT_caps.u.HT_cap_element.HT_caps_info = le16_to_cpu(pmlmeinfo->HT_caps.u.HT_cap_element.HT_caps_info);
2100         pmlmeinfo->HT_caps.u.HT_cap_element.HT_ext_caps = le16_to_cpu(pmlmeinfo->HT_caps.u.HT_cap_element.HT_ext_caps);
2101
2102         rtw_hal_get_hwreg(padapter, HW_VAR_RF_TYPE, (u8 *)(&rf_type));
2103
2104
2105         /* update the MCS set */
2106         for (i = 0; i < 16; i++)
2107                 pmlmeinfo->HT_caps.u.HT_cap_element.MCS_rate[i] &= pmlmeext->default_supported_mcs_set[i];
2108
2109         /* update the MCS rates */
2110         switch (rf_type) {
2111         case RF_1T1R:
2112         case RF_1T2R:
2113                 set_mcs_rate_by_mask(pmlmeinfo->HT_caps.u.HT_cap_element.MCS_rate, MCS_RATE_1R);
2114                 break;
2115         case RF_2T2R:
2116 #ifdef CONFIG_DISABLE_MCS13TO15
2117                 if (pmlmeext->cur_bwmode == CHANNEL_WIDTH_40 && pregistrypriv->wifi_spec != 1)
2118                         set_mcs_rate_by_mask(pmlmeinfo->HT_caps.u.HT_cap_element.MCS_rate, MCS_RATE_2R_13TO15_OFF);
2119                 else
2120                         set_mcs_rate_by_mask(pmlmeinfo->HT_caps.u.HT_cap_element.MCS_rate, MCS_RATE_2R);
2121 #else /* CONFIG_DISABLE_MCS13TO15 */
2122                 set_mcs_rate_by_mask(pmlmeinfo->HT_caps.u.HT_cap_element.MCS_rate, MCS_RATE_2R);
2123 #endif /* CONFIG_DISABLE_MCS13TO15 */
2124                 break;
2125         case RF_3T3R:
2126                 set_mcs_rate_by_mask(pmlmeinfo->HT_caps.u.HT_cap_element.MCS_rate, MCS_RATE_3R);
2127                 break;
2128         default:
2129                 RTW_INFO("[warning] rf_type %d is not expected\n", rf_type);
2130         }
2131
2132         if (check_fwstate(pmlmepriv, WIFI_AP_STATE)) {
2133                 /* Config STBC setting */
2134                 if (TEST_FLAG(phtpriv->stbc_cap, STBC_HT_ENABLE_TX) && GET_HT_CAP_ELE_RX_STBC(pIE->data)) {
2135                         SET_FLAG(cur_stbc_cap, STBC_HT_ENABLE_TX);
2136                         RTW_INFO("Enable HT Tx STBC !\n");
2137                 }
2138                 phtpriv->stbc_cap = cur_stbc_cap;
2139
2140 #ifdef CONFIG_BEAMFORMING
2141                 /* Config Tx beamforming setting */
2142                 if (TEST_FLAG(phtpriv->beamform_cap, BEAMFORMING_HT_BEAMFORMER_ENABLE) &&
2143                     GET_HT_CAP_TXBF_EXPLICIT_COMP_STEERING_CAP(pIE->data)) {
2144                         SET_FLAG(cur_beamform_cap, BEAMFORMING_HT_BEAMFORMER_ENABLE);
2145                         /* Shift to BEAMFORMING_HT_BEAMFORMEE_CHNL_EST_CAP*/
2146                         SET_FLAG(cur_beamform_cap, GET_HT_CAP_TXBF_CHNL_ESTIMATION_NUM_ANTENNAS(pIE->data) << 6);
2147                 }
2148
2149                 if (TEST_FLAG(phtpriv->beamform_cap, BEAMFORMING_HT_BEAMFORMEE_ENABLE) &&
2150                     GET_HT_CAP_TXBF_EXPLICIT_COMP_FEEDBACK_CAP(pIE->data)) {
2151                         SET_FLAG(cur_beamform_cap, BEAMFORMING_HT_BEAMFORMEE_ENABLE);
2152                         /* Shift to BEAMFORMING_HT_BEAMFORMER_STEER_NUM*/
2153                         SET_FLAG(cur_beamform_cap, GET_HT_CAP_TXBF_COMP_STEERING_NUM_ANTENNAS(pIE->data) << 4);
2154                 }
2155                 phtpriv->beamform_cap = cur_beamform_cap;
2156                 if (cur_beamform_cap)
2157                         RTW_INFO("AP HT Beamforming Cap = 0x%02X\n", cur_beamform_cap);
2158 #endif /*CONFIG_BEAMFORMING*/
2159         } else {
2160                 /*WIFI_STATION_STATEorI_ADHOC_STATE or WIFI_ADHOC_MASTER_STATE*/
2161                 /* Config LDPC Coding Capability */
2162                 if (TEST_FLAG(phtpriv->ldpc_cap, LDPC_HT_ENABLE_TX) && GET_HT_CAP_ELE_LDPC_CAP(pIE->data)) {
2163                         SET_FLAG(cur_ldpc_cap, (LDPC_HT_ENABLE_TX | LDPC_HT_CAP_TX));
2164                         RTW_INFO("Enable HT Tx LDPC!\n");
2165                 }
2166                 phtpriv->ldpc_cap = cur_ldpc_cap;
2167
2168                 /* Config STBC setting */
2169                 if (TEST_FLAG(phtpriv->stbc_cap, STBC_HT_ENABLE_TX) && GET_HT_CAP_ELE_RX_STBC(pIE->data)) {
2170                         SET_FLAG(cur_stbc_cap, (STBC_HT_ENABLE_TX | STBC_HT_CAP_TX));
2171                         RTW_INFO("Enable HT Tx STBC!\n");
2172                 }
2173                 phtpriv->stbc_cap = cur_stbc_cap;
2174
2175 #ifdef CONFIG_BEAMFORMING
2176 #ifdef RTW_BEAMFORMING_VERSION_2
2177                 /* Config beamforming setting */
2178                 if (TEST_FLAG(phtpriv->beamform_cap, BEAMFORMING_HT_BEAMFORMEE_ENABLE) &&
2179                     GET_HT_CAP_TXBF_EXPLICIT_COMP_STEERING_CAP(pIE->data)) {
2180                         SET_FLAG(cur_beamform_cap, BEAMFORMING_HT_BEAMFORMEE_ENABLE);
2181                         /* Shift to BEAMFORMING_HT_BEAMFORMEE_CHNL_EST_CAP*/
2182                         SET_FLAG(cur_beamform_cap, GET_HT_CAP_TXBF_CHNL_ESTIMATION_NUM_ANTENNAS(pIE->data) << 6);
2183                 }
2184
2185                 if (TEST_FLAG(phtpriv->beamform_cap, BEAMFORMING_HT_BEAMFORMER_ENABLE) &&
2186                     GET_HT_CAP_TXBF_EXPLICIT_COMP_FEEDBACK_CAP(pIE->data)) {
2187                         SET_FLAG(cur_beamform_cap, BEAMFORMING_HT_BEAMFORMER_ENABLE);
2188                         /* Shift to BEAMFORMING_HT_BEAMFORMER_STEER_NUM*/
2189                         SET_FLAG(cur_beamform_cap, GET_HT_CAP_TXBF_COMP_STEERING_NUM_ANTENNAS(pIE->data) << 4);
2190                 }
2191 #else /* !RTW_BEAMFORMING_VERSION_2 */
2192                 /* Config Tx beamforming setting */
2193                 if (TEST_FLAG(phtpriv->beamform_cap, BEAMFORMING_HT_BEAMFORMEE_ENABLE) &&
2194                     GET_HT_CAP_TXBF_EXPLICIT_COMP_STEERING_CAP(pIE->data)) {
2195                         SET_FLAG(cur_beamform_cap, BEAMFORMING_HT_BEAMFORMER_ENABLE);
2196                         /* Shift to BEAMFORMING_HT_BEAMFORMEE_CHNL_EST_CAP*/
2197                         SET_FLAG(cur_beamform_cap, GET_HT_CAP_TXBF_CHNL_ESTIMATION_NUM_ANTENNAS(pIE->data) << 6);
2198                 }
2199
2200                 if (TEST_FLAG(phtpriv->beamform_cap, BEAMFORMING_HT_BEAMFORMER_ENABLE) &&
2201                     GET_HT_CAP_TXBF_EXPLICIT_COMP_FEEDBACK_CAP(pIE->data)) {
2202                         SET_FLAG(cur_beamform_cap, BEAMFORMING_HT_BEAMFORMEE_ENABLE);
2203                         /* Shift to BEAMFORMING_HT_BEAMFORMER_STEER_NUM*/
2204                         SET_FLAG(cur_beamform_cap, GET_HT_CAP_TXBF_COMP_STEERING_NUM_ANTENNAS(pIE->data) << 4);
2205                 }
2206 #endif /* !RTW_BEAMFORMING_VERSION_2 */
2207                 phtpriv->beamform_cap = cur_beamform_cap;
2208                 if (cur_beamform_cap)
2209                         RTW_INFO("Client HT Beamforming Cap = 0x%02X\n", cur_beamform_cap);
2210 #endif /*CONFIG_BEAMFORMING*/
2211         }
2212
2213 #endif /* CONFIG_80211N_HT */
2214 }
2215
2216 void HT_info_handler(_adapter *padapter, PNDIS_802_11_VARIABLE_IEs pIE)
2217 {
2218 #ifdef CONFIG_80211N_HT
2219         struct mlme_ext_priv    *pmlmeext = &padapter->mlmeextpriv;
2220         struct mlme_ext_info    *pmlmeinfo = &(pmlmeext->mlmext_info);
2221         struct mlme_priv                *pmlmepriv = &padapter->mlmepriv;
2222         struct ht_priv                  *phtpriv = &pmlmepriv->htpriv;
2223
2224         if (pIE == NULL)
2225                 return;
2226
2227         if (phtpriv->ht_option == _FALSE)
2228                 return;
2229
2230
2231         if (pIE->Length > sizeof(struct HT_info_element))
2232                 return;
2233
2234         pmlmeinfo->HT_info_enable = 1;
2235         _rtw_memcpy(&(pmlmeinfo->HT_info), pIE->data, pIE->Length);
2236 #endif /* CONFIG_80211N_HT */
2237         return;
2238 }
2239
2240 void HTOnAssocRsp(_adapter *padapter)
2241 {
2242         unsigned char           max_AMPDU_len;
2243         unsigned char           min_MPDU_spacing;
2244         /* struct registry_priv  *pregpriv = &padapter->registrypriv; */
2245         struct mlme_ext_priv    *pmlmeext = &padapter->mlmeextpriv;
2246         struct mlme_ext_info    *pmlmeinfo = &(pmlmeext->mlmext_info);
2247
2248         RTW_INFO("%s\n", __FUNCTION__);
2249
2250         if ((pmlmeinfo->HT_info_enable) && (pmlmeinfo->HT_caps_enable))
2251                 pmlmeinfo->HT_enable = 1;
2252         else {
2253                 pmlmeinfo->HT_enable = 0;
2254                 /* set_channel_bwmode(padapter, pmlmeext->cur_channel, pmlmeext->cur_ch_offset, pmlmeext->cur_bwmode); */
2255                 return;
2256         }
2257
2258         /* handle A-MPDU parameter field */
2259         /*
2260                 AMPDU_para [1:0]:Max AMPDU Len => 0:8k , 1:16k, 2:32k, 3:64k
2261                 AMPDU_para [4:2]:Min MPDU Start Spacing
2262         */
2263         max_AMPDU_len = pmlmeinfo->HT_caps.u.HT_cap_element.AMPDU_para & 0x03;
2264
2265         min_MPDU_spacing = (pmlmeinfo->HT_caps.u.HT_cap_element.AMPDU_para & 0x1c) >> 2;
2266
2267         rtw_hal_set_hwreg(padapter, HW_VAR_AMPDU_MIN_SPACE, (u8 *)(&min_MPDU_spacing));
2268
2269         rtw_hal_set_hwreg(padapter, HW_VAR_AMPDU_FACTOR, (u8 *)(&max_AMPDU_len));
2270
2271 #if 0 /* move to rtw_update_ht_cap() */
2272         if ((pregpriv->bw_mode > 0) &&
2273             (pmlmeinfo->HT_caps.u.HT_cap_element.HT_caps_info & BIT(1)) &&
2274             (pmlmeinfo->HT_info.infos[0] & BIT(2))) {
2275                 /* switch to the 40M Hz mode accoring to the AP */
2276                 pmlmeext->cur_bwmode = CHANNEL_WIDTH_40;
2277                 switch ((pmlmeinfo->HT_info.infos[0] & 0x3)) {
2278                 case EXTCHNL_OFFSET_UPPER:
2279                         pmlmeext->cur_ch_offset = HAL_PRIME_CHNL_OFFSET_LOWER;
2280                         break;
2281
2282                 case EXTCHNL_OFFSET_LOWER:
2283                         pmlmeext->cur_ch_offset = HAL_PRIME_CHNL_OFFSET_UPPER;
2284                         break;
2285
2286                 default:
2287                         pmlmeext->cur_ch_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE;
2288                         break;
2289                 }
2290
2291                 /* SelectChannel(padapter, pmlmeext->cur_channel, pmlmeext->cur_ch_offset); */
2292         }
2293 #endif
2294
2295         /* set_channel_bwmode(padapter, pmlmeext->cur_channel, pmlmeext->cur_ch_offset, pmlmeext->cur_bwmode); */
2296
2297 #if 0 /* move to rtw_update_ht_cap() */
2298         /*  */
2299         /* Config SM Power Save setting */
2300         /*  */
2301         pmlmeinfo->SM_PS = (pmlmeinfo->HT_caps.u.HT_cap_element.HT_caps_info & 0x0C) >> 2;
2302         if (pmlmeinfo->SM_PS == WLAN_HT_CAP_SM_PS_STATIC) {
2303 #if 0
2304                 u8 i;
2305                 /* update the MCS rates */
2306                 for (i = 0; i < 16; i++)
2307                         pmlmeinfo->HT_caps.HT_cap_element.MCS_rate[i] &= MCS_rate_1R[i];
2308 #endif
2309                 RTW_INFO("%s(): WLAN_HT_CAP_SM_PS_STATIC\n", __FUNCTION__);
2310         }
2311
2312         /*  */
2313         /* Config current HT Protection mode. */
2314         /*  */
2315         pmlmeinfo->HT_protection = pmlmeinfo->HT_info.infos[1] & 0x3;
2316 #endif
2317
2318 }
2319
2320 void ERP_IE_handler(_adapter *padapter, PNDIS_802_11_VARIABLE_IEs pIE)
2321 {
2322         struct mlme_ext_priv    *pmlmeext = &padapter->mlmeextpriv;
2323         struct mlme_ext_info    *pmlmeinfo = &(pmlmeext->mlmext_info);
2324
2325         if (pIE->Length > 1)
2326                 return;
2327
2328         pmlmeinfo->ERP_enable = 1;
2329         _rtw_memcpy(&(pmlmeinfo->ERP_IE), pIE->data, pIE->Length);
2330 }
2331
2332 void VCS_update(_adapter *padapter, struct sta_info *psta)
2333 {
2334         struct registry_priv    *pregpriv = &padapter->registrypriv;
2335         struct mlme_priv        *pmlmepriv = &padapter->mlmepriv;
2336         struct mlme_ext_priv    *pmlmeext = &padapter->mlmeextpriv;
2337         struct mlme_ext_info    *pmlmeinfo = &(pmlmeext->mlmext_info);
2338
2339         switch (pregpriv->vrtl_carrier_sense) { /* 0:off 1:on 2:auto */
2340         case 0: /* off */
2341                 psta->rtsen = 0;
2342                 psta->cts2self = 0;
2343                 break;
2344
2345         case 1: /* on */
2346                 if (pregpriv->vcs_type == 1) { /* 1:RTS/CTS 2:CTS to self */
2347                         psta->rtsen = 1;
2348                         psta->cts2self = 0;
2349                 } else {
2350                         psta->rtsen = 0;
2351                         psta->cts2self = 1;
2352                 }
2353                 break;
2354
2355         case 2: /* auto */
2356         default:
2357                 if (((pmlmeinfo->ERP_enable) && (pmlmeinfo->ERP_IE & BIT(1)))
2358                     /*||(pmlmepriv->ht_op_mode & HT_INFO_OPERATION_MODE_NON_GF_DEVS_PRESENT)*/
2359                    ) {
2360                         if (pregpriv->vcs_type == 1) {
2361                                 psta->rtsen = 1;
2362                                 psta->cts2self = 0;
2363                         } else {
2364                                 psta->rtsen = 0;
2365                                 psta->cts2self = 1;
2366                         }
2367                 } else {
2368                         psta->rtsen = 0;
2369                         psta->cts2self = 0;
2370                 }
2371                 break;
2372         }
2373 }
2374
2375 void    update_ldpc_stbc_cap(struct sta_info *psta)
2376 {
2377 #ifdef CONFIG_80211N_HT
2378
2379 #ifdef CONFIG_80211AC_VHT
2380         if (psta->vhtpriv.vht_option) {
2381                 if (TEST_FLAG(psta->vhtpriv.ldpc_cap, LDPC_VHT_ENABLE_TX))
2382                         psta->ldpc = 1;
2383
2384                 if (TEST_FLAG(psta->vhtpriv.stbc_cap, STBC_VHT_ENABLE_TX))
2385                         psta->stbc = 1;
2386         } else
2387 #endif /* CONFIG_80211AC_VHT */
2388                 if (psta->htpriv.ht_option) {
2389                         if (TEST_FLAG(psta->htpriv.ldpc_cap, LDPC_HT_ENABLE_TX))
2390                                 psta->ldpc = 1;
2391
2392                         if (TEST_FLAG(psta->htpriv.stbc_cap, STBC_HT_ENABLE_TX))
2393                                 psta->stbc = 1;
2394                 } else {
2395                         psta->ldpc = 0;
2396                         psta->stbc = 0;
2397                 }
2398
2399 #endif /* CONFIG_80211N_HT */
2400 }
2401
2402
2403 /*
2404  * rtw_get_bcn_keys: get beacon keys from recv frame
2405  *
2406  * TODO:
2407  *      WLAN_EID_COUNTRY
2408  *      WLAN_EID_ERP_INFO
2409  *      WLAN_EID_CHANNEL_SWITCH
2410  *      WLAN_EID_PWR_CONSTRAINT
2411  */
2412 int rtw_get_bcn_keys(ADAPTER *Adapter, u8 *pframe, u32 packet_len,
2413                      struct beacon_keys *recv_beacon)
2414 {
2415         int left;
2416         u16 capability;
2417         unsigned char *pos;
2418         struct rtw_ieee802_11_elems elems;
2419         struct rtw_ieee80211_ht_cap *pht_cap = NULL;
2420         struct HT_info_element *pht_info = NULL;
2421
2422         _rtw_memset(recv_beacon, 0, sizeof(*recv_beacon));
2423
2424         /* checking capabilities */
2425         capability = le16_to_cpu(*(unsigned short *)(pframe + WLAN_HDR_A3_LEN + 10));
2426
2427         /* checking IEs */
2428         left = packet_len - sizeof(struct rtw_ieee80211_hdr_3addr) - _BEACON_IE_OFFSET_;
2429         pos = pframe + sizeof(struct rtw_ieee80211_hdr_3addr) + _BEACON_IE_OFFSET_;
2430         if (rtw_ieee802_11_parse_elems(pos, left, &elems, 1) == ParseFailed)
2431                 return _FALSE;
2432
2433         /* check bw and channel offset */
2434         if (elems.ht_capabilities) {
2435                 if (elems.ht_capabilities_len != sizeof(*pht_cap))
2436                         return _FALSE;
2437
2438                 pht_cap = (struct rtw_ieee80211_ht_cap *) elems.ht_capabilities;
2439                 recv_beacon->ht_cap_info = pht_cap->cap_info;
2440         }
2441
2442         if (elems.ht_operation) {
2443                 if (elems.ht_operation_len != sizeof(*pht_info))
2444                         return _FALSE;
2445
2446                 pht_info = (struct HT_info_element *) elems.ht_operation;
2447                 recv_beacon->ht_info_infos_0_sco = pht_info->infos[0] & 0x03;
2448         }
2449
2450         /* Checking for channel */
2451         if (elems.ds_params && elems.ds_params_len == sizeof(recv_beacon->bcn_channel))
2452                 _rtw_memcpy(&recv_beacon->bcn_channel, elems.ds_params,
2453                             sizeof(recv_beacon->bcn_channel));
2454         else if (pht_info)
2455                 /* In 5G, some ap do not have DSSET IE checking HT info for channel */
2456                 recv_beacon->bcn_channel = pht_info->primary_channel;
2457         else {
2458                 /* we don't find channel IE, so don't check it */
2459                 /* RTW_INFO("Oops: %s we don't find channel IE, so don't check it\n", __func__); */
2460                 recv_beacon->bcn_channel = Adapter->mlmeextpriv.cur_channel;
2461         }
2462
2463         /* checking SSID */
2464         if (elems.ssid) {
2465                 if (elems.ssid_len > sizeof(recv_beacon->ssid))
2466                         return _FALSE;
2467
2468                 _rtw_memcpy(recv_beacon->ssid, elems.ssid, elems.ssid_len);
2469                 recv_beacon->ssid_len = elems.ssid_len;
2470         } else
2471                 ; /* means hidden ssid */
2472
2473         /* checking RSN first */
2474         if (elems.rsn_ie && elems.rsn_ie_len) {
2475                 recv_beacon->encryp_protocol = ENCRYP_PROTOCOL_WPA2;
2476                 rtw_parse_wpa2_ie(elems.rsn_ie - 2, elems.rsn_ie_len + 2,
2477                         &recv_beacon->group_cipher, &recv_beacon->pairwise_cipher,
2478                                   &recv_beacon->is_8021x);
2479         }
2480         /* checking WPA secon */
2481         else if (elems.wpa_ie && elems.wpa_ie_len) {
2482                 recv_beacon->encryp_protocol = ENCRYP_PROTOCOL_WPA;
2483                 rtw_parse_wpa_ie(elems.wpa_ie - 2, elems.wpa_ie_len + 2,
2484                         &recv_beacon->group_cipher, &recv_beacon->pairwise_cipher,
2485                                  &recv_beacon->is_8021x);
2486         } else if (capability & BIT(4))
2487                 recv_beacon->encryp_protocol = ENCRYP_PROTOCOL_WEP;
2488
2489         return _TRUE;
2490 }
2491
2492 void rtw_dump_bcn_keys(struct beacon_keys *recv_beacon)
2493 {
2494         int i;
2495         char *p;
2496         u8 ssid[IW_ESSID_MAX_SIZE + 1];
2497
2498         _rtw_memcpy(ssid, recv_beacon->ssid, recv_beacon->ssid_len);
2499         ssid[recv_beacon->ssid_len] = '\0';
2500
2501         RTW_INFO("%s: ssid = %s\n", __func__, ssid);
2502         RTW_INFO("%s: channel = %x\n", __func__, recv_beacon->bcn_channel);
2503         RTW_INFO("%s: ht_cap = %x\n", __func__, recv_beacon->ht_cap_info);
2504         RTW_INFO("%s: ht_info_infos_0_sco = %x\n", __func__, recv_beacon->ht_info_infos_0_sco);
2505         RTW_INFO("%s: sec=%d, group = %x, pair = %x, 8021X = %x\n", __func__,
2506                  recv_beacon->encryp_protocol, recv_beacon->group_cipher,
2507                  recv_beacon->pairwise_cipher, recv_beacon->is_8021x);
2508 }
2509
2510 int rtw_check_bcn_info(ADAPTER *Adapter, u8 *pframe, u32 packet_len)
2511 {
2512 #if 0
2513         unsigned int            len;
2514         unsigned char           *p;
2515         unsigned short  val16, subtype;
2516         struct wlan_network *cur_network = &(Adapter->mlmepriv.cur_network);
2517         /* u8 wpa_ie[255],rsn_ie[255]; */
2518         u16 wpa_len = 0, rsn_len = 0;
2519         u8 encryp_protocol = 0;
2520         WLAN_BSSID_EX *bssid;
2521         int group_cipher = 0, pairwise_cipher = 0, is_8021x = 0;
2522         unsigned char *pbuf;
2523         u32 wpa_ielen = 0;
2524         u8 *pbssid = GetAddr3Ptr(pframe);
2525         u32 hidden_ssid = 0;
2526         u8 cur_network_type, network_type = 0;
2527         struct HT_info_element *pht_info = NULL;
2528         struct rtw_ieee80211_ht_cap *pht_cap = NULL;
2529         u32 bcn_channel;
2530         unsigned short  ht_cap_info;
2531         unsigned char   ht_info_infos_0;
2532 #endif
2533         unsigned int len;
2534         u8 *pbssid = GetAddr3Ptr(pframe);
2535         struct mlme_priv *pmlmepriv = &Adapter->mlmepriv;
2536         struct wlan_network *cur_network = &(Adapter->mlmepriv.cur_network);
2537         struct beacon_keys recv_beacon;
2538
2539         if (is_client_associated_to_ap(Adapter) == _FALSE)
2540                 return _TRUE;
2541
2542         len = packet_len - sizeof(struct rtw_ieee80211_hdr_3addr);
2543
2544         if (len > MAX_IE_SZ) {
2545                 RTW_INFO("%s IE too long for survey event\n", __func__);
2546                 return _FAIL;
2547         }
2548
2549         if (_rtw_memcmp(cur_network->network.MacAddress, pbssid, 6) == _FALSE) {
2550                 RTW_INFO("Oops: rtw_check_network_encrypt linked but recv other bssid bcn\n" MAC_FMT MAC_FMT,
2551                         MAC_ARG(pbssid), MAC_ARG(cur_network->network.MacAddress));
2552                 return _TRUE;
2553         }
2554
2555         if (rtw_get_bcn_keys(Adapter, pframe, packet_len, &recv_beacon) == _FALSE)
2556                 return _TRUE; /* parsing failed => broken IE */
2557
2558         /* don't care hidden ssid, use current beacon ssid directly */
2559         if (recv_beacon.ssid_len == 0) {
2560                 _rtw_memcpy(recv_beacon.ssid, pmlmepriv->cur_beacon_keys.ssid,
2561                             pmlmepriv->cur_beacon_keys.ssid_len);
2562                 recv_beacon.ssid_len = pmlmepriv->cur_beacon_keys.ssid_len;
2563         }
2564
2565         if (_rtw_memcmp(&recv_beacon, &pmlmepriv->cur_beacon_keys, sizeof(recv_beacon)) == _TRUE)
2566                 pmlmepriv->new_beacon_cnts = 0;
2567         else if ((pmlmepriv->new_beacon_cnts == 0) ||
2568                 _rtw_memcmp(&recv_beacon, &pmlmepriv->new_beacon_keys, sizeof(recv_beacon)) == _FALSE) {
2569                 RTW_ERR("%s: start new beacon (seq=%d)\n", __func__, GetSequence(pframe));
2570
2571                 if (pmlmepriv->new_beacon_cnts == 0) {
2572                         RTW_ERR("%s: cur beacon key\n", __func__);
2573                         RTW_DBG_EXPR(rtw_dump_bcn_keys(&pmlmepriv->cur_beacon_keys));
2574                 }
2575
2576                 RTW_ERR("%s: new beacon key\n", __func__);
2577                 RTW_DBG_EXPR(rtw_dump_bcn_keys(&recv_beacon));
2578
2579                 memcpy(&pmlmepriv->new_beacon_keys, &recv_beacon, sizeof(recv_beacon));
2580                 pmlmepriv->new_beacon_cnts = 1;
2581         } else {
2582                 RTW_ERR("%s: new beacon again (seq=%d)\n", __func__, GetSequence(pframe));
2583                 pmlmepriv->new_beacon_cnts++;
2584         }
2585
2586         /* if counter >= max, it means beacon is changed really */
2587         if (pmlmepriv->new_beacon_cnts >= new_bcn_max) {
2588                 RTW_ERR("%s: new beacon occur!!\n", __func__);
2589
2590                 /* check bw mode change only? */
2591                 pmlmepriv->cur_beacon_keys.ht_cap_info = recv_beacon.ht_cap_info;
2592                 pmlmepriv->cur_beacon_keys.ht_info_infos_0_sco = recv_beacon.ht_info_infos_0_sco;
2593
2594                 if (_rtw_memcmp(&recv_beacon, &pmlmepriv->cur_beacon_keys,
2595                                 sizeof(recv_beacon)) == _FALSE) {
2596                         /* beacon is changed, have to do disconnect/connect */
2597                         return _FAIL;
2598                 }
2599
2600                 RTW_INFO("%s bw mode change\n", __func__);
2601                 RTW_INFO("%s bcn now: ht_cap_info:%x ht_info_infos_0:%x\n", __func__,
2602                          cur_network->BcnInfo.ht_cap_info,
2603                          cur_network->BcnInfo.ht_info_infos_0);
2604
2605                 cur_network->BcnInfo.ht_cap_info = recv_beacon.ht_cap_info;
2606                 cur_network->BcnInfo.ht_info_infos_0 =
2607                         (cur_network->BcnInfo.ht_info_infos_0 & (~0x03)) |
2608                         recv_beacon.ht_info_infos_0_sco;
2609
2610                 RTW_INFO("%s bcn link: ht_cap_info:%x ht_info_infos_0:%x\n", __func__,
2611                          cur_network->BcnInfo.ht_cap_info,
2612                          cur_network->BcnInfo.ht_info_infos_0);
2613
2614                 memcpy(&pmlmepriv->cur_beacon_keys, &recv_beacon, sizeof(recv_beacon));
2615                 pmlmepriv->new_beacon_cnts = 0;
2616         }
2617
2618         return _SUCCESS;
2619
2620 #if 0
2621         bssid = (WLAN_BSSID_EX *)rtw_zmalloc(sizeof(WLAN_BSSID_EX));
2622         if (bssid == NULL) {
2623                 RTW_INFO("%s rtw_zmalloc fail !!!\n", __func__);
2624                 return _TRUE;
2625         }
2626
2627         if ((pmlmepriv->timeBcnInfoChkStart != 0) && (rtw_get_passing_time_ms(pmlmepriv->timeBcnInfoChkStart) > DISCONNECT_BY_CHK_BCN_FAIL_OBSERV_PERIOD_IN_MS)) {
2628                 pmlmepriv->timeBcnInfoChkStart = 0;
2629                 pmlmepriv->NumOfBcnInfoChkFail = 0;
2630         }
2631
2632         subtype = GetFrameSubType(pframe) >> 4;
2633
2634         if (subtype == WIFI_BEACON)
2635                 bssid->Reserved[0] = 1;
2636
2637         bssid->Length = sizeof(WLAN_BSSID_EX) - MAX_IE_SZ + len;
2638
2639         /* below is to copy the information element */
2640         bssid->IELength = len;
2641         _rtw_memcpy(bssid->IEs, (pframe + sizeof(struct rtw_ieee80211_hdr_3addr)), bssid->IELength);
2642
2643         /* check bw and channel offset */
2644         /* parsing HT_CAP_IE */
2645         p = rtw_get_ie(bssid->IEs + _FIXED_IE_LENGTH_, _HT_CAPABILITY_IE_, &len, bssid->IELength - _FIXED_IE_LENGTH_);
2646         if (p && len > 0) {
2647                 pht_cap = (struct rtw_ieee80211_ht_cap *)(p + 2);
2648                 ht_cap_info = pht_cap->cap_info;
2649         } else
2650                 ht_cap_info = 0;
2651         /* parsing HT_INFO_IE */
2652         p = rtw_get_ie(bssid->IEs + _FIXED_IE_LENGTH_, _HT_ADD_INFO_IE_, &len, bssid->IELength - _FIXED_IE_LENGTH_);
2653         if (p && len > 0) {
2654                 pht_info = (struct HT_info_element *)(p + 2);
2655                 ht_info_infos_0 = pht_info->infos[0];
2656         } else
2657                 ht_info_infos_0 = 0;
2658         if (ht_cap_info != cur_network->BcnInfo.ht_cap_info ||
2659             ((ht_info_infos_0 & 0x03) != (cur_network->BcnInfo.ht_info_infos_0 & 0x03))) {
2660                 RTW_INFO("%s bcn now: ht_cap_info:%x ht_info_infos_0:%x\n", __func__,
2661                          ht_cap_info, ht_info_infos_0);
2662                 RTW_INFO("%s bcn link: ht_cap_info:%x ht_info_infos_0:%x\n", __func__,
2663                         cur_network->BcnInfo.ht_cap_info, cur_network->BcnInfo.ht_info_infos_0);
2664                 RTW_INFO("%s bw mode change\n", __func__);
2665                 {
2666                         /* bcn_info_update */
2667                         cur_network->BcnInfo.ht_cap_info = ht_cap_info;
2668                         cur_network->BcnInfo.ht_info_infos_0 = ht_info_infos_0;
2669                         /* to do : need to check that whether modify related register of BB or not */
2670                 }
2671                 /* goto _mismatch; */
2672         }
2673
2674         /* Checking for channel */
2675         p = rtw_get_ie(bssid->IEs + _FIXED_IE_LENGTH_, _DSSET_IE_, &len, bssid->IELength - _FIXED_IE_LENGTH_);
2676         if (p)
2677                 bcn_channel = *(p + 2);
2678         else {/* In 5G, some ap do not have DSSET IE checking HT info for channel */
2679                 rtw_get_ie(bssid->IEs + _FIXED_IE_LENGTH_, _HT_ADD_INFO_IE_, &len, bssid->IELength - _FIXED_IE_LENGTH_);
2680                 if (pht_info)
2681                         bcn_channel = pht_info->primary_channel;
2682                 else { /* we don't find channel IE, so don't check it */
2683                         /* RTW_INFO("Oops: %s we don't find channel IE, so don't check it\n", __func__); */
2684                         bcn_channel = Adapter->mlmeextpriv.cur_channel;
2685                 }
2686         }
2687         if (bcn_channel != Adapter->mlmeextpriv.cur_channel) {
2688                 RTW_INFO("%s beacon channel:%d cur channel:%d disconnect\n", __func__,
2689                          bcn_channel, Adapter->mlmeextpriv.cur_channel);
2690                 goto _mismatch;
2691         }
2692
2693         /* checking SSID */
2694         p = rtw_get_ie(bssid->IEs + _FIXED_IE_LENGTH_, _SSID_IE_, &len, bssid->IELength - _FIXED_IE_LENGTH_);
2695         if (p == NULL) {
2696                 RTW_INFO("%s marc: cannot find SSID for survey event\n", __func__);
2697                 hidden_ssid = _TRUE;
2698         } else
2699                 hidden_ssid = _FALSE;
2700
2701         if ((NULL != p) && (_FALSE == hidden_ssid && (*(p + 1)))) {
2702                 _rtw_memcpy(bssid->Ssid.Ssid, (p + 2), *(p + 1));
2703                 bssid->Ssid.SsidLength = *(p + 1);
2704         } else {
2705                 bssid->Ssid.SsidLength = 0;
2706                 bssid->Ssid.Ssid[0] = '\0';
2707         }
2708
2709         RT_TRACE(_module_rtl871x_mlme_c_, _drv_info_, ("%s bssid.Ssid.Ssid:%s bssid.Ssid.SsidLength:%d "
2710                 "cur_network->network.Ssid.Ssid:%s len:%d\n", __func__, bssid->Ssid.Ssid,
2711                         bssid->Ssid.SsidLength, cur_network->network.Ssid.Ssid,
2712                         cur_network->network.Ssid.SsidLength));
2713
2714         if (_rtw_memcmp(bssid->Ssid.Ssid, cur_network->network.Ssid.Ssid, 32) == _FALSE ||
2715             bssid->Ssid.SsidLength != cur_network->network.Ssid.SsidLength) {
2716                 if (bssid->Ssid.Ssid[0] != '\0' && bssid->Ssid.SsidLength != 0) { /* not hidden ssid */
2717                         RTW_INFO("%s(), SSID is not match\n", __func__);
2718                         goto _mismatch;
2719                 }
2720         }
2721
2722         /* check encryption info */
2723         val16 = rtw_get_capability((WLAN_BSSID_EX *)bssid);
2724
2725         if (val16 & BIT(4))
2726                 bssid->Privacy = 1;
2727         else
2728                 bssid->Privacy = 0;
2729
2730         RT_TRACE(_module_rtl871x_mlme_c_, _drv_info_,
2731                 ("%s(): cur_network->network.Privacy is %d, bssid.Privacy is %d\n",
2732                   __func__, cur_network->network.Privacy, bssid->Privacy));
2733         if (cur_network->network.Privacy != bssid->Privacy) {
2734                 RTW_INFO("%s(), privacy is not match\n", __func__);
2735                 goto _mismatch;
2736         }
2737
2738         rtw_get_sec_ie(bssid->IEs, bssid->IELength, NULL, &rsn_len, NULL, &wpa_len);
2739
2740         if (rsn_len > 0)
2741                 encryp_protocol = ENCRYP_PROTOCOL_WPA2;
2742         else if (wpa_len > 0)
2743                 encryp_protocol = ENCRYP_PROTOCOL_WPA;
2744         else {
2745                 if (bssid->Privacy)
2746                         encryp_protocol = ENCRYP_PROTOCOL_WEP;
2747         }
2748
2749         if (cur_network->BcnInfo.encryp_protocol != encryp_protocol) {
2750                 RTW_INFO("%s(): enctyp is not match\n", __func__);
2751                 goto _mismatch;
2752         }
2753
2754         if (encryp_protocol == ENCRYP_PROTOCOL_WPA || encryp_protocol == ENCRYP_PROTOCOL_WPA2) {
2755                 pbuf = rtw_get_wpa_ie(&bssid->IEs[12], &wpa_ielen, bssid->IELength - 12);
2756                 if (pbuf && (wpa_ielen > 0)) {
2757                         if (_SUCCESS == rtw_parse_wpa_ie(pbuf, wpa_ielen + 2, &group_cipher, &pairwise_cipher, &is_8021x)) {
2758                                 RT_TRACE(_module_rtl871x_mlme_c_, _drv_info_,
2759                                         ("%s pnetwork->pairwise_cipher: %d, group_cipher is %d, is_8021x is %d\n", __func__,
2760                                         pairwise_cipher, group_cipher, is_8021x));
2761                         }
2762                 } else {
2763                         pbuf = rtw_get_wpa2_ie(&bssid->IEs[12], &wpa_ielen, bssid->IELength - 12);
2764
2765                         if (pbuf && (wpa_ielen > 0)) {
2766                                 if (_SUCCESS == rtw_parse_wpa2_ie(pbuf, wpa_ielen + 2, &group_cipher, &pairwise_cipher, &is_8021x)) {
2767                                         RT_TRACE(_module_rtl871x_mlme_c_, _drv_info_,
2768                                                 ("%s pnetwork->pairwise_cipher: %d, pnetwork->group_cipher is %d, is_802x is %d\n",
2769                                                 __func__, pairwise_cipher, group_cipher, is_8021x));
2770                                 }
2771                         }
2772                 }
2773
2774                 RT_TRACE(_module_rtl871x_mlme_c_, _drv_err_,
2775                         ("%s cur_network->group_cipher is %d: %d\n", __func__, cur_network->BcnInfo.group_cipher, group_cipher));
2776                 if (pairwise_cipher != cur_network->BcnInfo.pairwise_cipher || group_cipher != cur_network->BcnInfo.group_cipher) {
2777                         RTW_INFO("%s pairwise_cipher(%x:%x) or group_cipher(%x:%x) is not match\n", __func__,
2778                                 pairwise_cipher, cur_network->BcnInfo.pairwise_cipher,
2779                                 group_cipher, cur_network->BcnInfo.group_cipher);
2780                         goto _mismatch;
2781                 }
2782
2783                 if (is_8021x != cur_network->BcnInfo.is_8021x) {
2784                         RTW_INFO("%s authentication is not match\n", __func__);
2785                         goto _mismatch;
2786                 }
2787         }
2788
2789         rtw_mfree((u8 *)bssid, sizeof(WLAN_BSSID_EX));
2790         return _SUCCESS;
2791
2792 _mismatch:
2793         rtw_mfree((u8 *)bssid, sizeof(WLAN_BSSID_EX));
2794
2795         if (pmlmepriv->NumOfBcnInfoChkFail == 0)
2796                 pmlmepriv->timeBcnInfoChkStart = rtw_get_current_time();
2797
2798         pmlmepriv->NumOfBcnInfoChkFail++;
2799         RTW_INFO("%s by "ADPT_FMT" - NumOfChkFail = %d (SeqNum of this Beacon frame = %d).\n", __func__, ADPT_ARG(Adapter), pmlmepriv->NumOfBcnInfoChkFail, GetSequence(pframe));
2800
2801         if ((pmlmepriv->timeBcnInfoChkStart != 0) && (rtw_get_passing_time_ms(pmlmepriv->timeBcnInfoChkStart) <= DISCONNECT_BY_CHK_BCN_FAIL_OBSERV_PERIOD_IN_MS)
2802             && (pmlmepriv->NumOfBcnInfoChkFail >= DISCONNECT_BY_CHK_BCN_FAIL_THRESHOLD)) {
2803                 RTW_INFO("%s by "ADPT_FMT" - NumOfChkFail = %d >= threshold : %d (in %d ms), return FAIL.\n", __func__, ADPT_ARG(Adapter), pmlmepriv->NumOfBcnInfoChkFail,
2804                         DISCONNECT_BY_CHK_BCN_FAIL_THRESHOLD, rtw_get_passing_time_ms(pmlmepriv->timeBcnInfoChkStart));
2805                 pmlmepriv->timeBcnInfoChkStart = 0;
2806                 pmlmepriv->NumOfBcnInfoChkFail = 0;
2807                 return _FAIL;
2808         }
2809
2810         return _SUCCESS;
2811 #endif
2812 }
2813
2814 void update_beacon_info(_adapter *padapter, u8 *pframe, uint pkt_len, struct sta_info *psta)
2815 {
2816         unsigned int i;
2817         unsigned int len;
2818         PNDIS_802_11_VARIABLE_IEs       pIE;
2819
2820 #ifdef CONFIG_TDLS
2821         struct tdls_info *ptdlsinfo = &padapter->tdlsinfo;
2822         u8 tdls_prohibited[] = { 0x00, 0x00, 0x00, 0x00, 0x10 }; /* bit(38): TDLS_prohibited */
2823 #endif /* CONFIG_TDLS */
2824
2825         len = pkt_len - (_BEACON_IE_OFFSET_ + WLAN_HDR_A3_LEN);
2826
2827         for (i = 0; i < len;) {
2828                 pIE = (PNDIS_802_11_VARIABLE_IEs)(pframe + (_BEACON_IE_OFFSET_ + WLAN_HDR_A3_LEN) + i);
2829
2830                 switch (pIE->ElementID) {
2831                 case _VENDOR_SPECIFIC_IE_:
2832                         /* to update WMM paramter set while receiving beacon */
2833                         if (_rtw_memcmp(pIE->data, WMM_PARA_OUI, 6) && pIE->Length == WLAN_WMM_LEN)     /* WMM */
2834                                 (WMM_param_handler(padapter, pIE)) ? report_wmm_edca_update(padapter) : 0;
2835
2836                         break;
2837
2838                 case _HT_EXTRA_INFO_IE_:        /* HT info                               */
2839                         /* HT_info_handler(padapter, pIE); */
2840                         bwmode_update_check(padapter, pIE);
2841                         break;
2842 #ifdef CONFIG_80211AC_VHT
2843                 case EID_OpModeNotification:
2844                         rtw_process_vht_op_mode_notify(padapter, pIE->data, psta);
2845                         break;
2846 #endif /* CONFIG_80211AC_VHT */
2847                 case _ERPINFO_IE_:
2848                         ERP_IE_handler(padapter, pIE);
2849                         VCS_update(padapter, psta);
2850                         break;
2851
2852 #ifdef CONFIG_TDLS
2853                 case _EXT_CAP_IE_:
2854                         if (check_ap_tdls_prohibited(pIE->data, pIE->Length) == _TRUE)
2855                                 ptdlsinfo->ap_prohibited = _TRUE;
2856                         if (check_ap_tdls_ch_switching_prohibited(pIE->data, pIE->Length) == _TRUE)
2857                                 ptdlsinfo->ch_switch_prohibited = _TRUE;
2858                         break;
2859 #endif /* CONFIG_TDLS */
2860                 default:
2861                         break;
2862                 }
2863
2864                 i += (pIE->Length + 2);
2865         }
2866 }
2867
2868 #ifdef CONFIG_DFS
2869 void process_csa_ie(_adapter *padapter, u8 *pframe, uint pkt_len)
2870 {
2871         unsigned int i;
2872         unsigned int len;
2873         PNDIS_802_11_VARIABLE_IEs       pIE;
2874         u8 new_ch_no = 0;
2875
2876         if (padapter->mlmepriv.handle_dfs == _TRUE)
2877                 return;
2878
2879         len = pkt_len - (_BEACON_IE_OFFSET_ + WLAN_HDR_A3_LEN);
2880
2881         for (i = 0; i < len;) {
2882                 pIE = (PNDIS_802_11_VARIABLE_IEs)(pframe + (_BEACON_IE_OFFSET_ + WLAN_HDR_A3_LEN) + i);
2883
2884                 switch (pIE->ElementID) {
2885                 case _CH_SWTICH_ANNOUNCE_:
2886                         padapter->mlmepriv.handle_dfs = _TRUE;
2887                         _rtw_memcpy(&new_ch_no, pIE->data + 1, 1);
2888                         rtw_set_csa_cmd(padapter, new_ch_no);
2889                         break;
2890                 default:
2891                         break;
2892                 }
2893
2894                 i += (pIE->Length + 2);
2895         }
2896 }
2897 #endif /* CONFIG_DFS */
2898
2899 unsigned int is_ap_in_tkip(_adapter *padapter)
2900 {
2901         u32 i;
2902         PNDIS_802_11_VARIABLE_IEs       pIE;
2903         struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
2904         struct mlme_ext_info    *pmlmeinfo = &(pmlmeext->mlmext_info);
2905         WLAN_BSSID_EX           *cur_network = &(pmlmeinfo->network);
2906
2907         if (rtw_get_capability((WLAN_BSSID_EX *)cur_network) & WLAN_CAPABILITY_PRIVACY) {
2908                 for (i = sizeof(NDIS_802_11_FIXED_IEs); i < pmlmeinfo->network.IELength;) {
2909                         pIE = (PNDIS_802_11_VARIABLE_IEs)(pmlmeinfo->network.IEs + i);
2910
2911                         switch (pIE->ElementID) {
2912                         case _VENDOR_SPECIFIC_IE_:
2913                                 if ((_rtw_memcmp(pIE->data, RTW_WPA_OUI, 4)) && (_rtw_memcmp((pIE->data + 12), WPA_TKIP_CIPHER, 4)))
2914                                         return _TRUE;
2915                                 break;
2916
2917                         case _RSN_IE_2_:
2918                                 if (_rtw_memcmp((pIE->data + 8), RSN_TKIP_CIPHER, 4))
2919                                         return _TRUE;
2920
2921                         default:
2922                                 break;
2923                         }
2924
2925                         i += (pIE->Length + 2);
2926                 }
2927
2928                 return _FALSE;
2929         } else
2930                 return _FALSE;
2931
2932 }
2933
2934 unsigned int should_forbid_n_rate(_adapter *padapter)
2935 {
2936         u32 i;
2937         PNDIS_802_11_VARIABLE_IEs       pIE;
2938         struct mlme_priv        *pmlmepriv = &padapter->mlmepriv;
2939         WLAN_BSSID_EX  *cur_network = &pmlmepriv->cur_network.network;
2940
2941         if (rtw_get_capability((WLAN_BSSID_EX *)cur_network) & WLAN_CAPABILITY_PRIVACY) {
2942                 for (i = sizeof(NDIS_802_11_FIXED_IEs); i < cur_network->IELength;) {
2943                         pIE = (PNDIS_802_11_VARIABLE_IEs)(cur_network->IEs + i);
2944
2945                         switch (pIE->ElementID) {
2946                         case _VENDOR_SPECIFIC_IE_:
2947                                 if (_rtw_memcmp(pIE->data, RTW_WPA_OUI, 4) &&
2948                                     ((_rtw_memcmp((pIE->data + 12), WPA_CIPHER_SUITE_CCMP, 4)) ||
2949                                      (_rtw_memcmp((pIE->data + 16), WPA_CIPHER_SUITE_CCMP, 4))))
2950                                         return _FALSE;
2951                                 break;
2952
2953                         case _RSN_IE_2_:
2954                                 if ((_rtw_memcmp((pIE->data + 8), RSN_CIPHER_SUITE_CCMP, 4))  ||
2955                                     (_rtw_memcmp((pIE->data + 12), RSN_CIPHER_SUITE_CCMP, 4)))
2956                                         return _FALSE;
2957
2958                         default:
2959                                 break;
2960                         }
2961
2962                         i += (pIE->Length + 2);
2963                 }
2964
2965                 return _TRUE;
2966         } else
2967                 return _FALSE;
2968
2969 }
2970
2971
2972 unsigned int is_ap_in_wep(_adapter *padapter)
2973 {
2974         u32 i;
2975         PNDIS_802_11_VARIABLE_IEs       pIE;
2976         struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
2977         struct mlme_ext_info    *pmlmeinfo = &(pmlmeext->mlmext_info);
2978         WLAN_BSSID_EX           *cur_network = &(pmlmeinfo->network);
2979
2980         if (rtw_get_capability((WLAN_BSSID_EX *)cur_network) & WLAN_CAPABILITY_PRIVACY) {
2981                 for (i = sizeof(NDIS_802_11_FIXED_IEs); i < pmlmeinfo->network.IELength;) {
2982                         pIE = (PNDIS_802_11_VARIABLE_IEs)(pmlmeinfo->network.IEs + i);
2983
2984                         switch (pIE->ElementID) {
2985                         case _VENDOR_SPECIFIC_IE_:
2986                                 if (_rtw_memcmp(pIE->data, RTW_WPA_OUI, 4))
2987                                         return _FALSE;
2988                                 break;
2989
2990                         case _RSN_IE_2_:
2991                                 return _FALSE;
2992
2993                         default:
2994                                 break;
2995                         }
2996
2997                         i += (pIE->Length + 2);
2998                 }
2999
3000                 return _TRUE;
3001         } else
3002                 return _FALSE;
3003
3004 }
3005
3006 int wifirate2_ratetbl_inx(unsigned char rate);
3007 int wifirate2_ratetbl_inx(unsigned char rate)
3008 {
3009         int     inx = 0;
3010         rate = rate & 0x7f;
3011
3012         switch (rate) {
3013         case 54*2:
3014                 inx = 11;
3015                 break;
3016
3017         case 48*2:
3018                 inx = 10;
3019                 break;
3020
3021         case 36*2:
3022                 inx = 9;
3023                 break;
3024
3025         case 24*2:
3026                 inx = 8;
3027                 break;
3028
3029         case 18*2:
3030                 inx = 7;
3031                 break;
3032
3033         case 12*2:
3034                 inx = 6;
3035                 break;
3036
3037         case 9*2:
3038                 inx = 5;
3039                 break;
3040
3041         case 6*2:
3042                 inx = 4;
3043                 break;
3044
3045         case 11*2:
3046                 inx = 3;
3047                 break;
3048         case 11:
3049                 inx = 2;
3050                 break;
3051
3052         case 2*2:
3053                 inx = 1;
3054                 break;
3055
3056         case 1*2:
3057                 inx = 0;
3058                 break;
3059
3060         }
3061         return inx;
3062 }
3063
3064 unsigned int update_basic_rate(unsigned char *ptn, unsigned int ptn_sz)
3065 {
3066         unsigned int i, num_of_rate;
3067         unsigned int mask = 0;
3068
3069         num_of_rate = (ptn_sz > NumRates) ? NumRates : ptn_sz;
3070
3071         for (i = 0; i < num_of_rate; i++) {
3072                 if ((*(ptn + i)) & 0x80)
3073                         mask |= 0x1 << wifirate2_ratetbl_inx(*(ptn + i));
3074         }
3075         return mask;
3076 }
3077
3078 unsigned int update_supported_rate(unsigned char *ptn, unsigned int ptn_sz)
3079 {
3080         unsigned int i, num_of_rate;
3081         unsigned int mask = 0;
3082
3083         num_of_rate = (ptn_sz > NumRates) ? NumRates : ptn_sz;
3084
3085         for (i = 0; i < num_of_rate; i++)
3086                 mask |= 0x1 << wifirate2_ratetbl_inx(*(ptn + i));
3087
3088         return mask;
3089 }
3090
3091 unsigned int update_MCS_rate(struct HT_caps_element *pHT_caps)
3092 {
3093         unsigned int mask = 0;
3094
3095         mask = ((pHT_caps->u.HT_cap_element.MCS_rate[0] << 12) | (pHT_caps->u.HT_cap_element.MCS_rate[1] << 20));
3096
3097         return mask;
3098 }
3099
3100 int support_short_GI(_adapter *padapter, struct HT_caps_element *pHT_caps, u8 bwmode)
3101 {
3102         unsigned char                                   bit_offset;
3103         struct mlme_ext_priv    *pmlmeext = &padapter->mlmeextpriv;
3104         struct mlme_ext_info    *pmlmeinfo = &(pmlmeext->mlmext_info);
3105
3106         if (!(pmlmeinfo->HT_enable))
3107                 return _FAIL;
3108
3109         bit_offset = (bwmode & CHANNEL_WIDTH_40) ? 6 : 5;
3110
3111         if (pHT_caps->u.HT_cap_element.HT_caps_info & (0x1 << bit_offset))
3112                 return _SUCCESS;
3113         else
3114                 return _FAIL;
3115 }
3116
3117 unsigned char get_highest_rate_idx(u32 mask)
3118 {
3119         int i;
3120         unsigned char rate_idx = 0;
3121
3122         for (i = 31; i >= 0; i--) {
3123                 if (mask & BIT(i)) {
3124                         rate_idx = i;
3125                         break;
3126                 }
3127         }
3128
3129         return rate_idx;
3130 }
3131
3132 unsigned char get_highest_mcs_rate(struct HT_caps_element *pHT_caps);
3133 unsigned char get_highest_mcs_rate(struct HT_caps_element *pHT_caps)
3134 {
3135         int i, mcs_rate;
3136
3137         mcs_rate = (pHT_caps->u.HT_cap_element.MCS_rate[0] | (pHT_caps->u.HT_cap_element.MCS_rate[1] << 8));
3138
3139         for (i = 15; i >= 0; i--) {
3140                 if (mcs_rate & (0x1 << i))
3141                         break;
3142         }
3143
3144         return i;
3145 }
3146
3147 void Update_RA_Entry(_adapter *padapter, struct sta_info *psta)
3148 {
3149         rtw_hal_update_ra_mask(psta, psta->rssi_level);
3150 }
3151
3152 void enable_rate_adaptive(_adapter *padapter, struct sta_info *psta);
3153 void enable_rate_adaptive(_adapter *padapter, struct sta_info *psta)
3154 {
3155         Update_RA_Entry(padapter, psta);
3156 }
3157
3158 void set_sta_rate(_adapter *padapter, struct sta_info *psta)
3159 {
3160         /* rate adaptive         */
3161         enable_rate_adaptive(padapter, psta);
3162 }
3163
3164 /* Update RRSR and Rate for USERATE */
3165 void update_tx_basic_rate(_adapter *padapter, u8 wirelessmode)
3166 {
3167         NDIS_802_11_RATES_EX    supported_rates;
3168         struct mlme_ext_priv    *pmlmeext = &padapter->mlmeextpriv;
3169 #ifdef CONFIG_P2P
3170         struct wifidirect_info  *pwdinfo = &padapter->wdinfo;
3171
3172         /*      Added by Albert 2011/03/22 */
3173         /*      In the P2P mode, the driver should not support the b mode. */
3174         /*      So, the Tx packet shouldn't use the CCK rate */
3175         if (!rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE))
3176                 return;
3177 #endif /* CONFIG_P2P */
3178 #ifdef CONFIG_INTEL_WIDI
3179         if (padapter->mlmepriv.widi_state != INTEL_WIDI_STATE_NONE)
3180                 return;
3181 #endif /* CONFIG_INTEL_WIDI */
3182
3183         _rtw_memset(supported_rates, 0, NDIS_802_11_LENGTH_RATES_EX);
3184
3185         /* clear B mod if current channel is in 5G band, avoid tx cck rate in 5G band. */
3186         if (pmlmeext->cur_channel > 14)
3187                 wirelessmode &= ~(WIRELESS_11B);
3188
3189         if ((wirelessmode & WIRELESS_11B) && (wirelessmode == WIRELESS_11B))
3190                 _rtw_memcpy(supported_rates, rtw_basic_rate_cck, 4);
3191         else if (wirelessmode & WIRELESS_11B)
3192                 _rtw_memcpy(supported_rates, rtw_basic_rate_mix, 7);
3193         else
3194                 _rtw_memcpy(supported_rates, rtw_basic_rate_ofdm, 3);
3195
3196         if (wirelessmode & WIRELESS_11B)
3197                 update_mgnt_tx_rate(padapter, IEEE80211_CCK_RATE_1MB);
3198         else
3199                 update_mgnt_tx_rate(padapter, IEEE80211_OFDM_RATE_6MB);
3200
3201         rtw_hal_set_hwreg(padapter, HW_VAR_BASIC_RATE, supported_rates);
3202 }
3203
3204 unsigned char check_assoc_AP(u8 *pframe, uint len)
3205 {
3206         unsigned int    i;
3207         PNDIS_802_11_VARIABLE_IEs       pIE;
3208
3209         for (i = sizeof(NDIS_802_11_FIXED_IEs); i < len;) {
3210                 pIE = (PNDIS_802_11_VARIABLE_IEs)(pframe + i);
3211
3212                 switch (pIE->ElementID) {
3213                 case _VENDOR_SPECIFIC_IE_:
3214                         if ((_rtw_memcmp(pIE->data, ARTHEROS_OUI1, 3)) || (_rtw_memcmp(pIE->data, ARTHEROS_OUI2, 3))) {
3215                                 RTW_INFO("link to Artheros AP\n");
3216                                 return HT_IOT_PEER_ATHEROS;
3217                         } else if ((_rtw_memcmp(pIE->data, BROADCOM_OUI1, 3))
3218                                    || (_rtw_memcmp(pIE->data, BROADCOM_OUI2, 3))
3219                                 || (_rtw_memcmp(pIE->data, BROADCOM_OUI3, 3))) {
3220                                 RTW_INFO("link to Broadcom AP\n");
3221                                 return HT_IOT_PEER_BROADCOM;
3222                         } else if (_rtw_memcmp(pIE->data, MARVELL_OUI, 3)) {
3223                                 RTW_INFO("link to Marvell AP\n");
3224                                 return HT_IOT_PEER_MARVELL;
3225                         } else if (_rtw_memcmp(pIE->data, RALINK_OUI, 3)) {
3226                                 RTW_INFO("link to Ralink AP\n");
3227                                 return HT_IOT_PEER_RALINK;
3228                         } else if (_rtw_memcmp(pIE->data, CISCO_OUI, 3)) {
3229                                 RTW_INFO("link to Cisco AP\n");
3230                                 return HT_IOT_PEER_CISCO;
3231                         } else if (_rtw_memcmp(pIE->data, REALTEK_OUI, 3)) {
3232                                 u32     Vender = HT_IOT_PEER_REALTEK;
3233
3234                                 if (pIE->Length >= 5) {
3235                                         if (pIE->data[4] == 1) {
3236                                                 /* if(pIE->data[5] & RT_HT_CAP_USE_LONG_PREAMBLE) */
3237                                                 /*      bssDesc->BssHT.RT2RT_HT_Mode |= RT_HT_CAP_USE_LONG_PREAMBLE; */
3238
3239                                                 if (pIE->data[5] & RT_HT_CAP_USE_92SE) {
3240                                                         /* bssDesc->BssHT.RT2RT_HT_Mode |= RT_HT_CAP_USE_92SE; */
3241                                                         Vender = HT_IOT_PEER_REALTEK_92SE;
3242                                                 }
3243                                         }
3244
3245                                         if (pIE->data[5] & RT_HT_CAP_USE_SOFTAP)
3246                                                 Vender = HT_IOT_PEER_REALTEK_SOFTAP;
3247
3248                                         if (pIE->data[4] == 2) {
3249                                                 if (pIE->data[6] & RT_HT_CAP_USE_JAGUAR_BCUT) {
3250                                                         Vender = HT_IOT_PEER_REALTEK_JAGUAR_BCUTAP;
3251                                                         RTW_INFO("link to Realtek JAGUAR_BCUTAP\n");
3252                                                 }
3253                                                 if (pIE->data[6] & RT_HT_CAP_USE_JAGUAR_CCUT) {
3254                                                         Vender = HT_IOT_PEER_REALTEK_JAGUAR_CCUTAP;
3255                                                         RTW_INFO("link to Realtek JAGUAR_CCUTAP\n");
3256                                                 }
3257                                         }
3258                                 }
3259
3260                                 RTW_INFO("link to Realtek AP\n");
3261                                 return Vender;
3262                         } else if (_rtw_memcmp(pIE->data, AIRGOCAP_OUI, 3)) {
3263                                 RTW_INFO("link to Airgo Cap\n");
3264                                 return HT_IOT_PEER_AIRGO;
3265                         } else
3266                                 break;
3267
3268                 default:
3269                         break;
3270                 }
3271
3272                 i += (pIE->Length + 2);
3273         }
3274
3275         RTW_INFO("link to new AP\n");
3276         return HT_IOT_PEER_UNKNOWN;
3277 }
3278
3279 void update_capinfo(PADAPTER Adapter, u16 updateCap)
3280 {
3281         struct mlme_ext_priv    *pmlmeext = &Adapter->mlmeextpriv;
3282         struct mlme_ext_info    *pmlmeinfo = &(pmlmeext->mlmext_info);
3283         BOOLEAN         ShortPreamble;
3284
3285         /* Check preamble mode, 2005.01.06, by rcnjko. */
3286         /* Mark to update preamble value forever, 2008.03.18 by lanhsin */
3287         /* if( pMgntInfo->RegPreambleMode == PREAMBLE_AUTO ) */
3288         {
3289
3290                 if (updateCap & cShortPreamble) {
3291                         /* Short Preamble */
3292                         if (pmlmeinfo->preamble_mode != PREAMBLE_SHORT) { /* PREAMBLE_LONG or PREAMBLE_AUTO */
3293                                 ShortPreamble = _TRUE;
3294                                 pmlmeinfo->preamble_mode = PREAMBLE_SHORT;
3295                                 rtw_hal_set_hwreg(Adapter, HW_VAR_ACK_PREAMBLE, (u8 *)&ShortPreamble);
3296                         }
3297                 } else {
3298                         /* Long Preamble */
3299                         if (pmlmeinfo->preamble_mode != PREAMBLE_LONG) { /* PREAMBLE_SHORT or PREAMBLE_AUTO */
3300                                 ShortPreamble = _FALSE;
3301                                 pmlmeinfo->preamble_mode = PREAMBLE_LONG;
3302                                 rtw_hal_set_hwreg(Adapter, HW_VAR_ACK_PREAMBLE, (u8 *)&ShortPreamble);
3303                         }
3304                 }
3305         }
3306
3307         if (updateCap & cIBSS) {
3308                 /* Filen: See 802.11-2007 p.91 */
3309                 pmlmeinfo->slotTime = NON_SHORT_SLOT_TIME;
3310         } else {
3311                 /* Filen: See 802.11-2007 p.90 */
3312                 if (pmlmeext->cur_wireless_mode & (WIRELESS_11_24N | WIRELESS_11A | WIRELESS_11_5N | WIRELESS_11AC))
3313                         pmlmeinfo->slotTime = SHORT_SLOT_TIME;
3314                 else if (pmlmeext->cur_wireless_mode & (WIRELESS_11G)) {
3315                         if ((updateCap & cShortSlotTime) /* && (!(pMgntInfo->pHTInfo->RT2RT_HT_Mode & RT_HT_CAP_USE_LONG_PREAMBLE)) */) {
3316                                 /* Short Slot Time */
3317                                 pmlmeinfo->slotTime = SHORT_SLOT_TIME;
3318                         } else {
3319                                 /* Long Slot Time */
3320                                 pmlmeinfo->slotTime = NON_SHORT_SLOT_TIME;
3321                         }
3322                 } else {
3323                         /* B Mode */
3324                         pmlmeinfo->slotTime = NON_SHORT_SLOT_TIME;
3325                 }
3326         }
3327
3328         rtw_hal_set_hwreg(Adapter, HW_VAR_SLOT_TIME, &pmlmeinfo->slotTime);
3329
3330 }
3331
3332 /*
3333 * set adapter.mlmeextpriv.mlmext_info.HT_enable
3334 * set adapter.mlmeextpriv.cur_wireless_mode
3335 * set SIFS register
3336 * set mgmt tx rate
3337 */
3338 void update_wireless_mode(_adapter *padapter)
3339 {
3340         int ratelen, network_type = 0;
3341         u32 SIFS_Timer;
3342         struct mlme_ext_priv    *pmlmeext = &padapter->mlmeextpriv;
3343         struct mlme_ext_info    *pmlmeinfo = &(pmlmeext->mlmext_info);
3344         WLAN_BSSID_EX           *cur_network = &(pmlmeinfo->network);
3345         unsigned char                   *rate = cur_network->SupportedRates;
3346 #ifdef CONFIG_P2P
3347         struct wifidirect_info  *pwdinfo = &(padapter->wdinfo);
3348 #endif /* CONFIG_P2P */
3349
3350         ratelen = rtw_get_rateset_len(cur_network->SupportedRates);
3351
3352         if ((pmlmeinfo->HT_info_enable) && (pmlmeinfo->HT_caps_enable))
3353                 pmlmeinfo->HT_enable = 1;
3354
3355         if (pmlmeext->cur_channel > 14) {
3356                 if (pmlmeinfo->VHT_enable)
3357                         network_type = WIRELESS_11AC;
3358                 else if (pmlmeinfo->HT_enable)
3359                         network_type = WIRELESS_11_5N;
3360
3361                 network_type |= WIRELESS_11A;
3362         } else {
3363                 if (pmlmeinfo->VHT_enable)
3364                         network_type = WIRELESS_11AC;
3365                 else if (pmlmeinfo->HT_enable)
3366                         network_type = WIRELESS_11_24N;
3367
3368                 if ((cckratesonly_included(rate, ratelen)) == _TRUE)
3369                         network_type |= WIRELESS_11B;
3370                 else if ((cckrates_included(rate, ratelen)) == _TRUE)
3371                         network_type |= WIRELESS_11BG;
3372                 else
3373                         network_type |= WIRELESS_11G;
3374         }
3375
3376         pmlmeext->cur_wireless_mode = network_type & padapter->registrypriv.wireless_mode;
3377         /* RTW_INFO("network_type=%02x, padapter->registrypriv.wireless_mode=%02x\n", network_type, padapter->registrypriv.wireless_mode); */
3378 #if 0
3379         if ((pmlmeext->cur_wireless_mode == WIRELESS_11G) ||
3380             (pmlmeext->cur_wireless_mode == WIRELESS_11BG)) /* WIRELESS_MODE_G) */
3381                 SIFS_Timer = 0x0a0a;/* CCK */
3382         else
3383                 SIFS_Timer = 0x0e0e;/* pHalData->SifsTime; //OFDM */
3384 #endif
3385
3386         SIFS_Timer = 0x0a0a0808; /* 0x0808->for CCK, 0x0a0a->for OFDM
3387                               * change this value if having IOT issues. */
3388
3389         rtw_hal_set_hwreg(padapter, HW_VAR_RESP_SIFS, (u8 *)&SIFS_Timer);
3390
3391         rtw_hal_set_hwreg(padapter, HW_VAR_WIRELESS_MODE, (u8 *)&(pmlmeext->cur_wireless_mode));
3392
3393         if ((pmlmeext->cur_wireless_mode & WIRELESS_11B)
3394 #ifdef CONFIG_P2P
3395             && rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE)
3396 #endif /* CONFIG_P2P */
3397            )
3398                 update_mgnt_tx_rate(padapter, IEEE80211_CCK_RATE_1MB);
3399         else
3400                 update_mgnt_tx_rate(padapter, IEEE80211_OFDM_RATE_6MB);
3401 }
3402
3403 void fire_write_MAC_cmd(_adapter *padapter, unsigned int addr, unsigned int value);
3404 void fire_write_MAC_cmd(_adapter *padapter, unsigned int addr, unsigned int value)
3405 {
3406 #if 0
3407         struct cmd_obj                                  *ph2c;
3408         struct reg_rw_parm                      *pwriteMacPara;
3409         struct cmd_priv                                 *pcmdpriv = &(padapter->cmdpriv);
3410
3411         ph2c = (struct cmd_obj *)rtw_zmalloc(sizeof(struct cmd_obj));
3412         if (ph2c == NULL)
3413                 return;
3414
3415         pwriteMacPara = (struct reg_rw_parm *)rtw_malloc(sizeof(struct reg_rw_parm));
3416         if (pwriteMacPara == NULL) {
3417                 rtw_mfree((unsigned char *)ph2c, sizeof(struct cmd_obj));
3418                 return;
3419         }
3420
3421         pwriteMacPara->rw = 1;
3422         pwriteMacPara->addr = addr;
3423         pwriteMacPara->value = value;
3424
3425         init_h2fwcmd_w_parm_no_rsp(ph2c, pwriteMacPara, GEN_CMD_CODE(_Write_MACREG));
3426         rtw_enqueue_cmd(pcmdpriv, ph2c);
3427 #endif
3428 }
3429
3430 void update_sta_basic_rate(struct sta_info *psta, u8 wireless_mode)
3431 {
3432         if (IsSupportedTxCCK(wireless_mode)) {
3433                 /* Only B, B/G, and B/G/N AP could use CCK rate */
3434                 _rtw_memcpy(psta->bssrateset, rtw_basic_rate_cck, 4);
3435                 psta->bssratelen = 4;
3436         } else {
3437                 _rtw_memcpy(psta->bssrateset, rtw_basic_rate_ofdm, 3);
3438                 psta->bssratelen = 3;
3439         }
3440 }
3441
3442 int rtw_ies_get_supported_rate(u8 *ies, uint ies_len, u8 *rate_set, u8 *rate_num)
3443 {
3444         u8 *ie;
3445         unsigned int ie_len;
3446
3447         if (!rate_set || !rate_num)
3448                 return _FALSE;
3449
3450         *rate_num = 0;
3451
3452         ie = rtw_get_ie(ies, _SUPPORTEDRATES_IE_, &ie_len, ies_len);
3453         if (ie == NULL)
3454                 goto ext_rate;
3455
3456         _rtw_memcpy(rate_set, ie + 2, ie_len);
3457         *rate_num = ie_len;
3458
3459 ext_rate:
3460         ie = rtw_get_ie(ies, _EXT_SUPPORTEDRATES_IE_, &ie_len, ies_len);
3461         if (ie) {
3462                 _rtw_memcpy(rate_set + *rate_num, ie + 2, ie_len);
3463                 *rate_num += ie_len;
3464         }
3465
3466         if (*rate_num == 0)
3467                 return _FAIL;
3468
3469         if (0) {
3470                 int i;
3471
3472                 for (i = 0; i < *rate_num; i++)
3473                         RTW_INFO("rate:0x%02x\n", *(rate_set + i));
3474         }
3475
3476         return _SUCCESS;
3477 }
3478
3479 void process_addba_req(_adapter *padapter, u8 *paddba_req, u8 *addr)
3480 {
3481         struct sta_info *psta;
3482         u16 tid, start_seq, param;
3483         struct sta_priv *pstapriv = &padapter->stapriv;
3484         struct ADDBA_request    *preq = (struct ADDBA_request *)paddba_req;
3485         struct mlme_ext_priv    *pmlmeext = &padapter->mlmeextpriv;
3486         struct mlme_ext_info    *pmlmeinfo = &(pmlmeext->mlmext_info);
3487         u8 size, accept = _FALSE;
3488
3489         psta = rtw_get_stainfo(pstapriv, addr);
3490         if (!psta)
3491                 goto exit;
3492
3493         start_seq = le16_to_cpu(preq->BA_starting_seqctrl) >> 4;
3494
3495         param = le16_to_cpu(preq->BA_para_set);
3496         tid = (param >> 2) & 0x0f;
3497
3498
3499         accept = rtw_rx_ampdu_is_accept(padapter);
3500         size = rtw_rx_ampdu_size(padapter);
3501
3502         if (accept == _TRUE)
3503                 rtw_addbarsp_cmd(padapter, addr, tid, 0, size, start_seq);
3504         else
3505                 rtw_addbarsp_cmd(padapter, addr, tid, 37, size, start_seq); /* reject ADDBA Req */
3506
3507 exit:
3508         return;
3509 }
3510
3511 void update_TSF(struct mlme_ext_priv *pmlmeext, u8 *pframe, uint len)
3512 {
3513         u8 *pIE;
3514         u32 *pbuf;
3515
3516         pIE = pframe + sizeof(struct rtw_ieee80211_hdr_3addr);
3517         pbuf = (u32 *)pIE;
3518
3519         pmlmeext->TSFValue = le32_to_cpu(*(pbuf + 1));
3520
3521         pmlmeext->TSFValue = pmlmeext->TSFValue << 32;
3522
3523         pmlmeext->TSFValue |= le32_to_cpu(*pbuf);
3524 }
3525
3526 void correct_TSF(_adapter *padapter, struct mlme_ext_priv *pmlmeext)
3527 {
3528         rtw_hal_set_hwreg(padapter, HW_VAR_CORRECT_TSF, 0);
3529 }
3530
3531 void adaptive_early_32k(struct mlme_ext_priv *pmlmeext, u8 *pframe, uint len)
3532 {
3533         int i;
3534         u8 *pIE;
3535         u32 *pbuf;
3536         u64 tsf = 0;
3537         u32 delay_ms;
3538         struct mlme_ext_info    *pmlmeinfo = &(pmlmeext->mlmext_info);
3539
3540
3541         pmlmeext->bcn_cnt++;
3542
3543         pIE = pframe + sizeof(struct rtw_ieee80211_hdr_3addr);
3544         pbuf = (u32 *)pIE;
3545
3546         tsf = le32_to_cpu(*(pbuf + 1));
3547         tsf = tsf << 32;
3548         tsf |= le32_to_cpu(*pbuf);
3549
3550         /* RTW_INFO("%s(): tsf_upper= 0x%08x, tsf_lower=0x%08x\n", __func__, (u32)(tsf>>32), (u32)tsf); */
3551
3552         /* delay = (timestamp mod 1024*100)/1000 (unit: ms) */
3553         /* delay_ms = do_div(tsf, (pmlmeinfo->bcn_interval*1024))/1000; */
3554         delay_ms = rtw_modular64(tsf, (pmlmeinfo->bcn_interval * 1024));
3555         delay_ms = delay_ms / 1000;
3556
3557         if (delay_ms >= 8) {
3558                 pmlmeext->bcn_delay_cnt[8]++;
3559                 /* pmlmeext->bcn_delay_ratio[8] = (pmlmeext->bcn_delay_cnt[8] * 100) /pmlmeext->bcn_cnt; */
3560         } else {
3561                 pmlmeext->bcn_delay_cnt[delay_ms]++;
3562                 /* pmlmeext->bcn_delay_ratio[delay_ms] = (pmlmeext->bcn_delay_cnt[delay_ms] * 100) /pmlmeext->bcn_cnt; */
3563         }
3564
3565         /*
3566                 RTW_INFO("%s(): (a)bcn_cnt = %d\n", __func__, pmlmeext->bcn_cnt);
3567
3568
3569                 for(i=0; i<9; i++)
3570                 {
3571                         RTW_INFO("%s():bcn_delay_cnt[%d]=%d,  bcn_delay_ratio[%d]=%d\n", __func__, i,
3572                                 pmlmeext->bcn_delay_cnt[i] , i, pmlmeext->bcn_delay_ratio[i]);
3573                 }
3574         */
3575
3576         /* dump for  adaptive_early_32k */
3577         if (pmlmeext->bcn_cnt > 100 && (pmlmeext->adaptive_tsf_done == _TRUE)) {
3578                 u8 ratio_20_delay, ratio_80_delay;
3579                 u8 DrvBcnEarly, DrvBcnTimeOut;
3580
3581                 ratio_20_delay = 0;
3582                 ratio_80_delay = 0;
3583                 DrvBcnEarly = 0xff;
3584                 DrvBcnTimeOut = 0xff;
3585
3586                 RTW_INFO("%s(): bcn_cnt = %d\n", __func__, pmlmeext->bcn_cnt);
3587
3588                 for (i = 0; i < 9; i++) {
3589                         pmlmeext->bcn_delay_ratio[i] = (pmlmeext->bcn_delay_cnt[i] * 100) / pmlmeext->bcn_cnt;
3590
3591
3592                         /* RTW_INFO("%s():bcn_delay_cnt[%d]=%d,  bcn_delay_ratio[%d]=%d\n", __func__, i,  */
3593                         /*      pmlmeext->bcn_delay_cnt[i] , i, pmlmeext->bcn_delay_ratio[i]); */
3594
3595                         ratio_20_delay += pmlmeext->bcn_delay_ratio[i];
3596                         ratio_80_delay += pmlmeext->bcn_delay_ratio[i];
3597
3598                         if (ratio_20_delay > 20 && DrvBcnEarly == 0xff) {
3599                                 DrvBcnEarly = i;
3600                                 /* RTW_INFO("%s(): DrvBcnEarly = %d\n", __func__, DrvBcnEarly); */
3601                         }
3602
3603                         if (ratio_80_delay > 80 && DrvBcnTimeOut == 0xff) {
3604                                 DrvBcnTimeOut = i;
3605                                 /* RTW_INFO("%s(): DrvBcnTimeOut = %d\n", __func__, DrvBcnTimeOut); */
3606                         }
3607
3608                         /* reset adaptive_early_32k cnt */
3609                         pmlmeext->bcn_delay_cnt[i] = 0;
3610                         pmlmeext->bcn_delay_ratio[i] = 0;
3611                 }
3612
3613                 pmlmeext->DrvBcnEarly = DrvBcnEarly;
3614                 pmlmeext->DrvBcnTimeOut = DrvBcnTimeOut;
3615
3616                 pmlmeext->bcn_cnt = 0;
3617         }
3618
3619 }
3620
3621
3622 void beacon_timing_control(_adapter *padapter)
3623 {
3624         rtw_hal_bcn_related_reg_setting(padapter);
3625 }
3626
3627 #define CONFIG_SHARED_BMC_MACID
3628
3629 void dump_macid_map(void *sel, struct macid_bmp *map, u8 max_num)
3630 {
3631         RTW_PRINT_SEL(sel, "0x%08x\n", map->m0);
3632 #if (MACID_NUM_SW_LIMIT > 32)
3633         if (max_num && max_num > 32)
3634                 RTW_PRINT_SEL(sel, "0x%08x\n", map->m1);
3635 #endif
3636 #if (MACID_NUM_SW_LIMIT > 64)
3637         if (max_num && max_num > 64)
3638                 RTW_PRINT_SEL(sel, "0x%08x\n", map->m2);
3639 #endif
3640 #if (MACID_NUM_SW_LIMIT > 96)
3641         if (max_num && max_num > 96)
3642                 RTW_PRINT_SEL(sel, "0x%08x\n", map->m3);
3643 #endif
3644 }
3645
3646 inline bool rtw_macid_is_set(struct macid_bmp *map, u8 id)
3647 {
3648         if (id < 32)
3649                 return map->m0 & BIT(id);
3650 #if (MACID_NUM_SW_LIMIT > 32)
3651         else if (id < 64)
3652                 return map->m1 & BIT(id - 32);
3653 #endif
3654 #if (MACID_NUM_SW_LIMIT > 64)
3655         else if (id < 96)
3656                 return map->m2 & BIT(id - 64);
3657 #endif
3658 #if (MACID_NUM_SW_LIMIT > 96)
3659         else if (id < 128)
3660                 return map->m3 & BIT(id - 96);
3661 #endif
3662         else
3663                 rtw_warn_on(1);
3664
3665         return 0;
3666 }
3667
3668 inline void rtw_macid_map_set(struct macid_bmp *map, u8 id)
3669 {
3670         if (id < 32)
3671                 map->m0 |= BIT(id);
3672 #if (MACID_NUM_SW_LIMIT > 32)
3673         else if (id < 64)
3674                 map->m1 |= BIT(id - 32);
3675 #endif
3676 #if (MACID_NUM_SW_LIMIT > 64)
3677         else if (id < 96)
3678                 map->m2 |= BIT(id - 64);
3679 #endif
3680 #if (MACID_NUM_SW_LIMIT > 96)
3681         else if (id < 128)
3682                 map->m3 |= BIT(id - 96);
3683 #endif
3684         else
3685                 rtw_warn_on(1);
3686 }
3687
3688 /*Record bc's mac-id and sec-cam-id*/
3689 inline void rtw_iface_bcmc_id_set(_adapter *padapter, u8 mac_id)
3690 {
3691         struct dvobj_priv *dvobj = adapter_to_dvobj(padapter);
3692         struct macid_ctl_t *macid_ctl = dvobj_to_macidctl(dvobj);
3693
3694         macid_ctl->iface_bmc[padapter->iface_id] = mac_id;
3695 }
3696 inline u8 rtw_iface_bcmc_id_get(_adapter *padapter)
3697 {
3698         struct dvobj_priv *dvobj = adapter_to_dvobj(padapter);
3699         struct macid_ctl_t *macid_ctl = dvobj_to_macidctl(dvobj);
3700
3701         return macid_ctl->iface_bmc[padapter->iface_id];
3702 }
3703
3704 inline void rtw_macid_map_clr(struct macid_bmp *map, u8 id)
3705 {
3706         if (id < 32)
3707                 map->m0 &= ~BIT(id);
3708 #if (MACID_NUM_SW_LIMIT > 32)
3709         else if (id < 64)
3710                 map->m1 &= ~BIT(id - 32);
3711 #endif
3712 #if (MACID_NUM_SW_LIMIT > 64)
3713         else if (id < 96)
3714                 map->m2 &= ~BIT(id - 64);
3715 #endif
3716 #if (MACID_NUM_SW_LIMIT > 96)
3717         else if (id < 128)
3718                 map->m3 &= ~BIT(id - 96);
3719 #endif
3720         else
3721                 rtw_warn_on(1);
3722 }
3723
3724 inline bool rtw_macid_is_used(struct macid_ctl_t *macid_ctl, u8 id)
3725 {
3726         return rtw_macid_is_set(&macid_ctl->used, id);
3727 }
3728
3729 inline bool rtw_macid_is_bmc(struct macid_ctl_t *macid_ctl, u8 id)
3730 {
3731         return rtw_macid_is_set(&macid_ctl->bmc, id);
3732 }
3733
3734 inline s8 rtw_macid_get_if_g(struct macid_ctl_t *macid_ctl, u8 id)
3735 {
3736         int i;
3737
3738 #ifdef CONFIG_SHARED_BMC_MACID
3739         if (rtw_macid_is_bmc(macid_ctl, id)) {
3740                 for (i = 0; i < CONFIG_IFACE_NUMBER; i++)
3741                         if (macid_ctl->iface_bmc[i] == id)
3742                                 return i;
3743                 return -1;
3744         }
3745 #endif
3746
3747         for (i = 0; i < CONFIG_IFACE_NUMBER; i++) {
3748                 if (rtw_macid_is_set(&macid_ctl->if_g[i], id))
3749                         return i;
3750         }
3751         return -1;
3752 }
3753
3754 inline s8 rtw_macid_get_ch_g(struct macid_ctl_t *macid_ctl, u8 id)
3755 {
3756         int i;
3757
3758         for (i = 0; i < 2; i++) {
3759                 if (rtw_macid_is_set(&macid_ctl->ch_g[i], id))
3760                         return i;
3761         }
3762         return -1;
3763 }
3764
3765 void rtw_alloc_macid(_adapter *padapter, struct sta_info *psta)
3766 {
3767         int i;
3768         _irqL irqL;
3769         u8 bc_addr[ETH_ALEN] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
3770         struct dvobj_priv *dvobj = adapter_to_dvobj(padapter);
3771         struct macid_ctl_t *macid_ctl = dvobj_to_macidctl(dvobj);
3772         struct macid_bmp *used_map = &macid_ctl->used;
3773         /* static u8 last_id = 0;  for testing */
3774         u8 last_id = 0;
3775         u8 is_bc_sta = _FALSE;
3776
3777         if (_rtw_memcmp(psta->hwaddr, adapter_mac_addr(padapter), ETH_ALEN)) {
3778                 psta->mac_id = macid_ctl->num;
3779                 return;
3780         }
3781
3782         if (_rtw_memcmp(psta->hwaddr, bc_addr, ETH_ALEN)) {
3783                 is_bc_sta = _TRUE;
3784                 rtw_iface_bcmc_id_set(padapter, INVALID_SEC_MAC_CAM_ID);        /*init default value*/
3785         }
3786
3787 #ifdef CONFIG_SHARED_BMC_MACID
3788         if (is_bc_sta
3789 #ifdef CONFIG_CONCURRENT_MODE
3790             && (check_fwstate(&padapter->mlmepriv, WIFI_STATION_STATE) || check_fwstate(&padapter->mlmepriv, WIFI_NULL_STATE))
3791 #endif
3792            ) {
3793                 /* use shared broadcast & multicast macid 1 for all ifaces which configure to station mode*/
3794                 _enter_critical_bh(&macid_ctl->lock, &irqL);
3795                 rtw_macid_map_set(used_map, 1);
3796                 rtw_macid_map_set(&macid_ctl->bmc, 1);
3797                 rtw_macid_map_set(&macid_ctl->if_g[padapter->iface_id], 1);
3798                 macid_ctl->sta[1] = psta;
3799                 /* TODO ch_g? */
3800                 _exit_critical_bh(&macid_ctl->lock, &irqL);
3801                 i = 1;
3802                 goto assigned;
3803         }
3804 #endif
3805
3806 #ifdef CONFIG_MCC_MODE
3807         if (MCC_EN(padapter)) {
3808                 if (MLME_IS_AP(padapter) || MLME_IS_GO(padapter))
3809                         /* GO/AP assign client macid from 8 */
3810                         last_id = 8;
3811         }
3812 #endif /* CONFIG_MCC_MODE */
3813
3814         _enter_critical_bh(&macid_ctl->lock, &irqL);
3815
3816         for (i = last_id; i < macid_ctl->num; i++) {
3817 #ifdef CONFIG_SHARED_BMC_MACID
3818                 if (i == 1)
3819                         continue;
3820 #endif
3821
3822 #ifdef CONFIG_MCC_MODE
3823                 /* macid 0/1 reserve for mcc for mgnt queue macid */
3824                 if (MCC_EN(padapter)) {
3825                         if (i == MCC_ROLE_STA_GC_MGMT_QUEUE_MACID)
3826                                 continue;
3827                         if (i == MCC_ROLE_SOFTAP_GO_MGMT_QUEUE_MACID)
3828                                 continue;
3829                 }
3830 #endif /* CONFIG_MCC_MODE */
3831
3832                 if (is_bc_sta) {/*for SoftAP's Broadcast sta-info*/
3833                         /*TODO:non-security AP may allociated macid = 1*/
3834                         struct cam_ctl_t *cam_ctl = dvobj_to_sec_camctl(dvobj);
3835
3836                         if ((!rtw_macid_is_used(macid_ctl, i)) && (!rtw_sec_camid_is_used(cam_ctl, i)))
3837                                 break;
3838                 } else {
3839                         if (!rtw_macid_is_used(macid_ctl, i))
3840                                 break;
3841                 }
3842         }
3843
3844         if (i < macid_ctl->num) {
3845
3846                 rtw_macid_map_set(used_map, i);
3847
3848                 if (is_bc_sta) {
3849                         struct cam_ctl_t *cam_ctl = dvobj_to_sec_camctl(dvobj);
3850
3851                         rtw_macid_map_set(&macid_ctl->bmc, i);
3852                         rtw_iface_bcmc_id_set(padapter, i);
3853                         rtw_sec_cam_map_set(&cam_ctl->used, i);
3854                 }
3855
3856                 rtw_macid_map_set(&macid_ctl->if_g[padapter->iface_id], i);
3857                 macid_ctl->sta[i] = psta;
3858
3859                 /* TODO ch_g? */
3860
3861                 last_id++;
3862                 last_id %= macid_ctl->num;
3863         }
3864
3865         _exit_critical_bh(&macid_ctl->lock, &irqL);
3866
3867         if (i >= macid_ctl->num) {
3868                 psta->mac_id = macid_ctl->num;
3869                 RTW_ERR(FUNC_ADPT_FMT" if%u, hwaddr:"MAC_FMT" no available macid\n"
3870                         , FUNC_ADPT_ARG(padapter), padapter->iface_id + 1, MAC_ARG(psta->hwaddr));
3871                 rtw_warn_on(1);
3872                 goto exit;
3873         } else
3874                 goto assigned;
3875
3876 assigned:
3877         psta->mac_id = i;
3878         RTW_INFO(FUNC_ADPT_FMT" if%u, hwaddr:"MAC_FMT" macid:%u\n"
3879                 , FUNC_ADPT_ARG(padapter), padapter->iface_id + 1, MAC_ARG(psta->hwaddr), psta->mac_id);
3880
3881 exit:
3882         return;
3883 }
3884
3885 void rtw_release_macid(_adapter *padapter, struct sta_info *psta)
3886 {
3887         _irqL irqL;
3888         u8 bc_addr[ETH_ALEN] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
3889         struct dvobj_priv *dvobj = adapter_to_dvobj(padapter);
3890         struct macid_ctl_t *macid_ctl = dvobj_to_macidctl(dvobj);
3891         u8 is_bc_sta = _FALSE;
3892
3893         if (_rtw_memcmp(psta->hwaddr, adapter_mac_addr(padapter), ETH_ALEN))
3894                 return;
3895
3896         if (_rtw_memcmp(psta->hwaddr, bc_addr, ETH_ALEN))
3897                 is_bc_sta = _TRUE;
3898
3899 #ifdef CONFIG_SHARED_BMC_MACID
3900         if (is_bc_sta
3901 #ifdef CONFIG_CONCURRENT_MODE
3902             && (check_fwstate(&padapter->mlmepriv, WIFI_STATION_STATE) || check_fwstate(&padapter->mlmepriv, WIFI_NULL_STATE))
3903 #endif
3904            )
3905                 return;
3906
3907         if (psta->mac_id == 1) {
3908                 RTW_ERR(FUNC_ADPT_FMT" if%u, hwaddr:"MAC_FMT" with macid:%u\n"
3909                         , FUNC_ADPT_ARG(padapter), padapter->iface_id + 1, MAC_ARG(psta->hwaddr), psta->mac_id);
3910                 if (check_fwstate(&padapter->mlmepriv, WIFI_STATION_STATE) || check_fwstate(&padapter->mlmepriv, WIFI_NULL_STATE))
3911                         rtw_warn_on(1);
3912                 return;
3913         }
3914 #endif
3915
3916         _enter_critical_bh(&macid_ctl->lock, &irqL);
3917
3918         if (psta->mac_id < macid_ctl->num) {
3919                 int i;
3920
3921                 if (!rtw_macid_is_used(macid_ctl, psta->mac_id)) {
3922                         RTW_ERR(FUNC_ADPT_FMT" if%u, hwaddr:"MAC_FMT" macid:%u not used\n"
3923                                 , FUNC_ADPT_ARG(padapter), padapter->iface_id + 1, MAC_ARG(psta->hwaddr), psta->mac_id);
3924                         rtw_warn_on(1);
3925                 }
3926
3927                 rtw_macid_map_clr(&macid_ctl->used, psta->mac_id);
3928                 rtw_macid_map_clr(&macid_ctl->bmc, psta->mac_id);
3929
3930                 if (is_bc_sta) {
3931                         struct cam_ctl_t *cam_ctl = dvobj_to_sec_camctl(dvobj);
3932                         u8 id = rtw_iface_bcmc_id_get(padapter);
3933
3934                         if ((id != INVALID_SEC_MAC_CAM_ID) && (id < cam_ctl->num))
3935                                 rtw_sec_cam_map_clr(&cam_ctl->used, id);
3936
3937                         rtw_iface_bcmc_id_set(padapter, INVALID_SEC_MAC_CAM_ID);
3938                 }
3939
3940                 for (i = 0; i < CONFIG_IFACE_NUMBER; i++)
3941                         rtw_macid_map_clr(&macid_ctl->if_g[i], psta->mac_id);
3942                 for (i = 0; i < 2; i++)
3943                         rtw_macid_map_clr(&macid_ctl->ch_g[i], psta->mac_id);
3944                 macid_ctl->sta[psta->mac_id] = NULL;
3945         }
3946
3947         _exit_critical_bh(&macid_ctl->lock, &irqL);
3948
3949         psta->mac_id = macid_ctl->num;
3950 }
3951
3952 /* For 8188E RA */
3953 u8 rtw_search_max_mac_id(_adapter *padapter)
3954 {
3955         u8 max_mac_id = 0;
3956         struct dvobj_priv *dvobj = adapter_to_dvobj(padapter);
3957         struct macid_ctl_t *macid_ctl = dvobj_to_macidctl(dvobj);
3958         int i;
3959         _irqL irqL;
3960
3961         /* TODO: Only search for connected macid? */
3962
3963         _enter_critical_bh(&macid_ctl->lock, &irqL);
3964         for (i = (macid_ctl->num - 1); i > 0 ; i--) {
3965                 if (rtw_macid_is_used(macid_ctl, i))
3966                         break;
3967         }
3968         _exit_critical_bh(&macid_ctl->lock, &irqL);
3969         max_mac_id = i;
3970
3971         return max_mac_id;
3972 }
3973
3974 inline void rtw_macid_ctl_set_h2c_msr(struct macid_ctl_t *macid_ctl, u8 id, u8 h2c_msr)
3975 {
3976         if (id >= macid_ctl->num) {
3977                 rtw_warn_on(1);
3978                 return;
3979         }
3980
3981         macid_ctl->h2c_msr[id] = h2c_msr;
3982         if (0)
3983                 RTW_INFO("macid:%u, h2c_msr:"H2C_MSR_FMT"\n", id, H2C_MSR_ARG(&macid_ctl->h2c_msr[id]));
3984 }
3985
3986 inline void rtw_macid_ctl_init(struct macid_ctl_t *macid_ctl)
3987 {
3988         _rtw_spinlock_init(&macid_ctl->lock);
3989 }
3990
3991 inline void rtw_macid_ctl_deinit(struct macid_ctl_t *macid_ctl)
3992 {
3993         _rtw_spinlock_free(&macid_ctl->lock);
3994 }
3995
3996 #if 0
3997 unsigned int setup_beacon_frame(_adapter *padapter, unsigned char *beacon_frame)
3998 {
3999         unsigned short                          ATIMWindow;
4000         unsigned char                                   *pframe;
4001         struct tx_desc                          *ptxdesc;
4002         struct rtw_ieee80211_hdr        *pwlanhdr;
4003         unsigned short                          *fctrl;
4004         unsigned int                                    rate_len, len = 0;
4005         struct xmit_priv                        *pxmitpriv = &(padapter->xmitpriv);
4006         struct mlme_ext_priv    *pmlmeext = &(padapter->mlmeextpriv);
4007         struct mlme_ext_info    *pmlmeinfo = &(pmlmeext->mlmext_info);
4008         WLAN_BSSID_EX           *cur_network = &(pmlmeinfo->network);
4009         u8      bc_addr[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
4010
4011         _rtw_memset(beacon_frame, 0, 256);
4012
4013         pframe = beacon_frame + TXDESC_SIZE;
4014
4015         pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
4016
4017         fctrl = &(pwlanhdr->frame_ctl);
4018         *(fctrl) = 0;
4019
4020         _rtw_memcpy(pwlanhdr->addr1, bc_addr, ETH_ALEN);
4021         _rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN);
4022         _rtw_memcpy(pwlanhdr->addr3, get_my_bssid(cur_network), ETH_ALEN);
4023
4024         SetFrameSubType(pframe, WIFI_BEACON);
4025
4026         pframe += sizeof(struct rtw_ieee80211_hdr_3addr);
4027         len = sizeof(struct rtw_ieee80211_hdr_3addr);
4028
4029         /* timestamp will be inserted by hardware */
4030         pframe += 8;
4031         len += 8;
4032
4033         /* beacon interval: 2 bytes */
4034         _rtw_memcpy(pframe, (unsigned char *)(rtw_get_beacon_interval_from_ie(cur_network->IEs)), 2);
4035
4036         pframe += 2;
4037         len += 2;
4038
4039         /* capability info: 2 bytes */
4040         _rtw_memcpy(pframe, (unsigned char *)(rtw_get_capability_from_ie(cur_network->IEs)), 2);
4041
4042         pframe += 2;
4043         len += 2;
4044
4045         /* SSID */
4046         pframe = rtw_set_ie(pframe, _SSID_IE_, cur_network->Ssid.SsidLength, cur_network->Ssid.Ssid, &len);
4047
4048         /* supported rates... */
4049         rate_len = rtw_get_rateset_len(cur_network->SupportedRates);
4050         pframe = rtw_set_ie(pframe, _SUPPORTEDRATES_IE_, ((rate_len > 8) ? 8 : rate_len), cur_network->SupportedRates, &len);
4051
4052         /* DS parameter set */
4053         pframe = rtw_set_ie(pframe, _DSSET_IE_, 1, (unsigned char *)&(cur_network->Configuration.DSConfig), &len);
4054
4055         /* IBSS Parameter Set... */
4056         /* ATIMWindow = cur->Configuration.ATIMWindow; */
4057         ATIMWindow = 0;
4058         pframe = rtw_set_ie(pframe, _IBSS_PARA_IE_, 2, (unsigned char *)(&ATIMWindow), &len);
4059
4060         /* todo: ERP IE */
4061
4062         /* EXTERNDED SUPPORTED RATE */
4063         if (rate_len > 8)
4064                 pframe = rtw_set_ie(pframe, _EXT_SUPPORTEDRATES_IE_, (rate_len - 8), (cur_network->SupportedRates + 8), &len);
4065
4066         if ((len + TXDESC_SIZE) > 256) {
4067                 /* RTW_INFO("marc: beacon frame too large\n"); */
4068                 return 0;
4069         }
4070
4071         /* fill the tx descriptor */
4072         ptxdesc = (struct tx_desc *)beacon_frame;
4073
4074         /* offset 0      */
4075         ptxdesc->txdw0 |= cpu_to_le32(len & 0x0000ffff);
4076         ptxdesc->txdw0 |= cpu_to_le32(((TXDESC_SIZE + OFFSET_SZ) << OFFSET_SHT) & 0x00ff0000); /* default = 32 bytes for TX Desc */
4077
4078         /* offset 4      */
4079         ptxdesc->txdw1 |= cpu_to_le32((0x10 << QSEL_SHT) & 0x00001f00);
4080
4081         /* offset 8              */
4082         ptxdesc->txdw2 |= cpu_to_le32(BMC);
4083         ptxdesc->txdw2 |= cpu_to_le32(BK);
4084
4085         /* offset 16             */
4086         ptxdesc->txdw4 = 0x80000000;
4087
4088         /* offset 20 */
4089         ptxdesc->txdw5 = 0x00000000; /* 1M       */
4090
4091         return len + TXDESC_SIZE;
4092 }
4093 #endif
4094
4095 _adapter *dvobj_get_port0_adapter(struct dvobj_priv *dvobj)
4096 {
4097         _adapter *port0_iface = NULL;
4098         int i;
4099         for (i = 0; i < dvobj->iface_nums; i++) {
4100                 if (get_hw_port(dvobj->padapters[i]) == HW_PORT0)
4101                         break;
4102         }
4103
4104         if (i < 0 || i >= dvobj->iface_nums)
4105                 rtw_warn_on(1);
4106         else
4107                 port0_iface = dvobj->padapters[i];
4108
4109         return port0_iface;
4110 }
4111
4112 #if defined(CONFIG_WOWLAN) || defined(CONFIG_AP_WOWLAN)
4113 void rtw_get_current_ip_address(PADAPTER padapter, u8 *pcurrentip)
4114 {
4115         struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
4116         struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
4117         struct in_device *my_ip_ptr = padapter->pnetdev->ip_ptr;
4118         u8 ipaddress[4];
4119
4120         if ((pmlmeinfo->state & WIFI_FW_LINKING_STATE) ||
4121             pmlmeinfo->state & WIFI_FW_AP_STATE) {
4122                 if (my_ip_ptr != NULL) {
4123                         struct in_ifaddr *my_ifa_list  = my_ip_ptr->ifa_list ;
4124                         if (my_ifa_list != NULL) {
4125                                 ipaddress[0] = my_ifa_list->ifa_address & 0xFF;
4126                                 ipaddress[1] = (my_ifa_list->ifa_address >> 8) & 0xFF;
4127                                 ipaddress[2] = (my_ifa_list->ifa_address >> 16) & 0xFF;
4128                                 ipaddress[3] = my_ifa_list->ifa_address >> 24;
4129                                 RTW_INFO("%s: %d.%d.%d.%d ==========\n", __func__,
4130                                         ipaddress[0], ipaddress[1], ipaddress[2], ipaddress[3]);
4131                                 _rtw_memcpy(pcurrentip, ipaddress, 4);
4132                         }
4133                 }
4134         }
4135 }
4136 #endif
4137 #ifdef CONFIG_WOWLAN
4138 bool rtw_wowlan_parser_pattern_cmd(u8 *input, char *pattern,
4139                                    int *pattern_len, char *bit_mask)
4140 {
4141         char *cp = NULL, *end = NULL;
4142         size_t len = 0;
4143         int pos = 0, mask_pos = 0, res = 0;
4144         u8 member[2] = {0};
4145
4146         cp = strchr(input, '=');
4147         if (cp) {
4148                 *cp = 0;
4149                 cp++;
4150                 input = cp;
4151         }
4152
4153         while (1) {
4154                 cp = strchr(input, ':');
4155
4156                 if (cp) {
4157                         len = strlen(input) - strlen(cp);
4158                         *cp = 0;
4159                         cp++;
4160                 } else
4161                         len = 2;
4162
4163                 if (bit_mask && (strcmp(input, "-") == 0 ||
4164                                  strcmp(input, "xx") == 0 ||
4165                                  strcmp(input, "--") == 0)) {
4166                         /* skip this byte and leave mask bit unset */
4167                 } else {
4168                         u8 hex;
4169
4170                         strncpy(member, input, len);
4171                         if (!rtw_check_pattern_valid(member, sizeof(member))) {
4172                                 RTW_INFO("%s:[ERROR] pattern is invalid!!\n",
4173                                          __func__);
4174                                 goto error;
4175                         }
4176
4177                         res = sscanf(member, "%02hhx", &hex);
4178                         pattern[pos] = hex;
4179                         mask_pos = pos / 8;
4180                         if (bit_mask)
4181                                 bit_mask[mask_pos] |= 1 << (pos % 8);
4182                 }
4183
4184                 pos++;
4185                 if (!cp)
4186                         break;
4187                 input = cp;
4188         }
4189
4190         (*pattern_len) = pos;
4191
4192         return _TRUE;
4193 error:
4194         return _FALSE;
4195 }
4196
4197 bool rtw_check_pattern_valid(u8 *input, u8 len)
4198 {
4199         int i = 0;
4200         bool res = _FALSE;
4201
4202         if (len != 2)
4203                 goto exit;
4204
4205         for (i = 0 ; i < len ; i++)
4206                 if (IsHexDigit(input[i]) == _FALSE)
4207                         goto exit;
4208
4209         res = _SUCCESS;
4210
4211 exit:
4212         return res;
4213 }
4214
4215 u8 rtw_set_default_pattern(_adapter *adapter)
4216 {
4217         struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(adapter);
4218         struct registry_priv *pregistrypriv = &adapter->registrypriv;
4219         u8 index = 0;
4220         u8 currentip[4];
4221         u8 multicast_addr[3] = {0x01, 0x00, 0x5e};
4222         u8 multicast_ip[4] = {0xe0, 0x28, 0x28, 0x2a};
4223         u8 unicast_mask[5] = {0x3f, 0x70, 0x80, 0xc0, 0x03};
4224         u8 multicast_mask[5] = {0x07, 0x70, 0x80, 0xc0, 0x03};
4225         u8 ip_protocol[3] = {0x08, 0x00, 0x45};
4226         u8 icmp_protocol[1] = {0x01};
4227         u8 tcp_protocol[1] = {0x06};
4228         u8 udp_protocol[1] = {0x11};
4229
4230         if (pregistrypriv->default_patterns_en == _FALSE)
4231                 return 0;
4232
4233         for (index = 0 ; index < DEFAULT_PATTERN_NUM ; index++) {
4234                 _rtw_memset(pwrpriv->patterns[index].content, 0,
4235                             sizeof(pwrpriv->patterns[index].content));
4236                 _rtw_memset(pwrpriv->patterns[index].mask, 0,
4237                             sizeof(pwrpriv->patterns[index].mask));
4238                 pwrpriv->patterns[index].len = 0;
4239         }
4240
4241         rtw_get_current_ip_address(adapter, currentip);
4242
4243         /*TCP/ICMP unicast*/
4244         for (index = 0 ; index < DEFAULT_PATTERN_NUM ; index++) {
4245                 switch (index) {
4246                 case 0:
4247                         _rtw_memcpy(pwrpriv->patterns[index].content,
4248                                     adapter_mac_addr(adapter),
4249                                     ETH_ALEN);
4250                         _rtw_memcpy(pwrpriv->patterns[index].content + ETH_TYPE_OFFSET,
4251                                     &ip_protocol, sizeof(ip_protocol));
4252                         _rtw_memcpy(pwrpriv->patterns[index].content + PROTOCOL_OFFSET,
4253                                     &tcp_protocol, sizeof(tcp_protocol));
4254                         _rtw_memcpy(pwrpriv->patterns[index].content + IP_OFFSET,
4255                                     &currentip, sizeof(currentip));
4256                         _rtw_memcpy(pwrpriv->patterns[index].mask,
4257                                     &unicast_mask, sizeof(unicast_mask));
4258                         pwrpriv->patterns[index].len = IP_OFFSET + sizeof(currentip);
4259                         break;
4260                 case 1:
4261                         _rtw_memcpy(pwrpriv->patterns[index].content,
4262                                     adapter_mac_addr(adapter),
4263                                     ETH_ALEN);
4264                         _rtw_memcpy(pwrpriv->patterns[index].content + ETH_TYPE_OFFSET,
4265                                     &ip_protocol, sizeof(ip_protocol));
4266                         _rtw_memcpy(pwrpriv->patterns[index].content + PROTOCOL_OFFSET,
4267                                     &icmp_protocol, sizeof(icmp_protocol));
4268                         _rtw_memcpy(pwrpriv->patterns[index].content + IP_OFFSET,
4269                                     &currentip, sizeof(currentip));
4270                         _rtw_memcpy(pwrpriv->patterns[index].mask,
4271                                     &unicast_mask, sizeof(unicast_mask));
4272                         pwrpriv->patterns[index].len = IP_OFFSET + sizeof(currentip);
4273                         break;
4274                 case 2:
4275                         _rtw_memcpy(pwrpriv->patterns[index].content, &multicast_addr,
4276                                     sizeof(multicast_addr));
4277                         _rtw_memcpy(pwrpriv->patterns[index].content + ETH_TYPE_OFFSET,
4278                                     &ip_protocol, sizeof(ip_protocol));
4279                         _rtw_memcpy(pwrpriv->patterns[index].content + PROTOCOL_OFFSET,
4280                                     &udp_protocol, sizeof(udp_protocol));
4281                         _rtw_memcpy(pwrpriv->patterns[index].content + IP_OFFSET,
4282                                     &multicast_ip, sizeof(multicast_ip));
4283                         _rtw_memcpy(pwrpriv->patterns[index].mask,
4284                                     &multicast_mask, sizeof(multicast_mask));
4285                         pwrpriv->patterns[index].len =
4286                                 IP_OFFSET + sizeof(multicast_ip);
4287                         break;
4288                 }
4289         }
4290
4291         return index;
4292 }
4293
4294 bool rtw_read_from_frame_mask(_adapter *adapter, u8 idx)
4295 {
4296         u32 data_l = 0, data_h = 0, rx_dma_buff_sz = 0, page_sz = 0;
4297         u16 offset, rx_buf_ptr = 0;
4298         u16 cam_start_offset = 0;
4299         u16 ctrl_l = 0, ctrl_h = 0;
4300         u8 count = 0, tmp = 0;
4301         int i = 0;
4302         bool res = _TRUE;
4303
4304         if (idx > MAX_WKFM_NUM) {
4305                 RTW_INFO("[Error]: %s, pattern index is out of range\n",
4306                          __func__);
4307                 return _FALSE;
4308         }
4309
4310         rtw_hal_get_def_var(adapter, HAL_DEF_RX_DMA_SZ_WOW,
4311                             (u8 *)&rx_dma_buff_sz);
4312
4313         if (rx_dma_buff_sz == 0) {
4314                 RTW_INFO("[Error]: %s, rx_dma_buff_sz is 0!!\n", __func__);
4315                 return _FALSE;
4316         }
4317
4318         rtw_hal_get_def_var(adapter, HAL_DEF_RX_PAGE_SIZE, (u8 *)&page_sz);
4319
4320         if (page_sz == 0) {
4321                 RTW_INFO("[Error]: %s, page_sz is 0!!\n", __func__);
4322                 return _FALSE;
4323         }
4324
4325         offset = (u16)PageNum(rx_dma_buff_sz, page_sz);
4326         cam_start_offset = offset * page_sz;
4327
4328         ctrl_l = 0x0;
4329         ctrl_h = 0x0;
4330
4331         /* Enable RX packet buffer access */
4332         rtw_write8(adapter, REG_PKT_BUFF_ACCESS_CTRL, RXPKT_BUF_SELECT);
4333
4334         /* Read the WKFM CAM */
4335         for (i = 0; i < (WKFMCAM_ADDR_NUM / 2); i++) {
4336                 /*
4337                  * Set Rx packet buffer offset.
4338                  * RxBufer pointer increases 1, we can access 8 bytes in Rx packet buffer.
4339                  * CAM start offset (unit: 1 byte) =  Index*WKFMCAM_SIZE
4340                  * RxBufer pointer addr = (CAM start offset + per entry offset of a WKFMCAM)/8
4341                  * * Index: The index of the wake up frame mask
4342                  * * WKFMCAM_SIZE: the total size of one WKFM CAM
4343                  * * per entry offset of a WKFM CAM: Addr i * 4 bytes
4344                  */
4345                 rx_buf_ptr =
4346                         (cam_start_offset + idx * WKFMCAM_SIZE + i * 8) >> 3;
4347                 rtw_write16(adapter, REG_PKTBUF_DBG_CTRL, rx_buf_ptr);
4348
4349                 rtw_write16(adapter, REG_RXPKTBUF_CTRL, ctrl_l);
4350                 data_l = rtw_read32(adapter, REG_PKTBUF_DBG_DATA_L);
4351                 data_h = rtw_read32(adapter, REG_PKTBUF_DBG_DATA_H);
4352
4353                 RTW_INFO("[%d]: %08x %08x\n", i, data_h, data_l);
4354
4355                 count = 0;
4356
4357                 do {
4358                         tmp = rtw_read8(adapter, REG_RXPKTBUF_CTRL);
4359                         rtw_udelay_os(2);
4360                         count++;
4361                 } while (!tmp && count < 100);
4362
4363                 if (count >= 100) {
4364                         RTW_INFO("%s count:%d\n", __func__, count);
4365                         res = _FALSE;
4366                 }
4367         }
4368
4369         /* Disable RX packet buffer access */
4370         rtw_write8(adapter, REG_PKT_BUFF_ACCESS_CTRL,
4371                    DISABLE_TRXPKT_BUF_ACCESS);
4372         return res;
4373 }
4374
4375 bool rtw_write_to_frame_mask(_adapter *adapter, u8 idx,
4376                              struct  rtl_wow_pattern *context)
4377 {
4378         u32 data = 0, rx_dma_buff_sz = 0, page_sz = 0;
4379         u16 offset, rx_buf_ptr = 0;
4380         u16 cam_start_offset = 0;
4381         u16 ctrl_l = 0, ctrl_h = 0;
4382         u8 count = 0, tmp = 0;
4383         int res = 0, i = 0;
4384
4385         if (idx > MAX_WKFM_NUM) {
4386                 RTW_INFO("[Error]: %s, pattern index is out of range\n",
4387                          __func__);
4388                 return _FALSE;
4389         }
4390
4391         rtw_hal_get_def_var(adapter, HAL_DEF_RX_DMA_SZ_WOW,
4392                             (u8 *)&rx_dma_buff_sz);
4393
4394         if (rx_dma_buff_sz == 0) {
4395                 RTW_INFO("[Error]: %s, rx_dma_buff_sz is 0!!\n", __func__);
4396                 return _FALSE;
4397         }
4398
4399         rtw_hal_get_def_var(adapter, HAL_DEF_RX_PAGE_SIZE, (u8 *)&page_sz);
4400
4401         if (page_sz == 0) {
4402                 RTW_INFO("[Error]: %s, page_sz is 0!!\n", __func__);
4403                 return _FALSE;
4404         }
4405
4406         offset = (u16)PageNum(rx_dma_buff_sz, page_sz);
4407
4408         cam_start_offset = offset * page_sz;
4409
4410         if (IS_HARDWARE_TYPE_8188E(adapter)) {
4411                 ctrl_l = 0x0001;
4412                 ctrl_h = 0x0001;
4413         } else {
4414                 ctrl_l = 0x0f01;
4415                 ctrl_h = 0xf001;
4416         }
4417
4418         /* Enable RX packet buffer access */
4419         rtw_write8(adapter, REG_PKT_BUFF_ACCESS_CTRL, RXPKT_BUF_SELECT);
4420
4421         /* Write the WKFM CAM */
4422         for (i = 0; i < WKFMCAM_ADDR_NUM; i++) {
4423                 /*
4424                  * Set Rx packet buffer offset.
4425                  * RxBufer pointer increases 1, we can access 8 bytes in Rx packet buffer.
4426                  * CAM start offset (unit: 1 byte) =  Index*WKFMCAM_SIZE
4427                  * RxBufer pointer addr = (CAM start offset + per entry offset of a WKFMCAM)/8
4428                  * * Index: The index of the wake up frame mask
4429                  * * WKFMCAM_SIZE: the total size of one WKFM CAM
4430                  * * per entry offset of a WKFM CAM: Addr i * 4 bytes
4431                  */
4432                 rx_buf_ptr =
4433                         (cam_start_offset + idx * WKFMCAM_SIZE + i * 4) >> 3;
4434                 rtw_write16(adapter, REG_PKTBUF_DBG_CTRL, rx_buf_ptr);
4435
4436                 if (i == 0) {
4437                         if (context->type == PATTERN_VALID)
4438                                 data = BIT(31);
4439                         else if (context->type == PATTERN_BROADCAST)
4440                                 data = BIT(31) | BIT(26);
4441                         else if (context->type == PATTERN_MULTICAST)
4442                                 data = BIT(31) | BIT(25);
4443                         else if (context->type == PATTERN_UNICAST)
4444                                 data = BIT(31) | BIT(24);
4445
4446                         if (context->crc != 0)
4447                                 data |= context->crc;
4448
4449                         rtw_write32(adapter, REG_PKTBUF_DBG_DATA_L, data);
4450                         rtw_write16(adapter, REG_RXPKTBUF_CTRL, ctrl_l);
4451                 } else if (i == 1) {
4452                         data = 0;
4453                         rtw_write32(adapter, REG_PKTBUF_DBG_DATA_H, data);
4454                         rtw_write16(adapter, REG_RXPKTBUF_CTRL, ctrl_h);
4455                 } else if (i == 2 || i == 4) {
4456                         data = context->mask[i - 2];
4457                         rtw_write32(adapter, REG_PKTBUF_DBG_DATA_L, data);
4458                         /* write to RX packet buffer*/
4459                         rtw_write16(adapter, REG_RXPKTBUF_CTRL, ctrl_l);
4460                 } else if (i == 3 || i == 5) {
4461                         data = context->mask[i - 2];
4462                         rtw_write32(adapter, REG_PKTBUF_DBG_DATA_H, data);
4463                         /* write to RX packet buffer*/
4464                         rtw_write16(adapter, REG_RXPKTBUF_CTRL, ctrl_h);
4465                 }
4466
4467                 count = 0;
4468                 do {
4469                         tmp = rtw_read8(adapter, REG_RXPKTBUF_CTRL);
4470                         rtw_udelay_os(2);
4471                         count++;
4472                 } while (tmp && count < 100);
4473
4474                 if (count >= 100)
4475                         res = _FALSE;
4476                 else
4477                         res = _TRUE;
4478         }
4479
4480         /* Disable RX packet buffer access */
4481         rtw_write8(adapter, REG_PKT_BUFF_ACCESS_CTRL,
4482                    DISABLE_TRXPKT_BUF_ACCESS);
4483
4484         return res;
4485 }
4486
4487
4488 void rtw_dump_priv_pattern(_adapter *adapter, u8 idx)
4489 {
4490         struct pwrctrl_priv *pwrctl = adapter_to_pwrctl(adapter);
4491         char str_1[128];
4492         char *p_str;
4493         u8 val8 = 0;
4494         int i = 0, j = 0, len = 0, max_len = 0;
4495
4496         RTW_INFO("=========[%d]========\n", idx);
4497
4498         RTW_INFO(">>>priv_pattern_content:\n");
4499         p_str = str_1;
4500         max_len = sizeof(str_1);
4501         for (i = 0 ; i < MAX_WKFM_PATTERN_SIZE / 8 ; i++) {
4502                 _rtw_memset(p_str, 0, max_len);
4503                 len = 0;
4504                 for (j = 0 ; j < 8 ; j++) {
4505                         val8 = pwrctl->patterns[idx].content[i * 8 + j];
4506                         len += snprintf(p_str + len, max_len - len,
4507                                         "%02x ", val8);
4508                 }
4509                 RTW_INFO("%s\n", p_str);
4510         }
4511
4512         RTW_INFO(">>>priv_pattern_mask:\n");
4513         for (i = 0 ; i < MAX_WKFM_SIZE / 8 ; i++) {
4514                 _rtw_memset(p_str, 0, max_len);
4515                 len = 0;
4516                 for (j = 0 ; j < 8 ; j++) {
4517                         val8 = pwrctl->patterns[idx].mask[i * 8 + j];
4518                         len += snprintf(p_str + len, max_len - len,
4519                                         "%02x ", val8);
4520                 }
4521                 RTW_INFO("%s\n", p_str);
4522         }
4523
4524         RTW_INFO(">>>priv_pattern_len:\n");
4525         RTW_INFO("%s: len: %d\n", __func__, pwrctl->patterns[idx].len);
4526 }
4527
4528 void rtw_clean_pattern(_adapter *adapter)
4529 {
4530         struct pwrctrl_priv *pwrctl = adapter_to_pwrctl(adapter);
4531         struct rtl_wow_pattern zero_pattern;
4532         int i = 0;
4533
4534         _rtw_memset(&zero_pattern, 0, sizeof(struct rtl_wow_pattern));
4535
4536         zero_pattern.type = PATTERN_INVALID;
4537
4538         for (i = 0; i < MAX_WKFM_NUM; i++)
4539                 rtw_write_to_frame_mask(adapter, i, &zero_pattern);
4540
4541         rtw_write8(adapter, REG_WKFMCAM_NUM, 0);
4542 }
4543
4544 void rtw_get_sec_iv(PADAPTER padapter, u8 *pcur_dot11txpn, u8 *StaAddr)
4545 {
4546         struct sta_info         *psta;
4547         struct security_priv *psecpriv = &padapter->securitypriv;
4548
4549         _rtw_memset(pcur_dot11txpn, 0, 8);
4550         if (NULL == StaAddr)
4551                 return;
4552         psta = rtw_get_stainfo(&padapter->stapriv, StaAddr);
4553         RTW_INFO("%s(): StaAddr: %02x %02x %02x %02x %02x %02x\n",
4554                  __func__, StaAddr[0], StaAddr[1], StaAddr[2],
4555                  StaAddr[3], StaAddr[4], StaAddr[5]);
4556
4557         if (psta) {
4558                 if (psecpriv->dot11PrivacyAlgrthm != _NO_PRIVACY_ && psta->dot11txpn.val > 0)
4559                         psta->dot11txpn.val--;
4560                 AES_IV(pcur_dot11txpn, psta->dot11txpn, 0);
4561
4562                 RTW_INFO("%s(): CurrentIV: %02x %02x %02x %02x %02x %02x %02x %02x\n"
4563                          , __func__, pcur_dot11txpn[0], pcur_dot11txpn[1],
4564                         pcur_dot11txpn[2], pcur_dot11txpn[3], pcur_dot11txpn[4],
4565                         pcur_dot11txpn[5], pcur_dot11txpn[6], pcur_dot11txpn[7]);
4566         }
4567 }
4568 void rtw_set_sec_pn(PADAPTER padapter)
4569 {
4570         struct sta_info         *psta;
4571         struct mlme_ext_priv    *pmlmeext = &(padapter->mlmeextpriv);
4572         struct mlme_ext_info    *pmlmeinfo = &(pmlmeext->mlmext_info);
4573         struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(padapter);
4574         struct security_priv *psecpriv = &padapter->securitypriv;
4575
4576         psta = rtw_get_stainfo(&padapter->stapriv,
4577                                get_my_bssid(&pmlmeinfo->network));
4578
4579         if (psta) {
4580                 if (pwrpriv->wowlan_fw_iv > psta->dot11txpn.val) {
4581                         if (psecpriv->dot11PrivacyAlgrthm != _NO_PRIVACY_)
4582                                 psta->dot11txpn.val = pwrpriv->wowlan_fw_iv + 2;
4583                 } else {
4584                         RTW_INFO("%s(): FW IV is smaller than driver\n", __func__);
4585                         psta->dot11txpn.val += 2;
4586                 }
4587                 RTW_INFO("%s: dot11txpn: 0x%016llx\n", __func__ , psta->dot11txpn.val);
4588         }
4589 }
4590 #endif /* CONFIG_WOWLAN */
4591
4592 #ifdef CONFIG_PNO_SUPPORT
4593 #define CSCAN_TLV_TYPE_SSID_IE  'S'
4594 #define CIPHER_IE "key_mgmt="
4595 #define CIPHER_NONE "NONE"
4596 #define CIPHER_WPA_PSK "WPA-PSK"
4597 #define CIPHER_WPA_EAP "WPA-EAP IEEE8021X"
4598 /*
4599  *  SSIDs list parsing from cscan tlv list
4600  */
4601 int rtw_parse_ssid_list_tlv(char **list_str, pno_ssid_t *ssid,
4602                             int max, int *bytes_left)
4603 {
4604         char *str;
4605
4606         int idx = 0;
4607
4608         if ((list_str == NULL) || (*list_str == NULL) || (*bytes_left < 0)) {
4609                 RTW_INFO("%s error paramters\n", __func__);
4610                 return -1;
4611         }
4612
4613         str = *list_str;
4614         while (*bytes_left > 0) {
4615
4616                 if (str[0] != CSCAN_TLV_TYPE_SSID_IE) {
4617                         *list_str = str;
4618                         RTW_INFO("nssid=%d left_parse=%d %d\n", idx, *bytes_left, str[0]);
4619                         return idx;
4620                 }
4621
4622                 /* Get proper CSCAN_TLV_TYPE_SSID_IE */
4623                 *bytes_left -= 1;
4624                 str += 1;
4625
4626                 if (str[0] == 0) {
4627                         /* Broadcast SSID */
4628                         ssid[idx].SSID_len = 0;
4629                         memset((char *)ssid[idx].SSID, 0x0, WLAN_SSID_MAXLEN);
4630                         *bytes_left -= 1;
4631                         str += 1;
4632
4633                         RTW_INFO("BROADCAST SCAN  left=%d\n", *bytes_left);
4634                 } else if (str[0] <= WLAN_SSID_MAXLEN) {
4635                         /* Get proper SSID size */
4636                         ssid[idx].SSID_len = str[0];
4637                         *bytes_left -= 1;
4638                         str += 1;
4639
4640                         /* Get SSID */
4641                         if (ssid[idx].SSID_len > *bytes_left) {
4642                                 RTW_INFO("%s out of memory range len=%d but left=%d\n",
4643                                         __func__, ssid[idx].SSID_len, *bytes_left);
4644                                 return -1;
4645                         }
4646
4647                         memcpy((char *)ssid[idx].SSID, str, ssid[idx].SSID_len);
4648
4649                         *bytes_left -= ssid[idx].SSID_len;
4650                         str += ssid[idx].SSID_len;
4651
4652                         RTW_INFO("%s :size=%d left=%d\n",
4653                                 (char *)ssid[idx].SSID, ssid[idx].SSID_len, *bytes_left);
4654                 } else {
4655                         RTW_INFO("### SSID size more that %d\n", str[0]);
4656                         return -1;
4657                 }
4658
4659                 if (idx++ >  max) {
4660                         RTW_INFO("%s number of SSIDs more that %d\n", __func__, idx);
4661                         return -1;
4662                 }
4663         }
4664
4665         *list_str = str;
4666         return idx;
4667 }
4668
4669 int rtw_parse_cipher_list(struct pno_nlo_info *nlo_info, char *list_str)
4670 {
4671
4672         char *pch, *pnext, *pend;
4673         u8 key_len = 0, index = 0;
4674
4675         pch = list_str;
4676
4677         if (nlo_info == NULL || list_str == NULL) {
4678                 RTW_INFO("%s error paramters\n", __func__);
4679                 return -1;
4680         }
4681
4682         while (strlen(pch) != 0) {
4683                 pnext = strstr(pch, "key_mgmt=");
4684                 if (pnext != NULL) {
4685                         pch = pnext + strlen(CIPHER_IE);
4686                         pend = strstr(pch, "}");
4687                         if (strncmp(pch, CIPHER_NONE,
4688                                     strlen(CIPHER_NONE)) == 0)
4689                                 nlo_info->ssid_cipher_info[index] = 0x00;
4690                         else if (strncmp(pch, CIPHER_WPA_PSK,
4691                                          strlen(CIPHER_WPA_PSK)) == 0)
4692                                 nlo_info->ssid_cipher_info[index] = 0x66;
4693                         else if (strncmp(pch, CIPHER_WPA_EAP,
4694                                          strlen(CIPHER_WPA_EAP)) == 0)
4695                                 nlo_info->ssid_cipher_info[index] = 0x01;
4696                         index++;
4697                         pch = pend + 1;
4698                 } else
4699                         break;
4700         }
4701         return 0;
4702 }
4703
4704 int rtw_dev_nlo_info_set(struct pno_nlo_info *nlo_info, pno_ssid_t *ssid,
4705                  int num, int pno_time, int pno_repeat, int pno_freq_expo_max)
4706 {
4707
4708         int i = 0;
4709         struct file *fp;
4710         mm_segment_t fs;
4711         loff_t pos = 0;
4712         u8 *source = NULL;
4713         long len = 0;
4714
4715         RTW_INFO("+%s+\n", __func__);
4716
4717         nlo_info->fast_scan_period = pno_time;
4718         nlo_info->ssid_num = num & BIT_LEN_MASK_32(8);
4719         nlo_info->hidden_ssid_num = num & BIT_LEN_MASK_32(8);
4720         nlo_info->slow_scan_period = (pno_time * 2);
4721         nlo_info->fast_scan_iterations = 5;
4722
4723         if (nlo_info->hidden_ssid_num > 8)
4724                 nlo_info->hidden_ssid_num = 8;
4725
4726         /* TODO: channel list and probe index is all empty. */
4727         for (i = 0 ; i < num ; i++) {
4728                 nlo_info->ssid_length[i]
4729                         = ssid[i].SSID_len;
4730         }
4731
4732         /* cipher array */
4733         fp = filp_open("/home/timlee/wpa_kk/wpa.conf", O_RDONLY,  0644);
4734         if (IS_ERR(fp)) {
4735                 RTW_INFO("Error, wpa_supplicant.conf doesn't exist.\n");
4736                 RTW_INFO("Error, cipher array using default value.\n");
4737                 return 0;
4738         }
4739
4740         len = i_size_read(fp->f_path.dentry->d_inode);
4741         if (len < 0 || len > 2048) {
4742                 RTW_INFO("Error, file size is bigger than 2048.\n");
4743                 RTW_INFO("Error, cipher array using default value.\n");
4744                 return 0;
4745         }
4746
4747         fs = get_fs();
4748         set_fs(KERNEL_DS);
4749
4750         source = rtw_zmalloc(2048);
4751
4752         if (source != NULL) {
4753                 len = vfs_read(fp, source, len, &pos);
4754                 rtw_parse_cipher_list(nlo_info, source);
4755                 rtw_mfree(source, 2048);
4756         }
4757
4758         set_fs(fs);
4759         filp_close(fp, NULL);
4760
4761         RTW_INFO("-%s-\n", __func__);
4762         return 0;
4763 }
4764
4765 int rtw_dev_ssid_list_set(struct pno_ssid_list *pno_ssid_list,
4766                           pno_ssid_t *ssid, u8 num)
4767 {
4768
4769         int i = 0;
4770         if (num > MAX_PNO_LIST_COUNT)
4771                 num = MAX_PNO_LIST_COUNT;
4772
4773         for (i = 0 ; i < num ; i++) {
4774                 _rtw_memcpy(&pno_ssid_list->node[i].SSID,
4775                             ssid[i].SSID, ssid[i].SSID_len);
4776                 pno_ssid_list->node[i].SSID_len = ssid[i].SSID_len;
4777         }
4778         return 0;
4779 }
4780
4781 int rtw_dev_scan_info_set(_adapter *padapter, pno_ssid_t *ssid,
4782           unsigned char ch, unsigned char ch_offset, unsigned short bw_mode)
4783 {
4784
4785         struct pwrctrl_priv *pwrctl = adapter_to_pwrctl(padapter);
4786         struct pno_scan_info *scan_info = pwrctl->pscan_info;
4787         int i;
4788
4789         scan_info->channel_num = MAX_SCAN_LIST_COUNT;
4790         scan_info->orig_ch = ch;
4791         scan_info->orig_bw = bw_mode;
4792         scan_info->orig_40_offset = ch_offset;
4793
4794         for (i = 0 ; i < scan_info->channel_num ; i++) {
4795                 if (i < 11)
4796                         scan_info->ssid_channel_info[i].active = 1;
4797                 else
4798                         scan_info->ssid_channel_info[i].active = 0;
4799
4800                 scan_info->ssid_channel_info[i].timeout = 100;
4801
4802                 scan_info->ssid_channel_info[i].tx_power =
4803                         PHY_GetTxPowerIndex(padapter, 0, 0x02, bw_mode, i + 1);
4804
4805                 scan_info->ssid_channel_info[i].channel = i + 1;
4806         }
4807
4808         RTW_INFO("%s, channel_num: %d, orig_ch: %d, orig_bw: %d orig_40_offset: %d\n",
4809                  __func__, scan_info->channel_num, scan_info->orig_ch,
4810                  scan_info->orig_bw, scan_info->orig_40_offset);
4811         return 0;
4812 }
4813
4814 int rtw_dev_pno_set(struct net_device *net, pno_ssid_t *ssid, int num,
4815                     int pno_time, int pno_repeat, int pno_freq_expo_max)
4816 {
4817
4818         _adapter *padapter = (_adapter *)rtw_netdev_priv(net);
4819         struct pwrctrl_priv *pwrctl = adapter_to_pwrctl(padapter);
4820         struct mlme_ext_priv    *pmlmeext = &padapter->mlmeextpriv;
4821
4822         int ret = -1;
4823
4824         if (num == 0) {
4825                 RTW_INFO("%s, nssid is zero, no need to setup pno ssid list\n", __func__);
4826                 return 0;
4827         }
4828
4829         if (pwrctl == NULL) {
4830                 RTW_INFO("%s, ERROR: pwrctl is NULL\n", __func__);
4831                 return -1;
4832         } else {
4833                 pwrctl->pnlo_info =
4834                         (pno_nlo_info_t *)rtw_zmalloc(sizeof(pno_nlo_info_t));
4835                 pwrctl->pno_ssid_list =
4836                         (pno_ssid_list_t *)rtw_zmalloc(sizeof(pno_ssid_list_t));
4837                 pwrctl->pscan_info =
4838                         (pno_scan_info_t *)rtw_zmalloc(sizeof(pno_scan_info_t));
4839         }
4840
4841         if (pwrctl->pnlo_info == NULL ||
4842             pwrctl->pscan_info == NULL ||
4843             pwrctl->pno_ssid_list == NULL) {
4844                 RTW_INFO("%s, ERROR: alloc nlo_info, ssid_list, scan_info fail\n", __func__);
4845                 goto failing;
4846         }
4847
4848         pwrctl->pno_in_resume = _FALSE;
4849
4850         pwrctl->pno_inited = _TRUE;
4851         /* NLO Info */
4852         ret = rtw_dev_nlo_info_set(pwrctl->pnlo_info, ssid, num,
4853                                    pno_time, pno_repeat, pno_freq_expo_max);
4854
4855         /* SSID Info */
4856         ret = rtw_dev_ssid_list_set(pwrctl->pno_ssid_list, ssid, num);
4857
4858         /* SCAN Info */
4859         ret = rtw_dev_scan_info_set(padapter, ssid, pmlmeext->cur_channel,
4860                             pmlmeext->cur_ch_offset, pmlmeext->cur_bwmode);
4861
4862         RTW_INFO("+%s num: %d, pno_time: %d, pno_repeat:%d, pno_freq_expo_max:%d+\n",
4863                  __func__, num, pno_time, pno_repeat, pno_freq_expo_max);
4864
4865         return 0;
4866
4867 failing:
4868         if (pwrctl->pnlo_info) {
4869                 rtw_mfree((u8 *)pwrctl->pnlo_info, sizeof(pno_nlo_info_t));
4870                 pwrctl->pnlo_info = NULL;
4871         }
4872         if (pwrctl->pno_ssid_list) {
4873                 rtw_mfree((u8 *)pwrctl->pno_ssid_list, sizeof(pno_ssid_list_t));
4874                 pwrctl->pno_ssid_list = NULL;
4875         }
4876         if (pwrctl->pscan_info) {
4877                 rtw_mfree((u8 *)pwrctl->pscan_info, sizeof(pno_scan_info_t));
4878                 pwrctl->pscan_info = NULL;
4879         }
4880
4881         return -1;
4882 }
4883
4884 #ifdef CONFIG_PNO_SET_DEBUG
4885 void rtw_dev_pno_debug(struct net_device *net)
4886 {
4887         _adapter *padapter = (_adapter *)rtw_netdev_priv(net);
4888         struct pwrctrl_priv *pwrctl = adapter_to_pwrctl(padapter);
4889         int i = 0, j = 0;
4890
4891         RTW_INFO("*******NLO_INFO********\n");
4892         RTW_INFO("ssid_num: %d\n", pwrctl->pnlo_info->ssid_num);
4893         RTW_INFO("fast_scan_iterations: %d\n",
4894                  pwrctl->pnlo_info->fast_scan_iterations);
4895         RTW_INFO("fast_scan_period: %d\n", pwrctl->pnlo_info->fast_scan_period);
4896         RTW_INFO("slow_scan_period: %d\n", pwrctl->pnlo_info->slow_scan_period);
4897
4898
4899
4900         for (i = 0 ; i < MAX_PNO_LIST_COUNT ; i++) {
4901                 RTW_INFO("%d SSID (%s) length (%d) cipher(%x) channel(%d)\n",
4902                         i, pwrctl->pno_ssid_list->node[i].SSID, pwrctl->pnlo_info->ssid_length[i],
4903                         pwrctl->pnlo_info->ssid_cipher_info[i], pwrctl->pnlo_info->ssid_channel_info[i]);
4904         }
4905
4906         RTW_INFO("******SCAN_INFO******\n");
4907         RTW_INFO("ch_num: %d\n", pwrctl->pscan_info->channel_num);
4908         RTW_INFO("orig_ch: %d\n", pwrctl->pscan_info->orig_ch);
4909         RTW_INFO("orig bw: %d\n", pwrctl->pscan_info->orig_bw);
4910         RTW_INFO("orig 40 offset: %d\n", pwrctl->pscan_info->orig_40_offset);
4911         for (i = 0 ; i < MAX_SCAN_LIST_COUNT ; i++) {
4912                 RTW_INFO("[%02d] avtive:%d, timeout:%d, tx_power:%d, ch:%02d\n",
4913                          i, pwrctl->pscan_info->ssid_channel_info[i].active,
4914                          pwrctl->pscan_info->ssid_channel_info[i].timeout,
4915                          pwrctl->pscan_info->ssid_channel_info[i].tx_power,
4916                          pwrctl->pscan_info->ssid_channel_info[i].channel);
4917         }
4918         RTW_INFO("*****************\n");
4919 }
4920 #endif /* CONFIG_PNO_SET_DEBUG */
4921 #endif /* CONFIG_PNO_SUPPORT */