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