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