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