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