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