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