1 /******************************************************************************
2  *
3  * Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved.
4  *
5  * This program is free software; you can redistribute it and/or modify it
6  * under the terms of version 2 of the GNU General Public License as
7  * published by the Free Software Foundation.
8  *
9  * This program is distributed in the hope that it will be useful, but WITHOUT
10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11  * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12  * more details.
13  *
14  ******************************************************************************/
15 #define _RTW_MLME_C_
16 
17 #include <osdep_service.h>
18 #include <drv_types.h>
19 #include <recv_osdep.h>
20 #include <xmit_osdep.h>
21 #include <hal_intf.h>
22 #include <mlme_osdep.h>
23 #include <sta_info.h>
24 #include <linux/ieee80211.h>
25 #include <wifi.h>
26 #include <wlan_bssdef.h>
27 #include <rtw_sreset.h>
28 
29 static struct wlan_network *
30 rtw_select_candidate_from_queue(struct mlme_priv *pmlmepriv);
31 static int rtw_do_join(struct rtw_adapter *padapter);
32 
rtw_init_mlme_timer(struct rtw_adapter * padapter)33 static void rtw_init_mlme_timer(struct rtw_adapter *padapter)
34 {
35 	struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
36 
37 	setup_timer(&pmlmepriv->assoc_timer, rtw23a_join_to_handler,
38 		    (unsigned long)padapter);
39 
40 	setup_timer(&pmlmepriv->scan_to_timer, rtw_scan_timeout_handler23a,
41 		    (unsigned long)padapter);
42 
43 	setup_timer(&pmlmepriv->dynamic_chk_timer,
44 		    rtw_dynamic_check_timer_handler, (unsigned long)padapter);
45 
46 	setup_timer(&pmlmepriv->set_scan_deny_timer,
47 		    rtw_set_scan_deny_timer_hdl, (unsigned long)padapter);
48 }
49 
rtw_init_mlme_priv23a(struct rtw_adapter * padapter)50 int rtw_init_mlme_priv23a(struct rtw_adapter *padapter)
51 {
52 	struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
53 
54 	pmlmepriv->nic_hdl = padapter;
55 
56 	pmlmepriv->fw_state = 0;
57 	pmlmepriv->cur_network.network.ifmode = NL80211_IFTYPE_UNSPECIFIED;
58 	/*  1: active, 0: pasive. Maybe someday we should rename this
59 	    varable to "active_mode" (Jeff) */
60 	pmlmepriv->scan_mode = SCAN_ACTIVE;
61 
62 	spin_lock_init(&pmlmepriv->lock);
63 	_rtw_init_queue23a(&pmlmepriv->scanned_queue);
64 
65 	memset(&pmlmepriv->assoc_ssid, 0, sizeof(struct cfg80211_ssid));
66 
67 	rtw_clear_scan_deny(padapter);
68 
69 	rtw_init_mlme_timer(padapter);
70 	return _SUCCESS;
71 }
72 
73 #ifdef CONFIG_8723AU_AP_MODE
rtw_free_mlme_ie_data(u8 ** ppie,u32 * plen)74 static void rtw_free_mlme_ie_data(u8 **ppie, u32 *plen)
75 {
76 	if (*ppie) {
77 		kfree(*ppie);
78 		*plen = 0;
79 		*ppie = NULL;
80 	}
81 }
82 #endif
83 
rtw23a_free_mlme_priv_ie_data(struct mlme_priv * pmlmepriv)84 void rtw23a_free_mlme_priv_ie_data(struct mlme_priv *pmlmepriv)
85 {
86 #ifdef CONFIG_8723AU_AP_MODE
87 	kfree(pmlmepriv->assoc_req);
88 	kfree(pmlmepriv->assoc_rsp);
89 	rtw_free_mlme_ie_data(&pmlmepriv->wps_probe_req_ie,
90 			      &pmlmepriv->wps_probe_req_ie_len);
91 #endif
92 }
93 
rtw_free_mlme_priv23a(struct mlme_priv * pmlmepriv)94 void rtw_free_mlme_priv23a(struct mlme_priv *pmlmepriv)
95 {
96 	RT_TRACE(_module_rtl871x_mlme_c_, _drv_err_,
97 		 "rtw_free_mlme_priv23a\n");
98 
99 	rtw23a_free_mlme_priv_ie_data(pmlmepriv);
100 }
101 
rtw_alloc_network(struct mlme_priv * pmlmepriv,gfp_t gfp)102 struct wlan_network *rtw_alloc_network(struct mlme_priv *pmlmepriv, gfp_t gfp)
103 {
104 	struct wlan_network *pnetwork;
105 
106 	pnetwork = kzalloc(sizeof(struct wlan_network), gfp);
107 	if (pnetwork) {
108 		INIT_LIST_HEAD(&pnetwork->list);
109 		pnetwork->network_type = 0;
110 		pnetwork->fixed = false;
111 		pnetwork->last_scanned = jiffies;
112 		pnetwork->join_res = 0;
113 	}
114 
115 	return pnetwork;
116 }
117 
_rtw_free_network23a(struct mlme_priv * pmlmepriv,struct wlan_network * pnetwork)118 static void _rtw_free_network23a(struct mlme_priv *pmlmepriv,
119 				 struct wlan_network *pnetwork)
120 {
121 	if (!pnetwork)
122 		return;
123 
124 	if (pnetwork->fixed == true)
125 		return;
126 
127 	list_del_init(&pnetwork->list);
128 
129 	kfree(pnetwork);
130 }
131 
132 /*
133  return the wlan_network with the matching addr
134 
135  Shall be called under atomic context... to avoid possible racing condition...
136 */
137 struct wlan_network *
rtw_find_network23a(struct rtw_queue * scanned_queue,u8 * addr)138 rtw_find_network23a(struct rtw_queue *scanned_queue, u8 *addr)
139 {
140 	struct list_head *phead, *plist;
141 	struct wlan_network *pnetwork = NULL;
142 
143 	if (is_zero_ether_addr(addr)) {
144 		pnetwork = NULL;
145 		goto exit;
146 	}
147 
148 	/* spin_lock_bh(&scanned_queue->lock); */
149 
150 	phead = get_list_head(scanned_queue);
151 	plist = phead->next;
152 
153 	while (plist != phead) {
154 		pnetwork = container_of(plist, struct wlan_network, list);
155 
156 		if (ether_addr_equal(addr, pnetwork->network.MacAddress))
157 			break;
158 
159 		plist = plist->next;
160 	}
161 
162 	if (plist == phead)
163 		pnetwork = NULL;
164 
165 	/* spin_unlock_bh(&scanned_queue->lock); */
166 
167 exit:
168 
169 	return pnetwork;
170 }
171 
rtw_free_network_queue23a(struct rtw_adapter * padapter)172 void rtw_free_network_queue23a(struct rtw_adapter *padapter)
173 {
174 	struct list_head *phead, *plist, *ptmp;
175 	struct wlan_network *pnetwork;
176 	struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
177 	struct rtw_queue *scanned_queue = &pmlmepriv->scanned_queue;
178 
179 	spin_lock_bh(&scanned_queue->lock);
180 
181 	phead = get_list_head(scanned_queue);
182 
183 	list_for_each_safe(plist, ptmp, phead) {
184 		pnetwork = container_of(plist, struct wlan_network, list);
185 
186 		_rtw_free_network23a(pmlmepriv, pnetwork);
187 	}
188 
189 	spin_unlock_bh(&scanned_queue->lock);
190 }
191 
rtw_if_up23a(struct rtw_adapter * padapter)192 int rtw_if_up23a(struct rtw_adapter *padapter)
193 {
194 	int res;
195 
196 	if (padapter->bDriverStopped || padapter->bSurpriseRemoved ||
197 	    !check_fwstate(&padapter->mlmepriv, _FW_LINKED)) {
198 		RT_TRACE(_module_rtl871x_mlme_c_, _drv_info_,
199 			 "rtw_if_up23a:bDriverStopped(%d) OR bSurpriseRemoved(%d)\n",
200 			 padapter->bDriverStopped, padapter->bSurpriseRemoved);
201 		res = false;
202 	} else
203 		res =  true;
204 
205 	return res;
206 }
207 
rtw_generate_random_ibss23a(u8 * pibss)208 void rtw_generate_random_ibss23a(u8 *pibss)
209 {
210 	unsigned long curtime = jiffies;
211 
212 	pibss[0] = 0x02;  /* in ad-hoc mode bit1 must set to 1 */
213 	pibss[1] = 0x11;
214 	pibss[2] = 0x87;
215 	pibss[3] = curtime & 0xff;/* p[0]; */
216 	pibss[4] = (curtime >> 8) & 0xff;/* p[1]; */
217 	pibss[5] = (curtime >> 16) & 0xff;/* p[2]; */
218 }
219 
rtw_set_roaming(struct rtw_adapter * adapter,u8 to_roaming)220 void rtw_set_roaming(struct rtw_adapter *adapter, u8 to_roaming)
221 {
222 	if (to_roaming == 0)
223 		adapter->mlmepriv.to_join = false;
224 	adapter->mlmepriv.to_roaming = to_roaming;
225 }
226 
_rtw_roaming(struct rtw_adapter * padapter,struct wlan_network * tgt_network)227 static void _rtw_roaming(struct rtw_adapter *padapter,
228 			 struct wlan_network *tgt_network)
229 {
230 	struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
231 	struct wlan_network *pnetwork;
232 	int do_join_r;
233 
234 	if (tgt_network)
235 		pnetwork = tgt_network;
236 	else
237 		pnetwork = &pmlmepriv->cur_network;
238 
239 	if (padapter->mlmepriv.to_roaming > 0) {
240 		DBG_8723A("roaming from %s(%pM), length:%d\n",
241 			  pnetwork->network.Ssid.ssid,
242 			  pnetwork->network.MacAddress,
243 			  pnetwork->network.Ssid.ssid_len);
244 		memcpy(&pmlmepriv->assoc_ssid, &pnetwork->network.Ssid,
245 		       sizeof(struct cfg80211_ssid));
246 
247 		pmlmepriv->assoc_by_bssid = false;
248 
249 		while (1) {
250 			do_join_r = rtw_do_join(padapter);
251 			if (do_join_r == _SUCCESS)
252 				break;
253 			else {
254 				DBG_8723A("roaming do_join return %d\n",
255 					  do_join_r);
256 				pmlmepriv->to_roaming--;
257 
258 				if (padapter->mlmepriv.to_roaming > 0)
259 					continue;
260 				else {
261 					DBG_8723A("%s(%d) -to roaming fail, "
262 						  "indicate_disconnect\n",
263 						  __func__, __LINE__);
264 					rtw_indicate_disconnect23a(padapter);
265 					break;
266 				}
267 			}
268 		}
269 	}
270 }
271 
rtw23a_roaming(struct rtw_adapter * padapter,struct wlan_network * tgt_network)272 void rtw23a_roaming(struct rtw_adapter *padapter,
273 		    struct wlan_network *tgt_network)
274 {
275 	struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
276 
277 	spin_lock_bh(&pmlmepriv->lock);
278 	_rtw_roaming(padapter, tgt_network);
279 	spin_unlock_bh(&pmlmepriv->lock);
280 }
281 
rtw_free_network_nolock(struct mlme_priv * pmlmepriv,struct wlan_network * pnetwork)282 static void rtw_free_network_nolock(struct mlme_priv *pmlmepriv,
283 				    struct wlan_network *pnetwork)
284 {
285 	_rtw_free_network23a(pmlmepriv, pnetwork);
286 }
287 
rtw_is_same_ibss23a(struct rtw_adapter * adapter,struct wlan_network * pnetwork)288 bool rtw_is_same_ibss23a(struct rtw_adapter *adapter,
289 			 struct wlan_network *pnetwork)
290 {
291 	int ret;
292 	struct security_priv *psecuritypriv = &adapter->securitypriv;
293 
294 	if (psecuritypriv->dot11PrivacyAlgrthm != 0 &&
295 	    pnetwork->network.Privacy == 0)
296 		ret = false;
297 	else if (psecuritypriv->dot11PrivacyAlgrthm == 0 &&
298 		 pnetwork->network.Privacy == 1)
299 		ret = false;
300 	else
301 		ret = true;
302 
303 	return ret;
304 }
305 
306 inline int is_same_ess(struct wlan_bssid_ex *a, struct wlan_bssid_ex *b);
is_same_ess(struct wlan_bssid_ex * a,struct wlan_bssid_ex * b)307 inline int is_same_ess(struct wlan_bssid_ex *a, struct wlan_bssid_ex *b)
308 {
309 	return (a->Ssid.ssid_len == b->Ssid.ssid_len) &&
310 		!memcmp(a->Ssid.ssid, b->Ssid.ssid, a->Ssid.ssid_len);
311 }
312 
is_same_network23a(struct wlan_bssid_ex * src,struct wlan_bssid_ex * dst)313 int is_same_network23a(struct wlan_bssid_ex *src, struct wlan_bssid_ex *dst)
314 {
315 	u16 s_cap, d_cap;
316 
317 	s_cap = src->capability;
318 	d_cap = dst->capability;
319 
320 	return ((src->Ssid.ssid_len == dst->Ssid.ssid_len) &&
321 		/*	(src->DSConfig == dst->DSConfig) && */
322 		ether_addr_equal(src->MacAddress, dst->MacAddress) &&
323 		!memcmp(src->Ssid.ssid, dst->Ssid.ssid, src->Ssid.ssid_len) &&
324 		(s_cap & WLAN_CAPABILITY_IBSS) ==
325 		(d_cap & WLAN_CAPABILITY_IBSS) &&
326 		(s_cap & WLAN_CAPABILITY_ESS) == (d_cap & WLAN_CAPABILITY_ESS));
327 }
328 
329 struct wlan_network *
rtw_get_oldest_wlan_network23a(struct rtw_queue * scanned_queue)330 rtw_get_oldest_wlan_network23a(struct rtw_queue *scanned_queue)
331 {
332 	struct list_head *plist, *phead;
333 	struct wlan_network *pwlan;
334 	struct wlan_network *oldest = NULL;
335 
336 	phead = get_list_head(scanned_queue);
337 
338 	list_for_each(plist, phead) {
339 		pwlan = container_of(plist, struct wlan_network, list);
340 
341 		if (pwlan->fixed != true) {
342 			if (!oldest || time_after(oldest->last_scanned,
343 						  pwlan->last_scanned))
344 				oldest = pwlan;
345 		}
346 	}
347 
348 	return oldest;
349 }
350 
update_network23a(struct wlan_bssid_ex * dst,struct wlan_bssid_ex * src,struct rtw_adapter * padapter,bool update_ie)351 void update_network23a(struct wlan_bssid_ex *dst, struct wlan_bssid_ex *src,
352 		       struct rtw_adapter *padapter, bool update_ie)
353 {
354 	u8 ss_ori = dst->SignalStrength;
355 	u8 sq_ori = dst->SignalQuality;
356 	long rssi_ori = dst->Rssi;
357 
358 	u8 ss_smp = src->SignalStrength;
359 	u8 sq_smp = src->SignalQuality;
360 	long rssi_smp = src->Rssi;
361 
362 	u8 ss_final;
363 	u8 sq_final;
364 	long rssi_final;
365 
366 	DBG_8723A("%s %s(%pM, ch%u) ss_ori:%3u, sq_ori:%3u, rssi_ori:%3ld, "
367 		  "ss_smp:%3u, sq_smp:%3u, rssi_smp:%3ld\n",
368 		  __func__, src->Ssid.ssid, src->MacAddress,
369 		  src->DSConfig, ss_ori, sq_ori, rssi_ori,
370 		  ss_smp, sq_smp, rssi_smp
371 	);
372 
373 	/* The rule below is 1/5 for sample value, 4/5 for history value */
374 	if (check_fwstate(&padapter->mlmepriv, _FW_LINKED) &&
375 	    is_same_network23a(&padapter->mlmepriv.cur_network.network, src)) {
376 		/* Take the recvpriv's value for the connected AP*/
377 		ss_final = padapter->recvpriv.signal_strength;
378 		sq_final = padapter->recvpriv.signal_qual;
379 		/* the rssi value here is undecorated, and will be
380 		   used for antenna diversity */
381 		if (sq_smp != 101) /* from the right channel */
382 			rssi_final = (src->Rssi+dst->Rssi*4)/5;
383 		else
384 			rssi_final = rssi_ori;
385 	} else {
386 		if (sq_smp != 101) { /* from the right channel */
387 			ss_final = ((u32)src->SignalStrength +
388 				    (u32)dst->SignalStrength * 4) / 5;
389 			sq_final = ((u32)src->SignalQuality +
390 				    (u32)dst->SignalQuality * 4) / 5;
391 			rssi_final = src->Rssi+dst->Rssi * 4 / 5;
392 		} else {
393 			/* bss info not receiving from the right channel, use
394 			   the original RX signal infos */
395 			ss_final = dst->SignalStrength;
396 			sq_final = dst->SignalQuality;
397 			rssi_final = dst->Rssi;
398 		}
399 
400 	}
401 
402 	if (update_ie)
403 		memcpy(dst, src, get_wlan_bssid_ex_sz(src));
404 
405 	dst->SignalStrength = ss_final;
406 	dst->SignalQuality = sq_final;
407 	dst->Rssi = rssi_final;
408 
409 	DBG_8723A("%s %s(%pM), SignalStrength:%u, SignalQuality:%u, "
410 		  "RawRSSI:%ld\n",  __func__, dst->Ssid.ssid, dst->MacAddress,
411 		  dst->SignalStrength, dst->SignalQuality, dst->Rssi);
412 }
413 
update_current_network(struct rtw_adapter * adapter,struct wlan_bssid_ex * pnetwork)414 static void update_current_network(struct rtw_adapter *adapter,
415 				   struct wlan_bssid_ex *pnetwork)
416 {
417 	struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
418 
419 	if (check_fwstate(pmlmepriv, _FW_LINKED) &&
420 	    is_same_network23a(&pmlmepriv->cur_network.network, pnetwork)) {
421 		update_network23a(&pmlmepriv->cur_network.network,
422 				  pnetwork, adapter, true);
423 
424 		rtw_update_protection23a(adapter,
425 					 pmlmepriv->cur_network.network.IEs,
426 					 pmlmepriv->cur_network.network.IELength);
427 	}
428 }
429 
430 /*
431 
432 Caller must hold pmlmepriv->lock first.
433 
434 */
rtw_update_scanned_network(struct rtw_adapter * adapter,struct wlan_bssid_ex * target)435 static void rtw_update_scanned_network(struct rtw_adapter *adapter,
436 				       struct wlan_bssid_ex *target)
437 {
438 	struct list_head *plist, *phead;
439 	struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
440 	struct wlan_network *pnetwork = NULL;
441 	struct wlan_network *oldest = NULL;
442 	struct rtw_queue *queue = &pmlmepriv->scanned_queue;
443 	u32 bssid_ex_sz;
444 	int found = 0;
445 
446 	spin_lock_bh(&queue->lock);
447 	phead = get_list_head(queue);
448 
449 	list_for_each(plist, phead) {
450 		pnetwork = container_of(plist, struct wlan_network, list);
451 
452 		if (is_same_network23a(&pnetwork->network, target)) {
453 			found = 1;
454 			break;
455 		}
456 		if (!oldest || time_after(oldest->last_scanned,
457 					  pnetwork->last_scanned))
458 			oldest = pnetwork;
459 	}
460 
461 	/* If we didn't find a match, then get a new network slot to initialize
462 	 * with this beacon's information */
463 	if (!found) {
464 		pnetwork = rtw_alloc_network(pmlmepriv, GFP_ATOMIC);
465 		if (!pnetwork) {
466 			if (!oldest) {
467 				RT_TRACE(_module_rtl871x_mlme_c_, _drv_err_,
468 					 "something wrong here\n");
469 				goto exit;
470 			}
471 			pnetwork = oldest;
472 		} else
473 			list_add_tail(&pnetwork->list, &queue->queue);
474 
475 		bssid_ex_sz = get_wlan_bssid_ex_sz(target);
476 		target->Length = bssid_ex_sz;
477 		memcpy(&pnetwork->network, target, bssid_ex_sz);
478 
479 		/*  variable initialize */
480 		pnetwork->fixed = false;
481 		pnetwork->last_scanned = jiffies;
482 
483 		pnetwork->network_type = 0;
484 		pnetwork->join_res = 0;
485 
486 		/* bss info not receiving from the right channel */
487 		if (pnetwork->network.SignalQuality == 101)
488 			pnetwork->network.SignalQuality = 0;
489 	} else {
490 		/*
491 		 * we have an entry and we are going to update it. But
492 		 * this entry may be already expired. In this case we
493 		 * do the same as we found a new net and call the
494 		 * new_net handler
495 		 */
496 		bool update_ie = true;
497 
498 		pnetwork->last_scanned = jiffies;
499 
500 		/* target.reserved == 1, means that scanned network is
501 		 * a bcn frame. */
502 		if (pnetwork->network.IELength > target->IELength &&
503 		    target->reserved == 1)
504 			update_ie = false;
505 
506 		update_network23a(&pnetwork->network, target, adapter,
507 				  update_ie);
508 	}
509 
510 exit:
511 	spin_unlock_bh(&queue->lock);
512 }
513 
rtw_add_network(struct rtw_adapter * adapter,struct wlan_bssid_ex * pnetwork)514 static void rtw_add_network(struct rtw_adapter *adapter,
515 			    struct wlan_bssid_ex *pnetwork)
516 {
517 	update_current_network(adapter, pnetwork);
518 	rtw_update_scanned_network(adapter, pnetwork);
519 }
520 
521 /* select the desired network based on the capability of the (i)bss. */
522 /*  check items: (1) security */
523 /*			   (2) network_type */
524 /*			   (3) WMM */
525 /*			   (4) HT */
526 /*                      (5) others */
rtw_is_desired_network(struct rtw_adapter * adapter,struct wlan_network * pnetwork)527 static int rtw_is_desired_network(struct rtw_adapter *adapter,
528 				  struct wlan_network *pnetwork)
529 {
530 	struct security_priv *psecuritypriv = &adapter->securitypriv;
531 	struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
532 	u32 desired_encmode;
533 	u32 privacy;
534 	int bselected = true;
535 
536 	desired_encmode = psecuritypriv->ndisencryptstatus;
537 	privacy = pnetwork->network.Privacy;
538 
539 	if (check_fwstate(pmlmepriv, WIFI_UNDER_WPS)) {
540 		if (cfg80211_find_vendor_ie(WLAN_OUI_MICROSOFT,
541 					    WLAN_OUI_TYPE_MICROSOFT_WPA,
542 					    pnetwork->network.IEs,
543 					    pnetwork->network.IELength))
544 			return true;
545 		else
546 			return false;
547 	}
548 	if (adapter->registrypriv.wifi_spec == 1) {
549 		/* for  correct flow of 8021X  to do.... */
550 		if (desired_encmode == Ndis802_11EncryptionDisabled &&
551 		    privacy != 0)
552 			bselected = false;
553 	}
554 
555 	if (desired_encmode != Ndis802_11EncryptionDisabled && privacy == 0) {
556 		DBG_8723A("desired_encmode: %d, privacy: %d\n",
557 			  desired_encmode, privacy);
558 		bselected = false;
559 	}
560 
561 	if (check_fwstate(pmlmepriv, WIFI_ADHOC_STATE)) {
562 		if (pnetwork->network.ifmode !=
563 		    pmlmepriv->cur_network.network.ifmode)
564 			bselected = false;
565 	}
566 
567 	return bselected;
568 }
569 
rtw_survey_event_cb23a(struct rtw_adapter * adapter,const u8 * pbuf)570 void rtw_survey_event_cb23a(struct rtw_adapter *adapter, const u8 *pbuf)
571 {
572 	u32 len;
573 	struct wlan_bssid_ex *pnetwork;
574 	struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
575 	struct survey_event *survey = (struct survey_event *)pbuf;
576 
577 	pnetwork = survey->bss;
578 
579 	RT_TRACE(_module_rtl871x_mlme_c_, _drv_info_,
580 		 "rtw_survey_event_cb23a, ssid=%s\n", pnetwork->Ssid.ssid);
581 
582 	len = get_wlan_bssid_ex_sz(pnetwork);
583 	if (len > (sizeof(struct wlan_bssid_ex))) {
584 		RT_TRACE(_module_rtl871x_mlme_c_, _drv_err_,
585 			 "****rtw_survey_event_cb23a: return a wrong bss ***\n");
586 		return;
587 	}
588 
589 	spin_lock_bh(&pmlmepriv->lock);
590 
591 	/*  update IBSS_network 's timestamp */
592 	if (check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE)) {
593 		if (ether_addr_equal(pmlmepriv->cur_network.network.MacAddress,
594 				     pnetwork->MacAddress)) {
595 			struct wlan_network *ibss_wlan;
596 
597 			pmlmepriv->cur_network.network.beacon_interval =
598 				pnetwork->beacon_interval;
599 			pmlmepriv->cur_network.network.capability =
600 				pnetwork->capability;
601 			pmlmepriv->cur_network.network.tsf = pnetwork->tsf;
602 			spin_lock_bh(&pmlmepriv->scanned_queue.lock);
603 			ibss_wlan = rtw_find_network23a(
604 				&pmlmepriv->scanned_queue,
605 				pnetwork->MacAddress);
606 			if (ibss_wlan) {
607 				pmlmepriv->cur_network.network.beacon_interval =
608 					ibss_wlan->network.beacon_interval;
609 				pmlmepriv->cur_network.network.capability =
610 					ibss_wlan->network.capability;
611 				pmlmepriv->cur_network.network.tsf =
612 					ibss_wlan->network.tsf;
613 				spin_unlock_bh(&pmlmepriv->scanned_queue.lock);
614 				goto exit;
615 			}
616 			spin_unlock_bh(&pmlmepriv->scanned_queue.lock);
617 		}
618 	}
619 
620 	/*  lock pmlmepriv->lock when you accessing network_q */
621 	if (!check_fwstate(pmlmepriv, _FW_UNDER_LINKING)) {
622 		if (pnetwork->Ssid.ssid[0] == 0)
623 			pnetwork->Ssid.ssid_len = 0;
624 
625 		rtw_add_network(adapter, pnetwork);
626 	}
627 
628 exit:
629 
630 	spin_unlock_bh(&pmlmepriv->lock);
631 
632 	kfree(survey->bss);
633 	survey->bss = NULL;
634 }
635 
636 void
rtw_surveydone_event_callback23a(struct rtw_adapter * adapter,const u8 * pbuf)637 rtw_surveydone_event_callback23a(struct rtw_adapter *adapter, const u8 *pbuf)
638 {
639 	struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
640 	struct mlme_ext_priv *pmlmeext = &adapter->mlmeextpriv;
641 	int ret;
642 
643 	spin_lock_bh(&pmlmepriv->lock);
644 
645 	if (pmlmepriv->wps_probe_req_ie) {
646 		pmlmepriv->wps_probe_req_ie_len = 0;
647 		kfree(pmlmepriv->wps_probe_req_ie);
648 		pmlmepriv->wps_probe_req_ie = NULL;
649 	}
650 
651 	RT_TRACE(_module_rtl871x_mlme_c_, _drv_info_,
652 		 "rtw_surveydone_event_callback23a: fw_state:%x\n",
653 		 get_fwstate(pmlmepriv));
654 
655 	if (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY)) {
656 		del_timer_sync(&pmlmepriv->scan_to_timer);
657 
658 		_clr_fwstate_(pmlmepriv, _FW_UNDER_SURVEY);
659 	} else {
660 		RT_TRACE(_module_rtl871x_mlme_c_, _drv_err_,
661 			 "nic status =%x, survey done event comes too late!\n",
662 			 get_fwstate(pmlmepriv));
663 	}
664 
665 	rtw_set_signal_stat_timer(&adapter->recvpriv);
666 
667 	if (pmlmepriv->to_join == true) {
668 		set_fwstate(pmlmepriv, _FW_UNDER_LINKING);
669 		if (check_fwstate(pmlmepriv, WIFI_ADHOC_STATE)) {
670 			ret = rtw_select_and_join_from_scanned_queue23a(
671 				pmlmepriv);
672 			if (ret != _SUCCESS)
673 				rtw_do_join_adhoc(adapter);
674 		} else {
675 			pmlmepriv->to_join = false;
676 			ret = rtw_select_and_join_from_scanned_queue23a(
677 				pmlmepriv);
678 			if (ret != _SUCCESS) {
679 				DBG_8723A("try_to_join, but select scanning "
680 					  "queue fail, to_roaming:%d\n",
681 					  adapter->mlmepriv.to_roaming);
682 				if (adapter->mlmepriv.to_roaming) {
683 					if (--pmlmepriv->to_roaming == 0 ||
684 					    rtw_sitesurvey_cmd23a(
685 						    adapter,
686 						    &pmlmepriv->assoc_ssid, 1,
687 						    NULL, 0) != _SUCCESS) {
688 						rtw_set_roaming(adapter, 0);
689 						rtw_free_assoc_resources23a(
690 							adapter, 1);
691 						rtw_indicate_disconnect23a(
692 							adapter);
693 					} else
694 						pmlmepriv->to_join = true;
695 				}
696 				_clr_fwstate_(pmlmepriv, _FW_UNDER_LINKING);
697 			}
698 		}
699 	}
700 
701 	spin_unlock_bh(&pmlmepriv->lock);
702 
703 	rtw_os_xmit_schedule23a(adapter);
704 
705 	if (pmlmeext->sitesurvey_res.bss_cnt == 0)
706 		rtw_sreset_reset(adapter);
707 
708 	rtw_cfg80211_surveydone_event_callback(adapter);
709 }
710 
free_scanqueue(struct mlme_priv * pmlmepriv)711 static void free_scanqueue(struct mlme_priv *pmlmepriv)
712 {
713 	struct wlan_network *pnetwork;
714 	struct rtw_queue *scan_queue = &pmlmepriv->scanned_queue;
715 	struct list_head *plist, *phead, *ptemp;
716 
717 	RT_TRACE(_module_rtl871x_mlme_c_, _drv_notice_, "+free_scanqueue\n");
718 	spin_lock_bh(&scan_queue->lock);
719 
720 	phead = get_list_head(scan_queue);
721 
722 	list_for_each_safe(plist, ptemp, phead) {
723 		pnetwork = container_of(plist, struct wlan_network, list);
724 		pnetwork->fixed = false;
725 		_rtw_free_network23a(pmlmepriv, pnetwork);
726 	}
727 
728 	spin_unlock_bh(&scan_queue->lock);
729 }
730 
731 /*
732  *rtw_free_assoc_resources23a: the caller has to lock pmlmepriv->lock
733  */
rtw_free_assoc_resources23a(struct rtw_adapter * adapter,int lock_scanned_queue)734 void rtw_free_assoc_resources23a(struct rtw_adapter *adapter,
735 				 int lock_scanned_queue)
736 {
737 	struct wlan_network *pwlan;
738 	struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
739 	struct sta_priv *pstapriv = &adapter->stapriv;
740 	struct wlan_network *tgt_network = &pmlmepriv->cur_network;
741 	struct sta_info *psta;
742 
743 	RT_TRACE(_module_rtl871x_mlme_c_, _drv_notice_,
744 		 "+rtw_free_assoc_resources23a\n");
745 	RT_TRACE(_module_rtl871x_mlme_c_, _drv_info_,
746 		 "tgt_network->network.MacAddress=%pM ssid=%s\n",
747 		 tgt_network->network.MacAddress,
748 		 tgt_network->network.Ssid.ssid);
749 
750 	if (check_fwstate(pmlmepriv, WIFI_STATION_STATE|WIFI_AP_STATE)) {
751 		psta = rtw_get_stainfo23a(&adapter->stapriv,
752 					  tgt_network->network.MacAddress);
753 
754 		spin_lock_bh(&pstapriv->sta_hash_lock);
755 		rtw_free_stainfo23a(adapter,  psta);
756 		spin_unlock_bh(&pstapriv->sta_hash_lock);
757 	}
758 
759 	if (check_fwstate(pmlmepriv, WIFI_ADHOC_STATE |
760 			  WIFI_ADHOC_MASTER_STATE|WIFI_AP_STATE)) {
761 		rtw_free_all_stainfo23a(adapter);
762 
763 		psta = rtw_get_bcmc_stainfo23a(adapter);
764 		spin_lock_bh(&pstapriv->sta_hash_lock);
765 		rtw_free_stainfo23a(adapter, psta);
766 		spin_unlock_bh(&pstapriv->sta_hash_lock);
767 
768 		rtw_init_bcmc_stainfo23a(adapter);
769 	}
770 
771 	if (lock_scanned_queue)
772 		spin_lock_bh(&pmlmepriv->scanned_queue.lock);
773 
774 	pwlan = rtw_find_network23a(&pmlmepriv->scanned_queue,
775 				    tgt_network->network.MacAddress);
776 	if (pwlan)
777 		pwlan->fixed = false;
778 	else
779 		RT_TRACE(_module_rtl871x_mlme_c_, _drv_err_,
780 			 "rtw_free_assoc_resources23a : pwlan== NULL\n");
781 
782 	if (check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE) &&
783 	    adapter->stapriv.asoc_sta_count == 1)
784 		rtw_free_network_nolock(pmlmepriv, pwlan);
785 
786 	if (lock_scanned_queue)
787 		spin_unlock_bh(&pmlmepriv->scanned_queue.lock);
788 
789 	pmlmepriv->key_mask = 0;
790 }
791 
792 /*
793 *rtw_indicate_connect23a: the caller has to lock pmlmepriv->lock
794 */
rtw_indicate_connect23a(struct rtw_adapter * padapter)795 void rtw_indicate_connect23a(struct rtw_adapter *padapter)
796 {
797 	struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
798 
799 	RT_TRACE(_module_rtl871x_mlme_c_, _drv_err_,
800 		 "+rtw_indicate_connect23a\n");
801 
802 	pmlmepriv->to_join = false;
803 
804 	if (!check_fwstate(&padapter->mlmepriv, _FW_LINKED)) {
805 		set_fwstate(pmlmepriv, _FW_LINKED);
806 
807 		rtw_cfg80211_indicate_connect(padapter);
808 
809 		netif_carrier_on(padapter->pnetdev);
810 
811 		if (padapter->pid[2] != 0)
812 			kill_pid(find_vpid(padapter->pid[2]), SIGALRM, 1);
813 	}
814 
815 	rtw_set_roaming(padapter, 0);
816 
817 	rtw_set_scan_deny(padapter, 3000);
818 
819 	RT_TRACE(_module_rtl871x_mlme_c_, _drv_err_,
820 		 "-rtw_indicate_connect23a: fw_state=0x%08x\n",
821 		 get_fwstate(pmlmepriv));
822 }
823 
824 /*
825  *rtw_indicate_disconnect23a: the caller has to lock pmlmepriv->lock
826  */
rtw_indicate_disconnect23a(struct rtw_adapter * padapter)827 void rtw_indicate_disconnect23a(struct rtw_adapter *padapter)
828 {
829 	struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
830 
831 	RT_TRACE(_module_rtl871x_mlme_c_, _drv_err_,
832 		 "+rtw_indicate_disconnect23a\n");
833 
834 	_clr_fwstate_(pmlmepriv, _FW_UNDER_LINKING|WIFI_UNDER_WPS);
835 
836 	/* DBG_8723A("clear wps when %s\n", __func__); */
837 
838 	if (padapter->mlmepriv.to_roaming > 0)
839 		_clr_fwstate_(pmlmepriv, _FW_LINKED);
840 
841 	if (check_fwstate(&padapter->mlmepriv, _FW_LINKED) ||
842 	    padapter->mlmepriv.to_roaming <= 0) {
843 		rtw_os_indicate_disconnect23a(padapter);
844 
845 		/* set ips_deny_time to avoid enter IPS before LPS leave */
846 		padapter->pwrctrlpriv.ips_deny_time =
847 			jiffies + msecs_to_jiffies(3000);
848 
849 		_clr_fwstate_(pmlmepriv, _FW_LINKED);
850 
851 		rtw_clear_scan_deny(padapter);
852 	}
853 
854 	rtw_lps_ctrl_wk_cmd23a(padapter, LPS_CTRL_DISCONNECT, 1);
855 }
856 
rtw_scan_abort23a(struct rtw_adapter * adapter)857 void rtw_scan_abort23a(struct rtw_adapter *adapter)
858 {
859 	unsigned long start;
860 	struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
861 	struct mlme_ext_priv *pmlmeext = &adapter->mlmeextpriv;
862 
863 	start = jiffies;
864 	pmlmeext->scan_abort = true;
865 	while (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY) &&
866 	       jiffies_to_msecs(jiffies - start) <= 200) {
867 		if (adapter->bDriverStopped || adapter->bSurpriseRemoved)
868 			break;
869 
870 		DBG_8723A("%s(%s): fw_state = _FW_UNDER_SURVEY!\n",
871 			  __func__, adapter->pnetdev->name);
872 		msleep(20);
873 	}
874 
875 	if (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY)) {
876 		if (!adapter->bDriverStopped && !adapter->bSurpriseRemoved)
877 			DBG_8723A("%s(%s): waiting for scan_abort time out!\n",
878 				  __func__, adapter->pnetdev->name);
879 		rtw_cfg80211_indicate_scan_done(wdev_to_priv(adapter->rtw_wdev),
880 						true);
881 	}
882 	pmlmeext->scan_abort = false;
883 }
884 
885 static struct sta_info *
rtw_joinbss_update_stainfo(struct rtw_adapter * padapter,struct wlan_network * pnetwork)886 rtw_joinbss_update_stainfo(struct rtw_adapter *padapter,
887 			   struct wlan_network *pnetwork)
888 {
889 	int i;
890 	struct sta_info *bmc_sta, *psta;
891 	struct recv_reorder_ctrl *preorder_ctrl;
892 	struct sta_priv *pstapriv = &padapter->stapriv;
893 
894 	psta = rtw_get_stainfo23a(pstapriv, pnetwork->network.MacAddress);
895 	if (!psta)
896 		psta = rtw_alloc_stainfo23a(pstapriv,
897 					    pnetwork->network.MacAddress,
898 					    GFP_ATOMIC);
899 
900 	if (psta) { /* update ptarget_sta */
901 		DBG_8723A("%s\n", __func__);
902 
903 		psta->aid  = pnetwork->join_res;
904 		psta->mac_id = 0;
905 
906 		/* sta mode */
907 		rtl8723a_SetHalODMVar(padapter, HAL_ODM_STA_INFO, psta, true);
908 
909 		/* security related */
910 		if (padapter->securitypriv.dot11AuthAlgrthm ==
911 		    dot11AuthAlgrthm_8021X) {
912 			padapter->securitypriv.binstallGrpkey = 0;
913 			padapter->securitypriv.busetkipkey = 0;
914 
915 			psta->ieee8021x_blocked = true;
916 			psta->dot118021XPrivacy =
917 				padapter->securitypriv.dot11PrivacyAlgrthm;
918 
919 			memset(&psta->dot118021x_UncstKey, 0,
920 			       sizeof (union Keytype));
921 
922 			memset(&psta->dot11tkiprxmickey, 0,
923 			       sizeof (union Keytype));
924 			memset(&psta->dot11tkiptxmickey, 0,
925 			       sizeof (union Keytype));
926 
927 			memset(&psta->dot11txpn, 0, sizeof (union pn48));
928 			memset(&psta->dot11rxpn, 0, sizeof (union pn48));
929 		}
930 
931 		/*	Commented by Albert 2012/07/21 */
932 		/*	When doing the WPS, the wps_ie_len won't equal to 0 */
933 		/*	And the Wi-Fi driver shouldn't allow the data packet
934 			to be transmitted. */
935 		if (padapter->securitypriv.wps_ie_len != 0) {
936 			psta->ieee8021x_blocked = true;
937 			padapter->securitypriv.wps_ie_len = 0;
938 		}
939 
940 		/* for A-MPDU Rx reordering buffer control for bmc_sta &
941 		 * sta_info */
942 		/* if A-MPDU Rx is enabled, resetting
943 		   rx_ordering_ctrl wstart_b(indicate_seq) to default
944 		   value = 0xffff */
945 		/* todo: check if AP can send A-MPDU packets */
946 		for (i = 0; i < 16 ; i++) {
947 			/* preorder_ctrl = &precvpriv->recvreorder_ctrl[i]; */
948 			preorder_ctrl = &psta->recvreorder_ctrl[i];
949 			preorder_ctrl->enable = false;
950 			preorder_ctrl->indicate_seq = 0xffff;
951 			preorder_ctrl->wend_b = 0xffff;
952 			/* max_ampdu_sz; ex. 32(kbytes) -> wsize_b = 32 */
953 			preorder_ctrl->wsize_b = 64;
954 		}
955 
956 		bmc_sta = rtw_get_bcmc_stainfo23a(padapter);
957 		if (bmc_sta) {
958 			for (i = 0; i < 16 ; i++) {
959 				preorder_ctrl = &bmc_sta->recvreorder_ctrl[i];
960 				preorder_ctrl->enable = false;
961 				preorder_ctrl->indicate_seq = 0xffff;
962 				preorder_ctrl->wend_b = 0xffff;
963 				/* max_ampdu_sz; ex. 32(kbytes) ->
964 				   wsize_b = 32 */
965 				preorder_ctrl->wsize_b = 64;
966 			}
967 		}
968 
969 		/* misc. */
970 		update_sta_info23a(padapter, psta);
971 
972 	}
973 
974 	return psta;
975 }
976 
977 /* pnetwork : returns from rtw23a_joinbss_event_cb */
978 /* ptarget_wlan: found from scanned_queue */
979 static void
rtw_joinbss_update_network23a(struct rtw_adapter * padapter,struct wlan_network * ptarget_wlan,struct wlan_network * pnetwork)980 rtw_joinbss_update_network23a(struct rtw_adapter *padapter,
981 			      struct wlan_network *ptarget_wlan,
982 			      struct wlan_network  *pnetwork)
983 {
984 	struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
985 	struct wlan_network *cur_network = &pmlmepriv->cur_network;
986 
987 	DBG_8723A("%s\n", __func__);
988 
989 	RT_TRACE(_module_rtl871x_mlme_c_, _drv_info_,
990 		 "fw_state:%x, BSSID:%pM\n",
991 		 get_fwstate(pmlmepriv),
992 		 pnetwork->network.MacAddress);
993 
994 	/*  why not use ptarget_wlan?? */
995 	memcpy(&cur_network->network, &pnetwork->network,
996 	       pnetwork->network.Length);
997 	/*  some IEs in pnetwork is wrong, so we should use ptarget_wlan IEs */
998 	cur_network->network.IELength = ptarget_wlan->network.IELength;
999 	memcpy(&cur_network->network.IEs[0], &ptarget_wlan->network.IEs[0],
1000 	       MAX_IE_SZ);
1001 
1002 	cur_network->network.capability = ptarget_wlan->network.capability;
1003 	cur_network->network.beacon_interval =
1004 		ptarget_wlan->network.beacon_interval;
1005 	cur_network->network.tsf = ptarget_wlan->network.tsf;
1006 
1007 	rtw_set_signal_stat_timer(&padapter->recvpriv);
1008 	padapter->recvpriv.signal_strength =
1009 		ptarget_wlan->network.SignalStrength;
1010 	padapter->recvpriv.signal_qual = ptarget_wlan->network.SignalQuality;
1011 	/*
1012 	 * the ptarget_wlan->network.Rssi is raw data, we use
1013 	 * ptarget_wlan->network.SignalStrength instead (has scaled)
1014 	 */
1015 	DBG_8723A("%s signal_strength:%3u, signal_qual:%3u\n",
1016 		  __func__, padapter->recvpriv.signal_strength,
1017 		  padapter->recvpriv.signal_qual);
1018 	rtw_set_signal_stat_timer(&padapter->recvpriv);
1019 
1020 	/* update fw_state will clr _FW_UNDER_LINKING here indirectly */
1021 	switch (pnetwork->network.ifmode) {
1022 	case NL80211_IFTYPE_P2P_CLIENT:
1023 	case NL80211_IFTYPE_STATION:
1024 		if (pmlmepriv->fw_state & WIFI_UNDER_WPS)
1025 			pmlmepriv->fw_state = WIFI_STATION_STATE|WIFI_UNDER_WPS;
1026 		else
1027 			pmlmepriv->fw_state = WIFI_STATION_STATE;
1028 		break;
1029 	case NL80211_IFTYPE_ADHOC:
1030 		pmlmepriv->fw_state = WIFI_ADHOC_STATE;
1031 		break;
1032 	default:
1033 		pmlmepriv->fw_state = WIFI_NULL_STATE;
1034 		RT_TRACE(_module_rtl871x_mlme_c_, _drv_err_,
1035 			 "Invalid network_mode\n");
1036 		break;
1037 	}
1038 
1039 	rtw_update_protection23a(padapter, cur_network->network.IEs,
1040 				 cur_network->network.IELength);
1041 
1042 	rtw_update_ht_cap23a(padapter, cur_network->network.IEs,
1043 			     cur_network->network.IELength);
1044 }
1045 
1046 /*
1047  * Notes:
1048  * the function could be > passive_level (the same context as Rx tasklet)
1049  * pnetwork : returns from rtw23a_joinbss_event_cb
1050  * ptarget_wlan: found from scanned_queue
1051  * if join_res > 0, for (fw_state==WIFI_STATION_STATE),
1052  * we check if  "ptarget_sta" & "ptarget_wlan" exist.
1053  * if join_res > 0, for (fw_state==WIFI_ADHOC_STATE),
1054  * we only check if "ptarget_wlan" exist.
1055  * if join_res > 0, update "cur_network->network" from "pnetwork->network"
1056  * if (ptarget_wlan !=NULL).
1057  */
1058 
rtw_joinbss_event_prehandle23a(struct rtw_adapter * adapter,u8 * pbuf)1059 void rtw_joinbss_event_prehandle23a(struct rtw_adapter *adapter, u8 *pbuf)
1060 {
1061 	struct sta_info *ptarget_sta, *pcur_sta;
1062 	struct sta_priv *pstapriv = &adapter->stapriv;
1063 	struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
1064 	struct wlan_network *pnetwork = (struct wlan_network *)pbuf;
1065 	struct wlan_network *cur_network = &pmlmepriv->cur_network;
1066 	struct wlan_network *pcur_wlan, *ptarget_wlan = NULL;
1067 	bool the_same_macaddr;
1068 
1069 	RT_TRACE(_module_rtl871x_mlme_c_, _drv_info_,
1070 		 "joinbss event call back received with res=%d\n",
1071 		 pnetwork->join_res);
1072 
1073 	if (pmlmepriv->assoc_ssid.ssid_len == 0) {
1074 		RT_TRACE(_module_rtl871x_mlme_c_, _drv_err_,
1075 			 "@@@@@   joinbss event call back  for Any SSid\n");
1076 	} else {
1077 		RT_TRACE(_module_rtl871x_mlme_c_, _drv_err_,
1078 			 "@@@@@   rtw23a_joinbss_event_cb for SSid:%s\n",
1079 			 pmlmepriv->assoc_ssid.ssid);
1080 	}
1081 
1082 	if (ether_addr_equal(pnetwork->network.MacAddress,
1083 			     cur_network->network.MacAddress))
1084 		the_same_macaddr = true;
1085 	else
1086 		the_same_macaddr = false;
1087 
1088 	pnetwork->network.Length = get_wlan_bssid_ex_sz(&pnetwork->network);
1089 	if (pnetwork->network.Length > sizeof(struct wlan_bssid_ex)) {
1090 		RT_TRACE(_module_rtl871x_mlme_c_, _drv_err_,
1091 			 "***joinbss_evt_callback return a wrong bss ***\n");
1092 		return;
1093 	}
1094 
1095 	spin_lock_bh(&pmlmepriv->lock);
1096 
1097 	RT_TRACE(_module_rtl871x_mlme_c_, _drv_info_,
1098 		 "rtw23a_joinbss_event_cb !! _enter_critical\n");
1099 
1100 	if (pnetwork->join_res > 0) {
1101 		spin_lock_bh(&pmlmepriv->scanned_queue.lock);
1102 		if (check_fwstate(pmlmepriv, _FW_UNDER_LINKING)) {
1103 			/* s1. find ptarget_wlan */
1104 			if (check_fwstate(pmlmepriv, _FW_LINKED)) {
1105 				if (the_same_macaddr) {
1106 					ptarget_wlan = rtw_find_network23a(&pmlmepriv->scanned_queue, cur_network->network.MacAddress);
1107 				} else {
1108 					pcur_wlan = rtw_find_network23a(&pmlmepriv->scanned_queue, cur_network->network.MacAddress);
1109 					if (pcur_wlan)
1110 						pcur_wlan->fixed = false;
1111 
1112 					pcur_sta = rtw_get_stainfo23a(pstapriv, cur_network->network.MacAddress);
1113 					if (pcur_sta) {
1114 						spin_lock_bh(&pstapriv->sta_hash_lock);
1115 						rtw_free_stainfo23a(adapter,
1116 								    pcur_sta);
1117 						spin_unlock_bh(&pstapriv->sta_hash_lock);
1118 					}
1119 
1120 					ptarget_wlan = rtw_find_network23a(&pmlmepriv->scanned_queue, pnetwork->network.MacAddress);
1121 					if (check_fwstate(pmlmepriv,
1122 							  WIFI_STATION_STATE)) {
1123 						if (ptarget_wlan)
1124 							ptarget_wlan->fixed =
1125 								true;
1126 					}
1127 				}
1128 
1129 			} else {
1130 				ptarget_wlan = rtw_find_network23a(
1131 					&pmlmepriv->scanned_queue,
1132 					pnetwork->network.MacAddress);
1133 				if (check_fwstate(pmlmepriv,
1134 						  WIFI_STATION_STATE)) {
1135 					if (ptarget_wlan)
1136 						ptarget_wlan->fixed = true;
1137 				}
1138 			}
1139 
1140 			/* s2. update cur_network */
1141 			if (ptarget_wlan)
1142 				rtw_joinbss_update_network23a(adapter,
1143 							      ptarget_wlan,
1144 							      pnetwork);
1145 			else {
1146 				RT_TRACE(_module_rtl871x_mlme_c_, _drv_err_,
1147 					 "Can't find ptarget_wlan when joinbss_event callback\n");
1148 				spin_unlock_bh(&pmlmepriv->scanned_queue.lock);
1149 				goto ignore_joinbss_callback;
1150 			}
1151 
1152 			/* s3. find ptarget_sta & update ptarget_sta after
1153 			   update cur_network only for station mode */
1154 			if (check_fwstate(pmlmepriv, WIFI_STATION_STATE)) {
1155 				ptarget_sta = rtw_joinbss_update_stainfo(
1156 					adapter, pnetwork);
1157 				if (!ptarget_sta) {
1158 					RT_TRACE(_module_rtl871x_mlme_c_,
1159 						 _drv_err_,
1160 						 "Can't update stainfo when joinbss_event callback\n");
1161 					spin_unlock_bh(&pmlmepriv->scanned_queue.lock);
1162 					goto ignore_joinbss_callback;
1163 				}
1164 			}
1165 
1166 			/* s4. indicate connect */
1167 			if (check_fwstate(pmlmepriv, WIFI_STATION_STATE))
1168 				rtw_indicate_connect23a(adapter);
1169 			else {
1170 				/* adhoc mode will rtw_indicate_connect23a
1171 				   when rtw_stassoc_event_callback23a */
1172 				RT_TRACE(_module_rtl871x_mlme_c_, _drv_info_,
1173 					 "adhoc mode, fw_state:%x\n",
1174 					 get_fwstate(pmlmepriv));
1175 			}
1176 
1177 			/* s5. Cancle assoc_timer */
1178 			del_timer_sync(&pmlmepriv->assoc_timer);
1179 
1180 			RT_TRACE(_module_rtl871x_mlme_c_, _drv_info_,
1181 				 "Cancle assoc_timer\n");
1182 		} else {
1183 			RT_TRACE(_module_rtl871x_mlme_c_, _drv_err_,
1184 				 "rtw23a_joinbss_event_cb err: fw_state:%x\n",
1185 				 get_fwstate(pmlmepriv));
1186 			spin_unlock_bh(&pmlmepriv->scanned_queue.lock);
1187 			goto ignore_joinbss_callback;
1188 		}
1189 		spin_unlock_bh(&pmlmepriv->scanned_queue.lock);
1190 	} else if (pnetwork->join_res == -4) {
1191 		rtw_reset_securitypriv23a(adapter);
1192 		mod_timer(&pmlmepriv->assoc_timer,
1193 			  jiffies + msecs_to_jiffies(1));
1194 
1195 		/* rtw_free_assoc_resources23a(adapter, 1); */
1196 
1197 		if (check_fwstate(pmlmepriv, _FW_UNDER_LINKING)) {
1198 			RT_TRACE(_module_rtl871x_mlme_c_, _drv_err_,
1199 				 "fail! clear _FW_UNDER_LINKING ^^^fw_state=%x\n",
1200 				 get_fwstate(pmlmepriv));
1201 			_clr_fwstate_(pmlmepriv, _FW_UNDER_LINKING);
1202 		}
1203 	} else {
1204 		/* if join_res < 0 (join fails), then try again */
1205 		mod_timer(&pmlmepriv->assoc_timer,
1206 			  jiffies + msecs_to_jiffies(1));
1207 		_clr_fwstate_(pmlmepriv, _FW_UNDER_LINKING);
1208 	}
1209 
1210 ignore_joinbss_callback:
1211 
1212 	spin_unlock_bh(&pmlmepriv->lock);
1213 }
1214 
rtw23a_joinbss_event_cb(struct rtw_adapter * adapter,const u8 * pbuf)1215 void rtw23a_joinbss_event_cb(struct rtw_adapter *adapter, const u8 *pbuf)
1216 {
1217 	struct wlan_network *pnetwork = (struct wlan_network *)pbuf;
1218 
1219 	mlmeext_joinbss_event_callback23a(adapter, pnetwork->join_res);
1220 
1221 	rtw_os_xmit_schedule23a(adapter);
1222 }
1223 
rtw_stassoc_event_callback23a(struct rtw_adapter * adapter,const u8 * pbuf)1224 void rtw_stassoc_event_callback23a(struct rtw_adapter *adapter, const u8 *pbuf)
1225 {
1226 	struct sta_info *psta;
1227 	struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
1228 	struct stassoc_event *pstassoc = (struct stassoc_event *)pbuf;
1229 	struct wlan_network *cur_network = &pmlmepriv->cur_network;
1230 	struct wlan_network *ptarget_wlan;
1231 
1232 	if (rtw_access_ctrl23a(adapter, pstassoc->macaddr) == false)
1233 		return;
1234 
1235 #ifdef CONFIG_8723AU_AP_MODE
1236 	if (check_fwstate(pmlmepriv, WIFI_AP_STATE)) {
1237 		psta = rtw_get_stainfo23a(&adapter->stapriv, pstassoc->macaddr);
1238 		if (psta) {
1239 			/* bss_cap_update_on_sta_join23a(adapter, psta); */
1240 			/* sta_info_update23a(adapter, psta); */
1241 			ap_sta_info_defer_update23a(adapter, psta);
1242 		}
1243 		return;
1244 	}
1245 #endif
1246 	/* for AD-HOC mode */
1247 	psta = rtw_get_stainfo23a(&adapter->stapriv, pstassoc->macaddr);
1248 	if (psta != NULL) {
1249 		/* the sta have been in sta_info_queue => do nothing */
1250 		RT_TRACE(_module_rtl871x_mlme_c_, _drv_err_,
1251 			 "Error: rtw_stassoc_event_callback23a: sta has been in sta_hash_queue\n");
1252 		/* between drv has received this event before and
1253 		   fw have not yet to set key to CAM_ENTRY) */
1254 		return;
1255 	}
1256 
1257 	psta = rtw_alloc_stainfo23a(&adapter->stapriv, pstassoc->macaddr,
1258 		GFP_KERNEL);
1259 	if (!psta) {
1260 		RT_TRACE(_module_rtl871x_mlme_c_, _drv_err_,
1261 			 "Can't alloc sta_info when rtw_stassoc_event_callback23a\n");
1262 		return;
1263 	}
1264 
1265 	/* to do : init sta_info variable */
1266 	psta->qos_option = 0;
1267 	psta->mac_id = (uint)pstassoc->cam_id;
1268 	/* psta->aid = (uint)pstassoc->cam_id; */
1269 	DBG_8723A("%s\n", __func__);
1270 	/* for ad-hoc mode */
1271 	rtl8723a_SetHalODMVar(adapter, HAL_ODM_STA_INFO, psta, true);
1272 
1273 	if (adapter->securitypriv.dot11AuthAlgrthm == dot11AuthAlgrthm_8021X)
1274 		psta->dot118021XPrivacy =
1275 			adapter->securitypriv.dot11PrivacyAlgrthm;
1276 
1277 	psta->ieee8021x_blocked = false;
1278 
1279 	spin_lock_bh(&pmlmepriv->lock);
1280 
1281 	if (check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE) ||
1282 	    check_fwstate(pmlmepriv, WIFI_ADHOC_STATE)) {
1283 		if (adapter->stapriv.asoc_sta_count == 2) {
1284 			spin_lock_bh(&pmlmepriv->scanned_queue.lock);
1285 			ptarget_wlan =
1286 				rtw_find_network23a(&pmlmepriv->scanned_queue,
1287 						    cur_network->network.MacAddress);
1288 			if (ptarget_wlan)
1289 				ptarget_wlan->fixed = true;
1290 			spin_unlock_bh(&pmlmepriv->scanned_queue.lock);
1291 			/*  a sta + bc/mc_stainfo (not Ibss_stainfo) */
1292 			rtw_indicate_connect23a(adapter);
1293 		}
1294 	}
1295 
1296 	spin_unlock_bh(&pmlmepriv->lock);
1297 
1298 	mlmeext_sta_add_event_callback23a(adapter, psta);
1299 }
1300 
rtw_stadel_event_callback23a(struct rtw_adapter * adapter,const u8 * pbuf)1301 void rtw_stadel_event_callback23a(struct rtw_adapter *adapter, const u8 *pbuf)
1302 {
1303 	int mac_id;
1304 	struct sta_info *psta;
1305 	struct wlan_network *pwlan;
1306 	struct wlan_bssid_ex *pdev_network;
1307 	struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
1308 	struct stadel_event *pstadel = (struct stadel_event *)pbuf;
1309 	struct sta_priv *pstapriv = &adapter->stapriv;
1310 	struct wlan_network *tgt_network = &pmlmepriv->cur_network;
1311 
1312 	psta = rtw_get_stainfo23a(&adapter->stapriv, pstadel->macaddr);
1313 	if (psta)
1314 		mac_id = psta->mac_id;
1315 	else
1316 		mac_id = pstadel->mac_id;
1317 
1318 	DBG_8723A("%s(mac_id=%d)=%pM\n", __func__, mac_id, pstadel->macaddr);
1319 
1320 	if (check_fwstate(pmlmepriv, WIFI_AP_STATE))
1321 		return;
1322 
1323 	mlmeext_sta_del_event_callback23a(adapter);
1324 
1325 	spin_lock_bh(&pmlmepriv->lock);
1326 
1327 	if (check_fwstate(pmlmepriv, WIFI_STATION_STATE)) {
1328 		if (adapter->mlmepriv.to_roaming > 0) {
1329 			/* this stadel_event is caused by roaming,
1330 			   decrease to_roaming */
1331 			pmlmepriv->to_roaming--;
1332 		} else if (adapter->mlmepriv.to_roaming == 0)
1333 			rtw_set_roaming(adapter, adapter->registrypriv.max_roaming_times);
1334 		if (*((u16 *)pstadel->rsvd) != WLAN_REASON_EXPIRATION_CHK)
1335 			rtw_set_roaming(adapter, 0); /* don't roam */
1336 
1337 		rtw_free_uc_swdec_pending_queue23a(adapter);
1338 
1339 		rtw_free_assoc_resources23a(adapter, 1);
1340 		rtw_indicate_disconnect23a(adapter);
1341 		spin_lock_bh(&pmlmepriv->scanned_queue.lock);
1342 		/*  remove the network entry in scanned_queue */
1343 		pwlan = rtw_find_network23a(&pmlmepriv->scanned_queue,
1344 					    tgt_network->network.MacAddress);
1345 		if (pwlan) {
1346 			pwlan->fixed = false;
1347 			rtw_free_network_nolock(pmlmepriv, pwlan);
1348 		}
1349 		spin_unlock_bh(&pmlmepriv->scanned_queue.lock);
1350 
1351 		_rtw_roaming(adapter, tgt_network);
1352 	}
1353 
1354 	if (check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE) ||
1355 	    check_fwstate(pmlmepriv, WIFI_ADHOC_STATE)) {
1356 
1357 		spin_lock_bh(&pstapriv->sta_hash_lock);
1358 		rtw_free_stainfo23a(adapter,  psta);
1359 		spin_unlock_bh(&pstapriv->sta_hash_lock);
1360 
1361 		/* a sta + bc/mc_stainfo (not Ibss_stainfo) */
1362 		if (adapter->stapriv.asoc_sta_count == 1) {
1363 			spin_lock_bh(&pmlmepriv->scanned_queue.lock);
1364 			/* free old ibss network */
1365 			/* pwlan = rtw_find_network23a(
1366 			   &pmlmepriv->scanned_queue, pstadel->macaddr); */
1367 			pwlan = rtw_find_network23a(&pmlmepriv->scanned_queue,
1368 						    tgt_network->network.MacAddress);
1369 			if (pwlan) {
1370 				pwlan->fixed = false;
1371 				rtw_free_network_nolock(pmlmepriv, pwlan);
1372 			}
1373 			spin_unlock_bh(&pmlmepriv->scanned_queue.lock);
1374 			/* re-create ibss */
1375 			pdev_network = &adapter->registrypriv.dev_network;
1376 
1377 			memcpy(pdev_network, &tgt_network->network,
1378 			       get_wlan_bssid_ex_sz(&tgt_network->network));
1379 
1380 			rtw_do_join_adhoc(adapter);
1381 		}
1382 	}
1383 
1384 	spin_unlock_bh(&pmlmepriv->lock);
1385 }
1386 
1387 /*
1388 * rtw23a_join_to_handler - Timeout/failure handler for CMD JoinBss
1389 * @adapter: pointer to _adapter structure
1390 */
rtw23a_join_to_handler(unsigned long data)1391 void rtw23a_join_to_handler (unsigned long data)
1392 {
1393 	struct rtw_adapter *adapter = (struct rtw_adapter *)data;
1394 	struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
1395 	int do_join_r;
1396 
1397 	DBG_8723A("%s, fw_state=%x\n", __func__, get_fwstate(pmlmepriv));
1398 
1399 	if (adapter->bDriverStopped || adapter->bSurpriseRemoved)
1400 		return;
1401 
1402 	spin_lock_bh(&pmlmepriv->lock);
1403 
1404 	if (adapter->mlmepriv.to_roaming > 0) {
1405 		/* join timeout caused by roaming */
1406 		while (1) {
1407 			pmlmepriv->to_roaming--;
1408 			if (adapter->mlmepriv.to_roaming != 0) {
1409 				/* try another */
1410 				DBG_8723A("%s try another roaming\n", __func__);
1411 				do_join_r = rtw_do_join(adapter);
1412 				if (do_join_r != _SUCCESS) {
1413 					DBG_8723A("%s roaming do_join return "
1414 						  "%d\n", __func__ , do_join_r);
1415 					continue;
1416 				}
1417 				break;
1418 			} else {
1419 				DBG_8723A("%s We've try roaming but fail\n",
1420 					  __func__);
1421 				rtw_indicate_disconnect23a(adapter);
1422 				break;
1423 			}
1424 		}
1425 	} else {
1426 		rtw_indicate_disconnect23a(adapter);
1427 		free_scanqueue(pmlmepriv);/*  */
1428 
1429 		/* indicate disconnect for the case that join_timeout and
1430 		   check_fwstate != FW_LINKED */
1431 		rtw_cfg80211_indicate_disconnect(adapter);
1432 	}
1433 
1434 	spin_unlock_bh(&pmlmepriv->lock);
1435 
1436 }
1437 
1438 /*
1439 * rtw_scan_timeout_handler23a - Timeout/Failure handler for CMD SiteSurvey
1440 * @data: pointer to _adapter structure
1441 */
rtw_scan_timeout_handler23a(unsigned long data)1442 void rtw_scan_timeout_handler23a(unsigned long data)
1443 {
1444 	struct rtw_adapter *adapter = (struct rtw_adapter *)data;
1445 	struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
1446 
1447 	DBG_8723A("%s(%s): fw_state =%x\n", __func__, adapter->pnetdev->name,
1448 		  get_fwstate(pmlmepriv));
1449 
1450 	spin_lock_bh(&pmlmepriv->lock);
1451 
1452 	_clr_fwstate_(pmlmepriv, _FW_UNDER_SURVEY);
1453 
1454 	spin_unlock_bh(&pmlmepriv->lock);
1455 
1456 	rtw_cfg80211_indicate_scan_done(wdev_to_priv(adapter->rtw_wdev), true);
1457 }
1458 
rtw_dynamic_check_timer_handler(unsigned long data)1459 void rtw_dynamic_check_timer_handler(unsigned long data)
1460 {
1461 	struct rtw_adapter *adapter = (struct rtw_adapter *)data;
1462 
1463 	if (adapter->hw_init_completed == false)
1464 		goto out;
1465 
1466 	if (adapter->bDriverStopped == true ||
1467 	    adapter->bSurpriseRemoved == true)
1468 		goto out;
1469 
1470 	if (adapter->net_closed == true)
1471 		goto out;
1472 
1473 	rtw_dynamic_chk_wk_cmd23a(adapter);
1474 
1475 out:
1476 	mod_timer(&adapter->mlmepriv.dynamic_chk_timer,
1477 		  jiffies + msecs_to_jiffies(2000));
1478 }
1479 
rtw_is_scan_deny(struct rtw_adapter * adapter)1480 inline bool rtw_is_scan_deny(struct rtw_adapter *adapter)
1481 {
1482 	struct mlme_priv *mlmepriv = &adapter->mlmepriv;
1483 
1484 	return (atomic_read(&mlmepriv->set_scan_deny) != 0) ? true : false;
1485 }
1486 
rtw_clear_scan_deny(struct rtw_adapter * adapter)1487 void rtw_clear_scan_deny(struct rtw_adapter *adapter)
1488 {
1489 	struct mlme_priv *mlmepriv = &adapter->mlmepriv;
1490 
1491 	atomic_set(&mlmepriv->set_scan_deny, 0);
1492 }
1493 
rtw_set_scan_deny_timer_hdl(unsigned long data)1494 void rtw_set_scan_deny_timer_hdl(unsigned long data)
1495 {
1496 	struct rtw_adapter *adapter = (struct rtw_adapter *)data;
1497 
1498 	rtw_clear_scan_deny(adapter);
1499 }
1500 
rtw_set_scan_deny(struct rtw_adapter * adapter,u32 ms)1501 void rtw_set_scan_deny(struct rtw_adapter *adapter, u32 ms)
1502 {
1503 	struct mlme_priv *mlmepriv = &adapter->mlmepriv;
1504 
1505 	atomic_set(&mlmepriv->set_scan_deny, 1);
1506 	mod_timer(&mlmepriv->set_scan_deny_timer,
1507 		  jiffies + msecs_to_jiffies(ms));
1508 }
1509 
1510 #if defined(IEEE80211_SCAN_RESULT_EXPIRE)
1511 #define RTW_SCAN_RESULT_EXPIRE  \
1512 	((IEEE80211_SCAN_RESULT_EXPIRE / (HZ*1000)) - 1000) /* 3000 -1000 */
1513 #else
1514 #define RTW_SCAN_RESULT_EXPIRE 2000
1515 #endif
1516 
1517 /*
1518 * Select a new join candidate from the original @param candidate and
1519 *     @param competitor
1520 * @return true: candidate is updated
1521 * @return false: candidate is not updated
1522 */
rtw_check_join_candidate(struct mlme_priv * pmlmepriv,struct wlan_network ** candidate,struct wlan_network * competitor)1523 static int rtw_check_join_candidate(struct mlme_priv *pmlmepriv,
1524 				    struct wlan_network **candidate,
1525 				    struct wlan_network *competitor)
1526 {
1527 	int updated = false;
1528 	struct rtw_adapter *adapter;
1529 
1530 	adapter = container_of(pmlmepriv, struct rtw_adapter, mlmepriv);
1531 
1532 	/* check bssid, if needed */
1533 	if (pmlmepriv->assoc_by_bssid == true) {
1534 		if (!ether_addr_equal(competitor->network.MacAddress,
1535 				      pmlmepriv->assoc_bssid))
1536 			goto exit;
1537 	}
1538 
1539 	/* check ssid, if needed */
1540 	if (pmlmepriv->assoc_ssid.ssid_len) {
1541 		if (competitor->network.Ssid.ssid_len !=
1542 		    pmlmepriv->assoc_ssid.ssid_len ||
1543 		    memcmp(competitor->network.Ssid.ssid,
1544 			   pmlmepriv->assoc_ssid.ssid,
1545 			   pmlmepriv->assoc_ssid.ssid_len))
1546 			goto exit;
1547 	}
1548 
1549 	if (rtw_is_desired_network(adapter, competitor) == false)
1550 		goto exit;
1551 
1552 	if (adapter->mlmepriv.to_roaming > 0) {
1553 		unsigned int passed;
1554 
1555 		passed = jiffies_to_msecs(jiffies - competitor->last_scanned);
1556 		if (passed >= RTW_SCAN_RESULT_EXPIRE ||
1557 		    is_same_ess(&competitor->network,
1558 				&pmlmepriv->cur_network.network) == false)
1559 			goto exit;
1560 	}
1561 
1562 	if (!*candidate ||
1563 	    (*candidate)->network.Rssi<competitor->network.Rssi) {
1564 		*candidate = competitor;
1565 		updated = true;
1566 	}
1567 
1568 	if (updated) {
1569 		DBG_8723A("[by_bssid:%u][assoc_ssid:%s][to_roaming:%u] new candidate: %s(%pM) rssi:%d\n",
1570 			  pmlmepriv->assoc_by_bssid,
1571 			  pmlmepriv->assoc_ssid.ssid,
1572 			  adapter->mlmepriv.to_roaming,
1573 			  (*candidate)->network.Ssid.ssid,
1574 			  (*candidate)->network.MacAddress,
1575 			  (int)(*candidate)->network.Rssi);
1576 	}
1577 
1578 exit:
1579 	return updated;
1580 }
1581 
1582 /*
1583 Calling context:
1584 The caller of the sub-routine will be in critical section...
1585 
1586 The caller must hold the following spinlock
1587 
1588 pmlmepriv->lock
1589 
1590 */
1591 
rtw_do_join(struct rtw_adapter * padapter)1592 static int rtw_do_join(struct rtw_adapter *padapter)
1593 {
1594 	struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
1595 	int ret;
1596 
1597 	pmlmepriv->cur_network.join_res = -2;
1598 
1599 	set_fwstate(pmlmepriv, _FW_UNDER_LINKING);
1600 
1601 	pmlmepriv->to_join = true;
1602 
1603 	ret = rtw_select_and_join_from_scanned_queue23a(pmlmepriv);
1604 	if (ret == _SUCCESS) {
1605 		pmlmepriv->to_join = false;
1606 	} else {
1607 		if (check_fwstate(pmlmepriv, WIFI_ADHOC_STATE)) {
1608 			/* switch to ADHOC_MASTER */
1609 			ret = rtw_do_join_adhoc(padapter);
1610 			if (ret != _SUCCESS)
1611 				goto exit;
1612 		} else {
1613 			/*  can't associate ; reset under-linking */
1614 			_clr_fwstate_(pmlmepriv, _FW_UNDER_LINKING);
1615 
1616 			ret = _FAIL;
1617 			pmlmepriv->to_join = false;
1618 		}
1619 	}
1620 
1621 exit:
1622 	return ret;
1623 }
1624 
1625 static struct wlan_network *
rtw_select_candidate_from_queue(struct mlme_priv * pmlmepriv)1626 rtw_select_candidate_from_queue(struct mlme_priv *pmlmepriv)
1627 {
1628 	struct wlan_network *pnetwork, *candidate = NULL;
1629 	struct rtw_queue *queue = &pmlmepriv->scanned_queue;
1630 	struct list_head *phead, *plist, *ptmp;
1631 
1632 	spin_lock_bh(&pmlmepriv->scanned_queue.lock);
1633 	phead = get_list_head(queue);
1634 
1635 	list_for_each_safe(plist, ptmp, phead) {
1636 		pnetwork = container_of(plist, struct wlan_network, list);
1637 		if (!pnetwork) {
1638 			RT_TRACE(_module_rtl871x_mlme_c_, _drv_err_,
1639 				 "%s: return _FAIL:(pnetwork == NULL)\n",
1640 				 __func__);
1641 			goto exit;
1642 		}
1643 
1644 		rtw_check_join_candidate(pmlmepriv, &candidate, pnetwork);
1645 	}
1646 
1647 exit:
1648 	spin_unlock_bh(&pmlmepriv->scanned_queue.lock);
1649 	return candidate;
1650 }
1651 
1652 
rtw_do_join_adhoc(struct rtw_adapter * adapter)1653 int rtw_do_join_adhoc(struct rtw_adapter *adapter)
1654 {
1655 	struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
1656 	struct wlan_bssid_ex *pdev_network;
1657 	u8 *ibss;
1658 	int ret;
1659 
1660 	pdev_network = &adapter->registrypriv.dev_network;
1661 	ibss = adapter->registrypriv.dev_network.MacAddress;
1662 
1663 	_clr_fwstate_(pmlmepriv, _FW_UNDER_SURVEY);
1664 
1665 	RT_TRACE(_module_rtl871x_mlme_c_, _drv_err_,
1666 		 "switching to adhoc master\n");
1667 
1668 	memcpy(&pdev_network->Ssid, &pmlmepriv->assoc_ssid,
1669 	       sizeof(struct cfg80211_ssid));
1670 
1671 	rtw_update_registrypriv_dev_network23a(adapter);
1672 	rtw_generate_random_ibss23a(ibss);
1673 
1674 	pmlmepriv->fw_state = WIFI_ADHOC_MASTER_STATE;
1675 
1676 	ret = rtw_createbss_cmd23a(adapter);
1677 	if (ret != _SUCCESS) {
1678 		RT_TRACE(_module_rtl871x_mlme_c_, _drv_err_,
1679 			 "Error =>rtw_createbss_cmd23a status FAIL\n");
1680 	} else  {
1681 		pmlmepriv->to_join = false;
1682 	}
1683 
1684 	return ret;
1685 }
1686 
rtw_do_join_network(struct rtw_adapter * adapter,struct wlan_network * candidate)1687 int rtw_do_join_network(struct rtw_adapter *adapter,
1688 			struct wlan_network *candidate)
1689 {
1690 	int ret;
1691 
1692 	/*  check for situation of  _FW_LINKED */
1693 	if (check_fwstate(&adapter->mlmepriv, _FW_LINKED)) {
1694 		DBG_8723A("%s: _FW_LINKED while ask_for_joinbss!\n", __func__);
1695 
1696 		rtw_disassoc_cmd23a(adapter, 0, true);
1697 		rtw_indicate_disconnect23a(adapter);
1698 		rtw_free_assoc_resources23a(adapter, 0);
1699 	}
1700 	set_fwstate(&adapter->mlmepriv, _FW_UNDER_LINKING);
1701 
1702 	ret = rtw_joinbss_cmd23a(adapter, candidate);
1703 
1704 	if (ret == _SUCCESS)
1705 		mod_timer(&adapter->mlmepriv.assoc_timer,
1706 			  jiffies + msecs_to_jiffies(MAX_JOIN_TIMEOUT));
1707 
1708 	return ret;
1709 }
1710 
rtw_select_and_join_from_scanned_queue23a(struct mlme_priv * pmlmepriv)1711 int rtw_select_and_join_from_scanned_queue23a(struct mlme_priv *pmlmepriv)
1712 {
1713 	struct rtw_adapter *adapter;
1714 	struct wlan_network *candidate = NULL;
1715 	int ret;
1716 
1717 	adapter = pmlmepriv->nic_hdl;
1718 
1719 	candidate = rtw_select_candidate_from_queue(pmlmepriv);
1720 	if (!candidate) {
1721 		DBG_8723A("%s: return _FAIL(candidate == NULL)\n", __func__);
1722 		ret = _FAIL;
1723 		goto exit;
1724 	} else {
1725 		DBG_8723A("%s: candidate: %s(%pM, ch:%u)\n",
1726 			  __func__,
1727 			  candidate->network.Ssid.ssid,
1728 			  candidate->network.MacAddress,
1729 			  candidate->network.DSConfig);
1730 	}
1731 
1732 	ret = rtw_do_join_network(adapter, candidate);
1733 
1734 exit:
1735 	return ret;
1736 }
1737 
rtw_set_auth23a(struct rtw_adapter * adapter,struct security_priv * psecuritypriv)1738 int rtw_set_auth23a(struct rtw_adapter *adapter,
1739 		    struct security_priv *psecuritypriv)
1740 {
1741 	struct cmd_obj *pcmd;
1742 	struct setauth_parm *psetauthparm;
1743 	struct cmd_priv *pcmdpriv = &adapter->cmdpriv;
1744 	int res = _SUCCESS;
1745 
1746 	pcmd = kzalloc(sizeof(struct cmd_obj), GFP_KERNEL);
1747 	if (!pcmd) {
1748 		res = _FAIL;  /* try again */
1749 		goto exit;
1750 	}
1751 
1752 	psetauthparm = kzalloc(sizeof(struct setauth_parm), GFP_KERNEL);
1753 	if (!psetauthparm) {
1754 		kfree(pcmd);
1755 		res = _FAIL;
1756 		goto exit;
1757 	}
1758 
1759 	psetauthparm->mode = (unsigned char)psecuritypriv->dot11AuthAlgrthm;
1760 
1761 	pcmd->cmdcode = _SetAuth_CMD_;
1762 	pcmd->parmbuf = (unsigned char *)psetauthparm;
1763 	pcmd->cmdsz =  (sizeof(struct setauth_parm));
1764 	pcmd->rsp = NULL;
1765 	pcmd->rspsz = 0;
1766 
1767 	RT_TRACE(_module_rtl871x_mlme_c_, _drv_err_,
1768 		 "after enqueue set_auth_cmd, auth_mode=%x\n",
1769 		 psecuritypriv->dot11AuthAlgrthm);
1770 
1771 	res = rtw_enqueue_cmd23a(pcmdpriv, pcmd);
1772 
1773 exit:
1774 
1775 	return res;
1776 }
1777 
rtw_set_key23a(struct rtw_adapter * adapter,struct security_priv * psecuritypriv,int keyid,u8 set_tx)1778 int rtw_set_key23a(struct rtw_adapter *adapter,
1779 		   struct security_priv *psecuritypriv, int keyid, u8 set_tx)
1780 {
1781 	u8 keylen;
1782 	struct cmd_obj *pcmd;
1783 	struct setkey_parm *psetkeyparm;
1784 	struct cmd_priv *pcmdpriv = &adapter->cmdpriv;
1785 	struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
1786 	int res = _SUCCESS;
1787 
1788 	if (keyid >= 4) {
1789 		res = _FAIL;
1790 		goto exit;
1791 	}
1792 
1793 	pcmd = kzalloc(sizeof(struct cmd_obj), GFP_KERNEL);
1794 	if (!pcmd) {
1795 		res = _FAIL;  /* try again */
1796 		goto exit;
1797 	}
1798 	psetkeyparm = kzalloc(sizeof(struct setkey_parm), GFP_KERNEL);
1799 	if (!psetkeyparm) {
1800 		kfree(pcmd);
1801 		res = _FAIL;
1802 		goto exit;
1803 	}
1804 
1805 	if (psecuritypriv->dot11AuthAlgrthm == dot11AuthAlgrthm_8021X) {
1806 		psetkeyparm->algorithm = (unsigned char)
1807 			psecuritypriv->dot118021XGrpPrivacy;
1808 		RT_TRACE(_module_rtl871x_mlme_c_, _drv_err_,
1809 			 "rtw_set_key23a: psetkeyparm->algorithm = (unsigned char)psecuritypriv->dot118021XGrpPrivacy =%d\n",
1810 			 psetkeyparm->algorithm);
1811 	} else {
1812 		psetkeyparm->algorithm = (u8)psecuritypriv->dot11PrivacyAlgrthm;
1813 		RT_TRACE(_module_rtl871x_mlme_c_, _drv_err_,
1814 			 "rtw_set_key23a: psetkeyparm->algorithm = (u8)psecuritypriv->dot11PrivacyAlgrthm =%d\n",
1815 			 psetkeyparm->algorithm);
1816 	}
1817 	psetkeyparm->keyid = keyid;/* 0~3 */
1818 	psetkeyparm->set_tx = set_tx;
1819 	if (is_wep_enc(psetkeyparm->algorithm))
1820 		pmlmepriv->key_mask |= BIT(psetkeyparm->keyid);
1821 
1822 	DBG_8723A("==> rtw_set_key23a algorithm(%x), keyid(%x), key_mask(%x)\n",
1823 		  psetkeyparm->algorithm, psetkeyparm->keyid,
1824 		  pmlmepriv->key_mask);
1825 	RT_TRACE(_module_rtl871x_mlme_c_, _drv_err_,
1826 		 "rtw_set_key23a: psetkeyparm->algorithm =%d psetkeyparm->keyid = (u8)keyid =%d\n",
1827 		 psetkeyparm->algorithm, keyid);
1828 
1829 	switch (psetkeyparm->algorithm) {
1830 	case WLAN_CIPHER_SUITE_WEP40:
1831 		keylen = 5;
1832 		memcpy(&psetkeyparm->key[0],
1833 		       &psecuritypriv->wep_key[keyid].key, keylen);
1834 		break;
1835 	case WLAN_CIPHER_SUITE_WEP104:
1836 		keylen = 13;
1837 		memcpy(&psetkeyparm->key[0],
1838 		       &psecuritypriv->wep_key[keyid].key, keylen);
1839 		break;
1840 	case WLAN_CIPHER_SUITE_TKIP:
1841 		keylen = 16;
1842 		memcpy(&psetkeyparm->key,
1843 		       &psecuritypriv->dot118021XGrpKey[keyid], keylen);
1844 		psetkeyparm->grpkey = 1;
1845 		break;
1846 	case WLAN_CIPHER_SUITE_CCMP:
1847 		keylen = 16;
1848 		memcpy(&psetkeyparm->key,
1849 		       &psecuritypriv->dot118021XGrpKey[keyid], keylen);
1850 		psetkeyparm->grpkey = 1;
1851 		break;
1852 	default:
1853 		RT_TRACE(_module_rtl871x_mlme_c_, _drv_err_,
1854 			 "rtw_set_key23a:psecuritypriv->dot11PrivacyAlgrthm = %x (must be 1 or 2 or 4 or 5)\n",
1855 			 psecuritypriv->dot11PrivacyAlgrthm);
1856 		res = _FAIL;
1857 		kfree(pcmd);
1858 		kfree(psetkeyparm);
1859 		goto exit;
1860 	}
1861 
1862 	pcmd->cmdcode = _SetKey_CMD_;
1863 	pcmd->parmbuf = (u8 *)psetkeyparm;
1864 	pcmd->cmdsz =  (sizeof(struct setkey_parm));
1865 	pcmd->rsp = NULL;
1866 	pcmd->rspsz = 0;
1867 
1868 	/* sema_init(&pcmd->cmd_sem, 0); */
1869 
1870 	res = rtw_enqueue_cmd23a(pcmdpriv, pcmd);
1871 
1872 exit:
1873 
1874 	return res;
1875 }
1876 
1877 /* adjust IEs for rtw_joinbss_cmd23a in WMM */
rtw_restruct_wmm_ie23a(struct rtw_adapter * adapter,u8 * in_ie,u8 * out_ie,uint in_len,uint initial_out_len)1878 int rtw_restruct_wmm_ie23a(struct rtw_adapter *adapter, u8 *in_ie,
1879 			   u8 *out_ie, uint in_len, uint initial_out_len)
1880 {
1881 	int ielength;
1882 	const u8 *p;
1883 
1884 	ielength = initial_out_len;
1885 
1886 	p = cfg80211_find_vendor_ie(WLAN_OUI_MICROSOFT,
1887 				    WLAN_OUI_TYPE_MICROSOFT_WMM,
1888 				    in_ie, in_len);
1889 
1890 	if (p && p[1]) {
1891 		memcpy(out_ie + initial_out_len, p, 9);
1892 
1893 		out_ie[initial_out_len + 1] = 7;
1894 		out_ie[initial_out_len + 6] = 0;
1895 		out_ie[initial_out_len + 8] = 0;
1896 
1897 		ielength += 9;
1898 	}
1899 
1900 	return ielength;
1901 }
1902 
1903 /*  */
1904 /*  Ported from 8185: IsInPreAuthKeyList().
1905     (Renamed from SecIsInPreAuthKeyList(), 2006-10-13.) */
1906 /*  Added by Annie, 2006-05-07. */
1907 /*  */
1908 /*  Search by BSSID, */
1909 /*  Return Value: */
1910 /*		-1	:if there is no pre-auth key in the  table */
1911 /*		>= 0	:if there is pre-auth key, and   return the entry id */
1912 /*  */
1913 /*  */
1914 
SecIsInPMKIDList(struct rtw_adapter * Adapter,u8 * bssid)1915 static int SecIsInPMKIDList(struct rtw_adapter *Adapter, u8 *bssid)
1916 {
1917 	struct security_priv *psecuritypriv = &Adapter->securitypriv;
1918 	int i = 0;
1919 
1920 	do {
1921 		if (psecuritypriv->PMKIDList[i].bUsed &&
1922                     ether_addr_equal(psecuritypriv->PMKIDList[i].Bssid, bssid)) {
1923 			break;
1924 		} else {
1925 			i++;
1926 			/* continue; */
1927 		}
1928 	} while (i < NUM_PMKID_CACHE);
1929 
1930 	if (i == NUM_PMKID_CACHE)
1931 		i = -1;/*  Could not find. */
1932 	else {
1933 		/*  There is one Pre-Authentication Key for
1934 		    the specific BSSID. */
1935 	}
1936 
1937 	return i;
1938 }
1939 
1940 /*  */
1941 /*  Check the RSN IE length */
1942 /*  If the RSN IE length <= 20, the RSN IE didn't include
1943     the PMKID information */
1944 /*  0-11th element in the array are the fixed IE */
1945 /*  12th element in the array is the IE */
1946 /*  13th element in the array is the IE length */
1947 /*  */
1948 
rtw_append_pmkid(struct rtw_adapter * Adapter,int iEntry,u8 * ie,uint ie_len)1949 static int rtw_append_pmkid(struct rtw_adapter *Adapter, int iEntry,
1950 			    u8 *ie, uint ie_len)
1951 {
1952 	struct security_priv *psecuritypriv = &Adapter->securitypriv;
1953 
1954 	if (ie[1] <= 20) {
1955 		/*  The RSN IE didn't include the PMK ID,
1956 		    append the PMK information */
1957 			ie[ie_len] = 1;
1958 			ie_len++;
1959 			ie[ie_len] = 0;	/* PMKID count = 0x0100 */
1960 			ie_len++;
1961 			memcpy(&ie[ie_len],
1962 			       &psecuritypriv->PMKIDList[iEntry].PMKID, 16);
1963 
1964 			ie_len += 16;
1965 			ie[1] += 18;/* PMKID length = 2+16 */
1966 	}
1967 	return ie_len;
1968 }
1969 
rtw_restruct_sec_ie23a(struct rtw_adapter * adapter,u8 * in_ie,u8 * out_ie,uint in_len)1970 int rtw_restruct_sec_ie23a(struct rtw_adapter *adapter, u8 *in_ie, u8 *out_ie,
1971 			   uint in_len)
1972 {
1973 	u8 authmode;
1974 	uint ielength;
1975 	int iEntry;
1976 	struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
1977 	struct security_priv *psecuritypriv = &adapter->securitypriv;
1978 	uint ndisauthmode = psecuritypriv->ndisauthtype;
1979 	uint ndissecuritytype = psecuritypriv->ndisencryptstatus;
1980 
1981 	RT_TRACE(_module_rtl871x_mlme_c_, _drv_notice_,
1982 		 "+rtw_restruct_sec_ie23a: ndisauthmode=%d ndissecuritytype=%d\n",
1983 		 ndisauthmode, ndissecuritytype);
1984 
1985 	ielength = 0;
1986 	if (ndisauthmode == Ndis802_11AuthModeWPA ||
1987 	    ndisauthmode == Ndis802_11AuthModeWPAPSK)
1988 		authmode = WLAN_EID_VENDOR_SPECIFIC;
1989 	if (ndisauthmode == Ndis802_11AuthModeWPA2 ||
1990 	    ndisauthmode == Ndis802_11AuthModeWPA2PSK)
1991 		authmode = WLAN_EID_RSN;
1992 
1993 	if (check_fwstate(pmlmepriv, WIFI_UNDER_WPS)) {
1994 		memcpy(out_ie + ielength, psecuritypriv->wps_ie,
1995 		       psecuritypriv->wps_ie_len);
1996 
1997 		ielength += psecuritypriv->wps_ie_len;
1998 	} else if (authmode == WLAN_EID_VENDOR_SPECIFIC ||
1999 		   authmode == WLAN_EID_RSN) {
2000 		/* copy RSN or SSN */
2001 		memcpy(&out_ie[ielength], &psecuritypriv->supplicant_ie[0],
2002 		       psecuritypriv->supplicant_ie[1] + 2);
2003 		ielength += psecuritypriv->supplicant_ie[1] + 2;
2004 	}
2005 
2006 	iEntry = SecIsInPMKIDList(adapter, pmlmepriv->assoc_bssid);
2007 	if (iEntry < 0)
2008 		return ielength;
2009 	else {
2010 		if (authmode == WLAN_EID_RSN)
2011 			ielength = rtw_append_pmkid(adapter, iEntry,
2012 						    out_ie, ielength);
2013 	}
2014 
2015 	return ielength;
2016 }
2017 
rtw_init_registrypriv_dev_network23a(struct rtw_adapter * adapter)2018 void rtw_init_registrypriv_dev_network23a(struct rtw_adapter *adapter)
2019 {
2020 	struct registry_priv *pregistrypriv = &adapter->registrypriv;
2021 	struct eeprom_priv *peepriv = &adapter->eeprompriv;
2022 	struct wlan_bssid_ex    *pdev_network = &pregistrypriv->dev_network;
2023 	u8 *myhwaddr = myid(peepriv);
2024 
2025 	ether_addr_copy(pdev_network->MacAddress, myhwaddr);
2026 
2027 	memcpy(&pdev_network->Ssid, &pregistrypriv->ssid,
2028 	       sizeof(struct cfg80211_ssid));
2029 
2030 	pdev_network->beacon_interval = 100;
2031 }
2032 
rtw_update_registrypriv_dev_network23a(struct rtw_adapter * adapter)2033 void rtw_update_registrypriv_dev_network23a(struct rtw_adapter *adapter)
2034 {
2035 	int sz = 0;
2036 	struct registry_priv *pregistrypriv = &adapter->registrypriv;
2037 	struct wlan_bssid_ex *pdev_network = &pregistrypriv->dev_network;
2038 	struct security_priv *psecuritypriv = &adapter->securitypriv;
2039 	struct wlan_network *cur_network = &adapter->mlmepriv.cur_network;
2040 	/* struct	xmit_priv	*pxmitpriv = &adapter->xmitpriv; */
2041 
2042 	pdev_network->Privacy =
2043 		(psecuritypriv->dot11PrivacyAlgrthm > 0 ? 1 : 0);
2044 
2045 	pdev_network->Rssi = 0;
2046 
2047 	pdev_network->DSConfig = pregistrypriv->channel;
2048 	RT_TRACE(_module_rtl871x_mlme_c_, _drv_info_,
2049 		 "pregistrypriv->channel =%d, pdev_network->DSConfig = 0x%x\n",
2050 		 pregistrypriv->channel, pdev_network->DSConfig);
2051 
2052 	if (cur_network->network.ifmode == NL80211_IFTYPE_ADHOC)
2053 		pdev_network->ATIMWindow = 0;
2054 
2055 	pdev_network->ifmode = cur_network->network.ifmode;
2056 
2057 	/*  1. Supported rates */
2058 	/*  2. IE */
2059 
2060 	sz = rtw_generate_ie23a(pregistrypriv);
2061 
2062 	pdev_network->IELength = sz;
2063 
2064 	pdev_network->Length =
2065 		get_wlan_bssid_ex_sz(pdev_network);
2066 
2067 	/* notes: translate IELength & Length after assign the
2068 	   Length to cmdsz in createbss_cmd(); */
2069 	/* pdev_network->IELength = cpu_to_le32(sz); */
2070 }
2071 
2072 /* the function is at passive_level */
rtw_joinbss_reset23a(struct rtw_adapter * padapter)2073 void rtw_joinbss_reset23a(struct rtw_adapter *padapter)
2074 {
2075 	u8 threshold;
2076 	struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
2077 	struct ht_priv *phtpriv = &pmlmepriv->htpriv;
2078 
2079 	/* todo: if you want to do something io/reg/hw setting
2080 	   before join_bss, please add code here */
2081 
2082 	pmlmepriv->num_FortyMHzIntolerant = 0;
2083 
2084 	pmlmepriv->num_sta_no_ht = 0;
2085 
2086 	phtpriv->ampdu_enable = false;/* reset to disabled */
2087 
2088 	/*  TH = 1 => means that invalidate usb rx aggregation */
2089 	/*  TH = 0 => means that validate usb rx aggregation, use init value. */
2090 	if (phtpriv->ht_option) {
2091 		if (padapter->registrypriv.wifi_spec == 1)
2092 			threshold = 1;
2093 		else
2094 			threshold = 0;
2095 	} else
2096 		threshold = 1;
2097 
2098 	rtl8723a_set_rxdma_agg_pg_th(padapter, threshold);
2099 }
2100 
2101 /* the function is >= passive_level */
rtw_restructure_ht_ie23a(struct rtw_adapter * padapter,u8 * in_ie,u8 * out_ie,uint in_len,uint * pout_len)2102 bool rtw_restructure_ht_ie23a(struct rtw_adapter *padapter, u8 *in_ie,
2103 			      u8 *out_ie, uint in_len, uint *pout_len)
2104 {
2105 	u32 out_len;
2106 	int max_rx_ampdu_factor;
2107 	unsigned char *pframe;
2108 	const u8 *p;
2109 	struct ieee80211_ht_cap ht_capie;
2110 	u8 WMM_IE[7] = {0x00, 0x50, 0xf2, 0x02, 0x00, 0x01, 0x00};
2111 	struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
2112 	struct ht_priv *phtpriv = &pmlmepriv->htpriv;
2113 
2114 	phtpriv->ht_option = false;
2115 
2116 	p = cfg80211_find_ie(WLAN_EID_HT_CAPABILITY, in_ie, in_len);
2117 
2118 	if (p && p[1] > 0) {
2119 		u32 rx_packet_offset, max_recvbuf_sz;
2120 
2121 		if (pmlmepriv->qos_option == 0) {
2122 			out_len = *pout_len;
2123 			pframe = rtw_set_ie23a(out_ie + out_len,
2124 					       WLAN_EID_VENDOR_SPECIFIC,
2125 					       sizeof(WMM_IE), WMM_IE,
2126 					       pout_len);
2127 
2128 			pmlmepriv->qos_option = 1;
2129 		}
2130 
2131 		out_len = *pout_len;
2132 
2133 		memset(&ht_capie, 0, sizeof(struct ieee80211_ht_cap));
2134 
2135 		ht_capie.cap_info = cpu_to_le16(IEEE80211_HT_CAP_SUP_WIDTH_20_40 |
2136 			IEEE80211_HT_CAP_SGI_20 | IEEE80211_HT_CAP_SGI_40 |
2137 			IEEE80211_HT_CAP_TX_STBC | IEEE80211_HT_CAP_DSSSCCK40);
2138 
2139 		GetHalDefVar8192CUsb(padapter, HAL_DEF_RX_PACKET_OFFSET,
2140 				     &rx_packet_offset);
2141 		GetHalDefVar8192CUsb(padapter, HAL_DEF_MAX_RECVBUF_SZ,
2142 				     &max_recvbuf_sz);
2143 
2144 		GetHalDefVar8192CUsb(padapter, HW_VAR_MAX_RX_AMPDU_FACTOR,
2145 				     &max_rx_ampdu_factor);
2146 		ht_capie.ampdu_params_info = max_rx_ampdu_factor & 0x03;
2147 
2148 		if (padapter->securitypriv.dot11PrivacyAlgrthm ==
2149 		    WLAN_CIPHER_SUITE_CCMP)
2150 			ht_capie.ampdu_params_info |=
2151 				(IEEE80211_HT_AMPDU_PARM_DENSITY& (0x07 << 2));
2152 		else
2153 			ht_capie.ampdu_params_info |=
2154 				(IEEE80211_HT_AMPDU_PARM_DENSITY & 0x00);
2155 
2156 		pframe = rtw_set_ie23a(out_ie + out_len, WLAN_EID_HT_CAPABILITY,
2157 				    sizeof(struct ieee80211_ht_cap),
2158 				    (unsigned char *)&ht_capie, pout_len);
2159 
2160 		phtpriv->ht_option = true;
2161 
2162 		p = cfg80211_find_ie(WLAN_EID_HT_OPERATION, in_ie, in_len);
2163 		if (p && (p[1] == sizeof(struct ieee80211_ht_operation))) {
2164 			out_len = *pout_len;
2165 			pframe = rtw_set_ie23a(out_ie + out_len,
2166 					       WLAN_EID_HT_OPERATION,
2167 					       p[1], p + 2 , pout_len);
2168 		}
2169 	}
2170 
2171 	return phtpriv->ht_option;
2172 }
2173 
2174 /* the function is > passive_level (in critical_section) */
rtw_update_ht_cap23a(struct rtw_adapter * padapter,u8 * pie,uint ie_len)2175 void rtw_update_ht_cap23a(struct rtw_adapter *padapter, u8 *pie, uint ie_len)
2176 {
2177 	u8 max_ampdu_sz;
2178 	const u8 *p;
2179 	struct ieee80211_ht_cap *pht_capie;
2180 	struct ieee80211_ht_operation *pht_addtinfo;
2181 	struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
2182 	struct ht_priv *phtpriv = &pmlmepriv->htpriv;
2183 	struct registry_priv *pregistrypriv = &padapter->registrypriv;
2184 	struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
2185 	struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
2186 
2187 	if (!phtpriv->ht_option)
2188 		return;
2189 
2190 	if ((!pmlmeinfo->HT_info_enable) || (!pmlmeinfo->HT_caps_enable))
2191 		return;
2192 
2193 	DBG_8723A("+rtw_update_ht_cap23a()\n");
2194 
2195 	/* maybe needs check if ap supports rx ampdu. */
2196 	if (!phtpriv->ampdu_enable && pregistrypriv->ampdu_enable == 1) {
2197 		if (pregistrypriv->wifi_spec == 1)
2198 			phtpriv->ampdu_enable = false;
2199 		else
2200 			phtpriv->ampdu_enable = true;
2201 	} else if (pregistrypriv->ampdu_enable == 2)
2202 		phtpriv->ampdu_enable = true;
2203 
2204 	/* check Max Rx A-MPDU Size */
2205 	p = cfg80211_find_ie(WLAN_EID_HT_CAPABILITY, pie, ie_len);
2206 
2207 	if (p && p[1] > 0) {
2208 		pht_capie = (struct ieee80211_ht_cap *)(p + 2);
2209 		max_ampdu_sz = pht_capie->ampdu_params_info &
2210 			IEEE80211_HT_AMPDU_PARM_FACTOR;
2211 		/*  max_ampdu_sz (kbytes); */
2212 		max_ampdu_sz = 1 << (max_ampdu_sz + 3);
2213 
2214 		phtpriv->rx_ampdu_maxlen = max_ampdu_sz;
2215 	}
2216 
2217 	p = cfg80211_find_ie(WLAN_EID_HT_OPERATION, pie, ie_len);
2218 	if (p && p[1] > 0) {
2219 		pht_addtinfo = (struct ieee80211_ht_operation *)(p + 2);
2220 		/* todo: */
2221 	}
2222 
2223 	/* update cur_bwmode & cur_ch_offset */
2224 	if (pregistrypriv->cbw40_enable &&
2225 	    pmlmeinfo->ht_cap.cap_info &
2226 	    cpu_to_le16(IEEE80211_HT_CAP_SUP_WIDTH_20_40) &&
2227 	    pmlmeinfo->HT_info.ht_param & IEEE80211_HT_PARAM_CHAN_WIDTH_ANY) {
2228 		int i;
2229 		u8 rf_type;
2230 
2231 		rf_type = rtl8723a_get_rf_type(padapter);
2232 
2233 		/* update the MCS rates */
2234 		for (i = 0; i < IEEE80211_HT_MCS_MASK_LEN; i++) {
2235 			if (rf_type == RF_1T1R || rf_type == RF_1T2R)
2236 				pmlmeinfo->ht_cap.mcs.rx_mask[i] &=
2237 					MCS_rate_1R23A[i];
2238 			else
2239 				pmlmeinfo->ht_cap.mcs.rx_mask[i] &=
2240 					MCS_rate_2R23A[i];
2241 		}
2242 		/* switch to the 40M Hz mode according to the AP */
2243 		pmlmeext->cur_bwmode = HT_CHANNEL_WIDTH_40;
2244 		switch (pmlmeinfo->HT_info.ht_param &
2245 			IEEE80211_HT_PARAM_CHA_SEC_OFFSET) {
2246 		case IEEE80211_HT_PARAM_CHA_SEC_ABOVE:
2247 			pmlmeext->cur_ch_offset = HAL_PRIME_CHNL_OFFSET_LOWER;
2248 			break;
2249 
2250 		case IEEE80211_HT_PARAM_CHA_SEC_BELOW:
2251 			pmlmeext->cur_ch_offset = HAL_PRIME_CHNL_OFFSET_UPPER;
2252 			break;
2253 
2254 		default:
2255 			pmlmeext->cur_ch_offset =
2256 				HAL_PRIME_CHNL_OFFSET_DONT_CARE;
2257 			break;
2258 		}
2259 	}
2260 
2261 	/*  */
2262 	/*  Config SM Power Save setting */
2263 	/*  */
2264 	pmlmeinfo->SM_PS =
2265 		(le16_to_cpu(pmlmeinfo->ht_cap.cap_info) &
2266 		 IEEE80211_HT_CAP_SM_PS) >> IEEE80211_HT_CAP_SM_PS_SHIFT;
2267 	if (pmlmeinfo->SM_PS == WLAN_HT_CAP_SM_PS_STATIC)
2268 		DBG_8723A("%s(): WLAN_HT_CAP_SM_PS_STATIC\n", __func__);
2269 
2270 	/*  */
2271 	/*  Config current HT Protection mode. */
2272 	/*  */
2273 	pmlmeinfo->HT_protection =
2274 		le16_to_cpu(pmlmeinfo->HT_info.operation_mode) &
2275 		IEEE80211_HT_OP_MODE_PROTECTION;
2276 }
2277 
rtw_issue_addbareq_cmd23a(struct rtw_adapter * padapter,struct xmit_frame * pxmitframe)2278 void rtw_issue_addbareq_cmd23a(struct rtw_adapter *padapter,
2279 			       struct xmit_frame *pxmitframe)
2280 {
2281 	u8 issued;
2282 	int priority;
2283 	struct sta_info *psta;
2284 	struct ht_priv	*phtpriv;
2285 	struct pkt_attrib *pattrib = &pxmitframe->attrib;
2286 	s32 bmcst = is_multicast_ether_addr(pattrib->ra);
2287 
2288 	if (bmcst || padapter->mlmepriv.LinkDetectInfo.NumTxOkInPeriod < 100)
2289 		return;
2290 
2291 	priority = pattrib->priority;
2292 
2293 	if (pattrib->psta)
2294 		psta = pattrib->psta;
2295 	else {
2296 		DBG_8723A("%s, call rtw_get_stainfo23a()\n", __func__);
2297 		psta = rtw_get_stainfo23a(&padapter->stapriv, pattrib->ra);
2298 	}
2299 
2300 	if (!psta) {
2301 		DBG_8723A("%s, psta == NUL\n", __func__);
2302 		return;
2303 	}
2304 
2305 	if (!(psta->state &_FW_LINKED)) {
2306 		DBG_8723A("%s, psta->state(0x%x) != _FW_LINKED\n",
2307 			  __func__, psta->state);
2308 		return;
2309 	}
2310 
2311 	phtpriv = &psta->htpriv;
2312 
2313 	if (phtpriv->ht_option && phtpriv->ampdu_enable) {
2314 		issued = (phtpriv->agg_enable_bitmap>>priority)&0x1;
2315 		issued |= (phtpriv->candidate_tid_bitmap>>priority)&0x1;
2316 
2317 		if (issued == 0) {
2318 			DBG_8723A("rtw_issue_addbareq_cmd23a, p =%d\n",
2319 				  priority);
2320 			psta->htpriv.candidate_tid_bitmap |= BIT(priority);
2321 			rtw_addbareq_cmd23a(padapter, (u8) priority,
2322 					    pattrib->ra);
2323 		}
2324 	}
2325 }
2326 
rtw_linked_check(struct rtw_adapter * padapter)2327 int rtw_linked_check(struct rtw_adapter *padapter)
2328 {
2329 	if (check_fwstate(&padapter->mlmepriv, WIFI_AP_STATE) ||
2330 	    check_fwstate(&padapter->mlmepriv,
2331 			  WIFI_ADHOC_STATE|WIFI_ADHOC_MASTER_STATE)) {
2332 		if (padapter->stapriv.asoc_sta_count > 2)
2333 			return true;
2334 	} else {	/* Station mode */
2335 		if (check_fwstate(&padapter->mlmepriv, _FW_LINKED))
2336 			return true;
2337 	}
2338 	return false;
2339 }
2340