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