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