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