xref: /linux/drivers/staging/rtl8723bs/core/rtw_mlme.c (revision 3a39d672e7f48b8d6b91a09afa4b55352773b4b5)
1 // SPDX-License-Identifier: GPL-2.0
2 /******************************************************************************
3  *
4  * Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved.
5  *
6  ******************************************************************************/
7 #include <linux/etherdevice.h>
8 #include <drv_types.h>
9 #include <hal_btcoex.h>
10 #include <linux/jiffies.h>
11 
rtw_init_mlme_priv(struct adapter * padapter)12 int	rtw_init_mlme_priv(struct adapter *padapter)
13 {
14 	int	i;
15 	u8 *pbuf;
16 	struct wlan_network	*pnetwork;
17 	struct mlme_priv	*pmlmepriv = &padapter->mlmepriv;
18 	int	res = _SUCCESS;
19 
20 	pmlmepriv->nic_hdl = (u8 *)padapter;
21 
22 	pmlmepriv->pscanned = NULL;
23 	pmlmepriv->fw_state = WIFI_STATION_STATE; /*  Must sync with rtw_wdev_alloc() */
24 	pmlmepriv->cur_network.network.infrastructure_mode = Ndis802_11AutoUnknown;
25 	pmlmepriv->scan_mode = SCAN_ACTIVE;/*  1: active, 0: passive. Maybe someday we should rename this varable to "active_mode" (Jeff) */
26 
27 	spin_lock_init(&pmlmepriv->lock);
28 	INIT_LIST_HEAD(&pmlmepriv->free_bss_pool.queue);
29 	spin_lock_init(&pmlmepriv->free_bss_pool.lock);
30 	INIT_LIST_HEAD(&pmlmepriv->scanned_queue.queue);
31 	spin_lock_init(&pmlmepriv->scanned_queue.lock);
32 
33 	memset(&pmlmepriv->assoc_ssid, 0, sizeof(struct ndis_802_11_ssid));
34 
35 	pbuf = vzalloc(array_size(MAX_BSS_CNT, sizeof(struct wlan_network)));
36 
37 	if (!pbuf) {
38 		res = _FAIL;
39 		goto exit;
40 	}
41 	pmlmepriv->free_bss_buf = pbuf;
42 
43 	pnetwork = (struct wlan_network *)pbuf;
44 
45 	for (i = 0; i < MAX_BSS_CNT; i++) {
46 		INIT_LIST_HEAD(&pnetwork->list);
47 
48 		list_add_tail(&pnetwork->list, &pmlmepriv->free_bss_pool.queue);
49 
50 		pnetwork++;
51 	}
52 
53 	/* allocate DMA-able/Non-Page memory for cmd_buf and rsp_buf */
54 
55 	rtw_clear_scan_deny(padapter);
56 
57 	#define RTW_ROAM_SCAN_RESULT_EXP_MS 5000
58 	#define RTW_ROAM_RSSI_DIFF_TH 10
59 	#define RTW_ROAM_SCAN_INTERVAL_MS 10000
60 
61 	pmlmepriv->roam_flags = 0
62 		| RTW_ROAM_ON_EXPIRED
63 		| RTW_ROAM_ON_RESUME
64 		;
65 
66 	pmlmepriv->roam_scanr_exp_ms = RTW_ROAM_SCAN_RESULT_EXP_MS;
67 	pmlmepriv->roam_rssi_diff_th = RTW_ROAM_RSSI_DIFF_TH;
68 	pmlmepriv->roam_scan_int_ms = RTW_ROAM_SCAN_INTERVAL_MS;
69 
70 	rtw_init_mlme_timer(padapter);
71 
72 exit:
73 
74 	return res;
75 }
76 
rtw_free_mlme_ie_data(u8 ** ppie,u32 * plen)77 static void rtw_free_mlme_ie_data(u8 **ppie, u32 *plen)
78 {
79 	if (*ppie) {
80 		kfree(*ppie);
81 		*plen = 0;
82 		*ppie = NULL;
83 	}
84 }
85 
rtw_free_mlme_priv_ie_data(struct mlme_priv * pmlmepriv)86 void rtw_free_mlme_priv_ie_data(struct mlme_priv *pmlmepriv)
87 {
88 	rtw_buf_free(&pmlmepriv->assoc_req, &pmlmepriv->assoc_req_len);
89 	rtw_buf_free(&pmlmepriv->assoc_rsp, &pmlmepriv->assoc_rsp_len);
90 	rtw_free_mlme_ie_data(&pmlmepriv->wps_beacon_ie, &pmlmepriv->wps_beacon_ie_len);
91 	rtw_free_mlme_ie_data(&pmlmepriv->wps_probe_req_ie, &pmlmepriv->wps_probe_req_ie_len);
92 	rtw_free_mlme_ie_data(&pmlmepriv->wps_probe_resp_ie, &pmlmepriv->wps_probe_resp_ie_len);
93 	rtw_free_mlme_ie_data(&pmlmepriv->wps_assoc_resp_ie, &pmlmepriv->wps_assoc_resp_ie_len);
94 
95 	rtw_free_mlme_ie_data(&pmlmepriv->p2p_beacon_ie, &pmlmepriv->p2p_beacon_ie_len);
96 	rtw_free_mlme_ie_data(&pmlmepriv->p2p_probe_req_ie, &pmlmepriv->p2p_probe_req_ie_len);
97 	rtw_free_mlme_ie_data(&pmlmepriv->p2p_probe_resp_ie, &pmlmepriv->p2p_probe_resp_ie_len);
98 	rtw_free_mlme_ie_data(&pmlmepriv->p2p_go_probe_resp_ie, &pmlmepriv->p2p_go_probe_resp_ie_len);
99 	rtw_free_mlme_ie_data(&pmlmepriv->p2p_assoc_req_ie, &pmlmepriv->p2p_assoc_req_ie_len);
100 }
101 
_rtw_free_mlme_priv(struct mlme_priv * pmlmepriv)102 void _rtw_free_mlme_priv(struct mlme_priv *pmlmepriv)
103 {
104 	if (pmlmepriv) {
105 		rtw_free_mlme_priv_ie_data(pmlmepriv);
106 		vfree(pmlmepriv->free_bss_buf);
107 	}
108 }
109 
rtw_alloc_network(struct mlme_priv * pmlmepriv)110 struct	wlan_network *rtw_alloc_network(struct	mlme_priv *pmlmepriv)
111 {
112 	struct	wlan_network	*pnetwork;
113 	struct __queue *free_queue = &pmlmepriv->free_bss_pool;
114 	struct list_head *plist = NULL;
115 
116 	spin_lock_bh(&free_queue->lock);
117 
118 	if (list_empty(&free_queue->queue)) {
119 		pnetwork = NULL;
120 		goto exit;
121 	}
122 	plist = get_next(&(free_queue->queue));
123 
124 	pnetwork = container_of(plist, struct wlan_network, list);
125 
126 	list_del_init(&pnetwork->list);
127 
128 	pnetwork->network_type = 0;
129 	pnetwork->fixed = false;
130 	pnetwork->last_scanned = jiffies;
131 	pnetwork->aid = 0;
132 	pnetwork->join_res = 0;
133 
134 exit:
135 	spin_unlock_bh(&free_queue->lock);
136 
137 	return pnetwork;
138 }
139 
_rtw_free_network(struct mlme_priv * pmlmepriv,struct wlan_network * pnetwork,u8 isfreeall)140 void _rtw_free_network(struct	mlme_priv *pmlmepriv, struct wlan_network *pnetwork, u8 isfreeall)
141 {
142 	unsigned int delta_time;
143 	u32 lifetime = SCANQUEUE_LIFETIME;
144 	struct __queue *free_queue = &(pmlmepriv->free_bss_pool);
145 
146 	if (!pnetwork)
147 		return;
148 
149 	if (pnetwork->fixed)
150 		return;
151 
152 	if ((check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE) == true) ||
153 		(check_fwstate(pmlmepriv, WIFI_ADHOC_STATE) == true))
154 		lifetime = 1;
155 
156 	if (!isfreeall) {
157 		delta_time = jiffies_to_msecs(jiffies - pnetwork->last_scanned);
158 		if (delta_time < lifetime)/*  unit:msec */
159 			return;
160 	}
161 
162 	spin_lock_bh(&free_queue->lock);
163 
164 	list_del_init(&(pnetwork->list));
165 
166 	list_add_tail(&(pnetwork->list), &(free_queue->queue));
167 
168 	spin_unlock_bh(&free_queue->lock);
169 }
170 
_rtw_free_network_nolock(struct mlme_priv * pmlmepriv,struct wlan_network * pnetwork)171 void _rtw_free_network_nolock(struct	mlme_priv *pmlmepriv, struct wlan_network *pnetwork)
172 {
173 
174 	struct __queue *free_queue = &(pmlmepriv->free_bss_pool);
175 
176 	if (!pnetwork)
177 		return;
178 
179 	if (pnetwork->fixed)
180 		return;
181 
182 	list_del_init(&(pnetwork->list));
183 
184 	list_add_tail(&(pnetwork->list), get_list_head(free_queue));
185 }
186 
187 /*
188 	return the wlan_network with the matching addr
189 
190 	Shall be called under atomic context... to avoid possible racing condition...
191 */
_rtw_find_network(struct __queue * scanned_queue,u8 * addr)192 struct wlan_network *_rtw_find_network(struct __queue *scanned_queue, u8 *addr)
193 {
194 	struct list_head	*phead, *plist;
195 	struct	wlan_network *pnetwork = NULL;
196 
197 	if (is_zero_ether_addr(addr)) {
198 		pnetwork = NULL;
199 		goto exit;
200 	}
201 
202 	phead = get_list_head(scanned_queue);
203 	list_for_each(plist, phead) {
204 		pnetwork = list_entry(plist, struct wlan_network, list);
205 
206 		if (!memcmp(addr, pnetwork->network.mac_address, ETH_ALEN))
207 			break;
208 	}
209 
210 	if (plist == phead)
211 		pnetwork = NULL;
212 
213 exit:
214 	return pnetwork;
215 }
216 
rtw_free_network_queue(struct adapter * padapter,u8 isfreeall)217 void rtw_free_network_queue(struct adapter *padapter, u8 isfreeall)
218 {
219 	struct list_head *phead, *plist, *tmp;
220 	struct wlan_network *pnetwork;
221 	struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
222 	struct __queue *scanned_queue = &pmlmepriv->scanned_queue;
223 
224 	spin_lock_bh(&scanned_queue->lock);
225 
226 	phead = get_list_head(scanned_queue);
227 	list_for_each_safe(plist, tmp, phead) {
228 
229 		pnetwork = list_entry(plist, struct wlan_network, list);
230 
231 		_rtw_free_network(pmlmepriv, pnetwork, isfreeall);
232 
233 	}
234 
235 	spin_unlock_bh(&scanned_queue->lock);
236 }
237 
rtw_if_up(struct adapter * padapter)238 signed int rtw_if_up(struct adapter *padapter)
239 {
240 	signed int res;
241 
242 	if (padapter->bDriverStopped || padapter->bSurpriseRemoved ||
243 		(check_fwstate(&padapter->mlmepriv, _FW_LINKED) == false))
244 		res = false;
245 	else
246 		res =  true;
247 
248 	return res;
249 }
250 
rtw_generate_random_ibss(u8 * pibss)251 void rtw_generate_random_ibss(u8 *pibss)
252 {
253 	unsigned long curtime = jiffies;
254 
255 	pibss[0] = 0x02;  /* in ad-hoc mode bit1 must set to 1 */
256 	pibss[1] = 0x11;
257 	pibss[2] = 0x87;
258 	pibss[3] = (u8)(curtime & 0xff) ;/* p[0]; */
259 	pibss[4] = (u8)((curtime>>8) & 0xff) ;/* p[1]; */
260 	pibss[5] = (u8)((curtime>>16) & 0xff) ;/* p[2]; */
261 }
262 
rtw_get_capability_from_ie(u8 * ie)263 u8 *rtw_get_capability_from_ie(u8 *ie)
264 {
265 	return ie + 8 + 2;
266 }
267 
rtw_get_capability(struct wlan_bssid_ex * bss)268 u16 rtw_get_capability(struct wlan_bssid_ex *bss)
269 {
270 	__le16	val;
271 
272 	memcpy((u8 *)&val, rtw_get_capability_from_ie(bss->ies), 2);
273 
274 	return le16_to_cpu(val);
275 }
276 
rtw_get_beacon_interval_from_ie(u8 * ie)277 u8 *rtw_get_beacon_interval_from_ie(u8 *ie)
278 {
279 	return ie + 8;
280 }
281 
rtw_free_mlme_priv(struct mlme_priv * pmlmepriv)282 void rtw_free_mlme_priv(struct mlme_priv *pmlmepriv)
283 {
284 	_rtw_free_mlme_priv(pmlmepriv);
285 }
286 
287 void rtw_free_network_nolock(struct adapter *padapter, struct wlan_network *pnetwork);
rtw_free_network_nolock(struct adapter * padapter,struct wlan_network * pnetwork)288 void rtw_free_network_nolock(struct adapter *padapter, struct wlan_network *pnetwork)
289 {
290 	_rtw_free_network_nolock(&(padapter->mlmepriv), pnetwork);
291 	rtw_cfg80211_unlink_bss(padapter, pnetwork);
292 }
293 
294 /*
295 	return the wlan_network with the matching addr
296 
297 	Shall be called under atomic context... to avoid possible racing condition...
298 */
rtw_find_network(struct __queue * scanned_queue,u8 * addr)299 struct	wlan_network *rtw_find_network(struct __queue *scanned_queue, u8 *addr)
300 {
301 	struct	wlan_network *pnetwork = _rtw_find_network(scanned_queue, addr);
302 
303 	return pnetwork;
304 }
305 
rtw_is_same_ibss(struct adapter * adapter,struct wlan_network * pnetwork)306 int rtw_is_same_ibss(struct adapter *adapter, struct wlan_network *pnetwork)
307 {
308 	int ret = true;
309 	struct security_priv *psecuritypriv = &adapter->securitypriv;
310 
311 	if ((psecuritypriv->dot11PrivacyAlgrthm != _NO_PRIVACY_) &&
312 		    (pnetwork->network.privacy == 0))
313 		ret = false;
314 	else if ((psecuritypriv->dot11PrivacyAlgrthm == _NO_PRIVACY_) &&
315 		 (pnetwork->network.privacy == 1))
316 		ret = false;
317 	else
318 		ret = true;
319 
320 	return ret;
321 
322 }
323 
is_same_ess(struct wlan_bssid_ex * a,struct wlan_bssid_ex * b)324 inline int is_same_ess(struct wlan_bssid_ex *a, struct wlan_bssid_ex *b)
325 {
326 	return (a->ssid.ssid_length == b->ssid.ssid_length)
327 		&&  !memcmp(a->ssid.ssid, b->ssid.ssid, a->ssid.ssid_length);
328 }
329 
is_same_network(struct wlan_bssid_ex * src,struct wlan_bssid_ex * dst,u8 feature)330 int is_same_network(struct wlan_bssid_ex *src, struct wlan_bssid_ex *dst, u8 feature)
331 {
332 	u16 s_cap, d_cap;
333 	__le16 tmps, tmpd;
334 
335 	if (rtw_bug_check(dst, src, &s_cap, &d_cap) == false)
336 		return false;
337 
338 	memcpy((u8 *)&tmps, rtw_get_capability_from_ie(src->ies), 2);
339 	memcpy((u8 *)&tmpd, rtw_get_capability_from_ie(dst->ies), 2);
340 
341 	s_cap = le16_to_cpu(tmps);
342 	d_cap = le16_to_cpu(tmpd);
343 
344 	return (src->ssid.ssid_length == dst->ssid.ssid_length) &&
345 			((!memcmp(src->mac_address, dst->mac_address, ETH_ALEN))) &&
346 			((!memcmp(src->ssid.ssid, dst->ssid.ssid, src->ssid.ssid_length))) &&
347 			((s_cap & WLAN_CAPABILITY_IBSS) ==
348 			(d_cap & WLAN_CAPABILITY_IBSS)) &&
349 			((s_cap & WLAN_CAPABILITY_ESS) ==
350 			(d_cap & WLAN_CAPABILITY_ESS));
351 
352 }
353 
_rtw_find_same_network(struct __queue * scanned_queue,struct wlan_network * network)354 struct wlan_network *_rtw_find_same_network(struct __queue *scanned_queue, struct wlan_network *network)
355 {
356 	struct list_head *phead, *plist;
357 	struct wlan_network *found = NULL;
358 
359 	phead = get_list_head(scanned_queue);
360 	list_for_each(plist, phead) {
361 		found = list_entry(plist, struct wlan_network, list);
362 
363 		if (is_same_network(&network->network, &found->network, 0))
364 			break;
365 	}
366 
367 	if (plist == phead)
368 		found = NULL;
369 
370 	return found;
371 }
372 
rtw_get_oldest_wlan_network(struct __queue * scanned_queue)373 struct	wlan_network	*rtw_get_oldest_wlan_network(struct __queue *scanned_queue)
374 {
375 	struct list_head	*plist, *phead;
376 
377 	struct	wlan_network	*pwlan = NULL;
378 	struct	wlan_network	*oldest = NULL;
379 
380 	phead = get_list_head(scanned_queue);
381 
382 	list_for_each(plist, phead) {
383 
384 		pwlan = list_entry(plist, struct wlan_network, list);
385 
386 		if (!pwlan->fixed) {
387 			if (!oldest || time_after(oldest->last_scanned, pwlan->last_scanned))
388 				oldest = pwlan;
389 		}
390 	}
391 	return oldest;
392 
393 }
394 
update_network(struct wlan_bssid_ex * dst,struct wlan_bssid_ex * src,struct adapter * padapter,bool update_ie)395 void update_network(struct wlan_bssid_ex *dst, struct wlan_bssid_ex *src,
396 	struct adapter *padapter, bool update_ie)
397 {
398 	long rssi_ori = dst->rssi;
399 
400 	u8 sq_smp = src->phy_info.signal_quality;
401 
402 	u8 ss_final;
403 	u8 sq_final;
404 	long rssi_final;
405 
406 	/* The rule below is 1/5 for sample value, 4/5 for history value */
407 	if (check_fwstate(&padapter->mlmepriv, _FW_LINKED) && is_same_network(&(padapter->mlmepriv.cur_network.network), src, 0)) {
408 		/* Take the recvpriv's value for the connected AP*/
409 		ss_final = padapter->recvpriv.signal_strength;
410 		sq_final = padapter->recvpriv.signal_qual;
411 		/* the rssi value here is undecorated, and will be used for antenna diversity */
412 		if (sq_smp != 101) /* from the right channel */
413 			rssi_final = (src->rssi+dst->rssi*4)/5;
414 		else
415 			rssi_final = rssi_ori;
416 	} else {
417 		if (sq_smp != 101) { /* from the right channel */
418 			ss_final = ((u32)(src->phy_info.signal_strength)+(u32)(dst->phy_info.signal_strength)*4)/5;
419 			sq_final = ((u32)(src->phy_info.signal_quality)+(u32)(dst->phy_info.signal_quality)*4)/5;
420 			rssi_final = (src->rssi+dst->rssi*4)/5;
421 		} else {
422 			/* bss info not receiving from the right channel, use the original RX signal infos */
423 			ss_final = dst->phy_info.signal_strength;
424 			sq_final = dst->phy_info.signal_quality;
425 			rssi_final = dst->rssi;
426 		}
427 
428 	}
429 
430 	if (update_ie) {
431 		dst->reserved[0] = src->reserved[0];
432 		dst->reserved[1] = src->reserved[1];
433 		memcpy((u8 *)dst, (u8 *)src, get_wlan_bssid_ex_sz(src));
434 	}
435 
436 	dst->phy_info.signal_strength = ss_final;
437 	dst->phy_info.signal_quality = sq_final;
438 	dst->rssi = rssi_final;
439 }
440 
update_current_network(struct adapter * adapter,struct wlan_bssid_ex * pnetwork)441 static void update_current_network(struct adapter *adapter, struct wlan_bssid_ex *pnetwork)
442 {
443 	struct	mlme_priv *pmlmepriv = &(adapter->mlmepriv);
444 
445 	rtw_bug_check(&(pmlmepriv->cur_network.network),
446 		&(pmlmepriv->cur_network.network),
447 		&(pmlmepriv->cur_network.network),
448 		&(pmlmepriv->cur_network.network));
449 
450 	if ((check_fwstate(pmlmepriv, _FW_LINKED) == true) && (is_same_network(&(pmlmepriv->cur_network.network), pnetwork, 0))) {
451 		update_network(&(pmlmepriv->cur_network.network), pnetwork, adapter, true);
452 		rtw_update_protection(adapter, (pmlmepriv->cur_network.network.ies) + sizeof(struct ndis_802_11_fix_ie),
453 								pmlmepriv->cur_network.network.ie_length);
454 	}
455 }
456 
457 /*
458 Caller must hold pmlmepriv->lock first.
459 */
rtw_update_scanned_network(struct adapter * adapter,struct wlan_bssid_ex * target)460 void rtw_update_scanned_network(struct adapter *adapter, struct wlan_bssid_ex *target)
461 {
462 	struct list_head	*plist, *phead;
463 	u32 bssid_ex_sz;
464 	struct mlme_priv *pmlmepriv = &(adapter->mlmepriv);
465 	struct __queue	*queue	= &(pmlmepriv->scanned_queue);
466 	struct wlan_network	*pnetwork = NULL;
467 	struct wlan_network	*oldest = NULL;
468 	int target_find = 0;
469 	u8 feature = 0;
470 
471 	spin_lock_bh(&queue->lock);
472 	phead = get_list_head(queue);
473 	list_for_each(plist, phead) {
474 		pnetwork = list_entry(plist, struct wlan_network, list);
475 
476 		rtw_bug_check(pnetwork, pnetwork, pnetwork, pnetwork);
477 
478 		if (is_same_network(&(pnetwork->network), target, feature)) {
479 			target_find = 1;
480 			break;
481 		}
482 
483 		if (rtw_roam_flags(adapter)) {
484 			/* TODO: don't select network in the same ess as oldest if it's new enough*/
485 		}
486 
487 		if (!oldest || time_after(oldest->last_scanned, pnetwork->last_scanned))
488 			oldest = pnetwork;
489 
490 	}
491 
492 	/* If we didn't find a match, then get a new network slot to initialize
493 	 * with this beacon's information */
494 	if (!target_find) {
495 		if (list_empty(&pmlmepriv->free_bss_pool.queue)) {
496 			/* If there are no more slots, expire the oldest */
497 			/* list_del_init(&oldest->list); */
498 			pnetwork = oldest;
499 			if (!pnetwork)
500 				goto exit;
501 
502 			memcpy(&(pnetwork->network), target,  get_wlan_bssid_ex_sz(target));
503 			/*  variable initialize */
504 			pnetwork->fixed = false;
505 			pnetwork->last_scanned = jiffies;
506 
507 			pnetwork->network_type = 0;
508 			pnetwork->aid = 0;
509 			pnetwork->join_res = 0;
510 
511 			/* bss info not receiving from the right channel */
512 			if (pnetwork->network.phy_info.signal_quality == 101)
513 				pnetwork->network.phy_info.signal_quality = 0;
514 		} else {
515 			/* Otherwise just pull from the free list */
516 
517 			pnetwork = rtw_alloc_network(pmlmepriv); /*  will update scan_time */
518 
519 			if (!pnetwork)
520 				goto exit;
521 
522 			bssid_ex_sz = get_wlan_bssid_ex_sz(target);
523 			target->length = bssid_ex_sz;
524 			memcpy(&(pnetwork->network), target, bssid_ex_sz);
525 
526 			pnetwork->last_scanned = jiffies;
527 
528 			/* bss info not receiving from the right channel */
529 			if (pnetwork->network.phy_info.signal_quality == 101)
530 				pnetwork->network.phy_info.signal_quality = 0;
531 
532 			list_add_tail(&(pnetwork->list), &(queue->queue));
533 
534 		}
535 	} else {
536 		/* we have an entry and we are going to update it. But this entry may
537 		 * be already expired. In this case we do the same as we found a new
538 		 * net and call the new_net handler
539 		 */
540 		bool update_ie = true;
541 
542 		pnetwork->last_scanned = jiffies;
543 
544 		/* target.reserved[0]== 1, means that scanned network is a bcn frame. */
545 		if (pnetwork->network.ie_length > target->ie_length && target->reserved[0] == 1)
546 			update_ie = false;
547 
548 		/*  probe resp(3) > beacon(1) > probe req(2) */
549 		if (target->reserved[0] != 2 &&
550 		    target->reserved[0] >= pnetwork->network.reserved[0]) {
551 			update_ie = true;
552 		} else {
553 			update_ie = false;
554 		}
555 
556 		update_network(&(pnetwork->network), target, adapter, update_ie);
557 	}
558 
559 exit:
560 	spin_unlock_bh(&queue->lock);
561 }
562 
563 void rtw_add_network(struct adapter *adapter, struct wlan_bssid_ex *pnetwork);
rtw_add_network(struct adapter * adapter,struct wlan_bssid_ex * pnetwork)564 void rtw_add_network(struct adapter *adapter, struct wlan_bssid_ex *pnetwork)
565 {
566 	update_current_network(adapter, pnetwork);
567 	rtw_update_scanned_network(adapter, pnetwork);
568 }
569 
570 /* select the desired network based on the capability of the (i)bss. */
571 /*  check items: (1) security */
572 /* 			   (2) network_type */
573 /* 			   (3) WMM */
574 /* 			   (4) HT */
575 /*                      (5) others */
576 int rtw_is_desired_network(struct adapter *adapter, struct wlan_network *pnetwork);
rtw_is_desired_network(struct adapter * adapter,struct wlan_network * pnetwork)577 int rtw_is_desired_network(struct adapter *adapter, struct wlan_network *pnetwork)
578 {
579 	struct security_priv *psecuritypriv = &adapter->securitypriv;
580 	struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
581 	u32 desired_encmode;
582 	u32 privacy;
583 	uint wps_ielen;
584 	int bselected = true;
585 
586 	desired_encmode = psecuritypriv->ndisencryptstatus;
587 	privacy = pnetwork->network.privacy;
588 
589 	if (check_fwstate(pmlmepriv, WIFI_UNDER_WPS)) {
590 		if (rtw_get_wps_ie(pnetwork->network.ies+_FIXED_IE_LENGTH_, pnetwork->network.ie_length-_FIXED_IE_LENGTH_, NULL, &wps_ielen))
591 			return true;
592 		else
593 			return false;
594 
595 	}
596 	if (adapter->registrypriv.wifi_spec == 1) { /* for  correct flow of 8021X  to do.... */
597 		u8 *p = NULL;
598 		uint ie_len = 0;
599 
600 		if ((desired_encmode == Ndis802_11EncryptionDisabled) && (privacy != 0))
601 			bselected = false;
602 
603 		if (psecuritypriv->ndisauthtype == Ndis802_11AuthModeWPA2PSK) {
604 			p = rtw_get_ie(pnetwork->network.ies + _BEACON_IE_OFFSET_, WLAN_EID_RSN, &ie_len, (pnetwork->network.ie_length - _BEACON_IE_OFFSET_));
605 			if (p && ie_len > 0)
606 				bselected = true;
607 			else
608 				bselected = false;
609 		}
610 	}
611 
612 	if ((desired_encmode != Ndis802_11EncryptionDisabled) && (privacy == 0))
613 		bselected = false;
614 
615 	if (check_fwstate(pmlmepriv, WIFI_ADHOC_STATE) == true) {
616 		if (pnetwork->network.infrastructure_mode != pmlmepriv->cur_network.network.infrastructure_mode)
617 			bselected = false;
618 	}
619 
620 	return bselected;
621 }
622 
623 /* TODO: Perry : For Power Management */
rtw_atimdone_event_callback(struct adapter * adapter,u8 * pbuf)624 void rtw_atimdone_event_callback(struct adapter	*adapter, u8 *pbuf)
625 {
626 }
627 
rtw_survey_event_callback(struct adapter * adapter,u8 * pbuf)628 void rtw_survey_event_callback(struct adapter	*adapter, u8 *pbuf)
629 {
630 	u32 len;
631 	struct wlan_bssid_ex *pnetwork;
632 	struct	mlme_priv *pmlmepriv = &(adapter->mlmepriv);
633 
634 	pnetwork = (struct wlan_bssid_ex *)pbuf;
635 
636 	len = get_wlan_bssid_ex_sz(pnetwork);
637 	if (len > (sizeof(struct wlan_bssid_ex)))
638 		return;
639 
640 	spin_lock_bh(&pmlmepriv->lock);
641 
642 	/*  update IBSS_network 's timestamp */
643 	if ((check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE)) == true) {
644 		if (!memcmp(&(pmlmepriv->cur_network.network.mac_address), pnetwork->mac_address, ETH_ALEN)) {
645 			struct wlan_network *ibss_wlan = NULL;
646 
647 			memcpy(pmlmepriv->cur_network.network.ies, pnetwork->ies, 8);
648 			spin_lock_bh(&(pmlmepriv->scanned_queue.lock));
649 			ibss_wlan = rtw_find_network(&pmlmepriv->scanned_queue,  pnetwork->mac_address);
650 			if (ibss_wlan) {
651 				memcpy(ibss_wlan->network.ies, pnetwork->ies, 8);
652 				spin_unlock_bh(&(pmlmepriv->scanned_queue.lock));
653 				goto exit;
654 			}
655 			spin_unlock_bh(&(pmlmepriv->scanned_queue.lock));
656 		}
657 	}
658 
659 	/*  lock pmlmepriv->lock when you accessing network_q */
660 	if ((check_fwstate(pmlmepriv, _FW_UNDER_LINKING)) == false) {
661 		if (pnetwork->ssid.ssid[0] == 0)
662 			pnetwork->ssid.ssid_length = 0;
663 		rtw_add_network(adapter, pnetwork);
664 	}
665 
666 exit:
667 
668 	spin_unlock_bh(&pmlmepriv->lock);
669 }
670 
rtw_surveydone_event_callback(struct adapter * adapter,u8 * pbuf)671 void rtw_surveydone_event_callback(struct adapter	*adapter, u8 *pbuf)
672 {
673 	struct	mlme_priv *pmlmepriv = &(adapter->mlmepriv);
674 
675 	spin_lock_bh(&pmlmepriv->lock);
676 	if (pmlmepriv->wps_probe_req_ie) {
677 		pmlmepriv->wps_probe_req_ie_len = 0;
678 		kfree(pmlmepriv->wps_probe_req_ie);
679 		pmlmepriv->wps_probe_req_ie = NULL;
680 	}
681 
682 	if (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY)) {
683 		spin_unlock_bh(&pmlmepriv->lock);
684 		del_timer_sync(&pmlmepriv->scan_to_timer);
685 		spin_lock_bh(&pmlmepriv->lock);
686 		_clr_fwstate_(pmlmepriv, _FW_UNDER_SURVEY);
687 	}
688 
689 	rtw_set_signal_stat_timer(&adapter->recvpriv);
690 
691 	if (pmlmepriv->to_join) {
692 		if ((check_fwstate(pmlmepriv, WIFI_ADHOC_STATE) == true)) {
693 			if (check_fwstate(pmlmepriv, _FW_LINKED) == false) {
694 				set_fwstate(pmlmepriv, _FW_UNDER_LINKING);
695 
696 				if (rtw_select_and_join_from_scanned_queue(pmlmepriv) == _SUCCESS) {
697 					_set_timer(&pmlmepriv->assoc_timer, MAX_JOIN_TIMEOUT);
698 				} else {
699 					u8 ret = _SUCCESS;
700 					struct wlan_bssid_ex    *pdev_network = &(adapter->registrypriv.dev_network);
701 					u8 *pibss = adapter->registrypriv.dev_network.mac_address;
702 
703 					/* pmlmepriv->fw_state ^= _FW_UNDER_SURVEY;because don't set assoc_timer */
704 					_clr_fwstate_(pmlmepriv, _FW_UNDER_SURVEY);
705 
706 					memcpy(&pdev_network->ssid, &pmlmepriv->assoc_ssid, sizeof(struct ndis_802_11_ssid));
707 
708 					rtw_update_registrypriv_dev_network(adapter);
709 					rtw_generate_random_ibss(pibss);
710 
711 					pmlmepriv->fw_state = WIFI_ADHOC_MASTER_STATE;
712 
713 					pmlmepriv->to_join = false;
714 
715 					ret = rtw_createbss_cmd(adapter);
716 					if (ret != _SUCCESS)
717 						goto unlock;
718 				}
719 			}
720 		} else {
721 			int s_ret;
722 
723 			set_fwstate(pmlmepriv, _FW_UNDER_LINKING);
724 			pmlmepriv->to_join = false;
725 			s_ret = rtw_select_and_join_from_scanned_queue(pmlmepriv);
726 			if (s_ret == _SUCCESS) {
727 				_set_timer(&pmlmepriv->assoc_timer, MAX_JOIN_TIMEOUT);
728 			} else if (s_ret == 2) {/* there is no need to wait for join */
729 				_clr_fwstate_(pmlmepriv, _FW_UNDER_LINKING);
730 				rtw_indicate_connect(adapter);
731 			} else {
732 				if (rtw_to_roam(adapter) != 0) {
733 					if (rtw_dec_to_roam(adapter) == 0
734 						|| _SUCCESS != rtw_sitesurvey_cmd(adapter, &pmlmepriv->assoc_ssid, 1, NULL, 0)
735 					) {
736 						rtw_set_to_roam(adapter, 0);
737 						rtw_free_assoc_resources(adapter, 1);
738 						rtw_indicate_disconnect(adapter);
739 					} else {
740 						pmlmepriv->to_join = true;
741 					}
742 				} else
743 					rtw_indicate_disconnect(adapter);
744 
745 				_clr_fwstate_(pmlmepriv, _FW_UNDER_LINKING);
746 			}
747 		}
748 	} else {
749 		if (rtw_chk_roam_flags(adapter, RTW_ROAM_ACTIVE)) {
750 			if (check_fwstate(pmlmepriv, WIFI_STATION_STATE)
751 				&& check_fwstate(pmlmepriv, _FW_LINKED)) {
752 				if (rtw_select_roaming_candidate(pmlmepriv) == _SUCCESS) {
753 					receive_disconnect(adapter, pmlmepriv->cur_network.network.mac_address
754 						, WLAN_REASON_ACTIVE_ROAM);
755 				}
756 			}
757 		}
758 	}
759 
760 unlock:
761 	spin_unlock_bh(&pmlmepriv->lock);
762 
763 	rtw_os_xmit_schedule(adapter);
764 
765 	rtw_cfg80211_surveydone_event_callback(adapter);
766 
767 	rtw_indicate_scan_done(adapter, false);
768 }
769 
rtw_dummy_event_callback(struct adapter * adapter,u8 * pbuf)770 void rtw_dummy_event_callback(struct adapter *adapter, u8 *pbuf)
771 {
772 }
773 
rtw_fwdbg_event_callback(struct adapter * adapter,u8 * pbuf)774 void rtw_fwdbg_event_callback(struct adapter *adapter, u8 *pbuf)
775 {
776 }
777 
free_scanqueue(struct mlme_priv * pmlmepriv)778 static void free_scanqueue(struct	mlme_priv *pmlmepriv)
779 {
780 	struct __queue *free_queue = &pmlmepriv->free_bss_pool;
781 	struct __queue *scan_queue = &pmlmepriv->scanned_queue;
782 	struct list_head	*plist, *phead, *ptemp;
783 
784 	spin_lock_bh(&scan_queue->lock);
785 	spin_lock_bh(&free_queue->lock);
786 
787 	phead = get_list_head(scan_queue);
788 	plist = get_next(phead);
789 
790 	while (plist != phead) {
791 		ptemp = get_next(plist);
792 		list_del_init(plist);
793 		list_add_tail(plist, &free_queue->queue);
794 		plist = ptemp;
795 	}
796 
797 	spin_unlock_bh(&free_queue->lock);
798 	spin_unlock_bh(&scan_queue->lock);
799 }
800 
rtw_reset_rx_info(struct debug_priv * pdbgpriv)801 static void rtw_reset_rx_info(struct debug_priv *pdbgpriv)
802 {
803 	pdbgpriv->dbg_rx_ampdu_drop_count = 0;
804 	pdbgpriv->dbg_rx_ampdu_forced_indicate_count = 0;
805 	pdbgpriv->dbg_rx_ampdu_loss_count = 0;
806 	pdbgpriv->dbg_rx_dup_mgt_frame_drop_count = 0;
807 	pdbgpriv->dbg_rx_ampdu_window_shift_cnt = 0;
808 }
809 
find_network(struct adapter * adapter)810 static void find_network(struct adapter *adapter)
811 {
812 	struct wlan_network *pwlan = NULL;
813 	struct	mlme_priv *pmlmepriv = &adapter->mlmepriv;
814 	struct wlan_network *tgt_network = &pmlmepriv->cur_network;
815 
816 	pwlan = rtw_find_network(&pmlmepriv->scanned_queue, tgt_network->network.mac_address);
817 	if (pwlan)
818 		pwlan->fixed = false;
819 
820 	if (check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE) &&
821 	    (adapter->stapriv.asoc_sta_count == 1))
822 		rtw_free_network_nolock(adapter, pwlan);
823 }
824 
825 /*
826 *rtw_free_assoc_resources: the caller has to lock pmlmepriv->lock
827 */
rtw_free_assoc_resources(struct adapter * adapter,int lock_scanned_queue)828 void rtw_free_assoc_resources(struct adapter *adapter, int lock_scanned_queue)
829 {
830 	struct	mlme_priv *pmlmepriv = &adapter->mlmepriv;
831 	struct wlan_network *tgt_network = &pmlmepriv->cur_network;
832 	struct dvobj_priv *psdpriv = adapter->dvobj;
833 	struct debug_priv *pdbgpriv = &psdpriv->drv_dbg;
834 
835 	if (check_fwstate(pmlmepriv, WIFI_STATION_STATE|WIFI_AP_STATE)) {
836 		struct sta_info *psta;
837 
838 		psta = rtw_get_stainfo(&adapter->stapriv, tgt_network->network.mac_address);
839 		rtw_free_stainfo(adapter,  psta);
840 	}
841 
842 	if (check_fwstate(pmlmepriv, WIFI_ADHOC_STATE|WIFI_ADHOC_MASTER_STATE|WIFI_AP_STATE)) {
843 		struct sta_info *psta;
844 
845 		rtw_free_all_stainfo(adapter);
846 
847 		psta = rtw_get_bcmc_stainfo(adapter);
848 		rtw_free_stainfo(adapter, psta);
849 
850 		rtw_init_bcmc_stainfo(adapter);
851 	}
852 
853 	find_network(adapter);
854 
855 	if (lock_scanned_queue)
856 		adapter->securitypriv.key_mask = 0;
857 
858 	rtw_reset_rx_info(pdbgpriv);
859 }
860 
861 /*
862 *rtw_indicate_connect: the caller has to lock pmlmepriv->lock
863 */
rtw_indicate_connect(struct adapter * padapter)864 void rtw_indicate_connect(struct adapter *padapter)
865 {
866 	struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
867 
868 	pmlmepriv->to_join = false;
869 
870 	if (!check_fwstate(&padapter->mlmepriv, _FW_LINKED)) {
871 
872 		set_fwstate(pmlmepriv, _FW_LINKED);
873 
874 		rtw_os_indicate_connect(padapter);
875 	}
876 
877 	rtw_set_to_roam(padapter, 0);
878 	rtw_set_scan_deny(padapter, 3000);
879 
880 }
881 
882 /*
883 *rtw_indicate_disconnect: the caller has to lock pmlmepriv->lock
884 */
rtw_indicate_disconnect(struct adapter * padapter)885 void rtw_indicate_disconnect(struct adapter *padapter)
886 {
887 	struct	mlme_priv *pmlmepriv = &padapter->mlmepriv;
888 
889 	_clr_fwstate_(pmlmepriv, _FW_UNDER_LINKING|WIFI_UNDER_WPS);
890 
891 	if (rtw_to_roam(padapter) > 0)
892 		_clr_fwstate_(pmlmepriv, _FW_LINKED);
893 
894 	if (check_fwstate(&padapter->mlmepriv, _FW_LINKED)
895 		|| (rtw_to_roam(padapter) <= 0)
896 	) {
897 		rtw_os_indicate_disconnect(padapter);
898 
899 		/* set ips_deny_time to avoid enter IPS before LPS leave */
900 		rtw_set_ips_deny(padapter, 3000);
901 
902 		_clr_fwstate_(pmlmepriv, _FW_LINKED);
903 
904 		rtw_clear_scan_deny(padapter);
905 	}
906 
907 	rtw_lps_ctrl_wk_cmd(padapter, LPS_CTRL_DISCONNECT, 1);
908 }
909 
rtw_indicate_scan_done(struct adapter * padapter,bool aborted)910 inline void rtw_indicate_scan_done(struct adapter *padapter, bool aborted)
911 {
912 	rtw_os_indicate_scan_done(padapter, aborted);
913 
914 	if (is_primary_adapter(padapter) &&
915 	    (!adapter_to_pwrctl(padapter)->bInSuspend) &&
916 	    (!check_fwstate(&padapter->mlmepriv,
917 			    WIFI_ASOC_STATE|WIFI_UNDER_LINKING))) {
918 		rtw_set_ips_deny(padapter, 0);
919 		_set_timer(&padapter->mlmepriv.dynamic_chk_timer, 1);
920 	}
921 }
922 
rtw_scan_abort(struct adapter * adapter)923 void rtw_scan_abort(struct adapter *adapter)
924 {
925 	unsigned long start;
926 	struct mlme_priv *pmlmepriv = &(adapter->mlmepriv);
927 	struct mlme_ext_priv *pmlmeext = &(adapter->mlmeextpriv);
928 
929 	start = jiffies;
930 	pmlmeext->scan_abort = true;
931 	while (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY)
932 		&& jiffies_to_msecs(start) <= 200) {
933 
934 		if (adapter->bDriverStopped || adapter->bSurpriseRemoved)
935 			break;
936 
937 		msleep(20);
938 	}
939 
940 	if (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY))
941 		rtw_indicate_scan_done(adapter, true);
942 
943 	pmlmeext->scan_abort = false;
944 }
945 
rtw_joinbss_update_stainfo(struct adapter * padapter,struct wlan_network * pnetwork)946 static struct sta_info *rtw_joinbss_update_stainfo(struct adapter *padapter, struct wlan_network *pnetwork)
947 {
948 	int i;
949 	struct sta_info *bmc_sta, *psta = NULL;
950 	struct recv_reorder_ctrl *preorder_ctrl;
951 	struct sta_priv *pstapriv = &padapter->stapriv;
952 	struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
953 
954 	psta = rtw_get_stainfo(pstapriv, pnetwork->network.mac_address);
955 	if (!psta)
956 		psta = rtw_alloc_stainfo(pstapriv, pnetwork->network.mac_address);
957 
958 	if (psta) { /* update ptarget_sta */
959 
960 		psta->aid  = pnetwork->join_res;
961 
962 		update_sta_info(padapter, psta);
963 
964 		/* update station supportRate */
965 		psta->bssratelen = rtw_get_rateset_len(pnetwork->network.supported_rates);
966 		memcpy(psta->bssrateset, pnetwork->network.supported_rates, psta->bssratelen);
967 		rtw_hal_update_sta_rate_mask(padapter, psta);
968 
969 		psta->wireless_mode = pmlmeext->cur_wireless_mode;
970 		psta->raid = networktype_to_raid_ex(padapter, psta);
971 
972 		/* sta mode */
973 		rtw_hal_set_odm_var(padapter, HAL_ODM_STA_INFO, psta, true);
974 
975 		/* security related */
976 		if (padapter->securitypriv.dot11AuthAlgrthm == dot11AuthAlgrthm_8021X) {
977 			padapter->securitypriv.binstallGrpkey = false;
978 			padapter->securitypriv.busetkipkey = false;
979 			padapter->securitypriv.bgrpkey_handshake = false;
980 
981 			psta->ieee8021x_blocked = true;
982 			psta->dot118021XPrivacy = padapter->securitypriv.dot11PrivacyAlgrthm;
983 
984 			memset((u8 *)&psta->dot118021x_UncstKey, 0, sizeof(union Keytype));
985 
986 			memset((u8 *)&psta->dot11tkiprxmickey, 0, sizeof(union Keytype));
987 			memset((u8 *)&psta->dot11tkiptxmickey, 0, sizeof(union Keytype));
988 
989 			memset((u8 *)&psta->dot11txpn, 0, sizeof(union pn48));
990 			psta->dot11txpn.val = psta->dot11txpn.val + 1;
991 			memset((u8 *)&psta->dot11wtxpn, 0, sizeof(union pn48));
992 			memset((u8 *)&psta->dot11rxpn, 0, sizeof(union pn48));
993 		}
994 
995 		/* When doing the WPS, the wps_ie_len won't equal to 0 */
996 		/* And the Wi-Fi driver shouldn't allow the data packet to be transmitted. */
997 		if (padapter->securitypriv.wps_ie_len != 0) {
998 			psta->ieee8021x_blocked = true;
999 			padapter->securitypriv.wps_ie_len = 0;
1000 		}
1001 
1002 		/* for A-MPDU Rx reordering buffer control for bmc_sta & sta_info */
1003 		/* if A-MPDU Rx is enabled, resetting  rx_ordering_ctrl wstart_b(indicate_seq) to default value = 0xffff */
1004 		/* todo: check if AP can send A-MPDU packets */
1005 		for (i = 0; i < 16 ; i++) {
1006 			preorder_ctrl = &psta->recvreorder_ctrl[i];
1007 			preorder_ctrl->enable = false;
1008 			preorder_ctrl->indicate_seq = 0xffff;
1009 			preorder_ctrl->wend_b = 0xffff;
1010 			preorder_ctrl->wsize_b = 64;/* max_ampdu_sz;ex. 32(kbytes) -> wsize_b =32 */
1011 		}
1012 
1013 		bmc_sta = rtw_get_bcmc_stainfo(padapter);
1014 		if (bmc_sta) {
1015 			for (i = 0; i < 16 ; i++) {
1016 				preorder_ctrl = &bmc_sta->recvreorder_ctrl[i];
1017 				preorder_ctrl->enable = false;
1018 				preorder_ctrl->indicate_seq = 0xffff;
1019 				preorder_ctrl->wend_b = 0xffff;
1020 				preorder_ctrl->wsize_b = 64;/* max_ampdu_sz;ex. 32(kbytes) -> wsize_b =32 */
1021 			}
1022 		}
1023 	}
1024 
1025 	return psta;
1026 
1027 }
1028 
1029 /* pnetwork : returns from rtw_joinbss_event_callback */
1030 /* ptarget_wlan: found from scanned_queue */
rtw_joinbss_update_network(struct adapter * padapter,struct wlan_network * ptarget_wlan,struct wlan_network * pnetwork)1031 static void rtw_joinbss_update_network(struct adapter *padapter, struct wlan_network *ptarget_wlan, struct wlan_network  *pnetwork)
1032 {
1033 	struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
1034 	struct wlan_network  *cur_network = &(pmlmepriv->cur_network);
1035 
1036 	/*  why not use ptarget_wlan?? */
1037 	memcpy(&cur_network->network, &pnetwork->network, pnetwork->network.length);
1038 	/*  some ies in pnetwork is wrong, so we should use ptarget_wlan ies */
1039 	cur_network->network.ie_length = ptarget_wlan->network.ie_length;
1040 	memcpy(&cur_network->network.ies[0], &ptarget_wlan->network.ies[0], MAX_IE_SZ);
1041 
1042 	cur_network->aid = pnetwork->join_res;
1043 
1044 	rtw_set_signal_stat_timer(&padapter->recvpriv);
1045 
1046 	padapter->recvpriv.signal_strength = ptarget_wlan->network.phy_info.signal_strength;
1047 	padapter->recvpriv.signal_qual = ptarget_wlan->network.phy_info.signal_quality;
1048 	/* the ptarget_wlan->network.rssi is raw data, we use ptarget_wlan->network.phy_info.signal_strength instead (has scaled) */
1049 	padapter->recvpriv.rssi = translate_percentage_to_dbm(ptarget_wlan->network.phy_info.signal_strength);
1050 
1051 	rtw_set_signal_stat_timer(&padapter->recvpriv);
1052 
1053 	/* update fw_state will clr _FW_UNDER_LINKING here indirectly */
1054 	switch (pnetwork->network.infrastructure_mode) {
1055 	case Ndis802_11Infrastructure:
1056 
1057 			if (pmlmepriv->fw_state&WIFI_UNDER_WPS)
1058 				pmlmepriv->fw_state = WIFI_STATION_STATE|WIFI_UNDER_WPS;
1059 			else
1060 				pmlmepriv->fw_state = WIFI_STATION_STATE;
1061 
1062 			break;
1063 	case Ndis802_11IBSS:
1064 			pmlmepriv->fw_state = WIFI_ADHOC_STATE;
1065 			break;
1066 	default:
1067 			pmlmepriv->fw_state = WIFI_NULL_STATE;
1068 			break;
1069 	}
1070 
1071 	rtw_update_protection(padapter, (cur_network->network.ies) + sizeof(struct ndis_802_11_fix_ie),
1072 									(cur_network->network.ie_length));
1073 
1074 	rtw_update_ht_cap(padapter, cur_network->network.ies, cur_network->network.ie_length, (u8) cur_network->network.configuration.ds_config);
1075 }
1076 
1077 /* Notes: the function could be > passive_level (the same context as Rx tasklet) */
1078 /* pnetwork : returns from rtw_joinbss_event_callback */
1079 /* ptarget_wlan: found from scanned_queue */
1080 /* if join_res > 0, for (fw_state ==WIFI_STATION_STATE), we check if  "ptarget_sta" & "ptarget_wlan" exist. */
1081 /* if join_res > 0, for (fw_state ==WIFI_ADHOC_STATE), we only check if "ptarget_wlan" exist. */
1082 /* if join_res > 0, update "cur_network->network" from "pnetwork->network" if (ptarget_wlan != NULL). */
1083 /*  */
1084 /* define REJOIN */
rtw_joinbss_event_prehandle(struct adapter * adapter,u8 * pbuf)1085 void rtw_joinbss_event_prehandle(struct adapter *adapter, u8 *pbuf)
1086 {
1087 	static u8 __maybe_unused retry;
1088 	struct sta_info *ptarget_sta = NULL, *pcur_sta = NULL;
1089 	struct	sta_priv *pstapriv = &adapter->stapriv;
1090 	struct	mlme_priv *pmlmepriv = &(adapter->mlmepriv);
1091 	struct wlan_network	*pnetwork	= (struct wlan_network *)pbuf;
1092 	struct wlan_network	*cur_network = &(pmlmepriv->cur_network);
1093 	struct wlan_network	*pcur_wlan = NULL, *ptarget_wlan = NULL;
1094 	unsigned int		the_same_macaddr = false;
1095 
1096 	rtw_get_encrypt_decrypt_from_registrypriv(adapter);
1097 
1098 	the_same_macaddr = !memcmp(pnetwork->network.mac_address, cur_network->network.mac_address, ETH_ALEN);
1099 
1100 	pnetwork->network.length = get_wlan_bssid_ex_sz(&pnetwork->network);
1101 	if (pnetwork->network.length > sizeof(struct wlan_bssid_ex))
1102 		return;
1103 
1104 	spin_lock_bh(&pmlmepriv->lock);
1105 
1106 	pmlmepriv->LinkDetectInfo.TrafficTransitionCount = 0;
1107 	pmlmepriv->LinkDetectInfo.LowPowerTransitionCount = 0;
1108 
1109 	if (pnetwork->join_res > 0) {
1110 		spin_lock_bh(&(pmlmepriv->scanned_queue.lock));
1111 		retry = 0;
1112 		if (check_fwstate(pmlmepriv, _FW_UNDER_LINKING)) {
1113 			/* s1. find ptarget_wlan */
1114 			if (check_fwstate(pmlmepriv, _FW_LINKED)) {
1115 				if (the_same_macaddr) {
1116 					ptarget_wlan = rtw_find_network(&pmlmepriv->scanned_queue, cur_network->network.mac_address);
1117 				} else {
1118 					pcur_wlan = rtw_find_network(&pmlmepriv->scanned_queue, cur_network->network.mac_address);
1119 					if (pcur_wlan)
1120 						pcur_wlan->fixed = false;
1121 
1122 					pcur_sta = rtw_get_stainfo(pstapriv, cur_network->network.mac_address);
1123 					if (pcur_sta)
1124 						rtw_free_stainfo(adapter,  pcur_sta);
1125 
1126 					ptarget_wlan = rtw_find_network(&pmlmepriv->scanned_queue, pnetwork->network.mac_address);
1127 					if (check_fwstate(pmlmepriv, WIFI_STATION_STATE) == true) {
1128 						if (ptarget_wlan)
1129 							ptarget_wlan->fixed = true;
1130 					}
1131 				}
1132 
1133 			} else {
1134 				ptarget_wlan = _rtw_find_same_network(&pmlmepriv->scanned_queue, pnetwork);
1135 				if (check_fwstate(pmlmepriv, WIFI_STATION_STATE) == true) {
1136 					if (ptarget_wlan)
1137 						ptarget_wlan->fixed = true;
1138 				}
1139 			}
1140 
1141 			/* s2. update cur_network */
1142 			if (ptarget_wlan) {
1143 				rtw_joinbss_update_network(adapter, ptarget_wlan, pnetwork);
1144 			} else {
1145 				netdev_dbg(adapter->pnetdev,
1146 					   "Can't find ptarget_wlan when joinbss_event callback\n");
1147 				spin_unlock_bh(&(pmlmepriv->scanned_queue.lock));
1148 				goto ignore_joinbss_callback;
1149 			}
1150 
1151 			/* s3. find ptarget_sta & update ptarget_sta after update cur_network only for station mode */
1152 			if (check_fwstate(pmlmepriv, WIFI_STATION_STATE) == true) {
1153 				ptarget_sta = rtw_joinbss_update_stainfo(adapter, pnetwork);
1154 				if (!ptarget_sta) {
1155 					spin_unlock_bh(&(pmlmepriv->scanned_queue.lock));
1156 					goto ignore_joinbss_callback;
1157 				}
1158 			}
1159 
1160 			/* s4. indicate connect */
1161 			if (check_fwstate(pmlmepriv, WIFI_STATION_STATE) == true) {
1162 				pmlmepriv->cur_network_scanned = ptarget_wlan;
1163 				rtw_indicate_connect(adapter);
1164 			}
1165 
1166 			spin_unlock_bh(&pmlmepriv->scanned_queue.lock);
1167 
1168 			spin_unlock_bh(&pmlmepriv->lock);
1169 			/* s5. Cancel assoc_timer */
1170 			del_timer_sync(&pmlmepriv->assoc_timer);
1171 			spin_lock_bh(&pmlmepriv->lock);
1172 		} else {
1173 			spin_unlock_bh(&(pmlmepriv->scanned_queue.lock));
1174 		}
1175 	} else if (pnetwork->join_res == -4) {
1176 		rtw_reset_securitypriv(adapter);
1177 		_set_timer(&pmlmepriv->assoc_timer, 1);
1178 
1179 		if ((check_fwstate(pmlmepriv, _FW_UNDER_LINKING)) == true)
1180 			_clr_fwstate_(pmlmepriv, _FW_UNDER_LINKING);
1181 
1182 	} else {/* if join_res < 0 (join fails), then try again */
1183 
1184 		#ifdef REJOIN
1185 		res = _FAIL;
1186 		if (retry < 2)
1187 			res = rtw_select_and_join_from_scanned_queue(pmlmepriv);
1188 
1189 		if (res == _SUCCESS) {
1190 			/* extend time of assoc_timer */
1191 			_set_timer(&pmlmepriv->assoc_timer, MAX_JOIN_TIMEOUT);
1192 			retry++;
1193 		} else if (res == 2) {/* there is no need to wait for join */
1194 			_clr_fwstate_(pmlmepriv, _FW_UNDER_LINKING);
1195 			rtw_indicate_connect(adapter);
1196 		} else {
1197 		#endif
1198 
1199 			_set_timer(&pmlmepriv->assoc_timer, 1);
1200 			_clr_fwstate_(pmlmepriv, _FW_UNDER_LINKING);
1201 
1202 		#ifdef REJOIN
1203 			retry = 0;
1204 		}
1205 		#endif
1206 	}
1207 
1208 ignore_joinbss_callback:
1209 
1210 	spin_unlock_bh(&pmlmepriv->lock);
1211 }
1212 
rtw_joinbss_event_callback(struct adapter * adapter,u8 * pbuf)1213 void rtw_joinbss_event_callback(struct adapter *adapter, u8 *pbuf)
1214 {
1215 	struct wlan_network	*pnetwork	= (struct wlan_network *)pbuf;
1216 
1217 	mlmeext_joinbss_event_callback(adapter, pnetwork->join_res);
1218 
1219 	rtw_os_xmit_schedule(adapter);
1220 }
1221 
1222 /* FOR STA, AP , AD-HOC mode */
rtw_sta_media_status_rpt(struct adapter * adapter,struct sta_info * psta,u32 mstatus)1223 void rtw_sta_media_status_rpt(struct adapter *adapter, struct sta_info *psta, u32 mstatus)
1224 {
1225 	u16 media_status_rpt;
1226 
1227 	if (!psta)
1228 		return;
1229 
1230 	media_status_rpt = (u16)((psta->mac_id<<8)|mstatus); /*   MACID|OPMODE:1 connect */
1231 	rtw_hal_set_hwreg(adapter, HW_VAR_H2C_MEDIA_STATUS_RPT, (u8 *)&media_status_rpt);
1232 }
1233 
rtw_stassoc_event_callback(struct adapter * adapter,u8 * pbuf)1234 void rtw_stassoc_event_callback(struct adapter *adapter, u8 *pbuf)
1235 {
1236 	struct sta_info *psta;
1237 	struct mlme_priv *pmlmepriv = &(adapter->mlmepriv);
1238 	struct stassoc_event	*pstassoc	= (struct stassoc_event *)pbuf;
1239 	struct wlan_network	*cur_network = &(pmlmepriv->cur_network);
1240 	struct wlan_network	*ptarget_wlan = NULL;
1241 
1242 	if (rtw_access_ctrl(adapter, pstassoc->macaddr) == false)
1243 		return;
1244 
1245 	if (check_fwstate(pmlmepriv, WIFI_AP_STATE)) {
1246 		psta = rtw_get_stainfo(&adapter->stapriv, pstassoc->macaddr);
1247 		if (psta) {
1248 			u8 *passoc_req = NULL;
1249 			u32 assoc_req_len = 0;
1250 
1251 			rtw_sta_media_status_rpt(adapter, psta, 1);
1252 
1253 			ap_sta_info_defer_update(adapter, psta);
1254 
1255 			/* report to upper layer */
1256 			spin_lock_bh(&psta->lock);
1257 			if (psta->passoc_req && psta->assoc_req_len > 0) {
1258 				passoc_req = rtw_zmalloc(psta->assoc_req_len);
1259 				if (passoc_req) {
1260 					assoc_req_len = psta->assoc_req_len;
1261 					memcpy(passoc_req, psta->passoc_req, assoc_req_len);
1262 
1263 					kfree(psta->passoc_req);
1264 					psta->passoc_req = NULL;
1265 					psta->assoc_req_len = 0;
1266 				}
1267 			}
1268 			spin_unlock_bh(&psta->lock);
1269 
1270 			if (passoc_req && assoc_req_len > 0) {
1271 				rtw_cfg80211_indicate_sta_assoc(adapter, passoc_req, assoc_req_len);
1272 
1273 				kfree(passoc_req);
1274 			}
1275 		}
1276 		return;
1277 	}
1278 
1279 	/* for AD-HOC mode */
1280 	psta = rtw_get_stainfo(&adapter->stapriv, pstassoc->macaddr);
1281 	if (psta) {
1282 		/* the sta have been in sta_info_queue => do nothing */
1283 
1284 		return; /* between drv has received this event before and  fw have not yet to set key to CAM_ENTRY) */
1285 	}
1286 
1287 	psta = rtw_alloc_stainfo(&adapter->stapriv, pstassoc->macaddr);
1288 	if (!psta)
1289 		return;
1290 
1291 	/* to do : init sta_info variable */
1292 	psta->qos_option = 0;
1293 	psta->mac_id = (uint)pstassoc->cam_id;
1294 
1295 	/* for ad-hoc mode */
1296 	rtw_hal_set_odm_var(adapter, HAL_ODM_STA_INFO, psta, true);
1297 
1298 	rtw_sta_media_status_rpt(adapter, psta, 1);
1299 
1300 	if (adapter->securitypriv.dot11AuthAlgrthm == dot11AuthAlgrthm_8021X)
1301 		psta->dot118021XPrivacy = adapter->securitypriv.dot11PrivacyAlgrthm;
1302 
1303 	psta->ieee8021x_blocked = false;
1304 
1305 	spin_lock_bh(&pmlmepriv->lock);
1306 
1307 	if ((check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE) == true) ||
1308 		(check_fwstate(pmlmepriv, WIFI_ADHOC_STATE) == true)) {
1309 		if (adapter->stapriv.asoc_sta_count == 2) {
1310 			spin_lock_bh(&(pmlmepriv->scanned_queue.lock));
1311 			ptarget_wlan = rtw_find_network(&pmlmepriv->scanned_queue, cur_network->network.mac_address);
1312 			pmlmepriv->cur_network_scanned = ptarget_wlan;
1313 			if (ptarget_wlan)
1314 				ptarget_wlan->fixed = true;
1315 			spin_unlock_bh(&(pmlmepriv->scanned_queue.lock));
1316 			/*  a sta + bc/mc_stainfo (not Ibss_stainfo) */
1317 			rtw_indicate_connect(adapter);
1318 		}
1319 	}
1320 
1321 	spin_unlock_bh(&pmlmepriv->lock);
1322 
1323 	mlmeext_sta_add_event_callback(adapter, psta);
1324 }
1325 
rtw_stadel_event_callback(struct adapter * adapter,u8 * pbuf)1326 void rtw_stadel_event_callback(struct adapter *adapter, u8 *pbuf)
1327 {
1328 	int mac_id = (-1);
1329 	struct sta_info *psta;
1330 	struct wlan_network *pwlan = NULL;
1331 	struct wlan_bssid_ex    *pdev_network = NULL;
1332 	u8 *pibss = NULL;
1333 	struct	mlme_priv *pmlmepriv = &(adapter->mlmepriv);
1334 	struct	stadel_event *pstadel	= (struct stadel_event *)pbuf;
1335 	struct wlan_network *tgt_network = &(pmlmepriv->cur_network);
1336 	struct mlme_ext_priv *pmlmeext = &adapter->mlmeextpriv;
1337 	struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
1338 
1339 	psta = rtw_get_stainfo(&adapter->stapriv, pstadel->macaddr);
1340 	if (psta)
1341 		mac_id = psta->mac_id;
1342 	else
1343 		mac_id = pstadel->mac_id;
1344 
1345 	if (mac_id >= 0) {
1346 		u16 media_status;
1347 
1348 		media_status = (mac_id<<8)|0; /*   MACID|OPMODE:0 means disconnect */
1349 		/* for STA, AP, ADHOC mode, report disconnect stauts to FW */
1350 		rtw_hal_set_hwreg(adapter, HW_VAR_H2C_MEDIA_STATUS_RPT, (u8 *)&media_status);
1351 	}
1352 
1353 	/* if (check_fwstate(pmlmepriv, WIFI_AP_STATE)) */
1354 	if ((pmlmeinfo->state&0x03) == WIFI_FW_AP_STATE)
1355 		return;
1356 
1357 	mlmeext_sta_del_event_callback(adapter);
1358 
1359 	spin_lock_bh(&pmlmepriv->lock);
1360 
1361 	if (check_fwstate(pmlmepriv, WIFI_STATION_STATE)) {
1362 		u16 reason = *((unsigned short *)(pstadel->rsvd));
1363 		bool roam = false;
1364 		struct wlan_network *roam_target = NULL;
1365 
1366 		if (adapter->registrypriv.wifi_spec == 1) {
1367 			roam = false;
1368 		} else if (reason == WLAN_REASON_EXPIRATION_CHK && rtw_chk_roam_flags(adapter, RTW_ROAM_ON_EXPIRED)) {
1369 			roam = true;
1370 		} else if (reason == WLAN_REASON_ACTIVE_ROAM && rtw_chk_roam_flags(adapter, RTW_ROAM_ACTIVE)) {
1371 			roam = true;
1372 			roam_target = pmlmepriv->roam_network;
1373 		}
1374 
1375 		if (roam) {
1376 			if (rtw_to_roam(adapter) > 0)
1377 				rtw_dec_to_roam(adapter); /* this stadel_event is caused by roaming, decrease to_roam */
1378 			else if (rtw_to_roam(adapter) == 0)
1379 				rtw_set_to_roam(adapter, adapter->registrypriv.max_roaming_times);
1380 		} else {
1381 			rtw_set_to_roam(adapter, 0);
1382 		}
1383 
1384 		rtw_free_uc_swdec_pending_queue(adapter);
1385 
1386 		rtw_free_assoc_resources(adapter, 1);
1387 		rtw_indicate_disconnect(adapter);
1388 
1389 		spin_lock_bh(&(pmlmepriv->scanned_queue.lock));
1390 		/*  remove the network entry in scanned_queue */
1391 		pwlan = rtw_find_network(&pmlmepriv->scanned_queue, tgt_network->network.mac_address);
1392 		if (pwlan) {
1393 			pwlan->fixed = false;
1394 			rtw_free_network_nolock(adapter, pwlan);
1395 		}
1396 		spin_unlock_bh(&(pmlmepriv->scanned_queue.lock));
1397 
1398 		_rtw_roaming(adapter, roam_target);
1399 	}
1400 
1401 	if (check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE) ||
1402 	      check_fwstate(pmlmepriv, WIFI_ADHOC_STATE)) {
1403 
1404 		rtw_free_stainfo(adapter,  psta);
1405 
1406 		if (adapter->stapriv.asoc_sta_count == 1) {/* a sta + bc/mc_stainfo (not Ibss_stainfo) */
1407 			u8 ret = _SUCCESS;
1408 			spin_lock_bh(&(pmlmepriv->scanned_queue.lock));
1409 			/* free old ibss network */
1410 			pwlan = rtw_find_network(&pmlmepriv->scanned_queue, tgt_network->network.mac_address);
1411 			if (pwlan) {
1412 				pwlan->fixed = false;
1413 				rtw_free_network_nolock(adapter, pwlan);
1414 			}
1415 			spin_unlock_bh(&(pmlmepriv->scanned_queue.lock));
1416 			/* re-create ibss */
1417 			pdev_network = &(adapter->registrypriv.dev_network);
1418 			pibss = adapter->registrypriv.dev_network.mac_address;
1419 
1420 			memcpy(pdev_network, &tgt_network->network, get_wlan_bssid_ex_sz(&tgt_network->network));
1421 
1422 			memcpy(&pdev_network->ssid, &pmlmepriv->assoc_ssid, sizeof(struct ndis_802_11_ssid));
1423 
1424 			rtw_update_registrypriv_dev_network(adapter);
1425 
1426 			rtw_generate_random_ibss(pibss);
1427 
1428 			if (check_fwstate(pmlmepriv, WIFI_ADHOC_STATE)) {
1429 				set_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE);
1430 				_clr_fwstate_(pmlmepriv, WIFI_ADHOC_STATE);
1431 			}
1432 
1433 			ret = rtw_createbss_cmd(adapter);
1434 			if (ret != _SUCCESS)
1435 				goto unlock;
1436 		}
1437 
1438 	}
1439 
1440 unlock:
1441 	spin_unlock_bh(&pmlmepriv->lock);
1442 }
1443 
rtw_cpwm_event_callback(struct adapter * padapter,u8 * pbuf)1444 void rtw_cpwm_event_callback(struct adapter *padapter, u8 *pbuf)
1445 {
1446 	struct reportpwrstate_parm *preportpwrstate;
1447 
1448 	preportpwrstate = (struct reportpwrstate_parm *)pbuf;
1449 	preportpwrstate->state |= (u8)(adapter_to_pwrctl(padapter)->cpwm_tog + 0x80);
1450 	cpwm_int_hdl(padapter, preportpwrstate);
1451 }
1452 
rtw_wmm_event_callback(struct adapter * padapter,u8 * pbuf)1453 void rtw_wmm_event_callback(struct adapter *padapter, u8 *pbuf)
1454 {
1455 	WMMOnAssocRsp(padapter);
1456 }
1457 
1458 /*
1459 * _rtw_join_timeout_handler - Timeout/failure handler for CMD JoinBss
1460 * @adapter: pointer to struct adapter structure
1461 */
_rtw_join_timeout_handler(struct timer_list * t)1462 void _rtw_join_timeout_handler(struct timer_list *t)
1463 {
1464 	struct adapter *adapter = from_timer(adapter, t,
1465 						  mlmepriv.assoc_timer);
1466 	struct	mlme_priv *pmlmepriv = &adapter->mlmepriv;
1467 
1468 	if (adapter->bDriverStopped || adapter->bSurpriseRemoved)
1469 		return;
1470 
1471 	spin_lock_bh(&pmlmepriv->lock);
1472 
1473 	if (rtw_to_roam(adapter) > 0) { /* join timeout caused by roaming */
1474 		while (1) {
1475 			rtw_dec_to_roam(adapter);
1476 			if (rtw_to_roam(adapter) != 0) { /* try another */
1477 				int do_join_r;
1478 
1479 				do_join_r = rtw_do_join(adapter);
1480 				if (do_join_r != _SUCCESS)
1481 					continue;
1482 
1483 				break;
1484 			} else {
1485 				rtw_indicate_disconnect(adapter);
1486 				break;
1487 			}
1488 		}
1489 
1490 	} else {
1491 		rtw_indicate_disconnect(adapter);
1492 		free_scanqueue(pmlmepriv);/*  */
1493 
1494 		/* indicate disconnect for the case that join_timeout and check_fwstate != FW_LINKED */
1495 		rtw_cfg80211_indicate_disconnect(adapter);
1496 
1497 	}
1498 
1499 	spin_unlock_bh(&pmlmepriv->lock);
1500 }
1501 
1502 /*
1503 * rtw_scan_timeout_handler - Timeout/Failure handler for CMD SiteSurvey
1504 * @adapter: pointer to struct adapter structure
1505 */
rtw_scan_timeout_handler(struct timer_list * t)1506 void rtw_scan_timeout_handler(struct timer_list *t)
1507 {
1508 	struct adapter *adapter = from_timer(adapter, t,
1509 						  mlmepriv.scan_to_timer);
1510 	struct	mlme_priv *pmlmepriv = &adapter->mlmepriv;
1511 
1512 	spin_lock_bh(&pmlmepriv->lock);
1513 
1514 	_clr_fwstate_(pmlmepriv, _FW_UNDER_SURVEY);
1515 
1516 	spin_unlock_bh(&pmlmepriv->lock);
1517 
1518 	rtw_indicate_scan_done(adapter, true);
1519 }
1520 
rtw_mlme_reset_auto_scan_int(struct adapter * adapter)1521 void rtw_mlme_reset_auto_scan_int(struct adapter *adapter)
1522 {
1523 	struct mlme_priv *mlme = &adapter->mlmepriv;
1524 	struct mlme_ext_priv *pmlmeext = &adapter->mlmeextpriv;
1525 	struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
1526 
1527 	if (pmlmeinfo->VHT_enable) /* disable auto scan when connect to 11AC AP */
1528 		mlme->auto_scan_int_ms = 0;
1529 	else if (adapter->registrypriv.wifi_spec && is_client_associated_to_ap(adapter) == true)
1530 		mlme->auto_scan_int_ms = 60*1000;
1531 	else if (rtw_chk_roam_flags(adapter, RTW_ROAM_ACTIVE)) {
1532 		if (check_fwstate(mlme, WIFI_STATION_STATE) && check_fwstate(mlme, _FW_LINKED))
1533 			mlme->auto_scan_int_ms = mlme->roam_scan_int_ms;
1534 	} else
1535 		mlme->auto_scan_int_ms = 0; /* disabled */
1536 }
1537 
rtw_auto_scan_handler(struct adapter * padapter)1538 static void rtw_auto_scan_handler(struct adapter *padapter)
1539 {
1540 	struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
1541 
1542 	rtw_mlme_reset_auto_scan_int(padapter);
1543 
1544 	if (pmlmepriv->auto_scan_int_ms != 0
1545 		&& jiffies_to_msecs(jiffies - pmlmepriv->scan_start_time) > pmlmepriv->auto_scan_int_ms) {
1546 
1547 		if (!padapter->registrypriv.wifi_spec) {
1548 			if (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY | _FW_UNDER_LINKING) == true)
1549 				goto exit;
1550 
1551 			if (pmlmepriv->LinkDetectInfo.bBusyTraffic)
1552 				goto exit;
1553 		}
1554 
1555 		rtw_set_802_11_bssid_list_scan(padapter, NULL, 0);
1556 	}
1557 
1558 exit:
1559 	return;
1560 }
1561 
rtw_dynamic_check_timer_handler(struct adapter * adapter)1562 void rtw_dynamic_check_timer_handler(struct adapter *adapter)
1563 {
1564 	if (!adapter)
1565 		return;
1566 
1567 	if (!adapter->hw_init_completed)
1568 		return;
1569 
1570 	if (adapter->bDriverStopped || adapter->bSurpriseRemoved)
1571 		return;
1572 
1573 	if (adapter->net_closed)
1574 		return;
1575 
1576 	if ((adapter_to_pwrctl(adapter)->fw_current_in_ps_mode)
1577 		&& !(hal_btcoex_IsBtControlLps(adapter))
1578 		) {
1579 		u8 bEnterPS;
1580 
1581 		linked_status_chk(adapter);
1582 
1583 		bEnterPS = traffic_status_watchdog(adapter, 1);
1584 		if (bEnterPS) {
1585 			/* rtw_lps_ctrl_wk_cmd(adapter, LPS_CTRL_ENTER, 1); */
1586 			rtw_hal_dm_watchdog_in_lps(adapter);
1587 		} else {
1588 			/* call rtw_lps_ctrl_wk_cmd(padapter, LPS_CTRL_LEAVE, 1) in traffic_status_watchdog() */
1589 		}
1590 
1591 	} else {
1592 		if (is_primary_adapter(adapter))
1593 			rtw_dynamic_chk_wk_cmd(adapter);
1594 	}
1595 
1596 	/* auto site survey */
1597 	rtw_auto_scan_handler(adapter);
1598 }
1599 
rtw_is_scan_deny(struct adapter * adapter)1600 inline bool rtw_is_scan_deny(struct adapter *adapter)
1601 {
1602 	struct mlme_priv *mlmepriv = &adapter->mlmepriv;
1603 
1604 	return (atomic_read(&mlmepriv->set_scan_deny) != 0) ? true : false;
1605 }
1606 
rtw_clear_scan_deny(struct adapter * adapter)1607 inline void rtw_clear_scan_deny(struct adapter *adapter)
1608 {
1609 	struct mlme_priv *mlmepriv = &adapter->mlmepriv;
1610 
1611 	atomic_set(&mlmepriv->set_scan_deny, 0);
1612 }
1613 
rtw_set_scan_deny(struct adapter * adapter,u32 ms)1614 void rtw_set_scan_deny(struct adapter *adapter, u32 ms)
1615 {
1616 	struct mlme_priv *mlmepriv = &adapter->mlmepriv;
1617 
1618 	atomic_set(&mlmepriv->set_scan_deny, 1);
1619 	_set_timer(&mlmepriv->set_scan_deny_timer, ms);
1620 }
1621 
1622 /*
1623 * Select a new roaming candidate from the original @param candidate and @param competitor
1624 * @return true: candidate is updated
1625 * @return false: candidate is not updated
1626 */
rtw_check_roaming_candidate(struct mlme_priv * mlme,struct wlan_network ** candidate,struct wlan_network * competitor)1627 static int rtw_check_roaming_candidate(struct mlme_priv *mlme
1628 	, struct wlan_network **candidate, struct wlan_network *competitor)
1629 {
1630 	int updated = false;
1631 	struct adapter *adapter = container_of(mlme, struct adapter, mlmepriv);
1632 
1633 	if (is_same_ess(&competitor->network, &mlme->cur_network.network) == false)
1634 		goto exit;
1635 
1636 	if (rtw_is_desired_network(adapter, competitor) == false)
1637 		goto exit;
1638 
1639 	/* got specific addr to roam */
1640 	if (!is_zero_mac_addr(mlme->roam_tgt_addr)) {
1641 		if (!memcmp(mlme->roam_tgt_addr, competitor->network.mac_address, ETH_ALEN))
1642 			goto update;
1643 		else
1644 			goto exit;
1645 	}
1646 	if (jiffies_to_msecs(jiffies - competitor->last_scanned) >= mlme->roam_scanr_exp_ms)
1647 		goto exit;
1648 
1649 	if (competitor->network.rssi - mlme->cur_network_scanned->network.rssi < mlme->roam_rssi_diff_th)
1650 		goto exit;
1651 
1652 	if (*candidate && (*candidate)->network.rssi >= competitor->network.rssi)
1653 		goto exit;
1654 
1655 update:
1656 	*candidate = competitor;
1657 	updated = true;
1658 
1659 exit:
1660 	return updated;
1661 }
1662 
rtw_select_roaming_candidate(struct mlme_priv * mlme)1663 int rtw_select_roaming_candidate(struct mlme_priv *mlme)
1664 {
1665 	int ret = _FAIL;
1666 	struct list_head	*phead;
1667 	struct __queue	*queue	= &(mlme->scanned_queue);
1668 	struct	wlan_network	*pnetwork = NULL;
1669 	struct	wlan_network	*candidate = NULL;
1670 
1671 	if (!mlme->cur_network_scanned) {
1672 		rtw_warn_on(1);
1673 		return ret;
1674 	}
1675 
1676 	spin_lock_bh(&(mlme->scanned_queue.lock));
1677 	phead = get_list_head(queue);
1678 
1679 	list_for_each(mlme->pscanned, phead) {
1680 
1681 		pnetwork = list_entry(mlme->pscanned, struct wlan_network,
1682 				      list);
1683 
1684 		rtw_check_roaming_candidate(mlme, &candidate, pnetwork);
1685 
1686 	}
1687 
1688 	if (!candidate) {
1689 		ret = _FAIL;
1690 		goto exit;
1691 	} else {
1692 		mlme->roam_network = candidate;
1693 
1694 		if (!memcmp(candidate->network.mac_address, mlme->roam_tgt_addr, ETH_ALEN))
1695 			eth_zero_addr(mlme->roam_tgt_addr);
1696 	}
1697 
1698 	ret = _SUCCESS;
1699 exit:
1700 	spin_unlock_bh(&(mlme->scanned_queue.lock));
1701 
1702 	return ret;
1703 }
1704 
1705 /*
1706 * Select a new join candidate from the original @param candidate and @param competitor
1707 * @return true: candidate is updated
1708 * @return false: candidate is not updated
1709 */
rtw_check_join_candidate(struct mlme_priv * mlme,struct wlan_network ** candidate,struct wlan_network * competitor)1710 static int rtw_check_join_candidate(struct mlme_priv *mlme
1711 	, struct wlan_network **candidate, struct wlan_network *competitor)
1712 {
1713 	int updated = false;
1714 	struct adapter *adapter = container_of(mlme, struct adapter, mlmepriv);
1715 
1716 	/* check bssid, if needed */
1717 	if (mlme->assoc_by_bssid) {
1718 		if (memcmp(competitor->network.mac_address, mlme->assoc_bssid, ETH_ALEN))
1719 			goto exit;
1720 	}
1721 
1722 	/* check ssid, if needed */
1723 	if (mlme->assoc_ssid.ssid[0] && mlme->assoc_ssid.ssid_length) {
1724 		if (competitor->network.ssid.ssid_length != mlme->assoc_ssid.ssid_length
1725 			|| memcmp(competitor->network.ssid.ssid, mlme->assoc_ssid.ssid, mlme->assoc_ssid.ssid_length)
1726 		)
1727 			goto exit;
1728 	}
1729 
1730 	if (rtw_is_desired_network(adapter, competitor)  == false)
1731 		goto exit;
1732 
1733 	if (rtw_to_roam(adapter) > 0) {
1734 		if (jiffies_to_msecs(jiffies - competitor->last_scanned) >= mlme->roam_scanr_exp_ms
1735 			|| is_same_ess(&competitor->network, &mlme->cur_network.network) == false
1736 		)
1737 			goto exit;
1738 	}
1739 
1740 	if (!*candidate || (*candidate)->network.rssi < competitor->network.rssi) {
1741 		*candidate = competitor;
1742 		updated = true;
1743 	}
1744 
1745 exit:
1746 	return updated;
1747 }
1748 
1749 /*
1750 Calling context:
1751 The caller of the sub-routine will be in critical section...
1752 The caller must hold the following spinlock
1753 pmlmepriv->lock
1754 */
1755 
rtw_select_and_join_from_scanned_queue(struct mlme_priv * pmlmepriv)1756 int rtw_select_and_join_from_scanned_queue(struct mlme_priv *pmlmepriv)
1757 {
1758 	int ret;
1759 	struct list_head	*phead;
1760 	struct adapter *adapter;
1761 	struct __queue	*queue	= &(pmlmepriv->scanned_queue);
1762 	struct	wlan_network	*pnetwork = NULL;
1763 	struct	wlan_network	*candidate = NULL;
1764 
1765 	adapter = (struct adapter *)pmlmepriv->nic_hdl;
1766 
1767 	spin_lock_bh(&(pmlmepriv->scanned_queue.lock));
1768 
1769 	if (pmlmepriv->roam_network) {
1770 		candidate = pmlmepriv->roam_network;
1771 		pmlmepriv->roam_network = NULL;
1772 		goto candidate_exist;
1773 	}
1774 
1775 	phead = get_list_head(queue);
1776 	list_for_each(pmlmepriv->pscanned, phead) {
1777 
1778 		pnetwork = list_entry(pmlmepriv->pscanned,
1779 				      struct wlan_network, list);
1780 
1781 		rtw_check_join_candidate(pmlmepriv, &candidate, pnetwork);
1782 
1783 	}
1784 
1785 	if (!candidate) {
1786 		ret = _FAIL;
1787 		goto exit;
1788 	} else {
1789 		goto candidate_exist;
1790 	}
1791 
1792 candidate_exist:
1793 
1794 	/*  check for situation of  _FW_LINKED */
1795 	if (check_fwstate(pmlmepriv, _FW_LINKED) == true) {
1796 		rtw_disassoc_cmd(adapter, 0, true);
1797 		rtw_indicate_disconnect(adapter);
1798 		rtw_free_assoc_resources(adapter, 0);
1799 	}
1800 
1801 	set_fwstate(pmlmepriv, _FW_UNDER_LINKING);
1802 	ret = rtw_joinbss_cmd(adapter, candidate);
1803 
1804 exit:
1805 	spin_unlock_bh(&(pmlmepriv->scanned_queue.lock));
1806 	return ret;
1807 }
1808 
rtw_set_auth(struct adapter * adapter,struct security_priv * psecuritypriv)1809 signed int rtw_set_auth(struct adapter *adapter, struct security_priv *psecuritypriv)
1810 {
1811 	struct	cmd_obj *pcmd;
1812 	struct	setauth_parm *psetauthparm;
1813 	struct	cmd_priv *pcmdpriv = &(adapter->cmdpriv);
1814 	signed int		res = _SUCCESS;
1815 
1816 	pcmd = rtw_zmalloc(sizeof(struct cmd_obj));
1817 	if (!pcmd) {
1818 		res = _FAIL;  /* try again */
1819 		goto exit;
1820 	}
1821 
1822 	psetauthparm = rtw_zmalloc(sizeof(struct setauth_parm));
1823 	if (!psetauthparm) {
1824 		kfree(pcmd);
1825 		res = _FAIL;
1826 		goto exit;
1827 	}
1828 
1829 	psetauthparm->mode = (unsigned char)psecuritypriv->dot11AuthAlgrthm;
1830 
1831 	pcmd->cmdcode = _SetAuth_CMD_;
1832 	pcmd->parmbuf = (unsigned char *)psetauthparm;
1833 	pcmd->cmdsz =  (sizeof(struct setauth_parm));
1834 	pcmd->rsp = NULL;
1835 	pcmd->rspsz = 0;
1836 
1837 	INIT_LIST_HEAD(&pcmd->list);
1838 
1839 	res = rtw_enqueue_cmd(pcmdpriv, pcmd);
1840 
1841 exit:
1842 	return res;
1843 }
1844 
rtw_set_key(struct adapter * adapter,struct security_priv * psecuritypriv,signed int keyid,u8 set_tx,bool enqueue)1845 signed int rtw_set_key(struct adapter *adapter, struct security_priv *psecuritypriv, signed int keyid, u8 set_tx, bool enqueue)
1846 {
1847 	u8 keylen;
1848 	struct cmd_obj		*pcmd;
1849 	struct setkey_parm	*psetkeyparm;
1850 	struct cmd_priv 	*pcmdpriv = &(adapter->cmdpriv);
1851 	signed int	res = _SUCCESS;
1852 
1853 	psetkeyparm = rtw_zmalloc(sizeof(struct setkey_parm));
1854 	if (!psetkeyparm) {
1855 		res = _FAIL;
1856 		goto exit;
1857 	}
1858 
1859 	if (psecuritypriv->dot11AuthAlgrthm == dot11AuthAlgrthm_8021X)
1860 		psetkeyparm->algorithm = (unsigned char)psecuritypriv->dot118021XGrpPrivacy;
1861 	else
1862 		psetkeyparm->algorithm = (u8)psecuritypriv->dot11PrivacyAlgrthm;
1863 
1864 	psetkeyparm->keyid = (u8)keyid;/* 0~3 */
1865 	psetkeyparm->set_tx = set_tx;
1866 	if (is_wep_enc(psetkeyparm->algorithm))
1867 		adapter->securitypriv.key_mask |= BIT(psetkeyparm->keyid);
1868 
1869 	switch (psetkeyparm->algorithm) {
1870 
1871 	case _WEP40_:
1872 		keylen = 5;
1873 		memcpy(&(psetkeyparm->key[0]), &(psecuritypriv->dot11DefKey[keyid].skey[0]), keylen);
1874 		break;
1875 	case _WEP104_:
1876 		keylen = 13;
1877 		memcpy(&(psetkeyparm->key[0]), &(psecuritypriv->dot11DefKey[keyid].skey[0]), keylen);
1878 		break;
1879 	case _TKIP_:
1880 		keylen = 16;
1881 		memcpy(&psetkeyparm->key, &psecuritypriv->dot118021XGrpKey[keyid], keylen);
1882 		psetkeyparm->grpkey = 1;
1883 		break;
1884 	case _AES_:
1885 		keylen = 16;
1886 		memcpy(&psetkeyparm->key, &psecuritypriv->dot118021XGrpKey[keyid], keylen);
1887 		psetkeyparm->grpkey = 1;
1888 		break;
1889 	default:
1890 		res = _FAIL;
1891 		kfree(psetkeyparm);
1892 		goto exit;
1893 	}
1894 
1895 	if (enqueue) {
1896 		pcmd = rtw_zmalloc(sizeof(struct cmd_obj));
1897 		if (!pcmd) {
1898 			kfree(psetkeyparm);
1899 			res = _FAIL;  /* try again */
1900 			goto exit;
1901 		}
1902 
1903 		pcmd->cmdcode = _SetKey_CMD_;
1904 		pcmd->parmbuf = (u8 *)psetkeyparm;
1905 		pcmd->cmdsz =  (sizeof(struct setkey_parm));
1906 		pcmd->rsp = NULL;
1907 		pcmd->rspsz = 0;
1908 
1909 		INIT_LIST_HEAD(&pcmd->list);
1910 
1911 		res = rtw_enqueue_cmd(pcmdpriv, pcmd);
1912 	} else {
1913 		setkey_hdl(adapter, (u8 *)psetkeyparm);
1914 		kfree(psetkeyparm);
1915 	}
1916 exit:
1917 	return res;
1918 }
1919 
1920 /* adjust ies for rtw_joinbss_cmd in WMM */
rtw_restruct_wmm_ie(struct adapter * adapter,u8 * in_ie,u8 * out_ie,uint in_len,uint initial_out_len)1921 int rtw_restruct_wmm_ie(struct adapter *adapter, u8 *in_ie, u8 *out_ie, uint in_len, uint initial_out_len)
1922 {
1923 	unsigned	int ielength = 0;
1924 	unsigned int i, j;
1925 
1926 	i = 12; /* after the fixed IE */
1927 	while (i < in_len) {
1928 		ielength = initial_out_len;
1929 
1930 		if (in_ie[i] == 0xDD && in_ie[i+2] == 0x00 && in_ie[i+3] == 0x50  && in_ie[i+4] == 0xF2 && in_ie[i+5] == 0x02 && i+5 < in_len) { /* WMM element ID and OUI */
1931 			for (j = i; j < i + 9; j++) {
1932 				out_ie[ielength] = in_ie[j];
1933 				ielength++;
1934 			}
1935 			out_ie[initial_out_len + 1] = 0x07;
1936 			out_ie[initial_out_len + 6] = 0x00;
1937 			out_ie[initial_out_len + 8] = 0x00;
1938 
1939 			break;
1940 		}
1941 
1942 		i += (in_ie[i+1]+2); /*  to the next IE element */
1943 	}
1944 
1945 	return ielength;
1946 
1947 }
1948 
1949 /*  */
1950 /*  Ported from 8185: IsInPreAuthKeyList(). (Renamed from SecIsInPreAuthKeyList(), 2006-10-13.) */
1951 /*  Added by Annie, 2006-05-07. */
1952 /*  */
1953 /*  Search by BSSID, */
1954 /*  Return Value: */
1955 /* 		-1		:if there is no pre-auth key in the  table */
1956 /* 		>= 0		:if there is pre-auth key, and   return the entry id */
1957 /*  */
1958 /*  */
1959 
SecIsInPMKIDList(struct adapter * Adapter,u8 * bssid)1960 static int SecIsInPMKIDList(struct adapter *Adapter, u8 *bssid)
1961 {
1962 	struct security_priv *p = &Adapter->securitypriv;
1963 	int i;
1964 
1965 	for (i = 0; i < NUM_PMKID_CACHE; i++)
1966 		if ((p->PMKIDList[i].bUsed) &&
1967 				(!memcmp(p->PMKIDList[i].Bssid, bssid, ETH_ALEN)))
1968 			return i;
1969 	return -1;
1970 }
1971 
1972 /*  */
1973 /*  Check the RSN IE length */
1974 /*  If the RSN IE length <= 20, the RSN IE didn't include the PMKID information */
1975 /*  0-11th element in the array are the fixed IE */
1976 /*  12th element in the array is the IE */
1977 /*  13th element in the array is the IE length */
1978 /*  */
1979 
rtw_append_pmkid(struct adapter * Adapter,int iEntry,u8 * ie,uint ie_len)1980 static int rtw_append_pmkid(struct adapter *Adapter, int iEntry, u8 *ie, uint ie_len)
1981 {
1982 	struct security_priv *psecuritypriv = &Adapter->securitypriv;
1983 
1984 	if (ie[13] <= 20) {
1985 		/*  The RSN IE didn't include the PMK ID, append the PMK information */
1986 		ie[ie_len] = 1;
1987 		ie_len++;
1988 		ie[ie_len] = 0;	/* PMKID count = 0x0100 */
1989 		ie_len++;
1990 		memcpy(&ie[ie_len], &psecuritypriv->PMKIDList[iEntry].PMKID, 16);
1991 		ie_len += 16;
1992 		ie[13] += 18;/* PMKID length = 2+16 */
1993 	}
1994 	return ie_len;
1995 }
1996 
rtw_restruct_sec_ie(struct adapter * adapter,u8 * in_ie,u8 * out_ie,uint in_len)1997 signed int rtw_restruct_sec_ie(struct adapter *adapter, u8 *in_ie, u8 *out_ie, uint in_len)
1998 {
1999 	u8 authmode = 0x0;
2000 	uint	ielength;
2001 	int iEntry;
2002 
2003 	struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
2004 	struct security_priv *psecuritypriv = &adapter->securitypriv;
2005 	uint	ndisauthmode = psecuritypriv->ndisauthtype;
2006 
2007 	/* copy fixed ie only */
2008 	memcpy(out_ie, in_ie, 12);
2009 	ielength = 12;
2010 	if ((ndisauthmode == Ndis802_11AuthModeWPA) || (ndisauthmode == Ndis802_11AuthModeWPAPSK))
2011 		authmode = WLAN_EID_VENDOR_SPECIFIC;
2012 	if ((ndisauthmode == Ndis802_11AuthModeWPA2) || (ndisauthmode == Ndis802_11AuthModeWPA2PSK))
2013 		authmode = WLAN_EID_RSN;
2014 
2015 	if (check_fwstate(pmlmepriv, WIFI_UNDER_WPS)) {
2016 		memcpy(out_ie+ielength, psecuritypriv->wps_ie, psecuritypriv->wps_ie_len);
2017 
2018 		ielength += psecuritypriv->wps_ie_len;
2019 	} else if ((authmode == WLAN_EID_VENDOR_SPECIFIC) || (authmode == WLAN_EID_RSN)) {
2020 		/* copy RSN or SSN */
2021 		memcpy(&out_ie[ielength], &psecuritypriv->supplicant_ie[0], psecuritypriv->supplicant_ie[1]+2);
2022 		ielength += psecuritypriv->supplicant_ie[1]+2;
2023 		rtw_report_sec_ie(adapter, authmode, psecuritypriv->supplicant_ie);
2024 	}
2025 
2026 	iEntry = SecIsInPMKIDList(adapter, pmlmepriv->assoc_bssid);
2027 	if (iEntry < 0) {
2028 		return ielength;
2029 	} else {
2030 		if (authmode == WLAN_EID_RSN)
2031 			ielength = rtw_append_pmkid(adapter, iEntry, out_ie, ielength);
2032 	}
2033 	return ielength;
2034 }
2035 
rtw_init_registrypriv_dev_network(struct adapter * adapter)2036 void rtw_init_registrypriv_dev_network(struct adapter *adapter)
2037 {
2038 	struct registry_priv *pregistrypriv = &adapter->registrypriv;
2039 	struct eeprom_priv *peepriv = &adapter->eeprompriv;
2040 	struct wlan_bssid_ex    *pdev_network = &pregistrypriv->dev_network;
2041 	u8 *myhwaddr = myid(peepriv);
2042 
2043 	memcpy(pdev_network->mac_address, myhwaddr, ETH_ALEN);
2044 
2045 	memcpy(&pdev_network->ssid, &pregistrypriv->ssid, sizeof(struct ndis_802_11_ssid));
2046 
2047 	pdev_network->configuration.length = sizeof(struct ndis_802_11_conf);
2048 	pdev_network->configuration.beacon_period = 100;
2049 }
2050 
rtw_update_registrypriv_dev_network(struct adapter * adapter)2051 void rtw_update_registrypriv_dev_network(struct adapter *adapter)
2052 {
2053 	int sz = 0;
2054 	struct registry_priv *pregistrypriv = &adapter->registrypriv;
2055 	struct wlan_bssid_ex    *pdev_network = &pregistrypriv->dev_network;
2056 	struct	security_priv *psecuritypriv = &adapter->securitypriv;
2057 	struct	wlan_network	*cur_network = &adapter->mlmepriv.cur_network;
2058 
2059 	pdev_network->privacy = (psecuritypriv->dot11PrivacyAlgrthm > 0 ? 1 : 0) ; /*  adhoc no 802.1x */
2060 
2061 	pdev_network->rssi = 0;
2062 
2063 	switch (pregistrypriv->wireless_mode) {
2064 	case WIRELESS_11B:
2065 		pdev_network->network_type_in_use = (Ndis802_11DS);
2066 		break;
2067 	case WIRELESS_11G:
2068 	case WIRELESS_11BG:
2069 	case WIRELESS_11_24N:
2070 	case WIRELESS_11G_24N:
2071 	case WIRELESS_11BG_24N:
2072 		pdev_network->network_type_in_use = (Ndis802_11OFDM24);
2073 		break;
2074 	default:
2075 		/*  TODO */
2076 		break;
2077 	}
2078 
2079 	pdev_network->configuration.ds_config = (pregistrypriv->channel);
2080 
2081 	if (cur_network->network.infrastructure_mode == Ndis802_11IBSS)
2082 		pdev_network->configuration.atim_window = (0);
2083 
2084 	pdev_network->infrastructure_mode = (cur_network->network.infrastructure_mode);
2085 
2086 	/*  1. Supported rates */
2087 	/*  2. IE */
2088 
2089 	/* rtw_set_supported_rate(pdev_network->supported_rates, pregistrypriv->wireless_mode) ;  will be called in rtw_generate_ie */
2090 	sz = rtw_generate_ie(pregistrypriv);
2091 
2092 	pdev_network->ie_length = sz;
2093 
2094 	pdev_network->length = get_wlan_bssid_ex_sz((struct wlan_bssid_ex  *)pdev_network);
2095 
2096 	/* notes: translate ie_length & length after assign the length to cmdsz in createbss_cmd(); */
2097 	/* pdev_network->ie_length = cpu_to_le32(sz); */
2098 }
2099 
rtw_get_encrypt_decrypt_from_registrypriv(struct adapter * adapter)2100 void rtw_get_encrypt_decrypt_from_registrypriv(struct adapter *adapter)
2101 {
2102 }
2103 
2104 /* the function is at passive_level */
rtw_joinbss_reset(struct adapter * padapter)2105 void rtw_joinbss_reset(struct adapter *padapter)
2106 {
2107 	u8 threshold;
2108 	struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
2109 
2110 	struct ht_priv 	*phtpriv = &pmlmepriv->htpriv;
2111 
2112 	/* todo: if you want to do something io/reg/hw setting before join_bss, please add code here */
2113 
2114 	pmlmepriv->num_FortyMHzIntolerant = 0;
2115 
2116 	pmlmepriv->num_sta_no_ht = 0;
2117 
2118 	phtpriv->ampdu_enable = false;/* reset to disabled */
2119 
2120 	/*  TH = 1 => means that invalidate usb rx aggregation */
2121 	/*  TH = 0 => means that validate usb rx aggregation, use init value. */
2122 	if (phtpriv->ht_option) {
2123 		if (padapter->registrypriv.wifi_spec == 1)
2124 			threshold = 1;
2125 		else
2126 			threshold = 0;
2127 		rtw_hal_set_hwreg(padapter, HW_VAR_RXDMA_AGG_PG_TH, (u8 *)(&threshold));
2128 	} else {
2129 		threshold = 1;
2130 		rtw_hal_set_hwreg(padapter, HW_VAR_RXDMA_AGG_PG_TH, (u8 *)(&threshold));
2131 	}
2132 }
2133 
rtw_ht_use_default_setting(struct adapter * padapter)2134 void rtw_ht_use_default_setting(struct adapter *padapter)
2135 {
2136 	struct mlme_priv 	*pmlmepriv = &padapter->mlmepriv;
2137 	struct ht_priv 	*phtpriv = &pmlmepriv->htpriv;
2138 	struct registry_priv *pregistrypriv = &padapter->registrypriv;
2139 	bool		bHwLDPCSupport = false, bHwSTBCSupport = false;
2140 	bool		bHwSupportBeamformer = false, bHwSupportBeamformee = false;
2141 
2142 	if (pregistrypriv->wifi_spec)
2143 		phtpriv->bss_coexist = 1;
2144 	else
2145 		phtpriv->bss_coexist = 0;
2146 
2147 	phtpriv->sgi_40m = TEST_FLAG(pregistrypriv->short_gi, BIT1) ? true : false;
2148 	phtpriv->sgi_20m = TEST_FLAG(pregistrypriv->short_gi, BIT0) ? true : false;
2149 
2150 	/*  LDPC support */
2151 	rtw_hal_get_def_var(padapter, HAL_DEF_RX_LDPC, (u8 *)&bHwLDPCSupport);
2152 	CLEAR_FLAGS(phtpriv->ldpc_cap);
2153 	if (bHwLDPCSupport) {
2154 		if (TEST_FLAG(pregistrypriv->ldpc_cap, BIT4))
2155 			SET_FLAG(phtpriv->ldpc_cap, LDPC_HT_ENABLE_RX);
2156 	}
2157 	rtw_hal_get_def_var(padapter, HAL_DEF_TX_LDPC, (u8 *)&bHwLDPCSupport);
2158 	if (bHwLDPCSupport) {
2159 		if (TEST_FLAG(pregistrypriv->ldpc_cap, BIT5))
2160 			SET_FLAG(phtpriv->ldpc_cap, LDPC_HT_ENABLE_TX);
2161 	}
2162 
2163 	/*  STBC */
2164 	rtw_hal_get_def_var(padapter, HAL_DEF_TX_STBC, (u8 *)&bHwSTBCSupport);
2165 	CLEAR_FLAGS(phtpriv->stbc_cap);
2166 	if (bHwSTBCSupport) {
2167 		if (TEST_FLAG(pregistrypriv->stbc_cap, BIT5))
2168 			SET_FLAG(phtpriv->stbc_cap, STBC_HT_ENABLE_TX);
2169 	}
2170 	rtw_hal_get_def_var(padapter, HAL_DEF_RX_STBC, (u8 *)&bHwSTBCSupport);
2171 	if (bHwSTBCSupport) {
2172 		if (TEST_FLAG(pregistrypriv->stbc_cap, BIT4))
2173 			SET_FLAG(phtpriv->stbc_cap, STBC_HT_ENABLE_RX);
2174 	}
2175 
2176 	/*  Beamforming setting */
2177 	rtw_hal_get_def_var(padapter, HAL_DEF_EXPLICIT_BEAMFORMER, (u8 *)&bHwSupportBeamformer);
2178 	rtw_hal_get_def_var(padapter, HAL_DEF_EXPLICIT_BEAMFORMEE, (u8 *)&bHwSupportBeamformee);
2179 	CLEAR_FLAGS(phtpriv->beamform_cap);
2180 	if (TEST_FLAG(pregistrypriv->beamform_cap, BIT4) && bHwSupportBeamformer)
2181 		SET_FLAG(phtpriv->beamform_cap, BEAMFORMING_HT_BEAMFORMER_ENABLE);
2182 
2183 	if (TEST_FLAG(pregistrypriv->beamform_cap, BIT5) && bHwSupportBeamformee)
2184 		SET_FLAG(phtpriv->beamform_cap, BEAMFORMING_HT_BEAMFORMEE_ENABLE);
2185 }
2186 
rtw_build_wmm_ie_ht(struct adapter * padapter,u8 * out_ie,uint * pout_len)2187 void rtw_build_wmm_ie_ht(struct adapter *padapter, u8 *out_ie, uint *pout_len)
2188 {
2189 	unsigned char WMM_IE[] = {0x00, 0x50, 0xf2, 0x02, 0x00, 0x01, 0x00};
2190 	int out_len;
2191 
2192 	if (padapter->mlmepriv.qospriv.qos_option == 0) {
2193 		out_len = *pout_len;
2194 		rtw_set_ie(out_ie+out_len, WLAN_EID_VENDOR_SPECIFIC,
2195 			   _WMM_IE_Length_, WMM_IE, pout_len);
2196 
2197 		padapter->mlmepriv.qospriv.qos_option = 1;
2198 	}
2199 }
2200 
2201 /* the function is >= passive_level */
rtw_restructure_ht_ie(struct adapter * padapter,u8 * in_ie,u8 * out_ie,uint in_len,uint * pout_len,u8 channel)2202 unsigned int rtw_restructure_ht_ie(struct adapter *padapter, u8 *in_ie, u8 *out_ie, uint in_len, uint *pout_len, u8 channel)
2203 {
2204 	u32 ielen, out_len;
2205 	enum ieee80211_max_ampdu_length_exp max_rx_ampdu_factor;
2206 	unsigned char *p;
2207 	struct ieee80211_ht_cap ht_capie;
2208 	u8 cbw40_enable = 0, stbc_rx_enable = 0, operation_bw = 0;
2209 	struct registry_priv *pregistrypriv = &padapter->registrypriv;
2210 	struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
2211 	struct ht_priv 	*phtpriv = &pmlmepriv->htpriv;
2212 	struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
2213 
2214 	phtpriv->ht_option = false;
2215 
2216 	out_len = *pout_len;
2217 
2218 	memset(&ht_capie, 0, sizeof(struct ieee80211_ht_cap));
2219 
2220 	ht_capie.cap_info = cpu_to_le16(IEEE80211_HT_CAP_DSSSCCK40);
2221 
2222 	if (phtpriv->sgi_20m)
2223 		ht_capie.cap_info |= cpu_to_le16(IEEE80211_HT_CAP_SGI_20);
2224 
2225 	/* Get HT BW */
2226 	if (!in_ie) {
2227 		/* TDLS: TODO 20/40 issue */
2228 		if (check_fwstate(pmlmepriv, WIFI_STATION_STATE)) {
2229 			operation_bw = padapter->mlmeextpriv.cur_bwmode;
2230 			if (operation_bw > CHANNEL_WIDTH_40)
2231 				operation_bw = CHANNEL_WIDTH_40;
2232 		} else
2233 			/* TDLS: TODO 40? */
2234 			operation_bw = CHANNEL_WIDTH_40;
2235 	} else {
2236 		p = rtw_get_ie(in_ie, WLAN_EID_HT_OPERATION, &ielen, in_len);
2237 		if (p && (ielen == sizeof(struct ieee80211_ht_addt_info))) {
2238 			struct HT_info_element *pht_info = (struct HT_info_element *)(p+2);
2239 
2240 			if (pht_info->infos[0] & BIT(2)) {
2241 				switch (pht_info->infos[0] & 0x3) {
2242 				case 1:
2243 				case 3:
2244 					operation_bw = CHANNEL_WIDTH_40;
2245 					break;
2246 				default:
2247 					operation_bw = CHANNEL_WIDTH_20;
2248 					break;
2249 				}
2250 			} else {
2251 				operation_bw = CHANNEL_WIDTH_20;
2252 			}
2253 		}
2254 	}
2255 
2256 	/* to disable 40M Hz support while gd_bw_40MHz_en = 0 */
2257 	if (channel > 14) {
2258 		if ((pregistrypriv->bw_mode & 0xf0) > 0)
2259 			cbw40_enable = 1;
2260 	} else {
2261 		if ((pregistrypriv->bw_mode & 0x0f) > 0)
2262 			cbw40_enable = 1;
2263 	}
2264 
2265 	if ((cbw40_enable == 1) && (operation_bw == CHANNEL_WIDTH_40)) {
2266 		ht_capie.cap_info |= cpu_to_le16(IEEE80211_HT_CAP_SUP_WIDTH);
2267 		if (phtpriv->sgi_40m)
2268 			ht_capie.cap_info |= cpu_to_le16(IEEE80211_HT_CAP_SGI_40);
2269 	}
2270 
2271 	if (TEST_FLAG(phtpriv->stbc_cap, STBC_HT_ENABLE_TX))
2272 		ht_capie.cap_info |= cpu_to_le16(IEEE80211_HT_CAP_TX_STBC);
2273 
2274 	/* todo: disable SM power save mode */
2275 	ht_capie.cap_info |= cpu_to_le16(IEEE80211_HT_CAP_SM_PS);
2276 
2277 	if (TEST_FLAG(phtpriv->stbc_cap, STBC_HT_ENABLE_RX)) {
2278 		if ((channel <= 14 && pregistrypriv->rx_stbc == 0x1) ||	/* enable for 2.4GHz */
2279 			(pregistrypriv->wifi_spec == 1))
2280 			stbc_rx_enable = 1;
2281 	}
2282 
2283 	/* fill default supported_mcs_set */
2284 	memcpy(&ht_capie.mcs, pmlmeext->default_supported_mcs_set, 16);
2285 
2286 	/* update default supported_mcs_set */
2287 	if (stbc_rx_enable)
2288 		ht_capie.cap_info |= cpu_to_le16(IEEE80211_HT_CAP_RX_STBC_1R);/* RX STBC One spatial stream */
2289 
2290 	set_mcs_rate_by_mask(ht_capie.mcs.rx_mask, MCS_RATE_1R);
2291 
2292 	{
2293 		u32 rx_packet_offset, max_recvbuf_sz;
2294 
2295 		rtw_hal_get_def_var(padapter, HAL_DEF_RX_PACKET_OFFSET, &rx_packet_offset);
2296 		rtw_hal_get_def_var(padapter, HAL_DEF_MAX_RECVBUF_SZ, &max_recvbuf_sz);
2297 	}
2298 
2299 	if (padapter->driver_rx_ampdu_factor != 0xFF)
2300 		max_rx_ampdu_factor =
2301 		  (enum ieee80211_max_ampdu_length_exp)padapter->driver_rx_ampdu_factor;
2302 	else
2303 		rtw_hal_get_def_var(padapter, HW_VAR_MAX_RX_AMPDU_FACTOR,
2304 				    &max_rx_ampdu_factor);
2305 
2306 	ht_capie.ampdu_params_info = (max_rx_ampdu_factor&0x03);
2307 
2308 	if (padapter->securitypriv.dot11PrivacyAlgrthm == _AES_)
2309 		ht_capie.ampdu_params_info |= (IEEE80211_HT_CAP_AMPDU_DENSITY&(0x07<<2));
2310 	else
2311 		ht_capie.ampdu_params_info |= (IEEE80211_HT_CAP_AMPDU_DENSITY&0x00);
2312 
2313 	rtw_set_ie(out_ie+out_len, WLAN_EID_HT_CAPABILITY,
2314 		   sizeof(struct ieee80211_ht_cap), (unsigned char *)&ht_capie, pout_len);
2315 
2316 	phtpriv->ht_option = true;
2317 
2318 	if (in_ie) {
2319 		p = rtw_get_ie(in_ie, WLAN_EID_HT_OPERATION, &ielen, in_len);
2320 		if (p && (ielen == sizeof(struct ieee80211_ht_addt_info))) {
2321 			out_len = *pout_len;
2322 			rtw_set_ie(out_ie+out_len, WLAN_EID_HT_OPERATION, ielen, p+2, pout_len);
2323 		}
2324 	}
2325 
2326 	return phtpriv->ht_option;
2327 
2328 }
2329 
2330 /* the function is > passive_level (in critical_section) */
rtw_update_ht_cap(struct adapter * padapter,u8 * pie,uint ie_len,u8 channel)2331 void rtw_update_ht_cap(struct adapter *padapter, u8 *pie, uint ie_len, u8 channel)
2332 {
2333 	u8 *p, max_ampdu_sz;
2334 	int len;
2335 	struct ieee80211_ht_cap *pht_capie;
2336 	struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
2337 	struct ht_priv 	*phtpriv = &pmlmepriv->htpriv;
2338 	struct registry_priv *pregistrypriv = &padapter->registrypriv;
2339 	struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
2340 	struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
2341 	u8 cbw40_enable = 0;
2342 
2343 	if (!phtpriv->ht_option)
2344 		return;
2345 
2346 	if ((!pmlmeinfo->HT_info_enable) || (!pmlmeinfo->HT_caps_enable))
2347 		return;
2348 
2349 	/* maybe needs check if ap supports rx ampdu. */
2350 	if (!(phtpriv->ampdu_enable) && pregistrypriv->ampdu_enable == 1)
2351 		phtpriv->ampdu_enable = true;
2352 
2353 	/* check Max Rx A-MPDU Size */
2354 	len = 0;
2355 	p = rtw_get_ie(pie+sizeof(struct ndis_802_11_fix_ie), WLAN_EID_HT_CAPABILITY, &len, ie_len-sizeof(struct ndis_802_11_fix_ie));
2356 	if (p && len > 0) {
2357 		pht_capie = (struct ieee80211_ht_cap *)(p+2);
2358 		max_ampdu_sz = (pht_capie->ampdu_params_info & IEEE80211_HT_CAP_AMPDU_FACTOR);
2359 		max_ampdu_sz = 1 << (max_ampdu_sz+3); /*  max_ampdu_sz (kbytes); */
2360 
2361 		phtpriv->rx_ampdu_maxlen = max_ampdu_sz;
2362 
2363 	}
2364 
2365 	len = 0;
2366 	p = rtw_get_ie(pie+sizeof(struct ndis_802_11_fix_ie), WLAN_EID_HT_OPERATION, &len, ie_len-sizeof(struct ndis_802_11_fix_ie));
2367 	if (p && len > 0) {
2368 		/* todo: */
2369 	}
2370 
2371 	if (channel > 14) {
2372 		if ((pregistrypriv->bw_mode & 0xf0) > 0)
2373 			cbw40_enable = 1;
2374 	} else {
2375 		if ((pregistrypriv->bw_mode & 0x0f) > 0)
2376 			cbw40_enable = 1;
2377 	}
2378 
2379 	/* update cur_bwmode & cur_ch_offset */
2380 	if ((cbw40_enable) &&
2381 	    (le16_to_cpu(pmlmeinfo->HT_caps.u.HT_cap_element.HT_caps_info) &
2382 	      BIT(1)) && (pmlmeinfo->HT_info.infos[0] & BIT(2))) {
2383 		int i;
2384 
2385 		/* update the MCS set */
2386 		for (i = 0; i < 16; i++)
2387 			pmlmeinfo->HT_caps.u.HT_cap_element.MCS_rate[i] &= pmlmeext->default_supported_mcs_set[i];
2388 
2389 		/* update the MCS rates */
2390 		set_mcs_rate_by_mask(pmlmeinfo->HT_caps.u.HT_cap_element.MCS_rate, MCS_RATE_1R);
2391 
2392 		/* switch to the 40M Hz mode according to the AP */
2393 		/* pmlmeext->cur_bwmode = CHANNEL_WIDTH_40; */
2394 		switch ((pmlmeinfo->HT_info.infos[0] & 0x3)) {
2395 		case EXTCHNL_OFFSET_UPPER:
2396 			pmlmeext->cur_ch_offset = HAL_PRIME_CHNL_OFFSET_LOWER;
2397 			break;
2398 
2399 		case EXTCHNL_OFFSET_LOWER:
2400 			pmlmeext->cur_ch_offset = HAL_PRIME_CHNL_OFFSET_UPPER;
2401 			break;
2402 
2403 		default:
2404 			pmlmeext->cur_ch_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE;
2405 			break;
2406 		}
2407 	}
2408 
2409 	/*  */
2410 	/*  Config SM Power Save setting */
2411 	/*  */
2412 	pmlmeinfo->SM_PS =
2413 		(le16_to_cpu(pmlmeinfo->HT_caps.u.HT_cap_element.HT_caps_info) &
2414 		 0x0C) >> 2;
2415 
2416 	/*  */
2417 	/*  Config current HT Protection mode. */
2418 	/*  */
2419 	pmlmeinfo->HT_protection = pmlmeinfo->HT_info.infos[1] & 0x3;
2420 }
2421 
rtw_issue_addbareq_cmd(struct adapter * padapter,struct xmit_frame * pxmitframe)2422 void rtw_issue_addbareq_cmd(struct adapter *padapter, struct xmit_frame *pxmitframe)
2423 {
2424 	u8 issued;
2425 	int priority;
2426 	struct sta_info *psta;
2427 	struct ht_priv *phtpriv;
2428 	struct pkt_attrib *pattrib = &pxmitframe->attrib;
2429 	s32 bmcst = is_multicast_ether_addr(pattrib->ra);
2430 
2431 	/* if (bmcst || (padapter->mlmepriv.LinkDetectInfo.bTxBusyTraffic == false)) */
2432 	if (bmcst || (padapter->mlmepriv.LinkDetectInfo.NumTxOkInPeriod < 100))
2433 		return;
2434 
2435 	priority = pattrib->priority;
2436 
2437 	psta = rtw_get_stainfo(&padapter->stapriv, pattrib->ra);
2438 	if (pattrib->psta != psta)
2439 		return;
2440 
2441 	if (!psta)
2442 		return;
2443 
2444 	if (!(psta->state & _FW_LINKED))
2445 		return;
2446 
2447 	phtpriv = &psta->htpriv;
2448 
2449 	if (phtpriv->ht_option && phtpriv->ampdu_enable) {
2450 		issued = (phtpriv->agg_enable_bitmap>>priority)&0x1;
2451 		issued |= (phtpriv->candidate_tid_bitmap>>priority)&0x1;
2452 
2453 		if (issued == 0) {
2454 			psta->htpriv.candidate_tid_bitmap |= BIT((u8)priority);
2455 			rtw_addbareq_cmd(padapter, (u8) priority, pattrib->ra);
2456 		}
2457 	}
2458 
2459 }
2460 
rtw_append_exented_cap(struct adapter * padapter,u8 * out_ie,uint * pout_len)2461 void rtw_append_exented_cap(struct adapter *padapter, u8 *out_ie, uint *pout_len)
2462 {
2463 	struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
2464 	struct ht_priv 	*phtpriv = &pmlmepriv->htpriv;
2465 	u8 cap_content[8] = {0};
2466 
2467 	if (phtpriv->bss_coexist)
2468 		SET_EXT_CAPABILITY_ELE_BSS_COEXIST(cap_content, 1);
2469 
2470 	rtw_set_ie(out_ie + *pout_len, WLAN_EID_EXT_CAPABILITY, 8, cap_content, pout_len);
2471 }
2472 
rtw_set_to_roam(struct adapter * adapter,u8 to_roam)2473 inline void rtw_set_to_roam(struct adapter *adapter, u8 to_roam)
2474 {
2475 	if (to_roam == 0)
2476 		adapter->mlmepriv.to_join = false;
2477 	adapter->mlmepriv.to_roam = to_roam;
2478 }
2479 
rtw_dec_to_roam(struct adapter * adapter)2480 inline u8 rtw_dec_to_roam(struct adapter *adapter)
2481 {
2482 	adapter->mlmepriv.to_roam--;
2483 	return adapter->mlmepriv.to_roam;
2484 }
2485 
rtw_to_roam(struct adapter * adapter)2486 inline u8 rtw_to_roam(struct adapter *adapter)
2487 {
2488 	return adapter->mlmepriv.to_roam;
2489 }
2490 
rtw_roaming(struct adapter * padapter,struct wlan_network * tgt_network)2491 void rtw_roaming(struct adapter *padapter, struct wlan_network *tgt_network)
2492 {
2493 	struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
2494 
2495 	spin_lock_bh(&pmlmepriv->lock);
2496 	_rtw_roaming(padapter, tgt_network);
2497 	spin_unlock_bh(&pmlmepriv->lock);
2498 }
_rtw_roaming(struct adapter * padapter,struct wlan_network * tgt_network)2499 void _rtw_roaming(struct adapter *padapter, struct wlan_network *tgt_network)
2500 {
2501 	struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
2502 	struct wlan_network *cur_network = &pmlmepriv->cur_network;
2503 
2504 	if (rtw_to_roam(padapter) > 0) {
2505 		memcpy(&pmlmepriv->assoc_ssid, &cur_network->network.ssid, sizeof(struct ndis_802_11_ssid));
2506 
2507 		pmlmepriv->assoc_by_bssid = false;
2508 
2509 		while (rtw_do_join(padapter) != _SUCCESS) {
2510 			rtw_dec_to_roam(padapter);
2511 			if (rtw_to_roam(padapter) <= 0) {
2512 				rtw_indicate_disconnect(padapter);
2513 				break;
2514 			}
2515 		}
2516 	}
2517 }
2518 
rtw_linked_check(struct adapter * padapter)2519 signed int rtw_linked_check(struct adapter *padapter)
2520 {
2521 	if ((check_fwstate(&padapter->mlmepriv, WIFI_AP_STATE) == true) ||
2522 			(check_fwstate(&padapter->mlmepriv, WIFI_ADHOC_STATE|WIFI_ADHOC_MASTER_STATE) == true)) {
2523 		if (padapter->stapriv.asoc_sta_count > 2)
2524 			return true;
2525 	} else {	/* Station mode */
2526 		if (check_fwstate(&padapter->mlmepriv, _FW_LINKED) == true)
2527 			return true;
2528 	}
2529 	return false;
2530 }
2531