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