Merge tag 'trace-fixes-3.16' of git://git.kernel.org/pub/scm/linux/kernel/git/rostedt...
[cascardo/linux.git] / drivers / staging / rtl8723au / core / rtw_ap.c
1 /******************************************************************************
2  *
3  * Copyright(c) 2007 - 2012 Realtek Corporation. All rights reserved.
4  *
5  * This program is free software; you can redistribute it and/or modify it
6  * under the terms of version 2 of the GNU General Public License as
7  * published by the Free Software Foundation.
8  *
9  * This program is distributed in the hope that it will be useful, but WITHOUT
10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11  * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12  * more details.
13  *
14  ******************************************************************************/
15 #define _RTW_AP_C_
16
17 #include <osdep_service.h>
18 #include <drv_types.h>
19 #include <linux/ieee80211.h>
20 #include <wifi.h>
21 #include <rtl8723a_cmd.h>
22 #include <rtl8723a_hal.h>
23
24 extern unsigned char WMM_OUI23A[];
25 extern unsigned char WPS_OUI23A[];
26 extern unsigned char P2P_OUI23A[];
27
28 void init_mlme_ap_info23a(struct rtw_adapter *padapter)
29 {
30         struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
31         struct sta_priv *pstapriv = &padapter->stapriv;
32         struct wlan_acl_pool *pacl_list = &pstapriv->acl_list;
33
34         spin_lock_init(&pmlmepriv->bcn_update_lock);
35
36         /* for ACL */
37         _rtw_init_queue23a(&pacl_list->acl_node_q);
38
39         start_ap_mode23a(padapter);
40 }
41
42 void free_mlme_ap_info23a(struct rtw_adapter *padapter)
43 {
44         struct sta_info *psta = NULL;
45         struct sta_priv *pstapriv = &padapter->stapriv;
46         struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
47         struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
48         struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
49
50         pmlmepriv->update_bcn = false;
51         pmlmeext->bstart_bss = false;
52
53         rtw_sta_flush23a(padapter);
54
55         pmlmeinfo->state = MSR_NOLINK;
56
57         /* free_assoc_sta_resources */
58         rtw_free_all_stainfo23a(padapter);
59
60         /* free bc/mc sta_info */
61         psta = rtw_get_bcmc_stainfo23a(padapter);
62         spin_lock_bh(&pstapriv->sta_hash_lock);
63         rtw_free_stainfo23a(padapter, psta);
64         spin_unlock_bh(&pstapriv->sta_hash_lock);
65 }
66
67 static void update_BCNTIM(struct rtw_adapter *padapter)
68 {
69         struct sta_priv *pstapriv = &padapter->stapriv;
70         struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
71         struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
72         struct wlan_bssid_ex *pnetwork_mlmeext = &pmlmeinfo->network;
73         unsigned char *pie = pnetwork_mlmeext->IEs;
74         u8 *p, *dst_ie, *premainder_ie = NULL, *pbackup_remainder_ie = NULL;
75         __le16 tim_bitmap_le;
76         uint offset, tmp_len, tim_ielen, tim_ie_offset, remainder_ielen;
77
78         tim_bitmap_le = cpu_to_le16(pstapriv->tim_bitmap);
79
80         p = rtw_get_ie23a(pie, WLAN_EID_TIM, &tim_ielen,
81                           pnetwork_mlmeext->IELength);
82         if (p != NULL && tim_ielen>0) {
83                 tim_ielen += 2;
84
85                 premainder_ie = p+tim_ielen;
86
87                 tim_ie_offset = (int)(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 = 0;
98
99                 /* get ssid_ie len */
100                 p = rtw_get_ie23a(pie, WLAN_EID_SSID,
101                                   &tmp_len, pnetwork_mlmeext->IELength);
102                 if (p != NULL)
103                         offset += tmp_len+2;
104
105                 /*  get supported rates len */
106                 p = rtw_get_ie23a(pie, WLAN_EID_SUPP_RATES,
107                                   &tmp_len, pnetwork_mlmeext->IELength);
108                 if (p !=  NULL)
109                         offset += tmp_len+2;
110
111                 /* DS Parameter Set IE, len = 3 */
112                 offset += 3;
113
114                 premainder_ie = pie + offset;
115
116                 remainder_ielen = pnetwork_mlmeext->IELength - offset - tim_ielen;
117
118                 /* append TIM IE from offset */
119                 dst_ie = pie + offset;
120         }
121
122         if (remainder_ielen > 0) {
123                 pbackup_remainder_ie = kmalloc(remainder_ielen, GFP_ATOMIC);
124                 if (pbackup_remainder_ie && premainder_ie)
125                         memcpy(pbackup_remainder_ie, premainder_ie, remainder_ielen);
126         }
127
128         *dst_ie++= WLAN_EID_TIM;
129
130         if ((pstapriv->tim_bitmap&0xff00) && (pstapriv->tim_bitmap&0x00fc))
131                 tim_ielen = 5;
132         else
133                 tim_ielen = 4;
134
135         *dst_ie++= tim_ielen;
136
137         *dst_ie++= 0;/* DTIM count */
138         *dst_ie++= 1;/* DTIM period */
139
140         if (pstapriv->tim_bitmap & BIT(0))/* for bc/mc frames */
141                 *dst_ie++ = BIT(0);/* bitmap ctrl */
142         else
143                 *dst_ie++ = 0;
144
145         if (tim_ielen == 4) {
146                 *dst_ie++ = *(u8*)&tim_bitmap_le;
147         } else if (tim_ielen == 5) {
148                 memcpy(dst_ie, &tim_bitmap_le, 2);
149                 dst_ie+= 2;
150         }
151
152         /* copy remainder IE */
153         if (pbackup_remainder_ie) {
154                 memcpy(dst_ie, pbackup_remainder_ie, remainder_ielen);
155
156                 kfree(pbackup_remainder_ie);
157         }
158
159         offset =  (uint)(dst_ie - pie);
160         pnetwork_mlmeext->IELength = offset + remainder_ielen;
161
162         set_tx_beacon_cmd23a(padapter);
163 }
164
165 static u8 chk_sta_is_alive(struct sta_info *psta)
166 {
167         u8 ret = false;
168
169         if ((psta->sta_stats.last_rx_data_pkts +
170             psta->sta_stats.last_rx_ctrl_pkts) !=
171             (psta->sta_stats.rx_data_pkts + psta->sta_stats.rx_ctrl_pkts))
172                 ret = true;
173
174         sta_update_last_rx_pkts(psta);
175
176         return ret;
177 }
178
179 void    expire_timeout_chk23a(struct rtw_adapter *padapter)
180 {
181         struct list_head *phead, *plist, *ptmp;
182         u8 updated = 0;
183         struct sta_info *psta;
184         struct sta_priv *pstapriv = &padapter->stapriv;
185         u8 chk_alive_num = 0;
186         struct sta_info *chk_alive_list[NUM_STA];
187         int i;
188
189         spin_lock_bh(&pstapriv->auth_list_lock);
190
191         phead = &pstapriv->auth_list;
192
193         /* check auth_queue */
194         list_for_each_safe(plist, ptmp, phead) {
195                 psta = container_of(plist, struct sta_info, auth_list);
196
197                 if (psta->expire_to>0) {
198                         psta->expire_to--;
199                         if (psta->expire_to == 0) {
200                                 list_del_init(&psta->auth_list);
201                                 pstapriv->auth_list_cnt--;
202
203                                 DBG_8723A("auth expire %pM\n", psta->hwaddr);
204
205                                 spin_unlock_bh(&pstapriv->auth_list_lock);
206
207                                 spin_lock_bh(&pstapriv->sta_hash_lock);
208                                 rtw_free_stainfo23a(padapter, psta);
209                                 spin_unlock_bh(&pstapriv->sta_hash_lock);
210
211                                 spin_lock_bh(&pstapriv->auth_list_lock);
212                         }
213                 }
214
215         }
216
217         spin_unlock_bh(&pstapriv->auth_list_lock);
218
219         spin_lock_bh(&pstapriv->asoc_list_lock);
220
221         phead = &pstapriv->asoc_list;
222
223         /* check asoc_queue */
224         list_for_each_safe(plist, ptmp, phead) {
225                 psta = container_of(plist, struct sta_info, asoc_list);
226
227                 if (chk_sta_is_alive(psta) || !psta->expire_to) {
228                         psta->expire_to = pstapriv->expire_to;
229                         psta->keep_alive_trycnt = 0;
230                 } else {
231                         psta->expire_to--;
232                 }
233
234                 if (psta->expire_to <= 0)
235                 {
236                         struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
237
238                         if (padapter->registrypriv.wifi_spec == 1)
239                         {
240                                 psta->expire_to = pstapriv->expire_to;
241                                 continue;
242                         }
243
244                         if (psta->state & WIFI_SLEEP_STATE) {
245                                 if (!(psta->state & WIFI_STA_ALIVE_CHK_STATE)) {
246                                         /* to check if alive by another methods if station is at ps mode. */
247                                         psta->expire_to = pstapriv->expire_to;
248                                         psta->state |= WIFI_STA_ALIVE_CHK_STATE;
249
250                                         /* to update bcn with tim_bitmap for this station */
251                                         pstapriv->tim_bitmap |= CHKBIT(psta->aid);
252                                         update_beacon23a(padapter, WLAN_EID_TIM, NULL, false);
253
254                                         if (!pmlmeext->active_keep_alive_check)
255                                                 continue;
256                                 }
257                         }
258
259                         if (pmlmeext->active_keep_alive_check) {
260                                 chk_alive_list[chk_alive_num++] = psta;
261                                 continue;
262                         }
263
264                         list_del_init(&psta->asoc_list);
265                         pstapriv->asoc_list_cnt--;
266
267                         DBG_8723A("asoc expire "MAC_FMT", state = 0x%x\n", MAC_ARG(psta->hwaddr), psta->state);
268                         updated = ap_free_sta23a(padapter, psta, false, WLAN_REASON_DEAUTH_LEAVING);
269                 } else {
270                         /* TODO: Aging mechanism to digest frames in sleep_q to avoid running out of xmitframe */
271                         if (psta->sleepq_len > (NR_XMITFRAME/pstapriv->asoc_list_cnt)
272                                 && padapter->xmitpriv.free_xmitframe_cnt < ((NR_XMITFRAME/pstapriv->asoc_list_cnt)/2)
273                         ) {
274                                 DBG_8723A("%s sta:"MAC_FMT", sleepq_len:%u, free_xmitframe_cnt:%u, asoc_list_cnt:%u, clear sleep_q\n", __func__,
275                                           MAC_ARG(psta->hwaddr),
276                                           psta->sleepq_len,
277                                           padapter->xmitpriv.free_xmitframe_cnt,
278                                           pstapriv->asoc_list_cnt);
279                                 wakeup_sta_to_xmit23a(padapter, psta);
280                         }
281                 }
282         }
283
284         spin_unlock_bh(&pstapriv->asoc_list_lock);
285
286         if (chk_alive_num) {
287
288                 u8 backup_oper_channel = 0;
289                 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
290                 /* switch to correct channel of current network  before issue keep-alive frames */
291                 if (rtw_get_oper_ch23a(padapter) != pmlmeext->cur_channel) {
292                         backup_oper_channel = rtw_get_oper_ch23a(padapter);
293                         SelectChannel23a(padapter, pmlmeext->cur_channel);
294                 }
295
296         /* issue null data to check sta alive*/
297         for (i = 0; i < chk_alive_num; i++) {
298
299                 int ret = _FAIL;
300
301                 psta = chk_alive_list[i];
302                 if (!(psta->state &_FW_LINKED))
303                         continue;
304
305                 if (psta->state & WIFI_SLEEP_STATE)
306                         ret = issue_nulldata23a(padapter, psta->hwaddr, 0, 1, 50);
307                 else
308                         ret = issue_nulldata23a(padapter, psta->hwaddr, 0, 3, 50);
309
310                 psta->keep_alive_trycnt++;
311                 if (ret == _SUCCESS)
312                 {
313                         DBG_8723A("asoc check, sta(" MAC_FMT ") is alive\n", MAC_ARG(psta->hwaddr));
314                         psta->expire_to = pstapriv->expire_to;
315                         psta->keep_alive_trycnt = 0;
316                         continue;
317                 }
318                 else if (psta->keep_alive_trycnt <= 3)
319                 {
320                         DBG_8723A("ack check for asoc expire, keep_alive_trycnt =%d\n", psta->keep_alive_trycnt);
321                         psta->expire_to = 1;
322                         continue;
323                 }
324
325                 psta->keep_alive_trycnt = 0;
326
327                 DBG_8723A("asoc expire "MAC_FMT", state = 0x%x\n", MAC_ARG(psta->hwaddr), psta->state);
328                 spin_lock_bh(&pstapriv->asoc_list_lock);
329                 if (!list_empty(&psta->asoc_list)) {
330                         list_del_init(&psta->asoc_list);
331                         pstapriv->asoc_list_cnt--;
332                         updated = ap_free_sta23a(padapter, psta, false, WLAN_REASON_DEAUTH_LEAVING);
333                 }
334                 spin_unlock_bh(&pstapriv->asoc_list_lock);
335
336         }
337
338         if (backup_oper_channel>0) /* back to the original operation channel */
339                 SelectChannel23a(padapter, backup_oper_channel);
340 }
341
342         associated_clients_update23a(padapter, updated);
343 }
344
345 void add_RATid23a(struct rtw_adapter *padapter, struct sta_info *psta, u8 rssi_level)
346 {
347         int i;
348         u8 rf_type;
349         u32 init_rate = 0;
350         unsigned char sta_band = 0, raid, shortGIrate = false;
351         unsigned char limit;
352         unsigned int tx_ra_bitmap = 0;
353         struct ht_priv *psta_ht = NULL;
354         struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
355         struct wlan_bssid_ex *pcur_network = &pmlmepriv->cur_network.network;
356
357         if (psta)
358                 psta_ht = &psta->htpriv;
359         else
360                 return;
361
362         if (!(psta->state & _FW_LINKED))
363                 return;
364
365         /* b/g mode ra_bitmap */
366         for (i = 0; i<sizeof(psta->bssrateset); i++)
367         {
368                 if (psta->bssrateset[i])
369                         tx_ra_bitmap |= rtw_get_bit_value_from_ieee_value23a(psta->bssrateset[i]&0x7f);
370         }
371         /* n mode ra_bitmap */
372         if (psta_ht->ht_option) {
373                 rf_type = rtl8723a_get_rf_type(padapter);
374
375                 if (rf_type == RF_2T2R)
376                         limit = 16;/*  2R */
377                 else
378                         limit = 8;/*   1R */
379
380                 for (i = 0; i < limit; i++) {
381                         if (psta_ht->ht_cap.mcs.rx_mask[i / 8] & BIT(i % 8))
382                                 tx_ra_bitmap |= BIT(i + 12);
383                 }
384
385                 /* max short GI rate */
386                 shortGIrate = psta_ht->sgi;
387         }
388
389         if (pcur_network->DSConfig > 14) {
390                 /*  5G band */
391                 if (tx_ra_bitmap & 0xffff000)
392                         sta_band |= WIRELESS_11_5N | WIRELESS_11A;
393                 else
394                         sta_band |= WIRELESS_11A;
395         } else {
396                 if (tx_ra_bitmap & 0xffff000)
397                         sta_band |= WIRELESS_11_24N | WIRELESS_11G | WIRELESS_11B;
398                 else if (tx_ra_bitmap & 0xff0)
399                         sta_band |= WIRELESS_11G |WIRELESS_11B;
400                 else
401                         sta_band |= WIRELESS_11B;
402         }
403
404         psta->wireless_mode = sta_band;
405
406         raid = networktype_to_raid23a(sta_band);
407         init_rate = get_highest_rate_idx23a(tx_ra_bitmap&0x0fffffff)&0x3f;
408
409         if (psta->aid < NUM_STA)
410         {
411                 u8 arg = 0;
412
413                 arg = psta->mac_id&0x1f;
414
415                 arg |= BIT(7);/* support entry 2~31 */
416
417                 if (shortGIrate == true)
418                         arg |= BIT(5);
419
420                 tx_ra_bitmap |= ((raid<<28)&0xf0000000);
421
422                 DBG_8723A("%s => mac_id:%d , raid:%d , bitmap = 0x%x, arg = "
423                           "0x%x\n",
424                           __func__, psta->mac_id, raid, tx_ra_bitmap, arg);
425
426                 /* bitmap[0:27] = tx_rate_bitmap */
427                 /* bitmap[28:31]= Rate Adaptive id */
428                 /* arg[0:4] = macid */
429                 /* arg[5] = Short GI */
430                 rtl8723a_add_rateatid(padapter, tx_ra_bitmap, arg, rssi_level);
431
432                 if (shortGIrate == true)
433                         init_rate |= BIT(6);
434
435                 /* set ra_id, init_rate */
436                 psta->raid = raid;
437                 psta->init_rate = init_rate;
438
439         }
440         else
441         {
442                 DBG_8723A("station aid %d exceed the max number\n", psta->aid);
443         }
444 }
445
446 static void update_bmc_sta(struct rtw_adapter *padapter)
447 {
448         u32 init_rate = 0;
449         unsigned char network_type, raid;
450         int i, supportRateNum = 0;
451         unsigned int tx_ra_bitmap = 0;
452         struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
453         struct wlan_bssid_ex *pcur_network = &pmlmepriv->cur_network.network;
454         struct sta_info *psta = rtw_get_bcmc_stainfo23a(padapter);
455
456         if (psta)
457         {
458                 psta->aid = 0;/* default set to 0 */
459                 psta->mac_id = psta->aid + 1;
460
461                 psta->qos_option = 0;
462                 psta->htpriv.ht_option = false;
463
464                 psta->ieee8021x_blocked = 0;
465
466                 memset((void*)&psta->sta_stats, 0, sizeof(struct stainfo_stats));
467
468                 /* prepare for add_RATid23a */
469                 supportRateNum = rtw_get_rateset_len23a((u8*)&pcur_network->SupportedRates);
470                 network_type = rtw_check_network_type23a((u8*)&pcur_network->SupportedRates, supportRateNum, 1);
471
472                 memcpy(psta->bssrateset, &pcur_network->SupportedRates, supportRateNum);
473                 psta->bssratelen = supportRateNum;
474
475                 /* b/g mode ra_bitmap */
476                 for (i = 0; i<supportRateNum; i++)
477                 {
478                         if (psta->bssrateset[i])
479                                 tx_ra_bitmap |= rtw_get_bit_value_from_ieee_value23a(psta->bssrateset[i]&0x7f);
480                 }
481
482                 if (pcur_network->DSConfig > 14) {
483                         /* force to A mode. 5G doesn't support CCK rates */
484                         network_type = WIRELESS_11A;
485                         tx_ra_bitmap = 0x150; /*  6, 12, 24 Mbps */
486                 } else {
487                         /* force to b mode */
488                         network_type = WIRELESS_11B;
489                         tx_ra_bitmap = 0xf;
490                 }
491
492                 raid = networktype_to_raid23a(network_type);
493                 init_rate = get_highest_rate_idx23a(tx_ra_bitmap&0x0fffffff)&0x3f;
494
495                 /* ap mode */
496                 rtl8723a_SetHalODMVar(padapter, HAL_ODM_STA_INFO, psta, true);
497
498                 {
499                         u8 arg = 0;
500
501                         arg = psta->mac_id&0x1f;
502
503                         arg |= BIT(7);
504
505                         tx_ra_bitmap |= ((raid<<28)&0xf0000000);
506
507                         DBG_8723A("update_bmc_sta, mask = 0x%x, arg = 0x%x\n", tx_ra_bitmap, arg);
508
509                         /* bitmap[0:27] = tx_rate_bitmap */
510                         /* bitmap[28:31]= Rate Adaptive id */
511                         /* arg[0:4] = macid */
512                         /* arg[5] = Short GI */
513                         rtl8723a_add_rateatid(padapter, tx_ra_bitmap, arg, 0);
514                 }
515
516                 /* set ra_id, init_rate */
517                 psta->raid = raid;
518                 psta->init_rate = init_rate;
519
520                 spin_lock_bh(&psta->lock);
521                 psta->state = _FW_LINKED;
522                 spin_unlock_bh(&psta->lock);
523
524         }
525         else
526         {
527                 DBG_8723A("add_RATid23a_bmc_sta error!\n");
528         }
529 }
530
531 /* notes: */
532 /* AID: 1~MAX for sta and 0 for bc/mc in ap/adhoc mode */
533 /* MAC_ID = AID+1 for sta in ap/adhoc mode */
534 /* MAC_ID = 1 for bc/mc for sta/ap/adhoc */
535 /* MAC_ID = 0 for bssid for sta/ap/adhoc */
536 /* CAM_ID = 0~3 for default key, cmd_id = macid + 3, macid = aid+1; */
537
538 void update_sta_info23a_apmode23a(struct rtw_adapter *padapter, struct sta_info *psta)
539 {
540         struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
541         struct security_priv *psecuritypriv = &padapter->securitypriv;
542         struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
543         struct ht_priv *phtpriv_ap = &pmlmepriv->htpriv;
544         struct ht_priv *phtpriv_sta = &psta->htpriv;
545         /* set intf_tag to if1 */
546
547         psta->mac_id = psta->aid+1;
548         DBG_8723A("%s\n", __func__);
549
550         /* ap mode */
551         rtl8723a_SetHalODMVar(padapter, HAL_ODM_STA_INFO, psta, true);
552
553         if (psecuritypriv->dot11AuthAlgrthm == dot11AuthAlgrthm_8021X)
554                 psta->ieee8021x_blocked = true;
555         else
556                 psta->ieee8021x_blocked = false;
557
558         /* update sta's cap */
559
560         /* ERP */
561         VCS_update23a(padapter, psta);
562         /* HT related cap */
563         if (phtpriv_sta->ht_option)
564         {
565                 /* check if sta supports rx ampdu */
566                 phtpriv_sta->ampdu_enable = phtpriv_ap->ampdu_enable;
567
568                 /* check if sta support s Short GI */
569                 if ((phtpriv_sta->ht_cap.cap_info & phtpriv_ap->ht_cap.cap_info) & cpu_to_le16(IEEE80211_HT_CAP_SGI_20|IEEE80211_HT_CAP_SGI_40))
570                         phtpriv_sta->sgi = true;
571
572                 /*  bwmode */
573                 if ((phtpriv_sta->ht_cap.cap_info & phtpriv_ap->ht_cap.cap_info) & cpu_to_le16(IEEE80211_HT_CAP_SUP_WIDTH_20_40)) {
574                         /* phtpriv_sta->bwmode = HT_CHANNEL_WIDTH_40; */
575                         phtpriv_sta->bwmode = pmlmeext->cur_bwmode;
576                         phtpriv_sta->ch_offset = pmlmeext->cur_ch_offset;
577
578                 }
579
580                 psta->qos_option = true;
581
582         }
583         else
584         {
585                 phtpriv_sta->ampdu_enable = false;
586
587                 phtpriv_sta->sgi = false;
588                 phtpriv_sta->bwmode = HT_CHANNEL_WIDTH_20;
589                 phtpriv_sta->ch_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE;
590         }
591
592         /* Rx AMPDU */
593         send_delba23a(padapter, 0, psta->hwaddr);/*  recipient */
594
595         /* TX AMPDU */
596         send_delba23a(padapter, 1, psta->hwaddr);/*  originator */
597         phtpriv_sta->agg_enable_bitmap = 0x0;/* reset */
598         phtpriv_sta->candidate_tid_bitmap = 0x0;/* reset */
599
600         /* todo: init other variables */
601
602         memset((void*)&psta->sta_stats, 0, sizeof(struct stainfo_stats));
603
604         spin_lock_bh(&psta->lock);
605         psta->state |= _FW_LINKED;
606         spin_unlock_bh(&psta->lock);
607 }
608
609 static void update_hw_ht_param(struct rtw_adapter *padapter)
610 {
611         unsigned char max_AMPDU_len;
612         unsigned char min_MPDU_spacing;
613         struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
614         struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
615
616         DBG_8723A("%s\n", __func__);
617
618         /* handle A-MPDU parameter field */
619         /*
620                 AMPDU_para [1:0]:Max AMPDU Len => 0:8k , 1:16k, 2:32k, 3:64k
621                 AMPDU_para [4:2]:Min MPDU Start Spacing
622         */
623         max_AMPDU_len = pmlmeinfo->ht_cap.ampdu_params_info &
624                 IEEE80211_HT_AMPDU_PARM_FACTOR;
625
626         min_MPDU_spacing = (pmlmeinfo->ht_cap.ampdu_params_info &
627                             IEEE80211_HT_AMPDU_PARM_DENSITY) >> 2;
628
629         rtl8723a_set_ampdu_min_space(padapter, min_MPDU_spacing);
630         rtl8723a_set_ampdu_factor(padapter, max_AMPDU_len);
631
632         /*  Config SM Power Save setting */
633         pmlmeinfo->SM_PS = (le16_to_cpu(pmlmeinfo->ht_cap.cap_info) &
634                             IEEE80211_HT_CAP_SM_PS) >> 2;
635         if (pmlmeinfo->SM_PS == WLAN_HT_CAP_SM_PS_STATIC)
636                 DBG_8723A("%s(): WLAN_HT_CAP_SM_PS_STATIC\n", __func__);
637 }
638
639 static void start_bss_network(struct rtw_adapter *padapter, u8 *pbuf)
640 {
641         const u8 *p;
642         u8 val8, cur_channel, cur_bwmode, cur_ch_offset;
643         u16 bcn_interval;
644         u32 acparm;
645         struct registry_priv *pregpriv = &padapter->registrypriv;
646         struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
647         struct security_priv* psecuritypriv = &padapter->securitypriv;
648         struct wlan_bssid_ex *pnetwork = &pmlmepriv->cur_network.network;
649         struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
650         struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
651         struct wlan_bssid_ex *pnetwork_mlmeext = &pmlmeinfo->network;
652         struct ieee80211_ht_operation *pht_info = NULL;
653
654         bcn_interval = (u16)pnetwork->beacon_interval;
655         cur_channel = pnetwork->DSConfig;
656         cur_bwmode = HT_CHANNEL_WIDTH_20;;
657         cur_ch_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE;
658
659         /* check if there is wps ie, */
660         /* if there is wpsie in beacon, the hostapd will update beacon twice when stating hostapd, */
661         /* and at first time the security ie (RSN/WPA IE) will not include in beacon. */
662         if (NULL == cfg80211_find_vendor_ie(WLAN_OUI_MICROSOFT,
663                                             WLAN_OUI_TYPE_MICROSOFT_WPS,
664                                             pnetwork->IEs,
665                                             pnetwork->IELength))
666                 pmlmeext->bstart_bss = true;
667
668         /* todo: update wmm, ht cap */
669         /* pmlmeinfo->WMM_enable; */
670         /* pmlmeinfo->HT_enable; */
671         if (pmlmepriv->qos_option)
672                 pmlmeinfo->WMM_enable = true;
673         if (pmlmepriv->htpriv.ht_option) {
674                 pmlmeinfo->WMM_enable = true;
675                 pmlmeinfo->HT_enable = true;
676
677                 update_hw_ht_param(padapter);
678         }
679
680         if (pmlmepriv->cur_network.join_res != true) {
681                 /* setting only at  first time */
682                 /* WEP Key will be set before this function, do not clear CAM. */
683                 if (psecuritypriv->dot11PrivacyAlgrthm !=
684                     WLAN_CIPHER_SUITE_WEP40 &&
685                     psecuritypriv->dot11PrivacyAlgrthm !=
686                     WLAN_CIPHER_SUITE_WEP104)
687                         flush_all_cam_entry23a(padapter);       /* clear CAM */
688         }
689
690         /* set MSR to AP_Mode */
691         rtl8723a_set_media_status(padapter, MSR_AP);
692
693         /* Set BSSID REG */
694         hw_var_set_bssid(padapter, pnetwork->MacAddress);
695
696         /* Set EDCA param reg */
697         acparm = 0x002F3217; /*  VO */
698         rtl8723a_set_ac_param_vo(padapter, acparm);
699         acparm = 0x005E4317; /*  VI */
700         rtl8723a_set_ac_param_vi(padapter, acparm);
701         acparm = 0x005ea42b;
702         rtl8723a_set_ac_param_be(padapter, acparm);
703         acparm = 0x0000A444; /*  BK */
704         rtl8723a_set_ac_param_bk(padapter, acparm);
705
706         /* Set Security */
707         val8 = (psecuritypriv->dot11AuthAlgrthm == dot11AuthAlgrthm_8021X) ?
708                 0xcc: 0xcf;
709         rtl8723a_set_sec_cfg(padapter, val8);
710
711         /* Beacon Control related register */
712         rtl8723a_set_beacon_interval(padapter, bcn_interval);
713
714         UpdateBrateTbl23a(padapter, pnetwork->SupportedRates);
715         HalSetBrateCfg23a(padapter, pnetwork->SupportedRates);
716
717         if (!pmlmepriv->cur_network.join_res) {
718                 /* setting only at  first time */
719
720                 /* disable dynamic functions, such as high power, DIG */
721
722                 /* turn on all dynamic functions */
723                 rtl8723a_odm_support_ability_set(padapter,
724                                                  DYNAMIC_ALL_FUNC_ENABLE);
725         }
726         /* set channel, bwmode */
727
728         p = cfg80211_find_ie(WLAN_EID_HT_OPERATION, pnetwork->IEs,
729                              pnetwork->IELength);
730         if (p && p[1]) {
731                 pht_info = (struct ieee80211_ht_operation *)(p + 2);
732
733                 if (pregpriv->cbw40_enable && pht_info->ht_param &
734                     IEEE80211_HT_PARAM_CHAN_WIDTH_ANY) {
735                         /* switch to the 40M Hz mode */
736                         cur_bwmode = HT_CHANNEL_WIDTH_40;
737                         switch (pht_info->ht_param &
738                                 IEEE80211_HT_PARAM_CHA_SEC_OFFSET) {
739                         case IEEE80211_HT_PARAM_CHA_SEC_ABOVE:
740                                 /* pmlmeext->cur_ch_offset =
741                                    HAL_PRIME_CHNL_OFFSET_LOWER; */
742                                 cur_ch_offset = HAL_PRIME_CHNL_OFFSET_LOWER;
743                                 break;
744                         case IEEE80211_HT_PARAM_CHA_SEC_BELOW:
745                                 cur_ch_offset = HAL_PRIME_CHNL_OFFSET_UPPER;
746                                 break;
747                         default:
748                                 cur_ch_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE;
749                                 break;
750                         }
751                 }
752         }
753         /* TODO: need to judge the phy parameters on concurrent mode for single phy */
754         set_channel_bwmode23a(padapter, cur_channel, cur_ch_offset, cur_bwmode);
755
756         DBG_8723A("CH =%d, BW =%d, offset =%d\n", cur_channel, cur_bwmode,
757                   cur_ch_offset);
758
759         pmlmeext->cur_channel = cur_channel;
760         pmlmeext->cur_bwmode = cur_bwmode;
761         pmlmeext->cur_ch_offset = cur_ch_offset;
762         pmlmeext->cur_wireless_mode = pmlmepriv->cur_network.network_type;
763
764         /* update cur_wireless_mode */
765         update_wireless_mode23a(padapter);
766
767         /* update capability after cur_wireless_mode updated */
768         update_capinfo23a(padapter, pnetwork->capability);
769
770         /* let pnetwork_mlmeext == pnetwork_mlme. */
771         memcpy(pnetwork_mlmeext, pnetwork, pnetwork->Length);
772
773         if (pmlmeext->bstart_bss) {
774                 update_beacon23a(padapter, WLAN_EID_TIM, NULL, false);
775
776                 /* issue beacon frame */
777                 if (send_beacon23a(padapter) == _FAIL)
778                         DBG_8723A("issue_beacon23a, fail!\n");
779         }
780
781         /* update bc/mc sta_info */
782         update_bmc_sta(padapter);
783 }
784
785 int rtw_check_beacon_data23a(struct rtw_adapter *padapter,
786                              struct ieee80211_mgmt *mgmt, unsigned int len)
787 {
788         int ret = _SUCCESS;
789         u8 *p;
790         u8 *pHT_caps_ie = NULL;
791         u8 *pHT_info_ie = NULL;
792         struct sta_info *psta = NULL;
793         u16 ht_cap = false;
794         uint ie_len = 0;
795         int group_cipher, pairwise_cipher;
796         u8 channel, network_type, supportRate[NDIS_802_11_LENGTH_RATES_EX];
797         int supportRateNum = 0;
798         u8 WMM_PARA_IE[] = {0x00, 0x50, 0xf2, 0x02, 0x01, 0x01};
799         struct registry_priv *pregistrypriv = &padapter->registrypriv;
800         struct security_priv *psecuritypriv = &padapter->securitypriv;
801         struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
802         struct wlan_bssid_ex *pbss_network = &pmlmepriv->cur_network.network;
803         u8 *ie = pbss_network->IEs;
804         u8 *pbuf = mgmt->u.beacon.variable;
805         len -= offsetof(struct ieee80211_mgmt, u.beacon.variable);
806         /* SSID */
807         /* Supported rates */
808         /* DS Params */
809         /* WLAN_EID_COUNTRY */
810         /* ERP Information element */
811         /* Extended supported rates */
812         /* WPA/WPA2 */
813         /* Wi-Fi Wireless Multimedia Extensions */
814         /* ht_capab, ht_oper */
815         /* WPS IE */
816
817         DBG_8723A("%s, len =%d\n", __func__, len);
818
819         if (!check_fwstate(pmlmepriv, WIFI_AP_STATE))
820                 return _FAIL;
821
822         if (len > MAX_IE_SZ)
823                 return _FAIL;
824
825         pbss_network->IELength = len;
826
827         memset(ie, 0, MAX_IE_SZ);
828
829         memcpy(ie, pbuf, pbss_network->IELength);
830
831         if (pbss_network->ifmode != NL80211_IFTYPE_AP &&
832             pbss_network->ifmode != NL80211_IFTYPE_P2P_GO)
833                 return _FAIL;
834
835         pbss_network->Rssi = 0;
836
837         memcpy(pbss_network->MacAddress, myid(&padapter->eeprompriv), ETH_ALEN);
838
839         /* SSID */
840         p = rtw_get_ie23a(ie, WLAN_EID_SSID, &ie_len, pbss_network->IELength);
841         if (p && ie_len > 0) {
842                 memset(&pbss_network->Ssid, 0, sizeof(struct cfg80211_ssid));
843                 memcpy(pbss_network->Ssid.ssid, (p + 2), ie_len);
844                 pbss_network->Ssid.ssid_len = ie_len;
845         }
846
847         /* channel */
848         channel = 0;
849         p = rtw_get_ie23a(ie, WLAN_EID_DS_PARAMS, &ie_len,
850                           pbss_network->IELength);
851         if (p && ie_len > 0)
852                 channel = *(p + 2);
853
854         pbss_network->DSConfig = channel;
855
856         memset(supportRate, 0, NDIS_802_11_LENGTH_RATES_EX);
857         /*  get supported rates */
858         p = rtw_get_ie23a(ie, WLAN_EID_SUPP_RATES, &ie_len,
859                           pbss_network->IELength);
860         if (p) {
861                 memcpy(supportRate, p+2, ie_len);
862                 supportRateNum = ie_len;
863         }
864
865         /* get ext_supported rates */
866         p = rtw_get_ie23a(ie, WLAN_EID_EXT_SUPP_RATES,
867                           &ie_len, pbss_network->IELength);
868         if (p) {
869                 memcpy(supportRate+supportRateNum, p+2, ie_len);
870                 supportRateNum += ie_len;
871         }
872
873         network_type = rtw_check_network_type23a(supportRate,
874                                                  supportRateNum, channel);
875
876         rtw_set_supported_rate23a(pbss_network->SupportedRates, network_type);
877
878         /* parsing ERP_IE */
879         p = rtw_get_ie23a(ie, WLAN_EID_ERP_INFO, &ie_len,
880                           pbss_network->IELength);
881         if (p && ie_len > 0)
882                 ERP_IE_handler23a(padapter, p);
883
884         /* update privacy/security */
885         if (pbss_network->capability & BIT(4))
886                 pbss_network->Privacy = 1;
887         else
888                 pbss_network->Privacy = 0;
889
890         psecuritypriv->wpa_psk = 0;
891
892         /* wpa2 */
893         group_cipher = 0; pairwise_cipher = 0;
894         psecuritypriv->wpa2_group_cipher = 0;
895         psecuritypriv->wpa2_pairwise_cipher = 0;
896         p = rtw_get_ie23a(ie, WLAN_EID_RSN, &ie_len,
897                           pbss_network->IELength);
898         if (p && ie_len > 0) {
899                 if (rtw_parse_wpa2_ie23a(p, ie_len+2, &group_cipher,
900                                          &pairwise_cipher, NULL) == _SUCCESS) {
901                         psecuritypriv->dot11AuthAlgrthm = dot11AuthAlgrthm_8021X;
902
903                         psecuritypriv->dot8021xalg = 1;/* psk,  todo:802.1x */
904                         psecuritypriv->wpa_psk |= BIT(1);
905
906                         psecuritypriv->wpa2_group_cipher = group_cipher;
907                         psecuritypriv->wpa2_pairwise_cipher = pairwise_cipher;
908                 }
909         }
910
911         /* wpa */
912         ie_len = 0;
913         group_cipher = 0;
914         pairwise_cipher = 0;
915         psecuritypriv->wpa_group_cipher = 0;
916         psecuritypriv->wpa_pairwise_cipher = 0;
917         for (p = ie; ;p += (ie_len + 2)) {
918                 p = rtw_get_ie23a(p, WLAN_EID_VENDOR_SPECIFIC, &ie_len,
919                                   pbss_network->IELength - (ie_len + 2));
920                 if ((p) && (!memcmp(p+2, RTW_WPA_OUI23A_TYPE, 4))) {
921                         if (rtw_parse_wpa_ie23a(p, ie_len+2, &group_cipher,
922                                                 &pairwise_cipher, NULL) == _SUCCESS) {
923                                 psecuritypriv->dot11AuthAlgrthm = dot11AuthAlgrthm_8021X;
924
925                                 /* psk,  todo:802.1x */
926                                 psecuritypriv->dot8021xalg = 1;
927
928                                 psecuritypriv->wpa_psk |= BIT(0);
929
930                                 psecuritypriv->wpa_group_cipher = group_cipher;
931                                 psecuritypriv->wpa_pairwise_cipher = pairwise_cipher;
932                         }
933                         break;
934                 }
935
936                 if ((p == NULL) || (ie_len == 0))
937                                 break;
938         }
939
940         /* wmm */
941         ie_len = 0;
942         pmlmepriv->qos_option = 0;
943         if (pregistrypriv->wmm_enable) {
944                 for (p = ie; ;p += (ie_len + 2)) {
945                         p = rtw_get_ie23a(p, WLAN_EID_VENDOR_SPECIFIC, &ie_len,
946                                           (pbss_network->IELength -
947                                            (ie_len + 2)));
948                         if ((p) && !memcmp(p+2, WMM_PARA_IE, 6)) {
949                                 pmlmepriv->qos_option = 1;
950
951                                 *(p+8) |= BIT(7);/* QoS Info, support U-APSD */
952
953                                 /* disable all ACM bits since the WMM admission
954                                  * control is not supported
955                                  */
956                                 *(p + 10) &= ~BIT(4); /* BE */
957                                 *(p + 14) &= ~BIT(4); /* BK */
958                                 *(p + 18) &= ~BIT(4); /* VI */
959                                 *(p + 22) &= ~BIT(4); /* VO */
960                                 break;
961                         }
962                         if ((p == NULL) || (ie_len == 0))
963                                 break;
964                 }
965         }
966         /* parsing HT_CAP_IE */
967         p = rtw_get_ie23a(ie, WLAN_EID_HT_CAPABILITY, &ie_len,
968                           pbss_network->IELength);
969         if (p && ie_len > 0) {
970                 u8 rf_type;
971
972                 struct ieee80211_ht_cap *pht_cap = (struct ieee80211_ht_cap *)(p+2);
973
974                 pHT_caps_ie = p;
975
976                 ht_cap = true;
977                 network_type |= WIRELESS_11_24N;
978
979                 rf_type = rtl8723a_get_rf_type(padapter);
980
981                 if ((psecuritypriv->wpa_pairwise_cipher & WPA_CIPHER_CCMP) ||
982                     (psecuritypriv->wpa2_pairwise_cipher & WPA_CIPHER_CCMP))
983                         pht_cap->ampdu_params_info |= (IEEE80211_HT_AMPDU_PARM_DENSITY & (0x07<<2));
984                 else
985                         pht_cap->ampdu_params_info |= (IEEE80211_HT_AMPDU_PARM_DENSITY&0x00);
986
987                 /* set  Max Rx AMPDU size  to 64K */
988                 pht_cap->ampdu_params_info |= (IEEE80211_HT_AMPDU_PARM_FACTOR & 0x03);
989
990                 if (rf_type == RF_1T1R) {
991                         pht_cap->mcs.rx_mask[0] = 0xff;
992                         pht_cap->mcs.rx_mask[1] = 0x0;
993                 }
994
995                 memcpy(&pmlmepriv->htpriv.ht_cap, p+2, ie_len);
996         }
997
998         /* parsing HT_INFO_IE */
999         p = rtw_get_ie23a(ie, WLAN_EID_HT_OPERATION, &ie_len,
1000                           pbss_network->IELength);
1001         if (p && ie_len > 0)
1002                 pHT_info_ie = p;
1003
1004         pmlmepriv->cur_network.network_type = network_type;
1005
1006         pmlmepriv->htpriv.ht_option = false;
1007
1008         /* ht_cap */
1009         if (pregistrypriv->ht_enable && ht_cap) {
1010                 pmlmepriv->htpriv.ht_option = true;
1011                 pmlmepriv->qos_option = 1;
1012
1013                 if (pregistrypriv->ampdu_enable == 1)
1014                         pmlmepriv->htpriv.ampdu_enable = true;
1015
1016                 HT_caps_handler23a(padapter, pHT_caps_ie);
1017
1018                 HT_info_handler23a(padapter, pHT_info_ie);
1019         }
1020
1021         pbss_network->Length = get_wlan_bssid_ex_sz(pbss_network);
1022
1023         /* issue beacon to start bss network */
1024         start_bss_network(padapter, (u8*)pbss_network);
1025
1026         /* alloc sta_info for ap itself */
1027         psta = rtw_get_stainfo23a(&padapter->stapriv, pbss_network->MacAddress);
1028         if (!psta) {
1029                 psta = rtw_alloc_stainfo23a(&padapter->stapriv,
1030                                             pbss_network->MacAddress,
1031                                             GFP_KERNEL);
1032                 if (!psta)
1033                         return _FAIL;
1034         }
1035         /* fix bug of flush_cam_entry at STOP AP mode */
1036         psta->state |= WIFI_AP_STATE;
1037         rtw_indicate_connect23a(padapter);
1038
1039         /* for check if already set beacon */
1040         pmlmepriv->cur_network.join_res = true;
1041
1042         return ret;
1043 }
1044
1045 void rtw_set_macaddr_acl23a(struct rtw_adapter *padapter, int mode)
1046 {
1047         struct sta_priv *pstapriv = &padapter->stapriv;
1048         struct wlan_acl_pool *pacl_list = &pstapriv->acl_list;
1049
1050         DBG_8723A("%s, mode =%d\n", __func__, mode);
1051
1052         pacl_list->mode = mode;
1053 }
1054
1055 int rtw_acl_add_sta23a(struct rtw_adapter *padapter, u8 *addr)
1056 {
1057         struct list_head *plist, *phead;
1058         u8 added = false;
1059         int i, ret = 0;
1060         struct rtw_wlan_acl_node *paclnode;
1061         struct sta_priv *pstapriv = &padapter->stapriv;
1062         struct wlan_acl_pool *pacl_list = &pstapriv->acl_list;
1063         struct rtw_queue *pacl_node_q = &pacl_list->acl_node_q;
1064
1065         DBG_8723A("%s(acl_num =%d) =" MAC_FMT "\n", __func__, pacl_list->num, MAC_ARG(addr));
1066
1067         if ((NUM_ACL-1) < pacl_list->num)
1068                 return -1;
1069
1070         spin_lock_bh(&pacl_node_q->lock);
1071
1072         phead = get_list_head(pacl_node_q);
1073
1074         list_for_each(plist, phead) {
1075                 paclnode = container_of(plist, struct rtw_wlan_acl_node, list);
1076
1077                 if (!memcmp(paclnode->addr, addr, ETH_ALEN)) {
1078                         if (paclnode->valid == true) {
1079                                 added = true;
1080                                 DBG_8723A("%s, sta has been added\n", __func__);
1081                                 break;
1082                         }
1083                 }
1084         }
1085
1086         spin_unlock_bh(&pacl_node_q->lock);
1087
1088         if (added)
1089                 return ret;
1090
1091         spin_lock_bh(&pacl_node_q->lock);
1092
1093         for (i = 0; i < NUM_ACL; i++) {
1094                 paclnode = &pacl_list->aclnode[i];
1095
1096                 if (!paclnode->valid) {
1097                         INIT_LIST_HEAD(&paclnode->list);
1098
1099                         memcpy(paclnode->addr, addr, ETH_ALEN);
1100
1101                         paclnode->valid = true;
1102
1103                         list_add_tail(&paclnode->list, get_list_head(pacl_node_q));
1104
1105                         pacl_list->num++;
1106
1107                         break;
1108                 }
1109         }
1110
1111         DBG_8723A("%s, acl_num =%d\n", __func__, pacl_list->num);
1112
1113         spin_unlock_bh(&pacl_node_q->lock);
1114         return ret;
1115 }
1116
1117 int rtw_acl_remove_sta23a(struct rtw_adapter *padapter, u8 *addr)
1118 {
1119         struct list_head *plist, *phead, *ptmp;
1120         struct rtw_wlan_acl_node *paclnode;
1121         struct sta_priv *pstapriv = &padapter->stapriv;
1122         struct wlan_acl_pool *pacl_list = &pstapriv->acl_list;
1123         struct rtw_queue *pacl_node_q = &pacl_list->acl_node_q;
1124         int ret = 0;
1125
1126         DBG_8723A("%s(acl_num =%d) = %pM\n", __func__, pacl_list->num, addr);
1127
1128         spin_lock_bh(&pacl_node_q->lock);
1129
1130         phead = get_list_head(pacl_node_q);
1131
1132         list_for_each_safe(plist, ptmp, phead) {
1133                 paclnode = container_of(plist, struct rtw_wlan_acl_node, list);
1134
1135                 if (!memcmp(paclnode->addr, addr, ETH_ALEN)) {
1136                         if (paclnode->valid) {
1137                                 paclnode->valid = false;
1138
1139                                 list_del_init(&paclnode->list);
1140
1141                                 pacl_list->num--;
1142                         }
1143                 }
1144         }
1145
1146         spin_unlock_bh(&pacl_node_q->lock);
1147
1148         DBG_8723A("%s, acl_num =%d\n", __func__, pacl_list->num);
1149
1150         return ret;
1151 }
1152
1153 static void update_bcn_fixed_ie(struct rtw_adapter *padapter)
1154 {
1155         DBG_8723A("%s\n", __func__);
1156 }
1157
1158 static void update_bcn_erpinfo_ie(struct rtw_adapter *padapter)
1159 {
1160         struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
1161         struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
1162         struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
1163         struct wlan_bssid_ex *pnetwork = &pmlmeinfo->network;
1164         unsigned char *p, *ie = pnetwork->IEs;
1165         u32 len = 0;
1166
1167         DBG_8723A("%s, ERP_enable =%d\n", __func__, pmlmeinfo->ERP_enable);
1168
1169         if (!pmlmeinfo->ERP_enable)
1170                 return;
1171
1172         /* parsing ERP_IE */
1173         p = rtw_get_ie23a(ie, WLAN_EID_ERP_INFO, &len, pnetwork->IELength);
1174         if (p && len > 0) {
1175                 if (pmlmepriv->num_sta_non_erp == 1)
1176                         p[2] |= WLAN_ERP_NON_ERP_PRESENT |
1177                                 WLAN_ERP_USE_PROTECTION;
1178                 else
1179                         p[2] &= ~(WLAN_ERP_NON_ERP_PRESENT |
1180                                   WLAN_ERP_USE_PROTECTION);
1181
1182                 if (pmlmepriv->num_sta_no_short_preamble > 0)
1183                         p[2] |= WLAN_ERP_BARKER_PREAMBLE;
1184                 else
1185                         p[2] &= ~(WLAN_ERP_BARKER_PREAMBLE);
1186
1187                 ERP_IE_handler23a(padapter, p);
1188         }
1189 }
1190
1191 static void update_bcn_htcap_ie(struct rtw_adapter *padapter)
1192 {
1193         DBG_8723A("%s\n", __func__);
1194 }
1195
1196 static void update_bcn_htinfo_ie(struct rtw_adapter *padapter)
1197 {
1198         DBG_8723A("%s\n", __func__);
1199 }
1200
1201 static void update_bcn_rsn_ie(struct rtw_adapter *padapter)
1202 {
1203         DBG_8723A("%s\n", __func__);
1204 }
1205
1206 static void update_bcn_wpa_ie(struct rtw_adapter *padapter)
1207 {
1208         DBG_8723A("%s\n", __func__);
1209 }
1210
1211 static void update_bcn_wmm_ie(struct rtw_adapter *padapter)
1212 {
1213         DBG_8723A("%s\n", __func__);
1214 }
1215
1216 static void update_bcn_wps_ie(struct rtw_adapter *padapter)
1217 {
1218         DBG_8723A("%s\n", __func__);
1219
1220         return;
1221 }
1222
1223 static void update_bcn_p2p_ie(struct rtw_adapter *padapter)
1224 {
1225 }
1226
1227 static void update_bcn_vendor_spec_ie(struct rtw_adapter *padapter, u8*oui)
1228 {
1229         DBG_8723A("%s\n", __func__);
1230
1231         if (!memcmp(RTW_WPA_OUI23A_TYPE, oui, 4))
1232                 update_bcn_wpa_ie(padapter);
1233         else if (!memcmp(WMM_OUI23A, oui, 4))
1234                 update_bcn_wmm_ie(padapter);
1235         else if (!memcmp(WPS_OUI23A, oui, 4))
1236                 update_bcn_wps_ie(padapter);
1237         else if (!memcmp(P2P_OUI23A, oui, 4))
1238                 update_bcn_p2p_ie(padapter);
1239         else
1240                 DBG_8723A("unknown OUI type!\n");
1241 }
1242
1243 void update_beacon23a(struct rtw_adapter *padapter, u8 ie_id, u8 *oui, u8 tx)
1244 {
1245         struct mlme_priv *pmlmepriv;
1246         struct mlme_ext_priv *pmlmeext;
1247         /* struct mlme_ext_info *pmlmeinfo; */
1248
1249         /* DBG_8723A("%s\n", __func__); */
1250
1251         if (!padapter)
1252                 return;
1253
1254         pmlmepriv = &padapter->mlmepriv;
1255         pmlmeext = &padapter->mlmeextpriv;
1256         /* pmlmeinfo = &pmlmeext->mlmext_info; */
1257
1258         if (false == pmlmeext->bstart_bss)
1259                 return;
1260
1261         spin_lock_bh(&pmlmepriv->bcn_update_lock);
1262
1263         switch (ie_id)
1264         {
1265         case 0xFF:
1266                 /* 8: TimeStamp, 2: Beacon Interval 2:Capability */
1267                 update_bcn_fixed_ie(padapter);
1268                 break;
1269
1270         case WLAN_EID_TIM:
1271                 update_BCNTIM(padapter);
1272                 break;
1273
1274         case WLAN_EID_ERP_INFO:
1275                 update_bcn_erpinfo_ie(padapter);
1276                 break;
1277
1278         case WLAN_EID_HT_CAPABILITY:
1279                 update_bcn_htcap_ie(padapter);
1280                 break;
1281
1282         case WLAN_EID_RSN:
1283                 update_bcn_rsn_ie(padapter);
1284                 break;
1285
1286         case WLAN_EID_HT_OPERATION:
1287                 update_bcn_htinfo_ie(padapter);
1288                 break;
1289
1290         case WLAN_EID_VENDOR_SPECIFIC:
1291                 update_bcn_vendor_spec_ie(padapter, oui);
1292                 break;
1293
1294         default:
1295                 break;
1296         }
1297
1298         pmlmepriv->update_bcn = true;
1299
1300         spin_unlock_bh(&pmlmepriv->bcn_update_lock);
1301
1302         if (tx)
1303                 set_tx_beacon_cmd23a(padapter);
1304 }
1305
1306 /*
1307 op_mode
1308 Set to 0 (HT pure) under the following conditions
1309         - all STAs in the BSS are 20/40 MHz HT in 20/40 MHz BSS or
1310         - all STAs in the BSS are 20 MHz HT in 20 MHz BSS
1311 Set to 1 (HT non-member protection) if there may be non-HT STAs
1312         in both the primary and the secondary channel
1313 Set to 2 if only HT STAs are associated in BSS,
1314         however and at least one 20 MHz HT STA is associated
1315 Set to 3 (HT mixed mode) when one or more non-HT STAs are associated
1316         (currently non-GF HT station is considered as non-HT STA also)
1317 */
1318 static int rtw_ht_operation_update(struct rtw_adapter *padapter)
1319 {
1320         u16 cur_op_mode, new_op_mode;
1321         int op_mode_changes = 0;
1322         struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
1323         struct ht_priv *phtpriv_ap = &pmlmepriv->htpriv;
1324
1325         if (pmlmepriv->htpriv.ht_option)
1326                 return 0;
1327
1328         /* if (!iface->conf->ieee80211n || iface->conf->ht_op_mode_fixed) */
1329         /*      return 0; */
1330
1331         DBG_8723A("%s current operation mode = 0x%X\n",
1332                    __func__, pmlmepriv->ht_op_mode);
1333
1334         if (!(pmlmepriv->ht_op_mode & IEEE80211_HT_OP_MODE_NON_GF_STA_PRSNT)
1335             && pmlmepriv->num_sta_ht_no_gf) {
1336                 pmlmepriv->ht_op_mode |=
1337                         IEEE80211_HT_OP_MODE_NON_GF_STA_PRSNT;
1338                 op_mode_changes++;
1339         } else if ((pmlmepriv->ht_op_mode &
1340                     IEEE80211_HT_OP_MODE_NON_GF_STA_PRSNT) &&
1341                    pmlmepriv->num_sta_ht_no_gf == 0) {
1342                 pmlmepriv->ht_op_mode &=
1343                         ~IEEE80211_HT_OP_MODE_NON_GF_STA_PRSNT;
1344                 op_mode_changes++;
1345         }
1346
1347         if (!(pmlmepriv->ht_op_mode & IEEE80211_HT_OP_MODE_NON_HT_STA_PRSNT) &&
1348             (pmlmepriv->num_sta_no_ht || pmlmepriv->olbc_ht)) {
1349                 pmlmepriv->ht_op_mode |= IEEE80211_HT_OP_MODE_NON_HT_STA_PRSNT;
1350                 op_mode_changes++;
1351         } else if ((pmlmepriv->ht_op_mode &
1352                     IEEE80211_HT_OP_MODE_NON_HT_STA_PRSNT) &&
1353                    (pmlmepriv->num_sta_no_ht == 0 && !pmlmepriv->olbc_ht)) {
1354                 pmlmepriv->ht_op_mode &=
1355                         ~IEEE80211_HT_OP_MODE_NON_HT_STA_PRSNT;
1356                 op_mode_changes++;
1357         }
1358
1359         /* Note: currently we switch to the MIXED op mode if HT non-greenfield
1360          * station is associated. Probably it's a theoretical case, since
1361          * it looks like all known HT STAs support greenfield.
1362          */
1363         if (pmlmepriv->num_sta_no_ht ||
1364             (pmlmepriv->ht_op_mode & IEEE80211_HT_OP_MODE_NON_GF_STA_PRSNT))
1365                 new_op_mode = IEEE80211_HT_OP_MODE_PROTECTION_NONHT_MIXED;
1366         else if ((le16_to_cpu(phtpriv_ap->ht_cap.cap_info) &
1367                   IEEE80211_HT_CAP_SUP_WIDTH_20_40) &&
1368                  pmlmepriv->num_sta_ht_20mhz)
1369                 new_op_mode = IEEE80211_HT_OP_MODE_PROTECTION_20MHZ;
1370         else if (pmlmepriv->olbc_ht)
1371                 new_op_mode = IEEE80211_HT_OP_MODE_PROTECTION_NONMEMBER;
1372         else
1373                 new_op_mode = IEEE80211_HT_OP_MODE_PROTECTION_NONE;
1374
1375         cur_op_mode = pmlmepriv->ht_op_mode & IEEE80211_HT_OP_MODE_PROTECTION;
1376         if (cur_op_mode != new_op_mode) {
1377                 pmlmepriv->ht_op_mode &= ~IEEE80211_HT_OP_MODE_PROTECTION;
1378                 pmlmepriv->ht_op_mode |= new_op_mode;
1379                 op_mode_changes++;
1380         }
1381
1382         DBG_8723A("%s new operation mode = 0x%X changes =%d\n",
1383                    __func__, pmlmepriv->ht_op_mode, op_mode_changes);
1384
1385         return op_mode_changes;
1386 }
1387
1388 void associated_clients_update23a(struct rtw_adapter *padapter, u8 updated)
1389 {
1390         /* update associated stations cap. */
1391         if (updated == true)
1392         {
1393                 struct list_head *phead, *plist, *ptmp;
1394                 struct sta_info *psta;
1395                 struct sta_priv *pstapriv = &padapter->stapriv;
1396
1397                 spin_lock_bh(&pstapriv->asoc_list_lock);
1398
1399                 phead = &pstapriv->asoc_list;
1400
1401                 list_for_each_safe(plist, ptmp, phead) {
1402                         psta = container_of(plist, struct sta_info, asoc_list);
1403
1404                         VCS_update23a(padapter, psta);
1405                 }
1406
1407                 spin_unlock_bh(&pstapriv->asoc_list_lock);
1408         }
1409 }
1410
1411 /* called > TSR LEVEL for USB or SDIO Interface*/
1412 void bss_cap_update_on_sta_join23a(struct rtw_adapter *padapter, struct sta_info *psta)
1413 {
1414         u8 beacon_updated = false;
1415         struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
1416         struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
1417
1418         if (!(psta->flags & WLAN_STA_SHORT_PREAMBLE))
1419         {
1420                 if (!psta->no_short_preamble_set)
1421                 {
1422                         psta->no_short_preamble_set = 1;
1423
1424                         pmlmepriv->num_sta_no_short_preamble++;
1425
1426                         if ((pmlmeext->cur_wireless_mode > WIRELESS_11B) &&
1427                                 (pmlmepriv->num_sta_no_short_preamble == 1))
1428                         {
1429                                 beacon_updated = true;
1430                                 update_beacon23a(padapter, 0xFF, NULL, true);
1431                         }
1432
1433                 }
1434         }
1435         else
1436         {
1437                 if (psta->no_short_preamble_set)
1438                 {
1439                         psta->no_short_preamble_set = 0;
1440
1441                         pmlmepriv->num_sta_no_short_preamble--;
1442
1443                         if ((pmlmeext->cur_wireless_mode > WIRELESS_11B) &&
1444                                 (pmlmepriv->num_sta_no_short_preamble == 0))
1445                         {
1446                                 beacon_updated = true;
1447                                 update_beacon23a(padapter, 0xFF, NULL, true);
1448                         }
1449
1450                 }
1451         }
1452
1453         if (psta->flags & WLAN_STA_NONERP)
1454         {
1455                 if (!psta->nonerp_set)
1456                 {
1457                         psta->nonerp_set = 1;
1458
1459                         pmlmepriv->num_sta_non_erp++;
1460
1461                         if (pmlmepriv->num_sta_non_erp == 1)
1462                         {
1463                                 beacon_updated = true;
1464                                 update_beacon23a(padapter, WLAN_EID_ERP_INFO, NULL, true);
1465                         }
1466                 }
1467
1468         }
1469         else
1470         {
1471                 if (psta->nonerp_set)
1472                 {
1473                         psta->nonerp_set = 0;
1474
1475                         pmlmepriv->num_sta_non_erp--;
1476
1477                         if (pmlmepriv->num_sta_non_erp == 0)
1478                         {
1479                                 beacon_updated = true;
1480                                 update_beacon23a(padapter, WLAN_EID_ERP_INFO, NULL, true);
1481                         }
1482                 }
1483
1484         }
1485
1486         if (!(psta->capability & WLAN_CAPABILITY_SHORT_SLOT_TIME))
1487         {
1488                 if (!psta->no_short_slot_time_set)
1489                 {
1490                         psta->no_short_slot_time_set = 1;
1491
1492                         pmlmepriv->num_sta_no_short_slot_time++;
1493
1494                         if ((pmlmeext->cur_wireless_mode > WIRELESS_11B) &&
1495                                  (pmlmepriv->num_sta_no_short_slot_time == 1))
1496                         {
1497                                 beacon_updated = true;
1498                                 update_beacon23a(padapter, 0xFF, NULL, true);
1499                         }
1500
1501                 }
1502         }
1503         else
1504         {
1505                 if (psta->no_short_slot_time_set)
1506                 {
1507                         psta->no_short_slot_time_set = 0;
1508
1509                         pmlmepriv->num_sta_no_short_slot_time--;
1510
1511                         if ((pmlmeext->cur_wireless_mode > WIRELESS_11B) &&
1512                                  (pmlmepriv->num_sta_no_short_slot_time == 0))
1513                         {
1514                                 beacon_updated = true;
1515                                 update_beacon23a(padapter, 0xFF, NULL, true);
1516                         }
1517                 }
1518         }
1519
1520         if (psta->flags & WLAN_STA_HT)
1521         {
1522                 u16 ht_capab = le16_to_cpu(psta->htpriv.ht_cap.cap_info);
1523
1524                 DBG_8723A("HT: STA " MAC_FMT " HT Capabilities "
1525                            "Info: 0x%04x\n", MAC_ARG(psta->hwaddr), ht_capab);
1526
1527                 if (psta->no_ht_set) {
1528                         psta->no_ht_set = 0;
1529                         pmlmepriv->num_sta_no_ht--;
1530                 }
1531
1532                 if ((ht_capab & IEEE80211_HT_CAP_GRN_FLD) == 0) {
1533                         if (!psta->no_ht_gf_set) {
1534                                 psta->no_ht_gf_set = 1;
1535                                 pmlmepriv->num_sta_ht_no_gf++;
1536                         }
1537                         DBG_8723A("%s STA " MAC_FMT " - no "
1538                                    "greenfield, num of non-gf stations %d\n",
1539                                    __func__, MAC_ARG(psta->hwaddr),
1540                                    pmlmepriv->num_sta_ht_no_gf);
1541                 }
1542
1543                 if ((ht_capab & IEEE80211_HT_CAP_SUP_WIDTH_20_40) == 0) {
1544                         if (!psta->ht_20mhz_set) {
1545                                 psta->ht_20mhz_set = 1;
1546                                 pmlmepriv->num_sta_ht_20mhz++;
1547                         }
1548                         DBG_8723A("%s STA " MAC_FMT " - 20 MHz HT, "
1549                                    "num of 20MHz HT STAs %d\n",
1550                                    __func__, MAC_ARG(psta->hwaddr),
1551                                    pmlmepriv->num_sta_ht_20mhz);
1552                 }
1553
1554         }
1555         else
1556         {
1557                 if (!psta->no_ht_set) {
1558                         psta->no_ht_set = 1;
1559                         pmlmepriv->num_sta_no_ht++;
1560                 }
1561                 if (pmlmepriv->htpriv.ht_option) {
1562                         DBG_8723A("%s STA " MAC_FMT
1563                                    " - no HT, num of non-HT stations %d\n",
1564                                    __func__, MAC_ARG(psta->hwaddr),
1565                                    pmlmepriv->num_sta_no_ht);
1566                 }
1567         }
1568
1569         if (rtw_ht_operation_update(padapter) > 0)
1570         {
1571                 update_beacon23a(padapter, WLAN_EID_HT_CAPABILITY, NULL, false);
1572                 update_beacon23a(padapter, WLAN_EID_HT_OPERATION, NULL, true);
1573         }
1574
1575         /* update associated stations cap. */
1576         associated_clients_update23a(padapter,  beacon_updated);
1577
1578         DBG_8723A("%s, updated =%d\n", __func__, beacon_updated);
1579 }
1580
1581 u8 bss_cap_update_on_sta_leave23a(struct rtw_adapter *padapter, struct sta_info *psta)
1582 {
1583         u8 beacon_updated = false;
1584         struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
1585         struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
1586
1587         if (!psta)
1588                 return beacon_updated;
1589
1590         if (psta->no_short_preamble_set) {
1591                 psta->no_short_preamble_set = 0;
1592                 pmlmepriv->num_sta_no_short_preamble--;
1593                 if (pmlmeext->cur_wireless_mode > WIRELESS_11B
1594                     && pmlmepriv->num_sta_no_short_preamble == 0)
1595                 {
1596                         beacon_updated = true;
1597                         update_beacon23a(padapter, 0xFF, NULL, true);
1598                 }
1599         }
1600
1601         if (psta->nonerp_set) {
1602                 psta->nonerp_set = 0;
1603                 pmlmepriv->num_sta_non_erp--;
1604                 if (pmlmepriv->num_sta_non_erp == 0)
1605                 {
1606                         beacon_updated = true;
1607                         update_beacon23a(padapter, WLAN_EID_ERP_INFO,
1608                                          NULL, true);
1609                 }
1610         }
1611
1612         if (psta->no_short_slot_time_set) {
1613                 psta->no_short_slot_time_set = 0;
1614                 pmlmepriv->num_sta_no_short_slot_time--;
1615                 if (pmlmeext->cur_wireless_mode > WIRELESS_11B
1616                     && pmlmepriv->num_sta_no_short_slot_time == 0)
1617                 {
1618                         beacon_updated = true;
1619                         update_beacon23a(padapter, 0xFF, NULL, true);
1620                 }
1621         }
1622
1623         if (psta->no_ht_gf_set) {
1624                 psta->no_ht_gf_set = 0;
1625                 pmlmepriv->num_sta_ht_no_gf--;
1626         }
1627
1628         if (psta->no_ht_set) {
1629                 psta->no_ht_set = 0;
1630                 pmlmepriv->num_sta_no_ht--;
1631         }
1632
1633         if (psta->ht_20mhz_set) {
1634                 psta->ht_20mhz_set = 0;
1635                 pmlmepriv->num_sta_ht_20mhz--;
1636         }
1637
1638         if (rtw_ht_operation_update(padapter) > 0)
1639         {
1640                 update_beacon23a(padapter, WLAN_EID_HT_CAPABILITY, NULL, false);
1641                 update_beacon23a(padapter, WLAN_EID_HT_OPERATION, NULL, true);
1642         }
1643
1644         /* update associated stations cap. */
1645
1646         DBG_8723A("%s, updated =%d\n", __func__, beacon_updated);
1647
1648         return beacon_updated;
1649 }
1650
1651 u8 ap_free_sta23a(struct rtw_adapter *padapter, struct sta_info *psta, bool active, u16 reason)
1652 {
1653         struct sta_priv *pstapriv = &padapter->stapriv;
1654         u8 beacon_updated = false;
1655
1656         if (!psta)
1657                 return beacon_updated;
1658
1659         if (active == true)
1660         {
1661                 /* tear down Rx AMPDU */
1662                 send_delba23a(padapter, 0, psta->hwaddr);/*  recipient */
1663
1664                 /* tear down TX AMPDU */
1665                 send_delba23a(padapter, 1, psta->hwaddr);/* originator */
1666
1667                 issue_deauth23a(padapter, psta->hwaddr, reason);
1668         }
1669
1670         psta->htpriv.agg_enable_bitmap = 0x0;/* reset */
1671         psta->htpriv.candidate_tid_bitmap = 0x0;/* reset */
1672
1673         /* report_del_sta_event23a(padapter, psta->hwaddr, reason); */
1674
1675         /* clear cam entry / key */
1676         /* clear_cam_entry23a(padapter, (psta->mac_id + 3)); */
1677         rtw_clearstakey_cmd23a(padapter, (u8*)psta, (u8)(psta->mac_id + 3), true);
1678
1679         spin_lock_bh(&psta->lock);
1680         psta->state &= ~_FW_LINKED;
1681         spin_unlock_bh(&psta->lock);
1682
1683         rtw_cfg80211_indicate_sta_disassoc(padapter, psta->hwaddr, reason);
1684
1685         report_del_sta_event23a(padapter, psta->hwaddr, reason);
1686
1687         beacon_updated = bss_cap_update_on_sta_leave23a(padapter, psta);
1688
1689         spin_lock_bh(&pstapriv->sta_hash_lock);
1690         rtw_free_stainfo23a(padapter, psta);
1691         spin_unlock_bh(&pstapriv->sta_hash_lock);
1692
1693         return beacon_updated;
1694 }
1695
1696 int rtw_ap_inform_ch_switch23a (struct rtw_adapter *padapter, u8 new_ch, u8 ch_offset)
1697 {
1698         struct list_head *phead, *plist;
1699         int ret = 0;
1700         struct sta_info *psta = NULL;
1701         struct sta_priv *pstapriv = &padapter->stapriv;
1702         struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
1703         struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
1704         u8 bc_addr[ETH_ALEN] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
1705
1706         if ((pmlmeinfo->state&0x03) != MSR_AP)
1707                 return ret;
1708
1709         DBG_8723A("%s(%s): with ch:%u, offset:%u\n", __func__,
1710                   padapter->pnetdev->name, new_ch, ch_offset);
1711
1712         spin_lock_bh(&pstapriv->asoc_list_lock);
1713         phead = &pstapriv->asoc_list;
1714
1715         list_for_each(plist, phead) {
1716                 psta = container_of(plist, struct sta_info, asoc_list);
1717
1718                 issue_action_spct_ch_switch23a (padapter, psta->hwaddr, new_ch, ch_offset);
1719                 psta->expire_to = ((pstapriv->expire_to * 2) > 5) ? 5 : (pstapriv->expire_to * 2);
1720         }
1721         spin_unlock_bh(&pstapriv->asoc_list_lock);
1722
1723         issue_action_spct_ch_switch23a (padapter, bc_addr, new_ch, ch_offset);
1724
1725         return ret;
1726 }
1727
1728 int rtw_sta_flush23a(struct rtw_adapter *padapter)
1729 {
1730         struct list_head *phead, *plist, *ptmp;
1731         int ret = 0;
1732         struct sta_info *psta;
1733         struct sta_priv *pstapriv = &padapter->stapriv;
1734         struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
1735         struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
1736         u8 bc_addr[ETH_ALEN] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
1737         u8 chk_alive_num = 0;
1738         struct sta_info *chk_alive_list[NUM_STA];
1739         int i;
1740
1741         DBG_8723A("%s(%s)\n", __func__, padapter->pnetdev->name);
1742
1743         if ((pmlmeinfo->state&0x03) != MSR_AP)
1744                 return ret;
1745
1746         spin_lock_bh(&pstapriv->asoc_list_lock);
1747         phead = &pstapriv->asoc_list;
1748
1749         list_for_each_safe(plist, ptmp, phead) {
1750                 psta = container_of(plist, struct sta_info, asoc_list);
1751
1752                 /* Remove sta from asoc_list */
1753                 list_del_init(&psta->asoc_list);
1754                 pstapriv->asoc_list_cnt--;
1755
1756                 /* Keep sta for ap_free_sta23a() beyond this asoc_list loop */
1757                 chk_alive_list[chk_alive_num++] = psta;
1758         }
1759         spin_unlock_bh(&pstapriv->asoc_list_lock);
1760
1761         /* For each sta in chk_alive_list, call ap_free_sta23a */
1762         for (i = 0; i < chk_alive_num; i++)
1763                 ap_free_sta23a(padapter, chk_alive_list[i], true,
1764                                WLAN_REASON_DEAUTH_LEAVING);
1765
1766         issue_deauth23a(padapter, bc_addr, WLAN_REASON_DEAUTH_LEAVING);
1767
1768         associated_clients_update23a(padapter, true);
1769
1770         return ret;
1771 }
1772
1773 /* called > TSR LEVEL for USB or SDIO Interface*/
1774 void sta_info_update23a(struct rtw_adapter *padapter, struct sta_info *psta)
1775 {
1776         int flags = psta->flags;
1777         struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
1778
1779         /* update wmm cap. */
1780         if (WLAN_STA_WME&flags)
1781                 psta->qos_option = 1;
1782         else
1783                 psta->qos_option = 0;
1784
1785         if (pmlmepriv->qos_option == 0)
1786                 psta->qos_option = 0;
1787
1788         /* update 802.11n ht cap. */
1789         if (WLAN_STA_HT&flags)
1790         {
1791                 psta->htpriv.ht_option = true;
1792                 psta->qos_option = 1;
1793         }
1794         else
1795         {
1796                 psta->htpriv.ht_option = false;
1797         }
1798
1799         if (!pmlmepriv->htpriv.ht_option)
1800                 psta->htpriv.ht_option = false;
1801
1802         update_sta_info23a_apmode23a(padapter, psta);
1803 }
1804
1805 /* called >= TSR LEVEL for USB or SDIO Interface*/
1806 void ap_sta_info_defer_update23a(struct rtw_adapter *padapter, struct sta_info *psta)
1807 {
1808         if (psta->state & _FW_LINKED)
1809         {
1810                 /* add ratid */
1811                 add_RATid23a(padapter, psta, 0);/* DM_RATR_STA_INIT */
1812         }
1813 }
1814
1815 /* restore hw setting from sw data structures */
1816 void rtw_ap_restore_network(struct rtw_adapter *padapter)
1817 {
1818         struct mlme_priv *mlmepriv = &padapter->mlmepriv;
1819         struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
1820         struct sta_priv * pstapriv = &padapter->stapriv;
1821         struct sta_info *psta;
1822         struct security_priv *psecuritypriv = &padapter->securitypriv;
1823         struct list_head *phead, *plist, *ptmp;
1824         u8 chk_alive_num = 0;
1825         struct sta_info *chk_alive_list[NUM_STA];
1826         int i;
1827
1828         rtw_setopmode_cmd23a(padapter, NL80211_IFTYPE_AP);
1829
1830         set_channel_bwmode23a(padapter, pmlmeext->cur_channel, pmlmeext->cur_ch_offset, pmlmeext->cur_bwmode);
1831
1832         start_bss_network(padapter, (u8*)&mlmepriv->cur_network.network);
1833
1834         if (padapter->securitypriv.dot11PrivacyAlgrthm ==
1835             WLAN_CIPHER_SUITE_TKIP ||
1836             padapter->securitypriv.dot11PrivacyAlgrthm ==
1837             WLAN_CIPHER_SUITE_CCMP) {
1838                 /* restore group key, WEP keys is restored in ips_leave23a() */
1839                 rtw_set_key23a(padapter, psecuritypriv,
1840                                psecuritypriv->dot118021XGrpKeyid, 0);
1841         }
1842
1843         /* per sta pairwise key and settings */
1844         if (padapter->securitypriv.dot11PrivacyAlgrthm !=
1845             WLAN_CIPHER_SUITE_TKIP &&
1846             padapter->securitypriv.dot11PrivacyAlgrthm !=
1847             WLAN_CIPHER_SUITE_CCMP) {
1848                 return;
1849         }
1850
1851         spin_lock_bh(&pstapriv->asoc_list_lock);
1852
1853         phead = &pstapriv->asoc_list;
1854
1855         list_for_each_safe(plist, ptmp, phead) {
1856                 psta = container_of(plist, struct sta_info, asoc_list);
1857
1858                 chk_alive_list[chk_alive_num++] = psta;
1859         }
1860
1861         spin_unlock_bh(&pstapriv->asoc_list_lock);
1862
1863         for (i = 0; i < chk_alive_num; i++) {
1864                 psta = chk_alive_list[i];
1865
1866                 if (psta->state &_FW_LINKED) {
1867                         Update_RA_Entry23a(padapter, psta);
1868                         /* pairwise key */
1869                         rtw_setstakey_cmd23a(padapter, (unsigned char *)psta, true);
1870                 }
1871         }
1872 }
1873
1874 void start_ap_mode23a(struct rtw_adapter *padapter)
1875 {
1876         int i;
1877         struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
1878         struct sta_priv *pstapriv = &padapter->stapriv;
1879         struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
1880         struct wlan_acl_pool *pacl_list = &pstapriv->acl_list;
1881
1882         pmlmepriv->update_bcn = false;
1883
1884         /* init_mlme_ap_info23a(padapter); */
1885         pmlmeext->bstart_bss = false;
1886
1887         pmlmepriv->num_sta_non_erp = 0;
1888
1889         pmlmepriv->num_sta_no_short_slot_time = 0;
1890
1891         pmlmepriv->num_sta_no_short_preamble = 0;
1892
1893         pmlmepriv->num_sta_ht_no_gf = 0;
1894         pmlmepriv->num_sta_no_ht = 0;
1895         pmlmepriv->num_sta_ht_20mhz = 0;
1896
1897         pmlmepriv->olbc = false;
1898
1899         pmlmepriv->olbc_ht = false;
1900
1901         pmlmepriv->ht_op_mode = 0;
1902
1903         for (i = 0; i<NUM_STA; i++)
1904                 pstapriv->sta_aid[i] = NULL;
1905
1906         /* for ACL */
1907         INIT_LIST_HEAD(&pacl_list->acl_node_q.queue);
1908         pacl_list->num = 0;
1909         pacl_list->mode = 0;
1910         for (i = 0; i < NUM_ACL; i++) {
1911                 INIT_LIST_HEAD(&pacl_list->aclnode[i].list);
1912                 pacl_list->aclnode[i].valid = false;
1913         }
1914 }
1915
1916 void stop_ap_mode23a(struct rtw_adapter *padapter)
1917 {
1918         struct list_head *phead, *plist, *ptmp;
1919         struct rtw_wlan_acl_node *paclnode;
1920         struct sta_info *psta = NULL;
1921         struct sta_priv *pstapriv = &padapter->stapriv;
1922         struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
1923         struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
1924         struct wlan_acl_pool *pacl_list = &pstapriv->acl_list;
1925         struct rtw_queue *pacl_node_q = &pacl_list->acl_node_q;
1926
1927         pmlmepriv->update_bcn = false;
1928         pmlmeext->bstart_bss = false;
1929
1930         /* reset and init security priv , this can refine with rtw_reset_securitypriv23a */
1931         memset((unsigned char *)&padapter->securitypriv, 0, sizeof (struct security_priv));
1932         padapter->securitypriv.ndisauthtype = Ndis802_11AuthModeOpen;
1933         padapter->securitypriv.ndisencryptstatus = Ndis802_11WEPDisabled;
1934
1935         /* for ACL */
1936         spin_lock_bh(&pacl_node_q->lock);
1937         phead = get_list_head(pacl_node_q);
1938
1939         list_for_each_safe(plist, ptmp, phead) {
1940                 paclnode = container_of(plist, struct rtw_wlan_acl_node, list);
1941
1942                 if (paclnode->valid == true) {
1943                         paclnode->valid = false;
1944
1945                         list_del_init(&paclnode->list);
1946
1947                         pacl_list->num--;
1948                 }
1949         }
1950         spin_unlock_bh(&pacl_node_q->lock);
1951
1952         DBG_8723A("%s, free acl_node_queue, num =%d\n", __func__, pacl_list->num);
1953
1954         rtw_sta_flush23a(padapter);
1955
1956         /* free_assoc_sta_resources */
1957         rtw_free_all_stainfo23a(padapter);
1958
1959         psta = rtw_get_bcmc_stainfo23a(padapter);
1960         spin_lock_bh(&pstapriv->sta_hash_lock);
1961         rtw_free_stainfo23a(padapter, psta);
1962         spin_unlock_bh(&pstapriv->sta_hash_lock);
1963
1964         rtw_init_bcmc_stainfo23a(padapter);
1965
1966         rtw23a_free_mlme_priv_ie_data(pmlmepriv);
1967 }