add rk3288 pinctrl dts code
[firefly-linux-kernel-4.4.55.git] / drivers / net / wireless / rtl8723bs / 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 #ifdef CONFIG_WOWLAN
25 #include <linux/inetdevice.h>
26 #endif
27
28 unsigned char ARTHEROS_OUI1[] = {0x00, 0x03, 0x7f};
29 unsigned char ARTHEROS_OUI2[] = {0x00, 0x13, 0x74};
30
31 unsigned char BROADCOM_OUI1[] = {0x00, 0x10, 0x18};
32 unsigned char BROADCOM_OUI2[] = {0x00, 0x0a, 0xf7};
33 unsigned char BROADCOM_OUI3[] = {0x00, 0x05, 0xb5};
34
35 unsigned char CISCO_OUI[] = {0x00, 0x40, 0x96};
36 unsigned char MARVELL_OUI[] = {0x00, 0x50, 0x43};
37 unsigned char RALINK_OUI[] = {0x00, 0x0c, 0x43};
38 unsigned char REALTEK_OUI[] = {0x00, 0xe0, 0x4c};
39 unsigned char AIRGOCAP_OUI[] = {0x00, 0x0a, 0xf5};
40
41 unsigned char REALTEK_96B_IE[] = {0x00, 0xe0, 0x4c, 0x02, 0x01, 0x20};
42
43 extern unsigned char    MCS_rate_2R[16];
44 #ifdef CONFIG_DISABLE_MCS13TO15
45 extern unsigned char    MCS_rate_2R_MCS13TO15_OFF[16];
46 #endif //CONFIG_DISABLE_MCS13TO15
47 extern unsigned char    MCS_rate_1R[16];
48 extern unsigned char RTW_WPA_OUI[];
49 extern unsigned char WPA_TKIP_CIPHER[4];
50 extern unsigned char RSN_TKIP_CIPHER[4];
51
52 #define R2T_PHY_DELAY   (0)
53
54 //#define WAIT_FOR_BCN_TO_MIN   (3000)
55 #define WAIT_FOR_BCN_TO_MIN     (6000)
56 #define WAIT_FOR_BCN_TO_MAX     (20000)
57
58 static u8 rtw_basic_rate_cck[4] = {
59         IEEE80211_CCK_RATE_1MB|IEEE80211_BASIC_RATE_MASK, IEEE80211_CCK_RATE_2MB|IEEE80211_BASIC_RATE_MASK,
60         IEEE80211_CCK_RATE_5MB|IEEE80211_BASIC_RATE_MASK, IEEE80211_CCK_RATE_11MB|IEEE80211_BASIC_RATE_MASK
61 };
62
63 static u8 rtw_basic_rate_ofdm[3] = {
64         IEEE80211_OFDM_RATE_6MB|IEEE80211_BASIC_RATE_MASK, IEEE80211_OFDM_RATE_12MB|IEEE80211_BASIC_RATE_MASK,
65         IEEE80211_OFDM_RATE_24MB|IEEE80211_BASIC_RATE_MASK
66 };
67
68 static u8 rtw_basic_rate_mix[7] = {
69         IEEE80211_CCK_RATE_1MB|IEEE80211_BASIC_RATE_MASK, IEEE80211_CCK_RATE_2MB|IEEE80211_BASIC_RATE_MASK,
70         IEEE80211_CCK_RATE_5MB|IEEE80211_BASIC_RATE_MASK, IEEE80211_CCK_RATE_11MB|IEEE80211_BASIC_RATE_MASK,
71         IEEE80211_OFDM_RATE_6MB|IEEE80211_BASIC_RATE_MASK, IEEE80211_OFDM_RATE_12MB|IEEE80211_BASIC_RATE_MASK,
72         IEEE80211_OFDM_RATE_24MB|IEEE80211_BASIC_RATE_MASK
73 };
74
75
76 int cckrates_included(unsigned char *rate, int ratelen)
77 {
78         int     i;
79         
80         for(i = 0; i < ratelen; i++)
81         {
82                 if  (  (((rate[i]) & 0x7f) == 2)        || (((rate[i]) & 0x7f) == 4) ||
83                            (((rate[i]) & 0x7f) == 11)  || (((rate[i]) & 0x7f) == 22) )
84                 return _TRUE;   
85         }
86
87         return _FALSE;
88
89 }
90
91 int cckratesonly_included(unsigned char *rate, int ratelen)
92 {
93         int     i;
94         
95         for(i = 0; i < ratelen; i++)
96         {
97                 if  ( (((rate[i]) & 0x7f) != 2) && (((rate[i]) & 0x7f) != 4) &&
98                            (((rate[i]) & 0x7f) != 11)  && (((rate[i]) & 0x7f) != 22) )
99                 return _FALSE;  
100         }
101         
102         return _TRUE;
103 }
104
105 u8 networktype_to_raid(_adapter *adapter,struct sta_info *psta)
106 {
107         unsigned char raid;
108         switch(psta->wireless_mode)
109         {
110                 case WIRELESS_11B:
111                         raid = RATR_INX_WIRELESS_B;
112                         break;
113                 case WIRELESS_11A:
114                 case WIRELESS_11G:
115                         raid = RATR_INX_WIRELESS_G;
116                         break;
117                 case WIRELESS_11BG:
118                         raid = RATR_INX_WIRELESS_GB;
119                         break;
120                 case WIRELESS_11_24N:
121                 case WIRELESS_11_5N:
122                         raid = RATR_INX_WIRELESS_N;
123                         break;
124                 case WIRELESS_11A_5N:
125                 case WIRELESS_11G_24N:
126                         raid = RATR_INX_WIRELESS_NG;
127                         break;
128                 case WIRELESS_11BG_24N:
129                         raid = RATR_INX_WIRELESS_NGB;
130                         break;
131                 default:
132                         raid = RATR_INX_WIRELESS_GB;
133                         break;  
134
135         }
136         return raid;
137         
138 }
139
140 u8 networktype_to_raid_ex(_adapter *adapter, struct sta_info *psta)
141 {
142         struct mlme_ext_priv    *pmlmeext = &adapter->mlmeextpriv;
143         u8 raid, cur_rf_type, rf_type= RF_1T1R;
144
145         rtw_hal_get_hwreg(adapter, HW_VAR_RF_TYPE, (u8 *)(&cur_rf_type));
146
147         if(cur_rf_type == RF_1T1R) {
148                 rf_type = RF_1T1R;
149         }
150         else if(IsSupportedVHT(psta->wireless_mode)) {
151                 if(psta->ra_mask & 0xffc00000)
152                         rf_type = RF_2T2R;
153         }
154         else if(IsSupportedHT(psta->wireless_mode)) {
155                 if(psta->ra_mask & 0xfff00000)
156                         rf_type = RF_2T2R;
157         }
158
159         switch(psta->wireless_mode)
160         {
161                 case WIRELESS_11B:
162                         raid = RATEID_IDX_B;
163                         break;
164                 case WIRELESS_11A:
165                 case WIRELESS_11G:
166                         raid = RATEID_IDX_G;
167                         break;
168                 case WIRELESS_11BG:
169                         raid = RATEID_IDX_BG;
170                         break;
171                 case WIRELESS_11_24N:
172                 case WIRELESS_11_5N:
173                 case WIRELESS_11A_5N:
174                 case WIRELESS_11G_24N:
175                         if (rf_type == RF_2T2R)
176                                 raid = RATEID_IDX_GN_N2SS;
177                         else
178                                 raid = RATEID_IDX_GN_N1SS;
179                         break;
180                 case WIRELESS_11B_24N:
181                 case WIRELESS_11BG_24N:
182                         if (psta->bw_mode == CHANNEL_WIDTH_20) {
183                                 if (rf_type == RF_2T2R)
184                                         raid = RATEID_IDX_BGN_20M_2SS_BN;
185                                 else
186                                         raid = RATEID_IDX_BGN_20M_1SS_BN;
187                         } else {
188                                 if (rf_type == RF_2T2R)
189                                         raid = RATEID_IDX_BGN_40M_2SS;
190                                 else
191                                         raid = RATEID_IDX_BGN_40M_1SS;
192                         }
193                         break;
194 #ifdef CONFIG_80211AC_VHT
195                 case WIRELESS_11_5AC:
196                         if (rf_type == RF_1T1R)
197                                 raid = RATEID_IDX_VHT_1SS;
198                         else
199                                 raid = RATEID_IDX_VHT_2SS;
200                         break;
201                 case WIRELESS_11_24AC:
202                         if (psta->bw_mode >= CHANNEL_WIDTH_80)
203                         {
204                                 if (rf_type == RF_1T1R)
205                                         raid = RATEID_IDX_VHT_1SS;
206                                 else
207                                         raid = RATEID_IDX_VHT_2SS;
208                         }
209                         else
210                         {
211                                 if (rf_type == RF_1T1R)
212                                         raid = 11;
213                                 else
214                                         raid = 12;
215                         }
216                         break;
217 #endif
218                 default:
219                         raid = RATEID_IDX_BGN_40M_2SS;
220                         break;  
221
222         }
223         return raid;
224         
225 }
226
227 u8 judge_network_type(_adapter *padapter, unsigned char *rate, int ratelen)
228 {
229         u8 network_type = 0;
230         struct mlme_ext_priv    *pmlmeext = &padapter->mlmeextpriv;
231         struct mlme_ext_info    *pmlmeinfo = &(pmlmeext->mlmext_info);
232         
233
234         if(pmlmeext->cur_channel > 14)
235         {
236                 if (pmlmeinfo->VHT_enable)
237                         network_type = WIRELESS_11AC;
238                 else if (pmlmeinfo->HT_enable)
239                         network_type = WIRELESS_11_5N;
240
241                 network_type |= WIRELESS_11A;
242         }
243         else
244         {
245                 if (pmlmeinfo->HT_enable)
246                 {
247                         network_type = WIRELESS_11_24N;
248                 }
249
250                 if ((cckratesonly_included(rate, ratelen)) == _TRUE)
251                 {
252                         network_type |= WIRELESS_11B;
253                 }
254                 else if((cckrates_included(rate, ratelen)) == _TRUE)
255                 {
256                         network_type |= WIRELESS_11BG;
257                 }
258                 else
259                 {
260                         network_type |= WIRELESS_11G;
261                 }
262         }
263                 
264         return  network_type;
265 }
266
267 unsigned char ratetbl_val_2wifirate(unsigned char rate);
268 unsigned char ratetbl_val_2wifirate(unsigned char rate)
269 {
270         unsigned char val = 0;
271
272         switch (rate & 0x7f) 
273         {
274                 case 0:
275                         val = IEEE80211_CCK_RATE_1MB;
276                         break;
277
278                 case 1:
279                         val = IEEE80211_CCK_RATE_2MB;
280                         break;
281
282                 case 2:
283                         val = IEEE80211_CCK_RATE_5MB;
284                         break;
285
286                 case 3:
287                         val = IEEE80211_CCK_RATE_11MB;
288                         break;
289                         
290                 case 4:
291                         val = IEEE80211_OFDM_RATE_6MB;
292                         break;
293
294                 case 5:
295                         val = IEEE80211_OFDM_RATE_9MB;
296                         break;
297
298                 case 6:
299                         val = IEEE80211_OFDM_RATE_12MB;
300                         break;
301                         
302                 case 7:
303                         val = IEEE80211_OFDM_RATE_18MB;
304                         break;
305
306                 case 8:
307                         val = IEEE80211_OFDM_RATE_24MB;
308                         break;
309                         
310                 case 9:
311                         val = IEEE80211_OFDM_RATE_36MB;
312                         break;
313
314                 case 10:
315                         val = IEEE80211_OFDM_RATE_48MB;
316                         break;
317                 
318                 case 11:
319                         val = IEEE80211_OFDM_RATE_54MB;
320                         break;
321
322         }
323
324         return val;
325
326 }
327
328 int is_basicrate(_adapter *padapter, unsigned char rate);
329 int is_basicrate(_adapter *padapter, unsigned char rate)
330 {
331         int i;
332         unsigned char val;
333         struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
334         
335         for(i = 0; i < NumRates; i++)
336         {
337                 val = pmlmeext->basicrate[i];
338
339                 if ((val != 0xff) && (val != 0xfe))
340                 {
341                         if (rate == ratetbl_val_2wifirate(val))
342                         {
343                                 return _TRUE;
344                         }
345                 }
346         }
347         
348         return _FALSE;
349 }
350
351 unsigned int ratetbl2rateset(_adapter *padapter, unsigned char *rateset);
352 unsigned int ratetbl2rateset(_adapter *padapter, unsigned char *rateset)
353 {
354         int i;
355         unsigned char rate;
356         unsigned int    len = 0;
357         struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
358
359         for (i = 0; i < NumRates; i++)
360         {
361                 rate = pmlmeext->datarate[i];
362
363                 switch (rate)
364                 {
365                         case 0xff:
366                                 return len;
367                                 
368                         case 0xfe:
369                                 continue;
370                                 
371                         default:
372                                 rate = ratetbl_val_2wifirate(rate);
373
374                                 if (is_basicrate(padapter, rate) == _TRUE)
375                                 {
376                                         rate |= IEEE80211_BASIC_RATE_MASK;
377                                 }
378                                 
379                                 rateset[len] = rate;
380                                 len++;
381                                 break;
382                 }
383         }
384         return len;
385 }
386
387 void get_rate_set(_adapter *padapter, unsigned char *pbssrate, int *bssrate_len)
388 {
389         unsigned char supportedrates[NumRates];
390
391         _rtw_memset(supportedrates, 0, NumRates);
392         *bssrate_len = ratetbl2rateset(padapter, supportedrates);
393         _rtw_memcpy(pbssrate, supportedrates, *bssrate_len);
394 }
395
396 void UpdateBrateTbl(
397         IN PADAPTER             Adapter,
398         IN u8                   *mBratesOS
399 )
400 {
401         u8      i;
402         u8      rate;
403
404         // 1M, 2M, 5.5M, 11M, 6M, 12M, 24M are mandatory.
405         for(i=0;i<NDIS_802_11_LENGTH_RATES_EX;i++)
406         {
407                 rate = mBratesOS[i] & 0x7f;
408                 switch(rate)
409                 {
410                         case IEEE80211_CCK_RATE_1MB:
411                         case IEEE80211_CCK_RATE_2MB:
412                         case IEEE80211_CCK_RATE_5MB:
413                         case IEEE80211_CCK_RATE_11MB:
414                         case IEEE80211_OFDM_RATE_6MB:
415                         case IEEE80211_OFDM_RATE_12MB:
416                         case IEEE80211_OFDM_RATE_24MB:
417                                 mBratesOS[i] |= IEEE80211_BASIC_RATE_MASK;
418                                 break;
419                 }
420         }
421
422 }
423
424 void UpdateBrateTblForSoftAP(u8 *bssrateset, u32 bssratelen)
425 {
426         u8      i;
427         u8      rate;
428
429         for(i=0;i<bssratelen;i++)
430         {
431                 rate = bssrateset[i] & 0x7f;
432                 switch(rate)
433                 {
434                         case IEEE80211_CCK_RATE_1MB:
435                         case IEEE80211_CCK_RATE_2MB:
436                         case IEEE80211_CCK_RATE_5MB:
437                         case IEEE80211_CCK_RATE_11MB:
438                                 bssrateset[i] |= IEEE80211_BASIC_RATE_MASK;
439                                 break;
440                 }
441         }
442
443 }
444
445 void Save_DM_Func_Flag(_adapter *padapter)
446 {
447         u8      bSaveFlag = _TRUE;
448         rtw_hal_set_hwreg(padapter, HW_VAR_DM_FUNC_OP, (u8 *)(&bSaveFlag));
449 }
450
451 void Restore_DM_Func_Flag(_adapter *padapter)
452 {
453         u8      bSaveFlag = _FALSE;
454         rtw_hal_set_hwreg(padapter, HW_VAR_DM_FUNC_OP, (u8 *)(&bSaveFlag));
455 }
456
457 void Switch_DM_Func(_adapter *padapter, u32 mode, u8 enable)
458 {
459         if(enable == _TRUE)
460                 rtw_hal_set_hwreg(padapter, HW_VAR_DM_FUNC_SET, (u8 *)(&mode));
461         else
462                 rtw_hal_set_hwreg(padapter, HW_VAR_DM_FUNC_CLR, (u8 *)(&mode));
463 }
464
465 static void Set_NETYPE1_MSR(_adapter *padapter, u8 type)
466 {
467         rtw_hal_set_hwreg(padapter, HW_VAR_MEDIA_STATUS1, (u8 *)(&type));
468 }
469
470 static void Set_NETYPE0_MSR(_adapter *padapter, u8 type)
471 {
472         rtw_hal_set_hwreg(padapter, HW_VAR_MEDIA_STATUS, (u8 *)(&type));
473 }
474
475 void Set_MSR(_adapter *padapter, u8 type)
476 {
477 #ifdef CONFIG_CONCURRENT_MODE
478         if(padapter->iface_type == IFACE_PORT1)
479         {
480                 Set_NETYPE1_MSR(padapter, type);
481         }
482         else
483 #endif
484         {
485                 Set_NETYPE0_MSR(padapter, type);
486         }
487 }
488
489 inline u8 rtw_get_oper_ch(_adapter *adapter)
490 {
491         return adapter_to_dvobj(adapter)->oper_channel;
492 }
493
494 inline void rtw_set_oper_ch(_adapter *adapter, u8 ch)
495 {
496         if (adapter_to_dvobj(adapter)->oper_channel != ch)
497                 adapter_to_dvobj(adapter)->on_oper_ch_time = rtw_get_current_time();
498
499         adapter_to_dvobj(adapter)->oper_channel = ch;
500 }
501
502 inline u8 rtw_get_oper_bw(_adapter *adapter)
503 {
504         return adapter_to_dvobj(adapter)->oper_bwmode;
505 }
506
507 inline void rtw_set_oper_bw(_adapter *adapter, u8 bw)
508 {
509         adapter_to_dvobj(adapter)->oper_bwmode = bw;
510 }
511
512 inline u8 rtw_get_oper_choffset(_adapter *adapter)
513 {
514         return adapter_to_dvobj(adapter)->oper_ch_offset;
515 }
516
517 inline void rtw_set_oper_choffset(_adapter *adapter, u8 offset)
518 {
519         adapter_to_dvobj(adapter)->oper_ch_offset = offset;
520 }
521
522 u8 rtw_get_offset_by_ch(u8 channel)
523 {
524         u8 offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE;
525
526         if(channel>=1 && channel<=4)
527         {
528                 offset = HAL_PRIME_CHNL_OFFSET_LOWER;
529         }
530         else if(channel>=5 && channel<=14)
531         {
532                 offset = HAL_PRIME_CHNL_OFFSET_UPPER;                                           
533         }
534         else
535         {
536                 switch(channel)
537                 {
538                         case 36:
539                         case 44:
540                         case 52:
541                         case 60:
542                         case 100:
543                         case 108:
544                         case 116:
545                         case 124:
546                         case 132:
547                         case 149:
548                         case 157:
549                                 offset = HAL_PRIME_CHNL_OFFSET_LOWER;                           
550                                 break;          
551                         case 40:
552                         case 48:
553                         case 56:
554                         case 64:
555                         case 104:
556                         case 112:
557                         case 120:
558                         case 128:
559                         case 136:
560                         case 153:
561                         case 161:                               
562                                 offset = HAL_PRIME_CHNL_OFFSET_UPPER;                           
563                                 break;                          
564                         default:
565                                 offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE;
566                                 break;
567                 }
568
569         }
570
571         return offset;
572                 
573 }
574
575 u8      rtw_get_center_ch(u8 channel, u8 chnl_bw, u8 chnl_offset)
576 {
577         u8      center_ch = channel;
578
579         if(chnl_bw == CHANNEL_WIDTH_80)
580         {
581                 if((channel == 36) || (channel == 40) || (channel == 44) || (channel == 48) )
582                         center_ch = 42;
583                 if((channel == 52) || (channel == 56) || (channel == 60) || (channel == 64) )
584                         center_ch = 58;
585                 if((channel == 100) || (channel == 104) || (channel == 108) || (channel == 112) )
586                         center_ch = 106;
587                 if((channel == 116) || (channel == 120) || (channel == 124) || (channel == 128) )
588                         center_ch = 122;
589                 if((channel == 132) || (channel == 136) || (channel == 140) || (channel == 144) )
590                         center_ch = 138;
591                 if((channel == 149) || (channel == 153) || (channel == 157) || (channel == 161) )
592                         center_ch = 155;
593                 else if(channel <= 14)
594                         center_ch = 7;
595         }
596         else if(chnl_bw == CHANNEL_WIDTH_40)
597         {
598                 if (chnl_offset == HAL_PRIME_CHNL_OFFSET_LOWER)
599                         center_ch = channel + 2;
600                 else
601                         center_ch = channel - 2;
602         }
603
604         return center_ch;
605 }
606
607 inline u32 rtw_get_on_oper_ch_time(_adapter *adapter)
608 {
609         return adapter_to_dvobj(adapter)->on_oper_ch_time;
610 }
611
612 inline u32 rtw_get_on_cur_ch_time(_adapter *adapter)
613 {
614         if (adapter->mlmeextpriv.cur_channel == adapter_to_dvobj(adapter)->oper_channel)
615                 return adapter_to_dvobj(adapter)->on_oper_ch_time;
616         else
617                 return 0;
618 }
619
620 void SelectChannel(_adapter *padapter, unsigned char channel)
621 {
622         struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;        
623
624 #ifdef CONFIG_DUALMAC_CONCURRENT
625         //saved channel info
626         rtw_set_oper_ch(padapter, channel);
627         dc_SelectChannel(padapter, channel);
628 #else //CONFIG_DUALMAC_CONCURRENT
629
630         _enter_critical_mutex(&(adapter_to_dvobj(padapter)->setch_mutex), NULL);
631         
632         //saved channel info
633         rtw_set_oper_ch(padapter, channel);
634
635         rtw_hal_set_chan(padapter, channel);
636         
637         _exit_critical_mutex(&(adapter_to_dvobj(padapter)->setch_mutex), NULL);
638                 
639 #endif // CONFIG_DUALMAC_CONCURRENT
640 }
641
642 void SetBWMode(_adapter *padapter, unsigned short bwmode, unsigned char channel_offset)
643 {
644         struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
645
646 #ifdef CONFIG_DUALMAC_CONCURRENT
647         //saved bw info
648         rtw_set_oper_bw(padapter, bwmode);
649         rtw_set_oper_choffset(padapter, channel_offset);
650         dc_SetBWMode(padapter, bwmode, channel_offset);
651 #else //CONFIG_DUALMAC_CONCURRENT
652
653         _enter_critical_mutex(&(adapter_to_dvobj(padapter)->setbw_mutex), NULL);
654
655         //saved bw info
656         rtw_set_oper_bw(padapter, bwmode);
657         rtw_set_oper_choffset(padapter, channel_offset);
658
659         rtw_hal_set_bwmode(padapter, (CHANNEL_WIDTH)bwmode, channel_offset);
660
661         _exit_critical_mutex(&(adapter_to_dvobj(padapter)->setbw_mutex), NULL);
662
663 #endif // CONFIG_DUALMAC_CONCURRENT
664 }
665
666 void set_channel_bwmode(_adapter *padapter, unsigned char channel, unsigned char channel_offset, unsigned short bwmode)
667 {
668         u8 center_ch, chnl_offset80 = HAL_PRIME_CHNL_OFFSET_DONT_CARE;
669         struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
670
671         if ( padapter->bNotifyChannelChange )
672         {
673                 DBG_871X( "[%s] ch = %d, offset = %d, bwmode = %d\n", __FUNCTION__, channel, channel_offset, bwmode );
674         }
675
676         center_ch = rtw_get_center_ch(channel, bwmode, channel_offset);
677
678         if(bwmode == CHANNEL_WIDTH_80)
679         {
680                 if(center_ch > channel)
681                         chnl_offset80 = HAL_PRIME_CHNL_OFFSET_LOWER;
682                 else if(center_ch < channel)
683                         chnl_offset80 = HAL_PRIME_CHNL_OFFSET_UPPER;
684                 else
685                         chnl_offset80 = HAL_PRIME_CHNL_OFFSET_DONT_CARE;
686         }
687
688         //set Channel
689 #ifdef CONFIG_DUALMAC_CONCURRENT
690         //saved channel/bw info
691         rtw_set_oper_ch(padapter, channel);
692         rtw_set_oper_bw(padapter, bwmode);
693         rtw_set_oper_choffset(padapter, channel_offset);
694         SelectChannel(padapter, channel);
695         SetBWMode(padapter, bwmode, channel_offset);
696 #else //CONFIG_DUALMAC_CONCURRENT
697         
698         _enter_critical_mutex(&(adapter_to_dvobj(padapter)->setch_mutex), NULL);
699
700         //saved channel/bw info
701         rtw_set_oper_ch(padapter, channel);
702         rtw_set_oper_bw(padapter, bwmode);
703         rtw_set_oper_choffset(padapter, channel_offset);
704
705         rtw_hal_set_chnl_bw(padapter, center_ch, bwmode, channel_offset, chnl_offset80); // set center channel
706
707         _exit_critical_mutex(&(adapter_to_dvobj(padapter)->setch_mutex), NULL);
708
709 #endif // CONFIG_DUALMAC_CONCURRENT
710 }
711
712 int get_bsstype(unsigned short capability)
713 {
714         if (capability & BIT(0))
715         {
716                 return WIFI_FW_AP_STATE;
717         }
718         else if (capability & BIT(1))
719         {
720                 return WIFI_FW_ADHOC_STATE;
721         }
722         else
723         {
724                 return 0;               
725         }
726 }
727
728 __inline u8 *get_my_bssid(WLAN_BSSID_EX *pnetwork)
729 {       
730         return (pnetwork->MacAddress); 
731 }
732
733 u16 get_beacon_interval(WLAN_BSSID_EX *bss)
734 {
735         unsigned short val;
736         _rtw_memcpy((unsigned char *)&val, rtw_get_beacon_interval_from_ie(bss->IEs), 2);
737
738         return le16_to_cpu(val);        
739
740 }
741
742 int is_client_associated_to_ap(_adapter *padapter)
743 {
744         struct mlme_ext_priv    *pmlmeext;
745         struct mlme_ext_info    *pmlmeinfo;
746
747         if(!padapter)
748                 return _FAIL;
749
750         pmlmeext = &padapter->mlmeextpriv;
751         pmlmeinfo = &(pmlmeext->mlmext_info);
752         
753         if ((pmlmeinfo->state & WIFI_FW_ASSOC_SUCCESS) && ((pmlmeinfo->state&0x03) == WIFI_FW_STATION_STATE))
754         {
755                 return _TRUE;
756         }
757         else
758         {
759                 return _FAIL;
760         }
761 }
762
763 int is_client_associated_to_ibss(_adapter *padapter)
764 {
765         struct mlme_ext_priv    *pmlmeext = &padapter->mlmeextpriv;
766         struct mlme_ext_info    *pmlmeinfo = &(pmlmeext->mlmext_info);
767         
768         if ((pmlmeinfo->state & WIFI_FW_ASSOC_SUCCESS) && ((pmlmeinfo->state&0x03) == WIFI_FW_ADHOC_STATE))
769         {
770                 return _TRUE;
771         }
772         else
773         {
774                 return _FAIL;
775         }
776 }
777
778 int is_IBSS_empty(_adapter *padapter)
779 {
780         unsigned int i;
781         struct mlme_ext_priv    *pmlmeext = &padapter->mlmeextpriv;
782         struct mlme_ext_info    *pmlmeinfo = &(pmlmeext->mlmext_info);
783         
784         for (i = IBSS_START_MAC_ID; i < NUM_STA; i++)
785         {
786                 if (pmlmeinfo->FW_sta_info[i].status == 1)
787                 {
788                         return _FAIL;
789                 }
790         }
791         
792         return _TRUE;
793         
794 }
795
796 unsigned int decide_wait_for_beacon_timeout(unsigned int bcn_interval)
797 {
798         if ((bcn_interval << 2) < WAIT_FOR_BCN_TO_MIN)
799         {
800                 return WAIT_FOR_BCN_TO_MIN;
801         } 
802         else if ((bcn_interval << 2) > WAIT_FOR_BCN_TO_MAX)
803         {
804                 return WAIT_FOR_BCN_TO_MAX;
805         }       
806         else
807         {
808                 return ((bcn_interval << 2));
809         }
810 }
811
812 void CAM_empty_entry(
813         PADAPTER        Adapter,        
814         u8                      ucIndex
815 )
816 {
817         rtw_hal_set_hwreg(Adapter, HW_VAR_CAM_EMPTY_ENTRY, (u8 *)(&ucIndex));
818 }
819
820 void invalidate_cam_all(_adapter *padapter)
821 {
822         rtw_hal_set_hwreg(padapter, HW_VAR_CAM_INVALID_ALL, 0);
823 }
824 #if 1
825 static u32 _ReadCAM(_adapter *padapter ,u32 addr)
826 {
827         u32 count = 0, cmd;
828         cmd = CAM_POLLINIG |addr ;
829         rtw_write32(padapter, RWCAM, cmd);
830
831         do{
832                 if(0 == (rtw_read32(padapter,REG_CAMCMD) & CAM_POLLINIG)){
833                         break;
834                 }
835         }while(count++ < 100);          
836
837         return rtw_read32(padapter,REG_CAMREAD);        
838 }
839 void read_cam(_adapter *padapter ,u8 entry, u8 *get_key)
840 {
841         u32     j,count = 0, addr, cmd;
842         addr = entry << 3;
843
844         //DBG_8192C("********* DUMP CAM Entry_#%02d***************\n",entry);
845         for (j = 0; j < 6; j++)
846         {       
847                 cmd = _ReadCAM(padapter ,addr+j);
848                 //DBG_8192C("offset:0x%02x => 0x%08x \n",addr+j,cmd);
849                 if(j>1) //get key from cam
850                         _rtw_memcpy(get_key+(j-2)*4, &cmd, 4);
851         }
852         //DBG_8192C("*********************************\n");
853 }
854 #endif
855
856 void write_cam(_adapter *padapter, u8 entry, u16 ctrl, u8 *mac, u8 *key)
857 {
858         unsigned int    i, val, addr;
859         //unsigned int    cmd;
860         int j;
861         u32     cam_val[2];
862
863         addr = entry << 3;
864
865         for (j = 5; j >= 0; j--)
866         {       
867                 switch (j)
868                 {
869                         case 0:
870                                 val = (ctrl | (mac[0] << 16) | (mac[1] << 24) );
871                                 break;
872                                 
873                         case 1:
874                                 val = (mac[2] | ( mac[3] << 8) | (mac[4] << 16) | (mac[5] << 24));
875                                 break;
876                         
877                         default:
878                                 i = (j - 2) << 2;
879                                 val = (key[i] | (key[i+1] << 8) | (key[i+2] << 16) | (key[i+3] << 24));
880                                 break;
881                                 
882                 }
883
884                 cam_val[0] = val;
885                 cam_val[1] = addr + (unsigned int)j;
886
887                 rtw_hal_set_hwreg(padapter, HW_VAR_CAM_WRITE, (u8 *)cam_val);
888                 
889                 //rtw_write32(padapter, WCAMI, val);
890                 
891                 //cmd = CAM_POLLINIG | CAM_WRITE | (addr + j);
892                 //rtw_write32(padapter, RWCAM, cmd);
893                 
894                 //DBG_871X("%s=> cam write: %x, %x\n",__FUNCTION__, cmd, val);
895                 
896         }
897
898 }
899
900 void clear_cam_entry(_adapter *padapter, u8 entry)
901 {       
902 #if 0
903         u32     addr, val=0;
904         u32     cam_val[2];
905
906         addr = entry << 3;
907         
908
909         cam_val[0] = val;
910         cam_val[1] = addr + (unsigned int)0;
911
912         rtw_hal_set_hwreg(padapter, HW_VAR_CAM_WRITE, (u8 *)cam_val);
913
914
915
916         cam_val[0] = val;
917         cam_val[1] = addr + (unsigned int)1;
918
919         rtw_hal_set_hwreg(padapter, HW_VAR_CAM_WRITE, (u8 *)cam_val);
920 #else
921
922         unsigned char null_sta[] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
923
924         unsigned char null_key[] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,0x00, 0x00, 0x00, 0x00,0x00, 0x00, 0x00, 0x00};
925
926         write_cam(padapter, entry, 0, null_sta, null_key);
927
928 #endif
929 }
930
931 int allocate_fw_sta_entry(_adapter *padapter)
932 {
933         unsigned int mac_id;
934         struct mlme_ext_priv    *pmlmeext = &padapter->mlmeextpriv;
935         struct mlme_ext_info    *pmlmeinfo = &(pmlmeext->mlmext_info);
936         
937         for (mac_id = IBSS_START_MAC_ID; mac_id < NUM_STA; mac_id++)
938         {
939                 if (pmlmeinfo->FW_sta_info[mac_id].status == 0)
940                 {
941                         pmlmeinfo->FW_sta_info[mac_id].status = 1;
942                         pmlmeinfo->FW_sta_info[mac_id].retry = 0;
943                         break;
944                 }
945         }
946         
947         return mac_id;
948 }
949
950 void flush_all_cam_entry(_adapter *padapter)
951 {
952         struct mlme_ext_priv    *pmlmeext = &padapter->mlmeextpriv;
953         struct mlme_ext_info    *pmlmeinfo = &(pmlmeext->mlmext_info);
954
955 #ifdef CONFIG_CONCURRENT_MODE
956
957         struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
958
959         //if(check_buddy_mlmeinfo_state(padapter, _HW_STATE_NOLINK_))   
960         if(check_buddy_fwstate(padapter, _FW_LINKED) == _FALSE)
961         {
962                 rtw_hal_set_hwreg(padapter, HW_VAR_CAM_INVALID_ALL, 0);         
963         }
964         else
965         {
966                 if(check_fwstate(pmlmepriv, WIFI_STATION_STATE))
967                 {
968                         struct sta_priv *pstapriv = &padapter->stapriv;
969                         struct sta_info *psta;
970                         u8 cam_id;//cam_entry
971
972                         psta = rtw_get_stainfo(pstapriv, pmlmeinfo->network.MacAddress);
973                         if(psta) {
974                                 if(psta->state & WIFI_AP_STATE)
975                                 {}   //clear cam when ap free per sta_info        
976                                 else {
977
978                                         cam_id = (u8)rtw_get_camid(psta->mac_id);
979
980                                         //clear_cam_entry(padapter, cam_id);
981                                         rtw_clearstakey_cmd(padapter, (u8*)psta, cam_id, _FALSE);
982                                 }                               
983                         }
984                 }
985                 else if(check_fwstate(pmlmepriv, WIFI_AP_STATE) == _TRUE)
986                 {
987                         //clear cam when ap free per sta_info 
988                 }                       
989         }
990 #else //CONFIG_CONCURRENT_MODE
991
992         rtw_hal_set_hwreg(padapter, HW_VAR_CAM_INVALID_ALL, 0); 
993
994 #endif //CONFIG_CONCURRENT_MODE
995
996         _rtw_memset((u8 *)(pmlmeinfo->FW_sta_info), 0, sizeof(pmlmeinfo->FW_sta_info));
997         
998 }
999
1000 #if defined(CONFIG_P2P) && defined(CONFIG_WFD)
1001 int WFD_info_handler(_adapter *padapter, PNDIS_802_11_VARIABLE_IEs      pIE)
1002 {
1003         struct registry_priv    *pregpriv = &padapter->registrypriv;
1004         struct mlme_priv        *pmlmepriv = &(padapter->mlmepriv);
1005         struct mlme_ext_priv    *pmlmeext = &padapter->mlmeextpriv;
1006         struct mlme_ext_info    *pmlmeinfo = &(pmlmeext->mlmext_info);
1007         struct wifidirect_info  *pwdinfo;       
1008         u8      wfd_ie[ 128 ] = { 0x00 };
1009         u32     wfd_ielen = 0;
1010
1011
1012         pwdinfo = &padapter->wdinfo;
1013         if ( rtw_get_wfd_ie( ( u8* ) pIE, pIE->Length, wfd_ie, &wfd_ielen ) )
1014         {
1015                 u8      attr_content[ 10 ] = { 0x00 };
1016                 u32     attr_contentlen = 0;
1017                         
1018                 DBG_871X( "[%s] Found WFD IE\n", __FUNCTION__ );
1019                 rtw_get_wfd_attr_content( wfd_ie, wfd_ielen, WFD_ATTR_DEVICE_INFO, attr_content, &attr_contentlen);
1020                 if ( attr_contentlen )
1021                 {
1022                         pwdinfo->wfd_info->peer_rtsp_ctrlport = RTW_GET_BE16( attr_content + 2 );
1023                         DBG_8192C( "[%s] Peer PORT NUM = %d\n", __FUNCTION__, pwdinfo->wfd_info->peer_rtsp_ctrlport );
1024                         return( _TRUE );
1025                 }               
1026         }
1027         else
1028         {
1029                 DBG_871X( "[%s] NO WFD IE\n", __FUNCTION__ );
1030
1031         }
1032         return( _FAIL );
1033 }
1034 #endif
1035
1036 int WMM_param_handler(_adapter *padapter, PNDIS_802_11_VARIABLE_IEs     pIE)
1037 {
1038         //struct registry_priv  *pregpriv = &padapter->registrypriv;
1039         struct mlme_priv        *pmlmepriv = &(padapter->mlmepriv);
1040         struct mlme_ext_priv    *pmlmeext = &padapter->mlmeextpriv;
1041         struct mlme_ext_info    *pmlmeinfo = &(pmlmeext->mlmext_info);  
1042         
1043         if(pmlmepriv->qospriv.qos_option==0)
1044         {
1045                 pmlmeinfo->WMM_enable = 0;
1046                 return _FAIL;
1047         }       
1048
1049         pmlmeinfo->WMM_enable = 1;
1050         _rtw_memcpy(&(pmlmeinfo->WMM_param), (pIE->data + 6), sizeof(struct WMM_para_element));
1051         return _TRUE;
1052
1053         /*if (pregpriv->wifi_spec == 1)
1054         {
1055                 if (pmlmeinfo->WMM_enable == 1)
1056                 {
1057                         //todo: compare the parameter set count & decide wheher to update or not
1058                         return _FAIL;
1059                 }
1060                 else
1061                 {
1062                         pmlmeinfo->WMM_enable = 1;
1063                         _rtw_rtw_memcpy(&(pmlmeinfo->WMM_param), (pIE->data + 6), sizeof(struct WMM_para_element));
1064                         return _TRUE;
1065                 }
1066         }
1067         else
1068         {
1069                 pmlmeinfo->WMM_enable = 0;
1070                 return _FAIL;
1071         }*/
1072         
1073 }
1074
1075 void WMMOnAssocRsp(_adapter *padapter)
1076 {
1077         u8      ACI, ACM, AIFS, ECWMin, ECWMax, aSifsTime;
1078         u8      acm_mask;
1079         u16     TXOP;
1080         u32     acParm, i;
1081         u32     edca[4], inx[4];
1082         struct mlme_ext_priv    *pmlmeext = &padapter->mlmeextpriv;
1083         struct mlme_ext_info    *pmlmeinfo = &(pmlmeext->mlmext_info);
1084         struct xmit_priv                *pxmitpriv = &padapter->xmitpriv;
1085         struct registry_priv    *pregpriv = &padapter->registrypriv;
1086
1087         acm_mask = 0;
1088
1089         if (IsSupported5G(pmlmeext->cur_wireless_mode) || 
1090                 (pmlmeext->cur_wireless_mode & WIRELESS_11_24N) )
1091                 aSifsTime = 16;
1092         else
1093                 aSifsTime = 10;
1094
1095         if (pmlmeinfo->WMM_enable == 0)
1096         {
1097                 padapter->mlmepriv.acm_mask = 0;
1098
1099                 AIFS = aSifsTime + (2 * pmlmeinfo->slotTime);
1100
1101                 if (pmlmeext->cur_wireless_mode & (WIRELESS_11G |WIRELESS_11A)) {
1102                         ECWMin = 4;
1103                         ECWMax = 10;
1104                 } else if (pmlmeext->cur_wireless_mode & WIRELESS_11B) {
1105                         ECWMin = 5;
1106                         ECWMax = 10;
1107                 } else {
1108                         ECWMin = 4;
1109                         ECWMax = 10;
1110                 }
1111
1112                 TXOP = 0;
1113                 acParm = AIFS | (ECWMin << 8) | (ECWMax << 12) | (TXOP << 16);
1114                 rtw_hal_set_hwreg(padapter, HW_VAR_AC_PARAM_BE, (u8 *)(&acParm));
1115                 rtw_hal_set_hwreg(padapter, HW_VAR_AC_PARAM_BK, (u8 *)(&acParm));
1116                 rtw_hal_set_hwreg(padapter, HW_VAR_AC_PARAM_VI, (u8 *)(&acParm));
1117
1118                 ECWMin = 2;
1119                 ECWMax = 3;
1120                 TXOP = 0x2f;
1121                 acParm = AIFS | (ECWMin << 8) | (ECWMax << 12) | (TXOP << 16);
1122                 rtw_hal_set_hwreg(padapter, HW_VAR_AC_PARAM_VO, (u8 *)(&acParm));
1123         }
1124         else
1125         {
1126                 edca[0] = edca[1] = edca[2] = edca[3] = 0;
1127
1128                 for (i = 0; i < 4; i++)  
1129                 {
1130                         ACI = (pmlmeinfo->WMM_param.ac_param[i].ACI_AIFSN >> 5) & 0x03;
1131                         ACM = (pmlmeinfo->WMM_param.ac_param[i].ACI_AIFSN >> 4) & 0x01;
1132
1133                         //AIFS = AIFSN * slot time + SIFS - r2t phy delay
1134                         AIFS = (pmlmeinfo->WMM_param.ac_param[i].ACI_AIFSN & 0x0f) * pmlmeinfo->slotTime + aSifsTime;
1135
1136                         ECWMin = (pmlmeinfo->WMM_param.ac_param[i].CW & 0x0f);
1137                         ECWMax = (pmlmeinfo->WMM_param.ac_param[i].CW & 0xf0) >> 4;
1138                         TXOP = le16_to_cpu(pmlmeinfo->WMM_param.ac_param[i].TXOP_limit);
1139
1140                         acParm = AIFS | (ECWMin << 8) | (ECWMax << 12) | (TXOP << 16);
1141
1142                         switch (ACI)
1143                         {
1144                                 case 0x0:
1145                                         rtw_hal_set_hwreg(padapter, HW_VAR_AC_PARAM_BE, (u8 *)(&acParm));
1146                                         acm_mask |= (ACM? BIT(1):0);
1147                                         edca[XMIT_BE_QUEUE] = acParm;
1148                                         break;
1149
1150                                 case 0x1:
1151                                         rtw_hal_set_hwreg(padapter, HW_VAR_AC_PARAM_BK, (u8 *)(&acParm));
1152                                         //acm_mask |= (ACM? BIT(0):0);
1153                                         edca[XMIT_BK_QUEUE] = acParm;
1154                                         break;
1155
1156                                 case 0x2:
1157                                         rtw_hal_set_hwreg(padapter, HW_VAR_AC_PARAM_VI, (u8 *)(&acParm));
1158                                         acm_mask |= (ACM? BIT(2):0);
1159                                         edca[XMIT_VI_QUEUE] = acParm;
1160                                         break;
1161
1162                                 case 0x3:
1163                                         rtw_hal_set_hwreg(padapter, HW_VAR_AC_PARAM_VO, (u8 *)(&acParm));
1164                                         acm_mask |= (ACM? BIT(3):0);
1165                                         edca[XMIT_VO_QUEUE] = acParm;
1166                                         break;                                                  
1167                         }
1168
1169                         DBG_871X("WMM(%x): %x, %x\n", ACI, ACM, acParm);
1170                 }
1171
1172                 if(padapter->registrypriv.acm_method == 1)
1173                         rtw_hal_set_hwreg(padapter, HW_VAR_ACM_CTRL, (u8 *)(&acm_mask));
1174                 else
1175                         padapter->mlmepriv.acm_mask = acm_mask;
1176
1177                 inx[0] = 0; inx[1] = 1; inx[2] = 2; inx[3] = 3;
1178
1179                 if(pregpriv->wifi_spec==1)
1180                 {
1181                         u32     j, tmp, change_inx=_FALSE;
1182
1183                         //entry indx: 0->vo, 1->vi, 2->be, 3->bk.
1184                         for(i=0; i<4; i++)
1185                         {
1186                                 for(j=i+1; j<4; j++)
1187                                 {
1188                                         //compare CW and AIFS
1189                                         if((edca[j] & 0xFFFF) < (edca[i] & 0xFFFF))
1190                                         {
1191                                                 change_inx = _TRUE;
1192                                         }
1193                                         else if((edca[j] & 0xFFFF) == (edca[i] & 0xFFFF))
1194                                         {
1195                                                 //compare TXOP
1196                                                 if((edca[j] >> 16) > (edca[i] >> 16))
1197                                                         change_inx = _TRUE;
1198                                         }
1199                                 
1200                                         if(change_inx)
1201                                         {
1202                                                 tmp = edca[i];
1203                                                 edca[i] = edca[j];
1204                                                 edca[j] = tmp;
1205
1206                                                 tmp = inx[i];
1207                                                 inx[i] = inx[j];
1208                                                 inx[j] = tmp;
1209
1210                                                 change_inx = _FALSE;
1211                                         }
1212                                 }
1213                         }
1214                 }
1215
1216                 for(i=0; i<4; i++) {
1217                         pxmitpriv->wmm_para_seq[i] = inx[i];
1218                         DBG_871X("wmm_para_seq(%d): %d\n", i, pxmitpriv->wmm_para_seq[i]);
1219                 }
1220         }
1221 }
1222
1223 static void bwmode_update_check(_adapter *padapter, PNDIS_802_11_VARIABLE_IEs pIE)
1224 {
1225 #ifdef CONFIG_80211N_HT
1226         unsigned char    new_bwmode;
1227         unsigned char  new_ch_offset;
1228         struct HT_info_element   *pHT_info;
1229         struct mlme_priv        *pmlmepriv = &(padapter->mlmepriv);
1230         struct mlme_ext_priv    *pmlmeext = &padapter->mlmeextpriv;
1231         struct mlme_ext_info    *pmlmeinfo = &(pmlmeext->mlmext_info);
1232         struct registry_priv *pregistrypriv = &padapter->registrypriv;
1233         struct ht_priv                  *phtpriv = &pmlmepriv->htpriv;
1234         u8      cbw40_enable=0;
1235
1236         if(!pIE)
1237                 return;
1238
1239         if(phtpriv->ht_option == _FALSE)        return;
1240
1241         if(pmlmeext->cur_bwmode >= CHANNEL_WIDTH_80)    return;
1242
1243         if(pIE->Length > sizeof(struct HT_info_element))
1244                 return;
1245         
1246         pHT_info = (struct HT_info_element *)pIE->data;
1247
1248         if (pmlmeext->cur_channel > 14) {
1249                 if ((pregistrypriv->bw_mode & 0xf0) > 0)
1250                         cbw40_enable = 1;
1251         } else {
1252                 if ((pregistrypriv->bw_mode & 0x0f) > 0)
1253                         cbw40_enable = 1;
1254         }
1255
1256         if((pHT_info->infos[0] & BIT(2)) && cbw40_enable)
1257         {
1258                 new_bwmode = CHANNEL_WIDTH_40;
1259
1260                 switch (pHT_info->infos[0] & 0x3)
1261                 {
1262                         case 1:
1263                                 new_ch_offset = HAL_PRIME_CHNL_OFFSET_LOWER;
1264                                 break;
1265                         
1266                         case 3:
1267                                 new_ch_offset = HAL_PRIME_CHNL_OFFSET_UPPER;
1268                                 break;
1269                                 
1270                         default:
1271                                 new_bwmode = CHANNEL_WIDTH_20;
1272                                 new_ch_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE;
1273                                 break;
1274                 }
1275         }
1276         else
1277         {
1278                 new_bwmode = CHANNEL_WIDTH_20;
1279                 new_ch_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE;
1280         }       
1281
1282         
1283         if((new_bwmode!= pmlmeext->cur_bwmode) || (new_ch_offset!=pmlmeext->cur_ch_offset))
1284         {
1285                 pmlmeinfo->bwmode_updated = _TRUE;
1286                 
1287                 pmlmeext->cur_bwmode = new_bwmode;
1288                 pmlmeext->cur_ch_offset = new_ch_offset;
1289
1290                 //update HT info also
1291                 HT_info_handler(padapter, pIE);
1292         }
1293         else
1294         {
1295                 pmlmeinfo->bwmode_updated = _FALSE;
1296         }
1297                 
1298
1299         if(_TRUE == pmlmeinfo->bwmode_updated)
1300         {
1301                 struct sta_info *psta;
1302                 WLAN_BSSID_EX   *cur_network = &(pmlmeinfo->network);
1303                 struct sta_priv *pstapriv = &padapter->stapriv;
1304         
1305                 //set_channel_bwmode(padapter, pmlmeext->cur_channel, pmlmeext->cur_ch_offset, pmlmeext->cur_bwmode);
1306
1307                 
1308                 //update ap's stainfo
1309                 psta = rtw_get_stainfo(pstapriv, cur_network->MacAddress);
1310                 if(psta)
1311                 {
1312                         struct ht_priv  *phtpriv_sta = &psta->htpriv;
1313                         
1314                         if(phtpriv_sta->ht_option)
1315                         {                               
1316                                 // bwmode                               
1317                                 psta->bw_mode = pmlmeext->cur_bwmode;
1318                                 phtpriv_sta->ch_offset = pmlmeext->cur_ch_offset;               
1319                         }
1320                         else
1321                         {
1322                                 psta->bw_mode = CHANNEL_WIDTH_20;
1323                                 phtpriv_sta->ch_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE;
1324                         }
1325                         
1326                 }
1327
1328                 //pmlmeinfo->bwmode_updated = _FALSE;//bwmode_updated done, reset it!
1329
1330                 rtw_dm_ra_mask_wk_cmd(padapter);
1331         }       
1332 #endif //CONFIG_80211N_HT
1333 }
1334
1335 void HT_caps_handler(_adapter *padapter, PNDIS_802_11_VARIABLE_IEs pIE)
1336 {
1337 #ifdef CONFIG_80211N_HT
1338         unsigned int    i;
1339         u8      rf_type;
1340         u8      max_AMPDU_len, min_MPDU_spacing;
1341         struct mlme_ext_priv    *pmlmeext = &padapter->mlmeextpriv;
1342         struct mlme_ext_info    *pmlmeinfo = &(pmlmeext->mlmext_info);
1343         struct mlme_priv                *pmlmepriv = &padapter->mlmepriv;       
1344         struct ht_priv                  *phtpriv = &pmlmepriv->htpriv;
1345         struct registry_priv    *pregistrypriv = &padapter->registrypriv;
1346         
1347         if(pIE==NULL) return;
1348         
1349         if(phtpriv->ht_option == _FALSE)        return;
1350
1351         pmlmeinfo->HT_caps_enable = 1;
1352         
1353         for (i = 0; i < (pIE->Length); i++)
1354         {
1355                 if (i != 2)
1356                 {
1357                         //      Commented by Albert 2010/07/12
1358                         //      Got the endian issue here.
1359                         pmlmeinfo->HT_caps.u.HT_cap[i] &= (pIE->data[i]);
1360                 }
1361                 else
1362                 {
1363                         //modify from  fw by Thomas 2010/11/17
1364                         if ((pmlmeinfo->HT_caps.u.HT_cap_element.AMPDU_para & 0x3) > (pIE->data[i] & 0x3))
1365                         {
1366                                 max_AMPDU_len = (pIE->data[i] & 0x3);
1367                         }
1368                         else
1369                         {
1370                                 max_AMPDU_len = (pmlmeinfo->HT_caps.u.HT_cap_element.AMPDU_para & 0x3);
1371                         }
1372                         
1373                         if ((pmlmeinfo->HT_caps.u.HT_cap_element.AMPDU_para & 0x1c) > (pIE->data[i] & 0x1c))
1374                         {
1375                                 min_MPDU_spacing = (pmlmeinfo->HT_caps.u.HT_cap_element.AMPDU_para & 0x1c);
1376                         }
1377                         else
1378                         {
1379                                 min_MPDU_spacing = (pIE->data[i] & 0x1c);
1380                         }
1381
1382                         pmlmeinfo->HT_caps.u.HT_cap_element.AMPDU_para = max_AMPDU_len | min_MPDU_spacing;
1383                 }
1384         }
1385
1386         //      Commented by Albert 2010/07/12
1387         //      Have to handle the endian issue after copying.
1388         //      HT_ext_caps didn't be used yet. 
1389         pmlmeinfo->HT_caps.u.HT_cap_element.HT_caps_info = le16_to_cpu( pmlmeinfo->HT_caps.u.HT_cap_element.HT_caps_info );
1390         pmlmeinfo->HT_caps.u.HT_cap_element.HT_ext_caps = le16_to_cpu( pmlmeinfo->HT_caps.u.HT_cap_element.HT_ext_caps );
1391
1392         rtw_hal_get_hwreg(padapter, HW_VAR_RF_TYPE, (u8 *)(&rf_type));
1393
1394         //update the MCS rates
1395         for (i = 0; i < 16; i++)
1396         {
1397                 if((rf_type == RF_1T1R) || (rf_type == RF_1T2R))
1398                 {
1399                         pmlmeinfo->HT_caps.u.HT_cap_element.MCS_rate[i] &= MCS_rate_1R[i];
1400                 }
1401                 else
1402                 {
1403                         #ifdef CONFIG_DISABLE_MCS13TO15
1404                         if(pmlmeext->cur_bwmode == CHANNEL_WIDTH_40 && (pregistrypriv->wifi_spec!=1))
1405                                 pmlmeinfo->HT_caps.u.HT_cap_element.MCS_rate[i] &= MCS_rate_2R_MCS13TO15_OFF[i];
1406                         else
1407                         pmlmeinfo->HT_caps.u.HT_cap_element.MCS_rate[i] &= MCS_rate_2R[i];
1408                         #else
1409                         pmlmeinfo->HT_caps.u.HT_cap_element.MCS_rate[i] &= MCS_rate_2R[i];
1410                         #endif //CONFIG_DISABLE_MCS13TO15
1411                 }
1412                 #ifdef RTL8192C_RECONFIG_TO_1T1R
1413                 {
1414                         pmlmeinfo->HT_caps.HT_cap_element.MCS_rate[i] &= MCS_rate_1R[i];
1415                 }
1416                 #endif
1417         }
1418 #endif //CONFIG_80211N_HT
1419         return;
1420 }
1421
1422 void HT_info_handler(_adapter *padapter, PNDIS_802_11_VARIABLE_IEs pIE)
1423 {
1424 #ifdef CONFIG_80211N_HT
1425         struct mlme_ext_priv    *pmlmeext = &padapter->mlmeextpriv;
1426         struct mlme_ext_info    *pmlmeinfo = &(pmlmeext->mlmext_info);
1427         struct mlme_priv                *pmlmepriv = &padapter->mlmepriv;       
1428         struct ht_priv                  *phtpriv = &pmlmepriv->htpriv;
1429
1430         if(pIE==NULL) return;
1431
1432         if(phtpriv->ht_option == _FALSE)        return;
1433
1434
1435         if(pIE->Length > sizeof(struct HT_info_element))
1436                 return;
1437         
1438         pmlmeinfo->HT_info_enable = 1;
1439         _rtw_memcpy(&(pmlmeinfo->HT_info), pIE->data, pIE->Length);
1440 #endif //CONFIG_80211N_HT
1441         return;
1442 }
1443
1444 void HTOnAssocRsp(_adapter *padapter)
1445 {
1446         unsigned char           max_AMPDU_len;
1447         unsigned char           min_MPDU_spacing;
1448         //struct registry_priv   *pregpriv = &padapter->registrypriv;
1449         struct mlme_ext_priv    *pmlmeext = &padapter->mlmeextpriv;
1450         struct mlme_ext_info    *pmlmeinfo = &(pmlmeext->mlmext_info);
1451         
1452         DBG_871X("%s\n", __FUNCTION__);
1453
1454         if ((pmlmeinfo->HT_info_enable) && (pmlmeinfo->HT_caps_enable))
1455         {
1456                 pmlmeinfo->HT_enable = 1;
1457         }
1458         else
1459         {
1460                 pmlmeinfo->HT_enable = 0;
1461                 //set_channel_bwmode(padapter, pmlmeext->cur_channel, pmlmeext->cur_ch_offset, pmlmeext->cur_bwmode);
1462                 return;
1463         }
1464         
1465         //handle A-MPDU parameter field
1466         /*      
1467                 AMPDU_para [1:0]:Max AMPDU Len => 0:8k , 1:16k, 2:32k, 3:64k
1468                 AMPDU_para [4:2]:Min MPDU Start Spacing 
1469         */
1470         max_AMPDU_len = pmlmeinfo->HT_caps.u.HT_cap_element.AMPDU_para & 0x03;  
1471         
1472         min_MPDU_spacing = (pmlmeinfo->HT_caps.u.HT_cap_element.AMPDU_para & 0x1c) >> 2;        
1473
1474         rtw_hal_set_hwreg(padapter, HW_VAR_AMPDU_MIN_SPACE, (u8 *)(&min_MPDU_spacing));
1475
1476         rtw_hal_set_hwreg(padapter, HW_VAR_AMPDU_FACTOR, (u8 *)(&max_AMPDU_len));
1477
1478 #if 0 //move to rtw_update_ht_cap()
1479         if ((pregpriv->bw_mode > 0) &&
1480                 (pmlmeinfo->HT_caps.u.HT_cap_element.HT_caps_info & BIT(1)) && 
1481                 (pmlmeinfo->HT_info.infos[0] & BIT(2)))
1482         {
1483                 //switch to the 40M Hz mode accoring to the AP
1484                 pmlmeext->cur_bwmode = CHANNEL_WIDTH_40;
1485                 switch ((pmlmeinfo->HT_info.infos[0] & 0x3))
1486                 {
1487                         case EXTCHNL_OFFSET_UPPER:
1488                                 pmlmeext->cur_ch_offset = HAL_PRIME_CHNL_OFFSET_LOWER;
1489                                 break;
1490                         
1491                         case EXTCHNL_OFFSET_LOWER:
1492                                 pmlmeext->cur_ch_offset = HAL_PRIME_CHNL_OFFSET_UPPER;
1493                                 break;
1494                                 
1495                         default:
1496                                 pmlmeext->cur_ch_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE;
1497                                 break;
1498                 }
1499                 
1500                 //SelectChannel(padapter, pmlmeext->cur_channel, pmlmeext->cur_ch_offset);
1501         }
1502 #endif
1503
1504         //set_channel_bwmode(padapter, pmlmeext->cur_channel, pmlmeext->cur_ch_offset, pmlmeext->cur_bwmode);
1505
1506 #if 0 //move to rtw_update_ht_cap()
1507         //
1508         // Config SM Power Save setting
1509         //
1510         pmlmeinfo->SM_PS = (pmlmeinfo->HT_caps.u.HT_cap_element.HT_caps_info & 0x0C) >> 2;
1511         if(pmlmeinfo->SM_PS == WLAN_HT_CAP_SM_PS_STATIC)
1512         {
1513                 /*u8 i;
1514                 //update the MCS rates
1515                 for (i = 0; i < 16; i++)
1516                 {
1517                         pmlmeinfo->HT_caps.HT_cap_element.MCS_rate[i] &= MCS_rate_1R[i];
1518                 }*/
1519                 DBG_871X("%s(): WLAN_HT_CAP_SM_PS_STATIC\n",__FUNCTION__);
1520         }
1521
1522         //
1523         // Config current HT Protection mode.
1524         //
1525         pmlmeinfo->HT_protection = pmlmeinfo->HT_info.infos[1] & 0x3;
1526 #endif
1527         
1528 }
1529
1530 void ERP_IE_handler(_adapter *padapter, PNDIS_802_11_VARIABLE_IEs pIE)
1531 {
1532         struct mlme_ext_priv    *pmlmeext = &padapter->mlmeextpriv;
1533         struct mlme_ext_info    *pmlmeinfo = &(pmlmeext->mlmext_info);
1534
1535         if(pIE->Length>1)
1536                 return;
1537         
1538         pmlmeinfo->ERP_enable = 1;
1539         _rtw_memcpy(&(pmlmeinfo->ERP_IE), pIE->data, pIE->Length);
1540 }
1541
1542 void VCS_update(_adapter *padapter, struct sta_info *psta)
1543 {
1544         struct registry_priv     *pregpriv = &padapter->registrypriv;
1545         struct mlme_ext_priv    *pmlmeext = &padapter->mlmeextpriv;
1546         struct mlme_ext_info    *pmlmeinfo = &(pmlmeext->mlmext_info);
1547
1548         switch (pregpriv->vrtl_carrier_sense)/* 0:off 1:on 2:auto */
1549         {
1550                 case 0: //off
1551                         psta->rtsen = 0;
1552                         psta->cts2self = 0;
1553                         break;
1554                         
1555                 case 1: //on
1556                         if (pregpriv->vcs_type == 1) /* 1:RTS/CTS 2:CTS to self */
1557                         {
1558                                 psta->rtsen = 1;
1559                                 psta->cts2self = 0;
1560                         }
1561                         else
1562                         {
1563                                 psta->rtsen = 0;
1564                                 psta->cts2self = 1;
1565                         }
1566                         break;
1567                         
1568                 case 2: //auto
1569                 default:
1570                         if ((pmlmeinfo->ERP_enable) && (pmlmeinfo->ERP_IE & BIT(1)))
1571                         {
1572                                 if (pregpriv->vcs_type == 1)
1573                                 {
1574                                         psta->rtsen = 1;
1575                                         psta->cts2self = 0;
1576                                 }
1577                                 else
1578                                 {
1579                                         psta->rtsen = 0;
1580                                         psta->cts2self = 1;
1581                                 }
1582                         }
1583                         else
1584                         {
1585                                 psta->rtsen = 0;
1586                                 psta->cts2self = 0;
1587                         }       
1588                         break;
1589         }
1590 }
1591
1592 #ifdef CONFIG_TDLS
1593 int check_ap_tdls_prohibited(u8 *pframe, u8 pkt_len)
1594 {
1595         u8 tdls_prohibited_bit = 0x40; //bit(38); TDLS_prohibited
1596
1597         if(pkt_len < 5)
1598         {
1599                 return _FALSE;
1600         }
1601
1602         pframe += 4;
1603         if( (*pframe) & tdls_prohibited_bit )
1604                 return _TRUE;
1605
1606         return _FALSE;
1607 }
1608 #endif //CONFIG_TDLS
1609
1610 int rtw_check_bcn_info(ADAPTER *Adapter, u8 *pframe, u32 packet_len)
1611 {
1612         unsigned int            len;
1613         unsigned char           *p;
1614         unsigned short  val16, subtype;
1615         struct wlan_network *cur_network = &(Adapter->mlmepriv.cur_network);
1616         //u8 wpa_ie[255],rsn_ie[255];
1617         u16 wpa_len=0,rsn_len=0;
1618         u8 encryp_protocol = 0;
1619         WLAN_BSSID_EX *bssid;
1620         int group_cipher = 0, pairwise_cipher = 0, is_8021x = 0;
1621         unsigned char *pbuf;
1622         u32 wpa_ielen = 0;
1623         u8 *pbssid = GetAddr3Ptr(pframe);
1624         u32 hidden_ssid = 0;
1625         u8 cur_network_type, network_type=0;
1626         struct HT_info_element *pht_info = NULL;
1627         struct rtw_ieee80211_ht_cap *pht_cap = NULL;
1628         u32 bcn_channel;
1629         unsigned short  ht_cap_info;
1630         unsigned char   ht_info_infos_0;
1631
1632         if (is_client_associated_to_ap(Adapter) == _FALSE)
1633                 return _TRUE;
1634
1635         len = packet_len - sizeof(struct rtw_ieee80211_hdr_3addr);
1636
1637         if (len > MAX_IE_SZ) {
1638                 DBG_871X("%s IE too long for survey event\n", __func__);
1639                 return _FAIL;
1640         }
1641
1642         if (_rtw_memcmp(cur_network->network.MacAddress, pbssid, 6) == _FALSE) {
1643                 DBG_871X("Oops: rtw_check_network_encrypt linked but recv other bssid bcn\n" MAC_FMT MAC_FMT,
1644                                 MAC_ARG(pbssid), MAC_ARG(cur_network->network.MacAddress));
1645                 return _TRUE;
1646         }
1647
1648         bssid = (WLAN_BSSID_EX *)rtw_zmalloc(sizeof(WLAN_BSSID_EX));
1649
1650         subtype = GetFrameSubType(pframe) >> 4;
1651
1652         if(subtype==WIFI_BEACON)
1653                 bssid->Reserved[0] = 1;
1654
1655         bssid->Length = sizeof(WLAN_BSSID_EX) - MAX_IE_SZ + len;
1656
1657         /* below is to copy the information element */
1658         bssid->IELength = len;
1659         _rtw_memcpy(bssid->IEs, (pframe + sizeof(struct rtw_ieee80211_hdr_3addr)), bssid->IELength);
1660
1661         /* check bw and channel offset */
1662         /* parsing HT_CAP_IE */
1663         p = rtw_get_ie(bssid->IEs + _FIXED_IE_LENGTH_, _HT_CAPABILITY_IE_, &len, bssid->IELength - _FIXED_IE_LENGTH_);
1664         if(p && len>0) {
1665                         pht_cap = (struct rtw_ieee80211_ht_cap *)(p + 2);
1666                         ht_cap_info = pht_cap->cap_info;
1667         } else {
1668                         ht_cap_info = 0;
1669         }
1670         /* parsing HT_INFO_IE */
1671         p = rtw_get_ie(bssid->IEs + _FIXED_IE_LENGTH_, _HT_ADD_INFO_IE_, &len, bssid->IELength - _FIXED_IE_LENGTH_);
1672         if(p && len>0) {
1673                         pht_info = (struct HT_info_element *)(p + 2);
1674                         ht_info_infos_0 = pht_info->infos[0];
1675         } else {
1676                         ht_info_infos_0 = 0;
1677         }
1678         if (ht_cap_info != cur_network->BcnInfo.ht_cap_info ||
1679                 ((ht_info_infos_0&0x03) != (cur_network->BcnInfo.ht_info_infos_0&0x03))) {
1680                         DBG_871X("%s bcn now: ht_cap_info:%x ht_info_infos_0:%x\n", __func__,
1681                                                         ht_cap_info, ht_info_infos_0);
1682                         DBG_871X("%s bcn link: ht_cap_info:%x ht_info_infos_0:%x\n", __func__,
1683                                                         cur_network->BcnInfo.ht_cap_info, cur_network->BcnInfo.ht_info_infos_0);
1684                         DBG_871X("%s bw mode change, disconnect\n", __func__);
1685                         {       
1686                                 //bcn_info_update
1687                                 cur_network->BcnInfo.ht_cap_info = ht_cap_info;
1688                                 cur_network->BcnInfo.ht_info_infos_0 = ht_info_infos_0;
1689                                 //to do : need to check that whether modify related register of BB or not 
1690                         }
1691                         //goto _mismatch;
1692         }
1693
1694         /* Checking for channel */
1695         p = rtw_get_ie(bssid->IEs + _FIXED_IE_LENGTH_, _DSSET_IE_, &len, bssid->IELength - _FIXED_IE_LENGTH_);
1696         if (p) {
1697                         bcn_channel = *(p + 2);
1698         } else {/* In 5G, some ap do not have DSSET IE checking HT info for channel */
1699                         p = rtw_get_ie(bssid->IEs + _FIXED_IE_LENGTH_, _HT_ADD_INFO_IE_, &len, bssid->IELength - _FIXED_IE_LENGTH_);
1700                         if(pht_info) {
1701                                         bcn_channel = pht_info->primary_channel;
1702                         } else { /* we don't find channel IE, so don't check it */
1703                                         //DBG_871X("Oops: %s we don't find channel IE, so don't check it \n", __func__);
1704                                         bcn_channel = Adapter->mlmeextpriv.cur_channel;
1705                         }
1706         }
1707         if (bcn_channel != Adapter->mlmeextpriv.cur_channel) {
1708                         DBG_871X("%s beacon channel:%d cur channel:%d disconnect\n", __func__,
1709                                                    bcn_channel, Adapter->mlmeextpriv.cur_channel);
1710                         goto _mismatch;
1711         }
1712
1713         /* checking SSID */
1714         if ((p = rtw_get_ie(bssid->IEs + _FIXED_IE_LENGTH_, _SSID_IE_, &len, bssid->IELength - _FIXED_IE_LENGTH_)) == NULL) {
1715                 DBG_871X("%s marc: cannot find SSID for survey event\n", __func__);
1716                 hidden_ssid = _TRUE;
1717         } else {
1718                 hidden_ssid = _FALSE;
1719         }
1720
1721         if((NULL != p) && (_FALSE == hidden_ssid && (*(p + 1)))) {
1722                 _rtw_memcpy(bssid->Ssid.Ssid, (p + 2), *(p + 1));
1723                 bssid->Ssid.SsidLength = *(p + 1);
1724         } else {
1725                 bssid->Ssid.SsidLength = 0;
1726                 bssid->Ssid.Ssid[0] = '\0';
1727         }
1728
1729         RT_TRACE(_module_rtl871x_mlme_c_,_drv_info_,("%s bssid.Ssid.Ssid:%s bssid.Ssid.SsidLength:%d "
1730                                 "cur_network->network.Ssid.Ssid:%s len:%d\n", __func__, bssid->Ssid.Ssid,
1731                                 bssid->Ssid.SsidLength, cur_network->network.Ssid.Ssid,
1732                                 cur_network->network.Ssid.SsidLength));
1733
1734         if (_rtw_memcmp(bssid->Ssid.Ssid, cur_network->network.Ssid.Ssid, 32) == _FALSE ||
1735                         bssid->Ssid.SsidLength != cur_network->network.Ssid.SsidLength) {
1736                 if (bssid->Ssid.Ssid[0] != '\0' && bssid->Ssid.SsidLength != 0) { /* not hidden ssid */
1737                         DBG_871X("%s(), SSID is not match return FAIL\n", __func__);
1738                         goto _mismatch;
1739                 }
1740         }
1741
1742         /* check encryption info */
1743         val16 = rtw_get_capability((WLAN_BSSID_EX *)bssid);
1744
1745         if (val16 & BIT(4))
1746                 bssid->Privacy = 1;
1747         else
1748                 bssid->Privacy = 0;
1749
1750         RT_TRACE(_module_rtl871x_mlme_c_,_drv_info_,
1751                         ("%s(): cur_network->network.Privacy is %d, bssid.Privacy is %d\n",
1752                          __func__, cur_network->network.Privacy,bssid->Privacy));
1753         if (cur_network->network.Privacy != bssid->Privacy) {
1754                 DBG_871X("%s(), privacy is not match return FAIL\n",__func__);
1755                 goto _mismatch;
1756         }
1757
1758         rtw_get_sec_ie(bssid->IEs, bssid->IELength, NULL,&rsn_len,NULL,&wpa_len);
1759
1760         if (rsn_len > 0) {
1761                 encryp_protocol = ENCRYP_PROTOCOL_WPA2;
1762         } else if (wpa_len > 0) {
1763                 encryp_protocol = ENCRYP_PROTOCOL_WPA;
1764         } else {
1765                 if (bssid->Privacy)
1766                         encryp_protocol = ENCRYP_PROTOCOL_WEP;
1767         }
1768
1769         if (cur_network->BcnInfo.encryp_protocol != encryp_protocol) {
1770                 DBG_871X("%s(): enctyp is not match ,return FAIL\n",__func__);
1771                 goto _mismatch;
1772         }
1773
1774         if (encryp_protocol == ENCRYP_PROTOCOL_WPA || encryp_protocol == ENCRYP_PROTOCOL_WPA2) {
1775                 pbuf = rtw_get_wpa_ie(&bssid->IEs[12], &wpa_ielen, bssid->IELength-12);
1776                 if(pbuf && (wpa_ielen>0)) {
1777                         if (_SUCCESS == rtw_parse_wpa_ie(pbuf, wpa_ielen+2, &group_cipher, &pairwise_cipher, &is_8021x)) {
1778                                 RT_TRACE(_module_rtl871x_mlme_c_,_drv_info_,
1779                                                 ("%s pnetwork->pairwise_cipher: %d, group_cipher is %d, is_8021x is %d\n", __func__,
1780                                                  pairwise_cipher, group_cipher, is_8021x));
1781                         }
1782                 } else {
1783                         pbuf = rtw_get_wpa2_ie(&bssid->IEs[12], &wpa_ielen, bssid->IELength-12);
1784
1785                         if(pbuf && (wpa_ielen>0)) {
1786                                 if (_SUCCESS == rtw_parse_wpa2_ie(pbuf, wpa_ielen+2, &group_cipher, &pairwise_cipher, &is_8021x)) {
1787                                         RT_TRACE(_module_rtl871x_mlme_c_,_drv_info_,
1788                                                         ("%s pnetwork->pairwise_cipher: %d, pnetwork->group_cipher is %d, is_802x is %d\n",
1789                                                          __func__, pairwise_cipher, group_cipher, is_8021x));
1790                                 }
1791                         }
1792                 }
1793
1794                 RT_TRACE(_module_rtl871x_mlme_c_,_drv_err_,
1795                                 ("%s cur_network->group_cipher is %d: %d\n",__func__, cur_network->BcnInfo.group_cipher, group_cipher));
1796                 if (pairwise_cipher != cur_network->BcnInfo.pairwise_cipher || group_cipher != cur_network->BcnInfo.group_cipher) {
1797                         DBG_871X("%s pairwise_cipher(%x:%x) or group_cipher(%x:%x) is not match ,return FAIL\n",__func__,
1798                                         pairwise_cipher, cur_network->BcnInfo.pairwise_cipher,
1799                                         group_cipher, cur_network->BcnInfo.group_cipher);
1800                         goto _mismatch;
1801                 }
1802
1803                 if (is_8021x != cur_network->BcnInfo.is_8021x) {
1804                         DBG_871X("%s authentication is not match ,return FAIL\n", __func__);
1805                         goto _mismatch;
1806                 }
1807         }
1808
1809         rtw_mfree((u8 *)bssid, sizeof(WLAN_BSSID_EX));
1810         return _SUCCESS;
1811
1812 _mismatch:
1813         rtw_mfree((u8 *)bssid, sizeof(WLAN_BSSID_EX));
1814         return _FAIL;
1815
1816         _func_exit_;
1817 }
1818
1819 void update_beacon_info(_adapter *padapter, u8 *pframe, uint pkt_len, struct sta_info *psta)
1820 {
1821         unsigned int i;
1822         unsigned int len;
1823         PNDIS_802_11_VARIABLE_IEs       pIE;
1824                 
1825 #ifdef CONFIG_TDLS
1826         struct tdls_info *ptdlsinfo = &padapter->tdlsinfo;
1827         u8 tdls_prohibited[] = { 0x00, 0x00, 0x00, 0x00, 0x10 }; //bit(38): TDLS_prohibited
1828 #endif //CONFIG_TDLS
1829                 
1830         len = pkt_len - (_BEACON_IE_OFFSET_ + WLAN_HDR_A3_LEN);
1831
1832         for (i = 0; i < len;)
1833         {
1834                 pIE = (PNDIS_802_11_VARIABLE_IEs)(pframe + (_BEACON_IE_OFFSET_ + WLAN_HDR_A3_LEN) + i);
1835                 
1836                 switch (pIE->ElementID)
1837                 {
1838 #if 0                   
1839                         case _VENDOR_SPECIFIC_IE_:              
1840                                 //todo: to update WMM paramter set while receiving beacon                       
1841                                 if (_rtw_memcmp(pIE->data, WMM_PARA_OUI, 6))    //WMM
1842                                 {
1843                                         (WMM_param_handler(padapter, pIE))? WMMOnAssocRsp(padapter): 0;
1844                                 }                               
1845                                 break;
1846 #endif
1847
1848                         case _HT_EXTRA_INFO_IE_:        //HT info                               
1849                                 //HT_info_handler(padapter, pIE);
1850                                 bwmode_update_check(padapter, pIE);
1851                                 break;
1852
1853                         case _ERPINFO_IE_:
1854                                 ERP_IE_handler(padapter, pIE);
1855                                 VCS_update(padapter, psta);
1856                                 break;
1857
1858 #ifdef CONFIG_TDLS
1859                         case _EXT_CAP_IE_:
1860                                 if( check_ap_tdls_prohibited(pIE->data, pIE->Length) == _TRUE )
1861                                         ptdlsinfo->ap_prohibited = _TRUE;
1862                                 break;
1863 #endif //CONFIG_TDLS
1864                         default:
1865                                 break;
1866                 }
1867                 
1868                 i += (pIE->Length + 2);
1869         }
1870 }
1871
1872 #ifdef CONFIG_DFS
1873 void process_csa_ie(_adapter *padapter, u8 *pframe, uint pkt_len)
1874 {
1875         unsigned int i;
1876         unsigned int len;
1877         PNDIS_802_11_VARIABLE_IEs       pIE;
1878         u8 new_ch_no = 0; 
1879
1880         if(padapter->mlmepriv.handle_dfs == _TRUE )
1881                 return;
1882         
1883         len = pkt_len - (_BEACON_IE_OFFSET_ + WLAN_HDR_A3_LEN);
1884
1885         for (i = 0; i < len;)
1886         {
1887                 pIE = (PNDIS_802_11_VARIABLE_IEs)(pframe + (_BEACON_IE_OFFSET_ + WLAN_HDR_A3_LEN) + i);
1888                 
1889                 switch (pIE->ElementID)
1890                 {
1891                         case _CH_SWTICH_ANNOUNCE_:
1892                                 padapter->mlmepriv.handle_dfs = _TRUE;
1893                                 _rtw_memcpy(&new_ch_no, pIE->data+1, 1);
1894                                 rtw_set_csa_cmd(padapter, new_ch_no);
1895                                 break;
1896                         default:
1897                                 break;
1898                 }
1899                 
1900                 i += (pIE->Length + 2);
1901         }
1902 }
1903 #endif //CONFIG_DFS
1904
1905 unsigned int is_ap_in_tkip(_adapter *padapter)
1906 {
1907         u32 i;
1908         PNDIS_802_11_VARIABLE_IEs       pIE;
1909         struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
1910         struct mlme_ext_info    *pmlmeinfo = &(pmlmeext->mlmext_info);
1911         WLAN_BSSID_EX           *cur_network = &(pmlmeinfo->network);
1912
1913         if (rtw_get_capability((WLAN_BSSID_EX *)cur_network) & WLAN_CAPABILITY_PRIVACY)
1914         {
1915                 for (i = sizeof(NDIS_802_11_FIXED_IEs); i < pmlmeinfo->network.IELength;)
1916                 {
1917                         pIE = (PNDIS_802_11_VARIABLE_IEs)(pmlmeinfo->network.IEs + i);
1918                 
1919                         switch (pIE->ElementID)
1920                         {
1921                                 case _VENDOR_SPECIFIC_IE_:
1922                                         if ((_rtw_memcmp(pIE->data, RTW_WPA_OUI, 4)) && (_rtw_memcmp((pIE->data + 12), WPA_TKIP_CIPHER, 4))) 
1923                                         {
1924                                                 return _TRUE;
1925                                         }
1926                                         break;
1927                                 
1928                                 case _RSN_IE_2_:
1929                                         if (_rtw_memcmp((pIE->data + 8), RSN_TKIP_CIPHER, 4)) 
1930                                         {
1931                                                 return _TRUE;
1932                                         }
1933                                         
1934                                 default:
1935                                         break;
1936                         }
1937                 
1938                         i += (pIE->Length + 2);
1939                 }
1940                 
1941                 return _FALSE;
1942         }
1943         else
1944         {
1945                 return _FALSE;
1946         }
1947         
1948 }
1949
1950 unsigned int should_forbid_n_rate(_adapter * padapter)
1951 {
1952         u32 i;
1953         PNDIS_802_11_VARIABLE_IEs       pIE;
1954         struct mlme_priv        *pmlmepriv = &padapter->mlmepriv;
1955         WLAN_BSSID_EX  *cur_network = &pmlmepriv->cur_network.network;
1956
1957         if (rtw_get_capability((WLAN_BSSID_EX *)cur_network) & WLAN_CAPABILITY_PRIVACY)
1958         {
1959                 for (i = sizeof(NDIS_802_11_FIXED_IEs); i < cur_network->IELength;)
1960                 {
1961                         pIE = (PNDIS_802_11_VARIABLE_IEs)(cur_network->IEs + i);
1962
1963                         switch (pIE->ElementID)
1964                         {
1965                                 case _VENDOR_SPECIFIC_IE_:
1966                                         if (_rtw_memcmp(pIE->data, RTW_WPA_OUI, 4) &&
1967                                                 ((_rtw_memcmp((pIE->data + 12), WPA_CIPHER_SUITE_CCMP, 4)) ||
1968                                                   (_rtw_memcmp((pIE->data + 16), WPA_CIPHER_SUITE_CCMP, 4))))
1969                                                 return _FALSE;
1970                                         break;
1971
1972                                 case _RSN_IE_2_:
1973                                         if  ((_rtw_memcmp((pIE->data + 8), RSN_CIPHER_SUITE_CCMP, 4))  ||
1974                                                (_rtw_memcmp((pIE->data + 12), RSN_CIPHER_SUITE_CCMP, 4)))
1975                                         return _FALSE;
1976
1977                                 default:
1978                                         break;
1979                         }
1980
1981                         i += (pIE->Length + 2);
1982                 }
1983
1984                 return _TRUE;
1985         }
1986         else
1987         {
1988                 return _FALSE;
1989         }
1990
1991 }
1992
1993
1994 unsigned int is_ap_in_wep(_adapter *padapter)
1995 {
1996         u32 i;
1997         PNDIS_802_11_VARIABLE_IEs       pIE;
1998         struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
1999         struct mlme_ext_info    *pmlmeinfo = &(pmlmeext->mlmext_info);
2000         WLAN_BSSID_EX           *cur_network = &(pmlmeinfo->network);
2001
2002         if (rtw_get_capability((WLAN_BSSID_EX *)cur_network) & WLAN_CAPABILITY_PRIVACY)
2003         {
2004                 for (i = sizeof(NDIS_802_11_FIXED_IEs); i < pmlmeinfo->network.IELength;)
2005                 {
2006                         pIE = (PNDIS_802_11_VARIABLE_IEs)(pmlmeinfo->network.IEs + i);
2007
2008                         switch (pIE->ElementID)
2009                         {
2010                                 case _VENDOR_SPECIFIC_IE_:
2011                                         if (_rtw_memcmp(pIE->data, RTW_WPA_OUI, 4))
2012                                                 return _FALSE;
2013                                         break;
2014
2015                                 case _RSN_IE_2_:
2016                                         return _FALSE;
2017
2018                                 default:
2019                                         break;
2020                         }
2021
2022                         i += (pIE->Length + 2);
2023                 }
2024
2025                 return _TRUE;
2026         }
2027         else
2028         {
2029                 return _FALSE;
2030         }
2031
2032 }
2033
2034 int wifirate2_ratetbl_inx(unsigned char rate);
2035 int wifirate2_ratetbl_inx(unsigned char rate)
2036 {
2037         int     inx = 0;
2038         rate = rate & 0x7f;
2039
2040         switch (rate) 
2041         {
2042                 case 54*2:
2043                         inx = 11;
2044                         break;
2045
2046                 case 48*2:
2047                         inx = 10;
2048                         break;
2049
2050                 case 36*2:
2051                         inx = 9;
2052                         break;
2053
2054                 case 24*2:
2055                         inx = 8;
2056                         break;
2057                         
2058                 case 18*2:
2059                         inx = 7;
2060                         break;
2061
2062                 case 12*2:
2063                         inx = 6;
2064                         break;
2065
2066                 case 9*2:
2067                         inx = 5;
2068                         break;
2069                         
2070                 case 6*2:
2071                         inx = 4;
2072                         break;
2073
2074                 case 11*2:
2075                         inx = 3;
2076                         break;
2077                 case 11:
2078                         inx = 2;
2079                         break;
2080
2081                 case 2*2:
2082                         inx = 1;
2083                         break;
2084                 
2085                 case 1*2:
2086                         inx = 0;
2087                         break;
2088
2089         }
2090         return inx;     
2091 }
2092
2093 unsigned int update_basic_rate(unsigned char *ptn, unsigned int ptn_sz)
2094 {
2095         unsigned int i, num_of_rate;
2096         unsigned int mask = 0;
2097         
2098         num_of_rate = (ptn_sz > NumRates)? NumRates: ptn_sz;
2099                 
2100         for (i = 0; i < num_of_rate; i++)
2101         {
2102                 if ((*(ptn + i)) & 0x80)
2103                 {
2104                         mask |= 0x1 << wifirate2_ratetbl_inx(*(ptn + i));
2105                 }
2106         }
2107         return mask;
2108 }
2109
2110 unsigned int update_supported_rate(unsigned char *ptn, unsigned int ptn_sz)
2111 {
2112         unsigned int i, num_of_rate;
2113         unsigned int mask = 0;
2114         
2115         num_of_rate = (ptn_sz > NumRates)? NumRates: ptn_sz;
2116                 
2117         for (i = 0; i < num_of_rate; i++)
2118         {
2119                 mask |= 0x1 << wifirate2_ratetbl_inx(*(ptn + i));
2120         }
2121
2122         return mask;
2123 }
2124
2125 unsigned int update_MCS_rate(struct HT_caps_element *pHT_caps)
2126 {
2127         unsigned int mask = 0;
2128         
2129         mask = ((pHT_caps->u.HT_cap_element.MCS_rate[0] << 12) | (pHT_caps->u.HT_cap_element.MCS_rate[1] << 20));
2130                                                 
2131         return mask;
2132 }
2133
2134 int support_short_GI(_adapter *padapter, struct HT_caps_element *pHT_caps, u8 bwmode)
2135 {
2136         unsigned char                                   bit_offset;
2137         struct mlme_ext_priv    *pmlmeext = &padapter->mlmeextpriv;
2138         struct mlme_ext_info    *pmlmeinfo = &(pmlmeext->mlmext_info);
2139         
2140         if (!(pmlmeinfo->HT_enable))
2141                 return _FAIL; 
2142
2143         bit_offset = (bwmode & CHANNEL_WIDTH_40)? 6: 5;
2144         
2145         if (pHT_caps->u.HT_cap_element.HT_caps_info & (0x1 << bit_offset))
2146         {
2147                 return _SUCCESS;
2148         }
2149         else
2150         {
2151                 return _FAIL;
2152         }               
2153 }
2154
2155 unsigned char get_highest_rate_idx(u32 mask)
2156 {
2157         int i;
2158         unsigned char rate_idx=0;
2159
2160         for(i=31; i>=0; i--)
2161         {
2162                 if(mask & BIT(i))
2163                 {
2164                         rate_idx = i;
2165                         break;
2166                 }
2167         }
2168
2169         return rate_idx;
2170 }
2171
2172 unsigned char get_highest_mcs_rate(struct HT_caps_element *pHT_caps);
2173 unsigned char get_highest_mcs_rate(struct HT_caps_element *pHT_caps)
2174 {
2175         int i, mcs_rate;
2176         
2177         mcs_rate = (pHT_caps->u.HT_cap_element.MCS_rate[0] | (pHT_caps->u.HT_cap_element.MCS_rate[1] << 8));
2178         
2179         for (i = 15; i >= 0; i--)
2180         {
2181                 if (mcs_rate & (0x1 << i))
2182                 {
2183                         break;
2184                 }
2185         }
2186         
2187         return i;
2188 }
2189
2190 void Update_RA_Entry(_adapter *padapter, struct sta_info *psta)
2191 {
2192         rtw_hal_update_ra_mask(psta, 0);
2193 }
2194
2195 void enable_rate_adaptive(_adapter *padapter, struct sta_info *psta);
2196 void enable_rate_adaptive(_adapter *padapter, struct sta_info *psta)
2197 {
2198         Update_RA_Entry(padapter, psta);
2199 }
2200
2201 void set_sta_rate(_adapter *padapter, struct sta_info *psta)
2202 {
2203         //rate adaptive 
2204         enable_rate_adaptive(padapter, psta);
2205 }
2206
2207 // Update RRSR and Rate for USERATE
2208 void update_tx_basic_rate(_adapter *padapter, u8 wirelessmode)
2209 {
2210         NDIS_802_11_RATES_EX    supported_rates;
2211         struct mlme_ext_priv    *pmlmeext = &padapter->mlmeextpriv;
2212 #ifdef CONFIG_P2P
2213         struct wifidirect_info* pwdinfo = &padapter->wdinfo;
2214
2215         //      Added by Albert 2011/03/22
2216         //      In the P2P mode, the driver should not support the b mode.
2217         //      So, the Tx packet shouldn't use the CCK rate
2218         if(!rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE))
2219                 return;
2220 #endif //CONFIG_P2P
2221 #ifdef CONFIG_INTEL_WIDI
2222         if (padapter->mlmepriv.widi_state != INTEL_WIDI_STATE_NONE)
2223                 return;
2224 #endif //CONFIG_INTEL_WIDI
2225
2226         _rtw_memset(supported_rates, 0, NDIS_802_11_LENGTH_RATES_EX);
2227
2228         //clear B mod if current channel is in 5G band, avoid tx cck rate in 5G band.
2229         if(pmlmeext->cur_channel > 14)
2230                 wirelessmode &= ~(WIRELESS_11B);
2231
2232         if ((wirelessmode & WIRELESS_11B) && (wirelessmode == WIRELESS_11B)) {
2233                 _rtw_memcpy(supported_rates, rtw_basic_rate_cck, 4);
2234         } else if (wirelessmode & WIRELESS_11B) {
2235                 _rtw_memcpy(supported_rates, rtw_basic_rate_mix, 7);
2236         } else {
2237                 _rtw_memcpy(supported_rates, rtw_basic_rate_ofdm, 3);
2238         }
2239
2240         if (wirelessmode & WIRELESS_11B)
2241                 update_mgnt_tx_rate(padapter, IEEE80211_CCK_RATE_1MB);
2242         else
2243                 update_mgnt_tx_rate(padapter, IEEE80211_OFDM_RATE_6MB);
2244
2245         rtw_hal_set_hwreg(padapter, HW_VAR_BASIC_RATE, supported_rates);
2246 }
2247
2248 unsigned char check_assoc_AP(u8 *pframe, uint len)
2249 {
2250         unsigned int    i;
2251         PNDIS_802_11_VARIABLE_IEs       pIE;
2252
2253         for (i = sizeof(NDIS_802_11_FIXED_IEs); i < len;)
2254         {
2255                 pIE = (PNDIS_802_11_VARIABLE_IEs)(pframe + i);
2256                 
2257                 switch (pIE->ElementID)
2258                 {
2259                         case _VENDOR_SPECIFIC_IE_:
2260                                 if ((_rtw_memcmp(pIE->data, ARTHEROS_OUI1, 3)) || (_rtw_memcmp(pIE->data, ARTHEROS_OUI2, 3)))
2261                                 {
2262                                         DBG_871X("link to Artheros AP\n");
2263                                         return HT_IOT_PEER_ATHEROS;
2264                                 }
2265                                 else if ((_rtw_memcmp(pIE->data, BROADCOM_OUI1, 3))
2266                                                         || (_rtw_memcmp(pIE->data, BROADCOM_OUI2, 3))
2267                                                         || (_rtw_memcmp(pIE->data, BROADCOM_OUI2, 3)))
2268                                 {
2269                                         DBG_871X("link to Broadcom AP\n");
2270                                         return HT_IOT_PEER_BROADCOM;
2271                                 }
2272                                 else if (_rtw_memcmp(pIE->data, MARVELL_OUI, 3))
2273                                 {
2274                                         DBG_871X("link to Marvell AP\n");
2275                                         return HT_IOT_PEER_MARVELL;
2276                                 }
2277                                 else if (_rtw_memcmp(pIE->data, RALINK_OUI, 3))
2278                                 {
2279                                         DBG_871X("link to Ralink AP\n");
2280                                         return HT_IOT_PEER_RALINK;
2281                                 }
2282                                 else if (_rtw_memcmp(pIE->data, CISCO_OUI, 3))
2283                                 {
2284                                         DBG_871X("link to Cisco AP\n");
2285                                         return HT_IOT_PEER_CISCO;
2286                                 }
2287                                 else if (_rtw_memcmp(pIE->data, REALTEK_OUI, 3))
2288                                 {
2289                                         u32     Vender = HT_IOT_PEER_REALTEK;
2290
2291                                         if(pIE->Length >= 5) {
2292                                                 if(pIE->data[4]==1)
2293                                                 {
2294                                                         //if(pIE->data[5] & RT_HT_CAP_USE_LONG_PREAMBLE)
2295                                                         //      bssDesc->BssHT.RT2RT_HT_Mode |= RT_HT_CAP_USE_LONG_PREAMBLE;
2296
2297                                                         if(pIE->data[5] & RT_HT_CAP_USE_92SE)
2298                                                         {
2299                                                                 //bssDesc->BssHT.RT2RT_HT_Mode |= RT_HT_CAP_USE_92SE;
2300                                                                 Vender = HT_IOT_PEER_REALTEK_92SE;
2301                                                         }
2302                                                 }
2303
2304                                                 if(pIE->data[5] & RT_HT_CAP_USE_SOFTAP)
2305                                                         Vender = HT_IOT_PEER_REALTEK_SOFTAP;
2306
2307                                                 if(pIE->data[4] == 2)
2308                                                 {
2309                                                         if(pIE->data[6] & RT_HT_CAP_USE_JAGUAR_BCUT) {
2310                                                                 Vender = HT_IOT_PEER_REALTEK_JAGUAR_BCUTAP;
2311                                                                 DBG_871X("link to Realtek JAGUAR_BCUTAP\n");
2312                                                         }
2313                                                         if(pIE->data[6] & RT_HT_CAP_USE_JAGUAR_CCUT) {
2314                                                                 Vender = HT_IOT_PEER_REALTEK_JAGUAR_CCUTAP;
2315                                                                 DBG_871X("link to Realtek JAGUAR_CCUTAP\n");
2316                                                         }
2317                                                 }
2318                                         }
2319                                 
2320                                         DBG_871X("link to Realtek AP\n");
2321                                         return Vender;
2322                                 }
2323                                 else if (_rtw_memcmp(pIE->data, AIRGOCAP_OUI,3))
2324                                 {
2325                                         DBG_871X("link to Airgo Cap\n");
2326                                         return HT_IOT_PEER_AIRGO;
2327                                 }
2328                                 else
2329                                 {
2330                                         break;
2331                                 }
2332                                                 
2333                         default:
2334                                 break;
2335                 }
2336                                 
2337                 i += (pIE->Length + 2);
2338         }
2339         
2340         DBG_871X("link to new AP\n");
2341         return HT_IOT_PEER_UNKNOWN;
2342 }
2343
2344 void update_IOT_info(_adapter *padapter)
2345 {
2346         struct mlme_ext_priv    *pmlmeext = &padapter->mlmeextpriv;
2347         struct mlme_ext_info    *pmlmeinfo = &(pmlmeext->mlmext_info);
2348         
2349         switch (pmlmeinfo->assoc_AP_vendor)
2350         {
2351                 case HT_IOT_PEER_MARVELL:
2352                         pmlmeinfo->turboMode_cts2self = 1;
2353                         pmlmeinfo->turboMode_rtsen = 0;
2354                         break;
2355                 
2356                 case HT_IOT_PEER_RALINK:
2357                         pmlmeinfo->turboMode_cts2self = 0;
2358                         pmlmeinfo->turboMode_rtsen = 1;
2359                         //disable high power                    
2360                         Switch_DM_Func(padapter, (~DYNAMIC_BB_DYNAMIC_TXPWR), _FALSE);
2361                         break;
2362                 case HT_IOT_PEER_REALTEK:
2363                         //rtw_write16(padapter, 0x4cc, 0xffff);
2364                         //rtw_write16(padapter, 0x546, 0x01c0);
2365                         //disable high power                    
2366                         Switch_DM_Func(padapter, (~DYNAMIC_BB_DYNAMIC_TXPWR), _FALSE);
2367                         break;
2368                 default:
2369                         pmlmeinfo->turboMode_cts2self = 0;
2370                         pmlmeinfo->turboMode_rtsen = 1;
2371                         break;  
2372         }
2373         
2374 }
2375
2376 void update_capinfo(PADAPTER Adapter, u16 updateCap)
2377 {
2378         struct mlme_ext_priv    *pmlmeext = &Adapter->mlmeextpriv;
2379         struct mlme_ext_info    *pmlmeinfo = &(pmlmeext->mlmext_info);
2380         BOOLEAN         ShortPreamble;
2381
2382         // Check preamble mode, 2005.01.06, by rcnjko.
2383         // Mark to update preamble value forever, 2008.03.18 by lanhsin
2384         //if( pMgntInfo->RegPreambleMode == PREAMBLE_AUTO )
2385         {
2386                         
2387                 if(updateCap & cShortPreamble)
2388                 { // Short Preamble
2389                         if(pmlmeinfo->preamble_mode != PREAMBLE_SHORT) // PREAMBLE_LONG or PREAMBLE_AUTO
2390                         {
2391                                 ShortPreamble = _TRUE;
2392                                 pmlmeinfo->preamble_mode = PREAMBLE_SHORT;
2393                                 rtw_hal_set_hwreg( Adapter, HW_VAR_ACK_PREAMBLE, (u8 *)&ShortPreamble );
2394                         }
2395                 }
2396                 else
2397                 { // Long Preamble
2398                         if(pmlmeinfo->preamble_mode != PREAMBLE_LONG)  // PREAMBLE_SHORT or PREAMBLE_AUTO
2399                         {
2400                                 ShortPreamble = _FALSE;
2401                                 pmlmeinfo->preamble_mode = PREAMBLE_LONG;
2402                                 rtw_hal_set_hwreg( Adapter, HW_VAR_ACK_PREAMBLE, (u8 *)&ShortPreamble );
2403                         }
2404                 }
2405         }
2406
2407         if ( updateCap & cIBSS ) {
2408                 //Filen: See 802.11-2007 p.91
2409                 pmlmeinfo->slotTime = NON_SHORT_SLOT_TIME;
2410         }
2411         else
2412         {
2413                 //Filen: See 802.11-2007 p.90
2414                 if( pmlmeext->cur_wireless_mode & (WIRELESS_11_24N | WIRELESS_11A | WIRELESS_11_5N | WIRELESS_11AC))
2415                 {
2416                         pmlmeinfo->slotTime = SHORT_SLOT_TIME;
2417                 }
2418                 else if( pmlmeext->cur_wireless_mode & (WIRELESS_11G))
2419                 {
2420                         if( (updateCap & cShortSlotTime) /* && (!(pMgntInfo->pHTInfo->RT2RT_HT_Mode & RT_HT_CAP_USE_LONG_PREAMBLE)) */)
2421                         { // Short Slot Time
2422                                 pmlmeinfo->slotTime = SHORT_SLOT_TIME;
2423                         }
2424                         else
2425                         { // Long Slot Time
2426                                 pmlmeinfo->slotTime = NON_SHORT_SLOT_TIME;
2427                         }
2428                 }
2429                 else
2430                 {
2431                         //B Mode
2432                         pmlmeinfo->slotTime = NON_SHORT_SLOT_TIME;
2433                 }
2434         }
2435  
2436         rtw_hal_set_hwreg( Adapter, HW_VAR_SLOT_TIME, &pmlmeinfo->slotTime );
2437
2438 }
2439
2440 void update_wireless_mode(_adapter *padapter)
2441 {
2442         int ratelen, network_type = 0;
2443         u32 SIFS_Timer;
2444         struct mlme_ext_priv    *pmlmeext = &padapter->mlmeextpriv;
2445         struct mlme_ext_info    *pmlmeinfo = &(pmlmeext->mlmext_info);
2446         WLAN_BSSID_EX           *cur_network = &(pmlmeinfo->network);
2447         unsigned char                   *rate = cur_network->SupportedRates;
2448 #ifdef CONFIG_P2P
2449         struct wifidirect_info  *pwdinfo= &(padapter->wdinfo);
2450 #endif //CONFIG_P2P
2451
2452         ratelen = rtw_get_rateset_len(cur_network->SupportedRates);
2453
2454         if ((pmlmeinfo->HT_info_enable) && (pmlmeinfo->HT_caps_enable))
2455         {
2456                 pmlmeinfo->HT_enable = 1;
2457         }
2458
2459         if(pmlmeext->cur_channel > 14)
2460         {
2461                 if (pmlmeinfo->VHT_enable)
2462                         network_type = WIRELESS_11AC;
2463                 else if (pmlmeinfo->HT_enable)
2464                         network_type = WIRELESS_11_5N;
2465
2466                 network_type |= WIRELESS_11A;
2467         }
2468         else
2469         {
2470                 if (pmlmeinfo->VHT_enable)
2471                         network_type = WIRELESS_11AC;
2472                 else if (pmlmeinfo->HT_enable)
2473                         network_type = WIRELESS_11_24N;
2474         
2475                 if ((cckratesonly_included(rate, ratelen)) == _TRUE)
2476                 {
2477                         network_type |= WIRELESS_11B;
2478                 }
2479                 else if((cckrates_included(rate, ratelen)) == _TRUE)
2480                 {
2481                         network_type |= WIRELESS_11BG;
2482                 }
2483                 else
2484                 {
2485                         network_type |= WIRELESS_11G;
2486                 }
2487         }
2488
2489         pmlmeext->cur_wireless_mode = network_type & padapter->registrypriv.wireless_mode;
2490 /*
2491         if((pmlmeext->cur_wireless_mode==WIRELESS_11G) ||
2492                 (pmlmeext->cur_wireless_mode==WIRELESS_11BG))//WIRELESS_MODE_G)
2493                 SIFS_Timer = 0x0a0a;//CCK
2494         else
2495                 SIFS_Timer = 0x0e0e;//pHalData->SifsTime; //OFDM
2496 */
2497         
2498         SIFS_Timer = 0x0a0a0808; //0x0808 -> for CCK, 0x0a0a -> for OFDM
2499                              //change this value if having IOT issues.
2500                 
2501         padapter->HalFunc.SetHwRegHandler( padapter, HW_VAR_RESP_SIFS,  (u8 *)&SIFS_Timer);
2502
2503         padapter->HalFunc.SetHwRegHandler( padapter, HW_VAR_WIRELESS_MODE,  (u8 *)&(pmlmeext->cur_wireless_mode));
2504
2505 #ifdef CONFIG_P2P
2506         //      Added by Thomas 20130822
2507         //      In P2P enable, do not set tx rate.
2508         //      workaround for Actiontec GO case. 
2509         //      The Actiontec will use 1M to tx the beacon in 1.1.0 firmware.
2510         if(!rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE))
2511                 return;
2512 #endif //CONFIG_P2P
2513
2514         if (pmlmeext->cur_wireless_mode & WIRELESS_11B)
2515                 update_mgnt_tx_rate(padapter, IEEE80211_CCK_RATE_1MB);
2516          else
2517                 update_mgnt_tx_rate(padapter, IEEE80211_OFDM_RATE_6MB);
2518 }
2519
2520 void fire_write_MAC_cmd(_adapter *padapter, unsigned int addr, unsigned int value);
2521 void fire_write_MAC_cmd(_adapter *padapter, unsigned int addr, unsigned int value)
2522 {
2523 #if 0
2524         struct cmd_obj                                  *ph2c;
2525         struct reg_rw_parm                      *pwriteMacPara;
2526         struct cmd_priv                                 *pcmdpriv = &(padapter->cmdpriv);
2527
2528         if ((ph2c = (struct cmd_obj*)rtw_zmalloc(sizeof(struct cmd_obj))) == NULL)
2529         {
2530                 return;
2531         }       
2532
2533         if ((pwriteMacPara = (struct reg_rw_parm*)rtw_malloc(sizeof(struct reg_rw_parm))) == NULL) 
2534         {               
2535                 rtw_mfree((unsigned char *)ph2c, sizeof(struct cmd_obj));
2536                 return;
2537         }
2538         
2539         pwriteMacPara->rw = 1;
2540         pwriteMacPara->addr = addr;
2541         pwriteMacPara->value = value;
2542         
2543         init_h2fwcmd_w_parm_no_rsp(ph2c, pwriteMacPara, GEN_CMD_CODE(_Write_MACREG));
2544         rtw_enqueue_cmd(pcmdpriv, ph2c);
2545 #endif  
2546 }
2547
2548 void update_sta_basic_rate(struct sta_info *psta, u8 wireless_mode)
2549 {
2550         if(IsSupportedTxCCK(wireless_mode))
2551         {
2552                 // Only B, B/G, and B/G/N AP could use CCK rate
2553                 _rtw_memcpy(psta->bssrateset, rtw_basic_rate_cck, 4);
2554                 psta->bssratelen = 4;
2555         }
2556         else
2557         {
2558                 _rtw_memcpy(psta->bssrateset, rtw_basic_rate_ofdm, 3);
2559                 psta->bssratelen = 3;
2560         }
2561 }
2562
2563 int update_sta_support_rate(_adapter *padapter, u8* pvar_ie, uint var_ie_len, int cam_idx)
2564 {
2565         unsigned int    ie_len;
2566         PNDIS_802_11_VARIABLE_IEs       pIE;
2567         int     supportRateNum = 0;
2568         struct mlme_ext_priv    *pmlmeext = &(padapter->mlmeextpriv);
2569         struct mlme_ext_info    *pmlmeinfo = &(pmlmeext->mlmext_info);
2570         
2571         pIE = (PNDIS_802_11_VARIABLE_IEs)rtw_get_ie(pvar_ie, _SUPPORTEDRATES_IE_, &ie_len, var_ie_len);
2572         if (pIE == NULL)
2573         {
2574                 return _FAIL;
2575         }
2576         
2577         _rtw_memcpy(pmlmeinfo->FW_sta_info[cam_idx].SupportedRates, pIE->data, ie_len);
2578         supportRateNum = ie_len;
2579                                 
2580         pIE = (PNDIS_802_11_VARIABLE_IEs)rtw_get_ie(pvar_ie, _EXT_SUPPORTEDRATES_IE_, &ie_len, var_ie_len);
2581         if (pIE)
2582         {
2583                 _rtw_memcpy((pmlmeinfo->FW_sta_info[cam_idx].SupportedRates + supportRateNum), pIE->data, ie_len);
2584         }
2585
2586         return _SUCCESS;
2587         
2588 }
2589
2590 void process_addba_req(_adapter *padapter, u8 *paddba_req, u8 *addr)
2591 {
2592         struct sta_info *psta;
2593         u16 tid, start_seq, param;      
2594         struct recv_reorder_ctrl *preorder_ctrl;
2595         struct sta_priv *pstapriv = &padapter->stapriv; 
2596         struct ADDBA_request    *preq = (struct ADDBA_request*)paddba_req;
2597         struct mlme_ext_priv    *pmlmeext = &padapter->mlmeextpriv;
2598         struct mlme_ext_info    *pmlmeinfo = &(pmlmeext->mlmext_info);
2599
2600         psta = rtw_get_stainfo(pstapriv, addr);
2601
2602         if(psta)
2603         {
2604                 start_seq = le16_to_cpu(preq->BA_starting_seqctrl) >> 4;
2605                         
2606                 param = le16_to_cpu(preq->BA_para_set);
2607                 tid = (param>>2)&0x0f;
2608                 
2609                 preorder_ctrl = &psta->recvreorder_ctrl[tid];
2610
2611                 #ifdef CONFIG_UPDATE_INDICATE_SEQ_WHILE_PROCESS_ADDBA_REQ
2612                 preorder_ctrl->indicate_seq = start_seq;
2613                 #ifdef DBG_RX_SEQ
2614                 DBG_871X("DBG_RX_SEQ %s:%d IndicateSeq: %d, start_seq: %d\n", __FUNCTION__, __LINE__,
2615                         preorder_ctrl->indicate_seq, start_seq);
2616                 #endif
2617                 #else
2618                 preorder_ctrl->indicate_seq = 0xffff;
2619                 #endif
2620                 
2621                 preorder_ctrl->enable =(pmlmeinfo->bAcceptAddbaReq == _TRUE)? _TRUE :_FALSE;
2622         }
2623
2624 }
2625
2626 void update_TSF(struct mlme_ext_priv *pmlmeext, u8 *pframe, uint len)
2627 {       
2628         u8* pIE;
2629         u32 *pbuf;
2630                 
2631         pIE = pframe + sizeof(struct rtw_ieee80211_hdr_3addr);
2632         pbuf = (u32*)pIE;
2633
2634         pmlmeext->TSFValue = le32_to_cpu(*(pbuf+1));
2635         
2636         pmlmeext->TSFValue = pmlmeext->TSFValue << 32;
2637
2638         pmlmeext->TSFValue |= le32_to_cpu(*pbuf);
2639 }
2640
2641 void correct_TSF(_adapter *padapter, struct mlme_ext_priv *pmlmeext)
2642 {
2643         rtw_hal_set_hwreg(padapter, HW_VAR_CORRECT_TSF, 0);
2644 }
2645
2646 void adaptive_early_32k(struct mlme_ext_priv *pmlmeext, u8 *pframe, uint len)
2647 {       
2648         int i;
2649         u8* pIE;
2650         u32 *pbuf;
2651         u64 tsf=0;
2652         u32 delay_ms;
2653         struct mlme_ext_info    *pmlmeinfo = &(pmlmeext->mlmext_info);
2654
2655
2656         pmlmeext->bcn_cnt++;
2657
2658         pIE = pframe + sizeof(struct rtw_ieee80211_hdr_3addr);
2659         pbuf = (u32*)pIE;
2660
2661         tsf = le32_to_cpu(*(pbuf+1));   
2662         tsf = tsf << 32;
2663         tsf |= le32_to_cpu(*pbuf);
2664
2665         //DBG_871X("%s(): tsf_upper= 0x%08x, tsf_lower=0x%08x\n", __func__, (u32)(tsf>>32), (u32)tsf);
2666
2667         //delay = (timestamp mod 1024*100)/1000 (unit: ms)
2668         //delay_ms = do_div(tsf, (pmlmeinfo->bcn_interval*1024))/1000;
2669         delay_ms = rtw_modular64(tsf, (pmlmeinfo->bcn_interval*1024));
2670         delay_ms = delay_ms/1000;
2671
2672         if(delay_ms >= 8)
2673         {
2674                 pmlmeext->bcn_delay_cnt[8]++;
2675                 //pmlmeext->bcn_delay_ratio[8] = (pmlmeext->bcn_delay_cnt[8] * 100) /pmlmeext->bcn_cnt;
2676         }
2677         else
2678         {
2679                 pmlmeext->bcn_delay_cnt[delay_ms]++;
2680                 //pmlmeext->bcn_delay_ratio[delay_ms] = (pmlmeext->bcn_delay_cnt[delay_ms] * 100) /pmlmeext->bcn_cnt;
2681         }
2682
2683 /*
2684         DBG_871X("%s(): (a)bcn_cnt = %d\n", __func__, pmlmeext->bcn_cnt);
2685
2686
2687         for(i=0; i<9; i++)
2688         {
2689                 DBG_871X("%s():bcn_delay_cnt[%d]=%d,  bcn_delay_ratio[%d]=%d\n", __func__, i, 
2690                         pmlmeext->bcn_delay_cnt[i] , i, pmlmeext->bcn_delay_ratio[i]);                  
2691         }       
2692 */
2693
2694         //dump for  adaptive_early_32k
2695         if(pmlmeext->bcn_cnt > 100 && (pmlmeext->adaptive_tsf_done==_TRUE))
2696         {       
2697                 u8 ratio_20_delay, ratio_80_delay;
2698                 u8 DrvBcnEarly, DrvBcnTimeOut;
2699
2700                 ratio_20_delay = 0;
2701                 ratio_80_delay = 0;
2702                 DrvBcnEarly = 0xff;
2703                 DrvBcnTimeOut = 0xff;
2704         
2705                 DBG_871X("%s(): bcn_cnt = %d\n", __func__, pmlmeext->bcn_cnt);
2706
2707                 for(i=0; i<9; i++)
2708                 {
2709                         pmlmeext->bcn_delay_ratio[i] = (pmlmeext->bcn_delay_cnt[i] * 100) /pmlmeext->bcn_cnt;
2710                         
2711                 
2712                         DBG_871X("%s():bcn_delay_cnt[%d]=%d,  bcn_delay_ratio[%d]=%d\n", __func__, i, 
2713                                 pmlmeext->bcn_delay_cnt[i] , i, pmlmeext->bcn_delay_ratio[i]);
2714
2715                         ratio_20_delay += pmlmeext->bcn_delay_ratio[i];
2716                         ratio_80_delay += pmlmeext->bcn_delay_ratio[i];
2717                 
2718                         if(ratio_20_delay > 20 && DrvBcnEarly == 0xff)
2719                         {                       
2720                                 DrvBcnEarly = i;
2721                                 DBG_871X("%s(): DrvBcnEarly = %d\n", __func__, DrvBcnEarly);
2722                         }       
2723
2724                         if(ratio_80_delay > 80 && DrvBcnTimeOut == 0xff)
2725                         {
2726                                 DrvBcnTimeOut = i;
2727                                 DBG_871X("%s(): DrvBcnTimeOut = %d\n", __func__, DrvBcnTimeOut);
2728                         }
2729                         
2730                         //reset adaptive_early_32k cnt
2731                         pmlmeext->bcn_delay_cnt[i] = 0;
2732                         pmlmeext->bcn_delay_ratio[i] = 0;                       
2733                 }       
2734
2735                 pmlmeext->DrvBcnEarly = DrvBcnEarly;
2736                 pmlmeext->DrvBcnTimeOut = DrvBcnTimeOut;
2737
2738                 pmlmeext->bcn_cnt = 0;          
2739         }       
2740         
2741 }
2742
2743
2744 void beacon_timing_control(_adapter *padapter)
2745 {
2746         rtw_hal_bcn_related_reg_setting(padapter);
2747 }
2748
2749 uint rtw_get_camid(uint macid)
2750 {
2751         uint camid;
2752
2753         //camid 0, 1, 2, 3 is default entry for default key/group key
2754         //macid = 1 is for bc/mc stainfo, no mapping to camid
2755         //macid = 0 mapping to camid 4
2756         //for macid >=2, camid = macid+3;
2757
2758         if(macid==0)
2759                 camid = 4;
2760         else if(macid >=2)
2761                 camid = macid + 3;
2762         else
2763                 camid = 4;
2764
2765         return camid;
2766 }
2767
2768 void rtw_alloc_macid(_adapter *padapter, struct sta_info *psta)
2769 {
2770         int i;
2771         _irqL   irqL;
2772         u8 bc_addr[ETH_ALEN] = {0xff,0xff,0xff,0xff,0xff,0xff};
2773         struct dvobj_priv *pdvobj = adapter_to_dvobj(padapter);
2774
2775
2776         if(_rtw_memcmp(psta->hwaddr, bc_addr, ETH_ALEN))
2777                 return;
2778
2779         if(_rtw_memcmp(psta->hwaddr, myid(&padapter->eeprompriv), ETH_ALEN))
2780         {
2781                 psta->mac_id = NUM_STA;
2782                 return;
2783         }
2784
2785         _enter_critical_bh(&pdvobj->lock, &irqL);
2786         for(i=0; i<NUM_STA; i++)
2787         {
2788                 if(pdvobj->macid[i] == _FALSE)
2789                 {
2790                         pdvobj->macid[i]  = _TRUE;
2791                         break;
2792                 }
2793         }
2794         _exit_critical_bh(&pdvobj->lock, &irqL);
2795
2796         if( i > (NUM_STA-1))
2797         {
2798                 psta->mac_id = NUM_STA;
2799                 DBG_871X("  no room for more MACIDs\n");
2800         }
2801         else
2802         {
2803                 psta->mac_id = i;
2804                 DBG_871X("%s = %d\n", __FUNCTION__, psta->mac_id);
2805         }
2806
2807 }
2808
2809 void rtw_release_macid(_adapter *padapter, struct sta_info *psta)
2810 {
2811         int i;
2812         _irqL   irqL;
2813         u8 bc_addr[ETH_ALEN] = {0xff,0xff,0xff,0xff,0xff,0xff};
2814         struct dvobj_priv *pdvobj = adapter_to_dvobj(padapter);
2815
2816
2817         if(_rtw_memcmp(psta->hwaddr, bc_addr, ETH_ALEN))
2818                 return;
2819
2820         if(_rtw_memcmp(psta->hwaddr, myid(&padapter->eeprompriv), ETH_ALEN))
2821         {
2822                 return;
2823         }
2824
2825         _enter_critical_bh(&pdvobj->lock, &irqL);
2826         if(psta->mac_id<NUM_STA && psta->mac_id !=1 )
2827         {
2828                 if(pdvobj->macid[psta->mac_id] == _TRUE)
2829                 {
2830                         DBG_871X("%s = %d\n", __FUNCTION__, psta->mac_id);
2831                         pdvobj->macid[psta->mac_id]  = _FALSE;
2832                         psta->mac_id = NUM_STA;
2833                 }
2834
2835         }
2836         _exit_critical_bh(&pdvobj->lock, &irqL);
2837
2838 }
2839
2840 #if 0
2841 unsigned int setup_beacon_frame(_adapter *padapter, unsigned char *beacon_frame)
2842 {
2843         unsigned short                          ATIMWindow;
2844         unsigned char                                   *pframe;
2845         struct tx_desc                          *ptxdesc;
2846         struct rtw_ieee80211_hdr        *pwlanhdr;
2847         unsigned short                          *fctrl;
2848         unsigned int                                    rate_len, len = 0;
2849         struct xmit_priv                        *pxmitpriv = &(padapter->xmitpriv);
2850         struct mlme_ext_priv    *pmlmeext = &(padapter->mlmeextpriv);
2851         struct mlme_ext_info    *pmlmeinfo = &(pmlmeext->mlmext_info);
2852         WLAN_BSSID_EX           *cur_network = &(pmlmeinfo->network);
2853         u8      bc_addr[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
2854         
2855         _rtw_memset(beacon_frame, 0, 256);
2856         
2857         pframe = beacon_frame + TXDESC_SIZE;
2858         
2859         pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;  
2860         
2861         fctrl = &(pwlanhdr->frame_ctl);
2862         *(fctrl) = 0;
2863         
2864         _rtw_memcpy(pwlanhdr->addr1, bc_addr, ETH_ALEN);
2865         _rtw_memcpy(pwlanhdr->addr2, myid(&(padapter->eeprompriv)), ETH_ALEN);
2866         _rtw_memcpy(pwlanhdr->addr3, get_my_bssid(cur_network), ETH_ALEN);
2867         
2868         SetFrameSubType(pframe, WIFI_BEACON);
2869         
2870         pframe += sizeof(struct rtw_ieee80211_hdr_3addr);       
2871         len = sizeof(struct rtw_ieee80211_hdr_3addr);
2872
2873         //timestamp will be inserted by hardware
2874         pframe += 8;
2875         len += 8;
2876
2877         // beacon interval: 2 bytes
2878         _rtw_memcpy(pframe, (unsigned char *)(rtw_get_beacon_interval_from_ie(cur_network->IEs)), 2); 
2879
2880         pframe += 2;
2881         len += 2;
2882
2883         // capability info: 2 bytes
2884         _rtw_memcpy(pframe, (unsigned char *)(rtw_get_capability_from_ie(cur_network->IEs)), 2);
2885
2886         pframe += 2;
2887         len += 2;
2888
2889         // SSID
2890         pframe = rtw_set_ie(pframe, _SSID_IE_, cur_network->Ssid.SsidLength, cur_network->Ssid.Ssid, &len);
2891
2892         // supported rates...
2893         rate_len = rtw_get_rateset_len(cur_network->SupportedRates);
2894         pframe = rtw_set_ie(pframe, _SUPPORTEDRATES_IE_, ((rate_len > 8)? 8: rate_len), cur_network->SupportedRates, &len);
2895
2896         // DS parameter set
2897         pframe = rtw_set_ie(pframe, _DSSET_IE_, 1, (unsigned char *)&(cur_network->Configuration.DSConfig), &len);
2898
2899         // IBSS Parameter Set...
2900         //ATIMWindow = cur->Configuration.ATIMWindow;
2901         ATIMWindow = 0;
2902         pframe = rtw_set_ie(pframe, _IBSS_PARA_IE_, 2, (unsigned char *)(&ATIMWindow), &len);
2903
2904         //todo: ERP IE
2905         
2906         // EXTERNDED SUPPORTED RATE
2907         if (rate_len > 8)
2908         {
2909                 pframe = rtw_set_ie(pframe, _EXT_SUPPORTEDRATES_IE_, (rate_len - 8), (cur_network->SupportedRates + 8), &len);
2910         }
2911
2912         if ((len + TXDESC_SIZE) > 256)
2913         {
2914                 //DBG_871X("marc: beacon frame too large\n");
2915                 return 0;
2916         }
2917
2918         //fill the tx descriptor
2919         ptxdesc = (struct tx_desc *)beacon_frame;
2920         
2921         //offset 0      
2922         ptxdesc->txdw0 |= cpu_to_le32(len & 0x0000ffff); 
2923         ptxdesc->txdw0 |= cpu_to_le32(((TXDESC_SIZE + OFFSET_SZ) << OFFSET_SHT) & 0x00ff0000); //default = 32 bytes for TX Desc
2924         
2925         //offset 4      
2926         ptxdesc->txdw1 |= cpu_to_le32((0x10 << QSEL_SHT) & 0x00001f00);
2927         
2928         //offset 8              
2929         ptxdesc->txdw2 |= cpu_to_le32(BMC);
2930         ptxdesc->txdw2 |= cpu_to_le32(BK);
2931
2932         //offset 16             
2933         ptxdesc->txdw4 = 0x80000000;
2934         
2935         //offset 20
2936         ptxdesc->txdw5 = 0x00000000; //1M       
2937         
2938         return (len + TXDESC_SIZE);
2939 }
2940 #endif
2941
2942 static _adapter *pbuddy_padapter = NULL;
2943
2944 int rtw_handle_dualmac(_adapter *adapter, bool init)
2945 {
2946         int status = _SUCCESS;
2947         struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
2948
2949         if(adapter->chip_type != RTL8192D)      
2950                 goto exit;
2951                 
2952         if (init) {
2953                 #if 0
2954                 /* For SMSP on 92DU-VC, driver do not probe another Interface. */
2955                 if(dvobj->NumInterfaces == 2 && dvobj->InterfaceNumber != 0 &&
2956                         adapter->registrypriv.mac_phy_mode == 1) {
2957                         DBG_871X("%s(): Do not init another USB Interface because SMSP\n",__FUNCTION__);
2958                         status = _FAIL;
2959                         goto exit;
2960                 }
2961                 #endif
2962                 
2963                 if (pbuddy_padapter == NULL) {
2964                         pbuddy_padapter = adapter;
2965                         DBG_871X("%s(): pbuddy_padapter == NULL, Set pbuddy_padapter\n",__FUNCTION__);
2966                 } else {
2967                         adapter->pbuddy_adapter = pbuddy_padapter;
2968                         pbuddy_padapter->pbuddy_adapter = adapter;
2969                         // clear global value
2970                         pbuddy_padapter = NULL;
2971                         DBG_871X("%s(): pbuddy_padapter exist, Exchange Information\n",__FUNCTION__);
2972                 }
2973 #ifdef CONFIG_DUALMAC_CONCURRENT
2974                 if (dvobj->InterfaceNumber == 0) {
2975                         //set adapter_type/iface type
2976                         adapter->isprimary = _TRUE;
2977                         adapter->adapter_type = PRIMARY_ADAPTER;
2978                         adapter->iface_type = IFACE_PORT0;
2979                         DBG_871X("%s(): PRIMARY_ADAPTER\n",__FUNCTION__);
2980                 } else {
2981                         //set adapter_type/iface type
2982                         adapter->isprimary = _FALSE;
2983                         adapter->adapter_type = SECONDARY_ADAPTER;
2984                         adapter->iface_type = IFACE_PORT1;
2985                         DBG_871X("%s(): SECONDARY_ADAPTER\n",__FUNCTION__);
2986                 }
2987 #endif
2988         }else {
2989                 pbuddy_padapter = NULL;
2990         }
2991 exit:
2992         return status;
2993 }
2994
2995 _adapter *dvobj_get_port0_adapter(struct dvobj_priv *dvobj)
2996 {
2997         _adapter *port0_iface = NULL;
2998         int i;
2999         for (i=0;i<dvobj->iface_nums;i++) {
3000                 if (get_iface_type(dvobj->padapters[i]) == IFACE_PORT0)
3001                         break;
3002         }
3003
3004         if (i<0 || i>=dvobj->iface_nums)
3005                 rtw_warn_on(1);
3006         else
3007                 port0_iface = dvobj->padapters[i];
3008
3009         return port0_iface;
3010 }
3011
3012 #ifdef CONFIG_WOWLAN
3013 void rtw_get_current_ip_address(PADAPTER padapter, u8 *pcurrentip)
3014 {
3015         struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
3016         struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
3017         struct in_device *my_ip_ptr = padapter->pnetdev->ip_ptr;
3018         u8 ipaddress[4];
3019         
3020         if ( (pmlmeinfo->state & WIFI_FW_LINKING_STATE) ) {
3021                 if ( my_ip_ptr != NULL ) {
3022                         struct in_ifaddr *my_ifa_list  = my_ip_ptr->ifa_list ;
3023                         if ( my_ifa_list != NULL ) {
3024                                 ipaddress[0] = my_ifa_list->ifa_address & 0xFF;
3025                                 ipaddress[1] = (my_ifa_list->ifa_address >> 8) & 0xFF;
3026                                 ipaddress[2] = (my_ifa_list->ifa_address >> 16) & 0xFF;
3027                                 ipaddress[3] = my_ifa_list->ifa_address >> 24;
3028                                 DBG_871X("%s: %d.%d.%d.%d ==========\n", __func__, 
3029                                                 ipaddress[0], ipaddress[1], ipaddress[2], ipaddress[3]);
3030                                 _rtw_memcpy(pcurrentip, ipaddress, 4);
3031                         }
3032                 }
3033         }
3034 }
3035 void rtw_get_sec_iv(PADAPTER padapter, u8*pcur_dot11txpn, u8 *StaAddr)
3036 {
3037         struct sta_info         *psta;
3038         struct security_priv *psecpriv = &padapter->securitypriv;
3039
3040         _rtw_memset(pcur_dot11txpn, 0, 8);
3041         if(NULL == StaAddr)
3042                 return; 
3043         psta = rtw_get_stainfo(&padapter->stapriv, StaAddr);
3044         DBG_871X("%s(): StaAddr: %02x %02x %02x %02x %02x %02x\n", 
3045                 __func__, StaAddr[0], StaAddr[1], StaAddr[2],
3046                 StaAddr[3], StaAddr[4], StaAddr[5]);
3047
3048         if(psta)
3049         {
3050                 if (psecpriv->dot11PrivacyAlgrthm != _NO_PRIVACY_ && psta->dot11txpn.val > 0)
3051                         psta->dot11txpn.val--;
3052                 AES_IV(pcur_dot11txpn, psta->dot11txpn, 0);
3053
3054                 DBG_871X("%s(): CurrentIV: %02x %02x %02x %02x %02x %02x %02x %02x \n"
3055                 , __func__, pcur_dot11txpn[0],pcur_dot11txpn[1],
3056                 pcur_dot11txpn[2],pcur_dot11txpn[3], pcur_dot11txpn[4],
3057                 pcur_dot11txpn[5],pcur_dot11txpn[6],pcur_dot11txpn[7]);
3058         }
3059 }
3060 void rtw_set_sec_pn(PADAPTER padapter)
3061 {
3062         struct sta_info         *psta;
3063         struct mlme_ext_priv    *pmlmeext = &(padapter->mlmeextpriv);
3064         struct mlme_ext_info    *pmlmeinfo = &(pmlmeext->mlmext_info);
3065         struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(padapter);
3066                 struct security_priv *psecpriv = &padapter->securitypriv;
3067
3068         psta = rtw_get_stainfo(&padapter->stapriv,
3069                         get_my_bssid(&pmlmeinfo->network));
3070
3071         if(psta)
3072         {
3073                         if (pwrpriv->wowlan_fw_iv > psta->dot11txpn.val)
3074                         {
3075 #ifdef CONFIG_RTL8188E
3076                                 /* TODO: update 8188E FW to remove this workaround.*/
3077                                 psta->dot11txpn.val += 4;
3078                                 DBG_871X("%s: workaround only for 8188e, txpn +=4\n", __func__);
3079 #else
3080                                 if (psecpriv->dot11PrivacyAlgrthm != _NO_PRIVACY_)
3081                                         psta->dot11txpn.val = pwrpriv->wowlan_fw_iv + 2;
3082 #endif
3083                         } else {
3084                                 DBG_871X("%s(): FW IV is smaller than driver\n", __func__);
3085                 psta->dot11txpn.val += 2;
3086                         }
3087                 DBG_871X("%s: dot11txpn: 0x%016llx\n", __func__ ,psta->dot11txpn.val);
3088         }
3089 }
3090 #endif //CONFIG_WOWLAN
3091
3092 #ifdef CONFIG_PNO_SUPPORT
3093 #define CSCAN_TLV_TYPE_SSID_IE  'S'
3094 /*
3095  *  SSIDs list parsing from cscan tlv list
3096  */
3097 int rtw_parse_ssid_list_tlv(char** list_str, pno_ssid_t* ssid,
3098         int max, int *bytes_left) {
3099         char* str;
3100
3101         int idx = 0;
3102
3103         if ((list_str == NULL) || (*list_str == NULL) || (*bytes_left < 0)) {
3104                 DBG_871X("%s error paramters\n", __func__);
3105                 return -1;
3106         }
3107
3108         str = *list_str;
3109         while (*bytes_left > 0) {
3110
3111                 if (str[0] != CSCAN_TLV_TYPE_SSID_IE) {
3112                         *list_str = str;
3113                         DBG_871X("nssid=%d left_parse=%d %d\n", idx, *bytes_left, str[0]);
3114                         return idx;
3115                 }
3116
3117                 /* Get proper CSCAN_TLV_TYPE_SSID_IE */
3118                 *bytes_left -= 1;
3119                 str += 1;
3120
3121                 if (str[0] == 0) {
3122                         /* Broadcast SSID */
3123                         ssid[idx].SSID_len = 0;
3124                         memset((char*)ssid[idx].SSID, 0x0, WLAN_SSID_MAXLEN);
3125                         *bytes_left -= 1;
3126                         str += 1;
3127
3128                         DBG_871X("BROADCAST SCAN  left=%d\n", *bytes_left);
3129                 }
3130                 else if (str[0] <= WLAN_SSID_MAXLEN) {
3131                          /* Get proper SSID size */
3132                         ssid[idx].SSID_len = str[0];
3133                         *bytes_left -= 1;
3134                         str += 1;
3135
3136                         /* Get SSID */
3137                         if (ssid[idx].SSID_len > *bytes_left) {
3138                                 DBG_871X("%s out of memory range len=%d but left=%d\n",
3139                                 __func__, ssid[idx].SSID_len, *bytes_left);
3140                                 return -1;
3141                         }
3142
3143                         memcpy((char*)ssid[idx].SSID, str, ssid[idx].SSID_len);
3144
3145                         *bytes_left -= ssid[idx].SSID_len;
3146                         str += ssid[idx].SSID_len;
3147
3148                         DBG_871X("%s :size=%d left=%d\n",
3149                                 (char*)ssid[idx].SSID, ssid[idx].SSID_len, *bytes_left);
3150                 }
3151                 else {
3152                         DBG_871X("### SSID size more that %d\n", str[0]);
3153                         return -1;
3154                 }
3155
3156                 if (idx++ >  max) {
3157                         DBG_871X("%s number of SSIDs more that %d\n", __func__, idx);
3158                         return -1;
3159                 }
3160         }
3161
3162         *list_str = str;
3163         return idx;
3164 }
3165
3166 int rtw_dev_nlo_info_set(struct pno_nlo_info *nlo_info, pno_ssid_t* ssid,
3167         int num, int pno_time, int pno_repeat, int pno_freq_expo_max) {
3168
3169         int i = 0;
3170         nlo_info->fast_scan_period = pno_time;
3171         nlo_info->ssid_num = num & BIT_LEN_MASK_32(8);
3172         nlo_info->slow_scan_period = (pno_time * 2);
3173         nlo_info->fast_scan_iterations = 5;
3174
3175         //TODO: chiper array, channel list and probe index is all empty.
3176         for (i = 0 ; i < num ; i++) {
3177                 nlo_info->ssid_length[i]
3178                         = ssid[i].SSID_len;
3179         }
3180         return 0;
3181 }
3182
3183 int rtw_dev_ssid_list_set(struct pno_ssid_list *pno_ssid_list,
3184         pno_ssid_t* ssid, u8 num) {
3185
3186         int i = 0;
3187         if(num > MAX_PNO_LIST_COUNT)
3188                 num = MAX_PNO_LIST_COUNT;
3189
3190         for (i = 0 ; i < num ; i++) {
3191                 _rtw_memcpy(&pno_ssid_list->node[i].SSID,
3192                         ssid[i].SSID, ssid[i].SSID_len);
3193         }
3194         return 0;
3195 }
3196
3197 int rtw_dev_scan_info_set(_adapter *padapter, pno_ssid_t* ssid,
3198         unsigned char ch, unsigned char ch_offset, unsigned short bw_mode) {
3199
3200         struct pwrctrl_priv *pwrctl = adapter_to_pwrctl(padapter);
3201         struct pno_scan_info *scan_info = pwrctl->pscan_info;
3202         int i;
3203
3204         scan_info->channel_num = MAX_SCAN_LIST_COUNT;
3205         scan_info->orig_ch = ch;
3206         scan_info->orig_bw = bw_mode;
3207         scan_info->orig_40_offset = ch_offset;
3208
3209         for(i = 0 ; i < scan_info->channel_num ; i++) {
3210                 if (i < 11)
3211                         scan_info->ssid_channel_info[i].active = 1;
3212                 else
3213                         scan_info->ssid_channel_info[i].active = 0;
3214
3215                 scan_info->ssid_channel_info[i].timeout = 100;
3216
3217                 scan_info->ssid_channel_info[i].tx_power =
3218                         PHY_GetTxPowerIndex(padapter, 0, 0x02, bw_mode, i+1);
3219
3220                 scan_info->ssid_channel_info[i].channel = i+1;
3221         }
3222
3223         DBG_871X("%s, channel_num: %d, orig_ch: %d, orig_bw: %d orig_40_offset: %d\n",
3224                 __func__, scan_info->channel_num, scan_info->orig_ch,
3225                 scan_info->orig_bw, scan_info->orig_40_offset);
3226         return 0;
3227 }
3228
3229 int rtw_dev_pno_set(struct net_device *net, pno_ssid_t* ssid, int num,
3230         int pno_time, int pno_repeat, int pno_freq_expo_max) {
3231
3232         _adapter *padapter = (_adapter *)rtw_netdev_priv(net);
3233         struct pwrctrl_priv *pwrctl = adapter_to_pwrctl(padapter);
3234         struct mlme_ext_priv    *pmlmeext = &padapter->mlmeextpriv;
3235
3236         int ret = -1;
3237
3238         if (num == 0) {
3239                 DBG_871X("%s, nssid is zero, no need to setup pno ssid list\n", __func__);
3240                 return 0;
3241         }
3242
3243         if (pwrctl == NULL) {
3244                 DBG_871X("%s, ERROR: pwrctl is NULL\n", __func__);
3245                 return -1;
3246         } else {
3247                 pwrctl->pnlo_info =
3248                         (pno_nlo_info_t*)rtw_zmalloc(sizeof(pno_nlo_info_t));
3249                 pwrctl->pno_ssid_list =
3250                         (pno_ssid_list_t*)rtw_zmalloc(sizeof(pno_ssid_list_t));
3251                 pwrctl->pscan_info =
3252                         (pno_scan_info_t*)rtw_zmalloc(sizeof(pno_scan_info_t));
3253         }
3254
3255         if (pwrctl->pnlo_info == NULL ||
3256                 pwrctl->pscan_info == NULL ||
3257                 pwrctl->pno_ssid_list == NULL){
3258                 DBG_871X("%s, ERROR: alloc nlo_info, ssid_list, scan_info fail\n", __func__);
3259                 return -1;
3260         }
3261
3262         /* NLO Info */
3263         ret = rtw_dev_nlo_info_set(pwrctl->pnlo_info, ssid, num,
3264                         pno_time, pno_repeat, pno_freq_expo_max);
3265
3266         /* SSID Info */
3267         ret = rtw_dev_ssid_list_set(pwrctl->pno_ssid_list, ssid, num);
3268
3269         /* SCAN Info */
3270         ret = rtw_dev_scan_info_set(padapter, ssid, pmlmeext->cur_channel,
3271                         pmlmeext->cur_ch_offset, pmlmeext->cur_bwmode);
3272
3273         DBG_871X("+%s num: %d, pno_time: %d, pno_repeat:%d, pno_freq_expo_max:%d+\n",
3274                  __func__, num, pno_time, pno_repeat, pno_freq_expo_max);
3275
3276         return 0;
3277 }
3278
3279 #ifdef CONFIG_PNO_SET_DEBUG
3280 void rtw_dev_pno_debug(struct net_device *net) {
3281         _adapter *padapter = (_adapter *)rtw_netdev_priv(net);
3282         struct pwrctrl_priv *pwrctl = adapter_to_pwrctl(padapter);
3283         int i = 0, j = 0;
3284
3285         DBG_871X("*******NLO_INFO********\n");
3286         DBG_871X("ssid_num: %d\n", pwrctl->pnlo_info->ssid_num);
3287         DBG_871X("fast_scan_iterations: %d\n",
3288                         pwrctl->pnlo_info->fast_scan_iterations);
3289         DBG_871X("fast_scan_period: %d\n", pwrctl->pnlo_info->fast_scan_period);
3290         DBG_871X("slow_scan_period: %d\n", pwrctl->pnlo_info->slow_scan_period);
3291         DBG_871X("ssid_length: ");
3292         for (i = 0 ; i < MAX_PNO_LIST_COUNT ; i++) {
3293                 printk("%d, ", pwrctl->pnlo_info->ssid_length[i]);
3294         }
3295         DBG_871X("\n");
3296
3297         DBG_871X("chiper_info: ");
3298         for (i = 0 ; i < MAX_PNO_LIST_COUNT ; i++) {
3299                 DBG_871X("%d, ", pwrctl->pnlo_info->ssid_chiper_info[i]);
3300         }
3301         DBG_871X("\n");
3302
3303         DBG_871X("channel_info: ");
3304         for (i = 0 ; i < MAX_PNO_LIST_COUNT ; i++) {
3305                 DBG_871X("%d, ", pwrctl->pnlo_info->ssid_channel_info[i]);
3306         }
3307         DBG_871X("\n");
3308
3309         DBG_871X("******SSID_LISD******\n");
3310         for (i = 0 ; i < MAX_PNO_LIST_COUNT ; i++) {
3311                 DBG_871X("[%d]SSID: %s \n", i,
3312                         pwrctl->pno_ssid_list->node[i].SSID);
3313         }
3314
3315         DBG_871X("******SCAN_INFO******\n");
3316         DBG_871X("ch_num: %d\n", pwrctl->pscan_info->channel_num);
3317         DBG_871X("orig_ch: %d\n", pwrctl->pscan_info->orig_ch);
3318         DBG_871X("orig bw: %d\n", pwrctl->pscan_info->orig_bw);
3319         DBG_871X("orig 40 offset: %d\n", pwrctl->pscan_info->orig_40_offset);
3320         for(i = 0 ; i < MAX_SCAN_LIST_COUNT ; i++) {
3321                 DBG_871X("[%02d] avtive:%d, timeout:%d, tx_power:%d, ch:%02d\n",
3322                         i, pwrctl->pscan_info->ssid_channel_info[i].active,
3323                         pwrctl->pscan_info->ssid_channel_info[i].timeout,
3324                         pwrctl->pscan_info->ssid_channel_info[i].tx_power,
3325                         pwrctl->pscan_info->ssid_channel_info[i].channel);
3326         }
3327         DBG_871X("*****************\n");
3328 }
3329 #endif //CONFIG_PNO_SET_DEBUG
3330 #endif //CONFIG_PNO_SUPPORT