GNU Linux-libre 4.4.289-gnu1
[releases.git] / 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 < 0 || 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                 ie_len = min_t(int, ie_len, sizeof(pbss_network->Ssid.Ssid));
925                 memset(&pbss_network->Ssid, 0, sizeof(struct ndis_802_11_ssid));
926                 memcpy(pbss_network->Ssid.Ssid, (p + 2), ie_len);
927                 pbss_network->Ssid.SsidLength = ie_len;
928         }
929
930         /* channel */
931         channel = 0;
932         pbss_network->Configuration.Length = 0;
933         p = rtw_get_ie(ie + _BEACON_IE_OFFSET_, _DSSET_IE_, &ie_len, (pbss_network->IELength - _BEACON_IE_OFFSET_));
934         if (p && ie_len > 0)
935                 channel = *(p + 2);
936
937         pbss_network->Configuration.DSConfig = channel;
938
939         memset(supportRate, 0, NDIS_802_11_LENGTH_RATES_EX);
940         /*  get supported rates */
941         p = rtw_get_ie(ie + _BEACON_IE_OFFSET_, _SUPPORTEDRATES_IE_, &ie_len, (pbss_network->IELength - _BEACON_IE_OFFSET_));
942         if (p !=  NULL) {
943                 ie_len = min_t(int, ie_len, NDIS_802_11_LENGTH_RATES_EX);
944                 memcpy(supportRate, p+2, ie_len);
945                 supportRateNum = ie_len;
946         }
947
948         /* get ext_supported rates */
949         p = rtw_get_ie(ie + _BEACON_IE_OFFSET_, _EXT_SUPPORTEDRATES_IE_, &ie_len, pbss_network->IELength - _BEACON_IE_OFFSET_);
950         if (p !=  NULL) {
951                 ie_len = min_t(int, ie_len,
952                                NDIS_802_11_LENGTH_RATES_EX - supportRateNum);
953                 memcpy(supportRate+supportRateNum, p+2, ie_len);
954                 supportRateNum += ie_len;
955         }
956
957         network_type = rtw_check_network_type(supportRate, supportRateNum, channel);
958
959         rtw_set_supported_rate(pbss_network->SupportedRates, network_type);
960
961         /* parsing ERP_IE */
962         p = rtw_get_ie(ie + _BEACON_IE_OFFSET_, _ERPINFO_IE_, &ie_len, (pbss_network->IELength - _BEACON_IE_OFFSET_));
963         if (p && ie_len > 0)
964                 ERP_IE_handler(padapter, (struct ndis_802_11_var_ie *)p);
965
966         /* update privacy/security */
967         if (cap & BIT(4))
968                 pbss_network->Privacy = 1;
969         else
970                 pbss_network->Privacy = 0;
971
972         psecuritypriv->wpa_psk = 0;
973
974         /* wpa2 */
975         group_cipher = 0;
976         pairwise_cipher = 0;
977         psecuritypriv->wpa2_group_cipher = _NO_PRIVACY_;
978         psecuritypriv->wpa2_pairwise_cipher = _NO_PRIVACY_;
979         p = rtw_get_ie(ie + _BEACON_IE_OFFSET_, _RSN_IE_2_, &ie_len, (pbss_network->IELength - _BEACON_IE_OFFSET_));
980         if (p && ie_len > 0) {
981                 if (rtw_parse_wpa2_ie(p, ie_len+2, &group_cipher, &pairwise_cipher, NULL) == _SUCCESS) {
982                         psecuritypriv->dot11AuthAlgrthm = dot11AuthAlgrthm_8021X;
983
984                         psecuritypriv->dot8021xalg = 1;/* psk,  todo:802.1x */
985                         psecuritypriv->wpa_psk |= BIT(1);
986
987                         psecuritypriv->wpa2_group_cipher = group_cipher;
988                         psecuritypriv->wpa2_pairwise_cipher = pairwise_cipher;
989                 }
990         }
991         /* wpa */
992         ie_len = 0;
993         group_cipher = 0;
994         pairwise_cipher = 0;
995         psecuritypriv->wpa_group_cipher = _NO_PRIVACY_;
996         psecuritypriv->wpa_pairwise_cipher = _NO_PRIVACY_;
997         for (p = ie + _BEACON_IE_OFFSET_;; p += (ie_len + 2)) {
998                 p = rtw_get_ie(p, _SSN_IE_1_, &ie_len,
999                                (pbss_network->IELength - _BEACON_IE_OFFSET_ - (ie_len + 2)));
1000                 if ((p) && (!memcmp(p+2, OUI1, 4))) {
1001                         if (rtw_parse_wpa_ie(p, ie_len+2, &group_cipher,
1002                                              &pairwise_cipher, NULL) == _SUCCESS) {
1003                                 psecuritypriv->dot11AuthAlgrthm = dot11AuthAlgrthm_8021X;
1004
1005                                 psecuritypriv->dot8021xalg = 1;/* psk,  todo:802.1x */
1006
1007                                 psecuritypriv->wpa_psk |= BIT(0);
1008
1009                                 psecuritypriv->wpa_group_cipher = group_cipher;
1010                                 psecuritypriv->wpa_pairwise_cipher = pairwise_cipher;
1011                         }
1012                         break;
1013                 }
1014                 if ((p == NULL) || (ie_len == 0))
1015                         break;
1016         }
1017
1018         /* wmm */
1019         ie_len = 0;
1020         pmlmepriv->qospriv.qos_option = 0;
1021         if (pregistrypriv->wmm_enable) {
1022                 for (p = ie + _BEACON_IE_OFFSET_;; p += (ie_len + 2)) {
1023                         p = rtw_get_ie(p, _VENDOR_SPECIFIC_IE_, &ie_len,
1024                                        (pbss_network->IELength - _BEACON_IE_OFFSET_ - (ie_len + 2)));
1025                         if ((p) && !memcmp(p+2, WMM_PARA_IE, 6)) {
1026                                 pmlmepriv->qospriv.qos_option = 1;
1027
1028                                 *(p+8) |= BIT(7);/* QoS Info, support U-APSD */
1029
1030                                 /* disable all ACM bits since the WMM admission control is not supported */
1031                                 *(p + 10) &= ~BIT(4); /* BE */
1032                                 *(p + 14) &= ~BIT(4); /* BK */
1033                                 *(p + 18) &= ~BIT(4); /* VI */
1034                                 *(p + 22) &= ~BIT(4); /* VO */
1035                                 break;
1036                         }
1037
1038                         if ((p == NULL) || (ie_len == 0))
1039                                 break;
1040                 }
1041         }
1042         /* parsing HT_CAP_IE */
1043         p = rtw_get_ie(ie + _BEACON_IE_OFFSET_, _HT_CAPABILITY_IE_, &ie_len,
1044                        (pbss_network->IELength - _BEACON_IE_OFFSET_));
1045         if (p && ie_len > 0) {
1046                 u8 rf_type;
1047                 struct rtw_ieee80211_ht_cap *pht_cap = (struct rtw_ieee80211_ht_cap *)(p+2);
1048
1049                 pHT_caps_ie = p;
1050                 ht_cap = true;
1051                 network_type |= WIRELESS_11_24N;
1052
1053                 rtw_hal_get_hwreg(padapter, HW_VAR_RF_TYPE, (u8 *)(&rf_type));
1054
1055                 if ((psecuritypriv->wpa_pairwise_cipher & WPA_CIPHER_CCMP) ||
1056                     (psecuritypriv->wpa2_pairwise_cipher & WPA_CIPHER_CCMP))
1057                         pht_cap->ampdu_params_info |= (IEEE80211_HT_CAP_AMPDU_DENSITY&(0x07<<2));
1058                 else
1059                         pht_cap->ampdu_params_info |= (IEEE80211_HT_CAP_AMPDU_DENSITY&0x00);
1060
1061                 /* set  Max Rx AMPDU size  to 64K */
1062                 pht_cap->ampdu_params_info |= (IEEE80211_HT_CAP_AMPDU_FACTOR & 0x03);
1063
1064                 if (rf_type == RF_1T1R) {
1065                         pht_cap->supp_mcs_set[0] = 0xff;
1066                         pht_cap->supp_mcs_set[1] = 0x0;
1067                 }
1068                 ie_len = min_t(int, ie_len, sizeof(pmlmepriv->htpriv.ht_cap));
1069                 memcpy(&pmlmepriv->htpriv.ht_cap, p+2, ie_len);
1070         }
1071
1072         /* parsing HT_INFO_IE */
1073         p = rtw_get_ie(ie + _BEACON_IE_OFFSET_, _HT_ADD_INFO_IE_, &ie_len,
1074                        (pbss_network->IELength - _BEACON_IE_OFFSET_));
1075         if (p && ie_len > 0)
1076                 pHT_info_ie = p;
1077         switch (network_type) {
1078         case WIRELESS_11B:
1079                 pbss_network->NetworkTypeInUse = Ndis802_11DS;
1080                 break;
1081         case WIRELESS_11G:
1082         case WIRELESS_11BG:
1083         case WIRELESS_11G_24N:
1084         case WIRELESS_11BG_24N:
1085                 pbss_network->NetworkTypeInUse = Ndis802_11OFDM24;
1086                 break;
1087         case WIRELESS_11A:
1088                 pbss_network->NetworkTypeInUse = Ndis802_11OFDM5;
1089                 break;
1090         default:
1091                 pbss_network->NetworkTypeInUse = Ndis802_11OFDM24;
1092                 break;
1093         }
1094
1095         pmlmepriv->cur_network.network_type = network_type;
1096
1097         pmlmepriv->htpriv.ht_option = false;
1098
1099         if ((psecuritypriv->wpa2_pairwise_cipher & WPA_CIPHER_TKIP) ||
1100             (psecuritypriv->wpa_pairwise_cipher & WPA_CIPHER_TKIP)) {
1101                 /* todo: */
1102                 /* ht_cap = false; */
1103         }
1104
1105         /* ht_cap */
1106         if (pregistrypriv->ht_enable && ht_cap) {
1107                 pmlmepriv->htpriv.ht_option = true;
1108                 pmlmepriv->qospriv.qos_option = 1;
1109
1110                 if (pregistrypriv->ampdu_enable == 1)
1111                         pmlmepriv->htpriv.ampdu_enable = true;
1112                 HT_caps_handler(padapter, (struct ndis_802_11_var_ie *)pHT_caps_ie);
1113
1114                 HT_info_handler(padapter, (struct ndis_802_11_var_ie *)pHT_info_ie);
1115         }
1116
1117         pbss_network->Length = get_wlan_bssid_ex_sz((struct wlan_bssid_ex  *)pbss_network);
1118
1119         /* issue beacon to start bss network */
1120         start_bss_network(padapter, (u8 *)pbss_network);
1121
1122         /* alloc sta_info for ap itself */
1123         psta = rtw_get_stainfo(&padapter->stapriv, pbss_network->MacAddress);
1124         if (!psta) {
1125                 psta = rtw_alloc_stainfo(&padapter->stapriv, pbss_network->MacAddress);
1126                 if (psta == NULL)
1127                         return _FAIL;
1128         }
1129
1130         /* fix bug of flush_cam_entry at STOP AP mode */
1131         psta->state |= WIFI_AP_STATE;
1132         rtw_indicate_connect(padapter);
1133         pmlmepriv->cur_network.join_res = true;/* for check if already set beacon */
1134         return ret;
1135 }
1136
1137 void rtw_set_macaddr_acl(struct adapter *padapter, int mode)
1138 {
1139         struct sta_priv *pstapriv = &padapter->stapriv;
1140         struct wlan_acl_pool *pacl_list = &pstapriv->acl_list;
1141
1142         DBG_88E("%s, mode =%d\n", __func__, mode);
1143
1144         pacl_list->mode = mode;
1145 }
1146
1147 int rtw_acl_add_sta(struct adapter *padapter, u8 *addr)
1148 {
1149         struct list_head *plist, *phead;
1150         u8 added = false;
1151         int i, ret = 0;
1152         struct rtw_wlan_acl_node *paclnode;
1153         struct sta_priv *pstapriv = &padapter->stapriv;
1154         struct wlan_acl_pool *pacl_list = &pstapriv->acl_list;
1155         struct __queue *pacl_node_q = &pacl_list->acl_node_q;
1156
1157         DBG_88E("%s(acl_num =%d) =%pM\n", __func__, pacl_list->num, (addr));
1158
1159         if ((NUM_ACL-1) < pacl_list->num)
1160                 return -1;
1161
1162         spin_lock_bh(&(pacl_node_q->lock));
1163
1164         phead = get_list_head(pacl_node_q);
1165         plist = phead->next;
1166
1167         while (phead != plist) {
1168                 paclnode = container_of(plist, struct rtw_wlan_acl_node, list);
1169                 plist = plist->next;
1170
1171                 if (!memcmp(paclnode->addr, addr, ETH_ALEN)) {
1172                         if (paclnode->valid) {
1173                                 added = true;
1174                                 DBG_88E("%s, sta has been added\n", __func__);
1175                                 break;
1176                         }
1177                 }
1178         }
1179
1180         spin_unlock_bh(&(pacl_node_q->lock));
1181
1182         if (added)
1183                 return ret;
1184
1185         spin_lock_bh(&(pacl_node_q->lock));
1186
1187         for (i = 0; i < NUM_ACL; i++) {
1188                 paclnode = &pacl_list->aclnode[i];
1189
1190                 if (!paclnode->valid) {
1191                         INIT_LIST_HEAD(&paclnode->list);
1192
1193                         ether_addr_copy(paclnode->addr, addr);
1194
1195                         paclnode->valid = true;
1196
1197                         list_add_tail(&paclnode->list, get_list_head(pacl_node_q));
1198
1199                         pacl_list->num++;
1200
1201                         break;
1202                 }
1203         }
1204
1205         DBG_88E("%s, acl_num =%d\n", __func__, pacl_list->num);
1206
1207         spin_unlock_bh(&(pacl_node_q->lock));
1208
1209         return ret;
1210 }
1211
1212 int rtw_acl_remove_sta(struct adapter *padapter, u8 *addr)
1213 {
1214         struct list_head *plist, *phead;
1215         struct rtw_wlan_acl_node *paclnode;
1216         struct sta_priv *pstapriv = &padapter->stapriv;
1217         struct wlan_acl_pool *pacl_list = &pstapriv->acl_list;
1218         struct __queue *pacl_node_q = &pacl_list->acl_node_q;
1219
1220         DBG_88E("%s(acl_num =%d) =%pM\n", __func__, pacl_list->num, (addr));
1221
1222         spin_lock_bh(&(pacl_node_q->lock));
1223
1224         phead = get_list_head(pacl_node_q);
1225         plist = phead->next;
1226
1227         while (phead != plist) {
1228                 paclnode = container_of(plist, struct rtw_wlan_acl_node, list);
1229                 plist = plist->next;
1230
1231                 if (!memcmp(paclnode->addr, addr, ETH_ALEN)) {
1232                         if (paclnode->valid) {
1233                                 paclnode->valid = false;
1234
1235                                 list_del_init(&paclnode->list);
1236
1237                                 pacl_list->num--;
1238                         }
1239                 }
1240         }
1241
1242         spin_unlock_bh(&(pacl_node_q->lock));
1243
1244         DBG_88E("%s, acl_num =%d\n", __func__, pacl_list->num);
1245         return 0;
1246 }
1247
1248 static void update_bcn_fixed_ie(struct adapter *padapter)
1249 {
1250         DBG_88E("%s\n", __func__);
1251 }
1252
1253 static void update_bcn_erpinfo_ie(struct adapter *padapter)
1254 {
1255         struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
1256         struct mlme_ext_priv    *pmlmeext = &(padapter->mlmeextpriv);
1257         struct mlme_ext_info    *pmlmeinfo = &(pmlmeext->mlmext_info);
1258         struct wlan_bssid_ex *pnetwork = &(pmlmeinfo->network);
1259         unsigned char *p, *ie = pnetwork->IEs;
1260         u32 len = 0;
1261
1262         DBG_88E("%s, ERP_enable =%d\n", __func__, pmlmeinfo->ERP_enable);
1263
1264         if (!pmlmeinfo->ERP_enable)
1265                 return;
1266
1267         /* parsing ERP_IE */
1268         p = rtw_get_ie(ie + _BEACON_IE_OFFSET_, _ERPINFO_IE_, &len,
1269                        (pnetwork->IELength - _BEACON_IE_OFFSET_));
1270         if (p && len > 0) {
1271                 struct ndis_802_11_var_ie *pIE = (struct ndis_802_11_var_ie *)p;
1272
1273                 if (pmlmepriv->num_sta_non_erp == 1)
1274                         pIE->data[0] |= RTW_ERP_INFO_NON_ERP_PRESENT|RTW_ERP_INFO_USE_PROTECTION;
1275                 else
1276                         pIE->data[0] &= ~(RTW_ERP_INFO_NON_ERP_PRESENT|RTW_ERP_INFO_USE_PROTECTION);
1277
1278                 if (pmlmepriv->num_sta_no_short_preamble > 0)
1279                         pIE->data[0] |= RTW_ERP_INFO_BARKER_PREAMBLE_MODE;
1280                 else
1281                         pIE->data[0] &= ~(RTW_ERP_INFO_BARKER_PREAMBLE_MODE);
1282
1283                 ERP_IE_handler(padapter, pIE);
1284         }
1285 }
1286
1287 static void update_bcn_htcap_ie(struct adapter *padapter)
1288 {
1289         DBG_88E("%s\n", __func__);
1290 }
1291
1292 static void update_bcn_htinfo_ie(struct adapter *padapter)
1293 {
1294         DBG_88E("%s\n", __func__);
1295 }
1296
1297 static void update_bcn_rsn_ie(struct adapter *padapter)
1298 {
1299         DBG_88E("%s\n", __func__);
1300 }
1301
1302 static void update_bcn_wpa_ie(struct adapter *padapter)
1303 {
1304         DBG_88E("%s\n", __func__);
1305 }
1306
1307 static void update_bcn_wmm_ie(struct adapter *padapter)
1308 {
1309         DBG_88E("%s\n", __func__);
1310 }
1311
1312 static void update_bcn_wps_ie(struct adapter *padapter)
1313 {
1314         u8 *pwps_ie = NULL, *pwps_ie_src;
1315         u8 *premainder_ie, *pbackup_remainder_ie = NULL;
1316         uint wps_ielen = 0, wps_offset, remainder_ielen;
1317         struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
1318         struct mlme_ext_priv    *pmlmeext = &(padapter->mlmeextpriv);
1319         struct mlme_ext_info    *pmlmeinfo = &(pmlmeext->mlmext_info);
1320         struct wlan_bssid_ex *pnetwork = &(pmlmeinfo->network);
1321         unsigned char *ie = pnetwork->IEs;
1322         u32 ielen = pnetwork->IELength;
1323
1324         DBG_88E("%s\n", __func__);
1325
1326         pwps_ie_src = pmlmepriv->wps_beacon_ie;
1327         if (pwps_ie_src == NULL)
1328                 return;
1329
1330         pwps_ie = rtw_get_wps_ie(ie+_FIXED_IE_LENGTH_, ielen-_FIXED_IE_LENGTH_, NULL, &wps_ielen);
1331
1332         if (pwps_ie == NULL || wps_ielen == 0)
1333                 return;
1334
1335         wps_offset = (uint)(pwps_ie-ie);
1336
1337         premainder_ie = pwps_ie + wps_ielen;
1338
1339         remainder_ielen = ielen - wps_offset - wps_ielen;
1340
1341         if (remainder_ielen > 0) {
1342                 pbackup_remainder_ie = rtw_malloc(remainder_ielen);
1343                 if (pbackup_remainder_ie)
1344                         memcpy(pbackup_remainder_ie, premainder_ie, remainder_ielen);
1345         }
1346
1347         wps_ielen = (uint)pwps_ie_src[1];/* to get ie data len */
1348         if ((wps_offset+wps_ielen+2+remainder_ielen) <= MAX_IE_SZ) {
1349                 memcpy(pwps_ie, pwps_ie_src, wps_ielen+2);
1350                 pwps_ie += (wps_ielen+2);
1351
1352                 if (pbackup_remainder_ie)
1353                         memcpy(pwps_ie, pbackup_remainder_ie, remainder_ielen);
1354
1355                 /* update IELength */
1356                 pnetwork->IELength = wps_offset + (wps_ielen+2) + remainder_ielen;
1357         }
1358
1359         kfree(pbackup_remainder_ie);
1360 }
1361
1362 static void update_bcn_p2p_ie(struct adapter *padapter)
1363 {
1364 }
1365
1366 static void update_bcn_vendor_spec_ie(struct adapter *padapter, u8 *oui)
1367 {
1368         DBG_88E("%s\n", __func__);
1369
1370         if (!memcmp(RTW_WPA_OUI, oui, 4))
1371                 update_bcn_wpa_ie(padapter);
1372         else if (!memcmp(WMM_OUI, oui, 4))
1373                 update_bcn_wmm_ie(padapter);
1374         else if (!memcmp(WPS_OUI, oui, 4))
1375                 update_bcn_wps_ie(padapter);
1376         else if (!memcmp(P2P_OUI, oui, 4))
1377                 update_bcn_p2p_ie(padapter);
1378         else
1379                 DBG_88E("unknown OUI type!\n");
1380 }
1381
1382 void update_beacon(struct adapter *padapter, u8 ie_id, u8 *oui, u8 tx)
1383 {
1384         struct mlme_priv *pmlmepriv;
1385         struct mlme_ext_priv    *pmlmeext;
1386
1387         if (!padapter)
1388                 return;
1389
1390         pmlmepriv = &(padapter->mlmepriv);
1391         pmlmeext = &(padapter->mlmeextpriv);
1392
1393         if (!pmlmeext->bstart_bss)
1394                 return;
1395
1396         spin_lock_bh(&pmlmepriv->bcn_update_lock);
1397
1398         switch (ie_id) {
1399         case 0xFF:
1400                 update_bcn_fixed_ie(padapter);/* 8: TimeStamp, 2: Beacon Interval 2:Capability */
1401                 break;
1402         case _TIM_IE_:
1403                 update_BCNTIM(padapter);
1404                 break;
1405         case _ERPINFO_IE_:
1406                 update_bcn_erpinfo_ie(padapter);
1407                 break;
1408         case _HT_CAPABILITY_IE_:
1409                 update_bcn_htcap_ie(padapter);
1410                 break;
1411         case _RSN_IE_2_:
1412                 update_bcn_rsn_ie(padapter);
1413                 break;
1414         case _HT_ADD_INFO_IE_:
1415                 update_bcn_htinfo_ie(padapter);
1416                 break;
1417         case _VENDOR_SPECIFIC_IE_:
1418                 update_bcn_vendor_spec_ie(padapter, oui);
1419                 break;
1420         default:
1421                 break;
1422         }
1423
1424         pmlmepriv->update_bcn = true;
1425
1426         spin_unlock_bh(&pmlmepriv->bcn_update_lock);
1427
1428         if (tx)
1429                 set_tx_beacon_cmd(padapter);
1430 }
1431
1432 /*
1433 op_mode
1434 Set to 0 (HT pure) under the following conditions
1435         - all STAs in the BSS are 20/40 MHz HT in 20/40 MHz BSS or
1436         - all STAs in the BSS are 20 MHz HT in 20 MHz BSS
1437 Set to 1 (HT non-member protection) if there may be non-HT STAs
1438         in both the primary and the secondary channel
1439 Set to 2 if only HT STAs are associated in BSS,
1440         however and at least one 20 MHz HT STA is associated
1441 Set to 3 (HT mixed mode) when one or more non-HT STAs are associated
1442         (currently non-GF HT station is considered as non-HT STA also)
1443 */
1444 static int rtw_ht_operation_update(struct adapter *padapter)
1445 {
1446         u16 cur_op_mode, new_op_mode;
1447         int op_mode_changes = 0;
1448         struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
1449         struct ht_priv  *phtpriv_ap = &pmlmepriv->htpriv;
1450
1451         if (pmlmepriv->htpriv.ht_option)
1452                 return 0;
1453
1454         DBG_88E("%s current operation mode = 0x%X\n",
1455                 __func__, pmlmepriv->ht_op_mode);
1456
1457         if (!(pmlmepriv->ht_op_mode & HT_INFO_OPERATION_MODE_NON_GF_DEVS_PRESENT) &&
1458             pmlmepriv->num_sta_ht_no_gf) {
1459                 pmlmepriv->ht_op_mode |=
1460                         HT_INFO_OPERATION_MODE_NON_GF_DEVS_PRESENT;
1461                 op_mode_changes++;
1462         } else if ((pmlmepriv->ht_op_mode &
1463                    HT_INFO_OPERATION_MODE_NON_GF_DEVS_PRESENT) &&
1464                    pmlmepriv->num_sta_ht_no_gf == 0) {
1465                 pmlmepriv->ht_op_mode &=
1466                         ~HT_INFO_OPERATION_MODE_NON_GF_DEVS_PRESENT;
1467                 op_mode_changes++;
1468         }
1469
1470         if (!(pmlmepriv->ht_op_mode & HT_INFO_OPERATION_MODE_NON_HT_STA_PRESENT) &&
1471             (pmlmepriv->num_sta_no_ht || pmlmepriv->olbc_ht)) {
1472                 pmlmepriv->ht_op_mode |= HT_INFO_OPERATION_MODE_NON_HT_STA_PRESENT;
1473                 op_mode_changes++;
1474         } else if ((pmlmepriv->ht_op_mode &
1475                     HT_INFO_OPERATION_MODE_NON_HT_STA_PRESENT) &&
1476                    (pmlmepriv->num_sta_no_ht == 0 && !pmlmepriv->olbc_ht)) {
1477                 pmlmepriv->ht_op_mode &=
1478                         ~HT_INFO_OPERATION_MODE_NON_HT_STA_PRESENT;
1479                 op_mode_changes++;
1480         }
1481
1482         /* Note: currently we switch to the MIXED op mode if HT non-greenfield
1483          * station is associated. Probably it's a theoretical case, since
1484          * it looks like all known HT STAs support greenfield.
1485          */
1486         new_op_mode = 0;
1487         if (pmlmepriv->num_sta_no_ht ||
1488             (pmlmepriv->ht_op_mode & HT_INFO_OPERATION_MODE_NON_GF_DEVS_PRESENT))
1489                 new_op_mode = OP_MODE_MIXED;
1490         else if ((phtpriv_ap->ht_cap.cap_info & IEEE80211_HT_CAP_SUP_WIDTH) &&
1491                  pmlmepriv->num_sta_ht_20mhz)
1492                 new_op_mode = OP_MODE_20MHZ_HT_STA_ASSOCED;
1493         else if (pmlmepriv->olbc_ht)
1494                 new_op_mode = OP_MODE_MAY_BE_LEGACY_STAS;
1495         else
1496                 new_op_mode = OP_MODE_PURE;
1497
1498         cur_op_mode = pmlmepriv->ht_op_mode & HT_INFO_OPERATION_MODE_OP_MODE_MASK;
1499         if (cur_op_mode != new_op_mode) {
1500                 pmlmepriv->ht_op_mode &= ~HT_INFO_OPERATION_MODE_OP_MODE_MASK;
1501                 pmlmepriv->ht_op_mode |= new_op_mode;
1502                 op_mode_changes++;
1503         }
1504
1505         DBG_88E("%s new operation mode = 0x%X changes =%d\n",
1506                 __func__, pmlmepriv->ht_op_mode, op_mode_changes);
1507
1508         return op_mode_changes;
1509 }
1510
1511 void associated_clients_update(struct adapter *padapter, u8 updated)
1512 {
1513         /* update associated stations cap. */
1514         if (updated) {
1515                 struct list_head *phead, *plist;
1516                 struct sta_info *psta = NULL;
1517                 struct sta_priv *pstapriv = &padapter->stapriv;
1518
1519                 spin_lock_bh(&pstapriv->asoc_list_lock);
1520
1521                 phead = &pstapriv->asoc_list;
1522                 plist = phead->next;
1523
1524                 /* check asoc_queue */
1525                 while (phead != plist) {
1526                         psta = container_of(plist, struct sta_info, asoc_list);
1527
1528                         plist = plist->next;
1529
1530                         VCS_update(padapter, psta);
1531                 }
1532                 spin_unlock_bh(&pstapriv->asoc_list_lock);
1533         }
1534 }
1535
1536 /* called > TSR LEVEL for USB or SDIO Interface*/
1537 void bss_cap_update_on_sta_join(struct adapter *padapter, struct sta_info *psta)
1538 {
1539         u8 beacon_updated = false;
1540         struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
1541         struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
1542
1543         if (!(psta->flags & WLAN_STA_SHORT_PREAMBLE)) {
1544                 if (!psta->no_short_preamble_set) {
1545                         psta->no_short_preamble_set = 1;
1546
1547                         pmlmepriv->num_sta_no_short_preamble++;
1548
1549                         if ((pmlmeext->cur_wireless_mode > WIRELESS_11B) &&
1550                             (pmlmepriv->num_sta_no_short_preamble == 1)) {
1551                                 beacon_updated = true;
1552                                 update_beacon(padapter, 0xFF, NULL, true);
1553                         }
1554                 }
1555         } else {
1556                 if (psta->no_short_preamble_set) {
1557                         psta->no_short_preamble_set = 0;
1558
1559                         pmlmepriv->num_sta_no_short_preamble--;
1560
1561                         if ((pmlmeext->cur_wireless_mode > WIRELESS_11B) &&
1562                             (pmlmepriv->num_sta_no_short_preamble == 0)) {
1563                                 beacon_updated = true;
1564                                 update_beacon(padapter, 0xFF, NULL, true);
1565                         }
1566                 }
1567         }
1568
1569         if (psta->flags & WLAN_STA_NONERP) {
1570                 if (!psta->nonerp_set) {
1571                         psta->nonerp_set = 1;
1572
1573                         pmlmepriv->num_sta_non_erp++;
1574
1575                         if (pmlmepriv->num_sta_non_erp == 1) {
1576                                 beacon_updated = true;
1577                                 update_beacon(padapter, _ERPINFO_IE_, NULL, true);
1578                         }
1579                 }
1580         } else {
1581                 if (psta->nonerp_set) {
1582                         psta->nonerp_set = 0;
1583
1584                         pmlmepriv->num_sta_non_erp--;
1585
1586                         if (pmlmepriv->num_sta_non_erp == 0) {
1587                                 beacon_updated = true;
1588                                 update_beacon(padapter, _ERPINFO_IE_, NULL, true);
1589                         }
1590                 }
1591         }
1592
1593         if (!(psta->capability & WLAN_CAPABILITY_SHORT_SLOT_TIME)) {
1594                 if (!psta->no_short_slot_time_set) {
1595                         psta->no_short_slot_time_set = 1;
1596
1597                         pmlmepriv->num_sta_no_short_slot_time++;
1598
1599                         if ((pmlmeext->cur_wireless_mode > WIRELESS_11B) &&
1600                             (pmlmepriv->num_sta_no_short_slot_time == 1)) {
1601                                 beacon_updated = true;
1602                                 update_beacon(padapter, 0xFF, NULL, true);
1603                         }
1604                 }
1605         } else {
1606                 if (psta->no_short_slot_time_set) {
1607                         psta->no_short_slot_time_set = 0;
1608
1609                         pmlmepriv->num_sta_no_short_slot_time--;
1610
1611                         if ((pmlmeext->cur_wireless_mode > WIRELESS_11B) &&
1612                             (pmlmepriv->num_sta_no_short_slot_time == 0)) {
1613                                 beacon_updated = true;
1614                                 update_beacon(padapter, 0xFF, NULL, true);
1615                         }
1616                 }
1617         }
1618
1619         if (psta->flags & WLAN_STA_HT) {
1620                 u16 ht_capab = psta->htpriv.ht_cap.cap_info;
1621
1622                 DBG_88E("HT: STA %pM HT Capabilities Info: 0x%04x\n",
1623                         (psta->hwaddr), ht_capab);
1624
1625                 if (psta->no_ht_set) {
1626                         psta->no_ht_set = 0;
1627                         pmlmepriv->num_sta_no_ht--;
1628                 }
1629
1630                 if ((ht_capab & IEEE80211_HT_CAP_GRN_FLD) == 0) {
1631                         if (!psta->no_ht_gf_set) {
1632                                 psta->no_ht_gf_set = 1;
1633                                 pmlmepriv->num_sta_ht_no_gf++;
1634                         }
1635                         DBG_88E("%s STA %pM - no greenfield, num of non-gf stations %d\n",
1636                                    __func__, (psta->hwaddr),
1637                                    pmlmepriv->num_sta_ht_no_gf);
1638                 }
1639
1640                 if ((ht_capab & IEEE80211_HT_CAP_SUP_WIDTH) == 0) {
1641                         if (!psta->ht_20mhz_set) {
1642                                 psta->ht_20mhz_set = 1;
1643                                 pmlmepriv->num_sta_ht_20mhz++;
1644                         }
1645                         DBG_88E("%s STA %pM - 20 MHz HT, num of 20MHz HT STAs %d\n",
1646                                    __func__, (psta->hwaddr),
1647                                    pmlmepriv->num_sta_ht_20mhz);
1648                 }
1649         } else {
1650                 if (!psta->no_ht_set) {
1651                         psta->no_ht_set = 1;
1652                         pmlmepriv->num_sta_no_ht++;
1653                 }
1654                 if (pmlmepriv->htpriv.ht_option) {
1655                         DBG_88E("%s STA %pM - no HT, num of non-HT stations %d\n",
1656                                 __func__, (psta->hwaddr),
1657                                 pmlmepriv->num_sta_no_ht);
1658                 }
1659         }
1660
1661         if (rtw_ht_operation_update(padapter) > 0) {
1662                 update_beacon(padapter, _HT_CAPABILITY_IE_, NULL, false);
1663                 update_beacon(padapter, _HT_ADD_INFO_IE_, NULL, true);
1664         }
1665
1666         /* update associated stations cap. */
1667         associated_clients_update(padapter,  beacon_updated);
1668
1669         DBG_88E("%s, updated =%d\n", __func__, beacon_updated);
1670 }
1671
1672 u8 bss_cap_update_on_sta_leave(struct adapter *padapter, struct sta_info *psta)
1673 {
1674         u8 beacon_updated = false;
1675         struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
1676         struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
1677
1678         if (!psta)
1679                 return beacon_updated;
1680
1681         if (psta->no_short_preamble_set) {
1682                 psta->no_short_preamble_set = 0;
1683                 pmlmepriv->num_sta_no_short_preamble--;
1684                 if (pmlmeext->cur_wireless_mode > WIRELESS_11B &&
1685                     pmlmepriv->num_sta_no_short_preamble == 0) {
1686                         beacon_updated = true;
1687                         update_beacon(padapter, 0xFF, NULL, true);
1688                 }
1689         }
1690
1691         if (psta->nonerp_set) {
1692                 psta->nonerp_set = 0;
1693                 pmlmepriv->num_sta_non_erp--;
1694                 if (pmlmepriv->num_sta_non_erp == 0) {
1695                         beacon_updated = true;
1696                         update_beacon(padapter, _ERPINFO_IE_, NULL, true);
1697                 }
1698         }
1699
1700         if (psta->no_short_slot_time_set) {
1701                 psta->no_short_slot_time_set = 0;
1702                 pmlmepriv->num_sta_no_short_slot_time--;
1703                 if (pmlmeext->cur_wireless_mode > WIRELESS_11B &&
1704                     pmlmepriv->num_sta_no_short_slot_time == 0) {
1705                         beacon_updated = true;
1706                         update_beacon(padapter, 0xFF, NULL, true);
1707                 }
1708         }
1709
1710         if (psta->no_ht_gf_set) {
1711                 psta->no_ht_gf_set = 0;
1712                 pmlmepriv->num_sta_ht_no_gf--;
1713         }
1714
1715         if (psta->no_ht_set) {
1716                 psta->no_ht_set = 0;
1717                 pmlmepriv->num_sta_no_ht--;
1718         }
1719
1720         if (psta->ht_20mhz_set) {
1721                 psta->ht_20mhz_set = 0;
1722                 pmlmepriv->num_sta_ht_20mhz--;
1723         }
1724
1725         if (rtw_ht_operation_update(padapter) > 0) {
1726                 update_beacon(padapter, _HT_CAPABILITY_IE_, NULL, false);
1727                 update_beacon(padapter, _HT_ADD_INFO_IE_, NULL, true);
1728         }
1729
1730         /* update associated stations cap. */
1731
1732         DBG_88E("%s, updated =%d\n", __func__, beacon_updated);
1733
1734         return beacon_updated;
1735 }
1736
1737 u8 ap_free_sta(struct adapter *padapter, struct sta_info *psta,
1738                bool active, u16 reason)
1739 {
1740         u8 beacon_updated = false;
1741         struct sta_priv *pstapriv = &padapter->stapriv;
1742
1743         if (!psta)
1744                 return beacon_updated;
1745
1746         /* tear down Rx AMPDU */
1747         send_delba(padapter, 0, psta->hwaddr);/*  recipient */
1748
1749         /* tear down TX AMPDU */
1750         send_delba(padapter, 1, psta->hwaddr);/*  originator */
1751         psta->htpriv.agg_enable_bitmap = 0x0;/* reset */
1752         psta->htpriv.candidate_tid_bitmap = 0x0;/* reset */
1753
1754         if (active)
1755                 issue_deauth(padapter, psta->hwaddr, reason);
1756
1757         /* clear cam entry / key */
1758         rtw_clearstakey_cmd(padapter, (u8 *)psta, (u8)(psta->mac_id + 3), true);
1759
1760
1761         spin_lock_bh(&psta->lock);
1762         psta->state &= ~_FW_LINKED;
1763         spin_unlock_bh(&psta->lock);
1764
1765         rtw_indicate_sta_disassoc_event(padapter, psta);
1766
1767         report_del_sta_event(padapter, psta->hwaddr, reason);
1768
1769         beacon_updated = bss_cap_update_on_sta_leave(padapter, psta);
1770
1771         spin_lock_bh(&(pstapriv->sta_hash_lock));
1772         rtw_free_stainfo(padapter, psta);
1773         spin_unlock_bh(&(pstapriv->sta_hash_lock));
1774
1775         return beacon_updated;
1776 }
1777
1778 int rtw_ap_inform_ch_switch(struct adapter *padapter, u8 new_ch, u8 ch_offset)
1779 {
1780         struct list_head *phead, *plist;
1781         struct sta_info *psta = NULL;
1782         struct sta_priv *pstapriv = &padapter->stapriv;
1783         struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
1784         struct mlme_ext_info    *pmlmeinfo = &(pmlmeext->mlmext_info);
1785         u8 bc_addr[ETH_ALEN] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
1786
1787         if ((pmlmeinfo->state&0x03) != WIFI_FW_AP_STATE)
1788                 return 0;
1789
1790         DBG_88E(FUNC_NDEV_FMT" with ch:%u, offset:%u\n",
1791                 FUNC_NDEV_ARG(padapter->pnetdev), new_ch, ch_offset);
1792
1793         spin_lock_bh(&pstapriv->asoc_list_lock);
1794         phead = &pstapriv->asoc_list;
1795         plist = phead->next;
1796
1797         /* for each sta in asoc_queue */
1798         while (phead != plist) {
1799                 psta = container_of(plist, struct sta_info, asoc_list);
1800                 plist = plist->next;
1801
1802                 issue_action_spct_ch_switch(padapter, psta->hwaddr, new_ch, ch_offset);
1803                 psta->expire_to = min_t(unsigned int, pstapriv->expire_to * 2, 5);
1804         }
1805         spin_unlock_bh(&pstapriv->asoc_list_lock);
1806
1807         issue_action_spct_ch_switch(padapter, bc_addr, new_ch, ch_offset);
1808
1809         return 0;
1810 }
1811
1812 int rtw_sta_flush(struct adapter *padapter)
1813 {
1814         struct list_head *phead, *plist;
1815         struct sta_info *psta = NULL;
1816         struct sta_priv *pstapriv = &padapter->stapriv;
1817         struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
1818         struct mlme_ext_info    *pmlmeinfo = &(pmlmeext->mlmext_info);
1819         u8 bc_addr[ETH_ALEN] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
1820
1821         DBG_88E(FUNC_NDEV_FMT"\n", FUNC_NDEV_ARG(padapter->pnetdev));
1822
1823         if ((pmlmeinfo->state&0x03) != WIFI_FW_AP_STATE)
1824                 return 0;
1825
1826         spin_lock_bh(&pstapriv->asoc_list_lock);
1827         phead = &pstapriv->asoc_list;
1828         plist = phead->next;
1829
1830         /* free sta asoc_queue */
1831         while (phead != plist) {
1832                 psta = container_of(plist, struct sta_info, asoc_list);
1833
1834                 plist = plist->next;
1835
1836                 list_del_init(&psta->asoc_list);
1837                 pstapriv->asoc_list_cnt--;
1838
1839                 ap_free_sta(padapter, psta, true, WLAN_REASON_DEAUTH_LEAVING);
1840         }
1841         spin_unlock_bh(&pstapriv->asoc_list_lock);
1842
1843
1844         issue_deauth(padapter, bc_addr, WLAN_REASON_DEAUTH_LEAVING);
1845
1846         associated_clients_update(padapter, true);
1847
1848         return 0;
1849 }
1850
1851 /* called > TSR LEVEL for USB or SDIO Interface*/
1852 void sta_info_update(struct adapter *padapter, struct sta_info *psta)
1853 {
1854         int flags = psta->flags;
1855         struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
1856
1857         /* update wmm cap. */
1858         if (WLAN_STA_WME&flags)
1859                 psta->qos_option = 1;
1860         else
1861                 psta->qos_option = 0;
1862
1863         if (pmlmepriv->qospriv.qos_option == 0)
1864                 psta->qos_option = 0;
1865
1866         /* update 802.11n ht cap. */
1867         if (WLAN_STA_HT&flags) {
1868                 psta->htpriv.ht_option = true;
1869                 psta->qos_option = 1;
1870         } else {
1871                 psta->htpriv.ht_option = false;
1872         }
1873
1874         if (!pmlmepriv->htpriv.ht_option)
1875                 psta->htpriv.ht_option = false;
1876
1877         update_sta_info_apmode(padapter, psta);
1878 }
1879
1880 /* called >= TSR LEVEL for USB or SDIO Interface*/
1881 void ap_sta_info_defer_update(struct adapter *padapter, struct sta_info *psta)
1882 {
1883         if (psta->state & _FW_LINKED) {
1884                 /* add ratid */
1885                 add_RATid(padapter, psta, 0);/* DM_RATR_STA_INIT */
1886         }
1887 }
1888
1889 void start_ap_mode(struct adapter *padapter)
1890 {
1891         int i;
1892         struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
1893         struct sta_priv *pstapriv = &padapter->stapriv;
1894         struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
1895         struct wlan_acl_pool *pacl_list = &pstapriv->acl_list;
1896
1897         pmlmepriv->update_bcn = false;
1898
1899         pmlmeext->bstart_bss = false;
1900
1901         pmlmepriv->num_sta_non_erp = 0;
1902
1903         pmlmepriv->num_sta_no_short_slot_time = 0;
1904
1905         pmlmepriv->num_sta_no_short_preamble = 0;
1906
1907         pmlmepriv->num_sta_ht_no_gf = 0;
1908         pmlmepriv->num_sta_no_ht = 0;
1909         pmlmepriv->num_sta_ht_20mhz = 0;
1910
1911         pmlmepriv->olbc = false;
1912
1913         pmlmepriv->olbc_ht = false;
1914
1915         pmlmepriv->ht_op_mode = 0;
1916
1917         for (i = 0; i < NUM_STA; i++)
1918                 pstapriv->sta_aid[i] = NULL;
1919
1920         pmlmepriv->wps_beacon_ie = NULL;
1921         pmlmepriv->wps_probe_resp_ie = NULL;
1922         pmlmepriv->wps_assoc_resp_ie = NULL;
1923
1924         pmlmepriv->p2p_beacon_ie = NULL;
1925         pmlmepriv->p2p_probe_resp_ie = NULL;
1926
1927         /* for ACL */
1928         INIT_LIST_HEAD(&(pacl_list->acl_node_q.queue));
1929         pacl_list->num = 0;
1930         pacl_list->mode = 0;
1931         for (i = 0; i < NUM_ACL; i++) {
1932                 INIT_LIST_HEAD(&pacl_list->aclnode[i].list);
1933                 pacl_list->aclnode[i].valid = false;
1934         }
1935 }
1936
1937 void stop_ap_mode(struct adapter *padapter)
1938 {
1939         struct list_head *phead, *plist;
1940         struct rtw_wlan_acl_node *paclnode;
1941         struct sta_info *psta = NULL;
1942         struct sta_priv *pstapriv = &padapter->stapriv;
1943         struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
1944         struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
1945         struct wlan_acl_pool *pacl_list = &pstapriv->acl_list;
1946         struct __queue *pacl_node_q = &pacl_list->acl_node_q;
1947
1948         pmlmepriv->update_bcn = false;
1949         pmlmeext->bstart_bss = false;
1950
1951         /* reset and init security priv , this can refine with rtw_reset_securitypriv */
1952         memset((unsigned char *)&padapter->securitypriv, 0, sizeof(struct security_priv));
1953         padapter->securitypriv.ndisauthtype = Ndis802_11AuthModeOpen;
1954         padapter->securitypriv.ndisencryptstatus = Ndis802_11WEPDisabled;
1955
1956         /* for ACL */
1957         spin_lock_bh(&(pacl_node_q->lock));
1958         phead = get_list_head(pacl_node_q);
1959         plist = phead->next;
1960         while (phead != plist) {
1961                 paclnode = container_of(plist, struct rtw_wlan_acl_node, list);
1962                 plist = plist->next;
1963
1964                 if (paclnode->valid) {
1965                         paclnode->valid = false;
1966
1967                         list_del_init(&paclnode->list);
1968
1969                         pacl_list->num--;
1970                 }
1971         }
1972         spin_unlock_bh(&(pacl_node_q->lock));
1973
1974         DBG_88E("%s, free acl_node_queue, num =%d\n", __func__, pacl_list->num);
1975
1976         rtw_sta_flush(padapter);
1977
1978         /* free_assoc_sta_resources */
1979         rtw_free_all_stainfo(padapter);
1980
1981         psta = rtw_get_bcmc_stainfo(padapter);
1982         spin_lock_bh(&(pstapriv->sta_hash_lock));
1983         rtw_free_stainfo(padapter, psta);
1984         spin_unlock_bh(&(pstapriv->sta_hash_lock));
1985
1986         rtw_init_bcmc_stainfo(padapter);
1987
1988         rtw_free_mlme_priv_ie_data(pmlmepriv);
1989 }
1990
1991 #endif /* CONFIG_88EU_AP_MODE */