Merge branch 'develop-3.10-next' of 10.10.10.29:rk/kernel into develop-3.10-next
[firefly-linux-kernel-4.4.55.git] / drivers / net / wireless / rockchip_wlan / rtl8188eu / core / rtw_ap.c
1 /******************************************************************************\r
2  *\r
3  * Copyright(c) 2007 - 2012 Realtek Corporation. All rights reserved.\r
4  *                                        \r
5  * This program is free software; you can redistribute it and/or modify it\r
6  * under the terms of version 2 of the GNU General Public License as\r
7  * published by the Free Software Foundation.\r
8  *\r
9  * This program is distributed in the hope that it will be useful, but WITHOUT\r
10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\r
11  * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for\r
12  * more details.\r
13  *\r
14  * You should have received a copy of the GNU General Public License along with\r
15  * this program; if not, write to the Free Software Foundation, Inc.,\r
16  * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA\r
17  *\r
18  *\r
19  ******************************************************************************/\r
20 #define _RTW_AP_C_\r
21 \r
22 #include <drv_types.h>\r
23 \r
24 \r
25 #ifdef CONFIG_AP_MODE\r
26 \r
27 extern unsigned char    RTW_WPA_OUI[];\r
28 extern unsigned char    WMM_OUI[];\r
29 extern unsigned char    WPS_OUI[];\r
30 extern unsigned char    P2P_OUI[];\r
31 extern unsigned char    WFD_OUI[];\r
32 \r
33 void init_mlme_ap_info(_adapter *padapter)\r
34 {\r
35         struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;\r
36         struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);\r
37         struct sta_priv *pstapriv = &padapter->stapriv; \r
38         struct wlan_acl_pool *pacl_list = &pstapriv->acl_list;\r
39         \r
40 \r
41         _rtw_spinlock_init(&pmlmepriv->bcn_update_lock);        \r
42 \r
43         //for ACL \r
44         _rtw_init_queue(&pacl_list->acl_node_q);\r
45 \r
46         //pmlmeext->bstart_bss = _FALSE;\r
47 \r
48         start_ap_mode(padapter);\r
49 }\r
50 \r
51 void free_mlme_ap_info(_adapter *padapter)\r
52 {\r
53         _irqL irqL;\r
54         struct sta_info *psta=NULL;\r
55         struct sta_priv *pstapriv = &padapter->stapriv;\r
56         struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);\r
57         struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;\r
58         struct mlme_ext_info    *pmlmeinfo = &(pmlmeext->mlmext_info);\r
59 \r
60         //stop_ap_mode(padapter);\r
61 \r
62         pmlmepriv->update_bcn = _FALSE;\r
63         pmlmeext->bstart_bss = _FALSE;  \r
64         \r
65         rtw_sta_flush(padapter);\r
66 \r
67         pmlmeinfo->state = _HW_STATE_NOLINK_;\r
68 \r
69         //free_assoc_sta_resources\r
70         rtw_free_all_stainfo(padapter);\r
71 \r
72         //free bc/mc sta_info\r
73         psta = rtw_get_bcmc_stainfo(padapter);  \r
74         _enter_critical_bh(&(pstapriv->sta_hash_lock), &irqL);          \r
75         rtw_free_stainfo(padapter, psta);\r
76         _exit_critical_bh(&(pstapriv->sta_hash_lock), &irqL);\r
77         \r
78 \r
79         _rtw_spinlock_free(&pmlmepriv->bcn_update_lock);\r
80         \r
81 }\r
82 \r
83 static void update_BCNTIM(_adapter *padapter)\r
84 {\r
85         struct sta_priv *pstapriv = &padapter->stapriv;\r
86         struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);\r
87         struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);\r
88         WLAN_BSSID_EX *pnetwork_mlmeext = &(pmlmeinfo->network);\r
89         unsigned char *pie = pnetwork_mlmeext->IEs;\r
90 \r
91         //DBG_871X("%s\n", __FUNCTION__);\r
92         \r
93         //update TIM IE\r
94         //if(pstapriv->tim_bitmap)\r
95         if(_TRUE)\r
96         {\r
97                 u8 *p, *dst_ie, *premainder_ie=NULL, *pbackup_remainder_ie=NULL;\r
98                 u16 tim_bitmap_le;\r
99                 uint offset, tmp_len, tim_ielen, tim_ie_offset, remainder_ielen;        \r
100         \r
101                 tim_bitmap_le = cpu_to_le16(pstapriv->tim_bitmap);\r
102 \r
103                 p = rtw_get_ie(pie + _FIXED_IE_LENGTH_, _TIM_IE_, &tim_ielen, pnetwork_mlmeext->IELength - _FIXED_IE_LENGTH_);\r
104                 if (p != NULL && tim_ielen>0)\r
105                 {\r
106                         tim_ielen += 2;\r
107                         \r
108                         premainder_ie = p+tim_ielen;\r
109 \r
110                         tim_ie_offset = (sint)(p -pie);\r
111                         \r
112                         remainder_ielen = pnetwork_mlmeext->IELength - tim_ie_offset - tim_ielen;\r
113 \r
114                         //append TIM IE from dst_ie offset\r
115                         dst_ie = p;\r
116                 }\r
117                 else\r
118                 {\r
119                         tim_ielen = 0;\r
120 \r
121                         //calucate head_len             \r
122                         offset = _FIXED_IE_LENGTH_;\r
123 \r
124                         /* get ssid_ie len */\r
125                         p = rtw_get_ie(pie + _BEACON_IE_OFFSET_, _SSID_IE_, &tmp_len, (pnetwork_mlmeext->IELength - _BEACON_IE_OFFSET_));\r
126                         if (p != NULL)\r
127                                 offset += tmp_len+2;\r
128 \r
129                         // get supported rates len\r
130                         p = rtw_get_ie(pie + _BEACON_IE_OFFSET_, _SUPPORTEDRATES_IE_, &tmp_len, (pnetwork_mlmeext->IELength - _BEACON_IE_OFFSET_));     \r
131                         if (p !=  NULL) \r
132                         {                       \r
133                                 offset += tmp_len+2;\r
134                         }\r
135 \r
136                         //DS Parameter Set IE, len=3    \r
137                         offset += 3;\r
138 \r
139                         premainder_ie = pie + offset;\r
140 \r
141                         remainder_ielen = pnetwork_mlmeext->IELength - offset - tim_ielen;      \r
142 \r
143                         //append TIM IE from offset\r
144                         dst_ie = pie + offset;\r
145                         \r
146                 }\r
147 \r
148                 \r
149                 if(remainder_ielen>0)\r
150                 {\r
151                         pbackup_remainder_ie = rtw_malloc(remainder_ielen);\r
152                         if(pbackup_remainder_ie && premainder_ie)\r
153                                 _rtw_memcpy(pbackup_remainder_ie, premainder_ie, remainder_ielen);\r
154                 }               \r
155                 \r
156                 *dst_ie++=_TIM_IE_;\r
157 \r
158                 if((pstapriv->tim_bitmap&0xff00) && (pstapriv->tim_bitmap&0x00fe))                      \r
159                         tim_ielen = 5;\r
160                 else\r
161                         tim_ielen = 4;\r
162 \r
163                 *dst_ie++= tim_ielen;\r
164                 \r
165                 *dst_ie++=0;//DTIM count\r
166                 *dst_ie++=1;//DTIM peroid\r
167                 \r
168                 if(pstapriv->tim_bitmap&BIT(0))//for bc/mc frames\r
169                         *dst_ie++ = BIT(0);//bitmap ctrl \r
170                 else\r
171                         *dst_ie++ = 0;\r
172 \r
173                 if(tim_ielen==4)\r
174                 {\r
175                         u8 pvb=0;\r
176                         \r
177                         if(pstapriv->tim_bitmap&0x00fe)\r
178                                 pvb = (u8)tim_bitmap_le;\r
179                         else if(pstapriv->tim_bitmap&0xff00)                    \r
180                                 pvb = (u8)(tim_bitmap_le>>8);\r
181                         else\r
182                                 pvb = (u8)tim_bitmap_le;\r
183 \r
184                         *dst_ie++ = pvb;\r
185                         \r
186                 }       \r
187                 else if(tim_ielen==5)\r
188                 {\r
189                         _rtw_memcpy(dst_ie, &tim_bitmap_le, 2);\r
190                         dst_ie+=2;                              \r
191                 }       \r
192                 \r
193                 //copy remainder IE\r
194                 if(pbackup_remainder_ie)\r
195                 {\r
196                         _rtw_memcpy(dst_ie, pbackup_remainder_ie, remainder_ielen);\r
197 \r
198                         rtw_mfree(pbackup_remainder_ie, remainder_ielen);\r
199                 }       \r
200 \r
201                 offset =  (uint)(dst_ie - pie);\r
202                 pnetwork_mlmeext->IELength = offset + remainder_ielen;\r
203         \r
204         }\r
205 }\r
206 \r
207 void rtw_add_bcn_ie(_adapter *padapter, WLAN_BSSID_EX *pnetwork, u8 index, u8 *data, u8 len)\r
208 {\r
209         PNDIS_802_11_VARIABLE_IEs       pIE;\r
210         u8      bmatch = _FALSE;\r
211         u8      *pie = pnetwork->IEs;\r
212         u8      *p=NULL, *dst_ie=NULL, *premainder_ie=NULL, *pbackup_remainder_ie=NULL;\r
213         u32     i, offset, ielen, ie_offset, remainder_ielen = 0;\r
214 \r
215         for (i = sizeof(NDIS_802_11_FIXED_IEs); i < pnetwork->IELength;)\r
216         {\r
217                 pIE = (PNDIS_802_11_VARIABLE_IEs)(pnetwork->IEs + i);\r
218 \r
219                 if (pIE->ElementID > index)\r
220                 {\r
221                         break;\r
222                 }\r
223                 else if(pIE->ElementID == index) // already exist the same IE\r
224                 {\r
225                         p = (u8 *)pIE;\r
226                         ielen = pIE->Length;\r
227                         bmatch = _TRUE;\r
228                         break;\r
229                 }\r
230 \r
231                 p = (u8 *)pIE;\r
232                 ielen = pIE->Length;\r
233                 i += (pIE->Length + 2);\r
234         }\r
235 \r
236         if (p != NULL && ielen>0)\r
237         {\r
238                 ielen += 2;\r
239                 \r
240                 premainder_ie = p+ielen;\r
241 \r
242                 ie_offset = (sint)(p -pie);\r
243                 \r
244                 remainder_ielen = pnetwork->IELength - ie_offset - ielen;\r
245 \r
246                 if(bmatch)\r
247                         dst_ie = p;\r
248                 else\r
249                         dst_ie = (p+ielen);\r
250         }\r
251 \r
252         if(dst_ie == NULL)\r
253                 return;\r
254 \r
255         if(remainder_ielen>0)\r
256         {\r
257                 pbackup_remainder_ie = rtw_malloc(remainder_ielen);\r
258                 if(pbackup_remainder_ie && premainder_ie)\r
259                         _rtw_memcpy(pbackup_remainder_ie, premainder_ie, remainder_ielen);\r
260         }\r
261 \r
262         *dst_ie++=index;\r
263         *dst_ie++=len;\r
264 \r
265         _rtw_memcpy(dst_ie, data, len);\r
266         dst_ie+=len;\r
267 \r
268         //copy remainder IE\r
269         if(pbackup_remainder_ie)\r
270         {\r
271                 _rtw_memcpy(dst_ie, pbackup_remainder_ie, remainder_ielen);\r
272 \r
273                 rtw_mfree(pbackup_remainder_ie, remainder_ielen);\r
274         }\r
275 \r
276         offset =  (uint)(dst_ie - pie);\r
277         pnetwork->IELength = offset + remainder_ielen;\r
278 }\r
279 \r
280 void rtw_remove_bcn_ie(_adapter *padapter, WLAN_BSSID_EX *pnetwork, u8 index)\r
281 {\r
282         u8 *p, *dst_ie=NULL, *premainder_ie=NULL, *pbackup_remainder_ie=NULL;\r
283         uint offset, ielen, ie_offset, remainder_ielen = 0;\r
284         u8      *pie = pnetwork->IEs;\r
285 \r
286         p = rtw_get_ie(pie + _FIXED_IE_LENGTH_, index, &ielen, pnetwork->IELength - _FIXED_IE_LENGTH_);\r
287         if (p != NULL && ielen>0)\r
288         {\r
289                 ielen += 2;\r
290                 \r
291                 premainder_ie = p+ielen;\r
292 \r
293                 ie_offset = (sint)(p -pie);\r
294                 \r
295                 remainder_ielen = pnetwork->IELength - ie_offset - ielen;\r
296 \r
297                 dst_ie = p;\r
298         }\r
299         else {\r
300                 return;\r
301         }\r
302 \r
303         if(remainder_ielen>0)\r
304         {\r
305                 pbackup_remainder_ie = rtw_malloc(remainder_ielen);\r
306                 if(pbackup_remainder_ie && premainder_ie)\r
307                         _rtw_memcpy(pbackup_remainder_ie, premainder_ie, remainder_ielen);\r
308         }\r
309 \r
310         //copy remainder IE\r
311         if(pbackup_remainder_ie)\r
312         {\r
313                 _rtw_memcpy(dst_ie, pbackup_remainder_ie, remainder_ielen);\r
314 \r
315                 rtw_mfree(pbackup_remainder_ie, remainder_ielen);\r
316         }\r
317 \r
318         offset =  (uint)(dst_ie - pie);\r
319         pnetwork->IELength = offset + remainder_ielen;\r
320 }\r
321 \r
322 \r
323 u8 chk_sta_is_alive(struct sta_info *psta);\r
324 u8 chk_sta_is_alive(struct sta_info *psta)\r
325 {\r
326         u8 ret = _FALSE;\r
327         #ifdef DBG_EXPIRATION_CHK\r
328         DBG_871X("sta:"MAC_FMT", rssi:%d, rx:"STA_PKTS_FMT", expire_to:%u, %s%ssq_len:%u\n"\r
329                 , MAC_ARG(psta->hwaddr)\r
330                 , psta->rssi_stat.UndecoratedSmoothedPWDB\r
331                 //, STA_RX_PKTS_ARG(psta)\r
332                 , STA_RX_PKTS_DIFF_ARG(psta)\r
333                 , psta->expire_to\r
334                 , psta->state&WIFI_SLEEP_STATE?"PS, ":""\r
335                 , psta->state&WIFI_STA_ALIVE_CHK_STATE?"SAC, ":""\r
336                 , psta->sleepq_len\r
337         );\r
338         #endif\r
339 \r
340         //if(sta_last_rx_pkts(psta) == sta_rx_pkts(psta))\r
341         if((psta->sta_stats.last_rx_data_pkts + psta->sta_stats.last_rx_ctrl_pkts) == (psta->sta_stats.rx_data_pkts + psta->sta_stats.rx_ctrl_pkts))\r
342         {\r
343                 #if 0\r
344                 if(psta->state&WIFI_SLEEP_STATE)\r
345                         ret = _TRUE;\r
346                 #endif\r
347         }\r
348         else\r
349         {\r
350                 ret = _TRUE;\r
351         }\r
352 \r
353         sta_update_last_rx_pkts(psta);\r
354 \r
355         return ret;\r
356 }\r
357 \r
358 void    expire_timeout_chk(_adapter *padapter)\r
359 {\r
360         _irqL irqL;\r
361         _list   *phead, *plist;\r
362         u8 updated = _FALSE;\r
363         struct sta_info *psta=NULL;     \r
364         struct sta_priv *pstapriv = &padapter->stapriv;\r
365         u8 chk_alive_num = 0;\r
366         char chk_alive_list[NUM_STA];\r
367         int i;\r
368 \r
369 \r
370         _enter_critical_bh(&pstapriv->auth_list_lock, &irqL);\r
371         \r
372         phead = &pstapriv->auth_list;\r
373         plist = get_next(phead);\r
374         \r
375         //check auth_queue\r
376         #ifdef DBG_EXPIRATION_CHK\r
377         if (rtw_end_of_queue_search(phead, plist) == _FALSE) {\r
378                 DBG_871X(FUNC_NDEV_FMT" auth_list, cnt:%u\n"\r
379                         , FUNC_NDEV_ARG(padapter->pnetdev), pstapriv->auth_list_cnt);\r
380         }\r
381         #endif\r
382         while ((rtw_end_of_queue_search(phead, plist)) == _FALSE)       \r
383         {\r
384                 psta = LIST_CONTAINOR(plist, struct sta_info, auth_list);\r
385 \r
386                 plist = get_next(plist);\r
387 \r
388 \r
389 #ifdef CONFIG_ATMEL_RC_PATCH\r
390                 if (_TRUE == _rtw_memcmp((void *)(pstapriv->atmel_rc_pattern), (void *)(psta->hwaddr), ETH_ALEN))\r
391                         continue;\r
392                 if (psta->flag_atmel_rc)\r
393                         continue;\r
394 #endif\r
395                 if(psta->expire_to>0)\r
396                 {\r
397                         psta->expire_to--;\r
398                         if (psta->expire_to == 0)\r
399                         {\r
400                                 rtw_list_delete(&psta->auth_list);\r
401                                 pstapriv->auth_list_cnt--;\r
402                                 \r
403                                 DBG_871X("auth expire %02X%02X%02X%02X%02X%02X\n",\r
404                                         psta->hwaddr[0],psta->hwaddr[1],psta->hwaddr[2],psta->hwaddr[3],psta->hwaddr[4],psta->hwaddr[5]);\r
405                                 \r
406                                 _exit_critical_bh(&pstapriv->auth_list_lock, &irqL);\r
407                                 \r
408                                 _enter_critical_bh(&(pstapriv->sta_hash_lock), &irqL);  \r
409                                 rtw_free_stainfo(padapter, psta);\r
410                                 _exit_critical_bh(&(pstapriv->sta_hash_lock), &irqL);   \r
411                                 \r
412                                 _enter_critical_bh(&pstapriv->auth_list_lock, &irqL);\r
413                         }       \r
414                 }       \r
415                 \r
416         }\r
417 \r
418         _exit_critical_bh(&pstapriv->auth_list_lock, &irqL);\r
419         psta = NULL;\r
420         \r
421 \r
422         _enter_critical_bh(&pstapriv->asoc_list_lock, &irqL);\r
423         \r
424         phead = &pstapriv->asoc_list;\r
425         plist = get_next(phead);\r
426 \r
427         //check asoc_queue\r
428         #ifdef DBG_EXPIRATION_CHK\r
429         if (rtw_end_of_queue_search(phead, plist) == _FALSE) {\r
430                 DBG_871X(FUNC_NDEV_FMT" asoc_list, cnt:%u\n"\r
431                         , FUNC_NDEV_ARG(padapter->pnetdev), pstapriv->asoc_list_cnt);\r
432         }\r
433         #endif\r
434         while ((rtw_end_of_queue_search(phead, plist)) == _FALSE)\r
435         {\r
436                 psta = LIST_CONTAINOR(plist, struct sta_info, asoc_list);\r
437                 plist = get_next(plist);\r
438 #ifdef CONFIG_ATMEL_RC_PATCH\r
439                 DBG_871X("%s:%d  psta=%p, %02x,%02x||%02x,%02x  \n\n", __func__,  __LINE__,\r
440                         psta,pstapriv->atmel_rc_pattern[0], pstapriv->atmel_rc_pattern[5], psta->hwaddr[0], psta->hwaddr[5]);\r
441                 if (_TRUE == _rtw_memcmp((void *)pstapriv->atmel_rc_pattern, (void *)(psta->hwaddr), ETH_ALEN))\r
442                         continue;               \r
443                 if (psta->flag_atmel_rc)\r
444                         continue;\r
445                 DBG_871X("%s: debug line:%d \n", __func__, __LINE__);\r
446 #endif\r
447 #ifdef CONFIG_AUTO_AP_MODE\r
448                 if(psta->isrc)\r
449                         continue;\r
450 #endif\r
451                 if (chk_sta_is_alive(psta) || !psta->expire_to) {\r
452                         psta->expire_to = pstapriv->expire_to;\r
453                         psta->keep_alive_trycnt = 0;\r
454                         #ifdef CONFIG_TX_MCAST2UNI\r
455                         psta->under_exist_checking = 0;\r
456                         #endif  // CONFIG_TX_MCAST2UNI\r
457                 } else {\r
458                         psta->expire_to--;\r
459                 }\r
460 \r
461 #ifndef CONFIG_ACTIVE_KEEP_ALIVE_CHECK\r
462 #ifdef CONFIG_80211N_HT\r
463 #ifdef CONFIG_TX_MCAST2UNI\r
464                 if ( (psta->flags & WLAN_STA_HT) && (psta->htpriv.agg_enable_bitmap || psta->under_exist_checking) ) {\r
465                         // check sta by delba(addba) for 11n STA \r
466                         // ToDo: use CCX report to check for all STAs\r
467                         //DBG_871X("asoc check by DELBA/ADDBA! (pstapriv->expire_to=%d s)(psta->expire_to=%d s), [%02x, %d]\n", pstapriv->expire_to*2, psta->expire_to*2, psta->htpriv.agg_enable_bitmap, psta->under_exist_checking);\r
468                         \r
469                                 if ( psta->expire_to <= (pstapriv->expire_to - 50 ) ) {\r
470                                 DBG_871X("asoc expire by DELBA/ADDBA! (%d s)\n", (pstapriv->expire_to-psta->expire_to)*2);\r
471                                 psta->under_exist_checking = 0;\r
472                                 psta->expire_to = 0;\r
473                         } else if ( psta->expire_to <= (pstapriv->expire_to - 3) && (psta->under_exist_checking==0)) {\r
474                                 DBG_871X("asoc check by DELBA/ADDBA! (%d s)\n", (pstapriv->expire_to-psta->expire_to)*2);\r
475                                 psta->under_exist_checking = 1;\r
476                                 //tear down TX AMPDU\r
477                                 send_delba(padapter, 1, psta->hwaddr);// // originator\r
478                                 psta->htpriv.agg_enable_bitmap = 0x0;//reset\r
479                                 psta->htpriv.candidate_tid_bitmap = 0x0;//reset\r
480                         }\r
481                 }\r
482 #endif //CONFIG_TX_MCAST2UNI\r
483 #endif //CONFIG_80211N_HT\r
484 #endif //CONFIG_ACTIVE_KEEP_ALIVE_CHECK\r
485 \r
486                 if (psta->expire_to <= 0)\r
487                 {\r
488                         struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;\r
489 \r
490                         if (padapter->registrypriv.wifi_spec == 1)\r
491                         {\r
492                                 psta->expire_to = pstapriv->expire_to;\r
493                                 continue;\r
494                         }\r
495 \r
496 #ifndef CONFIG_ACTIVE_KEEP_ALIVE_CHECK\r
497 #ifdef CONFIG_80211N_HT\r
498 \r
499 #define KEEP_ALIVE_TRYCNT (3)\r
500 \r
501                         if(psta->keep_alive_trycnt > 0 && psta->keep_alive_trycnt <= KEEP_ALIVE_TRYCNT)\r
502                         {                               \r
503                                 if(psta->state & WIFI_STA_ALIVE_CHK_STATE)\r
504                                         psta->state ^= WIFI_STA_ALIVE_CHK_STATE;\r
505                                 else\r
506                                         psta->keep_alive_trycnt = 0;\r
507                                 \r
508                         }\r
509                         else if((psta->keep_alive_trycnt > KEEP_ALIVE_TRYCNT) && !(psta->state & WIFI_STA_ALIVE_CHK_STATE))\r
510                         {\r
511                                 psta->keep_alive_trycnt = 0;\r
512                         }                       \r
513                         if((psta->htpriv.ht_option==_TRUE) && (psta->htpriv.ampdu_enable==_TRUE)) \r
514                         {\r
515                                 uint priority = 1; //test using BK\r
516                                 u8 issued=0;                            \r
517                 \r
518                                 //issued = (psta->htpriv.agg_enable_bitmap>>priority)&0x1;\r
519                                 issued |= (psta->htpriv.candidate_tid_bitmap>>priority)&0x1;\r
520 \r
521                                 if(0==issued)\r
522                                 {\r
523                                         if (!(psta->state & WIFI_STA_ALIVE_CHK_STATE))\r
524                                         {\r
525                                                 psta->htpriv.candidate_tid_bitmap |= BIT((u8)priority);\r
526 \r
527                                                 if (psta->state & WIFI_SLEEP_STATE) \r
528                                                         psta->expire_to = 2; // 2x2=4 sec\r
529                                                 else\r
530                                                         psta->expire_to = 1; // 2 sec\r
531                                         \r
532                                                 psta->state |= WIFI_STA_ALIVE_CHK_STATE;\r
533                                         \r
534                                                 //add_ba_hdl(padapter, (u8*)paddbareq_parm);\r
535 \r
536                                                 DBG_871X("issue addba_req to check if sta alive, keep_alive_trycnt=%d\n", psta->keep_alive_trycnt);\r
537                                                 \r
538                                                 issue_action_BA(padapter, psta->hwaddr, RTW_WLAN_ACTION_ADDBA_REQ, (u16)priority);              \r
539                 \r
540                                                 _set_timer(&psta->addba_retry_timer, ADDBA_TO);\r
541                                                 \r
542                                                 psta->keep_alive_trycnt++;                                              \r
543 \r
544                                                 continue;\r
545                                         }                       \r
546                                 }                                       \r
547                         }\r
548                         if(psta->keep_alive_trycnt > 0 && psta->state & WIFI_STA_ALIVE_CHK_STATE)\r
549                         {\r
550                                 psta->keep_alive_trycnt = 0;\r
551                                 psta->state ^= WIFI_STA_ALIVE_CHK_STATE;\r
552                                 DBG_871X("change to another methods to check alive if staion is at ps mode\n");\r
553                         }       \r
554                         \r
555 #endif //CONFIG_80211N_HT\r
556 #endif //CONFIG_ACTIVE_KEEP_ALIVE_CHECK \r
557                         if (psta->state & WIFI_SLEEP_STATE) {\r
558                                 if (!(psta->state & WIFI_STA_ALIVE_CHK_STATE)) {\r
559                                         //to check if alive by another methods if staion is at ps mode.                                 \r
560                                         psta->expire_to = pstapriv->expire_to;\r
561                                         psta->state |= WIFI_STA_ALIVE_CHK_STATE;\r
562 \r
563                                         //DBG_871X("alive chk, sta:" MAC_FMT " is at ps mode!\n", MAC_ARG(psta->hwaddr));\r
564 \r
565                                         //to update bcn with tim_bitmap for this station\r
566                                         pstapriv->tim_bitmap |= BIT(psta->aid);\r
567                                         update_beacon(padapter, _TIM_IE_, NULL, _TRUE);\r
568 \r
569                                         if(!pmlmeext->active_keep_alive_check)\r
570                                                 continue;\r
571                                 }\r
572                         }\r
573                         #ifdef CONFIG_ACTIVE_KEEP_ALIVE_CHECK\r
574                         if (pmlmeext->active_keep_alive_check) {\r
575                                 int stainfo_offset;\r
576 \r
577                                 stainfo_offset = rtw_stainfo_offset(pstapriv, psta);\r
578                                 if (stainfo_offset_valid(stainfo_offset)) {\r
579                                         chk_alive_list[chk_alive_num++] = stainfo_offset;\r
580                                 }\r
581 \r
582                                 continue;\r
583                         }\r
584                         #endif /* CONFIG_ACTIVE_KEEP_ALIVE_CHECK */\r
585                         rtw_list_delete(&psta->asoc_list);\r
586                         pstapriv->asoc_list_cnt--;\r
587                         DBG_871X("asoc expire "MAC_FMT", state=0x%x\n", MAC_ARG(psta->hwaddr), psta->state);\r
588                         updated = ap_free_sta(padapter, psta, _FALSE, WLAN_REASON_DEAUTH_LEAVING);\r
589                 }       \r
590                 else\r
591                 {\r
592                         /* TODO: Aging mechanism to digest frames in sleep_q to avoid running out of xmitframe */\r
593                         if (psta->sleepq_len > (NR_XMITFRAME/pstapriv->asoc_list_cnt)\r
594                                 && padapter->xmitpriv.free_xmitframe_cnt < ((NR_XMITFRAME/pstapriv->asoc_list_cnt)/2)\r
595                         ){\r
596                                 DBG_871X("%s sta:"MAC_FMT", sleepq_len:%u, free_xmitframe_cnt:%u, asoc_list_cnt:%u, clear sleep_q\n", __func__\r
597                                         , MAC_ARG(psta->hwaddr)\r
598                                         , psta->sleepq_len, padapter->xmitpriv.free_xmitframe_cnt, pstapriv->asoc_list_cnt);\r
599                                 wakeup_sta_to_xmit(padapter, psta);\r
600                         }\r
601                 }\r
602         }\r
603 \r
604         _exit_critical_bh(&pstapriv->asoc_list_lock, &irqL);\r
605 \r
606 #ifdef CONFIG_ACTIVE_KEEP_ALIVE_CHECK\r
607 if (chk_alive_num) {\r
608 \r
609         u8 backup_oper_channel=0;\r
610         struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;\r
611         /* switch to correct channel of current network  before issue keep-alive frames */\r
612         if (rtw_get_oper_ch(padapter) != pmlmeext->cur_channel) {\r
613                 backup_oper_channel = rtw_get_oper_ch(padapter);\r
614                 SelectChannel(padapter, pmlmeext->cur_channel);\r
615         }\r
616 \r
617         /* issue null data to check sta alive*/\r
618         for (i = 0; i < chk_alive_num; i++) {\r
619                 int ret = _FAIL;\r
620 \r
621                 psta = rtw_get_stainfo_by_offset(pstapriv, chk_alive_list[i]);\r
622 #ifdef CONFIG_ATMEL_RC_PATCH\r
623                 if (_TRUE == _rtw_memcmp(  pstapriv->atmel_rc_pattern, psta->hwaddr, ETH_ALEN))\r
624                         continue;\r
625                 if (psta->flag_atmel_rc)\r
626                         continue;\r
627 #endif\r
628                 if(!(psta->state &_FW_LINKED))\r
629                         continue;               \r
630         \r
631                 if (psta->state & WIFI_SLEEP_STATE)\r
632                         ret = issue_nulldata(padapter, psta->hwaddr, 0, 1, 50);\r
633                 else\r
634                         ret = issue_nulldata(padapter, psta->hwaddr, 0, 3, 50);\r
635 \r
636                 psta->keep_alive_trycnt++;\r
637                 if (ret == _SUCCESS)\r
638                 {\r
639                         DBG_871X("asoc check, sta(" MAC_FMT ") is alive\n", MAC_ARG(psta->hwaddr));\r
640                         psta->expire_to = pstapriv->expire_to;\r
641                         psta->keep_alive_trycnt = 0;\r
642                         continue;\r
643                 }\r
644                 else if (psta->keep_alive_trycnt <= 3)\r
645                 {\r
646                         DBG_871X("ack check for asoc expire, keep_alive_trycnt=%d\n", psta->keep_alive_trycnt);\r
647                         psta->expire_to = 1;\r
648                         continue;\r
649                 }\r
650 \r
651                 psta->keep_alive_trycnt = 0;\r
652                 DBG_871X("asoc expire "MAC_FMT", state=0x%x\n", MAC_ARG(psta->hwaddr), psta->state);\r
653                 _enter_critical_bh(&pstapriv->asoc_list_lock, &irqL);\r
654                 if (rtw_is_list_empty(&psta->asoc_list)==_FALSE) {\r
655                         rtw_list_delete(&psta->asoc_list);\r
656                         pstapriv->asoc_list_cnt--;\r
657                         updated = ap_free_sta(padapter, psta, _FALSE, WLAN_REASON_DEAUTH_LEAVING);\r
658                 }\r
659                 _exit_critical_bh(&pstapriv->asoc_list_lock, &irqL);\r
660 \r
661         }\r
662 \r
663         if (backup_oper_channel>0) /* back to the original operation channel */\r
664                 SelectChannel(padapter, backup_oper_channel);\r
665 }\r
666 #endif /* CONFIG_ACTIVE_KEEP_ALIVE_CHECK */\r
667 \r
668         associated_clients_update(padapter, updated);\r
669 }\r
670 \r
671 void add_RATid(_adapter *padapter, struct sta_info *psta, u8 rssi_level)\r
672 {       \r
673         int i;\r
674         u8 rf_type;\r
675         unsigned char sta_band = 0, shortGIrate = _FALSE;\r
676         unsigned int tx_ra_bitmap=0;\r
677         struct ht_priv  *psta_ht = NULL;\r
678         struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);\r
679         WLAN_BSSID_EX *pcur_network = (WLAN_BSSID_EX *)&pmlmepriv->cur_network.network;\r
680 \r
681 #ifdef CONFIG_80211N_HT\r
682         if(psta)\r
683                 psta_ht = &psta->htpriv;\r
684         else\r
685                 return;\r
686 #endif //CONFIG_80211N_HT\r
687 \r
688         if(!(psta->state & _FW_LINKED))\r
689                 return;\r
690 \r
691 #if 0//gtest\r
692         if(get_rf_mimo_mode(padapter) == RTL8712_RF_2T2R)\r
693         {\r
694                 //is this a 2r STA?\r
695                 if((pstat->tx_ra_bitmap & 0x0ff00000) != 0 && !(priv->pshare->has_2r_sta & BIT(pstat->aid)))\r
696                 {\r
697                         priv->pshare->has_2r_sta |= BIT(pstat->aid);\r
698                         if(rtw_read16(padapter, 0x102501f6) != 0xffff)\r
699                         {\r
700                                 rtw_write16(padapter, 0x102501f6, 0xffff);\r
701                                 reset_1r_sta_RA(priv, 0xffff);\r
702                                 Switch_1SS_Antenna(priv, 3);\r
703                         }\r
704                 }\r
705                 else// bg or 1R STA? \r
706                 { \r
707                         if((priv->pmib->dot11BssType.net_work_type & WIRELESS_11N) && pstat->ht_cap_len && priv->pshare->has_2r_sta == 0)\r
708                         {\r
709                                 if(rtw_read16(padapter, 0x102501f6) != 0x7777)\r
710                                 { // MCS7 SGI\r
711                                         rtw_write16(padapter, 0x102501f6,0x7777);\r
712                                         reset_1r_sta_RA(priv, 0x7777);\r
713                                         Switch_1SS_Antenna(priv, 2);\r
714                                 }\r
715                         }\r
716                 }\r
717                 \r
718         }\r
719 \r
720         if ((pstat->rssi_level < 1) || (pstat->rssi_level > 3)) \r
721         {\r
722                 if (pstat->rssi >= priv->pshare->rf_ft_var.raGoDownUpper)\r
723                         pstat->rssi_level = 1;\r
724                 else if ((pstat->rssi >= priv->pshare->rf_ft_var.raGoDown20MLower) ||\r
725                         ((priv->pshare->is_40m_bw) && (pstat->ht_cap_len) &&\r
726                         (pstat->rssi >= priv->pshare->rf_ft_var.raGoDown40MLower) &&\r
727                         (pstat->ht_cap_buf.ht_cap_info & cpu_to_le16(_HTCAP_SUPPORT_CH_WDTH_))))\r
728                         pstat->rssi_level = 2;\r
729                 else\r
730                         pstat->rssi_level = 3;\r
731         }\r
732 \r
733         // rate adaptive by rssi\r
734         if ((priv->pmib->dot11BssType.net_work_type & WIRELESS_11N) && pstat->ht_cap_len)\r
735         {\r
736                 if ((get_rf_mimo_mode(priv) == MIMO_1T2R) || (get_rf_mimo_mode(priv) == MIMO_1T1R))\r
737                 {\r
738                         switch (pstat->rssi_level) {\r
739                                 case 1:\r
740                                         pstat->tx_ra_bitmap &= 0x100f0000;\r
741                                         break;\r
742                                 case 2:\r
743                                         pstat->tx_ra_bitmap &= 0x100ff000;\r
744                                         break;\r
745                                 case 3:\r
746                                         if (priv->pshare->is_40m_bw)\r
747                                                 pstat->tx_ra_bitmap &= 0x100ff005;\r
748                                         else\r
749                                                 pstat->tx_ra_bitmap &= 0x100ff001;\r
750 \r
751                                         break;\r
752                         }\r
753                 }\r
754                 else \r
755                 {\r
756                         switch (pstat->rssi_level) {\r
757                                 case 1:\r
758                                         pstat->tx_ra_bitmap &= 0x1f0f0000;\r
759                                         break;\r
760                                 case 2:\r
761                                         pstat->tx_ra_bitmap &= 0x1f0ff000;\r
762                                         break;\r
763                                 case 3:\r
764                                         if (priv->pshare->is_40m_bw)\r
765                                                 pstat->tx_ra_bitmap &= 0x000ff005;\r
766                                         else\r
767                                                 pstat->tx_ra_bitmap &= 0x000ff001;\r
768 \r
769                                         break;\r
770                         }\r
771 \r
772                         // Don't need to mask high rates due to new rate adaptive parameters\r
773                         //if (pstat->is_broadcom_sta)           // use MCS12 as the highest rate vs. Broadcom sta\r
774                         //      pstat->tx_ra_bitmap &= 0x81ffffff;\r
775 \r
776                         // NIC driver will report not supporting MCS15 and MCS14 in asoc req\r
777                         //if (pstat->is_rtl8190_sta && !pstat->is_2t_mimo_sta)\r
778                         //      pstat->tx_ra_bitmap &= 0x83ffffff;              // if Realtek 1x2 sta, don't use MCS15 and MCS14\r
779                 }\r
780         }\r
781         else if ((priv->pmib->dot11BssType.net_work_type & WIRELESS_11G) && isErpSta(pstat))\r
782         {\r
783                 switch (pstat->rssi_level) {\r
784                         case 1:\r
785                                 pstat->tx_ra_bitmap &= 0x00000f00;\r
786                                 break;\r
787                         case 2:\r
788                                 pstat->tx_ra_bitmap &= 0x00000ff0;\r
789                                 break;\r
790                         case 3:\r
791                                 pstat->tx_ra_bitmap &= 0x00000ff5;\r
792                                 break;\r
793                 }\r
794         }\r
795         else \r
796         {\r
797                 pstat->tx_ra_bitmap &= 0x0000000d;\r
798         }\r
799 \r
800         // disable tx short GI when station cannot rx MCS15(AP is 2T2R)\r
801         // disable tx short GI when station cannot rx MCS7 (AP is 1T2R or 1T1R)\r
802         // if there is only 1r STA and we are 2T2R, DO NOT mask SGI rate\r
803         if ((!(pstat->tx_ra_bitmap & 0x8000000) && (priv->pshare->has_2r_sta > 0) && (get_rf_mimo_mode(padapter) == RTL8712_RF_2T2R)) ||\r
804                  (!(pstat->tx_ra_bitmap & 0x80000) && (get_rf_mimo_mode(padapter) != RTL8712_RF_2T2R)))\r
805         {\r
806                 pstat->tx_ra_bitmap &= ~BIT(28);        \r
807         }\r
808 #endif\r
809 \r
810         rtw_hal_update_sta_rate_mask(padapter, psta);\r
811         tx_ra_bitmap = psta->ra_mask;\r
812 \r
813         shortGIrate = query_ra_short_GI(psta);\r
814 \r
815         if ( pcur_network->Configuration.DSConfig > 14 ) {\r
816                 \r
817                 if (tx_ra_bitmap & 0xffff000)\r
818                         sta_band |= WIRELESS_11_5N ;\r
819 \r
820                 if (tx_ra_bitmap & 0xff0)\r
821                         sta_band |= WIRELESS_11A;\r
822 \r
823                 // 5G band\r
824                 #ifdef CONFIG_80211AC_VHT\r
825                 if (psta->vhtpriv.vht_option)  {\r
826                         sta_band = WIRELESS_11_5AC;\r
827                 }               \r
828                 #endif\r
829                 \r
830         } else {\r
831                 if (tx_ra_bitmap & 0xffff000)\r
832                         sta_band |= WIRELESS_11_24N;\r
833 \r
834                 if (tx_ra_bitmap & 0xff0)\r
835                         sta_band |= WIRELESS_11G;\r
836 \r
837                 if (tx_ra_bitmap & 0x0f)\r
838                         sta_band |= WIRELESS_11B;\r
839         }\r
840 \r
841         psta->wireless_mode = sta_band;\r
842         psta->raid = rtw_hal_networktype_to_raid(padapter, psta);\r
843         \r
844         if (psta->aid < NUM_STA) \r
845         {\r
846                 u8      arg[4] = {0};\r
847 \r
848                 arg[0] = psta->mac_id;\r
849                 arg[1] = psta->raid;\r
850                 arg[2] = shortGIrate;\r
851                 arg[3] = psta->init_rate;\r
852 \r
853                 DBG_871X("%s=> mac_id:%d , raid:%d , shortGIrate=%d, bitmap=0x%x\n", \r
854                         __FUNCTION__ , psta->mac_id, psta->raid ,shortGIrate, tx_ra_bitmap);\r
855 \r
856                 rtw_hal_add_ra_tid(padapter, tx_ra_bitmap, arg, rssi_level);\r
857         }\r
858         else \r
859         {\r
860                 DBG_871X("station aid %d exceed the max number\n", psta->aid);\r
861         }\r
862 \r
863 }\r
864 \r
865 void update_bmc_sta(_adapter *padapter)\r
866 {\r
867         _irqL   irqL;\r
868         unsigned char   network_type;\r
869         int supportRateNum = 0;\r
870         unsigned int tx_ra_bitmap=0;\r
871         struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);\r
872         struct mlme_ext_priv    *pmlmeext = &(padapter->mlmeextpriv);\r
873         struct mlme_ext_info    *pmlmeinfo = &(pmlmeext->mlmext_info);  \r
874         WLAN_BSSID_EX *pcur_network = (WLAN_BSSID_EX *)&pmlmepriv->cur_network.network; \r
875         struct sta_info *psta = rtw_get_bcmc_stainfo(padapter);\r
876 \r
877         if(psta)\r
878         {\r
879                 psta->aid = 0;//default set to 0\r
880                 //psta->mac_id = psta->aid+4;   \r
881                 psta->mac_id = psta->aid + 1;//mac_id=1 for bc/mc stainfo\r
882 \r
883                 pmlmeinfo->FW_sta_info[psta->mac_id].psta = psta;\r
884 \r
885                 psta->qos_option = 0;\r
886 #ifdef CONFIG_80211N_HT \r
887                 psta->htpriv.ht_option = _FALSE;\r
888 #endif //CONFIG_80211N_HT\r
889 \r
890                 psta->ieee8021x_blocked = 0;\r
891 \r
892                 _rtw_memset((void*)&psta->sta_stats, 0, sizeof(struct stainfo_stats));\r
893 \r
894                 //psta->dot118021XPrivacy = _NO_PRIVACY_;//!!! remove it, because it has been set before this.\r
895 \r
896                 //prepare for add_RATid         \r
897                 supportRateNum = rtw_get_rateset_len((u8*)&pcur_network->SupportedRates);\r
898                 network_type = rtw_check_network_type((u8*)&pcur_network->SupportedRates, supportRateNum, pcur_network->Configuration.DSConfig);\r
899                 if (IsSupportedTxCCK(network_type)) {\r
900                         network_type = WIRELESS_11B;\r
901                 }\r
902                 else if (network_type == WIRELESS_INVALID) { // error handling\r
903                         if ( pcur_network->Configuration.DSConfig > 14 )\r
904                                 network_type = WIRELESS_11A;\r
905                         else\r
906                                 network_type = WIRELESS_11B;\r
907                 }\r
908                 update_sta_basic_rate(psta, network_type);\r
909                 psta->wireless_mode = network_type;\r
910 \r
911                 rtw_hal_update_sta_rate_mask(padapter, psta);\r
912                 tx_ra_bitmap = psta->ra_mask;\r
913 \r
914                 psta->raid = rtw_hal_networktype_to_raid(padapter,psta);\r
915 \r
916                 //ap mode\r
917                 rtw_hal_set_odm_var(padapter, HAL_ODM_STA_INFO, psta, _TRUE);\r
918 \r
919                 //if(pHalData->fw_ractrl == _TRUE)\r
920                 {\r
921                         u8      arg[4] = {0};\r
922 \r
923                         arg[0] = psta->mac_id;\r
924                         arg[1] = psta->raid;\r
925                         arg[2] = 0;\r
926                         arg[3] = psta->init_rate;\r
927 \r
928                         DBG_871X("%s=> mac_id:%d , raid:%d , bitmap=0x%x\n", \r
929                                 __FUNCTION__ , psta->mac_id, psta->raid , tx_ra_bitmap);\r
930 \r
931                         rtw_hal_add_ra_tid(padapter, tx_ra_bitmap, arg, 0);\r
932                 }\r
933 \r
934                 rtw_sta_media_status_rpt(padapter, psta, 1);\r
935 \r
936                 _enter_critical_bh(&psta->lock, &irqL);\r
937                 psta->state = _FW_LINKED;\r
938                 _exit_critical_bh(&psta->lock, &irqL);\r
939 \r
940         }\r
941         else\r
942         {\r
943                 DBG_871X("add_RATid_bmc_sta error!\n");\r
944         }\r
945                 \r
946 }\r
947 \r
948 //notes:\r
949 //AID: 1~MAX for sta and 0 for bc/mc in ap/adhoc mode \r
950 //MAC_ID = AID+1 for sta in ap/adhoc mode \r
951 //MAC_ID = 1 for bc/mc for sta/ap/adhoc\r
952 //MAC_ID = 0 for bssid for sta/ap/adhoc\r
953 //CAM_ID = //0~3 for default key, cmd_id=macid + 3, macid=aid+1;\r
954 \r
955 void update_sta_info_apmode(_adapter *padapter, struct sta_info *psta)\r
956 {       \r
957         _irqL   irqL;\r
958         struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);\r
959         struct security_priv *psecuritypriv = &padapter->securitypriv;\r
960         struct mlme_ext_priv    *pmlmeext = &(padapter->mlmeextpriv);\r
961 #ifdef CONFIG_80211N_HT\r
962         struct ht_priv  *phtpriv_ap = &pmlmepriv->htpriv;\r
963         struct ht_priv  *phtpriv_sta = &psta->htpriv;\r
964 #endif //CONFIG_80211N_HT\r
965         u8      cur_ldpc_cap=0, cur_stbc_cap=0, cur_beamform_cap=0;\r
966         //set intf_tag to if1\r
967         //psta->intf_tag = 0;\r
968 \r
969         DBG_871X("%s\n",__FUNCTION__);\r
970 \r
971         //psta->mac_id = psta->aid+4;\r
972         //psta->mac_id = psta->aid+1;//alloc macid when call rtw_alloc_stainfo(),\r
973                                                        //release macid when call rtw_free_stainfo()\r
974 \r
975         //ap mode\r
976         rtw_hal_set_odm_var(padapter,HAL_ODM_STA_INFO,psta,_TRUE);\r
977         \r
978         if(psecuritypriv->dot11AuthAlgrthm==dot11AuthAlgrthm_8021X)\r
979                 psta->ieee8021x_blocked = _TRUE;\r
980         else\r
981                 psta->ieee8021x_blocked = _FALSE;\r
982         \r
983 \r
984         //update sta's cap\r
985         \r
986         //ERP\r
987         VCS_update(padapter, psta);\r
988 #ifdef CONFIG_80211N_HT \r
989         //HT related cap\r
990         if(phtpriv_sta->ht_option)\r
991         {\r
992                 //check if sta supports rx ampdu\r
993                 phtpriv_sta->ampdu_enable = phtpriv_ap->ampdu_enable;\r
994 \r
995                 //check if sta support s Short GI 20M\r
996                 if((phtpriv_sta->ht_cap.cap_info & phtpriv_ap->ht_cap.cap_info) & cpu_to_le16(IEEE80211_HT_CAP_SGI_20))\r
997                 {\r
998                         phtpriv_sta->sgi_20m = _TRUE;\r
999                 }\r
1000                 //check if sta support s Short GI 40M\r
1001                 if((phtpriv_sta->ht_cap.cap_info & phtpriv_ap->ht_cap.cap_info) & cpu_to_le16(IEEE80211_HT_CAP_SGI_40))\r
1002                 {\r
1003                         phtpriv_sta->sgi_40m = _TRUE;\r
1004                 }\r
1005 \r
1006                 // bwmode\r
1007                 if((phtpriv_sta->ht_cap.cap_info & phtpriv_ap->ht_cap.cap_info) & cpu_to_le16(IEEE80211_HT_CAP_SUP_WIDTH))\r
1008                 {\r
1009                         phtpriv_sta->ch_offset = pmlmeext->cur_ch_offset;\r
1010                         psta->bw_mode = CHANNEL_WIDTH_40;\r
1011                 }\r
1012                 else\r
1013                 {\r
1014                         psta->bw_mode = CHANNEL_WIDTH_20;\r
1015                 }\r
1016 \r
1017                 psta->qos_option = _TRUE;\r
1018 \r
1019                 // B0 Config LDPC Coding Capability\r
1020                 if (TEST_FLAG(phtpriv_ap->ldpc_cap, LDPC_HT_ENABLE_TX) && \r
1021                         GET_HT_CAPABILITY_ELE_LDPC_CAP((u8 *)(&phtpriv_sta->ht_cap)))\r
1022                 {\r
1023                         SET_FLAG(cur_ldpc_cap, (LDPC_HT_ENABLE_TX | LDPC_HT_CAP_TX));\r
1024                         DBG_871X("Enable HT Tx LDPC for STA(%d)\n",psta->aid);\r
1025                 }\r
1026 \r
1027                 // B7 B8 B9 Config STBC setting\r
1028                 if (TEST_FLAG(phtpriv_ap->stbc_cap, STBC_HT_ENABLE_TX) &&\r
1029                         GET_HT_CAPABILITY_ELE_RX_STBC((u8 *)(&phtpriv_sta->ht_cap)))\r
1030                 {\r
1031                         SET_FLAG(cur_stbc_cap, (STBC_HT_ENABLE_TX | STBC_HT_CAP_TX) );\r
1032                         DBG_871X("Enable HT Tx STBC for STA(%d)\n",psta->aid);\r
1033                 }\r
1034 \r
1035 #ifdef CONFIG_BEAMFORMING\r
1036                 // Config Tx beamforming setting\r
1037                 if (TEST_FLAG(phtpriv_ap->beamform_cap, BEAMFORMING_HT_BEAMFORMEE_ENABLE) && \r
1038                         GET_HT_CAP_TXBF_EXPLICIT_COMP_STEERING_CAP((u8 *)(&phtpriv_sta->ht_cap)))\r
1039                 {\r
1040                         SET_FLAG(cur_beamform_cap, BEAMFORMING_HT_BEAMFORMER_ENABLE);\r
1041                 }\r
1042 \r
1043                 if (TEST_FLAG(phtpriv_ap->beamform_cap, BEAMFORMING_HT_BEAMFORMER_ENABLE) &&\r
1044                         GET_HT_CAP_TXBF_EXPLICIT_COMP_FEEDBACK_CAP((u8 *)(&phtpriv_sta->ht_cap)))\r
1045                 {\r
1046                         SET_FLAG(cur_beamform_cap, BEAMFORMING_HT_BEAMFORMEE_ENABLE);\r
1047                 }\r
1048 \r
1049                 if (cur_beamform_cap) {\r
1050                         DBG_871X("Client STA(%d) HT Beamforming Cap = 0x%02X\n", psta->aid, cur_beamform_cap);\r
1051                 }\r
1052 #endif //CONFIG_BEAMFORMING\r
1053         }\r
1054         else\r
1055         {\r
1056                 phtpriv_sta->ampdu_enable = _FALSE;\r
1057                 \r
1058                 phtpriv_sta->sgi_20m = _FALSE;\r
1059                 phtpriv_sta->sgi_40m = _FALSE;\r
1060                 psta->bw_mode = CHANNEL_WIDTH_20;\r
1061                 phtpriv_sta->ch_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE;\r
1062         }\r
1063 \r
1064         phtpriv_sta->ldpc_cap = cur_ldpc_cap;\r
1065         phtpriv_sta->stbc_cap = cur_stbc_cap;\r
1066         phtpriv_sta->beamform_cap = cur_beamform_cap;\r
1067 \r
1068         //Rx AMPDU\r
1069         send_delba(padapter, 0, psta->hwaddr);// recipient\r
1070         \r
1071         //TX AMPDU\r
1072         send_delba(padapter, 1, psta->hwaddr);// // originator\r
1073         phtpriv_sta->agg_enable_bitmap = 0x0;//reset\r
1074         phtpriv_sta->candidate_tid_bitmap = 0x0;//reset\r
1075 #endif //CONFIG_80211N_HT\r
1076 \r
1077 #ifdef CONFIG_80211AC_VHT\r
1078         update_sta_vht_info_apmode(padapter, psta);\r
1079 #endif\r
1080 \r
1081         update_ldpc_stbc_cap(psta);\r
1082 \r
1083         //todo: init other variables\r
1084         \r
1085         _rtw_memset((void*)&psta->sta_stats, 0, sizeof(struct stainfo_stats));\r
1086 \r
1087 \r
1088         //add ratid\r
1089         //add_RATid(padapter, psta);//move to ap_sta_info_defer_update()\r
1090 \r
1091 \r
1092         _enter_critical_bh(&psta->lock, &irqL);\r
1093         psta->state |= _FW_LINKED;\r
1094         _exit_critical_bh(&psta->lock, &irqL);\r
1095         \r
1096 \r
1097 }\r
1098 \r
1099 static void update_ap_info(_adapter *padapter, struct sta_info *psta)\r
1100 {\r
1101         struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);\r
1102         WLAN_BSSID_EX *pnetwork = (WLAN_BSSID_EX *)&pmlmepriv->cur_network.network;\r
1103         struct security_priv *psecuritypriv = &padapter->securitypriv;\r
1104         struct mlme_ext_priv    *pmlmeext = &(padapter->mlmeextpriv);\r
1105 #ifdef CONFIG_80211N_HT\r
1106         struct ht_priv  *phtpriv_ap = &pmlmepriv->htpriv;\r
1107 #endif //CONFIG_80211N_HT\r
1108 \r
1109 \r
1110         psta->wireless_mode = pmlmeext->cur_wireless_mode;\r
1111 \r
1112         psta->bssratelen = rtw_get_rateset_len(pnetwork->SupportedRates);\r
1113         _rtw_memcpy(psta->bssrateset, pnetwork->SupportedRates, psta->bssratelen);\r
1114 \r
1115 #ifdef CONFIG_80211N_HT \r
1116         //HT related cap\r
1117         if(phtpriv_ap->ht_option)\r
1118         {\r
1119                 //check if sta supports rx ampdu\r
1120                 //phtpriv_ap->ampdu_enable = phtpriv_ap->ampdu_enable;\r
1121 \r
1122                 //check if sta support s Short GI 20M\r
1123                 if((phtpriv_ap->ht_cap.cap_info) & cpu_to_le16(IEEE80211_HT_CAP_SGI_20))\r
1124                 {\r
1125                         phtpriv_ap->sgi_20m = _TRUE;\r
1126                 }\r
1127                 //check if sta support s Short GI 40M\r
1128                 if((phtpriv_ap->ht_cap.cap_info) & cpu_to_le16(IEEE80211_HT_CAP_SGI_40))\r
1129                 {\r
1130                         phtpriv_ap->sgi_40m = _TRUE;\r
1131                 }\r
1132 \r
1133                 psta->qos_option = _TRUE;\r
1134         }\r
1135         else\r
1136         {\r
1137                 phtpriv_ap->ampdu_enable = _FALSE;\r
1138                 \r
1139                 phtpriv_ap->sgi_20m = _FALSE;\r
1140                 phtpriv_ap->sgi_40m = _FALSE;\r
1141         }\r
1142 \r
1143         psta->bw_mode = pmlmeext->cur_bwmode;\r
1144         phtpriv_ap->ch_offset = pmlmeext->cur_ch_offset;\r
1145 \r
1146         phtpriv_ap->agg_enable_bitmap = 0x0;//reset\r
1147         phtpriv_ap->candidate_tid_bitmap = 0x0;//reset\r
1148 \r
1149         _rtw_memcpy(&psta->htpriv, &pmlmepriv->htpriv, sizeof(struct ht_priv));\r
1150 \r
1151 #ifdef CONFIG_80211AC_VHT\r
1152         _rtw_memcpy(&psta->vhtpriv, &pmlmepriv->vhtpriv, sizeof(struct vht_priv));\r
1153 #endif //CONFIG_80211AC_VHT\r
1154 \r
1155 #endif //CONFIG_80211N_HT\r
1156 }\r
1157 \r
1158 static void update_hw_ht_param(_adapter *padapter)\r
1159 {\r
1160         unsigned char           max_AMPDU_len;\r
1161         unsigned char           min_MPDU_spacing;\r
1162         struct registry_priv     *pregpriv = &padapter->registrypriv;\r
1163         struct mlme_ext_priv    *pmlmeext = &padapter->mlmeextpriv;\r
1164         struct mlme_ext_info    *pmlmeinfo = &(pmlmeext->mlmext_info);\r
1165         \r
1166         DBG_871X("%s\n", __FUNCTION__);\r
1167         \r
1168 \r
1169         //handle A-MPDU parameter field\r
1170         /*      \r
1171                 AMPDU_para [1:0]:Max AMPDU Len => 0:8k , 1:16k, 2:32k, 3:64k\r
1172                 AMPDU_para [4:2]:Min MPDU Start Spacing \r
1173         */\r
1174         max_AMPDU_len = pmlmeinfo->HT_caps.u.HT_cap_element.AMPDU_para & 0x03;  \r
1175         \r
1176         min_MPDU_spacing = (pmlmeinfo->HT_caps.u.HT_cap_element.AMPDU_para & 0x1c) >> 2;        \r
1177 \r
1178         rtw_hal_set_hwreg(padapter, HW_VAR_AMPDU_MIN_SPACE, (u8 *)(&min_MPDU_spacing));\r
1179 \r
1180         rtw_hal_set_hwreg(padapter, HW_VAR_AMPDU_FACTOR, (u8 *)(&max_AMPDU_len));\r
1181 \r
1182         //\r
1183         // Config SM Power Save setting\r
1184         //\r
1185         pmlmeinfo->SM_PS = (pmlmeinfo->HT_caps.u.HT_cap_element.HT_caps_info & 0x0C) >> 2;\r
1186         if(pmlmeinfo->SM_PS == WLAN_HT_CAP_SM_PS_STATIC)\r
1187         {\r
1188                 /*u8 i;\r
1189                 //update the MCS rates\r
1190                 for (i = 0; i < 16; i++)\r
1191                 {\r
1192                         pmlmeinfo->HT_caps.HT_cap_element.MCS_rate[i] &= MCS_rate_1R[i];\r
1193                 }*/\r
1194                 DBG_871X("%s(): WLAN_HT_CAP_SM_PS_STATIC\n",__FUNCTION__);\r
1195         }\r
1196 \r
1197         //\r
1198         // Config current HT Protection mode.\r
1199         //\r
1200         //pmlmeinfo->HT_protection = pmlmeinfo->HT_info.infos[1] & 0x3;\r
1201 \r
1202 }\r
1203 \r
1204 void start_bss_network(_adapter *padapter, u8 *pbuf)\r
1205 {\r
1206         u8 *p;\r
1207         u8 val8, cur_channel, cur_bwmode, cur_ch_offset;\r
1208         u16 bcn_interval;\r
1209         u32     acparm; \r
1210         int     ie_len; \r
1211         struct registry_priv     *pregpriv = &padapter->registrypriv;\r
1212         struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);\r
1213         struct security_priv* psecuritypriv=&(padapter->securitypriv);  \r
1214         WLAN_BSSID_EX *pnetwork = (WLAN_BSSID_EX *)&pmlmepriv->cur_network.network;\r
1215         struct mlme_ext_priv    *pmlmeext = &(padapter->mlmeextpriv);\r
1216         struct mlme_ext_info    *pmlmeinfo = &(pmlmeext->mlmext_info);\r
1217         WLAN_BSSID_EX *pnetwork_mlmeext = &(pmlmeinfo->network);\r
1218         struct HT_info_element *pht_info=NULL;\r
1219 #ifdef CONFIG_P2P\r
1220         struct wifidirect_info  *pwdinfo = &(padapter->wdinfo);\r
1221 #endif //CONFIG_P2P\r
1222         u8      cbw40_enable=0;\r
1223         u8      change_band = _FALSE;\r
1224         \r
1225         //DBG_871X("%s\n", __FUNCTION__);\r
1226 \r
1227         bcn_interval = (u16)pnetwork->Configuration.BeaconPeriod;       \r
1228         cur_channel = pnetwork->Configuration.DSConfig;\r
1229         cur_bwmode = CHANNEL_WIDTH_20;\r
1230         cur_ch_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE;\r
1231         \r
1232 \r
1233         //check if there is wps ie, \r
1234         //if there is wpsie in beacon, the hostapd will update beacon twice when stating hostapd,\r
1235         //and at first time the security ie ( RSN/WPA IE) will not include in beacon.\r
1236         if(NULL == rtw_get_wps_ie(pnetwork->IEs+_FIXED_IE_LENGTH_, pnetwork->IELength-_FIXED_IE_LENGTH_, NULL, NULL))\r
1237         {\r
1238                 pmlmeext->bstart_bss = _TRUE;\r
1239         }\r
1240 \r
1241         //todo: update wmm, ht cap\r
1242         //pmlmeinfo->WMM_enable;\r
1243         //pmlmeinfo->HT_enable;\r
1244         if(pmlmepriv->qospriv.qos_option)\r
1245                 pmlmeinfo->WMM_enable = _TRUE;\r
1246 #ifdef CONFIG_80211N_HT\r
1247         if(pmlmepriv->htpriv.ht_option)\r
1248         {\r
1249                 pmlmeinfo->WMM_enable = _TRUE;\r
1250                 pmlmeinfo->HT_enable = _TRUE;\r
1251                 //pmlmeinfo->HT_info_enable = _TRUE;\r
1252                 //pmlmeinfo->HT_caps_enable = _TRUE;\r
1253 \r
1254                 update_hw_ht_param(padapter);\r
1255         }\r
1256 #endif //#CONFIG_80211N_HT\r
1257 \r
1258 #ifdef CONFIG_80211AC_VHT\r
1259         if(pmlmepriv->vhtpriv.vht_option) {\r
1260                 pmlmeinfo->VHT_enable = _TRUE;\r
1261                 update_hw_vht_param(padapter);\r
1262         }\r
1263 #endif //CONFIG_80211AC_VHT\r
1264 \r
1265         if(pmlmepriv->cur_network.join_res != _TRUE) //setting only at  first time\r
1266         {\r
1267                 //WEP Key will be set before this function, do not clear CAM.\r
1268                 if ((psecuritypriv->dot11PrivacyAlgrthm != _WEP40_) && (psecuritypriv->dot11PrivacyAlgrthm != _WEP104_))\r
1269                         flush_all_cam_entry(padapter);  //clear CAM\r
1270         }       \r
1271 \r
1272         //set MSR to AP_Mode            \r
1273         Set_MSR(padapter, _HW_STATE_AP_);       \r
1274                 \r
1275         //Set BSSID REG\r
1276         rtw_hal_set_hwreg(padapter, HW_VAR_BSSID, pnetwork->MacAddress);\r
1277 \r
1278         //Set EDCA param reg\r
1279 #ifdef CONFIG_CONCURRENT_MODE\r
1280         acparm = 0x005ea42b;\r
1281 #else\r
1282         acparm = 0x002F3217; // VO\r
1283 #endif\r
1284         rtw_hal_set_hwreg(padapter, HW_VAR_AC_PARAM_VO, (u8 *)(&acparm));\r
1285         acparm = 0x005E4317; // VI\r
1286         rtw_hal_set_hwreg(padapter, HW_VAR_AC_PARAM_VI, (u8 *)(&acparm));\r
1287         //acparm = 0x00105320; // BE\r
1288         acparm = 0x005ea42b;\r
1289         rtw_hal_set_hwreg(padapter, HW_VAR_AC_PARAM_BE, (u8 *)(&acparm));\r
1290         acparm = 0x0000A444; // BK\r
1291         rtw_hal_set_hwreg(padapter, HW_VAR_AC_PARAM_BK, (u8 *)(&acparm));\r
1292 \r
1293         //Set Security\r
1294         val8 = (psecuritypriv->dot11AuthAlgrthm == dot11AuthAlgrthm_8021X)? 0xcc: 0xcf;\r
1295         rtw_hal_set_hwreg(padapter, HW_VAR_SEC_CFG, (u8 *)(&val8));\r
1296 \r
1297         //Beacon Control related register\r
1298         rtw_hal_set_hwreg(padapter, HW_VAR_BEACON_INTERVAL, (u8 *)(&bcn_interval));\r
1299 \r
1300         rtw_hal_set_hwreg(padapter, HW_VAR_DO_IQK, NULL);\r
1301 \r
1302         if(pmlmepriv->cur_network.join_res != _TRUE) //setting only at  first time\r
1303         {\r
1304                 //u32 initialgain;\r
1305 \r
1306                 //initialgain = 0x1e;\r
1307 \r
1308 \r
1309                 //disable dynamic functions, such as high power, DIG\r
1310                 //Save_DM_Func_Flag(padapter);\r
1311                 //Switch_DM_Func(padapter, DYNAMIC_FUNC_DISABLE, _FALSE);\r
1312                 \r
1313                 //turn on all dynamic functions \r
1314                 Switch_DM_Func(padapter, DYNAMIC_ALL_FUNC_ENABLE, _TRUE);\r
1315 \r
1316                 //rtw_hal_set_hwreg(padapter, HW_VAR_INITIAL_GAIN, (u8 *)(&initialgain));\r
1317         \r
1318         }\r
1319 #ifdef CONFIG_80211N_HT\r
1320         //set channel, bwmode   \r
1321         p = rtw_get_ie((pnetwork->IEs + sizeof(NDIS_802_11_FIXED_IEs)), _HT_ADD_INFO_IE_, &ie_len, (pnetwork->IELength - sizeof(NDIS_802_11_FIXED_IEs)));\r
1322         if( p && ie_len)\r
1323         {\r
1324                 pht_info = (struct HT_info_element *)(p+2);\r
1325 \r
1326                 if (cur_channel > 14) {\r
1327                         if ((pregpriv->bw_mode & 0xf0) > 0)\r
1328                                 cbw40_enable = 1;\r
1329                 } else {\r
1330                         if ((pregpriv->bw_mode & 0x0f) > 0)\r
1331                                 cbw40_enable = 1;\r
1332                 }\r
1333 \r
1334                 if ((cbw40_enable) &&    (pht_info->infos[0] & BIT(2)))\r
1335                 {\r
1336                         //switch to the 40M Hz mode\r
1337                         //pmlmeext->cur_bwmode = CHANNEL_WIDTH_40;\r
1338                         cur_bwmode = CHANNEL_WIDTH_40;\r
1339                         switch (pht_info->infos[0] & 0x3)\r
1340                         {\r
1341                                 case 1:\r
1342                                         //pmlmeext->cur_ch_offset = HAL_PRIME_CHNL_OFFSET_LOWER;\r
1343                                         cur_ch_offset = HAL_PRIME_CHNL_OFFSET_LOWER;\r
1344                                         break;\r
1345                         \r
1346                                 case 3:\r
1347                                         //pmlmeext->cur_ch_offset = HAL_PRIME_CHNL_OFFSET_UPPER;\r
1348                                         cur_ch_offset = HAL_PRIME_CHNL_OFFSET_UPPER;                                    \r
1349                                         break;\r
1350                                 \r
1351                                 default:\r
1352                                         //pmlmeext->cur_ch_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE;\r
1353                                         cur_ch_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE;\r
1354                                         break;\r
1355                         }               \r
1356                                                 \r
1357                 }\r
1358                                         \r
1359         }\r
1360 #endif //CONFIG_80211N_HT\r
1361 \r
1362 #ifdef CONFIG_80211AC_VHT\r
1363         p = rtw_get_ie((pnetwork->IEs + sizeof(NDIS_802_11_FIXED_IEs)), EID_VHTOperation, &ie_len, (pnetwork->IELength - sizeof(NDIS_802_11_FIXED_IEs)));\r
1364         if( p && ie_len)\r
1365         {\r
1366                 if(GET_VHT_OPERATION_ELE_CHL_WIDTH(p+2) >= 1) {\r
1367                         cur_bwmode = CHANNEL_WIDTH_80;\r
1368                 }\r
1369         }\r
1370 #endif\r
1371 \r
1372 #ifdef CONFIG_DUALMAC_CONCURRENT\r
1373         dc_set_ap_channel_bandwidth(padapter, cur_channel, cur_ch_offset, cur_bwmode);\r
1374 #else //!CONFIG_DUALMAC_CONCURRENT      \r
1375 #ifdef CONFIG_CONCURRENT_MODE\r
1376         //TODO: need to judge the phy parameters on concurrent mode for single phy\r
1377         concurrent_set_ap_chbw(padapter, cur_channel, cur_ch_offset, cur_bwmode);\r
1378 #else //!CONFIG_CONCURRENT_MODE\r
1379         set_channel_bwmode(padapter, cur_channel, cur_ch_offset, cur_bwmode);\r
1380         DBG_871X("CH=%d, BW=%d, offset=%d\n", cur_channel, cur_bwmode, cur_ch_offset);\r
1381         pmlmeext->cur_channel = cur_channel;    \r
1382         pmlmeext->cur_bwmode = cur_bwmode;\r
1383         pmlmeext->cur_ch_offset = cur_ch_offset;\r
1384 #endif //!CONFIG_CONCURRENT_MODE\r
1385 #endif //!CONFIG_DUALMAC_CONCURRENT\r
1386 \r
1387         pmlmeext->cur_wireless_mode = pmlmepriv->cur_network.network_type;\r
1388 \r
1389         //let pnetwork_mlmeext == pnetwork_mlme.\r
1390         _rtw_memcpy(pnetwork_mlmeext, pnetwork, pnetwork->Length);\r
1391 \r
1392         //update cur_wireless_mode\r
1393         update_wireless_mode(padapter);\r
1394 \r
1395         //update RRSR after set channel and bandwidth\r
1396         UpdateBrateTbl(padapter, pnetwork->SupportedRates);\r
1397         rtw_hal_set_hwreg(padapter, HW_VAR_BASIC_RATE, pnetwork->SupportedRates);\r
1398 \r
1399         //udpate capability after cur_wireless_mode updated\r
1400         update_capinfo(padapter, rtw_get_capability((WLAN_BSSID_EX *)pnetwork));\r
1401 \r
1402 \r
1403 #ifdef CONFIG_P2P\r
1404         _rtw_memcpy(pwdinfo->p2p_group_ssid, pnetwork->Ssid.Ssid, pnetwork->Ssid.SsidLength);   \r
1405         pwdinfo->p2p_group_ssid_len = pnetwork->Ssid.SsidLength;\r
1406 #endif //CONFIG_P2P\r
1407 \r
1408         if(_TRUE == pmlmeext->bstart_bss)\r
1409         {\r
1410                 update_beacon(padapter, _TIM_IE_, NULL, _TRUE);\r
1411 \r
1412 #ifndef CONFIG_INTERRUPT_BASED_TXBCN //other case will  tx beacon when bcn interrupt coming in.\r
1413 #if defined(CONFIG_USB_HCI) || defined(CONFIG_SDIO_HCI) || defined(CONFIG_GSPI_HCI)\r
1414                 //issue beacon frame\r
1415                 if(send_beacon(padapter)==_FAIL)\r
1416                 {\r
1417                         DBG_871X("issue_beacon, fail!\n");\r
1418                 }\r
1419 #endif \r
1420 #endif //!CONFIG_INTERRUPT_BASED_TXBCN\r
1421                 \r
1422         }\r
1423 \r
1424 \r
1425         //update bc/mc sta_info\r
1426         update_bmc_sta(padapter);\r
1427         \r
1428         //pmlmeext->bstart_bss = _TRUE;\r
1429         \r
1430 }\r
1431 \r
1432 int rtw_check_beacon_data(_adapter *padapter, u8 *pbuf,  int len)\r
1433 {\r
1434         int ret=_SUCCESS;\r
1435         u8 *p;\r
1436         u8 *pHT_caps_ie=NULL;\r
1437         u8 *pHT_info_ie=NULL;\r
1438         struct sta_info *psta = NULL;\r
1439         u16 cap, ht_cap=_FALSE;\r
1440         uint ie_len = 0;\r
1441         int group_cipher, pairwise_cipher;      \r
1442         u8      channel, network_type, supportRate[NDIS_802_11_LENGTH_RATES_EX];\r
1443         int supportRateNum = 0;\r
1444         u8 OUI1[] = {0x00, 0x50, 0xf2,0x01};\r
1445         u8 wps_oui[4]={0x0,0x50,0xf2,0x04};\r
1446         u8 WMM_PARA_IE[] = {0x00, 0x50, 0xf2, 0x02, 0x01, 0x01};        \r
1447         struct registry_priv *pregistrypriv = &padapter->registrypriv;  \r
1448         struct security_priv *psecuritypriv = &padapter->securitypriv;\r
1449         struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);\r
1450         WLAN_BSSID_EX *pbss_network = (WLAN_BSSID_EX *)&pmlmepriv->cur_network.network; \r
1451         struct sta_priv *pstapriv = &padapter->stapriv;\r
1452         u8 *ie = pbss_network->IEs;\r
1453         u8 vht_cap=_FALSE;\r
1454 \r
1455         /* SSID */\r
1456         /* Supported rates */\r
1457         /* DS Params */\r
1458         /* WLAN_EID_COUNTRY */\r
1459         /* ERP Information element */\r
1460         /* Extended supported rates */\r
1461         /* WPA/WPA2 */\r
1462         /* Wi-Fi Wireless Multimedia Extensions */\r
1463         /* ht_capab, ht_oper */\r
1464         /* WPS IE */\r
1465 \r
1466         DBG_871X("%s, len=%d\n", __FUNCTION__, len);\r
1467 \r
1468         if(check_fwstate(pmlmepriv, WIFI_AP_STATE) != _TRUE)\r
1469                 return _FAIL;\r
1470 \r
1471 \r
1472         if(len>MAX_IE_SZ)\r
1473                 return _FAIL;\r
1474         \r
1475         pbss_network->IELength = len;\r
1476 \r
1477         _rtw_memset(ie, 0, MAX_IE_SZ);\r
1478         \r
1479         _rtw_memcpy(ie, pbuf, pbss_network->IELength);\r
1480 \r
1481 \r
1482         if(pbss_network->InfrastructureMode!=Ndis802_11APMode)\r
1483                 return _FAIL;\r
1484 \r
1485         pbss_network->Rssi = 0;\r
1486 \r
1487         _rtw_memcpy(pbss_network->MacAddress, myid(&(padapter->eeprompriv)), ETH_ALEN);\r
1488         \r
1489         //beacon interval\r
1490         p = rtw_get_beacon_interval_from_ie(ie);//ie + 8;       // 8: TimeStamp, 2: Beacon Interval 2:Capability\r
1491         //pbss_network->Configuration.BeaconPeriod = le16_to_cpu(*(unsigned short*)p);\r
1492         pbss_network->Configuration.BeaconPeriod = RTW_GET_LE16(p);\r
1493         \r
1494         //capability\r
1495         //cap = *(unsigned short *)rtw_get_capability_from_ie(ie);\r
1496         //cap = le16_to_cpu(cap);\r
1497         cap = RTW_GET_LE16(ie);\r
1498 \r
1499         //SSID\r
1500         p = rtw_get_ie(ie + _BEACON_IE_OFFSET_, _SSID_IE_, &ie_len, (pbss_network->IELength -_BEACON_IE_OFFSET_));\r
1501         if(p && ie_len>0)\r
1502         {\r
1503                 _rtw_memset(&pbss_network->Ssid, 0, sizeof(NDIS_802_11_SSID));\r
1504                 _rtw_memcpy(pbss_network->Ssid.Ssid, (p + 2), ie_len);\r
1505                 pbss_network->Ssid.SsidLength = ie_len;\r
1506         }       \r
1507 \r
1508         //chnnel\r
1509         channel = 0;\r
1510         pbss_network->Configuration.Length = 0;\r
1511         p = rtw_get_ie(ie + _BEACON_IE_OFFSET_, _DSSET_IE_, &ie_len, (pbss_network->IELength - _BEACON_IE_OFFSET_));\r
1512         if(p && ie_len>0)\r
1513                 channel = *(p + 2);\r
1514 \r
1515         pbss_network->Configuration.DSConfig = channel;\r
1516 \r
1517         \r
1518         _rtw_memset(supportRate, 0, NDIS_802_11_LENGTH_RATES_EX);\r
1519         // get supported rates\r
1520         p = rtw_get_ie(ie + _BEACON_IE_OFFSET_, _SUPPORTEDRATES_IE_, &ie_len, (pbss_network->IELength - _BEACON_IE_OFFSET_));   \r
1521         if (p !=  NULL) \r
1522         {\r
1523                 _rtw_memcpy(supportRate, p+2, ie_len);  \r
1524                 supportRateNum = ie_len;\r
1525         }\r
1526         \r
1527         //get ext_supported rates\r
1528         p = rtw_get_ie(ie + _BEACON_IE_OFFSET_, _EXT_SUPPORTEDRATES_IE_, &ie_len, pbss_network->IELength - _BEACON_IE_OFFSET_); \r
1529         if (p !=  NULL)\r
1530         {\r
1531                 _rtw_memcpy(supportRate+supportRateNum, p+2, ie_len);\r
1532                 supportRateNum += ie_len;\r
1533         \r
1534         }\r
1535 \r
1536         network_type = rtw_check_network_type(supportRate, supportRateNum, channel);\r
1537 \r
1538         rtw_set_supported_rate(pbss_network->SupportedRates, network_type);\r
1539 \r
1540 \r
1541         //parsing ERP_IE\r
1542         p = rtw_get_ie(ie + _BEACON_IE_OFFSET_, _ERPINFO_IE_, &ie_len, (pbss_network->IELength - _BEACON_IE_OFFSET_));\r
1543         if(p && ie_len>0)\r
1544         {\r
1545                 ERP_IE_handler(padapter, (PNDIS_802_11_VARIABLE_IEs)p);\r
1546         }\r
1547 \r
1548         //update privacy/security\r
1549         if (cap & BIT(4))\r
1550                 pbss_network->Privacy = 1;\r
1551         else\r
1552                 pbss_network->Privacy = 0;\r
1553 \r
1554         psecuritypriv->wpa_psk = 0;\r
1555 \r
1556         //wpa2\r
1557         group_cipher = 0; pairwise_cipher = 0;\r
1558         psecuritypriv->wpa2_group_cipher = _NO_PRIVACY_;\r
1559         psecuritypriv->wpa2_pairwise_cipher = _NO_PRIVACY_;     \r
1560         p = rtw_get_ie(ie + _BEACON_IE_OFFSET_, _RSN_IE_2_, &ie_len, (pbss_network->IELength - _BEACON_IE_OFFSET_));            \r
1561         if(p && ie_len>0)\r
1562         {\r
1563                 if(rtw_parse_wpa2_ie(p, ie_len+2, &group_cipher, &pairwise_cipher, NULL) == _SUCCESS)\r
1564                 {\r
1565                         psecuritypriv->dot11AuthAlgrthm= dot11AuthAlgrthm_8021X;\r
1566                         \r
1567                         psecuritypriv->dot8021xalg = 1;//psk,  todo:802.1x\r
1568                         psecuritypriv->wpa_psk |= BIT(1);\r
1569 \r
1570                         psecuritypriv->wpa2_group_cipher = group_cipher;\r
1571                         psecuritypriv->wpa2_pairwise_cipher = pairwise_cipher;\r
1572 #if 0\r
1573                         switch(group_cipher)\r
1574                         {\r
1575                                 case WPA_CIPHER_NONE:                           \r
1576                                 psecuritypriv->wpa2_group_cipher = _NO_PRIVACY_;\r
1577                                 break;\r
1578                                 case WPA_CIPHER_WEP40:                          \r
1579                                 psecuritypriv->wpa2_group_cipher = _WEP40_;\r
1580                                 break;\r
1581                                 case WPA_CIPHER_TKIP:                           \r
1582                                 psecuritypriv->wpa2_group_cipher = _TKIP_;\r
1583                                 break;\r
1584                                 case WPA_CIPHER_CCMP:                           \r
1585                                 psecuritypriv->wpa2_group_cipher = _AES_;                               \r
1586                                 break;\r
1587                                 case WPA_CIPHER_WEP104:                                 \r
1588                                 psecuritypriv->wpa2_group_cipher = _WEP104_;\r
1589                                 break;\r
1590                         }\r
1591 \r
1592                         switch(pairwise_cipher)\r
1593                         {\r
1594                                 case WPA_CIPHER_NONE:                   \r
1595                                 psecuritypriv->wpa2_pairwise_cipher = _NO_PRIVACY_;\r
1596                                 break;\r
1597                                 case WPA_CIPHER_WEP40:                  \r
1598                                 psecuritypriv->wpa2_pairwise_cipher = _WEP40_;\r
1599                                 break;\r
1600                                 case WPA_CIPHER_TKIP:                           \r
1601                                 psecuritypriv->wpa2_pairwise_cipher = _TKIP_;\r
1602                                 break;\r
1603                                 case WPA_CIPHER_CCMP:                   \r
1604                                 psecuritypriv->wpa2_pairwise_cipher = _AES_;\r
1605                                 break;\r
1606                                 case WPA_CIPHER_WEP104:                                 \r
1607                                 psecuritypriv->wpa2_pairwise_cipher = _WEP104_;\r
1608                                 break;\r
1609                         }\r
1610 #endif                  \r
1611                 }\r
1612                 \r
1613         }\r
1614 \r
1615         //wpa\r
1616         ie_len = 0;\r
1617         group_cipher = 0; pairwise_cipher = 0;\r
1618         psecuritypriv->wpa_group_cipher = _NO_PRIVACY_;\r
1619         psecuritypriv->wpa_pairwise_cipher = _NO_PRIVACY_;      \r
1620         for (p = ie + _BEACON_IE_OFFSET_; ;p += (ie_len + 2))\r
1621         {\r
1622                 p = rtw_get_ie(p, _SSN_IE_1_, &ie_len, (pbss_network->IELength - _BEACON_IE_OFFSET_ - (ie_len + 2)));           \r
1623                 if ((p) && (_rtw_memcmp(p+2, OUI1, 4)))\r
1624                 {\r
1625                         if(rtw_parse_wpa_ie(p, ie_len+2, &group_cipher, &pairwise_cipher, NULL) == _SUCCESS)\r
1626                         {\r
1627                                 psecuritypriv->dot11AuthAlgrthm= dot11AuthAlgrthm_8021X;\r
1628                                 \r
1629                                 psecuritypriv->dot8021xalg = 1;//psk,  todo:802.1x\r
1630 \r
1631                                 psecuritypriv->wpa_psk |= BIT(0);\r
1632 \r
1633                                 psecuritypriv->wpa_group_cipher = group_cipher;\r
1634                                 psecuritypriv->wpa_pairwise_cipher = pairwise_cipher;\r
1635 \r
1636 #if 0\r
1637                                 switch(group_cipher)\r
1638                                 {\r
1639                                         case WPA_CIPHER_NONE:                                   \r
1640                                         psecuritypriv->wpa_group_cipher = _NO_PRIVACY_;\r
1641                                         break;\r
1642                                         case WPA_CIPHER_WEP40:                                  \r
1643                                         psecuritypriv->wpa_group_cipher = _WEP40_;\r
1644                                         break;\r
1645                                         case WPA_CIPHER_TKIP:                                   \r
1646                                         psecuritypriv->wpa_group_cipher = _TKIP_;\r
1647                                         break;\r
1648                                         case WPA_CIPHER_CCMP:                                   \r
1649                                         psecuritypriv->wpa_group_cipher = _AES_;                                \r
1650                                         break;\r
1651                                         case WPA_CIPHER_WEP104:                                 \r
1652                                         psecuritypriv->wpa_group_cipher = _WEP104_;\r
1653                                         break;\r
1654                                 }\r
1655 \r
1656                                 switch(pairwise_cipher)\r
1657                                 {\r
1658                                         case WPA_CIPHER_NONE:                                   \r
1659                                         psecuritypriv->wpa_pairwise_cipher = _NO_PRIVACY_;\r
1660                                         break;\r
1661                                         case WPA_CIPHER_WEP40:                                  \r
1662                                         psecuritypriv->wpa_pairwise_cipher = _WEP40_;\r
1663                                         break;\r
1664                                         case WPA_CIPHER_TKIP:                                   \r
1665                                         psecuritypriv->wpa_pairwise_cipher = _TKIP_;\r
1666                                         break;\r
1667                                         case WPA_CIPHER_CCMP:                                   \r
1668                                         psecuritypriv->wpa_pairwise_cipher = _AES_;\r
1669                                         break;\r
1670                                         case WPA_CIPHER_WEP104:                                 \r
1671                                         psecuritypriv->wpa_pairwise_cipher = _WEP104_;\r
1672                                         break;\r
1673                                 }\r
1674 #endif                          \r
1675                         }\r
1676 \r
1677                         break;\r
1678                         \r
1679                 }\r
1680                         \r
1681                 if ((p == NULL) || (ie_len == 0))\r
1682                 {\r
1683                                 break;\r
1684                 }\r
1685                 \r
1686         }\r
1687 \r
1688         //wmm\r
1689         ie_len = 0;\r
1690         pmlmepriv->qospriv.qos_option = 0;\r
1691         if(pregistrypriv->wmm_enable)\r
1692         {\r
1693                 for (p = ie + _BEACON_IE_OFFSET_; ;p += (ie_len + 2))\r
1694                 {                       \r
1695                         p = rtw_get_ie(p, _VENDOR_SPECIFIC_IE_, &ie_len, (pbss_network->IELength - _BEACON_IE_OFFSET_ - (ie_len + 2))); \r
1696                         if((p) && _rtw_memcmp(p+2, WMM_PARA_IE, 6)) \r
1697                         {\r
1698                                 pmlmepriv->qospriv.qos_option = 1;      \r
1699 \r
1700                                 *(p+8) |= BIT(7);//QoS Info, support U-APSD\r
1701                                 \r
1702                                 /* disable all ACM bits since the WMM admission control is not supported */\r
1703                                 *(p + 10) &= ~BIT(4); /* BE */\r
1704                                 *(p + 14) &= ~BIT(4); /* BK */\r
1705                                 *(p + 18) &= ~BIT(4); /* VI */\r
1706                                 *(p + 22) &= ~BIT(4); /* VO */\r
1707                                 \r
1708                                 break;                          \r
1709                         }\r
1710                         \r
1711                         if ((p == NULL) || (ie_len == 0))\r
1712                         {\r
1713                                 break;\r
1714                         }                       \r
1715                 }               \r
1716         }\r
1717 #ifdef CONFIG_80211N_HT\r
1718         //parsing HT_CAP_IE\r
1719         p = rtw_get_ie(ie + _BEACON_IE_OFFSET_, _HT_CAPABILITY_IE_, &ie_len, (pbss_network->IELength - _BEACON_IE_OFFSET_));\r
1720         if(p && ie_len>0)\r
1721         {\r
1722                 u8 rf_type=0;\r
1723                 u32 max_rx_ampdu_factor=0;\r
1724                 struct rtw_ieee80211_ht_cap *pht_cap = (struct rtw_ieee80211_ht_cap *)(p+2);\r
1725 \r
1726                 pHT_caps_ie=p;\r
1727 \r
1728                 ht_cap = _TRUE;\r
1729                 network_type |= WIRELESS_11_24N;\r
1730 \r
1731                 rtw_ht_use_default_setting(padapter);\r
1732 \r
1733                 if (pmlmepriv->htpriv.sgi_20m == _FALSE)\r
1734                         pht_cap->cap_info &= ~(IEEE80211_HT_CAP_SGI_20);\r
1735 \r
1736                 if (pmlmepriv->htpriv.sgi_40m == _FALSE)\r
1737                         pht_cap->cap_info &= ~(IEEE80211_HT_CAP_SGI_40);\r
1738 \r
1739                 if (!TEST_FLAG(pmlmepriv->htpriv.ldpc_cap, LDPC_HT_ENABLE_RX))\r
1740                 {\r
1741                         pht_cap->cap_info &= ~(IEEE80211_HT_CAP_LDPC_CODING);\r
1742                 }\r
1743 \r
1744                 if (!TEST_FLAG(pmlmepriv->htpriv.stbc_cap, STBC_HT_ENABLE_TX))\r
1745                 {\r
1746                         pht_cap->cap_info &= ~(IEEE80211_HT_CAP_TX_STBC);\r
1747                 }               \r
1748 \r
1749                 if (!TEST_FLAG(pmlmepriv->htpriv.stbc_cap, STBC_HT_ENABLE_RX))\r
1750                 {\r
1751                         pht_cap->cap_info &= ~(IEEE80211_HT_CAP_RX_STBC_3R);\r
1752                 }\r
1753 \r
1754                 pht_cap->ampdu_params_info &= ~(IEEE80211_HT_CAP_AMPDU_FACTOR|IEEE80211_HT_CAP_AMPDU_DENSITY);\r
1755                 \r
1756                 if((psecuritypriv->wpa_pairwise_cipher & WPA_CIPHER_CCMP) ||\r
1757                         (psecuritypriv->wpa2_pairwise_cipher & WPA_CIPHER_CCMP))\r
1758                 {\r
1759                         pht_cap->ampdu_params_info |= (IEEE80211_HT_CAP_AMPDU_DENSITY&(0x07<<2));\r
1760                 }       \r
1761                 else\r
1762                 {\r
1763                         pht_cap->ampdu_params_info |= (IEEE80211_HT_CAP_AMPDU_DENSITY&0x00);    \r
1764                 }       \r
1765 \r
1766                 rtw_hal_get_def_var(padapter, HW_VAR_MAX_RX_AMPDU_FACTOR, &max_rx_ampdu_factor);\r
1767                 pht_cap->ampdu_params_info |= (IEEE80211_HT_CAP_AMPDU_FACTOR & max_rx_ampdu_factor); //set  Max Rx AMPDU size  to 64K\r
1768 \r
1769                 rtw_hal_get_hwreg(padapter, HW_VAR_RF_TYPE, (u8 *)(&rf_type));\r
1770                 if(rf_type == RF_1T1R)\r
1771                 {                       \r
1772                         pht_cap->supp_mcs_set[0] = 0xff;\r
1773                         pht_cap->supp_mcs_set[1] = 0x0;\r
1774                 }\r
1775 \r
1776 #ifdef CONFIG_BEAMFORMING\r
1777                 // Use registry value to enable HT Beamforming.\r
1778                 // ToDo: use configure file to set these capability.\r
1779                 pht_cap->tx_BF_cap_info = 0;\r
1780 \r
1781                 // HT Beamformer\r
1782                 if(TEST_FLAG(pmlmepriv->htpriv.beamform_cap, BEAMFORMING_HT_BEAMFORMER_ENABLE))\r
1783                 {\r
1784                         // Transmit NDP Capable\r
1785                         SET_HT_CAP_TXBF_TRANSMIT_NDP_CAP(pht_cap, 1);\r
1786                         // Explicit Compressed Steering Capable\r
1787                         SET_HT_CAP_TXBF_EXPLICIT_COMP_STEERING_CAP(pht_cap, 1);\r
1788                         // Compressed Steering Number Antennas\r
1789                         SET_HT_CAP_TXBF_COMP_STEERING_NUM_ANTENNAS(pht_cap, 1);\r
1790                 }\r
1791 \r
1792                 // HT Beamformee\r
1793                 if(TEST_FLAG(pmlmepriv->htpriv.beamform_cap, BEAMFORMING_HT_BEAMFORMEE_ENABLE))\r
1794                 {\r
1795                         // Receive NDP Capable\r
1796                         SET_HT_CAP_TXBF_RECEIVE_NDP_CAP(pht_cap, 1);\r
1797                         // Explicit Compressed Beamforming Feedback Capable\r
1798                         SET_HT_CAP_TXBF_EXPLICIT_COMP_FEEDBACK_CAP(pht_cap, 2);\r
1799                 }\r
1800 #endif //CONFIG_BEAMFORMING\r
1801 \r
1802                 _rtw_memcpy(&pmlmepriv->htpriv.ht_cap, p+2, ie_len);\r
1803                 \r
1804         }\r
1805 \r
1806         //parsing HT_INFO_IE\r
1807         p = rtw_get_ie(ie + _BEACON_IE_OFFSET_, _HT_ADD_INFO_IE_, &ie_len, (pbss_network->IELength - _BEACON_IE_OFFSET_));\r
1808         if(p && ie_len>0)\r
1809         {\r
1810                 pHT_info_ie=p;\r
1811         }\r
1812 #endif //CONFIG_80211N_HT\r
1813         switch(network_type)\r
1814         {\r
1815                 case WIRELESS_11B:\r
1816                         pbss_network->NetworkTypeInUse = Ndis802_11DS;\r
1817                         break;  \r
1818                 case WIRELESS_11G:\r
1819                 case WIRELESS_11BG:\r
1820              case WIRELESS_11G_24N:\r
1821                 case WIRELESS_11BG_24N:\r
1822                         pbss_network->NetworkTypeInUse = Ndis802_11OFDM24;\r
1823                         break;\r
1824                 case WIRELESS_11A:\r
1825                         pbss_network->NetworkTypeInUse = Ndis802_11OFDM5;\r
1826                         break;\r
1827                 default :\r
1828                         pbss_network->NetworkTypeInUse = Ndis802_11OFDM24;\r
1829                         break;\r
1830         }\r
1831         \r
1832         pmlmepriv->cur_network.network_type = network_type;\r
1833 \r
1834 #ifdef CONFIG_80211N_HT\r
1835         pmlmepriv->htpriv.ht_option = _FALSE;\r
1836 \r
1837         if( (psecuritypriv->wpa2_pairwise_cipher&WPA_CIPHER_TKIP) ||\r
1838                       (psecuritypriv->wpa_pairwise_cipher&WPA_CIPHER_TKIP))\r
1839         {       \r
1840                 //todo:\r
1841                 //ht_cap = _FALSE;\r
1842         }\r
1843                       \r
1844         //ht_cap        \r
1845         if(pregistrypriv->ht_enable && ht_cap==_TRUE)\r
1846         {               \r
1847                 pmlmepriv->htpriv.ht_option = _TRUE;\r
1848                 pmlmepriv->qospriv.qos_option = 1;\r
1849 \r
1850                 if(pregistrypriv->ampdu_enable==1)\r
1851                 {\r
1852                         pmlmepriv->htpriv.ampdu_enable = _TRUE;\r
1853                 }\r
1854 \r
1855                 HT_caps_handler(padapter, (PNDIS_802_11_VARIABLE_IEs)pHT_caps_ie);\r
1856                 \r
1857                 HT_info_handler(padapter, (PNDIS_802_11_VARIABLE_IEs)pHT_info_ie);\r
1858         }\r
1859 #endif\r
1860 \r
1861 #ifdef CONFIG_80211AC_VHT\r
1862 \r
1863         //Parsing VHT CAP IE\r
1864         p = rtw_get_ie(ie + _BEACON_IE_OFFSET_, EID_VHTCapability, &ie_len, (pbss_network->IELength - _BEACON_IE_OFFSET_));\r
1865         if(p && ie_len>0)\r
1866         {       \r
1867                 vht_cap = _TRUE; \r
1868         }\r
1869         //Parsing VHT OPERATION IE\r
1870         \r
1871 \r
1872         pmlmepriv->vhtpriv.vht_option = _FALSE;\r
1873         // if channel in 5G band, then add vht ie .\r
1874         if ((pbss_network->Configuration.DSConfig > 14) && \r
1875                 (pmlmepriv->htpriv.ht_option == _TRUE) &&\r
1876                 (pregistrypriv->vht_enable)) \r
1877         {\r
1878                 if(vht_cap == _TRUE)\r
1879                 {\r
1880                         pmlmepriv->vhtpriv.vht_option = _TRUE;\r
1881                 }\r
1882                 else if(pregistrypriv->vht_enable == 2) // auto enabled\r
1883                 {\r
1884                         u8      cap_len, operation_len;\r
1885 \r
1886                         rtw_vht_use_default_setting(padapter);\r
1887 \r
1888                         // VHT Capabilities element\r
1889                         cap_len = rtw_build_vht_cap_ie(padapter, pbss_network->IEs + pbss_network->IELength);\r
1890                         pbss_network->IELength += cap_len;\r
1891 \r
1892                         // VHT Operation element\r
1893                         operation_len = rtw_build_vht_operation_ie(padapter, pbss_network->IEs + pbss_network->IELength, pbss_network->Configuration.DSConfig);\r
1894                         pbss_network->IELength += operation_len;\r
1895 \r
1896                         pmlmepriv->vhtpriv.vht_option = _TRUE;\r
1897                 }               \r
1898         }\r
1899 #endif //CONFIG_80211AC_VHT\r
1900 \r
1901         pbss_network->Length = get_WLAN_BSSID_EX_sz((WLAN_BSSID_EX  *)pbss_network);\r
1902 \r
1903         //issue beacon to start bss network\r
1904         //start_bss_network(padapter, (u8*)pbss_network);\r
1905         rtw_startbss_cmd(padapter, RTW_CMDF_WAIT_ACK);\r
1906                         \r
1907 \r
1908         //alloc sta_info for ap itself\r
1909         psta = rtw_get_stainfo(&padapter->stapriv, pbss_network->MacAddress);\r
1910         if(!psta)\r
1911         {\r
1912                 psta = rtw_alloc_stainfo(&padapter->stapriv, pbss_network->MacAddress);\r
1913                 if (psta == NULL) \r
1914                 { \r
1915                         return _FAIL;\r
1916                 }       \r
1917         }\r
1918 \r
1919         // update AP's sta info \r
1920         update_ap_info(padapter, psta);\r
1921         \r
1922         psta->state |= WIFI_AP_STATE;           //Aries, add,fix bug of flush_cam_entry at STOP AP mode , 0724  \r
1923         rtw_indicate_connect( padapter);\r
1924 \r
1925         pmlmepriv->cur_network.join_res = _TRUE;//for check if already set beacon\r
1926                 \r
1927         //update bc/mc sta_info\r
1928         //update_bmc_sta(padapter);\r
1929 \r
1930         return ret;\r
1931 \r
1932 }\r
1933 \r
1934 void rtw_set_macaddr_acl(_adapter *padapter, int mode)\r
1935 {\r
1936         struct sta_priv *pstapriv = &padapter->stapriv;\r
1937         struct wlan_acl_pool *pacl_list = &pstapriv->acl_list;\r
1938 \r
1939         DBG_871X("%s, mode=%d\n", __func__, mode);\r
1940 \r
1941         pacl_list->mode = mode;\r
1942 }\r
1943 \r
1944 int rtw_acl_add_sta(_adapter *padapter, u8 *addr)\r
1945 {\r
1946         _irqL irqL;\r
1947         _list   *plist, *phead;\r
1948         u8 added = _FALSE;\r
1949         int i, ret=0;\r
1950         struct rtw_wlan_acl_node *paclnode;\r
1951         struct sta_priv *pstapriv = &padapter->stapriv;\r
1952         struct wlan_acl_pool *pacl_list = &pstapriv->acl_list;\r
1953         _queue  *pacl_node_q =&pacl_list->acl_node_q;   \r
1954 \r
1955         DBG_871X("%s(acl_num=%d)=" MAC_FMT "\n", __func__, pacl_list->num, MAC_ARG(addr));      \r
1956 \r
1957         if((NUM_ACL-1) < pacl_list->num)\r
1958                 return (-1);    \r
1959 \r
1960 \r
1961         _enter_critical_bh(&(pacl_node_q->lock), &irqL);\r
1962 \r
1963         phead = get_list_head(pacl_node_q);\r
1964         plist = get_next(phead);\r
1965                 \r
1966         while ((rtw_end_of_queue_search(phead, plist)) == _FALSE)\r
1967         {\r
1968                 paclnode = LIST_CONTAINOR(plist, struct rtw_wlan_acl_node, list);\r
1969                 plist = get_next(plist);\r
1970 \r
1971                 if(_rtw_memcmp(paclnode->addr, addr, ETH_ALEN))\r
1972                 {\r
1973                         if(paclnode->valid == _TRUE)\r
1974                         {\r
1975                                 added = _TRUE;\r
1976                                 DBG_871X("%s, sta has been added\n", __func__);\r
1977                                 break;\r
1978                         }\r
1979                 }               \r
1980         }\r
1981         \r
1982         _exit_critical_bh(&(pacl_node_q->lock), &irqL);\r
1983 \r
1984 \r
1985         if(added == _TRUE)\r
1986                 return ret;\r
1987         \r
1988 \r
1989         _enter_critical_bh(&(pacl_node_q->lock), &irqL);\r
1990 \r
1991         for(i=0; i< NUM_ACL; i++)\r
1992         {\r
1993                 paclnode = &pacl_list->aclnode[i];\r
1994 \r
1995                 if(paclnode->valid == _FALSE)\r
1996                 {\r
1997                         _rtw_init_listhead(&paclnode->list);\r
1998         \r
1999                         _rtw_memcpy(paclnode->addr, addr, ETH_ALEN);\r
2000                 \r
2001                         paclnode->valid = _TRUE;\r
2002 \r
2003                         rtw_list_insert_tail(&paclnode->list, get_list_head(pacl_node_q));\r
2004         \r
2005                         pacl_list->num++;\r
2006 \r
2007                         break;\r
2008                 }\r
2009         }\r
2010 \r
2011         DBG_871X("%s, acl_num=%d\n", __func__, pacl_list->num);\r
2012         \r
2013         _exit_critical_bh(&(pacl_node_q->lock), &irqL);\r
2014 \r
2015         return ret;\r
2016 }\r
2017 \r
2018 int rtw_acl_remove_sta(_adapter *padapter, u8 *addr)\r
2019 {\r
2020         _irqL irqL;\r
2021         _list   *plist, *phead;\r
2022         int i, ret=0;\r
2023         struct rtw_wlan_acl_node *paclnode;\r
2024         struct sta_priv *pstapriv = &padapter->stapriv;\r
2025         struct wlan_acl_pool *pacl_list = &pstapriv->acl_list;\r
2026         _queue  *pacl_node_q =&pacl_list->acl_node_q;\r
2027         u8 baddr[ETH_ALEN] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };    //Baddr is used for clearing acl_list\r
2028 \r
2029         DBG_871X("%s(acl_num=%d)=" MAC_FMT "\n", __func__, pacl_list->num, MAC_ARG(addr));      \r
2030 \r
2031         _enter_critical_bh(&(pacl_node_q->lock), &irqL);\r
2032 \r
2033         phead = get_list_head(pacl_node_q);\r
2034         plist = get_next(phead);\r
2035                 \r
2036         while ((rtw_end_of_queue_search(phead, plist)) == _FALSE)\r
2037         {\r
2038                 paclnode = LIST_CONTAINOR(plist, struct rtw_wlan_acl_node, list);\r
2039                 plist = get_next(plist);\r
2040 \r
2041                 if(_rtw_memcmp(paclnode->addr, addr, ETH_ALEN) || _rtw_memcmp(baddr, addr, ETH_ALEN))\r
2042                 {\r
2043                         if(paclnode->valid == _TRUE)\r
2044                         {\r
2045                                 paclnode->valid = _FALSE;\r
2046 \r
2047                                 rtw_list_delete(&paclnode->list);\r
2048                                 \r
2049                                 pacl_list->num--;\r
2050                         }\r
2051                 }               \r
2052         }\r
2053         \r
2054         _exit_critical_bh(&(pacl_node_q->lock), &irqL);\r
2055 \r
2056         DBG_871X("%s, acl_num=%d\n", __func__, pacl_list->num);\r
2057         \r
2058         return ret;\r
2059 \r
2060 }\r
2061 \r
2062 u8 rtw_ap_set_pairwise_key(_adapter *padapter, struct sta_info *psta)\r
2063 {\r
2064         struct cmd_obj*                 ph2c;\r
2065         struct set_stakey_parm  *psetstakey_para;\r
2066         struct cmd_priv                         *pcmdpriv=&padapter->cmdpriv;   \r
2067         u8      res=_SUCCESS;\r
2068 \r
2069         ph2c = (struct cmd_obj*)rtw_zmalloc(sizeof(struct cmd_obj));\r
2070         if ( ph2c == NULL){\r
2071                 res= _FAIL;\r
2072                 goto exit;\r
2073         }\r
2074 \r
2075         psetstakey_para = (struct set_stakey_parm*)rtw_zmalloc(sizeof(struct set_stakey_parm));\r
2076         if(psetstakey_para==NULL){\r
2077                 rtw_mfree((u8 *) ph2c, sizeof(struct cmd_obj));\r
2078                 res=_FAIL;\r
2079                 goto exit;\r
2080         }\r
2081 \r
2082         init_h2fwcmd_w_parm_no_rsp(ph2c, psetstakey_para, _SetStaKey_CMD_);\r
2083 \r
2084 \r
2085         psetstakey_para->algorithm = (u8)psta->dot118021XPrivacy;\r
2086 \r
2087         _rtw_memcpy(psetstakey_para->addr, psta->hwaddr, ETH_ALEN);     \r
2088         \r
2089         _rtw_memcpy(psetstakey_para->key, &psta->dot118021x_UncstKey, 16);\r
2090 \r
2091         \r
2092         res = rtw_enqueue_cmd(pcmdpriv, ph2c);  \r
2093 \r
2094 exit:\r
2095 \r
2096         return res;\r
2097         \r
2098 }\r
2099 \r
2100 static int rtw_ap_set_key(_adapter *padapter, u8 *key, u8 alg, int keyid, u8 set_tx)\r
2101 {\r
2102         u8 keylen;\r
2103         struct cmd_obj* pcmd;\r
2104         struct setkey_parm *psetkeyparm;\r
2105         struct cmd_priv *pcmdpriv=&(padapter->cmdpriv); \r
2106         int res=_SUCCESS;\r
2107 \r
2108         //DBG_871X("%s\n", __FUNCTION__);\r
2109         \r
2110         pcmd = (struct cmd_obj*)rtw_zmalloc(sizeof(struct cmd_obj));\r
2111         if(pcmd==NULL){\r
2112                 res= _FAIL;\r
2113                 goto exit;\r
2114         }\r
2115         psetkeyparm=(struct setkey_parm*)rtw_zmalloc(sizeof(struct setkey_parm));\r
2116         if(psetkeyparm==NULL){\r
2117                 rtw_mfree((unsigned char *)pcmd, sizeof(struct cmd_obj));\r
2118                 res= _FAIL;\r
2119                 goto exit;\r
2120         }\r
2121 \r
2122         _rtw_memset(psetkeyparm, 0, sizeof(struct setkey_parm));\r
2123                 \r
2124         psetkeyparm->keyid=(u8)keyid;\r
2125         if (is_wep_enc(alg))\r
2126                 padapter->securitypriv.key_mask |= BIT(psetkeyparm->keyid);\r
2127 \r
2128         psetkeyparm->algorithm = alg;\r
2129 \r
2130         psetkeyparm->set_tx = set_tx;\r
2131 \r
2132         switch(alg)\r
2133         {\r
2134                 case _WEP40_:                                   \r
2135                         keylen = 5;\r
2136                         break;\r
2137                 case _WEP104_:\r
2138                         keylen = 13;                    \r
2139                         break;\r
2140                 case _TKIP_:\r
2141                 case _TKIP_WTMIC_:\r
2142                 case _AES_:\r
2143                 default:\r
2144                         keylen = 16;\r
2145         }\r
2146 \r
2147         _rtw_memcpy(&(psetkeyparm->key[0]), key, keylen);\r
2148         \r
2149         pcmd->cmdcode = _SetKey_CMD_;\r
2150         pcmd->parmbuf = (u8 *)psetkeyparm;   \r
2151         pcmd->cmdsz =  (sizeof(struct setkey_parm));  \r
2152         pcmd->rsp = NULL;\r
2153         pcmd->rspsz = 0;\r
2154 \r
2155 \r
2156         _rtw_init_listhead(&pcmd->list);\r
2157 \r
2158         res = rtw_enqueue_cmd(pcmdpriv, pcmd);\r
2159 \r
2160 exit:\r
2161 \r
2162         return res;\r
2163 }\r
2164 \r
2165 int rtw_ap_set_group_key(_adapter *padapter, u8 *key, u8 alg, int keyid)\r
2166 {\r
2167         DBG_871X("%s\n", __FUNCTION__);\r
2168 \r
2169         return rtw_ap_set_key(padapter, key, alg, keyid, 1);\r
2170 }\r
2171 \r
2172 int rtw_ap_set_wep_key(_adapter *padapter, u8 *key, u8 keylen, int keyid, u8 set_tx)\r
2173 {\r
2174         u8 alg;\r
2175 \r
2176         switch(keylen)\r
2177         {\r
2178                 case 5:\r
2179                         alg =_WEP40_;                   \r
2180                         break;\r
2181                 case 13:\r
2182                         alg =_WEP104_;                  \r
2183                         break;\r
2184                 default:\r
2185                         alg =_NO_PRIVACY_;                      \r
2186         }\r
2187 \r
2188         DBG_871X("%s\n", __FUNCTION__);\r
2189 \r
2190         return rtw_ap_set_key(padapter, key, alg, keyid, set_tx);\r
2191 }\r
2192 \r
2193 #ifdef CONFIG_NATIVEAP_MLME\r
2194 \r
2195 static void update_bcn_fixed_ie(_adapter *padapter)\r
2196 {\r
2197         DBG_871X("%s\n", __FUNCTION__);\r
2198 \r
2199 }\r
2200 \r
2201 static void update_bcn_erpinfo_ie(_adapter *padapter)\r
2202 {\r
2203         struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);\r
2204         struct mlme_ext_priv    *pmlmeext = &(padapter->mlmeextpriv);\r
2205         struct mlme_ext_info    *pmlmeinfo = &(pmlmeext->mlmext_info);\r
2206         WLAN_BSSID_EX *pnetwork = &(pmlmeinfo->network);\r
2207         unsigned char *p, *ie = pnetwork->IEs;\r
2208         u32 len = 0;\r
2209 \r
2210         DBG_871X("%s, ERP_enable=%d\n", __FUNCTION__, pmlmeinfo->ERP_enable);\r
2211 \r
2212         if(!pmlmeinfo->ERP_enable)\r
2213                 return;\r
2214 \r
2215         //parsing ERP_IE\r
2216         p = rtw_get_ie(ie + _BEACON_IE_OFFSET_, _ERPINFO_IE_, &len, (pnetwork->IELength - _BEACON_IE_OFFSET_));\r
2217         if(p && len>0)\r
2218         {\r
2219                 PNDIS_802_11_VARIABLE_IEs pIE = (PNDIS_802_11_VARIABLE_IEs)p;\r
2220 \r
2221                 if (pmlmepriv->num_sta_non_erp == 1)\r
2222                         pIE->data[0] |= RTW_ERP_INFO_NON_ERP_PRESENT|RTW_ERP_INFO_USE_PROTECTION;\r
2223                 else\r
2224                         pIE->data[0] &= ~(RTW_ERP_INFO_NON_ERP_PRESENT|RTW_ERP_INFO_USE_PROTECTION);\r
2225 \r
2226                 if(pmlmepriv->num_sta_no_short_preamble > 0)\r
2227                         pIE->data[0] |= RTW_ERP_INFO_BARKER_PREAMBLE_MODE;\r
2228                 else\r
2229                         pIE->data[0] &= ~(RTW_ERP_INFO_BARKER_PREAMBLE_MODE);\r
2230         \r
2231                 ERP_IE_handler(padapter, pIE);\r
2232         }\r
2233         \r
2234 }\r
2235 \r
2236 static void update_bcn_htcap_ie(_adapter *padapter)\r
2237 {\r
2238         DBG_871X("%s\n", __FUNCTION__);\r
2239 \r
2240 }\r
2241 \r
2242 static void update_bcn_htinfo_ie(_adapter *padapter)\r
2243 {       \r
2244         DBG_871X("%s\n", __FUNCTION__);\r
2245 \r
2246 }\r
2247 \r
2248 static void update_bcn_rsn_ie(_adapter *padapter)\r
2249 {\r
2250         DBG_871X("%s\n", __FUNCTION__);\r
2251 \r
2252 }\r
2253 \r
2254 static void update_bcn_wpa_ie(_adapter *padapter)\r
2255 {\r
2256         DBG_871X("%s\n", __FUNCTION__);\r
2257 \r
2258 }\r
2259 \r
2260 static void update_bcn_wmm_ie(_adapter *padapter)\r
2261 {\r
2262         DBG_871X("%s\n", __FUNCTION__);\r
2263         \r
2264 }\r
2265 \r
2266 static void update_bcn_wps_ie(_adapter *padapter)\r
2267 {\r
2268         u8 *pwps_ie=NULL, *pwps_ie_src, *premainder_ie, *pbackup_remainder_ie=NULL;\r
2269         uint wps_ielen=0, wps_offset, remainder_ielen;\r
2270         struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);\r
2271         struct mlme_ext_priv    *pmlmeext = &(padapter->mlmeextpriv);\r
2272         struct mlme_ext_info    *pmlmeinfo = &(pmlmeext->mlmext_info);\r
2273         WLAN_BSSID_EX *pnetwork = &(pmlmeinfo->network);\r
2274         unsigned char *ie = pnetwork->IEs;\r
2275         u32 ielen = pnetwork->IELength;\r
2276 \r
2277 \r
2278         DBG_871X("%s\n", __FUNCTION__);\r
2279 \r
2280         pwps_ie = rtw_get_wps_ie(ie+_FIXED_IE_LENGTH_, ielen-_FIXED_IE_LENGTH_, NULL, &wps_ielen);\r
2281         \r
2282         if(pwps_ie==NULL || wps_ielen==0)\r
2283                 return;\r
2284 \r
2285         pwps_ie_src = pmlmepriv->wps_beacon_ie;\r
2286         if(pwps_ie_src == NULL)\r
2287                 return;\r
2288 \r
2289         wps_offset = (uint)(pwps_ie-ie);\r
2290 \r
2291         premainder_ie = pwps_ie + wps_ielen;\r
2292 \r
2293         remainder_ielen = ielen - wps_offset - wps_ielen;\r
2294 \r
2295         if(remainder_ielen>0)\r
2296         {\r
2297                 pbackup_remainder_ie = rtw_malloc(remainder_ielen);\r
2298                 if(pbackup_remainder_ie)\r
2299                         _rtw_memcpy(pbackup_remainder_ie, premainder_ie, remainder_ielen);\r
2300         }\r
2301 \r
2302         wps_ielen = (uint)pwps_ie_src[1];//to get ie data len\r
2303         if((wps_offset+wps_ielen+2+remainder_ielen)<=MAX_IE_SZ)\r
2304         {\r
2305                 _rtw_memcpy(pwps_ie, pwps_ie_src, wps_ielen+2);\r
2306                 pwps_ie += (wps_ielen+2);\r
2307 \r
2308                 if(pbackup_remainder_ie)\r
2309                         _rtw_memcpy(pwps_ie, pbackup_remainder_ie, remainder_ielen);\r
2310 \r
2311                 //update IELength\r
2312                 pnetwork->IELength = wps_offset + (wps_ielen+2) + remainder_ielen;\r
2313         }\r
2314 \r
2315         if(pbackup_remainder_ie)\r
2316                 rtw_mfree(pbackup_remainder_ie, remainder_ielen);\r
2317         \r
2318         // deal with the case without set_tx_beacon_cmd() in update_beacon() \r
2319 #if defined( CONFIG_INTERRUPT_BASED_TXBCN ) || defined( CONFIG_PCI_HCI )\r
2320         if( (pmlmeinfo->state&0x03) == WIFI_FW_AP_STATE)\r
2321         {\r
2322                 u8 sr = 0;\r
2323                 rtw_get_wps_attr_content(pwps_ie_src,  wps_ielen, WPS_ATTR_SELECTED_REGISTRAR, (u8*)(&sr), NULL);\r
2324         \r
2325                 if( sr ) {\r
2326                         set_fwstate(pmlmepriv, WIFI_UNDER_WPS);\r
2327                         DBG_871X("%s, set WIFI_UNDER_WPS\n", __func__);\r
2328                 }\r
2329         }\r
2330 #endif\r
2331 }\r
2332 \r
2333 static void update_bcn_p2p_ie(_adapter *padapter)\r
2334 {\r
2335 \r
2336 }\r
2337 \r
2338 static void update_bcn_vendor_spec_ie(_adapter *padapter, u8*oui)\r
2339 {\r
2340         DBG_871X("%s\n", __FUNCTION__);\r
2341 \r
2342         if(_rtw_memcmp(RTW_WPA_OUI, oui, 4))\r
2343         {\r
2344                 update_bcn_wpa_ie(padapter);\r
2345         }\r
2346         else if(_rtw_memcmp(WMM_OUI, oui, 4))\r
2347         {\r
2348                 update_bcn_wmm_ie(padapter);\r
2349         }\r
2350         else if(_rtw_memcmp(WPS_OUI, oui, 4))\r
2351         {\r
2352                 update_bcn_wps_ie(padapter);\r
2353         }\r
2354         else if(_rtw_memcmp(P2P_OUI, oui, 4))\r
2355         {\r
2356                 update_bcn_p2p_ie(padapter);\r
2357         }\r
2358         else\r
2359         {\r
2360                 DBG_871X("unknown OUI type!\n");\r
2361         }\r
2362         \r
2363         \r
2364 }\r
2365 \r
2366 void update_beacon(_adapter *padapter, u8 ie_id, u8 *oui, u8 tx)\r
2367 {\r
2368         _irqL irqL;\r
2369         struct mlme_priv *pmlmepriv;\r
2370         struct mlme_ext_priv    *pmlmeext;\r
2371         //struct mlme_ext_info  *pmlmeinfo;\r
2372         \r
2373         //DBG_871X("%s\n", __FUNCTION__);\r
2374 \r
2375         if(!padapter)\r
2376                 return;\r
2377 \r
2378         pmlmepriv = &(padapter->mlmepriv);\r
2379         pmlmeext = &(padapter->mlmeextpriv);\r
2380         //pmlmeinfo = &(pmlmeext->mlmext_info);\r
2381 \r
2382         if(_FALSE == pmlmeext->bstart_bss)\r
2383                 return;\r
2384 \r
2385         _enter_critical_bh(&pmlmepriv->bcn_update_lock, &irqL);\r
2386 \r
2387         switch(ie_id)\r
2388         {\r
2389                 case 0xFF:\r
2390 \r
2391                         update_bcn_fixed_ie(padapter);//8: TimeStamp, 2: Beacon Interval 2:Capability\r
2392                         \r
2393                         break;\r
2394         \r
2395                 case _TIM_IE_:\r
2396                         \r
2397                         update_BCNTIM(padapter);\r
2398                         \r
2399                         break;\r
2400 \r
2401                 case _ERPINFO_IE_:\r
2402 \r
2403                         update_bcn_erpinfo_ie(padapter);\r
2404 \r
2405                         break;\r
2406 \r
2407                 case _HT_CAPABILITY_IE_:\r
2408 \r
2409                         update_bcn_htcap_ie(padapter);\r
2410                         \r
2411                         break;\r
2412 \r
2413                 case _RSN_IE_2_:\r
2414 \r
2415                         update_bcn_rsn_ie(padapter);\r
2416 \r
2417                         break;\r
2418                         \r
2419                 case _HT_ADD_INFO_IE_:\r
2420 \r
2421                         update_bcn_htinfo_ie(padapter);\r
2422                         \r
2423                         break;\r
2424         \r
2425                 case _VENDOR_SPECIFIC_IE_:\r
2426 \r
2427                         update_bcn_vendor_spec_ie(padapter, oui);\r
2428                         \r
2429                         break;\r
2430                         \r
2431                 default:\r
2432                         break;\r
2433         }\r
2434 \r
2435         pmlmepriv->update_bcn = _TRUE;\r
2436         \r
2437         _exit_critical_bh(&pmlmepriv->bcn_update_lock, &irqL);          \r
2438         \r
2439 #ifndef CONFIG_INTERRUPT_BASED_TXBCN \r
2440 #if defined(CONFIG_USB_HCI) || defined(CONFIG_SDIO_HCI) || defined(CONFIG_GSPI_HCI)\r
2441         if(tx)\r
2442         {\r
2443                 //send_beacon(padapter);//send_beacon must execute on TSR level\r
2444                 set_tx_beacon_cmd(padapter);\r
2445         }\r
2446 #else\r
2447         {       \r
2448                 //PCI will issue beacon when BCN interrupt occurs.              \r
2449         }\r
2450 #endif\r
2451 #endif //!CONFIG_INTERRUPT_BASED_TXBCN\r
2452         \r
2453 }\r
2454 \r
2455 #ifdef CONFIG_80211N_HT\r
2456 \r
2457 /*\r
2458 op_mode\r
2459 Set to 0 (HT pure) under the followign conditions\r
2460         - all STAs in the BSS are 20/40 MHz HT in 20/40 MHz BSS or\r
2461         - all STAs in the BSS are 20 MHz HT in 20 MHz BSS\r
2462 Set to 1 (HT non-member protection) if there may be non-HT STAs\r
2463         in both the primary and the secondary channel\r
2464 Set to 2 if only HT STAs are associated in BSS,\r
2465         however and at least one 20 MHz HT STA is associated\r
2466 Set to 3 (HT mixed mode) when one or more non-HT STAs are associated\r
2467         (currently non-GF HT station is considered as non-HT STA also)\r
2468 */\r
2469 static int rtw_ht_operation_update(_adapter *padapter)\r
2470 {\r
2471         u16 cur_op_mode, new_op_mode;\r
2472         int op_mode_changes = 0;\r
2473         struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);\r
2474         struct ht_priv  *phtpriv_ap = &pmlmepriv->htpriv;\r
2475 \r
2476         if(pmlmepriv->htpriv.ht_option == _TRUE) \r
2477                 return 0;\r
2478         \r
2479         //if (!iface->conf->ieee80211n || iface->conf->ht_op_mode_fixed)\r
2480         //      return 0;\r
2481 \r
2482         DBG_871X("%s current operation mode=0x%X\n",\r
2483                    __FUNCTION__, pmlmepriv->ht_op_mode);\r
2484 \r
2485         if (!(pmlmepriv->ht_op_mode & HT_INFO_OPERATION_MODE_NON_GF_DEVS_PRESENT)\r
2486             && pmlmepriv->num_sta_ht_no_gf) {\r
2487                 pmlmepriv->ht_op_mode |=\r
2488                         HT_INFO_OPERATION_MODE_NON_GF_DEVS_PRESENT;\r
2489                 op_mode_changes++;\r
2490         } else if ((pmlmepriv->ht_op_mode &\r
2491                     HT_INFO_OPERATION_MODE_NON_GF_DEVS_PRESENT) &&\r
2492                    pmlmepriv->num_sta_ht_no_gf == 0) {\r
2493                 pmlmepriv->ht_op_mode &=\r
2494                         ~HT_INFO_OPERATION_MODE_NON_GF_DEVS_PRESENT;\r
2495                 op_mode_changes++;\r
2496         }\r
2497 \r
2498         if (!(pmlmepriv->ht_op_mode & HT_INFO_OPERATION_MODE_NON_HT_STA_PRESENT) &&\r
2499             (pmlmepriv->num_sta_no_ht || pmlmepriv->olbc_ht)) {\r
2500                 pmlmepriv->ht_op_mode |= HT_INFO_OPERATION_MODE_NON_HT_STA_PRESENT;\r
2501                 op_mode_changes++;\r
2502         } else if ((pmlmepriv->ht_op_mode &\r
2503                     HT_INFO_OPERATION_MODE_NON_HT_STA_PRESENT) &&\r
2504                    (pmlmepriv->num_sta_no_ht == 0 && !pmlmepriv->olbc_ht)) {\r
2505                 pmlmepriv->ht_op_mode &=\r
2506                         ~HT_INFO_OPERATION_MODE_NON_HT_STA_PRESENT;\r
2507                 op_mode_changes++;\r
2508         }\r
2509 \r
2510         /* Note: currently we switch to the MIXED op mode if HT non-greenfield\r
2511          * station is associated. Probably it's a theoretical case, since\r
2512          * it looks like all known HT STAs support greenfield.\r
2513          */\r
2514         new_op_mode = 0;\r
2515         if (pmlmepriv->num_sta_no_ht ||\r
2516             (pmlmepriv->ht_op_mode & HT_INFO_OPERATION_MODE_NON_GF_DEVS_PRESENT))\r
2517                 new_op_mode = OP_MODE_MIXED;\r
2518         else if ((phtpriv_ap->ht_cap.cap_info & IEEE80211_HT_CAP_SUP_WIDTH)\r
2519                  && pmlmepriv->num_sta_ht_20mhz)\r
2520                 new_op_mode = OP_MODE_20MHZ_HT_STA_ASSOCED;\r
2521         else if (pmlmepriv->olbc_ht)\r
2522                 new_op_mode = OP_MODE_MAY_BE_LEGACY_STAS;\r
2523         else\r
2524                 new_op_mode = OP_MODE_PURE;\r
2525 \r
2526         cur_op_mode = pmlmepriv->ht_op_mode & HT_INFO_OPERATION_MODE_OP_MODE_MASK;\r
2527         if (cur_op_mode != new_op_mode) {\r
2528                 pmlmepriv->ht_op_mode &= ~HT_INFO_OPERATION_MODE_OP_MODE_MASK;\r
2529                 pmlmepriv->ht_op_mode |= new_op_mode;\r
2530                 op_mode_changes++;\r
2531         }\r
2532 \r
2533         DBG_871X("%s new operation mode=0x%X changes=%d\n",\r
2534                    __FUNCTION__, pmlmepriv->ht_op_mode, op_mode_changes);\r
2535 \r
2536         return op_mode_changes;\r
2537         \r
2538 }\r
2539 \r
2540 #endif /* CONFIG_80211N_HT */\r
2541 \r
2542 void associated_clients_update(_adapter *padapter, u8 updated)\r
2543 {\r
2544         //update associcated stations cap.\r
2545         if(updated == _TRUE)\r
2546         {\r
2547                 _irqL irqL;\r
2548                 _list   *phead, *plist;\r
2549                 struct sta_info *psta=NULL;     \r
2550                 struct sta_priv *pstapriv = &padapter->stapriv;\r
2551                         \r
2552                 _enter_critical_bh(&pstapriv->asoc_list_lock, &irqL);\r
2553                 \r
2554                 phead = &pstapriv->asoc_list;\r
2555                 plist = get_next(phead);\r
2556                 \r
2557                 //check asoc_queue\r
2558                 while ((rtw_end_of_queue_search(phead, plist)) == _FALSE)       \r
2559                 {\r
2560                         psta = LIST_CONTAINOR(plist, struct sta_info, asoc_list);\r
2561                 \r
2562                         plist = get_next(plist);\r
2563 \r
2564                         VCS_update(padapter, psta);             \r
2565                 }\r
2566 \r
2567                 _exit_critical_bh(&pstapriv->asoc_list_lock, &irqL);\r
2568 \r
2569         }               \r
2570 \r
2571 }\r
2572 \r
2573 /* called > TSR LEVEL for USB or SDIO Interface*/\r
2574 void bss_cap_update_on_sta_join(_adapter *padapter, struct sta_info *psta)\r
2575 {\r
2576         u8 beacon_updated = _FALSE;\r
2577         struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);\r
2578         struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);\r
2579 \r
2580         \r
2581 #if 0\r
2582         if (!(psta->capability & WLAN_CAPABILITY_SHORT_PREAMBLE) &&\r
2583             !psta->no_short_preamble_set) {\r
2584                 psta->no_short_preamble_set = 1;\r
2585                 pmlmepriv->num_sta_no_short_preamble++;\r
2586                 if ((pmlmeext->cur_wireless_mode > WIRELESS_11B) && \r
2587                      (pmlmepriv->num_sta_no_short_preamble == 1))\r
2588                         ieee802_11_set_beacons(hapd->iface);\r
2589         }\r
2590 #endif\r
2591 \r
2592 \r
2593         if(!(psta->flags & WLAN_STA_SHORT_PREAMBLE))    \r
2594         {\r
2595                 if(!psta->no_short_preamble_set)\r
2596                 {\r
2597                         psta->no_short_preamble_set = 1;\r
2598                         \r
2599                         pmlmepriv->num_sta_no_short_preamble++;\r
2600                         \r
2601                         if ((pmlmeext->cur_wireless_mode > WIRELESS_11B) && \r
2602                                 (pmlmepriv->num_sta_no_short_preamble == 1))\r
2603                         {\r
2604                                 beacon_updated = _TRUE;\r
2605                                 update_beacon(padapter, 0xFF, NULL, _TRUE);\r
2606                         }       \r
2607                         \r
2608                 }\r
2609         }\r
2610         else\r
2611         {\r
2612                 if(psta->no_short_preamble_set)\r
2613                 {\r
2614                         psta->no_short_preamble_set = 0;\r
2615                         \r
2616                         pmlmepriv->num_sta_no_short_preamble--;\r
2617                         \r
2618                         if ((pmlmeext->cur_wireless_mode > WIRELESS_11B) && \r
2619                                 (pmlmepriv->num_sta_no_short_preamble == 0))\r
2620                         {\r
2621                                 beacon_updated = _TRUE;\r
2622                                 update_beacon(padapter, 0xFF, NULL, _TRUE);\r
2623                         }       \r
2624                         \r
2625                 }\r
2626         }\r
2627 \r
2628 #if 0\r
2629         if (psta->flags & WLAN_STA_NONERP && !psta->nonerp_set) {\r
2630                 psta->nonerp_set = 1;\r
2631                 pmlmepriv->num_sta_non_erp++;\r
2632                 if (pmlmepriv->num_sta_non_erp == 1)\r
2633                         ieee802_11_set_beacons(hapd->iface);\r
2634         }\r
2635 #endif\r
2636 \r
2637         if(psta->flags & WLAN_STA_NONERP)\r
2638         {\r
2639                 if(!psta->nonerp_set)\r
2640                 {\r
2641                         psta->nonerp_set = 1;\r
2642                         \r
2643                         pmlmepriv->num_sta_non_erp++;\r
2644                         \r
2645                         if (pmlmepriv->num_sta_non_erp == 1)\r
2646                         {\r
2647                                 beacon_updated = _TRUE;\r
2648                                 update_beacon(padapter, _ERPINFO_IE_, NULL, _TRUE);\r
2649                         }       \r
2650                 }\r
2651                 \r
2652         }\r
2653         else\r
2654         {\r
2655                 if(psta->nonerp_set)\r
2656                 {\r
2657                         psta->nonerp_set = 0;\r
2658                         \r
2659                         pmlmepriv->num_sta_non_erp--;\r
2660                         \r
2661                         if (pmlmepriv->num_sta_non_erp == 0)\r
2662                         {\r
2663                                 beacon_updated = _TRUE;\r
2664                                 update_beacon(padapter, _ERPINFO_IE_, NULL, _TRUE);\r
2665                         }       \r
2666                 }\r
2667                 \r
2668         }\r
2669 \r
2670 \r
2671 #if 0\r
2672         if (!(psta->capability & WLAN_CAPABILITY_SHORT_SLOT) &&\r
2673             !psta->no_short_slot_time_set) {\r
2674                 psta->no_short_slot_time_set = 1;\r
2675                 pmlmepriv->num_sta_no_short_slot_time++;\r
2676                 if ((pmlmeext->cur_wireless_mode > WIRELESS_11B) &&\r
2677                     (pmlmepriv->num_sta_no_short_slot_time == 1))\r
2678                         ieee802_11_set_beacons(hapd->iface);\r
2679         }\r
2680 #endif\r
2681 \r
2682         if(!(psta->capability & WLAN_CAPABILITY_SHORT_SLOT))\r
2683         {\r
2684                 if(!psta->no_short_slot_time_set)\r
2685                 {\r
2686                         psta->no_short_slot_time_set = 1;\r
2687                         \r
2688                         pmlmepriv->num_sta_no_short_slot_time++;\r
2689                         \r
2690                         if ((pmlmeext->cur_wireless_mode > WIRELESS_11B) &&\r
2691                                  (pmlmepriv->num_sta_no_short_slot_time == 1))\r
2692                         {\r
2693                                 beacon_updated = _TRUE;\r
2694                                 update_beacon(padapter, 0xFF, NULL, _TRUE);\r
2695                         }                       \r
2696                         \r
2697                 }\r
2698         }\r
2699         else\r
2700         {\r
2701                 if(psta->no_short_slot_time_set)\r
2702                 {\r
2703                         psta->no_short_slot_time_set = 0;\r
2704                         \r
2705                         pmlmepriv->num_sta_no_short_slot_time--;\r
2706                         \r
2707                         if ((pmlmeext->cur_wireless_mode > WIRELESS_11B) &&\r
2708                                  (pmlmepriv->num_sta_no_short_slot_time == 0))\r
2709                         {\r
2710                                 beacon_updated = _TRUE;\r
2711                                 update_beacon(padapter, 0xFF, NULL, _TRUE);\r
2712                         }                       \r
2713                 }\r
2714         }       \r
2715         \r
2716 #ifdef CONFIG_80211N_HT\r
2717 \r
2718         if (psta->flags & WLAN_STA_HT) \r
2719         {\r
2720                 u16 ht_capab = le16_to_cpu(psta->htpriv.ht_cap.cap_info);\r
2721                         \r
2722                 DBG_871X("HT: STA " MAC_FMT " HT Capabilities "\r
2723                            "Info: 0x%04x\n", MAC_ARG(psta->hwaddr), ht_capab);\r
2724 \r
2725                 if (psta->no_ht_set) {\r
2726                         psta->no_ht_set = 0;\r
2727                         pmlmepriv->num_sta_no_ht--;\r
2728                 }\r
2729                 \r
2730                 if ((ht_capab & IEEE80211_HT_CAP_GRN_FLD) == 0) {\r
2731                         if (!psta->no_ht_gf_set) {\r
2732                                 psta->no_ht_gf_set = 1;\r
2733                                 pmlmepriv->num_sta_ht_no_gf++;\r
2734                         }\r
2735                         DBG_871X("%s STA " MAC_FMT " - no "\r
2736                                    "greenfield, num of non-gf stations %d\n",\r
2737                                    __FUNCTION__, MAC_ARG(psta->hwaddr),\r
2738                                    pmlmepriv->num_sta_ht_no_gf);\r
2739                 }\r
2740                 \r
2741                 if ((ht_capab & IEEE80211_HT_CAP_SUP_WIDTH) == 0) {\r
2742                         if (!psta->ht_20mhz_set) {\r
2743                                 psta->ht_20mhz_set = 1;\r
2744                                 pmlmepriv->num_sta_ht_20mhz++;\r
2745                         }\r
2746                         DBG_871X("%s STA " MAC_FMT " - 20 MHz HT, "\r
2747                                    "num of 20MHz HT STAs %d\n",\r
2748                                    __FUNCTION__, MAC_ARG(psta->hwaddr),\r
2749                                    pmlmepriv->num_sta_ht_20mhz);\r
2750                 }\r
2751                 \r
2752         } \r
2753         else \r
2754         {\r
2755                 if (!psta->no_ht_set) {\r
2756                         psta->no_ht_set = 1;\r
2757                         pmlmepriv->num_sta_no_ht++;\r
2758                 }\r
2759                 if(pmlmepriv->htpriv.ht_option == _TRUE) {              \r
2760                         DBG_871X("%s STA " MAC_FMT\r
2761                                    " - no HT, num of non-HT stations %d\n",\r
2762                                    __FUNCTION__, MAC_ARG(psta->hwaddr),\r
2763                                    pmlmepriv->num_sta_no_ht);\r
2764                 }\r
2765         }\r
2766 \r
2767         if (rtw_ht_operation_update(padapter) > 0)\r
2768         {\r
2769                 update_beacon(padapter, _HT_CAPABILITY_IE_, NULL, _FALSE);\r
2770                 update_beacon(padapter, _HT_ADD_INFO_IE_, NULL, _TRUE);\r
2771         }       \r
2772         \r
2773 #endif /* CONFIG_80211N_HT */\r
2774 \r
2775         //update associcated stations cap.\r
2776         associated_clients_update(padapter,  beacon_updated);\r
2777 \r
2778         DBG_871X("%s, updated=%d\n", __func__, beacon_updated);\r
2779 \r
2780 }\r
2781 \r
2782 u8 bss_cap_update_on_sta_leave(_adapter *padapter, struct sta_info *psta)\r
2783 {\r
2784         u8 beacon_updated = _FALSE;\r
2785         struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);\r
2786         struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);\r
2787 \r
2788         if(!psta)\r
2789                 return beacon_updated;\r
2790 \r
2791         if (psta->no_short_preamble_set) {\r
2792                 psta->no_short_preamble_set = 0;\r
2793                 pmlmepriv->num_sta_no_short_preamble--;\r
2794                 if (pmlmeext->cur_wireless_mode > WIRELESS_11B\r
2795                     && pmlmepriv->num_sta_no_short_preamble == 0)\r
2796                 {\r
2797                         beacon_updated = _TRUE;\r
2798                         update_beacon(padapter, 0xFF, NULL, _TRUE);\r
2799                 }       \r
2800         }       \r
2801 \r
2802         if (psta->nonerp_set) {\r
2803                 psta->nonerp_set = 0;           \r
2804                 pmlmepriv->num_sta_non_erp--;\r
2805                 if (pmlmepriv->num_sta_non_erp == 0)\r
2806                 {\r
2807                         beacon_updated = _TRUE;\r
2808                         update_beacon(padapter, _ERPINFO_IE_, NULL, _TRUE);\r
2809                 }       \r
2810         }\r
2811 \r
2812         if (psta->no_short_slot_time_set) {\r
2813                 psta->no_short_slot_time_set = 0;\r
2814                 pmlmepriv->num_sta_no_short_slot_time--;\r
2815                 if (pmlmeext->cur_wireless_mode > WIRELESS_11B\r
2816                     && pmlmepriv->num_sta_no_short_slot_time == 0)\r
2817                 {\r
2818                         beacon_updated = _TRUE;\r
2819                         update_beacon(padapter, 0xFF, NULL, _TRUE);\r
2820                 }       \r
2821         }\r
2822         \r
2823 #ifdef CONFIG_80211N_HT\r
2824 \r
2825         if (psta->no_ht_gf_set) {\r
2826                 psta->no_ht_gf_set = 0;\r
2827                 pmlmepriv->num_sta_ht_no_gf--;\r
2828         }\r
2829 \r
2830         if (psta->no_ht_set) {\r
2831                 psta->no_ht_set = 0;\r
2832                 pmlmepriv->num_sta_no_ht--;\r
2833         }\r
2834 \r
2835         if (psta->ht_20mhz_set) {\r
2836                 psta->ht_20mhz_set = 0;\r
2837                 pmlmepriv->num_sta_ht_20mhz--;\r
2838         }\r
2839 \r
2840         if (rtw_ht_operation_update(padapter) > 0)\r
2841         {\r
2842                 update_beacon(padapter, _HT_CAPABILITY_IE_, NULL, _FALSE);\r
2843                 update_beacon(padapter, _HT_ADD_INFO_IE_, NULL, _TRUE);\r
2844         }\r
2845         \r
2846 #endif /* CONFIG_80211N_HT */\r
2847 \r
2848         //update associcated stations cap.\r
2849         //associated_clients_update(padapter,  beacon_updated); //move it to avoid deadlock\r
2850 \r
2851         DBG_871X("%s, updated=%d\n", __func__, beacon_updated);\r
2852 \r
2853         return beacon_updated;\r
2854 \r
2855 }\r
2856 \r
2857 u8 ap_free_sta(_adapter *padapter, struct sta_info *psta, bool active, u16 reason)\r
2858 {\r
2859         _irqL irqL;\r
2860         u8 beacon_updated = _FALSE;\r
2861         struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);\r
2862         struct mlme_ext_priv    *pmlmeext = &(padapter->mlmeextpriv);\r
2863         struct sta_priv *pstapriv = &padapter->stapriv;\r
2864 \r
2865         if(!psta)\r
2866                 return beacon_updated;\r
2867 \r
2868         if (active == _TRUE)\r
2869         {\r
2870 #ifdef CONFIG_80211N_HT\r
2871                 //tear down Rx AMPDU\r
2872                 send_delba(padapter, 0, psta->hwaddr);// recipient\r
2873         \r
2874                 //tear down TX AMPDU\r
2875                 send_delba(padapter, 1, psta->hwaddr);// // originator\r
2876                 \r
2877 #endif //CONFIG_80211N_HT\r
2878 \r
2879                 issue_deauth(padapter, psta->hwaddr, reason);\r
2880         }\r
2881 \r
2882         psta->htpriv.agg_enable_bitmap = 0x0;//reset\r
2883         psta->htpriv.candidate_tid_bitmap = 0x0;//reset\r
2884 \r
2885 \r
2886         //report_del_sta_event(padapter, psta->hwaddr, reason);\r
2887 \r
2888         //clear cam entry / key\r
2889         rtw_clearstakey_cmd(padapter, psta, _TRUE);\r
2890 \r
2891 \r
2892         _enter_critical_bh(&psta->lock, &irqL);\r
2893         psta->state &= ~_FW_LINKED;\r
2894         _exit_critical_bh(&psta->lock, &irqL);\r
2895 \r
2896         #ifdef CONFIG_IOCTL_CFG80211\r
2897         if (1) {\r
2898                 #ifdef COMPAT_KERNEL_RELEASE\r
2899                 rtw_cfg80211_indicate_sta_disassoc(padapter, psta->hwaddr, reason);\r
2900                 #elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37)) && !defined(CONFIG_CFG80211_FORCE_COMPATIBLE_2_6_37_UNDER)\r
2901                 rtw_cfg80211_indicate_sta_disassoc(padapter, psta->hwaddr, reason);\r
2902                 #else //(LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37)) && !defined(CONFIG_CFG80211_FORCE_COMPATIBLE_2_6_37_UNDER)\r
2903                 /* will call rtw_cfg80211_indicate_sta_disassoc() in cmd_thread for old API context */\r
2904                 #endif //(LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37)) && !defined(CONFIG_CFG80211_FORCE_COMPATIBLE_2_6_37_UNDER)\r
2905         } else\r
2906         #endif //CONFIG_IOCTL_CFG80211\r
2907         {\r
2908                 rtw_indicate_sta_disassoc_event(padapter, psta);\r
2909         }\r
2910 \r
2911         report_del_sta_event(padapter, psta->hwaddr, reason);\r
2912 \r
2913         beacon_updated = bss_cap_update_on_sta_leave(padapter, psta);\r
2914 \r
2915         _enter_critical_bh(&(pstapriv->sta_hash_lock), &irqL);                                  \r
2916         rtw_free_stainfo(padapter, psta);\r
2917         _exit_critical_bh(&(pstapriv->sta_hash_lock), &irqL);\r
2918         \r
2919 \r
2920         return beacon_updated;\r
2921 \r
2922 }\r
2923 \r
2924 int rtw_ap_inform_ch_switch(_adapter *padapter, u8 new_ch, u8 ch_offset)\r
2925 {\r
2926         _irqL irqL;\r
2927         _list   *phead, *plist;\r
2928         int ret=0;      \r
2929         struct sta_info *psta = NULL;   \r
2930         struct sta_priv *pstapriv = &padapter->stapriv;\r
2931         struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;\r
2932         struct mlme_ext_info    *pmlmeinfo = &(pmlmeext->mlmext_info);\r
2933         u8 bc_addr[ETH_ALEN] = {0xff,0xff,0xff,0xff,0xff,0xff};\r
2934 \r
2935         if((pmlmeinfo->state&0x03) != WIFI_FW_AP_STATE)\r
2936                 return ret;\r
2937 \r
2938         DBG_871X(FUNC_NDEV_FMT" with ch:%u, offset:%u\n",\r
2939                 FUNC_NDEV_ARG(padapter->pnetdev), new_ch, ch_offset);\r
2940 \r
2941         _enter_critical_bh(&pstapriv->asoc_list_lock, &irqL);\r
2942         phead = &pstapriv->asoc_list;\r
2943         plist = get_next(phead);\r
2944         \r
2945         /* for each sta in asoc_queue */\r
2946         while ((rtw_end_of_queue_search(phead, plist)) == _FALSE)       \r
2947         {               \r
2948                 psta = LIST_CONTAINOR(plist, struct sta_info, asoc_list);\r
2949                 plist = get_next(plist);\r
2950 \r
2951                 issue_action_spct_ch_switch(padapter, psta->hwaddr, new_ch, ch_offset);\r
2952                 psta->expire_to = ((pstapriv->expire_to * 2) > 5) ? 5 : (pstapriv->expire_to * 2);\r
2953         }\r
2954         _exit_critical_bh(&pstapriv->asoc_list_lock, &irqL);\r
2955 \r
2956         issue_action_spct_ch_switch(padapter, bc_addr, new_ch, ch_offset);\r
2957 \r
2958         return ret;\r
2959 }\r
2960 \r
2961 int rtw_sta_flush(_adapter *padapter)\r
2962 {\r
2963         _irqL irqL;\r
2964         _list   *phead, *plist;\r
2965         int ret=0;      \r
2966         struct sta_info *psta = NULL;   \r
2967         struct sta_priv *pstapriv = &padapter->stapriv;\r
2968         struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;\r
2969         struct mlme_ext_info    *pmlmeinfo = &(pmlmeext->mlmext_info);\r
2970         u8 bc_addr[ETH_ALEN] = {0xff,0xff,0xff,0xff,0xff,0xff};\r
2971 \r
2972         DBG_871X(FUNC_NDEV_FMT"\n", FUNC_NDEV_ARG(padapter->pnetdev));\r
2973 \r
2974         if((pmlmeinfo->state&0x03) != WIFI_FW_AP_STATE)\r
2975                 return ret;\r
2976 \r
2977 \r
2978         _enter_critical_bh(&pstapriv->asoc_list_lock, &irqL);\r
2979         phead = &pstapriv->asoc_list;\r
2980         plist = get_next(phead);\r
2981 \r
2982         //free sta asoc_queue\r
2983         while ((rtw_end_of_queue_search(phead, plist)) == _FALSE)\r
2984         {\r
2985                 psta = LIST_CONTAINOR(plist, struct sta_info, asoc_list);\r
2986                 \r
2987                 plist = get_next(plist);\r
2988 \r
2989                 rtw_list_delete(&psta->asoc_list);\r
2990                 pstapriv->asoc_list_cnt--;\r
2991 \r
2992                 //_exit_critical_bh(&pstapriv->asoc_list_lock, &irqL);\r
2993                 ap_free_sta(padapter, psta, _TRUE, WLAN_REASON_DEAUTH_LEAVING);\r
2994                 //_enter_critical_bh(&pstapriv->asoc_list_lock, &irqL);\r
2995         }\r
2996         _exit_critical_bh(&pstapriv->asoc_list_lock, &irqL);\r
2997 \r
2998 \r
2999         issue_deauth(padapter, bc_addr, WLAN_REASON_DEAUTH_LEAVING);\r
3000 \r
3001         associated_clients_update(padapter, _TRUE);\r
3002 \r
3003         return ret;\r
3004 \r
3005 }\r
3006 \r
3007 /* called > TSR LEVEL for USB or SDIO Interface*/\r
3008 void sta_info_update(_adapter *padapter, struct sta_info *psta)\r
3009 {       \r
3010         int flags = psta->flags;\r
3011         struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);\r
3012         \r
3013                                 \r
3014         //update wmm cap.\r
3015         if(WLAN_STA_WME&flags)\r
3016                 psta->qos_option = 1;\r
3017         else\r
3018                 psta->qos_option = 0;\r
3019 \r
3020         if(pmlmepriv->qospriv.qos_option == 0)  \r
3021                 psta->qos_option = 0;\r
3022 \r
3023                 \r
3024 #ifdef CONFIG_80211N_HT         \r
3025         //update 802.11n ht cap.\r
3026         if(WLAN_STA_HT&flags)\r
3027         {\r
3028                 psta->htpriv.ht_option = _TRUE;\r
3029                 psta->qos_option = 1;   \r
3030         }\r
3031         else            \r
3032         {\r
3033                 psta->htpriv.ht_option = _FALSE;\r
3034         }\r
3035                 \r
3036         if(pmlmepriv->htpriv.ht_option == _FALSE)       \r
3037                 psta->htpriv.ht_option = _FALSE;\r
3038 #endif\r
3039 \r
3040 #ifdef CONFIG_80211AC_VHT\r
3041         //update 802.11AC vht cap.\r
3042         if(WLAN_STA_VHT&flags)\r
3043         {\r
3044                 psta->vhtpriv.vht_option = _TRUE;\r
3045         }\r
3046         else            \r
3047         {\r
3048                 psta->vhtpriv.vht_option = _FALSE;\r
3049         }\r
3050 \r
3051         if(pmlmepriv->vhtpriv.vht_option == _FALSE)\r
3052                 psta->vhtpriv.vht_option = _FALSE;\r
3053 #endif  \r
3054 \r
3055 \r
3056         update_sta_info_apmode(padapter, psta);\r
3057                 \r
3058 \r
3059 }\r
3060 \r
3061 /* called >= TSR LEVEL for USB or SDIO Interface*/\r
3062 void ap_sta_info_defer_update(_adapter *padapter, struct sta_info *psta)\r
3063 {\r
3064         struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;\r
3065         struct mlme_ext_info    *pmlmeinfo = &(pmlmeext->mlmext_info);\r
3066 \r
3067         if(psta->state & _FW_LINKED)\r
3068         {\r
3069                 pmlmeinfo->FW_sta_info[psta->mac_id].psta = psta;\r
3070         \r
3071                 //add ratid\r
3072                 add_RATid(padapter, psta, 0);//DM_RATR_STA_INIT\r
3073         }       \r
3074 }\r
3075 /* restore hw setting from sw data structures */\r
3076 void rtw_ap_restore_network(_adapter *padapter)\r
3077 {\r
3078         struct mlme_priv *mlmepriv = &padapter->mlmepriv;\r
3079         struct mlme_ext_priv    *pmlmeext = &padapter->mlmeextpriv;\r
3080         struct mlme_ext_info    *pmlmeinfo = &(pmlmeext->mlmext_info);\r
3081         struct sta_priv * pstapriv = &padapter->stapriv;\r
3082         struct sta_info *psta;\r
3083         struct security_priv* psecuritypriv=&(padapter->securitypriv);\r
3084         _irqL irqL;\r
3085         _list   *phead, *plist;\r
3086         u8 chk_alive_num = 0;\r
3087         char chk_alive_list[NUM_STA];\r
3088         int i;\r
3089 \r
3090         rtw_setopmode_cmd(padapter, Ndis802_11APMode,_FALSE);\r
3091 \r
3092         set_channel_bwmode(padapter, pmlmeext->cur_channel, pmlmeext->cur_ch_offset, pmlmeext->cur_bwmode);\r
3093 \r
3094         start_bss_network(padapter, (u8*)&mlmepriv->cur_network.network);\r
3095 \r
3096         if((padapter->securitypriv.dot11PrivacyAlgrthm == _TKIP_) ||\r
3097                 (padapter->securitypriv.dot11PrivacyAlgrthm == _AES_))\r
3098         {\r
3099                 /* restore group key, WEP keys is restored in ips_leave() */\r
3100                 rtw_set_key(padapter, psecuritypriv, psecuritypriv->dot118021XGrpKeyid, 0,_FALSE);\r
3101         }\r
3102 \r
3103         _enter_critical_bh(&pstapriv->asoc_list_lock, &irqL);\r
3104         \r
3105         phead = &pstapriv->asoc_list;\r
3106         plist = get_next(phead);\r
3107 \r
3108         while ((rtw_end_of_queue_search(phead, plist)) == _FALSE) {\r
3109                 int stainfo_offset;\r
3110 \r
3111                 psta = LIST_CONTAINOR(plist, struct sta_info, asoc_list);\r
3112                 plist = get_next(plist);\r
3113 \r
3114                 stainfo_offset = rtw_stainfo_offset(pstapriv, psta);\r
3115                 if (stainfo_offset_valid(stainfo_offset)) {\r
3116                         chk_alive_list[chk_alive_num++] = stainfo_offset;\r
3117                 }\r
3118         }\r
3119 \r
3120         _exit_critical_bh(&pstapriv->asoc_list_lock, &irqL);\r
3121 \r
3122         for (i = 0; i < chk_alive_num; i++) {\r
3123                 psta = rtw_get_stainfo_by_offset(pstapriv, chk_alive_list[i]);\r
3124 \r
3125                 if (psta == NULL) {\r
3126                         DBG_871X(FUNC_ADPT_FMT" sta_info is null\n", FUNC_ADPT_ARG(padapter));\r
3127                 } else if (psta->state &_FW_LINKED) {\r
3128                         rtw_sta_media_status_rpt(padapter, psta, 1);\r
3129                         Update_RA_Entry(padapter, psta);\r
3130                         //pairwise key\r
3131                         /* per sta pairwise key and settings */\r
3132                         if(     (padapter->securitypriv.dot11PrivacyAlgrthm == _TKIP_) ||\r
3133                                 (padapter->securitypriv.dot11PrivacyAlgrthm == _AES_))\r
3134                         {\r
3135                                 rtw_setstakey_cmd(padapter, psta, _TRUE,_FALSE);\r
3136                         }                       \r
3137                 }\r
3138         }\r
3139 \r
3140 }\r
3141 \r
3142 void start_ap_mode(_adapter *padapter)\r
3143 {\r
3144         int i;\r
3145         struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);\r
3146         struct sta_priv *pstapriv = &padapter->stapriv;\r
3147         struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;\r
3148         struct wlan_acl_pool *pacl_list = &pstapriv->acl_list;\r
3149         \r
3150         pmlmepriv->update_bcn = _FALSE;\r
3151         \r
3152         //init_mlme_ap_info(padapter);\r
3153         pmlmeext->bstart_bss = _FALSE;\r
3154 \r
3155         pmlmepriv->num_sta_non_erp = 0;\r
3156 \r
3157         pmlmepriv->num_sta_no_short_slot_time = 0;\r
3158 \r
3159         pmlmepriv->num_sta_no_short_preamble = 0;\r
3160 \r
3161         pmlmepriv->num_sta_ht_no_gf = 0;\r
3162 #ifdef CONFIG_80211N_HT\r
3163         pmlmepriv->num_sta_no_ht = 0;\r
3164 #endif //CONFIG_80211N_HT\r
3165         pmlmepriv->num_sta_ht_20mhz = 0;\r
3166 \r
3167         pmlmepriv->olbc = _FALSE;\r
3168 \r
3169         pmlmepriv->olbc_ht = _FALSE;\r
3170         \r
3171 #ifdef CONFIG_80211N_HT\r
3172         pmlmepriv->ht_op_mode = 0;\r
3173 #endif\r
3174 \r
3175         for(i=0; i<NUM_STA; i++)\r
3176                 pstapriv->sta_aid[i] = NULL;\r
3177 \r
3178         pmlmepriv->wps_beacon_ie = NULL;        \r
3179         pmlmepriv->wps_probe_resp_ie = NULL;\r
3180         pmlmepriv->wps_assoc_resp_ie = NULL;\r
3181         \r
3182         pmlmepriv->p2p_beacon_ie = NULL;\r
3183         pmlmepriv->p2p_probe_resp_ie = NULL;\r
3184 \r
3185         \r
3186         //for ACL \r
3187         _rtw_init_listhead(&(pacl_list->acl_node_q.queue));\r
3188         pacl_list->num = 0;\r
3189         pacl_list->mode = 0;\r
3190         for(i = 0; i < NUM_ACL; i++)\r
3191         {               \r
3192                 _rtw_init_listhead(&pacl_list->aclnode[i].list);\r
3193                 pacl_list->aclnode[i].valid = _FALSE;\r
3194         }\r
3195 \r
3196 }\r
3197 \r
3198 void stop_ap_mode(_adapter *padapter)\r
3199 {\r
3200         _irqL irqL;\r
3201         _list   *phead, *plist;\r
3202         struct rtw_wlan_acl_node *paclnode;\r
3203         struct sta_info *psta=NULL;\r
3204         struct sta_priv *pstapriv = &padapter->stapriv;\r
3205         struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);\r
3206         struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;        \r
3207         struct wlan_acl_pool *pacl_list = &pstapriv->acl_list;\r
3208         _queue  *pacl_node_q =&pacl_list->acl_node_q;   \r
3209 \r
3210         pmlmepriv->update_bcn = _FALSE;\r
3211         pmlmeext->bstart_bss = _FALSE;\r
3212         //_rtw_spinlock_free(&pmlmepriv->bcn_update_lock);\r
3213         \r
3214         //reset and init security priv , this can refine with rtw_reset_securitypriv\r
3215         _rtw_memset((unsigned char *)&padapter->securitypriv, 0, sizeof (struct security_priv));\r
3216         padapter->securitypriv.ndisauthtype = Ndis802_11AuthModeOpen;\r
3217         padapter->securitypriv.ndisencryptstatus = Ndis802_11WEPDisabled;\r
3218 \r
3219         //for ACL\r
3220         _enter_critical_bh(&(pacl_node_q->lock), &irqL);\r
3221         phead = get_list_head(pacl_node_q);\r
3222         plist = get_next(phead);                \r
3223         while ((rtw_end_of_queue_search(phead, plist)) == _FALSE)\r
3224         {\r
3225                 paclnode = LIST_CONTAINOR(plist, struct rtw_wlan_acl_node, list);\r
3226                 plist = get_next(plist);\r
3227 \r
3228                 if(paclnode->valid == _TRUE)\r
3229                 {\r
3230                         paclnode->valid = _FALSE;\r
3231 \r
3232                         rtw_list_delete(&paclnode->list);\r
3233                                 \r
3234                         pacl_list->num--;               \r
3235                 }               \r
3236         }       \r
3237         _exit_critical_bh(&(pacl_node_q->lock), &irqL);\r
3238         \r
3239         DBG_871X("%s, free acl_node_queue, num=%d\n", __func__, pacl_list->num);\r
3240         \r
3241         rtw_sta_flush(padapter);\r
3242 \r
3243         //free_assoc_sta_resources      \r
3244         rtw_free_all_stainfo(padapter);\r
3245         \r
3246         psta = rtw_get_bcmc_stainfo(padapter);\r
3247         _enter_critical_bh(&(pstapriv->sta_hash_lock), &irqL);          \r
3248         rtw_free_stainfo(padapter, psta);\r
3249         _exit_critical_bh(&(pstapriv->sta_hash_lock), &irqL);\r
3250         \r
3251         rtw_init_bcmc_stainfo(padapter);        \r
3252 \r
3253         rtw_free_mlme_priv_ie_data(pmlmepriv);\r
3254 \r
3255 #ifdef CONFIG_BT_COEXIST\r
3256         rtw_btcoex_MediaStatusNotify(padapter, 0); //disconnect \r
3257 #endif  \r
3258 \r
3259 }\r
3260 \r
3261 #endif //CONFIG_NATIVEAP_MLME\r
3262 \r
3263 #ifdef CONFIG_CONCURRENT_MODE\r
3264 void concurrent_set_ap_chbw(_adapter *padapter, u8 channel, u8 channel_offset, u8 bwmode)\r
3265 {\r
3266         u8 *p;\r
3267         int     ie_len=0;\r
3268         u8 cur_channel, cur_bwmode, cur_ch_offset, change_band;\r
3269         struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);\r
3270         WLAN_BSSID_EX *pnetwork = (WLAN_BSSID_EX *)&pmlmepriv->cur_network.network;\r
3271         struct mlme_ext_priv    *pmlmeext = &(padapter->mlmeextpriv);\r
3272         struct HT_info_element *pht_info=NULL;\r
3273         \r
3274         cur_channel = channel;\r
3275         cur_bwmode = bwmode;\r
3276         cur_ch_offset = channel_offset;\r
3277         change_band = _FALSE;\r
3278         \r
3279         p = rtw_get_ie((pnetwork->IEs + sizeof(NDIS_802_11_FIXED_IEs)), _HT_ADD_INFO_IE_, &ie_len, (pnetwork->IELength - sizeof(NDIS_802_11_FIXED_IEs)));\r
3280         if( p && ie_len)\r
3281         {\r
3282                 pht_info = (struct HT_info_element *)(p+2);\r
3283         }\r
3284 \r
3285         \r
3286         if(!check_buddy_fwstate(padapter, _FW_LINKED|_FW_UNDER_LINKING|_FW_UNDER_SURVEY))\r
3287         {\r
3288                 set_channel_bwmode(padapter, cur_channel, cur_ch_offset, cur_bwmode);\r
3289         }\r
3290         else if(check_buddy_fwstate(padapter, _FW_LINKED)==_TRUE)\r
3291         {\r
3292                 _adapter *pbuddy_adapter = padapter->pbuddy_adapter;            \r
3293                 struct mlme_ext_priv *pbuddy_mlmeext = &pbuddy_adapter->mlmeextpriv;\r
3294 \r
3295                 //To sync cur_channel/cur_bwmode/cur_ch_offset with buddy adapter\r
3296                 DBG_871X(ADPT_FMT" is at linked state\n", ADPT_ARG(pbuddy_adapter));\r
3297                 DBG_871X(ADPT_FMT": CH=%d, BW=%d, offset=%d\n", ADPT_ARG(pbuddy_adapter), pbuddy_mlmeext->cur_channel, pbuddy_mlmeext->cur_bwmode, pbuddy_mlmeext->cur_ch_offset);\r
3298                 DBG_871X(ADPT_FMT": CH=%d, BW=%d, offset=%d\n", ADPT_ARG(padapter), cur_channel, cur_bwmode, cur_ch_offset);\r
3299 \r
3300                 if((cur_channel <= 14 && pbuddy_mlmeext->cur_channel >= 36) ||\r
3301                         (cur_channel >= 36 && pbuddy_mlmeext->cur_channel <= 14))\r
3302                         change_band = _TRUE;\r
3303 \r
3304                 cur_channel = pbuddy_mlmeext->cur_channel;\r
3305 \r
3306 #ifdef CONFIG_80211AC_VHT\r
3307                 if(cur_bwmode == CHANNEL_WIDTH_80)\r
3308                 {\r
3309                         u8 *pvht_cap_ie, *pvht_op_ie;\r
3310                         int vht_cap_ielen, vht_op_ielen;\r
3311                         \r
3312                         pvht_cap_ie = rtw_get_ie((pnetwork->IEs + sizeof(NDIS_802_11_FIXED_IEs)), EID_VHTCapability, &vht_cap_ielen, (pnetwork->IELength - sizeof(NDIS_802_11_FIXED_IEs)));\r
3313                         pvht_op_ie = rtw_get_ie((pnetwork->IEs + sizeof(NDIS_802_11_FIXED_IEs)), EID_VHTOperation, &vht_op_ielen, (pnetwork->IELength - sizeof(NDIS_802_11_FIXED_IEs)));\r
3314                                                 \r
3315                         if(pbuddy_mlmeext->cur_channel <= 14) // downgrade to 20/40Mhz\r
3316                         {\r
3317                                 //modify vht cap ie\r
3318                                 if( pvht_cap_ie && vht_cap_ielen)\r
3319                                 {\r
3320                                         SET_VHT_CAPABILITY_ELE_SHORT_GI80M(pvht_cap_ie+2, 0);\r
3321                                 }\r
3322                                 \r
3323                                 //modify vht op ie\r
3324                                 if( pvht_op_ie && vht_op_ielen)\r
3325                                 {\r
3326                                         SET_VHT_OPERATION_ELE_CHL_WIDTH(pvht_op_ie+2, 0); //change to 20/40Mhz\r
3327                                         SET_VHT_OPERATION_ELE_CHL_CENTER_FREQ1(pvht_op_ie+2, 0);\r
3328                                         SET_VHT_OPERATION_ELE_CHL_CENTER_FREQ2(pvht_op_ie+2, 0);\r
3329                                         //SET_VHT_OPERATION_ELE_BASIC_MCS_SET(p+2, 0xFFFF);                                     \r
3330                                         cur_bwmode = CHANNEL_WIDTH_40;\r
3331                                 }               \r
3332                         }\r
3333                         else\r
3334                         {\r
3335                                 u8      center_freq;\r
3336                                 \r
3337                                 cur_bwmode = CHANNEL_WIDTH_80;\r
3338                                 \r
3339                                 if(pbuddy_mlmeext->cur_bwmode == CHANNEL_WIDTH_40 ||\r
3340                                         pbuddy_mlmeext->cur_bwmode == CHANNEL_WIDTH_80)\r
3341                                 {\r
3342                                         cur_ch_offset = pbuddy_mlmeext->cur_ch_offset;\r
3343                                 }\r
3344                                 else if(pbuddy_mlmeext->cur_bwmode == CHANNEL_WIDTH_20)\r
3345                                 {\r
3346                                         cur_ch_offset =  rtw_get_offset_by_ch(cur_channel);\r
3347                                 }       \r
3348 \r
3349                                 //modify ht info ie\r
3350                                 if(pht_info)\r
3351                                         pht_info->infos[0] &= ~HT_INFO_HT_PARAM_SECONDARY_CHNL_OFF_MASK;\r
3352                                 \r
3353                                 switch(cur_ch_offset)\r
3354                                 {\r
3355                                         case HAL_PRIME_CHNL_OFFSET_LOWER:\r
3356                                                 if(pht_info)\r
3357                                                         pht_info->infos[0] |= HT_INFO_HT_PARAM_SECONDARY_CHNL_ABOVE;            \r
3358                                                 //cur_bwmode = CHANNEL_WIDTH_40;\r
3359                                                 break;\r
3360                                         case HAL_PRIME_CHNL_OFFSET_UPPER:\r
3361                                                 if(pht_info)\r
3362                                                         pht_info->infos[0] |= HT_INFO_HT_PARAM_SECONDARY_CHNL_BELOW;                                            \r
3363                                                 //cur_bwmode = CHANNEL_WIDTH_40;\r
3364                                                 break;\r
3365                                         case HAL_PRIME_CHNL_OFFSET_DONT_CARE:                                                   \r
3366                                         default:\r
3367                                                 if(pht_info)\r
3368                                                         pht_info->infos[0] &= ~HT_INFO_HT_PARAM_SECONDARY_CHNL_OFF_MASK;\r
3369                                                 cur_bwmode = CHANNEL_WIDTH_20;\r
3370                                                 cur_ch_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE;\r
3371                                                 break;                                  \r
3372                                 }\r
3373 \r
3374                                 //modify vht op ie\r
3375                                 center_freq = rtw_get_center_ch(cur_channel, cur_bwmode, HAL_PRIME_CHNL_OFFSET_LOWER);\r
3376                                 if( pvht_op_ie && vht_op_ielen)\r
3377                                         SET_VHT_OPERATION_ELE_CHL_CENTER_FREQ1(pvht_op_ie+2, center_freq);\r
3378 \r
3379                                 set_channel_bwmode(padapter, cur_channel, cur_ch_offset, cur_bwmode);\r
3380                                 \r
3381                         }\r
3382                         \r
3383                 }\r
3384 #endif //CONFIG_80211AC_VHT\r
3385 \r
3386                 if(cur_bwmode == CHANNEL_WIDTH_40)\r
3387                 {\r
3388                         if(pht_info)\r
3389                                 pht_info->infos[0] &= ~HT_INFO_HT_PARAM_SECONDARY_CHNL_OFF_MASK;\r
3390                         \r
3391                         if(pbuddy_mlmeext->cur_bwmode == CHANNEL_WIDTH_40 ||\r
3392                                 pbuddy_mlmeext->cur_bwmode == CHANNEL_WIDTH_80)\r
3393                         {\r
3394                                 cur_ch_offset = pbuddy_mlmeext->cur_ch_offset;\r
3395 \r
3396                                 //to update cur_ch_offset value in beacon\r
3397                                 if(pht_info)\r
3398                                 {                               \r
3399                                         switch(cur_ch_offset)\r
3400                                         {\r
3401                                                 case HAL_PRIME_CHNL_OFFSET_LOWER:\r
3402                                                         pht_info->infos[0] |= HT_INFO_HT_PARAM_SECONDARY_CHNL_ABOVE;\r
3403                                                         break;\r
3404                                                 case HAL_PRIME_CHNL_OFFSET_UPPER:\r
3405                                                         pht_info->infos[0] |= HT_INFO_HT_PARAM_SECONDARY_CHNL_BELOW;\r
3406                                                         break;\r
3407                                                 case HAL_PRIME_CHNL_OFFSET_DONT_CARE:                                                   \r
3408                                                 default:                                                        \r
3409                                                         break;                                  \r
3410                                         }\r
3411                                 }               \r
3412                                 \r
3413                         }\r
3414                         else if(pbuddy_mlmeext->cur_bwmode == CHANNEL_WIDTH_20)\r
3415                         {\r
3416                                 cur_ch_offset =  rtw_get_offset_by_ch(cur_channel);\r
3417 \r
3418                                 switch(cur_ch_offset)\r
3419                                 {\r
3420                                         case HAL_PRIME_CHNL_OFFSET_LOWER:\r
3421                                                 if(pht_info)\r
3422                                                         pht_info->infos[0] |= HT_INFO_HT_PARAM_SECONDARY_CHNL_ABOVE;            \r
3423                                                 cur_bwmode = CHANNEL_WIDTH_40;\r
3424                                                 break;\r
3425                                         case HAL_PRIME_CHNL_OFFSET_UPPER:\r
3426                                                 if(pht_info)\r
3427                                                         pht_info->infos[0] |= HT_INFO_HT_PARAM_SECONDARY_CHNL_BELOW;                                            \r
3428                                                 cur_bwmode = CHANNEL_WIDTH_40;\r
3429                                                 break;\r
3430                                         case HAL_PRIME_CHNL_OFFSET_DONT_CARE:                                                   \r
3431                                         default:\r
3432                                                 if(pht_info)\r
3433                                                         pht_info->infos[0] &= ~HT_INFO_HT_PARAM_SECONDARY_CHNL_OFF_MASK;\r
3434                                                 cur_bwmode = CHANNEL_WIDTH_20;\r
3435                                                 cur_ch_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE;\r
3436                                                 break;                                  \r
3437                                 }                                               \r
3438                                 \r
3439                         }\r
3440 \r
3441                         set_channel_bwmode(padapter, cur_channel, cur_ch_offset, cur_bwmode);\r
3442                         \r
3443                 }\r
3444                 else\r
3445                 {\r
3446                         set_channel_bwmode(padapter, cur_channel, pbuddy_mlmeext->cur_ch_offset, pbuddy_mlmeext->cur_bwmode);\r
3447                 }               \r
3448 \r
3449                 // to update channel value in beacon\r
3450                 pnetwork->Configuration.DSConfig = cur_channel;         \r
3451                 p = rtw_get_ie((pnetwork->IEs + sizeof(NDIS_802_11_FIXED_IEs)), _DSSET_IE_, &ie_len, (pnetwork->IELength - sizeof(NDIS_802_11_FIXED_IEs)));\r
3452                 if(p && ie_len>0)\r
3453                         *(p + 2) = cur_channel;\r
3454                 \r
3455                 if(pht_info)\r
3456                         pht_info->primary_channel = cur_channel;\r
3457         }\r
3458 \r
3459         DBG_871X(FUNC_ADPT_FMT" CH=%d, BW=%d, offset=%d\n", FUNC_ADPT_ARG(padapter), cur_channel, cur_bwmode, cur_ch_offset);\r
3460 \r
3461         pmlmeext->cur_channel = cur_channel;    \r
3462         pmlmeext->cur_bwmode = cur_bwmode;\r
3463         pmlmeext->cur_ch_offset = cur_ch_offset;\r
3464 \r
3465         //buddy interface band is different from current interface, update ERP, support rate, ext support rate IE\r
3466         if(change_band == _TRUE)\r
3467                 change_band_update_ie(padapter, pnetwork);\r
3468 \r
3469 }\r
3470 #endif //CONFIG_CONCURRENT_MODE\r
3471 \r
3472 #endif //CONFIG_AP_MODE\r
3473 \r