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