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